diff --git a/.gitattributes b/.gitattributes index f46a38d1d1..924d25cd8c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -39,6 +39,3 @@ ##Force tab indents on dm files *.dm whitespace=indent-with-non-tab - -## Force changelog merging to use union -html/changelog.html text eol=lf merge=union diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index d10a2d79f6..d25839b92f 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -11,7 +11,8 @@ 6. [Pull Request Process](#pull-request-process) 7. [Porting features/sprites/sounds/tools from other codebases](#porting-featuresspritessoundstools-from-other-codebases) 8. [Banned content](#banned-content) -9. [A word on Git](#a-word-on-git) +9. [Content requiring prior approval](#content-requiring-prior-approval) +10. [A word on Git](#a-word-on-git) ## Reporting Issues If you ever encounter a bug in-game, the best way to let a coder know about it is with our GitHub Issue Tracker. Please make sure you use the supplied issue template, and include the round ID for the server. @@ -678,6 +679,14 @@ Do not add any of the following in a Pull Request or risk getting the PR closed: Just because something isn't on this list doesn't mean that it's acceptable. Use common sense above all else. +## Content requiring prior approval +Certain types of changes may require prior approval from maintainers. This currently includes: + +* Code adding, removing, or updating the availability of alien races/species/human mutants. This includes pull requests attempting to add or remove features from said races/species/mutants. (Requires approval from at least one maintainer) +* Code adding, removing, or modifying the functionality of adult-oriented features (such as, but not limited to: vore, genitals, MKUltra, and more). This also includes pull requests attempting to add or remove these features outright. (Requires approval from at least half of the formal maintainer team) + +If a PR contains any of the above content, and it lacks prior approval, then it may closed at maintainer discretion. Prior approval requires an @Maintainer ping in a relevant development/code or staff channel on the Discord. This is primarily to limit the impact of PRs that're created in bad faith, or are otherwise counterproductive to the server's health. + ## A word on Git This repository uses `LF` line endings for all code as specified in the **.gitattributes** and **.editorconfig** files. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f204eb0a72..f9a4055342 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -27,6 +27,11 @@ refactor: refactored some code config: changed some config setting admin: messed with admin stuff server: something server ops should know +wip: still being worked on +experiment: experimental +tgs: has something to do with tgs +expansion: expands on something +qol: quality of life content /:cl: diff --git a/.github/workflows/ci_suite.yml b/.github/workflows/ci_suite.yml index f36055dab0..dc93324bff 100644 --- a/.github/workflows/ci_suite.yml +++ b/.github/workflows/ci_suite.yml @@ -13,11 +13,20 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - - name: Setup cache + - name: Restore SpacemanDMM cache uses: actions/cache@v2 with: - path: $HOME/SpacemanDMM - key: ${{ runner.os }}-spacemandmm + path: ~/SpacemanDMM + key: ${{ runner.os }}-spacemandmm-${{ secrets.CACHE_PURGE_KEY }} + - name: Restore Yarn cache + uses: actions/cache@v2 + with: + path: tgui/.yarn/cache + key: ${{ runner.os }}-yarn-${{ secrets.CACHE_PURGE_KEY }}-${{ hashFiles('tgui/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-build-${{ secrets.CACHE_PURGE_KEY }}- + ${{ runner.os }}-build- + ${{ runner.os }}- - name: Install Tools run: | pip3 install setuptools @@ -28,16 +37,15 @@ jobs: run: | bash tools/ci/check_filedirs.sh tgstation.dme bash tools/ci/check_changelogs.sh + bash tools/ci/check_grep.sh find . -name "*.php" -print0 | xargs -0 -n1 php -l find . -name "*.json" -not -path "*/node_modules/*" -print0 | xargs -0 python3 ./tools/json_verifier.py - tgui/bin/tgui --lint - tgui/bin/tgui --test - bash tools/ci/check_grep.sh + tools/build/build --ci lint tools/bootstrap/python -m dmi.test tools/bootstrap/python -m mapmerge2.dmm_test ~/dreamchecker > ${GITHUB_WORKSPACE}/output-annotations.txt 2>&1 - name: Annotate Lints - uses: yogstation13/DreamAnnotate@v1 + uses: yogstation13/DreamAnnotate@v2 if: always() with: outputFile: output-annotations.txt @@ -48,19 +56,16 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - - name: Setup cache + - name: Restore BYOND cache uses: actions/cache@v2 with: - path: $HOME/BYOND - key: ${{ runner.os }}-byond + path: ~/BYOND + key: ${{ runner.os }}-byond-${{ secrets.CACHE_PURGE_KEY }} - name: Compile All Maps run: | bash tools/ci/install_byond.sh source $HOME/BYOND/byond/bin/byondsetup - python3 tools/ci/template_dm_generator.py - tools/build/build - env: - CBT_BUILD_MODE : ALL_MAPS + tools/build/build --ci dm -DCIBUILDING -DCITESTING -DALL_MAPS run_all_tests: if: "!contains(github.event.head_commit.message, '[ci skip]')" @@ -76,11 +81,20 @@ jobs: options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - uses: actions/checkout@v2 - - name: Setup cache + - name: Restore BYOND cache uses: actions/cache@v2 with: - path: $HOME/BYOND - key: ${{ runner.os }}-byond + path: ~/BYOND + key: ${{ runner.os }}-byond-${{ secrets.CACHE_PURGE_KEY }} + - name: Restore Yarn cache + uses: actions/cache@v2 + with: + path: tgui/.yarn/cache + key: ${{ runner.os }}-yarn-${{ secrets.CACHE_PURGE_KEY }}-${{ hashFiles('tgui/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-build-${{ secrets.CACHE_PURGE_KEY }}- + ${{ runner.os }}-build- + ${{ runner.os }}- - name: Setup database run: | sudo systemctl start mysql @@ -88,7 +102,7 @@ jobs: mysql -u root -proot tg_ci < SQL/tgstation_schema.sql mysql -u root -proot -e 'CREATE DATABASE tg_ci_prefixed;' mysql -u root -proot tg_ci_prefixed < SQL/tgstation_schema_prefixed.sql - - name: Install rust dependencies + - name: Install rust-g run: | sudo dpkg --add-architecture i386 sudo apt update || true @@ -96,15 +110,14 @@ jobs: bash tools/ci/install_rust_g.sh - name: Install auxmos run: | + sudo apt update || true bash tools/ci/install_auxmos.sh - name: Compile and run tests run: | bash tools/ci/install_byond.sh source $HOME/BYOND/byond/bin/byondsetup - tools/build/build -DCIBUILDING + tools/build/build --ci -DCIBUILDING bash tools/ci/run_server.sh - env: - CBT_BUILD_MODE: TEST_RUN test_windows: if: "!contains(github.event.head_commit.message, '[ci skip]')" @@ -112,6 +125,15 @@ jobs: runs-on: windows-latest steps: - uses: actions/checkout@v2 + - name: Restore Yarn cache + uses: actions/cache@v2 + with: + path: tgui/.yarn/cache + key: ${{ runner.os }}-yarn-${{ secrets.CACHE_PURGE_KEY }}-${{ hashFiles('tgui/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-build-${{ secrets.CACHE_PURGE_KEY }}- + ${{ runner.os }}-build- + ${{ runner.os }}- - name: Compile run: pwsh tools/ci/build.ps1 env: diff --git a/.github/workflows/compile_changelogs.yml b/.github/workflows/compile_changelogs.yml index b0e1578815..fc2f436986 100644 --- a/.github/workflows/compile_changelogs.yml +++ b/.github/workflows/compile_changelogs.yml @@ -36,17 +36,14 @@ jobs: - name: "Compile" if: steps.value_holder.outputs.CL_ENABLED run: | - python tools/ss13_genchangelog.py html/changelog.html html/changelogs - - name: "Convert Lineendings" - if: steps.value_holder.outputs.CL_ENABLED - run: | - unix2dos html/changelogs/.all_changelog.yml + python tools/ss13_genchangelog.py html/changelogs - name: Commit if: steps.value_holder.outputs.CL_ENABLED run: | git config --local user.email "action@github.com" git config --local user.name "Changelogs" git pull origin master + git add html/changelogs git commit -m "Automatic changelog compile [ci skip]" -a || true - name: "Push" if: steps.value_holder.outputs.CL_ENABLED diff --git a/.github/workflows/generate_documentation.yml b/.github/workflows/generate_documentation.yml index 0fa3f315be..265e179ff0 100644 --- a/.github/workflows/generate_documentation.yml +++ b/.github/workflows/generate_documentation.yml @@ -12,8 +12,8 @@ jobs: - name: Setup cache uses: actions/cache@v2 with: - path: $HOME/SpacemanDMM - key: ${{ runner.os }}-spacemandmm + path: ~/SpacemanDMM + key: ${{ runner.os }}-spacemandmm-${{ secrets.CACHE_PURGE_KEY }} - name: Install SpacemanDMM run: bash tools/ci/install_spaceman_dmm.sh dmdoc - name: Generate documentation diff --git a/.gitignore b/.gitignore index 91a0ef08eb..ef738bcf38 100644 --- a/.gitignore +++ b/.gitignore @@ -7,14 +7,16 @@ #Ignore byond config folder. /cfg/**/* -#Ignore rust-g and auxmos libraries which are compiled with scripts -*.so -/tools/build/binaries/**/* +# Ignore compiled linux libs in the root folder, e.g. librust_g.so +/*.so #Ignore compiled files and other files generated during compilation. *.mdme +*.mdme.* *.dmb *.rsc +*.m.dme +*.test.dme *.lk *.int *.backup @@ -53,27 +55,6 @@ __pycache__/ *.py[cod] *$py.class -# C extensions -#*.so - -# Distribution / packaging -.Python -env/ -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg - # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. @@ -81,8 +62,7 @@ var/ *.spec # Installer logs -pip-log.txt -pip-delete-this-directory.txt +pip-*.txt # Unit test / coverage reports htmlcov/ @@ -92,7 +72,6 @@ htmlcov/ .cache nosetests.xml coverage.xml -*,cover .hypothesis/ # Translations @@ -101,10 +80,6 @@ coverage.xml # Django stuff: *.log -local_settings.py - -# Flask instance folder -instance/ # Scrapy stuff: .scrapy @@ -112,9 +87,6 @@ instance/ # Sphinx documentation docs/_build/ -# PyBuilder -target/ - # IPython Notebook .ipynb_checkpoints @@ -127,10 +99,6 @@ celerybeat-schedule # dotenv .env -# virtualenv -venv/ -ENV/ - # IntelliJ IDEA / PyCharm (with plugin) .idea @@ -153,12 +121,6 @@ Desktop.ini # Recycle Bin used on file shares $RECYCLE.BIN/ -# Windows Installer files -#*.cab -#*.msi -#*.msm -#*.msp - # Windows shortcuts *.lnk @@ -199,11 +161,10 @@ Temporary Items #Visual studio stuff *.vscode/* -!/.vscode/extensions.json -tools/MapAtmosFixer/MapAtmosFixer/obj/* -tools/MapAtmosFixer/MapAtmosFixer/bin/* -tools/CreditsTool/bin/* -tools/CreditsTool/obj/* +/tools/MapAtmosFixer/MapAtmosFixer/obj/* +/tools/MapAtmosFixer/MapAtmosFixer/bin/* +/tools/CreditsTool/bin/* +/tools/CreditsTool/obj/* #GitHub Atom .atom-build.json @@ -228,13 +189,12 @@ tools/CreditsTool/obj/* !/config/title_screens/images/exclude #Linux docker -tools/LinuxOneShot/SetupProgram/obj/* -tools/LinuxOneShot/SetupProgram/bin/* -tools/LinuxOneShot/SetupProgram/.vs -tools/LinuxOneShot/Database -tools/LinuxOneShot/TGS_Config -tools/LinuxOneShot/TGS_Instances -tools/LinuxOneShot/TGS_Logs - -# Common build tooling -!/tools/build +/tools/LinuxOneShot/SetupProgram/obj/* +/tools/LinuxOneShot/SetupProgram/bin/* +/tools/LinuxOneShot/SetupProgram/.vs +/tools/LinuxOneShot/Database +/tools/LinuxOneShot/TGS_Config +/tools/LinuxOneShot/TGS_Instances +/tools/LinuxOneShot/TGS_Logs +tools/UnstandardnessTestForDM/UnstandardnessTestForDM/obj/x86/Debug/UnstandardnessTestForDM.csproj.AssemblyReference.cache +tools/UnstandardnessTestForDM/UnstandardnessTestForDM/obj/x86/Debug/.NETFramework,Version=v4.0,Profile=Client.AssemblyAttributes.cs diff --git a/.tgs.yml b/.tgs.yml new file mode 100644 index 0000000000..22a65f0edc --- /dev/null +++ b/.tgs.yml @@ -0,0 +1,23 @@ +# This file is used by TGS (https://github.com/tgstation/tgstation-server) clients to quickly initialize a server instance for the codebase +# The format isn't documented anywhere but hopefully we never have to change it. If there are questions, contact the TGS maintainer Cyberboss/@Dominion#0444 +version: 1 +# The BYOND version to use (kept in sync with dependencies.sh by the "TGS Test Suite" CI job) +# Must be interpreted as a string, keep quoted +byond: "514.1556" +# Folders to create in "/Configuration/GameStaticFiles/" +static_files: + # Config directory should be static + - name: config + # This implies the folder should be pre-populated with contents from the repo + populate: true + # Data directory must be static + - name: data +# String dictionary. The value is the location of the file in the repo to upload to TGS. The key is the name of the file to upload to "/Configuration/EventScripts/" +# This one is for Linux hosted servers +linux_scripts: + PreCompile.sh: tools/tgs4_scripts/PreCompile.sh +# Same as above for Windows hosted servers +windows_scripts: + PreCompile.bat: tools/tgs_scripts/PreCompile.bat +# The security level the game should be run at +security: Trusted diff --git a/.tgs4.yml b/.tgs4.yml deleted file mode 100644 index 932a3a6672..0000000000 --- a/.tgs4.yml +++ /dev/null @@ -1,8 +0,0 @@ -static_files: - - name: config - populate: true - - name: data -linux_scripts: - PreCompile.sh: tools/tgs4_scripts/PreCompile.sh -windows_scripts: - PreCompile.bat: tools/tgs4_scripts/PreCompile.bat diff --git a/.vscode/settings.json b/.vscode/settings.json index bfce9bda7c..8edb013566 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,7 +13,7 @@ "source.fixAll.eslint": true }, "workbench.editorAssociations": { - "*.dmi": "imagePreview.previewEditor" + "*.dmi": "dmiEditor.dmiEditor" }, "files.eol": "\n", "gitlens.advanced.blame.customArguments": ["-w"], diff --git a/Build.bat b/Build.bat index dd3a6fd9d9..68eaef0c2d 100644 --- a/Build.bat +++ b/Build.bat @@ -1,2 +1,3 @@ -@call tools\build\build -@pause +@echo off +call "%~dp0\tools\build\build.bat" %* +pause diff --git a/Build.sh b/Build.sh index 6fd691921e..f36de6e9d0 100755 --- a/Build.sh +++ b/Build.sh @@ -1,4 +1,4 @@ #!/bin/bash cd "$(dirname "$(readlink -f "$0")")" cd ./tools/build -sudo bash ./build.sh +sudo bash ./build diff --git a/CLEAN.bat b/CLEAN.bat new file mode 100644 index 0000000000..47293bb769 --- /dev/null +++ b/CLEAN.bat @@ -0,0 +1,3 @@ +@echo off +call "%~dp0\tools\build\build.bat" dist-clean +pause diff --git a/README.md b/README.md index bbceb0f05b..cc485278cc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## Citadel Station 13 Based and maintained from /tg/station. -[![Build Status](https://api.travis-ci.org/Citadel-Station-13/Citadel-Station-13.png)](https://travis-ci.org/Citadel-Station-13/Citadel-Station-13) +[![Build Status](https://github.com/Citadel-Station-13/Citadel-Station-13/workflows/CI%20Suite/badge.svg)](https://github.com/Citadel-Station-13/Citadel-Station-13/actions?query=workflow%3A%22CI+Suite%22) [![Percentage of issues still open](http://isitmaintained.com/badge/open/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Percentage of issues still open") [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Average time to resolve an issue") @@ -100,6 +100,14 @@ install, overwriting when prompted except if we've specified otherwise, and recompile the game. Once you start the server up again, you should be running the new version. +## :exclamation: How to compile :exclamation: + +On **2021-01-04** we have changed the way to compile the codebase. + +Find `Build.cmd` in this folder, and double click it to initiate the build. It consists of multiple steps and might take around 1-5 minutes to compile. If it closes, it means it has finished its job. You can then setup the server normally by opening `tgstation.dmb` in DreamDaemon. + +**Building tgstation in DreamMaker directly is now deprecated and might produce errors**, such as `'tgui.bundle.js': cannot find file`. + ## HOSTING If you'd like a more robust server hosting option for tgstation and its diff --git a/RUN_SERVER.bat b/RUN_SERVER.bat new file mode 100644 index 0000000000..93438f0c2e --- /dev/null +++ b/RUN_SERVER.bat @@ -0,0 +1,3 @@ +@echo off +call "%~dp0\tools\build\build.bat" server %* +pause diff --git a/SQL/mentor.sql b/SQL/mentor.sql index c5fb7f0d83..45d0829d88 100644 --- a/SQL/mentor.sql +++ b/SQL/mentor.sql @@ -5,10 +5,10 @@ CREATE TABLE `mentor_memo` ( `last_editor` varchar(32) DEFAULT NULL, `edits` text, PRIMARY KEY (`ckey`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; CREATE TABLE `mentor` ( `id` int(11) NOT NULL AUTO_INCREMENT, `ckey` varchar(32) NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; \ No newline at end of file +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; diff --git a/SQL/mentor_prefixed.sql b/SQL/mentor_prefixed.sql new file mode 100644 index 0000000000..81e76f333e --- /dev/null +++ b/SQL/mentor_prefixed.sql @@ -0,0 +1,14 @@ +CREATE TABLE `SS13_mentor_memo` ( + `ckey` varchar(32) NOT NULL, + `memotext` text NOT NULL, + `timestamp` datetime NOT NULL, + `last_editor` varchar(32) DEFAULT NULL, + `edits` text, + PRIMARY KEY (`ckey`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +CREATE TABLE `SS13_mentor` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ckey` varchar(32) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; diff --git a/_maps/RandomRuins/AnywhereRuins/fountain_hall.dmm b/_maps/RandomRuins/AnywhereRuins/fountain_hall.dmm index f1b0582ec3..35b5d702ab 100644 --- a/_maps/RandomRuins/AnywhereRuins/fountain_hall.dmm +++ b/_maps/RandomRuins/AnywhereRuins/fountain_hall.dmm @@ -5,45 +5,45 @@ "c" = ( /obj/structure/healingfountain, /turf/open/floor/carpet/purple, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "d" = ( /obj/structure/fluff/divine/conduit, /turf/open/floor/mineral/plasma, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "e" = ( /obj/structure/sacrificealtar, /turf/open/floor/carpet/purple, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "f" = ( /mob/living/simple_animal/butterfly, /turf/open/floor/carpet/purple, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "g" = ( /mob/living/simple_animal/butterfly, /turf/open/floor/carpet/red, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "h" = ( /obj/structure/fans/tiny/invisible, /turf/open/floor/carpet/red, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "u" = ( /turf/open/floor/carpet/purple, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "G" = ( /turf/closed/wall/mineral/cult{ sheet_amount = 0 }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "J" = ( /mob/living/simple_animal/butterfly, /turf/open/floor/carpet/royalblack, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "T" = ( /turf/open/floor/carpet/royalblack, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "U" = ( /turf/open/floor/carpet/red, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) (1,1,1) = {" a diff --git a/_maps/RandomRuins/AnywhereRuins/golem_ship.dmm b/_maps/RandomRuins/AnywhereRuins/golem_ship.dmm index e20fa042d7..2d2ad90206 100644 --- a/_maps/RandomRuins/AnywhereRuins/golem_ship.dmm +++ b/_maps/RandomRuins/AnywhereRuins/golem_ship.dmm @@ -4,7 +4,7 @@ /area/template_noop) "b" = ( /turf/closed/wall/mineral/titanium/nodiagonal, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "c" = ( /obj/structure/closet/crate, /obj/item/shovel, @@ -20,7 +20,7 @@ /obj/item/card/id/mining, /obj/item/gps/mining/off, /turf/open/floor/plating, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "d" = ( /obj/structure/closet/crate, /obj/item/shovel, @@ -34,18 +34,18 @@ /obj/item/card/id/mining, /obj/item/gps/mining/off, /turf/open/floor/plating, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "e" = ( /obj/item/storage/toolbox/mechanical, /turf/open/floor/plating, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "f" = ( /turf/open/floor/plating, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "g" = ( /obj/structure/reagent_dispensers/watertank, /turf/open/floor/plating, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "h" = ( /obj/structure/shuttle/engine/heater{ dir = 4 @@ -56,7 +56,7 @@ /turf/open/floor/plating{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "i" = ( /obj/structure/shuttle/engine/propulsion{ dir = 8 @@ -64,37 +64,37 @@ /turf/open/floor/plating{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "j" = ( /obj/machinery/door/airlock/titanium, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "k" = ( /obj/machinery/computer/arcade/battle{ dir = 4; icon_state = "arcade" }, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "l" = ( /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "m" = ( /obj/effect/mob_spawn/human/golem/adamantine, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "n" = ( /obj/machinery/mineral/equipment_vendor/golem, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "o" = ( /obj/item/resonator, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "p" = ( /obj/machinery/mineral/ore_redemption, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "q" = ( /obj/structure/statue/gold/rd, /obj/structure/window/reinforced{ @@ -105,24 +105,24 @@ dir = 8 }, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "r" = ( /obj/machinery/computer/shuttle, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "s" = ( /obj/machinery/computer/arcade/orion_trail{ dir = 4; icon_state = "arcade" }, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "t" = ( /obj/structure/extinguisher_cabinet{ pixel_y = 30 }, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "u" = ( /obj/structure/table/wood, /obj/item/bedsheet/rd/royal_cape{ @@ -141,27 +141,27 @@ }, /obj/item/tcg_card/special/golem, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "v" = ( /obj/item/resonator/upgraded, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "w" = ( /obj/machinery/autolathe, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "x" = ( /obj/structure/table/wood, /obj/machinery/reagentgrinder, /obj/item/gps/mining, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "z" = ( /obj/structure/extinguisher_cabinet{ pixel_y = -30 }, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "A" = ( /obj/structure/table/wood, /obj/item/surgical_drapes{ @@ -170,14 +170,14 @@ /obj/item/storage/firstaid/fire, /obj/item/storage/firstaid/fire, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "B" = ( /obj/item/storage/firstaid/fire, /obj/structure/table/wood, /obj/item/storage/firstaid/fire, /obj/machinery/light, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "C" = ( /obj/item/storage/firstaid/brute, /obj/structure/table/wood, @@ -187,34 +187,34 @@ name = "land claim" }, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "D" = ( /obj/item/storage/firstaid/brute, /obj/structure/table/wood, /obj/item/storage/firstaid/brute, /obj/item/disk/design_disk/golem_shell, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "E" = ( /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plating, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "F" = ( /obj/structure/ore_box, /turf/open/floor/plating, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "G" = ( /turf/closed/wall/mineral/titanium, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "H" = ( /obj/machinery/door/airlock/titanium, /obj/structure/fans/tiny, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "I" = ( /obj/machinery/light/small, /turf/open/floor/plating, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "K" = ( /obj/machinery/door/airlock/titanium, /obj/structure/fans/tiny, @@ -222,59 +222,59 @@ dir = 8 }, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "L" = ( /obj/machinery/light/small{ dir = 1 }, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "M" = ( /obj/effect/mob_spawn/human/golem/adamantine, /obj/machinery/light/small{ dir = 1 }, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "N" = ( /obj/machinery/light{ dir = 1 }, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "O" = ( /obj/machinery/light{ dir = 8 }, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "Q" = ( /obj/machinery/light/small, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "T" = ( /obj/structure/fans/tiny, /obj/machinery/door/airlock/titanium, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "U" = ( /obj/effect/mob_spawn/human/golem/adamantine, /obj/machinery/light/small, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "V" = ( /obj/machinery/light/small{ dir = 1 }, /turf/open/floor/plating, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) "Y" = ( /obj/machinery/door/airlock/titanium, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/golem_ship) +/area/ruin/lavaland/powered/golem_ship) (1,1,1) = {" a diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_bathhouse.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_bathhouse.dmm index 6947549f83..1ec9461699 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_bathhouse.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_bathhouse.dmm @@ -4,14 +4,14 @@ /area/template_noop) "b" = ( /turf/closed/wall/ice, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "c" = ( /obj/machinery/shower{ pixel_y = 16 }, /obj/structure/curtain, /turf/open/floor/plasteel/white, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "d" = ( /turf/closed/mineral/random/snow, /area/icemoon/underground/explored) @@ -23,40 +23,40 @@ pixel_y = 20 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "f" = ( /obj/structure/table/greyscale, /obj/item/bikehorn/rubberducky, /turf/open/floor/plasteel/white, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "g" = ( /turf/open/floor/plasteel/white, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "h" = ( /obj/item/soap, /turf/open/floor/plasteel/white, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "i" = ( /obj/machinery/door/airlock/freezer{ name = "bath house airlock" }, /turf/open/floor/plasteel/white, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "j" = ( /turf/closed/wall/mineral/wood, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "k" = ( /turf/open/floor/wood, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "l" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/meatballspaghetti, /turf/open/floor/wood, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "m" = ( /obj/structure/bookcase/random, /turf/open/floor/wood, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "n" = ( /turf/open/floor/plating/asteroid/snow/ice/icemoon, /area/icemoon/underground/explored) @@ -64,7 +64,7 @@ /obj/structure/bed, /obj/item/bedsheet, /turf/open/floor/wood, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) (1,1,1) = {" b diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_library.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_library.dmm index 38e4f2685e..0e2789066c 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_library.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_library.dmm @@ -7,167 +7,167 @@ /obj/item/documents/syndicate/mining, /obj/effect/decal/cleanable/cobweb, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ac" = ( /turf/closed/wall/mineral/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ad" = ( /turf/closed/mineral/random/snow, /area/icemoon/underground/explored) "ae" = ( /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "af" = ( /obj/item/stack/sheet/mineral/wood, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ag" = ( /obj/item/feather, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ah" = ( /obj/structure/bookcase/random, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ai" = ( /obj/structure/table/wood/fancy/black, /obj/item/paper/crumpled/fluff/stations/lavaland/library/diary2, /obj/effect/decal/cleanable/cobweb/cobweb2, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ak" = ( /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "al" = ( /turf/closed/wall/mineral/iron, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "am" = ( /obj/structure/table/wood/fancy/black, /obj/item/book_of_babel, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ao" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ap" = ( /obj/item/stack/sheet/mineral/wood, /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aq" = ( /obj/structure/fluff/paper{ dir = 1 }, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ar" = ( /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "as" = ( /obj/effect/decal/cleanable/dirt, /obj/item/paper/fluff/ruins/oldstation/protosing, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "at" = ( /obj/structure/fluff/paper, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "av" = ( /obj/structure/bookcase/random, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aw" = ( /turf/open/floor/plating, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ax" = ( /obj/effect/decal/cleanable/dirt, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ay" = ( /obj/machinery/door/keycard/library, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "az" = ( /obj/item/paper/crumpled/fluff/stations/lavaland/library/diary, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aA" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aC" = ( /obj/item/feather, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aD" = ( /turf/open/floor/carpet/black, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aE" = ( /obj/item/stack/sheet/mineral/wood, /obj/item/book/manual/random, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aF" = ( /obj/item/book/manual/random, /obj/effect/decal/cleanable/dirt, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aG" = ( /obj/structure/table/bronze, /obj/item/stack/ore/slag, /turf/open/floor/carpet/black, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aH" = ( /obj/structure/table/bronze, /obj/item/statuebust, /turf/open/floor/carpet/black, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aI" = ( /obj/effect/mob_spawn/human/skeleton, /obj/item/clothing/head/rice_hat, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aJ" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aK" = ( /obj/item/feather, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aL" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/fluff/paper/stack, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aM" = ( /obj/item/stack/sheet/mineral/wood, /obj/item/book/manual/random, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aN" = ( /obj/structure/statue/sandstone/venus, /turf/open/floor/carpet/black, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aO" = ( /mob/living/simple_animal/pet/fox, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aP" = ( /obj/item/keycard/library, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aQ" = ( /obj/effect/decal/cleanable/dirt, /obj/item/paper/fluff/awaymissions/moonoutpost19/research/larva_autopsy, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aR" = ( /obj/structure/fluff/paper/stack, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aS" = ( /obj/structure/table/wood/fancy/black, /obj/effect/decal/cleanable/dirt, @@ -176,39 +176,39 @@ on = 1 }, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aT" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/fluff/paper, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aV" = ( /obj/item/stack/sheet/mineral/wood, /obj/structure/fluff/paper/stack, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aW" = ( /obj/structure/fluff/paper/stack, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aX" = ( /obj/structure/table/bronze, /obj/item/statuebust, /turf/open/floor/plating, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aY" = ( /obj/structure/table_frame/wood, /turf/open/floor/plating, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aZ" = ( /obj/structure/fluff/paper/stack, /obj/structure/fluff/paper, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ba" = ( /obj/structure/barricade/wooden/snowed, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bc" = ( /obj/item/feather, /obj/structure/fluff/paper, @@ -216,81 +216,81 @@ dir = 1 }, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bd" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/fluff/paper{ dir = 1 }, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "be" = ( /obj/structure/fluff/paper{ dir = 5 }, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bf" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/fluff/paper{ dir = 4 }, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bg" = ( /obj/item/paper/fluff/ruins/oldstation/protogun, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bh" = ( /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/pet/fox, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bi" = ( /obj/structure/fluff/paper, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bj" = ( /obj/item/book/manual/random, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bk" = ( /obj/structure/fluff/paper{ dir = 10 }, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bl" = ( /obj/item/storage/box/fountainpens, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bm" = ( /obj/structure/fluff/paper/stack, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bn" = ( /obj/item/book/manual/random, /obj/item/stack/sheet/mineral/wood, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bo" = ( /obj/item/stack/sheet/mineral/wood, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bp" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/fluff/paper, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bq" = ( /obj/structure/mineral_door/wood, /obj/structure/barricade/wooden/crude/snow, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "br" = ( /obj/structure/girder, /turf/closed/mineral/random/snow, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bt" = ( /obj/effect/decal/cleanable/dirt, /turf/template_noop, @@ -305,21 +305,21 @@ "by" = ( /obj/item/statuebust, /turf/open/floor/carpet/black, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bz" = ( /obj/item/flashlight/lantern/jade{ on = 1 }, /turf/open/floor/plating, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bA" = ( /obj/structure/fluff/paper/stack, /turf/open/floor/plating, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bB" = ( /obj/structure/fluff/paper/stack, /turf/open/floor/carpet/black, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bC" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/fluff/paper{ @@ -327,7 +327,7 @@ }, /mob/living/simple_animal/pet/fox, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) (1,1,1) = {" aa diff --git a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm index 0d1e740d13..2e23cf937c 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm @@ -5,14 +5,14 @@ "ad" = ( /obj/structure/flora/ausbushes/leafybush, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "ae" = ( /obj/structure/table, /obj/item/storage/toolbox/mechanical, /obj/item/stack/cable_coil, /obj/item/storage/box/lights/mixed, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "af" = ( /obj/structure/table, /obj/item/clothing/mask/gas, @@ -23,22 +23,22 @@ /obj/item/clothing/glasses/sunglasses/big, /obj/item/clothing/glasses/sunglasses/big, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "ag" = ( /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "ah" = ( /obj/effect/mob_spawn/human/bartender/alive, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "ai" = ( /obj/machinery/portable_atmospherics/canister/oxygen, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aj" = ( /turf/closed/wall/mineral/sandstone, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "ak" = ( /obj/structure/toilet, /obj/effect/turf_decal/sand, @@ -47,27 +47,27 @@ }, /obj/effect/decal/cleanable/vomit/old, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "al" = ( /obj/structure/urinal{ pixel_y = 32 }, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "am" = ( /obj/structure/urinal{ pixel_y = 32 }, /obj/effect/turf_decal/sand, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "an" = ( /obj/item/flashlight/lantern, /obj/machinery/light/small{ dir = 1 }, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "ao" = ( /obj/structure/sink{ dir = 4; @@ -78,71 +78,71 @@ pixel_x = 28 }, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "ap" = ( /obj/structure/flora/ausbushes/sparsegrass, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aq" = ( /obj/structure/flora/ausbushes/sunnybush, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "ar" = ( /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "as" = ( /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "at" = ( /obj/item/tank/internals/oxygen, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "au" = ( /obj/effect/turf_decal/sand, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "av" = ( /obj/machinery/door/airlock/sandstone{ name = "Lavatory" }, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aw" = ( /obj/machinery/door/airlock/sandstone{ name = "Bar Storage" }, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "ax" = ( /obj/structure/extinguisher_cabinet, /turf/closed/wall/mineral/sandstone, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "ay" = ( /obj/effect/turf_decal/sand, /obj/machinery/door/airlock/sandstone{ name = "Restroom" }, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "az" = ( /obj/item/clothing/neck/necklace/dope, /obj/item/reagent_containers/spray/spraytan, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aA" = ( /obj/effect/turf_decal/sand, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aB" = ( /obj/effect/turf_decal/stripes/asteroid/line{ dir = 1 }, /obj/effect/turf_decal/sand, /turf/open/floor/plasteel, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aC" = ( /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aD" = ( /obj/structure/table, /obj/machinery/light{ @@ -150,19 +150,19 @@ }, /obj/machinery/chem_dispenser/drinks, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aE" = ( /obj/structure/table, /obj/machinery/reagentgrinder, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aF" = ( /obj/machinery/vending/boozeomat{ req_access_txt = "0"; set_obj_flags = "EMAGGED" }, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aH" = ( /obj/structure/table, /obj/machinery/light{ @@ -173,12 +173,12 @@ /obj/item/reagent_containers/food/drinks/shaker, /obj/item/reagent_containers/rag, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aI" = ( /obj/structure/table, /obj/machinery/microwave, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aJ" = ( /obj/structure/closet/crate/bin, /obj/item/tank/internals/emergency_oxygen, @@ -189,57 +189,57 @@ }, /obj/effect/turf_decal/sand, /turf/open/floor/plasteel, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aK" = ( /obj/effect/turf_decal/sand, /turf/open/floor/plasteel, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aM" = ( /obj/structure/reagent_dispensers/beerkeg{ reagent_id = /datum/reagent/consumable/ethanol/beer/light }, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aN" = ( /obj/machinery/vending/cigarette/beach, /obj/effect/turf_decal/sand, /turf/open/floor/plasteel, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aO" = ( /obj/structure/weightmachine/stacklifter, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aP" = ( /obj/structure/table/wood, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aQ" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aR" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/bottle/tequila, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aS" = ( /obj/machinery/processor, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aT" = ( /obj/machinery/vending/cola, /obj/effect/turf_decal/sand, /turf/open/floor/plasteel, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aU" = ( /obj/effect/overlay/palmtree_l, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aV" = ( /obj/effect/mob_spawn/human/beach/alive, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aW" = ( /obj/structure/chair/stool, /obj/effect/turf_decal/stripes/asteroid/line{ @@ -247,60 +247,60 @@ }, /obj/effect/turf_decal/sand, /turf/open/floor/plasteel, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aX" = ( /obj/structure/closet/secure_closet/freezer/meat, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aY" = ( /obj/machinery/vending/snack, /obj/effect/turf_decal/sand, /turf/open/floor/plasteel, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "aZ" = ( /obj/effect/overlay/coconut, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bb" = ( /obj/structure/weightmachine/weightlifter, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bc" = ( /obj/machinery/door/airlock/sandstone{ name = "Bar Access" }, /obj/effect/turf_decal/sand, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bd" = ( /obj/structure/closet/secure_closet/freezer/kitchen{ req_access = null }, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "be" = ( /obj/vehicle/ridden/scooter/skateboard{ dir = 4 }, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bg" = ( /obj/structure/sign/barsign, /turf/closed/wall/mineral/sandstone, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bl" = ( /obj/effect/turf_decal/caution, /obj/effect/turf_decal/sand, /turf/open/floor/plasteel, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bx" = ( /obj/structure/flora/rock, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bz" = ( /mob/living/simple_animal/crab, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bA" = ( /obj/structure/window/reinforced{ dir = 1 @@ -313,7 +313,7 @@ /obj/item/storage/firstaid, /obj/item/storage/firstaid/brute, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bB" = ( /obj/structure/window/reinforced{ dir = 4 @@ -324,15 +324,15 @@ }, /obj/structure/chair/stool, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bE" = ( /obj/item/reagent_containers/spray/spraytan, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bF" = ( /obj/item/toy/beach_ball, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bG" = ( /obj/structure/window/reinforced{ dir = 8 @@ -340,22 +340,22 @@ /obj/structure/window/reinforced, /obj/item/megaphone, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bH" = ( /obj/structure/window/reinforced{ dir = 4 }, /obj/effect/mob_spawn/human/beach/alive/lifeguard, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bJ" = ( /obj/structure/chair, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bK" = ( /obj/item/storage/backpack/duffelbag, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bL" = ( /obj/effect/turf_decal/sand{ density = 1 @@ -364,71 +364,71 @@ /turf/open/floor/pod/light{ density = 1 }, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bM" = ( /turf/open/floor/plasteel/stairs/old, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bN" = ( /obj/structure/flora/ausbushes/reedbush, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bO" = ( /obj/item/camera, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bP" = ( /obj/item/reagent_containers/food/drinks/beer/light, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bQ" = ( /obj/structure/flora/ausbushes/reedbush, /turf/open/floor/plating/beach/coastline_t, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bR" = ( /turf/open/floor/plating/beach/coastline_t, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bS" = ( /obj/structure/flora/ausbushes/sparsegrass, /turf/open/floor/plating/beach/coastline_t, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bT" = ( /turf/open/floor/plating/beach/coastline_b, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bU" = ( /turf/open/floor/plating/beach/water, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bV" = ( /obj/structure/flora/ausbushes/stalkybush, /turf/open/floor/plating/beach/water, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "bW" = ( /turf/closed/wall/r_wall, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "cd" = ( /obj/machinery/light/small{ dir = 1 }, /turf/closed/wall/mineral/sandstone, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "ce" = ( /obj/effect/turf_decal/sand, /obj/machinery/light{ dir = 1 }, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "cg" = ( /obj/machinery/light{ dir = 8 }, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "ch" = ( /obj/machinery/light{ dir = 4 }, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "cj" = ( /obj/effect/turf_decal/stripes/asteroid/line{ dir = 1 @@ -438,31 +438,31 @@ }, /obj/effect/turf_decal/sand, /turf/open/floor/plasteel, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "cs" = ( /obj/effect/overlay/palmtree_l, /obj/machinery/light{ dir = 4 }, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "ct" = ( /obj/machinery/light, /turf/open/floor/plating/beach/water, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "cR" = ( /obj/structure/table/wood, /obj/item/tank/internals/oxygen, /obj/item/pickaxe, /obj/item/clothing/mask/gas, /turf/open/floor/pod/dark, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "dw" = ( /obj/machinery/door/airlock/sandstone{ name = "Beach Access" }, /turf/open/floor/pod/dark, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "gg" = ( /obj/structure/table, /obj/item/storage/box/drinkingglasses, @@ -471,23 +471,23 @@ /obj/item/storage/box/donkpockets, /obj/item/soap, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "hY" = ( /obj/structure/table, /obj/machinery/chem_dispenser/drinks/beer, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "iw" = ( /obj/machinery/light/small{ brightness = 3; dir = 8 }, /turf/open/floor/pod/dark, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "jF" = ( /obj/effect/turf_decal/sand, /turf/open/floor/pod/dark, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "lF" = ( /obj/machinery/light{ dir = 4 @@ -495,55 +495,55 @@ /turf/open/floor/pod/dark{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "lM" = ( /obj/structure/dresser, /turf/open/floor/pod/dark, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "mh" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "oK" = ( /obj/effect/turf_decal/caution{ dir = 1 }, /obj/effect/turf_decal/sand, /turf/open/floor/plasteel, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "pg" = ( /obj/effect/turf_decal/sand, /obj/machinery/shower{ dir = 4 }, /turf/open/floor/pod/light, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "pI" = ( /obj/machinery/door/airlock/hatch{ name = "Lava Beach Club" }, /obj/structure/fans/tiny, /turf/open/floor/pod/dark, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "pU" = ( /obj/machinery/light/small{ dir = 4 }, /turf/open/floor/pod/dark, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "qa" = ( /obj/effect/turf_decal/sand, /obj/machinery/light/small{ dir = 4 }, /turf/open/floor/pod/dark, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "qT" = ( /obj/machinery/shower{ dir = 8 }, /turf/open/floor/pod/light, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "rV" = ( /obj/effect/turf_decal/sand, /obj/item/reagent_containers/food/drinks/beer/light{ @@ -551,79 +551,79 @@ pixel_y = -3 }, /turf/open/floor/plating, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "sy" = ( /obj/effect/turf_decal/caution{ dir = 4 }, /obj/effect/turf_decal/sand, /turf/open/floor/plasteel, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "sO" = ( /obj/machinery/jukebox/disco/indestructible, /turf/open/floor/light/colour_cycle, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "vl" = ( /obj/structure/closet/athletic_mixed, /turf/open/floor/pod/dark, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "wY" = ( /turf/open/floor/pod/light, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "yp" = ( /obj/item/reagent_containers/spray/spraytan, /obj/effect/turf_decal/sand, /turf/open/floor/plasteel, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "zw" = ( /obj/structure/closet/athletic_mixed, /obj/effect/turf_decal/sand, /turf/open/floor/pod/dark, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "Bl" = ( /obj/effect/turf_decal/sand, /obj/machinery/light{ dir = 8 }, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "Ec" = ( /obj/machinery/door/airlock/sandstone{ name = "Beach Access" }, /obj/effect/turf_decal/sand, /turf/open/floor/pod/dark, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "Ga" = ( /obj/effect/turf_decal/caution{ dir = 8 }, /obj/effect/turf_decal/sand, /turf/open/floor/plasteel, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "Gc" = ( /obj/effect/turf_decal/sand, /turf/open/floor/pod/light, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "Gu" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/beer/light, /turf/open/floor/wood, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "HC" = ( /obj/structure/rack, /obj/item/clothing/shoes/sandal, /obj/item/clothing/shoes/sandal, /obj/effect/turf_decal/sand, /turf/open/floor/pod/dark, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "QS" = ( /obj/effect/turf_decal/sand, /obj/machinery/light{ dir = 4 }, /turf/open/floor/plating/beach/sand, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "TP" = ( /obj/machinery/light{ dir = 8 @@ -631,10 +631,10 @@ /turf/open/floor/pod/dark{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "VO" = ( /turf/open/floor/pod/dark, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) "Xp" = ( /obj/effect/turf_decal/sand, /obj/machinery/light/small{ @@ -642,7 +642,7 @@ dir = 8 }, /turf/open/floor/pod/dark, -/area/ruin/powered/beach) +/area/ruin/lavaland/powered/beach) (1,1,1) = {" aa diff --git a/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm b/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm index cd512e44b6..7831c53667 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm @@ -7,32 +7,32 @@ dir = 6 }, /turf/closed/wall/r_wall, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "an" = ( /obj/structure/disposalpipe/segment{ dir = 10 }, /turf/closed/wall/r_wall, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "ao" = ( /obj/structure/disposalpipe/segment{ dir = 6 }, /turf/open/floor/plating, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "ap" = ( /obj/structure/disposalpipe/segment{ dir = 10 }, /turf/open/floor/plating, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aq" = ( /obj/structure/disposalpipe/trunk, /obj/structure/disposaloutlet{ dir = 1 }, /turf/open/floor/plating, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "ar" = ( /obj/structure/disposalpipe/segment{ invisibility = 101 @@ -51,7 +51,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "as" = ( /obj/effect/mob_spawn/human/corpse/damaged, /obj/effect/decal/cleanable/blood/old, @@ -72,7 +72,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "at" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -91,27 +91,27 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "au" = ( /obj/structure/disposalpipe/segment{ invisibility = 101 }, /turf/open/floor/plating, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "av" = ( /obj/structure/disposalpipe/sorting/mail/flip{ dir = 1; sortType = 3 }, /turf/closed/wall/r_wall, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aw" = ( /obj/structure/window/reinforced, /obj/structure/disposalpipe/segment{ invisibility = 101 }, /turf/open/floor/plating, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "ax" = ( /obj/effect/decal/cleanable/pie_smudge, /obj/structure/disposalpipe/segment{ @@ -131,7 +131,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "ay" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -151,7 +151,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "az" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -172,7 +172,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aA" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -192,7 +192,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aB" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -211,7 +211,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aC" = ( /obj/effect/turf_decal/tile/yellow, /obj/effect/turf_decal/tile/yellow{ @@ -227,7 +227,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aD" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/yellow, @@ -244,7 +244,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aE" = ( /obj/effect/decal/cleanable/cobweb{ icon_state = "cobweb2" @@ -263,7 +263,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aF" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -284,7 +284,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aG" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -303,7 +303,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aH" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -323,7 +323,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aI" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -343,13 +343,13 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aJ" = ( /obj/structure/disposalpipe/segment{ dir = 5 }, /turf/closed/wall/r_wall, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aK" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -370,14 +370,14 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aL" = ( /obj/structure/disposalpipe/segment{ dir = 4; invisibility = 101 }, /turf/closed/wall/r_wall, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aM" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -396,7 +396,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aO" = ( /obj/item/bikehorn, /obj/structure/disposalpipe/segment{ @@ -417,20 +417,20 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aP" = ( /obj/structure/disposalpipe/segment{ dir = 4; invisibility = 101 }, /turf/open/floor/plating, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aS" = ( /obj/structure/disposalpipe/segment{ dir = 9 }, /turf/open/floor/plating, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aT" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/disposalpipe/segment{ @@ -450,11 +450,11 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aU" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aV" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -474,7 +474,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aW" = ( /obj/item/bikehorn, /obj/effect/decal/cleanable/dirt, @@ -495,7 +495,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aX" = ( /obj/structure/disposalpipe/trunk{ dir = 4 @@ -504,7 +504,7 @@ dir = 8 }, /turf/open/floor/plating, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aY" = ( /obj/item/bikehorn, /obj/structure/disposalpipe/segment{ @@ -524,7 +524,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "aZ" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -544,7 +544,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "ba" = ( /obj/effect/decal/cleanable/pie_smudge, /obj/effect/turf_decal/tile/yellow, @@ -561,7 +561,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bb" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -570,7 +570,7 @@ /turf/open/indestructible{ icon_state = "white" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bc" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -590,7 +590,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bd" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -602,7 +602,7 @@ /turf/open/indestructible{ icon_state = "white" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "be" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -613,7 +613,7 @@ /turf/open/indestructible{ icon_state = "white" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bf" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -633,7 +633,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bg" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -643,7 +643,7 @@ /turf/open/indestructible{ icon_state = "white" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bh" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -651,7 +651,7 @@ /turf/open/indestructible{ icon_state = "white" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bi" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -659,7 +659,7 @@ /turf/open/indestructible{ icon_state = "white" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bj" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -668,7 +668,7 @@ /turf/open/indestructible{ icon_state = "light_on" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bk" = ( /obj/structure/disposalpipe/segment{ invisibility = 101 @@ -680,12 +680,12 @@ /turf/open/indestructible{ icon_state = "white" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bl" = ( /turf/open/indestructible{ icon_state = "light_on" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bm" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -693,7 +693,7 @@ /turf/open/indestructible{ icon_state = "white" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bn" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -701,21 +701,21 @@ /turf/open/indestructible{ icon_state = "white" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bp" = ( /turf/closed/mineral/bananium, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bq" = ( /obj/item/pickaxe, /turf/open/indestructible{ icon_state = "white" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "br" = ( /turf/open/indestructible{ icon_state = "white" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bs" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -734,13 +734,13 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bt" = ( /obj/structure/disposalpipe/segment{ dir = 5 }, /turf/open/floor/plating, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bu" = ( /obj/item/bikehorn, /obj/structure/disposalpipe/segment{ @@ -760,7 +760,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bx" = ( /obj/effect/decal/cleanable/cobweb, /obj/effect/turf_decal/tile/red, @@ -777,7 +777,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "by" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/tile/yellow, @@ -794,7 +794,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bz" = ( /obj/machinery/disposal/deliveryChute{ dir = 1 @@ -803,7 +803,7 @@ /turf/open/indestructible{ icon_state = "white" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bA" = ( /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ @@ -819,7 +819,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bB" = ( /turf/open/indestructible/sound{ icon_state = "bananium"; @@ -827,7 +827,7 @@ sound = 'sound/effects/clownstep1.ogg'; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bC" = ( /obj/structure/disposalpipe/junction/yjunction{ dir = 1; @@ -848,7 +848,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bD" = ( /obj/structure/mecha_wreckage/honker, /obj/structure/disposalpipe/segment{ @@ -856,7 +856,7 @@ invisibility = 101 }, /turf/open/floor/plating, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bE" = ( /obj/effect/decal/cleanable/oil, /obj/structure/disposalpipe/segment{ @@ -864,7 +864,7 @@ }, /obj/item/tcg_card/special/honk, /turf/open/floor/plating, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bF" = ( /obj/effect/decal/cleanable/cobweb{ icon_state = "cobweb2" @@ -875,7 +875,7 @@ sound = 'sound/effects/clownstep1.ogg'; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bH" = ( /obj/effect/decal/cleanable/dirt, /turf/open/indestructible/sound{ @@ -884,7 +884,7 @@ sound = 'sound/effects/clownstep1.ogg'; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bI" = ( /obj/effect/mob_spawn/human/corpse/damaged, /obj/effect/decal/cleanable/blood/old, @@ -902,7 +902,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bK" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -921,22 +921,22 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bL" = ( /obj/item/reagent_containers/food/drinks/trophy/gold_cup, /obj/structure/table/glass, /turf/open/floor/carpet, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bM" = ( /turf/open/floor/carpet, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bN" = ( /obj/machinery/disposal/deliveryChute, /obj/structure/disposalpipe/trunk{ dir = 1 }, /turf/open/floor/carpet, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bO" = ( /obj/effect/decal/cleanable/cobweb, /turf/open/indestructible/sound{ @@ -945,21 +945,21 @@ sound = 'sound/effects/clownstep1.ogg'; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bP" = ( /obj/structure/statue/bananium/clown, /turf/open/floor/carpet, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bQ" = ( /obj/structure/table/glass, /obj/item/grown/bananapeel/bluespace, /turf/open/floor/carpet, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bR" = ( /obj/structure/table/glass, /obj/item/clothing/shoes/clown_shoes/banana_shoes, /turf/open/floor/carpet, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bS" = ( /obj/item/coin/bananium, /obj/item/coin/bananium, @@ -969,21 +969,21 @@ dir = 8 }, /turf/open/floor/carpet, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bT" = ( /obj/structure/table/glass, /obj/item/reagent_containers/spray/waterflower/superlube, /turf/open/floor/carpet, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bU" = ( /obj/item/bikehorn/airhorn, /turf/open/floor/carpet, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bV" = ( /obj/structure/table/glass, /obj/item/gun/magic/staff/honk, /turf/open/floor/carpet, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bW" = ( /obj/item/bikehorn, /turf/open/indestructible/sound{ @@ -992,7 +992,7 @@ sound = 'sound/effects/clownstep1.ogg'; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bY" = ( /obj/effect/mob_spawn/human/corpse/damaged, /obj/effect/decal/cleanable/blood/old, @@ -1002,7 +1002,7 @@ sound = 'sound/effects/clownstep1.ogg'; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "bZ" = ( /obj/machinery/door/airlock/bananium, /turf/open/indestructible/sound{ @@ -1011,7 +1011,7 @@ sound = 'sound/effects/clownstep1.ogg'; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "ca" = ( /obj/item/bikehorn, /obj/effect/decal/cleanable/dirt, @@ -1021,19 +1021,19 @@ sound = 'sound/effects/clownstep1.ogg'; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "cc" = ( /turf/closed/wall/r_wall, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "ch" = ( /obj/structure/disposalpipe/segment{ invisibility = 101 }, /turf/closed/wall/r_wall, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "cu" = ( /turf/open/floor/plating, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "dB" = ( /obj/structure/disposalpipe/segment{ invisibility = 101 @@ -1055,7 +1055,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "dC" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -1078,7 +1078,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "dD" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -1100,7 +1100,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "dE" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -1123,7 +1123,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "dF" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -1136,7 +1136,7 @@ /turf/open/indestructible{ icon_state = "white" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "dG" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -1148,7 +1148,7 @@ /turf/open/indestructible{ icon_state = "white" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "dH" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -1159,7 +1159,7 @@ /turf/open/indestructible{ icon_state = "white" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "dI" = ( /obj/machinery/light{ dir = 1 @@ -1178,13 +1178,13 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "dK" = ( /obj/machinery/light/small{ dir = 1 }, /turf/open/floor/carpet, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "dL" = ( /obj/item/coin/bananium, /obj/item/coin/bananium, @@ -1194,7 +1194,7 @@ dir = 4 }, /turf/open/floor/carpet, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "dM" = ( /obj/machinery/light{ dir = 1 @@ -1205,7 +1205,7 @@ sound = 'sound/effects/clownstep1.ogg'; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "dO" = ( /obj/machinery/light, /turf/open/indestructible/sound{ @@ -1214,7 +1214,7 @@ sound = 'sound/effects/clownstep1.ogg'; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "eX" = ( /obj/effect/mapping_helpers/no_lava, /turf/open/floor/noslip{ @@ -1229,16 +1229,16 @@ /obj/machinery/light, /obj/effect/mapping_helpers/no_lava, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "pv" = ( /obj/machinery/light{ dir = 4 }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "ye" = ( /turf/open/lava/smooth, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "CB" = ( /obj/item/paper/crumpled/bloody/ruins/lavaland/clown_planet/hope, /obj/effect/decal/cleanable/blood/old, @@ -1263,7 +1263,7 @@ icon_state = "darkfull"; wet = 16 }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "KX" = ( /obj/item/grown/bananapeel{ color = "#2F3000"; @@ -1283,7 +1283,7 @@ /turf/open/floor/noslip{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "Mv" = ( /obj/effect/mapping_helpers/no_lava, /mob/living/simple_animal/hostile/retaliate/clown, @@ -1295,7 +1295,7 @@ }, /obj/effect/mapping_helpers/no_lava, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "TD" = ( /obj/structure/disposalpipe/trunk, /obj/structure/disposaloutlet{ @@ -1305,7 +1305,7 @@ /turf/open/floor/noslip{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "Xm" = ( /obj/item/clothing/head/cone, /obj/effect/mapping_helpers/no_lava, @@ -1323,14 +1323,14 @@ }, /obj/effect/mapping_helpers/no_lava, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) "YI" = ( /obj/machinery/light/small, /obj/effect/mapping_helpers/no_lava, /turf/open/floor/noslip{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/powered/clownplanet) +/area/ruin/lavaland/powered/clownplanet) (1,1,1) = {" aa diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_alien_nest.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_alien_nest.dmm index ed882850cf..155ce29fda 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_alien_nest.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_alien_nest.dmm @@ -9,31 +9,31 @@ /obj/structure/alien/resin/wall, /obj/structure/alien/weeds, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "ad" = ( /obj/structure/alien/weeds, /obj/effect/decal/cleanable/blood/gibs, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "ae" = ( /obj/structure/alien/weeds, /mob/living/simple_animal/hostile/alien/maid, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "af" = ( /obj/structure/alien/weeds, /obj/structure/alien/egg/burst, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "ag" = ( /obj/structure/alien/weeds, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "ah" = ( /obj/structure/bed/nest, /obj/structure/alien/weeds, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aj" = ( /obj/structure/alien/weeds, /obj/structure/bed/nest, @@ -41,22 +41,22 @@ /obj/item/storage/backpack/clown, /obj/item/bikehorn, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "ak" = ( /obj/structure/alien/resin/membrane, /obj/structure/alien/weeds, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "al" = ( /obj/structure/alien/weeds, /mob/living/simple_animal/hostile/alien/drone, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "am" = ( /obj/structure/alien/weeds, /obj/structure/bed/nest, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "an" = ( /turf/closed/mineral/volcanic/lava_land_surface, /area/lavaland/surface/outdoors) @@ -64,7 +64,7 @@ /obj/structure/alien/weeds/node, /obj/effect/decal/cleanable/blood, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "ap" = ( /obj/structure/bed/nest, /obj/structure/alien/weeds, @@ -74,73 +74,73 @@ /obj/effect/decal/cleanable/blood/old, /obj/item/clothing/under/syndicate/tacticool, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aq" = ( /obj/structure/alien/weeds, /obj/structure/alien/egg/burst, /obj/effect/decal/cleanable/blood, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "ar" = ( /obj/structure/alien/weeds/node, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "as" = ( /obj/structure/alien/resin/wall, /obj/structure/alien/weeds, /obj/structure/alien/weeds, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "at" = ( /obj/structure/alien/weeds, /obj/structure/alien/resin/wall, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "au" = ( /obj/structure/alien/weeds, /obj/item/grown/bananapeel, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "av" = ( /obj/structure/alien/weeds, /mob/living/simple_animal/hostile/alien/sentinel, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aw" = ( /obj/structure/alien/weeds, /obj/structure/alien/resin/membrane, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "ax" = ( /obj/structure/alien/weeds, /obj/effect/decal/cleanable/blood/gibs, /obj/structure/alien/weeds/node, /mob/living/simple_animal/hostile/alien/drone, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "ay" = ( /obj/structure/stone_tile/slab/cracked, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aA" = ( /obj/structure/alien/weeds, /obj/item/flamethrower, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aB" = ( /obj/structure/alien/weeds, /obj/item/ammo_casing/c45, /obj/effect/decal/cleanable/blood/gibs, /mob/living/simple_animal/hostile/alien/sentinel, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aC" = ( /obj/structure/alien/weeds, /obj/item/ammo_casing/c45{ pixel_x = -6 }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aD" = ( /obj/structure/stone_tile/surrounding_tile{ dir = 1 @@ -151,37 +151,37 @@ }, /obj/structure/stone_tile/center, /turf/open/chasm/lavaland, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aE" = ( /obj/structure/alien/weeds, /obj/effect/decal/cleanable/ash, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aF" = ( /obj/structure/alien/weeds, /mob/living/simple_animal/hostile/alien, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aG" = ( /obj/structure/alien/weeds, /obj/structure/mecha_wreckage/ripley, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aH" = ( /obj/structure/alien/weeds, /obj/effect/decal/cleanable/blood/tracks, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aI" = ( /obj/structure/alien/weeds, /obj/effect/decal/cleanable/vomit/old, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aJ" = ( /obj/structure/alien/weeds, /obj/effect/decal/cleanable/blood, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aK" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 4 @@ -194,17 +194,17 @@ }, /obj/structure/stone_tile/center/cracked, /turf/open/chasm/lavaland, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aL" = ( /obj/structure/alien/weeds, /obj/item/tank/internals/plasma, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aM" = ( /obj/structure/alien/weeds, /obj/effect/decal/cleanable/blood/xeno, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aN" = ( /obj/structure/stone_tile/block{ dir = 8 @@ -214,17 +214,17 @@ }, /obj/structure/stone_tile/cracked, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aO" = ( /obj/structure/alien/weeds, /obj/effect/mob_spawn/alien/corpse/humanoid/sentinel, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aP" = ( /obj/structure/alien/weeds, /obj/effect/mob_spawn/alien/corpse/humanoid/hunter, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aQ" = ( /obj/structure/alien/weeds, /obj/structure/bed/nest, @@ -234,18 +234,18 @@ /obj/item/clothing/mask/breath, /obj/item/flashlight/seclite, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aS" = ( /obj/structure/alien/weeds, /obj/structure/bed/nest, /obj/item/clothing/mask/facehugger/impregnated, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aT" = ( /obj/structure/alien/weeds, /obj/item/chainsaw, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aU" = ( /obj/structure/alien/weeds, /obj/structure/bed/nest, @@ -253,30 +253,30 @@ /obj/item/clothing/head/helmet/gladiator, /obj/item/clothing/mask/facehugger/impregnated, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aV" = ( /obj/structure/alien/weeds, /obj/structure/bed/nest, /obj/item/clothing/mask/facehugger/impregnated, /obj/effect/decal/cleanable/blood, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aW" = ( /obj/structure/alien/resin/wall, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aX" = ( /obj/structure/alien/weeds, /obj/effect/gibspawner/xeno, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "aZ" = ( /turf/closed/indestructible/riveted/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "ba" = ( /obj/structure/stone_tile/slab, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bb" = ( /obj/structure/stone_tile/cracked{ dir = 4 @@ -290,7 +290,7 @@ }, /obj/item/flashlight/lantern, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bc" = ( /obj/structure/stone_tile/block, /obj/structure/stone_tile{ @@ -300,7 +300,7 @@ dir = 4 }, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bd" = ( /obj/structure/stone_tile/block, /obj/structure/stone_tile{ @@ -311,7 +311,7 @@ }, /obj/effect/decal/cleanable/blood/xeno, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "be" = ( /obj/structure/stone_tile/block, /obj/structure/stone_tile{ @@ -321,7 +321,7 @@ dir = 1 }, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bf" = ( /obj/structure/stone_tile, /obj/structure/stone_tile{ @@ -335,12 +335,12 @@ }, /obj/item/flashlight/lantern, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bg" = ( /obj/structure/alien/weeds, /obj/item/clothing/mask/facehugger/dead, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bh" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 @@ -352,7 +352,7 @@ dir = 8 }, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bi" = ( /obj/structure/alien/weeds, /obj/structure/bed/nest, @@ -360,7 +360,7 @@ /obj/item/book_of_babel, /obj/item/clothing/head/wizard/black, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bj" = ( /obj/structure/stone_tile/surrounding_tile/cracked, /obj/structure/stone_tile/surrounding_tile{ @@ -371,11 +371,11 @@ }, /obj/structure/stone_tile/center/cracked, /turf/open/chasm/lavaland, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bk" = ( /obj/structure/stone_tile/block, /turf/open/chasm/lavaland, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bl" = ( /obj/structure/stone_tile/block{ dir = 8 @@ -385,7 +385,7 @@ }, /obj/structure/stone_tile, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bn" = ( /obj/structure/stone_tile/block{ dir = 4 @@ -397,7 +397,7 @@ dir = 4 }, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bo" = ( /obj/structure/stone_tile/surrounding_tile{ dir = 8 @@ -408,10 +408,10 @@ /obj/structure/stone_tile/surrounding_tile, /obj/structure/stone_tile/center, /turf/open/chasm/lavaland, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bq" = ( /turf/open/chasm/lavaland, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "br" = ( /obj/structure/stone_tile/block/cracked{ dir = 8 @@ -422,13 +422,13 @@ }, /obj/effect/decal/cleanable/blood/xeno, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bs" = ( /obj/structure/stone_tile/block{ dir = 8 }, /turf/open/chasm/lavaland, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bw" = ( /obj/structure/stone_tile/cracked{ dir = 4 @@ -442,7 +442,7 @@ }, /obj/item/flashlight/lantern, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bx" = ( /obj/structure/stone_tile/block{ dir = 1 @@ -453,7 +453,7 @@ }, /obj/effect/decal/cleanable/blood/xeno, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "by" = ( /obj/structure/stone_tile/block{ dir = 1 @@ -463,7 +463,7 @@ dir = 8 }, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bz" = ( /obj/structure/stone_tile/block/cracked{ dir = 1 @@ -473,7 +473,7 @@ dir = 8 }, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bA" = ( /obj/structure/stone_tile/cracked{ dir = 1 @@ -487,18 +487,18 @@ /obj/structure/stone_tile, /obj/item/flashlight/lantern, /turf/open/indestructible/boss, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bB" = ( /obj/structure/alien/weeds, /obj/effect/decal/cleanable/blood/old, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "bC" = ( /obj/structure/alien/weeds, /obj/structure/bed/nest, /mob/living/simple_animal/hostile/alien, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "dE" = ( /obj/structure/alien/weeds, /obj/structure/bed/nest, @@ -507,13 +507,13 @@ /obj/item/reagent_containers/hypospray/medipen, /obj/item/clothing/mask/facehugger/impregnated, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "gA" = ( /obj/structure/alien/weeds, /obj/structure/bed/nest, /obj/effect/mob_spawn/alien/corpse/humanoid/sentinel, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "iA" = ( /obj/structure/alien/weeds, /obj/structure/bed/nest, @@ -521,70 +521,70 @@ /obj/item/weldingtool/largetank, /obj/item/clothing/mask/facehugger/impregnated, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "lG" = ( /obj/structure/alien/weeds, /obj/effect/mob_spawn/alien/corpse/humanoid/drone, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "lM" = ( /obj/structure/stone_tile/block{ dir = 4 }, /turf/open/chasm/lavaland, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "nj" = ( /obj/effect/mob_spawn/alien/corpse/humanoid/praetorian, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "tY" = ( /obj/structure/alien/weeds/node, /obj/effect/mob_spawn/alien/corpse/humanoid/hunter, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "wA" = ( /obj/structure/alien/weeds, /obj/structure/alien/weeds/node, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "yf" = ( /obj/structure/alien/weeds/node, /mob/living/simple_animal/hostile/alien/sentinel, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "zj" = ( /obj/structure/stone_tile/block/cracked{ dir = 1 }, /turf/open/chasm/lavaland, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "Dd" = ( /obj/structure/alien/weeds, /obj/effect/decal/cleanable/blood/gibs, /obj/item/storage/backpack/duffelbag/sec/surgery, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "Ha" = ( /obj/structure/alien/weeds, /obj/item/reagent_containers/syringe/alien, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "JM" = ( /obj/structure/alien/weeds/node, /obj/effect/mob_spawn/alien/corpse/humanoid/drone, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "QG" = ( /obj/structure/alien/weeds, /obj/structure/bed/nest, /obj/structure/alien/weeds/node, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "Uh" = ( /obj/structure/alien/weeds, /obj/item/xenos_claw, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "Vi" = ( /obj/structure/bed/nest, /obj/structure/alien/weeds, @@ -593,16 +593,16 @@ /obj/item/radio/headset/headset_cargo/mining, /obj/item/clothing/mask/facehugger/impregnated, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "VZ" = ( /obj/structure/alien/weeds, /obj/effect/gibspawner/human, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) "ZT" = ( /obj/effect/mob_spawn/human/corpse/syndicatesoldier, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/xenonest) +/area/ruin/lavaland/unpowered/xenonest) (1,1,1) = {" aa diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm index 527a328563..aad53a4507 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm @@ -19,18 +19,18 @@ /area/lavaland/surface/outdoors) "ae" = ( /turf/closed/wall/mineral/titanium/nodiagonal, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "af" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "ag" = ( /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "ah" = ( /obj/structure/toilet, /obj/effect/turf_decal/tile/bar, @@ -38,7 +38,7 @@ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "ai" = ( /obj/machinery/vending/coffee, /obj/effect/turf_decal/tile/blue{ @@ -48,7 +48,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aj" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp, @@ -59,7 +59,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "ak" = ( /obj/structure/table/wood, /obj/item/taperecorder, @@ -71,7 +71,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "al" = ( /obj/structure/table/wood, /obj/item/toy/plush/carpplushie, @@ -82,7 +82,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "am" = ( /obj/machinery/vending/snack, /obj/effect/turf_decal/tile/blue{ @@ -92,7 +92,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "an" = ( /obj/machinery/sleeper{ dir = 4 @@ -101,10 +101,10 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "ao" = ( /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "ap" = ( /obj/structure/table, /obj/item/circular_saw, @@ -112,7 +112,7 @@ pixel_y = 12 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aq" = ( /obj/structure/table, /obj/item/cautery{ @@ -120,13 +120,13 @@ }, /obj/item/surgicaldrill, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "ar" = ( /obj/structure/table, /obj/item/surgical_drapes, /obj/item/razor, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "as" = ( /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -135,7 +135,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "at" = ( /obj/structure/chair/office/dark{ dir = 1 @@ -147,7 +147,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "au" = ( /obj/structure/chair/office/dark{ dir = 4 @@ -159,7 +159,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "av" = ( /obj/item/reagent_containers/rag, /obj/item/reagent_containers/spray/cleaner, @@ -170,14 +170,14 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aw" = ( /obj/structure/bed/roller, /obj/machinery/light{ dir = 4 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "ax" = ( /obj/structure/closet/crate/trashcart, /obj/item/storage/bag/trash, @@ -203,7 +203,7 @@ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "az" = ( /obj/structure/noticeboard{ dir = 1; @@ -217,27 +217,27 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aA" = ( /obj/structure/closet/secure_closet/medical2, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aB" = ( /obj/machinery/computer/operating{ dir = 4 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aC" = ( /obj/structure/table/optable, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aD" = ( /obj/structure/table, /obj/item/retractor, /obj/item/hemostat, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aF" = ( /obj/machinery/door/airlock/shuttle{ name = "Restroom" @@ -247,11 +247,11 @@ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aG" = ( /obj/structure/extinguisher_cabinet, /turf/closed/wall/mineral/titanium/nodiagonal, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aJ" = ( /turf/open/floor/plasteel/grimy{ initial_gas_mix = "o2=14;n2=23;TEMP=300" @@ -259,7 +259,7 @@ /area/lavaland/surface/outdoors) "aK" = ( /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aL" = ( /obj/effect/turf_decal/tile/blue{ dir = 1 @@ -268,7 +268,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aN" = ( /obj/structure/closet/crate/freezer, /obj/item/reagent_containers/blood/random, @@ -285,7 +285,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aO" = ( /obj/machinery/iv_drip, /obj/effect/turf_decal/tile/blue{ @@ -295,27 +295,27 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aP" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aQ" = ( /obj/effect/turf_decal/tile/blue{ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aR" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aS" = ( /obj/effect/turf_decal/tile/blue{ dir = 1 @@ -324,7 +324,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aT" = ( /obj/structure/closet, /obj/effect/decal/cleanable/cobweb, @@ -339,41 +339,41 @@ dir = 8 }, /turf/open/floor/plating, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aU" = ( /turf/open/floor/plating, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aV" = ( /obj/structure/closet/secure_closet/medical1, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aW" = ( /obj/machinery/vending/wallmed{ pixel_y = 28 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aX" = ( /obj/item/stack/cable_coil/random, /obj/item/stack/sheet/mineral/titanium{ amount = 30 }, /turf/open/floor/plating, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aY" = ( /obj/structure/bodycontainer/morgue, /turf/open/floor/plating, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "aZ" = ( /obj/effect/decal/cleanable/ash, /turf/open/floor/plating, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "ba" = ( /obj/structure/table/glass, /obj/item/reagent_containers/glass/beaker, /obj/item/storage/backpack/duffelbag/med, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bb" = ( /obj/structure/table/reinforced, /obj/item/laser_pointer, @@ -381,12 +381,12 @@ dir = 4 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bc" = ( /obj/structure/table/reinforced, /obj/item/storage/firstaid/regular, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bd" = ( /obj/structure/table/glass, /obj/item/storage/box/gloves, @@ -398,43 +398,43 @@ dir = 4 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "be" = ( /obj/effect/decal/cleanable/oil, /obj/item/storage/toolbox/mechanical, /turf/open/floor/plating, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bf" = ( /obj/structure/table, /obj/item/storage/fancy/cigarettes/dromedaryco, /obj/item/storage/box/matches, /turf/open/floor/plating, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bg" = ( /mob/living/simple_animal/cockroach, /turf/open/floor/plating, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bh" = ( /obj/structure/table/glass, /obj/item/storage/firstaid/brute, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bi" = ( /obj/item/toy/cattoy, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bj" = ( /obj/structure/table/glass, /obj/item/lazarus_injector, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bk" = ( /obj/structure/reagent_dispensers/fueltank, /obj/item/flashlight/glowstick/blue, /obj/item/flashlight/glowstick/blue, /obj/item/flashlight/glowstick/blue, /turf/open/floor/plating, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bl" = ( /obj/structure/table, /obj/item/reagent_containers/food/snacks/cookie{ @@ -465,7 +465,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bm" = ( /obj/structure/chair/comfy/teal{ dir = 8 @@ -477,19 +477,19 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bn" = ( /obj/machinery/sleeper{ dir = 4 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bo" = ( /obj/machinery/light/small{ dir = 1 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bp" = ( /obj/structure/closet/crate/bin, /obj/item/trash/pistachios, @@ -502,24 +502,24 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bq" = ( /obj/structure/filingcabinet/chestdrawer/wheeled, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "br" = ( /obj/structure/chair/office/dark, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bs" = ( /obj/structure/table/reinforced, /obj/item/phone, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bt" = ( /obj/item/kirbyplants, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bu" = ( /obj/structure/chair/comfy/teal{ dir = 8 @@ -529,19 +529,19 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bv" = ( /obj/effect/mob_spawn/human/doctor/alive/lavaland{ dir = 4 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bx" = ( /obj/machinery/door/airlock/medical{ name = "Rejuvenation Pods" }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "by" = ( /obj/structure/table/reinforced, /obj/item/flashlight/lamp, @@ -552,23 +552,23 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bz" = ( /obj/structure/table/reinforced, /obj/item/clothing/glasses/regular, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bA" = ( /obj/structure/table/reinforced, /obj/item/paper_bin, /obj/item/pen/fourcolor, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bB" = ( /obj/structure/table/reinforced, /obj/item/storage/box/hug, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bD" = ( /mob/living/simple_animal/bot/medbot{ desc = "A little medical robot. It's programmed to only act in emergencies."; @@ -576,7 +576,7 @@ name = "emergency Medibot" }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bE" = ( /obj/structure/closet/crate/critter, /obj/effect/turf_decal/tile/blue{ @@ -586,7 +586,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bF" = ( /obj/effect/turf_decal/tile/blue{ dir = 1 @@ -596,7 +596,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bG" = ( /obj/structure/chair/comfy/teal{ dir = 8 @@ -609,7 +609,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bH" = ( /obj/structure/table, /obj/item/tank/internals/oxygen, @@ -621,20 +621,20 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bI" = ( /obj/structure/sign/departments/medbay/alt{ name = "animal hospital" }, /turf/closed/wall/mineral/titanium/nodiagonal, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bJ" = ( /obj/machinery/door/airlock/glass_large{ name = "Ian's Pet Care" }, /obj/structure/fans/tiny/invisible, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bL" = ( /obj/vehicle/ridden/scooter/skateboard{ dir = 4 @@ -659,11 +659,11 @@ /obj/structure/table/glass, /obj/item/storage/firstaid/fire, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bQ" = ( /obj/machinery/light/small, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bR" = ( /obj/structure/table, /obj/machinery/cell_charger, @@ -680,7 +680,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bS" = ( /obj/structure/closet, /obj/item/defibrillator/loaded, @@ -696,7 +696,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bT" = ( /obj/item/pickaxe, /obj/effect/decal/cleanable/blood/old, @@ -716,7 +716,7 @@ "bW" = ( /obj/structure/fans/tiny/invisible, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "bX" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 6 @@ -758,25 +758,25 @@ "cc" = ( /obj/machinery/atmospherics/pipe/simple/general/visible, /turf/closed/wall/mineral/titanium/nodiagonal, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cd" = ( /obj/structure/table/reinforced, /obj/item/clothing/gloves/color/latex, /obj/item/clothing/mask/surgical, /obj/item/clothing/suit/apron/surgical, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "ce" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 1 }, /obj/machinery/portable_atmospherics/pump, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cf" = ( /obj/structure/closet/l3closet, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cg" = ( /obj/machinery/door/airlock/shuttle{ name = "Break Room" @@ -788,13 +788,13 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "ch" = ( /obj/machinery/door/airlock/shuttle{ name = "Operating Theatre" }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "ci" = ( /obj/structure/fans/tiny/invisible, /obj/machinery/door/airlock/shuttle{ @@ -802,31 +802,31 @@ name = "Staff Entrance" }, /turf/open/floor/plating, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cj" = ( /obj/machinery/door/airlock/shuttle{ name = "Morgue" }, /turf/open/floor/plating, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "ck" = ( /obj/machinery/door/airlock/shuttle{ name = "Medical Supplies" }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cl" = ( /obj/machinery/door/airlock/shuttle{ name = "Safety Supplies" }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cm" = ( /obj/machinery/door/airlock/shuttle{ name = "Storage" }, /turf/open/floor/plating, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cn" = ( /obj/machinery/light, /turf/open/floor/grass{ @@ -849,7 +849,7 @@ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cr" = ( /obj/machinery/light/small{ dir = 8 @@ -861,7 +861,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cs" = ( /obj/machinery/light/small{ dir = 4 @@ -873,7 +873,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cv" = ( /obj/machinery/light/small{ dir = 1 @@ -885,7 +885,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cw" = ( /obj/machinery/light/small, /obj/effect/turf_decal/tile/blue, @@ -893,7 +893,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cx" = ( /obj/machinery/light{ dir = 4 @@ -911,7 +911,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cz" = ( /obj/machinery/light{ dir = 1 @@ -923,7 +923,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cC" = ( /obj/machinery/light{ dir = 1 @@ -960,7 +960,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cH" = ( /mob/living/simple_animal/bot/cleanbot, /obj/effect/turf_decal/tile/blue, @@ -968,12 +968,12 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cI" = ( /obj/structure/table/glass, /obj/item/storage/firstaid/toxin, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) "cJ" = ( /obj/machinery/sleeper{ dir = 4 @@ -982,7 +982,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/animal_hospital) +/area/ruin/lavaland/powered/animal_hospital) (1,1,1) = {" aa diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm index 2d13b2743e..a94190e03b 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm @@ -59,7 +59,7 @@ /area/lavaland/surface/outdoors) "ak" = ( /turf/closed/indestructible/riveted/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "al" = ( /obj/structure/stone_tile/surrounding_tile{ dir = 1 @@ -76,7 +76,7 @@ }, /obj/effect/decal/cleanable/blood, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "an" = ( /obj/structure/stone_tile/surrounding_tile/cracked, /obj/structure/stone_tile/center, @@ -89,13 +89,13 @@ /turf/open/lava/smooth{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "ao" = ( /obj/structure/stone_tile/block/cracked, /turf/open/lava/smooth{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "ap" = ( /obj/structure/stone_tile/surrounding_tile/cracked, /obj/structure/stone_tile/surrounding_tile/cracked{ @@ -108,7 +108,7 @@ /turf/open/lava/smooth{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aq" = ( /obj/structure/stone_tile/block/cracked{ dir = 8 @@ -129,7 +129,7 @@ /area/lavaland/surface/outdoors) "as" = ( /turf/closed/wall/mineral/wood, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "at" = ( /obj/structure/stone_tile/block{ dir = 8 @@ -152,7 +152,7 @@ }, /obj/item/flashlight/lantern, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "av" = ( /obj/structure/stone_tile/block, /obj/structure/stone_tile{ @@ -162,7 +162,7 @@ dir = 4 }, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aw" = ( /obj/structure/stone_tile/block, /obj/structure/stone_tile{ @@ -173,7 +173,7 @@ }, /obj/effect/decal/cleanable/blood, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "ax" = ( /obj/structure/stone_tile/block, /obj/structure/stone_tile/cracked{ @@ -183,7 +183,7 @@ dir = 4 }, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "ay" = ( /obj/structure/stone_tile, /obj/structure/stone_tile{ @@ -197,7 +197,7 @@ }, /obj/item/flashlight/lantern, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "az" = ( /obj/structure/stone_tile/block{ dir = 4 @@ -212,7 +212,7 @@ /obj/item/disk/tech_disk/illegal, /obj/structure/safe, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aB" = ( /obj/structure/stone_tile/block/cracked, /obj/structure/stone_tile{ @@ -220,12 +220,12 @@ }, /obj/item/t_scanner/adv_mining_scanner/lesser, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aC" = ( /obj/structure/stone_tile/block/cracked, /obj/item/storage/toolbox/syndicate, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aD" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 @@ -233,7 +233,7 @@ /turf/open/lava/smooth{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aE" = ( /obj/structure/stone_tile{ dir = 4 @@ -246,7 +246,7 @@ /obj/item/reagent_containers/blood/lizard, /obj/item/stack/sheet/cloth/ten, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aF" = ( /obj/structure/stone_tile/block{ dir = 8 @@ -264,13 +264,13 @@ dir = 8 }, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aH" = ( /obj/structure/lavaland/ash_walker, /turf/open/lava/smooth{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aI" = ( /obj/structure/stone_tile/block{ dir = 8 @@ -278,7 +278,7 @@ /turf/open/lava/smooth{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aJ" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 4 @@ -291,7 +291,7 @@ /turf/open/lava/smooth{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aK" = ( /obj/structure/stone_tile/block/cracked{ dir = 8 @@ -302,7 +302,7 @@ /obj/structure/stone_tile, /mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aL" = ( /obj/structure/stone_tile/block{ dir = 1 @@ -310,32 +310,32 @@ /turf/open/lava/smooth{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aM" = ( /obj/structure/stone_tile/cracked{ dir = 4 }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aN" = ( /obj/structure/stone_tile{ dir = 1 }, /obj/item/weldingtool/experimental, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aO" = ( /obj/structure/stone_tile/surrounding/cracked{ dir = 1; icon_state = "cracked_surrounding1" }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aP" = ( /obj/structure/stone_tile, /obj/item/shard, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aQ" = ( /obj/structure/stone_tile/block{ dir = 8 @@ -343,7 +343,7 @@ /obj/machinery/iv_drip, /obj/item/reagent_containers/glass/beaker/waterbottle/large, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aR" = ( /obj/structure/stone_tile/block{ dir = 8 @@ -365,7 +365,7 @@ }, /obj/effect/decal/cleanable/blood, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aT" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 8 @@ -380,7 +380,7 @@ /turf/open/lava/smooth{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aW" = ( /obj/structure/stone_tile/block{ dir = 8 @@ -390,7 +390,7 @@ dir = 1 }, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aY" = ( /obj/structure/stone_tile, /obj/structure/stone_tile{ @@ -403,7 +403,7 @@ dir = 1 }, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "aZ" = ( /obj/structure/stone_tile/cracked{ dir = 4 @@ -416,7 +416,7 @@ }, /obj/effect/decal/cleanable/blood, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "ba" = ( /obj/structure/stone_tile/cracked{ dir = 8 @@ -425,7 +425,7 @@ dir = 4 }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bc" = ( /obj/structure/stone_tile/block{ dir = 4 @@ -438,7 +438,7 @@ }, /mob/living/simple_animal/hostile/asteroid/gutlunch/guthen, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bg" = ( /obj/structure/stone_tile/block{ dir = 8 @@ -448,7 +448,7 @@ }, /obj/structure/stone_tile, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bh" = ( /obj/structure/stone_tile/block{ dir = 4 @@ -478,7 +478,7 @@ /obj/item/seeds/cotton, /obj/item/seeds/cotton/durathread, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bk" = ( /obj/structure/stone_tile{ dir = 4 @@ -492,13 +492,13 @@ }, /obj/item/stack/marker_beacon/ten, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bl" = ( /obj/structure/stone_tile/cracked{ dir = 1 }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bm" = ( /obj/structure/stone_tile{ dir = 1 @@ -512,7 +512,7 @@ }, /obj/item/construction/rcd/loaded/upgraded, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bn" = ( /obj/structure/closet/crate/radiation, /obj/item/flashlight/lantern, @@ -526,7 +526,7 @@ dir = 1 }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bo" = ( /obj/structure/stone_tile/block{ dir = 8 @@ -548,7 +548,7 @@ }, /obj/item/flashlight/lantern, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bq" = ( /obj/structure/stone_tile/block{ dir = 1 @@ -558,11 +558,11 @@ dir = 8 }, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "br" = ( /obj/structure/stone_tile/slab/cracked, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bs" = ( /obj/structure/stone_tile/block/cracked{ dir = 1 @@ -573,7 +573,7 @@ /obj/structure/stone_tile, /obj/effect/decal/cleanable/blood, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bt" = ( /obj/structure/stone_tile, /obj/structure/stone_tile{ @@ -587,7 +587,7 @@ }, /obj/item/flashlight/lantern, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bv" = ( /obj/structure/stone_tile/cracked{ dir = 8 @@ -597,7 +597,7 @@ /obj/item/flashlight/lantern, /obj/item/flashlight/lantern, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bw" = ( /obj/structure/stone_tile/block{ dir = 1 @@ -613,12 +613,12 @@ /obj/item/seeds/tower, /obj/item/seeds/tower, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bx" = ( /obj/structure/stone_tile/slab/cracked, /obj/effect/decal/cleanable/blood, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "by" = ( /obj/structure/closet/crate, /obj/structure/stone_tile/block/cracked{ @@ -632,7 +632,7 @@ /obj/item/flashlight/lantern, /obj/item/flashlight/lantern, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bz" = ( /obj/structure/stone_tile{ dir = 4 @@ -646,7 +646,7 @@ }, /obj/machinery/the_singularitygen, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bA" = ( /obj/structure/stone_tile/block{ dir = 8 @@ -662,7 +662,7 @@ dir = 8 }, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bC" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 @@ -674,7 +674,7 @@ dir = 4 }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bE" = ( /obj/structure/stone_tile/surrounding_tile{ dir = 8 @@ -690,7 +690,7 @@ /area/lavaland/surface/outdoors) "bG" = ( /turf/closed/indestructible/riveted/boss/see_through, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "bI" = ( /obj/structure/stone_tile/slab/cracked, /turf/closed/mineral/volcanic/lava_land_surface, @@ -994,7 +994,7 @@ dir = 8 }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "cy" = ( /obj/structure/stone_tile{ dir = 8 @@ -1014,14 +1014,14 @@ }, /obj/item/spear, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "cA" = ( /obj/structure/stone_tile/slab/cracked{ dir = 4; icon_state = "cracked_slab1" }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "cB" = ( /obj/structure/stone_tile, /obj/structure/stone_tile{ @@ -1035,18 +1035,18 @@ }, /obj/effect/decal/cleanable/blood, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "cD" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 }, /obj/item/flashlight/lantern, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "cE" = ( /obj/structure/stone_tile/surrounding/cracked, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "cF" = ( /obj/structure/stone_tile/block{ dir = 8 @@ -1059,7 +1059,7 @@ /obj/item/spear, /obj/item/storage/belt, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "cI" = ( /obj/structure/stone_tile/cracked{ dir = 4 @@ -1101,7 +1101,7 @@ /obj/item/spear, /obj/item/scythe, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "cM" = ( /obj/structure/stone_tile/block{ dir = 1 @@ -1113,7 +1113,7 @@ /obj/structure/table/wood, /obj/item/kitchen/knife/combat/bone, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "cN" = ( /obj/structure/stone_tile, /obj/structure/stone_tile{ @@ -1129,7 +1129,7 @@ /obj/item/spear, /obj/item/clothing/head/helmet/roman/legionnaire, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "cO" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 8 @@ -1169,14 +1169,14 @@ }, /obj/item/surgical_drapes, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "cX" = ( /obj/item/storage/box/rxglasses, /obj/structure/stone_tile{ dir = 1 }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "cY" = ( /obj/item/seeds/glowshroom, /obj/item/seeds/glowshroom, @@ -1184,7 +1184,7 @@ dir = 4 }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "cZ" = ( /obj/structure/stone_tile/surrounding_tile{ dir = 8 diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_bathhouse.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_bathhouse.dmm index a4b572a2ee..a231d06d36 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_bathhouse.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_bathhouse.dmm @@ -4,14 +4,14 @@ /area/template_noop) "b" = ( /turf/closed/wall/mineral/silver, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "c" = ( /obj/machinery/shower{ pixel_y = 16 }, /obj/structure/curtain, /turf/open/floor/plasteel/white, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "e" = ( /obj/structure/mirror{ pixel_y = 28 @@ -20,40 +20,40 @@ pixel_y = 20 }, /turf/open/floor/plasteel/white, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "f" = ( /obj/structure/table/greyscale, /obj/item/bikehorn/rubberducky, /turf/open/floor/plasteel/white, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "g" = ( /turf/open/floor/plasteel/white, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "h" = ( /obj/item/soap, /turf/open/floor/plasteel/white, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "i" = ( /obj/machinery/door/airlock/freezer{ name = "bath house airlock" }, /turf/open/floor/plasteel/white, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "j" = ( /turf/closed/wall/mineral/wood, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "k" = ( /turf/open/floor/wood, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "l" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/meatballspaghetti, /turf/open/floor/wood, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "m" = ( /obj/structure/bookcase/random, /turf/open/floor/wood, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) "n" = ( /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) @@ -61,7 +61,7 @@ /obj/structure/bed, /obj/item/bedsheet, /turf/open/floor/wood, -/area/ruin/powered/bathhouse) +/area/ruin/lavaland/powered/bathhouse) (1,1,1) = {" b diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm index c7ae4c6eb4..63c557b8a8 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm @@ -7,7 +7,7 @@ /obj/structure/table, /obj/item/stack/medical/suture, /turf/open/floor/plating, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "ad" = ( /obj/structure/table, /obj/item/stack/medical/gauze, @@ -16,98 +16,98 @@ dir = 1 }, /turf/open/floor/plating, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "ae" = ( /obj/machinery/power/smes, /turf/open/floor/plating, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "af" = ( /turf/open/floor/plating, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "ag" = ( /obj/structure/reagent_dispensers/beerkeg, /obj/machinery/light/small{ dir = 1 }, /turf/open/floor/plating, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "ah" = ( /obj/item/reagent_containers/food/drinks/mug, /turf/open/floor/plating, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "ai" = ( /obj/machinery/shower, /turf/open/floor/plating, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aj" = ( /obj/structure/sink, /obj/machinery/light/small{ dir = 1 }, /turf/open/floor/plating, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "ak" = ( /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "al" = ( /obj/effect/decal/cleanable/oil, /turf/open/floor/plating, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "am" = ( /obj/machinery/door/airlock/hatch, /turf/open/floor/plating, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "an" = ( /obj/structure/toilet{ dir = 8 }, /turf/open/floor/plating, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "ao" = ( /turf/open/floor/plating/ice{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "ap" = ( /obj/structure/flora/rock/icy, /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aq" = ( /turf/closed/wall/mineral/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "ar" = ( /obj/machinery/door/airlock/wood, /turf/open/floor/plating, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "as" = ( /obj/structure/fans, /turf/closed/wall/mineral/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "at" = ( /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "au" = ( /obj/structure/bed, /obj/item/bedsheet/blue, /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "av" = ( /obj/structure/bookcase/random, /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aw" = ( /obj/structure/table/wood, /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "ax" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/beans, /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "ay" = ( /obj/structure/closet/crate/trashcart, /obj/item/trash/semki, @@ -115,92 +115,92 @@ /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "az" = ( /obj/structure/flora/tree/pine, /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aA" = ( /obj/structure/chair/comfy/brown{ dir = 4 }, /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aB" = ( /obj/structure/flora/rock/pile/icy, /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aC" = ( /obj/structure/flora/tree/dead, /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aD" = ( /obj/machinery/door/airlock/wood, /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aE" = ( /obj/structure/extinguisher_cabinet, /turf/closed/wall/mineral/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aF" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/mug/coco, /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aG" = ( /obj/structure/chair/comfy/brown{ dir = 8 }, /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aH" = ( /mob/living/simple_animal/hostile/skeleton/eskimo, /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aI" = ( /obj/structure/flora/bush, /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aJ" = ( /obj/vehicle/ridden/atv, /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aL" = ( /obj/structure/displaycase/captain, /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aM" = ( /turf/open/floor/carpet, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aN" = ( /obj/structure/bed/dogbed, /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aO" = ( /obj/machinery/door/airlock/glass_large, /obj/structure/fans/tiny, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aP" = ( /obj/structure/fans/tiny, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aQ" = ( /obj/structure/flora/grass/both, /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "aR" = ( /obj/structure/flora/tree/pine/xmas, /obj/item/a_gift{ @@ -212,13 +212,13 @@ /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "bl" = ( /turf/open/floor/wood{ initial_gas_mix = "o2=22;n2=82;TEMP=180"; name = "bridge" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "bv" = ( /obj/machinery/light{ dir = 1 @@ -226,20 +226,20 @@ /turf/open/floor/plating/ice{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "bw" = ( /obj/machinery/light/small{ brightness = 3; dir = 8 }, /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "bx" = ( /obj/machinery/light{ dir = 4 }, /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "by" = ( /obj/machinery/light{ dir = 8 @@ -247,11 +247,11 @@ /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "bz" = ( /obj/machinery/light, /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "bB" = ( /obj/machinery/light{ dir = 4 @@ -259,7 +259,7 @@ /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "bD" = ( /obj/machinery/light{ dir = 1 @@ -267,50 +267,50 @@ /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "bM" = ( /obj/machinery/light, /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "bN" = ( /obj/machinery/light, /turf/open/floor/plating/ice{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "dS" = ( /obj/machinery/light/small, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "eb" = ( /obj/machinery/light/small{ dir = 4 }, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "eg" = ( /obj/machinery/vending/coffee, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "gh" = ( /obj/machinery/light/small{ brightness = 3; dir = 8 }, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "gy" = ( /obj/item/toy/snowball, /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "gz" = ( /obj/structure/chair/stool, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "hA" = ( /obj/machinery/light/built{ dir = 1 @@ -319,7 +319,7 @@ /turf/open/floor/pod/dark{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "qt" = ( /obj/machinery/door/airlock/silver, /obj/structure/fans/tiny, @@ -327,69 +327,69 @@ dir = 8 }, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "rl" = ( /obj/structure/flora/bush, /obj/item/toy/snowball, /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "tb" = ( /obj/effect/mapping_helpers/no_lava, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors/explored) "tl" = ( /turf/open/floor/pod/light, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "xU" = ( /obj/item/storage/toolbox/mechanical, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "zT" = ( /obj/machinery/door/airlock/silver, /obj/structure/fans/tiny, /turf/open/floor/plating, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "AM" = ( /obj/structure/table, /obj/item/pen, /obj/item/paper, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "Dd" = ( /obj/structure/rack, /obj/item/clothing/suit/hooded/wintercoat/science, /obj/item/clothing/shoes/winterboots, /obj/item/clothing/gloves/fingerless, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "Ef" = ( /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "Ez" = ( /obj/structure/fans/tiny, /obj/machinery/door/airlock/glass_large, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "HP" = ( /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "HR" = ( /obj/structure/closet/secure_closet/freezer/fridge, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "IQ" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/mug, /turf/open/floor/wood, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "JZ" = ( /obj/structure/table, /obj/machinery/microwave, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "KS" = ( /obj/item/chainsaw, /obj/structure/closet, @@ -397,16 +397,16 @@ dir = 4 }, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "Mp" = ( /obj/item/clothing/mask/balaclava, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "Oj" = ( /obj/structure/table, /obj/item/reagent_containers/food/drinks/mug, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "PD" = ( /obj/machinery/door/airlock/hatch, /obj/structure/fans/tiny, @@ -414,13 +414,13 @@ dir = 4 }, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "PK" = ( /obj/structure/table, /obj/item/pen, /obj/item/paper_bin, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "Qa" = ( /obj/effect/mapping_helpers/no_lava, /obj/effect/mapping_helpers/no_lava, @@ -434,35 +434,35 @@ /obj/item/storage/fancy/cigarettes/cigpack_carp, /obj/item/reagent_containers/food/drinks/mug, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "QN" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "Sj" = ( /obj/effect/decal/cleanable/oil, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "SL" = ( /obj/structure/flora/grass/both, /obj/item/toy/snowball, /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "Ub" = ( /obj/structure/filingcabinet, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "UM" = ( /obj/machinery/computer/monitor/secret{ dir = 1 }, /turf/open/floor/pod/dark, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) "Wg" = ( /turf/closed/wall/r_wall, -/area/ruin/powered/snow_biodome) +/area/ruin/lavaland/powered/snow_biodome) (1,1,1) = {" aa diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm index 7c166a1a56..444984d88c 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm @@ -6,41 +6,41 @@ /turf/open/floor/engine/cult{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "c" = ( /turf/open/lava/smooth/lava_land_surface, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "d" = ( /turf/closed/wall/mineral/cult, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "e" = ( /obj/effect/decal/remains/human, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "f" = ( /obj/structure/destructible/cult/pylon, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "g" = ( /obj/effect/decal/cleanable/blood/old, /turf/open/floor/engine/cult{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "i" = ( /obj/effect/decal/remains/human, /obj/effect/decal/cleanable/blood/old, /turf/open/floor/engine/cult{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "k" = ( /obj/effect/decal/remains/human, /obj/item/melee/cultblade, /turf/open/floor/engine/cult{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "l" = ( /obj/effect/decal/remains/human, /obj/item/clothing/shoes/cult, @@ -48,13 +48,13 @@ /turf/open/floor/engine/cult{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "m" = ( /obj/effect/decal/remains/human, /turf/open/floor/engine/cult{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "o" = ( /obj/effect/rune/narsie{ color = "#ff0000"; @@ -76,7 +76,7 @@ /turf/open/floor/engine/cult{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "q" = ( /obj/effect/decal/remains/human, /obj/item/clothing/shoes/cult, @@ -85,10 +85,10 @@ /turf/open/floor/engine/cult{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "s" = ( /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) (1,1,1) = {" a diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_elephant_graveyard.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_elephant_graveyard.dmm index f590af752b..08bc2f35dd 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_elephant_graveyard.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_elephant_graveyard.dmm @@ -7,74 +7,74 @@ /area/lavaland/surface) "ac" = ( /turf/closed/mineral/volcanic/lava_land_surface, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ad" = ( /obj/effect/decal/cleanable/cobweb, /obj/structure/closet/crate/grave/lead_researcher, /obj/effect/decal/cleanable/blood/gibs/old, /obj/effect/mob_spawn/human/skeleton, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ae" = ( /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "af" = ( /obj/effect/decal/cleanable/blood/drip, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ag" = ( /obj/effect/decal/cleanable/vomit, /obj/item/shovel, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ah" = ( /obj/effect/decal/cleanable/blood/old, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ai" = ( /obj/effect/decal/cleanable/blood/tracks{ dir = 4 }, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aj" = ( /obj/effect/decal/cleanable/blood/tracks{ dir = 4 }, /obj/item/paper/fluff/ruins/elephant_graveyard/final_message, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ak" = ( /turf/open/floor/plating/asteroid/basalt/wasteland{ icon_state = "wasteland_dug" }, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "al" = ( /obj/effect/mapping_helpers/network_builder/power_cable, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "am" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/effect/mapping_helpers/network_builder/power_cable, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "an" = ( /obj/item/reagent_containers/food/snacks/deadmouse, /obj/item/assembly/mousetrap, /turf/open/floor/plating/asteroid/basalt/wasteland{ icon_state = "wasteland_dug" }, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ao" = ( /obj/structure/statue/bone/skull/half, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ap" = ( /obj/structure/statue/bone/skull/half{ dir = 1 }, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aq" = ( /obj/item/reagent_containers/glass/bottle/frostoil{ desc = "A small bottle. Contains cold sauce. There's a label on here: APPLY ON SEVERE BURNS."; @@ -82,11 +82,11 @@ }, /obj/effect/mapping_helpers/network_builder/power_cable, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ar" = ( /obj/structure/flora/rock, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "as" = ( /obj/structure/flora/rock, /obj/item/pickaxe{ @@ -96,7 +96,7 @@ }, /obj/effect/mapping_helpers/network_builder/power_cable, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "at" = ( /turf/closed/mineral/strong/wasteland, /area/lavaland/surface) @@ -105,47 +105,47 @@ /obj/item/t_scanner/adv_mining_scanner/lesser, /obj/effect/mapping_helpers/network_builder/power_cable, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "av" = ( /obj/structure/barricade/wooden/crude, /obj/structure/barricade/wooden, /obj/effect/decal/cleanable/blood/splatter, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aw" = ( /obj/structure/table, /obj/item/paper/crumpled/muddy/fluff/elephant_graveyard/rnd_notes, /obj/effect/mapping_helpers/network_builder/power_cable, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ax" = ( /obj/structure/statue/bone/rib{ dir = 1 }, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ay" = ( /obj/structure/statue/bone/rib, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "az" = ( /obj/structure/table, /obj/item/pen, /obj/item/pen, /obj/item/pen, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aA" = ( /turf/closed/wall, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aB" = ( /obj/item/chair, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aC" = ( /obj/effect/decal/remains/human, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aD" = ( /obj/structure/table, /obj/item/reagent_containers/glass/bottle/plasma{ @@ -153,80 +153,80 @@ }, /obj/effect/mapping_helpers/network_builder/power_cable, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aE" = ( /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aF" = ( /obj/structure/table, /obj/machinery/power/floodlight, /obj/effect/mapping_helpers/network_builder/power_cable, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aG" = ( /obj/structure/table, /obj/effect/spawner/lootdrop/glowstick, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aH" = ( /turf/closed/wall/mineral/titanium, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "aI" = ( /obj/effect/spawner/structure/window/shuttle, /obj/structure/grille, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "aJ" = ( /obj/structure/table, /obj/item/clipboard, /obj/effect/mapping_helpers/network_builder/power_cable, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aK" = ( /obj/item/cigbutt, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aL" = ( /obj/structure/table, /obj/item/paper_bin, /obj/effect/mapping_helpers/network_builder/power_cable, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aM" = ( /obj/structure/table, /obj/item/clothing/gloves/color/black, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aN" = ( /turf/closed/wall/mineral/titanium/nodiagonal, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "aO" = ( /obj/effect/decal/cleanable/glass, /obj/machinery/computer, /turf/open/floor/mineral/titanium/white, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "aP" = ( /obj/structure/bed, /obj/item/flashlight/lantern, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aQ" = ( /obj/machinery/power/floodlight, /obj/effect/mapping_helpers/network_builder/power_cable, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aR" = ( /obj/structure/table, /obj/item/taperecorder, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aS" = ( /obj/structure/table, /obj/item/tape/random, /obj/item/tape/random, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aT" = ( /obj/structure/closet/crate/bin, /obj/item/trash/candle, @@ -235,124 +235,124 @@ /obj/effect/decal/cleanable/dirt/dust, /obj/item/cigbutt, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aU" = ( /obj/structure/bed, /obj/item/bedsheet/brown, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aV" = ( /obj/structure/bed, /obj/item/bedsheet/brown, /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aW" = ( /obj/structure/filingcabinet/chestdrawer, /obj/item/clothing/mask/gas/explorer/folded, /turf/open/floor/mineral/titanium/white, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "aX" = ( /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aY" = ( /obj/structure/sign/warning/nosmoking/circle, /turf/closed/wall, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "aZ" = ( /obj/item/organ/brain, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ba" = ( /obj/structure/headpike/bone, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bb" = ( /obj/effect/decal/cleanable/oil/streak, /obj/effect/decal/cleanable/glass, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bc" = ( /obj/structure/sign/poster/ripped, /turf/closed/wall, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bd" = ( /obj/item/organ/heart, /obj/item/organ/eyes, /obj/item/organ/ears, /obj/effect/decal/cleanable/blood/gibs/old, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "be" = ( /obj/item/organ/lungs, /obj/item/organ/liver, /obj/effect/decal/cleanable/blood/old, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bf" = ( /turf/closed/mineral/strong/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bg" = ( /obj/structure/sign/warning/securearea, /turf/closed/wall/mineral/titanium, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "bh" = ( /obj/effect/decal/cleanable/oil, /obj/structure/chair/office/light, /turf/open/floor/mineral/titanium/white, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "bi" = ( /obj/effect/turf_decal/delivery/white, /turf/open/floor/circuit/off, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "bj" = ( /obj/structure/barricade/wooden, /obj/structure/mineral_door/wood, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bk" = ( /obj/item/kitchen/knife/combat/bone, /obj/item/organ/tongue, /obj/effect/decal/cleanable/blood/old, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bl" = ( /obj/effect/decal/cleanable/shreds, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bm" = ( /obj/structure/closet/wardrobe/curator, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bn" = ( /obj/structure/sink/oil_well, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bo" = ( /obj/item/stack/medical/gauze/improvised, /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bp" = ( /turf/open/floor/mineral/titanium/white, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "bq" = ( /obj/machinery/iv_drip, /turf/open/floor/mineral/titanium/white, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "br" = ( /obj/structure/sign/warning/nosmoking/circle, /turf/closed/wall/mineral/titanium, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "bs" = ( /obj/structure/fence/door, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bt" = ( /obj/structure/table, /turf/closed/mineral/strong/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bu" = ( /obj/structure/bed, /obj/item/trash/pistachios, @@ -360,54 +360,54 @@ /obj/item/bedsheet/brown, /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bv" = ( /obj/effect/decal/remains/human, /obj/item/clothing/under/misc/overalls, /obj/item/clothing/mask/bandana/green, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bw" = ( /obj/structure/rack, /obj/item/shovel, /obj/item/wrench, /obj/effect/mapping_helpers/network_builder/power_cable, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bx" = ( /obj/item/reagent_containers/food/snacks/deadmouse, /obj/item/assembly/mousetrap, /obj/effect/mapping_helpers/network_builder/power_cable, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "by" = ( /obj/structure/closet/emcloset, /obj/item/light/bulb, /obj/effect/turf_decal/box/white, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "bz" = ( /obj/item/paper/crumpled/muddy/fluff/elephant_graveyard/mutiny, /obj/item/cigbutt, /obj/item/cigbutt, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bA" = ( /obj/machinery/suit_storage_unit/mining/eva, /obj/effect/turf_decal/box/white, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "bB" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bC" = ( /obj/structure/barricade/sandbags, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bD" = ( /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bE" = ( /obj/structure/shuttle/engine/heater, /obj/structure/window{ @@ -415,17 +415,17 @@ }, /obj/effect/decal/cleanable/cobweb/cobweb2, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "bF" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bG" = ( /obj/effect/decal/remains/human, /obj/item/tank/internals/emergency_oxygen/empty, /obj/effect/decal/cleanable/blood/old, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bH" = ( /obj/item/paper/fluff/ruins/elephant_graveyard, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, @@ -433,70 +433,70 @@ "bI" = ( /obj/structure/shuttle/engine/propulsion, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "bJ" = ( /obj/structure/sign/warning/xeno_mining, /turf/closed/wall, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bK" = ( /obj/structure/sign/warning/explosives, /turf/closed/wall, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bL" = ( /obj/effect/decal/cleanable/blood/gibs/old, /obj/effect/decal/cleanable/blood/splatter, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bM" = ( /obj/item/storage/fancy/cigarettes/cigpack_mindbreaker, /obj/structure/closet/crate/grave, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bN" = ( /obj/structure/sign/warning/securearea, /obj/structure/sign/warning/securearea, /turf/closed/mineral/strong/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bO" = ( /obj/item/paper/fluff/ruins/elephant_graveyard, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bP" = ( /obj/structure/barricade/wooden/crude, /obj/item/paper/fluff/ruins/elephant_graveyard, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bQ" = ( /obj/structure/filingcabinet/chestdrawer, /obj/effect/decal/cleanable/cobweb, /obj/item/paper/fluff/ruins/elephant_graveyard/hypothesis, /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/mineral/titanium/white, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "bR" = ( /obj/effect/decal/cleanable/generic, /obj/item/cigbutt, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bS" = ( /obj/effect/decal/cleanable/oil/slippery, /obj/machinery/rnd/destructive_analyzer, /turf/open/floor/mineral/titanium/white, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "bT" = ( /obj/structure/barricade/wooden, /obj/item/paper/fluff/ruins/elephant_graveyard, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bU" = ( /obj/item/light/bulb/broken, /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/mineral/titanium/white, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "bV" = ( /obj/effect/decal/cleanable/dirt, /turf/closed/mineral/volcanic/lava_land_surface, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bW" = ( /obj/effect/decal/cleanable/glass, /obj/effect/decal/cleanable/dirt/dust, @@ -504,19 +504,19 @@ name = "archaeology shuttle airlock" }, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "bX" = ( /obj/effect/decal/remains/human, /obj/effect/decal/cleanable/dirt/dust, /obj/item/clothing/head/fedora/curator, /obj/item/clothing/suit/curator, /turf/open/floor/mineral/titanium/white, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "bY" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/item/cigbutt, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "bZ" = ( /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface) @@ -524,84 +524,84 @@ /obj/structure/table, /obj/item/storage/firstaid/o2, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "cb" = ( /obj/machinery/power/port_gen/pacman, /obj/effect/mapping_helpers/network_builder/power_cable, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "cc" = ( /obj/effect/decal/remains/human, /obj/effect/decal/cleanable/blood/old, /obj/effect/decal/cleanable/shreds, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "cd" = ( /obj/item/trash/can, /obj/structure/bedsheetbin/empty, /obj/structure/table, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ce" = ( /obj/structure/stone_tile/slab/cracked, /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "cf" = ( /obj/structure/bed, /obj/item/wirecutters, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "cg" = ( /obj/structure/stone_tile/center/cracked, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ch" = ( /obj/effect/decal/remains/human, /obj/item/restraints/handcuffs/cable/zipties/used, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ci" = ( /obj/structure/stone_tile/surrounding_tile, /turf/open/floor/plating/asteroid/basalt/wasteland{ icon_state = "wasteland_dug" }, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "cj" = ( /obj/structure/stone_tile/block/cracked, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ck" = ( /obj/structure/reagent_dispensers/water_cooler, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "cl" = ( /obj/structure/closet/crate/grave, /obj/effect/mob_spawn/human/skeleton, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "cm" = ( /obj/structure/table/optable, /obj/item/storage/backpack/explorer, /obj/item/reagent_containers/food/drinks/soda_cans/cola, /obj/item/restraints/handcuffs/cable/zipties/used, /turf/open/floor/mineral/titanium/white, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "cn" = ( /obj/structure/stone_tile/cracked, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "co" = ( /obj/effect/decal/cleanable/blood/drip, /obj/structure/stone_tile/cracked, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "cq" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 }, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "cr" = ( /obj/structure/bonfire/prelit, /obj/effect/decal/cleanable/ash, @@ -609,42 +609,42 @@ /obj/effect/decal/cleanable/blood/old, /obj/structure/stone_tile/slab/cracked, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "cs" = ( /obj/structure/ore_box, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "ct" = ( /obj/structure/stone_tile, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "cu" = ( /obj/structure/stone_tile{ dir = 8 }, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "cv" = ( /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/mineral/titanium/white, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "cw" = ( /obj/structure/closet/crate/grave, /obj/effect/decal/cleanable/dirt/dust, /obj/effect/mob_spawn/human/skeleton, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) "cx" = ( /obj/item/light/bulb/broken, /obj/effect/turf_decal/caution/stand_clear/white, /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/mineral/titanium/purple, -/area/ruin/powered/graveyard_shuttle) +/area/ruin/lavaland/powered/graveyard_shuttle) "cz" = ( /obj/structure/stone_tile, /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating/asteroid/basalt/wasteland, -/area/ruin/unpowered/elephant_graveyard) +/area/ruin/lavaland/unpowered/elephant_graveyard) (1,1,1) = {" aa diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_envy.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_envy.dmm index e7fa30c601..6e10d1dd76 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_envy.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_envy.dmm @@ -10,7 +10,7 @@ /area/lavaland/surface/outdoors) "d" = ( /turf/closed/wall/rust, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "f" = ( /obj/structure/mirror{ broken = 1; @@ -21,7 +21,7 @@ /obj/item/clothing/suit/hooded/bloated_human, /obj/effect/decal/cleanable/blood, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "g" = ( /obj/effect/decal/cleanable/blood/tracks, /obj/structure/mirror{ @@ -31,18 +31,18 @@ pixel_x = -28 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "h" = ( /obj/effect/decal/cleanable/blood, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "i" = ( /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "j" = ( /obj/effect/decal/cleanable/blood/splatter, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "k" = ( /obj/structure/mirror{ broken = 1; @@ -53,7 +53,7 @@ /turf/open/floor/plating{ icon_state = "panelscorched" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "l" = ( /obj/structure/mirror{ broken = 1; @@ -62,7 +62,7 @@ pixel_x = 28 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "m" = ( /obj/structure/mirror{ broken = 1; @@ -71,12 +71,12 @@ pixel_x = -28 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "n" = ( /turf/open/floor/plating{ icon_state = "platingdmg2" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "o" = ( /obj/structure/mirror{ broken = 1; @@ -87,11 +87,11 @@ /turf/open/floor/plating{ icon_state = "platingdmg1" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "p" = ( /obj/machinery/door/airlock/hatch, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "A" = ( /obj/effect/mapping_helpers/no_lava, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, @@ -105,7 +105,7 @@ }, /obj/item/kitchen/knife/envy, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) (1,1,1) = {" a diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm index 70ffdc85cd..5aeb8d8da1 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm @@ -10,115 +10,115 @@ /area/lavaland/surface/outdoors) "e" = ( /turf/open/lava/smooth, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "f" = ( /obj/item/reagent_containers/syringe/gluttony, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "g" = ( /obj/effect/gluttony, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "h" = ( /obj/item/trash/boritos, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "i" = ( /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "j" = ( /obj/item/trash/plate, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "l" = ( /obj/item/trash/candy, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "m" = ( /obj/item/trash/raisins, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "n" = ( /obj/item/trash/pistachios, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "o" = ( /obj/item/trash/popcorn, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "p" = ( /obj/item/trash/semki, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "q" = ( /obj/item/trash/syndi_cakes, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "r" = ( /obj/effect/gluttony, /obj/machinery/light/small{ dir = 1 }, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "t" = ( /obj/machinery/light/small{ dir = 1 }, /obj/item/trash/plate/alt, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "v" = ( /obj/machinery/light/small, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "z" = ( /obj/item/trash/plate, /obj/machinery/light/small{ dir = 8 }, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "A" = ( /obj/machinery/light/small{ dir = 4 }, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "B" = ( /obj/item/veilrender/vealrender, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "E" = ( /obj/machinery/light/small, /obj/item/trash/cheesie, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "G" = ( /obj/item/trash/waffles, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "L" = ( /obj/machinery/light/small, /obj/item/trash/plate/alt, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "N" = ( /obj/item/trash/cheesie, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "R" = ( /turf/closed/indestructible/riveted/uranium, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "S" = ( /obj/machinery/door/airlock/uranium, /obj/structure/fans/tiny/invisible, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) "Z" = ( /obj/item/trash/plate/alt, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/gluttony) +/area/ruin/lavaland/powered/gluttony) (1,1,1) = {" a diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_greed.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_greed.dmm index 671fdd54d6..26aebb4a4d 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_greed.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_greed.dmm @@ -17,11 +17,11 @@ /turf/open/floor/carpet{ icon_state = "carpetsymbol" }, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "f" = ( /obj/structure/cursed_slot_machine, /turf/open/floor/carpet/black, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "g" = ( /obj/structure/table/wood/poker, /obj/item/coin/mythril, @@ -31,48 +31,48 @@ /turf/open/floor/carpet{ icon_state = "carpetsymbol" }, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "h" = ( /obj/structure/table/wood/poker, /obj/item/coin/diamond, /turf/open/floor/carpet{ icon_state = "carpetsymbol" }, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "j" = ( /obj/structure/table/wood/poker, /obj/item/coin/adamantine, /turf/open/floor/carpet{ icon_state = "carpetsymbol" }, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "k" = ( /obj/machinery/computer/arcade/battle{ set_obj_flags = "EMAGGED" }, /turf/open/floor/carpet/black, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "l" = ( /obj/item/coin/gold, /turf/open/floor/carpet/black, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "m" = ( /turf/open/floor/carpet/black, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "n" = ( /obj/structure/table/wood/poker, /obj/item/stack/spacecash/c1000, /turf/open/floor/carpet, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "o" = ( /obj/item/storage/bag/money, /turf/open/floor/carpet/black, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "p" = ( /obj/structure/table/wood/poker, /obj/item/stack/ore/gold, /turf/open/floor/carpet, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "q" = ( /obj/structure/table/wood/poker, /obj/item/stack/spacecash/c20, @@ -82,19 +82,19 @@ dir = 8 }, /turf/open/floor/carpet, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "r" = ( /obj/structure/table/wood/poker, /obj/item/stack/spacecash/c500, /obj/item/stack/spacecash/c100, /obj/item/stack/spacecash/c1000, /turf/open/floor/carpet, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "s" = ( /obj/structure/table/wood/poker, /obj/item/stack/spacecash/c200, /turf/open/floor/carpet, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "u" = ( /obj/structure/table/wood/poker, /obj/item/stack/spacecash/c500, @@ -104,30 +104,30 @@ dir = 4 }, /turf/open/floor/carpet, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "v" = ( /obj/item/coin/gold, /obj/machinery/light/small, /turf/open/floor/carpet/black, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "w" = ( /obj/item/storage/bag/money, /obj/machinery/light/small, /turf/open/floor/carpet/black, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "H" = ( /turf/open/floor/carpet/purple, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "J" = ( /obj/machinery/door/airlock/gold, /obj/structure/fans/tiny/invisible, /turf/open/floor/carpet/purple, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) "W" = ( /turf/closed/wall/mineral/cult{ sheet_amount = 0 }, -/area/ruin/powered/greed) +/area/ruin/lavaland/powered/greed) (1,1,1) = {" a diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm index 4e16f9a174..6f1aaac226 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm @@ -4,57 +4,57 @@ /area/lavaland/surface/outdoors) "b" = ( /turf/closed/mineral/volcanic/lava_land_surface, -/area/ruin/powered) +/area/ruin/lavaland/powered) "c" = ( /turf/closed/wall/mineral/iron, -/area/ruin/powered) +/area/ruin/lavaland/powered) "d" = ( /obj/item/clothing/head/helmet/space/orange, /obj/item/clothing/mask/breath, /turf/open/floor/plating/asteroid/basalt, -/area/ruin/powered) +/area/ruin/lavaland/powered) "e" = ( /obj/item/clothing/suit/space/orange, /turf/open/floor/plating/asteroid/basalt, -/area/ruin/powered) +/area/ruin/lavaland/powered) "f" = ( /turf/open/floor/plating/asteroid/basalt, -/area/ruin/powered) +/area/ruin/lavaland/powered) "g" = ( /turf/open/floor/plating/asteroid{ name = "dirt" }, -/area/ruin/powered) +/area/ruin/lavaland/powered) "h" = ( /obj/item/shovel, /turf/open/floor/plating/asteroid{ name = "dirt" }, -/area/ruin/powered) +/area/ruin/lavaland/powered) "i" = ( /obj/item/reagent_containers/glass/bucket, /turf/open/floor/plating/asteroid{ name = "dirt" }, -/area/ruin/powered) +/area/ruin/lavaland/powered) "j" = ( /obj/structure/sink/puddle, /turf/open/floor/plating/asteroid{ name = "dirt" }, -/area/ruin/powered) +/area/ruin/lavaland/powered) "k" = ( /obj/structure/glowshroom/single, /turf/open/floor/plating/asteroid{ name = "dirt" }, -/area/ruin/powered) +/area/ruin/lavaland/powered) "l" = ( /obj/item/storage/toolbox/emergency, /turf/open/floor/plating/asteroid{ name = "dirt" }, -/area/ruin/powered) +/area/ruin/lavaland/powered) "m" = ( /obj/structure/rack, /obj/item/seeds/reishi, @@ -62,79 +62,79 @@ /obj/item/seeds/plump, /obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom, /turf/open/floor/plating/asteroid/basalt, -/area/ruin/powered) +/area/ruin/lavaland/powered) "n" = ( /obj/machinery/hydroponics/soil, /turf/open/floor/plating, -/area/ruin/powered) +/area/ruin/lavaland/powered) "o" = ( /turf/open/floor/plating, -/area/ruin/powered) +/area/ruin/lavaland/powered) "p" = ( /obj/structure/rack, /obj/item/storage/bag/plants/portaseeder, /obj/item/storage/bag/ore, /obj/item/storage/firstaid/regular, /turf/open/floor/plating/asteroid/basalt, -/area/ruin/powered) +/area/ruin/lavaland/powered) "q" = ( /obj/structure/glowshroom/single, /turf/open/floor/plating, -/area/ruin/powered) +/area/ruin/lavaland/powered) "r" = ( /obj/structure/rack, /obj/item/pickaxe/emergency, /obj/item/tank/internals/oxygen, /turf/open/floor/plating/asteroid/basalt, -/area/ruin/powered) +/area/ruin/lavaland/powered) "s" = ( /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "t" = ( /turf/closed/wall/mineral/titanium/survival/pod, -/area/ruin/powered) +/area/ruin/lavaland/powered) "u" = ( /obj/structure/bed/pod, /obj/item/bedsheet/black, /turf/open/floor/plating, -/area/ruin/powered) +/area/ruin/lavaland/powered) "v" = ( /obj/structure/fans, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "w" = ( /obj/machinery/smartfridge/survival_pod, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "x" = ( /obj/effect/mob_spawn/human/hermit, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "y" = ( /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "z" = ( /obj/machinery/light/small{ dir = 4 }, /obj/structure/tubes, /turf/open/floor/plating, -/area/ruin/powered) +/area/ruin/lavaland/powered) "A" = ( /obj/structure/table, /obj/item/kitchen/knife/combat/survival, /turf/open/floor/plating, -/area/ruin/powered) +/area/ruin/lavaland/powered) "B" = ( /obj/structure/table/survival_pod, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "C" = ( /obj/structure/tubes, /obj/item/crowbar, /obj/effect/decal/cleanable/blood/drip, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "D" = ( /obj/effect/decal/cleanable/blood/footprints{ dir = 1; @@ -143,37 +143,37 @@ /obj/machinery/door/airlock/survival_pod/glass, /obj/structure/fans/tiny, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "E" = ( /obj/structure/shuttle/engine/propulsion/burst{ dir = 8 }, /turf/closed/wall/mineral/titanium/interior, -/area/ruin/powered) +/area/ruin/lavaland/powered) "F" = ( /turf/closed/wall/mineral/titanium, -/area/ruin/powered) +/area/ruin/lavaland/powered) "G" = ( /turf/closed/wall/mineral/titanium/interior, -/area/ruin/powered) +/area/ruin/lavaland/powered) "H" = ( /obj/machinery/door/airlock/titanium{ name = "Escape Pod Airlock" }, /turf/open/floor/mineral/titanium/blue, -/area/ruin/powered) +/area/ruin/lavaland/powered) "I" = ( /obj/structure/chair{ dir = 4 }, /turf/open/floor/mineral/titanium/blue, -/area/ruin/powered) +/area/ruin/lavaland/powered) "J" = ( /obj/effect/spawner/structure/window/shuttle, /turf/open/floor/plating{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/powered) +/area/ruin/lavaland/powered) (1,1,1) = {" a diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_hierophant.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_hierophant.dmm index c307c2caae..1a9bc28f2d 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_hierophant.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_hierophant.dmm @@ -1,35 +1,35 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( /turf/closed/indestructible/riveted/hierophant, -/area/ruin/unpowered/hierophant) +/area/ruin/lavaland/unpowered/hierophant) "b" = ( /turf/open/indestructible/hierophant, -/area/ruin/unpowered/hierophant) +/area/ruin/lavaland/unpowered/hierophant) "c" = ( /obj/effect/light_emitter{ set_cap = 3; set_luminosity = 5 }, /turf/open/indestructible/hierophant, -/area/ruin/unpowered/hierophant) +/area/ruin/lavaland/unpowered/hierophant) "d" = ( /mob/living/simple_animal/hostile/megafauna/hierophant, /turf/open/indestructible/hierophant/two, -/area/ruin/unpowered/hierophant) +/area/ruin/lavaland/unpowered/hierophant) "e" = ( /turf/open/indestructible/hierophant/two, -/area/ruin/unpowered/hierophant) +/area/ruin/lavaland/unpowered/hierophant) "f" = ( /obj/effect/light_emitter{ set_cap = 3; set_luminosity = 5 }, /turf/open/indestructible/hierophant/two, -/area/ruin/unpowered/hierophant) +/area/ruin/lavaland/unpowered/hierophant) "s" = ( /obj/item/tcg_card/special/hierophant, /turf/open/indestructible/hierophant, -/area/ruin/unpowered/hierophant) +/area/ruin/lavaland/unpowered/hierophant) (1,1,1) = {" a diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_library.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_library.dmm index d1dcf9f11d..a21ea5f9dd 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_library.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_library.dmm @@ -7,149 +7,145 @@ /obj/item/documents/syndicate/mining, /obj/effect/decal/cleanable/cobweb, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ac" = ( /turf/closed/wall/mineral/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ad" = ( /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "ae" = ( /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "af" = ( /obj/item/stack/sheet/mineral/wood, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ag" = ( /obj/item/feather, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ah" = ( /obj/structure/bookcase/random, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ai" = ( /obj/structure/table/wood/fancy/black, /obj/item/paper/crumpled/fluff/stations/lavaland/library/diary2, /obj/effect/decal/cleanable/cobweb/cobweb2, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "al" = ( /turf/closed/wall/mineral/iron, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "am" = ( /obj/structure/table/wood/fancy/black, /obj/item/book_of_babel, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ao" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ap" = ( /obj/item/stack/sheet/mineral/wood, /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aq" = ( /obj/structure/bookcase/random, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ar" = ( /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "as" = ( /obj/effect/decal/cleanable/dirt, /obj/item/paper/fluff/ruins/oldstation/protosing, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) -"av" = ( -/obj/structure/bookcase/random, -/turf/open/space/basic, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aw" = ( /turf/open/floor/plating, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ay" = ( /obj/machinery/door/keycard/library, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "az" = ( /obj/item/paper/crumpled/fluff/stations/lavaland/library/diary, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aA" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aC" = ( /obj/item/feather, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aD" = ( /turf/open/floor/carpet/black, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aE" = ( /obj/item/stack/sheet/mineral/wood, /obj/item/book/manual/random, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aF" = ( /obj/item/book/manual/random, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aG" = ( /obj/structure/table/bronze, /obj/item/stack/ore/slag, /turf/open/floor/carpet/black, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aH" = ( /obj/structure/table/bronze, /obj/item/statuebust, /turf/open/floor/carpet/black, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aI" = ( /obj/effect/mob_spawn/human/skeleton, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aJ" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aK" = ( /obj/item/feather, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aL" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/fluff/paper/stack, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aM" = ( /obj/item/stack/sheet/mineral/wood, /obj/item/book/manual/random, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aN" = ( /obj/structure/statue/sandstone/venus, /turf/open/floor/carpet/black, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aP" = ( /obj/item/keycard/library, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aQ" = ( /obj/effect/decal/cleanable/dirt, /obj/item/paper/fluff/awaymissions/moonoutpost19/research/larva_autopsy, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aR" = ( /obj/structure/fluff/paper/stack, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aS" = ( /obj/structure/table/wood/fancy/black, /obj/effect/decal/cleanable/dirt, @@ -158,75 +154,74 @@ on = 1 }, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aV" = ( /obj/item/stack/sheet/mineral/wood, /obj/structure/fluff/paper/stack, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aW" = ( /obj/structure/fluff/paper/stack, /turf/open/floor/plasteel/cult, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aX" = ( /obj/structure/table/bronze, /obj/item/statuebust, /turf/open/floor/plating, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "aY" = ( /obj/structure/table_frame/wood, /turf/open/floor/plating, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "ba" = ( /obj/structure/barricade/wooden/crude, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bg" = ( /obj/item/paper/fluff/ruins/oldstation/protogun, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bh" = ( /obj/effect/decal/cleanable/dirt, /mob/living/simple_animal/pet/fox, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bi" = ( /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bj" = ( /obj/item/book/manual/random, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bl" = ( /obj/item/storage/box/fountainpens, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bm" = ( /obj/structure/fluff/paper/stack, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bn" = ( /obj/item/book/manual/random, /obj/item/stack/sheet/mineral/wood, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bo" = ( /obj/item/stack/sheet/mineral/wood, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bp" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bq" = ( /obj/structure/mineral_door/wood, -/obj/structure/barricade/wooden/crude/snow, /turf/open/floor/wood, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "br" = ( /obj/structure/girder, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bt" = ( /obj/effect/decal/cleanable/dirt, /turf/template_noop, @@ -241,21 +236,21 @@ "by" = ( /obj/item/statuebust, /turf/open/floor/carpet/black, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bz" = ( /obj/item/flashlight/lantern/jade{ on = 1 }, /turf/open/floor/plating, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bA" = ( /obj/structure/fluff/paper/stack, /turf/open/floor/plating, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) "bB" = ( /obj/structure/fluff/paper/stack, /turf/open/floor/carpet/black, -/area/ruin/unpowered/buried_library) +/area/ruin/lavaland/unpowered/buried_library) (1,1,1) = {" aa @@ -369,7 +364,7 @@ bi aC ae aQ -aq +ah bi aq bg @@ -394,7 +389,7 @@ ae bi aM ae -aq +ah bm aq aA @@ -440,7 +435,7 @@ aa ad bi bi -av +aq aA bi aG @@ -465,7 +460,7 @@ aa ad ac as -av +aq aF aD aD @@ -550,7 +545,7 @@ aD bi ae bm -ah +aq ag br ac @@ -573,9 +568,9 @@ ae af bp bi -ah +aq bi -ah +aq bp ac ad @@ -596,9 +591,9 @@ ah ao ah az -ah +aq bi -ah +aq bi bn ao @@ -621,7 +616,7 @@ ah aA ah ao -ah +aq bi bi bl @@ -646,7 +641,7 @@ ah ao aV bi -ah +aq bp bi bm diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_mining_site.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_mining_site.dmm index b4f7fec16f..6161bd8b86 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_mining_site.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_mining_site.dmm @@ -1,7 +1,7 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "b" = ( /turf/closed/wall/mineral/wood/nonmetal, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "c" = ( /obj/structure/closet/toolcloset, /obj/item/wrench, @@ -11,7 +11,7 @@ /obj/item/wirecutters, /obj/item/radio/off, /turf/open/floor/wood, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "d" = ( /turf/open/openspace/icemoon, /area/template_noop) @@ -25,14 +25,14 @@ /obj/structure/closet, /obj/item/clothing/shoes/jackboots, /turf/open/floor/wood, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "f" = ( /turf/open/floor/wood, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "g" = ( /obj/structure/fireplace, /turf/open/floor/wood, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "h" = ( /obj/structure/flora/ash/cacti, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, @@ -43,33 +43,40 @@ "j" = ( /obj/structure/sink/kitchen, /turf/open/floor/wood, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "k" = ( /obj/structure/closet/crate/freezer, /turf/open/floor/wood, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "l" = ( /obj/machinery/vending/dinnerware, /turf/open/floor/wood, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "m" = ( -/obj/structure/barricade/wooden/crude/snow, /obj/structure/mineral_door/wood, +/obj/effect/decal/cleanable/trail_holder{ + color = "#dc0000"; + dir = 8 + }, /turf/open/floor/wood, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "n" = ( /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "o" = ( /obj/item/reagent_containers/food/drinks/beer, /turf/open/floor/wood, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "p" = ( /obj/machinery/light/broken{ dir = 4 }, +/obj/effect/decal/cleanable/trail_holder{ + color = "#dc0000"; + dir = 6 + }, /turf/open/floor/wood, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "q" = ( /obj/structure/table/wood, /obj/item/pen, @@ -81,7 +88,7 @@ text = "" }, /turf/open/floor/wood, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "r" = ( /obj/item/chair/wood, /obj/effect/decal/cleanable/blood/splatter, @@ -90,11 +97,35 @@ dir = 8 }, /turf/open/floor/wood, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "s" = ( -/obj/effect/decal/cleanable/trail_holder, +/obj/effect/decal/cleanable/trail_holder{ + color = "#dc0000"; + dir = 9 + }, /turf/open/floor/wood, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) +"x" = ( +/obj/effect/decal/cleanable/trail_holder{ + color = "#dc0000"; + dir = 8 + }, +/turf/open/floor/wood, +/area/ruin/lavaland/unpowered) +"N" = ( +/obj/effect/decal/cleanable/trail_holder{ + color = "#dc0000"; + dir = 8 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"Q" = ( +/obj/effect/decal/cleanable/trail_holder{ + color = "#dc0000"; + dir = 6 + }, +/turf/open/floor/wood, +/area/ruin/lavaland/unpowered) (1,1,1) = {" i @@ -435,7 +466,7 @@ f f f f -s +x b b i @@ -462,7 +493,7 @@ g f f f -s +x b b i @@ -489,7 +520,7 @@ f f f f -s +x b b i @@ -516,7 +547,7 @@ j f f f -s +x b b i @@ -543,7 +574,7 @@ k f f f -s +x b b i @@ -569,8 +600,8 @@ b l f f -f s +Q b b i @@ -595,7 +626,7 @@ b b b f -f +s p b b @@ -622,7 +653,7 @@ i b b b -f +x b b b @@ -649,7 +680,7 @@ i i i b -f +x b i i @@ -676,7 +707,7 @@ i i i b -f +x b i i @@ -703,7 +734,7 @@ i i i b -f +x b i i @@ -757,7 +788,7 @@ i i n h -n +N h n i diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm index e582f6e9ce..d7811a66b2 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm @@ -11,13 +11,13 @@ /area/lavaland/surface/outdoors) "d" = ( /turf/closed/wall, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "e" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "f" = ( /obj/structure/table/wood, /obj/item/storage/box/cups, @@ -25,7 +25,7 @@ /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "g" = ( /obj/structure/reagent_dispensers/water_cooler{ name = "punch cooler"; @@ -35,27 +35,27 @@ /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "h" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "i" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "j" = ( /obj/item/reagent_containers/food/snacks/pizzaslice/mushroom, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "k" = ( /obj/structure/table/wood, /obj/effect/spawner/lootdrop/pizzaparty, @@ -63,7 +63,7 @@ /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "l" = ( /obj/machinery/light{ dir = 4 @@ -75,42 +75,42 @@ /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "m" = ( /obj/item/chair/wood/wings, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "n" = ( /obj/structure/glowshroom/single, /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "o" = ( /obj/item/trash/plate, /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "p" = ( /obj/effect/decal/remains/human, /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "q" = ( /obj/item/chair/wood/wings, /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "r" = ( /obj/structure/chair/wood/wings, /obj/effect/decal/remains/human, @@ -121,25 +121,25 @@ /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "s" = ( /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "t" = ( /obj/structure/chair/wood/wings, /obj/effect/decal/remains/human, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "u" = ( /obj/structure/glowshroom/single, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "v" = ( /obj/structure/lattice, /obj/item/chair/wood/wings, @@ -151,21 +151,21 @@ /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "x" = ( /obj/structure/table/wood, /obj/effect/spawner/lootdrop/pizzaparty, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "y" = ( /obj/structure/table/wood, /obj/item/trash/plate, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "z" = ( /obj/structure/table/wood, /obj/structure/glowshroom/single, @@ -173,7 +173,7 @@ /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "A" = ( /obj/structure/table/wood, /obj/item/trash/plate, @@ -181,14 +181,14 @@ /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "B" = ( /obj/effect/decal/cleanable/dirt, /obj/item/trash/candy, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "C" = ( /obj/structure/chair/wood/wings{ dir = 4 @@ -198,7 +198,7 @@ /turf/open/floor/plating{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "D" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/pizzaslice/margherita, @@ -206,48 +206,48 @@ /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "E" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/pizzaslice/meat, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "F" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/store/cake/birthday, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "G" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/lollipop, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "H" = ( /obj/item/chair/wood/wings, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "I" = ( /obj/item/kitchen/fork, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "J" = ( /obj/structure/glowshroom/single, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "K" = ( /obj/structure/chair/wood/wings{ dir = 1 @@ -257,21 +257,21 @@ /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "L" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "M" = ( /obj/effect/decal/cleanable/dirt, /obj/item/a_gift, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "N" = ( /obj/structure/lattice, /obj/effect/decal/cleanable/dirt, @@ -283,7 +283,7 @@ /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "P" = ( /obj/machinery/light{ dir = 4 @@ -292,12 +292,12 @@ /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "Q" = ( /turf/open/floor/plating{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "R" = ( /obj/structure/table/wood, /obj/effect/spawner/lootdrop/pizzaparty, @@ -306,27 +306,27 @@ /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "V" = ( /obj/item/reagent_containers/food/snacks/gumball, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "X" = ( /obj/effect/decal/cleanable/dirt, /obj/item/toy/snappop, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "Z" = ( /obj/effect/decal/cleanable/dirt, /obj/item/reagent_containers/food/snacks/gumball, /turf/open/floor/wood{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) (1,1,1) = {" a diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_pride.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_pride.dmm index f42aef243a..07c0693056 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_pride.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_pride.dmm @@ -4,7 +4,7 @@ /area/lavaland/surface/outdoors) "b" = ( /turf/closed/wall/mineral/diamond, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "c" = ( /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) @@ -13,20 +13,20 @@ pixel_x = -32 }, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "f" = ( /obj/structure/mirror{ pixel_x = 32 }, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "g" = ( /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "i" = ( /obj/item/clothing/gloves/ring, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "j" = ( /obj/structure/mirror{ pixel_x = -32 @@ -35,11 +35,11 @@ dir = 1 }, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "k" = ( /obj/structure/mirror/magic/pride, /turf/closed/wall/mineral/diamond, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "l" = ( /obj/structure/mirror{ pixel_x = -32 @@ -49,7 +49,7 @@ dir = 8 }, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "m" = ( /obj/structure/mirror{ pixel_x = 32 @@ -58,43 +58,43 @@ dir = 4 }, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "o" = ( /obj/structure/mirror{ pixel_x = -32 }, /obj/item/lipstick/random, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "q" = ( /obj/structure/mirror{ pixel_x = -32 }, /obj/item/clothing/gloves/ring/silver, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "r" = ( /obj/machinery/light/small, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "u" = ( /obj/structure/mirror{ pixel_x = 32 }, /obj/item/lipstick/random, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "D" = ( /obj/item/clothing/head/wig/random, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "G" = ( /turf/closed/mineral/volcanic/lava_land_surface, /area/lavaland/surface/outdoors) "I" = ( /obj/item/clothing/gloves/ring/silver, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "J" = ( /obj/structure/mirror{ pixel_x = 32 @@ -103,25 +103,25 @@ dir = 1 }, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "L" = ( /obj/item/lipstick/random, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "O" = ( /obj/item/clothing/gloves/ring/diamond, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "V" = ( /obj/item/clothing/head/wig, /turf/open/floor/mineral/silver, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) "Y" = ( /obj/machinery/door/airlock/silver/glass, /turf/open/floor/mineral/silver{ blocks_air = 1 }, -/area/ruin/powered/pride) +/area/ruin/lavaland/powered/pride) (1,1,1) = {" a diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm index e1097d3f68..0ca8a35149 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm @@ -9,7 +9,7 @@ /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "d" = ( -/obj/mecha/working/ripley/mining, +/obj/vehicle/sealed/mecha/working/ripley/mining, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "e" = ( diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm index e22f21ef4f..844d28415f 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm @@ -5,6 +5,10 @@ "b" = ( /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"c" = ( +/obj/structure/table/wood, +/turf/open/floor/plasteel/freezer, +/area/ruin/lavaland/powered/seedvault) "d" = ( /obj/structure/table/wood, /obj/item/lighter, @@ -14,29 +18,29 @@ /obj/item/storage/fancy/rollingpapers, /obj/item/storage/fancy/rollingpapers, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "e" = ( /obj/structure/table/wood, /obj/item/storage/box/disks_plantgene, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "f" = ( -/obj/machinery/plantgenes/seedvault{ - pixel_y = 6 +/obj/structure/sink{ + dir = 4; + pixel_x = 11 }, -/obj/structure/table/wood, -/turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/turf/open/floor/grass, +/area/ruin/lavaland/powered/seedvault) "g" = ( /obj/structure/table/wood, /obj/machinery/smartfridge/disks{ pixel_y = 2 }, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "h" = ( /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "i" = ( /obj/structure/closet/crate/hydroponics, /obj/structure/beebox, @@ -48,7 +52,7 @@ /obj/item/clothing/head/beekeeper_head, /obj/item/clothing/suit/beekeeper_suit, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "j" = ( /obj/structure/shuttle/engine/propulsion{ dir = 8 @@ -59,11 +63,11 @@ /obj/structure/closet/crate, /obj/effect/spawner/lootdrop/seed_vault, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "l" = ( -/obj/machinery/door/airlock, +/obj/machinery/door/airlock/titanium/glass, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "m" = ( /obj/machinery/door/airlock/external, /obj/structure/fans/tiny, @@ -71,11 +75,12 @@ dir = 8 }, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "n" = ( -/obj/machinery/smartfridge, +/obj/structure/table/wood, +/obj/item/gps, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "o" = ( /obj/structure/closet/crate/hydroponics, /obj/item/cultivator, @@ -91,18 +96,19 @@ /obj/item/hatchet, /obj/item/hatchet, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "p" = ( -/obj/machinery/hydroponics/constructable, -/turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/obj/structure/grille, +/obj/machinery/smartfridge, +/turf/open/floor/circuit/green, +/area/ruin/lavaland/powered/seedvault) "q" = ( /obj/item/hatchet, /obj/item/storage/bag/plants, /obj/item/reagent_containers/glass/bucket, /obj/structure/table/wood, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "r" = ( /obj/structure/table/wood, /obj/item/storage/bag/plants, @@ -110,36 +116,27 @@ /obj/item/storage/bag/plants, /obj/item/storage/bag/plants, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "s" = ( /obj/structure/table/wood, -/obj/item/gun/energy/floragun, -/obj/item/gun/energy/floragun, -/obj/item/gun/energy/floragun, -/obj/item/gun/energy/floragun, -/obj/item/storage/box/disks_plantgene, +/obj/item/seeds/bee_balm/honey_balm, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "t" = ( /obj/effect/mob_spawn/human/seed_vault, -/turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/turf/open/floor/grass, +/area/ruin/lavaland/powered/seedvault) "u" = ( -/obj/structure/sink{ - dir = 8; - pixel_x = -12; - pixel_y = 2 - }, -/turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/turf/open/floor/grass, +/area/ruin/lavaland/powered/seedvault) "v" = ( /obj/machinery/vending/hydronutrients, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "w" = ( /obj/machinery/vending/hydroseeds, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "x" = ( /obj/machinery/reagentgrinder{ pixel_y = 5 @@ -150,67 +147,74 @@ /obj/item/reagent_containers/glass/beaker/bluespace, /obj/item/reagent_containers/glass/beaker/bluespace, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "y" = ( -/obj/structure/sink{ - dir = 4; - pixel_x = 11 - }, +/obj/structure/table/wood, +/obj/item/pickaxe, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "z" = ( /obj/machinery/door/airlock/external, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) +"A" = ( +/obj/structure/table/glass, +/turf/open/floor/plasteel/freezer, +/area/ruin/lavaland/powered/seedvault) "B" = ( /obj/structure/disposalpipe/trunk, /obj/machinery/disposal/bin, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "C" = ( /obj/machinery/seed_extractor, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "D" = ( /obj/machinery/biogenerator, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "E" = ( /obj/machinery/chem_dispenser/mutagensaltpeter, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "F" = ( -/obj/structure/disposalpipe/segment, -/turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/obj/structure/grille, +/obj/structure/window/shuttle, +/turf/open/floor/circuit/green, +/area/ruin/lavaland/powered/seedvault) "G" = ( -/obj/structure/closet/crate/hydroponics, -/obj/item/clothing/under/rank/civilian/hydroponics, -/obj/item/clothing/under/rank/civilian/hydroponics, -/obj/item/clothing/under/rank/civilian/hydroponics, -/obj/item/clothing/under/rank/civilian/hydroponics, -/turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/obj/structure/disposalpipe/segment, +/turf/closed/wall/mineral/titanium/interior, +/area/ruin/lavaland/powered/seedvault) "H" = ( -/obj/machinery/chem_master/condimaster, +/obj/structure/table/glass, +/obj/item/gun/energy/floragun, +/obj/item/gun/energy/floragun, +/obj/item/gun/energy/floragun, +/obj/item/gun/energy/floragun, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "I" = ( /obj/structure/table/wood, -/obj/item/reagent_containers/glass/bucket, -/obj/item/reagent_containers/glass/bucket, -/obj/item/reagent_containers/glass/bucket, -/obj/item/reagent_containers/glass/bucket, +/obj/item/watertank, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "J" = ( /obj/item/storage/toolbox/syndicate, /obj/structure/table/wood, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) +"K" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/flora/ausbushes/ywflowers, +/turf/open/floor/grass, +/area/ruin/lavaland/powered/seedvault) "L" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -224,61 +228,84 @@ /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "N" = ( +/obj/machinery/plantgenes/seedvault{ + pixel_y = 6 + }, /obj/structure/table/wood, -/obj/item/storage/box/disks_plantgene, /obj/machinery/light{ dir = 1 }, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "O" = ( /obj/machinery/light{ dir = 1 }, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "P" = ( +/obj/structure/table/wood, +/obj/item/storage/box/disks_plantgene, +/obj/machinery/light, +/turf/open/floor/plasteel/freezer, +/area/ruin/lavaland/powered/seedvault) +"Q" = ( /obj/machinery/hydroponics/constructable, +/turf/open/floor/grass, +/area/ruin/lavaland/powered/seedvault) +"R" = ( +/obj/structure/sink{ + dir = 8; + pixel_x = -12; + pixel_y = 2 + }, +/turf/open/floor/grass, +/area/ruin/lavaland/powered/seedvault) +"S" = ( +/turf/closed/wall/mineral/titanium/interior, +/area/ruin/lavaland/powered/seedvault) +"T" = ( +/obj/structure/closet/crate/hydroponics, +/obj/item/clothing/under/rank/civilian/hydroponics, +/obj/item/clothing/under/rank/civilian/hydroponics, +/obj/item/clothing/under/rank/civilian/hydroponics, +/obj/item/clothing/under/rank/civilian/hydroponics, +/obj/machinery/light, +/turf/open/floor/plasteel/freezer, +/area/ruin/lavaland/powered/seedvault) +"U" = ( +/obj/machinery/light, +/obj/structure/flora/ausbushes/ppflowers, +/turf/open/floor/grass, +/area/ruin/lavaland/powered/seedvault) +"V" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/glass/bucket, +/obj/item/reagent_containers/glass/bucket, +/obj/item/reagent_containers/glass/bucket, +/obj/item/reagent_containers/glass/bucket, +/obj/machinery/light, +/turf/open/floor/plasteel/freezer, +/area/ruin/lavaland/powered/seedvault) +"X" = ( +/obj/structure/table/glass, +/obj/item/construction/plumbing, /obj/machinery/light{ dir = 1 }, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"Q" = ( -/turf/closed/wall/r_wall, -/area/ruin/powered/seedvault) -"R" = ( -/obj/machinery/light{ - dir = 8 - }, +/area/ruin/lavaland/powered/seedvault) +"Y" = ( +/obj/machinery/chem_master, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"S" = ( -/obj/machinery/light{ - dir = 4 - }, -/turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"U" = ( -/obj/machinery/light, -/turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) -"V" = ( -/obj/structure/disposalpipe/segment, -/turf/closed/wall/r_wall, -/area/ruin/powered/seedvault) -"X" = ( -/obj/machinery/hydroponics/constructable, -/obj/machinery/light, -/turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) "Z" = ( /obj/item/disk/design_disk/plant_disk, /obj/machinery/autolathe/hacked{ desc = "This autolathe seems to have its safety light off." }, /turf/open/floor/plasteel/freezer, -/area/ruin/powered/seedvault) +/area/ruin/lavaland/powered/seedvault) (1,1,1) = {" a @@ -288,12 +315,12 @@ a a a a -Q -Q -Q -Q -Q -Q +S +S +S +S +S +S a a a @@ -309,14 +336,14 @@ a a a a -a -Q +S +S t t t t -Q -a +S +S a a a @@ -329,41 +356,41 @@ b a a a -a -a -Q -Q -O -h -h +S +S +S +S +K +u +u U -Q -Q +S +S +S +S a a a b -a -b "} (4,1,1) = {" b a a -Q -Q -Q -Q -Q -Q +S +S +w +v +S +F l l -Q -Q -Q -Q -a -a +F +S +w +v +S +S a a a @@ -371,241 +398,241 @@ a (5,1,1) = {" a a -Q -Q -k -Q -n +S +S +u +u +u R u h h u R -Z -Q -a -a -a +u +u +u +S +S a a "} (6,1,1) = {" a a +S +C +u Q -d -h +u Q -o +u h h -h -h -h -h -G +u Q -a -a -a +u +Q +u +Z +S a a "} (7,1,1) = {" a a -Q +S N -h +u Q -P -h -p -h -h -p -h -X +u Q -a -a -a +u +h +h +u +Q +u +Q +u +V +S a a "} (8,1,1) = {" b a +S +g +u Q -e -h -l -h -h -v +u +Q +u h h +u +Q +u +Q +u B -F -F -V +G L a -a -a -a "} (9,1,1) = {" b a -Q +S +e +u +u +u f -h -Q -p -h -n +u h h -C -h -k -Q +u +f +u +u +u +r +S M a -a -a -a "} (10,1,1) = {" a a -Q -g -h -Q +S +S +F +l p -h -w -h -h +S D h +h +o +S p -Q +l +F +S +S b a -a -a -a "} (11,1,1) = {" a a -Q +S +k h h -Q -q +e +S +O h -x +h +T +S +H h h E -h -H -Q -a -a -a +S a a "} (12,1,1) = {" b a -Q -O +S +k +h h -Q P +S +I h h -h -h -h -h +J +S X -Q -a -a -a +h +h +A +S a a "} (13,1,1) = {" a a -Q -i -h -Q -r +S +k h h -p -p +d +S +c h h -I -Q -a -a -a +n +S +x +h +h +Y +S a a "} (14,1,1) = {" a a -Q -Q +S +S +i i -Q s S -y +q h h y S -J -Q -a -a -a +A +h +h +S +S a a "} (15,1,1) = {" a a -b -Q -Q -Q -Q -Q -Q +a +S +S +S +S +S +S z z -Q -Q -Q -Q -a -a +S +S +S +S +S +S a a a @@ -613,21 +640,21 @@ a (16,1,1) = {" b a -b +a j -Q +S j -Q +S j -Q +S h h -Q +S j -Q +S +j +S j -a -a a a a @@ -641,10 +668,10 @@ a a a a -Q +S m m -Q +S b b b @@ -683,7 +710,7 @@ a a b b -a +b b b b diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_sloth.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_sloth.dmm index 3576cab5c7..5bdb724e00 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_sloth.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_sloth.dmm @@ -1,30 +1,30 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( /turf/closed/indestructible/riveted, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "b" = ( /turf/open/lava/smooth/lava_land_surface, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "c" = ( /obj/item/paper/fluff/stations/lavaland/sloth/note, /turf/open/floor/sepia{ blocks_air = 0; slowdown = 10 }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "d" = ( /turf/open/floor/sepia{ blocks_air = 0; slowdown = 10 }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "e" = ( /obj/machinery/door/airlock/wood, /turf/open/floor/sepia{ blocks_air = 0; slowdown = 10 }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "f" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/grown/citrus/orange, @@ -32,7 +32,7 @@ blocks_air = 0; slowdown = 10 }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "g" = ( /obj/structure/bed, /obj/item/bedsheet/brown, @@ -40,7 +40,7 @@ blocks_air = 0; slowdown = 10 }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) (1,1,1) = {" a diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm index 47896ec886..5bb7d48a44 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm @@ -13,7 +13,7 @@ /area/lavaland/surface/outdoors) "d" = ( /turf/closed/wall/mineral/titanium/survival/pod, -/area/ruin/powered) +/area/ruin/lavaland/powered) "e" = ( /obj/structure/sign/mining/survival{ dir = 4; @@ -24,16 +24,16 @@ "f" = ( /obj/structure/fans, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "g" = ( /obj/machinery/smartfridge/survival_pod/empty, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "h" = ( /obj/item/gps/computer, /obj/structure/tubes, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "i" = ( /obj/structure/sign/mining/survival{ dir = 8; @@ -48,12 +48,12 @@ "k" = ( /obj/machinery/sleeper/survival_pod, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "l" = ( /obj/item/pickaxe, /obj/effect/decal/cleanable/blood, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "m" = ( /obj/structure/bed/pod, /obj/item/bedsheet/black, @@ -62,7 +62,7 @@ dir = 4 }, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "n" = ( /obj/effect/decal/cleanable/blood, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, @@ -78,7 +78,7 @@ /obj/structure/table/survival_pod, /obj/item/kitchen/knife/combat/survival, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "q" = ( /obj/effect/mob_spawn/human/miner/explorer{ brute_damage = 150; @@ -91,13 +91,13 @@ icon_state = "blood1" }, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "r" = ( /obj/structure/tubes, /obj/item/crowbar, /obj/effect/decal/cleanable/blood/drip, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "s" = ( /obj/effect/decal/cleanable/blood/footprints{ icon_state = "blood1" @@ -111,7 +111,7 @@ }, /obj/machinery/door/airlock/survival_pod/glass, /turf/open/floor/pod/dark, -/area/ruin/powered) +/area/ruin/lavaland/powered) "u" = ( /obj/effect/decal/cleanable/blood/footprints{ dir = 8; diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_swarmer_crash.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_swarmer_crash.dmm index 93b8195a40..7f6ba7464d 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_swarmer_crash.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_swarmer_crash.dmm @@ -7,24 +7,24 @@ /area/template_noop) "c" = ( /turf/closed/wall/mineral/plastitanium, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "d" = ( /turf/open/floor/mineral/plastitanium/red{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "e" = ( /obj/structure/shuttle/engine/propulsion{ dir = 4 }, /turf/template_noop, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "f" = ( /mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon, /turf/open/floor/mineral/plastitanium/red{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) (1,1,1) = {" a diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm index 4514e08d5e..bcf0830523 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm @@ -30,17 +30,17 @@ dir = 4 }, /turf/open/floor/plasteel/white, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "ae" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "af" = ( /obj/machinery/light/small{ dir = 4 }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "ag" = ( /obj/machinery/airalarm/syndicate{ dir = 4; @@ -53,7 +53,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "ah" = ( /obj/structure/table/wood, /obj/machinery/chem_dispenser/drinks/beer/fullupgrade{ @@ -64,14 +64,14 @@ req_access = null }, /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "ai" = ( /obj/structure/table/wood, /obj/machinery/chem_dispenser/drinks/fullupgrade{ dir = 1 }, /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "aj" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -79,17 +79,17 @@ /turf/open/floor/plasteel/white/side{ dir = 4 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "ak" = ( /obj/machinery/vending/boozeomat/syndicate_access, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "al" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/machinery/vending/medical/syndicate_access, /turf/open/floor/plasteel/white, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "am" = ( /obj/structure/table/reinforced, /obj/item/stock_parts/cell/high/plus{ @@ -104,7 +104,7 @@ /turf/open/floor/plasteel/white/side{ dir = 8 }, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "an" = ( /obj/structure/table/reinforced, /obj/item/stock_parts/cell/high/plus{ @@ -122,33 +122,33 @@ /turf/open/floor/plasteel/white/side{ dir = 4 }, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "ao" = ( /obj/structure/table/reinforced, /obj/item/integrated_circuit_printer/upgraded, /turf/open/floor/plasteel/white/side{ dir = 10 }, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "ap" = ( /obj/machinery/light/small{ dir = 1 }, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "aq" = ( /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "ar" = ( /obj/structure/table/reinforced, /obj/item/integrated_circuit_printer/upgraded, /turf/open/floor/plasteel/white/side{ dir = 6 }, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "as" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "at" = ( /obj/structure/grille, /obj/structure/window/plastitanium, @@ -156,7 +156,7 @@ id = "lavalandsyndi_chemistry" }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "au" = ( /obj/structure/grille, /obj/structure/window/plastitanium, @@ -165,7 +165,7 @@ id = "lavalandsyndi_circuits" }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "av" = ( /obj/structure/bed/roller, /obj/machinery/iv_drip, @@ -185,7 +185,7 @@ faction = list("neutral","Syndicate") }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "aw" = ( /obj/machinery/light/small, /obj/structure/bed/roller, @@ -206,7 +206,7 @@ faction = list("neutral","Syndicate") }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "ax" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -214,16 +214,16 @@ dir = 1 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "aF" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 4 }, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "aL" = ( /turf/closed/wall/mineral/plastitanium/explosive, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "aM" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -232,7 +232,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/chem_dispenser/fullupgrade, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "aO" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -242,7 +242,7 @@ /turf/open/floor/plasteel/white/side{ dir = 1 }, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "aP" = ( /obj/structure/cable/yellow{ icon_state = "0-8" @@ -255,14 +255,14 @@ /turf/open/floor/plasteel/white/side{ dir = 1 }, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "aR" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "aS" = ( /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "aT" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 @@ -274,7 +274,7 @@ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "aU" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 5 @@ -284,13 +284,13 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "aV" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "aW" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, @@ -300,7 +300,7 @@ /obj/machinery/door/firedoor, /obj/machinery/door/airlock/research, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "aX" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ dir = 8 @@ -312,7 +312,7 @@ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "ba" = ( /obj/structure/chair/office/light{ dir = 8 @@ -327,19 +327,19 @@ /turf/open/floor/plasteel/white/corner{ dir = 8 }, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "bb" = ( /obj/structure/chair/office/light{ dir = 4 }, /turf/open/floor/plasteel/white/corner, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "bd" = ( /obj/structure/closet/crate/bin, /turf/open/floor/plasteel/white/side{ dir = 10 }, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "be" = ( /obj/structure/table/glass, /obj/item/integrated_electronics/analyzer{ @@ -351,20 +351,20 @@ pixel_y = 1 }, /turf/open/floor/plasteel/white/side, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "bf" = ( /obj/structure/table/glass, /obj/item/paper_bin, /obj/item/pen, /turf/open/floor/plasteel/white/side, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "bg" = ( /obj/structure/closet/crate, /obj/item/stack/sheet/metal/fifty, /turf/open/floor/plasteel/white/side{ dir = 6 }, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "cA" = ( /obj/structure/table/reinforced, /obj/item/book/manual/wiki/chemistry, @@ -373,7 +373,7 @@ /obj/item/clothing/glasses/science, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "cG" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -382,19 +382,19 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "dc" = ( /obj/machinery/light/small{ dir = 8 }, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "di" = ( /obj/machinery/light/small{ dir = 4 }, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "do" = ( /obj/structure/closet/secure_closet/medical1{ req_access = null; @@ -406,7 +406,7 @@ /turf/open/floor/plasteel/white/side{ dir = 9 }, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "du" = ( /obj/machinery/light/small{ dir = 1 @@ -421,7 +421,7 @@ /turf/open/floor/plasteel/white/side{ dir = 1 }, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "dv" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -429,7 +429,7 @@ /obj/machinery/chem_heater, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "dw" = ( /obj/structure/chair/office/light{ dir = 1 @@ -437,7 +437,7 @@ /obj/effect/turf_decal/bot, /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "dx" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -445,10 +445,10 @@ /obj/structure/closet/crate/bin, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "dy" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "dA" = ( /obj/structure/closet/l3closet, /obj/machinery/power/apc/syndicate{ @@ -466,17 +466,17 @@ /turf/open/floor/plasteel/white/side{ dir = 8 }, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "dB" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "dC" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "dE" = ( /obj/structure/table/glass, /obj/item/stack/sheet/mineral/plasma{ @@ -501,7 +501,7 @@ /turf/open/floor/plasteel/white/corner{ dir = 4 }, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "dG" = ( /obj/structure/lattice/catwalk, /turf/open/lava/smooth/lava_land_surface, @@ -515,7 +515,7 @@ /turf/open/floor/plasteel/white/side{ dir = 5 }, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "dK" = ( /obj/effect/turf_decal/box/white/corners{ dir = 4 @@ -538,7 +538,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "dL" = ( /obj/machinery/airalarm/syndicate{ pixel_y = 24 @@ -579,7 +579,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "dM" = ( /obj/effect/turf_decal/box/white/corners{ dir = 8 @@ -597,14 +597,14 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "dP" = ( /turf/closed/wall/mineral/plastitanium/explosive, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "dQ" = ( /obj/structure/sign/warning/securearea, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "dR" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/hatch{ @@ -628,7 +628,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "dS" = ( /obj/structure/grille, /obj/structure/window/plastitanium, @@ -638,7 +638,7 @@ name = "Syndicate Research Experimentation Shutters" }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "dT" = ( /obj/machinery/firealarm{ dir = 8; @@ -654,32 +654,32 @@ /turf/open/floor/plasteel/white/side{ dir = 8 }, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "dU" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "dV" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "dX" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "dY" = ( /obj/structure/chair{ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "dZ" = ( /obj/machinery/light/small{ dir = 4 @@ -704,7 +704,7 @@ /turf/open/floor/plasteel/white/side{ dir = 4 }, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "ea" = ( /obj/effect/turf_decal/box/white/corners{ dir = 1 @@ -734,7 +734,7 @@ }, /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "eb" = ( /obj/structure/closet/crate, /obj/item/storage/toolbox/electrical{ @@ -742,7 +742,7 @@ }, /obj/item/storage/toolbox/mechanical, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "ec" = ( /obj/effect/turf_decal/box/white/corners, /obj/structure/closet/crate/medical, @@ -756,7 +756,7 @@ pixel_y = -3 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "ed" = ( /obj/structure/table, /obj/item/paper_bin, @@ -774,7 +774,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "ee" = ( /obj/structure/rack, /obj/item/flashlight{ @@ -790,7 +790,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "ef" = ( /obj/machinery/light/small{ dir = 1 @@ -812,7 +812,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "eg" = ( /obj/structure/closet/firecloset/full{ anchored = 1 @@ -826,22 +826,22 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "eh" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "ei" = ( /obj/structure/disposaloutlet{ dir = 1 }, /obj/structure/disposalpipe/trunk, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "ek" = ( /obj/structure/grille, /obj/structure/window/plastitanium, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "el" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -857,7 +857,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "em" = ( /obj/machinery/light/small{ dir = 1 @@ -883,7 +883,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "eo" = ( /obj/structure/table/reinforced, /obj/item/storage/toolbox/syndicate, @@ -898,7 +898,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "ep" = ( /obj/structure/table/reinforced, /obj/effect/decal/cleanable/dirt, @@ -917,7 +917,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "eq" = ( /obj/structure/table/reinforced, /obj/item/restraints/handcuffs, @@ -934,7 +934,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "er" = ( /obj/machinery/light/small{ dir = 8 @@ -951,7 +951,7 @@ /turf/open/floor/plasteel/white/side{ dir = 8 }, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "es" = ( /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -959,13 +959,13 @@ /obj/effect/decal/cleanable/dirt, /obj/structure/closet/crate/bin, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "et" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "eu" = ( /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -974,17 +974,17 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "ev" = ( /turf/open/floor/plasteel/white/corner, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "ew" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/vending/syndichem, /turf/open/floor/plasteel/white/side{ dir = 6 }, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "ex" = ( /obj/machinery/light/small{ dir = 8 @@ -1013,7 +1013,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "ey" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -1036,7 +1036,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "ez" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -1058,7 +1058,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "eA" = ( /obj/machinery/door/firedoor, /obj/structure/cable/yellow{ @@ -1086,7 +1086,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "eB" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -1099,7 +1099,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "eC" = ( /obj/structure/cable/yellow{ icon_state = "1-8" @@ -1112,12 +1112,12 @@ dir = 10 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "eD" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "eE" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -1127,7 +1127,7 @@ /obj/item/wrench, /obj/effect/decal/cleanable/dirt, /turf/open/floor/mineral/plastitanium, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "eF" = ( /obj/structure/grille, /obj/structure/window/plastitanium, @@ -1136,14 +1136,14 @@ id = "lavalandsyndi_cargo" }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "eG" = ( /obj/structure/closet/secure_closet/personal/patient, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white/side{ dir = 9 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "eH" = ( /obj/structure/bed, /obj/item/bedsheet, @@ -1153,16 +1153,16 @@ /turf/open/floor/plasteel/white/side{ dir = 5 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "eI" = ( /obj/structure/grille, /obj/structure/window/plastitanium, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "eJ" = ( /obj/structure/disposalpipe/segment, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "eL" = ( /obj/machinery/door/airlock/hatch{ name = "Monkey Pen"; @@ -1180,7 +1180,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "eM" = ( /obj/machinery/firealarm{ dir = 1; @@ -1200,7 +1200,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "eN" = ( /obj/machinery/airalarm/syndicate{ dir = 1; @@ -1220,7 +1220,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "eO" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_pump/on{ @@ -1240,7 +1240,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "eP" = ( /obj/structure/chair{ dir = 1 @@ -1262,7 +1262,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "eQ" = ( /obj/machinery/light/small, /obj/structure/table/reinforced, @@ -1279,7 +1279,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "eR" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -1289,7 +1289,7 @@ /turf/open/floor/plasteel/white/side{ dir = 10 }, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "eS" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -1297,13 +1297,13 @@ /obj/machinery/chem_master, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "eT" = ( /obj/effect/turf_decal/bot, /obj/structure/chair/office/light, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "eU" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -1312,13 +1312,13 @@ /obj/machinery/chem_dispenser/fullupgrade, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "eV" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white/side{ dir = 6 }, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "eW" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -1336,7 +1336,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "eX" = ( /obj/effect/turf_decal/box/white/corners{ dir = 4 @@ -1352,7 +1352,7 @@ /obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "eY" = ( /obj/effect/turf_decal/box/white/corners{ dir = 8 @@ -1372,7 +1372,7 @@ dir = 1 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "eZ" = ( /obj/structure/rack{ dir = 8 @@ -1394,13 +1394,13 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "fa" = ( /obj/structure/grille, /obj/structure/window/plastitanium, /obj/machinery/door/firedoor, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "fb" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/closet/crate/bin, @@ -1408,21 +1408,21 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "fc" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 5 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "fd" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ dir = 8 }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "fe" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -1431,7 +1431,7 @@ /obj/machinery/cell_charger, /obj/item/stock_parts/cell/high/plus, /turf/open/floor/mineral/plastitanium, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "ff" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ dir = 4 @@ -1440,7 +1440,7 @@ /turf/open/floor/plasteel/white/side{ dir = 10 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "fg" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ @@ -1449,7 +1449,7 @@ /turf/open/floor/plasteel/white/side{ dir = 6 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "fh" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ dir = 4 @@ -1457,7 +1457,7 @@ /turf/open/floor/plasteel/white/side{ dir = 10 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "fi" = ( /obj/structure/table/glass, /obj/item/storage/box/beakers{ @@ -1477,7 +1477,7 @@ /turf/open/floor/plasteel/white/side{ dir = 9 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "fj" = ( /obj/structure/table/glass, /obj/structure/reagent_dispensers/virusfood{ @@ -1495,7 +1495,7 @@ /turf/open/floor/plasteel/white/side{ dir = 5 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "fk" = ( /obj/machinery/power/apc/syndicate{ name = "Experimentation Lab APC"; @@ -1516,7 +1516,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "fl" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, @@ -1537,7 +1537,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "fm" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/medical{ @@ -1550,13 +1550,13 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/plasteel/white, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "fn" = ( /obj/structure/grille, /obj/structure/window/plastitanium, /obj/machinery/door/firedoor, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "fo" = ( /obj/machinery/door/firedoor, /obj/structure/table/reinforced, @@ -1569,14 +1569,14 @@ req_access_txt = "150" }, /turf/open/floor/plasteel/white, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "fp" = ( /obj/machinery/smartfridge/chemistry/preloaded, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/chemistry) +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry) "fq" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -1592,7 +1592,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "fr" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -1611,7 +1611,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "fs" = ( /obj/effect/turf_decal/box/white/corners{ dir = 1 @@ -1627,7 +1627,7 @@ /obj/item/circuitboard/machine/cell_charger, /obj/item/circuitboard/machine/smoke_machine, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "ft" = ( /obj/effect/turf_decal/box/white/corners, /obj/structure/closet/crate, @@ -1651,7 +1651,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "fu" = ( /obj/machinery/light/small{ dir = 8 @@ -1682,11 +1682,11 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "fv" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "fw" = ( /obj/effect/turf_decal/stripes/corner, /obj/machinery/firealarm{ @@ -1695,11 +1695,11 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "fx" = ( /obj/structure/sign/warning/securearea, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "fy" = ( /obj/machinery/door/airlock/virology/glass{ name = "Isolation B"; @@ -1708,7 +1708,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/plasteel/white, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "fz" = ( /obj/machinery/door/airlock/virology/glass{ name = "Isolation A"; @@ -1717,7 +1717,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/plasteel/white, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "fA" = ( /obj/structure/table/glass, /obj/item/book/manual/wiki/infections{ @@ -1732,14 +1732,14 @@ /turf/open/floor/plasteel/white/side{ dir = 8 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "fB" = ( /obj/structure/chair/stool, /obj/structure/disposalpipe/segment, /turf/open/floor/plasteel/white/corner{ dir = 4 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "fC" = ( /obj/machinery/smartfridge/chemistry/virology/preloaded, /obj/effect/decal/cleanable/dirt, @@ -1747,11 +1747,11 @@ /turf/open/floor/plasteel/white/side{ dir = 5 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "fD" = ( /obj/structure/sign/warning/biohazard, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "fE" = ( /obj/effect/turf_decal/bot, /obj/structure/closet/l3closet, @@ -1763,14 +1763,14 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "fF" = ( /obj/effect/turf_decal/bot, /obj/machinery/shower{ pixel_y = 14 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "fG" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -1793,13 +1793,13 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "fH" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white/side{ dir = 1 }, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "fI" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable/yellow{ @@ -1810,12 +1810,12 @@ /turf/open/floor/plasteel/white/side{ dir = 1 }, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "fO" = ( /turf/open/floor/plasteel/white/side{ dir = 1 }, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "fW" = ( /obj/machinery/door/firedoor, /obj/structure/cable/yellow{ @@ -1838,7 +1838,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "fY" = ( /obj/structure/extinguisher_cabinet{ pixel_x = -27; @@ -1863,7 +1863,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "gb" = ( /obj/structure/table, /obj/item/paper_bin, @@ -1873,7 +1873,7 @@ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "gc" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -1883,7 +1883,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "gd" = ( /obj/machinery/door/airlock/external{ req_access_txt = "150" @@ -1893,14 +1893,14 @@ dir = 4 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "gf" = ( /obj/structure/sign/warning/vacuum{ pixel_y = -32 }, /obj/machinery/light/small, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "gg" = ( /obj/structure/sign/warning/fire{ pixel_y = 32 @@ -1909,7 +1909,7 @@ pixel_y = -32 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "gh" = ( /obj/structure/fans/tiny, /obj/machinery/door/airlock/external{ @@ -1919,16 +1919,16 @@ dir = 8 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "gj" = ( /turf/closed/wall/mineral/plastitanium/explosive, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "gn" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 6 }, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "gp" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 @@ -1938,7 +1938,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "gq" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 @@ -1947,7 +1947,7 @@ dir = 1 }, /turf/open/floor/plasteel/white, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "gr" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -1956,14 +1956,14 @@ dir = 4 }, /turf/open/floor/plasteel/white, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "gs" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, /obj/machinery/light/small, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "gt" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -1974,7 +1974,7 @@ /turf/open/floor/plasteel/white/side{ dir = 9 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "gu" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -1988,7 +1988,7 @@ /turf/open/floor/plasteel/white/corner{ dir = 1 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "gv" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 @@ -2001,7 +2001,7 @@ icon_state = "4-8" }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "gw" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -2015,7 +2015,7 @@ /turf/open/floor/plasteel/white/side{ dir = 4 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "gy" = ( /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -2031,7 +2031,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "gz" = ( /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -2046,7 +2046,7 @@ icon_state = "4-8" }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "gA" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/virology{ @@ -2075,7 +2075,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "gB" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -2093,7 +2093,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "gE" = ( /obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, /obj/structure/cable/yellow{ @@ -2108,7 +2108,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "gF" = ( /obj/machinery/light/small{ dir = 1 @@ -2124,7 +2124,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "gG" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -2136,7 +2136,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "gH" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -2147,7 +2147,7 @@ icon_state = "1-8" }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "gI" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -2160,7 +2160,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "gJ" = ( /obj/machinery/door/firedoor, /obj/structure/cable/yellow{ @@ -2174,7 +2174,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "gK" = ( /obj/machinery/light/small{ dir = 1 @@ -2192,7 +2192,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "gL" = ( /obj/structure/cable/yellow{ icon_state = "1-8" @@ -2210,7 +2210,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "gM" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/brown{ @@ -2220,7 +2220,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "gN" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/brown{ @@ -2231,11 +2231,11 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "gO" = ( /obj/structure/sign/departments/cargo, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "gP" = ( /obj/machinery/photocopier, /obj/effect/decal/cleanable/dirt, @@ -2243,18 +2243,18 @@ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "gQ" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "gR" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "gS" = ( /obj/effect/turf_decal/stripes/corner{ dir = 8 @@ -2269,7 +2269,7 @@ req_access_txt = "150" }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "gT" = ( /obj/machinery/door/airlock/virology/glass{ name = "Monkey Pen"; @@ -2278,7 +2278,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/plasteel/white, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "gU" = ( /obj/machinery/airalarm/syndicate{ dir = 4; @@ -2296,11 +2296,11 @@ /turf/open/floor/plasteel/white/side{ dir = 8 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "gV" = ( /obj/structure/chair/office/light, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "gW" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 @@ -2309,7 +2309,7 @@ dir = 5 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "gX" = ( /obj/machinery/doorButtons/airlock_controller{ idExterior = "lavaland_syndie_virology_exterior"; @@ -2336,7 +2336,7 @@ /turf/open/floor/plasteel/white/side{ dir = 4 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "gY" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -2354,7 +2354,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "gZ" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -2364,10 +2364,10 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "ha" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hb" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/red{ @@ -2378,7 +2378,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hc" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, @@ -2389,18 +2389,18 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hd" = ( /obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "he" = ( /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hf" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/red, @@ -2408,7 +2408,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hg" = ( /obj/machinery/light/small, /obj/effect/decal/cleanable/dirt, @@ -2417,7 +2417,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hh" = ( /obj/machinery/door/firedoor, /obj/effect/turf_decal/tile/red, @@ -2425,20 +2425,20 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hi" = ( /obj/effect/turf_decal/tile/red{ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hj" = ( /obj/effect/turf_decal/tile/brown, /obj/effect/turf_decal/tile/brown{ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hk" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/mining/glass{ @@ -2446,17 +2446,17 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "hl" = ( /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "hn" = ( /obj/structure/chair{ dir = 4 }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "ho" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -2473,7 +2473,7 @@ shuttleId = "syndie_cargo" }, /turf/open/floor/mineral/plastitanium, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "hp" = ( /obj/effect/decal/cleanable/dirt, /mob/living/carbon/monkey{ @@ -2482,7 +2482,7 @@ /turf/open/floor/plasteel/white/side{ dir = 9 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "hq" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 @@ -2491,7 +2491,7 @@ /turf/open/floor/plasteel/white/side{ dir = 1 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "hr" = ( /mob/living/carbon/monkey{ faction = list("neutral","Syndicate") @@ -2499,7 +2499,7 @@ /turf/open/floor/plasteel/white/side{ dir = 5 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "hs" = ( /obj/machinery/computer/pandemic, /obj/effect/decal/cleanable/dirt, @@ -2512,7 +2512,7 @@ /turf/open/floor/plasteel/white/side{ dir = 10 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "ht" = ( /obj/structure/table, /obj/item/paper_bin{ @@ -2525,7 +2525,7 @@ /obj/effect/decal/cleanable/dirt, /obj/item/clothing/glasses/science, /turf/open/floor/plasteel/white/side, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "hu" = ( /obj/structure/table, /obj/machinery/reagentgrinder, @@ -2539,7 +2539,7 @@ amount = 10 }, /turf/open/floor/plasteel/white/side, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "hv" = ( /obj/machinery/disposal/bin, /obj/structure/sign/warning/deathsposal{ @@ -2553,7 +2553,7 @@ /turf/open/floor/plasteel/white/side{ dir = 6 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "hw" = ( /obj/machinery/door/airlock/external{ req_access_txt = "150" @@ -2561,7 +2561,7 @@ /obj/structure/fans/tiny, /obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hx" = ( /obj/machinery/airalarm/syndicate{ dir = 4; @@ -2580,17 +2580,17 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hy" = ( /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hz" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "hA" = ( /obj/structure/closet/emcloset/anchored, /obj/effect/decal/cleanable/dirt, @@ -2605,7 +2605,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "hB" = ( /obj/effect/turf_decal/tile/red{ dir = 1 @@ -2614,14 +2614,14 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hC" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/mining/glass{ name = "Cargo Bay" }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "hD" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -2630,7 +2630,7 @@ /obj/item/storage/belt/utility, /obj/effect/decal/cleanable/dirt, /turf/open/floor/mineral/plastitanium, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "hE" = ( /mob/living/carbon/monkey{ faction = list("neutral","Syndicate") @@ -2638,7 +2638,7 @@ /turf/open/floor/plasteel/white/side{ dir = 10 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "hF" = ( /obj/machinery/light/small, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ @@ -2646,7 +2646,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white/side, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "hG" = ( /obj/effect/decal/cleanable/dirt, /mob/living/carbon/monkey{ @@ -2655,7 +2655,7 @@ /turf/open/floor/plasteel/white/side{ dir = 6 }, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "hH" = ( /obj/structure/grille, /obj/structure/window/plastitanium, @@ -2663,17 +2663,17 @@ id = "lavalandsyndi_virology" }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/virology) +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology) "hI" = ( /obj/structure/sign/warning/vacuum{ pixel_x = -32 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hJ" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hK" = ( /obj/machinery/light/small{ dir = 4 @@ -2688,7 +2688,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hL" = ( /obj/machinery/light/small{ dir = 8 @@ -2705,7 +2705,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hM" = ( /obj/structure/table/wood, /obj/item/ammo_box/magazine/m10mm, @@ -2714,24 +2714,24 @@ pixel_y = 24 }, /turf/open/floor/plasteel/grimy, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "hN" = ( /obj/machinery/light/small{ dir = 4 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, /turf/open/floor/plasteel/grimy, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "hO" = ( /turf/closed/wall/mineral/plastitanium/explosive, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "hP" = ( /obj/machinery/light/small{ dir = 8 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, /turf/open/floor/plasteel/grimy, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "hQ" = ( /obj/structure/table/wood, /obj/item/ammo_box/magazine/m10mm, @@ -2739,14 +2739,14 @@ pixel_y = 24 }, /turf/open/floor/plasteel/grimy, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "hR" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/brown{ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hS" = ( /obj/structure/table/reinforced, /obj/item/folder, @@ -2761,7 +2761,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "hT" = ( /obj/machinery/vending/toyliberationstation{ req_access_txt = "150" @@ -2771,7 +2771,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "hU" = ( /obj/machinery/light/small, /obj/structure/filingcabinet/chestdrawer, @@ -2781,7 +2781,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "hV" = ( /obj/structure/filingcabinet/chestdrawer, /obj/effect/decal/cleanable/dirt, @@ -2790,13 +2790,13 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/cargo) +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo) "hW" = ( /obj/machinery/porta_turret/syndicate{ dir = 10 }, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hX" = ( /obj/structure/fans/tiny, /obj/machinery/door/airlock/external{ @@ -2806,7 +2806,7 @@ dir = 1 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hY" = ( /obj/structure/fans/tiny, /obj/machinery/door/airlock/external{ @@ -2817,7 +2817,7 @@ dir = 1 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "hZ" = ( /obj/machinery/firealarm{ dir = 8; @@ -2838,7 +2838,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "ia" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ dir = 8 @@ -2848,18 +2848,18 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "ib" = ( /obj/effect/mob_spawn/human/lavaland_syndicate{ dir = 4 }, /turf/open/floor/plasteel/grimy, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "ic" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/plasteel/grimy, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "id" = ( /obj/structure/toilet{ pixel_y = 18 @@ -2887,17 +2887,17 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "ie" = ( /obj/effect/mob_spawn/human/lavaland_syndicate/comms{ dir = 8 }, /turf/open/floor/plasteel/grimy, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "if" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "ig" = ( /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -2933,7 +2933,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "ij" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, @@ -2944,13 +2944,13 @@ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "ik" = ( /obj/effect/turf_decal/tile/red{ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "il" = ( /obj/machinery/door/airlock{ name = "Cabin 2" @@ -2958,7 +2958,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "im" = ( /obj/machinery/door/airlock{ name = "Unisex Restrooms" @@ -2975,7 +2975,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "in" = ( /obj/machinery/door/airlock{ name = "Cabin 4" @@ -2983,15 +2983,15 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "ip" = ( /obj/effect/turf_decal/stripes/red/corner, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "iq" = ( /obj/structure/sign/warning/securearea, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "ir" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/red/line{ @@ -3008,14 +3008,14 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "is" = ( /obj/machinery/light/small{ dir = 1 }, /obj/machinery/turretid{ ailock = 1; - control_area = "/area/ruin/unpowered/syndicate_lava_base/main"; + control_area = "/area/ruin/lavaland/unpowered/syndicate_lava_base/main"; dir = 1; icon_state = "control_kill"; lethal = 1; @@ -3025,7 +3025,7 @@ req_access_txt = "150" }, /turf/open/floor/circuit/red, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "it" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/red/line{ @@ -3044,7 +3044,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "iu" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -3079,7 +3079,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "ix" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, @@ -3088,20 +3088,20 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/space) "iy" = ( /obj/machinery/door/airlock/public/glass{ name = "Dormitories" }, /obj/machinery/door/firedoor, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iz" = ( /obj/effect/turf_decal/tile/neutral{ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, @@ -3113,7 +3113,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iB" = ( /obj/machinery/airalarm/syndicate{ pixel_y = 24 @@ -3124,11 +3124,11 @@ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iC" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iD" = ( /obj/machinery/light/small{ dir = 1 @@ -3141,7 +3141,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iE" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, @@ -3152,7 +3152,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iF" = ( /obj/machinery/washing_machine, /obj/effect/decal/cleanable/dirt, @@ -3167,7 +3167,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iG" = ( /obj/machinery/firealarm{ dir = 8; @@ -3181,7 +3181,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "iH" = ( /obj/effect/turf_decal/stripes/red/line{ dir = 4 @@ -3190,7 +3190,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "iI" = ( /obj/effect/mapping_helpers/airlock/locked, /obj/machinery/door/airlock/vault{ @@ -3208,16 +3208,16 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "iJ" = ( /turf/open/floor/circuit/red, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "iK" = ( /obj/machinery/syndicatebomb/self_destruct{ anchored = 1 }, /turf/open/floor/circuit/red, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "iM" = ( /obj/machinery/light/small{ dir = 4 @@ -3226,10 +3226,10 @@ baseturfs = /turf/open/lava/smooth/lava_land_surface; initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "iN" = ( /turf/closed/wall/mineral/plastitanium/explosive, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "iO" = ( /obj/machinery/light/small{ dir = 8 @@ -3244,7 +3244,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "iP" = ( /obj/structure/cable/yellow{ icon_state = "1-4" @@ -3254,7 +3254,7 @@ dir = 5 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "iQ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -3267,7 +3267,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "iR" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ @@ -3284,7 +3284,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iS" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 @@ -3301,7 +3301,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iT" = ( /obj/machinery/light/small, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, @@ -3315,7 +3315,7 @@ /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iU" = ( /obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ @@ -3329,7 +3329,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iV" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -3346,7 +3346,7 @@ }, /obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iW" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 @@ -3358,7 +3358,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iX" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 @@ -3373,7 +3373,7 @@ /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iY" = ( /obj/structure/table, /obj/structure/bedsheetbin, @@ -3391,7 +3391,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "iZ" = ( /obj/structure/extinguisher_cabinet{ pixel_x = -27; @@ -3405,7 +3405,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "ja" = ( /obj/effect/turf_decal/stripes/red/corner{ dir = 8 @@ -3420,7 +3420,7 @@ specialfunctions = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jb" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/red/line{ @@ -3437,11 +3437,11 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jc" = ( /obj/machinery/light/small, /turf/open/floor/circuit/red, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jd" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/red/line{ @@ -3458,7 +3458,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "je" = ( /obj/effect/turf_decal/stripes/corner{ dir = 4 @@ -3477,7 +3477,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "jg" = ( /obj/machinery/door/airlock/maintenance, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -3487,7 +3487,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "jh" = ( /obj/machinery/door/airlock{ name = "Cabin 3" @@ -3495,7 +3495,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "ji" = ( /obj/structure/cable/yellow{ icon_state = "0-2" @@ -3512,10 +3512,10 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jj" = ( /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jk" = ( /obj/effect/mapping_helpers/no_lava, /turf/open/floor/plating{ @@ -3532,7 +3532,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jm" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/red, @@ -3543,7 +3543,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jn" = ( /obj/effect/mob_spawn/human/lavaland_syndicate{ dir = 4 @@ -3552,14 +3552,14 @@ pixel_y = 24 }, /turf/open/floor/plasteel/grimy, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "jo" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/plasteel/grimy, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "jp" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, @@ -3568,7 +3568,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jq" = ( /obj/effect/mob_spawn/human/lavaland_syndicate{ dir = 8 @@ -3577,7 +3577,7 @@ pixel_y = 24 }, /turf/open/floor/plasteel/grimy, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "jr" = ( /obj/machinery/vending/snack/random{ extended_inventory = 1 @@ -3594,7 +3594,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "js" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -3604,7 +3604,7 @@ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jt" = ( /obj/machinery/light/small{ dir = 4 @@ -3614,16 +3614,16 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "ju" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "jv" = ( /obj/effect/turf_decal/bot, /obj/effect/decal/cleanable/dirt, /obj/machinery/suit_storage_unit/radsuit, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "jw" = ( /obj/effect/turf_decal/bot, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, @@ -3633,7 +3633,7 @@ }, /obj/item/crowbar, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "jx" = ( /obj/structure/grille, /obj/structure/window/plastitanium, @@ -3642,23 +3642,23 @@ id = "lavalandsyndi_bar" }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "jy" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "jz" = ( /obj/machinery/door/airlock/public/glass{ name = "Bar" }, /obj/machinery/door/firedoor, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "jA" = ( /obj/structure/table/wood, /obj/item/ammo_box/magazine/m10mm, /obj/item/ammo_box/magazine/sniper_rounds, /turf/open/floor/plasteel/grimy, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "jB" = ( /obj/machinery/light/small{ dir = 4 @@ -3667,7 +3667,7 @@ dir = 1 }, /turf/open/floor/plasteel/grimy, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "jC" = ( /obj/machinery/light/small{ dir = 8 @@ -3676,7 +3676,7 @@ dir = 1 }, /turf/open/floor/plasteel/grimy, -/area/ruin/unpowered/syndicate_lava_base/dormitories) +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories) "jD" = ( /obj/machinery/vending/cola/random{ extended_inventory = 1 @@ -3689,7 +3689,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jE" = ( /obj/structure/cable/yellow{ icon_state = "2-4" @@ -3704,7 +3704,7 @@ dir = 6 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jF" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -3720,7 +3720,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jG" = ( /obj/effect/turf_decal/delivery, /obj/machinery/door/firedoor, @@ -3738,7 +3738,7 @@ req_access_txt = "150" }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "jH" = ( /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -3753,7 +3753,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "jI" = ( /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -3775,20 +3775,20 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "jJ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ dir = 6 }, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "jK" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/on/layer3{ dir = 8; volume_rate = 200 }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "jL" = ( /obj/structure/table, /obj/effect/decal/cleanable/dirt, @@ -3811,7 +3811,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "jM" = ( /obj/machinery/light/small{ dir = 1 @@ -3826,7 +3826,7 @@ req_access_txt = "150" }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "jN" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -3839,16 +3839,16 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "jO" = ( /obj/structure/extinguisher_cabinet{ pixel_x = 25 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "jP" = ( /turf/closed/wall/mineral/plastitanium/explosive, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "jQ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, @@ -3856,7 +3856,7 @@ icon_state = "1-2" }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jR" = ( /obj/machinery/light/small{ dir = 8 @@ -3865,7 +3865,7 @@ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jS" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -3873,7 +3873,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jT" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/closet/firecloset/full{ @@ -3884,11 +3884,11 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "jU" = ( /obj/structure/sign/departments/engineering, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "jV" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -3907,7 +3907,7 @@ pixel_y = -32 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "jW" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -3919,22 +3919,22 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "jY" = ( /obj/structure/chair{ dir = 1 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "jZ" = ( /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "ka" = ( /obj/structure/closet/crate/bin, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "kb" = ( /obj/structure/rack{ dir = 8 @@ -3949,7 +3949,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "kc" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 @@ -3962,7 +3962,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "kd" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, @@ -3974,7 +3974,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "ke" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 @@ -3990,7 +3990,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "kf" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -4002,7 +4002,7 @@ icon_state = "4-8" }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "kg" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -4015,7 +4015,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "kh" = ( /obj/machinery/door/airlock/maintenance, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -4028,7 +4028,7 @@ icon_state = "4-8" }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "ki" = ( /obj/structure/cable/yellow{ icon_state = "1-8" @@ -4038,7 +4038,7 @@ }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "kj" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ dir = 8 @@ -4047,7 +4047,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "kk" = ( /obj/effect/turf_decal/delivery, /obj/machinery/door/firedoor, @@ -4061,11 +4061,11 @@ req_access_txt = "150" }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "kl" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "km" = ( /obj/structure/cable/yellow{ icon_state = "0-2" @@ -4075,7 +4075,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "kn" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/neutral{ @@ -4089,7 +4089,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "ko" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ dir = 4 @@ -4106,13 +4106,13 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "kp" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 10 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "kq" = ( /obj/machinery/airalarm/syndicate{ dir = 8; @@ -4133,7 +4133,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "kr" = ( /obj/machinery/door/airlock/maintenance{ req_access_txt = "150" @@ -4145,13 +4145,13 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "ks" = ( /obj/structure/reagent_dispensers/fueltank, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "kt" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -4161,14 +4161,14 @@ dir = 8 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "ku" = ( /turf/open/floor/plasteel/white/side, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "kv" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white/side, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "kw" = ( /obj/structure/table, /obj/effect/decal/cleanable/dirt, @@ -4184,7 +4184,7 @@ pixel_y = 4 }, /turf/open/floor/plasteel/white/side, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "kx" = ( /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -4197,7 +4197,7 @@ dir = 4 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "ky" = ( /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -4213,7 +4213,7 @@ dir = 4 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "kz" = ( /obj/structure/cable/yellow{ icon_state = "1-8" @@ -4227,7 +4227,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "kA" = ( /obj/machinery/light/small{ dir = 1 @@ -4247,7 +4247,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "kB" = ( /obj/structure/cable/yellow{ icon_state = "1-8" @@ -4255,7 +4255,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "kC" = ( /obj/machinery/computer/atmos_control/tank{ dir = 8; @@ -4271,26 +4271,26 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "kD" = ( /obj/structure/grille, /obj/structure/window/plastitanium, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "kE" = ( /obj/machinery/air_sensor{ frequency = 1442; id_tag = "syndie_lavaland_n2_sensor" }, /turf/open/floor/plating/airless, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "kF" = ( /obj/machinery/atmospherics/miner/nitrogen, /obj/machinery/light/small{ dir = 4 }, /turf/open/floor/plating/airless, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "kG" = ( /obj/structure/table, /obj/item/reagent_containers/food/drinks/beer, @@ -4306,19 +4306,19 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "kH" = ( /obj/structure/chair{ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "kI" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "kJ" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -4336,14 +4336,14 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "kK" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "kL" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 @@ -4361,7 +4361,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "kM" = ( /obj/machinery/firealarm{ dir = 4; @@ -4373,7 +4373,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "kN" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -4381,7 +4381,7 @@ pixel_y = 28 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "kO" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, @@ -4390,7 +4390,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "kP" = ( /obj/structure/reagent_dispensers/watertank, /obj/effect/decal/cleanable/dirt, @@ -4398,17 +4398,17 @@ /obj/item/mop, /obj/item/reagent_containers/glass/bucket, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "kQ" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "kR" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/medical/glass{ name = "Medbay" }, /turf/open/floor/plasteel/white, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "kS" = ( /obj/machinery/door/firedoor, /obj/effect/decal/cleanable/dirt, @@ -4416,17 +4416,17 @@ name = "Medbay" }, /turf/open/floor/plasteel/white, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "kT" = ( /obj/structure/sign/departments/medbay/alt, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "kU" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 1 }, /turf/closed/wall/mineral/plastitanium/explosive, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "kV" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -4439,7 +4439,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "kW" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -4448,7 +4448,7 @@ /obj/structure/cable/yellow, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "kX" = ( /obj/machinery/atmospherics/pipe/simple/supply/visible{ dir = 5 @@ -4459,7 +4459,7 @@ piping_layer = 3 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "kY" = ( /obj/machinery/atmospherics/pipe/manifold4w/supply/visible, /obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3, @@ -4467,7 +4467,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "kZ" = ( /obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped{ dir = 4 @@ -4477,7 +4477,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "la" = ( /obj/machinery/atmospherics/pipe/simple/supplymain/visible{ dir = 4 @@ -4493,7 +4493,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "lb" = ( /obj/structure/grille, /obj/structure/window/plastitanium, @@ -4504,7 +4504,7 @@ dir = 10 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "lc" = ( /obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ dir = 8; @@ -4513,7 +4513,7 @@ name = "nitrogen out" }, /turf/open/floor/plating/airless, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "ld" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/layer3{ dir = 4; @@ -4521,7 +4521,7 @@ piping_layer = 3 }, /turf/open/floor/plating/airless, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "le" = ( /obj/machinery/light/small{ dir = 4 @@ -4531,7 +4531,7 @@ baseturfs = /turf/open/lava/smooth/lava_land_surface; initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "lf" = ( /obj/machinery/light/small{ dir = 8 @@ -4545,7 +4545,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lg" = ( /obj/structure/chair/stool/bar, /obj/effect/decal/cleanable/dirt, @@ -4560,11 +4560,11 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lh" = ( /obj/structure/table/wood, /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "li" = ( /obj/structure/table/wood, /obj/item/toy/cards/deck/syndicate{ @@ -4574,7 +4574,7 @@ /turf/open/floor/wood{ icon_state = "wood-broken4" }, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lj" = ( /obj/machinery/door/window/southleft{ base_state = "right"; @@ -4585,7 +4585,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lk" = ( /obj/structure/table/wood, /obj/machinery/light/small{ @@ -4605,7 +4605,7 @@ /obj/item/book/manual/wiki/barman_recipes, /obj/item/reagent_containers/food/drinks/shaker, /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "ll" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, @@ -4614,7 +4614,7 @@ }, /obj/structure/reagent_dispensers/beerkeg, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lm" = ( /obj/structure/closet/secure_closet/medical1{ req_access = null; @@ -4625,12 +4625,12 @@ /turf/open/floor/plasteel/white/side{ dir = 9 }, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "ln" = ( /turf/open/floor/plasteel/white/side{ dir = 1 }, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "lo" = ( /obj/machinery/light/small{ dir = 1 @@ -4642,7 +4642,7 @@ /turf/open/floor/plasteel/white/side{ dir = 5 }, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "lp" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -4655,7 +4655,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "lq" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -4671,13 +4671,13 @@ icon_state = "2-8" }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "lr" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 10 }, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "ls" = ( /obj/machinery/atmospherics/pipe/simple/supply/visible, /obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3, @@ -4685,14 +4685,14 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "lt" = ( /obj/machinery/atmospherics/pipe/simple/supplymain/visible, /obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "lu" = ( /obj/machinery/light/small{ dir = 4 @@ -4704,7 +4704,7 @@ dir = 10 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "lv" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -4739,11 +4739,11 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "ly" = ( /obj/structure/chair/stool/bar, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lz" = ( /obj/structure/table/wood, /obj/item/reagent_containers/rag{ @@ -4756,15 +4756,15 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lA" = ( /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lB" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lC" = ( /obj/structure/table/wood, /obj/machinery/reagentgrinder, @@ -4773,11 +4773,11 @@ pixel_x = 6 }, /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lE" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lF" = ( /obj/machinery/light/small{ dir = 4 @@ -4800,7 +4800,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lG" = ( /obj/structure/table, /obj/item/storage/box/syringes, @@ -4810,20 +4810,20 @@ /turf/open/floor/plasteel/white/side{ dir = 9 }, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "lH" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white/corner{ dir = 1 }, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "lI" = ( /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "lJ" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "lK" = ( /obj/structure/table, /obj/item/storage/firstaid/regular, @@ -4831,7 +4831,7 @@ /turf/open/floor/plasteel/white/side{ dir = 4 }, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "lL" = ( /obj/machinery/airalarm/syndicate{ dir = 4; @@ -4855,21 +4855,21 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "lM" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/layer3{ id = "syndie_lavaland_tox_in"; piping_layer = 3 }, /turf/open/floor/plating/airless, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "lN" = ( /obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/o2{ dir = 1; piping_layer = 3 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "lO" = ( /obj/machinery/atmospherics/pipe/simple/supply/visible, /obj/effect/decal/cleanable/dirt, @@ -4878,7 +4878,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "lP" = ( /obj/machinery/computer/atmos_control/tank{ dir = 8; @@ -4896,27 +4896,27 @@ dir = 5 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "lQ" = ( /obj/machinery/air_sensor{ frequency = 1442; id_tag = "syndie_lavaland_o2_sensor" }, /turf/open/floor/plating/airless, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "lR" = ( /obj/machinery/atmospherics/miner/oxygen, /obj/machinery/light/small{ dir = 4 }, /turf/open/floor/plating/airless, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "lS" = ( /obj/machinery/porta_turret/syndicate{ dir = 9 }, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "lT" = ( /obj/structure/fans/tiny, /obj/machinery/door/airlock/external{ @@ -4924,7 +4924,7 @@ }, /obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "lU" = ( /obj/machinery/airalarm/syndicate{ dir = 4; @@ -4942,7 +4942,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lV" = ( /obj/structure/chair/stool/bar, /obj/effect/turf_decal/tile/neutral{ @@ -4956,7 +4956,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lW" = ( /obj/structure/table/wood, /obj/structure/cable/yellow{ @@ -4964,13 +4964,13 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lX" = ( /obj/structure/cable/yellow{ icon_state = "4-8" }, /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lY" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 @@ -4982,7 +4982,7 @@ icon_state = "4-8" }, /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "lZ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -4994,7 +4994,7 @@ icon_state = "4-8" }, /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "ma" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -5010,7 +5010,7 @@ icon_state = "4-8" }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "mb" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -5022,7 +5022,7 @@ icon_state = "4-8" }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "mc" = ( /obj/item/storage/box/donkpockets{ pixel_x = -2; @@ -5048,7 +5048,7 @@ req_access = null }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "md" = ( /obj/machinery/sleeper/syndie{ dir = 4 @@ -5056,11 +5056,11 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "me" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "mf" = ( /obj/structure/sink{ dir = 4; @@ -5072,7 +5072,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "mg" = ( /obj/machinery/firealarm{ dir = 8; @@ -5087,13 +5087,13 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "mh" = ( /obj/structure/cable{ icon_state = "1-2" }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "mi" = ( /obj/machinery/atmospherics/pipe/simple/orange/visible{ dir = 6 @@ -5103,7 +5103,7 @@ dir = 5 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "mj" = ( /obj/machinery/atmospherics/components/binary/pump/on{ dir = 8; @@ -5116,13 +5116,13 @@ dir = 9 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "mk" = ( /obj/machinery/atmospherics/pipe/manifold/supplymain/visible, /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "ml" = ( /obj/machinery/atmospherics/pipe/simple/supplymain/visible{ dir = 4 @@ -5133,7 +5133,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "mm" = ( /obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ dir = 8; @@ -5142,13 +5142,13 @@ name = "oxygen out" }, /turf/open/floor/plating/airless, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "mn" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "mo" = ( /turf/closed/wall/mineral/plastitanium/explosive, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "mp" = ( /obj/structure/grille, /obj/structure/window/plastitanium, @@ -5157,16 +5157,16 @@ id = "lavalandsyndi_telecomms" }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "mq" = ( /obj/structure/sign/warning/vacuum{ pixel_x = -32 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "mr" = ( /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "ms" = ( /obj/machinery/light/small{ dir = 4 @@ -5179,7 +5179,7 @@ /obj/item/flashlight/seclite, /obj/item/clothing/mask/gas, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "mu" = ( /obj/item/kirbyplants{ icon_state = "plant-22" @@ -5187,7 +5187,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "mv" = ( /obj/structure/table/wood, /obj/machinery/light/small, @@ -5197,23 +5197,23 @@ pixel_y = -24 }, /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "mw" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "mx" = ( /obj/structure/table/wood, /obj/machinery/microwave, /turf/open/floor/wood, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "my" = ( /obj/structure/closet/secure_closet/freezer/fridge, /obj/item/reagent_containers/food/condiment/enzyme, /obj/item/reagent_containers/food/snacks/chocolatebar, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "mz" = ( /obj/machinery/door/airlock/maintenance, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -5223,7 +5223,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/main) +/area/ruin/lavaland/unpowered/syndicate_lava_base/main) "mA" = ( /obj/machinery/light/small{ dir = 8 @@ -5239,26 +5239,26 @@ /turf/open/floor/plasteel/white/side{ dir = 8 }, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "mB" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "mC" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "mD" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "mE" = ( /obj/structure/table/reinforced, /obj/item/scalpel, @@ -5273,7 +5273,7 @@ /turf/open/floor/plasteel/white/side{ dir = 4 }, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "mF" = ( /obj/structure/extinguisher_cabinet{ pixel_x = -27; @@ -5282,21 +5282,21 @@ /obj/structure/chair/stool, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "mG" = ( /obj/structure/cable{ icon_state = "1-2" }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "mH" = ( /obj/machinery/atmospherics/pipe/manifold/orange/visible{ dir = 8 }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "mI" = ( /obj/effect/turf_decal/stripes/corner, /obj/machinery/light/small, @@ -5310,7 +5310,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/visible, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "mJ" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/simple/orange/visible{ @@ -5323,7 +5323,7 @@ dir = 5 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "mK" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/computer/atmos_control/tank{ @@ -5340,21 +5340,21 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "mM" = ( /turf/open/floor/circuit/green, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "mN" = ( /obj/structure/sign/warning/securearea, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "mP" = ( /obj/structure/filingcabinet/security, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "mQ" = ( /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "mR" = ( /obj/structure/table, /obj/item/storage/toolbox/syndicate, @@ -5366,7 +5366,7 @@ req_access_txt = "150" }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "mS" = ( /obj/machinery/door/airlock/external{ req_access_txt = "150" @@ -5376,16 +5376,16 @@ dir = 1 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "mT" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "mU" = ( /obj/structure/grille, /obj/structure/window/plastitanium, /obj/machinery/door/firedoor, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/bar) +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar) "mX" = ( /obj/structure/rack{ dir = 8 @@ -5404,7 +5404,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "mY" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, @@ -5416,20 +5416,20 @@ /turf/open/floor/plasteel/white/side{ dir = 4 }, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "mZ" = ( /obj/machinery/sleeper/syndie{ dir = 4 }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "na" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "nb" = ( /obj/structure/table/optable, /obj/item/surgical_drapes, @@ -5437,7 +5437,7 @@ /turf/open/floor/plasteel/white/side{ dir = 4 }, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "nc" = ( /obj/machinery/computer/turbine_computer{ dir = 1; @@ -5455,7 +5455,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "nd" = ( /obj/structure/cable{ icon_state = "1-2" @@ -5463,7 +5463,7 @@ /obj/effect/turf_decal/stripes/line, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "ne" = ( /obj/machinery/atmospherics/pipe/simple/orange/visible, /obj/machinery/embedded_controller/radio/airlock_controller/incinerator_syndicatelava{ @@ -5479,17 +5479,17 @@ /obj/machinery/portable_atmospherics/canister, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "nf" = ( /obj/structure/sign/warning/fire, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "ng" = ( /obj/structure/grille, /obj/structure/window/plastitanium, /obj/machinery/atmospherics/pipe/simple/orange/visible, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "nh" = ( /obj/machinery/telecomms/relay/preset/ruskie{ use_power = 0 @@ -5508,7 +5508,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "ni" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -5521,7 +5521,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "nj" = ( /obj/machinery/door/airlock/hatch{ name = "Telecommunications Control"; @@ -5538,7 +5538,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "nk" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ dir = 4 @@ -5554,7 +5554,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "nl" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 4 @@ -5570,7 +5570,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "nm" = ( /obj/machinery/light/small{ dir = 4 @@ -5594,14 +5594,14 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "nn" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "no" = ( /obj/effect/turf_decal/stripes/corner{ dir = 4 @@ -5610,7 +5610,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "np" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/red{ @@ -5620,7 +5620,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nq" = ( /obj/effect/turf_decal/tile/red{ dir = 1 @@ -5629,7 +5629,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nr" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/red{ @@ -5640,7 +5640,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "ns" = ( /obj/structure/closet/emcloset/anchored, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -5663,7 +5663,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nt" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -5690,7 +5690,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nu" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -5708,7 +5708,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nv" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 @@ -5726,7 +5726,7 @@ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nw" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, @@ -5739,7 +5739,7 @@ /turf/open/floor/plasteel/white/side{ dir = 4 }, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nx" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -5755,7 +5755,7 @@ name = "Medbay" }, /turf/open/floor/plasteel/white, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "ny" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -5769,7 +5769,7 @@ /turf/open/floor/plasteel/white/side{ dir = 8 }, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "nz" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 @@ -5781,20 +5781,20 @@ icon_state = "4-8" }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "nA" = ( /obj/structure/cable/yellow{ icon_state = "2-8" }, /turf/open/floor/plasteel/white/corner, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "nB" = ( /obj/structure/table/reinforced, /obj/item/surgicaldrill, /obj/item/cautery, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white/side, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "nC" = ( /obj/structure/table/reinforced, /obj/item/retractor, @@ -5803,7 +5803,7 @@ /turf/open/floor/plasteel/white/side{ dir = 6 }, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "nD" = ( /obj/structure/cable{ icon_state = "1-2" @@ -5812,11 +5812,11 @@ /obj/machinery/door/airlock/glass/incinerator/syndicatelava_interior, /obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "nE" = ( /obj/machinery/atmospherics/pipe/simple/orange/visible, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "nF" = ( /obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ dir = 1; @@ -5825,14 +5825,14 @@ name = "toxin out" }, /turf/open/floor/plating/airless, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "nG" = ( /obj/machinery/air_sensor{ frequency = 1442; id_tag = "syndie_lavaland_tox_sensor" }, /turf/open/floor/plating/airless, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "nH" = ( /obj/machinery/airalarm/syndicate{ dir = 4; @@ -5852,7 +5852,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "nI" = ( /obj/machinery/computer/camera_advanced, /obj/effect/turf_decal/tile/neutral{ @@ -5866,7 +5866,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "nJ" = ( /obj/structure/table/reinforced, /obj/effect/turf_decal/tile/neutral{ @@ -5880,7 +5880,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "nK" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 @@ -5902,7 +5902,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "nL" = ( /obj/machinery/door/airlock/hatch{ name = "Telecommunications"; @@ -5928,7 +5928,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "nM" = ( /obj/machinery/light/small, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -5943,7 +5943,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nN" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -5955,7 +5955,7 @@ icon_state = "4-8" }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nO" = ( /obj/effect/turf_decal/stripes/corner, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -5969,7 +5969,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nP" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/caution/stand_clear{ @@ -5985,7 +5985,7 @@ icon_state = "4-8" }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nQ" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -6001,7 +6001,7 @@ icon_state = "4-8" }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -6016,7 +6016,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nS" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 @@ -6037,7 +6037,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nT" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -6055,7 +6055,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nU" = ( /obj/machinery/light/small{ dir = 1 @@ -6080,7 +6080,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nV" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 @@ -6095,14 +6095,14 @@ dir = 1 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nW" = ( /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nX" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nY" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, @@ -6111,22 +6111,22 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "nZ" = ( /obj/machinery/light/small, /turf/open/floor/plasteel/white/side{ dir = 4 }, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "oa" = ( /turf/open/floor/plasteel/white/side{ dir = 10 }, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "ob" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white/side, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "oc" = ( /obj/machinery/light/small, /obj/structure/extinguisher_cabinet{ @@ -6142,7 +6142,7 @@ /turf/open/floor/plasteel/white/side{ dir = 6 }, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "od" = ( /obj/machinery/light/small{ dir = 8 @@ -6151,7 +6151,7 @@ dir = 4 }, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "oe" = ( /obj/structure/cable{ icon_state = "1-2" @@ -6160,7 +6160,7 @@ dir = 8 }, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "of" = ( /obj/machinery/light/small{ dir = 4 @@ -6175,12 +6175,12 @@ pixel_x = 22 }, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "og" = ( /obj/machinery/atmospherics/miner/toxins, /obj/machinery/light/small, /turf/open/floor/plating/airless, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "oh" = ( /obj/machinery/firealarm{ dir = 8; @@ -6197,7 +6197,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "oi" = ( /obj/structure/chair/office/dark{ dir = 4 @@ -6213,7 +6213,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "oj" = ( /obj/structure/table/reinforced, /obj/item/radio/intercom{ @@ -6231,7 +6231,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "ok" = ( /obj/structure/chair{ dir = 8 @@ -6252,7 +6252,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "ol" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -6266,7 +6266,7 @@ /obj/item/mining_scanner, /obj/item/pickaxe, /turf/open/floor/mineral/plastitanium, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "om" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/red, @@ -6274,7 +6274,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "on" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 @@ -6288,14 +6288,14 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "oo" = ( /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "op" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ dir = 1 @@ -6305,7 +6305,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "oq" = ( /obj/machinery/button/door{ id = "lavalandsyndi_arrivals"; @@ -6318,7 +6318,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "or" = ( /obj/structure/rack{ dir = 8 @@ -6329,7 +6329,7 @@ /obj/item/clothing/glasses/hud/health, /obj/item/clothing/neck/stethoscope, /turf/open/floor/plasteel/white, -/area/ruin/unpowered/syndicate_lava_base/medbay) +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay) "ot" = ( /obj/structure/cable{ icon_state = "1-2" @@ -6340,20 +6340,20 @@ dir = 1 }, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "ou" = ( /obj/machinery/computer/message_monitor{ dir = 1 }, /obj/item/paper/monitorkey, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "ov" = ( /obj/structure/table/reinforced, /obj/item/paper_bin, /obj/item/pen, /turf/open/floor/plasteel/dark, -/area/ruin/unpowered/syndicate_lava_base/telecomms) +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms) "ox" = ( /obj/structure/grille, /obj/structure/window/plastitanium, @@ -6362,17 +6362,17 @@ id = "lavalandsyndi_arrivals" }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "oz" = ( /turf/open/floor/engine/vacuum, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "oA" = ( /obj/structure/cable{ icon_state = "1-2" }, /obj/machinery/igniter/incinerator_syndicatelava, /turf/open/floor/engine/vacuum, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "oB" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/atmos{ dir = 1; @@ -6382,11 +6382,11 @@ pixel_y = -32 }, /turf/open/floor/engine/vacuum, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "oC" = ( /obj/machinery/door/poddoor/incinerator_syndicatelava_aux, /turf/open/floor/engine/vacuum, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "oD" = ( /obj/structure/sign/warning/xeno_mining{ pixel_x = -32 @@ -6395,7 +6395,7 @@ pixel_x = 32 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "oE" = ( /obj/structure/cable, /obj/structure/cable{ @@ -6408,22 +6408,22 @@ luminosity = 2 }, /turf/open/floor/engine/vacuum, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "oF" = ( /obj/structure/sign/warning/securearea, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "oG" = ( /obj/structure/cable, /obj/machinery/power/turbine{ luminosity = 2 }, /turf/open/floor/engine/vacuum, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "oH" = ( /obj/machinery/door/poddoor/incinerator_syndicatelava_main, /turf/open/floor/engine/vacuum, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "oI" = ( /obj/structure/sign/warning/vacuum{ pixel_x = -32 @@ -6432,11 +6432,11 @@ dir = 8 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "oP" = ( /obj/structure/sign/departments/chemistry, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "pC" = ( /obj/structure/grille, /obj/structure/window/plastitanium, @@ -6444,29 +6444,29 @@ dir = 10 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "qc" = ( /obj/machinery/atmospherics/pipe/simple/supplymain/visible, /obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3{ dir = 10 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "tW" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "uB" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 5 }, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "vu" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "BF" = ( /obj/structure/grille, /obj/structure/window/plastitanium, @@ -6478,7 +6478,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "Cg" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 @@ -6487,7 +6487,7 @@ dir = 4 }, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "CG" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 @@ -6496,7 +6496,7 @@ dir = 10 }, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "EZ" = ( /obj/machinery/door/airlock/external{ req_access_txt = "150" @@ -6504,65 +6504,65 @@ /obj/structure/fans/tiny, /obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "Gm" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "Go" = ( /obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/plasma{ dir = 1; piping_layer = 3 }, /turf/open/floor/plasteel, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "IJ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 1 }, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "KA" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 4 }, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "Lg" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ dir = 4 }, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "LQ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "MP" = ( /obj/effect/decal/cleanable/dirt, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "Ng" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 9 }, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "Pa" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/circuits) +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits) "RE" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 }, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "RV" = ( /obj/structure/sign/warning/fire, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "St" = ( /obj/structure/fans/tiny, /obj/machinery/door/airlock/external{ @@ -6572,7 +6572,7 @@ dir = 1 }, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/arrivals) +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals) "Tp" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 4 @@ -6581,7 +6581,7 @@ dir = 4 }, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "Tt" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/layer3{ dir = 4; @@ -6589,7 +6589,7 @@ piping_layer = 3 }, /turf/open/floor/plating/airless, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "TC" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ dir = 4 @@ -6598,7 +6598,7 @@ dir = 4 }, /turf/open/floor/engine, -/area/ruin/unpowered/syndicate_lava_base/testlab) +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab) "Vw" = ( /obj/structure/grille, /obj/structure/window/plastitanium, @@ -6607,7 +6607,7 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/plating, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) "Wq" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ dir = 5 @@ -6616,7 +6616,7 @@ dir = 10 }, /turf/closed/wall/mineral/plastitanium/nodiagonal, -/area/ruin/unpowered/syndicate_lava_base/engineering) +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering) (1,1,1) = {" aa diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm index 7ac6d32b80..691ad183b2 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm @@ -10,14 +10,14 @@ /area/lavaland/surface/outdoors) "d" = ( /turf/closed/wall/mineral/abductor, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "h" = ( /obj/structure/closet/abductor, /obj/item/tcg_card/special/abductor, /turf/open/floor/plating/abductor{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "j" = ( /obj/machinery/abductor/experiment{ team_number = 100 @@ -25,12 +25,12 @@ /turf/open/floor/plating/abductor{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "k" = ( /turf/open/floor/plating/abductor{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "l" = ( /obj/machinery/abductor/pad{ team_number = 100 @@ -38,59 +38,59 @@ /turf/open/floor/plating/abductor{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "o" = ( /obj/item/hemostat/alien, /turf/open/floor/plating/abductor{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "p" = ( /obj/effect/mob_spawn/human/abductor, /turf/open/floor/plating/abductor{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "q" = ( /obj/structure/closet/abductor, /turf/open/floor/plating/abductor{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "s" = ( /obj/structure/table/optable/abductor, /obj/item/cautery/alien, /turf/open/floor/plating/abductor{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "t" = ( /obj/structure/table/abductor, /obj/item/storage/box/alienhandcuffs, /turf/open/floor/plating/abductor{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "v" = ( /obj/item/scalpel/alien, /obj/item/surgical_drapes, /turf/open/floor/plating/abductor{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "w" = ( /obj/item/retractor/alien, /obj/item/paper/guides/antag/abductor, /turf/open/floor/plating/abductor{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "y" = ( /obj/machinery/abductor/gland_dispenser, /turf/open/floor/plating/abductor{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "z" = ( /obj/structure/table/abductor, /obj/item/surgicaldrill/alien, @@ -98,13 +98,13 @@ /turf/open/floor/plating/abductor{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) "A" = ( /obj/structure/bed/abductor, /turf/open/floor/plating/abductor{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered) +/area/ruin/lavaland/unpowered) (1,1,1) = {" a diff --git a/_maps/RandomRuins/SpaceRuins/deepstorage.dmm b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm index 5b246e57db..ea821570bd 100644 --- a/_maps/RandomRuins/SpaceRuins/deepstorage.dmm +++ b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm @@ -49,7 +49,6 @@ /area/ruin/space/has_grav/deepstorage/crusher) "an" = ( /obj/machinery/conveyor{ - dir = 2; id = "bunkerrecycle" }, /turf/open/floor/plating, @@ -142,7 +141,6 @@ icon_state = "0-8" }, /obj/machinery/power/apc{ - dir = 2; name = "Recycling APC"; pixel_y = -23 }, @@ -694,7 +692,6 @@ icon_state = "0-8" }, /obj/machinery/power/apc{ - dir = 2; name = "Kitchen APC"; pixel_y = -23 }, @@ -1762,7 +1759,6 @@ }, /obj/structure/cable/yellow, /obj/machinery/power/apc{ - dir = 2; name = "Main Area APC"; pixel_y = -23 }, @@ -2682,6 +2678,7 @@ /area/ruin/space/has_grav/deepstorage) "fU" = ( /obj/machinery/camera{ + c_tag = "Deep Storage - Entry"; network = list("bunker1") }, /obj/structure/sign/warning/securearea{ diff --git a/_maps/RandomRuins/SpaceRuins/mechtransport.dmm b/_maps/RandomRuins/SpaceRuins/mechtransport.dmm index a9beb9540e..dbe8722b83 100644 --- a/_maps/RandomRuins/SpaceRuins/mechtransport.dmm +++ b/_maps/RandomRuins/SpaceRuins/mechtransport.dmm @@ -102,7 +102,7 @@ /turf/open/floor/mineral/titanium/yellow/airless, /area/ruin/space/has_grav/powered/mechtransport) "A" = ( -/obj/mecha/working/ripley, +/obj/vehicle/sealed/mecha/working/ripley, /turf/open/floor/mineral/titanium/yellow/airless, /area/ruin/space/has_grav/powered/mechtransport) "B" = ( diff --git a/_maps/RandomRuins/SpaceRuins/skelter.dmm b/_maps/RandomRuins/SpaceRuins/skelter.dmm index 8dd0b3b5e1..694d093eeb 100644 --- a/_maps/RandomRuins/SpaceRuins/skelter.dmm +++ b/_maps/RandomRuins/SpaceRuins/skelter.dmm @@ -875,7 +875,8 @@ /area/service/cafeteria) "cj" = ( /obj/effect/decal/cleanable/blood/old, -/obj/item/clothing/suit/space/syndicate/orange, +/obj/item/clothing/suit/space/syndicate/green/dark, +/obj/item/clothing/head/helmet/space/syndicate/green/dark, /turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/skelter/sec) "ck" = ( @@ -1366,6 +1367,9 @@ dir = 1; icon_state = "trimline_fill" }, +/mob/living/simple_animal/hostile/syndicate/melee/sword/space{ + name = "Impostrous Commando" + }, /turf/open/floor/plasteel, /area/ruin/space/has_grav/skelter/nav) "ds" = ( @@ -1895,6 +1899,7 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, +/obj/item/clothing/head/helmet/space/syndicate/blue, /turf/open/floor/plating, /area/ruin/space/has_grav/skelter/engine/powerstorage) "eC" = ( @@ -2483,6 +2488,7 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, +/obj/item/clothing/head/helmet/space/syndicate, /turf/open/floor/plating, /area/ruin/space/has_grav/skelter/engine/powerstorage) "fR" = ( @@ -2581,6 +2587,7 @@ /obj/item/clothing/suit/space/syndicate/orange{ desc = "Wait, don't these normally come with a helmet?" }, +/obj/item/clothing/head/helmet/space/syndicate/orange, /turf/open/floor/plating, /area/ruin/space/has_grav/skelter/forehall) "gg" = ( @@ -2726,6 +2733,7 @@ dir = 1; pixel_y = -24 }, +/obj/item/clothing/head/helmet/space/syndicate/green, /turf/open/floor/carpet, /area/ruin/space/has_grav/skelter/admin) "gx" = ( @@ -2823,6 +2831,10 @@ /area/ruin/space/has_grav/skelter/engine/lower) "gH" = ( /obj/structure/rack, +/obj/item/dnainjector/tonguespike{ + desc = "It's a little suspicious."; + name = "suspicious serum" + }, /turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/skelter/sec) "gI" = ( @@ -2907,18 +2919,18 @@ /turf/open/floor/mineral/titanium/white, /area/ruin/space/has_grav/skelter/shields) "gT" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8; - icon_state = "scrub_map_on-2" - }, /obj/structure/cable/yellow{ icon_state = "0-8" }, /obj/machinery/power/apc{ + cell_type = null; dir = 1; name = "Shield Room APC"; pixel_y = 23 }, +/obj/machinery/atmospherics/components/unary/vent_scrubber{ + dir = 8 + }, /turf/open/floor/mineral/titanium/white, /area/ruin/space/has_grav/skelter/shields) "gU" = ( @@ -3136,7 +3148,9 @@ /obj/structure/cable/yellow{ icon_state = "1-8" }, -/turf/open/floor/mineral/titanium/white, +/turf/open/floor/plating/airless{ + icon_state = "platingdmg1" + }, /area/ruin/space/has_grav/skelter/shields) "hp" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -3325,7 +3339,9 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/turf/open/floor/mineral/titanium/white, +/turf/open/floor/plating/airless{ + icon_state = "platingdmg2" + }, /area/ruin/space/has_grav/skelter/shields) "hO" = ( /obj/machinery/shieldgen, @@ -3523,18 +3539,20 @@ /turf/open/floor/circuit, /area/ruin/space/has_grav/skelter/shields) "il" = ( -/turf/open/floor/mineral/titanium/white, +/obj/structure/lattice, +/turf/open/space/basic, /area/ruin/space/has_grav/skelter/shields) "im" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/obj/machinery/light, /obj/machinery/firealarm{ dir = 4; pixel_x = 24 }, -/turf/open/floor/mineral/titanium/white, +/obj/machinery/atmospherics/components/unary/vent_pump{ + dir = 1 + }, +/turf/open/floor/plating/airless{ + icon_state = "platingdmg3" + }, /area/ruin/space/has_grav/skelter/shields) "in" = ( /turf/open/floor/plasteel{ @@ -3722,10 +3740,6 @@ /obj/effect/turf_decal/tile/blue{ dir = 1 }, -/obj/item/uplink/old{ - pixel_x = -4; - pixel_y = 8 - }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4; icon_state = "scrub_map_on-2" @@ -3839,7 +3853,10 @@ /area/ruin/space/has_grav/skelter/comms) "iP" = ( /obj/structure/rack, -/obj/item/gun/ballistic/automatic/pistol, +/obj/item/book/granter/martial/cqc{ + name = "dusty manual"; + used = 1 + }, /turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/skelter/sec) "iQ" = ( @@ -3874,20 +3891,6 @@ }, /turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/skelter/storage) -"iU" = ( -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/machinery/telecomms/relay/preset/auto, -/turf/open/floor/plasteel/showroomfloor, -/area/ruin/space/has_grav/skelter/comms) "iV" = ( /obj/structure/chair/comfy/teal, /obj/effect/turf_decal/tile/blue, @@ -3917,6 +3920,7 @@ /obj/item/clothing/suit/space/syndicate/black{ desc = "Wait, don't these normally come with a helmet?" }, +/obj/item/clothing/head/helmet/space/syndicate/black, /turf/open/floor/plasteel/showroomfloor, /area/ruin/space/has_grav/skelter/comms) "iX" = ( @@ -4078,7 +4082,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 1 }, -/obj/machinery/telecomms/allinone, +/mob/living/simple_animal/hostile/syndicate/melee/space{ + name = "Impostrous Commando" + }, /turf/open/floor/plasteel/showroomfloor, /area/ruin/space/has_grav/skelter/comms) "jo" = ( @@ -4146,12 +4152,6 @@ /obj/item/gun/ballistic/automatic/pistol/no_mag, /turf/open/floor/plasteel/showroomfloor, /area/ruin/space/has_grav/skelter/comms) -"jw" = ( -/turf/open/space/basic, -/area/space/nearstation) -"jx" = ( -/turf/open/space/basic, -/area/template_noop) "jy" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -4166,6 +4166,66 @@ /obj/item/ammo_casing/c10mm, /turf/open/floor/plasteel/showroomfloor, /area/ruin/space/has_grav/skelter/comms) +"sg" = ( +/obj/effect/turf_decal/weather, +/turf/open/floor/plating/airless, +/area/ruin/space/has_grav/skelter/shields) +"vv" = ( +/mob/living/simple_animal/hostile/syndicate/melee/space{ + name = "Impostrous Commando" + }, +/turf/open/floor/plasteel/showroomfloor, +/area/ruin/space/has_grav/skelter/engine/powerstorage) +"vz" = ( +/obj/structure/fluff/broken_flooring{ + icon_state = "singular" + }, +/turf/open/floor/plating/airless{ + icon_state = "platingdmg3" + }, +/area/ruin/space/has_grav/skelter/shields) +"AJ" = ( +/turf/open/floor/plating/asteroid/airless, +/area/ruin/space/has_grav/skelter/shields) +"AR" = ( +/mob/living/simple_animal/hostile/syndicate/ranged/shotgun/space{ + name = "Impostrous Commando" + }, +/turf/open/floor/plasteel/dark, +/area/ruin/space/has_grav/skelter/sec) +"JR" = ( +/obj/effect/turf_decal/weather, +/turf/open/floor/plating/airless{ + icon_state = "platingdmg2" + }, +/area/ruin/space/has_grav/skelter/shields) +"Li" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/lattice, +/turf/open/space/basic, +/area/ruin/space/has_grav/skelter/shields) +"OA" = ( +/obj/structure/fluff/broken_flooring{ + icon_state = "singular" + }, +/turf/template_noop, +/area/template_noop) +"WM" = ( +/obj/effect/turf_decal/weather, +/turf/open/floor/plating/airless, +/area/ruin/unpowered/no_grav) +"Zs" = ( +/obj/item/shard{ + icon_state = "medium" + }, +/obj/structure/fluff/broken_flooring{ + dir = 8; + icon_state = "pile" + }, +/turf/template_noop, +/area/template_noop) (1,1,1) = {" ah @@ -4483,7 +4543,7 @@ cF cF ex eW -cF +AR fN gj hJ @@ -4525,7 +4585,7 @@ iI iQ iY ji -jx +ah "} (13,1,1) = {" ah @@ -4549,7 +4609,7 @@ gj iP gl hx -hx +vv is hx eA @@ -4705,7 +4765,7 @@ fV hX jb jj -jw +ah "} (19,1,1) = {" ah @@ -4885,7 +4945,7 @@ gO iT jf jk -jw +ah "} (25,1,1) = {" ay @@ -4942,7 +5002,7 @@ hH ih iG iN -iU +iO ii jl ah @@ -5091,10 +5151,10 @@ hn hM ik iH -gA -bx -ae -ah +gz +bL +bL +ak ah "} (32,1,1) = {" @@ -5118,13 +5178,13 @@ ga gx gR ho -hM +Li +vz il -il -gA -ae -ah -ah +sg +bL +ak +ak ah "} (33,1,1) = {" @@ -5150,12 +5210,12 @@ gS hp hN im -gA -gU -ah -ah -ah -ah +sg +JR +ac +ak +ak +bq "} (34,1,1) = {" ah @@ -5179,13 +5239,13 @@ gz gT hq hO -gA -gU -ah -ah -ah -ah -ah +gz +sg +WM +ac +ak +ak +cl "} (35,1,1) = {" aS @@ -5207,15 +5267,15 @@ dV gd gA gU -gU -gU -gU -ah -ah -ah -ah -ah -ah +gz +AJ +gz +ac +ac +ac +ac +ak +aZ "} (36,1,1) = {" ah @@ -5237,15 +5297,15 @@ fI ge gB gV -jw -ah -ah -ah -ah -ah -ah -ah -ah +aZ +ac +ak +ak +ac +ac +ac +ac +aZ "} (37,1,1) = {" ah @@ -5267,15 +5327,15 @@ cR gf ct cR -ah -ah -ah -ah -ah -ah -ah -ah -ah +aZ +ak +ak +ak +ak +ac +ac +ac +Zs "} (38,1,1) = {" ah @@ -5296,16 +5356,16 @@ bx dV ct ct -ah -ah -ah -ah -ah -ah -ah -ah -ah -ah +aZ +aZ +ac +ak +ak +ak +ak +ak +ac +aZ "} (39,1,1) = {" ah @@ -5326,16 +5386,16 @@ cu cb ae ah -ah -ah -ah -ah -ah -ah -ah -ah -ah -ah +OA +cl +do +ac +ak +ak +ak +ac +aZ +aS "} (40,1,1) = {" ah @@ -5356,15 +5416,15 @@ fr cc ah ah +do +aS +bq ah +aZ +aZ ah -ah -ah -ah -ah -ah -ah -ah +aZ +aS ah "} (41,1,1) = {" @@ -5387,13 +5447,13 @@ cc ah ah ah +aZ +do ah ah -ah -ah -ah -ah -ah +do +aZ +ba ah ah "} @@ -5419,12 +5479,12 @@ ah ah ah ah +bF ah ah ah ah -ah -ah +aZ ah "} (43,1,1) = {" @@ -5445,15 +5505,15 @@ ce ce ce ah +aZ +cl ah ah ah +aZ +aS ah -ah -ah -ah -ah -ah +cl ah ah "} @@ -5476,7 +5536,7 @@ ah ah ah ah -ah +bq ah ah ah diff --git a/_maps/RandomRuins/SpaceRuins/whiteshipdock.dmm b/_maps/RandomRuins/SpaceRuins/whiteshipdock.dmm index b5f2fb2237..ca0a4b55aa 100644 --- a/_maps/RandomRuins/SpaceRuins/whiteshipdock.dmm +++ b/_maps/RandomRuins/SpaceRuins/whiteshipdock.dmm @@ -3,16 +3,7 @@ /turf/open/space/basic, /area/space) "b" = ( -/obj/docking_port/stationary{ - dheight = 0; - dir = 2; - dwidth = 11; - height = 22; - id = "whiteship_away"; - json_key = "whiteship"; - name = "Deep Space"; - width = 35 - }, +/obj/docking_port/stationary/picked/whiteship, /turf/open/space, /area/space) diff --git a/_maps/RandomRuins/StationRuins/Box/Engine/engine_rbmk.dmm b/_maps/RandomRuins/StationRuins/Box/Engine/engine_rbmk.dmm new file mode 100644 index 0000000000..4c45f7e919 --- /dev/null +++ b/_maps/RandomRuins/StationRuins/Box/Engine/engine_rbmk.dmm @@ -0,0 +1,2285 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"au" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"ax" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/door/airlock/external{ + name = "Engineering External Access"; + req_access_txt = "10;13" + }, +/turf/open/floor/plating, +/area/engineering/main) +"az" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/closed/wall/r_wall, +/area/engineering/main) +"aN" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/sign/warning/radiation/rad_area, +/turf/closed/wall/r_wall, +/area/engineering/main) +"bf" = ( +/obj/machinery/portable_atmospherics/canister/nitrogen, +/obj/effect/turf_decal/delivery, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/conveyor{ + id = "rbmkn2" + }, +/turf/open/floor/engine, +/area/engineering/main) +"bQ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main) +"bU" = ( +/turf/open/pool, +/area/engineering/main) +"ce" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/engineering/main) +"dj" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main) +"dw" = ( +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"dF" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main) +"dK" = ( +/obj/structure/closet/radiation, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"dR" = ( +/obj/machinery/door/airlock/engineering/glass{ + name = "Nuclear Reactor Control Room"; + req_access_txt = "10" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"ec" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/door/poddoor/shutters/radiation/preopen{ + id = "engrbmk"; + name = "Radiation Chamber Shutters" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/plating, +/area/engineering/main) +"ee" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engineering/main) +"eg" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engineering/main) +"eu" = ( +/obj/structure/table, +/obj/effect/turf_decal/stripes/line, +/obj/item/book/manual/wiki/rbmk{ + name = "\improper Nuclear Reactors (for dummies)" + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"eM" = ( +/obj/structure/chair/office/light{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/engineering/main) +"fF" = ( +/obj/structure/sign/warning/radiation/rad_area, +/turf/closed/wall/r_wall, +/area/engineering/main) +"fU" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/space, +/area/space/nearstation) +"gn" = ( +/obj/structure/table, +/obj/item/storage/toolbox/mechanical{ + pixel_y = 5 + }, +/obj/item/flashlight{ + pixel_x = 1; + pixel_y = 5 + }, +/obj/item/flashlight{ + pixel_x = 1; + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"gF" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/effect/turf_decal/delivery, +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/conveyor{ + id = "rbmktoxins" + }, +/turf/open/floor/engine, +/area/engineering/main) +"ha" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engineering/main) +"hd" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 6 + }, +/turf/open/floor/engine, +/area/engineering/main) +"hi" = ( +/obj/structure/table, +/obj/effect/turf_decal/stripes/line, +/obj/item/geiger_counter{ + desc = "3.6 roentgen, not great, not terrible."; + name = "\improper Roentgen counter" + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"hj" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating, +/area/engineering/main) +"hn" = ( +/obj/machinery/pool/filter{ + pixel_y = 24 + }, +/turf/open/pool, +/area/engineering/main) +"hH" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/engine, +/area/engineering/main) +"hK" = ( +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/space/basic, +/area/space/nearstation) +"hQ" = ( +/obj/structure/closet/firecloset, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"hT" = ( +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main) +"id" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/door/poddoor/shutters/radiation/preopen{ + id = "engrbmk"; + name = "Radiation Chamber Shutters" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating, +/area/engineering/main) +"if" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/open/floor/carpet/green, +/area/engineering/main) +"iA" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/closet/radiation, +/turf/open/floor/plasteel, +/area/engineering/main) +"iQ" = ( +/obj/machinery/pool/drain, +/turf/open/pool, +/area/engineering/main) +"iY" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engineering/main) +"jg" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 6 + }, +/turf/open/floor/engine, +/area/engineering/main) +"ji" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/turf/open/floor/engine, +/area/engineering/main) +"jk" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"jv" = ( +/obj/structure/chair/office/light{ + dir = 8 + }, +/turf/open/floor/carpet/green, +/area/engineering/main) +"jw" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/engine, +/area/engineering/main) +"jx" = ( +/obj/machinery/conveyor_switch{ + id = "rbmktoxins" + }, +/turf/open/floor/engine, +/area/engineering/main) +"ke" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/engineering/main) +"kx" = ( +/obj/structure/lattice, +/turf/closed/wall/r_wall, +/area/engineering/main) +"kM" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/engine, +/area/engineering/main) +"kR" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main) +"kX" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main) +"lc" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/door/window/westright{ + dir = 2; + name = "Engineering Desk"; + req_access_txt = "10" + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main) +"ld" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/effect/turf_decal/delivery, +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/machinery/conveyor{ + id = "rbmkoxy" + }, +/turf/open/floor/engine, +/area/engineering/main) +"lg" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engineering/main) +"lE" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/door/poddoor/shutters/radiation/preopen{ + id = "engrbmk"; + name = "Radiation Chamber Shutters" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engineering/main) +"lW" = ( +/obj/structure/table, +/obj/machinery/computer/reactor/pump/rbmk_output, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"mb" = ( +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"mi" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/engine, +/area/engineering/main) +"mo" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"mx" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/engine, +/area/engineering/main) +"my" = ( +/obj/structure/table, +/obj/machinery/computer/reactor/stats, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"mE" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -24 + }, +/obj/machinery/camera{ + c_tag = "Reactor control room"; + dir = 1; + network = list("engine"); + pixel_x = 23 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"mT" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/engine, +/area/engineering/main) +"mY" = ( +/turf/open/floor/engine, +/area/engineering/main) +"nh" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engineering/main) +"nx" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/engine, +/area/engineering/main) +"nT" = ( +/obj/structure/rack, +/obj/item/clothing/mask/gas{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/clothing/mask/gas, +/obj/item/clothing/mask/gas{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"nW" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main) +"oe" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/engine, +/area/engineering/main) +"op" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/preset, +/turf/open/floor/engine, +/area/engineering/main) +"os" = ( +/obj/effect/turf_decal/stripes/corner, +/turf/open/floor/engine, +/area/engineering/main) +"pr" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/pool, +/area/engineering/main) +"pF" = ( +/obj/machinery/atmospherics/pipe/manifold/orange/visible, +/turf/open/floor/engine, +/area/engineering/main) +"qy" = ( +/turf/closed/wall, +/area/engineering/main) +"rl" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engineering/main) +"rQ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/engine, +/area/engineering/main) +"rV" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engineering/main) +"sA" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"sS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engineering/main) +"sV" = ( +/obj/structure/table, +/obj/item/clothing/gloves/color/yellow, +/obj/item/storage/toolbox/electrical{ + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"tt" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/turf/open/floor/engine, +/area/engineering/main) +"tw" = ( +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"tK" = ( +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"tR" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/closed/wall/r_wall, +/area/engineering/main) +"tZ" = ( +/obj/machinery/atmospherics/components/binary/pump/rbmk_input{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engineering/main) +"ue" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/space/basic, +/area/space/nearstation) +"ui" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/camera{ + c_tag = "Reactor cycling room"; + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"uj" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/engineering/main) +"up" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + name = "output gas connector port" + }, +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main) +"uA" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/engineering/main) +"uQ" = ( +/obj/machinery/pool/controller, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/engine, +/area/engineering/main) +"uR" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engineering/main) +"vg" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engineering/main) +"vh" = ( +/obj/structure/table, +/obj/machinery/computer/reactor/pump/rbmk_input, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"vX" = ( +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/space/basic, +/area/space/nearstation) +"vY" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/carpet/green, +/area/engineering/main) +"wL" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main) +"wN" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/engine, +/area/engineering/main) +"xO" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"xZ" = ( +/obj/machinery/conveyor_switch{ + id = "rbmkoxy" + }, +/turf/open/floor/engine, +/area/engineering/main) +"yf" = ( +/turf/open/space/basic, +/area/space/nearstation) +"yI" = ( +/turf/open/floor/carpet/green, +/area/engineering/main) +"zm" = ( +/obj/structure/table, +/obj/machinery/computer/reactor/pump/rbmk_moderator, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"zx" = ( +/obj/item/fuel_rod, +/turf/open/pool, +/area/engineering/main) +"zC" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/heat_exchanging/junction{ + dir = 8 + }, +/turf/open/floor/plating, +/area/engineering/main) +"zS" = ( +/turf/open/space/basic, +/area/space) +"Am" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main) +"AA" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"AI" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engineering/main) +"Bl" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/engineering/main) +"Bn" = ( +/obj/machinery/conveyor_switch{ + id = "rbmkn2" + }, +/turf/open/floor/engine, +/area/engineering/main) +"Bx" = ( +/turf/closed/wall/r_wall, +/area/engineering/main) +"BM" = ( +/obj/item/fuel_rod, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/pool, +/area/engineering/main) +"BU" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"Cg" = ( +/obj/machinery/atmospherics/components/binary/pump/rbmk_moderator, +/turf/open/floor/engine, +/area/engineering/main) +"Ck" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/delivery, +/turf/open/floor/engine, +/area/engineering/main) +"CE" = ( +/obj/structure/table, +/obj/machinery/computer/reactor/fuel_rods, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"CX" = ( +/obj/structure/pool/ladder{ + dir = 2; + pixel_y = 24 + }, +/turf/open/pool, +/area/engineering/main) +"CZ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 + }, +/turf/open/floor/engine, +/area/engineering/main) +"DF" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 9 + }, +/turf/open/floor/engine, +/area/engineering/main) +"DI" = ( +/obj/structure/sign/warning/vacuum/external{ + pixel_x = 32 + }, +/turf/open/floor/plating, +/area/engineering/main) +"DP" = ( +/obj/machinery/door/airlock/engineering/glass{ + name = "Nuclear Reactor Airlock"; + req_access_txt = "10" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, +/area/engineering/main) +"Et" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/engine, +/area/engineering/main) +"Ex" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/light, +/turf/open/floor/engine, +/area/engineering/main) +"EG" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/space/basic, +/area/space/nearstation) +"FT" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main) +"GH" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + name = "output gas connector port" + }, +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main) +"Hj" = ( +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ + dir = 1 + }, +/turf/open/floor/engine, +/area/engineering/main) +"Hq" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"Hv" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/door/poddoor/shutters/radiation/preopen{ + id = "engrbmk"; + name = "Radiation Chamber Shutters" + }, +/turf/open/floor/plating, +/area/engineering/main) +"Ie" = ( +/obj/machinery/portable_atmospherics/canister/nitrogen, +/obj/machinery/atmospherics/components/unary/portables_connector/visible, +/turf/open/floor/engine, +/area/engineering/main) +"Ir" = ( +/obj/machinery/portable_atmospherics/canister/nitrogen, +/obj/effect/turf_decal/delivery, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/obj/machinery/conveyor{ + id = "rbmkn2" + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engineering/main) +"IL" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engineering/main) +"Ja" = ( +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/space/basic, +/area/space/nearstation) +"Jm" = ( +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"Jy" = ( +/obj/structure/table, +/obj/machinery/computer/reactor/control_rods, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"JA" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/engine, +/area/engineering/main) +"JG" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"JS" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/effect/turf_decal/delivery, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/conveyor{ + id = "rbmktoxins" + }, +/turf/open/floor/engine, +/area/engineering/main) +"Le" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engineering/main) +"Ll" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Reactor Chamber"; + network = list("engine"); + pixel_x = 23 + }, +/turf/open/floor/engine, +/area/engineering/main) +"LC" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/atmospherics/pipe/simple/orange/visible, +/turf/open/floor/engine, +/area/engineering/main) +"Me" = ( +/obj/machinery/button/door{ + id = "rbmkshut"; + name = "Nuclear Blast Door Control"; + pixel_y = -24; + req_access_txt = "10" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/engineering/main) +"Mz" = ( +/obj/machinery/button/door{ + id = "engrbmk"; + name = "Radiation Shutters Control"; + pixel_y = -24; + req_access_txt = "10" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/engineering/main) +"MN" = ( +/obj/machinery/atmospherics/components/trinary/mixer/airmix/inverse, +/turf/open/floor/engine, +/area/engineering/main) +"NB" = ( +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"NE" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/space, +/area/space/nearstation) +"NG" = ( +/obj/effect/turf_decal/stripes/line, +/obj/structure/table/reinforced, +/obj/item/reagent_containers/food/snacks/pizza/meat, +/turf/open/floor/engine, +/area/engineering/main) +"NY" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engineering/main) +"Oj" = ( +/turf/closed/wall/r_wall, +/area/space/nearstation) +"Om" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main) +"On" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 9 + }, +/turf/open/floor/engine, +/area/engineering/main) +"OA" = ( +/obj/machinery/portable_atmospherics/canister/nitrogen, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1 + }, +/turf/open/floor/engine, +/area/engineering/main) +"OT" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engineering/main) +"Pt" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 5 + }, +/turf/open/floor/engine, +/area/engineering/main) +"Pv" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main) +"Pz" = ( +/turf/open/floor/plasteel, +/area/engineering/main) +"PE" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/space/basic, +/area/space/nearstation) +"Qs" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"QA" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/closet/emcloset/anchored, +/turf/open/floor/plating, +/area/engineering/main) +"QK" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"QR" = ( +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"Rh" = ( +/obj/structure/lattice, +/turf/open/space, +/area/space/nearstation) +"RJ" = ( +/obj/machinery/door/airlock/engineering/glass{ + name = "Nuclear Reactor"; + req_access_txt = "10" + }, +/turf/open/floor/plating, +/area/engineering/main) +"So" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/engine, +/area/engineering/main) +"St" = ( +/obj/structure/closet/radiation, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"Su" = ( +/obj/effect/turf_decal/stripes/corner, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"Sx" = ( +/obj/machinery/door/poddoor{ + id = "rbmkshut" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engineering/main) +"Tg" = ( +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/space/basic, +/area/space/nearstation) +"Tm" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/light{ + light_color = "#c9d3e8" + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"UR" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/engine, +/area/engineering/main) +"Vc" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/engineering/main) +"Ve" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/engine, +/area/engineering/main) +"Vi" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/turf/open/floor/engine, +/area/engineering/main) +"Vt" = ( +/obj/structure/closet/firecloset, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"Vu" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"VM" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/components/binary/pump/rbmk_output{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engineering/main) +"Wa" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/engine, +/area/engineering/main) +"WB" = ( +/obj/structure/lattice, +/obj/structure/grille, +/turf/open/space/basic, +/area/space/nearstation) +"WX" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/door/window/westright{ + dir = 2; + name = "Engineering Desk"; + req_access_txt = "10" + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engineering/main) +"XA" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/space/basic, +/area/space/nearstation) +"Ym" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/carpet/green, +/area/engineering/main) +"YD" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/machinery/door/airlock/external{ + name = "Engineering External Access"; + req_access_txt = "10;13" + }, +/turf/open/floor/plating, +/area/engineering/main) +"YJ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/engine, +/area/engineering/main) +"YM" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/engineering/glass{ + name = "Nuclear Reactor Airlock"; + req_access_txt = "10" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/turf/open/floor/plasteel, +/area/engineering/main) +"YO" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/structure/table, +/obj/machinery/microwave, +/obj/item/storage/box/donkpockets, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"YU" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/space/basic, +/area/space/nearstation) +"YZ" = ( +/obj/structure/lattice, +/obj/structure/grille, +/turf/open/space, +/area/space/nearstation) +"Zd" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/effect/turf_decal/delivery, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/machinery/conveyor{ + id = "rbmkoxy" + }, +/turf/open/floor/engine, +/area/engineering/main) +"ZN" = ( +/obj/machinery/shower{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) +"ZT" = ( +/turf/template_noop, +/area/template_noop) + +(1,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +yf +Rh +yf +yf +Rh +yf +yf +Rh +yf +yf +yf +YZ +YZ +YZ +ZT +ZT +ZT +ZT +ZT +"} +(2,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +hK +PE +Ja +Ja +PE +Ja +Ja +PE +Ja +Ja +vX +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(3,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +EG +ue +XA +PE +PE +PE +PE +PE +PE +fU +NE +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(4,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +hK +YU +Tg +Ja +PE +Ja +Ja +PE +Ja +Ja +vX +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(5,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +EG +ue +XA +PE +PE +PE +PE +PE +PE +fU +NE +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(6,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +hK +YU +Tg +Ja +PE +Ja +Ja +PE +Ja +Ja +vX +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(7,1,1) = {" +ZT +ZT +ZT +ZT +qy +qy +Bx +EG +ue +XA +PE +PE +PE +PE +PE +PE +fU +NE +YZ +Oj +YZ +yf +yf +yf +yf +zS +"} +(8,1,1) = {" +ZT +ZT +sV +gn +qy +QA +Bx +hK +YU +Tg +Ja +PE +Ja +Ja +PE +Ja +Ja +vX +YZ +Oj +YZ +yf +yf +Rh +yf +yf +"} +(9,1,1) = {" +ZT +ZT +Pz +Pz +ax +DI +YD +EG +ue +tw +XA +PE +PE +PE +PE +PE +fU +NE +YZ +YZ +YZ +tw +Rh +Rh +Rh +yf +"} +(10,1,1) = {" +ZT +Le +lg +NY +Bx +Bx +Bx +Bx +zC +NY +zC +NY +tR +az +tw +yf +yf +yf +Rh +yf +yf +yf +yf +Rh +yf +yf +"} +(11,1,1) = {" +eg +nh +nx +jw +jw +jw +rQ +jw +nW +jw +Om +jw +ji +Vc +yf +yf +yf +yf +yf +yf +yf +yf +WB +YZ +WB +yf +"} +(12,1,1) = {" +aN +kM +Wa +ld +Zd +Zd +lc +xZ +dF +mY +FT +mY +rV +Vc +yf +yf +yf +yf +yf +yf +yf +yf +YZ +Oj +YZ +yf +"} +(13,1,1) = {" +uR +Ve +uj +gF +JS +JS +WX +jx +dF +mY +FT +mY +Ck +Sx +yf +yf +yf +yf +yf +yf +yf +yf +YZ +Oj +YZ +yf +"} +(14,1,1) = {" +ee +YJ +uj +Ir +bf +bf +WX +Bn +dF +mY +FT +mY +Ck +Sx +yf +yf +yf +yf +yf +yf +yf +Rh +YZ +Oj +YZ +Rh +"} +(15,1,1) = {" +Bx +bQ +uj +mY +mY +mY +hd +Vi +On +mY +FT +mY +Ck +Sx +yf +yf +yf +yf +yf +yf +yf +yf +YZ +Oj +YZ +yf +"} +(16,1,1) = {" +fF +mx +hH +ke +ke +wN +VM +JA +mY +mY +FT +mY +Ck +Sx +yf +yf +yf +yf +yf +yf +yf +Rh +YZ +Oj +YZ +yf +"} +(17,1,1) = {" +NY +bQ +mY +mY +mY +mT +IL +mT +mY +mY +FT +mY +Ex +Vc +yf +yf +yf +yf +yf +yf +yf +yf +YZ +Oj +YZ +yf +"} +(18,1,1) = {" +NY +Ll +mY +jg +Cg +LC +op +mT +mY +mY +FT +mY +NG +Vc +Hv +Hv +Hv +Bx +Bx +yf +yf +yf +YZ +Oj +YZ +yf +"} +(19,1,1) = {" +NY +bQ +mY +kX +mY +UR +vg +UR +mY +mY +FT +mY +oe +lE +my +Jy +CE +YO +Bx +yf +yf +Rh +YZ +Oj +YZ +yf +"} +(20,1,1) = {" +fF +GH +Pt +kX +mY +mY +tZ +mY +mY +mY +FT +mY +oe +lE +sA +jv +yI +mE +Bx +yf +yf +Rh +YZ +Oj +YZ +yf +"} +(21,1,1) = {" +Bx +up +MN +pF +mY +mY +Hj +tt +tt +tt +DF +mY +oe +ec +QR +Ym +if +mo +Bx +yf +yf +yf +YZ +Oj +YZ +yf +"} +(22,1,1) = {" +NY +bQ +mY +kX +mY +mY +iY +mY +os +Pv +Pv +Pv +Et +RJ +NB +vY +Bl +Tm +fF +yf +yf +Rh +YZ +Oj +YZ +Rh +"} +(23,1,1) = {" +NY +bQ +Am +kX +mY +Ie +hT +OA +oe +hn +bU +zx +zx +Hv +vh +ce +Mz +hi +Bx +yf +yf +Rh +YZ +Oj +YZ +yf +"} +(24,1,1) = {" +fF +kR +dj +mY +mY +mY +wL +mY +oe +CX +iQ +zx +zx +Hv +zm +eM +Me +eu +Bx +yf +yf +Rh +YZ +Oj +YZ +yf +"} +(25,1,1) = {" +NY +OT +So +mi +AI +mi +CZ +mi +uQ +pr +pr +BM +BM +id +lW +Su +QK +au +Bx +yf +yf +yf +YZ +YZ +YZ +yf +"} +(26,1,1) = {" +iA +sS +ha +NY +uA +Bx +Bx +Bx +Bx +Bx +Hv +Hv +Hv +Bx +Bx +dR +rl +Bx +kx +yf +yf +yf +yf +Rh +yf +yf +"} +(27,1,1) = {" +ZT +ZT +ZT +Pz +nT +hj +St +ZN +dK +Bx +hQ +Vt +AA +Qs +dw +mb +tK +Hq +kx +tw +tw +tw +Rh +Rh +Rh +Rh +"} +(28,1,1) = {" +ZT +ZT +ZT +Pz +Pz +YM +Jm +BU +ui +DP +JG +xO +xO +xO +xO +xO +Vu +jk +kx +yf +tw +yf +yf +Rh +yf +yf +"} +(29,1,1) = {" +ZT +ZT +ZT +Pz +Pz +Bx +Bx +fF +Bx +Bx +NY +NY +NY +Bx +kx +kx +kx +kx +kx +yf +tw +yf +yf +Rh +yf +zS +"} diff --git a/_maps/RandomRuins/StationRuins/Lavaland/Mining_Station/Mining_Station_Public_01.dmm b/_maps/RandomRuins/StationRuins/Lavaland/Mining_Station/Mining_Station_Public_01.dmm index 69cf7c0867..f7be60c4b3 100644 --- a/_maps/RandomRuins/StationRuins/Lavaland/Mining_Station/Mining_Station_Public_01.dmm +++ b/_maps/RandomRuins/StationRuins/Lavaland/Mining_Station/Mining_Station_Public_01.dmm @@ -994,14 +994,14 @@ /turf/open/floor/plasteel/freezer, /area/mine/living_quarters) "qh" = ( -/obj/structure/sink{ - dir = 8; - pixel_x = 11 - }, /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ dir = 1 }, +/obj/structure/sink{ + dir = 4; + pixel_x = 12 + }, /turf/open/floor/plasteel, /area/mine/living_quarters) "qm" = ( @@ -2498,13 +2498,13 @@ /turf/open/floor/plasteel/white, /area/mine/laborcamp) "Mj" = ( -/obj/structure/sink{ - dir = 4; - pixel_x = -12 - }, /obj/structure/mirror{ pixel_x = -28 }, +/obj/structure/sink{ + dir = 8; + pixel_x = -12 + }, /turf/open/floor/plasteel/freezer, /area/mine/living_quarters) "Mk" = ( @@ -2714,10 +2714,6 @@ }, /turf/open/floor/plasteel, /area/mine/living_quarters) -"OI" = ( -/obj/machinery/mineral/mint, -/turf/open/floor/plasteel, -/area/mine/production) "ON" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/brown{ @@ -7031,7 +7027,7 @@ xv bg mI Cd -OI +es sz gk Wf diff --git a/_maps/RandomZLevels/VR/snowdin_VR.dmm b/_maps/RandomZLevels/VR/snowdin_VR.dmm index c0977f00f0..d1e3373633 100644 --- a/_maps/RandomZLevels/VR/snowdin_VR.dmm +++ b/_maps/RandomZLevels/VR/snowdin_VR.dmm @@ -14451,7 +14451,7 @@ /turf/open/floor/plasteel/dark, /area/awaymission/snowdin/post/mining_main/mechbay) "In" = ( -/obj/mecha/working/ripley/mining{ +/obj/vehicle/sealed/mecha/working/ripley/mining{ dir = 1; icon_state = "ripley" }, diff --git a/_maps/RandomZLevels/away_mission/SnowCabin.dmm b/_maps/RandomZLevels/away_mission/SnowCabin.dmm index dda382c4b7..7de2ed53f1 100644 --- a/_maps/RandomZLevels/away_mission/SnowCabin.dmm +++ b/_maps/RandomZLevels/away_mission/SnowCabin.dmm @@ -99,7 +99,9 @@ /obj/machinery/door/airlock/command{ name = "Manager's Office" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "as" = ( @@ -134,7 +136,9 @@ /area/awaymission/cabin) "aw" = ( /obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plating, /area/awaymission/cabin) "ax" = ( @@ -185,17 +189,18 @@ /turf/open/floor/plasteel/freezer, /area/awaymission/cabin) "aD" = ( -/obj/machinery/power/smes/magical{ - desc = "A high-capacity superconducting magnetic energy storage (SMES) unit. It seems to be powered just fine without our intervention."; - name = "nanotrasen power storage unit" - }, /obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/power/smes/magical, /turf/open/floor/plating, /area/awaymission/cabin) "aE" = ( /obj/effect/decal/cleanable/cobweb/cobweb2, /obj/effect/baseturf_helper/asteroid/snow, /obj/effect/decal/cleanable/dirt, +/obj/machinery/power/port_gen/pacman, /turf/open/floor/plating{ icon_state = "panelscorched" }, @@ -207,7 +212,12 @@ pixel_y = 23 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, /turf/open/floor/plating, /area/awaymission/cabin) "aG" = ( @@ -255,7 +265,9 @@ dir = 1 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-2" + }, /turf/open/floor/plating{ icon_state = "panelscorched" }, @@ -281,15 +293,6 @@ /turf/open/floor/carpet, /area/awaymission/cabin) "aQ" = ( -/obj/structure{ - anchored = 1; - density = 1; - desc = "Generates power from lava!"; - dir = 1; - icon = 'icons/obj/atmospherics/pipes/simple.dmi'; - icon_state = "compressor"; - name = "geothermal generator" - }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating{ icon_state = "panelscorched" @@ -366,7 +369,9 @@ /turf/open/floor/wood, /area/awaymission/cabin) "bb" = ( -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-2" + }, /turf/open/floor/carpet, /area/awaymission/cabin) "bc" = ( @@ -431,7 +436,9 @@ id_tag = "snowdorm5"; name = "Cabin 5" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "bn" = ( @@ -463,7 +470,9 @@ /obj/machinery/newscaster{ pixel_y = 32 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "bt" = ( @@ -492,7 +501,9 @@ "by" = ( /obj/structure/table, /obj/machinery/reagentgrinder, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-2" + }, /turf/open/floor/plasteel/cafeteria, /area/awaymission/cabin) "bz" = ( @@ -611,7 +622,9 @@ /obj/machinery/door/airlock/maintenance{ name = "Garage" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "bW" = ( @@ -739,7 +752,9 @@ /obj/structure/sign/poster/official/soft_cap_pop_art{ pixel_y = 32 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "cu" = ( @@ -838,14 +853,18 @@ dir = 8 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) "cM" = ( /obj/machinery/door/airlock/wood{ name = "Gateway" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "cN" = ( @@ -859,12 +878,16 @@ /turf/open/floor/carpet, /area/awaymission/cabin) "cP" = ( -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-2" + }, /turf/open/floor/plasteel/white, /area/awaymission/cabin) "cQ" = ( /obj/effect/landmark/awaystart, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/carpet, /area/awaymission/cabin) "cR" = ( @@ -898,7 +921,9 @@ /area/awaymission/cabin) "cW" = ( /obj/item/shovel, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plating{ icon_state = "platingdmg3" }, @@ -957,7 +982,9 @@ /obj/structure/chair/wood{ dir = 4 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-2" + }, /turf/open/floor/carpet, /area/awaymission/cabin) "df" = ( @@ -1040,20 +1067,19 @@ /area/awaymission/cabin) "du" = ( /obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-4" + }, /turf/open/floor/plating{ icon_state = "panelscorched" }, /area/awaymission/cabin) "dv" = ( -/obj/structure{ - anchored = 1; - density = 1; - desc = "Generates power from lava!"; - icon = 'icons/obj/atmospherics/pipes/simple.dmi'; - icon_state = "turbine"; - name = "geothermal generator" - }, /obj/effect/decal/cleanable/dirt, +/obj/machinery/power/rtg, +/obj/structure/cable{ + icon_state = "0-8" + }, /turf/open/floor/plating{ icon_state = "panelscorched" }, @@ -1269,7 +1295,9 @@ /turf/open/floor/wood/cold, /area/awaymission/cabin/snowforest) "eg" = ( -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "eh" = ( @@ -1279,7 +1307,9 @@ "ei" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/glass, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) "ej" = ( @@ -1350,7 +1380,9 @@ /area/awaymission/cabin/snowforest) "et" = ( /obj/effect/decal/cleanable/dirt/dust, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) "eu" = ( @@ -2724,11 +2756,15 @@ /obj/structure/sign/poster/official/fruit_bowl{ pixel_y = 32 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "hi" = ( -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-2" + }, /turf/open/floor/plasteel/freezer, /area/awaymission/cabin) "hj" = ( @@ -2736,7 +2772,9 @@ dir = 8 }, /obj/effect/decal/cleanable/dirt/dust, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) "hk" = ( @@ -2781,7 +2819,9 @@ /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/oil, /obj/effect/decal/cleanable/generic, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) "hs" = ( @@ -2789,14 +2829,18 @@ /obj/structure/sign/poster/contraband/missing_gloves{ pixel_x = 32 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) "ht" = ( /obj/structure/window{ dir = 4 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "hu" = ( @@ -2816,6 +2860,9 @@ pixel_y = 4 }, /obj/effect/decal/cleanable/dirt, +/obj/item/stack/sheet/mineral/plasma{ + amount = 26 + }, /turf/open/floor/plating, /area/awaymission/cabin) "hw" = ( @@ -2841,28 +2888,36 @@ /turf/open/floor/plating, /area/awaymission/cabin) "hz" = ( -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/cafeteria, /area/awaymission/cabin) "hA" = ( /obj/machinery/door/airlock/freezer{ name = "Freezer" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plasteel/freezer, /area/awaymission/cabin) "hB" = ( /obj/machinery/door/airlock{ name = "Backstage" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "hC" = ( /obj/structure/chair/wood{ dir = 8 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "2-8" + }, /turf/open/floor/carpet, /area/awaymission/cabin) "hD" = ( @@ -2874,7 +2929,9 @@ /obj/machinery/door/airlock{ name = "Kitchen" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "hF" = ( @@ -2889,7 +2946,9 @@ /obj/structure/chair/wood{ dir = 1 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "hH" = ( @@ -3124,7 +3183,9 @@ /obj/structure/extinguisher_cabinet{ pixel_y = 32 }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/wood, /area/awaymission/cabin) "io" = ( @@ -3321,7 +3382,9 @@ id_tag = "snowdorm1"; name = "Cabin 1" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "iW" = ( @@ -3329,7 +3392,9 @@ id_tag = "snowdorm2"; name = "Cabin 2" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "iX" = ( @@ -3337,7 +3402,9 @@ id_tag = "snowdorm3"; name = "Cabin 3" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "iY" = ( @@ -3345,7 +3412,9 @@ id_tag = "snowdorm4"; name = "Cabin 4" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/wood, /area/awaymission/cabin) "iZ" = ( @@ -3518,7 +3587,9 @@ }, /obj/item/reagent_containers/glass/bottle/cryoxadone, /obj/item/reagent_containers/glass/bottle/cryoxadone, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/white, /area/awaymission/cabin) "jr" = ( @@ -3649,7 +3720,9 @@ name = "Generator Room" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) "jD" = ( @@ -4408,7 +4481,7 @@ /area/awaymission/cabin/caves) "lr" = ( /obj/effect/decal/cleanable/blood/old, -/obj/item/kitchen/knife/carrotshiv, +/obj/item/kitchen/knife/shiv/carrot, /obj/effect/decal/cleanable/glitter/blue{ desc = "It looks like fancy glitter to me."; name = "icy wind" @@ -5450,7 +5523,9 @@ /turf/open/floor/wood, /area/awaymission/cabin) "nR" = ( -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "0-4" + }, /turf/open/floor/plating, /area/awaymission/cabin) "nS" = ( @@ -5477,13 +5552,152 @@ /obj/machinery/door/airlock/maintenance{ name = "Maintenance" }, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/awaymission/cabin) +"nY" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/cafeteria, +/area/awaymission/cabin) +"rn" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/cafeteria, +/area/awaymission/cabin) +"rV" = ( +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/wood, +/area/awaymission/cabin) +"sn" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/awaymission/cabin) +"uk" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/freezer, +/area/awaymission/cabin) +"uD" = ( +/obj/structure/chair/wood{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, +/area/awaymission/cabin) +"ww" = ( +/obj/effect/landmark/awaystart, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/carpet, +/area/awaymission/cabin) +"wx" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/freezer, +/area/awaymission/cabin) +"zF" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/wood, +/area/awaymission/cabin) +"BB" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/awaymission/cabin) +"Co" = ( +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel/cafeteria, +/area/awaymission/cabin) +"DU" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plating, +/area/awaymission/cabin) +"Fj" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/awaymission/cabin) +"FH" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/wood, +/area/awaymission/cabin) +"Hb" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/carpet, +/area/awaymission/cabin) +"He" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/awaymission/cabin) +"IG" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/white, +/area/awaymission/cabin) +"JZ" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, +/area/awaymission/cabin) +"KS" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/carpet, +/area/awaymission/cabin) +"MB" = ( +/obj/structure/chair/wood{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, +/area/awaymission/cabin) "MS" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/oil, -/obj/effect/mapping_helpers/network_builder/power_cable/yellow/auto, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plating, /area/awaymission/cabin) "TZ" = ( @@ -5495,6 +5709,37 @@ /obj/item/clothing/shoes/winterboots/ice_boots, /turf/open/floor/plating/ice/smooth, /area/awaymission/cabin/caves) +"UL" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/freezer, +/area/awaymission/cabin) +"WD" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/awaymission/cabin) +"WX" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plating, +/area/awaymission/cabin) +"WY" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/awaymission/cabin) (1,1,1) = {" ab @@ -25696,21 +25941,21 @@ iZ aN jl bb -bb -bb +JZ +JZ eg bm -eg +Fj nS an -eg +rV eg eg eg eg eg hB -eg +Fj aq an cT @@ -25957,7 +26202,7 @@ az az aq an -eg +He bh an cA @@ -25967,7 +26212,7 @@ an an hx an -eg +He aq an cU @@ -26214,7 +26459,7 @@ az az aq an -eg +He aq an aq @@ -26224,7 +26469,7 @@ aq aq aq an -eg +He aq an cV @@ -26481,11 +26726,11 @@ aq aq bh an -eg +He bh an aL -nR +BB aL ed an @@ -26728,17 +26973,17 @@ an an aR an -eg +He aq an aq aq -eg +FH aq aq aq an -eg +He aq an cU @@ -26985,21 +27230,21 @@ aH an an an -eg +He aq an cz aq -eg +He aq aq bh an -eg +He aq an ed -nR +BB aL kE an @@ -27242,7 +27487,7 @@ an an aS hg -eg +He bh an nT @@ -27252,11 +27497,11 @@ bo bo cB an -eg +WD eg bV -aw -aw +sn +DU gM an an @@ -27499,17 +27744,17 @@ aH an an an -eg +He aq an aO aO hC -hC -hC -bb -bb -eg +MB +MB +JZ +JZ +WY aq an eb @@ -27756,7 +28001,7 @@ an an aT an -eg +He aq an az @@ -27766,7 +28011,7 @@ az aq aq cO -eg +He bh an an @@ -28270,7 +28515,7 @@ az az aq an -eg +He aq an aP @@ -28280,7 +28525,7 @@ nB hd az aO -eg +He aq aq an @@ -28527,7 +28772,7 @@ az az aq an -eg +He bh an bq @@ -28537,7 +28782,7 @@ hc hd az az -eg +He aq aq aN @@ -28780,11 +29025,11 @@ ja bp jm bb -bb -bb +JZ +JZ eg iY -eg +WY aq an bt @@ -28794,7 +29039,7 @@ jx hd az cO -eg +He aq aq iR @@ -29041,7 +29286,7 @@ aI aA jj an -eg +He aq an cN @@ -29308,7 +29553,7 @@ az aq aq aO -eg +He aq aq an @@ -29555,17 +29800,17 @@ ju au ji an -eg +He aq an de -de -de -de -de -bb -bb -eg +uD +uD +uD +uD +JZ +JZ +WY bh an an @@ -29808,11 +30053,11 @@ jb aN jn bb -bb -bb +JZ +JZ eg iX -eg +WY bh an hb @@ -29822,7 +30067,7 @@ eu cK cD an -eg +He aq aq an @@ -30069,7 +30314,7 @@ az az aq an -eg +He aq an hn @@ -30079,7 +30324,7 @@ aq aq aq an -eg +He aq aq aN @@ -30326,7 +30571,7 @@ az az aq an -eg +He aq an bv @@ -30336,7 +30581,7 @@ aq ap aq an -eg +He aq aq iU @@ -30593,7 +30838,7 @@ bu an eo an -eg +He aq aq bp @@ -30840,7 +31085,7 @@ an an aU an -eg +He aq an bw @@ -30848,9 +31093,9 @@ bO bO bO bO -hz +Co hE -eg +WY aq aq an @@ -31097,7 +31342,7 @@ aH an an an -eg +He aq an bx @@ -31105,9 +31350,9 @@ bO cJ cF cJ -hz +nY an -eg +He bh an an @@ -31354,7 +31599,7 @@ an an hf hy -eg +He aq an by @@ -31362,9 +31607,9 @@ hz hz hz hz -hz +rn an -eg +He aq aq an @@ -31611,7 +31856,7 @@ aH an an an -eg +He bh an bz @@ -31619,9 +31864,9 @@ bO bW ck cj -hz +nY an -eg +He aq aq aN @@ -31868,7 +32113,7 @@ an an aW an -eg +He aq an an @@ -31878,7 +32123,7 @@ an an hA an -eg +He aq aq iS @@ -32133,9 +32378,9 @@ bB bX cl cl -hi +uk an -eg +He aq aq bp @@ -32382,15 +32627,15 @@ az az aq an -eg +He aq an hi -hi -hi -hi -hi -hi +UL +UL +UL +UL +wx an hh aq @@ -32639,7 +32884,7 @@ az az aq an -eg +He aq an bC @@ -32649,7 +32894,7 @@ is dt cG an -eg +He bh an an @@ -32892,11 +33137,11 @@ jc bp jo bb -bb -bb +JZ +JZ eg iW -eg +WY aq an an @@ -32906,7 +33151,7 @@ an an an an -eg +He aq aq an @@ -33153,7 +33398,7 @@ aI aA jg an -eg +He aq an aJ @@ -33163,7 +33408,7 @@ cv hq cv an -eg +He aq aq aN @@ -33420,7 +33665,7 @@ bE bE lz an -eg +He aq aq iT @@ -33667,7 +33912,7 @@ jw au jh an -eg +He aq an bD @@ -33677,7 +33922,7 @@ cI hD bE nM -eg +He aq aq bp @@ -33920,21 +34165,21 @@ jd aN jp bb -bb -bb +JZ +JZ eg iV -eg +WY aq an cP -cP -cP -cP +IG +IG +IG jq -cP -cP -eg +IG +IG +WY aq aq an @@ -34181,7 +34426,7 @@ az az aq an -eg +He aq an bF @@ -34191,7 +34436,7 @@ ho bE lz an -eg +He aq an an @@ -34438,7 +34683,7 @@ az az aq an -eg +He nS an bF @@ -34448,7 +34693,7 @@ hp js hp an -eg +He aq an dB @@ -34705,7 +34950,7 @@ an an an an -eg +He bh an dB @@ -34952,7 +35197,7 @@ an an aU an -eg +WD eg nV ei @@ -34962,7 +35207,7 @@ hr hs et nV -eg +zF aq an dB @@ -35466,7 +35711,7 @@ an an aX bf -bb +KS an bj bH @@ -35476,7 +35721,7 @@ aq aq aq io -bb +KS az an dB @@ -35719,11 +35964,11 @@ ax an aF cL -aw +sn jC -bb -bb -bb +JZ +JZ +Hb an bk bJ @@ -35987,10 +36232,10 @@ an an aq cp +rV eg eg -eg -cQ +ww hI an dB @@ -36230,8 +36475,8 @@ ac ac dB ax -ed -aw +WX +DU ed hv an diff --git a/_maps/RandomZLevels/away_mission/TheBeach.dmm b/_maps/RandomZLevels/away_mission/TheBeach.dmm index 80a649bcc8..2c65f2dd8a 100644 --- a/_maps/RandomZLevels/away_mission/TheBeach.dmm +++ b/_maps/RandomZLevels/away_mission/TheBeach.dmm @@ -272,7 +272,7 @@ /obj/structure/mirror{ pixel_y = 28 }, -/turf/open/floor/wood, +/turf/open/floor/wood/wood_diagonal, /area/awaymission/beach) "bd" = ( /turf/open/floor/wood, @@ -312,7 +312,7 @@ pixel_x = 24; specialfunctions = 4 }, -/turf/open/floor/wood, +/turf/open/floor/wood/wood_diagonal, /area/awaymission/beach) "bj" = ( /obj/machinery/button/door{ @@ -322,7 +322,7 @@ pixel_x = -24; specialfunctions = 4 }, -/turf/open/floor/wood, +/turf/open/floor/wood/wood_diagonal, /area/awaymission/beach) "bk" = ( /obj/structure/closet/secure_closet/personal/cabinet, @@ -392,14 +392,14 @@ id_tag = "changlinhut2"; name = "changing room" }, -/turf/open/floor/wood, +/turf/open/floor/wood/wood_diagonal, /area/awaymission/beach) "bt" = ( /obj/machinery/door/airlock/sandstone{ id_tag = "changlinhut1"; name = "changing room" }, -/turf/open/floor/wood, +/turf/open/floor/wood/wood_diagonal, /area/awaymission/beach) "bu" = ( /obj/item/reagent_containers/food/drinks/bottle/wine, @@ -477,9 +477,9 @@ /turf/open/floor/plating/beach/sand, /area/awaymission/beach) "bF" = ( -/obj/structure/bedsheetbin, /obj/effect/turf_decal/sand, /obj/structure/table/wood, +/obj/structure/bedsheetbin/towel, /turf/open/floor/plating/beach/sand, /area/awaymission/beach) "bG" = ( @@ -773,7 +773,7 @@ /area/awaymission/beach) "cv" = ( /obj/effect/turf_decal/stripes/white/corner{ - dir = 4 + dir = 1 }, /turf/open/floor/plating/beach/sand, /area/awaymission/beach) @@ -1001,6 +1001,16 @@ /obj/item/clothing/glasses/heat, /turf/open/floor/plating/beach/sand, /area/awaymission/beach) +"iv" = ( +/obj/structure/dresser{ + density = 0; + pixel_y = 18 + }, +/turf/open/floor/wood/wood_diagonal, +/area/awaymission/beach) +"kr" = ( +/turf/open/floor/wood/wood_diagonal, +/area/awaymission/beach) "np" = ( /obj/machinery/shower{ dir = 8 @@ -7586,8 +7596,8 @@ ak ak ak aX -bb -bd +iv +kr aX ak ba @@ -8442,7 +8452,7 @@ aJ aE ak aX -bb +iv bj bt ba @@ -8550,7 +8560,7 @@ ak aS aX bc -bd +kr aX ak ba @@ -9090,7 +9100,7 @@ ak ak ba ba -ak +bF ak ak ak diff --git a/_maps/RandomZLevels/away_mission/caves.dmm b/_maps/RandomZLevels/away_mission/caves.dmm index ed246ff8b5..2195b9d0ec 100644 --- a/_maps/RandomZLevels/away_mission/caves.dmm +++ b/_maps/RandomZLevels/away_mission/caves.dmm @@ -1504,12 +1504,6 @@ }, /turf/open/floor/plasteel, /area/awaymission/caves/listeningpost) -"eQ" = ( -/obj/machinery/mineral/mint, -/turf/open/floor/plating/asteroid/basalt{ - initial_gas_mix = "n2=23;o2=14;TEMP=2.7" - }, -/area/awaymission/caves/BMP_asteroid) "eR" = ( /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plasteel, @@ -2039,7 +2033,7 @@ }, /area/awaymission/caves/BMP_asteroid) "gC" = ( -/obj/mecha/working/ripley/mining, +/obj/vehicle/sealed/mecha/working/ripley/mining, /turf/open/floor/plasteel/recharge_floor, /area/awaymission/caves/BMP_asteroid) "gD" = ( @@ -9345,8 +9339,8 @@ bM bM bL bL -eQ -eQ +bV +bV bV bV bV diff --git a/_maps/RandomZLevels/away_mission/jungleresort.dmm b/_maps/RandomZLevels/away_mission/jungleresort.dmm index 9ff92b619a..cb5334e855 100644 --- a/_maps/RandomZLevels/away_mission/jungleresort.dmm +++ b/_maps/RandomZLevels/away_mission/jungleresort.dmm @@ -203,7 +203,7 @@ /area/awaymission/jungleresort) "cK" = ( /obj/structure/closet/crate, -/obj/item/clothing/head/collectable/petehat/gang, +/obj/item/clothing/head/collectable/petehat, /turf/open/floor/plating/rust, /area/awaymission/jungleresort) "cT" = ( @@ -1992,6 +1992,7 @@ dir = 8 }, /obj/effect/decal/cleanable/oil/streak, +/obj/machinery/power/port_gen/pacman, /turf/open/floor/plating, /area/awaymission/jungleresort) "BP" = ( @@ -2040,7 +2041,7 @@ /obj/structure/cable{ icon_state = "0-8" }, -/obj/machinery/power/port_gen/pacman/super, +/obj/machinery/power/rtg, /turf/open/floor/plating, /area/awaymission/jungleresort) "CA" = ( @@ -2811,12 +2812,7 @@ /obj/structure/cable{ icon_state = "0-8" }, -/obj/machinery/power/smes{ - charge = 1.5e+006; - input_level = 30000; - inputting = 0; - output_level = 7000 - }, +/obj/machinery/power/smes/magical, /turf/open/floor/plating, /area/awaymission/jungleresort) "LR" = ( @@ -3183,6 +3179,9 @@ /obj/item/stack/sheet/mineral/uranium, /obj/item/clothing/glasses/meson/engine, /obj/item/storage/belt/utility, +/obj/item/stack/sheet/mineral/plasma{ + amount = 26 + }, /turf/open/floor/plating, /area/awaymission/jungleresort) "Rm" = ( @@ -3720,7 +3719,7 @@ /obj/structure/cable{ icon_state = "2-4" }, -/obj/machinery/power/port_gen/pacman/super, +/obj/machinery/power/rtg, /turf/open/floor/plating, /area/awaymission/jungleresort) "Yb" = ( diff --git a/_maps/RandomZLevels/away_mission/moonoutpost19.dmm b/_maps/RandomZLevels/away_mission/moonoutpost19.dmm index 177a7af984..f342f8e36b 100644 --- a/_maps/RandomZLevels/away_mission/moonoutpost19.dmm +++ b/_maps/RandomZLevels/away_mission/moonoutpost19.dmm @@ -3664,7 +3664,8 @@ /area/awaymission/moonoutpost19/research) "hk" = ( /obj/structure/alien/weeds, -/obj/structure/alien/egg, +/obj/structure/bed/nest, +/obj/item/clothing/mask/facehugger/impregnated, /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251" @@ -26666,7 +26667,7 @@ ac ad ad ad -hk +ag ag ad ad @@ -26925,7 +26926,7 @@ ai ag ag ai -hk +ag ai ad ad @@ -27178,10 +27179,10 @@ ac ac ad ad -hk +ag ai ai -hk +ag aM ai ag @@ -27437,7 +27438,7 @@ ad ai ai aD -aj +hk ai ai aD @@ -27693,7 +27694,7 @@ ac ad ai ai -aj +hk ai aT av diff --git a/_maps/RandomZLevels/away_mission/research.dmm b/_maps/RandomZLevels/away_mission/research.dmm index e73fa81501..6acf819cc4 100644 --- a/_maps/RandomZLevels/away_mission/research.dmm +++ b/_maps/RandomZLevels/away_mission/research.dmm @@ -6417,7 +6417,6 @@ /area/awaymission/research/interior/maint) "Hs" = ( /obj/structure/table/wood, -/obj/item/book/granter/crafting_recipe/bone_bow, /turf/open/floor/mineral/plasma, /area/space/nearstation) "Km" = ( diff --git a/_maps/RandomZLevels/away_mission/snowdin.dmm b/_maps/RandomZLevels/away_mission/snowdin.dmm index aa4dd61154..dae17bd259 100644 --- a/_maps/RandomZLevels/away_mission/snowdin.dmm +++ b/_maps/RandomZLevels/away_mission/snowdin.dmm @@ -14452,7 +14452,7 @@ /turf/open/floor/plasteel/dark, /area/awaymission/snowdin/post/mining_main/mechbay) "In" = ( -/obj/mecha/working/ripley/mining{ +/obj/vehicle/sealed/mecha/working/ripley/mining{ dir = 1 }, /obj/effect/turf_decal/bot, diff --git a/_maps/RandomZLevels/away_mission/undergroundoutpost45.dmm b/_maps/RandomZLevels/away_mission/undergroundoutpost45.dmm index de2105e9d4..6eee9e9d9f 100644 --- a/_maps/RandomZLevels/away_mission/undergroundoutpost45.dmm +++ b/_maps/RandomZLevels/away_mission/undergroundoutpost45.dmm @@ -815,16 +815,16 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 351.9 + initial_temperature = 351.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "bX" = ( /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 351.9 + initial_temperature = 351.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "bY" = ( @@ -2263,8 +2263,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "eK" = ( @@ -2634,8 +2634,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/central) "fo" = ( @@ -2870,8 +2870,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/central) "fK" = ( @@ -3049,8 +3049,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "gg" = ( @@ -3197,8 +3197,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/crew_quarters) "gC" = ( @@ -3411,8 +3411,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/research) "he" = ( @@ -3422,8 +3422,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/crew_quarters) "hf" = ( @@ -3454,8 +3454,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/crew_quarters) "hi" = ( @@ -4789,8 +4789,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/gateway) "jM" = ( @@ -4823,8 +4823,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/research) "jR" = ( @@ -6221,6 +6221,7 @@ c_tag = "Engineering Secure Storage"; network = list("uo45") }, +/obj/machinery/power/port_gen/pacman, /turf/open/floor/plating{ heat_capacity = 1e+006 }, @@ -6606,8 +6607,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/gateway) "mJ" = ( @@ -7751,12 +7752,7 @@ /area/awaymission/undergroundoutpost45/engineering) "ou" = ( /obj/structure/cable, -/obj/machinery/power/smes{ - charge = 1.5e+006; - input_level = 30000; - inputting = 0; - output_level = 7000 - }, +/obj/machinery/power/smes/magical, /turf/open/floor/plating{ heat_capacity = 1e+006 }, @@ -8072,12 +8068,10 @@ /obj/machinery/power/terminal{ dir = 1 }, -/obj/machinery/power/port_gen/pacman{ - name = "P.A.C.M.A.N.-type portable generator" - }, /obj/structure/cable{ icon_state = "0-4" }, +/obj/machinery/power/rtg, /turf/open/floor/plating{ heat_capacity = 1e+006 }, @@ -8086,9 +8080,6 @@ /obj/machinery/power/terminal{ dir = 1 }, -/obj/machinery/power/port_gen/pacman/super{ - name = "S.U.P.E.R.P.A.C.M.A.N.-type portable generator" - }, /obj/item/wrench, /obj/structure/cable{ icon_state = "0-8" @@ -8096,6 +8087,7 @@ /obj/structure/cable{ icon_state = "0-4" }, +/obj/machinery/power/rtg, /turf/open/floor/plating{ heat_capacity = 1e+006 }, @@ -8104,12 +8096,10 @@ /obj/machinery/power/terminal{ dir = 1 }, -/obj/machinery/power/port_gen/pacman{ - name = "P.A.C.M.A.N.-type portable generator" - }, /obj/structure/cable{ icon_state = "0-8" }, +/obj/machinery/power/rtg, /turf/open/floor/plating{ heat_capacity = 1e+006 }, @@ -8356,8 +8346,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "pv" = ( @@ -8367,8 +8357,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "pw" = ( @@ -8379,8 +8369,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/engineering) "px" = ( @@ -8670,8 +8660,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "qb" = ( @@ -8902,8 +8892,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "qA" = ( @@ -8913,8 +8903,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "qB" = ( @@ -8924,8 +8914,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "qC" = ( @@ -11106,8 +11096,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/crew_quarters) "uc" = ( @@ -11752,8 +11742,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "vm" = ( @@ -11978,8 +11968,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/research) "vI" = ( @@ -12264,8 +12254,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/mining) "wk" = ( @@ -13483,8 +13473,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/mining) "yh" = ( @@ -13492,8 +13482,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yi" = ( @@ -13501,8 +13491,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yj" = ( @@ -13512,8 +13502,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yk" = ( @@ -13522,8 +13512,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yl" = ( @@ -13533,8 +13523,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "ym" = ( @@ -13543,8 +13533,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yn" = ( @@ -13552,8 +13542,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yo" = ( @@ -13562,8 +13552,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yp" = ( @@ -13572,8 +13562,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yq" = ( @@ -13581,8 +13571,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yr" = ( @@ -13590,8 +13580,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yt" = ( @@ -13600,8 +13590,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yu" = ( @@ -13610,8 +13600,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yw" = ( @@ -13620,8 +13610,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yz" = ( @@ -13629,8 +13619,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yA" = ( @@ -13639,8 +13629,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yB" = ( @@ -13648,8 +13638,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yC" = ( @@ -13658,8 +13648,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yD" = ( @@ -13669,8 +13659,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "yH" = ( @@ -13680,8 +13670,8 @@ /turf/open/floor/plating/asteroid{ heat_capacity = 1e+006; initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9"; - name = "Cave Floor"; - initial_temperature = 363.9 + initial_temperature = 363.9; + name = "Cave Floor" }, /area/awaymission/undergroundoutpost45/caves) "KE" = ( diff --git a/_maps/RandomZLevels/away_mission/wildwest.dmm b/_maps/RandomZLevels/away_mission/wildwest.dmm index 1fc7da1acd..37999e77ab 100644 --- a/_maps/RandomZLevels/away_mission/wildwest.dmm +++ b/_maps/RandomZLevels/away_mission/wildwest.dmm @@ -861,10 +861,6 @@ }, /turf/open/floor/carpet, /area/awaymission/wildwest/gov) -"di" = ( -/obj/machinery/mineral/mint, -/turf/open/floor/plating, -/area/awaymission/wildwest/refine) "dj" = ( /obj/effect/spawner/structure/window, /turf/open/floor/wood, @@ -1282,10 +1278,6 @@ icon_state = "ironsand4" }, /area/awaymission/wildwest/gov) -"eA" = ( -/obj/machinery/mineral/mint, -/turf/open/floor/plasteel, -/area/awaymission/wildwest/refine) "eC" = ( /obj/structure/chair/comfy/brown, /turf/open/floor/wood, @@ -29059,7 +29051,7 @@ aG aG aG et -eA +eu eu eu eu @@ -33673,7 +33665,7 @@ bc bc bc bc -di +bc bc bh aW diff --git a/_maps/_basemap.dm b/_maps/_basemap.dm index bf5b4f7d49..7e5db84a9a 100644 --- a/_maps/_basemap.dm +++ b/_maps/_basemap.dm @@ -12,6 +12,7 @@ #include "map_files\PubbyStation\PubbyStation.dmm" #include "map_files\BoxStation\BoxStation.dmm" #include "map_files\LambdaStation\lambda.dmm" + #include "map_files\SpookyStation\SpookyStation.dmm" #ifdef CIBUILDING #include "templates.dm" diff --git a/_maps/festivestation.dm b/_maps/festivestation.dm new file mode 100644 index 0000000000..2016d22f30 --- /dev/null +++ b/_maps/festivestation.dm @@ -0,0 +1 @@ +#define FORCE_MAP "_maps/FestiveStation.json" diff --git a/_maps/festivestation.json b/_maps/festivestation.json new file mode 100644 index 0000000000..b8884371a3 --- /dev/null +++ b/_maps/festivestation.json @@ -0,0 +1,14 @@ +{ + "map_name": "FestiveStation", + "map_path": "map_files/FestiveBall", + "map_file": "FestiveStation.dmm", + "shuttles": { + "cargo": "cargo_box", + "ferry": "ferry_fancy", + "whiteship": "whiteship_box", + "emergency": "emergency_box" + }, + "traits": [ + { "Weather_Icestorm":true } + ] +} diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index cf15bd05e1..81eca95be1 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -23,7 +23,7 @@ "aac" = ( /obj/machinery/camera{ c_tag = "Bar"; - dir = 8 + dir = 9 }, /obj/structure/table, /obj/machinery/chem_dispenser/drinks{ @@ -65,121 +65,123 @@ }, /turf/open/floor/plasteel, /area/security/office) -"aai" = ( -/turf/closed/wall/r_wall, -/area/security/prison) -"aaj" = ( -/obj/structure/cable{ - icon_state = "1-4" +"aam" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 }, -/obj/structure/cable{ - icon_state = "4-8" +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 }, /turf/open/floor/plasteel, -/area/security/prison) -"aam" = ( -/obj/structure/cable{ - icon_state = "0-2" - }, -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/security/prison) +/area/security/prison/upper) "aan" = ( -/obj/machinery/hydroponics/soil, -/obj/item/seeds/ambrosia, -/obj/machinery/newscaster{ - pixel_y = 32 - }, -/turf/open/floor/grass, -/area/security/prison) -"aao" = ( -/obj/machinery/hydroponics/soil, -/obj/item/plant_analyzer, -/obj/structure/sign/warning/electricshock{ - pixel_y = 32 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/grass, -/area/security/prison) -"aap" = ( -/obj/machinery/hydroponics/soil, -/obj/item/seeds/carrot, -/obj/structure/cable{ - icon_state = "1-4" - }, -/turf/open/floor/grass, -/area/security/prison) -"aaq" = ( -/obj/machinery/camera{ - c_tag = "Prison Common Room"; - network = list("ss13","prison") +/obj/structure/closet/crate/bin, +/obj/effect/spawner/lootdrop/prison_contraband, +/obj/item/trash/sosjerky, +/obj/item/trash/boritos, +/obj/item/trash/can, +/obj/effect/turf_decal/tile/green{ + dir = 8 }, +/obj/effect/turf_decal/tile/green, /obj/effect/turf_decal/tile/green{ dir = 1 }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/radio/intercom{ + desc = "Talk through this. It looks like it has been modified to not broadcast."; + name = "Prison Intercom (General)"; + pixel_x = -27; + pixel_y = -27; + prison_radio = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"aao" = ( /obj/effect/turf_decal/tile/green, /obj/effect/turf_decal/tile/green{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"aap" = ( /obj/effect/turf_decal/tile/green{ dir = 8 }, -/obj/structure/sink{ - pixel_y = 20 - }, -/obj/structure/cable{ - icon_state = "4-8" +/obj/effect/turf_decal/tile/green{ + dir = 1 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/security/prison) -"aar" = ( -/obj/machinery/hydroponics/soil, -/obj/item/seeds/glowshroom, -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/grass, -/area/security/prison) -"aas" = ( -/obj/structure/sign/warning/electricshock{ - pixel_y = 32 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/upper) "aat" = ( -/turf/open/floor/plasteel, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/dark, /area/security/prison) "aau" = ( -/obj/machinery/biogenerator, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, /turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/upper) "aav" = ( /obj/structure/cable{ icon_state = "1-2" }, /turf/open/floor/plasteel, /area/security/prison) -"aaw" = ( -/obj/machinery/light{ +"aax" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"aay" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ dir = 8 }, -/turf/open/floor/grass, -/area/security/prison) -"aax" = ( -/mob/living/simple_animal/mouse/brown/Tom, -/turf/open/floor/grass, -/area/security/prison) -"aay" = ( -/turf/open/floor/plating, -/area/security/prison) +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "aaz" = ( /obj/machinery/disposal/bin, /obj/structure/sign/plaques/deempisi{ @@ -207,29 +209,99 @@ /turf/open/floor/plasteel, /area/service/bar) "aaA" = ( -/obj/machinery/seed_extractor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, /turf/open/floor/plasteel, -/area/security/prison) -"aaB" = ( -/obj/structure/window/reinforced, -/obj/machinery/hydroponics/soil, -/obj/item/seeds/potato, -/turf/open/floor/grass, -/area/security/prison) +/area/security/prison/upper) "aaC" = ( -/obj/machinery/hydroponics/soil, -/obj/structure/window/reinforced, -/obj/item/seeds/tower, -/turf/open/floor/grass, -/area/security/prison) +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/obj/machinery/holopad, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/effect/decal/cleanable/blood/old, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel, +/area/security/prison/upper) "aaD" = ( -/obj/structure/window/reinforced, -/obj/machinery/hydroponics/soil, -/obj/item/seeds/grass, -/turf/open/floor/grass, -/area/security/prison) +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison/upper) "aaE" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Prison Cafeteria" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) +"aaF" = ( /obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"aaG" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) +"aaH" = ( +/turf/open/floor/plating/airless, +/area/space/nearstation) +"aaI" = ( +/obj/machinery/washing_machine, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) +"aaK" = ( /obj/effect/turf_decal/tile/green{ dir = 4 }, @@ -239,40 +311,12 @@ /obj/effect/turf_decal/tile/green{ dir = 1 }, -/turf/open/floor/plasteel, -/area/security/prison) -"aaF" = ( -/obj/structure/window/reinforced, -/obj/machinery/hydroponics/soil, -/obj/item/cultivator, -/turf/open/floor/grass, -/area/security/prison) -"aaG" = ( -/obj/machinery/light{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/vr_sleeper{ - dir = 8 - }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, -/area/security/prison) -"aaH" = ( -/turf/open/floor/plating/airless, -/area/space/nearstation) -"aaI" = ( -/obj/structure/bookcase, -/turf/open/floor/plasteel, -/area/security/prison) -"aaJ" = ( -/obj/structure/chair/stool, -/turf/open/floor/plasteel, -/area/security/prison) -"aaK" = ( -/obj/machinery/computer/arcade/battle{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/upper) "aaL" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/preopen{ @@ -300,9 +344,9 @@ /turf/open/floor/plating, /area/command/heads_quarters/hos) "aaN" = ( -/obj/structure/chair/sofa/right, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/effect/spawner/structure/window, +/turf/open/floor/plating, +/area/security/prison/upper) "aaO" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/preopen{ @@ -314,25 +358,17 @@ /turf/open/floor/plating, /area/command/heads_quarters/hos) "aaP" = ( -/obj/machinery/computer/cryopod{ - dir = 8; - pixel_x = 26 - }, -/obj/machinery/cryopod{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "aaQ" = ( /turf/closed/wall, /area/security/warden) "aaR" = ( -/obj/structure/lattice, -/obj/structure/sign/warning/securearea{ - pixel_y = -32 - }, -/turf/open/space, -/area/space/nearstation) +/obj/structure/table/reinforced, +/turf/open/floor/plasteel, +/area/security/prison/upper) "aaS" = ( /obj/structure/grille, /obj/structure/lattice, @@ -344,31 +380,31 @@ /turf/open/space, /area/space/nearstation) "aaU" = ( -/obj/machinery/computer/arcade/orion_trail{ - dir = 4 +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/door/airlock/security/glass{ + id_tag = "permaouter"; + name = "Permabrig Transfer"; + req_access_txt = "2" }, -/turf/open/floor/plasteel, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, /area/security/prison) "aaV" = ( -/obj/structure/table/wood, -/obj/item/storage/dice, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/closed/wall, +/area/security/prison/upper) "aaW" = ( -/obj/effect/landmark/event_spawn, -/obj/structure/chair/comfy/brown{ - color = "#596479"; +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel, -/area/security/prison) -"aaX" = ( -/obj/structure/window/reinforced, -/obj/machinery/cryopod{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/prison) +/turf/closed/wall, +/area/security/prison/upper) "aaY" = ( /obj/effect/turf_decal/bot, /obj/structure/closet/crate/secure/weapon{ @@ -408,17 +444,27 @@ /turf/open/space, /area/space/nearstation) "abb" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 +/obj/effect/turf_decal/tile/red{ + dir = 4 }, -/turf/closed/wall, -/area/security/execution/transfer) +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "abc" = ( /turf/closed/wall, /area/security/execution/transfer) "abd" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 }, /turf/closed/wall, /area/security/execution/transfer) @@ -426,34 +472,85 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/closed/wall, +/turf/closed/wall/r_wall, /area/security/execution/transfer) "abf" = ( -/obj/machinery/vending/sustenance, -/turf/open/floor/plasteel, -/area/security/prison) -"abg" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 }, -/turf/closed/wall, -/area/security/execution/transfer) -"abh" = ( -/obj/machinery/holopad, -/turf/open/floor/plasteel, -/area/security/prison) -"abi" = ( -/obj/machinery/shower{ +/obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/obj/item/soap/nanotrasen, -/turf/open/floor/plasteel/freezer, -/area/security/prison) +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/airlock/grunge{ + name = "Prison Laundry"; + wiretypepath = /datum/wires/airlock/security + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) +"abg" = ( +/obj/machinery/door/firedoor, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) +"abh" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/light, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/effect/decal/cleanable/blood/old, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"abi" = ( +/obj/machinery/button/flasher{ + id = "visitorflash"; + pixel_x = -6; + pixel_y = 24 + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/machinery/button/door{ + id = "visitation"; + name = "Visitation Shutters"; + pixel_x = -6; + pixel_y = 36; + req_access_txt = "2" + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "abj" = ( -/obj/structure/bedsheetbin/color, -/obj/structure/table, -/turf/open/floor/plasteel/freezer, -/area/security/prison) +/obj/structure/chair/office{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "abk" = ( /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ @@ -496,22 +593,18 @@ }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) -"abs" = ( -/obj/structure/cable{ - icon_state = "0-2" - }, -/obj/machinery/power/tracker, -/turf/open/floor/plasteel/airless/solarpanel, -/area/solars/port/fore) "abt" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 +/obj/effect/turf_decal/tile/red{ + dir = 8 }, -/obj/effect/turf_decal/stripes/line{ - dir = 9 +/obj/effect/turf_decal/tile/red, +/obj/machinery/light, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/structure/cable{ + icon_state = "4-8" }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) +/turf/open/floor/plasteel, +/area/security/prison/cells) "abu" = ( /obj/machinery/door/poddoor{ id = "executionspaceblast" @@ -519,27 +612,23 @@ /turf/open/floor/plating, /area/security/execution/transfer) "abv" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 +/obj/machinery/camera{ + c_tag = "Prison Cell Block East"; + dir = 8; + network = list("ss13","prison") }, -/obj/effect/turf_decal/stripes/line{ - dir = 5 +/obj/effect/turf_decal/tile/red{ + dir = 8 }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"abw" = ( -/obj/machinery/light/small{ - dir = 1 +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 }, -/obj/machinery/flasher{ - id = "executionflash"; - pixel_y = 25 +/obj/structure/cable{ + icon_state = "1-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) +/turf/open/floor/plasteel, +/area/security/prison/cells) "abx" = ( /obj/machinery/camera/motion{ c_tag = "Armory External Motion Sensor"; @@ -548,10 +637,6 @@ /obj/structure/lattice/catwalk, /turf/open/space/basic, /area/ai_monitored/security/armory) -"aby" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall/r_wall, -/area/security/execution/transfer) "abz" = ( /obj/machinery/light/small{ dir = 4; @@ -560,43 +645,35 @@ /turf/open/floor/engine, /area/science/xenobiology) "abA" = ( -/obj/machinery/light, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "2-4" }, -/turf/open/floor/plasteel, -/area/security/prison) -"abB" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 +/obj/structure/cable{ + icon_state = "0-2" }, -/turf/open/floor/plasteel, -/area/security/prison) -"abC" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Prison Lockdown Shutters" }, -/turf/open/floor/plasteel, -/area/security/prison) -"abD" = ( -/obj/machinery/light, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/security/prison) "abE" = ( -/obj/structure/cable{ - icon_state = "1-2" +/obj/structure/chair/stool, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 }, /turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/upper) "abF" = ( -/turf/open/floor/plasteel/freezer, -/area/security/prison) +/obj/structure/table, +/obj/item/flashlight/lamp, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "abG" = ( /obj/structure/lattice/catwalk, /turf/open/space/basic, @@ -633,43 +710,27 @@ /turf/open/floor/plasteel/dark, /area/security/office) "abK" = ( -/obj/structure/chair/stool, -/obj/machinery/light/small{ - dir = 1 +/obj/structure/window/reinforced{ + dir = 8 }, -/obj/machinery/button/door{ - id = "permabolt3"; - name = "Cell Bolt Control"; - normaldoorcontrol = 1; - pixel_y = 25; - specialfunctions = 4 +/obj/structure/chair{ + dir = 4 }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel, /area/security/prison) "abL" = ( /obj/structure/chair/stool, -/obj/machinery/light/small{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ dir = 1 }, -/obj/machinery/button/door{ - id = "permabolt2"; - name = "Cell Bolt Control"; - normaldoorcontrol = 1; - pixel_y = 25; - specialfunctions = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 - }, /turf/open/floor/plasteel, -/area/security/prison) -"abM" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/upper) "abN" = ( /obj/effect/landmark/secequipment, /obj/effect/turf_decal/tile/red{ @@ -731,7 +792,7 @@ }, /obj/machinery/firealarm{ dir = 4; - pixel_x = -26 + pixel_x = -24 }, /turf/open/floor/plasteel/showroomfloor, /area/security/office) @@ -757,13 +818,6 @@ /obj/structure/grille, /turf/open/space, /area/space/nearstation) -"abZ" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "aca" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -788,52 +842,52 @@ /turf/closed/wall, /area/security/prison) "ace" = ( -/obj/machinery/door/poddoor/preopen{ - id = "permacell3"; - name = "cell blast door" +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 }, -/obj/machinery/door/airlock/public/glass{ - id_tag = "permabolt3"; - name = "Cell 3" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plasteel, -/area/security/prison) -"acf" = ( -/obj/machinery/door/poddoor/preopen{ - id = "permacell2"; - name = "cell blast door" - }, -/obj/machinery/door/airlock/public/glass{ - id_tag = "permabolt2"; - name = "Cell 2" +/obj/structure/cable{ + icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/dark, /area/security/prison) "acg" = ( +/obj/machinery/door/poddoor/shutters{ + id = "visitation"; + name = "Visitation Shutters" + }, +/obj/machinery/door/window/southleft, +/obj/structure/table/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) +"ach" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/door/poddoor/preopen{ - id = "permacell1"; - name = "cell blast door" +/obj/machinery/camera{ + c_tag = "Prison Visitation"; + dir = 8; + network = list("ss13","prison") }, -/obj/machinery/door/airlock/public/glass{ - id_tag = "permabolt1"; - name = "Cell 1" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plasteel, -/area/security/prison) -"ach" = ( -/obj/machinery/door/airlock{ - name = "Unisex Restroom" - }, -/turf/open/floor/plasteel/freezer, -/area/security/prison) +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "aci" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, /obj/structure/cable{ @@ -949,10 +1003,12 @@ /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) "acp" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable{ icon_state = "2-4" }, @@ -1038,64 +1094,64 @@ /obj/item/stack/cable_coil/random, /turf/open/space, /area/space/nearstation) -"acz" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) "acA" = ( -/obj/machinery/atmospherics/components/unary/outlet_injector/on, -/obj/effect/turf_decal/stripes/line{ - dir = 6 +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"acB" = ( -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"acC" = ( -/obj/structure/bed, -/obj/machinery/camera{ - c_tag = "Prison Cell 3"; - network = list("ss13","prison") +/obj/effect/turf_decal/tile/neutral{ + dir = 8 }, -/obj/item/radio/intercom{ - desc = "Talk through this. It looks like it has been modified to not broadcast."; - name = "Prison Intercom (General)"; - pixel_y = 24; - prison_radio = 1 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"acD" = ( -/obj/structure/chair/stool, -/obj/machinery/light/small{ +/obj/effect/turf_decal/tile/neutral{ dir = 1 }, +/obj/effect/landmark/start/prisoner, /obj/machinery/button/door{ - id = "permabolt1"; - name = "Cell Bolt Control"; - normaldoorcontrol = 1; - pixel_y = 25; - specialfunctions = 4 + id = "permacells1"; + name = "Privacy Shutters"; + pixel_x = 25 }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) +"acC" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, /area/security/prison) -"acE" = ( -/obj/structure/bed, -/obj/machinery/camera{ - c_tag = "Prison Cell 2"; - network = list("ss13","prison") +"acD" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "Prison Gate"; + name = "prison blast door" }, -/obj/item/radio/intercom{ - desc = "Talk through this. It looks like it has been modified to not broadcast."; - name = "Prison Intercom (General)"; - pixel_y = 24; - prison_radio = 1 +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Prison Lockdown Shutters" + }, +/turf/open/floor/plating, +/area/security/prison/upper) +"acE" = ( +/obj/structure/chair{ + dir = 8 + }, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" }, /turf/open/floor/plasteel, /area/security/prison) @@ -1110,37 +1166,25 @@ /turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) "acG" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel, -/area/security/prison) +/turf/closed/wall, +/area/security/prison/upper) "acH" = ( -/obj/structure/bed, -/obj/machinery/camera{ - c_tag = "Prison Cell 1"; - network = list("ss13","prison") +/obj/structure/window/reinforced/tinted{ + dir = 8 }, -/obj/item/radio/intercom{ - desc = "Talk through this. It looks like it has been modified to not broadcast."; - name = "Prison Intercom (General)"; - pixel_y = 24; - prison_radio = 1 +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 }, -/turf/open/floor/plasteel, -/area/security/prison) -"acI" = ( -/obj/machinery/door/poddoor/preopen{ - id = "executionfireblast" +/obj/effect/turf_decal/tile/blue{ + dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/general/hidden, -/obj/machinery/door/firedoor, -/obj/machinery/door/window/westright{ - dir = 1; - name = "Transfer Room"; - req_access_txt = "2" - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/blue{ dir = 1 }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"acI" = ( +/obj/effect/spawner/lootdrop/prison_contraband, /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ dir = 4 @@ -1148,28 +1192,34 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/bed, +/obj/item/bedsheet/red, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel/dark, -/area/security/execution/transfer) +/area/security/prison/cells) "acJ" = ( +/obj/structure/chair/stool, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"acK" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, -/area/security/prison) -"acK" = ( -/obj/structure/mirror{ - pixel_x = 25 - }, -/obj/machinery/light/small{ - dir = 8 - }, -/obj/structure/sink{ - dir = 4; - pixel_x = 11 - }, -/turf/open/floor/plasteel/freezer, -/area/security/prison) +/area/security/prison/upper) "acL" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk, @@ -1178,7 +1228,7 @@ }, /obj/machinery/firealarm{ dir = 8; - pixel_x = 28 + pixel_x = 24 }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) @@ -1256,16 +1306,6 @@ /obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plating, /area/maintenance/fore/secondary) -"acV" = ( -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "acW" = ( /obj/structure/cable{ icon_state = "0-2" @@ -1276,77 +1316,77 @@ }, /turf/open/floor/plasteel/airless/solarpanel, /area/solars/port/fore) -"acX" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/poddoor/preopen{ - id = "executionfireblast" - }, -/obj/machinery/door/firedoor, -/turf/open/floor/plating, -/area/security/execution/transfer) "acY" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, /obj/structure/table, -/obj/item/paper, -/obj/item/pen, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/security/prison) -"acZ" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/preopen{ - id = "executionfireblast" - }, -/obj/machinery/door/firedoor, -/turf/open/floor/plating, -/area/security/execution/transfer) "ada" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/machinery/flasher{ - id = "PCell 3"; - pixel_x = -28 +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 }, -/turf/open/floor/plasteel, -/area/security/prison) -"adb" = ( -/obj/structure/table, -/obj/item/paper, -/obj/item/pen, -/turf/open/floor/plasteel, -/area/security/prison) -"adc" = ( -/obj/machinery/flasher{ - id = "PCell 1"; - pixel_x = -28 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"add" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/machinery/flasher{ - id = "PCell 2"; - pixel_x = -28 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"ade" = ( /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/structure/extinguisher_cabinet{ + pixel_x = -26 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"adb" = ( +/turf/open/floor/plasteel, +/area/security/prison/upper) +"adc" = ( +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"add" = ( +/obj/structure/table, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_x = -6; + pixel_y = 10 + }, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_x = -6; + pixel_y = -2 + }, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_x = -6; + pixel_y = 4 + }, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_x = -6; + pixel_y = -8 + }, +/obj/item/clothing/under/rank/prisoner{ + pixel_x = 8; + pixel_y = 5 + }, +/obj/machinery/camera{ + c_tag = "Permabrig Processing"; + dir = 8; + network = list("ss13","prison") }, /turf/open/floor/plasteel, /area/security/prison) "adf" = ( -/obj/structure/toilet/secret/prison{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" }, -/turf/open/floor/plasteel/freezer, -/area/security/prison) +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "adg" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -1446,18 +1486,7 @@ /turf/open/floor/plasteel, /area/security/prison) "adp" = ( -/obj/structure/table, /obj/effect/turf_decal/tile/red, -/obj/item/radio/headset{ - desc = "An updated, modular intercom that fits over the head. Takes encryption keys. It looks like it has been modified to not broadcast."; - name = "prisoner headset"; - prison_radio = 1 - }, -/obj/item/radio/headset{ - desc = "An updated, modular intercom that fits over the head. Takes encryption keys. It looks like it has been modified to not broadcast."; - name = "prisoner headset"; - prison_radio = 1 - }, /turf/open/floor/plasteel, /area/security/prison) "adq" = ( @@ -1496,24 +1525,6 @@ /obj/effect/landmark/barthpot, /turf/open/floor/wood, /area/service/library) -"adw" = ( -/obj/structure/cable, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) -"adx" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "ady" = ( /obj/structure/lattice/catwalk, /turf/open/space, @@ -1538,89 +1549,61 @@ }, /turf/open/floor/plasteel, /area/security/office) -"adC" = ( -/obj/structure/table, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/item/razor, -/obj/item/toy/plush/borgplushie{ - desc = "A horrible abomination to God in plushie form. Legends say this is used to torture prisoners by repeatedly beating them in the head with it.. ..It feels sorta heavy."; - force = 1; - name = "dogborg plushie"; - throwforce = 1 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) "adD" = ( -/obj/machinery/button/flasher{ - id = "executionflash"; - pixel_x = 24; - pixel_y = 5 - }, -/obj/machinery/button/door{ - id = "executionspaceblast"; - name = "Vent to Space"; - pixel_x = 25; - pixel_y = -5; - req_access_txt = "7" - }, -/obj/machinery/atmospherics/pipe/simple/general/hidden, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"adE" = ( -/obj/structure/table, -/obj/item/folder/red{ - pixel_x = 3 - }, -/obj/item/taperecorder{ - pixel_x = -3 - }, -/obj/item/assembly/flash/handheld, -/obj/item/reagent_containers/spray/pepper, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall, +/area/security/prison/cells) "adF" = ( +/obj/machinery/door/airlock/security/glass{ + id_tag = "permaouter"; + name = "Permabrig Transfer"; + req_access_txt = "2" + }, +/obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall, -/area/security/prison) -"adG" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/security/prison) -"adH" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Long-Term Cell 3"; - req_access_txt = "2" - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 }, -/turf/open/floor/plasteel, -/area/security/prison) -"adI" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Long-Term Cell 2"; - req_access_txt = "2" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"adJ" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Long-Term Cell 1"; - req_access_txt = "2" - }, /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"adH" = ( +/obj/machinery/door/airlock/security/glass{ + id_tag = "permaouter"; + name = "Permabrig Transfer"; + req_access_txt = "2" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 }, -/turf/open/floor/plasteel, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/dark, /area/security/prison) +"adI" = ( +/turf/closed/wall/r_wall, +/area/security/prison/upper) +"adJ" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Prison Visitation"; + req_access_txt = "2" + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "adK" = ( /obj/effect/turf_decal/tile/red{ dir = 4 @@ -1629,14 +1612,14 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/firealarm{ - dir = 4; - pixel_x = -26 - }, /obj/machinery/camera{ c_tag = "Brig EVA Storage"; dir = 4 }, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = -24 + }, /turf/open/floor/plasteel/dark, /area/security/brig) "adL" = ( @@ -1789,170 +1772,123 @@ /obj/structure/lattice/catwalk, /turf/open/space, /area/solars/starboard/fore) -"adZ" = ( -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) -"aea" = ( -/obj/machinery/portable_atmospherics/canister/nitrous_oxide, -/obj/machinery/atmospherics/components/unary/portables_connector/visible, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plating, -/area/security/execution/transfer) -"aeb" = ( -/obj/structure/table, -/obj/item/flashlight/lamp, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"aec" = ( -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/machinery/portable_atmospherics/canister/carbon_dioxide, -/obj/machinery/atmospherics/components/unary/portables_connector/visible, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plating, -/area/security/execution/transfer) "aed" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/turf_decal/delivery, +/obj/machinery/disposal/deliveryChute{ + name = "Prisoner Chute" }, -/obj/machinery/button/ignition{ - id = "executionburn"; - pixel_x = 24; - pixel_y = 5 +/obj/structure/plasticflaps/opaque{ + name = "Prisoner Transfer" }, -/obj/machinery/button/door{ - id = "executionfireblast"; - name = "Transfer Area Lockdown"; - pixel_x = 25; - pixel_y = -5; - req_access_txt = "2" - }, -/obj/machinery/atmospherics/pipe/simple/general/hidden, +/obj/structure/disposalpipe/trunk, /turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"aee" = ( -/obj/structure/chair{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) +/area/security/prison) "aef" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison) +"aeg" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /obj/effect/turf_decal/tile/red{ dir = 1 }, /obj/effect/turf_decal/tile/red{ dir = 8 }, -/obj/structure/table, -/obj/item/restraints/handcuffs, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, /turf/open/floor/plasteel, /area/security/prison) -"aeg" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/turf/closed/wall/r_wall, -/area/security/execution/transfer) "aeh" = ( -/obj/machinery/button/door{ - id = "permacell3"; - name = "Cell 3 Lockdown"; - pixel_x = -4; - pixel_y = 25; - req_access_txt = "2" - }, -/obj/machinery/button/flasher{ - id = "PCell 3"; - pixel_x = 6; - pixel_y = 24 - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/tile/red{ dir = 4 }, -/turf/open/floor/plasteel, -/area/security/prison) -"aei" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"aej" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"aek" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/machinery/computer/security/telescreen/prison{ - pixel_y = 30 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/extinguisher_cabinet{ + pixel_y = 30 + }, +/turf/open/floor/plasteel, +/area/security/prison) +"aei" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Prison Lockdown Shutters" + }, +/turf/open/floor/plating, +/area/security/prison) +"aej" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/light_switch{ + pixel_y = 23 + }, +/turf/open/floor/plasteel, +/area/security/prison) +"aek" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /obj/effect/turf_decal/tile/red{ dir = 1 }, /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/machinery/firealarm{ + pixel_y = 24 + }, /turf/open/floor/plasteel, /area/security/prison) "ael" = ( -/obj/machinery/button/door{ - id = "permacell2"; - name = "Cell 2 Lockdown"; - pixel_x = -4; - pixel_y = 25; - req_access_txt = "2" - }, -/obj/machinery/button/flasher{ - id = "PCell 2"; - pixel_x = 6; - pixel_y = 24 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, /turf/open/floor/plasteel, /area/security/prison) "aem" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/structure/disposalpipe/segment, /turf/open/floor/plasteel, /area/security/prison) "aen" = ( -/obj/machinery/computer/security/telescreen/prison{ - pixel_y = 30 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /obj/machinery/camera{ - c_tag = "Prison Hallway"; + c_tag = "Prison Hallway East"; network = list("ss13","prison") }, /obj/effect/turf_decal/tile/red{ @@ -1970,9 +1906,6 @@ /obj/effect/turf_decal/tile/red{ dir = 1 }, -/obj/structure/extinguisher_cabinet{ - pixel_y = 30 - }, /turf/open/floor/plasteel, /area/security/prison) "aep" = ( @@ -1982,41 +1915,24 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/security/prison) "aeq" = ( -/obj/machinery/button/door{ - id = "permacell1"; - name = "Cell 1 Lockdown"; - pixel_x = -4; - pixel_y = 25; - req_access_txt = "2" - }, -/obj/machinery/button/flasher{ - id = "PCell 1"; - pixel_x = 6; - pixel_y = 24 - }, -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, /turf/open/floor/plasteel, /area/security/prison) "aer" = ( -/obj/machinery/firealarm{ - pixel_y = 24 - }, /obj/machinery/power/apc{ areastring = "/area/security/prison"; dir = 4; name = "Prison Wing APC"; pixel_x = 24 }, -/obj/structure/cable{ - icon_state = "0-8" - }, /obj/effect/turf_decal/tile/red{ dir = 1 }, @@ -2024,6 +1940,13 @@ /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, /turf/open/floor/plasteel, /area/security/prison) "aes" = ( @@ -2165,6 +2088,9 @@ }, /obj/machinery/suit_storage_unit/hos, /obj/effect/turf_decal/delivery, +/obj/machinery/status_display/ai{ + pixel_x = 32 + }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) "aeE" = ( @@ -2216,103 +2142,31 @@ }, /turf/open/floor/plasteel/airless/solarpanel, /area/solars/starboard/fore) -"aeH" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 8 - }, -/obj/machinery/light/small{ - dir = 8 - }, -/obj/machinery/portable_atmospherics/canister/nitrous_oxide, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plating, -/area/security/execution/transfer) -"aeI" = ( -/obj/structure/rack, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/obj/item/flashlight{ - pixel_x = 1; - pixel_y = 5 - }, -/obj/item/tank/internals/anesthetic{ - pixel_x = -3; - pixel_y = 1 - }, -/obj/item/tank/internals/oxygen/red{ - pixel_x = 3 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"aeJ" = ( -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 9 - }, -/turf/open/floor/plating, -/area/security/execution/transfer) -"aeK" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/general/hidden, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) "aeL" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plasteel/dark, -/area/security/execution/transfer) +/area/security/prison) "aeM" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 +/obj/structure/cable{ + icon_state = "2-4" }, /obj/structure/cable{ - icon_state = "2-8" + icon_state = "1-4" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 }, /turf/open/floor/plasteel, /area/security/prison) -"aeN" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security{ - aiControlDisabled = 1; - name = "Prisoner Transfer Centre"; - req_access_txt = "2" - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) "aeO" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -2332,22 +2186,24 @@ /obj/structure/cable{ icon_state = "2-4" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, /obj/effect/turf_decal/tile/red{ dir = 1 }, /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/security/prison) "aeQ" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable{ icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/security/prison) "aeR" = ( @@ -2357,16 +2213,10 @@ /turf/open/floor/plating, /area/hallway/secondary/exit) "aeS" = ( -/obj/structure/closet/secure_closet/brig, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 }, -/obj/item/radio/headset{ - desc = "An updated, modular intercom that fits over the head. Takes encryption keys. It looks like it has been modified to not broadcast."; - name = "prisoner headset"; - prison_radio = 1 - }, /obj/structure/cable{ icon_state = "1-2" }, @@ -2376,10 +2226,12 @@ /obj/structure/cable{ icon_state = "1-4" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable{ icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/security/prison) "aeU" = ( @@ -2691,6 +2543,10 @@ /obj/structure/cable{ icon_state = "0-4" }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Prison Lockdown Shutters" + }, /turf/open/floor/plating, /area/security/brig) "afr" = ( @@ -2717,90 +2573,73 @@ /obj/effect/turf_decal/bot, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) -"aft" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 5 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/plating, -/area/security/execution/transfer) "afu" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/security/execution/transfer) -"afv" = ( -/obj/machinery/atmospherics/pipe/simple/general/hidden{ +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"afw" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 4; - layer = 2.4 - }, -/obj/machinery/door/window/southleft{ - base_state = "right"; - dir = 4; - icon_state = "right"; - name = "Armory"; - req_access_txt = "2" - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plating, -/area/security/execution/transfer) -"afx" = ( -/obj/machinery/light_switch{ - pixel_x = 25 - }, -/obj/machinery/atmospherics/pipe/simple/general/hidden{ - dir = 9 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"afy" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/general/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"afz" = ( /obj/effect/turf_decal/tile/red{ dir = 1 }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/bot_white, +/obj/structure/closet/secure_closet/brig, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"afv" = ( +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"afw" = ( /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 }, -/obj/structure/cable{ - icon_state = "1-2" +/obj/structure/reagent_dispensers/peppertank{ + pixel_y = -32 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"afy" = ( +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"afA" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 }, /turf/open/floor/plasteel, /area/security/prison) -"afA" = ( -/turf/closed/wall/r_wall, -/area/security/execution/transfer) "afB" = ( /obj/item/radio/intercom{ dir = 4; name = "Station Intercom (General)"; pixel_x = 27 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 - }, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/security/prison) "afC" = ( @@ -2831,21 +2670,16 @@ /turf/open/floor/plating, /area/hallway/secondary/exit) "afF" = ( -/obj/structure/table, -/obj/item/assembly/signaler, -/obj/item/clothing/suit/straight_jacket, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/machinery/light{ + light_color = "#d1dfff" + }, /turf/open/floor/plasteel, /area/security/prison) "afG" = ( -/obj/structure/table, -/obj/item/storage/box/hug, -/obj/item/razor{ - pixel_x = -6 - }, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 @@ -2893,17 +2727,6 @@ /obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel/showroomfloor, /area/security/brig) -"afJ" = ( -/obj/structure/extinguisher_cabinet{ - pixel_x = 1; - pixel_y = -27 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/prison) "afK" = ( /obj/structure/table/glass, /obj/machinery/computer/med_data/laptop, @@ -3082,39 +2905,59 @@ /area/security/range) "agf" = ( /obj/structure/table, -/obj/item/stack/sheet/metal, -/obj/item/storage/box/bodybags, -/obj/item/pen, -/obj/machinery/firealarm{ - dir = 1; - pixel_y = -24 +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/item/clothing/gloves/color/orange, +/obj/item/restraints/handcuffs, +/obj/item/reagent_containers/spray/pepper, /turf/open/floor/plasteel/dark, -/area/security/execution/transfer) +/area/security/prison) "agg" = ( -/obj/structure/closet/secure_closet/injection, -/obj/structure/cable, -/obj/machinery/power/apc{ - areastring = "/area/security/execution/transfer"; - name = "Prisoner Transfer Centre"; - pixel_y = -27 +/obj/structure/table, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/item/clothing/suit/straight_jacket, +/obj/item/electropack/shockcollar, +/obj/item/assembly/signaler, /turf/open/floor/plasteel/dark, -/area/security/execution/transfer) +/area/security/prison) "agh" = ( /obj/structure/table, -/obj/item/electropack, -/obj/item/screwdriver, -/obj/item/wrench, -/obj/item/clothing/head/helmet, -/obj/item/assembly/signaler, -/obj/machinery/light/small, -/obj/machinery/airalarm{ - dir = 1; - pixel_y = -22 +/obj/item/storage/box/hug, +/obj/item/razor{ + pixel_x = -6 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/light{ + light_color = "#d1dfff" }, /turf/open/floor/plasteel/dark, -/area/security/execution/transfer) +/area/security/prison) "agi" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/security/glass{ @@ -3494,7 +3337,11 @@ /obj/structure/cable{ icon_state = "1-8" }, -/turf/open/floor/plasteel, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Prison Lockdown Shutters" + }, +/turf/open/floor/plasteel/dark, /area/security/brig) "agP" = ( /obj/structure/cable{ @@ -3846,6 +3693,10 @@ /obj/structure/cable{ icon_state = "0-4" }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Prison Lockdown Shutters" + }, /turf/open/floor/plating, /area/security/brig) "ahw" = ( @@ -3857,6 +3708,10 @@ icon_state = "1-4" }, /obj/structure/cable, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Prison Lockdown Shutters" + }, /turf/open/floor/plating, /area/security/brig) "ahx" = ( @@ -3972,19 +3827,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/security/processing) -"ahE" = ( -/obj/structure/closet/secure_closet/brig, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/item/radio/headset{ - desc = "An updated, modular intercom that fits over the head. Takes encryption keys. It looks like it has been modified to not broadcast."; - name = "prisoner headset"; - prison_radio = 1 - }, -/turf/open/floor/plasteel, -/area/security/prison) "ahF" = ( /obj/structure/cable{ icon_state = "4-8" @@ -4407,9 +4249,6 @@ /turf/open/floor/plating, /area/security/brig) "aik" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, /obj/effect/turf_decal/tile/red{ dir = 1 }, @@ -4424,12 +4263,6 @@ }, /turf/open/floor/plasteel, /area/security/office) -"ail" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/security/range) "aim" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -4754,6 +4587,9 @@ }, /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/bot, +/obj/structure/extinguisher_cabinet{ + pixel_x = -26 + }, /turf/open/floor/plasteel/dark, /area/security/brig) "aiJ" = ( @@ -4822,7 +4658,7 @@ pixel_x = -32 }, /turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/area/medical/medbay/central) "aiQ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -5070,9 +4906,6 @@ /turf/open/floor/plasteel, /area/commons/vacant_room/office/b) "aju" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, /obj/structure/cable{ icon_state = "2-4" }, @@ -5392,13 +5225,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/maintenance/solars/port/fore) -"ajW" = ( -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "ajX" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -5577,6 +5403,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/machinery/status_display/ai{ + pixel_y = 32 + }, /turf/open/floor/plasteel, /area/security/brig) "akp" = ( @@ -5802,7 +5631,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/security/brig) @@ -5813,6 +5641,7 @@ "akL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/meter, +/obj/structure/closet/firecloset, /turf/open/floor/plating, /area/maintenance/fore) "akM" = ( @@ -5847,15 +5676,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/engine, /area/science/xenobiology) -"akQ" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/turf/open/floor/plasteel, -/area/security/prison) "akR" = ( /obj/machinery/camera{ c_tag = "Security Office"; @@ -5870,6 +5690,9 @@ }, /obj/structure/table, /obj/item/storage/box/donkpockets, +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, /turf/open/floor/plasteel, /area/security/office) "akS" = ( @@ -6629,19 +6452,6 @@ }, /turf/open/floor/plasteel/dark, /area/security/courtroom) -"amv" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "amw" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -7078,11 +6888,6 @@ id = "Cell 2"; name = "Cell 2 Locker" }, -/obj/item/radio/headset{ - desc = "An updated, modular intercom that fits over the head. Takes encryption keys. It looks like it has been modified to not broadcast."; - name = "prisoner headset"; - prison_radio = 1 - }, /obj/structure/cable{ icon_state = "1-4" }, @@ -7690,7 +7495,7 @@ }, /obj/machinery/firealarm{ dir = 8; - pixel_x = 24; + pixel_x = 26; pixel_y = -28 }, /turf/open/floor/plasteel, @@ -7858,14 +7663,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/power/apc{ - areastring = "/area/commons/fitness"; - name = "Fitness Room APC"; - pixel_y = -24 - }, -/obj/structure/cable{ - icon_state = "0-8" - }, /turf/open/floor/plating, /area/maintenance/fore/secondary) "apv" = ( @@ -8495,16 +8292,6 @@ }, /turf/open/floor/plasteel, /area/security/processing) -"aqJ" = ( -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "aqN" = ( /obj/structure/closet/secure_closet/warden, /obj/structure/sign/poster/official/ion_rifle{ @@ -8832,11 +8619,6 @@ id = "Cell 3"; name = "Cell 3 Locker" }, -/obj/item/radio/headset{ - desc = "An updated, modular intercom that fits over the head. Takes encryption keys. It looks like it has been modified to not broadcast."; - name = "prisoner headset"; - prison_radio = 1 - }, /obj/structure/cable{ icon_state = "1-4" }, @@ -9151,7 +8933,7 @@ }, /obj/machinery/firealarm{ dir = 8; - pixel_x = 28 + pixel_x = 24 }, /turf/open/floor/plasteel/dark, /area/security/brig) @@ -9201,8 +8983,8 @@ /turf/open/floor/plasteel, /area/security/processing) "ast" = ( -/obj/structure/bed, -/obj/item/bedsheet/random, +/obj/structure/bed/double, +/obj/item/bedsheet/random/double, /turf/open/floor/carpet, /area/commons/dorms) "asu" = ( @@ -9225,7 +9007,7 @@ }, /obj/machinery/firealarm{ dir = 8; - pixel_x = 28 + pixel_x = 24 }, /turf/open/floor/plasteel, /area/security/processing) @@ -9671,6 +9453,10 @@ /area/maintenance/port/fore) "atK" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = -24 + }, /turf/open/floor/plating, /area/commons/vacant_room/office/b) "atL" = ( @@ -11953,6 +11739,14 @@ /area/commons/dorms) "aAo" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/power/apc{ + areastring = "/area/commons/fitness"; + name = "Fitness Room APC"; + pixel_y = -24 + }, +/obj/structure/cable{ + icon_state = "0-8" + }, /turf/open/floor/plasteel/dark, /area/commons/dorms) "aAp" = ( @@ -11962,6 +11756,9 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, +/obj/structure/cable{ + icon_state = "2-4" + }, /turf/open/floor/plasteel, /area/commons/dorms) "aAr" = ( @@ -12885,9 +12682,7 @@ /turf/open/floor/plasteel, /area/construction/mining/aux_base) "aCW" = ( -/obj/machinery/sleeper{ - dir = 4 - }, +/obj/machinery/stasis, /turf/open/floor/plating, /area/maintenance/port/fore) "aCX" = ( @@ -13263,6 +13058,10 @@ /obj/machinery/door/firedoor, /turf/open/floor/mineral/titanium/blue, /area/commons/toilet) +"aDW" = ( +/obj/structure/loot_pile/maint, +/turf/open/floor/plasteel, +/area/cargo/warehouse) "aDZ" = ( /obj/structure/cable{ icon_state = "4-8" @@ -13601,6 +13400,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/status_display/ai{ + pixel_x = -32 + }, /turf/open/floor/plasteel/cafeteria, /area/command/heads_quarters/cmo) "aFb" = ( @@ -14865,6 +14667,9 @@ pixel_x = 5; pixel_y = 24 }, +/obj/structure/sign/painting/library{ + pixel_x = -32 + }, /turf/open/floor/wood, /area/service/library) "aIs" = ( @@ -14879,6 +14684,9 @@ dir = 1; light_color = "#c1caff" }, +/obj/structure/sign/painting/library{ + pixel_y = 32 + }, /turf/open/floor/wood, /area/service/library) "aIt" = ( @@ -14908,6 +14716,9 @@ dir = 4 }, /obj/structure/chair/sofa/left, +/obj/structure/sign/painting/library{ + pixel_y = 32 + }, /turf/open/floor/wood, /area/service/library) "aIx" = ( @@ -14917,6 +14728,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, +/obj/structure/sign/painting/library{ + pixel_x = 32 + }, /turf/open/floor/wood, /area/service/library) "aIy" = ( @@ -15412,7 +15226,7 @@ /obj/structure/plasticflaps/opaque, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, -/area/service/kitchen/coldroom) +/area/service/kitchen) "aJL" = ( /obj/machinery/navbeacon{ codes_txt = "delivery;dir=2"; @@ -15637,10 +15451,12 @@ /obj/item/radio/intercom{ pixel_y = 25 }, -/obj/machinery/camera, /obj/structure/chair/comfy/brown{ dir = 4 }, +/obj/machinery/camera{ + c_tag = "Bar North" + }, /turf/open/floor/wood, /area/service/bar) "aKs" = ( @@ -15685,7 +15501,7 @@ /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/showroomfloor, -/area/service/kitchen/coldroom) +/area/service/kitchen) "aKD" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -15789,7 +15605,7 @@ "aKT" = ( /obj/structure/closet/secure_closet/freezer/meat, /turf/open/floor/plasteel/showroomfloor, -/area/service/kitchen/coldroom) +/area/service/kitchen) "aKU" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel, @@ -15804,7 +15620,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/service/kitchen/coldroom) +/area/service/kitchen) "aKW" = ( /obj/machinery/light_switch{ pixel_y = 28 @@ -16256,13 +16072,13 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/showroomfloor, -/area/service/kitchen/coldroom) +/area/service/kitchen) "aMl" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, /turf/open/floor/plasteel/showroomfloor, -/area/service/kitchen/coldroom) +/area/service/kitchen) "aMm" = ( /obj/machinery/firealarm{ pixel_y = 24 @@ -16313,11 +16129,11 @@ /area/service/bar) "aMw" = ( /obj/machinery/vending/dinnerware{ - contraband = list(/obj/item/reagent_containers/food/condiment/flour = 4); + contraband = list(/obj/item/reagent_containers/food/condiment/flour=4); desc = "This vendor is full of condiments to put on food."; name = "\improper Condiments Vendor"; product_ads = "Get your sauces here!;No slave labour was used to make these products!;Nanotrasen Approved?!"; - products = list(/obj/item/storage/bag/tray = 8, /obj/item/reagent_containers/food/drinks/drinkingglass = 10, /obj/item/storage/box/cups = 5, /obj/item/reagent_containers/food/condiment/pack/ketchup = 20, /obj/item/reagent_containers/food/condiment/pack/mustard = 20, /obj/item/reagent_containers/food/condiment/pack/hotsauce = 20, /obj/item/reagent_containers/food/condiment/pack/astrotame = 20, /obj/item/reagent_containers/food/condiment/saltshaker = 20, /obj/item/reagent_containers/food/condiment/peppermill = 20) + products = list(/obj/item/storage/bag/tray=8,/obj/item/reagent_containers/food/drinks/drinkingglass=10,/obj/item/storage/box/cups=5,/obj/item/reagent_containers/food/condiment/pack/ketchup=20,/obj/item/reagent_containers/food/condiment/pack/mustard=20,/obj/item/reagent_containers/food/condiment/pack/hotsauce=20,/obj/item/reagent_containers/food/condiment/pack/astrotame=20,/obj/item/reagent_containers/food/condiment/saltshaker=20,/obj/item/reagent_containers/food/condiment/peppermill=20) }, /turf/open/floor/wood, /area/service/bar) @@ -16367,7 +16183,7 @@ "aMD" = ( /obj/machinery/icecream_vat, /turf/open/floor/plasteel/showroomfloor, -/area/service/kitchen/coldroom) +/area/service/kitchen) "aME" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -16379,7 +16195,7 @@ /area/service/hydroponics) "aMF" = ( /turf/open/floor/plasteel/showroomfloor, -/area/service/kitchen/coldroom) +/area/service/kitchen) "aMG" = ( /obj/structure/closet/crate/hydroponics, /obj/item/shovel/spade, @@ -16670,7 +16486,7 @@ name = "Pete" }, /turf/open/floor/plasteel/showroomfloor, -/area/service/kitchen/coldroom) +/area/service/kitchen) "aNL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, @@ -16681,7 +16497,7 @@ dir = 8 }, /turf/open/floor/plasteel/showroomfloor, -/area/service/kitchen/coldroom) +/area/service/kitchen) "aNN" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ @@ -16702,7 +16518,7 @@ }, /obj/machinery/vending/wardrobe/chef_wardrobe, /turf/open/floor/plasteel/showroomfloor, -/area/service/kitchen/coldroom) +/area/service/kitchen) "aNP" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/wood, @@ -16839,10 +16655,10 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "aOg" = ( -/obj/structure/closet/emcloset, /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/obj/structure/closet/firecloset, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "aOh" = ( @@ -17073,7 +16889,7 @@ "aOI" = ( /obj/structure/kitchenspike, /turf/open/floor/plasteel/showroomfloor, -/area/service/kitchen/coldroom) +/area/service/kitchen) "aOJ" = ( /obj/structure/chair/comfy/brown{ dir = 8 @@ -17095,14 +16911,18 @@ dir = 8 }, /turf/open/floor/plasteel/showroomfloor, -/area/service/kitchen/coldroom) +/area/service/kitchen) "aON" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = -24 + }, /turf/open/floor/plasteel/showroomfloor, -/area/service/kitchen/coldroom) +/area/service/kitchen) "aOO" = ( /obj/machinery/door/airlock{ name = "Bar Storage"; @@ -17139,7 +16959,7 @@ "aOT" = ( /obj/machinery/gibber, /turf/open/floor/plasteel/showroomfloor, -/area/service/kitchen/coldroom) +/area/service/kitchen) "aOU" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 @@ -17623,12 +17443,18 @@ /obj/machinery/light/small{ dir = 8 }, +/obj/structure/sign/painting/library{ + pixel_x = -32 + }, /turf/open/floor/wood, /area/service/library) "aQq" = ( /obj/machinery/light/small{ dir = 4 }, +/obj/structure/sign/painting/library{ + pixel_x = 32 + }, /turf/open/floor/wood, /area/service/library) "aQr" = ( @@ -18041,7 +17867,7 @@ /turf/open/floor/wood, /area/service/bar) "aRx" = ( -/obj/machinery/computer/arcade/minesweeper, +/obj/machinery/computer/arcade/orion_trail, /turf/open/floor/wood, /area/service/bar) "aRy" = ( @@ -18063,7 +17889,7 @@ /area/service/bar) "aRA" = ( /obj/machinery/vending/dinnerware{ - contraband = list(/obj/item/kitchen/rollingpin = 2, /obj/item/kitchen/knife/butcher = 2, /obj/item/reagent_containers/food/condiment/flour = 4) + contraband = list(/obj/item/kitchen/rollingpin=2,/obj/item/kitchen/knife/butcher=2,/obj/item/reagent_containers/food/condiment/flour=4) }, /turf/open/floor/plasteel/cafeteria, /area/service/kitchen) @@ -18876,6 +18702,7 @@ /obj/structure/table, /obj/item/storage/crayons, /obj/item/storage/crayons, +/obj/item/chisel, /turf/open/floor/plasteel, /area/commons/storage/art) "aTH" = ( @@ -20167,6 +19994,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, /turf/open/floor/plasteel, /area/command/bridge) "aWV" = ( @@ -20892,12 +20722,20 @@ /turf/closed/wall/r_wall, /area/ai_monitored/turret_protected/ai_upload) "aYy" = ( -/obj/machinery/status_display/ai, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/closed/wall/r_wall, -/area/ai_monitored/turret_protected/ai_upload) +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/status_display/ai{ + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/commons/dorms) "aYz" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 @@ -21579,6 +21417,9 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, +/obj/structure/sign/painting/library{ + pixel_x = -32 + }, /turf/open/floor/wood, /area/service/library) "bax" = ( @@ -21642,10 +21483,10 @@ /turf/open/floor/plasteel, /area/hallway/secondary/exit) "baF" = ( -/obj/structure/closet/emcloset, /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/structure/closet/firecloset, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "baG" = ( @@ -22142,6 +21983,7 @@ /obj/structure/table, /obj/item/aiModule/supplied/quarantine, /obj/machinery/camera/motion{ + c_tag = "AI Upload Chamber - West"; dir = 4; network = list("aiupload") }, @@ -22161,6 +22003,7 @@ pixel_x = 32 }, /obj/machinery/camera/motion{ + c_tag = "AI Upload Chamber - East"; dir = 8; network = list("aiupload") }, @@ -23095,6 +22938,10 @@ dir = 9 }, /obj/structure/closet/crate, +/obj/machinery/light_switch{ + pixel_x = 7; + pixel_y = -26 + }, /turf/open/floor/plasteel, /area/cargo/warehouse) "beE" = ( @@ -23116,6 +22963,9 @@ "beG" = ( /obj/machinery/door/firedoor, /obj/effect/turf_decal/tile/red, +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "beH" = ( @@ -23277,9 +23127,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "beY" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 - }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark, /area/medical/morgue) "beZ" = ( @@ -23401,12 +23249,11 @@ /turf/open/floor/plating, /area/maintenance/port) "bft" = ( -/obj/machinery/status_display/ai, -/obj/structure/cable{ - icon_state = "4-8" +/obj/machinery/status_display/ai{ + pixel_x = -32 }, -/turf/closed/wall/r_wall, -/area/ai_monitored/turret_protected/ai_upload) +/turf/open/floor/plasteel, +/area/commons/locker) "bfu" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 @@ -23476,13 +23323,18 @@ /turf/closed/wall, /area/medical/chemistry) "bfG" = ( -/obj/effect/spawner/structure/window, -/turf/open/floor/plating, -/area/medical/medbay/lobby) +/obj/machinery/cryopod{ + dir = 4 + }, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/carpet, +/area/commons/cryopod) "bfH" = ( /obj/structure/sign/departments/medbay/alt, /turf/closed/wall, -/area/medical/medbay/lobby) +/area/medical/medbay/central) "bfI" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 @@ -23614,8 +23466,12 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard) "bgc" = ( -/turf/closed/wall/r_wall, -/area/science/lab) +/obj/machinery/camera{ + c_tag = "Theatre - Stage"; + dir = 8 + }, +/turf/open/floor/carpet, +/area/service/theater) "bgd" = ( /obj/machinery/airalarm{ dir = 1; @@ -23646,8 +23502,8 @@ /turf/open/floor/plasteel, /area/hallway/secondary/exit) "bgg" = ( -/obj/structure/closet/emcloset, /obj/effect/turf_decal/stripes/line, +/obj/structure/closet/firecloset, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "bgh" = ( @@ -23883,7 +23739,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/area/medical/medbay/central) "bgX" = ( /obj/structure/table/wood, /obj/machinery/airalarm{ @@ -23950,7 +23806,7 @@ "bhe" = ( /obj/structure/chair, /turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/area/medical/medbay/central) "bhg" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -24024,9 +23880,6 @@ /turf/open/floor/plasteel, /area/security/checkpoint/medical) "bhm" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, /obj/machinery/power/apc{ areastring = "/area/medical/morgue"; dir = 1; @@ -24553,7 +24406,7 @@ dir = 1 }, /turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/area/medical/medbay/central) "biu" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/white, @@ -24625,9 +24478,12 @@ /turf/open/floor/plasteel/dark, /area/medical/paramedic) "biC" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/service/kitchen/coldroom) +/obj/machinery/light_switch{ + pixel_x = 7; + pixel_y = -26 + }, +/turf/open/floor/mineral/titanium/blue, +/area/commons/toilet) "biD" = ( /obj/machinery/portable_atmospherics/canister/air, /turf/open/floor/plating, @@ -24741,6 +24597,9 @@ /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/machinery/posialert{ + pixel_x = 32 + }, /turf/open/floor/plasteel/white, /area/science/robotics/lab) "biQ" = ( @@ -25189,14 +25048,14 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/area/medical/medbay/central) "bjU" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, /obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/area/medical/medbay/central) "bjV" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -25206,7 +25065,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/area/medical/medbay/central) "bjX" = ( /obj/structure/table, /obj/machinery/recharger{ @@ -25292,11 +25151,11 @@ /turf/open/floor/plasteel/white, /area/science/research) "bkj" = ( -/obj/structure/closet/emcloset, /obj/machinery/airalarm{ pixel_y = 24 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/closet/firecloset, /turf/open/floor/plasteel, /area/cargo/storage) "bkk" = ( @@ -25750,7 +25609,7 @@ dir = 4 }, /turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/area/medical/medbay/central) "bll" = ( /obj/structure/table/reinforced, /obj/item/folder/white, @@ -26022,6 +25881,7 @@ /obj/machinery/light/small{ dir = 1 }, +/obj/structure/loot_pile/maint, /turf/open/floor/plating, /area/maintenance/starboard/aft) "blR" = ( @@ -26366,7 +26226,7 @@ pixel_x = -24 }, /turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/area/medical/medbay/central) "bmK" = ( /obj/structure/table/reinforced, /turf/open/floor/plasteel/white, @@ -27181,6 +27041,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/status_display/ai{ + pixel_x = -32 + }, /turf/open/floor/plasteel/white, /area/science/research) "boB" = ( @@ -28610,6 +28473,9 @@ icon_state = "2-8" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/status_display/ai{ + pixel_x = 32 + }, /turf/open/floor/plasteel, /area/command/heads_quarters/hop) "bsa" = ( @@ -29232,9 +29098,6 @@ /turf/open/floor/plasteel/white, /area/science) "btB" = ( -/obj/machinery/computer/bounty{ - dir = 4 - }, /obj/effect/turf_decal/tile/blue{ dir = 1 }, @@ -29977,7 +29840,7 @@ /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/area/medical/medbay/central) "bvl" = ( /obj/machinery/door/airlock/medical/glass{ name = "Surgery Observation" @@ -30154,9 +30017,6 @@ departmentType = 2; pixel_x = -30 }, -/obj/machinery/computer/bounty{ - dir = 4 - }, /obj/effect/turf_decal/tile/brown{ dir = 1 }, @@ -30169,6 +30029,9 @@ /obj/machinery/keycard_auth{ pixel_y = 25 }, +/obj/machinery/computer/bounty{ + dir = 4 + }, /turf/open/floor/plasteel, /area/cargo/qm) "bvG" = ( @@ -31992,6 +31855,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 6 }, +/obj/machinery/status_display/ai{ + pixel_x = 32 + }, /turf/open/floor/plasteel/white, /area/command/heads_quarters/rd) "bzO" = ( @@ -32225,14 +32091,12 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "bAq" = ( -/obj/machinery/sleeper{ - dir = 8 - }, /obj/machinery/camera{ c_tag = "Medbay Treatment Center"; dir = 8; network = list("ss13","medbay") }, +/obj/machinery/stasis, /turf/open/floor/plasteel, /area/medical/medbay/central) "bAr" = ( @@ -33159,6 +33023,9 @@ pixel_x = 1; pixel_y = 9 }, +/obj/machinery/status_display/ai{ + pixel_x = -32 + }, /turf/open/floor/plasteel, /area/cargo/miningdock) "bCp" = ( @@ -33475,11 +33342,7 @@ /turf/open/floor/engine, /area/science/storage) "bDg" = ( -/obj/structure/rack, -/obj/effect/spawner/lootdrop/maintenance{ - lootcount = 3; - name = "3maintenance loot spawner" - }, +/obj/structure/loot_pile/maint, /turf/open/floor/plating, /area/maintenance/starboard) "bDh" = ( @@ -35294,6 +35157,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, /area/maintenance/aft) "bHp" = ( @@ -41516,10 +41380,6 @@ "bXs" = ( /turf/open/floor/plasteel/white, /area/science/circuit) -"bXv" = ( -/obj/item/stack/rods, -/turf/open/space, -/area/space) "bXw" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel, @@ -42169,7 +42029,8 @@ /area/maintenance/port/aft) "bZm" = ( /obj/structure/disposaloutlet{ - dir = 8 + dir = 8; + name = "Prisoner Outlet" }, /obj/structure/disposalpipe/trunk{ dir = 4 @@ -43065,7 +42926,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) "cbr" = ( @@ -44782,6 +44643,10 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 }, +/obj/machinery/camera{ + c_tag = "Atmospherics - Incinerator"; + name = "atmospherics camera" + }, /turf/open/floor/plasteel, /area/maintenance/disposal/incinerator) "cga" = ( @@ -45059,7 +44924,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/command) +/area/command/heads_quarters/ce) "cgQ" = ( /obj/machinery/camera{ c_tag = "Engineering East"; @@ -46956,6 +46821,9 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/status_display/ai{ + pixel_y = 32 + }, /turf/open/floor/plasteel, /area/engineering/main) "clN" = ( @@ -47068,8 +46936,7 @@ /turf/open/floor/plating, /area/maintenance/aft) "cmo" = ( -/obj/structure/rack, -/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/loot_pile/maint, /turf/open/floor/plating, /area/maintenance/starboard/aft) "cmq" = ( @@ -47742,7 +47609,7 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/machinery/air_sensor{ +/obj/machinery/air_sensor/atmos/incinerator_tank{ pixel_x = -32; pixel_y = -32 }, @@ -50585,6 +50452,12 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/plasteel, /area/hallway/secondary/exit) +"czP" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/wall, +/area/security/prison/cells) "czQ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/disposalpipe/segment, @@ -51133,6 +51006,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/loot_pile/maint, /turf/open/floor/plating, /area/maintenance/aft) "cBE" = ( @@ -51302,6 +51176,20 @@ /obj/machinery/deepfryer, /turf/open/floor/plasteel/cafeteria, /area/service/kitchen) +"cCr" = ( +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "cCs" = ( /obj/structure/closet/emcloset, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -51826,6 +51714,22 @@ /obj/structure/sign/poster/official/cohiba_robusto_ad, /turf/closed/wall, /area/service/lawoffice) +"cJA" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "cJW" = ( /obj/machinery/computer/gateway_control, /turf/open/floor/plasteel, @@ -51882,6 +51786,24 @@ "cNd" = ( /turf/open/space/basic, /area/space/station_ruins) +"cNi" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "Prison Gate"; + name = "prison blast door" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Prison Lockdown Shutters" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "cNE" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall, @@ -52042,13 +51964,13 @@ /obj/structure/sign/warning/securearea{ pixel_x = -32 }, -/obj/machinery/door/poddoor/preopen{ - id = "Prison Gate"; - name = "prison blast door" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Prison Lockdown Shutters" + }, +/turf/open/floor/plasteel/dark, /area/security/prison) "cPb" = ( /turf/open/floor/wood/wood_diagonal, @@ -52077,6 +51999,13 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"cPO" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/port/fore) "cQw" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -52112,6 +52041,23 @@ /obj/item/folder/blue, /turf/open/floor/plasteel/dark, /area/hallway/primary/central) +"cRq" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"cSp" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall, +/area/security/prison/upper) "cSA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -52379,6 +52325,13 @@ }, /turf/open/floor/plasteel, /area/engineering/main) +"cTo" = ( +/obj/structure/table/wood, +/obj/item/storage/dice, +/obj/item/instrument/piano_synth, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "cTD" = ( /obj/structure/cable{ icon_state = "1-2" @@ -52508,6 +52461,13 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"cVE" = ( +/obj/machinery/computer/cryopod{ + pixel_y = 26 + }, +/obj/effect/turf_decal/loading_area, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "cVK" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plasteel/white, @@ -52519,6 +52479,16 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/fore) +"cYf" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "cZe" = ( /obj/structure/cable{ icon_state = "4-8" @@ -52546,7 +52516,6 @@ /turf/open/floor/plasteel, /area/engineering/atmos) "dbb" = ( -/obj/structure/lattice, /obj/machinery/atmospherics/components/unary/relief_valve/atmos/atmos_waste{ dir = 1 }, @@ -52582,6 +52551,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, +/obj/machinery/light_switch{ + pixel_y = 24 + }, /turf/open/floor/plasteel/freezer, /area/commons/toilet/locker) "ddI" = ( @@ -52703,6 +52675,16 @@ }, /turf/open/floor/plasteel/dark, /area/medical/paramedic) +"dnX" = ( +/obj/effect/turf_decal/stripes/white/line, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "dqb" = ( /turf/open/floor/plasteel, /area/commons/fitness/pool) @@ -52749,6 +52731,17 @@ }, /turf/closed/wall, /area/science/circuit) +"dxv" = ( +/obj/machinery/camera{ + c_tag = "Prison Cafeteria"; + dir = 8; + network = list("ss13","prison") + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "dxF" = ( /obj/machinery/gear_painter, /turf/open/floor/wood, @@ -52781,24 +52774,28 @@ /turf/open/floor/plating, /area/security/brig) "dyS" = ( -/obj/effect/turf_decal/tile/green{ - dir = 8 +/obj/machinery/door/airlock/public/glass{ + name = "Prison Cafeteria" }, -/obj/effect/turf_decal/tile/green{ - dir = 1 - }, -/obj/effect/turf_decal/tile/green, -/obj/effect/turf_decal/tile/green{ +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel, -/area/security/prison) +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "dzi" = ( /obj/structure/cable{ icon_state = "2-4" }, /turf/open/floor/carpet, /area/commons/cryopod) +"dzK" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "dAe" = ( /obj/machinery/atmospherics/pipe/manifold/cyan/visible{ dir = 1 @@ -52806,6 +52803,11 @@ /obj/machinery/meter, /turf/open/floor/plasteel, /area/engineering/atmos) +"dCd" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/drinks/drinkingglass, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "dCr" = ( /obj/structure/pool/Rboard, /turf/open/floor/plasteel/yellowsiding{ @@ -52850,12 +52852,43 @@ icon_state = "platingdmg3" }, /area/commons/arcade) +"dGh" = ( +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/delivery, +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, +/turf/open/floor/plasteel, +/area/medical/medbay/central) "dIu" = ( /obj/structure/chair/sofa{ dir = 8 }, /turf/open/floor/plating, /area/maintenance/port/fore) +"dIZ" = ( +/turf/open/floor/padded, +/area/security/execution/transfer) +"dJu" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/decal/cleanable/blood/old, +/obj/machinery/button/door{ + id = "permacells3"; + name = "Privacy Shutters"; + pixel_x = 25 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "dJL" = ( /obj/structure/cable{ icon_state = "1-2" @@ -52875,6 +52908,28 @@ /obj/structure/chair/stool/bar, /turf/open/floor/wood, /area/maintenance/bar) +"dLi" = ( +/obj/machinery/hydroponics/soil, +/obj/item/cultivator, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"dLl" = ( +/obj/item/stack/rods, +/turf/open/space, +/area/space) +"dLZ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "dMj" = ( /obj/machinery/space_heater, /obj/effect/turf_decal/stripes/line{ @@ -52888,6 +52943,12 @@ }, /turf/open/floor/plasteel/white, /area/science/circuit) +"dNP" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "dPk" = ( /obj/structure/closet{ name = "Costume Closet" @@ -52912,8 +52973,39 @@ /obj/machinery/light/small{ dir = 4 }, +/obj/structure/loot_pile/maint, /turf/open/floor/plating, /area/maintenance/fore) +"dPs" = ( +/obj/machinery/hydroponics/soil, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"dPE" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "dQD" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 8; @@ -52921,6 +53013,26 @@ }, /turf/open/floor/plasteel, /area/maintenance/disposal/incinerator) +"dQS" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"dSh" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "dTI" = ( /obj/structure/urinal{ pixel_y = 32 @@ -52945,6 +53057,27 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/command/gateway) +"dYQ" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/effect/decal/cleanable/blood/old, +/obj/machinery/button/electrochromatic{ + id = "!permabrigshowers"; + pixel_x = -25 + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison/cells) "dYZ" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -52969,6 +53102,13 @@ }, /turf/open/space, /area/solars/starboard/fore) +"ebo" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "ecg" = ( /turf/open/floor/plasteel/yellowsiding/corner{ dir = 4 @@ -52981,6 +53121,10 @@ }, /turf/open/floor/plasteel/dark, /area/medical/morgue) +"ecB" = ( +/obj/item/toy/beach_ball/holoball, +/turf/open/floor/plasteel, +/area/security/prison/upper) "edj" = ( /obj/structure/sign/poster/contraband/random{ pixel_y = 32 @@ -52999,6 +53143,17 @@ }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) +"efs" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/security/prison/upper) "efO" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -53044,6 +53199,26 @@ }, /turf/open/floor/plasteel, /area/engineering/atmos) +"ejr" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/grunge{ + name = "Permanent Cell 4"; + wiretypepath = /datum/wires/airlock/security + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "eky" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/baguette, @@ -53062,6 +53237,17 @@ }, /turf/open/floor/wood, /area/service/bar) +"emf" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Permabrig Maintenance"; + req_access_txt = "1" + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/maintenance/prison/starboard) "ene" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -53087,6 +53273,48 @@ /obj/structure/table/wood/poker, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"eoJ" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/grunge{ + name = "Permanent Cell 5"; + wiretypepath = /datum/wires/airlock/security + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) +"eoR" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"epj" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "epD" = ( /obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, /obj/machinery/light{ @@ -53098,21 +53326,27 @@ }, /turf/open/floor/plasteel, /area/commons/fitness) -"eqd" = ( -/obj/item/electropack/shockcollar, -/obj/item/assembly/signaler, -/turf/open/floor/plating, -/area/security/prison) +"epG" = ( +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -24 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "eqq" = ( /obj/machinery/atmospherics/pipe/manifold/orange/visible, /turf/open/floor/plasteel, /area/engineering/atmos) "eqA" = ( -/obj/machinery/shower{ - dir = 8 +/obj/structure/cable{ + icon_state = "1-2" }, -/turf/open/floor/plasteel/freezer, -/area/security/prison) +/obj/machinery/firealarm{ + dir = 8; + pixel_x = 24 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "esK" = ( /obj/machinery/door/airlock/maintenance/abandoned{ name = "Chemical Storage"; @@ -53144,6 +53378,17 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/wood, /area/service/library) +"etr" = ( +/obj/structure/chair/stool, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "eus" = ( /obj/machinery/portable_atmospherics/scrubber, /obj/effect/turf_decal/stripes/line{ @@ -53151,6 +53396,40 @@ }, /turf/open/floor/plasteel, /area/engineering/atmos) +"evc" = ( +/obj/machinery/hydroponics/soil, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/camera{ + c_tag = "Prison Forestry"; + dir = 4; + network = list("ss13","prison") + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"evh" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/camera{ + c_tag = "Prison Workshop"; + dir = 4; + network = list("ss13","prison") + }, +/obj/item/stack/sticky_tape, +/obj/item/stack/sheet/cardboard{ + amount = 14 + }, +/obj/item/stack/packageWrap, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "evR" = ( /turf/open/floor/plating, /area/maintenance/bar) @@ -53165,6 +53444,17 @@ }, /turf/open/floor/plating, /area/commons/fitness) +"ewG" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "permacells5"; + name = "Privacy Shutters" + }, +/turf/open/floor/plating, +/area/security/prison/cells) "ewN" = ( /obj/machinery/hydroponics/soil{ pixel_y = 8 @@ -53273,6 +53563,16 @@ /obj/item/clothing/under/rank/civilian/lawyer/red, /turf/open/floor/plasteel, /area/commons/fitness) +"eCB" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "eCR" = ( /obj/structure/lattice, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -53280,6 +53580,19 @@ }, /turf/closed/wall/r_wall, /area/engineering/gravity_generator) +"eDf" = ( +/obj/structure/window/reinforced/tinted{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "eDz" = ( /obj/structure/cable/white{ icon_state = "2-8" @@ -53288,6 +53601,37 @@ icon_state = "panelscorched" }, /area/maintenance/starboard/aft) +"eDF" = ( +/obj/effect/landmark/event_spawn, +/obj/structure/chair/comfy/brown{ + color = "#596479"; + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"eDJ" = ( +/obj/machinery/firealarm{ + dir = 4; + pixel_x = -24 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "eFx" = ( /obj/effect/turf_decal/tile/red{ dir = 1 @@ -53324,6 +53668,14 @@ /obj/effect/spawner/structure/window/shuttle, /turf/open/floor/plating/airless, /area/space/nearstation) +"eIW" = ( +/obj/structure/table, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "eJa" = ( /obj/structure/table/wood/poker, /obj/item/toy/cards/deck{ @@ -53334,6 +53686,22 @@ }, /turf/open/floor/wood, /area/service/bar) +"eJu" = ( +/obj/machinery/button/door{ + id = "executionspaceblast"; + name = "Vent to Space"; + pixel_x = 25; + pixel_y = -5; + req_access_txt = "7" + }, +/obj/machinery/button/flasher{ + id = "executionflash"; + pixel_x = 24; + pixel_y = 5 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "eMs" = ( /obj/structure/rack, /obj/effect/spawner/lootdrop/maintenance{ @@ -53355,18 +53723,70 @@ /turf/open/floor/carpet, /area/commons/dorms) "eRr" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/obj/machinery/light_switch{ + pixel_x = -10; + pixel_y = 26 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main) "eRz" = ( /obj/structure/lattice, /obj/structure/grille, /turf/open/space/basic, /area/space/nearstation) +"eRS" = ( +/obj/structure/table, +/obj/item/folder/red{ + pixel_x = 3 + }, +/obj/item/taperecorder{ + pixel_x = -3 + }, +/obj/item/assembly/flash/handheld, +/obj/item/reagent_containers/spray/pepper, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "eSe" = ( /obj/structure/closet/secure_closet/personal/cabinet, /turf/open/floor/carpet, /area/commons/dorms) +"eSJ" = ( +/obj/machinery/button/ignition{ + id = "executionburn"; + pixel_x = 24; + pixel_y = 5 + }, +/obj/machinery/button/door{ + id = "executionfireblast"; + name = "Transfer Area Lockdown"; + pixel_x = 25; + pixel_y = -5; + req_access_txt = "2" + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"eTt" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/lattice/catwalk, +/turf/open/space, +/area/solars/port/fore) "eTA" = ( /obj/structure/table/wood/fancy, /obj/item/reagent_containers/food/condiment/saltshaker{ @@ -53421,15 +53841,21 @@ }, /turf/open/floor/plasteel, /area/cargo/miningdock) +"eVW" = ( +/obj/machinery/status_display/ai{ + pixel_x = -32 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) "eWL" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/poddoor/preopen{ - id = "Prison Gate"; - name = "prison blast door" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Prison Lockdown Shutters" + }, +/turf/open/floor/plasteel/dark, /area/security/prison) "eXz" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ @@ -53437,6 +53863,15 @@ }, /turf/open/floor/plasteel, /area/security/processing) +"eXI" = ( +/obj/structure/chair{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "eXL" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ dir = 10 @@ -53448,11 +53883,62 @@ /obj/effect/landmark/start/paramedic, /turf/open/floor/plasteel/white, /area/medical/medbay/central) +"eZI" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 10 + }, +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"eZS" = ( +/obj/effect/turf_decal/bot_white, +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/plating, +/area/maintenance/prison/starboard) "fbp" = ( /obj/structure/tank_dispenser, /obj/effect/turf_decal/bot, /turf/open/floor/engine, /area/science/storage) +"fbr" = ( +/obj/machinery/door/window/southleft{ + base_state = "right"; + dir = 4; + icon_state = "right"; + name = "Transfer Chamber Configuration"; + req_access_txt = "2" + }, +/obj/machinery/atmospherics/pipe/simple{ + dir = 10 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/security/execution/transfer) +"fbY" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/bed, +/obj/item/bedsheet/red, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "fcd" = ( /obj/structure/chair/sofa/right{ dir = 8 @@ -53461,6 +53947,11 @@ icon_state = "platingdmg1" }, /area/maintenance/port/fore) +"fcj" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plating, +/area/maintenance/prison/starboard) "fcn" = ( /obj/structure/disposalpipe/segment, /obj/machinery/door/airlock/maintenance{ @@ -53478,11 +53969,61 @@ }, /turf/closed/wall/r_wall, /area/science/mixing) +"fdJ" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "fdQ" = ( /obj/structure/bed, /obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/plating, /area/maintenance/fore) +"fdR" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/power/apc{ + areastring = "/area/security/prison/cells"; + damage_deflection = 21; + desc = "A control terminal for the area's electrical systems. It's secured with a durable antitampering plasteel cage."; + dir = 4; + name = "Armored Prison Wing Cells APC"; + pixel_x = 24 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"fdS" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light{ + dir = 1; + light_color = "#cee5d2" + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "feE" = ( /obj/structure/cable{ icon_state = "1-2" @@ -53501,8 +54042,29 @@ "fgl" = ( /obj/structure/closet/crate/bin, /obj/item/coin/silver, +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 23 + }, /turf/open/floor/carpet/arcade, /area/commons/arcade) +"fgy" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/landmark/start/prisoner, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "fhu" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -53526,6 +54088,26 @@ }, /turf/closed/wall, /area/maintenance/disposal/incinerator) +"fiR" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "fjS" = ( /obj/structure/closet/radiation, /turf/open/floor/plasteel, @@ -53586,6 +54168,19 @@ }, /turf/open/floor/wood/wood_diagonal, /area/maintenance/port/fore) +"fmR" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "fnC" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 @@ -53711,6 +54306,10 @@ dir = 8; pixel_x = 24 }, +/obj/machinery/light_switch{ + pixel_x = -7; + pixel_y = -24 + }, /turf/open/floor/plasteel, /area/security/range) "fsQ" = ( @@ -53824,6 +54423,12 @@ /obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel, /area/service/hydroponics) +"fzx" = ( +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, +/turf/open/floor/wood, +/area/service/bar) "fAj" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -53877,6 +54482,10 @@ }, /turf/open/floor/carpet/arcade, /area/commons/arcade) +"fCV" = ( +/obj/machinery/piratepad/civilian, +/turf/open/floor/plasteel, +/area/cargo/office) "fDn" = ( /obj/structure/table, /obj/item/trash/chips{ @@ -53915,6 +54524,12 @@ }, /turf/open/floor/plasteel, /area/service/hydroponics) +"fFR" = ( +/obj/structure/chair{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison) "fGf" = ( /obj/machinery/smartfridge/disks{ pixel_y = 2 @@ -53958,6 +54573,17 @@ /obj/effect/landmark/start/atmospheric_technician, /turf/open/floor/plasteel, /area/engineering/atmos) +"fKN" = ( +/obj/structure/table, +/obj/structure/bedsheetbin, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "fLN" = ( /obj/machinery/chem_dispenser/drinks/beer{ dir = 1 @@ -53969,6 +54595,49 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark, /area/security/courtroom) +"fMF" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/airlock/grunge{ + name = "Prison Laundry"; + wiretypepath = /datum/wires/airlock/security + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) +"fMY" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"fNB" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced/tinted/electrochromatic{ + electrochromatic_id = "!permabrigshowers" + }, +/turf/open/floor/plating, +/area/security/prison/cells) "fNN" = ( /obj/machinery/door/firedoor, /obj/structure/cable{ @@ -54051,6 +54720,7 @@ /obj/structure/sign/poster/contraband/robust_softdrinks{ pixel_y = 32 }, +/obj/machinery/vending/snack/orange, /turf/open/floor/wood, /area/service/bar) "fZm" = ( @@ -54113,11 +54783,6 @@ }, /turf/open/floor/plating, /area/construction) -"gbu" = ( -/obj/structure/bed, -/obj/effect/spawner/lootdrop/bedsheet, -/turf/open/floor/plating, -/area/security/prison) "gbT" = ( /obj/item/storage/box/lights/mixed, /obj/machinery/power/apc{ @@ -54131,6 +54796,13 @@ }, /turf/open/floor/plating, /area/maintenance/department/medical/morgue) +"gcm" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "gcx" = ( /obj/structure/chair/stool{ pixel_y = 8 @@ -54149,6 +54821,38 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/fore) +"gcV" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"gcX" = ( +/obj/structure/table, +/obj/item/flashlight/lamp, +/obj/item/stack/sheet/metal, +/obj/item/storage/box/bodybags, +/obj/item/pen, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"gcY" = ( +/obj/structure/weightmachine/weightlifter, +/turf/open/floor/plasteel, +/area/security/prison/upper) "geg" = ( /obj/machinery/light/small{ dir = 8 @@ -54158,6 +54862,16 @@ /obj/item/reagent_containers/food/snacks/egg/yellow, /turf/open/floor/plating, /area/maintenance/port/fore) +"gfw" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "gfC" = ( /obj/effect/turf_decal/tile/red, /obj/structure/chair{ @@ -54180,6 +54894,18 @@ }, /turf/open/floor/plasteel/white, /area/medical/surgery) +"ggT" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/cells) "ghD" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, @@ -54187,6 +54913,28 @@ "giy" = ( /turf/open/floor/carpet/arcade, /area/commons/arcade) +"giE" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/landmark/start/prisoner, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/button/door{ + id = "permacells4"; + name = "Privacy Shutters"; + pixel_y = 25 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "giT" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -54201,6 +54949,15 @@ "gjl" = ( /turf/closed/wall, /area/cargo/warehouse) +"gkP" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/computer/bounty{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/cargo/office) "gnf" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -54217,6 +54974,13 @@ /obj/item/poster/random_contraband, /turf/open/floor/plasteel, /area/commons/locker) +"goJ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "gpD" = ( /obj/effect/turf_decal/bot_white/left, /obj/effect/turf_decal/tile/neutral{ @@ -54242,6 +55006,10 @@ }, /turf/open/floor/plating, /area/maintenance/fore/secondary) +"grd" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall, +/area/security/prison/upper) "grr" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 @@ -54258,6 +55026,12 @@ }, /turf/open/floor/plasteel/dark, /area/commons/fitness) +"grS" = ( +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai_upload) "gsM" = ( /obj/structure/table, /obj/effect/spawner/lootdrop/maintenance, @@ -54287,10 +55061,34 @@ /obj/machinery/meter, /turf/closed/wall/r_wall, /area/engineering/atmos) +"gxK" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "permacells3"; + name = "Privacy Shutters" + }, +/turf/open/floor/plating, +/area/security/prison/cells) "gyr" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/security/brig) +"gyy" = ( +/obj/machinery/door/airlock/security{ + aiControlDisabled = 1; + name = "Isolation Cell"; + req_access_txt = "2" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "gyQ" = ( /turf/open/floor/plasteel/freezer, /area/commons/toilet) @@ -54336,16 +55134,16 @@ /turf/open/floor/plasteel/dark, /area/command/gateway) "gDP" = ( -/obj/machinery/firealarm{ - dir = 8; - pixel_x = 28 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, /obj/item/radio/intercom{ pixel_y = 20 }, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = 24 + }, /turf/open/floor/plasteel, /area/security/processing) "gDZ" = ( @@ -54412,6 +55210,15 @@ /obj/structure/bedsheetbin/towel, /turf/open/floor/wood/wood_diagonal, /area/maintenance/port/fore) +"gLu" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "gLw" = ( /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -54424,6 +55231,10 @@ }, /obj/effect/turf_decal/tile/red, /obj/effect/landmark/start/clown, +/obj/machinery/camera{ + c_tag = "Theatre - Backstage"; + dir = 1 + }, /turf/open/floor/plasteel, /area/service/theater) "gLz" = ( @@ -54453,6 +55264,26 @@ }, /turf/open/floor/wood, /area/maintenance/bar) +"gMB" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/grunge{ + name = "Permanent Cell 6"; + wiretypepath = /datum/wires/airlock/security + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "gMD" = ( /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 6 @@ -54477,15 +55308,15 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, +/obj/structure/sign/poster/official/high_class_martini{ + pixel_x = -32 + }, /mob/living/simple_animal/bot/mulebot{ beacon_freq = 1400; home_destination = "QM #1"; name = "Massive Load"; suffix = "#1" }, -/obj/structure/sign/poster/official/high_class_martini{ - pixel_x = -32 - }, /turf/open/floor/carpet/royalblue, /area/maintenance/starboard/aft) "gOZ" = ( @@ -54494,6 +55325,13 @@ }, /turf/open/floor/plating, /area/commons/fitness) +"gPY" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "gQr" = ( /obj/machinery/atmospherics/components/binary/valve/digital{ name = "gas to sauna" @@ -54511,6 +55349,24 @@ }, /turf/open/floor/carpet, /area/service/library) +"gSj" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/airlock/grunge{ + name = "Permanent Cell 3"; + wiretypepath = /datum/wires/airlock/security + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "gTx" = ( /obj/effect/turf_decal/bot_white/left, /obj/effect/turf_decal/tile/neutral{ @@ -54532,19 +55388,34 @@ }, /turf/closed/wall/r_wall, /area/engineering/gravity_generator) +"gVc" = ( +/obj/machinery/vending/sustenance, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "gWd" = ( /obj/structure/cable{ icon_state = "1-4" }, /turf/open/floor/plating, /area/construction) -"gWo" = ( -/turf/closed/wall, -/area/security/range) "gXs" = ( /obj/structure/lattice, /turf/open/space/basic, /area/space/nearstation) +"gXu" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "gYo" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -54576,6 +55447,18 @@ dir = 8 }, /area/medical/surgery) +"gZT" = ( +/obj/machinery/power/apc{ + areastring = "/area/maintenance/prison/port"; + dir = 8; + name = "Prison Port Maintenance APC"; + pixel_x = -25 + }, +/obj/effect/turf_decal/bot, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/turf/open/floor/plating, +/area/maintenance/prison/port) "haM" = ( /obj/item/radio/intercom{ name = "Station Intercom (General)"; @@ -54607,6 +55490,21 @@ icon_state = "platingdmg1" }, /area/maintenance/starboard/aft) +"hch" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "hcA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -54617,6 +55515,19 @@ /obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel, /area/commons/fitness) +"hcT" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/lattice/catwalk, +/turf/open/space, +/area/solars/port/fore) "hgG" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/structure/extinguisher_cabinet{ @@ -54653,6 +55564,26 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"hkA" = ( +/obj/structure/table, +/obj/item/clothing/under/rank/prisoner/skirt{ + pixel_x = -13; + pixel_y = 5 + }, +/obj/item/clothing/under/rank/prisoner/skirt{ + pixel_x = 9; + pixel_y = 5 + }, +/obj/item/clothing/under/rank/prisoner{ + pixel_x = -2; + pixel_y = 5 + }, +/obj/machinery/flasher{ + id = "waitingflash"; + pixel_y = -28 + }, +/turf/open/floor/plasteel, +/area/security/prison) "hlS" = ( /obj/structure/cable{ icon_state = "1-2" @@ -54677,12 +55608,28 @@ }, /turf/closed/wall, /area/commons/dorms) +"hmT" = ( +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/port) "hnc" = ( /obj/structure/chair/pew/left{ dir = 4 }, /turf/open/floor/wood/wood_diagonal, /area/maintenance/port/fore) +"hnp" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "hnU" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -54718,6 +55665,16 @@ }, /turf/open/floor/plasteel/dark, /area/command/gateway) +"hpY" = ( +/obj/machinery/vr_sleeper{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "hrF" = ( /obj/structure/lattice/catwalk, /obj/structure/cable{ @@ -54750,11 +55707,52 @@ }, /turf/open/floor/plating, /area/command/gateway) +"hvC" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) +"hvJ" = ( +/obj/item/toy/plush/beeplushie, +/turf/open/floor/padded, +/area/security/execution/transfer) +"hxg" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "hxn" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plating, /area/engineering/atmos) +"hyY" = ( +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) +"hzs" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/plate_press, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"hzC" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "hzK" = ( /turf/open/floor/plasteel/yellowsiding/corner{ dir = 1 @@ -54777,6 +55775,13 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/port/fore) +"hEL" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/security/execution/transfer) "hGH" = ( /obj/machinery/door/airlock{ desc = "Private study room where nerds are probably playing Dungeons and Dragons 13e, or a place for blood cult rituals."; @@ -54793,6 +55798,12 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/starboard/fore) +"hIi" = ( +/obj/structure/sign/painting/library{ + pixel_x = -32 + }, +/turf/open/floor/wood, +/area/service/library) "hIL" = ( /obj/structure/sign/poster/contraband/space_up{ pixel_x = -32; @@ -54807,6 +55818,33 @@ /obj/machinery/door/firedoor, /turf/open/floor/plasteel/dark, /area/hallway/primary/central) +"hJO" = ( +/obj/structure/closet/crate/trashcart, +/obj/effect/spawner/lootdrop/prison_contraband, +/obj/item/trash/chips, +/obj/item/trash/candy, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/security/prison/upper) +"hJP" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/machinery/portable_atmospherics/canister/nitrous_oxide, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1 + }, +/turf/open/floor/plating, +/area/security/execution/transfer) +"hKo" = ( +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/effect/spawner/structure/window/reinforced/tinted/electrochromatic{ + electrochromatic_id = "!permabrigshowers" + }, +/turf/open/floor/plating, +/area/security/prison/cells) "hMs" = ( /obj/structure/table, /obj/item/storage/box/bodybags, @@ -54837,6 +55875,12 @@ }, /turf/closed/wall, /area/cargo/warehouse) +"hQw" = ( +/obj/item/electropack/shockcollar, +/obj/item/assembly/signaler, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/maintenance/prison/port) "hQX" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -54873,6 +55917,11 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plating, /area/service/abandoned_gambling_den) +"hSf" = ( +/obj/structure/cable, +/obj/structure/lattice/catwalk, +/turf/open/space, +/area/solars/port/fore) "hSl" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -54911,18 +55960,44 @@ }, /turf/open/floor/plasteel, /area/commons/fitness) +"hWm" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/light/small, +/obj/machinery/button/door{ + id = "permacells3"; + name = "Privacy Shutters"; + pixel_y = -25 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "hYd" = ( /obj/machinery/door/airlock/medical{ name = "Morgue"; req_access_txt = "6" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark, /area/medical/morgue) "ibK" = ( /turf/open/floor/plasteel, /area/security/processing) +"icS" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/grille, +/turf/open/floor/plating, +/area/maintenance/prison/port) "idK" = ( /obj/effect/turf_decal/tile/red{ dir = 1 @@ -54947,9 +56022,22 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"ifM" = ( +/obj/machinery/shower{ + dir = 8; + pixel_y = -4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison/cells) "ihR" = ( -/turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/obj/machinery/airalarm{ + pixel_y = 24 + }, +/turf/open/floor/plasteel, +/area/cargo/warehouse) "ihS" = ( /obj/effect/landmark/event_spawn, /obj/effect/turf_decal/tile/blue{ @@ -54995,6 +56083,18 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) +"ikv" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/security/prison) "iky" = ( /obj/effect/turf_decal/weather/dirt, /obj/effect/decal/cleanable/dirt, @@ -55003,6 +56103,24 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"ili" = ( +/obj/structure/table, +/obj/item/electropack, +/obj/item/screwdriver, +/obj/item/wrench, +/obj/item/clothing/head/helmet, +/obj/item/assembly/signaler, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/machinery/light_switch{ + pixel_y = 23 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "imk" = ( /obj/structure/lattice, /obj/machinery/atmospherics/pipe/simple/orange/visible{ @@ -55050,6 +56168,21 @@ }, /turf/open/floor/plasteel, /area/commons/fitness/pool) +"iqi" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/camera{ + c_tag = "Prison Laundry"; + dir = 4; + network = list("ss13","prison") + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "iql" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -55111,6 +56244,15 @@ /obj/structure/table/optable, /turf/open/floor/plasteel/white, /area/medical/surgery) +"iwU" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "iyG" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small{ @@ -55120,6 +56262,19 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"iyK" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "QMLoad" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, +/turf/open/floor/plating, +/area/cargo/storage) "izg" = ( /obj/item/cigbutt/cigarbutt, /turf/open/floor/plating, @@ -55131,12 +56286,34 @@ }, /turf/open/floor/wood, /area/maintenance/bar) +"iBj" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/grille, +/turf/open/floor/plating, +/area/maintenance/prison/starboard) +"iBq" = ( +/obj/machinery/portable_atmospherics/canister/air, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/maintenance/prison/starboard) "iBv" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, /turf/open/floor/plasteel, /area/commons/fitness/pool) +"iCN" = ( +/obj/machinery/door/airlock{ + name = "Permabrig Showers" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "iDo" = ( /obj/structure/grille, /turf/open/space/basic, @@ -55213,6 +56390,14 @@ }, /turf/open/floor/plasteel, /area/commons/fitness/pool) +"iMy" = ( +/obj/structure/chair/sofa/right, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "iNn" = ( /obj/machinery/camera{ c_tag = "Kitchen Cold Room" @@ -55220,7 +56405,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/reagent_dispensers/cooking_oil, /turf/open/floor/plasteel/showroomfloor, -/area/service/kitchen/coldroom) +/area/service/kitchen) "iPX" = ( /obj/structure/table, /obj/machinery/reagentgrinder{ @@ -55423,6 +56608,10 @@ pixel_y = -28 }, /obj/effect/landmark/start/paramedic, +/obj/machinery/light_switch{ + pixel_x = -26; + pixel_y = -26 + }, /turf/open/floor/plasteel/dark, /area/medical/paramedic) "jex" = ( @@ -55450,6 +56639,10 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, /area/command/heads_quarters/captain) +"jge" = ( +/obj/structure/grille, +/turf/open/floor/plating, +/area/space/nearstation) "jgm" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -55475,14 +56668,18 @@ /turf/closed/wall, /area/engineering/main) "jiT" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) -"jjC" = ( -/obj/structure/table/wood, -/obj/item/toy/cards/deck, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/light_switch{ + pixel_x = -9; + pixel_y = 26 + }, /turf/open/floor/plasteel, -/area/security/prison) +/area/cargo/sorting) "jkx" = ( /obj/effect/decal/cleanable/cobweb/cobweb2, /obj/machinery/computer/slot_machine, @@ -55499,6 +56696,14 @@ /obj/machinery/rnd/production/techfab/department/cargo, /turf/open/floor/plasteel, /area/cargo/office) +"jlQ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/plating, +/area/maintenance/prison/port) "jmL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 @@ -55515,6 +56720,9 @@ }, /turf/open/floor/plasteel, /area/commons/fitness) +"jnk" = ( +/turf/closed/wall/r_wall, +/area/maintenance/prison/starboard) "jnV" = ( /obj/structure/cable{ icon_state = "1-2" @@ -55555,10 +56763,23 @@ }, /turf/open/floor/carpet/arcade, /area/commons/arcade) +"jqK" = ( +/obj/structure/rack, +/obj/effect/spawner/lootdrop/prison_contraband, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/maintenance/prison/starboard) "jrE" = ( /obj/item/beacon, /turf/open/floor/plasteel/white, /area/science/circuit) +"jrR" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "jsO" = ( /obj/machinery/hydroponics/soil{ pixel_y = 8 @@ -55596,10 +56817,53 @@ /obj/structure/closet/athletic_mixed, /turf/open/floor/plasteel, /area/commons/fitness) +"jvB" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"jvO" = ( +/obj/structure/rack, +/obj/item/flashlight{ + pixel_x = 1; + pixel_y = 5 + }, +/obj/item/tank/internals/anesthetic{ + pixel_x = -3; + pixel_y = 1 + }, +/obj/item/tank/internals/oxygen/red{ + pixel_x = 3 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple{ + dir = 6 + }, +/turf/open/floor/plating, +/area/security/execution/transfer) "jwH" = ( /obj/machinery/holopad, /turf/open/floor/plasteel, /area/service/hydroponics) +"jxx" = ( +/obj/machinery/door/firedoor, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/door/airlock/public/glass{ + name = "Prison Yard" + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "jxF" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -55678,6 +56942,10 @@ dir = 4 }, /area/service/theater) +"jCV" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/dark/side, +/area/security/prison/upper) "jDr" = ( /obj/machinery/door/poddoor/preopen{ id = "atmos"; @@ -55708,10 +56976,6 @@ dir = 1 }, /area/commons/fitness) -"jFd" = ( -/obj/effect/spawner/structure/window, -/turf/open/floor/plating, -/area/maintenance/port/fore) "jFB" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 @@ -55758,6 +57022,23 @@ /obj/effect/landmark/start/assistant, /turf/open/floor/plasteel, /area/hallway/secondary/entry) +"jHp" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "jHt" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/disposalpipe/segment{ @@ -55793,6 +57074,19 @@ /obj/structure/lattice, /turf/open/space/basic, /area/space/nearstation) +"jIH" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "jIW" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -55807,6 +57101,51 @@ }, /turf/open/floor/wood, /area/maintenance/port/aft) +"jKc" = ( +/obj/structure/closet/secure_closet/injection, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = 24 + }, +/obj/machinery/power/apc{ + areastring = "/area/security/execution/transfer"; + dir = 1; + name = "Prisoner Transfer Centre"; + pixel_y = 23 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"jKj" = ( +/obj/structure/table, +/obj/item/razor, +/obj/item/toy/plush/borgplushie{ + desc = "A horrible abomination to God in plushie form. Legends say this is used to torture prisoners by repeatedly beating them in the head with it.. ..It feels sorta heavy."; + force = 1; + name = "dogborg plushie"; + throwforce = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"jKm" = ( +/obj/structure/chair/comfy/brown{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "jKP" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable{ @@ -55828,12 +57167,6 @@ /obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plasteel, /area/engineering/engine_smes) -"jLv" = ( -/obj/structure/sign/warning/securearea{ - pixel_x = 32 - }, -/turf/open/space, -/area/space) "jLJ" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/machinery/light/small, @@ -55866,12 +57199,64 @@ }, /turf/open/floor/plating/rust, /area/maintenance/port/fore) -"jRw" = ( -/obj/machinery/computer/arcade/minesweeper{ - dir = 4 +"jNN" = ( +/obj/structure/cable{ + icon_state = "1-8" }, /turf/open/floor/plasteel, /area/security/prison) +"jNT" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/aft) +"jOB" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/medical/glass{ + name = "Prison Forestry" + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) +"jRw" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"jRV" = ( +/turf/open/floor/plasteel, +/area/security/prison) +"jRW" = ( +/obj/item/reagent_containers/glass/bucket, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/sink{ + dir = 8; + pixel_x = -12 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "jSD" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -55892,6 +57277,39 @@ }, /turf/open/floor/plasteel, /area/science/circuit) +"jSY" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel/dark/side, +/area/security/prison/upper) +"jTy" = ( +/obj/machinery/washing_machine, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) +"jUN" = ( +/obj/structure/table/reinforced, +/obj/structure/reagent_dispensers/servingdish, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "jUV" = ( /obj/structure/cable{ icon_state = "1-2" @@ -55908,6 +57326,22 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"jVP" = ( +/obj/structure/chair{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) +"jVV" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "jVX" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 4 @@ -55919,6 +57353,19 @@ dir = 1 }, /area/engineering/atmos) +"jYl" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"jYI" = ( +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, +/turf/open/floor/plasteel/white, +/area/science/robotics/lab) "jZT" = ( /obj/structure/cable{ icon_state = "4-8" @@ -55954,11 +57401,50 @@ }, /turf/open/floor/plasteel, /area/security/brig) +"kbO" = ( +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/closet/firecloset, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) "kcx" = ( /obj/structure/lattice, /obj/machinery/atmospherics/pipe/simple/dark/visible, /turf/open/space/basic, /area/space/nearstation) +"kcB" = ( +/obj/effect/turf_decal/tile/red, +/obj/machinery/camera{ + c_tag = "Prison Isolation Cell"; + dir = 8; + network = list("ss13","prison"); + view_range = 5 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"kcR" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "kdF" = ( /obj/structure/window/reinforced{ dir = 1 @@ -55993,15 +57479,23 @@ /turf/open/floor/plasteel, /area/commons/dorms) "keM" = ( -/obj/machinery/light/small{ - dir = 1 +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "Prison Gate"; + name = "prison blast door" }, -/obj/structure/window/reinforced{ - dir = 8 +/obj/structure/cable{ + icon_state = "2-4" }, -/obj/machinery/washing_machine, -/turf/open/floor/plasteel/freezer, -/area/security/prison) +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Prison Lockdown Shutters" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "kfv" = ( /obj/structure/cable{ icon_state = "4-8" @@ -56011,6 +57505,16 @@ }, /turf/open/floor/plating, /area/engineering/storage/tech) +"kfG" = ( +/obj/structure/table/wood, +/obj/item/toy/cards/deck, +/obj/item/instrument/harmonica, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "kfS" = ( /turf/closed/wall/rust, /area/maintenance/starboard/aft) @@ -56026,17 +57530,23 @@ }, /area/maintenance/starboard) "kgr" = ( -/obj/machinery/light/small{ - brightness = 3; +/obj/machinery/cryopod{ dir = 8 }, -/turf/open/floor/plating, -/area/security/prison) +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "kgB" = ( -/obj/machinery/vending/snack/orange, /obj/machinery/light{ dir = 1 }, +/obj/machinery/jukebox, /turf/open/floor/wood, /area/service/bar) "khb" = ( @@ -56056,6 +57566,22 @@ }, /turf/open/floor/plating, /area/maintenance/fore/secondary) +"khO" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security{ + aiControlDisabled = 1; + name = "Prisoner Transfer Centre"; + req_access_txt = "2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "khV" = ( /obj/machinery/vending/cola/red, /obj/structure/sign/poster/contraband/robust_softdrinks{ @@ -56105,6 +57631,13 @@ }, /turf/open/floor/plating, /area/hallway/secondary/entry) +"kkb" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "kkK" = ( /obj/machinery/vending/autodrobe, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -56119,6 +57652,16 @@ /obj/structure/grille, /turf/open/floor/plating, /area/maintenance/port/fore) +"kma" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/prison/cells) "kmw" = ( /obj/structure/chair/comfy/black{ dir = 1 @@ -56156,6 +57699,23 @@ /obj/machinery/door/firedoor, /turf/open/floor/plasteel/dark, /area/hallway/primary/central) +"knA" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "kob" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/disposalpipe/segment, @@ -56177,6 +57737,27 @@ /obj/machinery/gear_painter, /turf/open/floor/plasteel, /area/commons/fitness) +"ksa" = ( +/obj/structure/closet/secure_closet/brig, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/bot_white, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "ktP" = ( /obj/machinery/power/smes{ charge = 5e+006 @@ -56192,6 +57773,17 @@ "ktS" = ( /turf/open/space/basic, /area/space/nearstation) +"ktW" = ( +/obj/machinery/hydroponics/soil, +/obj/item/plant_analyzer, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "kuh" = ( /obj/structure/cable{ icon_state = "4-8" @@ -56335,6 +57927,21 @@ /obj/effect/landmark/stationroom/box/engine, /turf/open/space/basic, /area/space) +"kGj" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/light, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "kGv" = ( /obj/machinery/atmospherics/pipe/simple/yellow/visible, /obj/machinery/atmospherics/pipe/simple/dark/visible{ @@ -56358,6 +57965,11 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/starboard/fore) +"kGL" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/grille/broken, +/turf/open/floor/plating, +/area/maintenance/prison/starboard) "kHd" = ( /obj/structure/cable{ icon_state = "1-2" @@ -56390,6 +58002,36 @@ }, /turf/open/floor/plasteel, /area/engineering/atmos) +"kLK" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) +"kMn" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/camera{ + c_tag = "Permabrig North"; + dir = 4; + network = list("ss13","prison") + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/structure/disposaloutlet{ + dir = 4; + name = "Prisoner Delivery" + }, +/obj/effect/turf_decal/delivery, +/obj/structure/window/reinforced, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "kMt" = ( /obj/machinery/computer/prisoner/gulag_teleporter_computer, /turf/open/floor/plasteel, @@ -56409,6 +58051,14 @@ }, /turf/open/floor/plating, /area/maintenance/port/aft) +"kOE" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plasteel, +/area/security/prison/upper) "kOL" = ( /obj/structure/table/glass, /turf/open/floor/wood/wood_large, @@ -56521,6 +58171,24 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) +"kYm" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/obj/structure/chair/stool, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "kZS" = ( /obj/machinery/light{ dir = 8 @@ -56554,6 +58222,27 @@ }, /turf/closed/wall/r_wall, /area/command/gateway) +"ldT" = ( +/obj/structure/chair/office{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) +"ldY" = ( +/obj/machinery/door/airlock/security{ + name = "Firing Range"; + req_access_txt = "2" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/security/prison) "leE" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -56604,6 +58293,13 @@ }, /turf/open/floor/plasteel, /area/commons/dorms) +"lht" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "lhQ" = ( /obj/machinery/power/floodlight, /obj/structure/cable{ @@ -56611,6 +58307,20 @@ }, /turf/open/floor/plating, /area/engineering/atmos) +"lic" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "lip" = ( /obj/structure/closet{ name = "Suit Closet" @@ -56636,6 +58346,12 @@ /obj/item/clothing/under/rank/civilian/lawyer/red, /turf/open/floor/plasteel, /area/commons/locker) +"liJ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "ljV" = ( /obj/machinery/airalarm{ dir = 8; @@ -56656,6 +58372,18 @@ /obj/structure/grille, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"llb" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/computer/libraryconsole/bookmanagement, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "lnk" = ( /obj/item/radio/intercom{ pixel_y = 25 @@ -56670,6 +58398,11 @@ icon_state = "wood-broken6" }, /area/maintenance/bar) +"lpx" = ( +/obj/structure/window, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/white, +/area/security/prison/upper) "lpQ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/spawner/structure/window/reinforced, @@ -56721,12 +58454,31 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/fore) +"ltm" = ( +/obj/structure/chair/comfy/brown{ + color = "#66b266"; + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "ltv" = ( /mob/living/simple_animal/bot/cleanbot{ name = "Honest Work" }, /turf/open/floor/carpet/royalblue, /area/maintenance/starboard/aft) +"ltw" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "ltK" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -56739,12 +58491,60 @@ }, /turf/open/floor/plasteel, /area/commons/dorms) +"lux" = ( +/obj/structure/closet/crate/hydroponics, +/obj/item/paper/guides/jobs/hydroponics, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/obj/item/seeds/onion, +/obj/item/seeds/garlic, +/obj/item/seeds/potato, +/obj/item/seeds/tomato, +/obj/item/seeds/carrot, +/obj/item/seeds/grass, +/obj/item/seeds/ambrosia, +/obj/item/seeds/wheat, +/obj/item/seeds/pumpkin, +/obj/effect/spawner/lootdrop/prison_contraband, +/turf/open/floor/plasteel, +/area/security/prison/upper) "lva" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 }, /turf/open/floor/plasteel, /area/service/hydroponics) +"lvc" = ( +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"lvw" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "permacells6"; + name = "Privacy Shutters" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/security/prison/cells) "lwN" = ( /obj/structure/cable{ icon_state = "1-8" @@ -56770,6 +58570,25 @@ /obj/structure/sign/nanotrasen, /turf/closed/wall, /area/science/circuit) +"lAD" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/camera{ + c_tag = "Prison Cell Block Central"; + dir = 1; + network = list("ss13","prison") + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "lAH" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -56789,6 +58608,16 @@ dir = 1 }, /area/hallway/secondary/entry) +"lBk" = ( +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/public/glass{ + name = "Prison Yard" + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "lBz" = ( /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ @@ -56812,6 +58641,50 @@ }, /turf/open/floor/plasteel, /area/commons/fitness/pool) +"lCt" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"lDm" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"lEf" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "permacells4"; + name = "Privacy Shutters" + }, +/turf/open/floor/plating, +/area/security/prison/cells) +"lGm" = ( +/obj/machinery/shower{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison/cells) "lGV" = ( /obj/machinery/button/door{ id = "maintdiy"; @@ -56821,6 +58694,23 @@ }, /turf/open/floor/plating, /area/service/abandoned_gambling_den) +"lHK" = ( +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"lJA" = ( +/turf/closed/wall, +/area/security/prison/cells) "lJC" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 @@ -56830,6 +58720,13 @@ }, /turf/open/floor/plating, /area/security/office) +"lJS" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison) "lKj" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 @@ -56839,6 +58736,16 @@ "lLf" = ( /turf/closed/wall/r_wall, /area/ai_monitored/command/nuke_storage) +"lLu" = ( +/obj/structure/chair/stool, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "lLA" = ( /obj/machinery/computer/slot_machine{ balance = 15; @@ -56871,6 +58778,19 @@ }, /turf/open/floor/plasteel, /area/security/processing) +"lNQ" = ( +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"lOe" = ( +/obj/machinery/status_display/ai{ + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/command/meeting_room) "lOr" = ( /obj/structure/table, /obj/machinery/light/floor, @@ -56932,6 +58852,13 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/carpet, /area/commons/dorms) +"lUU" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "lVy" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/decal/cleanable/dirt, @@ -56946,6 +58873,18 @@ /obj/item/light/tube/broken, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"lYI" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "lZa" = ( /obj/effect/turf_decal/tile/red{ dir = 1 @@ -56986,6 +58925,20 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/security/brig) +"lZp" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "lZs" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/closet, @@ -57019,10 +58972,43 @@ dir = 4 }, /area/service/theater) +"maP" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/status_display/ai{ + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "maT" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/disposal/incinerator) +"maU" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"mbC" = ( +/turf/closed/wall/r_wall, +/area/security/execution/transfer) "mbU" = ( /obj/machinery/vr_sleeper{ dir = 8 @@ -57050,6 +59036,9 @@ /obj/structure/sign/poster/contraband/fun_police{ pixel_x = 32 }, +/obj/machinery/camera{ + c_tag = "Bar Arcade" + }, /turf/open/floor/carpet/arcade, /area/commons/arcade) "meb" = ( @@ -57066,10 +59055,59 @@ /obj/structure/bed, /turf/open/floor/plasteel, /area/commons/fitness/pool) +"mhv" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Prison Visitation Observation"; + req_access_txt = "2" + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "mjr" = ( /obj/structure/reagent_dispensers/keg/milk, /turf/open/floor/wood, /area/service/bar) +"mjJ" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"mke" = ( +/obj/machinery/camera{ + c_tag = "Prison Common Room"; + dir = 8; + network = list("ss13","prison") + }, +/obj/machinery/vr_sleeper{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "mkv" = ( /obj/machinery/camera{ c_tag = "Gravity Generator Room"; @@ -57112,11 +59150,28 @@ }, /turf/open/floor/plasteel/freezer, /area/commons/toilet/locker) +"mnu" = ( +/obj/machinery/cryopod{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "mnC" = ( /obj/structure/target_stake, /obj/item/target/syndicate, /turf/open/floor/plating, /area/security/range) +"moe" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "mos" = ( /obj/machinery/light/small{ dir = 8 @@ -57174,6 +59229,17 @@ icon_state = "wood-broken5" }, /area/maintenance/bar) +"mpY" = ( +/obj/item/reagent_containers/glass/bucket, +/obj/item/mop, +/obj/item/reagent_containers/glass/bottle/ammonia, +/obj/structure/sink{ + dir = 4; + pixel_x = 12 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/security/prison/upper) "mqo" = ( /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -57196,6 +59262,14 @@ }, /turf/open/floor/plasteel, /area/commons/locker) +"mqQ" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/grille/broken, +/turf/open/floor/plating, +/area/maintenance/prison/port) "mqZ" = ( /obj/item/reagent_containers/glass/beaker, /turf/open/floor/plating, @@ -57204,10 +59278,41 @@ /obj/effect/spawner/lootdrop/keg, /turf/open/floor/wood, /area/maintenance/bar) +"msp" = ( +/obj/machinery/computer/arcade/orion_trail, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"mte" = ( +/obj/structure/closet/crate, +/obj/item/reagent_containers/glass/bowl, +/obj/item/reagent_containers/glass/bowl, +/obj/item/reagent_containers/glass/bowl, +/obj/item/reagent_containers/glass/bowl, +/obj/item/reagent_containers/glass/bowl, +/obj/item/reagent_containers/glass/bowl, +/obj/item/reagent_containers/glass/bowl, +/obj/item/reagent_containers/glass/bowl, +/obj/item/storage/box/drinkingglasses, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/box/drinkingglasses, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/white, +/area/security/prison/upper) "mtU" = ( /obj/structure/sign/departments/holy, /turf/closed/wall, /area/service/chapel/main) +"mui" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Prison Common Room" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "muv" = ( /obj/item/radio/intercom{ pixel_y = 25 @@ -57222,6 +59327,29 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) +"mvV" = ( +/obj/effect/spawner/lootdrop/prison_contraband, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/bed{ + dir = 8 + }, +/obj/item/bedsheet/red{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "mwj" = ( /obj/structure/noticeboard{ dir = 8; @@ -57232,6 +59360,16 @@ }, /turf/open/floor/wood, /area/command/meeting_room) +"mwN" = ( +/obj/structure/chair/sofa/left, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "mwS" = ( /turf/open/floor/plating{ icon_state = "platingdmg3" @@ -57246,6 +59384,33 @@ }, /turf/open/floor/plating, /area/security/office) +"mxZ" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/closet/crate/trashcart/laundry, +/obj/item/clothing/under/rank/prisoner, +/obj/item/clothing/under/rank/prisoner, +/obj/item/clothing/under/rank/prisoner/skirt, +/obj/item/clothing/under/rank/prisoner/skirt, +/obj/effect/decal/cleanable/dirt, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_y = 8 + }, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_y = 8 + }, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_y = 8 + }, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_y = 8 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "myh" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -57279,6 +59444,30 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/fore) +"mAT" = ( +/obj/machinery/shower{ + dir = 8; + pixel_y = -4 + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison/cells) +"mCm" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/portable_atmospherics/canister/carbon_dioxide, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/open/floor/plating, +/area/security/execution/transfer) +"mCo" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "mDZ" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -57334,6 +59523,18 @@ /obj/effect/decal/cleanable/cobweb, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"mHH" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "mHU" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/light_construct{ @@ -57342,9 +59543,13 @@ /turf/open/floor/plating, /area/maintenance/starboard/fore) "mIZ" = ( -/obj/structure/falsewall, -/turf/open/floor/plating, -/area/security/prison) +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "mJf" = ( /obj/structure/cable{ icon_state = "0-8" @@ -57363,6 +59568,21 @@ /obj/item/electronics/airlock, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"mJy" = ( +/obj/structure/table, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/item/restraints/handcuffs, +/obj/item/taperecorder, +/obj/item/folder/red, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) +"mJH" = ( +/obj/structure/cable, +/obj/effect/spawner/structure/window/reinforced/tinted/electrochromatic{ + electrochromatic_id = "!permabrigshowers" + }, +/turf/open/floor/plating, +/area/security/prison/cells) "mLS" = ( /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating{ @@ -57380,6 +59600,7 @@ /obj/structure/sign/poster/official/fruit_bowl{ pixel_y = 32 }, +/obj/structure/closet/firecloset, /turf/open/floor/plasteel/white/corner{ dir = 1 }, @@ -57477,6 +59698,13 @@ }, /turf/open/floor/plasteel, /area/commons/locker) +"mZu" = ( +/obj/machinery/door/airlock{ + name = "Cleaning Closet" + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/security/prison/upper) "mZx" = ( /obj/structure/table/glass, /obj/item/storage/box/matches{ @@ -57485,6 +59713,18 @@ }, /turf/open/floor/wood/wood_large, /area/service/chapel/main) +"naj" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "executionfireblast" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/security/execution/transfer) "naI" = ( /turf/open/space, /area/space/station_ruins) @@ -57536,6 +59776,28 @@ }, /turf/open/floor/plasteel/freezer, /area/commons/toilet) +"ncU" = ( +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/obj/machinery/door/poddoor/shutters{ + id = "visitation"; + name = "Visitation Shutters" + }, +/obj/structure/window/reinforced, +/obj/structure/table/reinforced, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "ndq" = ( /turf/open/floor/plating, /area/service/abandoned_gambling_den) @@ -57560,6 +59822,18 @@ /obj/machinery/vending/autodrobe, /turf/open/floor/wood, /area/maintenance/bar) +"ngq" = ( +/obj/effect/turf_decal/tile/green, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel, +/area/security/prison/upper) "ngs" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable{ @@ -57590,12 +59864,28 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/fore) -"nkP" = ( -/obj/structure/rack, -/obj/effect/spawner/lootdrop/maintenance{ - lootcount = 8; - name = "8maintenance loot spawner" +"nko" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/landmark/start/prisoner, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/button/door{ + id = "permacells2"; + name = "Privacy Shutters"; + pixel_x = 25 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) +"nkP" = ( +/obj/structure/loot_pile/maint, /turf/open/floor/plating, /area/maintenance/port/aft) "nmZ" = ( @@ -57640,17 +59930,53 @@ }, /turf/open/floor/plasteel/dark, /area/maintenance/starboard/fore) +"noJ" = ( +/obj/structure/closet/secure_closet/brig, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/security/prison) "noL" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 }, /turf/open/floor/plating, /area/maintenance/port/fore) +"noR" = ( +/obj/structure/sink/kitchen{ + pixel_y = 28 + }, +/obj/structure/chair/stool, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/white, +/area/security/prison/upper) "noT" = ( /turf/open/floor/wood{ icon_state = "wood-broken4" }, /area/maintenance/starboard/aft) +"nqu" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "nsf" = ( /obj/structure/cable/white{ icon_state = "0-2" @@ -57736,6 +60062,14 @@ }, /turf/closed/wall, /area/maintenance/disposal/incinerator) +"nzX" = ( +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 8; + name = "8maintenance loot spawner" + }, +/obj/structure/rack, +/turf/open/floor/plating, +/area/maintenance/port/aft) "nBI" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -57773,6 +60107,21 @@ }, /turf/open/space/basic, /area/space/nearstation) +"nFA" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "nGf" = ( /obj/machinery/hydroponics/constructable, /obj/machinery/light{ @@ -57837,6 +60186,11 @@ }, /turf/open/floor/plasteel, /area/commons/locker) +"nLP" = ( +/obj/item/storage/bag/trash, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/security/prison/upper) "nNF" = ( /obj/machinery/light{ dir = 1 @@ -57860,6 +60214,24 @@ }, /turf/open/floor/wood, /area/maintenance/starboard/aft) +"nRO" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/airlock/grunge{ + name = "Permanent Cell 2"; + wiretypepath = /datum/wires/airlock/security + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "nSt" = ( /obj/effect/turf_decal/tile/neutral{ dir = 4 @@ -57872,6 +60244,11 @@ }, /turf/open/floor/plasteel, /area/commons/dorms) +"nSI" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plasteel/white, +/area/security/prison/upper) "nTG" = ( /obj/structure/chair{ dir = 1 @@ -57929,6 +60306,19 @@ /obj/machinery/atmospherics/pipe/simple/dark/visible, /turf/open/space, /area/space/nearstation) +"nZh" = ( +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"nZs" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "nZE" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/tile/neutral, @@ -57941,7 +60331,7 @@ /turf/open/floor/plasteel, /area/commons/dorms) "nZL" = ( -/obj/machinery/computer/arcade/minesweeper, +/obj/machinery/computer/arcade/orion_trail, /turf/open/floor/wood, /area/command/heads_quarters/captain) "oax" = ( @@ -57963,6 +60353,22 @@ /obj/item/clothing/head/hardhat/cakehat, /turf/open/floor/wood, /area/service/bar) +"obq" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/spawner/structure/window, +/turf/open/floor/plating, +/area/security/prison/upper) +"obs" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/padded, +/area/security/execution/transfer) "oby" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -57998,6 +60404,10 @@ /obj/machinery/vending/kink, /turf/open/floor/plating, /area/maintenance/bar) +"odV" = ( +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/fore/secondary) "ofj" = ( /obj/machinery/smartfridge/organ/preloaded, /turf/closed/wall, @@ -58015,6 +60425,12 @@ }, /turf/open/floor/plasteel, /area/commons/fitness/pool) +"oiY" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "okK" = ( /obj/machinery/light/small{ dir = 8 @@ -58071,6 +60487,11 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/white, /area/science/circuit) +"olH" = ( +/obj/structure/closet/crate, +/obj/effect/spawner/lootdrop/prison_contraband, +/turf/open/floor/plasteel/white, +/area/security/prison/upper) "omk" = ( /obj/machinery/atmospherics/pipe/manifold/cyan/visible{ dir = 1 @@ -58096,6 +60517,33 @@ /obj/machinery/holopad, /turf/open/floor/plasteel, /area/security/prison) +"ooF" = ( +/obj/effect/turf_decal/stripes/white/line, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -24 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"oqf" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/cells) "oqj" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -58117,6 +60565,21 @@ }, /turf/open/floor/plasteel, /area/engineering/gravity_generator) +"oss" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "otC" = ( /obj/machinery/status_display/evac, /turf/closed/wall/r_wall, @@ -58143,6 +60606,9 @@ /obj/machinery/recharger, /obj/item/gun/energy/laser/practice, /obj/item/gun/energy/laser/practice, +/obj/structure/extinguisher_cabinet{ + pixel_y = 30 + }, /turf/open/floor/plasteel, /area/security/range) "owa" = ( @@ -58209,6 +60675,22 @@ }, /turf/open/floor/plating, /area/maintenance/fore/secondary) +"ozh" = ( +/obj/machinery/door/window/eastright{ + dir = 8; + name = "Holding Cell"; + req_access_txt = "2" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/button/flasher{ + id = "waitingflash"; + pixel_x = 6; + pixel_y = 24 + }, +/turf/open/floor/plasteel, +/area/security/prison) "oAB" = ( /obj/structure/fireplace{ pixel_y = -6 @@ -58263,6 +60745,11 @@ "oHB" = ( /turf/open/floor/plasteel/dark, /area/commons/dorms) +"oIl" = ( +/obj/structure/weightmachine/weightlifter, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "oIJ" = ( /obj/structure/chair/comfy/brown{ dir = 8 @@ -58279,10 +60766,12 @@ /turf/open/floor/mineral/titanium/blue, /area/commons/dorms) "oJV" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ icon_state = "2-4" }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/medical/morgue) "oKh" = ( @@ -58291,6 +60780,14 @@ }, /turf/open/floor/wood, /area/maintenance/bar) +"oKB" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "oLl" = ( /obj/structure/cable{ icon_state = "4-8" @@ -58308,6 +60805,19 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark, /area/hallway/primary/central) +"oPY" = ( +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "oQP" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/grimy, @@ -58318,17 +60828,15 @@ }, /turf/closed/wall, /area/medical/medbay/central) -"oSl" = ( -/obj/machinery/door/airlock/security{ - name = "Firing Range"; - req_access_txt = "2" +"oTx" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "permacells2"; + name = "Privacy Shutters" }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel, -/area/security/range) +/turf/open/floor/plating, +/area/security/prison/cells) "oTH" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/shower, @@ -58351,10 +60859,22 @@ /obj/machinery/disposal/bin, /turf/open/floor/plasteel/white, /area/science/circuit) +"oUF" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "oVo" = ( /obj/structure/pool/ladder, /turf/open/pool, /area/commons/fitness/pool) +"oVL" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/dark/side, +/area/security/prison/upper) "oVN" = ( /obj/machinery/meter, /obj/machinery/atmospherics/pipe/manifold/cyan/visible, @@ -58366,6 +60886,28 @@ }, /turf/closed/wall/r_wall, /area/engineering/atmos) +"oXV" = ( +/obj/structure/window/reinforced/tinted{ + dir = 8 + }, +/obj/machinery/door/poddoor/shutters{ + id = "visitation"; + name = "Visitation Shutters" + }, +/obj/structure/window/reinforced, +/obj/structure/table/reinforced, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "oZl" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/closet/wardrobe/pjs, @@ -58418,15 +60960,47 @@ }, /turf/open/floor/wood, /area/service/library) +"peD" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"peE" = ( +/obj/structure/table/reinforced, +/obj/structure/reagent_dispensers/servingdish, +/turf/open/floor/plasteel, +/area/security/prison/upper) "pgf" = ( /turf/open/floor/mineral/titanium/blue, /area/commons/dorms) +"pgl" = ( +/obj/structure/closet/firecloset, +/turf/open/floor/plasteel, +/area/hallway/primary/port) "pgn" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 }, /turf/open/floor/plating, /area/security/range) +"pgq" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Prison Common Room" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "pgZ" = ( /obj/structure/cable{ icon_state = "1-2" @@ -58493,6 +61067,16 @@ }, /turf/open/floor/plasteel, /area/security/brig) +"pnb" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "pnc" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -58553,6 +61137,19 @@ }, /turf/open/floor/wood/wood_diagonal, /area/maintenance/port/fore) +"pry" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/lattice/catwalk, +/turf/open/space, +/area/solars/port/fore) "psf" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/sign/poster/official/the_owl{ @@ -58564,6 +61161,10 @@ /obj/machinery/gateway/centerstation, /turf/open/floor/plasteel/dark, /area/command/gateway) +"pta" = ( +/obj/structure/grille/broken, +/turf/open/floor/plating, +/area/space/nearstation) "pub" = ( /obj/machinery/light_switch{ pixel_x = -20 @@ -58608,6 +61209,12 @@ }, /turf/open/floor/plating, /area/maintenance/port/fore) +"pwF" = ( +/obj/machinery/shower{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison/cells) "pzG" = ( /obj/item/radio/intercom{ name = "Station Intercom (General)"; @@ -58653,6 +61260,18 @@ }, /turf/open/floor/plasteel, /area/security/brig) +"pBd" = ( +/obj/machinery/power/apc{ + areastring = "/area/maintenance/prison/starboard"; + dir = 8; + name = "Prison Central Maintenance APC"; + pixel_x = -24 + }, +/obj/effect/turf_decal/bot, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/turf/open/floor/plating, +/area/maintenance/prison/starboard) "pBp" = ( /obj/effect/landmark/event_spawn, /turf/closed/wall, @@ -58686,6 +61305,24 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"pFj" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"pFt" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison/cells) "pFY" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -58695,6 +61332,21 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) +"pGs" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/maintenance/prison/starboard) +"pGA" = ( +/obj/machinery/hydroponics/soil, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/turf/open/floor/plasteel, +/area/security/prison/upper) "pHl" = ( /obj/structure/table, /obj/item/storage/box/beakers{ @@ -58730,6 +61382,15 @@ }, /turf/open/floor/plasteel/dark, /area/hallway/primary/central) +"pHK" = ( +/obj/machinery/camera{ + c_tag = "Prison Yard"; + dir = 4; + network = list("ss13","prison") + }, +/obj/structure/chair/stool, +/turf/open/floor/plasteel/dark/corner, +/area/security/prison/upper) "pHO" = ( /obj/effect/turf_decal/tile/blue, /obj/structure/sign/poster/contraband/fun_police{ @@ -58737,6 +61398,33 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/fore) +"pIR" = ( +/obj/structure/table, +/obj/item/storage/box/handcuffs{ + pixel_y = 10 + }, +/obj/item/storage/box/prisoner{ + pixel_y = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/camera{ + c_tag = "Prison Hallway West"; + network = list("ss13","prison") + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "pJR" = ( /obj/structure/disposalpipe/segment, /obj/structure/chair/comfy/brown{ @@ -58780,6 +61468,14 @@ }, /turf/open/floor/plasteel, /area/commons/fitness) +"pPE" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "permacells1"; + name = "Privacy Shutters" + }, +/turf/open/floor/plating, +/area/security/prison/cells) "pPI" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 @@ -58805,6 +61501,41 @@ "pQN" = ( /turf/open/floor/plasteel/dark, /area/hallway/primary/central) +"pRi" = ( +/obj/structure/table, +/obj/item/reagent_containers/glass/bottle/morphine{ + pixel_x = -4; + pixel_y = 1 + }, +/obj/item/reagent_containers/glass/bottle/chloralhydrate, +/obj/item/reagent_containers/glass/bottle/toxin{ + pixel_x = 6; + pixel_y = 8 + }, +/obj/item/reagent_containers/glass/bottle/morphine{ + pixel_x = 5; + pixel_y = 1 + }, +/obj/item/reagent_containers/syringe, +/obj/item/reagent_containers/glass/bottle/facid{ + name = "fluorosulfuric acid bottle"; + pixel_x = -3; + pixel_y = 6 + }, +/obj/item/reagent_containers/syringe{ + pixel_y = 5 + }, +/obj/item/reagent_containers/dropper, +/obj/machinery/airalarm/directional/west, +/obj/item/assembly/signaler{ + pixel_x = -3; + pixel_y = 2 + }, +/obj/machinery/atmospherics/pipe/simple{ + dir = 10 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "pRj" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 @@ -58829,6 +61560,43 @@ }, /turf/open/space, /area/solars/starboard/aft) +"pTT" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"pUf" = ( +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "pUy" = ( /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ @@ -58870,6 +61638,24 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"pZD" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/airlock/grunge{ + name = "Permanent Cell 1"; + wiretypepath = /datum/wires/airlock/security + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "qae" = ( /obj/effect/decal/cleanable/vomit, /obj/effect/decal/cleanable/dirt, @@ -58884,6 +61670,23 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/service/bar) +"qbk" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"qcU" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "qeb" = ( /obj/structure/cable{ icon_state = "0-8" @@ -58938,6 +61741,24 @@ /obj/effect/spawner/structure/window, /turf/open/floor/wood, /area/service/library) +"qgj" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"qhA" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/lattice/catwalk, +/turf/open/space, +/area/solars/port/fore) "qje" = ( /obj/structure/sign/mining{ pixel_y = 7 @@ -58993,15 +61814,27 @@ icon_state = "panelscorched" }, /area/maintenance/starboard/aft) -"qmn" = ( -/obj/machinery/computer/libraryconsole/bookmanagement, -/obj/structure/table, -/turf/open/floor/plasteel, -/area/security/prison) "qnC" = ( -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/power/apc{ + areastring = "/area/maintenance/department/medical/morgue"; + dir = 1; + name = "Morgue Maintenance APC"; + pixel_y = 23 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/maintenance/department/medical/morgue) "qoT" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 @@ -59015,9 +61848,20 @@ }, /turf/open/floor/plasteel, /area/science/circuit) +"qto" = ( +/obj/machinery/hydroponics/soil, +/obj/item/shovel/spade, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "qtw" = ( /obj/machinery/door/airlock/external{ - dir = 2; name = "Port Docking Bay 4" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -59049,6 +61893,26 @@ /obj/structure/grille/broken, /turf/open/space/basic, /area/space/nearstation) +"qvc" = ( +/obj/structure/table, +/obj/structure/window, +/obj/item/reagent_containers/food/condiment/saltshaker{ + layer = 3.1; + pixel_x = -2; + pixel_y = 2 + }, +/obj/item/reagent_containers/food/condiment/peppermill{ + desc = "Often used to flavor food or make people sneeze. Fashionably moved to the left side of the table."; + pixel_x = -8; + pixel_y = 2 + }, +/obj/item/reagent_containers/food/condiment/enzyme{ + pixel_x = 9; + pixel_y = 3 + }, +/obj/item/book/manual/chef_recipes, +/turf/open/floor/plasteel/white, +/area/security/prison/upper) "qvf" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -59058,6 +61922,14 @@ }, /turf/open/floor/plasteel, /area/commons/dorms) +"qwA" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison/cells) "qAu" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 @@ -59073,6 +61945,9 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/port) +"qCc" = ( +/turf/closed/wall, +/area/maintenance/prison/port) "qCw" = ( /obj/structure/chair/stool{ pixel_y = 8 @@ -59113,6 +61988,20 @@ }, /turf/open/floor/plasteel/dark, /area/maintenance/starboard/aft) +"qFK" = ( +/obj/machinery/biogenerator, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "qGw" = ( /obj/structure/chair/pew/right{ dir = 8 @@ -59128,6 +62017,15 @@ "qIO" = ( /turf/open/floor/plating/rust, /area/maintenance/starboard/aft) +"qIW" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/machinery/atmospherics/components/unary/outlet_injector/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "qJr" = ( /obj/structure/lattice/catwalk, /obj/structure/cable{ @@ -59140,6 +62038,18 @@ /obj/structure/lattice, /turf/open/space, /area/space/nearstation) +"qLo" = ( +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced/tinted/electrochromatic{ + electrochromatic_id = "!permabrigshowers" + }, +/turf/open/floor/plating, +/area/security/prison/cells) "qLy" = ( /obj/structure/chair/sofa/left{ dir = 8 @@ -59177,6 +62087,29 @@ /obj/effect/decal/cleanable/blood/gibs/core, /turf/open/floor/plasteel/dark, /area/maintenance/starboard/aft) +"qNU" = ( +/obj/machinery/door/poddoor/preopen{ + id = "executionfireblast" + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/window/westright{ + dir = 2; + name = "Transfer Room"; + req_access_txt = "2" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "qOc" = ( /obj/effect/turf_decal/tile/green{ dir = 8 @@ -59197,6 +62130,37 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/port) +"qOY" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/plating, +/area/maintenance/prison/starboard) +"qQK" = ( +/obj/machinery/hydroponics/soil, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"qRI" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plasteel, +/area/security/prison/upper) "qSf" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ @@ -59234,7 +62198,7 @@ icon_state = "plant-22" }, /turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/area/medical/medbay/central) "qUh" = ( /obj/machinery/door/airlock/public/glass{ name = "Chapel Office"; @@ -59256,9 +62220,12 @@ /turf/open/pool, /area/commons/fitness/pool) "qXg" = ( -/obj/structure/chair/sofa/left, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/vending/cola/red{ + onstation = 0 + }, /turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/upper) "qXJ" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ dir = 9 @@ -59266,10 +62233,38 @@ /obj/structure/lattice, /turf/open/space/basic, /area/space/nearstation) +"qYa" = ( +/obj/effect/turf_decal/bot_white, +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/plating, +/area/maintenance/prison/port) "qZD" = ( /obj/effect/decal/cleanable/egg_smudge, /turf/open/floor/plating, /area/maintenance/port/fore) +"qZQ" = ( +/obj/structure/holohoop{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/white/line{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"qZT" = ( +/obj/machinery/shower{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison/cells) "raH" = ( /obj/machinery/atmospherics/pipe/manifold/orange/hidden{ dir = 8 @@ -59313,11 +62308,6 @@ id = "Cell 1"; name = "Cell 1 Locker" }, -/obj/item/radio/headset{ - desc = "An updated, modular intercom that fits over the head. Takes encryption keys. It looks like it has been modified to not broadcast."; - name = "prisoner headset"; - prison_radio = 1 - }, /obj/structure/cable{ icon_state = "1-4" }, @@ -59330,6 +62320,12 @@ }, /turf/open/floor/plasteel, /area/security/brig) +"rcV" = ( +/obj/structure/sign/warning/securearea{ + pixel_y = -32 + }, +/turf/open/space/basic, +/area/space) "rdl" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/cyan/visible{ @@ -59345,6 +62341,15 @@ }, /turf/open/floor/plasteel/dark, /area/service/hydroponics) +"ref" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/dark, +/area/security/prison) "reA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -59356,6 +62361,40 @@ /obj/machinery/vending/games, /turf/open/floor/plasteel, /area/commons/fitness) +"reE" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"rgu" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + layer = 2.4 + }, +/turf/open/floor/plating, +/area/security/execution/transfer) "rgL" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 @@ -59376,6 +62415,11 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/security/processing) +"rla" = ( +/obj/effect/turf_decal/stripes/line, +/obj/structure/closet/firecloset, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) "rmN" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 @@ -59437,6 +62481,17 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/commons/dorms) +"rqq" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "rqE" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 @@ -59451,6 +62506,18 @@ /obj/item/clothing/under/dress/sundress, /turf/open/floor/plasteel, /area/commons/fitness) +"rsn" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "executionfireblast" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/atmospherics/pipe/simple, +/turf/open/floor/plating, +/area/security/execution/transfer) "rsp" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/table, @@ -59490,6 +62557,18 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/commons/dorms) +"ruu" = ( +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/door/airlock/security/glass{ + id_tag = "permaouter"; + name = "Permabrig Transfer"; + req_access_txt = "2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/dark, +/area/security/prison) "rvr" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -59507,12 +62586,12 @@ /turf/open/floor/plasteel, /area/commons/fitness) "rvS" = ( -/obj/structure/chair/comfy/brown{ - color = "#66b266"; - dir = 1 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 }, /turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/upper) "rwj" = ( /obj/machinery/light/small{ dir = 1 @@ -59522,6 +62601,13 @@ icon_state = "platingdmg2" }, /area/maintenance/port/fore) +"rwA" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/lattice/catwalk, +/turf/open/space, +/area/solars/port/fore) "rxD" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 @@ -59540,6 +62626,21 @@ }, /turf/open/floor/wood/wood_large, /area/service/chapel/main) +"ryi" = ( +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "ryr" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -59550,6 +62651,27 @@ }, /turf/open/floor/plasteel, /area/commons/fitness) +"ryN" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison) "rAR" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 @@ -59559,12 +62681,42 @@ }, /turf/open/floor/plasteel, /area/security/brig) +"rAW" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/flasher{ + id = "executionflash"; + pixel_y = -25 + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "rBq" = ( /obj/item/clothing/head/kitty, /obj/item/clothing/under/costume/maid, /obj/item/clothing/mask/muzzle, /turf/open/floor/plating, /area/maintenance/bar) +"rBK" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) +"rBY" = ( +/obj/structure/bed, +/turf/open/floor/padded, +/area/security/execution/transfer) "rCl" = ( /obj/machinery/door/firedoor, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -59587,6 +62739,22 @@ }, /turf/open/floor/plasteel, /area/security/brig) +"rDc" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "rDh" = ( /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -59605,6 +62773,15 @@ /obj/item/toy/crayon/spraycan/lubecan, /turf/open/floor/plasteel, /area/service/theater) +"rDm" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "rGo" = ( /obj/machinery/light/small{ dir = 1 @@ -59622,6 +62799,16 @@ }, /turf/open/floor/plating, /area/maintenance/port/aft) +"rGZ" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/lattice/catwalk, +/turf/open/space, +/area/solars/port/fore) "rIA" = ( /obj/machinery/light{ dir = 8 @@ -59697,6 +62884,12 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"rTj" = ( +/obj/structure/chair{ + dir = 4 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "rTo" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 8; @@ -59711,6 +62904,12 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/medical/medbay/central) +"rUr" = ( +/obj/effect/spawner/lootdrop/prison_contraband, +/obj/structure/rack, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/maintenance/prison/port) "rVy" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -59773,6 +62972,13 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, /area/maintenance/port/fore) +"rYM" = ( +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/machinery/power/tracker, +/turf/open/floor/plasteel/airless/solarpanel, +/area/solars/port/fore) "rZE" = ( /obj/structure/table, /obj/item/flashlight/lamp, @@ -59806,10 +63012,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall/r_wall, /area/engineering/engine_smes) -"saX" = ( -/obj/item/reagent_containers/glass/bucket, -/turf/open/floor/grass, -/area/security/prison) "sci" = ( /obj/machinery/vr_sleeper{ dir = 4 @@ -59827,6 +63029,11 @@ dir = 4 }, /area/commons/fitness) +"sew" = ( +/obj/structure/table, +/obj/machinery/microwave, +/turf/open/floor/plasteel/white, +/area/security/prison/upper) "seP" = ( /obj/structure/cable{ icon_state = "0-8" @@ -59845,12 +63052,61 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, /area/maintenance/fore) +"sfz" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/bed, +/obj/item/bedsheet/red, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "shR" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 }, /turf/open/floor/plating/airless, /area/space/nearstation) +"siz" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"ske" = ( +/obj/machinery/camera{ + c_tag = "Permabrig South"; + dir = 1; + network = list("ss13","prison") + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "slk" = ( /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" @@ -59905,6 +63161,17 @@ }, /turf/open/floor/plating, /area/service/abandoned_gambling_den) +"ssc" = ( +/obj/effect/turf_decal/stripes/white/line, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "ssB" = ( /obj/effect/turf_decal/tile/green{ dir = 1 @@ -59932,6 +63199,13 @@ /obj/item/toy/poolnoodle/yellow, /turf/open/floor/plasteel, /area/commons/fitness/pool) +"suC" = ( +/obj/machinery/shower{ + dir = 4 + }, +/obj/item/soap/nanotrasen, +/turf/open/floor/plasteel/freezer, +/area/security/prison/cells) "suN" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/landmark/event_spawn, @@ -59940,6 +63214,18 @@ }, /turf/open/floor/plasteel, /area/science/circuit) +"suS" = ( +/obj/structure/table, +/obj/item/storage/fancy/egg_box, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/rice, +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/white, +/area/security/prison/upper) "sxs" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/table, @@ -59951,6 +63237,11 @@ pixel_x = 2; pixel_y = 2 }, +/obj/machinery/camera{ + c_tag = "Service Hallway"; + dir = 1; + name = "hallway camera" + }, /turf/open/floor/plasteel, /area/hallway/secondary/service) "syJ" = ( @@ -59960,6 +63251,18 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/port) +"szf" = ( +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"szn" = ( +/turf/closed/wall/r_wall, +/area/security/prison/cells) "sAk" = ( /obj/structure/cable{ icon_state = "1-8" @@ -59969,6 +63272,11 @@ }, /turf/open/floor/plasteel, /area/security/brig) +"sAm" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "sAH" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/neutral{ @@ -59989,6 +63297,43 @@ icon_state = "wood-broken6" }, /area/maintenance/bar) +"sAT" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"sBM" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "sCa" = ( /obj/structure/rack, /obj/item/circuitboard/machine/monkey_recycler, @@ -60039,6 +63384,12 @@ }, /turf/open/floor/plasteel, /area/commons/dorms) +"sHd" = ( +/obj/machinery/door/window/southleft{ + name = "Permabrig Kitchen" + }, +/turf/open/floor/plasteel/white, +/area/security/prison/upper) "sHx" = ( /obj/structure/table, /obj/item/book/manual/hydroponics_pod_people{ @@ -60051,6 +63402,14 @@ }, /turf/open/floor/plasteel, /area/service/hydroponics) +"sIn" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plating, +/area/maintenance/prison/starboard) "sJw" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -60083,6 +63442,12 @@ }, /turf/open/floor/plasteel, /area/commons/fitness) +"sKA" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/closed/wall/r_wall, +/area/security/execution/transfer) "sKL" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/grille/broken, @@ -60102,6 +63467,12 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"sMu" = ( +/obj/structure/lattice, +/obj/structure/lattice, +/obj/structure/grille, +/turf/open/space/basic, +/area/space/nearstation) "sMG" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 @@ -60115,6 +63486,29 @@ /obj/item/storage/secure/briefcase, /turf/open/floor/plasteel, /area/commons/locker) +"sNg" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plating, +/area/security/execution/transfer) +"sNj" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/security/prison/upper) "sOs" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -60193,15 +63587,6 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) -"sWR" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/computer/bounty{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/cargo/office) "sXy" = ( /obj/machinery/door/airlock/external{ name = "Security External Airlock"; @@ -60240,10 +63625,44 @@ }, /turf/open/floor/plasteel, /area/service/theater) +"sYV" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "tal" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/hallway/secondary/service) +"tbR" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/toilet{ + dir = 8 + }, +/obj/structure/window/reinforced/tinted{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "tcU" = ( /obj/machinery/door/airlock/maintenance{ req_access_txt = "46" @@ -60254,6 +63673,37 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/fore) +"tdd" = ( +/obj/machinery/camera{ + c_tag = "Prison Cell Block North"; + dir = 4; + network = list("ss13","prison") + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"teq" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/light, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "teS" = ( /obj/structure/chair/stool{ pixel_y = 8 @@ -60280,11 +63730,27 @@ /turf/open/floor/plating, /area/maintenance/port/fore) "thB" = ( -/obj/structure/sign/warning/securearea{ - pixel_y = -32 +/obj/effect/turf_decal/tile/green{ + dir = 4 }, -/turf/open/space, -/area/space) +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#cee5d2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "tif" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -60303,6 +63769,19 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel, /area/commons/dorms) +"tkx" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "tkB" = ( /obj/structure/sign/poster/official/help_others{ pixel_y = -32 @@ -60323,6 +63802,22 @@ }, /turf/open/floor/plating, /area/security/range) +"tnH" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#cee5d2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "tnL" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 @@ -60338,6 +63833,10 @@ }, /turf/open/floor/carpet, /area/commons/cryopod) +"tqk" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/closed/wall/r_wall, +/area/security/execution/transfer) "tqB" = ( /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -60364,6 +63863,28 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/port) +"tso" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/toilet{ + dir = 4 + }, +/obj/structure/window/reinforced/tinted{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "tsq" = ( /obj/structure/cable/white{ icon_state = "0-4" @@ -60412,6 +63933,48 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/white, /area/medical/medbay/central) +"txs" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/obj/structure/toilet{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) +"tyb" = ( +/obj/machinery/door/poddoor/shutters{ + id = "visitation"; + name = "Visitation Shutters" + }, +/obj/machinery/door/window/southright, +/obj/structure/table/reinforced, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "tyE" = ( /obj/structure/cable{ icon_state = "1-2" @@ -60459,6 +64022,10 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/engineering/atmos) +"tAS" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "tBV" = ( /turf/closed/wall, /area/medical/storage) @@ -60483,7 +64050,30 @@ dir = 1 }, /turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/area/medical/medbay/central) +"tCs" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/obj/structure/toilet{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "tEK" = ( /obj/structure/cable{ icon_state = "4-8" @@ -60532,6 +64122,18 @@ dir = 1 }, /area/hallway/secondary/entry) +"tHO" = ( +/obj/structure/table/reinforced, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/turf/open/floor/plasteel, +/area/security/prison/upper) "tIE" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 @@ -60549,6 +64151,24 @@ /obj/structure/musician/piano, /turf/open/floor/wood, /area/service/theater) +"tJE" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/door/airlock/grunge{ + name = "Isolation Cell"; + req_access_txt = "2"; + wiretypepath = /datum/wires/airlock/security + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "tJK" = ( /obj/machinery/door/airlock/engineering{ name = "Gravity Generator"; @@ -60591,14 +64211,23 @@ }, /turf/open/floor/plasteel, /area/commons/dorms) +"tLC" = ( +/obj/machinery/vr_sleeper{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "tMl" = ( /obj/effect/turf_decal/loading_area, /turf/open/floor/plasteel/showroomfloor, -/area/service/kitchen/coldroom) +/area/service/kitchen) "tNl" = ( /obj/structure/cable{ icon_state = "1-2" }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/medical/morgue) "tNF" = ( @@ -60607,6 +64236,27 @@ }, /turf/open/floor/plasteel, /area/engineering/gravity_generator) +"tOk" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "tOq" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 @@ -60618,6 +64268,12 @@ /obj/structure/table/wood, /turf/open/floor/wood, /area/maintenance/bar) +"tPY" = ( +/obj/structure/chair{ + dir = 8 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "tRe" = ( /obj/machinery/chem_master, /turf/open/floor/plasteel/white, @@ -60676,6 +64332,21 @@ icon_state = "wood-broken5" }, /area/maintenance/port/fore) +"tWe" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel, +/area/security/prison/upper) "tWj" = ( /obj/structure/window/reinforced, /turf/open/floor/wood, @@ -60694,6 +64365,24 @@ }, /turf/closed/wall/r_wall, /area/maintenance/disposal/incinerator) +"tYd" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple{ + dir = 10 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"tYg" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "tZa" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -60732,6 +64421,10 @@ /obj/structure/cable{ icon_state = "0-4" }, +/obj/machinery/light_switch{ + pixel_x = -26; + pixel_y = 26 + }, /turf/open/floor/wood, /area/maintenance/bar) "ucq" = ( @@ -60750,6 +64443,19 @@ }, /turf/open/floor/plating, /area/maintenance/fore/secondary) +"ueN" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "ueZ" = ( /obj/item/radio/intercom{ name = "Station Intercom (General)"; @@ -60777,6 +64483,9 @@ dir = 4 }, /area/commons/fitness) +"ugi" = ( +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "ugp" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ dir = 4 @@ -60816,6 +64525,16 @@ /obj/effect/decal/cleanable/blood/gibs/human/lizard/body, /turf/open/floor/plasteel/dark, /area/maintenance/starboard/aft) +"uhK" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "ujv" = ( /obj/structure/sign/departments/restroom, /turf/closed/wall, @@ -60878,6 +64597,15 @@ }, /turf/open/floor/plasteel/grimy, /area/security/detectives_office) +"uql" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "uqu" = ( /obj/machinery/hydroponics/soil{ pixel_y = 8 @@ -60902,6 +64630,17 @@ /obj/machinery/atmospherics/components/binary/valve, /turf/open/floor/plating, /area/maintenance/starboard/fore) +"uuw" = ( +/obj/machinery/hydroponics/soil, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "uuG" = ( /obj/structure/cable{ icon_state = "4-8" @@ -60942,6 +64681,9 @@ /obj/structure/disposalpipe/sorting/mail{ sortType = 26 }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel, /area/commons/dorms) "uys" = ( @@ -61000,13 +64742,6 @@ /obj/structure/grille, /turf/open/floor/plating, /area/maintenance/port/fore) -"uBr" = ( -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) "uCn" = ( /obj/structure/table/reinforced, /obj/item/paper_bin, @@ -61046,12 +64781,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/commons/fitness/pool) -"uEI" = ( -/obj/structure/chair/comfy/brown{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/prison) "uFp" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -61088,8 +64817,19 @@ /turf/open/floor/plasteel, /area/security/processing) "uGI" = ( -/turf/open/floor/grass, -/area/security/prison) +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "uHc" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -61132,11 +64872,62 @@ /obj/machinery/door/window, /turf/open/floor/wood, /area/service/theater) +"uJY" = ( +/obj/structure/chair/comfy/brown{ + color = "#596479"; + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"uKW" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/security/prison/upper) +"uLB" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "uOd" = ( +/obj/machinery/light_switch{ + pixel_x = 7; + pixel_y = -26 + }, /turf/open/floor/plasteel/white/side{ dir = 4 }, /area/service/theater) +"uOm" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/old, +/mob/living/simple_animal/mouse/brown/Tom, +/turf/open/floor/plating, +/area/security/prison/upper) "uOJ" = ( /obj/structure/cable{ icon_state = "1-8" @@ -61198,6 +64989,12 @@ }, /turf/open/floor/plasteel, /area/commons/locker) +"uUb" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark/side, +/area/security/prison/upper) "uUP" = ( /obj/structure/cable/white, /obj/structure/cable/white{ @@ -61239,6 +65036,11 @@ }, /turf/closed/wall/r_wall, /area/ai_monitored/turret_protected/ai_upload) +"uZY" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable, +/turf/open/floor/plating, +/area/security/prison/upper) "vae" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -61338,6 +65140,38 @@ }, /turf/open/floor/plating, /area/maintenance/fore) +"vhy" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"vhC" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"vim" = ( +/obj/machinery/computer/arcade/battle, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "viF" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -61345,6 +65179,31 @@ /obj/machinery/door/firedoor, /turf/open/floor/plasteel, /area/hallway/primary/port) +"viH" = ( +/obj/machinery/camera{ + c_tag = "Permabrig Central"; + dir = 8; + network = list("ss13","prison") + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "vjm" = ( /obj/structure/table/wood, /obj/item/reagent_containers/rag, @@ -61483,6 +65342,25 @@ }, /turf/open/floor/wood, /area/service/library) +"vws" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"vwQ" = ( +/obj/structure/bookcase, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "vxh" = ( /turf/open/floor/plating{ icon_state = "platingdmg1" @@ -61586,6 +65464,15 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/fore) +"vCS" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "vEi" = ( /obj/structure/cable{ icon_state = "4-8" @@ -61621,6 +65508,25 @@ }, /turf/open/floor/plasteel, /area/engineering/gravity_generator) +"vFZ" = ( +/obj/effect/spawner/lootdrop/prison_contraband, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/bed, +/obj/item/bedsheet/red, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "vGn" = ( /obj/structure/cable{ icon_state = "1-2" @@ -61662,6 +65568,9 @@ }, /turf/open/floor/plasteel, /area/commons/fitness) +"vHK" = ( +/turf/closed/wall, +/area/maintenance/prison/starboard) "vHT" = ( /obj/machinery/door/firedoor, /obj/structure/sign/departments/evac{ @@ -61729,6 +65638,17 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/maintenance/fore) +"vMi" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "vOC" = ( /obj/structure/lattice, /obj/machinery/atmospherics/pipe/simple/dark/visible{ @@ -61750,6 +65670,10 @@ /obj/machinery/atmospherics/pipe/simple/dark/visible, /turf/open/space, /area/space/nearstation) +"vPd" = ( +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/port/fore) "vPs" = ( /obj/structure/lattice/catwalk, /obj/structure/cable{ @@ -61781,6 +65705,14 @@ }, /turf/open/floor/plasteel, /area/engineering/atmos) +"vRN" = ( +/obj/structure/closet/crate, +/obj/item/stack/license_plates/empty/fifty, +/obj/item/stack/license_plates/empty/fifty, +/obj/item/stack/license_plates/empty/fifty, +/obj/item/stack/license_plates/empty/fifty, +/turf/open/floor/plating, +/area/security/prison/upper) "vTP" = ( /obj/machinery/door/airlock/external{ name = "Labor Camp Shuttle Airlock"; @@ -61791,6 +65723,29 @@ }, /turf/open/floor/plating, /area/security/processing) +"vYF" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) +"vYY" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "vZA" = ( /obj/structure/lattice/catwalk, /obj/structure/cable, @@ -61808,6 +65763,23 @@ }, /turf/open/floor/plasteel, /area/commons/fitness/pool) +"waX" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"wbw" = ( +/obj/structure/lattice, +/obj/structure/grille, +/turf/open/floor/plating, +/area/space/nearstation) "wbE" = ( /obj/effect/turf_decal/tile/blue{ alpha = 255 @@ -61823,7 +65795,7 @@ dir = 8 }, /turf/open/floor/plasteel/white, -/area/medical/medbay/lobby) +/area/medical/medbay/central) "wcB" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 @@ -61836,6 +65808,15 @@ "wcR" = ( /turf/open/floor/plasteel/yellowsiding/corner, /area/commons/fitness/pool) +"wcS" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/cells) "wdr" = ( /obj/machinery/door/window/southleft{ name = "Target Storage" @@ -61854,6 +65835,21 @@ /obj/structure/girder, /turf/open/floor/plating/airless, /area/space/nearstation) +"weW" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "wfC" = ( /obj/structure/chair/stool{ pixel_y = 8 @@ -61868,12 +65864,41 @@ /obj/item/assembly/signaler, /turf/open/floor/plating, /area/maintenance/bar) +"wfZ" = ( +/obj/machinery/computer/piratepad_control/civilian{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/cargo/office) +"wgo" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/structure/closet/firecloset, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"wgu" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Permabrig Maintenance"; + req_access_txt = "1" + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/maintenance/prison/port) "wig" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, /turf/open/floor/plasteel, /area/commons/fitness/pool) +"wiR" = ( +/obj/effect/landmark/event_spawn, +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/port/fore) "wjd" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/table, @@ -61902,6 +65927,15 @@ "wkN" = ( /turf/closed/wall, /area/science/circuit) +"wkU" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/security/prison/upper) "wlg" = ( /obj/structure/cable{ icon_state = "1-2" @@ -61934,6 +65968,15 @@ }, /turf/open/floor/plating, /area/engineering/main) +"wnX" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison/cells) "woR" = ( /obj/machinery/cryopod{ dir = 1 @@ -61954,6 +65997,22 @@ }, /turf/open/floor/plating, /area/construction/mining/aux_base) +"wpV" = ( +/obj/machinery/seed_extractor, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison/upper) "wql" = ( /turf/closed/wall/r_wall, /area/command/gateway) @@ -62075,6 +66134,31 @@ }, /turf/open/floor/plating, /area/maintenance/fore/secondary) +"wAj" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) +"wAN" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "wBd" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 @@ -62089,6 +66173,18 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"wGc" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "wHk" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -62113,6 +66209,13 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/starboard/fore) +"wIl" = ( +/obj/structure/bed, +/obj/effect/spawner/lootdrop/bedsheet, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plating, +/area/maintenance/prison/port) "wII" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/airlock/maintenance, @@ -62190,6 +66293,32 @@ icon_state = "platingdmg3" }, /area/maintenance/starboard/aft) +"wVq" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/door/airlock/grunge{ + name = "Prison Workshop"; + wiretypepath = /datum/wires/airlock/security + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) +"wVt" = ( +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "wVN" = ( /obj/structure/falsewall, /turf/open/floor/plating, @@ -62222,11 +66351,9 @@ /turf/open/floor/plasteel, /area/commons/fitness/pool) "wYc" = ( -/obj/machinery/vr_sleeper{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/structure/table, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "wYn" = ( /obj/structure/plasticflaps/opaque, /obj/structure/sign/poster/contraband/free_drone{ @@ -62281,6 +66408,20 @@ /obj/item/coin/gold, /turf/open/floor/plasteel, /area/commons/fitness) +"xbP" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "xcl" = ( /obj/structure/lattice, /obj/machinery/atmospherics/pipe/simple/dark/visible{ @@ -62301,6 +66442,13 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"xfW" = ( +/obj/machinery/vr_sleeper{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "xgk" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -62363,13 +66511,18 @@ /turf/open/floor/plating, /area/construction) "xib" = ( -/obj/machinery/door/window/westleft{ - base_state = "right"; - icon_state = "right"; - name = "Unisex Showers" +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "Prison Gate"; + name = "prison blast door" }, -/turf/open/floor/plasteel/freezer, -/area/security/prison) +/obj/structure/cable, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Prison Lockdown Shutters" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "xiw" = ( /obj/machinery/door/airlock{ name = "Service Hall"; @@ -62381,6 +66534,17 @@ }, /turf/open/floor/plating, /area/hallway/secondary/service) +"xjU" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/grunge{ + name = "Prison Visitation"; + wiretypepath = /datum/wires/airlock/security + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "xkd" = ( /obj/machinery/light/small{ dir = 4; @@ -62388,6 +66552,22 @@ }, /turf/open/floor/plasteel, /area/commons/fitness) +"xkk" = ( +/obj/machinery/door/firedoor, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/sign/warning/securearea{ + pixel_x = -32; + pixel_y = 32 + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Prison Lockdown Shutters" + }, +/turf/open/floor/plasteel/dark, +/area/security/range) "xlX" = ( /obj/structure/table/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -62415,6 +66595,21 @@ }, /turf/open/floor/plasteel, /area/security/brig) +"xnF" = ( +/obj/machinery/door/airlock/security{ + name = "Isolation Cell"; + req_access_txt = "2" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"xpH" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "xqG" = ( /obj/structure/table/reinforced, /obj/effect/turf_decal/tile/bar, @@ -62456,6 +66651,17 @@ }, /turf/open/floor/plasteel, /area/maintenance/disposal/incinerator) +"xuu" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Prison Lockdown Shutters" + }, +/turf/open/floor/plating, +/area/security/brig) "xwB" = ( /obj/structure/chair/stool{ pixel_y = 8 @@ -62514,6 +66720,13 @@ }, /turf/open/floor/plasteel, /area/commons/dorms) +"xAA" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "xBk" = ( /obj/structure/cable{ icon_state = "1-2" @@ -62530,6 +66743,16 @@ /obj/item/radio/headset/headset_cargo, /turf/open/floor/plasteel, /area/cargo/storage) +"xBJ" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) "xDM" = ( /obj/machinery/camera{ c_tag = "Locker Room South"; @@ -62574,6 +66797,12 @@ }, /turf/open/floor/wood/wood_large, /area/service/chapel/main) +"xFj" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "xFM" = ( /obj/item/clothing/gloves/color/rainbow, /obj/item/clothing/head/soft/rainbow, @@ -62581,6 +66810,20 @@ /obj/item/clothing/under/color/rainbow, /turf/open/floor/plating, /area/maintenance/port/fore) +"xGm" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/cells) "xGQ" = ( /obj/structure/sign/plaques/golden{ pixel_y = 32 @@ -62622,6 +66865,44 @@ }, /turf/open/floor/plating, /area/security/office) +"xKl" = ( +/obj/machinery/computer/security/telescreen/prison{ + pixel_y = 30 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison) +"xLQ" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/security/prison/upper"; + damage_deflection = 21; + desc = "A control terminal for the area's electrical systems. It's secured with a durable antitampering plasteel cage."; + dir = 1; + name = "Armored Upper Prison Wing APC"; + pixel_y = 23 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "xLX" = ( /obj/structure/lattice/catwalk, /obj/item/stack/marker_beacon{ @@ -62635,13 +66916,54 @@ }, /turf/open/floor/plating/airless, /area/space/nearstation) -"xOx" = ( -/obj/structure/chair/comfy/brown{ - color = "#596479"; - dir = 1 +"xMg" = ( +/obj/structure/chair{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) +"xMS" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) +"xNV" = ( +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "4-8" }, /turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/cells) +"xOx" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/flasher{ + id = "visitorflash"; + pixel_x = 16; + pixel_y = 24 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "xPk" = ( /obj/structure/bed, /obj/machinery/button/door{ @@ -62738,6 +67060,13 @@ }, /turf/open/floor/plasteel, /area/security/brig) +"xVZ" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/structure/lattice/catwalk, +/turf/open/space, +/area/solars/port/fore) "xWq" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/sign/warning/vacuum/external{ @@ -62752,6 +67081,13 @@ }, /turf/open/floor/plasteel/grimy, /area/maintenance/starboard/aft) +"xWS" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "xXi" = ( /obj/machinery/vending/clothing, /turf/open/floor/plasteel, @@ -62793,6 +67129,10 @@ /obj/item/seeds/ambrosia, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"ybb" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/security/prison/upper) "ycd" = ( /obj/structure/toilet/secret/low_loot{ dir = 4 @@ -62816,6 +67156,22 @@ }, /turf/open/floor/mineral/titanium/blue, /area/commons/toilet/locker) +"yco" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/security/prison/cells) +"ycL" = ( +/obj/effect/spawner/lootdrop/prison_contraband, +/obj/structure/closet/crate, +/obj/item/stack/license_plates/empty/fifty, +/obj/item/stack/license_plates/empty/fifty, +/obj/item/stack/license_plates/empty/fifty, +/obj/item/stack/license_plates/empty/fifty, +/turf/open/floor/plating, +/area/security/prison/upper) "ycY" = ( /obj/effect/turf_decal/tile/red{ dir = 1 @@ -62847,8 +67203,18 @@ /obj/machinery/status_display/evac, /turf/closed/wall, /area/hallway/primary/central) +"yeZ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/closed/wall/r_wall, +/area/security/execution/transfer) "yfX" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = -24 + }, /turf/open/floor/carpet/arcade, /area/commons/arcade) "ygb" = ( @@ -62874,6 +67240,14 @@ }, /turf/open/floor/plasteel/dark, /area/hallway/primary/central) +"yhI" = ( +/obj/machinery/computer/arcade/battle, +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/upper) (1,1,1) = {" cNd @@ -73028,7 +77402,7 @@ awW awZ aym azz -aAF +wgo awW aaa aaa @@ -73261,7 +77635,7 @@ apJ awZ aIK ayl -aAE +rla awW aaa aaa @@ -77076,12 +81450,6 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa aaS aaS aaS @@ -77097,9 +81465,15 @@ aaS aba aaS aaS +gXs +gXs +gXs +eRz +eRz +eRz aaf aaf -aaf +aaT aaf aaf alU @@ -77333,12 +81707,6 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa abY aaa aaf @@ -77351,7 +81719,7 @@ acy aaa aaf aaa -bXv +dLl aaa aaS aaa @@ -77359,6 +81727,12 @@ aaa aaa aaa aaa +gXs +aaa +aaa +aaa +aaa +aaa alU ash atU @@ -77590,31 +81964,31 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa abY aaa acW -acV +eTt adA aaa acW -acV +eTt adA aaa acW -acV +eTt adA aaa aaS +gXs +gXs +gXs +gXs +eRz +eRz aaf aaf -aaf -aaf +aaT +aaT aaf alU atn @@ -77844,33 +82218,33 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa aae aaa aaa abY aaf acW -adx +hcT adA aaa acW -adx +hcT adA aaa acW -adx +hcT adA aaf aaf aaa aaa aaa +gXs +aaa +ktS +aaa +aaa +gXs aaa aaa alU @@ -78104,30 +82478,30 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa abY aaa acW -adx +hcT adA aaf acW -adx +hcT adA aaf acW -adx +hcT adA aaa aaf aaa aaa aaa +gXs +aaa +ktS +aaa +aaa +gXs aaa aaa gXs @@ -78361,27 +82735,27 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa aaf aaf acW -adx +hcT adA aaa acW -adx +hcT adA aaa acW -adx +hcT adA aaf aaf +gXs +gXs +gXs +gXs +gXs +gXs aaf aaf aaf @@ -78398,7 +82772,7 @@ cCs ann ann hCn -arH +cwS ayh azi aAx @@ -78416,7 +82790,7 @@ aPz aPz aPz aPz -aSg +hmT aWj aXP aZr @@ -78615,32 +82989,32 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa aaS aaS aaS aaf aaa acW -adx +hcT adA aaa acW -adx +hcT adA aaa acW -adx +hcT adA aaa aaf aaa aaa +aaa +gXs +aaa +aaa +aaa +aaa ajV alR alR @@ -78872,29 +83246,29 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa aaS aaa aaf aaa aaa aaa -adZ +rwA aaa aaa aaa -adZ +rwA aaa aaa aaa -adZ +rwA aaa aaa +aaf +aaa +aaa +aaa +gXs +aaa ajV ajV ajV @@ -79129,18 +83503,12 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa aaS aaf -abs -abZ -abZ -adw +rYM +qhA +qhA +hSf ady ady ady @@ -79152,6 +83520,12 @@ ady ady cfK uDO +uDO +uDO +uDO +uDO +uDO +uDO ajq akB akB @@ -79386,29 +83760,29 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa aaS aaa aaf aaa aaa aaa -ajW +xVZ aaa aaa aaa -ajW +xVZ aaa aaa aaa -ajW +xVZ aaa aaa +aaf +aaa +aaa +aaa +gXs +aaa ajV ajV ajV @@ -79420,7 +83794,7 @@ anH oCF amC anJ -aFJ +wiR alU axK azG @@ -79643,32 +84017,32 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa aaS aba aaS aaf aaa acW -amv +pry adA aaa acW -amv +pry adA aaa acW -amv +pry adA aaa aaf aaa aaa +aaa +gXs +aaa +aaa +aaa +aaa ajV alR alR @@ -79903,30 +84277,30 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa aaf aaf acW -amv +pry adA aaa acW -amv +pry adA aaa acW -amv +pry adA aaf aaf aaa aaa aaa +gXs +aaa +aaa +aaa +aaa +aaa alU amF alF @@ -80160,27 +84534,27 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa aaS aaa acW -amv +pry adA aaf acW -amv +pry adA aaf acW -amv +pry adA aaa aaf +gXs +gXs +gXs +gXs +gXs +gXs aaf aaf aaf @@ -80417,30 +84791,30 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa aaS aaf acW -amv +pry adA aaa acW -amv +pry adA aaa acW -amv +pry adA aaf -aaf +aba aaa aaa aaa +aaa +aaa +aaa +quT +aaa +aaa alU alU alU @@ -80474,7 +84848,7 @@ aQN aTB aQN aWq -aQN +bft aWq aUt aQN @@ -80674,30 +85048,30 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa aaS aaa acW -aqJ +rGZ adA aaa acW -aqJ +rGZ adA aaa acW -aqJ +rGZ adA aaa aaS aaa aaa aaa +aaa +aaa +aaa +eRz +aaa +aaa alU lLA mzT @@ -80738,7 +85112,7 @@ aQN fRe qSo aPA -bgt +hmT bhS bjk aPz @@ -80918,18 +85292,12 @@ cNd cNd cNd cNd +naI cNd cNd cNd cNd cNd -cNd -aaa -aaa -aaa -aaa -aaa -aaa aaa aaa aaa @@ -80952,7 +85320,13 @@ aaa aaf aaa aaS -aaf +gXs +gXs +gXs +gXs +quT +eRz +aaT aaf aaf alU @@ -81183,17 +85557,11 @@ cNd cNd aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +gXs +gXs +gXs +gXs +gXs aaS aaS aaS @@ -81212,6 +85580,12 @@ aaS aaa aaa aaa +gXs +aaa +aaa +aaa +aaa +aaa alU enJ enJ @@ -81225,7 +85599,7 @@ alU alU alU alU -ntt +cPO amC avW gYo @@ -81446,6 +85820,7 @@ aaa aaa aaa aaa +gXs aaa aaa aaa @@ -81453,17 +85828,16 @@ aaa aaa aaa aaa +gXs aaa aaa aaa aaa +gXs aaa aaa aaa -aaa -aaa -aaa -aaa +gXs aaa aaa aaa @@ -81703,6 +86077,7 @@ aaa aaa aaa aaa +gXs aaa aaa aaa @@ -81710,23 +86085,22 @@ aaa aaa aaa aaa +gXs +aaa +aaa +aaa +aaa +gXs +aaa +aaa +aaa +gXs aaa aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -jFd +ali fDn gFs aKY @@ -81955,6 +86329,12 @@ aaa aaa aaa aaa +gXs +gXs +gXs +gXs +gXs +gXs aaa aaa aaa @@ -81962,22 +86342,16 @@ aaa aaa aaa aaa +gXs aaa aaa aaa aaa +quT aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +gXs aaa aaa aaa @@ -82212,29 +86586,29 @@ aaa aaa aaa aaa +gXs aaa aaa aaa aaa +gXs +aaa +aaa +aaa +eRz +eRz +eRz +quT +gXs aaa aaa aaa aaa +eRz aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +quT aaa aaa aaa @@ -82469,29 +86843,29 @@ aaa aaa aaa aaa +gXs aaa aaa aaa aaa +gXs +aaa +aaa +aaa +eRz +aaa +aaa +aaa +gXs aaa aaa aaa aaa +eRz aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +eRz aaa aaa aaa @@ -82722,32 +87096,32 @@ aaa aaa aaa aaa +gXs +gXs +gXs +aaa +gXs aaa aaa aaa aaa +gXs aaa aaa aaa +eRz aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +gXs +gXs +gXs +gXs +gXs +eRz +gXs +gXs +gXs ali ali alU @@ -82805,7 +87179,7 @@ bjr cBp bjr buB -bvV +iyK bxu bxu bxx @@ -82978,33 +87352,33 @@ cNd aaa aaa aaa +eRz +eRz +eRz +eRz +eRz +eRz +eRz +eRz +eRz +eRz +eRz +aaa +aaa +aaa +quT +aaa +aaa +aaa +gXs aaa aaa aaa aaa +wbw aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aae -aaa -aaa ali anL avY @@ -83234,31 +87608,31 @@ cNd cNd aaa aaa +gXs +eRz +aaa +gXs aaa aaa +gXs aaa aaa +gXs +aaa +gXs +gXs +gXs +gXs +gXs +gXs +gXs +gXs +gXs +aaa +aae aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +jge aaa aaa aaa @@ -83491,6 +87865,18 @@ cNd cNd aaa aaa +gXs +eRz +aaa +aaa +aaa +aaa +gXs +gXs +aaa +gXs +aaa +gXs aaa aaa aaa @@ -83498,31 +87884,19 @@ aaa aaa aaa aaa +gXs aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +jge aaa aaa aaa ali aoo avY -amC +vPd gsM sCa aoX @@ -83749,33 +88123,33 @@ cNd aaa aaa aaa +eRz aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +rcV +szn +hKo +fNB +szn +qLo +mJH +szn +szn +szn +szn +szn +szn +mbC +mbC +mbC +mbC +mbC +hEL +mbC +mbC +jge +gXs +gXs +gXs ali ali alU @@ -83803,7 +88177,7 @@ wUr mzB uSc wHm -qTG +bgc aJe aKw aLE @@ -83996,44 +88370,44 @@ cNd cNd cNd cNd +cNd +cNd +cNd +cNd aaa aaa aaa aaa +gDl +aaa +eRz +gXs +gXs +szn +suC +qZT +dYQ +lGm +pwF +lJA +mvV +tso +lJA +mvV +tso +abc +hvJ +dIZ +abc +jvO +sNg +hJP +mbC +jge aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +pta aaa aaa aaa @@ -84114,7 +88488,7 @@ bCq bVE bWz bHE -bHE +nkP bLu bCq bLu @@ -84253,44 +88627,44 @@ cNd cNd cNd cNd +cNd +cNd +cNd +cNd +aaa +gXs aaa aaa aaa aaa +eRz aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +szn +mAT +ifM +wnX +mAT +mAT +lJA +giE +rBK +lJA +fgy +hWm +abc +obs +rBY +abc +rgu +fbr +mCm +mbC +mbC +gXs +gXs +gXs +jge aaa aaa aaa @@ -84510,44 +88884,44 @@ cNd cNd cNd cNd +cNd +cNd +cNd +cNd aaa +gXs aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +fIs +fIs +fIs +eRz +gXs +gXs +szn +lJA +czP +iCN +lJA +lJA +lJA +ewG +eoJ +lJA +lEf +ejr +abc +tJE +hEL +abc +tYd +cRq +gcX +jKj +mbC +abu +abu +abu +mbC aaa aaa aaa @@ -84587,7 +88961,7 @@ aTH aPK aWz aWC -baS +ihR baS baS bcR @@ -84767,44 +89141,44 @@ cNd cNd cNd cNd +cNd +cNd +cNd +cNd +aaa +gXs +gXs +fIs aaa aaa +gXs aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +gXs +kma +fdJ +hch +reE +tdd +cJA +tOk +knA +vws +tkx +epj +lDm +xnF +pFj +kcB +gyy +mCo +vCS +nZh +pRi +rsn +qIW +aca +ebo +yeZ aaa aaa aaa @@ -84844,7 +89218,7 @@ aTJ aPK aWA aWC -baS +aDW aZI baS cCn @@ -85026,42 +89400,42 @@ cNd cNd aaa aaa +eRz +eRz +eRz +eRz +eRz +eRz +gXs +gXs +gXs aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aae -aaa -aaa -aaa -aaa +gXs +yco +lZp +qgj +lYI +hzC +ggT +fdR +qwA +oqf +wcS +pFt +lAD +lJA +lJA +lJA +lJA +ili +waX +mCo +eRS +naj +liJ +acc +rAW +abe aaa aaa aaa @@ -85283,42 +89657,42 @@ cNd cNd aaa aaa +eRz +aaa +gXs +gXs aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +adI +oUF +eCB +adI +qCc +qCc +wgu +qCc +qCc +qCc +lvw +gMB +lJA +tnH +wVt +gSj +vYF +txs +lJA +jKc +mjJ +eJu +eSJ +qNU +moe +acb +gcm +tqk aaa aaa aaa @@ -85540,42 +89914,42 @@ cNd cNd aaa aaa +eRz aaa aaa +gXs +aaa +gXs aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -jLv -aaa -aaa -aaa -gWo -gWo -gWo -dYZ -gWo -gWo +adI +hzs +evh +ycL +qCc +rUr +jlQ +gZT +hQw +qCc +kcR +hWm +lJA +weW +xNV +gxK +dJu +fbY +lJA +abd +khO +enB +enB +enB +enB +enB +enB +sKA gXs gXs gXs @@ -85624,13 +89998,13 @@ aZH aZK bhZ aZK -cNM +jiT bfQ bnG bnz bpA bbR -sWR +gkP jlm bud eyM @@ -85797,42 +90171,42 @@ cNd cNd aaa aaa +sMu aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -abc -abc -abc +adI +xWS +adI +xWS +adI +adI +lCt +qcU +vRN +qCc +icS +mqQ +qYa +wIl +qCc +sfz +tbR +lJA +ryi +cCr +lJA +lJA +lJA +lJA +noJ +uql afu -abc +acd wdr itQ pgn tmO -gWo +sXV xUe aiU aiT @@ -85865,7 +90239,7 @@ aKc aLp aMV aOy -aLE +pgl aPQ aRV aSW @@ -86054,42 +90428,42 @@ cNd cNd aaa aaa +eRz aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -abc -aea -aeH -aft -abc +oUF +llb +eXI +gLu +vwQ +acG +hzs +hnp +jVV +qCc +qCc +qCc +qCc +qCc +qCc +acG +acG +lJA +maP +lHK +nRO +vYF +txs +lJA +ksa +dQS +afu +acd pDe dly mnC mcp -gWo +sXV oDm ibK akb @@ -86145,7 +90519,7 @@ boR bqs bbR bkM -bbR +fCV bwd bxB bvL @@ -86311,38 +90685,38 @@ cNd cNd aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +eRz aaa gXs -gXs -gXs -abc -abu -abu -abu -abc -abc -aec -aeJ +adI +lNQ +eDF +jYl +lUU +acG +acG +aaW +wVq +acG +qFK +jRW +dLi +evc +qto +pGA +acG +mnu +xGm +xNV +oTx +nko +vFZ +lJA +noJ +uql afw -abc -abc +acd +acd dly xxp mcp @@ -86402,7 +90776,7 @@ boT bbR bbR buI -bbR +wfZ bwd bxD byL @@ -86416,7 +90790,7 @@ bHD bJe bCq nkP -bHE +nzX bHE bHE bHE @@ -86465,7 +90839,7 @@ aaa aaa iDo ctv -aaT +iDo aaa aaa aaa @@ -86568,42 +90942,42 @@ cNd cNd aaa aaa +eRz aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aae -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -gXs -aai -aai -aai +oUF +iMy +cTo +ltm +kkb +xfW +ybb +kMn +rDc +grd +wpV +tYg +tAS +sAm +jrR +teq +acG +cVE abb abt -aca -acz -acX -adC -aeb -aeI +lJA +lJA +lJA +lJA +noJ +uql afv agf -abc +acd dly xxp mcp -gWo +sXV gDP lAH lNH @@ -86722,7 +91096,7 @@ aaa aaa iDo iDo -aaT +iDo aaa aaa aaa @@ -86825,38 +91199,38 @@ cNd cNd aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aai -eqd +eRz +gXs +gXs +adI +mwN +kfG +uJY +vhC +tLC +ybb +uLB +kGj +acG +lux +gPY +ktW +qQK +uuw +dPs +acG kgr -abe -abw -acc -acB -acZ -adE -aee +nFA +wVt +pZD +vYF +tCs +lJA +pIR aeL afy agh -abc +acd kCa hnU vda @@ -87081,39 +91455,39 @@ cNd cNd cNd aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa gXs -aai -gbu +eRz +aaa +aaa +oUF +xFj +jKm +cYf +kkb +tAS +pgq +peD +sBM +acG +aaN +jOB +acG +acG +acG +acG +acG aay -abd +oss abv -acb +pPE acA acI adD aed -aeK -afx +wGc +afv agg -abc +acd ovv dCV idK @@ -87338,39 +91712,39 @@ cNd cNd cNd aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaf -aaf -aai -acd +gXs +sMu +gXs +gXs +adI +adI +yhI +lLu +dLZ +vYY +mui +gcV +lic +aau +xbP +mHH +fMF +ueN +iqi +fKN +acG mIZ abg -enB -aby -aby -aby -aby +lJA +lJA +lJA +lJA +lJA aeg -aeN +ryN afA -afA -abc +acd +acd kuA laq kdP @@ -87593,41 +91967,41 @@ cNd cNd cNd cNd -cNd +gXs +gXs +gXs +eRz aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaf -aaf -aaf -aai -aai +oUF +vim +kYm +mke +hpY +obq +fiR +dPE +pTT +jIH +rqq +acG +mxZ +xMS +pnb abf aaK jRw aaU -acd +eDJ acC ada adF aef aeM -afz -oSl -ail +aav +ldY +xkk lRb vIi fsj @@ -87853,36 +92227,36 @@ cNd cNd aaa aaa +eRz aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aag +rcV +adI +adI +adI +acG +acG +acG +lBk +jxx +acG thB -aai -aai -aai -aai +rqq +acG +acG +jTy aaI -aat -aat -aat -aat +acG +gXu +wAN +ruu ace -aat +ref aat adH -aei -aeO -afJ +aem +ikv +adp sXV sXV sXV @@ -87898,7 +92272,7 @@ nbY aiX iRj anz -aov +kbO cCi apU ajd @@ -88110,35 +92484,35 @@ cNd cNd aaa aaa +eRz +eRz +gXs aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aag -aaf -aai +gXs +adI +msp +pHK +wkU +sNj +efs +acG +sAT +rqq aan -aaw -aaB -qmn -aaJ -aat +acG +acG +acG +acG +xLQ abh -aat acd +ozh abK acY -adG +acd aeh -aeO +lJS ado afq afH @@ -88368,31 +92742,31 @@ cNd aaa aaa aaa +eRz aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aag -aaa +xWS +gcY +oVL +dSh +xBJ +fMY +acG +pUf aam aap -saX +aau aaD aau -aat -aat -aat +vMi +oKB +vhy abA -acd -acd -acd +jNN +jRV +hkA acd aek acp @@ -88625,32 +92999,32 @@ cNd aaa aaa aaa +eRz +eRz +eRz aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aag -aaf -aai +uKW +tAS +jCV +eoR +tAS +ooF +acG +viH +siz aao aax aaC aaA -aat -aat -aat +ngq +tWe +jHp aei -acd +fFR acE add -adF +acd aej aeQ adp @@ -88882,36 +93256,36 @@ cNd aaa aaa aaa +gXs aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aag -aaa -aam -aar +eRz +gXs +gXs +uKW +oIl +jCV +eoR +ecB +dnX +acG +acG +mZu +acG uGI aaF -aat -aat +qbk +ske aaW -aat -abB -acf -abM +xjU acG -adI -aem +acG +acG +acG +acG +xKl omX afG -aim +xuu afL ahu aie @@ -89139,32 +93513,32 @@ cNd aaa aaa aaa +gXs +aaa +eRz aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aag -aaf -aai -aaq +uhK +xAA +jSY +hxg +acK +ssc +acG +uOm +nLP +acG dyS aaE -aat +aaN aaN aaV rvS -aat -acd +etr +tyb abL adb -acd +acG ael aeO afF @@ -89396,35 +93770,35 @@ cNd aaa aaa aaa +gXs +aaa +eRz aaa aaa -aaa -aaa -aae -aaa -aaa -aaa -aaa -aaa -aaa -aag -aaa -aam -aaj -aat -aat -aat +adI +oIl +uUb +eZI +qZQ +dNP +acG +hJO +mpY +acG +szf +rDm +gVc qXg -jjC +acG xOx -abD -acd -acd -acd -acd +oPY +ncU +lvc +epG +acG aen aeO -ahE +afG afq aii afM @@ -89471,7 +93845,7 @@ aPR aWL aPR aZM -bbX +lOe bay bbM bcN @@ -89653,32 +94027,32 @@ cNd aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aag -aaf -aai -aas -aat -aat -aat -aat -uEI -aat -abC -acd +gXs +gXs +eRz +gXs +gXs +adI +jnk +emf +vHK +vHK +vHK +vHK +vHK +acG +acG +fdS +qRI +jvB +iwU +acG +ltw +eDf +oXV acH adc -acd +acG aeo aev aeS @@ -89912,34 +94286,34 @@ aaa aaa aaa aaa +eRz aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aag -aaa -aam -akQ -aav -aav -aav -aav -aav -aav +jnk +qOY +pBd +kGL +fcj +jqK +vHK +rTj +rTj +goJ +kLK +rTj +hvC +acG +oiY abE acg acJ -ade +adb adJ aep aeT -ahE -aim +afG +xuu ajL akj afM @@ -90169,30 +94543,30 @@ aaa aaa aaa aaa +eRz aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aag -aaf -aai -wYc -wYc +jnk +sIn +eZS +iBj +pGs +iBq +vHK +dCd +aaP +xpH aaG wYc aaP -aaX +acG keM xib -acd +acG acD -acY -adG +cNi +acG aeq aeV agj @@ -90426,30 +94800,30 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aag -aaa -aai -aai -aai -aai -aai -aai -aai +eRz +eRz +gXs +gXs +jnk +jnk +jnk +jnk +vHK +vHK +vHK +xMg +tPY +ugi +lht +jVP +tPY +acG abj abF -acd -acd -acd -acd +eIW +mJy +ldT +cSp aeP afC agk @@ -90684,29 +95058,29 @@ aaa aaa aaa aaa +eRz aaa aaa +gXs aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaf -aaf -aaa -aaf -aai +gXs +adI +olH +mte +lpx +nZs +nZs +nZs +sYV +nZs +maU +acG abi eqA ach -acK +wAj adf -acd +mhv aer afB agi @@ -90939,31 +95313,31 @@ aaa aaa aaa aaa +gDl +aaa +eRz aaa aaa +gXs aaa aaa -aaa -aaa -aaa -aaa -aaa -aaf -aaf -aaf -aaf -aaf -aaf -aaf -aaf +adI +noR +nSI +sHd +tAS +tHO aaR -aai -aai -aai -aai -aai -aai -aai +jUN +peE +aaR +adI +adI +adI +adI +adI +adI +adI aaZ aaZ aiX @@ -91198,23 +95572,23 @@ aaa aaa aaa aaa +eRz +eRz +eRz +eRz aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaf -aaa -aaf -aaf +adI +sew +suS +qvc +adb +kOE +dxv +fmR +dzK +adb +adI aaT aaf abx @@ -91273,8 +95647,8 @@ aZR aZR aZR aZR -aZR -bft +grS +nVz wZI gDO aBW @@ -91456,22 +95830,22 @@ aaa aaa aaa aaa +gXs +gXs +eRz aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaf -aaa -aaf -aaf +rcV +adI +adI +adI +adI +oUF +gfw +adI +adI +nqu +uZY +adI aaT gXs abG @@ -91714,21 +96088,21 @@ aaa aaa aaa aaa +gXs +eRz aaa aaa aaa aaa +gXs aaa aaa aaa aaa +gXs aaa +gXs aaa -aaa -aaf -aaa -aaf -aaf abY gXs abG @@ -91968,24 +96342,24 @@ aaa aaa aaa aaa +gXs +gXs +gXs +gXs +eRz +aaa +gXs +aaa +aaa +gXs aaa aaa aaa aaa +gXs aaa +gXs aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaf -aaa -aaf -aaf aaT gXs abG @@ -92229,18 +96603,18 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaf -aaa +eRz +eRz +eRz +eRz +eRz +eRz +eRz +eRz +eRz +eRz +aaT +eRz aaf aaf aaT @@ -92296,7 +96670,7 @@ aSA aTX aVm aWU -aYy +aYB aZR aZR aZR @@ -92488,18 +96862,18 @@ aaa aaa aaa aaa +gXs +gXs +gXs +gXs +gXs aaa -aaa -aaa -aaa -aaa -aaa -aaa +gXs aaa aaf aaa aaf -aaf +ktS abY gXs abG @@ -92746,17 +97120,17 @@ aaa aaa aaa aaa +gXs +aaa +gXs aaa aaa -aaa -aaa -aaa -aaa +gXs aaa aaf aaa aaf -aaf +ktS adR abo adR @@ -93003,17 +97377,17 @@ aaa aaa aaa aaa +gXs +aaa +gXs aaa aaa -aaa -aaa -aaa -aaa +gXs aaa aaf aaa aaf -aaf +ktS adR aaY abJ @@ -93053,7 +97427,7 @@ atf dgz tqg ujF -ujF +bfG ujF dgz aaa @@ -93262,15 +97636,15 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa +gXs +gXs +gXs +gXs aaf aaf aaf aaf -aaa +gXs abo abk abk @@ -93331,7 +97705,7 @@ bch bdi bbw bfy -bbw +eVW bik aZV aZV @@ -93519,7 +97893,7 @@ aaa aaa aaa aaa -aaa +gXs aaa aaa aaa @@ -93776,7 +98150,7 @@ aaa aaa aaa aaa -aaa +gXs aaa aaa aaa @@ -93784,7 +98158,7 @@ aaa aaa aaa aaf -aaa +gXs abo abO abO @@ -94033,7 +98407,7 @@ aaa aaa aaa aaa -aaa +gXs aaa aaa aaa @@ -94290,11 +98664,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +gXs +gXs +gXs +gXs +gXs aaf aaf aaf @@ -95369,7 +99743,7 @@ aDM aGx aDM aDM -aDM +biC aAh aMm aJq @@ -95616,7 +99990,7 @@ arf arf arf arf -ltK +aYy axP azb aAi @@ -97657,7 +102031,7 @@ uhm ahn aiA ahn -grc +odV anE aod ahn @@ -98216,7 +102590,7 @@ bet bfH aiP wbE -ihR +bhh wbE bmJ bof @@ -98470,12 +102844,12 @@ bby aYV aYV bet -bfG +rUe bhe bit bjS tCd -eRr +bli boe bli bpN @@ -98727,9 +103101,9 @@ aJC aYV aYV bet -bfG +rUe bhe -ihR +bhh bjU blk blk @@ -98984,9 +103358,9 @@ aJC bcr aYV bet -bfG +rUe bhe -ihR +bhh bjV blj bmK @@ -99242,8 +103616,8 @@ aYV bdo beu bvk -jiT -jiT +biu +biu bjT blm bmL @@ -99255,7 +103629,7 @@ btX bof bwG bxR -bxR +dGh bof bof bzW @@ -99493,14 +103867,14 @@ aSZ aQc qaY acN -aKR +fzx aJC aYV aYV bet -qnC -ihR -ihR +bfJ +bhh +bhh bgQ bll bhh @@ -99757,8 +104131,8 @@ aYV bet bfH qTV -ihR -uBr +bhh +bhg bln bmM boj @@ -100767,10 +105141,10 @@ alP aGL aIe bhr -bhr -bhr -bhr -bhr +aJI +aJI +aJI +aJI aJI aRC aSK @@ -101023,7 +105397,7 @@ aaa alP aGN aIh -bhr +aJI aKT aMD aNM @@ -101537,7 +105911,7 @@ aaa alP aGL aHY -biC +aQj iNn aMk aNK @@ -102051,9 +106425,9 @@ vpY alP aGJ avI -bhr -bhr -bhr +aJI +aJI +aJI aNO aOT aJI @@ -102310,9 +106684,9 @@ aGJ avI aJL aKX -bhr -bhr -bhr +aJI +aJI +aJI aJI aRH aVz @@ -103101,7 +107475,7 @@ tIE dnW jdE nyi -cTO +qnC bmZ bpG bqZ @@ -103890,7 +108264,7 @@ bFH bHb bIw bBN -bKT +jNT bMb bNd bOt @@ -105656,7 +110030,7 @@ qfD aRO aQp aRN -aIt +hIi aUB aFu aVN @@ -106924,7 +111298,7 @@ alP anf anf alP -anf +hyY anf apE anf @@ -106960,7 +111334,7 @@ blG biL cHV cIa -biL +jYI box buo bvc @@ -109250,7 +113624,7 @@ aFw aFw aFw aFw -aFz +eRr aPk aQu aPk @@ -111328,7 +115702,7 @@ pKV pKV pKV bpp -pKV +bqe brr bsE bvK @@ -111373,7 +115747,7 @@ clt cQw cCt cOe -cOe +cmo cNW aaa aaS @@ -111585,7 +115959,7 @@ biY bmd bnr bpr -bgc +bqe btj buu bvM @@ -111841,8 +116215,8 @@ bhG blO bmc bnq -bgc -bgc +bqe +bqe bru bsF btY @@ -112631,7 +117005,7 @@ bKc cNW bMB bNA -cOe +cmo bSl bUq flc diff --git a/_maps/map_files/CogStation/CogStation.dmm b/_maps/map_files/CogStation/CogStation.dmm index 25598ac9a1..2135803d28 100644 --- a/_maps/map_files/CogStation/CogStation.dmm +++ b/_maps/map_files/CogStation/CogStation.dmm @@ -858,7 +858,7 @@ /turf/open/floor/plating/airless, /area/router/aux) "acf" = ( -/obj/machinery/computer/arcade/minesweeper, +/obj/machinery/computer/arcade/battle, /turf/open/floor/carpet/arcade, /area/commons/arcade) "acg" = ( @@ -4505,7 +4505,7 @@ /area/maintenance/solars/starboard/fore) "alg" = ( /obj/structure/frame/machine, -/obj/item/circuitboard/computer/arcade/minesweeper, +/obj/item/circuitboard/computer/arcade/orion_trail, /turf/open/floor/plating, /area/construction/secondary) "alh" = ( @@ -8805,12 +8805,11 @@ /obj/effect/turf_decal/tile/blue{ dir = 1 }, -/obj/machinery/sleeper{ - dir = 8 - }, /obj/machinery/airalarm{ pixel_y = 24 }, +/obj/structure/table, +/obj/item/stack/medical/suture/five, /turf/open/floor/plasteel/white, /area/medical/clinic) "auS" = ( @@ -8876,9 +8875,7 @@ name = "Station Intercom (Common)"; pixel_y = 26 }, -/obj/machinery/sleep_console{ - dir = 8 - }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/clinic) "auZ" = ( @@ -9962,6 +9959,7 @@ /area/security/prison) "axk" = ( /obj/item/storage/pill_bottle/penis_enlargement, +/obj/effect/landmark/start/prisoner, /turf/open/floor/plasteel/freezer, /area/security/prison) "axl" = ( @@ -21247,9 +21245,6 @@ /turf/open/floor/plasteel/dark/side, /area/security/courtroom) "aUF" = ( -/obj/machinery/computer/bounty{ - dir = 1 - }, /turf/open/floor/carpet/green, /area/command/heads_quarters/hop) "aUG" = ( @@ -26771,7 +26766,6 @@ /turf/open/floor/engine, /area/engineering/teg) "bgS" = ( -/obj/machinery/computer/bounty, /obj/effect/turf_decal/tile/brown{ dir = 4 }, @@ -27427,6 +27421,9 @@ dir = 1; pixel_y = -22 }, +/obj/machinery/computer/piratepad_control/civilian{ + dir = 1 + }, /turf/open/floor/plasteel, /area/cargo/office) "bis" = ( @@ -29096,9 +29093,6 @@ /turf/open/floor/plasteel, /area/cargo/sorting) "blR" = ( -/obj/machinery/computer/bounty{ - dir = 4 - }, /obj/effect/turf_decal/tile/brown{ dir = 8 }, @@ -36750,9 +36744,6 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/item/storage/box/engineer{ - pixel_y = 4 - }, /turf/open/floor/plasteel, /area/maintenance/disposal) "bCu" = ( @@ -49205,6 +49196,9 @@ c_tag = "Robotics Lab"; dir = 4 }, +/obj/machinery/posialert{ + pixel_x = -32 + }, /turf/open/floor/plasteel/dark/side{ dir = 8 }, @@ -57325,7 +57319,7 @@ name = "Chief Engineer's RC"; pixel_y = -32 }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel, /area/command/heads_quarters/ce) "csf" = ( @@ -58025,6 +58019,7 @@ /obj/effect/turf_decal/tile/brown, /obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/structure/disposalpipe/segment, +/obj/machinery/piratepad/civilian, /turf/open/floor/plasteel, /area/cargo/office) "ctx" = ( @@ -58339,9 +58334,7 @@ dir = 4 }, /obj/structure/window/reinforced/spawner/east, -/obj/machinery/sleeper{ - dir = 8 - }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/medbay/zone2) "cua" = ( @@ -71005,6 +70998,11 @@ /obj/machinery/atmospherics/pipe/simple/violet/visible, /turf/open/floor/plasteel, /area/engineering/atmos) +"kTm" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/start/prisoner, +/turf/open/floor/plating, +/area/security/prison) "lcD" = ( /obj/machinery/atmospherics/components/unary/thermomachine/freezer{ dir = 1 @@ -71078,6 +71076,11 @@ /obj/machinery/atmospherics/pipe/simple/orange/hidden, /turf/open/floor/plasteel, /area/tcommsat/computer) +"mTf" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/start/prisoner, +/turf/open/floor/plasteel, +/area/security/prison) "nvn" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 @@ -95879,7 +95882,7 @@ adE aew afG agP -agP +kTm aiL ajT anu @@ -95894,7 +95897,7 @@ aHT aJt aJN aQg -akv +mTf aew ayU aSQ @@ -96395,7 +96398,7 @@ afY agP agP aiL -akv +mTf anw akv akv diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 2108c61d32..506f5e2396 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -2619,9 +2619,8 @@ /turf/closed/wall/r_wall, /area/space/nearstation) "ajs" = ( -/obj/structure/table, -/obj/item/storage/briefcase, /obj/effect/turf_decal/delivery, +/obj/machinery/vending/kink, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "ajt" = ( @@ -2880,15 +2879,17 @@ "ajR" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/delivery, -/obj/item/kirbyplants{ - icon_state = "plant-21" - }, +/obj/structure/table, +/obj/item/storage/briefcase, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "ajS" = ( /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/item/kirbyplants{ + icon_state = "plant-21" + }, /turf/open/floor/plasteel/cafeteria, /area/hallway/secondary/entry) "ajT" = ( @@ -3715,6 +3716,7 @@ "alM" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/delivery, +/obj/structure/loot_pile/maint, /turf/open/floor/plasteel, /area/maintenance/starboard/fore) "alN" = ( @@ -8243,6 +8245,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/loot_pile/maint, /turf/open/floor/plasteel, /area/maintenance/port/fore) "aCE" = ( @@ -10552,6 +10555,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 4 }, +/obj/effect/landmark/start/prisoner, /turf/open/floor/plasteel, /area/security/prison) "aMj" = ( @@ -12412,6 +12416,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/effect/landmark/start/prisoner, /turf/open/floor/plasteel, /area/security/prison) "aUx" = ( @@ -12458,6 +12463,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/effect/landmark/start/prisoner, /turf/open/floor/plasteel, /area/security/prison) "aUA" = ( @@ -12486,6 +12492,7 @@ /area/security/prison) "aUB" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/landmark/start/prisoner, /turf/open/floor/plating{ icon_state = "panelscorched" }, @@ -13709,8 +13716,8 @@ }, /turf/open/floor/plating{ initial_gas_mix = "o2=0.01;n2=0.01"; - luminosity = 2; - initial_temperature = 2.7 + initial_temperature = 2.7; + luminosity = 2 }, /area/security/prison) "ban" = ( @@ -14372,8 +14379,8 @@ }, /turf/open/floor/plating{ initial_gas_mix = "o2=0.01;n2=0.01"; - luminosity = 2; - initial_temperature = 2.7 + initial_temperature = 2.7; + luminosity = 2 }, /area/security/prison) "bdo" = ( @@ -14441,9 +14448,6 @@ /turf/closed/wall, /area/hallway/primary/fore) "bdO" = ( -/obj/structure/table, -/obj/item/paper_bin, -/obj/item/pen, /obj/machinery/light{ dir = 8 }, @@ -14460,20 +14464,19 @@ /obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/machinery/computer/piratepad_control/civilian, /turf/open/floor/plasteel, /area/hallway/primary/fore) "bdP" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/disposalpipe/segment, -/obj/item/kirbyplants{ - icon_state = "plant-21" - }, /obj/effect/turf_decal/tile/brown{ dir = 1 }, /obj/effect/turf_decal/tile/brown{ dir = 4 }, +/obj/machinery/piratepad/civilian, /turf/open/floor/plasteel, /area/hallway/primary/fore) "bdQ" = ( @@ -31961,6 +31964,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 1 }, +/obj/structure/loot_pile/maint, /turf/open/floor/plasteel, /area/maintenance/starboard) "clv" = ( @@ -35120,6 +35124,7 @@ "cuI" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/red, +/obj/structure/loot_pile/maint, /turf/open/floor/plasteel, /area/maintenance/starboard) "cuJ" = ( @@ -36306,6 +36311,12 @@ }, /turf/open/floor/plasteel, /area/maintenance/port) +"cCK" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/port/aft) "cCM" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -36403,8 +36414,8 @@ /turf/open/floor/plating, /area/maintenance/port) "cEA" = ( -/obj/effect/turf_decal/vg_decals/atmos/carbon_dioxide, -/turf/open/floor/engine/co2, +/obj/effect/turf_decal/vg_decals/atmos/air, +/turf/open/floor/engine/air, /area/engineering/atmos) "cFF" = ( /turf/open/floor/engine{ @@ -38003,6 +38014,7 @@ /obj/machinery/light/small{ dir = 8 }, +/obj/structure/loot_pile/maint, /turf/open/floor/plating, /area/maintenance/port) "cLM" = ( @@ -38748,6 +38760,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/loot_pile/maint, /turf/open/floor/plasteel, /area/maintenance/starboard/aft) "cNJ" = ( @@ -43274,6 +43287,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/item/kirbyplants/random, /turf/open/floor/plasteel/white, /area/medical/storage) "cWx" = ( @@ -46140,8 +46154,7 @@ }, /obj/effect/turf_decal/delivery, /obj/machinery/atmospherics/components/binary/valve/digital{ - dir = 8; - icon_state = "dvalve_map-2" + dir = 8 }, /turf/open/floor/plasteel, /area/science/xenobiology) @@ -46894,12 +46907,10 @@ dir = 4; pixel_x = -23 }, -/obj/machinery/sleeper{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 6 }, +/obj/machinery/stasis, /turf/open/floor/plasteel, /area/medical/abandoned) "ddn" = ( @@ -47543,10 +47554,10 @@ /turf/open/floor/plating, /area/security/checkpoint/medical) "deC" = ( -/obj/machinery/sleeper{ +/obj/effect/turf_decal/stripes/end{ dir = 4 }, -/obj/effect/turf_decal/stripes/end{ +/obj/machinery/sleeper{ dir = 4 }, /turf/open/floor/plasteel, @@ -47568,12 +47579,10 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "deF" = ( -/obj/machinery/sleeper{ - dir = 8 - }, /obj/effect/turf_decal/stripes/end{ dir = 8 }, +/obj/machinery/stasis, /turf/open/floor/plasteel, /area/medical/medbay/central) "deG" = ( @@ -50073,6 +50082,9 @@ /obj/effect/turf_decal/tile/purple{ dir = 4 }, +/obj/machinery/airalarm{ + pixel_y = 23 + }, /turf/open/floor/plasteel/white, /area/science/misc_lab) "djz" = ( @@ -50923,6 +50935,9 @@ /obj/effect/turf_decal/tile/purple{ dir = 8 }, +/obj/machinery/light_switch{ + pixel_x = -26 + }, /turf/open/floor/plasteel/white, /area/science/misc_lab) "dln" = ( @@ -53765,6 +53780,9 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/blue, +/obj/item/wallframe/light_fixture/small{ + pixel_y = -15 + }, /turf/open/floor/plasteel, /area/maintenance/department/medical) "dss" = ( @@ -53995,22 +54013,16 @@ /turf/closed/wall, /area/medical/surgery) "dsN" = ( -/obj/item/clothing/gloves/color/latex, -/obj/item/clothing/suit/apron/surgical, -/obj/item/clothing/mask/surgical, -/obj/item/surgical_drapes, -/obj/structure/table/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /obj/effect/turf_decal/tile/blue{ dir = 1 }, +/obj/structure/closet/secure_closet/medical2, /turf/open/floor/plasteel/white, /area/medical/surgery) "dsO" = ( -/obj/item/retractor, -/obj/item/hemostat, /obj/structure/table/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -54022,14 +54034,16 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/item/clothing/gloves/color/latex{ + pixel_y = 10 + }, +/obj/item/clothing/suit/apron/surgical, +/obj/item/clothing/mask/surgical{ + pixel_y = -6 + }, /turf/open/floor/plasteel/white, /area/medical/surgery) "dsP" = ( -/obj/item/circular_saw, -/obj/item/surgicaldrill{ - pixel_y = 5 - }, -/obj/structure/table/reinforced, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, @@ -54043,11 +54057,10 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/limbgrower, /turf/open/floor/plasteel/white, /area/medical/surgery) "dsQ" = ( -/obj/item/scalpel, -/obj/item/cautery, /obj/structure/table/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -54061,6 +54074,13 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/item/clothing/gloves/color/latex{ + pixel_y = 10 + }, +/obj/item/clothing/suit/apron/surgical, +/obj/item/clothing/mask/surgical{ + pixel_y = -6 + }, /turf/open/floor/plasteel/white, /area/medical/surgery) "dsR" = ( @@ -55218,9 +55238,6 @@ /turf/open/floor/plasteel/white, /area/medical/surgery) "dvF" = ( -/obj/machinery/computer/operating{ - dir = 4 - }, /obj/structure/cable/white{ icon_state = "4-8" }, @@ -55237,10 +55254,11 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/table/reinforced, +/obj/item/storage/backpack/duffelbag/med/surgery, /turf/open/floor/plasteel, /area/medical/surgery) "dvG" = ( -/obj/structure/table/optable, /obj/effect/decal/cleanable/blood/old, /obj/structure/cable/white{ icon_state = "2-8" @@ -55261,17 +55279,19 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/structure/table/reinforced, +/obj/item/reagent_containers/spray/cleaner, /turf/open/floor/plasteel, /area/medical/surgery) "dvH" = ( -/obj/machinery/holopad, /obj/structure/cable/white{ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/bot, +/obj/structure/table/reinforced, +/obj/item/storage/backpack/duffelbag/med/surgery, /turf/open/floor/plasteel, /area/medical/surgery) "dvI" = ( @@ -55945,21 +55965,21 @@ /turf/open/floor/plasteel/white, /area/medical/surgery) "dxm" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, /turf/open/floor/plasteel/white, /area/medical/surgery) "dxn" = ( /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, +/obj/machinery/holopad, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, /area/medical/surgery) "dxo" = ( /obj/effect/turf_decal/tile/blue, @@ -56558,7 +56578,6 @@ /turf/open/floor/plasteel/white, /area/medical/surgery) "dyG" = ( -/obj/structure/closet/secure_closet/medical2, /obj/structure/sign/poster/official/cleanliness{ pixel_x = -32 }, @@ -56572,25 +56591,12 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/turf/open/floor/plasteel/dark, -/area/medical/surgery) -"dyH" = ( +/obj/machinery/computer/operating{ + dir = 1 + }, /obj/machinery/status_display/ai{ pixel_y = -32 }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/medical/surgery) "dyI" = ( @@ -56616,12 +56622,10 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/closet/crate/freezer/blood, /turf/open/floor/plasteel/dark, /area/medical/surgery) "dyJ" = ( -/obj/machinery/status_display/evac{ - pixel_y = -32 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -56632,7 +56636,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/obj/structure/closet/crate/freezer/blood, +/obj/structure/table/optable, /turf/open/floor/plasteel/dark, /area/medical/surgery) "dyK" = ( @@ -56651,7 +56655,12 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/obj/machinery/limbgrower, +/obj/machinery/computer/operating{ + dir = 1 + }, +/obj/machinery/status_display/evac{ + pixel_y = -32 + }, /turf/open/floor/plasteel/dark, /area/medical/surgery) "dyL" = ( @@ -56683,6 +56692,10 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/delivery, +/obj/machinery/light_switch{ + pixel_x = -26; + pixel_y = -26 + }, /turf/open/floor/plasteel, /area/hallway/secondary/construction) "dyP" = ( @@ -57351,6 +57364,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, +/obj/structure/loot_pile/maint, /turf/open/floor/plating, /area/maintenance/port) "dAv" = ( @@ -59200,6 +59214,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/loot_pile/maint, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -60409,6 +60424,10 @@ /obj/item/clothing/gloves/color/latex/nitrile, /obj/item/clothing/suit/apron/surgical, /obj/item/clothing/mask/breath/medical, +/obj/item/wallframe/light_fixture/small{ + dir = 4; + pixel_x = 14 + }, /turf/open/floor/plating, /area/maintenance/department/medical/morgue) "dGA" = ( @@ -61480,12 +61499,12 @@ /obj/machinery/computer/operating{ dir = 1 }, -/obj/machinery/newscaster{ - pixel_y = -32 - }, /obj/effect/turf_decal/tile/purple{ dir = 8 }, +/obj/machinery/posialert{ + pixel_y = -32 + }, /turf/open/floor/plasteel/white, /area/science/robotics/lab) "dIR" = ( @@ -62648,6 +62667,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 4 }, +/obj/structure/loot_pile/maint, /turf/open/floor/plasteel, /area/maintenance/aft) "dLj" = ( @@ -62698,6 +62718,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/loot_pile/maint, /turf/open/floor/plasteel, /area/maintenance/starboard/aft) "dLn" = ( @@ -63080,6 +63101,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/loot_pile/maint, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -73820,16 +73842,6 @@ }, /turf/open/floor/plasteel, /area/engineering/main) -"fdZ" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/computer/bounty{ - dir = 8 - }, -/turf/open/floor/plasteel/grimy, -/area/command/heads_quarters/hop) "fer" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 @@ -74375,9 +74387,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/computer/bounty{ - dir = 4 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -75514,7 +75523,6 @@ name = "medbay camera"; network = list("ss13","medbay") }, -/obj/item/kirbyplants/random, /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ dir = 4 @@ -75754,7 +75762,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) "fLq" = ( @@ -77531,8 +77539,7 @@ /area/engineering/main) "grf" = ( /obj/machinery/atmospherics/pipe/simple/orange/hidden{ - dir = 5; - icon_state = "pipe11-2" + dir = 5 }, /turf/closed/wall/r_wall, /area/science/xenobiology) @@ -77868,8 +77875,7 @@ dir = 8 }, /obj/machinery/atmospherics/components/unary/outlet_injector/on{ - dir = 4; - icon_state = "inje_map-2" + dir = 4 }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) @@ -78932,7 +78938,6 @@ /turf/open/floor/plasteel, /area/commons/dorms) "gUc" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/bodycontainer/crematorium{ dir = 4; id = "cremawheat" @@ -79157,6 +79162,10 @@ "gWu" = ( /turf/closed/wall, /area/cargo/warehouse) +"gWF" = ( +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/port/fore) "gXc" = ( /obj/structure/sign/painting/library{ pixel_y = 32 @@ -81051,6 +81060,7 @@ /obj/machinery/light/small{ dir = 8 }, +/obj/machinery/atmospherics/miner/toxins, /turf/open/floor/engine/plasma, /area/engineering/atmos) "hEm" = ( @@ -86250,7 +86260,7 @@ "jjN" = ( /obj/structure/table/reinforced, /obj/machinery/camera{ - c_tag = "Science - Experimentation Lab"; + c_tag = "Science - Circuitry Lab"; name = "science camera"; network = list("ss13","rd") }, @@ -91325,7 +91335,7 @@ pixel_y = 32 }, /obj/machinery/camera{ - c_tag = "Library - Aft"; + c_tag = "Library - Port"; name = "library camera" }, /turf/open/floor/wood, @@ -92127,7 +92137,7 @@ /turf/closed/wall, /area/commons/storage/primary) "lkg" = ( -/obj/machinery/atmospherics/miner/toxins, +/obj/effect/turf_decal/vg_decals/atmos/plasma, /turf/open/floor/engine/plasma, /area/engineering/atmos) "lkF" = ( @@ -93687,7 +93697,7 @@ /turf/open/floor/plasteel, /area/engineering/main) "lNq" = ( -/obj/machinery/atmospherics/miner/nitrogen, +/obj/effect/turf_decal/vg_decals/atmos/nitrogen, /turf/open/floor/engine/n2, /area/engineering/atmos) "lNA" = ( @@ -95042,8 +95052,8 @@ /turf/open/floor/plasteel/dark, /area/engineering/atmos) "mmq" = ( -/obj/effect/turf_decal/vg_decals/atmos/nitrogen, -/turf/open/floor/engine/n2, +/obj/effect/turf_decal/vg_decals/atmos/mix, +/turf/open/floor/engine/vacuum, /area/engineering/atmos) "mmC" = ( /obj/structure/cable/white{ @@ -95236,6 +95246,11 @@ }, /turf/open/floor/plasteel, /area/service/library/abandoned) +"mpB" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/port) "mqb" = ( /obj/structure/cable{ icon_state = "1-2" @@ -95511,6 +95526,7 @@ /obj/machinery/light/small{ dir = 8 }, +/obj/machinery/atmospherics/miner/n2o, /turf/open/floor/engine/n2o, /area/engineering/atmos) "mwH" = ( @@ -96845,7 +96861,7 @@ /obj/item/folder/red, /obj/item/toy/gun, /obj/item/clothing/head/beret/sec{ - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0); + armor = list("melee"=0,"bullet"=0,"laser"=0,"energy"=0,"bomb"=0,"bio"=0,"rad"=0); desc = "A replica beret resembling that of a special operations officer under Nanotrasen."; name = "replica officer's beret" }, @@ -97238,6 +97254,17 @@ }, /turf/closed/wall/r_wall, /area/science/circuit) +"mYR" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/structure/loot_pile/maint, +/turf/open/floor/plasteel, +/area/maintenance/starboard/aft) "mYT" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/closet/cardboard, @@ -98596,6 +98623,7 @@ /obj/machinery/light/small{ dir = 8 }, +/obj/machinery/atmospherics/miner/carbon_dioxide, /turf/open/floor/engine/co2, /area/engineering/atmos) "nzv" = ( @@ -98904,7 +98932,7 @@ name = "Replica CentCom officer's jumpsuit" }, /obj/item/clothing/head/centhat{ - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0); + armor = list("melee"=0,"bullet"=0,"laser"=0,"energy"=0,"bomb"=0,"bio"=0,"rad"=0); desc = "A replica hat of a Central Commander's attire. It has a small tag on it saying, 'It's good to be emperor.'"; name = "Replica CentCom hat" }, @@ -100527,7 +100555,7 @@ /turf/open/floor/plasteel/dark, /area/service/library) "ohX" = ( -/obj/machinery/atmospherics/miner/carbon_dioxide, +/obj/effect/turf_decal/vg_decals/atmos/carbon_dioxide, /turf/open/floor/engine/co2, /area/engineering/atmos) "ohZ" = ( @@ -101048,6 +101076,19 @@ }, /turf/open/floor/plasteel, /area/engineering/main) +"orP" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating, +/area/maintenance/aft) "orZ" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -102564,7 +102605,7 @@ /turf/open/floor/plasteel, /area/engineering/break_room) "oTt" = ( -/obj/machinery/atmospherics/miner/n2o, +/obj/effect/turf_decal/vg_decals/atmos/nitrous_oxide, /turf/open/floor/engine/n2o, /area/engineering/atmos) "oTJ" = ( @@ -105980,7 +106021,6 @@ dir = 1; name = "atmospherics camera" }, -/obj/effect/turf_decal/vg_decals/atmos/mix, /turf/open/floor/engine/vacuum, /area/engineering/atmos) "qbJ" = ( @@ -106029,10 +106069,6 @@ }, /turf/open/floor/plating, /area/engineering/atmos) -"qcm" = ( -/obj/effect/turf_decal/vg_decals/atmos/plasma, -/turf/open/floor/engine/plasma, -/area/engineering/atmos) "qcW" = ( /obj/machinery/firealarm{ pixel_y = 26 @@ -108229,10 +108265,6 @@ }, /turf/open/floor/plasteel, /area/engineering/atmospherics_engine) -"qYy" = ( -/obj/effect/turf_decal/vg_decals/atmos/oxygen, -/turf/open/floor/engine/o2, -/area/engineering/atmos) "qYD" = ( /obj/machinery/atmospherics/pipe/simple/yellow/visible{ dir = 9 @@ -109905,6 +109937,7 @@ "rCr" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/structure/loot_pile/maint, /turf/open/floor/plating, /area/cargo/warehouse) "rCv" = ( @@ -109912,10 +109945,6 @@ dir = 6 }, /area/science/circuit) -"rCx" = ( -/obj/effect/turf_decal/vg_decals/atmos/nitrous_oxide, -/turf/open/floor/engine/n2o, -/area/engineering/atmos) "rCK" = ( /obj/machinery/button/door{ id = "teleporterhubshutters"; @@ -109940,6 +109969,11 @@ }, /turf/open/floor/plasteel, /area/cargo/storage) +"rCR" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/port/aft) "rDp" = ( /obj/structure/table/glass, /obj/structure/cable/white{ @@ -113621,6 +113655,20 @@ }, /turf/open/floor/plasteel, /area/engineering/break_room) +"sOn" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/light_switch{ + pixel_x = -26; + pixel_y = 8 + }, +/turf/open/floor/plasteel, +/area/security/brig) "sOo" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -114068,6 +114116,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 1 }, +/obj/machinery/vending/kink, /turf/open/floor/plasteel, /area/commons/fitness/recreation) "sVM" = ( @@ -114158,6 +114207,13 @@ }, /turf/open/floor/carpet, /area/commons/vacant_room/office) +"sWQ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/port/aft) "sWY" = ( /obj/machinery/door/firedoor, /obj/structure/cable/white{ @@ -114328,7 +114384,7 @@ dir = 4 }, /obj/machinery/camera{ - c_tag = "Library - Aft"; + c_tag = "Library - Beam"; name = "library camera" }, /turf/open/floor/plasteel/grimy, @@ -115671,13 +115727,13 @@ /obj/machinery/light_switch{ pixel_x = 23 }, -/obj/machinery/computer/bounty{ - dir = 8 - }, /obj/effect/turf_decal/tile/brown, /obj/effect/turf_decal/tile/brown{ dir = 4 }, +/obj/machinery/computer/bounty{ + dir = 8 + }, /turf/open/floor/plasteel, /area/cargo/qm) "twd" = ( @@ -116086,10 +116142,6 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/aisat/exterior) -"tBF" = ( -/obj/effect/turf_decal/vg_decals/atmos/air, -/turf/open/floor/engine/air, -/area/engineering/atmos) "tBH" = ( /obj/machinery/door/airlock/atmos/glass/critical{ heat_proof = 1; @@ -117027,6 +117079,10 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/camera{ + c_tag = "Engineering MiniSat Access"; + dir = 1 + }, /turf/open/floor/plasteel/dark, /area/engineering/transit_tube) "tVn" = ( @@ -117101,7 +117157,7 @@ /turf/open/floor/plasteel, /area/cargo/storage) "tWb" = ( -/obj/machinery/atmospherics/miner/oxygen, +/obj/effect/turf_decal/vg_decals/atmos/oxygen, /turf/open/floor/engine/o2, /area/engineering/atmos) "tWi" = ( @@ -118540,6 +118596,7 @@ /obj/machinery/light/small{ dir = 4 }, +/obj/machinery/atmospherics/miner/oxygen, /turf/open/floor/engine/o2, /area/engineering/atmos) "uuL" = ( @@ -118898,6 +118955,9 @@ /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/machinery/light_switch{ + pixel_y = 24 + }, /turf/open/floor/plasteel, /area/security/office) "uBU" = ( @@ -119193,6 +119253,10 @@ }, /turf/open/floor/plasteel, /area/command/heads_quarters/hos) +"uIT" = ( +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/port) "uJd" = ( /obj/item/kirbyplants/random, /obj/item/radio/intercom{ @@ -119339,7 +119403,7 @@ }, /obj/item/reagent_containers/food/drinks/beer{ desc = "Whatever it is, it reeks of foul, putrid froth."; - list_reagents = list("bacchus_blessing" = 15); + list_reagents = list("bacchus_blessing"=15); name = "Delta-Down"; pixel_x = 5; pixel_y = 5 @@ -119361,6 +119425,10 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/light_switch{ + pixel_x = 26; + pixel_y = 26 + }, /turf/open/floor/plasteel, /area/ai_monitored/command/storage/eva) "uNf" = ( @@ -121558,9 +121626,6 @@ name = "Station Intercom (General)"; pixel_x = 28 }, -/obj/machinery/computer/bounty{ - dir = 8 - }, /obj/effect/turf_decal/tile/brown, /obj/effect/turf_decal/tile/brown{ dir = 4 @@ -121568,6 +121633,9 @@ /obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/machinery/computer/bounty{ + dir = 8 + }, /turf/open/floor/plasteel, /area/cargo/office) "vEI" = ( @@ -124134,6 +124202,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/item/chisel, /turf/open/floor/plasteel/dark, /area/service/library) "wDf" = ( @@ -125270,6 +125339,7 @@ /obj/machinery/light/small{ dir = 4 }, +/obj/machinery/atmospherics/miner/nitrogen, /turf/open/floor/engine/n2, /area/engineering/atmos) "wXR" = ( @@ -126471,7 +126541,7 @@ dir = 4 }, /obj/machinery/camera{ - c_tag = "Science - Lab Access"; + c_tag = "Science - Circuitry Lab Starboard"; dir = 8; name = "science camera"; network = list("ss13","rd") @@ -128557,6 +128627,21 @@ }, /turf/open/floor/plasteel, /area/cargo/storage) +"yia" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/structure/loot_pile/maint, +/turf/open/floor/plasteel{ + heat_capacity = 1e+006 + }, +/area/maintenance/starboard/aft) "yiq" = ( /obj/structure/reflector/single/anchored{ dir = 6 @@ -150037,18 +150122,18 @@ aSQ iio iMu ohX -cEA +hFW iio sEM lkg -qcm +kRS iio rUo oTt -rCx +lbI iio kcG -kcG +mmq qbG iio aad @@ -150090,7 +150175,7 @@ opi xbs qjg qjg -ceb +mpB cLv cMQ cOq @@ -157011,7 +157096,7 @@ caE cdY cfR chI -ceb +mpB cfU cmi cnI @@ -157487,16 +157572,16 @@ aaa aad iio wTN +cEA lEq -tBF iio wjw tWb -qYy +sCm iio eFu lNq -mmq +skw iio aMN emZ @@ -158113,7 +158198,7 @@ dOl ean dLW dZg -dLW +rCR ecv edf edl @@ -158752,7 +158837,7 @@ lxH odN quN asF -alg +gWF avq awo axJ @@ -159291,7 +159376,7 @@ qOV ary aKj bbQ -alg +gWF beK bgj alf @@ -159341,7 +159426,7 @@ ojB roP uhj cCO -cea +uIT cJZ cLI cNg @@ -160928,7 +161013,7 @@ dPG dQz dRy dSx -dOS +cCK dUg dUX dVL @@ -164525,7 +164610,7 @@ dOY dPR dfm dRK -dOl +sWQ pPz sBt vSo @@ -164977,7 +165062,7 @@ xmR qTU xmR wGq -fdZ +xmR kxP pnQ gEc @@ -169400,7 +169485,7 @@ dGk dHF dIW dCy -dKY +orP dMx dNS aaa @@ -177100,7 +177185,7 @@ dsO dtR dvF dxm -dyH +dyJ dma cPy cPy @@ -179868,7 +179953,7 @@ byJ bAl bCe bEc -bmh +sOn bHA bJw bLn @@ -180424,7 +180509,7 @@ hYQ jjL pzu fzU -cYj +yia cZV dbC ddr @@ -181202,7 +181287,7 @@ ddt ddt aaB dbD -diW +mYR aaR dbA dnU diff --git a/_maps/map_files/FestiveBall/FestiveStation.dmm b/_maps/map_files/FestiveBall/FestiveStation.dmm new file mode 100644 index 0000000000..353b298ceb --- /dev/null +++ b/_maps/map_files/FestiveBall/FestiveStation.dmm @@ -0,0 +1,122204 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aaa" = ( +/obj/effect/baseturf_helper/asteroid/snow, +/turf/closed/indestructible/rock/snow, +/area/edina) +"aab" = ( +/obj/effect/mapping_helpers/planet_z, +/turf/closed/indestructible/rock/snow, +/area/edina) +"aac" = ( +/turf/closed/indestructible/rock/snow, +/area/edina) +"aad" = ( +/turf/closed/mineral/snowmountain, +/area/edina) +"aae" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/plating/dirt{ + initial_gas_mix = "o2=21.78;n2=82.36;TEMP=293.15" + }, +/area/edina) +"aaf" = ( +/obj/effect/festive/trainrails/north{ + icon_state = "trainrails_west" + }, +/turf/open/floor/plating/dirt{ + initial_gas_mix = "o2=21.78;n2=82.36;TEMP=293.15" + }, +/area/edina) +"aag" = ( +/obj/effect/festive/trainrails/north{ + icon_state = "trainrails_east" + }, +/turf/open/floor/plating/dirt{ + initial_gas_mix = "o2=21.78;n2=82.36;TEMP=293.15" + }, +/area/edina) +"aah" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/plating/dirt{ + initial_gas_mix = "o2=21.78;n2=82.36;TEMP=293.15" + }, +/area/edina) +"aaj" = ( +/turf/open/lava, +/area/edina) +"aak" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway, +/area/edina) +"aal" = ( +/turf/open/floor/grass/snow/edina, +/area/edina) +"aam" = ( +/mob/living/simple_animal/pet/redpanda, +/turf/open/floor/grass, +/area/edina/crew_quarters/store/pet) +"aan" = ( +/obj/structure/chair/wood{ + dir = 4 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"aao" = ( +/obj/structure/table/wood, +/turf/open/floor/grass/snow/edina, +/area/edina) +"aap" = ( +/obj/structure/chair/wood{ + dir = 8 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"aaq" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"aar" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"aat" = ( +/obj/item/clothing/shoes/kindleKicks, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"aau" = ( +/obj/item/clothing/shoes/wheelys, +/obj/item/clothing/suit/nerdshirt, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"aav" = ( +/obj/structure/flora/ausbushes/leafybush, +/obj/structure/flora/ausbushes/brflowers, +/obj/structure/flora/ausbushes/fernybush, +/obj/structure/window, +/turf/open/floor/grass, +/area/commons/storage/tools) +"aaw" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 5 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"aax" = ( +/obj/structure/flora/ausbushes/leafybush, +/obj/structure/flora/ausbushes/ppflowers, +/obj/structure/flora/ausbushes/reedbush, +/obj/structure/flora/ausbushes/stalkybush, +/obj/structure/flora/ausbushes/fernybush, +/obj/structure/flora/ausbushes/ywflowers, +/obj/structure/window, +/obj/structure/sign/poster/contraband/space_up{ + pixel_y = 32 + }, +/turf/open/floor/grass, +/area/commons/storage/tools) +"aay" = ( +/obj/structure/flora/rock, +/obj/structure/window, +/obj/structure/sign/poster/contraband/pwr_game{ + pixel_y = 32 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/turf/open/floor/grass, +/area/commons/storage/tools) +"aaz" = ( +/turf/open/floor/grass, +/area/edina/crew_quarters/store/pet) +"aaA" = ( +/mob/living/simple_animal/pet/cat, +/turf/open/floor/grass, +/area/edina/crew_quarters/store/pet) +"aaC" = ( +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/pet) +"aaD" = ( +/obj/structure/bed, +/obj/effect/spawner/lootdrop/bedsheet, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/obj/effect/decal/festive/green_stockings, +/turf/open/floor/carpet/red, +/area/commons/dorms) +"aaE" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"aaF" = ( +/obj/structure/window/reinforced, +/turf/open/floor/holofloor/ice, +/area/edina) +"aaG" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"aaH" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/flora/tree/pine/xmas, +/turf/open/floor/grass/snow/edina, +/area/edina) +"aaI" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"aaJ" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"aaK" = ( +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/structure/flora/tree/pine/xmas, +/turf/open/floor/grass/snow/edina, +/area/edina) +"aaL" = ( +/turf/closed/festive/whitebrick, +/area/ai_monitored/turret_protected/ai_upload) +"aaM" = ( +/turf/closed/festive/whitebrick, +/area/command/bridge) +"aaN" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plasteel/dark, +/area/command/bridge) +"aaO" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/floor/plasteel/dark, +/area/command/bridge) +"aaP" = ( +/turf/open/floor/festive/alleyway, +/area/edina) +"aaQ" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plasteel/dark, +/area/command/bridge) +"aaR" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 9 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aaS" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/flora/tree/pine/xmas, +/turf/open/floor/grass/snow/edina, +/area/edina) +"aaT" = ( +/obj/structure/table, +/obj/item/aiModule/core/full/asimov, +/obj/item/aiModule/core/freeformcore, +/obj/machinery/door/window{ + base_state = "right"; + dir = 4; + icon_state = "right"; + name = "Core Modules"; + req_access_txt = "20" + }, +/obj/structure/window/reinforced, +/obj/effect/spawner/lootdrop/aimodule_harmless, +/obj/effect/spawner/lootdrop/aimodule_neutral, +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/item/aiModule/core/full/custom, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai_upload) +"aaU" = ( +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai_upload) +"aaV" = ( +/obj/structure/table, +/obj/item/aiModule/supplied/quarantine, +/obj/machinery/camera/motion, +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai_upload) +"aaW" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aaX" = ( +/obj/structure/table, +/obj/item/aiModule/reset, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai_upload) +"aaY" = ( +/obj/machinery/porta_turret/ai{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai_upload) +"aaZ" = ( +/obj/machinery/computer/prisoner/management, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"aba" = ( +/turf/closed/festive/whitebrick, +/area/edina/street) +"abb" = ( +/obj/machinery/computer/security, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/turf/open/floor/plasteel, +/area/command/bridge) +"abc" = ( +/obj/machinery/computer/secure_data, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abd" = ( +/obj/structure/table/reinforced, +/obj/machinery/recharger, +/turf/open/floor/plasteel, +/area/command/bridge) +"abe" = ( +/obj/machinery/modular_computer/console/preset/command, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abf" = ( +/obj/machinery/computer/crew, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/turf/open/floor/plasteel, +/area/command/bridge) +"abg" = ( +/obj/machinery/computer/med_data, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abh" = ( +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai_upload) +"abi" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abj" = ( +/obj/structure/chair/comfy/black{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abk" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abl" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abm" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abn" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abo" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/turf/open/floor/plasteel, +/area/command/bridge) +"abp" = ( +/obj/machinery/computer/upload/ai{ + dir = 4 + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai_upload) +"abq" = ( +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel, +/area/ai_monitored/turret_protected/ai_upload) +"abr" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abs" = ( +/turf/open/floor/plasteel, +/area/command/bridge) +"abt" = ( +/obj/effect/landmark/event_spawn, +/turf/open/floor/plasteel, +/area/command/bridge) +"abu" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abv" = ( +/obj/machinery/computer/security/mining{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abw" = ( +/obj/machinery/holopad, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai_upload) +"abx" = ( +/obj/effect/landmark/event_spawn, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai_upload) +"aby" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/highsecurity{ + name = "AI Upload Access"; + req_access_txt = "16" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai_upload) +"abz" = ( +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/command/bridge) +"abA" = ( +/turf/open/floor/carpet/green, +/area/command/bridge) +"abB" = ( +/obj/structure/chair/comfy/black{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abC" = ( +/obj/machinery/computer/cargo/request{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abD" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/turf/open/floor/plasteel/dark, +/area/command/bridge) +"abE" = ( +/obj/machinery/computer/upload/borg{ + dir = 4 + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai_upload) +"abF" = ( +/obj/structure/chair/comfy/black{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/command/bridge) +"abG" = ( +/obj/structure/table/glass, +/obj/item/assembly/flash/handheld, +/obj/item/assembly/flash/handheld, +/turf/open/floor/carpet/green, +/area/command/bridge) +"abH" = ( +/obj/structure/chair/comfy/black{ + dir = 8 + }, +/turf/open/floor/carpet/green, +/area/command/bridge) +"abI" = ( +/obj/effect/turf_decal/tile/brown, +/turf/open/floor/plasteel, +/area/command/bridge) +"abJ" = ( +/obj/machinery/modular_computer/console/preset/engineering{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abK" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWEMiddle, +/turf/open/floor/plasteel/dark, +/area/command/bridge) +"abL" = ( +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/obj/machinery/computer/shuttle/labor, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abM" = ( +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/obj/machinery/computer/communications, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abN" = ( +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/machinery/computer/card, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abO" = ( +/obj/structure/table/glass, +/obj/item/storage/secure/briefcase, +/obj/item/storage/box/PDAs{ + pixel_x = 4; + pixel_y = 4 + }, +/obj/item/storage/box/ids, +/turf/open/floor/carpet/green, +/area/command/bridge) +"abP" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel, +/area/command/bridge) +"abQ" = ( +/obj/structure/table/reinforced, +/obj/item/storage/toolbox/emergency, +/obj/item/wrench, +/obj/item/assembly/timer, +/obj/item/assembly/signaler, +/obj/item/assembly/signaler, +/turf/open/floor/plasteel, +/area/command/bridge) +"abR" = ( +/obj/structure/table, +/obj/machinery/door/window{ + base_state = "right"; + dir = 4; + icon_state = "right"; + name = "Core Modules"; + req_access_txt = "20" + }, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/item/aiModule/supplied/oxygen, +/obj/item/aiModule/zeroth/oneHuman, +/obj/item/aiModule/reset/purge, +/obj/effect/spawner/lootdrop/aimodule_harmful, +/obj/item/aiModule/supplied/protectStation, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai_upload) +"abS" = ( +/obj/structure/table, +/obj/item/aiModule/supplied/freeform, +/obj/machinery/camera/motion{ + c_tag = "MiniSat Foyer"; + dir = 1; + network = list("minisat") + }, +/obj/machinery/light, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai_upload) +"abT" = ( +/obj/structure/table, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai_upload) +"abU" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/keycard_auth{ + name = "Keycard Authentication Device \[Bridge]"; + pixel_x = -26 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abV" = ( +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abW" = ( +/obj/structure/table/glass, +/obj/item/storage/fancy/donut_box, +/obj/item/radio, +/turf/open/floor/carpet/green, +/area/command/bridge) +"abX" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abY" = ( +/obj/machinery/computer/atmos_alert{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"abZ" = ( +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 5 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aca" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"acb" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"acc" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/command/bridge) +"acd" = ( +/obj/machinery/door/window{ + dir = 4; + name = "Command Console Access"; + req_access_txt = "19" + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"ace" = ( +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/turf/open/floor/holofloor/ice, +/area/edina) +"acf" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"acg" = ( +/turf/closed/festive/whitebrick, +/area/edina) +"ach" = ( +/obj/machinery/computer/station_alert{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"aci" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/turf/open/floor/plasteel/dark, +/area/command/bridge) +"acj" = ( +/obj/machinery/door/poddoor/shutters{ + id = "parkcomm"; + name = "Command Parking" + }, +/turf/open/floor/festive/cobblestone/safe, +/area/edina/street) +"ack" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/festive/cobblestone/safe, +/area/edina/street) +"acl" = ( +/obj/structure/table/reinforced, +/obj/item/aicard, +/obj/item/multitool, +/turf/open/floor/plasteel, +/area/command/bridge) +"acm" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"acn" = ( +/obj/machinery/airalarm/directional/south, +/turf/open/floor/plasteel, +/area/command/bridge) +"aco" = ( +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel, +/area/command/bridge) +"acp" = ( +/obj/machinery/computer/monitor{ + dir = 8; + name = "bridge power monitoring console" + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/plasteel, +/area/command/bridge) +"acq" = ( +/turf/closed/festive/whitebrick, +/area/command/meeting_room/council) +"acr" = ( +/obj/machinery/door/airlock/command/glass{ + name = "Bridge"; + req_access_txt = "19" + }, +/turf/open/floor/plasteel, +/area/command/meeting_room/council) +"acs" = ( +/turf/closed/festive/whitebrick, +/area/command/heads_quarters/captain) +"act" = ( +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"acu" = ( +/obj/structure/table/wood, +/obj/item/storage/fancy/donut_box, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"acv" = ( +/obj/machinery/newscaster{ + pixel_y = 32 + }, +/obj/structure/table/wood, +/obj/item/hand_labeler, +/obj/item/assembly/timer, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"acw" = ( +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"acx" = ( +/obj/structure/table/wood, +/obj/machinery/recharger{ + pixel_y = 4 + }, +/obj/machinery/button/door{ + id = "heads_meeting"; + name = "Security Shutters"; + pixel_y = 24 + }, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"acy" = ( +/obj/machinery/photocopier, +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"acz" = ( +/turf/open/floor/wood, +/area/command/meeting_room/council) +"acA" = ( +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"acB" = ( +/obj/machinery/camera{ + c_tag = "Conference Room" + }, +/obj/structure/filingcabinet/security, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"acC" = ( +/obj/structure/bookcase/random/reference, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"acD" = ( +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"acE" = ( +/obj/machinery/airalarm/directional/north, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"acF" = ( +/obj/structure/chair/comfy/brown, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"acG" = ( +/obj/vehicle/sealed/vectorcraft/CAPT{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/captain) +"acH" = ( +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/captain) +"acI" = ( +/obj/machinery/door/poddoor/shutters{ + id = "capgarage"; + name = "Captain's Garage" + }, +/turf/open/floor/plasteel/dark, +/area/edina/street) +"acJ" = ( +/turf/open/floor/plasteel, +/area/service/theater) +"acK" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/holofloor/ice, +/area/edina) +"acL" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/open/floor/holofloor/ice, +/area/edina) +"acM" = ( +/turf/closed/wall/r_wall, +/area/ai_monitored/turret_protected/ai) +"acN" = ( +/obj/machinery/door/airlock/command/glass{ + name = "Bridge Access"; + req_access_txt = "19" + }, +/turf/open/floor/plasteel/dark, +/area/command/meeting_room/council) +"acO" = ( +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"acP" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 9 + }, +/turf/open/floor/holofloor/ice, +/area/edina) +"acQ" = ( +/turf/open/floor/festive/sidewalk, +/area/edina) +"acR" = ( +/obj/machinery/door/airlock/command{ + name = "Captain's Office"; + req_access_txt = "20" + }, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"acS" = ( +/turf/open/floor/carpet/royalblue, +/area/command/heads_quarters/captain) +"acT" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"acU" = ( +/obj/machinery/button/door{ + id = "capgarage"; + name = "Captain's Garage"; + pixel_x = -28; + pixel_y = -7; + req_access_txt = "20" + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/captain) +"acV" = ( +/obj/machinery/door/poddoor/shutters{ + id = "capgarage"; + name = "Captain's Garage" + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/captain) +"acW" = ( +/obj/effect/festive/street/streetlineinnernw{ + pixel_x = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"acX" = ( +/obj/machinery/button/door{ + id = "parkcomm"; + name = "Command Parking"; + pixel_x = 28; + pixel_y = 7; + req_one_access_txt = "2;19" + }, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/festive/cobblestone/safe, +/area/edina/street) +"acY" = ( +/obj/machinery/light/floor, +/turf/open/floor/carpet/purple, +/area/command/meeting_room/council) +"acZ" = ( +/obj/structure/flora/tree/pine/xmas, +/turf/open/floor/grass/snow/edina, +/area/edina) +"ada" = ( +/obj/structure/chair/comfy{ + color = "#ff8000" + }, +/turf/open/floor/carpet/purple, +/area/command/meeting_room/council) +"adb" = ( +/obj/structure/chair/comfy/black, +/obj/structure/chair/comfy{ + color = "#d400ff" + }, +/turf/open/floor/carpet/purple, +/area/command/meeting_room/council) +"adc" = ( +/obj/structure/chair/comfy{ + color = "#0022e6" + }, +/turf/open/floor/carpet/purple, +/area/command/meeting_room/council) +"add" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"ade" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/command/nuke_storage) +"adf" = ( +/obj/machinery/door/airlock/command{ + name = "Captain's Office"; + req_access_txt = "20" + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/captain) +"adg" = ( +/obj/effect/festive/street/streetlinenorth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"adh" = ( +/obj/machinery/porta_turret/ai{ + dir = 4; + installation = /obj/item/gun/energy/e_gun + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"adi" = ( +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"adj" = ( +/obj/machinery/status_display{ + pixel_y = 32 + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"adk" = ( +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai) +"adm" = ( +/obj/machinery/porta_turret/ai{ + dir = 4; + installation = /obj/item/gun/energy/e_gun + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"adn" = ( +/obj/machinery/status_display/ai{ + pixel_y = 32 + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"adp" = ( +/obj/effect/festive/street/streetlinewest, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"adq" = ( +/obj/machinery/door/airlock/command{ + name = "Head of Personnel's Quarters"; + req_access_txt = "57" + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"adr" = ( +/obj/effect/festive/street/streetlinenm, +/turf/open/floor/festive/cobblestone/safe, +/area/edina/street) +"ads" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"adt" = ( +/obj/structure/chair/comfy/black{ + dir = 4 + }, +/turf/open/floor/carpet/purple, +/area/command/meeting_room/council) +"adu" = ( +/obj/structure/table/wood/fancy/black, +/turf/open/floor/carpet/purple, +/area/command/meeting_room/council) +"adv" = ( +/obj/structure/chair/brass{ + dir = 8; + name = "Top brass chair" + }, +/turf/open/floor/carpet/purple, +/area/command/meeting_room/council) +"adw" = ( +/turf/closed/wall/r_wall, +/area/edina) +"adx" = ( +/turf/closed/wall/r_wall, +/area/tcommsat/computer) +"ady" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"adz" = ( +/obj/machinery/vending/boozeomat/pubby_captain, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"adA" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp/green, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"adB" = ( +/obj/machinery/status_display{ + pixel_x = -32 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai) +"adC" = ( +/obj/effect/festive/street/streetlinese, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"adD" = ( +/obj/machinery/ai_slipper{ + uses = 10 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai) +"adE" = ( +/obj/machinery/power/terminal, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"adF" = ( +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"adG" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"adH" = ( +/turf/closed/wall/r_wall, +/area/tcommsat/server) +"adI" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"adJ" = ( +/obj/machinery/status_display/ai{ + pixel_x = 32 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai) +"adL" = ( +/obj/structure/closet/secure_closet/hop, +/obj/item/clothing/suit/hooded/wintercoat/hop, +/obj/item/clothing/neck/scarf/darkblue, +/obj/item/key/hop, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/wood, +/area/command/heads_quarters/hop/private) +"adM" = ( +/turf/open/floor/wood, +/area/command/heads_quarters/hop/private) +"adN" = ( +/obj/machinery/airalarm/directional/north, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/wood, +/area/command/heads_quarters/hop/private) +"adO" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/wood, +/area/commons/dorms) +"adP" = ( +/obj/effect/decal/festive/fairylights, +/turf/open/floor/wood, +/area/command/heads_quarters/hop/private) +"adQ" = ( +/obj/effect/decal/festive/red_stockings, +/obj/structure/bed/double, +/obj/item/bedsheet/hop/double, +/turf/open/floor/wood, +/area/command/heads_quarters/hop/private) +"adR" = ( +/obj/effect/festive/street/streetlinenm, +/obj/vehicle/sealed/vectorcraft/auto{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone/safe, +/area/edina/street) +"adS" = ( +/obj/machinery/airalarm/directional/west, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"adT" = ( +/obj/structure/chair/comfy{ + color = "#ffcc00"; + dir = 1 + }, +/turf/open/floor/carpet/purple, +/area/command/meeting_room/council) +"adU" = ( +/obj/structure/chair/comfy{ + color = "#38a2ff"; + dir = 1 + }, +/turf/open/floor/carpet/purple, +/area/command/meeting_room/council) +"adV" = ( +/obj/structure/chair/comfy{ + color = "#ff3838"; + dir = 1 + }, +/turf/open/floor/carpet/purple, +/area/command/meeting_room/council) +"adW" = ( +/obj/machinery/camera{ + c_tag = "Xenobiology Kill Room"; + dir = 4; + network = list("ss13","rd") + }, +/obj/machinery/vending/cigarette, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"adX" = ( +/obj/structure/table/wood, +/obj/item/card/id/captains_spare, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"adY" = ( +/obj/structure/chair/comfy/brown{ + dir = 8 + }, +/obj/effect/landmark/start/captain, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"adZ" = ( +/obj/machinery/computer/communications{ + dir = 8 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"aea" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/captain) +"aeb" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai) +"aec" = ( +/obj/machinery/power/smes{ + charge = 5e+006 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai) +"aed" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/closed/wall/r_wall, +/area/ai_monitored/turret_protected/ai) +"aee" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai) +"aeg" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/obj/effect/landmark/start/head_of_personnel, +/turf/open/floor/wood, +/area/command/heads_quarters/hop/private) +"aeh" = ( +/obj/effect/festive/street/streetlinenm, +/obj/effect/festive/street/streetlinesm, +/turf/open/floor/festive/cobblestone/safe, +/area/edina/street) +"aei" = ( +/obj/structure/table/wood/fancy/black, +/obj/item/storage/photo_album, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"aej" = ( +/obj/structure/table/wood, +/obj/item/clothing/mask/cigarette/cigar, +/obj/item/storage/box/matches, +/obj/item/razor{ + pixel_x = -4; + pixel_y = 2 + }, +/obj/item/reagent_containers/food/drinks/flask/gold, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"aek" = ( +/obj/machinery/computer/card{ + dir = 8 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"ael" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/captain) +"aem" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai) +"aen" = ( +/obj/effect/landmark/start/ai/secondary, +/obj/item/radio/intercom{ + freerange = 1; + listening = 0; + name = "Custom Channel"; + pixel_y = 28 + }, +/obj/item/radio/intercom{ + freerange = 1; + name = "Common Channel"; + pixel_x = 27; + pixel_y = 5 + }, +/obj/item/radio/intercom{ + freerange = 1; + frequency = 1447; + name = "Private Channel"; + pixel_y = -25 + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"aeo" = ( +/obj/effect/landmark/start/ai/secondary, +/obj/item/radio/intercom{ + freerange = 1; + listening = 0; + name = "Custom Channel"; + pixel_y = 28 + }, +/obj/item/radio/intercom{ + freerange = 1; + name = "Common Channel"; + pixel_x = -27; + pixel_y = 5 + }, +/obj/item/radio/intercom{ + freerange = 1; + frequency = 1447; + name = "Private Channel"; + pixel_y = -25 + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"aep" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"aeq" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai) +"aes" = ( +/obj/structure/bed/dogbed/ian, +/turf/open/floor/wood, +/area/command/heads_quarters/hop/private) +"aet" = ( +/obj/structure/dresser, +/turf/open/floor/wood, +/area/command/heads_quarters/hop/private) +"aeu" = ( +/obj/effect/festive/street/streetlineem, +/obj/vehicle/sealed/vectorcraft/hop{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone/safe, +/area/edina/street) +"aev" = ( +/obj/effect/turf_decal/delivery/white, +/turf/open/floor/festive/cobblestone/safe, +/area/edina/street) +"aew" = ( +/obj/structure/reagent_dispensers/water_cooler, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"aex" = ( +/obj/machinery/requests_console{ + announcementConsole = 1; + department = "Bridge"; + departmentType = 5; + name = "Bridge RC"; + pixel_y = -30 + }, +/obj/machinery/light, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"aey" = ( +/obj/machinery/light, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"aez" = ( +/obj/structure/table/wood/fancy/black, +/turf/open/floor/wood, +/area/command/meeting_room/council) +"aeA" = ( +/obj/machinery/door/window{ + dir = 8; + name = "Captain's Desk Access"; + req_access_txt = "20" + }, +/obj/machinery/light, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"aeB" = ( +/obj/structure/displaycase/captain, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"aeC" = ( +/turf/closed/festive/whitebrick, +/area/ai_monitored/command/nuke_storage) +"aeD" = ( +/obj/structure/showcase/cyborg/old{ + dir = 8; + pixel_x = 9; + pixel_y = 2 + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"aeE" = ( +/obj/effect/landmark/start/ai, +/obj/item/radio/intercom{ + freerange = 1; + frequency = 1447; + name = "Private Channel"; + pixel_x = 27; + pixel_y = -9 + }, +/obj/item/radio/intercom{ + freerange = 1; + name = "Common Channel"; + pixel_x = -27; + pixel_y = -9 + }, +/obj/item/radio/intercom{ + freerange = 1; + listening = 0; + name = "Custom Channel"; + pixel_y = 32 + }, +/obj/machinery/requests_console{ + department = "AI"; + departmentType = 5; + pixel_x = 28; + pixel_y = 32 + }, +/obj/machinery/newscaster/security_unit{ + pixel_x = -28; + pixel_y = 32 + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"aeF" = ( +/obj/structure/showcase/cyborg/old{ + dir = 4; + pixel_x = -9; + pixel_y = 2 + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"aeG" = ( +/turf/closed/festive/whitebrick, +/area/command/heads_quarters/hop/private) +"aeH" = ( +/obj/machinery/door/airlock/command{ + name = "Head of Personnel's Office"; + req_access_txt = "57" + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"aeI" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/obj/machinery/door/poddoor/preopen{ + id = "heads_meeting"; + name = "privacy shutters" + }, +/turf/open/floor/plasteel/dark, +/area/command/meeting_room/council) +"aeJ" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/obj/machinery/door/poddoor/preopen{ + id = "heads_meeting"; + name = "privacy shutters" + }, +/turf/open/floor/plasteel/dark, +/area/command/meeting_room/council) +"aeK" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/obj/machinery/door/poddoor/preopen{ + id = "heads_meeting"; + name = "privacy shutters" + }, +/turf/open/floor/plasteel/dark, +/area/command/meeting_room/council) +"aeL" = ( +/obj/machinery/door/airlock/command{ + name = "Captain's Office"; + req_access_txt = "20" + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/captain) +"aeM" = ( +/obj/machinery/door/airlock/command{ + name = "Captain's Quarters"; + req_access_txt = "20" + }, +/obj/effect/decal/festive/mistletoe, +/turf/open/floor/wood, +/area/command/heads_quarters/captain) +"aeN" = ( +/obj/machinery/computer/bank_machine, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/nuke_storage) +"aeO" = ( +/obj/machinery/light_switch{ + pixel_y = 28 + }, +/turf/open/floor/circuit/green{ + luminosity = 2 + }, +/area/ai_monitored/command/nuke_storage) +"aeP" = ( +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/circuit/green{ + luminosity = 2 + }, +/area/ai_monitored/command/nuke_storage) +"aeQ" = ( +/obj/machinery/power/apc{ + dir = 1; + name = "Vault APC"; + pixel_y = 25 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/circuit/green{ + luminosity = 2 + }, +/area/ai_monitored/command/nuke_storage) +"aeR" = ( +/obj/structure/filingcabinet, +/obj/item/folder/documents, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/nuke_storage) +"aeS" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"aeT" = ( +/obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/ai_monitored/turret_protected/ai"; + dir = 1; + name = "AI Chamber APC"; + pixel_x = -8; + pixel_y = 40 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"aeU" = ( +/obj/machinery/flasher{ + id = "AI"; + pixel_x = -24; + pixel_y = 40 + }, +/obj/machinery/ai_slipper{ + uses = 10 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/decal/festive/mistletoe, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"aeV" = ( +/obj/machinery/turretid{ + name = "AI Chamber turret control"; + pixel_x = null; + pixel_y = 40 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"aeW" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"aeX" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"aeY" = ( +/turf/closed/festive/whitebrick, +/area/command/gateway) +"aeZ" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hop/private) +"afa" = ( +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"afb" = ( +/obj/machinery/newscaster/security_unit{ + pixel_y = 32 + }, +/mob/living/simple_animal/pet/dog/corgi/Ian, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"afc" = ( +/obj/machinery/disposal/bin, +/obj/machinery/computer/security/telescreen/vault{ + pixel_y = 30 + }, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"afd" = ( +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_y = 35 + }, +/obj/structure/filingcabinet/chestdrawer, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"afe" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/machinery/pdapainter, +/obj/machinery/button/door{ + id = "hopqueue"; + name = "Queue Shutters Control"; + pixel_x = -4; + pixel_y = 25; + req_access_txt = "57" + }, +/obj/machinery/button/door{ + id = "hop"; + name = "Privacy Shutters Control"; + pixel_x = 6; + pixel_y = 25; + req_access_txt = "57" + }, +/obj/machinery/light_switch{ + pixel_x = -4; + pixel_y = 36 + }, +/obj/machinery/button/flasher{ + id = "hopflash"; + pixel_x = 6; + pixel_y = 36 + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"aff" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel, +/area/command/corporate_showroom) +"afg" = ( +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "hopqueue"; + name = "HoP Queue Shutters" + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel, +/area/command/corporate_showroom) +"afh" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel, +/area/command/corporate_showroom) +"afi" = ( +/obj/item/banner/command, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"afj" = ( +/obj/structure/showcase/machinery/tv, +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"afk" = ( +/obj/structure/showcase/machinery/implanter{ + layer = 2.7; + pixel_y = 4 + }, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"afl" = ( +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"afm" = ( +/obj/structure/showcase/perfect_employee, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"afn" = ( +/obj/structure/showcase/machinery/tv, +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"afo" = ( +/obj/item/banner/command, +/obj/effect/decal/festive/christmas_ivy_string, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"afp" = ( +/turf/open/floor/plasteel, +/area/command/corporate_showroom) +"afq" = ( +/turf/closed/festive/whitebrick, +/area/command/heads_quarters/captain/private) +"afr" = ( +/obj/machinery/shower{ + dir = 4 + }, +/obj/structure/curtain, +/obj/item/soap/deluxe, +/obj/item/bikehorn/rubberducky, +/turf/open/floor/plasteel/freezer, +/area/command/heads_quarters/captain/private) +"afs" = ( +/obj/structure/mirror{ + pixel_y = 28 + }, +/obj/structure/sink{ + pixel_y = 16 + }, +/turf/open/floor/plasteel/freezer, +/area/command/heads_quarters/captain/private) +"aft" = ( +/turf/open/floor/wood, +/area/command/heads_quarters/captain/private) +"afu" = ( +/obj/structure/table/wood, +/obj/item/storage/photo_album{ + pixel_y = -10 + }, +/obj/item/camera, +/turf/open/floor/wood, +/area/command/heads_quarters/captain/private) +"afv" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/nuke_storage) +"afw" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/circuit/green{ + luminosity = 2 + }, +/area/ai_monitored/command/nuke_storage) +"afx" = ( +/obj/machinery/nuclearbomb/selfdestruct, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/nuke_storage) +"afy" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/circuit/green{ + luminosity = 2 + }, +/area/ai_monitored/command/nuke_storage) +"afz" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/obj/machinery/ore_silo, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/nuke_storage) +"afA" = ( +/obj/machinery/porta_turret/ai{ + dir = 4; + installation = /obj/item/gun/energy/e_gun + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai) +"afB" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/north) +"afC" = ( +/turf/closed/festive/whitebrick, +/area/ai_monitored/command/storage/eva) +"afD" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/gateway) +"afH" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/command/gateway) +"afI" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWEMiddle, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hop/private) +"afK" = ( +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hop/private) +"afL" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/chair/office/dark{ + dir = 4 + }, +/obj/effect/landmark/start/head_of_personnel, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"afM" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/window/northleft{ + dir = 8; + name = "Reception Window" + }, +/obj/machinery/door/window/brigdoor{ + base_state = "rightsecure"; + dir = 4; + icon_state = "rightsecure"; + name = "Head of Personnel's Desk"; + req_access_txt = "57" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/flasher{ + id = "hopflash"; + pixel_y = 28 + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "hop"; + name = "Privacy Shutters" + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "hop"; + name = "Privacy Shutters" + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"afN" = ( +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/command/corporate_showroom) +"afO" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/plasteel/dark, +/area/command/corporate_showroom) +"afP" = ( +/obj/structure/toilet{ + dir = 4 + }, +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/plasteel/freezer, +/area/command/heads_quarters/captain/private) +"afQ" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/plasteel/freezer, +/area/command/heads_quarters/captain/private) +"afR" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/airalarm/directional/west, +/turf/open/floor/wood, +/area/command/heads_quarters/captain/private) +"afS" = ( +/obj/structure/table/wood, +/obj/item/pinpointer/nuke, +/obj/item/disk/nuclear, +/turf/open/floor/wood, +/area/command/heads_quarters/captain/private) +"afT" = ( +/obj/structure/closet/crate/goldcrate, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/nuke_storage) +"afU" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/circuit/green{ + luminosity = 2 + }, +/area/ai_monitored/command/nuke_storage) +"afV" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/circuit/green{ + luminosity = 2 + }, +/area/ai_monitored/command/nuke_storage) +"afW" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/circuit/green{ + luminosity = 2 + }, +/area/ai_monitored/command/nuke_storage) +"afX" = ( +/obj/structure/closet/crate/silvercrate, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/nuke_storage) +"afY" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai) +"afZ" = ( +/obj/machinery/suit_storage_unit/standard_unit, +/obj/structure/extinguisher_cabinet{ + pixel_x = -27 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/storage/eva) +"aga" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"agb" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"agc" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"agd" = ( +/obj/machinery/suit_storage_unit/standard_unit, +/obj/machinery/light_switch{ + pixel_x = -8; + pixel_y = 30 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/storage/eva) +"age" = ( +/turf/open/floor/plasteel/dark, +/area/command/gateway) +"agg" = ( +/obj/machinery/gateway, +/turf/open/floor/plasteel/dark, +/area/command/gateway) +"agh" = ( +/obj/effect/turf_decal/bot_white, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/gateway) +"agi" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hop/private) +"agj" = ( +/obj/machinery/holopad, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hop/private) +"agk" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/computer/card{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"agl" = ( +/obj/structure/grille, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "hop"; + name = "Privacy Shutters" + }, +/obj/structure/cable{ + icon_state = "0-2"; + pixel_y = 1 + }, +/obj/structure/festive/whitebrick/windowWERightEnd, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hop/private) +"agm" = ( +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/command/corporate_showroom) +"agn" = ( +/obj/structure/chair/comfy/black, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"ago" = ( +/obj/structure/table/wood/fancy/green, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 1; + pixel_y = 1 + }, +/obj/item/clothing/head/HoS/beret/syndicate, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"agp" = ( +/obj/machinery/door/window{ + dir = 1; + name = "Showcase Access"; + req_access_txt = "20" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"agq" = ( +/obj/structure/table/wood/fancy/red, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 1; + pixel_y = 1 + }, +/obj/item/clothing/accessory/armband/hydro, +/obj/item/banhammer, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"agr" = ( +/obj/machinery/airalarm/directional/east, +/turf/open/floor/plasteel, +/area/command/corporate_showroom) +"ags" = ( +/obj/machinery/door/airlock{ + name = "Private Restroom" + }, +/turf/open/floor/plasteel/freezer, +/area/command/heads_quarters/captain/private) +"agt" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/captain/private) +"agu" = ( +/obj/structure/closet/secure_closet/freezer/money, +/obj/item/reagent_containers/food/drinks/bottle/vodka/badminka, +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, +/obj/item/clothing/head/bearpelt, +/obj/item/skub, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/nuke_storage) +"agv" = ( +/obj/machinery/light, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/nuke_storage) +"agw" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/nuke_storage) +"agx" = ( +/obj/machinery/camera/motion{ + c_tag = "Vault"; + dir = 1; + network = list("vault") + }, +/obj/machinery/light, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/nuke_storage) +"agy" = ( +/obj/structure/safe, +/obj/item/bikehorn/golden, +/obj/item/ammo_box/a357, +/obj/item/tank/internals/plasma/full, +/obj/item/disk/nuclear/fake, +/obj/item/stack/ore/diamond, +/obj/item/gun/energy/disabler, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/nuke_storage) +"agz" = ( +/obj/structure/showcase/cyborg/old, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"agA" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"agB" = ( +/obj/structure/showcase/cyborg/old, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"agC" = ( +/obj/machinery/suit_storage_unit/standard_unit, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/storage/eva) +"agD" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"agE" = ( +/obj/structure/table, +/obj/item/storage/belt/utility, +/obj/item/storage/belt/utility, +/obj/item/radio/off, +/obj/item/radio/off, +/obj/item/radio/off, +/obj/item/radio/off, +/obj/item/multitool, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"agF" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"agG" = ( +/obj/machinery/suit_storage_unit/standard_unit, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/storage/eva) +"agH" = ( +/obj/effect/turf_decal/bot_white/left, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/gateway) +"agI" = ( +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/effect/turf_decal/bot_white, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/gateway) +"agJ" = ( +/obj/effect/turf_decal/bot_white/right, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/gateway) +"agK" = ( +/obj/machinery/camera{ + c_tag = "Fore Primary Hallway"; + dir = 4 + }, +/obj/machinery/airalarm/directional/west, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"agL" = ( +/obj/machinery/vending/cart, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"agM" = ( +/obj/structure/grille, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "hop"; + name = "Privacy Shutters" + }, +/obj/structure/cable, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/obj/structure/sign/warning/electricshock{ + pixel_y = -32 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hop/private) +"agN" = ( +/obj/effect/turf_decal/bot, +/obj/effect/landmark/event_spawn, +/turf/open/floor/plasteel, +/area/command/corporate_showroom) +"agO" = ( +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/command/corporate_showroom) +"agP" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/clothing/mask/cigarette/cigar/havana, +/obj/item/clothing/mask/cigarette/cigar/cohiba{ + pixel_x = -3 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"agQ" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/lighter, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"agR" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/reagent_containers/food/drinks/bottle/whiskey, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"agS" = ( +/obj/machinery/light/floor, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"agT" = ( +/obj/structure/table/wood/fancy/green, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/item/clothing/under/syndicate/baseball, +/obj/item/clothing/head/beret/sec{ + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0); + desc = "A replica beret resembling that of a special operations officer under Nanotrasen."; + name = "replica officer's beret" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"agU" = ( +/obj/structure/showcase/mecha/marauder, +/obj/machinery/light/floor, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"agV" = ( +/obj/structure/table/wood/fancy/red, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/item/clothing/head/centhat{ + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0); + desc = "A replica hat of a Central Commander's attire. It has a small tag on it saying, 'It's good to be emperor.'"; + name = "Replica CentCom hat" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"agW" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/folder/blue, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"agX" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/paper_bin, +/obj/item/pen/fountain, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"agY" = ( +/obj/structure/table/wood/fancy/green, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"agZ" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/plasteel, +/area/command/corporate_showroom) +"aha" = ( +/obj/structure/closet/secure_closet/captains, +/obj/item/clothing/head/caphat/beret/white, +/obj/item/radio, +/obj/item/clothing/neck/scarf/darkblue, +/obj/item/key/CAPT, +/turf/open/floor/wood, +/area/command/heads_quarters/captain/private) +"ahb" = ( +/obj/machinery/camera{ + c_tag = "Prison Common Room"; + network = list("ss13","prison") + }, +/obj/effect/decal/festive/green_stockings, +/turf/open/floor/wood, +/area/command/heads_quarters/captain/private) +"ahc" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWEMiddle, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/captain/private) +"ahd" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/closed/festive/whitebrick, +/area/ai_monitored/command/nuke_storage) +"ahe" = ( +/obj/structure/sign/warning/securearea, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/closed/festive/whitebrick, +/area/ai_monitored/command/nuke_storage) +"ahf" = ( +/obj/effect/mapping_helpers/airlock/locked, +/obj/machinery/door/airlock/vault{ + req_access_txt = "53" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/nuke_storage) +"ahg" = ( +/obj/structure/sign/warning/securearea, +/turf/closed/festive/whitebrick, +/area/ai_monitored/command/nuke_storage) +"ahh" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai) +"ahi" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai) +"ahj" = ( +/obj/item/stack/sheet/rglass{ + amount = 50 + }, +/obj/item/stack/sheet/rglass{ + amount = 50 + }, +/obj/item/stack/rods/fifty, +/obj/item/stack/rods/fifty, +/obj/structure/table, +/obj/item/storage/toolbox/mechanical{ + pixel_x = -2; + pixel_y = -1 + }, +/obj/item/storage/toolbox/mechanical{ + pixel_x = -2; + pixel_y = -1 + }, +/obj/machinery/power/apc{ + areastring = "/area/ai_monitored/command/storage/eva"; + dir = 8; + name = "E.V.A. Storage APC"; + pixel_x = -24 + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/storage/eva) +"ahk" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"ahl" = ( +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"ahm" = ( +/obj/machinery/door/window/northleft{ + dir = 8; + name = "Magboot Storage"; + pixel_x = -1; + req_access_txt = "19" + }, +/obj/structure/window/reinforced{ + dir = 1; + pixel_y = 1 + }, +/obj/structure/rack, +/obj/item/clothing/shoes/magboots{ + pixel_x = -4; + pixel_y = 3 + }, +/obj/item/clothing/shoes/magboots, +/obj/item/clothing/shoes/magboots{ + pixel_x = 4; + pixel_y = -3 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/storage/eva) +"ahn" = ( +/obj/structure/window/reinforced, +/turf/open/floor/plasteel/dark, +/area/command/gateway) +"aho" = ( +/obj/machinery/door/window{ + name = "Gateway Chamber"; + req_access_txt = "62" + }, +/turf/open/floor/plasteel/dark, +/area/command/gateway) +"ahp" = ( +/obj/structure/table, +/obj/item/paper_bin{ + pixel_x = -3; + pixel_y = 7 + }, +/obj/item/pen, +/obj/item/stamp/hop, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"ahq" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/machinery/computer/bounty{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"ahr" = ( +/obj/structure/table/wood/fancy/red, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"ahs" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/radio, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"aht" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"ahu" = ( +/obj/structure/table/wood/fancy/green, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/item/clothing/neck/cloak/festive, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"ahv" = ( +/obj/structure/window/reinforced, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"ahw" = ( +/obj/structure/table/wood/fancy/red, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/item/clothing/suit/armor/centcom, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"ahx" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/captain/private) +"ahy" = ( +/turf/open/floor/carpet/royalblue, +/area/command/heads_quarters/captain/private) +"ahz" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/captain/private) +"ahA" = ( +/turf/closed/festive/whitebrick, +/area/command/teleporter) +"ahB" = ( +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/command/nuke_storage) +"ahC" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/command/nuke_storage) +"ahD" = ( +/obj/machinery/status_display{ + pixel_x = -32 + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"ahE" = ( +/obj/machinery/light, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai) +"ahF" = ( +/obj/machinery/status_display/ai{ + pixel_x = 32 + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/ai) +"ahG" = ( +/obj/structure/closet/crate/rcd{ + pixel_y = 4 + }, +/obj/machinery/door/window/northleft{ + dir = 4; + name = "RCD Storage"; + pixel_x = 1; + req_access_txt = "19" + }, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 1; + pixel_y = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/storage/eva) +"ahH" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"ahI" = ( +/obj/structure/tank_dispenser/oxygen{ + pixel_x = -1; + pixel_y = 2 + }, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"ahJ" = ( +/obj/machinery/camera/motion{ + c_tag = "E.V.A. Storage"; + dir = 8 + }, +/obj/machinery/requests_console{ + department = "EVA"; + pixel_x = 32 + }, +/obj/machinery/light{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"ahK" = ( +/obj/machinery/camera{ + c_tag = "Gateway"; + dir = 4 + }, +/obj/structure/table, +/obj/structure/sign/warning/biohazard{ + pixel_x = -32 + }, +/obj/item/storage/firstaid/regular, +/turf/open/floor/plasteel, +/area/command/gateway) +"ahL" = ( +/obj/machinery/computer/gateway_control, +/turf/open/floor/plasteel, +/area/command/gateway) +"ahM" = ( +/turf/open/floor/plasteel, +/area/command/gateway) +"ahN" = ( +/obj/structure/table, +/obj/item/radio/off{ + pixel_y = 6 + }, +/obj/item/radio/off{ + pixel_x = 6; + pixel_y = 4 + }, +/obj/item/radio/off{ + pixel_x = -6; + pixel_y = 4 + }, +/obj/item/radio/off, +/turf/open/floor/plasteel, +/area/command/gateway) +"ahO" = ( +/obj/structure/table, +/obj/machinery/recharger, +/obj/structure/sign/warning/biohazard{ + pixel_x = 32 + }, +/turf/open/floor/plasteel, +/area/command/gateway) +"ahP" = ( +/obj/structure/chair{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"ahQ" = ( +/obj/structure/table, +/obj/item/folder/blue, +/obj/item/stack/packageWrap{ + pixel_x = -1; + pixel_y = -1 + }, +/obj/item/hand_labeler, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"ahR" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"ahS" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/keycard_auth{ + name = "Keycard Authentication Device \[HoP]"; + pixel_x = 26 + }, +/obj/machinery/computer/med_data{ + dir = 8 + }, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"ahT" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel, +/area/command/corporate_showroom) +"ahU" = ( +/obj/structure/chair/comfy/black{ + dir = 1 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"ahV" = ( +/obj/item/bedsheet/captain/double{ + dir = 1 + }, +/obj/structure/bed/double{ + dir = 1 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/captain/private) +"ahW" = ( +/obj/structure/chair/comfy/brown, +/obj/effect/landmark/start/captain, +/turf/open/floor/carpet/royalblue, +/area/command/heads_quarters/captain/private) +"ahX" = ( +/obj/item/storage/secure/safe{ + pixel_x = 35; + pixel_y = 5 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/captain/private) +"ahY" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = -27; + pixel_y = 1 + }, +/obj/structure/table, +/obj/item/beacon, +/turf/open/floor/plasteel, +/area/command/teleporter) +"ahZ" = ( +/obj/structure/table, +/obj/item/hand_tele, +/turf/open/floor/plasteel, +/area/command/teleporter) +"aia" = ( +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_y = 20 + }, +/obj/structure/closet/crate, +/obj/item/crowbar, +/turf/open/floor/plasteel, +/area/command/teleporter) +"aib" = ( +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/command/teleporter) +"aic" = ( +/obj/machinery/camera{ + c_tag = "Teleporter" + }, +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/turf/open/floor/plasteel, +/area/command/teleporter) +"aid" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/command/teleporter) +"aie" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/command/nuke_storage) +"aif" = ( +/obj/machinery/door/airlock/command/glass{ + name = "AI Core"; + req_access_txt = "65" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/ai) +"aig" = ( +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/metal/fifty, +/obj/structure/table, +/obj/item/stack/sheet/plasteel{ + amount = 10 + }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/obj/item/stack/sheet/glass/fifty, +/obj/item/stack/sheet/glass/fifty, +/obj/item/crowbar, +/obj/item/wrench, +/obj/item/storage/toolbox/electrical{ + pixel_x = 1; + pixel_y = -1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/storage/eva) +"aih" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/command/nuke_storage) +"aii" = ( +/obj/effect/landmark/event_spawn, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"aij" = ( +/obj/machinery/door/window/northleft{ + dir = 8; + name = "Jetpack Storage"; + pixel_x = -1; + req_access_txt = "19" + }, +/obj/structure/window/reinforced, +/obj/structure/rack, +/obj/item/tank/jetpack/carbondioxide/eva{ + pixel_x = 4; + pixel_y = -1 + }, +/obj/item/tank/jetpack/carbondioxide/eva, +/obj/item/tank/jetpack/carbondioxide/eva{ + pixel_x = -4; + pixel_y = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/command/storage/eva) +"aik" = ( +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_x = -30 + }, +/obj/item/paper/pamphlet/gateway, +/obj/structure/table, +/turf/open/floor/plasteel, +/area/command/gateway) +"ail" = ( +/obj/structure/chair/stool, +/turf/open/floor/plasteel, +/area/command/gateway) +"aim" = ( +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/turf/open/floor/plasteel, +/area/command/gateway) +"ain" = ( +/obj/machinery/light{ + light_color = "#c9d3e8" + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"aio" = ( +/obj/structure/table, +/obj/machinery/recharger, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"aip" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/requests_console{ + announcementConsole = 1; + department = "Head of Personnel's Desk"; + departmentType = 5; + name = "Head of Personnel RC"; + pixel_y = -30 + }, +/obj/machinery/computer/secure_data{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/hop/private) +"aiq" = ( +/obj/effect/turf_decal/loading_area{ + dir = 8 + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "hopqueue"; + name = "HoP Queue Shutters" + }, +/turf/open/floor/plasteel, +/area/command/corporate_showroom) +"air" = ( +/obj/machinery/light{ + light_color = "#e8eaff" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/command/corporate_showroom) +"ais" = ( +/obj/structure/dresser, +/turf/open/floor/wood, +/area/command/heads_quarters/captain/private) +"ait" = ( +/obj/structure/table/wood, +/obj/item/folder/blue, +/obj/item/stamp/captain, +/obj/item/pen/fountain/captain, +/turf/open/floor/wood, +/area/command/heads_quarters/captain/private) +"aiu" = ( +/obj/structure/table/wood, +/obj/item/hand_tele, +/turf/open/floor/wood, +/area/command/heads_quarters/captain/private) +"aiv" = ( +/obj/machinery/suit_storage_unit/captain, +/turf/open/floor/wood, +/area/command/heads_quarters/captain/private) +"aiw" = ( +/obj/machinery/power/apc{ + areastring = "/area/command/teleporter"; + dir = 8; + name = "Teleporter APC"; + pixel_x = -24 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel, +/area/command/teleporter) +"aix" = ( +/obj/machinery/light_switch{ + pixel_x = 27 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/teleporter) +"aiy" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/command/teleporter) +"aiz" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/chair/stool, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/command/teleporter) +"aiA" = ( +/obj/machinery/holopad, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/teleporter) +"aiB" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/bluespace_beacon, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/teleporter) +"aiC" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/teleporter) +"aiD" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/teleporter) +"aiE" = ( +/obj/machinery/door/airlock/command{ + name = "Teleport Access"; + req_access_txt = "17" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/teleporter) +"aiF" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/command/nuke_storage) +"aiG" = ( +/turf/closed/wall/r_wall, +/area/ai_monitored/turret_protected/aisat/hallway) +"aiH" = ( +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"aiI" = ( +/obj/effect/decal/festive/green_stockings, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"aiJ" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"aiK" = ( +/obj/machinery/holopad, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"aiL" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"aiM" = ( +/obj/structure/table, +/obj/machinery/cell_charger, +/obj/item/stock_parts/cell/high{ + charge = 100; + maxcharge = 15000 + }, +/obj/item/stock_parts/cell/high{ + charge = 100; + maxcharge = 15000 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"aiN" = ( +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 + }, +/obj/structure/closet/l3closet/scientist, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/command/gateway) +"aiO" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hop/private) +"aiP" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hop/private) +"aiQ" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hop/private) +"aiR" = ( +/turf/closed/festive/whitebrick, +/area/command/corporate_showroom) +"aiS" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plasteel/dark, +/area/command/corporate_showroom) +"aiT" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/floor/plasteel/dark, +/area/command/corporate_showroom) +"aiU" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plasteel/dark, +/area/command/corporate_showroom) +"aiV" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Atrium" + }, +/turf/open/floor/plasteel, +/area/command/corporate_showroom) +"aiW" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNS, +/turf/open/floor/plasteel/dark, +/area/command/corporate_showroom) +"aiX" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/captain/private) +"aiY" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/captain/private) +"aiZ" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/captain/private) +"aja" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/command/teleporter) +"ajb" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/command/teleporter) +"ajc" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/command/teleporter) +"ajd" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/command/teleporter) +"aje" = ( +/obj/machinery/shieldwallgen, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/command/teleporter) +"ajf" = ( +/obj/machinery/shieldwallgen, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/command/teleporter) +"ajg" = ( +/obj/structure/closet/crate, +/turf/open/floor/plasteel, +/area/command/teleporter) +"ajh" = ( +/obj/machinery/light/floor, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"aji" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/light/floor, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"ajj" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"ajk" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"ajl" = ( +/turf/closed/wall/r_wall, +/area/edina/street) +"ajm" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"ajn" = ( +/obj/machinery/button/door{ + id = "stationawaygate"; + name = "Gateway Access Shutter Control"; + pixel_x = -1; + pixel_y = -24; + req_access_txt = "31" + }, +/turf/open/floor/plasteel, +/area/command/gateway) +"ajo" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/structure/closet/secure_closet/exile, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/command/gateway) +"ajp" = ( +/obj/machinery/computer/teleporter{ + dir = 1 + }, +/turf/open/floor/plating, +/area/command/teleporter) +"ajq" = ( +/obj/machinery/teleport/station, +/turf/open/floor/plasteel/dark, +/area/command/teleporter) +"ajr" = ( +/obj/machinery/teleport/hub, +/turf/open/floor/plasteel/dark, +/area/command/teleporter) +"ajs" = ( +/obj/structure/rack, +/obj/item/tank/internals/oxygen, +/obj/item/clothing/mask/gas, +/turf/open/floor/plasteel/dark, +/area/command/teleporter) +"ajt" = ( +/obj/effect/festive/street/streetlinesouth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"aju" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"ajv" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 9 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"ajw" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"ajx" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/progcastaux) +"ajy" = ( +/obj/machinery/power/apc{ + areastring = "/area/ai_monitored/turret_protected/aisat/hallway"; + name = "MiniSat Chamber Hallway APC"; + pixel_x = null; + pixel_y = -24 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"ajz" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"ajA" = ( +/obj/machinery/door/poddoor/shutters{ + id = "evashutter"; + name = "E.V.A. Storage Shutter" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"ajB" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"ajC" = ( +/obj/machinery/button/door{ + id = "capgarage"; + name = "Captain's Garage"; + pixel_x = -28; + pixel_y = -7; + req_access_txt = "20" + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 9 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"ajD" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/command{ + name = "Gateway Access"; + req_access_txt = "62" + }, +/turf/open/floor/plasteel, +/area/command/gateway) +"ajE" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters{ + id = "stationawaygate"; + name = "Gateway Access Shutters" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/delivery, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/command/gateway) +"ajF" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters{ + id = "stationawaygate"; + name = "Gateway Access Shutters" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/command/gateway) +"ajG" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/command/nuke_storage) +"ajH" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/closed/festive/whitebrick, +/area/ai_monitored/command/nuke_storage) +"ajI" = ( +/obj/machinery/door/airlock/hatch{ + name = "MiniSat Service Bay"; + req_one_access_txt = "65" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"ajJ" = ( +/obj/machinery/door/airlock/hatch{ + name = "MiniSat Chamber Hallway"; + req_one_access_txt = "65" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"ajK" = ( +/turf/closed/wall/r_wall, +/area/engineering/main) +"ajL" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 5 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"ajM" = ( +/obj/effect/festive/street/streetlineeast, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"ajN" = ( +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"ajO" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/engine, +/area/engineering/main) +"ajP" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/machinery/light/floor, +/turf/open/floor/engine, +/area/engineering/main) +"ajQ" = ( +/obj/machinery/power/port_gen/pacman, +/obj/item/stack/sheet/mineral/plasma{ + amount = 35 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"ajR" = ( +/obj/machinery/porta_turret/ai{ + dir = 4 + }, +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/aisat/hallway) +"ajS" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/ai_monitored/turret_protected/aisat/hallway) +"ajT" = ( +/obj/item/clothing/head/welding, +/obj/structure/table/reinforced, +/obj/item/stack/sheet/glass/fifty, +/obj/item/stack/sheet/metal/fifty, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"ajU" = ( +/turf/open/floor/engine, +/area/engineering/main) +"ajV" = ( +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"ajW" = ( +/obj/effect/festive/street/streetlineinnerne, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"ajX" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/engineering/main) +"ajY" = ( +/obj/machinery/power/grounding_rod, +/turf/open/floor/engine, +/area/engineering/main) +"ajZ" = ( +/obj/structure/closet/cabinet{ + pixel_y = 15 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"aka" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"akc" = ( +/turf/open/floor/festive/alleyway, +/area/edina/street) +"akd" = ( +/obj/effect/festive/street/streetlinesw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"ake" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"akf" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"akg" = ( +/turf/open/floor/grass/snow/edina, +/area/edina/street/secondary/command) +"akh" = ( +/obj/machinery/power/tesla_coil, +/obj/structure/cable, +/turf/open/floor/engine, +/area/engineering/main) +"aki" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"akj" = ( +/turf/open/floor/circuit, +/area/ai_monitored/turret_protected/aisat/hallway) +"akk" = ( +/obj/structure/rack, +/obj/item/multitool, +/obj/item/storage/toolbox/mechanical, +/obj/item/storage/toolbox/electrical{ + pixel_x = -3; + pixel_y = 3 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"akl" = ( +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/turf/open/floor/grass/snow/edina, +/area/edina/street/secondary/command) +"akm" = ( +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"akn" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/command/nuke_storage) +"ako" = ( +/mob/living/simple_animal/pet/dog/pug, +/turf/open/floor/grass, +/area/edina/crew_quarters/store/pet) +"akp" = ( +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/machinery/light/floor, +/turf/open/floor/engine, +/area/engineering/main) +"akq" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/engineering/main) +"akr" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/engineering/main) +"aks" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/machinery/light/floor, +/turf/open/floor/engine, +/area/engineering/main) +"akt" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "MiniSat Service Bay"; + dir = 8; + network = list("minisat"); + start_active = 1 + }, +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"aku" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/engine, +/area/engineering/main) +"akv" = ( +/obj/machinery/power/tesla_coil, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/engine, +/area/engineering/main) +"akw" = ( +/obj/machinery/power/tesla_coil, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/engine, +/area/engineering/main) +"akx" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/engineering/main) +"aky" = ( +/obj/machinery/holopad, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"akz" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) +"akA" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) +"akB" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/grass/snow/edina, +/area/edina/street/secondary/command) +"akC" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 9 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"akD" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"akE" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"akF" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) +"akG" = ( +/obj/effect/festive/street/streetlineem, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"akH" = ( +/obj/effect/festive/street/streetlineem, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"akI" = ( +/turf/closed/wall/r_wall, +/area/engineering/atmos) +"akJ" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) +"akK" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) +"akL" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/reflector/single/anchored{ + dir = 6 + }, +/turf/open/floor/engine, +/area/engineering/main) +"akM" = ( +/obj/machinery/field/generator{ + anchored = 1 + }, +/turf/open/floor/engine, +/area/engineering/main) +"akN" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/reflector/single/anchored{ + dir = 10 + }, +/turf/open/floor/engine, +/area/engineering/main) +"akO" = ( +/obj/machinery/recharge_station, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"akP" = ( +/obj/structure/table/reinforced, +/obj/item/stock_parts/cell/high, +/obj/machinery/cell_charger, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/hallway) +"akQ" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) +"akR" = ( +/obj/machinery/manned_turret/ultimate{ + anchored = 1; + name = "Anti-Greyshit Cannon"; + projectile_type = /obj/item/projectile/beam/disabler/slug + }, +/turf/open/floor/wood, +/area/maintenance/starboard/fore) +"akS" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/turf/open/floor/wood, +/area/maintenance/starboard/fore) +"akT" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"akU" = ( +/obj/structure/streetdecor/lampfestive, +/turf/open/floor/grass/snow/edina, +/area/edina/street/secondary/command) +"akV" = ( +/turf/open/floor/plasteel/stairs/left, +/area/edina/street/secondary/command) +"akW" = ( +/obj/structure/table/wood, +/obj/item/storage/box/drinkingglasses, +/turf/open/floor/wood, +/area/maintenance/starboard/fore) +"akX" = ( +/turf/open/floor/plasteel/stairs/medium, +/area/edina/street/secondary/command) +"akY" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/table/wood, +/obj/machinery/chem_dispenser/drinks/beer, +/turf/open/floor/wood, +/area/maintenance/starboard/fore) +"akZ" = ( +/obj/structure/chair/office/dark{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/starboard/fore) +"ala" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/machinery/light/floor, +/turf/open/floor/engine, +/area/engineering/main) +"alb" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/light/floor, +/turf/open/floor/engine, +/area/engineering/main) +"alc" = ( +/turf/open/floor/plasteel/stairs/right, +/area/edina/street/secondary/command) +"ald" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"ale" = ( +/obj/effect/festive/street/streetlineem, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"alf" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) +"alg" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 5 + }, +/turf/open/floor/holofloor/ice, +/area/edina) +"alh" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"ali" = ( +/turf/open/floor/wood, +/area/maintenance/starboard/fore) +"alj" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/table/wood, +/obj/item/storage/fancy/donut_box, +/turf/open/floor/wood, +/area/maintenance/starboard/fore) +"alk" = ( +/obj/structure/reflector/single/anchored{ + dir = 6 + }, +/turf/open/floor/engine, +/area/engineering/main) +"all" = ( +/obj/structure/reflector/single/anchored{ + dir = 10 + }, +/turf/open/floor/engine, +/area/engineering/main) +"alm" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) +"aln" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) +"alo" = ( +/turf/closed/wall/mineral/iron, +/area/maintenance/starboard/fore) +"alp" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/wood, +/area/maintenance/starboard/fore) +"alq" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/maintenance/starboard/fore) +"alr" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/item/radio/intercom{ + pixel_x = 26 + }, +/turf/open/floor/wood, +/area/maintenance/starboard/fore) +"als" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/engine, +/area/engineering/main) +"alt" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"alu" = ( +/obj/effect/festive/street/streetlineem, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"alv" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina) +"alw" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"alx" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"aly" = ( +/turf/open/floor/plasteel, +/area/service/hydroponics) +"alz" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"alA" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/engineering/main) +"alB" = ( +/turf/closed/wall/r_wall, +/area/ai_monitored/turret_protected/aisat_interior) +"alC" = ( +/obj/structure/chair/sofa/right, +/obj/effect/landmark/start/cyborg, +/turf/open/floor/carpet/royalblack, +/area/ai_monitored/turret_protected/aisat_interior) +"alD" = ( +/obj/structure/chair/sofa, +/obj/effect/landmark/start/cyborg, +/turf/open/floor/carpet/royalblack, +/area/ai_monitored/turret_protected/aisat_interior) +"alE" = ( +/obj/structure/chair/sofa/left, +/obj/effect/landmark/start/cyborg, +/turf/open/floor/carpet/royalblack, +/area/ai_monitored/turret_protected/aisat_interior) +"alF" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/carpet/royalblack, +/area/ai_monitored/turret_protected/aisat_interior) +"alG" = ( +/obj/machinery/turretid{ + control_area = "/area/ai_monitored/turret_protected/aisat/hallway"; + name = "Chamber Hallway Turret Control"; + pixel_x = 32; + pixel_y = 32; + req_access = null; + req_access_txt = "65" + }, +/turf/open/floor/carpet/royalblack, +/area/ai_monitored/turret_protected/aisat_interior) +"alH" = ( +/turf/open/floor/carpet/royalblack, +/area/ai_monitored/turret_protected/aisat_interior) +"alI" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"alJ" = ( +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/castle) +"alK" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 9 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"alL" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/north) +"alM" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"alN" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 5 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"alO" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) +"alP" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/starboard/fore) +"alQ" = ( +/turf/open/floor/festive/stairs/stairsnorth, +/area/maintenance/starboard/fore) +"alR" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/stairs/stairsnorth, +/area/maintenance/starboard/fore) +"alS" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/maintenance/starboard/fore) +"alT" = ( +/turf/open/floor/festive/cobblestone/safe, +/area/edina/street) +"alU" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 10 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"alV" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) +"alW" = ( +/obj/machinery/power/tesla_coil, +/obj/structure/cable{ + icon_state = "0-2"; + pixel_y = 1 + }, +/turf/open/floor/engine, +/area/engineering/main) +"alX" = ( +/obj/structure/table/wood, +/turf/open/floor/carpet/royalblue, +/area/ai_monitored/turret_protected/aisat_interior) +"alY" = ( +/turf/open/floor/carpet/royalblue, +/area/ai_monitored/turret_protected/aisat_interior) +"alZ" = ( +/turf/closed/wall/mineral/iron, +/area/security) +"ama" = ( +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/carpet/royalblack, +/area/ai_monitored/turret_protected/aisat_interior) +"amb" = ( +/obj/structure/streetdecor/lampfestive, +/turf/open/floor/grass/snow/edina, +/area/edina) +"amc" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) +"amd" = ( +/turf/closed/wall/mineral/iron, +/area/security/processing) +"ame" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/maintenance/starboard/fore) +"amf" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/maintenance/starboard/fore) +"amg" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/stairs/stairswest, +/area/maintenance/starboard/fore) +"amh" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ami" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amj" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amk" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/door/airlock/security/glass, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"aml" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amm" = ( +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amn" = ( +/obj/machinery/door/airlock/security/glass, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amo" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amp" = ( +/obj/effect/festive/street/sidewalkw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"amq" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/festive/trainplatform/secorner, +/turf/open/floor/plating/dirt/space, +/area/edina) +"amr" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"ams" = ( +/obj/structure/festive/trainplatform/edge_west, +/turf/open/floor/plating/dirt/space, +/area/edina) +"amt" = ( +/turf/open/floor/festive/stairs/stairseast, +/area/maintenance/starboard/fore) +"amu" = ( +/turf/closed/wall/r_wall, +/area/command/heads_quarters/ce) +"amv" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "ceprivacy"; + name = "privacy shutter" + }, +/turf/open/floor/plating, +/area/command/heads_quarters/ce) +"amw" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "ceprivacy"; + name = "privacy shutter" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/command/heads_quarters/ce) +"amx" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "ceprivacy"; + name = "privacy shutter" + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/command/heads_quarters/ce) +"amy" = ( +/turf/closed/wall/mineral/iron, +/area/science/robotics/mechbay) +"amz" = ( +/turf/closed/wall/mineral/iron, +/area/security/office) +"amA" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/security/office) +"amB" = ( +/obj/machinery/manned_turret/ultimate{ + anchored = 1; + name = "Anti-Greyshit Cannon"; + projectile_type = /obj/item/projectile/beam/disabler/slug + }, +/turf/open/floor/wood, +/area/security/office) +"amC" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/light/floor, +/turf/open/floor/engine, +/area/engineering/main) +"amD" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/engineering/main) +"amE" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/machinery/light/floor, +/turf/open/floor/engine, +/area/engineering/main) +"amF" = ( +/obj/structure/fence, +/turf/open/floor/grass/snow/edina, +/area/edina) +"amG" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/engine, +/area/engineering/main) +"amH" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/machinery/light/floor, +/turf/open/floor/engine, +/area/engineering/main) +"amI" = ( +/obj/machinery/light/floor, +/turf/open/floor/carpet/royalblue, +/area/ai_monitored/turret_protected/aisat_interior) +"amJ" = ( +/obj/machinery/door/airlock/hatch{ + name = "MiniSat Foyer"; + req_one_access_txt = "32;19" + }, +/turf/open/floor/festive/alleyway, +/area/ai_monitored/turret_protected/aisat_interior) +"amK" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"amL" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/table, +/obj/item/poster/random_official, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amM" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/closet/wardrobe/mixed, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amN" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/table, +/obj/item/poster/random_official, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amO" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/closet/emcloset, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amP" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/table, +/obj/item/poster/random_official, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amQ" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/closet/wardrobe/mixed, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amR" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/closet/crate{ + icon_state = "crateopen" + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amS" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/closet/wardrobe/mixed, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amT" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amU" = ( +/obj/structure/cable/yellow, +/obj/machinery/power/apc{ + areastring = "/area/maintenance/starboard/fore"; + dir = 1; + name = "Starboard Bow Maintenance APC"; + pixel_y = -24 + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amV" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amW" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/rack, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amX" = ( +/obj/machinery/space_heater, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amY" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/closet/firecloset, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"amZ" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/closet/emcloset, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ana" = ( +/obj/structure/reagent_dispensers/watertank, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"anb" = ( +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/ce) +"anc" = ( +/obj/machinery/button/door{ + id = "ceprivacy"; + name = "Privacy Shutters Control"; + pixel_y = 26 + }, +/obj/machinery/holopad, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/ce) +"and" = ( +/obj/structure/rack, +/obj/item/lighter, +/obj/item/clothing/glasses/meson{ + pixel_y = 4 + }, +/obj/item/stock_parts/cell/high/plus, +/obj/item/reagent_containers/pill/patch/silver_sulf, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/ce) +"ane" = ( +/obj/structure/filingcabinet/chestdrawer, +/mob/living/simple_animal/parrot/Polly, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/ce) +"anf" = ( +/obj/structure/closet/secure_closet/engineering_chief, +/obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/command/heads_quarters/ce"; + dir = 4; + name = "CE Office APC"; + pixel_x = 24 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/item/key/CE, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/ce) +"ang" = ( +/obj/machinery/door/airlock/external{ + name = "External Containment Access"; + req_access_txt = "10; 13" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"anh" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/engineering/main) +"ani" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/engineering/main) +"anj" = ( +/obj/structure/flora/grass/both, +/turf/open/floor/grass/snow/edina, +/area/edina) +"ank" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"anl" = ( +/turf/closed/wall/mineral/iron, +/area/security/prison) +"anm" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"ann" = ( +/turf/closed/wall/mineral/iron, +/area/ai_monitored/security/armory) +"ano" = ( +/turf/closed/wall/mineral/iron, +/area/command/heads_quarters/hos) +"anp" = ( +/turf/closed/wall/mineral/iron, +/area/security/detectives_office) +"anq" = ( +/obj/machinery/button/door{ + id = "atmos"; + name = "Atmospherics Lockdown"; + pixel_x = -24; + pixel_y = 10; + req_access_txt = "24" + }, +/obj/machinery/button/door{ + desc = "A remote control-switch for secure storage."; + id = "Secure Storage"; + name = "Engineering Secure Storage"; + pixel_x = -24; + req_access_txt = "11" + }, +/obj/machinery/button/door{ + desc = "A remote control-switch for the engineering security doors."; + id = "Engineering"; + name = "Engineering Lockdown"; + pixel_x = -24; + pixel_y = -10; + req_access_txt = "10" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/ce) +"anr" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/ce) +"ans" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/security/office) +"ant" = ( +/turf/open/floor/wood, +/area/security/office) +"anu" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/ce) +"anv" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "ceprivacy"; + name = "privacy shutter" + }, +/turf/open/floor/plating, +/area/command/heads_quarters/ce) +"anx" = ( +/obj/machinery/power/emitter/anchored{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/circuit/red, +/area/engineering/main) +"any" = ( +/obj/machinery/the_singularitygen/tesla, +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/engineering/main) +"anz" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"anB" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/holofloor/ice, +/area/edina) +"anC" = ( +/obj/structure/flora/grass/brown, +/turf/open/floor/grass/snow/edina, +/area/edina) +"anD" = ( +/turf/open/floor/wood, +/area/security/prison) +"anE" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/wood, +/area/security/prison) +"anF" = ( +/obj/machinery/vending/cola, +/turf/open/floor/wood, +/area/security/prison) +"anG" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"anH" = ( +/obj/machinery/vending/sustenance, +/turf/open/floor/wood, +/area/security/prison) +"anI" = ( +/obj/machinery/cryopod, +/turf/open/floor/wood, +/area/security/prison) +"anJ" = ( +/obj/item/canvas/nineteenXnineteen, +/obj/structure/easel, +/turf/open/floor/wood, +/area/security/prison) +"anK" = ( +/obj/machinery/vr_sleeper, +/turf/open/floor/wood, +/area/security/prison) +"anL" = ( +/obj/machinery/button/door{ + id = "permabolt3"; + name = "Cell Bolt Control"; + normaldoorcontrol = 1; + pixel_y = 25; + specialfunctions = 4 + }, +/obj/structure/bed, +/obj/machinery/flasher{ + id = "PCell 3"; + pixel_x = -28 + }, +/obj/item/toy/plush/catgirl/fermis, +/turf/open/floor/wood, +/area/security/prison) +"anM" = ( +/obj/item/radio/intercom{ + desc = "Talk through this. It looks like it has been modified to not broadcast."; + name = "Prison Intercom (General)"; + pixel_y = 24; + prison_radio = 1 + }, +/turf/open/floor/wood, +/area/security/prison) +"anN" = ( +/obj/item/paper, +/obj/structure/table/wood, +/obj/item/pen, +/obj/machinery/camera{ + c_tag = "Prison Cell 3"; + network = list("ss13","prison") + }, +/turf/open/floor/wood, +/area/security/prison) +"anO" = ( +/obj/machinery/button/door{ + id = "permacell3"; + name = "Cell 3 Lockdown"; + pixel_x = -30; + req_access_txt = "2" + }, +/obj/machinery/button/flasher{ + id = "PCell 3"; + pixel_x = -20 + }, +/obj/structure/closet/secure_closet/brig, +/turf/open/floor/wood, +/area/security/prison) +"anP" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/closet/secure_closet/brig, +/turf/open/floor/wood, +/area/security/prison) +"anQ" = ( +/obj/structure/closet{ + name = "Evidence Closet" + }, +/turf/open/floor/wood, +/area/security/prison) +"anR" = ( +/obj/structure/rack, +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/turf/open/floor/wood, +/area/security/prison) +"anS" = ( +/obj/structure/table, +/obj/item/storage/box/firingpins, +/obj/item/storage/box/firingpins, +/obj/item/key/security, +/obj/structure/sign/poster/official/ion_rifle{ + pixel_x = -32 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"anT" = ( +/obj/structure/table, +/obj/item/storage/box/chemimp{ + pixel_x = 6 + }, +/obj/item/storage/box/trackimp{ + pixel_x = -3 + }, +/obj/item/storage/lockbox/loyalty, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"anU" = ( +/obj/structure/rack, +/obj/item/gun/ballistic/shotgun/riot{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/gun/ballistic/shotgun/riot, +/obj/item/gun/ballistic/shotgun/riot{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/effect/turf_decal/bot, +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"anV" = ( +/obj/structure/rack, +/obj/item/gun/energy/e_gun{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/gun/energy/e_gun, +/obj/item/gun/energy/e_gun{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/effect/turf_decal/bot, +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"anW" = ( +/obj/structure/rack, +/obj/item/gun/energy/laser{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/gun/energy/laser, +/obj/item/gun/energy/laser{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/effect/turf_decal/bot, +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/obj/machinery/camera/motion{ + c_tag = "Armory Motion Sensor" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"anX" = ( +/obj/structure/rack, +/obj/item/gun/energy/e_gun/advtaser{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/gun/energy/e_gun/advtaser, +/obj/item/gun/energy/e_gun/advtaser{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/effect/turf_decal/bot, +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"anY" = ( +/obj/structure/closet/secure_closet/lethalshots, +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"anZ" = ( +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/obj/structure/closet/secure_closet/contraband/armory, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"aoa" = ( +/obj/machinery/flasher/portable, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"aob" = ( +/obj/machinery/flasher/portable, +/obj/structure/sign/poster/official/enlist{ + pixel_y = 32 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"aoc" = ( +/obj/structure/dresser, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_x = 32; + pixel_y = 32 + }, +/obj/machinery/newscaster/security_unit{ + pixel_y = 32 + }, +/obj/item/storage/fancy/donut_box{ + pixel_y = 8 + }, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"aod" = ( +/obj/structure/sign/poster/contraband/donut_corp{ + pixel_y = -32 + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"aoe" = ( +/turf/closed/wall/mineral/iron, +/area/service/bar/atrium) +"aof" = ( +/obj/structure/table/wood, +/obj/machinery/light_switch{ + pixel_x = 23 + }, +/obj/machinery/computer/med_data/laptop, +/obj/machinery/requests_console{ + announcementConsole = 1; + department = "Head of Security's Desk"; + departmentType = 5; + name = "Head of Security RC"; + pixel_y = 30 + }, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"aog" = ( +/obj/structure/table/wood, +/obj/item/taperecorder, +/turf/open/floor/carpet, +/area/security/detectives_office) +"aoh" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/rack, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aoi" = ( +/obj/structure/closet/secure_closet/detective, +/turf/open/floor/carpet, +/area/security/detectives_office) +"aoj" = ( +/obj/machinery/computer/med_data, +/obj/machinery/newscaster{ + pixel_y = 32 + }, +/turf/open/floor/carpet, +/area/security/detectives_office) +"aok" = ( +/obj/machinery/computer/secure_data, +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/obj/machinery/camera, +/turf/open/floor/carpet, +/area/security/detectives_office) +"aol" = ( +/turf/open/floor/carpet, +/area/security/detectives_office) +"aom" = ( +/obj/machinery/computer/apc_control{ + dir = 4 + }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/ce) +"aon" = ( +/turf/open/floor/plasteel, +/area/command/heads_quarters/ce) +"aoo" = ( +/obj/structure/table/reinforced, +/obj/machinery/cell_charger, +/obj/item/stock_parts/cell/high/plus, +/turf/open/floor/plasteel, +/area/command/heads_quarters/ce) +"aop" = ( +/obj/structure/table/reinforced, +/obj/item/clipboard, +/obj/item/paper/monitorkey, +/turf/open/floor/plasteel, +/area/command/heads_quarters/ce) +"aoq" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/ce) +"aor" = ( +/obj/structure/cable, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "ceprivacy"; + name = "privacy shutter" + }, +/turf/open/floor/plating, +/area/command/heads_quarters/ce) +"aos" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"aot" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"aou" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/closed/wall/r_wall, +/area/engineering/main) +"aov" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"aow" = ( +/turf/open/floor/plating, +/area/engineering/main) +"aox" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/engineering/main) +"aoy" = ( +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"aoz" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"aoA" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"aoB" = ( +/obj/machinery/light/small, +/turf/open/floor/carpet/royalblack, +/area/ai_monitored/turret_protected/aisat_interior) +"aoC" = ( +/obj/structure/flora/grass/green, +/turf/open/floor/grass/snow/edina, +/area/edina) +"aoE" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/holofloor, +/area/security/prison) +"aoF" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/holofloor, +/area/security/prison) +"aoG" = ( +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet) +"aoH" = ( +/obj/structure/holohoop{ + layer = 3.9 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/holofloor, +/area/security/prison) +"aoI" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/turf/open/floor/holofloor, +/area/security/prison) +"aoJ" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/holofloor, +/area/security/prison) +"aoK" = ( +/obj/item/storage/crayons, +/turf/open/floor/wood, +/area/security/prison) +"aoL" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Security E.V.A. Storage"; + req_access_txt = "3" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/security/office) +"aoM" = ( +/obj/machinery/door/airlock/public/glass{ + id_tag = "permabolt3"; + name = "Cell 3" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/poddoor/preopen{ + id = "permacell3"; + name = "cell blast door" + }, +/turf/open/floor/wood, +/area/security/prison) +"aoN" = ( +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/security/prison) +"aoO" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Long-Term Cell 3"; + req_access_txt = "2" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/wood, +/area/security/prison) +"aoP" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Evidence Storage"; + req_access_txt = "63" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/security/prison) +"aoQ" = ( +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aoR" = ( +/obj/structure/closet{ + name = "Evidence Closet" + }, +/obj/item/radio/intercom{ + pixel_x = 26 + }, +/turf/open/floor/wood, +/area/security/prison) +"aoS" = ( +/obj/item/grenade/barrier{ + pixel_x = 4 + }, +/obj/item/grenade/barrier, +/obj/item/grenade/barrier{ + pixel_x = -4 + }, +/obj/structure/table, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"aoT" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/wood, +/area/ai_monitored/security/armory) +"aoU" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/wood, +/area/ai_monitored/security/armory) +"aoV" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/wood, +/area/ai_monitored/security/armory) +"aoW" = ( +/turf/closed/wall/r_wall, +/area/science/research) +"aoX" = ( +/turf/open/floor/grass/snow/edina, +/area/science/research) +"aoY" = ( +/obj/item/radio/intercom{ + pixel_x = 26 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"aoZ" = ( +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -24 + }, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"apa" = ( +/turf/open/floor/wood, +/area/commons/dorms) +"apb" = ( +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"apc" = ( +/obj/item/storage/secure/safe/HoS{ + pixel_x = 32 + }, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_x = 26; + pixel_y = -26 + }, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"apd" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/rack, +/obj/item/storage/briefcase, +/turf/open/floor/carpet, +/area/security/detectives_office) +"ape" = ( +/obj/machinery/holopad, +/turf/open/floor/carpet, +/area/security/detectives_office) +"apf" = ( +/obj/item/radio/intercom{ + pixel_x = 26 + }, +/turf/open/floor/carpet, +/area/security/detectives_office) +"apg" = ( +/obj/machinery/computer/card/minor/ce{ + dir = 4 + }, +/obj/machinery/requests_console{ + announcementConsole = 1; + department = "Chief Engineer's Desk"; + departmentType = 3; + name = "Chief Engineer RC"; + pixel_x = -32 + }, +/obj/machinery/camera{ + c_tag = "Chief Engineer's Office"; + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/ce) +"aph" = ( +/obj/structure/chair/office/light{ + dir = 4 + }, +/obj/effect/landmark/start/chief_engineer, +/turf/open/floor/plasteel, +/area/command/heads_quarters/ce) +"api" = ( +/obj/structure/table/reinforced, +/obj/item/folder/yellow, +/obj/item/stamp/ce, +/obj/effect/landmark/event_spawn, +/turf/open/floor/plasteel, +/area/command/heads_quarters/ce) +"apj" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/item/radio/intercom{ + dir = 4; + name = "Station Intercom (General)"; + pixel_x = 27 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/ce) +"apk" = ( +/obj/machinery/door/airlock/engineering/glass{ + name = "Server Room"; + req_access_txt = "61" + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/computer) +"apl" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/holofloor/ice, +/area/edina) +"apm" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/holofloor/ice, +/area/edina) +"apn" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"apo" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"app" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"apq" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/wood, +/area/security/prison) +"apr" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/holofloor, +/area/security/prison) +"aps" = ( +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/holofloor, +/area/security/prison) +"apt" = ( +/turf/open/floor/holofloor, +/area/security/prison) +"apu" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/turf/open/floor/holofloor, +/area/security/prison) +"apv" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/holofloor, +/area/security/prison) +"apw" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/prison) +"apx" = ( +/obj/item/radio/intercom{ + pixel_x = 26 + }, +/turf/open/floor/wood, +/area/security/prison) +"apy" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/structure/closet/secure_closet/brig, +/turf/open/floor/wood, +/area/security/prison) +"apz" = ( +/obj/vehicle/ridden/secway, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"apA" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/wood, +/area/ai_monitored/security/armory) +"apB" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/wood, +/area/ai_monitored/security/armory) +"apC" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/landmark/start/warden, +/turf/open/floor/wood, +/area/ai_monitored/security/armory) +"apD" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/landmark/event_spawn, +/turf/open/floor/wood, +/area/ai_monitored/security/armory) +"apE" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/wood, +/area/ai_monitored/security/armory) +"apF" = ( +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"apG" = ( +/obj/machinery/suit_storage_unit/security, +/turf/open/floor/wood, +/area/security/office) +"apH" = ( +/obj/structure/tank_dispenser/oxygen, +/turf/open/floor/wood, +/area/security/office) +"apI" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"apJ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"apK" = ( +/obj/machinery/door/airlock/command{ + name = "Head of Security's Office"; + req_access_txt = "58" + }, +/obj/effect/decal/festive/mistletoe, +/turf/open/floor/festive/wooden/wooden1, +/area/command/heads_quarters/hos) +"apL" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"apM" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/bottle/whiskey{ + pixel_x = 3 + }, +/obj/item/lighter, +/turf/open/floor/carpet, +/area/security/detectives_office) +"apN" = ( +/obj/structure/chair/comfy/brown, +/obj/effect/landmark/start/detective, +/turf/open/floor/carpet, +/area/security/detectives_office) +"apO" = ( +/obj/structure/table/wood, +/obj/item/camera/detective, +/turf/open/floor/carpet, +/area/security/detectives_office) +"apP" = ( +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 + }, +/turf/open/floor/carpet, +/area/security/detectives_office) +"apQ" = ( +/obj/machinery/computer/station_alert{ + dir = 4 + }, +/obj/machinery/computer/security/telescreen/ce{ + dir = 4; + pixel_x = -24 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/ce) +"apR" = ( +/obj/machinery/keycard_auth{ + pixel_y = -28 + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/ce) +"apS" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/ce) +"apT" = ( +/obj/structure/table/reinforced, +/obj/item/cartridge/engineering{ + pixel_x = 4; + pixel_y = 5 + }, +/obj/item/cartridge/engineering{ + pixel_x = -3; + pixel_y = 2 + }, +/obj/item/cartridge/engineering{ + pixel_x = 3 + }, +/obj/item/cartridge/atmos, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/ce) +"apU" = ( +/obj/machinery/light_switch{ + pixel_x = 27 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/ce) +"apV" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plating, +/area/engineering/main) +"apW" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/engineering/main) +"apX" = ( +/obj/machinery/announcement_system, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/computer) +"apY" = ( +/obj/structure/table/wood, +/obj/item/storage/fancy/donut_box, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/computer) +"apZ" = ( +/obj/structure/rack, +/obj/item/storage/toolbox/mechanical{ + pixel_x = -2; + pixel_y = -1 + }, +/obj/item/multitool, +/obj/item/radio/off, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/computer) +"aqa" = ( +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/computer) +"aqb" = ( +/obj/structure/filingcabinet/chestdrawer, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/computer) +"aqc" = ( +/obj/structure/table/wood, +/obj/item/paper_bin, +/obj/item/pen/blue, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/computer) +"aqd" = ( +/obj/structure/chair/office/dark{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/computer) +"aqe" = ( +/obj/machinery/computer/telecomms/monitor{ + dir = 8 + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/computer) +"aqf" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/holofloor/ice, +/area/edina) +"aqg" = ( +/turf/open/floor/holofloor/ice, +/area/edina) +"aqh" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/holofloor/ice, +/area/edina) +"aqi" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"aqj" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/security/prison) +"aqk" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/holofloor, +/area/security/prison) +"aql" = ( +/obj/structure/chair/stool, +/turf/open/floor/wood, +/area/security/prison) +"aqm" = ( +/obj/machinery/button/door{ + id = "permabolt2"; + name = "Cell Bolt Control"; + normaldoorcontrol = 1; + pixel_y = 25; + specialfunctions = 4 + }, +/obj/structure/bed, +/obj/machinery/flasher{ + id = "PCell 2"; + pixel_x = -28 + }, +/obj/item/toy/plush/catgirl/fermis, +/turf/open/floor/wood, +/area/security/prison) +"aqn" = ( +/obj/item/paper, +/obj/structure/table/wood, +/obj/item/pen, +/obj/machinery/camera{ + c_tag = "Prison Cell 2"; + network = list("ss13","prison") + }, +/turf/open/floor/wood, +/area/security/prison) +"aqo" = ( +/obj/machinery/button/door{ + id = "permacell2"; + name = "Cell 2 Lockdown"; + pixel_x = -30; + req_access_txt = "2" + }, +/obj/machinery/button/flasher{ + id = "PCell 2"; + pixel_x = -20 + }, +/turf/open/floor/wood, +/area/security/prison) +"aqp" = ( +/turf/open/floor/wood, +/area/service/bar/atrium) +"aqq" = ( +/obj/machinery/power/apc{ + areastring = "/area/security/prison"; + dir = 4; + name = "Prison Wing APC"; + pixel_x = 24 + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/wood, +/area/security/prison) +"aqr" = ( +/obj/structure/closet/secure_closet/brig, +/turf/open/floor/wood, +/area/security/prison) +"aqs" = ( +/obj/structure/rack, +/obj/item/storage/box/rubbershot{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/storage/box/rubbershot{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/storage/box/rubbershot, +/obj/item/storage/box/rubbershot, +/obj/item/storage/box/rubbershot{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/item/storage/box/rubbershot{ + pixel_x = 3; + pixel_y = -3 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"aqt" = ( +/obj/structure/rack, +/obj/item/gun/energy/e_gun/dragnet, +/obj/item/gun/energy/e_gun/dragnet, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"aqu" = ( +/obj/structure/rack, +/obj/item/clothing/suit/armor/bulletproof{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/clothing/suit/armor/bulletproof, +/obj/item/clothing/suit/armor/bulletproof{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/item/clothing/head/helmet/alt{ + layer = 3.00001; + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/clothing/head/helmet/alt{ + layer = 3.00001 + }, +/obj/item/clothing/head/helmet/alt{ + layer = 3.00001; + pixel_x = 3; + pixel_y = -3 + }, +/obj/structure/reagent_dispensers/peppertank{ + pixel_y = -32 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"aqv" = ( +/obj/structure/rack, +/obj/item/clothing/suit/armor/riot{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/clothing/suit/armor/riot, +/obj/item/clothing/suit/armor/riot{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/item/clothing/head/helmet/riot{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/clothing/head/helmet/riot, +/obj/item/clothing/head/helmet/riot{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/item/shield/riot{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/shield/riot, +/obj/item/shield/riot{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/machinery/button/door{ + id = "armory"; + name = "Armory Shutters"; + pixel_y = -26; + req_access_txt = "3" + }, +/obj/machinery/light, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"aqw" = ( +/obj/structure/chair/office/dark, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"aqx" = ( +/obj/structure/rack, +/obj/item/gun/energy/ionrifle, +/obj/item/gun/energy/temperature/security, +/obj/item/clothing/suit/armor/laserproof, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"aqy" = ( +/turf/open/floor/carpet/red, +/area/service/bar/atrium) +"aqz" = ( +/obj/structure/rack, +/obj/item/storage/box/teargas{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/storage/box/handcuffs, +/obj/item/storage/box/flashbangs{ + pixel_x = 3; + pixel_y = -3 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"aqA" = ( +/obj/machinery/suit_storage_unit/hos, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"aqB" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"aqC" = ( +/obj/structure/closet/secure_closet/hos, +/obj/item/key/hos, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/neck/scarf/red, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"aqD" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/security/office) +"aqE" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/security/office) +"aqF" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/wood, +/area/security/office) +"aqG" = ( +/obj/structure/filingcabinet, +/turf/open/floor/carpet, +/area/security/detectives_office) +"aqH" = ( +/obj/structure/table/wood, +/obj/machinery/computer/security/wooden_tv, +/turf/open/floor/carpet, +/area/security/detectives_office) +"aqI" = ( +/obj/structure/table/wood, +/obj/item/storage/fancy/cigarettes, +/obj/item/clothing/glasses/sunglasses, +/turf/open/floor/carpet, +/area/security/detectives_office) +"aqJ" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp/green, +/turf/open/floor/carpet, +/area/security/detectives_office) +"aqK" = ( +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aqL" = ( +/obj/machinery/light_switch{ + pixel_x = 27 + }, +/turf/open/floor/carpet, +/area/security/detectives_office) +"aqM" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/command/heads_quarters/ce) +"aqN" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/command/heads_quarters/ce) +"aqO" = ( +/obj/machinery/door/airlock/command/glass{ + name = "Chief Engineer"; + req_access_txt = "56" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/command/heads_quarters/ce) +"aqP" = ( +/obj/machinery/computer/message_monitor{ + dir = 4 + }, +/obj/machinery/newscaster{ + pixel_x = -32 + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/computer) +"aqQ" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/computer) +"aqR" = ( +/obj/machinery/light/floor, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/computer) +"aqS" = ( +/obj/machinery/computer/telecomms/server{ + dir = 8 + }, +/obj/machinery/newscaster{ + pixel_x = 32 + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/computer) +"aqT" = ( +/obj/effect/festive/street/sidewalkwem, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aqU" = ( +/obj/structure/table, +/obj/item/instrument/harmonica, +/turf/open/floor/wood, +/area/security/prison) +"aqV" = ( +/obj/machinery/door/airlock/public/glass{ + id_tag = "permabolt2"; + name = "Cell 2" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/poddoor/preopen{ + id = "permacell2"; + name = "cell blast door" + }, +/turf/open/floor/wood, +/area/security/prison) +"aqW" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Long-Term Cell 2"; + req_access_txt = "2" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/wood, +/area/security/prison) +"aqX" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/security/prison) +"aqY" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Brig Control"; + req_access_txt = "3" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/security/prison) +"aqZ" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/wood, +/area/ai_monitored/security/armory) +"ara" = ( +/obj/machinery/door/window/southleft{ + base_state = "right"; + icon_state = "right"; + name = "Armory"; + req_access_txt = "3" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"arb" = ( +/obj/machinery/door/poddoor/shutters{ + id = "armory"; + name = "Armoury Shutter" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"arc" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/window/eastleft{ + dir = 2; + name = "armoury desk"; + req_access_txt = "1" + }, +/obj/machinery/door/window/westleft{ + dir = 1; + name = "armoury desk"; + req_access_txt = "3" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/security/armory) +"ard" = ( +/obj/machinery/door/airlock/command{ + name = "Head of Security's Office"; + req_access_txt = "58" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"are" = ( +/obj/machinery/door/airlock/security{ + name = "Detective's Office"; + req_access_txt = "4" + }, +/turf/open/floor/carpet, +/area/security/detectives_office) +"arf" = ( +/obj/machinery/computer/station_alert{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"arg" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"arh" = ( +/obj/machinery/power/apc/highcap/fifteen_k{ + areastring = "/area/engineering/main"; + dir = 1; + name = "Engineering APC"; + pixel_y = 25 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"ari" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"ark" = ( +/obj/machinery/quantumpad{ + map_pad_id = "EngieL2"; + map_pad_link_id = "AME" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"arl" = ( +/obj/machinery/vending/engineering, +/turf/open/floor/plasteel, +/area/engineering/main) +"arm" = ( +/obj/structure/particle_accelerator/end_cap, +/obj/structure/particle_accelerator/fuel_chamber, +/obj/structure/particle_accelerator/particle_emitter/center, +/obj/structure/particle_accelerator/particle_emitter/left, +/obj/structure/particle_accelerator/particle_emitter/right, +/obj/structure/particle_accelerator/power_box, +/obj/machinery/particle_accelerator/control_box, +/obj/structure/closet/crate/engineering{ + name = "Particle Accelerator Crate" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/engineering/main) +"arn" = ( +/obj/item/stack/cable_coil/red, +/obj/item/wrench, +/obj/item/weldingtool/largetank, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/power/apc/highcap/fifteen_k{ + areastring = "/area/engineering/main"; + dir = 1; + name = "Engineering APC"; + pixel_x = 30 + }, +/obj/structure/cable, +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/engineering/main) +"aro" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/tcommsat/server) +"arp" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/tcommsat/server) +"arq" = ( +/obj/machinery/door/airlock/engineering/glass{ + name = "Server Room"; + req_access_txt = "61" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"arr" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/tcommsat/server) +"ars" = ( +/obj/vehicle/ridden/secway, +/obj/item/key/security, +/turf/open/floor/wood, +/area/security/office) +"art" = ( +/obj/item/radio/intercom{ + pixel_x = 26 + }, +/turf/open/floor/wood, +/area/security/office) +"aru" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/tcommsat/server) +"arv" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/tcommsat/server) +"arw" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 8; + name = "8maintenance loot spawner" + }, +/obj/structure/table, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"arx" = ( +/obj/structure/weightmachine/weightlifter, +/turf/open/floor/wood, +/area/security/prison) +"ary" = ( +/obj/item/toy/cards/deck, +/obj/structure/table, +/turf/open/floor/wood, +/area/security/prison) +"arz" = ( +/obj/item/paper_bin{ + pixel_x = -3; + pixel_y = 7 + }, +/obj/item/pen, +/obj/structure/table, +/turf/open/floor/wood, +/area/security/prison) +"arA" = ( +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/prison) +"arB" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/security/prison) +"arC" = ( +/turf/closed/wall/mineral/iron, +/area/security/warden) +"arD" = ( +/obj/structure/table, +/obj/item/folder/red, +/obj/item/pen, +/obj/item/hand_labeler, +/obj/item/book/manual/wiki/security_space_law, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/wood, +/area/security/warden) +"arE" = ( +/turf/open/floor/wood, +/area/security/warden) +"arF" = ( +/obj/structure/bed/double, +/obj/structure/sign/poster/official/nt_storm_officer{ + pixel_y = 32 + }, +/obj/item/bedsheet/hos/double, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"arG" = ( +/obj/machinery/computer/security, +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/turf/open/floor/wood, +/area/security/warden) +"arH" = ( +/obj/machinery/computer/secure_data, +/turf/open/floor/wood, +/area/security/warden) +"arI" = ( +/obj/structure/table, +/obj/item/storage/box/drinkingglasses, +/obj/item/storage/fancy/donut_box, +/turf/open/floor/wood, +/area/security/warden) +"arJ" = ( +/obj/item/clothing/gloves/color/latex, +/obj/item/clothing/mask/surgical, +/obj/item/reagent_containers/spray/cleaner, +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/security/brig) +"arK" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/security/brig) +"arL" = ( +/obj/machinery/iv_drip, +/obj/item/reagent_containers/blood, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_y = 24 + }, +/turf/open/floor/plasteel/white, +/area/security/brig) +"arM" = ( +/obj/machinery/computer/security/hos{ + dir = 4 + }, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"arN" = ( +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"arO" = ( +/obj/structure/table/wood, +/obj/item/book/manual/wiki/security_space_law, +/obj/item/radio/off{ + pixel_y = 3 + }, +/obj/item/taperecorder{ + pixel_x = -4 + }, +/obj/item/cartridge/detective, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"arP" = ( +/obj/machinery/photocopier, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"arQ" = ( +/obj/structure/table/reinforced, +/obj/machinery/recharger, +/turf/open/floor/wood, +/area/security/office) +"arR" = ( +/obj/item/clothing/mask/gas/sechailer{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/clothing/mask/gas/sechailer{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/clothing/mask/gas/sechailer{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/assembly/flash/handheld, +/obj/item/assembly/flash/handheld, +/obj/item/assembly/flash/handheld, +/obj/structure/rack, +/turf/open/floor/wood, +/area/security/office) +"arS" = ( +/obj/machinery/modular_computer/console/preset/engineering{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"arT" = ( +/obj/structure/chair/comfy/black{ + dir = 8 + }, +/obj/effect/landmark/start/station_engineer, +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/engineering/main) +"arU" = ( +/obj/machinery/door/window/southleft{ + dir = 4; + name = "Engineering"; + req_access_txt = "10" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"arV" = ( +/obj/machinery/light/floor, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"arW" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/engineering/engine_smes) +"arX" = ( +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"arY" = ( +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"arZ" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"asa" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/turf/open/floor/holofloor, +/area/security/prison) +"asb" = ( +/obj/item/toy/beach_ball/holoball, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/turf/open/floor/holofloor, +/area/security/prison) +"asc" = ( +/obj/structure/table, +/obj/machinery/light/floor, +/turf/open/floor/wood, +/area/security/prison) +"asd" = ( +/obj/structure/table, +/turf/open/floor/wood, +/area/security/prison) +"ase" = ( +/obj/machinery/button/door{ + id = "permabolt1"; + name = "Cell Bolt Control"; + normaldoorcontrol = 1; + pixel_y = 25; + specialfunctions = 4 + }, +/obj/structure/bed, +/obj/machinery/flasher{ + id = "PCell 1"; + pixel_x = -28 + }, +/obj/item/toy/plush/catgirl/fermis, +/turf/open/floor/wood, +/area/security/prison) +"asf" = ( +/obj/item/paper, +/obj/structure/table/wood, +/obj/item/pen, +/obj/machinery/camera{ + c_tag = "Prison Cell 1"; + network = list("ss13","prison") + }, +/turf/open/floor/wood, +/area/security/prison) +"asg" = ( +/obj/machinery/button/door{ + id = "permacell1"; + name = "Cell 1 Lockdown"; + pixel_x = -30; + req_access_txt = "2" + }, +/obj/machinery/button/flasher{ + id = "PCell 1"; + pixel_x = -20 + }, +/turf/open/floor/wood, +/area/security/prison) +"ash" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/wood, +/area/security/warden) +"asi" = ( +/obj/structure/table, +/obj/machinery/recharger, +/turf/open/floor/wood, +/area/security/warden) +"asj" = ( +/obj/structure/table, +/obj/machinery/chem_dispenser/drinks/beer{ + dir = 8 + }, +/obj/item/radio/intercom{ + pixel_x = 26 + }, +/turf/open/floor/wood, +/area/security/warden) +"ask" = ( +/obj/item/storage/box/bodybags, +/obj/structure/extinguisher_cabinet{ + pixel_x = -27 + }, +/obj/item/reagent_containers/syringe{ + name = "steel point" + }, +/obj/item/reagent_containers/glass/bottle/charcoal, +/obj/item/reagent_containers/glass/bottle/epinephrine, +/obj/machinery/light{ + dir = 8 + }, +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/security/brig) +"asl" = ( +/turf/open/floor/plasteel/white, +/area/security/brig) +"asm" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/structure/bodycontainer/morgue{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/security/brig) +"asn" = ( +/obj/machinery/computer/secure_data{ + dir = 4 + }, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"aso" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"asp" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/obj/effect/landmark/start/head_of_security, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"asq" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/holopad, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"asr" = ( +/obj/structure/chair/office/dark{ + dir = 4 + }, +/obj/effect/landmark/start/head_of_security, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"ass" = ( +/obj/machinery/computer/prisoner/management{ + dir = 8 + }, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"ast" = ( +/obj/machinery/holopad, +/turf/open/floor/wood, +/area/security/office) +"asu" = ( +/obj/structure/window/reinforced, +/obj/machinery/computer/atmos_alert{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"asv" = ( +/obj/structure/window/reinforced, +/turf/open/floor/plasteel, +/area/engineering/main) +"asw" = ( +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"asx" = ( +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/vending/wardrobe/engi_wardrobe, +/turf/open/floor/plasteel, +/area/engineering/main) +"asy" = ( +/obj/structure/window/reinforced, +/obj/machinery/vending/tool, +/turf/open/floor/plasteel, +/area/engineering/main) +"asz" = ( +/obj/structure/window/reinforced, +/obj/machinery/vending/engivend, +/turf/open/floor/plasteel, +/area/engineering/main) +"asA" = ( +/obj/machinery/power/smes/engineering, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel, +/area/engineering/engine_smes) +"asB" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/power/terminal{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/engine_smes) +"asC" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/engineering/engine_smes) +"asD" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/power/terminal{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/engine_smes) +"asE" = ( +/obj/machinery/telecomms/server/presets/service, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"asF" = ( +/obj/machinery/telecomms/server/presets/supply, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"asG" = ( +/obj/machinery/blackbox_recorder, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"asH" = ( +/obj/machinery/telecomms/server/presets/common, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"asI" = ( +/obj/machinery/telecomms/server/presets/engineering, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"asJ" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Security E.V.A. Storage"; + req_access_txt = "3" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/security/office) +"asK" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"asL" = ( +/obj/structure/fence, +/obj/structure/streetdecor/lampfestive{ + pixel_x = 16 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"asM" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/holofloor, +/area/security/prison) +"asN" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/turf/open/floor/holofloor, +/area/security/prison) +"asO" = ( +/obj/structure/table, +/obj/machinery/computer/libraryconsole/bookmanagement, +/turf/open/floor/wood, +/area/security/prison) +"asP" = ( +/obj/machinery/door/airlock/public/glass{ + id_tag = "permabolt1"; + name = "Cell 1" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/poddoor/preopen{ + id = "permacell1"; + name = "cell blast door" + }, +/turf/open/floor/wood, +/area/security/prison) +"asQ" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Long-Term Cell 1"; + req_access_txt = "2" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/wood, +/area/security/prison) +"asR" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/security/warden) +"asS" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/security/warden) +"asT" = ( +/obj/machinery/holopad, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/security/warden) +"asU" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/power/apc{ + areastring = "/area/security/warden"; + dir = 8; + name = "Brig Control APC"; + pixel_x = 24 + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/wood, +/area/security/warden) +"asV" = ( +/obj/structure/table/glass, +/obj/machinery/computer/med_data/laptop, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/camera{ + c_tag = "Brig Infirmary"; + dir = 4 + }, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -24 + }, +/turf/open/floor/plasteel/white, +/area/security/brig) +"asW" = ( +/obj/machinery/computer/card/minor/hos{ + dir = 4 + }, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"asX" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/mob/living/simple_animal/hostile/retaliate/bat{ + desc = "A fierce companion for any person of power, this spider has been carefully trained by Nanotrasen specialists. Its beady, staring eyes send shivers down your spine."; + emote_hear = list("chitters"); + faction = list("spiders"); + harm_intent_damage = 3; + health = 200; + icon_dead = "guard_dead"; + icon_gib = "guard_dead"; + icon_living = "guard"; + icon_state = "guard"; + maxHealth = 250; + max_co2 = 5; + max_tox = 2; + melee_damage_lower = 15; + melee_damage_upper = 20; + min_oxy = 5; + movement_type = 1; + name = "Sergeant Araneus"; + real_name = "Sergeant Araneus"; + turns_per_move = 10 + }, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"asY" = ( +/obj/machinery/computer/security/labor{ + dir = 8 + }, +/obj/item/radio/intercom{ + pixel_x = 26 + }, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"asZ" = ( +/obj/structure/table/reinforced, +/obj/item/lighter, +/obj/item/folder/blue{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/folder/red{ + pixel_x = -2; + pixel_y = -2 + }, +/turf/open/floor/wood, +/area/security/office) +"ata" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/wood, +/area/security/office) +"atb" = ( +/obj/structure/chair/office/dark, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/office) +"atc" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/engine/n2, +/area/engineering/atmos) +"atd" = ( +/obj/machinery/portable_atmospherics/canister/nitrogen, +/obj/machinery/atmospherics/miner/nitrogen, +/turf/open/floor/engine/n2, +/area/engineering/atmos) +"ate" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/engine/o2, +/area/engineering/atmos) +"atf" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/machinery/atmospherics/miner/oxygen, +/turf/open/floor/engine/o2, +/area/engineering/atmos) +"atg" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"ath" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/machinery/rnd/production/protolathe/department/engineering, +/turf/open/floor/plasteel, +/area/engineering/main) +"ati" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"atj" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"atk" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/closet/crate/solarpanel_small, +/turf/open/floor/plasteel, +/area/engineering/main) +"atl" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/item/clothing/gloves/color/yellow, +/obj/item/clothing/gloves/color/yellow, +/obj/item/pipe_dispenser, +/obj/item/clothing/glasses/meson/engine, +/obj/structure/rack, +/turf/open/floor/plasteel, +/area/engineering/main) +"atm" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/engineering/engine_smes) +"atn" = ( +/obj/machinery/telecomms/processor/preset_two, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"ato" = ( +/obj/machinery/telecomms/bus/preset_two, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"atp" = ( +/obj/machinery/telecomms/broadcaster/preset_left, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"atq" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"atr" = ( +/obj/machinery/telecomms/broadcaster/preset_right, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"ats" = ( +/obj/machinery/telecomms/processor/preset_four, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"att" = ( +/obj/machinery/telecomms/bus/preset_four, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"atu" = ( +/obj/structure/fence, +/obj/structure/fence, +/turf/open/floor/grass/snow/edina, +/area/edina) +"atv" = ( +/obj/structure/ice_stasis, +/turf/open/floor/holofloor/ice, +/area/edina) +"atw" = ( +/obj/item/flashlight/seclite, +/obj/item/flashlight/seclite, +/obj/item/flashlight/seclite, +/obj/item/restraints/handcuffs, +/obj/item/restraints/handcuffs, +/obj/item/restraints/handcuffs, +/obj/structure/rack, +/turf/open/floor/wood, +/area/security/office) +"atx" = ( +/obj/effect/landmark/start/security_officer, +/turf/open/floor/wood, +/area/security/office) +"aty" = ( +/obj/structure/table/reinforced, +/obj/item/storage/fancy/donut_box, +/turf/open/floor/wood, +/area/security/office) +"atz" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"atA" = ( +/obj/structure/grille, +/obj/structure/grille, +/turf/closed/wall/r_wall, +/area/engineering/atmos) +"atB" = ( +/obj/structure/grille, +/turf/closed/wall/r_wall, +/area/engineering/atmos) +"atC" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/closet/toolcloset, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"atD" = ( +/obj/machinery/washing_machine, +/turf/open/floor/wood, +/area/security/prison) +"atE" = ( +/obj/structure/filingcabinet/chestdrawer, +/obj/machinery/requests_console{ + department = "Security"; + departmentType = 5; + pixel_x = -30 + }, +/turf/open/floor/wood, +/area/security/warden) +"atF" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/security/warden) +"atG" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk, +/turf/open/floor/wood, +/area/security/warden) +"atH" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/festive/street/streetlineem, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"atI" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"atJ" = ( +/obj/item/storage/toolbox/drone, +/obj/structure/table, +/turf/open/floor/wood, +/area/security/warden) +"atK" = ( +/obj/structure/table, +/obj/item/toy/figure/warden, +/turf/open/floor/wood, +/area/security/warden) +"atL" = ( +/obj/effect/landmark/start/warden, +/obj/structure/chair/office/dark, +/obj/machinery/button/door{ + id = "Prison Gate"; + name = "Prison Wing Lockdown"; + pixel_x = -27; + pixel_y = 8; + req_access_txt = "2" + }, +/obj/machinery/button/door{ + id = "Secure Gate"; + name = "Cell Shutters"; + pixel_x = -27; + pixel_y = -2 + }, +/turf/open/floor/wood, +/area/security/warden) +"atM" = ( +/obj/machinery/computer/crew{ + dir = 8 + }, +/turf/open/floor/wood, +/area/security/warden) +"atN" = ( +/obj/structure/closet/secure_closet/warden, +/turf/open/floor/wood, +/area/security/warden) +"atO" = ( +/obj/item/storage/firstaid/regular{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/firstaid/regular, +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/turf/open/floor/plasteel/white, +/area/security/brig) +"atP" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/security/brig) +"atQ" = ( +/obj/structure/bed, +/obj/item/clothing/suit/straight_jacket, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/security/brig) +"atR" = ( +/obj/structure/bed, +/obj/item/clothing/suit/straight_jacket, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/security/brig) +"atS" = ( +/obj/machinery/computer/crew{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"atT" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"atU" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"atV" = ( +/obj/structure/table/wood, +/obj/item/stamp/hos, +/obj/item/folder/red{ + pixel_x = 3 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/recharger{ + pixel_x = -8; + pixel_y = 6 + }, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"atW" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"atX" = ( +/obj/structure/table/reinforced, +/obj/item/paper_bin, +/obj/item/storage/fancy/donut_box, +/turf/open/floor/wood, +/area/security/office) +"atY" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/security/office) +"atZ" = ( +/obj/machinery/computer/secure_data{ + dir = 1 + }, +/turf/open/floor/wood, +/area/security/office) +"aua" = ( +/obj/machinery/rnd/production/techfab/department/security, +/turf/open/floor/wood, +/area/security/office) +"aub" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/nitrogen_output, +/turf/open/floor/engine/n2, +/area/engineering/atmos) +"auc" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/nitrogen_input, +/turf/open/floor/engine/n2, +/area/engineering/atmos) +"aud" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/oxygen_output, +/turf/open/floor/engine/o2, +/area/engineering/atmos) +"aue" = ( +/obj/structure/table/reinforced, +/obj/item/storage/fancy/donut_box, +/obj/item/radio/intercom{ + pixel_x = 26 + }, +/turf/open/floor/wood, +/area/security/office) +"auf" = ( +/turf/open/floor/engine/n2, +/area/engineering/atmos) +"aug" = ( +/turf/open/floor/engine/o2, +/area/engineering/atmos) +"auh" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/oxygen_input, +/turf/open/floor/engine/o2, +/area/engineering/atmos) +"aui" = ( +/obj/machinery/computer/rdconsole/production{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"auj" = ( +/obj/effect/landmark/start/station_engineer, +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/engineering/main) +"auk" = ( +/obj/machinery/door/window/southleft{ + dir = 8; + name = "Engineering"; + req_access_txt = "10" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"aul" = ( +/obj/item/clothing/gloves/color/yellow, +/obj/item/clothing/gloves/color/yellow, +/obj/item/pipe_dispenser, +/obj/item/clothing/glasses/meson/engine, +/obj/structure/rack, +/turf/open/floor/plasteel, +/area/engineering/main) +"aum" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/engineering/engine_smes) +"aun" = ( +/obj/machinery/telecomms/hub/preset, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"auo" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"aup" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"auq" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/tcommsat/server"; + dir = 4; + name = "Telecomms Server APC"; + pixel_x = 25 + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"aur" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"aus" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/closet/toolcloset, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"aut" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/holofloor, +/area/security/prison) +"auu" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/turf/open/floor/holofloor, +/area/security/prison) +"auv" = ( +/obj/machinery/holopad, +/turf/open/floor/wood, +/area/security/prison) +"auw" = ( +/obj/machinery/door/airlock{ + name = "Unisex Restroom" + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison) +"aux" = ( +/turf/open/floor/plasteel/freezer, +/area/security/prison) +"auy" = ( +/obj/structure/urinal{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison) +"auz" = ( +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/obj/structure/mirror{ + pixel_x = 30 + }, +/obj/item/soap/nanotrasen, +/turf/open/floor/plasteel/freezer, +/area/security/prison) +"auA" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Prison Wing"; + req_access_txt = "2" + }, +/obj/machinery/door/poddoor/preopen{ + id = "Prison Gate"; + name = "prison blast door" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/security/prison) +"auB" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Prison Wing"; + req_access_txt = "2" + }, +/obj/machinery/door/poddoor/preopen{ + id = "Prison Gate"; + name = "prison blast door" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/security/prison) +"auC" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Brig Control"; + req_access_txt = "3" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/security/warden) +"auD" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/security/warden) +"auE" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/wood, +/area/security/warden) +"auF" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"auG" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/effect/decal/festive/holly, +/turf/open/floor/wood, +/area/security/warden) +"auH" = ( +/obj/machinery/door/window/southleft{ + name = "Reception Desk"; + req_access_txt = "63" + }, +/obj/structure/table/reinforced, +/obj/machinery/door/window/brigdoor{ + dir = 1; + name = "Armory Desk"; + req_access_txt = "3" + }, +/obj/item/pen{ + pixel_x = 4; + pixel_y = 4 + }, +/obj/item/paper_bin{ + pixel_x = -3; + pixel_y = 7 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/security/warden) +"auI" = ( +/turf/closed/wall/mineral/iron, +/area/security/brig) +"auJ" = ( +/obj/machinery/door/airlock/security/glass{ + id_tag = "innerbrig"; + name = "Brig"; + req_access_txt = "63" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/white, +/area/security/brig) +"auK" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow, +/turf/open/floor/plating, +/area/command/heads_quarters/hos) +"auL" = ( +/obj/machinery/door/airlock/command{ + name = "Head of Security's Office"; + req_access_txt = "58" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"auM" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Security Office"; + req_access_txt = "63" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plating, +/area/security/office) +"auN" = ( +/obj/structure/grille, +/obj/machinery/atmospherics/pipe/layer_manifold{ + dir = 1 + }, +/turf/closed/wall/r_wall, +/area/engineering/atmos) +"auO" = ( +/obj/structure/grille, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/engine/vacuum, +/area/engineering/atmos) +"auP" = ( +/obj/structure/grille, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 1 + }, +/turf/closed/wall/r_wall, +/area/engineering/atmos) +"auQ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/office) +"auR" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/wood, +/area/security/office) +"auS" = ( +/obj/structure/grille, +/obj/machinery/atmospherics/pipe/layer_manifold, +/turf/closed/wall/r_wall, +/area/engineering/atmos) +"auT" = ( +/obj/structure/window/reinforced, +/obj/machinery/rnd/production/circuit_imprinter, +/turf/open/floor/plasteel, +/area/engineering/main) +"auU" = ( +/obj/structure/closet/crate, +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/rods/fifty, +/obj/item/stack/sheet/glass/fifty, +/obj/item/electronics/airlock, +/obj/item/electronics/airlock, +/obj/item/stock_parts/cell/high/plus, +/obj/item/stack/sheet/mineral/plasma{ + amount = 30 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced, +/turf/open/floor/plasteel, +/area/engineering/main) +"auV" = ( +/obj/structure/window/reinforced, +/obj/item/clothing/gloves/color/yellow, +/obj/item/clothing/gloves/color/yellow, +/obj/item/pipe_dispenser, +/obj/item/clothing/glasses/meson/engine, +/obj/structure/rack, +/turf/open/floor/plasteel, +/area/engineering/main) +"auW" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/closed/wall/r_wall, +/area/engineering/engine_smes) +"auX" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/machinery/door/airlock/engineering{ + name = "Engine Room"; + req_access_txt = "10" + }, +/turf/open/floor/plasteel, +/area/engineering/engine_smes) +"auY" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/closed/wall/r_wall, +/area/engineering/engine_smes) +"auZ" = ( +/obj/machinery/telecomms/bus/preset_one, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"ava" = ( +/obj/machinery/telecomms/processor/preset_one, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"avb" = ( +/obj/machinery/telecomms/receiver/preset_left, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"avc" = ( +/obj/machinery/telecomms/receiver/preset_right, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"avd" = ( +/obj/machinery/telecomms/bus/preset_three, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"ave" = ( +/obj/machinery/telecomms/processor/preset_three, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"avf" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/holofloor, +/area/security/prison) +"avg" = ( +/obj/structure/table, +/obj/structure/bedsheetbin/towel, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/prison) +"avh" = ( +/obj/machinery/light/small, +/obj/item/bikehorn/rubberducky, +/turf/open/floor/plasteel/freezer, +/area/security/prison) +"avi" = ( +/turf/open/floor/wood, +/area/security/brig) +"avj" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/security/brig) +"avk" = ( +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/turf/open/floor/wood, +/area/security/brig) +"avl" = ( +/obj/structure/disposalpipe/junction/yjunction{ + dir = 4 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/wood, +/area/security/brig) +"avm" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/wood, +/area/security/brig) +"avn" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/wood, +/area/security/brig) +"avo" = ( +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/obj/machinery/power/apc/auto_name/north, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/wood, +/area/security/brig) +"avp" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/wood, +/area/security/brig) +"avq" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/wood, +/area/security/brig) +"avr" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/security/brig) +"avs" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/wood, +/area/security/brig) +"avt" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/processing) +"avu" = ( +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/progcastaux) +"avv" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/machinery/computer/shuttle/labor, +/turf/open/floor/wood, +/area/security/processing) +"avw" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/machinery/computer/security/labor, +/turf/open/floor/wood, +/area/security/processing) +"avx" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/machinery/computer/secure_data, +/turf/open/floor/wood, +/area/security/processing) +"avy" = ( +/obj/machinery/recharger, +/obj/structure/table/reinforced, +/turf/open/floor/wood, +/area/security/processing) +"avz" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1, +/obj/machinery/atmospherics/components/unary/portables_connector/layer3{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"avA" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"avB" = ( +/obj/machinery/suit_storage_unit/engine, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"avC" = ( +/obj/machinery/suit_storage_unit/engine, +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"avD" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/reagent_dispensers/watertank, +/turf/open/floor/plasteel, +/area/engineering/main) +"avE" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/machinery/atmospherics/components/unary/portables_connector/visible, +/turf/open/floor/plasteel, +/area/engineering/main) +"avF" = ( +/obj/structure/closet, +/obj/item/clothing/suit/hooded/wintercoat/engineering, +/obj/item/clothing/suit/hooded/wintercoat/engineering, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/mask/gas, +/obj/item/clothing/mask/gas, +/turf/open/floor/plasteel, +/area/engineering/main) +"avG" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"avH" = ( +/obj/machinery/telecomms/server/presets/science, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"avI" = ( +/obj/machinery/telecomms/server/presets/medical, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"avJ" = ( +/obj/machinery/power/terminal{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"avK" = ( +/obj/machinery/power/smes{ + charge = 5e+006 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"avL" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"avM" = ( +/obj/machinery/telecomms/server/presets/command, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"avN" = ( +/obj/machinery/telecomms/server/presets/security, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"avO" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"avP" = ( +/obj/structure/streetdecor/bigtree{ + pixel_x = -16 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"avQ" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/table, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"avR" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green, +/turf/open/floor/holofloor, +/area/security/prison) +"avS" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/holofloor, +/area/security/prison) +"avT" = ( +/obj/structure/holohoop{ + dir = 1; + layer = 4.1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/turf/open/floor/holofloor, +/area/security/prison) +"avU" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/turf/open/floor/holofloor, +/area/security/prison) +"avV" = ( +/obj/machinery/computer/security{ + dir = 1 + }, +/turf/open/floor/wood, +/area/security/office) +"avW" = ( +/obj/machinery/disposal/bin, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/turf/open/floor/wood, +/area/security/office) +"avX" = ( +/obj/machinery/photocopier, +/turf/open/floor/wood, +/area/security/office) +"avY" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/turf/open/floor/holofloor, +/area/security/prison) +"avZ" = ( +/obj/item/cultivator, +/turf/open/floor/wood, +/area/security/prison) +"awa" = ( +/obj/item/shovel/spade, +/turf/open/floor/wood, +/area/security/prison) +"awb" = ( +/obj/item/reagent_containers/glass/bucket, +/turf/open/floor/wood, +/area/security/prison) +"awc" = ( +/obj/item/plant_analyzer, +/turf/open/floor/wood, +/area/security/prison) +"awd" = ( +/obj/machinery/door/airlock{ + name = "Unit 1" + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison) +"awe" = ( +/obj/machinery/door/airlock{ + name = "Unit 2" + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison) +"awf" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/wood, +/area/security/brig) +"awg" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/brig) +"awh" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/brig) +"awi" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/wood, +/area/security/brig) +"awj" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/wood, +/area/security/brig) +"awk" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/brig) +"awl" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/holopad, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/brig) +"awm" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/brig) +"awn" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/brig) +"awo" = ( +/obj/structure/fence, +/turf/open/floor/grass/snow/edina, +/area/science) +"awp" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/brig) +"awq" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/sorting/mail/flip{ + dir = 4; + sortType = 8 + }, +/turf/open/floor/wood, +/area/security/brig) +"awr" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/brig) +"aws" = ( +/turf/open/floor/grass/snow/edina, +/area/science) +"awt" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/disposalpipe/sorting/mail/flip{ + dir = 4; + sortType = 7 + }, +/turf/open/floor/wood, +/area/security/brig) +"awu" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Security Transferring Control"; + req_access_txt = "63" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/security/processing) +"awv" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/processing) +"aww" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/processing) +"awx" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/processing) +"awy" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/wood, +/area/security/processing) +"awz" = ( +/turf/open/floor/wood, +/area/security/processing) +"awA" = ( +/obj/effect/decal/festive/fairylights, +/obj/structure/chair/sofa/corner{ + dir = 4 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/ce) +"awB" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1, +/obj/machinery/atmospherics/components/binary/pump, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"awC" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"awD" = ( +/obj/machinery/atmospherics/components/trinary/filter/atmos/n2{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"awE" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"awF" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1, +/obj/machinery/atmospherics/components/binary/pump, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"awG" = ( +/obj/machinery/atmospherics/components/trinary/filter/atmos/o2{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"awH" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"awI" = ( +/obj/machinery/portable_atmospherics/pump, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"awJ" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/structure/fans/tiny, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/door/airlock/engineering{ + name = "Engine Room"; + req_access_txt = "10" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"awK" = ( +/obj/machinery/ntnet_relay, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"awL" = ( +/obj/machinery/camera{ + c_tag = "Telecomms Server Room"; + dir = 1; + network = list("tcomms") + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"awM" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/holofloor/ice, +/area/edina) +"awN" = ( +/obj/machinery/light, +/turf/open/floor/wood, +/area/security/prison) +"awO" = ( +/obj/machinery/biogenerator, +/turf/open/floor/wood, +/area/security/prison) +"awP" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/office) +"awQ" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/security/office) +"awR" = ( +/obj/machinery/seed_extractor, +/turf/open/floor/wood, +/area/security/prison) +"awS" = ( +/obj/machinery/hydroponics/constructable, +/obj/item/seeds/glowshroom, +/turf/open/floor/wood, +/area/security/prison) +"awT" = ( +/obj/machinery/hydroponics/constructable, +/obj/item/seeds/grass, +/turf/open/floor/wood, +/area/security/prison) +"awU" = ( +/obj/machinery/hydroponics/constructable, +/obj/item/seeds/corn, +/turf/open/floor/wood, +/area/security/prison) +"awV" = ( +/obj/machinery/hydroponics/constructable, +/obj/item/seeds/poppy, +/turf/open/floor/wood, +/area/security/prison) +"awW" = ( +/obj/structure/toilet{ + dir = 1 + }, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison) +"awX" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/toilet{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison) +"awY" = ( +/obj/effect/festive/street/streetlineem, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"awZ" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/security/brig) +"axa" = ( +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/security/brig) +"axb" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/security/brig) +"axc" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/wood, +/area/security/brig) +"axd" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/wood, +/area/security/brig) +"axe" = ( +/obj/machinery/door_timer{ + id = "Cell 1"; + name = "Cell 1"; + pixel_y = -32 + }, +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/security/brig) +"axf" = ( +/obj/machinery/door_timer{ + id = "Cell 2"; + name = "Cell 2"; + pixel_y = -32 + }, +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/security/brig) +"axg" = ( +/obj/machinery/door_timer{ + id = "Cell 3"; + name = "Cell 3"; + pixel_y = -32 + }, +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/security/brig) +"axh" = ( +/obj/machinery/door_timer{ + id = "Cell 4"; + name = "Cell 4"; + pixel_y = -32 + }, +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/security/brig) +"axi" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/security/brig) +"axj" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow, +/turf/open/floor/plating, +/area/security/processing) +"axk" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/security/processing) +"axl" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/security/processing) +"axm" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"axn" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"axo" = ( +/obj/machinery/atmospherics/components/trinary/mixer/airmix{ + dir = 8; + node1_concentration = 0.21; + node2_concentration = 0.79; + piping_layer = 1 + }, +/obj/machinery/atmospherics/pipe/simple/yellow{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"axp" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"axq" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"axr" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"axs" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"axt" = ( +/obj/structure/closet/secure_closet/engineering_personal, +/turf/open/floor/plasteel, +/area/engineering/main) +"axu" = ( +/obj/structure/closet/secure_closet/engineering_personal, +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"axv" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plasteel, +/area/engineering/main) +"axw" = ( +/obj/structure/tank_dispenser, +/turf/open/floor/plasteel, +/area/engineering/main) +"axx" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel, +/area/engineering/main) +"axy" = ( +/obj/effect/festive/street/streetlineem, +/turf/open/floor/plasteel, +/area/engineering/main) +"axz" = ( +/obj/effect/festive/street/streetlineem, +/obj/vehicle/sealed/vectorcraft/truck, +/turf/open/floor/plasteel, +/area/engineering/main) +"axA" = ( +/obj/vehicle/sealed/vectorcraft/CE, +/obj/effect/festive/street/streetlineem, +/turf/open/floor/plasteel, +/area/engineering/main) +"axB" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/prison) +"axC" = ( +/obj/machinery/door/airlock/security/glass{ + id_tag = "innerbrig"; + name = "Brig"; + req_access_txt = "63" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/security/brig) +"axD" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow, +/turf/open/floor/plating, +/area/security/brig) +"axE" = ( +/obj/machinery/door/window/brigdoor/security/cell{ + id = "Cell 1"; + name = "Cell 1" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/security/brig) +"axF" = ( +/obj/machinery/door/window/brigdoor/security/cell{ + id = "Cell 2"; + name = "Cell 2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/security/brig) +"axG" = ( +/obj/machinery/door/window/brigdoor/security/cell{ + id = "Cell 3"; + name = "Cell 3" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/security/brig) +"axH" = ( +/obj/machinery/door/window/brigdoor/security/cell{ + id = "Cell 4"; + name = "Cell 4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/security/brig) +"axI" = ( +/turf/closed/wall/mineral/iron, +/area/service/lawoffice) +"axJ" = ( +/obj/machinery/door/airlock{ + name = "Law Office"; + req_access_txt = "38" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/wood, +/area/service/lawoffice) +"axK" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "lawyer_blast"; + name = "privacy door" + }, +/obj/structure/cable/yellow, +/turf/open/floor/plating, +/area/service/lawoffice) +"axL" = ( +/obj/machinery/power/apc{ + areastring = "/area/security/processing"; + dir = 8; + name = "Labor Shuttle Dock APC"; + pixel_x = -24 + }, +/obj/structure/cable/yellow, +/turf/open/floor/wood, +/area/security/processing) +"axM" = ( +/obj/machinery/holopad, +/turf/open/floor/wood, +/area/security/processing) +"axN" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"axO" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"axP" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"axQ" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"axR" = ( +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"axS" = ( +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"axT" = ( +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"axU" = ( +/obj/machinery/light/floor, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"axV" = ( +/obj/machinery/door/airlock/engineering, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"axW" = ( +/obj/machinery/light/floor, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"axX" = ( +/obj/machinery/button/door{ + id = "enggarage"; + name = "Engineering Garage Door"; + pixel_x = 28 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"axY" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/closed/wall/r_wall, +/area/engineering/main) +"axZ" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/stairs/stairssouth, +/area/maintenance/starboard/fore) +"aya" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/rack, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ayb" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/closet/wardrobe/mixed, +/obj/effect/spawner/lootdrop/maintenance, +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ayc" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/closet/cardboard, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ayd" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"aye" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/table, +/obj/item/flashlight/lamp, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ayf" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/table, +/obj/item/folder/white, +/obj/item/pen, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ayg" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/table, +/obj/item/paper_bin{ + pixel_x = -2; + pixel_y = 5 + }, +/obj/item/storage/fancy/donut_box, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ayh" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/table, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 8; + name = "8maintenance loot spawner" + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ayi" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/closet/wardrobe/mixed, +/obj/effect/spawner/lootdrop/maintenance, +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ayj" = ( +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ayk" = ( +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ayl" = ( +/turf/open/floor/festive/alleyway/safe, +/area/security/brig) +"aym" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway/safe, +/area/security/brig) +"ayn" = ( +/obj/structure/closet/secure_closet/brig{ + id = "Cell 1"; + name = "Cell 1 Locker" + }, +/turf/open/floor/plasteel/dark, +/area/security/brig) +"ayo" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/security/brig) +"ayp" = ( +/obj/structure/bed, +/obj/item/bedsheet, +/turf/open/floor/plasteel/dark, +/area/security/brig) +"ayq" = ( +/obj/structure/closet/secure_closet/brig{ + id = "Cell 2"; + name = "Cell 2 Locker" + }, +/turf/open/floor/plasteel/dark, +/area/security/brig) +"ayr" = ( +/obj/structure/closet/secure_closet/brig{ + id = "Cell 3"; + name = "Cell 3 Locker" + }, +/turf/open/floor/plasteel/dark, +/area/security/brig) +"ays" = ( +/obj/structure/closet/secure_closet/brig{ + id = "Cell 4"; + name = "Cell 4 Locker" + }, +/turf/open/floor/plasteel/dark, +/area/security/brig) +"ayt" = ( +/obj/machinery/requests_console{ + department = "Law office"; + pixel_x = -32 + }, +/obj/structure/rack, +/obj/item/storage/briefcase, +/turf/open/floor/wood, +/area/service/lawoffice) +"ayu" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"ayv" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/service/lawoffice) +"ayw" = ( +/obj/item/radio/intercom{ + pixel_y = 25 + }, +/obj/machinery/holopad, +/turf/open/floor/wood, +/area/service/lawoffice) +"ayx" = ( +/turf/open/floor/wood, +/area/service/lawoffice) +"ayy" = ( +/obj/machinery/photocopier, +/obj/machinery/button/door{ + id = "lawyer_blast"; + name = "Privacy Shutters"; + pixel_x = 25; + pixel_y = 8 + }, +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/turf/open/floor/wood, +/area/service/lawoffice) +"ayz" = ( +/obj/machinery/gulag_teleporter, +/turf/open/floor/wood, +/area/security/processing) +"ayA" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/door/airlock/security/glass{ + name = "Prisoner Processing"; + req_access_txt = "2" + }, +/turf/open/floor/wood, +/area/security/processing) +"ayB" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"ayC" = ( +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/engineering/main) +"ayD" = ( +/obj/item/clothing/head/beret/eng, +/turf/open/floor/plasteel, +/area/engineering/main) +"ayE" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/holofloor/ice, +/area/edina) +"ayF" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/holofloor/ice, +/area/edina) +"ayG" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/holofloor/ice, +/area/edina) +"ayH" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/maintenance/starboard/fore) +"ayI" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ayJ" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/light, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ayK" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/chair/office/dark{ + dir = 1 + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ayL" = ( +/obj/machinery/door/airlock/external{ + name = "Gulag Shuttle Airlock"; + req_access_txt = "63" + }, +/turf/open/floor/wood, +/area/security/processing) +"ayM" = ( +/obj/machinery/door/airlock/security/glass, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway/safe, +/area/maintenance/starboard/fore) +"ayN" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway/safe, +/area/security/brig) +"ayO" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway/safe, +/area/security/brig) +"ayP" = ( +/obj/item/radio/intercom{ + desc = "Talk through this. It looks like it has been modified to not broadcast."; + name = "Prison Intercom (General)"; + pixel_x = -25; + pixel_y = -2; + prison_radio = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/brig) +"ayQ" = ( +/turf/open/floor/plasteel/dark, +/area/security/brig) +"ayR" = ( +/obj/machinery/vending/cigarette, +/turf/open/floor/wood, +/area/service/lawoffice) +"ayS" = ( +/obj/structure/chair/comfy/brown{ + dir = 4 + }, +/turf/open/floor/wood, +/area/service/lawoffice) +"ayT" = ( +/obj/structure/table/wood, +/obj/item/pen/red, +/obj/item/book/manual/wiki/security_space_law, +/turf/open/floor/wood, +/area/service/lawoffice) +"ayU" = ( +/obj/structure/table/wood, +/obj/item/folder/blue, +/obj/item/stamp/law, +/turf/open/floor/wood, +/area/service/lawoffice) +"ayV" = ( +/obj/structure/filingcabinet/employment, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/turf/open/floor/wood, +/area/service/lawoffice) +"ayW" = ( +/obj/machinery/computer/prisoner/gulag_teleporter_computer{ + dir = 4 + }, +/turf/open/floor/wood, +/area/security/processing) +"ayX" = ( +/obj/machinery/gulag_item_reclaimer{ + pixel_y = 24 + }, +/turf/open/floor/wood, +/area/security/processing) +"ayY" = ( +/obj/effect/decal/festive/fairylights, +/obj/structure/chair/sofa/left, +/turf/open/floor/wood, +/area/command/heads_quarters/ce) +"ayZ" = ( +/obj/effect/decal/festive/fairylights, +/turf/open/floor/engine/plasma, +/area/engineering/atmos) +"aza" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/toxin_input{ + dir = 4 + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/engine/plasma, +/area/engineering/atmos) +"azb" = ( +/obj/structure/grille, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 8 + }, +/turf/closed/wall/r_wall, +/area/engineering/atmos) +"azc" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"azd" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aze" = ( +/obj/structure/table/wood, +/obj/item/candle, +/turf/open/floor/grass/snow/edina, +/area/edina) +"azf" = ( +/obj/machinery/atmospherics/components/trinary/filter/atmos/plasma, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"azg" = ( +/obj/machinery/door/airlock/atmos/glass, +/turf/open/floor/plasteel, +/area/engineering/main) +"azh" = ( +/obj/structure/grille, +/obj/structure/window/plasma/reinforced/fulltile, +/turf/open/floor/plasteel, +/area/engineering/main) +"azi" = ( +/obj/structure/table, +/obj/item/clothing/head/beret/atmos, +/obj/machinery/door/window/westleft{ + dir = 2; + icon_state = "right" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"azj" = ( +/obj/structure/table, +/obj/item/clothing/head/beret/ce/white, +/obj/machinery/door/window/westleft{ + dir = 2; + icon_state = "right" + }, +/obj/effect/decal/festive/holly, +/turf/open/floor/plasteel, +/area/engineering/main) +"azk" = ( +/obj/machinery/door/poddoor/shutters{ + id = "enggarage" + }, +/turf/open/floor/festive/cobblestone, +/area/engineering/main) +"azl" = ( +/obj/structure/statue/sandstone/venus{ + dir = 8 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"azm" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/holofloor/ice, +/area/edina) +"azn" = ( +/obj/machinery/door/poddoor/shutters{ + id = "evashutter"; + name = "E.V.A. Storage Shutter" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"azo" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/service/bar/atrium) +"azp" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/closed/wall/mineral/iron, +/area/maintenance/starboard/fore) +"azq" = ( +/obj/structure/chair/sofa/right, +/obj/machinery/flasher{ + id = "Cell 1"; + pixel_x = -28 + }, +/turf/open/floor/carpet/red, +/area/security/brig) +"azr" = ( +/obj/structure/chair/sofa, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/red, +/area/security/brig) +"azs" = ( +/obj/structure/chair/sofa/left, +/turf/open/floor/carpet/red, +/area/security/brig) +"azt" = ( +/obj/structure/chair/sofa/right, +/obj/machinery/flasher{ + id = "Cell 2"; + pixel_x = -28 + }, +/turf/open/floor/carpet/red, +/area/security/brig) +"azu" = ( +/obj/structure/chair/sofa/right, +/obj/machinery/flasher{ + id = "Cell 3"; + pixel_x = -28 + }, +/turf/open/floor/carpet/red, +/area/security/brig) +"azv" = ( +/obj/structure/chair/sofa/right, +/obj/machinery/flasher{ + id = "Cell 4"; + pixel_x = -28 + }, +/turf/open/floor/carpet/red, +/area/security/brig) +"azw" = ( +/obj/machinery/vending/coffee, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/wood, +/area/service/lawoffice) +"azx" = ( +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/service/lawoffice) +"azy" = ( +/obj/effect/landmark/start/lawyer, +/obj/structure/chair/office/dark{ + dir = 8 + }, +/turf/open/floor/wood, +/area/service/lawoffice) +"azz" = ( +/obj/effect/landmark/start/lawyer, +/turf/open/floor/wood, +/area/service/lawoffice) +"azA" = ( +/obj/machinery/vending/wardrobe/law_wardrobe, +/obj/machinery/light{ + dir = 4 + }, +/obj/item/radio/intercom{ + pixel_x = 26 + }, +/turf/open/floor/wood, +/area/service/lawoffice) +"azB" = ( +/obj/item/storage/box/prisoner, +/obj/structure/table/reinforced, +/turf/open/floor/wood, +/area/security/processing) +"azC" = ( +/turf/open/floor/engine/plasma, +/area/engineering/atmos) +"azD" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/machinery/atmospherics/miner/toxins, +/turf/open/floor/engine/plasma, +/area/engineering/atmos) +"azE" = ( +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"azF" = ( +/turf/open/floor/wood, +/area/engineering/main) +"azG" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/wood, +/area/engineering/main) +"azH" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) +"azI" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/closed/wall/mineral/iron, +/area/security/brig) +"azJ" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/carpet/red, +/area/security/brig) +"azK" = ( +/obj/structure/table/wood, +/obj/item/paper_bin, +/obj/item/pen, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/carpet/red, +/area/security/brig) +"azL" = ( +/obj/structure/table/wood, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/carpet/red, +/area/security/brig) +"azM" = ( +/obj/structure/rack, +/obj/item/storage/briefcase, +/turf/open/floor/wood, +/area/service/lawoffice) +"azN" = ( +/obj/structure/chair/comfy/brown{ + dir = 4 + }, +/obj/machinery/light_switch{ + pixel_y = -23 + }, +/turf/open/floor/wood, +/area/service/lawoffice) +"azO" = ( +/obj/structure/table/wood, +/obj/machinery/camera{ + c_tag = "Law Office"; + dir = 1 + }, +/obj/item/flashlight/lamp/green{ + pixel_x = 1; + pixel_y = 5 + }, +/turf/open/floor/wood, +/area/service/lawoffice) +"azP" = ( +/obj/structure/table/wood, +/obj/item/taperecorder, +/obj/item/cartridge/lawyer, +/turf/open/floor/wood, +/area/service/lawoffice) +"azQ" = ( +/obj/structure/table/wood, +/obj/item/paper_bin{ + pixel_x = -3; + pixel_y = 7 + }, +/obj/item/pen, +/obj/machinery/computer/security/telescreen/prison{ + dir = 1; + pixel_y = -27 + }, +/turf/open/floor/wood, +/area/service/lawoffice) +"azR" = ( +/obj/machinery/disposal/bin, +/turf/open/floor/wood, +/area/service/lawoffice) +"azS" = ( +/obj/structure/table/reinforced, +/obj/item/restraints/handcuffs, +/obj/item/storage/fancy/donut_box, +/turf/open/floor/wood, +/area/security/processing) +"azT" = ( +/obj/machinery/button/door{ + desc = "A remote control switch for the exit."; + id = "laborexit"; + name = "exit button"; + normaldoorcontrol = 1; + pixel_x = 26; + pixel_y = -6 + }, +/turf/open/floor/wood, +/area/security/processing) +"azU" = ( +/obj/machinery/light, +/turf/open/floor/engine/plasma, +/area/engineering/atmos) +"azV" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/toxin_output{ + dir = 4 + }, +/turf/open/floor/engine/plasma, +/area/engineering/atmos) +"azW" = ( +/obj/structure/grille, +/obj/machinery/atmospherics/pipe/layer_manifold{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/engineering/atmos) +"azX" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/layer3{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"azY" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"azZ" = ( +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aAa" = ( +/obj/machinery/door/airlock/security/glass{ + id_tag = "outerbrig"; + name = "Brig"; + req_access_txt = "63" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway/safe, +/area/security/brig) +"aAb" = ( +/obj/machinery/door/poddoor/preopen{ + id = "Secure Gate"; + name = "brig shutters" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow, +/turf/open/floor/plating, +/area/security/brig) +"aAc" = ( +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/door/airlock/security{ + id_tag = "laborexit"; + name = "Labor Shuttle"; + req_access_txt = "63" + }, +/turf/open/floor/festive/alleyway/safe, +/area/security/processing) +"aAd" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/command{ + name = "E.V.A. Storage"; + req_access_txt = "18" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"aAe" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"aAf" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"aAg" = ( +/turf/open/floor/festive/sidewalk, +/area/security) +"aAh" = ( +/obj/effect/festive/street/streetlineinnernw, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAi" = ( +/obj/effect/festive/street/streetlinenorth, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAj" = ( +/obj/machinery/mech_bay_recharge_port{ + dir = 2 + }, +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAk" = ( +/obj/machinery/computer/mech_bay_power_console, +/obj/effect/festive/street/streetlinenorth, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAl" = ( +/obj/machinery/mech_bay_recharge_port{ + dir = 2 + }, +/obj/effect/festive/street/streetlinenorth, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAm" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/computer/mech_bay_power_console, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAn" = ( +/obj/structure/reagent_dispensers/fueltank, +/obj/effect/festive/street/streetlineinnerne, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAo" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway/safe, +/area/security/processing) +"aAp" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/command{ + name = "E.V.A. Storage"; + req_access_txt = "18" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/ai_monitored/command/storage/eva) +"aAq" = ( +/obj/effect/landmark/start/atmospheric_technician, +/turf/open/floor/wood, +/area/engineering/main) +"aAr" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/button/door{ + id = "secgate1"; + name = "Gate doors"; + pixel_x = -28 + }, +/turf/open/floor/festive/sidewalk, +/area/security) +"aAs" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8 + }, +/turf/open/floor/festive/sidewalk, +/area/security) +"aAt" = ( +/obj/effect/festive/street/streetlinewest, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAu" = ( +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAv" = ( +/obj/vehicle/sealed/vectorcraft/cyber, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAw" = ( +/obj/vehicle/sealed/vectorcraft/hos, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAx" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAy" = ( +/turf/open/floor/festive/alleyway/safe, +/area/security/processing) +"aAz" = ( +/obj/machinery/light, +/turf/open/floor/wood, +/area/engineering/main) +"aAA" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/door/poddoor/shutters{ + id = "secgate1" + }, +/turf/open/floor/festive/cobblestone, +/area/security) +"aAB" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/security) +"aAC" = ( +/obj/effect/festive/street/streetlinenorth, +/turf/open/floor/festive/cobblestone, +/area/security) +"aAD" = ( +/obj/effect/festive/street/sidewalkn, +/turf/open/floor/festive/cobblestone, +/area/security) +"aAE" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aAF" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAG" = ( +/obj/effect/festive/street/streetlinenw, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAH" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAI" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/circuit, +/area/science/robotics/mechbay) +"aAJ" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/power/apc{ + areastring = "/area/science/robotics/mechbay"; + dir = 4; + name = "Mech Bay APC"; + pixel_x = 26 + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAK" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway/safe, +/area/security/processing) +"aAL" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/security/processing) +"aAM" = ( +/obj/effect/decal/festive/fairylights, +/turf/open/floor/engine/co2, +/area/engineering/atmos) +"aAN" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/carbon_input{ + dir = 4 + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/engine/co2, +/area/engineering/atmos) +"aAO" = ( +/obj/machinery/atmospherics/components/trinary/filter/atmos/co2, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aAP" = ( +/obj/machinery/door/poddoor/shutters{ + id = "secgate1" + }, +/turf/open/floor/festive/cobblestone, +/area/security) +"aAQ" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/security) +"aAR" = ( +/turf/open/floor/festive/cobblestone, +/area/security) +"aAS" = ( +/obj/effect/festive/street/sidewalknsm, +/turf/open/floor/festive/cobblestone, +/area/security) +"aAT" = ( +/turf/open/floor/circuit, +/area/science/robotics/mechbay) +"aAU" = ( +/turf/open/floor/circuit/green, +/area/science/robotics/mechbay) +"aAV" = ( +/obj/effect/festive/street/streetlineeast, +/obj/structure/table/reinforced, +/obj/item/storage/toolbox/mechanical, +/obj/item/storage/toolbox/mechanical, +/obj/item/storage/toolbox/mechanical, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aAW" = ( +/obj/machinery/door/airlock/security/glass, +/obj/machinery/door/firedoor, +/turf/open/floor/festive/alleyway, +/area/security/processing) +"aAX" = ( +/turf/open/floor/engine/co2, +/area/engineering/atmos) +"aAY" = ( +/obj/machinery/portable_atmospherics/canister/carbon_dioxide, +/obj/machinery/atmospherics/miner/carbon_dioxide, +/turf/open/floor/engine/co2, +/area/engineering/atmos) +"aAZ" = ( +/obj/effect/festive/street/streetlineeast, +/obj/structure/table/reinforced, +/obj/item/storage/belt/utility/full/engi, +/obj/item/storage/belt/utility/full/engi, +/obj/item/storage/belt/utility/full/engi, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aBa" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/item/radio/intercom{ + pixel_x = -26 + }, +/turf/open/floor/festive/alleyway/safe, +/area/security/processing) +"aBb" = ( +/obj/machinery/light, +/turf/open/floor/engine/co2, +/area/engineering/atmos) +"aBc" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/carbon_output{ + dir = 4 + }, +/turf/open/floor/engine/co2, +/area/engineering/atmos) +"aBd" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aBe" = ( +/obj/effect/festive/street/streetlineeast, +/obj/structure/table/reinforced, +/obj/item/clothing/head/collectable/welding, +/obj/item/clothing/head/collectable/welding, +/obj/item/clothing/glasses/welding, +/obj/item/clothing/glasses/welding, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aBf" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aBg" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"aBh" = ( +/obj/effect/festive/street/streetlineeast, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aBi" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aBj" = ( +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aBk" = ( +/obj/effect/landmark/start/assistant, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"aBl" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/door/poddoor/shutters{ + id = "secgate1" + }, +/turf/open/floor/festive/cobblestone, +/area/security) +"aBm" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/security) +"aBn" = ( +/turf/open/floor/plasteel/dark, +/area/service/bar/atrium) +"aBo" = ( +/obj/effect/festive/street/streetlinesouth, +/turf/open/floor/festive/cobblestone, +/area/security) +"aBp" = ( +/obj/effect/festive/street/sidewalks, +/turf/open/floor/festive/cobblestone, +/area/security) +"aBq" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/light, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aBr" = ( +/obj/effect/festive/street/streetlinesw, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aBs" = ( +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aBt" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aBu" = ( +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aBv" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aBw" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aBx" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"aBy" = ( +/obj/effect/festive/street/sidewalke, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aBz" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"aBA" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/closed/wall/mineral/iron, +/area/security) +"aBB" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/security) +"aBC" = ( +/obj/machinery/recharge_station, +/obj/effect/festive/street/streetlineinnersw, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aBD" = ( +/obj/machinery/recharge_station, +/obj/effect/festive/street/streetlinesouth, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aBE" = ( +/obj/effect/festive/street/streetlinese, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aBF" = ( +/obj/machinery/recharge_station, +/obj/effect/festive/street/streetlineinnerse, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aBG" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/engine/n2o, +/area/engineering/atmos) +"aBH" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/nitrous_input{ + dir = 4 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/engine/n2o, +/area/engineering/atmos) +"aBI" = ( +/obj/machinery/atmospherics/components/trinary/filter/atmos/n2o, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aBJ" = ( +/obj/machinery/atmospherics/components/binary/pump, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aBK" = ( +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aBL" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aBM" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/portables_connector/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aBN" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/mix_output{ + dir = 8 + }, +/turf/open/floor/engine/vacuum, +/area/engineering/atmos) +"aBO" = ( +/turf/open/floor/engine/vacuum, +/area/engineering/atmos) +"aBP" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/closed/wall/mineral/iron, +/area/edina/street) +"aBQ" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/closed/wall/mineral/iron, +/area/service/bar/atrium) +"aBR" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"aBS" = ( +/obj/structure/statue/snow/snowman{ + name = "Condom" + }, +/turf/open/floor/grass/snow/edina, +/area/edina/street/secondary/command) +"aBT" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"aBU" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aBV" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aBW" = ( +/obj/machinery/door/airlock/security/glass{ + id_tag = "outerbrig"; + name = "Brig"; + req_access_txt = "63" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security) +"aBX" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/festive/sidewalk, +/area/security) +"aBY" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/science/robotics/mechbay) +"aBZ" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Equipment Room"; + req_access_txt = "1" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway/safe, +/area/security/office) +"aCa" = ( +/turf/open/floor/engine/n2o, +/area/engineering/atmos) +"aCb" = ( +/obj/machinery/portable_atmospherics/canister/nitrous_oxide, +/obj/machinery/atmospherics/miner/n2o, +/turf/open/floor/engine/n2o, +/area/engineering/atmos) +"aCc" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aCd" = ( +/obj/machinery/atmospherics/components/unary/portables_connector{ + dir = 4; + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aCe" = ( +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aCf" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aCg" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/grille, +/obj/effect/decal/festive/holly, +/turf/open/floor/engine/vacuum, +/area/engineering/atmos) +"aCh" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"aCi" = ( +/obj/effect/festive/street/streetlinenm, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aCj" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"aCk" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aCl" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/grass/snow/edina, +/area/edina/street/primary/perimeter) +"aCm" = ( +/obj/structure/sign/departments/xenobio, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science/xenobiology) +"aCn" = ( +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science/xenobiology) +"aCo" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/junction, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science/xenobiology) +"aCp" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSRightEnd, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aCq" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSLeftEnd, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aCr" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Atrium" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aCs" = ( +/obj/structure/sign/departments/science, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science/xenobiology) +"aCt" = ( +/obj/structure/bed, +/obj/effect/spawner/lootdrop/bedsheet, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/obj/effect/decal/festive/red_stockings, +/turf/open/floor/carpet/red, +/area/commons/dorms) +"aCu" = ( +/obj/machinery/shower{ + pixel_y = 8 + }, +/obj/structure/curtain{ + color = "#FF5555" + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/freezer, +/area/commons/dorms) +"aCv" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/toilet{ + pixel_x = 2; + pixel_y = 8 + }, +/turf/open/floor/plasteel/freezer, +/area/commons/dorms) +"aCw" = ( +/obj/machinery/door/airlock/security/glass{ + id_tag = "outerbrig"; + name = "Brig"; + req_access_txt = "63" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aCx" = ( +/obj/machinery/door/airlock/security/glass, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aCy" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/service/bar/atrium) +"aCz" = ( +/obj/effect/festive/street/streetlinewest, +/turf/open/floor/festive/cobblestone, +/area/security) +"aCA" = ( +/obj/effect/festive/street/streetlineeast, +/turf/open/floor/festive/cobblestone, +/area/security) +"aCB" = ( +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/north) +"aCC" = ( +/obj/machinery/vending/wardrobe/sec_wardrobe, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aCD" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aCE" = ( +/obj/structure/closet/secure_closet/security/sec, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/neck/scarf/red, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aCF" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aCG" = ( +/obj/machinery/light, +/turf/open/floor/engine/n2o, +/area/engineering/atmos) +"aCH" = ( +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/grass/snow/edina, +/area/science/research) +"aCI" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/nitrous_output{ + dir = 4 + }, +/turf/open/floor/engine/n2o, +/area/engineering/atmos) +"aCJ" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aCK" = ( +/obj/machinery/atmospherics/components/trinary/filter, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aCL" = ( +/obj/machinery/atmospherics/pipe/manifold/green/visible{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aCM" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aCN" = ( +/obj/structure/grille, +/obj/machinery/atmospherics/pipe/simple/green/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/engineering/atmos) +"aCO" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/mix_input{ + dir = 8 + }, +/turf/open/floor/engine/vacuum, +/area/engineering/atmos) +"aCP" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aCQ" = ( +/obj/effect/festive/street/sidewalkw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"aCR" = ( +/obj/effect/festive/street/sidewalke, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"aCS" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"aCT" = ( +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"aCU" = ( +/obj/effect/festive/street/streetlinenw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"aCV" = ( +/obj/machinery/light, +/turf/open/floor/engine/vacuum, +/area/engineering/atmos) +"aCW" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aCX" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aCY" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aCZ" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science/xenobiology) +"aDa" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold, +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aDb" = ( +/obj/machinery/disposal/bin, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aDc" = ( +/obj/machinery/computer/arcade, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aDd" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aDe" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aDf" = ( +/obj/effect/festive/street/streetlinene, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"aDg" = ( +/obj/effect/festive/street/streetlinenorth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"aDh" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/north) +"aDi" = ( +/obj/structure/table/wood, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"aDj" = ( +/obj/machinery/vending/cigarette, +/turf/open/floor/wood, +/area/commons/storage/tools) +"aDk" = ( +/obj/machinery/vending/coffee, +/turf/open/floor/wood, +/area/commons/storage/tools) +"aDl" = ( +/obj/machinery/vending/cola/space_up, +/turf/open/floor/wood, +/area/commons/storage/tools) +"aDm" = ( +/obj/machinery/vending/cola/pwr_game, +/turf/open/floor/wood, +/area/commons/storage/tools) +"aDn" = ( +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/commons/dorms) +"aDo" = ( +/obj/machinery/processor, +/turf/open/floor/wood, +/area/commons/dorms) +"aDp" = ( +/turf/open/floor/carpet/red, +/area/maintenance/bar) +"aDq" = ( +/obj/machinery/shower{ + dir = 4 + }, +/turf/open/floor/mineral/titanium/blue, +/area/commons/dorms) +"aDr" = ( +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/turf/open/floor/plasteel/freezer, +/area/commons/dorms) +"aDs" = ( +/obj/machinery/vr_sleeper{ + dir = 4 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/commons/fitness/recreation) +"aDt" = ( +/obj/effect/festive/street/streetlineinnerne, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"aDu" = ( +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"aDv" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/commons/fitness/recreation) +"aDx" = ( +/obj/structure/table/wood, +/obj/machinery/reagentgrinder, +/turf/open/floor/carpet/monochrome, +/area/commons/storage/tools) +"aDz" = ( +/obj/structure/musician/piano, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aDA" = ( +/obj/structure/chair/comfy{ + dir = 8 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aDB" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aDC" = ( +/obj/item/radio/intercom{ + pixel_y = 26 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aDD" = ( +/obj/machinery/computer/slot_machine, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aDE" = ( +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"aDF" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/security/office) +"aDG" = ( +/obj/effect/festive/street/streetlineeast, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"aDH" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"aDI" = ( +/obj/effect/festive/street/streetlinesw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"aDJ" = ( +/obj/effect/festive/street/streetlinese, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"aDK" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aDL" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aDM" = ( +/obj/effect/landmark/start/security_officer, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/junction, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aDN" = ( +/obj/structure/closet/secure_closet/security/sec, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/light{ + dir = 4 + }, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/neck/scarf/red, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aDO" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1; + pixel_x = 5 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aDP" = ( +/obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aDQ" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aDR" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aDS" = ( +/obj/structure/fence{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/grass/snow/edina, +/area/science) +"aDT" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aDU" = ( +/turf/open/floor/circuit/green, +/area/science/xenobiology) +"aDV" = ( +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aDW" = ( +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aDX" = ( +/turf/open/floor/carpet/red, +/area/science/xenobiology) +"aDY" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aDZ" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowWERightEnd, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aEa" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"aEb" = ( +/obj/structure/chair/sofa/right, +/turf/open/floor/wood, +/area/commons/storage/tools) +"aEc" = ( +/obj/effect/festive/street/streetlinewest, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"aEd" = ( +/obj/effect/festive/street/sidewalkwem, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"aEe" = ( +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aEf" = ( +/obj/structure/chair/sofa, +/turf/open/floor/wood, +/area/commons/storage/tools) +"aEg" = ( +/obj/structure/chair/sofa/left, +/turf/open/floor/wood, +/area/commons/storage/tools) +"aEi" = ( +/obj/structure/chair/comfy/black{ + dir = 4 + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"aEj" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/obj/structure/table/wood/fancy/monochrome, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"aEk" = ( +/obj/structure/chair/comfy/black{ + dir = 8 + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"aEl" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/service/bar/atrium) +"aEm" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aEn" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aEo" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aEp" = ( +/obj/structure/chair/stool, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aEq" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aEr" = ( +/obj/effect/festive/street/sidewalknsm, +/turf/open/floor/festive/cobblestone/safe, +/area/edina/street) +"aEs" = ( +/obj/structure/chair/stool, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aEt" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aEu" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aEv" = ( +/obj/effect/landmark/start/security_officer, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aEw" = ( +/obj/structure/closet/secure_closet/security/sec, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/neck/scarf/red, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aEx" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aEy" = ( +/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aEz" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/grass/snow/edina, +/area/science) +"aEA" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"aEB" = ( +/obj/structure/disposalpipe/trunk, +/obj/structure/disposaloutlet{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aEC" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"aED" = ( +/turf/open/floor/grass/snow/edina, +/area/edina/street/primary/princess) +"aEE" = ( +/obj/structure/table/wood, +/obj/structure/window/spawner/east, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"aEF" = ( +/obj/structure/window/spawner, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"aEG" = ( +/obj/structure/streetdecor/lampfestive, +/turf/open/floor/grass/snow/edina, +/area/edina/street/primary/princess) +"aEH" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aEI" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowWEMiddle, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aEJ" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"aEK" = ( +/turf/closed/festive/whitebrick, +/area/maintenance/bar/cafe) +"aEL" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"aEM" = ( +/obj/structure/chair/comfy/black{ + dir = 4 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"aEN" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/obj/structure/table/wood/fancy/monochrome, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"aEO" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"aEP" = ( +/obj/structure/chair/comfy/black{ + dir = 8 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"aEQ" = ( +/turf/open/floor/carpet/black, +/area/commons/dorms) +"aER" = ( +/obj/structure/dresser{ + pixel_y = 15 + }, +/turf/open/floor/carpet/black, +/area/commons/dorms) +"aES" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWERight, +/turf/closed/festive/redbrick, +/area/commons/dorms) +"aET" = ( +/turf/closed/wall/mineral/silver, +/area/maintenance/bar) +"aEU" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/service/bar/atrium) +"aEV" = ( +/turf/open/floor/festive/stairs/stairswest, +/area/service/bar/atrium) +"aEW" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = -5 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"aEX" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aEY" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"aEZ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"aFa" = ( +/obj/structure/streetdecor/lampfestive, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"aFb" = ( +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"aFc" = ( +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"aFd" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"aFe" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"aFf" = ( +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aFg" = ( +/obj/structure/chair/comfy, +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aFh" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aFi" = ( +/obj/structure/disposalpipe/junction/yjunction{ + dir = 8 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aFj" = ( +/obj/machinery/atmospherics/components/unary/thermomachine/heater{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aFk" = ( +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "xeno6"; + name = "Creature Cell #6" + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFl" = ( +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/machinery/door/window/brigdoor{ + dir = 1; + name = "Creature Pen"; + req_access_txt = "47" + }, +/obj/machinery/door/poddoor/preopen{ + id = "xeno6"; + name = "Creature Cell #6" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFm" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/disposalpipe/segment, +/obj/machinery/door/poddoor/preopen{ + id = "xeno6"; + name = "Creature Cell #6" + }, +/obj/structure/cable/white{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFn" = ( +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "xeno5"; + name = "Creature Cell #5" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFo" = ( +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/machinery/door/window/brigdoor{ + dir = 1; + name = "Creature Pen"; + req_access_txt = "47" + }, +/obj/machinery/door/poddoor/preopen{ + id = "xeno5"; + name = "Creature Cell #5" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFp" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/disposalpipe/segment, +/obj/machinery/door/poddoor/preopen{ + id = "xeno5"; + name = "Creature Cell #5" + }, +/obj/structure/cable/white{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFq" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"aFr" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aFs" = ( +/obj/structure/fence/corner{ + dir = 9 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"aFt" = ( +/obj/effect/festive/street/streetlinewest, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aFu" = ( +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "xeno4"; + name = "Creature Cell #4" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFv" = ( +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/machinery/door/window/brigdoor{ + dir = 1; + name = "Creature Pen"; + req_access_txt = "47" + }, +/obj/machinery/door/poddoor/preopen{ + id = "xeno4"; + name = "Creature Cell #4" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFw" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/disposalpipe/segment, +/obj/machinery/door/poddoor/preopen{ + id = "xeno4"; + name = "Creature Cell #4" + }, +/obj/structure/cable/white{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFx" = ( +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "xeno3"; + name = "Creature Cell #3" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFy" = ( +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/machinery/door/window/brigdoor{ + dir = 1; + name = "Creature Pen"; + req_access_txt = "47" + }, +/obj/machinery/door/poddoor/preopen{ + id = "xeno3"; + name = "Creature Cell #3" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFz" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/disposalpipe/segment, +/obj/machinery/door/poddoor/preopen{ + id = "xeno3"; + name = "Creature Cell #3" + }, +/obj/structure/cable/white{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFA" = ( +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "xeno2"; + name = "Creature Cell #2" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFB" = ( +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/machinery/door/window/brigdoor{ + dir = 1; + name = "Creature Pen"; + req_access_txt = "47" + }, +/obj/machinery/door/poddoor/preopen{ + id = "xeno2"; + name = "Creature Cell #2" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFC" = ( +/obj/effect/festive/street/streetlineeast, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aFD" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/disposalpipe/segment, +/obj/machinery/door/poddoor/preopen{ + id = "xeno2"; + name = "Creature Cell #2" + }, +/obj/structure/cable/white{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFE" = ( +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "xeno1"; + name = "Creature Cell #1" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFF" = ( +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/machinery/door/window/brigdoor{ + dir = 1; + name = "Creature Pen"; + req_access_txt = "47" + }, +/obj/machinery/door/poddoor/preopen{ + id = "xeno1"; + name = "Creature Cell #1" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFG" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/disposalpipe/segment, +/obj/machinery/door/poddoor/preopen{ + id = "xeno1"; + name = "Creature Cell #1" + }, +/obj/structure/cable/white{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFH" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Atrium" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aFI" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aFJ" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowWELeftEnd, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aFK" = ( +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aFL" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/machinery/button/door{ + id = "enggarage"; + name = "Engineering Garage Door"; + pixel_x = 28 + }, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aFM" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/wood, +/area/commons/storage/tools) +"aFO" = ( +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/commons/storage/tools) +"aFP" = ( +/obj/structure/table/wood, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/wood, +/area/commons/storage/tools) +"aFQ" = ( +/turf/closed/wall/mineral/wood, +/area/maintenance/bar) +"aFR" = ( +/turf/closed/indestructible/fakeglass, +/area/maintenance/bar) +"aFS" = ( +/obj/machinery/door/airlock/wood/glass, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"aFT" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/north) +"aFU" = ( +/obj/structure/bed, +/obj/item/bedsheet/random, +/turf/open/floor/wood, +/area/maintenance/bar) +"aFW" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/service/bar/atrium) +"aFX" = ( +/obj/machinery/manned_turret/ultimate{ + anchored = 1; + name = "Anti-Greyshit Cannon"; + projectile_type = /obj/item/projectile/beam/disabler/slug + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aFY" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/disposalpipe/junction{ + dir = 1 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aFZ" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/stairs/stairswest, +/area/service/bar/atrium) +"aGa" = ( +/obj/machinery/door/airlock/security/glass{ + id_tag = "outerbrig"; + name = "Brig"; + req_access_txt = "63" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aGb" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/disposalpipe/junction/yjunction{ + dir = 8 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aGc" = ( +/obj/structure/table/wood/fancy/royalblue, +/obj/item/reagent_containers/food/snacks/burrito, +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aGd" = ( +/obj/item/reagent_containers/food/snacks/dulcedebatataslice, +/obj/structure/table/wood/fancy/royalblue, +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aGe" = ( +/obj/item/reagent_containers/food/snacks/salad/validsalad, +/obj/structure/table/wood/fancy/royalblue, +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aGf" = ( +/obj/item/reagent_containers/food/snacks/carneburrito, +/obj/structure/table/wood/fancy/royalblue, +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aGg" = ( +/obj/item/reagent_containers/food/snacks/chawanmushi, +/obj/structure/table/wood/fancy/royalblue, +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aGh" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/edina/street/primary/perimeter) +"aGi" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"aGj" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"aGk" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/miningoffice) +"aGl" = ( +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"aGm" = ( +/obj/machinery/door/airlock/maintenance, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"aGn" = ( +/obj/structure/fence/door, +/turf/open/floor/grass/snow/edina, +/area/edina) +"aGo" = ( +/obj/structure/table/wood/fancy/royalblue, +/obj/item/reagent_containers/food/snacks/cannedpeaches, +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aGp" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aGq" = ( +/obj/structure/table/reinforced, +/obj/machinery/recharger, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aGr" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aGs" = ( +/obj/structure/grille, +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/engineering/atmos) +"aGt" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/layer1{ + dir = 8; + on = 1 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/engine/vacuum, +/area/engineering/atmos) +"aGu" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/engine/vacuum, +/area/engineering/atmos) +"aGv" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aGw" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aGx" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aGy" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aGz" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aGA" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aGB" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aGC" = ( +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/machinery/shieldwallgen/xenobiologyaccess, +/turf/open/floor/plating, +/area/science/xenobiology) +"aGD" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aGE" = ( +/obj/effect/festive/street/streetlinewest, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aGF" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aGG" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aGH" = ( +/obj/structure/table/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/button/door{ + id = "xeno6"; + name = "Containment Control"; + req_access_txt = "55" + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aGI" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/door/window/brigdoor{ + name = "Creature Pen"; + req_access_txt = "47" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aGJ" = ( +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/disposal/bin, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aGK" = ( +/obj/structure/table/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/button/door{ + id = "xeno5"; + name = "Containment Control"; + req_access_txt = "55" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aGL" = ( +/obj/structure/sign/directions/engineering{ + desc = "A sign that shows there are doors here. There are doors everywhere!"; + icon_state = "doors"; + name = "WARNING: BIOHAZARD CELL" + }, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science/xenobiology) +"aGM" = ( +/obj/structure/table/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/machinery/button/door{ + id = "xeno4"; + name = "Containment Control"; + req_access_txt = "55" + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aGN" = ( +/obj/structure/table/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/button/door{ + id = "xeno3"; + name = "Containment Control"; + req_access_txt = "55" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aGO" = ( +/obj/structure/table/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/button/door{ + id = "xeno2"; + name = "Containment Control"; + req_access_txt = "55" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aGP" = ( +/obj/structure/table/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/button/door{ + id = "xeno1"; + name = "Containment Control"; + req_access_txt = "55" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aGQ" = ( +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/disposal/bin, +/obj/effect/turf_decal/stripes/corner, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aGR" = ( +/obj/machinery/door/airlock/research{ + name = "Xenobiology Lab"; + req_access_txt = "47" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aGS" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"aGT" = ( +/turf/open/floor/grass/fakebasalt, +/area/edina) +"aGU" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"aGV" = ( +/obj/effect/turf_decal/stripes/asteroid/line{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"aGW" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"aGX" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"aGY" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"aGZ" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/festive/street/sidewalkw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aHa" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aHb" = ( +/obj/effect/festive/street/sidewalkwem, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aHc" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aHd" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/sidewalke, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aHe" = ( +/obj/effect/festive/street/sidewalkn, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aHf" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/north, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"aHg" = ( +/obj/structure/sign/directions/engineering{ + dir = 8; + pixel_x = -32; + pixel_y = 36 + }, +/obj/structure/sign/directions/evac{ + dir = 1; + pixel_x = -32; + pixel_y = 28 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"aHh" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"aHi" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aHj" = ( +/obj/effect/festive/street/streetlinenw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aHk" = ( +/obj/effect/festive/street/sidewalkw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aHl" = ( +/obj/effect/festive/street/sidewalke, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aHm" = ( +/obj/structure/table, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/chem_dispenser/drinks, +/turf/open/floor/wood, +/area/maintenance/bar) +"aHn" = ( +/obj/structure/table, +/obj/machinery/chem_dispenser/drinks/beer, +/turf/open/floor/wood, +/area/maintenance/bar) +"aHo" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow, +/turf/open/floor/plating, +/area/service/bar/atrium) +"aHp" = ( +/obj/structure/table/wood/fancy/royalblue, +/obj/item/reagent_containers/food/snacks/meatballspaghetti, +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aHq" = ( +/obj/item/reagent_containers/food/snacks/hotdog, +/obj/structure/table/wood/fancy/royalblue, +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aHr" = ( +/obj/item/reagent_containers/food/snacks/pie/grapetart, +/obj/structure/table/wood/fancy/royalblue, +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aHs" = ( +/obj/item/reagent_containers/food/snacks/burger/superbite, +/obj/structure/table/wood/fancy/royalblue, +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aHt" = ( +/obj/item/reagent_containers/food/snacks/cakeslice/slimecake, +/obj/structure/table/wood/fancy/royalblue, +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aHu" = ( +/obj/structure/table/wood/fancy/royalblue, +/obj/item/reagent_containers/food/snacks/hotcrossbun, +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aHv" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Equipment Room"; + req_access_txt = "1" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/security/office) +"aHw" = ( +/obj/machinery/vending/security, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/light{ + dir = 4 + }, +/obj/item/radio/intercom{ + pixel_x = 26 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aHx" = ( +/obj/effect/decal/remains/xeno, +/obj/effect/decal/cleanable/blood/xeno, +/turf/open/floor/circuit/green, +/area/science/xenobiology) +"aHy" = ( +/obj/structure/sign/warning/electricshock, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science/xenobiology) +"aHz" = ( +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "xenosecure"; + name = "Secure Pen Shutters" + }, +/turf/open/floor/plating, +/area/science/xenobiology) +"aHA" = ( +/obj/structure/table/reinforced, +/obj/machinery/computer/security/telescreen{ + dir = 4; + network = list("xeno") + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aHB" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aHC" = ( +/obj/structure/extinguisher_cabinet{ + dir = 4; + pixel_x = -5; + pixel_y = 27 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aHD" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aHE" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/structure/extinguisher_cabinet{ + dir = 4; + pixel_x = -5; + pixel_y = 27 + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aHF" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"aHG" = ( +/obj/effect/festive/street/streetlinene, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aHH" = ( +/turf/open/floor/grass/snow/edina, +/area/science/mixing/chamber) +"aHI" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aHJ" = ( +/obj/machinery/vending/boozeomat{ + set_obj_flags = "EMAGGED" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"aHK" = ( +/obj/structure/table, +/obj/machinery/reagentgrinder, +/turf/open/floor/wood, +/area/maintenance/bar) +"aHL" = ( +/obj/structure/table, +/obj/machinery/light{ + dir = 1 + }, +/obj/item/book/manual/wiki/barman_recipes, +/obj/item/book/granter/action/drink_fling, +/obj/item/reagent_containers/food/drinks/shaker, +/obj/item/reagent_containers/rag, +/turf/open/floor/wood, +/area/maintenance/bar) +"aHM" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow, +/turf/open/floor/plating, +/area/service/bar/atrium) +"aHN" = ( +/obj/machinery/door/window/southleft{ + acted_explosions = "63"; + dir = 1; + name = "Bar"; + req_access_txt = "50" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aHO" = ( +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aHP" = ( +/obj/machinery/jukebox, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aHQ" = ( +/obj/structure/chair/comfy{ + dir = 1 + }, +/turf/open/floor/carpet/purple, +/area/service/bar/atrium) +"aHR" = ( +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science/robotics/mechbay) +"aHS" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aHT" = ( +/obj/machinery/camera{ + c_tag = "Brig Equipment Room"; + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/power/apc/auto_name/west, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aHU" = ( +/obj/machinery/holopad, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aHV" = ( +/obj/structure/sign/departments/science, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science/robotics/mechbay) +"aHW" = ( +/obj/effect/festive/street/streetlinenw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aHX" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aHY" = ( +/obj/effect/festive/street/sidewalkn, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aHZ" = ( +/obj/machinery/door/airlock/security/glass{ + id_tag = "outerbrig"; + name = "Brig"; + req_access_txt = "63" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security) +"aIa" = ( +/obj/structure/closet/bombcloset/security, +/obj/structure/reagent_dispensers/peppertank{ + pixel_x = 30 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aIb" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/mix_output{ + dir = 4 + }, +/turf/open/floor/engine/vacuum, +/area/engineering/atmos) +"aIc" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1{ + dir = 10 + }, +/obj/machinery/atmospherics/components/unary/portables_connector/layer3{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aId" = ( +/obj/machinery/atmospherics/pipe/manifold/yellow/visible, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aIe" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aIf" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + on = 1; + target_pressure = 4500 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aIg" = ( +/obj/structure/cable/white, +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "xenosecure"; + name = "Secure Pen Shutters" + }, +/turf/open/floor/plating, +/area/science/xenobiology) +"aIh" = ( +/obj/structure/table/reinforced, +/obj/structure/window/reinforced, +/obj/machinery/button/door{ + id = "xenosecure"; + name = "Containment Control"; + pixel_y = -3; + req_access_txt = "55" + }, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_y = 5 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIi" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIj" = ( +/obj/structure/sign/warning/biohazard{ + name = "Xeno Biohazard"; + pixel_x = -32 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIk" = ( +/obj/structure/table, +/obj/machinery/microwave, +/turf/open/floor/wood, +/area/maintenance/bar) +"aIl" = ( +/obj/machinery/power/apc/auto_name/south, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIm" = ( +/obj/effect/turf_decal/stripes/corner, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIn" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aIo" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIp" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIq" = ( +/obj/item/slime_extract/grey, +/obj/item/slime_extract/grey, +/obj/item/slime_extract/grey, +/obj/item/slime_extract/grey, +/obj/item/slime_extract/grey, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIr" = ( +/obj/effect/turf_decal/stripes/corner, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIs" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIt" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aIu" = ( +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aIv" = ( +/obj/machinery/door/firedoor, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "xenolobby"; + name = "Xenobiology Shutter" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aIw" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aIx" = ( +/obj/structure/closet/crate/bin, +/obj/item/tank/internals/emergency_oxygen, +/obj/item/trash/candy, +/obj/item/toy/talking/owl, +/obj/effect/turf_decal/stripes/asteroid/line{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"aIy" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aIz" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = 25 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"aIA" = ( +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"aIB" = ( +/obj/structure/chair/sofa/right{ + dir = 1 + }, +/turf/open/floor/wood, +/area/commons/storage/tools) +"aIC" = ( +/obj/structure/chair/sofa{ + dir = 1 + }, +/turf/open/floor/wood, +/area/commons/storage/tools) +"aID" = ( +/obj/machinery/requests_console{ + department = "Bar"; + departmentType = 2; + pixel_y = 30; + receive_ore_updates = 1 + }, +/obj/machinery/vending/dinnerware, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aIE" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/condiment/sugar, +/obj/item/reagent_containers/food/condiment/enzyme, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aIF" = ( +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aIG" = ( +/obj/structure/chair/comfy, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aIH" = ( +/obj/machinery/vending/security, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aII" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aIJ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aIK" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"aIL" = ( +/obj/machinery/camera{ + c_tag = "Xenobiology - Secure Cell"; + dir = 4; + name = "xenobiology camera"; + network = list("ss13","xeno","rd") + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aIM" = ( +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/machinery/door/window/brigdoor{ + dir = 8; + name = "Secure Creature Pen"; + req_access_txt = "47" + }, +/obj/machinery/door/poddoor/preopen{ + id = "xenosecure"; + name = "Secure Pen Shutters" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aIN" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/door/window/brigdoor{ + dir = 4; + name = "Secure Creature Pen"; + req_access_txt = "47" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIO" = ( +/obj/effect/festive/street/streetlineeast, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aIP" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIQ" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIR" = ( +/obj/machinery/door/airlock/research{ + name = "Xenobiology Lab"; + req_access_txt = "47" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIS" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aIT" = ( +/obj/machinery/door/airlock/research{ + name = "Xenobiology Lab"; + req_access_txt = "47" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIU" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science) +"aIV" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIW" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"aIX" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIY" = ( +/obj/structure/rack, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/ears/earmuffs, +/obj/item/clothing/neck/scarf/purple, +/obj/item/clothing/head/beret/sci, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aIZ" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science/xenobiology) +"aJa" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science/xenobiology) +"aJb" = ( +/obj/machinery/door/airlock/research/glass{ + name = "Xenobiology Kill Room"; + req_access_txt = "47" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aJc" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aJd" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science/xenobiology) +"aJe" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple, +/obj/machinery/disposal/bin, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aJf" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aJg" = ( +/obj/effect/turf_decal/stripes/line, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aJh" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aJi" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aJj" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aJk" = ( +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aJl" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "xenolobby"; + name = "Xenobiology Shutter" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aJm" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/red, +/area/science/xenobiology) +"aJn" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aJo" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowWEMiddle, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aJp" = ( +/obj/structure/chair/sofa/left{ + dir = 1 + }, +/turf/open/floor/wood, +/area/commons/storage/tools) +"aJq" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"aJr" = ( +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aJs" = ( +/obj/structure/table/wood, +/obj/machinery/microwave{ + pixel_x = -3; + pixel_y = 6 + }, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aJt" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/meatballspaghetti, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aJu" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/notasandwich, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aJv" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/pastatomato, +/obj/machinery/light/floor, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aJw" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/kebab/tofu, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aJx" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/honkdae, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aJy" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/enchiladas, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aJz" = ( +/obj/machinery/door/airlock/security/glass, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aJA" = ( +/obj/structure/disposaloutlet{ + dir = 8 + }, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aJB" = ( +/obj/structure/cable/white, +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "xenosecure"; + name = "Secure Pen Shutters" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/science/xenobiology) +"aJC" = ( +/obj/structure/window/reinforced{ + dir = 1; + pixel_y = 1 + }, +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aJD" = ( +/obj/structure/sign/warning/biohazard{ + name = "Xeno Biohazard"; + pixel_x = -32 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aJE" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aJF" = ( +/obj/structure/reagent_dispensers/watertank/high, +/obj/item/reagent_containers/glass/bucket, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"aJG" = ( +/obj/structure/rack, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/suit/hooded/wintercoat/science, +/obj/item/clothing/ears/earmuffs, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/head/beret/sci, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aJH" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 6 + }, +/turf/open/floor/circuit/telecomms, +/area/science/xenobiology) +"aJI" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 4 + }, +/turf/open/floor/circuit/telecomms, +/area/science/xenobiology) +"aJJ" = ( +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 1 + }, +/turf/open/floor/circuit/telecomms, +/area/science/xenobiology) +"aJK" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 4 + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aJL" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 10 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aJM" = ( +/obj/structure/chair/comfy/black, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aJN" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/item/stack/sheet/mineral/plasma, +/obj/machinery/reagentgrinder, +/obj/structure/table/glass, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aJO" = ( +/obj/effect/landmark/start/scientist, +/obj/structure/chair/comfy/black, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aJP" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aJQ" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aJR" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/machinery/button/door{ + id = "xenolobby"; + name = "Xenobiology Privacy Shutters"; + pixel_x = 26; + pixel_y = 7; + req_access_txt = "30" + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aJS" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/carpet/red, +/area/science/xenobiology) +"aJT" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aJX" = ( +/turf/open/floor/carpet/orange, +/area/maintenance/bar) +"aJY" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/rack, +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aJZ" = ( +/obj/structure/table/wood, +/obj/machinery/microwave{ + pixel_x = -3; + pixel_y = 6 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aKa" = ( +/obj/structure/table/wood, +/obj/item/book/manual/wiki/barman_recipes, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aKb" = ( +/obj/machinery/holopad, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aKc" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/melonfruitbowl, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aKd" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/khachapuri, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aKe" = ( +/turf/open/floor/plasteel, +/area/science/circuit) +"aKf" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/grilledcheese, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aKg" = ( +/turf/open/floor/plasteel, +/area/science) +"aKh" = ( +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"aKi" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/jelliedtoast/cherry, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aKj" = ( +/turf/open/floor/plasteel, +/area/science/robotics/mechbay) +"aKk" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/honeybun, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aKl" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/eggplantparm, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aKm" = ( +/obj/structure/cable/white, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "xenosecure"; + name = "Secure Pen Shutters" + }, +/turf/open/floor/plating, +/area/science/xenobiology) +"aKn" = ( +/obj/structure/table/reinforced, +/obj/machinery/cell_charger, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aKo" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSRightEnd, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "xenolobby"; + name = "Xenobiology Shutter" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aKp" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSMiddle, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "xenolobby"; + name = "Xenobiology Shutter" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aKq" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSLeftEnd, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "xenolobby"; + name = "Xenobiology Shutter" + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aKr" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ + dir = 1; + external_pressure_bound = 120; + name = "killroom vent" + }, +/turf/open/floor/circuit/telecomms, +/area/science/xenobiology) +"aKs" = ( +/obj/machinery/light, +/turf/open/floor/circuit/telecomms, +/area/science/xenobiology) +"aKt" = ( +/turf/open/floor/circuit/telecomms, +/area/science/xenobiology) +"aKu" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1; + external_pressure_bound = 140; + name = "killroom vent" + }, +/turf/open/floor/circuit/telecomms, +/area/science/xenobiology) +"aKv" = ( +/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aKw" = ( +/obj/machinery/computer/camera_advanced/xenobio{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aKx" = ( +/obj/structure/table/glass, +/obj/item/storage/box/beakers{ + pixel_x = 2; + pixel_y = 7 + }, +/obj/item/storage/box/syringes{ + pixel_y = 5 + }, +/obj/item/storage/box/monkeycubes{ + pixel_x = 2; + pixel_y = -2 + }, +/obj/item/storage/box/monkeycubes, +/obj/machinery/light, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aKy" = ( +/obj/structure/table/glass, +/obj/item/paper_bin{ + pixel_y = 4 + }, +/obj/item/folder/white{ + pixel_x = 4; + pixel_y = 4 + }, +/obj/item/pen{ + pixel_x = -4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aKz" = ( +/obj/machinery/processor/slime, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aKA" = ( +/obj/machinery/smartfridge/extract/preloaded, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"aKB" = ( +/obj/structure/fluff/lightpost/light, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"aKC" = ( +/obj/machinery/deepfryer, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aKD" = ( +/obj/structure/table/wood, +/obj/item/instrument/piano_synth, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aKE" = ( +/obj/structure/chair/comfy{ + dir = 1 + }, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"aKF" = ( +/obj/machinery/light, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/science/xenobiology) +"aKG" = ( +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/shieldwallgen/xenobiologyaccess, +/turf/open/floor/plating, +/area/science/xenobiology) +"aKH" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aKI" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aKJ" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/closet/wardrobe/mixed, +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aKK" = ( +/obj/machinery/chem_dispenser/drinks, +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aKL" = ( +/obj/structure/table/wood, +/obj/item/storage/box/drinkingglasses, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aKM" = ( +/obj/structure/chair/comfy, +/turf/open/floor/carpet/red, +/area/service/bar/atrium) +"aKN" = ( +/turf/closed/festive/whitebrick, +/area/science/misc_lab) +"aKO" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/junction, +/turf/closed/festive/whitebrick, +/area/science/misc_lab) +"aKP" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/junction{ + dir = 1 + }, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science/xenobiology) +"aKQ" = ( +/obj/structure/fluff/lightpost/light, +/turf/open/floor/grass/snow/edina, +/area/science/research) +"aKR" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aKT" = ( +/turf/open/floor/festive/alleyway, +/area/science) +"aKU" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/festive/street/streetlineem, +/turf/open/floor/festive/alleyway, +/area/science) +"aKV" = ( +/obj/structure/chair/sofa/right, +/turf/open/floor/wood, +/area/maintenance/bar) +"aKW" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aKX" = ( +/obj/machinery/chem_dispenser/drinks/beer, +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aKY" = ( +/obj/structure/table/wood, +/obj/item/storage/fancy/donut_box, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aKZ" = ( +/obj/structure/table/wood/fancy/black, +/obj/item/reagent_containers/food/snacks/khinkali, +/turf/open/floor/carpet/red, +/area/service/bar/atrium) +"aLa" = ( +/obj/item/reagent_containers/food/snacks/candiedapple, +/obj/structure/table/wood/fancy/black, +/turf/open/floor/carpet/red, +/area/service/bar/atrium) +"aLb" = ( +/obj/item/reagent_containers/food/snacks/burger/baconburger, +/obj/structure/table/wood/fancy/black, +/turf/open/floor/carpet/red, +/area/service/bar/atrium) +"aLc" = ( +/obj/item/reagent_containers/food/snacks/benedict, +/obj/structure/table/wood/fancy/black, +/turf/open/floor/carpet/red, +/area/service/bar/atrium) +"aLd" = ( +/obj/item/reagent_containers/food/snacks/cakeslice/chocolate, +/obj/structure/table/wood/fancy/black, +/turf/open/floor/carpet/red, +/area/service/bar/atrium) +"aLe" = ( +/obj/item/reagent_containers/food/snacks/chowmein, +/obj/structure/table/wood/fancy/black, +/turf/open/floor/carpet/red, +/area/service/bar/atrium) +"aLf" = ( +/obj/machinery/vending/wardrobe/sec_wardrobe, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aLg" = ( +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aLh" = ( +/obj/structure/closet/secure_closet/security/sec, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/neck/scarf/red, +/turf/open/floor/plasteel/dark, +/area/security/office) +"aLi" = ( +/obj/structure/table, +/obj/item/pipe_dispenser, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aLj" = ( +/obj/structure/table, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aLk" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aLl" = ( +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aLm" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aLn" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aLo" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aLp" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/science) +"aLq" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aLr" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aLs" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aLt" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aLu" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/fence/door/opened{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aLv" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/science) +"aLw" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/festive/street/streetlineem, +/turf/open/floor/festive/alleyway, +/area/science) +"aLx" = ( +/obj/structure/chair/sofa/left, +/turf/open/floor/wood, +/area/maintenance/bar) +"aLy" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSRightEnd, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"aLz" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSMiddle, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"aLA" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSLeftEnd, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"aLB" = ( +/turf/closed/festive/redbrick/redbrickcornerse, +/area/commons/dorms) +"aLC" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"aLD" = ( +/obj/structure/chair/sofa/left{ + dir = 1 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"aLE" = ( +/obj/structure/closet{ + name = "Evidence Closet" + }, +/obj/structure/sign/poster/official/the_owl{ + pixel_x = 32 + }, +/turf/open/floor/wood, +/area/security/prison) +"aLF" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/rack, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aLG" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 16 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"aLH" = ( +/obj/structure/table/wood/fancy/black, +/obj/item/reagent_containers/food/snacks/fuegoburrito, +/turf/open/floor/carpet/red, +/area/service/bar/atrium) +"aLI" = ( +/obj/item/reagent_containers/food/snacks/copypasta, +/obj/structure/table/wood/fancy/black, +/turf/open/floor/carpet/red, +/area/service/bar/atrium) +"aLJ" = ( +/obj/item/reagent_containers/food/snacks/bearsteak, +/obj/structure/table/wood/fancy/black, +/turf/open/floor/carpet/red, +/area/service/bar/atrium) +"aLK" = ( +/obj/item/reagent_containers/food/snacks/boiledspaghetti, +/obj/structure/table/wood/fancy/black, +/turf/open/floor/carpet/red, +/area/service/bar/atrium) +"aLL" = ( +/obj/item/reagent_containers/food/snacks/cherrycupcake, +/obj/structure/table/wood/fancy/black, +/turf/open/floor/carpet/red, +/area/service/bar/atrium) +"aLM" = ( +/obj/item/reagent_containers/food/snacks/customizable/pizza, +/obj/structure/table/wood/fancy/black, +/turf/open/floor/carpet/red, +/area/service/bar/atrium) +"aLN" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Equipment Room"; + req_access_txt = "1" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/security/office) +"aLO" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/festive/whitebrick, +/area/science/misc_lab) +"aLP" = ( +/obj/structure/table, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aLQ" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aLR" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aLS" = ( +/obj/machinery/power/apc{ + areastring = "/area/science/misc_lab"; + dir = 4; + name = "Testing Lab APC"; + pixel_x = 26 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aLT" = ( +/obj/structure/sign/warning/electricshock, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/edina) +"aLU" = ( +/turf/closed/festive/whitebrick, +/area/science/explab) +"aLV" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/junction, +/turf/closed/festive/whitebrick, +/area/science/explab) +"aLW" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"aLX" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aLY" = ( +/turf/closed/festive/redbrick, +/area/security/checkpoint/science) +"aLZ" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/junction, +/turf/closed/festive/redbrick, +/area/security/checkpoint/science) +"aMa" = ( +/obj/structure/fluff/lightpost/light, +/turf/open/floor/grass/snow/edina, +/area/science) +"aMb" = ( +/turf/closed/festive/whitebrick, +/area/science) +"aMc" = ( +/obj/structure/reagent_dispensers/beerkeg{ + reagent_id = /datum/reagent/consumable/ethanol/beer/light + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"aMd" = ( +/obj/machinery/vending/cigarette/beach, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"aMe" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/vending/snack/teal, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"aMf" = ( +/obj/machinery/reagentgrinder, +/obj/structure/table/wood, +/obj/machinery/power/apc/auto_name/west, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aMg" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aMh" = ( +/obj/structure/chair/comfy{ + dir = 1 + }, +/turf/open/floor/carpet/red, +/area/service/bar/atrium) +"aMi" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aMj" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aMk" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/sidewalk, +/area/security) +"aMl" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aMm" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aMn" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aMo" = ( +/obj/machinery/door/poddoor/preopen{ + id = "testlab"; + name = "test chamber blast door" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/engine, +/area/science/research) +"aMp" = ( +/obj/structure/reagent_dispensers/fueltank, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aMq" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aMr" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aMs" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aMt" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aMu" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aMv" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aMw" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aMx" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aMy" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/floor/engine, +/area/science/explab) +"aMz" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/engine, +/area/science/explab) +"aMA" = ( +/obj/machinery/camera{ + c_tag = "Science - Experimentation Lab"; + name = "science camera"; + network = list("ss13","rd") + }, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/engine, +/area/science/explab) +"aMB" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold, +/turf/open/floor/engine, +/area/science/explab) +"aMC" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/engine, +/area/science/explab) +"aMD" = ( +/obj/structure/closet/secure_closet/security/science, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -24 + }, +/obj/machinery/status_display{ + pixel_y = 32 + }, +/obj/structure/extinguisher_cabinet{ + pixel_x = -26; + pixel_y = 32 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aME" = ( +/obj/structure/table/reinforced, +/obj/machinery/recharger, +/obj/machinery/light{ + dir = 1 + }, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_y = 26 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aMF" = ( +/obj/structure/table/reinforced, +/obj/item/book/manual/wiki/security_space_law, +/obj/item/radio, +/obj/machinery/status_display/ai{ + pixel_y = 32 + }, +/obj/structure/reagent_dispensers/peppertank{ + pixel_x = 32 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aMG" = ( +/turf/closed/festive/whitebrick, +/area/science/lab) +"aMH" = ( +/obj/effect/decal/festive/fairylights, +/turf/open/floor/wood, +/area/command/heads_quarters/ce) +"aMI" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "rndlab1"; + name = "Research and Development Shutter" + }, +/turf/open/floor/plasteel, +/area/science/lab) +"aMJ" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "rndlab1"; + name = "Research and Development Shutter" + }, +/turf/open/floor/plasteel, +/area/science/lab) +"aMK" = ( +/turf/closed/festive/whitebrick, +/area/science/research/lobby) +"aML" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, +/area/commons/fitness/recreation) +"aMM" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/vending/cola/pwr_game, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"aMO" = ( +/obj/machinery/processor, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aMP" = ( +/obj/machinery/disposal/bin, +/obj/machinery/light, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aMQ" = ( +/obj/item/reagent_containers/food/snacks/grown/wheat, +/obj/item/reagent_containers/food/snacks/grown/wheat, +/obj/item/reagent_containers/food/snacks/grown/wheat, +/obj/item/reagent_containers/food/snacks/grown/wheat, +/obj/item/reagent_containers/food/snacks/grown/wheat, +/obj/item/reagent_containers/food/snacks/grown/wheat, +/obj/item/reagent_containers/food/snacks/grown/wheat, +/obj/item/reagent_containers/food/snacks/grown/potato, +/obj/item/reagent_containers/food/snacks/grown/potato, +/obj/item/reagent_containers/food/snacks/grown/potato, +/obj/item/reagent_containers/food/snacks/grown/potato, +/obj/item/reagent_containers/food/snacks/grown/potato, +/obj/item/reagent_containers/food/snacks/grown/carrot, +/obj/item/reagent_containers/food/snacks/grown/carrot, +/obj/item/reagent_containers/food/snacks/grown/carrot, +/obj/item/reagent_containers/food/snacks/grown/carrot, +/obj/item/reagent_containers/food/snacks/grown/carrot, +/obj/item/reagent_containers/food/snacks/grown/carrot, +/obj/item/reagent_containers/food/snacks/grown/tomato, +/obj/item/reagent_containers/food/snacks/grown/tomato, +/obj/item/reagent_containers/food/snacks/grown/tomato, +/obj/item/reagent_containers/food/snacks/grown/tomato, +/obj/item/reagent_containers/food/snacks/grown/tomato, +/obj/structure/closet/secure_closet/freezer{ + storage_capacity = 120 + }, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/rice, +/obj/item/reagent_containers/food/condiment/rice, +/obj/item/reagent_containers/food/condiment/rice, +/obj/item/reagent_containers/food/condiment/rice, +/obj/item/reagent_containers/food/condiment/rice, +/obj/item/reagent_containers/food/condiment/rice, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aMR" = ( +/obj/machinery/computer/arcade{ + dir = 1 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aMS" = ( +/obj/machinery/computer/arcade{ + dir = 1 + }, +/obj/machinery/light, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aMT" = ( +/obj/machinery/light, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aMU" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aMV" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/festive/sidewalk, +/area/security) +"aMW" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/festive/sidewalk, +/area/security) +"aMX" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aMY" = ( +/turf/open/floor/engine, +/area/science/research) +"aMZ" = ( +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/obj/machinery/camera{ + name = "Test Chamber Camera"; + network = list("test") + }, +/turf/open/floor/engine, +/area/science/research) +"aNa" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aNb" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aNc" = ( +/obj/structure/reagent_dispensers/watertank, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aNd" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/science) +"aNe" = ( +/turf/closed/festive/whitebrick, +/area/science/research) +"aNf" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/junction, +/turf/closed/festive/whitebrick, +/area/science) +"aNg" = ( +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Science Maintenance"; + req_access_txt = "47" + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/science) +"aNh" = ( +/turf/closed/festive/whitebrick, +/area/science/nanite) +"aNi" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aNj" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/engine, +/area/science/explab) +"aNk" = ( +/turf/open/floor/engine, +/area/science/explab) +"aNl" = ( +/obj/machinery/rnd/experimentor, +/turf/open/floor/engine, +/area/science/explab) +"aNm" = ( +/obj/effect/landmark/blobstart, +/obj/effect/landmark/xeno_spawn, +/turf/open/floor/engine, +/area/science/explab) +"aNn" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"aNo" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWE, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aNp" = ( +/obj/machinery/light_switch{ + pixel_x = -38; + pixel_y = 26 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aNq" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aNr" = ( +/obj/machinery/computer/secure_data{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aNs" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWERightEnd, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aNt" = ( +/obj/structure/table, +/obj/item/storage/toolbox/mechanical{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/item/storage/toolbox/mechanical, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aNu" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aNv" = ( +/obj/machinery/disposal/bin, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aNw" = ( +/obj/machinery/computer/rdconsole/core, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/lab) +"aNx" = ( +/obj/machinery/rnd/destructive_analyzer, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/lab) +"aNy" = ( +/obj/structure/table, +/obj/machinery/cell_charger, +/obj/item/stock_parts/cell/high/plus, +/obj/item/stock_parts/cell/high/plus, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aNz" = ( +/obj/structure/table, +/obj/item/disk/design_disk, +/obj/item/disk/design_disk, +/obj/item/disk/tech_disk, +/obj/item/disk/tech_disk, +/obj/effect/turf_decal/tile/purple, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aNA" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/science/lab) +"aNB" = ( +/obj/machinery/vending/cigarette, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/research/lobby) +"aNC" = ( +/obj/machinery/disposal/bin, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/research/lobby) +"aND" = ( +/obj/machinery/computer/arcade, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/research/lobby) +"aNE" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/beer/light, +/turf/open/floor/wood, +/area/maintenance/bar) +"aNF" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp, +/turf/open/floor/wood, +/area/maintenance/bar) +"aNG" = ( +/obj/effect/festive/street/sidewalkw, +/turf/open/floor/festive/cobblestone, +/area/security) +"aNH" = ( +/obj/effect/festive/street/sidewalkwem, +/turf/open/floor/festive/cobblestone, +/area/security) +"aNI" = ( +/obj/effect/festive/street/sidewalke, +/turf/open/floor/festive/cobblestone, +/area/security) +"aNJ" = ( +/obj/machinery/door/airlock/security/glass{ + id_tag = "outerbrig"; + name = "Brig"; + req_access_txt = "63" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/sidewalk, +/area/security/office) +"aNK" = ( +/obj/machinery/atmospherics/components/unary/thermomachine/freezer, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aNL" = ( +/obj/item/radio/intercom{ + pixel_x = -25 + }, +/turf/open/floor/engine, +/area/science/research) +"aNM" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/science/research) +"aNN" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aNO" = ( +/obj/structure/reagent_dispensers/watertank, +/obj/effect/turf_decal/bot, +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aNP" = ( +/obj/machinery/recharge_station, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science) +"aNQ" = ( +/obj/machinery/door/airlock{ + name = "Borg Charger" + }, +/turf/open/floor/plasteel, +/area/science) +"aNR" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/science) +"aNS" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold, +/turf/open/floor/plasteel, +/area/science) +"aNT" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/table, +/obj/structure/bedsheetbin/towel, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science) +"aNU" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/science/nanite) +"aNV" = ( +/obj/structure/table, +/obj/item/disk/nanite_program/monitoring, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aNW" = ( +/obj/machinery/nanite_programmer, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aNX" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aNY" = ( +/obj/machinery/nanite_chamber, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aNZ" = ( +/obj/structure/frame/computer, +/obj/item/circuitboard/computer/nanite_chamber_control, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aOa" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aOb" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aOc" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"aOd" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aOe" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security{ + name = "Security Post - Science"; + req_access_txt = "63" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aOf" = ( +/obj/structure/chair/office/dark{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/effect/landmark/start/depsec/science, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aOg" = ( +/obj/machinery/computer/security{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aOh" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWEMiddle, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aOi" = ( +/obj/structure/sign/warning/electricshock, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science) +"aOj" = ( +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/grass/snow/edina, +/area/science) +"aOk" = ( +/obj/structure/table, +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/glass/fifty, +/obj/item/clothing/glasses/welding, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aOl" = ( +/turf/open/floor/plasteel/white, +/area/science/lab) +"aOm" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science/lab) +"aOn" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/lab) +"aOo" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aOp" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/robotics/mechbay) +"aOq" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "rndlab1"; + name = "Research and Development Shutter" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/festive/wooden/wooden1, +/area/science/lab) +"aOr" = ( +/turf/open/floor/carpet/green, +/area/science/research/lobby) +"aOs" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"aOt" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"aOu" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/festive/wooden/wooden1, +/area/science/research/lobby) +"aOv" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/turf/open/floor/plasteel, +/area/science/research/lobby) +"aOw" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/bottle/tequila, +/turf/open/floor/wood, +/area/maintenance/bar) +"aOx" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/stairs/stairssouth, +/area/service/bar/atrium) +"aOy" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/table, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aOz" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/closet/firecloset, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aOA" = ( +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aOB" = ( +/obj/structure/reagent_dispensers/watertank, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aOC" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/table, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 8; + name = "8maintenance loot spawner" + }, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aOD" = ( +/obj/machinery/portable_atmospherics/canister/air, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aOE" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/closet/wardrobe/mixed, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aOF" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/stairs/stairssouth, +/area/security/office) +"aOG" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aOH" = ( +/obj/machinery/sparker{ + id = "testigniter"; + pixel_x = -25 + }, +/turf/open/floor/engine, +/area/science/research) +"aOI" = ( +/obj/item/beacon, +/turf/open/floor/engine, +/area/science/research) +"aOJ" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/engine, +/area/science/research) +"aOK" = ( +/obj/machinery/door/poddoor/preopen{ + id = "testlab"; + name = "test chamber blast door" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/airlock/research/glass{ + name = "Test Chamber"; + req_access_txt = "47" + }, +/turf/open/floor/engine, +/area/science/research) +"aOL" = ( +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/science/research) +"aOM" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/airlock/research/glass{ + name = "Test Chamber"; + req_access_txt = "47" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/science/research) +"aON" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aOO" = ( +/obj/machinery/door/airlock/research/glass{ + name = "Testing Lab"; + req_access_txt = "47" + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aOP" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science) +"aOQ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/blobstart, +/turf/open/floor/plasteel, +/area/science) +"aOR" = ( +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/obj/structure/mirror{ + pixel_x = 28 + }, +/turf/open/floor/plasteel, +/area/science) +"aOS" = ( +/obj/structure/table, +/obj/item/folder/white, +/obj/item/nanite_scanner, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aOT" = ( +/obj/structure/chair/office/light{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aOU" = ( +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aOV" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aOW" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/closed/festive/whitebrick, +/area/science/nanite) +"aOX" = ( +/obj/machinery/door/poddoor/preopen{ + id = "telelab"; + name = "test chamber blast door" + }, +/obj/machinery/door/firedoor/heavy, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/engine, +/area/science/explab) +"aOY" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/obj/machinery/door/poddoor/preopen{ + id = "telelab"; + name = "test chamber blast door" + }, +/obj/machinery/door/firedoor/heavy, +/turf/open/floor/engine, +/area/science/explab) +"aOZ" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/obj/machinery/door/poddoor/preopen{ + id = "telelab"; + name = "test chamber blast door" + }, +/obj/machinery/door/firedoor/heavy, +/turf/open/floor/engine, +/area/science/explab) +"aPa" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/obj/machinery/door/poddoor/preopen{ + id = "telelab"; + name = "test chamber blast door" + }, +/obj/machinery/door/firedoor/heavy, +/turf/open/floor/engine, +/area/science/explab) +"aPb" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/closed/festive/whitebrick, +/area/science/explab) +"aPc" = ( +/obj/machinery/holopad, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aPd" = ( +/obj/machinery/computer/mecha{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aPe" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWELeftEnd, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aPf" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/machinery/button/door{ + id = "secgate1"; + name = "Gate doors"; + pixel_x = 28 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"aPg" = ( +/obj/machinery/door/airlock/research{ + name = "Research and Development Lab"; + req_one_access_txt = "7;29" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aPh" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aPi" = ( +/obj/machinery/holopad, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aPj" = ( +/obj/machinery/rnd/production/circuit_imprinter/department/science, +/obj/item/reagent_containers/glass/beaker/sulphuric, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/science/lab) +"aPk" = ( +/obj/machinery/rnd/production/protolathe/department/science, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/science/lab) +"aPl" = ( +/obj/structure/chair/office/dark{ + dir = 4 + }, +/obj/effect/landmark/start/scientist, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aPm" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "rndlab1"; + name = "Research and Development Shutter" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/festive/wooden/wooden1, +/area/science/lab) +"aPn" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/festive/wooden/wooden1, +/area/science/research/lobby) +"aPo" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWEMiddle, +/turf/open/floor/plasteel, +/area/science/research/lobby) +"aPp" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/service/bar/atrium) +"aPq" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aPr" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/stairs/stairswest, +/area/service/bar/atrium) +"aPs" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aPt" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/light, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aPu" = ( +/obj/machinery/door/airlock/security/glass{ + id_tag = "outerbrig"; + name = "Brig"; + req_access_txt = "63" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/alleyway/safe, +/area/service/bar/atrium) +"aPv" = ( +/obj/effect/festive/street/streetlinene, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aPw" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/security) +"aPx" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/button/door{ + id = "secgate2"; + name = "Gate doors"; + pixel_y = -22 + }, +/turf/open/floor/festive/sidewalk, +/area/security) +"aPy" = ( +/obj/effect/festive/street/streetlinewest, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/security) +"aPz" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/security) +"aPA" = ( +/obj/effect/festive/street/streetlineeast, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/security) +"aPB" = ( +/obj/machinery/door/airlock/security/glass{ + id_tag = "outerbrig"; + name = "Brig"; + req_access_txt = "63" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/security/office) +"aPC" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/stairs/stairseast, +/area/security/office) +"aPD" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/wood, +/area/security/office) +"aPE" = ( +/obj/item/radio/intercom{ + pixel_y = 26 + }, +/turf/open/floor/wood, +/area/security/office) +"aPF" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/office) +"aPG" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/on, +/turf/open/floor/engine, +/area/science/research) +"aPH" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/engine, +/area/science/research) +"aPI" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aPJ" = ( +/turf/closed/festive/whitebrick, +/area/science/storage) +"aPK" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/toilet{ + dir = 4 + }, +/obj/machinery/newscaster{ + pixel_y = 32 + }, +/obj/effect/landmark/xeno_spawn, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science) +"aPL" = ( +/obj/machinery/door/airlock{ + name = "Toilet Unit" + }, +/turf/open/floor/plasteel, +/area/science) +"aPM" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small, +/turf/open/floor/plasteel, +/area/science) +"aPN" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/obj/structure/mirror{ + pixel_x = 28 + }, +/turf/open/floor/plasteel, +/area/science) +"aPO" = ( +/obj/structure/chair/office/light{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aPP" = ( +/obj/structure/frame/computer{ + dir = 8 + }, +/obj/item/circuitboard/computer/nanite_cloud_controller, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aPQ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/button/door{ + id = "telelab"; + name = "Testing Lab Blast Doors"; + pixel_x = -26; + pixel_y = 7 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aPR" = ( +/obj/structure/closet/radiation, +/turf/open/floor/plasteel/white/corner, +/area/science/explab) +"aPS" = ( +/obj/machinery/computer/rdconsole/experiment, +/turf/open/floor/plasteel/white/side, +/area/science/explab) +"aPT" = ( +/obj/structure/table, +/obj/item/clipboard, +/obj/item/book/manual/wiki/experimentor, +/turf/open/floor/plasteel/white/corner{ + dir = 8 + }, +/area/science/explab) +"aPU" = ( +/obj/machinery/disposal/bin, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/explab) +"aPV" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aPW" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aPX" = ( +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 + }, +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Security Post - Science"; + dir = 8; + network = list("ss13","rd") + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aPY" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aPZ" = ( +/obj/effect/festive/street/sidewalkn, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aQa" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/festive/wooden/wooden1, +/area/science/research/lobby) +"aQb" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/turf/open/floor/plasteel, +/area/science/research/lobby) +"aQc" = ( +/obj/machinery/processor, +/turf/open/floor/wood, +/area/maintenance/bar) +"aQd" = ( +/obj/machinery/vending/cola, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"aQe" = ( +/obj/machinery/manned_turret/ultimate{ + anchored = 1; + name = "Anti-Greyshit Cannon"; + projectile_type = /obj/item/projectile/beam/disabler/slug + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aQf" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"aQg" = ( +/obj/machinery/door/airlock/security/glass, +/turf/open/floor/plasteel, +/area/security) +"aQh" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/door/poddoor/shutters{ + id = "secgate2" + }, +/turf/open/floor/festive/cobblestone, +/area/security) +"aQi" = ( +/obj/machinery/door/poddoor/shutters{ + id = "secgate2" + }, +/turf/open/floor/festive/cobblestone, +/area/security) +"aQj" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/door/poddoor/shutters{ + id = "secgate2" + }, +/turf/open/floor/festive/cobblestone, +/area/security) +"aQk" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/office) +"aQl" = ( +/obj/machinery/atmospherics/components/unary/thermomachine/heater{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aQm" = ( +/obj/machinery/door/poddoor/preopen{ + id = "testlab"; + name = "test chamber blast door" + }, +/obj/machinery/atmospherics/pipe/simple/general/visible, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/engine, +/area/science/research) +"aQn" = ( +/obj/structure/closet/bombcloset, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aQo" = ( +/obj/structure/closet/l3closet/scientist{ + pixel_x = -2 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aQp" = ( +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aQq" = ( +/obj/item/radio/intercom{ + pixel_x = 25 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aQr" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/science/misc_lab) +"aQs" = ( +/obj/structure/filingcabinet/chestdrawer, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/storage) +"aQt" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/storage) +"aQu" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/airalarm{ + pixel_y = 22 + }, +/obj/machinery/portable_atmospherics/canister/nitrogen, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/storage) +"aQv" = ( +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_y = 26 + }, +/obj/machinery/portable_atmospherics/canister/nitrogen, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/storage) +"aQw" = ( +/obj/structure/table, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/crowbar, +/obj/item/wrench, +/obj/item/clothing/mask/gas, +/obj/structure/extinguisher_cabinet{ + pixel_x = 26 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/storage) +"aQx" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aQy" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aQz" = ( +/obj/structure/table, +/obj/item/stack/sheet/glass{ + amount = 30 + }, +/obj/item/stack/cable_coil{ + amount = 5 + }, +/obj/item/stack/cable_coil{ + amount = 5 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aQA" = ( +/obj/structure/table, +/obj/item/paper_bin, +/obj/item/pen/fountain, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aQB" = ( +/obj/machinery/requests_console{ + department = "Science"; + departmentType = 2; + name = "Science Requests Console"; + pixel_x = -30; + receive_ore_updates = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aQC" = ( +/obj/structure/extinguisher_cabinet{ + dir = 4; + pixel_x = -5; + pixel_y = 27 + }, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aQD" = ( +/turf/open/floor/plasteel/white, +/area/science/explab) +"aQE" = ( +/obj/structure/chair/office/light{ + dir = 1 + }, +/obj/effect/landmark/start/scientist, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aQF" = ( +/obj/machinery/power/apc{ + areastring = "/area/science/explab"; + dir = 1; + name = "Experimentation Lab APC"; + pixel_y = 24 + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aQG" = ( +/obj/effect/festive/street/streetlinenorth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aQH" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aQI" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aQJ" = ( +/obj/machinery/door_timer{ + id = "scicell"; + name = "Science Cell"; + pixel_x = -32; + pixel_y = -32 + }, +/obj/machinery/power/apc{ + areastring = "/area/security/checkpoint/science"; + dir = 8; + name = "Security Post - Science APC"; + pixel_x = -26; + pixel_y = 3 + }, +/obj/machinery/button/door{ + desc = "A remote control switch."; + id = "scidoor"; + name = "Science Cell Control"; + normaldoorcontrol = 1; + pixel_x = -36; + pixel_y = -7 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable/yellow, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aQK" = ( +/obj/structure/table/glass, +/obj/item/reagent_containers/glass/beaker, +/obj/item/reagent_containers/glass/beaker/large, +/obj/item/reagent_containers/dropper, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aQL" = ( +/obj/structure/table/glass, +/obj/item/stock_parts/capacitor, +/obj/item/stock_parts/capacitor, +/obj/item/stock_parts/micro_laser, +/obj/item/stock_parts/micro_laser, +/obj/item/stock_parts/manipulator, +/obj/item/stock_parts/manipulator, +/obj/item/stack/cable_coil, +/obj/item/stack/cable_coil, +/obj/machinery/light{ + light_color = "#c9d3e8" + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aQM" = ( +/obj/structure/table/glass, +/obj/item/stack/sheet/glass, +/obj/item/stack/sheet/glass, +/obj/item/stack/sheet/glass, +/obj/item/stock_parts/matter_bin, +/obj/item/stock_parts/matter_bin, +/obj/item/stock_parts/scanning_module, +/obj/item/stock_parts/scanning_module, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aQN" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aQO" = ( +/obj/machinery/button/door{ + id = "rndlab1"; + name = "Research and Development Privacy Shutters"; + pixel_x = 26; + pixel_y = 7; + req_access_txt = "30" + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/machinery/light{ + light_color = "#c9d3e8" + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/lab) +"aQP" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/research/lobby) +"aQQ" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold, +/turf/open/floor/festive/wooden/wooden1, +/area/science/research/lobby) +"aQR" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/junction{ + dir = 8 + }, +/turf/closed/festive/whitebrick, +/area/science/research/lobby) +"aQS" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"aQT" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"aQV" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/obj/machinery/power/apc/auto_name/west, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aQW" = ( +/obj/machinery/door/airlock/public/glass, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"aQX" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow, +/turf/open/floor/plating, +/area/service/bar/atrium) +"aQY" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/service/bar/atrium) +"aQZ" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/service/bar/atrium) +"aRa" = ( +/obj/structure/flora/tree/pine/xmas, +/turf/open/floor/grass/snow/edina, +/area/edina/street/primary/perimeter) +"aRb" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow, +/turf/open/floor/plating, +/area/security/office) +"aRc" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/security/office) +"aRd" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/security/office) +"aRe" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRf" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRg" = ( +/obj/machinery/disposal/bin, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRh" = ( +/obj/structure/filingcabinet/chestdrawer, +/obj/machinery/requests_console{ + department = "Science"; + departmentType = 2; + name = "Science Requests Console"; + pixel_y = 30; + receive_ore_updates = 1 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRi" = ( +/obj/structure/table, +/obj/machinery/button/door{ + id = "testlab"; + name = "Test Chamber Blast Doors"; + pixel_x = 4; + pixel_y = 2; + req_access_txt = "55" + }, +/obj/machinery/button/ignition{ + id = "testigniter"; + pixel_x = -6; + pixel_y = 2 + }, +/obj/machinery/atmospherics/pipe/simple/general/visible, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRj" = ( +/obj/structure/table, +/obj/item/folder/white, +/obj/item/folder/white, +/obj/item/pen, +/obj/item/taperecorder, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRk" = ( +/obj/structure/table, +/obj/item/paper_bin{ + pixel_y = 6 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRl" = ( +/obj/structure/rack, +/obj/item/wrench, +/obj/item/crowbar, +/obj/machinery/computer/security/telescreen{ + name = "Test Chamber Monitor"; + network = list("test"); + pixel_y = 30 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRm" = ( +/obj/structure/rack, +/obj/item/clothing/mask/gas{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/clothing/mask/gas, +/obj/item/clothing/mask/gas{ + pixel_x = -3; + pixel_y = -3 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRn" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRo" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRp" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = -26 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/science/storage) +"aRq" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/storage) +"aRr" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/storage) +"aRs" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/storage) +"aRt" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/toilet{ + dir = 4 + }, +/obj/machinery/newscaster{ + pixel_y = 32 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science) +"aRu" = ( +/obj/structure/rack, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/ears/earmuffs, +/obj/item/clothing/neck/scarf/purple, +/obj/item/clothing/neck/scarf/christmas, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aRv" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aRw" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plasteel, +/area/science/nanite) +"aRx" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plasteel, +/area/science/nanite) +"aRy" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/closed/festive/whitebrick, +/area/science/nanite) +"aRz" = ( +/obj/machinery/door/firedoor/heavy, +/obj/machinery/door/airlock/research{ + name = "Experimentation Lab"; + req_access_txt = "47" + }, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aRA" = ( +/obj/machinery/holopad, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aRB" = ( +/obj/effect/landmark/event_spawn, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aRC" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aRD" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aRE" = ( +/obj/structure/closet/secure_closet/brig{ + id = "scicell"; + name = "Science Cell Locker" + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aRF" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "rndlab1"; + name = "Research and Development Shutter" + }, +/turf/open/floor/plasteel, +/area/science/lab) +"aRG" = ( +/obj/structure/sign/departments/science, +/turf/closed/festive/whitebrick, +/area/science/lab) +"aRH" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/red, +/area/science/xenobiology) +"aRI" = ( +/obj/structure/sign/departments/science, +/turf/closed/festive/whitebrick, +/area/science/research/lobby) +"aRJ" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aRK" = ( +/obj/machinery/atmospherics/pipe/manifold/general/visible, +/obj/machinery/meter, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRL" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRM" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRN" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRO" = ( +/obj/structure/chair/stool, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRP" = ( +/obj/machinery/door/airlock/research/glass{ + name = "Testing Lab"; + req_access_txt = "47" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aRQ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/storage) +"aRR" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/science/storage) +"aRS" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/machinery/light_switch{ + pixel_x = 26 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/storage) +"aRT" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aRU" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock{ + name = "Bathroom" + }, +/turf/open/floor/plasteel, +/area/science) +"aRV" = ( +/turf/open/floor/festive/alleyway, +/area/edina/backstreet) +"aRW" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/closed/festive/whitebrick, +/area/science) +"aRX" = ( +/obj/machinery/vending/wardrobe/science_wardrobe, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aRY" = ( +/obj/machinery/door/airlock/research/glass{ + name = "Nanite Lab"; + req_access_txt = "47" + }, +/turf/open/floor/plasteel/white, +/area/science/nanite) +"aRZ" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWE, +/turf/open/floor/plasteel, +/area/science/explab) +"aSa" = ( +/obj/structure/closet/emcloset, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aSb" = ( +/obj/structure/closet/l3closet/scientist, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aSc" = ( +/obj/structure/table, +/obj/item/folder/white, +/obj/item/folder/white, +/obj/item/radio/off, +/obj/machinery/firealarm{ + pixel_y = -26 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aSd" = ( +/obj/structure/table, +/obj/item/pen/fountain, +/obj/item/hand_labeler, +/obj/item/stack/packageWrap, +/obj/machinery/camera{ + c_tag = "Science - Research Director's Quarters"; + dir = 1; + name = "science camera"; + network = list("ss13","rd") + }, +/obj/machinery/light{ + light_color = "#c9d3e8" + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aSe" = ( +/obj/structure/table, +/obj/item/paper_bin{ + pixel_y = 6 + }, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aSf" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aSg" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aSh" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aSi" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aSj" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security{ + id_tag = "scidoor"; + name = "Security Post - Science"; + req_access_txt = "63" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aSk" = ( +/obj/structure/sign/warning/biohazard{ + name = "Xeno Biohazard"; + pixel_x = -32 + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aSl" = ( +/obj/structure/table, +/obj/item/stack/sheet/glass/fifty{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/mineral/plasma, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aSm" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aSn" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aSo" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aSp" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/portable_atmospherics/pump, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aSq" = ( +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 23 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/portable_atmospherics/pump, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aSr" = ( +/obj/effect/festive/street/streetlinewest, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"aSs" = ( +/obj/machinery/door/firedoor/heavy, +/obj/machinery/door/airlock/atmos{ + name = "Toxins Storage"; + req_access_txt = "24" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/science/storage) +"aSt" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/storage) +"aSu" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/storage) +"aSv" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science/storage) +"aSw" = ( +/obj/effect/festive/street/streetlinenw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aSx" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet) +"aSy" = ( +/obj/machinery/power/apc/auto_name/east, +/obj/structure/cable/yellow, +/turf/open/floor/grass/snow/edina, +/area/edina/street/secondary/castle) +"aSz" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/science/storage) +"aSA" = ( +/obj/structure/sign/warning/biohazard{ + name = "Xeno Biohazard"; + pixel_y = -32 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aSB" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aSC" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aSD" = ( +/obj/structure/table/wood, +/obj/machinery/microwave{ + desc = "Cooks and boils stuff, somehow."; + pixel_x = -3; + pixel_y = 5 + }, +/obj/structure/extinguisher_cabinet{ + pixel_x = -26 + }, +/turf/open/floor/wood, +/area/science) +"aSE" = ( +/obj/structure/table/wood, +/obj/structure/sign/poster/official/report_crimes{ + pixel_y = 32 + }, +/obj/item/storage/box/donkpockets, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/wood, +/area/science) +"aSF" = ( +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_y = 26 + }, +/turf/open/floor/wood, +/area/science) +"aSG" = ( +/turf/open/floor/wood, +/area/science) +"aSH" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/wood, +/area/science) +"aSI" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/closed/festive/redbrick, +/area/security/checkpoint/science) +"aSJ" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/structure/cable/yellow, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aSK" = ( +/obj/machinery/door/window/brigdoor{ + id = "scicell"; + name = "Medical Cell"; + req_access_txt = "63" + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aSL" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet) +"aSM" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"aSN" = ( +/obj/structure/sign/departments/science, +/turf/closed/festive/redbrick, +/area/security/checkpoint/science) +"aSO" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aSP" = ( +/obj/structure/table, +/obj/item/storage/box/beakers{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/grenade/chem_grenade, +/obj/item/grenade/chem_grenade, +/turf/open/floor/engine, +/area/science/misc_lab) +"aSQ" = ( +/turf/open/floor/engine, +/area/science/misc_lab) +"aSR" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 6 + }, +/turf/open/floor/engine, +/area/science/misc_lab) +"aSS" = ( +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 1 + }, +/turf/open/floor/engine, +/area/science/misc_lab) +"aST" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 8 + }, +/turf/open/floor/engine, +/area/science/misc_lab) +"aSU" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aSV" = ( +/obj/machinery/portable_atmospherics/scrubber, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aSW" = ( +/obj/machinery/portable_atmospherics/scrubber, +/obj/effect/turf_decal/bot, +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aSX" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aSY" = ( +/obj/structure/table, +/obj/item/paper_bin, +/obj/item/pen, +/obj/machinery/camera{ + c_tag = "Science - Toxins Secure Storage"; + dir = 4; + name = "science camera"; + network = list("ss13","rd") + }, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/storage) +"aSZ" = ( +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/storage) +"aTc" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science/storage) +"aTd" = ( +/obj/machinery/portable_atmospherics/scrubber/huge, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/storage) +"aTe" = ( +/obj/machinery/portable_atmospherics/scrubber/huge, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/power/apc{ + areastring = "/area/science/storage"; + dir = 4; + name = "Toxins Storage APC"; + pixel_x = 26 + }, +/obj/structure/cable/white, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/storage) +"aTf" = ( +/obj/effect/landmark/event_spawn, +/turf/open/floor/wood, +/area/science) +"aTg" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science) +"aTh" = ( +/turf/open/floor/carpet/red, +/area/service/bar) +"aTi" = ( +/obj/structure/chair/stool, +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/wood, +/area/science) +"aTj" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/science/research) +"aTk" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/xenobiology) +"aTl" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aTm" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aTn" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"aTo" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"aTp" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aTq" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aTr" = ( +/obj/structure/fence, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aTs" = ( +/obj/effect/festive/street/streetlinesw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aTt" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"aTu" = ( +/obj/effect/festive/street/streetlinese, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aTv" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aTw" = ( +/obj/effect/festive/street/sidewalknsm, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aTx" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aTy" = ( +/obj/machinery/door/airlock/wood/glass, +/turf/open/floor/wood, +/area/commons/dorms) +"aTz" = ( +/turf/closed/festive/greybrick, +/area/commons/dorms) +"aTA" = ( +/obj/structure/table, +/obj/item/assembly/igniter{ + pixel_x = -5; + pixel_y = 3 + }, +/obj/item/assembly/igniter{ + pixel_x = 5; + pixel_y = -4 + }, +/obj/item/assembly/igniter{ + pixel_x = 2; + pixel_y = 6 + }, +/obj/item/assembly/igniter{ + pixel_x = 2; + pixel_y = -1 + }, +/obj/item/assembly/timer{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/assembly/timer{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/assembly/timer{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/assembly/timer{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/engine, +/area/science/misc_lab) +"aTC" = ( +/obj/structure/chair/stool, +/obj/effect/turf_decal/stripes/asteroid/line{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"aTD" = ( +/obj/machinery/atmospherics/components/trinary/mixer/flipped, +/turf/open/floor/engine, +/area/science/misc_lab) +"aTE" = ( +/obj/machinery/atmospherics/components/binary/valve, +/turf/open/floor/engine, +/area/science/misc_lab) +"aTF" = ( +/obj/structure/table, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/item/storage/toolbox/mechanical, +/obj/item/clothing/ears/earmuffs, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aTG" = ( +/obj/structure/table, +/obj/item/electropack, +/obj/item/healthanalyzer, +/obj/item/assembly/signaler, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aTH" = ( +/obj/structure/table, +/obj/machinery/cell_charger{ + pixel_y = 5 + }, +/obj/item/stack/cable_coil, +/obj/item/stock_parts/cell/high/plus, +/obj/item/multitool, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aTI" = ( +/obj/machinery/portable_atmospherics/canister, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aTJ" = ( +/obj/machinery/portable_atmospherics/canister, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/science/misc_lab) +"aTK" = ( +/obj/machinery/portable_atmospherics/canister/carbon_dioxide, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/storage) +"aTL" = ( +/obj/machinery/portable_atmospherics/canister/carbon_dioxide, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/storage) +"aTM" = ( +/obj/machinery/portable_atmospherics/canister/nitrous_oxide, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/storage) +"aTN" = ( +/obj/machinery/portable_atmospherics/canister/nitrous_oxide, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/storage) +"aTO" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/structure/chair/stool, +/turf/open/floor/plasteel, +/area/science) +"aTP" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb, +/obj/machinery/camera{ + c_tag = "Science - Break Room"; + dir = 8; + name = "science camera"; + network = list("ss13","rd") + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/wood, +/area/science) +"aTQ" = ( +/turf/closed/festive/whitebrick, +/area/science/server) +"aTR" = ( +/obj/machinery/door/airlock/research{ + name = "Xenobiology Lab"; + req_access_txt = "47" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) +"aTS" = ( +/obj/effect/landmark/start/assistant, +/turf/open/floor/carpet/green, +/area/science/research/lobby) +"aTT" = ( +/obj/structure/fence/door/opened{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/science) +"aTU" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aTV" = ( +/obj/effect/festive/street/sidewalknsm, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aTW" = ( +/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ + dir = 4 + }, +/turf/open/floor/engine, +/area/science/misc_lab) +"aTX" = ( +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 4 + }, +/turf/open/floor/engine, +/area/science/misc_lab) +"aTY" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible, +/obj/machinery/meter, +/turf/open/floor/engine, +/area/science/misc_lab) +"aTZ" = ( +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 8 + }, +/turf/open/floor/engine, +/area/science/misc_lab) +"aUa" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/storage) +"aUb" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/storage) +"aUc" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/storage) +"aUd" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/storage) +"aUe" = ( +/obj/machinery/vending/coffee, +/turf/open/floor/wood, +/area/science) +"aUf" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science) +"aUg" = ( +/obj/structure/table/wood, +/obj/machinery/newscaster{ + pixel_x = 32 + }, +/obj/item/clipboard, +/obj/item/folder, +/obj/item/clothing/head/beret/sci, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/wood, +/area/science) +"aUh" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"aUi" = ( +/obj/machinery/rnd/server, +/turf/open/floor/circuit/telecomms/server, +/area/science/server) +"aUj" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4; + external_pressure_bound = 140; + name = "server vent"; + pressure_checks = 0 + }, +/turf/open/floor/circuit/telecomms/server, +/area/science/server) +"aUk" = ( +/obj/machinery/atmospherics/pipe/simple{ + dir = 4 + }, +/obj/structure/sign/warning/securearea{ + desc = "A warning sign which reads 'SERVER ROOM'."; + name = "SERVER ROOM"; + pixel_y = 32 + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/science/server) +"aUl" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Aft Primary Hallway" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/science/research/lobby) +"aUm" = ( +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aUn" = ( +/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/plasteel/dark, +/area/science/server) +"aUo" = ( +/turf/closed/festive/whitebrick, +/area/science/robotics) +"aUp" = ( +/obj/structure/sign/departments/science, +/turf/closed/festive/whitebrick/whitebrickcornerne, +/area/science/robotics) +"aUq" = ( +/obj/structure/closet/secure_closet/freezer/meat, +/turf/open/floor/wood, +/area/maintenance/bar) +"aUr" = ( +/obj/machinery/vending/snack, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"aUs" = ( +/obj/structure/fluff/lightpost/light, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"aUu" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/power/apc/auto_name/west, +/obj/structure/cable/yellow, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"aUv" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/power/apc/auto_name/north, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"aUw" = ( +/turf/closed/wall/mineral/wood, +/area/commons/dorms) +"aUx" = ( +/obj/effect/festive/street/streetlineeast, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"aUy" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/festive/street/streetliftedtile2, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aUz" = ( +/obj/effect/festive/street/streetlinenorth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aUA" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aUB" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aUC" = ( +/obj/machinery/atmospherics/components/unary/thermomachine/heater{ + dir = 4 + }, +/turf/open/floor/engine, +/area/science/misc_lab) +"aUD" = ( +/obj/machinery/atmospherics/pipe/manifold/general/visible, +/turf/open/floor/engine, +/area/science/misc_lab) +"aUE" = ( +/obj/machinery/atmospherics/components/trinary/filter{ + dir = 8 + }, +/turf/open/floor/engine, +/area/science/misc_lab) +"aUF" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science/storage) +"aUG" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/science/storage) +"aUH" = ( +/obj/machinery/disposal/bin, +/turf/open/floor/wood, +/area/science) +"aUI" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/floor/wood, +/area/science) +"aUJ" = ( +/obj/machinery/status_display{ + pixel_y = -32 + }, +/obj/machinery/vending/cola/random, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/wood, +/area/science) +"aUK" = ( +/obj/machinery/vending/cigarette, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/wood, +/area/science) +"aUL" = ( +/obj/structure/table/wood, +/obj/item/paper_bin, +/obj/item/pen, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/floor/wood, +/area/science) +"aUM" = ( +/obj/structure/flora/tree/pine/xmas, +/turf/open/floor/grass/snow/edina, +/area/science/research) +"aUN" = ( +/obj/machinery/airalarm/server{ + dir = 4; + pixel_x = -22 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/science/server) +"aUO" = ( +/obj/effect/landmark/blobstart, +/turf/open/floor/plasteel/dark/telecomms, +/area/science/server) +"aUP" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/command/glass{ + name = "Server Room"; + req_access_txt = "30" + }, +/turf/open/floor/plasteel/dark, +/area/science/server) +"aUQ" = ( +/obj/machinery/atmospherics/pipe/manifold{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/science/server) +"aUR" = ( +/obj/structure/chair/office/light, +/obj/machinery/atmospherics/pipe/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/science/server) +"aUS" = ( +/obj/machinery/atmospherics/pipe/simple{ + dir = 9 + }, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/science/server) +"aUT" = ( +/obj/machinery/disposal/bin, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/floor/plasteel/white, +/area/science/robotics) +"aUU" = ( +/obj/structure/chair/wood/normal, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/robotics) +"aUV" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/robotics) +"aUW" = ( +/obj/machinery/computer/arcade{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/plasteel/white, +/area/science/robotics) +"aUX" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/turf/open/floor/plasteel/white, +/area/science/robotics) +"aUY" = ( +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aUZ" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"aVa" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/science/storage) +"aVb" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/storage) +"aVc" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/science/storage) +"aVd" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aVe" = ( +/obj/effect/festive/street/streetlinese, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aVf" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aVg" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ + dir = 4; + external_pressure_bound = 120; + name = "server vent" + }, +/turf/open/floor/circuit/telecomms/server, +/area/science/server) +"aVh" = ( +/obj/structure/sign/warning/securearea{ + desc = "A warning sign which reads 'SERVER ROOM'."; + name = "SERVER ROOM"; + pixel_y = -32 + }, +/obj/machinery/atmospherics/pipe/simple{ + dir = 4 + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/science/server) +"aVi" = ( +/obj/machinery/atmospherics/pipe/simple{ + dir = 9 + }, +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -24 + }, +/turf/open/floor/plasteel/dark, +/area/science/server) +"aVj" = ( +/obj/machinery/computer/rdservercontrol{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/science/server) +"aVk" = ( +/obj/structure/table, +/obj/item/folder/white, +/obj/item/pen/fountain, +/turf/open/floor/plasteel/dark, +/area/science/server) +"aVl" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/carpet/red, +/area/science/robotics) +"aVm" = ( +/turf/open/floor/carpet/red, +/area/science/robotics) +"aVn" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeft, +/turf/open/floor/plasteel/white, +/area/science/robotics) +"aVo" = ( +/obj/effect/festive/street/streetlinesouth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aVp" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"aVq" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"aVr" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/security) +"aVs" = ( +/turf/closed/festive/whitebrick, +/area/science/mixing/chamber) +"aVt" = ( +/turf/open/floor/grass/snow/edina, +/area/medical/medbay/aft) +"aVu" = ( +/obj/machinery/door/firedoor/heavy, +/obj/machinery/door/airlock/research{ + name = "Toxins Storage"; + req_access_txt = "8" + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"aVv" = ( +/turf/closed/festive/whitebrick, +/area/science/mixing) +"aVw" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/closed/festive/whitebrick, +/area/science/mixing) +"aVx" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel/white, +/area/science/explab) +"aVy" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/carpet/red, +/area/science/robotics) +"aVz" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/carpet/red, +/area/science/robotics) +"aVA" = ( +/obj/effect/decal/festive/christmas_reef, +/obj/machinery/door/airlock/wood/glass, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"aVB" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina) +"aVC" = ( +/obj/effect/turf_decal/caution{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"aVD" = ( +/obj/machinery/door/airlock/sandstone{ + name = "Bar Access" + }, +/obj/effect/turf_decal/sand, +/turf/open/floor/wood, +/area/maintenance/bar) +"aVE" = ( +/obj/structure/closet/secure_closet/freezer/kitchen{ + req_access = null + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"aVF" = ( +/obj/structure/fluff/lightpost/light, +/turf/open/floor/festive/alleyway, +/area/edina) +"aVG" = ( +/obj/machinery/door/poddoor/incinerator_toxmix, +/turf/open/floor/engine/vacuum, +/area/science/mixing/chamber) +"aVH" = ( +/obj/structure/sign/warning/vacuum/external{ + pixel_y = 32 + }, +/turf/open/floor/engine/vacuum, +/area/science/mixing/chamber) +"aVI" = ( +/obj/machinery/sparker/toxmix{ + pixel_x = 25 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/toxins_mixing_output{ + dir = 4 + }, +/turf/open/floor/engine/vacuum, +/area/science/mixing/chamber) +"aVJ" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/science/mixing/chamber) +"aVK" = ( +/obj/machinery/airlock_sensor/incinerator_toxmix{ + pixel_y = 24 + }, +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/engine, +/area/science/mixing/chamber) +"aVL" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 4 + }, +/obj/machinery/meter, +/obj/machinery/embedded_controller/radio/airlock_controller/incinerator_toxmix{ + pixel_x = -24 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"aVM" = ( +/obj/machinery/atmospherics/components/binary/valve{ + dir = 4; + name = "mix to port" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"aVN" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/mixing) +"aVO" = ( +/turf/closed/festive/whitebrick, +/area/command/heads_quarters/rd) +"aVP" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/obj/machinery/door/firedoor/heavy, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd) +"aVQ" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/obj/machinery/door/firedoor/heavy, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd) +"aVR" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/obj/machinery/door/firedoor/heavy, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd) +"aVS" = ( +/obj/machinery/door/firedoor/heavy, +/obj/machinery/door/airlock/command{ + name = "Research Director's Office"; + req_access_txt = "30" + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd) +"aVT" = ( +/obj/machinery/door/airlock/research/glass, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/white, +/area/science/robotics) +"aVU" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Aft Primary Hallway" + }, +/obj/machinery/door/firedoor, +/obj/effect/decal/festive/mistletoe, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel, +/area/science/robotics) +"aVV" = ( +/turf/closed/wall/mineral/iron, +/area/service/chapel/office) +"aVW" = ( +/obj/effect/spawner/structure/window/reinforced/indestructable, +/turf/open/floor/plating, +/area/service/chapel/office) +"aVX" = ( +/turf/open/floor/engine/vacuum, +/area/science/mixing/chamber) +"aVY" = ( +/obj/effect/landmark/event_spawn, +/obj/machinery/air_sensor/atmos/toxins_mixing_tank, +/turf/open/floor/engine/vacuum, +/area/science/mixing/chamber) +"aVZ" = ( +/obj/machinery/door/airlock/research/glass/incinerator/toxmix_exterior, +/turf/open/floor/engine, +/area/science/mixing/chamber) +"aWa" = ( +/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_toxmix, +/turf/open/floor/engine, +/area/science/mixing/chamber) +"aWb" = ( +/obj/machinery/door/airlock/research/glass/incinerator/toxmix_interior, +/turf/open/floor/engine, +/area/science/mixing/chamber) +"aWc" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"aWd" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/item/toy/plush/catgirl/fermis, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"aWe" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = 27 + }, +/obj/machinery/camera{ + c_tag = "Toxins Lab East"; + dir = 8; + network = list("ss13","rd"); + pixel_y = -22 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/mixing) +"aWf" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/obj/machinery/door/firedoor/heavy, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd) +"aWg" = ( +/obj/machinery/computer/card/minor/rd{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aWh" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aWi" = ( +/obj/structure/table/reinforced, +/obj/machinery/button/door{ + id = "rdxeno"; + name = "Xenobiology Containment Control"; + pixel_x = -7; + pixel_y = 7; + req_access_txt = "30" + }, +/obj/machinery/button/door{ + id = "rdtoxins"; + name = "Toxins Containment Control"; + pixel_x = -7; + pixel_y = -4; + req_access_txt = "30" + }, +/obj/machinery/button/door{ + id = "rdrnd"; + name = "Research and Development Containment Control"; + pixel_x = 7; + pixel_y = 7; + req_access_txt = "30" + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aWj" = ( +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_y = 26 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aWk" = ( +/obj/effect/festive/street/streetlineem, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"aWl" = ( +/obj/structure/table/reinforced, +/obj/item/paper_bin, +/obj/item/pen/fountain, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/plasteel/white, +/area/edina) +"aWm" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWE, +/obj/machinery/door/firedoor/heavy, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd) +"aWn" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"aWo" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/robotics) +"aWp" = ( +/turf/open/floor/plasteel/white, +/area/science/robotics) +"aWq" = ( +/obj/machinery/vending/cola/red, +/obj/machinery/light/small, +/turf/open/floor/plasteel/white, +/area/science/robotics) +"aWr" = ( +/obj/machinery/vending/snack/green, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/robotics) +"aWs" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aWt" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aWu" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"aWv" = ( +/turf/closed/wall/mineral/iron, +/area/medical/morgue) +"aWw" = ( +/obj/structure/curtain, +/obj/effect/spawner/structure/window/reinforced/indestructable, +/turf/open/floor/plating, +/area/medical/morgue) +"aWx" = ( +/obj/structure/disposalpipe/trunk, +/obj/machinery/disposal/bin, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aWy" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aWz" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/office) +"aWA" = ( +/turf/closed/festive/whitebrick, +/area/command/heads_quarters/cmo) +"aWB" = ( +/obj/structure/chair/comfy/brown, +/obj/machinery/newscaster{ + pixel_y = 32 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/landmark/start/chaplain, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/office) +"aWC" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/office) +"aWD" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aWE" = ( +/obj/effect/festive/street/streetlinesw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aWF" = ( +/obj/machinery/door/morgue{ + name = "Confession Booth (Chaplain)"; + req_access_txt = "22" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/office) +"aWG" = ( +/obj/structure/chair/wood/wings, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/office) +"aWJ" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/progcastaux) +"aWK" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/aux) +"aWL" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/cable/yellow, +/obj/machinery/power/apc/auto_name/west, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/aux) +"aWM" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/machinery/power/apc/auto_name/north, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"aWN" = ( +/obj/machinery/sparker/toxmix{ + pixel_x = 25 + }, +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/toxins_mixing_input{ + dir = 4 + }, +/turf/open/floor/engine/vacuum, +/area/science/mixing/chamber) +"aWO" = ( +/obj/structure/sign/warning/fire{ + pixel_y = -32 + }, +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/engine, +/area/science/mixing/chamber) +"aWP" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 4 + }, +/obj/machinery/meter, +/obj/machinery/button/door/incinerator_vent_toxmix{ + pixel_x = -25; + pixel_y = 5 + }, +/obj/machinery/button/ignition/incinerator/toxmix{ + pixel_x = -25; + pixel_y = -5 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"aWQ" = ( +/obj/machinery/atmospherics/components/binary/valve{ + dir = 4; + name = "port to mix" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"aWR" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/mixing) +"aWS" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWEMiddle, +/obj/machinery/door/firedoor/heavy, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd) +"aWT" = ( +/obj/machinery/computer/mecha{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aWU" = ( +/obj/structure/chair/office/light{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/obj/item/toy/plush/catgirl/fermis, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aWV" = ( +/obj/machinery/computer/aifixer{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aWW" = ( +/obj/structure/chair/office/light{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aWX" = ( +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aWY" = ( +/obj/machinery/camera{ + c_tag = "Science - Research Director's Office"; + dir = 8; + name = "science camera"; + network = list("ss13","rd") + }, +/obj/structure/filingcabinet/chestdrawer, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aWZ" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNS, +/obj/machinery/door/firedoor/heavy, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd) +"aXa" = ( +/turf/closed/festive/whitebrick, +/area/science/circuit) +"aXb" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plasteel, +/area/science/circuit) +"aXc" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/floor/plasteel, +/area/science/circuit) +"aXd" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plasteel, +/area/science/circuit) +"aXe" = ( +/obj/effect/festive/street/streetlinesouth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aXf" = ( +/turf/closed/festive/whitebrick, +/area/science/robotics/lab) +"aXg" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "roboticsprivacy"; + name = "Robotics Shutters" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"aXh" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "roboticsprivacy"; + name = "Robotics Shutters" + }, +/obj/machinery/door/firedoor, +/obj/item/toy/plush/aiplush, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"aXi" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "roboticsprivacy"; + name = "Robotics Shutters" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"aXj" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/closed/festive/whitebrick, +/area/science/robotics/lab) +"aXk" = ( +/obj/machinery/door/poddoor/shutters{ + id = "mechbay"; + name = "Mech Bay Shutters" + }, +/obj/effect/turf_decal/caution, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/science/robotics/mechbay) +"aXl" = ( +/obj/machinery/door/poddoor/shutters{ + id = "mechbay"; + name = "Mech Bay Shutters" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/science/robotics/mechbay) +"aXv" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/commons/storage/tools) +"aXw" = ( +/obj/structure/noticeboard{ + name = "Tool Shoppe" + }, +/obj/item/screwdriver{ + anchored = 1; + pixel_y = 8 + }, +/turf/closed/festive/creambrick{ + color = "#ffbb4d" + }, +/area/commons/storage/tools) +"aXz" = ( +/turf/closed/festive/creambrick{ + color = "#ffbb4d" + }, +/area/commons/storage/tools) +"aXB" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/hydroponics/constructable, +/turf/open/floor/plasteel/dark, +/area/service/hydroponics) +"aXC" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Hydroponics"; + req_access_txt = "35" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"aXD" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRight, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"aXE" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"aXF" = ( +/obj/structure/table, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/item/storage/box/bodybags{ + pixel_y = 8 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/medical/morgue) +"aXG" = ( +/obj/structure/reagent_dispensers/watertank/high, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/medical/morgue) +"aXH" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 6 + }, +/obj/structure/closet/crate, +/obj/item/nullrod, +/obj/item/nullrod, +/obj/item/book/granter/spell/smoke/lesser{ + pixel_y = 2 + }, +/obj/item/book/granter/spell/smoke/lesser{ + pixel_y = 2 + }, +/obj/item/paper/fluff/festive/note_for_chap, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/medical/morgue) +"aXI" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 8 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/medical/morgue) +"aXJ" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/grunge{ + name = "Morgue"; + req_access_txt = "6" + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/medical/morgue) +"aXK" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aXL" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aXM" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aXN" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aXO" = ( +/obj/structure/table/wood/fancy/red, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/obj/item/storage/book/bible{ + pixel_y = 4 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/office) +"aXP" = ( +/obj/effect/decal/festive/fairylights, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"aXQ" = ( +/turf/closed/festive/greybrick, +/area/edina/street/primary/perimeter) +"aXR" = ( +/obj/structure/chair/comfy/black, +/obj/effect/decal/festive/large_green_stocking, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"aXS" = ( +/turf/closed/festive/bluebrick, +/area/edina) +"aXT" = ( +/obj/effect/turf_decal/caution{ + dir = 8 + }, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"aXU" = ( +/obj/machinery/jukebox/disco/indestructible, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"aXV" = ( +/obj/effect/turf_decal/caution{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"aXW" = ( +/obj/structure/table/wood/fancy/red, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/item/camera/spooky, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/office) +"aXX" = ( +/obj/structure/table/wood/fancy/red, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/item/paper_bin{ + pixel_y = 8 + }, +/obj/item/storage/crayons{ + pixel_y = 2 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/office) +"aXY" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aXZ" = ( +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/machinery/power/apc{ + areastring = "/area/service/chapel/office"; + dir = 4; + name = "Chapel Office APC"; + pixel_x = 26 + }, +/obj/structure/filingcabinet, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aYa" = ( +/obj/effect/spawner/structure/window/reinforced/tinted, +/obj/machinery/atmospherics/pipe/layer_manifold, +/turf/open/floor/plating, +/area/service/chapel/office) +"aYc" = ( +/obj/structure/sign/warning/nosmoking{ + pixel_x = -32 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"aYd" = ( +/turf/open/floor/plasteel/white, +/area/science/mixing) +"aYe" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"aYf" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/obj/machinery/door/firedoor/heavy, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd) +"aYg" = ( +/obj/machinery/computer/robotics{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aYh" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aYi" = ( +/obj/effect/festive/street/sidewalks, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"aYj" = ( +/obj/structure/table/reinforced, +/obj/item/folder/white, +/obj/item/stamp/rd, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aYk" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aYl" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aYm" = ( +/obj/structure/displaycase/labcage, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aYn" = ( +/obj/structure/table/reinforced, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_x = -26 + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/stock_parts/cell/high, +/obj/item/stock_parts/cell/high, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"aYo" = ( +/obj/structure/table/reinforced, +/obj/item/integrated_electronics/analyzer, +/obj/item/integrated_electronics/debugger, +/obj/item/integrated_electronics/wirer, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"aYp" = ( +/obj/structure/table/reinforced, +/obj/item/paper_bin, +/obj/item/pen/fountain, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"aYq" = ( +/obj/machinery/camera{ + c_tag = "Science - Experimentation Lab"; + name = "science camera"; + network = list("ss13","rd") + }, +/obj/machinery/requests_console{ + department = "Circuitry Lab"; + name = "Circuitry Lab RC"; + pixel_y = 32; + receive_ore_updates = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"aYr" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"aYs" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"aYt" = ( +/obj/structure/table/reinforced, +/obj/item/storage/fancy/donut_box, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"aYu" = ( +/obj/machinery/vending/assist, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"aYv" = ( +/obj/machinery/button/door{ + id = "roboticsprivacy"; + name = "Robotics Privacy Control"; + pixel_x = -26; + req_access_txt = "29" + }, +/obj/machinery/aug_manipulator, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/science/robotics/lab) +"aYw" = ( +/obj/structure/chair/office/dark{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/science/robotics/lab) +"aYx" = ( +/obj/structure/table, +/obj/machinery/cell_charger, +/obj/item/stock_parts/cell/bluespace, +/obj/item/stock_parts/cell/bluespace, +/obj/item/stock_parts/cell/bluespace, +/obj/item/assembly/prox_sensor, +/obj/item/assembly/prox_sensor, +/obj/item/assembly/prox_sensor, +/obj/item/assembly/prox_sensor, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/science/robotics/lab) +"aYy" = ( +/obj/machinery/conveyor_switch/oneway{ + dir = 8; + id = "robotics1" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"aYz" = ( +/obj/structure/table, +/obj/item/storage/toolbox/electrical, +/obj/item/clothing/head/welding, +/obj/item/clothing/glasses/welding, +/obj/item/multitool, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"aYA" = ( +/obj/structure/table, +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/glass/fifty, +/obj/item/storage/belt/utility, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"aYB" = ( +/obj/machinery/mecha_part_fabricator, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"aYC" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"aYD" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"aYE" = ( +/obj/machinery/mech_bay_recharge_port{ + dir = 2 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/floor/plating, +/area/science/robotics/mechbay) +"aYF" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/circuit, +/area/science/robotics/mechbay) +"aYG" = ( +/obj/machinery/button/door{ + id = "mechbay"; + name = "Mech Bay Shutters Control"; + pixel_y = 26; + req_access_txt = "29" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/robotics/mechbay) +"aYH" = ( +/obj/effect/turf_decal/arrows{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/science/robotics/mechbay) +"aYI" = ( +/obj/machinery/recharge_station, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/plasteel/dark, +/area/science/robotics/mechbay) +"aYV" = ( +/obj/effect/festive/street/streetlinesw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aYW" = ( +/obj/structure/sign/barsign, +/turf/closed/wall/mineral/silver, +/area/maintenance/bar) +"aYX" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSRightEnd, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"aYY" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSMiddle, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"aYZ" = ( +/turf/closed/festive/greybrick/greybrickns, +/area/maintenance/bar) +"aZa" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow, +/obj/machinery/power/apc/auto_name/east, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/supply) +"aZb" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"aZg" = ( +/obj/machinery/vending/assist, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"aZh" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/trainplatform/safe, +/area/maintenance/bar) +"aZi" = ( +/turf/closed/festive/whitebrick, +/area/service/hydroponics) +"aZj" = ( +/obj/structure/table, +/obj/item/watertank, +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"aZk" = ( +/obj/structure/table, +/obj/machinery/reagentgrinder, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"aZl" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"aZm" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"aZn" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"aZo" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Hydroponics"; + req_access_txt = "35" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"aZp" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/research) +"aZq" = ( +/obj/structure/sign/poster/official/space_cops{ + pixel_y = -32 + }, +/turf/open/floor/wood, +/area/security/office) +"aZr" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aZs" = ( +/obj/machinery/door/airlock/freezer{ + name = "Freezer"; + req_one_access_txt = "25;26;28;35" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"aZt" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/hydroponics/constructable, +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/hydroponics) +"aZu" = ( +/turf/closed/wall/ice, +/area/edina) +"aZv" = ( +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/medical/morgue) +"aZw" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/medical/morgue) +"aZx" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aZy" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/extinguisher_cabinet{ + pixel_y = -32 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aZz" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aZA" = ( +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aZB" = ( +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"aZC" = ( +/obj/machinery/light, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aZD" = ( +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aZE" = ( +/obj/machinery/vending/wardrobe/chap_wardrobe, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"aZF" = ( +/obj/structure/chair/wood/wings{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main) +"aZG" = ( +/obj/structure/chair/wood/wings, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"aZH" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aZI" = ( +/turf/open/floor/plasteel/white, +/area/medical/virology) +"aZJ" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"aZK" = ( +/obj/structure/closet/bombcloset, +/obj/machinery/light_switch{ + pixel_y = 28 + }, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/science/mixing) +"aZL" = ( +/obj/structure/closet/bombcloset, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science/mixing) +"aZM" = ( +/obj/machinery/portable_atmospherics/canister, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/obj/machinery/camera{ + c_tag = "Toxins Lab West"; + network = list("ss13","rd") + }, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science/mixing) +"aZN" = ( +/obj/machinery/portable_atmospherics/canister, +/obj/item/radio/intercom{ + pixel_y = 25 + }, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science/mixing) +"aZO" = ( +/obj/machinery/portable_atmospherics/scrubber, +/obj/item/storage/firstaid/toxin, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/airalarm/unlocked{ + pixel_y = 24 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science/mixing) +"aZP" = ( +/obj/machinery/portable_atmospherics/pump, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science/mixing) +"aZQ" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"aZR" = ( +/obj/machinery/holopad, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"aZS" = ( +/obj/machinery/disposal/bin, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/requests_console{ + announcementConsole = 1; + department = "Research Director's Desk"; + departmentType = 5; + name = "Research Director's RC"; + pixel_x = -32; + receive_ore_updates = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aZT" = ( +/obj/machinery/newscaster{ + pixel_y = -32 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aZU" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"aZV" = ( +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/storage) +"aZW" = ( +/obj/structure/table/reinforced, +/obj/item/paicard, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"aZX" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/turf/open/floor/plasteel, +/area/science/circuit) +"aZY" = ( +/obj/structure/table/reinforced, +/obj/item/clothing/head/beret/sci, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"aZZ" = ( +/obj/structure/chair/office/light{ + dir = 8 + }, +/obj/effect/landmark/start/scientist, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"baa" = ( +/turf/open/floor/plasteel/white, +/area/science/circuit) +"bab" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"bac" = ( +/obj/structure/table/reinforced, +/obj/item/circular_saw, +/obj/item/scalpel, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/floor/plasteel/white, +/area/science/robotics/lab) +"bad" = ( +/obj/structure/table/optable{ + name = "Robotics Operating Table" + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/plasteel/white, +/area/science/robotics/lab) +"bae" = ( +/obj/machinery/computer/operating, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/robotics/lab) +"baf" = ( +/obj/structure/table/reinforced, +/obj/item/mmi, +/obj/item/mmi, +/obj/item/mmi, +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/robotics/lab) +"bag" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/floor/plasteel/white, +/area/science/robotics/lab) +"bah" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"bai" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"baj" = ( +/obj/structure/table/wood/fancy/monochrome, +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bak" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Hotel" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/edina) +"bal" = ( +/turf/open/floor/plasteel/white, +/area/science/robotics/lab) +"bam" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"ban" = ( +/obj/effect/turf_decal/bot_red, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bao" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "robotics1" + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bap" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "robotics1" + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"baq" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/mech_bay_recharge_floor, +/area/science/robotics/mechbay) +"bar" = ( +/obj/effect/landmark/start/cyborg, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/robotics/mechbay) +"bas" = ( +/turf/open/floor/plasteel/dark, +/area/science/robotics/mechbay) +"bat" = ( +/obj/structure/table, +/obj/machinery/cell_charger, +/obj/item/stock_parts/cell/bluespace, +/obj/item/stock_parts/cell/bluespace, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/plasteel/dark, +/area/science/robotics/mechbay) +"baE" = ( +/obj/structure/table/wood, +/obj/item/clothing/glasses/prism_glasses, +/obj/machinery/light{ + dir = 1; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"baF" = ( +/obj/structure/table/wood, +/obj/item/slapper, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"baG" = ( +/obj/structure/table/wood, +/obj/item/coin/iron{ + icon_state = "coin_bananium_heads"; + name = "arcade coin"; + pixel_x = -6 + }, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"baH" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/fluff/lightpost/light, +/turf/open/floor/festive/alleyway, +/area/edina) +"baL" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"baS" = ( +/obj/structure/table/reinforced, +/obj/item/crowbar, +/obj/item/wrench, +/obj/item/gps, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"baT" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"baU" = ( +/turf/closed/festive/whitebrick/whitebrickns, +/area/service/hydroponics) +"baV" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/mob/living/simple_animal/hostile/lizard{ + name = "Wags-His-Tail"; + real_name = "Wags-His-Tail" + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"baW" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"baX" = ( +/obj/machinery/computer/prisoner/management, +/obj/structure/sign/poster/official/duelshotgun{ + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/security/warden) +"baY" = ( +/obj/effect/landmark/start/botanist, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"baZ" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bba" = ( +/obj/structure/table/reinforced, +/obj/machinery/recharger, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/structure/sign/poster/official/nt_storm{ + pixel_x = 32 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) +"bbb" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/window/northleft, +/obj/machinery/door/window/southright, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bbc" = ( +/turf/closed/festive/redbrick, +/area/security/checkpoint/medical) +"bbd" = ( +/obj/effect/turf_decal/tile/green, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bbe" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bbf" = ( +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bbg" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/landmark/start/botanist, +/obj/structure/chair/stool, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bbh" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bbi" = ( +/obj/structure/bodycontainer/morgue{ + dir = 1 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/medical/morgue) +"bbj" = ( +/obj/structure/bodycontainer/morgue{ + dir = 1 + }, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/medical/morgue) +"bbk" = ( +/obj/effect/turf_decal/caution, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"bbl" = ( +/obj/effect/turf_decal/stripes/asteroid/line{ + dir = 1 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"bbm" = ( +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"bbn" = ( +/obj/structure/cable/yellow, +/obj/machinery/light/small, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/machinery/power/apc{ + areastring = "/area/medical/morgue"; + name = "Chapel Morgue APC"; + pixel_y = -26 + }, +/obj/item/extinguisher, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/medical/morgue) +"bbo" = ( +/obj/structure/bodycontainer/crematorium{ + dir = 1 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/medical/morgue) +"bbp" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Chapel Office"; + req_access_txt = "22" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"bbq" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Chapel Office"; + req_access_txt = "22" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/indestructible/hotelwood, +/area/service/chapel/office) +"bbr" = ( +/obj/machinery/door/morgue{ + name = "Confession Booth" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main) +"bbs" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -23 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bbt" = ( +/obj/structure/table/wood/fancy/green, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bbu" = ( +/obj/structure/table/wood/fancy/green, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bbv" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/festive/street/streetliftedtile2, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bbw" = ( +/obj/machinery/door/firedoor/heavy, +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWE, +/turf/open/floor/plasteel/dark, +/area/science/mixing) +"bbx" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"bby" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/junction{ + dir = 4 + }, +/turf/closed/wall/mineral/wood, +/area/command/heads_quarters/rd/private) +"bbz" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold{ + dir = 4 + }, +/turf/closed/wall/mineral/wood, +/area/command/heads_quarters/rd/private) +"bbA" = ( +/turf/closed/wall/mineral/wood, +/area/command/heads_quarters/rd/private) +"bbB" = ( +/obj/machinery/door/firedoor/heavy, +/obj/machinery/door/airlock/research{ + name = "Toxins Storage"; + req_access_txt = "8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/science/storage) +"bbC" = ( +/obj/structure/table/reinforced, +/obj/item/aicard, +/obj/item/circuitboard/aicore, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"bbD" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/turf/open/floor/plasteel, +/area/science/circuit) +"bbE" = ( +/obj/structure/table/reinforced, +/obj/item/multitool, +/obj/item/screwdriver, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"bbF" = ( +/obj/structure/table/reinforced, +/obj/item/integrated_circuit_printer, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"bbG" = ( +/obj/structure/table/reinforced, +/obj/machinery/cell_charger, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"bbH" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/science/circuit) +"bbI" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/circuit) +"bbJ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/circuit) +"bbK" = ( +/obj/structure/table/reinforced, +/obj/item/retractor, +/obj/item/hemostat, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/robotics/lab) +"bbL" = ( +/obj/structure/table/reinforced, +/obj/item/cautery, +/obj/item/surgical_drapes, +/obj/item/clothing/gloves/color/latex, +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/turf/open/floor/plasteel/white, +/area/science/robotics/lab) +"bbM" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"bbN" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"bbO" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/command{ + name = "Server Room"; + req_access_txt = "30" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/science/server) +"bbP" = ( +/obj/machinery/computer/mech_bay_power_console{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/circuit, +/area/science/robotics/mechbay) +"bbQ" = ( +/obj/structure/table, +/obj/item/storage/toolbox/mechanical, +/obj/item/crowbar/red, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/dark, +/area/science/robotics/mechbay) +"bbR" = ( +/turf/closed/festive/whitebrick, +/area/medical/surgery) +"bbY" = ( +/obj/effect/landmark/start/assistant, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"bcb" = ( +/obj/structure/flora/ausbushes/genericbush, +/obj/structure/flora/ausbushes/lavendergrass, +/obj/structure/flora/ausbushes/fernybush, +/obj/structure/flora/ausbushes/ppflowers, +/obj/structure/window, +/obj/structure/sign/poster/official/cohiba_robusto_ad{ + pixel_y = 32 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/turf/open/floor/grass, +/area/commons/storage/tools) +"bcc" = ( +/obj/machinery/vending/wardrobe/hydro_wardrobe, +/turf/open/floor/carpet/monochrome, +/area/commons/storage/tools) +"bcd" = ( +/obj/machinery/vending/wardrobe/chef_wardrobe, +/turf/open/floor/carpet/monochrome, +/area/commons/storage/tools) +"bce" = ( +/obj/machinery/vending/wardrobe/bar_wardrobe, +/turf/open/floor/carpet/monochrome, +/area/commons/storage/tools) +"bcf" = ( +/obj/structure/closet/secure_closet/bar, +/obj/item/storage/box/drinkingglasses, +/obj/item/storage/box/cups, +/obj/item/gun/ballistic/revolver/doublebarrel, +/turf/open/floor/carpet/monochrome, +/area/commons/storage/tools) +"bci" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bcj" = ( +/obj/machinery/vending/wardrobe/hydro_wardrobe, +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bck" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bcl" = ( +/obj/item/wrench, +/obj/item/wirecutters, +/obj/item/hand_labeler, +/obj/item/hand_labeler_refill, +/obj/item/hand_labeler_refill, +/obj/item/stack/packageWrap, +/obj/item/stack/packageWrap, +/obj/item/stack/wrapping_paper, +/obj/structure/closet/crate/hydroponics, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bcm" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/grass/snow/edina, +/area/edina/street/secondary/command) +"bcn" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"bco" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bcp" = ( +/obj/structure/closet/secure_closet/hydroponics, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bcq" = ( +/obj/structure/closet/secure_closet/hydroponics, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bcr" = ( +/obj/effect/festive/street/sidewalks, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bcs" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bct" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bcv" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Pet Store" + }, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"bcw" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bcx" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/service/bar/atrium) +"bcy" = ( +/obj/machinery/vending/hydronutrients, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/dark, +/area/service/hydroponics) +"bcz" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Pet Store" + }, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"bcB" = ( +/obj/structure/festive/trainplatform/edge_west, +/obj/structure/chair/stool/bar, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/light, +/area/maintenance/bar) +"bcC" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/trainplatform/safe, +/area/maintenance/bar) +"bcD" = ( +/obj/machinery/chem_master/condimaster, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bcE" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/landmark/start/botanist, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bcF" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bcG" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bcH" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 8 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bcI" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 8 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bcJ" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer1{ + dir = 4 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bcK" = ( +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/obj/machinery/power/apc{ + areastring = "/area/service/chapel/main/monastery"; + dir = 8; + name = "Chapel Dining Room APC"; + pixel_x = -26 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bcL" = ( +/obj/structure/chair/wood/wings{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bcM" = ( +/obj/structure/chair/wood/wings{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bcN" = ( +/obj/structure/closet/crate/trashcart, +/obj/effect/spawner/lootdrop/maintenance, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bcO" = ( +/obj/machinery/door/firedoor/heavy, +/obj/machinery/door/airlock/research{ + name = "Toxins Lab"; + req_access_txt = "7" + }, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"bcP" = ( +/obj/structure/closet/secure_closet/RD, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_x = -32 + }, +/obj/item/clothing/suit/hooded/wintercoat/rd, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/ears/earmuffs, +/obj/item/key/RD, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/wood, +/area/command/heads_quarters/rd/private) +"bcQ" = ( +/obj/machinery/camera{ + c_tag = "Science - Port"; + name = "science camera"; + network = list("ss13","rd") + }, +/turf/open/floor/carpet/purple, +/area/command/heads_quarters/rd/private) +"bcR" = ( +/turf/open/floor/carpet/purple, +/area/command/heads_quarters/rd/private) +"bcS" = ( +/obj/machinery/atmospherics/pipe/simple{ + dir = 10 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel/dark, +/area/science/server) +"bcT" = ( +/obj/structure/dresser, +/obj/item/storage/secure/safe{ + pixel_x = 32 + }, +/turf/open/floor/holofloor/wood, +/area/command/heads_quarters/rd/private) +"bcU" = ( +/turf/closed/festive/whitebrick, +/area/command/heads_quarters/rd/private) +"bcV" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/closed/festive/whitebrick, +/area/command/heads_quarters/rd) +"bcW" = ( +/obj/structure/table/reinforced, +/obj/machinery/computer/security/telescreen{ + desc = "Used for watching the RD's goons from the safety of his office."; + dir = 4; + name = "Research Monitor"; + network = list("rd"); + pixel_x = -28 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"bcX" = ( +/obj/structure/table/reinforced, +/obj/item/integrated_electronics/analyzer, +/obj/item/integrated_electronics/debugger, +/obj/item/integrated_electronics/wirer, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"bcY" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/science/circuit) +"bcZ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/circuit) +"bda" = ( +/obj/machinery/door/airlock/research{ + name = "Robotics Lab"; + req_access_txt = "29" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bdb" = ( +/obj/machinery/camera{ + c_tag = "Server Room"; + network = list("ss13","rd"); + pixel_x = 22 + }, +/obj/machinery/power/apc{ + areastring = "/area/science/server"; + dir = 1; + name = "Server Room APC"; + pixel_y = 25 + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel/dark, +/area/science/server) +"bdc" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bdd" = ( +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bde" = ( +/obj/machinery/conveyor_switch/oneway{ + dir = 8; + id = "robotics2" + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bdf" = ( +/obj/structure/table, +/obj/item/storage/toolbox/electrical, +/obj/item/clothing/head/welding, +/obj/item/clothing/glasses/welding, +/obj/item/multitool, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bdg" = ( +/obj/structure/table, +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/glass/fifty, +/obj/item/storage/belt/utility, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bdh" = ( +/obj/machinery/mecha_part_fabricator, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bdi" = ( +/obj/structure/chair/wood/normal, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/effect/landmark/start/assistant, +/turf/open/floor/plasteel/white, +/area/science/robotics) +"bdj" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/robotics/mechbay) +"bdk" = ( +/obj/effect/landmark/start/roboticist, +/obj/machinery/holopad, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/robotics/mechbay) +"bdl" = ( +/obj/machinery/recharge_station, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/dark, +/area/science/robotics/mechbay) +"bdq" = ( +/turf/closed/festive/whitebrick, +/area/medical/exam_room) +"bds" = ( +/obj/structure/table/wood, +/obj/item/sord, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"bdt" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"bdu" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/trainplatform/safe, +/area/maintenance/bar) +"bdv" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/carpet/monochrome, +/area/commons/storage/tools) +"bdw" = ( +/obj/structure/table/reinforced, +/obj/item/stack/packageWrap, +/obj/item/hand_labeler, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"bdx" = ( +/obj/structure/table/reinforced, +/obj/item/storage/toolbox/mechanical, +/obj/item/flashlight, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"bdy" = ( +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bdA" = ( +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bdE" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bdF" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/grass/snow/edina, +/area/edina/street/secondary/command) +"bdG" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"bdH" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8; + pixel_y = 20 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/north) +"bdI" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"bdJ" = ( +/obj/effect/festive/street/streetlinewest, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"bdK" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/north) +"bdL" = ( +/obj/structure/chair/comfy/black{ + dir = 1 + }, +/obj/structure/window/reinforced, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bdM" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bdN" = ( +/obj/structure/window/reinforced, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bdO" = ( +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/research) +"bdQ" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bdR" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bdS" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bdT" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 16; + pixel_y = 16 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bdU" = ( +/obj/effect/festive/street/sidewalkw, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"bdX" = ( +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/obj/machinery/power/apc{ + areastring = "/area/service/chapel/main/monastery"; + dir = 8; + name = "Chapel Hall APC"; + pixel_y = 24 + }, +/turf/open/indestructible{ + dir = 1; + icon_state = "chapel" + }, +/area/service/chapel/main/monastery) +"bdY" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/indestructible{ + dir = 4; + icon_state = "chapel" + }, +/area/service/chapel/main/monastery) +"bdZ" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/airalarm{ + pixel_y = 22 + }, +/turf/open/indestructible{ + dir = 1; + icon_state = "chapel" + }, +/area/service/chapel/main/monastery) +"bea" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/indestructible{ + dir = 4; + icon_state = "chapel" + }, +/area/service/chapel/main/monastery) +"beb" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bec" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bed" = ( +/turf/open/indestructible{ + dir = 1; + icon_state = "chapel" + }, +/area/service/chapel/main/monastery) +"bee" = ( +/turf/open/indestructible{ + dir = 4; + icon_state = "chapel" + }, +/area/service/chapel/main/monastery) +"bef" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"beg" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"beh" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bei" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bej" = ( +/obj/structure/closet/crate/trashcart, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 3; + name = "3maintenance loot spawner" + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bek" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"bel" = ( +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 1 + }, +/obj/machinery/meter, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"bem" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 10 + }, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"ben" = ( +/obj/item/assembly/prox_sensor{ + pixel_x = -4; + pixel_y = 1 + }, +/obj/item/assembly/prox_sensor{ + pixel_x = 8; + pixel_y = 9 + }, +/obj/item/assembly/prox_sensor{ + pixel_x = 9; + pixel_y = -2 + }, +/obj/item/assembly/prox_sensor{ + pixel_y = 2 + }, +/obj/structure/table/reinforced, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"beo" = ( +/obj/structure/chair/stool, +/obj/effect/landmark/start/scientist, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"bep" = ( +/obj/structure/table/reinforced, +/obj/item/wrench, +/obj/item/screwdriver{ + pixel_y = 10 + }, +/obj/item/analyzer, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"beq" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/status_display/ai{ + pixel_x = -32 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/wood, +/area/command/heads_quarters/rd/private) +"ber" = ( +/obj/effect/landmark/start/research_director, +/turf/open/floor/carpet/purple, +/area/command/heads_quarters/rd/private) +"bes" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/status_display{ + pixel_x = 32 + }, +/obj/item/bedsheet/rd/double, +/obj/structure/bed/double, +/turf/open/floor/holofloor/wood, +/area/command/heads_quarters/rd/private) +"bet" = ( +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd) +"beu" = ( +/obj/machinery/button/door{ + id = "rdgarage"; + name = "Director's Garage Door"; + pixel_x = -7; + pixel_y = 26; + req_access_txt = "30" + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd) +"bev" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/science) +"bew" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"bex" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/science) +"bey" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"bez" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"beA" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"beB" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"beC" = ( +/obj/effect/festive/street/sidewalke, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"beD" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/north) +"beE" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/castle) +"beF" = ( +/obj/structure/fence/corner{ + dir = 10 + }, +/turf/open/floor/grass/snow/edina, +/area/edina/street/primary/progress) +"beG" = ( +/obj/structure/chair/office/light{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"beH" = ( +/obj/structure/table/reinforced, +/obj/item/storage/box/bodybags, +/obj/item/pen/fountain, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"beI" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/research{ + name = "Break Room"; + req_access_txt = "47" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/science) +"beJ" = ( +/obj/machinery/conveyor{ + dir = 8; + name = "robotics2" + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"beK" = ( +/obj/machinery/conveyor{ + dir = 8; + name = "robotics2" + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"beL" = ( +/obj/machinery/computer/mech_bay_power_console{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/circuit/green, +/area/science/robotics/mechbay) +"beM" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science/robotics/mechbay) +"beR" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 5 + }, +/area/commons/fitness/recreation) +"beT" = ( +/turf/open/floor/plasteel, +/area/service/electronic_marketing_den) +"beU" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 9 + }, +/area/commons/fitness/recreation) +"beW" = ( +/turf/open/floor/wood, +/area/commons/storage/tools) +"beX" = ( +/turf/open/floor/carpet/monochrome, +/area/commons/storage/tools) +"beY" = ( +/obj/structure/table/reinforced, +/obj/item/clothing/gloves/color/yellow, +/obj/item/storage/box/lights/mixed, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"bfb" = ( +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/door/airlock/engineering/glass{ + name = "Tool Shoppe" + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"bfc" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = 16 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bfd" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8; + pixel_y = 16 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bfe" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/security) +"bff" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bfg" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/security) +"bfh" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/security) +"bfi" = ( +/obj/machinery/door/firedoor/heavy, +/obj/machinery/door/airlock/command{ + name = "Research Director's Office"; + req_access_txt = "30" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd) +"bfj" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bfk" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/sidewalke, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bfl" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bfm" = ( +/turf/closed/festive/whitebrick, +/area/medical/medbay/lobby) +"bfn" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bfo" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bfp" = ( +/obj/structure/table/wood/fancy/green, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bfq" = ( +/turf/open/indestructible{ + dir = 8; + icon_state = "chapel" + }, +/area/service/chapel/main/monastery) +"bfr" = ( +/turf/open/indestructible{ + icon_state = "chapel" + }, +/area/service/chapel/main/monastery) +"bfs" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bft" = ( +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/turf/open/indestructible{ + dir = 8; + icon_state = "chapel" + }, +/area/service/chapel/main/monastery) +"bfu" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bfv" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/carpet/royalblue, +/area/service/cafeteria) +"bfw" = ( +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/castle) +"bfx" = ( +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bfy" = ( +/turf/closed/wall/mineral/iron, +/area/service/chapel/main) +"bfz" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/airlock/public/glass, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bfA" = ( +/obj/effect/spawner/structure/window/reinforced/indestructable, +/turf/open/floor/plating, +/area/service/chapel/main) +"bfB" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"bfC" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"bfD" = ( +/obj/structure/closet/l3closet/scientist{ + pixel_x = -2 + }, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/ears/earmuffs, +/obj/item/clothing/ears/earmuffs, +/obj/item/clothing/neck/scarf/purple, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/head/beret/sci, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"bfE" = ( +/obj/machinery/vending/wardrobe/science_wardrobe, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"bfF" = ( +/obj/item/assembly/signaler{ + pixel_y = 8 + }, +/obj/item/assembly/signaler{ + pixel_x = -8; + pixel_y = 5 + }, +/obj/item/assembly/signaler{ + pixel_x = 6; + pixel_y = 5 + }, +/obj/item/assembly/signaler{ + pixel_x = -2; + pixel_y = -2 + }, +/obj/structure/table/reinforced, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"bfG" = ( +/obj/item/transfer_valve{ + pixel_x = -5 + }, +/obj/item/transfer_valve{ + pixel_x = -5 + }, +/obj/item/transfer_valve, +/obj/item/transfer_valve, +/obj/item/transfer_valve{ + pixel_x = 5 + }, +/obj/item/transfer_valve{ + pixel_x = 5 + }, +/obj/machinery/requests_console{ + department = "Science"; + departmentType = 2; + name = "Science Requests Console"; + pixel_y = -30; + receive_ore_updates = 1 + }, +/obj/structure/table/reinforced, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"bfH" = ( +/obj/item/assembly/timer{ + pixel_x = 5; + pixel_y = 4 + }, +/obj/item/assembly/timer{ + pixel_x = -4; + pixel_y = 2 + }, +/obj/item/assembly/timer{ + pixel_x = 6; + pixel_y = -4 + }, +/obj/item/assembly/timer, +/obj/structure/table/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"bfI" = ( +/obj/structure/tank_dispenser, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"bfJ" = ( +/obj/machinery/suit_storage_unit/rd, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/rd/private) +"bfL" = ( +/obj/machinery/button/door{ + id = "idquarters"; + name = "Privacy Control"; + pixel_x = -26; + pixel_y = -26; + req_access_txt = "30" + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/rd/private) +"bfM" = ( +/obj/machinery/modular_computer/console/preset/research{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/rd/private) +"bfN" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/rd/private) +"bfO" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp, +/obj/machinery/newscaster{ + pixel_y = -32 + }, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_x = 26 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/holofloor/wood, +/area/command/heads_quarters/rd/private) +"bfP" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/command/heads_quarters/rd/private) +"bfQ" = ( +/obj/vehicle/sealed/vectorcraft/RD, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd) +"bfR" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd) +"bfS" = ( +/obj/structure/closet/crate/trashcart, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 2; + name = "2maintenance loot spawner" + }, +/turf/open/floor/grass/snow/edina, +/area/science) +"bfT" = ( +/obj/structure/table/reinforced, +/obj/item/stock_parts/cell/high, +/obj/item/stock_parts/cell/high, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"bfU" = ( +/obj/structure/table/reinforced, +/obj/machinery/newscaster{ + pixel_y = -32 + }, +/obj/item/integrated_circuit_printer, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"bfV" = ( +/obj/structure/table/reinforced, +/obj/item/paper_bin, +/obj/item/pen/fountain, +/obj/structure/sign/poster/official/random{ + pixel_y = -32 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"bfW" = ( +/obj/machinery/light, +/obj/structure/closet/crate, +/obj/item/target/alien, +/obj/item/target/alien, +/obj/item/target/clown, +/obj/item/target/clown, +/obj/item/target/syndicate, +/obj/item/gun/energy/laser/practice, +/obj/item/gun/energy/laser/practice, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"bfX" = ( +/obj/structure/target_stake, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/circuit) +"bfY" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/circuit) +"bfZ" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/science/circuit) +"bga" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/circuit) +"bgb" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/science/circuit) +"bgc" = ( +/obj/structure/fence{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"bgd" = ( +/obj/structure/fence{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"bge" = ( +/obj/structure/bodycontainer/morgue, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bgf" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bgg" = ( +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/machinery/disposal/bin, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bgh" = ( +/obj/machinery/vending/wardrobe/robo_wardrobe, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bgi" = ( +/obj/machinery/rnd/production/circuit_imprinter, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bgj" = ( +/obj/machinery/computer/rdconsole/robotics{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bgk" = ( +/obj/structure/table, +/obj/item/storage/firstaid{ + empty = 1; + name = "first-aid kit (empty)" + }, +/obj/item/storage/firstaid{ + empty = 1; + name = "first-aid kit (empty)" + }, +/obj/item/storage/firstaid{ + empty = 1; + name = "first-aid kit (empty)" + }, +/obj/item/healthanalyzer, +/obj/item/healthanalyzer, +/obj/item/healthanalyzer, +/obj/item/clothing/head/beret/robo, +/obj/item/clothing/head/beret/robo, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bgl" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bgm" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bgn" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bgo" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bgp" = ( +/obj/effect/festive/street/streetlinewest, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/castle) +"bgq" = ( +/obj/structure/table, +/obj/item/stack/sheet/plasteel{ + amount = 15 + }, +/obj/item/assembly/flash/handheld, +/obj/item/assembly/flash/handheld, +/obj/item/assembly/flash/handheld, +/obj/item/assembly/flash/handheld, +/obj/item/assembly/flash/handheld, +/obj/item/assembly/flash/handheld, +/obj/item/stack/cable_coil{ + amount = 5 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bgr" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bgs" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bgt" = ( +/obj/item/key, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/vehicle/sealed/vectorcraft/truck{ + dir = 8 + }, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/plasteel/dark, +/area/science/robotics/mechbay) +"bgy" = ( +/obj/machinery/vr_sleeper{ + dir = 4 + }, +/obj/effect/turf_decal/tile/bar, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bgz" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk, +/turf/open/floor/carpet/monochrome, +/area/commons/storage/tools) +"bgA" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/shaker, +/obj/item/book/granter/action/drink_fling, +/obj/item/stack/spacecash/c100, +/turf/open/floor/carpet/monochrome, +/area/commons/storage/tools) +"bgB" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bgC" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bgD" = ( +/obj/machinery/door/airlock/atmos{ + name = "Toxins Storage"; + req_access_txt = "24" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bgE" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bgF" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bgG" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bgH" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bgI" = ( +/turf/closed/wall/mineral/wood, +/area/commons/storage/tools) +"bgJ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bgK" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bgM" = ( +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/turf/open/indestructible{ + dir = 1; + icon_state = "chapel" + }, +/area/service/chapel/main/monastery) +"bgN" = ( +/obj/structure/table/wood/fancy/red, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bgO" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bgP" = ( +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/castle) +"bgQ" = ( +/obj/effect/festive/street/streetlineeast, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/castle) +"bgR" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/castle) +"bgS" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bgT" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bgU" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bgV" = ( +/turf/open/floor/grass/snow/edina, +/area/edina/street/secondary/castle) +"bgW" = ( +/obj/effect/festive/street/streetlinewest, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/castle) +"bgX" = ( +/obj/machinery/airalarm{ + pixel_y = 22 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bgY" = ( +/turf/open/floor/festive/cobblestone/safe, +/area/cargo) +"bgZ" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bha" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bhb" = ( +/obj/structure/table/wood/fancy/green, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bhc" = ( +/obj/machinery/newscaster{ + pixel_y = 32 + }, +/obj/structure/table/wood/fancy/green, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bhd" = ( +/obj/machinery/door/firedoor/heavy, +/obj/machinery/door/airlock/research{ + name = "Toxins Launch Room Access"; + req_access_txt = "7" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"bhe" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "idquarters"; + name = "Director's Quarters Shutters" + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd/private) +"bhf" = ( +/obj/machinery/door/poddoor/shutters{ + id = "rdgarage"; + name = "Director's Garage" + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/rd) +"bhg" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/junction{ + dir = 1 + }, +/turf/closed/festive/whitebrick, +/area/science/circuit) +"bhh" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/research) +"bhi" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 5 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/research) +"bhj" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/junction{ + dir = 1 + }, +/turf/closed/festive/whitebrick, +/area/science/robotics/lab) +"bhk" = ( +/obj/structure/fence{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bhl" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"bhm" = ( +/obj/machinery/mech_bay_recharge_port{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/floor/plating, +/area/science/robotics/mechbay) +"bhn" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold{ + dir = 1 + }, +/turf/open/floor/circuit/green, +/area/science/robotics/mechbay) +"bho" = ( +/obj/machinery/button/door{ + id = "RL01"; + name = "Alley Door Control"; + pixel_y = -26 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/science/robotics/mechbay) +"bhp" = ( +/obj/effect/turf_decal/arrows, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/science/robotics/mechbay) +"bhq" = ( +/obj/item/key, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/obj/vehicle/sealed/vectorcraft/truck{ + dir = 8 + }, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/science/robotics/mechbay) +"bht" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = -5 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/castle) +"bhu" = ( +/obj/machinery/vr_sleeper{ + dir = 4 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bhx" = ( +/obj/machinery/computer/arcade/battle{ + dir = 8 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bhy" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/castle) +"bhz" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/castle) +"bhA" = ( +/obj/effect/festive/street/streetlinewest, +/obj/structure/disposalpipe/segment, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/castle) +"bhB" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/castle) +"bhC" = ( +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/castle) +"bhD" = ( +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/castle) +"bhG" = ( +/obj/structure/disposalpipe/segment, +/turf/closed/festive/whitebrick, +/area/commons/storage/tools) +"bhI" = ( +/obj/machinery/door/airlock/titanium{ + name = "Service Office"; + req_one_access_txt = "25;26;28;35" + }, +/turf/open/floor/plasteel/dark, +/area/commons/storage/tools) +"bhK" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"bhL" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWELeft, +/turf/closed/festive/redbrick, +/area/commons/dorms) +"bhM" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/science/mixing) +"bhN" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/castle) +"bhO" = ( +/turf/closed/festive/greypanel/greypanelcornernw, +/area/commons/fitness/recreation) +"bhP" = ( +/turf/closed/festive/greypanel/greypanelns, +/area/commons/fitness/recreation) +"bhQ" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/storage/fancy/candle_box{ + pixel_y = 8 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bhR" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/flashlight/lantern{ + pixel_y = 8 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bhS" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/flashlight/lantern{ + pixel_y = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bhT" = ( +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bhU" = ( +/obj/structure/disposalpipe/segment, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bhV" = ( +/obj/structure/sign/departments/holy, +/turf/closed/wall/mineral/iron, +/area/service/chapel/main) +"bhW" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/research) +"bhX" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/research) +"bhY" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/research) +"bhZ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/research) +"bia" = ( +/obj/structure/fence{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 10 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/research) +"bib" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"bic" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/junction{ + dir = 1 + }, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science/robotics/mechbay) +"bid" = ( +/obj/machinery/door/poddoor/shutters{ + id = "RL01"; + name = "Robotics Bay Alley Access" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/science/robotics/mechbay) +"bie" = ( +/obj/machinery/door/poddoor/shutters{ + id = "RL01"; + name = "Robotics Bay Alley Access" + }, +/obj/effect/turf_decal/caution, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/science/robotics/mechbay) +"bij" = ( +/obj/structure/fence{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/research) +"bik" = ( +/obj/structure/fence{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/research) +"bil" = ( +/turf/closed/festive/greypanel/greypanelcornerne, +/area/commons/fitness/recreation) +"bim" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/research) +"biq" = ( +/obj/machinery/vr_sleeper{ + dir = 4 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bir" = ( +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/commons/fitness/recreation) +"bit" = ( +/obj/effect/turf_decal/tile/bar, +/obj/structure/chair/stool/bar, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, +/area/commons/fitness/recreation) +"biu" = ( +/obj/machinery/computer/arcade/orion_trail{ + dir = 8 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bix" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"biC" = ( +/obj/structure/table/reinforced, +/obj/item/stock_parts/cell/high, +/obj/item/stock_parts/cell/high, +/obj/machinery/cell_charger, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"biE" = ( +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/research) +"biF" = ( +/obj/effect/landmark/start/assistant, +/obj/machinery/door/window/westleft, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"biG" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"biH" = ( +/turf/closed/festive/greypanel/greypanelwe, +/area/commons/fitness/recreation) +"biI" = ( +/obj/structure/table/wood, +/obj/item/clothing/suit/nerdshirt, +/obj/item/clothing/glasses/prism_glasses, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"biJ" = ( +/obj/structure/table/wood, +/obj/item/slapper, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"biK" = ( +/obj/structure/table/wood, +/obj/item/clothing/shoes/kindleKicks, +/obj/structure/window/spawner/east, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"biL" = ( +/obj/machinery/vending/cola/pwr_game, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"biM" = ( +/obj/structure/chair/sofa/corp/left{ + dir = 4 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"biN" = ( +/obj/structure/table/glass, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"biO" = ( +/turf/closed/indestructible/fakeglass, +/area/commons/storage/tools) +"biP" = ( +/obj/machinery/light/floor, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"biQ" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"biR" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"biS" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"biT" = ( +/obj/structure/chair/sofa/corp/right{ + dir = 8 + }, +/obj/structure/window/spawner/east, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"biU" = ( +/obj/effect/festive/street/sidewalkw, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"biV" = ( +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"biW" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"biX" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer1{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"biY" = ( +/obj/structure/mineral_door/wood, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main) +"biZ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bja" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer1{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bjb" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/service/chapel/main) +"bjc" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/service/chapel/main) +"bjd" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bje" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Chapel" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main) +"bjf" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"bjg" = ( +/turf/closed/festive/whitebrick, +/area/commons/storage/tools) +"bjh" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"bjk" = ( +/obj/structure/chair/sofa/corp/left{ + dir = 4 + }, +/obj/structure/window/spawner/west, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"bjl" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/table/glass, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"bjm" = ( +/obj/structure/chair/sofa/corp/right{ + dir = 8 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"bjn" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bjo" = ( +/obj/effect/festive/street/sidewalke, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bjp" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"bjq" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/commons/dorms) +"bjr" = ( +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"bjs" = ( +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"bjt" = ( +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"bju" = ( +/obj/structure/chair/sofa/corp/right{ + dir = 4 + }, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"bjv" = ( +/obj/structure/table/glass, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"bjw" = ( +/obj/structure/chair/sofa/corp/left{ + dir = 8 + }, +/obj/structure/window/spawner/east, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"bjx" = ( +/obj/structure/chair/sofa/corp/right{ + dir = 4 + }, +/obj/structure/window/spawner/west, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"bjy" = ( +/obj/structure/chair/sofa/corp/left{ + dir = 8 + }, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"bjz" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/carpet/royalblue, +/area/service/cafeteria) +"bjA" = ( +/obj/machinery/holopad, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bjB" = ( +/obj/effect/landmark/start/chaplain, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bjC" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/storage/book/bible{ + pixel_y = 4 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bjD" = ( +/obj/structure/disposalpipe/junction/yjunction{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bjE" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/light/floor, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bjF" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bjG" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bjH" = ( +/obj/structure/mineral_door/wood, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main) +"bjI" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bjJ" = ( +/obj/structure/disposalpipe/junction{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bjK" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/light/floor, +/turf/open/floor/carpet/green, +/area/service/chapel/main) +"bjL" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/green, +/area/service/chapel/main) +"bjM" = ( +/obj/structure/disposalpipe/junction/flip{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/landmark/xmastree, +/turf/open/floor/carpet/green, +/area/service/chapel/main) +"bjN" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/festive/sidewalk, +/area/security) +"bjO" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bjP" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bjQ" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bjR" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/service/cafeteria) +"bjS" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"bjT" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bjU" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessprogress) +"bjV" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/light/floor, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bjW" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bjX" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Chapel" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main) +"bjY" = ( +/turf/closed/festive/greybrick, +/area/commons/fitness/recreation) +"bjZ" = ( +/turf/closed/festive/whitebrick{ + color = "#c1ff91" + }, +/area/medical/virology) +"bka" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bkb" = ( +/obj/structure/window{ + dir = 8 + }, +/obj/effect/landmark/event_spawn, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"bkc" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessservitor) +"bkd" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessservitor) +"bke" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessservitor) +"bkf" = ( +/obj/structure/table/wood, +/obj/item/sord, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"bkg" = ( +/obj/structure/table/wood, +/turf/open/floor/carpet/arcade, +/area/commons/fitness/recreation) +"bkh" = ( +/obj/machinery/vr_sleeper, +/obj/structure/window/spawner/west, +/turf/open/floor/plasteel/vaporwave, +/area/commons/fitness/recreation) +"bki" = ( +/obj/machinery/vr_sleeper, +/turf/open/floor/plasteel/vaporwave, +/area/commons/fitness/recreation) +"bkj" = ( +/obj/machinery/vr_sleeper, +/obj/structure/window/spawner/east, +/turf/open/floor/plasteel/vaporwave, +/area/commons/fitness/recreation) +"bkk" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/plasteel/elevatorshaft, +/area/commons/fitness/recreation) +"bkl" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bkm" = ( +/obj/machinery/door/airlock/public/glass, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"bkn" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"bko" = ( +/turf/open/floor/plasteel/vaporwave, +/area/commons/fitness/recreation) +"bkp" = ( +/obj/machinery/door/airlock/public/glass, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"bkq" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bkr" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bks" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bkt" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bku" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bkv" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bkw" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bkx" = ( +/obj/structure/mineral_door/wood, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main) +"bky" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bkz" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bkA" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/service/chapel/main) +"bkB" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Chapel" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main) +"bkC" = ( +/obj/machinery/camera{ + c_tag = "Holodeck" + }, +/obj/machinery/airalarm{ + pixel_y = 24 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bkD" = ( +/obj/machinery/vr_sleeper{ + dir = 1 + }, +/obj/structure/window/spawner/west, +/turf/open/floor/plasteel/vaporwave, +/area/commons/fitness/recreation) +"bkE" = ( +/turf/open/floor/engine{ + name = "Holodeck Projector Floor" + }, +/area/holodeck/rec_center) +"bkF" = ( +/turf/closed/festive/whitebrick{ + color = "#5496ff" + }, +/area/medical/genetics) +"bkG" = ( +/turf/closed/festive/whitebrick/whitebrickns{ + color = "#5496ff" + }, +/area/medical/genetics) +"bkH" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bkI" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bkJ" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bkK" = ( +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/machinery/door/airlock/research{ + name = "Genetics Lab"; + req_access_txt = "9" + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bkL" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/door/airlock/research{ + name = "Genetics Lab"; + req_access_txt = "9" + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bkM" = ( +/obj/structure/grille, +/obj/effect/spawner/structure/window, +/turf/open/floor/grass, +/area/medical/genetics) +"bkN" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/grass, +/area/medical/virology) +"bkO" = ( +/obj/structure/table/glass, +/obj/item/pen/red, +/obj/item/folder/white{ + pixel_y = 4 + }, +/obj/item/reagent_containers/glass/beaker, +/obj/item/reagent_containers/dropper, +/turf/open/floor/plasteel/freezer, +/area/medical/virology) +"bkP" = ( +/obj/item/bedsheet/medical, +/obj/structure/bed, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/medical/virology) +"bkQ" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/table/wood, +/obj/machinery/microwave{ + desc = "Cooks and boils stuff, somehow."; + pixel_x = -3; + pixel_y = 5 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bkR" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/table/wood, +/obj/item/storage/box/ingredients/wildcard, +/obj/item/storage/box/donkpockets, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bkS" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/table/wood, +/obj/item/reagent_containers/spray/cleaner{ + pixel_x = -3; + pixel_y = 2 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bkT" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/requests_console{ + department = "Virology Lab"; + name = "Virology RC"; + pixel_y = 32; + receive_ore_updates = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bkU" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bkV" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/power/apc/highcap/five_k{ + dir = 1; + name = "Virology APC"; + pixel_y = 24 + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bkW" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/light_switch{ + pixel_x = -4; + pixel_y = 24 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bkX" = ( +/obj/structure/table/glass, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"bkY" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/door/airlock/virology{ + name = "Virology Access"; + req_access_txt = "39" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bkZ" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bla" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"blb" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/doorButtons/access_button{ + dir = 1; + idDoor = "virology_airlock_exterior"; + idSelf = "virology_airlock_control"; + name = "Virology Access Button"; + pixel_x = 24; + pixel_y = -8; + req_access_txt = "39" + }, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"blc" = ( +/obj/structure/sink, +/turf/closed/festive/whitebrick{ + color = "#c1ff91" + }, +/area/medical/virology) +"bld" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/doorButtons/access_button{ + dir = 1; + idDoor = "virology_airlock_exterior"; + idSelf = "virology_airlock_control"; + name = "Virology Access Button"; + pixel_x = -24; + pixel_y = -8; + req_access_txt = "39" + }, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/obj/effect/landmark/start/virologist, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"ble" = ( +/obj/structure/closet/emcloset, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"blf" = ( +/obj/structure/closet/l3closet, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"blg" = ( +/obj/structure/closet/l3closet, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"blh" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bli" = ( +/turf/closed/wall/r_wall, +/area/command/heads_quarters/cmo) +"blj" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/door/poddoor/shutters{ + id = "CMOgarage"; + name = "CMO's Garage" + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/cmo) +"blk" = ( +/obj/machinery/vr_sleeper{ + dir = 1 + }, +/turf/open/floor/plasteel/vaporwave, +/area/commons/fitness/recreation) +"bll" = ( +/obj/machinery/vr_sleeper{ + dir = 1 + }, +/obj/structure/window/spawner/east, +/turf/open/floor/plasteel/vaporwave, +/area/commons/fitness/recreation) +"blm" = ( +/obj/structure/window/spawner/north, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"bln" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 9 + }, +/area/commons/fitness/recreation) +"blo" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/chair/stool/bar, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/commons/fitness/recreation) +"blp" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/chair/stool/bar, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/landmark/start/assistant, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/commons/fitness/recreation) +"blq" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/commons/fitness/recreation) +"blr" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/plasteel/dark/side{ + dir = 5 + }, +/area/commons/fitness/recreation) +"bls" = ( +/obj/machinery/vending/snack/teal, +/turf/open/floor/plasteel/dark, +/area/commons/fitness/recreation) +"blt" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"blu" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"blv" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/bar, +/obj/machinery/light, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, +/area/commons/fitness/recreation) +"blw" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/computer/arcade/orion_trail{ + dir = 1 + }, +/obj/structure/sign/poster/official/nanomichi_ad{ + pixel_y = -32 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"blx" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/computer/arcade/battle{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bly" = ( +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/effect/turf_decal/tile/bar, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"blz" = ( +/obj/structure/table/wood/fancy/red, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"blA" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/flashlight/lantern{ + pixel_y = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"blB" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"blC" = ( +/obj/structure/chair{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"blD" = ( +/turf/closed/festive/whitebrick/whitebrickwe{ + color = "#5496ff" + }, +/area/medical/genetics) +"blE" = ( +/obj/structure/table, +/obj/item/folder/white, +/obj/item/pen/fountain, +/obj/machinery/airalarm{ + pixel_y = 22 + }, +/obj/structure/extinguisher_cabinet{ + pixel_x = -26 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"blF" = ( +/obj/machinery/computer/scan_consolenew, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"blG" = ( +/obj/machinery/dna_scannernew, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"blH" = ( +/obj/structure/closet/secure_closet/medical1, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/item/clothing/shoes/winterboots, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"blI" = ( +/obj/structure/closet/secure_closet/personal/patient, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/power/apc{ + areastring = "/area/medical/genetics"; + dir = 1; + name = "Genetics APC"; + pixel_y = 24 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/obj/item/clothing/suit/hooded/wintercoat/genetics, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"blJ" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple, +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"blK" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"blL" = ( +/obj/structure/flora/junglebush, +/obj/structure/flora/ausbushes/sparsegrass, +/mob/living/carbon/monkey, +/turf/open/floor/grass, +/area/medical/genetics) +"blM" = ( +/obj/structure/flora/grass/jungle, +/obj/item/reagent_containers/food/snacks/grown/banana, +/turf/open/floor/grass, +/area/medical/genetics) +"blN" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"blO" = ( +/obj/structure/flora/ausbushes/lavendergrass, +/obj/structure/flora/ausbushes/sparsegrass, +/obj/structure/flora/ausbushes/fullgrass, +/obj/structure/flora/ausbushes/grassybush, +/obj/structure/flora/ausbushes/ppflowers, +/obj/structure/flora/ausbushes/pointybush, +/obj/structure/flora/junglebush, +/obj/structure/flora/junglebush/large, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/turf/open/floor/grass, +/area/medical/genetics) +"blP" = ( +/obj/structure/flora/junglebush/large, +/turf/open/floor/grass, +/area/medical/virology) +"blQ" = ( +/obj/structure/flora/grass/jungle, +/obj/structure/flora/ausbushes/brflowers, +/obj/structure/flora/ausbushes/ywflowers, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/grass, +/area/medical/virology) +"blR" = ( +/obj/structure/flora/grass/jungle, +/mob/living/carbon/monkey, +/turf/open/floor/grass, +/area/medical/virology) +"blS" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel/freezer, +/area/medical/virology) +"blT" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel/freezer, +/area/medical/virology) +"blU" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"blV" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"blW" = ( +/obj/effect/turf_decal/tile/green, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"blX" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/door/airlock/virology{ + name = "Virology Access"; + req_access_txt = "39" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"blY" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"blZ" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bma" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bmb" = ( +/obj/machinery/door/airlock/virology{ + autoclose = 0; + frequency = 1449; + id_tag = "virology_airlock_interior"; + name = "Virology Interior Airlock"; + req_access_txt = "39" + }, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bmc" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/machinery/doorButtons/airlock_controller{ + idExterior = "virology_airlock_exterior"; + idInterior = "virology_airlock_interior"; + idSelf = "virology_airlock_control"; + name = "Virology Access Console"; + pixel_x = 16; + pixel_y = -22; + req_access_txt = "39" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bmd" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bme" = ( +/obj/machinery/door/airlock/virology{ + autoclose = 0; + frequency = 1449; + id_tag = "virology_airlock_exterior"; + name = "Virology Exterior Airlock"; + req_access_txt = "39" + }, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bmf" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bmg" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/effect/landmark/start/virologist, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bmh" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bmi" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bmj" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/cmo) +"bmk" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/button/door{ + id = "CMOgarage"; + name = "CMO's Garage Door"; + pixel_x = 28 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/cmo) +"bml" = ( +/obj/structure/closet/crate/wooden, +/obj/item/stack/sheet/mineral/wood/fifty, +/turf/open/floor/festive/wooden/wooden2, +/area/command/heads_quarters/cmo) +"bmm" = ( +/obj/item/radio/intercom{ + pixel_y = 26 + }, +/obj/structure/closet/secure_closet/CMO, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/head/beret/cmo/blue, +/obj/item/clothing/suit/hooded/wintercoat/cmo, +/obj/item/key/CMO, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/festive/wooden/wooden2, +/area/command/heads_quarters/cmo) +"bmn" = ( +/obj/machinery/suit_storage_unit/cmo, +/turf/open/floor/carpet/royalblack, +/area/command/heads_quarters/cmo) +"bmo" = ( +/obj/structure/dresser, +/turf/open/floor/carpet/royalblack, +/area/command/heads_quarters/cmo) +"bmp" = ( +/obj/item/flashlight/lamp/green, +/obj/structure/table/wood, +/obj/item/reagent_containers/food/snacks/grown/tea/catnip, +/turf/open/floor/carpet/royalblack, +/area/command/heads_quarters/cmo) +"bmq" = ( +/turf/closed/wall/mineral/wood, +/area/command/heads_quarters/cmo) +"bmu" = ( +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/service/theater) +"bmv" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"bmw" = ( +/turf/closed/festive/creambrick, +/area/edina/crew_quarters/store/clothes) +"bmx" = ( +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/effect/turf_decal/tile/bar, +/obj/machinery/computer/arcade/battle{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bmy" = ( +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/effect/turf_decal/tile/bar, +/obj/machinery/computer/arcade/orion_trail{ + dir = 1 + }, +/obj/structure/sign/poster/contraband/pwr_game{ + pixel_y = -32 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bmz" = ( +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/light, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/commons/fitness/recreation) +"bmA" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Clothes and coats" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"bmB" = ( +/turf/closed/festive/greybrick/greybrickte, +/area/commons/fitness/recreation) +"bmC" = ( +/obj/machinery/door/airlock/wood, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bmD" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plasteel/elevatorshaft, +/area/commons/fitness/recreation) +"bmE" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Clothes and coats" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"bmF" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bmG" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"bmH" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/primary/perimeter) +"bmI" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bmJ" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bmK" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bmL" = ( +/obj/machinery/light/small, +/obj/machinery/power/apc{ + areastring = "/area/service/chapel/main/monastery"; + dir = 8; + name = "Chapel APC"; + pixel_y = -26 + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bmM" = ( +/obj/structure/chair/wood/wings{ + dir = 1 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bmN" = ( +/obj/machinery/newscaster{ + pixel_y = -32 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"bmO" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"bmP" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bmQ" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bmR" = ( +/obj/structure/table, +/obj/item/storage/box/disks, +/obj/item/flashlight/pen, +/obj/item/flashlight/pen, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bmS" = ( +/obj/structure/chair/stool, +/obj/effect/landmark/start/geneticist, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bmT" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bmU" = ( +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bmV" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bmW" = ( +/obj/structure/flora/grass/jungle/b, +/obj/structure/flora/ausbushes/ppflowers, +/obj/item/reagent_containers/food/snacks/grown/banana, +/obj/machinery/camera{ + c_tag = "Genetics Monkey Pen Fore"; + dir = 4; + network = list("ss13","medbay") + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/grass, +/area/medical/genetics) +"bmX" = ( +/obj/structure/sink/puddle, +/obj/structure/flora/ausbushes/reedbush{ + pixel_y = 6 + }, +/turf/open/floor/grass, +/area/medical/genetics) +"bmY" = ( +/obj/structure/flora/grass/jungle/b, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/mob/living/carbon/monkey, +/turf/open/floor/grass, +/area/medical/genetics) +"bmZ" = ( +/obj/structure/flora/junglebush/c, +/mob/living/carbon/monkey, +/turf/open/floor/grass, +/area/medical/virology) +"bna" = ( +/obj/structure/flora/junglebush, +/obj/structure/flora/ausbushes/brflowers, +/turf/open/floor/grass, +/area/medical/virology) +"bnb" = ( +/obj/item/reagent_containers/food/snacks/grown/banana, +/turf/open/floor/grass, +/area/medical/virology) +"bnc" = ( +/obj/effect/spawner/structure/window, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/freezer, +/area/medical/virology) +"bnd" = ( +/obj/machinery/door/airlock/virology/glass{ + name = "Isolation B"; + req_access_txt = "39" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/freezer, +/area/medical/virology) +"bne" = ( +/obj/machinery/door/airlock/virology/glass{ + name = "Isolation A"; + req_access_txt = "39" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/freezer, +/area/medical/virology) +"bnf" = ( +/obj/structure/extinguisher_cabinet, +/turf/closed/festive/whitebrick{ + color = "#c1ff91" + }, +/area/medical/virology) +"bng" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/window/reinforced, +/obj/structure/chair/wood/normal{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bnh" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/window/reinforced, +/obj/structure/table/wood, +/obj/item/clothing/head/beret/viro, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bni" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"bnj" = ( +/obj/machinery/biogenerator, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/dark, +/area/service/hydroponics) +"bnk" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/window/reinforced, +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bnl" = ( +/obj/effect/turf_decal/tile/green, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bnm" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bnn" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bno" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bnp" = ( +/obj/machinery/door/airlock/virology{ + name = "Virology Access"; + req_access_txt = "39" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bnq" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/door/airlock/virology{ + name = "Virology Access"; + req_access_txt = "39" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bnr" = ( +/obj/vehicle/sealed/vectorcraft/CMO{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/cmo) +"bns" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/cmo) +"bnt" = ( +/turf/open/floor/festive/wooden/wooden2, +/area/command/heads_quarters/cmo) +"bnu" = ( +/turf/open/floor/carpet/royalblack, +/area/command/heads_quarters/cmo) +"bnv" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"bnw" = ( +/turf/closed/festive/greybrick/greybrickcornernw, +/area/maintenance/bar) +"bnB" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSLeftEnd, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"bnD" = ( +/obj/structure/chair/sofa/corner{ + dir = 1 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bnE" = ( +/obj/structure/chair/stool/bar, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"bnF" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bnG" = ( +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bnH" = ( +/obj/structure/chair/comfy/black, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"bnJ" = ( +/turf/closed/festive/whitebrick, +/area/medical/cryo) +"bnM" = ( +/obj/structure/mirror{ + pixel_y = 30 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/edina/crew_quarters/store/clothes) +"bnN" = ( +/obj/structure/fireplace, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"bnO" = ( +/obj/structure/closet/crate/wooden, +/obj/item/stack/sheet/mineral/wood/fifty, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"bnP" = ( +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"bnQ" = ( +/obj/machinery/vending/clothing, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"bnR" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"bnS" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"bnT" = ( +/obj/structure/rack, +/obj/item/clothing/under/color/random, +/obj/item/clothing/under/color/random, +/obj/item/clothing/under/color/random, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"bnU" = ( +/obj/structure/window/fulltile, +/obj/effect/decal/festive/holly, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"bnV" = ( +/obj/effect/festive/street/streetlinenw, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bnW" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Holodeck Door" + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bnX" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bnY" = ( +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/miningoffice) +"bnZ" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/airlock/public/glass, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main) +"boa" = ( +/obj/effect/festive/street/sidewalkw, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bob" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/public/glass{ + name = "Holodeck Door" + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"boc" = ( +/obj/effect/festive/street/sidewalkwem, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bod" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWEMiddle, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"boe" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bof" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bog" = ( +/obj/machinery/door/window/eastleft{ + name = "Monkey Pen"; + req_one_access_txt = "9" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"boh" = ( +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/grass, +/area/medical/genetics) +"boi" = ( +/obj/structure/flora/junglebush, +/obj/structure/flora/grass/jungle/b, +/mob/living/simple_animal/butterfly, +/turf/open/floor/grass, +/area/medical/genetics) +"boj" = ( +/obj/item/toy/beach_ball, +/turf/open/floor/grass, +/area/medical/genetics) +"bok" = ( +/obj/structure/flora/grass/jungle/b, +/obj/structure/flora/ausbushes/ppflowers, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/turf/open/floor/grass, +/area/medical/genetics) +"bol" = ( +/obj/effect/festive/street/sidewalkn, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bom" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/engineering/glass{ + name = "Tool Shoppe" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"bon" = ( +/obj/effect/festive/street/sidewalke, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"boo" = ( +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/obj/machinery/power/apc{ + areastring = "/area/commons/storage/tools"; + dir = 8; + name = "Primary Tool Storage APC"; + pixel_x = -26; + pixel_y = 3 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"bop" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"boq" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/progcastaux) +"bor" = ( +/obj/structure/rack, +/obj/item/book/manual/wiki/engineering_hacking{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/book/manual/wiki/engineering_guide, +/obj/item/book/manual/wiki/engineering_construction{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"bos" = ( +/obj/structure/flora/grass/jungle/b, +/obj/machinery/camera{ + c_tag = "Genetics Monkey Pen Aft"; + dir = 4; + network = list("ss13","medbay") + }, +/obj/structure/flora/ausbushes/grassybush, +/obj/item/reagent_containers/food/snacks/grown/banana, +/turf/open/floor/grass, +/area/medical/virology) +"bot" = ( +/obj/structure/flora/ausbushes/ppflowers, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/mob/living/carbon/monkey, +/mob/living/carbon/monkey, +/turf/open/floor/grass, +/area/medical/virology) +"bou" = ( +/obj/structure/sink/puddle, +/turf/open/floor/grass, +/area/medical/virology) +"bov" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/window/eastleft{ + name = "Monkey Pen"; + req_one_access_txt = "9" + }, +/obj/structure/flora/grass/jungle, +/turf/open/floor/grass, +/area/medical/virology) +"bow" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"box" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"boy" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_y = 26 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"boz" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/disposal/bin{ + pixel_x = 5 + }, +/obj/structure/disposalpipe/trunk, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"boA" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"boB" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"boC" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"boD" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/turf/closed/festive/whitebrick{ + color = "#c1ff91" + }, +/area/medical/virology) +"boE" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"boF" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"boG" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"boH" = ( +/obj/structure/fireplace{ + dir = 4; + pixel_x = -7; + pixel_y = 10 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/command/heads_quarters/cmo) +"boI" = ( +/obj/structure/bed/dogbed/runtime, +/obj/item/toy/plush/random, +/turf/open/floor/carpet/royalblack, +/area/command/heads_quarters/cmo) +"boM" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"boN" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"boQ" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"boR" = ( +/turf/open/floor/festive/wooden/wooden2, +/area/edina/crew_quarters/store/clothes) +"boS" = ( +/obj/structure/curtain{ + color = "#FF5555" + }, +/turf/open/floor/festive/wooden/wooden2, +/area/edina/crew_quarters/store/clothes) +"boT" = ( +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"boV" = ( +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/qm) +"boX" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"boY" = ( +/obj/structure/rack, +/obj/item/storage/toolbox/emergency{ + pixel_x = 2; + pixel_y = -3 + }, +/obj/item/storage/toolbox/emergency, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"boZ" = ( +/obj/machinery/firealarm{ + pixel_y = 30 + }, +/obj/structure/ore_box, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bpa" = ( +/obj/structure/extinguisher_cabinet{ + dir = 4; + pixel_x = -5; + pixel_y = 27 + }, +/obj/structure/reagent_dispensers/fueltank, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bpb" = ( +/obj/structure/closet/emcloset, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bpc" = ( +/obj/structure/closet/crate, +/obj/item/flashlight{ + pixel_x = 1; + pixel_y = 5 + }, +/obj/item/flashlight{ + pixel_x = 1; + pixel_y = 5 + }, +/obj/item/stock_parts/cell/high{ + charge = 100; + maxcharge = 15000 + }, +/obj/item/stack/cable_coil{ + pixel_x = 3; + pixel_y = -7 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/item/radio/intercom{ + desc = "Talk smack through this."; + pixel_y = 28; + syndie = 1 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bpd" = ( +/obj/machinery/power/apc{ + areastring = "/area/cargo/miningoffice"; + dir = 1; + name = "Mining APC"; + pixel_y = 24 + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/obj/machinery/light_switch{ + pixel_y = 38 + }, +/obj/structure/closet/wardrobe/miner, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bpe" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/item/radio/intercom{ + dir = 4; + name = "Station Intercom (General)"; + pixel_x = 27 + }, +/obj/structure/reagent_dispensers/water_cooler, +/obj/effect/turf_decal/tile/brown, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bpf" = ( +/obj/structure/musician/piano{ + icon_state = "piano" + }, +/obj/machinery/light/small, +/turf/open/indestructible{ + icon_state = "chapel" + }, +/area/service/chapel/main/monastery) +"bpg" = ( +/obj/machinery/door/airlock/wood, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bpi" = ( +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/machinery/disposal/bin, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bpj" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bpk" = ( +/obj/structure/extinguisher_cabinet{ + pixel_y = 32 + }, +/obj/structure/chair/wood/wings, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bpl" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bpm" = ( +/obj/machinery/door/airlock/wood, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bpn" = ( +/obj/machinery/computer/holodeck{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bpo" = ( +/obj/structure/table, +/obj/item/clothing/gloves/color/latex, +/obj/item/clothing/gloves/color/latex, +/obj/item/storage/box/monkeycubes, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/machinery/light{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bpp" = ( +/obj/machinery/holopad, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bpq" = ( +/obj/machinery/vending/wardrobe/gene_wardrobe, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/light, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bpr" = ( +/obj/machinery/light_switch{ + pixel_y = -26 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bps" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bpt" = ( +/obj/structure/flora/ausbushes/palebush, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/grass, +/area/medical/genetics) +"bpu" = ( +/obj/structure/flora/ausbushes/brflowers, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/mob/living/carbon/monkey, +/turf/open/floor/grass, +/area/medical/genetics) +"bpv" = ( +/obj/machinery/light/small, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/grass, +/area/medical/genetics) +"bpw" = ( +/obj/structure/flora/junglebush, +/obj/structure/flora/ausbushes/sunnybush, +/obj/item/reagent_containers/food/snacks/grown/banana, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/mob/living/carbon/monkey, +/turf/open/floor/grass, +/area/medical/genetics) +"bpx" = ( +/obj/structure/flora/ausbushes/sparsegrass, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/mob/living/carbon/monkey, +/turf/open/floor/grass, +/area/medical/virology) +"bpy" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/machinery/light/small, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/grass, +/area/medical/virology) +"bpz" = ( +/obj/structure/flora/ausbushes/brflowers, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/grass, +/area/medical/virology) +"bpA" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/window/eastleft{ + name = "Monkey Pen"; + req_one_access_txt = "9" + }, +/obj/structure/flora/ausbushes/ppflowers, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/grass, +/area/medical/virology) +"bpB" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/light{ + light_color = "#c9d3e8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bpC" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bpD" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bpE" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bpF" = ( +/obj/machinery/holopad, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bpG" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bpH" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bpI" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bpJ" = ( +/obj/machinery/newscaster{ + pixel_x = 32 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bpK" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick{ + color = "#c1ff91" + }, +/area/medical/virology) +"bpL" = ( +/obj/structure/closet/cabinet{ + pixel_y = 15 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/medical/virology) +"bpM" = ( +/obj/structure/dresser, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/medical/virology) +"bpN" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bpO" = ( +/obj/structure/fluff/lightpost/light, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bpP" = ( +/turf/open/floor/plasteel, +/area/medical/chemistry) +"bpQ" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bpR" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bpS" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bpT" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/fluff/lightpost/light, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bpU" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bpV" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bpW" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/command/heads_quarters/cmo) +"bpX" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/command/heads_quarters/cmo) +"bpY" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/door/airlock/command{ + name = "Chief Medical Officer's Office"; + req_access_txt = "40" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/cmo) +"bpZ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall/mineral/wood, +/area/command/heads_quarters/cmo) +"bqa" = ( +/obj/structure/mineral_door/wood, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/holofloor/wood, +/area/command/heads_quarters/cmo) +"bqb" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/edina) +"bqf" = ( +/obj/structure/fireplace{ + dir = 8; + pixel_x = -24; + pixel_y = 26 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bqg" = ( +/obj/structure/fireplace{ + dir = 4; + pixel_x = -7; + pixel_y = 26 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bqh" = ( +/obj/machinery/newscaster{ + pixel_x = -32 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"bqi" = ( +/obj/structure/table/glass, +/obj/item/clothing/neck/petcollar/choker, +/obj/item/clothing/neck/petcollar/choker, +/obj/item/clothing/neck/petcollar/choker, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"bqj" = ( +/turf/closed/festive/whitebrick{ + color = "#ff9b8a" + }, +/area/edina/crew_quarters/store/pet) +"bqk" = ( +/obj/structure/table/glass, +/obj/item/clothing/neck/cloak/polychromic/polyce, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"bql" = ( +/obj/structure/rack, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"bqm" = ( +/obj/structure/noticeboard{ + name = "Clothes and coats" + }, +/obj/item/clothing/suit/hooded/wintercoat/cosmic{ + anchored = 1; + name = "Clothes and Coats" + }, +/turf/closed/festive/creambrick, +/area/edina/crew_quarters/store/clothes) +"bqn" = ( +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bqo" = ( +/obj/machinery/door/airlock/wood, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bqp" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bqt" = ( +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"bqv" = ( +/obj/machinery/vending/hydroseeds{ + slogan_delay = 700 + }, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/dark, +/area/service/hydroponics) +"bqw" = ( +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bqx" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bqy" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bqz" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/computer/shuttle/mining{ + dir = 8 + }, +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bqA" = ( +/turf/closed/wall/mineral/iron, +/area/service/chapel/main/monastery) +"bqB" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bqC" = ( +/obj/machinery/light/small, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 8 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bqD" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 9 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bqE" = ( +/obj/structure/closet/secure_closet/freezer/fridge, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bqF" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 5 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bqG" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/structure/table/wood, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bqH" = ( +/obj/effect/spawner/structure/window/reinforced/indestructable, +/turf/open/floor/plating, +/area/service/chapel/main/monastery) +"bqI" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile2, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bqJ" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bqK" = ( +/obj/structure/table, +/obj/item/paper/fluff/holodeck/disclaimer, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"bqL" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bqM" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bqN" = ( +/obj/machinery/shower{ + dir = 8 + }, +/obj/machinery/requests_console{ + department = "Genetics"; + name = "Genetics Requests Console"; + pixel_x = 32 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bqO" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/closed/festive/whitebrick{ + color = "#5496ff" + }, +/area/medical/genetics) +"bqP" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/closed/festive/whitebrick{ + color = "#5496ff" + }, +/area/medical/genetics) +"bqQ" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/research{ + name = "Genetics Lab"; + req_access_txt = "9" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bqR" = ( +/turf/closed/festive/whitebrick, +/area/medical/storage) +"bqS" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/research{ + name = "Genetics Lab"; + req_access_txt = "9" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bqT" = ( +/obj/structure/grille, +/obj/effect/spawner/structure/window, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/grass, +/area/medical/genetics) +"bqU" = ( +/obj/structure/grille, +/obj/effect/spawner/structure/window, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/grass, +/area/medical/genetics) +"bqV" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/grass, +/area/medical/virology) +"bqW" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/grass, +/area/medical/virology) +"bqX" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/closed/festive/whitebrick{ + color = "#c1ff91" + }, +/area/medical/virology) +"bqY" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bqZ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bra" = ( +/obj/structure/chair/office/light, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"brb" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"brc" = ( +/obj/machinery/holopad, +/obj/structure/disposalpipe/junction{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"brd" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bre" = ( +/obj/structure/mineral_door/wood, +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/green, +/area/medical/virology) +"brf" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/green, +/area/medical/virology) +"brg" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/structure/bed, +/obj/item/bedsheet/green, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/green, +/area/medical/virology) +"brh" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/festive/whitebrick{ + color = "#c1ff91" + }, +/area/medical/virology) +"bri" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"brj" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"brk" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/festive/whitebrick/whitebrickcornernw, +/area/medical/medbay/lobby) +"brl" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"brm" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"brn" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bro" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/festive/whitebrick, +/area/medical/medbay/lobby) +"brp" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/festive/whitebrick, +/area/medical/medbay/lobby) +"brq" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/festive/whitebrick, +/area/medical/medbay/lobby) +"brr" = ( +/obj/structure/disposalpipe/junction{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/festive/whitebrick, +/area/medical/medbay/lobby) +"brs" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"brt" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/noticeboard/cmo, +/turf/closed/festive/bluebrick, +/area/command/heads_quarters/cmo) +"bru" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/table/glass, +/obj/item/storage/firstaid/regular, +/obj/machinery/light{ + dir = 8 + }, +/obj/item/storage/secure/briefcase, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/junction{ + dir = 4 + }, +/obj/machinery/power/apc/auto_name/west, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"brv" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"brw" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/fireplace{ + pixel_x = 0 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"brx" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"bry" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/requests_console{ + announcementConsole = 1; + department = "Chief Medical Officer's Desk"; + departmentType = 5; + name = "Chief Medical Officer's RC"; + pixel_y = 30 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/filingcabinet/chestdrawer, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"brz" = ( +/obj/structure/table/glass, +/obj/item/folder/blue, +/obj/item/cartridge/medical{ + pixel_x = -3 + }, +/obj/item/cartridge/medical{ + pixel_x = 3 + }, +/obj/item/cartridge/chemistry{ + pixel_y = 6 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/item/radio/intercom{ + pixel_y = 26 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"brA" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/bed/dogbed/runtime, +/obj/machinery/light{ + dir = 1; + light_color = "#e8eaff" + }, +/obj/machinery/firealarm{ + pixel_y = 26 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/mob/living/simple_animal/pet/cat/Runtime, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"brB" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/wall/mineral/wood, +/area/command/heads_quarters/cmo) +"brC" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/festive/whitebrick, +/area/edina) +"brI" = ( +/obj/machinery/door/airlock/silver/glass, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"brJ" = ( +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"brK" = ( +/obj/effect/festive/trainrails/north{ + icon_state = "trainrails_west" + }, +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"brL" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"brM" = ( +/obj/effect/festive/trainrails/north{ + icon_state = "trainrails_east" + }, +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"brN" = ( +/obj/structure/chair/wood/normal, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"brO" = ( +/obj/structure/mirror{ + pixel_y = 30 + }, +/obj/item/clothing/suit/ran, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/edina/crew_quarters/store/clothes) +"brP" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = -36 + }, +/obj/machinery/light_switch{ + pixel_x = -26 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"brR" = ( +/obj/structure/table/glass, +/obj/item/clothing/neck/scarf/purple, +/obj/item/clothing/neck/scarf/purple, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"brT" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Clothes and coats" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"brU" = ( +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"brV" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8; + pixel_y = -5 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"brW" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"brX" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"brY" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile1, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"brZ" = ( +/obj/effect/festive/street/sidewalks, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"bsa" = ( +/turf/closed/festive/greypanel/greypanelcornersw, +/area/commons/fitness/recreation) +"bsb" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"bsc" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bsd" = ( +/obj/structure/reagent_dispensers/watertank/high, +/obj/item/reagent_containers/glass/bucket, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bsg" = ( +/obj/machinery/camera{ + c_tag = "Mining Office"; + dir = 8 + }, +/obj/machinery/mineral/equipment_vendor, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bsh" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/holopad, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bsi" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bsj" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/cargo/miningoffice) +"bsk" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/item/clothing/gloves/color/black, +/obj/item/clothing/shoes/combat/coldres, +/obj/item/nullrod, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/chaplain/nun, +/obj/item/clothing/suit/chaplain/holidaypriest, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bsl" = ( +/obj/structure/dresser, +/obj/machinery/airalarm{ + pixel_y = 22 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bsm" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/obj/item/storage/firstaid, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bsn" = ( +/obj/item/bedsheet/chaplain/double, +/obj/structure/bed/double, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bso" = ( +/obj/structure/fence/corner{ + dir = 4 + }, +/turf/open/floor/grass/snow/edina, +/area/edina/street/primary/progress) +"bsp" = ( +/obj/machinery/light/small, +/turf/open/floor/carpet/black, +/area/commons/dorms) +"bsq" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -23 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bsr" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bss" = ( +/obj/structure/sink/kitchen{ + dir = 8; + pixel_x = 12 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bst" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/sign/directions/supply{ + pixel_x = -32; + pixel_y = -32 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"bsu" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bsv" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bsw" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bsx" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/fulltile{ + max_integrity = 5000; + name = "hardened window"; + obj_integrity = 5000 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bsy" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/grass/snow/edina, +/area/medical/medbay/aft) +"bsz" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bsA" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bsB" = ( +/obj/structure/flora/tree/pine/xmas, +/turf/open/floor/grass/snow/edina, +/area/medical/medbay/aft) +"bsC" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/closed/festive/whitebrick{ + color = "#c1ff91" + }, +/area/medical/virology) +"bsD" = ( +/obj/structure/reagent_dispensers/virusfood{ + pixel_x = -32 + }, +/obj/structure/table/glass, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/reagentgrinder{ + desc = "Used to grind things up into raw materials and liquids."; + pixel_y = 5 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/medical/virology) +"bsE" = ( +/obj/machinery/smartfridge/chemistry/virology/preloaded, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/medical/virology) +"bsF" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/structure/table/glass, +/obj/item/stack/sheet/mineral/plasma{ + amount = 5 + }, +/obj/item/book/manual/wiki/infections, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bsG" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/computer/pandemic, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bsH" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/structure/table/reinforced, +/obj/item/storage/box/syringes, +/obj/item/storage/box/beakers{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bsI" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/structure/table/reinforced, +/obj/item/reagent_containers/syringe/antiviral, +/obj/item/reagent_containers/dropper, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bsJ" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/structure/table/reinforced, +/obj/item/paper_bin, +/obj/item/flashlight/pen, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bsK" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/structure/table/reinforced, +/obj/item/healthanalyzer, +/obj/item/clothing/glasses/hud/health, +/obj/machinery/button/door{ + id = "detectivewindows"; + name = "Privacy Shutters"; + pixel_x = 26; + pixel_y = -26; + req_access_txt = "4" + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bsL" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/structure/closet/secure_closet/medical1, +/obj/machinery/light{ + light_color = "#c9d3e8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bsM" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/structure/closet/l3closet/virology, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bsN" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/structure/closet/crate/freezer/blood, +/obj/machinery/iv_drip, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bsO" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick{ + color = "#c1ff91" + }, +/area/medical/virology) +"bsP" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/medical/virology) +"bsQ" = ( +/obj/structure/table/wood, +/obj/item/toy/plush/dr_scanny, +/obj/item/flashlight/lamp/green, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/medical/virology) +"bsR" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick{ + color = "#c1ff91" + }, +/area/medical/virology) +"bsS" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bsT" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bsU" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bsV" = ( +/obj/machinery/vending/coffee, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bsW" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/decal/festive/green_stockings, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bsX" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/camera{ + c_tag = "Medbay - Break Room"; + name = "medbay camera"; + network = list("ss13","medbay") + }, +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/flora/tree/pine/xmas, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bsY" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/table/wood, +/obj/machinery/microwave{ + desc = "Cooks and boils stuff, somehow."; + pixel_x = -3; + pixel_y = 5 + }, +/obj/machinery/firealarm{ + pixel_y = 26 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/medical/medbay/lobby) +"bsZ" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/obj/structure/table/wood, +/obj/item/storage/box/donkpockets, +/obj/item/storage/box/ingredients/wildcard, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/medical/medbay/lobby) +"bta" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/vending/snack/random, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/medical/medbay/lobby) +"btb" = ( +/obj/machinery/disposal/bin, +/obj/machinery/camera{ + c_tag = "MiniSat Exterior - Port Fore"; + dir = 8; + network = list("minisat") + }, +/obj/machinery/status_display/ai{ + pixel_x = 32 + }, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"btc" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/medical/medbay/lobby) +"btd" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bte" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/bluebrick/bluebrickwe, +/area/command/heads_quarters/cmo) +"btf" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/plating/dirt{ + initial_gas_mix = "o2=21.78;n2=82.36;TEMP=293.15" + }, +/area/edina) +"btg" = ( +/turf/open/floor/plating/dirt{ + initial_gas_mix = "o2=21.78;n2=82.36;TEMP=293.15" + }, +/area/edina) +"bth" = ( +/obj/structure/streetdecor/lampfestive, +/turf/open/floor/festive/sidewalk, +/area/edina) +"bti" = ( +/obj/structure/table/glass, +/obj/item/folder/white, +/obj/item/flashlight/pen, +/obj/item/clothing/neck/stethoscope, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -23 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"btj" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"btk" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"btl" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"btm" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"btn" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/item/toy/cattoy, +/obj/machinery/computer/security/telescreen/cmo{ + dir = 8; + pixel_x = 30 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"bto" = ( +/turf/closed/festive/bluebrick, +/area/command/heads_quarters/cmo) +"btt" = ( +/obj/structure/closet/cabinet{ + pixel_y = 15 + }, +/turf/open/floor/carpet/black, +/area/commons/dorms) +"btu" = ( +/obj/structure/table/reinforced, +/obj/machinery/microwave{ + desc = "Cooks and boils stuff, somehow."; + pixel_y = 8 + }, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"btv" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"btw" = ( +/obj/structure/table/wood, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"btx" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/holopad, +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"bty" = ( +/mob/living/simple_animal/pet/penguin/baby, +/turf/open/floor/holofloor/ice, +/area/edina/crew_quarters/store/pet) +"btz" = ( +/obj/structure/table/glass, +/obj/item/clothing/neck/scarf/pink, +/obj/item/clothing/neck/scarf/pink, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"btA" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/carpet/red, +/area/service/bar) +"btB" = ( +/obj/structure/table/wood, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel/dark, +/area/service/bar) +"btC" = ( +/obj/structure/chair/stool, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"btD" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"btE" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/sign/departments/botany{ + pixel_x = 32; + pixel_y = -32 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"btF" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/red, +/area/service/bar) +"btG" = ( +/obj/effect/festive/street/streetlinene, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"btK" = ( +/obj/structure/closet/secure_closet/miner, +/obj/item/clothing/suit/hooded/wintercoat/miner, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"btL" = ( +/obj/effect/landmark/start/shaft_miner, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"btM" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"btN" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/landmark/event_spawn, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"btO" = ( +/obj/machinery/door/airlock/external{ + name = "Mining Dock Airlock"; + req_access_txt = "48" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/turf/open/floor/plating, +/area/cargo/miningoffice) +"btP" = ( +/turf/open/floor/plating, +/area/cargo/miningoffice) +"btQ" = ( +/obj/machinery/door/airlock/external{ + name = "Mining Dock Airlock"; + req_access_txt = "48" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/turf/open/floor/plating, +/area/cargo/miningoffice) +"btR" = ( +/obj/structure/curtain, +/obj/effect/spawner/structure/window/reinforced/indestructable, +/turf/open/floor/plating, +/area/service/chapel/main/monastery) +"btS" = ( +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"btT" = ( +/obj/effect/landmark/start/chaplain, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"btU" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"btV" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"btW" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/extinguisher_cabinet{ + pixel_y = 32 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"btX" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/newscaster{ + pixel_y = 32 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"btY" = ( +/obj/structure/chair/sofa/right, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/landmark/start/chaplain, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"btZ" = ( +/obj/structure/chair/sofa, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"bua" = ( +/obj/structure/chair/sofa/left, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/airalarm{ + pixel_y = 22 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"bub" = ( +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/machinery/power/apc{ + areastring = "/area/service/chapel/main/monastery"; + dir = 1; + name = "Chaplain's Quarters APC"; + pixel_y = 24 + }, +/obj/structure/table/wood, +/obj/item/book/granter/spell/smoke/lesser{ + pixel_y = 2 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"buc" = ( +/obj/structure/bookcase/random/religion, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"bud" = ( +/obj/structure/curtain, +/obj/machinery/shower{ + pixel_y = 16 + }, +/obj/item/soap/deluxe, +/turf/open/indestructible/hoteltile, +/area/service/chapel/main/monastery) +"bue" = ( +/obj/structure/table/wood, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/obj/machinery/power/apc{ + areastring = "/area/service/chapel/main/monastery"; + dir = 8; + name = "Chapel Kitchen APC"; + pixel_x = -26 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"buf" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bug" = ( +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"buh" = ( +/obj/machinery/door/airlock/research/glass{ + name = "Circuitry Lab"; + req_access_txt = "47" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/science/circuit) +"bui" = ( +/obj/structure/chair/stool, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"buj" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"buk" = ( +/obj/structure/table, +/obj/item/reagent_containers/glass/beaker, +/obj/item/reagent_containers/dropper, +/obj/item/storage/pill_bottle/mutadone, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bul" = ( +/obj/structure/chair/stool, +/obj/effect/landmark/start/geneticist, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bum" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bun" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"buo" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "geneticsdesk"; + name = "Genetics Desk Shutters" + }, +/obj/machinery/door/window/westright{ + dir = 4; + name = "Genetics Desk"; + req_access_txt = "9" + }, +/obj/machinery/door/window/westright{ + name = "Genetics Desk" + }, +/obj/item/folder/white, +/obj/item/pen/fountain, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bup" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"buq" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bur" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bus" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"but" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"buu" = ( +/obj/machinery/vending/cola/random, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"buv" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"buw" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/medical/medbay/lobby) +"bux" = ( +/obj/effect/landmark/start/medical_doctor, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/medical/medbay/lobby) +"buy" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"buz" = ( +/turf/closed/festive/whitebrick/whitebrickwe, +/area/medical/medbay/lobby) +"buA" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/fulltile{ + max_integrity = 5000; + name = "hardened window"; + obj_integrity = 5000 + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "cmoshutter"; + name = "CMO Office Shutters" + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"buB" = ( +/obj/structure/table/wood, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/light, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/service/bar) +"buC" = ( +/turf/open/floor/carpet/blue, +/area/command/heads_quarters/cmo) +"buD" = ( +/obj/structure/table/wood/fancy/royalblue, +/obj/item/clothing/glasses/hud/health, +/turf/open/floor/carpet/blue, +/area/command/heads_quarters/cmo) +"buE" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"buF" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/blue, +/area/command/heads_quarters/cmo) +"buG" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/computer/crew{ + dir = 8 + }, +/obj/machinery/status_display/ai{ + pixel_x = 32 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"buH" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/bluebrick, +/area/command/heads_quarters/cmo) +"buI" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/edina) +"buL" = ( +/obj/structure/bed, +/obj/item/bedsheet/random, +/turf/open/floor/carpet/black, +/area/commons/dorms) +"buM" = ( +/obj/structure/chair/wood/normal{ + dir = 1 + }, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"buN" = ( +/obj/machinery/power/apc/auto_name/west, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"buO" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"buP" = ( +/obj/structure/festive/trainplatform/edge_north, +/turf/open/floor/grass/snow/edina, +/area/edina) +"buQ" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8; + pixel_y = -5 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"buR" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/item/clothing/gloves/mittens/random, +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"buS" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"buT" = ( +/obj/structure/disposalpipe/junction/flip{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/red, +/area/service/bar) +"buV" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"buW" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"buX" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"buY" = ( +/obj/effect/landmark/start/cook, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"buZ" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bva" = ( +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -23 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"bvb" = ( +/obj/structure/closet/secure_closet/miner, +/obj/item/clothing/suit/hooded/wintercoat/miner, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bvc" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/obj/effect/landmark/start/shaft_miner, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bvd" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bve" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bvf" = ( +/obj/structure/table/wood, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/item/storage/book/bible{ + pixel_x = 4; + pixel_y = 4 + }, +/obj/item/radio{ + pixel_x = -8; + pixel_y = 6 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bvg" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 8 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bvh" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/carpet{ + icon_state = "carpetsymbol" + }, +/area/service/chapel/main/monastery) +"bvi" = ( +/obj/machinery/door/airlock/wood, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"bvj" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"bvk" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"bvl" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"bvm" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"bvn" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/service/chapel/main/monastery) +"bvo" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"bvp" = ( +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"bvq" = ( +/obj/machinery/door/airlock/wood, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"bvr" = ( +/obj/structure/mirror{ + pixel_x = 28 + }, +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/turf/open/indestructible/hoteltile, +/area/service/chapel/main/monastery) +"bvs" = ( +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bvt" = ( +/obj/structure/table/wood, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bvu" = ( +/obj/structure/table/wood, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bvv" = ( +/obj/structure/table/wood, +/obj/machinery/microwave{ + pixel_y = 8 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/service/chapel/main/monastery) +"bvw" = ( +/obj/structure/table, +/obj/item/pen/fountain, +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_x = -27 + }, +/obj/item/paper_bin{ + layer = 2.9 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bvx" = ( +/obj/machinery/computer/scan_consolenew{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bvy" = ( +/obj/machinery/dna_scannernew, +/obj/machinery/camera{ + c_tag = "Genetics"; + dir = 1; + network = list("ss13","medbay") + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bvz" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bvA" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/fulltile{ + max_integrity = 5000; + name = "hardened window"; + obj_integrity = 5000 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bvB" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bvC" = ( +/obj/structure/fluff/lightpost/light, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bvD" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/fluff/lightpost/light, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bvE" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bvF" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bvG" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/decal/festive/fairylights, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bvH" = ( +/obj/machinery/newscaster{ + pixel_x = -32 + }, +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bvI" = ( +/obj/machinery/holopad, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bvJ" = ( +/obj/structure/chair/wood/normal{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bvK" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/spray/cleaner{ + pixel_x = -3; + pixel_y = 2 + }, +/obj/item/folder/white, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bvL" = ( +/obj/structure/table/wood, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/item/clothing/head/beret/med, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bvM" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bvN" = ( +/obj/machinery/newscaster{ + pixel_x = 32 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bvO" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bvP" = ( +/obj/machinery/door/airlock/command{ + name = "Chief Medical Officer's Office"; + req_access_txt = "40" + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"bvQ" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"bvR" = ( +/obj/machinery/holopad, +/turf/open/floor/carpet/blue, +/area/command/heads_quarters/cmo) +"bvS" = ( +/obj/structure/chair/wood/wings{ + dir = 4 + }, +/turf/open/floor/carpet/blue, +/area/command/heads_quarters/cmo) +"bvT" = ( +/obj/structure/table/wood/fancy/royalblue, +/obj/item/clipboard, +/obj/item/toy/figure/cmo, +/obj/item/stamp/cmo, +/turf/open/floor/carpet/blue, +/area/command/heads_quarters/cmo) +"bvU" = ( +/turf/open/floor/festive/trainplatform, +/area/edina/street/primary/perimeter) +"bvV" = ( +/obj/effect/festive/street/streetlinewest, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bvW" = ( +/obj/machinery/newscaster{ + pixel_x = 32 + }, +/turf/open/floor/carpet/blue, +/area/command/heads_quarters/cmo) +"bvX" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/rd) +"bvY" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/computer/card/minor/cmo{ + dir = 8 + }, +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/newscaster{ + pixel_x = 32 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"bwb" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"bwc" = ( +/obj/machinery/door/airlock/silver/glass, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"bwd" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/condiment/enzyme{ + layer = 5; + pixel_x = -4 + }, +/obj/item/storage/box/donkpockets, +/obj/item/reagent_containers/rag/towel, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bwe" = ( +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -24 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"bwf" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"bwg" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"bwh" = ( +/obj/structure/rack, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"bwi" = ( +/obj/structure/table, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bwk" = ( +/turf/open/floor/festive/cobblestone/safe, +/area/cargo/qm) +"bwl" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Quartermaster"; + req_access_txt = "41" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"bwn" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Quartermaster"; + req_access_txt = "41" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"bwo" = ( +/obj/structure/closet/secure_closet/miner, +/obj/item/clothing/suit/hooded/wintercoat/miner, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bwp" = ( +/obj/structure/table, +/obj/item/folder/yellow, +/obj/item/pen, +/obj/machinery/requests_console{ + department = "Mining"; + pixel_y = -30 + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bwq" = ( +/obj/structure/table, +/obj/item/paper_bin{ + pixel_x = -3; + pixel_y = 7 + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/item/stack/medical/bruise_pack, +/obj/item/stack/medical/ointment, +/obj/item/stack/medical/gauze, +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bwr" = ( +/obj/structure/rack, +/obj/item/pickaxe{ + pixel_x = 5 + }, +/obj/item/shovel{ + pixel_x = -5 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bws" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/machinery/computer/security/mining{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bwt" = ( +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/obj/machinery/disposal/bin, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"bwu" = ( +/obj/structure/table/wood, +/obj/item/storage/fancy/candle_box{ + pixel_y = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"bwv" = ( +/turf/open/floor/carpet/green, +/area/service/chapel/main/monastery) +"bww" = ( +/obj/structure/mineral_door/wood, +/turf/open/floor/wood, +/area/command/heads_quarters/ce) +"bwx" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bwy" = ( +/obj/structure/toilet{ + dir = 8 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/indestructible/hoteltile, +/area/service/chapel/main/monastery) +"bwz" = ( +/obj/machinery/door/airlock/titanium{ + name = "Kitchen"; + req_one_access_txt = "25;26;28;35" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bwA" = ( +/turf/closed/festive/whitebrick/whitebrickcornersw{ + color = "#5496ff" + }, +/area/medical/genetics) +"bwB" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeft, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bwC" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/research{ + name = "Genetics Lab"; + req_access_txt = "9" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bwD" = ( +/turf/closed/wall/mineral/wood, +/area/medical/surgery) +"bwE" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/carpet/green, +/area/medical/surgery) +"bwF" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bwG" = ( +/obj/structure/sign/poster/official/help_others{ + pixel_x = -32 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bwH" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bwI" = ( +/obj/structure/table/wood, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bwJ" = ( +/obj/structure/table/wood, +/obj/item/paper_bin, +/obj/item/pen/fountain, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bwK" = ( +/obj/effect/festive/street/sidewalkn, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bwL" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/button/door{ + id = "cmoshutter"; + name = "CMO Office Shutters"; + pixel_x = 7; + pixel_y = -26; + req_access_txt = "40" + }, +/obj/machinery/light_switch{ + pixel_x = -7; + pixel_y = -26 + }, +/obj/machinery/disposal/bin{ + pixel_x = 5 + }, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"bwM" = ( +/obj/structure/table/wood/fancy/royalblue, +/obj/item/paper_bin, +/obj/item/pen/fountain, +/turf/open/floor/carpet/blue, +/area/command/heads_quarters/cmo) +"bwN" = ( +/obj/structure/table/wood/fancy/royalblue, +/obj/item/flashlight/lamp, +/turf/open/floor/carpet/blue, +/area/command/heads_quarters/cmo) +"bwO" = ( +/obj/structure/table/wood/fancy/royalblue, +/obj/machinery/computer/med_data/laptop{ + dir = 1 + }, +/turf/open/floor/carpet/blue, +/area/command/heads_quarters/cmo) +"bwP" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/table/wood/fancy/royalblue, +/obj/item/folder/blue{ + pixel_x = 6; + pixel_y = 6 + }, +/obj/item/folder/white, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"bwU" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"bwV" = ( +/obj/structure/toilet{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/commons/dorms) +"bwW" = ( +/obj/machinery/shower{ + dir = 8 + }, +/obj/structure/curtain, +/turf/open/floor/plasteel/freezer, +/area/commons/dorms) +"bwY" = ( +/obj/structure/rack, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/machinery/light, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"bxa" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bxb" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bxc" = ( +/obj/machinery/door/airlock/freezer{ + name = "Freezer"; + req_one_access_txt = "25;26;28;35" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bxd" = ( +/obj/effect/festive/street/streetlinenw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bxf" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = -24 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"bxg" = ( +/obj/machinery/light{ + light_color = "#c9d3e8" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"bxi" = ( +/obj/structure/closet/crate/wooden, +/obj/item/stack/sheet/mineral/wood/fifty, +/obj/effect/decal/festive/large_red_stocking, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bxk" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/mining/glass, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"bxl" = ( +/obj/structure/fence, +/turf/open/floor/grass/snow/edina, +/area/medical/medbay/aft) +"bxm" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/medical/medbay/aft) +"bxn" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/obj/structure/chair/pew/left, +/turf/open/floor/carpet/green, +/area/medical/surgery) +"bxo" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/obj/structure/chair/pew, +/turf/open/floor/carpet/green, +/area/medical/surgery) +"bxp" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/carpet/green, +/area/medical/surgery) +"bxq" = ( +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bxr" = ( +/obj/effect/festive/street/streetlineeast, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bxs" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"bxt" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bxu" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/carpet/green, +/area/medical/surgery) +"bxv" = ( +/obj/machinery/door/airlock/medical{ + name = "Observation" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/carpet/green, +/area/medical/surgery) +"bxw" = ( +/turf/closed/festive/whitebrick/whitebrickns, +/area/medical/exam_room) +"bxx" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/medical/exam_room) +"bxy" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/medical/exam_room) +"bxz" = ( +/turf/closed/festive/whitebrick/whitebrickcornerne, +/area/medical/exam_room) +"bxA" = ( +/turf/closed/festive/whitebrick/whitebrickcornernw, +/area/medical/medbay/lobby) +"bxB" = ( +/obj/effect/decal/festive/fairylights, +/turf/closed/festive/whitebrick, +/area/medical/medbay/lobby) +"bxC" = ( +/obj/effect/landmark/start/roboticist, +/turf/open/floor/plasteel/white, +/area/science/robotics/lab) +"bxD" = ( +/obj/machinery/door/airlock/medical/glass{ + id_tag = "MedbayFoyer"; + name = "Medbay"; + req_access_txt = "5" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bxE" = ( +/obj/structure/extinguisher_cabinet{ + dir = 4; + pixel_y = -27 + }, +/obj/structure/extinguisher_cabinet{ + dir = 4; + pixel_y = -27 + }, +/obj/structure/extinguisher_cabinet, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/festive/whitebrick, +/area/medical/medbay/lobby) +"bxF" = ( +/turf/closed/festive/whitebrick/whitebrickns, +/area/medical/medbay/lobby) +"bxG" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bxH" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bxI" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"bxJ" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bxK" = ( +/obj/structure/sign/departments/medbay/alt, +/turf/closed/festive/whitebrick/whitebrickcornerse, +/area/medical/medbay/lobby) +"bxL" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/fence{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bxM" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/fence/door/opened, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bxN" = ( +/turf/closed/festive/bluebrick/bluebrickcornersw, +/area/command/heads_quarters/cmo) +"bxO" = ( +/obj/structure/festive/trainplatform/edge_east, +/turf/open/floor/plating/dirt/space, +/area/edina) +"bxP" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "cmoshutter"; + name = "CMO Office Shutters" + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/cmo) +"bxQ" = ( +/obj/structure/sign/directions/medical{ + dir = 8 + }, +/turf/closed/festive/bluebrick/bluebrickcornerse, +/area/command/heads_quarters/cmo) +"bxR" = ( +/obj/structure/sign/departments/medbay, +/turf/closed/festive/whitebrick, +/area/edina) +"bxS" = ( +/obj/structure/window/reinforced{ + name = "Exam Room 4"; + pixel_y = -4 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/pet) +"bxU" = ( +/obj/structure/window/reinforced{ + name = "Exam Room 4"; + pixel_y = -4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/pet) +"bxV" = ( +/turf/open/floor/holofloor/ice, +/area/edina/crew_quarters/store/pet) +"bxW" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/engineering/glass{ + name = "Tool Shoppe" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"bxX" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"bxY" = ( +/obj/machinery/door/poddoor/shutters{ + id = "QMgarage"; + name = "QM's Garage" + }, +/turf/open/floor/festive/cobblestone/safe, +/area/cargo/qm) +"bxZ" = ( +/obj/effect/festive/street/streetlinenw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bya" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"byb" = ( +/obj/effect/festive/street/streetlinene, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"byc" = ( +/obj/effect/festive/street/sidewalkn, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"byd" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bye" = ( +/obj/item/reagent_containers/glass/bucket, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"byf" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet) +"byg" = ( +/obj/structure/fence, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/grass/snow/edina, +/area/medical/medbay/aft) +"byh" = ( +/obj/structure/flora/tree/pine/xmas, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/grass/snow/edina, +/area/medical/medbay/aft) +"byi" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/grass/snow/edina, +/area/medical/medbay/aft) +"byj" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/dark, +/area/medical/medbay/aft) +"byk" = ( +/obj/structure/chair/pew/left, +/turf/open/floor/carpet/green, +/area/medical/surgery) +"byl" = ( +/obj/machinery/holopad, +/turf/open/floor/carpet/green, +/area/medical/surgery) +"bym" = ( +/turf/open/floor/carpet/green, +/area/medical/surgery) +"byn" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/obj/machinery/sleeper, +/turf/open/floor/plasteel/white/side, +/area/medical/exam_room) +"byo" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/progcastaux) +"byp" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"byq" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"byr" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bys" = ( +/obj/effect/festive/street/streetlinenorth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"byt" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/primary/progress) +"byu" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/primary/progress) +"byv" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet) +"byw" = ( +/obj/structure/dresser{ + pixel_y = 12 + }, +/obj/item/flashlight/lamp/green{ + on = 0; + pixel_y = 30 + }, +/turf/open/floor/carpet/red, +/area/commons/dorms) +"byx" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/table/wood, +/obj/item/clipboard, +/obj/item/paper, +/obj/item/pen/fountain, +/turf/open/floor/plasteel/white/side, +/area/medical/exam_room) +"byy" = ( +/obj/machinery/sleeper, +/turf/open/floor/plasteel/white/side, +/area/medical/exam_room) +"byz" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/camera{ + c_tag = "Medbay - Aft Port"; + dir = 8; + name = "medbay camera"; + network = list("ss13","medbay") + }, +/obj/item/clipboard, +/obj/item/healthanalyzer, +/obj/structure/table, +/obj/effect/turf_decal/tile/blue, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/plasteel/white/side, +/area/medical/exam_room) +"byA" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"byB" = ( +/obj/structure/fence{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"byC" = ( +/obj/structure/fence/door/opened, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"byD" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"byE" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"byF" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"byG" = ( +/obj/structure/chair/wood/normal, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/plasteel/white/side, +/area/medical/exam_room) +"byH" = ( +/obj/machinery/vending/medical, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/plasteel/white/side, +/area/medical/exam_room) +"byI" = ( +/obj/structure/sign/departments/examroom, +/turf/closed/festive/whitebrick, +/area/medical/exam_room) +"byJ" = ( +/obj/machinery/computer/crew, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"byK" = ( +/obj/structure/bed, +/obj/effect/spawner/lootdrop/bedsheet, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/carpet/red, +/area/commons/dorms) +"byM" = ( +/obj/machinery/computer/med_data, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"byN" = ( +/obj/structure/table/reinforced, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"byO" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"byP" = ( +/obj/machinery/vending/coffee, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, +/area/medical/medbay/lobby) +"byQ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"byR" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"byS" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"byT" = ( +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/warehouse) +"byU" = ( +/turf/closed/festive/greybrick, +/area/service/electronic_marketing_den) +"byV" = ( +/turf/closed/festive/whitebrick/whitebrickcornernw{ + color = "#5496ff" + }, +/area/medical/genetics/cloning) +"byW" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"byX" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"byY" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeft, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"byZ" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Cloning"; + req_one_access_txt = "5;9" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bza" = ( +/turf/closed/festive/whitebrick{ + color = "#5496ff" + }, +/area/medical/genetics/cloning) +"bzb" = ( +/turf/closed/festive/whitebrick/whitebrickcornernw, +/area/medical/surgery) +"bzc" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plating, +/area/medical/surgery) +"bzd" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/floor/plating, +/area/medical/surgery) +"bze" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plating, +/area/medical/surgery) +"bzf" = ( +/turf/closed/festive/whitebrick/whitebrickns, +/area/medical/surgery) +"bzg" = ( +/obj/machinery/button/privacy{ + pixel_x = -25; + tar_name = "Exam Room 1" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bzh" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bzi" = ( +/obj/machinery/button/privacy{ + pixel_x = -25; + tar_name = "Exam Room 2" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bzj" = ( +/obj/machinery/iv_drip, +/obj/structure/bed/roller, +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bzk" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bzl" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWEMiddle, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bzm" = ( +/obj/structure/chair/office/light{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bzn" = ( +/obj/structure/table/reinforced, +/obj/item/reagent_containers/food/drinks/britcup, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bzo" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bzp" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, +/area/medical/medbay/lobby) +"bzq" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/primary/progress) +"bzr" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/primary/progress) +"bzs" = ( +/turf/open/floor/grass/snow/edina, +/area/edina/street/primary/progress) +"bzt" = ( +/obj/structure/statue/snow/snowman, +/turf/open/floor/grass/snow/edina, +/area/edina/street/primary/progress) +"bzu" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"bzv" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/button/door{ + id = "secgate2"; + name = "Gate doors"; + pixel_y = 22 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"bzw" = ( +/obj/effect/festive/street/streetlinewest, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bzx" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bzy" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bzA" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bzB" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bzC" = ( +/obj/structure/closet/crate, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bzD" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/sign/poster/official/random{ + pixel_y = 32 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bzE" = ( +/obj/structure/closet/cardboard, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/camera{ + c_tag = "Cargo Warehouse" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bzF" = ( +/obj/item/cigbutt/cigarbutt, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bzG" = ( +/turf/open/indestructible, +/area/cargo/warehouse) +"bzH" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/machinery/power/apc{ + areastring = "/area/cargo/warehouse"; + dir = 4; + name = "Cargo Warehouse APC"; + pixel_x = 26 + }, +/obj/structure/cable, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bzI" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/plasteel, +/area/service/electronic_marketing_den) +"bzJ" = ( +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -33 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bzK" = ( +/obj/structure/closet/wardrobe/mixed, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bzL" = ( +/obj/machinery/vending/clothing, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bzM" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bzN" = ( +/obj/structure/sign/warning/nosmoking{ + pixel_x = -28 + }, +/obj/structure/table, +/obj/item/book/manual/wiki/surgery, +/obj/item/razor{ + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/medical/surgery) +"bzO" = ( +/obj/effect/decal/festive/fairylights, +/obj/structure/table/optable, +/turf/open/floor/plasteel/white/side, +/area/medical/surgery) +"bzP" = ( +/obj/effect/decal/festive/fairylights, +/obj/machinery/computer/operating, +/turf/open/floor/plasteel/white/side, +/area/medical/surgery) +"bzQ" = ( +/obj/structure/table, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/effect/decal/festive/fairylights, +/obj/item/storage/backpack/duffelbag/med/surgery, +/turf/open/floor/plasteel, +/area/medical/surgery) +"bzR" = ( +/obj/structure/closet, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bzS" = ( +/obj/structure/table, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bzT" = ( +/obj/structure/bed, +/obj/item/bedsheet/medical, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bzU" = ( +/obj/machinery/vending/wallmed, +/turf/closed/festive/whitebrick, +/area/medical/exam_room) +"bzV" = ( +/obj/machinery/iv_drip, +/obj/structure/bed/roller, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bzW" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeft, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bzX" = ( +/obj/structure/table/reinforced, +/obj/effect/decal/festive/holly, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bzY" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bzZ" = ( +/obj/machinery/door/airlock/command{ + name = "Research Director's Quarters"; + req_access_txt = "30" + }, +/obj/machinery/door/firedoor/heavy, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/holofloor/wood, +/area/command/heads_quarters/rd/private) +"bAa" = ( +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bAb" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bAc" = ( +/turf/open/indestructible, +/area/cargo) +"bAd" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet) +"bAe" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/indestructible, +/area/cargo) +"bAf" = ( +/obj/structure/closet/crate/freezer, +/obj/structure/sign/poster/official/random{ + pixel_x = -32 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bAg" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bAh" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bAi" = ( +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bAj" = ( +/obj/structure/closet/crate, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bAl" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = 27 + }, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bAm" = ( +/obj/machinery/door/airlock/wood, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/service/electronic_marketing_den) +"bAn" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/service/electronic_marketing_den) +"bAo" = ( +/obj/machinery/power/apc/auto_name/east, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel, +/area/service/electronic_marketing_den) +"bAp" = ( +/obj/machinery/power/apc/auto_name/west, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bAq" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bAr" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bAs" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bAt" = ( +/obj/structure/extinguisher_cabinet, +/turf/closed/festive/whitebrick, +/area/medical/surgery) +"bAu" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/light_switch{ + pixel_x = -28; + pixel_y = 17 + }, +/turf/open/floor/plasteel/white/side{ + dir = 4 + }, +/area/medical/surgery) +"bAv" = ( +/obj/effect/landmark/start/medical_doctor, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bAw" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bAx" = ( +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/obj/structure/table, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/item/clothing/gloves/color/latex, +/obj/item/clothing/mask/surgical, +/obj/item/clothing/suit/apron/surgical, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, +/area/medical/surgery) +"bAy" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bAz" = ( +/obj/machinery/door/airlock/medical{ + name = "Surgery"; + req_access_txt = "45" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bAA" = ( +/obj/effect/festive/street/streetlinenm{ + pixel_y = 3 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#bae3ff" + }, +/area/medical/medbay/aft) +"bAB" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/door/airlock/medical{ + name = "Surgery Theatre"; + req_access_txt = "45" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bAC" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/door/window/eastleft{ + dir = 1; + icon_state = "right"; + name = "Exam Room 1"; + pixel_y = 4; + req_access_txt = "5" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bAD" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 1; + name = "Exam Room 1"; + pixel_y = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bAE" = ( +/obj/structure/festive/trainplatform/edge_north, +/obj/structure/festive/trainplatform/edge_south, +/turf/open/floor/festive/stairs/stairswest, +/area/edina/street/primary/perimeter) +"bAF" = ( +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bAG" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/firealarm{ + pixel_y = 28 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bAH" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/door/window/eastleft{ + dir = 1; + icon_state = "right"; + name = "Exam Room 2"; + pixel_y = 4; + req_access_txt = "5" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bAI" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 1; + name = "Exam Room 2"; + pixel_y = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bAJ" = ( +/obj/effect/festive/street/streetlineeast, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bAK" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bAL" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bAM" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bAN" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Aft Primary Hallway" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bAO" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/festive/street/streetlinenm{ + pixel_y = 3 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#bae3ff" + }, +/area/medical/medbay/aft) +"bAP" = ( +/obj/structure/filingcabinet/chestdrawer, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bAQ" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bAR" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, +/area/medical/medbay/lobby) +"bAS" = ( +/obj/structure/sign/departments/medbay, +/turf/closed/festive/whitebrick, +/area/medical/medbay/lobby) +"bAT" = ( +/obj/effect/festive/street/streetlinesw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bAU" = ( +/obj/effect/festive/street/streetlinese, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bAV" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bAW" = ( +/obj/effect/festive/street/sidewalknsm, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bAX" = ( +/obj/machinery/door/poddoor/shutters{ + id = "cargocars"; + name = "Cargo Loading dock" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/festive/cobblestone/safe, +/area/cargo) +"bAY" = ( +/obj/effect/turf_decal/loading_area{ + dir = 8 + }, +/turf/open/indestructible, +/area/cargo) +"bAZ" = ( +/obj/effect/turf_decal/delivery, +/turf/open/indestructible, +/area/cargo) +"bBa" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bBb" = ( +/obj/item/stack/sheet/cardboard, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bBc" = ( +/obj/structure/closet/crate, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bBd" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bBe" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bBf" = ( +/obj/machinery/clonepod, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/shower{ + dir = 4; + name = "emergency shower" + }, +/turf/open/floor/plasteel, +/area/medical/genetics/cloning) +"bBg" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bBh" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bBi" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bBj" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/fulltile{ + max_integrity = 5000; + name = "hardened window"; + obj_integrity = 5000 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bBk" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bBl" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bBm" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/medical/surgery) +"bBn" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/obj/structure/sink{ + dir = 8; + pixel_x = -12; + pixel_y = 2 + }, +/obj/structure/mirror{ + pixel_x = -24 + }, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bBo" = ( +/obj/structure/chair/sofa/right{ + dir = 4 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/ce) +"bBp" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bBq" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bBr" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bBs" = ( +/obj/machinery/door/airlock/medical{ + name = "Surgery"; + req_access_txt = "45" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bBt" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#bae3ff" + }, +/area/medical/medbay/aft) +"bBu" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/door/airlock/medical{ + name = "Surgery Theatre"; + req_access_txt = "45" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bBv" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bBw" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bBx" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/holopad, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bBy" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bBz" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Aft Primary Hallway" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bBA" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#bae3ff" + }, +/area/medical/medbay/aft) +"bBB" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick/whitebrickwe, +/area/medical/medbay/lobby) +"bBC" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Medbay Desk"; + req_access_txt = "5" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bBD" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/machinery/camera{ + c_tag = "Captain's Office - Emergency Escape"; + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = -28 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bBE" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bBF" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/public/glass{ + name = "Aft Primary Hallway" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/decal/festive/mistletoe, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel, +/area/medical/medbay/lobby) +"bBG" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bBH" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/festive/street/streetliftedtile2, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bBI" = ( +/obj/effect/festive/street/streetlinenorth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bBJ" = ( +/obj/effect/festive/street/sidewalks, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bBK" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/junction{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bBL" = ( +/obj/effect/turf_decal/loading_area{ + dir = 8 + }, +/obj/vehicle/sealed/vectorcraft/truck{ + dir = 8 + }, +/turf/open/indestructible, +/area/cargo) +"bBM" = ( +/obj/machinery/button/door{ + id = "qm_warehouse"; + name = "Warehouse Door Control"; + pixel_x = -24; + req_access_txt = "31" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bBN" = ( +/obj/item/flashlight, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bBO" = ( +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bBP" = ( +/turf/closed/festive/whitebrick, +/area/hallway/secondary/service) +"bBQ" = ( +/obj/machinery/door/poddoor/shutters{ + id = "civgarage" + }, +/turf/open/floor/plating, +/area/service/electronic_marketing_den) +"bBR" = ( +/turf/open/floor/plating, +/area/service/electronic_marketing_den) +"bBS" = ( +/obj/vehicle/sealed/vectorcraft/cyber, +/turf/open/floor/plating, +/area/service/electronic_marketing_den) +"bBT" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/plating, +/area/service/electronic_marketing_den) +"bBU" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"bBV" = ( +/obj/vehicle/sealed/vectorcraft, +/turf/open/floor/plating, +/area/service/electronic_marketing_den) +"bBW" = ( +/obj/machinery/computer/cloning{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel, +/area/medical/genetics/cloning) +"bBX" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bBY" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/holopad, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bBZ" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bCa" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Cloning"; + req_one_access_txt = "5;9" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bCb" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/festive/street/streetlinenm{ + pixel_y = 3 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#bae3ff" + }, +/area/medical/medbay/aft) +"bCc" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/festive/street/streetlinenm{ + pixel_y = 3 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#bae3ff" + }, +/area/medical/medbay/aft) +"bCd" = ( +/obj/machinery/door/airlock/medical{ + name = "Operating Theatre"; + req_access_txt = "45" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bCe" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bCf" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bCg" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/disposalpipe/junction{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bCh" = ( +/obj/machinery/door/window/eastleft{ + icon_state = "right"; + name = "First-Aid Supplies"; + req_access_txt = "5" + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, +/area/medical/surgery) +"bCi" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bCj" = ( +/obj/machinery/vending/wallmed, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/festive/whitebrick, +/area/medical/surgery) +"bCk" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/festive/street/streetlinenm{ + pixel_y = 2 + }, +/obj/effect/festive/street/streetlineem{ + pixel_x = 3 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bCl" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/white_alleyway{ + color = "#bae3ff" + }, +/area/medical/medbay/aft) +"bCm" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/door/airlock/medical{ + name = "Surgery Theatre"; + req_access_txt = "45" + }, +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bCn" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/door/window/eastleft{ + dir = 2; + icon_state = "right"; + name = "Exam Room 3"; + pixel_y = -4; + req_access_txt = "5" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bCo" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/window/reinforced{ + name = "Exam Room 3"; + pixel_y = -4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bCp" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Medbay Surgery"; + dir = 1; + network = list("ss13","medbay") + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bCq" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/door/window/eastleft{ + dir = 2; + icon_state = "right"; + name = "Exam Room 4"; + pixel_y = -4; + req_access_txt = "5" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bCr" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/window/reinforced{ + name = "Exam Room 4"; + pixel_y = -4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bCs" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/item/radio/intercom{ + broadcasting = 1; + frequency = 1485; + listening = 0; + name = "Station Intercom (Medbay)"; + pixel_y = -30 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bCt" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bCu" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bCv" = ( +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bCw" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/disposalpipe/junction{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bCx" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Aft Primary Hallway" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bCy" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/white_alleyway{ + color = "#bae3ff" + }, +/area/medical/medbay/aft) +"bCz" = ( +/obj/structure/extinguisher_cabinet, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/festive/whitebrick, +/area/medical/medbay/lobby) +"bCA" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bCB" = ( +/obj/vehicle/ridden/wheelchair, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/item/radio/intercom{ + broadcasting = 1; + frequency = 1485; + listening = 0; + name = "Station Intercom (Medbay)"; + pixel_y = 30 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bCC" = ( +/obj/vehicle/ridden/wheelchair, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bCD" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bCE" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bCF" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/public/glass{ + name = "Aft Primary Hallway" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel, +/area/medical/medbay/lobby) +"bCG" = ( +/obj/effect/festive/street/streetlinesw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bCH" = ( +/obj/effect/festive/street/streetlinesouth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bCI" = ( +/obj/effect/festive/street/sidewalks, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bCJ" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = 20 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessprogress) +"bCK" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bCL" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bCM" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bCN" = ( +/obj/effect/turf_decal/caution{ + dir = 8; + pixel_x = 6; + pixel_y = 16 + }, +/turf/open/floor/festive/cobblestone/safe, +/area/cargo) +"bCO" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo) +"bCP" = ( +/obj/machinery/door/poddoor/shutters{ + id = "qm_warehouse"; + name = "warehouse shutters" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/delivery, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bCQ" = ( +/obj/machinery/door/poddoor/shutters{ + id = "qm_warehouse"; + name = "warehouse shutters" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bCR" = ( +/obj/machinery/door/poddoor/shutters{ + id = "qm_warehouse"; + name = "warehouse shutters" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/cargo/warehouse) +"bCS" = ( +/obj/vehicle/sealed/vectorcraft/truck{ + dir = 8 + }, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/plating, +/area/service/electronic_marketing_den) +"bCT" = ( +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"bCU" = ( +/obj/machinery/dna_scannernew, +/obj/machinery/camera{ + c_tag = "Genetics Cloning"; + dir = 4; + network = list("ss13","medbay") + }, +/obj/machinery/airalarm/unlocked{ + dir = 4; + pixel_x = -23 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/medical/genetics/cloning) +"bCV" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bCW" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bCX" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/office) +"bCY" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bCZ" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/fulltile{ + max_integrity = 5000; + name = "hardened window"; + obj_integrity = 5000 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bDa" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/effect/festive/street/streetlinenm{ + pixel_y = 2 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bDb" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/festive/street/streetlinenm{ + pixel_y = 2 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bDc" = ( +/obj/effect/spawner/structure/window, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/medical/surgery) +"bDd" = ( +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/obj/structure/closet/secure_closet/medical2, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/medical/surgery) +"bDe" = ( +/obj/machinery/light, +/obj/machinery/camera{ + c_tag = "Medbay Surgery"; + dir = 1; + network = list("ss13","medbay") + }, +/obj/machinery/power/apc{ + areastring = "/area/medical/surgery"; + name = "Surgery APC"; + pixel_y = -26 + }, +/obj/structure/cable/yellow, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/medical/surgery) +"bDf" = ( +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -24 + }, +/obj/machinery/disposal/bin{ + pixel_x = 5 + }, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/medical/surgery) +"bDg" = ( +/obj/item/radio/intercom{ + broadcasting = 1; + frequency = 1485; + listening = 0; + name = "Station Intercom (Medbay)"; + pixel_y = -30 + }, +/obj/structure/closet/crate/freezer/blood, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel, +/area/medical/surgery) +"bDh" = ( +/obj/machinery/shower{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/medical/surgery) +"bDi" = ( +/obj/machinery/shower{ + dir = 1 + }, +/obj/item/bedsheet/medical, +/obj/item/bedsheet/medical, +/obj/structure/bed, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bDj" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bDk" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/festive/street/streetlinenm{ + pixel_y = 2 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bDl" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/medical/exam_room) +"bDm" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bDn" = ( +/obj/structure/bed, +/obj/item/bedsheet/medical, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bDo" = ( +/obj/structure/closet/crate/wooden, +/obj/item/stack/sheet/mineral/wood/fifty, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bDp" = ( +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bDq" = ( +/obj/structure/extinguisher_cabinet, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/medical/exam_room) +"bDr" = ( +/obj/machinery/iv_drip, +/obj/structure/bed/roller, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bDs" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bDt" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bDu" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERight, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bDv" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#bae3ff" + }, +/area/medical/medbay/aft) +"bDw" = ( +/obj/structure/closet/crate/trashcart, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 4; + name = "4maintenance loot spawner" + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bDx" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#bae3ff" + }, +/area/medical/medbay/aft) +"bDy" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Aft Primary Hallway" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bDz" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bDA" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bDB" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bDC" = ( +/obj/machinery/holopad, +/turf/open/floor/plasteel/white, +/area/science/robotics/lab) +"bDD" = ( +/obj/structure/sign/departments/medbay, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/medical/medbay/lobby) +"bDE" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/turf_decal/arrows/white, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bDF" = ( +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/storage) +"bDG" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"bDH" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bDI" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8; + pixel_y = 20 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessprogress) +"bDJ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessprogress) +"bDK" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessprogress) +"bDL" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessprogress) +"bDM" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/machinery/chem_dispenser{ + layer = 2.7 + }, +/obj/machinery/requests_console{ + pixel_x = 30 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bDN" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bDO" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bDP" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bDQ" = ( +/obj/structure/table/wood, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"bDR" = ( +/obj/machinery/door/poddoor/shutters{ + id = "civgarage" + }, +/obj/machinery/door/poddoor/shutters{ + id = "civgarage" + }, +/turf/open/floor/plating, +/area/service/electronic_marketing_den) +"bDS" = ( +/obj/machinery/button/door{ + id = "civgarage"; + name = "Engineering Garage Door"; + pixel_x = 28 + }, +/turf/open/floor/plating, +/area/service/electronic_marketing_den) +"bDT" = ( +/obj/structure/table, +/obj/item/book/manual/wiki/medical_cloning{ + pixel_y = 6 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/item/radio/intercom{ + broadcasting = 1; + frequency = 1485; + listening = 0; + name = "Station Intercom (Medbay)"; + pixel_y = -30 + }, +/obj/machinery/camera{ + c_tag = "Brig Infirmary"; + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bDU" = ( +/obj/structure/table, +/obj/item/storage/box/rxglasses{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/box/bodybags, +/obj/item/pen/fountain, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bDV" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bDW" = ( +/obj/machinery/button/door{ + desc = "A remote control switch for the genetics doors."; + id = "GeneticsDoor"; + name = "Genetics Exit Button"; + normaldoorcontrol = 1; + pixel_x = 24; + pixel_y = 8 + }, +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/obj/structure/disposalpipe/junction, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bDX" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/festive/whitebrick{ + color = "#5496ff" + }, +/area/medical/genetics/cloning) +"bDY" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/plasteel, +/area/medical/surgery) +"bDZ" = ( +/obj/machinery/button/privacy{ + pixel_x = -25; + tar_name = "Exam Room 3" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bEa" = ( +/obj/machinery/button/privacy{ + pixel_x = -25; + tar_name = "Exam Room 4" + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bEb" = ( +/obj/machinery/iv_drip, +/obj/structure/bed/roller, +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/power/apc{ + areastring = "/area/medical/exam_room"; + dir = 8; + name = "Medbay APC"; + pixel_x = -26 + }, +/obj/structure/cable/yellow, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bEc" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bEd" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bEe" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/turf/open/floor/plasteel/white, +/area/medical/exam_room) +"bEf" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#bae3ff" + }, +/area/medical/medbay/aft) +"bEg" = ( +/turf/open/floor/festive/white_alleyway{ + color = "#bae3ff" + }, +/area/medical/medbay/aft) +"bEh" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Aft Primary Hallway" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bEi" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bEj" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/machinery/holopad, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bEk" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bEl" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/obj/machinery/status_display/ai{ + pixel_x = 32 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, +/area/medical/medbay/lobby) +"bEm" = ( +/obj/effect/festive/street/sidewalkw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bEn" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bEo" = ( +/obj/machinery/button/door{ + id = "cargocars"; + name = "Garage door button" + }, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo) +"bEp" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Loading Garage"; + req_one_access_txt = "31;48" + }, +/obj/machinery/door/firedoor, +/turf/open/indestructible, +/area/cargo) +"bEq" = ( +/obj/structure/fence, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/supply) +"bEr" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bEs" = ( +/obj/structure/closet/crate{ + icon_state = "crateopen" + }, +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/indestructible, +/area/cargo/warehouse) +"bEt" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/obj/structure/chair/sofa/left{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bEu" = ( +/obj/vehicle/sealed/vectorcraft/ambulance{ + dir = 1 + }, +/turf/open/floor/plating, +/area/service/electronic_marketing_den) +"bEv" = ( +/obj/vehicle/sealed/vectorcraft/auto{ + dir = 1 + }, +/turf/open/floor/plating, +/area/service/electronic_marketing_den) +"bEw" = ( +/obj/vehicle/sealed/vectorcraft/ambulance{ + dir = 1 + }, +/obj/machinery/light/small, +/turf/open/floor/plating, +/area/service/electronic_marketing_den) +"bEx" = ( +/obj/vehicle/sealed/vectorcraft/truck{ + dir = 8 + }, +/turf/open/floor/plating, +/area/service/electronic_marketing_den) +"bEy" = ( +/turf/closed/festive/whitebrick/whitebrickns{ + color = "#5496ff" + }, +/area/medical/genetics/cloning) +"bEz" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bEA" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Cloning"; + req_one_access_txt = "5;9" + }, +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel/white, +/area/medical/genetics/cloning) +"bEB" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/turf/closed/festive/whitebrick{ + color = "#5496ff" + }, +/area/medical/genetics/cloning) +"bEC" = ( +/obj/machinery/stasis{ + dir = 4 + }, +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/medical/exam_room) +"bED" = ( +/obj/machinery/light, +/obj/structure/table/wood, +/obj/item/clipboard, +/obj/item/paper, +/obj/item/pen/fountain, +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/medical/exam_room) +"bEE" = ( +/obj/machinery/bloodbankgen, +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/medical/exam_room) +"bEF" = ( +/obj/structure/chair/wood/normal{ + dir = 1 + }, +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/medical/exam_room) +"bEG" = ( +/obj/machinery/disposal/bin{ + pixel_x = 5 + }, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/medical/exam_room) +"bEH" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/festive/street/streetlinenm{ + pixel_y = 2 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bEI" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/festive/street/streetlinenm{ + pixel_y = 2 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bEJ" = ( +/obj/structure/flora/tree/pine/xmas, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bEK" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bEL" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"bEM" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bEN" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bEO" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bEP" = ( +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bEQ" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/power/apc{ + areastring = "/area/medical/medbay/lobby"; + dir = 4; + name = "Medbay Reception APC"; + pixel_x = 26 + }, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, +/area/medical/medbay/lobby) +"bER" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bES" = ( +/obj/effect/festive/street/sidewalke, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"bET" = ( +/obj/machinery/conveyor_switch{ + id = "cargocars" + }, +/turf/open/indestructible, +/area/cargo) +"bEU" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bEV" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bEW" = ( +/obj/structure/chair/sofa/right{ + dir = 8 + }, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bEX" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/medical/medbay/aft) +"bEY" = ( +/turf/closed/festive/greybrick, +/area/maintenance/bar) +"bEZ" = ( +/turf/closed/festive/whitebrick/whitebrickcornerse, +/area/medical/exam_room) +"bFa" = ( +/turf/closed/festive/redbrick/redbrickte, +/area/security/checkpoint/medical) +"bFb" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSRightEnd, +/turf/open/floor/plasteel/white, +/area/security/checkpoint/medical) +"bFc" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSLeftEnd, +/turf/open/floor/plasteel/white, +/area/security/checkpoint/medical) +"bFd" = ( +/obj/machinery/door/airlock/research{ + name = "Robotics Lab"; + req_access_txt = "29" + }, +/obj/machinery/door/firedoor, +/obj/effect/decal/festive/christmas_reef, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bFe" = ( +/obj/effect/festive/street/streetlinenw, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bFf" = ( +/obj/effect/festive/street/streetlinene, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bFg" = ( +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"bFh" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bFi" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowdoornsend1, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/security/checkpoint/medical) +"bFj" = ( +/turf/closed/festive/redbrick/redbricktn, +/area/security/checkpoint/medical) +"bFk" = ( +/obj/structure/sign/departments/medbay/alt, +/turf/closed/festive/redbrick/redbrickcornerne, +/area/security/checkpoint/medical) +"bFl" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessprogress) +"bFm" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/sign/directions/evac{ + pixel_x = 32; + pixel_y = -40 + }, +/obj/structure/sign/directions/supply{ + pixel_x = 32; + pixel_y = -32 + }, +/obj/structure/sign/directions/medical{ + pixel_x = 32; + pixel_y = -24 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessprogress) +"bFn" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/mob/living/simple_animal/jacq/car_spawner, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"bFo" = ( +/obj/effect/festive/street/streetlineem, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"bFp" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/sign/departments/botany{ + pixel_y = -32 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"bFq" = ( +/obj/structure/fence, +/turf/open/floor/grass/snow/edina, +/area/edina/street/primary/progress) +"bFr" = ( +/obj/machinery/door/airlock{ + id_tag = "pubtoilet1"; + name = "Unisex Toilet" + }, +/turf/open/floor/mineral/titanium/blue, +/area/service/cafeteria/lunchroom) +"bFs" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bFt" = ( +/obj/structure/table, +/obj/item/reagent_containers/spray/plantbgone, +/obj/item/reagent_containers/spray/plantbgone{ + pixel_x = 5; + pixel_y = 5 + }, +/obj/structure/sign/poster/contraband/ambrosia_vulgaris{ + pixel_y = -32 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bFu" = ( +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bFv" = ( +/obj/structure/fluff/lightpost/light, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bFw" = ( +/turf/closed/festive/whitebrick/whitebrickns, +/area/medical/cryo) +"bFx" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bFy" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bFz" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bFA" = ( +/obj/structure/extinguisher_cabinet, +/turf/closed/festive/whitebrick/whitebrickns, +/area/medical/cryo) +"bFB" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bFC" = ( +/obj/structure/closet/secure_closet/brig{ + id = "medcell"; + name = "Medical Cell Locker" + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bFD" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWERightEnd, +/turf/open/floor/plasteel/white, +/area/security/checkpoint/medical) +"bFE" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/carpet/purple, +/area/command/heads_quarters/rd/private) +"bFF" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bFG" = ( +/obj/structure/table/reinforced, +/obj/item/book/manual/wiki/security_space_law, +/obj/item/radio, +/obj/machinery/camera{ + c_tag = "Holodeck" + }, +/obj/machinery/firealarm{ + pixel_y = 26 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bFH" = ( +/obj/structure/table/reinforced, +/obj/machinery/recharger, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bFI" = ( +/obj/machinery/computer/secure_data{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bFJ" = ( +/obj/effect/spawner/structure/window, +/obj/structure/curtain{ + color = "#FF5555" + }, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bFK" = ( +/obj/structure/sign/departments/chemistry, +/turf/closed/wall/mineral/wood, +/area/medical/chemistry) +"bFL" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Pharmacy" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/carpet/orange, +/area/medical/chemistry) +"bFM" = ( +/obj/effect/spawner/structure/window, +/obj/structure/curtain{ + color = "#FF5555" + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "chemistry_shutters"; + name = "chemistry shutters" + }, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bFN" = ( +/turf/closed/festive/greybrick/greybrickcornernw, +/area/service/bar/atrium) +"bFO" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSRightEnd, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bFP" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSMiddle, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bFQ" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSLeftEnd, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bFR" = ( +/turf/closed/festive/greybrick/greybrickns, +/area/service/bar/atrium) +"bFS" = ( +/turf/closed/festive/greybrick, +/area/service/bar/atrium) +"bFT" = ( +/turf/closed/festive/greybrick/greybrickts, +/area/service/bar/atrium) +"bFU" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSRightEnd, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bFV" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSLeftEnd, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bFW" = ( +/turf/closed/festive/greybrick/greybrickns, +/area/service/cafeteria/lunchroom) +"bFX" = ( +/obj/item/reagent_containers/food/urinalcake, +/obj/structure/urinal{ + pixel_y = 25 + }, +/obj/machinery/light/small, +/turf/open/floor/mineral/titanium/blue, +/area/service/cafeteria/lunchroom) +"bFY" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bFZ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bGa" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bGb" = ( +/obj/structure/fence{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"bGc" = ( +/turf/closed/festive/greybrick/greybrickts, +/area/commons/dorms) +"bGd" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSRightEnd, +/turf/open/floor/wood, +/area/commons/dorms) +"bGe" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSLeftEnd, +/turf/open/floor/wood, +/area/commons/dorms) +"bGf" = ( +/turf/closed/festive/greybrick/greybrickcornerne, +/area/commons/dorms) +"bGg" = ( +/turf/open/floor/festive/alleyway, +/area/edina/street/primary/progress) +"bGh" = ( +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/office) +"bGi" = ( +/obj/structure/table/reinforced, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bGj" = ( +/obj/structure/reagent_dispensers/water_cooler, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bGk" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bGl" = ( +/obj/machinery/door/firedoor, +/obj/structure/table/reinforced, +/obj/machinery/door/window/westleft{ + dir = 1; + name = "Delivery Desk"; + req_access_txt = "50" + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/cargo) +"bGm" = ( +/obj/machinery/conveyor{ + id = "garbage" + }, +/obj/structure/plasticflaps, +/turf/open/floor/plating, +/area/cargo) +"bGn" = ( +/obj/structure/chair/sofa/right{ + dir = 1 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bGo" = ( +/obj/machinery/button/door{ + id = "parkcomm"; + name = "Command Parking"; + pixel_x = -4; + pixel_y = 7; + req_one_access_txt = "2;19" + }, +/turf/closed/festive/whitebrick, +/area/edina/street) +"bGp" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bGq" = ( +/obj/structure/festive/trainplatform/edge_west, +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"bGr" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/command/nuke_storage) +"bGs" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Atrium" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/command/nuke_storage) +"bGt" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Atrium" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/ai_monitored/command/nuke_storage) +"bGu" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/festive/street/streetlineem, +/mob/living/simple_animal/jacq/car_spawner, +/turf/open/floor/festive/alleyway, +/area/edina/street/primary/progress) +"bGv" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"bGw" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/closed/festive/redbrick, +/area/security/checkpoint/science) +"bGx" = ( +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/medical/morgue) +"bGy" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/medical/morgue) +"bGz" = ( +/obj/machinery/door/airlock/grunge{ + name = "Morgue"; + req_access_txt = "6" + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bGA" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/medical/morgue) +"bGB" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/fulltile{ + max_integrity = 5000; + name = "hardened window"; + obj_integrity = 5000 + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bGC" = ( +/obj/structure/table/glass, +/obj/item/reagent_containers/glass/beaker/cryoxadone{ + pixel_x = 7; + pixel_y = 1 + }, +/obj/item/reagent_containers/glass/beaker/cryoxadone{ + pixel_x = 7; + pixel_y = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/firealarm{ + dir = 1; + pixel_y = 26 + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bGD" = ( +/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/medical/cryo) +"bGE" = ( +/obj/structure/festive/greybrick/windowWERightEnd, +/turf/open/floor/festive/trainplatform, +/area/edina/street/primary/perimeter) +"bGF" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/festive/trainplatform, +/area/edina/street/primary/perimeter) +"bGG" = ( +/obj/structure/table, +/obj/machinery/cell_charger, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/item/wrench/medical, +/obj/item/crowbar, +/obj/item/screwdriver, +/turf/open/floor/plasteel, +/area/medical/cryo) +"bGH" = ( +/obj/machinery/atmospherics/components/unary/cryo_cell, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/medical/cryo) +"bGI" = ( +/obj/structure/table/glass, +/obj/machinery/camera{ + c_tag = "Medbay Cryogenics"; + network = list("ss13","medbay") + }, +/obj/item/reagent_containers/glass/beaker/cryoxadone, +/obj/item/reagent_containers/glass/beaker/cryoxadone, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/camera{ + c_tag = "Research Division Access" + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bGJ" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/machinery/light{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bGK" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bGL" = ( +/obj/machinery/light_switch{ + pixel_x = 26; + pixel_y = 26 + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/carpet/purple, +/area/command/heads_quarters/rd/private) +"bGM" = ( +/obj/machinery/door/firedoor/heavy, +/obj/machinery/door/airlock/research{ + name = "Experimentation Lab"; + req_access_txt = "47" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/science/explab) +"bGN" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/vehicle/sealed/vectorcraft/auto, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"bGO" = ( +/obj/machinery/holopad, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bGP" = ( +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bGQ" = ( +/obj/structure/chair/office/dark{ + dir = 4 + }, +/obj/effect/landmark/start/depsec/medical, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bGR" = ( +/obj/machinery/computer/security{ + dir = 8 + }, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bGS" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bGT" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWEMiddle, +/turf/open/floor/plasteel/white, +/area/security/checkpoint/medical) +"bGU" = ( +/obj/structure/chair/wood/normal{ + dir = 4 + }, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bGV" = ( +/obj/effect/decal/festive/fairylights, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bGW" = ( +/obj/structure/chair/wood/normal, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bGX" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bGY" = ( +/turf/open/floor/carpet/orange, +/area/medical/chemistry) +"bGZ" = ( +/obj/structure/flora/tree/pine/xmas, +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/obj/structure/noticeboard{ + desc = "A board for pinning important notices upon. Probably helpful for keeping track of requests."; + name = "requests board"; + pixel_x = 32 + }, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bHa" = ( +/obj/effect/decal/festive/holly, +/turf/closed/wall/mineral/wood, +/area/medical/chemistry) +"bHb" = ( +/obj/machinery/smartfridge/chemistry, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bHc" = ( +/obj/structure/closet/crate/wooden, +/obj/item/stack/sheet/mineral/wood/fifty, +/obj/item/toy/plush/catgirl/fermis, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bHd" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowWERightEnd, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bHe" = ( +/obj/structure/chair/sofa/corner{ + dir = 4 + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bHf" = ( +/obj/structure/chair/sofa, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bHg" = ( +/obj/structure/chair/sofa/corner, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bHh" = ( +/obj/structure/fireplace, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bHi" = ( +/obj/machinery/computer/arcade/battle{ + dir = 8 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bHj" = ( +/obj/structure/chair/sofa/corner{ + dir = 4 + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"bHk" = ( +/obj/structure/chair/sofa, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"bHl" = ( +/obj/structure/chair/sofa/corner, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"bHm" = ( +/turf/open/floor/carpet/green, +/area/service/cafeteria/lunchroom) +"bHn" = ( +/obj/structure/fireplace, +/turf/open/floor/carpet/green, +/area/service/cafeteria/lunchroom) +"bHo" = ( +/obj/structure/mirror{ + pixel_y = 28 + }, +/obj/structure/sink{ + pixel_y = 22 + }, +/obj/structure/toilet{ + dir = 8 + }, +/turf/open/floor/mineral/titanium/blue, +/area/service/cafeteria/lunchroom) +"bHp" = ( +/obj/machinery/door/airlock{ + id_tag = "pubtoilet2"; + name = "Unisex Toilet" + }, +/turf/open/floor/mineral/titanium/blue, +/area/service/cafeteria/lunchroom) +"bHq" = ( +/obj/machinery/door/airlock{ + id_tag = "pubtoilet3"; + name = "Unisex Toilet" + }, +/turf/open/floor/mineral/titanium/blue, +/area/service/cafeteria/lunchroom) +"bHr" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bHs" = ( +/obj/structure/fence/door/opened, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bHt" = ( +/obj/machinery/vending/kink, +/turf/open/floor/wood, +/area/commons/storage/tools) +"bHu" = ( +/obj/machinery/vending/medical, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/commons/storage/tools) +"bHv" = ( +/obj/machinery/vending/kink, +/obj/machinery/vending/autodrobe, +/turf/open/floor/wood, +/area/commons/storage/tools) +"bHw" = ( +/obj/machinery/vending/clothing, +/turf/open/floor/wood, +/area/commons/storage/tools) +"bHx" = ( +/obj/structure/chair/sofa/left{ + dir = 1 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bHy" = ( +/obj/machinery/vending/wardrobe/chef_wardrobe, +/turf/open/floor/carpet/monochrome, +/area/hallway/secondary/service) +"bHz" = ( +/obj/machinery/vending/wardrobe/bar_wardrobe, +/turf/open/floor/carpet/monochrome, +/area/hallway/secondary/service) +"bHA" = ( +/obj/structure/closet/secure_closet/bar, +/obj/item/storage/box/drinkingglasses, +/obj/item/storage/box/cups, +/obj/item/gun/ballistic/revolver/doublebarrel, +/turf/open/floor/carpet/monochrome, +/area/hallway/secondary/service) +"bHB" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"bHC" = ( +/obj/structure/mirror{ + pixel_y = 28 + }, +/obj/structure/sink{ + pixel_y = 22 + }, +/obj/structure/toilet{ + dir = 8 + }, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/mineral/titanium/blue, +/area/commons/dorms) +"bHD" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/structure/table/wood/fancy/red, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/decal/festive/fairylights{ + pixel_y = 32 + }, +/turf/open/indestructible, +/area/cargo/office) +"bHE" = ( +/obj/structure/chair, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/landmark/start/cargo_technician, +/obj/effect/decal/festive/fairylights{ + pixel_y = 32 + }, +/turf/open/indestructible, +/area/cargo/office) +"bHF" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/structure/chair, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/obj/structure/sign/poster/official/foam_force_ad{ + pixel_y = 32 + }, +/obj/effect/decal/festive/mistletoe, +/turf/open/indestructible, +/area/cargo/office) +"bHG" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/structure/chair, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/turf/open/indestructible, +/area/cargo/office) +"bHH" = ( +/obj/effect/turf_decal/caution/stand_clear{ + pixel_y = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/indestructible, +/area/cargo/office) +"bHI" = ( +/obj/machinery/autolathe{ + name = "public autolathe" + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/decal/festive/christmas_reef{ + pixel_y = 24 + }, +/turf/open/indestructible, +/area/cargo/office) +"bHJ" = ( +/obj/machinery/computer/cargo/request, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/sign/departments/cargo{ + pixel_y = 32 + }, +/turf/open/indestructible, +/area/cargo/office) +"bHK" = ( +/obj/structure/table/wood/fancy/green, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/turf/open/indestructible, +/area/cargo/office) +"bHL" = ( +/obj/machinery/computer/cargo, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/structure/noticeboard/qm{ + pixel_y = 32 + }, +/obj/effect/decal/festive/red_stockings, +/turf/open/indestructible, +/area/cargo/office) +"bHM" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bHN" = ( +/obj/structure/closet/crate/trashcart, +/obj/structure/fence{ + dir = 4 + }, +/obj/item/pipe_dispenser, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bHO" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/structure/extinguisher_cabinet{ + pixel_y = 32 + }, +/obj/machinery/power/apc/auto_name{ + pixel_x = 30 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/decal/festive/fairylights, +/turf/open/indestructible, +/area/cargo/office) +"bHP" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/office) +"bHQ" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bHR" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo) +"bHS" = ( +/obj/structure/chair/stool, +/obj/machinery/requests_console{ + department = "Cargo Bay"; + departmentType = 2; + pixel_x = -30 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/cargo) +"bHT" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/machinery/door/window{ + req_one_access_txt = "48,50" + }, +/obj/effect/turf_decal/bot, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/cargo) +"bHU" = ( +/obj/structure/chair/sofa/corner{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bHV" = ( +/obj/machinery/conveyor_switch/oneway{ + id = "packageSort2" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/cargo) +"bHW" = ( +/obj/structure/table, +/obj/item/stack/wrapping_paper, +/obj/item/stack/wrapping_paper, +/obj/item/stack/packageWrap{ + pixel_x = 2; + pixel_y = -3 + }, +/obj/item/stack/packageWrap{ + pixel_x = 2; + pixel_y = -3 + }, +/obj/item/stack/packageWrap{ + pixel_x = 2; + pixel_y = -3 + }, +/obj/item/stack/packageWrap{ + pixel_x = 2; + pixel_y = -3 + }, +/obj/item/stack/packageWrap{ + pixel_x = 2; + pixel_y = -3 + }, +/obj/item/stack/packageWrap{ + pixel_x = 2; + pixel_y = -3 + }, +/obj/item/stack/packageWrap{ + pixel_x = 2; + pixel_y = -3 + }, +/obj/item/stack/packageWrap{ + pixel_x = 2; + pixel_y = -3 + }, +/obj/item/storage/box/lights/mixed, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white/corner, +/area/cargo) +"bHX" = ( +/obj/item/storage/box, +/obj/structure/table, +/obj/item/storage/box, +/obj/item/storage/box, +/obj/item/hand_labeler, +/obj/machinery/power/apc{ + areastring = "/area/cargo/sorting"; + dir = 4; + name = "Delivery Office APC"; + pixel_y = 26 + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white/corner, +/area/cargo) +"bHZ" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bIa" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bIb" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bIc" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bId" = ( +/obj/docking_port/stationary{ + dir = 8; + dwidth = 4; + height = 15; + id = "emergency_home"; + name = "PubbyStation emergency evac bay"; + width = 20 + }, +/obj/structure/festive/trainplatform/edge_west, +/turf/open/floor/plating/dirt/space, +/area/edina) +"bIe" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/festive/trainplatform/necorner, +/turf/open/floor/plating/dirt/space, +/area/edina) +"bIf" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/fence, +/turf/open/floor/plating/dirt/space, +/area/edina) +"bIg" = ( +/obj/effect/festive/street/sidewalkwem, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bIh" = ( +/obj/structure/sign/departments/chemistry, +/turf/closed/festive/whitebrick{ + color = "#ffe6a8" + }, +/area/medical/chemistry) +"bIi" = ( +/turf/closed/festive/whitebrick{ + color = "#ffe6a8" + }, +/area/medical/chemistry) +"bIj" = ( +/obj/structure/bodycontainer/morgue, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bIk" = ( +/obj/machinery/airalarm/unlocked{ + pixel_y = 23 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bIl" = ( +/obj/machinery/light{ + dir = 1; + light_color = "#e8eaff" + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bIm" = ( +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bIn" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/power/apc{ + dir = 1; + name = "Morgue APC"; + pixel_y = 24 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bIo" = ( +/obj/machinery/door/airlock/medical{ + name = "Cyrostasis" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bIp" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bIq" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 5 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/medical/cryo) +"bIr" = ( +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 1 + }, +/obj/effect/landmark/start/medical_doctor, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/medical/cryo) +"bIs" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWEMiddle, +/turf/closed/festive/redbrick, +/area/edina/street/primary/perimeter) +"bIt" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 9 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/medical/cryo) +"bIu" = ( +/obj/machinery/door/airlock/medical{ + name = "Cyrostasis" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bIv" = ( +/turf/closed/festive/whitebrick/whitebrickns, +/area/medical/storage) +"bIw" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + id = "loungeshutters"; + name = "privacy shutters" + }, +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bIx" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + id = "loungeshutters"; + name = "privacy shutters" + }, +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bIy" = ( +/turf/closed/festive/whitebrick/whitebrickcornerne, +/area/medical/storage) +"bIz" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/door/airlock/medical{ + name = "Recovery Room" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bIA" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bIB" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/medical/glass{ + name = "Medbay Storage"; + req_access_txt = "5" + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bIC" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Medbay Storage"; + req_access_txt = "5" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bID" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bIE" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bIF" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/science/explab) +"bIG" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"bIH" = ( +/obj/item/radio/intercom{ + dir = 8; + name = "Station Intercom (General)"; + pixel_y = -26 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bII" = ( +/obj/structure/closet/secure_closet/security/med, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bIJ" = ( +/obj/machinery/computer/crew{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"bIK" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWELeftEnd, +/turf/open/floor/plasteel/white, +/area/security/checkpoint/medical) +"bIL" = ( +/obj/structure/table/wood, +/obj/machinery/door/window/eastright{ + dir = 8; + name = "Chemistry Desk"; + req_access_txt = "5" + }, +/obj/machinery/door/window/eastright{ + name = "Chemistry Desk" + }, +/obj/item/stack/packageWrap, +/obj/item/stack/packageWrap, +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "chemistry_shutters"; + name = "chemistry shutters" + }, +/obj/item/paper_bin, +/obj/item/pen/fountain, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bIM" = ( +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/obj/effect/landmark/start/chemist, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bIN" = ( +/obj/machinery/button/door{ + id = "chemistry_shutters"; + name = "chemistry shutters control"; + pixel_x = 24; + pixel_y = 24; + req_access_txt = "5; 33" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bIO" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowWEMiddle, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bIP" = ( +/obj/structure/chair/sofa{ + dir = 4 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bIQ" = ( +/obj/structure/chair/sofa{ + dir = 8 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bIR" = ( +/obj/machinery/computer/arcade/orion_trail{ + dir = 8 + }, +/obj/structure/extinguisher_cabinet{ + pixel_x = 24 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bIS" = ( +/obj/structure/chair/sofa{ + dir = 4 + }, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"bIT" = ( +/obj/structure/table/wood, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"bIU" = ( +/obj/structure/chair/sofa{ + dir = 8 + }, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"bIV" = ( +/obj/structure/chair/comfy/lime{ + color = "#51ad6a"; + dir = 4; + name = "cozy chair" + }, +/turf/open/floor/carpet/green, +/area/service/cafeteria/lunchroom) +"bIW" = ( +/obj/structure/table/wood/fancy/green, +/turf/open/floor/carpet/green, +/area/service/cafeteria/lunchroom) +"bIX" = ( +/obj/structure/chair/comfy/lime{ + color = "#51ad6a"; + dir = 8; + name = "cozy chair" + }, +/turf/open/floor/carpet/green, +/area/service/cafeteria/lunchroom) +"bIY" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bIZ" = ( +/obj/machinery/vending/autodrobe, +/turf/open/floor/wood, +/area/commons/storage/tools) +"bJb" = ( +/obj/structure/table/reinforced, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"bJc" = ( +/obj/structure/table/reinforced, +/obj/item/reagent_containers/rag/towel, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"bJd" = ( +/obj/machinery/keycard_auth{ + pixel_x = -6; + pixel_y = 24 + }, +/obj/machinery/computer/card/minor/qm, +/turf/open/floor/festive/wooden/wooden2, +/area/cargo/qm) +"bJe" = ( +/turf/open/floor/carpet/monochrome, +/area/hallway/secondary/service) +"bJf" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"bJg" = ( +/obj/structure/curtain, +/obj/structure/window/reinforced/tinted{ + dir = 8 + }, +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/turf/open/floor/mineral/titanium/blue, +/area/commons/dorms) +"bJh" = ( +/turf/closed/festive/greybrick/greybricktw, +/area/commons/dorms) +"bJi" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Cargo Bay"; + req_one_access_txt = "31;48" + }, +/obj/machinery/door/firedoor, +/obj/effect/decal/festive/christmas_reef, +/turf/open/indestructible, +/area/cargo/office) +"bJj" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/festive/street/streetlineem, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bJk" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/office) +"bJl" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/office) +"bJm" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/indestructible, +/area/cargo/office) +"bJn" = ( +/obj/effect/turf_decal/bot, +/turf/open/indestructible, +/area/cargo/office) +"bJo" = ( +/obj/effect/turf_decal/delivery, +/turf/open/indestructible, +/area/cargo/office) +"bJp" = ( +/obj/structure/table/wood/fancy/green, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/window/westleft{ + name = "Cargo Desk"; + req_access_txt = "50" + }, +/turf/open/indestructible, +/area/cargo/office) +"bJq" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/obj/effect/landmark/start/cargo_technician, +/turf/open/indestructible, +/area/cargo/office) +"bJr" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/indestructible, +/area/cargo/office) +"bJs" = ( +/obj/effect/festive/street/sidewalkn, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bJt" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/airlock/wood{ + name = "Chaplain's Quarters"; + req_access_txt = "27" + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"bJu" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/airlock/wood{ + name = "Chaplain's Quarters"; + req_access_txt = "27" + }, +/turf/open/indestructible/hotelwood, +/area/service/chapel/main/monastery) +"bJv" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/service/janitor) +"bJw" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/indestructible, +/area/cargo) +"bJx" = ( +/obj/structure/sign/departments/botany{ + pixel_x = 32; + pixel_y = 32 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bJy" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/door/airlock/mining/glass{ + name = "Reclaiming center" + }, +/turf/open/indestructible, +/area/cargo) +"bJz" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bJA" = ( +/obj/effect/festive/street/sidewalkw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bJB" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bJC" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bJD" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bJE" = ( +/obj/machinery/firealarm{ + dir = 1; + pixel_y = 26 + }, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bJF" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bJG" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/vending/wardrobe/chem_wardrobe, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bJH" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/closet/secure_closet/chemical, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bJI" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/firealarm{ + dir = 1; + pixel_y = 26 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bJJ" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#e8eaff" + }, +/obj/item/radio/intercom{ + broadcasting = 1; + frequency = 1485; + listening = 0; + name = "Station Intercom (Medbay)"; + pixel_y = 30 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bJK" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/table, +/obj/item/reagent_containers/dropper, +/obj/item/reagent_containers/glass/beaker, +/obj/item/reagent_containers/glass/beaker/large, +/obj/structure/extinguisher_cabinet{ + dir = 4; + pixel_x = -5; + pixel_y = 27 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bJL" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/machinery/chem_master, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bJM" = ( +/obj/structure/bodycontainer/morgue, +/obj/structure/bodycontainer/morgue, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bJN" = ( +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bJO" = ( +/obj/structure/bodycontainer/morgue, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bJP" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bJQ" = ( +/obj/structure/chair{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bJR" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bJS" = ( +/obj/machinery/door/airlock/medical{ + name = "Cyrostasis" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bJT" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bJU" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 6 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/medical/cryo) +"bJV" = ( +/obj/machinery/atmospherics/pipe/manifold4w/general/visible, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/medical/cryo) +"bJW" = ( +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 10 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/medical/cryo) +"bJX" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bJY" = ( +/obj/machinery/door/airlock/medical{ + name = "Cyrostasis" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bJZ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bKa" = ( +/obj/machinery/shower{ + pixel_y = 8 + }, +/obj/structure/curtain, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/turf/open/floor/plasteel/freezer, +/area/medical/storage) +"bKb" = ( +/obj/structure/closet/cabinet{ + pixel_y = 15 + }, +/turf/open/floor/carpet/purple, +/area/medical/storage) +"bKc" = ( +/obj/structure/bed, +/obj/item/toy/plush/random, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/carpet/purple, +/area/medical/storage) +"bKd" = ( +/obj/effect/spawner/structure/window, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "loungeshutters"; + name = "privacy shutters" + }, +/turf/open/floor/carpet/purple, +/area/medical/storage) +"bKe" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bKf" = ( +/obj/docking_port/stationary{ + dir = 4; + dwidth = 3; + height = 5; + id = "mining_home"; + name = "mining shuttle bay"; + roundstart_template = /datum/map_template/shuttle/mining/delta; + width = 7 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"bKg" = ( +/obj/structure/festive/greybrick/windowWELeftEnd, +/turf/open/floor/festive/trainplatform, +/area/edina/street/primary/perimeter) +"bKh" = ( +/obj/machinery/light/small, +/turf/open/floor/festive/trainplatform, +/area/edina/street/primary/perimeter) +"bKi" = ( +/obj/machinery/rnd/production/techfab/department/medical, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = -28 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bKj" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/structure/sink{ + pixel_y = 22 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bKk" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bKl" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bKm" = ( +/obj/machinery/door/airlock/research{ + name = "Mech Bay"; + req_access_txt = "29" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/science/robotics/mechbay) +"bKn" = ( +/turf/closed/festive/redbrick/redbrickcornerse, +/area/security/checkpoint/medical) +"bKo" = ( +/obj/structure/table/wood, +/obj/machinery/door/window/eastright{ + dir = 8; + name = "Chemistry Desk"; + req_access_txt = "5" + }, +/obj/machinery/door/window/eastright{ + name = "Chemistry Desk" + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "chemistry_shutters"; + name = "chemistry shutters" + }, +/obj/machinery/cell_charger, +/obj/item/toy/plush/catgirl/fermis, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bKp" = ( +/obj/structure/fireplace{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bKq" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowWELeftEnd, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bKr" = ( +/obj/structure/chair/sofa/right{ + dir = 4 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bKs" = ( +/obj/structure/chair/sofa/left{ + dir = 8 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bKt" = ( +/obj/machinery/vending/dinnerware{ + desc = "A vending machine stocked full of condiments to put on food."; + name = "\improper Condiments Dispenser"; + products = list(/obj/item/storage/bag/tray = 10, /obj/item/kitchen/fork = 6, /obj/item/kitchen/knife = 6, /obj/item/reagent_containers/food/drinks/drinkingglass = 20, /obj/item/clothing/suit/apron/chef = 2, /obj/item/storage/box/cups = 10, /obj/item/reagent_containers/food/condiment/pack/ketchup = 20, /obj/item/reagent_containers/food/condiment/pack/mustard = 20, /obj/item/reagent_containers/food/condiment/pack/hotsauce = 20, /obj/item/reagent_containers/food/condiment/pack/astrotame = 20, /obj/item/reagent_containers/food/condiment/saltshaker = 20, /obj/item/reagent_containers/food/condiment/peppermill = 20, /obj/item/reagent_containers/glass/bowl = 30) + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bKu" = ( +/obj/structure/chair/sofa/right{ + dir = 4 + }, +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"bKv" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/bottle/patron{ + pixel_x = -5; + pixel_y = 16 + }, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"bKw" = ( +/obj/structure/chair/sofa/left{ + dir = 8 + }, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/carpet/royalblack, +/area/service/bar/atrium) +"bKx" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/carpet/green, +/area/service/cafeteria/lunchroom) +"bKy" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bKz" = ( +/obj/structure/table/wood/fancy/black, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"bKA" = ( +/obj/machinery/door/airlock/titanium{ + name = "Service Office"; + req_one_access_txt = "25;26;28;35" + }, +/turf/open/floor/plasteel/dark, +/area/hallway/secondary/service) +"bKB" = ( +/obj/structure/table/wood, +/obj/machinery/reagentgrinder, +/turf/open/floor/carpet/monochrome, +/area/hallway/secondary/service) +"bKC" = ( +/obj/structure/fireplace, +/turf/open/floor/carpet/royalblack, +/area/commons/dorms) +"bKD" = ( +/obj/structure/closet/secure_closet/personal/cabinet{ + pixel_y = 15 + }, +/obj/item/coin/iron, +/turf/open/floor/carpet/royalblack, +/area/commons/dorms) +"bKE" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bKF" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/spawner/structure/window/reinforced/indestructable, +/obj/structure/sign/poster/official/foam_force_ad, +/turf/open/floor/plating, +/area/cargo/office) +"bKG" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/indestructible, +/area/cargo/office) +"bKH" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/junction/flip{ + dir = 8 + }, +/turf/open/indestructible, +/area/cargo/office) +"bKI" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/indestructible, +/area/cargo/office) +"bKJ" = ( +/obj/machinery/holopad, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/indestructible, +/area/cargo/office) +"bKK" = ( +/obj/effect/landmark/start/quartermaster, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/indestructible, +/area/cargo/office) +"bKL" = ( +/obj/structure/table/wood/fancy/green, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/turf/open/indestructible, +/area/cargo/office) +"bKM" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/table/wood/fancy/green, +/obj/item/stamp, +/obj/item/stamp/denied{ + pixel_x = 6; + pixel_y = 6 + }, +/turf/open/indestructible, +/area/cargo/office) +"bKN" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"bKO" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/disposal/bin, +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 + }, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/turf/open/indestructible, +/area/cargo/office) +"bKP" = ( +/obj/machinery/conveyor{ + dir = 4; + id = "packageSort2" + }, +/obj/structure/disposaloutlet{ + dir = 4 + }, +/obj/structure/disposalpipe/trunk, +/turf/open/floor/plating, +/area/cargo) +"bKQ" = ( +/obj/machinery/conveyor{ + dir = 4; + id = "packageSort2" + }, +/obj/effect/spawner/lootdrop/maintenance, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/floor/plating, +/area/cargo) +"bKR" = ( +/obj/machinery/conveyor{ + dir = 4; + id = "packageSort2" + }, +/obj/effect/spawner/lootdrop/maintenance, +/obj/machinery/light{ + light_color = "#e8eaff" + }, +/turf/open/floor/plating, +/area/cargo) +"bKS" = ( +/obj/machinery/conveyor{ + dir = 4; + id = "packageSort2" + }, +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/plating, +/area/cargo) +"bKT" = ( +/obj/machinery/conveyor{ + dir = 4; + id = "packageSort2" + }, +/obj/structure/plasticflaps, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating, +/area/cargo) +"bKU" = ( +/obj/machinery/disposal/deliveryChute{ + dir = 8 + }, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating, +/area/cargo) +"bKV" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bKW" = ( +/obj/structure/fluff/lightpost/light, +/turf/open/floor/grass/snow/edina, +/area/edina) +"bKX" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 5 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"bKY" = ( +/obj/effect/festive/trainrails/north, +/obj/structure/fence, +/turf/open/floor/plating/dirt/space, +/area/edina) +"bKZ" = ( +/obj/effect/festive/street/sidewalke, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bLa" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/fence, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"bLb" = ( +/obj/effect/festive/street/streetlineem, +/turf/open/floor/festive/alleyway, +/area/edina/street/primary/progress) +"bLc" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bLd" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/orange, +/area/medical/chemistry) +"bLe" = ( +/obj/machinery/smartfridge/chemistry, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bLf" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bLg" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bLh" = ( +/obj/structure/chair/office/light{ + dir = 4 + }, +/obj/effect/landmark/start/chemist, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bLi" = ( +/turf/closed/festive/whitebrick{ + color = "#ffe6a8" + }, +/area/commons/fitness) +"bLj" = ( +/obj/structure/bodycontainer/morgue, +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bLk" = ( +/obj/effect/landmark/xeno_spawn, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bLl" = ( +/obj/structure/table, +/obj/item/storage/box/bodybags, +/obj/item/pen/fountain, +/obj/machinery/camera{ + c_tag = "Morgue"; + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bLm" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bLn" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/light/small, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bLo" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/medical/cryo) +"bLp" = ( +/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/medical/cryo) +"bLq" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/medical/cryo) +"bLr" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/bed/roller, +/obj/machinery/light/small, +/obj/machinery/power/apc{ + name = "Cyrogenics APC"; + pixel_y = -28 + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bLs" = ( +/obj/structure/toilet{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/obj/machinery/door/window/southleft{ + dir = 4; + name = "Outer Window" + }, +/turf/open/floor/plasteel/freezer, +/area/medical/storage) +"bLt" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/carpet/purple, +/area/medical/storage) +"bLu" = ( +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/commons/locker) +"bLv" = ( +/obj/machinery/light/small, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/machinery/button/door{ + id = "patientA"; + name = "Privacy Shutters"; + pixel_y = -25 + }, +/turf/open/floor/carpet/purple, +/area/medical/storage) +"bLw" = ( +/obj/machinery/door/airlock/medical{ + name = "Patient Room A"; + req_access_txt = "5" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/purple, +/area/medical/storage) +"bLx" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bLy" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/medical/storage) +"bLz" = ( +/obj/item/storage/firstaid/regular{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/item/storage/firstaid/toxin{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/firstaid/toxin, +/obj/item/storage/firstaid/toxin{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/door/window/eastleft{ + name = "First-Aid Supplies"; + req_access_txt = "5" + }, +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/sign/poster/official/cleanliness{ + pixel_x = -32 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bLA" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bLB" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bLC" = ( +/obj/machinery/requests_console{ + department = "Medbay"; + departmentType = 1; + name = "Medbay RC"; + pixel_x = 30 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/disposal/bin{ + pixel_x = 5 + }, +/obj/structure/disposalpipe/trunk, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bLD" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bLE" = ( +/turf/closed/festive/whitebrick{ + color = "#ffe6a8" + }, +/area/medical/storage) +"bLF" = ( +/obj/machinery/smartfridge/chemistry, +/turf/closed/wall/mineral/wood, +/area/medical/chemistry) +"bLG" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Chemistry Lab"; + req_access_txt = "5; 33" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bLH" = ( +/obj/effect/spawner/structure/window, +/obj/structure/curtain{ + color = "#FF5555" + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "chemistry_shutters"; + name = "chemistry shutters" + }, +/obj/effect/decal/festive/holly, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bLI" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = -28 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bLJ" = ( +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 28; + pixel_y = 5 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bLK" = ( +/obj/machinery/door/airlock/wood/glass, +/obj/effect/decal/festive/mistletoe, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/plasteel/dark, +/area/service/bar/atrium) +"bLL" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bLM" = ( +/turf/open/floor/festive/stairs/stairseast, +/area/service/bar/atrium) +"bLN" = ( +/obj/structure/bed/dogbed{ + name = "cat bed" + }, +/mob/living/simple_animal/pet/dog/corgi/puppy, +/turf/open/floor/grass, +/area/edina/crew_quarters/store/pet) +"bLO" = ( +/obj/item/stack/sheet/bone, +/turf/open/floor/grass, +/area/edina/crew_quarters/store/pet) +"bLP" = ( +/mob/living/simple_animal/pet/dog/corgi/Lisa, +/turf/open/floor/grass, +/area/edina/crew_quarters/store/pet) +"bLQ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/festive/trainplatform/edge_west, +/turf/open/floor/plating/dirt/space, +/area/edina) +"bLR" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/shaker, +/obj/item/book/granter/action/drink_fling, +/obj/item/stack/spacecash/c100, +/turf/open/floor/carpet/monochrome, +/area/hallway/secondary/service) +"bLS" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = 24 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"bLT" = ( +/obj/structure/bed, +/obj/item/bedsheet/random, +/turf/open/floor/carpet/royalblack, +/area/commons/dorms) +"bLU" = ( +/obj/machinery/light, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel/white, +/area/service/janitor) +"bLV" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/indestructible, +/area/cargo/office) +"bLW" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/office) +"bLX" = ( +/turf/open/indestructible, +/area/cargo/office) +"bLY" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/indestructible, +/area/cargo/office) +"bLZ" = ( +/obj/structure/table/wood/fancy/green, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/window/westleft{ + name = "Cargo Desk"; + req_access_txt = "50" + }, +/turf/open/indestructible, +/area/cargo/office) +"bMa" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/chair/office/dark{ + dir = 8 + }, +/turf/open/indestructible, +/area/cargo/office) +"bMb" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/structure/sign/warning/enginesafety{ + pixel_x = -32 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"bMc" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/festive/greybrick, +/area/service/janitor) +"bMd" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"bMe" = ( +/obj/structure/disposalpipe/segment, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo) +"bMf" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/indestructible, +/area/cargo) +"bMg" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/indestructible, +/area/cargo) +"bMh" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/indestructible, +/area/cargo) +"bMi" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bMj" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bMk" = ( +/obj/machinery/door/airlock/abandoned{ + name = "Filthy Powergame Shack" + }, +/turf/open/floor/plating/dirt{ + initial_gas_mix = "o2=21.78;n2=82.36;TEMP=293.15" + }, +/area/science) +"bMl" = ( +/obj/effect/festive/trainrails/south, +/obj/structure/fence, +/turf/open/floor/plating/dirt/space, +/area/edina) +"bMm" = ( +/obj/structure/closet/cardboard, +/obj/structure/reagent_dispensers/keg/milk, +/obj/effect/turf_decal/delivery/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"bMn" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"bMo" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Chemical Factory Reception" + }, +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bMp" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bMq" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/carpet/orange, +/area/medical/chemistry) +"bMr" = ( +/obj/machinery/door/window/eastright{ + dir = 8; + name = "Chemistry Desk"; + req_access_txt = "5" + }, +/obj/machinery/door/window/eastright{ + name = "Chemistry Desk" + }, +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/grass/snow/edina, +/area/medical/chemistry) +"bMs" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bMt" = ( +/obj/effect/turf_decal/tile/yellow, +/obj/structure/table, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/item/clothing/suit/hooded/wintercoat/chemistry, +/obj/item/clothing/head/beret/chem, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bMu" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/structure/table, +/obj/machinery/reagentgrinder, +/obj/item/stack/sheet/mineral/plasma, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bMv" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/obj/machinery/disposal/bin{ + pixel_x = 5 + }, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bMw" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/machinery/chem_heater, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bMx" = ( +/obj/effect/landmark/blobstart, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bMy" = ( +/obj/structure/table, +/obj/item/folder/white, +/obj/item/clothing/gloves/color/latex, +/obj/item/storage/fancy/candle_box, +/obj/machinery/light_switch{ + pixel_x = 22 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bMz" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/closed/festive/whitebrick/whitebrickns, +/area/medical/cryo) +"bMA" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/closed/festive/whitebrick, +/area/medical/storage) +"bMB" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/medical/storage) +"bMC" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "MiniSat Exterior - Port Fore"; + dir = 8; + network = list("minisat") + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bMD" = ( +/obj/item/storage/firstaid/regular{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/item/storage/firstaid/o2{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/firstaid/o2, +/obj/item/storage/firstaid/o2{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/door/window/eastleft{ + name = "First-Aid Supplies"; + req_access_txt = "5" + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bME" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bMF" = ( +/obj/structure/chair/office/dark, +/obj/effect/landmark/start/roboticist, +/turf/open/floor/plasteel, +/area/science/robotics/lab) +"bMG" = ( +/obj/structure/closet/secure_closet/medical3, +/obj/item/screwdriver{ + pixel_y = 6 + }, +/obj/item/storage/belt/medical{ + pixel_y = 2 + }, +/obj/item/clothing/neck/stethoscope, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/suit/hooded/wintercoat/medical, +/obj/item/clothing/head/beret/med, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bMH" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bMI" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/firealarm{ + dir = 1; + pixel_y = 26 + }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bMJ" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#e8eaff" + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bMK" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/window/southleft{ + dir = 8; + icon_state = "right"; + name = "Medbay Delivery"; + req_access_txt = "28" + }, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=2"; + dir = 4; + freq = 1400; + location = "Medbay" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plating, +/area/medical/storage) +"bML" = ( +/obj/structure/plasticflaps/opaque, +/obj/effect/turf_decal/loading_area{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/medical/storage) +"bMM" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Chemistry Lab"; + req_access_txt = "5; 33" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bMN" = ( +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bMO" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bMP" = ( +/obj/machinery/chem_heater, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bMQ" = ( +/obj/machinery/computer/security/mining{ + dir = 1 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/cargo/qm) +"bMR" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/fence, +/turf/open/floor/plating/dirt/space, +/area/edina) +"bMS" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/dropper, +/obj/item/reagent_containers/glass/beaker/large, +/obj/item/storage/box/beakers, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bMT" = ( +/obj/machinery/chem_dispenser{ + layer = 2.7 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bMU" = ( +/obj/machinery/chem_heater, +/obj/structure/disposalpipe/junction/yjunction, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bMV" = ( +/obj/machinery/chem_dispenser{ + layer = 2.7 + }, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bMW" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bMX" = ( +/obj/machinery/light_switch{ + dir = 9; + pixel_x = 24; + pixel_y = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bMY" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/wood, +/area/service/bar/atrium) +"bMZ" = ( +/obj/structure/closet/crate/trashcart, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 2; + name = "2maintenance loot spawner" + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 5 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet) +"bNa" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bNb" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bNc" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"bNd" = ( +/turf/closed/wall/mineral/wood, +/area/medical/chemistry) +"bNe" = ( +/obj/structure/table/glass, +/obj/item/toy/fluff/tennis_poly/blue, +/obj/item/toy/fluff/tennis_poly/purple, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"bNf" = ( +/obj/structure/table/glass, +/obj/item/toy/cattoy, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"bNg" = ( +/obj/structure/table, +/obj/item/paper/fluff/festive/note_for_qm, +/turf/open/floor/festive/wooden/wooden2, +/area/cargo/qm) +"bNh" = ( +/turf/closed/festive/greybrick/greybrickcornerse, +/area/commons/dorms) +"bNi" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"bNj" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/structure/table/wood/fancy/red, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown, +/turf/open/indestructible, +/area/cargo/office) +"bNk" = ( +/obj/machinery/disposal/bin, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/turf/open/indestructible, +/area/cargo/office) +"bNl" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/indestructible, +/area/cargo/office) +"bNm" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/light, +/obj/structure/sign/poster/official/nanotrasen_logo{ + pixel_y = -32 + }, +/turf/open/indestructible, +/area/cargo/office) +"bNn" = ( +/obj/effect/turf_decal/caution/stand_clear{ + dir = 1; + pixel_y = -8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/indestructible, +/area/cargo/office) +"bNo" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/vending/donksofttoyvendor, +/turf/open/indestructible, +/area/cargo/office) +"bNp" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/vending/toyliberationstation, +/turf/open/indestructible, +/area/cargo/office) +"bNq" = ( +/obj/structure/table/wood/fancy/green, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/light, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/turf/open/indestructible, +/area/cargo/office) +"bNr" = ( +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/structure/sign/poster/contraband/missing_gloves{ + pixel_y = -32 + }, +/obj/machinery/photocopier, +/turf/open/indestructible, +/area/cargo/office) +"bNs" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/autolathe, +/obj/structure/sign/poster/official/cohiba_robusto_ad{ + pixel_x = 32 + }, +/turf/open/indestructible, +/area/cargo/office) +"bNt" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bNu" = ( +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/med) +"bNv" = ( +/obj/structure/sign/poster/contraband/kudzu{ + pixel_x = 32 + }, +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bNw" = ( +/obj/structure/flora/tree/pine/xmas, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/med) +"bNx" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bNy" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Cargo Bay"; + req_one_access_txt = "31;48" + }, +/obj/machinery/door/firedoor, +/turf/open/indestructible, +/area/cargo/storage) +"bNz" = ( +/obj/structure/fence/end, +/turf/open/floor/grass/snow/edina, +/area/edina) +"bNA" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"bNB" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Chemical Factory Reception" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bNC" = ( +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bND" = ( +/obj/machinery/door/window/eastright{ + dir = 8; + name = "Chemistry Desk"; + req_access_txt = "5" + }, +/obj/machinery/door/window/eastright{ + name = "Chemistry Desk" + }, +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/turf/open/floor/grass/snow/edina, +/area/medical/chemistry) +"bNE" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bNF" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/structure/table, +/obj/structure/noticeboard{ + desc = "A board for pinning important notices upon. Probably helpful for keeping track of requests."; + name = "requests board"; + pixel_x = 32 + }, +/obj/item/book/manual/wiki/cit/chemistry, +/obj/item/book/manual/wiki/cit/chem_recipies, +/obj/item/clothing/glasses/science{ + pixel_x = 2; + pixel_y = 4 + }, +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bNG" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bNH" = ( +/obj/structure/bodycontainer/morgue, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bNI" = ( +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 28 + }, +/obj/structure/chair{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bNJ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/medical/morgue) +"bNK" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bNL" = ( +/obj/machinery/door/airlock/medical{ + name = "Ambulance Bay" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bNM" = ( +/obj/structure/bed/roller, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/button/door{ + id = "weewoo"; + name = "Ambulance Garage button"; + pixel_y = 28; + req_access_txt = "5" + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bNN" = ( +/obj/effect/turf_decal/delivery/white, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/vehicle/sealed/vectorcraft/ambulance, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bNO" = ( +/obj/machinery/vending/wallmed{ + pixel_y = 28 + }, +/obj/structure/bed/roller, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bNP" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bNQ" = ( +/obj/machinery/shower{ + pixel_y = 8 + }, +/obj/structure/curtain, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/medical/storage) +"bNR" = ( +/obj/structure/closet/cabinet{ + pixel_y = 15 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/cyan, +/area/medical/storage) +"bNS" = ( +/obj/structure/bed, +/obj/machinery/button/door{ + id = "patientB"; + name = "Privacy Shutters"; + pixel_y = 25 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/item/toy/plush/random, +/obj/effect/spawner/lootdrop/bedsheet, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/carpet/cyan, +/area/medical/storage) +"bNT" = ( +/obj/effect/spawner/structure/window, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "patientB"; + name = "privacy shutters" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/cyan, +/area/medical/storage) +"bNU" = ( +/obj/machinery/vending/wallmed, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/medical/storage) +"bNV" = ( +/obj/item/storage/firstaid/regular{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/item/storage/firstaid/fire{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/firstaid/fire, +/obj/item/storage/firstaid/fire{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/door/window/eastleft{ + name = "First-Aid Supplies"; + req_access_txt = "5" + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bNW" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bNX" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/grass/snow/edina, +/area/edina) +"bNY" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bNZ" = ( +/obj/structure/closet/secure_closet/medical3, +/obj/item/screwdriver{ + pixel_y = 6 + }, +/obj/item/storage/belt/medical{ + pixel_y = 2 + }, +/obj/item/clothing/neck/stethoscope, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/suit/hooded/wintercoat/medical, +/obj/item/clothing/head/beret/med, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bOa" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bOb" = ( +/obj/machinery/airalarm, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/medical/storage) +"bOc" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Apothecary"; + req_access_txt = "5" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bOd" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bOe" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bOf" = ( +/obj/structure/window/reinforced{ + dir = 1; + pixel_y = 2 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bOg" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bOh" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "chemistry_shutters"; + name = "chemistry shutters" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bOi" = ( +/obj/structure/closet/wardrobe/chemistry_white, +/obj/item/storage/box/pillbottles, +/obj/machinery/light{ + dir = 8 + }, +/obj/item/radio/headset/headset_med, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/item/reagent_containers/glass/bottle/epinephrine{ + pixel_x = 8 + }, +/obj/item/reagent_containers/glass/bottle/toxin{ + pixel_x = 5; + pixel_y = 4 + }, +/obj/item/reagent_containers/glass/bottle/morphine, +/obj/item/reagent_containers/glass/bottle/charcoal{ + pixel_x = -5 + }, +/obj/item/reagent_containers/glass/bottle/charcoal{ + pixel_x = -5 + }, +/obj/item/storage/box/syringes, +/obj/item/storage/box/medsprays, +/obj/item/clothing/suit/hooded/wintercoat/chemistry, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/head/beret/chem, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bOj" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bOk" = ( +/obj/machinery/disposal/bin{ + pixel_x = 5 + }, +/obj/structure/disposalpipe/trunk, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bOl" = ( +/obj/structure/chair/office/light{ + dir = 1; + pixel_y = 3 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/landmark/start/chemist, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bOm" = ( +/obj/machinery/chem_master, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bOn" = ( +/obj/machinery/chem_master, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bOo" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bOp" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bOq" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall/mineral/wood, +/area/medical/chemistry) +"bOr" = ( +/turf/closed/festive/greybrick/greybrickte, +/area/service/bar/atrium) +"bOs" = ( +/obj/structure/filingcabinet, +/turf/open/floor/festive/wooden/wooden2, +/area/cargo/qm) +"bOt" = ( +/turf/closed/festive/greybrick/greybrickts, +/area/service/bar) +"bOu" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSRightEnd, +/turf/open/floor/wood, +/area/service/bar) +"bOv" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSMiddle, +/turf/open/floor/wood, +/area/service/bar) +"bOw" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSLeftEnd, +/turf/open/floor/wood, +/area/service/bar) +"bOx" = ( +/turf/closed/festive/greybrick, +/area/service/cafeteria/lunchroom) +"bOy" = ( +/turf/open/floor/plasteel/dark, +/area/service/cafeteria/lunchroom) +"bOz" = ( +/obj/structure/table/glass, +/obj/item/toy/fluff/tennis_poly/yellow, +/obj/item/toy/fluff/tennis_poly/red, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"bOB" = ( +/obj/structure/table/glass, +/obj/item/toy/plush/random, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"bOC" = ( +/obj/machinery/newscaster, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/qm) +"bOD" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina) +"bOE" = ( +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bOF" = ( +/obj/structure/fence/door/opened{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina) +"bOG" = ( +/obj/machinery/conveyor{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/end{ + dir = 1 + }, +/obj/structure/plasticflaps/opaque, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, +/area/cargo/office) +"bOH" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Delivery Office"; + req_access_txt = 0; + req_one_access_txt = "48;50" + }, +/turf/open/indestructible, +/area/cargo/office) +"bOI" = ( +/obj/effect/spawner/structure/window/reinforced/indestructable, +/turf/open/indestructible, +/area/cargo/office) +"bOJ" = ( +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"bOK" = ( +/obj/structure/sign/logo, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/office) +"bOL" = ( +/obj/structure/closet/secure_closet/quartermaster, +/obj/item/clothing/suit/hooded/wintercoat/cargo, +/obj/item/clothing/shoes/winterboots, +/obj/item/stamp/qm, +/obj/item/radio, +/obj/item/clothing/neck/scarf/orange, +/turf/open/floor/carpet/orange, +/area/cargo/qm) +"bOM" = ( +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/sorting) +"bON" = ( +/obj/structure/flora/grass/green, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/med) +"bOO" = ( +/obj/structure/closet/crate/medical, +/obj/effect/decal/festive/fairylights, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/warehouse) +"bOP" = ( +/obj/machinery/light/small, +/turf/open/indestructible, +/area/cargo/warehouse) +"bOQ" = ( +/obj/effect/turf_decal/loading_area{ + dir = 8 + }, +/turf/open/indestructible, +/area/cargo/storage) +"bOR" = ( +/obj/effect/turf_decal/delivery, +/turf/open/indestructible, +/area/cargo/storage) +"bOS" = ( +/obj/machinery/conveyor_switch{ + id = "cargocars" + }, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/obj/effect/decal/festive/fairylights, +/turf/open/indestructible, +/area/cargo/storage) +"bOT" = ( +/turf/open/floor/carpet/orange, +/area/cargo/qm) +"bOU" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/closet/crate{ + icon_state = "crateopen" + }, +/obj/effect/turf_decal/delivery, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bOV" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/closet/crate, +/obj/effect/turf_decal/delivery, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bOW" = ( +/obj/machinery/status_display/supply, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/storage) +"bOX" = ( +/obj/structure/lattice, +/turf/open/floor/grass/snow/edina, +/area/edina) +"bOY" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"bOZ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"bPa" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"bPb" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bPc" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bPd" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/orange, +/area/medical/chemistry) +"bPe" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bPf" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bPg" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bPh" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bPi" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Chemical Factory Garage"; + req_access_txt = "5; 33" + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bPj" = ( +/obj/effect/festive/street/streetlineem, +/obj/effect/festive/street/streetlinewm, +/obj/machinery/button/door{ + id = "chemistry_shutters"; + name = "chemical factory garage"; + pixel_x = 24; + pixel_y = 7; + req_access_txt = "5; 33" + }, +/turf/open/floor/plasteel, +/area/medical/chemistry) +"bPk" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/bodycontainer/morgue, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bPl" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/carpet/orange, +/area/medical/chemistry) +"bPm" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bPn" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bPo" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/grunge{ + name = "Morgue"; + req_access_txt = "6" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bPp" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bPq" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bPr" = ( +/obj/machinery/door/airlock/medical{ + name = "Ambulance Bay" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bPs" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bPt" = ( +/obj/effect/turf_decal/loading_area/white, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bPu" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bPv" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bPw" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"bPx" = ( +/obj/structure/fence/door/opened, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/science/research) +"bPy" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bPz" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/festive/whitebrick, +/area/medical/storage) +"bPA" = ( +/obj/structure/toilet{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/obj/machinery/door/window/southleft{ + dir = 4; + name = "Outer Window" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/freezer, +/area/medical/storage) +"bPB" = ( +/obj/structure/fence, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"bPC" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/carpet/cyan, +/area/medical/storage) +"bPD" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/carpet/cyan, +/area/medical/storage) +"bPE" = ( +/obj/machinery/door/airlock/medical{ + name = "Patient Room B"; + req_access_txt = "5" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/cyan, +/area/medical/storage) +"bPF" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bPG" = ( +/obj/item/storage/firstaid/regular{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/item/storage/firstaid/brute{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/firstaid/brute, +/obj/item/storage/firstaid/brute{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/structure/table/glass, +/obj/structure/window/reinforced, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/door/window/eastleft{ + name = "First-Aid Supplies"; + req_access_txt = "5" + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bPH" = ( +/obj/structure/closet/crate/trashcart, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 3; + name = "3maintenance loot spawner" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bPI" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bPJ" = ( +/obj/structure/table, +/obj/item/storage/box/syringes, +/obj/item/reagent_containers/glass/bottle/epinephrine{ + pixel_x = 7; + pixel_y = -3 + }, +/obj/item/reagent_containers/glass/bottle/morphine{ + pixel_x = 8; + pixel_y = -3 + }, +/obj/item/reagent_containers/syringe{ + pixel_x = 6; + pixel_y = -3 + }, +/obj/item/borg/sight/hud/med, +/obj/item/borg/sight/hud/med, +/obj/item/borg/sight/hud/med, +/obj/item/reagent_containers/spray/cleaner{ + pixel_x = -3; + pixel_y = 2 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/disposalpipe/junction{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bPK" = ( +/obj/item/radio/intercom{ + broadcasting = 1; + frequency = 1485; + listening = 0; + name = "Station Intercom (Medbay)"; + pixel_y = 30 + }, +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bPL" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/vending/wardrobe/medi_wardrobe, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bPM" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/closet/crate/freezer/surplus_limbs, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bPN" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/closet/crate/freezer/blood, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bPO" = ( +/obj/machinery/firealarm{ + dir = 1; + pixel_y = 26 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/closet/crate/medical, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/blue, +/obj/item/storage/belt/medolier/full, +/obj/item/gun/syringe/dart, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bPP" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/festive/whitebrick{ + color = "#ffe6a8" + }, +/area/medical/storage) +"bPQ" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/table/wood, +/obj/item/storage/box/beakers{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bPR" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/chair/office/light, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bPS" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bPT" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Apothecary"; + req_access_txt = "5" + }, +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bPU" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "chemistry_shutters"; + name = "chemistry shutters" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bPV" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/closet/wardrobe/chemistry_white, +/obj/item/storage/box/pillbottles, +/obj/item/radio/headset/headset_med, +/obj/item/reagent_containers/glass/bottle/epinephrine{ + pixel_x = 8 + }, +/obj/item/reagent_containers/glass/bottle/toxin{ + pixel_x = 5; + pixel_y = 4 + }, +/obj/item/reagent_containers/glass/bottle/morphine, +/obj/item/reagent_containers/glass/bottle/charcoal{ + pixel_x = -5 + }, +/obj/item/storage/box/syringes, +/obj/item/storage/box/medsprays, +/obj/item/clothing/suit/hooded/wintercoat/chemistry, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/head/beret/chem, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bPW" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/primary/progress) +"bPX" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bPY" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bPZ" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bQa" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/sorting/mail{ + dir = 8; + name = "Chemistry Junction"; + sortType = 11 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bQb" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bQc" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/wall/mineral/wood, +/area/medical/chemistry) +"bQd" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowWERightEnd, +/turf/open/floor/wood, +/area/service/cafeteria) +"bQe" = ( +/obj/structure/chair/sofa/right, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bQf" = ( +/obj/effect/festive/street/streetlineem, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/primary/progress) +"bQg" = ( +/obj/structure/chair/sofa/left, +/obj/machinery/light{ + dir = 1; + light_color = "#e8eaff" + }, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bQh" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 10 + }, +/turf/open/floor/holofloor/ice, +/area/edina) +"bQi" = ( +/obj/structure/closet/crate/bin{ + pixel_y = 8 + }, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bQj" = ( +/turf/closed/festive/greybrick, +/area/service/bar) +"bQk" = ( +/obj/structure/table/wood, +/obj/machinery/chem_dispenser/drinks/beer, +/obj/structure/extinguisher_cabinet{ + pixel_x = -24 + }, +/turf/open/floor/carpet/red, +/area/service/bar) +"bQl" = ( +/obj/structure/table/wood, +/obj/machinery/vending/boozeomat, +/turf/open/floor/carpet/red, +/area/service/bar) +"bQm" = ( +/obj/structure/table/wood, +/obj/machinery/chem_dispenser/drinks, +/turf/open/floor/carpet/red, +/area/service/bar) +"bQn" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/condiment/saltshaker{ + pixel_x = -10; + pixel_y = 17 + }, +/obj/item/reagent_containers/food/condiment/saltshaker{ + pixel_x = -5; + pixel_y = 17 + }, +/obj/item/reagent_containers/food/condiment/saltshaker{ + pixel_y = 17 + }, +/obj/item/reagent_containers/food/condiment/saltshaker{ + pixel_x = 5; + pixel_y = 17 + }, +/obj/item/reagent_containers/food/condiment/saltshaker{ + pixel_x = 10; + pixel_y = 17 + }, +/obj/item/reagent_containers/food/condiment/peppermill{ + pixel_x = -10; + pixel_y = 10 + }, +/obj/item/reagent_containers/food/condiment/peppermill{ + pixel_x = -5; + pixel_y = 10 + }, +/obj/item/reagent_containers/food/condiment/peppermill{ + pixel_y = 10 + }, +/obj/item/reagent_containers/food/condiment/peppermill{ + pixel_x = 5; + pixel_y = 10 + }, +/obj/item/reagent_containers/food/condiment/peppermill{ + pixel_x = 10; + pixel_y = 10 + }, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bQo" = ( +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bQp" = ( +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bQq" = ( +/obj/structure/chair/sofa/right, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bQr" = ( +/obj/structure/chair/sofa, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bQs" = ( +/obj/structure/chair/sofa/corner, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bQt" = ( +/obj/machinery/newscaster{ + pixel_y = -32 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"bQu" = ( +/obj/machinery/conveyor{ + dir = 4; + id = "robo1" + }, +/obj/effect/turf_decal/stripes/end{ + dir = 8 + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/plating, +/area/cargo/sorting) +"bQv" = ( +/obj/machinery/conveyor/inverted{ + dir = 10 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, +/area/cargo/sorting) +"bQw" = ( +/obj/structure/window/spawner/west, +/obj/machinery/conveyor_switch/oneway, +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/turf/open/indestructible, +/area/cargo/sorting) +"bQx" = ( +/obj/effect/turf_decal/caution{ + dir = 8; + pixel_x = 6 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/indestructible, +/area/cargo/sorting) +"bQy" = ( +/obj/effect/turf_decal/delivery, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/cargo/sorting) +"bQz" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"bQA" = ( +/obj/effect/festive/street/streetlineinnernw, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bQB" = ( +/obj/effect/turf_decal/caution{ + dir = 4; + pixel_x = -6 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/indestructible, +/area/cargo/sorting) +"bQC" = ( +/obj/structure/closet/crate, +/turf/open/indestructible, +/area/cargo/warehouse) +"bQD" = ( +/turf/open/floor/plating, +/area/cargo/warehouse) +"bQE" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street) +"bQF" = ( +/obj/effect/festive/street/streetlineem, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"bQG" = ( +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"bQH" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bQI" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bQJ" = ( +/obj/effect/festive/street/streetlinenorth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bQK" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bQL" = ( +/obj/structure/closet/crate/trashcart, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 3; + name = "3maintenance loot spawner" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bQM" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/button/door{ + id = "CMOgarage"; + name = "CMO's Garage Door"; + pixel_y = -28 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bQN" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/festive/street/streetlineem, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bQO" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bQP" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bQQ" = ( +/turf/open/indestructible, +/area/cargo/storage) +"bQR" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/loading_area{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bQS" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/conveyor{ + dir = 1; + id = "cargounload" + }, +/turf/open/floor/plating, +/area/cargo/storage) +"bQT" = ( +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/cargo/storage) +"bQU" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/turf/open/floor/holofloor/ice, +/area/edina) +"bQV" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"bQW" = ( +/obj/machinery/light{ + light_color = "#e8eaff" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bQX" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bQY" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bQZ" = ( +/obj/machinery/light/small, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bRa" = ( +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"bRb" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bRc" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/structure/table, +/obj/item/storage/toolbox/mechanical, +/obj/item/clothing/head/welding, +/obj/item/stack/sheet/metal/twenty, +/obj/item/hand_labeler, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bRd" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bRe" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/machinery/power/apc/auto_name{ + dir = 4; + pixel_x = 30 + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bRf" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/medical/morgue) +"bRg" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/medical/morgue) +"bRh" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/fence{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bRi" = ( +/obj/structure/fence{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bRj" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick, +/area/medical/cryo) +"bRk" = ( +/obj/structure/table/reinforced, +/obj/item/stack/medical/ointment, +/obj/item/stack/medical/gauze, +/obj/item/stack/medical/bruise_pack, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bRl" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/medical/cryo) +"bRm" = ( +/obj/structure/table/reinforced, +/obj/item/stack/medical/ointment, +/obj/item/stack/medical/gauze, +/obj/item/stack/medical/bruise_pack, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/cryo) +"bRn" = ( +/obj/effect/turf_decal/delivery/white, +/obj/machinery/food_cart, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"bRo" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/fence{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bRp" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick/whitebrickns, +/area/medical/storage) +"bRq" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + id = "loungeshutters"; + name = "privacy shutters" + }, +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRr" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + id = "loungeshutters"; + name = "privacy shutters" + }, +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRs" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick/whitebrickcornerse, +/area/medical/storage) +"bRt" = ( +/obj/effect/spawner/structure/window, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRu" = ( +/obj/machinery/light_switch{ + pixel_x = -26 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/vending/medical, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRv" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/power/apc{ + areastring = "/area/medical/storage"; + name = "Medbay Storage APC"; + pixel_y = -24 + }, +/obj/structure/cable/yellow, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRw" = ( +/obj/effect/festive/street/streetlinesouth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bRx" = ( +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/light, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRy" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/camera{ + c_tag = "Medbay Surgery"; + dir = 1; + network = list("ss13","medbay") + }, +/obj/structure/extinguisher_cabinet{ + dir = 4; + pixel_y = -27 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRz" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/door/window/eastleft{ + name = "First-Aid Supplies"; + req_access_txt = "5" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRA" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRB" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRC" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Medbay Storage"; + req_access_txt = "5" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRD" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bRE" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRF" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/chem_heater, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRG" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/chem_master, +/obj/machinery/light, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRH" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/chem_dispenser, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRI" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"bRJ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "chemistry_shutters"; + name = "chemistry shutters" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bRK" = ( +/obj/machinery/vending/wardrobe/chem_wardrobe, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bRL" = ( +/obj/machinery/rnd/production/techfab/department/medical, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bRM" = ( +/obj/structure/table/wood, +/obj/machinery/reagentgrinder, +/obj/machinery/light, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bRN" = ( +/obj/structure/table/wood, +/obj/item/clothing/glasses/science{ + pixel_x = 2; + pixel_y = 4 + }, +/obj/item/hand_labeler, +/obj/item/storage/box, +/obj/item/storage/box, +/obj/item/book/manual/wiki/cit/chem_recipies, +/obj/item/book/manual/wiki/cit/chemistry, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bRO" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bRP" = ( +/obj/structure/table/wood, +/obj/item/grenade/chem_grenade, +/obj/item/grenade/chem_grenade, +/obj/item/grenade/chem_grenade, +/obj/item/stack/cable_coil, +/obj/item/assembly/igniter{ + pixel_x = 3; + pixel_y = -7 + }, +/obj/item/assembly/timer{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/screwdriver{ + pixel_x = -2; + pixel_y = 6 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/power/apc{ + areastring = "/area/medical/chemistry"; + name = "Chemistry Lab APC"; + pixel_y = -24 + }, +/obj/structure/cable/yellow, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bRQ" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/glass/beaker/large, +/obj/machinery/light, +/obj/item/stack/sheet/mineral/plasma, +/obj/item/stack/sheet/mineral/plasma, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/extinguisher_cabinet{ + dir = 4; + pixel_y = -27 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bRR" = ( +/obj/structure/table/wood, +/obj/machinery/microwave, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bRS" = ( +/obj/machinery/vending/snack/random, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bRT" = ( +/obj/machinery/vending/coffee, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bRU" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/wall/mineral/wood, +/area/medical/chemistry) +"bRV" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowWEMiddle, +/turf/open/floor/wood, +/area/service/cafeteria) +"bRW" = ( +/obj/structure/table/wood, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bRX" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/britcup, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bRY" = ( +/obj/structure/chair/comfy/lime{ + color = "#51ad6a"; + dir = 8; + name = "cozy chair" + }, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bRZ" = ( +/obj/structure/chair/stool, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bSa" = ( +/obj/structure/table/wood, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/service/bar) +"bSb" = ( +/obj/effect/landmark/start/bartender, +/turf/open/floor/carpet/red, +/area/service/bar) +"bSc" = ( +/obj/structure/closet/cardboard, +/obj/effect/turf_decal/delivery/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"bSd" = ( +/obj/effect/festive/street/streetlinene, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bSe" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bSf" = ( +/obj/effect/festive/street/streetlinesw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bSg" = ( +/obj/structure/chair/stool, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bSh" = ( +/obj/structure/chair/comfy/brown{ + dir = 4 + }, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bSi" = ( +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bSj" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/power/apc/auto_name/east, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"bSk" = ( +/obj/structure/chair/sofa/left{ + dir = 8 + }, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bSl" = ( +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/supply) +"bSm" = ( +/obj/structure/fence{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bSn" = ( +/obj/effect/spawner/structure/window/reinforced/indestructable, +/turf/open/floor/plating, +/area/cargo/sorting) +"bSo" = ( +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, +/turf/open/indestructible, +/area/cargo/sorting) +"bSp" = ( +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/indestructible, +/area/cargo/sorting) +"bSq" = ( +/turf/open/indestructible, +/area/cargo/sorting) +"bSr" = ( +/obj/effect/landmark/start/cargo_technician, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/indestructible, +/area/cargo/sorting) +"bSs" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/cargo/sorting) +"bSt" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bSu" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"bSv" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/sorting) +"bSw" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bSx" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"bSy" = ( +/obj/effect/turf_decal/loading_area{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bSz" = ( +/obj/structure/cable/white, +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/cargo/storage) +"bSA" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"bSB" = ( +/obj/effect/festive/street/sidewalkw, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"bSC" = ( +/obj/effect/festive/street/sidewalke, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"bSD" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Chemical Factory Reception"; + req_access_txt = "5; 33" + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bSE" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/grunge{ + name = "Morgue"; + req_access_txt = "6" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/medical/morgue) +"bSF" = ( +/obj/machinery/door/poddoor/shutters, +/turf/open/floor/plasteel, +/area/medical/chemistry) +"bSG" = ( +/obj/structure/disposalpipe/junction/flip, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bSH" = ( +/obj/machinery/door/poddoor/shutters{ + id = "weewoo"; + name = "Ambulance Garage" + }, +/turf/open/floor/plasteel, +/area/medical/cryo) +"bSI" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/fence/door/opened, +/turf/open/floor/festive/alleyway, +/area/medical/medbay/aft) +"bSJ" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "chemistry_shutters"; + name = "chemistry shutters" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/medical/chemistry) +"bSK" = ( +/obj/structure/chair/sofa/right{ + dir = 1 + }, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bSL" = ( +/obj/structure/chair/sofa/left{ + dir = 1 + }, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bSM" = ( +/obj/structure/table/wood, +/turf/open/floor/plasteel/dark, +/area/service/bar) +"bSN" = ( +/obj/structure/table/wood, +/obj/item/storage/fancy/donut_box, +/turf/open/floor/plasteel/dark, +/area/service/bar) +"bSO" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/sign/poster/official/hydro_ad{ + pixel_x = 32 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bSP" = ( +/obj/effect/turf_decal/delivery, +/turf/open/indestructible, +/area/cargo/sorting) +"bSQ" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/indestructible, +/area/cargo/sorting) +"bSR" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/sorting) +"bSS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/extinguisher_cabinet{ + pixel_y = -32 + }, +/turf/open/indestructible, +/area/cargo/sorting) +"bST" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/sorting) +"bSU" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Cargo Bay"; + req_one_access_txt = "31;48" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/indestructible, +/area/cargo/storage) +"bSV" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/machinery/light, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/indestructible, +/area/cargo/sorting) +"bSW" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bSX" = ( +/obj/machinery/light/floor, +/turf/open/indestructible, +/area/cargo/storage) +"bSY" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/conveyor_switch/oneway{ + dir = 8; + id = "cargounload" + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bSZ" = ( +/obj/structure/cable/white, +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/cargo/storage) +"bTa" = ( +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/obj/structure/cable/white{ + icon_state = "0-8" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/sign/warning/vacuum, +/turf/open/floor/plating, +/area/cargo/storage) +"bTb" = ( +/obj/structure/cable/white{ + icon_state = "0-8" + }, +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/cargo/storage) +"bTc" = ( +/obj/effect/festive/street/streetlinenw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bTe" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/street/primary/progress) +"bTf" = ( +/obj/effect/festive/street/sidewalkw, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"bTg" = ( +/obj/effect/festive/street/sidewalke, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"bTh" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/machinery/door/airlock/medical/glass{ + name = "Chemical Factory Reception"; + req_access_txt = "5; 33" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/white, +/area/medical/chemistry) +"bTi" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 10 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bTj" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bTk" = ( +/obj/machinery/button/door{ + id = "rdgarage"; + name = "Director's Garage Door"; + pixel_x = -7; + pixel_y = -6; + req_access_txt = "30" + }, +/turf/closed/festive/whitebrick, +/area/command/heads_quarters/rd) +"bTl" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/medical/cryo) +"bTm" = ( +/obj/structure/chair/sofa/left, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bTn" = ( +/obj/structure/window{ + dir = 1 + }, +/obj/machinery/door/window/westright{ + name = "Pub - Staff Only"; + req_one_access_txt = "25;26;28;35" + }, +/obj/machinery/door/window/eastleft{ + name = "Pub - Staff Only"; + req_one_access_txt = "25;26;28;35" + }, +/obj/structure/table/glass, +/obj/item/reagent_containers/food/drinks/bottle/hcider{ + layer = 3.1; + pixel_x = -6; + pixel_y = 5 + }, +/obj/item/reagent_containers/food/drinks/bottle/kahlua{ + pixel_x = 9; + pixel_y = 7 + }, +/obj/item/reagent_containers/food/drinks/bottle/vodka{ + pixel_x = 2; + pixel_y = 4 + }, +/turf/open/floor/carpet/red, +/area/service/bar) +"bTo" = ( +/obj/machinery/jukebox, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bTp" = ( +/obj/structure/flora/tree/pine/xmas/presents, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bTq" = ( +/obj/structure/disposalpipe/segment, +/turf/closed/festive/whitebrick, +/area/service/hydroponics) +"bTr" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"bTs" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/holofloor/ice, +/area/edina/crew_quarters/store/pet) +"bTt" = ( +/obj/structure/flora/grass/green, +/turf/open/floor/grass/snow/edina, +/area/science) +"bTu" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plating, +/area/cargo/sorting) +"bTv" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/floor/plating, +/area/cargo/sorting) +"bTw" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plating, +/area/cargo/sorting) +"bTx" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/indestructible, +/area/cargo/storage) +"bTy" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/sorting) +"bTz" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/turf/open/indestructible, +/area/cargo/storage) +"bTA" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bTB" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/conveyor{ + dir = 9; + id = "cargoload" + }, +/turf/open/floor/plating, +/area/cargo/storage) +"bTC" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "cargounload" + }, +/obj/machinery/door/poddoor{ + id = "cargounload"; + name = "supply dock unloading door" + }, +/turf/open/floor/plating, +/area/cargo/storage) +"bTD" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "cargounload" + }, +/obj/structure/plasticflaps, +/turf/open/floor/plating, +/area/cargo/storage) +"bTE" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "cargounload" + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/door/poddoor{ + id = "cargounload"; + name = "supply dock unloading door" + }, +/turf/open/floor/plating, +/area/cargo/storage) +"bTF" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/command) +"bTG" = ( +/obj/effect/festive/street/streetlineinnernw{ + pixel_x = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"bTH" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"bTI" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/festive/street/streetlineem, +/turf/open/floor/festive/alleyway, +/area/edina/street/primary/progress) +"bTJ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"bTK" = ( +/obj/item/reagent_containers/food/condiment/saltshaker{ + pixel_x = -9; + pixel_y = 15 + }, +/obj/item/reagent_containers/food/condiment/peppermill{ + pixel_x = -9; + pixel_y = 8 + }, +/obj/structure/table/wood, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bTL" = ( +/obj/structure/window, +/obj/machinery/door/window/westleft{ + name = "Pub - Staff Only"; + req_one_access_txt = "25;26;28;35" + }, +/obj/machinery/door/window/eastright{ + name = "Pub - Staff Only"; + req_one_access_txt = "25;26;28;35" + }, +/obj/structure/table/glass, +/obj/item/reagent_containers/food/drinks/bottle/wine{ + layer = 3.1; + pixel_x = 6; + pixel_y = 5 + }, +/obj/item/reagent_containers/food/drinks/shaker{ + pixel_x = 1; + pixel_y = 8 + }, +/obj/item/reagent_containers/food/drinks/bottle/whiskey{ + pixel_x = 7; + pixel_y = 16 + }, +/obj/item/reagent_containers/food/drinks/bottle/gin{ + pixel_x = -10; + pixel_y = 15 + }, +/obj/item/reagent_containers/food/drinks/bottle/goldschlager{ + pixel_x = -8; + pixel_y = 15 + }, +/obj/item/reagent_containers/food/drinks/bottle/cognac{ + pixel_x = -7; + pixel_y = 5 + }, +/turf/open/floor/carpet/red, +/area/service/bar) +"bTM" = ( +/turf/closed/festive/greybrick, +/area/service/kitchen/coldroom) +"bTN" = ( +/obj/structure/sign/mining{ + pixel_x = 32; + pixel_y = 32 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bTO" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bTP" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bTQ" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWEMiddle, +/turf/open/indestructible, +/area/cargo/storage) +"bTR" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bTS" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/airlock/external{ + name = "Supply Dock Airlock"; + req_access_txt = "31" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bTT" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bTU" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/airlock/external{ + name = "Supply Dock Airlock"; + req_access_txt = "31" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bTV" = ( +/obj/effect/festive/street/streetlineinnernw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bTW" = ( +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bTX" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"bTY" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/docking_port/stationary{ + dir = 4; + dwidth = 5; + height = 7; + id = "supply_home"; + name = "Cargo Bay"; + width = 12 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"bTZ" = ( +/obj/structure/toilet/secret/low_loot, +/obj/structure/window/spawner/east, +/obj/machinery/door/window/southleft, +/obj/machinery/door/window/southright, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/commons/fitness) +"bUa" = ( +/obj/structure/toilet, +/obj/machinery/door/window/southright, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/commons/fitness) +"bUb" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bUc" = ( +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bUd" = ( +/turf/closed/festive/whitebrick{ + color = "#fff200" + }, +/area/service/theater) +"bUe" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/disposalpipe/junction, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bUf" = ( +/turf/closed/festive/whitebrick{ + color = "#993e28" + }, +/area/commons/lounge) +"bUg" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Curator Access"; + req_access_txt = "37" + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bUh" = ( +/turf/closed/festive/whitebrick{ + color = "#993e28" + }, +/area/service/library) +"bUi" = ( +/obj/effect/decal/festive/red_stockings, +/turf/closed/festive/whitebrick{ + color = "#993e28" + }, +/area/service/library) +"bUj" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/rag/towel, +/turf/open/floor/plasteel/dark, +/area/service/bar) +"bUk" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 28; + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"bUl" = ( +/obj/structure/chair/sofa/left{ + dir = 4 + }, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bUm" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/britcup, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bUn" = ( +/obj/structure/chair/sofa/right{ + dir = 8 + }, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bUo" = ( +/obj/machinery/icecream_vat, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bUp" = ( +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bUq" = ( +/obj/machinery/vending/wardrobe/chef_wardrobe, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bUr" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Hotel" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bUs" = ( +/obj/machinery/button/door{ + id = "QMgarage"; + name = "Garage door button"; + pixel_y = -4 + }, +/turf/closed/festive/greybrick, +/area/service/kitchen) +"bUt" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/turf/open/indestructible, +/area/cargo/storage) +"bUu" = ( +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bUv" = ( +/obj/machinery/button/door{ + id = "cargounload"; + layer = 4; + name = "Loading Doors"; + pixel_x = 24; + pixel_y = 8 + }, +/obj/machinery/button/door{ + id = "cargoload"; + layer = 4; + name = "Loading Doors"; + pixel_x = 24; + pixel_y = -8 + }, +/obj/machinery/computer/cargo{ + dir = 8 + }, +/obj/machinery/camera{ + c_tag = "Cargo Bay - Starboard"; + dir = 8; + name = "cargo camera" + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bUw" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/cargo/storage) +"bUx" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"bUy" = ( +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/obj/structure/cable/white, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/cargo/storage) +"bUz" = ( +/obj/structure/statue/snow/snowman, +/turf/open/floor/grass/snow/edina, +/area/edina) +"bUA" = ( +/obj/effect/festive/street/streetlinese, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bUB" = ( +/obj/effect/festive/street/sidewalknsm, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bUC" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bUD" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bUE" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"bUF" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"bUG" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"bUH" = ( +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"bUI" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"bUJ" = ( +/turf/closed/festive/whitebrick{ + color = "#ffe6a8" + }, +/area/commons/fitness/pool) +"bUK" = ( +/obj/structure/table/wood, +/obj/item/instrument/eguitar, +/obj/item/toy/crayon/spraycan/lubecan{ + charges = 5 + }, +/obj/structure/sign/poster/contraband/clown{ + pixel_y = 32 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/service/theater) +"bUL" = ( +/obj/machinery/vending/autodrobe, +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/power/apc{ + areastring = "/area/service/theater"; + dir = 1; + name = "Theatre Backstage APC"; + pixel_y = 24 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/service/theater) +"bUM" = ( +/obj/structure/sign/poster/contraband/random{ + pixel_y = 32 + }, +/obj/structure/closet/crate/wooden/toy, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/item/stack/sheet/mineral/wood/fifty, +/turf/open/floor/plasteel, +/area/service/theater) +"bUN" = ( +/obj/structure/table/wood, +/obj/structure/extinguisher_cabinet{ + pixel_x = 26 + }, +/obj/item/storage/crayons, +/obj/item/storage/crayons, +/obj/item/flashlight/lamp/bananalamp{ + pixel_y = 5 + }, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_y = 26 + }, +/obj/item/toy/figure/clown, +/obj/item/clipboard, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/service/theater) +"bUO" = ( +/obj/effect/landmark/start/librarian, +/turf/open/indestructible/hoteltile, +/area/commons/lounge) +"bUP" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/toilet{ + dir = 8 + }, +/turf/open/indestructible/hoteltile, +/area/commons/lounge) +"bUQ" = ( +/obj/structure/sign/departments/restroom, +/turf/closed/festive/whitebrick{ + color = "#993e28" + }, +/area/commons/lounge) +"bUR" = ( +/obj/machinery/vending/coffee, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bUS" = ( +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bUT" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bUU" = ( +/obj/machinery/computer/libraryconsole{ + pixel_y = 8 + }, +/obj/structure/table/wood/fancy/red, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bUV" = ( +/obj/machinery/airalarm{ + pixel_y = 22 + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bUW" = ( +/obj/machinery/power/apc/auto_name/north, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bUX" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bUY" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/computer/libraryconsole/bookmanagement{ + pixel_y = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/window/spawner/west, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bUZ" = ( +/obj/machinery/libraryscanner, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bVa" = ( +/obj/machinery/newscaster{ + pixel_y = 32 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bVb" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bVc" = ( +/obj/machinery/bookbinder, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bVd" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk, +/obj/structure/window/spawner/east, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bVe" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp/green{ + pixel_x = 1; + pixel_y = 5 + }, +/obj/machinery/newscaster{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/grimy, +/area/commons/lounge) +"bVf" = ( +/obj/structure/table/wood, +/obj/item/folder, +/obj/item/folder, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = 30 + }, +/turf/open/floor/plasteel/grimy, +/area/commons/lounge) +"bVg" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp/green{ + pixel_x = 1; + pixel_y = 5 + }, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = 30 + }, +/turf/open/floor/plasteel/grimy, +/area/commons/lounge) +"bVh" = ( +/obj/structure/table/wood, +/obj/machinery/newscaster{ + pixel_y = 32 + }, +/obj/item/folder, +/obj/item/folder, +/turf/open/floor/plasteel/grimy, +/area/commons/lounge) +"bVi" = ( +/obj/machinery/vending/games, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"bVj" = ( +/turf/open/floor/carpet/green, +/area/service/library) +"bVk" = ( +/obj/structure/chair/wood, +/turf/open/floor/carpet/green, +/area/service/library) +"bVl" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/carpet/green, +/area/service/library) +"bVm" = ( +/obj/effect/festive/street/streetlinewest{ + pixel_x = -1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bVn" = ( +/obj/effect/festive/street/streetlinese, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bVo" = ( +/turf/closed/festive/greybrick, +/area/service/janitor) +"bVp" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"bVq" = ( +/obj/effect/festive/street/streetlinesw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bVr" = ( +/obj/structure/flora/grass/green, +/turf/open/floor/grass/snow/edina, +/area/medical/medbay/aft) +"bVs" = ( +/obj/structure/table/wood, +/obj/machinery/light, +/turf/open/floor/plasteel/dark, +/area/service/bar) +"bVt" = ( +/obj/structure/chair/sofa/right{ + dir = 4 + }, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bVu" = ( +/obj/structure/chair/sofa/left{ + dir = 8 + }, +/obj/machinery/light, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bVv" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/condiment/saltshaker{ + pixel_y = 17 + }, +/obj/item/reagent_containers/food/condiment/peppermill{ + pixel_y = 10 + }, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"bVw" = ( +/obj/effect/festive/street/streetlinenm, +/obj/vehicle/ridden/janicart, +/obj/item/key/janitor, +/turf/open/indestructible, +/area/service/janitor) +"bVx" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"bVy" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"bVz" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"bVA" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/chair/stool, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"bVB" = ( +/obj/structure/kitchenspike, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bVC" = ( +/obj/machinery/gibber, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bVD" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/closed/festive/redbrick, +/area/security/checkpoint/supply) +"bVE" = ( +/obj/machinery/conveyor/inverted{ + dir = 6; + id = "cargocars" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bVF" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSRightEnd, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/festive/redbrick, +/area/security/checkpoint/supply) +"bVG" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSMiddle, +/turf/closed/festive/redbrick, +/area/security/checkpoint/supply) +"bVH" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bVI" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSLeft, +/turf/closed/festive/redbrick, +/area/security/checkpoint/supply) +"bVJ" = ( +/turf/closed/festive/redbrick, +/area/security/checkpoint/supply) +"bVK" = ( +/obj/effect/festive/street/streetlinese, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bVL" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"bVM" = ( +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/indestructible, +/area/cargo/storage) +"bVN" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/airlock/external{ + name = "Supply Dock Airlock"; + req_access_txt = "31" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bVO" = ( +/obj/machinery/door/airlock/maintenance, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"bVP" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/closet/athletic_mixed, +/obj/item/toy/poolnoodle/blue, +/obj/effect/decal/festive/fairylights{ + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"bVQ" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/closet/athletic_mixed, +/obj/item/toy/poolnoodle/red, +/obj/effect/decal/festive/christmas_ivy_string{ + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"bVR" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/obj/structure/closet/athletic_mixed, +/obj/item/toy/poolnoodle/yellow, +/obj/effect/decal/festive/fairylights{ + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"bVS" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/closet/athletic_mixed, +/obj/item/toy/poolnoodle/blue, +/obj/effect/decal/festive/christmas_ivy_string{ + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"bVT" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/light_switch{ + pixel_y = 30 + }, +/obj/structure/table/glass, +/obj/effect/decal/festive/fairylights{ + pixel_y = 32 + }, +/obj/structure/bedsheetbin/towel, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"bVU" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/service/theater) +"bVV" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/service/theater) +"bVW" = ( +/obj/effect/landmark/start/clown, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/service/theater) +"bVX" = ( +/obj/structure/sink{ + dir = 8; + pixel_x = -12; + pixel_y = 2 + }, +/obj/structure/mirror{ + pixel_x = -24 + }, +/turf/open/indestructible/hoteltile, +/area/commons/lounge) +"bVY" = ( +/turf/open/indestructible/hoteltile, +/area/commons/lounge) +"bVZ" = ( +/obj/machinery/door/airlock{ + name = "Unisex Restroom" + }, +/turf/open/indestructible/hoteltile, +/area/commons/lounge) +"bWa" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bWb" = ( +/obj/machinery/photocopier, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bWc" = ( +/obj/structure/chair/wood{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bWd" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bWe" = ( +/obj/machinery/door/window/westright, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bWf" = ( +/obj/structure/chair/office/light, +/obj/effect/landmark/start/librarian, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bWg" = ( +/obj/structure/disposalpipe/junction{ + dir = 1 + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bWh" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bWi" = ( +/obj/machinery/door/window/eastleft, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bWj" = ( +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bWk" = ( +/turf/open/floor/plasteel/grimy, +/area/commons/lounge) +"bWl" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Games Room" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"bWm" = ( +/obj/structure/chair/wood{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/service/library) +"bWn" = ( +/obj/structure/table/wood/fancy/red, +/turf/open/indestructible/hotelwood, +/area/service/library) +"bWo" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/service/library) +"bWp" = ( +/obj/structure/chair/wood{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/service/library) +"bWq" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick{ + color = "#993e28" + }, +/area/service/library) +"bWr" = ( +/obj/structure/cable/yellow, +/turf/open/floor/carpet/red, +/area/service/bar) +"bWs" = ( +/turf/closed/festive/greybrick, +/area/service/kitchen) +"bWt" = ( +/obj/machinery/door/window/westright{ + dir = 1; + name = "Pub - Staff Only"; + req_one_access_txt = "25;26;28;35" + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/service/kitchen) +"bWu" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bWv" = ( +/obj/machinery/conveyor{ + dir = 1; + id = "cargocars" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bWw" = ( +/obj/structure/kitchenspike, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bWx" = ( +/obj/structure/reagent_dispensers/cooking_oil, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bWy" = ( +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo) +"bWz" = ( +/turf/closed/festive/whitebrick, +/area/commons/dorms) +"bWA" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/supply) +"bWB" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bWC" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bWD" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bWE" = ( +/obj/effect/festive/street/streetlinesouth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bWF" = ( +/obj/machinery/door/airlock/freezer{ + name = "Freezer"; + req_one_access_txt = "25;26;28;35" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bWG" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/landmark/start/virologist, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"bWH" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bWI" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bWJ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bWK" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bWL" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/conveyor{ + dir = 5; + id = "cargoload" + }, +/turf/open/floor/plating, +/area/cargo/storage) +"bWM" = ( +/obj/machinery/conveyor{ + dir = 4; + id = "cargoload" + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/poddoor{ + id = "cargoload"; + name = "supply dock loading door" + }, +/turf/open/floor/plating, +/area/cargo/storage) +"bWN" = ( +/obj/machinery/conveyor{ + dir = 4; + id = "cargoload" + }, +/obj/structure/plasticflaps, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/cargo/storage) +"bWO" = ( +/obj/machinery/conveyor{ + dir = 4; + id = "cargoload" + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/poddoor{ + id = "cargoload"; + name = "supply dock loading door" + }, +/turf/open/floor/plating, +/area/cargo/storage) +"bWP" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/structure/closet/athletic_mixed, +/obj/item/toy/poolnoodle/yellow, +/obj/effect/decal/festive/fairylights{ + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"bWQ" = ( +/obj/machinery/status_display{ + pixel_x = -32 + }, +/obj/structure/chair/wood/wings{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/service/theater) +"bWR" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/service/theater) +"bWS" = ( +/obj/structure/mirror{ + pixel_x = 30 + }, +/obj/structure/dresser, +/turf/open/floor/festive/wooden/wooden1, +/area/service/theater) +"bWT" = ( +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bWU" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bWV" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bWW" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bWX" = ( +/obj/structure/table/wood/fancy/green, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bWY" = ( +/obj/structure/table/wood/fancy/green, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/obj/structure/disposalpipe/segment, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bWZ" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bXa" = ( +/obj/machinery/door/morgue{ + name = "Study #1" + }, +/turf/open/floor/plasteel/grimy, +/area/commons/lounge) +"bXb" = ( +/obj/machinery/door/morgue{ + name = "Study #2" + }, +/turf/open/floor/plasteel/grimy, +/area/commons/lounge) +"bXc" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/service/library) +"bXd" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/service/library) +"bXe" = ( +/obj/structure/chair/wood{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/turf/open/floor/carpet/green, +/area/service/library) +"bXf" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick{ + color = "#993e28" + }, +/area/service/library) +"bXg" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowWELeftEnd, +/turf/open/floor/wood, +/area/service/cafeteria) +"bXh" = ( +/obj/machinery/light, +/obj/structure/chair/sofa/right{ + dir = 1 + }, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bXi" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Service"; + req_one_access_txt = "25;26;28;35" + }, +/turf/open/floor/plasteel/dark, +/area/service/bar) +"bXj" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bXk" = ( +/obj/structure/table, +/obj/machinery/microwave{ + pixel_x = 2; + pixel_y = 10 + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bXl" = ( +/obj/structure/table, +/obj/machinery/microwave{ + pixel_x = -6; + pixel_y = 10 + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bXm" = ( +/obj/structure/sink/kitchen{ + pixel_y = 26 + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bXn" = ( +/obj/machinery/vending/dinnerware, +/obj/structure/extinguisher_cabinet{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bXo" = ( +/obj/machinery/chem_master/condimaster{ + name = "CondiMaster Neo" + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bXp" = ( +/obj/effect/festive/street/streetlinenm{ + pixel_y = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"bXq" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessservitor) +"bXr" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessservitor) +"bXs" = ( +/obj/effect/festive/street/sidewalkw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"bXt" = ( +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"bXu" = ( +/obj/structure/table, +/obj/item/storage/box/monkeycubes{ + pixel_y = 5 + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bXv" = ( +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/obj/machinery/door/window/westleft{ + name = "Freezer Delivery"; + req_access_txt = "28" + }, +/mob/living/simple_animal/hostile/retaliate/goat{ + name = "Pete" + }, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bXw" = ( +/turf/closed/festive/bluebrick/bluebrickwe, +/area/commons/dorms) +"bXx" = ( +/obj/structure/sink{ + dir = 8; + pixel_x = -12 + }, +/obj/structure/mirror{ + pixel_y = 32 + }, +/turf/open/indestructible/hoteltile, +/area/cargo) +"bXy" = ( +/obj/structure/sign/poster/official/cleanliness{ + pixel_x = 32 + }, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/indestructible/hoteltile, +/area/cargo) +"bXz" = ( +/obj/effect/landmark/start/geneticist, +/turf/open/floor/plasteel/white, +/area/medical/genetics) +"bXA" = ( +/obj/structure/bed/double, +/obj/item/bedsheet/cmo/double, +/turf/open/floor/carpet/royalblack, +/area/command/heads_quarters/cmo) +"bXB" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bXC" = ( +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=4"; + dir = 4; + freq = 1400; + location = "QM #1" + }, +/obj/effect/turf_decal/delivery, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bXD" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bXE" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bXF" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/conveyor_switch/oneway{ + id = "cargoload" + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bXG" = ( +/obj/machinery/conveyor{ + dir = 1; + id = "cargoload" + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/cargo/storage) +"bXH" = ( +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/cargo/storage) +"bXI" = ( +/obj/structure/cable/white{ + icon_state = "0-8" + }, +/obj/structure/cable/white, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/cargo/storage) +"bXJ" = ( +/obj/machinery/door/airlock/bananium{ + name = "Clown House"; + req_access_txt = "46" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/festive/wooden/wooden1, +/area/service/theater) +"bXK" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/service/theater) +"bXL" = ( +/obj/machinery/newscaster{ + pixel_x = 32 + }, +/obj/structure/fireplace{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/service/theater) +"bXM" = ( +/obj/structure/closet/crate/trashcart, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 3; + name = "3maintenance loot spawner" + }, +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bXN" = ( +/obj/structure/closet/crate/trashcart, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 3; + name = "3maintenance loot spawner" + }, +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bXO" = ( +/obj/structure/bookcase/random/religion, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bXP" = ( +/obj/structure/bookcase/random/nonfiction, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bXQ" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bXR" = ( +/turf/open/indestructible, +/area/commons/lounge) +"bXS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/disposalpipe/segment, +/turf/open/indestructible, +/area/commons/lounge) +"bXT" = ( +/obj/structure/extinguisher_cabinet{ + dir = 4; + pixel_x = -5; + pixel_y = 27 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bXU" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bXV" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Library" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bXW" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"bXX" = ( +/obj/structure/chair/wood{ + dir = 1 + }, +/turf/open/floor/carpet/green, +/area/service/library) +"bXY" = ( +/turf/closed/festive/greybrick/greybrickte, +/area/service/cafeteria) +"bXZ" = ( +/obj/structure/chair/sofa/right, +/turf/open/floor/carpet/royalblack, +/area/commons/dorms) +"bYa" = ( +/obj/structure/chair/sofa/left, +/turf/open/floor/carpet/royalblack, +/area/commons/dorms) +"bYb" = ( +/turf/closed/festive/greybrick, +/area/service/cafeteria) +"bYc" = ( +/turf/open/floor/plasteel/stairs/left, +/area/service/cafeteria) +"bYd" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/carpet/red, +/area/service/bar) +"bYe" = ( +/obj/machinery/door/window/westleft{ + dir = 1; + name = "Pub - Staff Only"; + req_one_access_txt = "25;26;28;35" + }, +/turf/open/floor/plasteel/stairs, +/area/service/bar) +"bYf" = ( +/obj/effect/landmark/start/cook, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bYg" = ( +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bYh" = ( +/obj/machinery/smartfridge/food, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bYi" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"bYj" = ( +/obj/structure/grille, +/obj/structure/festive/bluebrick/windowWERightEnd, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bYk" = ( +/obj/structure/toilet{ + dir = 4 + }, +/turf/open/indestructible/hoteltile, +/area/cargo) +"bYl" = ( +/turf/open/indestructible/hoteltile, +/area/cargo) +"bYm" = ( +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/supply) +"bYn" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/carpet/red, +/area/service/bar) +"bYo" = ( +/obj/effect/landmark/start/chief_medical_officer, +/turf/open/floor/carpet/royalblack, +/area/command/heads_quarters/cmo) +"bYp" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/green, +/area/service/cafeteria) +"bYq" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=4"; + dir = 4; + freq = 1400; + location = "QM #2" + }, +/obj/effect/turf_decal/delivery, +/mob/living/simple_animal/bot/mulebot{ + home_destination = "QM #3"; + suffix = "#3" + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bYr" = ( +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bYs" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bYt" = ( +/obj/machinery/door/airlock/silver{ + name = "Mime House"; + req_access_txt = "46" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/festive/wooden/wooden1, +/area/service/theater) +"bYu" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/service/theater) +"bYv" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/festive/wooden/wooden1, +/area/service/theater) +"bYw" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/item/radio/intercom{ + pixel_y = 25 + }, +/obj/effect/decal/festive/christmas_ivy_string{ + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"bYx" = ( +/turf/open/floor/carpet/red, +/area/commons/lounge) +"bYy" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/disposalpipe/segment, +/turf/open/floor/carpet/red, +/area/commons/lounge) +"bYz" = ( +/turf/open/floor/carpet/royalblue, +/area/service/cafeteria) +"bYA" = ( +/obj/machinery/light{ + dir = 1; + light_color = "#e8eaff" + }, +/turf/open/floor/carpet/royalblue, +/area/service/cafeteria) +"bYB" = ( +/turf/open/floor/carpet/orange, +/area/service/bar) +"bYC" = ( +/obj/structure/closet/secure_closet/freezer/meat, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bYD" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/condiment/saltshaker{ + pixel_x = -9; + pixel_y = 9 + }, +/obj/item/reagent_containers/food/condiment/peppermill{ + dir = 1; + pixel_x = -3 + }, +/obj/item/sharpener{ + pixel_x = 10 + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bYE" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bYF" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bYG" = ( +/obj/structure/table, +/obj/machinery/reagentgrinder{ + desc = "Used to grind things up into raw materials and liquids."; + pixel_x = -5; + pixel_y = 5 + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bYH" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"bYI" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"bYJ" = ( +/obj/structure/extinguisher_cabinet{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bYK" = ( +/obj/structure/reagent_dispensers/keg/gargle, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bYL" = ( +/obj/structure/grille, +/obj/structure/festive/bluebrick/windowWEMiddle, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"bYM" = ( +/obj/machinery/door/airlock{ + name = "Bathroom" + }, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"bYN" = ( +/obj/effect/spawner/structure/window/reinforced/indestructable, +/turf/open/floor/plating, +/area/cargo) +"bYO" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=4"; + dir = 4; + freq = 1400; + location = "QM #3" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bYP" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bYQ" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bYR" = ( +/obj/structure/chair/wood/wings{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Kitchen"; + dir = 4; + name = "service camera" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/service/theater) +"bYS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/service/theater) +"bYT" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/wooden/wooden1, +/area/service/theater) +"bYU" = ( +/obj/machinery/door/airlock/grunge{ + name = "Garage"; + req_access_txt = "46" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/service/theater) +"bYV" = ( +/obj/machinery/button/door{ + id = "clowngarage"; + name = "Garage Door"; + pixel_x = 28 + }, +/turf/open/floor/plasteel, +/area/service/theater) +"bYW" = ( +/obj/effect/spawner/structure/window/reinforced/indestructable, +/turf/open/floor/plating, +/area/commons/lounge) +"bYX" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bYY" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bYZ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"bZa" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/light/small, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bZb" = ( +/obj/structure/displaycase/clown, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/commons/lounge) +"bZc" = ( +/obj/structure/displaycase/captain, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/red, +/area/commons/lounge) +"bZd" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/carpet/red, +/area/commons/lounge) +"bZe" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/carpet/red, +/area/commons/lounge) +"bZf" = ( +/obj/structure/displaycase/labcage, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/carpet/red, +/area/commons/lounge) +"bZg" = ( +/obj/structure/displaycase/trophy, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/commons/lounge) +"bZh" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"bZi" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWERightEnd, +/turf/open/floor/plating, +/area/commons/lounge) +"bZj" = ( +/obj/machinery/vending/wardrobe/curator_wardrobe, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"bZk" = ( +/obj/structure/destructible/cult/tome, +/obj/item/book/codex_gigas, +/obj/machinery/light_switch{ + pixel_y = 26 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"bZl" = ( +/obj/machinery/airalarm{ + pixel_y = 22 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"bZm" = ( +/obj/machinery/power/apc/auto_name/north, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"bZn" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/door/window/southleft{ + dir = 8; + icon_state = "right"; + name = "Library Delivery"; + req_access_txt = "37" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) +"bZo" = ( +/obj/effect/turf_decal/bot, +/obj/structure/plasticflaps/opaque, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) +"bZp" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowWELeft, +/turf/open/floor/plasteel/dark, +/area/service/cafeteria) +"bZq" = ( +/obj/structure/window{ + dir = 1 + }, +/obj/structure/window, +/obj/machinery/door/window/westleft{ + name = "Cloakroom Three"; + req_one_access_txt = "25;26;28;35" + }, +/obj/structure/rack, +/turf/open/floor/carpet/orange, +/area/service/bar) +"bZr" = ( +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/structure/disposalpipe/segment, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bZs" = ( +/obj/machinery/deepfryer, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"bZt" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"bZu" = ( +/obj/structure/reagent_dispensers/keg/mead, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bZv" = ( +/obj/structure/closet/crate/freezer{ + desc = "A small crate with a cooling system, keeps fresh produce chilled."; + name = "Food Chiller" + }, +/obj/item/storage/box/ingredients/american, +/obj/item/storage/box/ingredients/american, +/obj/item/storage/box/ingredients/delights, +/obj/item/storage/box/ingredients/delights, +/obj/item/storage/box/ingredients/fruity, +/obj/item/storage/box/ingredients/fruity, +/obj/item/storage/box/ingredients/italian, +/obj/item/storage/box/ingredients/italian, +/obj/item/storage/box/ingredients/wildcard, +/obj/item/storage/box/ingredients/wildcard, +/obj/item/storage/box/ingredients/wildcard, +/obj/item/storage/box/ingredients/wildcard, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"bZw" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/structure/chair, +/obj/effect/landmark/start/quartermaster, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"bZx" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"bZy" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/structure/sink/kitchen{ + name = "utility sink"; + pixel_y = 28 + }, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"bZz" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/structure/table, +/obj/machinery/microwave{ + pixel_y = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/structure/sign/poster/official/soft_cap_pop_art{ + pixel_y = 32 + }, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"bZA" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"bZB" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/vending/snack/green, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"bZC" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/vending/cola/black, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"bZD" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"bZE" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bZF" = ( +/obj/structure/closet/wardrobe/cargotech, +/obj/item/clothing/suit/hooded/wintercoat/cargo, +/obj/item/clothing/under/color/brown, +/obj/item/clothing/shoes/winterboots, +/obj/effect/turf_decal/tile/brown, +/obj/item/radio, +/obj/item/clothing/neck/scarf/orange, +/obj/effect/decal/festive/red_stockings, +/turf/open/indestructible, +/area/commons/locker) +"bZG" = ( +/obj/structure/closet/wardrobe/cargotech, +/obj/item/clothing/suit/hooded/wintercoat/cargo, +/obj/item/clothing/shoes/winterboots, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/item/stamp/qm, +/obj/item/radio, +/obj/item/clothing/neck/scarf/orange, +/obj/structure/closet/secure_closet/quartermaster, +/obj/effect/decal/festive/red_stockings, +/turf/open/indestructible, +/area/commons/locker) +"bZH" = ( +/obj/machinery/vending/wardrobe/cargo_wardrobe, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/indestructible, +/area/commons/locker) +"bZI" = ( +/obj/structure/closet/wardrobe/cargotech, +/obj/item/clothing/suit/hooded/wintercoat/cargo, +/obj/item/clothing/shoes/winterboots, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/item/stamp/qm, +/obj/item/radio, +/obj/item/clothing/neck/scarf/orange, +/turf/open/indestructible, +/area/commons/locker) +"bZJ" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp/green{ + on = 0; + pixel_x = -7; + pixel_y = 12 + }, +/turf/open/floor/carpet/royalblack, +/area/commons/dorms) +"bZK" = ( +/obj/structure/chair/comfy/brown{ + dir = 8 + }, +/turf/open/floor/carpet/royalblack, +/area/commons/dorms) +"bZL" = ( +/obj/structure/fence, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"bZM" = ( +/obj/machinery/camera{ + c_tag = "Cargo Bay - Port"; + dir = 4; + name = "cargo camera" + }, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=4"; + dir = 4; + freq = 1400; + location = "QM #4" + }, +/obj/effect/turf_decal/delivery, +/mob/living/simple_animal/bot/mulebot{ + beacon_freq = 1400; + home_destination = "QM #1"; + suffix = "#1" + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bZN" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/window/reinforced, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bZO" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"bZP" = ( +/obj/machinery/conveyor{ + dir = 4; + id = "cargoload" + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/cargo/storage) +"bZQ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/conveyor/inverted{ + dir = 10; + id = "cargoload" + }, +/turf/open/floor/plating, +/area/cargo/storage) +"bZR" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/extinguisher_cabinet{ + dir = 4; + pixel_x = -5; + pixel_y = 27 + }, +/obj/effect/decal/festive/fairylights{ + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"bZS" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"bZT" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/obj/effect/decal/festive/fairylights{ + pixel_y = 32 + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/power/apc{ + areastring = "/area/commons/fitness/pool"; + dir = 1; + name = "Pool APC"; + pixel_y = 24 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"bZU" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/sign/departments/showers{ + pixel_y = 32 + }, +/obj/effect/decal/festive/christmas_ivy_string{ + pixel_y = 32 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"bZV" = ( +/obj/structure/table/wood, +/obj/machinery/requests_console{ + department = "Theatre Backstage"; + name = "Theatre RC"; + pixel_x = -32 + }, +/obj/item/lipstick/random{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/lipstick/random{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/item/lipstick/random, +/turf/open/floor/plasteel/cafeteria, +/area/service/theater) +"bZW" = ( +/obj/effect/landmark/event_spawn, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/cafeteria, +/area/service/theater) +"bZX" = ( +/obj/effect/landmark/start/mime, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/cafeteria, +/area/service/theater) +"bZY" = ( +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/obj/machinery/light_switch{ + pixel_x = 26; + pixel_y = -26 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel, +/area/service/theater) +"bZZ" = ( +/obj/vehicle/sealed/vectorcraft/clown, +/turf/open/floor/plasteel, +/area/service/theater) +"caa" = ( +/obj/structure/bookcase/random/reference, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"cab" = ( +/obj/structure/bookcase/manuals/engineering, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"cac" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Library" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/firedoor, +/turf/open/floor/carpet/red, +/area/commons/lounge) +"cad" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Library" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment, +/turf/open/floor/carpet/red, +/area/commons/lounge) +"cae" = ( +/obj/structure/bookcase/random/fiction, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"caf" = ( +/obj/structure/bookcase/random/adult, +/turf/open/indestructible/hotelwood, +/area/commons/lounge) +"cag" = ( +/obj/effect/festive/street/streetlineinnersw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"cah" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWELeftEnd, +/turf/open/floor/plating, +/area/commons/lounge) +"cai" = ( +/obj/machinery/firealarm{ + dir = 4; + pixel_x = -28 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"caj" = ( +/obj/structure/chair/comfy/black, +/obj/effect/landmark/start/librarian, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"cak" = ( +/obj/structure/window/reinforced{ + dir = 1; + name = "Library Delivery"; + pixel_y = 2 + }, +/obj/machinery/newscaster{ + pixel_x = 32 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"cal" = ( +/obj/machinery/door/airlock/wood/glass, +/obj/effect/decal/festive/mistletoe, +/turf/open/floor/plasteel/dark, +/area/service/cafeteria) +"cam" = ( +/obj/structure/window{ + dir = 1 + }, +/obj/structure/window, +/obj/machinery/door/window/westleft{ + name = "Cloakroom Two"; + req_one_access_txt = "25;26;28;35" + }, +/obj/structure/rack, +/turf/open/floor/carpet/orange, +/area/service/bar) +"can" = ( +/obj/structure/sink/kitchen{ + dir = 4; + pixel_x = -14 + }, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"cao" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"cap" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"caq" = ( +/obj/effect/landmark/start/quartermaster, +/turf/open/floor/carpet/orange, +/area/cargo/qm) +"car" = ( +/obj/structure/grille, +/obj/structure/festive/bluebrick/windowWELeftEnd, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"cas" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/structure/table/wood/fancy/red, +/obj/item/storage/box/donkpockets, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"cat" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"cau" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"cav" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/landmark/start/cargo_technician, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"caw" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"cax" = ( +/obj/structure/chair/office/light, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/landmark/start/virologist, +/turf/open/floor/plasteel/white, +/area/medical/virology) +"cay" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"caz" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/science) +"caA" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Hydroponics"; + req_access_txt = "35" + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"caB" = ( +/obj/effect/festive/street/sidewalke, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"caC" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/mining, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/door/firedoor, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/commons/locker) +"caD" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/indestructible, +/area/cargo/storage) +"caE" = ( +/obj/effect/landmark/start/quartermaster, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/indestructible, +/area/commons/locker) +"caF" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/indestructible, +/area/commons/locker) +"caG" = ( +/obj/effect/landmark/start/cargo_technician, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/indestructible, +/area/commons/locker) +"caH" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/mining, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/door/firedoor, +/turf/open/indestructible, +/area/commons/locker) +"caI" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/cargo/sorting) +"caJ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/effect/landmark/start/quartermaster, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/indestructible, +/area/cargo/sorting) +"caK" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/indestructible, +/area/cargo/sorting) +"caL" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"caM" = ( +/obj/machinery/door/airlock/medical{ + name = "Showers" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/commons/fitness/pool) +"caN" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/window/spawner, +/turf/open/floor/plasteel/white, +/area/commons/fitness) +"caO" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/sign/poster/official/no_erp{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/white, +/area/commons/fitness) +"caP" = ( +/obj/machinery/door/airlock/medical{ + name = "Showers" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/white, +/area/commons/fitness) +"caQ" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/sign/poster/official/cleanliness{ + pixel_y = -32 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel/white, +/area/commons/fitness) +"caR" = ( +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel/white, +/area/commons/fitness) +"caS" = ( +/turf/open/floor/plasteel/dark, +/area/commons/fitness) +"caT" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/snacks/baguette, +/obj/item/toy/crayon/spraycan/mimecan{ + charges = 5 + }, +/obj/structure/sign/poster/contraband/random{ + pixel_y = -32 + }, +/obj/effect/spawner/lootdrop/minor/kittyears_or_rabbitears, +/turf/open/floor/plasteel/cafeteria, +/area/service/theater) +"caU" = ( +/obj/machinery/vending/autodrobe, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/obj/machinery/light, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/cafeteria, +/area/service/theater) +"caV" = ( +/obj/structure/table/wood, +/obj/item/clipboard, +/obj/item/toy/figure/mime, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/cafeteria, +/area/service/theater) +"caW" = ( +/obj/structure/sign/poster/contraband/random{ + pixel_y = -32 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/reagent_dispensers/keg{ + desc = "A keg of laughter."; + reagent_id = "laughter" + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/theater) +"caX" = ( +/obj/structure/bookcase/manuals/medical, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"caY" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessservitor) +"caZ" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"cba" = ( +/obj/effect/festive/street/streetlinenw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"cbb" = ( +/obj/machinery/conveyor{ + dir = 1; + id = "cargocars" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cbc" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Curator's Closet"; + req_access_txt = "37" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"cbd" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"cbe" = ( +/obj/structure/filingcabinet, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"cbf" = ( +/obj/structure/table/wood, +/obj/item/paper_bin, +/obj/item/pen/fountain, +/obj/machinery/status_display{ + pixel_y = -32 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"cbg" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/carpet/royalblack, +/area/commons/dorms) +"cbh" = ( +/turf/open/floor/carpet/royalblack, +/area/commons/dorms) +"cbi" = ( +/obj/machinery/light, +/obj/structure/table/wood, +/obj/item/folder, +/obj/item/laser_pointer{ + pixel_x = 3 + }, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_y = -26 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"cbj" = ( +/obj/structure/table/wood, +/obj/item/taperecorder, +/obj/item/camera, +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/structure/sign/directions/medical{ + dir = 1; + pixel_x = 32; + pixel_y = -24 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/service/library) +"cbk" = ( +/obj/machinery/light/small, +/turf/open/floor/carpet/orange, +/area/service/bar) +"cbl" = ( +/obj/structure/window{ + dir = 1 + }, +/obj/structure/window, +/obj/machinery/door/window/westleft{ + name = "Cloakroom One"; + req_one_access_txt = "25;26;28;35" + }, +/obj/structure/rack, +/turf/open/floor/carpet/orange, +/area/service/bar) +"cbm" = ( +/obj/structure/table, +/obj/item/book/manual/wiki/cooking_to_serve_man, +/obj/item/kitchen/rollingpin, +/obj/machinery/button/door{ + id = "kitchen"; + name = "Kitchen Shutters Control"; + pixel_x = -1; + pixel_y = -24; + req_access_txt = "28" + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"cbn" = ( +/obj/structure/table, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"cbo" = ( +/obj/structure/table, +/obj/machinery/reagentgrinder{ + desc = "Used to grind things up into raw materials and liquids."; + pixel_x = -5; + pixel_y = 5 + }, +/obj/item/reagent_containers/glass/beaker/large{ + pixel_x = -10; + pixel_y = 4 + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"cbp" = ( +/obj/machinery/processor, +/obj/structure/disposalpipe/junction/flip, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"cbq" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"cbr" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/condiment/flour{ + pixel_x = 7 + }, +/obj/item/reagent_containers/food/condiment/flour{ + pixel_x = -8 + }, +/obj/machinery/button/door{ + id = "kitchen"; + name = "Kitchen Shutters Control"; + pixel_x = -1; + pixel_y = -24; + req_access_txt = "28" + }, +/turf/open/floor/plasteel/cafeteria, +/area/service/kitchen) +"cbs" = ( +/obj/structure/reagent_dispensers/keg/milk, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"cbt" = ( +/obj/structure/closet/crate/freezer{ + desc = "A small crate with a cooling system, keeps fresh produce chilled."; + name = "Food Chiller" + }, +/obj/item/reagent_containers/food/condiment/flour{ + desc = "A large sack of flour for restaurants, not the home-baker!"; + list_reagents = list(/datum/reagent/consumable/flour = 90); + name = "Large Flour Sack" + }, +/obj/item/reagent_containers/food/condiment/flour{ + desc = "A large sack of flour for restaurants, not the home-baker!"; + list_reagents = list(/datum/reagent/consumable/flour = 90); + name = "Large Flour Sack" + }, +/obj/item/reagent_containers/food/condiment/flour{ + desc = "A large sack of flour for restaurants, not the home-baker!"; + list_reagents = list(/datum/reagent/consumable/flour = 90); + name = "Large Flour Sack" + }, +/obj/item/reagent_containers/food/condiment/flour{ + desc = "A large sack of flour for restaurants, not the home-baker!"; + list_reagents = list(/datum/reagent/consumable/flour = 90); + name = "Large Flour Sack" + }, +/obj/item/reagent_containers/food/condiment/rice{ + desc = "A huge sack of rice. Probably for restaurants that actually go through such a huge volume of it easily, not for the home cook."; + list_reagents = list(/datum/reagent/consumable/rice = 90); + name = "Large Rice Sack" + }, +/obj/item/reagent_containers/food/condiment/rice{ + desc = "A huge sack of rice. Probably for restaurants that actually go through such a huge volume of it easily, not for the home cook."; + list_reagents = list(/datum/reagent/consumable/rice = 90); + name = "Large Rice Sack" + }, +/obj/item/reagent_containers/food/condiment/rice{ + desc = "A huge sack of rice. Probably for restaurants that actually go through such a huge volume of it easily, not for the home cook."; + list_reagents = list(/datum/reagent/consumable/rice = 90); + name = "Large Rice Sack" + }, +/obj/item/reagent_containers/food/condiment/rice{ + desc = "A huge sack of rice. Probably for restaurants that actually go through such a huge volume of it easily, not for the home cook."; + list_reagents = list(/datum/reagent/consumable/rice = 90); + name = "Large Rice Sack" + }, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"cbu" = ( +/obj/structure/sign/poster/official/twelve_gauge{ + pixel_y = 32 + }, +/turf/open/floor/carpet/orange, +/area/cargo/qm) +"cbv" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/structure/chair{ + dir = 1 + }, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"cbw" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/newscaster{ + pixel_y = -32 + }, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"cbx" = ( +/obj/machinery/light/small, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/structure/extinguisher_cabinet{ + pixel_y = -32 + }, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"cby" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"cbz" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/structure/cable/yellow, +/obj/machinery/power/apc/auto_name{ + pixel_y = -30 + }, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"cbA" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/supply) +"cbB" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cbC" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"cbD" = ( +/obj/structure/closet/wardrobe/cargotech, +/obj/item/clothing/suit/hooded/wintercoat/cargo, +/obj/item/clothing/under/color/brown, +/obj/item/clothing/shoes/winterboots, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/item/radio, +/obj/item/clothing/neck/scarf/orange, +/obj/machinery/light/small, +/obj/structure/closet/secure_closet/quartermaster, +/turf/open/indestructible, +/area/commons/locker) +"cbE" = ( +/obj/item/clothing/suit/hooded/wintercoat/cargo, +/obj/item/clothing/shoes/winterboots, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/item/stamp/qm, +/obj/item/radio, +/obj/structure/closet/wardrobe/cargotech, +/obj/item/clothing/neck/scarf/orange, +/turf/open/indestructible, +/area/commons/locker) +"cbF" = ( +/obj/structure/closet/wardrobe/cargotech, +/obj/item/clothing/suit/hooded/wintercoat/cargo, +/obj/item/clothing/under/color/brown, +/obj/item/clothing/shoes/winterboots, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/item/radio, +/obj/item/clothing/neck/scarf/orange, +/obj/structure/closet/secure_closet/quartermaster, +/turf/open/indestructible, +/area/commons/locker) +"cbG" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/cargo/storage) +"cbH" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/light/small, +/turf/open/floor/plasteel, +/area/cargo/storage) +"cbI" = ( +/obj/structure/cable/white, +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/white{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/cargo/storage) +"cbJ" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"cbK" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWERightEnd, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/commons/fitness/pool) +"cbL" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"cbM" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/festive/whitebrick, +/area/service/theater) +"cbN" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/service/theater) +"cbO" = ( +/obj/structure/disposalpipe/segment, +/turf/closed/festive/whitebrick, +/area/service/theater) +"cbP" = ( +/obj/machinery/door/poddoor/shutters{ + id = "clowngarage" + }, +/turf/open/floor/plasteel, +/area/service/theater) +"cbQ" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSRightEnd, +/turf/open/floor/plating, +/area/commons/lounge) +"cbR" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/floor/plating, +/area/commons/lounge) +"cbS" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSLeftEnd, +/turf/open/floor/plating, +/area/commons/lounge) +"cbT" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/closed/festive/whitebrick{ + color = "#993e28" + }, +/area/commons/lounge) +"cbU" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"cbV" = ( +/obj/effect/festive/street/streetlineinnerse, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"cbW" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"cbX" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"cbY" = ( +/obj/machinery/door/airlock/glass_large{ + name = "Pub" + }, +/turf/open/floor/plasteel/dark, +/area/service/cafeteria) +"cbZ" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSRight, +/turf/open/floor/plasteel/dark, +/area/service/cafeteria) +"cca" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSMiddle, +/turf/open/floor/plasteel/dark, +/area/service/bar) +"ccb" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSLeftEnd, +/turf/open/floor/plasteel/dark, +/area/service/bar) +"ccc" = ( +/turf/closed/festive/greybrick/greybrickns, +/area/service/bar) +"ccd" = ( +/turf/closed/festive/greybrick/greybrickns, +/area/service/kitchen) +"cce" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSRightEnd, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "kitchen"; + name = "kitchen shutters" + }, +/turf/open/floor/wood, +/area/service/kitchen) +"ccf" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSMiddle, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "kitchen"; + name = "kitchen shutters" + }, +/turf/open/floor/wood, +/area/service/kitchen) +"ccg" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSMiddle, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "kitchen"; + name = "kitchen shutters" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/service/kitchen) +"cch" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSLeftEnd, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "kitchen"; + name = "kitchen shutters" + }, +/turf/open/floor/wood, +/area/service/kitchen) +"cci" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"ccj" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"cck" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/turf/open/indestructible, +/area/cargo/storage) +"ccl" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/indestructible, +/area/cargo/storage) +"ccm" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/indestructible, +/area/cargo/storage) +"ccn" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/indestructible, +/area/cargo/storage) +"cco" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"ccp" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/sign/departments/custodian{ + pixel_y = 32 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"ccq" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"ccr" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"ccs" = ( +/obj/effect/festive/street/sidewalks, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"cct" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = 16 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/progcastaux) +"ccu" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"ccv" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"ccw" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = 16 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"ccx" = ( +/obj/structure/table/wood, +/obj/item/paper_bin/bundlenatural{ + pixel_x = 6; + pixel_y = 4 + }, +/obj/item/paper_bin{ + pixel_x = -6; + pixel_y = 4 + }, +/obj/item/pen/fountain, +/turf/open/floor/carpet/royalblack, +/area/commons/dorms) +"ccy" = ( +/obj/effect/festive/street/streetlinewest, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"ccz" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"ccA" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"ccB" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"ccC" = ( +/obj/machinery/door/airlock/mining{ + name = "Quartermaster's Quarters"; + req_access_txt = "41" + }, +/turf/open/floor/carpet/orange, +/area/cargo/qm) +"ccD" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"ccE" = ( +/obj/structure/dresser, +/turf/open/floor/carpet/orange, +/area/cargo/qm) +"ccF" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8; + pixel_y = 16 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/progcastaux) +"ccG" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/progcastaux) +"ccH" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/progcastaux) +"ccI" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"ccJ" = ( +/obj/machinery/vending/kink{ + extended_inventory = 1 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"ccK" = ( +/obj/machinery/airalarm/directional/north, +/turf/open/floor/wood, +/area/maintenance/bar) +"ccL" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"ccM" = ( +/obj/machinery/conveyor_switch/oneway{ + dir = 8; + id = "QMLoad2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/turf/open/indestructible, +/area/cargo/storage) +"ccN" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"ccO" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"ccP" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"ccQ" = ( +/obj/structure/sink{ + dir = 1; + pixel_y = 25 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"ccR" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"ccS" = ( +/obj/structure/table/wood, +/obj/item/lipstick{ + pixel_x = 4 + }, +/obj/item/lipstick/black, +/obj/item/lipstick/jade{ + pixel_x = -4 + }, +/obj/item/lipstick/purple{ + pixel_x = -8 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"ccT" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"ccU" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"ccV" = ( +/turf/closed/festive/bluebrick, +/area/commons/cryopod) +"ccW" = ( +/turf/open/floor/plasteel/dark, +/area/commons/cryopod) +"ccX" = ( +/obj/machinery/cryopod{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/commons/cryopod) +"ccY" = ( +/obj/machinery/cryopod, +/turf/open/floor/plasteel/dark, +/area/commons/cryopod) +"ccZ" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Hotel" + }, +/turf/open/floor/plasteel/dark, +/area/commons/cryopod) +"cda" = ( +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/obj/effect/decal/festive/holly, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/cryopod) +"cdb" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/effect/decal/festive/red_stockings, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/cryopod) +"cdc" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/plasteel/elevatorshaft, +/area/commons/cryopod) +"cdd" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Hotel" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/cryopod) +"cde" = ( +/turf/open/floor/festive/wooden/wooden1, +/area/commons/cryopod) +"cdf" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/blue, +/area/commons/cryopod) +"cdg" = ( +/obj/effect/festive/street/sidewalkw, +/obj/effect/festive/street/streetliftedtile2, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"cdh" = ( +/obj/structure/table/wood/fancy/blue, +/turf/open/floor/carpet/blue, +/area/commons/cryopod) +"cdi" = ( +/turf/open/floor/carpet/blue, +/area/commons/cryopod) +"cdj" = ( +/obj/structure/festive/bluebrick/windowWERight, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/cryopod) +"cdk" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"cdl" = ( +/obj/effect/festive/street/sidewalke, +/obj/effect/festive/street/streetliftedtile1, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/progcastaux) +"cdm" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/progcastaux) +"cdn" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/festive/trainplatform/nwcorner, +/turf/open/floor/plating/dirt/space, +/area/edina) +"cdo" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/progcastaux) +"cdp" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"cdq" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/holofloor/ice, +/area/edina) +"cdr" = ( +/obj/structure/fence, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"cds" = ( +/obj/structure/sign/departments/engineering, +/turf/closed/wall/r_wall, +/area/engineering/main) +"cdt" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/obj/structure/sign/departments/security, +/turf/closed/wall/mineral/iron, +/area/security) +"cdu" = ( +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/grass/snow/edina, +/area/edina/street/primary/progress) +"cdv" = ( +/obj/structure/sign/departments/security, +/turf/closed/wall/mineral/iron, +/area/security) +"cdw" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/science) +"cdx" = ( +/obj/structure/fence, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cdy" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/aux) +"cdz" = ( +/obj/structure/sign/directions/evac{ + dir = 1; + pixel_y = -8 + }, +/obj/structure/sign/directions/medical{ + dir = 8 + }, +/turf/closed/festive/greybrick, +/area/service/cafeteria) +"cdA" = ( +/obj/structure/sign/directions/evac{ + dir = 1 + }, +/obj/structure/sign/directions/science{ + dir = 1; + pixel_y = -8 + }, +/turf/closed/festive/whitebrick{ + color = "#993e28" + }, +/area/service/library) +"cdB" = ( +/obj/structure/sign/directions/engineering{ + dir = 8 + }, +/obj/structure/sign/directions/evac{ + dir = 1; + pixel_y = -8 + }, +/obj/structure/sign/directions/security{ + dir = 1; + pixel_y = 8 + }, +/turf/closed/festive/greybrick, +/area/edina/street/primary/perimeter) +"cdC" = ( +/obj/structure/sign/directions/supply{ + dir = 4; + pixel_y = -8 + }, +/obj/structure/sign/directions/medical{ + dir = 1 + }, +/obj/structure/sign/directions/science{ + dir = 1; + pixel_y = 8 + }, +/turf/closed/festive/greybrick, +/area/edina/street/primary/perimeter) +"cdD" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/stairs/right, +/area/service/cafeteria) +"cdE" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/royalblue, +/area/service/cafeteria) +"cdF" = ( +/obj/effect/landmark/start/chief_medical_officer, +/turf/open/floor/carpet/blue, +/area/command/heads_quarters/cmo) +"cdG" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/carpet/blue, +/area/command/heads_quarters/cmo) +"cdH" = ( +/obj/structure/chair/wood/normal{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/landmark/start/paramedic, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"cdI" = ( +/obj/structure/chair/comfy/teal, +/obj/effect/landmark/start/chief_medical_officer, +/turf/open/floor/carpet/blue, +/area/command/heads_quarters/cmo) +"cdJ" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"cdK" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/freezer, +/area/service/kitchen/coldroom) +"cdL" = ( +/obj/structure/chair/office/light{ + dir = 4 + }, +/obj/effect/landmark/start/medical_doctor, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"cdM" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 + }, +/obj/effect/landmark/start/assistant, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, +/area/medical/medbay/lobby) +"cdN" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/effect/landmark/start/assistant, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, +/area/medical/medbay/lobby) +"cdO" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/lobby) +"cdP" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSRightEnd, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel/white, +/area/security/checkpoint/medical) +"cdQ" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSLeftEnd, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel/white, +/area/security/checkpoint/medical) +"cdR" = ( +/obj/structure/sign/departments/security, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/closed/festive/redbrick/redbrickcornerne, +/area/security/checkpoint/medical) +"cdS" = ( +/obj/machinery/door/airlock/security{ + name = "Security Post - Medical"; + req_access_txt = "63" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"cdT" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWERightEnd, +/obj/structure/cable/yellow, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel/white, +/area/security/checkpoint/medical) +"cdU" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"cdV" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWELeft, +/obj/structure/cable/yellow, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel/white, +/area/security/checkpoint/medical) +"cdW" = ( +/obj/structure/chair/wood/normal, +/obj/effect/decal/festive/christmas_ivy_string, +/obj/effect/landmark/start/assistant, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"cdX" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"cdY" = ( +/obj/effect/spawner/structure/window/reinforced/indestructable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/cargo) +"cdZ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/landmark/start/paramedic, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"cea" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/landmark/start/medical_doctor, +/turf/open/floor/plasteel/white, +/area/medical/storage) +"ceb" = ( +/obj/machinery/door/airlock/security/glass{ + id_tag = "cardoor"; + name = "Cargo Cell"; + req_access_txt = "63" + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/indestructible, +/area/security/checkpoint/supply) +"cec" = ( +/obj/effect/turf_decal/caution/stand_clear{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/cargo/sorting) +"ced" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWERight, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/obj/structure/cable/yellow, +/turf/closed/festive/redbrick, +/area/security/checkpoint/supply) +"cee" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/obj/structure/closet/secure_closet/brig{ + id = "cargocell"; + name = "Cargo Cell Locker" + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"cef" = ( +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/aux) +"ceg" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/indestructible, +/area/security/checkpoint/supply) +"ceh" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWERightEnd, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel/white, +/area/security/checkpoint/supply) +"cei" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"cej" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"cek" = ( +/obj/structure/table/reinforced, +/obj/item/book/manual/wiki/security_space_law, +/obj/item/radio, +/obj/machinery/camera{ + c_tag = "Cargo Security Post" + }, +/obj/machinery/firealarm{ + pixel_y = 26 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"cel" = ( +/obj/structure/table/reinforced, +/obj/machinery/recharger, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"cem" = ( +/obj/machinery/computer/secure_data{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"cen" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWEMiddle, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/obj/structure/cable/yellow, +/turf/closed/festive/redbrick, +/area/security/checkpoint/supply) +"ceo" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/indestructible, +/area/security/checkpoint/supply) +"cep" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWELeft, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/obj/structure/cable/yellow, +/turf/open/floor/plasteel/white, +/area/security/checkpoint/supply) +"ceq" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"cer" = ( +/obj/machinery/holopad, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"ces" = ( +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"cet" = ( +/obj/structure/chair/office/dark{ + dir = 4 + }, +/obj/effect/landmark/start/depsec/supply, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"ceu" = ( +/obj/machinery/computer/security{ + dir = 8 + }, +/obj/machinery/light{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"cev" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWELeft, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/obj/structure/cable/yellow, +/turf/closed/festive/redbrick, +/area/security/checkpoint/supply) +"cew" = ( +/obj/machinery/door/airlock/security/glass{ + id_tag = "cardoor"; + name = "Cargo Cell"; + req_access_txt = "63" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"cex" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"cey" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"cez" = ( +/obj/item/radio/intercom{ + dir = 8; + name = "Station Intercom (General)"; + pixel_y = -26 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"ceA" = ( +/obj/structure/closet/secure_closet/security/cargo, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"ceB" = ( +/obj/machinery/computer/crew{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"ceC" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/closed/festive/redbrick, +/area/security/checkpoint/supply) +"ceD" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSRightEnd, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/closed/festive/redbrick, +/area/security/checkpoint/supply) +"ceE" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSLeft, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/closed/festive/redbrick, +/area/security/checkpoint/supply) +"ceF" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/closed/festive/redbrick, +/area/security/checkpoint/supply) +"ceG" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/indestructible, +/area/cargo/sorting) +"ceH" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/indestructible, +/area/cargo/storage) +"ceI" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/indestructible, +/area/cargo/storage) +"ceJ" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Cargo Bay"; + req_one_access_txt = "31;48" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/indestructible, +/area/cargo/storage) +"ceK" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/aux) +"ceL" = ( +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/aux) +"ceM" = ( +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"ceN" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"ceO" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"ceP" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"ceQ" = ( +/obj/machinery/door/airlock/wood, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"ceR" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/streetlineeast, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"ceS" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"ceT" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"ceU" = ( +/obj/item/bedsheet/qm/double, +/obj/structure/bed/double, +/turf/open/floor/carpet/orange, +/area/cargo/qm) +"ceV" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"ceW" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/supply) +"ceX" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"ceY" = ( +/obj/structure/fence, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"ceZ" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"cfa" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cfb" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cfc" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cfd" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"cfe" = ( +/obj/effect/festive/street/streetlineeast, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/aux) +"cff" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/festive/street/sidewalkw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cfg" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel/yellowsiding/corner, +/area/commons/fitness/pool) +"cfh" = ( +/turf/open/floor/plasteel/yellowsiding, +/area/commons/fitness/pool) +"cfi" = ( +/obj/machinery/pool/controller, +/turf/open/floor/plasteel/yellowsiding, +/area/commons/fitness/pool) +"cfj" = ( +/turf/open/floor/plasteel/yellowsiding/corner{ + dir = 8 + }, +/area/commons/fitness/pool) +"cfk" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/machinery/shower{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/commons/fitness) +"cfl" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel/freezer, +/area/commons/fitness) +"cfm" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/machinery/shower{ + dir = 8 + }, +/turf/open/floor/plasteel/freezer, +/area/commons/fitness) +"cfn" = ( +/obj/machinery/door/airlock/medical{ + name = "Restroom" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/white, +/area/commons/fitness) +"cfo" = ( +/turf/open/floor/wood, +/area/commons/fitness) +"cfp" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWEMiddle, +/turf/open/floor/plasteel/white, +/area/commons/fitness/pool) +"cfq" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/structure/bed, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"cfr" = ( +/turf/open/floor/plasteel/yellowsiding{ + dir = 4 + }, +/area/commons/fitness/pool) +"cfs" = ( +/obj/machinery/pool/filter{ + pixel_y = 16 + }, +/turf/open/pool, +/area/commons/fitness/pool) +"cft" = ( +/turf/open/pool, +/area/commons/fitness/pool) +"cfu" = ( +/obj/structure/pool/ladder{ + dir = 2; + pixel_y = 24 + }, +/turf/open/pool, +/area/commons/fitness/pool) +"cfv" = ( +/turf/open/floor/plasteel/yellowsiding{ + dir = 8 + }, +/area/commons/fitness/pool) +"cfw" = ( +/obj/structure/sign/departments/restroom{ + pixel_y = 32 + }, +/obj/effect/decal/festive/christmas_ivy_string{ + pixel_y = 32 + }, +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk, +/turf/open/floor/wood, +/area/commons/fitness) +"cfx" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/commons/fitness) +"cfy" = ( +/obj/effect/decal/festive/christmas_ivy_string{ + pixel_y = 32 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/commons/fitness) +"cfz" = ( +/obj/structure/punching_bag, +/obj/effect/decal/festive/fairylights{ + pixel_y = 32 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/dark, +/area/commons/fitness) +"cfA" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plasteel/white, +/area/commons/fitness) +"cfB" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/floor/plasteel/white, +/area/commons/fitness) +"cfC" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plasteel/white, +/area/commons/fitness) +"cfD" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/festive/whitebrick{ + color = "#ffe6a8" + }, +/area/commons/fitness) +"cfE" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"cfF" = ( +/obj/structure/sign/poster/official/walk{ + pixel_x = 32; + pixel_y = 32 + }, +/turf/open/floor/plasteel/yellowsiding{ + dir = 8 + }, +/area/commons/fitness/pool) +"cfG" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/festive/street/sidewalkwem, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cfH" = ( +/obj/structure/weightmachine/stacklifter, +/turf/open/floor/plasteel/grimy, +/area/commons/fitness) +"cfI" = ( +/turf/open/floor/plasteel/grimy, +/area/commons/fitness) +"cfJ" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel/grimy, +/area/commons/fitness) +"cfK" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/grimy, +/area/commons/fitness) +"cfL" = ( +/obj/structure/table/glass, +/obj/structure/window/spawner/east, +/obj/item/storage/firstaid, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"cfM" = ( +/obj/effect/decal/festive/christmas_ivy_string{ + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/commons/fitness) +"cfN" = ( +/obj/structure/weightmachine/weightlifter, +/turf/open/floor/plasteel/grimy, +/area/commons/fitness) +"cfO" = ( +/obj/machinery/airalarm/unlocked{ + pixel_y = 23 + }, +/obj/effect/decal/festive/fairylights{ + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/commons/fitness) +"cfP" = ( +/obj/machinery/light, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/wood, +/area/commons/fitness) +"cfQ" = ( +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/obj/effect/decal/festive/christmas_ivy_string{ + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/commons/fitness) +"cfR" = ( +/obj/effect/decal/festive/fairylights{ + pixel_y = 32 + }, +/obj/item/radio/intercom{ + pixel_y = 25 + }, +/turf/open/floor/wood, +/area/commons/fitness) +"cfS" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/commons/fitness) +"cfT" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/commons/fitness) +"cfU" = ( +/obj/structure/sign/poster/contraband/punch_shit{ + pixel_x = 32 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/commons/fitness) +"cfV" = ( +/obj/structure/pool/ladder{ + pixel_x = -4 + }, +/turf/open/pool, +/area/commons/fitness/pool) +"cfW" = ( +/obj/machinery/pool/drain, +/turf/open/pool, +/area/commons/fitness/pool) +"cfX" = ( +/obj/machinery/door/window/eastleft{ + name = "Pool Room" + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"cfY" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/wood, +/area/commons/fitness) +"cfZ" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/structure/table/wood/fancy/green, +/obj/item/clothing/gloves/boxing{ + pixel_y = 12 + }, +/obj/item/clothing/gloves/boxing/blue{ + pixel_y = 4 + }, +/obj/item/clothing/gloves/boxing/green{ + pixel_y = -4 + }, +/obj/item/clothing/gloves/boxing/yellow{ + pixel_y = -12 + }, +/turf/open/floor/wood, +/area/commons/fitness) +"cga" = ( +/obj/machinery/disposal/bin, +/obj/effect/turf_decal/bot, +/obj/structure/disposalpipe/trunk, +/turf/open/floor/festive/wooden/wooden1, +/area/service/theater) +"cgb" = ( +/obj/structure/pool/Lboard, +/turf/open/pool, +/area/commons/fitness/pool) +"cgc" = ( +/obj/structure/pool/Rboard, +/turf/open/floor/plasteel/yellowsiding{ + dir = 8 + }, +/area/commons/fitness/pool) +"cgd" = ( +/obj/structure/window/spawner/east, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"cge" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/commons/fitness) +"cgf" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/commons/fitness) +"cgg" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/commons/fitness) +"cgh" = ( +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/structure/table/wood/fancy/green, +/obj/machinery/power/apc{ + areastring = "/area/commons/fitness"; + dir = 4; + name = "Gymnasium APC"; + pixel_x = 26 + }, +/turf/open/floor/wood, +/area/commons/fitness) +"cgi" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowWELeftEnd, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/commons/fitness/pool) +"cgj" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"cgk" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel/yellowsiding{ + dir = 4 + }, +/area/commons/fitness/pool) +"cgl" = ( +/obj/structure/window/spawner/east, +/obj/structure/chair{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"cgm" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/wood, +/area/commons/fitness) +"cgn" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/commons/fitness) +"cgo" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/commons/fitness) +"cgp" = ( +/obj/machinery/status_display{ + pixel_x = 32 + }, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/wood, +/area/commons/fitness) +"cgq" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/structure/chair{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"cgr" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel/yellowsiding/corner{ + dir = 4 + }, +/area/commons/fitness/pool) +"cgs" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/machinery/light, +/turf/open/floor/plasteel/yellowsiding{ + dir = 1 + }, +/area/commons/fitness/pool) +"cgt" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel/yellowsiding{ + dir = 1 + }, +/area/commons/fitness/pool) +"cgu" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/floor/plasteel/yellowsiding{ + dir = 1 + }, +/area/commons/fitness/pool) +"cgv" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/machinery/firealarm{ + pixel_y = -30 + }, +/turf/open/floor/plasteel/yellowsiding/corner{ + dir = 1 + }, +/area/commons/fitness/pool) +"cgw" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/structure/window/spawner/east, +/obj/structure/chair{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/pool) +"cgx" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/commons/fitness) +"cgy" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSRightEnd, +/turf/open/floor/plasteel/white, +/area/commons/fitness/pool) +"cgz" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/turf/open/floor/plasteel/white, +/area/commons/fitness/pool) +"cgA" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSLeftEnd, +/turf/open/floor/plasteel/white, +/area/commons/fitness/pool) +"cgB" = ( +/obj/machinery/door/airlock/glass_large{ + name = "Gymnasium" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/commons/fitness) +"cgC" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/sidewalke, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cgD" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cgE" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/disposalpipe/junction/flip{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cgF" = ( +/obj/structure/statue/snow/snowman, +/turf/open/floor/grass/snow/edina, +/area/science/research) +"cgG" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/junction/flip, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"cgH" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/holofloor/wood, +/area/medical/chemistry) +"cgI" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/carpet/orange, +/area/medical/chemistry) +"cgJ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"cgK" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/disposalpipe/junction/yjunction{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cgL" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/indestructible, +/area/service/janitor) +"cgM" = ( +/obj/machinery/door/poddoor/shutters{ + id = "custodialshutters"; + name = "Custodial Closet Shutters" + }, +/turf/open/indestructible, +/area/service/janitor) +"cgN" = ( +/obj/effect/festive/street/streetlinewest, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"cgO" = ( +/obj/machinery/vending/wardrobe/jani_wardrobe, +/obj/effect/decal/festive/christmas_ivy_string, +/obj/effect/turf_decal/stripes/line, +/turf/open/indestructible, +/area/service/janitor) +"cgP" = ( +/obj/structure/closet/jcloset, +/obj/item/storage/bag/trash, +/obj/item/clothing/under/rank/civilian/janitor/maid, +/obj/item/clothing/under/rank/civilian/janitor/maid, +/obj/item/clothing/under/rank/civilian/janitor/maid, +/obj/item/clothing/under/costume/maid, +/obj/item/clothing/under/costume/maid, +/obj/item/clothing/under/costume/maid, +/obj/effect/decal/festive/christmas_ivy_string, +/obj/machinery/light{ + dir = 1; + light_color = "#e8eaff" + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/indestructible, +/area/service/janitor) +"cgQ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"cgR" = ( +/obj/effect/festive/street/streetlinenm, +/obj/machinery/button/door{ + id = "custodialshutters"; + name = "Custodial Shutters"; + pixel_x = -26; + req_access_txt = "26" + }, +/turf/open/indestructible, +/area/service/janitor) +"cgS" = ( +/obj/vehicle/ridden/janicart, +/obj/item/key/janitor, +/turf/open/indestructible, +/area/service/janitor) +"cgT" = ( +/obj/structure/sign/poster/contraband/lusty_xenomorph{ + pixel_x = -32 + }, +/obj/effect/turf_decal/delivery/white, +/turf/open/floor/plasteel/white, +/area/service/janitor) +"cgU" = ( +/turf/closed/festive/bluebrick, +/area/commons/dorms) +"cgV" = ( +/obj/effect/landmark/start/janitor, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/service/janitor) +"cgW" = ( +/obj/effect/festive/street/streetlineeast, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"cgX" = ( +/obj/machinery/door/airlock{ + glass = 1; + name = "Custodial Closet"; + req_access_txt = "26" + }, +/turf/open/indestructible, +/area/service/janitor) +"cgY" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowWERightEnd, +/turf/open/indestructible, +/area/service/janitor) +"cgZ" = ( +/obj/item/grenade/chem_grenade/cleaner, +/obj/item/grenade/chem_grenade/cleaner, +/obj/item/grenade/chem_grenade/cleaner, +/obj/structure/table, +/obj/item/reagent_containers/spray/cleaner, +/obj/item/reagent_containers/spray/cleaner, +/obj/item/restraints/legcuffs/beartrap, +/obj/item/storage/box/mousetraps, +/obj/item/watertank/janitor, +/obj/item/construction/rld, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/indestructible, +/area/service/janitor) +"cha" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/indestructible, +/area/cargo) +"chb" = ( +/obj/structure/closet/crate, +/turf/open/floor/plating, +/area/cargo/warehouse) +"chc" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/service/janitor) +"chd" = ( +/obj/effect/landmark/start/janitor, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/service/janitor) +"che" = ( +/obj/structure/sign/poster/contraband/busty_backdoor_xeno_babes_6{ + pixel_x = 32 + }, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/portable_atmospherics/canister/water_vapor, +/turf/open/indestructible, +/area/service/janitor) +"chf" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowWELeft, +/turf/open/indestructible, +/area/service/janitor) +"chg" = ( +/obj/structure/table, +/obj/structure/bedsheetbin/towel, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/indestructible, +/area/service/janitor) +"chh" = ( +/obj/structure/janitorialcart, +/obj/item/mop, +/obj/item/reagent_containers/glass/bucket, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/white, +/area/service/janitor) +"chi" = ( +/obj/structure/closet/crate/internals, +/turf/open/floor/plating, +/area/cargo/warehouse) +"chj" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/festive/street/streetliftedtile2, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"chk" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/aux) +"chl" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"chm" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"chn" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"cho" = ( +/obj/machinery/button/door{ + id = "qm_warehouse"; + name = "Warehouse Door Control"; + pixel_y = -8; + req_access_txt = "31" + }, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/warehouse) +"chp" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = 25 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"chq" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"chr" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"chs" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"cht" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"chu" = ( +/obj/machinery/button/door{ + id = "QMgarage"; + name = "Garage door button"; + pixel_x = -28 + }, +/obj/effect/festive/street/streetlinenm, +/turf/open/floor/festive/cobblestone/safe, +/area/cargo/qm) +"chv" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"chw" = ( +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"chx" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"chy" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"chz" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"chA" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"chB" = ( +/turf/closed/wall/mineral/plastitanium, +/area/maintenance/bar/cafe) +"chC" = ( +/obj/structure/sign/poster/contraband/syndicate_logo, +/turf/closed/wall/mineral/plastitanium, +/area/maintenance/bar/cafe) +"chD" = ( +/obj/structure/chair/stool/bar, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 10 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"chE" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"chF" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/chair{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"chG" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"chH" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/chair{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"chI" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"chJ" = ( +/obj/structure/table/wood/fancy/red, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"chK" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 5 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"chL" = ( +/obj/machinery/grill, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"chM" = ( +/obj/machinery/deepfryer, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"chN" = ( +/obj/structure/window/reinforced/spawner/east, +/obj/machinery/processor, +/obj/machinery/button/door{ + id = "Syndicafe"; + name = "Cafe Shutters"; + pixel_y = 24 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"chO" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "syndicafe" + }, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"chP" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 5 + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "syndicafe" + }, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"chQ" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/chair/stool/bar, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"chR" = ( +/obj/structure/chair{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"chS" = ( +/obj/structure/table/wood/fancy/blackred, +/turf/open/floor/festive/sidewalk, +/area/edina) +"chT" = ( +/obj/structure/chair{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"chU" = ( +/obj/structure/table/wood/fancy/red, +/turf/open/floor/festive/sidewalk, +/area/edina) +"chV" = ( +/obj/machinery/vending/dinnerware, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"chW" = ( +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"chX" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "syndicafe" + }, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"chY" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 10 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"chZ" = ( +/obj/machinery/door/airlock/centcom{ + name = "Syndicafe Entrance" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/maintenance/bar/cafe) +"cia" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"cib" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"cic" = ( +/obj/machinery/vending/boozeomat/pubby_maint, +/turf/closed/wall/mineral/plastitanium, +/area/maintenance/bar/cafe) +"cid" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/obj/structure/table/reinforced, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"cie" = ( +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/structure/cable/yellow, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"cif" = ( +/obj/structure/rack{ + icon = 'icons/obj/stationobjs.dmi'; + icon_state = "minibar_left"; + name = "skeletal minibar" + }, +/obj/machinery/microwave{ + pixel_y = 12 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"cig" = ( +/obj/structure/rack{ + icon = 'icons/obj/stationobjs.dmi'; + icon_state = "minibar_right"; + name = "skeletal minibar" + }, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"cih" = ( +/obj/structure/closet/secure_closet/freezer/kitchen, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"cii" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/structure/window/reinforced/spawner/east, +/obj/machinery/chem_dispenser/drinks/fullupgrade{ + dir = 1 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"cij" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "syndicafe" + }, +/turf/open/floor/mineral/plastitanium/red, +/area/maintenance/bar/cafe) +"cik" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/chair/stool/bar, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 10 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"cil" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/chair{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"cim" = ( +/obj/structure/table/wood/fancy/red, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina) +"cin" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/chair{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"cio" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina) +"cip" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"ciq" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"cir" = ( +/obj/effect/turf_decal/bot, +/turf/open/indestructible, +/area/cargo) +"cis" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "cargocars" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating, +/area/cargo) +"cit" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "cargocars" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating, +/area/cargo) +"ciu" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "cargocars" + }, +/obj/structure/plasticflaps, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating, +/area/cargo) +"civ" = ( +/obj/structure/disposalpipe/segment, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/warehouse) +"ciw" = ( +/obj/effect/spawner/structure/window/reinforced/indestructable, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, +/area/cargo/qm) +"cix" = ( +/obj/effect/spawner/structure/window/reinforced/indestructable, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating, +/area/cargo/qm) +"ciy" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Cargo Bay"; + req_one_access_txt = "31;48" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo/office) +"ciz" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Cargo Office"; + req_access_txt = "50" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/indestructible, +/area/cargo/office) +"ciA" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/disposaloutlet, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/effect/turf_decal/delivery, +/obj/structure/disposalpipe/trunk, +/turf/open/floor/plasteel, +/area/cargo) +"ciB" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"ciC" = ( +/obj/machinery/computer/cargo, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/cargo/qm) +"ciD" = ( +/obj/machinery/computer/bounty, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/cargo/qm) +"ciE" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/qm) +"ciF" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"ciG" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"ciH" = ( +/obj/effect/festive/street/streetlinenm, +/obj/vehicle/sealed/vectorcraft/auto{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone/safe, +/area/cargo/qm) +"ciI" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/machinery/door/window, +/obj/effect/turf_decal/bot, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel, +/area/cargo) +"ciJ" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"ciK" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/cargo/qm) +"ciL" = ( +/obj/structure/closet/cabinet{ + pixel_y = 15 + }, +/turf/open/floor/carpet/blue, +/area/commons/dorms) +"ciM" = ( +/obj/structure/dresser{ + pixel_y = 15 + }, +/obj/item/flashlight/lamp/green{ + on = 0; + pixel_y = 30 + }, +/turf/open/floor/carpet/blue, +/area/commons/dorms) +"ciN" = ( +/obj/structure/bed, +/obj/item/bedsheet/random, +/turf/open/floor/carpet/blue, +/area/commons/dorms) +"ciO" = ( +/obj/machinery/vending/coffee, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"ciP" = ( +/obj/machinery/vending/cola/sodie, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"ciQ" = ( +/obj/effect/landmark/start/quartermaster, +/obj/structure/chair/office/dark, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/cargo/qm) +"ciR" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/cargo/qm) +"ciS" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/indestructible, +/area/cargo/office) +"ciT" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/indestructible, +/area/cargo/office) +"ciU" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/office) +"ciV" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Cargo Office"; + req_access_txt = "50" + }, +/obj/effect/decal/festive/christmas_reef, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/office) +"ciW" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"ciX" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Reclaiming center" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo) +"ciY" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo) +"ciZ" = ( +/obj/effect/turf_decal/stripes/line, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/indestructible, +/area/cargo) +"cja" = ( +/obj/effect/turf_decal/stripes/line, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo) +"cjb" = ( +/obj/structure/window/reinforced, +/obj/effect/turf_decal/stripes/line, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo) +"cjc" = ( +/obj/structure/window/reinforced, +/obj/effect/turf_decal/stripes/line, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo) +"cjd" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cje" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cjf" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cjg" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "QMLoad2" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cjh" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "QMLoad2" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cji" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cjj" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cjk" = ( +/obj/structure/sign/departments/cargo{ + pixel_x = 32; + pixel_y = -32 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"cjl" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cjm" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 9 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cjn" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cjo" = ( +/obj/structure/closet/crate/trashcart, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 2; + name = "2maintenance loot spawner" + }, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/med) +"cjp" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/indestructible, +/area/cargo/office) +"cjq" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/effect/landmark/start/cargo_technician, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/office) +"cjr" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/computer/bounty{ + dir = 8 + }, +/turf/open/indestructible, +/area/cargo/office) +"cjs" = ( +/obj/effect/spawner/structure/window/reinforced/indestructable, +/turf/open/floor/plating, +/area/cargo/office) +"cjt" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/primary/servitor) +"cju" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"cjv" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"cjw" = ( +/obj/machinery/conveyor{ + dir = 1; + id = "cargocars" + }, +/obj/structure/plasticflaps, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating, +/area/cargo/storage) +"cjx" = ( +/obj/machinery/conveyor{ + dir = 9; + id = "cargoload" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/plating, +/area/cargo/storage) +"cjy" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "cargocars" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/cargo/storage) +"cjz" = ( +/obj/effect/turf_decal/stripes/end{ + dir = 4 + }, +/obj/machinery/conveyor{ + dir = 8; + id = "cargocars" + }, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/plating, +/area/cargo/storage) +"cjA" = ( +/obj/effect/turf_decal/bot, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/indestructible, +/area/cargo/sorting) +"cjB" = ( +/turf/open/floor/carpet/blue, +/area/commons/dorms) +"cjC" = ( +/obj/effect/turf_decal/loading_area{ + dir = 8 + }, +/obj/structure/sign/logo{ + icon_state = "nanotrasen_sign2"; + pixel_y = 32 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/indestructible, +/area/cargo/sorting) +"cjD" = ( +/obj/effect/turf_decal/stripes/end{ + dir = 8 + }, +/obj/machinery/conveyor{ + dir = 8; + id = "QMLoad2" + }, +/obj/structure/sign/logo{ + icon_state = "nanotrasen_sign3"; + pixel_y = 32 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/festive/alleyway, +/area/cargo/sorting) +"cjE" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "QMLoad2" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/sign/logo{ + icon_state = "nanotrasen_sign2"; + pixel_y = 32 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/festive/alleyway, +/area/cargo/sorting) +"cjF" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "QMLoad2" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/sign/logo{ + icon_state = "nanotrasen_sign3"; + pixel_y = 32 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/festive/alleyway, +/area/cargo/sorting) +"cjG" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "QMLoad2" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/sign/logo{ + icon_state = "nanotrasen_sign4"; + pixel_y = 32 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/festive/alleyway, +/area/cargo/sorting) +"cjH" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "QMLoad2" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/plasticflaps, +/obj/structure/sign/logo{ + icon_state = "nanotrasen_sign5"; + pixel_y = 32 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/festive/alleyway, +/area/cargo/sorting) +"cjI" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "QMLoad2" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/plasticflaps, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plating, +/area/cargo/storage) +"cjJ" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "QMLoad2" + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/cargo/storage) +"cjK" = ( +/obj/effect/turf_decal/stripes/end{ + dir = 4 + }, +/obj/machinery/conveyor{ + dir = 8; + id = "QMLoad2" + }, +/turf/open/floor/plating, +/area/cargo/storage) +"cjL" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Delivery Office"; + req_access_txt = 0; + req_one_access_txt = "48;50" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/sorting) +"cjM" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Cargo Bay"; + req_one_access_txt = "31;48" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/storage) +"cjN" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Delivery Office"; + req_access_txt = 0; + req_one_access_txt = "48;50" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/sorting) +"cjO" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Cargo Bay"; + req_one_access_txt = "31;48" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/storage) +"cjP" = ( +/obj/structure/festive/bluebrick/windowWEMiddle, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/cryopod) +"cjQ" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/carpet/blue, +/area/commons/cryopod) +"cjR" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/blue, +/area/commons/cryopod) +"cjS" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/carpet/blue, +/area/commons/cryopod) +"cjT" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8; + pixel_y = 25 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cjU" = ( +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/door/airlock/engineering/glass{ + name = "Tool Shoppe" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"cjV" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/obj/vehicle/sealed/vectorcraft, +/turf/open/floor/plating, +/area/service/electronic_marketing_den) +"cjW" = ( +/obj/effect/festive/street/streetlinewest, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/aux) +"cjX" = ( +/obj/effect/landmark/start/assistant, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"cjY" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cjZ" = ( +/obj/effect/festive/street/streetlineem{ + pixel_x = 3 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cka" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/white_alleyway{ + color = "#ffe994" + }, +/area/edina/backstreet/med) +"ckb" = ( +/turf/closed/festive/whitebrick{ + color = "#555555" + }, +/area/science) +"ckc" = ( +/obj/effect/festive/street/streetlineem{ + pixel_x = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/white_alleyway{ + color = "#ffe994" + }, +/area/edina/backstreet/med) +"ckd" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"cke" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/aux) +"ckf" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = -5 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/aux) +"ckg" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/aux) +"ckh" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"cki" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"ckj" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"ckk" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"ckl" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"ckm" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"ckn" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"cko" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/structure/window/reinforced/spawner/east, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"ckp" = ( +/obj/effect/turf_decal/bot, +/obj/structure/disposalpipe/junction, +/obj/machinery/door/window/northright, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"ckq" = ( +/obj/machinery/vending/tool, +/obj/effect/turf_decal/delivery, +/obj/structure/window/reinforced/spawner/west, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"ckr" = ( +/obj/structure/table, +/obj/item/storage/box/lights/mixed, +/obj/item/storage/box/lights/mixed, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/newscaster{ + pixel_x = 32 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/indestructible, +/area/service/janitor) +"cks" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"ckt" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cku" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"ckv" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"ckw" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"ckx" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"cky" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/disposalpipe/sorting/mail{ + dir = 2; + name = "Medbay Junction"; + sortType = 9 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"ckz" = ( +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/aux) +"ckA" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/aux) +"ckB" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/aux) +"ckC" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/aux) +"ckD" = ( +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/aux) +"ckE" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/aux) +"ckF" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"ckG" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"ckI" = ( +/obj/effect/festive/street/streetlinene, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/aux) +"ckJ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"ckK" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"ckL" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"ckM" = ( +/obj/effect/festive/street/sidewalke, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"ckN" = ( +/obj/effect/festive/street/streetlineem{ + pixel_x = 3 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"ckO" = ( +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"ckP" = ( +/obj/structure/streetdecor/lampfestive, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"ckQ" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 16; + pixel_y = 16 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"ckR" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessservitor) +"ckS" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"ckT" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"ckU" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/festive/trainplatform/swcorner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"ckV" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"ckW" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"ckX" = ( +/obj/structure/festive/trainplatform/edge_east, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"ckY" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8; + pixel_y = -5 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"ckZ" = ( +/obj/effect/festive/street/sidewalkn, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/aux) +"cla" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/loading_area{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"clb" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"clc" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cld" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"cle" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"clf" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/vehicle/ridden/atv{ + dir = 8 + }, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"clg" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"clh" = ( +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessservitor) +"cli" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"clj" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"clk" = ( +/obj/effect/festive/street/streetliftedtile1, +/obj/effect/festive/street/streetlinenw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/aux) +"cll" = ( +/obj/structure/festive/trainplatform/nwcorner, +/obj/structure/festive/trainplatform/swcorner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"clm" = ( +/obj/effect/festive/street/streetlinese, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/aux) +"cln" = ( +/obj/effect/festive/street/sidewalks, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/aux) +"clo" = ( +/obj/effect/festive/street/streetlinesw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/aux) +"clp" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/aux) +"clq" = ( +/obj/effect/festive/street/streetlineem{ + pixel_x = 3 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"clr" = ( +/obj/machinery/newscaster{ + pixel_x = -32 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"cls" = ( +/obj/structure/table/reinforced, +/obj/item/assembly/timer, +/obj/item/assembly/timer, +/obj/item/multitool, +/obj/item/multitool, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clt" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"clu" = ( +/obj/machinery/status_display{ + pixel_x = 32 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clv" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/supply) +"clw" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"clx" = ( +/obj/effect/festive/street/sidewalkw, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"cly" = ( +/obj/effect/turf_decal/delivery, +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clz" = ( +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/supply) +"clA" = ( +/obj/effect/turf_decal/delivery, +/obj/structure/reagent_dispensers/watertank, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clB" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk, +/turf/open/floor/carpet/red, +/area/service/bar) +"clC" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/delivery, +/obj/structure/plasticflaps/opaque, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=2"; + freq = 1400; + location = "Tool Storage" + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clD" = ( +/obj/structure/rack, +/obj/item/airlock_painter, +/obj/item/toner, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clE" = ( +/obj/machinery/camera{ + c_tag = "Primary Tool Storage"; + dir = 4; + name = "Tool Shoppe camera" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clF" = ( +/obj/structure/disposalpipe/segment, +/turf/closed/festive/greybrick, +/area/service/janitor) +"clG" = ( +/obj/structure/closet/l3closet/janitor, +/obj/effect/decal/festive/christmas_ivy_string, +/obj/effect/turf_decal/stripes/line, +/obj/structure/disposalpipe/segment, +/turf/open/indestructible, +/area/service/janitor) +"clH" = ( +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/white, +/area/service/janitor) +"clI" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/white, +/area/service/janitor) +"clJ" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clK" = ( +/obj/machinery/door/airlock{ + glass = 1; + name = "Custodial Closet"; + req_access_txt = "26" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/disposalpipe/segment, +/turf/open/indestructible, +/area/service/janitor) +"clL" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/effect/festive/street/streetliftedtile2, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"clM" = ( +/obj/effect/festive/street/sidewalke, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"clN" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/junction, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"clO" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"clP" = ( +/obj/effect/festive/street/streetlineinnernw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"clQ" = ( +/obj/item/clothing/suit/hazardvest{ + desc = "A high-visibility lifejacket complete with whistle and slot for oxygen tanks."; + name = "emergency lifejacket" + }, +/obj/item/clothing/suit/hazardvest{ + desc = "A high-visibility lifejacket complete with whistle and slot for oxygen tanks."; + name = "emergency lifejacket" + }, +/obj/item/clothing/suit/hazardvest{ + desc = "A high-visibility lifejacket complete with whistle and slot for oxygen tanks."; + name = "emergency lifejacket" + }, +/obj/item/clothing/suit/hazardvest{ + desc = "A high-visibility lifejacket complete with whistle and slot for oxygen tanks."; + name = "emergency lifejacket" + }, +/obj/item/clothing/suit/hazardvest{ + desc = "A high-visibility lifejacket complete with whistle and slot for oxygen tanks."; + name = "emergency lifejacket" + }, +/obj/item/tank/internals/emergency_oxygen/double{ + pixel_x = 3 + }, +/obj/item/tank/internals/emergency_oxygen/double{ + pixel_x = 3 + }, +/obj/item/tank/internals/emergency_oxygen/double{ + pixel_x = 3 + }, +/obj/item/tank/internals/emergency_oxygen/double{ + pixel_x = 3 + }, +/obj/item/tank/internals/emergency_oxygen/double{ + pixel_x = 3 + }, +/obj/item/clothing/mask/breath{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/item/clothing/mask/breath{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/item/clothing/mask/breath{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/item/clothing/mask/breath{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/item/clothing/mask/breath{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/item/clothing/head/hardhat/orange{ + name = "protective hat"; + pixel_y = 9 + }, +/obj/item/clothing/head/hardhat/orange{ + name = "protective hat"; + pixel_y = 9 + }, +/obj/item/clothing/head/hardhat/orange{ + name = "protective hat"; + pixel_y = 9 + }, +/obj/item/clothing/head/hardhat/orange{ + name = "protective hat"; + pixel_y = 9 + }, +/obj/item/clothing/head/hardhat/orange{ + name = "protective hat"; + pixel_y = 9 + }, +/obj/structure/closet/crate/internals, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clR" = ( +/obj/structure/table/reinforced, +/obj/item/analyzer{ + pixel_x = 7; + pixel_y = 3 + }, +/obj/item/analyzer{ + pixel_x = 7; + pixel_y = 3 + }, +/obj/item/assembly/signaler, +/obj/item/assembly/signaler, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clS" = ( +/obj/structure/table/reinforced, +/obj/item/assembly/igniter, +/obj/item/assembly/igniter, +/obj/item/assembly/igniter, +/obj/effect/spawner/lootdrop/maintenance, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clT" = ( +/obj/structure/table/reinforced, +/obj/item/stack/rods{ + amount = 25 + }, +/obj/item/stack/cable_coil/white{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/stack/cable_coil/white, +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/obj/effect/turf_decal/bot, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clU" = ( +/obj/structure/table/reinforced, +/obj/item/radio{ + pixel_x = 5; + pixel_y = 5 + }, +/obj/item/radio{ + pixel_x = -5; + pixel_y = 5 + }, +/obj/item/radio, +/obj/machinery/light_switch{ + pixel_x = 26 + }, +/obj/machinery/light{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clV" = ( +/obj/structure/table/reinforced, +/obj/item/stack/sheet/metal{ + amount = 30 + }, +/obj/item/stack/sheet/glass{ + amount = 30 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clW" = ( +/obj/structure/table/reinforced, +/obj/item/crowbar, +/obj/item/wrench, +/obj/item/gps, +/obj/effect/turf_decal/bot, +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 23 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clX" = ( +/obj/structure/table/reinforced, +/obj/item/storage/belt/utility, +/obj/item/weldingtool, +/obj/item/clothing/head/welding, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"clY" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet) +"clZ" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"cma" = ( +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"cmb" = ( +/obj/structure/table/reinforced, +/obj/item/storage/toolbox/electrical, +/obj/effect/turf_decal/bot, +/obj/structure/sign/poster/contraband/tools{ + pixel_x = 32 + }, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"cmc" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"cmd" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"cme" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/plasteel, +/area/commons/storage/tools) +"cmf" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cmg" = ( +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cmh" = ( +/obj/effect/festive/street/streetlineeast, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cmi" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/supply) +"cmj" = ( +/obj/structure/streetdecor/lampfestive, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cmk" = ( +/obj/effect/festive/street/streetlinene, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cml" = ( +/obj/effect/festive/street/sidewalkn, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cmm" = ( +/obj/effect/festive/street/streetliftedtile1, +/obj/effect/festive/street/streetlinenw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cmn" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/streetliftedtile1, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cmo" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cmp" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"cmq" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"cmr" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/sign/poster/contraband/grey_tide{ + pixel_y = 32 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet) +"cms" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/sign/poster/contraband/hacking_guide{ + pixel_y = 32 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet) +"cmt" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/landmark/start/janitor, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/disposalpipe/junction/flip, +/turf/open/floor/plasteel/white, +/area/service/janitor) +"cmu" = ( +/obj/effect/turf_decal/delivery/white, +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/service/janitor) +"cmv" = ( +/obj/effect/festive/street/streetlinenorth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"cmw" = ( +/obj/effect/festive/street/streetlinese, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cmx" = ( +/obj/effect/festive/street/sidewalks, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cmy" = ( +/obj/effect/festive/street/streetlinesw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cmz" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/supply) +"cmA" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"cmB" = ( +/obj/effect/festive/street/streetlinewest, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cmC" = ( +/turf/closed/festive/whitebrick, +/area/edina/backstreet/med) +"cmD" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cmE" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/junction/flip, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cmF" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cmG" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cmH" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"cmI" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = -5 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"cmJ" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/supply) +"cmK" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/supply) +"cmL" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cmM" = ( +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cmN" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/sign/departments/cargo{ + pixel_x = 32; + pixel_y = 32 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/supply) +"cmO" = ( +/obj/structure/flora/grass/green, +/turf/open/floor/grass/snow/edina, +/area/edina/street/secondary/supply) +"cmP" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cmQ" = ( +/turf/open/floor/grass/snow/edina, +/area/edina/street/secondary/supply) +"cmR" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cmS" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/streetdecor/lampfestive, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cmT" = ( +/obj/machinery/light{ + light_color = "#c9d3e8" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"cmU" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"cmV" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/sidewalke, +/obj/effect/festive/street/streetliftedtile1, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cmW" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cmX" = ( +/obj/effect/festive/street/streetlineem{ + pixel_x = 3 + }, +/obj/structure/disposalpipe/junction, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cmY" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cmZ" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cna" = ( +/turf/closed/festive/redbrick, +/area/commons/dorms) +"cnb" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnc" = ( +/obj/effect/festive/street/streetlineem{ + pixel_x = 3 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnd" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"cne" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cnf" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/supply) +"cng" = ( +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/supply) +"cni" = ( +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/turf/open/floor/mineral/titanium/blue, +/area/commons/dorms) +"cnj" = ( +/obj/structure/mirror{ + pixel_y = 28 + }, +/obj/structure/sink{ + pixel_y = 22 + }, +/obj/structure/toilet{ + dir = 8 + }, +/turf/open/floor/mineral/titanium/blue, +/area/commons/dorms) +"cnk" = ( +/obj/structure/table/wood, +/obj/item/paper_bin/bundlenatural{ + pixel_x = 6; + pixel_y = 4 + }, +/obj/item/paper_bin{ + pixel_x = -6; + pixel_y = 4 + }, +/obj/item/pen/fountain, +/turf/open/floor/wood, +/area/commons/dorms) +"cnl" = ( +/turf/open/floor/carpet, +/area/commons/dorms) +"cnm" = ( +/obj/structure/fireplace, +/turf/open/floor/carpet, +/area/commons/dorms) +"cnn" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/supply) +"cno" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina) +"cnp" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnq" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"cnr" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/festive/street/streetlinewest, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"cns" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cnt" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"cnu" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"cnv" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"cnw" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/princess) +"cnx" = ( +/obj/effect/decal/festive/fairylights, +/obj/structure/flora/grass/green, +/turf/open/floor/grass/snow/edina, +/area/edina/street/primary/perimeter) +"cny" = ( +/obj/effect/decal/festive/fairylights, +/turf/open/floor/grass/snow/edina, +/area/edina/street/primary/perimeter) +"cnz" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/stairs/left, +/area/edina/street/primary/perimeter) +"cnA" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/stairs/right, +/area/edina/street/primary/perimeter) +"cnB" = ( +/turf/open/floor/grass/snow/edina, +/area/edina/street/primary/perimeter) +"cnC" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnD" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnE" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnF" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/supply) +"cnG" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnH" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnI" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnJ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnK" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/junction/flip{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnL" = ( +/obj/effect/festive/street/sidewalkw, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cnM" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cnN" = ( +/obj/effect/festive/street/sidewalke, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cnO" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnP" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnQ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnR" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/junction/flip{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnS" = ( +/obj/machinery/button/door{ + id = "chemistry_shutters"; + name = "chemical factory garage"; + pixel_x = -8; + pixel_y = -6; + req_access_txt = "5; 33" + }, +/turf/closed/festive/whitebrick{ + color = "#ffe6a8" + }, +/area/medical/chemistry) +"cnT" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/festive/street/streetlinenm{ + pixel_y = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnU" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnV" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnW" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnX" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/disposalpipe/junction/flip{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnY" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/festive/street/streetlinenm{ + pixel_y = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cnZ" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"coa" = ( +/obj/effect/festive/street/sidewalkn, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"cob" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"coc" = ( +/obj/effect/festive/street/streetlinenw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"cod" = ( +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"coe" = ( +/obj/effect/festive/street/streetlinene, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"cof" = ( +/obj/effect/festive/street/streetlinenw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"cog" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"coh" = ( +/obj/effect/festive/street/sidewalkw, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"coi" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"coj" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cok" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"col" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"com" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"con" = ( +/obj/structure/sign/departments/cargo{ + pixel_x = 32; + pixel_y = 32 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"coo" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cop" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"coq" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cor" = ( +/obj/structure/curtain, +/turf/open/floor/mineral/titanium/blue, +/area/commons/dorms) +"cos" = ( +/obj/structure/festive/trainplatform/edge_east, +/turf/open/floor/grass/snow/edina, +/area/edina) +"cot" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 16 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cou" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cov" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cow" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cox" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"coy" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"coz" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"coA" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/streetdecor/lampfestive{ + pixel_x = 16 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"coB" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/structure/streetdecor/lampfestive{ + pixel_x = 16 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"coC" = ( +/obj/effect/festive/street/sidewalkn, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"coD" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"coE" = ( +/obj/effect/festive/street/sidewalkn, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"coF" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"coG" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"coH" = ( +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"coI" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"coJ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"coK" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"coL" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 16; + pixel_y = 10 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"coM" = ( +/obj/structure/plasticflaps/opaque, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/cargo/sorting) +"coN" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowWELeftEnd, +/turf/open/floor/wood, +/area/commons/dorms) +"coO" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"coP" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"coQ" = ( +/obj/effect/festive/street/streetlinene, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"coR" = ( +/turf/open/floor/carpet/red, +/area/commons/dorms) +"coS" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"coT" = ( +/obj/effect/festive/street/sidewalkn, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"coU" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"coV" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"coW" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"coX" = ( +/obj/effect/festive/street/sidewalkn, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"coY" = ( +/obj/effect/festive/street/streetlinenw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"coZ" = ( +/obj/effect/festive/street/streetlinene, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpa" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"cpb" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"cpc" = ( +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"cpd" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/festive/street/streetlineinnerne, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"cpe" = ( +/obj/effect/festive/street/streetlinenw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"cpf" = ( +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"cpg" = ( +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"cph" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"cpi" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"cpj" = ( +/obj/effect/festive/street/streetlineinnerne, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpk" = ( +/obj/structure/festive/trainplatform/edge_east, +/obj/structure/festive/trainplatform/edge_east, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cpl" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpm" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"cpn" = ( +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"cpo" = ( +/obj/effect/festive/street/streetliftedtile1, +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpp" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpq" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpr" = ( +/obj/effect/festive/street/sidewalknsm, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"cps" = ( +/obj/effect/festive/street/streetlineinnersw{ + pixel_x = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpt" = ( +/turf/open/floor/grass, +/area/edina) +"cpu" = ( +/obj/effect/festive/street/sidewalks, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpv" = ( +/obj/effect/festive/street/sidewalks, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpw" = ( +/obj/effect/festive/street/sidewalks, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpx" = ( +/obj/effect/festive/street/streetlineinnerse, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpy" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 16; + pixel_y = 16 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cpz" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"cpA" = ( +/obj/structure/festive/trainplatform/edge_east, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cpB" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cpC" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cpD" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"cpE" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/railing, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cpF" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cpG" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/festive/trainplatform/secorner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cpH" = ( +/obj/structure/festive/trainplatform/edge_north, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cpI" = ( +/obj/structure/festive/trainplatform/swcorner, +/obj/structure/festive/trainplatform/secorner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cpJ" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"cpK" = ( +/obj/structure/festive/trainplatform/swcorner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cpL" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/festive/trainplatform/swcorner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cpM" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cpN" = ( +/obj/effect/festive/street/streetlineem, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpO" = ( +/obj/effect/festive/street/streetlineem, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpP" = ( +/obj/effect/festive/street/streetlineem, +/obj/vehicle/sealed/vectorcraft/cyber, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpQ" = ( +/obj/effect/festive/street/streetlineem, +/obj/vehicle/sealed/vectorcraft, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpR" = ( +/obj/effect/festive/street/streetlineem, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpS" = ( +/obj/structure/fireplace{ + dir = 4; + pixel_x = -7 + }, +/turf/open/floor/carpet/blue, +/area/commons/dorms) +"cpT" = ( +/obj/structure/flora/grass/green, +/turf/open/floor/grass/snow/edina, +/area/edina/street/primary/perimeter) +"cpU" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpV" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpW" = ( +/obj/effect/festive/street/streetlineem, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpX" = ( +/obj/effect/festive/street/streetlineem, +/obj/effect/turf_decal/weather/snow/corner, +/obj/vehicle/sealed/vectorcraft/auto{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpY" = ( +/obj/effect/festive/street/streetlineem, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cpZ" = ( +/obj/effect/festive/street/streetlineem, +/obj/vehicle/sealed/vectorcraft/truck{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cqa" = ( +/obj/effect/festive/street/streetlineem, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cqb" = ( +/obj/machinery/door/airlock/mining/glass, +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"cqc" = ( +/obj/effect/festive/street/streetlineem{ + pixel_x = 3 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cqd" = ( +/obj/machinery/door/airlock/wood/glass{ + glass = 0 + }, +/turf/open/floor/wood, +/area/commons/dorms) +"cqe" = ( +/obj/structure/chair/sofa/right, +/turf/open/floor/wood, +/area/commons/dorms) +"cqf" = ( +/obj/structure/chair/sofa/left, +/turf/open/floor/wood, +/area/commons/dorms) +"cqg" = ( +/obj/structure/festive/trainplatform/edge_south, +/turf/open/floor/grass/snow/edina, +/area/edina) +"cqh" = ( +/obj/structure/festive/trainplatform/nwcorner, +/turf/open/floor/grass/snow/edina, +/area/edina) +"cqi" = ( +/turf/open/floor/festive/white_alleyway{ + color = "#ffe994" + }, +/area/edina/backstreet/med) +"cqj" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"cqk" = ( +/obj/effect/festive/street/sidewalknsm, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"cql" = ( +/obj/effect/festive/street/streetlineeast, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"cqm" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"cqn" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowWERightEnd, +/turf/open/floor/wood, +/area/commons/dorms) +"cqo" = ( +/obj/effect/festive/street/streetlinewest{ + pixel_x = -1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"cqp" = ( +/obj/effect/festive/street/streetlinese, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"cqq" = ( +/obj/effect/festive/street/streetlinesw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"cqr" = ( +/obj/effect/festive/street/streetlineem{ + pixel_x = 1 + }, +/turf/open/floor/festive/white_alleyway{ + color = "#ffe994" + }, +/area/edina/backstreet/med) +"cqs" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cqt" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/festive/street/streetlineem, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cqu" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cqv" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cqw" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cqx" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/closet/crate/wooden, +/obj/effect/decal/festive/red_stockings, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"cqy" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/table/reinforced, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"cqz" = ( +/obj/structure/table/reinforced, +/obj/effect/decal/festive/red_stockings, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"cqA" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"cqB" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cqC" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cqD" = ( +/obj/structure/closet/cabinet{ + pixel_y = 15 + }, +/obj/item/coin/iron, +/obj/item/coin/iron, +/obj/item/coin/iron, +/turf/open/floor/carpet/black, +/area/commons/dorms) +"cqG" = ( +/obj/structure/chair/sofa/left{ + dir = 4 + }, +/turf/open/floor/wood, +/area/commons/dorms) +"cqH" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp/green{ + on = 0; + pixel_x = -7; + pixel_y = 12 + }, +/turf/open/floor/wood, +/area/commons/dorms) +"cqI" = ( +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/maintenance/bar) +"cqJ" = ( +/obj/structure/chair/sofa/right{ + dir = 8 + }, +/turf/open/floor/wood, +/area/commons/dorms) +"cqK" = ( +/obj/structure/flora/tree/pine/xmas, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/supply) +"cqL" = ( +/obj/structure/chair/sofa/right, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"cqM" = ( +/obj/structure/chair/sofa, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"cqN" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/obj/effect/landmark/start/quartermaster, +/obj/structure/chair/sofa/left, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"cqO" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cqP" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cqQ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cqR" = ( +/obj/structure/closet/crate/trashcart, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 3; + name = "3maintenance loot spawner" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cqS" = ( +/obj/structure/sign/poster/contraband/bountyhunters{ + pixel_y = -32 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/cargo/qm) +"cqT" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"cqU" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"cqV" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"cqW" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"cqX" = ( +/obj/effect/festive/street/streetlinesw, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"cqY" = ( +/obj/effect/festive/street/streetlinese, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"cqZ" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"cra" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"crb" = ( +/obj/effect/festive/street/streetlinesouth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crc" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crd" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"cre" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"crf" = ( +/obj/effect/festive/street/streetlinenorth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"crg" = ( +/obj/effect/festive/street/streetlinenw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"crh" = ( +/obj/effect/festive/street/streetlinene, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"cri" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"crj" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"crk" = ( +/obj/effect/festive/street/streetlinewest{ + pixel_x = -1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crl" = ( +/obj/effect/festive/street/streetlinene, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crm" = ( +/obj/effect/festive/street/streetlinenw, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crn" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"cro" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crp" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/structure/disposalpipe/sorting/mail{ + dir = 2; + name = "Medbay Junction"; + sortType = 9 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"crq" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"crr" = ( +/obj/effect/festive/street/streetlinenorth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"crs" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crt" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"cru" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"crv" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"crw" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/caution{ + dir = 8; + pixel_x = 6; + pixel_y = 16 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crx" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"cry" = ( +/obj/effect/festive/street/streetlineinnersw, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crz" = ( +/obj/effect/festive/street/streetlinesw, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crA" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crB" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crC" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"crD" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"crE" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"crF" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crG" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"crH" = ( +/obj/effect/festive/street/streetlineinnersw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crI" = ( +/obj/effect/festive/street/sidewalks, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"crJ" = ( +/obj/machinery/light{ + light_color = "#c9d3e8" + }, +/turf/open/floor/carpet/black, +/area/commons/dorms) +"crK" = ( +/obj/structure/bed, +/obj/item/bedsheet/random, +/obj/item/bedsheet/random, +/turf/open/floor/carpet/black, +/area/commons/dorms) +"crL" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"crM" = ( +/obj/structure/chair/sofa/right{ + dir = 4 + }, +/turf/open/floor/wood, +/area/commons/dorms) +"crN" = ( +/obj/structure/table/wood, +/obj/item/dice/d20, +/turf/open/floor/wood, +/area/commons/dorms) +"crO" = ( +/obj/structure/chair/sofa/left{ + dir = 8 + }, +/turf/open/floor/wood, +/area/commons/dorms) +"crP" = ( +/obj/effect/festive/street/streetlinesw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"crQ" = ( +/obj/effect/festive/street/streetlinesw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"crR" = ( +/obj/effect/festive/street/streetlinesouth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"crS" = ( +/obj/effect/festive/street/sidewalks, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"crT" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crU" = ( +/obj/effect/festive/street/sidewalks, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"crV" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"crW" = ( +/obj/effect/festive/street/streetlinesouth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"crX" = ( +/obj/effect/festive/street/streetlinesw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"crY" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"crZ" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"csa" = ( +/obj/effect/festive/street/sidewalks, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"csb" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/festive/street/streetlineinnerse, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/servitor) +"csc" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8 + }, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"csd" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"cse" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = 20 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessservitor) +"csf" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"csg" = ( +/obj/effect/festive/street/streetliftedtile1, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"csh" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/turf_decal/arrows/white, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"csi" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"csj" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8; + pixel_y = 20 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessservitor) +"csk" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"csl" = ( +/obj/effect/festive/street/streetlinese, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"csm" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"csn" = ( +/obj/structure/grille, +/obj/structure/festive/whitebrick/windowNSMiddle, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating, +/area/cargo/sorting) +"cso" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/festive/street/streetliftedtile2, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"csp" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = 16 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"csq" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = 25 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"csr" = ( +/obj/structure/chair/comfy/black{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"css" = ( +/obj/structure/table/wood/fancy/blue, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"cst" = ( +/obj/structure/table/wood/fancy/blue, +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"csu" = ( +/obj/structure/chair/comfy/black{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"csv" = ( +/obj/machinery/vending/cigarette/syndicate, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"csw" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/festive/street/streetlinenm{ + pixel_y = 3 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/primary/servitor) +"csx" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/primary/servitor) +"csy" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessservitor) +"csz" = ( +/obj/effect/festive/street/sidewalkw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"csA" = ( +/obj/effect/festive/street/sidewalkwem, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"csB" = ( +/obj/effect/festive/street/sidewalke, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessservitor) +"csC" = ( +/obj/structure/sign/directions/supply{ + dir = 4; + pixel_x = 32; + pixel_y = -32 + }, +/obj/structure/sign/directions/evac{ + pixel_x = 32; + pixel_y = -40 + }, +/obj/structure/sign/directions/engineering{ + dir = 1; + pixel_x = 32; + pixel_y = -24 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessservitor) +"csD" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"csE" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"csF" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/supply) +"csG" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"csH" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"csI" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"csJ" = ( +/obj/effect/festive/street/streetlinesw, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"csK" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/supply) +"csL" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"csM" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"csN" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"csO" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"csP" = ( +/obj/structure/festive/bluebrick/windowWELeftEnd, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/cryopod) +"csQ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/south) +"csR" = ( +/obj/effect/festive/street/sidewalkw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"csS" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"csT" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"csU" = ( +/obj/effect/festive/street/sidewalke, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"csV" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/junction{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/south) +"csW" = ( +/obj/structure/sign/directions/evac{ + dir = 1 + }, +/turf/closed/festive/bluebrick, +/area/commons/cryopod) +"csX" = ( +/obj/structure/festive/bluebrick/windowNSRightEnd, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/cryopod) +"csY" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8 + }, +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/south) +"csZ" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"cta" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctb" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctc" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctd" = ( +/obj/effect/festive/street/streetlineeast, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"cte" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8 + }, +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/obj/structure/disposalpipe/segment, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/south) +"ctf" = ( +/obj/structure/festive/bluebrick/windowNSLeftEnd, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/cryopod) +"ctg" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Hotel" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/blue, +/area/commons/cryopod) +"cth" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"cti" = ( +/obj/effect/festive/street/streetlinenw, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctj" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctk" = ( +/obj/effect/festive/street/streetlinene, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctl" = ( +/obj/effect/festive/street/streetlinenw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctm" = ( +/obj/effect/festive/street/streetlinene, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctn" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"cto" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Hotel" + }, +/turf/open/floor/carpet/blue, +/area/commons/cryopod) +"ctp" = ( +/obj/structure/festive/bluebrick/windowNSMiddle, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/cryopod) +"ctq" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctr" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"cts" = ( +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctt" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/junction/flip{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/south) +"ctu" = ( +/obj/effect/festive/street/sidewalknsm, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctv" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctw" = ( +/obj/effect/festive/street/streetlinesw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctx" = ( +/obj/effect/festive/street/streetlinese, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"cty" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile1, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctz" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctA" = ( +/obj/effect/festive/street/streetlinenw, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctB" = ( +/obj/effect/festive/street/streetlinene, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctC" = ( +/obj/effect/festive/street/streetlinenorth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctD" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctE" = ( +/obj/effect/festive/street/sidewalks, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctF" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctG" = ( +/obj/effect/festive/street/streetlinesouth, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"ctH" = ( +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/south) +"ctI" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8; + pixel_y = 16 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/south) +"ctJ" = ( +/obj/structure/festive/trainplatform/edge_north, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/south) +"ctK" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = 16 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"ctL" = ( +/obj/effect/festive/street/streetlinewest, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"ctM" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"ctN" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8; + pixel_y = 16 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"ctO" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"ctP" = ( +/obj/effect/festive/street/sidewalkw, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"ctQ" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/plating/dirt/space, +/area/edina) +"ctR" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"ctS" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/festive/street/streetliftedtile2, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"ctT" = ( +/obj/effect/festive/street/sidewalke, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"ctU" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"ctV" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"ctW" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"ctX" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"ctY" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"ctZ" = ( +/obj/effect/turf_decal/caution, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cua" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/festive/street/streetlinenm{ + pixel_y = 1 + }, +/mob/living/simple_animal/jacq/car_spawner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cub" = ( +/obj/effect/festive/street/streetlinenm{ + pixel_y = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cuc" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/festive/street/streetlinenm{ + pixel_y = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cud" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cue" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cuf" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/supply) +"cug" = ( +/obj/structure/statue/snow/snowman, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/supply) +"cuh" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cui" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cuj" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cuk" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cul" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"cum" = ( +/obj/effect/festive/street/streetlinenw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"cun" = ( +/obj/effect/festive/street/streetlinene, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"cuo" = ( +/obj/effect/festive/street/streetlinenw, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"cup" = ( +/obj/effect/festive/street/streetlinene, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"cuq" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"cur" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"cus" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"cuu" = ( +/obj/effect/decal/festive/mistletoe, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"cuv" = ( +/obj/structure/chair/comfy/black{ + dir = 1 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"cuw" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"cux" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"cuy" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"cuz" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/secondary/command) +"cuA" = ( +/obj/effect/festive/street/streetlinesw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/princess) +"cuB" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"cuC" = ( +/obj/effect/festive/street/sidewalkwem, +/obj/effect/festive/street/streetliftedtile2, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"cuD" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cuE" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"cuF" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"cuG" = ( +/obj/effect/festive/street/sidewalkn, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"cuH" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"cuI" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile1, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"cuJ" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile2, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"cuK" = ( +/obj/effect/festive/street/sidewalks, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"cuL" = ( +/obj/structure/disposalpipe/junction{ + dir = 4 + }, +/obj/structure/sign/departments/cargo{ + pixel_x = 32; + pixel_y = -32 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"cuM" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/supply) +"cuN" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/indestructible, +/area/cargo/office) +"cuO" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/supply) +"cuP" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/disposalpipe/junction{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/secondary/supply) +"cuQ" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWERightEnd, +/obj/structure/cable/yellow, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"cuR" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWE, +/obj/structure/cable/yellow, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"cuS" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"cuT" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowWELeftEnd, +/obj/structure/cable/yellow, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"cuU" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"cuV" = ( +/obj/structure/sign/departments/security, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/closed/festive/redbrick, +/area/security/checkpoint/science) +"cuW" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSRightEnd, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"cuX" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSMiddle, +/obj/machinery/atmospherics/pipe/heat_exchanging/junction{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/junction{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"cuY" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSLeftEnd, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/science) +"cuZ" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"cva" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"cvb" = ( +/obj/machinery/door/airlock/security/glass{ + id_tag = "meddoor"; + name = "Medical Cell"; + req_access_txt = "63" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"cvc" = ( +/obj/machinery/light, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"cvd" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel, +/area/security/checkpoint/medical) +"cve" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/grass/snow/edina, +/area/edina) +"cvf" = ( +/obj/structure/fence, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/grass/snow/edina, +/area/edina) +"cvg" = ( +/obj/effect/festive/street/sidewalkw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cvh" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cvi" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"cvj" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessprogress) +"cvk" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"cvl" = ( +/obj/effect/festive/street/streetlineeast, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"cvm" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"cvn" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessprogress) +"cvo" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/progress) +"cvp" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessprogress) +"cvq" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cvr" = ( +/obj/effect/festive/street/streetlinenw, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cvs" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cvt" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cvu" = ( +/obj/structure/spacevine, +/turf/open/floor/grass, +/area/edina) +"cvv" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cvw" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cvx" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cvy" = ( +/obj/effect/festive/street/streetliftedtile2, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cvz" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile1, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"cvA" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cvB" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cvC" = ( +/obj/effect/festive/street/sidewalks, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"cvD" = ( +/obj/effect/festive/street/streetlinesouth, +/obj/effect/turf_decal/arrows/white{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"cvE" = ( +/obj/effect/festive/street/streetlinesw, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"cvF" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cvG" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/north) +"cvH" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = 20 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/north) +"cvI" = ( +/obj/effect/festive/street/streetlinewest, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/north) +"cvJ" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/junction, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/north) +"cvK" = ( +/turf/open/floor/plating/beach/water, +/area/edina) +"cvL" = ( +/turf/open/water, +/area/edina) +"cvM" = ( +/obj/structure/fence/post{ + dir = 8 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"cvN" = ( +/obj/structure/disposalpipe/junction/flip{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/south) +"cvO" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cvP" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cvQ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/south) +"cvR" = ( +/obj/effect/festive/street/sidewalkn, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"cvS" = ( +/turf/closed/wall/mineral/wood/nonmetal, +/area/maintenance/bar) +"cvT" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/med) +"cvU" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/wood, +/area/maintenance/bar) +"cvV" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cvW" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cvX" = ( +/obj/structure/spacevine, +/turf/open/floor/plating/beach/sand, +/area/edina) +"cvY" = ( +/obj/machinery/vending/clothing{ + extended_inventory = 1; + scan_id = 0 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cvZ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cwa" = ( +/obj/structure/chair/sofa/right{ + dir = 1 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cwb" = ( +/obj/machinery/door/airlock/security{ + name = "Security Post - Cargo"; + req_access_txt = "63" + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/security/checkpoint/supply) +"cwc" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Break room" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible{ + icon_state = "sepia" + }, +/area/cargo) +"cwd" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cwe" = ( +/obj/structure/chair/wood/normal{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cwf" = ( +/obj/structure/mirror/magic/lesser{ + pixel_x = 32 + }, +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/maintenance/bar) +"cwg" = ( +/turf/open/floor/plating/beach/coastline_t{ + dir = 10 + }, +/area/edina) +"cwh" = ( +/turf/open/floor/plating/beach/coastline_t, +/area/edina) +"cwi" = ( +/turf/open/floor/plating/beach/coastline_t/sandwater_inner{ + dir = 8 + }, +/area/edina) +"cwj" = ( +/obj/machinery/vending/autodrobe{ + extended_inventory = 1; + scan_id = 0 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cwk" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/junction/yjunction, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/turf/open/indestructible, +/area/commons/locker) +"cwl" = ( +/turf/open/floor/wood, +/area/maintenance/bar) +"cwm" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cwn" = ( +/turf/open/floor/plating/beach/coastline_t{ + dir = 8 + }, +/area/edina) +"cwo" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/turf/open/floor/wood, +/area/maintenance/bar) +"cwp" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/wood, +/area/maintenance/bar) +"cwq" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/wood, +/area/maintenance/bar) +"cwr" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/stairs/stairsnorth, +/area/maintenance/bar) +"cws" = ( +/obj/item/storage/toolbox/emergency, +/turf/open/floor/wood, +/area/maintenance/bar) +"cwt" = ( +/turf/open/floor/plating/beach/coastline_t{ + dir = 1 + }, +/area/edina) +"cwu" = ( +/turf/open/floor/plating/beach/coastline_t{ + dir = 5 + }, +/area/edina) +"cwv" = ( +/obj/machinery/icecream_vat, +/turf/open/floor/grass/snow/edina, +/area/edina) +"cww" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cwx" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"cwy" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"cwz" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/cargo/storage) +"cwA" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall/mineral/wood/nonmetal, +/area/maintenance/bar) +"cwB" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall/mineral/wood/nonmetal, +/area/maintenance/bar) +"cwC" = ( +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/obj/structure/window/reinforced/tinted{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/trainplatform/safe, +/area/maintenance/bar) +"cwD" = ( +/turf/open/floor/plating/beach/sand, +/area/edina) +"cwE" = ( +/turf/open/floor/plating/beach/coastline_t/sandwater_inner{ + dir = 1 + }, +/area/edina) +"cwF" = ( +/obj/structure/spacevine, +/turf/open/floor/plating/beach/coastline_t{ + dir = 1 + }, +/area/edina) +"cwG" = ( +/obj/machinery/vending/cola/random, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/wood, +/area/maintenance/bar) +"cwH" = ( +/obj/machinery/vending/cigarette, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/wood, +/area/maintenance/bar) +"cwI" = ( +/obj/structure/festive/trainplatform/edge_west, +/obj/structure/chair/stool/bar, +/turf/open/floor/light, +/area/maintenance/bar) +"cwJ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/festive/trainplatform/safe, +/area/maintenance/bar) +"cwK" = ( +/turf/open/floor/festive/trainplatform/safe, +/area/maintenance/bar) +"cwL" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/festive/trainplatform/safe, +/area/maintenance/bar) +"cwM" = ( +/obj/structure/festive/trainplatform/edge_east, +/obj/structure/chair/stool/bar, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/light, +/area/maintenance/bar) +"cwN" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/wood, +/area/maintenance/bar) +"cwO" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/indestructible, +/area/commons/locker) +"cwP" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cwQ" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cwR" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 16; + pixel_y = 10 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cwS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cwT" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/princessperimeter/south) +"cwU" = ( +/obj/effect/festive/street/sidewalkn, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cwV" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/trainplatform/safe, +/area/maintenance/bar) +"cwW" = ( +/obj/structure/festive/trainplatform/edge_east, +/obj/structure/chair/stool/bar, +/turf/open/floor/light, +/area/maintenance/bar) +"cwX" = ( +/obj/structure/spacevine, +/turf/open/floor/grass/snow/edina, +/area/edina) +"cwY" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"cwZ" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cxa" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cxb" = ( +/obj/effect/festive/street/streetlineem, +/turf/open/floor/festive/cobblestone/safe, +/area/edina/street) +"cxc" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile1, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cxd" = ( +/obj/effect/festive/street/sidewalknsm, +/obj/effect/festive/street/streetliftedtile2, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cxe" = ( +/obj/effect/festive/street/sidewalks, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"cxf" = ( +/turf/closed/festive/bluebrick, +/area/maintenance/department/medical) +"cxg" = ( +/obj/machinery/door/airlock/glass_large{ + name = "Clinic" + }, +/obj/structure/barricade/wooden/snowed, +/turf/open/floor/plating, +/area/maintenance/department/medical) +"cxh" = ( +/obj/structure/barricade/wooden/snowed, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cxi" = ( +/obj/structure/grille, +/obj/structure/festive/bluebrick/windowNSRight, +/obj/structure/barricade/wooden/crude/snow, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cxj" = ( +/obj/structure/grille, +/obj/structure/festive/bluebrick/windowNSMiddle, +/obj/structure/barricade/wooden/crude/snow, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cxk" = ( +/obj/structure/grille, +/obj/structure/festive/bluebrick/windowNSLeftEnd, +/obj/structure/barricade/wooden/crude/snow, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cxl" = ( +/turf/closed/festive/bluebrick/bluebrickts, +/area/maintenance/department/medical) +"cxm" = ( +/obj/structure/festive/trainplatform/edge_west, +/turf/open/floor/grass/snow/edina, +/area/edina) +"cxn" = ( +/obj/structure/festive/trainplatform/edge_west, +/obj/structure/festive/trainplatform/edge_east, +/turf/open/floor/festive/stairs/stairssouth, +/area/edina/street/primary/perimeter) +"cxo" = ( +/obj/structure/sign/directions/command{ + dir = 1; + pixel_y = -8 + }, +/turf/closed/festive/greybrick/greybrickcornernw, +/area/edina/street/primary/perimeter) +"cxp" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSRightEnd, +/turf/open/floor/festive/trainplatform, +/area/edina/street/primary/perimeter) +"cxq" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSLeftEnd, +/turf/open/floor/festive/trainplatform, +/area/edina/street/primary/perimeter) +"cxr" = ( +/turf/closed/festive/greybrick/greybrickcornerne, +/area/edina/street/primary/perimeter) +"cxs" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = -8; + pixel_y = 16 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cxt" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"cxu" = ( +/obj/machinery/door/airlock/wood, +/obj/effect/decal/festive/christmas_reef, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/wood, +/area/maintenance/bar) +"cxv" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/wood, +/area/maintenance/bar) +"cxy" = ( +/obj/structure/window/fulltile, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"cxz" = ( +/obj/machinery/door/airlock/wood/glass, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"cxA" = ( +/turf/closed/festive/greybrick, +/area/maintenance/bar/cafe) +"cxB" = ( +/obj/machinery/door/airlock/wood, +/turf/open/floor/carpet/monochrome, +/area/maintenance/bar/cafe) +"cxC" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSRight, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar/cafe) +"cxD" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSMiddle, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar/cafe) +"cxE" = ( +/obj/structure/grille, +/obj/structure/festive/greybrick/windowNSLeftEnd, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar/cafe) +"cxF" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/intersection/servsuppaux) +"cxG" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cxH" = ( +/obj/effect/landmark/start/assistant, +/turf/open/floor/festive/trainplatform/safe, +/area/maintenance/bar) +"cxI" = ( +/obj/structure/grille, +/obj/structure/festive/bluebrick/windowWERightEnd, +/obj/structure/barricade/wooden/crude/snow, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cxJ" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cxK" = ( +/obj/effect/decal/cleanable/blood/splats, +/turf/open/floor/plating, +/area/maintenance/department/medical) +"cxL" = ( +/obj/structure/chair/comfy/black, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cxM" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/chair/comfy/black, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cxN" = ( +/turf/open/floor/plating, +/area/maintenance/department/medical) +"cxO" = ( +/obj/structure/closet/crate/freezer/blood, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cxP" = ( +/obj/structure/grille, +/obj/structure/festive/bluebrick/windowdoorweend2, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cxR" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/chair/office/dark, +/turf/open/floor/plating, +/area/maintenance/department/medical) +"cxS" = ( +/obj/machinery/iv_drip{ + pixel_y = -16 + }, +/obj/structure/table, +/obj/item/clipboard, +/obj/item/pen/fountain, +/obj/item/clothing/gloves/color/latex, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cxT" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/festive/trainplatform, +/area/edina/street/primary/perimeter) +"cxU" = ( +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/festive/trainplatform, +/area/edina/street/primary/perimeter) +"cxZ" = ( +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/structure/toilet{ + pixel_x = -2; + pixel_y = 8 + }, +/turf/open/floor/plasteel/freezer, +/area/commons/dorms) +"cya" = ( +/obj/machinery/shower{ + pixel_y = 8 + }, +/obj/structure/curtain{ + color = "#FF5555" + }, +/turf/open/floor/plasteel/freezer, +/area/commons/dorms) +"cyb" = ( +/obj/structure/chair/comfy/black, +/turf/open/floor/carpet/monochrome, +/area/maintenance/bar/cafe) +"cyc" = ( +/turf/open/floor/carpet/monochrome, +/area/maintenance/bar/cafe) +"cyd" = ( +/obj/structure/chair/comfy/black{ + dir = 4 + }, +/turf/open/floor/carpet/monochrome, +/area/maintenance/bar/cafe) +"cye" = ( +/obj/structure/table/wood/fancy/monochrome, +/turf/open/floor/carpet/monochrome, +/area/maintenance/bar/cafe) +"cyf" = ( +/obj/structure/chair/comfy/black{ + dir = 8 + }, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/carpet/monochrome, +/area/maintenance/bar/cafe) +"cyg" = ( +/obj/structure/chair/sofa/corner{ + dir = 1 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyh" = ( +/obj/structure/chair/sofa, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyi" = ( +/obj/structure/chair/sofa, +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyj" = ( +/obj/structure/chair/sofa/left, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/obj/machinery/airalarm/directional/north, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyk" = ( +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/obj/machinery/vending/kink{ + extended_inventory = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyl" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cym" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyn" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyo" = ( +/obj/structure/chair/comfy/brown{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyp" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyq" = ( +/obj/structure/chair/comfy/brown{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyr" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"cys" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/festive/fairylights, +/obj/structure/chair/sofa/left{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyt" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"cyu" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/effect/decal/festive/fairylights, +/obj/machinery/vending/boozeomat{ + pixel_y = 31 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyv" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/festive/fairylights, +/obj/structure/table/glass, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyw" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyx" = ( +/obj/effect/landmark/xmastree/rdrod, +/turf/open/floor/festive/trainplatform/safe, +/area/maintenance/bar) +"cyA" = ( +/obj/structure/grille, +/obj/structure/festive/bluebrick/windowWELeftEnd, +/obj/structure/barricade/wooden/crude/snow, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cyB" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/plating, +/area/maintenance/department/medical) +"cyC" = ( +/obj/machinery/door/airlock/silver/glass{ + name = "Clinic" + }, +/obj/structure/barricade/wooden/snowed, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cyD" = ( +/obj/machinery/door/airlock/silver/glass{ + name = "Patient Room 1" + }, +/turf/open/floor/plating, +/area/maintenance/department/medical) +"cyE" = ( +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cyF" = ( +/obj/structure/bed, +/obj/item/bedsheet/medical, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cyI" = ( +/obj/structure/sink{ + dir = 8; + pixel_x = -12; + pixel_y = 2 + }, +/turf/open/floor/plasteel/freezer, +/area/commons/dorms) +"cyJ" = ( +/obj/machinery/light/small, +/turf/open/floor/plasteel/freezer, +/area/commons/dorms) +"cyK" = ( +/obj/machinery/door/airlock/silver{ + name = "Bathroom" + }, +/turf/open/floor/plasteel/freezer, +/area/commons/dorms) +"cyL" = ( +/obj/structure/table/wood/fancy/monochrome, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/carpet/monochrome, +/area/maintenance/bar/cafe) +"cyM" = ( +/turf/open/floor/plasteel/checker, +/area/maintenance/bar/cafe) +"cyN" = ( +/obj/machinery/light{ + dir = 1; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel/checker, +/area/maintenance/bar/cafe) +"cyO" = ( +/obj/structure/table/reinforced, +/obj/machinery/chem_dispenser/drinks/fullupgrade, +/turf/open/floor/plasteel/checker, +/area/maintenance/bar/cafe) +"cyP" = ( +/obj/structure/table/reinforced, +/obj/machinery/microwave{ + desc = "Cooks and boils stuff, somehow."; + pixel_y = 8 + }, +/turf/open/floor/plasteel/checker, +/area/maintenance/bar/cafe) +"cyQ" = ( +/obj/structure/chair/sofa{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyR" = ( +/obj/structure/table/wood/poker, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyS" = ( +/obj/structure/table/wood/poker, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyT" = ( +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyU" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyV" = ( +/obj/structure/chair/comfy/brown{ + buildstackamount = 0; + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyW" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/storage) +"cyX" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyY" = ( +/obj/structure/table/glass, +/turf/open/floor/wood, +/area/maintenance/bar) +"cyZ" = ( +/obj/structure/table, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cza" = ( +/obj/structure/table, +/obj/machinery/door/window/eastleft{ + dir = 1; + icon_state = "right"; + name = "Abandoned Clinic"; + req_access_txt = "5" + }, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"czb" = ( +/turf/closed/festive/bluebrick/bluebrickcornernw, +/area/maintenance/department/medical) +"czc" = ( +/obj/structure/streetdecor/welcomesign, +/turf/open/floor/festive/trainplatform, +/area/edina/street/primary/perimeter) +"czf" = ( +/obj/structure/fireplace{ + dir = 8; + pixel_x = -24; + pixel_y = 26 + }, +/obj/structure/chair/comfy/black, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"czg" = ( +/obj/structure/chair/comfy/black{ + dir = 1 + }, +/turf/open/floor/carpet/monochrome, +/area/maintenance/bar/cafe) +"czh" = ( +/obj/structure/chair/comfy/black{ + dir = 8 + }, +/turf/open/floor/carpet/monochrome, +/area/maintenance/bar/cafe) +"czi" = ( +/obj/structure/table/reinforced, +/turf/open/floor/plasteel/checker, +/area/maintenance/bar/cafe) +"czj" = ( +/obj/effect/landmark/start/assistant, +/turf/open/floor/plasteel/checker, +/area/maintenance/bar/cafe) +"czk" = ( +/obj/machinery/door/airlock/silver, +/turf/open/floor/plasteel/checker, +/area/maintenance/bar/cafe) +"czl" = ( +/obj/structure/closet/secure_closet/freezer/fridge, +/turf/open/floor/plasteel/checker, +/area/maintenance/bar/cafe) +"czm" = ( +/obj/structure/chair/sofa{ + dir = 4 + }, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"czn" = ( +/obj/structure/table/wood/poker, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/wood, +/area/maintenance/bar) +"czo" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/wood, +/area/maintenance/bar) +"czp" = ( +/obj/structure/festive/trainplatform/necorner, +/turf/open/floor/light, +/area/maintenance/bar) +"czq" = ( +/obj/structure/chair/stool/bar, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/light, +/area/maintenance/bar) +"czr" = ( +/obj/structure/chair/stool/bar, +/turf/open/floor/light, +/area/maintenance/bar) +"czs" = ( +/obj/structure/festive/trainplatform/nwcorner, +/turf/open/floor/light, +/area/maintenance/bar) +"czt" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"czu" = ( +/obj/structure/table/reinforced, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/obj/item/storage/firstaid/regular{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/item/storage/firstaid/toxin{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/machinery/door/window/eastleft{ + name = "First-Aid Supplies"; + req_access_txt = "5" + }, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"czv" = ( +/obj/structure/chair/office/dark{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"czw" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"czx" = ( +/obj/machinery/iv_drip{ + pixel_y = -16 + }, +/obj/structure/table, +/obj/item/clipboard, +/obj/item/pen/fountain, +/obj/item/clothing/gloves/color/latex, +/obj/item/scalpel, +/obj/item/hemostat, +/obj/item/clothing/mask/surgical, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"czy" = ( +/obj/effect/landmark/latejoin, +/turf/open/floor/festive/trainplatform, +/area/edina/street/primary/perimeter) +"czA" = ( +/obj/structure/dresser{ + pixel_y = 12 + }, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/carpet/red, +/area/commons/dorms) +"czB" = ( +/obj/structure/closet/cabinet{ + pixel_y = 15 + }, +/turf/open/floor/carpet/red, +/area/commons/dorms) +"czC" = ( +/obj/structure/bed, +/obj/item/bedsheet/syndie, +/turf/open/floor/carpet/red, +/area/commons/dorms) +"czD" = ( +/obj/structure/table/wood/fancy/monochrome, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"czG" = ( +/obj/machinery/light{ + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel/checker, +/area/maintenance/bar/cafe) +"czH" = ( +/obj/structure/chair/sofa/corner{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"czI" = ( +/obj/structure/chair/sofa{ + dir = 1 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"czK" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"czL" = ( +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"czM" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"czN" = ( +/obj/structure/chair/comfy/brown, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"czO" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/wood, +/area/maintenance/bar) +"czP" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/turf/open/indestructible, +/area/cargo/storage) +"czQ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/chair/sofa/right{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"czR" = ( +/obj/structure/table/glass, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/obj/machinery/chem_dispenser/drinks/fullupgrade{ + dir = 1 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"czS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/table/glass, +/turf/open/floor/wood, +/area/maintenance/bar) +"czT" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"czU" = ( +/obj/structure/chair/comfy/brown, +/turf/open/floor/wood, +/area/maintenance/bar) +"cAa" = ( +/obj/structure/table/reinforced, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/structure/window/reinforced, +/obj/item/storage/firstaid/fire{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/item/storage/firstaid/brute{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cAb" = ( +/obj/structure/table, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/suit/hooded/wintercoat/medical, +/turf/open/floor/plating, +/area/maintenance/department/medical) +"cAc" = ( +/obj/machinery/door/airlock/silver/glass{ + name = "Clinic Storage" + }, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cAd" = ( +/obj/machinery/door/airlock/silver/glass{ + name = "Patient Room 2" + }, +/turf/open/floor/plating, +/area/maintenance/department/medical) +"cAe" = ( +/obj/structure/bed, +/obj/item/bedsheet/medical, +/obj/effect/decal/cleanable/blood, +/turf/open/floor/plasteel/white, +/area/maintenance/department/medical) +"cAj" = ( +/obj/structure/chair/comfy/black{ + dir = 1 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/dorms) +"cAk" = ( +/turf/closed/festive/greybrick/greybricktn, +/area/maintenance/bar/cafe) +"cAl" = ( +/obj/machinery/vending/games, +/turf/open/floor/wood, +/area/maintenance/bar) +"cAm" = ( +/obj/structure/window/reinforced/tinted{ + dir = 1 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cAn" = ( +/obj/machinery/light{ + light_color = "#e8eaff" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cAo" = ( +/obj/structure/chair/comfy/brown{ + dir = 4 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cAp" = ( +/obj/structure/table/wood/fancy/red, +/turf/open/floor/wood, +/area/maintenance/bar) +"cAq" = ( +/obj/structure/chair/comfy/brown{ + dir = 8 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cAr" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/storage) +"cAs" = ( +/obj/machinery/light{ + light_color = "#c9d3e8" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cAu" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/indestructible, +/area/cargo/storage) +"cAv" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cAw" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/indestructible, +/area/cargo/storage) +"cAx" = ( +/turf/closed/festive/greybrick/greybrickcornersw, +/area/edina/street/primary/perimeter) +"cAy" = ( +/turf/closed/festive/greybrick/greybrickcornerse, +/area/edina/street/primary/perimeter) +"cAA" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSRightEnd, +/obj/structure/curtain, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"cAB" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSMiddle, +/obj/structure/curtain, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"cAC" = ( +/obj/structure/grille, +/obj/structure/festive/redbrick/windowNSLeftEnd, +/obj/structure/curtain, +/turf/open/floor/plasteel/checker, +/area/commons/dorms) +"cAD" = ( +/turf/closed/festive/redbrick/redbrickns, +/area/commons/dorms) +"cAE" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/vehicle/sealed/vectorcraft/auto, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet) +"cAF" = ( +/obj/structure/closet/crate/trashcart, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 4; + name = "4maintenance loot spawner" + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet) +"cAG" = ( +/obj/structure/closet/crate/trashcart, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 4; + name = "4maintenance loot spawner" + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet) +"cAH" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"cAI" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/festive/trainplatform/necorner, +/turf/open/floor/plating/dirt/space, +/area/edina) +"cAJ" = ( +/obj/structure/festive/trainplatform/edge_south, +/turf/open/floor/plating/dirt/space, +/area/edina) +"cAL" = ( +/obj/structure/fluff/lightpost/light, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"cAM" = ( +/obj/effect/festive/trainrails/north, +/turf/open/floor/plating/dirt/space, +/area/edina) +"cAN" = ( +/obj/effect/festive/trainrails/north, +/obj/effect/festive/trainrails/north, +/turf/open/floor/plating/dirt/space, +/area/edina) +"cAO" = ( +/obj/effect/festive/trainrails/north, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"cAP" = ( +/obj/effect/festive/trainrails/north{ + icon_state = "trainrails_turn_int" + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"cAQ" = ( +/obj/effect/festive/trainrails/south, +/turf/open/floor/plating/dirt/space, +/area/edina) +"cAR" = ( +/obj/effect/festive/trainrails/south, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"cAS" = ( +/obj/effect/festive/trainrails/north{ + icon_state = "trainrails_turn_ext" + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"cAT" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"cAV" = ( +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/closed/wall, +/area/engineering/main) +"cAW" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/closed/wall, +/area/engineering/main) +"cAX" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/mineral/snowmountain, +/area/edina) +"cAY" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"cAZ" = ( +/turf/closed/wall, +/area/engineering/gravity_generator) +"cBa" = ( +/turf/closed/wall, +/area/engineering/main) +"cBb" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall, +/area/engineering/main) +"cBc" = ( +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/engineering/main) +"cBd" = ( +/turf/open/floor/plasteel, +/area/engineering/main) +"cBe" = ( +/turf/open/floor/plasteel, +/area/engineering/gravity_generator) +"cBf" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/power/apc/highcap/fifteen_k{ + areastring = "/area/engineering/main"; + dir = 1; + name = "Antimatter Engine APC"; + pixel_y = 25 + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"cBg" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/closed/wall, +/area/engineering/main) +"cBh" = ( +/obj/effect/turf_decal/delivery/red, +/turf/open/floor/plasteel, +/area/engineering/main) +"cBi" = ( +/obj/machinery/gravity_generator/main/station/admin, +/turf/open/floor/plasteel, +/area/engineering/gravity_generator) +"cBj" = ( +/obj/machinery/door/airlock/engineering/glass{ + name = "Antimatter Engine Room"; + req_access_txt = "10" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"cBk" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"cBl" = ( +/obj/effect/turf_decal/delivery/white, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"cBm" = ( +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_containment, +/obj/item/am_containment, +/obj/item/am_containment, +/obj/machinery/power/am_control_unit, +/obj/structure/closet/crate/engineering{ + name = "Antimatter Engine Crate" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"cBn" = ( +/obj/machinery/quantumpad{ + map_pad_id = "AME"; + map_pad_link_id = "EngieL2" + }, +/turf/open/floor/plasteel, +/area/engineering/main) +"cDt" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"cGh" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/closed/indestructible/rock/snow, +/area/edina) +"cHo" = ( +/obj/machinery/door/airlock/wood/glass, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"cHq" = ( +/obj/structure/bedsheetbin/color, +/obj/structure/table, +/turf/open/floor/plasteel/white, +/area/commons/dorms) +"cIt" = ( +/obj/vehicle/ridden/janicart, +/obj/item/key/janitor, +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/commons/dorms) +"cIQ" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8; + pixel_y = 16 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/south) +"cKl" = ( +/obj/machinery/light/small, +/obj/structure/closet/crate, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/box/matches, +/obj/item/shovel, +/obj/item/pickaxe/diamond, +/obj/item/hatchet, +/turf/open/floor/wood, +/area/commons/storage/tools) +"cMJ" = ( +/obj/structure/chair/wood/normal{ + dir = 4 + }, +/turf/open/floor/carpet/red, +/area/maintenance/bar) +"cNG" = ( +/obj/structure/mineral_door/woodrustic{ + name = "Event Hall" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cPd" = ( +/obj/structure/table, +/obj/item/book/manual/wiki/cooking_to_serve_man, +/obj/item/kitchen/rollingpin, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"cRE" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cTr" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/wood, +/area/science) +"cUs" = ( +/obj/structure/flora/ausbushes/ppflowers, +/turf/open/floor/grass, +/area/edina) +"cVb" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/microwave, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"cZi" = ( +/obj/structure/table, +/obj/machinery/microwave{ + pixel_x = 2; + pixel_y = 10 + }, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"dfl" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/condiment/enzyme{ + layer = 5; + pixel_x = -4 + }, +/obj/item/storage/box/donkpockets, +/obj/item/reagent_containers/rag/towel, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"dgn" = ( +/obj/effect/festive/trainrails/north{ + icon_state = "trainrails_east" + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"dgB" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/edina) +"dhz" = ( +/obj/machinery/door/airlock/wood, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/wood, +/area/maintenance/bar) +"dkq" = ( +/obj/item/reagent_containers/food/snacks/cheesewedge, +/turf/open/floor/festive/wooden/wooden2, +/area/edina/crew_quarters/store/pet) +"dlA" = ( +/obj/structure/fireplace{ + dir = 8 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"dnQ" = ( +/mob/living/simple_animal/pet/penguin/emperor/shamebrero, +/turf/open/floor/holofloor/ice, +/area/edina/crew_quarters/store/pet) +"dpH" = ( +/obj/machinery/nanite_chamber, +/turf/open/floor/circuit/off, +/area/science) +"dqG" = ( +/turf/open/floor/plasteel, +/area/engineering/engine_smes) +"dra" = ( +/mob/living/simple_animal/pet/cat/kitten, +/turf/open/floor/grass, +/area/edina/crew_quarters/store/pet) +"dts" = ( +/obj/item/storage/fancy/cigarettes/cigpack_mindbreaker, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/edina) +"duf" = ( +/obj/effect/decal/festive/holly, +/turf/closed/indestructible/riveted/hierophant, +/area/science) +"duE" = ( +/obj/effect/decal/festive/green_stockings{ + pixel_y = -15 + }, +/turf/closed/festive/greybrick, +/area/commons/dorms) +"dzc" = ( +/obj/item/reagent_containers/food/drinks/soda_cans/starkist{ + pixel_x = -12; + pixel_y = 3 + }, +/turf/open/floor/plating/beach/sand, +/area/edina) +"dAt" = ( +/turf/open/floor/festive/wooden/wooden1, +/area/service/theater) +"dSL" = ( +/turf/open/floor/wood{ + icon_state = "wood-broken2" + }, +/area/commons/dorms) +"dTR" = ( +/obj/structure/table, +/obj/item/storage/box/lights/mixed, +/obj/item/storage/box/lights/mixed, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/commons/dorms) +"dWP" = ( +/obj/machinery/door/airlock/silver{ + name = "Bathroom" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/maintenance/bar) +"ecw" = ( +/turf/closed/festive/whitebrick, +/area/service/theater) +"ecE" = ( +/obj/structure/rack, +/obj/item/clothing/neck/cloak/festive, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_y = 26 + }, +/obj/item/clothing/gloves/mittens/random, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"edV" = ( +/turf/closed/indestructible/riveted/hierophant, +/area/science) +"egT" = ( +/obj/item/chair/wood, +/turf/open/floor/wood, +/area/commons/dorms) +"ejZ" = ( +/obj/structure/bookcase/random/reference, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"emA" = ( +/turf/open/floor/wood{ + icon_state = "wood-broken4" + }, +/area/commons/dorms) +"enm" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"eoy" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"epO" = ( +/obj/machinery/conveyor{ + dir = 1; + id = "cargocars" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"eqs" = ( +/obj/structure/fence{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"esO" = ( +/obj/structure/bed/dogbed{ + name = "cat bed" + }, +/turf/open/floor/grass, +/area/edina/crew_quarters/store/pet) +"ett" = ( +/obj/item/reagent_containers/food/drinks/bottle/whiskey, +/turf/open/floor/plasteel, +/area/edina) +"euK" = ( +/obj/structure/bed, +/obj/item/bedsheet/random, +/turf/open/floor/wood, +/area/commons/dorms) +"evB" = ( +/obj/structure/closet, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/cryopod) +"ewh" = ( +/obj/structure/sign/barsign{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"ezz" = ( +/obj/effect/overlay/palmtree_r, +/turf/open/floor/plating/beach/sand, +/area/edina) +"ezS" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"ezY" = ( +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/maintenance/bar) +"eEU" = ( +/obj/structure/fireplace{ + dir = 4; + pixel_x = -8 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"eGN" = ( +/turf/open/floor/wood{ + icon_state = "wood-broken3" + }, +/area/commons/dorms) +"eKm" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/light, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/pet) +"eKC" = ( +/obj/vehicle/sealed/vectorcraft/rideable/wheelchair, +/turf/open/floor/grass/snow/edina, +/area/edina) +"ePE" = ( +/obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb{ + pixel_x = -9; + pixel_y = -7 + }, +/turf/open/floor/plating/beach/sand, +/area/edina) +"eRU" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"eSe" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/engineering/main) +"eYQ" = ( +/obj/structure/table/glass, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"fao" = ( +/obj/structure/sign/directions/medical{ + dir = 8 + }, +/obj/structure/sign/directions/science{ + dir = 1; + pixel_y = 8 + }, +/obj/structure/sign/directions/security{ + dir = 1; + pixel_y = -8 + }, +/obj/structure/sign/directions/command{ + dir = 1; + pixel_y = 16 + }, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/qm) +"feR" = ( +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 4; + name = "4maintenance loot spawner" + }, +/obj/structure/closet/crate/trashcart, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 5 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"fhW" = ( +/obj/structure/chair/stool, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"fkS" = ( +/turf/closed/indestructible/rock/glacierrock/blue, +/area/edina) +"fld" = ( +/obj/machinery/processor, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"fls" = ( +/mob/living/simple_animal/jacq/car_spawner, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/progress) +"fqI" = ( +/obj/machinery/door/airlock{ + glass = 1; + name = "Custodial Closet"; + req_access_txt = "26" + }, +/turf/open/floor/plasteel, +/area/commons/dorms) +"frM" = ( +/obj/effect/turf_decal/stripes/white/corner, +/obj/effect/overlay/palmtree_r, +/turf/open/floor/plating/beach/sand, +/area/edina) +"fsH" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/bottle/wine, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"ftC" = ( +/obj/structure/flora/tree/dead, +/turf/open/floor/grass, +/area/edina) +"fwK" = ( +/turf/open/floor/plasteel/white, +/area/commons/dorms) +"fxy" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"fyx" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp, +/turf/open/floor/wood, +/area/command/heads_quarters/ce) +"fBZ" = ( +/mob/living/simple_animal/crab, +/turf/open/floor/holofloor/beach, +/area/edina/crew_quarters/store/pet) +"fCo" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"fCF" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/carpet/blue, +/area/commons/cryopod) +"fGL" = ( +/obj/machinery/suit_storage_unit/ce, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plasteel/white, +/area/command/heads_quarters/ce) +"fIm" = ( +/obj/structure/fence, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/supply) +"fKS" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating, +/area/edina) +"fNO" = ( +/obj/structure/chair/wood/normal{ + dir = 4 + }, +/turf/open/floor/carpet/orange, +/area/maintenance/bar) +"fQp" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"fRf" = ( +/mob/living/simple_animal/crab/kreb, +/turf/open/floor/holofloor/beach, +/area/edina/crew_quarters/store/pet) +"fUG" = ( +/obj/structure/table/wood, +/turf/open/floor/carpet/orange, +/area/command/heads_quarters/ce) +"fVP" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 16; + pixel_y = 10 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina) +"fWp" = ( +/obj/structure/table/wood, +/obj/item/clothing/head/festive, +/turf/open/floor/carpet/orange, +/area/maintenance/bar) +"fXg" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"fZm" = ( +/obj/structure/chair/sofa/left{ + dir = 1; + icon_state = "sofamiddle" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"fZZ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/mob/living/simple_animal/jacq/car_spawner, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/command) +"ggz" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/grass/fakebasalt, +/area/edina) +"gia" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"giH" = ( +/obj/structure/statue/gold/cmo{ + anchored = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/castle) +"gnR" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"gpj" = ( +/obj/structure/bed/dogbed, +/mob/living/simple_animal/pet/fox, +/turf/open/floor/grass, +/area/edina/crew_quarters/store/pet) +"grV" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/edina/crew_quarters/store/pet) +"gud" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb, +/turf/open/floor/wood, +/area/maintenance/bar) +"gzG" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/reagent_containers/food/snacks/taco, +/turf/open/floor/carpet/royalblack, +/area/maintenance/bar) +"gAS" = ( +/mob/living/simple_animal/chick, +/turf/open/floor/grass, +/area/edina/crew_quarters/store/pet) +"gBV" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"gCJ" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/reagent_containers/food/snacks/sausage, +/turf/open/floor/carpet/royalblack, +/area/maintenance/bar) +"gFH" = ( +/obj/structure/table/wood, +/obj/machinery/chem_dispenser/drinks/beer/fullupgrade, +/turf/open/floor/wood, +/area/maintenance/bar) +"gIU" = ( +/obj/structure/table/wood, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/sign/directions/cells{ + dir = 4 + }, +/turf/open/floor/carpet/red, +/area/security/brig) +"gMa" = ( +/obj/structure/curtain{ + color = "#B22222" + }, +/turf/closed/indestructible/fakeglass, +/area/commons/dorms) +"gOB" = ( +/obj/machinery/deepfryer, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"gZg" = ( +/obj/machinery/vending/tool, +/turf/open/floor/circuit/off, +/area/science) +"heG" = ( +/obj/structure/mineral_door/wood{ + name = "Bedroom" + }, +/turf/open/floor/wood, +/area/commons/dorms) +"hgb" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/portables_connector/layer3{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"hie" = ( +/obj/structure/bookcase/random/adult, +/turf/open/floor/wood, +/area/maintenance/bar) +"hji" = ( +/obj/structure/dresser, +/turf/open/floor/wood, +/area/maintenance/bar) +"hki" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/mob/living/simple_animal/mouse/gray, +/turf/open/floor/festive/wooden/wooden2, +/area/edina/crew_quarters/store/pet) +"hkj" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/festive/fairylights, +/obj/structure/chair/sofa/right{ + dir = 8 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"hlu" = ( +/obj/machinery/seed_extractor, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"hlN" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"hoN" = ( +/mob/living/simple_animal/pet/penguin/emperor/shamebrero, +/turf/open/floor/holofloor/ice, +/area/edina) +"hqI" = ( +/obj/structure/closet/crate, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/box/matches, +/obj/item/shovel, +/obj/item/pickaxe/diamond, +/obj/item/hatchet, +/turf/open/floor/wood, +/area/commons/storage/tools) +"hqN" = ( +/turf/open/floor/wood{ + icon_state = "wood-broken5" + }, +/area/commons/dorms) +"huk" = ( +/obj/structure/table/plasmaglass, +/obj/item/multitool, +/obj/item/multitool, +/obj/item/multitool, +/obj/item/multitool, +/turf/open/floor/circuit/off, +/area/science) +"hxw" = ( +/obj/structure/mineral_door/wood, +/turf/closed/wall/mineral/wood, +/area/commons/storage/tools) +"hya" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"hzc" = ( +/obj/structure/window/reinforced{ + dir = 1; + pixel_y = 2 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/pet) +"hBk" = ( +/obj/effect/landmark/start/chief_engineer, +/turf/open/floor/carpet/orange, +/area/command/heads_quarters/ce) +"hER" = ( +/obj/machinery/rnd/production/circuit_imprinter, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/circuit/off, +/area/science) +"hHy" = ( +/obj/structure/closet/crate, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/box/matches, +/obj/item/shovel, +/obj/item/pickaxe/diamond, +/obj/item/hatchet, +/turf/open/floor/carpet/orange, +/area/commons/storage/tools) +"hKj" = ( +/obj/docking_port/stationary{ + dir = 4; + dwidth = 2; + height = 5; + id = "laborcamp_home"; + name = "fore bay 1"; + roundstart_template = /datum/map_template/shuttle/labour/delta; + width = 9 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"hLe" = ( +/obj/structure/chair/pew, +/turf/open/floor/carpet/green, +/area/medical/surgery) +"hMn" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 16; + pixel_y = 10 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"hOo" = ( +/obj/structure/statue/plasma/scientist{ + anchored = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/castle) +"hPL" = ( +/obj/structure/statue/gold/rd{ + anchored = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/castle) +"hTY" = ( +/obj/structure/bed/dogbed, +/turf/open/floor/grass, +/area/edina/crew_quarters/store/pet) +"hUp" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/sidewalk, +/area/edina) +"hXd" = ( +/obj/vehicle/ridden/janicart, +/obj/item/key/janitor, +/turf/open/floor/plasteel/white/side{ + dir = 4 + }, +/area/commons/dorms) +"hYa" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"iaA" = ( +/obj/structure/closet/toolcloset, +/obj/item/storage/belt/durathread, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/circuit/off, +/area/science) +"iaE" = ( +/obj/structure/statue/petrified, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/castle) +"ibM" = ( +/obj/effect/mob_spawn/human/bartender/alive, +/turf/open/floor/wood, +/area/maintenance/bar) +"ihe" = ( +/obj/machinery/autolathe/hacked, +/turf/open/floor/circuit/off, +/area/science) +"ikY" = ( +/obj/structure/table/glass, +/obj/item/toy/fluff/tennis_poly, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"ilI" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/pet) +"imW" = ( +/obj/effect/decal/festive/holly, +/turf/closed/indestructible/riveted/boss, +/area/science) +"inO" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"ior" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/obj/machinery/vending/tool, +/turf/open/floor/circuit/off, +/area/science) +"iqa" = ( +/obj/effect/festive/trainrails/north{ + icon_state = "trainrails_east" + }, +/turf/closed/indestructible/rock/snow, +/area/edina) +"irN" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/closed/indestructible/rock/snow, +/area/edina) +"iug" = ( +/obj/effect/festive/trainrails/north{ + icon_state = "trainrails_west" + }, +/turf/closed/indestructible/rock/snow, +/area/edina) +"ium" = ( +/obj/machinery/processor, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/wood, +/area/commons/dorms) +"iwy" = ( +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/wood, +/area/commons/dorms) +"izr" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/condiment/flour{ + pixel_x = 7 + }, +/obj/item/reagent_containers/food/condiment/flour{ + pixel_x = -8 + }, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"iAN" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/turf/open/indestructible/airblock, +/area/science) +"iCT" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/chair/sofa/left{ + dir = 8 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"iFP" = ( +/mob/living/simple_animal/jacq/car_spawner, +/turf/open/floor/grass/snow/edina, +/area/edina) +"iIf" = ( +/mob/living/simple_animal/babyKiwi, +/turf/open/floor/festive/wooden/wooden2, +/area/edina/crew_quarters/store/pet) +"iKG" = ( +/obj/structure/closet/crate/bin{ + pixel_y = 8 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"iLC" = ( +/obj/structure/sign/directions/medical{ + dir = 8 + }, +/obj/structure/sign/directions/science{ + dir = 1; + pixel_y = 8 + }, +/turf/closed/festive/greybrick, +/area/service/janitor) +"iMm" = ( +/obj/structure/sign/directions/medical{ + dir = 8 + }, +/turf/closed/wall/mineral/wood, +/area/medical/chemistry) +"iMq" = ( +/obj/machinery/computer/nanite_cloud_controller, +/turf/open/floor/circuit/off, +/area/science) +"iOS" = ( +/obj/structure/table, +/obj/machinery/reagentgrinder{ + desc = "Used to grind things up into raw materials and liquids."; + pixel_x = -5; + pixel_y = 5 + }, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"iQh" = ( +/obj/structure/table/wood/fancy/blue, +/obj/item/flashlight/lamp{ + pixel_x = 4; + pixel_y = 8 + }, +/turf/open/floor/carpet/blue, +/area/commons/cryopod) +"jdx" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Hotel" + }, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/wood, +/area/commons/dorms) +"jdD" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/mob/living/simple_animal/pet/penguin/emperor, +/turf/open/floor/holofloor/ice, +/area/edina/crew_quarters/store/pet) +"jdY" = ( +/obj/machinery/door/window/westleft{ + dir = 2; + icon_state = "right"; + pixel_y = -3 + }, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"jep" = ( +/obj/structure/bed, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/carpet/red, +/area/commons/dorms) +"jqv" = ( +/obj/structure/table/glass, +/obj/item/toy/fluff/tennis_poly/green, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"jse" = ( +/obj/machinery/vending/dinnerware, +/obj/structure/extinguisher_cabinet{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"jvh" = ( +/obj/structure/bookcase/random/adult, +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/maintenance/bar) +"jzG" = ( +/obj/structure/table, +/obj/machinery/smartfridge/disks, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"jBv" = ( +/obj/structure/dresser{ + pixel_y = 15 + }, +/obj/item/flashlight/lamp/green{ + on = 0; + pixel_y = 30 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"jBF" = ( +/obj/machinery/computer/rdconsole, +/turf/open/floor/circuit/off, +/area/science) +"jCx" = ( +/obj/structure/chair/sofa{ + dir = 4 + }, +/turf/open/floor/wood, +/area/commons/dorms) +"jDv" = ( +/obj/effect/landmark/start/bartender, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"jIs" = ( +/obj/structure/bed, +/obj/item/bedsheet/random, +/turf/open/floor/plasteel, +/area/edina) +"jIH" = ( +/obj/machinery/mech_bay_recharge_port, +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/circuit/off, +/area/science) +"jSU" = ( +/obj/structure/flora/grass/green, +/turf/open/floor/grass, +/area/edina) +"jUo" = ( +/obj/structure/table/plasmaglass, +/turf/open/floor/circuit/off, +/area/science) +"jZF" = ( +/obj/structure/chair/comfy/brown{ + buildstackamount = 0; + color = "#c45c57" + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/wood, +/area/commons/dorms) +"kaF" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/obj/structure/chair/pew, +/turf/open/floor/carpet/green, +/area/medical/surgery) +"kda" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/pet) +"kfz" = ( +/obj/structure/closet/jcloset, +/obj/item/storage/bag/trash, +/obj/item/clothing/under/rank/civilian/janitor/maid, +/obj/item/clothing/under/rank/civilian/janitor/maid, +/obj/item/clothing/under/rank/civilian/janitor/maid, +/obj/item/clothing/under/costume/maid, +/obj/item/clothing/under/costume/maid, +/obj/item/clothing/under/costume/maid, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/white/side, +/area/commons/dorms) +"kfS" = ( +/turf/closed/wall/mineral/sandstone, +/area/maintenance/bar) +"kge" = ( +/obj/effect/decal/festive/holly, +/turf/open/indestructible/airblock, +/area/science) +"kld" = ( +/turf/open/floor/plating/dirt/space, +/area/edina) +"klL" = ( +/obj/structure/bed, +/obj/item/bedsheet, +/turf/open/floor/wood, +/area/maintenance/bar) +"kmK" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/supply) +"knK" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/ale, +/turf/open/floor/wood, +/area/maintenance/bar) +"kpp" = ( +/obj/structure/table/wood, +/obj/item/clothing/glasses/sunglasses, +/obj/item/reagent_containers/food/drinks/beer, +/obj/item/reagent_containers/food/drinks/beer, +/turf/open/floor/wood, +/area/maintenance/bar) +"ksx" = ( +/obj/structure/barricade/sandbags, +/turf/open/indestructible/airblock, +/area/science) +"kwB" = ( +/obj/effect/turf_decal/stripes/white/corner, +/obj/effect/turf_decal/stripes/white/line{ + dir = 4 + }, +/turf/open/floor/plating/beach/sand, +/area/edina) +"kyR" = ( +/mob/living/simple_animal/pet/dog/corgi, +/turf/open/floor/grass, +/area/edina) +"kAo" = ( +/obj/structure/statue/gold/hop{ + anchored = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/castle) +"kBi" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/table/glass, +/obj/machinery/chem_dispenser/drinks/beer/fullupgrade{ + dir = 1 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"kJH" = ( +/obj/machinery/button/door{ + id = "weewoo"; + name = "Ambulance Garage button"; + pixel_y = -5; + req_access_txt = "5" + }, +/turf/closed/festive/whitebrick, +/area/medical/cryo) +"kSC" = ( +/obj/structure/toilet{ + dir = 4 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/maintenance/bar) +"kTw" = ( +/obj/structure/reagent_dispensers/keg/mead, +/turf/open/floor/wood, +/area/maintenance/bar) +"kUD" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/mob/living/simple_animal/jacq/car_spawner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"kWd" = ( +/obj/structure/sign/directions/cells{ + dir = 8 + }, +/turf/closed/wall/mineral/iron, +/area/security/brig) +"kXA" = ( +/obj/structure/chair/wood/normal{ + dir = 1 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"kYC" = ( +/obj/structure/festive/trainplatform/edge_north{ + pixel_y = -7 + }, +/turf/open/floor/festive/trainplatform/safe, +/area/maintenance/bar) +"kZN" = ( +/obj/machinery/light, +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/commons/dorms) +"lcg" = ( +/obj/structure/sign/directions/cells{ + dir = 4 + }, +/turf/closed/wall/mineral/iron, +/area/security/brig) +"lde" = ( +/obj/structure/chair/stool/bar, +/turf/open/floor/wood, +/area/maintenance/bar) +"ldU" = ( +/obj/machinery/nanite_program_hub, +/turf/open/floor/circuit/off, +/area/science) +"lhY" = ( +/obj/structure/closet/secure_closet/bar, +/obj/item/storage/box/drinkingglasses, +/obj/item/storage/box/drinkingglasses, +/obj/item/storage/box/drinkingglasses, +/obj/item/storage/box/drinkingglasses, +/obj/item/storage/box/drinkingglasses, +/obj/item/storage/box/drinkingglasses, +/turf/open/floor/wood, +/area/maintenance/bar) +"loi" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/reagent_containers/food/snacks/cubancarp, +/turf/open/floor/carpet/royalblack, +/area/maintenance/bar) +"lpy" = ( +/obj/structure/statue/sandstone/assistant{ + anchored = 1 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/castle) +"lqC" = ( +/obj/effect/decal/festive/christmas_reef, +/turf/closed/indestructible/riveted/hierophant, +/area/science) +"lyO" = ( +/obj/item/lighter/greyscale, +/turf/open/floor/wood, +/area/commons/dorms) +"lzS" = ( +/obj/structure/chair/comfy/beige, +/turf/open/floor/circuit/off, +/area/science) +"lBE" = ( +/obj/structure/sink/kitchen{ + pixel_y = 26 + }, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"lDE" = ( +/obj/structure/fence/post{ + dir = 8 + }, +/turf/open/floor/plating/beach/sand, +/area/edina) +"lEt" = ( +/obj/item/storage/pill_bottle/happiness, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/edina) +"lEK" = ( +/obj/structure/flora/tree/pine/xmas, +/turf/open/floor/grass/snow/edina, +/area/science) +"lIt" = ( +/obj/item/flashlight/glowstick/cyan, +/turf/open/floor/wood, +/area/commons/dorms) +"lLu" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 4 + }, +/turf/open/floor/plating/beach/sand, +/area/edina) +"lLP" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/soda_cans/lemon_lime, +/turf/open/floor/wood, +/area/maintenance/bar) +"lLT" = ( +/mob/living/simple_animal/mouse/white, +/turf/open/floor/grass, +/area/edina) +"lNo" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/indestructible/airblock, +/area/science) +"lNU" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/rag, +/turf/open/floor/wood, +/area/maintenance/bar) +"lPf" = ( +/obj/machinery/rnd/production/circuit_imprinter, +/turf/open/floor/circuit/off, +/area/science) +"lTb" = ( +/obj/machinery/door/airlock/maintenance, +/turf/open/floor/grass/snow/edina, +/area/edina) +"lUa" = ( +/obj/item/storage/box/handcuffs, +/turf/open/floor/grass/fakebasalt, +/area/edina) +"lVW" = ( +/obj/structure/fluff/lightpost/light, +/turf/open/floor/plating/beach/sand, +/area/edina) +"lXj" = ( +/obj/structure/closet/gmcloset, +/turf/open/floor/wood, +/area/maintenance/bar) +"lYe" = ( +/obj/item/reagent_containers/food/drinks/soda_cans/space_mountain_wind, +/turf/open/floor/plating/beach/sand, +/area/edina) +"lYh" = ( +/obj/structure/fence{ + dir = 4 + }, +/obj/structure/fence/post{ + dir = 8 + }, +/turf/open/floor/plating/beach/sand, +/area/edina) +"lYj" = ( +/obj/machinery/door/airlock/vault{ + name = "Mecha Battleground" + }, +/turf/open/floor/circuit/off, +/area/science) +"mdc" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/reagent_containers/food/snacks/soup/hotchili, +/turf/open/floor/carpet/royalblack, +/area/maintenance/bar) +"miw" = ( +/obj/structure/rack, +/obj/item/clothing/neck/stripedbluescarf, +/obj/item/clothing/neck/stripedgreenscarf, +/obj/item/clothing/neck/stripedredscarf, +/obj/item/clothing/gloves/mittens/random, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"mkV" = ( +/obj/item/grenade/chem_grenade/cleaner, +/obj/item/grenade/chem_grenade/cleaner, +/obj/item/grenade/chem_grenade/cleaner, +/obj/structure/table, +/obj/item/reagent_containers/spray/cleaner, +/obj/item/reagent_containers/spray/cleaner, +/obj/item/restraints/legcuffs/beartrap, +/obj/item/storage/box/mousetraps, +/obj/item/watertank/janitor, +/obj/item/construction/rld, +/obj/structure/sign/poster/contraband/busty_backdoor_xeno_babes_6{ + pixel_x = 32 + }, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, +/area/commons/dorms) +"mmZ" = ( +/turf/open/floor/plasteel/showroomfloor, +/area/maintenance/bar) +"mok" = ( +/obj/machinery/light/small, +/turf/open/floor/carpet/red, +/area/commons/dorms) +"mrd" = ( +/obj/structure/table/wood, +/obj/machinery/microwave, +/obj/effect/decal/festive/fairylights, +/turf/open/floor/wood, +/area/commons/dorms) +"mrJ" = ( +/obj/structure/barricade/security, +/turf/open/indestructible/airblock, +/area/science) +"msV" = ( +/obj/structure/chair/wood/normal, +/turf/open/floor/carpet/orange, +/area/maintenance/bar) +"mtg" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"mua" = ( +/turf/open/floor/carpet/royalblack, +/area/maintenance/bar) +"mwL" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"mGF" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/landmark/observer_start, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"mIf" = ( +/obj/structure/festive/trainplatform/edge_east, +/mob/living/simple_animal/jacq/car_spawner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"mJQ" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/circuit/off, +/area/science) +"mRs" = ( +/obj/structure/bookcase/random/religion, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/commons/lounge) +"mRx" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + mouse_opacity = 0 + }, +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + mouse_opacity = 0 + }, +/turf/open/floor/circuit/off, +/area/science) +"mTn" = ( +/obj/structure/table/plasmaglass, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/turf/open/floor/circuit/off, +/area/science) +"mTB" = ( +/obj/structure/flora/grass/both, +/turf/open/floor/grass, +/area/edina) +"mUg" = ( +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"mWJ" = ( +/obj/structure/chair/wood/normal, +/turf/open/floor/wood, +/area/maintenance/bar) +"mWS" = ( +/obj/machinery/mech_bay_recharge_port, +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/turf/open/floor/circuit/off, +/area/science) +"mXT" = ( +/obj/effect/decal/festive/christmas_reef, +/turf/closed/festive/greybrick, +/area/service/cafeteria/lunchroom) +"nbP" = ( +/turf/open/floor/carpet/orange, +/area/commons/storage/tools) +"nij" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 8 + }, +/turf/open/floor/plating/beach/sand, +/area/edina) +"nlJ" = ( +/turf/closed/wall, +/area/edina) +"nma" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"noa" = ( +/obj/structure/mineral_door/wood{ + name = "bar" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"nsX" = ( +/obj/machinery/door/window/westleft, +/turf/open/floor/holofloor/ice, +/area/edina/crew_quarters/store/pet) +"ntI" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina) +"nvy" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/chem_dispenser/drinks/beer/fullupgrade, +/turf/open/floor/wood, +/area/maintenance/bar) +"nxe" = ( +/obj/machinery/button/door{ + id = "clowngarage"; + name = "Garage Door"; + pixel_y = -4 + }, +/turf/closed/festive/whitebrick{ + color = "#fff200" + }, +/area/service/theater) +"nzc" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"nEs" = ( +/obj/structure/statue/gold/ce{ + anchored = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/castle) +"nII" = ( +/mob/living/simple_animal/pet/fox, +/turf/open/floor/grass, +/area/edina) +"nOZ" = ( +/turf/closed/wall/r_wall, +/area/engineering/engine_smes) +"nQw" = ( +/obj/machinery/computer/nanite_chamber_control{ + dir = 1 + }, +/turf/open/floor/circuit/off, +/area/science) +"nRW" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/indestructible/airblock, +/area/science) +"nRX" = ( +/obj/structure/closet/toolcloset, +/obj/item/storage/belt/durathread, +/turf/open/floor/circuit/off, +/area/science) +"nSS" = ( +/obj/structure/statue/sandstone/venus, +/turf/open/floor/grass/snow/edina, +/area/edina) +"nTN" = ( +/obj/structure/dresser{ + pixel_y = 12 + }, +/turf/open/floor/carpet/red, +/area/commons/dorms) +"nWq" = ( +/obj/item/toy/beach_ball, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/holofloor/beach, +/area/edina/crew_quarters/store/pet) +"nXv" = ( +/obj/structure/flora/grass/brown, +/turf/open/floor/grass, +/area/edina) +"nZW" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"oeX" = ( +/obj/machinery/mecha_part_fabricator, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/circuit/off, +/area/science) +"ohM" = ( +/mob/living/simple_animal/pet/redpanda, +/turf/open/floor/grass, +/area/edina) +"oin" = ( +/obj/machinery/light, +/turf/open/floor/wood, +/area/commons/dorms) +"oiv" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + mouse_opacity = 0 + }, +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/turf/open/floor/circuit/off, +/area/science) +"oju" = ( +/obj/structure/closet/cabinet{ + pixel_y = 15 + }, +/obj/item/coin/iron, +/turf/open/floor/wood, +/area/commons/dorms) +"okc" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/obj/structure/chair/pew/right, +/turf/open/floor/carpet/green, +/area/medical/surgery) +"olL" = ( +/obj/structure/fireplace, +/turf/open/floor/wood, +/area/commons/dorms) +"orN" = ( +/obj/machinery/light/small, +/turf/open/floor/mineral/titanium/blue, +/area/commons/dorms) +"oua" = ( +/obj/item/storage/pill_bottle/penis_enlargement, +/turf/open/floor/wood, +/area/commons/dorms) +"oud" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/chem_dispenser/drinks/fullupgrade, +/turf/open/floor/wood, +/area/maintenance/bar) +"ovH" = ( +/obj/structure/dresser, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"oyS" = ( +/obj/structure/streetdecor/bigtree{ + pixel_x = -16 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/castle) +"oCy" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"oIz" = ( +/obj/machinery/jukebox/disco/indestructible, +/turf/open/floor/holofloor/ice, +/area/edina) +"oKt" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"oMB" = ( +/obj/item/integrated_circuit_printer, +/obj/structure/table/plasmaglass, +/turf/open/floor/circuit/off, +/area/science) +"oMD" = ( +/obj/machinery/computer/mech_bay_power_console{ + dir = 1 + }, +/turf/open/floor/circuit/off, +/area/science) +"oNc" = ( +/obj/structure/table/reinforced, +/obj/machinery/chem_dispenser/drinks{ + dir = 1 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"oNL" = ( +/obj/item/scythe, +/turf/open/floor/wood, +/area/commons/dorms) +"oTd" = ( +/obj/structure/fluff/broken_flooring, +/turf/open/floor/plating, +/area/edina) +"oUj" = ( +/mob/living/simple_animal/jacq/car_spawner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/servitor) +"oWb" = ( +/obj/machinery/light/small{ + brightness = 3; + dir = 4 + }, +/turf/open/floor/plasteel, +/area/commons/fitness/recreation) +"oWw" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/turf/open/floor/festive/sidewalk, +/area/edina) +"oYk" = ( +/obj/structure/chair/comfy/brown{ + buildstackamount = 0; + dir = 1 + }, +/turf/open/floor/wood, +/area/commons/dorms) +"oYY" = ( +/obj/structure/closet/secure_closet/freezer/meat, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/item/reagent_containers/food/snacks/meat/slab, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"pbB" = ( +/turf/open/floor/holofloor/beach, +/area/edina/crew_quarters/store/pet) +"pcj" = ( +/obj/effect/decal/festive/fairylights, +/turf/open/floor/wood, +/area/commons/dorms) +"peF" = ( +/obj/effect/decal/festive/fairylights, +/turf/open/indestructible/airblock, +/area/science) +"phl" = ( +/obj/machinery/vending/boozeomat, +/turf/open/floor/wood, +/area/maintenance/bar) +"phV" = ( +/turf/open/floor/plasteel/white/side, +/area/commons/dorms) +"pkQ" = ( +/obj/machinery/vending/assist, +/turf/open/floor/circuit/off, +/area/science) +"poQ" = ( +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/plasteel, +/area/edina) +"pqA" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/science) +"pqW" = ( +/obj/structure/fluff/broken_flooring, +/turf/open/floor/grass/fakebasalt, +/area/edina) +"prz" = ( +/mob/living/simple_animal/crab, +/turf/open/floor/plating/beach/sand, +/area/edina) +"psQ" = ( +/obj/structure/table/wood, +/obj/item/clothing/head/festive, +/turf/open/floor/carpet/red, +/area/maintenance/bar) +"ptp" = ( +/obj/structure/chair/sofa{ + dir = 8 + }, +/turf/open/floor/wood, +/area/commons/dorms) +"pwQ" = ( +/obj/structure/table/wood, +/obj/item/phone, +/turf/open/floor/wood, +/area/maintenance/bar) +"pyF" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 8 + }, +/obj/structure/streetdecor/lampfestive{ + pixel_y = 16 + }, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"pBd" = ( +/mob/living/simple_animal/jacq/car_spawner, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/castle) +"pCu" = ( +/obj/structure/rack, +/obj/item/clothing/accessory/waistcoat, +/obj/item/clothing/accessory/maidapron, +/obj/item/clothing/gloves/mittens/random, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"pCQ" = ( +/obj/structure/sign/directions/science{ + dir = 8; + pixel_y = 8 + }, +/obj/structure/sign/directions/command{ + dir = 1; + pixel_y = 16 + }, +/obj/structure/sign/directions/security{ + dir = 1; + pixel_y = -8 + }, +/obj/structure/sign/directions/engineering{ + dir = 1 + }, +/turf/closed/festive/creambrick{ + color = "#ffbb4d" + }, +/area/commons/storage/tools) +"pEv" = ( +/obj/structure/dresser, +/obj/machinery/light{ + dir = 1; + light_color = "#e8eaff" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"pEX" = ( +/obj/effect/decal/festive/green_stockings, +/turf/closed/indestructible/riveted/boss, +/area/science) +"pNf" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"pOy" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/hydroponics/constructable, +/obj/machinery/light/small, +/turf/open/floor/plasteel/dark, +/area/service/hydroponics) +"pQk" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"pRa" = ( +/obj/structure/chair/pew/right, +/turf/open/floor/carpet/green, +/area/medical/surgery) +"pRU" = ( +/obj/structure/table/plasmaglass, +/obj/item/integrated_electronics/analyzer, +/obj/item/integrated_electronics/debugger, +/obj/item/integrated_electronics/detailer, +/obj/item/integrated_electronics/wirer, +/turf/open/floor/circuit/off, +/area/science) +"pVt" = ( +/obj/structure/festive/trainplatform/edge_north, +/mob/living/simple_animal/jacq/car_spawner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/princessperimeter/south) +"pXv" = ( +/obj/structure/fluff/beach_umbrella, +/turf/open/floor/holofloor/beach, +/area/edina/crew_quarters/store/pet) +"pXS" = ( +/obj/structure/toilet{ + dir = 8 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/maintenance/bar) +"pYF" = ( +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"pZT" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/warehouse) +"qaU" = ( +/obj/structure/flora/ausbushes/brflowers, +/turf/open/floor/grass, +/area/edina) +"qcl" = ( +/obj/machinery/rnd/production/protolathe/department/science{ + acted_explosions = "Dumbasses"; + allowed_department_flags = 126; + name = "department protolathe (Dumb powergamers)" + }, +/turf/open/floor/circuit/off, +/area/science) +"qcq" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/table/glass, +/turf/open/floor/wood, +/area/maintenance/bar) +"qkz" = ( +/obj/effect/decal/festive/fairylights, +/turf/open/floor/carpet/royalblue, +/area/service/cafeteria) +"qua" = ( +/obj/machinery/door/airlock/wood/glass, +/turf/open/floor/plasteel/dark, +/area/service/cafeteria/lunchroom) +"qvz" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"qvZ" = ( +/obj/structure/closet/l3closet/janitor, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/white/side, +/area/commons/dorms) +"qwr" = ( +/obj/structure/dresser{ + pixel_y = 15 + }, +/turf/open/floor/wood, +/area/commons/dorms) +"qzd" = ( +/obj/machinery/computer/rdconsole{ + dir = 1 + }, +/turf/open/floor/circuit/off, +/area/science) +"qzx" = ( +/obj/structure/chair/sofa{ + dir = 8 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"qzA" = ( +/obj/structure/table/glass, +/obj/item/stack/sheet/bone, +/obj/item/stack/sheet/bone, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"qPh" = ( +/obj/structure/mineral_door/woodrustic, +/turf/open/floor/wood, +/area/maintenance/bar) +"qPQ" = ( +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/castle) +"qRm" = ( +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"qUh" = ( +/obj/structure/closet/secure_closet/freezer/kitchen/maintenance, +/turf/open/floor/wood, +/area/maintenance/bar) +"qUP" = ( +/obj/structure/dresser, +/turf/open/floor/wood, +/area/command/heads_quarters/ce) +"qVq" = ( +/obj/effect/decal/festive/red_stockings, +/turf/closed/indestructible/riveted/boss, +/area/science) +"qXb" = ( +/obj/structure/mirror{ + pixel_x = 28 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/shower{ + dir = 8; + pixel_y = -4 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/maintenance/bar) +"qXY" = ( +/mob/living/simple_animal/chicken/rabbit, +/turf/open/floor/grass, +/area/edina/crew_quarters/store/pet) +"rbl" = ( +/obj/structure/janitorialcart, +/obj/item/mop, +/obj/item/reagent_containers/glass/bucket, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, +/area/commons/dorms) +"rcW" = ( +/obj/machinery/vending/wardrobe/jani_wardrobe, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/white/corner, +/area/commons/dorms) +"reC" = ( +/obj/structure/rack, +/obj/item/gun/magic/staff/healing, +/turf/open/floor/circuit/off, +/area/science) +"rgc" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/festive/trainplatform/edge_north{ + pixel_y = -7 + }, +/turf/open/floor/festive/trainplatform/safe, +/area/maintenance/bar) +"rgC" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"rhc" = ( +/obj/structure/table/reinforced, +/obj/item/storage/toolbox/syndicate, +/obj/item/storage/toolbox/gold_real, +/obj/item/storage/toolbox/syndicate, +/obj/item/storage/toolbox/gold_real, +/turf/open/floor/circuit/off, +/area/science) +"rho" = ( +/obj/structure/spacevine, +/obj/structure/flora/ausbushes/brflowers, +/turf/open/floor/grass, +/area/edina) +"rkk" = ( +/mob/living/simple_animal/pet/cat, +/turf/open/floor/grass, +/area/edina) +"rni" = ( +/turf/closed/indestructible/rock, +/area/edina) +"rqO" = ( +/obj/structure/table/wood, +/obj/machinery/microwave, +/turf/open/floor/wood, +/area/maintenance/bar) +"ruk" = ( +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/commons/dorms) +"rvH" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/holofloor/beach, +/area/edina/crew_quarters/store/pet) +"rvS" = ( +/obj/effect/spawner/structure/window/reinforced/indestructable, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/cargo) +"rvT" = ( +/turf/closed/indestructible/riveted/boss, +/area/science) +"rvZ" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/edina) +"rxa" = ( +/obj/effect/landmark/start/janitor, +/turf/open/floor/plasteel/white, +/area/commons/dorms) +"rxI" = ( +/obj/item/chair/stool, +/turf/open/floor/wood, +/area/commons/dorms) +"rxL" = ( +/obj/structure/table/wood/fancy/blue, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/carpet/blue, +/area/commons/cryopod) +"ryU" = ( +/obj/structure/rack, +/obj/item/stack/sheet/mineral/wood, +/obj/item/stack/sheet/mineral/wood, +/turf/open/floor/wood, +/area/maintenance/bar) +"ryV" = ( +/turf/closed/wall/rust, +/area/edina) +"rCM" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"rDE" = ( +/obj/structure/table, +/obj/machinery/microwave{ + pixel_x = -6; + pixel_y = 10 + }, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"rEg" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"rGH" = ( +/turf/open/floor/wood, +/area/command/heads_quarters/ce) +"rKc" = ( +/obj/structure/sign/poster/contraband/lusty_xenomorph{ + pixel_x = 32 + }, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, +/area/commons/dorms) +"rKC" = ( +/obj/structure/flora/ausbushes/ywflowers, +/turf/open/floor/grass, +/area/edina) +"rRn" = ( +/obj/structure/closet/secure_closet/freezer/meat, +/obj/item/stamp/hop, +/turf/open/floor/wood, +/area/maintenance/bar) +"rSr" = ( +/obj/machinery/vending/boozeomat, +/turf/closed/festive/greybrick, +/area/maintenance/bar) +"scn" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/turf/open/floor/circuit/off, +/area/science) +"scv" = ( +/obj/structure/rack, +/obj/item/clothing/neck/scarf/red, +/obj/item/clothing/neck/scarf/red, +/obj/item/clothing/neck/scarf/yellow, +/obj/item/clothing/neck/scarf/yellow, +/obj/item/clothing/neck/scarf/green, +/obj/item/clothing/neck/scarf/cyan, +/obj/item/clothing/neck/scarf/black, +/obj/item/clothing/neck/scarf/black, +/obj/item/clothing/neck/scarf/zebra, +/obj/item/clothing/gloves/mittens/random, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/clothes) +"sek" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/shaker, +/turf/open/floor/wood, +/area/maintenance/bar) +"sgh" = ( +/mob/living/simple_animal/jacq/car_spawner, +/turf/open/floor/plasteel, +/area/service/electronic_marketing_den) +"sgT" = ( +/obj/structure/fluff/broken_flooring, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/edina) +"shm" = ( +/obj/structure/table/glass, +/obj/item/reagent_containers/food/snacks/cheesewedge, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"shJ" = ( +/obj/machinery/door/airlock/wood, +/turf/open/floor/wood, +/area/maintenance/bar) +"skd" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/window/westleft{ + name = "Hydroponics - Staff Only"; + req_one_access_txt = "25;26;28;35" + }, +/obj/machinery/door/window/eastleft{ + name = "Hydroponics" + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"slt" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"snc" = ( +/obj/machinery/portable_atmospherics/canister/water_vapor, +/turf/open/floor/plasteel/white/corner{ + dir = 4 + }, +/area/commons/dorms) +"sol" = ( +/obj/effect/turf_decal/delivery, +/obj/effect/decal/festive/fairylights, +/turf/open/indestructible{ + icon_state = "darkfull" + }, +/area/cargo/sorting) +"sqp" = ( +/obj/machinery/vending/dinnerware, +/turf/open/floor/wood, +/area/maintenance/bar) +"ssr" = ( +/obj/structure/sign/directions/cells{ + dir = 1 + }, +/turf/closed/wall/mineral/iron, +/area/security/brig) +"ssY" = ( +/obj/structure/chair/sofa/right{ + dir = 1 + }, +/turf/open/floor/wood, +/area/commons/dorms) +"suS" = ( +/obj/structure/table/wood, +/obj/effect/decal/festive/christmas_reef, +/turf/open/floor/wood, +/area/service/cafeteria/lunchroom) +"szb" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/table/glass, +/obj/item/reagent_containers/food/drinks/shaker{ + pixel_x = -9; + pixel_y = 7 + }, +/obj/item/reagent_containers/rag, +/turf/open/floor/wood, +/area/maintenance/bar) +"sEK" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood, +/area/commons/dorms) +"sGn" = ( +/obj/machinery/chem_master/condimaster{ + name = "CondiMaster Neo" + }, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"sIJ" = ( +/obj/effect/turf_decal/stripes/white/line, +/turf/open/floor/plating/beach/sand, +/area/edina) +"sMS" = ( +/obj/effect/decal/festive/fairylights, +/turf/open/indestructible, +/area/cargo) +"sOG" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/decal/festive/fairylights, +/obj/machinery/airalarm/directional/north, +/turf/open/floor/wood, +/area/maintenance/bar) +"sQo" = ( +/turf/open/floor/plasteel/white/side{ + dir = 4 + }, +/area/commons/dorms) +"sRS" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"sSj" = ( +/obj/item/flashlight/lantern, +/turf/open/floor/plating/beach/sand, +/area/edina) +"sVS" = ( +/obj/structure/table/wood, +/obj/machinery/light{ + dir = 4 + }, +/obj/item/reagent_containers/food/drinks/bottle/wine, +/turf/open/floor/wood, +/area/maintenance/bar) +"sVW" = ( +/obj/structure/chair/sofa/corp/right{ + dir = 4 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"sYK" = ( +/obj/structure/chair/sofa/left{ + dir = 1 + }, +/turf/open/floor/wood, +/area/commons/dorms) +"sYT" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"sZL" = ( +/obj/structure/chair/sofa/right{ + dir = 1 + }, +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/maintenance/bar) +"tax" = ( +/obj/structure/table, +/obj/machinery/plantgenes{ + pixel_y = 7 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/service/hydroponics) +"tbd" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/turf/open/floor/carpet/red, +/area/maintenance/bar) +"tek" = ( +/obj/structure/table, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"tmZ" = ( +/obj/structure/bedsheetbin/towel, +/obj/structure/table, +/turf/open/floor/plasteel/white, +/area/commons/dorms) +"toY" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/layer3{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) +"twg" = ( +/obj/structure/fence{ + dir = 4 + }, +/turf/open/floor/plating/beach/sand, +/area/edina) +"txa" = ( +/obj/effect/decal/festive/green_stockings, +/turf/closed/indestructible/riveted/hierophant, +/area/science) +"txb" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"tyL" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 8 + }, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/festive/alleyway, +/area/edina) +"tAq" = ( +/obj/structure/reagent_dispensers/beerkeg, +/turf/open/floor/wood, +/area/maintenance/bar) +"tBN" = ( +/obj/structure/sign/directions/evac{ + dir = 1 + }, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo) +"tHL" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/festive/alleyway, +/area/science) +"tOA" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/mob/living/simple_animal/jacq/car_spawner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/primary/perimeter) +"tPA" = ( +/obj/structure/table/wood/fancy/red, +/turf/open/floor/carpet/royalblack, +/area/maintenance/bar) +"tRd" = ( +/obj/structure/bed, +/obj/item/bedsheet/random, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"tRh" = ( +/obj/structure/flora/tree/pine/xmas{ + pixel_x = 2; + pixel_y = 14 + }, +/turf/open/floor/carpet, +/area/commons/dorms) +"tRk" = ( +/obj/machinery/nanite_programmer, +/turf/open/floor/circuit/off, +/area/science) +"tRM" = ( +/obj/structure/chair/wood/wings, +/turf/open/floor/carpet/royalblack, +/area/maintenance/bar) +"tTe" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFF"; + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/festive/alleyway, +/area/edina/backstreet/supply) +"tTL" = ( +/obj/machinery/door/window/westleft, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"tUx" = ( +/mob/living/simple_animal/kiwi, +/turf/open/floor/grass, +/area/edina) +"tWU" = ( +/obj/effect/festive/street/streetlinenorth, +/obj/effect/turf_decal/arrows/white{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"tXg" = ( +/obj/structure/table/glass, +/obj/item/toy/fluff/tennis_poly/tri/squeak/rainbow, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"ucp" = ( +/obj/effect/festive/trainrails/north{ + icon_state = "trainrails_west" + }, +/turf/open/floor/plating/dirt/space, +/area/edina) +"udo" = ( +/obj/structure/chair, +/turf/open/floor/plating/beach/sand, +/area/edina) +"ueO" = ( +/obj/structure/statue/gold/hos{ + anchored = 1 + }, +/turf/open/floor/festive/alleyway, +/area/edina/street/secondary/castle) +"uja" = ( +/obj/structure/table/wood, +/obj/item/clothing/head/festive, +/turf/open/floor/wood, +/area/maintenance/bar) +"uje" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/indestructible/airblock, +/area/science) +"ukq" = ( +/mob/living/simple_animal/mouse/white, +/turf/open/floor/festive/wooden/wooden2, +/area/edina/crew_quarters/store/pet) +"ulj" = ( +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/command/heads_quarters/ce) +"uma" = ( +/obj/structure/bonfire, +/turf/open/floor/wood, +/area/commons/dorms) +"uvz" = ( +/turf/open/floor/circuit/off, +/area/science) +"uwi" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/obj/effect/decal/festive/fairylights, +/turf/open/indestructible/airblock, +/area/science) +"uyg" = ( +/obj/effect/landmark/start/head_of_security, +/turf/open/floor/carpet/red, +/area/command/heads_quarters/hos) +"uAY" = ( +/turf/closed/festive/redbrick/redbrickcornersw, +/area/commons/dorms) +"uBp" = ( +/obj/structure/flora/rock/pile/icy, +/turf/open/floor/grass, +/area/edina) +"uBB" = ( +/obj/structure/closet/crate/freezer{ + desc = "A small crate with a cooling system, keeps fresh produce chilled."; + name = "Food Chiller" + }, +/obj/item/storage/box/ingredients/american, +/obj/item/storage/box/ingredients/american, +/obj/item/storage/box/ingredients/delights, +/obj/item/storage/box/ingredients/delights, +/obj/item/storage/box/ingredients/fruity, +/obj/item/storage/box/ingredients/fruity, +/obj/item/storage/box/ingredients/italian, +/obj/item/storage/box/ingredients/italian, +/obj/item/storage/box/ingredients/wildcard, +/obj/item/storage/box/ingredients/wildcard, +/obj/item/storage/box/ingredients/wildcard, +/obj/item/storage/box/ingredients/wildcard, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/wood, +/area/commons/dorms) +"uHF" = ( +/obj/machinery/computer/rdconsole/robotics, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/circuit/off, +/area/science) +"uIG" = ( +/obj/structure/fluff/lightpost/light, +/turf/open/floor/grass, +/area/edina) +"uMK" = ( +/turf/open/indestructible/airblock, +/area/science) +"uOf" = ( +/obj/structure/table/reinforced, +/obj/machinery/chem_dispenser/drinks/beer{ + dir = 1 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/maintenance/bar) +"uSp" = ( +/obj/structure/reagent_dispensers/keg/milk, +/turf/open/floor/wood, +/area/maintenance/bar) +"uSq" = ( +/obj/structure/bookcase/random/adult, +/turf/open/floor/grass/fakebasalt, +/area/edina) +"uVF" = ( +/obj/machinery/computer/mech_bay_power_console, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/circuit/off, +/area/science) +"uWR" = ( +/obj/structure/chair/wood/wings{ + dir = 1 + }, +/turf/open/floor/carpet/royalblack, +/area/maintenance/bar) +"uZt" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/closed/wall/r_wall, +/area/engineering/engine_smes) +"uZJ" = ( +/turf/open/floor/plating, +/area/edina) +"uZS" = ( +/turf/open/indestructible/cobble, +/area/edina) +"vdN" = ( +/turf/open/floor/carpet/orange, +/area/command/heads_quarters/ce) +"vgD" = ( +/obj/structure/sign/directions/cells, +/turf/closed/wall/mineral/iron, +/area/security/brig) +"viT" = ( +/obj/effect/turf_decal/stripes/white/full, +/turf/open/floor/plating/beach/sand, +/area/edina) +"vmW" = ( +/mob/living/simple_animal/pet/penguin/baby, +/turf/open/floor/holofloor/ice, +/area/edina) +"voP" = ( +/mob/living/simple_animal/pet/penguin/emperor, +/turf/open/floor/holofloor/ice, +/area/edina/crew_quarters/store/pet) +"vsn" = ( +/obj/item/reagent_containers/food/drinks/soda_cans/cola{ + pixel_x = -8; + pixel_y = -4 + }, +/turf/open/floor/plating/beach/sand, +/area/edina) +"vyi" = ( +/obj/item/toy/cattoy, +/obj/structure/bed/dogbed{ + name = "cat bed" + }, +/turf/open/floor/grass, +/area/edina/crew_quarters/store/pet) +"vyu" = ( +/obj/structure/table/glass, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/turf/open/floor/carpet/purple, +/area/edina/crew_quarters/store/clothes) +"vyE" = ( +/obj/machinery/vending/boozeomat, +/turf/closed/festive/whitebrick, +/area/maintenance/bar/cafe) +"vzt" = ( +/obj/item/gun/magic/wand/resurrection, +/turf/open/floor/plating/beach/sand, +/area/edina) +"vAa" = ( +/obj/structure/fluff/lightpost/light, +/turf/open/floor/plating/dirt/space, +/area/edina) +"vBV" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/power/apc/auto_name/south, +/obj/structure/cable/yellow, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/pet) +"vCH" = ( +/obj/item/reagent_containers/food/drinks/soda_cans/lemon_lime{ + pixel_x = -12 + }, +/obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb{ + pixel_x = 13 + }, +/turf/open/floor/plating/beach/sand, +/area/edina) +"vCT" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"vIN" = ( +/obj/structure/statue/snow/snowman, +/turf/open/floor/grass/snow/edina, +/area/science) +"vLq" = ( +/obj/machinery/vending/boozeomat{ + pixel_x = 32; + pixel_y = 32; + req_access = null + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"vPw" = ( +/obj/structure/window/reinforced{ + name = "Exam Room 4"; + pixel_y = -4 + }, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"wcL" = ( +/obj/structure/table/wood, +/obj/item/storage/box/donkpockets, +/turf/open/floor/wood, +/area/commons/dorms) +"wcS" = ( +/obj/structure/table/plasmaglass, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + mouse_opacity = 0 + }, +/turf/open/floor/circuit/off, +/area/science) +"wgK" = ( +/obj/structure/dead_ratvar, +/turf/open/floor/grass/snow/edina, +/area/edina) +"whG" = ( +/obj/structure/sink/kitchen{ + dir = 4; + pixel_x = -14 + }, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"wjp" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/plasteel, +/area/edina) +"wlp" = ( +/obj/machinery/door/window/westleft{ + dir = 2; + icon_state = "right" + }, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"wlG" = ( +/mob/living/simple_animal/jacq{ + active = 0 + }, +/turf/open/floor/plasteel, +/area/service/electronic_marketing_den) +"wpT" = ( +/obj/structure/fence, +/turf/open/floor/plating/beach/sand, +/area/edina) +"wsC" = ( +/obj/machinery/vending/boozeomat{ + req_access = null + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"wux" = ( +/obj/structure/table/wood, +/obj/machinery/chem_dispenser/drinks/fullupgrade, +/obj/structure/sign/picture_frame{ + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"wuG" = ( +/obj/machinery/washing_machine, +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/white/corner{ + dir = 8 + }, +/area/commons/dorms) +"wxl" = ( +/obj/structure/window/reinforced{ + dir = 1; + pixel_y = 2 + }, +/obj/machinery/light, +/turf/open/floor/festive/wooden/wooden1, +/area/edina/crew_quarters/store/pet) +"wxM" = ( +/obj/effect/spawner/trap, +/turf/open/indestructible/airblock, +/area/science) +"wHw" = ( +/mob/living/simple_animal/pet/penguin/emperor, +/turf/open/floor/holofloor/ice, +/area/edina) +"wIE" = ( +/mob/living/simple_animal/pet/dog/corgi/Ian, +/turf/open/floor/grass, +/area/edina) +"wJY" = ( +/obj/effect/decal/festive/christmas_ivy_string, +/turf/open/floor/plasteel/dark, +/area/commons/cryopod) +"wKa" = ( +/obj/machinery/door/airlock/silver{ + name = "Bathroom" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/maintenance/bar) +"wQd" = ( +/obj/effect/decal/festive/fairylights, +/turf/open/floor/circuit/off, +/area/science) +"wQO" = ( +/obj/structure/closet/crate/wooden, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/gloves/mittens/random, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/neck/scarf/christmas, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/turf/open/floor/festive/trainplatform, +/area/edina/street/primary/perimeter) +"wWV" = ( +/obj/item/toy/cattoy, +/turf/open/floor/grass, +/area/edina/crew_quarters/store/pet) +"xao" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/shower{ + dir = 4 + }, +/obj/structure/mirror{ + pixel_x = -28 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/maintenance/bar) +"xbi" = ( +/mob/living/simple_animal/mouse/brown/Tom, +/turf/open/floor/festive/wooden/wooden2, +/area/edina/crew_quarters/store/pet) +"xck" = ( +/obj/structure/fence/door/opened, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#FFFFFE"; + dir = 8 + }, +/turf/open/floor/festive/alleyway, +/area/edina) +"xcA" = ( +/obj/effect/festive/street/streetlinewest, +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"xkz" = ( +/obj/effect/festive/street/streetlineem, +/mob/living/simple_animal/jacq/car_spawner, +/turf/open/floor/festive/cobblestone, +/area/edina/street/primary/perimeter) +"xpf" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/festive/white_alleyway{ + color = "#967832" + }, +/area/edina/backstreet/supply) +"xpl" = ( +/obj/structure/closet/secure_closet/freezer/kitchen{ + req_access = list(25) + }, +/obj/item/storage/fancy/egg_box, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/mayonnaise, +/obj/item/reagent_containers/food/condiment/sugar, +/obj/item/reagent_containers/food/condiment/sugar, +/obj/item/reagent_containers/food/condiment/enzyme, +/turf/open/floor/wood, +/area/maintenance/bar) +"xri" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + mouse_opacity = 0 + }, +/turf/open/floor/circuit/off, +/area/science) +"xrZ" = ( +/obj/effect/turf_decal/stripes/white/corner{ + dir = 4 + }, +/turf/open/floor/plating/beach/sand, +/area/edina) +"xyb" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/festive/whitebrick{ + color = "#967832" + }, +/area/cargo/storage) +"xyu" = ( +/obj/effect/decal/festive/fairylights, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/indestructible, +/area/cargo/warehouse) +"xzs" = ( +/obj/effect/decal/festive/red_stockings, +/turf/closed/indestructible/riveted/hierophant, +/area/science) +"xAC" = ( +/obj/structure/mineral_door/wood, +/turf/open/floor/wood, +/area/commons/dorms) +"xEb" = ( +/obj/structure/table/wood, +/obj/machinery/light{ + dir = 1 + }, +/obj/item/phone, +/turf/open/floor/wood, +/area/maintenance/bar) +"xFf" = ( +/obj/structure/bed/double{ + dir = 1 + }, +/obj/item/bedsheet/ce/double{ + dir = 1 + }, +/turf/open/floor/wood, +/area/command/heads_quarters/ce) +"xGM" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/reagent_containers/food/snacks/waffles, +/turf/open/floor/wood, +/area/maintenance/bar) +"xJM" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/mob/living/simple_animal/jacq/car_spawner, +/turf/open/floor/festive/sidewalk, +/area/edina/street/intersection/servsuppaux) +"xMH" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/grass/snow/edina, +/area/edina/backstreet/supply) +"xQh" = ( +/obj/structure/table, +/obj/machinery/reagentgrinder{ + desc = "Used to grind things up into raw materials and liquids."; + pixel_x = -5; + pixel_y = 5 + }, +/obj/item/reagent_containers/glass/beaker/large{ + pixel_x = -10; + pixel_y = 4 + }, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"xSz" = ( +/obj/structure/closet/secure_closet/freezer/meat/open, +/obj/item/reagent_containers/food/snacks/meat/slab/goliath, +/obj/item/reagent_containers/food/snacks/meat/slab/xeno, +/obj/item/reagent_containers/food/snacks/meat/slab/spider, +/obj/item/reagent_containers/food/snacks/meat/slab/killertomato, +/obj/item/reagent_containers/food/snacks/meat/slab/bear, +/turf/open/floor/wood, +/area/maintenance/bar) +"xSI" = ( +/obj/structure/streetdecor/lampfestive{ + pixel_x = 16; + pixel_y = 10 + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"xVS" = ( +/obj/structure/reagent_dispensers/keg/gargle, +/turf/open/floor/wood, +/area/maintenance/bar) +"ycr" = ( +/obj/item/reagent_containers/food/drinks/bottle/lizardwine, +/turf/open/floor/wood, +/area/commons/dorms) +"yez" = ( +/obj/effect/landmark/start/assistant, +/turf/open/floor/carpet/royalblue, +/area/edina/crew_quarters/store/pet) +"ygB" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/grass/snow/edina, +/area/edina) +"ygQ" = ( +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"yij" = ( +/obj/structure/table/wood, +/obj/item/phone, +/turf/open/floor/carpet/red, +/area/maintenance/bar) +"yiY" = ( +/obj/structure/table/glass, +/obj/item/reagent_containers/food/drinks/bottle/patron{ + pixel_x = -6; + pixel_y = 16 + }, +/obj/item/reagent_containers/food/drinks/bottle/absinthe/premium{ + pixel_x = 7; + pixel_y = 14 + }, +/obj/item/reagent_containers/food/drinks/bottle/fernet{ + pixel_y = 11 + }, +/obj/item/reagent_containers/food/drinks/bottle/gin{ + pixel_x = -7; + pixel_y = 3 + }, +/obj/item/reagent_containers/food/drinks/bottle/whiskey{ + pixel_x = 7; + pixel_y = 4 + }, +/turf/open/floor/wood, +/area/maintenance/bar) +"yjk" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/condiment/saltshaker{ + pixel_x = -9; + pixel_y = 9 + }, +/obj/item/reagent_containers/food/condiment/peppermill{ + dir = 1; + pixel_x = -3 + }, +/obj/item/sharpener{ + pixel_x = 10 + }, +/turf/open/floor/plasteel/cafeteria, +/area/maintenance/bar/cafe) +"ylJ" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + mouse_opacity = 0 + }, +/turf/closed/indestructible/riveted/boss, +/area/science) + +(1,1,1) = {" +aaa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +"} +(2,1,1) = {" +aab +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aZu +aZu +aZu +aZu +aZu +aZu +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(3,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aac +aac +aac +aac +aZu +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(4,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aac +aac +aac +aac +aZu +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(5,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aac +aac +aac +aac +aZu +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(6,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aac +aac +aac +aac +aZu +aac +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(7,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aac +aac +aac +aac +aZu +aac +aac +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(8,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aac +aac +aac +aac +aZu +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aad +aad +aad +aad +aac +"} +(9,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aac +aac +aac +aac +aZu +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +cAZ +cAZ +cAZ +cAZ +cAZ +aad +aad +aad +aad +aac +"} +(10,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aal +aal +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aac +aac +aac +aac +aZu +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +cAZ +cBe +cBe +cBe +cAZ +aad +aad +aad +aad +aac +"} +(11,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aac +aac +aac +aac +aZu +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +cAZ +cBe +cBi +cBe +cAZ +aad +aad +aad +aad +aac +"} +(12,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aac +aac +aac +aac +aZu +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +cAZ +cBe +cBe +cBe +cAZ +aad +aad +aad +aad +aac +"} +(13,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aac +aac +aac +aac +aZu +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +cBa +cBa +cBj +cBa +cBa +aad +aad +aad +aad +aac +"} +(14,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aac +cAM +aac +aac +aZu +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +cBa +cBd +cBd +cBd +cBa +aad +aad +aad +aad +aac +"} +(15,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +kld +cAM +cAQ +aac +aZu +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +cBa +cBd +cBc +cBn +cBa +aad +aad +aad +aad +aac +"} +(16,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +kld +cAM +cAQ +kld +aZu +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +cBa +cBf +cBd +cBd +cBa +aad +aad +aad +aad +aac +"} +(17,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +bKW +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +kld +cAM +cAQ +kld +aZu +aac +aac +aac +aac +aac +aac +aac +aac +aac +cAV +cBb +cBg +cBj +cBa +cBa +cBa +aad +aad +aad +aac +"} +(18,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aal +aal +aal +aal +aan +aan +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aal +aal +aad +aad +aad +aac +aZu +kld +cAM +cAQ +kld +aZu +aac +aac +aac +aac +aac +aac +aac +aac +aac +cAW +cBc +cBd +cBk +cBd +cBc +cBa +aad +aad +aad +aac +"} +(19,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aao +aze +aal +aal +aal +aal +aal +aal +aan +aan +aal +aal +aal +aal +acZ +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +acZ +aal +acZ +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aZu +kld +cAM +cAQ +kld +aZu +aac +aac +aac +aac +aac +aac +aac +aac +aac +cAW +cBd +cBd +cBl +cBd +cBd +cBa +aad +aad +aad +aac +"} +(20,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aap +aap +aal +aal +aal +aal +aal +aal +aao +aze +aal +aal +aal +aal +acZ +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +cwv +aad +aad +aad +aad +aal +aal +aal +aad +aac +brL +cAM +cAQ +ctQ +aad +aac +aac +aac +aac +aac +aac +aac +aac +aac +cAW +cBd +cBh +cBh +cBh +cBd +cBa +aad +aad +aad +aac +"} +(21,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aap +aap +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aal +aal +aal +aad +aad +aad +aal +aal +aal +aal +aad +aad +aad +aal +aal +aal +acZ +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +acZ +aal +aal +acZ +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aad +aad +aac +aac +aac +aac +aac +aac +aac +aac +cAW +cBd +cBh +cBh +cBh +cBd +cBa +aad +aad +aad +aac +"} +(22,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +bKW +aal +aal +aal +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +acZ +aal +acZ +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +brL +cAM +cAQ +ctQ +aad +aad +aad +aac +aad +aac +aac +aac +aac +aac +cAW +cBd +cBh +cBh +cBh +cBd +cBa +aad +aad +aad +aac +"} +(23,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +bKW +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aal +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +brL +cAM +cAQ +ctQ +aad +aad +aad +aac +aac +aad +aac +aac +aac +aac +cAW +cBc +cBd +cBm +cBd +cBc +cBa +aad +aad +aad +aac +"} +(24,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +kfS +kfS +kfS +kfS +noa +kfS +aIA +aIA +aqg +aqg +aqg +aqg +aqg +aqg +vmW +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aal +aal +aal +aal +aal +aal +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +acZ +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +brL +cAM +cAQ +ctQ +aad +aad +aad +aad +aac +aac +aad +aad +aac +aac +cAW +cBa +cBa +cBa +cBa +cBa +cBa +aad +aad +aad +aac +"} +(25,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +kfS +lXj +cwl +cwl +cwl +knK +aIA +aIA +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aal +aal +aal +aal +aal +aal +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aal +aad +aad +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +brL +cAM +cAQ +ctQ +aad +aad +aad +aad +aad +aac +aad +aad +aac +aac +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(26,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +kfS +lhY +cwl +cwl +cwl +knK +fhW +aIA +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aal +aal +aal +aal +aal +aal +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aal +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +akI +aoQ +atz +aoQ +aoQ +aoQ +atz +aoQ +aoQ +axm +axN +ayB +ayB +ayB +axN +ayB +ayB +ayB +axN +ayB +ayB +ayB +axN +ayB +ayB +ayB +axN +ayB +ayB +ayB +aGr +atz +aoQ +aoQ +aBj +akI +aad +aad +aad +aad +aad +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +bqH +bqH +bqH +bqH +bqH +bqH +bqH +bqH +bqH +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +brL +cAM +cAQ +ctQ +aad +aad +aad +aad +aad +aad +aac +aad +aac +aac +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(27,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +kfS +ibM +cwl +cwl +cwl +cqI +fhW +aIA +aqg +aqg +aqg +wHw +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aal +aal +aal +aal +aal +aal +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +akI +aoQ +atA +atB +atB +atB +atA +aoQ +aoQ +axn +aoQ +atA +atB +atB +atB +atA +aoQ +atA +atB +atB +atB +atA +aoQ +atA +atB +atB +atB +atA +aoQ +atA +aGs +atB +atB +atA +aoQ +akI +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aWv +aWv +aWw +aWv +aWv +bqH +bqH +btS +btS +btS +btS +btS +btS +btS +bqH +bqH +bqA +bqA +btR +bqA +bqA +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +brL +cAM +cAQ +ctQ +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(28,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +kfS +sek +cwl +cwl +cwl +cqI +fhW +aIA +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +vmW +aqg +aqg +aqg +aqg +aal +aal +aal +aal +aal +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +akI +aoQ +atB +auf +atc +aub +auN +avz +awB +axo +aoQ +atB +ayZ +azC +azC +atB +aoQ +atB +aAM +aAX +aAX +atB +aoQ +atB +aBG +aCa +aCa +atB +aoQ +atB +aGt +aBO +aBO +atB +aoQ +akI +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aWv +aXF +aZv +bbi +aWv +bfp +bfp +btS +btS +btS +bjA +btS +btS +btS +bfp +bfp +bqA +bsk +btS +bvf +bqA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +brL +cAM +cAQ +ctQ +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(29,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +kfS +kpp +cwl +cwl +cwl +lNU +fhW +aIA +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aal +aal +aal +aal +aal +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +akI +asK +atB +auf +atd +auf +auO +aoQ +awC +axp +axO +atB +ayZ +azD +azU +atB +aoQ +atB +aAM +aAY +aBb +atB +aoQ +atB +aBG +aCb +aCG +atB +aoQ +atB +aGu +aBO +aCV +atB +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aWw +aXG +aZv +bbj +aWv +bdX +bfq +btS +btS +btS +btS +btS +btS +btS +bed +bfq +bqA +bsl +btS +bvg +btR +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +brL +cAM +cAQ +ctQ +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(30,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +kfS +phl +cwl +cwl +cwl +gud +fhW +aIA +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aal +aal +aal +aal +aal +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +akI +aoQ +atB +auf +auf +auc +auP +avA +awD +axq +awE +atB +aza +azC +azV +atB +aoQ +atB +aAN +aAX +aBc +atB +aoQ +atB +aBH +aCa +aCI +atB +aoQ +atB +aGu +aBO +aIb +atB +aBj +akI +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aWv +aXH +aZw +bbn +aWv +bdY +bfr +btS +bhQ +biP +bjB +biP +blz +btS +bee +bpf +bqA +bsm +btS +bvg +bqA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +brL +cAM +cAQ +ctQ +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(31,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +kfS +wux +cwl +cwl +cwl +lLP +fhW +aIA +aqg +aqg +aqg +aqg +vmW +hoN +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aal +aal +aal +aal +aal +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aad +aad +aad +aad +aal +aal +aad +aad +aad +akI +aoQ +atB +atB +atB +atB +atA +aoQ +awE +axq +awE +atB +azb +auO +azW +atA +aoQ +atB +azb +auO +azW +atA +aoQ +atB +azb +auO +azW +atA +aoQ +atB +atB +auO +azW +atA +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aWv +aXI +aZv +bbo +aWv +bdZ +bfq +btS +bhR +biQ +bjC +bkq +bhR +btS +bed +bft +bqA +bsn +btT +bvh +bqA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(32,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +kfS +gFH +cwl +cwl +cwl +cqI +fhW +aIA +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +wHw +aqg +aqg +aqg +aqg +aqg +aal +aal +aal +aal +aal +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aal +aad +aad +aad +aad +akI +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +awE +axq +awE +aoQ +azc +aoQ +azX +aoQ +aoQ +aoQ +azc +aoQ +hgb +aoQ +aoQ +aoQ +azc +aoQ +hgb +aoQ +aoQ +aoQ +aGv +aoQ +aIc +aGr +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aWv +aXJ +aWv +aWv +aWv +bea +bfr +btS +btS +biR +btS +bkr +btS +btS +bee +bfr +bqA +bqA +bqA +bvi +bqA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +acZ +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aad +aad +aad +aad +aad +aad +aad +aad +aac +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(33,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +kfS +rqO +cwl +cwl +cwl +cqI +fhW +aIA +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +vmW +aqg +aqg +aqg +aal +aal +aal +aal +aal +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aal +aal +aad +aad +aad +aad +akI +aoQ +atB +atB +atB +atB +atA +aoQ +awE +axq +awH +axs +azf +axs +azY +axs +axs +axs +aAO +axs +azY +axs +axs +axs +aBI +axs +azY +axs +axs +axs +axs +axs +azY +aII +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aVV +aXK +aWy +bbp +bcF +beb +bcF +bcF +bcF +biV +bcF +bks +bcF +bcF +bcF +bcF +bcF +bJt +btU +bvj +bqA +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(34,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +kfS +cwl +cwl +cwl +cwl +cqI +fhW +aIA +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aal +aal +aal +aal +aal +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +bKW +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +akI +asK +atB +aug +ate +aud +auS +avz +awF +axr +axP +axP +axP +axP +azZ +axP +axP +axP +axP +axP +azZ +axP +axP +axP +axP +axP +azZ +axP +axP +axP +axP +axP +aId +aIJ +aBj +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aVV +aVV +aXL +aZx +bbq +bcG +bec +bfs +bfs +bfs +biW +bjD +bkt +bfs +bfs +bfs +bfs +bqB +bJu +btV +bvk +bqA +bqA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(35,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +kfS +xpl +aQc +xSz +cwl +kfS +ewh +aIA +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aal +aal +aal +aal +aal +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +akI +aoQ +atB +aug +atf +aug +auO +aoQ +awE +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aqK +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aqK +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aqK +aBv +aIJ +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +acZ +aal +acZ +aal +aVV +aWx +aXM +aZy +aVV +bcH +bed +bft +bgM +bft +biR +bjE +bkr +bgM +bft +bgM +bfq +bcH +bqA +btW +bvl +bwt +bqA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(36,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +kfS +kfS +kfS +kfS +kfS +kfS +aIA +cAL +aqg +aqg +vmW +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aal +aal +aal +aal +aad +aad +aad +aad +aad +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +amu +amu +amu +amu +amu +amu +akI +aoQ +atB +aug +aug +auh +auP +avA +awG +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aCc +aCJ +aDO +aCf +aoQ +aoQ +aoQ +aBv +aIJ +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aVW +aWy +aXN +aZz +aVV +bcH +bee +bfr +bee +bfr +biR +bjF +bkr +bee +bfr +bee +bfr +bcH +bqA +btX +bvm +bwu +btR +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +acZ +aal +aal +aad +aad +aad +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(37,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +amu +awA +bBo +rGH +xFf +fyx +akI +aoQ +atA +atB +atB +atB +atA +aoQ +awH +axs +axs +axs +axs +axs +axs +axs +axs +axs +axs +axs +axs +axs +axs +axs +axs +axs +axs +axs +axs +axs +axO +aoQ +aBv +aIJ +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aVW +aWz +aXO +aZA +aVV +bcH +bed +bft +bgM +bft +biR +bjF +bkr +bgM +bft +bgM +bfq +bcH +bqA +btY +bvn +bwv +btR +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(38,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aad +aad +amu +ayY +fUG +vdN +vdN +ulj +akI +asK +aoQ +aoQ +atg +aoQ +aoQ +aoQ +atg +aoQ +aoQ +atg +aoQ +aoQ +aoQ +aoQ +awE +aoQ +aoQ +aoQ +aoQ +aoQ +aqK +aoQ +aoQ +aCd +aCJ +aCJ +aoQ +aqK +awE +aoQ +aBv +aIJ +aBj +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aVV +aWB +aXW +aZC +aVV +bcI +bee +bfr +bee +bfr +biR +bjE +bkr +bee +bfr +bee +bfr +bqC +bqA +btZ +bvn +bwv +bqA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(39,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +amu +aMH +vdN +hBk +vdN +qUP +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +azE +aoQ +aoQ +awE +aoQ +aoQ +aoQ +aoQ +aoQ +aBi +aBs +aBJ +aCe +aCK +aCe +aEx +aBJ +aGw +aoQ +aBv +aIJ +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aVW +aWC +aXX +aZD +aVV +bcH +bed +bft +bgM +bft +biR +bjF +bkr +bgM +bft +bgM +bfq +bcH +bqA +bua +bvn +bwv +btR +aal +aal +aal +aal +aal +aFs +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +amF +bIf +bKY +bMl +bMR +bNz +aal +aal +aal +aal +aal +aal +aad +aad +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(40,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aal +aal +aal +aad +aal +aal +aan +aan +aal +aal +aal +aal +aal +aal +aal +aal +aal +bKW +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +amu +aMH +rGH +rGH +rGH +fGL +ajK +arf +arS +asu +ath +aui +auT +avB +cBd +axt +axQ +cBd +ajK +aoQ +aoQ +aoQ +awE +aqK +aoQ +aoQ +aoQ +aoQ +aoQ +aBt +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aGx +aoQ +aBv +aIJ +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aVW +aWD +aXY +aZA +aVV +bcH +bee +bfr +bee +bfr +biR +bjF +bkr +bee +bfr +bee +bfr +bcH +bqA +bub +bvo +bvp +btR +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(41,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aal +aal +aal +aal +aal +aal +aao +aze +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +amu +bww +amu +amu +amu +amu +amu +cBd +arT +asv +ati +auj +asv +avB +auj +axt +axR +cBd +ajK +aoQ +aoQ +aoQ +awE +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aBu +aBJ +aBs +aBs +aBs +aBs +aBs +aGy +aoQ +aBv +aIJ +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aVV +aWD +aXZ +aZE +aVV +bcH +bed +bft +bgM +bft +biR +bjE +bkr +bgM +bft +bgM +bfq +bcH +bqA +buc +bvp +bvp +bqA +aal +aal +aal +acZ +aal +aGn +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +acZ +aal +aad +aad +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(42,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aal +aal +aal +aap +aap +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +amu +anb +amu +aom +apg +apQ +amu +arg +arU +asw +atj +arU +asw +avC +arU +axu +axR +cBd +ajK +aoQ +aoQ +aoQ +awE +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aBv +aoQ +aCf +aCf +aCf +aEy +aFj +aoQ +aoQ +aBv +aIJ +aBj +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +acZ +aVV +aWF +aVV +aVV +aVV +bcH +bee +bfr +bee +bfr +biR +bjF +bkr +bee +bfr +bee +bfr +bcH +bqA +bqA +bvq +bqA +bqA +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(43,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +bKW +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +amu +anc +anq +aon +aon +apR +amu +arh +cBd +cBd +cBd +cBd +cBd +cBd +cBd +cBd +cBd +ayC +ajK +azE +aoQ +aoQ +awE +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aBv +aoQ +aoQ +aqK +aoQ +aoQ +aoQ +aoQ +aoQ +aBv +aIJ +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aVV +aWG +aYa +aZF +bbr +bcJ +bef +bfx +bef +bef +biX +bjG +bkw +bef +bef +bfx +bef +bqD +bqA +bud +bvr +bwy +bqA +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(44,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aan +aan +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +amv +and +anr +aoo +aph +apS +aqM +ari +arV +anz +anz +arV +anz +anz +arV +anz +aos +cBd +azg +aoQ +aoQ +aoQ +awE +aoQ +aoQ +aoQ +aqK +aoQ +aoQ +aBv +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aBv +aIJ +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +acZ +aal +aal +aal +aal +aVV +aVV +aVV +bqA +bqA +bqA +bqA +bfy +bfy +bfy +biY +bjH +bkx +bfy +bfy +bfy +bqA +bqA +bqA +bqA +bqA +bqA +bqA +aal +alK +pNf +pNf +pNf +bjS +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +btf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +pNf +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(45,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aao +aze +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +amw +ane +anr +aop +api +apT +aqN +cBk +cBd +cBd +cBd +cBd +cBd +cBd +cBd +cBd +cBk +cBd +azg +aoQ +aoQ +aoQ +awE +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aBw +aBK +axP +axP +axP +axP +axP +aBK +axP +aIe +aIJ +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +bqA +btS +btS +bbs +bcK +btS +bfy +bgN +bhS +biZ +bjI +bky +blA +bgN +bfy +bpi +bqE +bsq +bue +bvt +bqA +aal +aal +brL +ucp +ucp +ucp +brK +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(46,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aap +aap +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +amx +anf +anu +aoq +apj +apU +aqO +aoA +cBd +asx +atk +auk +auU +avD +auk +axv +axS +cBd +ajK +azE +aoQ +aoQ +awH +axs +axs +axs +aBd +aBf +aBf +aBf +aBL +aBf +aCL +aDP +aDP +aDP +aGz +aDP +aCL +aIK +aBj +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +bqH +btS +aZG +bbt +bcL +beg +bfz +bgO +bgO +bja +bjJ +bkz +blB +bmJ +bnZ +bpj +bqF +bsr +buf +bvu +bqH +aal +aal +brL +dgn +dgn +dgn +brM +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +aag +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(47,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +amu +amu +anv +aor +amu +amu +amu +ark +cBc +asy +ati +auj +asv +ati +auj +cBd +axS +cBd +ajK +ajK +ajK +ajK +ajK +ajK +ajK +aoQ +aoQ +aoQ +aoQ +aoQ +aBM +aoQ +aCM +aoQ +aoQ +aoQ +toY +aoQ +aIf +aoQ +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +bqA +btS +aZG +bbu +bcM +beh +bfy +bgX +bhT +bjb +bjK +bkA +bhT +bmK +bfy +bpk +bqG +bss +bug +bvv +bqA +aal +aal +alN +amq +ams +ams +bGq +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +bId +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +ams +bIe +gnR +gnR +gnR +gnR +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(48,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aan +aan +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +ajK +ajU +ajU +ajU +ajU +ajU +ajU +ajU +ajU +ajU +ajU +ang +cBd +cBd +cBd +cBd +anh +arl +cBd +asz +atl +aul +auV +avE +awI +axw +axS +cBd +azg +azF +azF +azF +azF +azF +ajK +aoQ +aoQ +aoQ +aoQ +atB +azW +aCg +aCN +atA +aoQ +atB +azW +aCg +aCN +atB +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +bqA +bqA +bqH +bqA +bqH +bqA +bfy +bgZ +bhT +bjb +bjL +bkA +bhT +bmL +bfy +bqA +bqH +bqA +bqH +bqA +bqA +aal +aal +aal +buP +bvU +bvU +bvU +bvU +bvU +bvU +bvU +aXQ +bGE +bKg +bGE +bKg +aXQ +bvU +bvU +bvU +bvU +bvU +aXQ +bGE +bIs +bKg +aXQ +bvU +bvU +bvU +bvU +bvU +aXQ +bGE +bKg +bGE +bKg +aXQ +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cqg +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(49,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aao +aze +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +ajK +ajU +ajU +ajU +ajU +ajU +ajU +alk +ajU +ajU +ajU +anh +anx +aos +cBc +cBd +anh +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +axT +cBd +azh +azG +azF +azF +azF +aAz +ajK +aoQ +aoQ +aoQ +aoQ +atB +aBN +aBO +aCO +atB +aoQ +atB +aBN +aBO +aCO +atB +aoQ +akI +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +bfy +bha +bhU +bjc +bjM +bkA +bhT +bmM +bfy +aal +aal +aal +aal +aal +aal +aal +aal +aal +buP +bvU +bvU +bvU +bvU +bvU +bvU +bvU +aXQ +bGF +bvU +bvU +bKh +aXQ +bvU +bvU +bvU +bvU +bvU +aXQ +bGF +bvU +bKh +aXQ +bvU +bvU +bvU +bvU +bvU +aXQ +bGF +bvU +bvU +bKh +aXQ +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cqg +aal +aal +acZ +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(50,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aap +aap +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +ajK +ajU +akp +ajX +aku +akL +ala +ajX +als +ajX +amC +anh +anx +aot +cBd +cBd +anh +cBd +cBd +cBd +cBd +cBd +ajK +avF +avF +cBd +cBk +ayD +azi +azF +azF +azF +aAq +azF +ajK +aoQ +aoQ +aoQ +aBj +atB +aBO +aBO +aCV +atB +aoQ +atB +aBO +aBO +aCV +atB +aBj +akI +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +acZ +aal +aal +aal +bfA +bhb +bhT +bjb +bjL +bkA +bhT +bmM +bfA +aal +aal +acZ +aal +aal +aal +aal +aal +aal +buP +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cqg +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(51,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +ajK +ajU +akq +ajY +akv +ajU +akv +ajU +akv +ajY +akq +anh +ajK +aou +aow +ajK +ajK +ajK +nOZ +nOZ +nOZ +nOZ +nOZ +cBc +cBd +cBd +cBk +cBd +azj +azF +azF +azF +azF +azF +ajK +aoQ +aoQ +aoQ +aoQ +atB +aBO +aBO +aBO +atB +aoQ +atB +aBO +aBO +aBO +atB +aoQ +akI +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +bfy +bhc +bhT +bjb +bjL +bkA +bhT +bmN +bfy +aal +aal +aal +aal +aal +aal +aal +aal +aal +buP +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cqg +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(52,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aac +ajK +ajU +akr +akh +ajU +ajU +ajU +ajU +ajU +alW +amD +anh +any +aov +anz +anz +anz +arm +arW +asA +asA +asA +auW +avF +avF +cBd +cBk +cBd +azh +azG +azF +azF +azF +aAz +ajK +aoQ +aoQ +aoQ +aoQ +atA +atB +atB +atB +atA +aoQ +atA +atB +atB +atB +atA +aoQ +akI +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +bfA +bhb +bhT +bjd +bjV +bky +bhT +bhT +bfA +aal +aal +aal +aal +aal +acZ +aal +aal +aal +buP +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cqg +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(53,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +sVW +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aac +ajK +ajU +akq +ajU +ajU +akM +ajU +akM +ajU +ajU +akq +anh +cBd +aow +aow +aow +aow +cBd +dqG +asB +asB +asB +uZt +ajK +ajK +axx +cBk +cBd +ajK +azG +azF +azF +azF +azF +ajK +aoQ +aoQ +aoQ +aoQ +aoQ +aoQ +aCk +aoQ +aoQ +aoQ +aCk +aoQ +aoQ +aoQ +aCk +aoQ +akI +aal +aal +aal +acZ +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +acZ +aal +aal +acZ +aal +bfy +bhT +bhT +bjd +bjW +bky +bhT +bhT +bfy +aal +aal +aal +aal +aal +aal +aal +aal +aal +buP +bvU +bvU +bvU +bvU +bvU +bvU +bvU +aXQ +bGF +bvU +bvU +bKh +aXQ +bvU +bvU +bvU +bvU +bvU +aXQ +bGF +bvU +bKh +aXQ +bvU +bvU +bvU +bvU +bvU +aXQ +bGF +bvU +bvU +bKh +aXQ +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cqg +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(54,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aan +aan +aal +aal +aal +aal +aal +aal +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aac +aac +ajK +ajU +aks +akh +ajU +ajU +ajU +ajU +ajU +alW +amE +ani +anz +aox +aox +apV +aox +anz +arW +asC +atm +aum +auX +avG +awJ +anz +axU +cBd +ajK +ajK +ajK +azg +azg +ajK +ajK +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +akI +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +bfy +bfy +bhV +bje +bjX +bkB +bhV +bfy +bfy +acZ +aal +aal +aal +aal +aal +aal +aal +aal +buP +bvU +bvU +bvU +bvU +bAE +bvU +bvU +aXQ +bGE +bKg +bGE +bKg +aXQ +bvU +bvU +bAE +bvU +bvU +aXQ +bGE +bIs +bKg +aXQ +bvU +bvU +bAE +bvU +bvU +aXQ +bGE +bKg +bGE +bKg +aXQ +bvU +bvU +bAE +bvU +bvU +bvU +bvU +cqg +aal +aal +aal +acZ +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aad +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(55,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aao +aze +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aac +aac +ajK +ajU +akq +ajU +ajU +akM +ajU +akM +ajU +ajU +akq +anh +cBd +aow +aow +apW +aow +cBd +dqG +asD +asD +asD +uZt +ajK +ajK +cBd +cBk +cBd +ajK +aFe +aEY +aGl +aGl +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +ceN +bgn +bdS +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +ckJ +ckJ +ckJ +ckU +ckX +mIf +ckX +ckX +cll +ckX +ckX +ckX +ckX +ckX +ckX +ckX +ckX +ckX +ckX +cll +ckX +ckX +ckX +ckX +ckX +ckX +ckX +ckX +ckX +cll +ckX +ckX +ckX +ckX +ckX +ckX +cpk +cpk +cpk +cpk +cll +ckX +cpA +cos +cos +cqh +aal +aal +aal +aal +brL +cAN +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(56,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +acZ +aal +aal +aal +aap +aap +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aac +aac +ajK +ajU +ajO +akh +ajU +ajU +ajU +ajU +ajU +alW +amG +anh +cBc +aoy +anz +anz +anz +arn +arW +asA +asA +asA +auY +aal +ajK +ajK +axV +ajK +ajK +tOA +aGl +aGl +aIz +aGl +aGl +aGl +aGl +aGl +aGl +aGl +aGl +aGl +aGl +aIz +aGl +aGl +aGl +aGl +aGl +aGl +aIz +aGl +aGl +aGl +aGl +aGl +aGl +aIz +aGl +aGl +aGl +aGl +aGl +aGl +aIz +aGl +aGl +aGl +aGl +aGl +aGl +aIz +aGl +aGl +aGl +aGl +aGl +aGl +aIz +aGl +aGl +aGl +ceN +bgn +chp +aGl +aGl +aGl +aGl +aGl +aGl +aGl +aIz +aGl +aGl +aGl +aGl +aGl +aGl +aIz +aGl +aGl +aGl +aGl +aGl +aGl +ckP +aGl +aGl +aGl +aGl +aGl +aGl +aGl +aGl +aGl +aGl +ckP +aGl +aGl +aGl +aGl +aGl +aGl +aGl +aGl +ckP +aGl +aGl +aGl +aGl +aGl +aGl +aGl +aGl +ckP +cpB +chA +chA +chA +chY +aal +aal +aal +brL +cAN +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(57,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aac +aac +ajK +ajU +akq +ajY +akw +ajU +akw +ajU +akw +ajY +akq +anh +ajK +aou +cBd +ajK +ajK +ajK +nOZ +nOZ +nOZ +nOZ +nOZ +aal +ajK +axy +cBk +cBd +cds +aFr +aGE +aGZ +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGZ +aMl +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +byF +ceO +cff +chq +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aHk +aMl +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aHk +aMl +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aHk +aMl +aGE +aGE +aGE +aGE +aGE +cps +aGl +bgU +aal +chB +chB +chZ +chB +chB +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +cAX +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(58,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +bKW +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aal +aal +aal +aal +aal +aad +aad +aad +aad +aal +aad +aad +aad +aac +aac +ajK +ajU +ajP +ajX +akx +akN +alb +ajX +alA +ajX +amH +anh +anx +aoz +cBd +cBd +anh +aal +aal +aal +aal +aal +aal +aal +ajK +axz +axW +cBd +azk +aFK +aFK +aHa +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aHc +aFK +aUm +aFK +aFK +aFK +aFK +aFK +aUY +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aUm +aFK +aFK +aFK +aFK +aFK +aFK +aUY +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aUm +aFK +aFK +aFK +aFK +aFK +aFK +ceP +cfG +cht +aFK +aFK +aFK +aFK +aUY +aFK +aFK +aFK +aFK +aFK +aHa +aFK +aFK +aFK +aFK +aFK +aFK +aUY +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aUY +aFK +aFK +aHa +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aUm +aFK +aFK +aFK +aHb +aFK +aFK +aFK +aFK +aUm +aFK +aVo +aGl +bgU +chB +chB +chV +cia +cie +chB +chB +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +fQp +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(59,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aad +aad +aad +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aac +ajK +ajU +ajU +ajU +ajU +ajU +ajU +all +ajU +ajU +ajU +anh +anx +aoA +cBc +cBd +anh +aal +aal +acZ +aal +aal +aal +acZ +ajK +axz +cBk +cBd +azk +aFK +aFK +aHb +aFK +aFK +aFK +aUm +aFK +aFK +aVe +aIO +aHb +bjQ +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +byq +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +byq +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +ceR +cfG +chx +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aHb +bjQ +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +byq +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aHb +bjQ +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aHc +bjQ +aPv +aFK +aFK +aFK +aFK +aVo +aGl +bgU +chB +chL +chW +cib +chW +cif +chB +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +fQp +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(60,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aEK +aEK +vyE +aEK +aEK +aEK +cHo +aEK +aEK +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aac +ajK +ajU +ajU +ajU +ajU +ajU +ajU +ajU +ajU +ajU +ajU +ang +cBd +cBd +cBd +cBd +anh +aal +aal +aal +aal +aal +aal +aal +ajK +axy +cBk +cBd +azk +aFK +aFK +aHc +aFK +aFK +aFK +aFK +aFK +aFK +aYV +bdQ +aHa +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +byF +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +byF +aGE +aGE +ceS +cfG +chy +aGE +aGE +byF +aGE +aGE +aGE +aGE +aGE +aGE +bdQ +aHc +aGE +aGE +aGE +clc +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +aGE +byF +aGE +bdQ +aHb +aGE +aGE +aGE +byF +aGE +aGE +aGE +aGE +byF +aGE +bdQ +aHb +aGE +aSw +aFK +aFK +aFK +aFK +aVo +aGl +bgU +chC +chM +chW +cic +chW +cig +chC +brL +cAM +cAQ +ctQ +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +fQp +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(61,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aEK +cZi +ygQ +oYY +mUg +whG +ygQ +xQh +aEK +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +ajK +aal +aal +aal +aal +aal +aal +aal +ajK +axA +axW +cBd +azk +aFK +aFK +aHb +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aHb +aFK +aFK +aFK +aUY +aFK +aFK +aFK +aFK +aUm +aFK +aFK +aFK +aFK +aUY +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aUm +aFK +aFK +aFK +aFK +aUY +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +ceP +bjn +chz +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aHb +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +ceP +aHb +cmY +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aHa +aFK +aFK +aFK +aFK +aFK +aFK +aVo +aGl +bgU +chB +chN +chW +cid +chW +cih +chB +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +fQp +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(62,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aEK +rDE +ygQ +ygQ +ygQ +ygQ +ygQ +ygQ +aEK +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aal +aal +aal +aal +acZ +aal +aal +ajK +cBd +axX +cBd +ajK +aFL +aGF +aHd +aIO +aPv +aFK +aVe +aPv +aFK +aVe +bdR +bfk +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +aIO +aIO +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +aIO +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +bjT +ceT +cgC +cji +bjT +bjT +bjT +cks +bjT +bjT +bjT +bjT +bjT +ckK +ckM +bjT +bjT +bjT +cks +bjT +bjT +bjT +bjT +bjT +bjT +bjT +cmn +bjT +cks +bjT +bjT +bjT +bjT +cmR +cmV +cmZ +bjT +bjT +cks +bjT +bjT +bjT +bjT +bjT +bjT +ckK +ckM +bjT +coQ +aFK +aVe +aPv +aFK +aVo +aGl +bgU +chB +chO +chW +chW +chW +cii +chB +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +fQp +aal +aal +aad +aad +aad +aad +aad +aad +aad +aac +"} +(63,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aal +aal +aal +aal +acZ +aal +aal +aal +aEK +lBE +ygQ +iOS +yjk +gOB +gOB +ygQ +aEK +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +ajK +ajK +axY +eSe +eSe +aGh +aGh +aHf +aJq +aPY +aTU +aVf +aZr +aTU +bco +bVp +bfl +bkl +brV +bkl +bkl +bkl +bkl +bkl +bkl +brV +bkl +bkl +bkl +bkl +bkl +bkl +brV +bkl +bkl +bkl +bkl +bkl +bkl +brV +bkl +bkl +bkl +bkl +bkl +bkl +brV +bkl +bkl +bkl +bkl +bkl +bkl +brV +bkl +bkl +bkl +bkl +cfb +cgD +cjT +bkl +bkl +bkl +cfb +ckv +bkl +brV +bkl +bkl +bkl +bkl +bkl +bkl +ckY +cfb +bkl +bkl +bkl +bkl +bkl +bkl +cmj +bkl +bkl +cfb +bkl +bkl +ckv +bkl +cmS +cmW +cnb +bkl +bkl +cnp +bkl +bkl +bkl +bkl +ckv +bkl +bkl +bkl +coq +coS +aFK +aWt +aRT +aFK +aVo +aGl +biS +chD +chP +chX +chX +chX +cij +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +fQp +aal +aal +aad +aad +aad +aad +aad +aad +aad +aac +"} +(64,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aal +aal +aal +aal +aal +aal +eKC +aal +aEK +jse +ygQ +ygQ +ygQ +ygQ +ygQ +ygQ +aEK +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aal +aal +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aFq +aGl +aPZ +aTV +aTV +aVd +aTV +bcr +bdS +bfu +bmF +bmF +bmF +bsc +bmF +bmF +bmF +bmF +bmF +bmF +bxt +bxt +bmF +bmF +byr +bmF +bmF +bmF +bmF +bmF +bmF +bmF +bmF +bmF +bmF +bmF +bmF +bmF +bmF +bsc +bmF +bmF +bmF +bmF +bmF +bmF +bmF +bmF +bmF +bmF +bxt +cfc +cgE +bmF +bmF +bmF +bmF +ckt +ckw +bmF +bmF +bmF +bmF +bmF +ckN +bmF +bmF +clb +cfc +clg +clg +clg +clg +bmF +clq +clq +cmo +cmo +cmD +cmE +cmG +cmL +cmo +cmo +cmX +cnc +cmo +cmo +cmD +cmo +cmo +cmo +cmo +cmL +cmo +cmo +cnG +bez +coT +cpl +cpp +cpp +cpp +cpu +aHh +cpC +chE +chQ +chQ +chQ +chQ +cik +ciq +cAH +cAO +cAR +cAT +cwY +cwY +cwY +cwY +cwY +cwY +cwY +cwY +cwY +cwY +cAY +aal +aal +aad +aad +aad +aad +aad +aad +aad +aac +"} +(65,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aEK +sGn +ygQ +dfl +tek +izr +cPd +fld +aEK +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aFq +aGl +aQG +aFK +aVo +aZH +aFK +bcw +bdS +bgl +cnB +byU +byU +bAm +byU +bBQ +bBQ +bDR +bBQ +byU +bhh +bhW +aKN +aKN +aLO +aKN +aKN +aKN +aKN +aKN +aKN +aKN +aKN +aKN +aKN +aKN +aKN +aKN +aKN +bgD +aNe +aNe +aNe +aNe +aNe +aNe +aNe +aNe +aNe +aNe +bFs +bHQ +bhO +biH +biH +biH +biH +bkm +bkp +bkk +bkk +bkk +bmB +biH +biH +biH +biH +bpg +bqo +biH +biH +biH +biH +bsa +bFs +bHZ +bIh +bJB +bLc +bMo +bNB +bPb +bQY +bIh +cjY +bHZ +bUJ +bUJ +cbK +cfp +cfp +cfp +cfp +cgi +bUJ +bUJ +cnH +bdS +coU +aFK +aVo +aZH +aFK +bdM +ckP +aGl +acQ +acQ +acQ +acQ +acQ +cno +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aac +"} +(66,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aal +aal +aal +aal +aad +aad +aad +aad +aEK +aEK +aEK +aEK +aEK +aEK +aEK +aEK +aEK +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +acM +acM +acM +acM +acM +acM +acM +acM +acM +acM +acM +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aal +aal +aal +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +bUz +aal +aal +acO +aFq +aLG +aQG +aFK +aVo +aQG +aFK +bdE +bdT +bgm +cnB +byU +beT +bAn +byU +bBS +bBR +bBR +bBR +byU +bhh +bhW +aKN +aLi +aLP +aMm +aMX +aNK +aOG +aMm +aQl +aRe +aRe +aSl +aSP +aTA +aTW +aUC +aKN +bgE +aoX +aoX +aoX +aoX +aoX +aoX +aoX +aoX +aoX +aCH +bFs +bHQ +bhP +biI +bjr +alM +bkf +bkn +bjt +bjt +bjt +bls +bjY +bkC +blC +bmP +bnG +bpl +bqp +brU +brW +blC +bdd +bhP +bFs +bHZ +bIi +bNC +bJC +bMp +bNC +bPc +bNC +bIi +cjY +bHZ +bUJ +bVP +cbL +cfq +cfq +cfq +cfq +cgj +cgq +bUJ +cnH +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +aGl +acQ +acQ +acQ +acQ +acQ +cno +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(67,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aal +aal +aal +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +acM +acM +acM +acM +acM +acM +acM +acM +acM +acM +acM +acM +acM +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +cnB +byU +sgh +bAn +beT +bBR +bBR +bBR +bBR +byU +bhh +bhW +aKN +aLj +aLQ +aMn +aMn +aMn +aMn +aMn +aMn +aRf +aRK +aSm +aSQ +aSR +aTX +aUD +aKN +bgE +aoX +aoX +aoX +aUM +aoX +aoX +aoX +aoX +aoX +aCH +bFs +bHQ +bhP +biJ +bjs +aBk +bkg +bjt +bjt +bjt +bjt +bjt +bmC +bdd +bdd +bnF +bdd +bpn +bqK +bdd +brX +bdd +bdd +bhP +bFs +bHZ +bIi +cgH +cgI +bMq +bGY +bPl +bQZ +bIi +cjY +bHZ +bUJ +bVQ +cfg +cfr +cfr +cfr +cfr +cgk +cgr +bUJ +cnH +bdS +coU +aFK +aVo +aQG +aUm +aVo +aGl +cpE +chF +chR +acQ +acQ +chR +cil +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(68,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +acM +acM +adh +adB +adk +aem +adk +adk +afA +adB +adi +acM +acM +acM +aiG +aiG +aiG +aiG +aiG +aiG +aiG +aiG +aiG +aiG +alB +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aFq +aGl +aQG +aUm +aVo +aQG +aFK +bdE +bdS +bgm +cnB +byU +bzI +bAn +byU +cjV +bBR +bBR +bEu +byU +bhh +bhW +aKN +aLk +aLR +aoW +aoW +aoW +aoW +aoW +aoW +aRg +aRL +aSn +aSR +aTD +aTY +aUE +aKN +bgE +aoX +aoX +aoX +aoX +aoX +aoX +aoX +cgF +aoX +aCH +bFs +bHQ +bhP +biK +bjs +aEE +bkg +bjt +bjt +bjt +bln +blv +bhO +bmD +bmD +bmD +bob +bmD +bmD +bob +bmD +bmD +bmD +bhP +bFs +bHZ +bIi +bJE +bLd +bMq +bGY +bPd +bRa +bIi +cjY +bHZ +bUJ +bVR +cfh +cfs +cft +cfV +cft +cft +cgs +bUJ +cnH +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpE +chG +chS +acQ +acQ +chU +cim +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(69,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +acM +acM +adi +adk +adi +adi +aeD +adk +adk +adk +adi +adi +acM +acM +aiG +aiG +aiG +aiG +aiG +aiG +aiG +aiG +aiG +aiG +alB +alB +alB +alB +alB +alB +adx +adx +adx +adH +adH +adH +adH +adH +adH +adH +adH +adH +aal +aal +aal +aal +acO +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +cnB +byU +beT +bAn +byU +bBS +bBR +bBR +bEv +byU +bhh +bhW +aKN +aLk +aLR +aoW +aMY +aNL +aOH +aMY +aoW +aRh +aRM +aSn +aSS +aTE +aTZ +aUD +aKN +bgE +aoX +aoX +aoX +aoX +aoX +aoX +aoX +aoX +aoX +aCH +bFs +bHQ +bhP +biL +bjt +bjt +bjt +bjt +bjt +bjt +blo +blw +bhP +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bhP +bFs +bHZ +bIi +bJF +bLe +bMr +bND +bPe +bRb +bIi +cjY +bHZ +bUJ +bVS +cfh +cft +cft +cft +cft +cft +cgt +cgy +cnH +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpE +chH +chT +acQ +acQ +chT +cin +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(70,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aal +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +acM +acM +adi +adk +acM +acM +aeb +adk +adk +adi +adD +adk +ahD +acM +aiH +aiH +aiH +ajI +aiH +aki +aiH +akO +aiG +aiG +alC +alH +alH +alH +alH +alH +adx +adx +adx +adH +adH +adH +adH +adH +adH +adH +adH +adH +adH +aal +aal +aal +acO +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +cnB +byU +beT +bAo +byU +bBV +bCS +bDS +bEu +byU +bhh +bhW +aKN +aLk +aLR +aMo +aMY +aMY +aMY +aPG +aQm +aRi +aRN +aSn +aST +aSQ +aST +aST +aKN +bgE +aKQ +aoX +aoX +aoX +aoX +aoX +aoX +aoX +aoX +aCH +bFs +bHQ +bhP +biM +bju +bjt +bjt +bjt +bjt +bjt +blp +blx +bhP +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bhP +bFs +bHZ +bIi +bJG +bLf +bMs +bNE +bPf +bRc +bIi +cjZ +cqc +bUJ +bVT +cfh +cft +cft +cft +cft +cft +cgt +cgz +cnH +bdS +coU +aFK +aWs +aQG +aFK +aVo +aGl +cpE +chI +acQ +bth +acQ +acQ +cno +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(71,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +byU +byU +bAm +byU +bBQ +bBQ +bDR +bBQ +byU +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +acM +acM +adj +adD +adk +adB +adk +aeb +adi +adk +adk +adk +adi +acM +aiH +ajh +aiH +aiG +ajQ +aiH +aiH +akO +aiG +aiG +alD +alX +alY +alY +alY +alH +adx +apX +aqP +adH +arX +asE +atn +arX +auZ +avH +arX +adH +adH +aal +aal +aal +acO +aFq +aGl +aQG +aFK +aVo +aZJ +aFK +bdE +bdS +bgm +cnB +byU +byU +byU +byU +byU +byU +byU +byU +byU +bhh +bhW +aKN +aLl +aLR +aoW +aMZ +aMY +aOI +aMY +aMo +aRj +aRO +aSo +aSU +aTF +aKN +aKN +aKN +bgE +aoX +aoX +aoX +aoX +aoX +aoX +aoX +aoX +aoX +aCH +bFs +bHQ +bhP +biN +bjv +aEF +bkh +bko +bkD +blm +blq +bly +bmD +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bhP +bFs +bHZ +bIi +bJH +bLg +bGS +bCv +bPg +bRd +bSD +cka +cqi +bUJ +bVQ +cfh +cft +cft +cft +cft +cft +cgt +cgz +cnH +bdS +coV +aFK +aVo +aQG +aFK +aVo +aGl +cpE +chF +chR +acQ +acQ +chR +cil +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(72,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +byU +beT +bAn +byU +bBR +bBR +bBR +bBR +byU +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +acM +acM +adk +adi +aeb +adi +adi +adi +aeb +adk +adk +adk +adh +acM +aiH +aiH +aiH +aiG +aiG +aiG +aiG +aiG +aiG +aiG +alD +alX +amI +amI +alY +alH +adx +apY +aqQ +aro +arX +asF +ato +arX +ava +avI +arX +adH +adH +aal +aal +aal +acO +aFq +aGl +aRT +aFK +aVo +aQG +aFK +bdE +bdS +bgl +cnB +aal +aal +aal +aal +aal +aal +aal +aal +acO +bhi +bhW +aKO +aLm +aLR +aMo +aMY +aMY +aOJ +aPH +aMo +aRk +aQp +aQp +aQp +aTG +aKN +bfn +bgB +bgF +bfj +bfj +bfj +bfj +bgH +aoX +aoX +aoX +aoX +aCH +bFs +bHQ +bhP +biT +bjw +aEF +bki +bko +blk +blm +blo +bmx +bhP +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bhP +bFs +bHZ +bIi +bJI +bCv +bMt +bNF +bPh +bRe +bTh +ckc +cqr +bUJ +bWP +cfh +cft +cft +cfW +cft +cft +cgt +cgz +cnH +bdS +coU +aUm +aVo +aQG +aFK +aVo +aGl +cpE +chJ +chU +acQ +acQ +chS +cio +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(73,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +byU +beT +bAn +byU +bBS +bBR +bBR +bBR +byU +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +acM +acM +adk +adi +acM +aen +acM +aeS +adk +aeb +agz +adk +ahE +acM +aiH +aiH +aiH +aiG +ajR +akj +akj +akj +ajR +aiG +alE +alY +alY +alY +alY +alH +adx +apZ +aqR +arp +arY +arY +atp +arX +avb +arY +arY +adH +adH +aal +aal +aal +acO +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +cnB +bWz +bWz +bWz +bWz +bWz +bWz +bWz +bWz +bWz +bWz +bhX +aKN +aLk +aLR +aoW +aMY +aMY +aMY +aMY +aoW +aRl +aQp +aQp +aQp +aTH +aKN +aTo +aTj +aVs +aVs +aVs +aVs +aVs +aTo +aLW +aLW +bei +aoX +aCH +bFs +bHQ +bhP +bjk +bjx +aEF +bki +bko +blk +blm +blo +bmy +bhP +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bkE +bhP +bFs +bHZ +bIi +bJJ +bCv +bMu +bIi +bPi +bIi +bIi +cjY +bHZ +bUJ +bYw +cfh +cft +cft +cft +cft +cft +cgt +cgA +cnH +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpE +chH +chT +acQ +acQ +chT +cin +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(74,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +byU +bzI +bAn +byU +bBT +bBR +bBR +bEu +byU +aad +aad +aal +aad +aad +aal +aad +aad +aad +aad +aac +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +acM +acM +adi +adi +acM +acM +acM +aeT +adk +acM +agA +adk +adk +acM +aiI +aiH +ajy +aiG +ajS +ajS +ajS +ajS +ajS +aiG +alF +alY +alY +alY +alY +aoB +adx +aqa +aqa +arp +arY +arY +arX +arX +arX +avJ +arY +adH +adH +aal +aal +aal +acO +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +cnB +bWz +bwV +bWz +btt +bsp +bWz +bDp +boM +bGi +bWz +bhX +aKN +aLk +aLR +aoW +aoW +aoW +aOK +aoW +aoW +aRm +aQp +aQp +aQp +aLk +aKN +aTo +aTj +aVs +aHH +aHH +aHH +aVs +bgJ +bgK +bcN +bej +aoX +aCH +bFs +bHQ +bhP +bjl +bjv +aEF +bkj +bko +bll +blm +blr +bmz +bil +bmD +bmD +bmD +bnW +bmD +bmD +bnW +bmD +bmD +bmD +bhP +bFs +bHZ +bIi +bJK +bLh +bMv +bIi +bpP +bpP +bSF +cki +bHZ +bUJ +bZR +cfi +cft +cft +cft +cft +cft +cgt +bUJ +cnH +bdS +coU +aFK +aVo +aQG +aUY +aVo +ckP +cpE +chK +bdI +bdI +bdI +bdI +cip +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(75,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +byU +beT +bAn +byU +bBS +bBR +bBR +bEv +byU +aad +aad +aad +aal +aad +aad +aad +aal +aad +aad +aac +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +acM +acM +adm +adE +aec +acM +aeE +aeU +afA +acM +agA +adF +aep +aif +aiJ +aji +ajz +ajJ +aiH +ajh +aky +ajh +aiH +ajJ +alG +alY +alY +alY +alY +alH +apk +aqa +aqa +arq +arX +arX +arX +aun +arX +avK +awK +adH +adH +aal +aal +aal +acO +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +cnB +bWz +bjq +cyK +aEQ +aEQ +brI +bDp +bDp +bGi +bWz +bhX +aKN +aLk +aLR +aMp +aMp +aNM +aOL +aNM +aQn +aQp +aQp +aSp +aSV +aTI +aKN +aTo +aTj +aVs +aHH +aHH +aHH +aVs +aVv +bhd +aMb +aVv +aVv +aVv +bFs +bHQ +bhP +bjm +bjy +bjt +bjt +bjt +bjt +bjt +bjt +bjt +bmC +bdd +bdd +bdd +bdd +bdd +bdd +bdd +bdd +bdd +bdd +bhP +bFs +bHZ +bIi +bJL +bDM +bMw +bIi +bPj +bpP +bSF +ckj +cjn +bVO +bZS +cfh +cft +cft +cft +cft +cft +cgu +bUJ +cnH +cot +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +aal +aal +aal +aal +aal +aal +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(76,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +byU +beT +bAn +byU +bBR +bBR +bBR +bBR +byU +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +acM +acM +adi +adF +aed +acM +acM +aeV +adk +acM +agA +ahh +adk +acM +aiH +aiH +aiH +aiG +ajS +ajS +ajS +ajS +ajS +aiG +alF +alY +alY +alY +alY +aoB +adx +aqb +aqa +arr +arZ +arZ +atq +auo +atq +avL +awL +adH +adH +aal +aal +aal +acO +aFq +aLG +aQG +aFK +aVo +aQG +aFK +bdE +bdT +bgm +cnB +bWz +bwW +bWz +aER +buL +bWz +bDp +bDp +bGj +bWz +bhX +aKN +aLn +aLS +aMq +aNa +aNM +aOM +aNM +aQo +aRn +aMn +aSq +aSW +aTJ +aKN +aTo +aTj +aVs +aVG +aVG +aVG +aVs +aZK +bhM +aYe +bek +bfB +aVv +bFs +bHQ +bil +biH +biH +aGm +bkk +bkk +bkk +bkk +bkk +biH +bjY +bdd +bdd +bdd +oWb +bdd +bdd +oWb +bdd +bdd +bdd +bhP +bFs +bHZ +bIi +bIi +bIi +bIi +bIi +bIi +bIi +cnS +cjY +bHZ +bUJ +bZT +cfh +cfu +cft +cft +cgb +cft +cgs +bUJ +cnH +bdS +coU +aFK +cpq +aQG +aFK +aVo +aGl +cpF +aal +aal +aal +aal +aal +aal +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(77,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +byU +wlG +bAn +byU +bBV +bBR +bBR +bEw +byU +aad +aal +aad +aad +aad +aal +aad +aad +aad +aad +aac +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +acM +acM +adk +adG +acM +aeo +acM +aeW +adk +aeb +agB +ahh +ahE +acM +aiH +aiH +aiH +aiG +ajR +akj +akj +akj +ajR +aiG +alH +alY +alY +alY +alY +alH +adx +aqc +aqR +aru +arY +asG +atr +aup +avc +arY +arY +adH +adH +aal +aal +aal +acO +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +bWz +bWz +bWz +bWz +bWz +bWz +bWz +bDp +bWz +bWz +bWz +bhX +aKN +aKN +aKN +aKN +aNb +aNN +aON +aPI +aQp +aLk +aKN +aKN +aKN +aKN +aKN +aTo +aTj +aVs +aVH +aVX +aVX +aVs +aZL +aYd +aYd +bel +bfC +aVv +bFs +coJ +bNb +bNb +bNb +bFu +bNb +bNb +bNb +bNb +bNb +bTi +bil +biH +biH +biH +biH +bpm +bpm +biH +biH +biH +biH +bjY +bFs +bFu +bNb +bNb +bNb +bNb +bNb +bNb +bNb +bNb +cki +bHZ +bUJ +bZU +cfj +cfv +cfF +cfv +cgc +cfv +cgv +bUJ +cnH +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +aal +aal +aal +aal +aal +aal +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(78,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +byU +beT +bAn +byU +bBV +bBR +bBR +bEv +byU +aal +aad +aad +aad +aad +aal +aal +aal +aal +aal +aac +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +acM +acM +adk +adI +aee +aep +aep +aeX +aee +afY +afY +ahi +adh +acM +aiH +aiH +aiH +aiG +aiG +aiG +aiG +aiG +aiG +aiG +alH +alY +amI +amI +alY +alH +adx +aqd +aqd +arv +arX +asH +ats +aup +avd +avM +arX +adH +adH +aal +aal +aal +acO +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +bWz +bDp +bDp +bWz +btu +brJ +bWz +bDp +bEt +bnD +bWz +bhh +bia +aws +aws +aKN +aNc +aNO +aMq +aMq +aQq +aRo +aRP +aZU +bfj +bfj +bfj +bfo +aUZ +aVs +aVI +aVY +aWN +aVs +aZM +aYd +aYd +bem +bfC +aVv +bFs +coJ +bNt +bNt +bNt +bNt +bNt +bNt +bNt +bNt +bNt +bNt +bTj +bTJ +bTJ +bTJ +bTJ +bNt +bNt +bTJ +bTJ +bTJ +bTJ +bTJ +bNt +bNx +bNx +bNx +bNx +bNx +bNx +bNx +bNx +bNx +cki +bHZ +bUJ +caM +bUJ +bUJ +cfL +cfX +cgd +cgl +cgw +bUJ +cnH +bdS +coU +aFK +aVo +aQG +aUm +aVo +aGl +cpF +aal +aal +aal +aal +aal +aal +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(79,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +byU +bzI +bAn +byU +bBR +bBR +bBR +bEv +byU +aad +aad +aad +aal +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +acM +acM +adn +adD +adk +adJ +adk +aeb +adi +adk +adk +adk +adi +acM +aiH +ajh +aiH +aiG +ajT +akk +aiH +akP +aiG +aiG +alH +alY +alY +alY +alY +alH +adx +aqe +aqS +adH +arX +asI +att +auq +ave +avN +arX +adH +adH +aal +aal +aal +acO +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +bWz +bDp +bDp +bwc +brJ +cjX +brJ +bDp +bDp +bGn +bWz +bhh +bij +aws +aws +aKN +aKN +aKN +aOO +aKN +aQr +aQr +aKN +aSs +aPJ +aPJ +aPJ +aPJ +aPJ +aVs +aVJ +aVZ +aVJ +aVs +aZN +aYd +aYd +aYd +bfD +aVv +bFs +bHQ +bNu +bkF +blD +bmQ +bod +bod +bod +bod +buj +bkF +bwA +aoG +byf +byV +bza +bza +bza +bza +bza +bza +bza +bNu +bNu +bGx +bGx +bGx +bGx +bGx +bGx +bGx +bGx +bON +cjY +bHZ +bLi +caN +cfk +bLi +cfM +cfo +cfo +cfo +cfo +cfA +cnH +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +aal +aal +aal +aal +aal +aal +acO +brL +cAM +cAQ +ctQ +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(80,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +byU +beT +bAn +byU +bBR +bBR +bBR +bBR +byU +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +acM +acM +adi +adk +acM +acM +aeb +adk +adk +adi +adD +adk +ahF +acM +aiH +aiH +aiH +ajI +ajV +akt +aiH +akP +aiG +aiG +alH +ama +alH +alH +ama +alH +adx +adx +adx +adH +adH +adH +adH +adH +adH +adH +adH +adH +adH +aal +aal +aal +acO +aFq +aGl +aQG +aUm +aVo +aQG +aFK +bdE +bdS +bgn +brI +bDp +bDp +bWz +brN +bDQ +buM +bDp +bDp +bqf +bWz +bhh +bij +aws +aws +aws +aws +aws +aMw +aPJ +aQs +aRp +aRQ +aSt +aSY +aTK +aUa +aUa +aVa +aVs +aVK +aWa +aWO +aVs +aZO +aYd +aYd +aYd +bfE +aVv +bFs +bHQ +bNw +bkG +blE +bmR +boe +bpo +bqL +boe +buk +bvw +bkH +bxl +byg +byW +bzJ +bAp +bBf +bBW +bCU +bDT +bEy +bxl +bxl +bGx +bIj +bJM +bLj +bIj +bIj +bPk +bGx +cjm +cki +bHZ +bLi +caO +cfl +bLi +cfO +cfH +cfI +cfN +cfo +cfB +cnH +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +aal +aal +aal +aal +aal +aal +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(81,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +byU +sgh +bAo +beT +bBR +bCS +bDS +bEx +byU +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +acM +acM +adi +adk +adi +adi +aeF +adk +adk +adk +adi +adi +acM +acM +aiG +aiG +aiG +aiG +aiG +aiG +aiG +aiG +aiG +aiG +alB +alB +amJ +amJ +alB +alB +adx +adx +adx +adH +adH +adH +adH +adH +adH +adH +adH +adH +aal +aal +aal +aal +acO +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +anG +bDp +bDp +bWz +bWz +bWz +bWz +bWz +bWz +bWz +bWz +bhh +bij +aws +aws +aws +lEK +aws +aMw +aPJ +aQt +aRq +aRR +aSu +aSZ +aTL +aUb +aUb +aVb +aVs +aVJ +aWb +aVJ +aVs +aZP +aYd +aYd +ben +bfF +aVv +bFs +bHQ +bNu +bkH +blF +bmS +bmU +bmU +bqM +bsu +bul +bvx +bkI +aVt +byh +byX +bzK +bAq +bBg +bBX +bCV +bDU +byW +aVt +bsB +bGx +bIk +bJN +bLk +bMx +bNG +bPm +bSE +cjn +ckS +cqs +bLi +caN +cfm +bLi +cfQ +cfI +cfJ +cfI +cfo +cfB +cnH +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +aal +aal +aal +aal +aal +aal +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(82,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +byU +byU +byU +byU +byU +byU +byU +byU +byU +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +acM +acM +adh +adJ +adk +aeq +adk +adk +afA +adJ +adi +acM +acM +acM +aiG +aiG +aiG +aiG +aiG +aiG +aiG +aiG +aiG +aiG +alB +anC +akm +akm +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +acO +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgo +brI +bDp +bDp +bWz +brN +btw +buM +bDp +bDp +bqg +bWz +bhh +bij +aws +aws +aws +aws +aws +aMw +aPJ +aQu +aRq +aRR +aSv +aTc +aTc +aTc +aUF +aVc +aVu +aVL +aWc +aWP +aYc +aZQ +aYd +aYd +beo +bfG +aVv +bFs +bHQ +bNu +bkI +blG +bmT +bmU +bpp +bqM +bsv +bum +bvy +bwB +aVt +byi +byY +bzL +bAr +bBh +bBY +bCW +bDV +bEz +aVt +aVt +bGy +bIl +bJO +bJO +bJO +bNH +bQW +bRf +bFs +bHZ +bLi +bLi +caP +bLi +bLi +cfR +cfH +cfK +cfN +cfo +cfB +cnH +bdS +coU +aFK +aVo +aQG +aUm +aVo +ckP +cpF +aal +aal +aal +aal +aal +aal +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(83,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +acM +acM +acM +acM +acM +acM +acM +acM +acM +acM +acM +acM +acM +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +acO +aal +aal +akm +akm +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aFq +aGl +aQG +aFK +aVo +aRT +aFK +bdE +bdS +bgl +bWz +bDp +bDp +bwc +brJ +cjX +brJ +bDp +bDp +bHx +bWz +bhh +bij +aws +aws +aws +aws +aws +aMw +aPJ +aQv +aRr +aRR +aSz +aTd +aTM +aUc +aUG +aUG +aVv +aVM +aWd +aWQ +aYd +aZR +aYd +aYd +bep +bfH +aVv +bFs +bHQ +bNu +bkJ +blH +bmU +bmU +bmU +bqN +bsw +bun +bvz +bwC +bxm +byj +byZ +bzM +bAs +bBi +bBZ +bCY +bDW +bEA +bEX +bEX +bGz +bIm +bJP +bJP +bJP +bJP +bQX +bRg +bFs +bHZ +bLi +bTZ +caQ +bLi +cfw +cfS +cfS +cge +cgm +cfo +cfC +cnH +bdS +coU +aUY +aVo +aQG +aFK +aVo +aGl +cpF +aal +aal +aal +aal +aal +aal +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(84,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +acM +acM +acM +acM +acM +acM +acM +acM +acM +acM +acM +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +acZ +acO +aal +amb +akm +akm +aal +amb +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +acO +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +bWz +bDp +bDp +bWz +btu +brJ +bWz +bDp +bEW +bHU +bWz +bhh +bij +aws +aws +lEK +aws +aMa +aMw +aPJ +aQw +aRs +aRS +aZV +aTe +aTN +aUd +aUd +aUd +aVw +aVN +aWe +aWR +aYe +aYe +aYe +aYe +aYe +bfI +aVv +bFs +bHQ +bNu +bkG +blI +bmV +bof +bpq +bqO +bsx +buo +bvA +bkF +bVr +aVt +bza +bza +bza +bBj +bCa +bCZ +bDX +bEB +aVt +aVt +bGA +bIn +bJQ +bLl +bMy +bNI +bPn +bRg +bFs +bHZ +bLi +bUa +caR +cfn +cfx +cfx +cfx +cgf +cgn +cfP +cfD +cnI +cou +coW +aFK +aVo +aQG +aFK +aVo +aGl +cpF +aal +aal +aal +aal +aal +aal +acO +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(85,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +acO +aal +aal +akm +akm +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +bWz +bWz +bWz +bWz +bWz +bWz +bWz +bDp +bWz +bWz +bWz +bhh +bik +aws +aws +aws +aws +aws +aMw +aPJ +aPJ +aPJ +aPJ +bbB +aPJ +aPJ +aPJ +aPJ +aPJ +aVv +aVv +aVv +aVv +aVv +aVv +bbw +bcO +bbw +aVv +aVv +bFs +bHQ +bNu +bkF +blJ +bmU +bmT +bpr +bqP +bsy +bup +bvB +bvB +bvB +bvB +bvB +bvB +bvB +bBk +bCb +bDa +bku +bku +bku +bFv +bGx +bGx +bGx +bGx +bGx +bNJ +bPo +bRg +bFs +bHZ +bLi +bLi +bLi +bLi +cfy +cfT +cfY +cgg +cgo +cgx +cgB +cnJ +cov +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +cxf +cxI +cyA +cxf +cxf +cxf +cxf +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(86,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +lTb +aad +aad +aad +aad +aal +aal +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +aac +afC +afC +afC +afC +afC +afC +afC +afC +afC +aal +aal +acZ +aal +aal +aal +adw +amF +ajl +akm +akm +ajl +amF +amF +amF +amF +amF +amF +asL +atu +amF +amF +amF +amF +asL +amF +amF +amF +amF +adw +aFq +aLG +aRT +aFK +aVo +aQG +aFK +bdE +bdT +bgm +cnB +bWz +bwV +bWz +btt +bsp +bWz +bDp +bDp +bGj +bWz +bhY +ckb +awo +ckb +aMr +ezS +ezS +aKT +ezS +ezS +ezS +ezS +bbM +gia +gia +gia +gia +gia +bIG +cdw +cdw +cdw +cdw +cdw +cdw +caz +cdw +cdw +cdw +coI +cvT +bNb +bkK +blK +bXz +bmT +bps +bqQ +bsz +buq +bvC +bkv +bkv +bkv +bkv +bkv +bkv +bBl +bCc +bDb +aVq +aZB +aZB +aZB +bku +bku +bku +bku +bku +bDj +bPp +bRh +bFs +bFu +bTi +bLi +caS +bLi +cfz +cfU +cfZ +cgh +cgp +cfS +cfS +cnK +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +aGl +cxg +cxJ +cxN +cxf +czu +cAa +cxf +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(87,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +afC +afZ +agC +ahj +ahG +aig +agC +agC +afC +akC +alU +akg +aBV +aCF +aCF +aQV +aCF +aCF +act +act +aCF +aCF +aCF +aCF +aCF +aCF +aCF +aCF +aCF +aCF +aCF +aCF +aCF +aCF +aCF +aCF +aCF +aCF +aCF +aHg +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +cnB +bWz +bjq +cyK +aEQ +aEQ +brI +bDp +bDp +bGi +bWz +bhY +bdO +bdO +biE +aMs +aNd +aNd +aNd +aNd +aNd +aNd +aNd +aNd +aNd +aNd +aNd +aNd +aNd +cdX +aNd +aNd +aNd +aNd +aNd +bbx +aNd +aNd +aNd +aNd +bFY +bFu +bNx +bkL +blK +bmU +bog +bog +bqS +bsA +aZB +aUh +bwD +bwE +bwE +bzb +bbR +bAt +bBm +bCd +bDc +bbR +aTt +aZB +bkv +bkv +aZB +bJR +bLm +bLm +bNK +bPq +bRi +bMZ +bFu +bHZ +bLi +bLi +bLi +bLi +bLi +bLi +bLi +bLi +bLi +bLi +cnH +bdS +coS +aFK +aWt +aQG +aFK +aVo +aGl +aGl +cxh +cxK +cxN +cxf +cxN +cyE +cxf +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(88,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +afC +aga +agD +ahk +ahH +aiK +aiL +ajB +aAd +aBg +aCh +bcm +bNA +bQV +bTF +aRJ +bTF +bTF +aCP +aCP +bTF +bTF +bTF +bTF +bTF +bTF +bTF +bTF +bTF +bTF +bTF +bTF +bTF +bTF +bTF +bTF +bTF +bTF +bTF +cuD +cuD +cvq +cvs +cvv +cvq +cvy +cvA +cvF +bgC +cnB +bWz +bwW +bWz +aER +buL +bWz +bDp +boN +bGi +bWz +bhY +bdO +bdO +ckb +aMt +aMb +aMb +aMb +aMb +aMb +aMb +aMb +aws +aws +bTt +aws +aws +aws +rEg +aVO +aWf +aWS +aYf +aVO +bby +bbA +bbA +bbA +bbA +bFZ +bHZ +bNu +bkM +bkM +bkM +boh +bpt +bqT +aVt +aTt +aUh +bwE +bxn +byk +bzc +bzN +bAu +bBn +bCe +bDd +bbR +aTt +aUh +bnJ +bGB +bIo +bJS +bGB +bnJ +bNL +bPr +bRj +bnJ +bFs +bFu +cua +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +aEY +bgn +bdS +coX +aTV +bci +aTV +aTV +cpv +aGl +cpF +cxi +cxL +cyB +cxf +cxN +cAb +cxf +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(89,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aad +aad +aad +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +afC +agb +agE +ahl +ahI +aii +aiM +ajk +afC +akE +aso +akg +aaW +bSA +bTG +cur +cur +cur +aCQ +adp +cur +cur +cur +cur +cur +cur +cur +cur +cur +cur +cur +cur +cur +cur +cur +cur +cur +cur +cur +cvg +cvh +cvr +cvt +cvw +cvx +cvt +cvB +bdS +bgm +cnB +bWz +bWz +bWz +bWz +bWz +bWz +bWz +bWz +bWz +bWz +bhh +bim +bim +aNi +ckd +aMb +aNP +aMb +aPK +aMb +aRt +aMb +aMb +aMb +aMb +aMb +aMb +aMb +rEg +aVP +aWg +aWT +aYg +aZS +bbz +bcP +beq +bfJ +bbA +bFZ +bHZ +bNu +bkM +blL +bmW +boi +bpu +bqT +aVt +aTt +aUh +bwE +bxo +hLe +bzd +bzO +bAv +bBp +bCf +bDe +bbR +aTt +aUh +bFw +bGC +bIp +bJT +bLn +bFw +bNM +bPs +bRk +kJH +bTl +akc +cub +aGl +aGl +aGl +aGl +aGl +aGl +aGl +aGl +aGl +bgn +cow +coU +aUm +aVo +aZH +aFK +bdM +aGl +cpF +cxj +cxM +cxN +cyZ +cxN +cxN +cxf +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(90,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aQS +aUs +bmv +bnw +bEY +bEY +bEY +bEY +bEY +bEY +ajv +aaE +xck +aaE +aaE +ntI +aal +aal +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aad +aad +aad +aad +afC +agc +agF +agF +ahJ +agF +ajj +akD +aAp +aBx +aCS +bdF +bOZ +azd +bTH +aDu +aDu +aDu +aEd +aDu +aDu +aDu +aDu +aDu +aDu +aDu +aDu +aDu +aDu +aDu +aDu +aDu +aDu +aDu +aDu +aFc +aDu +aDu +aDu +aHb +aFK +aFK +aFK +aWs +aQG +aFK +bdE +bdS +bgn +bmH +aZp +aZp +aZp +aZp +aZp +aZp +aZp +aZp +aZp +aZp +bhZ +bdO +bdO +ckb +ckh +aMb +aNQ +aMb +aPL +aMb +aPL +aMb +aSD +aTf +cTr +aUe +aUH +aMb +rEg +aVQ +aWh +aWU +aYh +aZT +bbA +bcQ +bcR +bfL +bhe +bFZ +bHZ +bNu +bkM +blM +bmX +boj +bpv +bqU +aVt +aTt +aUh +bwE +kaF +hLe +bzd +bzP +bAw +bBp +bCg +bDf +bbR +aTt +aUh +bFx +bGD +bIq +bJU +bLo +bFx +bNN +bPt +bRl +bSH +ctW +aGE +aGE +aGE +clc +aGE +aGE +aGE +aGE +aGE +aGE +aGE +cnL +chq +coY +aFK +aYV +aSw +aFK +aVo +aGl +cpF +cxk +cxL +cxJ +cza +czv +cxN +cxf +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(91,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +alt +aaP +alv +aYX +bbm +bnE +bJb +pYF +uOf +bEY +feR +ajw +eqs +ajw +aaP +alv +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +afC +agd +agG +ahm +afC +aij +ajm +amr +afC +akE +aso +akg +aaW +bSA +cul +aDu +adC +ajM +aCR +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +aGW +aHl +aIO +aPv +aFK +aVo +aQG +aFK +bdE +bdS +bgm +cnB +aRa +bdO +bdO +bdO +bdO +bdO +bdO +bdO +bdO +bdO +bdO +bdO +bdO +biE +aMt +aMb +aNR +aOP +aOP +aOP +aOP +aRW +aSE +aUf +aUf +aUf +aUI +beI +aTm +aVR +aWi +aWV +aYj +buS +bzZ +bFE +ber +bfM +bhe +bFZ +bHZ +bNu +bkM +blO +bmY +bok +bpw +bqT +aVt +aTt +aUh +bwD +okc +pRa +bze +bzQ +bAx +bBq +bCh +bDg +bbR +aTt +aUh +bFy +bGG +bIr +bJV +bLp +bFy +bNN +bPt +bRl +bSH +ctX +ctZ +aFK +aFK +aFK +aFK +aFK +aFK +aFK +aUm +aFK +aFK +cnM +cht +ceP +aFK +aFK +aFK +aFK +aVo +ckP +cpF +cxl +cxf +cyC +cxf +cxf +cAc +cxf +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(92,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +alt +aaP +alv +aYY +bbm +bnE +bJb +bbm +oNc +bEY +bEY +bEY +bEY +bEY +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aeY +afC +afC +afC +afC +afC +afC +ajA +azn +afC +akE +aso +akg +aaW +bSA +cul +aDu +ajt +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +aGl +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +cnB +cnB +aOi +awo +awo +awo +awo +awo +awo +awo +awo +awo +awo +awo +aLT +aMu +aNf +aNS +aOQ +aKg +aKg +aKg +aMb +aSF +aTg +aTg +aTg +aUJ +aMb +rEg +aVO +aWj +aWW +aWW +buV +bbA +bGL +bcR +bfN +bhe +bFZ +bHZ +bNu +bkN +blP +bmZ +bos +bpx +bqV +aVt +aTt +aUh +bwD +bxp +byl +bzf +bzR +bAy +bBr +bCi +bDh +bDY +aTt +aUh +bFz +bGH +bIt +bJW +bLq +bFz +bNN +bPt +bRl +bSH +ctY +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +aIO +bdR +cnN +cox +coZ +aFK +aVe +aPv +aFK +aVo +aGl +cpF +cxf +cxN +cxN +cxN +cyE +cyE +cxf +brL +cAM +cAQ +ctQ +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(93,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +alt +aaP +alv +bnB +bbm +bnE +bJb +jDv +bbm +aFS +bbm +bbm +bbm +aFS +aaP +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aeY +afD +age +age +ahn +ahK +aik +ahM +ahM +ajD +akG +atH +akU +aaW +bSA +cul +aDu +ajt +act +act +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aGl +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +cnB +cnB +aOj +aws +aws +aws +aws +aws +aws +aws +aws +aws +aws +aws +aOj +aMv +aNg +aIU +aKg +aPM +aMb +aKg +aRU +aSG +aTg +aTO +aTO +aUK +aMb +cva +bfi +bib +bnv +bnv +bvX +bbA +bcT +bes +bfO +bbA +bFZ +bHZ +bON +bkN +blQ +bna +bot +bpy +bqV +bsB +aTt +aUh +bwD +bxu +bym +bbR +bzS +bAy +bBr +bCi +bDi +bDY +aTt +aUh +bFA +bGI +bIp +bJX +bLr +bMz +bNO +bPy +bRm +bnJ +bTl +akc +cub +aGl +aGl +aGl +aGl +aGl +aGl +aGl +aGl +aGl +bgn +coy +coS +aFK +aWt +aQG +aFK +aVo +aGl +cpF +cxf +cxO +cxN +cyE +czw +cxN +cxf +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(94,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +alt +aaP +alv +aYZ +bbm +bnE +bJb +bbm +bbm +rSr +bbm +bbm +iKG +bEY +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aeY +agJ +agh +agH +ahn +ahL +ail +ahM +ajn +aeY +aaW +act +aca +act +bSA +cul +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aRT +aFK +bdE +bdS +bgl +cnB +aRa +aOj +aws +aCn +aCn +aCn +aCn +aCn +aCn +aCn +aCn +aCn +aws +aOj +aMw +aMb +aNT +aOR +aPN +aMb +aNR +aRW +aSH +aTi +aTP +aUg +aUL +aMb +rEg +aVO +aWl +aWY +aYk +aWX +bbA +bcU +bcU +bfP +bcU +bFZ +bHZ +bNu +bkN +blR +bnb +bou +bpz +bqW +aVt +aTt +bvD +bwD +bxv +bxv +bbR +bbR +bAz +bBs +bCj +bDc +bbR +aTt +bvD +bnJ +bGB +bIu +bJY +bGB +bnJ +bNL +bPr +bRj +bnJ +bFs +bFu +cuc +bff +bff +bff +aGl +aGl +bff +bff +bff +bff +bgn +bdS +coX +aVd +aTV +aTV +bci +bcr +aGl +cpF +cxl +cxP +cyD +czb +cxP +cAd +czb +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(95,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +alt +aaP +alv +bEY +bbm +bnE +bJc +bJb +bJb +bEY +bEY +bbm +bEY +bEY +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aeY +agh +agg +agI +aho +ahM +ahM +ahM +ahM +ajE +adp +adp +adp +adp +bSB +cum +aDu +ajt +act +aEq +aal +aal +amb +aal +aal +aal +aal +aal +amb +aal +aal +aal +aal +aal +amb +aal +aal +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +cnB +cnB +aOj +aws +aCn +aGA +aGA +aGA +aIL +aGA +aGA +aGA +aCn +aws +aOj +aMw +aNh +aNU +aNh +aNh +aNh +aNU +aNh +aNh +aMb +aMb +aMb +aMb +aMb +rEg +aVO +aWm +aVO +aYl +aWX +aWX +aVS +bet +bfQ +bhf +bGk +bHZ +bNu +bkN +bkN +bkN +bov +bpA +bqV +aVt +bur +aZB +bku +aZB +aZB +bku +bku +bAA +bBt +bCk +bDj +aVp +aZB +aZB +bku +bku +aZB +bJZ +bvB +bvB +bNP +bPp +bRh +cjo +bFs +bHZ +bUd +bUd +bUd +bUd +bXJ +bYt +bmu +ecw +bmu +ecw +cnO +bdS +coU +aFK +aVo +aZH +aFK +bdM +aGl +cpF +cxf +cxN +cxN +cxf +cxN +cxN +cxf +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(96,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aQT +aaP +aaP +aFS +bbm +bbm +bbm +bbm +bbm +bEY +jBv +bbm +bbm +bEY +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aeY +agH +agh +agJ +ahn +ahN +ahM +ahM +ahM +ajF +ajM +ajM +ajM +ajM +bSC +cun +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aFq +aLG +aQG +aFK +aVo +aQG +aFK +bdE +bdT +bgm +cnB +cnB +aOj +aws +aCn +aGB +aHx +aDU +aDU +aDU +aDU +aKF +aCn +aws +aOj +aLp +aNh +aNV +aOS +aOU +aQx +aRu +aRX +aNh +aws +aws +aws +aws +aws +rEg +aMa +aws +aWZ +aYm +aZW +bbC +bcV +beu +bfR +bhf +bGk +bHZ +bjZ +bjZ +bjZ +bjZ +bkU +bpB +bqX +bsC +bjZ +bvE +aZB +aZB +aZB +aZB +aZB +bAA +bBt +bCl +bDk +aZB +aZB +aZB +aZB +bvC +aVq +aVq +aVq +bkv +bpV +brs +bRo +bNu +bFs +bHZ +bUd +bUK +bVU +bWQ +dAt +dAt +bYR +bZV +caT +bmu +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +cxf +cxR +cyE +cxf +cxR +cyE +cxf +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(97,1,1) = {" +aac +bjY +bjY +bjY +bjY +bjY +bjY +bjY +bjY +bjY +bjY +alt +alv +bEY +bbm +bnH +bKz +cuv +bbm +bEY +ajZ +bbm +tRd +bEY +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aeY +afH +age +age +ahn +ahO +aim +aiN +ajo +aeY +aaW +act +act +act +bSA +cul +aDu +ajt +act +aEq +aal +aal +aal +apl +aqf +aqf +aqf +aqf +aqf +aqf +aqf +aqf +aqf +aqf +aqf +aqf +ayE +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +cnB +aRa +aOj +aws +aCn +aGA +aGA +aGA +aGA +aGA +aGA +aGA +aCn +aws +aOj +aLp +aNh +aNW +aOT +aOU +aQy +aRv +aOU +aNh +aws +aws +aws +aws +aws +rEg +aws +aws +aVO +aWf +aWS +aYf +aVO +aVO +aVO +bTk +bFZ +bHZ +bjZ +bkO +blS +bnc +bow +bpC +bqY +bsD +bjZ +bvE +bvC +bkv +bkv +bkv +bkv +bAA +bBt +bCl +bDb +aVq +aVq +aVq +aZB +aUh +bqR +bqR +bqR +bqR +bLy +bPz +bMB +bNu +bFs +bHZ +bUd +bUL +bVV +bWR +bXK +bYu +bYu +bZW +caU +cbM +cnP +cov +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +cxf +cxS +cyF +cxf +czx +cAe +cxf +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(98,1,1) = {" +aac +bjY +bjt +aat +bds +aDs +bgy +bhu +biq +aMe +bkk +alt +alv +bEY +bEY +bEY +bEY +bEY +bEY +bEY +bEY +bEY +bEY +bEY +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aeY +aeY +aeY +aeY +aeY +aeY +aeY +aeY +aeY +aeY +aaW +act +act +act +bSA +cul +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aUY +bdE +bdS +bgm +cnB +cnB +aOj +aws +aCn +aCn +aHy +aGA +aGA +aJA +aHy +aCn +aCn +aws +aOj +aLp +aNh +aOa +aOU +aOU +aOa +aNh +aRY +aNh +aws +aws +aws +aws +aws +hya +nZW +nZW +nZW +nZW +nZW +nZW +nZW +bev +bfS +aOj +bFZ +bHZ +bjZ +bkP +blT +bnd +box +bpD +bqZ +bsE +bjZ +bvE +aUh +bdq +bdq +bdq +bdq +bAB +bBu +bCm +bDl +bdq +bdq +bdq +aTt +aUh +bIv +bKa +bLs +bqR +bNQ +bPA +bRp +bNu +bFs +bHZ +bUd +bUM +bVW +dAt +dAt +bYv +bYS +bZX +caV +cbN +cnQ +coz +coW +aFK +aVo +aZJ +aFK +aVo +aGl +cpF +cxf +cxf +cxf +cxf +cxf +cxf +cxf +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(99,1,1) = {" +aac +bjY +bjt +aau +aDi +beR +bir +bir +bir +bir +bkk +alt +aaP +aaE +btv +btv +btv +btv +btv +btv +btv +btv +btv +btv +aaP +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aaR +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +act +act +act +act +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aQG +aUm +aVo +aQG +aFK +bdE +bdS +bgm +cnB +cnB +aOj +aws +aCn +aGC +aHz +aIg +aIM +aJB +aKm +aKG +aCn +aws +aOj +aLp +aNh +aNY +aOU +aOU +aOa +aNh +aMv +ezS +nZW +nZW +nZW +nZW +nZW +bbM +mwL +aKT +pqA +pqA +pqA +pqA +pqA +bex +bfS +aOj +bFZ +bHZ +bjZ +bjZ +bjZ +bjZ +boy +bpE +cax +bsF +bus +aTt +aUh +bdq +byn +bzg +bdy +bAC +bBv +bCn +bDm +bDZ +bEC +bdq +aTt +aUh +bIw +bKb +bLt +bMA +bNR +bPC +bRq +bNu +bFs +bHZ +bUd +bUN +bVU +bWS +bXL +cga +bYT +bZY +caW +cbO +cnR +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +aal +aal +aal +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(100,1,1) = {" +aac +bjY +baE +bbY +baG +bjt +bjt +bjt +bjt +bjt +aQW +aaP +aaP +alv +bqj +bqj +boQ +boQ +boQ +boQ +boQ +boQ +bqj +bqj +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aaW +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +cnB +aRa +aOj +aws +aCn +aGD +aHA +aIh +aIN +aJC +aKn +aGD +aCn +aws +aOj +aLp +aNh +aNZ +aOU +aOU +aOa +aRw +aMv +aKT +aKT +aLX +aLX +aLX +aLX +aLX +slt +aLv +aXa +aXa +aZX +bbD +aXa +aZX +bbD +aXa +bFZ +bHZ +bjZ +bkO +blS +bnc +bow +bpF +brb +bsG +bus +aTt +aUh +bdq +byx +bzh +bzT +bAD +bBw +bCo +bDn +bzh +bED +bdq +aTt +aUh +bIx +bKc +bLv +bMB +bNS +bPD +bRr +bNu +bFs +bHZ +bUd +bUd +bUd +bUd +bUd +ecw +bYU +bmu +ecw +bmu +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +cna +cna +cna +cna +cna +cna +cna +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(101,1,1) = {" +aac +bjY +baF +bjt +aDi +beU +bit +bit +bit +aML +bkk +alt +aaP +alv +bqj +bxU +bLN +esO +vyi +hTY +gpj +hTY +hzc +bqj +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aaW +acW +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +aCQ +aCU +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +cnB +cnB +aOj +aws +aCn +aGG +aHB +aHB +aIP +aHB +aHB +aKH +aCn +aws +aOj +aLp +aNh +aOa +aOU +aPO +aQz +aRx +aMv +aKT +aLv +aMa +aws +aws +aws +aws +hya +aLv +aXb +aYn +aZY +bbE +bcW +bbE +bfT +aXa +bFZ +bHZ +bjZ +bkP +blT +bne +box +bpD +bqZ +bsH +bus +aTt +aUh +bdq +bdq +bdq +bdq +bAG +bBv +bCp +bDq +bdq +bdq +bdq +aTt +aUh +bIy +bKd +bLw +bMB +bNT +bPE +bRs +bON +bFs +bFu +cqw +cqw +cqw +cqw +cqO +bUd +acJ +bZZ +acJ +cbP +bgn +bdS +coU +aUY +aVo +aQG +aFK +aVo +aGl +cpF +cna +cxZ +cyI +cna +czA +coR +cAA +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(102,1,1) = {" +aac +bjY +baG +bjt +bdt +aDv +biu +bhx +biu +aMM +bkk +alt +aaP +alv +boQ +bxS +bLO +qXY +aam +dra +aaA +aaz +wxl +bqj +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aaW +adg +adC +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +aCR +aDf +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +oIz +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +beA +bgG +aCl +aCl +aDS +aEz +aCo +aDT +aDT +aIi +aIQ +aIi +aDT +aDT +aKP +aws +aOj +aLp +aNh +aOb +aOV +aPP +aQA +aNh +aMv +aKT +aLv +aws +aws +aws +vIN +aws +hya +aLv +aXc +aYo +aZZ +bbF +bcX +beG +bfU +aXa +bFZ +bHZ +bjZ +bjZ +bjZ +bnf +boz +bpG +brc +bsI +bus +aTt +aUh +bdq +byy +bzi +bdy +bAH +bBx +bCq +bDm +bEa +bEC +bdq +aTt +aZB +bIz +bKe +bLx +bMC +bLx +bPF +bRt +bNu +bFs +bHZ +bUf +bUf +bUf +bUf +cqP +ecw +bYV +bZZ +acJ +cbP +bgn +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +cna +cya +cyJ +cna +czB +coR +cAB +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(103,1,1) = {" +aac +bjY +bjY +bjY +bjY +bkk +bkk +bkk +bkk +bkk +bkk +alt +aVF +alv +boQ +bxS +bLP +wWV +aaz +gAS +ako +aaz +hzc +bqj +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +abZ +adg +ajt +ajN +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +aka +akf +akf +akH +akH +akf +act +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aUm +bdE +bdS +bgl +cnB +aRa +aOj +aws +aCn +aCn +aCn +aCn +aIR +aCn +aCn +aCn +aCn +aws +aOj +aLp +aNh +aNh +aOW +aNh +aNh +aRy +aMv +aKT +aLv +aws +aws +lEK +aws +aws +hya +aLv +aXd +aYp +baa +bbG +bbG +baa +bfV +aXa +bFZ +bHZ +bjZ +bkQ +blU +bng +boA +bpH +bra +bsJ +bus +aTt +aUh +bdq +byx +bzh +bzT +bAI +bBy +bCr +bDn +bzh +bED +bdq +aTt +aUh +bqR +bqR +bLy +bMB +bNU +bPz +bMB +bqR +bFs +bHZ +bUf +bUO +bVX +bUf +cqP +bUd +ecw +bUd +ecw +nxe +cnO +bdS +coU +aFK +aVo +aQG +aFK +cpq +aGl +cpF +cna +cna +cyK +cna +czC +coR +cAC +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(104,1,1) = {" +aac +aad +baH +aju +aju +aju +aju +aju +aju +aju +aju +aaP +aaP +alv +boQ +cpD +bNc +sRS +tTL +tTL +bNc +ilI +aaC +bqj +fxy +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aba +acj +acj +bGo +aba +aba +aeG +aeZ +afI +agi +aeG +aeZ +afI +agi +aeG +aeZ +afI +agi +aeG +akg +akg +akE +aso +akU +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +atv +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +cnB +cnB +aOj +aws +aws +aws +aws +aCn +aIS +aCn +aws +aws +aws +aws +aOj +aMx +aNi +aKI +aKI +aKI +aKI +nZW +aLX +aLX +aLv +aws +aws +aws +aws +aws +hya +aLv +aXa +aYq +baa +baa +baa +baa +bfW +aXa +bFZ +bHZ +bjZ +bkR +bWG +bnh +boB +bpI +bqZ +bsK +bus +aTt +aUh +bdq +bdq +bdq +bzU +bAK +bBv +bCs +bDl +bdq +bdq +bdq +aTt +aUh +bqR +bKi +bLz +bMD +bNV +bPG +bRu +bqR +bFs +bHZ +bUf +bUP +bVY +bUf +cqQ +cqw +cqw +cqw +cqw +cqw +cnT +coA +coU +aFK +aVo +aQG +aFK +aVo +cpy +cpF +cxy +bDp +bDp +cna +cna +bDp +cAD +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(105,1,1) = {" +aac +aad +ajw +ajw +ajw +ajw +ajw +ajw +ajw +ajw +ajw +aaP +aaP +alv +boQ +cpD +bOJ +bOJ +bOJ +bOJ +vPw +grV +hki +boQ +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +acP +aqf +aqf +aqf +aqf +aqf +aqf +aqf +aqf +aqf +aqf +aqf +bQh +aba +alT +alT +aba +alT +alT +aeG +adL +adM +adM +aeH +afa +afa +afa +agK +afa +afa +ain +aeG +akg +akg +akE +aso +akg +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aRT +aFK +aVo +aQG +aFK +bdE +bdS +bgl +aCm +aCn +aCn +aCn +aCn +aCn +aCn +aCn +aIT +aCn +aCm +awo +awo +awo +aLU +aLU +aLU +aLU +aLU +aLU +aLU +aRz +aRZ +aLU +aLp +aws +aws +aws +aws +bTt +bhl +bjf +buh +aYr +baa +baa +baa +baa +bfX +aXa +bFZ +bHZ +bjZ +bkS +blU +bnk +aZI +bpE +brb +bsL +bjZ +bvE +aUh +bxw +byz +bzj +bzV +bAL +bBv +bCt +bDr +bEb +bEE +bxw +aTt +aUh +bIA +bKj +bLA +bME +bNW +cea +bRv +bqR +bFs +bHZ +bUf +bUQ +bVZ +bUf +bUf +bUf +bYW +bUf +bUf +bUf +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +aGl +cxz +bDp +bDp +bDp +bDp +bDp +cna +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(106,1,1) = {" +aac +aad +bjg +bjg +bjg +bjg +bjg +bjg +bjg +bjg +bjg +alt +aaP +alv +bqj +bwb +bNe +bNf +jqv +tXg +jdY +xbi +dkq +boQ +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aba +ack +alT +aba +ack +alT +adq +adM +adM +adM +aeG +afb +afK +afK +afK +afa +ahP +afa +aiO +akg +akg +akE +aso +akg +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aLG +aQG +aFK +aVo +aQG +aFK +bdE +bdT +bgm +aCn +aCW +aDT +aDT +aFk +aGH +aDT +aIj +aIQ +aJD +aCn +aws +aws +aws +aLU +aMy +aNj +aNj +aOX +aPQ +aQB +aQH +aSa +aLU +aLp +aws +aws +aws +aws +aws +hya +aLv +aXa +aYs +baa +bbH +bcY +bcY +bfY +bhg +bGp +bHZ +bjZ +bkT +blU +blU +aZI +bpE +brb +bsM +bjZ +bvG +aUh +bxx +byG +bdy +bdy +bAM +bBy +bCu +bDs +bEc +bEF +bxx +aTt +aZB +bIB +bKk +bLB +cdZ +bNY +bPI +bRx +bqR +bFs +bHZ +bUf +bUR +bUS +bWT +mRs +bXO +bWT +ejZ +caa +bUf +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +cxy +bDo +bDp +czf +czD +cAj +cna +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(107,1,1) = {" +aac +aad +bjg +bcb +aDj +beW +beW +aFM +beW +beW +bjg +alt +aaP +aaP +bcv +bOJ +bNf +bOJ +bOJ +qzA +vPw +iIf +ukq +boQ +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aqg +ace +ace +acL +acL +acL +acL +acL +acL +acL +awM +aba +alT +alT +aba +alT +alT +aeG +adN +adM +adM +aeG +afc +afK +agj +afK +ahp +ahQ +aio +aiP +akg +akg +akE +aso +akg +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aal +anB +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +azm +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +aCn +aCX +aDU +aDV +aFl +aGI +aHB +aHB +aIV +aCY +aGR +aKI +aKI +aLo +aLU +aMz +aNk +aNk +aLU +aLU +aQC +aRA +aSb +aLU +aLp +aTQ +aTQ +aTQ +aTQ +aTQ +hya +aLv +aXb +aYr +baa +bbI +aKe +aKe +bfZ +aXa +bFZ +bHZ +bjZ +bkU +aZI +bnl +boC +bpJ +brd +bsN +bjZ +bvE +aUh +bxy +byH +bdy +bdy +bAL +bBv +bCw +bDt +bEd +bEG +bxy +aTt +aZB +bIC +bKl +bLC +bMG +bNZ +bPJ +bRy +bqR +bFs +bHZ +bUf +bUS +bWa +bWT +bWT +bWT +bWT +bWT +bWT +cbQ +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +cna +cna +cna +cna +cna +cna +cna +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(108,1,1) = {" +aac +aad +bjg +aav +aDk +beW +aEb +aFO +aIB +beW +bhI +aaP +aaP +aaP +bcz +bOJ +bOz +yez +bOJ +wlp +bOJ +ilI +eKm +bqj +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaG +acf +acf +aaS +acf +acf +acf +acf +aaS +acf +aba +alT +alT +aba +alT +alT +aeG +adP +adM +aes +aeG +afd +afK +afK +afK +afa +ahR +afa +aiQ +akg +akg +akE +aso +akg +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aoC +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +aCn +aCY +aDV +aEB +aFm +aGJ +aDV +aDV +aIX +aCY +aKo +aws +aMa +aLp +aLU +aMz +aNk +aNk +aOY +aPR +aQD +aQD +aSc +aLU +aLp +aTQ +aUi +aUN +aUi +aTQ +hya +aLv +aXc +aYt +baa +bbI +aKe +aKe +bga +aXa +bFZ +bHZ +bjZ +bkV +blV +bnm +bjZ +bpK +bre +bsO +bjZ +bvE +bvD +bxz +byI +bzk +bzW +bAN +bBz +bCx +bDu +bEe +byI +bEZ +aTt +bvD +bqR +bqR +bqR +bqR +bLy +bPK +bRz +bqR +bFs +bHZ +bUf +bUT +bWb +bWT +bXP +bXP +bWT +caa +caa +cbR +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +aGl +cpN +cpN +cpU +cpU +cpN +cpW +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(109,1,1) = {" +aac +aad +bjg +aax +aDl +beW +aEf +aFO +aIC +beW +bjg +alt +aaP +aaP +bcv +bOJ +ikY +bOJ +bOJ +shm +vPw +nWq +rvH +boQ +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaH +aal +aal +aal +aal +aal +aal +aal +aal +aal +aba +ack +alT +aba +ack +alT +aeG +adQ +aeg +aet +aeG +afe +afL +agk +agL +ahq +ahS +aip +aeG +akg +akg +akE +aso +akg +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aUY +bdE +bdS +bgm +aCn +aCZ +aCn +aCn +aCn +aCn +aHC +aDV +aIX +aCY +aKp +aws +aws +aLp +aLU +aMA +aNl +aNk +aOZ +aPS +aQE +aRB +aSd +aLU +aLp +aTQ +aUj +aUO +aVg +aTQ +hya +aLv +aXd +aYu +bab +bbJ +bcZ +bcZ +bgb +aXa +bFZ +bHZ +bjZ +bkW +aZI +bmh +bjZ +bpL +brf +bsP +bjZ +bvE +aZB +bku +bku +bku +bku +bAA +bBt +bCl +bDv +bEf +bEH +bku +aZB +aZB +bku +bku +bku +bMH +bOa +bPL +bRA +bqR +bFs +bHZ +bUf +bUU +bWc +bWU +bWU +bWU +bYX +bWT +bWT +cbR +cnU +bdS +coU +aUm +aVo +aQG +aFK +aVo +aGl +aGl +cpO +cpO +aFK +aFK +cpO +cpX +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(110,1,1) = {" +aac +aad +bjg +aay +aDm +beW +aEg +aFP +aJp +beW +bjg +alt +aaP +alv +bqj +bwb +bOB +ikY +tXg +bOB +jdY +fBZ +pbB +boQ +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaI +aal +aaL +aaL +aaL +aaL +aaL +aaL +aaL +aaL +aaL +alT +alT +aba +aEr +aEr +aeG +aeG +aeG +aeG +aeG +aeG +afM +agl +agM +aeG +aeG +aeG +aeG +akg +akg +akE +aso +akg +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +avP +aal +aal +aal +aal +aal +aal +aFq +aGl +aQG +aUm +aVo +aQG +aFK +bdE +bdS +bgm +aCn +aCY +aDV +aDV +aFn +aGK +aDV +aDV +aIX +aCY +aKp +aws +aws +aLp +aLU +aMz +aNm +aNk +aPa +aPT +aQD +aQD +aSe +aLU +aLp +aTQ +aUk +aUP +aVh +aTQ +hya +aLv +aXa +aXa +aXa +aXa +aXa +aXa +aXa +aXa +bFZ +bHZ +bjZ +bkU +blW +bmi +boD +bpM +brg +bsQ +bjZ +bvE +aZB +bkv +bkv +bkv +bkv +bAO +bBA +bCy +bDx +bEg +bEI +bkv +bkv +bkv +bkv +bkv +aZB +aUh +bOa +bPM +bRA +bIA +bFs +bHZ +bUf +bUV +bUS +bWT +bXP +bXP +bYY +cab +caX +cbS +cnO +bdS +coU +aFK +aVo +aZJ +aFK +aVo +aGl +ckP +cpP +cpO +aFK +aFK +cpO +cpY +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(111,1,1) = {" +aac +aad +bjg +bjg +bjg +bhI +bjg +bjg +bjg +bjg +bjg +alt +aVF +alv +boQ +cpD +bOJ +bOJ +bOJ +bOJ +vPw +pXv +fRf +boQ +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aad +aad +aad +apm +aqg +aaF +aaI +aal +aaL +aaT +aaY +abp +abh +abE +aaY +abR +aaL +alT +alT +alT +alT +alT +alT +alT +alT +cxb +aba +aff +afN +agm +agN +agm +ahT +agm +aiR +akg +akg +akE +aso +akg +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +aCn +aCX +aDU +aDV +aFo +aGI +aHB +aHB +aIV +aCY +aKq +aws +aws +aLq +aLV +aMB +aNk +aNk +aLU +aLU +aQF +aVx +aSf +aLU +bbN +bbO +bcS +aUQ +aVi +aTQ +hya +aKT +nZW +nZW +nZW +nZW +nZW +nZW +bgc +bEr +bGk +bHZ +bjZ +bkY +blX +bjZ +bjZ +bpK +brh +bsR +bjZ +bvE +aUh +bxA +bvO +bzl +bzl +but +bBB +bCz +bDy +bEh +bfm +bFa +bbc +bbc +bbc +bbc +aTt +aUh +bOb +bPN +bRA +bIA +bFs +bHZ +bUf +bUW +bWd +bWV +bXQ +bXQ +bYZ +bXQ +bXQ +cbT +cnV +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +aGl +cpO +cpO +aFK +aFK +cpO +cpY +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(112,1,1) = {" +aac +aad +bjg +bcc +bdv +beX +bgz +bhG +bix +bjh +bjh +aak +aaP +alv +boQ +bwU +bTr +nzc +nzc +nzc +bTr +kda +vBV +bqj +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaI +aal +aaL +aaU +abh +abq +abh +abq +abh +aaU +aaL +ack +alT +alT +alT +alT +alT +alT +alT +aeu +aba +afg +afO +afO +afO +afO +afO +aiq +aiR +akg +akg +akE +aso +akg +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +nSS +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +aCn +aCY +aDV +aEB +aFp +aGJ +aDV +aDV +aIX +aJE +aCn +aws +aws +aLr +aLU +aMC +aNj +aNj +aPb +aPU +aQH +bIF +aSg +aLU +aTl +aTQ +bdb +aUR +aVj +aTQ +bhl +bjf +tHL +tHL +tHL +tHL +mwL +pqA +bgd +bEM +bGk +bHZ +bka +bkZ +blY +bnn +boE +bpN +bri +bsS +bku +aZB +aUh +bfm +byJ +bdA +bdA +bdA +bBC +bCA +bDz +bEi +bEJ +cdP +bFB +bGJ +bID +bbc +aTt +aUh +bLy +bPO +bRB +bIA +bFs +bHZ +bUf +bUX +bUS +bWW +bUS +bUS +bZa +bUf +bUf +bUf +cnO +bdS +coU +aFK +aVo +aQG +aFK +aYV +aHk +aSw +aFK +aFK +aFK +aFK +cpO +cpY +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(113,1,1) = {" +aac +aad +bjg +bcd +beX +beX +beX +bjg +alt +aaP +aaP +aaP +aaP +alv +boQ +bxS +bTs +jdD +nsX +nsX +bTs +bTs +hzc +bqj +alt +alv +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaI +aal +aaL +aaV +abh +aaU +abw +aaU +abh +abS +aaL +alT +alT +alT +alT +alT +alT +alT +alT +cxb +aba +afh +afp +afp +agO +afp +afp +afp +aiR +akg +akg +akE +aso +akg +aaW +act +adg +aDu +ajt +act +aEq +anj +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +aCn +aCZ +aCn +aCn +aCn +aGL +aDV +aDV +aIX +aCY +aKo +aws +aws +aLr +aLU +aLU +aLU +aLU +aLU +aLU +aLU +bGM +aRZ +aLU +aTl +aTQ +aUn +aUS +aVk +aTQ +hya +aLv +aws +aXf +aXf +aXf +bda +aXf +aXf +aXf +bFZ +bHZ +bka +bla +blZ +bno +boF +bpO +brj +bsT +bkv +bkv +bwF +bfm +byM +bzm +cdL +bAP +btc +bCB +bDz +bEi +bEK +cdQ +bFC +bGK +bGK +bbc +aTt +aUh +bLy +bPz +bRC +bqR +bFs +bHZ +bUf +bUY +bWe +bWX +bXR +bXR +bZb +bUf +cnx +cnB +cnO +bdS +coU +aFK +aVo +aQG +aUY +aVe +aHl +aPv +cpO +cpO +aFK +aFK +cpO +cpZ +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(114,1,1) = {" +aac +aad +bjg +bce +beX +beX +beX +bhI +aaP +aaP +aaP +aaP +aaP +alv +boQ +bxS +bxV +bxV +bxV +dnQ +bty +bxV +wxl +bqj +alt +alv +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaI +acZ +aaL +aaX +abh +abh +abx +abh +abh +abT +aaL +alT +alT +alT +alT +acX +adr +adR +aeh +aev +aba +afh +afp +afp +afp +afp +afp +afp +aiS +akg +akg +akT +akm +aBz +aCi +act +adg +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +apn +mGF +aEY +aEY +aEY +aEY +aEY +aEY +aGl +aGl +aQG +aFK +aVo +aZJ +aFK +bdE +bdS +bgl +aCn +aCY +aDV +aDV +aFu +aGM +aDV +aDV +aIX +aCY +aKp +aws +aws +aLs +ezS +ezS +ezS +nZW +nZW +nZW +nZW +slt +nZW +nZW +aTm +aTQ +aTQ +aTQ +aTQ +aTQ +hya +aLv +aMa +aXf +bac +bbK +bGX +beH +bge +aXf +bFZ +bHZ +bka +blb +bma +bka +aTt +bpQ +brk +bsU +but +buz +bfm +bxB +byN +bzn +bzX +bzn +btc +bCC +bDz +bEj +bEL +cdR +cdT +cdV +cvb +bbc +aTt +aZB +bDj +bri +bRD +bxL +bFs +bHZ +bUf +bUZ +bUS +bWX +bXR +bYx +bZc +bUf +cny +cnC +bgn +bdS +coU +aFK +aVo +aZH +aFK +bdM +aGl +aGl +xkz +cpO +aFK +aFK +cpO +cpY +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(115,1,1) = {" +aac +aad +bjg +bcf +beX +aDx +bgA +bjg +alt +aaP +aaP +aaP +aaP +alv +bqj +bxU +bxV +bty +bxV +voP +bxV +bxV +hzc +bqj +alt +alv +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaI +aal +aaL +aaY +abh +aaU +aaU +aaU +abh +aaY +aaL +aaM +acq +acq +acN +acq +acq +acq +acq +acq +acq +afi +afl +agn +agP +ahr +ahU +afl +aiT +akg +akg +akg +atI +akm +aCi +act +adg +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +avO +aEZ +aEZ +aEZ +aEZ +aEZ +aEZ +aEZ +aGl +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +aCn +aCX +aDU +aDV +aFv +aGI +aHB +aHB +aIV +aCY +aKp +bTt +aws +aLs +aLX +aLX +pqA +aOd +tHL +tHL +tHL +cuB +cuS +cuS +cuZ +ezS +ezS +ezS +ezS +ezS +slt +aLv +aws +aXf +bad +bal +bdc +aKh +bgf +aXf +bFZ +bHZ +bjZ +bjZ +bmb +bjZ +aTt +bpQ +brl +bsV +buu +bvH +bwG +bxD +byO +bzo +bzY +bAQ +bBD +bCD +bDA +bEk +cdO +cdS +cdU +cdU +cvc +bbc +bLD +bkv +bpU +brs +btd +bSI +bFu +bHZ +bUf +bVa +bWf +bWX +bXR +bYx +bZd +cac +cnz +bkl +cnW +coB +coU +aFK +aVo +aQG +aFK +aVo +cpy +aGl +cpO +cpO +aFK +aFK +cpO +cpX +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(116,1,1) = {" +aac +aad +bjg +bjg +bjg +bjg +bjg +bjg +alt +aaP +aaP +aaP +aaP +alv +bqj +bqj +boQ +boQ +boQ +boQ +boQ +boQ +bqj +bqj +alt +alv +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaI +aal +aaM +aaM +aaM +aaM +aby +aaM +aaM +aaM +aaM +acl +acq +acu +acz +acz +ads +adS +acz +aew +acq +afj +afl +afl +agQ +ahs +afl +afl +aiT +akg +akg +akU +akg +akE +aCi +act +adg +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aFq +aLG +aQG +aFK +aVo +aQG +aFK +bdE +bdT +bgm +aCn +aCY +aDV +aEB +aFw +aGJ +aDV +aDV +aIX +aCY +aKq +aws +aws +aLt +aLY +aLY +aNo +aOe +aNo +aLY +aSI +cuQ +cuT +cuV +hya +aKT +pqA +aLX +aLX +aLX +slt +aWn +aws +aXf +bae +bal +bdc +aKh +bgg +aXf +bFZ +bFu +bPH +blc +bmc +bjZ +aTt +bpQ +brm +bsW +buv +bvI +bwH +bxE +byP +bzp +cdM +bAR +bBE +bCE +cdN +bEl +bEQ +bFi +bFF +bGO +cvd +bbc +bLE +bLE +bOc +bPP +bRE +bLE +bFs +bHZ +bUg +bVb +bWg +bWY +bXS +bYy +bZe +cad +cnA +cnD +cnX +coz +coW +aFK +aVo +aQG +aFK +aVo +aGl +aGl +cpO +cpO +aFK +aFK +cpO +cpY +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(117,1,1) = {" +aac +aad +aju +aju +aju +aju +aju +aju +hMn +aaP +aaP +aaP +aaP +aaP +aaE +aaE +aaE +aaE +aaE +aaE +aaE +aaE +aaE +aaE +aaP +alv +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaI +aal +aaM +aaZ +abi +abr +abs +abr +abL +abU +acb +acb +acq +acv +acz +acz +acz +acz +acz +aex +acq +afk +afl +agn +agR +aht +ahU +afl +aiU +akl +akl +akl +akl +akE +aCi +act +adg +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +azl +aal +iFP +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +aCn +aCZ +aCn +aCn +aCn +aCn +aDV +aCW +aIY +aJG +aCn +aws +aws +aLt +aLY +aMD +aNp +aPV +aQI +aQJ +aSJ +aRC +aSh +cuW +hya +aLv +aUo +aUo +aUo +aUo +aVT +aUo +aXf +aXf +baf +bbL +bdc +aKh +bgh +aXf +bFZ +bFu +bQL +blc +bmd +bjZ +aTt +bpQ +brn +bsX +bdA +cdH +bvJ +bfm +bfm +bfm +bfm +bAS +bBF +bCF +bDD +bfm +buz +bFj +bFG +bGP +bIH +bbc +bLE +bMI +bOd +bPQ +bRF +bLE +bFs +bHZ +bUf +bVc +bWh +bWX +bXR +bYx +bZf +bUf +cny +cnE +bgn +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +aGl +cpQ +cpO +aFK +aFK +cpO +cpX +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(118,1,1) = {" +aac +aad +bhK +bhK +bhK +bhK +bhK +bhK +bhK +eRU +eRU +bnS +bnS +bnS +bnS +bnS +bnS +bnS +sYT +eRU +aaP +aaP +hMn +aaP +aaP +alv +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaI +aal +aaN +abb +abj +abs +abs +abs +abM +abj +acc +acm +acq +acx +acz +acY +adt +acY +acz +acz +aeI +afl +afl +afl +agS +afl +afl +air +aiR +akm +akm +akV +akV +akm +aCi +act +adg +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +aCn +aCY +aDV +aDV +aFx +aGN +aDV +aCY +aIZ +aCn +aCn +aCn +awo +aLu +aLZ +aME +aNq +aOf +aPc +aPW +aSK +aRD +aPW +cuX +aTp +aLv +aUo +aUT +aVl +aVy +aVl +aWo +aXg +aYv +bag +bal +bdc +aKh +bgi +aXf +bFZ +bHZ +bjZ +bjZ +bme +bjZ +aTt +bpQ +bro +bsY +buw +bvK +bwI +bxF +bVy +cju +cju +cju +cqm +crj +crx +cju +csc +bFb +bFH +bGQ +bII +bbc +bLE +bMJ +bOe +bPR +bRG +bLE +bFs +bHZ +bUf +bVd +bWi +bWX +bXR +bXR +bZg +bUf +cny +cnB +cnO +bdS +coU +aFK +aVo +aQG +aUm +aVo +aGl +aGl +cpR +cpR +cpV +cpV +cpR +cqa +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(119,1,1) = {" +aac +aad +cna +cna +cna +cna +aES +bhL +uAY +alt +alv +cna +cna +cna +cna +cna +cna +uAY +eoy +aaP +aaP +aaP +aaP +aaP +aaP +alv +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaH +aal +aaO +abc +abk +abs +abs +abs +abN +abV +acd +abV +acq +acy +acz +ada +adu +adT +acz +acz +aeJ +afl +afl +ago +agT +ahu +afl +afl +aiV +akm +akm +akX +akX +akm +aCi +act +adg +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aFq +aGl +aQG +aUm +aVo +aQG +aFK +bdE +beA +bgS +aCo +aDa +aDU +aDV +aFy +aGI +aHB +aIl +aJa +aJH +aKr +aCn +aKR +aLv +aLY +aMF +aNr +aOg +aPd +aPX +aSM +aRE +aSi +cuY +aTq +aLv +aUo +aUU +aVm +aVm +aVm +aWp +aXh +aYw +bal +bDC +bdc +bMF +bgj +aXf +bFZ +bHZ +bjZ +bld +bmf +bnn +boG +bpR +brp +bsZ +bux +bvL +bwJ +bxG +bVz +ckO +ckO +ckO +cqm +crj +cli +ckO +csd +bFc +bFI +bGR +bIJ +bbc +bLE +bMK +bOf +bPS +bRH +bLE +bFs +bHZ +bUf +bUS +bWj +bWZ +bUS +bUS +bZa +bUf +bUf +bUf +cnO +bdS +coU +aUm +aVo +aQG +aFK +aVo +aGl +cpG +cxm +cxm +cxm +cxm +cxm +cxm +cxm +cAI +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(120,1,1) = {" +aac +aad +cna +cxZ +cyI +cna +aEi +brJ +aLy +alt +alv +cna +cxZ +cyI +cna +byw +coR +cAA +eoy +aaP +ajw +ajw +ajw +ajw +ajw +aVB +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaI +aal +aaO +abd +abl +abt +abz +abs +abs +abz +abs +abs +acr +acz +acz +adb +adu +adU +acz +acz +aeJ +afl +afl +agp +agU +ahv +afl +afl +aiW +akm +akm +akX +akX +akm +aCi +act +adg +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +aCn +aCY +aDV +aEB +aFz +aGJ +aDV +aCY +aJb +aJI +aKs +aCn +aMv +aLv +aLY +aLY +aNs +aOh +aPe +aLY +bGw +cuR +aSj +aSN +aTr +aTT +aUo +bdi +aVm +aVm +aVm +aWp +aXi +aYx +bxC +bal +bdc +aKh +bgk +aXf +bFZ +bHZ +bjZ +ble +bmg +bno +boF +bpS +brq +bta +buw +bvM +bvM +bxH +bVz +ckO +oUj +clP +cqo +crk +cry +ckO +csd +bFk +bFD +bGT +bIK +bKn +bLE +bML +bOg +bPT +bRI +bLE +bFs +bHZ +bUf +bUf +bUf +bUf +bXT +bWT +bYY +bWT +bWT +bUf +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpH +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(121,1,1) = {" +aac +aad +cna +cya +cyJ +cna +aEj +brJ +aLz +alt +alv +cna +cya +cyJ +cna +czB +coR +cAB +eoy +alv +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaI +aal +aaO +abe +abm +abs +abA +abF +abA +abF +abA +abs +acq +acA +acz +adc +adu +adV +acz +acz +aeJ +afl +afl +agq +agV +ahw +afl +afl +aiV +akm +akm +akX +akX +akm +aCi +act +adg +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aUm +bdE +bdS +bgm +aCn +aCZ +aCn +aCn +aCn +aCn +aDV +aCY +aJc +aJI +aKt +aCn +aMv +aLv +aws +aws +bTt +aOj +byt +bzq +bzq +bzq +bGg +bzq +bPW +bTe +aUo +aUV +aVm +aVm +aVm +aWq +aXf +aYy +bam +bam +bde +aKh +bgq +aXf +bFZ +bHZ +bjZ +blf +bmh +bnp +aZB +bpQ +brr +btb +buy +bvN +bdA +bxJ +bVz +ckO +clP +cpe +cqp +crl +crz +crH +bQG +csw +bNb +bNb +bNb +bNb +bNb +bFu +ciW +cje +cjj +bNb +bFu +bHZ +bUf +bVe +bWk +bUf +bXU +bWT +bYY +cae +cae +cbQ +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpH +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(122,1,1) = {" +aac +aad +cna +cna +cyK +cna +aEk +brJ +aLA +alt +alv +cna +cna +cyK +cna +byK +coR +cAC +eoy +alv +aTz +apa +apa +cqe +aDn +sYK +aTz +rcW +sQo +hXd +hXd +snc +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaI +aal +aaQ +abf +abj +abs +abA +abG +abO +abW +abA +abs +acq +acB +acz +acY +adv +acY +acz +acz +aeK +afl +afl +afl +agS +afl +afl +air +aiR +akm +akm +alc +alc +akm +aCi +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apl +aqf +aqf +aqf +aqf +aqf +aqf +aqf +aqf +aqf +aqf +aqf +aqf +ayE +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +aCn +aCY +aDV +aDV +aFA +aGO +aDV +aCY +aIZ +aJJ +aKu +aCn +aMv +aLv +aMa +aws +aws +aOj +byu +bzr +bzr +bzr +bGg +bGg +bPW +bTe +aUo +aUW +aVl +aVz +aVl +aWr +aXj +aYz +ban +aKh +bdf +ban +bgr +bhj +bGp +bHZ +bjZ +blg +bmi +bnq +aZB +bpT +bro +btc +buz +bvO +but +bxK +bVz +ckO +cmv +bQG +cqq +crm +crA +crb +bQG +csx +bNt +bNt +bNt +bNt +bNt +bFu +cjd +cjf +cjl +bNx +bFu +bHZ +bUf +bVf +bWk +bXa +bWT +bWT +bYY +bWT +bWT +cbR +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpH +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(123,1,1) = {" +aac +aad +cna +byw +coR +cna +cna +bDp +cAD +alt +alv +cxy +bDp +bDp +cna +cna +cuu +cAD +eoy +alv +aTz +apa +apa +cqf +aDn +ssY +aTz +kfz +rxa +fwK +fwK +cIt +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaI +aal +aaM +abg +abn +abs +abA +abH +abA +abH +abA +acn +acq +acz +acz +acz +acz +acz +acz +aey +acq +afm +afl +agn +agW +agY +ahU +afl +aiS +akB +akB +akB +akB +akE +aCi +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aRT +aFK +aVo +aQG +aFK +bdE +bdS +bgl +aCn +aCX +aDU +aDV +aFB +aGI +aHB +aIm +aJd +aJK +aCn +aCn +aMv +aLv +aws +aMG +aMG +aMG +aPg +aMG +aMG +aMG +bGu +bLb +bQf +bTI +aUp +aUX +aVn +aUo +aVU +aUo +aXf +aYA +bao +bEN +bdg +beJ +aIW +aXf +bFZ +bHZ +bjZ +bjZ +bjZ +bjZ +aTt +bpU +bri +bsS +bku +bku +bku +bxL +bVz +ckO +cmv +bQG +cqp +crl +crA +crb +ckO +csd +bNd +bNd +bNd +bNd +bNd +bMM +bOh +bPU +bRJ +bNd +bFs +bHZ +bUf +bUf +bUf +bUf +bXU +bWT +bYY +cae +cae +cbR +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpH +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(124,1,1) = {" +aac +aad +cna +czB +coR +bDp +bDp +bDp +cna +alt +aaP +cxz +bDp +bDp +bDp +bDp +bDp +cna +eoy +alv +aTz +apa +apa +apa +apa +apa +fqI +phV +fwK +cHq +tmZ +kZN +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaI +aal +aaM +aaM +abo +abu +abB +abI +abP +abX +abB +aco +acq +acC +acz +acz +ady +acz +aei +aez +acq +afn +afl +afl +agX +agY +afl +afl +aiT +akg +akg +akU +akg +akE +aCi +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +aCn +aCY +aDV +aEB +aFD +aGJ +aDV +aIo +aJe +aJL +aKv +aKo +aMv +aLv +aws +aMG +aNt +aOk +aPh +aPh +aQK +aMG +bBU +bFg +bQz +bFg +bzu +bzu +bzu +bzu +bFg +ccA +aXf +aYB +bap +bEO +bdh +beK +bgs +aXf +bFZ +bFu +bNb +blh +blh +blh +bkv +bpV +brs +btd +bkv +aZB +bkv +bxM +bXp +ckO +cmv +bQG +cqT +crn +crA +crb +ckO +csd +bFJ +bGU +bGU +bGU +bLF +bMN +bOi +bPV +bRK +bNd +bFs +bHZ +bUf +bVg +bWk +bXb +bWT +bWT +bYY +bWT +bWT +cbS +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpI +cxn +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(125,1,1) = {" +aac +aad +cna +aaD +coR +cna +aEJ +bDp +cna +alt +alv +cxy +bDo +bDp +czf +czD +cAj +cna +eoy +hMn +jdx +apa +apa +apa +apa +apa +aTz +qvZ +fwK +rxa +fwK +ruk +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaH +aal +aal +aaM +aaM +abv +abC +abJ +abQ +abY +ach +acp +acq +acq +acR +acq +acq +acq +acq +acq +acq +afo +afl +agn +agY +agY +ahU +afl +aiT +akg +akg +akg +ald +akm +aCi +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +aCn +aCZ +aCn +aCn +aCn +aGL +aDV +aIp +aJf +aJM +aKw +aKq +aMv +aLv +aws +aMG +aNu +aOl +aOl +aOl +aQL +aMG +cuU +bFg +bQz +bTV +bVm +bVm +cag +bFg +bFg +ccB +aXf +aXf +aXf +bFd +aXf +aXf +aXf +aXf +bFZ +bFu +bHZ +bli +bli +bli +bli +bpW +brt +bte +buA +bvP +buA +bxN +bVz +ckO +cmv +cpf +cqT +crn +crA +crb +ckO +csd +bFJ +bGV +bGY +bGY +bLG +bMO +bOj +bPX +bRL +bNd +bFs +bHZ +bUf +bVh +bWk +bUf +bXU +bWT +bZh +caf +caf +bUf +cnO +bdS +coU +aFK +aVo +aQG +aUm +aVo +aGl +cpH +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(126,1,1) = {" +aac +aad +cna +cna +cna +cna +cna +cxz +cna +alt +alv +cna +cna +cna +cna +cna +cna +cna +eoy +alv +aTz +apa +apa +apa +apa +apa +aTz +wuG +rKc +rbl +mkV +dTR +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaI +aal +aal +aal +aaM +aaM +abD +abK +abK +abK +aci +aaM +acs +acD +acD +add +adz +adW +add +acD +aeL +afp +afp +agr +agZ +afp +afp +afp +aiU +akg +akg +akg +akE +aBR +aCi +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aLG +aQG +aFK +aVo +aQG +aFK +bdE +bdT +bgl +aCn +aCY +aDV +aDV +aFE +aGP +aDV +aIq +aJg +aJN +aKx +aCn +aMv +aLv +aws +aMG +aNv +aOl +aPi +aOl +aQM +aMG +bBU +bFg +bQA +bTc +bVn +bSd +bVq +cag +bFg +bFg +cdu +aYC +aOc +aTn +aOc +aOc +aOc +bhk +bFZ +bFu +bFu +blj +bmj +bnr +bmj +bpX +bru +bti +bvQ +bvQ +bwL +bto +bVz +ckO +cmv +bQG +cqT +crn +crA +crb +ckO +csd +bNd +bGW +bGY +bGY +bLH +bMP +bOk +bPY +bRM +bNd +bFs +bHZ +bUf +bUf +bUf +bUf +bXV +bXV +bZi +cah +bUf +bUf +cnO +coA +coU +aFK +aVo +aQG +aFK +aVo +cpy +cpH +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(127,1,1) = {" +aac +aad +btv +btv +btv +btv +btv +ajw +aKB +aaP +aaP +btv +btv +btv +btv +btv +btv +btv +hlN +alv +aTz +apa +apa +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaI +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +acs +acE +acS +acS +acS +acS +acS +acD +acs +afq +afq +afq +afq +afq +afq +afq +afq +akg +akg +ald +aso +akg +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +oIz +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aQG +aFK +aWs +aQG +aFK +bdE +bdS +bgl +aCn +aCX +aDU +aDV +aFF +aGI +aHB +aIr +aJh +aJO +aKw +aKo +aMv +aKT +aws +aRF +aNw +aOm +aPj +aOl +aQN +aRF +bBU +bFg +bQH +bAF +bVq +bTc +bAF +bWE +bFg +bFg +cdu +aYD +aNn +bFh +bIE +buE +buE +bPx +bHr +bIa +bFu +blj +bmk +bns +bmj +bpY +brv +btj +buC +buC +buC +bxP +bVz +ckO +cmv +bQG +cqT +crn +crB +crb +ckO +csd +bFK +cdW +bGY +bGY +bLH +bMS +bOl +bPX +bRN +bNd +bFs +bFu +bNb +bNb +bNb +bNb +bFu +bFu +bNb +bNb +bNb +bNb +cnT +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpH +cxo +cdB +bvU +bvU +bvU +aXQ +cAx +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(128,1,1) = {" +aac +aad +aal +aal +aal +aal +aal +aal +aal +alt +alv +cna +cna +cna +cna +cna +cna +uAY +eoy +alv +aTz +apa +apa +aTz +cqG +jCx +crM +adO +apa +apa +cor +aDq +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aaF +aaJ +aaK +acw +acw +acw +acw +aaK +acw +acw +acw +acw +acw +acs +acD +acS +acS +acS +acS +acS +acD +acs +afr +afP +afq +aha +ahx +ahV +ais +afq +akg +akg +akE +aso +akg +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aQG +aUm +aVo +aQG +aFK +bdE +bdS +bgm +aCn +aCY +aDV +aEB +aFG +aGQ +aHD +aIs +aJi +aJP +aKy +aKq +aMv +aLv +aws +aMI +aNx +aOn +aPk +aOl +aQN +aMI +bBU +bFg +bQH +bAF +bVK +bSd +bAF +bWE +bFg +ccD +aHR +aHR +aHR +aHR +bKm +aHR +aHR +aHR +aHR +bIb +bQM +bli +bli +bli +bli +bpW +brw +btk +cdF +bvR +buC +bxP +bVz +ckO +cmv +bQG +cqT +crn +crA +crb +ckO +ckO +bFL +bGY +bGY +bGY +bLH +bMT +bOm +bPX +bRO +bMM +bFu +bFu +bNt +bNt +bFu +bFu +bNt +bNt +bNt +bNt +cud +cui +cnY +cov +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpH +cxp +cxT +bvU +czc +czy +cxT +cxp +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(129,1,1) = {" +aac +aad +aan +aan +aal +aal +acZ +aal +aal +alt +alv +cna +cxZ +cyI +cna +byw +coR +cAA +eoy +alv +aTz +apa +apa +duE +olL +aDn +aDn +oYk +apa +apa +aTz +orN +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aqg +acK +acK +acK +acK +acK +acK +acK +acK +acK +acK +acK +ayG +acs +acF +acT +acD +acD +acD +acD +acD +acs +afs +afQ +ags +aft +ahy +ahy +aft +aiX +akg +akg +akE +aso +akg +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +aCn +aCZ +aCn +aCn +aCn +aCn +aHE +aIt +aJj +aJQ +aKz +aCn +aMv +aLv +aws +aMJ +aNy +aOl +aOl +aOl +aQN +aMJ +bBU +bFg +bQH +bAF +bWE +bQJ +bAF +bWE +bFg +ccD +aHR +aYE +baq +bbP +bdj +beL +baq +bhm +aHR +bIb +bHZ +aWA +bml +bnt +boH +bpZ +brx +btk +buC +bvS +buC +bxP +bVz +ckO +cmv +bQG +cqT +crn +crA +crb +ckO +ckO +bFL +bGY +bGY +bGY +bLH +bMU +bOk +bPZ +bRP +bNd +bFs +bHZ +bUh +bUh +bWl +bWl +bUh +bUh +bUh +bUh +cbc +bUh +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpH +cxq +bvU +bvU +bvU +czy +bvU +cxq +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(130,1,1) = {" +aac +aad +aao +aze +aal +aal +aal +aal +aal +alt +alv +cna +cya +cyJ +cna +czB +coR +cAB +eoy +aaP +jdx +apa +apa +aTz +cqJ +ptp +crO +apa +apa +apa +aTz +cnj +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +acs +acs +acs +acs +adA +adX +aej +aeA +acs +afq +afq +afq +ahb +ahy +ahy +ait +aiY +akg +akg +akE +aso +aBS +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgm +aCp +aDb +aDW +aDW +aSk +aTR +aHI +aIu +aJk +aJR +aKA +aCn +aMv +aLv +aws +aMG +aNz +aOo +aPl +aOo +aQO +aMG +bBU +bFg +bQH +bAF +bWE +bQJ +bAF +bWE +bFg +ccD +aHR +aYF +aAT +aAT +aKj +aAU +aAU +bhn +bic +bIc +bHZ +aWA +bmm +bnt +bnt +bqa +brx +btk +buD +bvT +bwM +bxP +bVz +ckO +cmv +bQG +cqT +crn +crA +crb +ckO +csd +bFK +bGZ +bGY +bGY +bLH +bMS +bOl +bPX +bRQ +bNd +bFs +bHZ +bUh +bVi +bCT +bCT +bXW +bUh +bZj +cai +cbd +bUh +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpH +cxp +bvU +bvU +bvU +czy +bvU +cxp +cAJ +cAM +cAQ +ctQ +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(131,1,1) = {" +aac +aad +aap +aap +aal +aal +aal +acZ +aal +alt +alv +cna +cna +cyK +cna +byK +coR +cAC +eoy +alv +aTz +apa +apa +aTy +apa +apa +apa +apa +aTz +aTz +aTz +aTz +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +alg +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +bQU +acs +acG +acU +adf +acD +adY +acD +acD +aeM +aft +afR +aft +aft +ahy +ahW +aiu +aiZ +akg +akg +fZZ +aso +akg +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aal +apm +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aUY +bdE +bdS +bgl +aCq +aDc +aDX +aDX +aSA +aCn +aCn +aIv +aJl +aCZ +aCn +aCn +aMv +aLv +aws +aMG +aNA +aOq +aPm +aOq +aNA +aRG +bBU +bFg +bQH +bAF +bWE +bQJ +bAF +bWE +bFg +ccD +aHR +aYG +bar +aOp +bdk +aOp +bar +bho +aHR +bIb +bHZ +aWA +bmn +bnu +bYo +bpZ +bry +btl +cdG +bvW +bwN +bxP +bVz +ckO +cmv +bQG +cqT +crn +crA +crb +ckO +csd +bNd +bHa +bIL +bKo +bNd +bMV +bOn +bQa +bRR +bNd +bFs +bHZ +bUi +bVj +bWm +bWm +bVj +bUh +bZk +bCT +cbe +bUh +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpH +cxq +cxU +bvU +bvU +czy +cxU +cxq +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(132,1,1) = {" +aac +aad +aal +aal +aal +aal +aal +aal +bKW +alt +alv +cxy +aXP +bDp +cna +cna +cuu +cAD +eoy +alv +aTz +apa +oin +aTz +pcj +apa +apa +apa +aTz +oju +jZF +aDn +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +acs +acH +acH +acs +acD +adZ +aek +aeB +acs +afu +afS +aft +aft +aft +ahX +aiv +afq +akg +akg +akE +aso +akg +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aal +anB +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +aqh +azm +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +aCn +aDd +aDX +aDX +aSC +aDW +aDX +aDX +aJm +aJS +aDW +aCn +aMv +aLv +aws +aMK +aNB +aOr +aOr +aOr +aQP +aMK +bBU +bFg +bQH +bAF +bWE +bQJ +bAF +bWE +bAF +bAF +aXk +aYH +bas +bas +bas +bas +bas +bhp +bid +bIY +bHZ +aWA +bmo +bnu +bnu +bpZ +brz +btm +buF +cdI +bwO +bxP +bVz +ckO +cmv +bQG +cqT +cro +crA +crb +ckO +csd +bFM +bHb +bIM +bIM +bLI +bMW +bOo +bQb +bRS +bSJ +bFs +bHZ +bUh +bVk +bWn +bXc +bXX +bUh +bZl +bCT +cbf +bUh +cnO +bdS +coU +aFK +aWs +aQG +aUY +aVo +aGl +cpH +cxr +cdC +bvU +bvU +bvU +aXQ +cAy +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(133,1,1) = {" +aac +aad +btv +btv +btv +btv +btv +aaE +btv +aaP +aaP +cxz +bDp +bDp +bDp +bDp +bDp +cna +eoy +fVP +aTz +apa +apa +aTz +ium +apa +apa +apa +aTz +qwr +apa +apa +aTz +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +acs +acI +acV +acs +acs +aea +ael +acs +acs +afq +afq +agt +ahc +ahz +afq +afq +afq +akg +akg +ale +awY +akU +aaW +act +adg +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgT +aFH +aFI +aRH +aRH +aTk +aDW +aDX +aDX +aJm +aJS +aDW +aCr +aKT +aLv +aws +aMK +aNC +aOr +aTS +aOr +aQP +aUl +bFg +bFg +bQH +bAF +bWE +bQJ +bAF +bWE +bAF +bAF +aXl +aYH +bas +bas +bas +bas +bas +bhp +bie +bIY +bHZ +aWA +bmp +bXA +boI +bpZ +brA +btn +buG +bvY +bwP +bto +bVz +ckQ +cmv +bQG +cqT +crn +crA +crb +ckQ +csd +bFM +bHc +bIN +bKp +bLJ +bMX +bOp +bPX +bRT +bSJ +cla +bHZ +bUh +bVk +bWo +bXd +bXX +bUh +bZm +caj +cbi +bUh +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpH +wQO +bvU +bvU +bvU +bvU +bvU +wQO +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(134,1,1) = {" +aac +aad +cna +cna +cna +cna +cna +cxz +cna +alt +alv +cxy +bDo +bDp +czf +czD +cAj +cna +eoy +aaP +jdx +apa +apa +aTz +mrd +wcL +uBB +apa +heG +apa +apa +euK +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +ajC +adg +ajt +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +aca +act +act +aca +act +act +adg +aDu +ajt +act +aEq +aal +aal +amb +aal +aal +aal +aal +aal +amb +aal +aal +aal +aal +aal +amb +aal +aal +aal +aal +aal +aFq +aGl +aQG +aFK +aVo +aQG +aFK +bdE +bdS +bgl +aCn +aDe +aDY +aDY +aDY +aDY +aDY +aIw +aJn +aJT +aDW +aCn +aMv +aLv +bTt +aMK +aND +aOu +aPn +aQa +aQQ +aMK +bBU +bFg +bQH +bAF +bWE +bQJ +bAF +bWE +bFg +ccD +aHR +aYI +bat +bbQ +bdl +beM +bgt +bhq +aHR +bIb +bHZ +aWA +bmq +bmq +bmq +bpZ +brB +bto +buH +bto +bto +bxQ +bVz +ckO +cmv +cpg +cqT +crn +crA +crb +ckO +csd +iMm +bNd +bNd +bNd +bNd +bNd +bOq +bQc +bRU +bNd +clf +bHZ +bUh +bVl +bWp +bXe +bVj +bUh +bZn +cak +cbj +bUh +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpH +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(135,1,1) = {" +aac +aad +cna +byw +coR +cna +aEL +bDp +cna +alt +alv +cna +cna +cna +cna +cna +cna +cna +eoy +alv +aTz +apa +apa +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aaW +adg +ajt +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +adg +aDu +ajt +act +aEq +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aFq +aGl +aSB +aFK +aWt +aQG +aFK +bdE +beB +bjO +aCs +aCn +aDZ +aEI +aFJ +aCn +aCn +aDZ +aJo +aFJ +aCn +aCm +aKU +aLw +aMb +aMK +aMK +aOv +aPo +aQb +aQR +aRI +bBU +bFg +bQI +bAF +bXj +bQJ +bAF +bWE +bFg +ccD +aHV +aHR +aHR +aHR +aHR +aHR +aHR +aHR +aHR +bJj +bQN +acg +acg +acg +acg +bqb +brC +acg +buI +acg +acg +bxR +bVz +ckO +cnZ +cpf +cqU +crn +crA +crb +ckO +csd +bxR +acg +acg +acg +acg +acg +bqb +brC +buI +acg +cmC +cqt +bUh +bUh +bWq +bXf +bUh +bUh +bZo +bUh +bUh +cdA +cnO +bdS +coS +aFK +aVo +aQG +aFK +aVo +aGl +cpI +cxn +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(136,1,1) = {" +aac +aad +cna +czB +coR +bDp +bDp +bDp +cna +alt +aaP +btv +btv +btv +btv +btv +btv +btv +hlN +alv +aTz +apa +apa +aTz +cqG +jCx +crM +adO +apa +apa +cor +aDq +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aaW +adg +akd +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +adp +aSr +bdJ +bdJ +bTf +cuo +cus +cuy +aDQ +aDQ +aEC +aEC +aEC +aEC +aEC +aEC +aEC +aEC +aEC +aEC +aEC +aEC +aEO +aEO +aEO +aEO +aEO +aEO +aEO +aEO +afB +afB +aHe +aIn +aIn +aTx +cvz +cvC +cvG +cvJ +aEO +aEO +aEO +aEO +aEO +aEO +aEO +aEO +bxs +aEO +bxI +bxI +aHF +aHF +aEO +aUu +aEO +aEO +aEO +aEO +aGi +aEO +bDK +bjU +bwK +byR +byR +bBG +byR +bBJ +bjU +bDK +aEO +aEO +aEO +aEO +aEO +aEO +aEO +aEO +aEO +cfd +cgG +aEO +aEO +aEO +aEO +cku +cky +aEC +ckF +aEO +aEO +aEO +bXq +ckR +coa +cph +cqV +crp +crC +crI +ckR +ckR +aEO +aEO +aEO +aEO +aEO +aEO +cmH +cky +ckF +aEO +aEO +aHF +aEO +aEO +cnq +cnt +cnu +cnu +cnw +cnu +cnu +cnu +ctt +cvQ +cvR +ctD +ctu +cty +ctu +ctE +ctH +ctJ +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(137,1,1) = {" +aac +aad +cna +aCt +coR +cna +cna +bDp +cAD +alt +alv +cgU +cgU +cgU +cgU +cgU +cgU +cgU +eoy +alv +aTz +apa +apa +duE +olL +aDn +aDn +oYk +apa +apa +aTz +orN +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aaW +ajW +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +ajM +aUx +aBT +aBT +bTg +cup +cuw +cuz +aDR +aEA +aEA +aEA +aEA +aEA +aEA +aEA +aEA +aEA +aEA +aEA +aEA +aEA +aEA +aEA +aEA +aEA +aEA +aEA +aEA +aEA +alL +aDh +aHi +aIy +aSX +aUy +aIy +cvD +cvH +bdK +aEA +aEA +aEA +aEA +aEA +aEA +aEW +aEA +aEA +aEA +aEA +aEA +aEA +aEA +aEW +aEA +aEA +aEA +aEA +aEA +aGj +aEA +bDL +cvj +bxa +bzx +bAh +bBH +bzx +cvp +bCJ +bDL +aEA +aEA +aEA +aEA +aEA +aEA +aEW +aEA +aEA +aGj +cgJ +aEA +aEA +aEA +aEW +aGj +aEA +aEA +ckG +aEA +aEA +aEA +bXr +bkc +cob +cpi +cqW +crq +crD +crL +cse +csy +aEA +aEA +aEA +aEA +aEA +aEA +cmI +aEA +ckG +aEA +aEA +aEA +aEA +aEA +ckG +cmI +aEA +aEA +ckG +aEA +aEA +aEA +csQ +csY +cth +ctq +ctv +ctz +cts +ctF +cIQ +pVt +wQO +bvU +bvU +bvU +bvU +bvU +wQO +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(138,1,1) = {" +aac +aad +cna +cna +cyK +cna +aEM +brJ +aLy +alt +alv +cgU +aXR +baj +bdL +czB +nTN +cgU +eoy +alv +aTz +apa +apa +aTz +cqJ +ptp +crO +apa +apa +apa +aTz +cnj +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aaW +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +act +alh +aUB +aBU +aBU +aBU +cuq +cux +cuA +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +amp +aDL +aHj +aNX +aTs +aHj +aNX +cvE +cvI +bdU +aOs +aEa +aEa +aEa +aEa +aEa +aEa +aFd +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +bEm +cvk +bnV +bzy +bAT +bxd +bzy +bAT +bCK +bEm +aOs +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aEa +cgN +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aFd +aEa +aEa +aEa +bXs +ckT +coc +cpm +cqX +coc +cpm +crP +csf +csz +aOs +aEa +aEa +aEa +aEa +aEa +aEa +aEa +aFd +aEa +aEa +cnd +aEa +aEa +cnr +aEa +aEa +aEa +aFd +aEa +aEa +aEa +csR +csZ +cti +ctr +ctw +ctA +cts +ctG +ctH +ctJ +cxo +cdB +bvU +bvU +bvU +aXQ +cAx +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(139,1,1) = {" +aac +aad +cna +aCu +cyJ +cna +aEN +brJ +aLz +alt +aaP +aVA +bDp +bDp +bdN +coR +mok +cgU +eoy +alv +aTz +apa +apa +aTy +apa +apa +apa +apa +aTz +aTz +aTz +aTz +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +acZ +aal +aal +ajL +aka +aka +aka +akf +akf +akf +akf +akf +akf +akf +akf +akf +aka +aka +aka +aka +aka +aka +alu +aWk +akf +act +aCT +aDg +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +amK +aEe +aEe +aEe +aEe +aEe +aEe +aEe +aEe +bew +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aFb +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +cuC +bCL +boX +bqn +bqn +bqn +bqn +bqn +bCL +bEn +aDE +aDE +aDE +aDE +aDE +aFb +aDE +aDE +ceM +aDE +cgQ +aDE +aDE +aDE +aDE +aFb +aDE +aDE +aDE +aDE +aDE +aDE +bYi +ckV +cod +cod +cod +cod +cod +cod +csg +csA +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +ceM +aDE +aDE +aDE +aFb +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +csS +cta +ctj +cts +cts +cts +cts +ctG +ctH +ctJ +cxp +cxT +bvU +czc +czy +cxT +cxp +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(140,1,1) = {" +aac +aad +cna +aCv +aDr +cna +aEP +brJ +aLA +alt +alv +cgU +bxi +bDp +bqf +coR +jep +cgU +eoy +aaP +jdx +apa +apa +aTz +pcj +apa +apa +apa +aTz +oju +jZF +aDn +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +ahA +ahA +ahA +ahA +ahA +ahA +alw +aWu +akU +aCj +aCT +aDg +aDE +aDJ +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aqT +aEH +aHG +aEe +aEe +aEe +aEe +aTu +aFC +bey +aOt +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +bER +cvl +btG +bqn +bqn +bqn +bqn +bAU +bCM +bER +aOt +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +cgW +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +ckL +bZt +ckW +coe +cod +cod +cod +cod +cqY +cle +csA +aOt +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +cnv +aDG +aDG +aDG +aDG +csT +ctb +ctk +cts +cts +cts +cts +ctG +ctH +ctJ +cxq +bvU +bvU +bvU +czy +bvU +cxq +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(141,1,1) = {" +aac +aad +cna +cna +cna +cna +aES +bhL +aLB +alt +alv +cgU +cgU +cgU +cgU +cgU +cgU +cgU +eoy +alv +aTz +apa +apa +aTz +aDo +apa +apa +apa +aTz +qwr +apa +apa +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +acZ +aal +aal +ahA +ahY +aiw +aja +ajp +ahA +alw +aWu +akg +aCj +aCT +aDg +aDE +aDI +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aGX +aqT +aFt +aHW +aOA +aEe +aEe +aEe +aWE +bcn +bey +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aGX +bER +cvm +bxZ +bAa +bqn +bqn +bqn +bCG +bDE +bER +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +chj +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aGX +bZt +cld +cof +cod +cod +cod +cpn +crQ +csh +csA +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +cmU +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aEc +aGX +csT +ctc +ctl +cts +cts +cts +cts +ctG +ctH +ctJ +cxp +bvU +bvU +bvU +czy +bvU +cxp +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(142,1,1) = {" +aac +aad +aaq +aaE +aaE +aaE +aaE +aaE +aLC +aaP +aaP +aaE +aaE +aaE +aaE +aaE +aaE +aaE +hlN +alv +aTz +apa +apa +aTz +mrd +wcL +uBB +apa +heG +apa +apa +euK +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +ahA +ahZ +aiz +ajb +ajq +ahA +alw +aWu +akg +aCj +aCT +aDg +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aFb +aDE +aDE +aDE +aDE +aDE +aqT +aEe +aEe +aEe +aEe +aEe +aEe +aEe +aEe +bey +aDE +aDE +aDE +aDE +aFb +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aFb +aDE +aDE +aDE +aDE +aDE +bER +bCL +boX +bqn +bqn +bqn +bqn +bqn +bCL +bER +aDE +aDE +aFb +aDE +aDE +aDE +ceM +aDE +aDE +aDE +cgQ +aDE +aDE +aDE +aFb +aDE +aDE +ceM +aDE +aDE +aDE +aDE +bZt +ckV +cod +cpn +cod +cod +cod +cod +ckV +csA +aDE +aDE +aDE +ceM +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +aDE +ceM +aDE +aDE +aDE +aDE +ceM +csT +cta +ctj +cts +cts +cts +cts +ctG +ctH +ctJ +cxq +cxU +bvU +bvU +czy +cxU +cxq +cAJ +cAM +cAQ +ctQ +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(143,1,1) = {" +aac +aad +aar +ajw +ajw +ajw +ajw +aGS +aaP +aaP +aaP +aaP +aaP +aaP +aaP +aaP +aaP +aaP +hlN +tyL +aTz +jdx +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +ahA +aia +aiA +ajc +ajr +ahA +alw +aWu +akg +aCj +aCT +aDt +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aGY +aBy +aFC +aHG +aEe +aTu +aHG +aEe +aTu +bdG +beC +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aGY +bES +bCM +btG +bqn +bAU +byb +bqn +bAU +bDH +bES +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +cgW +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aGY +caB +cle +coe +cod +cqY +coe +cod +cqY +csi +csB +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aDG +aGY +csU +ctd +ctm +ctr +ctx +ctB +cts +ctG +ctH +ctJ +cxr +cdC +bvU +bvU +bvU +aXQ +cAy +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(144,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +alt +aaP +aaP +aaP +aaP +ajw +aaP +aaP +ajw +ajw +ajw +ajw +ajw +oKt +aVB +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +acZ +aal +aal +aad +aad +aad +ahA +aib +aiB +ajd +ajs +ahA +alw +aWu +akg +aCj +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCB +aFT +aHX +aEe +aTv +aUz +aEe +aXe +bdH +beD +aCT +aCT +aCT +aCT +aCT +aCT +buQ +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aFa +aCT +aCT +aCT +aCT +aCT +aCT +bFl +cvn +bya +bqn +bAV +bBI +bqn +bCH +bDI +bFl +aCT +aCT +aCT +aCT +aCT +aCT +buQ +aCT +aCT +aCT +chl +aCT +aCT +aCT +aFa +aCT +aCT +aCT +aCT +aCT +aCT +aCT +caY +bkd +cog +cod +cqZ +crr +cod +crR +csj +clh +aCT +aCT +aCT +aCT +aCT +aCT +buQ +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aCT +aFa +aCT +aCT +aCT +aCT +aCT +aCT +csV +cte +cwT +cts +ctv +ctC +cts +ctG +ctI +ctJ +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(145,1,1) = {" +aac +bBP +bBP +bBP +bBP +bBP +bBP +alt +ajw +ajw +ajw +aVB +aXS +bak +bak +aXS +aXS +aXS +aXS +aXS +aXS +aXS +aXS +rni +rni +rni +rni +rni +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aac +ahA +aic +aiC +aje +aje +ahA +alw +aWu +akg +aCj +aCT +aCT +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aCB +aCB +aHY +aSO +aTw +aTw +aUA +aYi +aCB +beD +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +bFl +bDJ +byc +bAb +bAW +bAW +bAW +bCI +bDJ +bFm +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +aDH +chl +aDH +aDH +aCT +aCT +aDH +aDH +aDH +aDH +aDH +aDH +aDH +caY +bke +coC +cpr +cra +cpr +crE +crS +bke +csC +clt +clt +clt +clt +clt +clt +clt +clt +aCT +aCT +clt +clt +aCT +clt +clt +clt +clt +clt +clt +clt +clt +clt +cvN +cvQ +cvR +ctu +cty +ctu +ctD +ctE +ctH +ctJ +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(146,1,1) = {" +aac +bBP +bHy +bJe +bJe +bJe +bBP +bsb +cgU +cgU +cgU +cgU +cgU +bDp +bDp +bUr +cjB +cjB +cjB +cgU +css +bDp +cgU +rni +rni +rni +rni +rni +rni +rni +rni +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aad +aad +aad +aad +aad +aac +aac +ahA +aid +aiC +ajf +ajf +ahA +alw +aWu +aal +aal +aal +aal +alm +alO +amc +alo +aED +aED +aEG +aED +aED +aED +aED +aED +aEG +aED +aED +aED +aED +aED +aEG +alo +akz +akQ +azH +cnB +aFq +aGl +aQG +aUY +aVo +aZH +aFK +bdM +aGl +biG +giH +alJ +alJ +alJ +ueO +alJ +alJ +alJ +hPL +alJ +alJ +hOo +bmw +bmw +bmw +bmw +bmw +bmw +bmw +bmw +bmw +bmw +bGv +ccu +byp +bAF +bWE +bYH +bTW +caZ +ccu +ccI +aXz +pCQ +aXz +aXz +aXz +aXv +aXv +aXv +aXv +aXw +cjU +aXz +aXz +aSx +aRV +aRV +bVo +bVo +bVo +cgY +chf +iLC +cbW +cli +coD +bQG +crb +crs +bQG +bQE +cli +csd +boV +fao +boV +boV +boV +boV +boV +boV +aSx +aSL +ccV +ccV +ccZ +ccV +ccV +ccV +ccV +cdj +cjP +csP +ccV +csW +cnO +bdS +coU +aFK +aVo +aZH +aFK +bdM +aGl +cpK +cxn +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(147,1,1) = {" +aac +bBP +bHz +bJe +bJe +bJe +bKA +alv +cgU +ciL +cjB +cjB +cgU +bDp +bDp +cgU +ciM +cjB +cjB +cgU +cst +bDp +cgU +rni +rni +rni +rni +rni +rni +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aeC +aeC +aeC +aeC +aeC +aeC +ahA +aix +aiD +ajg +ajg +ahA +alw +aWu +aal +aal +aal +aal +akJ +akR +ame +alo +alo +alo +alo +alo +alo +alo +alo +alo +alo +alo +alo +alo +alo +alo +alo +alo +ame +akR +akJ +cnB +aFq +aGl +aQG +aFK +aVo +aQG +aFK +aVo +aGl +biG +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +oyS +qPQ +bmw +bnM +boR +bmw +brO +boR +bmw +bnM +boR +bmw +aUv +ccu +byp +bAF +bWE +bQJ +bAF +bWE +ccu +ccI +aXw +boo +clr +bMb +clE +cma +cma +cma +cma +cmc +ckk +cly +aXz +cmr +aRV +aRV +bVo +cgO +cgT +cgZ +chg +bVo +cbW +cli +coD +bQG +crb +crt +bQG +cqT +cli +csd +boV +bJd +ciK +bMQ +boV +bOL +ccE +boV +aSx +aSL +ccV +wJY +ccW +ccV +cda +ccV +cde +cde +cde +cde +cde +csX +cnO +bdS +coU +aFK +cpq +aQG +aFK +aVo +aGl +cpH +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(148,1,1) = {" +aac +bBP +bHA +bJe +bKB +bLR +bBP +bOD +cgU +ciM +cjB +cjB +bUr +bDp +cmT +cgU +ciL +ciN +cjB +cgU +csu +bDp +cgU +rni +rni +rni +rni +rni +rni +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aeC +aeN +afv +afT +agu +ahd +ahA +aiy +aiE +ahA +ahA +ahA +alw +aWu +aal +aal +aal +aal +aln +alP +amf +alR +ank +ank +ank +apo +ank +ank +ank +ank +ank +ank +aur +ank +ank +ank +ank +axZ +ayH +alP +aln +cnB +aFq +aGl +aQG +aFK +aVo +aQG +aFK +aWs +aGl +biG +pBd +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +qPQ +bmw +bmw +boS +bmw +bmw +boS +bmw +bmw +boS +bmw +bGv +ccu +byp +bAF +bWE +bQJ +bAF +bWE +ccu +ccL +bom +bop +bor +clD +clJ +clQ +clS +clV +cls +cmd +ckk +cko +aXz +aSx +aRV +aRV +bVo +cgP +cgV +bJv +chh +bVo +ccj +cli +coD +bQG +crb +cmv +bQG +crT +clj +csD +ciw +ciC +ciQ +bNg +bOC +caq +bOT +boV +aSx +aSL +ccV +wJY +ccW +ccV +cdb +cdd +cdf +cdf +cjQ +cde +cde +ctf +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpH +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(149,1,1) = {" +aac +bBP +bBP +bBP +bBP +bBP +bBP +bOD +cgU +ciN +cjB +cjB +cgU +bDp +bDp +cgU +cgU +cgU +cgU +cgU +csv +bDp +cgU +rni +rni +rni +rni +rni +rni +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aeC +aeO +afw +afU +agv +ahe +ade +aih +aiF +ade +ade +bGs +alx +baL +aal +aal +aal +aal +alo +alo +amg +alo +alo +amm +amM +app +aqi +aqi +arw +aqi +aqi +atC +aus +amM +avQ +amm +alo +alo +amg +alo +alo +cnB +aFq +aGl +aQG +aFK +aVo +aQG +aFK +aVo +aGl +biG +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +qPQ +bmw +bnN +bnP +bqh +brP +bnP +buN +bwe +bnP +bnU +bGv +ccu +byp +bTW +bWE +bQJ +bAF +bWE +ccv +ccU +bxW +bxX +bKN +bMd +clJ +cma +cma +cma +cma +cmd +ckl +ckp +clC +clY +clY +clY +clF +clG +clH +clI +cmt +clK +cco +bmO +coD +bQG +crb +cmv +bQG +cqT +cli +csd +boV +ciD +ciR +bOs +boV +cbu +ceU +boV +aSx +aSL +ccV +wJY +ccW +ccV +ccV +ccV +rxL +iQh +cjR +cde +cde +ccV +cnH +bdS +coU +aFK +aVo +aQG +aUY +aVo +aGl +cpH +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(150,1,1) = {" +aac +bGb +bHB +bJf +bJf +bJf +bJf +alv +cgU +cgU +cgU +cgU +cgU +bDp +bDp +cgU +cjB +cpS +cjB +cgU +csr +bDp +cgU +rni +rni +rni +rni +rni +rni +rni +aad +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aal +aal +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aad +aeC +aeP +afx +afV +agw +ahf +aie +aie +ajG +ahC +ahC +ajH +alz +baW +aal +aal +aal +aal +aal +alo +amh +alo +anl +anl +anl +anl +aqj +aqj +aqj +aqj +aqj +aqj +aqj +anl +anl +anl +anl +alo +amh +azp +cnB +cnB +aFq +aGl +aQG +aFK +aVo +aQG +aFK +aVo +aGl +biG +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +qPQ +bmw +bnO +boT +boT +boT +btx +buR +bwf +bnP +bnU +bGv +ccu +byp +bAF +bWE +bQJ +bUc +bWE +bFg +ccI +aXv +byE +bdw +bdx +clJ +clR +clT +baS +clX +cmd +ckm +ckq +aXz +aSx +aSL +bVo +bVo +bVo +bVo +chc +cmu +bVo +ccp +cli +coD +bQG +crb +cmv +bQG +cqT +cli +csd +boV +ciE +ciR +boV +boV +ccC +boV +boV +aSx +aSL +ccV +wJY +ccW +ccW +ccW +ccV +fCF +cdh +cjS +cdf +cdf +ctg +cvO +bdS +coU +aUm +aVo +aQG +aFK +aVo +aGl +cpH +bvU +bvU +bvU +bvU +bvU +bvU +bvU +cAJ +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(151,1,1) = {" +aac +aTz +aTz +aTz +aTz +aTz +aTz +bOD +cgU +ciO +bDp +bDp +bDp +bDp +bDp +bUr +cjB +cjB +cjB +cgU +cst +bDp +cgU +rni +rni +rni +rni +rni +rni +aad +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aac +aad +aad +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aeC +aeQ +afy +afW +agx +ahg +ahB +ahB +akn +bGr +bGr +bGt +alI +aso +aal +aal +aal +aal +aal +alo +amh +amm +anl +anD +anD +apq +anD +anD +arx +anD +arx +anD +anD +apq +anD +anD +anl +amm +amh +azp +cnB +cnB +aFq +aGl +aQG +aFK +aVo +aQG +aFK +aVo +aGl +biG +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +qPQ +bmw +bnP +boT +bqi +biF +bkb +bkX +blt +blu +bmA +bmG +bni +byA +bAF +bWE +bQJ +bAF +bWE +bFg +ccI +aXv +byE +bdx +beY +clJ +cma +cma +cma +cma +cmd +ckn +aZg +aXz +cms +aSL +bVo +bVw +cgR +cgX +chd +bLU +bMc +ccq +clj +cmv +bQG +crb +cmv +bQG +cqT +cli +csd +boV +cqx +cmp +bxf +bva +bqt +bqt +boV +aSx +aSL +ccV +wJY +ccX +ccY +ccW +ccV +fCF +cdh +cdi +cdi +cdi +cto +bgn +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpL +cos +cos +cos +cos +cos +cos +cos +cdn +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(152,1,1) = {" +aac +aTz +bXZ +bZJ +cbg +ccx +aTz +bOD +cgU +ciP +bDp +ckx +bDp +bDp +bDp +cgU +ciM +cjB +cjB +cgU +css +bDp +cgU +rni +rni +rni +rni +rni +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aac +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aeC +aeR +afz +afX +agy +aeC +aeC +aeC +aeC +aeC +aeC +aeC +akE +aso +aal +aal +aal +aal +aal +alo +amh +amL +anl +anD +aoE +apr +apr +apr +apr +asa +asM +asM +asM +asM +avR +anD +anl +amW +amh +azp +cnB +cnB +aFq +aGl +aQG +aUm +aVo +aQG +aFK +aVo +aGl +biG +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +qPQ +bmw +bnQ +boT +vyu +bjp +boT +eYQ +bwg +blN +bmE +cvi +cvo +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccI +aXv +bLS +clu +bUk +clZ +cmb +clU +clW +biC +cme +cmd +clA +aXz +aSx +aSL +bVo +cgL +cgS +bVo +che +ckr +bVo +aWM +cli +cnZ +bQG +crc +cmv +bQG +cqT +csk +csE +cix +cqy +cmq +cmA +cmA +cqL +bxg +boV +aSx +aSL +ccV +wJY +ccX +ccY +ccW +ccV +fCF +cdh +cdi +cde +cde +ccV +cnO +cow +coU +aFK +aVo +aQG +aFK +aVo +bfc +cpF +aal +aal +aal +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(153,1,1) = {" +aac +aTz +bYa +bZK +cbh +cbh +aTz +bOD +cgU +cgU +cgU +cgU +cgU +bDp +cmT +cgU +ciL +ciN +cjB +cgU +csu +bDp +cgU +rni +rni +rni +rni +rni +rni +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aac +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aeC +aeC +aeC +aeC +aeC +aeC +aad +aad +aal +aal +aal +aal +alt +alv +aal +aal +aal +aal +aal +alo +ami +amM +anl +anE +aoF +aps +aqk +apt +apt +asa +apt +apt +aut +avf +avS +awN +anl +aya +ayI +azp +cnB +cnB +aFq +aGl +aQG +aFK +aVo +aQG +aUY +aVo +aGl +biG +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +qPQ +bmw +bnR +boT +bqk +brR +btz +vyu +boT +bnP +bnU +bBU +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccI +aXz +aXz +aXz +aXz +aXz +aXz +aXz +aXz +aXz +aXw +bfb +aXz +aXz +aSx +aSL +bVo +cgM +cgM +bVo +bVo +bVo +bVo +ccr +cli +coE +cpz +cqk +cqk +crF +crU +cli +csd +boV +cqz +cqA +bqt +bqt +cqM +bqt +boV +aSx +aSL +ccV +wJY +ccX +ccY +ccW +ccV +fCF +cdi +cdi +cde +cde +csX +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +aGl +bAd +bAd +bAd +bAd +bAd +bAd +byv +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(154,1,1) = {" +aac +bGc +aTz +aTz +bKC +cbh +aTy +alv +cgU +ciL +cjB +cjB +cgU +bDp +bDp +cgU +cgU +cgU +cgU +cgU +bDp +bDp +cgU +rni +rni +rni +rni +rni +rni +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aac +aad +aal +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +acZ +alt +alv +aal +aal +aal +aal +aal +alo +amh +amN +anm +anD +aoH +apt +aqk +apt +apt +asb +apt +apt +auu +apt +avT +anD +axB +ayb +ayJ +azp +cnB +cnB +aFq +aGl +aQG +aFK +aVo +aQG +aFK +aVo +aGl +biG +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +qPQ +bmw +ecE +boT +boT +boT +boT +boT +boT +bnP +bqm +ajx +avu +bys +bxq +bRw +bYE +bxq +bRw +avu +aWJ +aWK +aWL +cdy +cdy +cdy +cdy +cdy +cdy +cdy +cdy +cef +ckB +cdy +cef +cef +cdy +ckI +clm +cdy +cdy +cdy +cdy +clw +cre +crf +cpc +crW +cso +cpc +csH +cre +ctO +boV +boV +boV +boV +bqt +cqN +bQt +boV +aSx +aSL +ccV +wJY +ccX +ccY +ccW +cdc +cde +cde +cde +cde +cde +ctp +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +cxA +cxA +cxA +cxA +cxA +cxA +aSx +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(155,1,1) = {" +aac +bGd +aDq +bJg +cbh +cbh +aTz +bOD +cgU +ciM +cjB +cjB +bUr +bDp +bDp +bDp +bDp +boM +bDp +bDp +bDp +bDp +cgU +rni +rni +rni +rni +rni +rni +rni +rni +rni +aad +aac +aac +aac +aac +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aac +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +alt +alv +aal +aal +aal +aal +aal +alo +amh +amO +anm +anD +aoI +apu +aqk +apt +apt +asa +apt +apt +auu +asN +avU +anD +axB +ayc +amh +azp +cnB +cnB +aFq +aGl +aQG +aFK +aVo +aQG +aFK +aVo +aGl +biG +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +qPQ +bmw +bnP +bnP +bnP +bnP +bnP +bnP +bnP +bwY +bmw +ajx +boq +bys +bOE +bSe +bYI +bxq +bRw +cct +ccH +cef +cef +cef +cef +cef +cef +ckf +cef +cef +cef +cef +cef +cef +cef +ckf +cef +ckZ +cln +cef +cef +cef +cef +clw +cpa +crf +cpc +crX +crg +cpc +csI +cre +ctO +boV +ciH +chu +bwl +bqt +bqt +cqS +boV +aSx +aSL +ccV +wJY +ccX +ccY +ccW +ccZ +cde +cde +cde +cde +cde +ctf +cnO +bdS +coU +aFK +aVo +aQG +aFK +bdM +aGl +cpF +cxA +cyb +cyL +czg +cyc +cxA +aSx +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(156,1,1) = {" +aac +bGe +bHC +aTz +bKD +bLT +aTz +bOD +cgU +ciN +cjB +cjB +cgU +bDp +bDp +bDp +bDp +bDp +bDp +bDp +bDp +bDp +cgU +rni +rni +rni +rni +rni +rni +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aac +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +alt +alv +aal +aal +aal +aal +aal +alo +amh +amP +anm +anF +aoJ +apv +apv +apv +apv +asa +asN +asN +asN +asN +avY +awO +axB +ayd +amh +azp +cnB +cnB +aFq +aGl +aQG +aFK +aVo +aQG +aFK +aVo +aGl +biG +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +alJ +qPQ +bmw +bnT +miw +bql +bnP +bnP +scv +bwh +pCu +bmw +ajx +avu +bys +bxq +bSf +cba +bxq +bSf +ccy +cdg +ceK +cjW +cjW +cjW +cjW +cjW +cjW +cjW +cjW +cjW +cjW +cjW +cjW +cjW +cjW +cjW +clk +clo +ceK +cjW +cjW +cjW +clx +cpb +crg +cpc +cpc +cpc +cpc +csI +cre +ctO +boV +bwk +bwk +boV +bqt +bqt +bqt +boV +aSx +aSL +ccV +wJY +ccW +ccW +ccW +cdc +evB +evB +evB +evB +evB +ccV +cnO +bdS +coU +aFK +aVo +aQG +aFK +aVo +aGl +aGl +cxB +cyc +cyc +cyc +cyc +cxA +aSx +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(157,1,1) = {" +aac +bGf +aTz +bJh +cqn +coN +bNh +bOF +cgU +cgU +cgU +cgU +cgU +bUr +bUr +cgU +bXw +bYj +bYL +bYL +car +bXw +cgU +rni +rni +rni +rni +rni +aad +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +alt +alv +aal +aal +aal +aal +aal +alo +amh +amQ +anm +anH +anD +anD +anD +aql +aql +aql +aql +anD +anD +anD +anD +awR +axB +ayd +amh +azp +cnB +cnB +aFq +aGl +aQG +aFK +aVo +aQG +aFK +aVo +aGl +biG +kAo +alJ +alJ +alJ +nEs +alJ +alJ +alJ +iaE +alJ +alJ +lpy +bmw +bnU +bnU +bqm +brT +brT +bnU +bnU +bnU +bmw +ajx +avu +bys +bxq +bxq +bxq +bxq +bxq +bxq +cdk +ceL +ceL +ceL +ceL +ceL +ceL +ceL +ckz +ceL +ceL +ceL +ceL +ceL +ceL +ceL +ckD +ceL +ceL +ceL +ceL +ceL +ceL +clL +cxF +cpc +cpc +cpc +cpc +cpc +csI +cre +ctO +boV +bxY +bxY +boV +boV +bwn +boV +boV +aSx +aSL +ccV +cdj +cjP +csP +ccV +ccV +ccV +ccV +ccV +ccV +ccV +ccV +cnO +bdS +tWU +aFK +aWt +aQG +aFK +aVo +aGl +aGl +cxB +cyc +cyc +cyd +cyd +cxC +aSx +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(158,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +rni +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +alt +alv +aal +aal +aal +aal +aal +alo +amh +amR +anm +anI +anD +anD +aql +asd +ary +asc +asO +aql +anD +anD +avZ +awS +axB +aye +amh +azp +cnB +cnB +aFq +aGl +aQG +aFK +aVo +aQG +aFK +aVo +aGl +biS +beE +beE +beE +beE +beE +beE +beE +beE +beE +beE +beE +beE +beE +beE +beE +beE +bfw +bfw +beE +beE +beE +beE +avu +avu +bys +bxq +bOE +bxq +bxq +bUA +ccz +cdl +cfe +cfe +cfe +cfe +cfe +cke +cfe +cfe +cfe +cfe +cfe +cfe +ckC +cfe +cfe +ckE +cfe +cfe +cfe +cfe +cfe +ckE +clM +cpJ +crh +cpc +cpc +cpc +cpc +crW +cre +coH +clv +cmk +cmw +clv +clv +clz +clv +clv +clz +clz +clv +clv +clv +clv +clv +clv +clv +clv +clv +clv +clv +clv +cvP +inO +cwU +cwZ +cwZ +cxc +cxd +cxe +aGl +cpF +cxC +cyd +cyc +cye +cye +cxD +aSx +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aad +aad +aad +aad +aad +aad +aac +"} +(159,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aGT +aGT +aGT +aad +aad +aad +aad +aad +aad +aad +aad +rni +aad +rni +rni +rni +rni +rni +aad +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +alt +alv +aal +aal +aal +aal +aal +alo +amh +amR +anm +anJ +aoK +anD +aql +aqU +arz +asd +asd +aql +auv +anD +awa +awT +axB +ayf +ayK +azp +cnB +cnB +aFq +aLG +aQG +aFK +aWt +bbv +aFK +aVo +bfc +biS +bfw +bfw +bfw +bfw +bfw +bfw +bht +bfw +bfw +bfw +bfw +bfw +bfw +bfw +bht +bfw +bfw +bfw +bfw +bfw +bfw +bfw +avu +boq +bys +bxq +bxq +bxq +bxq +bRw +ccF +ccH +cef +cef +cef +cef +cef +cef +ckg +cef +cef +cef +cef +cef +cef +cef +ckg +cef +cef +cef +cef +cef +cef +cef +clw +cqj +crf +cpc +cpc +cpc +cpc +crW +ctK +coH +clz +cml +cmx +clz +clz +clz +cmJ +clz +clz +clz +clz +clz +clz +clz +clz +cmJ +clz +clz +clz +clz +clz +clz +bgn +cow +coU +aFK +aVo +aZH +aFK +bdM +beB +cpF +cxD +cye +cyc +czh +czh +cxD +aSx +kld +cAM +cAQ +ctQ +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(160,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aGT +aGT +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +alt +alv +aal +aal +aal +aal +aal +alo +amh +amR +anm +anK +anD +anD +anD +aql +aql +aql +aql +anD +anD +anD +awb +awU +axB +ayg +amh +azp +cnB +cnB +aFq +aGl +aQG +aFK +aYV +aSw +aFK +aYV +aGE +biU +bgp +bgW +bgW +bgW +bgW +bgW +bgW +bgW +bgW +bgW +bhA +bgW +bgW +bgW +bgW +bgW +bgW +bgW +bgW +bgW +bgW +bgW +boa +bvV +bFe +bPu +bPu +bPu +bPu +cbU +ccG +cdm +chk +chk +chk +chk +chk +chk +chk +chk +chk +ckA +ckA +ckA +ckA +chk +ckA +ckA +ckA +ckA +ckA +clp +ckA +ckA +clN +crd +cri +crG +crY +crY +csG +csJ +ctL +ctP +cmf +cmm +cmy +cmB +cmB +cmB +cmB +cmB +cmP +cmB +cmB +cne +cmB +cmB +cmB +cmB +cmB +cmB +cmB +cmB +cmB +cmB +coh +xcA +coY +aFK +aYV +aSw +aFK +aVo +beB +cpF +cxE +cyf +cyc +cyc +cyc +cxE +aSx +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(161,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aGT +aGT +aGT +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +aad +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +ajv +aaP +ake +aal +aal +aal +aal +aal +alo +amj +amS +anl +anK +anD +apw +anD +anD +arA +anD +anD +atD +anD +avg +awc +awV +anl +ayh +amh +azp +cnB +cnB +aFq +aGl +aQG +aFK +aFK +aFK +aFK +aFK +aFK +bjn +bgP +bgP +bgP +bgP +bgP +bgP +bgP +bgP +bgP +bgP +bgP +bgP +bgP +bgP +bgP +bgP +bhC +bgP +bgP +bgP +bgP +bhD +boc +bxq +bxq +bxq +bxq +bxq +bxq +bRw +avu +cdo +bFN +bHd +bIO +bKq +bLK +bFS +bOr +bQd +bRV +bRV +bRV +bRV +bRV +bRV +bRV +bXg +bXY +bQd +bZp +cal +bYb +cdz +xJM +cre +crf +cpc +cpc +cpc +cpc +cpc +cxF +ctS +cmg +cmg +cmg +cmg +cmg +cmg +cmg +cmM +cmg +cmg +cmg +cmg +cmg +cmg +cmg +cmg +cmg +cmg +cmM +cmg +cmg +cmg +cnM +cht +ceP +aFK +aFK +aFK +aFK +aVo +pyF +cpF +cxA +cxA +cyM +czi +czi +cAk +aSx +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aac +"} +(162,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aGT +aGT +aGT +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +ajv +aaP +ake +amb +aal +aal +aqg +aqf +bQh +alo +amh +amm +anl +anl +aoM +anl +anl +aqV +anl +anl +asP +anl +auw +anl +anl +anl +anl +ayi +ayJ +azp +cnB +cnB +aFq +aGl +aQG +aFK +aFK +aFK +aFK +aVe +bdR +bjo +bgQ +bgQ +bgQ +bgQ +bgQ +bgQ +bhy +bgQ +bgQ +bgQ +bhB +bgQ +bgQ +bgQ +bgQ +bgQ +bgQ +bgQ +bgQ +bgQ +bgQ +bhN +bon +bxr +bFf +bxq +bUA +bFf +bxq +bRw +avu +cdo +bFO +bHe +bIP +bKr +aqp +bMY +bFS +bQe +bRW +bSL +bQe +bTK +bSL +bQe +bRW +bSL +bYb +qkz +bYz +bYz +bYz +bYb +coF +cre +crf +cpc +csl +crh +cpc +csl +ctM +ctT +cmh +cmh +cmh +cmh +cmh +cmF +cmh +cmh +cmh +cmh +cmh +cmh +cmh +cmh +cns +cmh +cmh +cmh +cmh +cmh +cmh +cnF +cnN +cox +coZ +aFK +aVe +aPv +aFK +aVo +beB +cpF +cnB +cxA +cyM +cyM +cyM +cxA +aSx +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aac +"} +(163,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aGT +aad +aGT +aGT +aGT +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +ajv +aaP +ake +aal +aal +aqg +cdq +aqg +aqg +ayF +alo +amh +amm +anl +anL +anD +anl +aqm +anD +anl +ase +anD +anl +aux +aux +awd +awW +anl +ayj +amh +azp +cnB +cnB +aFq +aGl +aSB +aFK +aFK +aFK +aFK +aVo +bfd +bgo +bfw +bfw +bfw +bfw +bfw +bfw +bhz +bfw +bfw +bfw +bfw +bfw +bfw +bfw +bhz +bfw +bfw +bfw +bfw +bfw +bfw +bfw +avu +byo +bHM +bxq +bSe +bys +bxq +bRw +avu +cdo +bFP +bHf +aHO +aHO +aqp +bck +bFS +bQg +bRX +bSK +bTm +bRW +bSK +bTm +bRW +bXh +bYb +bYA +bYz +bYz +bYz +cbY +coG +coH +cru +cpc +csm +crf +cpc +crW +ctN +ctU +clz +clz +clz +clz +clz +clz +cmK +clz +clz +clz +clz +clz +clz +clz +clz +cmK +clz +clz +clz +clz +clz +clz +bgn +coy +tWU +aFK +aWt +aQG +aFK +aVo +beB +cpF +cnB +cxA +cyN +czj +cyM +cxA +aSx +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aac +"} +(164,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aGT +aGT +aGT +aGT +aad +aGT +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +rni +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +ajv +aaP +ake +aal +aal +aqg +aqg +aqg +aqg +aqg +ayF +alo +amh +amm +anl +anM +aoN +anl +anM +aoN +anl +anM +aoN +anl +auy +avh +anl +anl +anl +ayk +amh +azp +cnB +cnB +aAe +bnX +bol +bqI +bqJ +brY +bqJ +brZ +bnX +bBK +bgR +bgR +bgR +bgR +bgR +bgR +bgR +bgR +bgR +bgR +bgR +bgR +bgR +bgR +bgR +bgR +bgR +bgR +bgR +bgR +bgR +bgR +avu +avu +bJs +bQK +bUB +bUB +bUB +ccs +avu +cdo +bFQ +bHg +bIQ +bKs +aqp +bcs +aBn +bvs +bRY +bvs +bvs +bRY +bvs +bvs +bRY +bvs +bYc +bYz +bYz +bYz +bfv +bjR +cuE +cuF +cuG +cuH +cuI +cuJ +cuH +cuK +cyr +cuL +cuM +aZa +cuO +cuP +cmz +cmi +cmi +cmN +cmi +cmi +cmi +cmz +cmz +cmz +cmi +cmi +cmi +cmi +cmi +cmi +cmi +cmi +coi +bdS +coX +cpo +aTV +aTV +aTV +cpw +beB +cpF +cnB +cxA +cyO +cyM +cyM +cxA +aSx +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(165,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aGT +aGT +aGT +aad +aGT +aGT +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aac +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +ajv +aju +aaP +ake +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amh +amm +anl +anN +anD +anl +aqn +anD +anl +asf +anD +anl +auz +aux +awe +awX +anl +amm +amh +azp +cnB +cnB +aAf +aGl +aQG +aFK +aFK +aFK +aFK +bdM +aGl +bjO +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bzs +bBU +bFg +bQJ +bAF +bWE +bYH +bAF +caZ +bFg +ccI +bFR +bHh +aqp +aqp +aqp +bct +bcx +bmI +bmI +bmI +bmI +bmI +bmI +bXB +bYp +bYp +cdD +cdE +cdE +cdE +bjz +cbZ +cbW +ckO +cmv +bQG +crb +crs +bQG +crZ +cli +csL +bGh +bGh +bJi +bKF +bJi +bGh +bGh +cmO +cmQ +cmQ +cmQ +cnf +cng +cnn +bWy +bWy +bWy +bWy +bWy +bYN +bWy +tBN +coj +bdS +coU +aFK +aVo +aZH +aFK +bdM +beB +cpF +cnB +cxA +cxA +czk +cxA +cxA +aSx +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(166,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aGT +aGT +aGT +aad +aad +aGT +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +rni +rni +aac +aad +aad +aad +rni +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aac +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aac +aac +aad +aad +aaw +ajw +ake +amb +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amh +aod +anl +anl +aoO +anl +anl +aqW +anl +anl +asQ +anl +anl +anl +anl +anl +anl +alo +ayM +azp +aBP +cnB +aAf +aPf +aQG +aFK +aFK +aFK +aFK +aVo +bff +bjP +aSy +bgV +aEl +aEU +aFW +aHo +aHM +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +bgV +aoe +aPp +aHo +aQX +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccI +bFS +bHi +bIR +bKt +aqp +aqp +bFS +bQi +bRZ +bRZ +bRZ +bRZ +bRZ +bui +bvs +bvs +bQj +bSM +bSM +bSM +bSM +cca +cbW +ckO +cmv +bQG +crb +cmv +bQG +crb +cli +csL +bGh +bHD +ciS +bKG +cjp +bNj +bGh +bOM +bSn +bOM +bOM +bDN +bEP +bQO +bWy +bXx +bYk +bWy +bZw +cas +cbv +bWy +coj +bdS +coU +aFK +aVo +aQG +aFK +aVo +beB +cpF +cnB +cxA +cyM +cyM +czG +cxA +cAE +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(167,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aGT +aGT +aGT +aGT +aGT +aad +aad +aad +aad +aad +aad +aad +aad +rni +aad +rni +rni +rni +aad +rni +aac +aad +aad +rni +rni +rni +rni +rni +aad +aac +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aac +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amh +amm +anl +anO +anD +anD +aqo +anD +anD +asg +anD +anD +auA +avi +avi +avi +auI +ayl +ayN +ayl +azI +azI +aHZ +alZ +aAA +aAP +aAP +aAP +aAP +aBl +cdt +aBW +aBQ +aBQ +aoe +aqp +aFX +aqp +aoe +aBQ +aBQ +aBQ +aBQ +aBQ +aBQ +aBQ +aBQ +aBQ +aBQ +aoe +auF +aQe +aQY +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccI +bFT +bFS +bFS +bFS +aEV +aEV +bOt +bQj +bSa +bSM +bSM +bSM +bUj +buB +bQj +bXi +bQj +bYB +bYB +bYB +cbk +ccb +cbW +ckO +cmv +bQG +crb +cmv +bQG +crb +cli +csL +bGh +bHE +bJk +bKH +bLV +bNk +bGh +bQu +bSo +bSP +bTu +bDN +bEP +bQO +bWy +bXy +bYl +bYM +bZx +bZx +cbw +bWy +coj +bdS +coU +aUm +aVo +aQG +aFK +aVo +beB +cpF +cpT +cxA +cyP +czl +czl +cxA +cAF +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(168,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aGT +aad +aGT +aGT +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +aad +rni +aad +rni +rni +rni +rni +rni +rni +rni +aad +rni +rni +aad +rni +aad +aGT +aad +aGT +aad +aad +aad +aad +aad +aal +aal +aad +aad +rni +aac +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqh +aqh +aqh +bQU +alo +amh +amT +anl +anP +anD +apx +aqq +aqX +arB +arB +arB +arB +auB +avj +awf +awZ +axC +aym +ayO +aym +aym +aAa +bjN +aAr +aAB +aAQ +aAQ +aAQ +aAQ +aBm +aBB +aBX +aCw +aAE +aEm +azo +aFY +azo +aEm +aAE +aAE +aAE +aAE +aAE +aKW +aAE +aAE +aAE +aAE +aOx +aPq +aQf +aQZ +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccI +bFO +bHj +bIS +bKu +aIF +aIF +bOu +bQk +bSb +aTh +aTh +aTh +aTh +bYd +bWr +aTh +bYe +bYB +bZq +cam +cbl +ccc +cbW +cli +cmv +bQG +crb +cmv +bQG +cqT +cli +csL +bGh +bHF +bJl +bKI +bLW +bNl +bOG +bQv +bSp +bSQ +bTv +bDN +bEP +bQO +bWy +bWy +bWy +bWy +bZy +bZx +bZx +cci +coj +bdS +coU +aFK +aVo +aQG +aFK +aVo +beB +cpF +cnB +cxA +cxA +cxA +cxA +cxA +cAG +kld +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(169,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aGT +aad +aGT +aGT +aGT +aad +aad +aGT +aad +aad +aad +aad +aad +aad +aad +rni +rni +aad +aGT +rni +aGT +rni +rni +rni +rni +rni +rni +rni +aad +aGT +aac +aad +aad +aGT +aad +aad +aal +aal +aal +aad +aad +rni +rni +rni +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aad +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +ayF +akz +akQ +alf +alo +alo +amk +alo +anl +anl +aoP +anl +anl +anl +arC +ash +ash +arC +arC +avi +awg +axa +auI +auI +auI +auI +auI +vgD +aAg +aAg +aVr +aAR +aAR +aAR +aAR +aBo +aAg +aAg +aoe +aoe +aoe +aEV +aFZ +aEV +aoe +aoe +aJr +aJY +aJY +aKJ +aKJ +aLF +aLF +aJr +aoe +aoe +aPr +aoe +aoe +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccI +bFP +bHk +bIT +bKv +aIF +aIF +bOv +bQl +aTh +aTh +bTn +bTL +clB +buT +bWs +bWs +bWs +bWs +bWs +bWs +bWs +bWs +cbW +cli +cmv +bQG +crb +cmv +bQG +cqT +cli +csL +bGh +bHG +bJk +bKJ +bLX +bNm +bGh +bQw +bSq +bSR +bTv +bDN +bEP +bEV +cqC +cqC +cqR +bWy +bZz +cat +cat +ceZ +cok +coK +coW +aFK +aVo +aQG +aFK +aVo +beB +cpF +cnB +aal +aal +aal +aal +aal +aal +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(170,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +rni +aGT +aGT +rni +rni +aGT +aGT +aGT +aGT +aGT +aGT +aal +aal +aad +aad +rni +rni +rni +aac +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aad +aad +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +ayF +akA +akR +ali +alp +alQ +amh +amm +anl +anQ +anD +apy +aqr +anl +arD +asi +asi +atE +arC +avk +awg +axb +axD +ayn +ayP +azq +azJ +aAb +aAg +aAg +aAD +aAS +aAS +aAS +aAS +aBp +aAg +aAg +aoe +aDz +aoe +aqp +ayu +aqp +aoe +aoe +aoe +aoe +aoe +aoe +aoe +aoe +aoe +aoe +aoe +aoe +aPs +aBQ +bzs +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bTW +bWE +bFg +ccI +bFQ +bHl +bIU +bKw +aIF +aIF +bOw +bQm +aTh +aTh +bSb +btA +btF +bYn +bWt +buW +buX +bYC +bZr +can +cbm +ccd +cbW +cli +cmv +bQG +crb +cmv +bQG +crb +csp +csM +ciy +bHH +bJm +bKK +bLY +bNn +bOH +bQx +bSr +bSR +bTv +bDN +bQO +bSl +bSl +bSl +bTO +bYN +bZA +cau +cbx +bWy +coj +bdS +coU +aFK +aVo +aQG +aFK +cpq +beB +cpF +cvS +cvS +cvS +cvS +cvS +cvS +cvS +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(171,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +pqW +aGT +fkS +rni +rni +rni +rni +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aad +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +ayF +akA +akS +ali +ali +alQ +amh +amm +anl +anR +anD +anD +anD +aqY +arE +arE +asR +atF +auC +avj +awh +axc +axE +ayo +ayo +azr +azK +aAb +aAg +aAg +aAC +aAR +aAR +aAR +aAR +bfe +aAg +aAg +aoe +aDA +aoe +aoe +aGa +aoe +aoe +aID +aJs +aJZ +aKC +aKK +aKX +bLL +aMf +aMO +aoe +aJr +aPs +aBQ +bzs +bzs +bBU +bMn +bQJ +bAF +bWE +bQJ +bAF +bWE +ccw +ccI +bFT +bFS +bFS +bFS +bLM +bLM +bOt +bQj +bSa +bSN +bSM +btB +bSM +bVs +bWs +bXk +buY +bYg +bYg +cao +cbn +cce +cbW +ckO +cmv +bQG +crb +cmv +bQG +crb +cli +csL +bGh +bHI +bJn +bKG +bJk +bNo +bOI +bQy +bSs +bSR +bTw +bDN +bQO +bSl +cqK +bSl +bTO +bWy +bZB +cav +cby +bWy +coj +coL +coU +aFK +aVo +aQG +aFK +aVo +beB +cpF +cvS +czH +cyQ +czm +cyg +cAl +cvS +brL +cAM +cAQ +ctQ +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(172,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aGT +aal +aal +aGT +aal +aal +aal +aal +aal +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aGT +aal +aal +rni +rni +rni +rni +aad +rni +rni +rni +rni +rni +rni +rni +rni +fkS +fkS +ggz +aGT +aGT +fkS +rni +rni +rni +rni +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aad +aal +aal +acZ +aal +aqg +aqg +aqg +aqg +aqg +aqg +ayF +akA +akW +ali +ali +alQ +amh +amm +anl +anQ +aoR +aLE +anQ +anl +baX +arE +asS +atG +auD +avl +awi +axd +axD +ayp +ayQ +azs +gIU +aAb +aAg +aAg +aAC +aAR +aAR +aAR +aAR +aBo +aAg +aAg +aoe +aDB +aEn +aEX +aGb +azo +aHN +azo +azo +azo +azo +azo +azo +azo +aMg +aMP +aoe +aoh +aPs +aBQ +bzs +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccI +bFU +bHm +bHm +bKx +bHm +bHm +bOx +bQn +bSg +bSg +bSg +btC +bSg +bSg +bWs +bXl +buZ +bYD +bZs +cao +cbo +ccf +cbW +ckO +cmv +bQG +crb +cmv +bQG +crb +cli +csL +bGh +bHJ +bJo +bKG +bJk +bNp +bOI +bQy +bSs +bSS +bOM +bDN +bQO +bSl +bSl +bSl +bTO +bWy +bZC +caw +cbz +bWy +coj +bdS +coU +aFK +aVo +aQG +aFK +aVo +beB +cpF +cvS +cyh +cyR +cyR +czI +cwj +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(173,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aal +aGT +aal +aal +aal +aal +aal +aal +aal +aal +aal +aGT +aal +aGT +aal +aGT +aal +aal +aal +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +poQ +aGT +aGT +dgB +fkS +rni +rni +rni +aac +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aad +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +ayF +akF +akY +alj +alq +alR +aml +amU +ann +ann +ann +ann +ann +ann +arG +arE +asT +atJ +auE +avm +awj +axe +auI +auI +auI +auI +auI +ssr +aAg +aAg +aAC +aAR +aAR +aAR +aAR +aBo +aAg +aAg +aCx +aqp +aEo +aqp +aqp +aqp +aHO +aIE +aqp +aqp +aqp +aqp +aqp +aqp +aqp +aMQ +aoe +aoh +aPs +aBQ +bzs +bzs +bBU +bFg +bQJ +bTW +bWE +bQJ +bAF +bWE +bFg +ccI +bFV +bHm +bIV +bIV +bIV +bHm +bOx +bQo +bQo +bQo +bQo +btD +bQo +bQo +bWs +bXm +buZ +bYG +bZs +cap +cbp +ccg +chm +ckO +cmv +bQG +crb +cmv +bQG +crb +cli +csL +bGh +bHK +bJp +bKL +bLZ +bNq +bGh +sol +bSs +bST +bOM +cqu +bEP +bDB +bDB +bDB +bQO +bWy +bWy +cwc +bWy +bWy +coj +bdS +coU +aFK +aVo +aQG +aUm +aVo +beB +cpF +cvS +cyi +cyR +cyR +cwa +cvY +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(174,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +rni +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +rni +fkS +aGT +aGT +aGT +aGT +rni +fkS +rni +rni +rni +rni +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aad +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +ayF +akJ +akW +ali +ali +alQ +amm +amm +ann +anS +aoS +apz +aqs +aqZ +arH +arE +asS +atK +auG +avn +awg +axb +axD +ayq +ayP +azt +azJ +aAb +aAg +aAg +aAC +aAR +aAR +aAR +aAR +aBo +aAg +aAg +aCy +aqp +aEo +aqp +aqp +aqp +aHP +aHO +aHO +aKa +aKD +aKL +aKY +aHO +aHO +aHO +aoe +aOy +aPt +aBQ +bzs +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccI +bFW +bHn +bIW +bIW +bIW +bHm +bOy +bQo +bQo +bQo +bTo +btD +bUl +bVt +bWs +bXn +buZ +bYg +bYf +bYg +cbq +cch +chn +ckO +cmv +bQG +crb +cmv +bQG +crb +cli +csL +bGh +bHL +bJq +bKM +bMa +bNr +bGh +bQy +caI +cec +coM +ctn +bSt +cvZ +cvZ +cvZ +cvZ +cue +cuj +cwd +cue +cuj +col +cov +coU +aUY +aVo +aQG +aFK +aVo +beB +cpF +cvS +cyj +cyS +czn +czK +cwl +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +aac +"} +(175,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +rni +rni +rni +rni +aad +rni +rni +rni +rni +rni +rni +rni +fkS +uSq +aGT +aGT +sgT +aGT +aGT +nlJ +rni +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aad +aad +aad +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +ayF +akJ +akZ +ali +ali +alQ +amm +amm +ann +anT +aoT +apA +apF +ara +arE +arE +asS +atL +auH +avn +awk +axc +axF +ayo +ayo +azr +azK +aAb +aAg +aAg +aAC +aAR +aAR +aAR +aAR +aBo +aAg +aAg +aCx +aqp +aEo +aqp +aqp +aqp +aqp +aqp +aqp +aqp +aqp +aqp +aqp +aqp +aqp +aMR +aoe +aOz +aPs +aBQ +bzs +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccI +bFU +bHm +bIX +bIX +bIX +bHm +bOy +bQo +bQo +bQo +bTp +btD +bUm +bSi +bWs +bXo +bvF +bwd +bwi +bwx +cbr +ccd +chn +ckO +cmv +bQG +crb +cmv +bQG +crb +cyt +csN +ciz +cuN +ciT +bCX +cjq +bJr +bOH +bQB +caJ +bSV +bTy +cqv +cqB +bVD +ced +cen +cev +ceC +crv +csF +cuf +cuk +com +beB +coU +aFK +aVo +aQG +aFK +aVo +cxs +cpF +cvS +cyk +cyT +cyT +czL +cAm +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +rvT +iAN +uMK +wxM +uMK +uMK +uMK +uMK +uMK +iAN +uMK +uMK +uMK +uMK +iAN +rvT +aac +"} +(176,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +rni +aad +aad +rni +rni +rni +rni +rni +rni +rni +rni +rni +nlJ +uZJ +aGT +aGT +dgB +aGT +uZJ +fkS +rni +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aad +aad +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +ayF +akJ +akR +ali +alr +alQ +amm +amm +ann +anU +aoU +apB +apF +ara +arE +arE +asS +atM +auE +avn +awg +axd +axD +ayp +ayQ +azs +azL +aAb +aAg +aAs +aAC +aAR +aAR +aAR +aAR +aBo +aAg +aAg +aoe +aDB +aEo +aFf +aFf +aFf +aFf +aIF +aIF +aKb +aIF +aqy +aqy +aqy +aqy +aMS +aoe +aOB +aPs +aBQ +bzs +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccI +bFV +bHm +bHm +bHm +bHm +bHm +mXT +bQp +bSh +bQo +bQo +btD +bUn +bVu +bWs +bWs +bYh +bWs +bWs +bwz +bWs +bUs +ccr +ckO +cmv +bQG +crb +cmv +bQG +crb +ckO +csL +bGh +bHO +ciU +bKO +cjr +bNs +bOK +cjA +bSv +bSR +bOM +bDN +bQO +bVJ +cee +ceo +ceo +ceD +bWB +csK +cug +bDN +biS +beB +coU +aFK +aVo +aQG +aFK +aVo +cxt +bkl +cxu +cxv +cwl +cwl +czM +cAn +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +rvT +uMK +iAN +uMK +uMK +uMK +iAN +uMK +wxM +uMK +uMK +uMK +uMK +wxM +uMK +rvT +aac +"} +(177,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +acZ +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +rni +aac +aac +aac +rni +rni +rni +rni +rni +rni +rni +fkS +fkS +wjp +uZJ +aGT +ett +aGT +fkS +rni +rni +rni +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +ayF +akK +akQ +alf +alo +alo +amn +alo +ann +anV +aoU +apC +aqt +aqZ +arI +asj +asU +atN +auE +avn +awl +axf +auI +auI +auI +auI +auI +lcg +aAg +aAg +aAC +aAR +aAR +aAR +aAR +aBo +aAg +aAg +aoe +aqp +aEo +aFg +aGc +aHp +aHQ +aIG +aJt +aKc +aKE +aKM +aKZ +aLH +aMh +aqp +aoe +aOC +aPs +aBQ +bzs +bzs +bBU +bFg +bQJ +bTW +bWE +bSw +bAF +bWE +bFg +ccI +bOx +bFr +bOx +bHp +bOx +bHq +bOx +bQq +suS +bQo +bQo +btD +bUl +bVt +bOx +bFn +bPw +bPw +bPw +bTX +bVx +bVx +chr +bQG +cmv +bQG +crb +cmv +bQG +crb +ckO +csL +bGh +bHP +ciV +bGh +cjs +bGh +bGh +cjC +bSv +bSR +bTu +bDN +bEP +ceb +ceg +ceg +ceg +ceE +bDP +ctV +cuh +bEV +biS +beB +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +cvS +cym +cwl +cwl +czM +cAo +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +rvT +uMK +uMK +iAN +edV +uje +uMK +uMK +uMK +uMK +uMK +duf +uMK +uMK +iAN +rvT +aac +"} +(178,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +bKW +aal +aal +aal +aal +aal +aac +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +fkS +rni +fkS +rni +aGT +uZJ +rni +fkS +aad +rni +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqf +aqf +aqf +bQh +alo +amm +amV +ann +anW +aoU +apB +aqu +ann +arC +arC +arC +arC +arC +avn +awg +axb +axD +ayr +ayP +azu +azJ +aAb +aAg +aAg +aAC +aAR +aAR +aAR +aAR +aBo +aAg +aAg +aoe +aDC +aEo +aFg +aGd +aHq +aHQ +aIG +aJu +aKd +aKE +aKM +aLa +aLI +aMh +aqp +aoe +aOD +aPs +aBQ +bzt +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccI +bOx +bFX +bOx +bFX +bOx +bFX +bOx +bQr +bSi +bQo +bQo +btD +bSi +bVv +bOx +bFo +bQF +bQF +bQG +bUx +bQG +bQG +ciF +bQG +cmv +bQG +crb +cmv +bQG +crb +ckO +csO +bWu +bWD +bZD +bWu +bWu +cfa +bOM +cjD +bSv +bSR +bTv +bDN +bQO +bVJ +ceh +cep +cew +ceF +bLu +caC +bLu +bLu +coj +beB +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +cvS +cyn +cwl +cwl +czN +cAp +cvS +brL +cAM +cAQ +ctQ +aal +acZ +aad +aad +rvT +uMK +mrJ +uMK +edV +lNo +uMK +edV +txa +peF +uMK +edV +lNo +mrJ +uMK +rvT +aac +"} +(179,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aal +aan +aan +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aac +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +fkS +rni +rni +rni +rvZ +rni +rni +fkS +aad +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amm +amm +ann +anX +aoU +apB +aqv +ann +arJ +ask +asV +atO +auI +avo +awm +axc +axG +ayo +ayo +azr +azK +aAb +aAg +aAg +aAC +aAR +aAR +aAR +aAR +aBo +aAg +aAg +aoe +aDD +aEp +aFg +aGe +aHr +aHQ +aIG +aJv +aKf +aKE +aKM +aLb +aLJ +aMh +aqp +aoe +aOE +aPs +aBQ +bzs +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccI +bOx +bHo +bOx +bHo +bOx +bHo +bOx +bQs +bSk +bQo +bQo +chw +bUn +bSk +bOx +bGN +bQG +bQG +bQG +bUx +bQG +bQG +ciG +ckO +cmv +bQG +crb +cmv +bQG +crb +ckO +csd +bWy +bHR +ciX +bWy +bWy +bKV +bOM +cjE +caK +ceG +csn +cvV +cvW +cwb +cei +ceq +cex +bVJ +bZF +cwk +cwO +bLu +coj +beB +coU +aFK +cpq +aQG +aFK +aVo +aGl +cpF +cvS +cyo +cyU +cwl +czM +cAq +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +rvT +uMK +mrJ +uMK +edV +nRW +nRW +edV +txa +peF +iAN +edV +lNo +mrJ +uMK +rvT +aac +"} +(180,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aal +aao +aze +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aad +rni +rni +rni +rni +ryV +nlJ +rni +fkS +rni +rni +ryV +uZJ +fkS +fkS +rni +rni +rni +rni +rni +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amm +amm +ann +anY +aoU +apD +apF +arb +arK +asl +asl +atP +auJ +avi +awg +axd +axD +ayp +ayQ +azs +azL +aAb +aAg +aAg +aAC +aAR +aAR +aAR +aAR +aBo +aAg +aAg +aoe +aDD +aEp +aFg +aGf +aHs +aHQ +aIG +aJw +aKi +aKE +aKM +aLc +aLK +aMh +aqp +aoe +aOE +aPs +aBQ +bzs +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccI +bOx +bOx +bOx +bOx +bOx +bOx +bOx +bOx +bOx +bOx +qua +bOx +bOx +bOx +bOx +bFo +bQF +bQF +bQG +bUx +bQG +bQG +ciG +ckO +coE +cqk +cqk +cqk +cqk +csa +ckO +ckO +bGl +bHS +ciY +bKP +bMe +cgK +bOM +cjF +bSv +bSR +bTv +bDN +mtg +bVF +cej +cer +cey +bVJ +bZG +caE +cbD +bLu +coj +cwR +coU +aFK +aVo +aQG +aFK +cpq +aGl +cpF +cvS +cyp +cyV +czo +czO +cAn +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +rvT +uMK +mrJ +uMK +txa +uMK +iAN +uMK +uMK +uMK +uMK +duf +uMK +mrJ +uMK +rvT +aac +"} +(181,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aal +aap +aap +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aad +rni +rni +rni +rni +rni +oTd +aGT +rni +aGT +lUa +ryV +rvZ +aGT +aGT +ryV +aad +rni +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amm +amm +ann +anZ +aoU +apB +aqw +arc +arK +asl +asl +atQ +auI +avn +awg +axg +auI +auI +auI +auI +auI +kWd +aAg +aAg +aAC +aAR +aAR +aAR +aAR +aBo +aAg +aAg +aoe +aDD +aEp +aFg +aGg +aHt +aHQ +aIG +aJx +aKk +aKE +aKM +aLd +aLL +aMh +aqp +aoe +aOE +aPt +aBQ +bzs +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +bst +byB +byD +bDw +bDB +bDB +bDB +bDB +bDB +bHs +bDB +bEP +bDB +bDB +bDB +bSm +bMm +bRn +bSc +bQG +bUx +bQG +bQG +cjk +clO +cpd +cql +cql +crw +cql +csb +csq +clO +bGm +bHT +bJw +bKQ +bWy +bKV +bOM +cjG +bSv +bSR +bTw +bDN +txb +bVG +cek +ces +cez +bVJ +bZH +caF +cbE +bLu +coj +beB +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +cvS +cyq +cyw +cwl +czM +cAo +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +rvT +uMK +uMK +uMK +uMK +uMK +iAN +kge +uMK +wxM +uMK +uMK +uMK +uMK +uMK +rvT +aac +"} +(182,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aad +rni +rni +rni +ryV +aGT +dgB +lEt +aGT +uZJ +rvZ +uZJ +uZJ +dts +dgB +ryV +aad +aad +rni +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aal +aal +acZ +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amm +amm +ann +aoa +aoV +apE +aqx +ann +arL +asm +asm +atR +auI +avn +awg +axb +axD +ays +ayP +azv +azJ +aAb +aAg +aAg +aAC +aAR +aAR +aAR +aAR +aBo +aAg +aAg +aoe +aDD +aEp +aFg +aGo +aHu +aHQ +aIG +aJy +aKl +aKE +aKM +aLe +aLM +aMh +aMT +aoe +aoh +aPs +aBQ +bzs +bzs +bBU +bFg +bSw +bAF +bWE +bQJ +bAF +bWE +bFg +btE +byC +byQ +byQ +byQ +byQ +byQ +byQ +byQ +bHN +bJx +bEP +byQ +byQ +byQ +byC +bNi +bNi +bNi +bNi +bUx +bNi +bNi +cjt +bWy +bWy +bAX +bAX +bAX +bAX +bEo +bWy +bWy +ciA +ciI +ciZ +bKR +bWy +bKV +bOM +cjH +cjL +cjN +bOM +bDN +txb +bVG +cel +cet +ceA +bVJ +bZI +caG +cbF +bLu +coj +beB +coU +aFK +aVo +aQG +aFK +aVo +aGl +cpF +cvS +cym +cwl +cwl +czN +cAp +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +rvT +uMK +wxM +uMK +uMK +uMK +uMK +uMK +uMK +uMK +uMK +uMK +uMK +kge +uMK +rvT +aac +"} +(183,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aan +aan +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +rni +rni +rni +ryV +jIs +uZJ +uZJ +dgB +dgB +oTd +ryV +fKS +rvZ +aGT +ryV +rni +rni +rni +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amm +amm +ann +aob +aoY +apF +aqz +ano +ano +ano +ano +ano +ano +avn +awk +axc +axH +ayo +ayo +azr +azK +aAb +aAg +aAg +aAC +aAR +aAR +aAR +aAR +aBo +aAg +aAg +aoe +aDD +aEs +aFh +aFf +aFf +aFf +aIF +aIF +aIF +aIF +aqy +aqy +aqy +aqy +aqp +aoe +aoh +aPs +aBQ +bzs +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bUc +bWE +bFg +ccI +aZi +aZi +aZi +aZi +aZi +aZi +aZi +aZi +aZi +bDN +bQO +bTM +bTM +bTM +bTM +bTM +bTM +bTM +bTM +bxc +bTM +bTM +bKV +bWy +sMS +bgY +bgY +bgY +bgY +bAc +cha +cir +bWy +bHV +cja +bKS +bMf +chv +bDB +cjg +cbC +cjv +bDB +bEP +txb +bVI +cem +ceu +ceB +bVJ +bLu +caH +bLu +bLu +coj +beB +coU +aUm +aVo +aQG +aFK +aVo +aGl +cpF +cvS +cyn +cwl +cwl +czM +cAq +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +rvT +uMK +uMK +uMK +edV +edV +edV +uMK +uMK +uMK +uMK +edV +lqC +uwi +iAN +rvT +aac +"} +(184,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aGU +aIA +aIA +aIA +aIA +aIA +aal +aal +aal +aal +aao +aze +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +rni +rni +rni +ryV +rni +ryV +rni +ryV +rni +rni +ryV +aGT +aGT +oTd +rni +rni +rni +rni +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amo +amW +ano +ano +ano +apK +ano +ano +arM +asn +asW +atS +auK +avn +awg +axd +axD +ayp +ayQ +azs +azL +aAb +aAg +aAg +aAC +aAR +aAR +aAR +aAR +aBo +aAg +aAg +aoe +aoe +aEn +aFi +aEX +aEX +aEX +aEX +aEX +aEX +aEX +aEX +aEX +aEX +aMi +aqp +aoe +aJr +aPs +aBQ +bzs +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccI +aZi +aZt +aXB +aXB +aZt +aXB +aXB +aZt +aZi +bDN +bQO +bTM +bUo +bVB +bWw +bXu +bTM +bYJ +bZu +cdJ +cbs +bTM +bKV +bWy +sMS +bgY +bgY +bCN +bgY +bAc +bAc +bAY +bWy +bHW +cjb +bKT +bMg +chv +bEP +cjg +cbC +cjv +bEP +bEP +txb +bVJ +bVJ +bVJ +bVJ +bVJ +crV +cwm +cwP +cwP +cwQ +cwS +fCo +aFK +aVo +aQG +aFK +aVo +aGl +cpF +cvS +cym +cwl +cwl +czM +cwl +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +rvT +uMK +uMK +iAN +uMK +uMK +uMK +uMK +uMK +iAN +uMK +uMK +uMK +uMK +uMK +rvT +aac +"} +(185,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aGV +aIA +aIA +aIA +aIA +aIA +aal +aal +aal +aal +aap +aap +aal +aal +aal +wgK +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +ryV +nlJ +ryV +rni +ryV +rni +rni +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amm +amW +ano +aoc +aoZ +apb +aqA +ano +arN +asp +arN +atT +auK +avn +awg +axh +auI +auI +auI +auI +auI +auI +aAg +aAg +aAC +aAR +aAR +aAR +aAR +aBo +aAg +aAg +aAg +aoe +aEt +aqp +aqp +aqp +aHS +aqp +aqp +aqp +aqp +aHS +aqp +aqp +aMj +aMU +aoe +aoe +aPu +aBQ +bzs +bzs +bBU +bMn +bQJ +bAF +bWE +bQJ +bAF +bWE +ccw +cdp +aXC +aZl +aZm +aZm +aZm +aZm +aZm +aZn +aZo +bJz +bJz +aZs +bWH +bWH +bWH +bWH +bWF +bWH +bWH +cdK +cbt +bTM +bKV +bWy +bAe +bAY +bBL +bAY +bBL +bAc +bAc +cis +bWy +bHX +cjc +bKU +bMh +chv +bEV +cjh +cbC +cjv +bEV +bEV +tTe +cDt +enm +cqC +cqC +cqC +bEV +cww +bEP +bEV +con +beB +aQG +aFK +aVo +aQG +aFK +aVo +aGl +cpF +cvS +cys +cyQ +cyQ +czQ +cwl +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +rvT +uMK +iAN +uMK +uMK +uMK +uMK +mrJ +mrJ +mrJ +uMK +uMK +uMK +uMK +uMK +rvT +aac +"} +(186,1,1) = {" +aac +aad +aad +aad +aad +aad +aET +aET +aET +aET +aGV +aIA +aIA +aIA +aal +aal +aal +bKW +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aal +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +rni +aad +rni +aad +rni +rni +rni +rni +rni +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aad +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amm +amX +ano +arF +uyg +apb +aqB +ard +aqB +asq +asX +atU +auL +avj +awn +avi +axI +ayt +ayR +azw +azM +axI +amy +amy +aAF +aAu +aAu +aAu +aAu +aBq +amy +amy +aAg +aoe +aoe +aoe +aoe +aoe +aoe +aCy +aJz +aJz +aCy +aoe +aoe +aoe +aoe +aoe +aoe +aAg +aPw +aBA +bzs +bzs +bBU +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccD +aXD +aJF +aly +aly +aly +aly +bbd +bsd +aZi +bDN +bQO +bTM +bUq +bVC +bWx +bXv +bTM +bYK +bZv +bUp +bUp +bTM +bKV +bWy +sMS +bAZ +bAZ +bAZ +bAZ +bAc +bET +cit +bWy +rvS +bJy +cdY +bWy +ciB +bDF +cjI +cjM +cjO +bTz +bTQ +bUt +bDF +xyb +bDF +bDF +bDF +bDF +cjO +bNy +bDF +coo +beB +aQG +aFK +aVo +aQG +aFK +aVo +aGl +aGl +cvS +qcq +cyY +cyY +czS +cAs +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +rvT +uMK +edV +lNo +uMK +wxM +uMK +uMK +uMK +uMK +uMK +edV +edV +nRW +edV +rvT +aac +"} +(187,1,1) = {" +aac +aad +aad +aad +aad +aad +aET +cwl +cwl +aNE +aTC +aIA +aXT +aIA +aIA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aal +aad +aad +aad +aad +aac +aad +aad +aad +rni +rni +rni +aad +aad +aad +rni +rni +rni +aad +aad +rni +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aad +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amm +amX +ano +aof +apc +apL +aqC +ano +arO +asr +arN +atV +auK +avn +awp +avj +axJ +ayv +ayv +ayv +ayv +axJ +aAh +aAt +aAG +aAu +aAu +aAu +aAu +aBr +aBC +amy +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aPw +aQg +bzu +bzu +bFg +bFg +bQJ +bAF +bWE +bQJ +bAF +bWE +bFg +ccD +baT +baV +aly +aly +aXB +aly +bbe +aXB +aZi +bDN +bQO +bTM +bTM +bTM +bTM +bTM +bTM +bTM +bTM +bTM +bTM +bTM +bKV +bWy +sMS +bAc +bAc +bCO +bAc +bAc +bAc +cit +bWy +rgC +bZE +cay +ceV +ciJ +bDF +cjJ +cck +cAr +bQQ +bQQ +bQQ +bVM +bWI +bXC +bYq +bYO +bZM +cwx +bQQ +ccl +coj +beB +aQG +aFK +aVo +aZJ +aFK +aVo +aGl +cpF +dhz +cym +cwl +cwl +kBi +cwl +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +rvT +uMK +edV +lNo +lqC +peF +uMK +uMK +iAN +uMK +uMK +uMK +uMK +uMK +uMK +rvT +aac +"} +(188,1,1) = {" +aac +aad +aad +aad +aad +aad +aET +aHm +cwl +aNF +aTC +aVC +aXU +bbk +aIA +aIA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aad +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amm +amY +ano +ano +ano +ano +ano +ano +arP +ass +asY +atW +auK +avp +awq +avi +axI +ayw +ayS +ayS +azN +axI +aAi +aAu +aAH +aAu +aAu +aAu +aAu +aAu +aBD +amy +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aPx +alZ +bzv +bFg +bFg +bFg +bQJ +bUc +bWE +bQJ +bAF +bWE +bFg +ccD +bbb +bbg +aly +aly +aXB +aly +bbe +aXB +aXD +bDN +bEP +bDB +bDB +bDB +bDB +bDB +bDB +bDB +bDB +bDB +bDB +bDB +bMi +bWy +bWy +bWy +bWy +bWy +bWy +bEp +bEp +ciu +bWy +nma +bEP +bUb +bMi +bDF +bDF +cjK +ccM +cAr +bQQ +bQQ +bQQ +bQQ +bWJ +bXD +bYr +bYP +bZN +cwy +bQQ +ccm +coj +beB +aQG +aFK +aYV +aSw +aFK +aVo +bfd +cpF +cvS +sOG +yiY +cwl +szb +cwl +cvS +brL +cAM +cAQ +ctQ +aal +aal +aad +aad +rvT +uMK +edV +lNo +edV +peF +uMK +uMK +uMK +uMK +uMK +uMK +iAN +uMK +uMK +rvT +aac +"} +(189,1,1) = {" +aac +aad +aad +aad +aad +aad +aET +aHn +cwl +cqI +aTC +aIA +aXV +aIA +aIA +aIA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aad +aal +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amm +amY +anp +aog +apd +apM +aqG +ano +ano +ano +ano +ano +ano +avn +awg +axb +axK +ayx +ayT +azx +azO +axI +aAj +aAv +aAI +aAT +aAT +aAT +aAT +aAu +aBr +aBY +aCz +aCz +aCz +aCz +aCz +aCz +aCz +aCz +aCz +aCz +aCz +aCz +aCz +aCz +aCz +aCz +aNG +bfh +aPy +aQh +bzw +bzw +bJA +bPv +bTc +bAF +bXj +bYH +bTW +bWE +bFg +ccD +bbb +baZ +aly +aly +aXB +aly +bbe +pOy +baT +bDN +bEP +bEP +bEP +bEP +bEP +bEP +bEP +bEP +bEP +bEP +bEP +bEP +bUb +bDB +bDB +bDB +bDB +bDB +bDB +bUE +bUH +bVE +bWv +epO +bWv +cbb +cbb +cjw +cjx +bOQ +cyW +cAu +cAw +cAw +cAw +cAw +bWK +bXE +bYs +bYQ +bZO +cwz +bQQ +ccn +coj +beB +cpj +aIO +aIO +aIO +aIO +cpx +aGl +cpF +cvS +cyu +cyX +cwl +czR +cAv +cvS +brL +cAM +cAQ +ctQ +aal +aad +aad +aad +rvT +uMK +edV +lNo +uMK +uMK +edV +lqC +edV +nRW +edV +peF +uMK +uMK +uMK +rvT +aac +"} +(190,1,1) = {" +aac +aad +aad +aad +aad +aad +aET +aHJ +cwl +aOw +aTC +aIA +aIA +aIA +aIA +aIA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aad +aal +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amm +amZ +anp +aoi +aol +aol +aqH +anp +arQ +arQ +asZ +atX +awP +avq +awr +axi +axK +ayx +ayU +azy +azP +axI +aAk +aAu +aAI +aAU +aAU +aAU +aAT +aAu +aAu +aAu +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aNH +aAR +aPz +aQi +bAF +bAF +bJD +bAF +bAF +bAF +bVq +bTc +bAF +bWE +bFg +ccD +aXD +bbh +bxb +aly +aXB +aly +bbe +aXB +aZi +bKy +bQP +bQP +bQP +bQP +bQP +bSG +bSW +bSW +bSW +bSW +bSW +bTN +bUe +bQP +bQP +bQP +bQP +bQP +bEU +bUF +bUI +bVH +bWA +kmK +bWA +cbA +ceW +bDF +cjy +bOR +bQQ +bSX +bQQ +bQQ +bQQ +bSX +bQQ +bQQ +bQQ +bSX +bQQ +bQQ +bQQ +bNy +biS +aGl +aGl +aGl +aGl +aGl +aGl +aGl +aGl +cpF +cvS +cyv +cyY +cyY +czS +cwl +cvS +brL +cAM +cAQ +ctQ +aal +aad +aad +aad +rvT +uMK +uMK +iAN +uMK +uMK +iAN +uMK +uMK +uMK +uMK +uMK +ksx +uMK +uMK +rvT +aac +"} +(191,1,1) = {" +aac +aad +aad +aad +aad +aad +aET +aHK +cwl +aET +aET +aVD +aET +bbl +aIA +aIA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aad +aal +aal +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amm +amZ +anp +aoj +ape +apN +aqI +anp +arQ +ant +ata +atY +auM +avr +awt +axd +axK +ayx +ayx +azz +azQ +axI +aAl +aAv +aAI +aAU +aAU +aAU +aAT +aAu +aAu +aAu +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aNH +aAR +aPz +aQi +bAF +bAF +bIg +bAF +bAF +bAF +bAF +bAF +bAF +bWE +bFg +ccD +baT +bcy +byd +aly +aly +aly +bcE +tax +aZi +bKV +bSl +bSl +bSl +bnY +bnY +cqb +bnY +bnY +bnY +bnY +bnY +bTO +byT +byT +byT +byT +byT +cho +bDN +bUE +bUH +bUC +bDB +qvz +bDB +cbB +ceX +bDF +cjz +bQQ +cyW +bQQ +bOR +bQQ +bOR +bQQ +bOR +bQQ +bOR +bQQ +bQQ +bQQ +ceH +ceJ +cop +aHh +kUD +coO +coO +coO +coO +coO +coO +cpM +cvS +hkj +qzx +qzx +iCT +cwl +cvS +brL +cAM +cAQ +ctQ +aal +aad +aad +aad +rvT +uMK +uMK +uMK +uMK +uMK +uMK +uMK +uMK +uMK +kge +uMK +ksx +wxM +iAN +rvT +aac +"} +(192,1,1) = {" +aac +aad +aad +aad +aad +aad +aET +aHL +cwl +cwl +cwl +cwl +aYW +aGV +aIA +aIA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aac +aal +aal +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aad +aad +aal +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amo +ana +anp +aok +aol +apO +aqJ +anp +ant +ant +auQ +ant +awP +avs +awg +avi +axI +ayy +ayV +azA +azR +axI +aAk +aAu +aAI +aAU +aAU +aAU +aAT +aAu +aAu +aAu +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aNH +aAR +aPz +aQi +bAF +bAF +bKE +bAF +bAF +bAF +bAF +bAF +bAF +bWE +bFg +bFp +baU +bnj +bye +aly +aly +aly +aly +jzG +aZi +bKV +bSl +bSl +bSl +bnY +boY +bqw +bsg +btK +bvb +bwo +bnY +bTO +byT +bzA +bAf +bBa +bBM +bCP +gBV +xpf +vCT +pQk +pQk +rCM +bVL +cbX +bVL +bNy +bOQ +bQQ +cyW +bQQ +bQQ +bQQ +bQQ +bQQ +bQQ +bQQ +bQQ +bQQ +bQQ +bQQ +ceI +ccl +cnB +coP +cvS +cvS +cvS +cvS +cvS +cvS +cvS +ceQ +cvS +cym +cwl +cwl +czM +cwl +cvS +brL +cAM +cAQ +ctQ +aal +aad +aad +aad +rvT +uMK +iAN +uMK +wxM +uMK +edV +edV +edV +uMK +uMK +uMK +ksx +uMK +iAN +rvT +aac +"} +(193,1,1) = {" +aac +aad +aad +aad +aad +aad +aET +aIk +aMc +aQc +aUq +aVE +aET +aGV +aIA +aIA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +ayF +alo +amm +ana +anp +aol +apf +apP +aqL +are +ant +ant +auQ +atZ +amz +avt +awu +axj +axI +axI +axI +axI +axI +axI +aAj +aAw +aAI +aAT +aAT +aAT +aAT +aAu +aBE +aAx +aCA +aCA +aCA +aCA +aCA +aCA +aCA +aCA +aCA +aCA +aCA +aCA +aCA +aCA +aCA +bfg +aNI +aCA +aPA +aQj +bAJ +bGa +bKZ +bAJ +bAJ +bAJ +bYF +bAJ +bAJ +cbV +bFg +ccD +aZi +bqv +byS +aXE +bAg +bSO +bVA +hlu +aZi +bKV +bSl +bSl +bSl +bnY +boZ +bqw +bqw +btL +bqw +bqw +bxk +bQO +byT +bzB +bAi +bBb +bBN +bCQ +bSt +bUG +bSu +bSu +bSu +bSu +bSu +bSx +bSu +bSU +bTx +caD +czP +bQQ +bOR +bQQ +bOR +bQQ +bOR +bQQ +bOR +bQQ +bQQ +bQQ +ceI +ccm +aal +hUp +cvS +ccJ +cvY +cwj +cwo +cvS +cwG +bah +cxG +cyl +cwl +cwl +czM +cwl +cvS +brL +cAM +cAQ +ctQ +aal +aad +aad +aad +rvT +uMK +uMK +uMK +uMK +uMK +uMK +uMK +uMK +iAN +wxM +uMK +ksx +uMK +uMK +rvT +aac +"} +(194,1,1) = {" +aac +aad +aad +aad +aad +aad +aET +aET +aET +aET +aET +aET +aET +bbl +aIA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +ayF +alo +amm +ana +anp +anp +anp +anp +anp +anp +arR +ast +atb +aua +amz +awz +awv +axk +axL +ayz +ayW +azB +azS +amd +aAm +aAu +aAH +aAu +aAu +aAu +aAu +aAu +aBD +amy +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAg +aAs +aAg +aAg +aAg +aAg +aAg +aAg +aPw +cdv +bBU +bFg +bFg +bFg +bFg +bFg +bPa +bFg +bAF +bAF +bFg +ccD +aZi +aZi +aZi +caA +aZi +aZi +skd +aZi +aZi +bKV +bSl +bSl +cqK +bnY +bpa +bqw +bqw +bqw +bqw +bqw +bxk +bTP +byT +bzC +bAi +bBc +bAi +bCR +bUD +bEV +bEV +bEV +bEP +bEP +bEP +bUb +bQO +bDF +bOS +bQQ +bQQ +bSX +bQQ +bQQ +bQQ +bSX +bQQ +bQQ +bQQ +bSX +bQQ +bQQ +ceI +ccn +aal +oWw +shJ +cwl +cxa +cvU +cwp +cwA +cwH +bai +cvU +cyw +cwl +cwl +czM +cAo +cvS +brL +cAM +cAQ +ctQ +aal +aad +aad +aad +rvT +uMK +uMK +edV +edV +uMK +uMK +wxM +uMK +uMK +uMK +uMK +ksx +uMK +uMK +rvT +aac +"} +(195,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aIx +aMd +aQd +aUr +aIA +aIA +aIA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +ayF +alo +amm +amm +amz +apG +ant +ars +ars +amz +atw +ant +auQ +avV +awP +avv +aww +awz +awz +awz +awz +awz +awz +amd +aAn +aAx +aAJ +aAV +aAZ +aBe +aBh +aAx +aBF +amz +amz +aDF +aDF +aDF +aDF +aHv +amz +aHv +aDF +aDF +aDF +aDF +amz +amz +aAg +aAg +aAg +aAg +aPw +aQg +bDG +bDG +bFg +bFg +bFg +bFg +bFg +bFg +bAF +bAF +bFg +ccD +bzs +aZi +bcj +baY +aZj +aZi +bDN +bDB +bDB +bMi +bSl +bSl +bSl +bnY +bpb +btL +bqw +bqw +bqw +bwp +bnY +bSl +byT +bzD +bAi +bBd +bBO +byT +byT +byT +byT +byT +bDN +bEP +bEP +bUb +bQO +bDF +bOU +bQR +bSy +bSY +bTA +bTA +bUu +bUu +bTA +bXF +bUu +bUu +bZP +caL +cbG +bDF +cve +xSI +cvS +ccK +ccN +ccR +cwo +cvS +cwI +bcB +cwI +cwI +cwI +czp +czM +cAp +cvS +brL +cAM +cAQ +ctQ +aal +aad +aad +aad +rvT +uMK +kge +uMK +uMK +iAN +uMK +uMK +uMK +uMK +edV +uMK +uMK +uMK +wxM +rvT +aac +"} +(196,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aIA +aIA +aIA +aIA +aIA +aIA +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aad +aad +aad +aad +aal +aal +acZ +aal +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +bQU +alo +amm +alo +amz +apG +aqD +ans +ans +asJ +ans +ans +auR +avW +awQ +avw +awx +awz +axM +amd +amd +amd +amd +amd +amd +amd +amd +amd +amd +amd +amd +amd +amd +amz +aCC +aDK +aEu +aEu +aEu +aEu +aHT +aEu +aEu +aEu +aEu +aEu +aLf +amz +aAg +aAg +aAg +amz +aPB +amz +bzs +bzs +bBU +bFg +bAF +bAF +bAF +bAF +bAF +bAF +bFg +ccD +bzs +aZi +bcl +aly +bFt +aZi +bDN +bEP +bEP +bMi +bSl +bSl +bSl +bnY +bpc +bqx +bqw +bqw +bvc +bwq +bnY +bSl +byT +bzE +bAj +bBd +bOP +byT +bQD +bQD +bQD +civ +bDO +bQP +bEU +ccT +bQO +bDF +bOV +bQS +bQS +bQS +bTB +bTR +bUv +bTR +bWL +bXG +bXG +bXG +bZQ +caL +cbH +bDF +cve +aal +cvS +bSj +ccO +czT +cwq +cwB +cwJ +bcC +cwV +cwV +rgc +czq +czT +cAq +cvS +brL +cAM +cAQ +ctQ +aal +aad +aad +aad +rvT +uMK +iAN +iAN +nRW +uMK +mrJ +mrJ +mrJ +uMK +uMK +uMK +uMK +uMK +uMK +rvT +aac +"} +(197,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aIA +aIA +aIA +aIA +aIA +aIA +aal +aal +aal +aal +aal +bKW +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aqg +aqg +aqg +aqg +ayF +alo +alo +amt +alo +amz +apH +aqE +ant +aZq +amz +atx +atx +atx +atx +awP +avx +awy +axl +axl +ayA +axl +axl +axl +aAc +aAo +aAo +aAK +aAo +aBa +aAo +aAK +aAo +aAo +aBZ +aCD +aDM +aEv +aEv +aGp +aGp +aHU +aGp +aGp +aEv +aEv +aEv +aLg +aLN +aMk +aMV +amz +amz +aPC +amz +amz +beF +bBU +bFg +fls +bAF +bAF +bAF +bAF +bAF +bFg +ccD +bzs +aZi +bcp +aly +aZk +aZi +bDN +bEP +bEP +bMi +bSl +bSl +bSl +bnY +bpd +bqy +bsh +btM +bvd +bwr +bnY +bSl +byT +bzF +bAi +bBe +bzG +bzG +bQD +bQD +bQD +byT +bWB +bXt +bZL +cdx +ceY +bDF +bOW +bQT +bSz +bSZ +bTC +bTS +bUw +bVN +bWM +bXH +bSz +bSz +bSz +bSz +cbI +bDF +cvf +amF +cvS +cvS +ccP +aZb +cwr +cwC +aZh +bdu +cxH +cyx +kYC +czr +cwl +cAn +cvS +brL +cAM +cAQ +ctQ +aal +aad +aad +aad +rvT +uMK +uMK +uMK +nRW +uMK +uMK +uMK +uMK +uMK +uMK +iAN +uMK +edV +edV +rvT +aac +"} +(198,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aal +aad +aad +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aac +aad +aad +aad +aad +aal +aal +aal +aal +aqg +aqg +aqg +aqg +ayF +alm +alS +alq +alR +aoL +ans +aqF +art +ant +amz +aty +aue +aty +avX +amz +avy +awz +awz +awz +amd +ayX +awz +azT +amd +aAy +aAy +aAy +aAy +aAy +aAy +aAy +aAy +aAy +amz +aCE +aDN +aEw +aEw +aGq +aHw +aIa +aIH +bba +aEw +aEw +aDN +aLh +amz +aAg +aMW +aNJ +aOF +aPD +amA +aRb +cdu +bBU +bFg +bAF +bAF +bAF +bAF +bAF +bAF +bFg +ccD +bzs +aZi +bcp +aly +bcD +aZi +bDN +bEP +bEP +bMi +bSl +bSl +bSl +bnY +bpe +bqz +bsi +btN +bve +bws +aGk +xMH +byT +bOO +bzG +bAi +bzG +bzG +bQD +bQD +chb +byT +bDN +bXM +aal +aal +aal +aal +bOX +bOX +bOX +bTa +bTD +bTT +bOW +bTT +bWN +bTa +bOX +bOX +bOX +bOX +bOX +aal +aal +aal +aal +cvS +ccQ +cwl +cws +cvS +cwL +cwK +cwK +cwK +kYC +czr +cwl +cwl +cvS +brL +cAM +cAQ +ctQ +aal +aad +aad +aad +rvT +uMK +edV +uMK +uMK +iAN +uMK +wxM +uMK +uMK +uMK +uMK +iAN +uMK +uMK +rvT +aac +"} +(199,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aal +aal +aal +aal +aal +aal +aal +acZ +aan +aan +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aad +aal +aal +aal +aal +aal +apm +aqg +aqg +ayF +akJ +akR +ali +alo +amz +amz +amz +amz +amz +amz +amz +amz +amz +amz +amz +amd +awz +amd +amd +amd +awz +amd +amd +amd +amd +amd +aAL +aAW +aAL +aAW +aAL +amd +amd +amz +amz +amz +amz +amz +amz +amz +amz +amz +amz +amz +amz +amz +amz +amz +alZ +alZ +amz +amz +aPE +amB +aRc +cdu +bBU +bFg +bAF +bAF +bAF +bAF +bAF +bAF +bFg +ccD +bzs +aZi +bcq +bbf +bNv +bTq +bDO +bEU +bEU +bMj +bSl +bSl +cqK +bnY +bnY +bnY +bsj +btO +bsj +bnY +bnY +fIm +byT +xyu +bzG +bzG +bzG +bzG +bQD +bQD +chi +byT +bWC +bXN +aal +aal +aal +aal +aal +aal +aal +bTb +bTE +bTU +bUy +bTU +bWO +bXI +aal +aal +aal +aal +aal +aal +aal +aal +aal +cvS +cwe +cwl +cwe +cvS +cwM +cwW +cwW +cwW +cwW +czs +cwl +cAo +cvS +brL +cAM +cAQ +ctQ +aal +aad +aad +aad +rvT +uMK +edV +uMK +edV +lNo +uMK +uMK +uMK +uMK +xzs +uMK +uMK +uMK +uMK +rvT +aac +"} +(200,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aal +aal +aad +aal +aal +aal +aal +aal +aao +aze +aal +aal +aal +aal +aal +aal +aal +aal +aal +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aal +aal +aal +aal +aal +apm +aqg +aqg +ayF +akK +alV +alf +alo +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +aal +amd +ayL +amd +aal +amd +ayL +amd +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +amz +aPF +aQk +aRd +cdu +bBU +bFg +bFg +bFg +bFg +bFg +bFg +bFg +bFg +ccD +bzs +aZi +aZi +aZi +aZi +aZi +bDP +bEV +bEV +bNa +bSl +bSl +bSl +acO +aal +aal +bsj +btP +bsj +aal +aal +ygB +pZT +bzH +bAl +bEs +bQC +byT +bQD +bQD +bQD +byT +bSl +bYm +aal +aal +aal +aal +bOY +fXg +fXg +fXg +fXg +bTY +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +cbJ +aal +aal +aal +aal +cvS +cwf +ccS +cwf +cvS +cwN +cwl +cwl +cwl +cwl +czt +czU +cAp +cvS +brL +cAM +cAQ +ctQ +aal +aad +aad +aad +rvT +uMK +edV +uMK +edV +lNo +mrJ +mrJ +mrJ +uMK +edV +uMK +uMK +uMK +iAN +rvT +aac +"} +(201,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aap +aap +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZu +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +kld +kld +kld +ctQ +aal +aal +aal +aal +aal +apm +aqg +aqg +aqg +bQh +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +hKj +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +bso +bLa +bPB +bPB +bPB +bPB +bPB +bPB +bPB +bPB +cdr +bFq +amF +amF +amF +amF +amF +bEq +bEq +bEq +bEq +bEq +bEq +bEq +cvM +aal +aal +bsj +btQ +bsj +aal +aal +aal +byT +byT +byT +byT +byT +byT +byT +byT +byT +byT +bEq +bXt +aal +aal +aal +aal +brL +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +ctQ +aal +aal +aal +aal +cvS +cvS +cvS +cvS +cvS +cvS +cvS +cvS +cvS +cvS +cvS +cvS +cvS +cvS +brL +cAM +cAQ +ctQ +aal +aad +aad +aad +rvT +uMK +uMK +uMK +edV +lNo +uMK +uMK +uMK +uMK +lqC +uMK +wxM +uMK +uMK +rvT +aac +"} +(202,1,1) = {" +irN +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +aae +btg +btg +btg +btg +btg +btg +btg +btg +btg +btg +aZu +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +aac +kld +kld +kld +kld +fXg +fXg +fXg +fXg +bxO +bxO +bxO +bxO +bxO +bxO +bxO +fXg +fXg +fXg +apI +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +apI +fXg +fXg +fXg +fXg +fXg +fXg +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +apI +fXg +fXg +kld +bKf +kld +fXg +fXg +fXg +apI +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +apI +fXg +fXg +fXg +fXg +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +fXg +kld +cAM +cAQ +ctQ +aal +aad +aad +aad +rvT +uMK +wxM +uMK +edV +lNo +uMK +uMK +uMK +iAN +edV +uMK +iAN +uMK +uMK +rvT +aac +"} +(203,1,1) = {" +iug +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aZu +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +ucp +cAP +cAQ +ctQ +aal +aad +aad +aad +rvT +uMK +uMK +uMK +uMK +iAN +uMK +wxM +uMK +iAN +uMK +uMK +uMK +uMK +uMK +rvT +aac +"} +(204,1,1) = {" +iqa +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aag +aZu +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +dgn +cAS +ctQ +aal +aad +aad +aad +rvT +uMK +iAN +iAN +uMK +uMK +uMK +uMK +uMK +uMK +uMK +uMK +uMK +edV +edV +rvT +aac +"} +(205,1,1) = {" +cGh +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +btg +btg +btg +btg +btg +btg +btg +btg +btg +btg +aZu +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +aac +kld +kld +kld +kld +gnR +gnR +gnR +gnR +bLQ +bLQ +bLQ +bLQ +bLQ +bLQ +bLQ +gnR +gnR +gnR +apJ +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +apJ +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +apJ +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +apJ +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +apJ +gnR +gnR +gnR +gnR +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +gnR +kld +kld +kld +ctQ +aad +aad +aad +aad +rvT +uMK +edV +edV +uMK +uMK +nRW +nRW +nRW +uMK +edV +edV +peF +uMK +uMK +rvT +aac +"} +(206,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aZu +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aac +aac +aac +aac +kld +kld +ctQ +aal +aal +aal +aal +aal +apm +aqg +aqg +aqg +ayF +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +brL +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +kld +ctQ +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +brL +kld +kld +ctQ +aad +aad +aad +aad +rvT +uMK +uMK +uMK +uMK +uMK +iAN +uMK +uMK +uMK +nRW +uMK +iAN +uMK +iAN +rvT +aac +"} +(207,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +bKW +aal +aal +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aZu +aal +aal +aal +aal +aal +apm +aqg +aqg +aqg +ayF +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +acO +aal +aal +aal +aal +cfE +chs +chs +chs +chs +chs +chs +chs +chs +chs +chs +chs +chs +chs +ctR +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +brL +vAa +kld +ctQ +aad +aad +aad +aad +rvT +uMK +uMK +wxM +uMK +edV +lqC +edV +lqC +edV +uMK +uMK +uMK +wxM +uMK +rvT +aac +"} +(208,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aal +aal +aal +aal +aal +aal +aal +bgI +bgI +bgI +bgI +hxw +hxw +hxw +bgI +bgI +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aad +aad +aad +aal +aal +aal +apm +aqg +aqg +aqg +ayF +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +buO +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +acZ +bNX +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +cvK +cvK +cvK +aad +aad +aad +aad +aad +aad +aad +aad +aad +brL +kld +kld +ctQ +aad +aad +aad +aad +rvT +kge +uMK +uMK +uMK +uMK +uMK +uMK +uMK +uMK +uMK +uMK +uMK +uMK +uMK +rvT +aac +"} +(209,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aal +aal +aal +aal +aal +aal +aal +biO +bHt +nbP +nbP +nbP +beW +beW +beW +biO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aqg +aqg +aqg +aad +aad +aal +aal +aal +acO +amF +amF +amF +amF +amF +amF +amF +amF +amF +cvM +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cvK +cvK +cvK +cvK +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +brL +kld +kld +ctQ +aad +aad +aad +aad +rvT +iAN +uMK +mrJ +uMK +uMK +iAN +iAN +iAN +kge +uMK +mrJ +uMK +uMK +uMK +rvT +aac +"} +(210,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aal +aal +aal +aal +aal +aal +aal +biO +bHu +nbP +nbP +nbP +beW +beW +beW +biO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aqg +aqg +aqg +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +aaj +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +aal +aal +aal +aal +aal +aal +aal +acO +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cvK +cvL +cvL +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +brL +kld +kld +ctQ +aad +aad +aad +aad +rvT +iAN +uMK +mrJ +uMK +uMK +uMK +uMK +uMK +uMK +uMK +mrJ +uMK +uMK +iAN +rvT +aac +"} +(211,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aal +aal +aal +aal +aal +aal +bgI +bHv +nbP +hHy +nbP +hqI +beW +cKl +bgI +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aqg +aqg +aqg +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +aaj +aaj +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cvL +cvL +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +brL +rvT +bMk +bMk +rvT +rvT +rvT +rvT +rvT +rvT +rvT +imW +rvT +rvT +rvT +lYj +lYj +rvT +rvT +rvT +rvT +rvT +rvT +rvT +aac +"} +(212,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aal +aal +aal +aal +aal +aal +bgI +bHw +nbP +hHy +nbP +hqI +beW +hqI +bgI +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aqg +aqg +aqg +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +aaj +aaj +rni +aad +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aad +aad +aad +aad +aad +cvK +cvK +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +brL +rvT +uvz +uvz +nRX +nRX +nRX +nRX +rvT +jIH +uvz +uvz +uvz +uvz +xri +xri +xri +xri +uvz +uvz +uvz +uvz +mWS +rvT +aac +"} +(213,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aal +aal +aal +acZ +aal +aal +aal +bgI +bHu +nbP +hHy +nbP +hqI +beW +hqI +biO +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +prz +cwh +cvK +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +cvK +cvK +cwt +cwD +cwD +cwD +twg +rni +rni +aaj +aaj +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aTz +aDq +aTz +apa +aTz +cqD +aEQ +aTz +cpt +jSU +aad +aad +aad +aad +cvK +cvK +cwt +cwD +aad +aad +aad +aad +aad +aad +aad +aad +aad +brL +bMk +uvz +uvz +scn +uvz +scn +nRX +imW +mJQ +uvz +uvz +uvz +uvz +xri +mRx +mRx +xri +uvz +uvz +uvz +uvz +uvz +rvT +aac +"} +(214,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aal +aal +aal +aal +aal +aal +biO +bHv +nbP +hHy +nbP +hqI +beW +hqI +biO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwh +cvK +aqg +aqg +aqg +aqg +aqg +aqg +aqg +cvK +aqg +aqg +cvK +cvK +cwt +cwD +cwD +cwD +twg +rni +aaj +rni +aaj +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aTz +cni +cor +apa +cqd +aEQ +crJ +aTz +cpt +cpt +uBp +aad +aad +aad +cwg +cvK +cwu +cwE +cvX +aad +aad +aad +aad +aad +aad +aal +aal +bKX +bMk +uvz +uvz +uvz +uvz +uvz +nRX +imW +uVF +uvz +uvz +uvz +rvT +reC +reC +reC +reC +rvT +wQd +uvz +uvz +oMD +rvT +aac +"} +(215,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aal +aal +aal +aal +aal +aal +biO +bHw +nbP +hHy +nbP +hqI +beW +hqI +bgI +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +aad +cwD +cwD +cwD +cwD +cwD +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwh +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +cvK +cwt +cwD +cwD +cwD +twg +aaj +aaj +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aTz +cnj +aTz +apa +aTz +aER +crK +aTz +cpt +rKC +cpt +aad +aad +aad +cwh +cvK +cvK +cwF +cvX +cvX +aad +aad +aad +aad +aal +aal +aal +aad +rvT +iaA +scn +uvz +uvz +uvz +nRX +rvT +hER +uvz +uvz +uvz +pEX +rvT +rvT +rvT +rvT +rvT +wQd +uvz +uvz +uvz +rvT +aac +"} +(216,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aal +aal +aal +aal +aal +aal +bgI +bIZ +nbP +hHy +nbP +hqI +beW +hqI +bgI +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +lVW +cwD +cwD +ezz +cwD +cwD +aad +aad +aad +aad +aad +cwD +cwD +lVW +cwD +udo +cwh +cvK +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +cvK +cvK +aqg +cwt +cwD +cwD +cwD +twg +aaj +aaj +aaj +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aTz +aTz +aTz +apa +aTz +aTz +aTz +aTz +cpt +cpt +cpt +cpt +cvu +cvX +cwi +cwn +cvK +aad +cvX +cwD +cwX +aad +aad +aal +aal +aal +aad +aad +rvT +iaA +uvz +rhc +rhc +scn +nRX +rvT +uHF +uvz +uvz +uvz +ihe +uvz +scn +scn +uvz +ihe +uvz +scn +uvz +tRk +rvT +aac +"} +(217,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aal +aal +aal +aal +bKW +aal +biO +bHw +nbP +hHy +nbP +hqI +beW +hqI +biO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +vCH +cwh +cvK +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aqg +cvK +aqg +aqg +cvK +cwt +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aTz +cnk +apa +apa +apa +adO +apa +aTy +cpt +cpt +cpt +cvu +cvu +cvu +cvX +aad +cvK +aad +aad +cwX +aal +aal +aal +aal +aal +aad +aad +aad +rvT +iaA +uvz +pkQ +pkQ +uvz +nRX +rvT +oeX +uvz +scn +uvz +qcl +uvz +uvz +uvz +uvz +qcl +uvz +scn +uvz +iMq +rvT +aac +"} +(218,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aal +aal +aal +aal +aal +aal +biO +bHt +nbP +hHy +nbP +hqI +beW +hqI +biO +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +ezz +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +udo +cwh +cvK +aqg +aqg +aqg +aqg +aqg +aqg +aqg +cvK +aqg +cvK +cvK +cvK +cwt +cwD +cwD +cwD +twg +aaj +aad +aaj +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aTz +cnl +cnl +apa +apa +cqG +crM +aTz +cpt +cpt +cpt +cpt +rho +aad +aad +aad +cvL +cvL +aad +aad +cwv +aal +aal +aal +aad +aad +aad +aad +rvT +iaA +scn +gZg +gZg +uvz +nRX +rvT +hER +uvz +scn +uvz +jBF +uvz +uvz +uvz +uvz +qzd +uvz +uvz +uvz +nQw +rvT +aac +"} +(219,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aal +aal +aal +aal +aal +aal +bgI +bHu +nbP +hHy +nbP +hqI +beW +hqI +bgI +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +prz +cwD +cwD +cwD +cwD +cwD +aFQ +aFQ +aFQ +aFQ +aFR +aFR +aFQ +aFQ +aFQ +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwh +cvK +aqg +aqg +cvK +aqg +cvK +aqg +cvK +aqg +cvK +aqg +cvK +cvK +cwt +cwD +cwD +cwD +twg +aaj +aaj +rni +aaj +rni +aad +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aTz +cnm +cnl +apa +cqe +cqH +aDn +aTz +cpt +ftC +cpt +aad +aad +aad +aad +aad +aad +cvL +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rvT +iaA +uvz +pkQ +pkQ +uvz +nRX +rvT +uHF +uvz +uvz +uvz +lPf +uvz +uvz +uvz +uvz +lPf +uvz +uvz +uvz +dpH +rvT +aac +"} +(220,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aal +aal +aal +aal +aal +aal +bgI +biO +bgI +bgI +bgI +bgI +bgI +biO +bgI +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +aFQ +aFQ +sqp +aFQ +cwl +cwl +cwl +cRE +cwl +aFQ +aFQ +aFQ +cwD +cwD +cwD +cwD +cwD +cwD +udo +cwh +cvK +cvK +aqg +aqg +aqg +cvK +aqg +cvK +aqg +aqg +cvK +cvK +cvK +cwt +cwD +lVW +cwD +twg +aaj +aaj +aad +aaj +rni +rni +rni +aaj +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aTz +cnl +tRh +apa +cqf +aDn +crN +aTz +cpt +cpt +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rvT +iaA +uvz +ior +gZg +uvz +nRX +rvT +oeX +uvz +scn +uvz +uvz +scn +scn +scn +uvz +uvz +uvz +scn +uvz +ldU +rvT +aac +"} +(221,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +ezz +cwD +aFQ +aFQ +aFR +aFQ +aFQ +qUh +cwl +qPh +cwl +cwl +cwl +cwl +cwl +cwl +cwl +aFQ +cwD +cwD +sSj +cwD +cwD +cwD +dzc +cwh +cvK +cvK +cvK +cvK +cvK +aqg +cvK +aqg +cvK +cvK +cvK +cvK +cvK +cwt +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +rni +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aTz +apa +apa +apa +apa +cqJ +crO +aTz +cpt +cpt +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rvT +iaA +uvz +pkQ +pkQ +scn +nRX +imW +mJQ +uvz +scn +uvz +uvz +scn +scn +scn +uvz +uvz +uvz +scn +uvz +uvz +rvT +aac +"} +(222,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +aFQ +xVS +cwl +tAq +aFQ +cVb +cwl +aFQ +cwl +mua +mua +mua +mua +mua +cwl +aFR +uZS +uZS +uZS +cwD +cwD +cwD +udo +cwh +cvK +cvK +cvK +cvK +aqg +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cwt +prz +cwD +cwD +twg +aaj +aaj +rni +rni +rni +rni +rni +aaj +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aad +aad +aUw +aUw +aUw +aUw +aUw +aUw +aUw +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aTz +aTz +aTz +aTz +aTz +aTz +aTz +aTz +nXv +cpt +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rvT +iaA +uvz +gZg +gZg +uvz +nRX +rvT +mJQ +uvz +uvz +uvz +uvz +scn +scn +scn +uvz +uvz +uvz +uvz +jUo +mTn +rvT +aac +"} +(223,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +acZ +aal +aal +aal +aal +aal +aal +aal +aal +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aad +aad +aad +aad +aad +cwD +cwD +cwD +aFQ +kTw +cwl +uSp +aFQ +nvy +cwl +oCy +lde +mua +mua +mua +mua +mua +cwl +qPh +uZS +uZS +uZS +cwD +cwD +cwD +vsn +cwh +cvK +cvK +cvK +cvK +cvK +aqg +aqg +cvK +cvK +cvK +cvK +cvK +cvK +cwt +cwD +vzt +cwD +twg +aaj +aaj +aaj +aaj +aaj +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aUw +iwy +ycr +apa +sEK +apa +aUw +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +mTB +cpt +cpt +cpt +cpt +cpt +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rvT +iaA +uvz +scn +uvz +uvz +nRX +qVq +mJQ +uvz +scn +uvz +lPf +uvz +uvz +uvz +uvz +lPf +uvz +scn +lzS +pRU +rvT +aac +"} +(224,1,1) = {" +aac +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +aFQ +cwl +cwl +cwl +aFQ +oud +cwl +cAp +lde +mua +mua +mua +mua +mua +cwl +aFR +uZS +uZS +uZS +cwD +cwD +cwD +udo +cwh +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cwt +cwD +cwD +cwD +twg +aaj +aaj +aaj +aad +aaj +aaj +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aal +aal +gMa +oNL +sEK +lIt +eGN +euK +aUw +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rvT +iaA +uvz +uvz +uvz +uvz +uvz +uvz +uvz +uvz +scn +uvz +jBF +uvz +uvz +uvz +uvz +qzd +uvz +scn +oMB +huk +rvT +aac +"} +(225,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +aFQ +rRn +qRm +cwl +qPh +vLq +cwl +cAp +lde +cwl +cwl +cwl +cwl +cwl +jvh +aFQ +uZS +uZS +uZS +cwD +cwD +cwD +ePE +cwh +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cwt +cwD +cwD +cwD +twg +aaj +aaj +aaj +aad +aaj +rni +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aal +aal +gMa +eGN +apa +dSL +rxI +apa +aUw +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rvT +iaA +scn +uvz +uvz +uvz +uvz +uvz +uvz +uvz +uvz +uvz +qcl +uvz +uvz +uvz +uvz +qcl +uvz +scn +lzS +pRU +rvT +aac +"} +(226,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +aFQ +aFQ +aFQ +aFQ +aFQ +aFQ +cAp +xGM +cAp +cwl +cwl +cwl +cwl +cwl +cwl +hie +aFQ +aFQ +aFQ +aFQ +aFQ +aFQ +cwD +udo +cwh +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cwt +cwD +cwD +cwD +twg +aaj +aaj +aaj +aad +aaj +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aUw +oua +apa +apa +apa +sEK +aUw +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rvT +iaA +nRX +nRX +nRX +nRX +xri +ylJ +xri +uvz +uvz +uvz +ihe +uvz +oiv +oiv +uvz +ihe +uvz +uvz +oMB +wcS +rvT +aac +"} +(227,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +aFQ +aFU +fsH +ryU +eEU +aFQ +aFQ +cwl +cwl +mua +mua +mua +mua +cwl +cwl +aFQ +aFQ +eEU +ryU +fsH +aFU +aFQ +cwD +lYe +cwh +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cwt +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +aaj +rni +aaj +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aUw +olL +rxI +apa +hqN +apa +aUw +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +rvT +aac +"} +(228,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +aFR +cwl +cwl +cwl +cwl +pwQ +aFQ +cwl +cwl +tRM +mdc +tPA +uWR +cwl +cwl +cNG +cwl +cwl +cwl +cwl +cwl +aFR +cwD +cwD +cwh +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cwt +cwD +cwD +cwD +twg +aaj +aaj +aaj +rni +rni +rni +aaj +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aUw +apa +apa +apa +lyO +apa +aUw +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(229,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +aFR +cwl +cwl +cwl +aJX +aJX +cNG +cwl +cwl +tRM +tPA +gzG +uWR +cwl +cwl +aFQ +cMJ +aDp +cwl +cwl +cwl +aFR +cwD +cwD +cwh +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cwt +cwD +cwD +cwD +twg +aaj +aaj +aaj +rni +rni +rni +aaj +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +xAC +emA +apa +uma +apa +apa +aUw +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(230,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +ezz +cwD +cwD +aFR +wsC +cwl +cwl +aJX +fNO +aFQ +cwl +cwl +tRM +gCJ +tPA +uWR +cwl +cwl +aFQ +psQ +yij +cwl +cwl +cwl +aFR +cwD +cwD +cwh +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cwt +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +aaj +aaj +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aUw +apa +egT +apa +sEK +eGN +aUw +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(231,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +aFQ +pEv +cwl +cwl +msV +fWp +aFQ +cwl +cwl +tRM +loi +tPA +uWR +cwl +cwl +aFQ +tbd +aDp +cwl +wsC +hji +aFQ +cwD +cwD +cwD +cwn +cwn +cwn +cwn +cwn +cwn +cwn +cwn +cwn +cwn +cwn +cwn +cwn +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +aaj +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aUw +aUw +aUw +gMa +gMa +aUw +aUw +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(232,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +aFQ +aFQ +aFQ +dWP +aFQ +aFQ +aFQ +aFQ +cwl +mua +mua +mua +mua +cwl +aFQ +aFQ +aFQ +aFQ +dWP +aFQ +aFQ +aFQ +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +vzt +cwD +cwD +twg +aaj +aaj +aaj +aaj +aaj +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aad +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(233,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +aFQ +xao +mmZ +aFQ +mmZ +kSC +aFQ +hYa +cwl +cwl +cwl +cwl +ezY +aFQ +kSC +mmZ +aFQ +mmZ +xao +aFQ +cwD +cwD +cwD +cwD +cwD +cwD +cwD +prz +cwD +cwD +lVW +cwD +vzt +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(234,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +ezz +cwD +cwD +ezz +cwD +cwD +aFQ +mmZ +pXS +aFQ +qXb +mmZ +aFQ +cwl +cwl +cwl +cwl +cwl +cwl +aFQ +mmZ +qXb +aFQ +pXS +mmZ +aFQ +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +prz +cwD +cwD +cwD +cwD +cwD +cwD +twg +aaj +aaj +aad +aaj +aaj +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(235,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +aFQ +aFQ +aFQ +aFQ +aFQ +wKa +aFQ +aFQ +aFQ +cwl +cwl +aFQ +aFQ +aFQ +wKa +aFQ +aFQ +aFQ +aFQ +aFQ +cwD +cwD +cwD +cwD +cwD +cwD +vzt +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +aaj +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aqg +aqg +aqg +aqg +aqg +aal +aal +cpt +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(236,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +aFQ +ovH +cwl +cwl +mWJ +pwQ +aFQ +cwl +cwl +aFQ +xEb +kXA +cwl +wsC +hji +aFQ +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +rni +rni +aaj +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +cpt +cpt +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(237,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +prz +cwD +cwD +cwD +cwD +cwD +aFR +wsC +cwl +cwl +mWJ +uja +aFQ +cwl +cwl +aFQ +uja +kXA +cwl +cwl +cwl +aFR +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +ezz +ezz +cwD +lDE +wpT +wpT +wpT +wpT +wpT +wpT +wpT +wpT +wpT +lDE +aaj +aaj +aaj +rni +rni +aaj +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aqg +aad +aad +aad +aad +aad +aad +aad +rni +aad +aad +aad +aad +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(238,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +aFR +cwl +cwl +cwl +cwl +cwl +cNG +cwl +cwl +cNG +cwl +cwl +cwl +cwl +cwl +aFR +cwD +cwD +cwD +frM +lLu +lLu +lLu +lLu +kwB +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aad +aaj +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +aqg +aqg +aqg +aqg +aqg +aqg +aad +aad +aad +aad +rni +rni +rni +aad +rni +aad +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(239,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +aFR +cwl +cwl +cwl +cwl +cwl +aFQ +cwl +cwl +aFQ +cwl +cwl +cwl +cwl +cwl +aFR +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aal +aal +cpt +aqg +aqg +aqg +aqg +aqg +cvK +cvK +cpt +cpt +cpt +rni +rni +rni +rni +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(240,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +ezz +cwD +cwD +cwD +lVW +cwD +cwD +aFQ +klL +sVS +ryU +dlA +aFQ +aFQ +cwl +cwl +aFQ +aFQ +dlA +ryU +sVS +klL +aFQ +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +ezz +twg +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +aad +aad +aad +aad +aad +rni +rni +aad +rni +aal +aal +aal +cpt +aqg +aqg +aqg +aqg +aqg +cvK +cvK +cvK +cpt +cpt +rni +rni +rni +rni +rni +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(241,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +aFQ +aFQ +aFQ +aFQ +aFQ +aFQ +aKV +mua +mua +sZL +aFQ +aFQ +aFQ +aFQ +aFQ +aFQ +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aad +aad +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +aad +rni +rni +aad +rni +rni +rni +rni +rni +cpt +cpt +cvK +aqg +aqg +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cpt +cpt +rni +cpt +cpt +rni +rni +rni +rni +aad +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(242,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +aFR +cyh +mua +mua +fZm +aFR +cwD +cwD +cwD +cwD +cwD +cwD +cwD +lVW +sIJ +cwD +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +cpt +rni +cpt +cpt +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cpt +uIG +cpt +cpt +rni +rni +rni +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(243,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +ezz +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +aFR +aLx +mua +mua +aLD +aFR +cwD +cwD +cwD +cwD +cwD +prz +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aad +aad +rni +aad +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +rni +cpt +rni +rni +uIG +cpt +cpt +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cpt +cpt +cpt +lLT +cpt +rni +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(244,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +ezz +cwD +cwD +cwD +aFQ +aFQ +cwl +cwl +aFQ +aFQ +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +sIJ +viT +viT +viT +viT +viT +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aad +aaj +aaj +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +rni +rni +cpt +cpt +cpt +cpt +cpt +cpt +cpt +cpt +cpt +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cvK +cpt +qaU +cpt +cpt +cpt +cpt +rni +rni +aad +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(245,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +aFQ +aFR +aFR +aFQ +cwD +cwD +cwD +cwD +cwD +cwD +ezz +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +ezz +twg +aaj +aaj +aaj +aaj +rni +aaj +aaj +aad +aad +aaj +aaj +aad +aaj +aad +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +rni +cpt +rni +cpt +cpt +cpt +cUs +cpt +cpt +cpt +cpt +cpt +cpt +cpt +cpt +cvK +cvK +cvK +cvK +cvK +cpt +cpt +cpt +cpt +rKC +cpt +cpt +rni +rni +aad +aad +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(246,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +ezz +cwD +cwD +cwD +cwD +cwD +ezz +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aad +aad +aad +rni +rni +aad +aaj +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +cpt +cpt +cpt +cpt +cpt +cpt +cpt +kyR +rKC +cpt +cpt +cpt +cpt +cpt +cvK +cpt +cpt +cvK +cpt +cpt +cpt +ohM +cpt +cpt +cpt +cpt +cpt +rni +aad +aad +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(247,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +rni +aaj +aaj +aad +rni +rni +rni +rni +aad +aad +aad +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +rni +cpt +qaU +cpt +rKC +cpt +cpt +cpt +cpt +cpt +cpt +cpt +cpt +cpt +cvK +cpt +cpt +cpt +cpt +rKC +lLT +cpt +cpt +cpt +cpt +cpt +rni +cpt +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(248,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +ezz +cwD +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +rni +aad +aad +rni +aad +rni +aad +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +aad +rni +rni +rni +cpt +rni +rni +cpt +cpt +cpt +rkk +cpt +rKC +cpt +cpt +cpt +cpt +wIE +rKC +cpt +cpt +tUx +cpt +cpt +cpt +nII +cpt +cpt +cpt +cpt +cpt +cpt +rni +cpt +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(249,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +sIJ +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +rni +rni +rni +rni +rni +aad +rni +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +aad +rni +rni +rni +rni +cpt +rni +cpt +cpt +cpt +cpt +cpt +cpt +qaU +cpt +cpt +cUs +cpt +cpt +cpt +qaU +cpt +cpt +cpt +cpt +cpt +cpt +cpt +cpt +cpt +qaU +cpt +cpt +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(250,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +xrZ +nij +nij +nij +nij +nij +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +aaj +aad +aad +rni +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +aad +aad +rni +rni +rni +rni +rni +rni +cpt +rni +cpt +cpt +cpt +cpt +cpt +cpt +cpt +rkk +cpt +cpt +cpt +cpt +cpt +cpt +cpt +cpt +rKC +cpt +cpt +cUs +cpt +cpt +cpt +cpt +cpt +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(251,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +ezz +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +cwD +twg +aaj +aaj +aaj +aaj +rni +aaj +rni +rni +aad +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +rni +rni +rni +cpt +rni +cpt +cpt +qaU +cpt +rKC +cpt +cpt +cpt +cpt +cpt +qaU +cpt +cpt +cpt +cUs +cpt +cpt +cpt +cpt +cpt +cpt +cpt +cpt +cpt +rni +rni +cpt +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(252,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +wpT +wpT +wpT +wpT +wpT +wpT +wpT +wpT +wpT +wpT +wpT +wpT +wpT +wpT +lYh +aaj +aaj +aaj +rni +rni +aad +aad +rni +aad +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +rni +aad +rni +rni +rni +rni +rni +rni +rni +rni +cpt +cpt +cpt +cUs +cpt +cpt +cpt +rni +cpt +cpt +rni +cpt +cpt +cpt +cpt +cpt +cpt +cpt +rni +cpt +cpt +rni +rni +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(253,1,1) = {" +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +cwD +cwD +cwD +cwD +cwD +cwD +ezz +cwD +cwD +aad +aad +aad +aaj +aaj +aaj +rni +aaj +aad +rni +rni +aad +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +aad +rni +rni +rni +rni +rni +rni +rni +rni +rni +cpt +cpt +rni +rni +rni +cpt +cpt +rni +rni +cpt +cpt +cpt +cpt +rni +cpt +cpt +rni +cpt +cpt +rni +cpt +rni +rni +rni +rni +rni +aad +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(254,1,1) = {" +aac +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aaj +aad +aaj +rni +rni +rni +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +rni +rni +rni +aad +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +rni +aad +aad +rni +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aad +aac +"} +(255,1,1) = {" +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +"} diff --git a/_maps/map_files/FestiveBall/doorButtonOrganizer.dm b/_maps/map_files/FestiveBall/doorButtonOrganizer.dm new file mode 100644 index 0000000000..855126fd13 --- /dev/null +++ b/_maps/map_files/FestiveBall/doorButtonOrganizer.dm @@ -0,0 +1,10 @@ +// This will let me avoid having to edit all of these variables in every instance, while also avoiding var-editing. +/obj/machinery/button/door/dorms + name = "Dorm 1 Lock" + normaldoorcontrol = 1 + id = "dorm01" + specialfunctions = 4 + +/obj/machinery/door/airlock/wood/dorms + name = "Dorm 1" + id_tag = "dorm01" diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index 2690cb1644..74dbdcf8d7 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -12343,6 +12343,7 @@ /obj/machinery/light{ dir = 4 }, +/obj/structure/closet/firecloset, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "auA" = ( @@ -13135,9 +13136,6 @@ /turf/open/floor/plasteel, /area/command/bridge) "avS" = ( -/obj/machinery/computer/bounty{ - dir = 4 - }, /obj/machinery/requests_console{ announcementConsole = 1; department = "Head of Personnel's Desk"; @@ -13429,7 +13427,7 @@ /obj/item/radio/intercom{ pixel_x = 28 }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) "awq" = ( @@ -22447,7 +22445,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/machinery/sleeper{ +/obj/machinery/stasis{ dir = 4 }, /turf/open/floor/plasteel/dark, @@ -35252,7 +35250,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 1 }, -/obj/structure/closet/firecloset, +/obj/machinery/piratepad/civilian, /turf/open/floor/plasteel/dark, /area/hallway/primary/starboard) "beP" = ( @@ -36997,6 +36995,9 @@ /obj/item/assembly/flash/handheld, /obj/item/assembly/flash/handheld, /obj/item/assembly/flash/handheld, +/obj/machinery/posialert{ + pixel_x = -32 + }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bhC" = ( @@ -37144,7 +37145,6 @@ /turf/open/floor/plasteel, /area/cargo/miningoffice) "bhO" = ( -/obj/machinery/computer/bounty, /obj/effect/turf_decal/bot, /obj/effect/turf_decal/tile/neutral{ dir = 8 @@ -38740,9 +38740,6 @@ dir = 4 }, /obj/effect/turf_decal/bot, -/obj/machinery/computer/bounty{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/cargo/office) "bks" = ( @@ -39443,6 +39440,7 @@ /obj/machinery/light/small{ dir = 1 }, +/obj/item/chisel, /turf/open/floor/plasteel/dark, /area/service/library) "blB" = ( @@ -42089,8 +42087,10 @@ /turf/open/floor/plasteel, /area/cargo/storage) "bpF" = ( -/obj/structure/sign/departments/cargo, -/turf/closed/wall, +/obj/machinery/computer/piratepad_control/civilian{ + dir = 8 + }, +/turf/open/floor/plasteel, /area/hallway/primary/starboard) "bpG" = ( /obj/effect/turf_decal/tile/neutral, @@ -43728,7 +43728,7 @@ }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 @@ -49265,10 +49265,6 @@ /area/security/checkpoint/supply) "bBp" = ( /obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, /obj/structure/cable{ icon_state = "1-2" }, @@ -55924,6 +55920,7 @@ dir = 1; pixel_y = -22 }, +/obj/effect/landmark/start/prisoner, /turf/open/floor/plasteel/showroomfloor, /area/security/prison) "bLR" = ( @@ -59245,6 +59242,7 @@ dir = 1; pixel_y = -22 }, +/obj/effect/landmark/start/prisoner, /turf/open/floor/plasteel/showroomfloor, /area/security/prison) "bRc" = ( @@ -61866,6 +61864,7 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/effect/landmark/start/prisoner, /turf/open/floor/plasteel/showroomfloor, /area/security/prison) "bVq" = ( @@ -79329,6 +79328,7 @@ dir = 4 }, /obj/effect/turf_decal/tile/neutral, +/obj/effect/landmark/start/prisoner, /turf/open/floor/plasteel/dark, /area/security/prison) "czS" = ( @@ -84640,6 +84640,17 @@ icon_state = "wood-broken6" }, /area/commons/vacant_room/office) +"fuh" = ( +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/sleeper{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/medical/medbay/central) "fyr" = ( /obj/effect/decal/cleanable/cobweb/cobweb2, /turf/closed/mineral/random/labormineral, @@ -84876,7 +84887,7 @@ /obj/item/reagent_containers/food/drinks/bottle/grenadine, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 @@ -84960,56 +84971,56 @@ /obj/item/reagent_containers/food/drinks/bottle/wine, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 }, /obj/item/reagent_containers/food/drinks/beer{ desc = "A station exclusive. Consumpt may result in seizures, blindness, drunkenness, or even death."; - list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 10); + list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko=10); name = "Kilo-Kocktail"; pixel_x = 5; pixel_y = 5 @@ -85048,6 +85059,10 @@ "khA" = ( /turf/closed/wall/rust, /area/construction/mining/aux_base) +"kmy" = ( +/obj/structure/sign/departments/cargo, +/turf/closed/wall, +/area/cargo/office) "koc" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1, /turf/open/floor/wood, @@ -104566,7 +104581,7 @@ aRd aOR abl aSW -aLi +fuh aLi aOW aWp @@ -122826,7 +122841,7 @@ aYK aYd bhe cLt -bhI +kmy bhX bhs biM diff --git a/_maps/map_files/LambdaStation/dorms.dmm b/_maps/map_files/LambdaStation/dorms.dmm index afe85da6cc..99626ac667 100644 --- a/_maps/map_files/LambdaStation/dorms.dmm +++ b/_maps/map_files/LambdaStation/dorms.dmm @@ -365,13 +365,6 @@ /obj/machinery/door/firedoor, /turf/open/floor/plasteel, /area/hallway/primary/central) -"aQ" = ( -/obj/machinery/door/airlock/hatch{ - name = "Telecomms Control Room"; - req_one_access_txt = "19; 61" - }, -/turf/open/floor/plating/airless, -/area/tcommsat/chamber) "aR" = ( /obj/item/electropack/shockcollar, /obj/item/assembly/signaler, @@ -3201,6 +3194,12 @@ }, /turf/open/floor/plasteel, /area/service/hydroponics/garden/monastery) +"iA" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plating/airless, +/area/tcommsat/chamber) "iC" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -5012,6 +5011,7 @@ dir = 1 }, /obj/machinery/light, +/obj/machinery/jukebox, /turf/open/floor/plasteel, /area/service/bar) "nb" = ( @@ -5602,6 +5602,12 @@ }, /turf/open/floor/plating, /area/maintenance/solars/starboard) +"ox" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plating/airless, +/area/space/nearstation) "oy" = ( /obj/structure/railing{ dir = 4; @@ -7714,12 +7720,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, /turf/open/floor/carpet/blue, /area/commons/vacant_room/office) -"tS" = ( -/obj/structure/cable{ - icon_state = "0-2" - }, -/turf/open/floor/plating/airless, -/area/tcommsat/chamber) "tT" = ( /obj/structure/cable{ icon_state = "1-2" @@ -9501,7 +9501,7 @@ /obj/machinery/camera/autoname{ dir = 4 }, -/obj/machinery/computer/arcade/minesweeper{ +/obj/machinery/computer/arcade/orion_trail{ dir = 4 }, /turf/open/floor/plasteel, @@ -14697,6 +14697,15 @@ }, /turf/open/floor/plasteel, /area/commons/fitness/recreation) +"LG" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plating/airless, +/area/space/nearstation) "LH" = ( /obj/structure/cable{ icon_state = "4-8" @@ -37240,11 +37249,11 @@ lQ Yv Yv Yv -dh -Yv -Yv -aQ -tS +LG +ox +ox +kF +iA kF Gq LC diff --git a/_maps/map_files/LambdaStation/lambda.dmm b/_maps/map_files/LambdaStation/lambda.dmm index 98bdbe6542..22241d6dfc 100644 --- a/_maps/map_files/LambdaStation/lambda.dmm +++ b/_maps/map_files/LambdaStation/lambda.dmm @@ -443,6 +443,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/effect/landmark/start/prisoner, /turf/open/floor/plasteel, /area/security/prison) "abr" = ( @@ -7932,6 +7933,9 @@ /obj/structure/table, /obj/item/stack/cable_coil/random, /obj/machinery/camera/autoname, +/obj/machinery/posialert{ + pixel_y = 32 + }, /turf/open/floor/plasteel, /area/science/robotics/lab) "apy" = ( @@ -13475,24 +13479,6 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"ayl" = ( -/obj/structure/table/wood, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/item/storage/secure/briefcase{ - pixel_x = -2 - }, -/obj/item/book/manual/wiki/security_space_law, -/obj/item/cartridge/detective, -/obj/machinery/power/apc{ - areastring = "/area/command/heads_quarters/hos"; - dir = 1; - name = "Head of Security's Office APC"; - pixel_y = 23 - }, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) "aym" = ( /obj/structure/table/wood, /obj/effect/turf_decal/tile/red{ @@ -13531,7 +13517,7 @@ }, /mob/living/simple_animal/pet/gondola{ desc = "The last known gondola for lightyears, it is your duty to keep them safe from the filthy yellowed hands of the greytide."; - loot = list(/obj/effect/decal/cleanable/blood/gibs, /obj/item/stack/sheet/animalhide/gondola = 1); + loot = list(/obj/effect/decal/cleanable/blood/gibs,/obj/item/stack/sheet/animalhide/gondola=1); name = "Filbert" }, /turf/open/floor/plasteel/dark, @@ -14824,15 +14810,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) -"aAy" = ( -/obj/machinery/computer/prisoner{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) "aAz" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -18332,6 +18309,7 @@ /obj/structure/table, /obj/item/stack/cable_coil/random, /obj/item/stack/cable_coil/random, +/obj/item/chisel, /turf/open/floor/plasteel, /area/commons/storage/art) "aGS" = ( @@ -23398,9 +23376,6 @@ /turf/open/floor/plasteel, /area/cargo/miningoffice) "aQs" = ( -/obj/machinery/computer/bounty{ - dir = 4 - }, /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 10 }, @@ -24376,12 +24351,10 @@ /turf/open/floor/plasteel, /area/hallway/primary/fore) "aTo" = ( -/obj/structure/chair{ - dir = 4 - }, /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 8 }, +/obj/machinery/piratepad/civilian, /turf/open/floor/plasteel, /area/hallway/primary/central) "aTp" = ( @@ -25039,9 +25012,6 @@ name = "Station Intercom"; pixel_y = -28 }, -/obj/machinery/computer/bounty{ - dir = 1 - }, /obj/machinery/light, /turf/open/floor/plasteel, /area/cargo/storage) @@ -25142,9 +25112,6 @@ /turf/open/floor/plasteel, /area/cargo/office) "aVG" = ( -/obj/structure/chair{ - dir = 4 - }, /obj/machinery/light{ dir = 8; light_color = "#e8eaff" @@ -25152,6 +25119,9 @@ /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 8 }, +/obj/machinery/computer/piratepad_control/civilian{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aVH" = ( @@ -34519,13 +34489,6 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) -"bpO" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/hallway/secondary/exit/departure_lounge) "bpP" = ( /obj/structure/lattice/catwalk, /obj/item/wrench, @@ -38055,7 +38018,7 @@ dir = 5 }, /obj/machinery/vending/medical{ - products = list(/obj/item/reagent_containers/syringe = 12, /obj/item/reagent_containers/dropper = 3, /obj/item/healthanalyzer = 4, /obj/item/sensor_device = 4, /obj/item/pinpointer/crew = 2, /obj/item/reagent_containers/medspray/sterilizine = 1, /obj/item/stack/medical/gauze = 8, /obj/item/reagent_containers/pill/patch/styptic = 5, /obj/item/reagent_containers/medspray/styptic = 2, /obj/item/reagent_containers/pill/patch/silver_sulf = 5, /obj/item/reagent_containers/medspray/silver_sulf = 2, /obj/item/reagent_containers/pill/insulin = 10, /obj/item/reagent_containers/pill/salbutamol = 2, /obj/item/reagent_containers/glass/bottle/charcoal = 4, /obj/item/reagent_containers/glass/bottle/epinephrine = 4, /obj/item/reagent_containers/glass/bottle/salglu_solution = 3, /obj/item/reagent_containers/glass/bottle/morphine = 4, /obj/item/reagent_containers/glass/bottle/toxin = 3, /obj/item/reagent_containers/syringe/antiviral = 6, /obj/item/storage/hypospraykit/fire = 2, /obj/item/storage/hypospraykit/toxin = 2, /obj/item/storage/hypospraykit/o2 = 2, /obj/item/storage/hypospraykit/brute = 2, /obj/item/storage/hypospraykit/enlarge = 2, /obj/item/reagent_containers/glass/bottle/vial/small = 5, /obj/item/storage/briefcase/medical = 2, /obj/item/stack/sticky_tape/surgical = 3, /obj/item/healthanalyzer/wound = 4, /obj/item/stack/medical/ointment = 2, /obj/item/stack/medical/suture = 2, /obj/item/stack/medical/bone_gel = 4) + products = list(/obj/item/reagent_containers/syringe=12,/obj/item/reagent_containers/dropper=3,/obj/item/healthanalyzer=4,/obj/item/sensor_device=4,/obj/item/pinpointer/crew=2,/obj/item/reagent_containers/medspray/sterilizine=1,/obj/item/stack/medical/gauze=8,/obj/item/reagent_containers/pill/patch/styptic=5,/obj/item/reagent_containers/medspray/styptic=2,/obj/item/reagent_containers/pill/patch/silver_sulf=5,/obj/item/reagent_containers/medspray/silver_sulf=2,/obj/item/reagent_containers/pill/insulin=10,/obj/item/reagent_containers/pill/salbutamol=2,/obj/item/reagent_containers/glass/bottle/charcoal=4,/obj/item/reagent_containers/glass/bottle/epinephrine=4,/obj/item/reagent_containers/glass/bottle/salglu_solution=3,/obj/item/reagent_containers/glass/bottle/morphine=4,/obj/item/reagent_containers/glass/bottle/toxin=3,/obj/item/reagent_containers/syringe/antiviral=6,/obj/item/storage/hypospraykit/fire=2,/obj/item/storage/hypospraykit/toxin=2,/obj/item/storage/hypospraykit/o2=2,/obj/item/storage/hypospraykit/brute=2,/obj/item/storage/hypospraykit/enlarge=2,/obj/item/reagent_containers/glass/bottle/vial/small=5,/obj/item/storage/briefcase/medical=2,/obj/item/stack/sticky_tape/surgical=3,/obj/item/healthanalyzer/wound=4,/obj/item/stack/medical/ointment=2,/obj/item/stack/medical/suture=2,/obj/item/stack/medical/bone_gel=4) }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) @@ -38186,17 +38149,19 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bDq" = ( -/obj/machinery/sleeper, /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 9 }, +/obj/machinery/sleeper{ + dir = 4 + }, /turf/open/floor/plasteel/white, /area/medical/cryo) "bDr" = ( -/obj/machinery/sleeper, /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 5 }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/cryo) "bDs" = ( @@ -44889,7 +44854,7 @@ /obj/item/gps/engineering{ gpstag = "CE0" }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) "bUH" = ( @@ -46057,7 +46022,7 @@ "bXK" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/machinery/vending/medical{ - products = list(/obj/item/reagent_containers/syringe = 12, /obj/item/reagent_containers/dropper = 3, /obj/item/healthanalyzer = 4, /obj/item/sensor_device = 4, /obj/item/pinpointer/crew = 2, /obj/item/reagent_containers/medspray/sterilizine = 1, /obj/item/stack/medical/gauze = 8, /obj/item/reagent_containers/pill/patch/styptic = 5, /obj/item/reagent_containers/medspray/styptic = 2, /obj/item/reagent_containers/pill/patch/silver_sulf = 5, /obj/item/reagent_containers/medspray/silver_sulf = 2, /obj/item/reagent_containers/pill/insulin = 10, /obj/item/reagent_containers/pill/salbutamol = 2, /obj/item/reagent_containers/glass/bottle/charcoal = 4, /obj/item/reagent_containers/glass/bottle/epinephrine = 4, /obj/item/reagent_containers/glass/bottle/salglu_solution = 3, /obj/item/reagent_containers/glass/bottle/morphine = 4, /obj/item/reagent_containers/glass/bottle/toxin = 3, /obj/item/reagent_containers/syringe/antiviral = 6, /obj/item/storage/hypospraykit/fire = 2, /obj/item/storage/hypospraykit/toxin = 2, /obj/item/storage/hypospraykit/o2 = 2, /obj/item/storage/hypospraykit/brute = 2, /obj/item/storage/hypospraykit/enlarge = 2, /obj/item/reagent_containers/glass/bottle/vial/small = 5, /obj/item/storage/briefcase/medical = 2, /obj/item/stack/sticky_tape/surgical = 3, /obj/item/healthanalyzer/wound = 4, /obj/item/stack/medical/ointment = 2, /obj/item/stack/medical/suture = 2, /obj/item/stack/medical/bone_gel = 4) + products = list(/obj/item/reagent_containers/syringe=12,/obj/item/reagent_containers/dropper=3,/obj/item/healthanalyzer=4,/obj/item/sensor_device=4,/obj/item/pinpointer/crew=2,/obj/item/reagent_containers/medspray/sterilizine=1,/obj/item/stack/medical/gauze=8,/obj/item/reagent_containers/pill/patch/styptic=5,/obj/item/reagent_containers/medspray/styptic=2,/obj/item/reagent_containers/pill/patch/silver_sulf=5,/obj/item/reagent_containers/medspray/silver_sulf=2,/obj/item/reagent_containers/pill/insulin=10,/obj/item/reagent_containers/pill/salbutamol=2,/obj/item/reagent_containers/glass/bottle/charcoal=4,/obj/item/reagent_containers/glass/bottle/epinephrine=4,/obj/item/reagent_containers/glass/bottle/salglu_solution=3,/obj/item/reagent_containers/glass/bottle/morphine=4,/obj/item/reagent_containers/glass/bottle/toxin=3,/obj/item/reagent_containers/syringe/antiviral=6,/obj/item/storage/hypospraykit/fire=2,/obj/item/storage/hypospraykit/toxin=2,/obj/item/storage/hypospraykit/o2=2,/obj/item/storage/hypospraykit/brute=2,/obj/item/storage/hypospraykit/enlarge=2,/obj/item/reagent_containers/glass/bottle/vial/small=5,/obj/item/storage/briefcase/medical=2,/obj/item/stack/sticky_tape/surgical=3,/obj/item/healthanalyzer/wound=4,/obj/item/stack/medical/ointment=2,/obj/item/stack/medical/suture=2,/obj/item/stack/medical/bone_gel=4) }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) @@ -49052,18 +49017,6 @@ }, /turf/open/floor/plasteel, /area/engineering/main) -"cgv" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/power/apc/highcap/fifteen_k{ - areastring = "/area/engineering/main"; - dir = 1; - name = "Engine Room APC"; - pixel_y = 23 - }, -/turf/open/floor/plasteel, -/area/engineering/main) "cgw" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -62261,7 +62214,7 @@ /area/engineering/break_room) "cUI" = ( /obj/machinery/vending/engineering{ - products = list(/obj/item/clothing/under/rank/engineering/engineer = 4, /obj/item/clothing/shoes/sneakers/orange = 4, /obj/item/clothing/head/hardhat = 4, /obj/item/storage/belt/utility = 4, /obj/item/clothing/glasses/meson/engine = 4, /obj/item/clothing/gloves/color/yellow = 2, /obj/item/screwdriver = 12, /obj/item/crowbar = 12, /obj/item/wirecutters = 12, /obj/item/multitool = 12, /obj/item/wrench = 12, /obj/item/t_scanner = 12, /obj/item/stock_parts/cell = 8, /obj/item/weldingtool = 8, /obj/item/clothing/head/welding = 8, /obj/item/light/tube = 10, /obj/item/clothing/suit/fire = 4, /obj/item/stock_parts/scanning_module = 5, /obj/item/stock_parts/micro_laser = 5, /obj/item/stock_parts/matter_bin = 5, /obj/item/stock_parts/manipulator = 5) + products = list(/obj/item/clothing/under/rank/engineering/engineer=4,/obj/item/clothing/shoes/sneakers/orange=4,/obj/item/clothing/head/hardhat=4,/obj/item/storage/belt/utility=4,/obj/item/clothing/glasses/meson/engine=4,/obj/item/clothing/gloves/color/yellow=2,/obj/item/screwdriver=12,/obj/item/crowbar=12,/obj/item/wirecutters=12,/obj/item/multitool=12,/obj/item/wrench=12,/obj/item/t_scanner=12,/obj/item/stock_parts/cell=8,/obj/item/weldingtool=8,/obj/item/clothing/head/welding=8,/obj/item/light/tube=10,/obj/item/clothing/suit/fire=4,/obj/item/stock_parts/scanning_module=5,/obj/item/stock_parts/micro_laser=5,/obj/item/stock_parts/matter_bin=5,/obj/item/stock_parts/manipulator=5) }, /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 1 @@ -63052,6 +63005,42 @@ }, /turf/open/space/basic, /area/space) +"cZI" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/start/prisoner, +/turf/open/floor/plasteel, +/area/security/prison) +"cZR" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/hallway/secondary/exit/departure_lounge) +"dbH" = ( +/obj/structure/table/wood, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/item/storage/secure/briefcase{ + pixel_x = -2 + }, +/obj/item/book/manual/wiki/security_space_law, +/obj/item/cartridge/detective, +/obj/machinery/power/apc{ + areastring = "/area/command/heads_quarters/hos"; + dir = 1; + name = "Head of Security's Office APC"; + pixel_y = 23 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hos) "dcB" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 4 @@ -64976,6 +64965,21 @@ /obj/structure/stairs/south, /turf/open/floor/plasteel, /area/maintenance/department/cargo) +"gci" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/power/apc/highcap/fifteen_k{ + areastring = "/area/engineering/main"; + dir = 1; + name = "Engine Room APC"; + pixel_y = 23 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel, +/area/engineering/main) "gcM" = ( /obj/effect/turf_decal/tile/red{ dir = 8 @@ -66094,6 +66098,15 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) +"igd" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/computer/secure_data{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hos) "igf" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, @@ -70166,7 +70179,7 @@ }, /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/sillycup/smallcarton{ - list_reagents = list(/datum/reagent/consumable/milk = 20); + list_reagents = list(/datum/reagent/consumable/milk=20); name = "small milk carton"; pixel_x = -8; pixel_y = 5 @@ -112428,7 +112441,7 @@ agJ ahA ady bPZ -adx +cZI adx ama aNh @@ -113456,7 +113469,7 @@ afg agM ady ajM -adx +cZI adx asb baj @@ -115255,7 +115268,7 @@ amN agQ ady aiu -adx +cZI adx amc beg @@ -117839,7 +117852,7 @@ axW awm axd axF -ayl +dbH azp aAr aBS @@ -119639,7 +119652,7 @@ ayO aCD axF ays -aAy +igd aBz cAp cJw @@ -120776,7 +120789,7 @@ lQs ceh ceP cXQ -cgv +gci chh cia cku @@ -128940,7 +128953,7 @@ bnL bot boJ blZ -bpO +cZR bqG brm blZ @@ -129196,7 +129209,7 @@ jqb bnL bot eec -bpO +cZR bip bqH brn diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 57a4831073..44a080ccb4 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -95,49 +95,161 @@ /turf/open/floor/plating, /area/security/prison) "aaA" = ( -/obj/machinery/seed_extractor, -/obj/machinery/light/small{ - dir = 8 +/obj/structure/table, +/obj/item/reagent_containers/glass/bottle/morphine{ + pixel_x = -4; + pixel_y = 1 }, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/item/reagent_containers/glass/bottle/chloralhydrate{ + name = "chloral hydrate bottle" + }, +/obj/item/reagent_containers/glass/bottle/toxin{ + pixel_x = 6; + pixel_y = 8 + }, +/obj/item/reagent_containers/glass/bottle/morphine{ + pixel_x = 5; + pixel_y = 1 + }, +/obj/item/reagent_containers/syringe, +/obj/item/reagent_containers/glass/bottle/facid{ + name = "fluorosulfuric acid bottle"; + pixel_x = -3; + pixel_y = 6 + }, +/obj/item/reagent_containers/syringe{ + pixel_y = 5 + }, +/obj/item/reagent_containers/dropper, +/obj/machinery/airalarm/all_access{ + dir = 4; + pixel_x = -24 + }, +/obj/machinery/button/ignition{ + id = "executionburn"; + name = "Justice Ignition Switch"; + pixel_x = -25; + pixel_y = 36 + }, +/obj/machinery/button/door{ + id = "executionfireblast"; + name = "Justice Area Lockdown"; + pixel_x = -25; + pixel_y = 26; + req_access_txt = "2" + }, +/obj/item/assembly/signaler{ + pixel_x = -3; + pixel_y = 2 + }, +/obj/machinery/button/flasher{ + id = "justiceflash"; + name = "Justice Flash Control"; + pixel_x = -36; + pixel_y = 36; + req_access_txt = "1" + }, +/obj/machinery/button/door{ + id = "SecJusticeChamber"; + layer = 4; + name = "Justice Vent Control"; + pixel_x = -36; + pixel_y = 26; + req_access_txt = "3" + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) "aaB" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" +/obj/structure/table, +/obj/item/folder/red{ + pixel_x = 3 }, -/obj/item/kirbyplants{ - icon_state = "plant-03" +/obj/item/taperecorder{ + pixel_x = -3 }, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/item/storage/fancy/cigarettes, +/obj/item/assembly/flash/handheld, +/obj/item/reagent_containers/spray/pepper, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) "aaC" = ( +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) +"aaD" = ( /obj/structure/sink/kitchen{ desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; name = "old sink"; pixel_y = 28 }, -/turf/open/floor/plating{ - icon_state = "platingdmg3" +/obj/effect/turf_decal/tile/red{ + dir = 1 }, -/area/security/prison) -"aaD" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/item/kirbyplants, -/turf/open/floor/plasteel, -/area/security/prison) -"aaE" = ( -/obj/machinery/biogenerator, -/obj/machinery/light/small{ +/obj/effect/turf_decal/tile/red{ dir = 4 }, -/obj/machinery/camera{ - c_tag = "Prison Hydroponics"; - network = list("ss13","prison") +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 }, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) +"aaE" = ( +/obj/machinery/power/apc{ + areastring = "/area/security/execution/education"; + dir = 1; + name = "Prisoner Education Chamber APC"; + pixel_y = 23 + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/obj/structure/closet/secure_closet/injection{ + name = "educational injections"; + pixel_x = 2 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) "aaF" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable/yellow{ @@ -146,82 +258,87 @@ /turf/open/floor/plating, /area/security/prison) "aaG" = ( -/obj/machinery/hydroponics/constructable, -/obj/item/seeds/ambrosia, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/structure/table, +/obj/item/flashlight/lamp, +/obj/structure/reagent_dispensers/peppertank{ + pixel_x = -29 + }, +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) "aaH" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" +/obj/structure/chair/office/dark{ + dir = 1 }, -/obj/structure/cable/yellow{ - icon_state = "2-4" - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) "aaI" = ( /obj/structure/cable/yellow{ icon_state = "4-8" }, /turf/open/floor/plasteel, /area/security/prison) -"aaJ" = ( -/obj/item/reagent_containers/glass/bucket, +"aaK" = ( /obj/structure/cable/yellow{ - icon_state = "4-8" + icon_state = "1-2" }, +/obj/machinery/light_switch{ + pixel_x = 26 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) +"aaL" = ( +/obj/effect/spawner/structure/window/reinforced, /obj/structure/cable/yellow{ icon_state = "1-8" }, -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plasteel, -/area/security/prison) -"aaK" = ( -/obj/machinery/hydroponics/constructable, -/obj/item/seeds/glowshroom, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/security/prison) -"aaL" = ( -/obj/effect/spawner/structure/window/reinforced, /obj/structure/cable/yellow{ icon_state = "0-8" }, /turf/open/floor/plating, /area/security/prison) -"aaP" = ( -/obj/machinery/hydroponics/constructable, -/obj/item/cultivator, -/obj/item/seeds/carrot, -/turf/open/floor/plasteel, -/area/security/prison) "aaQ" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" +/obj/effect/turf_decal/tile/red{ + dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/item/reagent_containers/glass/bucket, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) "aaR" = ( /turf/open/floor/plasteel, /area/security/prison) "aaS" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/security/prison) -"aaT" = ( -/obj/machinery/hydroponics/constructable, -/obj/item/plant_analyzer, -/obj/machinery/airalarm{ - dir = 8; - pixel_x = 24 +/obj/effect/turf_decal/tile/red{ + dir = 8 }, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/machinery/light/small, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) +"aaT" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) "aaW" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -242,30 +359,6 @@ "aaZ" = ( /turf/closed/wall/r_wall, /area/security/execution/education) -"aba" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable/yellow{ - icon_state = "0-2" - }, -/obj/structure/cable/yellow, -/turf/open/floor/plating, -/area/security/prison) -"abb" = ( -/obj/machinery/door/airlock/public/glass{ - id_tag = "permahydro"; - name = "Hydroponics Module" - }, -/turf/open/floor/plasteel, -/area/security/prison) -"abc" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable/yellow{ - icon_state = "0-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating, -/area/security/prison) "abd" = ( /obj/machinery/vending/cola/random, /obj/structure/sign/poster/official/pda_ad600{ @@ -294,39 +387,22 @@ /turf/open/floor/plating, /area/security/execution/education) "abh" = ( -/obj/item/soap/nanotrasen, -/obj/item/bikehorn/rubberducky, -/obj/machinery/shower{ +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ dir = 4 }, -/obj/structure/cable/yellow{ - icon_state = "1-4" - }, -/turf/open/floor/plasteel/freezer, -/area/security/prison) -"abi" = ( -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/structure/sink/kitchen{ - desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; - name = "old sink"; - pixel_y = 28 - }, -/turf/open/floor/plasteel/freezer, -/area/security/prison) -"abj" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/structure/easel, -/obj/item/canvas/twentythreeXtwentythree, -/obj/item/canvas/twentythreeXtwentythree, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/upper) +"abj" = ( +/obj/item/storage/bag/trash, +/obj/machinery/airalarm/directional/west, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/plating, +/area/maintenance/prison) "abk" = ( /obj/structure/kitchenspike_frame, /obj/effect/decal/cleanable/blood/gibs/old, @@ -336,73 +412,105 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "abl" = ( -/obj/structure/table, -/obj/machinery/computer/libraryconsole/bookmanagement, -/turf/open/floor/plasteel, -/area/security/prison) -"abm" = ( -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_y = 32 - }, -/obj/machinery/vr_sleeper, -/turf/open/floor/plasteel, -/area/security/prison) -"abn" = ( -/obj/machinery/newscaster{ - pixel_y = 32 +/obj/effect/turf_decal/stripes/line, +/obj/machinery/camera{ + c_tag = "Prison Workshop"; + dir = 8; + network = list("ss13","prison") }, /turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/upper) "abo" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" +/obj/item/tank/internals/oxygen/red{ + pixel_x = -4; + pixel_y = -1 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable/yellow{ - icon_state = "2-4" +/obj/item/tank/internals/oxygen/red{ + pixel_x = 4; + pixel_y = -1 }, -/turf/open/floor/plasteel, -/area/security/prison) -"abp" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable/yellow{ - icon_state = "1-8" +/obj/item/tank/internals/anesthetic{ + pixel_x = 2 }, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/item/storage/toolbox/mechanical, +/obj/item/clothing/mask/gas, +/obj/item/clothing/mask/gas, +/obj/structure/closet/crate{ + icon_state = "crateopen" + }, +/obj/machinery/atmospherics/pipe/manifold/general/visible, +/obj/item/wrench, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) "abq" = ( -/obj/structure/holohoop{ - pixel_y = 29 +/obj/structure/table/glass, +/obj/item/reagent_containers/syringe, +/obj/item/reagent_containers/glass/bottle/morphine{ + pixel_y = 6 }, -/obj/item/toy/beach_ball/holoball, -/turf/open/floor/plating{ - icon_state = "platingdmg1" +/obj/effect/turf_decal/tile/blue{ + dir = 1 }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/white, /area/security/prison) "abr" = ( -/obj/machinery/status_display/evac{ - pixel_y = 32 +/obj/structure/table/glass, +/obj/item/reagent_containers/glass/beaker{ + pixel_x = 4; + pixel_y = 4 + }, +/obj/item/reagent_containers/glass/beaker{ + pixel_x = -5; + pixel_y = 6 + }, +/obj/item/reagent_containers/dropper, +/obj/effect/turf_decal/tile/blue{ + dir = 1 }, /obj/effect/turf_decal/tile/blue{ dir = 4 }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/machinery/firealarm{ + pixel_y = 24 }, -/turf/open/floor/plasteel/cafeteria, +/turf/open/floor/plasteel/white, /area/security/prison) "abs" = ( -/obj/machinery/washing_machine, -/obj/structure/cable/yellow{ - icon_state = "1-2" +/obj/structure/table/glass, +/obj/item/reagent_containers/syringe, +/obj/item/reagent_containers/glass/bottle/morphine{ + pixel_y = 6 + }, +/obj/machinery/camera{ + c_tag = "Prison Sanitarium"; + network = list("ss13","prison") + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 }, /obj/effect/turf_decal/tile/blue{ dir = 4 }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/cafeteria, +/turf/open/floor/plasteel/white, /area/security/prison) "abt" = ( /obj/machinery/vending/hydroseeds{ @@ -459,52 +567,31 @@ /turf/open/floor/plasteel/dark, /area/security/execution/education) "abA" = ( -/obj/machinery/shower{ +/obj/structure/disposalpipe/segment, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) +"abB" = ( +/turf/closed/wall, +/area/maintenance/prison) +"abC" = ( +/obj/structure/weightmachine/weightlifter, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/turf/open/floor/plasteel/freezer, -/area/security/prison) -"abB" = ( -/obj/machinery/door/window/westleft{ - base_state = "right"; - dir = 4; - icon_state = "right"; - name = "Unisex Showers" - }, -/obj/machinery/light/small, -/turf/open/floor/plasteel/freezer, -/area/security/prison) -"abC" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/cells) "abD" = ( -/obj/structure/chair/stool, -/turf/open/floor/plasteel, -/area/security/prison) -"abF" = ( -/obj/structure/table, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/item/reagent_containers/food/condiment/peppermill{ - pixel_x = 3 - }, -/obj/item/reagent_containers/food/condiment/saltshaker{ - pixel_x = -3; - pixel_y = 5 +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/white/line{ + dir = 1 }, /turf/open/floor/plasteel, -/area/security/prison) -"abG" = ( -/obj/structure/table, -/obj/item/toy/cards/deck, -/obj/item/toy/cards/deck, -/turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/cells) "abH" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -530,38 +617,36 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "abI" = ( -/obj/structure/cable/yellow{ - icon_state = "2-4" +/obj/structure/bed, +/obj/item/clothing/suit/straight_jacket, +/obj/item/clothing/mask/muzzle, +/obj/effect/turf_decal/tile/blue{ + dir = 1 }, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel/white, /area/security/prison) "abJ" = ( -/obj/structure/window/reinforced, -/obj/structure/cable/yellow{ - icon_state = "4-8" +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/cafeteria, +/turf/open/floor/plasteel/white, /area/security/prison) "abK" = ( -/obj/structure/table, -/obj/structure/bedsheetbin, -/obj/structure/window/reinforced, -/obj/structure/cable/yellow{ - icon_state = "1-8" - }, +/obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ dir = 4 }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 }, -/turf/open/floor/plasteel/cafeteria, +/turf/open/floor/plasteel/white, /area/security/prison) "abL" = ( /turf/open/floor/plating, @@ -577,10 +662,10 @@ name = "Solar Maintenance"; req_access_txt = "10; 13" }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, /obj/structure/cable{ icon_state = "1-2" }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plating, /area/maintenance/solars/port/fore) "abV" = ( @@ -618,40 +703,35 @@ /turf/open/floor/plasteel/dark, /area/security/execution/education) "abY" = ( -/obj/machinery/door/airlock{ - name = "Unisex Restroom" +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/red{ + dir = 4 }, -/turf/open/floor/plasteel/freezer, -/area/security/prison) -"abZ" = ( -/obj/structure/table, -/obj/item/book/manual/chef_recipes{ - pixel_x = 2; - pixel_y = 6 +/obj/effect/turf_decal/tile/red{ + dir = 1 }, -/obj/item/clothing/head/chefhat, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, -/area/security/prison) -"aca" = ( -/obj/structure/table, +/area/security/prison/cells) +"abZ" = ( /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/item/toy/cards/deck, -/obj/item/toy/cards/deck, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, /turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/cells) "acb" = ( -/obj/structure/table, -/obj/item/storage/dice, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/white/line{ + dir = 10 + }, /turf/open/floor/plasteel, -/area/security/prison) -"acc" = ( -/obj/structure/chair/stool, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/cells) "acd" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/neutral{ @@ -663,50 +743,63 @@ /turf/open/floor/plasteel, /area/hallway/primary/aft) "ace" = ( -/obj/machinery/vending/sustenance{ - desc = "A vending machine normally reserved for work camps."; - name = "\improper sustenance vendor"; - product_slogans = "Enjoy your meal.;Enough calories to support any worker." +/obj/item/folder/red, +/obj/item/pen, +/obj/structure/table/glass, +/obj/item/folder/white{ + pixel_x = -4; + pixel_y = 2 }, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, /area/security/prison) "acf" = ( -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plating, +/obj/structure/table, +/obj/item/storage/box/prisoner{ + pixel_y = 8 + }, +/obj/item/storage/box/prisoner, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, /area/security/prison) "acg" = ( -/obj/machinery/light/small, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plating{ - icon_state = "panelscorched" +/obj/structure/cable/yellow{ + icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, /area/security/prison) "ach" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/machinery/door/airlock/external{ - name = "Security External Airlock"; - req_access_txt = "1" - }, -/turf/open/floor/plating, +/turf/open/floor/plasteel/dark, /area/security/prison) "acj" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/structure/sign/warning/vacuum/external{ - pixel_y = 32 - }, -/obj/effect/turf_decal/stripes/line{ +/obj/structure/closet/secure_closet/brig, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ dir = 4 }, -/turf/open/floor/plating, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/bot_white, +/obj/structure/extinguisher_cabinet{ + pixel_y = 30 + }, +/turf/open/floor/plasteel/dark, /area/security/prison) "ack" = ( /obj/structure/lattice/catwalk, @@ -739,514 +832,375 @@ /turf/open/floor/plasteel/dark, /area/security/execution/education) "acp" = ( -/obj/machinery/light/small{ +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/obj/structure/toilet/secret/prison{ - dir = 4 - }, -/turf/open/floor/plasteel/freezer, -/area/security/prison) +/turf/open/floor/plasteel, +/area/security/prison/cells) "acq" = ( -/obj/structure/table, -/obj/item/storage/box/donkpockets{ - pixel_x = 2; - pixel_y = 1 +/obj/structure/cable/yellow{ + icon_state = "1-2" }, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -23 - }, -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, -/area/security/prison) +/turf/open/floor/plasteel, +/area/security/prison/cells) "acr" = ( -/obj/structure/cable/yellow{ - icon_state = "1-4" +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/turf/open/floor/plasteel, -/area/security/prison) -"acs" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 - }, -/turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/cells) "act" = ( +/obj/effect/decal/cleanable/dirt, +/obj/item/toy/beach_ball/holoball, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"acu" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/holohoop{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/white/line{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Prison Yard"; + dir = 8; + network = list("ss13","prison") + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"acw" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "PermaLockdown"; + name = "Lockdown Shutters" + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/security/prison) +"acy" = ( +/obj/structure/table, +/obj/item/clothing/gloves/color/orange, +/obj/item/restraints/handcuffs, +/obj/item/reagent_containers/spray/pepper, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/obj/structure/extinguisher_cabinet{ + pixel_x = -26 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"acD" = ( +/obj/structure/punching_bag, +/obj/effect/turf_decal/bot, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"acE" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/security/prison/cells) +"acF" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/white/line{ + dir = 5 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"acG" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/white/line, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"acJ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/white/line{ + dir = 9 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"acK" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "PermaLockdown"; + name = "Lockdown Shutters" + }, +/obj/effect/turf_decal/delivery, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/prison) +"acL" = ( +/obj/structure/table, +/obj/item/clothing/under/rank/prisoner/skirt{ + pixel_x = -13; + pixel_y = 5 + }, +/obj/item/clothing/under/rank/prisoner/skirt{ + pixel_x = 9; + pixel_y = 5 + }, +/obj/item/clothing/under/rank/prisoner{ + pixel_x = -2; + pixel_y = 5 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"acM" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/security/prison) +"acN" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"acO" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"acR" = ( +/obj/structure/closet/secure_closet/brig, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"acV" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/toilet{ + dir = 4 + }, +/obj/structure/window/reinforced/tinted, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) +"acW" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) +"acX" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/door/airlock/grunge{ + name = "Permanent Cell 3"; + wiretypepath = /datum/wires/airlock/security + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) +"acY" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"ada" = ( +/obj/machinery/holopad, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"adb" = ( +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/turf/open/floor/plasteel/dark/corner{ + dir = 4 + }, +/area/security/prison/cells) +"adc" = ( +/obj/structure/sign/warning/securearea, +/turf/closed/wall/r_wall, +/area/security/prison) +"add" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/security/prison/cells) +"ade" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"adf" = ( /obj/structure/cable/yellow{ icon_state = "4-8" }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison) +"adg" = ( /obj/structure/cable/yellow{ - icon_state = "1-8" + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"adh" = ( +/obj/structure/closet/secure_closet/brig, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"adi" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "4-8" }, /obj/structure/cable/yellow{ icon_state = "2-8" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"acu" = ( -/obj/machinery/holopad, /obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/security/prison) -"acv" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/security/prison) -"acw" = ( -/obj/structure/cable/yellow{ - icon_state = "1-8" - }, -/turf/open/floor/plasteel, -/area/security/prison) -"acx" = ( -/obj/machinery/cryopod{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"acy" = ( -/obj/machinery/door/airlock/external{ - name = "Escape Pod Two" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plating, -/area/security/prison) -"acA" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/poddoor/preopen{ - id = "executionfireblast" - }, -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/education) -"acB" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/preopen{ - id = "executionfireblast" - }, -/obj/machinery/door/firedoor, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/education) -"acC" = ( -/obj/machinery/door/window/brigdoor{ - name = "Justice Chamber"; - req_access_txt = "3" - }, -/obj/machinery/atmospherics/pipe/simple/general/hidden, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 - }, -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/machinery/door/window/brigdoor{ - dir = 1; - name = "Justice Chamber"; - req_access_txt = "3" - }, -/obj/machinery/door/firedoor, -/obj/machinery/door/poddoor/preopen{ - id = "executionfireblast" - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/education) -"acD" = ( -/obj/structure/table, -/obj/machinery/microwave{ - pixel_x = -3; - pixel_y = 6 - }, -/turf/open/floor/plating{ - icon_state = "platingdmg1" - }, -/area/security/prison) -"acE" = ( -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, -/area/security/prison) -"acF" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/obj/machinery/light, -/turf/open/floor/plasteel, -/area/security/prison) -"acG" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 - }, -/obj/item/kirbyplants{ - icon_state = "plant-13" - }, -/turf/open/floor/plasteel, -/area/security/prison) -"acH" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 - }, -/obj/item/radio/intercom{ - desc = "Talk through this. It looks like it has been modified to not broadcast."; - name = "Prison Intercom (General)"; - pixel_y = -28; - prison_radio = 1 - }, -/obj/machinery/camera{ - c_tag = "Prison Chamber"; - dir = 1; - network = list("ss13","prison") - }, -/turf/open/floor/plasteel, -/area/security/prison) -"acI" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"acJ" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"acK" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/turf/open/floor/plasteel, -/area/security/prison) -"acL" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, -/obj/machinery/light, -/turf/open/floor/plasteel, -/area/security/prison) -"acM" = ( -/obj/structure/table, -/obj/item/paper_bin{ - pixel_x = -3; - pixel_y = 7 - }, -/obj/item/pen, -/obj/machinery/computer/cryopod{ - dir = 8; - pixel_x = 26 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"acN" = ( -/obj/structure/table/glass, -/obj/item/reagent_containers/syringe, -/obj/item/reagent_containers/glass/bottle/morphine{ - pixel_y = 6 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/security/prison) -"acO" = ( -/obj/machinery/newscaster{ - pixel_y = 32 - }, -/obj/structure/table/glass, -/obj/item/reagent_containers/glass/beaker{ - pixel_x = 4; - pixel_y = 4 - }, -/obj/item/reagent_containers/glass/beaker{ - pixel_x = -5; - pixel_y = 6 - }, -/obj/item/reagent_containers/dropper, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/security/prison) -"acR" = ( -/obj/structure/table/glass, -/obj/item/reagent_containers/syringe, -/obj/item/reagent_containers/glass/bottle/morphine{ - pixel_y = 6 - }, -/obj/machinery/camera{ - c_tag = "Prison Sanitarium"; - network = list("ss13","prison") - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/security/prison) -"acV" = ( -/obj/structure/table, -/obj/item/reagent_containers/glass/bottle/morphine{ - pixel_x = -4; - pixel_y = 1 - }, -/obj/item/reagent_containers/glass/bottle/chloralhydrate{ - name = "chloral hydrate bottle" - }, -/obj/item/reagent_containers/glass/bottle/toxin{ - pixel_x = 6; - pixel_y = 8 - }, -/obj/item/reagent_containers/glass/bottle/morphine{ - pixel_x = 5; - pixel_y = 1 - }, -/obj/item/reagent_containers/syringe, -/obj/item/reagent_containers/glass/bottle/facid{ - name = "fluorosulfuric acid bottle"; - pixel_x = -3; - pixel_y = 6 - }, -/obj/item/reagent_containers/syringe{ - pixel_y = 5 - }, -/obj/item/reagent_containers/dropper, -/obj/machinery/airalarm/all_access{ - dir = 4; - pixel_x = -24 - }, -/obj/machinery/button/ignition{ - id = "executionburn"; - name = "Justice Ignition Switch"; - pixel_x = -25; - pixel_y = 36 - }, -/obj/machinery/button/door{ - id = "executionfireblast"; - name = "Justice Area Lockdown"; - pixel_x = -25; - pixel_y = 26; - req_access_txt = "2" - }, -/obj/item/assembly/signaler{ - pixel_x = -3; - pixel_y = 2 - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 8 - }, -/obj/machinery/button/flasher{ - id = "justiceflash"; - name = "Justice Flash Control"; - pixel_x = -36; - pixel_y = 36; - req_access_txt = "1" - }, -/obj/machinery/button/door{ - id = "SecJusticeChamber"; - layer = 4; - name = "Justice Vent Control"; - pixel_x = -36; - pixel_y = 26; - req_access_txt = "3" - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/education) -"acW" = ( -/obj/structure/table, -/obj/item/folder/red{ - pixel_x = 3 - }, -/obj/item/taperecorder{ - pixel_x = -3 - }, -/obj/item/storage/fancy/cigarettes, -/obj/item/assembly/flash/handheld, -/obj/item/reagent_containers/spray/pepper, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/education) -"acX" = ( -/obj/machinery/atmospherics/pipe/simple/general/hidden, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/education) -"acY" = ( -/obj/structure/sink/kitchen{ - desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; - name = "old sink"; - pixel_y = 28 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/education) -"ada" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 - }, -/turf/closed/wall/r_wall, -/area/security/prison) -"adb" = ( -/obj/machinery/door/poddoor/preopen{ - id = "permacell3"; - name = "Cell Shutters" - }, -/obj/machinery/door/airlock/public/glass{ - id_tag = "permabolt3"; - name = "Cell 3" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plasteel, -/area/security/prison) -"adc" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/security/prison) -"add" = ( -/obj/machinery/door/poddoor/preopen{ - id = "permacell2"; - name = "Cell Shutters" - }, -/obj/machinery/door/airlock/public/glass{ - id_tag = "permabolt2"; - name = "Cell 2" - }, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plasteel, -/area/security/prison) -"ade" = ( -/obj/machinery/door/poddoor/preopen{ - id = "permacell1"; - name = "Cell Shutters" - }, -/obj/machinery/door/airlock/public/glass{ - id_tag = "permabolt1"; - name = "Cell 1" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plasteel, -/area/security/prison) -"adf" = ( -/obj/machinery/light/small{ - dir = 4 + icon_state = "0-8" }, /turf/open/floor/plating, /area/security/prison) -"adg" = ( -/obj/structure/bed, -/obj/item/clothing/suit/straight_jacket, -/obj/item/clothing/glasses/sunglasses/blindfold, -/obj/item/clothing/mask/muzzle, -/turf/open/floor/plasteel/white, -/area/security/prison) -"adh" = ( -/obj/structure/cable/yellow{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel/white, -/area/security/prison) -"adi" = ( -/obj/structure/bed, -/obj/item/clothing/suit/straight_jacket, -/obj/item/clothing/glasses/sunglasses/blindfold, -/obj/item/clothing/mask/muzzle, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel/white, -/area/security/prison) "adk" = ( /obj/structure/sign/poster/contraband/scum{ pixel_y = -32 @@ -1264,155 +1218,210 @@ /turf/open/floor/plating, /area/maintenance/fore) "adm" = ( -/obj/structure/table, -/obj/item/flashlight/lamp, -/obj/structure/reagent_dispensers/peppertank{ - pixel_x = -29 +/obj/effect/spawner/lootdrop/prison_contraband, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/education) -"adn" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/chair/office/dark{ - dir = 1 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ +/obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/bed{ + dir = 8 + }, +/obj/item/bedsheet/red{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, /turf/open/floor/plasteel/dark, -/area/security/execution/education) +/area/security/prison/cells) +"adn" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/landmark/start/prisoner, +/obj/machinery/button/door{ + id = "permacells3"; + name = "Privacy Shutters"; + pixel_y = -25 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "ado" = ( -/obj/machinery/atmospherics/pipe/simple/general/hidden, -/turf/open/floor/plasteel/dark, -/area/security/execution/education) +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "permacells3"; + name = "Privacy Shutters" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/security/prison/cells) "adp" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel/dark, /area/security/execution/education) "adq" = ( /obj/structure/cable/yellow{ - icon_state = "1-2" + icon_state = "4-8" }, -/obj/machinery/firealarm{ - dir = 8; - pixel_x = 28 +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 }, -/obj/machinery/light{ +/turf/open/floor/plasteel, +/area/security/prison/cells) +"adr" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"ads" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"adu" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"adv" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"adw" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"adx" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/machinery/light/small, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"ady" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/door/airlock/security/glass{ + id_tag = "permaouter"; + name = "Permabrig Transfer"; + req_access_txt = "2" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/plasteel/dark, -/area/security/execution/education) -"adr" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall/r_wall, -/area/security/execution/education) -"ads" = ( -/obj/structure/bed, -/obj/machinery/camera{ - c_tag = "Prison Cell 3"; - network = list("ss13","prison") - }, -/turf/open/floor/plasteel, -/area/security/prison) -"adt" = ( -/obj/structure/chair/stool, -/obj/machinery/light/small{ - dir = 1 - }, -/obj/machinery/button/door{ - id = "permabolt3"; - name = "Cell Bolt Control"; - normaldoorcontrol = 1; - pixel_y = 25; - specialfunctions = 4 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"adu" = ( -/obj/structure/bed, -/obj/machinery/camera{ - c_tag = "Prison Cell 2"; - network = list("ss13","prison") - }, -/turf/open/floor/plasteel, -/area/security/prison) -"adv" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/security/prison) -"adw" = ( -/obj/structure/chair/stool, -/obj/machinery/light/small{ - dir = 1 - }, -/obj/machinery/button/door{ - id = "permabolt2"; - name = "Cell Bolt Control"; - normaldoorcontrol = 1; - pixel_y = 25; - specialfunctions = 4 - }, -/turf/open/floor/plating{ - icon_state = "platingdmg2" - }, -/area/security/prison) -"adx" = ( -/obj/structure/bed, -/obj/machinery/camera{ - c_tag = "Prison Cell 1"; - network = list("ss13","prison") - }, -/turf/open/floor/plasteel, -/area/security/prison) -"ady" = ( -/obj/structure/chair/stool, -/obj/machinery/light/small{ - dir = 1 - }, -/obj/machinery/button/door{ - id = "permabolt1"; - name = "Cell Bolt Control"; - normaldoorcontrol = 1; - pixel_y = 25; - specialfunctions = 4 - }, -/turf/open/floor/plasteel, /area/security/prison) "adz" = ( -/turf/open/floor/plating{ - icon_state = "platingdmg1" +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 }, +/turf/open/floor/plasteel, /area/security/prison) "adA" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/machinery/light{ +/obj/structure/table, +/obj/item/storage/box/bodybags{ + pixel_x = 4; + pixel_y = 2 + }, +/obj/item/pen, +/obj/item/storage/box/prisoner, +/obj/machinery/camera{ + c_tag = "Prison Hallway Aft"; + dir = 1; + network = list("ss13","prison") + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ dir = 8 }, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -23 +/obj/effect/turf_decal/tile/red{ + dir = 1 }, -/turf/open/floor/plasteel/white, -/area/security/prison) -"adB" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" +/obj/machinery/computer/security/telescreen/prison{ + dir = 1; + pixel_y = -27 }, -/turf/open/floor/plasteel/white, +/obj/machinery/light, +/turf/open/floor/plasteel/dark, /area/security/prison) "adC" = ( -/obj/machinery/flasher{ - id = "insaneflash"; - pixel_x = 26 +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-8" }, -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plasteel/white, +/obj/structure/cable/yellow, +/turf/open/floor/plating, /area/security/prison) "adD" = ( /obj/structure/lattice, @@ -1434,12 +1443,11 @@ /turf/open/space/basic, /area/space) "adG" = ( -/obj/docking_port/stationary/random{ - id = "pod_lavaland2"; - name = "lavaland" +/obj/machinery/door/airlock/external{ + name = "Escape Pod Two" }, -/turf/open/space, -/area/space/nearstation) +/turf/open/floor/plating, +/area/security/prison) "adI" = ( /obj/structure/rack, /obj/item/hatchet, @@ -1468,150 +1476,81 @@ }, /turf/open/floor/plasteel/dark, /area/security/execution/education) -"adK" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/education) -"adL" = ( -/obj/machinery/atmospherics/pipe/simple/general/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/education) "adM" = ( -/obj/machinery/button/door{ - id = "prisonereducation"; - name = "Door Bolt Control"; - normaldoorcontrol = 1; - pixel_y = -25; - specialfunctions = 4 +/obj/machinery/computer/arcade/orion_trail{ + dir = 4 }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 }, -/turf/open/floor/plasteel/dark, -/area/security/execution/education) +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "adN" = ( -/obj/machinery/light_switch{ - pixel_x = 26 - }, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, +/obj/structure/chair/stool, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 }, -/turf/open/floor/plasteel/dark, -/area/security/execution/education) -"adO" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/machinery/flasher{ - id = "PCell 3"; - pixel_x = -28 - }, -/turf/open/floor/plating{ - icon_state = "platingdmg3" - }, -/area/security/prison) -"adP" = ( -/obj/structure/table, -/obj/item/paper, -/obj/item/pen, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"adQ" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 4 - }, -/turf/closed/wall, -/area/security/prison) -"adR" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/obj/machinery/flasher{ - id = "PCell 2"; - pixel_x = -28 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"adS" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"adT" = ( -/obj/structure/table, -/obj/item/paper, -/obj/item/pen, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/turf/open/floor/plasteel, -/area/security/prison) -"adU" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/machinery/flasher{ - id = "PCell 1"; - pixel_x = -28 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"adV" = ( -/obj/item/folder/red, -/obj/item/pen, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/table/glass, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"adO" = ( +/obj/structure/cable/yellow, +/obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/security/prison/upper"; + damage_deflection = 21; + desc = "A control terminal for the area's electrical systems. It's secured with a durable antitampering plasteel cage."; + name = "Armored Prison Wing Cells APC"; + pixel_y = -26 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"adP" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"adQ" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"adR" = ( /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 }, -/turf/open/floor/plasteel/white, -/area/security/prison) -"adW" = ( /obj/structure/cable/yellow{ icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"adS" = ( /obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, /obj/effect/turf_decal/tile/red{ dir = 8 }, -/turf/open/floor/plasteel/white, -/area/security/prison) -"adX" = ( -/obj/structure/bed/roller, -/obj/structure/bed/roller, -/obj/machinery/iv_drip, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/iv_drip, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/security/prison) +/turf/open/floor/plasteel, +/area/security/prison/cells) "adY" = ( /turf/closed/wall/r_wall, /area/security/warden) @@ -1620,12 +1559,12 @@ /turf/open/floor/plating, /area/maintenance/solars/port/fore) "aef" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/maintenance/solars/port/fore) "aeg" = ( @@ -1663,84 +1602,72 @@ /turf/open/floor/plasteel/dark, /area/security/execution/education) "aej" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security{ - aiControlDisabled = 1; - id_tag = "prisonereducation"; - name = "Prisoner Education Chamber"; - req_access_txt = "3" - }, -/obj/structure/cable/yellow{ - icon_state = "1-2" +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "permacells2"; + name = "Privacy Shutters" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ +/turf/open/floor/plating, +/area/security/prison/cells) +"aek" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/turf/open/floor/plasteel, -/area/security/execution/education) -"aek" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/door/airlock/grunge{ + name = "Permanent Cell 2"; + wiretypepath = /datum/wires/airlock/security + }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall/r_wall, -/area/security/prison) +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "ael" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall, +/obj/structure/tank_dispenser/oxygen, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, /area/security/prison) "aem" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Long-Term Cell 3"; - req_access_txt = "2" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"aen" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Long-Term Cell 2"; - req_access_txt = "2" - }, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"aeo" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Long-Term Cell 1"; - req_access_txt = "2" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"aep" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security/glass{ - name = "Prison Sanitarium"; - req_access_txt = "2" - }, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/door/airlock/grunge{ + name = "Permanent Cell 1"; + wiretypepath = /datum/wires/airlock/security + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) +"aen" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/public/glass{ + name = "Visitation" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "aeq" = ( /turf/closed/wall/r_wall, /area/ai_monitored/security/armory) @@ -1774,7 +1701,7 @@ name = "3maintenance loot spawner" }, /obj/effect/spawner/lootdrop/armory_contraband{ - loot = list(/obj/item/gun/ballistic/automatic/pistol = 5, /obj/item/gun/ballistic/shotgun/automatic/combat = 5, /obj/item/gun/ballistic/revolver/mateba, /obj/item/gun/ballistic/automatic/pistol/deagle, /obj/item/storage/box/syndie_kit/throwing_weapons = 3) + loot = list(/obj/item/gun/ballistic/automatic/pistol=5,/obj/item/gun/ballistic/shotgun/automatic/combat=5,/obj/item/gun/ballistic/revolver/mateba,/obj/item/gun/ballistic/automatic/pistol/deagle,/obj/item/storage/box/syndie_kit/throwing_weapons=3) }, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -1835,38 +1762,6 @@ }, /turf/open/floor/plasteel/dark, /area/security/execution/education) -"aeI" = ( -/obj/item/tank/internals/oxygen/red{ - pixel_x = -4; - pixel_y = -1 - }, -/obj/item/tank/internals/oxygen/red{ - pixel_x = 4; - pixel_y = -1 - }, -/obj/item/tank/internals/anesthetic{ - pixel_x = 2 - }, -/obj/item/storage/toolbox/mechanical, -/obj/item/clothing/mask/gas, -/obj/item/clothing/mask/gas, -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, -/obj/machinery/atmospherics/pipe/manifold/general/visible, -/obj/item/wrench, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/education) "aeJ" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 9 @@ -1885,275 +1780,162 @@ /turf/open/floor/plasteel/dark, /area/security/execution/education) "aeK" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable/yellow{ - icon_state = "1-4" +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, -/area/security/prison) -"aeL" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" +/obj/effect/turf_decal/tile/neutral{ + dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/obj/structure/sign/warning/securearea{ - desc = "A warning sign which reads 'WARNING: Do Not Enter When Red Light Shows', detailing the penalties that any Nanotrasen employee or silicon will suffer if violating this rule."; - name = "WARNING: Do Not Enter When Red Light Shows"; - pixel_y = 32 - }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, -/area/security/prison) -"aeM" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/structure/cable/yellow{ - icon_state = "2-4" - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, -/area/security/prison) -"aeN" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ +/obj/effect/turf_decal/tile/neutral{ dir = 1 }, -/obj/structure/cable/yellow{ - icon_state = "4-8" +/obj/machinery/button/door{ + id = "permacells2"; + name = "Privacy Shutters"; + pixel_x = -25 }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/effect/landmark/start/prisoner, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) +"aeL" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) +"aeN" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "aeO" = ( -/obj/machinery/button/door{ - id = "permacell3"; - name = "Cell 3 Lockdown"; - pixel_x = -4; - pixel_y = 25; - req_access_txt = "2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/machinery/button/flasher{ - id = "PCell 3"; - pixel_x = 6; - pixel_y = 24 +/obj/effect/turf_decal/tile/neutral{ + dir = 8 }, -/obj/structure/cable/yellow{ - icon_state = "4-8" +/obj/effect/turf_decal/tile/neutral{ + dir = 1 }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, -/area/security/prison) -"aeP" = ( +/obj/effect/landmark/start/prisoner, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/machinery/computer/security/telescreen{ - desc = "Used for watching Prison Wing holding areas."; - name = "Prison Monitor"; - network = list("prison"); - pixel_y = 30 - }, -/obj/machinery/camera{ - c_tag = "Prison Hallway Port"; - network = list("ss13","prison") - }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, -/area/security/prison) -"aeQ" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/structure/cable/yellow{ - icon_state = "2-4" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, -/area/security/prison) -"aeR" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/structure/cable/yellow{ - icon_state = "1-4" - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, -/area/security/prison) -"aeS" = ( /obj/machinery/button/door{ - id = "permacell2"; - name = "Cell 2 Lockdown"; - pixel_x = -4; - pixel_y = 25; - req_access_txt = "2" + id = "permacells1"; + name = "Privacy Shutters"; + pixel_x = 25 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/button/flasher{ - id = "PCell 2"; - pixel_x = 6; - pixel_y = 24 - }, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, -/area/security/prison) +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "aeT" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" +/obj/effect/turf_decal/tile/neutral{ + dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/machinery/computer/security/telescreen{ - desc = "Used for watching Prison Wing holding areas."; - name = "Prison Monitor"; - network = list("prison"); - pixel_y = 30 +/obj/effect/turf_decal/tile/neutral{ + dir = 8 }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = -24 + }, +/turf/open/floor/plasteel/dark, /area/security/prison) "aeU" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/machinery/light{ +/obj/machinery/camera{ + c_tag = "Security - EVA Storage"; dir = 1 }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel/dark, /area/security/prison) "aeV" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/structure/cable/yellow{ - icon_state = "4-8" +/obj/effect/turf_decal/tile/neutral{ + dir = 8 }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/security/prison) "aeW" = ( -/obj/machinery/button/door{ - id = "permacell1"; - name = "Cell 1 Lockdown"; - pixel_x = -4; - pixel_y = 25; - req_access_txt = "2" +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security/glass{ + name = "Security E.V.A. Storage"; + req_access_txt = "3" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/button/flasher{ - id = "PCell 1"; - pixel_x = 6; - pixel_y = 24 - }, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/security/prison) "aeY" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" +/obj/effect/turf_decal/tile/red{ + dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/effect/turf_decal/tile/red{ dir = 4 }, -/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeZ" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/light/small{ + dir = 4 }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ +/obj/machinery/button/door{ + id = "Prison Gate"; + name = "Prison Wing Lockdown"; + pixel_x = 26; + req_access_txt = "2" + }, +/obj/effect/turf_decal/tile/red{ dir = 1 }, -/obj/structure/sign/warning/pods{ - pixel_y = 30 - }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, -/area/security/prison) -"afa" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/effect/turf_decal/tile/red{ dir = 4 }, -/obj/machinery/button/flasher{ - id = "insaneflash"; - pixel_y = 26 - }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, -/area/security/prison) -"afb" = ( -/obj/structure/cable/yellow{ - icon_state = "1-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, -/area/security/prison) -"afc" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable/yellow{ - icon_state = "0-8" - }, -/obj/structure/cable/yellow{ - icon_state = "2-8" - }, -/turf/open/floor/plating, -/area/security/prison) -"afd" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, -/obj/item/kirbyplants{ - icon_state = "plant-16" - }, -/obj/structure/sign/warning/securearea{ - desc = "A warning sign which reads 'WARNING: Criminally Insane Inmates', describing the possible hazards of those contained within."; - name = "WARNING: Criminally Insane Inmates"; - pixel_y = 32 - }, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, /turf/open/floor/plasteel, /area/security/prison) "aff" = ( @@ -2207,9 +1989,6 @@ }, /area/holodeck/rec_center) "afE" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/machinery/door/airlock/external{ name = "Solar Maintenance"; req_access_txt = "10; 13" @@ -2217,133 +1996,95 @@ /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/maintenance/solars/port/fore) "afF" = ( -/obj/item/kirbyplants{ - icon_state = "applebush" +/obj/effect/spawner/lootdrop/prison_contraband, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 +/obj/effect/turf_decal/tile/neutral{ + dir = 8 }, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/bed, +/obj/item/bedsheet/red, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "afG" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ dir = 1 }, -/turf/open/floor/plasteel, -/area/security/prison) -"afH" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/red{ +/obj/structure/toilet{ dir = 1 }, -/turf/open/floor/plasteel, -/area/security/prison) -"afI" = ( +/obj/structure/window/reinforced/tinted{ + dir = 8 + }, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) +"afH" = ( +/turf/closed/wall, +/area/security/prison/cells) +"afI" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ dir = 1 }, -/turf/open/floor/plasteel, -/area/security/prison) -"afJ" = ( -/obj/machinery/light, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/structure/window/reinforced/tinted{ dir = 4 }, -/obj/machinery/newscaster/security_unit{ - pixel_y = -30 - }, -/obj/effect/turf_decal/tile/red{ +/obj/structure/toilet{ dir = 1 }, -/turf/open/floor/plasteel, -/area/security/prison) -"afK" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/obj/effect/turf_decal/tile/red{ +/obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/turf/open/floor/plasteel, -/area/security/prison) +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "afL" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, +/obj/effect/decal/cleanable/dirt, /obj/structure/cable/yellow{ icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, /obj/effect/turf_decal/tile/red{ dir = 1 }, -/turf/open/floor/plasteel, -/area/security/prison) -"afM" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/machinery/firealarm{ - dir = 1; - pixel_y = -24 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 + dir = 4; + pixel_x = -24 }, /turf/open/floor/plasteel, -/area/security/prison) -"afN" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/structure/extinguisher_cabinet{ - pixel_y = -30 - }, -/obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"afO" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/item/radio/intercom{ - name = "Station Intercom (General)"; - pixel_y = -30 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"afP" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/airalarm{ - dir = 1; - pixel_y = -22 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/cells) "afQ" = ( /obj/machinery/door/airlock/external{ name = "Solar Maintenance"; @@ -2356,55 +2097,48 @@ /turf/open/floor/plating, /area/maintenance/solars/starboard/fore) "afR" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security/glass{ + name = "Prison Wing"; + req_access_txt = "1" }, /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/red{ +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 }, -/turf/open/floor/plasteel, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, /area/security/prison) "afS" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security/glass{ + name = "Prison Wing"; + req_access_txt = "1" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/security/prison) -"afT" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/obj/machinery/light, -/obj/effect/turf_decal/tile/red{ - dir = 1 +"afW" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/yellow{ + icon_state = "1-8" }, -/turf/open/floor/plasteel, -/area/security/prison) -"afU" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ dir = 8 }, /obj/effect/turf_decal/tile/red{ dir = 1 }, /turf/open/floor/plasteel, -/area/security/prison) -"afV" = ( -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"afW" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable/yellow, -/turf/open/floor/plating, -/area/security/prison) +/area/security/prison/cells) "afX" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 @@ -2554,173 +2288,34 @@ icon_state = "platingdmg2" }, /area/maintenance/solars/port/fore) -"agE" = ( -/obj/structure/table, -/obj/item/folder/red{ - pixel_x = 3 - }, -/obj/item/folder/white{ - pixel_x = -4; - pixel_y = 2 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"agF" = ( -/obj/structure/rack, -/obj/item/restraints/handcuffs, -/obj/item/assembly/flash/handheld, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"agG" = ( -/obj/structure/table, -/obj/item/storage/box/bodybags{ - pixel_x = 4; - pixel_y = 2 - }, -/obj/item/pen, -/obj/item/storage/box/prisoner, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) "agH" = ( -/obj/structure/closet/secure_closet/brig, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"agI" = ( -/obj/structure/closet/secure_closet/brig, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"agJ" = ( -/obj/structure/sign/warning/securearea, -/turf/closed/wall, -/area/security/prison) -"agK" = ( -/obj/machinery/door/firedoor, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/machinery/door/airlock/security/glass{ - name = "Prison Wing"; - req_access_txt = "1" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/cells) +"agI" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "agL" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/security/prison) -"agM" = ( -/obj/machinery/door/firedoor, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/airlock/security/glass{ - name = "Prison Wing"; - req_access_txt = "1" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plasteel, -/area/security/prison) "agN" = ( -/obj/structure/sign/warning/securearea{ - desc = "A warning sign which reads 'WARNING: Dangerous Inmates'."; - name = "\improper WARNING: Dangerous Inmates" - }, /turf/closed/wall, -/area/security/prison) -"agO" = ( -/obj/structure/table, -/obj/machinery/recharger{ - pixel_y = 4 - }, -/obj/structure/reagent_dispensers/peppertank{ - pixel_y = -30 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"agP" = ( -/obj/structure/table, -/obj/item/paper_bin{ - pixel_x = -3; - pixel_y = 7 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) +/area/space) "agQ" = ( /obj/machinery/holopad{ pixel_y = -15 @@ -2843,83 +2438,22 @@ }, /turf/open/floor/plating, /area/maintenance/solars/port/fore) -"ahu" = ( -/obj/machinery/suit_storage_unit/security, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/brig) "ahv" = ( -/obj/structure/tank_dispenser/oxygen, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/blue{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/blue{ dir = 8 }, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"ahw" = ( -/obj/structure/extinguisher_cabinet{ - pixel_x = 27 +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" }, -/obj/machinery/suit_storage_unit/security, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/security/brig) "ahx" = ( /turf/closed/wall, /area/security/brig) -"ahy" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/machinery/door/poddoor/preopen{ - id = "Prison Gate"; - name = "Security Blast Door" - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/security/brig) -"ahz" = ( -/obj/machinery/door/poddoor/preopen{ - id = "Prison Gate"; - name = "Security Blast Door" - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/security/brig) -"ahA" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/poddoor/preopen{ - id = "Prison Gate"; - name = "Security Blast Door" - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/security/brig) "ahB" = ( /turf/closed/wall, /area/security/warden) @@ -3210,96 +2744,36 @@ /turf/open/floor/plating, /area/security/brig) "air" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" +/obj/machinery/door/poddoor/shutters{ + id = "visitation"; + name = "Visitation Shutters" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/door/window/southright{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/security/brig) "ais" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/machinery/light/small, -/obj/machinery/camera{ - c_tag = "Security - EVA Storage"; +/obj/structure/chair/stool, +/obj/effect/turf_decal/tile/blue{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/blue{ dir = 8 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/security/brig) "ait" = ( -/obj/machinery/door/firedoor, /obj/machinery/door/airlock/security/glass{ - name = "Security E.V.A. Storage"; - req_access_txt = "1" - }, -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"aiu" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/structure/cable/yellow{ - icon_state = "2-8" - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"aiv" = ( -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"aiw" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/light/small{ - dir = 4 - }, -/obj/machinery/button/door{ - id = "Prison Gate"; - name = "Prison Wing Lockdown"; - pixel_x = 26; + name = "Prison Visitation"; req_access_txt = "2" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Lockdown Shutters" }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/security/brig) "aix" = ( /obj/structure/closet{ @@ -3531,45 +3005,10 @@ "ajm" = ( /turf/closed/wall/r_wall, /area/security/brig) -"ajn" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security/glass{ - name = "Prison Wing"; - req_access_txt = "1" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) "ajo" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/security/brig) -"ajp" = ( -/obj/machinery/door/firedoor, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/airlock/security/glass{ - name = "Prison Wing"; - req_access_txt = "1" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) "ajq" = ( /obj/structure/closet{ name = "Evidence Closet 2" @@ -4704,6 +4143,10 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/machinery/light_switch{ + pixel_x = -10; + pixel_y = -26 + }, /turf/open/floor/plasteel, /area/security/range) "amt" = ( @@ -6532,6 +5975,10 @@ pixel_x = -3; pixel_y = 5 }, +/obj/machinery/light_switch{ + pixel_x = 16; + pixel_y = -26 + }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "ast" = ( @@ -8550,6 +7997,20 @@ }, /turf/open/floor/plating, /area/maintenance/port/fore) +"ayq" = ( +/obj/machinery/camera{ + c_tag = "Prison Central"; + dir = 8; + network = list("ss13","prison") + }, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison/upper) "ayu" = ( /obj/machinery/door/window/northleft{ dir = 8; @@ -9066,6 +8527,9 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/machinery/light/small{ + dir = 1 + }, /turf/open/floor/plating{ icon_state = "platingdmg2" }, @@ -9614,6 +9078,16 @@ }, /turf/open/floor/plating, /area/maintenance/fore) +"aCJ" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "aCM" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -9633,6 +9107,13 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, /area/maintenance/port/fore) +"aDg" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison) "aDu" = ( /turf/closed/wall, /area/hallway/primary/fore) @@ -9872,6 +9353,10 @@ icon_state = "platingdmg1" }, /area/maintenance/fore) +"aEv" = ( +/obj/structure/lattice, +/turf/open/space, +/area/space/station_ruins) "aEI" = ( /obj/machinery/airalarm{ dir = 4; @@ -11161,6 +10646,10 @@ /obj/structure/lattice, /turf/open/space, /area/space/nearstation) +"aME" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/security/prison/cells) "aMG" = ( /obj/structure/table, /obj/item/aiModule/core/full/asimov, @@ -13073,9 +12562,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "aWV" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "aWW" = ( @@ -14110,6 +13597,13 @@ }, /turf/open/floor/plasteel, /area/security/checkpoint/engineering) +"aZO" = ( +/obj/effect/spawner/structure/window/reinforced/tinted, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/prison) "aZQ" = ( /obj/effect/landmark/start/ai/secondary, /obj/item/radio/intercom{ @@ -14819,9 +14313,6 @@ /turf/open/floor/plasteel, /area/hallway/primary/port) "bca" = ( -/obj/structure/chair{ - dir = 8 - }, /obj/machinery/light{ dir = 4 }, @@ -14833,6 +14324,7 @@ /obj/effect/turf_decal/tile/brown{ dir = 4 }, +/obj/machinery/piratepad/civilian, /turf/open/floor/plasteel, /area/hallway/primary/port) "bcb" = ( @@ -15099,13 +14591,13 @@ /turf/open/floor/plasteel, /area/hallway/primary/port) "bdv" = ( -/obj/structure/chair{ - dir = 8 - }, /obj/effect/turf_decal/tile/brown, /obj/effect/turf_decal/tile/brown{ dir = 4 }, +/obj/machinery/computer/piratepad_control/civilian{ + dir = 8 + }, /turf/open/floor/plasteel, /area/hallway/primary/port) "bdw" = ( @@ -15573,6 +15065,9 @@ /obj/structure/cable/yellow, /turf/open/floor/plating, /area/security/checkpoint/engineering) +"bgb" = ( +/turf/closed/wall/r_wall, +/area/security/prison/cells) "bgh" = ( /obj/structure/table/reinforced, /obj/item/paper_bin{ @@ -16571,13 +16066,15 @@ /obj/effect/turf_decal/tile/neutral{ dir = 1 }, -/obj/structure/cable, /obj/effect/turf_decal/tile/neutral{ dir = 8 }, /obj/effect/turf_decal/tile/neutral{ dir = 4 }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, /turf/open/floor/plasteel, /area/hallway/primary/port) "bke" = ( @@ -17180,6 +16677,9 @@ dir = 1 }, /obj/effect/turf_decal/tile/neutral, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, /turf/open/floor/plasteel, /area/hallway/primary/port) "bmc" = ( @@ -19504,6 +19004,15 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port) +"bvX" = ( +/obj/item/stack/sticky_tape, +/obj/item/stack/sheet/cardboard{ + amount = 14 + }, +/obj/item/stack/packageWrap, +/obj/machinery/light/small, +/turf/open/floor/plasteel, +/area/security/prison/upper) "bvY" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -19623,6 +19132,10 @@ /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/machinery/navbeacon{ + codes_txt = "patrol;next_patrol=14-Starboard-Central"; + location = "13.2-Tcommstore" + }, /turf/open/floor/plasteel/dark/corner, /area/hallway/primary/starboard) "bxn" = ( @@ -19934,6 +19447,10 @@ /obj/machinery/atmospherics/pipe/simple/orange/hidden{ dir = 4 }, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = 24 + }, /turf/open/floor/plasteel/dark/corner, /area/hallway/primary/starboard) "bzi" = ( @@ -21691,10 +21208,6 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/machinery/navbeacon{ - codes_txt = "patrol;next_patrol=14-Starboard-Central"; - location = "13.2-Tcommstore" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/hallway/primary/starboard) @@ -21705,10 +21218,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, -/obj/machinery/firealarm{ - dir = 8; - pixel_x = 24 - }, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, @@ -21882,11 +21391,6 @@ /obj/item/clothing/suit/hooded/wintercoat, /turf/open/floor/plating, /area/maintenance/department/science/xenobiology) -"bID" = ( -/obj/structure/cable, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "bIE" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable/yellow{ @@ -22835,6 +22339,14 @@ /obj/machinery/portable_atmospherics/canister, /turf/open/floor/plating, /area/maintenance/starboard) +"bQZ" = ( +/obj/structure/closet/crate, +/obj/item/stack/license_plates/empty/fifty, +/obj/item/stack/license_plates/empty/fifty, +/obj/item/stack/license_plates/empty/fifty, +/obj/item/stack/license_plates/empty/fifty, +/turf/open/floor/plating, +/area/security/prison/upper) "bRc" = ( /obj/structure/cable/yellow{ icon_state = "1-4" @@ -22891,6 +22403,13 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"bRR" = ( +/obj/item/soap/nanotrasen, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison/upper) "bSc" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable/yellow{ @@ -23174,6 +22693,22 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, /area/maintenance/port) +"bTB" = ( +/obj/machinery/airalarm/directional/west, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "bTD" = ( /obj/machinery/vending/snack/random, /obj/machinery/newscaster{ @@ -24678,6 +24213,11 @@ }, /obj/structure/table, /obj/item/kitchen/rollingpin, +/obj/machinery/camera{ + c_tag = "Service Hallway"; + dir = 4; + name = "hallway camera" + }, /turf/open/floor/plasteel, /area/hallway/secondary/service) "bYp" = ( @@ -25140,14 +24680,14 @@ /turf/closed/wall, /area/maintenance/disposal/incinerator) "bZD" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Incinerator Access"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/yellow{ icon_state = "1-2" }, +/obj/machinery/door/airlock/atmos{ + name = "Turbine Access"; + req_access_txt = "32" + }, /turf/open/floor/plating, /area/maintenance/disposal/incinerator) "bZE" = ( @@ -25764,7 +25304,10 @@ icon_state = "1-4" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plating, /area/maintenance/disposal/incinerator) "caZ" = ( /obj/structure/cable/yellow{ @@ -25775,7 +25318,11 @@ /obj/structure/sign/warning/deathsposal{ pixel_y = 32 }, -/turf/open/floor/plasteel, +/obj/machinery/camera{ + c_tag = "Atmospherics - Incinerator"; + name = "atmospherics camera" + }, +/turf/open/floor/plating, /area/maintenance/disposal/incinerator) "cba" = ( /obj/machinery/power/smes{ @@ -25785,7 +25332,7 @@ /obj/structure/cable/yellow{ icon_state = "0-8" }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/maintenance/disposal/incinerator) "cbp" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -26380,7 +25927,7 @@ /obj/machinery/atmospherics/pipe/simple/dark/visible{ dir = 6 }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/maintenance/disposal/incinerator) "ccU" = ( /obj/structure/table/wood/poker, @@ -33641,6 +33188,10 @@ icon_state = "1-8" }, /obj/effect/landmark/start/medical_doctor, +/obj/machinery/camera{ + c_tag = "Patient Room"; + dir = 10 + }, /turf/open/floor/plasteel/white, /area/medical/patients_rooms/room_a) "cum" = ( @@ -33831,6 +33382,10 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/light_switch{ + pixel_x = -25; + pixel_y = 26 + }, /turf/open/floor/plasteel, /area/medical/paramedic) "cuy" = ( @@ -35831,7 +35386,7 @@ dir = 10 }, /obj/machinery/camera{ - c_tag = "Genetics Lab"; + c_tag = "Genetics Lab Hall"; dir = 6; network = list("ss13","medbay") }, @@ -41368,6 +40923,12 @@ name = "Station Intercom (General)"; pixel_x = -29 }, +/obj/item/cautery{ + pixel_y = 15 + }, +/obj/machinery/posialert{ + pixel_y = -32 + }, /turf/open/floor/plasteel/white/corner{ dir = 4 }, @@ -41764,6 +41325,12 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) +"cKy" = ( +/obj/machinery/flasher{ + id = "visitorflash" + }, +/turf/closed/wall, +/area/security/brig) "cKz" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -43033,6 +42600,11 @@ icon_state = "4-8" }, /obj/structure/chair/stool, +/obj/machinery/light/small, +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_y = -28 + }, /turf/open/floor/plating, /area/maintenance/solars/starboard/aft) "cNq" = ( @@ -44105,7 +43677,8 @@ idDoor = "xeno_airlock_exterior"; idSelf = "xeno_airlock_control"; name = "Access Button"; - pixel_x = -24 + pixel_x = -24; + req_access_txt = "47" }, /obj/structure/cable/yellow{ icon_state = "1-2" @@ -45097,6 +44670,37 @@ /obj/effect/landmark/start/scientist, /turf/open/floor/plasteel/white, /area/science/xenobiology) +"cUT" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"cUU" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/extinguisher_cabinet{ + pixel_y = -30 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "cUZ" = ( /obj/docking_port/stationary{ dir = 8; @@ -45145,9 +44749,6 @@ /turf/open/floor/plasteel/dark, /area/hallway/primary/central) "cVp" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, @@ -45241,12 +44842,8 @@ /turf/open/floor/carpet, /area/service/theater) "cWn" = ( -/obj/machinery/door/airlock/atmos/glass{ - name = "Atmospherics Monitoring"; - req_access_txt = "24" - }, -/obj/structure/cable/yellow{ - icon_state = "4-8" +/obj/structure/disposalpipe/segment{ + dir = 6 }, /turf/open/floor/plasteel, /area/engineering/atmos) @@ -45719,7 +45316,7 @@ /turf/open/floor/plating, /area/maintenance/starboard) "dbl" = ( -/obj/structure/easel, +/obj/structure/loot_pile/maint, /turf/open/floor/plating, /area/maintenance/starboard/aft) "dbo" = ( @@ -45796,6 +45393,18 @@ }, /turf/open/floor/circuit/telecomms, /area/science/xenobiology) +"dbx" = ( +/obj/structure/table, +/obj/item/paper_bin{ + pixel_x = -3; + pixel_y = 7 + }, +/obj/item/pen, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "dbG" = ( /obj/machinery/power/apc{ areastring = "/area/science/circuit"; @@ -45892,7 +45501,8 @@ idSelf = "xeno_airlock_control"; name = "Access Button"; pixel_x = 29; - pixel_y = -8 + pixel_y = -8; + req_access_txt = "47" }, /obj/machinery/firealarm{ pixel_y = 24 @@ -46067,7 +45677,8 @@ idSelf = "xeno_airlock_control"; name = "Access Console"; pixel_x = -25; - pixel_y = -25 + pixel_y = -25; + req_access_txt = "47" }, /obj/effect/turf_decal/tile/purple{ dir = 1 @@ -47046,10 +46657,10 @@ /turf/open/floor/plating, /area/maintenance/fore) "dht" = ( -/obj/item/cigbutt, /obj/structure/sign/poster/contraband/random{ pixel_x = -32 }, +/obj/structure/loot_pile/maint, /turf/open/floor/plating, /area/maintenance/starboard/fore) "dhu" = ( @@ -48013,30 +47624,16 @@ }, /area/maintenance/starboard/fore) "dpy" = ( -/obj/machinery/power/apc/highcap/five_k{ - areastring = "/area/security/prison"; - dir = 1; - name = "Prison Wing APC"; - pixel_x = 1; - pixel_y = 23 +/obj/structure/cable/yellow{ + icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ dir = 4 }, -/obj/structure/cable/yellow{ - icon_state = "0-2" - }, -/obj/structure/cable/yellow{ - icon_state = "0-8" - }, -/obj/structure/cable/yellow{ - icon_state = "0-4" - }, -/obj/machinery/camera{ - c_tag = "Prison Hallway Starboard"; - network = list("ss13","prison") - }, -/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/security/prison) "dpF" = ( @@ -48201,6 +47798,15 @@ /obj/structure/closet/emcloset, /turf/open/floor/plating, /area/maintenance/port/fore) +"dsC" = ( +/obj/effect/turf_decal/loading_area{ + dir = 8 + }, +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "dsL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, @@ -48221,24 +47827,11 @@ /turf/open/floor/plasteel/dark, /area/ai_monitored/aisat/exterior) "dtk" = ( -/obj/machinery/disposal/bin, -/obj/structure/disposalpipe/trunk{ - dir = 8 - }, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/machinery/button/door{ - id = "atmos"; - name = "Atmospherics Lockdown"; - pixel_x = 26; - pixel_y = -26; - req_access_txt = "24" - }, -/turf/open/floor/plasteel, +/obj/machinery/suit_storage_unit/atmos, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "dtl" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -48390,6 +47983,16 @@ }, /turf/open/floor/plasteel/freezer, /area/commons/fitness/recreation) +"dve" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "dvg" = ( /obj/structure/chair/office/light{ dir = 8 @@ -48490,6 +48093,29 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, /area/maintenance/port/aft) +"dwf" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + id = "PermaLockdown"; + name = "Lockdown Shutters" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/door/airlock/security/glass{ + id_tag = "permaouter"; + name = "Permabrig Transfer"; + req_access_txt = "2" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "dwi" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -48596,6 +48222,17 @@ icon_state = "platingdmg3" }, /area/maintenance/port/aft) +"dxy" = ( +/obj/machinery/button/flasher{ + id = "IsolationFlash"; + pixel_x = -23; + pixel_y = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison) "dxQ" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -49040,6 +48677,10 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/plating, /area/maintenance/starboard/fore) +"dCu" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/security/prison/upper) "dCx" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/yellow{ @@ -49179,13 +48820,10 @@ /turf/open/floor/plasteel/cafeteria, /area/service/kitchen) "dDj" = ( -/obj/structure/cable, -/obj/machinery/power/solar{ - id = "foreport"; - name = "Fore-Port Solar Array" - }, -/turf/open/floor/plasteel/airless/solarpanel, -/area/solars/port/fore) +/obj/structure/lattice, +/obj/item/shard, +/turf/open/space/basic, +/area/space/nearstation) "dDo" = ( /obj/effect/landmark/event_spawn, /turf/open/floor/plasteel/white, @@ -49728,12 +49366,8 @@ /area/maintenance/port) "dRb" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/door/airlock/atmos/glass{ - name = "Atmospherics Monitoring"; - req_access_txt = "24" +/obj/structure/cable/yellow{ + icon_state = "2-8" }, /turf/open/floor/plasteel, /area/engineering/atmos) @@ -49768,11 +49402,6 @@ }, /turf/open/floor/wood, /area/service/library) -"dSe" = ( -/obj/effect/landmark/xeno_spawn, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "dSm" = ( /obj/structure/table, /obj/machinery/microwave{ @@ -50107,6 +49736,15 @@ /obj/structure/table/wood, /turf/open/floor/carpet, /area/service/chapel/main) +"eaE" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "eaK" = ( /obj/structure/chair/office/dark, /turf/open/floor/wood, @@ -50182,6 +49820,10 @@ }, /turf/open/floor/wood, /area/commons/vacant_room/office) +"edY" = ( +/obj/structure/window, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "eeb" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -50351,6 +49993,13 @@ }, /turf/open/floor/plasteel/dark, /area/hallway/primary/port) +"eiU" = ( +/obj/structure/table, +/obj/item/pen, +/obj/item/instrument/harmonica, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison/upper) "ejd" = ( /obj/structure/bookcase{ name = "Holy Bookcase" @@ -50527,6 +50176,10 @@ }, /turf/open/floor/plasteel, /area/commons/fitness/recreation) +"emo" = ( +/obj/structure/chair/stool, +/turf/open/floor/plasteel, +/area/security/prison/upper) "emB" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -50603,13 +50256,6 @@ }, /turf/open/floor/plasteel/dark, /area/engineering/main) -"erz" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/engineering/atmos) "erD" = ( /obj/machinery/reagentgrinder, /obj/structure/table/glass, @@ -50774,6 +50420,22 @@ /obj/item/gps, /turf/open/floor/plating, /area/engineering/main) +"ewU" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/door/airlock/security/glass{ + id_tag = "permaouter"; + name = "Permabrig Transfer"; + req_access_txt = "2" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "ewZ" = ( /obj/machinery/conveyor/inverted{ dir = 6; @@ -50787,6 +50449,19 @@ }, /turf/closed/wall/r_wall, /area/engineering/atmos) +"exz" = ( +/obj/structure/weightmachine/weightlifter, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "exJ" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -50905,9 +50580,6 @@ /turf/open/floor/plasteel/dark, /area/engineering/storage/tech) "eAe" = ( -/obj/machinery/sleeper{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -50921,6 +50593,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/treatment_center) "eAy" = ( @@ -51143,8 +50816,28 @@ }, /turf/open/floor/plasteel/white, /area/science/circuit) +"eEy" = ( +/obj/machinery/shower{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison/upper) +"eFk" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "eFn" = ( -/obj/machinery/portable_atmospherics/canister/oxygen, /obj/machinery/atmospherics/miner/oxygen, /turf/open/floor/engine/o2, /area/engineering/atmos) @@ -51547,6 +51240,14 @@ /obj/machinery/vending/coffee, /turf/open/floor/wood, /area/service/library) +"eSb" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/security/prison) "eSp" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -52036,6 +51737,15 @@ /obj/machinery/holopad/secure, /turf/open/floor/plasteel/cafeteria, /area/command/heads_quarters/cmo) +"fdl" = ( +/obj/machinery/door/airlock{ + name = "Prison Showers" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "fdE" = ( /obj/structure/chair/wood/wings{ dir = 1 @@ -52174,6 +51884,13 @@ }, /turf/open/floor/plasteel/cult, /area/service/chapel/main) +"fhs" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/space/basic, +/area/solars/port/fore) "fht" = ( /obj/structure/table/reinforced, /obj/item/flashlight/lamp, @@ -52184,6 +51901,18 @@ /obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/closed/wall/r_wall, /area/engineering/atmos) +"fhK" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "fhO" = ( /obj/structure/closet/secure_closet/personal, /obj/item/clothing/under/misc/assistantformal, @@ -52323,6 +52052,7 @@ /obj/structure/extinguisher_cabinet{ pixel_y = -30 }, +/obj/structure/loot_pile/maint, /turf/open/floor/plating, /area/maintenance/port/aft) "fpg" = ( @@ -52330,7 +52060,9 @@ dir = 8 }, /obj/machinery/pipedispenser/disposal, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "fpr" = ( @@ -52477,6 +52209,19 @@ "fvo" = ( /turf/closed/wall, /area/service/chapel/main) +"fvV" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security/glass{ + name = "Prison Wing"; + req_access_txt = "1" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison) "fwb" = ( /obj/item/soap/nanotrasen, /obj/machinery/light/small{ @@ -52664,6 +52409,12 @@ }, /turf/open/floor/plasteel, /area/service/hydroponics) +"fCR" = ( +/obj/machinery/shower{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison/upper) "fCZ" = ( /obj/machinery/atmospherics/pipe/manifold/supply/visible{ dir = 1 @@ -52735,6 +52486,18 @@ }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) +"fEV" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison/upper) "fEX" = ( /turf/open/floor/wood, /area/service/library) @@ -52785,12 +52548,8 @@ /turf/open/floor/plasteel/white, /area/science/circuit) "fFR" = ( -/obj/structure/closet/crate, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/camera{ - c_tag = "Atmospherics - Entrance" - }, -/turf/open/floor/plasteel, +/turf/closed/wall, /area/engineering/atmos) "fFY" = ( /obj/structure/cable, @@ -52905,6 +52664,16 @@ }, /turf/open/floor/plasteel, /area/engineering/break_room) +"fKj" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison/upper) "fKu" = ( /obj/structure/chair/comfy/black{ dir = 8 @@ -52913,6 +52682,15 @@ dir = 4 }, /area/service/chapel/main) +"fKv" = ( +/obj/machinery/door/airlock{ + name = "Cleaning Closet" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/maintenance/prison) "fKG" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -53019,7 +52797,12 @@ /obj/structure/cable/yellow{ icon_state = "2-4" }, -/obj/machinery/light/small, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "fNh" = ( @@ -53027,6 +52810,9 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/camera{ + c_tag = "Atmospherics - Bow" + }, /turf/open/floor/plasteel, /area/engineering/atmos) "fNk" = ( @@ -53051,6 +52837,22 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/aisat/exterior) +"fOe" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"fOG" = ( +/obj/structure/grille/broken, +/turf/open/floor/plating/airless, +/area/space/nearstation) "fOS" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, @@ -53100,6 +52902,17 @@ /obj/effect/spawner/structure/window/plasma/reinforced, /turf/open/floor/plating, /area/engineering/main) +"fRj" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "permacells4"; + name = "Privacy Shutters" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/security/prison/cells) "fRo" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, @@ -53169,6 +52982,11 @@ }, /turf/open/floor/plasteel, /area/engineering/gravity_generator) +"fUI" = ( +/obj/structure/bed, +/obj/machinery/airalarm/directional/east, +/turf/open/floor/padded, +/area/security/prison) "fVa" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -53307,6 +53125,12 @@ }, /turf/open/floor/plasteel, /area/service/hydroponics) +"fYL" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/engineering/atmos) "fZR" = ( /obj/machinery/seed_extractor, /obj/effect/turf_decal/stripes/line{ @@ -53346,9 +53170,6 @@ /obj/machinery/firealarm{ pixel_y = 24 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, /obj/machinery/pipedispenser, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/camera{ @@ -53358,6 +53179,9 @@ /obj/machinery/atmospherics/pipe/simple/orange/hidden{ dir = 4 }, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "gbt" = ( @@ -53402,6 +53226,13 @@ }, /turf/open/floor/plasteel/white, /area/command/heads_quarters/rd) +"gcB" = ( +/obj/machinery/power/tracker, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating/airless, +/area/solars/port/fore) "gcE" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -53481,6 +53312,13 @@ }, /turf/open/floor/carpet, /area/command/corporate_showroom) +"gec" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "geK" = ( /obj/structure/cable/yellow{ icon_state = "2-4" @@ -53491,6 +53329,12 @@ }, /turf/open/floor/plasteel, /area/commons/locker) +"geU" = ( +/obj/structure/lattice, +/obj/structure/grille/broken, +/obj/item/stack/rods, +/turf/open/space/basic, +/area/space/nearstation) "geY" = ( /obj/machinery/vending/cigarette, /turf/open/floor/wood, @@ -53630,6 +53474,17 @@ }, /turf/open/floor/wood, /area/service/bar) +"gjm" = ( +/obj/structure/table, +/obj/item/toy/cards/deck, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "gjo" = ( /obj/machinery/door/airlock{ name = "Unisex Showers" @@ -53694,6 +53549,15 @@ }, /turf/open/floor/plasteel, /area/commons/fitness/recreation) +"gkG" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "glc" = ( /turf/closed/wall, /area/service/library) @@ -53722,6 +53586,14 @@ }, /turf/open/floor/plasteel, /area/cargo/miningoffice) +"glz" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison/upper) "glJ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/disposalpipe/segment{ @@ -53766,6 +53638,20 @@ /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/engineering/atmos) +"gmU" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "PermaLockdown"; + name = "Lockdown Shutters" + }, +/turf/open/floor/plating, +/area/security/prison) "gnZ" = ( /obj/item/radio/intercom{ pixel_y = -30 @@ -53844,25 +53730,27 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) -"grC" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/structure/lattice/catwalk, +"grh" = ( +/obj/structure/lattice, +/obj/item/stack/cable_coil/red, /turf/open/space, -/area/solars/port/fore) +/area/space/nearstation) +"grC" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "grX" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ dir = 6 }, /obj/structure/cable/yellow{ - icon_state = "1-2" + icon_state = "2-4" }, /turf/open/floor/plasteel, /area/engineering/atmos) @@ -54017,6 +53905,36 @@ /obj/effect/spawner/lootdrop/techstorage/engineering, /turf/open/floor/plasteel/dark, /area/engineering/storage/tech) +"gwC" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/security/prison/upper) +"gwI" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/door/airlock/grunge{ + name = "Permanent Cell 4"; + wiretypepath = /datum/wires/airlock/security + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "gwR" = ( /obj/machinery/camera{ c_tag = "Teleporter Room"; @@ -54097,6 +54015,15 @@ }, /turf/open/floor/plasteel, /area/cargo/office) +"gyf" = ( +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "gyh" = ( /turf/closed/wall, /area/cargo/warehouse) @@ -54155,6 +54082,10 @@ }, /turf/open/floor/plating, /area/service/chapel/main) +"gzW" = ( +/obj/structure/grille, +/turf/open/space/basic, +/area/space/nearstation) "gzX" = ( /obj/effect/spawner/structure/window, /obj/machinery/door/poddoor/preopen{ @@ -54382,14 +54313,20 @@ /turf/open/floor/plasteel, /area/commons/dorms) "gGc" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 8 }, -/obj/structure/cable/yellow{ - icon_state = "1-8" +/obj/effect/turf_decal/tile/yellow{ + dir = 4 }, -/obj/effect/landmark/event_spawn, -/turf/open/floor/plasteel, +/obj/machinery/button/door{ + id = "atmos"; + name = "Atmospherics Lockdown"; + pixel_x = 26; + req_access_txt = "24" + }, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "gGH" = ( /obj/structure/cable/yellow{ @@ -54441,6 +54378,11 @@ /obj/effect/landmark/xeno_spawn, /turf/open/floor/engine/air, /area/engineering/atmos) +"gIi" = ( +/obj/structure/lattice, +/obj/item/stack/rods, +/turf/open/space/basic, +/area/space/nearstation) "gJm" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/preopen{ @@ -54832,7 +54774,7 @@ "gXt" = ( /obj/machinery/cryopod, /obj/machinery/camera{ - c_tag = "Fitness Room - Fore" + c_tag = "Cryogenics" }, /turf/open/floor/plasteel/dark, /area/commons/cryopod) @@ -54922,6 +54864,16 @@ }, /turf/open/floor/plasteel/dark, /area/engineering/main) +"haD" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -24 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "hbh" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall/r_wall, @@ -54963,8 +54915,11 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, /obj/machinery/suit_storage_unit/atmos, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "hdR" = ( /obj/structure/chair/stool{ @@ -55197,6 +55152,11 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/construction/storage_wing) +"hlO" = ( +/obj/structure/table/reinforced, +/obj/structure/reagent_dispensers/servingdish, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "hlQ" = ( /obj/item/folder/white{ pixel_x = 4; @@ -55220,6 +55180,22 @@ }, /turf/open/floor/plasteel/dark, /area/command/bridge) +"hma" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "hmh" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/security{ @@ -55449,6 +55425,20 @@ }, /turf/open/floor/plasteel, /area/commons/locker) +"hsr" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "hsv" = ( /obj/machinery/light/small{ dir = 1 @@ -55572,6 +55562,16 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/commons/dorms) +"hwd" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "hwv" = ( /obj/machinery/requests_console{ department = "Engineering"; @@ -55648,13 +55648,12 @@ /turf/closed/wall, /area/commons/toilet/auxiliary) "hyP" = ( -/obj/machinery/door/airlock/external{ - name = "Escape Pod Two" +/obj/effect/turf_decal/delivery, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Lockdown Shutters" }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/turf/open/floor/plating, +/turf/open/floor/plasteel/dark, /area/security/prison) "hyV" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -55715,6 +55714,19 @@ }, /turf/open/floor/plasteel/grimy, /area/service/chapel/office) +"hzP" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison/upper) "hzS" = ( /obj/machinery/door/poddoor{ id = "Secure Storage"; @@ -55739,6 +55751,12 @@ /area/ai_monitored/aisat/exterior) "hAI" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "hAL" = ( @@ -55860,6 +55878,25 @@ }, /turf/open/floor/plasteel, /area/cargo/qm) +"hDB" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/button/door{ + id = "Prison Gate"; + name = "Prison Wing Lockdown"; + pixel_x = -24; + pixel_y = 24; + req_access_txt = "2" + }, +/turf/open/floor/plasteel, +/area/security/prison) "hEm" = ( /obj/item/taperecorder, /obj/item/cartridge/lawyer, @@ -55968,6 +56005,9 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/engineering/gravity_generator) +"hGz" = ( +/turf/open/floor/padded, +/area/security/prison) "hGX" = ( /turf/open/floor/engine/co2, /area/engineering/atmos) @@ -56054,6 +56094,13 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/aisat/exterior) +"hKk" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "hKm" = ( /obj/item/folder/white{ pixel_x = 4; @@ -56203,6 +56250,10 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/light_switch{ + pixel_x = 8; + pixel_y = 30 + }, /turf/open/floor/plasteel/dark, /area/command/teleporter) "hNB" = ( @@ -56352,6 +56403,16 @@ }, /turf/open/floor/engine/n2, /area/engineering/atmos) +"hRD" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/light_switch{ + pixel_x = -24 + }, +/turf/open/floor/plasteel, +/area/security/brig) "hSe" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 @@ -56495,6 +56556,12 @@ }, /turf/open/floor/plasteel/dark, /area/engineering/break_room) +"hXi" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "hXr" = ( /obj/structure/extinguisher_cabinet{ pixel_x = 27 @@ -56552,6 +56619,19 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/commons/fitness/recreation) +"hXW" = ( +/obj/structure/chair/stool, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/turf/open/floor/plasteel, +/area/security/brig) "hYa" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -56608,6 +56688,15 @@ }, /turf/open/floor/plasteel/dark, /area/command/bridge) +"hZd" = ( +/obj/machinery/vr_sleeper{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "hZe" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/yellow{ @@ -56689,6 +56778,13 @@ }, /turf/open/floor/plasteel, /area/service/hydroponics) +"iaH" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/starboard) "ibn" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -56759,6 +56855,12 @@ /obj/structure/lattice, /turf/open/space/basic, /area/space/nearstation) +"iei" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "ieA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 @@ -56793,6 +56895,13 @@ }, /turf/open/floor/plasteel, /area/commons/fitness/recreation) +"ify" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/meter, +/turf/closed/wall/r_wall, +/area/engineering/atmos) "ifM" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 @@ -56834,6 +56943,13 @@ }, /turf/open/floor/plating/airless, /area/solars/starboard/aft) +"ihO" = ( +/obj/machinery/portable_atmospherics/canister/air, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plating, +/area/maintenance/prison) "iiu" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -56845,6 +56961,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/machinery/light/small, /turf/open/floor/plasteel, /area/engineering/atmos) "iiE" = ( @@ -56887,6 +57004,13 @@ dir = 5 }, /area/service/kitchen) +"ijq" = ( +/obj/machinery/cryopod{ + dir = 8 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "ijr" = ( /turf/closed/wall, /area/ai_monitored/command/storage/eva) @@ -56917,6 +57041,14 @@ }, /turf/open/floor/plasteel, /area/command/heads_quarters/ce) +"ikj" = ( +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/obj/structure/lattice, +/turf/open/space/basic, +/area/security/execution/education) "ikm" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -57106,7 +57238,7 @@ "iqV" = ( /obj/structure/table/wood/poker, /obj/effect/spawner/lootdrop{ - loot = list(/obj/item/gun/ballistic/revolver/russian = 5, /obj/item/storage/box/syndie_kit/throwing_weapons, /obj/item/toy/cards/deck/syndicate = 2); + loot = list(/obj/item/gun/ballistic/revolver/russian=5,/obj/item/storage/box/syndie_kit/throwing_weapons,/obj/item/toy/cards/deck/syndicate=2); name = "gambling valuables spawner" }, /turf/open/floor/wood, @@ -57160,6 +57292,21 @@ }, /turf/open/floor/carpet, /area/command/heads_quarters/hop) +"itk" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "itH" = ( /obj/machinery/portable_atmospherics/pump, /obj/effect/turf_decal/tile/blue{ @@ -57343,7 +57490,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) "ixH" = ( @@ -57355,11 +57502,11 @@ /turf/open/floor/plating, /area/service/chapel/main) "ixJ" = ( -/obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/yellow/visible, /obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 }, +/obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/engineering/atmos) "ixL" = ( @@ -57405,6 +57552,17 @@ /obj/machinery/space_heater, /turf/open/floor/plasteel/dark, /area/engineering/atmos) +"iyp" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison) "iyy" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -57458,6 +57616,9 @@ }, /turf/open/floor/wood, /area/command/heads_quarters/captain/private) +"izT" = ( +/turf/closed/wall/r_wall, +/area/security/prison/upper) "izZ" = ( /turf/open/floor/engine/n2o, /area/engineering/atmos) @@ -57511,10 +57672,31 @@ }, /turf/open/floor/engine, /area/engineering/main) +"iBL" = ( +/obj/machinery/washing_machine, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "iCn" = ( -/obj/machinery/vr_sleeper, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/structure/rack, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/machinery/power/apc{ + areastring = "/area/maintenance/prison"; + dir = 4; + name = "Prison Central Maintenance APC"; + pixel_x = 24 + }, +/obj/effect/spawner/lootdrop/prison_contraband, +/turf/open/floor/plating, +/area/maintenance/prison) "iDz" = ( /obj/structure/window/reinforced{ dir = 1; @@ -57576,9 +57758,6 @@ /turf/closed/wall/r_wall, /area/engineering/main) "iFl" = ( -/obj/machinery/portable_atmospherics/canister/nitrous_oxide{ - valve_open = 1 - }, /obj/machinery/atmospherics/miner/n2o, /turf/open/floor/engine/n2o, /area/engineering/atmos) @@ -57986,6 +58165,18 @@ /obj/effect/landmark/start/cargo_technician, /turf/open/floor/plasteel, /area/cargo/warehouse) +"iRC" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Prison Forestry" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "iSt" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -58099,6 +58290,13 @@ /obj/structure/barricade/wooden, /turf/open/floor/plating, /area/commons/fitness/pool) +"iUN" = ( +/obj/machinery/shower{ + dir = 8; + pixel_y = -4 + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison/upper) "iUY" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /obj/effect/turf_decal/tile/bar, @@ -58277,6 +58475,18 @@ }, /turf/open/floor/wood, /area/service/theater) +"jbJ" = ( +/obj/structure/table/reinforced, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "jbZ" = ( /obj/machinery/light_switch{ pixel_x = 27 @@ -58320,6 +58530,19 @@ }, /turf/open/floor/plasteel, /area/cargo/storage) +"jde" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/space, +/area/solars/port/fore) "jdJ" = ( /obj/machinery/atmospherics/components/trinary/filter/atmos/n2o{ dir = 1 @@ -58441,15 +58664,12 @@ /turf/closed/wall/r_wall, /area/command/teleporter) "jhu" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/machinery/door/airlock/public/glass{ - id_tag = "permahydro"; - name = "Recreation Module" - }, -/turf/open/floor/plasteel, -/area/security/prison) +/obj/structure/closet/crate/trashcart, +/obj/effect/spawner/lootdrop/prison_contraband, +/obj/item/trash/chips, +/obj/item/trash/candy, +/turf/open/floor/plating, +/area/maintenance/prison) "jhw" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 @@ -58720,6 +58940,17 @@ }, /turf/open/floor/plasteel/dark, /area/commons/fitness/recreation) +"jpk" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/security/prison/upper) "jpq" = ( /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 10 @@ -58802,6 +59033,25 @@ /obj/item/clothing/mask/cigarette/cigar, /turf/open/floor/wood, /area/service/bar) +"jsO" = ( +/obj/structure/closet/crate, +/obj/item/reagent_containers/glass/bowl, +/obj/effect/spawner/lootdrop/prison_contraband, +/obj/item/reagent_containers/glass/bowl, +/obj/item/reagent_containers/glass/bowl, +/obj/item/reagent_containers/glass/bowl, +/obj/item/reagent_containers/glass/bowl, +/obj/item/reagent_containers/glass/bowl, +/obj/item/reagent_containers/glass/bowl, +/obj/item/reagent_containers/glass/bowl, +/obj/item/storage/box/drinkingglasses, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/bag/tray/cafeteria, +/obj/item/storage/box/drinkingglasses, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "jtn" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/poddoor/preopen{ @@ -58848,6 +59098,19 @@ }, /turf/open/floor/plasteel, /area/cargo/miningoffice) +"jtG" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "jtI" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -58963,6 +59226,11 @@ }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) +"jxe" = ( +/obj/structure/table, +/obj/machinery/microwave, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "jxm" = ( /obj/structure/sign/warning/securearea, /turf/closed/wall/r_wall, @@ -59329,6 +59597,11 @@ }, /turf/closed/wall, /area/commons/storage/art) +"jIF" = ( +/obj/machinery/plate_press, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/security/prison/upper) "jIS" = ( /obj/machinery/vending/autodrobe, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -59336,6 +59609,16 @@ }, /turf/open/floor/wood, /area/service/theater) +"jIU" = ( +/obj/structure/sink/kitchen{ + pixel_y = 28 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#cee5d2" + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "jJw" = ( /obj/structure/sign/map/left{ desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; @@ -59607,6 +59890,16 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/cargo/storage) +"jPq" = ( +/obj/structure/urinal{ + pixel_y = 29 + }, +/obj/machinery/camera{ + c_tag = "Auxiliary Restrooms"; + dir = 5 + }, +/turf/open/floor/plating, +/area/commons/toilet/auxiliary) "jPu" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -59865,6 +60158,39 @@ /obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel, /area/engineering/main) +"jVo" = ( +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/obj/machinery/power/apc{ + areastring = "/area/security/prison/cells"; + damage_deflection = 21; + desc = "A control terminal for the area's electrical systems. It's secured with a durable antitampering plasteel cage."; + dir = 8; + name = "Armored Upper Prison APC"; + pixel_x = -25 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"jVK" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "jVR" = ( /obj/structure/cable{ icon_state = "4-8" @@ -59950,6 +60276,13 @@ }, /turf/open/floor/plasteel/dark, /area/command/bridge) +"kaM" = ( +/obj/structure/table, +/obj/item/storage/fancy/egg_box, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/rice, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "kbg" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -60044,6 +60377,18 @@ "ker" = ( /turf/closed/wall, /area/service/chapel/office) +"keE" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "keY" = ( /obj/structure/table, /obj/item/folder/red, @@ -60104,11 +60449,6 @@ /obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel, /area/cargo/storage) -"kfT" = ( -/obj/item/stack/cable_coil, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "kgv" = ( /obj/machinery/door/poddoor/shutters/preopen{ id = "kitchen"; @@ -60273,6 +60613,19 @@ /obj/effect/spawner/structure/window/reinforced/tinted, /turf/open/floor/plating, /area/service/hydroponics/garden) +"kkC" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/space, +/area/solars/port/fore) "kkR" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock{ @@ -60321,6 +60674,21 @@ }, /turf/open/floor/plasteel, /area/service/bar) +"kmQ" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/obj/machinery/camera{ + c_tag = "Prison Forestry"; + dir = 8; + network = list("ss13","prison") + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "kmT" = ( /obj/structure/table/reinforced, /obj/machinery/computer/security/telescreen/rd, @@ -60464,7 +60832,12 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 }, -/turf/closed/wall, +/obj/machinery/door/airlock/atmos/glass{ + name = "Atmospherics Monitoring"; + req_access_txt = "24" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, /area/engineering/atmos) "kuk" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -60550,6 +60923,16 @@ }, /turf/open/floor/carpet, /area/command/heads_quarters/hop) +"kwe" = ( +/obj/effect/spawner/structure/window/reinforced/tinted, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/prison) "kwq" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 @@ -60655,6 +61038,19 @@ }, /turf/open/floor/plasteel, /area/commons/locker) +"kyV" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/plating, +/area/security/prison) +"kze" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "kzn" = ( /obj/machinery/door/airlock/external{ name = "Departure Lounge Airlock" @@ -60831,6 +61227,16 @@ }, /turf/open/floor/wood, /area/service/theater) +"kCX" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/space, +/area/solars/port/fore) "kDc" = ( /obj/machinery/reagentgrinder, /obj/structure/table/wood, @@ -60987,6 +61393,11 @@ }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) +"kGI" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/drinks/drinkingglass, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "kGY" = ( /obj/structure/extinguisher_cabinet{ pixel_x = 27 @@ -61127,6 +61538,11 @@ }, /turf/open/floor/carpet, /area/service/theater) +"kKH" = ( +/turf/open/floor/plating/airless{ + icon_state = "panelscorched" + }, +/area/space/nearstation) "kKR" = ( /obj/structure/window/reinforced, /obj/effect/turf_decal/tile/blue{ @@ -61304,6 +61720,30 @@ /obj/structure/window/reinforced, /turf/open/floor/plasteel/dark, /area/ai_monitored/aisat/exterior) +"kQr" = ( +/obj/machinery/camera{ + c_tag = "Prison Cell Block 2"; + dir = 4; + network = list("ss13","prison") + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "kQJ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 @@ -61333,10 +61773,6 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/port) -"kQW" = ( -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "kRE" = ( /obj/machinery/power/apc{ areastring = "/area/ai_monitored/turret_protected/ai"; @@ -61506,6 +61942,30 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel/dark, /area/command/bridge) +"kUL" = ( +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) +"kUN" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison) "kUS" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 @@ -61530,6 +61990,16 @@ }, /turf/open/floor/carpet, /area/service/chapel/main) +"kVM" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security/glass{ + name = "Prison Wing"; + req_access_txt = "1" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison) "kVZ" = ( /obj/item/paper_bin{ pixel_x = -2; @@ -61550,21 +62020,15 @@ /obj/machinery/vending/snack/random, /turf/open/floor/plasteel/dark, /area/command/bridge) -"kWh" = ( -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "kWW" = ( /obj/structure/cable/yellow{ - icon_state = "1-2" + icon_state = "1-4" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/obj/machinery/light/small{ + dir = 8 }, -/turf/closed/wall, +/obj/structure/closet/crate, +/turf/open/floor/plasteel, /area/engineering/atmos) "kXd" = ( /obj/machinery/power/terminal, @@ -61934,6 +62398,14 @@ }, /turf/open/floor/plasteel, /area/commons/locker) +"lha" = ( +/obj/machinery/hydroponics/soil, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/grass, +/area/security/prison/upper) "lhH" = ( /obj/structure/table, /obj/item/storage/toolbox/mechanical{ @@ -62095,6 +62567,28 @@ }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) +"llF" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/white/line{ + dir = 6 + }, +/obj/machinery/airalarm/directional/north, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"llY" = ( +/obj/machinery/suit_storage_unit/security, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "lmb" = ( /obj/machinery/power/port_gen/pacman, /obj/structure/cable/yellow, @@ -62409,6 +62903,47 @@ }, /turf/open/floor/plasteel, /area/cargo/sorting) +"lxV" = ( +/obj/structure/table, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_x = -6; + pixel_y = 10 + }, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_x = -6; + pixel_y = -2 + }, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_x = -6; + pixel_y = 4 + }, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_x = -6; + pixel_y = -8 + }, +/obj/item/clothing/under/rank/prisoner{ + pixel_x = 8; + pixel_y = 5 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel/dark, +/area/security/prison) "lyF" = ( /obj/structure/table, /obj/machinery/cell_charger, @@ -62505,6 +63040,11 @@ }, /turf/open/floor/plasteel, /area/security/checkpoint/supply) +"lAA" = ( +/obj/structure/closet/crate, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "lAF" = ( /obj/structure/table/wood, /obj/item/paper_bin{ @@ -62638,14 +63178,13 @@ /turf/open/floor/plasteel, /area/commons/locker) "lFH" = ( -/obj/machinery/light/small{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/suit_storage_unit/atmos, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "lFQ" = ( /obj/structure/chair/office/dark{ @@ -62666,6 +63205,23 @@ /obj/machinery/vending/clothing, /turf/open/floor/plasteel/white/corner, /area/hallway/secondary/entry) +"lFW" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "lFY" = ( /obj/machinery/door/airlock/highsecurity{ name = "Gravity Generator Room"; @@ -62716,7 +63272,6 @@ /turf/open/floor/plasteel, /area/engineering/atmos) "lIs" = ( -/obj/machinery/portable_atmospherics/canister/carbon_dioxide, /obj/machinery/atmospherics/miner/carbon_dioxide, /turf/open/floor/engine/co2, /area/engineering/atmos) @@ -62943,13 +63498,6 @@ }, /turf/open/floor/plating, /area/command/gateway) -"lPr" = ( -/obj/structure/cable{ - icon_state = "0-2" - }, -/obj/machinery/power/tracker, -/turf/open/floor/plating/airless, -/area/solars/port/fore) "lPE" = ( /obj/structure/chair/stool{ pixel_y = 8 @@ -62993,6 +63541,15 @@ }, /turf/open/floor/plasteel, /area/cargo/miningoffice) +"lQK" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/computer/libraryconsole/bookmanagement, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "lQV" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -63058,6 +63615,13 @@ /obj/item/toy/poolnoodle/blue, /turf/open/floor/plating, /area/commons/fitness/pool) +"lSH" = ( +/obj/docking_port/stationary/random{ + id = "pod_2_lavaland"; + name = "lavaland" + }, +/turf/open/space, +/area/space) "lTr" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 @@ -63090,6 +63654,11 @@ }, /turf/open/floor/plasteel/freezer, /area/commons/toilet/restrooms) +"lUk" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow, +/turf/open/floor/plating, +/area/security/prison/cells) "lUn" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -63115,10 +63684,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 4 - }, -/turf/closed/wall, +/obj/machinery/pipedispenser/disposal/transit_tube, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, /area/engineering/atmos) "lUv" = ( /obj/structure/noticeboard{ @@ -63256,10 +63824,7 @@ /area/commons/fitness/recreation) "lXt" = ( /obj/structure/cable/yellow{ - icon_state = "2-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 + icon_state = "1-8" }, /turf/open/floor/plasteel, /area/engineering/atmos) @@ -63341,6 +63906,10 @@ /obj/structure/table/wood, /turf/open/floor/wood, /area/service/lawoffice) +"mak" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison/upper) "maE" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 @@ -63642,6 +64211,26 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/engineering/gravity_generator) +"mgT" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison) +"mhG" = ( +/obj/structure/sink{ + pixel_y = 29 + }, +/turf/open/floor/plating, +/area/maintenance/prison) +"mhW" = ( +/obj/item/stack/rods, +/turf/open/space/basic, +/area/space/nearstation) "mhX" = ( /obj/structure/table, /obj/item/weldingtool, @@ -63677,6 +64266,15 @@ icon_state = "wood-broken3" }, /area/command/corporate_showroom) +"mjl" = ( +/obj/machinery/vending/cola/red, +/obj/machinery/camera{ + c_tag = "Prison Cafeteria"; + dir = 8; + network = list("ss13","prison") + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "mjp" = ( /obj/machinery/light, /obj/machinery/camera{ @@ -63775,6 +64373,15 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/commons/fitness/recreation) +"mlV" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "mmy" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -63831,6 +64438,10 @@ "moT" = ( /obj/structure/table, /obj/item/camera, +/obj/machinery/camera{ + c_tag = "Art Storage"; + dir = 1 + }, /turf/open/floor/plasteel, /area/commons/storage/art) "moW" = ( @@ -63848,6 +64459,20 @@ }, /turf/open/floor/plasteel/dark, /area/command/bridge) +"mpv" = ( +/obj/machinery/computer/security/telescreen/interrogation{ + name = "isolation room monitor"; + network = list("isolation"); + pixel_y = 31 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/prison) "mpx" = ( /obj/machinery/light{ dir = 4 @@ -64045,6 +64670,10 @@ }, /turf/open/floor/plasteel, /area/engineering/atmos) +"mud" = ( +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/solars/port/fore) "muJ" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -64064,9 +64693,22 @@ }, /turf/closed/wall, /area/hallway/secondary/service) +"mvI" = ( +/obj/machinery/computer/arcade/battle{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "mvN" = ( /turf/closed/wall, /area/construction/storage_wing) +"mvS" = ( +/obj/structure/chair, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "mvY" = ( /obj/structure/window/reinforced{ dir = 4 @@ -64176,6 +64818,15 @@ }, /turf/open/floor/plasteel, /area/security/office) +"mxT" = ( +/obj/effect/spawner/lootdrop/prison_contraband, +/obj/structure/closet/crate, +/obj/item/stack/license_plates/empty/fifty, +/obj/item/stack/license_plates/empty/fifty, +/obj/item/stack/license_plates/empty/fifty, +/obj/item/stack/license_plates/empty/fifty, +/turf/open/floor/plating, +/area/security/prison/upper) "myk" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable/yellow{ @@ -64307,6 +64958,19 @@ "mBW" = ( /turf/open/floor/plasteel, /area/commons/locker) +"mBZ" = ( +/obj/machinery/vr_sleeper{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#cee5d2" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "mCa" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/blue, @@ -64427,6 +65091,11 @@ }, /turf/open/floor/plasteel, /area/commons/locker) +"mFa" = ( +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, +/area/security/prison) "mFr" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel, @@ -64537,6 +65206,25 @@ }, /turf/open/space, /area/space/nearstation) +"mIR" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "executionfireblast" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) "mIW" = ( /obj/machinery/computer/arcade, /obj/machinery/airalarm{ @@ -64620,6 +65308,10 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/cargo/storage) +"mKY" = ( +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/port) "mLh" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -64629,13 +65321,12 @@ "mLk" = ( /turf/closed/wall, /area/command/heads_quarters/captain/private) -"mLH" = ( -/obj/structure/cable{ - icon_state = "0-2" +"mMf" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) +/turf/open/floor/plating, +/area/maintenance/port/fore) "mMn" = ( /turf/open/floor/plasteel, /area/engineering/atmos) @@ -64702,6 +65393,16 @@ }, /turf/open/floor/carpet, /area/service/chapel/main) +"mOH" = ( +/obj/structure/table, +/obj/item/storage/dice, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/item/instrument/piano_synth, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison/upper) "mPm" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -64737,6 +65438,13 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plasteel, /area/cargo/storage) +"mQt" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison) "mQW" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -64769,13 +65477,13 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/computer/bounty, /obj/effect/turf_decal/tile/brown{ dir = 1 }, /obj/effect/turf_decal/tile/brown{ dir = 4 }, +/obj/machinery/computer/bounty, /turf/open/floor/plasteel, /area/cargo/qm) "mSd" = ( @@ -64800,6 +65508,10 @@ /obj/structure/cable/yellow{ icon_state = "1-8" }, +/obj/effect/landmark/event_spawn, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "mSL" = ( @@ -64850,6 +65562,12 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/carpet, /area/service/library) +"mUE" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "mUZ" = ( /obj/structure/table/reinforced, /obj/item/clipboard, @@ -64914,6 +65632,14 @@ }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) +"mWS" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/jukebox, +/turf/open/floor/plasteel, +/area/service/bar) "mXi" = ( /turf/open/floor/wood, /area/command/heads_quarters/captain/private) @@ -65125,6 +65851,10 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/ai_monitored/command/storage/eva) +"ngt" = ( +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/space/nearstation) "ngZ" = ( /obj/item/radio/intercom{ name = "Station Intercom (General)"; @@ -65153,6 +65883,14 @@ /obj/machinery/door/firedoor, /turf/open/floor/plasteel, /area/hallway/primary/port) +"nhI" = ( +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/obj/structure/lattice, +/turf/open/space/basic, +/area/security/execution/education) "nhL" = ( /obj/machinery/airalarm{ pixel_y = 28 @@ -65290,6 +66028,22 @@ }, /turf/open/space, /area/solars/starboard/aft) +"nlq" = ( +/obj/structure/closet/secure_closet/brig, +/obj/machinery/airalarm/directional/east, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/security/prison) "nlr" = ( /obj/structure/chair/office/dark{ dir = 4 @@ -65339,15 +66093,11 @@ /turf/open/floor/plasteel/dark, /area/ai_monitored/aisat/exterior) "nmO" = ( -/obj/structure/cable{ - icon_state = "0-2" - }, -/obj/machinery/power/solar{ - id = "foreport"; - name = "Fore-Port Solar Array" - }, -/turf/open/floor/plasteel/airless/solarpanel, -/area/solars/port/fore) +/obj/machinery/hydroponics/soil, +/obj/item/cultivator, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/grass, +/area/security/prison/upper) "nnB" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -65374,6 +66124,19 @@ }, /turf/open/floor/plasteel/white, /area/science/circuit) +"nnO" = ( +/obj/structure/bed, +/obj/item/clothing/suit/straight_jacket, +/obj/item/clothing/mask/muzzle, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/security/prison) "noG" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -65412,6 +66175,12 @@ /obj/machinery/atmospherics/components/unary/thermomachine/freezer, /turf/open/floor/plasteel, /area/engineering/atmos) +"npY" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison/upper) "nqx" = ( /obj/machinery/suit_storage_unit/standard_unit, /obj/machinery/light_switch{ @@ -65464,6 +66233,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/structure/bedsheetbin/color, /turf/open/floor/plasteel/cafeteria, /area/commons/dorms) "nry" = ( @@ -65473,6 +66243,16 @@ }, /turf/open/floor/plasteel, /area/commons/toilet/auxiliary) +"nsg" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/power/solar{ + id = "aftstarboard"; + name = "Aft-Starboard Solar Array" + }, +/turf/open/floor/plasteel/airless/solarpanel, +/area/solars/port/fore) "nsA" = ( /mob/living/simple_animal/cow{ name = "Betsy"; @@ -65626,6 +66406,13 @@ }, /turf/open/floor/plating, /area/cargo/sorting) +"nAj" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison) "nAl" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/lattice/catwalk, @@ -65697,6 +66484,22 @@ "nDn" = ( /turf/closed/wall/r_wall, /area/command/corporate_showroom) +"nEa" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison/upper) "nEw" = ( /obj/machinery/power/terminal{ dir = 1 @@ -65719,6 +66522,10 @@ /obj/machinery/bookbinder, /turf/open/floor/wood, /area/service/library) +"nEC" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/plating, +/area/security/prison/upper) "nFz" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/closed/wall/r_wall, @@ -65732,6 +66539,10 @@ }, /turf/open/floor/plasteel, /area/service/bar) +"nFN" = ( +/obj/machinery/light, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "nFS" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/stripes/line{ @@ -65833,6 +66644,17 @@ }, /turf/open/floor/plasteel, /area/service/hydroponics/garden) +"nJo" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison) "nJr" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel, @@ -65921,6 +66743,16 @@ }, /turf/open/floor/plasteel/dark, /area/engineering/storage/tech) +"nLC" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "nLQ" = ( /obj/structure/cable{ icon_state = "1-8" @@ -65953,6 +66785,21 @@ /obj/effect/landmark/blobstart, /turf/open/floor/plating, /area/engineering/main) +"nNO" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "nOm" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -66013,6 +66860,14 @@ dir = 5 }, /area/service/kitchen) +"nPH" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow, +/turf/open/floor/plating, +/area/security/prison/upper) "nPJ" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -66262,6 +67117,12 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/secondary/entry) +"nWG" = ( +/obj/machinery/hydroponics/soil, +/obj/item/shovel/spade, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/grass, +/area/security/prison/upper) "nWX" = ( /obj/machinery/shower{ dir = 8 @@ -66470,6 +67331,9 @@ /obj/effect/turf_decal/bot{ dir = 1 }, +/obj/machinery/light_switch{ + pixel_x = -23 + }, /turf/open/floor/plasteel{ dir = 1 }, @@ -66487,10 +67351,6 @@ /obj/machinery/light_switch{ pixel_x = -26 }, -/obj/machinery/pipedispenser/disposal/transit_tube, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, /obj/machinery/atmospherics/pipe/simple/orange/hidden{ dir = 4 }, @@ -66503,6 +67363,13 @@ }, /turf/open/floor/plating, /area/construction/storage_wing) +"oaH" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "oaZ" = ( /obj/effect/turf_decal/tile/green{ dir = 1 @@ -66775,12 +67642,35 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/plasteel, /area/cargo/storage) +"ofK" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison/cells) "ogf" = ( /obj/structure/table/wood, /obj/item/stamp/captain, /obj/machinery/computer/security/wooden_tv, /turf/open/floor/wood, /area/command/heads_quarters/captain/private) +"ohf" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "ohj" = ( /obj/item/integrated_electronics/analyzer, /obj/item/integrated_electronics/debugger, @@ -66820,6 +67710,17 @@ }, /turf/open/floor/plasteel/dark, /area/command/bridge) +"ojh" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison) "ojs" = ( /obj/structure/table/wood, /obj/machinery/newscaster/security_unit{ @@ -66908,6 +67809,13 @@ name = "Atmospherics Monitoring"; req_access_txt = "24" }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/door/firedoor, /turf/open/floor/plasteel, /area/engineering/atmos) "olW" = ( @@ -67077,6 +67985,20 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel/white, /area/command/heads_quarters/rd) +"oqC" = ( +/obj/effect/spawner/structure/window, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/security/prison/upper) +"oqD" = ( +/obj/machinery/cryopod{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "oqK" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -67125,6 +68047,10 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall, /area/security/brig) +"osn" = ( +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) "osB" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/external{ @@ -67224,10 +68150,29 @@ }, /turf/open/floor/plasteel/dark, /area/engineering/storage/tech) +"ovd" = ( +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/turf/open/floor/padded, +/area/security/prison) "ovB" = ( /obj/effect/landmark/event_spawn, /turf/open/floor/plasteel, /area/commons/storage/primary) +"ovU" = ( +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/machinery/power/apc{ + areastring = "/area/maintenance/prison/starboard"; + dir = 4; + name = "Prison Wing APC"; + pixel_x = 24 + }, +/turf/open/floor/plasteel, +/area/security/prison) "owz" = ( /obj/structure/chair{ dir = 1 @@ -67382,9 +68327,6 @@ /turf/open/floor/plasteel, /area/service/bar) "oBF" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/engineering/atmos) @@ -67492,6 +68434,14 @@ }, /turf/open/floor/plating, /area/maintenance/starboard) +"oEN" = ( +/obj/machinery/camera{ + c_tag = "Prison Isolation Cell"; + dir = 8; + network = list("ss13","prison","isolation") + }, +/turf/open/floor/padded, +/area/security/prison) "oFv" = ( /obj/machinery/atmospherics/components/binary/pump/on{ name = "Gas to Cold Loop" @@ -67527,6 +68477,15 @@ }, /turf/open/floor/plasteel, /area/security/office) +"oGG" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "permacells1"; + name = "Privacy Shutters" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, +/area/security/prison/cells) "oHW" = ( /obj/machinery/portable_atmospherics/canister/air, /obj/effect/turf_decal/bot, @@ -67580,6 +68539,22 @@ }, /turf/open/floor/plasteel, /area/commons/locker) +"oKe" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "oKf" = ( /obj/item/wrench, /obj/item/clothing/suit/apron, @@ -67596,6 +68571,25 @@ /obj/machinery/holopad/secure, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat/foyer) +"oKu" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"oKD" = ( +/obj/structure/lattice, +/obj/structure/sign/warning/electricshock{ + pixel_y = -32 + }, +/turf/open/space/basic, +/area/space/nearstation) "oKY" = ( /obj/machinery/light/small{ dir = 4 @@ -67979,6 +68973,25 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/cargo/storage) +"oUR" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/chair/stool, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"oVt" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison) "oVF" = ( /obj/structure/window/reinforced{ dir = 1 @@ -68016,10 +69029,16 @@ /turf/open/floor/plasteel, /area/commons/dorms) "oWF" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/airlock/atmos/glass{ + name = "Atmospherics Monitoring"; + req_access_txt = "24" }, -/turf/closed/wall, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, /area/engineering/atmos) "oWR" = ( /obj/effect/spawner/lootdrop/maintenance, @@ -68308,6 +69327,11 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/freezer, /area/commons/toilet/restrooms) +"pdH" = ( +/obj/machinery/hydroponics/soil, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/grass, +/area/security/prison/upper) "pdZ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -68427,7 +69451,6 @@ }, /area/command/heads_quarters/rd) "pgT" = ( -/obj/machinery/portable_atmospherics/canister/toxins, /obj/machinery/atmospherics/miner/toxins, /turf/open/floor/engine/plasma, /area/engineering/atmos) @@ -68687,6 +69710,16 @@ /obj/machinery/light/small, /turf/open/floor/plasteel, /area/commons/fitness/recreation) +"png" = ( +/obj/machinery/door/airlock/external{ + name = "Security External Airlock"; + req_access_txt = "1" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/turf/open/floor/plating, +/area/security/prison) "pnA" = ( /obj/machinery/light_switch{ pixel_x = 28 @@ -68725,6 +69758,16 @@ /obj/machinery/vending/cigarette, /turf/open/floor/carpet, /area/service/bar) +"poR" = ( +/obj/machinery/computer/cryopod{ + pixel_y = 26 + }, +/obj/effect/turf_decal/loading_area{ + dir = 4; + pixel_x = -3 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "poT" = ( /obj/structure/cable/yellow{ icon_state = "0-2" @@ -68778,6 +69821,33 @@ }, /turf/open/floor/plasteel, /area/commons/storage/primary) +"pqv" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/closet/crate/trashcart/laundry, +/obj/item/clothing/under/rank/prisoner, +/obj/item/clothing/under/rank/prisoner, +/obj/item/clothing/under/rank/prisoner/skirt, +/obj/item/clothing/under/rank/prisoner/skirt, +/obj/effect/decal/cleanable/dirt, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_y = 8 + }, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_y = 8 + }, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_y = 8 + }, +/obj/item/clothing/shoes/sneakers/orange{ + pixel_y = 8 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "pqG" = ( /obj/structure/chair{ dir = 4 @@ -68929,6 +69999,14 @@ }, /turf/open/floor/wood, /area/command/heads_quarters/hop) +"pvy" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Lockdown Shutters" + }, +/turf/open/floor/plating, +/area/security/brig) "pvA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -69030,6 +70108,16 @@ dir = 1 }, /area/engineering/atmos) +"pxQ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "pxS" = ( /obj/machinery/light/small, /obj/machinery/libraryscanner, @@ -69103,6 +70191,13 @@ }, /turf/open/floor/plasteel, /area/command/gateway) +"pzy" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "pzF" = ( /obj/structure/disposalpipe/trunk{ dir = 1 @@ -69144,6 +70239,19 @@ }, /turf/open/floor/engine/vacuum, /area/engineering/atmos) +"pAw" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "pAA" = ( /obj/item/flashlight/lamp, /obj/machinery/newscaster{ @@ -69210,6 +70318,19 @@ dir = 1 }, /area/command/gateway) +"pCQ" = ( +/obj/machinery/computer/arcade/battle{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"pCS" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel, +/area/security/prison/upper) "pCV" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -69450,6 +70571,37 @@ }, /turf/open/floor/plasteel/dark, /area/command/bridge) +"pJv" = ( +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/security/prison/cells) +"pJX" = ( +/obj/structure/table, +/obj/item/storage/box/hug{ + pixel_x = 4; + pixel_y = 3 + }, +/obj/item/razor{ + pixel_x = -8; + pixel_y = 3 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison) +"pKa" = ( +/obj/structure/lattice, +/obj/item/stack/rods{ + amount = 25 + }, +/turf/open/space/basic, +/area/space/nearstation) "pKe" = ( /obj/structure/cable{ icon_state = "0-2" @@ -69624,6 +70776,10 @@ pixel_x = -28 }, /obj/machinery/light/small, +/obj/machinery/light_switch{ + pixel_x = -10; + pixel_y = -26 + }, /turf/open/floor/plasteel/freezer, /area/commons/fitness/recreation) "pRd" = ( @@ -69788,6 +70944,16 @@ }, /turf/open/floor/wood, /area/service/bar) +"pUL" = ( +/obj/structure/rack, +/obj/item/restraints/handcuffs, +/obj/item/assembly/flash/handheld, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "pUZ" = ( /obj/structure/window/reinforced, /obj/machinery/computer/atmos_control/tank/oxygen_tank{ @@ -70186,6 +71352,25 @@ }, /turf/open/floor/plasteel/dark, /area/commons/fitness/recreation) +"qhO" = ( +/obj/structure/closet/crate/hydroponics, +/obj/item/paper/guides/jobs/hydroponics, +/obj/item/seeds/onion, +/obj/item/seeds/garlic, +/obj/item/seeds/potato, +/obj/item/seeds/tomato, +/obj/item/seeds/carrot, +/obj/item/seeds/grass, +/obj/item/seeds/ambrosia, +/obj/item/seeds/wheat, +/obj/item/seeds/pumpkin, +/obj/effect/spawner/lootdrop/prison_contraband, +/obj/effect/turf_decal/bot, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "qin" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable/yellow{ @@ -70200,6 +71385,22 @@ }, /turf/open/floor/plating, /area/command/heads_quarters/hos) +"qiz" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Prison Laundry"; + dir = 8; + network = list("ss13","prison") + }, +/obj/structure/table, +/obj/structure/bedsheetbin, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "qiA" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -70306,6 +71507,12 @@ }, /turf/open/floor/plasteel, /area/construction/storage_wing) +"qle" = ( +/obj/structure/sign/warning/electricshock{ + pixel_x = 32 + }, +/turf/open/space/basic, +/area/space) "qlI" = ( /obj/structure/table/glass, /obj/item/lightreplacer{ @@ -70403,6 +71610,13 @@ }, /turf/open/floor/plasteel, /area/cargo/storage) +"qmP" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/space/basic, +/area/solars/port/fore) "qnv" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable/yellow{ @@ -70554,6 +71768,19 @@ }, /turf/open/floor/plasteel, /area/science/mixing) +"qqj" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "qqK" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -70582,6 +71809,21 @@ "qrc" = ( /turf/open/floor/plasteel/chapel, /area/service/chapel/main) +"qrs" = ( +/obj/item/reagent_containers/glass/bucket, +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green, +/turf/open/floor/plasteel, +/area/security/prison/upper) "qrH" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 @@ -70863,7 +72105,6 @@ departmentType = 2; pixel_y = 30 }, -/obj/machinery/computer/bounty, /obj/effect/turf_decal/tile/brown{ dir = 1 }, @@ -70873,6 +72114,7 @@ /obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/machinery/computer/bounty, /turf/open/floor/plasteel, /area/cargo/office) "qBq" = ( @@ -70994,6 +72236,32 @@ }, /turf/open/floor/plasteel/white, /area/command/heads_quarters/rd) +"qEk" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/machinery/disposal/deliveryChute{ + dir = 4; + name = "Prisoner Chute" + }, +/obj/structure/plasticflaps/opaque{ + name = "Prisoner Transfer" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"qES" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/public/glass{ + name = "Visitation" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "qFr" = ( /obj/structure/toilet/secret/low_loot{ pixel_y = 13 @@ -71008,6 +72276,9 @@ }, /turf/open/floor/plasteel/white, /area/command/heads_quarters/captain/private) +"qFN" = ( +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "qGg" = ( /obj/structure/sink{ dir = 8; @@ -71116,6 +72387,11 @@ }, /turf/open/floor/plasteel, /area/engineering/gravity_generator) +"qIB" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/chair/stool, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "qID" = ( /obj/structure/sign/warning/securearea, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -71191,6 +72467,21 @@ /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/cargo/storage) +"qKq" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison) "qKC" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/white, @@ -71247,6 +72538,7 @@ /obj/item/stack/cable_coil/random, /obj/item/stack/cable_coil/random, /obj/item/stack/cable_coil/random, +/obj/item/chisel, /turf/open/floor/plasteel, /area/commons/storage/art) "qNe" = ( @@ -71336,6 +72628,23 @@ }, /turf/open/space, /area/space/nearstation) +"qRZ" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Prison Sanitarium"; + req_access_txt = "2" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "qSc" = ( /obj/machinery/vr_sleeper, /obj/effect/turf_decal/tile/neutral{ @@ -71398,6 +72707,27 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/command/teleporter) +"qTc" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/firealarm{ + pixel_y = 24 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"qTq" = ( +/obj/structure/chair{ + dir = 4 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "qTB" = ( /obj/item/paper_bin{ pixel_x = -2; @@ -71442,6 +72772,14 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/aisat/exterior) +"qTV" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/security/prison/cells) "qTW" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, @@ -71456,6 +72794,20 @@ dir = 1 }, /area/engineering/atmos) +"qUm" = ( +/obj/structure/bed/roller, +/obj/structure/bed/roller, +/obj/machinery/iv_drip, +/obj/machinery/iv_drip, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/security/prison) "qUy" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -71467,6 +72819,15 @@ /obj/structure/sign/warning/nosmoking, /turf/closed/wall/r_wall, /area/engineering/main) +"qUX" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "qUY" = ( /obj/structure/table/wood, /obj/item/book/manual/wiki/security_space_law{ @@ -71543,6 +72904,13 @@ dir = 1 }, /area/command/gateway) +"qWm" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel/freezer, +/area/security/prison/upper) "qWu" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -71559,6 +72927,12 @@ /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "qXd" = ( @@ -71573,6 +72947,28 @@ }, /turf/open/floor/plasteel, /area/commons/dorms) +"qXt" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) +"qXS" = ( +/obj/effect/landmark/carpspawn, +/turf/open/space/basic, +/area/space/station_ruins) "qXX" = ( /obj/effect/landmark/start/lawyer, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -71685,12 +73081,6 @@ }, /turf/open/floor/plasteel/dark, /area/command/teleporter) -"ram" = ( -/obj/machinery/computer/arcade{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/prison) "rbc" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/atmos/oxygen_input{ dir = 1 @@ -71819,12 +73209,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ dir = 4 }, -/obj/machinery/door/airlock/atmos/glass{ - name = "Distribution Loop"; - req_access_txt = "24" - }, /obj/machinery/atmospherics/pipe/simple/orange/hidden, -/turf/open/floor/plasteel, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, /area/engineering/atmos) "rdv" = ( /obj/effect/turf_decal/stripes/line, @@ -72010,6 +73397,13 @@ /obj/machinery/atmospherics/pipe/layer_manifold, /turf/open/floor/plating, /area/engineering/atmos) +"rif" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "rii" = ( /obj/machinery/vending/tool, /obj/effect/turf_decal/tile/brown{ @@ -72162,13 +73556,6 @@ }, /turf/open/floor/plasteel, /area/security/office) -"roa" = ( -/obj/structure/chair/stool, -/obj/machinery/light/small{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/prison) "rom" = ( /obj/structure/bed/roller, /obj/machinery/vending/wallmed{ @@ -72214,6 +73601,20 @@ "roz" = ( /turf/open/floor/plasteel/dark, /area/engineering/main) +"rpQ" = ( +/obj/structure/lattice, +/obj/structure/grille, +/turf/open/space/basic, +/area/space/nearstation) +"rqn" = ( +/obj/machinery/vr_sleeper{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "rqx" = ( /obj/machinery/airalarm{ dir = 8; @@ -72267,7 +73668,6 @@ /area/commons/fitness/recreation) "rta" = ( /obj/machinery/door/airlock/external{ - dir = 2; name = "Public Mining Dock" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -72296,6 +73696,13 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/carpet, /area/command/heads_quarters/hos) +"rub" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison) "ruc" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -72342,6 +73749,28 @@ }, /turf/open/floor/plasteel, /area/command/gateway) +"rvO" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/toilet{ + dir = 4 + }, +/obj/structure/window/reinforced/tinted{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "rvU" = ( /obj/machinery/power/apc/highcap/ten_k{ areastring = "/area/engineering/main"; @@ -72548,6 +73977,22 @@ }, /turf/open/floor/plasteel, /area/cargo/miningoffice) +"rCq" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#cee5d2" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "rCx" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/yellow{ @@ -72556,6 +74001,16 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/wood, /area/service/lawoffice) +"rCF" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Prison Common Room" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "rCH" = ( /obj/machinery/door/airlock{ name = "Kitchen Cold Room"; @@ -72724,6 +74179,26 @@ }, /turf/open/floor/plasteel, /area/commons/locker) +"rIe" = ( +/obj/structure/table, +/obj/structure/window, +/obj/item/reagent_containers/food/condiment/saltshaker{ + layer = 3.1; + pixel_x = -2; + pixel_y = 2 + }, +/obj/item/reagent_containers/food/condiment/peppermill{ + desc = "Often used to flavor food or make people sneeze. Fashionably moved to the left side of the table."; + pixel_x = -8; + pixel_y = 2 + }, +/obj/item/reagent_containers/food/condiment/enzyme{ + pixel_x = 9; + pixel_y = 3 + }, +/obj/item/book/manual/chef_recipes, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "rIw" = ( /obj/machinery/hydroponics/constructable, /obj/machinery/firealarm{ @@ -72809,6 +74284,18 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) +"rLx" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/security/prison) "rLB" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -72858,16 +74345,10 @@ /turf/open/floor/plasteel, /area/commons/locker) "rLV" = ( -/obj/structure/table, -/obj/item/folder, -/obj/item/paper/guides/jobs/hydroponics, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, -/obj/item/pen, -/obj/item/storage/crayons, +/obj/effect/turf_decal/stripes/line, +/obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, -/area/security/prison) +/area/security/prison/upper) "rMx" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, /obj/effect/turf_decal/tile/neutral{ @@ -72966,6 +74447,10 @@ }, /turf/open/floor/plasteel/dark, /area/command/bridge) +"rPp" = ( +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/port/fore) "rPB" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -73041,6 +74526,16 @@ }, /turf/open/floor/plasteel/white, /area/medical/virology) +"rRB" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/security/prison/cells) "rRZ" = ( /obj/item/folder, /obj/item/folder, @@ -73052,6 +74547,17 @@ /obj/item/tape, /turf/open/floor/wood, /area/service/library) +"rSi" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "rSx" = ( /obj/structure/cable{ icon_state = "1-2" @@ -73260,6 +74766,12 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall, /area/command/bridge) +"rYP" = ( +/obj/machinery/door/window/southleft{ + name = "Permabrig Kitchen" + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "rZb" = ( /obj/structure/reagent_dispensers/watertank, /obj/effect/turf_decal/tile/brown, @@ -73328,6 +74840,22 @@ }, /turf/open/floor/plasteel, /area/engineering/main) +"sbg" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "sbs" = ( /obj/structure/closet/secure_closet/personal/cabinet, /obj/machinery/airalarm{ @@ -73413,6 +74941,21 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/security/office) +"sck" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"scs" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/security/execution/education) "scx" = ( /obj/structure/plasticflaps, /obj/machinery/conveyor{ @@ -73656,6 +75199,13 @@ /obj/item/clothing/under/suit/burgundy, /turf/open/floor/carpet, /area/commons/dorms) +"sja" = ( +/obj/item/toy/plush/beeplushie{ + desc = "Maybe hugging this will make you feel better about yourself."; + name = "Therabee" + }, +/turf/open/floor/padded, +/area/security/prison) "sjK" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -73891,13 +75441,6 @@ }, /turf/open/floor/plasteel, /area/cargo/miningoffice) -"spA" = ( -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "spG" = ( /obj/structure/closet/crate/rcd{ pixel_y = 4 @@ -73967,6 +75510,16 @@ luminosity = 2 }, /area/ai_monitored/command/nuke_storage) +"ssE" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/space, +/area/solars/port/fore) "stk" = ( /obj/machinery/camera{ c_tag = "Captain's Office"; @@ -74012,6 +75565,39 @@ }, /turf/open/floor/plasteel, /area/construction/storage_wing) +"suZ" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security{ + aiControlDisabled = 1; + id_tag = "prisonereducation"; + name = "Prisoner Education Chamber"; + req_access_txt = "3" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) +"svu" = ( +/obj/structure/table, +/obj/item/folder, +/obj/item/pen, +/obj/effect/decal/cleanable/dirt, +/obj/item/camera, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "swu" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -74044,6 +75630,28 @@ }, /turf/open/floor/plasteel, /area/command/heads_quarters/hop) +"swH" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/landmark/start/prisoner, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/button/door{ + id = "permacells4"; + name = "Privacy Shutters"; + pixel_y = 25 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "swK" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/blue{ @@ -74091,6 +75699,48 @@ }, /turf/open/floor/wood, /area/service/bar) +"syL" = ( +/obj/machinery/door/window/brigdoor{ + name = "Justice Chamber"; + req_access_txt = "3" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/machinery/door/window/brigdoor{ + dir = 1; + name = "Justice Chamber"; + req_access_txt = "3" + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/preopen{ + id = "executionfireblast" + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) +"szt" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "szz" = ( /obj/structure/sign/warning/securearea, /turf/closed/wall/r_wall, @@ -74268,15 +75918,14 @@ /turf/open/floor/plating, /area/maintenance/starboard/aft) "sFR" = ( -/obj/structure/cable{ - icon_state = "2-8" +/obj/machinery/hydroponics/soil, +/obj/effect/decal/cleanable/dirt, +/obj/item/plant_analyzer, +/obj/structure/cable/yellow{ + icon_state = "4-8" }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) +/turf/open/floor/grass, +/area/security/prison/upper) "sGh" = ( /obj/structure/cable{ icon_state = "1-2" @@ -74382,6 +76031,10 @@ "sIL" = ( /turf/open/floor/plasteel/dark, /area/command/bridge) +"sIN" = ( +/obj/structure/bookcase/random, +/turf/open/floor/plasteel, +/area/security/prison/upper) "sIP" = ( /obj/structure/chair/stool{ pixel_y = 8 @@ -74481,6 +76134,9 @@ }, /turf/open/floor/plasteel, /area/engineering/main) +"sMe" = ( +/turf/closed/wall, +/area/security/prison/upper) "sMk" = ( /obj/machinery/power/apc{ areastring = "/area/service/janitor"; @@ -74500,6 +76156,16 @@ "sMN" = ( /turf/closed/wall/r_wall, /area/commons/storage/primary) +"sMT" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "sNj" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -74685,7 +76351,6 @@ /turf/closed/wall, /area/service/bar) "sTB" = ( -/obj/machinery/portable_atmospherics/canister/nitrogen, /obj/machinery/atmospherics/miner/nitrogen, /turf/open/floor/engine/n2, /area/engineering/atmos) @@ -74706,6 +76371,12 @@ }, /turf/open/floor/plasteel, /area/commons/dorms) +"sUd" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "sUI" = ( /obj/structure/table, /obj/machinery/chem_dispenser/drinks/beer, @@ -74864,13 +76535,6 @@ /obj/structure/closet/firecloset, /turf/open/floor/plating, /area/maintenance/port) -"sZQ" = ( -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "sZV" = ( /obj/effect/turf_decal/stripes/line, /turf/open/floor/engine, @@ -74919,16 +76583,6 @@ /obj/structure/table/wood, /turf/open/floor/wood, /area/commons/vacant_room/office) -"tbc" = ( -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "tbN" = ( /obj/machinery/status_display/ai{ pixel_y = 32 @@ -74976,9 +76630,6 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/computer/bounty{ - dir = 4 - }, /turf/open/floor/wood, /area/command/heads_quarters/hop) "tdQ" = ( @@ -75703,6 +77354,13 @@ /obj/structure/lattice/catwalk, /turf/open/space, /area/solars/starboard/fore) +"tzt" = ( +/obj/machinery/power/floodlight, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/engineering/atmos) "tAp" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 @@ -75764,6 +77422,19 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/aisat/exterior) +"tDM" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison) "tDZ" = ( /obj/machinery/computer/cryopod{ dir = 4; @@ -75812,6 +77483,9 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, /turf/open/floor/plasteel, /area/engineering/atmos) "tFJ" = ( @@ -75838,6 +77512,16 @@ }, /turf/open/floor/plasteel/dark, /area/security/office) +"tGd" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/dark/visible, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) "tGD" = ( /obj/structure/closet/crate, /obj/structure/extinguisher_cabinet{ @@ -75969,6 +77653,22 @@ }, /turf/open/floor/plating, /area/maintenance/department/science/xenobiology) +"tJI" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Lockdown Shutters" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = -24 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "tJQ" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 @@ -76295,6 +77995,13 @@ }, /turf/open/floor/plasteel, /area/engineering/atmos) +"tSe" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/space/basic, +/area/solars/port/fore) "tTX" = ( /obj/structure/cable/yellow{ icon_state = "1-4" @@ -76540,6 +78247,15 @@ }, /turf/open/floor/plasteel, /area/commons/fitness/recreation) +"uam" = ( +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "uar" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 @@ -76564,6 +78280,24 @@ }, /turf/open/floor/plating, /area/maintenance/port) +"ubD" = ( +/obj/structure/bed/roller, +/obj/machinery/camera{ + c_tag = "Prison Hallway Fore"; + network = list("ss13","prison") + }, +/turf/open/floor/plasteel, +/area/security/prison) +"ubH" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "ubJ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/yellow{ @@ -76838,6 +78572,14 @@ }, /turf/open/floor/plasteel/dark, /area/commons/dorms) +"uiA" = ( +/obj/machinery/door/airlock/security{ + id_tag = "IsolationCell"; + name = "Isolation Cell"; + req_access_txt = "2" + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "uiF" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -76894,12 +78636,29 @@ }, /turf/open/floor/plasteel, /area/commons/dorms) +"ulp" = ( +/obj/machinery/vending/sustenance, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "ulG" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/table, /obj/item/flashlight, /turf/open/floor/plasteel, /area/hallway/secondary/entry) +"ulI" = ( +/obj/machinery/biogenerator, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) +"ulQ" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "umv" = ( /obj/effect/turf_decal/tile/neutral, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -77008,6 +78767,15 @@ }, /turf/open/floor/plasteel/airless/solarpanel, /area/solars/starboard/fore) +"upD" = ( +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "upN" = ( /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -77028,6 +78796,32 @@ }, /turf/open/floor/plasteel, /area/service/bar) +"upX" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + id = "PermaLockdown"; + name = "Lockdown Shutters" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/door/airlock/security/glass{ + id_tag = "permaouter"; + name = "Permabrig Transfer"; + req_access_txt = "2" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "uqh" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -77130,8 +78924,11 @@ /turf/open/floor/plasteel/dark, /area/cargo/office) "usM" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 + dir = 4 }, /turf/open/floor/plasteel, /area/engineering/atmos) @@ -77208,6 +79005,23 @@ }, /turf/open/floor/wood, /area/service/library) +"uvn" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Prison Cafeteria" + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) +"uvz" = ( +/obj/item/clothing/suit/straight_jacket, +/obj/item/electropack, +/obj/structure/table, +/turf/open/floor/plasteel, +/area/security/prison) "uvH" = ( /obj/structure/window/reinforced, /turf/open/floor/plasteel/dark, @@ -77251,6 +79065,12 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/construction/storage_wing) +"uxR" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/wall, +/area/security/prison/upper) "uxT" = ( /obj/machinery/door/window/eastright{ base_state = "left"; @@ -77325,6 +79145,15 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/wood, /area/service/bar) +"uBA" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/security/prison) "uBW" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable/yellow{ @@ -77408,11 +79237,14 @@ /turf/open/floor/wood, /area/commons/vacant_room/office) "uED" = ( -/obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/manifold/cyan/visible{ dir = 1 }, -/turf/open/floor/plating, +/obj/machinery/door/airlock/atmos/glass{ + name = "Atmospherics Monitoring"; + req_access_txt = "24" + }, +/turf/open/floor/plasteel, /area/engineering/atmos) "uFM" = ( /obj/machinery/power/emitter, @@ -77628,6 +79460,13 @@ }, /turf/open/floor/plasteel, /area/service/bar) +"uNg" = ( +/obj/machinery/atmospherics/pipe/simple/general/hidden, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) "uOc" = ( /obj/effect/landmark/start/captain, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -77646,6 +79485,13 @@ }, /turf/open/floor/plasteel, /area/commons/fitness/recreation) +"uOr" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/white/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "uOv" = ( /obj/structure/sign/directions/evac, /obj/structure/sign/directions/medical{ @@ -77656,6 +79502,10 @@ }, /turf/closed/wall, /area/service/library) +"uOH" = ( +/obj/structure/lattice, +/turf/open/space/basic, +/area/security/execution/education) "uPN" = ( /obj/machinery/light{ dir = 8 @@ -77741,6 +79591,14 @@ }, /turf/open/floor/plating, /area/engineering/gravity_generator) +"uTQ" = ( +/obj/structure/table/reinforced, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = -24 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "uTS" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -77767,6 +79625,26 @@ }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) +"uUK" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#cee5d2" + }, +/turf/open/floor/plasteel, +/area/security/prison) +"uUN" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "uVj" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/navbeacon{ @@ -77987,6 +79865,18 @@ }, /turf/open/floor/plasteel, /area/command/gateway) +"vbH" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "vbR" = ( /obj/structure/cable{ icon_state = "4-8" @@ -78093,6 +79983,16 @@ /obj/machinery/suit_storage_unit/hos, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) +"ven" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison/cells) "veq" = ( /obj/structure/window/reinforced{ dir = 4 @@ -78304,6 +80204,12 @@ }, /turf/open/floor/plasteel, /area/cargo/miningoffice) +"viX" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "vjq" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -78314,13 +80220,6 @@ /obj/effect/landmark/xmastree, /turf/open/floor/carpet, /area/service/chapel/main) -"vjC" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "vjL" = ( /obj/item/paper_bin{ pixel_y = 7 @@ -78342,6 +80241,16 @@ dir = 5 }, /area/command/heads_quarters/rd) +"vjV" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/security/prison/upper) "vkg" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 @@ -78360,6 +80269,19 @@ }, /turf/open/floor/plasteel/grimy, /area/service/chapel/office) +"vkq" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison/upper) "vkY" = ( /obj/machinery/requests_console{ announcementConsole = 1; @@ -78382,30 +80304,9 @@ /turf/open/floor/plasteel/dark, /area/command/bridge) "vla" = ( -/obj/machinery/power/apc{ - areastring = "/area/security/execution/education"; - dir = 1; - name = "Prisoner Education Chamber APC"; - pixel_y = 23 - }, -/obj/structure/cable/yellow{ - icon_state = "0-2" - }, -/obj/structure/closet/secure_closet/injection{ - name = "educational injections"; - pixel_x = 2 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/education) +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison/cells) "vls" = ( /obj/machinery/door/airlock{ id_tag = "AuxToilet3"; @@ -78634,6 +80535,15 @@ }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) +"vtn" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "vtZ" = ( /obj/structure/cable/yellow{ icon_state = "2-4" @@ -78777,6 +80687,12 @@ dir = 4 }, /obj/effect/landmark/start/atmospheric_technician, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "vzs" = ( @@ -78867,6 +80783,11 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/carpet, /area/command/heads_quarters/captain/private) +"vCh" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable, +/turf/open/space/basic, +/area/solars/port/fore) "vCi" = ( /obj/effect/landmark/start/botanist, /obj/effect/turf_decal/tile/green, @@ -79117,9 +81038,6 @@ /turf/open/space/basic, /area/space) "vLV" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/effect/turf_decal/tile/blue{ dir = 1 }, @@ -79130,6 +81048,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/sleeper{ + dir = 4 + }, /turf/open/floor/plasteel/white, /area/medical/treatment_center) "vMm" = ( @@ -79273,6 +81194,25 @@ }, /turf/open/floor/plasteel, /area/engineering/atmos) +"vRz" = ( +/obj/machinery/button/flasher{ + id = "visitorflash"; + pixel_x = -6; + pixel_y = 24 + }, +/obj/machinery/button/door{ + id = "visitation"; + name = "Visitation Shutters"; + pixel_x = -6; + pixel_y = 36; + req_access_txt = "2" + }, +/obj/machinery/camera{ + c_tag = "Prison Visitation"; + network = list("ss13","prison") + }, +/turf/open/floor/plasteel, +/area/security/brig) "vSm" = ( /obj/machinery/power/emitter, /turf/open/floor/plating, @@ -79309,6 +81249,24 @@ dir = 5 }, /area/service/kitchen) +"vSH" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison) +"vSL" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "Prison Gate"; + name = "Lockdown Shutters" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison) "vTo" = ( /obj/structure/cable/yellow{ icon_state = "1-8" @@ -79442,6 +81400,17 @@ }, /turf/open/floor/plating, /area/command/heads_quarters/rd) +"vXi" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/white/line{ + dir = 1 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#cee5d2" + }, +/turf/open/floor/plasteel, +/area/security/prison/cells) "vXk" = ( /obj/structure/chair{ dir = 4 @@ -79654,6 +81623,24 @@ }, /turf/open/floor/plasteel, /area/service/bar) +"wcj" = ( +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/structure/disposaloutlet{ + dir = 8; + name = "Prisoner Outlet" + }, +/obj/structure/window/reinforced{ + dir = 1; + pixel_y = 1 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "wcl" = ( /obj/structure/chair{ dir = 1 @@ -79806,6 +81793,15 @@ }, /turf/open/floor/plasteel, /area/commons/toilet/auxiliary) +"wgf" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "wgw" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall/r_wall, @@ -80070,6 +82066,13 @@ }, /turf/open/floor/plasteel, /area/command/teleporter) +"wol" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/space/basic, +/area/solars/port/fore) "wox" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -80292,6 +82295,12 @@ }, /turf/open/floor/plating, /area/engineering/main) +"wtO" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/security/prison) "wtU" = ( /obj/structure/chair/wood/wings{ dir = 8 @@ -80413,13 +82422,15 @@ }, /turf/open/floor/plasteel, /area/commons/dorms) -"wwD" = ( -/obj/structure/cable{ - icon_state = "0-8" +"wwa" = ( +/obj/machinery/door/airlock/grunge{ + name = "Prison Workshop" }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "wxd" = ( /obj/machinery/suit_storage_unit/standard_unit, /obj/structure/extinguisher_cabinet{ @@ -80469,6 +82480,13 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/service/chapel/main) +"wyf" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison/upper) "wyt" = ( /obj/machinery/washing_machine, /obj/effect/turf_decal/tile/blue{ @@ -80489,6 +82507,18 @@ /obj/machinery/atmospherics/components/trinary/filter/flipped/critical, /turf/open/floor/engine, /area/engineering/main) +"wzi" = ( +/obj/machinery/camera{ + c_tag = "Prison Common Room"; + dir = 1; + network = list("ss13","prison") + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/security/prison/upper) "wzm" = ( /obj/machinery/holopad, /turf/open/floor/plasteel, @@ -80549,6 +82579,10 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/plasteel, /area/engineering/main) +"wBB" = ( +/obj/structure/chair/stool, +/turf/open/floor/plasteel/dark, +/area/security/prison/cells) "wBE" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /obj/machinery/camera{ @@ -80660,6 +82694,32 @@ }, /turf/open/floor/plasteel/chapel, /area/service/chapel/main) +"wDM" = ( +/obj/structure/closet/crate/bin, +/obj/effect/spawner/lootdrop/prison_contraband, +/obj/item/trash/sosjerky, +/obj/item/trash/boritos, +/obj/item/trash/can, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/radio/intercom{ + desc = "Talk through this. It looks like it has been modified to not broadcast."; + name = "Prison Intercom (General)"; + pixel_x = -27; + pixel_y = -27; + prison_radio = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "wDZ" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, /obj/machinery/button/door{ @@ -80752,8 +82812,11 @@ /turf/open/floor/plating, /area/maintenance/starboard/aft) "wFX" = ( -/obj/machinery/portable_atmospherics/canister/air, -/turf/open/floor/engine/air, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/meter, +/turf/closed/wall/r_wall, /area/engineering/atmos) "wGp" = ( /obj/structure/cable/white{ @@ -80821,6 +82884,16 @@ /obj/structure/sign/warning/securearea, /turf/closed/wall/r_wall, /area/ai_monitored/command/nuke_storage) +"wHw" = ( +/obj/machinery/door/poddoor/shutters{ + id = "visitation"; + name = "Visitation Shutters" + }, +/obj/machinery/door/window/southleft{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/brig) "wIf" = ( /obj/effect/landmark/blobstart, /obj/machinery/power/apc{ @@ -80832,6 +82905,9 @@ /obj/structure/cable/yellow, /turf/open/floor/plating, /area/maintenance/central) +"wIu" = ( +/turf/open/floor/plasteel, +/area/security/prison/cells) "wIw" = ( /turf/open/floor/carpet, /area/command/heads_quarters/captain/private) @@ -80882,7 +82958,8 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, -/turf/closed/wall, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, /area/engineering/atmos) "wKo" = ( /obj/effect/turf_decal/stripes/line, @@ -80894,6 +82971,20 @@ }, /turf/open/floor/plasteel/grimy, /area/security/office) +"wKG" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/space/basic, +/area/solars/port/fore) +"wKX" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/security/brig) "wKY" = ( /obj/machinery/light_switch{ pixel_y = 28 @@ -80960,6 +83051,19 @@ }, /turf/open/floor/plasteel, /area/cargo/storage) +"wNK" = ( +/obj/machinery/vr_sleeper{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#cee5d2" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "wNL" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/disposalpipe/segment, @@ -81274,6 +83378,12 @@ /obj/effect/landmark/xeno_spawn, /turf/open/floor/carpet, /area/commons/dorms) +"wWN" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "wWO" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -81454,11 +83564,11 @@ /turf/open/floor/plasteel, /area/cargo/storage) "wZC" = ( +/obj/structure/lattice/catwalk, /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/lattice/catwalk, -/turf/open/space, +/turf/open/space/basic, /area/solars/port/fore) "wZK" = ( /obj/structure/table, @@ -81482,6 +83592,13 @@ }, /turf/open/floor/plasteel, /area/commons/locker) +"wZR" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/space/basic, +/area/solars/port/fore) "wZX" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -81724,6 +83841,15 @@ }, /turf/open/floor/wood, /area/commons/dorms) +"xhP" = ( +/obj/structure/sign/warning/vacuum/external{ + pixel_y = 32 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating, +/area/security/prison) "xiO" = ( /obj/structure/cable{ icon_state = "4-8" @@ -81882,6 +84008,9 @@ /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/machinery/light_switch{ + pixel_x = -24 + }, /turf/open/floor/plasteel, /area/security/office) "xnt" = ( @@ -81957,6 +84086,21 @@ }, /turf/open/floor/plasteel, /area/engineering/break_room) +"xpx" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "xpy" = ( /obj/effect/landmark/xeno_spawn, /obj/machinery/atmospherics/components/unary/vent_pump/on{ @@ -82129,6 +84273,15 @@ /obj/effect/landmark/carpspawn, /turf/open/space, /area/space/station_ruins) +"xuu" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison/upper) "xuF" = ( /obj/structure/chair/comfy/black, /obj/effect/landmark/start/assistant, @@ -82156,6 +84309,25 @@ }, /turf/open/floor/plating, /area/engineering/gravity_generator) +"xvj" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) +"xvm" = ( +/obj/structure/grille/broken, +/turf/open/floor/plating/airless{ + icon_state = "panelscorched" + }, +/area/space/nearstation) "xwg" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/engineering{ @@ -82178,6 +84350,11 @@ }, /turf/open/floor/plasteel/dark, /area/engineering/storage/tech) +"xwj" = ( +/obj/structure/lattice, +/obj/structure/grille/broken, +/turf/open/space/basic, +/area/space/nearstation) "xww" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -82300,6 +84477,23 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, /area/service/library) +"xAw" = ( +/obj/machinery/seed_extractor, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) +"xAI" = ( +/obj/machinery/hydroponics/soil, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/grass, +/area/security/prison/upper) +"xAO" = ( +/turf/open/floor/plasteel, +/area/security/prison/upper) "xAR" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel/white, @@ -82377,6 +84571,15 @@ }, /turf/open/floor/plating, /area/maintenance/port) +"xDA" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "xDD" = ( /obj/machinery/door/airlock{ id_tag = "AuxShower"; @@ -82458,6 +84661,9 @@ /turf/open/floor/wood, /area/service/lawoffice) "xEM" = ( +/obj/machinery/light_switch{ + pixel_x = -20 + }, /turf/open/floor/plating, /area/commons/toilet/auxiliary) "xFb" = ( @@ -82505,6 +84711,11 @@ /obj/structure/table/wood, /turf/open/floor/carpet, /area/command/corporate_showroom) +"xGl" = ( +/turf/open/floor/plating/airless{ + icon_state = "platingdmg2" + }, +/area/space/nearstation) "xGp" = ( /obj/structure/rack, /obj/item/storage/toolbox/mechanical{ @@ -82599,9 +84810,8 @@ /turf/open/floor/plasteel, /area/science/mixing) "xHm" = ( -/obj/machinery/holopad, -/obj/structure/cable/yellow{ - icon_state = "1-4" +/obj/structure/disposalpipe/segment{ + dir = 9 }, /turf/open/floor/plasteel, /area/engineering/atmos) @@ -82638,14 +84848,14 @@ /turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) "xIi" = ( +/obj/item/reagent_containers/glass/bucket, +/obj/item/mop, +/obj/item/reagent_containers/glass/bottle/ammonia, /obj/structure/cable/yellow{ - icon_state = "1-2" + icon_state = "4-8" }, -/obj/structure/cable/yellow{ - icon_state = "2-8" - }, -/turf/open/floor/plasteel, -/area/security/prison) +/turf/open/floor/plating, +/area/maintenance/prison) "xIv" = ( /obj/item/radio/intercom{ name = "Station Intercom (General)"; @@ -82666,6 +84876,25 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/engine, /area/science/xenobiology) +"xJb" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "executionfireblast" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/security/execution/education) "xJf" = ( /obj/structure/window/reinforced{ dir = 8 @@ -82881,6 +85110,10 @@ /obj/structure/kitchenspike, /turf/open/floor/plasteel/showroomfloor, /area/service/kitchen) +"xOh" = ( +/obj/structure/table, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison/upper) "xOk" = ( /obj/structure/table/reinforced, /obj/machinery/door/firedoor, @@ -83112,6 +85345,16 @@ "xUO" = ( /turf/open/space, /area/space/nearstation) +"xUR" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/power/solar{ + id = "aftstarboard"; + name = "Aft-Starboard Solar Array" + }, +/turf/open/floor/plasteel/airless/solarpanel, +/area/solars/port/fore) "xVh" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -83206,6 +85449,13 @@ }, /turf/open/floor/plasteel/dark, /area/command/bridge) +"xXN" = ( +/obj/effect/spawner/structure/window, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/security/prison/upper) "xXR" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -83334,6 +85584,22 @@ }, /turf/open/floor/plasteel, /area/security/office) +"yaL" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/light{ + dir = 4; + light_color = "#c1caff" + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) "yaS" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ @@ -83406,6 +85672,16 @@ }, /turf/open/floor/plating, /area/maintenance/port/aft) +"ydu" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/security/prison) "ydB" = ( /obj/structure/showcase/machinery/microwave{ dir = 1; @@ -83676,24 +85952,18 @@ }, /turf/open/floor/plasteel, /area/cargo/warehouse) +"ykn" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Prison Common Room" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison/upper) "yko" = ( /obj/structure/table/wood, /obj/item/paicard, /turf/open/floor/wood, /area/service/library) -"ykx" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port/fore) "ykE" = ( /obj/structure/lattice, /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ @@ -83727,6 +85997,22 @@ }, /turf/open/floor/plasteel, /area/engineering/main) +"ylY" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison/upper) (1,1,1) = {" oRp @@ -87116,7 +89402,7 @@ oRp oRp oRp oRp -oRp +xyp oRp oRp oRp @@ -94581,17 +96867,17 @@ oRp oRp oRp oRp -xyp -oRp -oRp -oRp -oRp -oRp +aaa oRp oRp oRp oRp oRp +rpQ +xwj +rpQ +rpQ +rpQ oRp oRp oRp @@ -94844,11 +97130,11 @@ oRp oRp oRp oRp +rpQ oRp oRp oRp -oRp -oRp +xwj oRp oRp oRp @@ -95101,11 +97387,11 @@ oRp oRp oRp oRp -oRp -oRp -oRp -oRp -oRp +rpQ +aaf +gcB +aaf +lMJ oRp oRp oRp @@ -95350,33 +97636,33 @@ oRp oRp oRp oRp +xwj +rpQ +xwj +rpQ +rpQ +xGl +xwj +rpQ +lMJ oRp +wKG oRp +rpQ +rpQ +xvm +rpQ +rpQ +rpQ +xvm +anT +xvm +anT oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -aaa -aaa -aaa +anT +xvm +anT +anT anS anS anS @@ -95607,6 +97893,17 @@ oRp oRp oRp oRp +xvm +oRp +lMJ +oRp +oRp +oRp +oRp +oRp +oRp +qXS +wKG oRp oRp oRp @@ -95614,23 +97911,12 @@ oRp oRp oRp oRp +aaf oRp oRp +lMJ oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp +lMJ aaa aaa aaa @@ -95864,30 +98150,30 @@ oRp oRp oRp oRp +rpQ +oRp +lMJ +oRp +xUR +xUR +xUR +xUR +xUR +lMJ +fhs +aaf +xUR +xUR +xUR +xUR +xUR +oRp +aaf oRp oRp +rpQ oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp +lMJ aaa aaa aaa @@ -96110,41 +98396,41 @@ oRp oRp oRp oRp +aaa +aaa +aaa +aaa +aaa oRp oRp oRp oRp oRp oRp +lMJ +aaf +lMJ +aaf +kCX +kkC +kkC +kkC +kkC +vCh +mud +wol +jde +jde +jde +jde +ssE +aaf +aaf +aaf +aaf +rpQ oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp +lMJ aaa aaa aaa @@ -96367,6 +98653,10 @@ oRp oRp oRp oRp +aaa +aaa +aaa +aaa oRp oRp oRp @@ -96374,34 +98664,30 @@ oRp oRp oRp oRp +rpQ +oRp +lMJ +oRp +nsg +nsg +nsg +nsg +nsg +lMJ +mud +lMJ +nsg +nsg +nsg +nsg +nsg +oRp +aaf oRp oRp +lMJ oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -xtS -oRp -oRp -oRp -oRp -oRp -oRp +rpQ aaa aaa aaa @@ -96624,41 +98910,41 @@ oRp oRp oRp oRp +aaa +aaa +aaa +aaa +aaa oRp oRp oRp oRp oRp oRp +rpQ +oRp +lMJ +oRp +aEv +aEv +aEv oRp oRp oRp +mud +oRp +aEv oRp oRp +aEv oRp oRp +aaf +aaf +aaf +lMJ oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp +lMJ aaa aaa aaa @@ -96881,45 +99167,45 @@ oRp oRp oRp oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp aaa aaa aaa +aaa +aaa +oRp +oRp +oRp +oRp +oRp +oRp +rpQ +oRp +lMJ +oRp +xUR +xUR +xUR +xUR +xUR +lMJ +mud aaf +xUR +xUR +xUR +xUR +xUR +oRp +aaf +oRp +oRp +xwj +oRp +lMJ +aaa +aaa +aaa +xvm dne dne aip @@ -97138,45 +99424,45 @@ oRp oRp oRp oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp aaa aaa aaa +aaa +aaa +oRp +oRp +oRp +oRp +oRp +oRp +rpQ aaf +lMJ +lMJ +kCX +kkC +kkC +kkC +kkC +vCh +mud +wol +jde +jde +jde +jde +ssE +xwj +rpQ +aqB +anT +anT +oRp +anT +aqB +anT +xvm +anT dne aqC arW @@ -97395,27 +99681,6 @@ oRp oRp oRp oRp -oRp -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa aaa aaa aaa @@ -97425,11 +99690,32 @@ aaa aaa aaa aaa +lMJ +aaa +rpQ +aaa +lMJ +aaa +nsg +nsg +nsg +nsg +nsg +lMJ +mud +lMJ +nsg +nsg +nsg +nsg +nsg aaa aaa aaa aaa +xwj aaa +lMJ aaa aaa aaa @@ -97440,7 +99726,7 @@ arX dne dne dne -aRG +rPp aoc drQ dne @@ -97652,25 +99938,6 @@ oRp oRp oRp oRp -oRp -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa aaa aaa aaa @@ -97682,11 +99949,30 @@ aaa aaa aaa aaa +xwj +aaa +lMJ +mhW +aaa +aaf +aaf +aaf +lMJ +aaa +mud +aaa +gIi +aaf +aaf +aaf +aaf aaa aaa aaa aaa +rpQ aaa +lMJ aaa aaa aaa @@ -97738,7 +100024,7 @@ auF bCJ tUa alK -apz +mKY aob alC aqK @@ -97909,9 +100195,6 @@ oRp oRp oRp oRp -oRp -aaa -aaa aaa aaa aaa @@ -97939,11 +100222,14 @@ aaa aaa aaa aaa +rpQ aaa aaa aaa aaa +rpQ aaa +lMJ aaa aaa aaa @@ -98166,11 +100452,6 @@ oRp oRp oRp oRp -oRp -aaa -aaa -aaa -aaa aaa aaa aaa @@ -98190,6 +100471,7 @@ aaa aaa aaa aaa +lMJ aaa aaa aaa @@ -98202,10 +100484,14 @@ aaa aaa aaa aaa +lMJ +aaa +rpQ aaa aaa aaa aaa +aaf aqF doJ atq @@ -98423,7 +100709,6 @@ oRp oRp oRp oRp -oRp aaa aaa aaa @@ -98434,16 +100719,8 @@ aaa aaa aaa aaa -aaf aaa -aaa -aaa -aaa -aaf -aaa -aaa -aaa -aaf +lMJ aaa aaa aaa @@ -98457,11 +100734,20 @@ aaa aaa aaa aaa +geU aaa aaa aaa aaa aaa +aaa +lMJ +aaa +lMJ +lMJ +lMJ +lMJ +lMJ aaf aqF doJ @@ -98680,29 +100966,6 @@ oRp oRp oRp oRp -oRp -aaa -aaa -aaa -aaa -aaa -aaa -aaf -aaj -aag -aag -aag -aai -aag -aag -aag -aaj -aag -aag -aai -aag -aag -aaf aaa aaa aaa @@ -98718,7 +100981,30 @@ aaa aaa aaa aaa -aaf +aaa +aaa +aaa +aaa +mhW +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +lMJ +aaa +xwj +aaa +aaa +aaa +aaa aaf aqF doJ @@ -98937,29 +101223,6 @@ oRp oRp oRp oRp -oRp -aaa -aaa -aaa -aac -aaa -aaa -aai -aaa -aaf -aaf -aaf -aaa -aaf -aaf -aaf -aaa -aaf -aaf -aaa -aaa -aag -aaf aaa aaa aaa @@ -98976,6 +101239,29 @@ aaa aaa aaa aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +lMJ +aaa +xwj +lMJ +lMJ +lMJ +lMJ aaf aqF doJ @@ -99194,32 +101480,6 @@ oRp oRp oRp oRp -oRp -aaa -aaa -aaa -aaa -aaa -aaa -aaj -aaa -nmO -tbc -dDj -aaa -nmO -tbc -dDj -aaa -nmO -tbc -dDj -aaf -aag -aaf -aaa -aaa -aaf aaa aaa aaa @@ -99232,7 +101492,33 @@ aaa aaa aaa aaa -aaf +aaa +aaa +aaa +aaa +aaa +lMJ +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +gIi +aaa +aaa +aaa +aaa +lMJ +aaa +lMJ +aaa +aaa +aaa +aaa aaf aqF doJ @@ -99451,42 +101737,42 @@ oRp oRp oRp oRp -oRp aaa aaa aaa aaa aaa aaa -aag -aaf -nmO -ykx -dDj -aaa -nmO -ykx -dDj -aaa -nmO -ykx -dDj -aaf -aaf -aaf -aaf -aaf -aaf aaa aaa aaa aaa aaa aaa -aaf aaa aaa aaa +mhW +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +xwj +aaa +lMJ +aaa aaa aaa aaa @@ -99708,41 +101994,41 @@ oRp oRp oRp oRp -oRp aaa aaa aaa aaa aaa -aaf -aag -aaf -nmO -ykx +aaa +aaa +aaa +lMJ +aaa +aaa +rpQ +aaa +lMJ +aaa +aaa +aaa +aaa +aaa dDj -aaf -nmO -ykx -dDj -aaf -nmO -ykx -dDj -aaf aaa -aaf +mud +aaa +geU aaa aaa -aaf +aaa +mhW aaa aaa aaa aaa +aqB aaf -aaf -aaf -aaa -aaf +anT aaf aaf aaf @@ -99965,44 +102251,44 @@ oRp oRp oRp oRp -oRp aaa aaa aaa aaa aaa -aaf aaa aaa -nmO -ykx -dDj -aaa -nmO -ykx -dDj -aaa -nmO -ykx -dDj -aaf -aaa -aaf aaa aaa -aaf -aaf -aaf aaa aaa -aaf +rpQ aaa -aaf +lMJ +aaa +xUR +xUR +xUR +xUR +xUR +pKa +mud +grh +xUR +xUR +xUR +xUR +xUR +aaa +aaa +aaa +aaa +anT +aaa +anT aaa -aaf aaa aaa -aaf aaa aip dnO @@ -100222,38 +102508,38 @@ oRp oRp oRp oRp -oRp aaa aaa aaa -aaj -aag -aaj aaa aaa -nmO -ykx -dDj aaa -nmO -ykx -dDj aaa -nmO -ykx -dDj -aaf -aaf -aaf -aaf -aaf -aaf aaa +aaa +aaa +aaa +rpQ aaf +lMJ +lMJ +kCX +kkC +kkC +kkC +kkC +vCh +mud +wol +jde +jde +jde +jde +ssE +rpQ +rpQ aaf -aaf -aaf -aaf +aqB ahp aif ahp @@ -100304,7 +102590,7 @@ btZ bvV bxN mei -nzp +jPq xEM mei smm @@ -100478,38 +102764,38 @@ oRp oRp oRp oRp -oRp -oRp aaa aaa aaa -aag aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +rpQ +aaa +lMJ +aaa +nsg +nsg +nsg +nsg +nsg aaf -aaa -aaa -aaf -wwD -aaf -aaf -aaf -wwD -aaf -aaa -aaf -wwD -aaf -aaa +wZR aaf +nsg +nsg +nsg +nsg +nsg aaa aaa aaa -aaf -aaa -aaa -aaa -aaa -aaf aaa ahp aig @@ -100735,38 +103021,38 @@ oRp oRp oRp oRp -oRp -oRp aaa aaa aaa -aai aaa -lPr -wZC -wZC -bID -kQW -kQW -kQW -kfT -kQW -kQW -dSe -kQW -kQW -kQW -mLH -wZC -wZC -wZC -wZC -sZQ +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +rpQ +aaa +lMJ aaa aaa aaf +aaa +aaa +aaa +aaa +wKG +aaa aaf -aaf +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa ahq ahq @@ -100992,39 +103278,39 @@ oRp oRp oRp oRp -oRp -oRp aaa aaa aaa -aag aaa -aaf aaa -aaf -aaf -spA -aaf aaa -aaf -spA -aaf aaa -aaf -spA -aaf +aaa +aaa +aaa +aaa +aaa +xwj +aaa +lMJ +aaa aaa aaf aaa aaa +lMJ aaa -vjC +wKG +aaa +lMJ aaf -aaa aaf -aaa aaf -aaa +lMJ +lMJ +rpQ +rpQ +xwj ahq aih ajd @@ -101249,39 +103535,39 @@ oRp oRp oRp oRp -oRp -oRp aaa aaa aaa -aai -aaj -aaj -aaa -aaf -nmO -grC -dDj -aaa -nmO -grC -dDj -aaa -nmO -grC -dDj -aaa -aaf aaa aaa aaa -vjC aaa aaa aaa aaa +aaa +aaa +rpQ +aaa +lMJ +aaa +aaa aaf aaa +aaa +lMJ +aaa +qmP +wZC +tSe +aaa +aaf +aaa +lMJ +aaa +lMJ +aaa +aaa ahq aii ajg @@ -101506,8 +103792,6 @@ oRp oRp oRp oRp -oRp -oRp aaa aaa aaa @@ -101516,28 +103800,30 @@ aaa aaa aaa aaa -nmO -grC -dDj -aaf -nmO -grC -dDj -aaa -nmO -grC -dDj -aaa -aaf aaa aaa aaa -vjC +aaa +lMJ +aaa +lMJ aaf aaf aaf aaf aaf +lMJ +aaa +lMJ +aaa +wKG +aaa +aaf +aaa +lMJ +aaa +lMJ +aaa aaa ahq aij @@ -101763,39 +104049,39 @@ oRp oRp oRp oRp -oRp -oRp aaa aaa aaa aaa aaa aaa -aag -aaf -nmO -grC -dDj -aaa -nmO -grC -dDj -aaf -nmO -grC -dDj -aaf -aaf -aaf -aaf -aaf -vjC aaa aaa aaa +aaa +aaa +aaa +xwj +aaa +lMJ +aaa +aaa +aaa +aaa +aaa +lMJ +qle +lMJ +aaa +wKG +aaa aaf -aaf -aaf +aaa +lMJ +aaa +lMJ +aaa +aaa ahq aik anZ @@ -102020,37 +104306,37 @@ oRp oRp oRp oRp -oRp -oRp aaa aaa aaa aaa aaa aaa -aai -aaf -nmO +aaa +aaa +aaa +aaa +aaa +aaa +rpQ +aaa +lMJ +aaa +aaa +nLC grC -dDj -aaf -nmO grC -dDj +vjV +izT +izT aaa -nmO -grC -dDj -aaa -aaf -aaa -aaa -aaa -vjC +wKG aaa aaf aaf +lMJ aaf +lMJ aee bbo bbo @@ -102277,34 +104563,34 @@ oRp oRp oRp oRp -oRp -oRp aaa aaa aaa aaa aaa aaa -aaj aaa +aaa +aaa +aaa +aaa +aaa +rpQ +aaa +lMJ +aaa +nLC +gwC nmO sFR -dDj +lha +nWG +izT aaa -nmO -sFR -dDj -aaa -nmO -sFR -dDj +wKG aaa aaf aaa -aaa -aaa -vjC -aaa aee aee aee @@ -102534,33 +104820,33 @@ oRp oRp oRp oRp -oRp -oRp aaa aaa aaa +xvm +rpQ +rpQ +xwj +rpQ +xwj +rpQ +rpQ +aaf +xGl aaa +lMJ aaa -aaa -aaj +ubH +ulI +vbH +jVK +fOe +jpk +izT aaf -aaa -aaf -aaf -aaa -aaf -aaa -aaf -aaf -aaf -aaf -aaf -aaf -aaf -aaf -aaf -aaf -kWh +qmP +wZC +wZC wZC abN aef @@ -102791,31 +105077,31 @@ oRp oRp oRp oRp -oRp -oRp aaa aaa aaa -aaa -aaa -aaa -aaa -aaf -aai -aag -aai -aag -aaj -aag -aai -aaj +lMJ aaa aaa aaf aaa +lMJ aaa +aaa +aaa +lMJ aaf +lMJ aaa +gec +xAw +wgf +sUd +pCS +jtG +izT +izT +aaf aaa aaf aaa @@ -102830,7 +105116,7 @@ aji dnd alE vhj -aRG +rPp alE dou dne @@ -103048,37 +105334,37 @@ oRp oRp oRp oRp -oRp -oRp aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaf -aaf -aaa -aaf -aaa -aaf -aaa -aaa -aaa -aaf +lMJ aaa aaa aaf aaa +lMJ aaa -aaf aaa +aaa +rpQ +aaa +lMJ aaf +izT +qhO +qrs +kmQ +qUX +xvj +pdH +izT +xwj +gzW +gzW +rpQ +lMJ aaf -aaf +lMJ aee bbo bbo @@ -103305,37 +105591,37 @@ oRp oRp oRp oRp -oRp -oRp -aaa -aaa -aaa -aaa -aaa aaa aaa aaa +rpQ aaa aaa aaf -aaf -aaf aaa -aaf +izT +hKk +izT +izT +izT +izT +izT +izT +izT +sMe +sMe +sMe +qTc +xvj +pdH +hKk +aaa +xwj aaa aaa +lMJ aaa -aaf -aaf -aaa -aaf -aaa -aaa -aaf -aaf -aaf -aaa -aaf +lMJ aaf aaf aaf @@ -103561,38 +105847,38 @@ oRp oRp oRp oRp -oRp -oRp -oRp -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaf +rpQ +xvm +rpQ +lMJ +xwj aaf aaf +nLC +vjV +izT +svu +sMe +lAA +jsO +edY +ulp +uTQ +hlO +hlO +jbJ +sMe +eFk +hma +xAI +nPH +aaa +gzW aaa aaa +rpQ aaa -aaa -aaf -aaa -aaf -aaa -aaa -aaf -aaa -aaf -aaa -aaa +lMJ aaf aaa aaf @@ -103818,39 +106104,39 @@ oRp oRp oRp oRp -oRp -oRp -oRp -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +rpQ aaa aaa aaf aaa aaa aaa -aaZ -aaZ -aaZ -aaZ -aaZ -aaZ -aaZ -aaZ -aaZ -aaZ -aaZ -aaZ +gec +lQK +oUR +xDA +sMe +jIU +qFN +rYP +qFN +qFN +kze +rif +nFN +sMe +oqC +iRC +afH +bgb +bgb +bgb +bgb +bgb +bgb +lMJ +lMJ +aaa aaa aaf aio @@ -104075,39 +106361,39 @@ oRp oRp oRp oRp -oRp -oRp -oRp -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaf -aaf -aaa -aaa -aaf -abg -abx -abV -acm -acA +rpQ +lMJ +oKD +izT +oaH +vjV +izT +izT +sIN +xAO +haD +sMe +jxe +kaM +rIe +mjl +qTq +iei +mvS +xOh +nEC +itk +ylY +afH +adm +rvO +afH acV adm -adJ -aeg -aeH -aaZ +bgb +aaf +aaa +aaa aaa aaf aio @@ -104332,39 +106618,39 @@ oRp oRp oRp oRp +rpQ oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -aaa -aaa -aaa -aaa -aaa -aaa -aaf -aaf -aaf -aaf -aaf -abg -aby -abW -acn -acB +izT +izT +wNK +rqn +nEC +pCQ +xAO +xAO +wzi +sMe +sMe +sMe +sMe +sMe +kGI +iei +mvS +xOh +nEC +cUT +xvj +afH +swH +lFW +afH acW adn -adK -aeh -aeI -aaZ +bgb +aaf +aaf +aaa aaf aaf aaf @@ -104589,40 +106875,40 @@ oRp oRp oRp oRp +rpQ oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -aaa -aaa -aaa -aaa -aaf -aaf -aaf -aaa -aaa -aaa -aaf -abg -abz -abX -aco -acC +izT +oqD +mUE +sck +nEC +emo +xAO +hXi +viX +dCu +pAw +jVo +wDM +sMe +sMe +uvn +xXN +nEC +sMe +rCq +xvj +afH +fRj +gwI +afH acX ado -adL -aei -aeJ -aaZ -aaa +bgb +bgb +aaf +aaf +aaf aaa aaf aaf @@ -104846,40 +107132,40 @@ oRp oRp oRp oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -aaa -aaa -aaa -aaa -aai -aaa -aaf -aaa -aaa -aaa -aax -aax -aax -aax -aax -aax +rpQ +lMJ +izT +poR +mUE +oKu +rCF +wyf +mOH +gjm +fKj +gyf +hzP +nEa +oKe +bTB +hzP +sbg +vkq +hzP +nNO +qqj +xpx +upD +qXt acY -adp +kQr +acY +ofK adM -aax -aax -aax -aax +bgb +bgb +bgb +bgb aaa aaa aaf @@ -105103,41 +107389,41 @@ oRp oRp oRp oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -aaa -aaa -aaa -aaa -aaj -aaf -aaf -aaa -aaa -aaf -aay +xwj +lMJ +izT +dsC +mUE +mlV +ykn +mak +eiU +dbx +mak +uam +ayq +abh +xuu +yaL +abh +xuu +fEV +abh +fhK +rSi abh abA abY acp -aax +uUN vla adq adN aej aeK afF -aax -aax +bgb +aaa aaa aaf aaa @@ -105360,41 +107646,41 @@ oRp oRp oRp oRp +rpQ oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -aaa -aaa -aaa -aaa -aai -aaa -aaf -aaf -aaf -aaf -aax -abi +izT +ijq +mUE +eaE +nEC +emo +xAO +wWN +xAO +pxQ +sMe +sMe +fdl +uxR +sMe +wwa +uxR +sMe +sMe abB -abe -abe -aax +abB +abB +exz +wIu +gkG ada -adr +ven adr aek aeL afG -agE -aax +bgb +aaa aaa aaf aaf @@ -105617,41 +107903,41 @@ oRp oRp oRp oRp +rpQ oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -aaa -aaa -aaa -aaa -aaf -aaa -aax -aax -aaF -aax -aax +izT +izT +mBZ +hZd +nEC +mvI +pzy +xAO +xAO +wcj +sMe +fCR +npY +eEy +sMe +wWN +ulQ +jIF +sMe +mhG abj -aaR +fKv abZ acq acD -abe +szt ads adO -ael -aeM afH -agF -afW +afH +afH +bgb +aaf aaf aaf aaa @@ -105874,41 +108160,41 @@ oRp oRp oRp oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -aaa -aaa -aaa -aaa -aaf -aaf -aay +kKH +lMJ +oKD +izT +oaH +gwC +izT +izT +izT +pqv +sMT +sMT +sMe +glz +bRR +qWm +sMe +mxT rLV -xIi -abC +bvX +sMe jhu xIi -abC +abB abC acr acE adb -aaR -aaR +ven +adr aem aeN afI -agG -aax +bgb +aaa aaa aaf aaa @@ -106132,40 +108418,40 @@ oRp oRp oRp oRp +lMJ oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -aaa -aaa -aaa -aaa aaf -aaa -aax +oRp +oRp +aaf +oRp +izT +qiz +iBL +iBL +sMe +iUN +iUN +iUN +sMe +bQZ abl -roa -ram -aax +jIF +sMe +ihO iCn -aaR -aaR -aaI +abB +llF +uOr acF -abe -adt +qTV +adq adP -abe +oGG aeO -afJ -aax -aax +afF +bgb +aaa aaa aaf aaa @@ -106389,42 +108675,42 @@ oRp oRp oRp oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -oRp -aaa -aaa -aaa -aaa -aaa -aaa -aax -aax -aax -aax -aax -abm -aaR -aaR -aaI -acG -adc -adc -adQ -adc -aeP -afK -agH -aax -aaa aaf +rpQ +xwj +xGl +rpQ +xvm +rpQ +izT +izT +izT +izT +aaZ +aaZ +aaZ +aaZ +aaZ +aaZ +aaZ +aaZ +aaZ +aaZ +aaZ +aaZ +vXi +aME +acG +qTV +vtn +adQ +afH +afH +afH +bgb +rRB +lUk +bgb dne dne dne @@ -106657,34 +108943,34 @@ oRp oRp oRp aaa -aaa -aaa -aaa -aaf -aaa -aax +nhI +abg +abx +abV +acm +xJb aaA aaG -aaP -aax -abn -aaR +adJ +aeg +aeH +aaZ abD -acs -acH -abe +aME +acG +qTV adu adR -abe -aeQ +qES +agI afL agI afW -aaf -aaf -dne +dve +bgb alL anb +mMf aok aox aqV @@ -106914,34 +109200,34 @@ oRp oRp oRp aaa -aaa -aaa -aaa -aaf -aaf -aay +uOH +abg +aby +abW +acn +mIR aaB aaH aaQ -aba +aeh abo -abF -aca +aaZ +abD act -acI +acG add adv adS aen -aeR -afG agH -aax -aaf -aaf -dne +agH +agH +hsr +ohf +bgb alL anc +aRG aol apD aqW @@ -107171,30 +109457,30 @@ oRp oRp oRp aaa -aaa -aaa -aaa -aaf -aaa -aax +ikj +abg +abz +abX +aco +syL aaC -aaI -aaR -abb -aaI -abG +uNg +kUL +aei +aeJ +aaZ acb acu acJ -abe +pJv adw -adT -adc -aeS -afM -abe aax -aiq +aax +aax +aax +wBB +cKy +qIB ajm ajm ajm @@ -107423,36 +109709,36 @@ oRp oRp oRp oRp -oRp -oRp -oRp -oRp -aaa -aaa -aaa -aaa -aaa -aaa -aay +rpQ +fOG +siF +siF +siF +aaZ +aaZ +aaZ +aaZ +aaZ +aaZ aaD -aaJ +adp aaS -abc -abp -acc -acc -acv +aaZ +aaZ +aaZ +aax +aax acK -abe -abe -abe -abe +dwf +upX +aax +llY aeT -afN -abe -ahu +aax +wHw +ajm air -ahx +ajm akt alM and @@ -107680,33 +109966,33 @@ oRp oRp oRp oRp -oRp -oRp -oRp -oRp -aaa -aaa -aaa -aaa -aaf -aaa +lMJ +lMJ +lMJ +lMJ +lMJ +lMJ +lMJ aax +hGz +sja +aaZ aaE aaK aaT -aax +aaZ abq abI -abC +nnO acw acL -abe +kUN adx -adU +abe ael aeU -afO abe +hXW ahv ais ahx @@ -107942,30 +110228,30 @@ oRp oRp oRp aaa +vLD aaa -aaa -aaa -aaf -aaf -aax -aax -aaL -aax aax +ovd +hGz +aaZ +aaZ +scs +suZ +aaZ abr abJ -aaR -aaR -aaR +qUm +gmU +lxV ade -aaR -aaR -aeo -aeV -afP +cUU abe -ahw -air +llY +aeV +abe +vRz +aws +aws ahx akv alO @@ -108199,29 +110485,29 @@ oRp oRp oRp aaa +vLD aaa -aaa -aaa -aaf -aaa -aaa -aaf -aaa -aaa -aay +aax +fUI +oEN +hGz +uiA +dxy +vSH +abe abs abK ace -acx +aax acM -abe +ewU ady -adT -adc +abe +abe aeW -afK -agJ -ahx +abe +pvy +pvy ait ahx akw @@ -108456,32 +110742,32 @@ oRp oRp oRp aaa -aaa -aaa -aaa -aaf -aaf -aaf -aaf -aaa +ack +lMJ urv aax aax +aZO +kwe +mpv +rLx +abe +aay +qRZ +eSb aax -aax -aax -abe -abe -abe -abe -abe +qEk +hDB +oVt +fvV +tJI dpy afR -agK -ahy -aiu -ajn akx +anh +anh +hRD +anh alQ anh aor @@ -108717,28 +111003,28 @@ aaa aaa aaa aaa -aaa -aaf -aaa -aaa -aaa -aaa wOY abL +aax +uUK +uBA +nAj +nAj +nJo acf acy -abL +iyp adf adz -acf +agL hyP aeY -afG agL -ahz -aiv -ajo aky +azE +azE +azE +azE akg ani aos @@ -108970,32 +111256,32 @@ oRp oRp oRp aaa -aaa -aaa -aaa -aaa -aaa -aaa -adG +lSH aaa aaa aaa abu abM +adG +wtO +mgT +ydu +mQt +tDM acg -aax -abe -abe -abe -abe -abe +keE +ojh +qKq +rub +kVM +vSL aeZ afS -agM -ahA -aiw -ajp akz +wKX +wKX +wKX +wKX ajQ egm aot @@ -109231,23 +111517,23 @@ aaa aaa aaa aaa -aaf -aaf -aaa -aaa -aaa -aaa wOY -abe -ach +mFa aax +ubD +aaI +ovU +aaR +aDg +ach +pUL acN adg adA -adV +aax adc -afa -afT +aax +aax agN ahB ahB @@ -109484,29 +111770,29 @@ oRp oRp oRp aaa -aaa -aaa -aaa -aaa -aaa -aaf -aaa -aaa +ngt +lMJ urv -abe -abe -abe -abL aax +aax +aax +aax +uvz +pJX +abe +png +abe +aCJ +hwd acO adh -adB -adW -aep -afb -afU -agO -ahB +aaF +aax +aaf +aaf +aaf +aaf +adY aNA ajq aix @@ -109743,27 +112029,27 @@ oRp aaa aaa aaa +vLD aaa aaa aaa -aaf -aaf -aaa -aaa -aaf -aaa +aax +aay +aaL +abe +kyV abe acj -aax +nlq acR adi adC -adX -ael -afd -afV -agP -ahB +aaa +aaa +aaa +aaa +aaf +adY aiy dBZ ajr @@ -110000,26 +112286,26 @@ oRp aaa aaa aaa +vLD +vLD +vLD +vLD +vLD aaa -aaa -aaa -aaa -aaf -aaf -aaf -aaf -aaf +vLD +aax +xhP abe -wiZ aax aax +aay aaL -aax -aax -aax -afc -afW -aax +aaa +aaa +aaa +aaa +aaa +aaf adY aiz ajt @@ -110257,22 +112543,22 @@ oRp aaa aaa aaa +vLD aaa aaa aaa +vLD aaa +vLD +aax +wiZ +aax aaf aaa aaa -aaf aaa aaa -ack aaa -aaa -aaf -aaa -aaf aaf aaf aaf @@ -110514,21 +112800,21 @@ oRp aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaf -aaf -aaf -ack +vLD +vLD +vLD +vLD +vLD +vLD +vLD +ngt +ngt +ngt aaf aaf aaf aaf +aaa aaf aaf aeq @@ -110785,7 +113071,7 @@ aaa aaa aaa aaf -aaa +aaf aaf aeq aeq @@ -112063,7 +114349,7 @@ oRp oRp oRp oRp -aav +oRp oRp aaa aaa @@ -112300,7 +114586,7 @@ oRp oRp oRp oRp -xtS +oRp oRp oRp oRp @@ -114375,7 +116661,7 @@ oRp oRp oRp oRp -aav +oRp oRp oRp aaa @@ -117522,7 +119808,7 @@ teZ teZ wbZ hCA -msI +mWS pzY kPZ upO @@ -120075,7 +122361,7 @@ nQW yeJ pSY avD -dnR +osn dtS tMD eoN @@ -122936,7 +125222,7 @@ alq diu bWZ bYs -bZB +iaH bZE ccG ceb @@ -123437,8 +125723,8 @@ ieJ nGn uoM lUn -dlF -uhB +wFX +ify qxd qtO qtO @@ -124206,7 +126492,7 @@ qxd jJw usM lXt -xHm +lzQ tyC kLr kdi @@ -124463,7 +126749,7 @@ odq ipm hAI oBF -erz +oBF jxI kLr qDJ @@ -124719,9 +127005,9 @@ bvh qxd oNX vzb -iix -woN -tyC +mMn +cWn +xHm kLr iix sKv @@ -124977,7 +127263,7 @@ qxd wtG qWR cVp -woN +gGc dtk lFH hdJ @@ -125233,8 +127519,8 @@ iLe qxd oBX olw -oWF -cWn +sKv +sKv uKL ktV wKg @@ -125491,7 +127777,7 @@ sKv oay fNf kWW -gGc +uKL grX hop ldI @@ -125501,7 +127787,7 @@ ooB ibJ ibJ ibJ -ibJ +tGd ibJ ibJ omb @@ -125748,7 +128034,7 @@ hZe mZD mSB dRb -hAI +oWF tFH tfk sfM @@ -125758,7 +128044,7 @@ eCZ mMn mMn mMn -mMn +fYL mMn mMn eWY @@ -126015,7 +128301,7 @@ pcs mMn mMn mMn -mMn +fYL mMn mMn mMn @@ -126262,7 +128548,7 @@ uhB jiZ mHn mHn -fGc +mHn rdg fGc lHN @@ -126272,7 +128558,7 @@ mMn mMn mMn mMn -mMn +fYL mMn mMn mMn @@ -126529,7 +128815,7 @@ mMn mMn mMn mMn -mMn +tzt mMn mMn mMn @@ -127312,7 +129598,7 @@ uKL aaf dYX htG -wFX +uLh rjT dPI aaf diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm index 1355aab9a6..84339218c3 100644 --- a/_maps/map_files/Mining/Lavaland.dmm +++ b/_maps/map_files/Mining/Lavaland.dmm @@ -77,35 +77,20 @@ "aA" = ( /turf/open/lava/smooth/lava_land_surface, /area/template_noop) +"aJ" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/item/pickaxe, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) "aQ" = ( /obj/structure/stone_tile/surrounding_tile{ dir = 1 }, /turf/closed/indestructible/riveted/boss, /area/lavaland/surface/outdoors) -"aU" = ( -/obj/structure/stone_tile/block/cracked, -/obj/structure/stone_tile{ - dir = 4 - }, -/obj/item/t_scanner/adv_mining_scanner/lesser, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"cp" = ( -/obj/structure/stone_tile/block{ - dir = 1 - }, -/turf/closed/indestructible/riveted/boss, -/area/ruin/unpowered/ash_walkers) -"cu" = ( -/obj/item/pickaxe, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"cv" = ( -/obj/structure/ore_box, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"cw" = ( +"aV" = ( /obj/structure/stone_tile/block{ dir = 4 }, @@ -117,46 +102,104 @@ }, /obj/effect/decal/cleanable/blood, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"dA" = ( +/area/ruin/lavaland/unpowered/ash_walkers) +"bb" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/item/storage/bag/plants/portaseeder, +/obj/item/storage/bag/plants, +/obj/item/seeds/cotton{ + yield = 5 + }, +/obj/item/seeds/cotton/durathread, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"bn" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/obj/structure/stone_tile/block{ + dir = 4 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"ci" = ( +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/effect/decal/cleanable/blood, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"cn" = ( +/obj/structure/stone_tile/slab, +/obj/structure/table/wood, +/obj/item/storage/toolbox/syndicate, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"cu" = ( +/obj/item/pickaxe, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"cv" = ( +/obj/structure/ore_box, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"cO" = ( +/obj/structure/stone_tile, +/obj/item/shard, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"cQ" = ( +/obj/structure/stone_tile/surrounding/cracked, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"cU" = ( /obj/structure/stone_tile/block/cracked{ dir = 1 }, -/turf/closed/indestructible/riveted/boss, -/area/ruin/unpowered/ash_walkers) +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile, +/obj/effect/decal/cleanable/blood, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"cW" = ( +/obj/structure/stone_tile/block, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"cZ" = ( +/obj/machinery/hydroponics/soil, +/obj/structure/stone_tile/block{ + dir = 8 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) "dD" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 4 }, /turf/closed/indestructible/riveted/boss, /area/lavaland/surface/outdoors) -"dF" = ( -/obj/structure/stone_tile/block/cracked, -/turf/closed/mineral/volcanic/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"dM" = ( -/obj/structure/stone_tile/cracked{ - dir = 8 - }, -/obj/structure/stone_tile{ - dir = 4 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"eb" = ( -/obj/structure/stone_tile/block{ - dir = 8 - }, -/obj/machinery/iv_drip, -/obj/item/reagent_containers/glass/beaker/waterbottle/large, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"eh" = ( -/obj/structure/stone_tile/slab/cracked{ - dir = 4 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) "eo" = ( /obj/structure/stone_tile/cracked, /obj/structure/stone_tile/block{ @@ -176,25 +219,20 @@ }, /turf/closed/mineral/volcanic/lava_land_surface, /area/lavaland/surface/outdoors) -"eQ" = ( -/obj/structure/closet/crate/radiation, -/obj/item/flashlight/lantern, -/obj/item/flashlight/lantern, -/obj/item/flashlight/lantern, -/obj/item/flashlight/flare, +"fd" = ( +/obj/structure/stone_tile, +/turf/closed/mineral/volcanic/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"fp" = ( +/obj/structure/stone_tile/surrounding_tile/cracked, +/turf/closed/mineral/volcanic/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"fx" = ( /obj/structure/stone_tile/block/cracked{ - dir = 8 - }, -/obj/structure/stone_tile/cracked{ dir = 1 }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"ft" = ( -/obj/structure/stone_tile/block, -/obj/item/spear/bonespear, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/turf/closed/indestructible/riveted/boss, +/area/ruin/lavaland/unpowered/ash_walkers) "fN" = ( /obj/structure/stone_tile{ dir = 4 @@ -367,6 +405,18 @@ }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"gV" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) "hd" = ( /obj/structure/mineral_door/sandstone, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, @@ -395,19 +445,13 @@ }, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) -"hy" = ( -/obj/structure/stone_tile/block/cracked{ - dir = 4 +"hG" = ( +/obj/item/storage/box/rxglasses, +/obj/structure/stone_tile{ + dir = 1 }, -/turf/open/lava/smooth{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, -/area/ruin/unpowered/ash_walkers) -"hD" = ( -/obj/effect/mob_spawn/human/corpse/damaged, -/obj/effect/decal/cleanable/blood, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "hH" = ( /obj/structure/stone_tile/block{ dir = 1 @@ -491,47 +535,6 @@ /obj/structure/stone_tile/block/cracked, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"iG" = ( -/obj/structure/stone_tile/block{ - dir = 1 - }, -/obj/structure/stone_tile, -/obj/structure/stone_tile/cracked{ - dir = 8 - }, -/obj/item/stack/sheet/mineral/wood, -/obj/item/stack/sheet/mineral/wood, -/obj/item/stack/sheet/mineral/wood, -/obj/item/stack/sheet/mineral/wood, -/obj/item/seeds/ambrosia/deus{ - potency = 50; - yield = 5 - }, -/obj/item/seeds/ambrosia/deus{ - potency = 50; - yield = 5 - }, -/obj/item/seeds/tower, -/obj/item/seeds/tower, -/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"iJ" = ( -/obj/structure/stone_tile, -/obj/structure/stone_tile{ - dir = 8 - }, -/obj/structure/stone_tile{ - dir = 1 - }, -/obj/structure/stone_tile/cracked{ - dir = 4 - }, -/obj/structure/table/wood, -/obj/item/clothing/head/helmet/roman/legionnaire, -/obj/item/spear/bonespear, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) "iK" = ( /obj/structure/stone_tile/block, /obj/structure/stone_tile/cracked{ @@ -581,16 +584,15 @@ }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"jj" = ( -/obj/structure/stone_tile/block, -/obj/structure/stone_tile/cracked{ - dir = 1 - }, -/obj/structure/stone_tile{ +"jh" = ( +/obj/structure/stone_tile/block{ dir = 4 }, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/obj/structure/stone_tile/block/cracked{ + dir = 1 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) "jk" = ( /obj/structure/stone_tile/center, /obj/structure/stone_tile/surrounding_tile, @@ -706,12 +708,17 @@ }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"ke" = ( -/obj/structure/stone_tile/block{ - dir = 4 +"jV" = ( +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/effect/mob_spawn/human/corpse/damaged, +/obj/effect/decal/cleanable/blood, +/obj/structure/stone_tile/cracked{ + dir = 1 }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "kg" = ( /obj/structure/fluff/drake_statue, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, @@ -739,6 +746,20 @@ /obj/structure/stone_tile, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"kw" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/item/flashlight/lantern, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) "ky" = ( /obj/structure/stone_tile/cracked{ dir = 4 @@ -830,15 +851,13 @@ /obj/structure/stone_tile/slab/cracked, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"lb" = ( -/obj/structure/stone_tile/block{ - dir = 1 - }, +"kZ" = ( +/obj/item/shovel, /obj/structure/stone_tile/cracked{ dir = 8 }, -/turf/closed/indestructible/riveted/boss, -/area/ruin/unpowered/ash_walkers) +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) "le" = ( /obj/structure/stone_tile, /obj/structure/stone_tile{ @@ -858,6 +877,19 @@ }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"li" = ( +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/closet/crate/medical, +/obj/item/storage/firstaid/regular, +/obj/item/storage/firstaid/ancient, +/obj/item/reagent_containers/blood/random, +/obj/item/reagent_containers/blood/lizard, +/obj/item/reagent_containers/blood/lizard, +/obj/item/stack/sheet/cloth/ten, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) "lj" = ( /obj/structure/stone_tile/block{ dir = 1 @@ -990,6 +1022,16 @@ }, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) +"lJ" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 1 + }, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) "lP" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 @@ -1085,6 +1127,20 @@ }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"mo" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/obj/item/flashlight/lantern, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) "mq" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 @@ -1427,85 +1483,77 @@ }, /turf/open/indestructible/boss, /area/lavaland/surface/outdoors) -"nt" = ( -/obj/structure/stone_tile/block, +"nI" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/turf/open/lava/smooth{ + initial_gas_mix = "o2=14;n2=23;TEMP=300" + }, +/area/ruin/lavaland/unpowered/ash_walkers) +"nR" = ( +/obj/structure/well_foundation, +/obj/item/reagent_containers/glass/bucket/wood, +/obj/item/reagent_containers/glass/bucket/wood, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"nT" = ( +/obj/structure/stone_tile, /obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ dir = 1 }, -/obj/structure/stone_tile{ - dir = 4 - }, -/obj/effect/decal/cleanable/blood, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"nB" = ( -/obj/item/shovel, -/obj/structure/stone_tile/cracked{ - dir = 8 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"nJ" = ( -/turf/closed/wall/mineral/wood, -/area/ruin/unpowered/ash_walkers) -"nU" = ( -/obj/structure/stone_tile, -/obj/item/shard, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"nW" = ( -/obj/structure/stone_tile, -/obj/structure/stone_tile{ - dir = 1 - }, -/obj/structure/stone_tile/cracked{ - dir = 4 - }, +/obj/item/spear/bonespear, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"nV" = ( /obj/structure/stone_tile/cracked{ dir = 8 }, +/obj/structure/closet/crate, /obj/item/flashlight/lantern, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/obj/item/flashlight/lantern, +/obj/item/flashlight/lantern, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"nZ" = ( +/obj/structure/stone_tile/surrounding_tile/cracked, +/obj/structure/stone_tile/center, +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/turf/open/lava/smooth{ + initial_gas_mix = "o2=14;n2=23;TEMP=300" + }, +/area/ruin/lavaland/unpowered/ash_walkers) "ol" = ( /obj/effect/landmark/stationroom/lavaland/station, /turf/open/lava/smooth/lava_land_surface, /area/template_noop) +"oo" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) "ot" = ( /obj/structure/stone_tile/surrounding_tile, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"oB" = ( -/obj/item/stack/sheet/mineral/wood, -/obj/structure/stone_tile{ +"oQ" = ( +/obj/structure/stone_tile/block{ dir = 4 }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"oS" = ( -/obj/structure/stone_tile/cracked{ +/obj/structure/stone_tile/block/cracked{ dir = 8 }, -/obj/item/storage/firstaid/ancient, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"pc" = ( -/obj/effect/decal/cleanable/blood, -/obj/structure/stone_tile/block, -/obj/structure/stone_tile/cracked{ - dir = 4 - }, -/obj/structure/stone_tile/cracked{ - dir = 1 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"pq" = ( -/obj/structure/stone_tile/cracked{ - dir = 1 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) "pt" = ( /obj/structure/stone_tile/block/cracked{ dir = 8 @@ -1546,20 +1594,6 @@ }, /turf/closed/indestructible/riveted/boss, /area/lavaland/surface/outdoors) -"qh" = ( -/obj/structure/stone_tile/surrounding/cracked{ - dir = 1 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"qi" = ( -/obj/structure/stone_tile/block{ - dir = 8 - }, -/turf/open/lava/smooth{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, -/area/ruin/unpowered/ash_walkers) "qA" = ( /obj/item/flashlight/lantern, /obj/structure/stone_tile/center, @@ -1579,49 +1613,28 @@ /obj/structure/stone_tile/slab, /turf/closed/indestructible/riveted/boss, /area/lavaland/surface/outdoors) -"rz" = ( -/obj/item/storage/box/rxglasses, -/obj/structure/stone_tile{ - dir = 1 +"ri" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/obj/item/flashlight/lantern, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"ry" = ( +/obj/effect/decal/cleanable/blood, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "rO" = ( /obj/structure/stone_tile/surrounding_tile/cracked, /obj/structure/ore_box, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"rQ" = ( -/obj/structure/stone_tile/block{ - dir = 1 - }, -/turf/open/lava/smooth{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, -/area/ruin/unpowered/ash_walkers) -"sa" = ( -/obj/structure/stone_tile/block{ - dir = 4 - }, -/obj/structure/stone_tile/block/cracked{ - dir = 8 - }, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"se" = ( -/obj/structure/stone_tile, -/obj/structure/stone_tile{ - dir = 8 - }, -/obj/structure/stone_tile{ - dir = 1 - }, -/obj/structure/stone_tile/cracked{ - dir = 4 - }, -/obj/item/flashlight/lantern, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) "sk" = ( /obj/structure/stone_tile/block/cracked{ dir = 1 @@ -1632,109 +1645,43 @@ }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"sl" = ( -/obj/structure/stone_tile/block{ - dir = 1 - }, -/obj/structure/stone_tile{ - dir = 8 - }, -/turf/closed/indestructible/riveted/boss, -/area/ruin/unpowered/ash_walkers) -"sx" = ( -/obj/item/stack/sheet/mineral/coal, -/obj/item/stack/sheet/mineral/coal, -/obj/item/stack/sheet/mineral/coal, -/obj/item/stack/sheet/mineral/coal, -/obj/item/stack/sheet/mineral/coal, -/obj/item/stack/sheet/mineral/coal, -/obj/item/stack/sheet/mineral/coal, -/obj/item/stack/sheet/mineral/coal, -/obj/item/stack/sheet/mineral/coal, -/obj/item/stack/sheet/mineral/coal, -/obj/item/stack/sheet/mineral/coal, -/obj/item/stack/sheet/mineral/coal, -/obj/item/stack/sheet/mineral/coal, -/obj/item/stack/sheet/mineral/coal, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"ty" = ( -/obj/structure/stone_tile, -/obj/structure/stone_tile{ - dir = 8 - }, -/obj/structure/stone_tile{ - dir = 1 - }, -/obj/structure/stone_tile{ +"sn" = ( +/obj/structure/stone_tile/surrounding_tile{ dir = 4 }, -/obj/item/flashlight/lantern, +/obj/structure/stone_tile/center/cracked, +/obj/structure/stone_tile/surrounding_tile/cracked, +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 1 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"sD" = ( +/obj/structure/lavaland/ash_walker, +/turf/open/lava/smooth{ + initial_gas_mix = "o2=14;n2=23;TEMP=300" + }, +/area/ruin/lavaland/unpowered/ash_walkers) +"sI" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 8 + }, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"tz" = ( +/area/ruin/lavaland/unpowered/ash_walkers) +"td" = ( /obj/structure/stone_tile/slab, /obj/structure/table/wood, /obj/item/toy/cards/deck/syndicate, /obj/item/construction/rcd/loaded/upgraded, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"ui" = ( -/obj/structure/stone_tile/cracked{ - dir = 4 - }, -/obj/structure/stone_tile{ - dir = 1 - }, -/obj/structure/stone_tile{ - dir = 8 - }, -/obj/effect/decal/cleanable/blood, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"uk" = ( -/obj/structure/lavaland/ash_walker, -/turf/open/lava/smooth{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, -/area/ruin/unpowered/ash_walkers) -"uz" = ( -/obj/structure/stone_tile/block/cracked{ - dir = 1 - }, -/turf/closed/indestructible/riveted/boss, -/area/lavaland/surface/outdoors) -"vi" = ( -/obj/structure/stone_tile/block{ - dir = 1 - }, -/obj/structure/stone_tile/cracked, -/obj/structure/stone_tile{ - dir = 8 - }, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"vu" = ( -/obj/structure/stone_tile/surrounding_tile/cracked, -/obj/structure/stone_tile/surrounding_tile/cracked{ - dir = 4 - }, -/obj/structure/stone_tile/center, -/obj/structure/stone_tile/surrounding_tile{ - dir = 8 - }, -/turf/open/lava/smooth{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, -/area/ruin/unpowered/ash_walkers) -"vR" = ( -/obj/machinery/hydroponics/soil, -/obj/structure/stone_tile/block/cracked{ - dir = 1 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"wm" = ( +/area/ruin/lavaland/unpowered/ash_walkers) +"tG" = ( /obj/item/seeds/glowshroom{ potency = 50; yield = 5 @@ -1748,26 +1695,111 @@ }, /mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"ww" = ( -/obj/structure/stone_tile/surrounding_tile/cracked{ +/area/ruin/lavaland/unpowered/ash_walkers) +"tL" = ( +/obj/structure/flora/rock/pile/largejungle{ + light_range = null + }, +/turf/open/water, +/area/ruin/lavaland/unpowered/ash_walkers) +"tN" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/turf/closed/mineral/volcanic/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"ut" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/effect/decal/cleanable/blood, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"uz" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 1 + }, +/turf/closed/indestructible/riveted/boss, +/area/lavaland/surface/outdoors) +"uD" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/structure/stone_tile/block{ + dir = 4 + }, +/turf/closed/indestructible/riveted/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"uT" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/item/flashlight/lantern, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"vo" = ( +/obj/structure/stone_tile/surrounding_tile{ dir = 4 }, -/obj/structure/stone_tile/center/cracked, -/obj/structure/stone_tile/surrounding_tile, /obj/structure/stone_tile/surrounding_tile{ dir = 1 }, -/turf/open/lava/smooth{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 8 }, -/area/ruin/unpowered/ash_walkers) +/obj/structure/stone_tile/center, +/obj/effect/decal/cleanable/blood, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"vs" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/table/wood, +/obj/item/clothing/head/helmet/roman/legionnaire, +/obj/item/spear/bonespear, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"vR" = ( +/obj/machinery/hydroponics/soil, +/obj/structure/stone_tile/block/cracked{ + dir = 1 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) "wF" = ( /obj/structure/stone_tile/surrounding_tile{ dir = 4 }, /turf/closed/indestructible/riveted/boss, /area/lavaland/surface/outdoors) +"wT" = ( +/obj/structure/stone_tile/block/cracked, +/turf/open/lava/smooth{ + initial_gas_mix = "o2=14;n2=23;TEMP=300" + }, +/area/ruin/lavaland/unpowered/ash_walkers) "xr" = ( /obj/structure/stone_tile/cracked{ dir = 4 @@ -1781,112 +1813,67 @@ /obj/item/pickaxe, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"xs" = ( -/obj/structure/stone_tile/block/cracked{ +"xJ" = ( +/obj/structure/stone_tile/cracked{ dir = 8 }, -/turf/closed/mineral/volcanic/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"xX" = ( -/obj/structure/stone_tile/block{ - dir = 8 - }, -/obj/item/pickaxe, +/obj/item/storage/firstaid/ancient, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"yf" = ( -/obj/machinery/hydroponics/soil, -/obj/structure/stone_tile/surrounding_tile/cracked{ +/area/ruin/lavaland/unpowered/ash_walkers) +"yg" = ( +/obj/structure/stone_tile/cracked{ dir = 1 }, +/turf/closed/mineral/volcanic/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"yZ" = ( +/turf/closed/wall/mineral/wood, +/area/ruin/lavaland/unpowered/ash_walkers) +"zE" = ( +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/center/cracked, /obj/structure/stone_tile/surrounding_tile, /obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/turf/open/lava/smooth{ + initial_gas_mix = "o2=14;n2=23;TEMP=300" + }, +/area/ruin/lavaland/unpowered/ash_walkers) +"Am" = ( +/obj/structure/stone_tile/block/cracked, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ dir = 4 }, -/obj/structure/stone_tile/center, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"zf" = ( -/obj/structure/stone_tile, -/obj/structure/stone_tile{ - dir = 4 - }, -/obj/structure/stone_tile{ - dir = 8 - }, +/area/ruin/lavaland/unpowered/ash_walkers) +"Ay" = ( /obj/structure/stone_tile/cracked{ dir = 1 }, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"zv" = ( -/obj/machinery/hydroponics/soil, -/obj/structure/stone_tile/block{ - dir = 8 - }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"An" = ( -/obj/structure/stone_tile/slab, -/obj/structure/table/wood, -/obj/item/spear/bonespear, -/obj/item/spear/bonespear, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"AH" = ( -/obj/structure/stone_tile{ - dir = 4 - }, -/obj/structure/stone_tile/cracked{ - dir = 8 - }, -/obj/item/spear/bonespear, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"AU" = ( -/obj/structure/stone_tile, -/turf/closed/mineral/volcanic/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"AY" = ( -/obj/structure/stone_tile, -/obj/structure/stone_tile{ - dir = 8 - }, -/obj/structure/stone_tile/cracked{ - dir = 4 - }, -/obj/structure/stone_tile/cracked{ - dir = 1 - }, -/obj/item/flashlight/lantern, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"Bj" = ( -/obj/structure/stone_tile/block{ - dir = 4 - }, -/obj/structure/stone_tile/block/cracked{ - dir = 8 - }, +/area/ruin/lavaland/unpowered/ash_walkers) +"AN" = ( /obj/effect/decal/cleanable/blood, -/obj/structure/necropolis_gate/ashwalker, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/obj/structure/stone_tile/block, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) "Br" = ( /obj/structure/stone_tile/slab, /obj/effect/decal/cleanable/blood, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"Bs" = ( -/obj/structure/stone_tile/cracked{ - dir = 8 - }, -/obj/structure/closet/crate, -/obj/item/flashlight/lantern, -/obj/item/flashlight/lantern, -/obj/item/flashlight/lantern, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) "BF" = ( /obj/structure/flora/rock/jungle, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, @@ -1913,94 +1900,89 @@ /obj/structure/stone_tile/center/cracked, /turf/closed/mineral/volcanic/lava_land_surface, /area/lavaland/surface/outdoors) -"BP" = ( -/obj/structure/stone_tile/block/cracked{ - dir = 4 - }, -/obj/structure/stone_tile/cracked{ - dir = 4 - }, -/obj/structure/stone_tile{ - dir = 8 - }, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"BU" = ( -/turf/closed/indestructible/riveted/boss/see_through, -/area/ruin/unpowered/ash_walkers) -"Ch" = ( -/obj/structure/stone_tile/surrounding_tile{ - dir = 4 - }, -/obj/structure/stone_tile/center/cracked, -/obj/structure/stone_tile/surrounding_tile/cracked, -/obj/structure/stone_tile/surrounding_tile/cracked{ - dir = 1 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"CG" = ( -/obj/structure/stone_tile/cracked{ +"CI" = ( +/obj/structure/stone_tile/slab/cracked{ dir = 4 }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"CL" = ( -/obj/structure/stone_tile/slab, -/obj/structure/table/wood, -/obj/item/clothing/head/helmet/skull, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"Dn" = ( -/obj/structure/stone_tile/block{ - dir = 8 - }, -/turf/closed/indestructible/riveted/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "Do" = ( /obj/structure/stone_tile/block{ dir = 8 }, /turf/closed/indestructible/riveted/boss, /area/lavaland/surface/outdoors) +"Dt" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/item/stack/sheet/mineral/wood, +/obj/item/stack/sheet/mineral/wood, +/obj/item/stack/sheet/mineral/wood, +/obj/item/stack/sheet/mineral/wood, +/obj/item/seeds/ambrosia/deus{ + potency = 50; + yield = 5 + }, +/obj/item/seeds/ambrosia/deus{ + potency = 50; + yield = 5 + }, +/obj/item/seeds/tower, +/obj/item/seeds/tower, +/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) "Dx" = ( /obj/structure/bonfire/dense, /obj/structure/stone_tile/center, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"Dz" = ( +"DT" = ( +/obj/structure/stone_tile/slab, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"Eb" = ( +/obj/structure/closet/crate, /obj/structure/stone_tile/block/cracked{ - dir = 8 - }, -/obj/structure/stone_tile/cracked{ dir = 1 }, -/obj/structure/stone_tile, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"DQ" = ( /obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/cracked, +/obj/item/flashlight/lantern, +/obj/item/flashlight/lantern, +/obj/item/flashlight/lantern, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"Ej" = ( +/obj/structure/stone_tile/block/cracked{ dir = 4 }, -/obj/item/book/granter/crafting_recipe/bone_bow, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"Ef" = ( -/obj/structure/stone_tile/block/cracked, /turf/open/lava/smooth{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered/ash_walkers) -"Ez" = ( -/obj/machinery/grill{ - name = "old rusty grill" +/area/ruin/lavaland/unpowered/ash_walkers) +"ER" = ( +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 8 }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"EQ" = ( -/obj/structure/stone_tile/surrounding/cracked, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/obj/structure/stone_tile/center, +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/turf/open/lava/smooth{ + initial_gas_mix = "o2=14;n2=23;TEMP=300" + }, +/area/ruin/lavaland/unpowered/ash_walkers) "Fn" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 @@ -2010,15 +1992,6 @@ }, /turf/closed/indestructible/riveted/boss, /area/lavaland/surface/outdoors) -"Fz" = ( -/obj/structure/stone_tile/surrounding_tile{ - dir = 8 - }, -/obj/structure/stone_tile/block{ - dir = 4 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) "FD" = ( /obj/structure/stone_tile/cracked{ dir = 8 @@ -2026,6 +1999,13 @@ /obj/structure/stone_tile/cracked, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"FG" = ( +/obj/item/stack/sheet/mineral/wood, +/obj/structure/stone_tile{ + dir = 4 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) "Gc" = ( /obj/structure/flora/junglebush/b, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, @@ -2043,20 +2023,73 @@ }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"GC" = ( -/obj/structure/stone_tile/surrounding_tile/cracked, -/obj/structure/stone_tile/center, -/obj/structure/stone_tile/surrounding_tile{ +"GS" = ( +/turf/closed/indestructible/riveted/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"Hw" = ( +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile/cracked, +/obj/structure/stone_tile/cracked{ dir = 1 }, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/machinery/the_singularitygen, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"HN" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"HV" = ( +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"Ig" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/turf/closed/indestructible/riveted/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"Ih" = ( +/obj/structure/stone_tile/block, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"Ir" = ( +/obj/structure/stone_tile/block/cracked, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/item/t_scanner/adv_mining_scanner/lesser, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"Ji" = ( +/obj/structure/stone_tile/surrounding_tile/cracked, +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/center, /obj/structure/stone_tile/surrounding_tile{ dir = 8 }, /turf/open/lava/smooth{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, -/area/ruin/unpowered/ash_walkers) -"Hq" = ( +/area/ruin/lavaland/unpowered/ash_walkers) +"JS" = ( /obj/structure/stone_tile, /obj/structure/stone_tile{ dir = 8 @@ -2071,60 +2104,63 @@ /obj/item/scythe, /obj/item/spear/bonespear, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"HX" = ( -/obj/structure/stone_tile/block{ - dir = 4 - }, -/obj/structure/stone_tile/block/cracked{ +/area/ruin/lavaland/unpowered/ash_walkers) +"JW" = ( +/obj/structure/stone_tile/surrounding/cracked{ dir = 1 }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"Jq" = ( -/obj/structure/stone_tile/slab/cracked, -/obj/effect/decal/cleanable/blood, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"JP" = ( +/area/ruin/lavaland/unpowered/ash_walkers) +"KF" = ( /obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, /obj/structure/stone_tile{ dir = 1 }, /obj/structure/stone_tile/cracked{ dir = 4 }, -/obj/structure/stone_tile/cracked{ - dir = 8 - }, -/obj/effect/decal/cleanable/blood, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"KA" = ( -/obj/structure/stone_tile/slab, +/obj/item/flashlight/lantern, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"KJ" = ( -/obj/structure/stone_tile/block/cracked, -/obj/structure/stone_tile{ +/area/ruin/lavaland/unpowered/ash_walkers) +"KX" = ( +/obj/machinery/hydroponics/soil, +/obj/structure/stone_tile/surrounding_tile/cracked{ dir = 1 }, -/obj/structure/stone_tile{ +/obj/structure/stone_tile/surrounding_tile, +/obj/structure/stone_tile/surrounding_tile{ dir = 4 }, +/obj/structure/stone_tile/center, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"KV" = ( -/obj/structure/stone_tile/cracked{ +/area/ruin/lavaland/unpowered/ash_walkers) +"Lu" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/turf/open/lava/smooth{ + initial_gas_mix = "o2=14;n2=23;TEMP=300" + }, +/area/ruin/lavaland/unpowered/ash_walkers) +"Ly" = ( +/obj/structure/stone_tile/block{ dir = 8 }, -/obj/effect/mob_spawn/human/corpse/damaged, -/obj/effect/decal/cleanable/blood, /obj/structure/stone_tile/cracked{ dir = 1 }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/obj/structure/stone_tile, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"LF" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/turf/closed/indestructible/riveted/boss, +/area/ruin/lavaland/unpowered/ash_walkers) "LJ" = ( /turf/open/water, /area/lavaland/surface/outdoors) @@ -2135,17 +2171,24 @@ }, /turf/closed/indestructible/riveted/boss, /area/lavaland/surface/outdoors) +"Ms" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/obj/structure/stone_tile, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) "Mx" = ( /turf/closed/mineral/volcanic/lava_land_surface, /area/lavaland/surface/outdoors) -"MQ" = ( -/obj/structure/table/optable, -/obj/structure/stone_tile{ - dir = 1 - }, -/obj/item/surgical_drapes, +"ML" = ( +/obj/structure/stone_tile/block, +/obj/item/spear/bonespear, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) "MS" = ( /obj/structure/stone_tile/cracked{ dir = 1 @@ -2153,31 +2196,29 @@ /obj/structure/stone_tile/cracked, /turf/closed/mineral/volcanic/lava_land_surface, /area/lavaland/surface/outdoors) -"MX" = ( -/obj/structure/stone_tile/slab/cracked, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"Ou" = ( -/obj/structure/stone_tile/slab, -/obj/structure/table/wood, -/obj/item/storage/toolbox/syndicate, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"Oy" = ( -/obj/structure/stone_tile/surrounding_tile{ - dir = 4 - }, -/obj/structure/stone_tile/surrounding_tile{ +"Nl" = ( +/obj/structure/stone_tile/block/cracked, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"Ny" = ( +/obj/structure/table/optable, +/obj/structure/stone_tile{ dir = 1 }, -/obj/structure/stone_tile/surrounding_tile/cracked{ - dir = 8 - }, -/obj/structure/stone_tile/center, -/obj/effect/decal/cleanable/blood, +/obj/item/surgical_drapes, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"Pj" = ( +/area/ruin/lavaland/unpowered/ash_walkers) +"NJ" = ( +/obj/machinery/grill{ + name = "old rusty grill" + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"Pa" = ( +/obj/structure/stone_tile/block/cracked, +/turf/closed/mineral/volcanic/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"Pc" = ( /obj/structure/stone_tile/surrounding_tile/cracked, /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 1 @@ -2187,21 +2228,112 @@ }, /obj/structure/stone_tile/center, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"Qd" = ( +/area/ruin/lavaland/unpowered/ash_walkers) +"Qc" = ( /obj/structure/stone_tile/block{ dir = 8 }, +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/turf/closed/indestructible/riveted/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"Qv" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/machinery/iv_drip, +/obj/item/reagent_containers/glass/beaker/waterbottle/large, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"Rk" = ( /obj/structure/stone_tile, +/obj/structure/stone_tile/block{ + dir = 1 + }, +/turf/closed/indestructible/riveted/boss, +/area/lavaland/surface/outdoors) +"Rs" = ( +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/item/spear/bonespear, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"Sh" = ( +/obj/structure/stone_tile/block, +/turf/closed/mineral/volcanic/lava_land_surface, +/area/lavaland/surface/outdoors) +"Sn" = ( +/obj/structure/stone_tile/slab, +/obj/structure/table/wood, +/obj/item/spear/bonespear, +/obj/item/spear/bonespear, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"SG" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/turf/closed/indestructible/riveted/boss, +/area/lavaland/surface/outdoors) +"SJ" = ( +/obj/structure/closet/crate/radiation, +/obj/item/flashlight/lantern, +/obj/item/flashlight/lantern, +/obj/item/flashlight/lantern, +/obj/item/flashlight/flare, +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"ST" = ( /obj/structure/stone_tile{ dir = 1 }, -/obj/structure/table/wood, -/obj/item/storage/belt, -/obj/item/spear/bonespear, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"SW" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/obj/effect/decal/cleanable/blood, +/obj/structure/necropolis_gate/ashwalker, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"Qk" = ( +/area/ruin/lavaland/unpowered/ash_walkers) +"Tc" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/closed/indestructible/riveted/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"Tj" = ( +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"TA" = ( /obj/structure/stone_tile{ dir = 4 }, @@ -2214,122 +2346,21 @@ }, /obj/item/stack/marker_beacon/ten, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"QC" = ( -/obj/structure/stone_tile/block, -/obj/structure/stone_tile{ - dir = 1 - }, -/obj/structure/stone_tile{ - dir = 4 - }, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"QG" = ( -/obj/structure/stone_tile/block{ - dir = 8 - }, -/obj/structure/stone_tile/cracked{ - dir = 1 - }, -/obj/structure/stone_tile, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"QM" = ( -/obj/structure/stone_tile/surrounding_tile/cracked, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"Rb" = ( -/obj/structure/closet/crate, -/obj/structure/stone_tile/block/cracked{ - dir = 1 - }, -/obj/structure/stone_tile{ - dir = 8 - }, -/obj/structure/stone_tile/cracked, -/obj/item/flashlight/lantern, -/obj/item/flashlight/lantern, -/obj/item/flashlight/lantern, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"Rk" = ( -/obj/structure/stone_tile, -/obj/structure/stone_tile/block{ - dir = 1 - }, -/turf/closed/indestructible/riveted/boss, -/area/lavaland/surface/outdoors) -"Rr" = ( -/obj/structure/stone_tile/block/cracked{ - dir = 8 - }, -/turf/closed/indestructible/riveted/boss, -/area/ruin/unpowered/ash_walkers) -"RF" = ( -/obj/structure/stone_tile/block/cracked{ - dir = 8 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"RX" = ( -/obj/structure/stone_tile/block/cracked{ - dir = 1 - }, -/obj/structure/stone_tile{ - dir = 8 - }, -/obj/structure/stone_tile, +/area/ruin/lavaland/unpowered/ash_walkers) +"TF" = ( +/obj/effect/mob_spawn/human/corpse/damaged, /obj/effect/decal/cleanable/blood, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"Sh" = ( -/obj/structure/stone_tile/block, -/turf/closed/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) -"Si" = ( -/turf/closed/indestructible/riveted/boss, -/area/ruin/unpowered/ash_walkers) -"SG" = ( -/obj/structure/stone_tile/block{ - dir = 4 - }, -/turf/closed/indestructible/riveted/boss, -/area/lavaland/surface/outdoors) -"Tn" = ( -/obj/structure/stone_tile/block{ - dir = 1 - }, -/obj/structure/stone_tile/cracked, -/obj/structure/stone_tile{ - dir = 8 - }, -/obj/structure/table/wood, -/obj/item/kitchen/knife/combat/bone, -/obj/item/book/granter/crafting_recipe/bone_bow, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"TN" = ( -/obj/structure/stone_tile/surrounding_tile/cracked{ - dir = 8 - }, -/obj/structure/stone_tile/center, -/obj/structure/stone_tile/surrounding_tile{ - dir = 1 - }, -/obj/structure/stone_tile/surrounding_tile{ - dir = 4 - }, -/turf/open/lava/smooth{ - initial_gas_mix = "o2=14;n2=23;TEMP=300" - }, -/area/ruin/unpowered/ash_walkers) -"Uh" = ( +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"TP" = ( /obj/structure/stone_tile/slab, /obj/structure/table/wood, /obj/item/weldingtool/experimental, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/area/ruin/lavaland/unpowered/ash_walkers) +"Ug" = ( +/turf/closed/indestructible/riveted/boss/see_through, +/area/ruin/lavaland/unpowered/ash_walkers) "Uq" = ( /obj/docking_port/stationary{ area_type = /area/lavaland/surface/outdoors; @@ -2350,96 +2381,65 @@ /obj/effect/decal/cleanable/blood, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"Vb" = ( -/obj/structure/stone_tile/block/cracked{ - dir = 4 +"VG" = ( +/obj/structure/stone_tile/block, +/obj/structure/stone_tile{ + dir = 1 }, /obj/structure/stone_tile{ - dir = 8 - }, -/obj/structure/stone_tile/cracked{ dir = 4 }, -/obj/item/storage/bag/plants/portaseeder, -/obj/item/storage/bag/plants, -/obj/item/seeds/cotton{ - yield = 5 - }, -/obj/item/seeds/cotton/durathread, +/obj/effect/decal/cleanable/blood, /turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"Vj" = ( -/obj/structure/stone_tile/cracked{ +/area/ruin/lavaland/unpowered/ash_walkers) +"VT" = ( +/obj/structure/stone_tile/block{ dir = 1 }, -/turf/closed/mineral/volcanic/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"VI" = ( -/obj/structure/well_foundation, -/obj/item/reagent_containers/glass/bucket/wood, -/obj/item/reagent_containers/glass/bucket/wood, +/obj/structure/stone_tile/cracked, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/table/wood, +/obj/item/kitchen/knife/combat/bone, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"We" = ( +/obj/structure/stone_tile/surrounding_tile/cracked, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"Wb" = ( +/area/ruin/lavaland/unpowered/ash_walkers) +"WH" = ( +/obj/structure/stone_tile/slab/cracked, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"WR" = ( /obj/structure/stone_tile/block{ dir = 8 }, -/obj/structure/stone_tile/block{ - dir = 4 - }, -/turf/closed/indestructible/riveted/boss, -/area/ruin/unpowered/ash_walkers) -"Wh" = ( -/obj/structure/stone_tile{ - dir = 1 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"Wj" = ( -/obj/structure/stone_tile/surrounding_tile/cracked, -/turf/closed/mineral/volcanic/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"WA" = ( -/obj/structure/stone_tile/block/cracked, -/obj/item/book/granter/crafting_recipe/bone_bow, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"WL" = ( -/obj/structure/stone_tile{ - dir = 4 - }, -/obj/structure/closet/crate/medical, -/obj/item/storage/firstaid/regular, -/obj/item/storage/firstaid/ancient, -/obj/item/reagent_containers/blood/random, -/obj/item/reagent_containers/blood/lizard, -/obj/item/reagent_containers/blood/lizard, -/obj/item/stack/sheet/cloth/ten, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"WN" = ( /obj/structure/stone_tile, /obj/structure/stone_tile{ - dir = 8 - }, -/obj/structure/stone_tile/cracked{ dir = 1 }, +/obj/structure/table/wood, +/obj/item/storage/belt, /obj/item/spear/bonespear, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"WT" = ( -/obj/structure/stone_tile/block{ - dir = 4 - }, -/obj/structure/stone_tile{ +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"Xb" = ( +/obj/structure/stone_tile/cracked{ dir = 8 }, /obj/structure/stone_tile{ dir = 4 }, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) +"Xd" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/turf/closed/indestructible/riveted/boss, +/area/ruin/lavaland/unpowered/ash_walkers) "Xe" = ( /obj/structure/stone_tile/surrounding_tile, /obj/structure/stone_tile/center/cracked, @@ -2451,87 +2451,78 @@ }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"Xf" = ( -/obj/structure/stone_tile/block{ - dir = 8 - }, -/obj/structure/stone_tile, -/obj/structure/stone_tile{ - dir = 1 - }, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) "Xo" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 }, /turf/closed/indestructible/riveted/boss, /area/lavaland/surface/outdoors) -"Xw" = ( -/obj/structure/stone_tile{ - dir = 1 - }, -/obj/structure/stone_tile, -/obj/structure/stone_tile/cracked{ - dir = 8 - }, -/obj/structure/stone_tile/cracked{ - dir = 4 - }, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) "Xz" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 8 }, /turf/closed/mineral/volcanic/lava_land_surface, /area/lavaland/surface/outdoors) -"XG" = ( -/obj/effect/decal/cleanable/blood, -/obj/structure/stone_tile/cracked{ - dir = 8 - }, -/obj/structure/stone_tile/cracked{ - dir = 4 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"Yg" = ( -/obj/structure/flora/rock/pile/largejungle{ - light_range = null - }, -/turf/open/water, -/area/ruin/unpowered/ash_walkers) -"Yy" = ( -/obj/structure/stone_tile/block/cracked{ - dir = 4 - }, -/obj/item/flashlight/lantern, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered/ash_walkers) -"Zc" = ( -/obj/structure/stone_tile{ - dir = 4 - }, -/obj/structure/stone_tile/cracked, -/obj/structure/stone_tile/cracked{ +"XS" = ( +/obj/structure/stone_tile/block{ dir = 1 }, /obj/structure/stone_tile/cracked{ dir = 8 }, -/obj/machinery/the_singularitygen, -/turf/open/indestructible/boss, -/area/ruin/unpowered/ash_walkers) -"Zs" = ( -/obj/structure/stone_tile/block{ - dir = 8 - }, -/obj/structure/stone_tile/block/cracked{ +/turf/closed/indestructible/riveted/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"Yc" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile{ dir = 4 }, -/turf/closed/indestructible/riveted/boss, -/area/ruin/unpowered/ash_walkers) +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"Yd" = ( +/obj/structure/stone_tile/slab/cracked, +/obj/effect/decal/cleanable/blood, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"YQ" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/obj/structure/stone_tile/cracked, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"Zh" = ( +/obj/structure/stone_tile/slab, +/obj/structure/table/wood, +/obj/item/clothing/head/helmet/skull, +/turf/open/indestructible/boss, +/area/ruin/lavaland/unpowered/ash_walkers) +"Zk" = ( +/obj/item/stack/sheet/mineral/coal, +/obj/item/stack/sheet/mineral/coal, +/obj/item/stack/sheet/mineral/coal, +/obj/item/stack/sheet/mineral/coal, +/obj/item/stack/sheet/mineral/coal, +/obj/item/stack/sheet/mineral/coal, +/obj/item/stack/sheet/mineral/coal, +/obj/item/stack/sheet/mineral/coal, +/obj/item/stack/sheet/mineral/coal, +/obj/item/stack/sheet/mineral/coal, +/obj/item/stack/sheet/mineral/coal, +/obj/item/stack/sheet/mineral/coal, +/obj/item/stack/sheet/mineral/coal, +/obj/item/stack/sheet/mineral/coal, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/ruin/lavaland/unpowered/ash_walkers) (1,1,1) = {" aa @@ -55489,11 +55480,11 @@ aa aa ab ab -Ez +NJ ab LJ LJ -Yg +tL LJ ai ai @@ -55746,7 +55737,7 @@ aa aa ab ab -sx +Zk ab LJ LJ @@ -56771,9 +56762,9 @@ Do Mh aa aa -Rr +Ig Mx -xs +tN eq ab ab @@ -57024,13 +57015,13 @@ aa aa aa aa -Si -Si -Si -Si -Si -Si -Si +GS +GS +GS +GS +GS +GS +GS it ab ab @@ -57281,22 +57272,22 @@ aa aa aa aa -Si -oS -CG -wm -Vb -Bs -Si +GS +xJ +HV +tG +bb +nV +GS it jq jR -AH +Rs jS jS -KV +jV ab -DQ +jx aa aa ab @@ -57538,18 +57529,18 @@ aa aa aa Gw -Si -aU -Wh -zf -Qk -iG -Si +GS +Ir +ST +Yc +TA +Dt +GS jQ ll Xe iu -Ch +sn ja jx jQ @@ -57795,13 +57786,13 @@ aa aa aa Rk -Si -WA -rz -qh -pq -Jq -ke +GS +Nl +hG +JW +Ay +Yd +oo gP ma ix @@ -58052,13 +58043,13 @@ aa aa aa uz -Si -MQ -nU -ui -Xw -Rb -Si +GS +Ny +cO +ci +Tj +Eb +GS ix jQ gt @@ -58309,21 +58300,21 @@ aa aa aa uz -Si -WL -eb -dM -eQ -Zc -Si +GS +li +Qv +Xb +SJ +Hw +GS jQ -XG +ry kN mn iy -oB +FG ll -nB +kZ ab aa aa @@ -58566,21 +58557,21 @@ aa aa aa aa -Si -Si -Si -Si -Si -Si -Si +GS +GS +GS +GS +GS +GS +GS jR jQ jR ae jx -Pj +Pc ia -yf +KX jS aa aj @@ -58823,17 +58814,17 @@ aa aa dD pt -Wb -Dn -Zs -Zs -xX +uD +LF +Qc +Qc +aJ jb -Fz -QM +bn +We jR jQ -pc +AN lg it qA @@ -59079,13 +59070,13 @@ aa aa wF qS -Si -Si -Si -Si -Si -Si -Si +GS +GS +GS +GS +GS +GS +GS Br pD jQ @@ -59093,7 +59084,7 @@ jx mn jQ hr -zv +cZ BH jq Mx @@ -59334,24 +59325,24 @@ aj aa aa aa -cp -Si -KA -KA -KA -KA -KA -Si -Si -Si -ft +Xd +GS +DT +DT +DT +DT +DT +GS +GS +GS +ML jx kN mn -VI -Vj +nR +yg MS -AU +fd Mx Mx ab @@ -59591,19 +59582,19 @@ aj aa aa aa -lb -tz -KA -AY -BP -cw -WT -ty -Si -Si +XS +td +DT +mo +sI +aV +gV +uT +GS +GS qN ab -hD +TF gR Mx Mx @@ -59848,25 +59839,25 @@ aj aa aa aa -dA -Ou -KA -QC -GC -hy -ww -vi -Si -BU +fx +cn +DT +cW +nZ +Ej +zE +YQ +GS +Ug kP iY jR lG js Mx -xs -xs -xs +tN +tN +tN Xz Mx ab @@ -60105,25 +60096,25 @@ aj aa aa aa -cp -An -KA -nt -Ef -uk -rQ -MX -sa -Bj +Xd +Sn +DT +VG +wT +sD +Lu +WH +oQ +SW gP kj lg sk -Si -Si -nJ -Si -Si +GS +GS +yZ +GS +GS Mx Mx ab @@ -60362,25 +60353,25 @@ aj aa aa aa -cp -Uh -KA -jj -vu -qi -TN -RX -Si -BU -Oy +Xd +TP +DT +Ih +Ji +nI +ER +cU +GS +Ug +vo iY kN gR -nJ -WN -Yy -Hq -nJ +yZ +nT +ri +JS +yZ Mx Mx ab @@ -60619,25 +60610,25 @@ aj aa aa aa -sl -CL -KA -nW -Dz -Xf -QG -se -Si -Si -KJ +Tc +Zh +DT +kw +Ms +lJ +Ly +KF +GS +GS +Am jR fN gP -RF -eh -EQ -Tn -nJ +HN +CI +cQ +VT +yZ Mx Mx aj @@ -60876,25 +60867,25 @@ aj aa aa aa -cp -Si -KA -KA -KA -KA -KA -Si -Si -Si +Xd +GS +DT +DT +DT +DT +DT +GS +GS +GS ix kN jq ab -nJ -JP -Qd -iJ -Si +yZ +ut +WR +vs +GS Sh Mx ab @@ -61135,24 +61126,24 @@ aa aa pH qS -Si -Si -Si -Si -Si -Si -Si +GS +GS +GS +GS +GS +GS +GS kR rO xr ab eo -nJ -nJ -nJ -Si -Si -dF +yZ +yZ +yZ +GS +GS +Pa Mx ab aj @@ -61409,7 +61400,7 @@ Mx eP Mx Mx -Wj +fp Mx ab aj @@ -61660,7 +61651,7 @@ Mx ab ab ab -HX +jh Mx Mx Mx diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index 92f9ff0c53..fb77051142 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -151,16 +151,6 @@ icon_state = "1-2" }, /obj/structure/table/reinforced, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aat" = ( @@ -168,16 +158,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aau" = ( @@ -187,16 +167,6 @@ icon_state = "1-2" }, /obj/structure/table/reinforced, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aav" = ( @@ -302,32 +272,12 @@ pixel_y = 3 }, /obj/item/storage/firstaid/regular, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaD" = ( /obj/structure/chair/office/dark{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaE" = ( @@ -338,16 +288,6 @@ icon_state = "1-2" }, /obj/structure/table/reinforced, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaF" = ( @@ -358,16 +298,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaG" = ( @@ -378,32 +308,12 @@ icon_state = "1-2" }, /obj/structure/table/reinforced, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaH" = ( /obj/structure/chair/office/dark{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaI" = ( @@ -411,16 +321,6 @@ /obj/machinery/cell_charger, /obj/item/stock_parts/cell/high, /obj/item/stock_parts/cell/high, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaJ" = ( @@ -487,16 +387,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaN" = ( @@ -506,16 +396,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaO" = ( @@ -528,16 +408,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaP" = ( @@ -550,32 +420,12 @@ pixel_x = -3; pixel_y = 3 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaQ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaR" = ( @@ -585,17 +435,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 9 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "aaS" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -604,16 +446,6 @@ /obj/item/kirbyplants{ icon_state = "plant-22" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaT" = ( @@ -623,16 +455,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaU" = ( @@ -651,16 +473,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaV" = ( @@ -682,12 +494,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaY" = ( @@ -697,12 +503,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aaZ" = ( @@ -721,12 +521,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "aba" = ( @@ -734,12 +528,6 @@ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "abb" = ( @@ -756,16 +544,6 @@ c_tag = "Bar"; dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/bar/atrium) "abc" = ( @@ -778,17 +556,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/command/bridge) "abd" = ( /obj/structure/cable/white{ @@ -805,17 +573,8 @@ }, /obj/effect/landmark/event_spawn, /obj/machinery/holopad, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, /area/command/bridge) "abe" = ( /obj/structure/cable/white{ @@ -827,12 +586,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "abf" = ( @@ -848,12 +601,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "abg" = ( @@ -864,12 +611,6 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "abh" = ( @@ -885,12 +626,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "abi" = ( @@ -902,10 +637,6 @@ /area/asteroid/nearstation) "abk" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/command/glass{ - name = "Bridge Access"; - req_access_txt = "19" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/sign/directions/engineering{ desc = "A sign that shows there are doors here. There are doors everywhere!"; @@ -916,24 +647,20 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/command/bridge) -"abl" = ( -/obj/machinery/door/firedoor, /obj/machinery/door/airlock/command/glass{ name = "Bridge Access"; req_access_txt = "19" }, +/turf/open/floor/plasteel/dark, +/area/command/bridge) +"abl" = ( +/obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/command/glass{ + name = "Bridge Access"; + req_access_txt = "19" }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/command/bridge) "abm" = ( /obj/structure/cable/white{ @@ -967,50 +694,25 @@ }, /turf/open/floor/plating, /area/engineering/main) -"abo" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/command/bridge) "abp" = ( /obj/structure/cable/white{ icon_state = "1-2" }, /obj/structure/table/wood, /obj/item/storage/lockbox/medal, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/command/bridge) "abq" = ( /obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/airlock/command/glass{ name = "Bridge Access"; req_access_txt = "19" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/command/bridge) "abr" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/command/glass{ - name = "Bridge Access"; - req_access_txt = "19" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" @@ -1021,11 +723,11 @@ name = "WARNING: PRESSURIZED DOORS"; pixel_x = 32 }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/command/glass{ + name = "Bridge Access"; + req_access_txt = "19" }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/command/bridge) "abs" = ( /turf/closed/wall/r_wall, @@ -1059,24 +761,18 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 10 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "abz" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/light_switch{ pixel_x = 24 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 5 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "abA" = ( /turf/closed/wall, @@ -1104,26 +800,12 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "abD" = ( /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "abE" = ( @@ -1136,28 +818,12 @@ /obj/structure/table/wood, /obj/item/paper_bin, /obj/item/pen, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "abF" = ( /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "abG" = ( @@ -1182,13 +848,9 @@ /obj/machinery/light_switch{ pixel_x = -24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "abI" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -1198,11 +860,9 @@ /obj/structure/extinguisher_cabinet{ pixel_x = 26 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 6 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "abJ" = ( /obj/structure/table/wood, @@ -1212,16 +872,6 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/bar/atrium) "abK" = ( @@ -1282,9 +932,6 @@ /obj/structure/cable/white{ icon_state = "0-2" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, /obj/effect/spawner/structure/window/plasma/reinforced, /obj/machinery/door/poddoor/shutters/radiation/preopen{ id = "engsm"; @@ -1430,24 +1077,18 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 10 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "ace" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 5 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "acf" = ( /obj/structure/cable/white{ @@ -1464,10 +1105,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "ach" = ( @@ -1510,36 +1147,24 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "acm" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "acn" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 6 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "aco" = ( /obj/structure/table/wood, @@ -1559,11 +1184,9 @@ c_tag = "Bridge - Head of Personnel's Quarters"; name = "command camera" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 9 }, -/turf/open/floor/plasteel/dark, /area/command/heads_quarters/hop) "acp" = ( /obj/structure/bed, @@ -1633,9 +1256,6 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "acw" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, /obj/structure/cable/white{ icon_state = "4-8" }, @@ -1645,13 +1265,15 @@ /obj/structure/cable/white{ icon_state = "2-8" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, /turf/open/floor/plating, /area/maintenance/starboard) "acx" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, -/obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/freezer, /area/commons/toilet/restrooms) "acy" = ( @@ -1659,9 +1281,6 @@ name = "External Airlock"; req_access_txt = "13" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 8 }, @@ -1674,7 +1293,7 @@ /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/maintenance/starboard) "acz" = ( /obj/structure/cable/white{ @@ -1692,14 +1311,14 @@ /area/engineering/main) "acA" = ( /obj/structure/cable/white, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 - }, /obj/effect/spawner/structure/window/plasma/reinforced, /obj/machinery/door/poddoor/shutters/radiation/preopen{ id = "engsm"; name = "Radiation Chamber Shutters" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, /turf/open/floor/plating, /area/engineering/gravity_generator) "acB" = ( @@ -1709,6 +1328,9 @@ id = "engsm"; name = "Radiation Chamber Shutters" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plating, /area/engineering/main) "acC" = ( @@ -1781,15 +1403,8 @@ /obj/machinery/camera{ c_tag = "Head of Security's Office - Quarters" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/item/storage/fancy/donut_box{ + pixel_y = 7 }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) @@ -1884,24 +1499,18 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 10 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "acV" = ( /obj/structure/cable/white{ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 5 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "acW" = ( /obj/structure/cable/white{ @@ -1910,35 +1519,13 @@ /obj/structure/cable/white{ icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /obj/machinery/door/airlock/command{ name = "Council Chambers"; req_access_txt = "19" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/command/bridge) -"acX" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "acY" = ( @@ -1975,10 +1562,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/camera{ - c_tag = "Bridge Center"; - dir = 1 - }, /obj/item/storage/fancy/donut_box, /obj/item/clothing/mask/cigarette/cigar/havana{ pixel_x = -3 @@ -2018,20 +1601,14 @@ /obj/structure/cable/white{ icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /obj/machinery/door/airlock/command{ name = "Council Chambers"; req_access_txt = "19" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/command/bridge) "ade" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -2041,13 +1618,9 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "adf" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -2059,11 +1632,9 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 6 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "adg" = ( /obj/structure/closet/secure_closet/hop, @@ -2075,11 +1646,9 @@ icon_state = "2-4" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/command/heads_quarters/hop) "adh" = ( /obj/structure/cable/white{ @@ -2138,12 +1707,9 @@ /turf/open/floor/plasteel/white, /area/command/heads_quarters/hop) "adm" = ( -/obj/structure/sign/warning/securearea{ - pixel_x = 32; - pixel_y = -32 - }, -/turf/open/space/basic, -/area/space) +/obj/structure/girder, +/turf/open/floor/plating, +/area/engineering/storage/tech) "adn" = ( /turf/closed/wall, /area/cargo/storage) @@ -2250,26 +1816,13 @@ /turf/open/floor/plating, /area/command/heads_quarters/hos) "adD" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/structure/closet/secure_closet/hos, +/obj/item/gun/energy/e_gun/hos, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) "adE" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/structure/cable/white{ icon_state = "1-2" }, @@ -2283,7 +1836,7 @@ name = "Head of Security's Office"; req_access_txt = "58" }, -/turf/open/floor/plasteel, +/turf/open/floor/wood, /area/command/heads_quarters/hos) "adF" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, @@ -2312,7 +1865,6 @@ /turf/closed/wall, /area/command/heads_quarters/captain/private) "adI" = ( -/obj/structure/filingcabinet, /obj/structure/cable/white{ icon_state = "2-4" }, @@ -2324,6 +1876,7 @@ dir = 4; name = "command camera" }, +/obj/structure/closet/secure_closet/captains, /turf/open/floor/wood, /area/command/heads_quarters/captain/private) "adJ" = ( @@ -2336,16 +1889,10 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/item/kirbyplants{ - icon_state = "plant-22" - }, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/obj/machinery/camera{ - c_tag = "Captain's Quarters"; - dir = 1 - }, +/obj/structure/filingcabinet, /turf/open/floor/wood{ icon_state = "wood-broken" }, @@ -2396,11 +1943,9 @@ name = "Station Intercom"; pixel_x = 28 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 5 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "adO" = ( /obj/machinery/status_display/ai, @@ -2435,13 +1980,9 @@ /obj/structure/sign/nanotrasen{ pixel_x = -32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "adT" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -2450,11 +1991,9 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 6 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "adU" = ( /obj/structure/sign/warning/electricshock{ @@ -2475,10 +2014,6 @@ name = "Head of Personnel's Quarters"; req_access_txt = "57" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/command/heads_quarters/hop) "adW" = ( @@ -2743,19 +2278,15 @@ /area/command/heads_quarters/captain/private) "aew" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/command{ - name = "Captain's Quarters"; - req_access_txt = "20" - }, /obj/structure/cable/white{ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/command{ + name = "Captain's Quarters"; + req_access_txt = "20" }, -/turf/open/floor/plasteel, +/turf/open/floor/wood, /area/command/heads_quarters/captain/private) "aex" = ( /obj/structure/cable/white, @@ -2771,11 +2302,9 @@ /obj/machinery/light{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 5 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "aez" = ( /obj/structure/table/reinforced, @@ -2795,10 +2324,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "aeA" = ( @@ -2809,16 +2334,6 @@ uses = 10 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "aeB" = ( @@ -2834,10 +2349,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/structure/closet/crate/goldcrate, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "aeC" = ( @@ -2860,10 +2372,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/structure/closet/crate/silvercrate, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "aeE" = ( @@ -2880,16 +2389,6 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "aeF" = ( @@ -2910,12 +2409,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "aeG" = ( @@ -2926,13 +2419,9 @@ /obj/machinery/computer/security/telescreen/entertainment{ pixel_x = -32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "aeH" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -2941,11 +2430,9 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 6 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "aeI" = ( /obj/effect/spawner/structure/window/reinforced, @@ -2960,12 +2447,10 @@ "aeJ" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/bed/dogbed/ian, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /mob/living/simple_animal/pet/dog/corgi/Ian, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/command/heads_quarters/hop) "aeK" = ( /obj/structure/cable/white{ @@ -2975,31 +2460,19 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/command/heads_quarters/hop) "aeL" = ( /obj/machinery/photocopier, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/command/heads_quarters/hop) "aeM" = ( /obj/structure/filingcabinet/security, /obj/item/folder/documents, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/command/heads_quarters/hop) "aeN" = ( /obj/structure/table/wood, @@ -3017,11 +2490,7 @@ name = "Head of Personnel Quarter's APC"; pixel_y = 23 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/command/heads_quarters/hop) "aeO" = ( /obj/structure/table/wood, @@ -3038,10 +2507,9 @@ pixel_y = 24 }, /obj/machinery/recharger, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/corner{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/command/heads_quarters/hop) "aeP" = ( /obj/structure/cable/white{ @@ -3064,6 +2532,10 @@ pixel_x = 24; pixel_y = 24 }, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = -24 + }, /turf/open/floor/plasteel, /area/cargo/qm) "aeQ" = ( @@ -3075,10 +2547,6 @@ name = "Quartermaster"; req_access_txt = "41" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/cargo/qm) "aeR" = ( @@ -3087,13 +2555,15 @@ /turf/open/floor/plating, /area/cargo/qm) "aeS" = ( -/obj/structure/closet/crate, -/obj/effect/turf_decal/delivery, -/obj/item/toy/figure/cargotech, -/turf/open/floor/plasteel, -/area/cargo/storage) +/obj/machinery/camera{ + c_tag = "MiniSat External Southwest"; + dir = 8; + network = list("minisat"); + start_active = 1 + }, +/turf/open/floor/plating/asteroid/airless, +/area/asteroid/nearstation) "aeT" = ( -/obj/structure/closet/crate, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/cargo/storage) @@ -3124,16 +2594,6 @@ /turf/open/floor/plasteel, /area/cargo/storage) "aeW" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/structure/cable/white{ icon_state = "1-2" }, @@ -3179,25 +2639,13 @@ /turf/open/floor/plasteel, /area/cargo/storage) "afb" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /obj/machinery/suit_storage_unit/hos, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 9 + }, /area/command/heads_quarters/hos) "afc" = ( /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/structure/cable/white{ icon_state = "1-2" }, @@ -3274,10 +2722,6 @@ }, /obj/machinery/suit_storage_unit/captain, /obj/effect/turf_decal/stripes/end, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/captain/private) "afl" = ( @@ -3338,11 +2782,9 @@ dir = 8; name = "command camera" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 5 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "afq" = ( /obj/structure/table/reinforced, @@ -3368,13 +2810,7 @@ network = list("minisat"); start_active = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "afr" = ( @@ -3403,12 +2839,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "aft" = ( @@ -3424,13 +2854,9 @@ dir = 4; name = "command camera" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "afu" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -3443,11 +2869,9 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 6 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "afv" = ( /obj/machinery/door/firedoor, @@ -3457,23 +2881,17 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/machinery/door/airlock/command{ - name = "Head of Personnel's Office"; - req_access_txt = "57" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/command{ + name = "Head of Personnel's Office"; + req_access_txt = "57" }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/command/heads_quarters/hop) "afw" = ( /obj/structure/cable/white{ @@ -3541,13 +2959,9 @@ dir = 8; name = "command camera" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/command/heads_quarters/hop) "afB" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -3574,73 +2988,31 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/structure/cable/white{ icon_state = "1-2" }, /turf/open/floor/plasteel, /area/cargo/storage) "afE" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/cargo/storage) "afF" = ( /obj/effect/landmark/start/cargo_technician, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/conveyor_switch/oneway{ + dir = 8; + id = "cargounload" }, /turf/open/floor/plasteel, /area/cargo/storage) "afG" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/cargo/storage) "afH" = ( -/obj/machinery/conveyor_switch/oneway{ - dir = 8; - id = "cargounload" +/turf/open/floor/plating{ + icon_state = "panelscorched" }, -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/cargo/storage) +/area/maintenance/port/fore) "afI" = ( /obj/machinery/button/door{ id = "cargounload"; @@ -3671,17 +3043,13 @@ /area/cargo/storage) "afK" = ( /obj/machinery/door/firedoor, +/obj/structure/cable/white{ + icon_state = "1-2" + }, /obj/machinery/door/airlock/mining{ name = "Cargo Bay"; req_one_access_txt = "48;50" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/structure/cable/white{ - icon_state = "1-2" - }, /turf/open/floor/plasteel, /area/cargo/storage) "afL" = ( @@ -3737,12 +3105,6 @@ name = "Head of Security's Office Maintenance"; req_access_txt = "4" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /turf/open/floor/plating, /area/maintenance/fore) "afS" = ( @@ -3758,12 +3120,6 @@ /turf/open/floor/wood, /area/command/heads_quarters/hos) "afT" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/machinery/door/airlock/maintenance_hatch{ name = "Security Maintenance"; req_access_txt = "63" @@ -3786,30 +3142,20 @@ /area/maintenance/fore) "afW" = ( /obj/machinery/door/firedoor, +/obj/structure/cable/white{ + icon_state = "4-8" + }, /obj/machinery/door/airlock/command{ name = "Captain's Emergency Escape"; req_access_txt = "20" }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/maintenance/fore) "afX" = ( /obj/structure/cable/white{ icon_state = "4-8" }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/captain/private) "afY" = ( @@ -3874,23 +3220,17 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 10 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "agf" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 5 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "agg" = ( /obj/machinery/airalarm{ @@ -3919,25 +3259,11 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "agh" = ( /obj/machinery/computer/upload/ai, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "agi" = ( @@ -3946,16 +3272,6 @@ "agj" = ( /obj/machinery/computer/upload/borg, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "agk" = ( @@ -3969,23 +3285,13 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "agl" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "agm" = ( /obj/structure/cable/white{ @@ -4048,10 +3354,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/machinery/camera{ - c_tag = "Head of Personnel's Office"; - dir = 1 - }, /turf/open/floor/wood{ icon_state = "wood-broken5" }, @@ -4092,13 +3394,9 @@ pixel_y = -24; req_access_txt = "57" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/command/heads_quarters/hop) "agu" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -4122,16 +3420,6 @@ /turf/open/floor/plasteel, /area/cargo/storage) "agw" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/structure/cable/white{ icon_state = "1-4" }, @@ -4141,30 +3429,10 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/cargo/storage) "agy" = ( /obj/effect/landmark/start/cargo_technician, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/structure/cable/white{ icon_state = "4-8" }, @@ -4175,16 +3443,8 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/item/toy/figure/cargotech, +/obj/structure/closet/crate, /turf/open/floor/plasteel, /area/cargo/storage) "agA" = ( @@ -4297,11 +3557,9 @@ name = "Station Intercom"; pixel_x = -26 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) "agM" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -4334,10 +3592,6 @@ icon_state = "0-4" }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/captain/private) "agP" = ( @@ -4403,10 +3657,6 @@ /area/command/heads_quarters/captain/private) "agU" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/command{ - name = "Captain's Office"; - req_access_txt = "20" - }, /obj/structure/cable/white{ icon_state = "4-8" }, @@ -4419,13 +3669,11 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/machinery/door/airlock/command{ + name = "Captain's Office"; + req_access_txt = "20" }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/command/heads_quarters/captain/private) "agV" = ( /obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, @@ -4435,24 +3683,18 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 10 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "agW" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 5 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "agX" = ( /obj/structure/table/reinforced, @@ -4468,10 +3710,6 @@ dir = 4 }, /obj/item/aiModule/supplied/freeform, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "agY" = ( @@ -4488,16 +3726,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "aha" = ( @@ -4518,16 +3746,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "ahb" = ( @@ -4538,16 +3756,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "ahc" = ( @@ -4576,25 +3784,15 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "ahe" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "ahf" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -4604,11 +3802,9 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 6 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "ahg" = ( /obj/structure/cable/white, @@ -4672,16 +3868,6 @@ /turf/open/floor/plasteel, /area/cargo/storage) "ahm" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/cargo/storage) @@ -4689,16 +3875,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/cargo/storage) @@ -4779,15 +3955,12 @@ /turf/open/floor/plasteel, /area/cargo/storage) "ahu" = ( -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/airlock/maintenance_hatch{ name = "Security Maintenance"; req_access_txt = "63" }, -/obj/machinery/door/firedoor, /turf/open/floor/plasteel, /area/security/prison) "ahv" = ( @@ -4807,14 +3980,12 @@ /obj/machinery/light{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /obj/machinery/computer/card/minor/hos{ dir = 4 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/command/heads_quarters/hos) "ahy" = ( /obj/machinery/door/firedoor, @@ -4822,15 +3993,13 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/machinery/door/airlock/command{ name = "Head of Security's Office"; req_access_txt = "58" }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, /area/command/heads_quarters/hos) "ahz" = ( /obj/structure/reagent_dispensers/peppertank{ @@ -4913,15 +4082,10 @@ /obj/structure/sign/warning/securearea{ pixel_x = -32 }, -/obj/structure/closet/secure_closet/captains, /obj/effect/turf_decal/stripes/end{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/item/gun/energy/e_gun/hos, +/obj/machinery/vending/wardrobe/cap_wardrobe, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/captain/private) "ahI" = ( @@ -4972,8 +4136,10 @@ pixel_y = -24 }, /obj/structure/table/wood, -/obj/item/storage/fancy/donut_box, -/obj/item/lighter, +/obj/item/hand_tele{ + pixel_y = 9 + }, +/obj/item/storage/lockbox/medal, /turf/open/floor/wood, /area/command/heads_quarters/captain/private) "ahN" = ( @@ -4991,21 +4157,15 @@ pixel_x = 24 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 5 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "ahP" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 }, /obj/machinery/ore_silo, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "ahQ" = ( @@ -5023,16 +4183,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "ahT" = ( @@ -5069,12 +4219,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/nuke_storage) "ahW" = ( @@ -5082,16 +4226,6 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/structure/cable/white{ icon_state = "1-2" }, @@ -5106,11 +4240,9 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 6 }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "ahY" = ( /turf/closed/wall/r_wall, @@ -5246,6 +4378,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/machinery/conveyor_switch/oneway{ + id = "cargoload" + }, /turf/open/floor/plasteel, /area/cargo/storage) "aij" = ( @@ -5327,15 +4462,11 @@ /obj/structure/cable/white{ icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/airlock/security/glass{ name = "Security E.V.A. Storage"; req_access_txt = "63" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/security/brig) "ais" = ( @@ -5365,14 +4496,10 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/effect/turf_decal/stripes/end{ dir = 4 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/checker, /area/security/brig) "aiv" = ( /obj/item/cultivator, @@ -5392,35 +4519,27 @@ }, /area/maintenance/starboard/central) "aix" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/structure/cable/white{ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, /turf/open/floor/plating, /area/maintenance/fore) "aiy" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/command/glass{ - name = "Bridge Access"; - req_access_txt = "19" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/command/glass{ + name = "Bridge Access"; + req_access_txt = "19" }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/command/bridge) "aiz" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -5458,19 +4577,15 @@ /area/ai_monitored/command/nuke_storage) "aiC" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/command/glass{ - name = "Bridge Access"; - req_access_txt = "19" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/command/glass{ + name = "Bridge Access"; + req_access_txt = "19" }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/command/bridge) "aiD" = ( /obj/machinery/door/poddoor/shutters/preopen{ @@ -5503,16 +4618,12 @@ /area/hallway/primary/starboard/fore) "aiH" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/effect/turf_decal/stripes/line, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, /turf/open/floor/plating, /area/maintenance/starboard/fore) @@ -5665,14 +4776,10 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/effect/turf_decal/stripes/end{ dir = 8 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/checker, /area/security/brig) "aiS" = ( /obj/structure/sign/poster/official/do_not_question{ @@ -5710,6 +4817,7 @@ /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/effect/turf_decal/stripes/box, /turf/open/floor/plasteel, /area/security/brig) "aiW" = ( @@ -5724,12 +4832,6 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/security/brig) "aiY" = ( @@ -5839,18 +4941,12 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "aji" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "ajj" = ( @@ -5861,9 +4957,6 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "ajk" = ( @@ -5874,9 +4967,6 @@ pixel_y = 32 }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "ajl" = ( @@ -5887,9 +4977,6 @@ name = "Station Intercom"; pixel_y = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "ajm" = ( @@ -5902,9 +4989,6 @@ /obj/machinery/light{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "ajn" = ( @@ -5915,12 +4999,6 @@ dir = 4 }, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "ajo" = ( @@ -5950,9 +5028,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "ajr" = ( @@ -5962,9 +5037,6 @@ /obj/machinery/airalarm{ pixel_y = 23 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "ajs" = ( @@ -6016,9 +5088,6 @@ pixel_y = 24 }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "ajw" = ( @@ -6029,9 +5098,6 @@ name = "Station Intercom"; pixel_y = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "ajx" = ( @@ -6044,9 +5110,6 @@ /obj/machinery/camera{ c_tag = "Fore Primary Hallway 2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "ajy" = ( @@ -6080,12 +5143,6 @@ dir = 4 }, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "ajB" = ( @@ -6125,9 +5182,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "ajF" = ( @@ -6140,15 +5194,15 @@ /obj/machinery/camera{ c_tag = "Central Hallway North-East" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "ajG" = ( /turf/closed/wall/r_wall, /area/command/heads_quarters/cmo) "ajH" = ( +/obj/machinery/door/window/eastleft{ + req_access_txt = "48;50" + }, /obj/structure/plasticflaps/opaque, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, @@ -6183,16 +5237,6 @@ dir = 4 }, /obj/effect/landmark/start/cargo_technician, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/cargo/storage) "ajM" = ( @@ -6201,9 +5245,6 @@ name = "Cargo Office RC"; pixel_x = 32 }, -/obj/machinery/computer/bounty{ - dir = 8 - }, /obj/effect/turf_decal/tile/brown, /obj/effect/turf_decal/tile/brown{ dir = 4 @@ -6233,21 +5274,10 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, -/obj/effect/landmark/start/paramedic, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "ajO" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/effect/landmark/start/paramedic, /turf/open/floor/plasteel, /area/medical/medbay/zone3) @@ -6272,11 +5302,9 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 10 }, -/turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) "ajS" = ( /obj/structure/cable/white{ @@ -6345,17 +5373,14 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/security/brig) "ajX" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/sand/plating, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 5 + }, /turf/open/floor/plating, -/area/asteroid/nearstation) +/area/engineering/atmos) "ajY" = ( /obj/structure/cable/white{ icon_state = "4-8" @@ -6363,10 +5388,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/security/brig) "ajZ" = ( @@ -6424,7 +5445,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "ake" = ( @@ -6434,9 +5454,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -6447,9 +5464,6 @@ }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/machinery/light, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -6461,9 +5475,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/structure/chair, /turf/open/floor/plasteel{ heat_capacity = 1e+006 @@ -6477,9 +5488,6 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/structure/chair, /turf/open/floor/plasteel{ heat_capacity = 1e+006 @@ -6493,9 +5501,6 @@ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/structure/cable/white{ icon_state = "2-8" }, @@ -6514,9 +5519,6 @@ dir = 1; pixel_y = -22 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -6531,9 +5533,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -6618,12 +5617,6 @@ dir = 4 }, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "akr" = ( @@ -6640,9 +5633,6 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -6657,9 +5647,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -6777,7 +5764,6 @@ codes_txt = "patrol;next_patrol=4.2-HoP"; location = "4.1-BridgeEast" }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/fore) "akB" = ( @@ -6788,7 +5774,6 @@ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/fore) "akC" = ( @@ -6807,7 +5792,6 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/fore) "akD" = ( @@ -6899,7 +5883,6 @@ location = "4.2-HoP"; name = "Billy Herrington memorial navigation beacon" }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "akJ" = ( @@ -6910,9 +5893,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -6941,10 +5921,14 @@ /turf/open/floor/plasteel, /area/cargo/storage) "akM" = ( +/obj/item/chair, /obj/item/stack/ore/silver, /obj/item/stack/ore/iron, -/turf/open/floor/plating/asteroid, -/area/asteroid/nearstation) +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engineering/atmos) "akN" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 8 @@ -6952,9 +5936,14 @@ /turf/closed/wall/r_wall, /area/command/heads_quarters/ce) "akO" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/command/heads_quarters/ce) +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/obj/structure/lattice, +/obj/item/broken_bottle, +/obj/item/pickaxe, +/turf/open/floor/plating/asteroid/airless, +/area/asteroid/nearstation) "akP" = ( /obj/machinery/photocopier, /obj/effect/turf_decal/tile/brown{ @@ -6987,16 +5976,6 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/engineering/atmos) "akS" = ( @@ -7023,16 +6002,12 @@ /obj/structure/cable/white{ icon_state = "1-4" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, /obj/machinery/door/airlock/security{ name = "Armoury"; req_access_txt = "3" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plasteel, /area/security/brig) "akV" = ( @@ -7086,12 +6061,6 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/security/brig) "akZ" = ( @@ -7125,9 +6094,6 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "ald" = ( @@ -7174,10 +6140,6 @@ name = "Teleport Access"; req_access_txt = "17" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/command/teleporter) "alk" = ( @@ -7300,10 +6262,6 @@ name = "E.V.A. Storage"; req_access_txt = "18" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/ai_monitored/command/storage/eva) "alx" = ( @@ -7320,9 +6278,6 @@ /area/ai_monitored/command/storage/eva) "aly" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "alz" = ( @@ -7370,32 +6325,12 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/cargo/storage) "alD" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/cargo/storage) "alE" = ( @@ -7414,7 +6349,10 @@ c_tag = "Chief Engineer's Office"; network = list("ss13","engine") }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 10 + }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) "alF" = ( @@ -7468,18 +6406,12 @@ /area/security/brig) "alK" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security/glass{ - name = "Security Office"; - req_access_txt = "63" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/security/glass{ + name = "Security Office"; + req_access_txt = "63" }, /turf/open/floor/plasteel, /area/security/brig) @@ -7497,10 +6429,6 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/security/brig) "alN" = ( @@ -7555,7 +6483,6 @@ id = "brig2"; pixel_y = 26 }, -/obj/structure/chair, /obj/structure/cable/white{ icon_state = "2-4" }, @@ -7572,6 +6499,8 @@ /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/structure/bed, +/obj/item/bedsheet/blue, /turf/open/floor/plasteel, /area/security/brig) "alR" = ( @@ -7594,9 +6523,6 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "alT" = ( @@ -7612,15 +6538,18 @@ /turf/open/floor/wood, /area/service/lawoffice) "alU" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, /turf/open/floor/wood, /area/service/lawoffice) "alV" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, /obj/structure/window/reinforced/spawner/east, /obj/structure/chair, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, /area/service/lawoffice) "alW" = ( @@ -7631,10 +6560,13 @@ /area/commons/toilet/restrooms) "alX" = ( /obj/machinery/vending/wardrobe/law_wardrobe, +/obj/machinery/camera{ + c_tag = "Law Office"; + dir = 8 + }, /turf/open/floor/wood, /area/service/lawoffice) "alY" = ( -/obj/machinery/shieldwallgen, /obj/machinery/button/door{ id = "teleportershutters"; name = "Teleporter Shutters"; @@ -7642,10 +6574,7 @@ req_access_txt = "19" }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, +/obj/machinery/shieldwallgen, /turf/open/floor/plasteel/dark, /area/command/teleporter) "alZ" = ( @@ -7677,7 +6606,6 @@ /turf/open/floor/plasteel, /area/command/teleporter) "amc" = ( -/obj/machinery/shieldwallgen, /obj/structure/cable/white{ icon_state = "4-8" }, @@ -7685,12 +6613,7 @@ c_tag = "Teleporter" }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/shieldwallgen, /turf/open/floor/plasteel/dark, /area/command/teleporter) "amd" = ( @@ -7716,19 +6639,9 @@ icon_state = "1-2" }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/hallway/primary/fore) "amg" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -7739,16 +6652,6 @@ icon_state = "1-2" }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "ami" = ( @@ -7756,22 +6659,7 @@ /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/hallway/primary/central) -"amj" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) "amk" = ( -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "aml" = ( @@ -7783,16 +6671,7 @@ icon_state = "1-2" }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/hallway/primary/fore) "amm" = ( /obj/structure/cable/white{ @@ -7818,10 +6697,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/storage/eva) "amp" = ( @@ -7865,12 +6740,6 @@ pixel_x = 26; req_access_txt = "19" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/storage/eva) "amt" = ( @@ -7882,9 +6751,6 @@ name = "Station Intercom"; pixel_x = -26 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "amu" = ( @@ -7900,9 +6766,6 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "amv" = ( -/obj/machinery/computer/bounty{ - dir = 4 - }, /obj/effect/turf_decal/tile/brown{ dir = 1 }, @@ -7910,6 +6773,9 @@ /obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/machinery/computer/bounty{ + dir = 4 + }, /turf/open/floor/plasteel, /area/cargo/storage) "amw" = ( @@ -8039,7 +6905,9 @@ /obj/structure/sign/warning/nosmoking{ pixel_y = 32 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "amI" = ( /obj/machinery/holopad, @@ -8063,12 +6931,6 @@ c_tag = "Security - Central"; dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/security/brig) "amL" = ( @@ -8089,12 +6951,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/security/brig) "amN" = ( @@ -8104,10 +6960,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/machinery/door/window/brigdoor/security/cell/westright{ - id = "brig2"; - name = "Cell 2" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -8117,6 +6969,10 @@ /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/machinery/door/window/brigdoor/security/cell/eastright{ + id = "Cell 1"; + name = "Cell 1" + }, /turf/open/floor/plasteel, /area/security/brig) "amO" = ( @@ -8134,6 +6990,7 @@ /obj/structure/window/reinforced/spawner, /obj/item/clipboard, /obj/item/folder/red, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, /area/service/lawoffice) "amR" = ( @@ -8143,14 +7000,10 @@ /turf/open/floor/wood, /area/service/lawoffice) "amS" = ( -/obj/machinery/camera{ - c_tag = "Law Office"; - dir = 8 - }, /obj/machinery/power/apc{ - areastring = "/area/commons/toilet/restrooms"; + areastring = "/area/service/lawoffice"; dir = 4; - name = "Restrooms APC"; + name = "Law Office APC"; pixel_x = 24 }, /obj/structure/cable/white{ @@ -8162,7 +7015,6 @@ /turf/open/floor/wood, /area/service/lawoffice) "amT" = ( -/obj/structure/table/reinforced, /obj/item/stack/cable_coil/white, /obj/item/stack/packageWrap, /obj/item/hand_labeler, @@ -8175,10 +7027,7 @@ dir = 4; name = "command camera" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, +/obj/structure/table/reinforced, /turf/open/floor/plasteel/dark, /area/command/teleporter) "amU" = ( @@ -8220,12 +7069,6 @@ /area/command/teleporter) "amX" = ( /obj/machinery/teleport/hub, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/teleporter) "amY" = ( @@ -8241,34 +7084,19 @@ icon_state = "1-8" }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/hallway/primary/fore) "ana" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, /area/hallway/primary/fore) -"anb" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) "anc" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/fore) "and" = ( @@ -8280,13 +7108,7 @@ icon_state = "1-4" }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/hallway/primary/fore) "ane" = ( /obj/structure/sign/warning/electricshock, @@ -8297,7 +7119,9 @@ /obj/effect/turf_decal/stripes/end{ dir = 8 }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/ai_monitored/command/storage/eva) "ang" = ( /obj/structure/cable/white{ @@ -8337,15 +7161,13 @@ /obj/effect/turf_decal/stripes/end{ dir = 4 }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, /area/ai_monitored/command/storage/eva) "ank" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "anl" = ( @@ -8354,10 +7176,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "anm" = ( @@ -8380,17 +7198,13 @@ /area/cargo/storage) "ano" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/mining/glass{ - name = "Cargo Office"; - req_access_txt = "48;50" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/mining/glass{ + name = "Cargo Office"; + req_access_txt = "48;50" }, /turf/open/floor/plasteel, /area/cargo/storage) @@ -8407,12 +7221,16 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, /area/cargo/miningdock) "anr" = ( /obj/machinery/mineral/equipment_vendor, /obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, /area/cargo/miningdock) "ans" = ( /obj/machinery/power/apc{ @@ -8431,7 +7249,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 6 }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, /area/cargo/miningdock) "ant" = ( /obj/effect/spawner/structure/window/reinforced, @@ -8439,19 +7259,17 @@ /turf/open/floor/plating, /area/cargo/miningdock) "anu" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/command/glass{ - name = "Chief Engineer"; - req_access_txt = "56" - }, -/obj/effect/turf_decal/stripes/line{ +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 }, -/turf/open/floor/plasteel, -/area/command/heads_quarters/ce) +/turf/open/floor/plasteel/dark/corner{ + dir = 4 + }, +/area/engineering/atmos) "anv" = ( /obj/effect/turf_decal/stripes/end{ dir = 8 @@ -8460,6 +7278,14 @@ dir = 1 }, /obj/effect/turf_decal/tile/yellow, +/obj/machinery/atmospherics/pipe/simple/orange/visible, +/obj/machinery/button/door{ + id = "engstorage"; + name = "Engineering Secure Storage Control"; + pixel_x = -25; + pixel_y = 7; + req_access_txt = "10" + }, /turf/open/floor/plasteel, /area/command/heads_quarters/ce) "anw" = ( @@ -8492,16 +7318,6 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/security/brig) "anA" = ( @@ -8523,6 +7339,10 @@ name = "Chief Engineer RC"; pixel_x = 32 }, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = -17 + }, /turf/open/floor/plasteel, /area/command/heads_quarters/ce) "anB" = ( @@ -8560,10 +7380,6 @@ "anD" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/security/brig) "anE" = ( @@ -8607,10 +7423,6 @@ "anH" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "anI" = ( @@ -8619,10 +7431,6 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "anJ" = ( @@ -8652,6 +7460,11 @@ pixel_x = -26 }, /obj/item/rcl/pre_loaded, +/obj/item/clothing/glasses/meson/gar, +/obj/machinery/atmospherics/pipe/simple/orange/visible, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) "anL" = ( @@ -8668,10 +7481,6 @@ }, /obj/structure/closet/crate/engineering, /obj/item/hand_tele, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/teleporter) "anM" = ( @@ -8687,7 +7496,6 @@ /turf/open/floor/plasteel, /area/command/teleporter) "anO" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line{ dir = 8 }, @@ -8696,22 +7504,19 @@ dir = 1 }, /obj/effect/turf_decal/tile/yellow, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/command/heads_quarters/ce) "anP" = ( -/obj/machinery/teleport/station, /obj/machinery/light{ dir = 4 }, /obj/machinery/status_display{ pixel_x = 32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/teleport/station, /turf/open/floor/plasteel/dark, /area/command/teleporter) "anQ" = ( @@ -8721,48 +7526,33 @@ "anR" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/public/glass{ - name = "Atrium" - }, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/door/airlock/public/glass{ + name = "Atrium" + }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "anS" = ( /obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, /obj/machinery/door/airlock/public/glass{ name = "Atrium" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plasteel, /area/hallway/primary/fore) "anT" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, /obj/machinery/door/airlock/public/glass{ name = "Atrium" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plasteel, /area/hallway/primary/fore) "anU" = ( -/obj/structure/closet/crate/rcd{ - pixel_y = 4 - }, /obj/machinery/door/window/northleft{ dir = 4; name = "RCD Storage"; @@ -8780,15 +7570,8 @@ /obj/machinery/status_display{ pixel_x = -32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/structure/closet/crate/rcd{ + pixel_y = 4 }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/storage/eva) @@ -8833,9 +7616,6 @@ dir = 4; pixel_x = -24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "aoa" = ( @@ -8859,12 +7639,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "aoc" = ( @@ -9033,6 +7807,9 @@ dir = 4; pixel_x = -23 }, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 5 + }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) "aop" = ( @@ -9054,6 +7831,9 @@ dir = 1; pixel_y = -24 }, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/command/heads_quarters/ce) "aoq" = ( @@ -9131,23 +7911,17 @@ /area/security/brig) "aox" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security/glass{ - id_tag = "secinterior"; - name = "Brig"; - req_access_txt = "63" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, +/obj/machinery/door/airlock/security/glass{ + id_tag = "secinterior"; + name = "Brig"; + req_access_txt = "63" + }, /turf/open/floor/plasteel, /area/security/brig) "aoy" = ( @@ -9174,23 +7948,17 @@ /area/security/brig) "aoA" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security/glass{ - id_tag = "secexterior"; - name = "Brig"; - req_access_txt = "63" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, +/obj/machinery/door/airlock/security/glass{ + id_tag = "secexterior"; + name = "Brig"; + req_access_txt = "63" + }, /turf/open/floor/plasteel, /area/security/brig) "aoB" = ( @@ -9213,7 +7981,7 @@ /obj/structure/table/wood, /obj/structure/window/reinforced/spawner/west, /obj/item/folder/blue, -/turf/open/floor/carpet/green/airless, +/turf/open/floor/carpet/green, /area/service/lawoffice) "aoE" = ( /obj/machinery/airalarm{ @@ -9228,7 +7996,6 @@ /turf/open/floor/wood, /area/service/lawoffice) "aoF" = ( -/obj/structure/table/reinforced, /obj/item/stock_parts/cell/high, /obj/item/stock_parts/cell/high, /obj/machinery/cell_charger, @@ -9236,10 +8003,7 @@ dir = 4; pixel_x = -22 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, +/obj/structure/table/reinforced, /turf/open/floor/plasteel/dark, /area/command/teleporter) "aoG" = ( @@ -9260,16 +8024,10 @@ /turf/open/floor/plasteel, /area/command/teleporter) "aoI" = ( -/obj/machinery/computer/teleporter{ - dir = 8 - }, /obj/machinery/newscaster{ pixel_x = 32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/computer/teleporter{ dir = 8 }, /turf/open/floor/plasteel/dark, @@ -9278,6 +8036,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/obj/machinery/space_heater, /turf/open/floor/plasteel, /area/maintenance/port/central) "aoK" = ( @@ -9327,6 +8086,9 @@ /obj/item/stack/cable_coil/white, /obj/item/hand_labeler, /obj/item/hand_labeler_refill, +/obj/machinery/status_display/ai{ + pixel_x = -32 + }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aoO" = ( @@ -9339,9 +8101,6 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, @@ -9351,25 +8110,12 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aoQ" = ( /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, @@ -9390,22 +8136,16 @@ /turf/open/floor/plasteel, /area/service/bar/atrium) "aoS" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, /turf/open/floor/plating, /area/maintenance/starboard/central) "aoU" = ( @@ -9437,7 +8177,9 @@ /obj/effect/turf_decal/stripes/end{ dir = 8 }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/ai_monitored/command/storage/eva) "aoX" = ( /obj/structure/tank_dispenser/oxygen, @@ -9452,7 +8194,9 @@ /obj/effect/turf_decal/stripes/end{ dir = 4 }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, /area/ai_monitored/command/storage/eva) "aoZ" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -9461,9 +8205,6 @@ /obj/machinery/light{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -9497,12 +8238,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "apc" = ( @@ -9581,21 +8316,15 @@ /area/hallway/primary/starboard/fore) "api" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/mining{ - name = "Mining Dock"; - req_access_txt = "48" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/mining{ + name = "Mining Dock"; + req_access_txt = "48" }, /turf/open/floor/plasteel, /area/cargo/miningdock) @@ -9662,9 +8391,6 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 6 }, @@ -9672,6 +8398,9 @@ dir = 1 }, /obj/effect/turf_decal/tile/yellow, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/command/heads_quarters/ce) "app" = ( @@ -9690,9 +8419,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/tile/neutral{ dir = 4 @@ -9708,47 +8434,39 @@ pixel_x = 8; pixel_y = 32 }, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/machinery/atmospherics/pipe/simple/orange/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/ce) "apr" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/machinery/door/firedoor, /obj/structure/cable/white{ icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, /obj/machinery/door/airlock/command/glass{ name = "Chief Engineer"; req_access_txt = "56" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /turf/open/floor/plasteel, /area/command/heads_quarters/ce) "aps" = ( /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/machinery/button/door{ - id = "engstorage"; - name = "Engineering Secure Storage Control"; - pixel_y = 24; - req_access_txt = "10" - }, /obj/effect/turf_decal/stripes/line{ dir = 9 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 }, /turf/open/floor/engine, /area/engineering/main) @@ -9759,16 +8477,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/engineering/main) "apu" = ( @@ -9779,9 +8487,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /obj/structure/sign/departments/custodian{ pixel_x = 32; pixel_y = 32 @@ -9818,18 +8523,14 @@ /obj/structure/cable/white{ icon_state = "1-4" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, /obj/machinery/door/airlock/security/glass{ name = "Security Office"; req_access_txt = "63" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, /turf/open/floor/plasteel, /area/security/brig) "apy" = ( @@ -9855,10 +8556,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/security/brig) "apA" = ( @@ -9896,26 +8593,20 @@ /area/security/brig) "apC" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security/glass{ - id_tag = "secinterior"; - name = "Brig"; - req_access_txt = "63" - }, /obj/structure/cable/white{ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, +/obj/machinery/door/airlock/security/glass{ + id_tag = "secinterior"; + name = "Brig"; + req_access_txt = "63" + }, /turf/open/floor/plasteel, /area/security/brig) "apD" = ( @@ -9942,26 +8633,20 @@ /area/security/brig) "apF" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security/glass{ - id_tag = "secexterior"; - name = "Brig"; - req_access_txt = "63" - }, /obj/structure/cable/white{ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, +/obj/machinery/door/airlock/security/glass{ + id_tag = "secexterior"; + name = "Brig"; + req_access_txt = "63" + }, /turf/open/floor/plasteel, /area/security/brig) "apG" = ( @@ -9995,9 +8680,6 @@ name = "Station Intercom"; pixel_x = 26 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "apI" = ( @@ -10015,10 +8697,6 @@ pixel_y = -28 }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/teleporter) "apL" = ( @@ -10055,7 +8733,6 @@ /turf/open/floor/plasteel, /area/command/teleporter) "apO" = ( -/obj/machinery/shieldwallgen, /obj/item/radio/intercom{ name = "Station Intercom"; pixel_x = 28 @@ -10064,12 +8741,7 @@ pixel_y = -32 }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/shieldwallgen, /turf/open/floor/plasteel/dark, /area/command/teleporter) "apP" = ( @@ -10107,21 +8779,15 @@ /turf/open/floor/plasteel/dark, /area/security/brig) "apS" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, /turf/open/floor/plasteel, /area/maintenance/port/central) @@ -10155,9 +8821,6 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -10166,16 +8829,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "apW" = ( @@ -10183,18 +8836,18 @@ /obj/effect/turf_decal/loading_area{ dir = 8 }, -/obj/effect/turf_decal/stripes/corner, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/service/bar/atrium) "apX" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/box, /obj/machinery/rnd/production/techfab/department/service, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/obj/machinery/status_display{ + pixel_x = 32 + }, /turf/open/floor/plasteel, /area/service/bar/atrium) "apY" = ( @@ -10232,7 +8885,6 @@ /turf/open/floor/plasteel, /area/maintenance/starboard/central) "aqc" = ( -/obj/structure/table/reinforced, /obj/item/tank/jetpack/carbondioxide{ pixel_x = 3; pixel_y = 3 @@ -10246,10 +8898,7 @@ /obj/structure/sign/warning/nosmoking{ pixel_y = -32 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, +/obj/structure/table/reinforced, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/storage/eva) "aqd" = ( @@ -10289,7 +8938,6 @@ /turf/open/floor/plasteel, /area/ai_monitored/command/storage/eva) "aqg" = ( -/obj/structure/table/reinforced, /obj/item/stack/sheet/plasteel{ amount = 15 }, @@ -10309,19 +8957,11 @@ /obj/structure/extinguisher_cabinet{ pixel_y = -28 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/structure/table/reinforced, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/storage/eva) "aqh" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -10368,14 +9008,12 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "aqn" = ( -/obj/structure/chair{ - dir = 1 - }, /obj/machinery/airalarm{ dir = 1; pixel_y = -22 }, /obj/effect/turf_decal/bot, +/obj/machinery/piratepad/civilian, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "aqo" = ( @@ -10505,6 +9143,7 @@ dir = 1 }, /obj/effect/turf_decal/stripes/line, +/obj/structure/closet/secure_closet/contraband/armory, /turf/open/floor/plasteel, /area/security/brig) "aqC" = ( @@ -10548,6 +9187,14 @@ /obj/effect/turf_decal/stripes/corner{ dir = 4 }, +/mob/living/simple_animal/bot/secbot{ + arrest_type = 1; + health = 45; + icon_state = "secbot1"; + idcheck = 1; + name = "Sergeant-at-Armsky"; + weaponscheck = 1 + }, /turf/open/floor/plasteel, /area/security/brig) "aqH" = ( @@ -10576,28 +9223,16 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/security/brig) "aqJ" = ( /obj/structure/cable/white{ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/security/brig) "aqK" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -10605,17 +9240,9 @@ dir = 4 }, /obj/machinery/vending/wardrobe/sec_wardrobe, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/corner{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/security/brig) "aqL" = ( /obj/structure/cable/white{ @@ -10655,12 +9282,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/security/brig) "aqP" = ( @@ -10720,9 +9341,6 @@ /obj/machinery/light{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "aqT" = ( @@ -10813,46 +9431,34 @@ "arc" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/public/glass{ - name = "Atrium" - }, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 }, -/turf/open/floor/plasteel, +/obj/machinery/door/airlock/public/glass{ + name = "Atrium" + }, +/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "ard" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ name = "Atrium" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "are" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/public/glass{ - name = "Atrium" - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 }, -/turf/open/floor/plasteel, +/obj/machinery/door/airlock/public/glass{ + name = "Atrium" + }, +/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "arf" = ( /obj/effect/spawner/structure/window/reinforced, @@ -10878,9 +9484,6 @@ /obj/structure/extinguisher_cabinet{ pixel_x = -24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -10890,7 +9493,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "ark" = ( @@ -10963,15 +9565,13 @@ /turf/closed/wall, /area/maintenance/port/fore) "arp" = ( -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/machinery/door/airlock/maintenance_hatch{ name = "Maintenance Hatch"; req_access_txt = "12" }, -/turf/open/floor/plasteel, +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, /area/maintenance/port/fore) "arq" = ( /turf/closed/wall/r_wall, @@ -10981,16 +9581,6 @@ dir = 8 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "ars" = ( @@ -11013,12 +9603,6 @@ /obj/machinery/newscaster/security_unit{ pixel_x = -32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /obj/structure/table/reinforced, /obj/item/grenade/barrier{ pixel_x = -3; @@ -11037,53 +9621,25 @@ c_tag = "Brig Control Room"; dir = 4 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/security/brig) "arv" = ( /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 9 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "arw" = ( /obj/machinery/computer/atmos_control/tank/mix_tank, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "arx" = ( /obj/machinery/atmospherics/pipe/simple/yellow/visible, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "ary" = ( @@ -11091,16 +9647,6 @@ name = "Mix to Distro" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "arz" = ( @@ -11115,16 +9661,6 @@ name = "Station Intercom"; pixel_y = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "arA" = ( @@ -11137,7 +9673,7 @@ /obj/structure/sign/poster/random{ pixel_y = 32 }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/engineering/atmos) "arB" = ( /obj/effect/turf_decal/tile/red{ @@ -11160,11 +9696,9 @@ dir = 1 }, /obj/structure/closet/l3closet/security, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/security/brig) "arE" = ( /obj/structure/cable/white{ @@ -11174,58 +9708,32 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/security/brig) "arF" = ( /obj/structure/cable/white{ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/security/brig) "arG" = ( /obj/machinery/door/firedoor, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/machinery/door/airlock/security/glass{ - name = "Gear Room"; - req_access_txt = "63" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, /obj/structure/cable/white{ icon_state = "1-4" }, /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/security/glass{ + name = "Gear Room"; + req_access_txt = "63" }, /turf/open/floor/plasteel, /area/security/brig) @@ -11255,10 +9763,6 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/security/brig) "arJ" = ( @@ -11282,10 +9786,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/security/brig) "arL" = ( @@ -11296,18 +9796,12 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/machinery/door/airlock/security/glass{ - name = "Security Desk"; - req_access_txt = "63" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/security/glass{ + name = "Security Desk"; + req_access_txt = "63" }, /turf/open/floor/plasteel, /area/security/brig) @@ -11324,17 +9818,9 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/security/brig) "arN" = ( /obj/machinery/button/door{ @@ -11374,16 +9860,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/security/brig) "arO" = ( @@ -11484,21 +9960,15 @@ /turf/open/floor/plating, /area/maintenance/port/central) "arW" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/structure/cable/white{ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, /turf/open/floor/plating, /area/maintenance/port/central) @@ -11586,11 +10056,9 @@ c_tag = "Central Diner 3"; dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 9 }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "ase" = ( /obj/item/kirbyplants{ @@ -11673,13 +10141,9 @@ /obj/machinery/newscaster{ pixel_x = 32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 5 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "ask" = ( /obj/structure/cable/white{ @@ -11699,19 +10163,6 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/central) -"asm" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/turf/open/floor/plasteel, -/area/maintenance/port/fore) "asn" = ( /obj/machinery/airalarm/unlocked{ dir = 4; @@ -11724,12 +10175,6 @@ /obj/machinery/light{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /obj/structure/table/reinforced, /obj/item/storage/box/chemimp{ pixel_x = 6 @@ -11738,7 +10183,9 @@ pixel_x = -3 }, /obj/item/storage/lockbox/loyalty, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/security/brig) "aso" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -11778,7 +10225,6 @@ /turf/open/floor/plasteel, /area/maintenance/starboard) "ass" = ( -/obj/machinery/mineral/mint, /obj/structure/sign/poster/official/random{ pixel_y = 32 }, @@ -11814,10 +10260,10 @@ /obj/machinery/atmospherics/pipe/manifold/yellow/visible, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/yellow{ - dir = 4 + dir = 1 }, /turf/open/floor/plasteel/dark/corner{ - dir = 1 + dir = 4 }, /area/engineering/atmos) "asx" = ( @@ -11836,12 +10282,6 @@ name = "Security RC"; pixel_x = -32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /obj/structure/table/reinforced, /obj/item/storage/box/teargas{ pixel_x = 3; @@ -11852,7 +10292,9 @@ pixel_x = -3; pixel_y = -3 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/security/brig) "asA" = ( /obj/structure/reagent_dispensers/fueltank, @@ -11887,10 +10329,10 @@ /obj/machinery/meter, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/yellow{ - dir = 4 + dir = 1 }, /turf/open/floor/plasteel/dark/corner{ - dir = 1 + dir = 4 }, /area/engineering/atmos) "asD" = ( @@ -11902,37 +10344,26 @@ }, /turf/open/floor/plasteel, /area/maintenance/port/fore) -"asE" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/maintenance/port/fore) "asF" = ( /obj/machinery/atmospherics/pipe/simple/supply/visible{ dir = 5 }, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/yellow{ - dir = 4 + dir = 1 }, /turf/open/floor/plasteel/dark/corner{ - dir = 1 + dir = 4 }, /area/engineering/atmos) "asG" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/manifold4w/supply/visible, /obj/effect/turf_decal/tile/yellow{ - dir = 4 + dir = 1 }, /turf/open/floor/plasteel/dark/corner{ - dir = 1 + dir = 4 }, /area/engineering/atmos) "asH" = ( @@ -11947,16 +10378,6 @@ c_tag = "Atmospherics North"; network = list("ss13","engine") }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "asI" = ( @@ -11973,10 +10394,9 @@ pixel_y = -32 }, /obj/structure/closet/secure_closet/security/sec, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 10 }, -/turf/open/floor/plasteel/dark, /area/security/brig) "asK" = ( /obj/structure/rack, @@ -12010,13 +10430,7 @@ c_tag = "Security - Gear Room"; dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/security/brig) "asL" = ( /obj/structure/closet/secure_closet/security/sec, @@ -12024,13 +10438,7 @@ dir = 1; pixel_y = -26 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/security/brig) "asM" = ( /obj/structure/cable/white, @@ -12134,13 +10542,9 @@ c_tag = "Security - Front Desk"; dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 6 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, /area/security/brig) "asS" = ( /obj/machinery/computer/secure_data{ @@ -12156,12 +10560,6 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/security/brig) "asT" = ( @@ -12174,27 +10572,18 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "asU" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/engineering/glass{ - name = "Primary Tool Storage" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/engineering/glass{ + name = "Primary Tool Storage" }, /turf/open/floor/plasteel, /area/commons/storage/primary) @@ -12320,10 +10709,6 @@ /turf/closed/wall, /area/service/theater) "atg" = ( -/obj/machinery/door/airlock{ - name = "Theatre Backstage"; - req_access_txt = "46" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" @@ -12331,11 +10716,11 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock{ + name = "Theatre Backstage"; + req_access_txt = "46" }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/maintenance/port/central) "ath" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -12348,14 +10733,9 @@ /obj/machinery/light{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "atj" = ( /obj/machinery/vending/coffee, @@ -12366,14 +10746,9 @@ /obj/machinery/light{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "atk" = ( /obj/effect/spawner/structure/window/reinforced/tinted, @@ -12397,25 +10772,6 @@ }, /turf/open/floor/plasteel/white/corner, /area/hallway/primary/starboard/fore) -"atq" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/maintenance/starboard) "atr" = ( /obj/structure/table/wood, /obj/item/storage/secure/briefcase, @@ -12490,9 +10846,6 @@ /turf/open/floor/engine/n2, /area/engineering/atmos) "aty" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, /obj/machinery/atmospherics/components/binary/pump{ dir = 1; name = "Oxygen to Pure" @@ -12505,15 +10858,13 @@ /area/security/detectives_office) "atA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/machinery/door/airlock/security{ name = "Detective's Office"; req_access_txt = "4" }, -/turf/open/floor/plasteel, +/turf/open/floor/wood{ + icon_state = "wood-broken" + }, /area/security/detectives_office) "atB" = ( /obj/machinery/portable_atmospherics/canister/air, @@ -12613,10 +10964,10 @@ /obj/item/clothing/suit/hazardvest, /obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas, -/obj/effect/turf_decal/tile/yellow{ +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel/dark/corner{ dir = 4 }, -/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "atJ" = ( /turf/open/floor/wood, @@ -12633,17 +10984,13 @@ }, /area/maintenance/port/fore) "atL" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Security Maintenance"; - req_access_txt = "63" - }, /obj/structure/cable/white{ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Security Maintenance"; + req_access_txt = "63" }, /turf/open/floor/plasteel, /area/security/brig) @@ -12654,9 +11001,6 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "atN" = ( @@ -12667,24 +11011,15 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "atO" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/engineering/glass{ - name = "Primary Tool Storage" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/engineering/glass{ + name = "Primary Tool Storage" }, /turf/open/floor/plasteel, /area/commons/storage/primary) @@ -12860,16 +11195,6 @@ pixel_y = 3 }, /obj/item/camera_film, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/theater) "atY" = ( @@ -12907,11 +11232,9 @@ /area/service/theater) "aub" = ( /obj/machinery/vending/cigarette, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 9 }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "auc" = ( /obj/item/reagent_containers/food/condiment/saltshaker{ @@ -12921,33 +11244,13 @@ /obj/item/reagent_containers/food/condiment/peppermill{ pixel_x = -8 }, -/obj/structure/table/wood, /obj/item/kitchen/fork, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, +/obj/structure/table/wood, /turf/open/floor/plasteel, /area/service/bar/atrium) "aud" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aue" = ( @@ -12971,17 +11274,9 @@ pixel_y = 3 }, /obj/item/lighter, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "aug" = ( /obj/structure/sign/barsign{ @@ -13010,17 +11305,9 @@ c_tag = "Bar Backroom"; dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "auk" = ( /obj/structure/sink/kitchen{ @@ -13029,16 +11316,6 @@ pixel_y = 28 }, /obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/bar/atrium) "aul" = ( @@ -13056,17 +11333,9 @@ pixel_x = 26 }, /obj/structure/closet, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "aun" = ( /obj/effect/landmark/blobstart, @@ -13083,9 +11352,6 @@ /obj/machinery/status_display{ pixel_x = -32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -13149,11 +11415,14 @@ /turf/open/floor/wood, /area/security/detectives_office) "auv" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 10 +/obj/structure/chair{ + dir = 4 }, -/turf/open/floor/plasteel, -/area/engineering/atmos) +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/wood, +/area/service/lawoffice) "auw" = ( /obj/machinery/atmospherics/components/binary/pump{ name = "Pure to Port" @@ -13188,21 +11457,17 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/firedoor, +/obj/structure/cable/white{ + icon_state = "4-8" }, /obj/machinery/door/airlock/security{ name = "Detective's Office"; req_access_txt = "4" }, -/obj/machinery/door/firedoor, -/obj/structure/cable/white{ - icon_state = "4-8" +/turf/open/floor/wood{ + icon_state = "wood-broken7" }, -/turf/open/floor/plasteel, /area/security/detectives_office) "auA" = ( /obj/effect/turf_decal/stripes/line{ @@ -13229,10 +11494,10 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/yellow{ +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel/dark/corner{ dir = 4 }, -/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "auC" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -13335,18 +11600,12 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, /turf/open/floor/plasteel, /area/maintenance/port/fore) @@ -13358,11 +11617,9 @@ dir = 4 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/port) "auO" = ( /obj/structure/cable/white{ @@ -13380,9 +11637,6 @@ /obj/machinery/camera{ c_tag = "Port Hallway 2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "auP" = ( @@ -13392,9 +11646,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "auQ" = ( @@ -13404,9 +11655,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "auR" = ( @@ -13417,9 +11665,6 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "auS" = ( @@ -13429,9 +11674,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "auT" = ( @@ -13494,16 +11736,6 @@ "ava" = ( /obj/structure/table/wood, /obj/item/instrument/guitar, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/theater) "avb" = ( @@ -13538,11 +11770,9 @@ /obj/structure/table/wood, /obj/item/clothing/head/fedora, /obj/item/clothing/mask/cigarette/pipe, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "avf" = ( /obj/structure/chair/stool, @@ -13552,16 +11782,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "avg" = ( @@ -13570,16 +11790,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "avh" = ( @@ -13588,16 +11798,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "avi" = ( @@ -13638,33 +11838,15 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "avl" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/bar/atrium) "avm" = ( @@ -13690,7 +11872,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, /area/service/bar/atrium) "avp" = ( /obj/effect/landmark/start/bartender, @@ -13698,16 +11882,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/bar/atrium) "avq" = ( @@ -13718,20 +11892,12 @@ dir = 8; pixel_x = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/service/bar/atrium) "avs" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -13746,9 +11912,6 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -13775,11 +11938,9 @@ /obj/machinery/airalarm{ pixel_y = 23 }, -/obj/effect/turf_decal/bot, /turf/open/floor/plasteel/freezer, /area/commons/toilet/restrooms) "avx" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, /obj/machinery/computer/atmos_control/tank/oxygen_tank{ dir = 1 }, @@ -13787,34 +11948,18 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/obj/machinery/atmospherics/pipe/layer_manifold, +/turf/open/floor/plasteel/dark/side, /area/engineering/atmos) "avy" = ( /obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/o2{ dir = 4 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel/dark/corner{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/engineering/atmos) "avz" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -13890,10 +12035,10 @@ /obj/structure/closet/secure_closet/atmospherics, /obj/effect/turf_decal/bot, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/yellow{ +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel/dark/corner{ dir = 4 }, -/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "avH" = ( /obj/structure/table/wood, @@ -13937,18 +12082,12 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, /turf/open/floor/plasteel, /area/maintenance/port/fore) @@ -14054,11 +12193,9 @@ pixel_x = -32 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/port) "avT" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -14068,9 +12205,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "avU" = ( @@ -14080,14 +12214,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/turf/open/floor/plasteel, -/area/hallway/primary/port) -"avV" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port) "avW" = ( @@ -14098,7 +12224,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port) "avX" = ( @@ -14109,7 +12234,6 @@ /obj/item/kirbyplants{ icon_state = "plant-21" }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port) "avY" = ( @@ -14186,16 +12310,6 @@ "awf" = ( /obj/structure/table/wood, /obj/item/camera, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/theater) "awg" = ( @@ -14223,11 +12337,9 @@ /obj/structure/chair/comfy/brown{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "awk" = ( /obj/structure/chair/stool, @@ -14236,31 +12348,11 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "awl" = ( /obj/structure/table/wood, /obj/item/storage/bag/tray, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "awm" = ( @@ -14268,16 +12360,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "awn" = ( @@ -14322,17 +12404,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "awq" = ( /obj/effect/landmark/start/bartender, @@ -14350,37 +12424,21 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/bar/atrium) "aws" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock{ - name = "Bar Backroom"; - req_access_txt = "25" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/machinery/door/airlock{ + name = "Bar Backroom"; + req_access_txt = "25" }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "awt" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -14389,16 +12447,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/bar/atrium) "awu" = ( @@ -14406,16 +12454,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/bar/atrium) "awv" = ( @@ -14428,34 +12466,18 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/bar/atrium) "aww" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Bar Maintenance"; - req_access_txt = "25" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Bar Maintenance"; + req_access_txt = "25" }, /turf/open/floor/plating, /area/maintenance/starboard/central) @@ -14481,9 +12503,6 @@ pixel_x = -26 }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -14517,16 +12536,6 @@ /obj/structure/sign/warning/nosmoking{ pixel_y = 30 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "awD" = ( @@ -14556,31 +12565,12 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/engineering/atmos) -"awG" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/maintenance/port/aft) "awH" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ +/obj/machinery/atmospherics/pipe/manifold/general/visible{ dir = 1 }, -/turf/closed/wall/r_wall, -/area/maintenance/port/aft) +/turf/open/floor/plasteel, +/area/engineering/atmos) "awI" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ dir = 5 @@ -14602,34 +12592,27 @@ }, /obj/effect/decal/cleanable/dirt, /obj/machinery/vending/wardrobe/atmos_wardrobe, -/obj/effect/turf_decal/tile/yellow{ +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel/dark/corner{ dir = 4 }, -/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "awL" = ( -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ dir = 4 }, -/turf/open/floor/plating, -/area/maintenance/port/aft) +/obj/machinery/atmospherics/pipe/simple/general/visible, +/turf/open/floor/plasteel, +/area/engineering/atmos) "awM" = ( /obj/structure/cable/white{ icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/machinery/door/airlock/maintenance_hatch{ name = "Atmospherics Maintenance"; req_access_txt = "24" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel, /area/maintenance/port/fore) "awN" = ( @@ -14640,6 +12623,10 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/delivery, +/obj/machinery/door/window/eastright{ + dir = 1; + req_access_txt = "24" + }, /turf/open/floor/plasteel, /area/engineering/atmos) "awO" = ( @@ -14648,10 +12635,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "awP" = ( @@ -14664,16 +12647,6 @@ "awR" = ( /obj/structure/table/wood, /obj/item/soap/nanotrasen, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/theater) "awS" = ( @@ -14688,16 +12661,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "awU" = ( @@ -14709,16 +12672,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "awV" = ( @@ -14727,63 +12680,26 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "awW" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "awX" = ( /obj/structure/table/reinforced, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "awY" = ( /obj/structure/cable/white{ icon_state = "1-2" }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/bar/atrium) "awZ" = ( @@ -14792,16 +12708,6 @@ /obj/item/reagent_containers/food/drinks/shaker, /obj/item/reagent_containers/rag, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/bar/atrium) "axa" = ( @@ -14818,22 +12724,16 @@ dir = 1; pixel_y = -24 }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "axc" = ( /obj/machinery/light, /obj/machinery/vending/wardrobe/bar_wardrobe, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, /area/service/bar/atrium) "axd" = ( /obj/structure/closet/secure_closet/bar, @@ -14843,17 +12743,9 @@ /obj/structure/extinguisher_cabinet{ pixel_x = 26 }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "axe" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -14864,7 +12756,6 @@ /area/maintenance/starboard/central) "axf" = ( /obj/structure/table, -/obj/effect/turf_decal/bot, /obj/structure/bedsheetbin/towel, /obj/structure/sign/poster/official/cleanliness{ pixel_y = -32 @@ -14880,6 +12771,10 @@ pixel_x = -26; pixel_y = -26 }, +/obj/machinery/camera{ + c_tag = "Bathrooms"; + dir = 1 + }, /turf/open/floor/plasteel/freezer, /area/commons/toilet/restrooms) "axg" = ( @@ -14887,7 +12782,6 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, -/obj/effect/turf_decal/bot, /obj/machinery/light_switch{ pixel_x = 8; pixel_y = -24 @@ -14900,9 +12794,6 @@ lootcount = 3; name = "3maintenance loot spawner" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -14926,17 +12817,13 @@ /turf/open/floor/wood, /area/service/library) "axk" = ( -/obj/structure/girder, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 6 }, -/turf/open/floor/plating, -/area/maintenance/port/aft) +/turf/open/floor/plasteel, +/area/engineering/atmos) "axl" = ( /obj/structure/closet/firecloset, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -14952,9 +12839,6 @@ /obj/item/reagent_containers/food/drinks/bottle/whiskey, /obj/effect/spawner/lootdrop/maintenance, /obj/machinery/light/small, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -14973,10 +12857,9 @@ icon_state = "1-2" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/yellow{ +/turf/open/floor/plasteel/dark/corner{ dir = 4 }, -/turf/open/floor/plasteel/checker, /area/engineering/atmos) "axq" = ( /obj/machinery/light{ @@ -14990,7 +12873,12 @@ }, /obj/effect/turf_decal/bot, /obj/effect/decal/cleanable/dirt, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel/dark/corner{ + dir = 4 + }, /area/engineering/atmos) "axr" = ( /obj/structure/cable/white{ @@ -14999,7 +12887,12 @@ /obj/effect/turf_decal/delivery, /obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/decal/cleanable/dirt, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel/dark/corner{ + dir = 4 + }, /area/engineering/atmos) "axs" = ( /obj/structure/reagent_dispensers/fueltank, @@ -15010,7 +12903,13 @@ /obj/effect/decal/cleanable/oil, /obj/effect/turf_decal/bot, /obj/effect/decal/cleanable/dirt, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel/dark/corner{ + dir = 4 + }, /area/engineering/atmos) "axt" = ( /obj/effect/spawner/structure/window/reinforced, @@ -15113,16 +13012,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/port) -"axC" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "axD" = ( @@ -15132,17 +13021,9 @@ }, /obj/effect/turf_decal/bot, /obj/machinery/computer/arcade, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/commons/dorms) "axE" = ( /obj/machinery/status_display{ @@ -15150,54 +13031,30 @@ }, /obj/effect/turf_decal/bot, /obj/structure/closet/wardrobe/white, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/commons/dorms) "axF" = ( /obj/machinery/light_switch{ pixel_y = 24 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/item/kirbyplants{ icon_state = "plant-21" }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, /area/commons/dorms) "axG" = ( /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/machinery/cryopod{ dir = 8 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 5 + }, /area/commons/dorms) "axH" = ( /obj/structure/closet/secure_closet/personal/cabinet, @@ -15214,6 +13071,9 @@ /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = 32 }, +/obj/machinery/newscaster{ + pixel_x = 32 + }, /turf/open/floor/plasteel/grimy, /area/commons/dorms) "axJ" = ( @@ -15238,6 +13098,9 @@ /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = 32 }, +/obj/machinery/newscaster{ + pixel_x = 32 + }, /turf/open/floor/carpet, /area/commons/dorms) "axL" = ( @@ -15246,9 +13109,6 @@ lootcount = 2; name = "2maintenance loot spawner" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -15266,16 +13126,6 @@ pixel_y = -3 }, /obj/item/lipstick/random, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/theater) "axN" = ( @@ -15300,16 +13150,6 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "axP" = ( @@ -15333,16 +13173,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "axR" = ( @@ -15354,17 +13184,9 @@ name = "Bar Door"; req_access_txt = "25" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "axS" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ @@ -15391,32 +13213,19 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/bar/atrium) "axU" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/machinery/atmospherics/pipe/simple/orange/visible{ dir = 4 }, -/turf/closed/wall, -/area/maintenance/port/aft) +/turf/open/floor/plasteel, +/area/engineering/atmos) "axV" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/newscaster{ pixel_x = -32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -15425,9 +13234,12 @@ /turf/closed/wall, /area/hallway/secondary/exit) "axX" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall/r_wall/rust, -/area/maintenance/port/aft) +/obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) "axY" = ( /obj/structure/cable/white{ icon_state = "1-2" @@ -15447,18 +13259,14 @@ /obj/structure/cable/white{ icon_state = "2-4" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable/white{ + icon_state = "1-2" + }, /obj/machinery/door/airlock/security/glass{ name = "Security E.V.A. Storage"; req_access_txt = "63" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/structure/cable/white{ - icon_state = "1-2" - }, /turf/open/floor/plasteel, /area/security/brig) "ayb" = ( @@ -15508,17 +13316,12 @@ /obj/effect/decal/cleanable/oil, /obj/effect/decal/cleanable/dirt, /obj/machinery/meter/atmos, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/corner{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/engineering/atmos) "ayi" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/visible, @@ -15526,6 +13329,9 @@ icon_state = "4-8" }, /obj/machinery/meter/atmos/atmos_waste_loop, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "ayj" = ( @@ -15630,42 +13436,17 @@ }, /turf/open/floor/plating, /area/engineering/atmos) -"ayt" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/port) "ayu" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/commons/dorms) -"ayv" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/commons/dorms) "ayw" = ( /obj/effect/landmark/start/assistant, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white/corner, /area/commons/dorms) "ayx" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white/corner, /area/commons/dorms) "ayy" = ( /obj/effect/turf_decal/stripes/line{ @@ -15682,10 +13463,14 @@ /area/commons/dorms) "ayA" = ( /obj/structure/bed, -/obj/machinery/newscaster{ - pixel_x = 32 - }, /obj/item/bedsheet/blue, +/obj/machinery/button/door{ + id = "Dorm1"; + name = "Dorm Bolt Control"; + normaldoorcontrol = 1; + pixel_x = 25; + specialfunctions = 4 + }, /turf/open/floor/plasteel/grimy, /area/commons/dorms) "ayB" = ( @@ -15693,10 +13478,14 @@ /area/commons/dorms) "ayC" = ( /obj/structure/bed, -/obj/machinery/newscaster{ - pixel_x = 32 - }, /obj/item/bedsheet/red, +/obj/machinery/button/door{ + id = "Dorm2"; + name = "Dorm Bolt Control"; + normaldoorcontrol = 1; + pixel_x = 25; + specialfunctions = 4 + }, /turf/open/floor/carpet, /area/commons/dorms) "ayD" = ( @@ -15707,35 +13496,23 @@ dir = 4 }, /obj/machinery/door/firedoor, +/obj/structure/cable/white{ + icon_state = "1-8" + }, /obj/machinery/door/airlock/security/glass{ id_tag = "secinterior"; name = "Brig"; req_access_txt = "63" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/structure/cable/white{ - icon_state = "1-8" - }, /turf/open/floor/plasteel, /area/security/brig) "ayE" = ( /obj/structure/table/wood, /obj/item/instrument/violin, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/camera{ + c_tag = "Central Diner 2"; dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/theater) "ayF" = ( @@ -15768,31 +13545,15 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/camera{ - c_tag = "Central Diner 2"; - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "ayJ" = ( /obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "ayK" = ( @@ -15800,16 +13561,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "ayL" = ( @@ -15843,25 +13594,10 @@ /turf/open/floor/plasteel, /area/service/bar/atrium) "ayN" = ( -/obj/item/storage/fancy/cigarettes/cigars{ - pixel_y = 6 - }, -/obj/item/storage/fancy/cigarettes/cigars/cohiba{ - pixel_y = 3 - }, -/obj/item/storage/fancy/cigarettes/cigars/havana, -/obj/structure/table/reinforced, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/jukebox, +/turf/open/floor/plasteel/dark/corner{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "ayO" = ( /obj/structure/table/reinforced, @@ -15869,17 +13605,16 @@ pixel_x = 32 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ +/obj/item/storage/fancy/cigarettes/cigars/havana, +/obj/item/storage/fancy/cigarettes/cigars/cohiba{ + pixel_y = 3 + }, +/obj/item/storage/fancy/cigarettes/cigars{ + pixel_y = 6 + }, +/turf/open/floor/plasteel/dark/side{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "ayP" = ( /turf/closed/wall, @@ -15927,9 +13662,6 @@ /obj/machinery/light{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -15937,13 +13669,9 @@ "ayV" = ( /obj/structure/closet/firecloset, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/port) "ayW" = ( /obj/structure/table/reinforced, @@ -16099,12 +13827,6 @@ name = "Maintenance Hatch"; req_access_txt = "12" }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, /turf/open/floor/plasteel, /area/maintenance/port/fore) "azh" = ( @@ -16143,27 +13865,20 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel/dark/corner{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/engineering/atmos) "azm" = ( /obj/machinery/atmospherics/pipe/simple/yellow/visible, /obj/machinery/meter, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/yellow{ - dir = 4 + dir = 1 }, /turf/open/floor/plasteel/dark/corner{ - dir = 1 + dir = 4 }, /area/engineering/atmos) "azn" = ( @@ -16179,6 +13894,9 @@ /obj/structure/cable/white{ icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "azq" = ( @@ -16186,14 +13904,17 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "azr" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 }, /turf/open/floor/plasteel, /area/engineering/atmos) @@ -16271,16 +13992,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/engineering/atmos) "azz" = ( @@ -16302,66 +14013,25 @@ /turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "azA" = ( -/obj/structure/table, -/obj/item/paicard, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/structure/closet/crate/bin, /turf/open/floor/plasteel, /area/commons/dorms) "azB" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/commons/dorms) -"azC" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white/corner, /area/commons/dorms) "azD" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock{ - name = "Bar Back Room" + id_tag = "Dorm1"; + name = "Dorm 1" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/grimy, /area/commons/dorms) "azE" = ( /obj/structure/table/wood, /obj/item/staff/broom, /obj/item/clothing/head/witchwig, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/theater) "azF" = ( @@ -16404,11 +14074,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 10 }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "azJ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -16418,16 +14086,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "azK" = ( @@ -16436,16 +14094,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "azL" = ( @@ -16516,18 +14164,12 @@ /turf/open/floor/plating, /area/maintenance/starboard/central) "azS" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, /turf/open/floor/plating, /area/maintenance/starboard/central) @@ -16535,9 +14177,6 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -16547,13 +14186,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/starboard/fore) "azV" = ( /obj/structure/table/reinforced, @@ -16570,16 +14205,6 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "azX" = ( @@ -16595,16 +14220,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "azZ" = ( @@ -16704,10 +14319,10 @@ /turf/open/floor/plasteel, /area/security/prison) "aAn" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 6 +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8; + name = "Mix to Engine" }, -/obj/machinery/meter, /turf/open/floor/plasteel, /area/engineering/atmos) "aAo" = ( @@ -16717,6 +14332,10 @@ /turf/open/floor/plasteel, /area/security/prison) "aAp" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 }, @@ -16773,10 +14392,6 @@ /area/engineering/atmos) "aAu" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/atmos{ - name = "Atmospherics Access"; - req_access_txt = "24" - }, /obj/structure/cable/white{ icon_state = "4-8" }, @@ -16786,11 +14401,9 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/atmos{ + name = "Atmospherics Access"; + req_access_txt = "24" }, /turf/open/floor/plasteel, /area/engineering/atmos) @@ -16805,12 +14418,6 @@ /area/engineering/atmos) "aAw" = ( /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -16822,30 +14429,10 @@ /area/security/prison) "aAx" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/engineering/atmos) "aAy" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/engineering/atmos) "aAz" = ( @@ -16861,16 +14448,6 @@ dir = 4 }, /obj/effect/landmark/start/atmospheric_technician, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/engineering/atmos) "aAB" = ( @@ -16893,24 +14470,15 @@ codes_txt = "patrol;next_patrol=1.1-BrigCentral"; location = "9.6-LeavingDorms" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "aAD" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/public/glass{ - name = "Lockerroom" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/public/glass{ + name = "Lockerroom" }, /turf/open/floor/plasteel, /area/commons/dorms) @@ -16918,9 +14486,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/commons/dorms) "aAF" = ( @@ -16935,32 +14500,13 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/commons/dorms) -"aAH" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/commons/dorms) "aAI" = ( /obj/structure/sign/warning/nosmoking{ pixel_y = 32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white/corner, /area/commons/dorms) "aAJ" = ( /obj/structure/table, @@ -16973,6 +14519,14 @@ dir = 4 }, /obj/structure/bedsheetbin/color, +/obj/structure/sign/warning/fire{ + desc = "A sign that states the labeled room's number."; + dir = 1; + icon_state = "roomnum"; + name = "Room Number 2"; + pixel_x = -1; + pixel_y = 26 + }, /turf/open/floor/plasteel/white/corner, /area/commons/dorms) "aAK" = ( @@ -16984,27 +14538,13 @@ /area/service/theater) "aAM" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock{ - name = "Theatre Backstage"; - req_access_txt = "46" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/door/airlock{ + name = "Theatre Backstage"; + req_access_txt = "46" }, /turf/open/floor/plasteel/dark, /area/service/theater) @@ -17048,16 +14588,6 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aAP" = ( @@ -17073,16 +14603,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aAQ" = ( @@ -17143,21 +14663,15 @@ /turf/open/floor/plasteel, /area/service/bar/atrium) "aAT" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, /turf/open/floor/plating, /area/maintenance/starboard/central) @@ -17205,9 +14719,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -17219,19 +14730,14 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "aBb" = ( /obj/machinery/vending/cola/random, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/starboard/fore) "aBc" = ( /obj/machinery/computer/security{ @@ -17580,9 +15086,6 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "aBL" = ( @@ -17597,25 +15100,18 @@ codes_txt = "patrol;next_patrol=9.5-Dorms"; location = "9.4-EnteringDorms" }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port) "aBM" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/public/glass{ - name = "Lockerroom" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/public/glass{ + name = "Lockerroom" }, /turf/open/floor/plasteel, /area/commons/dorms) @@ -17626,9 +15122,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -17640,16 +15133,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/commons/dorms) "aBP" = ( @@ -17659,24 +15142,13 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/commons/dorms) "aBQ" = ( /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white/corner, /area/commons/dorms) "aBR" = ( /obj/machinery/light, @@ -17692,12 +15164,7 @@ codes_txt = "patrol;next_patrol=9.6-LeavingDorms"; location = "9.5-Dorms" }, -/obj/effect/turf_decal/tile/neutral, -/turf/open/floor/plasteel, -/area/commons/dorms) -"aBS" = ( -/obj/effect/turf_decal/tile/neutral, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white/corner, /area/commons/dorms) "aBT" = ( /obj/machinery/washing_machine, @@ -17705,6 +15172,14 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/structure/sign/warning/fire{ + desc = "A sign that states the labeled room's number."; + dir = 8; + icon_state = "roomnum"; + name = "Room Number 4"; + pixel_x = -1; + pixel_y = -24 + }, /turf/open/floor/plasteel/white/corner, /area/commons/dorms) "aBU" = ( @@ -17730,13 +15205,15 @@ /obj/machinery/camera{ c_tag = "Theatre Storage" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 9 }, -/turf/open/floor/plasteel/dark, /area/service/theater) "aBW" = ( +/obj/machinery/light_switch{ + pixel_x = 10; + pixel_y = 26 + }, /turf/open/floor/wood{ icon_state = "wood-broken7" }, @@ -17759,17 +15236,9 @@ /obj/structure/cable/white{ icon_state = "0-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 5 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/theater) "aBY" = ( /obj/machinery/airalarm{ @@ -17794,16 +15263,6 @@ "aBZ" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/cheesiehonkers, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aCa" = ( @@ -17835,16 +15294,12 @@ /area/service/kitchen) "aCd" = ( /obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/airlock{ name = "Kitchen"; req_access_txt = "28" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/service/kitchen) "aCe" = ( /turf/closed/wall, @@ -17854,9 +15309,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -17868,13 +15320,9 @@ pixel_x = 24 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/starboard/fore) "aCi" = ( /obj/effect/spawner/structure/window/reinforced, @@ -17986,10 +15434,6 @@ /area/security/brig) "aCr" = ( /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/airlock/security/glass{ name = "Gen-Pop Access"; @@ -18112,13 +15556,10 @@ dir = 8 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "aCE" = ( /obj/structure/cable/white{ @@ -18129,13 +15570,10 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/visible, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "aCF" = ( /obj/effect/decal/cleanable/dirt, @@ -18184,10 +15622,6 @@ name = "Atmospherics Lockdown Blast door" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/atmos/glass{ - name = "Atmospherics Desk"; - req_access_txt = "24" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-8" @@ -18195,11 +15629,11 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/door/airlock/atmos/glass{ + name = "Atmospherics Desk"; + req_access_txt = "24" + }, /turf/open/floor/plasteel, /area/engineering/atmos) "aCJ" = ( @@ -18246,53 +15680,28 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/machinery/camera{ - c_tag = "Central Hallway East"; - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "aCM" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "aCN" = ( -/obj/structure/table, /obj/item/storage/firstaid/regular, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/item/paicard{ + pixel_x = 15 }, +/obj/structure/table, /turf/open/floor/plasteel, /area/commons/dorms) "aCO" = ( -/obj/structure/table, /obj/item/storage/toolbox/mechanical{ pixel_x = 3; pixel_y = 3 }, /obj/item/storage/toolbox/emergency, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/structure/table, /turf/open/floor/plasteel, /area/commons/dorms) "aCP" = ( @@ -18304,11 +15713,9 @@ /obj/structure/sign/poster/contraband/clown{ pixel_x = -32 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/service/theater) "aCQ" = ( /obj/effect/landmark/start/clown, @@ -18336,17 +15743,9 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/theater) "aCT" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -18382,19 +15781,15 @@ /obj/machinery/camera{ c_tag = "Kitchen" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/service/kitchen) "aCW" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/service/kitchen) "aCX" = ( /obj/structure/sink/kitchen{ @@ -18402,11 +15797,9 @@ name = "sink"; pixel_y = 28 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/service/kitchen) "aCY" = ( /obj/machinery/light{ @@ -18418,11 +15811,9 @@ pixel_y = 32 }, /obj/structure/closet/secure_closet/freezer/kitchen, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/service/kitchen) "aCZ" = ( /obj/structure/closet/secure_closet/freezer/fridge, @@ -18431,11 +15822,9 @@ }, /obj/item/storage/box/donkpockets, /obj/item/storage/box/donkpockets, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/service/kitchen) "aDa" = ( /obj/structure/table/reinforced, @@ -18449,11 +15838,9 @@ /obj/structure/sign/nanotrasen{ pixel_x = 32 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/service/kitchen) "aDb" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -18560,24 +15947,11 @@ /turf/open/floor/plasteel, /area/engineering/atmos) "aDm" = ( -/obj/structure/bookcase/random/fiction, -/obj/structure/cable/white{ - icon_state = "1-2" +/turf/open/floor/plating{ + icon_state = "platingdmg3" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/dark, -/area/service/library) +/area/maintenance/port/fore) "aDn" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/structure/cable/white{ icon_state = "1-2" }, @@ -18589,7 +15963,9 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aDp" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -18608,16 +15984,6 @@ /turf/open/floor/plasteel, /area/hallway/primary/port/aft) "aDq" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/structure/closet/crate/bin, /obj/machinery/airalarm{ dir = 1; @@ -18641,19 +16007,15 @@ /area/engineering/atmos) "aDt" = ( /obj/machinery/door/firedoor, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/machinery/door/airlock/atmos{ name = "Atmospherics Engine Access"; req_access_txt = "24" }, -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel, /area/engineering/atmos) "aDu" = ( @@ -18664,7 +16026,7 @@ "aDv" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall/r_wall, -/area/engineering/break_room) +/area/engineering/lobby) "aDw" = ( /obj/machinery/firealarm{ dir = 4; @@ -18680,7 +16042,7 @@ /turf/open/floor/plasteel/white/corner{ dir = 1 }, -/area/engineering/break_room) +/area/engineering/lobby) "aDx" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 @@ -18694,7 +16056,7 @@ /turf/open/floor/plasteel/dark/corner{ dir = 1 }, -/area/engineering/break_room) +/area/engineering/lobby) "aDy" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/tile/yellow{ @@ -18703,7 +16065,7 @@ /turf/open/floor/plasteel/dark/corner{ dir = 1 }, -/area/engineering/break_room) +/area/engineering/lobby) "aDz" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 @@ -18714,7 +16076,7 @@ /turf/open/floor/plasteel/dark/corner{ dir = 1 }, -/area/engineering/break_room) +/area/engineering/lobby) "aDA" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 @@ -18725,7 +16087,7 @@ /turf/open/floor/plasteel/dark/corner{ dir = 1 }, -/area/engineering/break_room) +/area/engineering/lobby) "aDB" = ( /obj/item/kirbyplants{ icon_state = "plant-21" @@ -18734,28 +16096,21 @@ dir = 4 }, /turf/open/floor/plasteel/checker, -/area/engineering/break_room) +/area/engineering/lobby) "aDC" = ( /obj/structure/table/reinforced, /obj/item/airlock_painter, -/obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/hallway/primary/port) "aDD" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel{ - heat_capacity = 1e+006 - }, +/turf/open/floor/plasteel/white/corner, /area/commons/dorms) "aDE" = ( /obj/effect/landmark/start/assistant, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white/corner, /area/commons/dorms) "aDF" = ( /obj/machinery/light{ @@ -18764,11 +16119,7 @@ /obj/machinery/newscaster{ pixel_x = 32 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white/corner, /area/commons/dorms) "aDG" = ( /obj/effect/landmark/event_spawn, @@ -18776,18 +16127,26 @@ /area/commons/dorms) "aDH" = ( /obj/structure/bed, -/obj/machinery/newscaster{ - pixel_x = 32 - }, /obj/item/bedsheet/brown, +/obj/machinery/button/door{ + id = "Dorm3"; + name = "Dorm Bolt Control"; + normaldoorcontrol = 1; + pixel_x = 25; + specialfunctions = 4 + }, /turf/open/floor/wood, /area/commons/dorms) "aDI" = ( /obj/structure/bed, -/obj/machinery/newscaster{ - pixel_x = 32 - }, /obj/item/bedsheet/black, +/obj/machinery/button/door{ + id = "Dorm4"; + name = "Dorm Bolt Control"; + normaldoorcontrol = 1; + pixel_x = 25; + specialfunctions = 4 + }, /turf/open/floor/plasteel/grimy, /area/commons/dorms) "aDJ" = ( @@ -18804,11 +16163,9 @@ /obj/structure/mirror{ pixel_x = -28 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/service/theater) "aDK" = ( /obj/effect/landmark/start/mime, @@ -18835,35 +16192,21 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/theater) "aDN" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock{ - name = "Theatre Backstage"; - req_access_txt = "46" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock{ + name = "Theatre Backstage"; + req_access_txt = "46" }, /turf/open/floor/plasteel, /area/service/theater) @@ -18881,16 +16224,6 @@ /obj/structure/cable/white{ icon_state = "1-8" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aDP" = ( @@ -18898,16 +16231,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aDQ" = ( @@ -18999,21 +16322,13 @@ }, /turf/open/floor/plasteel, /area/service/kitchen) -"aDZ" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/starboard) "aEa" = ( /obj/structure/table, /obj/item/storage/firstaid/regular, /obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, /area/hallway/primary/starboard) "aEb" = ( /obj/effect/turf_decal/bot, @@ -19024,16 +16339,6 @@ /area/hallway/secondary/exit) "aEc" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "aEd" = ( @@ -19053,16 +16358,6 @@ codes_txt = "patrol;next_patrol=6.3-DeparturesS"; location = "6.2-DeparturesN" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "aEf" = ( @@ -19073,9 +16368,15 @@ /turf/open/floor/plasteel, /area/hallway/secondary/exit) "aEg" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall/r_wall, -/area/maintenance/port/aft) +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) "aEh" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -19089,9 +16390,6 @@ /obj/machinery/camera{ c_tag = "Aft Primary Hallway 4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/aft) "aEi" = ( @@ -19111,9 +16409,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/aft) "aEj" = ( @@ -19141,9 +16436,6 @@ /obj/structure/cable/white{ icon_state = "0-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/aft) "aEl" = ( @@ -19181,32 +16473,15 @@ name = "Station Intercom"; pixel_x = -26 }, -/obj/machinery/camera{ - c_tag = "Engineering Secure Storage"; - dir = 4; - network = list("ss13","engine") - }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/engineering/main) "aEo" = ( /obj/machinery/shieldgen, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/engineering/main) "aEp" = ( /obj/effect/turf_decal/stripes/line{ @@ -19224,36 +16499,19 @@ "aEr" = ( /obj/machinery/portable_atmospherics/canister/toxins, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/engineering/main) "aEs" = ( /obj/machinery/portable_atmospherics/canister/nitrogen, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/main) "aEt" = ( /turf/closed/wall/r_wall, /area/engineering/main) "aEu" = ( -/obj/machinery/computer/monitor{ - name = "Engineering Power Monitoring Console" - }, /obj/machinery/status_display{ pixel_x = -32 }, @@ -19267,9 +16525,8 @@ dir = 1 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/computer/monitor{ + name = "Engineering Power Monitoring Console" }, /turf/open/floor/plasteel/dark, /area/engineering/main) @@ -19277,12 +16534,12 @@ /obj/structure/cable/white{ icon_state = "0-8" }, -/obj/machinery/power/smes{ - charge = 5e+006 - }, /obj/structure/cable/white{ icon_state = "0-4" }, +/obj/machinery/power/smes{ + charge = 5e+006 + }, /turf/open/floor/circuit/green, /area/engineering/main) "aEw" = ( @@ -19310,6 +16567,11 @@ dir = 9 }, /obj/item/clothing/glasses/meson/engine, +/obj/machinery/camera{ + c_tag = "Engineering Access"; + dir = 4; + network = list("ss13","engine") + }, /turf/open/floor/plasteel, /area/engineering/main) "aEy" = ( @@ -19338,7 +16600,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/sign/warning/nosmoking, /turf/closed/wall/r_wall, -/area/engineering/break_room) +/area/engineering/lobby) "aEB" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 4 @@ -19350,7 +16612,7 @@ /turf/open/floor/plasteel/white/corner{ dir = 1 }, -/area/engineering/break_room) +/area/engineering/lobby) "aEC" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 @@ -19358,67 +16620,27 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aED" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aEE" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aEF" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aEG" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -19427,7 +16649,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aEH" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -19436,14 +16658,8 @@ /obj/machinery/door/airlock/public/glass{ name = "Engineering Foyer" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aEI" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -19452,9 +16668,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "aEJ" = ( @@ -19464,63 +16677,35 @@ /obj/structure/extinguisher_cabinet{ pixel_x = 24 }, -/obj/effect/turf_decal/tile/neutral, +/obj/machinery/camera{ + c_tag = "Central Hallway West"; + dir = 8 + }, /turf/open/floor/plasteel, /area/hallway/primary/port) "aEK" = ( -/obj/machinery/vending/clothing, /obj/machinery/firealarm{ dir = 4; pixel_x = -24 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/obj/machinery/vending/clothing, +/turf/open/floor/plasteel/dark/side, /area/commons/dorms) "aEL" = ( /obj/machinery/status_display{ pixel_y = -32 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/machinery/gear_painter, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/commons/dorms) "aEM" = ( -/obj/structure/closet/crate/bin, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/obj/machinery/vending/kink, +/turf/open/floor/plasteel/dark/side, /area/commons/dorms) "aEN" = ( -/obj/machinery/vending/autodrobe, /obj/structure/extinguisher_cabinet{ pixel_x = 26 }, @@ -19529,17 +16714,8 @@ dir = 8 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/obj/machinery/vending/autodrobe, +/turf/open/floor/plasteel/dark/side, /area/commons/dorms) "aEO" = ( /obj/structure/closet/secure_closet/personal/cabinet, @@ -19561,6 +16737,9 @@ /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = -32 }, +/obj/machinery/newscaster{ + pixel_x = 32 + }, /turf/open/floor/wood{ icon_state = "wood-broken7" }, @@ -19583,6 +16762,9 @@ /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = -32 }, +/obj/machinery/newscaster{ + pixel_x = 32 + }, /turf/open/floor/plasteel/grimy, /area/commons/dorms) "aES" = ( @@ -19594,10 +16776,9 @@ /obj/structure/sign/poster/contraband/random{ pixel_y = -32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 10 }, -/turf/open/floor/plasteel/dark, /area/service/theater) "aET" = ( /obj/structure/table/wood, @@ -19609,13 +16790,7 @@ name = "Station Intercom"; pixel_y = -26 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/service/theater) "aEU" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ @@ -19625,13 +16800,7 @@ pixel_y = -32 }, /obj/structure/closet/crate/wooden/toy, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/service/theater) "aEV" = ( /obj/structure/closet/crate/bin, @@ -19642,13 +16811,9 @@ dir = 8; pixel_x = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 6 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, /area/service/theater) "aEW" = ( /obj/structure/chair/stool, @@ -19656,31 +16821,11 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aEX" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/chips, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aEY" = ( @@ -19793,21 +16938,15 @@ /turf/open/floor/plasteel/white, /area/service/kitchen) "aFf" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Kitchen Maintenance"; - req_access_txt = "28" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Kitchen Maintenance"; + req_access_txt = "28" }, /turf/open/floor/plating, /area/maintenance/starboard/central) @@ -19874,16 +17013,6 @@ /area/hallway/secondary/exit) "aFl" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "aFm" = ( @@ -19897,16 +17026,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "aFo" = ( @@ -19932,10 +17051,6 @@ /obj/machinery/power/emitter, /obj/machinery/light/small, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/engineering/main) "aFr" = ( @@ -19945,17 +17060,9 @@ pixel_y = -26 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/engineering/main) "aFs" = ( /obj/effect/turf_decal/stripes/line{ @@ -19971,17 +17078,9 @@ /area/engineering/main) "aFu" = ( /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/engineering/main) "aFv" = ( /obj/structure/closet/crate, @@ -19995,15 +17094,6 @@ pixel_x = 26 }, /obj/effect/turf_decal/bot, -/obj/item/areaeditor/blueprints, -/obj/item/tank/jetpack/suit, -/obj/item/clothing/shoes/magboots/advance, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/main) "aFw" = ( @@ -20084,20 +17174,21 @@ /turf/open/floor/plasteel, /area/engineering/main) "aFB" = ( -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/machinery/power/terminal{ - dir = 4 - }, -/obj/effect/turf_decal/delivery, -/obj/machinery/airalarm{ - pixel_y = 24 - }, /obj/machinery/camera{ c_tag = "Starboard Bow Solar"; network = list("ss13","engine") }, +/obj/machinery/power/solar_control{ + id = "forestarboard"; + name = "Starboard Bow Solar Control" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/bot, /turf/open/floor/plating, /area/maintenance/solars/starboard/fore) "aFC" = ( @@ -20115,7 +17206,7 @@ /turf/open/floor/plasteel/white/corner{ dir = 1 }, -/area/engineering/break_room) +/area/engineering/lobby) "aFD" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 @@ -20129,18 +17220,8 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aFE" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ @@ -20153,18 +17234,8 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aFF" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 @@ -20173,18 +17244,8 @@ icon_state = "4-8" }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aFG" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -20193,18 +17254,8 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aFH" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -20214,26 +17265,20 @@ }, /obj/effect/turf_decal/tile/yellow, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aFI" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/door/airlock/public/glass{ - name = "Engineering Foyer" - }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/public/glass{ + name = "Engineering Foyer" }, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aFJ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -20241,9 +17286,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -20262,9 +17304,6 @@ codes_txt = "patrol;next_patrol=9.3-Engi"; location = "9.2-EnteringEngi" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -20275,11 +17314,6 @@ pixel_x = 24 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/camera{ - c_tag = "Central Hallway West"; - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port) "aFM" = ( @@ -20318,16 +17352,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aFP" = ( @@ -20335,16 +17359,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aFQ" = ( @@ -20428,9 +17442,6 @@ name = "Station Intercom"; pixel_x = -26 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "aFY" = ( @@ -20451,16 +17462,6 @@ "aGa" = ( /obj/effect/landmark/event_spawn, /obj/item/beacon, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "aGb" = ( @@ -20521,7 +17522,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side, /area/engineering/main) "aGi" = ( /obj/structure/sign/warning/securearea, @@ -20539,10 +17540,6 @@ /area/engineering/main) "aGk" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/engineering/glass{ - name = "Power Monitoring"; - req_access_txt = "32" - }, /obj/structure/cable/white{ icon_state = "1-2" }, @@ -20553,11 +17550,11 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/engineering/glass{ + name = "Power Monitoring"; + req_access_txt = "32" }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side, /area/engineering/main) "aGl" = ( /obj/machinery/door/firedoor, @@ -20591,21 +17588,17 @@ /area/engineering/main) "aGn" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/engineering{ - name = "Engineering Access"; - req_access_txt = "10" - }, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 }, -/turf/open/floor/plasteel, +/obj/machinery/door/airlock/engineering{ + name = "Engineering Access"; + req_access_txt = "10" + }, +/turf/open/floor/plasteel/dark/side, /area/engineering/main) "aGo" = ( /obj/structure/sign/warning/fire, @@ -20626,7 +17619,7 @@ /turf/open/floor/plasteel/white/corner{ dir = 1 }, -/area/engineering/break_room) +/area/engineering/lobby) "aGq" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 @@ -20638,7 +17631,7 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aGr" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/light, @@ -20657,34 +17650,33 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aGs" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aGt" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, /obj/effect/turf_decal/tile/yellow, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aGu" = ( /obj/item/kirbyplants{ icon_state = "plant-22" }, /obj/effect/turf_decal/tile/yellow, /turf/open/floor/plasteel, -/area/engineering/break_room) +/area/engineering/lobby) "aGv" = ( /obj/structure/table/reinforced, /obj/item/stock_parts/cell/high, /obj/item/stock_parts/cell/high, /obj/machinery/cell_charger, -/obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/hallway/primary/port) "aGw" = ( @@ -20695,9 +17687,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -20706,7 +17695,6 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port) "aGy" = ( @@ -20800,11 +17788,9 @@ pixel_y = 32 }, /obj/machinery/door/window/southleft, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/medical/genetics) "aGG" = ( /obj/structure/cable/white{ @@ -20897,16 +17883,6 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aGO" = ( @@ -20922,16 +17898,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aGP" = ( @@ -20940,16 +17906,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aGQ" = ( @@ -20991,10 +17947,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/white/corner, +/turf/open/floor/plasteel/dark/side, /area/service/kitchen) "aGS" = ( /obj/machinery/processor, @@ -21003,23 +17956,14 @@ /obj/effect/turf_decal/stripes/line{ dir = 5 }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/white/corner, +/turf/open/floor/plasteel/dark/side, /area/service/kitchen) "aGT" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/service/kitchen) "aGU" = ( /obj/structure/rack, @@ -21033,13 +17977,7 @@ /obj/item/storage/box/donkpockets, /obj/item/clothing/head/chefhat, /obj/machinery/light, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/service/kitchen) "aGV" = ( /obj/structure/table/reinforced, @@ -21052,13 +17990,7 @@ dir = 1; pixel_y = -22 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/service/kitchen) "aGW" = ( /obj/structure/table/reinforced, @@ -21067,21 +17999,12 @@ pixel_x = -3; pixel_y = 5 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/service/kitchen) "aGX" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "aGY" = ( @@ -21107,12 +18030,6 @@ dir = 8 }, /obj/effect/turf_decal/loading_area, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, /obj/structure/disposalpipe/segment{ dir = 9 }, @@ -21155,36 +18072,23 @@ }, /obj/machinery/door/window/southright, /obj/item/radio/intercom{ - name = "Station Intercom"; - pixel_y = 26 + frequency = 1485; + name = "Station Intercom (Medbay)"; + pixel_y = 30 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/medical/genetics) "aHd" = ( /obj/structure/window/reinforced, /obj/machinery/clonepod, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/medical/genetics) "aHe" = ( /obj/effect/turf_decal/bot_white/right, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/gravity_generator) "aHf" = ( @@ -21196,25 +18100,6 @@ }, /turf/open/floor/plating, /area/medical/genetics) -"aHg" = ( -/obj/machinery/camera{ - c_tag = "Gravity Generator Room"; - dir = 8; - network = list("ss13","engine") - }, -/obj/effect/turf_decal/bot_white/left, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/engineering/gravity_generator) "aHh" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall/r_wall, @@ -21234,24 +18119,25 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/effect/turf_decal/stripes/corner{ dir = 4 }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + name = "Mix to Engine" + }, /turf/open/floor/engine, /area/engineering/main) "aHk" = ( /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/effect/turf_decal/stripes/corner{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/green/visible{ + dir = 1 + }, /turf/open/floor/engine, /area/engineering/main) "aHl" = ( @@ -21273,13 +18159,15 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 + }, /turf/open/floor/engine, /area/engineering/main) "aHn" = ( @@ -21289,9 +18177,6 @@ /obj/structure/sign/warning/electricshock{ pixel_y = 32 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -21300,6 +18185,9 @@ network = list("ss13","engine"); pixel_x = 23 }, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 10 + }, /turf/open/floor/engine, /area/engineering/main) "aHo" = ( @@ -21309,10 +18197,12 @@ /obj/structure/cable/white{ icon_state = "1-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, /turf/open/floor/engine, /area/engineering/main) "aHp" = ( @@ -21365,7 +18255,7 @@ /area/engineering/main) "aHs" = ( /obj/effect/turf_decal/tile/blue, -/obj/machinery/vending/medical, +/obj/structure/closet/crate/freezer/blood, /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "aHt" = ( @@ -21387,15 +18277,13 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/item/kirbyplants{ - icon_state = "plant-22" - }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/obj/machinery/vending/wardrobe/engi_wardrobe, /turf/open/floor/engine, /area/engineering/main) "aHv" = ( @@ -21427,10 +18315,6 @@ name = "Engineering Lockdown Shutters" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/engineering{ - name = "Engineering Access"; - req_access_txt = "10" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 }, @@ -21440,13 +18324,13 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 }, +/obj/machinery/door/airlock/engineering{ + name = "Engineering Access"; + req_access_txt = "10" + }, /turf/open/floor/plasteel, /area/engineering/main) "aHy" = ( @@ -21518,9 +18402,6 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -21533,7 +18414,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port) "aHE" = ( @@ -21544,30 +18424,20 @@ icon_state = "4-8" }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/port) "aHF" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, /turf/open/floor/plating, /area/maintenance/port/central) @@ -21582,11 +18452,6 @@ /obj/structure/cable/white{ icon_state = "0-4" }, -/obj/structure/table, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral, /obj/machinery/button/door{ id = "geneticsbot"; name = "Genetics Shutter Control"; @@ -21600,7 +18465,10 @@ pixel_y = 4 }, /obj/item/storage/box/rxglasses, -/turf/open/floor/plasteel/dark, +/obj/structure/table, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/medical/genetics) "aHH" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -21662,10 +18530,6 @@ /turf/closed/wall, /area/service/hydroponics) "aHO" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Hydroponics Maintenance"; - req_access_txt = "35" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -21673,9 +18537,9 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Hydroponics Maintenance"; + req_access_txt = "35" }, /turf/open/floor/plating, /area/maintenance/port/central) @@ -21717,31 +18581,11 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aHT" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/coffee, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aHU" = ( @@ -21770,49 +18614,37 @@ /area/service/kitchen) "aHW" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock{ - name = "Kitchen Coldroom"; - req_access_txt = "28" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock{ + name = "Kitchen Coldroom"; + req_access_txt = "28" }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/service/kitchen) "aHX" = ( /obj/structure/sign/warning/nosmoking{ pixel_x = 32 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/effect/turf_decal/bot, /obj/machinery/computer/scan_consolenew{ dir = 8 }, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, /area/medical/genetics) "aHY" = ( /obj/structure/table, /obj/item/paper_bin, /obj/item/pen, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/starboard) "aHZ" = ( /obj/item/kirbyplants{ @@ -21825,52 +18657,14 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) -"aIb" = ( -/obj/structure/sign/warning/radiation{ - pixel_x = -32 - }, -/obj/effect/turf_decal/bot_white, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/engineering/gravity_generator) "aIc" = ( /turf/open/floor/circuit/green, /area/engineering/gravity_generator) "aId" = ( -/obj/effect/turf_decal/bot_white, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, /area/engineering/gravity_generator) "aIe" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -21885,10 +18679,12 @@ /obj/structure/sign/warning/nosmoking{ pixel_x = -32 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 6 + }, /turf/open/floor/engine, /area/engineering/main) "aIg" = ( @@ -21897,9 +18693,8 @@ }, /obj/effect/turf_decal/stripes/corner, /obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 6 + dir = 4 }, -/obj/machinery/meter, /turf/open/floor/engine, /area/engineering/main) "aIh" = ( @@ -21908,7 +18703,7 @@ }, /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 + dir = 9 }, /turf/open/floor/engine, /area/engineering/main) @@ -21917,8 +18712,8 @@ icon_state = "4-8" }, /obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ - dir = 4 +/obj/machinery/atmospherics/components/binary/pump{ + name = "Gas to Chamber" }, /turf/open/floor/engine, /area/engineering/main) @@ -21926,13 +18721,7 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, /obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 - }, /turf/open/floor/engine, /area/engineering/main) "aIk" = ( @@ -21945,7 +18734,7 @@ }, /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/manifold/green/visible{ - dir = 1 + dir = 8 }, /turf/open/floor/engine, /area/engineering/main) @@ -22119,9 +18908,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -22135,23 +18921,18 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port) "aIB" = ( /turf/closed/wall, /area/service/janitor) "aIC" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Custodial Maintenance"; - req_access_txt = "26" - }, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Custodial Maintenance"; + req_access_txt = "26" }, /turf/open/floor/plating, /area/maintenance/port/central) @@ -22174,11 +18955,9 @@ /obj/effect/turf_decal/delivery, /obj/item/wrench, /obj/item/wirecutters, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/service/hydroponics) "aIF" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -22186,11 +18965,9 @@ pixel_y = 32 }, /obj/structure/closet/secure_closet/hydroponics, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/corner{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/service/hydroponics) "aIG" = ( /obj/machinery/hydroponics/constructable, @@ -22240,11 +19017,9 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/corner{ + dir = 4 }, -/turf/open/floor/plasteel/dark, /area/service/hydroponics) "aIM" = ( /obj/machinery/requests_console{ @@ -22257,26 +19032,21 @@ /obj/machinery/chem_master/condimaster{ name = "BrewMaster 3000" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/service/hydroponics) "aIN" = ( -/obj/machinery/vending/hydronutrients, /obj/structure/noticeboard{ pixel_y = 30 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/vending/hydronutrients, +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/service/hydroponics) "aIO" = ( -/obj/machinery/vending/hydroseeds, /obj/machinery/light_switch{ pixel_x = -8; pixel_y = 24 @@ -22289,11 +19059,10 @@ req_access_txt = "35" }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/vending/hydroseeds, +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/service/hydroponics) "aIP" = ( /obj/structure/table/reinforced, @@ -22305,6 +19074,10 @@ /obj/item/paper_bin, /obj/item/pen, /obj/effect/turf_decal/delivery, +/obj/machinery/door/window/westright{ + name = "Hydroponics Desk"; + req_access_txt = "35" + }, /turf/open/floor/plasteel, /area/service/hydroponics) "aIQ" = ( @@ -22312,16 +19085,9 @@ pixel_x = 32 }, /obj/structure/closet/crate/bin, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "aIR" = ( /obj/structure/closet/secure_closet/freezer/meat, @@ -22382,9 +19148,6 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "aIY" = ( @@ -22395,9 +19158,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "aIZ" = ( @@ -22418,14 +19178,14 @@ /turf/open/floor/plasteel, /area/hallway/secondary/exit) "aJb" = ( -/obj/effect/turf_decal/tile/red{ +/obj/effect/turf_decal/tile/brown{ dir = 8 }, /turf/open/floor/plasteel/white/corner, /area/hallway/secondary/exit) "aJc" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/red{ +/obj/effect/turf_decal/tile/brown{ dir = 8 }, /turf/open/floor/plasteel/white/corner, @@ -22471,53 +19231,24 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/machinery/dna_scannernew, -/obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/delivery, /obj/machinery/firealarm{ dir = 8; pixel_x = 24 }, -/turf/open/floor/plasteel/dark, -/area/medical/genetics) -"aJh" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/effect/turf_decal/bot_white/left, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/dna_scannernew, +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/area/medical/genetics) +"aJh" = ( +/obj/effect/turf_decal/bot_white/left, /turf/open/floor/plasteel/dark, /area/engineering/gravity_generator) "aJi" = ( /obj/machinery/gravity_generator/main/station, -/obj/effect/turf_decal/bot_white, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, /area/engineering/gravity_generator) "aJj" = ( /obj/effect/spawner/structure/window/reinforced, @@ -22598,6 +19329,7 @@ /obj/structure/cable{ icon_state = "0-2" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/engineering/gravity_generator) "aJo" = ( @@ -22621,8 +19353,8 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 +/obj/machinery/atmospherics/pipe/manifold/green/visible{ + dir = 8 }, /turf/open/floor/engine, /area/engineering/main) @@ -22633,23 +19365,26 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8; + name = "Gas to Mix" + }, /turf/open/floor/engine, /area/engineering/main) "aJr" = ( -/obj/item/wrench, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 6 - }, /obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 1 + }, +/obj/item/wrench, /turf/open/floor/plasteel/dark, /area/engineering/main) "aJs" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/manifold/general/visible{ dir = 4 }, -/obj/machinery/meter, -/obj/effect/turf_decal/delivery, +/obj/machinery/meter/atmos, /turf/open/floor/plasteel/dark, /area/engineering/main) "aJt" = ( @@ -22682,17 +19417,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/dark, /area/engineering/main) -"aJx" = ( -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral, -/turf/open/floor/plasteel/dark, -/area/medical/morgue) "aJy" = ( /obj/structure/cable{ icon_state = "1-2" @@ -22789,16 +19513,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/engineering/main) "aJE" = ( @@ -22820,16 +19534,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/engineering/main) "aJG" = ( @@ -22867,7 +19571,6 @@ /turf/open/floor/plasteel, /area/engineering/main) "aJI" = ( -/obj/structure/table/reinforced, /obj/item/storage/box/mousetraps{ pixel_x = 3; pixel_y = 3 @@ -22886,11 +19589,10 @@ c_tag = "Custodial Closet" }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/obj/structure/table/reinforced, +/turf/open/floor/plasteel/dark/side{ + dir = 9 }, -/turf/open/floor/plasteel/dark, /area/service/janitor) "aJJ" = ( /obj/vehicle/ridden/janicart, @@ -22906,14 +19608,18 @@ icon_state = "0-2" }, /obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, /area/service/janitor) "aJK" = ( /obj/structure/cable/white{ icon_state = "1-2" }, /obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, /area/service/janitor) "aJL" = ( /obj/structure/closet/crate/bin, @@ -22926,13 +19632,9 @@ name = "Station Intercom"; pixel_x = 26 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 5 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/janitor) "aJM" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -23051,6 +19753,11 @@ /obj/item/reagent_containers/food/snacks/grown/pumpkin, /obj/item/reagent_containers/food/snacks/grown/grapes, /obj/effect/turf_decal/delivery, +/obj/machinery/door/window/northleft{ + dir = 8; + name = "Hydroponics Desk"; + req_access_txt = "35" + }, /turf/open/floor/plasteel, /area/service/hydroponics) "aJW" = ( @@ -23060,27 +19767,13 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "aJX" = ( /obj/machinery/vending/cola/random, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "aJY" = ( /obj/structure/sign/warning/nosmoking, @@ -23169,13 +19862,7 @@ "aKg" = ( /obj/structure/closet/emcloset, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/hallway/primary/port/aft) "aKh" = ( /obj/structure/sign/nanotrasen, @@ -23222,59 +19909,31 @@ /turf/closed/wall, /area/maintenance/port/aft) "aKn" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, /obj/structure/cable/white{ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, +/turf/open/floor/plating, /area/maintenance/port/aft) "aKo" = ( /obj/structure/lattice, /turf/open/floor/plating/asteroid/airless, /area/asteroid/nearstation) "aKp" = ( -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -23 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/gravity_generator) "aKq" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/engineering/gravity_generator) "aKr" = ( /obj/machinery/power/solar{ @@ -23289,26 +19948,22 @@ /area/solars/port/aft) "aKs" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/command/glass{ - name = "Gravity Generator Chamber"; - req_access_txt = "19; 61" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, /obj/structure/cable{ icon_state = "2-4" }, /obj/structure/cable{ icon_state = "1-4" }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, -/turf/open/floor/plasteel, +/obj/machinery/door/airlock/engineering/glass{ + name = "Gravity Generator"; + req_access_txt = "11" + }, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/engineering/gravity_generator) "aKt" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -23333,16 +19988,6 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/engineering/gravity_generator) "aKv" = ( @@ -23363,14 +20008,11 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/engineering/gravity_generator) "aKx" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/engineering{ - name = "Engineering Access"; - req_access_txt = "10" - }, /obj/structure/cable/white{ icon_state = "1-8" }, @@ -23380,17 +20022,16 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, -/turf/open/floor/plasteel, +/obj/machinery/door/airlock/engineering{ + name = "Engineering Access"; + req_access_txt = "10" + }, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, /area/engineering/gravity_generator) "aKy" = ( /obj/structure/cable/white{ @@ -23405,17 +20046,15 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 6 - }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/engine, /area/engineering/main) "aKz" = ( -/obj/machinery/portable_atmospherics/scrubber, +/obj/effect/turf_decal/bot, /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 1 }, -/obj/effect/turf_decal/bot, +/obj/machinery/portable_atmospherics/canister/nitrous_oxide, /turf/open/floor/plasteel/dark, /area/engineering/main) "aKA" = ( @@ -23482,10 +20121,6 @@ /area/engineering/main) "aKH" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/engineering{ - name = "Engineering Access"; - req_access_txt = "10" - }, /obj/structure/cable/white{ icon_state = "1-8" }, @@ -23495,13 +20130,13 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ +/obj/machinery/door/airlock/engineering{ + name = "Engineering Access"; + req_access_txt = "10" + }, +/turf/open/floor/plasteel/dark/side{ dir = 8 }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, /area/engineering/main) "aKI" = ( /obj/structure/cable/white{ @@ -23529,9 +20164,6 @@ }, /obj/item/clothing/gloves/color/yellow, /obj/item/reagent_containers/food/drinks/soda_cans/thirteenloko, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 - }, /obj/item/clothing/gloves/color/yellow, /obj/item/clothing/gloves/color/yellow, /obj/effect/turf_decal/tile/yellow{ @@ -23544,6 +20176,9 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, /turf/open/floor/plasteel, /area/engineering/main) "aKL" = ( @@ -23564,16 +20199,6 @@ }, /obj/item/rcl/pre_loaded, /obj/item/rcl/pre_loaded, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/engineering/main) "aKM" = ( @@ -23584,7 +20209,7 @@ /obj/effect/turf_decal/bot, /obj/structure/closet/l3closet/janitor, /obj/item/toy/figure/janitor, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side, /area/service/janitor) "aKN" = ( /obj/structure/cable/white{ @@ -23593,16 +20218,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/engineering/main) "aKO" = ( @@ -23626,7 +20241,6 @@ /turf/open/floor/plasteel, /area/engineering/main) "aKP" = ( -/obj/structure/table/reinforced, /obj/item/clothing/gloves/color/orange, /obj/item/reagent_containers/spray/cleaner, /obj/item/reagent_containers/spray/cleaner, @@ -23639,11 +20253,10 @@ pixel_x = -32 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/obj/structure/table/reinforced, +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/service/janitor) "aKQ" = ( /obj/effect/landmark/start/janitor, @@ -23688,13 +20301,9 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/janitor) "aKT" = ( /obj/effect/turf_decal/stripes/line{ @@ -23711,38 +20320,17 @@ /area/service/hydroponics) "aKU" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/hydroponics) "aKV" = ( /turf/closed/wall/r_wall, /area/medical/virology) "aKW" = ( -/obj/machinery/seed_extractor, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/seed_extractor, /turf/open/floor/plasteel, /area/service/hydroponics) "aKX" = ( -/obj/structure/table/glass, /obj/item/crowbar/red, /obj/item/cultivator, /obj/item/shovel/spade, @@ -23754,20 +20342,10 @@ }, /obj/item/reagent_containers/glass/bucket, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/structure/table/glass, /turf/open/floor/plasteel, /area/service/hydroponics) "aKY" = ( -/obj/structure/table/glass, /obj/machinery/reagentgrinder{ desc = "Used to grind things up into raw materials and liquids."; pixel_y = 5 @@ -23778,35 +20356,16 @@ /obj/item/reagent_containers/glass/bottle/nutrient/rh, /obj/item/reagent_containers/dropper, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/structure/table/glass, /turf/open/floor/plasteel, /area/service/hydroponics) "aKZ" = ( -/obj/structure/table/glass, /obj/item/watertank, /obj/item/reagent_containers/spray/pestspray, /obj/item/grenade/chem_grenade/antiweed, /obj/item/grenade/chem_grenade/antiweed, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/structure/table/glass, /turf/open/floor/plasteel, /area/service/hydroponics) "aLa" = ( @@ -23816,16 +20375,6 @@ icon_state = "1-2" }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/hydroponics) "aLb" = ( @@ -23849,13 +20398,7 @@ /obj/item/reagent_containers/food/snacks/grown/tomato, /obj/effect/turf_decal/bot, /obj/item/paper/guides/jobs/hydroponics, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/service/hydroponics) "aLd" = ( /obj/structure/table/glass, @@ -23871,13 +20414,7 @@ /obj/item/seeds/tower, /obj/effect/turf_decal/bot, /obj/item/book/manual/hydroponics_pod_people, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/service/hydroponics) "aLe" = ( /obj/machinery/smartfridge, @@ -23910,13 +20447,9 @@ dir = 8; pixel_x = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "aLi" = ( /obj/structure/kitchenspike, @@ -23943,9 +20476,6 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "aLn" = ( @@ -23976,6 +20506,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 }, +/obj/effect/turf_decal/trimline/green/line, /turf/open/floor/plating, /area/maintenance/port/aft) "aLq" = ( @@ -24075,16 +20606,21 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, +/obj/effect/turf_decal/trimline/green/line{ + dir = 1 + }, /turf/open/floor/plating, /area/maintenance/port/aft) "aLC" = ( /turf/closed/wall, /area/maintenance/solars/port/aft) "aLD" = ( -/obj/machinery/power/port_gen/pacman, /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/obj/structure/table/reinforced, +/obj/item/paper/guides/jobs/engi/gravity_gen, +/obj/item/pen/blue, /turf/open/floor/plasteel, /area/engineering/gravity_generator) "aLE" = ( @@ -24094,17 +20630,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/engineering/gravity_generator) "aLF" = ( /obj/structure/table/reinforced, @@ -24136,6 +20662,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/obj/machinery/power/port_gen/pacman, /turf/open/floor/plasteel, /area/engineering/gravity_generator) "aLI" = ( @@ -24167,24 +20694,19 @@ dir = 1; pixel_y = -22 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/effect/turf_decal/bot, /obj/structure/cable{ icon_state = "1-8" }, /obj/item/clothing/glasses/meson/engine, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel, /area/engineering/gravity_generator) "aLL" = ( -/obj/effect/turf_decal/box, -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/machinery/power/tracker, -/turf/open/floor/plasteel/airless/solarpanel, -/area/solars/port/aft) +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) "aLM" = ( /obj/structure/cable/white{ icon_state = "1-2" @@ -24277,6 +20799,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, /turf/open/floor/engine, /area/engineering/main) "aLX" = ( @@ -24291,6 +20816,9 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engineering/main) "aLZ" = ( @@ -24304,19 +20832,12 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engineering/main) "aMa" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/engineering/main) "aMb" = ( @@ -24367,7 +20888,6 @@ /turf/open/floor/plasteel, /area/engineering/main) "aMe" = ( -/obj/structure/table/reinforced, /obj/item/storage/box/lights/mixed{ pixel_x = 3; pixel_y = 3 @@ -24378,11 +20898,10 @@ dir = 4; pixel_x = -23 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/obj/structure/table/reinforced, +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/service/janitor) "aMf" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, @@ -24423,13 +20942,9 @@ dir = 9 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/janitor) "aMi" = ( /obj/effect/turf_decal/stripes/line{ @@ -24544,6 +21059,10 @@ dir = 1; pixel_y = 1 }, +/obj/machinery/camera{ + c_tag = "Hydroponics South"; + dir = 9 + }, /turf/open/floor/grass, /area/service/hydroponics) "aMt" = ( @@ -24595,17 +21114,7 @@ /obj/structure/sign/poster/contraband/random{ pixel_y = 32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/maintenance/port/aft) "aMw" = ( /obj/structure/rack, @@ -24615,17 +21124,10 @@ }, /obj/item/storage/secure/briefcase, /obj/effect/decal/cleanable/cobweb/cobweb2, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/corner{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/maintenance/port/aft) "aMx" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -24641,13 +21143,9 @@ icon_state = "plant-22" }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/starboard) "aMz" = ( /obj/item/kirbyplants{ @@ -24670,16 +21168,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "aMC" = ( @@ -24689,11 +21177,6 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) -"aMD" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/sign/poster/contraband/random, -/turf/closed/wall, -/area/maintenance/port/aft) "aME" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -24734,18 +21217,14 @@ /area/tcommsat/server) "aML" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/command{ - name = "Telecomms Control Room"; - req_access_txt = "19; 61" - }, /obj/structure/cable{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/engineering{ + name = "Telecommunications"; + req_access_txt = "61" }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side, /area/tcommsat/server) "aMM" = ( /obj/effect/spawner/structure/window/reinforced, @@ -24860,15 +21339,9 @@ /turf/open/floor/engine, /area/engineering/supermatter) "aMY" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/machinery/dna_scannernew, /obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel/dark, +/obj/machinery/dna_scannernew, +/turf/open/floor/plasteel/dark/side, /area/medical/genetics) "aMZ" = ( /obj/structure/cable{ @@ -24978,12 +21451,9 @@ icon_state = "1-2" }, /obj/machinery/camera{ - c_tag = "Atmospherics South West"; + c_tag = "Central Hallway West 2"; dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -24993,7 +21463,6 @@ /obj/machinery/newscaster{ pixel_x = 32 }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port) "aNj" = ( @@ -25004,11 +21473,9 @@ pixel_y = -26 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 10 }, -/turf/open/floor/plasteel/dark, /area/service/janitor) "aNk" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -25016,18 +21483,13 @@ icon_state = "1-2" }, /obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side, /area/service/janitor) "aNl" = ( -/obj/structure/table, /obj/machinery/airalarm/unlocked{ dir = 4; pixel_x = -23 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral, /obj/item/clipboard, /obj/item/folder/white, /obj/item/storage/pill_bottle/mutadone{ @@ -25043,32 +21505,25 @@ pixel_x = 5; pixel_y = 13 }, -/turf/open/floor/plasteel/dark, +/obj/structure/table, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/medical/genetics) "aNm" = ( /obj/effect/turf_decal/bot, /obj/machinery/vending/wardrobe/jani_wardrobe, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 6 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/janitor) "aNn" = ( -/obj/structure/table/glass, /obj/item/storage/box/syringes, /obj/effect/turf_decal/bot, /obj/item/storage/box/disks_plantgene, /obj/item/toy/figure/botanist, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/obj/structure/table/glass, +/turf/open/floor/plasteel/dark/side, /area/service/hydroponics) "aNo" = ( /obj/machinery/light_switch{ @@ -25095,12 +21550,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/machinery/door/airlock/medical/glass{ name = "Genetics"; req_access_txt = "5; 9; 68" @@ -25141,29 +21590,15 @@ /area/service/hydroponics) "aNt" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/corner{ + dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, /area/service/hydroponics) "aNu" = ( /obj/structure/closet/crate/bin, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/camera{ - c_tag = "Hydroponics South"; - dir = 8 - }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/service/hydroponics) "aNv" = ( /obj/structure/window/reinforced{ @@ -25182,30 +21617,22 @@ /area/service/hydroponics) "aNy" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/public/glass{ - name = "Atrium" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/service/bar/atrium) -"aNz" = ( -/obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ name = "Atrium" }, +/turf/open/floor/plasteel/dark, +/area/service/bar/atrium) +"aNz" = ( +/obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/public/glass{ + name = "Atrium" }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "aNA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -25253,9 +21680,6 @@ pixel_x = -24 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -25365,20 +21789,16 @@ /area/medical/genetics) "aNQ" = ( /obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/mapping_helpers/airlock/unres{ + dir = 1 + }, /obj/machinery/door/airlock/medical/glass{ id_tag = "cloningfoyer"; name = "Cloning Lab"; req_access_txt = "5" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/airlock/unres{ - dir = 1 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white, /area/medical/genetics) "aNR" = ( /obj/effect/spawner/structure/window/reinforced, @@ -25400,23 +21820,13 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "aNT" = ( -/obj/machinery/announcement_system, /obj/machinery/status_display/ai{ pixel_x = -32 }, /obj/machinery/firealarm{ pixel_y = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/announcement_system, /turf/open/floor/plasteel/dark, /area/tcommsat/server) "aNU" = ( @@ -25440,21 +21850,11 @@ /turf/open/floor/plasteel/grimy, /area/tcommsat/server) "aNX" = ( -/obj/machinery/computer/telecomms/monitor{ - dir = 8 - }, /obj/item/radio/intercom{ name = "Station Intercom"; pixel_y = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/computer/telecomms/monitor{ dir = 8 }, /turf/open/floor/plasteel/dark, @@ -25526,43 +21926,34 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/engine, /area/engineering/main) "aOe" = ( /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/door/airlock/command{ - name = "Chief Medical Officer's Office"; - req_access_txt = "40" - }, /obj/machinery/door/firedoor, /obj/structure/cable/white{ icon_state = "2-8" }, +/obj/machinery/door/airlock/command{ + name = "Chief Medical Officer's Office"; + req_access_txt = "40" + }, /turf/open/floor/plasteel, /area/command/heads_quarters/cmo) "aOf" = ( -/obj/machinery/door/airlock{ - name = "Custodial Closet"; - req_access_txt = "26" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock{ + name = "Custodial Closet"; + req_access_txt = "26" }, /turf/open/floor/plasteel, /area/service/janitor) @@ -25590,15 +21981,11 @@ /area/service/hydroponics) "aOi" = ( /obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/airlock/medical/glass{ name = "Hydroponics"; req_access_txt = "35" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/service/hydroponics) "aOj" = ( @@ -25701,41 +22088,31 @@ dir = 4 }, /obj/machinery/shieldgen, -/turf/open/floor/plasteel, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/maintenance/port/aft) "aOu" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, /turf/open/floor/plating, /area/maintenance/starboard/central) "aOv" = ( -/obj/machinery/computer/message_monitor{ - dir = 4 - }, /obj/machinery/newscaster{ pixel_x = -32 }, /obj/item/paper/monitorkey, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/computer/message_monitor{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/tcommsat/server) "aOw" = ( @@ -25755,9 +22132,6 @@ /turf/open/floor/plasteel/grimy, /area/tcommsat/server) "aOy" = ( -/obj/machinery/computer/telecomms/server{ - dir = 8 - }, /obj/machinery/newscaster{ pixel_x = 32 }, @@ -25765,14 +22139,7 @@ pixel_x = 24; pixel_y = -24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/computer/telecomms/server{ dir = 8 }, /turf/open/floor/plasteel/dark, @@ -25867,6 +22234,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/engine, /area/engineering/main) "aOH" = ( @@ -25882,15 +22250,6 @@ }, /turf/open/space/basic, /area/solars/port/aft) -"aOI" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 - }, -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/turf/open/floor/plating, -/area/maintenance/port/aft) "aOJ" = ( /obj/structure/cable/white{ icon_state = "4-8" @@ -25937,9 +22296,6 @@ "aOL" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /turf/open/floor/plating, /area/maintenance/port/aft) "aOM" = ( @@ -25947,49 +22303,27 @@ /obj/item/paper_bin, /obj/item/pen, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/maintenance/port/aft) "aON" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, /area/maintenance/port/aft) "aOO" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/status_display{ - pixel_y = 32 - }, /obj/structure/cable/white{ icon_state = "4-8" }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/obj/machinery/status_display/ai{ + pixel_y = 32 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/port/aft) "aOP" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, @@ -25999,9 +22333,6 @@ /obj/structure/cable/white{ icon_state = "1-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -26034,11 +22365,16 @@ /turf/open/floor/plasteel/white, /area/medical/genetics) "aOS" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ +/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 }, -/turf/closed/wall, -/area/maintenance/port/aft) +/turf/open/floor/plasteel, +/area/engineering/atmos) "aOT" = ( /obj/structure/cable/white{ icon_state = "1-4" @@ -26055,12 +22391,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/machinery/airalarm{ pixel_y = 24 }, @@ -26183,12 +22513,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/aft) "aPe" = ( @@ -26344,9 +22668,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aPq" = ( @@ -26368,9 +22689,6 @@ /obj/structure/cable/white{ icon_state = "0-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aPr" = ( @@ -26384,9 +22702,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aPs" = ( @@ -26399,9 +22714,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aPt" = ( @@ -26414,9 +22726,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aPu" = ( @@ -26427,9 +22736,6 @@ /obj/structure/cable/white{ icon_state = "1-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "aPv" = ( @@ -26468,9 +22774,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "aPx" = ( @@ -26483,20 +22786,15 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "aPy" = ( /obj/structure/table, /obj/item/storage/briefcase, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/starboard) "aPz" = ( /obj/effect/turf_decal/delivery, @@ -26516,10 +22814,6 @@ pixel_x = -3; pixel_y = -3 }, -/obj/machinery/airalarm{ - dir = 1; - pixel_y = -22 - }, /obj/structure/disposalpipe/segment, /turf/open/floor/plasteel, /area/medical/medbay/zone3) @@ -26528,11 +22822,11 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/firedoor, /obj/machinery/door/airlock/grunge{ name = "Morgue"; req_access_txt = "5" }, -/obj/machinery/door/firedoor, /turf/open/floor/plasteel/dark, /area/medical/morgue) "aPB" = ( @@ -26576,10 +22870,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel/dark, /area/medical/morgue) "aPF" = ( @@ -26601,10 +22891,6 @@ /turf/open/floor/plating, /area/tcommsat/server) "aPH" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral, /obj/structure/disposalpipe/trunk{ dir = 1 }, @@ -26673,7 +22959,7 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 + dir = 9 }, /turf/open/floor/engine, /area/engineering/main) @@ -26700,9 +22986,15 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "aPQ" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plating, -/area/maintenance/port/aft) +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) "aPR" = ( /turf/open/floor/wood{ icon_state = "wood-broken5" @@ -26721,24 +23013,19 @@ }, /area/maintenance/port/aft) "aPU" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock{ + id_tag = "Dorm2"; + name = "Dorm 2" }, -/turf/closed/wall, -/area/maintenance/port/aft) +/turf/open/floor/carpet, +/area/commons/dorms) "aPV" = ( /obj/structure/barricade/wooden, /obj/machinery/door/airlock/maintenance_hatch{ name = "Maintenance Hatch"; req_access_txt = "12" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/maintenance/port/aft) "aPW" = ( @@ -26747,47 +23034,28 @@ dir = 4; pixel_x = -24 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/obj/machinery/status_display/evac{ + pixel_y = -32 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/port/aft) "aPX" = ( /obj/item/kirbyplants{ icon_state = "plant-21" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/camera{ - c_tag = "Central Primary Hallway South-West"; - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, /area/hallway/primary/port/aft) "aPY" = ( -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, /obj/machinery/navbeacon{ codes_txt = "patrol;next_patrol=9.2-EnteringEngi"; location = "9.1-Library" }, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, /turf/open/floor/plasteel{ @@ -26802,9 +23070,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -26816,18 +23081,12 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, /area/hallway/primary/port/aft) "aQb" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -26837,21 +23096,12 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/aft) "aQd" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -26862,17 +23112,11 @@ dir = 8; network = list("ss13","medbay") }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /obj/machinery/computer/scan_consolenew{ dir = 1 }, /obj/effect/turf_decal/bot, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/medical/genetics) "aQf" = ( /obj/machinery/firealarm{ @@ -26882,9 +23126,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -26899,16 +23140,6 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "aQh" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /obj/machinery/airalarm{ dir = 4; pixel_x = -22 @@ -26916,16 +23147,6 @@ /turf/open/floor/plasteel/dark, /area/medical/morgue) "aQi" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, @@ -27070,7 +23291,6 @@ dir = 4 }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "aQy" = ( @@ -27081,7 +23301,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "aQz" = ( @@ -27092,7 +23311,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "aQA" = ( @@ -27103,36 +23321,19 @@ pixel_y = -32 }, /obj/machinery/camera{ - c_tag = "Starboard Primary Hallway 3"; + c_tag = "Starboard Primary Hallway"; dir = 1 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/hallway/primary/starboard) -"aQB" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, +/area/hallway/primary/starboard) +"aQB" = ( /obj/structure/sign/poster/contraband/random, /turf/closed/wall, /area/maintenance/port/aft) "aQC" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, @@ -27147,16 +23348,6 @@ icon_state = "2-4" }, /obj/effect/landmark/blobstart, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, @@ -27170,11 +23361,15 @@ /turf/open/floor/plating/asteroid, /area/command/heads_quarters/rd) "aQF" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/obj/structure/sign/warning/fire{ + desc = "A sign that states the labeled room's number."; + icon_state = "roomnum"; + name = "Room Number 1"; + pixel_x = -1; + pixel_y = 26 }, -/turf/closed/wall/rust, -/area/maintenance/port/aft) +/turf/open/floor/plasteel/white/corner, +/area/commons/dorms) "aQG" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 6 @@ -27183,16 +23378,6 @@ /obj/effect/turf_decal/stripes/corner{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) "aQH" = ( @@ -27200,16 +23385,12 @@ icon_state = "1-2" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper, -/obj/machinery/door/airlock/command{ - name = "Telecomms Server Room"; - req_access_txt = "61" - }, -/obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/engineering/glass{ + name = "Server Room"; + req_access_txt = "61" }, /turf/open/floor/plasteel/grimy, /area/tcommsat/server) @@ -27218,12 +23399,6 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/medical/morgue) "aQJ" = ( @@ -27240,38 +23415,27 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + name = "Loop to Freezer" }, /turf/open/floor/engine, /area/engineering/main) "aQL" = ( /obj/structure/table/wood, /obj/item/clothing/gloves/color/latex, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/medical/morgue) "aQM" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/machinery/atmospherics/components/trinary/filter/critical{ - dir = 4 - }, /turf/open/floor/engine, /area/engineering/main) "aQN" = ( /obj/effect/turf_decal/stripes/line{ dir = 5 }, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 - }, /turf/open/floor/engine, /area/engineering/main) "aQO" = ( @@ -27280,9 +23444,6 @@ network = list("ss13","engine"); pixel_x = 23 }, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 - }, /obj/effect/turf_decal/loading_area{ dir = 1 }, @@ -27292,26 +23453,19 @@ /obj/effect/turf_decal/stripes/line{ dir = 9 }, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 - }, /turf/open/floor/engine, /area/engineering/main) "aQQ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/barricade/wooden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /turf/open/floor/plating, /area/maintenance/port/aft) "aQR" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/machinery/meter, -/obj/machinery/atmospherics/pipe/manifold/orange/visible{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 6 }, /turf/open/floor/engine, /area/engineering/main) @@ -27329,42 +23483,25 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/structure/closet/secure_closet/engineering_electrical, /turf/open/floor/engine, /area/engineering/main) "aQU" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel, -/area/maintenance/port/aft) -"aQV" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/light/small{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) +"aQV" = ( /obj/machinery/computer/arcade{ dir = 4 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, /area/maintenance/port/aft) "aQW" = ( /turf/closed/wall, @@ -27375,28 +23512,20 @@ /area/service/library) "aQY" = ( /obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/airlock/public/glass{ name = "Library Access" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/service/library) "aQZ" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/public/glass{ - name = "Library Access" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/public/glass{ + name = "Library Access" }, /turf/open/floor/plasteel, /area/service/library) @@ -27416,9 +23545,19 @@ /turf/open/floor/wood, /area/maintenance/port/aft) "aRe" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall/r_wall, -/area/medical/virology) +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/sign/warning/fire{ + desc = "A sign that states the labeled room's number."; + dir = 4; + icon_state = "roomnum"; + name = "Room Number 3"; + pixel_x = -1; + pixel_y = -24 + }, +/turf/open/floor/plasteel/white/corner, +/area/commons/dorms) "aRf" = ( /turf/closed/wall, /area/medical/chemistry) @@ -27501,10 +23640,6 @@ /obj/structure/bodycontainer/morgue{ dir = 2 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral, /obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/medical/morgue) @@ -27542,58 +23677,42 @@ /area/science/lab) "aRu" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/research{ - name = "Research Division Access"; - req_access_txt = "47" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/research{ + name = "Research Division Access"; + req_access_txt = "47" }, /turf/open/floor/plasteel, /area/science/research) "aRv" = ( /obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/airlock/research{ name = "Research Division Access"; req_access_txt = "47" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/science/research) "aRw" = ( /obj/structure/bodycontainer/morgue{ dir = 2 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, /turf/open/floor/plasteel/dark, /area/medical/morgue) "aRx" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, /turf/open/floor/plating, /area/maintenance/starboard/aft) @@ -27642,10 +23761,6 @@ /obj/item/clipboard, /obj/item/storage/firstaid/o2, /obj/item/crowbar, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/tcommsat/server) "aRC" = ( @@ -27656,35 +23771,24 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/tcommsat/server) "aRE" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on, /turf/open/floor/plasteel/dark, /area/tcommsat/server) "aRF" = ( /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/item/radio/intercom{ - name = "Station Intercom"; - pixel_x = -28 - }, /obj/effect/turf_decal/stripes/line{ dir = 8 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/closet/secure_closet/engineering_electrical, /turf/open/floor/engine, /area/engineering/main) "aRG" = ( @@ -27694,21 +23798,10 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/atmospherics/components/binary/pump/on{ - name = "Gas to Cooling Loop" - }, +/obj/machinery/atmospherics/pipe/simple/general/visible, /turf/open/floor/engine, /area/engineering/main) "aRH" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/engine, -/area/engineering/main) -"aRI" = ( /obj/structure/cable/white{ icon_state = "4-8" }, @@ -27717,12 +23810,21 @@ }, /turf/open/floor/engine, /area/engineering/main) +"aRI" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 5 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/engineering/main) "aRJ" = ( /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 5 +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 }, /turf/open/floor/engine, /area/engineering/main) @@ -27746,6 +23848,7 @@ dir = 4 }, /obj/effect/turf_decal/bot, +/obj/machinery/meter, /turf/open/floor/plasteel/dark, /area/engineering/main) "aRM" = ( @@ -27758,9 +23861,8 @@ /turf/open/floor/engine, /area/engineering/main) "aRN" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 4; - name = "Freezer to Gas" +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 }, /turf/open/floor/engine, /area/engineering/main) @@ -27777,10 +23879,7 @@ /turf/open/floor/engine, /area/engineering/main) "aRQ" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ - dir = 1; - name = "Gas to Cooling Loop" - }, +/obj/machinery/atmospherics/pipe/simple/general/visible, /turf/open/floor/engine, /area/engineering/main) "aRR" = ( @@ -27811,36 +23910,24 @@ c_tag = "Library 2"; dir = 4 }, -/turf/open/floor/plasteel/dark, +/obj/structure/sign/painting/library{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aRU" = ( /obj/structure/table/wood, /obj/item/folder, /obj/item/pen, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/structure/sign/painting/library{ + pixel_x = 32 }, /turf/open/floor/plasteel/dark, /area/service/library) "aRV" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/structure/cable/white{ icon_state = "1-2" }, @@ -27854,16 +23941,6 @@ name = "Station Intercom"; pixel_y = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/library) "aRX" = ( @@ -27872,7 +23949,9 @@ /obj/machinery/newscaster{ pixel_y = 32 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aRY" = ( /obj/structure/table/wood, @@ -27884,23 +23963,15 @@ }, /obj/item/paper_bin, /obj/item/pen, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/library) "aRZ" = ( /obj/structure/chair/office/dark{ dir = 8 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aSa" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -27916,16 +23987,6 @@ "aSc" = ( /obj/structure/table/wood, /obj/machinery/computer/libraryconsole, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/library) "aSd" = ( @@ -27934,7 +23995,12 @@ /obj/machinery/newscaster{ pixel_x = 32 }, -/turf/open/floor/plasteel/dark, +/obj/structure/sign/painting/library{ + pixel_x = 32 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aSe" = ( /obj/machinery/vending/wallmed{ @@ -27947,6 +24013,10 @@ dir = 1 }, /obj/machinery/holopad, +/obj/machinery/light_switch{ + pixel_x = 12; + pixel_y = 32 + }, /turf/open/floor/plasteel/white, /area/medical/virology) "aSf" = ( @@ -27957,12 +24027,12 @@ dir = 8 }, /obj/machinery/shieldgen, -/turf/open/floor/plasteel, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/maintenance/port/aft) "aSg" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/item/cigbutt, /turf/open/floor/plating, /area/maintenance/port/aft) @@ -27989,7 +24059,9 @@ /obj/structure/closet/secure_closet/medical1, /obj/item/storage/box/beakers, /obj/item/storage/box/pillbottles, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/medical/chemistry) "aSk" = ( /obj/structure/cable/white{ @@ -28011,16 +24083,7 @@ /turf/open/floor/plasteel, /area/medical/chemistry) "aSm" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/maintenance/port/aft) "aSn" = ( @@ -28038,17 +24101,11 @@ /turf/open/floor/plasteel, /area/medical/chemistry) "aSo" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /obj/effect/landmark/event_spawn, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = -24 + }, /turf/open/floor/plasteel/dark, /area/medical/morgue) "aSp" = ( @@ -28071,9 +24128,6 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "aSr" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 4 }, @@ -28088,10 +24142,6 @@ "aSt" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "aSu" = ( @@ -28255,29 +24305,15 @@ }, /area/maintenance/port/aft) "aSM" = ( -/obj/machinery/door/airlock/command{ - name = "Telecomms Server Room"; - req_access_txt = "61" - }, /obj/structure/cable{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/door/airlock/engineering/glass{ + name = "Server Room"; + req_access_txt = "61" }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) @@ -28296,23 +24332,14 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, -/obj/machinery/vending/wardrobe/engi_wardrobe, +/obj/machinery/vending/tool, /turf/open/floor/engine, /area/engineering/main) "aSQ" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/machinery/door/airlock/maintenance_hatch{ name = "Maintenance Hatch"; req_access_txt = "12" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /turf/open/floor/plating, /area/maintenance/port/aft) "aSR" = ( @@ -28341,18 +24368,6 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/engine, /area/engineering/main) -"aSU" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/thermomachine/heater/on{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/engine, -/area/engineering/main) "aSV" = ( /obj/machinery/power/emitter/anchored{ dir = 1; @@ -28370,11 +24385,8 @@ /obj/machinery/atmospherics/components/unary/thermomachine/freezer/on{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/effect/turf_decal/stripes/end{ + dir = 1 }, /turf/open/floor/engine, /area/engineering/main) @@ -28428,64 +24440,40 @@ dir = 8 }, /obj/effect/landmark/start/assistant, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aTd" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/library) "aTe" = ( /obj/structure/chair/office/dark{ dir = 4 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aTf" = ( /obj/structure/table/wood, /obj/item/clipboard, /obj/item/storage/dice, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/library) "aTg" = ( /obj/structure/table/wood, /obj/item/folder, /obj/item/pen/red, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aTh" = ( /obj/structure/chair/office/dark{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/library) "aTi" = ( @@ -28493,12 +24481,11 @@ dir = 4 }, /obj/effect/landmark/start/librarian, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aTj" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 8 }, @@ -28586,7 +24573,9 @@ dir = 6 }, /obj/machinery/vending/wardrobe/chem_wardrobe, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/medical/chemistry) "aTr" = ( /obj/structure/cable/white{ @@ -28617,15 +24606,13 @@ /turf/open/floor/plasteel, /area/medical/chemistry) "aTv" = ( -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -22 +/obj/machinery/door/airlock/virology/glass{ + name = "Isolation Room"; + req_access_txt = "39" }, -/obj/machinery/light/small{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 }, /turf/open/floor/plasteel/freezer, /area/medical/virology) @@ -28641,58 +24628,38 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "aTy" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp, /turf/open/floor/plasteel/grimy, -/area/commons/lounge) +/area/hallway/primary/aft) "aTz" = ( /obj/structure/chair/comfy/brown, /turf/open/floor/plasteel/grimy, -/area/commons/lounge) +/area/hallway/primary/aft) "aTA" = ( /obj/item/kirbyplants{ icon_state = "plant-18" }, -/obj/machinery/camera{ - c_tag = "Arrivals Lounge" - }, /turf/open/floor/plasteel/grimy, -/area/commons/lounge) +/area/hallway/primary/aft) "aTB" = ( /obj/structure/chair/comfy/brown, /obj/effect/landmark/start/assistant, /turf/open/floor/plasteel/grimy, -/area/commons/lounge) +/area/hallway/primary/aft) "aTC" = ( /obj/structure/table/wood, /obj/item/storage/fancy/donut_box, +/obj/machinery/camera{ + c_tag = "Arrivals Lounge" + }, /turf/open/floor/plasteel/grimy, -/area/commons/lounge) +/area/hallway/primary/aft) "aTD" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "aTE" = ( @@ -28736,16 +24703,6 @@ /area/science/lab) "aTI" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, /turf/open/floor/plasteel, /area/science/lab) "aTJ" = ( @@ -28765,10 +24722,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 9 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/lab) "aTL" = ( @@ -28804,21 +24757,15 @@ /turf/open/floor/plasteel/white, /area/science/research) "aTO" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Science Maintenance"; - req_access_txt = "47" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Science Maintenance"; + req_access_txt = "47" }, /turf/open/floor/plating, /area/science/research) @@ -28892,23 +24839,18 @@ /obj/machinery/light/small{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 }, /turf/open/floor/plasteel/dark, /area/maintenance/port/aft) "aTW" = ( -/obj/structure/bed, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, +/obj/machinery/light/small{ + dir = 4 + }, /turf/open/floor/plasteel/freezer, /area/medical/virology) "aTX" = ( @@ -28916,16 +24858,6 @@ dir = 8 }, /obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) "aTY" = ( @@ -28936,16 +24868,6 @@ dir = 4 }, /obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) "aTZ" = ( @@ -28956,16 +24878,6 @@ dir = 9 }, /obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) "aUa" = ( @@ -28973,21 +24885,14 @@ /turf/closed/wall/r_wall/rust, /area/engineering/main) "aUb" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/landmark/event_spawn, /obj/structure/cable/white{ icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/maintenance/port/aft) "aUc" = ( @@ -29001,7 +24906,9 @@ /obj/structure/cable/white{ icon_state = "0-4" }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aUd" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -29040,7 +24947,9 @@ /turf/open/floor/wood, /area/service/library) "aUh" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, /turf/closed/wall/r_wall, /area/medical/virology) "aUi" = ( @@ -29048,7 +24957,12 @@ /area/maintenance/port/aft) "aUj" = ( /obj/machinery/photocopier, -/turf/open/floor/plasteel/dark, +/obj/structure/sign/painting/library{ + pixel_x = 32 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aUk" = ( /obj/structure/table/wood, @@ -29061,31 +24975,15 @@ /obj/structure/sign/poster/contraband/random{ pixel_y = -32 }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/maintenance/port/aft) "aUm" = ( /obj/machinery/computer/slot_machine, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/maintenance/port/aft) "aUn" = ( /obj/effect/spawner/structure/window/reinforced/tinted, @@ -29118,17 +25016,9 @@ pixel_y = 5 }, /obj/item/reagent_containers/syringe, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/corner{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/maintenance/port/aft) "aUq" = ( /obj/structure/table/wood, @@ -29146,6 +25036,7 @@ /obj/structure/cable/white{ icon_state = "0-4" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/port/aft) "aUr" = ( @@ -29153,16 +25044,12 @@ /turf/closed/wall, /area/medical/chemistry) "aUs" = ( -/obj/structure/table/glass, /obj/machinery/reagentgrinder{ pixel_y = 5 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/obj/structure/table/glass, +/turf/open/floor/plasteel, /area/medical/chemistry) "aUt" = ( /obj/effect/turf_decal/bot, @@ -29182,6 +25069,7 @@ /obj/structure/cable/white{ icon_state = "1-8" }, +/obj/effect/turf_decal/trimline/green/line, /turf/open/floor/plating, /area/maintenance/port/aft) "aUv" = ( @@ -29200,48 +25088,34 @@ dir = 4 }, /obj/structure/closet/crate/bin, -/turf/open/floor/plasteel/white, +/turf/open/floor/plasteel, /area/medical/chemistry) "aUx" = ( /obj/structure/chair/comfy/brown{ dir = 4 }, /turf/open/floor/plasteel/grimy, -/area/commons/lounge) +/area/hallway/primary/aft) "aUy" = ( /turf/open/floor/carpet, -/area/commons/lounge) +/area/hallway/primary/aft) "aUz" = ( /obj/structure/chair/comfy/brown{ dir = 8 }, /turf/open/floor/plasteel/grimy, -/area/commons/lounge) +/area/hallway/primary/aft) "aUA" = ( /obj/machinery/rnd/destructive_analyzer, /obj/effect/turf_decal/stripes/line{ dir = 9 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/lab) "aUB" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/lab) "aUC" = ( @@ -29250,10 +25124,6 @@ dir = 5 }, /obj/machinery/rnd/production/protolathe/department/science, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/science/lab) "aUD" = ( @@ -29286,10 +25156,6 @@ dir = 8 }, /obj/item/multitool, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/lab) "aUF" = ( @@ -29342,36 +25208,31 @@ /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = -32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/effect/turf_decal/trimline/green/line, /turf/open/floor/plasteel/dark, /area/maintenance/port/aft) "aUK" = ( /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/effect/mapping_helpers/airlock/locked, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 }, /obj/machinery/door/airlock/virology{ - name = "Virology Access"; + autoclose = 0; + frequency = 1449; + id_tag = "virology_airlock_interior"; + name = "Virology Interior Airlock"; req_access_txt = "39" }, -/obj/machinery/door/firedoor, /turf/open/floor/plasteel, /area/medical/virology) "aUL" = ( @@ -29386,16 +25247,12 @@ /area/maintenance/port/aft) "aUM" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Medbay Maintenance"; - req_access_txt = "5" - }, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Medbay Maintenance"; + req_access_txt = "5" }, /turf/open/floor/plasteel, /area/maintenance/port/aft) @@ -29405,8 +25262,7 @@ icon_state = "1-2" }, /obj/effect/turf_decal/trimline/green/line{ - dir = 8; - icon_state = "trimline" + dir = 9 }, /turf/open/floor/plating, /area/maintenance/port/aft) @@ -29421,16 +25277,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) "aUP" = ( @@ -29481,16 +25327,6 @@ pixel_x = -26 }, /obj/machinery/libraryscanner, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/library) "aUW" = ( @@ -29517,8 +25353,7 @@ dir = 4 }, /obj/effect/turf_decal/trimline/green/line{ - dir = 1; - icon_state = "trimline" + dir = 1 }, /turf/open/floor/plating, /area/maintenance/port/aft) @@ -29531,8 +25366,7 @@ dir = 1 }, /obj/effect/turf_decal/trimline/green/line{ - dir = 1; - icon_state = "trimline" + dir = 1 }, /turf/open/floor/plating, /area/maintenance/port/aft) @@ -29547,16 +25381,7 @@ name = "Station Intercom"; pixel_x = 26 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/item/chisel, /turf/open/floor/plasteel/dark, /area/service/library) "aVc" = ( @@ -29574,8 +25399,7 @@ }, /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/trimline/green/line{ - dir = 1; - icon_state = "trimline" + dir = 1 }, /turf/open/floor/plating{ icon_state = "panelscorched" @@ -29596,8 +25420,7 @@ }, /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/trimline/green/line{ - dir = 1; - icon_state = "trimline" + dir = 1 }, /turf/open/floor/plating, /area/maintenance/port/aft) @@ -29610,8 +25433,7 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/trimline/green/line{ - dir = 1; - icon_state = "trimline" + dir = 1 }, /turf/open/floor/plating, /area/maintenance/port/aft) @@ -29630,8 +25452,7 @@ dir = 1 }, /obj/effect/turf_decal/trimline/green/corner{ - dir = 1; - icon_state = "trimline_corner" + dir = 1 }, /turf/open/floor/plating, /area/maintenance/port/aft) @@ -29702,16 +25523,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "aVp" = ( @@ -29719,32 +25530,16 @@ dir = 8 }, /turf/open/floor/plasteel/grimy, -/area/commons/lounge) +/area/hallway/primary/aft) "aVq" = ( /obj/machinery/holopad, /turf/open/floor/carpet, -/area/commons/lounge) +/area/hallway/primary/aft) "aVr" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, /turf/open/floor/plasteel/grimy, -/area/commons/lounge) -"aVs" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, /area/hallway/primary/aft) "aVt" = ( /obj/machinery/computer/rdconsole/core{ @@ -29763,10 +25558,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/lab) "aVu" = ( @@ -29776,16 +25567,6 @@ icon_state = "2-8" }, /obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/lab) "aVv" = ( @@ -29795,10 +25576,6 @@ dir = 6 }, /obj/machinery/rnd/production/circuit_imprinter/department/science, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/science/lab) "aVw" = ( @@ -29814,10 +25591,6 @@ /obj/item/integrated_electronics/analyzer, /obj/item/integrated_electronics/debugger, /obj/item/integrated_electronics/wirer, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/lab) "aVy" = ( @@ -29842,11 +25615,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/obj/machinery/camera{ - c_tag = "Engineering Access"; - dir = 8; - network = list("ss13","engine") - }, /obj/effect/turf_decal/stripes/line{ dir = 6 }, @@ -29864,16 +25632,6 @@ /turf/open/floor/circuit/green/telecomms/mainframe, /area/science/research) "aVC" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark/telecomms, /area/science/research) "aVD" = ( @@ -29893,31 +25651,31 @@ /turf/closed/wall/r_wall, /area/science/research) "aVF" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock{ + id_tag = "Dorm3"; + name = "Dorm 3" }, -/turf/open/floor/plating, -/area/maintenance/port/aft) +/turf/open/floor/wood, +/area/commons/dorms) "aVG" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/turf/open/floor/plating{ + icon_state = "platingdmg2" }, -/turf/open/floor/plating, /area/maintenance/port/aft) "aVH" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock{ + id_tag = "Dorm4"; + name = "Room Four" }, -/turf/open/floor/plating, -/area/maintenance/port/aft) +/turf/open/floor/plasteel/grimy, +/area/commons/dorms) "aVI" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, /obj/effect/turf_decal/trimline/green/line{ - dir = 9; - icon_state = "trimline" + dir = 9 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/port/aft) "aVJ" = ( @@ -29928,8 +25686,7 @@ icon_state = "2-4" }, /obj/effect/turf_decal/trimline/green/line{ - dir = 1; - icon_state = "trimline" + dir = 1 }, /turf/open/floor/plating, /area/maintenance/port/aft) @@ -29955,8 +25712,7 @@ icon_state = "1-8" }, /obj/effect/turf_decal/trimline/green/corner{ - dir = 1; - icon_state = "trimline_corner" + dir = 1 }, /turf/open/floor/plating, /area/maintenance/port/aft) @@ -29967,19 +25723,15 @@ /obj/machinery/status_display{ pixel_x = -32 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aVO" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/door/window/northright{ + name = "Library Desk Door"; + req_access_txt = "37" }, /turf/open/floor/plasteel/dark, /area/service/library) @@ -29987,19 +25739,11 @@ /obj/structure/table/wood, /obj/item/flashlight/lamp, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aVQ" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/library) "aVR" = ( @@ -30030,7 +25774,9 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aVU" = ( /obj/effect/turf_decal/tile/neutral{ @@ -30047,9 +25793,13 @@ /turf/open/floor/plasteel/dark, /area/service/library) "aVV" = ( -/obj/structure/bookcase/random/religion, -/turf/open/floor/plasteel/dark, -/area/service/library) +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/brig) "aVW" = ( /obj/structure/rack, /obj/item/storage/toolbox/mechanical, @@ -30068,13 +25818,11 @@ /obj/structure/extinguisher_cabinet{ pixel_x = 26 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aVY" = ( -/obj/machinery/door/airlock/grunge{ - name = "Crematorium"; - req_access_txt = "27" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" @@ -30083,23 +25831,13 @@ dir = 4 }, /obj/effect/mapping_helpers/airlock/cyclelink_helper, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/obj/machinery/door/airlock/grunge{ + name = "Crematorium"; + req_access_txt = "27" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plating, /area/maintenance/port/aft) "aVZ" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" @@ -30107,9 +25845,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, /turf/open/floor/plating, /area/maintenance/port/aft) @@ -30218,13 +25956,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/white, /area/medical/chemistry) "aWj" = ( /obj/structure/table/glass, @@ -30260,6 +25992,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/item/screwdriver, /turf/open/floor/plasteel, /area/medical/chemistry) "aWk" = ( @@ -30298,7 +26031,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/medical/medbay/zone3) "aWn" = ( /obj/machinery/firealarm{ @@ -30325,10 +26060,6 @@ }, /obj/item/stock_parts/cell/high, /obj/item/stock_parts/cell/high, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/lab) "aWp" = ( @@ -30366,16 +26097,6 @@ /obj/machinery/atmospherics/pipe/simple/general/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark/telecomms, /area/science/research) "aWu" = ( @@ -30386,18 +26107,12 @@ /turf/open/floor/circuit/green/telecomms/mainframe, /area/science/research) "aWv" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, /turf/open/floor/plating, /area/maintenance/port/aft) @@ -30407,8 +26122,7 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/trimline/green/line{ - dir = 8; - icon_state = "trimline" + dir = 8 }, /turf/open/floor/plating, /area/maintenance/port/aft) @@ -30443,16 +26157,6 @@ /obj/machinery/light_switch{ pixel_y = -24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/library) "aWB" = ( @@ -30461,7 +26165,9 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aWC" = ( /obj/structure/table/wood, @@ -30471,24 +26177,18 @@ }, /obj/item/camera_film, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/library) "aWD" = ( /obj/machinery/holopad, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aWE" = ( -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aWF" = ( /obj/structure/cable/white{ @@ -30503,16 +26203,6 @@ /obj/machinery/status_display{ pixel_x = 32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/library) "aWH" = ( @@ -30530,6 +26220,12 @@ /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/newscaster{ + pixel_y = 32 + }, /turf/open/floor/plasteel/white, /area/medical/virology) "aWJ" = ( @@ -30537,15 +26233,15 @@ dir = 1 }, /obj/effect/turf_decal/delivery, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, /obj/structure/cable/white{ icon_state = "4-8" }, /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, /turf/open/floor/plasteel/white, /area/medical/virology) "aWK" = ( @@ -30557,46 +26253,47 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/newscaster{ - pixel_x = 32 +/obj/machinery/doorButtons/access_button{ + idDoor = "virology_airlock_interior"; + idSelf = "virology_airlock_control"; + name = "Virology Access Button"; + pixel_x = 24; + req_access_txt = "39" }, /turf/open/floor/plasteel, /area/medical/virology) "aWM" = ( -/obj/machinery/door/airlock/virology{ - name = "Virology Access"; - req_access_txt = "39" - }, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, +/obj/effect/mapping_helpers/airlock/locked, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/airlock/virology{ + autoclose = 0; + frequency = 1449; + id_tag = "virology_airlock_exterior"; + name = "Virology Exterior Airlock"; + req_access_txt = "39" + }, /turf/open/floor/plasteel/white, /area/medical/virology) "aWN" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/medical/glass{ - name = "Chemistry Lab"; - req_access_txt = "5; 33" - }, /obj/structure/cable/white{ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/medical/glass{ + name = "Chemistry Lab"; + req_access_txt = "5; 33" }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white, /area/medical/chemistry) "aWO" = ( /obj/effect/spawner/structure/window/reinforced, @@ -30610,7 +26307,7 @@ /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/chips, /turf/open/floor/plasteel/grimy, -/area/commons/lounge) +/area/hallway/primary/aft) "aWQ" = ( /obj/structure/chair/comfy/brown{ buildstackamount = 0; @@ -30622,7 +26319,7 @@ pixel_y = -22 }, /turf/open/floor/plasteel/grimy, -/area/commons/lounge) +/area/hallway/primary/aft) "aWR" = ( /obj/item/kirbyplants{ icon_state = "plant-21"; @@ -30634,7 +26331,7 @@ pixel_y = -32 }, /turf/open/floor/plasteel/grimy, -/area/commons/lounge) +/area/hallway/primary/aft) "aWS" = ( /obj/structure/chair/comfy/brown{ buildstackamount = 0; @@ -30645,24 +26342,23 @@ pixel_y = -24 }, /turf/open/floor/plasteel/grimy, -/area/commons/lounge) +/area/hallway/primary/aft) "aWT" = ( /obj/structure/table/wood, /obj/item/folder, /obj/item/pen, /turf/open/floor/plasteel/grimy, -/area/commons/lounge) +/area/hallway/primary/aft) "aWU" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/research{ - name = "Research and Development Lab"; - req_one_access_txt = "7;29" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, +/obj/machinery/door/airlock/research{ + name = "Research and Development Lab"; + req_one_access_txt = "7;29" + }, /turf/open/floor/plasteel, /area/science/lab) "aWV" = ( @@ -30709,20 +26405,6 @@ name = "Server Access"; req_access_txt = "30" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/research) "aXa" = ( @@ -30753,7 +26435,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/machinery/light/small, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, @@ -30761,8 +26442,14 @@ icon_state = "4-8" }, /obj/effect/turf_decal/trimline/green/corner{ - dir = 1; - icon_state = "trimline_corner" + dir = 1 + }, +/obj/machinery/doorButtons/access_button{ + idDoor = "virology_airlock_exterior"; + idSelf = "virology_airlock_control"; + name = "Virology Access Button"; + pixel_y = -24; + req_access_txt = "39" }, /turf/open/floor/plating, /area/maintenance/port/aft) @@ -30772,6 +26459,9 @@ /obj/structure/cable/white{ icon_state = "1-8" }, +/obj/machinery/light/small{ + dir = 4 + }, /turf/open/floor/plating, /area/maintenance/port/aft) "aXf" = ( @@ -30779,22 +26469,17 @@ /turf/closed/wall, /area/service/library) "aXg" = ( -/obj/structure/sign/painting{ +/obj/structure/sign/painting/library{ pixel_y = -32 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aXh" = ( /obj/machinery/light, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/structure/sign/painting/library{ + pixel_y = -32 }, /turf/open/floor/plasteel/dark, /area/service/library) @@ -30813,17 +26498,7 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "aXj" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/structure/sign/painting{ +/obj/structure/sign/painting/library{ pixel_y = -32 }, /turf/open/floor/plasteel/dark, @@ -30836,7 +26511,12 @@ c_tag = "Library 1"; dir = 8 }, -/turf/open/floor/plasteel/dark, +/obj/structure/sign/painting/library{ + pixel_x = 32 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, /area/service/library) "aXm" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -30940,17 +26620,13 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "aXv" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, /turf/open/floor/plasteel, /area/maintenance/port/aft) @@ -30958,26 +26634,16 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "aXx" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/research{ - name = "Research Division Access"; - req_access_txt = "47" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/research{ + name = "Research Division Access"; + req_access_txt = "47" }, /turf/open/floor/plasteel, /area/science/research) @@ -31045,10 +26711,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/firealarm{ - dir = 1; - pixel_y = -26 - }, /turf/open/floor/plasteel, /area/medical/virology) "aXE" = ( @@ -31066,23 +26728,17 @@ /turf/open/floor/plasteel/white, /area/science/research) "aXF" = ( -/obj/machinery/door/airlock/command{ - name = "Research Division Server Room"; - req_access_txt = "30" - }, /obj/structure/cable/white{ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/machinery/door/airlock/command{ + name = "Research Division Server Room"; + req_access_txt = "30" }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/science/research) "aXG" = ( /obj/machinery/atmospherics/pipe/simple/general/hidden, @@ -31092,16 +26748,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/research) "aXH" = ( @@ -31114,16 +26760,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/research) "aXI" = ( @@ -31135,16 +26771,6 @@ pixel_x = 24 }, /obj/item/clothing/suit/armor/reactive/teleport, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/research) "aXJ" = ( @@ -31178,16 +26804,12 @@ /area/service/library) "aXN" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/decal/cleanable/dirt/dust, /obj/machinery/door/airlock/maintenance_hatch{ name = "Maintenance Hatch"; req_access_txt = "12" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/plasteel, +/turf/open/floor/wood, /area/maintenance/port/aft) "aXO" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -31204,10 +26826,6 @@ /area/medical/medbay/zone3) "aXQ" = ( /obj/structure/closet/secure_closet/medical3, -/obj/item/radio/intercom{ - name = "Station Intercom"; - pixel_y = 26 - }, /obj/machinery/light_switch{ pixel_x = 24; pixel_y = 24 @@ -31224,6 +26842,11 @@ /obj/item/clothing/neck/stethoscope, /obj/item/clothing/neck/stethoscope, /obj/item/gun/syringe/dart, +/obj/item/radio/intercom{ + frequency = 1485; + name = "Station Intercom (Medbay)"; + pixel_y = 30 + }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "aXR" = ( @@ -31232,26 +26855,18 @@ /turf/open/floor/plating, /area/medical/medbay/zone3) "aXS" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 6 }, -/turf/open/floor/plasteel, +/obj/machinery/sleeper{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/medical/medbay/zone3) "aXT" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "aXU" = ( @@ -31278,16 +26893,6 @@ /area/medical/medbay/zone3) "aXX" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "aXY" = ( @@ -31321,26 +26926,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) -"aYc" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "aYd" = ( @@ -31350,43 +26935,17 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "aYe" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 }, -/obj/machinery/power/apc{ - areastring = "/area/commons/lounge"; - dir = 1; - name = "Lounge APC"; - pixel_y = 23 - }, -/obj/structure/cable/white{ - icon_state = "0-2" - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) +/turf/open/floor/plasteel/white/corner, +/area/commons/dorms) "aYf" = ( /obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "aYg" = ( @@ -31394,26 +26953,16 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "aYh" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/research{ - name = "Research Division Access"; - req_access_txt = "47" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/research{ + name = "Research Division Access"; + req_access_txt = "47" }, /turf/open/floor/plasteel, /area/science/research) @@ -31496,23 +27045,13 @@ /area/science/research) "aYp" = ( /obj/machinery/camera{ - c_tag = "Communications Relay"; + c_tag = "Telecommunications Relay"; dir = 8; network = list("ss13","tcomms") }, /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) "aYq" = ( @@ -31526,16 +27065,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/research) "aYr" = ( @@ -31553,16 +27082,6 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/research) "aYs" = ( @@ -31573,16 +27092,6 @@ /obj/structure/cable/white{ icon_state = "0-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/research) "aYt" = ( @@ -31595,21 +27104,15 @@ /turf/open/floor/plating, /area/maintenance/starboard) "aYu" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" }, /turf/open/floor/plating, /area/maintenance/starboard/aft) @@ -31673,21 +27176,15 @@ /area/maintenance/port/aft) "aYB" = ( /obj/machinery/door/firedoor/heavy, -/obj/machinery/door/airlock/command{ - name = "Research Director's Office"; - req_access_txt = "30" - }, /obj/structure/cable/white{ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/machinery/door/airlock/command{ + name = "Research Director's Office"; + req_access_txt = "30" }, /turf/open/floor/plasteel, /area/command/heads_quarters/rd) @@ -31719,7 +27216,9 @@ "aYF" = ( /obj/structure/chair/comfy/black, /obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/wood, +/turf/open/floor/wood{ + icon_state = "wood-broken6" + }, /area/maintenance/port/aft) "aYG" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -31752,13 +27251,7 @@ name = "Medbay Storage"; req_access_txt = "5" }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "aYK" = ( /obj/effect/turf_decal/delivery, @@ -31788,6 +27281,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/effect/landmark/start/medical_doctor, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "aYN" = ( @@ -31814,14 +27308,18 @@ }, /obj/structure/table, /obj/item/reagent_containers/glass/beaker/cryoxadone{ - pixel_x = -6; - pixel_y = 6 + pixel_x = -5; + pixel_y = 10 }, /obj/item/reagent_containers/glass/beaker/cryoxadone{ - pixel_x = 6; + pixel_x = -5; pixel_y = 6 }, -/obj/item/storage/pill_bottle/mannitol, +/obj/item/storage/pill_bottle/mannitol{ + pixel_x = 6; + pixel_y = 8 + }, +/obj/item/reagent_containers/spray/cleaner, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "aYQ" = ( @@ -31845,16 +27343,6 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "aYS" = ( @@ -31869,36 +27357,24 @@ /area/medical/medbay/zone3) "aYT" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/medical/glass{ - id_tag = "MedbayFoyer"; - name = "Medbay"; - req_access_txt = "5" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/effect/mapping_helpers/airlock/unres{ dir = 8 }, -/turf/open/floor/plasteel, +/obj/machinery/door/airlock/medical/glass{ + id_tag = "MedbayFoyer"; + name = "Medbay"; + req_access_txt = "5" + }, +/turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "aYU" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "aYV" = ( @@ -31909,28 +27385,12 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "aYW" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -31949,16 +27409,6 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "aYZ" = ( @@ -31984,15 +27434,11 @@ /area/science/robotics/mechbay) "aZd" = ( /obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/airlock/research{ name = "Mech Bay"; req_access_txt = "29" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/science/robotics/mechbay) "aZe" = ( @@ -32002,7 +27448,6 @@ "aZf" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/research) "aZg" = ( @@ -32011,7 +27456,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/research) "aZh" = ( @@ -32076,17 +27520,11 @@ /turf/open/floor/plasteel, /area/maintenance/port/aft) "aZq" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, +/obj/effect/decal/cleanable/dirt/dust, /obj/machinery/door/airlock/maintenance_hatch{ name = "Maintenance Hatch"; req_access_txt = "12" }, -/obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plasteel, /area/maintenance/port/aft) "aZr" = ( @@ -32102,14 +27540,10 @@ /area/maintenance/port/aft) "aZs" = ( /obj/machinery/vending/autodrobe, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, /area/maintenance/port/aft) "aZt" = ( /obj/effect/turf_decal/tile/neutral{ @@ -32203,14 +27637,10 @@ /area/maintenance/port/aft) "aZz" = ( /obj/structure/dresser, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, /area/maintenance/port/aft) "aZA" = ( /obj/structure/table/glass, @@ -32221,12 +27651,6 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /obj/item/folder/white, /obj/item/toy/figure/chemist, /obj/item/reagent_containers/glass/beaker/large{ @@ -32237,16 +27661,15 @@ pixel_x = 3; pixel_y = 6 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/medical/chemistry) "aZB" = ( -/obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/airlock/virology/glass{ - name = "Isolation Room"; - req_access_txt = "39" +/obj/machinery/firealarm{ + dir = 8; + pixel_x = 24 }, -/turf/open/floor/plasteel/freezer, +/turf/open/floor/plasteel, /area/medical/virology) "aZC" = ( /obj/structure/table/wood, @@ -32274,33 +27697,21 @@ name = "Atmospherics Maintenance"; req_access_txt = "12;24" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/maintenance/port/aft) "aZF" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/medical/glass{ - name = "Medbay Storage"; - req_access_txt = "5" - }, /obj/structure/cable/white{ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/medical/glass{ + name = "Medbay Storage"; + req_access_txt = "5" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "aZG" = ( /obj/structure/cable/white{ @@ -32330,16 +27741,6 @@ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "aZJ" = ( @@ -32396,16 +27797,6 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "aZN" = ( @@ -32442,27 +27833,21 @@ /area/medical/medbay/zone3) "aZP" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/medical/glass{ - id_tag = "MedbayFoyer"; - name = "Medbay"; - req_access_txt = "5" - }, /obj/structure/cable/white{ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/effect/mapping_helpers/airlock/unres{ dir = 8 }, -/turf/open/floor/plasteel, +/obj/machinery/door/airlock/medical/glass{ + id_tag = "MedbayFoyer"; + name = "Medbay"; + req_access_txt = "5" + }, +/turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "aZQ" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -32471,12 +27856,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "aZR" = ( @@ -32493,16 +27872,6 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "aZS" = ( @@ -32533,10 +27902,6 @@ icon_state = "0-2" }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/mechbay) "aZV" = ( @@ -32544,29 +27909,17 @@ /obj/effect/landmark/start/cyborg, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/mechbay) "aZW" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/mechbay) "aZX" = ( /obj/structure/reagent_dispensers/fueltank, /obj/effect/decal/cleanable/oil, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/mechbay) "aZY" = ( @@ -32610,10 +27963,6 @@ network = list("ss13","rd") }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bac" = ( @@ -32621,10 +27970,6 @@ /obj/effect/turf_decal/stripes/end{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bad" = ( @@ -32637,9 +27982,8 @@ dir = 1 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/posialert{ + pixel_y = 32 }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) @@ -32660,7 +28004,7 @@ /obj/structure/cable{ icon_state = "4-8" }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/maintenance/solars/port/aft) "baf" = ( /obj/item/stack/sheet/metal/fifty, @@ -32680,10 +28024,6 @@ pixel_y = 32 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bag" = ( @@ -32716,10 +28056,6 @@ /obj/item/stack/sheet/plasteel{ amount = 15 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bah" = ( @@ -32736,28 +28072,21 @@ }, /area/maintenance/starboard) "baj" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/obj/effect/landmark/xeno_spawn, /obj/structure/sign/warning/vacuum{ pixel_x = -32; pixel_y = 32 }, -/obj/effect/turf_decal/delivery, /obj/structure/cable{ icon_state = "4-8" }, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/caution, +/turf/open/floor/plating, /area/maintenance/solars/port/aft) "bak" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/structure/cable{ icon_state = "4-8" }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/maintenance/solars/port/aft) "bal" = ( /obj/effect/turf_decal/stripes/line{ @@ -32766,9 +28095,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/machinery/door/airlock/external{ name = "External Airlock"; req_access_txt = "13" @@ -32779,12 +28105,9 @@ /obj/structure/cable{ icon_state = "4-8" }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/maintenance/solars/port/aft) "bam" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/structure/sign/warning/vacuum{ pixel_y = 32 }, @@ -32797,8 +28120,8 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 }, /turf/open/floor/plating, /area/maintenance/solars/port/aft) @@ -32815,22 +28138,14 @@ /turf/open/floor/plating, /area/maintenance/solars/port/aft) "bap" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +/obj/structure/cable/white{ + icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/machinery/door/airlock/maintenance_hatch{ name = "Maintenance Hatch"; req_access_txt = "12" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, /turf/open/floor/plating, /area/maintenance/solars/port/aft) "baq" = ( @@ -32871,11 +28186,10 @@ /area/maintenance/solars/port/aft) "bav" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable, /obj/structure/cable{ - icon_state = "0-2" + icon_state = "1-2" }, -/turf/closed/wall, +/turf/open/floor/plating, /area/maintenance/solars/port/aft) "baw" = ( /obj/effect/spawner/structure/window/reinforced, @@ -32889,9 +28203,6 @@ /turf/open/floor/plating, /area/medical/medbay/zone3) "bax" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/machinery/newscaster{ pixel_y = -32 }, @@ -32901,16 +28212,25 @@ /obj/effect/turf_decal/stripes/end{ dir = 4 }, -/turf/open/floor/plasteel, +/obj/machinery/stasis{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/medical/medbay/zone3) "bay" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/machinery/defibrillator_mount/loaded{ - pixel_y = -32 - }, /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/item/radio/intercom{ + broadcasting = 1; + frequency = 1485; + listening = 0; + name = "Station Intercom (Medbay)"; + pixel_y = -30 + }, /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "baz" = ( @@ -32937,16 +28257,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "baB" = ( @@ -32969,16 +28279,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "baD" = ( @@ -33032,16 +28332,6 @@ c_tag = "Medbay Foyer"; dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "baI" = ( @@ -33100,16 +28390,6 @@ dir = 8 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "baM" = ( @@ -33171,21 +28451,15 @@ /area/science/robotics/mechbay) "baR" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/research{ - name = "Mech Bay"; - req_access_txt = "29" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/research{ + name = "Mech Bay"; + req_access_txt = "29" }, /turf/open/floor/plasteel, /area/science/robotics/mechbay) @@ -33235,7 +28509,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 9 }, -/obj/structure/closet/crate/bin, /turf/open/floor/plasteel, /area/science/robotics/lab) "baW" = ( @@ -33271,12 +28544,6 @@ /area/science/robotics/lab) "bba" = ( /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bbb" = ( @@ -33308,9 +28575,14 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "bbf" = ( +/obj/machinery/camera{ + c_tag = "Port Quarter Solar"; + dir = 4; + network = list("ss13","engine") + }, /obj/machinery/power/smes, /obj/structure/cable/white{ - icon_state = "0-2" + icon_state = "0-4" }, /turf/open/floor/plating, /area/maintenance/solars/port/aft) @@ -33324,42 +28596,23 @@ icon_state = "1-4" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/white{ + icon_state = "4-8" + }, /turf/open/floor/plating, /area/maintenance/solars/port/aft) "bbi" = ( -/obj/structure/cable/white{ - icon_state = "0-8" - }, -/obj/structure/cable/white{ - icon_state = "0-2" - }, /obj/machinery/power/apc{ areastring = "/area/maintenance/solars/port/aft"; dir = 4; name = "Port Quarter Solar APC"; pixel_x = 24 }, +/obj/structure/cable/white{ + icon_state = "0-8" + }, /turf/open/floor/plating, /area/maintenance/solars/port/aft) -"bbj" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/maintenance/port/aft) "bbk" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -33367,19 +28620,11 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/dark, -/area/maintenance/port/aft) -"bbl" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/area/maintenance/port/aft) +"bbl" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, @@ -33389,23 +28634,16 @@ /turf/open/floor/plasteel/dark, /area/maintenance/port/aft) "bbm" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/structure/cable/white{ icon_state = "4-8" }, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, /turf/open/floor/plasteel, /area/maintenance/port/aft) "bbn" = ( @@ -33424,9 +28662,13 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "bbo" = ( -/obj/structure/cable/white{ - icon_state = "1-4" +/obj/machinery/power/terminal{ + dir = 1 }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/turf_decal/delivery, /turf/open/floor/plating, /area/maintenance/solars/port/aft) "bbp" = ( @@ -33493,33 +28735,17 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "bbx" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security/glass{ - name = "Security Checkpoint"; - req_access_txt = "63" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/security/glass{ + name = "Security Checkpoint"; + req_access_txt = "63" }, /turf/open/floor/plasteel, /area/security/checkpoint) @@ -33647,21 +28873,15 @@ /area/science/research) "bbI" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/research/glass{ - name = "Robotics Lab"; - req_access_txt = "29" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/research/glass{ + name = "Robotics Lab"; + req_access_txt = "29" }, /turf/open/floor/plasteel, /area/science/robotics/lab) @@ -33693,16 +28913,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/science/robotics/lab) "bbM" = ( @@ -33711,6 +28921,7 @@ }, /obj/effect/decal/cleanable/oil, /obj/effect/turf_decal/bot, +/obj/item/bot_assembly/cleanbot, /turf/open/floor/plasteel, /area/science/robotics/lab) "bbN" = ( @@ -33734,12 +28945,6 @@ dir = 8; pixel_x = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bbP" = ( @@ -33772,15 +28977,15 @@ /turf/open/space/basic, /area/solars/starboard/fore) "bbR" = ( -/obj/structure/cable/white{ - icon_state = "0-8" - }, -/obj/structure/cable/white, +/obj/machinery/light/small, /obj/machinery/power/solar_control{ dir = 8; id = "aftport"; name = "Port Quarter Solar Control" }, +/obj/structure/cable{ + icon_state = "0-8" + }, /obj/effect/turf_decal/bot, /turf/open/floor/plating, /area/maintenance/solars/port/aft) @@ -33821,41 +29026,32 @@ /turf/open/space/basic, /area/solars/starboard/fore) "bbX" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/structure/closet/emcloset/anchored, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, /area/maintenance/solars/starboard/fore) "bbY" = ( /obj/structure/lattice/catwalk, /turf/open/floor/plating/airless, /area/solars/starboard/fore) "bbZ" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, /obj/structure/cable{ icon_state = "2-4" }, -/turf/open/floor/plasteel, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plating, /area/maintenance/solars/starboard/fore) "bca" = ( /obj/structure/sign/warning/vacuum{ pixel_x = 32; pixel_y = 32 }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, -/obj/effect/landmark/xeno_spawn, -/obj/effect/turf_decal/delivery, /obj/structure/cable{ icon_state = "4-8" }, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/caution, +/turf/open/floor/plating, /area/maintenance/solars/starboard/fore) "bcb" = ( /obj/machinery/door/airlock/external{ @@ -33871,7 +29067,7 @@ /obj/structure/cable{ icon_state = "4-8" }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/maintenance/solars/starboard/fore) "bcc" = ( /obj/effect/turf_decal/stripes/line, @@ -33883,16 +29079,12 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ icon_state = "1-2" }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/maintenance/solars/starboard/fore) "bcd" = ( -/obj/item/retractor, -/obj/item/hemostat, -/obj/structure/table/reinforced, /obj/machinery/vending/wallmed{ name = "Emergency NanoMed"; pixel_x = -26; @@ -33902,25 +29094,17 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/item/storage/backpack/duffelbag/med/surgery, +/obj/structure/table/reinforced, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_y = 26 }, /turf/open/floor/plasteel/dark, /area/medical/medbay/zone3) "bce" = ( /obj/structure/table/optable, /obj/effect/decal/cleanable/blood/old, -/obj/item/radio/intercom{ - name = "Station Intercom"; - pixel_y = 26 - }, /obj/effect/turf_decal/tile/blue{ dir = 1 }, @@ -33934,41 +29118,15 @@ /turf/open/floor/plasteel, /area/medical/medbay/zone3) "bcf" = ( -/obj/machinery/computer/operating{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/computer/operating, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "bcg" = ( -/obj/item/clothing/gloves/color/latex, -/obj/item/clothing/suit/apron/surgical, -/obj/item/clothing/mask/surgical, -/obj/item/surgical_drapes, -/obj/structure/table/reinforced, /obj/effect/turf_decal/bot, /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/limbgrower, /turf/open/floor/plasteel/dark, /area/medical/medbay/zone3) "bch" = ( @@ -33985,16 +29143,9 @@ "bci" = ( /obj/structure/bed/roller, /obj/machinery/iv_drip, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/medical/medbay/zone3) "bcj" = ( /obj/structure/table/reinforced, @@ -34008,23 +29159,25 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/delivery, +/obj/item/reagent_containers/glass/bottle/epinephrine, +/obj/item/reagent_containers/glass/bottle/charcoal{ + pixel_x = 6 + }, +/obj/item/reagent_containers/syringe, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "bck" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/medical/glass{ - name = "Medbay Desk"; - req_access_txt = "5" - }, /obj/structure/sign/warning/nosmoking/circle{ pixel_x = 32 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/medical/glass{ + id_tag = "MedbayFoyer"; + name = "Paramedic's Office"; + req_access_txt = "5;6;12;64" }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "bcl" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -34034,16 +29187,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "bcm" = ( @@ -34069,16 +29212,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/security/checkpoint) "bcp" = ( @@ -34102,16 +29235,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "bcr" = ( @@ -34185,6 +29308,7 @@ /area/science/robotics/lab) "bcA" = ( /obj/effect/turf_decal/stripes/line, +/obj/machinery/rnd/production/circuit_imprinter, /turf/open/floor/plasteel, /area/science/robotics/lab) "bcB" = ( @@ -34199,12 +29323,6 @@ }, /obj/effect/turf_decal/bot, /obj/machinery/aug_manipulator, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bcD" = ( @@ -34224,13 +29342,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/science/mixing) "bcF" = ( /obj/structure/sign/warning/securearea, @@ -34241,58 +29353,58 @@ pixel_x = 32; pixel_y = 32 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ icon_state = "1-4" }, -/turf/open/floor/plating, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel, /area/maintenance/solars/starboard/fore) "bcH" = ( -/obj/machinery/light/small{ - dir = 4 +/obj/structure/cable{ + icon_state = "4-8" }, +/obj/structure/closet/emcloset/anchored, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/maintenance/solars/starboard/fore) +"bcI" = ( +/obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ icon_state = "4-8" }, /turf/open/floor/plating, /area/maintenance/solars/starboard/fore) -"bcI" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/maintenance/solars/starboard/fore) "bcJ" = ( +/obj/structure/lattice, +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"bcK" = ( +/obj/machinery/power/terminal{ + dir = 4 + }, /obj/structure/cable{ icon_state = "0-8" }, -/obj/effect/turf_decal/box, -/obj/machinery/power/tracker, -/turf/open/floor/plasteel/airless/solarpanel, -/area/solars/starboard/fore) -"bcK" = ( -/obj/machinery/power/smes, -/obj/structure/cable/white{ - icon_state = "0-4" - }, +/obj/effect/turf_decal/delivery, /turf/open/floor/plating, /area/maintenance/solars/starboard/fore) "bcL" = ( +/obj/machinery/power/smes, /obj/structure/cable/white{ icon_state = "0-2" }, -/obj/structure/cable/white{ - icon_state = "0-8" - }, -/obj/machinery/power/solar_control{ - id = "forestarboard"; - name = "Starboard Bow Solar Control" - }, -/obj/effect/turf_decal/bot, /turf/open/floor/plating, /area/maintenance/solars/starboard/fore) "bcM" = ( @@ -34302,12 +29414,9 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/maintenance/solars/starboard/fore) "bcN" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/structure/cable/white{ icon_state = "4-8" }, @@ -34315,12 +29424,13 @@ pixel_x = 32; pixel_y = -32 }, -/turf/open/floor/plating, -/area/maintenance/solars/starboard/fore) -"bcO" = ( +/obj/machinery/light/small, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/turf/open/floor/plasteel, +/area/maintenance/solars/starboard/fore) +"bcO" = ( /obj/structure/cable/white{ icon_state = "4-8" }, @@ -34328,6 +29438,9 @@ name = "Starboard Bow Solar Access"; req_access_txt = "10" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plating, /area/maintenance/solars/starboard/fore) "bcP" = ( @@ -34337,6 +29450,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, +/obj/effect/landmark/xeno_spawn, /turf/open/floor/plating, /area/maintenance/solars/starboard/fore) "bcQ" = ( @@ -34348,6 +29462,10 @@ /obj/structure/cable/white{ icon_state = "1-8" }, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, /turf/open/floor/plating, /area/maintenance/solars/starboard/fore) "bcS" = ( @@ -34376,11 +29494,6 @@ /turf/open/floor/plating, /area/maintenance/solars/starboard/fore) "bcU" = ( -/obj/item/circular_saw, -/obj/item/surgicaldrill{ - pixel_y = 5 - }, -/obj/structure/table/reinforced, /obj/structure/mirror{ pixel_x = -28 }, @@ -34388,30 +29501,14 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/item/clothing/gloves/color/latex, +/obj/item/clothing/suit/apron/surgical, +/obj/item/clothing/mask/surgical, +/obj/structure/table/reinforced, /turf/open/floor/plasteel/dark, /area/medical/medbay/zone3) "bcV" = ( /obj/effect/landmark/start/medical_doctor, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "bcW" = ( @@ -34431,9 +29528,6 @@ /turf/open/floor/plasteel, /area/medical/medbay/zone3) "bcX" = ( -/obj/item/scalpel, -/obj/item/cautery, -/obj/structure/table/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -34441,16 +29535,8 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/item/reagent_containers/glass/beaker/synthflesh, +/obj/structure/closet/crate/freezer/surplus_limbs, /turf/open/floor/plasteel/dark, /area/medical/medbay/zone3) "bcY" = ( @@ -34461,10 +29547,6 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, -/obj/machinery/camera{ - c_tag = "Medbay South"; - dir = 4 - }, /obj/effect/turf_decal/tile/blue{ dir = 8 }, @@ -34473,29 +29555,23 @@ "bcZ" = ( /obj/structure/bed/roller, /obj/machinery/iv_drip, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, /area/medical/medbay/zone3) "bda" = ( -/obj/machinery/computer/med_data{ - dir = 4 +/obj/machinery/suit_storage_unit/paramedic, +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, /area/medical/medbay/zone3) "bdb" = ( /obj/structure/chair/office/light{ dir = 1 }, -/obj/effect/landmark/start/medical_doctor, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, @@ -34508,17 +29584,10 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/effect/landmark/start/paramedic, /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "bdc" = ( -/obj/machinery/button/door{ - desc = "A remote control switch for the medbay foyer."; - id = "MedbayFoyer"; - name = "Medbay Doors Control"; - normaldoorcontrol = 1; - pixel_x = 24; - pixel_y = 24 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/tile/blue{ dir = 1 @@ -34579,16 +29648,6 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/security/checkpoint) "bdg" = ( @@ -34737,16 +29796,6 @@ icon_state = "0-4" }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bdu" = ( @@ -34761,16 +29810,6 @@ icon_state = "1-8" }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bdv" = ( @@ -34784,9 +29823,12 @@ network = list("ss13","engine") }, /obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel/dark/corner{ dir = 4 }, -/turf/open/floor/plasteel/checker, /area/engineering/atmos) "bdw" = ( /obj/machinery/holopad, @@ -34810,12 +29852,6 @@ pixel_x = 32 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bdz" = ( @@ -34824,7 +29860,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/airlock/maintenance{ - req_one_access_txt = "8;12" + req_one_access_txt = "7;12" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 @@ -34843,11 +29879,12 @@ /turf/open/floor/plating/airless, /area/solars/starboard/fore) "bdC" = ( -/obj/structure/cable, -/obj/machinery/power/terminal{ - dir = 8 +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable/white{ + icon_state = "4-8" }, -/obj/effect/turf_decal/delivery, /turf/open/floor/plating, /area/maintenance/solars/port/aft) "bdD" = ( @@ -34877,7 +29914,7 @@ /area/command/heads_quarters/rd) "bdE" = ( /obj/structure/cable/white{ - icon_state = "0-4" + icon_state = "4-8" }, /obj/structure/cable/white{ icon_state = "0-8" @@ -34906,9 +29943,6 @@ /turf/open/floor/plating, /area/maintenance/starboard/fore) "bdG" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, @@ -34916,6 +29950,10 @@ dir = 1; pixel_y = -22 }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/landmark/xeno_spawn, /turf/open/floor/plating, /area/maintenance/solars/port/aft) "bdH" = ( @@ -35072,7 +30110,6 @@ /turf/open/floor/plating/asteroid, /area/command/heads_quarters/rd) "bdQ" = ( -/obj/structure/closet/secure_closet/medical2, /obj/machinery/airalarm{ dir = 4; pixel_x = -22 @@ -35084,16 +30121,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/structure/closet/secure_closet/medical2, /turf/open/floor/plasteel/dark, /area/medical/medbay/zone3) "bdR" = ( @@ -35125,34 +30153,18 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/medical/medbay/zone3) "bdT" = ( /obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /obj/machinery/door/airlock/medical{ name = "Surgery Theatre"; req_access_txt = "45" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/medical/medbay/zone3) "bdU" = ( /obj/machinery/firealarm{ @@ -35167,7 +30179,6 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "bdV" = ( -/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, @@ -35175,6 +30186,9 @@ /obj/effect/turf_decal/tile/green{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "bdW" = ( @@ -35199,25 +30213,23 @@ /obj/machinery/computer/crew{ dir = 4 }, -/obj/machinery/newscaster{ - pixel_y = -32 - }, /obj/machinery/firealarm{ dir = 1; pixel_x = -26; pixel_y = -26 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/obj/machinery/newscaster{ + pixel_x = -32 }, -/turf/open/floor/plasteel/dark, -/area/medical/medbay/zone3) -"bdY" = ( /obj/machinery/airalarm{ dir = 1; pixel_y = -22 }, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, +/area/medical/medbay/zone3) +"bdY" = ( /obj/effect/turf_decal/tile/blue{ dir = 1 }, @@ -35225,16 +30237,27 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/structure/chair/office/light{ + dir = 8 + }, +/obj/machinery/button/door{ + desc = "A remote control switch for the medbay foyer."; + id = "MedbayFoyer"; + name = "Medbay Doors Control"; + normaldoorcontrol = 1; + pixel_x = 24; + pixel_y = -24 + }, +/obj/item/radio/intercom{ + broadcasting = 1; + frequency = 1485; + listening = 0; + name = "Station Intercom (Medbay)"; + pixel_y = -30 + }, /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "bdZ" = ( -/obj/structure/chair/office/light{ - dir = 4 - }, -/obj/item/radio/intercom{ - name = "Station Intercom"; - pixel_y = -26 - }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, @@ -35245,23 +30268,23 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/structure/closet/secure_closet/paramedic, +/obj/machinery/camera{ + c_tag = "Paramedic Disbatch"; + dir = 10; + network = list("ss13","medbay") + }, /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "bea" = ( -/obj/structure/table/reinforced, -/obj/machinery/door/firedoor, -/obj/item/reagent_containers/glass/bottle/charcoal{ - pixel_x = 6 +/obj/machinery/camera{ + c_tag = "MiniSat External South"; + dir = 6; + network = list("minisat"); + start_active = 1 }, -/obj/item/reagent_containers/glass/bottle/epinephrine, -/obj/item/reagent_containers/syringe, -/obj/machinery/door/window/westleft{ - name = "Medbay Desk"; - req_access_txt = "5" - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/medical/medbay/zone3) +/turf/open/space/basic, +/area/space) "beb" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable/white, @@ -35283,16 +30306,6 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/security/checkpoint) "bee" = ( @@ -35360,22 +30373,20 @@ /area/science/robotics/mechbay) "bek" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side, /area/science/research) "bel" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side, /area/science/research) "bem" = ( /obj/structure/table, @@ -35388,12 +30399,6 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "ben" = ( @@ -35402,12 +30407,6 @@ icon_state = "1-2" }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "beo" = ( @@ -35423,10 +30422,6 @@ }, /obj/machinery/light, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bep" = ( @@ -35463,12 +30458,16 @@ pixel_x = 28 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/obj/item/storage/firstaid/regular{ + empty = 1; + name = "First-Aid (empty)" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/item/healthanalyzer, +/obj/item/storage/firstaid/regular{ + empty = 1; + name = "First-Aid (empty)" }, +/obj/item/healthanalyzer, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bes" = ( @@ -35486,11 +30485,13 @@ }, /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/camera{ + c_tag = "Toxins Lab"; + network = list("ss13","rd") + }, +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/science/mixing) "bev" = ( /obj/structure/table/plasmaglass, @@ -35580,11 +30581,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/turf/open/floor/plasteel/dark, /area/science/mixing) "beB" = ( /obj/structure/cable/white{ @@ -35730,24 +30729,16 @@ /area/science/robotics/mechbay) "beM" = ( /obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, /obj/machinery/door/airlock/research{ name = "Research Division Access"; req_access_txt = "47" }, -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/science/research) "beN" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/research{ - name = "Research Division Access"; - req_access_txt = "47" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -35755,12 +30746,12 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plasteel, +/obj/machinery/door/airlock/research{ + name = "Research Division Access"; + req_access_txt = "47" + }, +/turf/open/floor/plasteel/dark, /area/science/research) "beO" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, @@ -35768,10 +30759,6 @@ /area/science/robotics/lab) "beP" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Robotics Lab Maintenance"; - req_access_txt = "29" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -35779,9 +30766,9 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Robotics Lab Maintenance"; + req_access_txt = "29" }, /turf/open/floor/plating, /area/maintenance/starboard) @@ -35868,11 +30855,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/turf/open/floor/plasteel/dark, /area/science/mixing) "beW" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -35917,11 +30902,9 @@ /obj/machinery/portable_atmospherics/scrubber, /obj/item/storage/firstaid/toxin, /obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/science/mixing) "bfc" = ( /obj/structure/cable/white{ @@ -35958,10 +30941,6 @@ name = "Security Checkpoint"; req_access_txt = "63" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/security/checkpoint) "bfg" = ( @@ -36017,7 +30996,7 @@ icon_state = "4-8" }, /obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/maintenance/starboard/aft) "bfm" = ( /obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, @@ -36034,7 +31013,7 @@ icon_state = "2-4" }, /obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/maintenance/starboard/aft) "bfn" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, @@ -36103,13 +31082,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/science/mixing) "bft" = ( /obj/structure/closet/secure_closet/RD, @@ -36124,10 +31097,8 @@ /obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, /obj/item/circuitboard/aicore, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel{ icon_state = "sepia" }, @@ -36166,6 +31137,9 @@ dir = 1; pixel_y = -28 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel{ icon_state = "sepia" }, @@ -36199,7 +31173,7 @@ /area/service/chapel/main) "bfB" = ( /obj/machinery/holopad, -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plasteel, /area/science/mixing) "bfC" = ( @@ -36225,16 +31199,6 @@ name = "Morgue APC"; pixel_x = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /obj/machinery/camera{ c_tag = "Morgue"; dir = 8; @@ -36251,10 +31215,6 @@ /obj/item/surgical_drapes, /obj/item/cautery, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /obj/item/toy/figure/roboticist{ pixel_x = -4; pixel_y = 14 @@ -36271,20 +31231,13 @@ network = list("ss13","medbay"); pixel_x = 22 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/smartfridge/organ/preloaded{ + density = 0; + pixel_y = -31 }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "bfG" = ( -/obj/structure/closet/crate/freezer/blood, /obj/structure/extinguisher_cabinet{ pixel_y = -26 }, @@ -36293,22 +31246,16 @@ }, /obj/machinery/camera{ c_tag = "Medbay Recovery Room"; - dir = 8; + dir = 1; network = list("ss13","medbay") }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/obj/machinery/vending/medical, +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/medical/medbay/zone3) "bfH" = ( /obj/effect/landmark/start/virologist, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 4 - }, /obj/machinery/power/apc/highcap/five_k{ areastring = "/area/medical/virology"; dir = 1; @@ -36322,6 +31269,9 @@ c_tag = "Virology"; network = list("ss13","medbay") }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, /turf/open/floor/plasteel, /area/medical/virology) "bfI" = ( @@ -36347,16 +31297,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "bfK" = ( @@ -36366,16 +31306,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "bfL" = ( @@ -36389,16 +31319,6 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "bfM" = ( @@ -36415,6 +31335,9 @@ dir = 1; network = list("ss13","medbay") }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, /turf/open/floor/plasteel/white, /area/medical/virology) "bfN" = ( @@ -36449,18 +31372,14 @@ name = "Xenobiology Containment Door" }, /obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, /obj/machinery/door/airlock/research{ name = "Xenobiology Lab"; req_access_txt = "47" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, /turf/open/floor/plasteel, /area/science/xenobiology) "bfR" = ( @@ -36469,10 +31388,6 @@ name = "Xenobiology Containment Door" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/research{ - name = "Xenobiology Lab"; - req_access_txt = "47" - }, /obj/structure/sign/departments/xenobio{ pixel_x = 32 }, @@ -36480,13 +31395,13 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 }, +/obj/machinery/door/airlock/research{ + name = "Xenobiology Lab"; + req_access_txt = "47" + }, /turf/open/floor/plasteel, /area/science/xenobiology) "bfS" = ( @@ -36515,10 +31430,6 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) "bfU" = ( @@ -36533,16 +31444,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) "bfV" = ( @@ -36553,16 +31454,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) "bfX" = ( @@ -36644,38 +31535,13 @@ /obj/effect/turf_decal/stripes/end{ dir = 8 }, -/obj/machinery/camera{ - c_tag = "Xenobiology Central"; - dir = 4; - network = list("ss13","rd"); - pixel_y = -5 - }, /turf/open/floor/plasteel, /area/science/xenobiology) "bgd" = ( -/obj/structure/table/reinforced, -/obj/item/storage/box/beakers{ - pixel_x = 3; - pixel_y = 3 +/obj/structure/closet/l3closet/scientist, +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/obj/item/storage/box/syringes, -/obj/item/extinguisher/mini, -/obj/machinery/airalarm/unlocked{ - dir = 4; - pixel_x = -23 - }, -/obj/machinery/newscaster{ - pixel_y = -32 - }, -/obj/machinery/camera{ - c_tag = "Xenobiology Lab"; - dir = 4; - network = list("ss13","rd") - }, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plasteel, /area/science/xenobiology) "bge" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -36689,9 +31555,6 @@ codes_txt = "patrol;next_patrol=8.4-AftNW"; location = "8.3-AftSW" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -36704,29 +31567,19 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, /area/hallway/primary/aft) "bgg" = ( -/obj/structure/table/reinforced, -/obj/item/storage/box/monkeycubes, -/obj/item/storage/box/monkeycubes, -/obj/machinery/status_display{ - pixel_y = -32 - }, -/obj/effect/turf_decal/stripes/line{ +/obj/effect/turf_decal/tile/purple{ dir = 1 }, -/obj/machinery/camera{ - c_tag = "Xenobiology South"; - dir = 1; - network = list("ss13","rd") +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white, /area/science/xenobiology) "bgh" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -36740,6 +31593,12 @@ dir = 1; network = list("ss13","engine") }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "bgi" = ( @@ -36754,13 +31613,10 @@ network = list("ss13","engine") }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "bgj" = ( /obj/machinery/atmospherics/components/binary/pump{ @@ -36782,14 +31638,11 @@ /turf/open/floor/engine, /area/maintenance/disposal/incinerator) "bgk" = ( -/obj/structure/cable/white{ - icon_state = "4-8" +/obj/structure/cable{ + icon_state = "1-8" }, -/obj/machinery/light/small, -/obj/machinery/camera{ - c_tag = "Port Quarter Solar"; - dir = 1; - network = list("ss13","engine") +/obj/structure/cable{ + icon_state = "1-4" }, /turf/open/floor/plating, /area/maintenance/solars/port/aft) @@ -36799,26 +31652,15 @@ pixel_x = 32 }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/hallway/primary/aft) -"bgm" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/area/hallway/primary/aft) +"bgm" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/engine, /area/science/xenobiology) "bgn" = ( /obj/structure/extinguisher_cabinet{ @@ -36839,6 +31681,9 @@ /obj/structure/cable/white{ icon_state = "0-2" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plating, /area/science/xenobiology) "bgp" = ( @@ -36856,12 +31701,19 @@ pixel_y = 32 }, /obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 9 + }, /area/science/xenobiology) "bgq" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, /area/science/xenobiology) "bgr" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -36869,7 +31721,12 @@ icon_state = "1-2" }, /obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, /area/science/xenobiology) "bgu" = ( /obj/effect/turf_decal/tile/neutral, @@ -36900,11 +31757,12 @@ /obj/structure/mirror{ pixel_x = 26 }, -/obj/structure/sink{ - dir = 4; - pixel_x = 12 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/sink{ + dir = 8; + pixel_x = -12; + pixel_y = 2 + }, /turf/open/floor/plasteel/white, /area/service/chapel/main) "bgC" = ( @@ -36946,10 +31804,6 @@ c_tag = "Crematorium"; dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) "bgE" = ( @@ -36959,16 +31813,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) "bgF" = ( @@ -37068,28 +31912,20 @@ /area/hallway/secondary/entry) "bgR" = ( /obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/airlock/public/glass{ name = "Arrivals Port" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bgS" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/public/glass{ - name = "Arrivals Port" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/door/airlock/public/glass{ + name = "Arrivals Port" }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) @@ -37107,14 +31943,10 @@ /area/hallway/secondary/entry) "bgW" = ( /obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/airlock/public/glass{ name = "Arrivals Port" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bgX" = ( @@ -37135,21 +31967,14 @@ /obj/machinery/light{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/engine, /area/science/xenobiology) "bgZ" = ( /mob/living/simple_animal/slime, -/turf/open/floor/circuit/green, +/turf/open/floor/engine, /area/science/xenobiology) "bha" = ( /obj/structure/cable/white{ @@ -37167,16 +31992,6 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) "bhb" = ( @@ -37184,10 +31999,11 @@ icon_state = "4-8" }, /obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/science/xenobiology) "bhc" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "4-8" }, @@ -37200,10 +32016,12 @@ /obj/effect/turf_decal/tile/purple{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/white, /area/science/xenobiology) "bhd" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, @@ -37219,30 +32037,25 @@ /obj/effect/turf_decal/tile/purple{ dir = 1 }, -/obj/effect/turf_decal/tile/purple, /obj/effect/turf_decal/tile/purple{ dir = 4 }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, /turf/open/floor/plasteel/white, /area/science/xenobiology) "bhg" = ( -/turf/open/floor/circuit/green, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/engine, /area/science/xenobiology) "bhi" = ( /obj/machinery/light{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/engine, /area/science/xenobiology) "bhj" = ( /obj/effect/turf_decal/sand/plating, @@ -37262,8 +32075,7 @@ "bhn" = ( /obj/machinery/light/floor, /turf/open/floor/plasteel/yellowsiding/corner{ - dir = 8; - icon_state = "yellowcornersiding" + dir = 8 }, /area/maintenance/starboard/aft) "bho" = ( @@ -37295,10 +32107,6 @@ /turf/closed/wall, /area/service/chapel/main) "bhr" = ( -/obj/machinery/door/airlock/grunge{ - name = "Crematorium"; - req_access_txt = "27" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" @@ -37306,15 +32114,9 @@ /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/door/airlock/grunge{ + name = "Crematorium"; + req_access_txt = "27" }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) @@ -37369,34 +32171,18 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) "bhy" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/grunge{ - name = "Chapel Hall" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/grunge{ + name = "Chapel Hall" }, /turf/open/floor/plasteel, /area/service/chapel/main) @@ -37405,9 +32191,8 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/airalarm{ + pixel_y = 23 }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) @@ -37431,12 +32216,8 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/airalarm{ - pixel_y = 23 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/camera{ + c_tag = "Arrivals Bay 1 North" }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) @@ -37463,76 +32244,48 @@ dir = 4 }, /obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bhE" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, /turf/open/floor/plasteel/white/corner, /area/hallway/secondary/entry) "bhF" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/structure/cable/white{ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bhG" = ( /obj/machinery/light{ dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/effect/turf_decal/tile/blue{ dir = 8 }, /turf/open/floor/plasteel/white/corner, /area/hallway/secondary/entry) "bhH" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bhI" = ( /obj/machinery/holopad, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bhJ" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bhK" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/blue{ +/obj/effect/turf_decal/tile/purple{ dir = 8 }, /turf/open/floor/plasteel/white/corner, @@ -37550,12 +32303,6 @@ pixel_x = 24 }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/hallway/secondary/entry) "bhM" = ( @@ -37565,17 +32312,7 @@ /obj/structure/disposaloutlet{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/engine, /area/science/xenobiology) "bhN" = ( /obj/effect/spawner/structure/window/reinforced, @@ -37591,7 +32328,9 @@ dir = 8 }, /obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/science/xenobiology) "bhP" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -37609,31 +32348,17 @@ icon_state = "1-2" }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, /turf/open/floor/plasteel/white, /area/science/xenobiology) "bhS" = ( -/obj/structure/disposalpipe/trunk{ - dir = 8 - }, -/obj/structure/disposaloutlet{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/corner{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/science/xenobiology) +/area/engineering/atmos) "bhX" = ( /obj/machinery/pool/filter{ pixel_y = 16 @@ -37651,16 +32376,6 @@ c_tag = "Chaplain's Quarters" }, /obj/machinery/vending/wardrobe/chap_wardrobe, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) "bia" = ( @@ -37714,16 +32429,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) "big" = ( @@ -37826,12 +32531,6 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -37843,10 +32542,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/machinery/camera{ - c_tag = "Arrivals Bay 1 North"; - dir = 1 - }, /obj/effect/turf_decal/tile/blue{ dir = 4 }, @@ -37867,12 +32562,6 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -37900,12 +32589,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -37926,12 +32609,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -37954,7 +32631,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, -/obj/effect/turf_decal/tile/blue{ +/obj/effect/turf_decal/tile/purple{ dir = 4 }, /turf/open/floor/plasteel/white/corner{ @@ -37965,12 +32642,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -37986,19 +32657,9 @@ name = "arrivals camera" }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/hallway/secondary/entry) "biD" = ( -/obj/machinery/shower{ - dir = 8; - name = "emergency shower" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" @@ -38006,6 +32667,12 @@ /obj/effect/turf_decal/stripes/end{ dir = 4 }, +/obj/machinery/camera{ + c_tag = "Xenobiology Central"; + dir = 8; + network = list("ss13","rd"); + pixel_y = -5 + }, /turf/open/floor/plasteel, /area/science/xenobiology) "biF" = ( @@ -38028,20 +32695,14 @@ /turf/open/floor/plasteel/grimy, /area/service/chapel/main) "biH" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /obj/machinery/door/airlock/grunge{ name = "Chapel Quarters"; req_access_txt = "27" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/grimy, /area/service/chapel/main) "biI" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -38066,37 +32727,21 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) "biM" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/grunge{ - name = "Chapel Office"; - req_access_txt = "27" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/machinery/door/airlock/grunge{ + name = "Chapel Office"; + req_access_txt = "27" }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/service/chapel/main) "biN" = ( /obj/machinery/light_switch{ @@ -38116,16 +32761,6 @@ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) "biP" = ( @@ -38205,23 +32840,11 @@ "biU" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "biV" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/camera{ - c_tag = "Arrivals Hallway 3"; - dir = 8 - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "biW" = ( @@ -38232,6 +32855,9 @@ /obj/structure/cable/white{ icon_state = "0-2" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plating, /area/science/xenobiology) "biX" = ( @@ -38242,7 +32868,12 @@ req_access_txt = "55" }, /obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/science/xenobiology) "biY" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ @@ -38290,7 +32921,7 @@ name = "server vent"; pressure_checks = 0 }, -/turf/open/floor/circuit/green/telecomms/mainframe, +/turf/open/floor/circuit/telecomms, /area/science/xenobiology) "bje" = ( /obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ @@ -38303,7 +32934,7 @@ name = "science camera"; network = list("ss13","rd") }, -/turf/open/floor/circuit/green/telecomms/mainframe, +/turf/open/floor/circuit/telecomms, /area/science/xenobiology) "bjf" = ( /obj/structure/dresser, @@ -38313,16 +32944,6 @@ /obj/structure/sign/nanotrasen{ pixel_y = -32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) "bjg" = ( @@ -38331,16 +32952,6 @@ dir = 1; pixel_y = -22 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) "bjh" = ( @@ -38407,22 +33018,9 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) "bjq" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, /obj/structure/cable/white{ icon_state = "4-8" }, @@ -38432,18 +33030,19 @@ /obj/effect/turf_decal/tile/purple{ dir = 8 }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, /turf/open/floor/plasteel/white, /area/science/xenobiology) "bjr" = ( -/obj/machinery/holopad, /obj/structure/cable/white{ icon_state = "1-2" }, /obj/structure/cable/white{ icon_state = "1-8" }, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white, /area/science/xenobiology) "bjs" = ( /obj/effect/turf_decal/tile/purple{ @@ -38470,53 +33069,29 @@ dir = 6 }, /obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, /area/science/xenobiology) "bjv" = ( +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + dir = 4 + }, /obj/machinery/door/airlock/research/glass{ name = "Xenobiology Kill Room"; req_access_txt = "47" }, -/obj/machinery/atmospherics/pipe/simple/general/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/telecomms, /area/science/xenobiology) "bjw" = ( /obj/machinery/atmospherics/pipe/manifold/general/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark/telecomms, +/turf/open/floor/circuit/telecomms, /area/science/xenobiology) "bjx" = ( /obj/machinery/atmospherics/pipe/simple/general/hidden{ dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark/telecomms, +/turf/open/floor/circuit/telecomms, /area/science/xenobiology) "bjy" = ( /obj/machinery/airalarm{ @@ -38565,56 +33140,44 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bjD" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple, /obj/effect/turf_decal/tile/purple{ dir = 8 }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, /turf/open/floor/plasteel/white, /area/science/xenobiology) "bjE" = ( -/obj/structure/chair/office/light, -/obj/effect/landmark/start/scientist, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel/white, +/obj/effect/turf_decal/bot, +/obj/machinery/holopad, +/turf/open/floor/plasteel, /area/science/xenobiology) "bjF" = ( -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, /turf/open/floor/plasteel/white, /area/science/xenobiology) "bjG" = ( -/obj/structure/closet/l3closet/scientist, /obj/effect/turf_decal/tile/purple, /obj/effect/turf_decal/tile/purple{ dir = 4 }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, +/obj/machinery/portable_atmospherics/canister/bz, /turf/open/floor/plasteel/white, /area/science/xenobiology) "bjH" = ( /obj/machinery/atmospherics/components/unary/thermomachine/freezer/on{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 9 +/obj/effect/turf_decal/stripes/end{ + dir = 8 }, /turf/open/floor/plasteel, /area/science/xenobiology) "bjI" = ( -/turf/open/floor/circuit/green/telecomms/mainframe, +/turf/open/floor/circuit/telecomms, /area/science/xenobiology) "bjJ" = ( /obj/machinery/photocopier, @@ -38665,67 +33228,33 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bjR" = ( -/obj/machinery/computer/camera_advanced/xenobio{ - dir = 1 - }, -/obj/machinery/light, -/obj/machinery/requests_console{ - department = "Xenobiology Lab"; - name = "Xenobiology RC"; - pixel_y = -32; - receive_ore_updates = 1 - }, +/obj/structure/chair/office/light, +/obj/effect/landmark/start/scientist, /obj/structure/cable/white{ - icon_state = "1-4" + icon_state = "1-2" }, -/turf/open/floor/circuit/green, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel/white, /area/science/xenobiology) "bjS" = ( -/obj/structure/table/reinforced, -/obj/item/folder/white, -/obj/item/stack/sheet/mineral/plasma{ - amount = 5 +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 }, -/obj/item/reagent_containers/glass/beaker/large, -/obj/item/reagent_containers/glass/beaker, -/obj/item/reagent_containers/dropper, -/obj/machinery/status_display{ - pixel_y = -32 - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white, /area/science/xenobiology) "bjT" = ( -/obj/structure/table/reinforced, -/obj/machinery/reagentgrinder{ - pixel_y = 5 +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 }, -/obj/machinery/power/apc{ - areastring = "/area/science/xenobiology"; - dir = 4; - name = "Xenobiology Lab APC"; - pixel_x = 24 +/obj/effect/turf_decal/tile/purple{ + dir = 8 }, -/obj/machinery/light_switch{ - pixel_x = 24; - pixel_y = -24 - }, -/obj/item/radio/intercom{ - name = "Station Intercom"; - pixel_y = -24 - }, -/obj/structure/cable/white{ - icon_state = "0-8" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white, /area/science/xenobiology) "bjU" = ( /obj/machinery/status_display{ @@ -38737,6 +33266,10 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/machinery/camera{ + c_tag = "Arrivals Hallway"; + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bjV" = ( @@ -38893,6 +33426,10 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/obj/machinery/camera{ + c_tag = "Arrivals Hallway 2"; + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bkX" = ( @@ -38910,12 +33447,12 @@ "blb" = ( /obj/structure/closet/firecloset, /obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side, /area/hallway/secondary/entry) "blc" = ( /obj/structure/closet/emcloset, /obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark/side, /area/hallway/secondary/entry) "blf" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -38924,9 +33461,6 @@ /obj/machinery/camera{ c_tag = "Fore Primary Hallway 3" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "blg" = ( @@ -38936,10 +33470,6 @@ c_tag = "Port Primary Hallway"; dir = 4 }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "blh" = ( @@ -38948,10 +33478,9 @@ icon_state = "1-2" }, /obj/machinery/camera{ - c_tag = "Starboard Primary Hallway 2"; + c_tag = "Starboard Primary Hallway 3"; dir = 8 }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "bli" = ( @@ -38960,13 +33489,9 @@ c_tag = "Starboard Primary Hallway 2" }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/starboard/fore) "blj" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -39011,16 +33536,12 @@ "blm" = ( /obj/structure/closet/emcloset, /obj/machinery/camera{ - c_tag = "Starboard Primary Hallway" + c_tag = "Starboard Primary Hallway 1" }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/starboard) "bln" = ( /obj/structure/cable/white{ @@ -39034,6 +33555,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/engine, /area/engineering/main) "blo" = ( @@ -39049,9 +33571,6 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "blp" = ( @@ -39073,82 +33592,27 @@ /turf/open/floor/circuit/telecomms/mainframe, /area/tcommsat/server) "bls" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/camera{ - c_tag = "Security Checkpoint"; - dir = 1 - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel{ - heat_capacity = 1e+006 - }, -/area/hallway/primary/aft) +/turf/closed/wall, +/area/engineering/storage/tech) "blv" = ( +/turf/closed/wall/rust, +/area/engineering/storage/tech) +"blx" = ( +/obj/structure/sign/poster/contraband/random, +/turf/closed/wall, +/area/engineering/storage/tech) +"bly" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/camera{ - c_tag = "Arrivals Bay 1 North"; - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel{ - heat_capacity = 1e+006 - }, -/area/hallway/secondary/entry) -"blx" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/camera{ - c_tag = "Arrivals Hallway"; - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/hallway/secondary/entry) -"bly" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/camera{ - c_tag = "Arrivals Hallway 2"; - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/hallway/secondary/entry) +/turf/closed/wall/r_wall, +/area/command/heads_quarters/rd) "blA" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/airlock/grunge{ name = "Mass Driver Room"; req_access_txt = "27" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) "blC" = ( @@ -39176,20 +33640,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) "blF" = ( -/obj/structure/fans/tiny, /obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/service/chapel/main) @@ -39202,12 +33655,6 @@ dir = 8 }, /obj/machinery/light/small, -/obj/machinery/button/massdriver{ - id = "chapelmassdoor"; - name = "mass driver blast door button"; - pixel_x = 24; - pixel_y = -8 - }, /obj/machinery/button/massdriver{ id = "chapelgun"; pixel_x = 24; @@ -39216,24 +33663,14 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main) "blI" = ( +/obj/structure/fans/tiny, /obj/machinery/door/poddoor{ - id = "chapelmassdoor"; + id = "chapelgun"; name = "Chapel Launcher Door" }, -/obj/structure/fans/tiny, /turf/open/floor/plating, /area/service/chapel/main) "blJ" = ( @@ -39251,17 +33688,11 @@ /turf/open/floor/engine, /area/engineering/main) "blL" = ( -/obj/machinery/door/airlock/public/glass{ - name = "Departure Lounge" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/public/glass{ + name = "Departure Lounge" }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) @@ -39284,12 +33715,6 @@ /obj/machinery/door/airlock/public/glass{ name = "Departure Lounge" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "blZ" = ( @@ -39311,12 +33736,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/machinery/door/firedoor, /obj/effect/turf_decal/tile/red{ dir = 4 @@ -39326,25 +33745,30 @@ }, /area/hallway/secondary/exit) "bmC" = ( -/obj/machinery/vending/snack/random, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/obj/machinery/vending/snack/random, +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/hallway/secondary/exit) "bmG" = ( /obj/effect/turf_decal/bot, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, +/area/hallway/secondary/exit) +"bnS" = ( +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/structure/disposaloutlet{ dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/hallway/secondary/exit) +/turf/open/floor/engine, +/area/science/xenobiology) "boD" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -39442,9 +33866,6 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "bsA" = ( @@ -39461,20 +33882,14 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard) "bsB" = ( -/obj/machinery/door/airlock/public/glass{ - name = "Departure Lounge" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/public/glass{ + name = "Departure Lounge" }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) @@ -39497,7 +33912,7 @@ /obj/machinery/status_display{ pixel_y = -32 }, -/obj/effect/turf_decal/tile/red{ +/obj/effect/turf_decal/tile/brown{ dir = 8 }, /turf/open/floor/plasteel/white/corner, @@ -39520,7 +33935,7 @@ /obj/structure/sign/poster/official/random{ pixel_y = -32 }, -/obj/effect/turf_decal/tile/red{ +/obj/effect/turf_decal/tile/brown{ dir = 8 }, /turf/open/floor/plasteel/white/corner, @@ -39539,10 +33954,6 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "bsO" = ( @@ -39564,16 +33975,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "bsQ" = ( @@ -39600,16 +34001,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "bsS" = ( @@ -39634,16 +34025,6 @@ codes_txt = "patrol;next_patrol=6.4-LeavingDepartures"; location = "6.3-DeparturesS" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "bsV" = ( @@ -39654,7 +34035,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ +/obj/effect/turf_decal/tile/brown{ dir = 8 }, /turf/open/floor/plasteel/white/corner, @@ -39662,13 +34043,9 @@ "bsX" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/machinery/door/airlock/mining/glass{ name = "Cargo Office"; req_access_txt = "48;50" @@ -39795,16 +34172,6 @@ /obj/effect/turf_decal/stripes/corner{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) "buH" = ( @@ -39828,16 +34195,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) "buJ" = ( @@ -39845,24 +34202,17 @@ /turf/open/floor/circuit/green/telecomms, /area/tcommsat/server) "buK" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, /obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 + dir = 1; + external_pressure_bound = 140; + name = "server vent"; + pressure_checks = 0 }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) @@ -39871,10 +34221,10 @@ /turf/open/floor/circuit/green/telecomms, /area/tcommsat/server) "buN" = ( -/obj/machinery/announcement_system, /obj/machinery/status_display/ai{ pixel_x = 32 }, +/obj/machinery/ntnet_relay, /turf/open/floor/circuit/telecomms/mainframe, /area/tcommsat/server) "buO" = ( @@ -39903,35 +34253,14 @@ /obj/effect/turf_decal/stripes/corner{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) "buS" = ( -/obj/machinery/ntnet_relay, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark/telecomms, -/area/tcommsat/server) +/turf/closed/wall/r_wall/rust, +/area/science/mixing) "buW" = ( /turf/closed/wall/r_wall, /area/engineering/supermatter) @@ -39999,11 +34328,15 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ dir = 9 }, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_x = -28 + }, /turf/open/floor/engine, /area/engineering/main) "bwW" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 }, /turf/closed/wall/r_wall/rust, /area/tcommsat/server) @@ -40024,9 +34357,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 9 - }, /turf/open/floor/engine, /area/engineering/main) "bxc" = ( @@ -40067,8 +34397,10 @@ /turf/closed/wall/r_wall, /area/tcommsat/server) "bxu" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible, /obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/components/binary/pump/on{ + name = "Gas to Cooling Loop" + }, /turf/open/floor/engine, /area/engineering/main) "bxv" = ( @@ -40100,13 +34432,9 @@ icon_state = "1-2" }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 10 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "bxy" = ( /obj/structure/cable/white{ @@ -40121,9 +34449,6 @@ "bxz" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "bxA" = ( @@ -40187,30 +34512,10 @@ dir = 4 }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "bxH" = ( /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/engineering/atmos) "bxJ" = ( @@ -40218,10 +34523,6 @@ dir = 4; light_color = "#e8eaff" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /obj/machinery/computer/cryopod{ dir = 8; pixel_x = 26 @@ -40229,28 +34530,20 @@ /obj/machinery/cryopod{ dir = 8 }, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, /area/commons/dorms) "bxK" = ( /obj/structure/cable/white{ icon_state = "4-8" }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white/corner, /area/commons/dorms) "bxL" = ( /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "bxM" = ( @@ -40277,15 +34570,11 @@ "bxP" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port) "bxQ" = ( /obj/effect/landmark/event_spawn, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -40340,12 +34629,6 @@ dir = 4 }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -40404,6 +34687,18 @@ dir = 1 }, /area/engineering/atmos) +"bOy" = ( +/obj/item/stack/ore/iron, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/floor/plating{ + icon_state = "platingdmg1" + }, +/area/engineering/atmos) "bOJ" = ( /obj/machinery/atmospherics/components/unary/thermomachine/heater{ dir = 8 @@ -40415,6 +34710,10 @@ /obj/structure/sign/warning/securearea, /turf/closed/wall, /area/command/gateway) +"bRW" = ( +/obj/structure/disposalpipe/segment, +/turf/closed/wall/r_wall, +/area/science/xenobiology) "bVs" = ( /obj/structure/girder, /obj/effect/turf_decal/sand/plating, @@ -40450,11 +34749,15 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) +"cfq" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/girder/reinforced, +/turf/open/floor/plating, +/area/space/nearstation) "cfz" = ( /obj/machinery/hydroponics/constructable, /obj/effect/turf_decal/stripes/line{ @@ -40472,13 +34775,13 @@ /turf/open/floor/plasteel, /area/science/mixing) "chJ" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible, /obj/effect/turf_decal/bot, /obj/machinery/space_heater, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/dark/visible, /turf/open/floor/plasteel/dark/corner{ dir = 1 }, @@ -40511,32 +34814,24 @@ pixel_y = 2 }, /obj/structure/table/glass, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/hydroponics) +"cpn" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/command/heads_quarters/ce) "csX" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, +/obj/machinery/door/firedoor, /obj/machinery/door/airlock/medical/glass{ name = "Hydroponics"; req_access_txt = "35" }, -/obj/machinery/door/firedoor, /turf/open/floor/plasteel, /area/service/hydroponics) "cBf" = ( @@ -40565,32 +34860,63 @@ }, /turf/open/floor/engine/vacuum, /area/maintenance/disposal/incinerator) +"cCv" = ( +/obj/machinery/door/window/brigdoor{ + dir = 4; + name = "Creature Pen"; + req_access_txt = "47" + }, +/obj/machinery/door/poddoor/preopen{ + id = "xeno5"; + name = "Creature Cell #5" + }, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/science/xenobiology) "cGA" = ( /obj/machinery/pool/controller, /turf/open/floor/wood, /area/maintenance/starboard/aft) +"cLO" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/closed/wall/r_wall, +/area/medical/virology) "cRz" = ( /obj/machinery/button/door{ id = "supplybridge"; name = "Shuttle Bay Space Bridge Control"; pixel_y = 27 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Bridge Hatch"; - req_access_txt = "12" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Bridge Hatch"; + req_access_txt = "12" + }, /turf/open/floor/plating, /area/maintenance/starboard) "cUd" = ( @@ -40616,6 +34942,10 @@ name = "Atmospherics Lockdown Blast door" }, /obj/effect/turf_decal/delivery, +/obj/machinery/door/window/eastright{ + dir = 2; + req_access_txt = "24" + }, /turf/open/floor/plasteel, /area/engineering/atmos) "cXu" = ( @@ -40623,9 +34953,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "dai" = ( @@ -40648,25 +34975,19 @@ /turf/open/floor/plating, /area/science/mixing) "dfP" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, /turf/open/floor/plating, /area/maintenance/starboard/aft) "dgV" = ( @@ -40676,6 +34997,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/orange/visible, /turf/open/floor/plasteel, /area/engineering/atmos) "die" = ( @@ -40684,7 +35006,7 @@ icon_state = "1-2" }, /obj/machinery/door/airlock/maintenance{ - req_one_access_txt = "8;12" + req_one_access_txt = "7;12" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plating, @@ -40704,16 +35026,23 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "dvB" = ( -/obj/structure/sink/puddle, -/turf/open/floor/plating/asteroid, +/obj/effect/turf_decal/sand, +/obj/structure/well_foundation, +/turf/open/floor/plating, /area/maintenance/port/aft) +"dxC" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk, +/obj/structure/sign/warning/deathsposal{ + pixel_x = 30 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/science/xenobiology) "dFV" = ( /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 4 @@ -40723,21 +35052,28 @@ name = "Oxygen to Airmix" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow{ dir = 8 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) +"dIK" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/item/radio/intercom{ + frequency = 1485; + name = "Station Intercom (Medbay)"; + pixel_x = -30 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "dMl" = ( /obj/structure/sign/warning/fire, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ +/obj/machinery/atmospherics/pipe/simple/dark/visible{ dir = 4 }, /turf/closed/wall/r_wall, @@ -40761,22 +35097,11 @@ dir = 4 }, /obj/machinery/vr_sleeper, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/bar/atrium) "dSq" = ( /turf/open/floor/plasteel/yellowsiding{ - dir = 4; - icon_state = "yellowsiding" + dir = 4 }, /area/maintenance/starboard/aft) "dXv" = ( @@ -40800,11 +35125,21 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/fore) +"dZL" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) "eaf" = ( /obj/machinery/atmospherics/pipe/simple/yellow/visible, /obj/structure/cable{ @@ -40813,11 +35148,24 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/engineering/atmos) +"ebS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/status_display/evac{ + pixel_x = -32 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/starboard) "eew" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "2-4" + }, /obj/structure/cable{ icon_state = "4-8" }, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "ekG" = ( @@ -40848,17 +35196,10 @@ dir = 1 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow{ dir = 8 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "ewT" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ @@ -40888,16 +35229,6 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) "eyu" = ( @@ -40937,23 +35268,32 @@ /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/yellow/visible, /obj/machinery/computer/atmos_control/tank/nitrogen_tank{ dir = 1 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow, +/obj/machinery/atmospherics/pipe/layer_manifold, +/turf/open/floor/plasteel/dark/corner{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/engineering/atmos) +"eDk" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/turf/closed/wall/r_wall, +/area/science/mixing) +"eDE" = ( +/obj/effect/landmark/carpspawn, +/turf/open/space/basic, +/area/space/station_ruins) +"eIk" = ( +/obj/structure/bookcase/random/fiction, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, +/area/service/library) "eOg" = ( /obj/structure/closet/crate{ icon_state = "crateopen" @@ -40983,10 +35323,6 @@ "eUz" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "eWo" = ( @@ -41009,13 +35345,13 @@ name = "Incinerator Exterior Airlock"; req_access_txt = "12" }, -/obj/structure/cable{ - icon_state = "4-8" - }, /obj/effect/decal/cleanable/dirt, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, /turf/open/floor/engine, /area/maintenance/disposal/incinerator) "eZd" = ( @@ -41030,7 +35366,6 @@ /turf/open/floor/plasteel, /area/science/mixing) "fbH" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible, /obj/effect/decal/cleanable/dirt, /obj/structure/fireaxecabinet{ pixel_x = -30 @@ -41038,6 +35373,7 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/dark/visible, /turf/open/floor/plasteel/dark/corner{ dir = 1 }, @@ -41052,6 +35388,15 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/engine, /area/science/mixing) +"fey" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 10 + }, +/turf/open/floor/engine, +/area/engineering/main) "fff" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ @@ -41060,20 +35405,24 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "fgG" = ( /obj/machinery/status_display/ai, /turf/closed/wall, -/area/commons/lounge) +/area/hallway/primary/aft) "fgZ" = ( /obj/structure/girder/reinforced, /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating/airless, /area/asteroid/nearstation) +"fji" = ( +/obj/structure/disposaloutlet, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/turf/open/floor/plating, +/area/space/nearstation) "fjs" = ( /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 4 @@ -41083,17 +35432,10 @@ c_tag = "Atmospherics Central"; dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel/dark/corner{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/engineering/atmos) "fjN" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ @@ -41101,6 +35443,12 @@ }, /turf/open/floor/plasteel, /area/science/mixing) +"fkE" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel/dark, +/area/maintenance/port/aft) "flE" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -41111,7 +35459,8 @@ /obj/structure/table/wood, /obj/structure/window/reinforced/spawner/west, /obj/item/flashlight/lamp/green, -/turf/open/floor/carpet/green/airless, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/carpet/green, /area/service/lawoffice) "fnp" = ( /obj/machinery/air_sensor/atmos/nitrous_tank, @@ -41148,14 +35497,14 @@ /turf/open/space/basic, /area/space) "fsJ" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume{ frequency = 1449; id = "incinerator_airlock_pump" }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, /turf/open/floor/engine, /area/maintenance/disposal/incinerator) "fuR" = ( @@ -41202,6 +35551,15 @@ /obj/machinery/portable_atmospherics/canister, /turf/open/floor/plasteel, /area/engineering/atmos) +"fHF" = ( +/obj/structure/table/wood, +/obj/item/folder, +/obj/item/pen, +/obj/structure/sign/painting/library{ + pixel_x = -32 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "fIN" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 10 @@ -41229,25 +35587,24 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "fNN" = ( /obj/machinery/hydroponics/soil, /obj/item/seeds/tea, /obj/machinery/light/small, -/turf/open/floor/plating/asteroid, +/obj/effect/turf_decal/sand, +/turf/open/floor/plating, /area/maintenance/port/aft) "fRe" = ( /turf/open/floor/plating/airless{ icon_state = "platingdmg3" }, /area/asteroid/nearstation) +"fTp" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/engineering/gravity_generator) "fWh" = ( /turf/open/floor/wood{ icon_state = "wood-broken5" @@ -41270,8 +35627,8 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/machinery/light, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/orange/visible, /turf/open/floor/plasteel, /area/engineering/atmos) "gap" = ( @@ -41294,27 +35651,51 @@ /area/maintenance/disposal/incinerator) "geZ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port) +"gfr" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/closed/wall, +/area/science/mixing) "ggq" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 10 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/command/bridge) "ghr" = ( /obj/structure/reagent_dispensers/fueltank, /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/maintenance/port/aft) +"gia" = ( +/obj/structure/table/reinforced, +/obj/machinery/reagentgrinder{ + pixel_y = 5 + }, +/obj/machinery/power/apc{ + areastring = "/area/science/xenobiology"; + dir = 4; + name = "Xenobiology Lab APC"; + pixel_x = 24 + }, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = -24 + }, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_y = -24 + }, +/obj/structure/cable/white{ + icon_state = "0-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) "gii" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -41323,41 +35704,45 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) +"gkP" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) "glC" = ( /turf/closed/wall/r_wall, /area/maintenance/starboard/aft) -"guM" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 +"gre" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 }, +/obj/structure/sign/warning/radiation{ + pixel_x = -32 + }, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -25 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/gravity_generator) +"guM" = ( /obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/structure/cable{ icon_state = "1-2" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "gyV" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -41366,11 +35751,23 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) +"gBp" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/closed/wall/r_wall, +/area/science/mixing) +"gBW" = ( +/obj/structure/sign/poster/random{ + pixel_y = 32 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/engine, +/area/science/xenobiology) "gGq" = ( /obj/machinery/mass_driver{ dir = 4; @@ -41379,19 +35776,13 @@ /turf/open/floor/plating, /area/science/mixing) "gIT" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, /obj/machinery/door/airlock/maintenance_hatch{ name = "Maintenance Hatch"; req_access_txt = "12" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, /turf/open/floor/plasteel, /area/maintenance/port/aft) "gLD" = ( @@ -41422,26 +35813,36 @@ }, /turf/open/floor/plasteel/white/corner, /area/hallway/primary/starboard/fore) -"gNH" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 4 - }, -/turf/open/floor/plating/asteroid/airless, -/area/asteroid/nearstation) -"gPY" = ( -/obj/machinery/vr_sleeper, -/obj/effect/turf_decal/tile/red{ +"gMF" = ( +/mob/living/simple_animal/slime, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ +/turf/open/floor/engine, +/area/science/xenobiology) +"gNH" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 +/obj/machinery/door/airlock/external{ + name = "External Access"; + req_access_txt = "13" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engineering/atmos) +"gPY" = ( +/obj/machinery/vr_sleeper, /turf/open/floor/plasteel, /area/service/bar/atrium) +"gRa" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/engine, +/area/science/xenobiology) "gRe" = ( /obj/structure/cable/white{ icon_state = "1-2" @@ -41450,71 +35851,67 @@ /area/command/gateway) "gSu" = ( /turf/open/floor/plasteel/yellowsiding{ - dir = 8; - icon_state = "yellowsiding" + dir = 8 }, /area/maintenance/starboard/aft) "gSv" = ( -/obj/structure/cable{ +/obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/orange/visible, -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/atmospherics/pipe/simple/dark/visible, +/obj/effect/turf_decal/tile/yellow{ dir = 8 }, -/turf/open/floor/plasteel/dark, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel/dark/corner{ + dir = 1 + }, /area/engineering/atmos) "gVX" = ( /obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/co2{ dir = 8 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "gWt" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/dirt/dust, /obj/machinery/light/broken{ - dir = 1; - icon_state = "tube-broken" + dir = 1 }, /turf/open/floor/carpet/green/airless, /area/maintenance/starboard/aft) +"gYv" = ( +/turf/open/floor/plasteel, +/area/commons/dorms) "gZk" = ( /obj/machinery/atmospherics/pipe/simple/dark/visible{ dir = 10 }, /turf/open/floor/plating/asteroid/airless, /area/asteroid/nearstation) +"heH" = ( +/obj/structure/table/reinforced, +/mob/living/carbon/monkey/punpun, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/service/bar/atrium) "heQ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/navbeacon{ codes_txt = "patrol;next_patrol=8.3-AftSW"; location = "8.2-AftSE" }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/aft) +"hfm" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/closed/wall/r_wall/rust, +/area/science/xenobiology) "hhM" = ( /turf/closed/mineral/random/labormineral, /area/science/test_area) @@ -41567,6 +35964,21 @@ }, /turf/closed/wall/r_wall/rust, /area/engineering/atmos) +"huj" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/service/bar/atrium) +"hvC" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/closed/wall/r_wall, +/area/medical/virology) "hyX" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ dir = 5 @@ -41585,6 +35997,7 @@ /obj/effect/turf_decal/tile/purple{ dir = 4 }, +/obj/machinery/portable_atmospherics/pump, /turf/open/floor/plasteel, /area/science/mixing) "hDi" = ( @@ -41610,6 +36023,10 @@ /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/machinery/light_switch{ + dir = 9; + pixel_x = -22 + }, /turf/open/floor/plasteel/dark, /area/command/gateway) "hIu" = ( @@ -41620,11 +36037,20 @@ dir = 4 }, /obj/effect/turf_decal/trimline/green/line{ - dir = 1; - icon_state = "trimline" + dir = 1 }, /turf/open/floor/plating, /area/maintenance/port/aft) +"hIF" = ( +/obj/structure/sign/warning/vacuum/external{ + pixel_y = -32 + }, +/obj/structure/closet/emcloset/anchored, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engineering/atmos) "hNO" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 5 @@ -41648,15 +36074,6 @@ /obj/structure/cable/white{ icon_state = "0-8" }, -/obj/structure/cable/white{ - icon_state = "1-8" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -41669,10 +36086,27 @@ /obj/machinery/atmospherics/miner/carbon_dioxide, /turf/open/floor/engine/co2, /area/engineering/atmos) +"hPC" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ + dir = 1; + external_pressure_bound = 120; + name = "server vent" + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) "hQH" = ( /obj/structure/sign/warning/vacuum, /turf/closed/wall, /area/cargo/storage) +"hRi" = ( +/turf/open/floor/plasteel, +/area/service/bar/atrium) "hSE" = ( /obj/structure/cable/white{ icon_state = "4-8" @@ -41681,8 +36115,7 @@ dir = 4 }, /obj/effect/turf_decal/trimline/green/line{ - dir = 1; - icon_state = "trimline" + dir = 1 }, /turf/open/floor/plating{ icon_state = "panelscorched" @@ -41694,10 +36127,7 @@ name = "Robotics Lab"; req_access_txt = "29" }, -/obj/machinery/door/airlock/research/glass{ - name = "Robotics Lab"; - req_access_txt = "29" - }, +/obj/machinery/door/firedoor, /turf/open/floor/plasteel, /area/science/robotics/lab) "hUG" = ( @@ -41709,11 +36139,28 @@ /area/engineering/atmos) "hUL" = ( /obj/effect/landmark/start/atmospheric_technician, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 10 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "hVE" = ( /turf/open/floor/plasteel, /area/science/mixing) +"hWW" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/status_display/ai{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/hallway/secondary/exit) "hXc" = ( /turf/closed/wall/rust, /area/science/mixing) @@ -41754,17 +36201,10 @@ }, /obj/machinery/light, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel/dark/corner{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/engineering/atmos) "iey" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -41773,12 +36213,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -41800,15 +36234,18 @@ /obj/machinery/air_sensor/atmos/carbon_tank, /turf/open/floor/engine/co2, /area/engineering/atmos) +"irp" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall/r_wall/rust, +/area/science/mixing) "isT" = ( /turf/open/floor/wood{ icon_state = "wood-broken2" }, /area/maintenance/starboard/aft) "ixk" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 5 }, /turf/open/floor/plasteel, /area/engineering/atmos) @@ -41822,10 +36259,12 @@ /turf/closed/wall, /area/service/lawoffice) "iIj" = ( -/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/orange/visible, +/obj/machinery/door/airlock/maintenance{ + name = "Atmospherics Maintenance"; + req_access_txt = "24" }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engineering/atmos) "iJz" = ( /obj/structure/window/reinforced{ @@ -41835,37 +36274,27 @@ /turf/open/floor/grass, /area/hallway/secondary/entry) "iJY" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/structure/cable{ icon_state = "4-8" }, /obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 6 + }, +/obj/machinery/meter, /turf/open/floor/plasteel, /area/engineering/atmos) "iKp" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 5 - }, /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/machinery/meter/atmos, +/obj/machinery/atmospherics/pipe/simple/orange/visible, /turf/open/floor/plasteel, /area/engineering/atmos) "iML" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "iOL" = ( @@ -41875,6 +36304,10 @@ /obj/structure/lattice/catwalk, /turf/open/space/basic, /area/space/nearstation) +"iQs" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark/corner, +/area/service/hydroponics) "iSq" = ( /turf/open/floor/plating/asteroid/airless, /area/maintenance/starboard/aft) @@ -41883,6 +36316,13 @@ /obj/item/toy/poolnoodle/red, /turf/open/floor/wood, /area/maintenance/starboard/aft) +"iUa" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/closed/wall/r_wall, +/area/engineering/gravity_generator) "iUq" = ( /obj/machinery/status_display, /turf/closed/wall, @@ -41894,6 +36334,13 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/machinery/button/door{ + id = "stationawaygate"; + name = "Gateway Access Shutter Control"; + pixel_x = -1; + pixel_y = -24; + req_access_txt = "31" + }, /turf/open/floor/plasteel, /area/command/gateway) "iUO" = ( @@ -41902,8 +36349,7 @@ /area/science/mixing) "iVs" = ( /obj/machinery/computer/gateway_control{ - dir = 4; - icon_state = "computer" + dir = 4 }, /obj/effect/turf_decal/delivery, /obj/machinery/camera{ @@ -41917,10 +36363,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, /turf/open/floor/plasteel/white, /area/science/xenobiology) "iVy" = ( @@ -41936,7 +36378,10 @@ "iYt" = ( /obj/structure/chair/office/dark, /obj/effect/landmark/start/lawyer, -/turf/open/floor/carpet/green/airless, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/carpet/green, /area/service/lawoffice) "iZQ" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/atmos/carbon_input, @@ -41960,9 +36405,6 @@ codes_txt = "patrol;next_patrol=3.1-AtriumNW"; location = "2.2-BridgeWest" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -41990,12 +36432,16 @@ req_access_txt = "55" }, /obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, /area/science/xenobiology) "jeI" = ( /turf/open/floor/plasteel/yellowsiding{ - dir = 1; - icon_state = "yellowsiding" + dir = 1 }, /area/maintenance/starboard/aft) "jkc" = ( @@ -42011,6 +36457,15 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/engineering/atmos) +"jkQ" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel/white/corner, +/area/hallway/secondary/entry) "jlZ" = ( /obj/structure/closet/crate, /obj/item/stack/ore/silver, @@ -42021,6 +36476,7 @@ /obj/machinery/light/small{ dir = 1 }, +/obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plasteel, /area/maintenance/port/aft) "jnK" = ( @@ -42047,31 +36503,33 @@ dir = 1 }, /area/engineering/atmos) +"jpG" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/space/nearstation) "jqM" = ( /obj/effect/turf_decal/bot, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/starboard) "jrd" = ( -/obj/machinery/pool/drain, -/turf/open/pool, -/area/maintenance/starboard/aft) +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/science/mixing) "jsD" = ( -/obj/effect/mapping_helpers/airlock/locked, /obj/machinery/door/airlock/research/glass/incinerator/toxmix_exterior, /turf/open/floor/engine, /area/science/mixing) "jtZ" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, /turf/open/floor/plasteel, @@ -42087,6 +36545,13 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/wood, /area/maintenance/starboard/aft) +"jvx" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall/r_wall, +/area/engineering/gravity_generator) "jwi" = ( /obj/structure/sign/directions/engineering{ dir = 8; @@ -42109,6 +36574,15 @@ }, /turf/open/floor/plasteel, /area/engineering/atmos) +"jzq" = ( +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/engineering/atmos) "jBh" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -42130,32 +36604,19 @@ /obj/structure/cable/white{ icon_state = "1-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/white, /area/science/xenobiology) "jCi" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 - }, /obj/machinery/light, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 5 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow{ dir = 8 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "jDd" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ @@ -42190,6 +36651,15 @@ /obj/machinery/atmospherics/pipe/simple/dark/visible, /turf/open/floor/plating, /area/science/mixing) +"jJn" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/cryopod{ + dir = 8 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/commons/dorms) "jLF" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -42255,6 +36725,9 @@ /obj/structure/lattice/catwalk, /turf/open/space/basic, /area/space/nearstation) +"kas" = ( +/turf/closed/wall, +/area/engineering/atmos) "kaA" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 1 @@ -42280,7 +36753,6 @@ /turf/open/floor/plating/asteroid/airless, /area/asteroid/nearstation) "kdd" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-8" }, @@ -42296,14 +36768,36 @@ /area/engineering/atmos) "kiw" = ( /obj/machinery/atmospherics/pipe/simple/general/visible, +/obj/machinery/power/terminal, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, /obj/structure/cable{ - icon_state = "4-8" + icon_state = "1-4" }, /obj/effect/turf_decal/stripes/line{ - dir = 8 + dir = 10 }, /turf/open/floor/plasteel, /area/engineering/atmos) +"koJ" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/structure/bed{ + dir = 1 + }, +/obj/machinery/airalarm{ + pixel_y = 22 + }, +/turf/open/floor/plasteel/freezer, +/area/medical/virology) +"koL" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/engineering/main) "kpi" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple, /obj/structure/lattice/catwalk, @@ -42317,14 +36811,12 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/science/mixing) "krX" = ( /obj/machinery/light/floor, /turf/open/floor/plasteel/yellowsiding/corner{ - dir = 4; - icon_state = "yellowcornersiding" + dir = 4 }, /area/maintenance/starboard/aft) "kwF" = ( @@ -42337,17 +36829,10 @@ }, /obj/machinery/light, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel/dark/corner{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/engineering/atmos) "kyS" = ( /obj/structure/chair/stool/bar, @@ -42368,31 +36853,25 @@ /turf/open/floor/plasteel, /area/science/mixing) "kCU" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 1 }, /obj/machinery/meter/atmos, +/obj/machinery/atmospherics/pipe/simple/dark/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engineering/atmos) +"kFf" = ( +/obj/structure/closet/crate/bin, +/turf/open/floor/plasteel, +/area/science/mixing) "kHA" = ( /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 4 }, /obj/machinery/computer/atmos_control/tank/carbon_tank, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "kIL" = ( @@ -42447,16 +36926,31 @@ /turf/open/floor/plating, /area/maintenance/starboard/aft) "kTz" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, /obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/orange/visible, +/obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel, /area/engineering/atmos) "kUu" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, /area/maintenance/starboard/aft) +"kWQ" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/portable_atmospherics/pump, +/turf/open/floor/plasteel, +/area/science/mixing) +"kYh" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/closed/wall/r_wall, +/area/science/mixing) "lcW" = ( /turf/open/floor/wood, /area/maintenance/starboard/aft) @@ -42479,6 +36973,9 @@ pixel_y = 24 }, /obj/effect/landmark/start/lawyer, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, /turf/open/floor/wood, /area/service/lawoffice) "loX" = ( @@ -42515,27 +37012,49 @@ /obj/structure/flora/ausbushes/ywflowers, /turf/open/floor/grass, /area/hallway/secondary/entry) +"lvb" = ( +/obj/structure/sign/warning/vacuum/external{ + pixel_x = -32 + }, +/obj/structure/sign/warning/vacuum/external{ + pixel_x = 32 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "lvw" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible, /obj/effect/decal/cleanable/dirt, /obj/machinery/meter/atmos, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/dark/visible, /turf/open/floor/plasteel/dark/corner{ dir = 1 }, /area/engineering/atmos) +"lwu" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner, +/area/hallway/secondary/exit) "lxq" = ( /obj/structure/cable/white{ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) +"lxu" = ( +/obj/structure/bookcase/random/religion, +/turf/open/floor/plasteel/dark/side{ + dir = 10 + }, +/area/service/library) "lyp" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /obj/effect/turf_decal/tile/blue, @@ -42555,6 +37074,18 @@ }, /turf/open/floor/plasteel, /area/science/mixing) +"lBN" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/extinguisher_cabinet{ + pixel_y = -28 + }, +/turf/open/floor/plasteel, +/area/hallway/secondary/exit) "lCg" = ( /obj/machinery/door/airlock/external{ name = "Supply Dock Airlock"; @@ -42575,13 +37106,20 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/aft) "lFi" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/hallway/primary/starboard) +"lFj" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/barricade/wooden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "lFm" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -42594,7 +37132,7 @@ /area/asteroid/nearstation) "lIM" = ( /turf/closed/wall/rust, -/area/commons/lounge) +/area/hallway/primary/aft) "lMu" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -42606,14 +37144,14 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) +"lSQ" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood{ + icon_state = "wood-broken" + }, +/area/maintenance/port/aft) "lTY" = ( /obj/structure/window/reinforced{ dir = 4 @@ -42629,18 +37167,11 @@ "lXk" = ( /obj/structure/closet/firecloset, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/aft) "lZR" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -42723,6 +37254,12 @@ }, /turf/open/floor/engine/vacuum, /area/maintenance/disposal/incinerator) +"mrI" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/closed/wall/r_wall/rust, +/area/science/xenobiology) "msl" = ( /turf/closed/wall/rust, /area/command/gateway) @@ -42732,12 +37269,12 @@ /area/science/mixing) "msJ" = ( /obj/machinery/atmospherics/pipe/simple/cyan/visible, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/atmospherics/pipe/simple/dark/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "mvB" = ( @@ -42760,22 +37297,19 @@ /obj/structure/cable/white{ icon_state = "0-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "mJP" = ( /obj/machinery/igniter{ id = "Incinerator" }, -/obj/structure/cable{ - icon_state = "4-8" - }, /obj/machinery/air_sensor/atmos/incinerator_tank{ pixel_x = -32; pixel_y = 32 }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, /turf/open/floor/engine/vacuum, /area/maintenance/disposal/incinerator) "mQi" = ( @@ -42798,7 +37332,7 @@ "mTT" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 8; - name = "Port to Fuel Pipe" + name = "Port to Incinerator" }, /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -42810,9 +37344,6 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "mZm" = ( @@ -42845,9 +37376,12 @@ /turf/open/floor/plasteel, /area/maintenance/starboard) "ndg" = ( -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/fore) +"nfH" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/service/bar/atrium) "nfS" = ( /obj/machinery/portable_atmospherics/canister/carbon_dioxide, /turf/open/floor/plating, @@ -42861,20 +37395,48 @@ }, /turf/open/floor/plasteel, /area/science/mixing) +"nhL" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/zone3) "nhU" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/machinery/airalarm{ + dir = 4; + name = "Inceinerator air alarm"; + pixel_x = 10 + }, /turf/closed/wall/r_wall, /area/maintenance/disposal/incinerator) "nio" = ( /obj/structure/pool/ladder{ dir = 1; - icon_state = "ladder"; pixel_y = -24 }, /turf/open/pool, /area/maintenance/starboard/aft) +"nmv" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/service/bar/atrium) "nqr" = ( /obj/item/kirbyplants{ icon_state = "plant-22" @@ -42914,30 +37476,34 @@ /obj/machinery/meter, /turf/open/floor/plasteel, /area/engineering/atmos) +"nHD" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/turf_decal/caution, +/turf/open/floor/plating, +/area/engineering/atmos) "nIf" = ( /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating, /area/maintenance/starboard/aft) "nKi" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, /turf/open/floor/plating, /area/maintenance/starboard/aft) "nMh" = ( @@ -42948,17 +37514,15 @@ /obj/machinery/firealarm{ pixel_y = 24 }, -/obj/machinery/camera{ - c_tag = "Toxins Lab West"; - network = list("ss13","rd") - }, /obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/science/mixing) +"nPS" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/maintenance/solars/port/aft) "nTg" = ( /obj/item/assembly/timer{ pixel_x = 5; @@ -42976,18 +37540,23 @@ "nUk" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/general/visible, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/power/smes, +/obj/structure/cable{ + icon_state = "0-4" + }, /turf/open/floor/plasteel/dark/corner, -/area/engineering/atmos) +/area/maintenance/disposal/incinerator) +"nXb" = ( +/obj/machinery/pool/drain, +/turf/open/pool, +/area/maintenance/starboard/aft) "oaV" = ( /obj/structure/grille, /obj/machinery/meter, -/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/obj/machinery/atmospherics/pipe/layer_manifold, /turf/closed/wall/r_wall, /area/engineering/atmos) "ogx" = ( @@ -43023,11 +37592,11 @@ /turf/closed/wall, /area/asteroid/nearstation) "ooX" = ( -/obj/machinery/smartfridge/organ/preloaded{ - pixel_y = 2 +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 }, -/turf/closed/wall, -/area/medical/medbay/zone3) +/turf/closed/wall/r_wall, +/area/science/mixing) "oql" = ( /obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel, @@ -43038,17 +37607,11 @@ icon_state = "1-8" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/structure/closet/radiation, +/obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "orV" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -43062,20 +37625,9 @@ }, /obj/effect/decal/cleanable/dirt, /obj/machinery/meter/atmos, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "oxb" = ( -/obj/effect/mapping_helpers/airlock/locked, /obj/machinery/door/airlock/research/glass/incinerator/toxmix_interior, /turf/open/floor/engine, /area/science/mixing) @@ -43085,13 +37637,13 @@ dir = 4; luminosity = 2 }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/structure/cable{ +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/yellow{ icon_state = "0-8" }, -/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, /turf/open/floor/engine/vacuum, /area/maintenance/disposal/incinerator) "oys" = ( @@ -43111,17 +37663,11 @@ icon_state = "1-2" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/structure/closet/radiation, +/obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "oGc" = ( /obj/machinery/atmospherics/pipe/simple/cyan/visible{ @@ -43132,8 +37678,7 @@ "oIA" = ( /obj/machinery/light/floor, /turf/open/floor/plasteel/yellowsiding/corner{ - dir = 1; - icon_state = "yellowcornersiding" + dir = 1 }, /area/maintenance/starboard/aft) "oIG" = ( @@ -43152,24 +37697,6 @@ /obj/effect/landmark/start/scientist, /turf/open/floor/plasteel/white, /area/science/mixing) -"oKz" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/command/bridge) "oOk" = ( /turf/open/floor/engine/plasma, /area/engineering/atmos) @@ -43183,7 +37710,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "oXj" = ( @@ -43192,7 +37718,6 @@ }, /obj/machinery/door/window/westright, /obj/effect/decal/cleanable/egg_smudge, -/obj/effect/turf_decal/bot, /turf/open/floor/plasteel/freezer, /area/commons/toilet/restrooms) "oXz" = ( @@ -43220,16 +37745,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/gravity_generator) "pcl" = ( @@ -43250,18 +37765,45 @@ }, /turf/open/floor/plasteel/dark, /area/command/gateway) +"pdQ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, +/area/maintenance/port/aft) "pdX" = ( /obj/machinery/portable_atmospherics/canister, /obj/item/radio/intercom{ pixel_y = 25 }, /obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/science/mixing) +"pej" = ( +/turf/open/floor/engine, +/area/science/xenobiology) +"pgH" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall/r_wall, +/area/science/mixing) +"phb" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 5 + }, +/area/command/bridge) "pix" = ( /turf/open/floor/wood{ icon_state = "wood-broken7" @@ -43300,6 +37842,10 @@ pixel_y = 6; req_access_txt = "55" }, +/obj/machinery/shower{ + dir = 8; + name = "emergency shower" + }, /turf/open/floor/plasteel, /area/science/xenobiology) "pmx" = ( @@ -43336,34 +37882,24 @@ /obj/structure/sign/warning/vacuum{ pixel_y = -32 }, -/obj/structure/cable{ +/obj/structure/cable/yellow{ icon_state = "0-4" }, /turf/open/floor/engine/vacuum, /area/maintenance/disposal/incinerator) "psq" = ( -/obj/structure/sign/poster/random{ - pixel_y = 32 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/camera{ + c_tag = "Gravity Generator Room"; + network = list("ss13","engine") }, /turf/open/floor/plasteel/dark, -/area/science/xenobiology) +/area/engineering/gravity_generator) "puc" = ( /obj/structure/bed, /turf/open/floor/wood, /area/maintenance/starboard/aft) "pvX" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/orange/visible, /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 4 }, @@ -43380,7 +37916,13 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, -/turf/open/floor/plasteel/checker, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/atmospherics/pipe/simple/dark/visible, +/turf/open/floor/plasteel/dark/corner{ + dir = 1 + }, /area/engineering/atmos) "pAN" = ( /obj/structure/table/reinforced, @@ -43392,6 +37934,23 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/white, /area/science/mixing) +"pDm" = ( +/obj/effect/turf_decal/bot_white/right, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/status_display/ai{ + pixel_x = 32 + }, +/turf/open/floor/plasteel/dark, +/area/command/gateway) "pEt" = ( /obj/machinery/power/apc{ areastring = "/area/hallway/primary/starboard/fore"; @@ -43403,9 +37962,6 @@ /obj/structure/cable/white{ icon_state = "0-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, @@ -43429,22 +37985,19 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/science/mixing) "pLb" = ( /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 4 - }, /obj/effect/turf_decal/tile/purple{ dir = 1 }, /obj/effect/turf_decal/tile/purple{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/white, /area/science/xenobiology) "pMh" = ( @@ -43463,7 +38016,6 @@ /obj/structure/sign/poster/official/no_erp{ pixel_x = 32 }, -/obj/effect/turf_decal/bot, /turf/open/floor/plasteel/freezer, /area/commons/toilet/restrooms) "pMQ" = ( @@ -43471,7 +38023,8 @@ icon_state = "1-4" }, /obj/item/reagent_containers/glass/bottle/nutrient/rh, -/turf/open/floor/plating/asteroid/airless, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, /area/maintenance/port/aft) "pNE" = ( /obj/structure/grille, @@ -43491,6 +38044,18 @@ icon_state = "wood-broken5" }, /area/asteroid/nearstation) +"qaX" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/green/visible{ + dir = 1 + }, +/turf/open/floor/engine, +/area/engineering/main) "qcg" = ( /obj/structure/window/reinforced{ dir = 4 @@ -43500,21 +38065,15 @@ /area/hallway/secondary/entry) "qcP" = ( /obj/machinery/door/firedoor/heavy, -/obj/machinery/door/airlock/research{ - name = "Toxins Launch Room Access"; - req_access_txt = "7" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/machinery/door/airlock/research{ + name = "Toxins Launch Room Access"; + req_access_txt = "7" }, /turf/open/floor/plasteel, /area/science/mixing) @@ -43539,16 +38098,18 @@ /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/hallway/primary/fore) +"qdY" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engineering/gravity_generator) "qeO" = ( +/obj/machinery/door/firedoor, /obj/machinery/door/airlock/command{ name = "Gateway"; req_access_txt = "62" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/door/firedoor, /turf/open/floor/plasteel, /area/command/gateway) "qgg" = ( @@ -43559,7 +38120,8 @@ /obj/structure/cable/white{ icon_state = "0-2" }, -/turf/open/floor/plating/asteroid/airless, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, /area/maintenance/port/aft) "qgC" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/atmos/incinerator_input{ @@ -43591,8 +38153,10 @@ /turf/open/floor/plasteel, /area/engineering/atmos) "qpG" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall/r_wall/rust, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, /area/engineering/gravity_generator) "qsc" = ( /obj/machinery/air_sensor/atmos/air_tank, @@ -43625,7 +38189,6 @@ /turf/open/floor/plasteel, /area/engineering/atmos) "qFj" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, @@ -43643,16 +38206,6 @@ dir = 1 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "qHx" = ( @@ -43669,6 +38222,12 @@ }, /turf/open/floor/plasteel, /area/engineering/atmos) +"qKS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/service/bar/atrium) "qMr" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -43677,8 +38236,21 @@ dir = 1 }, /obj/machinery/meter, +/obj/structure/cable{ + icon_state = "2-8" + }, /turf/open/floor/plasteel, /area/engineering/atmos) +"qOl" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/blue, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/zone3) "qRz" = ( /obj/machinery/newscaster{ pixel_x = 32 @@ -43686,13 +38258,18 @@ /obj/machinery/photocopier, /turf/open/floor/wood, /area/service/lawoffice) -"qTa" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 +"qSs" = ( +/turf/open/floor/plasteel/dark/side{ + dir = 6 }, +/area/command/bridge) +"qTa" = ( /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/machinery/atmospherics/pipe/simple/dark/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "qUQ" = ( @@ -43703,9 +38280,7 @@ }, /area/maintenance/starboard/aft) "qUW" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall/r_wall, /area/engineering/atmos) "rae" = ( @@ -43713,8 +38288,23 @@ dir = 1; name = "Air to Pure" }, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engineering/atmos) +"rbN" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, +/area/science/xenobiology) "ria" = ( /obj/effect/turf_decal/bot_white/right, /obj/effect/turf_decal/tile/neutral{ @@ -43740,16 +38330,22 @@ /obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plasteel, /area/engineering/atmos) +"rll" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, +/turf/open/floor/plating, +/area/maintenance/starboard) "rlq" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/aft) "rmZ" = ( @@ -43772,33 +38368,20 @@ /turf/open/floor/plasteel, /area/engineering/atmos) "rCw" = ( -/obj/machinery/door/window/brigdoor{ - dir = 4; - name = "Creature Pen"; - req_access_txt = "47" - }, -/obj/machinery/door/poddoor/preopen{ - id = "xeno4"; - name = "Creature Cell #4" - }, -/obj/structure/cable/white{ - icon_state = "1-8" - }, -/obj/structure/cable/white{ - icon_state = "2-8" - }, -/obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/purple{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 1 }, -/turf/open/floor/plasteel/dark, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, /area/science/xenobiology) "rEx" = ( /obj/machinery/atmospherics/pipe/simple/cyan/visible{ @@ -43808,6 +38391,7 @@ icon_state = "4-8" }, /obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel, /area/engineering/atmos) "rVj" = ( @@ -43860,6 +38444,7 @@ /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/weather, /obj/effect/turf_decal/weather, +/obj/machinery/space_heater, /turf/open/floor/plasteel/dark, /area/maintenance/starboard/aft) "sdX" = ( @@ -43883,6 +38468,12 @@ /obj/machinery/door/firedoor, /turf/open/floor/plasteel, /area/command/gateway) +"snF" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/science/xenobiology) "soC" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -43890,9 +38481,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "spw" = ( @@ -43910,22 +38498,19 @@ name = "CO2 to Pure" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "srR" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/atmos/nitrous_input, /turf/open/floor/engine/n2o, /area/engineering/atmos) +"svk" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/computer/piratepad_control/civilian{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/starboard/fore) "svX" = ( /obj/structure/sign/warning/fire{ pixel_y = -32 @@ -43952,12 +38537,6 @@ /turf/closed/wall/r_wall/rust, /area/command/bridge) "swy" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "swz" = ( @@ -43969,19 +38548,6 @@ "swG" = ( /turf/closed/wall/rust, /area/security/detectives_office) -"swJ" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/command/bridge) "swK" = ( /obj/structure/cable/white{ icon_state = "4-8" @@ -43989,12 +38555,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "swL" = ( @@ -44007,9 +38567,22 @@ "swZ" = ( /turf/closed/wall/r_wall/rust, /area/security/brig) +"sxy" = ( +/obj/structure/girder, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "sxC" = ( /turf/closed/wall/r_wall/rust, /area/ai_monitored/turret_protected/ai) +"syb" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/engine, +/area/science/xenobiology) "syC" = ( /turf/closed/wall/r_wall/rust, /area/command/teleporter) @@ -44025,7 +38598,7 @@ name = "Lawyer RC"; pixel_y = -30 }, -/turf/open/floor/carpet/green/airless, +/turf/open/floor/carpet/green, /area/service/lawoffice) "syT" = ( /turf/closed/wall/r_wall/rust, @@ -44056,13 +38629,10 @@ /turf/closed/wall/rust, /area/service/theater) "sBx" = ( -/obj/effect/landmark/xeno_spawn, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, /obj/structure/cable/white{ icon_state = "4-8" }, +/obj/effect/turf_decal/caution, /turf/open/floor/plating, /area/maintenance/starboard) "sBy" = ( @@ -44082,7 +38652,7 @@ /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/maintenance/starboard) "sCr" = ( /obj/structure/cable/white{ @@ -44093,6 +38663,16 @@ icon_state = "platingdmg2" }, /area/maintenance/port/central) +"sCW" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) "sDl" = ( /turf/closed/wall/rust, /area/commons/dorms) @@ -44138,6 +38718,9 @@ /obj/structure/cable/white{ icon_state = "4-8" }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, /turf/open/floor/plating, /area/maintenance/starboard) "sEq" = ( @@ -44147,7 +38730,7 @@ "sEG" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, -/area/commons/lounge) +/area/hallway/primary/aft) "sEJ" = ( /obj/structure/cable/white{ icon_state = "1-2" @@ -44155,26 +38738,19 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "sEK" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, /obj/machinery/door/airlock/maintenance_hatch{ name = "Maintenance Hatch"; req_access_txt = "12" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, /turf/open/floor/plating, /area/maintenance/starboard) "sEL" = ( @@ -44192,22 +38768,11 @@ name = "Technology Storage"; req_access_txt = "23" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/structure/cable/white{ + icon_state = "1-2" }, /turf/open/floor/plasteel/dark, -/area/maintenance/starboard) +/area/engineering/storage/tech) "sEQ" = ( /obj/structure/rack, /obj/item/radio, @@ -44232,38 +38797,37 @@ pixel_x = -3; pixel_y = -3 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/obj/machinery/power/apc{ + areastring = "/area/engineering/storage/tech"; + dir = 1; + name = "Tech Storage APC"; + pixel_y = 23 + }, +/obj/structure/cable/white{ + icon_state = "0-4" }, /turf/open/floor/plasteel/dark, -/area/maintenance/starboard) +/area/engineering/storage/tech) "sFo" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/obj/structure/cable/white{ + icon_state = "1-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/maintenance/starboard) +/area/engineering/storage/tech) "sFp" = ( /obj/effect/turf_decal/bot{ dir = 1 }, /obj/structure/closet/crate/solarpanel_small, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/light/small{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 5 }, -/turf/open/floor/plasteel/dark, -/area/maintenance/starboard) +/area/engineering/storage/tech) "sFq" = ( /obj/effect/turf_decal/bot, /obj/effect/turf_decal/stripes/line{ @@ -44275,14 +38839,8 @@ /obj/item/aicard, /obj/item/analyzer, /obj/item/assembly/flash/handheld, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, -/area/maintenance/starboard) +/area/engineering/storage/tech) "sFs" = ( /obj/structure/grille, /obj/structure/window/reinforced/fulltile, @@ -44323,33 +38881,24 @@ pixel_x = -4; pixel_y = -4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/camera{ + c_tag = "Tech Storage"; dir = 4 }, /turf/open/floor/plasteel/dark, -/area/maintenance/starboard) +/area/engineering/storage/tech) "sFS" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 10 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/maintenance/starboard) +/area/engineering/storage/tech) "sFT" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/obj/effect/landmark/xeno_spawn, +/turf/open/floor/plasteel/dark/side{ + dir = 6 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/maintenance/starboard) +/area/engineering/storage/tech) "sFU" = ( /obj/effect/turf_decal/bot, /obj/effect/turf_decal/stripes/line{ @@ -44361,14 +38910,16 @@ /obj/item/electronics/apc, /obj/item/electronics/airlock, /obj/item/stock_parts/cell/high, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/light_switch{ + pixel_x = -6; + pixel_y = -24 }, /turf/open/floor/plasteel/dark, -/area/maintenance/starboard) +/area/engineering/storage/tech) "sFX" = ( /obj/machinery/light/small{ dir = 8 @@ -44390,27 +38941,13 @@ /area/hallway/secondary/exit) "sGy" = ( /obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/airlock/engineering{ name = "Technology Storage"; req_access_txt = "23" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, -/area/maintenance/starboard) +/area/engineering/storage/tech) "sGA" = ( /obj/structure/cable/white{ icon_state = "2-4" @@ -44505,16 +39042,12 @@ "sHz" = ( /obj/structure/closet/crate/bin, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/starboard) "sHB" = ( -/obj/effect/turf_decal/tile/red{ +/obj/effect/turf_decal/tile/brown{ dir = 8 }, /turf/open/floor/plasteel/white/corner{ @@ -44528,10 +39061,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "sHV" = ( @@ -44565,10 +39094,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "sIe" = ( @@ -44594,7 +39119,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/red{ +/obj/effect/turf_decal/tile/brown{ dir = 8 }, /turf/open/floor/plasteel/white/corner, @@ -44606,16 +39131,16 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/structure/extinguisher_cabinet{ - pixel_y = -28 - }, /obj/machinery/camera{ c_tag = "Departures Hallway"; dir = 1 }, -/obj/effect/turf_decal/tile/red{ +/obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/machinery/status_display/ai{ + pixel_y = -32 + }, /turf/open/floor/plasteel/white/corner, /area/hallway/secondary/exit) "sIx" = ( @@ -44625,12 +39150,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/machinery/door/firedoor, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 @@ -44641,10 +39160,10 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/red{ +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/turf_decal/tile/brown{ dir = 8 }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "sIB" = ( @@ -44681,13 +39200,11 @@ /turf/closed/wall/rust, /area/maintenance/starboard) "sIP" = ( -/obj/machinery/vending/cola/random, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/obj/machinery/vending/cola/random, +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/hallway/secondary/exit) "sIR" = ( /obj/structure/table, @@ -44742,9 +39259,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "sJc" = ( @@ -44759,22 +39273,16 @@ name = "Shuttle Bay Space Bridge Control"; pixel_y = 27 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Bridge Hatch"; - req_access_txt = "12" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Bridge Hatch"; + req_access_txt = "12" + }, /turf/open/floor/plating, /area/maintenance/starboard) "sJe" = ( @@ -44796,22 +39304,16 @@ /turf/open/floor/plating, /area/maintenance/starboard) "sJj" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Maintenance Hatch"; + req_access_txt = "12" + }, /turf/open/floor/plating, /area/maintenance/starboard) "sJk" = ( @@ -44822,7 +39324,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ +/obj/effect/turf_decal/tile/brown{ dir = 8 }, /turf/open/floor/plasteel/cafeteria, @@ -44834,13 +39336,9 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 6 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "sJq" = ( /obj/structure/sign/directions/engineering{ @@ -44857,11 +39355,9 @@ "sJA" = ( /obj/structure/closet/firecloset, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/hallway/primary/central) "sJD" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -44876,24 +39372,12 @@ "sJJ" = ( /obj/structure/closet/firecloset, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/hallway/primary/port/aft) "sJK" = ( /obj/structure/closet/crate/bin, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/hallway/primary/port/aft) "sJL" = ( /turf/closed/wall/r_wall, @@ -44905,20 +39389,12 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/tcommsat/server) "sJP" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/tcommsat/server) "sJS" = ( @@ -44976,32 +39452,12 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) "sKn" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) "sKp" = ( @@ -45040,25 +39496,18 @@ /turf/closed/wall/r_wall/rust, /area/ai_monitored/turret_protected/ai) "sLx" = ( -/obj/structure/table, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/line, /obj/machinery/camera{ - c_tag = "AI Chamber - Core"; + c_tag = "AI Chamber - Core Fore"; name = "core camera"; network = list("rd") }, /obj/machinery/cell_charger, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/structure/table, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sLy" = ( -/obj/machinery/power/smes{ - charge = 5e+006 - }, /obj/structure/cable{ icon_state = "0-4" }, @@ -45066,21 +39515,20 @@ /obj/machinery/light{ dir = 1 }, +/obj/machinery/power/smes{ + charge = 5e+006 + }, /turf/open/floor/circuit/green, /area/ai_monitored/turret_protected/ai) "sLz" = ( /obj/item/paper_bin, /obj/item/pen, -/obj/structure/table, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/line, /obj/structure/cable{ icon_state = "2-8" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/structure/table, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sLA" = ( @@ -45142,13 +39590,12 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/corner, /area/ai_monitored/turret_protected/ai) "sLL" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ - id = "AI Core shutters"; + id = "aicorewindow"; name = "AI core shutters" }, /turf/open/floor/plating, @@ -45160,10 +39607,9 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/corner{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sLN" = ( /obj/effect/turf_decal/stripes/line{ @@ -45178,11 +39624,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sLP" = ( /obj/machinery/turretid{ @@ -45207,16 +39651,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sLQ" = ( @@ -45253,16 +39687,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sLS" = ( @@ -45272,13 +39696,9 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sLT" = ( /obj/machinery/firealarm{ @@ -45338,11 +39758,9 @@ dir = 8 }, /obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sLZ" = ( /obj/effect/turf_decal/stripes/line{ @@ -45352,13 +39770,9 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sMa" = ( /obj/effect/turf_decal/stripes/line, @@ -45374,10 +39788,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/corner{ dir = 4 }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sMc" = ( /obj/machinery/airalarm{ @@ -45396,19 +39809,13 @@ dir = 10 }, /obj/machinery/camera{ - c_tag = "AI Chamber - Core"; + c_tag = "AI Chamber - Core Aft"; name = "core camera"; network = list("rd") }, /obj/machinery/light{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sMe" = ( @@ -45431,10 +39838,9 @@ icon_state = "1-8" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/corner{ dir = 1 }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sMg" = ( /obj/effect/turf_decal/stripes/line, @@ -45456,16 +39862,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sMm" = ( @@ -45493,43 +39889,25 @@ /obj/item/crowbar, /obj/item/wrench, /obj/item/mmi, -/obj/structure/table, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/structure/table, +/turf/open/floor/plasteel/dark/corner{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sMw" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sMx" = ( /obj/item/folder/blue, /obj/item/assembly/flash/handheld, /obj/structure/table, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/corner{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "sMD" = ( /turf/closed/wall, @@ -45538,19 +39916,14 @@ /turf/closed/wall/rust, /area/ai_monitored/turret_protected/aisat_interior) "sMG" = ( -/obj/machinery/teleport/hub, /obj/machinery/airalarm{ pixel_y = 23 }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/teleport/hub, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sMH" = ( -/obj/machinery/teleport/station, /obj/machinery/light{ dir = 1 }, @@ -45558,19 +39931,12 @@ pixel_y = 32 }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/teleport/station, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sMI" = ( -/obj/machinery/computer/teleporter, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/computer/teleporter, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sMK" = ( @@ -45580,10 +39946,6 @@ "sML" = ( /obj/machinery/door/firedoor, /obj/effect/mapping_helpers/airlock/locked, -/obj/machinery/door/airlock/highsecurity{ - name = "MiniSat Chamber"; - req_access_txt = "16" - }, /obj/machinery/door/poddoor/shutters/preopen{ id = "aicoredoor"; name = "AI Core Access" @@ -45604,15 +39966,9 @@ }, /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/door/airlock/highsecurity{ + name = "MiniSat Chamber"; + req_access_txt = "16" }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) @@ -45667,12 +40023,6 @@ dir = 1 }, /obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sMU" = ( @@ -45690,29 +40040,14 @@ network = list("minisat"); start_active = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/corner, /area/ai_monitored/turret_protected/aisat_interior) "sMW" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, /obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/ai_monitored/turret_protected/aisat_interior) "sMX" = ( /obj/effect/turf_decal/stripes/line{ @@ -45729,14 +40064,9 @@ pixel_x = 26; pixel_y = 26 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/corner{ + dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sMY" = ( /obj/structure/sign/warning/securearea, @@ -45750,16 +40080,7 @@ dir = 9 }, /obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/corner, /area/ai_monitored/turret_protected/aisat_interior) "sNa" = ( /obj/effect/turf_decal/bot, @@ -45774,13 +40095,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/side, /area/ai_monitored/turret_protected/aisat_interior) "sNb" = ( /obj/effect/turf_decal/stripes/line{ @@ -45790,14 +40105,9 @@ dir = 4 }, /obj/item/beacon, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/corner{ + dir = 8 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNc" = ( /obj/structure/sign/warning/securearea, @@ -45854,6 +40164,12 @@ }, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/sand/plating, +/obj/machinery/camera{ + c_tag = "MiniSat External SouthEast"; + dir = 4; + network = list("minisat"); + start_active = 1 + }, /turf/open/floor/plating/airless, /area/ai_monitored/turret_protected/aisat_interior) "sNj" = ( @@ -45864,23 +40180,9 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNk" = ( -/obj/machinery/door/airlock/external{ - name = "MiniSat External Access"; - req_access_txt = "65" - }, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -45888,15 +40190,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/door/airlock/external{ + name = "MiniSat External Access"; + req_access_txt = "65" }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) @@ -45907,13 +40203,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNm" = ( /obj/effect/turf_decal/bot, @@ -45935,32 +40227,20 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNo" = ( -/obj/machinery/door/airlock/hatch{ - name = "MiniSat Antechamber"; - req_one_access_txt = "32;19" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/door/airlock/hatch{ + name = "MiniSat Antechamber"; + req_one_access_txt = "32;19" }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) @@ -45975,19 +40255,16 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNq" = ( /obj/machinery/ai_slipper{ uses = 10 }, /obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/mob/living/simple_animal/bot/secbot/pingsky, /turf/open/floor/circuit/green, /area/ai_monitored/turret_protected/aisat_interior) "sNr" = ( @@ -45998,32 +40275,20 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNs" = ( -/obj/machinery/door/airlock/hatch{ - name = "MiniSat Antechamber"; - req_one_access_txt = "32;19" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/door/airlock/hatch{ + name = "MiniSat Antechamber"; + req_one_access_txt = "32;19" }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) @@ -46038,13 +40303,9 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNu" = ( /obj/effect/turf_decal/bot, @@ -46052,16 +40313,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNv" = ( @@ -46078,42 +40329,30 @@ /obj/machinery/newscaster{ pixel_x = 32 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/side{ + dir = 8 }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNx" = ( /obj/structure/sign/warning/securearea, /turf/closed/wall, /area/ai_monitored/turret_protected/aisat_interior) "sNy" = ( -/obj/machinery/door/airlock/external{ - name = "MiniSat External Access"; - req_access_txt = "65" - }, /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/door/airlock/external{ + name = "MiniSat External Access"; + req_access_txt = "65" }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNz" = ( /obj/item/beacon, /turf/open/floor/carpet, -/area/commons/lounge) +/area/hallway/primary/aft) "sNA" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -46125,14 +40364,9 @@ /obj/machinery/newscaster{ pixel_y = -32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/corner{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNB" = ( /obj/structure/transit_tube, @@ -46151,14 +40385,9 @@ name = "AI Satellite turret control"; pixel_x = 30 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/corner{ + dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNE" = ( /obj/effect/turf_decal/stripes/line{ @@ -46174,13 +40403,9 @@ network = list("minisat"); start_active = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/turf/open/floor/plasteel/dark/corner{ + dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNF" = ( /obj/effect/turf_decal/stripes/corner, @@ -46190,17 +40415,17 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/turf/open/floor/circuit/green, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, /area/ai_monitored/turret_protected/aisat_interior) "sNG" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 +/turf/open/floor/plasteel/dark/corner{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNI" = ( /obj/item/stack/sheet/metal/fifty, @@ -46221,10 +40446,6 @@ dir = 1 }, /obj/structure/table, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNJ" = ( @@ -46235,10 +40456,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNK" = ( @@ -46255,10 +40472,6 @@ dir = 1; pixel_y = -26 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNM" = ( @@ -46275,16 +40488,12 @@ /turf/closed/wall/r_wall, /area/ai_monitored/turret_protected/aisat_interior) "sNS" = ( -/obj/machinery/porta_turret/ai, /obj/effect/turf_decal/delivery, /obj/machinery/airalarm{ dir = 4; pixel_x = -22 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/porta_turret/ai, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNT" = ( @@ -46299,28 +40508,20 @@ pixel_x = -8; pixel_y = 4 }, -/obj/structure/table, /obj/machinery/status_display{ pixel_y = -32 }, /obj/machinery/light, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/structure/table, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sNU" = ( -/obj/machinery/porta_turret/ai, /obj/effect/turf_decal/delivery, /obj/machinery/firealarm{ dir = 1; pixel_y = -26 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/porta_turret/ai, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "sOb" = ( @@ -46347,12 +40548,6 @@ name = "MiniSat Access"; req_access_txt = "65" }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "sOt" = ( @@ -46362,10 +40557,6 @@ /obj/machinery/status_display/ai{ pixel_y = 32 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "sOu" = ( @@ -46378,10 +40569,6 @@ dir = 4 }, /obj/machinery/light/small, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/command/bridge) "sOw" = ( @@ -46442,7 +40629,6 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "sOJ" = ( @@ -46456,35 +40642,23 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, +/obj/machinery/door/firedoor, /obj/machinery/door/airlock{ name = "Primary Restroom" }, -/obj/machinery/door/firedoor, /turf/open/floor/plasteel/freezer, /area/commons/toilet/restrooms) "sOL" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, /obj/machinery/door/airlock/maintenance_hatch{ name = "Maintenance Hatch"; req_access_txt = "12" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, /turf/open/floor/plating, /area/maintenance/starboard) "sOM" = ( @@ -46597,7 +40771,8 @@ "sTH" = ( /obj/machinery/hydroponics/soil, /obj/item/seeds/tower, -/turf/open/floor/plating/asteroid, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, /area/maintenance/port/aft) "sVt" = ( /turf/closed/wall/r_wall, @@ -46610,7 +40785,8 @@ /area/maintenance/starboard/aft) "sZH" = ( /obj/item/reagent_containers/glass/bucket, -/turf/open/floor/plating/asteroid, +/obj/effect/turf_decal/sand, +/turf/open/floor/plating, /area/maintenance/port/aft) "tac" = ( /obj/structure/grille, @@ -46620,12 +40796,12 @@ /area/engineering/atmos) "tdN" = ( /obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/atmospherics/pipe/simple/dark/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "tfP" = ( @@ -46648,6 +40824,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/orange/visible, /turf/open/floor/plasteel, /area/engineering/atmos) "tin" = ( @@ -46659,16 +40836,10 @@ /turf/open/floor/carpet/green/airless, /area/asteroid/nearstation) "tkH" = ( +/obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ name = "Courtroom" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/door/firedoor, /turf/open/floor/plasteel, /area/service/lawoffice) "ttp" = ( @@ -46679,13 +40850,9 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/hallway/primary/port) "ttA" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible, /obj/effect/turf_decal/bot, /obj/machinery/space_heater, /obj/effect/decal/cleanable/dirt, @@ -46695,15 +40862,26 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/dark/visible, /turf/open/floor/plasteel/dark/corner{ dir = 1 }, /area/engineering/atmos) +"twh" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/airlock/external{ + name = "External Access"; + req_access_txt = "13" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating, +/area/engineering/atmos) "twy" = ( /obj/structure/table/reinforced, /obj/machinery/chem_dispenser/drinks{ - dir = 1; - icon_state = "soda_dispenser" + dir = 1 }, /turf/open/floor/wood{ icon_state = "wood-broken6" @@ -46723,16 +40901,26 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "tPn" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/science/mixing) +"tSA" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/hallway/secondary/entry) "tWh" = ( /turf/closed/wall, -/area/commons/lounge) +/area/hallway/primary/aft) "tWQ" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -46760,6 +40948,26 @@ }, /turf/open/floor/plasteel/dark, /area/service/library) +"uac" = ( +/obj/structure/table/reinforced, +/obj/item/storage/box/beakers{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/box/syringes, +/obj/item/extinguisher/mini, +/obj/machinery/airalarm/unlocked{ + dir = 4; + pixel_x = -23 + }, +/obj/machinery/newscaster{ + pixel_y = -32 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) "ucd" = ( /obj/machinery/door/airlock/research{ name = "Toxins Storage"; @@ -46768,11 +40976,31 @@ /turf/open/floor/plating, /area/science/mixing) "ucu" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 }, -/turf/closed/wall, -/area/science/mixing) +/turf/open/floor/plasteel, +/area/engineering/atmos) +"udG" = ( +/obj/structure/table/reinforced, +/obj/item/folder/white, +/obj/item/stack/sheet/mineral/plasma{ + amount = 5 + }, +/obj/item/reagent_containers/glass/beaker/large, +/obj/item/reagent_containers/glass/beaker, +/obj/item/reagent_containers/dropper, +/obj/machinery/status_display{ + pixel_y = -32 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) "udT" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/power/apc{ @@ -46785,9 +41013,6 @@ /obj/structure/cable/white{ icon_state = "0-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "ueC" = ( @@ -46799,9 +41024,6 @@ /turf/open/floor/plasteel, /area/engineering/atmos) "ueG" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 6 - }, /obj/machinery/light{ dir = 8 }, @@ -46812,6 +41034,9 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/dark/visible{ + dir = 6 + }, /turf/open/floor/plasteel/dark/corner{ dir = 1 }, @@ -46838,7 +41063,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/aft) "uhz" = ( @@ -46855,6 +41079,15 @@ /obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/nitrous_output, /turf/open/floor/engine/n2o, /area/engineering/atmos) +"ukp" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/closed/wall/r_wall, +/area/medical/virology) "uok" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 8 @@ -46862,29 +41095,20 @@ /turf/closed/wall/r_wall, /area/engineering/atmos) "upN" = ( -/obj/machinery/door/airlock/research{ - name = "Toxins Launch Room"; - req_access_txt = "7" - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/door/airlock/research{ + name = "Toxins Launch Room"; + req_access_txt = "7" }, /turf/open/floor/plasteel, /area/science/mixing) "uqY" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -46901,16 +41125,6 @@ }, /obj/effect/turf_decal/bot, /obj/structure/table/glass, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/service/hydroponics) "uuJ" = ( @@ -46926,14 +41140,11 @@ "uuU" = ( /obj/machinery/status_display, /turf/closed/wall, -/area/commons/lounge) +/area/hallway/primary/aft) "uuX" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -46944,17 +41155,13 @@ /area/maintenance/disposal/incinerator) "uxJ" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/public/glass{ - name = "Atrium" - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 }, -/turf/open/floor/plasteel, +/obj/machinery/door/airlock/public/glass{ + name = "Atrium" + }, +/turf/open/floor/plasteel/dark, /area/service/bar/atrium) "uxM" = ( /obj/machinery/door/airlock/external{ @@ -46975,20 +41182,20 @@ /turf/open/floor/plasteel, /area/engineering/atmos) "uBJ" = ( -/obj/effect/turf_decal/bot_white/right, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/light{ dir = 8 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/engineering/gravity_generator) +"uBW" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/effect/turf_decal/box, +/obj/machinery/power/tracker, +/turf/open/floor/plasteel/airless/solarpanel, +/area/solars/starboard/fore) "uCY" = ( /turf/open/pool, /area/maintenance/starboard/aft) @@ -47033,18 +41240,14 @@ /turf/open/floor/plasteel/dark, /area/command/gateway) "uMi" = ( -/obj/machinery/door/airlock/security{ - name = "Law Office"; - req_access_txt = "38" - }, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, /obj/structure/cable/white{ icon_state = "1-2" }, +/obj/machinery/door/airlock{ + name = "Law Office"; + req_access_txt = "38" + }, /turf/open/floor/plasteel, /area/service/lawoffice) "uSs" = ( @@ -47053,18 +41256,27 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow{ dir = 8 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) +"uTb" = ( +/obj/machinery/computer/camera_advanced/xenobio{ + dir = 1 + }, +/obj/machinery/light, +/obj/machinery/requests_console{ + department = "Xenobiology Lab"; + name = "Xenobiology RC"; + pixel_y = -32; + receive_ore_updates = 1 + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/circuit/green, +/area/science/xenobiology) "uTF" = ( /obj/machinery/door/window/southleft{ name = "Mass Driver Door"; @@ -47075,8 +41287,8 @@ /area/science/mixing) "uVJ" = ( /obj/effect/decal/cleanable/oil, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 }, /turf/open/floor/plasteel, /area/engineering/atmos) @@ -47103,16 +41315,6 @@ }, /obj/machinery/computer/atmos_control/tank/nitrous_tank, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "vjN" = ( @@ -47125,17 +41327,12 @@ "vkK" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard) "vlJ" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/science/mixing) "vmq" = ( @@ -47156,16 +41353,6 @@ }, /obj/machinery/computer/atmos_control/tank/toxin_tank, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "vmV" = ( @@ -47201,18 +41388,15 @@ /turf/open/floor/plasteel, /area/engineering/atmos) "vsf" = ( -/obj/effect/decal/cleanable/blood/gibs/xeno, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/structure/closet/l3closet/scientist, +/obj/effect/turf_decal/stripes/line, +/obj/item/extinguisher/mini, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/turf/open/floor/plasteel/dark/side{ + dir = 1 }, -/turf/open/floor/plasteel/dark, /area/science/xenobiology) "vsL" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -47244,16 +41428,6 @@ name = "N2O to Pure" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "vuN" = ( @@ -47262,6 +41436,26 @@ }, /turf/open/floor/plasteel, /area/engineering/atmos) +"vuZ" = ( +/obj/structure/disposaloutlet{ + dir = 8 + }, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/turf/open/floor/plating, +/area/space/nearstation) +"vvD" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk, +/obj/structure/sign/warning/deathsposal{ + pixel_y = -32 + }, +/turf/open/floor/plasteel, +/area/medical/virology) "vxf" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -47307,7 +41501,6 @@ /turf/open/floor/plasteel, /area/engineering/atmos) "vJt" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible, /obj/effect/turf_decal/bot, /obj/machinery/space_heater, /obj/machinery/light{ @@ -47321,6 +41514,7 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/dark/visible, /turf/open/floor/plasteel/dark/corner{ dir = 1 }, @@ -47332,6 +41526,42 @@ "vMb" = ( /turf/open/floor/engine/n2o, /area/engineering/atmos) +"vMG" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"vPH" = ( +/obj/effect/turf_decal/box, +/obj/machinery/power/tracker, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel/airless/solarpanel, +/area/solars/port/aft) +"vPL" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/service/bar/atrium) +"vPQ" = ( +/obj/structure/table/wood, +/obj/machinery/computer/libraryconsole, +/obj/structure/sign/poster/random{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "vPZ" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 8 @@ -47354,17 +41584,10 @@ /obj/structure/sign/warning/nosmoking{ pixel_y = -30 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow{ dir = 8 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "vVS" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/atmos/toxin_input, @@ -47378,12 +41601,6 @@ dir = 4 }, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/starboard/fore) "vZb" = ( @@ -47417,23 +41634,48 @@ icon_state = "4-8" }, /obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/hallway/primary/aft) +"wdK" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 1; + name = "Gas to Cooling Loop" + }, +/turf/open/floor/engine, +/area/engineering/main) +"wep" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/mob/living/simple_animal/bot/cleanbot{ + auto_patrol = 1; + icon_state = "cleanbot1"; + name = "Rustbucket" + }, +/turf/open/floor/plasteel/dark/side{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/hallway/primary/aft) +/area/command/bridge) +"wiJ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall/r_wall, +/area/engineering/gravity_generator) "wkn" = ( /obj/machinery/hydroponics/soil, /obj/item/shovel/spade, /obj/item/cultivator, -/turf/open/floor/plating/asteroid, +/obj/effect/turf_decal/sand, +/turf/open/floor/plating, /area/maintenance/port/aft) "wkG" = ( /obj/structure/lattice/catwalk, -/turf/open/floor/plating/airless, +/turf/open/space/basic, /area/space/nearstation) "wkO" = ( /obj/structure/cable/white{ @@ -47448,6 +41690,13 @@ }, /turf/open/floor/plasteel/dark, /area/command/bridge) +"wle" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/space/basic, +/area/solars/starboard/fore) "wqL" = ( /obj/machinery/atmospherics/pipe/simple/yellow/visible{ dir = 4 @@ -47472,7 +41721,8 @@ /obj/structure/cable/white{ icon_state = "0-4" }, -/turf/open/floor/plating/asteroid, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, /area/maintenance/port/aft) "wwT" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ @@ -47480,24 +41730,30 @@ }, /turf/open/floor/plasteel, /area/science/mixing) -"wDb" = ( -/obj/structure/lattice, -/turf/open/space/basic, -/area/space) -"wOe" = ( -/obj/machinery/door/firedoor/heavy, -/obj/machinery/door/airlock/research{ - name = "Toxins Lab"; - req_access_txt = "7" +"wBp" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 }, /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/turf/open/floor/plasteel, +/area/service/bar/atrium) +"wDb" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/sign/warning/radiation{ + pixel_x = -32 }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/turf/open/floor/plasteel/dark, +/area/engineering/gravity_generator) +"wOe" = ( +/obj/machinery/door/firedoor/heavy, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/door/airlock/research{ + name = "Toxins Lab"; + req_access_txt = "7" }, /turf/open/floor/plasteel, /area/science/mixing) @@ -47514,6 +41770,13 @@ /obj/structure/window/reinforced/spawner/west, /turf/open/floor/plasteel/white, /area/science/mixing) +"wQj" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/engineering/main) "wRY" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ dir = 4 @@ -47533,15 +41796,12 @@ /turf/open/floor/engine, /area/engineering/supermatter) "wUL" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/delivery, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/closet/crate, /turf/open/floor/plasteel, -/area/science/xenobiology) +/area/cargo/storage) "wWj" = ( /obj/structure/window/reinforced{ dir = 4 @@ -47554,17 +41814,9 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/corner{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/engineering/atmos) "xdr" = ( /obj/effect/turf_decal/sand/plating, @@ -47585,6 +41837,7 @@ dir = 4 }, /obj/effect/landmark/event_spawn, +/obj/machinery/atmospherics/pipe/simple/general/visible, /turf/open/floor/plasteel, /area/engineering/atmos) "xiZ" = ( @@ -47597,13 +41850,61 @@ }, /turf/open/floor/plasteel, /area/science/mixing) +"xjj" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Science Foyer"; + dir = 6 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/aft) +"xjR" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"xlL" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/science/xenobiology) +"xoR" = ( +/obj/structure/table/reinforced, +/obj/item/storage/box/monkeycubes, +/obj/item/storage/box/monkeycubes, +/obj/machinery/status_display{ + pixel_y = -32 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/camera{ + c_tag = "Xenobiology South"; + dir = 1; + network = list("ss13","rd") + }, +/turf/open/floor/plasteel, +/area/science/xenobiology) "xpX" = ( /obj/structure/toilet{ dir = 8 }, /obj/structure/window/spawner/north, /obj/machinery/door/window/westright, -/obj/effect/turf_decal/bot, /obj/effect/landmark/blobstart, /turf/open/floor/plasteel/freezer, /area/commons/toilet/restrooms) @@ -47614,11 +41915,11 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/orange/visible, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/dark/visible, /turf/open/floor/plasteel/dark/corner{ dir = 1 }, @@ -47631,6 +41932,9 @@ dir = 8; name = "Waste to Filter" }, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "xtL" = ( @@ -47658,52 +41962,54 @@ id = "incineratorturbine" }, /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 9 - }, -/obj/machinery/airalarm{ - dir = 1; - pixel_x = -32; - pixel_y = -22 - }, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/dark/visible{ + dir = 9 + }, /turf/open/floor/plasteel/checker, /area/maintenance/disposal/incinerator) "xwu" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, -/area/engineering/break_room) +/area/engineering/lobby) +"xxx" = ( +/obj/structure/chair/stool/bar, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/service/bar/atrium) "xyo" = ( /obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/obj/machinery/shower{ + dir = 8; + name = "emergency shower" }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/vg_decals/radiation, +/obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/dark/corner, /area/engineering/atmos) "xAj" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/yellow{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plasteel/dark/corner{ dir = 8 }, -/turf/open/floor/plasteel/dark, /area/engineering/atmos) "xEl" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -47716,7 +42022,6 @@ /obj/structure/cable/white{ icon_state = "0-8" }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port) "xEQ" = ( @@ -47724,16 +42029,6 @@ dir = 8 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) "xFw" = ( @@ -47746,6 +42041,40 @@ /obj/structure/grille, /turf/closed/wall/r_wall, /area/engineering/atmos) +"xKp" = ( +/obj/machinery/door/window/brigdoor{ + dir = 4; + name = "Creature Pen"; + req_access_txt = "47" + }, +/obj/machinery/door/poddoor/preopen{ + id = "xeno4"; + name = "Creature Cell #4" + }, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/science/xenobiology) "xMv" = ( /obj/structure/lattice, /obj/structure/fluff/broken_flooring{ @@ -47758,11 +42087,18 @@ /turf/closed/wall, /area/command/gateway) "xPz" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ dir = 9 }, -/turf/open/floor/plating/asteroid/airless, -/area/asteroid/nearstation) +/turf/open/floor/plating, +/area/engineering/atmos) +"xPL" = ( +/obj/structure/girder, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/plating, +/area/maintenance/port/aft) "xTs" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ @@ -47786,6 +42122,22 @@ }, /turf/open/floor/plasteel, /area/command/gateway) +"xZz" = ( +/obj/item/kirbyplants{ + icon_state = "plant-22" + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/service/bar/atrium) "xZO" = ( /obj/effect/mapping_helpers/airlock/locked, /obj/machinery/door/airlock/public/glass{ @@ -47796,9 +42148,6 @@ name = "Incinerator Interior Airlock"; req_access_txt = "12" }, -/obj/structure/cable{ - icon_state = "4-8" - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, @@ -47814,6 +42163,9 @@ sanitize_external = 1; sensor_tag = "incinerator_airlock_sensor" }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, /turf/open/floor/engine, /area/maintenance/disposal/incinerator) "yba" = ( @@ -47831,36 +42183,14 @@ /turf/open/floor/plasteel, /area/science/mixing) "yeE" = ( -/obj/machinery/door/window/brigdoor{ - dir = 4; - name = "Creature Pen"; - req_access_txt = "47" - }, -/obj/machinery/door/poddoor/preopen{ - id = "xeno5"; - name = "Creature Cell #5" - }, -/obj/structure/cable/white{ - icon_state = "1-8" - }, -/obj/structure/cable/white{ - icon_state = "2-8" - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, -/obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/turf_decal/tile/purple{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/effect/turf_decal/tile/purple, +/obj/structure/cable/white{ + icon_state = "4-8" }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/white, /area/science/xenobiology) "yeO" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -47872,49 +42202,37 @@ /turf/open/floor/plasteel, /area/hallway/primary/port/aft) "ygB" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "Maintenance Hatch"; - req_access_txt = "12" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/cable/white{ icon_state = "4-8" }, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "Gateway Maintenance Hatch"; + req_access_txt = "62" + }, /turf/open/floor/plating, /area/maintenance/starboard) "ygE" = ( /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/service/bar/atrium) "yhg" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating{ + icon_state = "panelscorched" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engineering/atmos) +/area/asteroid/nearstation) "yin" = ( /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plating/asteroid, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, /area/maintenance/port/aft) "ykL" = ( /obj/structure/chair/stool/bar, @@ -47936,16 +42254,6 @@ dir = 1 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/engineering/atmos) @@ -70691,7 +64999,7 @@ jFP jFP jFP jFP -jFP +eDE jFP jFP jFP @@ -71203,23 +65511,23 @@ jFP jFP jFP jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa jFP jFP jFP @@ -71460,23 +65768,23 @@ jFP jFP jFP jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa jFP jFP jFP @@ -71717,23 +66025,23 @@ jFP jFP jFP jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa jFP jFP jFP @@ -71974,23 +66282,23 @@ jFP jFP jFP jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP +aaa +aaa +fMP +sdX +aLL +aLL +aLL +sdX +vPH +sdX +aLL +aLL +aLL +sdX +aLL +aaa +aaa jFP jFP jFP @@ -72231,23 +66539,23 @@ jFP jFP jFP jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP +aaa +aaa +fMP +aaa +aaa +aaa +aaa +aaa +aMH +aaa +aaa +aaa +aaa +aaa +aLL +aaa +aaa jFP jFP jFP @@ -72488,21 +66796,21 @@ jFP jFP jFP jFP -jFP -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa aaa aaa +fMP aaa +aKr +aKr +aKr +aKr +aMI +aKr +aKr +aKr +aKr aaa +aLL aaa aaa jFP @@ -72745,21 +67053,21 @@ jFP jFP jFP jFP -jFP -aaa -aaa -aaa -aab -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa aaa aaa +sdX +sdX +aKB +aLz +aLz +aLz +aMQ +bar +bar +bar +bbS +sdX +sdX aaa aaa jFP @@ -73004,19 +67312,19 @@ aaa aaa aaa aaa -pZU -sdX -pZU -pZU -pZU -sdX aLL -sdX -pZU -pZU -pZU -sdX -pZU +aaa +aKF +aKF +aKF +aKF +aMH +aKF +aKF +aKF +aKF +aaa +bcJ aaa aaa jFP @@ -73261,13 +67569,13 @@ aaa aaa aaa aaa -pZU +aLL aaa aaa aaa aaa aaa -aMH +aZS aaa aaa aaa @@ -73754,7 +68062,7 @@ aac aac aac aac -sdX +aKo uhz iye mJP @@ -74017,8 +68325,8 @@ bpn eYe bYE uhz -lrg -aad +akO +aac aad aac aac @@ -74276,8 +68584,8 @@ eyu uvg lFw aad -aac -aac +aad +aad aad aad aad @@ -74532,8 +68840,8 @@ xZO dMl uhz gNH -aad -aad +kas +kas aad aad aad @@ -74788,9 +69096,9 @@ pvX gSv xtL uhz -gNH -aad -aad +nHD +hIF +kas aad aad aad @@ -75037,7 +69345,7 @@ aCF qTa oJp hUG -yhg +hUG hUG hUG ueC @@ -75046,13 +69354,13 @@ kiw nUk ezP xPz -aad -aad -aad -aad -aad -aad -aad +aGe +aGe +aGe +aGe +aGe +aGe +aGe bxd aad aad @@ -75294,7 +69602,7 @@ jpv msJ rjQ rjQ -jtZ +rjQ rjQ bGL vuN @@ -75302,13 +69610,13 @@ jkl eew bgh qUW -aqz -aqz -aGe -sIu -aGe -aGe -aGe +twh +wiJ +wDb +fTp +uBJ +fTp +gre sIu bwY abi @@ -75552,18 +69860,18 @@ tdN oql oql ixk -oql +axk kTz iKp tgp dgV fYx -aCG +iIj ajX -ajX -qpG -uBJ -aIb +aGe +psq +aHe +aId aJh aKp aLD @@ -75809,16 +70117,16 @@ kCU rzq awI uVJ -diG +axU mTv guM oCy orI xyo hNO -aaW -abu +bOy aGe +qdY aId aIc aJi @@ -75838,7 +70146,7 @@ aad aad aLC bae -aLC +nPS aLC sdX sdX @@ -76066,7 +70374,7 @@ mTT tgm vjN hUL -diG +axX rEx jCi anx @@ -76074,9 +70382,9 @@ anx anx uok akM -abu aGe -aHg +qpG +aJh aId aHe pbT @@ -76330,9 +70638,9 @@ xIm rVj aAg akN -akO -anu -aGe +cpn +alI +bwY aGe sIu aJj @@ -76352,10 +70660,10 @@ buO sKn aMJ bak -bat -aLC aLC aLC +nPS +nPS aaa pZU aaa @@ -76580,7 +70888,7 @@ fIN auq hqX wqL -diG +aAn yba eva aqA @@ -76609,10 +70917,10 @@ sKj buR aMJ bal -bau +aLC bbf bbo -aLC +nPS aaa pZU aaa @@ -76834,10 +71142,10 @@ tac xEQ bKQ fvd -mae +awH xeu -wqL -aAn +awL +fLr iJY uSs xIm @@ -76848,7 +71156,7 @@ amF anw anO aop -aGe +iUa aJl aKu aLI @@ -76863,13 +71171,13 @@ aTY aUP buL buP -buS +sKn aMJ bam bav bdC bgk -aLC +nPS sdX sdX aaa @@ -77094,8 +71402,8 @@ fvd mae mkF wqL +diG aAp -yba vVA anx anx @@ -77118,7 +71426,7 @@ sJP aPG buG buI -buK +hPC sKj buR aMJ @@ -77351,8 +71659,8 @@ fFw auq hXn wqL -iIj -iJY +diG +aEg dFV aAh aBp @@ -77362,7 +71670,7 @@ akS alI alI apq -bwY +jvx aJn aKw aLK @@ -77603,13 +71911,13 @@ anx anx anx awC -bKQ +jzq fFw fEt mnD asx aty -eaf +aOS avx aAi axi @@ -77629,13 +71937,13 @@ sJD aMN bxt bwW -aMJ -aMJ -aMJ -sJV -aMJ -aMJ -sJV +aMN +aMN +aMN +sJD +aMN +aMN +sJD bap bau bat @@ -77860,13 +72168,13 @@ vMb srR tac arr -bKQ +anu fFw auq qEl wqL +diG aAp -yba avy aAj blk @@ -77888,11 +72196,11 @@ bwV aRF aSP aEt -bvo +yhg aad bvo aad -aKm +aqo baq bbb aKm @@ -78117,13 +72425,13 @@ gap fnp aqA viy -bKQ +anu qIp mae eOs wqL +diG aAp -yba fjs anx anx @@ -78149,7 +72457,7 @@ aUQ aVK aUQ aXc -aKm +aqo aqo bbc aLv @@ -78379,8 +72687,8 @@ jxc mae hqX wqL -auv -iJY +diG +aPQ kwF aAh aBr @@ -78646,16 +72954,16 @@ uok aEr aFu aGi -aHl +qaX aIi aJs -aKz +wQj buW aMR aMX aMX sJG -aQK +fey aRI aSS aPL @@ -79145,7 +73453,7 @@ aor apv aqA arw -oiL +bhS jxc mae hqX @@ -79171,14 +73479,14 @@ aMT aPK aQN aRK -aSU +aSW aPL aUS aUU aWz aVL ylr -aSG +lvb jXc aME aLv @@ -79910,7 +74218,7 @@ azg aro aro aro -asm +azg bko cWv cWv @@ -79923,7 +74231,7 @@ qui awJ axo ayi -diG +jtZ oGc awF aCA @@ -79940,7 +74248,7 @@ aMW aMW aOD buW -aQK +aQM aRN aSX aPL @@ -79952,13 +74260,13 @@ bvg aKm jlZ vDy -aOI +qFj qFj kdd -aPQ -aPQ -aPQ -aVF +aSG +aSG +aVi +aSG aKV aLn aRA @@ -80162,11 +74470,11 @@ aad aro ars ars -ars +asI ars ars arp -ars +asI ars asu asA @@ -80208,22 +74516,22 @@ aVL bvo aqo aKm -bbj -axU +bbm +aKm aKm aMG aMG aUi aKm -aVG +aSG aKV aSe aSJ aTm aLw -aaa -aaa -aaa +vuZ +aad +aad aaa aaa aaa @@ -80424,7 +74732,7 @@ ayd ayy arq azh -ars +aDm asy ars ars @@ -80437,7 +74745,7 @@ aqz aqz axq cBf -diG +ucu aAr aBy aCD @@ -80472,11 +74780,13 @@ aQV aSq aUk aUi -aVG +aSG aKV aTk aSK aYE +cLO +hvC aKV aad aaa @@ -80494,8 +74804,6 @@ aaa aaa aaa aaa -aaa -aaa jFP jFP jFP @@ -80674,7 +74982,7 @@ acH acH acH acH -ars +aDm agF agF agF @@ -80685,7 +74993,7 @@ agF agF agF ars -asE +azg ars asI atK @@ -80713,7 +75021,7 @@ aOF aPM aQS aRQ -bxu +wdK aUa aUU aUU @@ -80733,10 +75041,10 @@ aVG aKV aTl aXD -aKV -aKV -aKV -aKV +vvD +ukp +koJ +aLw aaa aaa aaa @@ -80979,15 +75287,15 @@ bvo bvo aqo aMw -bbk +pdQ aON aPT aRd aRc aUm aKm -aVH -aRe +aSG +aKV bfH aWL aZB @@ -81224,21 +75532,21 @@ acB aEt aEt aqo -awH -axX -aEg -aEg -axX -axX -aEg -aEg -axX -aEg -aEg -aMD +aqo +aLs +aqo +aqo +aLs +aLs +aqo +aqo +aLs +aqo +aqo +aQB bbm -aOS -aPU +aKm +aKm aRj aSG aUo @@ -81481,7 +75789,7 @@ aLY aNa aEt aqx -awL +aFM axY aEj aFM @@ -81701,7 +76009,7 @@ aep azo aAo acH -ars +afH ars agF aio @@ -81991,14 +76299,14 @@ aHh aIu aJD aKK -aMa +koL aNc aEt atE -axk +aMG aQW aRT -aRU +fHF aUc aUV aVN @@ -82009,7 +76317,7 @@ aYw aZu aQW awB -aQF +aUi aRC aTb aUp @@ -82254,7 +76562,7 @@ sHV avB axl sJI -aSc +vPQ aTc aUd sKd @@ -82266,11 +76574,11 @@ aYx aZv aQW aOV -axU +aKm aKm aTU aKm -aMG +sxy aVI aWw aXd @@ -82476,7 +76784,7 @@ ahz aBw aCp air -aiW +aVV ajW akX alM @@ -82527,7 +76835,7 @@ aQQ aRS aTV aUq -aMG +xPL aVJ aWx aXe @@ -82780,7 +77088,7 @@ aQW aQW sJI aPO -aQU +aXv aRV aUb aUu @@ -82790,7 +77098,7 @@ aKm aKm aKm aZC -aRm +lSQ aRm aZo aZp @@ -83022,14 +77330,14 @@ aKO aMd aNg aEt -awG -axU +bbm +aKm aQW aRX aTf axj aCB -aDm +aDo aDn aDo aKn @@ -83037,9 +77345,9 @@ aLy aFM aFM aPP -aQQ -aSm +lFj aSm +fkE aUJ aKm aVR @@ -83287,7 +77595,7 @@ aTg sJX bxS aVS -aWE +eIk aXh ajG ajG @@ -83520,12 +77828,12 @@ auO avT awO axB -ayt -ayt -ayt +cXu +cXu +cXu aBK aCL -ayt +cXu aEI aFK aGw @@ -83776,9 +78084,9 @@ agF auP avU anH -axC -axC -axC +geZ +geZ +geZ aAC aBL geZ @@ -83801,7 +78109,7 @@ aSa aUg sKe aVU -aWE +lxu aXj ajG aOb @@ -84031,7 +78339,7 @@ arO ajc agF auQ -avV +ccy awP awQ ayu @@ -84057,7 +78365,7 @@ aSb sJS aBn aDf -aVV +aWE aVQ aXg ajG @@ -84291,12 +78599,12 @@ auR avW awQ axD -ayv -ayv +aDD +gYv aAE aBN -ayv -ayv +gYv +aDD aEK awQ aGy @@ -84577,9 +78885,9 @@ aXl aSh aOg aGC -aGC +nhL aPA -aJx +aQI aQD aQI aHi @@ -85062,11 +79370,11 @@ auT avY awQ axG -axG +jJn bxJ -aAH +aDD aBQ -azC +aYe aDF aEN awQ @@ -85308,7 +79616,7 @@ akg ale alU amP -aoC +auv aoC sAc aqU @@ -85321,7 +79629,7 @@ awQ awQ awQ sDl -aAH +aDD bxK awQ awQ @@ -85578,9 +79886,9 @@ sDl axH ayz azD -aAH +aDD aBQ -azD +aVF aDG aEO sDl @@ -85835,8 +80143,8 @@ awQ axI ayA awQ -aAH -aBQ +aQF +aRe awQ aDH aEP @@ -85867,7 +80175,7 @@ aSh bcf bcW bfF -ooX +aSh hSE bfA bfX @@ -86348,10 +80656,10 @@ apI awQ axJ ayB -azD -aAH -aBS -azD +aPU +aDD +aDD +aVH ayz aEQ sDl @@ -86893,7 +81201,7 @@ ajN baA bbq bbq -bbq +qOl bdV aUM aVf @@ -87407,8 +81715,8 @@ aZL baC aHs aSi -aWK -aWK +aSh +aSh aSh aVg aWa @@ -87646,7 +81954,7 @@ aIL aJR aLa aMp -aNt +iQs aOi aPe aQg @@ -87681,14 +81989,14 @@ bjV bjC bjC bkl -blx bjC bjC bjC bjC bjC bjC -bly +bjC +bjC bkS bkX blc @@ -88436,7 +82744,7 @@ aXR aSh aSh aWK -bea +aWK beG aUi aWv @@ -88690,7 +82998,7 @@ aYa aYU aZQ baG -bbv +dIK bbv baG baG @@ -88893,7 +83201,7 @@ aba abm abB acg -swJ +swK adO aez afq @@ -88912,7 +83220,7 @@ apS ara asd ati -asi +xZz asg asg asg @@ -89146,8 +83454,8 @@ aak aar aaD aaQ -acX -abo +swK +swy abC ach acY @@ -89170,22 +83478,22 @@ arb ase hpr asg -asg -asg +hRi +hRi bxG -asg -avi -awn -axP -asg -avi -aAR -asg +hRi +qKS +apV +aoP +hRi +qKS +huj +hRi awT -aAR -avi +huj +qKS bxL -asg +hRi aLf aMt arb @@ -89200,7 +83508,7 @@ aVp aUx aWP uuU -aYc +ugK iey byo byo @@ -89425,8 +83733,8 @@ aoO apU arc asf -asf -asf +nmv +nmv avf awk awU @@ -89434,14 +83742,14 @@ axO ayJ azJ aAO -asf +nmv ayJ aDO aEW awU aGN aHS -asf +nmv aJW ygE aMu @@ -89457,7 +83765,7 @@ aUy aUy aWQ tWh -aYc +ugK iey sKB baI @@ -89659,7 +83967,7 @@ aaa aal aat aaF -aaR +wep abd abp abE @@ -89676,23 +83984,23 @@ ajt akw alp qdD -anb +ndg anS aoP apV uxJ asg -asg +hRi auc avg awl awV -axP -avi +aoP +qKS azK aAP aBZ -avi +qKS aDP aEX aFO @@ -89700,7 +84008,7 @@ aGO aHT gPY dQC -asg +hRi axP ard aOo @@ -89715,7 +84023,7 @@ sNz aWR tWh aYd -bls +iey byq baJ bbz @@ -89725,10 +84033,10 @@ bed beI bff bfL -aYc +ugK bgU bhI -blv +biw bgU aaa aaa @@ -89916,9 +84224,9 @@ aaa aal aau aaG -aaR +phb abc -ggq +qSs abD aci adb @@ -89932,14 +84240,14 @@ aiB aju akx alq -amj +anc anc anT aoQ apW are ash -ash +nfH aud avh awm @@ -89947,17 +84255,17 @@ awW axQ ayK awW -aAQ -ash +wBp +nfH ayK awW -ash +nfH aFP aGP aud -ash +nfH ayK -ash +nfH aAQ aNz aOp @@ -89971,7 +84279,7 @@ aUy aUy aWS lIM -aYe +ugK hOc byo baK @@ -89985,7 +84293,7 @@ bfK ugK bgU bhH -bix +tSA bgU aaa aaa @@ -90174,7 +84482,7 @@ aak aav aaH aaQ -oKz +swK swy abF ack @@ -90198,19 +84506,19 @@ arf asi bvV asg -avi -awn -asg -axP -ayL -asg -aAR +qKS +apV +hRi +aoP +vPL +hRi +huj bxL -avi -asg -asg -asg -asg +qKS +hRi +hRi +hRi +hRi asg asg ayL @@ -90228,7 +84536,7 @@ aVr aUz aWT fgG -aYc +xjj aYW bys byo @@ -90241,7 +84549,7 @@ byo bfK ugK bgV -bhG +jkQ biw bgU aaa @@ -90454,7 +84762,7 @@ ayP ara asj atj -aue +xxx avj awo aue @@ -90481,7 +84789,7 @@ aCM eUz aTD aTD -aVs +lEr aTD aTD aTD @@ -90675,7 +84983,7 @@ aad aad aad aad -aac +aeS aac aaa sdX @@ -90717,7 +85025,7 @@ awp awX axR ayN -aue +asg blj aCb aCe @@ -90973,7 +85281,7 @@ avl awq awY axS -awX +heH aue aAR aCc @@ -91021,10 +85329,10 @@ aae aaa aaa aaa -aaa -aaa -aaa -aaa +aac +aac +aac +aac aaa aaa aaa @@ -91280,9 +85588,9 @@ bjc bfP bfP aad -aaa -aaa -aaa +fji +aac +aac aaa aaa aaa @@ -91526,19 +85834,19 @@ sOV bfP bgm bgY -bgm +pej ibv bgm bgY -bgm +pej ibv bgm bgY -bgm +pej bfP aad -aac -aac +jpG +aKo aad aad aaa @@ -91706,7 +86014,7 @@ sMV sNl sNA sMr -aaa +bea aaa aae aaa @@ -91781,20 +86089,20 @@ bei beL aTS sKZ -bgm +gRa bgZ bhM ibv -bgm +gRa bgZ bhM ibv -bgm -bgZ +gRa +pej bhM sKZ aad -aac +cfq aad aad aad @@ -92051,7 +86359,7 @@ exb bhN bfP bfP -aad +hfm aad aad aad @@ -92296,19 +86604,19 @@ beL nKi bfP bgp -bhb +rbN bhO ibv biX -wUL +bhb bhO nTi jdD bhb bhO bgd -bfP -aad +uac +snF aad aad aad @@ -92556,16 +86864,16 @@ bgq bhc bhP bfN -bhP +xjR pLb bhP bgc -bhP +xlL bjq bjD bgg -bfP -aad +xoR +snF aad aad aad @@ -92813,7 +87121,7 @@ bgr bhd bhQ plz -iVw +sCW jBG iVw biD @@ -92821,8 +87129,8 @@ biY bjr bjE bjR -bfP -aad +uTb +snF aad aad aad @@ -93066,20 +87374,20 @@ baa aZl dfP bfP -bgo +vsf rCw -bhN +vMG ibv -bgo +dZL yeE -bhN +gkP nTi biZ bjs bjF bjS -bfP -aad +udG +snF aad aad aad @@ -93253,8 +87561,8 @@ aad aad aaa aaa -bbT -bbT +aaa +bcF bbT bbT bcF @@ -93291,7 +87599,7 @@ azT aAZ aCg ank -aly +ebS aly aFX aGX @@ -93323,20 +87631,20 @@ bem beO sOV bfP -bgm -bgm -bhS +bgo +xKp +bhN ibv -bgm -bgm -bhS +bgo +cCv +bhN ibv bja bjt bjG bjT -bfP -aad +gia +snF aad aad aad @@ -93509,8 +87817,8 @@ sMq aad aad aaa -adm -bbT +aaa +aaa bbX bbZ bcc @@ -93521,7 +87829,7 @@ bym bdi bdF bxw -bym +aQU afB agu ahj @@ -93548,11 +87856,11 @@ sEJ aBa aBa anl -aDZ +tLt mXV aFY bsz -aDZ +tLt aIY fff sJa @@ -93580,20 +87888,20 @@ ben beP bfn bfP -vsf -bhg -bgm +gRa +pej +bnS ibv -psq -bgZ -bgm +gRa +pej +bnS xFw bjb bju bjH -bfP -sKZ -aad +dxC +bRW +mrI aad aad aad @@ -93767,8 +88075,8 @@ aad aad aaa aad -bbU -bbT +aaa +bbX bca bbT bcH @@ -93794,7 +88102,7 @@ apb nwY sOF sOG -atq +sEK oyD oyD sOK @@ -93837,19 +88145,19 @@ beo aZl sPK bfP -bgm +syb bhg -bgm +pej ibv -bgm -bhg -bgm +gBW +gMF +pej bfP bjc bjv bjc bfP -aad +bfP aad aad aad @@ -94058,7 +88366,7 @@ acx axf oyD aRz -sEK +rll sJN aRz aRz @@ -94094,13 +88402,13 @@ bep aZl sPI bfP -bgm +pej bhi -bgm +pej ibv -bgm +pej bhi -bgm +pej sKZ bjd bjw @@ -94541,7 +88849,7 @@ bbW bcQ adq aad -bbT +bbX bcK bdE adu @@ -94572,10 +88880,10 @@ xpX pML oyD bfp -aSD -aRz -aRz -aRz +adm +bls +bls +bls saI aRz sIb @@ -94798,7 +89106,7 @@ aef aaa aaa aaa -bbT +bbX bcL bcR adu @@ -94806,9 +89114,9 @@ aeb aeP adu aec -aeS +ajI afF -agx +wUL aii adp aiL @@ -94829,10 +89137,10 @@ oyD oyD oyD sGY -aRz +bls sFn sFR -sJN +blv sGY aRz bmb @@ -95055,8 +89363,8 @@ adq sdX sdX sdX -bbT -bbT +bbX +bbX bbU adu adu @@ -95089,7 +89397,7 @@ sEn sEN sFo sFS -aSH +blx sGY aRz sIc @@ -95321,7 +89629,7 @@ aad adn aee aeU -afH +aeU agA aho aif @@ -95333,7 +89641,7 @@ amA ano aog apg -aqk +svk aRz abN acy @@ -95343,14 +89651,14 @@ eOg sDq aRz bfp -aRz +bls sFp sFT sGy sHb aRz bxM -bsC +lBN axW aae sIU @@ -95373,7 +89681,7 @@ hXc abP jLF aAY -hVE +kFf bdA aRy aRy @@ -95600,10 +89908,10 @@ xMZ bRf xMZ ygB -aRz +bls sFq sFU -aRz +bls sGY sJN blM @@ -95863,7 +90171,7 @@ aRz aSD sHd aRz -bxM +hWW bsC sIG aRz @@ -95896,8 +90204,8 @@ lMu aRy bhm bhX -jrd uCY +nXb nio jeI juY @@ -96330,7 +90638,7 @@ aaa aaa aaa aaa -pZU +sdX aaa aaa aaa @@ -96342,7 +90650,7 @@ aaa aaa aaa aaa -pZU +sdX aaa aaa aaa @@ -96368,13 +90676,13 @@ bvg xMZ uIq pcD -ria +pDm kQz xWb sEQ bRf aRz -atq +sEK aRz aRz bmh @@ -96587,7 +90895,7 @@ aaa aaa aaa aaa -sdX +aLL aaa abL abL @@ -96599,7 +90907,7 @@ abL abL abL aaa -sdX +pZU aaa aaa aaa @@ -96844,7 +91152,7 @@ jFP aaa aaa aaa -pZU +aLL sdX abM bbQ @@ -96893,9 +91201,9 @@ bsS sHC sId bsM -bsS +lwu sIR -bsS +lwu bsY axW aae @@ -97101,13 +91409,13 @@ jFP aaa aaa aaa -pZU +aLL aaa acu acu acu acu -aef +wle acu acu acu @@ -97358,19 +91666,19 @@ jFP aaa aaa aaa -pZU +sdX aaa aaa aaa aaa aaa -adt +aef aaa aaa aaa aaa aaa -pZU +sdX aaa aaa aaa @@ -97615,19 +91923,19 @@ jFP aaa aaa aaa -sdX -sdX -pZU -pZU -pZU -sdX bcJ -sdX +aaa +abL +abL +abL +abL +adt +abL +abL +abL +abL +aaa pZU -pZU -pZU -sdX -sdX aaa aaa aaa @@ -97686,12 +91994,12 @@ xiZ wvy bfz bfB -mvB -mvB +hVE +hVE kqH vlJ pHH -ucu +kPi aad aad aad @@ -97706,7 +92014,7 @@ aaa aaa aaa aaa -wDb +sdX aaa aaa aaa @@ -97872,19 +92180,19 @@ jFP aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +aLL +sdX +abM +bbQ +bbQ +bbQ +adM +bbV +bbV +bbV +bcD +sdX +pZU aaa aaa aaa @@ -97939,7 +92247,7 @@ bdI bdM bft ajP -mhf +kWQ kCG ybw vGQ @@ -97948,7 +92256,7 @@ eZs vPZ jde pmK -iio +kPi aad aad aad @@ -97960,7 +92268,7 @@ aad aaa aaa aaa -wDb +sdX aaa sjr aaa @@ -98129,19 +92437,19 @@ jFP aaa aaa aaa +pZU aaa +acu +acu +acu +acu +aef +acu +acu +acu +acu aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +pZU aaa aaa aaa @@ -98200,12 +92508,12 @@ sVt sVt sVt qcP -sVt -meo -meo -sVt -sVt -sVt +pgH +irp +irp +pgH +pgH +kYh iio aad aad @@ -98386,19 +92694,19 @@ jFP aaa aaa aaa +pZU aaa aaa aaa aaa aaa +adt aaa aaa aaa aaa aaa -aaa -aaa -aaa +pZU aaa aaa aaa @@ -98451,7 +92759,7 @@ aJO aJO bdK bew -ajP +bly ajP sVt meo @@ -98472,7 +92780,7 @@ aaa aaa aaa aaa -wDb +sdX aaa aaa nqr @@ -98643,19 +92951,19 @@ jFP aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +pZU +sdX +pZU +pZU +pZU +sdX +uBW +sdX +pZU +pZU +pZU +sdX +pZU aaa aaa aaa @@ -98708,7 +93016,7 @@ aaa aJO aJO aJO -ajP +bly dfK dfK sVt @@ -98965,7 +93273,7 @@ aaa aaa aad aad -meo +buS dfK qnA ucd @@ -99155,23 +93463,23 @@ jFP jFP jFP jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa jFP jFP jFP @@ -99222,11 +93530,11 @@ aaa aaa aac aad -sVt +jrd lmq nfS -sVt -iio +gBp +gfr upN iio iio @@ -99412,23 +93720,23 @@ jFP jFP jFP jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP -jFP +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa jFP jFP jFP @@ -99479,10 +93787,10 @@ aaa aaa aac aad -sVt -sVt -sVt -sVt +ooX +gcw +gcw +eDk gLD lFm uTF diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 536d5f4aa3..207b47c096 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -223,6 +223,16 @@ /obj/structure/sign/poster/official/medical_green_cross{ pixel_x = 32 }, +/obj/machinery/light/small{ + dir = 1; + light_color = "#ffc1c1" + }, +/obj/item/kirbyplants{ + icon_state = "plant-11" + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "aay" = ( @@ -1734,6 +1744,16 @@ /turf/open/floor/plating, /area/security/prison) "aeo" = ( +/obj/machinery/washing_machine, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison) +"aep" = ( /obj/machinery/hydroponics/constructable, /obj/item/seeds/potato, /obj/item/seeds/carrot, @@ -1743,14 +1763,14 @@ }, /turf/open/floor/plasteel/dark, /area/security/prison) -"aep" = ( +"aeq" = ( /obj/item/cultivator, /obj/structure/cable{ icon_state = "1-4" }, /turf/open/floor/plasteel/dark, /area/security/prison) -"aeq" = ( +"aer" = ( /obj/machinery/hydroponics/constructable, /obj/structure/cable{ icon_state = "4-8" @@ -1765,7 +1785,7 @@ }, /turf/open/floor/plasteel/dark, /area/security/prison) -"aer" = ( +"aes" = ( /obj/item/reagent_containers/glass/bucket, /obj/structure/cable{ icon_state = "1-4" @@ -1775,7 +1795,7 @@ }, /turf/open/floor/plasteel/dark, /area/security/prison) -"aes" = ( +"aet" = ( /obj/structure/easel, /obj/item/canvas/nineteenXnineteen, /obj/structure/cable{ @@ -1786,7 +1806,7 @@ }, /turf/open/floor/plasteel/dark, /area/security/prison) -"aet" = ( +"aeu" = ( /obj/structure/cable{ icon_state = "2-8" }, @@ -1795,19 +1815,6 @@ }, /turf/open/floor/plasteel/dark, /area/security/prison) -"aeu" = ( -/obj/machinery/biogenerator, -/obj/structure/sign/poster/official/random{ - pixel_y = 32 - }, -/obj/effect/turf_decal/tile/green{ - dir = 1 - }, -/obj/effect/turf_decal/tile/green{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) "aev" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 @@ -1848,7 +1855,7 @@ network = list("minisat") }, /turf/open/space, -/area/ai_monitored/turret_protected/AIsatextAP) +/area/ai_monitored/turret_protected/AIsatextAS) "aeA" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 @@ -1862,35 +1869,61 @@ /turf/open/floor/plating, /area/ai_monitored/turret_protected/AIsatextAS) "aeC" = ( +/obj/structure/table, +/obj/structure/bedsheetbin, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/window/reinforced, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison) +"aeD" = ( +/obj/machinery/biogenerator, +/obj/structure/sign/poster/official/random{ + pixel_y = 32 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"aeE" = ( +/obj/structure/sink{ + pixel_y = 30 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison) +"aeF" = ( /obj/machinery/hydroponics/constructable, /obj/item/seeds/grass, /turf/open/floor/plasteel/dark, /area/security/prison) -"aeD" = ( +"aeG" = ( /obj/item/plant_analyzer, /obj/item/shovel/spade, /turf/open/floor/plasteel/dark, /area/security/prison) -"aeE" = ( +"aeH" = ( /obj/machinery/hydroponics/constructable, /obj/item/seeds/sunflower, /obj/item/seeds/poppy, /turf/open/floor/plasteel/dark, /area/security/prison) -"aeF" = ( -/obj/machinery/holopad, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"aeG" = ( -/obj/item/storage/crayons, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"aeH" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) "aeJ" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 @@ -1961,38 +1994,32 @@ }, /turf/open/floor/plating, /area/ai_monitored/turret_protected/AIsatextAS) -"aeT" = ( -/obj/structure/bookcase, -/turf/open/floor/plasteel/dark, -/area/security/prison) "aeU" = ( +/obj/machinery/holopad, /turf/open/floor/plasteel/dark, /area/security/prison) "aeV" = ( -/obj/effect/landmark/xeno_spawn, +/obj/item/storage/crayons, /turf/open/floor/plasteel/dark, /area/security/prison) "aeW" = ( -/obj/structure/sink{ - pixel_y = 30 +/obj/structure/cable{ + icon_state = "1-2" }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/cafeteria, +/turf/open/floor/plasteel/dark, /area/security/prison) "aeX" = ( -/obj/machinery/washing_machine, -/obj/effect/turf_decal/tile/blue{ - dir = 4 +/obj/machinery/seed_extractor, +/obj/effect/turf_decal/tile/green{ + dir = 1 }, -/obj/effect/turf_decal/tile/blue{ +/obj/effect/turf_decal/tile/green{ dir = 8 }, -/turf/open/floor/plasteel/cafeteria, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, /area/security/prison) "aeY" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ @@ -2055,12 +2082,12 @@ /turf/open/floor/plating, /area/ai_monitored/turret_protected/AIsatextAP) "afd" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 - }, /obj/structure/cable/yellow{ icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "afe" = ( @@ -2076,6 +2103,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "aff" = ( @@ -2091,6 +2121,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "afg" = ( @@ -2108,14 +2141,18 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "afh" = ( /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) @@ -2127,24 +2164,21 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plating, /area/ai_monitored/turret_protected/AIsatextAS) "afj" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/structure/cable/yellow{ icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plating, /area/ai_monitored/turret_protected/AIsatextAS) "afk" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 - }, /obj/structure/cable/yellow{ icon_state = "4-8" }, @@ -2155,15 +2189,21 @@ c_tag = "MiniSat Maintenance Starboard Aft"; network = list("minisat") }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plating, /area/ai_monitored/turret_protected/AIsatextAS) "afl" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, /obj/structure/cable/yellow{ icon_state = "4-8" }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, /turf/open/floor/plating, /area/ai_monitored/turret_protected/AIsatextAS) "afm" = ( @@ -2180,37 +2220,40 @@ /turf/open/floor/plating, /area/ai_monitored/turret_protected/AIsatextAS) "afn" = ( -/obj/machinery/computer/libraryconsole/bookmanagement, -/obj/structure/table, -/obj/machinery/newscaster{ - pixel_x = -32 +/obj/machinery/vr_sleeper{ + dir = 8 }, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"afo" = ( -/obj/structure/chair/stool, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"afp" = ( -/obj/item/storage/dice, -/obj/structure/table, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"afq" = ( -/obj/structure/table, -/obj/item/instrument/harmonica, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"afr" = ( /obj/effect/turf_decal/tile/blue{ dir = 8 }, /obj/effect/turf_decal/tile/blue{ dir = 4 }, -/obj/machinery/light/small, /turf/open/floor/plasteel/cafeteria, /area/security/prison) +"afo" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison) +"afp" = ( +/obj/structure/bookcase, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"afq" = ( +/obj/effect/landmark/xeno_spawn, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"afr" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "aft" = ( /obj/machinery/light/small{ dir = 8 @@ -2282,60 +2325,46 @@ /turf/open/floor/plating, /area/ai_monitored/turret_protected/AIsatextAS) "afC" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 +/obj/structure/cable{ + icon_state = "2-8" }, /turf/open/floor/plasteel/dark, /area/security/prison) "afD" = ( -/obj/structure/chair/stool, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, +/obj/structure/weightmachine/weightlifter, /turf/open/floor/plasteel/dark, /area/security/prison) "afE" = ( -/obj/item/toy/cards/deck, -/obj/structure/table, -/turf/open/floor/plasteel/dark, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/cafeteria, /area/security/prison) "afF" = ( -/obj/item/paper_bin{ - pixel_x = -3; - pixel_y = 7 - }, -/obj/item/pen, +/obj/machinery/computer/libraryconsole/bookmanagement, /obj/structure/table, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 6 +/obj/machinery/newscaster{ + pixel_x = -32 }, /turf/open/floor/plasteel/dark, /area/security/prison) "afG" = ( /obj/structure/chair/stool, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, /turf/open/floor/plasteel/dark, /area/security/prison) "afH" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, +/obj/item/storage/dice, +/obj/structure/table, /turf/open/floor/plasteel/dark, /area/security/prison) "afI" = ( -/obj/machinery/computer/arcade{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) "afJ" = ( /obj/effect/turf_decal/tile/neutral, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -2405,43 +2434,44 @@ }, /turf/open/floor/plating, /area/ai_monitored/turret_protected/AIsatextAS) -"afU" = ( -/turf/closed/wall, -/area/security/execution/transfer) -"afX" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) "afZ" = ( -/obj/machinery/vending/sustenance, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"aga" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"agb" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"agc" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/machinery/door/window/westleft{ - base_state = "right"; - icon_state = "right"; - name = "Unisex Showers" - }, -/turf/open/floor/plasteel/freezer, -/area/security/prison) -"agd" = ( /obj/machinery/shower{ dir = 8 }, /obj/item/bikehorn/rubberducky, /turf/open/floor/plasteel/freezer, /area/security/prison) +"aga" = ( +/obj/structure/table, +/obj/item/instrument/harmonica, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"agb" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel/cafeteria, +/area/security/prison) +"agc" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"agd" = ( +/obj/structure/chair/stool, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "age" = ( /obj/machinery/teleport/station, /obj/effect/turf_decal/stripes/line{ @@ -2474,41 +2504,23 @@ /turf/open/floor/plating, /area/ai_monitored/turret_protected/aisat_interior) "agi" = ( -/obj/machinery/door/poddoor{ - id = "executionspaceblast" - }, -/turf/open/floor/plating, -/area/security/execution/transfer) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison) "agj" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 5 +/obj/machinery/computer/cryopod{ + dir = 1; + pixel_y = -26 }, -/obj/machinery/light/small{ +/turf/open/floor/plasteel/dark, +/area/security/prison) +"agl" = ( +/obj/machinery/cryopod{ dir = 1 }, -/turf/open/floor/plating, -/area/security/execution/transfer) -"agl" = ( -/obj/structure/table/glass, -/obj/item/restraints/handcuffs, -/obj/item/razor, -/obj/machinery/light/small{ - dir = 4 - }, /turf/open/floor/plasteel/dark, -/area/security/execution/transfer) +/area/security/prison) "agn" = ( -/obj/machinery/vending/cola, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"ago" = ( -/obj/structure/window/reinforced{ - dir = 8; - layer = 2.9 - }, -/turf/open/floor/plasteel/freezer, -/area/security/prison) -"agp" = ( /obj/item/soap/nanotrasen, /turf/open/floor/plasteel/freezer, /area/security/prison) @@ -2545,54 +2557,11 @@ /turf/open/floor/plating, /area/ai_monitored/turret_protected/aisat_interior) "agv" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plating, -/area/security/execution/transfer) +/obj/item/toy/cards/deck, +/obj/structure/table, +/turf/open/floor/plasteel/dark, +/area/security/prison) "agw" = ( -/obj/machinery/door/airlock/security{ - aiControlDisabled = 1; - name = "Solutions Room"; - req_access_txt = "2" - }, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"agx" = ( -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"agy" = ( -/turf/closed/wall, -/area/security/prison) -"agz" = ( -/obj/machinery/door/poddoor/preopen{ - id = "permacell2"; - name = "cell blast door" - }, -/obj/machinery/door/airlock/public/glass{ - id_tag = "permabolt2"; - name = "Cell 2" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"agA" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/turf/closed/wall, -/area/security/prison) -"agB" = ( /obj/structure/cable{ icon_state = "1-2" }, @@ -2617,11 +2586,42 @@ }, /turf/open/floor/plasteel/dark, /area/security/prison) -"agC" = ( -/obj/machinery/door/airlock{ - name = "Unisex Restroom" +"agx" = ( +/obj/item/paper_bin{ + pixel_x = -3; + pixel_y = 7 }, -/turf/open/floor/plasteel/freezer, +/obj/item/pen, +/obj/structure/table, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"agy" = ( +/turf/closed/wall, +/area/security/prison) +"agz" = ( +/obj/structure/chair/stool, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"agA" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"agB" = ( +/obj/machinery/computer/arcade{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, /area/security/prison) "agD" = ( /obj/machinery/light/small{ @@ -2638,52 +2638,6 @@ /turf/open/floor/plating, /area/ai_monitored/turret_protected/aisat_interior) "agF" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plating, -/area/security/execution/transfer) -"agH" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"agI" = ( -/obj/structure/bed, -/obj/machinery/camera{ - c_tag = "Permabrig Cell 2"; - network = list("ss13","prison") - }, -/obj/item/radio/intercom{ - desc = "Talk through this. It looks like it has been modified to not broadcast."; - name = "Prison Intercom (General)"; - pixel_y = 24; - prison_radio = 1 - }, -/obj/machinery/light/small{ - dir = 1 - }, -/obj/item/toy/plush/slimeplushie, -/turf/open/floor/plasteel, -/area/security/prison) -"agK" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/machinery/button/door{ - id = "permabolt2"; - name = "Cell Bolt Control"; - normaldoorcontrol = 1; - pixel_y = 25; - specialfunctions = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 - }, -/obj/structure/chair, -/turf/open/floor/plasteel, -/area/security/prison) -"agL" = ( /obj/structure/bed, /obj/machinery/camera{ c_tag = "Permabrig Cell 1"; @@ -2701,16 +2655,7 @@ /obj/item/toy/plush/lizardplushie, /turf/open/floor/plasteel, /area/security/prison) -"agM" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"agN" = ( +"agH" = ( /obj/machinery/light/small{ dir = 1 }, @@ -2727,23 +2672,27 @@ /obj/structure/chair, /turf/open/floor/plasteel, /area/security/prison) -"agO" = ( -/obj/structure/sink{ - dir = 8; - pixel_x = -12; - pixel_y = 2 - }, -/obj/machinery/light/small{ - dir = 4 - }, -/turf/open/floor/plasteel/freezer, -/area/security/prison) -"agP" = ( +"agI" = ( /turf/closed/wall, -/area/security/office) -"agQ" = ( +/area/security/execution/transfer) +"agK" = ( /obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"agL" = ( +/obj/machinery/vending/sustenance, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"agM" = ( +/obj/machinery/door/poddoor{ + id = "executionspaceblast" + }, /turf/open/floor/plating, +/area/security/execution/transfer) +"agP" = ( +/obj/machinery/suit_storage_unit/security, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/showroomfloor, /area/security/office) "agR" = ( /obj/structure/sign/warning/vacuum/external{ @@ -2757,41 +2706,6 @@ /turf/open/space/basic, /area/space/nearstation) "agT" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/machinery/door/poddoor/preopen{ - id = "executionfireblast" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/turf/open/floor/plating, -/area/security/execution/transfer) -"agV" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security{ - aiControlDisabled = 1; - name = "Solutions Room"; - req_access_txt = "2" - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"agW" = ( -/obj/machinery/flasher{ - id = "PCell 2"; - pixel_x = -28 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plasteel, -/area/security/prison) -"agY" = ( -/obj/structure/table, -/obj/item/paper, -/obj/item/pen, -/turf/open/floor/plasteel, -/area/security/prison) -"agZ" = ( /obj/machinery/flasher{ id = "PCell 1"; pixel_x = -28 @@ -2799,24 +2713,37 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel, /area/security/prison) +"agW" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating, +/area/security/execution/transfer) +"agZ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/flasher{ + id = "executionflash"; + pixel_y = 25 + }, +/obj/machinery/igniter{ + id = "secigniter" + }, +/turf/open/floor/plating, +/area/security/execution/transfer) "aha" = ( -/obj/structure/cable{ - icon_state = "1-2" +/obj/effect/turf_decal/stripes/line{ + dir = 5 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel, -/area/security/prison) -"ahb" = ( -/obj/structure/toilet/secret/prison{ - dir = 8 +/obj/machinery/light/small{ + dir = 1 }, -/turf/open/floor/plasteel/freezer, -/area/security/prison) -"ahd" = ( -/obj/structure/closet/secure_closet/security/sec, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) +/turf/open/floor/plating, +/area/security/execution/transfer) "ahh" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 @@ -2832,84 +2759,12 @@ /turf/open/space, /area/space/nearstation) "ahj" = ( -/obj/structure/rack, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/obj/item/clothing/suit/straight_jacket, -/obj/item/tank/internals/anesthetic, -/obj/item/clothing/mask/breath/medical, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"ahk" = ( -/obj/machinery/button/flasher{ - id = "executionflash"; - pixel_x = 6; - pixel_y = 27 - }, -/obj/machinery/button/door{ - id = "executionspaceblast"; - name = "Vent to Space"; - pixel_x = -6; - pixel_y = 32; - req_access_txt = "7" - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/machinery/button/ignition{ - id = "secigniter"; - pixel_x = 6; - pixel_y = 36 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"ahl" = ( -/obj/item/radio/intercom{ - name = "Station Intercom (General)"; - pixel_x = 28 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"ahm" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Long-Term Cell 2"; - req_access_txt = "2" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"ahn" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 5 - }, -/turf/closed/wall, -/area/security/prison) -"aho" = ( /obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ dir = 4 }, /turf/closed/wall, /area/security/prison) -"ahp" = ( +"ahk" = ( /obj/machinery/door/airlock/security/glass{ name = "Long-Term Cell 1"; req_access_txt = "2" @@ -2923,19 +2778,45 @@ }, /turf/open/floor/plasteel, /area/security/prison) -"ahq" = ( -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) -"ahr" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ +"ahl" = ( +/obj/structure/table/glass, +/obj/item/restraints/handcuffs, +/obj/item/razor, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"ahm" = ( +/obj/machinery/vending/cola, +/turf/open/floor/plasteel/dark, +/area/security/prison) +"ahn" = ( +/obj/structure/lattice, +/obj/machinery/camera/motion{ + c_tag = "Armory External"; + dir = 1 + }, +/turf/open/space, +/area/space/nearstation) +"aho" = ( +/obj/structure/window/reinforced{ + dir = 8; + layer = 2.9 + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison) +"ahp" = ( +/obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/machinery/door/airlock/external{ - name = "Security External Airlock"; - req_access_txt = "63" - }, /turf/open/floor/plating, -/area/maintenance/fore) +/area/security/execution/transfer) +"ahr" = ( +/obj/structure/chair, +/obj/machinery/atmospherics/components/unary/outlet_injector/on, +/turf/open/floor/plating, +/area/security/execution/transfer) "ahs" = ( /obj/structure/lattice/catwalk, /obj/structure/transit_tube, @@ -2946,128 +2827,16 @@ /turf/open/space/basic, /area/space/nearstation) "ahu" = ( -/obj/structure/table/glass, -/obj/item/flashlight/lamp, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/security/execution/transfer) +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/prison) "ahv" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ dir = 4 }, -/turf/open/floor/plasteel/white, -/area/security/execution/transfer) +/turf/open/floor/plasteel, +/area/security/prison) "ahw" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plating, -/area/security/execution/transfer) -"ahx" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"ahy" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"ahz" = ( -/obj/machinery/button/door{ - id = "executionfireblast"; - name = "Transfer Area Lockdown"; - pixel_x = 25; - pixel_y = -5; - req_access_txt = "2" - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/obj/machinery/light/small{ - dir = 4 - }, -/obj/machinery/light_switch{ - dir = 9; - pixel_x = 24; - pixel_y = 4 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"ahA" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/closed/wall/r_wall, -/area/security/execution/transfer) -"ahB" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"ahC" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/button/flasher{ - id = "PCell 2"; - pixel_x = 5; - pixel_y = 24 - }, -/obj/machinery/button/door{ - id = "permacell2"; - name = "Cell 2 Lockdown"; - pixel_x = 4; - pixel_y = 34; - req_access_txt = "2" - }, -/turf/open/floor/plasteel, -/area/security/prison) -"ahD" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/turf/open/floor/plasteel, -/area/security/prison) -"ahF" = ( /obj/machinery/camera{ c_tag = "Brig Prison Hallway"; network = list("ss13","prison") @@ -3080,7 +2849,7 @@ }, /turf/open/floor/plasteel, /area/security/prison) -"ahG" = ( +"ahx" = ( /obj/structure/cable{ icon_state = "2-4" }, @@ -3102,7 +2871,7 @@ }, /turf/open/floor/plasteel, /area/security/prison) -"ahH" = ( +"ahy" = ( /obj/structure/cable{ icon_state = "1-8" }, @@ -3114,7 +2883,7 @@ }, /turf/open/floor/plasteel, /area/security/prison) -"ahI" = ( +"ahz" = ( /obj/machinery/light{ dir = 1 }, @@ -3123,7 +2892,7 @@ }, /turf/open/floor/plasteel, /area/security/prison) -"ahJ" = ( +"ahA" = ( /obj/machinery/power/apc/highcap/five_k{ dir = 1; name = "Prison Wing APC"; @@ -3135,165 +2904,75 @@ }, /turf/open/floor/plasteel, /area/security/prison) -"ahK" = ( +"ahB" = ( /obj/structure/table, /obj/item/melee/chainofcommand, /obj/item/melee/baton, /turf/open/floor/plasteel, /area/security/prison) +"ahJ" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/machinery/light_switch{ + dir = 9; + pixel_x = -22 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) +"ahK" = ( +/obj/structure/closet/l3closet, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) "ahL" = ( -/turf/closed/wall/r_wall, -/area/ai_monitored/security/armory) -"ahM" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 6 - }, -/obj/machinery/firealarm{ - dir = 4; - pixel_x = -27 - }, +/obj/structure/closet/secure_closet/security/sec, +/obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/showroomfloor, /area/security/office) "ahN" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hos) "ahO" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 +/obj/structure/closet/secure_closet/hos, +/obj/machinery/requests_console{ + announcementConsole = 1; + department = "Head of Security's Desk"; + departmentType = 5; + name = "Head of Security RC"; + pixel_y = 30 }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) -"ahP" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 +/obj/machinery/button/door{ + id = "hos_spess_shutters"; + name = "Space shutters"; + pixel_x = 24; + req_access_txt = "1" }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hos) "ahQ" = ( -/obj/machinery/light{ +/obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/structure/extinguisher_cabinet{ - pixel_x = 27 - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) +/turf/open/floor/plating, +/area/security/execution/transfer) "ahR" = ( /obj/structure/lattice/catwalk, /obj/structure/transit_tube/crossing, /turf/open/space/basic, /area/space/nearstation) "ahS" = ( -/obj/structure/table/optable, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/security/execution/transfer) -"ahT" = ( -/turf/open/floor/plasteel/white, -/area/security/execution/transfer) -"ahU" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plating, -/area/security/execution/transfer) -"ahV" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 5 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"ahW" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ - dir = 1 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"ahX" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"ahY" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security{ - aiControlDisabled = 1; - name = "Prisoner Transfer Centre"; - req_access_txt = "2" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"ahZ" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"aia" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"aib" = ( /obj/structure/cable{ icon_state = "4-8" }, /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel, /area/security/prison) -"aic" = ( +"ahU" = ( /obj/structure/cable{ icon_state = "4-8" }, /turf/open/floor/plasteel, /area/security/prison) -"aid" = ( +"ahV" = ( /obj/structure/cable{ icon_state = "1-2" }, @@ -3303,22 +2982,22 @@ /obj/machinery/atmospherics/pipe/simple/cyan/hidden, /turf/open/floor/plasteel, /area/security/prison) -"aie" = ( +"ahW" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, /turf/open/floor/plasteel, /area/security/prison) -"aif" = ( +"ahX" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, /turf/open/floor/plasteel, /area/security/prison) -"aig" = ( +"ahY" = ( /turf/open/floor/plasteel, /area/security/prison) -"aih" = ( +"ahZ" = ( /obj/structure/table, /obj/structure/extinguisher_cabinet{ pixel_x = 27 @@ -3327,7 +3006,7 @@ /obj/item/razor, /turf/open/floor/plasteel, /area/security/prison) -"aii" = ( +"aib" = ( /obj/structure/table, /obj/item/storage/box/chemimp{ pixel_x = 6 @@ -3337,25 +3016,18 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"aij" = ( +"aic" = ( /obj/structure/closet/secure_closet/contraband/armory, /obj/item/poster/random_contraband, /obj/item/clothing/suit/armor/navyblue/russian, /obj/item/grenade/plastic/c4, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"aik" = ( -/obj/structure/closet/secure_closet/lethalshots, -/obj/machinery/camera/motion{ - c_tag = "Armory Motion Sensor" - }, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"ail" = ( +"aid" = ( /obj/vehicle/ridden/secway, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"aim" = ( +"aie" = ( /obj/item/grenade/barrier{ pixel_x = 4 }, @@ -3366,43 +3038,62 @@ /obj/structure/table, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"ain" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/obj/machinery/light_switch{ - dir = 9; - pixel_x = -22 +"aig" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security{ + name = "Equipment Room"; + req_access_txt = "1" }, -/turf/open/floor/plasteel/showroomfloor, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/security/office) +"ail" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security{ + name = "Equipment Room"; + req_access_txt = "1" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, /area/security/office) "aio" = ( -/obj/structure/closet/l3closet, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) -"aip" = ( -/obj/structure/closet/bombcloset/security, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) -"aiq" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) -"air" = ( -/obj/vehicle/ridden/secway, -/obj/item/key/security, -/obj/effect/turf_decal/bot, -/obj/machinery/airalarm{ - dir = 1; - pixel_y = -22 +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/effect/turf_decal/tile/red, +/obj/item/storage/secure/safe{ + pixel_x = -22; + pixel_y = 32 }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hos) +"aiq" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hos) +"air" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/machinery/door/poddoor/preopen{ + id = "hos_spess_shutters"; + name = "Space shutters" + }, +/turf/open/floor/plating, +/area/command/heads_quarters/hos) "ais" = ( -/obj/structure/tank_dispenser/oxygen, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) +/obj/machinery/door/airlock/security{ + aiControlDisabled = 1; + name = "Solutions Room"; + req_access_txt = "2" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "ait" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -3411,100 +3102,22 @@ /turf/closed/wall, /area/maintenance/department/security/brig) "aiv" = ( -/obj/structure/table/glass, -/obj/item/storage/backpack/duffelbag/sec/surgery{ - pixel_y = 5 +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 }, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 }, -/turf/open/floor/plasteel/white, -/area/security/execution/transfer) +/turf/open/floor/plasteel, +/area/security/prison) "aiw" = ( -/obj/machinery/power/emitter/anchored{ - dir = 1; - state = 2 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/structure/cable, -/turf/open/floor/plating, -/area/security/execution/transfer) -"aix" = ( -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"aiy" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"aiz" = ( -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"aiA" = ( -/turf/closed/wall/r_wall, -/area/security/execution/transfer) -"aiB" = ( -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"aiC" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 5 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"aiD" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"aiE" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"aiF" = ( /obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ dir = 1 }, /turf/open/floor/plasteel, /area/security/prison) -"aiG" = ( +"aix" = ( /obj/structure/cable{ icon_state = "1-2" }, @@ -3513,22 +3126,29 @@ }, /turf/open/floor/plasteel, /area/security/prison) -"aiH" = ( +"aiy" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/security/prison) -"aiJ" = ( -/obj/machinery/airalarm{ - dir = 1; - pixel_y = -22 - }, +"aiz" = ( /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 }, /turf/open/floor/plasteel, /area/security/prison) -"aiK" = ( +"aiA" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/door/window/westleft{ + base_state = "right"; + icon_state = "right"; + name = "Unisex Showers" + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison) +"aiB" = ( /obj/structure/table, /obj/item/assembly/signaler, /obj/item/electropack, @@ -3538,7 +3158,7 @@ }, /turf/open/floor/plasteel, /area/security/prison) -"aiL" = ( +"aiD" = ( /obj/structure/table, /obj/item/storage/box/flashbangs{ pixel_x = 6; @@ -3553,16 +3173,16 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"aiM" = ( +"aiF" = ( /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"aiN" = ( +"aiG" = ( /obj/structure/cable{ icon_state = "2-4" }, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"aiO" = ( +"aiH" = ( /obj/structure/table, /obj/item/storage/box/firingpins, /obj/item/storage/box/firingpins, @@ -3576,28 +3196,98 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"aiP" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security{ - name = "Equipment Room"; - req_access_txt = "1" - }, +"aiJ" = ( +/obj/effect/landmark/start/security_officer, /obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, /turf/open/floor/plasteel, /area/security/office) +"aiK" = ( +/obj/structure/filingcabinet, +/obj/machinery/requests_console{ + department = "Security"; + departmentType = 5; + pixel_y = 30 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/office) +"aiL" = ( +/obj/structure/table, +/obj/structure/sign/plaques/golden{ + pixel_y = 32 + }, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/syndicatebomb/training{ + pixel_x = -9 + }, +/obj/item/storage/box/handcuffs{ + pixel_x = 1; + pixel_y = 3 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/office) +"aiM" = ( +/obj/machinery/vending/coffee, +/obj/machinery/status_display/evac{ + pixel_y = 32 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/office) +"aiN" = ( +/obj/effect/landmark/start/security_officer, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/office) +"aiO" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) "aiQ" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security{ - name = "Equipment Room"; - req_access_txt = "1" +/obj/machinery/computer/secure_data{ + dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/security/office) -"aiR" = ( -/turf/closed/wall, +/turf/open/floor/carpet, /area/command/heads_quarters/hos) "aiS" = ( /turf/closed/wall, @@ -3613,28 +3303,6 @@ /area/maintenance/department/crew_quarters/dorms) "aiV" = ( /obj/structure/table, -/obj/machinery/microwave, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aiW" = ( -/obj/structure/table, -/obj/structure/bedsheetbin, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aiX" = ( -/obj/structure/sink/kitchen{ - pixel_y = 28 - }, -/obj/item/reagent_containers/glass/beaker, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aiY" = ( -/obj/structure/table, -/obj/item/flashlight/lamp, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aiZ" = ( -/obj/structure/table, /obj/item/storage/box/bodybags, /obj/item/pen, /obj/machinery/firealarm{ @@ -3651,7 +3319,7 @@ }, /turf/open/floor/plasteel/dark, /area/security/execution/transfer) -"aja" = ( +"aiW" = ( /obj/structure/cable{ icon_state = "1-2" }, @@ -3664,7 +3332,7 @@ }, /turf/open/floor/plasteel/dark, /area/security/execution/transfer) -"ajb" = ( +"aiX" = ( /obj/structure/closet/secure_closet/injection, /obj/machinery/power/apc{ dir = 4; @@ -3680,30 +3348,7 @@ }, /turf/open/floor/plasteel/dark, /area/security/execution/transfer) -"ajc" = ( -/obj/structure/closet/secure_closet/brig, -/turf/open/floor/plasteel/dark, -/area/security/prison) -"ajd" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security/glass{ - name = "Prison Wing"; - req_access_txt = "1" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/prison) -"aje" = ( +"aiZ" = ( /obj/structure/cable{ icon_state = "0-2" }, @@ -3711,7 +3356,7 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/security/prison) -"ajf" = ( +"aja" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/security/glass{ name = "Prison Wing"; @@ -3730,22 +3375,10 @@ }, /turf/open/floor/plasteel, /area/security/prison) -"ajg" = ( -/obj/structure/rack, -/obj/item/gun/energy/ionrifle, -/obj/item/gun/energy/temperature/security, -/obj/item/clothing/suit/armor/laserproof, -/obj/machinery/light{ - dir = 8; - light_color = "#e8eaff" - }, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -23 - }, +"ajb" = ( /turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"ajh" = ( +/area/security/execution/transfer) +"ajd" = ( /obj/structure/rack, /obj/item/clothing/suit/armor/riot{ pixel_x = -3; @@ -3767,13 +3400,13 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"aji" = ( +"aje" = ( /obj/structure/cable{ icon_state = "1-2" }, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"ajj" = ( +"ajf" = ( /obj/structure/rack, /obj/item/storage/box/rubbershot{ pixel_x = -3; @@ -3798,123 +3431,143 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) +"ajg" = ( +/obj/structure/chair/stool, +/obj/effect/landmark/start/security_officer, +/turf/open/floor/plasteel, +/area/security/office) +"ajh" = ( +/obj/effect/landmark/start/security_officer, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/security/office) +"aji" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel, +/area/security/office) +"ajj" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 6 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/office) "ajk" = ( -/obj/effect/landmark/start/security_officer, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 1 +/obj/machinery/door/airlock/command/glass{ + name = "Head of Security"; + req_access_txt = "58" }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 }, -/turf/open/floor/plasteel, -/area/security/office) +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hos) "ajl" = ( -/obj/structure/filingcabinet, -/obj/machinery/requests_console{ - department = "Security"; - departmentType = 5; - pixel_y = 30 +/obj/structure/cable{ + icon_state = "4-8" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 +/obj/structure/cable{ + icon_state = "2-8" }, -/obj/effect/turf_decal/tile/red{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 9 }, -/turf/open/floor/plasteel, -/area/security/office) +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hos) "ajm" = ( -/obj/structure/table, -/obj/item/storage/fancy/donut_box{ - pixel_y = 2 +/obj/structure/cable{ + icon_state = "2-8" }, -/obj/structure/noticeboard{ - pixel_y = 32 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ +/obj/structure/disposalpipe/segment{ dir = 4 }, -/turf/open/floor/plasteel, -/area/security/office) +/obj/effect/landmark/start/head_of_security, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) "ajn" = ( -/obj/structure/table, -/obj/structure/sign/plaques/golden{ - pixel_y = 32 +/obj/structure/disposalpipe/segment{ + dir = 9 }, -/obj/machinery/light{ - dir = 1 - }, -/obj/item/storage/box/handcuffs{ - pixel_x = 1; - pixel_y = 3 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ +/obj/structure/chair/office/dark{ dir = 4 }, -/turf/open/floor/plasteel, -/area/security/office) +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) "ajo" = ( -/obj/machinery/vending/coffee, -/obj/machinery/status_display/evac{ - pixel_y = 32 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/office) +/obj/structure/table/wood, +/obj/item/book/manual/wiki/security_space_law, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) "ajp" = ( -/obj/machinery/photocopier, -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_y = 32 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/office) -"ajq" = ( -/obj/effect/landmark/start/security_officer, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/reagent_dispensers/peppertank{ - pixel_x = 32 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ +/obj/structure/chair/comfy/black{ dir = 8 }, -/turf/open/floor/plasteel, -/area/security/office) +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"ajq" = ( +/obj/machinery/computer/security/hos{ + dir = 8 + }, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) "ajr" = ( -/obj/item/reagent_containers/food/snacks/donut/chaos, -/turf/open/floor/plating, -/area/command/heads_quarters/hos) +/obj/machinery/door/poddoor/preopen{ + id = "permacell2"; + name = "cell blast door" + }, +/obj/machinery/door/airlock/public/glass{ + id_tag = "permabolt2"; + name = "Cell 2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/prison) "ajs" = ( -/turf/closed/wall/r_wall, -/area/command/heads_quarters/hos) +/obj/machinery/door/airlock{ + name = "Unisex Restroom" + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison) "ajt" = ( /obj/structure/table, /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass{ @@ -3971,37 +3624,7 @@ }, /turf/open/space, /area/space/nearstation) -"ajB" = ( -/obj/item/storage/box/mousetraps, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) "ajC" = ( -/obj/structure/chair/stool, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"ajD" = ( -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"ajE" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/obj/structure/sign/poster/contraband/random{ - pixel_x = 32 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"ajF" = ( -/obj/machinery/atmospherics/components/unary/tank/oxygen, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"ajG" = ( -/obj/machinery/atmospherics/components/unary/tank/nitrogen, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"ajH" = ( -/turf/closed/wall, -/area/security/processing/cremation) -"ajI" = ( /obj/machinery/door/airlock/security{ aiControlDisabled = 1; name = "Crematorium"; @@ -4012,7 +3635,30 @@ }, /turf/open/floor/plasteel/dark, /area/security/processing/cremation) -"ajJ" = ( +"ajD" = ( +/turf/closed/wall, +/area/security/processing/cremation) +"ajE" = ( +/turf/closed/wall/r_wall, +/area/security/execution/transfer) +"ajF" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/vending/wardrobe/sec_wardrobe, +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) +"ajG" = ( +/obj/structure/closet/secure_closet/security/sec, +/obj/machinery/camera{ + c_tag = "Brig Equipment Room" + }, +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_y = 29 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) +"ajH" = ( /obj/machinery/door/firedoor, /obj/machinery/door/poddoor/preopen{ id = "Prison Gate"; @@ -4022,19 +3668,7 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/security/brig) -"ajK" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/poddoor/preopen{ - id = "Prison Gate"; - name = "prison blast door" - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/security/brig) -"ajL" = ( +"ajI" = ( /obj/machinery/door/firedoor, /obj/machinery/door/poddoor/preopen{ id = "Prison Gate"; @@ -4044,60 +3678,7 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/security/brig) -"ajM" = ( -/turf/closed/wall, -/area/security/brig) -"ajN" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/machinery/light/small{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"ajO" = ( -/obj/structure/closet{ - name = "Evidence Closet" - }, -/obj/structure/sign/poster/official/safety_report{ - pixel_y = 32 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"ajP" = ( -/obj/structure/rack, -/obj/item/gun/energy/e_gun{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/gun/energy/e_gun, -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/machinery/firealarm{ - dir = 4; - pixel_x = -27 - }, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"ajQ" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"ajR" = ( +"ajJ" = ( /obj/structure/rack, /obj/item/clothing/suit/armor/bulletproof{ pixel_x = -3; @@ -4114,14 +3695,14 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"ajS" = ( +"ajK" = ( /obj/structure/cable{ icon_state = "1-2" }, /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"ajT" = ( +"ajL" = ( /obj/structure/rack, /obj/item/gun/energy/laser{ pixel_x = -3; @@ -4133,118 +3714,112 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"ajU" = ( +"ajM" = ( +/turf/closed/wall, +/area/security/brig) +"ajN" = ( /obj/structure/cable{ - icon_state = "0-2" + icon_state = "1-2" }, -/obj/machinery/power/apc{ - dir = 8; - name = "Security Office APC"; - pixel_x = -25 +/obj/machinery/newscaster{ + pixel_x = -32 }, /obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/effect/turf_decal/tile/red{ dir = 1 }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, /obj/effect/turf_decal/tile/red{ dir = 8 }, /turf/open/floor/plasteel, /area/security/office) -"ajV" = ( +"ajQ" = ( /obj/effect/landmark/start/security_officer, /turf/open/floor/plasteel, /area/security/office) -"ajW" = ( -/obj/structure/chair/stool, +"ajR" = ( /obj/effect/landmark/start/security_officer, +/obj/structure/disposalpipe/segment, /turf/open/floor/plasteel, /area/security/office) -"ajX" = ( -/obj/effect/landmark/start/security_officer, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/office) -"ajY" = ( -/obj/effect/landmark/start/security_officer, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/office) -"ajZ" = ( -/obj/machinery/light{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 4 +"ajS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 1 }, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel, /area/security/office) +"ajT" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/open/floor/plasteel/dark, +/area/security/office) +"ajU" = ( +/turf/closed/wall, +/area/command/heads_quarters/hos) +"ajV" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hos) +"ajW" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"ajX" = ( +/obj/structure/table/wood, +/obj/item/phone, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"ajY" = ( +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"ajZ" = ( +/obj/machinery/computer/card/minor/hos{ + dir = 8 + }, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) "aka" = ( -/obj/machinery/suit_storage_unit/hos, -/obj/machinery/airalarm{ - pixel_y = 22 - }, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) +/obj/machinery/vending/security, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) "akb" = ( -/obj/machinery/disposal/bin, -/obj/structure/disposalpipe/trunk, -/obj/structure/sign/plaques/kiddie{ - desc = "An embossed piece of paper from the University of Nanotrasen at Portpoint."; - name = "\improper 'Diploma' frame"; - pixel_y = 32 +/obj/effect/turf_decal/stripes/line{ + dir = 10 }, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plating, +/area/security/execution/transfer) "akc" = ( -/obj/structure/table/wood, -/obj/machinery/recharger, -/obj/machinery/status_display/evac{ - pixel_y = 32 - }, -/obj/machinery/light{ - dir = 1; - light_color = "#706891" - }, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) +/obj/machinery/atmospherics/pipe/simple/general/visible, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating, +/area/security/execution/transfer) "akd" = ( -/obj/structure/table/wood, -/obj/item/storage/box/seccarts{ - pixel_x = 3; - pixel_y = 2 +/obj/effect/turf_decal/stripes/line{ + dir = 6 }, -/obj/item/storage/box/deputy, -/obj/machinery/newscaster/security_unit{ - pixel_y = 32 - }, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plating, +/area/security/execution/transfer) "ake" = ( -/obj/structure/closet/secure_closet/hos, -/obj/machinery/requests_console{ - announcementConsole = 1; - department = "Head of Security's Desk"; - departmentType = 5; - name = "Head of Security RC"; - pixel_y = 30 - }, -/obj/machinery/button/door{ - id = "hos_spess_shutters"; - name = "Space shutters"; - pixel_x = 24; - req_access_txt = "1" - }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) +/area/security/execution/transfer) "akf" = ( /turf/open/floor/carpet, /area/maintenance/department/crew_quarters/dorms) @@ -4352,54 +3927,6 @@ /turf/open/floor/plating, /area/maintenance/department/crew_quarters/dorms) "akr" = ( -/obj/machinery/washing_machine, -/obj/item/radio/intercom{ - dir = 4; - name = "Station Intercom (General)"; - pixel_x = -31 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aks" = ( -/obj/machinery/light/small, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"akt" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/obj/machinery/button/door{ - id = "mainthideout"; - name = "Door Bolt Control"; - normaldoorcontrol = 1; - pixel_x = 25; - specialfunctions = 4 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aku" = ( -/obj/machinery/atmospherics/components/trinary/mixer/flipped{ - dir = 1; - node1_concentration = 0.2; - node2_concentration = 0.8; - on = 1 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"akv" = ( -/obj/machinery/atmospherics/pipe/manifold/general/hidden, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"akw" = ( -/obj/machinery/atmospherics/pipe/simple/general/hidden{ - dir = 9 - }, -/obj/machinery/meter, -/obj/machinery/light/small{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"akx" = ( /obj/structure/bodycontainer/crematorium, /obj/item/radio/intercom{ name = "Station Intercom (General)"; @@ -4407,16 +3934,7 @@ }, /turf/open/floor/plasteel/dark, /area/security/processing/cremation) -"aky" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel/dark, -/area/security/processing/cremation) -"akz" = ( +"aks" = ( /obj/machinery/button/crematorium{ pixel_x = 25 }, @@ -4431,26 +3949,7 @@ }, /turf/open/floor/plasteel/dark, /area/security/processing/cremation) -"akA" = ( -/turf/closed/wall/r_wall, -/area/security/brig) -"akB" = ( -/obj/item/clothing/gloves/color/latex, -/obj/item/clothing/mask/surgical, -/obj/item/reagent_containers/spray/cleaner, -/obj/structure/table/glass, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/security/brig) -"akC" = ( +"aku" = ( /obj/item/storage/firstaid/regular{ pixel_x = 3; pixel_y = 3 @@ -4468,26 +3967,24 @@ }, /turf/open/floor/plasteel/white, /area/security/brig) -"akD" = ( +"akv" = ( /obj/item/radio/intercom{ name = "Station Intercom (General)"; pixel_y = 24 }, -/obj/structure/table/glass, -/obj/machinery/computer/med_data/laptop, /obj/effect/turf_decal/tile/red{ dir = 1 }, /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/structure/table/optable, /turf/open/floor/plasteel/white, /area/security/brig) -"akE" = ( +"akw" = ( /obj/structure/window/reinforced{ dir = 4 }, -/obj/machinery/iv_drip, /obj/effect/turf_decal/tile/red{ dir = 1 }, @@ -4495,21 +3992,11 @@ /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/structure/table/glass, +/obj/machinery/computer/med_data/laptop, /turf/open/floor/plasteel/white, /area/security/brig) -"akF" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"akG" = ( +"akx" = ( /obj/structure/cable{ icon_state = "1-2" }, @@ -4518,14 +4005,14 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"akH" = ( +"aky" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/security/brig) -"akI" = ( +"akz" = ( /obj/machinery/door/airlock/security{ name = "Evidence Room"; req_access_txt = "63" @@ -4545,13 +4032,13 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"akJ" = ( +"akA" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 9 }, /turf/open/floor/plasteel, /area/security/brig) -"akK" = ( +"akB" = ( /obj/structure/closet{ name = "Evidence Closet" }, @@ -4565,7 +4052,7 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"akL" = ( +"akD" = ( /obj/structure/rack, /obj/item/gun/energy/e_gun/advtaser{ pixel_x = -3; @@ -4580,24 +4067,24 @@ /obj/machinery/atmospherics/pipe/simple/cyan/hidden, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"akM" = ( +"akE" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"akN" = ( +"akF" = ( /obj/effect/landmark/event_spawn, /obj/structure/rack, /obj/item/key/security, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"akO" = ( +"akG" = ( /obj/structure/cable{ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/cyan/hidden, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"akP" = ( +"akH" = ( /obj/structure/rack, /obj/item/gun/ballistic/shotgun/riot, /obj/item/gun/ballistic/shotgun/riot{ @@ -4606,88 +4093,144 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"akQ" = ( +"akJ" = ( /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/newscaster{ - pixel_x = -32 - }, /obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = -27 + }, /obj/effect/turf_decal/tile/red{ dir = 1 }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, /obj/effect/turf_decal/tile/red{ dir = 8 }, /turf/open/floor/plasteel, /area/security/office) -"akR" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, +"akN" = ( +/obj/machinery/computer/security, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel, +/area/security/office) +"akO" = ( /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel, /area/security/office) -"akT" = ( +"akP" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/open/floor/plasteel/dark, +/area/security/office) +"akQ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ icon_state = "0-4" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plating, /area/command/heads_quarters/hos) -"akU" = ( +"akR" = ( /obj/structure/cable{ - icon_state = "2-8" + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 }, -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) +"akT" = ( +/obj/structure/bed, +/obj/machinery/camera{ + c_tag = "Permabrig Cell 2"; + network = list("ss13","prison") + }, +/obj/item/radio/intercom{ + desc = "Talk through this. It looks like it has been modified to not broadcast."; + name = "Prison Intercom (General)"; + pixel_y = 24; + prison_radio = 1 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/item/toy/plush/slimeplushie, +/turf/open/floor/plasteel, +/area/security/prison) +"akU" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/obj/effect/landmark/start/prisoner, +/turf/open/floor/plasteel, +/area/security/prison) "akV" = ( -/obj/item/storage/secure/safe{ - pixel_x = -22; - pixel_y = 32 +/obj/structure/cable{ + icon_state = "1-2" }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 }, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) +/obj/effect/landmark/start/prisoner, +/turf/open/floor/plasteel, +/area/security/prison) "akW" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 +/obj/structure/sink{ + dir = 8; + pixel_x = -12; + pixel_y = 2 }, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison) "akX" = ( -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) -"akZ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ - icon_state = "0-2" + icon_state = "0-4" }, /obj/machinery/door/poddoor/preopen{ - id = "hos_spess_shutters"; - name = "Space shutters" + id = "executionfireblast" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, +/area/security/execution/transfer) +"akZ" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/general/visible, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/machinery/door/poddoor/preopen{ + id = "executionfireblast" }, /turf/open/floor/plating, -/area/command/heads_quarters/hos) +/area/security/execution/transfer) "ala" = ( /obj/structure/transit_tube/curved{ dir = 1 @@ -4741,92 +4284,12 @@ /turf/open/floor/plating, /area/maintenance/department/crew_quarters/dorms) "ali" = ( -/obj/machinery/door/airlock/abandoned{ - id_tag = "mainthideout"; - name = "Hideout" - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"alj" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ - dir = 8 - }, -/obj/item/wrench, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"alk" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"all" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible{ - dir = 8 - }, -/obj/machinery/portable_atmospherics/canister/nitrous_oxide, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"alm" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -22 - }, -/turf/open/floor/plasteel/dark, -/area/security/processing/cremation) -"aln" = ( /obj/structure/cable{ icon_state = "1-2" }, /turf/open/floor/plasteel/dark, /area/security/processing/cremation) -"alo" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/machinery/camera{ - c_tag = "Brig Crematorium"; - dir = 8 - }, -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/processing/cremation) -"alp" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/turf/closed/wall/r_wall, -/area/security/brig) -"alq" = ( -/obj/item/storage/box/bodybags, -/obj/structure/extinguisher_cabinet{ - pixel_x = -27 - }, -/obj/machinery/light{ - dir = 8 - }, -/obj/structure/table/glass, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/obj/item/reagent_containers/syringe{ - name = "steel point" - }, -/obj/item/reagent_containers/glass/bottle/charcoal, -/obj/item/reagent_containers/glass/bottle/epinephrine, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/security/brig) -"alr" = ( +"alj" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 4 }, @@ -4835,13 +4298,13 @@ }, /turf/open/floor/plasteel/white, /area/security/brig) -"als" = ( +"alk" = ( /obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ dir = 1 }, /turf/open/floor/plasteel/white, /area/security/brig) -"alt" = ( +"all" = ( /obj/machinery/door/window/westleft{ dir = 4; name = "Brig Infirmary" @@ -4855,19 +4318,7 @@ }, /turf/open/floor/plasteel/white, /area/security/brig) -"alu" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"alv" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"alw" = ( +"aln" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, @@ -4877,13 +4328,13 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"alx" = ( +"alo" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/closed/wall, /area/security/brig) -"aly" = ( +"alp" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, @@ -4901,7 +4352,7 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"alz" = ( +"alq" = ( /obj/structure/closet{ name = "Evidence Closet" }, @@ -4914,7 +4365,54 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"alA" = ( +"als" = ( +/obj/machinery/flasher/portable, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) +"alt" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) +"alu" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/mob/living/simple_animal/bot/secbot{ + arrest_type = 1; + health = 45; + icon_state = "secbot1"; + idcheck = 1; + name = "Sergeant-at-Armsky"; + weaponscheck = 1 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) +"alv" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) +"alw" = ( /obj/machinery/flasher/portable, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -4928,334 +4426,10 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"alB" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/obj/machinery/firealarm{ - dir = 4; - pixel_x = -27 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/office) -"alC" = ( -/obj/structure/table/wood, -/obj/item/flashlight/lamp/green{ - pixel_x = -4; - pixel_y = 12 - }, -/obj/item/pen, -/obj/item/folder/red{ - layer = 2.9; - pixel_x = 8 - }, -/turf/open/floor/plasteel, -/area/security/office) -"alD" = ( -/obj/machinery/computer/secure_data, -/turf/open/floor/plasteel, -/area/security/office) -"alE" = ( -/turf/open/floor/plasteel, -/area/security/office) -"alF" = ( -/obj/machinery/computer/security, -/turf/open/floor/plasteel, -/area/security/office) -"alG" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/office) -"alH" = ( -/turf/open/floor/plasteel/dark, -/area/security/office) -"alI" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) -"alJ" = ( -/turf/open/floor/carpet, -/area/command/heads_quarters/hos) -"alK" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/chair/office/dark{ - dir = 4 - }, -/turf/open/floor/carpet, -/area/command/heads_quarters/hos) -"alL" = ( -/obj/structure/table/wood, -/obj/item/folder/red, -/obj/item/stamp/hos, -/turf/open/floor/carpet, -/area/command/heads_quarters/hos) -"alM" = ( -/obj/machinery/computer/secure_data{ - dir = 8 - }, -/turf/open/floor/carpet, -/area/command/heads_quarters/hos) -"alN" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-2" - }, -/obj/structure/cable, -/obj/machinery/door/poddoor/preopen{ - id = "hos_spess_shutters"; - name = "Space shutters" - }, -/turf/open/floor/plating, -/area/command/heads_quarters/hos) -"alO" = ( -/obj/structure/transit_tube/diagonal, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) -"alP" = ( -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, -/area/maintenance/department/crew_quarters/dorms) -"alQ" = ( -/obj/structure/chair/stool/bar, -/turf/open/floor/wood{ - icon_state = "wood-broken7" - }, -/area/maintenance/department/crew_quarters/dorms) -"alR" = ( -/obj/effect/landmark/blobstart, -/obj/structure/chair/stool/bar, -/turf/open/floor/wood, -/area/maintenance/department/crew_quarters/dorms) -"alS" = ( -/obj/structure/chair/stool/bar, -/turf/open/floor/wood, -/area/maintenance/department/crew_quarters/dorms) -"alT" = ( -/obj/machinery/meter, -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ - dir = 8 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"alU" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 8; - name = "Supply to Security" - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"alV" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 - }, -/obj/machinery/meter, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"alW" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel/dark, -/area/security/processing/cremation) -"alX" = ( -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/open/floor/plasteel/dark, -/area/security/processing/cremation) -"alY" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/turf/open/floor/plasteel/dark, -/area/security/processing/cremation) -"alZ" = ( -/obj/structure/bodycontainer/morgue, -/obj/machinery/camera{ - c_tag = "Brig Infirmary"; - dir = 4 - }, -/obj/structure/window/reinforced{ - dir = 1; - layer = 2.9 - }, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"ama" = ( -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/security/brig) -"amb" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/turf/open/floor/plasteel/white, -/area/security/brig) -"amc" = ( -/obj/machinery/door/window/westleft{ - base_state = "right"; - dir = 4; - icon_state = "right"; - name = "Brig Infirmary" - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/security/brig) -"amd" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/turf/open/floor/plasteel, -/area/security/brig) -"ame" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"amf" = ( -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/machinery/power/apc/highcap/ten_k{ - dir = 4; - name = "Brig APC"; - pixel_x = 24 - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"amg" = ( +"alx" = ( /turf/closed/wall/r_wall, -/area/security/warden) -"amh" = ( -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/security/warden) -"ami" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/window/southleft{ - base_state = "right"; - icon_state = "right"; - name = "Armory"; - req_access_txt = "3" - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/warden) -"amj" = ( -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/security/warden) -"amk" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/window/southleft{ - base_state = "right"; - icon_state = "right"; - name = "Armory"; - req_access_txt = "3" - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/warden) -"aml" = ( -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-2" - }, -/turf/open/floor/plating, -/area/security/warden) -"amm" = ( +/area/ai_monitored/security/armory) +"aly" = ( /obj/structure/cable{ icon_state = "1-2" }, @@ -5282,52 +4456,282 @@ }, /turf/open/floor/plasteel, /area/security/office) -"amn" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +"alA" = ( +/obj/machinery/light{ dir = 4 }, -/turf/open/floor/plasteel, -/area/security/office) -"amo" = ( -/obj/structure/chair/office/dark{ - dir = 1 - }, -/obj/effect/landmark/start/security_officer, /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 + dir = 9 }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/dark, /area/security/office) -"amp" = ( -/obj/machinery/holopad, -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ - dir = 1 +"alI" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-8" }, +/obj/machinery/door/poddoor/preopen{ + id = "executionfireblast" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/open/floor/plating, +/area/security/execution/transfer) +"alJ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security{ + aiControlDisabled = 1; + name = "Solutions Room"; + req_access_txt = "2" + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"alK" = ( +/obj/machinery/flasher{ + id = "PCell 2"; + pixel_x = -28 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel, -/area/security/office) -"amq" = ( -/obj/structure/chair/office/dark{ - dir = 1 - }, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/effect/landmark/start/security_officer, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 +/area/security/prison) +"alL" = ( +/obj/structure/cable{ + icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, +/area/security/prison) +"alM" = ( +/obj/structure/toilet/secret/prison{ + dir = 8 + }, +/turf/open/floor/plasteel/freezer, +/area/security/prison) +"alN" = ( +/obj/structure/weightmachine/weightlifter, +/turf/open/floor/plasteel/showroomfloor, /area/security/office) -"amr" = ( +"alO" = ( +/obj/structure/transit_tube/diagonal, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"alP" = ( +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/crew_quarters/dorms) +"alQ" = ( +/obj/structure/chair/stool/bar, +/turf/open/floor/wood{ + icon_state = "wood-broken7" + }, +/area/maintenance/department/crew_quarters/dorms) +"alR" = ( +/obj/effect/landmark/blobstart, +/obj/structure/chair/stool/bar, +/turf/open/floor/wood, +/area/maintenance/department/crew_quarters/dorms) +"alS" = ( +/obj/structure/chair/stool/bar, +/turf/open/floor/wood, +/area/maintenance/department/crew_quarters/dorms) +"alT" = ( /obj/structure/cable{ icon_state = "2-4" }, -/obj/structure/disposalpipe/segment{ +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/security/brig) +"alU" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/security/brig) +"alV" = ( +/obj/machinery/door/window/westleft{ + base_state = "right"; + dir = 4; + icon_state = "right"; + name = "Brig Infirmary" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +/turf/open/floor/plasteel/white, +/area/security/brig) +"alW" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, +/turf/open/floor/plasteel, +/area/security/brig) +"alX" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/power/apc/highcap/ten_k{ + dir = 4; + name = "Brig APC"; + pixel_x = 24 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/brig) +"alY" = ( +/obj/structure/punching_bag, +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) +"alZ" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 4 + }, +/obj/structure/window/reinforced, +/obj/machinery/portable_atmospherics/canister/toxins, +/turf/open/floor/plating, +/area/security/execution/transfer) +"ama" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + layer = 2.4 + }, +/obj/item/wrench, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, +/area/security/execution/transfer) +"amb" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/security/warden) +"amc" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/window/southleft{ + base_state = "right"; + icon_state = "right"; + name = "Armory"; + req_access_txt = "3" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/warden) +"amd" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/security/warden) +"ame" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/window/southleft{ + base_state = "right"; + icon_state = "right"; + name = "Armory"; + req_access_txt = "3" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/warden) +"amf" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/warden) +"amg" = ( +/turf/closed/wall/r_wall, +/area/security/warden) +"ami" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp/green{ + pixel_x = -4; + pixel_y = 12 + }, +/obj/item/pen, +/obj/item/folder/red{ + layer = 2.9; + pixel_x = 8 + }, +/turf/open/floor/plasteel, +/area/security/office) +"amj" = ( +/obj/structure/table/wood, +/obj/machinery/recharger, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel, +/area/security/office) +"amk" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ @@ -5335,89 +4739,150 @@ }, /turf/open/floor/plasteel, /area/security/office) -"ams" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 +"aml" = ( +/obj/machinery/computer/security/telescreen/interrogation{ + dir = 8; + pixel_x = 30 }, /turf/open/floor/plasteel/dark, /area/security/office) +"amm" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel/dark, +/area/security/office) +"amn" = ( +/turf/open/floor/plasteel/dark, +/area/security/office) +"amo" = ( +/obj/machinery/status_display/ai{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) +"amp" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel/dark, +/area/security/office) +"amq" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 9 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/security/execution/transfer) +"amr" = ( +/obj/structure/rack, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/item/clothing/suit/straight_jacket, +/obj/item/tank/internals/anesthetic, +/obj/item/clothing/mask/breath/medical, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"ams" = ( +/obj/machinery/button/flasher{ + id = "executionflash"; + pixel_x = 6; + pixel_y = 27 + }, +/obj/machinery/button/door{ + id = "executionspaceblast"; + name = "Vent to Space"; + pixel_x = -6; + pixel_y = 32; + req_access_txt = "7" + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/machinery/button/ignition{ + id = "secigniter"; + pixel_x = 6; + pixel_y = 36 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "amt" = ( -/obj/machinery/door/airlock/command/glass{ - name = "Head of Security"; - req_access_txt = "58" +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_x = 28 }, -/obj/structure/cable{ - icon_state = "4-8" +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 1 }, -/obj/structure/disposalpipe/segment{ +/obj/effect/turf_decal/tile/red{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/obj/machinery/door/firedoor, /turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) +/area/security/execution/transfer) "amu" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/cable{ - icon_state = "1-8" +/obj/machinery/light{ + dir = 8 }, /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 9 + dir = 6 }, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) +/obj/machinery/firealarm{ + dir = 4; + pixel_x = -27 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) "amv" = ( -/obj/structure/cable{ - icon_state = "2-8" +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/landmark/start/head_of_security, -/turf/open/floor/carpet, -/area/command/heads_quarters/hos) +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) "amw" = ( -/obj/structure/disposalpipe/segment{ - dir = 9 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 }, -/obj/structure/chair/office/dark{ +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) +"amx" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) +"amy" = ( +/obj/machinery/light{ dir = 4 }, -/turf/open/floor/carpet, -/area/command/heads_quarters/hos) -"amx" = ( -/obj/structure/table/wood, -/obj/item/book/manual/wiki/security_space_law, -/turf/open/floor/carpet, -/area/command/heads_quarters/hos) -"amy" = ( -/obj/structure/chair/comfy/black{ - dir = 8 +/obj/structure/extinguisher_cabinet{ + pixel_x = 27 }, -/turf/open/floor/carpet, -/area/command/heads_quarters/hos) +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) "amz" = ( -/obj/machinery/computer/security/hos{ - dir = 8 +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-4" }, -/turf/open/floor/carpet, -/area/command/heads_quarters/hos) +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/execution/transfer) "amA" = ( /obj/structure/transit_tube/curved/flipped{ dir = 4 @@ -5456,134 +4921,26 @@ }, /area/maintenance/department/crew_quarters/dorms) "amH" = ( -/obj/machinery/door/airlock/atmos/abandoned{ - name = "Atmospherics Maintenance"; - req_access_txt = "12;24" +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/iv_drip, +/turf/open/floor/plasteel/white, +/area/security/brig) "amI" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Crematorium Maintenance"; - req_one_access_txt = "2;27" - }, /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/brig) "amJ" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 6 - }, -/turf/closed/wall, -/area/security/processing/cremation) -"amK" = ( -/obj/machinery/door/window/eastright{ - base_state = "left"; - dir = 1; - icon_state = "left"; - name = "Security Delivery"; - req_access_txt = "1" - }, -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=4"; - dir = 1; - freq = 1400; - location = "Security" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 9 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/processing/cremation) -"amL" = ( -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 - }, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"amM" = ( -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/security/brig) -"amN" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/security/brig) -"amO" = ( -/obj/structure/closet/crate/freezer, -/obj/structure/window/reinforced{ - dir = 4; - layer = 2.9 - }, -/obj/item/reagent_containers/blood/OMinus, -/obj/item/reagent_containers/blood/OMinus, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/security/brig) -"amP" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"amQ" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"amR" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, @@ -5593,30 +4950,31 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"amS" = ( -/obj/structure/closet/secure_closet/warden, -/obj/item/clothing/mask/gas/sechailer, -/obj/machinery/power/apc{ - dir = 8; - name = "Brig Control APC"; - pixel_x = -25 - }, +"amK" = ( +/obj/structure/table/glass, +/obj/item/flashlight/lamp, /obj/structure/cable{ - icon_state = "0-2" + icon_state = "4-8" }, -/obj/structure/reagent_dispensers/peppertank{ - pixel_y = 30 +/obj/effect/turf_decal/tile/red{ + dir = 1 }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"amT" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/security/execution/transfer) +"amL" = ( /obj/machinery/computer/prisoner/management, /obj/machinery/airalarm{ pixel_y = 22 }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"amU" = ( +"amM" = ( /obj/machinery/computer/security, /obj/machinery/light{ dir = 1 @@ -5631,22 +4989,15 @@ }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"amV" = ( +"amN" = ( /obj/machinery/computer/secure_data, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"amW" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"amX" = ( -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"amY" = ( +"amQ" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"amZ" = ( +"amR" = ( /obj/structure/table, /obj/machinery/recharger, /obj/machinery/light/small{ @@ -5661,92 +5012,168 @@ }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"ana" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, +"amS" = ( /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"anb" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/obj/machinery/light_switch{ - dir = 9; - pixel_x = -22 - }, /obj/effect/turf_decal/tile/red{ dir = 1 }, /obj/effect/turf_decal/tile/red{ dir = 8 }, -/turf/open/floor/plasteel, -/area/security/office) -"anc" = ( -/obj/structure/table/wood, -/obj/machinery/recharger, -/turf/open/floor/plasteel, -/area/security/office) -"and" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden, /turf/open/floor/plasteel, /area/security/office) -"ane" = ( -/obj/structure/table/wood, -/obj/machinery/recharger, -/obj/structure/disposalpipe/segment, +"amU" = ( +/obj/structure/chair/office/dark{ + dir = 1 + }, +/obj/effect/landmark/start/security_officer, /turf/open/floor/plasteel, /area/security/office) -"anf" = ( +"amV" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/open/floor/plasteel, +/area/security/office) +"amX" = ( +/obj/structure/chair/office/dark{ + dir = 1 + }, +/obj/structure/disposalpipe/segment, +/obj/effect/landmark/start/security_officer, +/turf/open/floor/plasteel, +/area/security/office) +"amY" = ( /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 4 }, /turf/open/floor/plasteel, /area/security/office) -"ang" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) -"anh" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/carpet, -/area/command/heads_quarters/hos) -"ani" = ( -/obj/structure/chair/office/dark{ +"amZ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/carpet, -/area/command/heads_quarters/hos) -"anj" = ( -/obj/structure/table/wood, -/obj/item/phone, -/turf/open/floor/carpet, -/area/command/heads_quarters/hos) -"ank" = ( -/obj/machinery/computer/card/minor/hos{ +/turf/open/floor/plasteel/dark, +/area/security/office) +"ana" = ( +/obj/structure/filingcabinet/chestdrawer, +/obj/machinery/light_switch{ + pixel_y = -22 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/showroomfloor, +/area/security/warden) +"anb" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) +"anc" = ( +/obj/item/flashlight/lamp, +/obj/structure/table/glass, +/turf/open/floor/plasteel/dark, +/area/security/office) +"and" = ( +/obj/structure/chair{ dir = 8 }, -/turf/open/floor/carpet, -/area/command/heads_quarters/hos) +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/machinery/camera{ + c_tag = "Brig Interrogation"; + dir = 8; + network = list("interrogation") + }, +/turf/open/floor/plasteel/dark, +/area/security/office) +"ane" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/security/execution/transfer) +"anf" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/security/execution/transfer) +"ang" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"anh" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"ani" = ( +/obj/machinery/button/door{ + id = "executionfireblast"; + name = "Transfer Area Lockdown"; + pixel_x = 25; + pixel_y = -5; + req_access_txt = "2" + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/light_switch{ + dir = 9; + pixel_x = 24; + pixel_y = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"anj" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/security/execution/transfer) +"ank" = ( +/obj/structure/closet/bombcloset/security, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) "anl" = ( /obj/structure/transit_tube/diagonal, /turf/open/space/basic, @@ -5758,83 +5185,16 @@ /turf/open/floor/plating, /area/maintenance/department/crew_quarters/dorms) "anq" = ( -/obj/structure/grille/broken, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"anr" = ( -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 5 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"ans" = ( -/obj/item/wirecutters, -/obj/effect/spawner/lootdrop/maintenance, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"ant" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"anu" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"anv" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 9 }, /turf/closed/wall, /area/security/processing/cremation) -"anw" = ( -/obj/structure/plasticflaps/opaque, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/processing/cremation) -"anx" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Brig Infirmary Maintenance"; - req_access_txt = "63" - }, -/obj/structure/cable{ - icon_state = "1-2" - }, +"ans" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"any" = ( +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) +"ant" = ( /obj/machinery/light{ dir = 8 }, @@ -5851,13 +5211,13 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"anz" = ( +"anu" = ( /obj/structure/cable{ icon_state = "1-4" }, /turf/open/floor/plasteel, /area/security/brig) -"anA" = ( +"anv" = ( /obj/structure/cable{ icon_state = "4-8" }, @@ -5869,9 +5229,13 @@ /obj/structure/cable{ icon_state = "2-8" }, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = 24 + }, /turf/open/floor/plasteel, /area/security/brig) -"anB" = ( +"anw" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ icon_state = "0-8" @@ -5881,47 +5245,23 @@ }, /turf/open/floor/plating, /area/security/warden) -"anC" = ( -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"anD" = ( +"anx" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"anE" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"anF" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"anG" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"anH" = ( +"any" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 6 }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"anI" = ( +"anz" = ( /obj/machinery/atmospherics/pipe/manifold/cyan/hidden, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"anJ" = ( +"anA" = ( /obj/structure/table, /obj/machinery/recharger, /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ @@ -5932,7 +5272,7 @@ }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"anK" = ( +"anB" = ( /obj/structure/cable{ icon_state = "0-2" }, @@ -5945,166 +5285,171 @@ }, /turf/open/floor/plating, /area/security/warden) -"anL" = ( +"anC" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, /obj/structure/cable{ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 9 }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ +/turf/open/floor/plasteel, +/area/security/office) +"anE" = ( +/turf/open/floor/plasteel, +/area/security/office) +"anF" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ dir = 8 }, /turf/open/floor/plasteel, /area/security/office) -"anM" = ( -/obj/structure/chair/office/dark{ - dir = 1 - }, -/obj/effect/landmark/start/security_officer, -/turf/open/floor/plasteel, -/area/security/office) -"anN" = ( -/obj/structure/chair/office/dark{ - dir = 1 - }, +"anH" = ( /obj/structure/disposalpipe/segment, -/obj/effect/landmark/start/security_officer, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/security/office) -"anO" = ( +"anI" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, /turf/open/floor/plasteel, /area/security/office) -"anP" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +"anJ" = ( +/obj/machinery/light{ dir = 4 }, -/obj/item/kirbyplants{ - icon_state = "plant-22" +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 }, /turf/open/floor/plasteel/dark, /area/security/office) -"anQ" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +"anK" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 4 }, -/turf/open/floor/plating, +/turf/closed/wall, +/area/security/office) +"anL" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) +"anM" = ( +/obj/item/folder/red, +/obj/item/taperecorder, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/obj/structure/table/glass, +/turf/open/floor/plasteel/dark, +/area/security/office) +"anN" = ( +/obj/vehicle/ridden/secway, +/obj/item/key/security, +/obj/effect/turf_decal/bot, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) +"anO" = ( +/obj/structure/tank_dispenser/oxygen, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) +"anP" = ( +/obj/machinery/suit_storage_unit/hos, +/obj/machinery/airalarm{ + pixel_y = 22 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hos) +"anQ" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk, +/obj/structure/sign/plaques/kiddie{ + desc = "An embossed piece of paper from the University of Nanotrasen at Portpoint."; + name = "\improper 'Diploma' frame"; + pixel_y = 32 + }, +/turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) "anR" = ( -/obj/structure/cable{ - icon_state = "1-8" +/obj/structure/table/wood, +/obj/machinery/recharger, +/obj/machinery/status_display/evac{ + pixel_y = 32 }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 - }, -/obj/machinery/light_switch{ - pixel_y = -24 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 +/obj/machinery/light{ + dir = 1; + light_color = "#706891" }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) "anS" = ( -/obj/structure/cable{ - icon_state = "1-4" +/obj/structure/table/wood, +/obj/item/storage/box/seccarts{ + pixel_x = 3; + pixel_y = 2 }, -/obj/machinery/keycard_auth{ - pixel_y = -24 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 +/obj/item/storage/box/deputy, +/obj/machinery/newscaster/security_unit{ + pixel_y = 32 }, /turf/open/floor/plasteel/dark, /area/command/heads_quarters/hos) "anT" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) -"anU" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/camera{ - c_tag = "Head of Security's Office"; - dir = 1 - }, -/obj/item/radio/intercom{ - dir = 4; - name = "Station Intercom (General)"; - pixel_y = -27 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) -"anV" = ( -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/machinery/power/apc{ - name = "Head of Security's Office APC"; - pixel_y = -24 - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) -"anW" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-8" - }, /obj/structure/cable, -/obj/machinery/door/poddoor/preopen{ - id = "hos_spess_shutters"; - name = "Space shutters" +/turf/open/floor/plating, +/area/security/execution/transfer) +"anU" = ( +/obj/structure/table/optable, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/security/execution/transfer) +"anV" = ( +/turf/open/floor/plasteel/white, +/area/security/execution/transfer) +"anW" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "1-2" }, /turf/open/floor/plating, -/area/command/heads_quarters/hos) +/area/security/execution/transfer) "anX" = ( /turf/closed/wall/r_wall, /area/command/teleporter) @@ -6128,82 +5473,7 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, /area/maintenance/department/security/brig) -"aoe" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aof" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aog" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) "aoh" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aoi" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aoj" = ( -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aok" = ( -/obj/machinery/computer/security/labor, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"aol" = ( -/obj/machinery/computer/shuttle/labor, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"aom" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"aon" = ( -/turf/open/floor/plasteel, -/area/security/brig) -"aoo" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ @@ -6214,7 +5484,7 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"aop" = ( +"aoi" = ( /obj/structure/bed/dogbed, /obj/machinery/requests_console{ department = "Security"; @@ -6226,33 +5496,26 @@ }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"aoq" = ( +"aok" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/showroomfloor, +/area/security/warden) +"aom" = ( /obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ dir = 8 }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"aor" = ( +"aon" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"aos" = ( -/obj/machinery/door/airlock/security{ - name = "Brig Control"; - req_access_txt = "3" - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/machinery/door/firedoor, +"aoo" = ( /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"aot" = ( +"aop" = ( /obj/structure/cable{ icon_state = "4-8" }, @@ -6267,34 +5530,7 @@ }, /turf/open/floor/plasteel, /area/security/office) -"aou" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/security/office) -"aov" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/office) -"aow" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/office) -"aox" = ( +"aoq" = ( /obj/structure/cable{ icon_state = "4-8" }, @@ -6304,16 +5540,13 @@ }, /turf/open/floor/plasteel, /area/security/office) -"aoy" = ( +"aor" = ( /obj/structure/cable{ icon_state = "1-2" }, /obj/structure/cable{ icon_state = "2-8" }, -/obj/machinery/light{ - dir = 4 - }, /obj/structure/disposalpipe/segment{ dir = 10 }, @@ -6324,6 +5557,13 @@ }, /turf/open/floor/plasteel, /area/security/office) +"aow" = ( +/turf/closed/wall/r_wall, +/area/security/office) +"aoy" = ( +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/plating, +/area/maintenance/fore) "aoz" = ( /turf/closed/wall, /area/maintenance/fore) @@ -6349,134 +5589,51 @@ /obj/structure/grille, /turf/open/space, /area/solars/port) -"aoI" = ( -/obj/structure/lattice, -/turf/open/space, -/area/solars/port) "aoJ" = ( -/obj/structure/lattice, -/obj/structure/grille/broken, -/turf/open/space, -/area/solars/port) +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) "aoK" = ( -/turf/open/floor/plating{ - icon_state = "platingdmg3" - }, -/area/maintenance/department/security/brig) -"aoL" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aoO" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ dir = 1 }, -/obj/machinery/camera{ - c_tag = "Brig Gulag Teleporter"; +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"aoL" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 4 }, -/obj/machinery/light{ - dir = 8 - }, -/obj/structure/table, -/obj/item/storage/box/prisoner, -/obj/item/razor{ - pixel_x = -6 - }, -/obj/item/paper/guides/jobs/security/labor_camp, -/obj/item/pen, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"aoP" = ( -/obj/structure/chair/office/dark{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"aoQ" = ( -/obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ - icon_state = "0-8" + icon_state = "4-8" }, -/turf/open/floor/plating, -/area/security/warden) -"aoR" = ( -/obj/item/book/manual/wiki/security_space_law, -/obj/item/clothing/ears/earmuffs, -/obj/item/clothing/glasses/sunglasses, -/obj/structure/table/reinforced, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"aoS" = ( -/obj/structure/table/reinforced, -/obj/machinery/button/door{ - id = "Secure Gate"; - name = "Entrance Lockdown"; - pixel_x = 5; - pixel_y = -2 - }, -/obj/machinery/button/door{ - id = "Prison Gate"; - name = "Permabrig Lockdown"; - pixel_x = 5; - pixel_y = 8; - req_access_txt = "2" - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"aoT" = ( -/obj/structure/chair/office/dark, -/obj/effect/landmark/start/warden, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"aoU" = ( +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"aoO" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/computer/crew{ dir = 8 }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"aoV" = ( +"aoP" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ dir = 4 }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"aoW" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"aoX" = ( -/obj/structure/rack, -/obj/item/crowbar, -/obj/item/wrench, -/obj/item/laser_pointer/red, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"aoY" = ( -/obj/structure/filingcabinet/chestdrawer, -/obj/machinery/light_switch{ - pixel_y = -22 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"aoZ" = ( +"aoQ" = ( /obj/structure/cable, /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -6484,7 +5641,7 @@ }, /turf/open/floor/plating, /area/security/warden) -"apa" = ( +"aoR" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ dir = 4 @@ -6501,7 +5658,18 @@ }, /turf/open/floor/plasteel, /area/security/office) -"apb" = ( +"aoS" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/security/office) +"aoT" = ( /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -6511,7 +5679,7 @@ }, /turf/open/floor/plasteel, /area/security/office) -"apc" = ( +"aoU" = ( /obj/structure/disposalpipe/sorting/mail/flip{ dir = 1; sortType = 7 @@ -6521,7 +5689,7 @@ }, /turf/open/floor/plasteel, /area/security/office) -"apd" = ( +"aoV" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -6531,7 +5699,7 @@ }, /turf/open/floor/plasteel, /area/security/office) -"ape" = ( +"aoW" = ( /obj/machinery/airalarm{ dir = 1; pixel_y = -22 @@ -6545,17 +5713,13 @@ }, /turf/open/floor/plasteel, /area/security/office) -"apf" = ( +"aoX" = ( /obj/structure/cable{ icon_state = "1-4" }, /obj/structure/disposalpipe/segment{ dir = 5 }, -/obj/structure/sign/warning/vacuum/external{ - pixel_x = 32; - pixel_y = -32 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, @@ -6569,9 +5733,29 @@ /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/machinery/light, /turf/open/floor/plasteel, /area/security/office) -"apg" = ( +"aoY" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/office) +"aoZ" = ( /obj/structure/cable{ icon_state = "4-8" }, @@ -6584,7 +5768,7 @@ }, /turf/open/floor/plating, /area/maintenance/fore) -"aph" = ( +"apa" = ( /obj/structure/cable{ icon_state = "4-8" }, @@ -6593,7 +5777,7 @@ }, /turf/open/floor/plating, /area/maintenance/fore) -"api" = ( +"apb" = ( /obj/machinery/power/apc{ dir = 1; name = "Fore Maintenance APC"; @@ -6602,34 +5786,51 @@ /obj/structure/cable{ icon_state = "0-4" }, -/obj/structure/cable{ - icon_state = "0-8" - }, /obj/structure/disposalpipe/segment{ dir = 4 }, -/turf/open/floor/plating, -/area/maintenance/fore) -"apj" = ( /obj/structure/cable{ icon_state = "4-8" }, +/turf/open/floor/plating, +/area/maintenance/fore) +"apc" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, +/area/maintenance/fore) +"apf" = ( /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/light{ - dir = 1 +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/grille, +/turf/open/floor/plating, +/area/maintenance/fore) +"apj" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" }, /turf/open/floor/plating, /area/maintenance/fore) "apk" = ( -/obj/structure/cable{ - icon_state = "2-8" - }, /obj/structure/disposalpipe/segment{ dir = 10 }, -/turf/open/floor/plating, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, /area/maintenance/fore) "apl" = ( /obj/machinery/door/airlock/external{ @@ -6648,6 +5849,13 @@ /turf/open/floor/plating, /area/maintenance/fore) "apn" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/airlock/external{ + name = "Security External Airlock"; + req_access_txt = "63" + }, /turf/open/floor/plating, /area/maintenance/fore) "apo" = ( @@ -6706,49 +5914,21 @@ }, /area/maintenance/department/crew_quarters/dorms) "apz" = ( -/obj/item/target/clown, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"apB" = ( -/obj/structure/girder, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"apE" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/security/brig) -"apF" = ( -/obj/machinery/computer/prisoner/gulag_teleporter_computer{ - dir = 1 +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security{ + aiControlDisabled = 1; + name = "Prisoner Transfer Centre"; + req_access_txt = "2" }, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"apG" = ( -/obj/machinery/gulag_teleporter, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"apH" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 10 + dir = 4 }, -/turf/open/floor/plasteel, -/area/security/brig) -"apI" = ( -/obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ - icon_state = "0-2" + icon_state = "4-8" }, -/obj/structure/cable, -/turf/open/floor/plating, -/area/security/warden) -"apJ" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-2" - }, -/turf/open/floor/plating, -/area/security/warden) -"apK" = ( +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"apE" = ( /obj/structure/table/reinforced, /obj/machinery/door/window/brigdoor{ dir = 1; @@ -6768,7 +5948,7 @@ }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"apL" = ( +"apF" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ @@ -6776,50 +5956,22 @@ }, /turf/open/floor/plating, /area/security/warden) -"apM" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Brig Control"; - req_access_txt = "3" +"apG" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-2" }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/obj/structure/disposalpipe/segment, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel/showroomfloor, +/turf/open/floor/plating, /area/security/warden) -"apN" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, +"apH" = ( +/obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ - icon_state = "4-8" + icon_state = "0-2" }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"apO" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"apP" = ( +/obj/structure/cable, +/turf/open/floor/plating, +/area/security/warden) +"apL" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/security{ name = "Security Office"; @@ -6829,6 +5981,21 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/security/office) +"apN" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/reagent_dispensers/peppertank{ + pixel_y = 30 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/brig) "apQ" = ( /obj/structure/cable{ icon_state = "1-2" @@ -6897,16 +6064,6 @@ /turf/closed/wall, /area/commons/dorms) "aqa" = ( -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/machinery/power/solar{ - id = "portsolar"; - name = "Port Solar Array" - }, -/turf/open/floor/plasteel/airless/solarpanel, -/area/solars/port) -"aqb" = ( /obj/structure/lattice/catwalk, /obj/structure/cable{ icon_state = "2-8" @@ -6916,171 +6073,60 @@ }, /turf/open/space, /area/solars/port) -"aqc" = ( -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/machinery/power/solar{ - id = "portsolar"; - name = "Port Solar Array" - }, -/turf/open/floor/plasteel/airless/solarpanel, -/area/solars/port) "aqd" = ( -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/machinery/power/solar{ - id = "starboardsolar"; - name = "Starboard Solar Array" - }, -/turf/open/floor/plasteel/airless/solarpanel, +/obj/structure/lattice, +/turf/open/space, /area/solars/port) "aqe" = ( -/obj/item/target/alien, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison) "aqg" = ( /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plating, /area/maintenance/department/security/brig) -"aqh" = ( -/obj/structure/reagent_dispensers/watertank, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) "aqi" = ( -/obj/structure/closet, -/obj/item/clothing/under/color/black, -/obj/item/clothing/under/color/red, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aqm" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ +/obj/machinery/computer/prisoner/gulag_teleporter_computer{ dir = 1 }, +/turf/open/floor/plasteel/dark, +/area/security/brig) +"aqm" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-8" + }, /turf/open/floor/plasteel, /area/security/brig) "aqn" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/firealarm{ + pixel_y = 29 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 }, /obj/effect/turf_decal/tile/red{ dir = 4 }, -/obj/structure/cable{ - icon_state = "1-4" - }, /turf/open/floor/plasteel, /area/security/brig) "aqo" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/structure/extinguisher_cabinet{ - pixel_y = 30 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"aqp" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"aqq" = ( -/obj/machinery/camera{ - c_tag = "Brig Cells" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"aqr" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"aqs" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"aqt" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"aqu" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/obj/structure/disposalpipe/segment, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"aqv" = ( /obj/machinery/camera{ c_tag = "Brig Entrance" }, @@ -7099,22 +6145,23 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"aqw" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +"aqp" = ( +/obj/structure/chair{ + name = "Defense" }, -/obj/structure/reagent_dispensers/peppertank{ - pixel_y = 30 - }, -/obj/effect/turf_decal/tile/red{ +/obj/effect/turf_decal/tile/green{ dir = 1 }, -/obj/effect/turf_decal/tile/red{ +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ dir = 4 }, +/obj/machinery/camera{ + c_tag = "Courtroom" + }, /turf/open/floor/plasteel, -/area/security/brig) -"aqx" = ( +/area/security/courtroom) +"aqq" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -7129,14 +6176,10 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"aqy" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ +"aqr" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel, -/area/security/brig) -"aqz" = ( /obj/effect/turf_decal/tile/red{ dir = 1 }, @@ -7145,11 +6188,23 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"aqA" = ( -/obj/machinery/computer/security/telescreen/interrogation{ - dir = 8; - pixel_x = 30 +"aqs" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 }, +/turf/open/floor/plasteel, +/area/security/brig) +"aqt" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/brig) +"aqu" = ( /obj/effect/turf_decal/tile/red{ dir = 1 }, @@ -7159,19 +6214,59 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"aqB" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +"aqv" = ( +/obj/structure/chair, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel/dark, -/area/security/brig) -"aqC" = ( -/turf/open/floor/plasteel/dark, -/area/security/brig) -"aqD" = ( -/obj/machinery/status_display/ai{ - pixel_y = 32 +/area/security/courtroom) +"aqw" = ( +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_y = 22 + }, +/turf/open/floor/plasteel, +/area/security/courtroom) +"aqx" = ( +/obj/structure/chair{ + name = "Defense" + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/courtroom) +"aqA" = ( +/obj/structure/chair{ + dir = 8 + }, +/obj/machinery/light{ + dir = 1 }, /turf/open/floor/plasteel/dark, -/area/security/brig) +/area/security/courtroom) +"aqB" = ( +/obj/structure/closet/secure_closet/lethalshots, +/obj/machinery/camera/motion{ + c_tag = "Armory Motion Sensor" + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) "aqE" = ( /obj/structure/cable{ icon_state = "1-2" @@ -7364,166 +6459,137 @@ }, /turf/open/space/basic, /area/space) -"ara" = ( -/obj/structure/lattice/catwalk, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/space, -/area/solars/port) "arc" = ( -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"ard" = ( -/obj/item/clothing/head/cone, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"ari" = ( -/obj/machinery/door/airlock/external{ - name = "Labor Camp Shuttle Airlock"; - req_access_txt = "2" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"arj" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security/glass{ - name = "Labor Camp Shuttle Airlock"; - req_access_txt = "2" - }, -/obj/machinery/button/door{ - id = "prison release"; - name = "Labor Camp Shuttle Lockdown"; - pixel_y = -25; - req_access_txt = "2" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/security/brig) -"ark" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/turf/open/floor/plasteel, -/area/security/brig) -"arl" = ( +/area/command/heads_quarters/hos) +"ari" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/security/brig) -"arm" = ( +"arj" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, /turf/open/floor/plasteel, /area/security/brig) -"arn" = ( +"ark" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/structure/disposalpipe/segment{ dir = 5 }, /turf/open/floor/plasteel, /area/security/brig) -"aro" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +"arl" = ( /obj/structure/disposalpipe/segment{ dir = 4 }, /turf/open/floor/plasteel, /area/security/brig) -"arp" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"arq" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/structure/disposalpipe/junction{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"arr" = ( -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"ars" = ( +"arm" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/structure/cable{ + icon_state = "2-4" + }, /turf/open/floor/plasteel, /area/security/brig) -"art" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, +"arn" = ( /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, /turf/open/floor/plasteel, /area/security/brig) -"aru" = ( +"aro" = ( /obj/machinery/door/airlock/security{ - name = "Interrogation"; - req_access_txt = "63" + name = "Security Access"; + req_access_txt = "1" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"arv" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ +/turf/open/floor/plasteel, +/area/security/courtroom) +"arp" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"arw" = ( +/turf/open/floor/plasteel, +/area/security/courtroom) +"ars" = ( /obj/structure/chair{ - dir = 4 + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 }, /turf/open/floor/plasteel/dark, -/area/security/brig) -"arx" = ( -/obj/item/flashlight/lamp, -/obj/structure/table/glass, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"ary" = ( +/area/security/courtroom) +"art" = ( /obj/structure/chair{ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/security/brig) -"arz" = ( -/obj/machinery/camera{ - c_tag = "Brig Interrogation"; - dir = 8; - network = list("interrogation") - }, +/area/security/courtroom) +"aru" = ( +/obj/structure/table, +/obj/item/storage/fancy/donut_box, /turf/open/floor/plasteel/dark, -/area/security/brig) +/area/security/courtroom) +"arv" = ( +/obj/structure/table/glass, +/obj/item/mmi, +/obj/item/clothing/mask/balaclava, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/security/execution/transfer) +"arw" = ( +/obj/effect/decal/cleanable/ash, +/obj/item/cigbutt, +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, +/area/maintenance/fore) +"arx" = ( +/obj/structure/girder, +/obj/structure/grille/broken, +/turf/open/floor/plating, +/area/maintenance/fore) "arA" = ( /turf/closed/wall/r_wall, /area/command/bridge) @@ -7909,7 +6975,6 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, -/obj/structure/bedsheetbin/color, /turf/open/floor/plasteel/cafeteria, /area/commons/dorms) "ash" = ( @@ -7929,114 +6994,49 @@ /turf/open/floor/plating, /area/commons/dorms) "aso" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating{ - icon_state = "platingdmg3" - }, -/area/maintenance/department/security/brig) -"asr" = ( -/obj/structure/cable{ - icon_state = "2-8" - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"asu" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 +/obj/structure/table/glass, +/obj/item/storage/backpack/duffelbag/sec/surgery{ + pixel_y = 5 }, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 }, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/white, +/area/security/execution/transfer) +"asr" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/door/poddoor/preopen{ + id = "prison release"; + name = "prisoner processing blast door" + }, +/turf/open/floor/plasteel/dark, /area/security/brig) -"asv" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 +"asu" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden, +/obj/structure/cable{ + icon_state = "4-8" }, /turf/open/floor/plasteel, /area/security/brig) -"asw" = ( +"asv" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"asx" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/light, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/obj/machinery/door_timer{ - id = "Cell 1"; - name = "Cell 1"; - pixel_y = -32 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"asy" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"asz" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/obj/machinery/door_timer{ - id = "Cell 2"; - name = "Cell 2"; - pixel_y = -32 - }, -/obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 }, /obj/structure/cable{ icon_state = "4-8" }, -/turf/open/floor/plasteel, -/area/security/brig) -"asA" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden, /obj/structure/cable{ - icon_state = "4-8" + icon_state = "2-8" }, /turf/open/floor/plasteel, /area/security/brig) -"asB" = ( +"asw" = ( /obj/machinery/light, /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 4 @@ -8055,95 +7055,171 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"asC" = ( +"asx" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"asD" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"asE" = ( -/obj/machinery/light, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"asF" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"asG" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/turf/closed/wall, -/area/security/brig) -"asH" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"asI" = ( -/obj/structure/chair{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"asJ" = ( -/obj/item/folder/red, -/obj/item/taperecorder, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/obj/structure/table/glass, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"asK" = ( -/obj/structure/chair{ +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 +/obj/structure/cable{ + icon_state = "4-8" }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/security/brig) -"asL" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +"asy" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, /turf/open/floor/plasteel/dark, +/area/security/courtroom) +"asz" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, /area/security/brig) +"asA" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/security/brig) +"asB" = ( +/obj/machinery/power/apc{ + areastring = "/area/security/courtroom"; + dir = 8; + name = "Courtroom APC"; + pixel_x = -25 + }, +/obj/structure/cable, +/obj/structure/chair{ + dir = 4; + name = "Bailiff" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 10 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/courtroom) +"asC" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/door/airlock/public/glass{ + name = "Courtroom"; + req_access_txt = "42" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/courtroom) +"asD" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/item/beacon, +/turf/open/floor/plasteel, +/area/security/courtroom) +"asE" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/landmark/start/lawyer, +/turf/open/floor/plasteel, +/area/security/courtroom) +"asF" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/effect/landmark/event_spawn, +/turf/open/floor/plasteel/dark, +/area/security/courtroom) +"asG" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = 26 + }, +/turf/open/floor/plasteel/dark, +/area/security/courtroom) +"asH" = ( +/obj/machinery/power/emitter/anchored{ + dir = 1; + state = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/security/execution/transfer) +"asI" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/sign/warning/vacuum/external{ + pixel_y = 32 + }, +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, +/area/maintenance/fore) +"asK" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, +/area/maintenance/fore) "asM" = ( /obj/machinery/light{ dir = 8 @@ -8398,30 +7474,10 @@ "atn" = ( /turf/closed/wall, /area/commons/fitness/recreation) -"atp" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/circuit/green, -/area/maintenance/department/security/brig) -"atq" = ( -/turf/open/floor/circuit/green, -/area/maintenance/department/security/brig) "atv" = ( -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/turf/open/floor/plating, -/area/security/brig) -"atw" = ( /obj/machinery/door/window/brigdoor/security/cell{ - id = "Cell 1"; - name = "Cell 1" - }, -/obj/structure/cable{ - icon_state = "4-8" + id = "Cell 3"; + name = "Cell 3" }, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ @@ -8429,10 +7485,7 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"atx" = ( -/obj/structure/cable{ - icon_state = "0-8" - }, +"atw" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable, @@ -8441,10 +7494,19 @@ }, /turf/open/floor/plating, /area/security/brig) -"aty" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ +"atx" = ( +/obj/effect/turf_decal/tile/red{ dir = 1 }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"aty" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 @@ -8458,77 +7520,14 @@ /turf/open/floor/plasteel, /area/security/brig) "atz" = ( +/obj/structure/cable{ + icon_state = "0-2" + }, /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/structure/cable, /turf/open/floor/plating, /area/security/brig) "atA" = ( -/obj/machinery/door/window/brigdoor/security/cell{ - id = "Cell 2"; - name = "Cell 2" - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"atB" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"atC" = ( -/obj/machinery/door/window/brigdoor/security/cell{ - id = "Cell 3"; - name = "Cell 3" - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"atD" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable, -/obj/structure/cable{ - icon_state = "0-2" - }, -/turf/open/floor/plating, -/area/security/brig) -"atE" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/obj/machinery/door/airlock/security/glass{ - id_tag = "innerbrig"; - name = "Brig"; - req_access_txt = "63" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"atF" = ( -/obj/structure/cable{ - icon_state = "0-2" - }, -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable, -/turf/open/floor/plating, -/area/security/brig) -"atG" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper, /obj/machinery/door/airlock/security/glass{ id_tag = "innerbrig"; @@ -8543,25 +7542,70 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"atH" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Brig Desk"; - req_access_txt = "1" +"atB" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel/dark, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, /area/security/brig) -"atI" = ( +"atC" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall, +/area/security/brig) +"atE" = ( +/obj/structure/table/wood, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue, +/obj/item/gavelblock, +/turf/open/floor/plasteel, +/area/security/courtroom) +"atF" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/courtroom) +"atG" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/obj/machinery/holopad, +/obj/effect/landmark/event_spawn, +/turf/open/floor/plasteel, +/area/security/courtroom) +"atH" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, -/area/security/brig) -"atJ" = ( +/area/security/courtroom) +"atI" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/dark, -/area/security/brig) +/area/security/execution/transfer) "atK" = ( /obj/structure/cable{ icon_state = "1-2" @@ -8590,7 +7634,7 @@ dir = 10 }, /turf/open/floor/plasteel/dark, -/area/ai_monitored/turret_protected/aisat_interior) +/area/command/bridge) "atN" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 @@ -8900,76 +7944,38 @@ }, /area/holodeck/rec_center) "aus" = ( -/obj/machinery/mech_bay_recharge_port, -/obj/structure/cable, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aut" = ( -/obj/item/clothing/head/collectable/police, -/turf/open/floor/mech_bay_recharge_floor, -/area/maintenance/department/security/brig) -"auu" = ( -/obj/machinery/computer/mech_bay_power_console{ - dir = 1 - }, -/obj/structure/cable, -/turf/open/floor/plasteel, -/area/maintenance/department/security/brig) -"aux" = ( -/obj/item/radio/intercom{ - desc = "Talk through this. It looks like it has been modified to not broadcast."; - name = "Prison Intercom (General)"; - pixel_x = -25; - pixel_y = -2; - prison_radio = 1 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"auz" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"auA" = ( -/obj/effect/landmark/event_spawn, -/turf/open/floor/plasteel, -/area/security/brig) -"auB" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/flasher{ - id = "brigentry"; - pixel_x = -28 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"auC" = ( -/obj/structure/disposalpipe/segment, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 4 }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"aut" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 5 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison) +"auu" = ( +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/prison) +"aux" = ( +/obj/effect/landmark/event_spawn, /turf/open/floor/plasteel, /area/security/brig) -"auD" = ( +"auz" = ( /obj/structure/table/reinforced, /obj/machinery/door/window/eastleft{ dir = 8; @@ -8982,48 +7988,68 @@ }, /turf/open/floor/plasteel/dark, /area/security/brig) -"auE" = ( -/obj/machinery/computer/secure_data, -/obj/machinery/button/door{ - desc = "A remote control switch for the medbay foyer."; - id = "innerbrig"; - name = "Brig Interior Doors Control"; - normaldoorcontrol = 1; - pixel_x = -6; - pixel_y = 36; - req_access_txt = "63" +"auB" = ( +/obj/structure/table/wood, +/obj/effect/turf_decal/tile/blue{ + dir = 4 }, -/obj/machinery/button/door{ - desc = "A remote control switch for the medbay foyer."; - id = "outerbrig"; - name = "Brig Exterior Doors Control"; - normaldoorcontrol = 1; - pixel_x = -6; - pixel_y = 24; - req_access_txt = "63" +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 }, -/obj/machinery/button/flasher{ - id = "brigentry"; - pixel_x = 6; - pixel_y = 24 +/turf/open/floor/plasteel, +/area/security/courtroom) +"auC" = ( +/obj/structure/table/wood, +/turf/open/floor/plasteel, +/area/security/courtroom) +"auD" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/security/brig) +/obj/structure/table/wood, +/turf/open/floor/plasteel, +/area/security/courtroom) "auF" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/structure/chair{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, /turf/open/floor/plasteel/dark, -/area/security/brig) +/area/security/courtroom) "auG" = ( -/obj/machinery/computer/security, +/obj/structure/chair{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/dark, -/area/security/brig) +/area/security/courtroom) "auH" = ( /turf/closed/wall, /area/command/heads_quarters/captain) "auI" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/command/heads_quarters/captain) +/obj/structure/table, +/obj/item/storage/fancy/donut_box{ + pixel_y = 2 + }, +/obj/structure/noticeboard{ + pixel_y = 32 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/office) "auJ" = ( /obj/structure/cable{ icon_state = "1-2" @@ -9333,91 +8359,13 @@ /turf/open/floor/plating, /area/maintenance/department/crew_quarters/dorms) "avp" = ( -/obj/docking_port/stationary{ - dir = 8; - dwidth = 2; - height = 5; - id = "laborcamp_home"; - name = "fore bay 1"; - roundstart_template = /datum/map_template/shuttle/labour/box; - width = 9 +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 }, -/turf/open/space/basic, -/area/space) +/turf/open/floor/plasteel, +/area/security/brig) "avq" = ( -/obj/machinery/door/airlock/external{ - name = "Labor Camp Shuttle Airlock" - }, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"avr" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/machinery/camera{ - c_tag = "Labor Shuttle Dock"; - dir = 8 - }, -/obj/machinery/gulag_item_reclaimer{ - pixel_y = 24 - }, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"avs" = ( -/obj/structure/bed, -/obj/machinery/flasher{ - id = "Cell 1"; - pixel_x = -28 - }, -/obj/item/bedsheet/blue, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"avt" = ( -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"avu" = ( -/obj/structure/closet/secure_closet/brig{ - id = "Cell 1"; - name = "Cell 1 Locker" - }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/security/brig) -"avv" = ( -/obj/structure/bed, -/obj/machinery/flasher{ - id = "Cell 2"; - pixel_x = -28 - }, -/obj/item/bedsheet/green, -/obj/effect/turf_decal/tile/green, -/obj/effect/turf_decal/tile/green{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"avw" = ( -/obj/effect/turf_decal/tile/green, -/obj/effect/turf_decal/tile/green{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"avx" = ( /obj/structure/closet/secure_closet/brig{ id = "Cell 2"; name = "Cell 2 Locker" @@ -9431,27 +8379,27 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"avy" = ( -/obj/structure/bed, -/obj/machinery/flasher{ - id = "Cell 3"; - pixel_x = -28 +"avr" = ( +/obj/machinery/photocopier, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = 32 }, -/obj/item/bedsheet/orange, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/office) +"avs" = ( /obj/effect/turf_decal/tile/yellow, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, /turf/open/floor/plasteel, /area/security/brig) -"avz" = ( -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"avA" = ( +"avt" = ( /obj/structure/closet/secure_closet/brig{ id = "Cell 3"; name = "Cell 3 Locker" @@ -9465,17 +8413,25 @@ }, /turf/open/floor/plasteel, /area/security/brig) -"avB" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 +"avu" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hos) +"avv" = ( +/obj/structure/cable{ + icon_state = "1-2" }, /turf/open/floor/plasteel, /area/security/brig) -"avC" = ( +"avw" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/brig) +"avx" = ( /obj/structure/table/reinforced, /obj/machinery/door/window/eastleft{ dir = 8; @@ -9486,69 +8442,94 @@ /obj/item/restraints/handcuffs, /turf/open/floor/plasteel/dark, /area/security/brig) -"avD" = ( -/obj/structure/chair/office/dark{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"avE" = ( +"avy" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 9 }, /turf/open/floor/plasteel/dark, /area/security/brig) -"avF" = ( +"avz" = ( /obj/structure/chair/office/dark, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 + dir = 1 }, /turf/open/floor/plasteel/dark, /area/security/brig) -"avG" = ( +"avC" = ( +/obj/structure/chair{ + dir = 1; + name = "Prosecution" + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/floor/plasteel, +/area/security/courtroom) +"avE" = ( +/obj/structure/chair{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/security/courtroom) +"avF" = ( +/obj/structure/chair{ + dir = 8 + }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/closed/wall, -/area/command/heads_quarters/captain) +/obj/machinery/light, +/turf/open/floor/plasteel/dark, +/area/security/courtroom) "avH" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/structure/disposalpipe/segment, +/obj/structure/chair/office/dark{ + dir = 4 + }, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) +"avI" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /obj/structure/curtain, -/obj/item/soap/deluxe, -/obj/item/bikehorn/rubberducky, /obj/machinery/shower{ dir = 1 }, +/obj/item/soap/deluxe, +/obj/item/bikehorn/rubberducky, /turf/open/floor/plasteel/freezer, /area/command/heads_quarters/captain) -"avI" = ( +"avJ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, /obj/structure/sink{ pixel_y = 28 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/structure/mirror{ pixel_y = 30 }, /turf/open/floor/plasteel/freezer, /area/command/heads_quarters/captain) -"avJ" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, -/turf/open/floor/plasteel/freezer, -/area/command/heads_quarters/captain) "avK" = ( /obj/structure/toilet/secret/low_loot{ dir = 8 }, +/obj/machinery/light{ + dir = 1 + }, /turf/open/floor/plasteel/freezer, /area/command/heads_quarters/captain) "avL" = ( @@ -9640,7 +8621,7 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ai_monitored/turret_protected/aisat_interior) +/area/command/bridge) "avR" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -9746,7 +8727,7 @@ req_access_txt = "10;13" }, /turf/open/floor/plating, -/area/ai_monitored/turret_protected/aisat_interior) +/area/command/bridge) "awd" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -9961,14 +8942,10 @@ /obj/item/storage/briefcase, /turf/open/floor/plating, /area/maintenance/department/security/brig) -"awH" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/security/glass{ - name = "Labor Camp Shuttle Airlock" - }, -/turf/open/floor/plasteel/dark, -/area/security/brig) "awI" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, /obj/structure/cable{ icon_state = "0-4" }, @@ -9983,132 +8960,40 @@ /obj/structure/cable{ icon_state = "0-8" }, -/obj/structure/cable{ - icon_state = "0-4" - }, /obj/machinery/door/poddoor/preopen{ id = "Secure Gate"; name = "brig shutters" }, +/obj/structure/cable, /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/security/brig) "awK" = ( +/obj/machinery/light, /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 }, -/obj/structure/cable{ - icon_state = "2-4" - }, /obj/structure/cable{ icon_state = "4-8" }, /turf/open/floor/plasteel, /area/security/brig) -"awL" = ( -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/obj/machinery/door/airlock/security/glass{ - id_tag = "outerbrig"; - name = "Brig"; - req_access_txt = "63" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/brig) "awM" = ( -/obj/structure/cable, -/obj/machinery/door/poddoor/preopen{ - id = "Secure Gate"; - name = "brig shutters" - }, +/obj/effect/spawner/structure/window/reinforced, +/obj/effect/spawner/structure/window/reinforced/tinted, +/turf/open/floor/plating, +/area/security/courtroom) +"awO" = ( +/turf/closed/wall/r_wall, +/area/security/courtroom) +"awQ" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, -/area/security/brig) -"awN" = ( -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/obj/machinery/door/airlock/security/glass{ - id_tag = "outerbrig"; - name = "Brig"; - req_access_txt = "63" - }, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"awO" = ( -/obj/structure/table/reinforced, -/obj/machinery/door/window/southleft{ - base_state = "right"; - dir = 1; - icon_state = "right"; - name = "Brig Desk"; - req_access_txt = "1" - }, -/obj/machinery/door/poddoor/preopen{ - id = "Secure Gate"; - name = "brig shutters" - }, -/obj/item/radio, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"awP" = ( -/obj/machinery/door/window/southleft{ - base_state = "right"; - dir = 1; - icon_state = "right"; - name = "Brig Desk"; - req_access_txt = "1" - }, -/obj/item/reagent_containers/food/snacks/donut, -/obj/machinery/door/poddoor/preopen{ - id = "Secure Gate"; - name = "brig shutters" - }, -/obj/structure/table/reinforced, -/obj/item/folder/red{ - layer = 2.9 - }, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"awQ" = ( -/obj/structure/table/reinforced, -/obj/item/pen, -/obj/machinery/door/poddoor/preopen{ - id = "Secure Gate"; - name = "brig shutters" - }, -/obj/machinery/door/window/southleft{ - base_state = "right"; - dir = 1; - icon_state = "right"; - name = "Brig Desk"; - req_access_txt = "1" - }, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel/dark, -/area/security/brig) +/area/security/courtroom) "awR" = ( /turf/closed/wall/r_wall, /area/command/heads_quarters/captain) @@ -10353,57 +9238,51 @@ /obj/effect/landmark/xeno_spawn, /turf/open/floor/plasteel, /area/commons/fitness/recreation) -"axB" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/maintenance/solars/port) "axC" = ( -/turf/closed/wall, -/area/maintenance/solars/port) -"axE" = ( -/obj/machinery/door/poddoor/preopen{ - id = "prison release"; - name = "prisoner processing blast door" - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) -"axF" = ( -/obj/item/kirbyplants{ - icon_state = "plant-10" - }, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) +/obj/structure/table/wood, +/obj/item/folder/red, +/obj/item/stamp/hos, +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) "axG" = ( /turf/open/floor/plasteel, /area/hallway/primary/fore) "axH" = ( -/obj/structure/extinguisher_cabinet{ - pixel_y = 30 +/obj/effect/turf_decal/tile/red{ + dir = 4 }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) "axI" = ( -/obj/machinery/light{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 }, /obj/machinery/airalarm{ - pixel_y = 22 + dir = 1; + pixel_y = -22 }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "axJ" = ( -/obj/structure/sign/departments/security{ +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/structure/sign/poster/official/random{ pixel_y = 32 }, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"axK" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) "axL" = ( -/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "axM" = ( @@ -10411,6 +9290,9 @@ /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "axN" = ( @@ -10570,7 +9452,7 @@ }, /obj/machinery/door/firedoor, /turf/open/floor/plasteel/dark, -/area/ai_monitored/turret_protected/aisat_interior) +/area/command/bridge) "ayf" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -10721,85 +9603,57 @@ /turf/open/floor/plasteel, /area/commons/fitness/recreation) "ayy" = ( -/obj/structure/lattice/catwalk, -/obj/structure/cable, -/turf/open/space, -/area/solars/port) -"ayz" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/structure/sign/warning/vacuum/external{ - pixel_x = -32 +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/structure/cable, +/obj/machinery/door/poddoor/preopen{ + id = "hos_spess_shutters"; + name = "Space shutters" }, /turf/open/floor/plating, -/area/maintenance/solars/port) +/area/command/heads_quarters/hos) +"ayz" = ( +/obj/structure/table, +/obj/machinery/microwave, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "ayA" = ( -/obj/machinery/power/solar_control{ - dir = 4; - id = "portsolar"; - name = "Port Solar Control" - }, -/obj/structure/cable{ - icon_state = "0-2" - }, +/obj/structure/table, +/obj/structure/bedsheetbin, /turf/open/floor/plating, -/area/maintenance/solars/port) +/area/maintenance/department/security/brig) "ayB" = ( -/obj/machinery/light/small{ - dir = 1 +/obj/structure/sink/kitchen{ + pixel_y = 28 }, +/obj/item/reagent_containers/glass/beaker, /turf/open/floor/plating, -/area/maintenance/solars/port) +/area/maintenance/department/security/brig) "ayC" = ( -/obj/structure/cable{ - icon_state = "0-2" - }, -/obj/machinery/power/apc{ - dir = 1; - name = "Port Solar APC"; - pixel_y = 23 - }, -/obj/machinery/camera{ - c_tag = "Port Bow Solar"; - dir = 9; - name = "solar camera" - }, +/obj/structure/table, +/obj/item/flashlight/lamp, /turf/open/floor/plating, -/area/maintenance/solars/port) +/area/maintenance/department/security/brig) "ayD" = ( /obj/structure/closet/firecloset, /turf/open/floor/plating, /area/maintenance/department/security/brig) -"ayE" = ( -/obj/machinery/button/door{ - id = "prison release"; - name = "Labor Camp Shuttle Lockdown"; - pixel_x = -25; - req_access_txt = "2" - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) "ayF" = ( -/obj/structure/sign/warning/vacuum/external{ - pixel_y = 32 - }, /obj/structure/disposalpipe/segment{ dir = 6 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "ayG" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) "ayH" = ( @@ -10812,20 +9666,14 @@ /turf/open/floor/plasteel, /area/hallway/primary/fore) "ayI" = ( -/obj/machinery/navbeacon{ - codes_txt = "patrol;next_patrol=BrigS2"; - location = "BrigP" - }, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) "ayJ" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "ayL" = ( @@ -10835,17 +9683,11 @@ /turf/open/floor/plasteel, /area/hallway/primary/fore) "ayM" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) +/obj/structure/closet/secure_closet/brig, +/turf/open/floor/plasteel/dark, +/area/security/prison) "ayN" = ( /obj/machinery/holopad, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/navbeacon{ codes_txt = "patrol;next_patrol=BrigP"; location = "BrigS1" @@ -10853,11 +9695,24 @@ /turf/open/floor/plasteel, /area/hallway/primary/fore) "ayO" = ( -/obj/structure/disposalpipe/segment{ - dir = 9 +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security/glass{ + name = "Prison Wing"; + req_access_txt = "1" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 }, /turf/open/floor/plasteel, -/area/hallway/primary/fore) +/area/security/prison) "ayP" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel, @@ -11251,12 +10106,20 @@ /turf/open/floor/plasteel, /area/commons/fitness/recreation) "azG" = ( -/obj/machinery/power/tracker, -/obj/structure/cable{ - icon_state = "0-4" +/obj/structure/rack, +/obj/item/gun/energy/ionrifle, +/obj/item/gun/energy/temperature/security, +/obj/item/clothing/suit/armor/laserproof, +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" }, -/turf/open/floor/plasteel/airless/solarpanel, -/area/solars/port) +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -23 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) "azH" = ( /obj/structure/lattice/catwalk, /obj/structure/cable{ @@ -11265,96 +10128,15 @@ /turf/open/space, /area/solars/port) "azI" = ( -/obj/structure/lattice/catwalk, /obj/structure/cable{ - icon_state = "0-8" + icon_state = "0-2" }, -/turf/open/space, -/area/solars/port) -"azJ" = ( -/obj/structure/lattice/catwalk, -/obj/item/stack/cable_coil, -/turf/open/space, -/area/solars/port) -"azK" = ( -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port) -"azL" = ( -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/solars/port) -"azN" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plating, -/area/maintenance/solars/port) -"azP" = ( -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plating, -/area/maintenance/solars/port) -"azQ" = ( -/obj/structure/cable{ - icon_state = "2-8" - }, -/turf/open/floor/plating, -/area/maintenance/solars/port) -"azR" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/plating, -/area/maintenance/solars/port) -"azS" = ( -/obj/machinery/door/airlock/engineering{ - name = "Port Solar Access"; - req_access_txt = "10" - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plating, -/area/maintenance/solars/port) -"azY" = ( -/obj/structure/plasticflaps, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"azZ" = ( -/mob/living/simple_animal/bot/secbot/beepsky{ - name = "Officer Beepsky" - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aAa" = ( -/obj/structure/table, -/obj/machinery/cell_charger, -/obj/item/stock_parts/cell/potato{ - name = "\improper Beepsky's emergency battery" - }, -/obj/item/paper/fluff/jobs/security/beepsky_mom, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"aAb" = ( /obj/machinery/power/apc{ dir = 8; - name = "Fore Primary Hallway APC"; + name = "Security Office APC"; pixel_x = -25 }, -/obj/structure/cable{ - icon_state = "0-4" - }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/effect/turf_decal/tile/red{ dir = 1 }, @@ -11362,36 +10144,104 @@ dir = 8 }, /turf/open/floor/plasteel, -/area/hallway/primary/fore) -"aAc" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 - }, -/obj/structure/disposalpipe/segment, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) -"aAd" = ( -/obj/machinery/light, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/area/security/office) +"azJ" = ( +/obj/effect/landmark/start/security_officer, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, /turf/open/floor/plasteel, +/area/security/office) +"azK" = ( +/obj/structure/lattice/catwalk, +/turf/open/space, +/area/solars/port) +"azL" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/office) +"azN" = ( +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"azP" = ( +/obj/item/storage/box/mousetraps, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"azQ" = ( +/obj/structure/chair/stool, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"azR" = ( +/obj/structure/bed, +/obj/item/bedsheet, +/obj/structure/sign/poster/contraband/random{ + pixel_x = 32 + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"azS" = ( +/obj/machinery/atmospherics/components/unary/tank/oxygen, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"azY" = ( +/obj/machinery/atmospherics/components/unary/tank/nitrogen, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"azZ" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/preopen{ + id = "Prison Gate"; + name = "prison blast door" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/security/brig) +"aAa" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/brig) +"aAc" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, /area/hallway/primary/fore) "aAe" = ( -/obj/structure/cable{ - icon_state = "2-8" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aAf" = ( @@ -11399,30 +10249,34 @@ c_tag = "Fore Primary Hallway Port"; dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/structure/extinguisher_cabinet{ + pixel_y = -32 }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aAg" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aAh" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) -"aAi" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/obj/effect/turf_decal/tile/red{ + dir = 8 }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aAj" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 }, /turf/open/floor/plasteel, /area/hallway/primary/fore) @@ -11437,12 +10291,14 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aAm" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aAn" = ( @@ -11454,6 +10310,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aAo" = ( @@ -11703,45 +10560,60 @@ /turf/open/floor/plasteel, /area/commons/fitness/recreation) "aAV" = ( -/obj/structure/lattice/catwalk, -/obj/structure/cable{ - icon_state = "0-2" +/obj/structure/closet{ + name = "Evidence Closet" }, -/turf/open/space, -/area/solars/port) -"aAW" = ( -/obj/structure/rack, -/obj/item/clothing/mask/gas, -/obj/item/multitool, -/turf/open/floor/plating, -/area/maintenance/solars/port) -"aAX" = ( -/obj/structure/chair/stool, -/obj/machinery/power/terminal{ +/obj/structure/sign/poster/official/safety_report{ + pixel_y = 32 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ dir = 4 }, -/obj/structure/cable, -/turf/open/floor/plating, -/area/maintenance/solars/port) +/turf/open/floor/plasteel, +/area/security/brig) +"aAW" = ( +/obj/structure/rack, +/obj/item/gun/energy/e_gun{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/gun/energy/e_gun, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = -27 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) +"aAX" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) "aAY" = ( -/obj/machinery/power/smes, -/obj/structure/cable, -/turf/open/floor/plating, -/area/maintenance/solars/port) +/obj/machinery/rnd/production/techfab/department/security, +/turf/open/floor/plasteel/dark, +/area/security/office) "aBa" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plating{ - icon_state = "panelscorched" + icon_state = "platingdmg3" }, /area/maintenance/department/security/brig) "aBc" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/disposalpipe/segment, /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, -/obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/maintenance/department/security/brig) "aBd" = ( @@ -12173,20 +11045,19 @@ /turf/open/floor/plasteel, /area/commons/fitness/recreation) "aCa" = ( -/obj/structure/lattice/catwalk, /obj/structure/cable{ - icon_state = "1-4" + icon_state = "0-8" }, +/obj/machinery/power/solar{ + id = "starboardsolar"; + name = "Starboard Solar Array" + }, +/turf/open/floor/plasteel/airless/solarpanel, +/area/solars/port) +"aCc" = ( /obj/structure/cable{ icon_state = "1-8" }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/space, -/area/solars/port) -"aCc" = ( -/obj/structure/closet/emcloset, /turf/open/floor/plating, /area/maintenance/department/security/brig) "aCd" = ( @@ -12212,9 +11083,6 @@ /area/maintenance/department/security/brig) "aCh" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/maintenance/department/security/brig) @@ -12802,13 +11670,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/cargo) -"aDm" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) "aDo" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk, @@ -13715,11 +12576,8 @@ /area/space/nearstation) "aFk" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/spawner/lootdrop/minor/bowler_or_that, -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/structure/disposalpipe/segment, +/obj/effect/spawner/lootdrop/minor/bowler_or_that, /turf/open/floor/plating{ icon_state = "platingdmg3" }, @@ -14014,9 +12872,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/structure/disposalpipe/junction{ dir = 1 }, @@ -15067,15 +13922,22 @@ /turf/open/floor/plating, /area/maintenance/department/cargo) "aIr" = ( -/obj/structure/lattice/catwalk, /obj/structure/cable{ - icon_state = "1-4" + icon_state = "0-8" }, -/obj/structure/cable{ - icon_state = "1-8" +/obj/machinery/power/solar{ + id = "portsolar"; + name = "Port Solar Array" }, -/turf/open/space, +/turf/open/floor/plasteel/airless/solarpanel, /area/solars/port) +"aIz" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/structure/disposalpipe/junction{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/brig) "aIC" = ( /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" @@ -16354,6 +15216,10 @@ /obj/structure/cable{ icon_state = "1-8" }, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = 24 + }, /turf/open/floor/plasteel, /area/command/teleporter) "aMa" = ( @@ -16865,7 +15731,7 @@ /area/service/cafeteria/lunchroom) "aNb" = ( /obj/machinery/vending/sustenance{ - contraband = list(/obj/item/kitchen/knife = 6, /obj/item/reagent_containers/food/drinks/coffee = 12); + contraband = list(/obj/item/kitchen/knife=6,/obj/item/reagent_containers/food/drinks/coffee=12); desc = "A vending machine which vends food."; product_ads = "Sufficiently healthy." }, @@ -16988,6 +15854,10 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = 24 + }, /turf/open/floor/plasteel/dark, /area/ai_monitored/command/storage/eva) "aNu" = ( @@ -17092,6 +15962,10 @@ /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = 24 + }, /turf/open/floor/plasteel, /area/security/checkpoint/supply) "aNH" = ( @@ -17303,6 +16177,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/item/chisel, /turf/open/floor/plasteel, /area/commons/storage/art) "aOu" = ( @@ -18040,6 +16915,10 @@ /area/cargo/warehouse) "aQe" = ( /obj/effect/spawner/lootdrop/maintenance, +/obj/machinery/light_switch{ + pixel_x = -7; + pixel_y = -24 + }, /turf/open/floor/plasteel, /area/cargo/warehouse) "aQf" = ( @@ -19297,11 +18176,14 @@ /turf/open/floor/plasteel, /area/cargo/office) "aTe" = ( -/obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plating, +/obj/machinery/mineral/ore_redemption{ + input_dir = 4; + output_dir = 8 + }, +/turf/open/floor/plasteel, /area/cargo/office) "aTf" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -20624,7 +19506,7 @@ receive_ore_updates = 1 }, /obj/machinery/camera{ - c_tag = "Bar Access" + c_tag = "Service Hallway" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -20805,12 +19687,11 @@ /turf/open/floor/plasteel, /area/cargo/office) "aWv" = ( -/obj/machinery/door/firedoor, -/obj/machinery/mineral/ore_redemption{ - input_dir = 4; - output_dir = 8 +/obj/effect/turf_decal/tile/brown, +/obj/machinery/computer/piratepad_control/civilian{ + dir = 1 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel, /area/cargo/office) "aWw" = ( /obj/effect/turf_decal/tile/brown, @@ -21786,6 +20667,10 @@ /obj/effect/turf_decal/tile/brown{ dir = 4 }, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = 24 + }, /turf/open/floor/plasteel, /area/cargo/office) "aYs" = ( @@ -22379,10 +21264,10 @@ }, /area/hallway/secondary/entry) "aZA" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +/obj/effect/turf_decal/tile/blue{ dir = 4 }, -/obj/effect/turf_decal/tile/blue{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plasteel/white/corner{ @@ -22390,9 +21275,6 @@ }, /area/hallway/secondary/entry) "aZC" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, /obj/item/radio/intercom{ name = "Station Intercom (General)"; pixel_y = 26 @@ -22400,20 +21282,23 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/white/corner{ dir = 1 }, /area/hallway/secondary/entry) "aZD" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, /obj/machinery/airalarm{ pixel_y = 22 }, /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/white/corner{ dir = 1 }, @@ -22902,7 +21787,7 @@ req_access_txt = "10;13" }, /turf/open/floor/plating, -/area/ai_monitored/turret_protected/aisat_interior) +/area/command/bridge) "baI" = ( /obj/structure/cable{ icon_state = "0-8" @@ -22948,10 +21833,10 @@ /obj/machinery/light{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "baQ" = ( @@ -22977,6 +21862,10 @@ /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/machinery/light_switch{ + pixel_x = -26; + pixel_y = -26 + }, /turf/open/floor/plasteel, /area/security/checkpoint/customs) "baR" = ( @@ -23393,10 +22282,10 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bbU" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bbV" = ( @@ -23875,7 +22764,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bdb" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bdc" = ( @@ -24109,13 +22998,13 @@ /turf/open/floor/plasteel, /area/cargo/qm) "bdH" = ( -/obj/machinery/computer/bounty{ - dir = 8 - }, /obj/effect/turf_decal/tile/brown, /obj/effect/turf_decal/tile/brown{ dir = 4 }, +/obj/machinery/computer/bounty{ + dir = 8 + }, /turf/open/floor/plasteel, /area/cargo/qm) "bdI" = ( @@ -24205,14 +23094,14 @@ /turf/open/floor/plating, /area/hallway/secondary/entry) "bdW" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bdX" = ( /obj/machinery/door/firedoor, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plasteel, @@ -24666,10 +23555,10 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "beZ" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bfa" = ( @@ -25058,8 +23947,8 @@ /turf/open/floor/plating, /area/maintenance/department/cargo) "bfY" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bfZ" = ( @@ -25690,6 +24579,10 @@ /obj/effect/turf_decal/tile/brown{ dir = 8 }, +/obj/machinery/light_switch{ + pixel_x = -6; + pixel_y = -24 + }, /turf/open/floor/plasteel, /area/cargo/miningdock) "bht" = ( @@ -25757,8 +24650,8 @@ /obj/machinery/light{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bhF" = ( @@ -26136,10 +25029,10 @@ /turf/open/floor/plating, /area/maintenance/department/cargo) "biI" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "biJ" = ( @@ -26148,7 +25041,7 @@ id = "loungeshutters"; name = "privacy shutters" }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plating, @@ -26163,13 +25056,13 @@ dir = 1; pixel_y = -22 }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plasteel/grimy, /area/commons/lounge) "biL" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plasteel/grimy, @@ -26234,15 +25127,19 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "biR" = ( -/obj/machinery/light, -/obj/machinery/camera{ - c_tag = "Central Primary Hallway Genetics"; - dir = 1 - }, /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "biS" = ( @@ -26264,16 +25161,19 @@ /area/hallway/primary/central) "biW" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/airlock/maintenance{ - name = "Port Emergency Storage" +/obj/machinery/door/airlock/medical{ + name = "Paramedic's Office"; + req_access_txt = "5;6;12;64" }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plating, -/area/commons/storage/emergency/port) +/obj/effect/turf_decal/trimline/blue/filled, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/medical/paramedic) "biX" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall, -/area/commons/storage/emergency/port) +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/medical/paramedic) "biY" = ( /turf/closed/wall, /area/medical/morgue) @@ -26341,19 +25241,24 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "bjj" = ( -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, -/obj/structure/cable{ - icon_state = "2-8" - }, /obj/effect/turf_decal/tile/purple, /obj/effect/turf_decal/tile/purple{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/light, +/obj/machinery/camera{ + c_tag = "Central Primary Hallway Genetics"; + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "bjk" = ( @@ -26481,18 +25386,54 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/commons/storage/emergency/port) +"bjO" = ( +/obj/machinery/door/airlock/grunge{ + name = "Monastery Cemetary" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "bjP" = ( -/obj/machinery/space_heater, -/turf/open/floor/plating, -/area/commons/storage/emergency/port) +/obj/structure/table/glass, +/obj/item/flashlight/lamp{ + pixel_x = -2; + pixel_y = 11 + }, +/obj/effect/spawner/lootdrop/cig_packs{ + pixel_x = 9; + pixel_y = 7 + }, +/obj/item/folder/white, +/obj/item/pen/blue{ + pixel_x = 1; + pixel_y = -2 + }, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 9 + }, +/turf/open/floor/plasteel/dark, +/area/medical/paramedic) "bjQ" = ( /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "bjR" = ( -/obj/structure/plasticflaps/opaque, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating, -/area/commons/storage/emergency/port) +/obj/structure/closet/secure_closet/paramedic, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 5 + }, +/obj/machinery/camera{ + c_tag = "Paramedic Disbatch"; + dir = 8; + network = list("ss13","medbay") + }, +/obj/structure/sign/poster/official/help_others{ + pixel_x = 32 + }, +/turf/open/floor/plasteel/dark, +/area/medical/paramedic) "bjS" = ( /obj/machinery/airalarm/unlocked{ pixel_y = 23 @@ -26598,6 +25539,9 @@ /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/machinery/light_switch{ + pixel_y = 22 + }, /turf/open/floor/plasteel, /area/security/checkpoint/medical) "bkb" = ( @@ -26842,10 +25786,10 @@ /turf/open/space, /area/solars/starboard) "bkQ" = ( -/obj/machinery/vending/snack, /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/structure/closet/emcloset, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bkR" = ( @@ -26865,11 +25809,11 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bkT" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/structure/extinguisher_cabinet{ pixel_x = 27 }, /obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bkW" = ( @@ -26886,53 +25830,90 @@ /obj/structure/extinguisher_cabinet{ pixel_x = -28 }, -/turf/open/floor/plasteel/freezer, -/area/commons/storage/emergency/port) -"bkY" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel/freezer, -/area/commons/storage/emergency/port) -"bkZ" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/machinery/camera{ - c_tag = "Genetics Cloning Foyer"; - network = list("ss13","medbay") +/obj/machinery/space_heater, +/obj/machinery/airalarm{ + pixel_y = 22 }, /obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plating, +/area/commons/storage/emergency/port) +"bkY" = ( /obj/machinery/power/apc{ dir = 1; name = "Port Emergency Storage APC"; pixel_y = 23 }, /obj/structure/cable{ - icon_state = "0-2"; - pixel_y = 1 + icon_state = "0-2" }, -/turf/open/floor/plasteel/freezer, +/obj/machinery/camera{ + c_tag = "Genetics Cloning Foyer"; + network = list("ss13","medbay") + }, +/turf/open/floor/plating, +/area/commons/storage/emergency/port) +"bkZ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plating, /area/commons/storage/emergency/port) "bla" = ( -/obj/machinery/airalarm{ - pixel_y = 22 +/obj/machinery/light{ + dir = 1 }, -/turf/open/floor/plasteel/freezer, +/obj/item/cigbutt{ + pixel_x = 6; + pixel_y = -6 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/decal/cleanable/ash{ + pixel_x = -8; + pixel_y = -8 + }, +/turf/open/floor/plating, /area/commons/storage/emergency/port) "blb" = ( -/turf/open/floor/plating, -/area/commons/storage/emergency/port) -"blc" = ( -/obj/structure/window/reinforced{ - dir = 1; - pixel_y = 2 +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 9 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating, -/area/commons/storage/emergency/port) +/obj/machinery/power/apc{ + areastring = "/area/medical/paramedic"; + dir = 1; + name = "Paramedic Station APC"; + pixel_y = 25 + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel/dark, +/area/medical/paramedic) +"blc" = ( +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 4 + }, +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 23 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/obj/effect/landmark/start/paramedic, +/turf/open/floor/plasteel/dark, +/area/medical/paramedic) "bld" = ( /obj/structure/bodycontainer/morgue, /turf/open/floor/plasteel/dark, @@ -27467,6 +26448,9 @@ /obj/structure/cable{ icon_state = "2-4" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, /turf/open/floor/plating{ icon_state = "panelscorched" }, @@ -27476,6 +26460,9 @@ icon_state = "4-8" }, /obj/effect/spawner/lootdrop/maintenance, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plating{ icon_state = "platingdmg1" }, @@ -27494,63 +26481,72 @@ name = "Genetics Maintenance"; req_one_access_txt = "12;45;5;9" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plating, /area/maintenance/department/engine) "bmh" = ( /obj/structure/cable{ icon_state = "4-8" }, -/turf/open/floor/plasteel/freezer, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plating, /area/commons/storage/emergency/port) "bmi" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, /obj/structure/cable{ icon_state = "1-4" }, /obj/structure/cable{ icon_state = "4-8" }, -/turf/open/floor/plasteel/freezer, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plating, /area/commons/storage/emergency/port) "bmj" = ( -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ icon_state = "2-8" }, -/obj/structure/cable{ - icon_state = "1-8" +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 }, -/turf/open/floor/plasteel/freezer, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plating, /area/commons/storage/emergency/port) "bmk" = ( /obj/structure/table, /obj/item/crowbar, /obj/item/storage/toolbox/emergency, -/turf/open/floor/plasteel/freezer, +/turf/open/floor/plating, /area/commons/storage/emergency/port) "bml" = ( -/obj/structure/girder, -/turf/open/floor/plating, -/area/commons/storage/emergency/port) +/obj/machinery/computer/crew{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 10 + }, +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/vending/wallmed{ + pixel_y = -28 + }, +/obj/machinery/light_switch{ + pixel_x = -23 + }, +/turf/open/floor/plasteel/dark, +/area/medical/paramedic) "bmn" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Medbay Maintenance"; - req_access_txt = "5" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/turf/open/floor/plating, -/area/commons/storage/emergency/port) +/obj/effect/turf_decal/trimline/blue/filled/line, +/turf/open/floor/plasteel/dark, +/area/medical/paramedic) "bmp" = ( /obj/structure/bodycontainer/morgue, /obj/machinery/light/small{ @@ -27929,30 +26925,30 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bnp" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bnq" = ( /obj/item/beacon, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bnr" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bns" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bnt" = ( @@ -27962,69 +26958,36 @@ /obj/effect/landmark/start/assistant, /turf/open/floor/plasteel, /area/hallway/secondary/entry) -"bnu" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plating{ - icon_state = "platingdmg1" - }, -/area/maintenance/department/engine) "bnv" = ( /turf/closed/wall, /area/medical/genetics) "bnw" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/medical/glass{ - name = "Cloning"; - req_one_access_txt = "5;9" - }, /obj/structure/cable{ icon_state = "1-2" }, /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/mapping_helpers/airlock/unres, -/turf/open/floor/plasteel/freezer, -/area/commons/storage/emergency/port) -"bnx" = ( -/obj/structure/sign/poster/official/random{ - pixel_x = -32 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 - }, -/obj/structure/table, -/obj/item/clothing/gloves/color/latex/nitrile, -/obj/item/clothing/neck/stethoscope, -/obj/item/clothing/mask/surgical, -/obj/effect/turf_decal/tile/blue{ +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 +/obj/machinery/door/airlock/maintenance{ + name = "Medbay Maintenance"; + req_access_txt = "5" }, -/turf/open/floor/plasteel/white, -/area/medical/medbay/zone3) +/turf/open/floor/plating, +/area/commons/storage/emergency/port) +"bnx" = ( +/turf/closed/wall, +/area/medical/paramedic) "bny" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/firealarm{ dir = 8; pixel_x = 28 }, -/obj/item/kirbyplants{ - icon_state = "plant-11" - }, -/obj/machinery/light/small{ - dir = 1; - light_color = "#ffc1c1" - }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/medical/medbay/zone3) +/turf/closed/wall, +/area/medical/paramedic) "bnz" = ( /obj/structure/table, /obj/item/folder/white, @@ -28443,16 +27406,22 @@ /turf/open/floor/plasteel/white, /area/medical/genetics) "boA" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/chair{ - dir = 4 - }, /obj/effect/turf_decal/tile/blue{ dir = 1 }, /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/structure/table, +/obj/item/clothing/gloves/color/latex/nitrile, +/obj/item/clothing/neck/stethoscope, +/obj/item/clothing/mask/surgical, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "boC" = ( @@ -28893,6 +27862,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/department/engine) "bpv" = ( @@ -28975,6 +27945,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/structure/chair{ + dir = 4 + }, /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "bpE" = ( @@ -29613,8 +28586,8 @@ /obj/structure/cable{ icon_state = "0-2" }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/yellowsiding{ dir = 8 }, @@ -30302,8 +29275,8 @@ /obj/machinery/light{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/yellowsiding{ dir = 8 }, @@ -30527,7 +29500,8 @@ /obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ id_tag = "medbaybolts"; - name = "Medbay" + name = "Medbay"; + req_access_txt = "5" }, /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -30539,12 +29513,13 @@ /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/public/glass{ - id_tag = "medbaybolts"; - name = "Medbay" - }, /obj/effect/turf_decal/tile/blue, /obj/effect/mapping_helpers/airlock/unres, +/obj/machinery/door/airlock/public/glass{ + id_tag = "medbaybolts"; + name = "Medbay"; + req_access_txt = "5" + }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bsJ" = ( @@ -30646,6 +29621,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/posialert{ + pixel_x = -32 + }, /turf/open/floor/plasteel/dark, /area/science/robotics/lab) "bsX" = ( @@ -30703,6 +29681,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/item/cautery, /turf/open/floor/plasteel/white, /area/science/robotics/lab) "btb" = ( @@ -30967,10 +29946,10 @@ /obj/structure/cable{ icon_state = "1-4" }, -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel/yellowsiding{ dir = 8 }, @@ -30991,21 +29970,21 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plating, /area/maintenance/department/engine) "btQ" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 10 - }, /obj/structure/cable{ icon_state = "2-8" }, /obj/structure/cable{ icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, /turf/open/floor/plating, /area/maintenance/department/engine) "btR" = ( @@ -31517,16 +30496,19 @@ /obj/effect/turf_decal/tile/purple{ dir = 8 }, +/obj/machinery/light_switch{ + pixel_x = 24 + }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) "bva" = ( /turf/closed/wall, /area/maintenance/department/engine) "bvb" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/structure/cable{ icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/department/engine) "bvc" = ( @@ -32094,10 +31076,10 @@ /turf/open/floor/plating, /area/maintenance/department/engine) "bwt" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/structure/cable{ icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating{ icon_state = "platingdmg1" }, @@ -32222,6 +31204,10 @@ dir = 4 }, /obj/structure/disposalpipe/segment, +/obj/machinery/light_switch{ + dir = 8; + pixel_x = 24 + }, /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "bwE" = ( @@ -32238,7 +31224,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, -/obj/machinery/bloodbankgen, +/obj/structure/bed/roller, /turf/open/floor/plasteel/white, /area/medical/treatment_center) "bwG" = ( @@ -32890,10 +31876,10 @@ /turf/open/floor/plating, /area/maintenance/department/engine) "byc" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/structure/cable{ icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating{ icon_state = "panelscorched" }, @@ -33638,13 +32624,13 @@ /area/maintenance/department/engine) "bzD" = ( /obj/structure/chair/stool, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/structure/cable{ icon_state = "1-2" }, /obj/machinery/light/small{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating{ icon_state = "panelscorched" }, @@ -33748,9 +32734,6 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "bzP" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -33767,6 +32750,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/sleeper{ + dir = 4 + }, /turf/open/floor/plasteel, /area/medical/treatment_center) "bzQ" = ( @@ -33803,6 +32789,10 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = 24 + }, /turf/open/floor/plasteel/white, /area/medical/treatment_center) "bzU" = ( @@ -34177,11 +33167,11 @@ /turf/open/floor/plating, /area/hallway/secondary/entry) "bAM" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/structure/cable{ icon_state = "1-2" }, /obj/item/extinguisher, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating{ icon_state = "panelscorched" }, @@ -34976,9 +33966,6 @@ /turf/open/floor/plasteel, /area/medical/treatment_center) "bCj" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/effect/turf_decal/tile/blue{ dir = 1 }, @@ -34989,6 +33976,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/stasis{ + dir = 4 + }, /turf/open/floor/plasteel, /area/medical/treatment_center) "bCl" = ( @@ -35004,6 +33994,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/structure/bed/roller, /turf/open/floor/plasteel/white, /area/medical/treatment_center) "bCm" = ( @@ -35214,32 +34205,15 @@ /turf/open/floor/plating, /area/maintenance/department/engine) "bCA" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/light/small{ - dir = 1 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, +/obj/structure/loot_pile/maint, /turf/open/floor/plating, -/area/maintenance/department/engine) +/area/maintenance/department/crew_quarters/dorms) "bCB" = ( -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 }, /obj/structure/cable{ - icon_state = "4-8" + icon_state = "2-4" }, /turf/open/floor/plating, /area/maintenance/department/engine) @@ -35507,11 +34481,11 @@ /turf/open/space, /area/space/nearstation) "bDg" = ( -/obj/machinery/atmospherics/components/unary/tank/air, +/obj/machinery/portable_atmospherics/canister/oxygen, /turf/open/floor/plating, /area/maintenance/department/engine) "bDh" = ( -/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/machinery/atmospherics/components/unary/portables_connector/visible, /turf/open/floor/plating, /area/maintenance/department/engine) "bDi" = ( @@ -35519,10 +34493,10 @@ /area/maintenance/department/engine) "bDj" = ( /obj/item/trash/candy, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/structure/cable{ icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/department/engine) "bDk" = ( @@ -35675,11 +34649,28 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/item/kirbyplants{ + icon_state = "plant-16" + }, +/obj/machinery/light_switch{ + pixel_y = -22 + }, /turf/open/floor/plasteel/white, /area/command/heads_quarters/cmo) "bDy" = ( -/turf/closed/wall, -/area/medical/exam_room) +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/engine) "bDz" = ( /obj/structure/cable{ icon_state = "1-2" @@ -36034,22 +35025,15 @@ /turf/open/floor/plasteel/dark, /area/science/mixing) "bEj" = ( -/obj/machinery/atmospherics/pipe/manifold/general/hidden{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 }, /turf/open/floor/plating, /area/maintenance/department/engine) "bEk" = ( -/obj/machinery/atmospherics/pipe/manifold/general/hidden, /obj/machinery/meter, /obj/machinery/light/small, -/turf/open/floor/plating, -/area/maintenance/department/engine) -"bEl" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ - dir = 4; - name = "Air Out" - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plating, /area/maintenance/department/engine) "bEm" = ( @@ -36057,7 +35041,7 @@ name = "Atmospherics Maintenance"; req_access_txt = "12;24" }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plating, @@ -36072,7 +35056,7 @@ /obj/structure/cable{ icon_state = "1-4" }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 }, /turf/open/floor/plating, @@ -36316,97 +35300,45 @@ /turf/open/floor/plasteel/white, /area/command/heads_quarters/cmo) "bEH" = ( -/obj/item/kirbyplants{ - icon_state = "plant-16" +/obj/structure/loot_pile/maint, +/turf/open/floor/plating{ + icon_state = "platingdmg3" }, -/obj/machinery/light_switch{ - pixel_y = -22 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/command/heads_quarters/cmo) +/area/maintenance/department/security/brig) "bEI" = ( -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/structure/closet, -/obj/item/clothing/under/rank/medical/doctor/nurse, -/obj/item/clothing/head/nursehat, -/obj/effect/decal/cleanable/cobweb, -/obj/machinery/airalarm{ - pixel_y = 22 - }, -/obj/structure/sign/poster/official/no_erp{ - pixel_x = -32 - }, -/turf/open/floor/plasteel/dark, -/area/medical/exam_room) -"bEJ" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/light/small{ - dir = 1 - }, -/obj/machinery/vending/wallmed{ - pixel_y = 28 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/effect/landmark/blobstart, -/obj/item/melee/baton/cattleprod{ - preload_cell_type = /obj/item/stock_parts/cell/high - }, -/turf/open/floor/plasteel/dark, -/area/medical/exam_room) -"bEK" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/button/door{ - id = "CMOCell"; - name = "Door Bolt Control"; - normaldoorcontrol = 1; - pixel_y = 26; - specialfunctions = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/obj/effect/landmark/xeno_spawn, -/turf/open/floor/plasteel/dark, -/area/medical/exam_room) -"bEL" = ( -/obj/machinery/door/airlock/command{ - id_tag = "CMOCell"; - name = "Personal Examination Room"; - req_access_txt = "40" - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/medical/exam_room) -"bEM" = ( /obj/structure/cable{ icon_state = "1-2" }, -/obj/structure/disposalpipe/segment, -/obj/structure/cable{ - icon_state = "2-8" +/obj/structure/disposalpipe/segment{ + dir = 10 }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, +/obj/structure/cable{ + icon_state = "2-8" + }, /turf/open/floor/plating, /area/maintenance/department/engine) +"bEJ" = ( +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"bEK" = ( +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/department/cargo) +"bEL" = ( +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/department/engine) +"bEM" = ( +/obj/effect/landmark/blobstart, +/obj/structure/grille/broken, +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, +/area/maintenance/department/engine) "bEN" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/sign/poster/official/random{ @@ -36576,6 +35508,10 @@ /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = -24 + }, /turf/open/floor/plasteel, /area/security/checkpoint/science) "bEZ" = ( @@ -36801,19 +35737,14 @@ /turf/open/floor/plating, /area/maintenance/department/science) "bFE" = ( -/obj/docking_port/stationary{ - dwidth = 2; - height = 6; - id = "monastery_shuttle_asteroid"; - name = "monastery"; - width = 5 - }, -/turf/open/space, -/area/space/nearstation) +/obj/structure/reagent_dispensers/watertank, +/turf/open/floor/plating, +/area/maintenance/department/crew_quarters/dorms) "bFF" = ( -/obj/machinery/atmospherics/components/unary/tank/air{ +/obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, +/obj/effect/landmark/xeno_spawn, /turf/open/floor/plating, /area/maintenance/department/engine) "bFG" = ( @@ -36935,53 +35866,56 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = 28 + }, +/obj/machinery/light{ + dir = 4 + }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bFU" = ( /turf/closed/wall, /area/medical/surgery) "bFV" = ( -/obj/structure/table/glass, -/obj/item/flashlight/pen, -/obj/item/clothing/neck/stethoscope, -/obj/item/lipstick/black, -/obj/machinery/power/apc{ - dir = 8; - name = "Personal Examination Room APC"; - pixel_x = -25 +/obj/machinery/camera{ + c_tag = "Surgery"; + network = list("ss13","surgery") }, -/obj/structure/cable, -/obj/item/reagent_containers/pill/morphine, -/turf/open/floor/plasteel/dark, -/area/medical/exam_room) +/obj/structure/closet/secure_closet/medical2, +/turf/open/floor/plasteel/white/side, +/area/medical/surgery) "bFW" = ( -/obj/effect/decal/remains/human, -/obj/structure/chair/office/dark{ +/obj/structure/table, +/obj/item/clothing/suit/apron/surgical, +/obj/item/clothing/gloves/color/latex, +/obj/item/clothing/mask/surgical, +/obj/machinery/vending/wallmed{ + pixel_y = 29 + }, +/turf/open/floor/plasteel/white/side, +/area/medical/surgery) +"bFX" = ( +/obj/structure/table, +/obj/item/storage/backpack/duffelbag/med/surgery, +/obj/machinery/firealarm{ + pixel_y = 27 + }, +/turf/open/floor/plasteel/white/corner{ dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/dark, -/area/medical/exam_room) -"bFX" = ( -/obj/structure/bed, -/obj/item/bedsheet/cmo, -/obj/effect/decal/cleanable/blood/drip, -/obj/item/restraints/handcuffs, -/obj/item/clothing/mask/muzzle, -/obj/machinery/light_switch{ - pixel_y = -22 - }, -/turf/open/floor/plasteel/dark, -/area/medical/exam_room) +/area/medical/surgery) "bFY" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, /obj/structure/cable{ - icon_state = "1-2" + icon_state = "1-4" }, -/obj/structure/disposalpipe/segment, -/obj/structure/sign/departments/examroom{ - pixel_x = -32 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/department/engine) "bFZ" = ( @@ -37338,21 +36272,32 @@ /turf/open/floor/plating, /area/service/chapel/dock) "bGF" = ( -/obj/machinery/door/airlock/external{ - name = "Pod Docking Bay" +/obj/docking_port/stationary{ + dwidth = 2; + height = 6; + id = "monastery_shuttle_asteroid"; + name = "monastery"; + width = 5 }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plating, -/area/service/chapel/dock) +/turf/open/space, +/area/space/nearstation) "bGG" = ( -/obj/machinery/atmospherics/components/unary/outlet_injector/on, -/obj/structure/window/reinforced, -/obj/structure/window/reinforced{ +/obj/machinery/power/apc{ dir = 8; - layer = 2.9 + name = "Fore Primary Hallway APC"; + pixel_x = -25 }, -/turf/open/floor/plating/airless, -/area/service/chapel/dock) +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) "bGH" = ( /obj/structure/window/reinforced, /turf/open/space, @@ -37501,50 +36446,66 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bHa" = ( -/obj/machinery/light{ +/obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/firealarm{ - dir = 8; - pixel_x = 28 - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 +/obj/structure/cable{ + icon_state = "4-8" }, -/turf/open/floor/plasteel/white, -/area/medical/medbay/central) +/turf/open/floor/plating, +/area/maintenance/department/engine) "bHb" = ( /obj/machinery/newscaster/security_unit{ pixel_y = 32 }, -/obj/machinery/limbgrower, -/turf/open/floor/plasteel/freezer, +/obj/structure/bed{ + dir = 1 + }, +/obj/item/bedsheet/medical{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/turf/open/floor/plasteel/white, /area/medical/surgery) "bHc" = ( -/obj/machinery/computer/med_data, /obj/machinery/status_display/evac{ pixel_y = 32 }, -/turf/open/floor/plasteel/freezer, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#d1dfff" + }, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, /area/medical/surgery) "bHd" = ( -/obj/structure/table, -/obj/structure/bedsheetbin, -/obj/structure/extinguisher_cabinet{ - pixel_x = 24 - }, /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = 32 }, -/turf/open/floor/plasteel/freezer, -/area/medical/surgery) -"bHe" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall, +/obj/structure/closet/wardrobe/pjs, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, /area/medical/surgery) "bHf" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -37856,38 +36817,39 @@ /turf/open/floor/plasteel, /area/science/mixing) "bHI" = ( -/obj/structure/grille/broken, -/turf/open/space/basic, -/area/space/nearstation) +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plating, +/area/maintenance/department/cargo) "bHJ" = ( +/obj/machinery/door/airlock/external{ + name = "Pod Docking Bay" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plating, /area/service/chapel/dock) "bHK" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 - }, +/obj/item/cigbutt, /turf/open/floor/plating, -/area/service/chapel/dock) +/area/maintenance/department/cargo) "bHL" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 - }, -/turf/open/floor/plating, -/area/service/chapel/dock) -"bHM" = ( -/turf/closed/wall/r_wall, -/area/service/chapel/dock) -"bHN" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/on, /obj/structure/window/reinforced, /obj/structure/window/reinforced{ dir = 8; layer = 2.9 }, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) +/turf/open/floor/plating/airless, +/area/service/chapel/dock) +"bHM" = ( +/turf/closed/wall/r_wall, +/area/service/chapel/dock) +"bHN" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/vending/cola/random, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) "bHP" = ( /obj/effect/decal/cleanable/cobweb, /turf/open/floor/plasteel/dark, @@ -38080,6 +37042,10 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/structure/table/glass, +/obj/item/soap/nanotrasen, +/obj/item/clothing/neck/stethoscope, +/obj/item/gun/syringe/dart, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bIj" = ( @@ -38087,130 +37053,64 @@ /turf/open/floor/plating, /area/medical/surgery) "bIk" = ( -/turf/open/floor/plasteel/freezer, +/obj/structure/bed{ + dir = 1 + }, +/obj/item/bedsheet/medical{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/turf/open/floor/plasteel/white, /area/medical/surgery) "bIl" = ( -/obj/structure/chair/office/light{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/white/side{ + dir = 8 }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/turf/open/floor/plasteel/freezer, /area/medical/surgery) "bIm" = ( -/obj/machinery/camera{ - c_tag = "Medbay Recovery Room"; - dir = 8; - network = list("ss13","medbay") - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/turf/open/floor/plasteel/dark/side{ dir = 4 }, -/obj/item/radio/intercom{ - frequency = 1485; - name = "Station Intercom (Medbay)"; - pixel_x = 28 - }, -/turf/open/floor/plasteel/freezer, /area/medical/surgery) "bIn" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/structure/chair{ dir = 4 }, -/turf/closed/wall, +/turf/open/floor/plasteel/dark, /area/medical/surgery) "bIo" = ( -/obj/structure/closet/crate/freezer/blood, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/machinery/light_switch{ - pixel_x = -22 - }, -/turf/open/floor/plasteel/white, +/obj/machinery/limbgrower, +/turf/open/floor/plasteel/white/corner, /area/medical/surgery) "bIp" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/machinery/iv_drip, +/turf/open/floor/plasteel/white/side{ dir = 4 }, -/obj/structure/sink{ - pixel_y = 28 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/structure/closet/crate/freezer/surplus_limbs, -/obj/item/reagent_containers/glass/beaker/synthflesh, -/turf/open/floor/plasteel/white, /area/medical/surgery) "bIq" = ( -/obj/machinery/light{ - dir = 1 +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel/white/side{ + dir = 9 }, -/obj/machinery/camera{ - c_tag = "Surgery"; - network = list("ss13","surgery") - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/airalarm{ - pixel_y = 22 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/white, /area/medical/surgery) "bIr" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/vending/wallmed{ - pixel_y = 28 - }, -/obj/effect/turf_decal/tile/blue{ +/turf/open/floor/plasteel/white/side{ dir = 1 }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/white, /area/medical/surgery) "bIs" = ( -/obj/structure/closet/secure_closet/medical2, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, -/obj/effect/turf_decal/tile/blue{ +/obj/structure/table/optable, +/obj/machinery/light/small, +/turf/open/floor/plasteel/white/corner{ dir = 1 }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, /area/medical/surgery) "bIt" = ( /obj/structure/disposalpipe/segment{ @@ -38346,6 +37246,10 @@ /obj/structure/cable{ icon_state = "0-8" }, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = -24 + }, /turf/open/floor/engine, /area/science/storage) "bII" = ( @@ -38426,50 +37330,36 @@ /turf/open/space/basic, /area/space/nearstation) "bIU" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/closed/wall, -/area/service/chapel/dock) +/obj/machinery/vending/snack/random, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) "bIV" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/structure/sign/warning/vacuum/external, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, /turf/open/floor/plating, /area/service/chapel/dock) "bIW" = ( -/obj/machinery/computer/shuttle/monastery_shuttle, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plating, /area/service/chapel/dock) "bIX" = ( -/obj/machinery/atmospherics/components/unary/tank/air, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/chapel/dock) +/obj/structure/grille/broken, +/turf/open/space/basic, +/area/space/nearstation) "bIY" = ( +/obj/structure/window/reinforced, /obj/structure/window/reinforced{ dir = 8; layer = 2.9 }, +/obj/structure/lattice, /turf/open/space/basic, -/area/space) +/area/space/nearstation) "bIZ" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -38656,109 +37546,100 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bJq" = ( -/obj/machinery/door/airlock/medical/glass{ - name = "Recovery Room" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 +/obj/machinery/door/airlock/medical/glass{ + name = "Recovery Room" }, /obj/machinery/door/firedoor, -/turf/open/floor/plasteel/freezer, +/turf/open/floor/plasteel/white, /area/medical/surgery) "bJr" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/freezer, -/area/medical/surgery) -"bJs" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ dir = 1 }, -/turf/open/floor/plasteel/freezer, +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bJs" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, /area/medical/surgery) "bJt" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/medical{ - name = "Surgery"; - req_access_txt = "45" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/turf/open/floor/plasteel/freezer, +/turf/open/floor/plasteel/dark, /area/medical/surgery) "bJu" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 }, -/obj/effect/turf_decal/tile/blue{ - dir = 1 +/obj/machinery/door/airlock/medical/glass{ + name = "Operating Theatre"; + req_access_txt = "45" }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, /area/medical/surgery) "bJv" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 + dir = 4 + }, +/turf/open/floor/plasteel/white/side{ + dir = 4 }, -/turf/open/floor/plasteel/white, /area/medical/surgery) "bJw" = ( -/obj/machinery/computer/operating, -/turf/open/floor/plasteel/white, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, /area/medical/surgery) "bJx" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/smartfridge/organ/preloaded, /turf/open/floor/plasteel/white, /area/medical/surgery) "bJy" = ( -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 8 - }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ +/obj/structure/closet/crate/freezer/surplus_limbs, +/obj/item/reagent_containers/glass/beaker/synthflesh, +/turf/open/floor/plasteel/white/side{ dir = 4 }, -/turf/open/floor/plasteel/white, /area/medical/surgery) "bJz" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Surgery Maintenance"; - req_access_txt = "45" +/obj/effect/landmark/start/medical_doctor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 }, -/obj/structure/cable{ - icon_state = "4-8" +/obj/machinery/holopad, +/turf/open/floor/plasteel/dark/side{ + dir = 4 }, +/area/medical/surgery) +"bJA" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plating, -/area/maintenance/department/engine) -"bJA" = ( -/obj/structure/cable{ - icon_state = "1-2" +/obj/machinery/iv_drip, +/turf/open/floor/plasteel/white/side{ + dir = 4 }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 - }, -/turf/open/floor/plating, -/area/maintenance/department/engine) +/area/medical/surgery) "bJB" = ( /obj/structure/cable{ icon_state = "1-2" @@ -38984,44 +37865,58 @@ /turf/open/space/basic, /area/space/nearstation) "bKa" = ( -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -22 +/obj/machinery/door/airlock/external{ + name = "Pod Docking Bay" }, -/turf/open/floor/plasteel/dark, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/turf/open/floor/plating, /area/service/chapel/dock) "bKb" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/sign/warning/vacuum/external, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plating, /area/service/chapel/dock) "bKc" = ( -/obj/structure/cable{ - icon_state = "4-8" +/obj/machinery/computer/shuttle/monastery_shuttle, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 }, /turf/open/floor/plasteel/dark, /area/service/chapel/dock) "bKd" = ( -/obj/machinery/power/apc{ - dir = 4; - name = "Monastery Docking Bay APC"; - pixel_x = 24 +/obj/machinery/atmospherics/components/unary/tank/air, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 }, -/obj/structure/cable{ - icon_state = "0-8" +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark, /area/service/chapel/dock) "bKe" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plasteel/white{ - heat_capacity = 1e+006 +/obj/structure/lattice, +/obj/structure/window/reinforced{ + dir = 8; + layer = 2.9 }, -/area/service/chapel/dock) +/turf/open/space/basic, +/area/space/nearstation) "bKf" = ( +/obj/structure/chair, /turf/open/floor/plasteel/white{ heat_capacity = 1e+006 }, @@ -39152,6 +38047,7 @@ /obj/machinery/light{ dir = 1 }, +/obj/effect/landmark/xeno_spawn, /turf/open/floor/plasteel/freezer, /area/medical/medbay/central) "bKx" = ( @@ -39194,52 +38090,61 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, -/turf/open/floor/plasteel/white, -/area/medical/medbay/central) -"bKB" = ( -/obj/structure/bed/roller, -/obj/machinery/iv_drip, -/turf/open/floor/plasteel/freezer, -/area/medical/surgery) -"bKC" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/freezer, -/area/medical/surgery) -"bKD" = ( -/obj/structure/bed, -/turf/open/floor/plasteel/freezer, -/area/medical/surgery) -"bKE" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue{ +/obj/vehicle/ridden/wheelchair/motorized{ dir = 8 }, /turf/open/floor/plasteel/white, -/area/medical/surgery) -"bKF" = ( -/obj/structure/table/optable, -/turf/open/floor/plasteel/white, -/area/medical/surgery) -"bKG" = ( -/obj/machinery/power/apc{ - dir = 4; - name = "Surgery APC"; - pixel_x = 24 +/area/medical/medbay/central) +"bKB" = ( +/obj/structure/table, +/obj/structure/bedsheetbin, +/obj/effect/turf_decal/tile/blue{ + dir = 8 }, -/obj/structure/cable, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ +/obj/effect/turf_decal/tile/blue{ dir = 1 }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ +/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bKC" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, -/turf/open/floor/plasteel/white, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, +/area/medical/surgery) +"bKD" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/medical/surgery) +"bKE" = ( +/obj/effect/spawner/structure/window, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/medical/surgery) +"bKF" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel/white/side{ + dir = 10 + }, +/area/medical/surgery) +"bKG" = ( +/obj/structure/table/optable, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel/white/corner{ + dir = 8 + }, /area/medical/surgery) "bKH" = ( /obj/structure/cable{ @@ -39492,52 +38397,40 @@ /turf/open/floor/plating, /area/science/mixing) "bLn" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/structure/extinguisher_cabinet{ + pixel_x = -24 + }, /turf/open/floor/plasteel/dark, /area/service/chapel/dock) "bLo" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ - icon_state = "1-2" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 + icon_state = "2-4" }, /turf/open/floor/plasteel/dark, /area/service/chapel/dock) "bLp" = ( -/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plasteel/dark, /area/service/chapel/dock) "bLq" = ( -/obj/machinery/door/airlock/grunge{ - name = "Monastery Transit" +/obj/machinery/power/apc{ + dir = 4; + name = "Monastery Docking Bay APC"; + pixel_y = 24 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/structure/cable{ + icon_state = "0-8" }, /turf/open/floor/plasteel/dark, /area/service/chapel/dock) "bLr" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, /turf/open/floor/plasteel/white{ heat_capacity = 1e+006 }, @@ -39640,6 +38533,10 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, /turf/open/floor/plasteel/freezer, /area/medical/medbay/central) "bLH" = ( @@ -39678,59 +38575,45 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bLL" = ( /obj/machinery/light, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 +/obj/structure/extinguisher_cabinet{ + pixel_y = -32 }, -/turf/open/floor/plasteel/freezer, -/area/medical/surgery) -"bLM" = ( -/obj/structure/table, -/obj/item/clothing/gloves/color/latex, -/obj/item/clothing/mask/surgical, -/obj/item/clothing/suit/apron/surgical, -/obj/effect/turf_decal/tile/blue{ - dir = 1 +/obj/structure/chair/office/light{ + dir = 8 }, /obj/effect/turf_decal/tile/blue{ dir = 8 }, -/obj/machinery/firealarm{ - dir = 4; - pixel_x = -26 +/turf/open/floor/plasteel/white/side{ + dir = 8 }, -/turf/open/floor/plasteel/white, +/area/medical/surgery) +"bLM" = ( +/turf/open/floor/plasteel/white/side, /area/medical/surgery) "bLN" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/turf/open/floor/plasteel/white, -/area/medical/surgery) -"bLO" = ( -/obj/effect/landmark/start/medical_doctor, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/structure/closet/crate/freezer/blood, +/turf/open/floor/plasteel/white/side{ dir = 4 }, -/turf/open/floor/plasteel/white, /area/medical/surgery) "bLP" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, /turf/open/floor/plasteel/white, /area/medical/surgery) "bLQ" = ( -/obj/structure/table, -/obj/item/surgical_drapes, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 +/obj/machinery/computer/operating{ + dir = 8 + }, +/turf/open/floor/plasteel/white/side{ + dir = 8 }, -/turf/open/floor/plasteel/white, /area/medical/surgery) "bLR" = ( /obj/machinery/vending/cigarette, @@ -39908,7 +38791,7 @@ input_tag = "mix_in"; name = "Gas Mix Tank Control"; output_tag = "mix_in"; - sensors = list("mix_sensor" = "Tank") + sensors = list("mix_sensor"="Tank") }, /obj/effect/turf_decal/tile/yellow, /obj/effect/turf_decal/tile/yellow{ @@ -39986,9 +38869,6 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 8 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -39999,12 +38879,12 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/service/chapel/dock) "bMt" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -40012,39 +38892,27 @@ /obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, /turf/open/floor/plasteel/dark, /area/service/chapel/dock) "bMu" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel/dark, /area/service/chapel/dock) "bMv" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/closed/wall, -/area/service/chapel/dock) -"bMw" = ( -/obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/white{ - heat_capacity = 1e+006 +/obj/effect/turf_decal/stripes/corner, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 }, +/turf/open/floor/plasteel/dark, /area/service/chapel/dock) "bMx" = ( /obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 - }, /turf/open/floor/plasteel/white{ heat_capacity = 1e+006 }, @@ -40141,9 +39009,6 @@ /turf/open/floor/plasteel/white, /area/medical/virology) "bMK" = ( -/obj/item/soap/nanotrasen, -/obj/item/clothing/neck/stethoscope, -/obj/structure/table/glass, /obj/effect/turf_decal/tile/blue{ dir = 1 }, @@ -40151,104 +39016,63 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, -/obj/item/gun/syringe/dart, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bMM" = ( -/obj/structure/closet/l3closet, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 +/obj/machinery/door/window/southleft{ + base_state = "right"; + dir = 1; + icon_state = "right"; + name = "Medbay Delivery"; + req_access_txt = "28" }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 +/obj/effect/turf_decal/delivery, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=2"; + dir = 4; + freq = 1400; + location = "Medbay" }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bMN" = ( -/obj/structure/table, -/obj/item/hemostat, -/obj/item/stack/medical/gauze, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, -/area/medical/surgery) +/obj/structure/loot_pile/maint, +/turf/open/floor/plating, +/area/maintenance/department/science) "bMO" = ( -/obj/structure/table, -/obj/item/surgicaldrill, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ +/obj/machinery/bloodbankgen, +/turf/open/floor/plasteel/white/corner{ dir = 4 }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, /area/medical/surgery) "bMP" = ( -/obj/structure/table, -/obj/item/scalpel{ - pixel_y = 12 - }, -/obj/item/circular_saw, -/obj/machinery/light, -/obj/effect/turf_decal/tile/blue{ +/obj/structure/closet/secure_closet/medical2, +/turf/open/floor/plasteel/white/side{ dir = 1 }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, /area/medical/surgery) "bMQ" = ( /obj/structure/table, -/obj/item/cautery{ - pixel_x = 4 +/obj/item/clothing/suit/apron/surgical, +/obj/item/clothing/gloves/color/latex, +/obj/item/clothing/mask/surgical, +/obj/machinery/vending/wallmed{ + pixel_y = -29 }, -/obj/item/razor{ - pixel_y = 5 - }, -/obj/effect/turf_decal/tile/blue{ +/turf/open/floor/plasteel/white/side{ dir = 1 }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, /area/medical/surgery) "bMR" = ( /obj/structure/table, -/obj/item/retractor, -/obj/effect/turf_decal/tile/blue{ +/obj/item/storage/backpack/duffelbag/med/surgery, +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -26 + }, +/turf/open/floor/plasteel/white/corner{ dir = 1 }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, /area/medical/surgery) "bMS" = ( /obj/structure/cable{ @@ -40454,12 +39278,6 @@ /turf/open/floor/plating, /area/service/chapel/asteroid/monastery) "bNt" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/obj/structure/extinguisher_cabinet{ - pixel_x = -24 - }, /obj/machinery/light/small, /obj/machinery/camera{ c_tag = "Monastery Dock"; @@ -40476,21 +39294,18 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/table/wood, +/obj/item/clothing/under/misc/burial, /turf/open/floor/plasteel/dark, /area/service/chapel/dock) "bNu" = ( /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 4 - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/service/chapel/dock) "bNv" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, /obj/item/radio/intercom{ name = "Station Intercom (General)"; pixel_x = 27 @@ -40506,6 +39321,8 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/table/wood, +/obj/item/reagent_containers/food/snacks/grown/poppy, /turf/open/floor/plasteel/dark, /area/service/chapel/dock) "bNw" = ( @@ -40544,14 +39361,26 @@ /obj/structure/lattice/catwalk, /turf/open/space, /area/space/nearstation) -"bNE" = ( -/obj/machinery/light/small{ +"bNC" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/turf/open/floor/plating{ - icon_state = "panelscorched" +/turf/open/floor/plasteel/dark, +/area/service/library) +"bNE" = ( +/obj/structure/chair/office/dark{ + dir = 4 }, -/area/maintenance/department/chapel/monastery) +/turf/open/floor/carpet, +/area/command/heads_quarters/hos) "bNF" = ( /obj/item/stack/medical/suture, /turf/open/floor/plasteel/dark, @@ -40669,12 +39498,10 @@ /area/maintenance/department/engine) "bNV" = ( /obj/item/wrench/medical, +/obj/effect/decal/cleanable/generic, /turf/open/floor/plating, /area/maintenance/department/engine) "bNW" = ( -/obj/machinery/light/small{ - dir = 1 - }, /obj/machinery/space_heater, /turf/open/floor/plating{ icon_state = "platingdmg3" @@ -40692,8 +39519,8 @@ icon_state = "1-4" }, /obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 }, /turf/open/floor/plating, /area/maintenance/department/engine) @@ -40905,19 +39732,12 @@ /turf/open/floor/plasteel/dark, /area/service/chapel/dock) "bOy" = ( -/obj/effect/turf_decal/tile/neutral{ +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/chair{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/dock) "bOz" = ( @@ -41171,6 +39991,12 @@ }, /turf/open/floor/plating, /area/science/mixing) +"bPm" = ( +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) "bPn" = ( /obj/machinery/door/airlock/grunge{ name = "Chapel" @@ -41309,7 +40135,7 @@ req_access_txt = "23" }, /turf/open/floor/plating, -/area/engineering/storage/tech) +/area/maintenance/department/engine) "bPG" = ( /obj/machinery/light{ dir = 8 @@ -41379,6 +40205,10 @@ /obj/structure/disposalpipe/sorting/mail{ sortType = 6 }, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = 24 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "bPP" = ( @@ -41449,7 +40279,7 @@ input_tag = "n2o_in"; name = "Nitrous Oxide Supply Control"; output_tag = "n2o_out"; - sensors = list("n2o_sensor" = "Tank") + sensors = list("n2o_sensor"="Tank") }, /obj/effect/turf_decal/tile/yellow, /obj/effect/turf_decal/tile/yellow{ @@ -41798,6 +40628,9 @@ dir = 4 }, /obj/effect/turf_decal/tile/yellow, +/obj/machinery/light{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engineering/atmos) "bQI" = ( @@ -42835,7 +41668,7 @@ input_tag = "tox_in"; name = "Plasma Supply Control"; output_tag = "tox_out"; - sensors = list("tox_sensor" = "Tank") + sensors = list("tox_sensor"="Tank") }, /obj/effect/turf_decal/tile/yellow, /obj/effect/turf_decal/tile/yellow{ @@ -43421,13 +42254,13 @@ /turf/open/floor/plasteel, /area/security/checkpoint/engineering) "bUj" = ( -/obj/machinery/computer/secure_data, /obj/effect/turf_decal/tile/red{ dir = 1 }, /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/machinery/computer/security, /turf/open/floor/plasteel, /area/security/checkpoint/engineering) "bUk" = ( @@ -43788,6 +42621,10 @@ /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/machinery/light_switch{ + pixel_x = -24; + pixel_y = -13 + }, /turf/open/floor/plasteel, /area/security/checkpoint/engineering) "bUW" = ( @@ -44077,7 +42914,7 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel, /area/command/heads_quarters/ce) "bVE" = ( @@ -44347,8 +43184,8 @@ /turf/open/floor/plating, /area/maintenance/department/engine) "bWl" = ( -/obj/structure/disposalpipe/segment{ - dir = 9 +/obj/structure/disposalpipe/junction/yjunction{ + dir = 8 }, /turf/open/floor/plating, /area/maintenance/department/engine) @@ -45059,6 +43896,7 @@ /area/service/chapel/asteroid/monastery) "bXS" = ( /obj/structure/grille/broken, +/obj/structure/loot_pile/maint, /turf/open/floor/plating{ icon_state = "platingdmg1" }, @@ -45747,8 +44585,18 @@ /turf/open/floor/carpet, /area/service/chapel/main/monastery) "bZo" = ( -/turf/open/floor/carpet, -/area/service/chapel/main/monastery) +/obj/machinery/washing_machine, +/obj/item/radio/intercom{ + dir = 4; + name = "Station Intercom (General)"; + pixel_x = -31 + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"bZp" = ( +/obj/structure/closet/emcloset, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "bZr" = ( /obj/item/trash/tray, /obj/structure/disposalpipe/segment{ @@ -45974,7 +44822,10 @@ /turf/open/floor/engine, /area/maintenance/disposal/incinerator) "bZV" = ( -/turf/closed/wall, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, /area/hallway/primary/fore) "bZY" = ( /turf/closed/wall, @@ -46226,8 +45077,9 @@ /turf/open/floor/engine, /area/maintenance/disposal/incinerator) "caS" = ( -/turf/closed/wall, -/area/service/chapel/asteroid/monastery) +/obj/machinery/light/small, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "caT" = ( /obj/structure/grille, /obj/structure/window/reinforced/tinted/fulltile, @@ -46526,6 +45378,9 @@ "cbT" = ( /obj/item/shovel, /obj/effect/landmark/xeno_spawn, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, /turf/open/floor/plating, /area/maintenance/department/engine) "cbV" = ( @@ -46596,6 +45451,16 @@ /obj/structure/sign/warning/nosmoking, /turf/closed/wall/r_wall, /area/engineering/main) +"ccg" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/button/massdriver{ + id = "chapelgun"; + pixel_x = 28 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "cci" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/light{ @@ -46898,6 +45763,7 @@ "cdE" = ( /obj/structure/chair, /obj/item/cigbutt, +/obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/maintenance/department/engine) "cdI" = ( @@ -46969,6 +45835,11 @@ }, /turf/open/floor/plating, /area/engineering/main) +"cdV" = ( +/obj/structure/window/reinforced/fulltile, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, +/area/service/library/lounge) "cdW" = ( /obj/structure/reflector/box/anchored, /turf/open/floor/plasteel/dark, @@ -47140,6 +46011,12 @@ }, /turf/open/floor/plasteel/dark, /area/service/chapel/office) +"ceD" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/structure/cable, +/turf/open/floor/plating, +/area/security/brig) "ceE" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, @@ -47209,10 +46086,7 @@ /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) "ceQ" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/carpet, /area/service/chapel/main/monastery) "ceT" = ( /obj/effect/turf_decal/stripes/line, @@ -48123,17 +46997,26 @@ /turf/open/floor/engine, /area/engineering/supermatter) "ciJ" = ( -/obj/structure/closet/emcloset, -/obj/effect/decal/cleanable/cobweb, -/obj/effect/decal/cleanable/blood/old, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) +/obj/structure/bed, +/obj/item/bedsheet, +/obj/machinery/button/door{ + id = "mainthideout"; + name = "Door Bolt Control"; + normaldoorcontrol = 1; + pixel_x = 25; + specialfunctions = 4 + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "ciK" = ( -/obj/structure/table, -/obj/item/crowbar, -/obj/item/clothing/mask/gas, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) +/obj/machinery/atmospherics/components/trinary/mixer/flipped{ + dir = 1; + node1_concentration = 0.2; + node2_concentration = 0.8; + on = 1 + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "ciN" = ( /obj/structure/closet/crate/bin, /turf/open/floor/plasteel/dark, @@ -48211,38 +47094,38 @@ /turf/open/floor/plasteel/showroomfloor, /area/service/chapel/main/monastery) "cjf" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) +/obj/machinery/atmospherics/pipe/manifold/general/hidden, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "cjg" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + dir = 9 + }, +/obj/machinery/meter, +/obj/machinery/light/small{ dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "cjj" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, +/obj/structure/table/wood, +/obj/item/reagent_containers/food/snacks/grown/poppy, +/obj/item/reagent_containers/food/snacks/grown/harebell, /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) "cjk" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-4" }, /turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) +/area/security/processing/cremation) "cjl" = ( -/obj/machinery/door/airlock/grunge{ - name = "Monastery Cemetary" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +/obj/structure/chair/wood/normal, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 }, /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) @@ -48309,163 +47192,132 @@ /turf/open/space/basic, /area/space) "cjC" = ( -/obj/structure/sign/warning/vacuum/external{ - pixel_y = 32 - }, -/obj/machinery/light/small{ +/obj/item/clothing/gloves/color/latex, +/obj/item/clothing/mask/surgical, +/obj/item/reagent_containers/spray/cleaner, +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/red{ dir = 1 }, -/turf/open/floor/plating, -/area/service/chapel/main/monastery) +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/security/brig) "cjH" = ( -/obj/machinery/door/airlock/grunge{ - name = "Chapel Garden" +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ + dir = 8 }, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/brig) "cjO" = ( -/obj/effect/decal/cleanable/cobweb{ - icon_state = "cobweb2" +/obj/machinery/power/apc{ + dir = 1; + name = "Monastery Maintenance APC"; + pixel_y = 23 }, -/obj/item/stack/sheet/glass/fifty{ - layer = 4 +/obj/structure/cable{ + icon_state = "0-8" }, -/obj/item/stack/sheet/metal{ - amount = 20; - layer = 3.1 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 }, /turf/open/floor/plating, /area/maintenance/department/chapel/monastery) "cjP" = ( -/obj/item/kirbyplants{ - icon_state = "plant-22" +/obj/machinery/light/small{ + dir = 1 }, -/obj/item/radio/intercom{ - name = "Station Intercom (General)"; - pixel_y = 26 - }, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "cjQ" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/carpet, +/obj/structure/bookcase/random/nonfiction, +/turf/open/floor/plasteel/dark, /area/service/library) -"cjR" = ( -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/carpet, -/area/service/library/lounge) "cjV" = ( /obj/machinery/camera/preset/toxins, /turf/open/floor/plating/asteroid/airless, /area/asteroid/nearstation/bomb_site) "cjZ" = ( -/obj/structure/table, -/obj/item/storage/crayons, -/obj/item/wrench, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) +/obj/machinery/computer/secure_data, +/turf/open/floor/plasteel, +/area/security/office) "cka" = ( -/obj/structure/chair{ +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, +/obj/machinery/light_switch{ + pixel_y = -24 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, /turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) +/area/command/heads_quarters/hos) "ckb" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/carpet, -/area/service/chapel/main/monastery) -"ckc" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/obj/machinery/door/window/eastleft{ + dir = 1; + name = "Coffin Storage"; + req_one_access_txt = "22" }, /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) "ckd" = ( -/obj/machinery/light/small{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) -"cke" = ( -/obj/machinery/power/smes{ - charge = 5e+006 - }, -/obj/structure/cable, -/obj/structure/cable{ - icon_state = "0-2" - }, -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) -"ckf" = ( -/obj/machinery/power/terminal{ - dir = 8 - }, -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) -"ckg" = ( -/obj/item/wrench, -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) -"ckh" = ( -/obj/item/stack/cable_coil, -/obj/item/stack/cable_coil, -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) -"cki" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ +/obj/machinery/door/window/eastleft{ + base_state = "right"; dir = 1; - name = "Air Out" + icon_state = "right"; + name = "Coffin Storage"; + req_one_access_txt = "22" }, -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) -"ckj" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) -"ckk" = ( -/obj/structure/extinguisher_cabinet{ +/obj/machinery/airalarm{ + dir = 8; pixel_x = 24 }, -/obj/item/stack/rods/fifty, -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) -"ckl" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/obj/machinery/photocopier, /turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"ckm" = ( +/area/service/chapel/main/monastery) +"ckf" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/keycard_auth{ + pixel_y = -24 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hos) +"cko" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/carpet, /area/service/library) -"cko" = ( -/obj/structure/bookcase/random/religion, -/turf/open/floor/plasteel/dark, -/area/service/library) "ckp" = ( -/obj/structure/bookcase/random/religion, -/obj/effect/decal/cleanable/cobweb{ - icon_state = "cobweb2" - }, +/obj/structure/closet/crate/bin, /turf/open/floor/plasteel/dark, /area/service/library/lounge) "ckt" = ( @@ -48474,102 +47326,91 @@ /area/asteroid/nearstation/bomb_site) "cku" = ( /obj/structure/chair/wood/normal, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/carpet, +/turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) "ckv" = ( -/obj/machinery/mass_driver{ - id = "chapelgun" - }, -/obj/machinery/door/window/eastleft{ - dir = 8; - name = "Mass Driver" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/item/flashlight/lantern, /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) "ckw" = ( -/obj/machinery/mass_driver{ - id = "chapelgun" +/obj/structure/cable{ + icon_state = "4-8" }, -/obj/structure/window/reinforced{ - dir = 4; - layer = 2.9 +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -26 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) -"cky" = ( -/obj/machinery/power/smes{ - charge = 5e+006 - }, -/obj/structure/cable, -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) -"ckz" = ( -/obj/machinery/atmospherics/pipe/simple/general/hidden{ - dir = 6 - }, -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) -"ckA" = ( -/obj/machinery/atmospherics/pipe/manifold/general/hidden{ +/obj/effect/turf_decal/tile/red{ dir = 1 }, -/obj/machinery/meter, -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hos) +"cky" = ( +/obj/item/clothing/under/misc/burial, +/obj/item/clothing/under/misc/burial, +/obj/item/clothing/under/misc/burial, +/obj/item/clothing/under/misc/burial, +/obj/structure/table/wood, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "ckB" = ( -/obj/machinery/atmospherics/pipe/manifold/general/hidden{ +/obj/effect/spawner/structure/window/reinforced, +/turf/closed/wall, +/area/maintenance/fore) +"ckD" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/camera{ + c_tag = "Head of Security's Office"; + dir = 1 + }, +/obj/item/radio/intercom{ + dir = 4; + name = "Station Intercom (General)"; + pixel_y = -27 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/command/heads_quarters/hos) +"ckE" = ( +/obj/structure/grille/broken, +/obj/structure/disposalpipe/segment{ dir = 4 }, /turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) -"ckC" = ( -/obj/item/extinguisher, +/area/maintenance/department/engine) +"ckF" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, /turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) -"ckD" = ( +/area/maintenance/department/engine) +"ckG" = ( /obj/structure/chair/wood/normal, /obj/machinery/firealarm{ dir = 4; pixel_x = -28 }, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"ckE" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 +/obj/machinery/camera{ + c_tag = "Monastery Library"; + dir = 4; + network = list("ss13","monastery") }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) -"ckF" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/carpet, -/area/service/library/lounge) -"ckG" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ +/obj/machinery/light/small{ dir = 8 }, /turf/open/floor/plasteel/dark, @@ -48578,8 +47419,8 @@ /turf/open/floor/plasteel/dark, /area/service/library) "ckI" = ( -/obj/machinery/light/small{ - dir = 4 +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 }, /turf/open/floor/plasteel/dark, /area/service/library/lounge) @@ -48595,114 +47436,98 @@ /turf/open/floor/plating/airless, /area/asteroid/nearstation/bomb_site) "ckM" = ( -/obj/structure/window/reinforced{ - dir = 8 +/obj/structure/cable{ + icon_state = "0-8" }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ +/obj/machinery/power/apc{ + name = "Head of Security's Office APC"; + pixel_y = -24 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/turf_decal/tile/red{ dir = 1 }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, /turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) +/area/command/heads_quarters/hos) "ckN" = ( +/obj/machinery/door/airlock/abandoned{ + id_tag = "mainthideout"; + name = "Hideout" + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"ckQ" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Monastery Maintenance"; + req_one_access_txt = "22;24;10;11;37" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) +"ckU" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/machinery/libraryscanner, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) +"ckV" = ( +/obj/effect/landmark/barthpot, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/carpet, +/area/service/library/lounge) +"ckW" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/closed/wall, +/area/maintenance/department/engine) +"ckX" = ( +/obj/structure/table/wood, +/obj/machinery/computer/libraryconsole, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) +"clb" = ( +/obj/structure/window/reinforced{ + dir = 1; + pixel_y = 1 + }, /obj/structure/window/reinforced{ dir = 4; layer = 2.9 }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) -"ckO" = ( -/obj/structure/closet/emcloset, -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) -"ckP" = ( -/obj/machinery/atmospherics/components/unary/tank/air{ - dir = 1 - }, -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) -"ckQ" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall/mineral/iron, -/area/maintenance/department/chapel/monastery) -"ckR" = ( -/obj/structure/reagent_dispensers/watertank, -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) -"ckS" = ( -/obj/structure/table/wood, -/obj/item/folder/yellow, -/obj/item/pen, -/obj/machinery/camera{ - c_tag = "Monastery Library"; - dir = 4; - network = list("ss13","monastery") - }, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"ckT" = ( -/obj/machinery/door/airlock/grunge{ - name = "Library" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"ckU" = ( -/obj/machinery/bookbinder, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"ckV" = ( -/obj/structure/bookcase/random/reference, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"ckW" = ( -/obj/structure/bookcase/random/nonfiction, -/turf/open/floor/plasteel/dark, -/area/service/library) -"ckX" = ( -/obj/structure/bookcase/random/fiction, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"clb" = ( -/obj/machinery/door/poddoor{ - id = "chapelgun"; - name = "mass driver door" - }, -/turf/open/floor/plating, -/area/service/chapel/main/monastery) -"cld" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 - }, -/turf/closed/wall, -/area/maintenance/department/chapel/monastery) +/turf/open/space/basic, +/area/space/nearstation) "cle" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ + dir = 8 + }, +/obj/item/wrench, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"clf" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/closed/wall, -/area/maintenance/department/chapel/monastery) -"clf" = ( -/obj/machinery/light/small{ - dir = 1 +/obj/structure/cable{ + icon_state = "1-8" }, -/obj/item/storage/box/lights/bulbs, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 +/obj/structure/cable{ + icon_state = "1-4" }, /turf/open/floor/plating, /area/maintenance/department/chapel/monastery) -"clg" = ( -/obj/structure/chair/wood/normal{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) "cli" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, /turf/open/floor/plasteel/dark, @@ -48714,25 +47539,27 @@ /turf/open/floor/plating/asteroid/airless, /area/asteroid/nearstation/bomb_site) "clk" = ( -/obj/machinery/light/small{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 }, -/obj/machinery/libraryscanner, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "clm" = ( -/obj/structure/closet/crate/bin, +/obj/machinery/photocopier, +/obj/machinery/light_switch{ + pixel_x = -24; + pixel_y = -8 + }, /turf/open/floor/plasteel/dark, /area/service/library/lounge) "cln" = ( -/obj/structure/bookcase/random/adult, -/turf/open/floor/plasteel/dark, +/obj/machinery/newscaster{ + pixel_x = -32; + pixel_y = -32 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/carpet, /area/service/library/lounge) -"clp" = ( -/obj/structure/table/wood, -/obj/machinery/computer/libraryconsole/bookmanagement, -/turf/open/floor/plasteel/dark, -/area/service/library) "cls" = ( /obj/effect/spawner/lootdrop/maintenance, /turf/closed/mineral, @@ -49485,42 +48312,42 @@ /obj/structure/lattice, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/space/basic, -/area/ai_monitored/turret_protected/AIsatextAP) +/area/ai_monitored/turret_protected/AIsatextAS) "cnJ" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/vending/wardrobe/sec_wardrobe, -/turf/open/floor/plasteel/showroomfloor, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, /area/security/office) "cnN" = ( -/obj/structure/closet/secure_closet/security/sec, -/obj/machinery/camera{ - c_tag = "Brig Equipment Room" +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 8 }, -/obj/item/radio/intercom{ - name = "Station Intercom (General)"; - pixel_y = 29 - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) +/obj/machinery/portable_atmospherics/canister/nitrous_oxide, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "cnP" = ( -/obj/machinery/vending/security, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/turf/open/floor/plasteel/dark, +/area/security/processing/cremation) "cnQ" = ( -/obj/machinery/suit_storage_unit/security, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) -"cnT" = ( -/obj/structure/weightmachine/weightlifter, -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Brig Crematorium"; + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/processing/cremation) "cnV" = ( -/obj/structure/punching_bag, -/turf/open/floor/plasteel/showroomfloor, -/area/security/office) +/turf/closed/wall/r_wall, +/area/command/heads_quarters/hos) "cnX" = ( /obj/structure/table, /obj/effect/spawner/lootdrop/maintenance, @@ -49546,6 +48373,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/structure/bedsheetbin/color, /turf/open/floor/plasteel/cafeteria, /area/commons/dorms) "coe" = ( @@ -50325,15 +49153,18 @@ /turf/open/floor/plasteel, /area/engineering/atmos) "cqH" = ( -/obj/machinery/light/small{ - dir = 8 +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 }, /turf/open/floor/plasteel/dark, /area/service/chapel/dock) "cqS" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/space/nearstation) +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/security/brig) "cqU" = ( /obj/structure/window/reinforced{ dir = 4 @@ -50352,11 +49183,13 @@ /turf/open/floor/plasteel, /area/command/heads_quarters/ce) "cqW" = ( -/obj/structure/chair, -/turf/open/floor/plasteel/white{ - heat_capacity = 1e+006 +/obj/structure/closet, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 3; + name = "3maintenance loot spawner" }, -/area/service/chapel/dock) +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "cqX" = ( /obj/structure/disposalpipe/segment, /obj/structure/lattice, @@ -50713,7 +49546,7 @@ "csy" = ( /obj/effect/spawner/lootdrop/maintenance, /obj/structure/disposalpipe/segment{ - dir = 6 + dir = 4 }, /turf/open/floor/plating, /area/maintenance/department/engine) @@ -51049,12 +49882,31 @@ /turf/open/floor/plating, /area/service/chapel/main/monastery) "ctS" = ( -/obj/structure/disposaloutlet, -/obj/structure/disposalpipe/trunk{ +/obj/item/storage/box/bodybags, +/obj/structure/extinguisher_cabinet{ + pixel_x = -27 + }, +/obj/machinery/light{ + dir = 8 + }, +/obj/structure/table/glass, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/obj/item/reagent_containers/syringe{ + name = "steel point" + }, +/obj/item/reagent_containers/glass/bottle/charcoal, +/obj/item/reagent_containers/glass/bottle/epinephrine, +/obj/effect/turf_decal/tile/red{ dir = 1 }, -/turf/open/floor/plating/airless, -/area/space/nearstation) +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/security/brig) "ctX" = ( /obj/machinery/vending/wardrobe/chap_wardrobe, /turf/open/floor/carpet, @@ -51463,6 +50315,15 @@ /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) "cvq" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) +"cvr" = ( /obj/machinery/camera{ c_tag = "Monastery Secondary Dock"; dir = 8; @@ -51473,42 +50334,20 @@ }, /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) -"cvr" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +"cvs" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ dir = 4 }, -/obj/machinery/door/window/eastleft{ - dir = 1; - name = "Coffin Storage"; - req_one_access_txt = "22" - }, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) -"cvs" = ( +/turf/open/floor/plasteel, +/area/security/brig) +"cvt" = ( /obj/structure/window/reinforced{ dir = 1 }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) -"cvt" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/door/window/eastleft{ - base_state = "right"; - dir = 1; - icon_state = "right"; - name = "Coffin Storage"; - req_one_access_txt = "22" - }, -/obj/machinery/airalarm{ - dir = 8; - pixel_x = 24 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/carpet, /area/service/chapel/main/monastery) "cvu" = ( /obj/structure/cable{ @@ -51531,25 +50370,16 @@ /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) "cvw" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ +/obj/structure/chair/office/dark{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/effect/landmark/start/security_officer, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) +/turf/open/floor/plasteel, +/area/security/office) "cvy" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -51560,9 +50390,16 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) "cvA" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) +"cvB" = ( /obj/machinery/door/airlock/external{ name = "Dock Access" }, @@ -51571,29 +50408,19 @@ }, /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) -"cvB" = ( +"cvC" = ( /obj/structure/chair/wood/normal, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) -"cvC" = ( -/obj/structure/chair/wood/normal, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/carpet, /area/service/chapel/main/monastery) "cvE" = ( /obj/structure/cable{ icon_state = "1-4" }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/item/kirbyplants{ - icon_state = "plant-21" - }, +/obj/machinery/light/small, /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) "cvF" = ( @@ -51616,15 +50443,9 @@ /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) "cvH" = ( -/obj/structure/cable{ - icon_state = "2-8" - }, /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -51635,32 +50456,27 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) -"cvI" = ( -/obj/machinery/light/small, -/obj/structure/cable{ - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/camera{ c_tag = "Monastery Cloister Aft"; dir = 1; network = list("ss13","monastery") }, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/light/small, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) +"cvI" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) "cvJ" = ( @@ -51671,39 +50487,31 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) "cvK" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +/obj/structure/closet, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 8; + name = "8maintenance loot spawner" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) +"cvR" = ( +/obj/machinery/meter, +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ dir = 8 }, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) -"cvR" = ( +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"cvS" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8; + name = "Supply to Security" + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"cvT" = ( /obj/machinery/light/small{ dir = 8 }, @@ -51717,238 +50525,173 @@ }, /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) -"cvS" = ( -/obj/structure/chair/wood/normal, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) -"cvT" = ( +"cvV" = ( /obj/structure/chair/wood/normal, /turf/open/floor/carpet, /area/service/chapel/main/monastery) -"cvV" = ( -/obj/structure/chair/wood/normal, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) -"cvX" = ( -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/closed/wall/mineral/iron, -/area/maintenance/department/chapel/monastery) -"cvY" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/closed/wall/mineral/iron, -/area/maintenance/department/chapel/monastery) -"cvZ" = ( -/obj/structure/cable{ - icon_state = "2-8" - }, -/turf/closed/wall/mineral/iron, -/area/maintenance/department/chapel/monastery) -"cwa" = ( -/turf/closed/wall/mineral/iron, -/area/maintenance/department/chapel/monastery) "cwc" = ( -/obj/structure/cable{ - icon_state = "1-2" +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 }, -/obj/machinery/door/airlock/maintenance{ - name = "Monastery Maintenance"; - req_one_access_txt = "22;24;10;11;37" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/meter, /turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) +/area/maintenance/department/security/brig) "cwe" = ( /turf/closed/wall/mineral/iron, /area/service/library/lounge) "cwg" = ( -/obj/machinery/door/airlock/grunge{ - name = "Library" - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) +/obj/structure/grille, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "cwj" = ( -/obj/item/storage/box/matches{ - pixel_x = -3; - pixel_y = 8 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "2-4" }, -/obj/structure/table/wood, /turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) +/area/security/processing/cremation) "cwk" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 +/obj/structure/cable{ + icon_state = "1-8" }, -/turf/open/floor/carpet, -/area/service/chapel/main/monastery) +/turf/open/floor/plasteel/dark, +/area/security/processing/cremation) "cwl" = ( -/obj/effect/decal/cleanable/cobweb{ - icon_state = "cobweb2" +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 }, -/obj/item/storage/fancy/candle_box, -/obj/structure/table/wood, /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) "cwm" = ( -/obj/machinery/portable_atmospherics/canister/oxygen, -/obj/structure/cable{ - icon_state = "1-4" +/obj/machinery/power/smes{ + charge = 5e+006 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/structure/cable, +/obj/structure/cable{ + icon_state = "1-2" }, /turf/open/floor/plating, /area/maintenance/department/chapel/monastery) "cwn" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/item/storage/toolbox/mechanical, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/open/floor/plasteel/dark, +/area/security/processing/cremation) +"cwo" = ( /obj/machinery/light/small{ dir = 1 }, +/obj/machinery/portable_atmospherics/canister/oxygen, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) -"cwo" = ( -/obj/machinery/power/apc{ - dir = 1; - name = "Monastery Maintenance APC"; - pixel_y = 23 + dir = 6 }, /obj/structure/cable{ - icon_state = "0-8" - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 + icon_state = "1-4" }, /turf/open/floor/plating, /area/maintenance/department/chapel/monastery) "cwp" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/structure/bodycontainer/morgue, +/obj/machinery/camera{ + c_tag = "Brig Infirmary"; dir = 4 }, -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/turf/open/floor/plasteel/dark, +/area/security/brig) "cwr" = ( /obj/item/kirbyplants{ icon_state = "plant-22" }, -/obj/structure/cable{ - icon_state = "0-8" +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_y = 26 }, -/obj/machinery/power/apc{ - dir = 4; - name = "Library Lounge APC"; - pixel_x = 24 - }, -/obj/machinery/airalarm{ - pixel_y = 22 +/obj/structure/sign/painting/library{ + pixel_x = -32 }, /turf/open/floor/plasteel/dark, /area/service/library/lounge) "cww" = ( -/obj/structure/table/wood, -/obj/item/reagent_containers/food/snacks/grown/poppy, -/obj/item/reagent_containers/food/snacks/grown/harebell, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/open/floor/plasteel, +/area/security/brig) "cwx" = ( -/obj/structure/table/wood/fancy, -/obj/item/storage/book/bible, -/turf/open/floor/carpet, -/area/service/chapel/main/monastery) +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/machinery/light_switch{ + dir = 9; + pixel_x = -22 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/office) "cwy" = ( -/obj/structure/table/wood/fancy, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/item/candle, -/obj/item/candle{ - pixel_x = 6; - pixel_y = 8 +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 }, -/obj/item/candle{ - pixel_x = -8; - pixel_y = 6 - }, -/turf/open/floor/carpet, +/turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) "cwz" = ( -/obj/item/clothing/under/misc/burial, -/obj/item/clothing/under/misc/burial, -/obj/item/clothing/under/misc/burial, -/obj/item/clothing/under/misc/burial, /obj/structure/table/wood, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) -"cwA" = ( -/turf/open/floor/plating, -/area/maintenance/department/chapel/monastery) +/obj/machinery/recharger, +/turf/open/floor/plasteel, +/area/security/office) "cwE" = ( -/obj/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/closed/wall, +/area/maintenance/department/security/brig) "cwF" = ( +/obj/machinery/door/airlock/atmos/abandoned{ + name = "Atmospherics Maintenance"; + req_access_txt = "12;24" + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"cwG" = ( /obj/structure/window/reinforced, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) -"cwG" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/machinery/button/massdriver{ - id = "chapelgun"; - pixel_x = 28 - }, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) "cwH" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 8; + name = "Air to Distro" }, /turf/open/floor/plating, /area/maintenance/department/chapel/monastery) "cwK" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 8 - }, -/turf/open/floor/carpet, -/area/service/library/lounge) +/obj/item/extinguisher, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "cwM" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall, +/area/maintenance/department/security/brig) +"cwO" = ( /obj/structure/window/reinforced{ dir = 4; layer = 2.9 }, /turf/open/space, /area/space/nearstation) -"cwO" = ( -/obj/item/flashlight/lantern, -/turf/open/floor/plasteel/dark, -/area/service/chapel/main/monastery) "cwR" = ( /obj/structure/window/reinforced{ dir = 8; @@ -51957,12 +50700,18 @@ /turf/open/space/basic, /area/space/nearstation) "cwS" = ( -/obj/structure/reagent_dispensers/fueltank, +/obj/machinery/atmospherics/components/unary/tank/air{ + dir = 1 + }, /turf/open/floor/plating, /area/maintenance/department/chapel/monastery) "cwU" = ( /obj/structure/table/wood, -/obj/machinery/computer/libraryconsole, +/obj/item/folder/yellow, +/obj/item/pen, +/obj/structure/sign/painting/library{ + pixel_x = -32 + }, /turf/open/floor/plasteel/dark, /area/service/library/lounge) "cxb" = ( @@ -51974,51 +50723,35 @@ /turf/open/floor/plasteel, /area/science/mixing) "cxe" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/courtroom) +"cxg" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Crematorium Maintenance"; + req_one_access_txt = "2;27" }, /obj/structure/cable{ icon_state = "1-2" }, -/turf/open/floor/carpet, -/area/service/library/lounge) -"cxg" = ( -/obj/structure/window/reinforced{ - dir = 1; - pixel_y = 1 - }, -/turf/open/space/basic, -/area/space/nearstation) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "cxh" = ( -/obj/structure/window/reinforced{ - dir = 1; - pixel_y = 1 +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 6 }, -/obj/structure/window/reinforced{ - dir = 4; - layer = 2.9 - }, -/turf/open/space/basic, -/area/space/nearstation) +/turf/closed/wall, +/area/security/processing/cremation) "cxk" = ( -/obj/structure/window/reinforced{ - dir = 1; - pixel_y = 1 +/obj/machinery/door/poddoor{ + id = "chapelgun"; + name = "mass driver door" }, -/obj/structure/window/reinforced{ - dir = 8; - layer = 2.9 - }, -/turf/open/space/basic, -/area/space/nearstation) -"cxn" = ( -/obj/machinery/newscaster{ - pixel_x = -32; - pixel_y = -32 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/carpet, -/area/service/library/lounge) +/turf/open/floor/plating, +/area/service/chapel/main/monastery) "cxt" = ( /obj/effect/turf_decal/box/corners{ dir = 8 @@ -52036,29 +50769,50 @@ /turf/open/floor/plasteel/dark, /area/science/explab) "cxz" = ( -/obj/machinery/door/airlock/grunge{ - name = "Library" +/obj/structure/disposalpipe/segment{ + dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/structure/grille/broken, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) +"cxB" = ( /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"cxB" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/fore) +"cxD" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/effect/landmark/xeno_spawn, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) +"cxE" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, /turf/closed/wall, /area/service/library/lounge) -"cxC" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 1 +"cxL" = ( +/obj/machinery/door/window/eastright{ + base_state = "left"; + dir = 1; + icon_state = "left"; + name = "Security Delivery"; + req_access_txt = "1" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=4"; + dir = 1; + freq = 1400; + location = "Security" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 9 }, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -52071,230 +50825,69 @@ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"cxD" = ( -/obj/effect/turf_decal/stripes/corner, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"cxE" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, -/turf/closed/wall, -/area/service/library/lounge) -"cxJ" = ( +/area/security/processing/cremation) +"cxM" = ( /obj/structure/window/reinforced/fulltile, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/service/library/lounge) -"cxK" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"cxL" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"cxM" = ( -/obj/structure/window/reinforced/fulltile, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plating, -/area/service/library/lounge) "cxX" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/camera{ - c_tag = "Monastery Archives Access Tunnel"; - dir = 4; - network = list("ss13","monastery") - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"cxY" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/light/small{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"cyl" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) +/obj/structure/table/wood, +/obj/item/folder/red, +/turf/open/floor/plasteel, +/area/security/courtroom) "cym" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/turf/closed/wall, +/area/security/courtroom) +"cyy" = ( /obj/structure/cable{ - icon_state = "1-2" + icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 }, /turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"cyy" = ( +/area/security/brig) +"cyz" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/brig) +"cyB" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, /turf/closed/wall, /area/service/library/lounge) -"cyz" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"cyA" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 8 +"cyP" = ( +/obj/structure/closet/secure_closet/warden, +/obj/item/clothing/mask/gas/sechailer, +/obj/machinery/power/apc{ + dir = 8; + name = "Brig Control APC"; + pixel_x = -25 }, /obj/structure/cable{ - icon_state = "1-2" + icon_state = "0-2" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) -"cyB" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 - }, -/turf/closed/wall, -/area/service/library/lounge) -"cyL" = ( -/obj/structure/lattice, -/obj/structure/lattice, -/turf/closed/mineral, -/area/service/chapel/asteroid/monastery) -"cyM" = ( -/obj/structure/lattice, -/turf/closed/mineral, -/area/service/chapel/asteroid/monastery) -"cyP" = ( -/obj/structure/bookcase/random/nonfiction, -/obj/machinery/light/small{ - dir = 1 +/obj/structure/reagent_dispensers/peppertank{ + pixel_y = 30 }, +/turf/open/floor/plasteel/showroomfloor, +/area/security/warden) +"cyQ" = ( +/obj/machinery/vending/games, /turf/open/floor/plasteel/dark, /area/service/library) -"cyQ" = ( +"cyR" = ( /obj/item/kirbyplants{ icon_state = "plant-22" }, @@ -52307,48 +50900,37 @@ }, /turf/open/floor/plasteel/dark, /area/service/library) -"cyR" = ( +"cyT" = ( /obj/item/kirbyplants{ icon_state = "plant-22" }, /turf/open/floor/plasteel/dark, /area/service/library) -"cyS" = ( -/obj/structure/bookcase/random/religion, -/obj/machinery/light/small{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, -/area/service/library) -"cyT" = ( -/obj/structure/table/wood, -/obj/item/paper_bin{ - layer = 2.9; - pixel_x = -2; - pixel_y = 4 - }, -/obj/item/pen, -/turf/open/floor/plasteel/dark, -/area/service/library) "cyU" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/service/library) "cyY" = ( +/obj/machinery/door/airlock/security{ + name = "Interrogation"; + req_access_txt = "63" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) +"cyZ" = ( /obj/machinery/light/small{ dir = 8 }, /turf/open/floor/plasteel/dark, /area/service/library) -"cyZ" = ( -/obj/structure/displaycase/trophy, -/turf/open/floor/plasteel/dark, -/area/service/library) "czl" = ( -/obj/structure/chair/wood/normal, -/turf/open/floor/carpet, -/area/service/library) -"czo" = ( +/obj/structure/grille/broken, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) +"czq" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp/green{ pixel_x = 1; @@ -52356,28 +50938,15 @@ }, /turf/open/floor/plasteel/dark, /area/service/library) -"czp" = ( -/obj/structure/table/wood, -/obj/item/barcodescanner, -/turf/open/floor/plasteel/dark, -/area/service/library) -"czq" = ( -/obj/machinery/airalarm{ - dir = 8; - pixel_x = 24 - }, -/turf/open/floor/plasteel/dark, -/area/service/library) -"czr" = ( -/obj/structure/table/wood/fancy, -/turf/open/floor/carpet, -/area/service/library) "czt" = ( -/obj/structure/table/wood/fancy, -/obj/item/storage/photo_album, +/obj/structure/closet/firecloset, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) +"czv" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/carpet, /area/service/library) -"czu" = ( +"czw" = ( /obj/structure/table/wood, /obj/item/paper_bin{ layer = 2.9; @@ -52386,38 +50955,33 @@ }, /turf/open/floor/plasteel/dark, /area/service/library) -"czv" = ( -/obj/structure/chair/wood/normal{ +"czB" = ( +/obj/structure/chair{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) +"czC" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/turf/open/floor/plasteel/dark, -/area/service/library) -"czw" = ( -/obj/machinery/newscaster{ - pixel_x = 32 +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 }, /turf/open/floor/plasteel/dark, -/area/service/library) -"czB" = ( -/obj/structure/table/wood/fancy, -/obj/item/storage/fancy/candle_box, -/turf/open/floor/carpet, -/area/service/library) -"czC" = ( -/obj/structure/table/wood/fancy, -/obj/item/flashlight/lantern{ - icon_state = "lantern-on"; - pixel_y = 8 - }, -/turf/open/floor/carpet, -/area/service/library) +/area/service/chapel/main/monastery) "czD" = ( -/obj/structure/table/wood, -/obj/item/folder/yellow, -/obj/item/pen, -/turf/open/floor/plasteel/dark, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/carpet, /area/service/library) -"czH" = ( +"czI" = ( /obj/machinery/light/small{ dir = 8 }, @@ -52428,73 +50992,61 @@ }, /turf/open/floor/plasteel/dark, /area/service/library) -"czI" = ( +"czM" = ( /obj/structure/chair/wood/normal{ dir = 1 }, /turf/open/floor/carpet, /area/service/library) -"czL" = ( +"czN" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark, /area/service/library) -"czM" = ( +"czO" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/service/library) -"czN" = ( +"czP" = ( +/obj/machinery/light_switch{ + pixel_x = -24 + }, +/turf/open/floor/carpet/black, +/area/service/chapel/office) +"czQ" = ( /obj/structure/table/wood, /obj/item/storage/bag/books, /turf/open/floor/plasteel/dark, /area/service/library) -"czO" = ( -/obj/structure/table/wood, -/obj/item/instrument/saxophone, -/turf/open/floor/plasteel/dark, -/area/service/library) -"czP" = ( -/obj/structure/table/wood, -/obj/item/stack/packageWrap, -/obj/item/coin/gold, -/turf/open/floor/plasteel/dark, -/area/service/library) -"czQ" = ( -/obj/machinery/light/small{ +"czV" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"czW" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/machinery/camera{ - c_tag = "Monastery Archives Starboard"; - dir = 8; - network = list("ss13","monastery") +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 }, /turf/open/floor/plasteel/dark, -/area/service/library) -"czV" = ( +/area/service/chapel/main/monastery) +"czY" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, /turf/open/floor/plasteel/dark, /area/service/library) -"czW" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/service/library) -"czY" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/service/library) -"czZ" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/library) "cAa" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plasteel/dark, @@ -52513,56 +51065,30 @@ /turf/open/floor/plasteel/dark, /area/service/library) "cAi" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/library) +/turf/closed/mineral, +/area/service/chapel/asteroid/monastery) "cAj" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/library) +/turf/closed/wall, +/area/maintenance/department/chapel/monastery) "cAr" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /obj/machinery/light/small{ - dir = 8 + dir = 1 }, -/obj/machinery/door/window/northright{ - base_state = "left"; - dir = 2; - icon_state = "left"; - name = "Curator Desk Door"; - req_access_txt = "37" - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/library) +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "cAs" = ( /obj/structure/table/wood, -/obj/item/kirbyplants{ - icon_state = "plant-05"; - pixel_y = 10 - }, +/obj/item/clothing/head/pharaoh, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -52593,9 +51119,28 @@ /turf/open/floor/plasteel/dark, /area/service/library) "cAu" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/machinery/door/window/northright{ + base_state = "left"; + dir = 2; + icon_state = "left"; + name = "Curator Desk Door"; + req_access_txt = "37" + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) +"cAv" = ( /obj/structure/table/wood, -/obj/item/clothing/head/pharaoh, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/item/kirbyplants{ + icon_state = "plant-05"; + pixel_y = 10 + }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -52608,7 +51153,7 @@ }, /turf/open/floor/plasteel/dark, /area/service/library) -"cAv" = ( +"cAy" = ( /obj/structure/table/wood, /obj/item/camera, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -52624,38 +51169,7 @@ }, /turf/open/floor/plasteel/dark, /area/service/library) -"cAy" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/machinery/door/window/northright{ - dir = 2; - name = "Curator Desk Door"; - req_access_txt = "37" - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/library) "cAB" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/service/library) -"cAC" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/chair/wood/wings{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, -/area/service/library) -"cAD" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/chair/wood/wings{ dir = 1 @@ -52663,32 +51177,46 @@ /obj/effect/landmark/start/librarian, /turf/open/floor/plasteel/dark, /area/service/library) +"cAC" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) +"cAD" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/closed/wall, +/area/maintenance/department/chapel/monastery) "cAH" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/space/basic, +/area/space) +"cAJ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"cAK" = ( /obj/machinery/light/small, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, /turf/open/floor/plasteel/dark, /area/service/library) -"cAJ" = ( +"cAM" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 }, /turf/open/floor/plasteel/dark, /area/service/library) -"cAK" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 - }, -/turf/open/floor/plasteel/dark, -/area/service/library) -"cAM" = ( -/obj/machinery/light/small, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/service/library) "cAQ" = ( /obj/structure/cable{ icon_state = "1-8" @@ -52699,50 +51227,59 @@ /turf/open/floor/plating, /area/engineering/main) "cAS" = ( -/obj/machinery/vending/wardrobe/curator_wardrobe, -/turf/open/floor/plasteel/dark, -/area/service/library) -"cAT" = ( -/obj/structure/destructible/cult/tome, -/turf/open/floor/plasteel/dark, -/area/service/library) -"cAU" = ( -/obj/structure/rack{ - icon = 'icons/obj/stationobjs.dmi'; - icon_state = "minibar"; - name = "skeletal minibar" +/obj/structure/cable{ + icon_state = "4-8" }, -/obj/item/book/codex_gigas, -/obj/machinery/camera{ - c_tag = "Monastery Archives Aft"; - dir = 1; - network = list("ss13","monastery") +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/service/library) -"cAV" = ( -/obj/structure/bookcase{ - name = "Forbidden Knowledge" - }, -/turf/open/floor/plasteel/dark, -/area/service/library) -"cBi" = ( -/obj/machinery/flasher/portable, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ dir = 4 }, /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 5 +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) +"cAT" = ( +/obj/structure/grille/broken, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"cAU" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 }, /turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) +/area/service/chapel/main/monastery) +"cAV" = ( +/obj/machinery/vending/wardrobe/curator_wardrobe, +/turf/open/floor/plasteel/dark, +/area/service/library) +"cBi" = ( +/obj/machinery/holopad, +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/office) "cBk" = ( /obj/machinery/vending/boozeomat/pubby_maint, /turf/closed/wall, @@ -52865,12 +51402,9 @@ /turf/open/floor/plasteel/white, /area/medical/virology) "cBL" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Medbay Maintenance"; - req_one_access_txt = "12;45;5;9" - }, +/obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, -/area/maintenance/department/engine) +/area/medical/paramedic) "cBM" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -52927,19 +51461,18 @@ /obj/effect/turf_decal/bot/right, /turf/open/floor/plasteel/white, /area/engineering/gravity_generator) -"cCR" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/atmospherics/components/unary/outlet_injector/on{ - dir = 1 - }, -/turf/open/floor/plating/airless, -/area/maintenance/department/chapel/monastery) "cCS" = ( -/obj/machinery/rnd/production/techfab/department/security, -/turf/open/floor/plasteel/dark, -/area/security/office) +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/cable, +/obj/machinery/door/poddoor/preopen{ + id = "hos_spess_shutters"; + name = "Space shutters" + }, +/turf/open/floor/plating, +/area/command/heads_quarters/hos) "cCT" = ( /obj/machinery/rnd/production/techfab/department/cargo, /turf/open/floor/plasteel, @@ -52958,9 +51491,14 @@ /turf/open/floor/plasteel, /area/engineering/main) "cCW" = ( -/obj/machinery/vending/games, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, /turf/open/floor/plasteel/dark, -/area/service/library) +/area/service/chapel/main/monastery) "cCX" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -52997,18 +51535,69 @@ icon_state = "platingdmg3" }, /area/maintenance/department/science) -"cFB" = ( -/obj/effect/landmark/carpspawn, -/turf/open/space/basic, -/area/space) -"cHS" = ( -/obj/machinery/door/airlock/maintenance/abandoned{ - name = "Firing Range" - }, +"cFr" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/drinks/soda_cans/cola, /turf/open/floor/plating{ icon_state = "platingdmg3" }, /area/maintenance/department/security/brig) +"cFB" = ( +/obj/effect/landmark/carpspawn, +/turf/open/space/basic, +/area/space) +"cFG" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/zone3) +"cFH" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) +"cHm" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, +/area/maintenance/department/security/brig) +"cHB" = ( +/obj/structure/sign/painting/library{ + pixel_y = -32 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) +"cHS" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/circuit/green, +/area/maintenance/department/security/brig) +"cIN" = ( +/obj/machinery/door/airlock/grunge{ + name = "Library" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "cJo" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 @@ -53044,6 +51633,15 @@ }, /turf/open/floor/plating, /area/engineering/main) +"cLJ" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/structure/sign/poster/official/cleanliness{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/dark, +/area/medical/surgery) "cOp" = ( /obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas, @@ -53143,6 +51741,23 @@ }, /turf/open/floor/plasteel/dark, /area/science/lab) +"cTI" = ( +/obj/item/wirecutters, +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"cVq" = ( +/obj/structure/rack, +/obj/item/clothing/mask/gas, +/obj/item/multitool, +/turf/open/floor/plating, +/area/maintenance/solars/port) "cXP" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 @@ -53186,13 +51801,22 @@ /turf/open/floor/plasteel, /area/commons/dorms) "dci" = ( -/obj/structure/rack, -/obj/item/gun/energy/laser/practice, -/obj/item/clothing/ears/earmuffs, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/department/security/brig) "dcL" = ( -/obj/structure/barricade/wooden, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, /turf/open/floor/plating, /area/maintenance/department/security/brig) "deJ" = ( @@ -53293,6 +51917,12 @@ }, /turf/open/floor/plating, /area/science/xenobiology) +"dnG" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/brig) "dnS" = ( /obj/machinery/atmospherics/components/binary/pump{ name = "Mix Bypass" @@ -53436,6 +52066,13 @@ }, /turf/open/floor/plasteel/white/corner, /area/hallway/secondary/exit/departure_lounge) +"dwq" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/chair/wood/wings{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "dxc" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -53476,15 +52113,50 @@ icon_state = "platingdmg1" }, /area/maintenance/department/engine) +"dCo" = ( +/obj/machinery/door/poddoor/preopen{ + id = "prison release"; + name = "prisoner processing blast door" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/security/brig) "dEy" = ( /obj/structure/reflector/double/anchored{ dir = 9 }, /turf/open/floor/plasteel/dark, /area/engineering/main) +"dET" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "dFJ" = ( /turf/open/floor/engine, /area/engineering/supermatter) +"dHg" = ( +/obj/structure/plasticflaps/opaque, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/processing/cremation) "dHo" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -53556,6 +52228,14 @@ icon_state = "platingdmg3" }, /area/maintenance/department/science) +"dLN" = ( +/obj/structure/closet/crate, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 4; + name = "4maintenance loot spawner" + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "dLY" = ( /obj/structure/table, /obj/item/assembly/igniter, @@ -53595,6 +52275,10 @@ /obj/machinery/shieldwallgen/xenobiologyaccess, /turf/open/floor/plating, /area/maintenance/department/engine) +"dRT" = ( +/obj/structure/bookcase/random/reference, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "dSp" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/atmos/engine_waste{ dir = 1 @@ -53611,15 +52295,23 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) -"dVI" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 4; - layer = 2.4 +"dVp" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Brig Infirmary Maintenance"; + req_access_txt = "63" + }, +/obj/structure/cable{ + icon_state = "1-2" }, -/obj/item/wrench, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, -/area/security/execution/transfer) +/area/maintenance/department/security/brig) +"dVI" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/showroomfloor, +/area/security/warden) "dVJ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -53628,6 +52320,10 @@ icon_state = "platingdmg1" }, /area/maintenance/department/science) +"dVP" = ( +/obj/item/chair, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "dWk" = ( /obj/item/reagent_containers/food/snacks/meat/slab/monkey, /turf/open/floor/plating, @@ -53644,11 +52340,23 @@ /turf/open/floor/plating, /area/engineering/main) "dYe" = ( -/obj/structure/cable{ - icon_state = "2-8" +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/security/warden) +"dYI" = ( +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 }, /turf/open/floor/plasteel/dark, -/area/security/prison) +/area/service/library) +"dZa" = ( +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, +/area/maintenance/department/security/brig) "dZj" = ( /obj/machinery/atmospherics/pipe/manifold/green/visible, /obj/machinery/airalarm/engine{ @@ -53689,6 +52397,10 @@ /obj/machinery/status_display/supply, /turf/closed/wall, /area/cargo/office) +"eeG" = ( +/obj/machinery/bookbinder, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "eeQ" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -53710,12 +52422,22 @@ icon_state = "panelscorched" }, /area/maintenance/department/science) +"egu" = ( +/obj/structure/bookcase/random/religion, +/turf/open/floor/plasteel/dark, +/area/service/library) "egK" = ( -/obj/structure/girder, -/turf/open/floor/plating{ - icon_state = "panelscorched" +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 }, -/area/maintenance/department/security/brig) +/turf/open/floor/plasteel/showroomfloor, +/area/security/warden) +"ehJ" = ( +/obj/structure/chair{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "ehM" = ( /obj/effect/decal/remains/human, /obj/structure/disposaloutlet, @@ -53724,6 +52446,12 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) +"ehR" = ( +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + dir = 6 + }, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "eiV" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ dir = 4 @@ -53732,11 +52460,18 @@ /turf/open/space/basic, /area/space/nearstation) "ekU" = ( -/obj/effect/decal/cleanable/cobweb{ - icon_state = "cobweb2" +/obj/machinery/light/small{ + dir = 4 }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/obj/machinery/camera{ + c_tag = "Labor Shuttle Dock"; + dir = 8 + }, +/obj/machinery/gulag_item_reclaimer{ + pixel_y = 24 + }, +/turf/open/floor/plasteel/dark, +/area/security/brig) "elk" = ( /obj/structure/chair/office/dark, /turf/open/floor/wood, @@ -53785,6 +52520,12 @@ }, /turf/open/floor/plasteel/dark, /area/engineering/main) +"ete" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel/dark, +/area/security/courtroom) "euQ" = ( /obj/structure/sign/warning/vacuum/external{ pixel_y = 32 @@ -53794,10 +52535,35 @@ }, /turf/open/floor/plating, /area/maintenance/department/science) +"evQ" = ( +/obj/effect/spawner/lootdrop/grille_or_trash, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "eyj" = ( /obj/effect/spawner/structure/window/plasma/reinforced, /turf/open/floor/plating, /area/engineering/main) +"eyu" = ( +/obj/item/radio/intercom{ + desc = "Talk through this. It looks like it has been modified to not broadcast."; + name = "Prison Intercom (General)"; + pixel_x = -25; + pixel_y = -2; + prison_radio = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/brig) +"ezx" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/open/floor/plating, +/area/security/brig) "ezF" = ( /obj/structure/table/wood, /obj/item/paper_bin, @@ -53914,6 +52680,18 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"eKC" = ( +/obj/machinery/door/airlock/grunge{ + name = "Library" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "eLt" = ( /obj/structure/closet/firecloset, /obj/effect/turf_decal/tile/neutral{ @@ -53937,14 +52715,7 @@ }, /area/maintenance/department/science) "eNc" = ( -/obj/effect/spawner/lootdrop/maintenance{ - lootcount = 3; - name = "3maintenance loot spawner" - }, -/obj/structure/rack, -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, +/turf/open/floor/plating, /area/maintenance/department/chapel/monastery) "eNq" = ( /obj/effect/turf_decal/stripes/line{ @@ -53965,11 +52736,30 @@ /turf/open/floor/plating, /area/maintenance/department/security/brig) "ePU" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/machinery/computer/security/labor, +/turf/open/floor/plasteel/dark, +/area/security/brig) +"eQk" = ( +/obj/machinery/computer/med_data{ dir = 4 }, -/turf/closed/wall, -/area/maintenance/department/security/brig) +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/item/radio/intercom{ + frequency = 1485; + name = "Station Intercom (Medbay)"; + pixel_y = -27 + }, +/obj/structure/sign/poster/official/no_erp{ + pixel_x = -32 + }, +/turf/open/floor/plasteel/white, +/area/medical/surgery) "eQN" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -53996,13 +52786,20 @@ /obj/machinery/door/firedoor, /turf/open/floor/plasteel, /area/hallway/primary/aft) -"eSB" = ( -/obj/machinery/computer/cryopod{ - dir = 1; - pixel_y = -26 +"eRv" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Surgery Maintenance"; + req_access_txt = "45" }, -/turf/open/floor/plasteel/dark, -/area/security/prison) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, +/area/maintenance/department/engine) +"eSB" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/security/warden) "eSL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/item/beacon, @@ -54053,6 +52850,10 @@ }, /turf/open/floor/engine, /area/science/explab) +"eXX" = ( +/obj/structure/plasticflaps, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "eYr" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -54069,6 +52870,26 @@ /obj/item/stack/cable_coil/cut/random, /turf/open/floor/plating, /area/maintenance/department/cargo) +"fbX" = ( +/obj/structure/chair/stool, +/obj/effect/turf_decal/trimline/blue/filled/line, +/obj/item/cigbutt{ + pixel_x = -15; + pixel_y = 14 + }, +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -26 + }, +/obj/effect/landmark/start/paramedic, +/turf/open/floor/plasteel/dark, +/area/medical/paramedic) +"fdM" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "fdQ" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -54133,6 +52954,11 @@ }, /turf/open/floor/plasteel, /area/construction/mining/aux_base) +"fgh" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable, +/turf/open/space, +/area/solars/port) "fgS" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -54258,6 +53084,18 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) +"fug" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/power/apc{ + dir = 4; + name = "Library APC"; + pixel_x = 24 + }, +/obj/structure/cable, +/turf/open/floor/plasteel/dark, +/area/service/library) "fuP" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -54347,15 +53185,8 @@ /turf/open/floor/plasteel, /area/maintenance/department/engine) "fAx" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/turf/closed/wall, +/area/hallway/primary/fore) "fBt" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ @@ -54410,11 +53241,14 @@ /turf/open/floor/plasteel, /area/commons/dorms) "fIN" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 9 +/obj/structure/chair{ + dir = 4 }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) "fIT" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -54441,6 +53275,12 @@ }, /turf/open/floor/plating, /area/maintenance/department/cargo) +"fPy" = ( +/obj/machinery/atmospherics/pipe/manifold/general/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "fQf" = ( /obj/structure/cable{ icon_state = "4-8" @@ -54459,6 +53299,16 @@ "fRs" = ( /turf/closed/wall, /area/command/heads_quarters/rd) +"fRL" = ( +/obj/structure/closet/crate{ + icon_state = "crateopen" + }, +/obj/item/ammo_box/foambox, +/obj/item/ammo_box/foambox, +/obj/item/gun/ballistic/shotgun/toy, +/obj/item/gun/ballistic/shotgun/toy, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "fRT" = ( /obj/structure/lattice, /obj/machinery/atmospherics/pipe/simple/orange/visible{ @@ -54485,9 +53335,15 @@ }, /area/hallway/secondary/exit/departure_lounge) "fWv" = ( -/obj/structure/bookcase/random/religion, -/turf/open/floor/plasteel/dark, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/carpet, /area/service/library/lounge) +"fZq" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/carpet, +/area/service/chapel/main/monastery) "fZK" = ( /obj/machinery/atmospherics/pipe/manifold/cyan/visible{ dir = 4 @@ -54543,13 +53399,19 @@ }, /turf/open/floor/plasteel/white, /area/science/xenobiology) +"geL" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/ai_monitored/turret_protected/AIsatextAS) "geN" = ( /obj/machinery/igniter{ id = "xenoigniter"; luminosity = 2 }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 }, /turf/open/floor/engine, /area/science/xenobiology) @@ -54575,6 +53437,25 @@ }, /turf/open/floor/plasteel/dark, /area/engineering/main) +"ggN" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "giI" = ( /obj/machinery/light/small{ dir = 1 @@ -54582,14 +53463,11 @@ /turf/open/floor/plating, /area/service/chapel/office) "giO" = ( -/obj/structure/cable{ - icon_state = "2-8" +/obj/machinery/door/airlock/external{ + name = "Labor Camp Shuttle Airlock" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/turf/open/floor/plasteel/dark, +/area/security/brig) "gjp" = ( /obj/structure/table/wood, /obj/structure/bedsheetbin, @@ -54618,13 +53496,14 @@ /turf/open/floor/plating, /area/maintenance/department/science) "gjN" = ( -/obj/item/weldingtool, -/obj/effect/spawner/lootdrop/maintenance, -/obj/effect/decal/cleanable/oil{ - icon_state = "floor6" +/obj/structure/chair{ + dir = 8 }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel/dark, +/area/security/office) "gkR" = ( /obj/item/kirbyplants/random, /obj/structure/extinguisher_cabinet{ @@ -54672,6 +53551,12 @@ }, /turf/open/floor/plasteel/dark, /area/science/mixing) +"gmm" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "gmp" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 @@ -54741,6 +53626,14 @@ }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) +"gqi" = ( +/obj/structure/bookcase/random/religion, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) +"gtX" = ( +/obj/structure/barricade/wooden, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "gue" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 @@ -54756,6 +53649,25 @@ }, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"gur" = ( +/obj/structure/table/wood/fancy, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/item/candle, +/obj/item/candle{ + pixel_x = 6; + pixel_y = 8 + }, +/obj/item/candle{ + pixel_x = -8; + pixel_y = 6 + }, +/turf/open/floor/carpet, +/area/service/chapel/main/monastery) +"guy" = ( +/obj/machinery/recharger, +/obj/structure/table, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "gvf" = ( /obj/effect/turf_decal/tile/neutral{ dir = 8 @@ -54765,11 +53677,9 @@ }, /area/hallway/secondary/exit/departure_lounge) "gwn" = ( -/obj/structure/sign/warning{ - pixel_y = 32 - }, -/obj/structure/sign/warning{ - pixel_y = -32 +/obj/structure/girder, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 }, /turf/open/floor/plating, /area/maintenance/department/security/brig) @@ -54811,6 +53721,12 @@ }, /turf/open/floor/plating, /area/maintenance/department/science) +"gyQ" = ( +/obj/structure/closet/emcloset, +/obj/effect/decal/cleanable/cobweb, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "gAG" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp/green, @@ -54824,9 +53740,16 @@ /obj/structure/lattice/catwalk, /turf/open/space/basic, /area/space/nearstation) +"gBu" = ( +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_x = 27 + }, +/turf/open/floor/plasteel/dark, +/area/security/courtroom) "gDR" = ( /obj/machinery/camera{ - c_tag = "Central Primary Hallway Escape"; + c_tag = "Aft Primary Hallway Medsci"; dir = 4 }, /obj/effect/turf_decal/tile/blue{ @@ -54884,11 +53807,10 @@ /turf/open/floor/plasteel/dark, /area/science/lab) "gGy" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/obj/structure/lattice, +/obj/structure/grille/broken, +/turf/open/space, +/area/solars/port) "gGA" = ( /obj/structure/table/glass, /obj/machinery/reagentgrinder, @@ -54901,6 +53823,16 @@ }, /turf/open/floor/plasteel/white, /area/medical/chemistry) +"gHB" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/plating, +/area/maintenance/department/engine) "gHZ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -54938,6 +53870,12 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"gJV" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "gKz" = ( /obj/structure/table/wood, /obj/item/kirbyplants{ @@ -54956,6 +53894,15 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"gLv" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) "gLF" = ( /obj/machinery/vending/snack/random, /obj/effect/turf_decal/tile/neutral{ @@ -54981,6 +53928,15 @@ /obj/structure/plasticflaps/opaque, /turf/open/floor/plating, /area/maintenance/department/engine) +"gNq" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/security/brig) "gNv" = ( /obj/structure/sign/poster/contraband/random{ pixel_x = 32 @@ -55002,6 +53958,20 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"gPs" = ( +/obj/machinery/door/airlock/grunge{ + name = "Library" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/service/library) "gPV" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 @@ -55018,6 +53988,12 @@ /obj/machinery/vending/wardrobe/det_wardrobe, /turf/open/floor/plasteel/grimy, /area/security/detectives_office) +"gRo" = ( +/mob/living/simple_animal/bot/secbot/beepsky{ + name = "Officer Beepsky" + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "gSH" = ( /turf/closed/wall, /area/service/lawoffice) @@ -55047,10 +54023,13 @@ }, /turf/open/floor/plating, /area/maintenance/department/science) +"gXv" = ( +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "gXZ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/camera{ - c_tag = "Engineering Supermatter Fore"; + c_tag = "Engineering Supermatter Port"; dir = 4; network = list("ss13","engine") }, @@ -55060,6 +54039,23 @@ /obj/structure/grille, /turf/open/space/basic, /area/space/nearstation) +"gYI" = ( +/obj/structure/closet/crate, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 8; + name = "8maintenance loot spawner" + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"gZF" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) "haA" = ( /obj/structure/table, /obj/item/stack/sheet/metal/fifty, @@ -55076,6 +54072,12 @@ /obj/machinery/door/poddoor/incinerator_atmos_main, /turf/open/floor/engine/vacuum, /area/maintenance/disposal/incinerator) +"het" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "heC" = ( /obj/machinery/power/apc/highcap/five_k{ dir = 8; @@ -55106,9 +54108,8 @@ /turf/closed/wall, /area/maintenance/department/science) "hiw" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, +/obj/structure/target_stake, +/obj/item/target/syndicate, /turf/open/floor/plating, /area/maintenance/department/security/brig) "hiY" = ( @@ -55162,6 +54163,18 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) +"hlj" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) +"hlw" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "hnu" = ( /obj/machinery/button/door{ id = "lawyer_shutters"; @@ -55239,13 +54252,16 @@ /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "hwj" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible{ - dir = 4 +/obj/machinery/door/airlock/security/glass{ + name = "Long-Term Cell 2"; + req_access_txt = "2" }, -/obj/structure/window/reinforced, -/obj/machinery/portable_atmospherics/canister/toxins, -/turf/open/floor/plating, -/area/security/execution/transfer) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/prison) "hxn" = ( /obj/structure/chair, /obj/item/clothing/glasses/regular, @@ -55265,6 +54281,19 @@ /obj/structure/lattice/catwalk, /turf/open/space/basic, /area/space/nearstation) +"hyn" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/space, +/area/solars/port) "hzc" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -55282,18 +54311,48 @@ /turf/open/floor/plating, /area/maintenance/department/engine) "hzd" = ( -/obj/structure/cable{ - icon_state = "4-8" +/obj/machinery/door/airlock/maintenance/abandoned{ + name = "Firing Range Target" }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, +/area/maintenance/department/security/brig) +"hBa" = ( +/obj/machinery/light{ dir = 8 }, -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance"; - req_access_txt = "10; 13" +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/flasher{ + id = "brigentry"; + pixel_x = -28 }, -/turf/open/floor/plating, -/area/maintenance/solars/port) +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/brig) +"hBu" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) +"hCn" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/open/floor/plasteel/dark, +/area/security/brig) "hDG" = ( /obj/machinery/door/airlock/engineering{ name = "Auxillary Base Construction"; @@ -55325,6 +54384,16 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"hGp" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/brig) "hGB" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 @@ -55363,9 +54432,25 @@ /turf/open/floor/engine, /area/engineering/supermatter) "hKX" = ( -/obj/machinery/space_heater, +/obj/structure/sign/warning{ + pixel_y = 32 + }, +/obj/structure/sign/warning{ + pixel_y = -32 + }, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"hMg" = ( +/obj/machinery/power/solar_control{ + dir = 4; + id = "portsolar"; + name = "Port Solar Control" + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/maintenance/solars/port) "hMx" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible, /turf/open/floor/plating{ @@ -55373,15 +54458,12 @@ }, /area/maintenance/department/science) "hOx" = ( -/obj/structure/cable{ - icon_state = "2-4" +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 }, /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, /turf/open/floor/plating, /area/maintenance/department/security/brig) "hOz" = ( @@ -55484,7 +54566,7 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, /turf/open/floor/plasteel/dark, /area/science/xenobiology) "hVx" = ( @@ -55602,11 +54684,11 @@ /turf/open/floor/plasteel/white, /area/science/xenobiology) "ijF" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "1-2" +/obj/structure/bookcase/random/nonfiction, +/obj/machinery/light/small{ + dir = 1 }, -/turf/open/floor/carpet, +/turf/open/floor/plasteel/dark, /area/service/library) "ijU" = ( /obj/effect/spawner/lootdrop/organ_spawner, @@ -55692,6 +54774,10 @@ }, /turf/open/floor/plasteel, /area/engineering/main) +"ipv" = ( +/obj/structure/chair/wood/normal, +/turf/open/floor/carpet, +/area/service/library) "iqc" = ( /turf/open/floor/plasteel/stairs/right, /area/maintenance/department/crew_quarters/dorms) @@ -55702,6 +54788,23 @@ }, /turf/open/floor/plasteel, /area/engineering/main) +"isH" = ( +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/machinery/door/airlock/security/glass{ + id_tag = "outerbrig"; + name = "Brig"; + req_access_txt = "63" + }, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/brig) "itl" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -55717,6 +54820,10 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"ito" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/open/floor/plasteel, +/area/security/brig) "iuM" = ( /obj/machinery/door/window/southleft{ dir = 8; @@ -55738,19 +54845,16 @@ /turf/open/floor/plasteel/dark, /area/science/xenobiology) "ivO" = ( +/obj/structure/chair/office/dark{ + dir = 1 + }, +/obj/effect/landmark/start/security_officer, +/obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 4 }, -/mob/living/simple_animal/bot/secbot{ - arrest_type = 1; - health = 45; - icon_state = "secbot1"; - idcheck = 1; - name = "Sergeant-at-Armsky"; - weaponscheck = 1 - }, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) +/turf/open/floor/plasteel, +/area/security/office) "iwe" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/tile/blue{ @@ -55761,6 +54865,9 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/aft) +"iye" = ( +/turf/closed/wall, +/area/service/chapel/asteroid/monastery) "iyg" = ( /obj/structure/cable{ icon_state = "1-2" @@ -55777,6 +54884,16 @@ }, /turf/open/floor/plasteel/dark, /area/engineering/main) +"iyL" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/closed/wall, +/area/service/library/lounge) +"iyP" = ( +/obj/structure/disposaloutlet, +/turf/open/floor/plating, +/area/space/nearstation) "izB" = ( /obj/machinery/door/airlock/external{ name = "Escape Pod" @@ -55787,11 +54904,17 @@ /turf/open/floor/plating, /area/commons/dorms) "izF" = ( -/obj/structure/closet/emcloset, -/turf/open/floor/plasteel/white{ - heat_capacity = 1e+006 +/obj/structure/cable{ + icon_state = "2-8" }, -/area/service/chapel/dock) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "iAx" = ( /obj/structure/cable{ icon_state = "4-8" @@ -55831,12 +54954,27 @@ /turf/open/floor/plasteel/dark, /area/engineering/main) "iCV" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 10 +/obj/machinery/light/small{ + dir = 1 }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/turf/open/floor/plating, -/area/security/execution/transfer) +/obj/machinery/button/door{ + id = "permabolt2"; + name = "Cell Bolt Control"; + normaldoorcontrol = 1; + pixel_y = 25; + specialfunctions = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/structure/chair, +/turf/open/floor/plasteel, +/area/security/prison) +"iEP" = ( +/obj/structure/table/wood/fancy, +/obj/item/storage/fancy/candle_box, +/turf/open/floor/carpet, +/area/service/library) "iEQ" = ( /obj/structure/table, /obj/item/storage/box/lights/mixed, @@ -55846,6 +54984,17 @@ /obj/effect/spawner/lootdrop/keg, /turf/open/floor/plating, /area/maintenance/department/crew_quarters/dorms) +"iEX" = ( +/obj/machinery/power/apc{ + dir = 1; + name = "Brig Maintenance APC"; + pixel_y = 23 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "iFI" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -55854,11 +55003,16 @@ /turf/open/floor/plasteel, /area/engineering/main) "iGJ" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 +/obj/machinery/door/airlock/medical/glass{ + id_tag = "MedbayFoyer"; + name = "Paramedic's Office"; + req_access_txt = "5;6;12;64" }, -/turf/open/floor/plasteel/white, -/area/medical/medbay/zone3) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/trimline/blue/filled, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/medical/paramedic) "iJi" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 @@ -55887,27 +55041,24 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "iLR" = ( -/obj/structure/table, -/obj/structure/bedsheetbin, -/obj/effect/turf_decal/tile/blue{ - dir = 4 +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/cable{ + icon_state = "4-8" }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/structure/window/reinforced, -/obj/machinery/light/small{ - dir = 4 - }, -/turf/open/floor/plasteel/cafeteria, -/area/security/prison) +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "iPj" = ( /obj/machinery/igniter{ id = "xenoigniter"; luminosity = 2 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/engine, /area/science/xenobiology) +"iPu" = ( +/obj/structure/plasticflaps/opaque, +/turf/open/floor/plating, +/area/medical/medbay/central) "iPz" = ( /obj/structure/extinguisher_cabinet{ pixel_x = -24 @@ -55932,17 +55083,17 @@ /turf/open/floor/plasteel/dark, /area/science/xenobiology) "iPH" = ( -/obj/machinery/vr_sleeper{ - dir = 8 +/obj/structure/cable{ + icon_state = "2-4" }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 +/obj/structure/cable{ + icon_state = "4-8" }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 }, -/turf/open/floor/plasteel/cafeteria, -/area/security/prison) +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "iPO" = ( /obj/machinery/door/poddoor/shutters{ id = "aux_base_shutters"; @@ -55953,20 +55104,11 @@ /turf/open/floor/plasteel, /area/construction/mining/aux_base) "iPU" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 5 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 9 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plating, -/area/security/execution/transfer) +/turf/closed/wall, +/area/security/prison) "iSz" = ( /obj/structure/cable{ icon_state = "2-8" @@ -55983,6 +55125,13 @@ /obj/structure/sign/warning/electricshock, /turf/closed/wall/r_wall, /area/engineering/supermatter) +"iUy" = ( +/obj/structure/window/reinforced{ + dir = 1; + pixel_y = 1 + }, +/turf/open/space/basic, +/area/space/nearstation) "iVJ" = ( /obj/effect/spawner/lootdrop/organ_spawner, /turf/open/floor/plating{ @@ -56001,29 +55150,55 @@ icon_state = "panelscorched" }, /area/maintenance/department/chapel/monastery) +"iYp" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) +"iYQ" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "jcT" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"jee" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/closed/wall, +/area/service/library/lounge) "jen" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/turf/open/floor/plasteel, -/area/security/brig) +/turf/closed/wall/r_wall, +/area/security/courtroom) "jeq" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -56038,17 +55213,33 @@ dir = 1 }, /area/hallway/secondary/exit/departure_lounge) -"jgr" = ( -/obj/machinery/door/airlock/grunge{ - name = "Library" +"jfY" = ( +/obj/structure/chair{ + dir = 1; + name = "Prosecution" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ +/obj/effect/turf_decal/tile/red{ dir = 1 }, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel/dark, -/area/service/library) +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_y = -26 + }, +/turf/open/floor/plasteel, +/area/security/courtroom) +"jgr" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "jhk" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -56071,6 +55262,23 @@ icon_state = "platingdmg3" }, /area/maintenance/department/crew_quarters/dorms) +"jiC" = ( +/obj/structure/table/reinforced, +/obj/item/pen, +/obj/machinery/door/poddoor/preopen{ + id = "Secure Gate"; + name = "brig shutters" + }, +/obj/machinery/door/window/southleft{ + base_state = "right"; + dir = 1; + icon_state = "right"; + name = "Brig Desk"; + req_access_txt = "1" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/security/brig) "jjC" = ( /obj/structure/rack, /obj/item/storage/briefcase{ @@ -56087,6 +55295,34 @@ /obj/machinery/atmospherics/components/binary/pump, /turf/closed/wall/r_wall, /area/tcommsat/computer) +"jmt" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Brig Desk"; + req_access_txt = "1" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/security/brig) +"jnR" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) +"jqZ" = ( +/obj/structure/table/wood, +/obj/item/paper_bin{ + layer = 2.9; + pixel_x = -2; + pixel_y = 4 + }, +/obj/item/pen, +/turf/open/floor/plasteel/dark, +/area/service/library) "jrG" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -56105,7 +55341,9 @@ /turf/open/floor/plasteel, /area/engineering/main) "jsf" = ( -/obj/item/toy/katana, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plating, /area/maintenance/department/security/brig) "jsj" = ( @@ -56118,6 +55356,24 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel/white, /area/medical/treatment_center) +"jsl" = ( +/obj/structure/sign/warning/vacuum/external{ + pixel_y = 32 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating, +/area/service/chapel/main/monastery) +"jst" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/security/brig) "jsD" = ( /obj/structure/sign/plaques/deempisi{ pixel_y = 28 @@ -56141,29 +55397,27 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"jtB" = ( +/obj/structure/closet/crate, +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "juw" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) +/turf/open/floor/plasteel, +/area/security/office) "jvi" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/firealarm{ - dir = 1; - pixel_y = -26 - }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/effect/turf_decal/tile/red{ dir = 1 }, /obj/effect/turf_decal/tile/red{ - dir = 4 + dir = 8 }, -/turf/open/floor/plasteel/dark, -/area/command/heads_quarters/hos) +/turf/open/floor/plasteel, +/area/security/brig) "jvO" = ( /obj/machinery/atmospherics/pipe/simple/orange/visible, /turf/closed/wall/r_wall, @@ -56194,19 +55448,36 @@ /turf/open/floor/plasteel/dark, /area/science/xenobiology) "jxK" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +/obj/structure/table/wood, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/obj/effect/turf_decal/tile/blue{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/item/book/manual/wiki/security_space_law, +/turf/open/floor/plasteel, +/area/security/courtroom) +"jzw" = ( +/obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/structure/cable{ - icon_state = "4-8" +/obj/effect/turf_decal/tile/neutral{ + dir = 1 }, -/turf/open/floor/plasteel, -/area/security/brig) +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "jzz" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/sign/warning/vacuum/external, @@ -56283,12 +55554,28 @@ /turf/open/floor/plating, /area/maintenance/department/science) "jFO" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/airlock/security{ + name = "Brig Control"; + req_access_txt = "3" + }, /obj/structure/cable{ icon_state = "1-2" }, -/turf/open/floor/carpet, -/area/service/library/lounge) +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/showroomfloor, +/area/security/warden) +"jHl" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) "jHP" = ( /obj/structure/table, /obj/item/reagent_containers/food/drinks/bottle/vodka/badminka{ @@ -56329,8 +55616,17 @@ }, /turf/open/floor/plating, /area/maintenance/department/science) +"jRI" = ( +/obj/structure/girder, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/security/brig) "jSa" = ( /obj/machinery/door/airlock/maintenance, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, /turf/open/floor/plating, /area/service/chapel/main/monastery) "jTh" = ( @@ -56354,6 +55650,9 @@ }, /turf/open/floor/carpet, /area/service/lawoffice) +"jTx" = ( +/turf/open/floor/plasteel, +/area/security/courtroom) "jTU" = ( /obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/structure/cable/yellow{ @@ -56373,9 +55672,25 @@ }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) +"jVB" = ( +/obj/effect/decal/cleanable/cobweb{ + icon_state = "cobweb2" + }, +/obj/item/stack/sheet/metal{ + amount = 20; + layer = 3.1 + }, +/obj/item/stack/sheet/glass/fifty{ + layer = 4 + }, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "jXh" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 +/obj/structure/chair/wood/normal{ + dir = 1 + }, +/obj/structure/sign/painting/library{ + pixel_x = -32 }, /turf/open/floor/plasteel/dark, /area/service/library/lounge) @@ -56385,11 +55700,8 @@ /turf/open/floor/plating, /area/maintenance/department/science) "jXF" = ( -/obj/machinery/cryopod{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) +/turf/closed/wall, +/area/security/office) "jXV" = ( /obj/machinery/light/small{ dir = 1 @@ -56414,6 +55726,12 @@ icon_state = "platingdmg3" }, /area/maintenance/department/engine) +"jYO" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/courtroom) "jZG" = ( /obj/machinery/door/poddoor/shutters/preopen{ id = "chemistry_shutters"; @@ -56422,6 +55740,19 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/medical/chemistry) +"jZZ" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/vehicle/ridden/wheelchair/motorized{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/central) "kas" = ( /obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 @@ -56432,6 +55763,13 @@ /obj/effect/turf_decal/tile/yellow, /turf/open/floor/plasteel, /area/engineering/atmos) +"kau" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/brig) "kaR" = ( /obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ dir = 8 @@ -56467,6 +55805,19 @@ }, /turf/open/floor/plasteel, /area/science/mixing) +"kix" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) +"kjp" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Courtroom" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/security/courtroom) "kjK" = ( /obj/machinery/door/airlock/maintenance_hatch{ name = "MiniSat Maintenance"; @@ -56535,12 +55886,37 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/aft) +"kpi" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "kpK" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, /turf/open/floor/plating, /area/maintenance/department/engine) +"kqF" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plating, +/area/maintenance/solars/port) +"kro" = ( +/obj/structure/sign/painting/library{ + pixel_x = -32 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "krU" = ( /obj/structure/chair{ dir = 4 @@ -56635,6 +56011,12 @@ }, /turf/open/floor/plasteel/dark, /area/hallway/secondary/exit/departure_lounge) +"kAX" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/office) "kDf" = ( /obj/machinery/light/small, /turf/open/floor/carpet/black, @@ -56671,6 +56053,13 @@ /obj/structure/table, /turf/open/floor/plasteel, /area/service/hydroponics) +"kFd" = ( +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) "kFm" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -56742,25 +56131,45 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "kJo" = ( -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, -/area/maintenance/department/security/brig) +/area/maintenance/department/chapel/monastery) "kJw" = ( -/obj/machinery/door/airlock/maintenance/abandoned{ - name = "Firing Range Target" - }, -/turf/open/floor/plating{ - icon_state = "platingdmg3" +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 }, +/turf/closed/wall, /area/maintenance/department/security/brig) +"kJN" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/office) +"kKB" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) "kKI" = ( /obj/effect/spawner/lootdrop/maintenance, /obj/structure/closet, /turf/open/floor/plating, /area/maintenance/department/cargo) +"kMf" = ( +/obj/machinery/atmospherics/pipe/manifold/general/hidden{ + dir = 1 + }, +/obj/machinery/meter, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "kNf" = ( /obj/machinery/door/window/northleft{ base_state = "right"; @@ -56777,6 +56186,15 @@ }, /turf/open/floor/engine, /area/science/xenobiology) +"kOW" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, +/area/service/library/lounge) "kPi" = ( /obj/structure/table, /obj/machinery/microwave, @@ -56791,6 +56209,12 @@ icon_state = "platingdmg3" }, /area/maintenance/department/science) +"kPt" = ( +/obj/structure/chair/stool, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/security/brig) "kQy" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -56803,6 +56227,12 @@ }, /turf/open/floor/plasteel/white, /area/medical/treatment_center) +"kQH" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "kQZ" = ( /obj/structure/closet, /obj/item/stack/spacecash/c10, @@ -56813,6 +56243,12 @@ "kRq" = ( /turf/open/floor/plasteel, /area/maintenance/department/engine) +"kRH" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/courtroom) "kRK" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible, /obj/machinery/portable_atmospherics/canister/bz, @@ -56827,6 +56263,26 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"kRY" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "kSb" = ( /obj/structure/chair/office/light{ dir = 8 @@ -56836,6 +56292,24 @@ }, /turf/open/floor/plasteel/white, /area/science/lab) +"kSC" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/obj/machinery/door_timer{ + id = "Cell 2"; + name = "Cell 2"; + pixel_y = -32 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/brig) "kSF" = ( /obj/structure/cable{ icon_state = "1-4" @@ -56853,7 +56327,11 @@ /area/engineering/main) "kSO" = ( /obj/machinery/door/airlock/maintenance{ - name = "Port Emergency Storage" + name = "Port Emergency Storage"; + req_access_txt = "5;6;12;64" + }, +/obj/structure/cable{ + icon_state = "4-8" }, /turf/open/floor/plating, /area/commons/storage/emergency/port) @@ -56904,7 +56382,6 @@ /turf/open/floor/engine, /area/engineering/main) "kXx" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -56915,9 +56392,10 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/obj/item/kirbyplants{ - icon_state = "plant-10" +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark, /area/service/chapel/main/monastery) "kYM" = ( @@ -56934,8 +56412,27 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/aft) +"kZk" = ( +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/security/brig) +"kZF" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, +/area/maintenance/department/security/brig) +"lac" = ( +/obj/structure/disposalpipe/segment, +/turf/open/space/basic, +/area/space) "lcU" = ( -/obj/effect/turf_decal/stripes/line{ +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 5 }, /turf/open/floor/plating, @@ -56949,18 +56446,9 @@ /turf/open/floor/plating, /area/maintenance/department/science) "lem" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/flasher{ - id = "executionflash"; - pixel_y = 25 - }, -/obj/machinery/igniter{ - id = "secigniter" - }, -/turf/open/floor/plating, -/area/security/execution/transfer) +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/open/floor/plasteel/dark, +/area/security/prison) "lfx" = ( /obj/structure/table, /obj/item/clothing/suit/hooded/wintercoat/engineering, @@ -56974,6 +56462,11 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/engineering/main) +"lhq" = ( +/obj/machinery/computer/security, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/security/brig) "lhA" = ( /obj/machinery/atmospherics/pipe/manifold/general/visible, /turf/open/floor/plasteel/dark, @@ -56992,6 +56485,18 @@ /obj/machinery/atmospherics/pipe/simple/general/hidden, /turf/open/floor/plating, /area/maintenance/department/cargo) +"llx" = ( +/obj/docking_port/stationary{ + dir = 8; + dwidth = 2; + height = 5; + id = "laborcamp_home"; + name = "fore bay 1"; + roundstart_template = /datum/map_template/shuttle/labour/box; + width = 9 + }, +/turf/open/space/basic, +/area/space) "lms" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 @@ -57038,19 +56543,9 @@ /turf/open/floor/engine, /area/engineering/main) "lqc" = ( -/obj/item/toy/gun, -/obj/effect/decal/cleanable/oil, +/obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, -/area/maintenance/department/security/brig) -"lqy" = ( -/obj/machinery/door/airlock/grunge{ - name = "Library" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel/dark, -/area/service/library/lounge) +/area/security/brig) "lrM" = ( /obj/structure/cable{ icon_state = "2-8" @@ -57058,16 +56553,31 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/engineering/main) -"lxI" = ( -/obj/effect/landmark/xeno_spawn, -/turf/open/floor/plating{ - icon_state = "platingdmg1" +"lsz" = ( +/obj/structure/chair{ + dir = 4; + name = "Bailiff" }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/courtroom) +"lxI" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, /area/maintenance/department/chapel/monastery) "lzJ" = ( /obj/structure/closet/crate/bin, /turf/open/floor/carpet, /area/service/chapel/office) +"lzT" = ( +/obj/structure/sign/painting/library{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "lAf" = ( /obj/machinery/light/small{ dir = 1 @@ -57075,9 +56585,38 @@ /obj/effect/turf_decal/tile/yellow, /turf/open/floor/plasteel/dark, /area/service/chapel/office) +"lAj" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/brig) +"lAn" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security/glass{ + name = "Labor Camp Shuttle Airlock" + }, +/turf/open/floor/plasteel/dark, +/area/security/brig) "lAs" = ( /turf/closed/wall, /area/cargo/sorting) +"lAL" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/office) "lAR" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -57101,6 +56640,12 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/engine, /area/science/xenobiology) +"lEh" = ( +/obj/structure/bookcase{ + name = "Forbidden Knowledge" + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "lEn" = ( /obj/structure/window/reinforced{ dir = 1 @@ -57120,9 +56665,11 @@ /turf/open/floor/plasteel/dark, /area/science/xenobiology) "lGp" = ( -/obj/structure/weightmachine/weightlifter, +/obj/item/kirbyplants{ + icon_state = "plant-22" + }, /turf/open/floor/plasteel/dark, -/area/security/prison) +/area/security/office) "lGv" = ( /obj/machinery/door/airlock/atmos/abandoned{ name = "Atmospherics Maintenance"; @@ -57146,12 +56693,9 @@ /turf/open/floor/plasteel/dark, /area/science/xenobiology) "lHc" = ( -/obj/structure/girder, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/obj/machinery/computer/shuttle/labor, +/turf/open/floor/plasteel/dark, +/area/security/brig) "lHX" = ( /obj/structure/bed, /obj/item/bedsheet/orange, @@ -57190,9 +56734,11 @@ /turf/open/floor/plating, /area/commons/storage/emergency/starboard) "lMU" = ( -/obj/effect/spawner/lootdrop/maintenance, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, /obj/structure/cable{ - icon_state = "4-8" + icon_state = "1-4" }, /turf/open/floor/plating, /area/maintenance/department/security/brig) @@ -57210,6 +56756,12 @@ }, /turf/open/floor/plating, /area/maintenance/department/science) +"lQo" = ( +/obj/machinery/newscaster{ + pixel_x = 32 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "lQQ" = ( /obj/machinery/door/poddoor/preopen{ id = "bridgespace"; @@ -57235,6 +56787,15 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) +"lTx" = ( +/obj/structure/sign/departments/security{ + pixel_y = 32 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) "lTC" = ( /obj/item/shard, /obj/effect/turf_decal/stripes/line{ @@ -57245,6 +56806,10 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) +"lUz" = ( +/obj/structure/girder, +/turf/open/floor/plating, +/area/maintenance/fore) "lUO" = ( /obj/structure/sign/warning/radiation, /turf/closed/wall/r_wall, @@ -57281,16 +56846,37 @@ /turf/open/floor/engine, /area/engineering/main) "lXc" = ( -/obj/structure/table, -/obj/item/clothing/head/beret, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 8; + name = "8maintenance loot spawner" + }, +/obj/structure/closet/crate, /turf/open/floor/plating, -/area/maintenance/department/security/brig) +/area/maintenance/fore) +"lXd" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel, +/area/security/brig) "lXt" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, /turf/open/floor/engine, /area/science/xenobiology) +"lXv" = ( +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/maintenance/fore) "lXJ" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 4 @@ -57342,6 +56928,20 @@ /obj/machinery/portable_atmospherics/canister/toxins, /turf/open/floor/plating, /area/engineering/main) +"mcB" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/engine) "mdL" = ( /obj/structure/table, /obj/item/paper_bin, @@ -57355,6 +56955,18 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/white, /area/science/lab) +"mdS" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/security/brig) "meF" = ( /obj/machinery/status_display/evac, /turf/closed/wall/r_wall, @@ -57430,6 +57042,15 @@ }, /turf/open/floor/plating, /area/science/xenobiology) +"mlt" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/brig) "mmv" = ( /obj/machinery/door/airlock/engineering{ name = "Engineering Supplies"; @@ -57490,25 +57111,56 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/aft) -"msX" = ( -/obj/effect/spawner/structure/window/reinforced, +"mqS" = ( /obj/structure/cable{ - icon_state = "0-4" + icon_state = "1-2" }, -/obj/machinery/door/poddoor/preopen{ - id = "executionfireblast" +/obj/machinery/light, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plating, -/area/security/execution/transfer) -"mtu" = ( +/obj/machinery/door_timer{ + id = "Cell 1"; + name = "Cell 1"; + pixel_y = -32 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/security/brig) +"mrk" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/plating{ + icon_state = "platingdmg1" + }, +/area/maintenance/department/security/brig) +"msX" = ( /obj/structure/table, -/obj/item/folder/yellow, -/obj/item/reagent_containers/food/snacks/donut, +/obj/item/paper, +/obj/item/pen, +/turf/open/floor/plasteel, +/area/security/prison) +"mtu" = ( /obj/machinery/light/small{ dir = 4 }, -/turf/closed/wall, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plating, /area/maintenance/department/security/brig) "mtI" = ( /obj/structure/cable{ @@ -57545,13 +57197,9 @@ /turf/open/floor/plating, /area/maintenance/solars/starboard) "mwg" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" +/obj/effect/turf_decal/stripes/line{ + dir = 10 }, -/obj/item/ammo_box/foambox, -/obj/item/ammo_box/foambox, -/obj/item/gun/ballistic/shotgun/toy, -/obj/item/gun/ballistic/shotgun/toy, /turf/open/floor/plating, /area/maintenance/department/security/brig) "mwG" = ( @@ -57600,11 +57248,6 @@ }, /turf/open/floor/plasteel/dark, /area/command/bridge) -"mzl" = ( -/obj/structure/chair, -/obj/machinery/atmospherics/components/unary/outlet_injector/on, -/turf/open/floor/plating, -/area/security/execution/transfer) "mzE" = ( /obj/machinery/portable_atmospherics/canister/toxins, /obj/effect/turf_decal/delivery, @@ -57625,6 +57268,12 @@ }, /turf/open/floor/plasteel, /area/engineering/atmos) +"mAU" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/structure/table/wood, +/obj/item/folder/blue, +/turf/open/floor/plasteel, +/area/security/courtroom) "mCe" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/preopen{ @@ -57633,6 +57282,22 @@ }, /turf/open/floor/plating, /area/security/checkpoint/engineering) +"mDs" = ( +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/machinery/power/apc{ + dir = 1; + name = "Port Solar APC"; + pixel_y = 23 + }, +/obj/machinery/camera{ + c_tag = "Port Bow Solar"; + dir = 9; + name = "solar camera" + }, +/turf/open/floor/plating, +/area/maintenance/solars/port) "mDW" = ( /obj/machinery/power/smes{ charge = 5e+006 @@ -57640,6 +57305,10 @@ /obj/structure/cable, /turf/open/floor/plating, /area/tcommsat/computer) +"mEe" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "mEu" = ( /obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 @@ -57656,19 +57325,48 @@ }, /turf/open/floor/plating, /area/maintenance/department/science) +"mFw" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Medbay Recovery Room"; + dir = 1; + network = list("ss13","medbay") + }, +/obj/machinery/light_switch{ + pixel_y = -22 + }, +/turf/open/floor/plasteel/dark, +/area/medical/surgery) +"mGa" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/navbeacon{ + codes_txt = "patrol;next_patrol=BrigS2"; + location = "BrigP" + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) "mHy" = ( /obj/item/storage/fancy/cigarettes/cigpack_shadyjims, /turf/open/floor/wood, /area/maintenance/department/engine) "mIa" = ( -/obj/structure/disposalpipe/segment{ - dir = 10 - }, /obj/machinery/light/small{ dir = 8 }, +/obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/maintenance/department/engine) +"mIO" = ( +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "mJp" = ( /obj/structure/lattice, /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ @@ -57680,8 +57378,11 @@ /turf/open/water/decorative, /area/hallway/secondary/entry) "mKc" = ( -/obj/structure/bookcase/random/nonfiction, -/turf/open/floor/plasteel/dark, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, /area/service/library/lounge) "mKk" = ( /obj/structure/cable{ @@ -57689,16 +57390,17 @@ }, /turf/open/floor/plating/airless, /area/space/nearstation) +"mKP" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "mLB" = ( -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/turf/open/floor/plating{ - icon_state = "platingdmg1" +/obj/effect/turf_decal/stripes/line{ + dir = 6 }, +/turf/open/floor/plating, /area/maintenance/department/security/brig) "mMz" = ( /obj/effect/spawner/structure/window/reinforced, @@ -57737,16 +57439,48 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"mUU" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "mVM" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating/airless, /area/space/nearstation) +"mWN" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "mXq" = ( /obj/item/taperecorder, /obj/item/cartridge/lawyer, /obj/structure/table/wood, /turf/open/floor/wood, /area/service/lawoffice) +"mXJ" = ( +/obj/structure/table/wood/fancy, +/turf/open/floor/carpet, +/area/service/library) "mZE" = ( /turf/open/space/basic, /area/space/nearstation) @@ -57830,11 +57564,28 @@ /obj/item/chair/stool, /turf/open/floor/carpet, /area/maintenance/department/crew_quarters/dorms) +"ngq" = ( +/obj/structure/closet/secure_closet/courtroom, +/obj/structure/extinguisher_cabinet{ + pixel_y = -32 + }, +/obj/item/gavelhammer, +/obj/machinery/light_switch{ + pixel_x = -26; + pixel_y = 26 + }, +/turf/open/floor/plasteel, +/area/security/courtroom) "nih" = ( /obj/structure/closet, /obj/effect/spawner/lootdrop/costume, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"nix" = ( +/obj/structure/lattice, +/obj/structure/lattice, +/turf/closed/mineral, +/area/service/chapel/asteroid/monastery) "niy" = ( /obj/structure/table, /obj/item/reagent_containers/food/snacks/cookie, @@ -57853,6 +57604,11 @@ }, /turf/open/floor/plasteel/dark, /area/hallway/secondary/exit/departure_lounge) +"njI" = ( +/obj/structure/table/wood, +/obj/machinery/computer/libraryconsole/bookmanagement, +/turf/open/floor/plasteel/dark, +/area/service/library) "nku" = ( /obj/machinery/door/airlock/centcom{ name = "Crematorium"; @@ -57899,6 +57655,10 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"nso" = ( +/obj/structure/girder, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "nsy" = ( /obj/structure/table, /obj/item/stack/sheet/metal/fifty, @@ -57958,6 +57718,33 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"nwp" = ( +/obj/machinery/button/door{ + id = "prison release"; + name = "Labor Camp Shuttle Lockdown"; + pixel_x = -25; + req_access_txt = "2" + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) +"nxf" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/security/brig) "nxT" = ( /obj/machinery/smartfridge/extract/preloaded, /turf/open/floor/plasteel, @@ -58037,6 +57824,40 @@ }, /turf/open/floor/plasteel/dark, /area/hallway/secondary/exit/departure_lounge) +"nDM" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/window/southleft{ + base_state = "right"; + dir = 1; + icon_state = "right"; + name = "Brig Desk"; + req_access_txt = "1" + }, +/obj/machinery/door/poddoor/preopen{ + id = "Secure Gate"; + name = "brig shutters" + }, +/obj/item/radio, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/security/brig) +"nDP" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/brig) "nEb" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -58089,6 +57910,25 @@ }, /turf/open/floor/plasteel/white, /area/science/lab) +"nJG" = ( +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/machinery/door/airlock/security/glass{ + id_tag = "outerbrig"; + name = "Brig"; + req_access_txt = "63" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/brig) "nJI" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible, /obj/structure/sign/plaques/kiddie/perfect_drone{ @@ -58097,10 +57937,12 @@ /turf/open/floor/engine, /area/science/explab) "nKo" = ( -/obj/structure/lattice, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "nLl" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -58156,6 +57998,25 @@ }, /turf/open/floor/plating/airless, /area/space/nearstation) +"nOF" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "nOY" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -58172,7 +58033,12 @@ /turf/open/floor/plasteel/dark, /area/science/xenobiology) "nPA" = ( -/obj/item/chair, +/obj/machinery/door/airlock/maintenance{ + req_access_txt = "12" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plating, /area/maintenance/department/security/brig) "nQc" = ( @@ -58211,6 +58077,26 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/aft) +"nUc" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/machinery/camera{ + c_tag = "Brig Gulag Teleporter"; + dir = 4 + }, +/obj/machinery/light{ + dir = 8 + }, +/obj/structure/table, +/obj/item/storage/box/prisoner, +/obj/item/razor{ + pixel_x = -6 + }, +/obj/item/paper/guides/jobs/security/labor_camp, +/obj/item/pen, +/turf/open/floor/plasteel/dark, +/area/security/brig) "nUQ" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/engine, @@ -58219,10 +58105,33 @@ /obj/item/spear, /turf/open/floor/plating, /area/maintenance/department/engine) +"nWD" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/door/window/northright{ + dir = 2; + name = "Curator Desk Door"; + req_access_txt = "37" + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "nWP" = ( /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plating, /area/maintenance/department/engine) +"nXR" = ( +/obj/structure/table/wood/fancy, +/obj/item/flashlight/lantern{ + icon_state = "lantern-on"; + pixel_y = 8 + }, +/turf/open/floor/carpet, +/area/service/library) "nYb" = ( /obj/structure/table_frame/wood, /turf/open/floor/wood, @@ -58232,6 +58141,21 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/hallway/secondary/exit/departure_lounge) +"nYq" = ( +/obj/structure/rack, +/obj/item/gun/energy/laser/practice, +/obj/item/clothing/ears/earmuffs, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"nYC" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/sign/painting/library{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "nZw" = ( /obj/machinery/door/airlock/abandoned{ name = "Backup Laboratory" @@ -58259,11 +58183,15 @@ /obj/item/pen, /turf/open/floor/plating, /area/maintenance/department/science) -"odM" = ( -/obj/effect/landmark/barthpot, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, +"odz" = ( +/obj/structure/table/wood/fancy, +/obj/item/storage/photo_album, /turf/open/floor/carpet, -/area/service/library/lounge) +/area/service/library) +"odM" = ( +/obj/structure/reagent_dispensers/watertank, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "oep" = ( /obj/structure/table/glass, /obj/item/paper_bin, @@ -58277,6 +58205,12 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"ofi" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating, +/area/maintenance/solars/port) "ofN" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/tile/blue, @@ -58311,6 +58245,16 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) +"onE" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = 28 + }, +/turf/open/floor/plasteel/dark, +/area/security/courtroom) "onX" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ @@ -58334,6 +58278,13 @@ /obj/item/wrench/medical, /turf/open/floor/engine, /area/medical/chemistry) +"opr" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/brig) "opz" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 1 @@ -58380,6 +58331,12 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"osW" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/brig) "osY" = ( /obj/structure/flora/ausbushes/reedbush{ pixel_x = -2; @@ -58408,26 +58365,35 @@ dir = 4 }, /turf/open/floor/plating/airless, -/area/space/nearstation) +/area/maintenance/department/engine) +"ouy" = ( +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "ovB" = ( -/obj/effect/turf_decal/tile/blue{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ dir = 4 }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 +/obj/structure/cable{ + icon_state = "1-2" }, -/turf/open/floor/plasteel/cafeteria, -/area/security/prison) +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/security/brig) "ovM" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, /obj/machinery/camera{ c_tag = "Arrivals Port Fore" }, /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/white/corner{ dir = 1 }, @@ -58442,6 +58408,13 @@ }, /turf/open/floor/plasteel/dark, /area/service/chapel/office) +"oxo" = ( +/obj/structure/bookcase/random/religion, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "oxw" = ( /obj/structure/cable/yellow{ icon_state = "4-8" @@ -58455,6 +58428,7 @@ /area/commons/storage/primary) "ozO" = ( /obj/machinery/door/airlock/maintenance, +/obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/maintenance/department/engine) "oAw" = ( @@ -58484,6 +58458,12 @@ /obj/effect/landmark/start/lawyer, /turf/open/floor/carpet, /area/service/lawoffice) +"oCG" = ( +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/closed/wall/mineral/iron, +/area/service/chapel/main/monastery) "oCX" = ( /obj/structure/cable{ icon_state = "4-8" @@ -58532,14 +58512,12 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "oFf" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/light/small{ - dir = 1 +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-8" }, /turf/open/floor/plating, -/area/maintenance/department/security/brig) +/area/security/warden) "oFo" = ( /obj/structure/closet/emcloset/anchored, /obj/structure/sign/warning/vacuum/external{ @@ -58562,6 +58540,12 @@ icon_state = "platingdmg3" }, /area/maintenance/disposal/incinerator) +"oGX" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/maintenance/solars/port) "oHa" = ( /obj/machinery/power/emitter/anchored{ dir = 8; @@ -58572,6 +58556,22 @@ }, /turf/open/floor/plating, /area/engineering/main) +"oHk" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, +/area/service/library/lounge) +"oIU" = ( +/obj/structure/table/wood, +/obj/item/folder/yellow, +/obj/item/pen, +/turf/open/floor/plasteel/dark, +/area/service/library) "oKa" = ( /obj/structure/rack, /obj/effect/spawner/lootdrop/maintenance{ @@ -58599,6 +58599,17 @@ }, /turf/open/floor/engine, /area/engineering/main) +"oKX" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plating{ + icon_state = "platingdmg1" + }, +/area/maintenance/department/security/brig) "oLR" = ( /obj/effect/turf_decal/tile/red{ dir = 4 @@ -58618,22 +58629,17 @@ dir = 8 }, /obj/machinery/atmospherics/components/binary/pump/on{ - dir = 3; name = "Waste to Space" }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) "oPx" = ( -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, -/area/maintenance/department/security/brig) +/obj/item/book/manual/wiki/security_space_law, +/obj/item/clothing/ears/earmuffs, +/obj/item/clothing/glasses/sunglasses, +/obj/structure/table/reinforced, +/turf/open/floor/plasteel/showroomfloor, +/area/security/warden) "oPy" = ( /obj/machinery/door/airlock/external{ name = "Mining Dock Airlock"; @@ -58644,6 +58650,11 @@ }, /turf/open/floor/plating, /area/cargo/miningdock) +"oPX" = ( +/obj/structure/lattice/catwalk, +/obj/item/stack/cable_coil, +/turf/open/space, +/area/solars/port) "oQm" = ( /obj/docking_port/stationary{ dir = 8; @@ -58656,6 +58667,16 @@ }, /turf/open/space/basic, /area/space) +"oQY" = ( +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "oRX" = ( /obj/structure/closet, /turf/open/floor/plating, @@ -58714,12 +58735,14 @@ /turf/open/floor/plating, /area/maintenance/department/security/brig) "oTC" = ( -/obj/structure/table, -/obj/item/reagent_containers/food/drinks/soda_cans/cola, +/obj/machinery/vending/cigarette, /turf/open/floor/plating{ icon_state = "platingdmg3" }, /area/maintenance/department/security/brig) +"oTF" = ( +/turf/open/floor/circuit/green, +/area/maintenance/department/security/brig) "oUa" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -58750,19 +58773,20 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) -"oXe" = ( -/obj/structure/table/glass, -/obj/item/mmi, -/obj/item/clothing/mask/balaclava, -/obj/effect/turf_decal/tile/red{ - dir = 1 +"oWD" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 }, +/turf/open/floor/plasteel/dark, +/area/service/library) +"oXe" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 }, -/turf/open/floor/plasteel/white, -/area/security/execution/transfer) +/turf/open/floor/plasteel, +/area/security/prison) "oXq" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 1; @@ -58798,12 +58822,6 @@ /turf/open/floor/plating/airless, /area/engineering/main) "pbm" = ( -/obj/machinery/door/airlock/external{ - name = "Pod Docking Bay" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, /turf/open/floor/plating, /area/service/chapel/dock) "pbI" = ( @@ -58817,9 +58835,22 @@ /turf/open/floor/engine, /area/science/xenobiology) "pdq" = ( -/obj/effect/decal/cleanable/oil, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/obj/structure/table/reinforced, +/obj/machinery/button/door{ + id = "Secure Gate"; + name = "Entrance Lockdown"; + pixel_x = 5; + pixel_y = -2 + }, +/obj/machinery/button/door{ + id = "Prison Gate"; + name = "Permabrig Lockdown"; + pixel_x = 5; + pixel_y = 8; + req_access_txt = "2" + }, +/turf/open/floor/plasteel/showroomfloor, +/area/security/warden) "pdW" = ( /obj/structure/cable{ icon_state = "1-4" @@ -58831,32 +58862,48 @@ dir = 5 }, /turf/open/floor/plating, -/area/science/explab) +/area/maintenance/department/cargo) "peE" = ( -/obj/structure/cable{ - icon_state = "1-4" - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) +/obj/structure/chair/office/dark, +/obj/effect/landmark/start/warden, +/turf/open/floor/plasteel/showroomfloor, +/area/security/warden) "pfz" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-4" +/obj/machinery/light{ + dir = 1 }, -/obj/structure/cable{ - icon_state = "0-2" +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 }, -/turf/open/floor/plating, -/area/security/execution/transfer) +/obj/machinery/button/flasher{ + id = "PCell 2"; + pixel_x = 5; + pixel_y = 24 + }, +/obj/machinery/button/door{ + id = "permacell2"; + name = "Cell 2 Lockdown"; + pixel_x = 4; + pixel_y = 34; + req_access_txt = "2" + }, +/turf/open/floor/plasteel, +/area/security/prison) "pfB" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ dir = 4 }, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) +/turf/open/floor/plasteel, +/area/security/office) "pfP" = ( /obj/structure/table, /obj/item/storage/box/syringes, @@ -58889,15 +58936,19 @@ /turf/open/floor/plating, /area/maintenance/disposal) "pia" = ( -/obj/effect/spawner/lootdrop/maintenance, -/obj/structure/rack, -/obj/machinery/light/small{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/structure/disposalpipe/segment{ + dir = 10 }, -/turf/open/floor/plating{ - icon_state = "panelscorched" +/turf/open/floor/plasteel/showroomfloor, +/area/security/warden) +"pid" = ( +/obj/machinery/power/tracker, +/obj/structure/cable{ + icon_state = "0-4" }, -/area/maintenance/department/chapel/monastery) +/turf/open/floor/plasteel/airless/solarpanel, +/area/solars/port) "pjH" = ( /obj/structure/cable{ icon_state = "1-2" @@ -58931,6 +58982,19 @@ }, /turf/open/floor/plasteel, /area/engineering/atmos) +"pmC" = ( +/obj/structure/bed, +/obj/machinery/flasher{ + id = "Cell 2"; + pixel_x = -28 + }, +/obj/item/bedsheet/green, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/brig) "pnU" = ( /obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ dir = 4; @@ -58967,6 +59031,26 @@ }, /turf/open/floor/plating, /area/hallway/secondary/entry) +"pqR" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/space, +/area/solars/port) +"prB" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/airlock/external{ + name = "Solar Maintenance"; + req_access_txt = "10; 13" + }, +/turf/open/floor/plating, +/area/maintenance/solars/port) "prQ" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 @@ -58984,6 +59068,19 @@ /obj/structure/sign/warning/fire, /turf/closed/wall/r_wall, /area/engineering/supermatter) +"puy" = ( +/obj/structure/bed, +/obj/machinery/flasher{ + id = "Cell 1"; + pixel_x = -28 + }, +/obj/item/bedsheet/blue, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/brig) "pvK" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ @@ -59050,6 +59147,21 @@ /obj/structure/lattice/catwalk, /turf/open/space/basic, /area/space/nearstation) +"pCF" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/security/courtroom) +"pCL" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plating, +/area/maintenance/department/engine) "pDP" = ( /obj/machinery/vending/assist, /obj/effect/turf_decal/tile/neutral{ @@ -59083,6 +59195,26 @@ /obj/machinery/atmospherics/pipe/manifold/general/visible, /turf/open/floor/plasteel, /area/engineering/atmos) +"pEZ" = ( +/obj/machinery/door/window/southleft{ + base_state = "right"; + dir = 1; + icon_state = "right"; + name = "Brig Desk"; + req_access_txt = "1" + }, +/obj/item/reagent_containers/food/snacks/donut, +/obj/machinery/door/poddoor/preopen{ + id = "Secure Gate"; + name = "brig shutters" + }, +/obj/structure/table/reinforced, +/obj/item/folder/red{ + layer = 2.9 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/security/brig) "pFe" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/red{ @@ -59095,12 +59227,12 @@ /turf/open/floor/plasteel/dark, /area/service/chapel/office) "pFy" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "pGe" = ( @@ -59114,11 +59246,20 @@ /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "pHo" = ( -/obj/machinery/computer/bounty{ - dir = 1 +/obj/effect/turf_decal/tile/brown, +/obj/machinery/piratepad/civilian, +/turf/open/floor/plasteel, +/area/cargo/office) +"pJy" = ( +/obj/structure/rack, +/obj/item/crowbar, +/obj/item/wrench, +/obj/item/laser_pointer/red, +/obj/structure/cable{ + icon_state = "2-4" }, -/turf/open/floor/wood, -/area/command/heads_quarters/hop) +/turf/open/floor/plasteel/showroomfloor, +/area/security/warden) "pKd" = ( /obj/effect/spawner/lootdrop/maintenance{ lootcount = 2; @@ -59147,6 +59288,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/machinery/light_switch{ + pixel_x = -25 + }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) "pNy" = ( @@ -59191,6 +59335,13 @@ }, /turf/closed/wall/r_wall, /area/medical/virology) +"pRz" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) "pVD" = ( /obj/machinery/light/small{ dir = 1 @@ -59236,12 +59387,15 @@ /turf/open/floor/plasteel, /area/service/hydroponics) "pXc" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ - icon_state = "1-4" + icon_state = "0-4" }, -/turf/open/floor/carpet, -/area/service/library) +/obj/machinery/power/solar{ + id = "portsolar"; + name = "Port Solar Array" + }, +/turf/open/floor/plasteel/airless/solarpanel, +/area/solars/port) "pXg" = ( /obj/structure/table/glass, /obj/structure/window/reinforced, @@ -59355,9 +59509,29 @@ /obj/item/stack/sheet/mineral/wood, /turf/open/floor/plating, /area/maintenance/department/engine) +"qdY" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/light_switch{ + pixel_x = 24; + pixel_y = -24 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "qeY" = ( /turf/closed/wall/r_wall, /area/engineering/supermatter) +"qgb" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/item/kirbyplants{ + icon_state = "plant-21" + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "qhE" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 @@ -59367,6 +59541,17 @@ }, /turf/open/floor/plasteel, /area/engineering/main) +"qiG" = ( +/obj/machinery/mass_driver{ + id = "chapelgun" + }, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "qjx" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line, @@ -59386,8 +59571,13 @@ /turf/open/floor/engine, /area/engineering/main) "qni" = ( -/obj/machinery/smartfridge/organ/preloaded, -/turf/closed/wall, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/chair{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, /area/medical/surgery) "qnT" = ( /obj/machinery/iv_drip, @@ -59405,6 +59595,28 @@ }, /turf/open/floor/engine, /area/engineering/main) +"qpE" = ( +/obj/structure/chair{ + dir = 4; + name = "Judge" + }, +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/security/courtroom) +"qpR" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "qpS" = ( /obj/structure/cable{ icon_state = "2-4" @@ -59440,6 +59652,37 @@ }, /turf/open/floor/plasteel, /area/engineering/main) +"quc" = ( +/obj/structure/disposalpipe/segment, +/turf/open/space/basic, +/area/space/nearstation) +"quY" = ( +/obj/machinery/computer/secure_data, +/obj/machinery/button/door{ + desc = "A remote control switch for the medbay foyer."; + id = "innerbrig"; + name = "Brig Interior Doors Control"; + normaldoorcontrol = 1; + pixel_x = -6; + pixel_y = 36; + req_access_txt = "63" + }, +/obj/machinery/button/door{ + desc = "A remote control switch for the medbay foyer."; + id = "outerbrig"; + name = "Brig Exterior Doors Control"; + normaldoorcontrol = 1; + pixel_x = -6; + pixel_y = 24; + req_access_txt = "63" + }, +/obj/machinery/button/flasher{ + id = "brigentry"; + pixel_x = 6; + pixel_y = 24 + }, +/turf/open/floor/plasteel/dark, +/area/security/brig) "qxq" = ( /obj/machinery/atmospherics/components/binary/pump/on{ name = "Air Out" @@ -59460,6 +59703,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/engine, /area/science/xenobiology) "qAx" = ( @@ -59470,10 +59714,13 @@ /turf/open/floor/plasteel, /area/commons/fitness/recreation) "qAM" = ( -/obj/effect/spawner/lootdrop/maintenance, -/obj/item/cigbutt, -/turf/open/floor/plating, -/area/maintenance/department/cargo) +/obj/machinery/door/airlock/grunge{ + name = "Library" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "qBv" = ( /obj/item/clothing/head/ushanka, /turf/open/floor/plating, @@ -59524,6 +59771,15 @@ dir = 1 }, /area/hallway/secondary/entry) +"qGf" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/outlet_injector/on{ + dir = 1 + }, +/turf/open/floor/plating/airless, +/area/maintenance/department/chapel/monastery) "qGu" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -59533,6 +59789,12 @@ }, /turf/open/floor/plating, /area/maintenance/department/security/brig) +"qGW" = ( +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/security/brig) "qGZ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -59556,6 +59818,10 @@ }, /turf/open/floor/plating, /area/maintenance/department/cargo) +"qIr" = ( +/obj/machinery/rnd/bepis, +/turf/open/floor/plasteel/white, +/area/science/explab) "qIC" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 @@ -59576,6 +59842,12 @@ /obj/effect/decal/cleanable/cobweb, /turf/open/floor/plating, /area/maintenance/department/science) +"qLb" = ( +/obj/machinery/door/poddoor/shutters{ + id = "shootshut" + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "qLI" = ( /obj/structure/table, /obj/item/stack/sheet/glass/fifty{ @@ -59591,25 +59863,11 @@ }, /turf/open/floor/plasteel, /area/engineering/main) -"qMi" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/general/visible, -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/machinery/door/poddoor/preopen{ - id = "executionfireblast" - }, -/turf/open/floor/plating, -/area/security/execution/transfer) "qOE" = ( -/turf/open/floor/plasteel/dark, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/carpet, /area/service/library/lounge) "qOH" = ( /obj/structure/cable{ @@ -59708,6 +59966,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/light_switch{ + pixel_x = -25 + }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) "qVP" = ( @@ -59722,9 +59983,10 @@ /turf/open/floor/plasteel/dark, /area/science/xenobiology) "qWo" = ( -/turf/open/floor/plating{ - icon_state = "platingdmg3" +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 }, +/turf/closed/wall, /area/maintenance/department/chapel/monastery) "qWG" = ( /obj/structure/closet/emcloset/anchored, @@ -59755,6 +60017,12 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) +"qXE" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/closed/wall/mineral/iron, +/area/service/chapel/main/monastery) "qXH" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -59796,6 +60064,10 @@ }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) +"qYW" = ( +/obj/structure/bookcase/random/nonfiction, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "rar" = ( /obj/machinery/door/firedoor, /obj/structure/disposalpipe/segment{ @@ -59822,10 +60094,7 @@ dir = 8 }, /obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "2-8" + icon_state = "1-8" }, /turf/open/floor/plasteel, /area/security/brig) @@ -59872,6 +60141,11 @@ icon_state = "wood-broken4" }, /area/maintenance/department/engine) +"rif" = ( +/obj/machinery/mech_bay_recharge_port, +/obj/structure/cable, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "riF" = ( /obj/machinery/computer/arcade, /obj/effect/turf_decal/tile/neutral{ @@ -59896,16 +60170,7 @@ /turf/open/floor/plasteel/dark, /area/science/xenobiology) "rjF" = ( -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/machinery/door/poddoor/preopen{ - id = "Secure Gate"; - name = "brig shutters" - }, -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable, -/turf/open/floor/plating, +/turf/closed/wall/r_wall, /area/security/brig) "rmC" = ( /turf/open/space/basic, @@ -59917,12 +60182,16 @@ /turf/open/floor/plating/airless, /area/space/nearstation) "rnE" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 +/obj/machinery/door/airlock/grunge{ + name = "Library" }, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "roc" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -59932,18 +60201,26 @@ /obj/machinery/light/small{ dir = 4 }, +/obj/structure/closet/emcloset, /turf/open/floor/plasteel/white{ heat_capacity = 1e+006 }, /area/service/chapel/dock) -"rrb" = ( +"roU" = ( /obj/structure/cable{ - icon_state = "1-2" + icon_state = "2-8" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating{ - icon_state = "panelscorched" +/turf/closed/wall/mineral/iron, +/area/service/chapel/main/monastery) +"rpY" = ( +/obj/structure/cable{ + icon_state = "2-8" }, +/turf/open/floor/plating, +/area/maintenance/solars/port) +"rrb" = ( +/obj/item/target/clown, +/turf/open/floor/plating, /area/maintenance/department/security/brig) "rrU" = ( /obj/effect/turf_decal/tile/red{ @@ -59975,6 +60252,22 @@ }, /turf/open/floor/plasteel, /area/tcommsat/computer) +"rtg" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/security/brig) "rui" = ( /obj/structure/closet/emcloset/anchored, /obj/machinery/light/small{ @@ -59984,19 +60277,18 @@ /turf/open/floor/plating, /area/maintenance/department/science) "rvH" = ( -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=2"; - dir = 4; - freq = 1400; - location = "Medbay" +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/door/airlock{ + name = "Port Emergency Storage" }, -/obj/machinery/door/window/southleft{ - dir = 4; - name = "Medbay Delivery"; - req_access_txt = "28" +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "1-2" }, -/turf/open/floor/plasteel/dark, -/area/service/bar) +/obj/structure/disposalpipe/segment, +/obj/machinery/door/firedoor, +/turf/open/floor/plating, +/area/commons/storage/emergency/port) "rxa" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 1 @@ -60021,6 +60313,12 @@ }, /turf/open/floor/plasteel/cafeteria, /area/service/kitchen) +"rzm" = ( +/obj/structure/table/wood, +/obj/item/stack/packageWrap, +/obj/item/coin/gold, +/turf/open/floor/plasteel/dark, +/area/service/library) "rzp" = ( /obj/structure/table, /obj/item/stack/sheet/metal/fifty, @@ -60057,8 +60355,8 @@ }, /area/maintenance/department/science) "rGY" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/yellowsiding/corner{ dir = 8 }, @@ -60092,18 +60390,15 @@ /turf/open/floor/plating, /area/construction/mining/aux_base) "rKr" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ - icon_state = "4-8" + icon_state = "1-2" }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance"; - req_access_txt = "10; 13" +/obj/structure/cable{ + icon_state = "2-8" }, /turf/open/floor/plating, -/area/maintenance/solars/port) +/area/maintenance/department/security/brig) "rKL" = ( /obj/item/trash/cheesie, /turf/open/floor/plating{ @@ -60111,12 +60406,16 @@ }, /area/maintenance/department/science) "rLi" = ( -/obj/machinery/button/door{ - id = "shootshut"; - name = "shutters control"; - pixel_x = 28 +/obj/item/clothing/head/collectable/police, +/turf/open/floor/mech_bay_recharge_floor, +/area/maintenance/department/security/brig) +"rMb" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/obj/structure/cable{ + icon_state = "2-8" }, -/obj/item/ammo_casing/shotgun/improvised, /turf/open/floor/plating, /area/maintenance/department/security/brig) "rMB" = ( @@ -60143,6 +60442,14 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/maintenance/department/science) +"rNF" = ( +/obj/item/storage/box/matches{ + pixel_x = -3; + pixel_y = 8 + }, +/obj/structure/table/wood, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "rPg" = ( /obj/machinery/atmospherics/components/unary/thermomachine/freezer{ dir = 8 @@ -60153,6 +60460,26 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall/r_wall, /area/science/mixing) +"rRj" = ( +/obj/effect/turf_decal/tile/red, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) +"rRv" = ( +/obj/structure/bookcase/random/religion, +/obj/effect/decal/cleanable/cobweb{ + icon_state = "cobweb2" + }, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) +"rSE" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/structure/sign/painting/library{ + pixel_x = 32 + }, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "rSH" = ( /obj/item/trash/can, /turf/open/floor/wood, @@ -60164,6 +60491,23 @@ }, /turf/open/floor/plasteel, /area/engineering/main) +"rUj" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security/glass{ + name = "Labor Camp Shuttle Airlock"; + req_access_txt = "2" + }, +/obj/machinery/button/door{ + id = "prison release"; + name = "Labor Camp Shuttle Lockdown"; + pixel_y = -25; + req_access_txt = "2" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/security/brig) "rWE" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -60224,13 +60568,25 @@ /turf/open/floor/plasteel, /area/engineering/main) "sdk" = ( -/obj/structure/lattice, -/obj/machinery/camera/motion{ - c_tag = "Armory External"; +/turf/open/floor/plasteel/showroomfloor, +/area/security/office) +"seG" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/door/airlock/security/glass{ + id_tag = "innerbrig"; + name = "Brig"; + req_access_txt = "63" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/red{ dir = 1 }, -/turf/open/space, -/area/space/nearstation) +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/brig) "sgc" = ( /obj/machinery/vending/cigarette, /obj/effect/turf_decal/tile/neutral{ @@ -60252,6 +60608,17 @@ }, /turf/open/space, /area/space/nearstation) +"sgD" = ( +/obj/structure/bookcase/random/adult, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) +"shw" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/carpet, +/area/service/library) "shH" = ( /turf/closed/wall/r_wall, /area/space/nearstation) @@ -60260,6 +60627,10 @@ /obj/item/reagent_containers/food/snacks/meat/slab/monkey, /turf/open/floor/plating, /area/maintenance/department/engine) +"siA" = ( +/obj/item/toy/katana, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "sjC" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/tile/yellow, @@ -60269,10 +60640,30 @@ /obj/machinery/power/port_gen/pacman, /turf/open/floor/plasteel, /area/engineering/main) +"skq" = ( +/obj/machinery/door/airlock/engineering{ + name = "Port Solar Access"; + req_access_txt = "10" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/maintenance/solars/port) "skw" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, -/turf/closed/wall, -/area/maintenance/department/security/brig) +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/security/brig) "slJ" = ( /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 4 @@ -60313,9 +60704,17 @@ }, /turf/open/floor/plasteel/dark, /area/maintenance/department/crew_quarters/dorms) +"sqt" = ( +/obj/structure/chair, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "sqQ" = ( /turf/open/floor/plating, /area/maintenance/disposal) +"srK" = ( +/obj/item/broken_bottle, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "srZ" = ( /obj/structure/closet/crate{ icon_state = "crateopen" @@ -60365,17 +60764,17 @@ /obj/item/reagent_containers/food/snacks/meat/slab/monkey, /turf/open/floor/plating, /area/maintenance/department/engine) +"swB" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating, +/area/maintenance/department/engine) "syn" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plating{ - icon_state = "platingdmg1" - }, -/area/maintenance/department/security/brig) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall/mineral/iron, +/area/service/chapel/main/monastery) "syQ" = ( /obj/machinery/vending/games, /obj/structure/sign/plaques/deempisi{ @@ -60386,30 +60785,30 @@ }, /area/maintenance/department/science) "szG" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/obj/machinery/light/small{ - dir = 1 - }, -/turf/open/floor/plating, -/area/security/execution/transfer) +/turf/open/floor/plasteel/dark, +/area/security/prison) "sAK" = ( /obj/item/clothing/mask/gas/plaguedoctor, /turf/open/floor/plating, /area/maintenance/department/science) "sBA" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/obj/machinery/door/window/southleft{ + name = "Court Cell"; + req_access_txt = "2" }, -/obj/machinery/firealarm{ - pixel_y = 29 +/turf/open/floor/plasteel/dark, +/area/security/courtroom) +"sDV" = ( +/obj/structure/closet/secure_closet/brig{ + id = "Cell 1"; + name = "Cell 1 Locker" }, -/obj/effect/turf_decal/tile/red{ - dir = 1 +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 }, -/obj/effect/turf_decal/tile/red{ - dir = 4 +/obj/structure/cable{ + icon_state = "1-2" }, /turf/open/floor/plasteel, /area/security/brig) @@ -60425,7 +60824,13 @@ /turf/open/floor/plasteel/white, /area/medical/virology) "sGr" = ( -/obj/effect/turf_decal/stripes/line{ +/obj/machinery/light/small{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/plating, @@ -60447,11 +60852,15 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) +"sIO" = ( +/obj/structure/chair/wood/normal, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "sJp" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plating, -/area/security/execution/transfer) +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/turf/closed/wall, +/area/security/prison) "sJr" = ( /turf/open/floor/wood, /area/service/lawoffice) @@ -60468,6 +60877,44 @@ }, /turf/open/floor/plasteel, /area/engineering/main) +"sKq" = ( +/obj/machinery/door/airlock/grunge{ + name = "Library" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/dark, +/area/service/library) +"sMe" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/space, +/area/solars/port) +"sMA" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/security/brig) +"sMZ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/medical/surgery) "sNk" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -60482,12 +60929,22 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel/dark, /area/science/xenobiology) -"sOC" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 +"sNS" = ( +/obj/item/storage/toolbox/mechanical, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" }, /turf/open/floor/plating, -/area/security/execution/transfer) +/area/maintenance/department/chapel/monastery) +"sOC" = ( +/obj/structure/closet, +/obj/item/clothing/under/color/black, +/obj/item/clothing/under/color/red, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "sPh" = ( /turf/open/floor/plasteel/yellowsiding, /area/hallway/secondary/entry) @@ -60664,12 +61121,29 @@ /area/maintenance/department/science) "tfP" = ( /obj/item/beacon, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/engine, /area/science/xenobiology) "tfZ" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall, -/area/maintenance/department/security/brig) +/obj/structure/closet/crate/freezer, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/item/reagent_containers/blood/OMinus, +/obj/item/reagent_containers/blood/OMinus, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/security/brig) "thA" = ( /obj/machinery/atmospherics/pipe/simple/general/hidden, /turf/closed/wall/r_wall, @@ -60687,7 +61161,7 @@ }, /obj/structure/disposalpipe/segment, /turf/open/floor/plating, -/area/science/explab) +/area/maintenance/department/cargo) "tix" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -60712,10 +61186,9 @@ /turf/open/floor/engine, /area/engineering/main) "tlc" = ( -/obj/machinery/recharger, -/obj/structure/table, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/obj/machinery/gulag_teleporter, +/turf/open/floor/plasteel/dark, +/area/security/brig) "tlp" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ dir = 9 @@ -60743,18 +61216,11 @@ /turf/open/floor/plating, /area/engineering/main) "tnP" = ( -/obj/machinery/seed_extractor, -/obj/effect/turf_decal/tile/green{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 10 }, -/obj/effect/turf_decal/tile/green{ - dir = 8 - }, -/obj/machinery/light{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/security/prison) +/turf/open/floor/plasteel, +/area/security/brig) "tnY" = ( /obj/machinery/button/door{ id = "aux_base_shutters"; @@ -60770,11 +61236,15 @@ /turf/open/floor/plasteel, /area/construction/mining/aux_base) "tpb" = ( -/obj/item/reagent_containers/food/snacks/donut, -/turf/open/floor/plating{ - icon_state = "panelscorched" +/obj/machinery/door/airlock/security/glass{ + name = "Brig Control"; + req_access_txt = "3" }, -/area/maintenance/department/security/brig) +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/structure/disposalpipe/segment, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/showroomfloor, +/area/security/warden) "tqO" = ( /obj/structure/sign/poster/official/random{ pixel_x = -32 @@ -60869,11 +61339,15 @@ }, /area/maintenance/department/science) "tyL" = ( -/obj/structure/cable{ - icon_state = "1-8" +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 2; + name = "2maintenance loot spawner" }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/obj/structure/rack, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/chapel/monastery) "tzj" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel/white, @@ -60895,10 +61369,25 @@ /obj/item/pen, /turf/open/floor/plasteel/dark, /area/science/explab) +"tBh" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "tCJ" = ( /obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/department/crew_quarters/bar) +"tCN" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/snacks/donut, +/obj/item/folder/yellow, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "tCP" = ( /obj/docking_port/stationary/public_mining_dock, /turf/open/floor/plating, @@ -60907,6 +61396,15 @@ /obj/item/wrench, /turf/open/floor/plating, /area/maintenance/department/cargo) +"tFp" = ( +/obj/item/kirbyplants{ + icon_state = "plant-10" + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) "tHk" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -60944,6 +61442,19 @@ /obj/machinery/status_display/supply, /turf/closed/wall, /area/cargo/warehouse) +"tMe" = ( +/obj/effect/decal/cleanable/oil, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"tMI" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) "tOD" = ( /obj/machinery/atmospherics/pipe/simple/green/visible, /obj/effect/turf_decal/stripes/line{ @@ -60951,12 +61462,50 @@ }, /turf/open/floor/engine, /area/engineering/main) +"tPb" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/structure/lattice/catwalk, +/turf/open/space, +/area/solars/port) +"tPj" = ( +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + dir = 10 + }, +/obj/item/wrench, +/obj/item/stack/cable_coil, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) +"tPu" = ( +/obj/structure/table, +/obj/machinery/cell_charger, +/obj/item/stock_parts/cell/potato{ + name = "\improper Beepsky's emergency battery" + }, +/obj/item/paper/fluff/jobs/security/beepsky_mom, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "tRc" = ( /obj/structure/ore_box, /turf/open/floor/plating{ icon_state = "panelscorched" }, /area/maintenance/department/engine) +"tRZ" = ( +/obj/structure/lattice, +/obj/structure/disposalpipe/segment, +/turf/open/space/basic, +/area/space/nearstation) +"tSt" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "tSL" = ( /turf/open/floor/plating{ icon_state = "panelscorched" @@ -60967,18 +61516,11 @@ /turf/open/floor/plasteel, /area/hallway/primary/aft) "tTZ" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/turf/open/floor/plasteel, -/area/security/brig) +/turf/open/floor/plasteel/dark, +/area/security/courtroom) "tUO" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 @@ -61006,6 +61548,20 @@ }, /turf/open/floor/plasteel/white, /area/science/xenobiology) +"tXP" = ( +/obj/machinery/door/airlock/maintenance/abandoned{ + name = "Firing Range" + }, +/turf/open/floor/plating{ + icon_state = "platingdmg3" + }, +/area/maintenance/department/security/brig) +"tYu" = ( +/obj/item/reagent_containers/food/snacks/donut, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/security/brig) "uaC" = ( /obj/structure/chair/comfy/black{ dir = 8 @@ -61013,10 +61569,15 @@ /turf/open/floor/carpet, /area/maintenance/department/crew_quarters/dorms) "uaE" = ( -/obj/effect/decal/cleanable/oil{ - icon_state = "floor6" +/obj/machinery/door/airlock/maintenance{ + req_access_txt = "12" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating{ + icon_state = "platingdmg3" }, -/turf/open/floor/plating, /area/maintenance/department/security/brig) "uaO" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ @@ -61082,6 +61643,13 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"ugu" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/sign/warning/vacuum/external{ + pixel_x = -32 + }, +/turf/open/floor/plating, +/area/maintenance/solars/port) "ugC" = ( /obj/structure/chair/office/light{ dir = 4 @@ -61108,11 +61676,15 @@ /turf/open/floor/plating, /area/maintenance/department/security/brig) "ukn" = ( -/obj/structure/disposalpipe/segment{ +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/rack, +/obj/machinery/light/small{ dir = 4 }, -/turf/closed/wall, -/area/maintenance/department/engine) +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/maintenance/department/chapel/monastery) "ukp" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 4; @@ -61137,6 +61709,19 @@ }, /turf/open/floor/plasteel, /area/commons/storage/primary) +"ulQ" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/space, +/area/solars/port) "ulY" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall/r_wall, @@ -61174,6 +61759,23 @@ }, /turf/open/floor/plasteel, /area/construction/mining/aux_base) +"uoN" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/power/apc{ + areastring = "/area/medical/surgery"; + dir = 8; + name = "Surgery APC"; + pixel_x = -25 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating, +/area/maintenance/department/engine) "uoS" = ( /turf/open/floor/plating, /area/construction/mining/aux_base) @@ -61194,10 +61796,14 @@ /turf/open/water/decorative, /area/hallway/secondary/entry) "uqJ" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable, -/turf/open/floor/plating, -/area/security/execution/transfer) +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/prison) "urP" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -61206,14 +61812,9 @@ /turf/open/floor/plasteel, /area/science/explab) "utg" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/cafeteria, -/area/security/prison) +/obj/item/ammo_casing/shotgun/beanbag, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "uug" = ( /turf/open/floor/plating{ icon_state = "platingdmg1" @@ -61286,7 +61887,7 @@ name = "Defense" }, /obj/machinery/camera{ - c_tag = "Atmospherics Starboard"; + c_tag = "Atmospherics Hallway"; dir = 8 }, /obj/effect/turf_decal/tile/purple, @@ -61295,6 +61896,15 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/aft) +"uyI" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/maintenance/solars/port) "uyJ" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/engine, @@ -61322,12 +61932,40 @@ }, /turf/open/floor/plasteel, /area/tcommsat/computer) +"uzy" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "uzB" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, /turf/open/floor/engine, /area/science/xenobiology) +"uAA" = ( +/obj/item/target/alien, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"uAE" = ( +/obj/machinery/power/smes, +/obj/structure/cable, +/turf/open/floor/plating, +/area/maintenance/solars/port) "uAU" = ( /obj/structure/table/wood, /obj/item/folder/blue, @@ -61356,6 +61994,19 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/construction/mining/aux_base) +"uFA" = ( +/obj/item/storage/box/lights/bulbs, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) +"uFZ" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/brig) "uHG" = ( /obj/structure/cable{ icon_state = "1-4" @@ -61363,10 +62014,19 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating/airless, /area/space/nearstation) +"uIh" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/closed/wall, +/area/maintenance/department/chapel/monastery) "uIn" = ( /obj/machinery/power/terminal{ dir = 1 }, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, /turf/open/floor/plating, /area/maintenance/department/engine) "uIB" = ( @@ -61375,6 +62035,13 @@ }, /turf/closed/wall/r_wall, /area/engineering/main) +"uKR" = ( +/obj/machinery/computer/mech_bay_power_console{ + dir = 1 + }, +/obj/structure/cable, +/turf/open/floor/plasteel, +/area/maintenance/department/security/brig) "uLF" = ( /obj/structure/cable{ icon_state = "1-4" @@ -61402,6 +62069,16 @@ /obj/structure/grille, /turf/open/floor/plating, /area/maintenance/department/engine) +"uMf" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) "uMo" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/tile/yellow, @@ -61420,7 +62097,8 @@ /turf/open/floor/plasteel, /area/commons/fitness/recreation) "uQR" = ( -/obj/item/ammo_casing/shotgun/beanbag, +/obj/structure/table, +/obj/item/clothing/head/beret, /turf/open/floor/plating, /area/maintenance/department/security/brig) "uRk" = ( @@ -61432,6 +62110,12 @@ }, /turf/open/floor/engine, /area/engineering/main) +"uTZ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "uUQ" = ( /obj/machinery/door/airlock/maintenance{ name = "Engineering Maintenance"; @@ -61458,6 +62142,14 @@ /obj/item/stamp/law, /turf/open/floor/carpet, /area/service/lawoffice) +"uXp" = ( +/obj/item/weldingtool, +/obj/effect/spawner/lootdrop/maintenance, +/obj/effect/decal/cleanable/oil{ + icon_state = "floor6" + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "uXG" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -61504,11 +62196,19 @@ /turf/open/floor/plating, /area/maintenance/department/engine) "vco" = ( -/obj/machinery/light/small{ - dir = 8 - }, +/obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/maintenance/department/chapel/monastery) +"vcv" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "veF" = ( /obj/structure/window/reinforced{ dir = 8 @@ -61532,6 +62232,11 @@ }, /turf/open/floor/plasteel/dark, /area/science/mixing) +"vgg" = ( +/obj/structure/table/wood, +/obj/item/barcodescanner, +/turf/open/floor/plasteel/dark, +/area/service/library) "vgp" = ( /obj/machinery/door/firedoor, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -61549,10 +62254,45 @@ }, /turf/open/floor/plasteel, /area/science/xenobiology) +"vgF" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "vhk" = ( /obj/structure/chair, /turf/open/floor/carpet, /area/service/lawoffice) +"vik" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/closet/l3closet, +/obj/structure/window/reinforced{ + dir = 4; + layer = 2.9 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/medical/medbay/central) +"vil" = ( +/obj/machinery/mass_driver{ + id = "chapelgun" + }, +/obj/machinery/door/window/eastleft{ + dir = 8; + name = "Mass Driver" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "vjd" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -61562,6 +62302,14 @@ }, /turf/open/floor/plasteel, /area/engineering/main) +"vjD" = ( +/obj/structure/chair/stool, +/obj/machinery/power/terminal{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/maintenance/solars/port) "vli" = ( /obj/structure/table, /obj/item/clothing/glasses/meson/engine, @@ -61621,6 +62369,19 @@ }, /turf/open/floor/plating, /area/maintenance/department/engine) +"vnI" = ( +/obj/structure/bed, +/obj/machinery/flasher{ + id = "Cell 3"; + pixel_x = -28 + }, +/obj/item/bedsheet/orange, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/brig) "voh" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ dir = 5 @@ -61628,6 +62389,31 @@ /obj/structure/lattice, /turf/open/space/basic, /area/space/nearstation) +"vrn" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) +"vrQ" = ( +/obj/machinery/power/terminal{ + dir = 8 + }, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "vsk" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -61688,6 +62474,14 @@ /obj/item/clothing/mask/gas, /turf/open/floor/plating, /area/maintenance/department/science) +"vwY" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/suit_storage_unit/paramedic, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 6 + }, +/turf/open/floor/plasteel/dark, +/area/medical/paramedic) "vxp" = ( /obj/machinery/door/window/eastright{ base_state = "left"; @@ -61712,6 +62506,11 @@ }, /turf/open/floor/plasteel, /area/engineering/main) +"vxV" = ( +/obj/item/toy/gun, +/obj/effect/decal/cleanable/oil, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "vzp" = ( /obj/effect/turf_decal/tile/brown, /obj/item/stack/ore/iron, @@ -61783,13 +62582,7 @@ /turf/open/floor/engine, /area/engineering/main) "vCC" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/item/clothing/head/cone, /turf/open/floor/plating, /area/maintenance/department/security/brig) "vGg" = ( @@ -61807,6 +62600,10 @@ }, /turf/open/floor/plating, /area/maintenance/department/science) +"vHh" = ( +/obj/structure/lattice, +/turf/closed/mineral, +/area/service/chapel/asteroid/monastery) "vIa" = ( /turf/open/floor/plasteel/yellowsiding/corner{ dir = 4 @@ -61838,19 +62635,66 @@ /turf/open/floor/plasteel/dark, /area/science/xenobiology) "vOw" = ( -/obj/machinery/door/airlock/grunge{ - name = "Library" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ +/obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, +/turf/open/floor/plasteel, +/area/security/brig) +"vOQ" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/door/airlock/public/glass{ + name = "Courtroom"; + req_access_txt = "42" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/courtroom) +"vQx" = ( +/obj/machinery/door/window/brigdoor/security/cell{ + id = "Cell 1"; + name = "Cell 1" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/brig) +"vQN" = ( +/obj/effect/turf_decal/stripes/corner, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, /turf/open/floor/plasteel/dark, -/area/service/library) +/area/service/library/lounge) "vRi" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -61889,6 +62733,20 @@ }, /turf/open/floor/plasteel, /area/engineering/main) +"vTc" = ( +/obj/structure/rack{ + icon = 'icons/obj/stationobjs.dmi'; + icon_state = "minibar"; + name = "skeletal minibar" + }, +/obj/item/book/codex_gigas, +/obj/machinery/camera{ + c_tag = "Monastery Archives Aft"; + dir = 1; + network = list("ss13","monastery") + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "vTL" = ( /obj/machinery/vending/tool, /obj/effect/turf_decal/tile/neutral{ @@ -61968,6 +62826,26 @@ /obj/machinery/meter, /turf/open/floor/plating, /area/maintenance/department/engine) +"wdU" = ( +/obj/machinery/button/door{ + id = "shootshut"; + name = "shutters control"; + pixel_x = 28 + }, +/obj/item/ammo_casing/shotgun/improvised, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"wdY" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Monastery Archives Starboard"; + dir = 8; + network = list("ss13","monastery") + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "weL" = ( /obj/machinery/light/small, /turf/open/floor/plating, @@ -62007,17 +62885,15 @@ /turf/open/floor/engine, /area/engineering/main) "whP" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/yellowsiding/corner{ dir = 1 }, /area/hallway/secondary/entry) "wig" = ( -/obj/machinery/vending/cigarette, -/turf/open/floor/plating{ - icon_state = "platingdmg3" - }, +/obj/structure/closet/emcloset, +/turf/open/floor/plating, /area/maintenance/department/security/brig) "wiB" = ( /obj/item/shard{ @@ -62055,6 +62931,17 @@ /obj/item/flashlight, /turf/open/floor/plasteel, /area/hallway/secondary/entry) +"wkC" = ( +/obj/structure/window/reinforced{ + dir = 1; + pixel_y = 1 + }, +/obj/structure/window/reinforced{ + dir = 8; + layer = 2.9 + }, +/turf/open/space/basic, +/area/space/nearstation) "wkZ" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 @@ -62082,14 +62969,38 @@ }, /turf/open/floor/plasteel/white, /area/science/explab) +"wnp" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) +"wnE" = ( +/obj/machinery/light/small, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/library) "wnJ" = ( /obj/structure/sign/warning, /turf/closed/wall, /area/science/mixing) "woq" = ( -/obj/structure/chair, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/security/brig) "wqu" = ( /obj/effect/turf_decal/loading_area{ dir = 8 @@ -62105,12 +63016,14 @@ /turf/open/floor/wood, /area/service/lawoffice) "wtE" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/effect/turf_decal/trimline/blue/filled/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, -/obj/effect/landmark/start/paramedic, -/turf/open/floor/plasteel/white, -/area/medical/medbay/central) +/turf/open/floor/plasteel/dark, +/area/medical/paramedic) "wun" = ( /obj/structure/cable{ icon_state = "1-2" @@ -62133,30 +63046,53 @@ /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "wwG" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/extinguisher_cabinet{ + pixel_y = 30 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "2-8" }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) -"wxb" = ( /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/turf/open/floor/plasteel, +/area/security/brig) +"wxb" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plating{ - icon_state = "platingdmg3" +/obj/effect/turf_decal/tile/red{ + dir = 1 }, -/area/maintenance/department/security/brig) -"wxJ" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/door/poddoor/preopen{ - id = "prison release"; - name = "prisoner processing blast door" +/obj/effect/turf_decal/tile/red{ + dir = 4 }, -/turf/open/floor/plasteel/dark, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, /area/security/brig) +"wxJ" = ( +/turf/open/floor/plasteel, +/area/security/brig) +"wyf" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "wzb" = ( /obj/structure/chair, /turf/open/floor/wood, @@ -62191,9 +63127,30 @@ /turf/open/floor/plasteel, /area/engineering/main) "wDm" = ( -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/obj/machinery/camera{ + c_tag = "Brig Cells" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/security/brig) +"wDq" = ( +/obj/structure/bookcase/random/fiction, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "wDZ" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 @@ -62215,12 +63172,39 @@ dir = 1 }, /area/hallway/secondary/exit/departure_lounge) +"wFB" = ( +/obj/structure/grille, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "wFT" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, /turf/open/floor/plating, /area/maintenance/department/science) +"wGD" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/space, +/area/solars/port) +"wIa" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/brig) "wIo" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple, /obj/structure/lattice, @@ -62254,9 +63238,9 @@ /turf/open/floor/plating, /area/command/heads_quarters/cmo) "wMF" = ( -/obj/effect/spawner/lootdrop/three_course_meal, -/obj/effect/spawner/lootdrop/three_course_meal, /obj/structure/closet/crate, +/obj/effect/spawner/lootdrop/three_course_meal, +/obj/effect/spawner/lootdrop/three_course_meal, /turf/open/floor/plating{ icon_state = "platingdmg1" }, @@ -62302,6 +63286,20 @@ }, /turf/open/floor/plating, /area/science/mixing) +"wPk" = ( +/obj/machinery/door/airlock/external{ + name = "Labor Camp Shuttle Airlock"; + req_access_txt = "2" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/brig) +"wPp" = ( +/obj/item/stack/rods/fifty, +/turf/open/floor/plating, +/area/maintenance/department/chapel/monastery) "wQU" = ( /obj/effect/spawner/lootdrop/maintenance, /obj/structure/cable{ @@ -62321,27 +63319,30 @@ /turf/open/floor/plating, /area/maintenance/department/engine) "wRz" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 }, /obj/structure/cable{ icon_state = "4-8" }, -/turf/open/floor/plating{ - icon_state = "platingdmg3" - }, -/area/maintenance/department/security/brig) +/turf/open/floor/plasteel, +/area/security/brig) "wRI" = ( -/obj/machinery/power/apc{ - dir = 1; - name = "Brig Maintenance APC"; - pixel_y = 23 +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 }, /obj/structure/cable{ - icon_state = "0-4" + icon_state = "4-8" }, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/security/brig) "wSX" = ( /obj/structure/flora/junglebush/large{ pixel_x = -15; @@ -62377,14 +63378,29 @@ /area/maintenance/department/science) "wUf" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plating, -/area/commons/storage/emergency/port) -"wUz" = ( -/obj/structure/chair/stool, -/turf/open/floor/plating{ - icon_state = "panelscorched" +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 1 }, -/area/maintenance/department/security/brig) +/turf/open/floor/plasteel/dark, +/area/medical/paramedic) +"wUz" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/security/brig) "wVC" = ( /obj/machinery/navbeacon{ codes_txt = "patrol;next_patrol=Sci"; @@ -62392,6 +63408,17 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"wWJ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/security/brig) "wXu" = ( /obj/machinery/disposal/bin, /obj/structure/window/reinforced{ @@ -62407,15 +63434,20 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "wYu" = ( -/obj/machinery/door/poddoor/shutters{ - id = "shootshut" - }, +/obj/structure/reagent_dispensers/watertank, /turf/open/floor/plating, /area/maintenance/department/security/brig) "wYK" = ( /obj/machinery/power/supermatter_crystal/engine, /turf/open/floor/engine, /area/engineering/supermatter) +"wZT" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Medbay Maintenance"; + req_one_access_txt = "12;45;5;9" + }, +/turf/open/floor/plating, +/area/maintenance/department/engine) "xah" = ( /obj/structure/cable{ icon_state = "1-2" @@ -62457,6 +63489,19 @@ "xbJ" = ( /turf/open/floor/plasteel/dark, /area/maintenance/department/crew_quarters/dorms) +"xcw" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/airlock/external{ + name = "Solar Maintenance"; + req_access_txt = "10; 13" + }, +/turf/open/floor/plating, +/area/maintenance/solars/port) "xee" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/sign/warning/vacuum/external, @@ -62478,6 +63523,15 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/maintenance/department/chapel/monastery) +"xgz" = ( +/obj/structure/cable, +/obj/machinery/door/poddoor/preopen{ + id = "Secure Gate"; + name = "brig shutters" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/security/brig) "xgG" = ( /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -62488,9 +63542,13 @@ /turf/open/floor/plasteel, /area/science/explab) "xhj" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/carpet, -/area/service/library/lounge) +/obj/effect/decal/cleanable/cobweb{ + icon_state = "cobweb2" + }, +/obj/item/storage/fancy/candle_box, +/obj/structure/table/wood, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "xhE" = ( /obj/structure/extinguisher_cabinet{ pixel_x = 27 @@ -62509,23 +63567,19 @@ /turf/open/floor/plasteel, /area/engineering/main) "xja" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/machinery/power/apc{ - dir = 4; - name = "Library APC"; - pixel_x = 24 - }, -/obj/structure/cable, +/obj/structure/displaycase/trophy, /turf/open/floor/plasteel/dark, /area/service/library) "xjc" = ( /obj/structure/cable{ - icon_state = "2-8" + icon_state = "1-4" }, -/turf/open/floor/plasteel/dark, -/area/service/library) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, +/area/service/library/lounge) "xje" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, @@ -62560,6 +63614,32 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"xkB" = ( +/obj/structure/table, +/obj/item/book/manual/wiki/security_space_law, +/turf/open/floor/plasteel/dark, +/area/security/courtroom) +"xld" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/camera{ + c_tag = "Monastery Archives Access Tunnel"; + dir = 4; + network = list("ss13","monastery") + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "xlg" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/heat_exchanging/junction, @@ -62616,10 +63696,6 @@ /obj/item/ectoplasm, /turf/open/floor/plating, /area/maintenance/department/science) -"xuv" = ( -/obj/item/broken_bottle, -/turf/open/floor/plating, -/area/maintenance/department/security/brig) "xvO" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -62630,10 +63706,27 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"xxl" = ( +/obj/structure/table/wood/fancy, +/obj/item/storage/book/bible, +/turf/open/floor/carpet, +/area/service/chapel/main/monastery) "xxw" = ( /obj/machinery/atmospherics/components/binary/pump, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"xxK" = ( +/obj/structure/sign/departments/security{ + pixel_y = 32 + }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) "xxO" = ( /obj/machinery/door/poddoor/preopen{ id = "xenobio2"; @@ -62670,11 +63763,9 @@ /turf/open/floor/plating, /area/maintenance/department/cargo) "xyB" = ( -/obj/effect/spawner/lootdrop/maintenance, -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, -/area/maintenance/department/security/brig) +/obj/structure/lattice, +/turf/open/space/basic, +/area/space) "xzp" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -62694,6 +63785,18 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/science/xenobiology) +"xBh" = ( +/obj/structure/sign/warning/vacuum/external{ + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) +"xBn" = ( +/obj/structure/table, +/obj/item/storage/crayons, +/obj/item/wrench, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "xCV" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -62717,12 +63820,26 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/aft) +"xDw" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/fore) +"xEb" = ( +/obj/structure/destructible/cult/tome, +/turf/open/floor/plasteel/dark, +/area/service/library) "xEx" = ( /obj/machinery/portable_atmospherics/scrubber/huge, /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/bot, /turf/open/floor/engine, /area/science/storage) +"xEy" = ( +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "xFl" = ( /obj/machinery/power/apc/highcap/five_k{ areastring = "/area/tcommsat/server"; @@ -62740,12 +63857,22 @@ /obj/effect/landmark/carpspawn, /turf/open/space, /area/space/station_ruins) +"xGY" = ( +/obj/structure/table/wood, +/obj/item/instrument/saxophone, +/turf/open/floor/plasteel/dark, +/area/service/library) "xIx" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, /turf/closed/wall/r_wall, /area/science/mixing) +"xIV" = ( +/obj/structure/chair/wood/normal, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "xJy" = ( /obj/structure/chair/comfy/black, /obj/structure/sign/plaques/kiddie{ @@ -62783,11 +63910,48 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plasteel/dark, /area/service/lawoffice) +"xLL" = ( +/turf/closed/wall, +/area/maintenance/solars/port) +"xMk" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/door/poddoor/preopen{ + id = "Secure Gate"; + name = "brig shutters" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/security/brig) +"xNn" = ( +/obj/machinery/door/window/brigdoor/security/cell{ + id = "Cell 2"; + name = "Cell 2" + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/security/brig) "xNx" = ( -/obj/structure/lattice, -/obj/structure/disposalpipe/junction/flip, -/turf/open/space/basic, -/area/space/nearstation) +/obj/item/kirbyplants{ + icon_state = "plant-22" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/power/apc{ + dir = 4; + name = "Library Lounge APC"; + pixel_x = 24 + }, +/obj/machinery/airalarm{ + pixel_y = 22 + }, +/turf/open/floor/plasteel/dark, +/area/service/library/lounge) "xNy" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line{ @@ -62795,6 +63959,29 @@ }, /turf/open/floor/engine, /area/engineering/main) +"xNL" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/closed/wall/mineral/iron, +/area/service/chapel/main/monastery) +"xNO" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/security/courtroom) +"xNW" = ( +/obj/effect/decal/cleanable/cobweb{ + icon_state = "cobweb2" + }, +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plating, +/area/maintenance/department/security/brig) "xOC" = ( /obj/machinery/door/airlock/external{ name = "Construction Zone" @@ -62810,18 +63997,14 @@ /turf/open/floor/engine, /area/science/explab) "xQc" = ( -/obj/machinery/door/firedoor, -/obj/structure/cable{ - icon_state = "1-2" +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 4 }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/airlock{ - name = "Port Emergency Storage" +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 }, -/obj/effect/mapping_helpers/airlock/unres, -/turf/open/floor/plasteel/freezer, -/area/commons/storage/emergency/port) +/turf/open/floor/plasteel/dark, +/area/medical/paramedic) "xQk" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ dir = 6 @@ -62829,10 +64012,28 @@ /obj/structure/lattice/catwalk, /turf/open/space, /area/space/nearstation) +"xRD" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/door/poddoor/preopen{ + id = "Secure Gate"; + name = "brig shutters" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable, +/turf/open/floor/plating, +/area/security/brig) "xSd" = ( /obj/machinery/light/small, /turf/open/floor/plating, /area/maintenance/department/chapel/monastery) +"xSk" = ( +/obj/structure/table, +/obj/item/crowbar, +/obj/item/clothing/mask/gas, +/turf/open/floor/plasteel/dark, +/area/service/chapel/main/monastery) "xSX" = ( /obj/machinery/airalarm/unlocked{ pixel_y = 23 @@ -62847,14 +64048,8 @@ /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "xVt" = ( -/obj/effect/spawner/lootdrop/maintenance{ - lootcount = 2; - name = "2maintenance loot spawner" - }, -/obj/structure/rack, -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall, /area/maintenance/department/chapel/monastery) "xWl" = ( /obj/item/pen, @@ -62868,9 +64063,13 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "xYV" = ( -/turf/open/floor/plating{ - icon_state = "panelscorched" +/obj/machinery/atmospherics/components/unary/outlet_injector/on{ + dir = 1 }, +/obj/effect/turf_decal{ + dir = 1 + }, +/turf/open/floor/plating, /area/maintenance/department/chapel/monastery) "ybX" = ( /obj/structure/table, @@ -62878,8 +64077,9 @@ /turf/open/floor/plating, /area/maintenance/department/cargo) "ycr" = ( -/obj/structure/target_stake, -/obj/item/target/syndicate, +/obj/effect/decal/cleanable/oil{ + icon_state = "floor6" + }, /turf/open/floor/plating, /area/maintenance/department/security/brig) "ycx" = ( @@ -62909,6 +64109,10 @@ }, /turf/open/floor/plating, /area/maintenance/department/cargo) +"yin" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/maintenance/solars/port) "ymb" = ( /obj/machinery/camera{ c_tag = "Engineering Telecomms Access"; @@ -65571,35 +66775,35 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa rmC rmC rmC @@ -65828,35 +67032,35 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa rmC rmC rmC @@ -66085,35 +67289,35 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa rmC rmC rmC @@ -66342,35 +67546,35 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa rmC rmC rmC @@ -66599,35 +67803,35 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa rmC rmC rmC @@ -66856,35 +68060,35 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aoH +aoH +aoH +aoH +aoH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa rmC rmC rmC @@ -67113,35 +68317,35 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aoH +aaa +aqd +aaa +aoH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa rmC rmC rmC @@ -67370,35 +68574,35 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aqd +aqd +pid +aqd +aqd +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa rmC rmC rmC @@ -67627,35 +68831,35 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aoH +aoH +aoH +aoH +aoH +aoH +aoH +aoH +aoH +aoH +aaa +azH +aaa +aoH +aoH +aoH +aoH +aoH +aoH +aoH +aoH +aoH +aoH +aaa +aaa rmC rmC rmC @@ -67884,35 +69088,35 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aqd +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +azH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aqd +aaa +aaa rmC rmC rmC @@ -68145,29 +69349,29 @@ aaa aaa aaa aaa +aoH aaa +pXc +pXc +pXc +pXc +pXc +pXc +pXc +pXc aaa +wGD aaa +pXc +pXc +pXc +pXc +pXc +pXc +pXc +pXc aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +aoH aaa aaa aaa @@ -68402,29 +69606,29 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +aoH +aqd +aqa +ulQ +ulQ +ulQ +ulQ +ulQ +ulQ +ulQ +fgh +oPX +pqR +hyn +hyn +hyn +hyn +hyn +hyn +hyn +sMe +aqd +aoH aaa aaa aaa @@ -68659,29 +69863,29 @@ aaa aaa aaa aaa +aoH aaa +aIr +aIr +aIr +aIr +aIr +aIr +aIr +aIr aaa +azK aaa +aCa +aCa +aCa +aCa +aCa +aCa +aCa +aIr aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +aoH aaa aaa aaa @@ -68916,6 +70120,7 @@ aaa aaa aaa aaa +gGy aaa aaa aaa @@ -68926,6 +70131,7 @@ aaa aaa aaa aaa +azK aaa aaa aaa @@ -68936,9 +70142,7 @@ aaa aaa aaa aaa -aaa -aaa -aaa +aoH aaa aaa aaa @@ -69173,29 +70377,29 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aoH -aoH -aoH -aoH aoH aaa +pXc +pXc +pXc +pXc +pXc +pXc +pXc +pXc aaa +azK aaa +pXc +pXc +pXc +pXc +pXc +pXc +pXc +pXc aaa -aaa -aaa -aaa -aaa -aaa +aoH aaa aaa aaa @@ -69430,34 +70634,34 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa aoH -aaa -aoI -aaa +aqd +aqa +ulQ +ulQ +ulQ +ulQ +ulQ +ulQ +ulQ +fgh +azK +pqR +hyn +hyn +hyn +hyn +hyn +hyn +hyn +sMe +aqd aoH aaa aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa rmC rmC rmC @@ -69687,29 +70891,29 @@ aaa aaa aaa aaa +aoH aaa +aIr +aIr +aIr +aIr +aIr +aIr +aIr +aIr aaa +azK aaa +aCa +aCa +aCa +aCa +aCa +aCa +aCa +aIr aaa -aaa -aaa -aaa -aaa -aaa -aoI -aoI -azG -aoI -aoI -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +aoH aaa aaa aaa @@ -69945,27 +71149,27 @@ aaa aaa aaa aoH -aoH -aoH -aoH -aoH -aoH -aoH -aoH -aoH -aoH aaa -azH aaa -aoH -aoH -aoH -aoH -aoH -aoH -aoH -aoH -aoH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +azK +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aoH aaa aaa @@ -70201,29 +71405,29 @@ aaa aaa aaa aaa -aoI +aoH aaa +pXc +pXc +pXc +pXc +pXc +pXc +pXc +pXc aaa +azK aaa +pXc +pXc +pXc +pXc +pXc +pXc +pXc +pXc aaa -aaa -aaa -aaa -aaa -aaa -aaa -azH -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aoI +aoH aaa aaa aaa @@ -70459,27 +71663,27 @@ aaa aaa aaa aoH -aaa +aqd aqa -aqa -aqa -aqa -aqa -aqa -aqa -aqa -aaa -azI -aaa -aqa -aqa -aqa -aqa -aqa -aqa -aqa -aqa -aaa +ulQ +ulQ +ulQ +ulQ +ulQ +ulQ +ulQ +fgh +azK +pqR +hyn +hyn +hyn +hyn +hyn +hyn +hyn +sMe +aqd aoH aaa aaa @@ -70716,18 +71920,7 @@ aaa aaa aaa aoH -aoI -aqb -ara -ara -ara -ara -ara -ara -ara -ayy -azJ -aAV +aaa aCa aCa aCa @@ -70736,7 +71929,18 @@ aCa aCa aCa aIr -aoI +aaa +azK +aaa +aCa +aCa +aCa +aCa +aCa +aCa +aCa +aIr +aaa aoH aaa aaa @@ -70974,27 +72178,27 @@ aaa aaa aoH aaa -aqc -aqc -aqc -aqc -aqc -aqc -aqc -aqc +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa azK aaa -aqd -aqd -aqd -aqd -aqd -aqd -aqd -aqc aaa -aoH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +gGy aaa aaa aaa @@ -71229,27 +72433,27 @@ aaa aaa aaa aaa -aoJ -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +aoH aaa +pXc +pXc +pXc +pXc +pXc +pXc +pXc +pXc aaa azK aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +pXc +pXc +pXc +pXc +pXc +pXc +pXc +pXc aaa aoH aaa @@ -71487,27 +72691,27 @@ aaa aaa aaa aoH -aaa +aqd aqa -aqa -aqa -aqa -aqa -aqa -aqa -aqa -aaa +ulQ +ulQ +ulQ +ulQ +ulQ +ulQ +ulQ +fgh azK -aaa -aqa -aqa -aqa -aqa -aqa -aqa -aqa -aqa -aaa +pqR +hyn +hyn +hyn +hyn +hyn +hyn +hyn +sMe +aqd aoH aaa aaa @@ -71744,18 +72948,7 @@ aaa aaa aaa aoH -aoI -aqb -ara -ara -ara -ara -ara -ara -ara -ayy -azK -aAV +aaa aCa aCa aCa @@ -71764,7 +72957,18 @@ aCa aCa aCa aIr -aoI +aaa +azK +aaa +aCa +aCa +aCa +aCa +aCa +aCa +aCa +aIr +aaa aoH aaa aaa @@ -72002,27 +73206,27 @@ aaa aaa aoH aaa -aqc -aqc -aqc -aqc -aqc -aqc -aqc -aqc +aaa +aaa +aqd +aaa +aaa +aaa +aaa +aaa aaa azK aaa -aqd -aqd -aqd -aqd -aqd -aqd -aqd -aqc aaa -aoH +aaa +aaa +aaa +aaa +aqd +aaa +aaa +aaa +aqd aaa aaa aaa @@ -72258,21 +73462,17 @@ aaa aaa aaa aoH +aqd +aoH +aoH +aoH aaa aaa aaa aaa aaa aaa -aaa -aaa -aaa -aaa -azK -aaa -aaa -aaa -aaa +tPb aaa aaa aaa @@ -72280,6 +73480,10 @@ aaa aaa aaa aoH +aqd +aoH +aoH +aoH aaa aaa aaa @@ -72514,29 +73718,29 @@ aaa aaa aaa aaa -aoH aaa -aqa -aqa -aqa -aqa -aqa -aqa -aqa -aqa aaa -azK aaa -aqa -aqa -aqa -aqa -aqa -aqa -aqa -aqa aaa -aoH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +azH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -72771,29 +73975,29 @@ aaa aaa aaa aaa -aoH -aoI -aqb -ara -ara -ara -ara -ara -ara -ara -ayy -azK -aAV -aCa -aCa -aCa -aCa -aCa -aCa -aCa -aIr -aoI -aoH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +azH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -73028,29 +74232,29 @@ aaa aaa aaa aaa -aoH aaa -aqd -aqd -aqd -aqd -aqd -aqd -aqd -aqc aaa -azK aaa -aqd -aqd -aqd -aqd -aqd -aqd -aqd -aqc aaa -aoH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +azH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -73280,12 +74484,6 @@ rmC rmC rmC rmC -rmC -aaa -aaa -aaa -aaa -aoH aaa aaa aaa @@ -73296,7 +74494,14 @@ aaa aaa aaa aaa -azK +aaa +aaa +aaa +aaa +aaa +aaa +azH +aaa aaa aaa aaa @@ -73307,7 +74512,6 @@ aaa aaa aaa aaa -aoJ aaa aaa aaa @@ -73537,34 +74741,34 @@ rmC rmC rmC rmC -rmC aaa aaa aaa aaa -aoH aaa -aqa -aqa -aqa -aqa -aqa -aqa -aqa -aqa aaa -azK aaa -aqa -aqa -aqa -aqa -aqa -aqa -aqa -aqa aaa -aoH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +azH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -73794,34 +74998,34 @@ rmC rmC rmC rmC -rmC aaa aaa aaa aaa -aoH -aoI -aqb -ara -ara -ara -ara -ara -ara -ara -ayy -azK -aAV -aCa -aCa -aCa -aCa -aCa -aCa -aCa -aIr -aoI -aoH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +azH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -73904,12 +75108,12 @@ aaa aaa aaa aaa -cfN -cfN -fIT -cfH -fIT -cfN +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -74051,34 +75255,34 @@ rmC rmC rmC rmC -rmC aaa aaa aaa aaa -aoH aaa -aqd -aqd -aqd -aqd -aqd -aqd -aqd -aqc aaa -azK aaa -aqd -aqd -aqd -aqd -aqd -aqd -aqd -aqc aaa -aoH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +azH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -74161,13 +75365,13 @@ cfN cfN cfN cfN -cfN -cfN -fIT -cfI -fIT -cfN -cfN +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -74308,34 +75512,34 @@ rmC rmC rmC rmC -rmC -aaa -aaa -aaa -aaa -aoH -aaa -aaa -aaa -aoI aaa aaa aaa aaa aaa aaa -azK aaa aaa aaa aaa aaa aaa -aoI aaa aaa aaa -aoI +aaa +azH +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -74408,7 +75612,7 @@ csd csd csB csd -csd +czP cBM aaa aaa @@ -74421,10 +75625,10 @@ cfN cfN cfN fIT -cjC +cfH fIT cfN -cfN +aaa aaa aaa aaa @@ -74565,35 +75769,35 @@ rmC rmC rmC rmC -rmC aaa aaa aaa +aby +aed +aby +aht +aby +aby +aby +aht +aby +aby +aby aaa -aoH -aoI -aoH -aoH -aoH +aaa +azH aaa aaa aaa aaa aaa aaa -azL aaa aaa aaa aaa aaa aaa -aoH -aoI -aoH -aoH -aoH -aaa aaa aaa aaa @@ -74675,14 +75879,14 @@ cfN cfN cfN cfN -bWV -bWV -fIT -cfJ -fIT -bWV cfN cfN +fIT +cfI +fIT +cfN +cfN +aaa aaa aaa aaa @@ -74822,21 +76026,21 @@ rmC rmC rmC rmC -rmC -aaa -aaa -aaa -aaa -aaa -aaa +aaa +aaa +aaa +aht aaa aaa aaa aaa +aht aaa aaa aaa aaa +aht +aht aaa azH aaa @@ -74932,14 +76136,14 @@ cfN cfN cfN cfN -bWV -ciJ -cjf -bXJ -cjZ -bWV cfN cfN +fIT +jsl +fIT +cfN +cfN +aaa aaa aaa aaa @@ -75079,21 +76283,21 @@ rmC rmC rmC rmC -rmC -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa aaa aaa aaa +aiu +ait +ait +ait +aiu +aiu +ait +ait +ait +aiu +aiu +aht aaa azH aaa @@ -75190,10 +76394,10 @@ bWV bWV bWV bWV -ciK -cjg -cjk -cka +bWV +fIT +cfJ +fIT bWV cfN cfN @@ -75336,21 +76540,21 @@ rmC rmC rmC rmC -rmC -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa aaa aaa aaa +aiu +czV +gJV +mwg +qLb +utg +ycr +tMe +azN +nYq +aiu +aht aaa azH aaa @@ -75447,15 +76651,15 @@ bWV chC chV bWV -bWV +gyQ cvq -ceP +bXJ +xBn bWV -bWV -bWV -bWV -cwM -bIT +cfN +cfN +aaa +aaa aaa aaa aaa @@ -75577,23 +76781,6 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC aaa aaa aaa @@ -75609,6 +76796,23 @@ aaa aaa aaa aaa +aaa +aaa +aaa +aaa +aiu +cAr +hiw +mEe +qLb +azN +azN +azN +azN +fRL +aiu +aht +aaa azH aaa aaa @@ -75616,7 +76820,7 @@ aaa aaa aaa aaa -aaa +cFB aaa aaa aaa @@ -75704,16 +76908,16 @@ chb chD chW bWV -bWV -cgf +xSk +fdM cvA +ehJ bWV -cwj -cww -bWV -fIT -fIT -cxg +cfN +cfN +aaa +aaa +aaa aaa aaa aaa @@ -75814,23 +77018,7 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +xGc rmC rmC rmC @@ -75866,10 +77054,26 @@ aaa aaa aaa aaa -azH aaa aaa aaa +aiu +cAJ +hlw +mLB +qLb +azN +siA +azN +wdU +guy +aiu +aht +yin +xcw +yin +aaa +aaa aaa aaa aaa @@ -75961,16 +77165,16 @@ chc cuZ chX bWV -ciz +bWV cvr ceP -cvR -bXJ -bXJ -crj +bWV +bWV +bWV +bWV cwO -fIT -cxh +bIT +aaa aaa aaa aaa @@ -76091,22 +77295,6 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC aaa aaa aaa @@ -76123,10 +77311,26 @@ aaa aaa aaa aaa -azH aaa aaa aaa +aiu +aiu +hzd +aiu +aiu +aiu +aiu +tXP +aiu +aiu +aiu +xLL +yin +oGX +yin +aaa +aaa aaa aaa aaa @@ -76218,17 +77422,17 @@ chd chE chY bWV -ciz -cvs +bWV +cgf cvB -cvS -cdw +bWV +rNF cjj -bXJ -bXJ +bWV fIT fIT -cxg +iUy +aaa aaa aaa rmC @@ -76348,22 +77552,6 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC aaa aaa aaa @@ -76380,10 +77568,26 @@ aaa aaa aaa aaa -azH aaa aaa aaa +aht +aiu +hKX +aiu +rrb +uAA +bEH +gtX +nso +aiu +tYu +xLL +ugu +oGX +yin +aaa +aaa aaa aaa aaa @@ -76477,13 +77681,13 @@ chZ bWV ciz ckb -cku +ceP cvT -bZo -cwx -cwE +bXJ +bXJ +crj ckv -ckM +fIT clb aaa aaa @@ -76605,22 +77809,6 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC aaa aaa aaa @@ -76634,12 +77822,28 @@ aaa aaa aaa aaa -aaa -aaa -aaa -azH -aaa -aaa +ait +ait +ait +aiu +aiu +aht +aht +aiu +iEX +azN +azN +azN +dZa +kZk +qGW +aiu +tPu +xLL +yin +prB +yin +xLL aaa aaa aaa @@ -76733,41 +77937,16 @@ bWV bWV bWV ciz -ckb +qpR cku -cvT -cwk +xIV +cdw cwy -cwF -ckw -ckN -clb -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +bXJ +bXJ +fIT +fIT +iUy aaa aaa aaa @@ -76804,6 +77983,31 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC "} (55,1,1) = {" rmC @@ -76862,39 +78066,11 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC aaa aaa aaa -aby -aed -aby -aht -aby -aby -aby -aht -aby -aby -aby aaa aaa -azH aaa aaa aaa @@ -76903,6 +78079,34 @@ aaa aaa aaa aaa +ait +ayz +azP +bZo +aiu +ait +ait +aiu +iLR +nso +sqt +uQR +dVP +jRI +kZk +aiu +gRo +xLL +hMg +uyI +cVq +xLL +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -76990,40 +78194,15 @@ crj ciN bWV ciz -ckc +cvt cvC cvV ceQ -ciA -bXJ -bXJ -fIT -fIT -cxg -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +xxl +mIO +vil +jnR +cxk aaa aaa aaa @@ -77061,6 +78240,31 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC "} (56,1,1) = {" rmC @@ -77113,45 +78317,16 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -aaa -aaa -aaa -aht aaa aaa aaa aaa -aht aaa aaa aaa aaa -aht aaa aaa -azH aaa aaa aaa @@ -77161,6 +78336,35 @@ aaa aaa aaa aaa +ait +ayA +azQ +azN +ckN +azN +azN +cAT +jsf +aiu +nso +aiu +aiu +aiu +dZa +aiu +eXX +xLL +ofi +rpY +vjD +xLL +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -77248,43 +78452,43 @@ cvd bWV ciz cvt -ceP -crk -bXJ -bXJ +cvC +cvV +fZq +gur cwG -cwO -fIT +qiG +oQY cxk aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC rmC rmC rmC @@ -77370,47 +78574,47 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa aiu -ait -ait -ait -aiu +ayB +azN +caS aiu ait ait -ait aiu -aiu -aht -aaa -azH -aaa -aaa +iPH +nKo +nKo +nKo +kpi +cHm +cHm +jst +sMA +xLL +mDs +kqF +uAE +xLL aaa aaa aaa @@ -77503,16 +78707,21 @@ ceP cdC ciO bWV -bWV -cgf +ciz +tSt cjl -bWV +sIO cwl -cwz -bWV +ciA +bXJ +bXJ fIT fIT -cxg +iUy +aaa +aaa +aaa +aaa aaa aaa aaa @@ -77523,17 +78732,12 @@ aaa aaa aaa aaa -cfN -cfN -cfN aaa aaa aaa aaa aaa aaa -cfN -cfN aaa aaa aaa @@ -77627,48 +78831,48 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC aaa aaa aaa -aiu -fIN -wwG -gGy -wYu -uQR -uaE -pdq -ajD -dci -aiu +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +adR +adR +adR aht -aaa -azH -aaa +ait +ayC +azR +ciJ +aiu aaa aaa +aiu +aCg +aiu +aiu +aiu +uaE +aiu +aiu +aiu +oKX +xLL +xLL +skq +xLL +xLL +aiu aaa aaa aaa @@ -77760,15 +78964,28 @@ ceP bXJ cve bWV -bXJ +ciz ckd ceP -bWV -bWV -bWV -bWV -cwR -cwR +crk +bXJ +bXJ +ccg +ckv +fIT +wkC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -77777,22 +78994,9 @@ aaa aaa aaa aaa -cfN -cfN -cfN -cfN -cfN -cyM aaa aaa aaa -cfN -cfN -cfN -cfN -cfN -cfN -cfN aaa aaa aaa @@ -77884,50 +79088,50 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC aaa aaa aaa -aiu -oFf -ycr -wDm -wYu -ajD -ajD -ajD -ajD -mwg -aiu +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aht -aaa -azH -aaa -aaa -aaa -aaa -aaa +aht +aht +aht +aiu +aiu +aiu +aiu +aiu +aiu +aiu +aiu +aCg +aiu +aqg +uXp +vgF +cHS +rif +aiu +aBa +aiu +srK +jsf +evQ +xEy +aiu +aiu +aiu aaa aaa aaa @@ -78017,14 +79221,16 @@ cuU cfm cfm cfm -cjH +cfm chF -cuQ -cvX -cke +bjO +cfm +xhj cky -cld -cCR +bWV +fIT +fIT +iUy aaa aaa aaa @@ -78033,25 +79239,23 @@ aaa aaa aaa cfN -cfN -cfN -cfN -cfN -cfN -cfN -aht aaa aaa aaa -cfN -cyM -cfN -cfN -cfN -cfN -cfN -cfN -cfN +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -78141,12 +79345,6 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC aaa aaa aaa @@ -78162,29 +79360,35 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aiu +agI +agI +amz +anT +agI +agI +azS +ciK +cle +cvR +cwE lcU sGr -hiw -wYu -ajD -jsf -ajD -rLi -tlc aiu -aht -axB +wYu +vxV +jsf +oTF +rLi +aiu +wnp +nKo +ujI rKr -axB -aaa -aaa -aaa -aaa +nKo +nKo +tBh +dLN +aiu aaa aaa aaa @@ -78274,15 +79478,16 @@ cuV ciD cfD chf -cfD +qgb cvu cvE -cvY -ckf -ckf -cle -cjm -cjm +cfm +bWV +bWV +bWV +cwR +cwR +aaa aaa aaa aaa @@ -78292,23 +79497,22 @@ aaa cfN cfN cfN -cyM -cfN -cyM -aaa -aht -aaa -aaa -aaa -aaa -aht aaa cfN cfN cfN +aaa +aaa +aaa +aaa +aaa +aaa cfN cfN -cfN +aaa +aaa +aaa +aaa aaa aaa aaa @@ -78384,12 +79588,6 @@ rmC rmC rmC rmC -xGc -rmC -rmC -rmC -rmC -rmC rmC rmC rmC @@ -78413,35 +79611,41 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aiu -aiu +adR +aht +agI +agM +agM +agM +agI +alZ +amK +anU +arv +agI +azY +cjf +clk +cvS +cwF +cTI kJw aiu -aiu -aiu -aiu +sOC +vCC +gmm cHS +uKR aiu +xNW aiu -aiu -axC -axB +wYu azN -axB -aaa -aaa -aaa -aaa +evQ +dVP +qGu +azN +aiu aaa aaa aaa @@ -78534,38 +79738,38 @@ cfE cfE cfo cvF -cvZ +oCG cwm -ckj -cwH -ckO -cjm -cfN +cwm +uIh +xYV +mZE aaa aaa aaa aaa aaa -cfN -cfN -cfN -aht aaa -aht -aaa -aht -aht -aht -aht -aht -aht aaa cfN cfN -cyM cfN cfN cfN +cfN +vHh +aaa +aaa +aaa +cfN +cfN +cfN +cfN +cfN +cfN +cfN +aaa +aaa aaa aaa aaa @@ -78655,22 +79859,6 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa aaa aaa aaa @@ -78680,21 +79868,41 @@ aaa aaa aaa aaa +adR aht -aiu +agI +agW +ahp +akb +akX +ama +ane +anV +aso +agI +azY +cjg +cnN +cwc +cwM +dci gwn aiu -apz -aqe -aoK -dcL -apB aiu -tpb -axC -ayz -azN -axB +aiu +ait +ait +aiu +aiu +aiu +aiu +ait +ait +aiu +aiu +qGu +bEJ +aiu aaa aaa aaa @@ -78746,11 +79954,7 @@ aaa aaa aaa aaa -aaa -aaa -aaa -bHI -aby +bIX aby aby bGH @@ -78791,38 +79995,38 @@ cgG bWV cfn ciR -cwa -cwn -ckg -ckz -ckP +qXE +vrQ +vrQ +cAj cjm -cfN -cfN -cfN -aaa -aaa -aaa -aaa -aaa -aaa +cjm +iye aht -aaa aht -aaa +aht +aht +aht +aht +cfN +cfN +cfN +cfN +cfN +cfN aht aaa aaa aaa -aaa -aht -aaa -aaa -aaa -aht +cfN +vHh +cfN +cfN +cfN +cfN +cfN cfN cfN -aaa aaa aaa aaa @@ -78912,12 +80116,6 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC aaa aaa aaa @@ -78927,32 +80125,26 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -ait -ait -ait -aiu -aiu -aht +adR aht +agI +agZ +ahr +akc +akZ +amq +anf +anW +asH +agI +ajD +ajD +ajD +ajD +ajD +dcL aiu -wRI -ajD -ajD -ajD -aoK -aBa -xyB aiu -aAa -axC -axB -hzd -axB -axC aaa aaa aaa @@ -78964,6 +80156,19 @@ aaa aaa aaa aaa +aiu +qGu +nso +aiu +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -79009,7 +80214,6 @@ bGD bGD bIT bJZ -bIT bMr bNs bOw @@ -79047,40 +80251,40 @@ ciT cvh cgG cfn -cvF -cwa +ciR +roU cwo -ckh -ckA -ckP +lxI +mKP +eNc cjm cfN cfN +aaa +aaa +aaa +aaa cfN cfN +cfN +vHh +cfN +vHh aaa -aaa -aaa -aaa -aaa -cjp -cyU -cjp -cyU -cjp -cjp -cyU -cjp -cyU -cjp -cyU -aht -aht aht aaa aaa aaa aaa +aht +aaa +cfN +cfN +cfN +cfN +cfN +cfN +aaa aaa aaa aaa @@ -79169,12 +80373,6 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC aaa aaa aaa @@ -79184,32 +80382,26 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -ait +adR +aht +agI +aha +ahQ +akd +alI +amr +ang +aoJ +atx aiV -ajB +ajD akr -aiu -ait -ait -aiu +cnP +cwj +cxg +dET lMU -apB -woq -lXc -nPA -egK -aBa aiu -azZ -axC -ayA -azP -aAW -axC aaa aaa aaa @@ -79221,6 +80413,19 @@ aaa aaa aaa aaa +aiu +qGu +gYI +aiu +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -79264,8 +80469,7 @@ aaa aaa bGE bGE -bIU -bHM +bGE bHM bHM bHM @@ -79305,45 +80509,45 @@ cid cgG cfn cvH -cwc -cwp -cki -ckB -ckP +cfm +sNS +eNc +eNc +bZp cjm -caS -caS -caS -caS +cfN +cfN +cfN +aaa +aaa +aaa +cfN +cfN +cfN +aht +aaa +aht +aaa +aht aht aht aht aht -cjp -cjp -ckH -cyY -ckH -ckH -ckH -ckH -czH -ckH -cyR -cyU -aaa -aaa aht aaa +cfN +cfN +vHh +cfN +cfN +cfN aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +rmC +rmC +rmC rmC rmC rmC @@ -79426,12 +80630,6 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC aaa aaa aaa @@ -79441,32 +80639,44 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -ait +adR +aht +agI +agI +ais +agI +agI +ams +anh +aoK +atI aiW ajC -ajD +cjk ali -ajD -ajD +cwk +cxh anq -aoe +hOx aiu -apB +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aiu +qGu aiu aiu +ait +ait aiu -aoK -aiu -azY -axC -ayB -azQ -aAX -axC aaa aaa aaa @@ -79513,12 +80723,6 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -bFE bGF bHJ pbm @@ -79560,47 +80764,47 @@ chG ciT cjo bWV -cvw +czW cvI ckQ clf -cwA -cwA +wyf +ehR cwS cjm cfN -caS +cfN cfN aaa aaa aaa aaa aaa -cjp -cCW -ckH -cyZ -ckH -czl -czr -czr -czI -ckH -ckH -cjp -cjp -cyU +aaa +aht +aaa +aht +aaa aht aaa aaa aaa aaa +aht +aaa +aaa +aaa +aht +cfN +cfN aaa aaa aaa aaa aaa -aaa +rmC +rmC +rmC rmC rmC rmC @@ -79687,43 +80891,31 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aiu +aed +adR +abI +abI +abI +abI +abI +agK +ahl +ajb +ake +alJ +amt +ani +aoL +aus aiX ajD aks -aiu -ait -ait -aiu +cnQ +cwn +cxL +dHg hOx -aDm -aDm -aDm -aoL -aso -aso -rrb -oPx -axC -ayC -azR -aAY -axC +aiu aaa aaa aaa @@ -79735,6 +80927,18 @@ aaa aaa aaa aaa +aiu +qGu +nso +aiu +kZk +cFr +ait +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -79776,8 +80980,8 @@ aaa aaa aaa aaa +aaa bGE -bHK bIV bKb bLo @@ -79817,37 +81021,37 @@ cgH cgH cvi cgG -cfn -ciR -cwa +czC +cAS +syn cjO -ckk -ckC -ckR +cwH +kMf +cwS cjm cfN -caS -caS -aht -aht -aht -aht -aht +cfN +cfN +aaa +aaa +aaa +aaa +aaa +aaa cjp -ckW -ckH -ckH -ckH -czl -czr -czB -czI -czV -ckH -cAr -cAB cyU cjp +cyU +cjp +cjp +cyU +cjp +cyU +cjp +cyU +aht +aht +aht aaa aaa aaa @@ -79855,9 +81059,9 @@ aaa aaa aaa aaa -aaa -aaa -aaa +rmC +rmC +rmC rmC rmC rmC @@ -79943,50 +81147,50 @@ rmC aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa adR -adR -adR -aht -ait -aiY +aaa +aem +aem +aem +aem +aem +aem ajE -akt +ajE +ajE +ajE +ajE +ajE +anj +apz +ajE +ajE +ajE +rjF +cqS +rjF +rjF +rjF +iYQ aiu aaa aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aiu -aCg -aiu -aiu -aiu -wRz -aiu -aiu -aiu -syn -axC -axC -azS -axC -axC -aiu -aiu -aiu +rMb +vcv +nKo +mrk +kPt ait -ait -aiu aaa aaa aaa @@ -80033,7 +81237,7 @@ aaa aaa aaa aaa -bGG +aaa bHL bIW bKc @@ -80076,41 +81280,41 @@ cid cgG cfn ciR -cwe -cwe -cwe -cwe -cwe -cwe -cwe -cwe -cfN -aaa -aaa -aaa -aaa -aaa +cfm +uFA +tPj +fPy +cwS +cjm +iye +iye +iye +aht +aht +aht +aht +aht cjp -cyP -ckH +cjp +lzT cyZ ckH -czl -czt -czC -czI -czW -cAg -cAs +kro +kro ckH -cAH -cjp +czI +ckH +cyT cyU aaa aaa +aht +aaa +aaa +aaa +aaa aaa aaa -cfN aaa aaa aaa @@ -80200,52 +81404,52 @@ rmC aaa aaa aaa +adR +aaa +aem +aep +aeF +afp +afF +agy +agL +ahm +agy +agy +agy +agy +ahv +aqe +aiz +ayM +ajM +cjC +ctS +cwp +cyy +dVp +jgr +aiu aaa aaa aaa aaa aaa aaa +llx aaa aaa aaa aaa -aaa -aaa -aht -aht -aht -aht -aiu -aiu -aiu -aiu -aiu -aiu -aiu -aiu -aCg -aiu -aqg -gjN -arc -atp -aus -aiu -wxb -aiu -xuv -aoe -ajD -hKX -aiu -apB aiu +wFB +jsf +cAT aBa oTC ait aaa -abN +bBW aaa aHA aKz @@ -80290,9 +81494,9 @@ aaa aaa aaa aaa +aaa bGH bGE -bIX bKd bLp bMu @@ -80333,42 +81537,42 @@ cvj bWV cfn cvJ -cwe +cfm cjP -ckl -ckD -ckS -clg -clk -cwe -cwe -cxB -cxJ -cxJ -cxJ -cyy +eNc +eNc +ouy +cjm +cfN +cfN +aaa +aaa +aaa +aaa +aaa +aaa cjp cyQ ckH +xja ckH +ipv +mXJ +mXJ +czM ckH -ckH -ckH -ckH -ckH -czW -cAg -cAt -ckH -czW -cAS +cHB +cjp +cjp cyU aht -aht -aht -cyM -cfN -cfN +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -80457,53 +81661,53 @@ rmC aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -afU -afU +adR +abI +aen +aeq +aeG +szG +szG +agc +szG +szG +agy +akT +alK +sJp pfz uqJ -afU -afU -ajF +aut +ayM +ajM aku alj alT skw -anr -aof -aiu -aqh +rjF +rjF +rjF +lqc +lqc +wPk +lqc +bBW lqc -aoe -atq -aut -aiu giO -aDm -kJo +lqc +ajM fAx -aDm -aDm -aDm -aDm -aDm -mLB -wUz -ait -aht -aht -aht +fAx +aiu +tCN +jsf +wFB +qGu +aiu +aiu +aaa +aaa +aaa aHA dqG aHA @@ -80547,10 +81751,10 @@ aaa aaa aaa aaa +aaa bGI bHM bHM -bNw bLq bMv bNw @@ -80589,43 +81793,43 @@ ciV cjq cgG cfn -ckE -ckT -xhj -xhj +ciR +cfm +jVB +wPp cwK odM -xhj -cxn -xhj -lqy -cxC -cxK -cxX -cyl -cyz -jgr +cjm +iye +iye +aht +aht +aht +aht +aht +aht +cjp cjQ -cjQ -cjQ -cjQ -cjQ -cjQ -cjQ -czL +ckH +ckH +ckH +ipv +mXJ +iEP +czM czY -cAi +ckH cAu cAC -cAJ -cAT cyU +cjp +aaa +aaa +aaa +aaa aaa aaa aaa -cfN -cfN -cfN aaa aaa aaa @@ -80714,53 +81918,53 @@ rmC aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa adR -aht -afU +aaa +aem +aer +aeH +szG +afG +agd agi agi -agi -afU +ajr +akU +aiy hwj ahu ahS oXe -afU -ajG +ayM +ajM akv alk alU amH -ans +ajM ePU -aiu +nUc aqi -ard +lqc asr -atp -auu -aiu +lqc +bBW +ajM ekU -aiu -asr -tyL -ajD +lAn +dCo +nwp +bGG nPA mtu aCc aiu -wxb +qGu wig -ait -aaa -aaa -aaa +aiu +aht +aht +aht aHA wqu aHA @@ -80805,11 +82009,11 @@ aaa aaa aaa aaa -bHN +aaa +bIY bGE -bKe bLr -bMw +bMx bNx bNw bOw @@ -80845,45 +82049,45 @@ ciE ciW cjr cgG -cvw -cvK -cwg -cjR -jFO -ckF -jFO -cxe -jFO -jFO -cxz -cxD -cxL -cxY -cym -cyA -vOw +czW +ceJ +cwe +cwe +cwe +cwe +cwe +cwe +cwe +cwe +cfN +aaa +aaa +aaa +aaa +aaa +cjp ijF -pXc -ckm -ckm -ckm -ckm -ckm +ckH +xja +ckH +ipv +odz +nXR czM -czZ -cAj +cAa +cAg cAv -cAD +ckH cAK -cAU +cjp cyU aaa aaa aaa +aaa cfN -cfN -cfN -cfN +aaa +aaa aaa aaa rmC @@ -80971,43 +82175,43 @@ rmC aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa adR -aht -afU +abI +aen +aes +aeU szG -sOC +afH +agv +szG +szG +agy iCV msX -dVI +agy ahv -ahT +ahU aiv -afU -ajG +agy +ajM akw all alV tfZ -vCC +ajM lHc -aiu -aiu -aiu -ait -ait -aiu -aiu -aiu -aiu -ait -ait -aiu +osW +tlc +ajM +rUj +ajM +ajM +rjF +rjF +rjF +ajM +xBh +bPm aiu aiu aiu @@ -81061,12 +82265,12 @@ aaa aaa aaa aaa -aht +aaa +aaa aqG bGE -cqW bKf -bMw +bMx bNy bNw bOw @@ -81103,7 +82307,7 @@ cgG cgG bWV cfn -ceP +cAU cwe cwr clm @@ -81120,7 +82324,7 @@ cxM cyB cjp cyR -ick +ckH ckH ckH ckH @@ -81134,14 +82338,14 @@ ckH cAa cAV cyU +aht +aht +aht +vHh +cfN +cfN aaa aaa -cfN -cfN -cfN -cfN -cfN -aaa aaa rmC rmC @@ -81228,43 +82432,43 @@ rmC aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa adR -aht -afU +aaa +aem +aet +aeV +afq +aga +agx +lem lem -mzl sJp -qMi +sJp +sJp iPU ahw ahU aiw -afU -ajH -ajH -ajH -ajH +ayO ajH +cjH +cvs +cww +cyz ant -aiu -aiu -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +jvi +jvi +cjH +jvi +ito +lAj +ezx +eyu +puy +xMk +tFp +kKB +kFd aiu aCd hHr @@ -81317,11 +82521,11 @@ aaa aaa aaa aaa -aht +aaa +aaa aht aqG bGE -izF ros bMx bNz @@ -81360,44 +82564,44 @@ chn cfE cfE cvy -cfG -cwe -cwe +cCW +qAM +fWv fWv qOE ckV -qOE +fWv cln -cwe -cfN -aaa -aaa -aaa -aaa -aaa -cjp -cyS -ick -cyZ -ckH -czo -czu +fWv +cIN +ggN +nOF +xld +jzw +vrn +sKq +czD +czD +czD +czD +czD +czD czD czN -cAa -cAg +kQH +bNC cAs -ckH +dwq cAM -cjp +xEb cyU aaa aaa +aaa cfN cfN cfN -cfN -cfN +aaa aaa aaa rmC @@ -81485,17 +82689,17 @@ rmC aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa adR -aht -afU +abI +aen +aeu +aeW +afr +afG +agz +szG agj -agv +agy agF agT ahj @@ -81503,25 +82707,25 @@ ahx ahV aix aiZ -ajH +azZ akx -alm +avv alW amI anu -aog -aiu -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +wxJ +wxJ +tnP +vOw +wxJ +dnG +vQx +wxJ +opr +awI +axL +bZV +bPm aiu nyO ezJ @@ -81576,11 +82780,11 @@ aaa aaa aaa aaa +aaa aqG bGE bGE bHM -bHM bNA bHM bSZ @@ -81617,40 +82821,40 @@ cho cvk cdx kXx -csS -cfm -cwe -fWv -qOE +izF +rnE +xjc mKc -qOE -cln -cwe -caS -aht -aht -aht -aht -aht -cjp +oHk +mKc +kOW +mKc +mKc +eKC +vQN +uzy +mWN +kRY +iYp +gPs cko -ick -ckH -ckH -clp +shw +czv +czv +czv czv czv czO cli -ckH +hBu cAy cAB +uTZ +vTc cyU -cjp -aht -aht -aht -cyM +aaa +aaa +aaa cfN cfN cfN @@ -81742,19 +82946,19 @@ rmC aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa adR -aht -afU -afU +aaa +aem +aeD +aeX +afC +aeW +agA +aeW +aeW agw -afU -afU +akV +alL ahk ahy ahW @@ -81767,18 +82971,18 @@ alX amJ anv aoh -aiu -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +ovB +aoh +woq +ari +lXd +mdS +nxf +sDV +xRD +axL +bZV +bPm aiu awE qGu @@ -81834,9 +83038,9 @@ aaa aaa aaa aaa -bIY -bIY -aht +aaa +cwR +bKe aht bNB abI @@ -81873,45 +83077,45 @@ cfm ciF cuQ cfm -cfm +xNL jSa -cfm cwe +xNx ckp ckI ckX -ckI -cln +het +eeG cwe -cfN -cfN -aaa -aaa -aaa -aaa +cwe +jee +cdV +cdV +cdV +iyL cjp cyT ick -cyZ -ckH -czp ckH ckH -czP ckH ckH -cjp -cjp +ckH +ckH +hlj +cAg +cAt +ckH +qdY +lEh cyU -aht -aaa aaa aaa cfN cfN cfN cfN -aaa +cfN aaa aaa rmC @@ -81999,43 +83203,43 @@ rmC aaa aaa aaa -aaa -aed adR abI -abI -abI -abI -abI -afX +aem +agy +agy +afD +szG +agB +szG agl -agx +agy agH -agV -ahl +msX +agy ahz ahX aiz -ajb -ajH +agy +ajM akz alo -alY -amK +amg +amg anw -aoh -aiu -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +amg +oFf +amg +wwG +avv +mqS +ajM +ajM +ajM +rjF +jHl +bZV +bPm aiu aiu kFx @@ -82103,7 +83307,7 @@ aby abI bSn uZb -cqS +bNs bNs bQe bOw @@ -82130,39 +83334,40 @@ cio chq ciX cfm +cAi +eNc +cjm +cwe +gqi +gXv +dRT +gXv +sgD +cwe cfN -cwA -cfN -cwe -cwe -cwe -cwe -cwe -cwe -cwe -caS -caS -aht -aht -aht -aht +aaa +aaa +aaa +aaa +aaa cjp -cjp -xjc +oxo +ick xja ckH czq czw -ckH +oIU czQ +hlj +cAg +cAv ckH -cyR +wnE +cjp cyU aaa aaa -aht -aaa -aaa cfN cfN cfN @@ -82170,7 +83375,6 @@ cfN cfN aaa aaa -aaa rmC rmC rmC @@ -82259,40 +83463,40 @@ aaa adR aaa aem -aem -aem -aem -aem -aem -aiA -aiA -aiA -aiA -aiA +aeE +afo +afE +agb +agy aiA +aho +agy +agy +agy +agy ahA ahY -aiA -aiA -aiA +auu +agy +aAa akA alp -akA -akA -akA +amg +cyP +dVI aoi -aiu -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +oPx +apG +wxb +wxJ +wIa +ceD +eyu +pmC +xMk +axL +bZV +tMI ebD sbY fuP @@ -82387,47 +83591,47 @@ cgM chr chL cfm -cfN +cAi xSd -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -aaa -aaa -aaa -aaa -aht -cjp -cyU -cjp -cyU -cjp -cjp -cyU -cjp -cyU -cjp -cyU +cjm +cwe +gqi +gXv +qYW +gXv +sgD +cwe +iye aht aht aht aht -cyM +aht +cjp +egu +ick +ckH +ckH +njI +kix +kix +xGY +oWD +ckH +nWD +cAC +cyU +cjp +aht +aht +aht +vHh cfN cfN cfN cfN aaa aaa -aaa -aaa rmC rmC rmC @@ -82518,38 +83722,38 @@ aaa aem aeo aeC -aeT +afn afn agy afZ agn -agy -agy -agy +ajs +akW +alM agy ahB ahZ aiB -ajc -ajM +agy +aAV akB alq -alZ +amg amL anx -aoj -aiu -aaa -aaa -aaa -aaa -aaa -aaa +aoo +pdq +apG +wDm +wxJ +mlt +xNn +aux avp -aaa -aaa -aaa -aaa +awI +axL +mGa +pFy ebD aCe gPV @@ -82644,47 +83848,47 @@ cip chs ciY cfm -cfN -cwA -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN +cAi +eNc +cjm +cwe +rRv +rSE +wDq +rSE +sgD +cwe cfN cfN aaa aaa aaa -aht -aaa -aaa -aht -aaa -aaa -aht -aaa -aht aaa +cjp +jqZ +ick +xja +ckH +vgg +ckH +ckH +rzm +ckH +cHB +cjp +cjp +cyU aht aaa aaa aaa -aaa -aaa cfN cfN -aaa cfN cfN aaa aaa aaa -aaa rmC rmC rmC @@ -82770,43 +83974,43 @@ rmC aaa aaa aaa -adR +aaa abI -aen -aep -aeD -aeU -aeU -afC -aeU -aeU -agy -agI -agW -agA -ahC -aia -aiC -ajc -ajM -akC -alr -ama +aem +aem +aem +aem +aem +aem +aem +aem +aem +aem +aem +aem +alx +alx +alx +alx +alx +alx +alx +amg amM -akA -akA -akA -apE +dYe +aoo +peE apE +wRz ari -apE -bBW -apE +nDP +atw +nxf avq -apE -ajM -bZV +xRD +axL bZV +uMf gSH xJy sJr @@ -82901,44 +84105,44 @@ cfm cht cfm cfm +cAi +eNc cfN -cwA -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -aaa -aaa -aaa +cwe +cwe +cwe +cwe +cwe +cwe +cwe +iye +iye aht aht aht aht +cjp +cjp +nYC +fug +ckH +dYI +lQo +ckH +wdY +ckH +cyT +cyU aaa aaa aht -aht -aht aaa -aht aaa cfN cfN -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +cfN +cfN +cfN aaa aaa aaa @@ -83027,43 +84231,43 @@ rmC aaa aaa aaa -adR aaa -aem -aeq -aeE -aeU -afo -afD -aga -aga -agz -aie -aiH -ahm -ahD +aaa +aed +adR +abI +aaa +aaa +aaa +aaa +aaa +aaa +aby +abI +abI +alx aib aiD -ajc -ajM +azG +aAW akD als amb amN -ajM +egK aok aoO apF -apE +wRI wxJ -apE -bBW +kSC ajM -avr -awH -axE -ayE -aAb +ajM +ajM +rjF +axL +bZV +pFy ebD jjC eEp @@ -83158,9 +84362,8 @@ ciq chu ciZ cfm -cfN -cwA -cfN +cAi +kJo cfN cfN cfN @@ -83174,27 +84377,28 @@ cfN aaa aaa aaa +aaa aht -aaa -aaa +cjp +cyU +cjp +cyU +cjp +cjp +cyU +cjp +cyU +cjp +cyU aht -cfN -cfN -cyM -cfN aht -aaa aht +aht +vHh +cfN cfN cfN cfN -aaa -aaa -aaa -aaa -aaa -aaa -aaa aaa aaa aaa @@ -83284,41 +84488,41 @@ rmC aaa aaa aaa -adR +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aby abI -aen -aer -aeF -aeU -afp -afE -aeU -aeU -agy -agK -agY -agy -ahB +abI +alx aic -aiE -agy -ajM +aiF +aiF +aAX akE alt amc -amO -ajM -aol +aok +eSB +aoo aoP apG -ajM +wUz arj -ajM -ajM -akA -akA -akA -ajM +rtg +ceD +eyu +vnI +xMk +axL ayF aAc xLC @@ -83415,43 +84619,43 @@ cfm cfm cfm cfm +cAj +eNc +cfN +cfN +cfN +cfN +cfN +cfN +cfN cfN -cwA -cjm cfN cfN cfN aaa aaa -cfN -cfN -cfN -cfN -aaa aaa +aht aaa aaa aht aaa -cfN -cyM -cfN -cfN -cfN -cfN -cyM -cfN -cyM -cfN -cfN -cfN -cfN +aaa +aht +aaa +aht +aaa +aht aaa aaa aaa aaa aaa +cfN +cfN aaa +cfN +cfN aaa aaa aaa @@ -83541,43 +84745,43 @@ rmC aaa aaa aaa -adR aaa -aem -aes -aeG -aeV -afq -afF -agb -agb -agA -agA -agA +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aby +abI ahn -ahF -aic +alx +aqB aiF ajd ajJ akF alu amd -amP +aoo any aom -aom -akF -aom +pia +tpb +wWJ ark asu atv aux avs awI -axF -ayL -aAd +axL +gLv +pFy ebD aCf hnu @@ -83663,38 +84867,20 @@ arF crO crO crO -crO -crO -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN +aaa +aaa +cjm +cjm +cjm +cjm +cjm +cjm +cjm +cAj iXx cjm cfN cfN -aaa -aaa -aaa -aaa -cfN -cfN -aaa -aaa -aaa -aaa -aaa -cyL -cfN -cfN -cfN -cfN -cfN -cfN cfN cfN cfN @@ -83706,13 +84892,31 @@ cfN aaa aaa aaa -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aht +aht +aht +aht +aaa +aaa +aht +aht +aht +aaa +aht +aaa +cfN +cfN +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa rmC rmC rmC @@ -83798,21 +85002,21 @@ rmC aaa aaa aaa -adR +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aby abI -aen -aet -aeH -peE -afo -afG -aeU -eSB -agy -agL -agZ -aho -ahG +abI +alx aid aiG aje @@ -83823,16 +85027,16 @@ ame amQ anz aon -aon +pJy apH aqm -aon +kau asv atw -aon +nxf avt awJ -axG +pRz ayG pFy aiu @@ -83871,7 +85075,7 @@ aaa aaa aaa aYG -bbR +bHN bbR bnp baK @@ -83917,24 +85121,48 @@ bva bIZ bIZ bIZ -aaa -aaa -aaa -aaa -aaa -aaa -cfN -cfN -cfN -cfN -cfN -cfN -cfN -xYV +aht +aht +aht +aht +aht cjm +cvK +cjm +cfN +cfN +cfN +cfN +cAj +eNc +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN +aaa +aaa +aaa aht aaa aaa +aht +cfN +cfN +vHh +cfN +aht +aaa +aht +cfN +cfN +cfN aaa aaa aaa @@ -83944,32 +85172,8 @@ aaa aaa aaa aaa -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN -cfN aaa aaa -aaa -rmC -rmC -rmC -rmC -rmC -rmC -rmC rmC rmC rmC @@ -84052,24 +85256,24 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC aaa aaa aaa -adR aaa -aem -aeu -tnP -dYe -aeH -afH -aeH -aeH -agB -agM -aha -ahp -ahH +aaa +aaa +aaa +aaa +aaa +aby +abI +abI +alx aie aiH ajf @@ -84081,21 +85285,21 @@ amR anA aoo ana -aoo +amg aqn arl asw -atx -auz -avu +ajM +ajM +ajM rjF -axG +xxK ayH aAe aBc aCh -eQZ -eQZ +kZF +kZF aFk aFU eQZ @@ -84128,7 +85332,7 @@ aZx aZx aYG aYG -baK +bIU baK bnq baM @@ -84174,24 +85378,49 @@ caZ cbS ccN bIZ +xgh +xgh +xgh +xgh cjm cjm +cwg cjm -cjm -cjm -cjm -cjm -cjm +cfN +kJo +cfN +cfN +cAj +eNc cjm cfN cfN cfN +fon +aaa cfN -qWo -cjm -cjm +cfN +cfN +cfN +aaa +aaa +aaa +aaa aht aaa +cfN +vHh +cfN +cfN +cfN +cfN +vHh +cfN +vHh +cfN +cfN +cfN +cfN aaa aaa aaa @@ -84201,32 +85430,7 @@ aaa aaa aaa aaa -cfN -cfN -cfN -cfN -cfN -cfN -cfN aaa -aaa -cfN -cfN -cfN -cfN -cfN -cfN -cfN -aaa -aaa -aaa -rmC -rmC -rmC -rmC -rmC -rmC -rmC rmC rmC rmC @@ -84309,43 +85513,43 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC +aaa +aaa aaa aaa aaa -adR -abI -aem -agy -agy -lGp -aeU afI -aeU +abI jXF -agy -agN -agY -agy -ahI -aif -aiB -agy -ajM -akI +jXF +cnJ +cnJ +jXF +alx +alx +alx +alx +alx +alx alx amg amg anB -amg +jFO aoQ amg aqo -alv +kau asx -ajM -ajM -ajM -akA +seG +hBa +hGp +nJG axH ayI aAf @@ -84399,7 +85603,7 @@ bxZ bzA bAK bBX -bDg +bDh bEk bva bva @@ -84429,51 +85633,51 @@ aaa bIZ cba cbT -bDi +bRD ozO -cwA -cwA -cwA -cwA vco -cwA -cwA -cwA -cwA -xYV -bNE -xYV +vco +vco +vco +vco +vco +mUU +cjm +cwg +eNc +czt +cfN qWo lxI xVt -cjm +qGf aht -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +aht +fon aaa aaa cfN cfN -cfN -aaa aaa aaa aaa aaa aaa +nix +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN cfN cfN cfN cfN -aaa aaa aaa aaa @@ -84566,46 +85770,46 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC aaa aaa aaa -adR aaa -aem -aeW -ovB -utg -afr -agy -agc -ago -agy -agy -agy -agy +aaa +aby +aaa +jXF +ajF +sdk +sdk +amu ahJ aig aiJ -agy +azI ajN akJ aly -amg +cwx amS anC aop aoR -apJ +jXF apN -aon +arl aty atz -aux avv -awI -axG +avv +xgz +gZF ayL -aAi +axI aBd aCi aDo @@ -84656,8 +85860,8 @@ bya bzB bAL bBX -bDh -bEl +bDi +nNJ bva bGK bHQ @@ -84685,27 +85889,28 @@ bva aaa bIZ cbb -bDi +bSq ccO bva -cjm -cjm +xgh +xgh xgh xgh cjm -cjm -cjm -xgh -xgh -cjm -cjm -cjm +jtB +cxz cjm eNc -pia +czl +cjm +cfN +cfN +eNc +cjm cjm aht aaa +fon aaa aaa aaa @@ -84714,23 +85919,22 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN +cfN aaa aaa aaa @@ -84823,46 +86027,46 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC aaa aaa aaa -adR aaa -aem -aeX -iLR -iPH -iPH -agy -agd -agp -agC -agO -ahb -agy +aaa +aby +aaa +cnJ +ahL +sdk +sdk +amv ahK -aih +jXF aiK -agy -ajO -akK -alz -amg -amT -anD -amX +ajQ +ajQ +ami +juw +ami +anE +anE +kAX aoS -apJ +jXF aqq -aon +aIz atB atA -auA avw -awJ -axG -ayL -aAi +avw +isH +cFH +xDw +uMf aBd aCj aDp @@ -84942,42 +86146,28 @@ bIZ aaa bva bva -bNK +ckE bva bva aht aht -fon -fon aht aht +cjm +cqW +cxD +vco +vco +vco +vco +vco +mUU +eNc +tyL +cjm +aht +aaa mau -fon -fon -aht -aht -aht -cjm -cjm -cjm -cjm -aht -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa aaa aaa aaa @@ -84986,8 +86176,22 @@ aaa aaa aaa aaa +cfN +cfN +cfN +cfN +cfN +cfN +cfN aaa aaa +cfN +cfN +cfN +cfN +cfN +cfN +cfN aaa aaa aaa @@ -85080,44 +86284,44 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC aaa aaa aaa aaa -abI -aem -aem -aem -aem -aem -aem -aem -aem -aem -aem -aem -aem +aaa +aby +aaa +cnJ ahL +sdk +alN +sdk ahL -ahL -ahL -ahL -ahL -ahL -amg +jXF +auI +ajg +ajQ +cjZ +cvw +cwz amU anE -amX +kAX aoT -apK +cnJ aqr arl awK -atD +ajM auz avx rjF -axG +lTx ayJ aAg aBe @@ -85171,7 +86375,7 @@ bzC bzC bBY bDi -bEn +nNJ bva bGM bHR @@ -85200,54 +86404,54 @@ aaa aaa bIZ csy -bQl -cqX -xNx -ctS -cFB -aaa -aaa -aaa -aaa +bIZ +aht aaa aaa aaa aaa +cjm +cjm +xgh +xgh +xgh +xgh +xgh +cjm +cAD +eNc +ukn +cjm +aht aaa fon -fon -aht -aht -nKo aaa aaa aaa -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +cfN +cfN +cfN +aaa +aaa +aaa +aaa +aaa +aaa +cfN +cfN +cfN +cfN +aaa +aaa +aaa +aaa rmC rmC rmC @@ -85337,45 +86541,45 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC aaa aaa aaa aaa -aaa -aed -adR -abI -aaa -aaa -aaa -aaa -aaa -aaa +cFB aby -abI -abI +aaa +cnJ ahL -aii +sdk +sdk +sdk +ahL +jXF aiL ajg -ajP -akL +ajQ +anE cBi -amh +amV amV anF -amW +kJN aoU apL aqs -aon +gNq asz ajM -ajM -ajM -akA -axI -ayL +quY +uFZ +nDM +axL +axG aAh aBf aCl @@ -85415,11 +86619,11 @@ biL bjI bgd bmd -bnu -boq +bwt +bvb bpu -boq -boq +bvb +bvb btQ bvb bwt @@ -85459,7 +86663,33 @@ bva bSq bva bva -rnE +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +cAD +cjm +cjm +cjm +aht +aaa +fon +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -85479,32 +86709,6 @@ aaa aaa aaa aaa -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC rmC rmC rmC @@ -85594,15 +86798,11 @@ rmC rmC rmC rmC -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +rmC +rmC +rmC +rmC +rmC aaa aaa aaa @@ -85610,30 +86810,34 @@ aaa aaa aby abI -abI +jXF +ajG +sdk +alN +sdk ahL -aij -aiM +jXF aiM +azJ ajQ -akM +ami juw ami -amW -anG -amX +anE +juw +lAL aoV -apJ +cnJ aqt arm rdB -atz -aux +jmt +hCn avy -awI +pEZ +axL axG -ayL -aAi +pFy aBe aCm aCk @@ -85715,15 +86919,41 @@ bXa bRD bWl cdE -bIZ -rnE -aaa -aaa -aaa -nge -adR -adR -adR +ckF +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +cAH +lac +tRZ +quc +tRZ +quc +iyP +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -85736,32 +86966,6 @@ aaa aaa aaa aaa -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC rmC rmC rmC @@ -85851,26 +87055,26 @@ rmC rmC rmC rmC -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +rmC +rmC +rmC +rmC +rmC aaa aaa aaa aaa aaa aby -abI -sdk +aaa +cnJ ahL -aik -aiM +sdk +sdk +sdk +ank +jXF +avr ajh ajR akN @@ -85880,17 +87084,17 @@ amX anH aoq aoW -apM +jXF aqu arn asA atC -auA +lhq avz -awJ +jiC +axL axG -ayL -aAi +pFy aBd aCn aDt @@ -85928,7 +87132,7 @@ bid bgV bjK bgd -bmf +btP bnv bor bpv @@ -85941,7 +87145,7 @@ byd bzE bAN bnv -bDi +bEL bEp bsn bva @@ -85972,15 +87176,41 @@ bva bva bva bva +ckW bva -ukn bIZ bva bva -aht -aht -aht -aht +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +mZE +aaa +mZE +aaa +mZE +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -85993,32 +87223,6 @@ aaa aaa aaa aaa -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC rmC rmC rmC @@ -86108,24 +87312,24 @@ rmC rmC rmC rmC -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +rmC +rmC +rmC +rmC +rmC aaa aaa aaa aaa aaa aby -abI -abI -ahL +aaa +cnJ +aka +sdk +sdk +amw +ans ail aiN aji @@ -86137,17 +87341,17 @@ amY anI aor aoX -apI -apO +awO +awO aro jen -atD -auz -avA -rjF +awO +awO +awO +awO +jHl axG -ayL -aAi +pFy aBd aCo aCk @@ -86185,7 +87389,7 @@ bie biN bgd bgd -bmf +btP bnv bos bpw @@ -86242,6 +87446,7 @@ aht adR aaa aaa +cFB aaa aaa aaa @@ -86312,7 +87517,6 @@ rmC rmC rmC rmC -rmC "} (92,1,1) = {" rmC @@ -86365,25 +87569,25 @@ rmC rmC rmC rmC -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +rmC +rmC +rmC +rmC +rmC aaa aaa aaa aaa aaa aby -abI -abI -ahL -aim +aaa +cnJ +agP +sdk +alY +amx +anN +jXF aiO ajj ajT @@ -86392,19 +87596,19 @@ alA aml amZ anJ -amX +lGp aoY -amg +awO sBA arp asB -ajM -ajM -ajM -akA +qpE +lsz +ngq +cym axJ -ayL -aAi +axG +pFy aBd aBd aBd @@ -86442,7 +87646,7 @@ bgd bga bgd bkW -bmf +btP bnv bot bpx @@ -86499,15 +87703,15 @@ aht nge aaa aaa -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa rmC rmC rmC @@ -86608,6 +87812,7 @@ rmC rmC rmC rmC +xGc rmC rmC rmC @@ -86626,41 +87831,40 @@ rmC rmC rmC rmC -rmC -aaa aaa aaa aaa aaa aaa aby -abI +aaa +jXF agP -agQ -agQ -agP -ahL -ahL -ahL -ahL -ahL -ahL -ahL -amg -amg +sdk +sdk +amy +anO +jXF +amn +azL +aAY +amZ +jXF +jXF +cyY anK -aos +aow aoZ -amg +awO aqv -aro +pCF jxK atE auB -avB -awL -axK -ayM +jTx +awM +axL +axG aAj aBg aCp @@ -86889,34 +88093,34 @@ aaa aaa aaa aaa -aaa aby -aaa -agP +abI +jXF cnJ -ahq -ahq -ahM -ain -aiP +cnJ +cnJ +jXF +jXF +jXF +ajU ajk ajU akQ -alB +cnV amm anb anL -aot -apa -agP +aow +asI +awO aqw -arp -tTZ +jYO +cxe atF -alv -alv +kRH +jTx awM -axG +axL ayN aAk axG @@ -87147,34 +88351,34 @@ aaa aaa aaa aaa -aby aaa -agQ -ahd -ahq -ahq +aaa +abI +abI +abI +cnV ahN aio -agP +avu ajl ajV -ajV -alC +cka +cnV amn -alC -alE -aou +czB +fIN +aow apb -agP +awO aqx -arq +auC asD atG -auC -auC -awN +cxX +jfY +cym axL -ayO +axG aAl aBh aBh @@ -87211,7 +88415,7 @@ bha bhL aHN bjj -xQc +bjL bkY bmi bjN @@ -87404,33 +88608,33 @@ aaa aaa aaa aaa -aby aaa -agQ -ahd -ahq -cnT -ahq -ahd -agP +aaa +aaa +aaa +aht +cnV +anP +aiq +ajY ajm ajW -ajV -alD +ckf +cnV amo anc anM -aou -apb -agQ +aow +apa +awO aqp -arp +mAU asE -ajM +xNO auD avC -akA -axJ +cym +jHl axG aAm aBi @@ -87468,7 +88672,7 @@ bhb aDZ aHN biR -bjL +rvH bkZ bmj bnw @@ -87655,39 +88859,39 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC aaa aaa aaa aaa aaa -cFB -aby -aaa -agQ -ahd -ahq -ahq -ahq -ahd -agP +aht +cnV +anQ +arc +avH ajn -ajW -ajV -alE +bNE +ckw +cnV amp and -and -aov -apc -apP -aqy -arr -asC -ajM -auE -avD +gjN +aow +apa awO -axG +awQ +awQ +asC +vOQ +awQ +awQ +cym +axJ axG aAm aBi @@ -87912,39 +89116,39 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC aaa aaa aaa aaa aaa -aaa -aby -abI -agP -cnN -ahq -cnT -ahq -ahd -agP +aht +cnV +anR +aiq +axC ajo ajX -ajV -alC -amn -alC -alE +ckD +cnV aow -apd -agQ -aqz +aow +aow +aow +apj +awO +art ars asy atH auF avE -awP -axG +awM +axL ayP aAn aBi @@ -87982,10 +89186,10 @@ aJI aDZ aHN biT -bjL +bnx kSO -bjL -bjL +bnx +bnx boz bpB bqZ @@ -88169,41 +89373,41 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC aaa aaa aaa aaa aaa -aaa -aby -aaa -agQ -ahd -ahq -ahq -ahq -aip -agP +aht +cnV +anS +aiq +ajY ajp ajY -ajV -alF -amq -ane -anN -aox -ape -agP +ckM +cnV +aaa +aaa +aqF +aoy +apj +awO aqA art asF -ajM +ete auG avF -awQ -axG +awM +axL ayQ -axG +rRj aBi aCt aDy @@ -88238,11 +89442,11 @@ bgi aJI aDZ aHN -bjL -bjL +bnx +bnx blb bml -bjL +bnx bnv bpC bra @@ -88426,38 +89630,38 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC aaa aaa aaa aaa aaa -aaa -aby -aaa -agQ -cnP -ahq -ahq +aht +cnV ahO aiq aiQ ajq ajZ akR -alG -amr -anf -anO -aoy +cnV +aaa +aaa +aqF +apc apf -ajM -ajM +awO +xkB aru asG -ajM -auH -avG -awR +gBu +onE +tTZ +kjp axM ayR aAo @@ -88495,10 +89699,10 @@ aaw aJI aDZ aHN -bjL +cBL bjP -blb -bjL +wtE +fbX bnx boA bpD @@ -88683,37 +89887,37 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC aaa aaa aaa aaa aaa -aaa -aby -aaa -agQ -cnQ -ahq +aht +cnV cnV -ahP air -agP -agP -agP +ayy +ayy +ayy cCS -alH -ams -alH -anP -agP -apg -ajM -aqB -arv -asH -atI -auI -avH +cnV +aaa +aaa +aqF +arw +apj +aqF +awO +awO +awO +awO +awO +aCD awR awR awR @@ -88754,10 +89958,10 @@ aDZ bih biW wUf -wUf +xQc bmn iGJ -bjQ +cFG bpE brc bsy @@ -88940,35 +90144,35 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC aaa aaa aaa aaa aaa aaa -aby +cnV +aht +abI +abI +abI +abI +abI +cnV aaa -agP -cnQ -ahq -ahq -ahQ -ais -agP -ajr -aiR -akT -aiR -amt -aiR -anQ -aiR -aph -ajM -aqC -arw -asI -aqC +aaa +aqF +arx +apj +aoz +xyB +aaa +aaa +xyB auH avI auH @@ -89012,7 +90216,7 @@ bii biX bjR blc -biX +vwY bny aax bpF @@ -89178,7 +90382,16 @@ rmC rmC rmC rmC -xGc +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC rmC rmC rmC @@ -89203,29 +90416,20 @@ aaa aaa aaa aaa -aby -abI -agP -agQ -agQ -agQ -agP -agP -agP -ajs -aiR -akU -alI -amu -ang -anR -aiR -aph -ajM -aqD -arx -asJ -aqC +aaa +aaa +aaa +aaa +aaa +aaa +aqF +lUz +apj +ckB +xyB +aaa +aaa +aaa auH avJ awS @@ -89267,7 +90471,7 @@ aJI aDZ bij biY -rvH +biY biY biY biY @@ -89454,6 +90658,15 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +xGc +rmC aaa aaa aaa @@ -89463,26 +90676,17 @@ aaa aaa aaa aaa -abI -abI -abI -abI -abI -abI -ajs -aka -akV -alJ -amv -anh -anS -aiR -api -ajM -aqC -ary -asK -aqC +aaa +aaa +aaa +aqF +lXc +apj +ckB +xyB +aaa +aaa +aaa auH avK auH @@ -89711,6 +90915,15 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC aaa aaa aaa @@ -89723,23 +90936,14 @@ aaa aaa aaa aaa -aaa -aaa -abI -ajs -akb -akW -alK -amw -ani -jvi -aiR -aph -ajM -aqC -arz -asL -atJ +aqF +lUz +apj +ckB +xyB +xyB +xyB +xyB auH auH auH @@ -89968,6 +91172,15 @@ rmC rmC rmC rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC +rmC aaa aaa aaa @@ -89979,25 +91192,16 @@ aaa aaa aaa aaa -cFB aaa -aaa -abI -ajs -akc -akX -alL -amx -anj -anU -aiR -apj -ajM -ajM -ajM -ajM -ajM -ajM +aqF +lXv +asK +ckB +ckB +apR +aoz +aoz +aoz avL auH auH @@ -90231,6 +91435,9 @@ rmC rmC rmC rmC +rmC +rmC +rmC aaa aaa aaa @@ -90239,20 +91446,17 @@ aaa aaa aaa aaa -abI -ajs -akd -akX -alJ -amy -alJ -anV -aiR +aaa +aaa +aaa +aaa +aqF +aqF apk apQ aqE aqE -aqE +cxB atK auJ aqE @@ -90488,6 +91692,9 @@ rmC rmC rmC rmC +rmC +rmC +rmC aaa aaa aaa @@ -90496,15 +91703,12 @@ aaa aaa aaa aaa -abI -ajs -ake -akX -alM -amz -ank -anT -ajs +aaa +aaa +aaa +aaa +aaa +aqF apl aoz aqF @@ -90569,7 +91773,7 @@ bBc bCm bDr bEz -wtE +bnF buh bIg bjc @@ -90745,6 +91949,9 @@ rmC rmC rmC rmC +rmC +rmC +rmC aaa aaa aaa @@ -90753,15 +91960,12 @@ aaa aaa aaa aaa -aiR -ajs -ajs -akZ -alN -alN -alN -anW -ajs +aaa +aaa +aaa +aaa +aaa +apR apm apR aqG @@ -91005,19 +92209,19 @@ rmC rmC rmC rmC -rmC -rmC -rmC aaa aaa aaa aaa -aiR -abI -abI -abI -abI -abI +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aoz apn aoz @@ -91090,7 +92294,7 @@ bJo bGZ bLJ bMK -bjc +wZT bCz bPB bQp @@ -91262,9 +92466,6 @@ rmC rmC rmC rmC -rmC -rmC -rmC aaa aaa aaa @@ -91275,9 +92476,12 @@ aaa aaa aaa aaa -aoz -ahr -aoz +aaa +aaa +aaa +cdm +cdm +cdm aqG arD asO @@ -91346,8 +92550,8 @@ bIh bkh bKz bnH -boN -cBL +vik +bjc bCz bPB bQq @@ -91519,9 +92723,6 @@ rmC rmC rmC rmC -rmC -rmC -rmC aaa aaa aaa @@ -91533,8 +92734,11 @@ aaa aaa aaa aaa +aaa +aaa +aht cdm -cdm +aht aqG arE arA @@ -91598,13 +92802,13 @@ bCp bpP bEC bFT -bHa bIi +jZZ bJp bKA bLK bMM -bjc +iPu bCz bPB bPB @@ -91774,9 +92978,6 @@ rmC rmC rmC rmC -xGc -rmC -rmC rmC rmC aaa @@ -91790,6 +92991,9 @@ aaa aaa aaa aaa +aaa +aaa +aht aht apS ala @@ -91860,7 +93064,7 @@ bIj bJq bIj bFU -bFU +bjc bjc bCz bPC @@ -92033,9 +93237,9 @@ rmC rmC rmC rmC -rmC -rmC -rmC +aaa +aaa +aaa aaa aaa aaa @@ -92116,7 +93320,7 @@ bHb bIk bJr bKB -bKB +eQk bFU bNV bCz @@ -92286,13 +93490,13 @@ aaa aaa aaa aaa -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -92628,12 +93832,12 @@ bEF bFU bHd bIm -bJr +bJz bKD -bKD -bFU -bNX -bCz +sMZ +eRv +npE +gHB bPE bQs bRg @@ -92883,13 +94087,13 @@ bCu bDw bEG bFU -bFU +cLJ bIn bJt qni +mFw bFU -bFU -bFU +swB hZB bPF bTu @@ -93138,14 +94342,14 @@ bAd bBk bCv bDx -bEH +byu bFU -bFU -bIo +bIj +bIj bJu bKE -bLM -bMN +bIj +bFU bFU bCz bPE @@ -93394,13 +94598,13 @@ bpY bpY bpY bCw -bDy -bDy -bDy +byu bFU +bIo +bJy bIp bJv -bJx +bJA bLN bMO bFU @@ -93651,14 +94855,14 @@ byw bAe bpY bCx -bDy -bEI -bFV +bEL bFU +bFV +bLP bIq bJw bKF -bLO +bLP bMP bFU bCz @@ -93908,13 +95112,13 @@ byx bAf bBl bCy -bDy -bEJ +bEM +bFU bFW -bHe +bLP bIr bJx -bJx +bLM bLP bMQ bFU @@ -94164,13 +95368,13 @@ bsK bsK bAg bpY -bCz bDy -bEK -bFX +bFY bFU +bFX +bLQ bIs -bJy +bFU bKG bLQ bMR @@ -94421,18 +95625,18 @@ bwV byz ooh bpY -bCA -bDy -bEL -bDy -bFU -bFU -bJz +bOB +bHa bFU bFU bFU bFU -bCz +bFU +bFU +bFU +bFU +bFU +mcB bPE bQz bRl @@ -94679,15 +95883,15 @@ byA bAi bpY bCB -bDz -bEM -bFY +bEI bDz bDz -bJA -bKH -bKH -bKH +bDz +pCL +bDz +bDz +bDz +uoN bNY bOJ bPE @@ -95917,7 +97121,7 @@ aAG aBA aCQ aDS -pHo +aCS aAH aGu aHh @@ -97166,7 +98370,7 @@ aek aek aek aeA -adF +geL afk ael afS @@ -99539,8 +100743,8 @@ aVu bat aLf bcy -qAM -aEj +aKp +kKI aEj bgC bhi @@ -99795,8 +100999,8 @@ aYp aPY bau aLf -aFi -aMA +bHK +aIp beI beI bgD @@ -100303,7 +101507,7 @@ aSe aTc aOT aVp -aWu +pHo aPW aYr aOV @@ -100560,13 +101764,13 @@ aSf aTd aUn aVr -aWu +aWv aLf aYs aZk bax aLf -aFi +aMA bdC beI bfx @@ -100817,7 +102021,7 @@ lAs aTe aUo aVs -aWv +aLf aLf aPW aZl @@ -101039,7 +102243,7 @@ aiS aob eaw ajv -ajv +bCA cnX aiS apv @@ -104176,7 +105380,7 @@ bjx bjw blV bnb -bqs +qIr bqs bqt brL @@ -105458,7 +106662,7 @@ aaa aaa aEj bjx -aFi +bEK bjw nJI bog @@ -105919,7 +107123,7 @@ aaa aaa aiT akn -ajv +bFE aaF aaU aaL @@ -106719,7 +107923,7 @@ aFi aJs aFi aFi -aFi +bHI aEj aaa aaa @@ -107488,7 +108692,7 @@ aGO aFi aGO aFi -aFi +bEK aEj aJs aEj @@ -107508,7 +108712,7 @@ aEj aEj aTx aFi -aFi +bEK aEj bjD lEn @@ -109334,7 +110538,7 @@ bwm nzD uoj bwm -lWy +bMN bwm dMI lWy @@ -111887,7 +113091,7 @@ rxa bnl bok aFi -aFi +bEK aEj btA uXG @@ -114714,13 +115918,13 @@ abI aby aaa xKc -blX +lCN qAk iPj tfP geN qAk -blX +uzB xKc aaa aby diff --git a/_maps/map_files/PubbyStation/job_changes.dm b/_maps/map_files/PubbyStation/job_changes.dm new file mode 100644 index 0000000000..dfef9491ed --- /dev/null +++ b/_maps/map_files/PubbyStation/job_changes.dm @@ -0,0 +1,25 @@ +#define JOB_MODIFICATION_MAP_NAME "PubbyStation" + +/datum/job/hos/New() + ..() + MAP_JOB_CHECK + access += ACCESS_CREMATORIUM + minimal_access += ACCESS_CREMATORIUM + +/datum/job/warden/New() + ..() + MAP_JOB_CHECK + access += ACCESS_CREMATORIUM + minimal_access += ACCESS_CREMATORIUM + +/datum/job/officer/New() + ..() + MAP_JOB_CHECK + access += ACCESS_CREMATORIUM + minimal_access += ACCESS_CREMATORIUM + +/datum/job/prisoner/New() + ..() + MAP_JOB_CHECK + total_positions = 0 + spawn_positions = 2 diff --git a/_maps/map_files/Snaxi/Snaxi.dmm b/_maps/map_files/Snaxi/Snaxi.dmm index d9cf6c7948..51b0cdb586 100644 --- a/_maps/map_files/Snaxi/Snaxi.dmm +++ b/_maps/map_files/Snaxi/Snaxi.dmm @@ -85,7 +85,7 @@ /obj/machinery/keycard_auth{ pixel_y = -28 }, -/mob/living/simple_animal/parrot/Poly, +/mob/living/simple_animal/parrot/Polly, /turf/open/floor/plasteel, /area/command/heads_quarters/ce) "aai" = ( @@ -870,7 +870,7 @@ /obj/machinery/light{ dir = 4 }, -/obj/machinery/computer/arcade/minesweeper{ +/obj/machinery/computer/arcade/orion_trail{ dir = 8 }, /obj/structure/sign/poster/official/nanomichi_ad{ @@ -5842,7 +5842,7 @@ /turf/open/floor/plating, /area/maintenance/aft/secondary) "akQ" = ( -/obj/machinery/computer/arcade/minesweeper, +/obj/machinery/computer/arcade/battle, /turf/open/floor/plasteel/dark, /area/security/prison) "akR" = ( @@ -9515,6 +9515,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/machinery/posialert{ + pixel_x = -32 + }, /turf/open/floor/plasteel/white, /area/science/robotics/lab) "axr" = ( @@ -11007,9 +11010,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, -/obj/machinery/sleeper{ - dir = 8 - }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/medbay/zone2) "aPZ" = ( @@ -20516,9 +20517,6 @@ /turf/open/floor/plating, /area/maintenance/solars/starboard/aft) "fUX" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/structure/window/reinforced{ dir = 1 }, @@ -20528,6 +20526,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/machinery/sleeper{ + dir = 4 + }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "fVm" = ( @@ -23736,9 +23737,6 @@ /turf/open/floor/plasteel/dark, /area/security/office) "hWn" = ( -/obj/machinery/sleeper{ - dir = 8 - }, /obj/structure/window/reinforced{ dir = 1 }, @@ -23755,6 +23753,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "hWp" = ( @@ -25710,7 +25709,6 @@ /obj/effect/turf_decal/tile/brown{ dir = 4 }, -/obj/machinery/computer/bounty, /turf/open/floor/plasteel, /area/cargo/storage) "jjB" = ( @@ -29421,9 +29419,6 @@ /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai_upload_foyer) "lOX" = ( -/obj/machinery/sleeper{ - dir = 8 - }, /obj/structure/window/reinforced, /obj/structure/mirror{ pixel_x = 25 @@ -29433,6 +29428,7 @@ }, /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/stripes/line, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "lPB" = ( @@ -34938,7 +34934,7 @@ dir = 1; pixel_y = -24 }, -/obj/machinery/computer/arcade/minesweeper{ +/obj/machinery/computer/arcade/orion_trail{ dir = 4 }, /turf/open/floor/plasteel/dark, @@ -35740,7 +35736,7 @@ pixel_y = -22 }, /obj/machinery/light, -/obj/structure/closet/emcloset, +/obj/machinery/piratepad/civilian, /turf/open/floor/plasteel, /area/hallway/primary/fore) "pLP" = ( @@ -36872,7 +36868,7 @@ /area/engineering/secure_construction) "qzP" = ( /obj/machinery/vending/dinnerware{ - contraband = list(/obj/item/kitchen/rollingpin = 2, /obj/item/kitchen/knife/butcher = 2, /obj/item/reagent_containers/food/condiment/flour = 4) + contraband = list(/obj/item/kitchen/rollingpin=2,/obj/item/kitchen/knife/butcher=2,/obj/item/reagent_containers/food/condiment/flour=4) }, /turf/open/floor/plasteel/freezer, /area/service/kitchen) @@ -37118,7 +37114,9 @@ }, /area/service/chapel/main) "qHq" = ( -/obj/structure/closet/crate, +/obj/machinery/computer/piratepad_control/civilian{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "qHC" = ( @@ -43682,6 +43680,7 @@ /obj/structure/table, /obj/item/toy/cards/deck, /obj/item/storage/crayons, +/obj/item/chisel, /turf/open/floor/plasteel/grimy, /area/commons/fitness/recreation) "uWC" = ( @@ -44164,9 +44163,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, -/obj/machinery/sleeper{ - dir = 8 - }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "vkk" = ( @@ -44908,7 +44905,7 @@ dir = 8 }, /obj/effect/spawner/lootdrop/armory_contraband{ - loot = list(/obj/item/gun/ballistic/automatic/pistol = 5, /obj/item/gun/ballistic/shotgun/automatic/combat = 5, /obj/item/gun/ballistic/revolver/mateba, /obj/item/gun/ballistic/automatic/pistol/deagle, /obj/item/storage/box/syndie_kit/throwing_weapons = 3) + loot = list(/obj/item/gun/ballistic/automatic/pistol=5,/obj/item/gun/ballistic/shotgun/automatic/combat=5,/obj/item/gun/ballistic/revolver/mateba,/obj/item/gun/ballistic/automatic/pistol/deagle,/obj/item/storage/box/syndie_kit/throwing_weapons=3) }, /obj/effect/spawner/lootdrop/maintenance{ lootcount = 3; @@ -46270,9 +46267,6 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "wut" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/structure/window/reinforced, /obj/structure/window/reinforced{ dir = 8 @@ -46281,6 +46275,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/obj/machinery/sleeper{ + dir = 4 + }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "wuC" = ( @@ -47811,16 +47808,6 @@ }, /turf/closed/wall/r_wall, /area/ai_monitored/turret_protected/ai_upload) -"xEf" = ( -/obj/machinery/computer/bounty{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown, -/turf/open/floor/plasteel, -/area/cargo/qm) "xEt" = ( /obj/structure/cable{ icon_state = "4-8" @@ -89693,7 +89680,7 @@ rDE dFF sLn acv -xEf +jmU krH avT xUL diff --git a/_maps/map_files/SpookyStation/SpookyStation.dmm b/_maps/map_files/SpookyStation/SpookyStation.dmm new file mode 100644 index 0000000000..ae37b94ad1 --- /dev/null +++ b/_maps/map_files/SpookyStation/SpookyStation.dmm @@ -0,0 +1,83277 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aaa" = ( +/obj/vehicle/ridden/bicycle, +/turf/open/floor/spooktime/beach, +/area/eventmap/outside) +"aab" = ( +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aac" = ( +/turf/closed/mineral/ash_rock, +/area/eventmap/mountain) +"aad" = ( +/obj/structure/bed, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aae" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aaf" = ( +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury01, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/wood, +/area/eventmap/inside) +"aag" = ( +/obj/structure/bed, +/obj/item/bedsheet/random, +/turf/open/floor/wood, +/area/eventmap/inside) +"aah" = ( +/obj/structure/closet/crate/grave, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aai" = ( +/obj/machinery/vending/boozeomat{ + req_access = null + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aaj" = ( +/obj/structure/dresser, +/obj/machinery/light{ + dir = 1; + light_color = "#e8eaff" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aak" = ( +/obj/structure/reagent_dispensers/keg/gargle, +/turf/open/floor/wood/damturf/broken1, +/area/eventmap/inside) +"aal" = ( +/obj/structure/closet/secure_closet/freezer/meat, +/turf/open/floor/wood, +/area/eventmap/inside) +"aam" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/bottle/wine, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aan" = ( +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/inside) +"aao" = ( +/obj/machinery/door/airlock/silver{ + name = "Bathroom" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/inside) +"aap" = ( +/obj/structure/bed, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"aaq" = ( +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury02, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/wood, +/area/eventmap/inside) +"aar" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/wood, +/area/eventmap/inside) +"aas" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 4; + icon_state = "" + }, +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/obj/docking_port/mobile/arrivals, +/turf/open/floor/plasteel/dark{ + icon_state = "bus" + }, +/area/shuttle/arrival) +"aat" = ( +/obj/item/flashlight/lantern{ + anchored = 1; + can_be_unanchored = 1; + light_color = "#EE9933"; + light_range = 5; + on = 1 + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aau" = ( +/obj/structure/flora/junglebush{ + icon_state = "busha1" + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aav" = ( +/obj/structure/fluff/bus/passable, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aaw" = ( +/turf/closed/wall, +/area/eventmap/inside) +"aax" = ( +/obj/structure/holohoop, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aay" = ( +/obj/structure/rack, +/obj/item/stack/sheet/mineral/wood/fifty, +/turf/open/floor/wood, +/area/eventmap/inside) +"aaz" = ( +/obj/structure/reagent_dispensers/keg/milk, +/turf/open/floor/wood/damturf/broken3, +/area/eventmap/inside) +"aaA" = ( +/obj/structure/fireplace{ + dir = 4; + pixel_x = -8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aaB" = ( +/obj/structure/flora/tree/jungle, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aaD" = ( +/obj/structure/flora/junglebush, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aaE" = ( +/obj/machinery/light/small, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aaF" = ( +/obj/structure/flora/junglebush{ + icon_state = "bushb1" + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aaG" = ( +/obj/machinery/camera/emp_proof{ + c_tag = "Containment - Particle Accelerator"; + dir = 1; + network = list("singularity") + }, +/obj/machinery/light/small, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aaH" = ( +/obj/structure/chair/wood/normal, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"aaI" = ( +/obj/structure/dresser, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aaJ" = ( +/obj/structure/bed, +/obj/item/bedsheet, +/turf/open/floor/wood, +/area/eventmap/inside) +"aaK" = ( +/obj/structure/table/wood/fancy, +/obj/item/clothing/head/hardhat/pumpkinhead/jaqc{ + light_range = 3 + }, +/turf/open/floor/wood/damturf/broken5, +/area/eventmap/inside) +"aaL" = ( +/obj/structure/bodycontainer/crematorium, +/turf/open/floor/wood, +/area/eventmap/inside) +"aaM" = ( +/obj/structure/chair/comfy/plywood{ + dir = 8 + }, +/turf/open/floor/spooktime/cobble/cornerNE, +/area/eventmap/outside) +"aaN" = ( +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aaO" = ( +/obj/machinery/rnd/production/techfab/department/cargo, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aaP" = ( +/obj/structure/bodycontainer/morgue{ + dir = 2 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aaQ" = ( +/obj/structure/chair/sofa/right, +/turf/open/floor/wood, +/area/eventmap/inside) +"aaR" = ( +/obj/structure/chair/sofa/left, +/turf/open/floor/wood, +/area/eventmap/inside) +"aaS" = ( +/obj/structure/mineral_door/woodrustic, +/turf/open/floor/wood, +/area/eventmap/inside) +"aaT" = ( +/obj/machinery/button/door/dorms/luxury1, +/obj/machinery/vending/coffee, +/turf/open/floor/wood, +/area/eventmap/inside) +"aaU" = ( +/obj/structure/chair/wood/normal{ + dir = 4 + }, +/obj/structure/curtain{ + color = "#B22222"; + pixel_y = -32 + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"aaV" = ( +/obj/structure/table/wood, +/obj/item/clothing/head/festive, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"aaW" = ( +/obj/structure/mirror{ + pixel_x = 28 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/shower{ + dir = 8; + pixel_y = -4 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/inside) +"aaX" = ( +/obj/structure/table/wood, +/obj/machinery/light{ + dir = 4 + }, +/obj/item/reagent_containers/food/drinks/bottle/wine, +/turf/open/floor/wood, +/area/eventmap/inside) +"aaY" = ( +/obj/structure/table/wood/fancy, +/obj/item/clothing/head/scarecrow_hat, +/turf/open/floor/wood, +/area/eventmap/inside) +"aaZ" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/pastatomato, +/turf/open/floor/wood, +/area/eventmap/inside) +"aba" = ( +/obj/structure/table/wood/fancy, +/obj/item/clothing/head/hardhat/pumpkinhead/jaqc{ + light_range = 3 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"abb" = ( +/obj/structure/closet/secure_closet/freezer/kitchen/maintenance, +/turf/open/floor/wood, +/area/eventmap/inside) +"abc" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/microwave, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"abd" = ( +/obj/structure/chair/comfy/plywood{ + dir = 8 + }, +/turf/open/floor/spooktime/cobble/sideE, +/area/eventmap/outside) +"abe" = ( +/obj/structure/sign/poster/official/no_erp, +/turf/closed/wall/mineral/wood, +/area/eventmap/mountaininside) +"abf" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/chem_dispenser/drinks/beer/fullupgrade, +/turf/open/floor/wood, +/area/eventmap/inside) +"abg" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/chem_dispenser/drinks/fullupgrade, +/turf/open/floor/wood, +/area/eventmap/inside) +"abh" = ( +/obj/structure/table/wood/fancy/red, +/turf/open/floor/wood, +/area/eventmap/inside) +"abi" = ( +/obj/structure/mineral_door/woodrustic{ + name = "Event Hall" + }, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury01, +/turf/open/floor/wood, +/area/eventmap/inside) +"abj" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury01, +/turf/open/floor/wood, +/area/eventmap/inside) +"abk" = ( +/obj/machinery/vending/wardrobe/cargo_wardrobe, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"abl" = ( +/obj/structure/toilet{ + dir = 4 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/inside) +"abm" = ( +/obj/machinery/door/airlock/silver{ + name = "Bathroom" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"abn" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plasteel/elevatorshaft, +/area/eventmap/inside) +"abo" = ( +/obj/structure/fireplace{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"abp" = ( +/obj/effect/landmark/start/chaplain, +/turf/open/floor/wood, +/area/eventmap/inside) +"abq" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/reagent_containers/food/snacks/waffles, +/turf/open/floor/wood, +/area/eventmap/inside) +"abr" = ( +/obj/structure/chair/comfy/plywood{ + dir = 1 + }, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"abs" = ( +/obj/structure/fluff/bus/passable, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"abt" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"abu" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"abv" = ( +/obj/structure/table/wood, +/obj/item/phone, +/turf/open/floor/wood, +/area/eventmap/inside) +"abw" = ( +/obj/structure/table/wood, +/obj/item/clothing/head/festive, +/obj/structure/curtain{ + color = "#B22222"; + pixel_y = -32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"abx" = ( +/obj/machinery/button/door/dorms/luxury2, +/obj/machinery/vending/coffee, +/turf/open/floor/wood/damturf/broken6, +/area/eventmap/inside) +"aby" = ( +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"abz" = ( +/obj/structure/chair/wood/wings, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"abA" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury02, +/turf/open/floor/wood, +/area/eventmap/inside) +"abB" = ( +/obj/structure/mineral_door/woodrustic{ + name = "Event Hall" + }, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury02, +/turf/open/floor/wood, +/area/eventmap/inside) +"abC" = ( +/obj/structure/chair/sofa, +/turf/open/floor/wood, +/area/eventmap/inside) +"abD" = ( +/obj/structure/closet/crate/coffin, +/turf/open/floor/wood, +/area/eventmap/inside) +"abE" = ( +/obj/structure/bed, +/obj/item/bedsheet/random, +/turf/open/floor/carpet, +/area/eventmap/inside) +"abF" = ( +/obj/machinery/vending/donksofttoyvendor, +/turf/open/floor/spooktime/cobble/cornerNW, +/area/eventmap/outside) +"abG" = ( +/obj/structure/table/wood, +/obj/item/stack/sheet/plastic/fifty{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/stack/sheet/metal/fifty, +/turf/open/floor/spooktime/cobble/sideN, +/area/eventmap/outside) +"abH" = ( +/turf/closed/wall/mineral/gold, +/area/eventmap/mountain) +"abI" = ( +/obj/structure/table/wood, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/item/storage/firstaid/regular, +/obj/structure/sign/poster/contraband/masked_men{ + pixel_x = 32 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"abJ" = ( +/turf/open/floor/carpet, +/area/eventmap/inside) +"abK" = ( +/turf/closed/wall/mineral/iron, +/area/eventmap/outside) +"abL" = ( +/obj/structure/healingfountain, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"abM" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/reagent_containers/food/snacks/soup/hotchili, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"abN" = ( +/obj/structure/table/wood/fancy/red, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"abO" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/reagent_containers/food/snacks/sausage, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"abP" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/reagent_containers/food/snacks/cubancarp, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"abQ" = ( +/obj/structure/sink{ + dir = 8; + pixel_x = -12 + }, +/obj/structure/mirror{ + dir = 8; + pixel_x = -28 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"abR" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"abS" = ( +/obj/structure/mineral_door/wood, +/turf/open/floor/wood/damturf/broken7, +/area/eventmap/inside) +"abT" = ( +/obj/effect/landmark/start/chaplain, +/turf/open/floor/carpet, +/area/eventmap/inside) +"abU" = ( +/obj/machinery/vending/wardrobe/chap_wardrobe, +/turf/open/floor/carpet, +/area/eventmap/inside) +"abV" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/reagent_containers/food/snacks/taco, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"abW" = ( +/obj/structure/chair/sofa/left{ + dir = 1; + icon_state = "sofamiddle" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"abX" = ( +/obj/structure/chair/sofa/left{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"abY" = ( +/turf/open/floor/wood{ + icon_state = "wood-broken2" + }, +/area/eventmap/inside) +"abZ" = ( +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/eventmap/inside) +"aca" = ( +/obj/structure/toilet{ + dir = 4 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"acb" = ( +/obj/machinery/power/apc{ + name = "Chapel Office APC"; + pixel_y = -24 + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"acc" = ( +/obj/structure/dresser, +/turf/open/floor/carpet, +/area/eventmap/inside) +"acd" = ( +/obj/structure/chair/wood/wings{ + dir = 1 + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"ace" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03, +/turf/open/floor/wood, +/area/eventmap/inside) +"acf" = ( +/obj/structure/mineral_door/woodrustic{ + name = "Event Hall" + }, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03, +/turf/open/floor/wood, +/area/eventmap/inside) +"acg" = ( +/obj/machinery/light/small, +/obj/structure/chair/sofa/left{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ach" = ( +/obj/structure/chair/sofa/right{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aci" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"acj" = ( +/obj/structure/bookcase/random/adult, +/turf/open/floor/wood, +/area/eventmap/inside) +"ack" = ( +/obj/structure/table/wood, +/obj/machinery/light{ + dir = 1 + }, +/obj/item/phone, +/turf/open/floor/wood, +/area/eventmap/inside) +"acl" = ( +/obj/structure/table/wood, +/obj/item/clothing/head/festive, +/obj/structure/curtain{ + color = "#B22222"; + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"acm" = ( +/obj/machinery/button/door/dorms/luxury3, +/obj/machinery/vending/coffee, +/turf/open/floor/wood/damturf/broken1, +/area/eventmap/inside) +"acn" = ( +/obj/item/barthpot{ + active = 0 + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aco" = ( +/obj/machinery/holopad, +/obj/effect/landmark/start/chaplain, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"acp" = ( +/mob/living/simple_animal/jacq{ + active = 0; + spawn_cars = 0 + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"acq" = ( +/obj/structure/chair/wood/normal{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"acr" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/plasteel/elevatorshaft, +/area/eventmap/inside) +"acs" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/camera/emp_proof{ + c_tag = "Cargo Bay" + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"act" = ( +/turf/open/floor/plasteel{ + dir = 1; + icon_state = "chapel" + }, +/area/eventmap/inside) +"acu" = ( +/obj/structure/dresser, +/turf/open/floor/wood, +/area/eventmap/inside) +"acv" = ( +/turf/open/floor/plasteel{ + dir = 4; + icon_state = "chapel" + }, +/area/eventmap/inside) +"acw" = ( +/obj/structure/table/wood/fancy, +/obj/item/flashlight/lantern{ + anchored = 1; + can_be_unanchored = 1; + light_color = "#EE9933"; + light_range = 5; + on = 1 + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"acx" = ( +/obj/structure/table/wood/fancy, +/turf/open/floor/carpet, +/area/eventmap/inside) +"acy" = ( +/obj/structure/mineral_door/wood, +/turf/open/floor/wood, +/area/eventmap/inside) +"acz" = ( +/obj/structure/table/wood/fancy, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"acA" = ( +/obj/effect/turf_decal/delivery, +/obj/structure/closet/crate{ + icon_state = "crateopen" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"acB" = ( +/turf/open/floor/plasteel/stairs/left, +/area/eventmap/inside) +"acC" = ( +/obj/structure/bookcase/random/adult, +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/eventmap/inside) +"acD" = ( +/turf/open/floor/plasteel/stairs/right, +/area/eventmap/inside) +"acE" = ( +/obj/structure/mineral_door/woodrustic{ + name = "Event Hall" + }, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury04, +/turf/open/floor/wood, +/area/eventmap/inside) +"acF" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"acG" = ( +/obj/machinery/door/airlock/mining{ + name = "Mining"; + req_access_txt = "48" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"acH" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury04, +/turf/open/floor/wood, +/area/eventmap/inside) +"acI" = ( +/obj/structure/flora/grass/jungle/b{ + icon_state = "busha2" + }, +/obj/vehicle/ridden/atv, +/obj/item/key, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"acJ" = ( +/obj/structure/flora/junglebush{ + icon_state = "bushb1" + }, +/obj/vehicle/ridden/atv, +/obj/item/key, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"acK" = ( +/obj/vehicle/ridden/atv, +/obj/item/key, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"acL" = ( +/turf/open/floor/plasteel{ + dir = 8; + icon_state = "chapel" + }, +/area/eventmap/inside) +"acM" = ( +/turf/open/floor/plasteel{ + icon_state = "chapel" + }, +/area/eventmap/inside) +"acN" = ( +/obj/structure/spacevine, +/turf/closed/wall/rust, +/area/eventmap/outside) +"acO" = ( +/obj/structure/bed, +/obj/item/bedsheet/cmo, +/obj/item/restraints/handcuffs, +/obj/item/reagent_containers/syringe, +/obj/item/clothing/suit/straight_jacket, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"acP" = ( +/obj/machinery/vending/kink, +/turf/open/floor/wood, +/area/eventmap/inside) +"acQ" = ( +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"acR" = ( +/obj/structure/table/wood, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown, +/obj/item/paper_bin, +/obj/item/pen, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"acS" = ( +/obj/machinery/vending/clothing, +/turf/open/floor/wood, +/area/eventmap/inside) +"acT" = ( +/obj/machinery/camera/emp_proof{ + c_tag = "Containment - Fore Port"; + dir = 4; + network = list("singularity") + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"acU" = ( +/obj/structure/sign/departments/medbay/alt{ + pixel_x = 32 + }, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"acV" = ( +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"acW" = ( +/obj/structure/mineral_door/woodrustic, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"acX" = ( +/obj/machinery/washing_machine, +/turf/open/floor/wood, +/area/eventmap/inside) +"acY" = ( +/obj/machinery/button/door/dorms/luxury4, +/turf/open/floor/wood, +/area/eventmap/inside) +"acZ" = ( +/obj/structure/flora/grass/jungle/b{ + icon_state = "grassa3" + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"ada" = ( +/obj/structure/flora/grass/jungle/b{ + icon_state = "grassa1" + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"adb" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"adc" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"add" = ( +/obj/effect/landmark/start/cargo_technician, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ade" = ( +/obj/machinery/cryopod{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"adf" = ( +/obj/structure/chair/wood/normal{ + dir = 4 + }, +/obj/structure/curtain{ + color = "#B22222"; + pixel_y = 32 + }, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"adg" = ( +/obj/structure/closet/secure_closet/CMO, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"adh" = ( +/obj/structure/table/wood, +/obj/item/clothing/head/festive, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"adi" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"adj" = ( +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"adk" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"adl" = ( +/obj/structure/window/reinforced/tinted/fulltile, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"adm" = ( +/obj/structure/sign/poster/official/do_not_question{ + pixel_y = 32 + }, +/obj/structure/bookcase/random/nonfiction, +/turf/open/floor/wood, +/area/eventmap/inside) +"adn" = ( +/obj/structure/spirit_board, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"ado" = ( +/obj/structure/easel, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"adp" = ( +/obj/machinery/door/firedoor/border_only/closed{ + dir = 4; + name = "Therapist's Office" + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"adq" = ( +/obj/item/storage/briefcase, +/turf/open/floor/wood, +/area/eventmap/inside) +"adr" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood{ + icon_state = "wood-broken3" + }, +/area/eventmap/inside) +"ads" = ( +/mob/living/simple_animal/pet/cat/Runtime, +/turf/open/floor/wood, +/area/eventmap/inside) +"adt" = ( +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"adu" = ( +/obj/machinery/computer/crew, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"adv" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/paper_bin, +/obj/item/pen, +/obj/item/storage/pill_bottle/mannitol, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"adw" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/flashlight/lamp/green, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"adx" = ( +/obj/structure/table/wood, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ady" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/effect/landmark/start/chief_medical_officer, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"adz" = ( +/obj/effect/turf_decal/tile/blue, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"adA" = ( +/obj/structure/table/wood, +/obj/item/phone, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"adB" = ( +/obj/structure/chair/pew/left{ + dir = 1 + }, +/turf/open/floor/plasteel{ + icon_state = "chapel" + }, +/area/eventmap/inside) +"adC" = ( +/obj/structure/chair/pew{ + dir = 1 + }, +/turf/open/floor/plasteel{ + dir = 8; + icon_state = "chapel" + }, +/area/eventmap/inside) +"adD" = ( +/obj/structure/flora/grass/jungle/b{ + icon_state = "busha2" + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"adE" = ( +/obj/structure/chair/pew/right{ + dir = 1 + }, +/turf/open/floor/plasteel{ + icon_state = "chapel" + }, +/area/eventmap/inside) +"adF" = ( +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/obj/machinery/power/apc{ + dir = 1; + name = "CM Quarters APC"; + pixel_x = 24 + }, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"adG" = ( +/obj/structure/chair/pew/left{ + dir = 1 + }, +/turf/open/floor/plasteel{ + dir = 8; + icon_state = "chapel" + }, +/area/eventmap/inside) +"adH" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"adI" = ( +/obj/structure/mineral_door/wood, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"adJ" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/landmark/start/chief_medical_officer, +/turf/open/floor/wood, +/area/eventmap/inside) +"adK" = ( +/obj/structure/window/reinforced/tinted/frosted{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"adL" = ( +/obj/item/folder/white, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"adM" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"adN" = ( +/turf/open/floor/wood{ + icon_state = "wood-broken5" + }, +/area/eventmap/inside) +"adO" = ( +/obj/structure/chair/office/dark{ + dir = 4 + }, +/obj/effect/landmark/start/chief_medical_officer, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"adP" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/computer/med_data/laptop{ + dir = 8 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"adQ" = ( +/obj/structure/chair/pew{ + dir = 1 + }, +/turf/open/floor/plasteel{ + icon_state = "chapel" + }, +/area/eventmap/inside) +"adR" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/white{ + icon_state = "0-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"adS" = ( +/obj/structure/table/wood, +/obj/item/paper/fluff/balls/spookyasylum/traffickingvictim, +/obj/item/clothing/mask/muzzle, +/obj/item/clothing/glasses/sunglasses/blindfold, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"adT" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"adU" = ( +/obj/structure/chair/pew/right{ + dir = 1 + }, +/turf/open/floor/plasteel{ + dir = 8; + icon_state = "chapel" + }, +/area/eventmap/inside) +"adV" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"adW" = ( +/obj/item/toy/beach_ball/holoball, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"adX" = ( +/obj/structure/chair/sofa/left{ + dir = 1 + }, +/turf/open/floor/wood{ + icon_state = "wood-broken7" + }, +/area/eventmap/inside) +"adY" = ( +/obj/structure/chair/sofa/right{ + dir = 1 + }, +/turf/open/floor/wood{ + icon_state = "wood-broken2" + }, +/area/eventmap/inside) +"adZ" = ( +/obj/structure/window/reinforced/tinted/frosted{ + dir = 4 + }, +/obj/structure/statue/silver/md, +/turf/open/floor/wood, +/area/eventmap/inside) +"aea" = ( +/obj/machinery/suit_storage_unit/cmo, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeb" = ( +/obj/structure/chair/comfy/teal{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aec" = ( +/obj/structure/filingcabinet/medical, +/obj/structure/cable/yellow, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"aed" = ( +/obj/machinery/computer/card/minor/cmo{ + dir = 1 + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"aee" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"aef" = ( +/obj/structure/window/reinforced/tinted/fulltile, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeg" = ( +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeh" = ( +/obj/machinery/door/airlock/command/glass{ + name = "Chief Medical Officer"; + req_access_txt = "40" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aei" = ( +/obj/effect/turf_decal/bot, +/obj/structure/closet/cardboard, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aej" = ( +/obj/structure/filingcabinet/medical, +/turf/open/floor/wood, +/area/eventmap/inside) +"aek" = ( +/obj/item/reagent_containers/spray/cleaner, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/table/wood/fancy/purple, +/obj/item/gun/magic/wand/resurrection, +/turf/open/floor/wood, +/area/eventmap/inside) +"ael" = ( +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury04, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/wood, +/area/eventmap/inside) +"aem" = ( +/obj/item/chair/wood, +/turf/open/floor/plasteel{ + icon_state = "chapel" + }, +/area/eventmap/inside) +"aen" = ( +/obj/item/chair/wood, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aeo" = ( +/obj/effect/spawner/structure/window, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aep" = ( +/obj/machinery/vending/wardrobe/cargo_wardrobe, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeq" = ( +/obj/machinery/vending/wardrobe/chap_wardrobe, +/turf/open/floor/wood, +/area/eventmap/inside) +"aer" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"aes" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"aet" = ( +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/chair/stool, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"aeu" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"aev" = ( +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/structure/chair/stool, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"aew" = ( +/obj/machinery/mineral/ore_redemption, +/obj/effect/turf_decal/delivery, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aex" = ( +/obj/structure/table/plasmaglass, +/obj/item/toy/cards/deck/unum, +/obj/machinery/light/floor, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"aey" = ( +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/structure/chair/stool, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"aez" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/vending/medical{ + req_access = null + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeA" = ( +/obj/machinery/rnd/production/techfab/department/medical, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeB" = ( +/obj/structure/window/reinforced, +/obj/structure/table/wood/fancy/green, +/obj/item/storage/firstaid/toxin{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/storage/firstaid/toxin, +/obj/effect/decal/cleanable/cobweb, +/obj/item/gun/syringe, +/obj/item/gun/syringe, +/obj/item/gun/syringe, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeC" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/storage/firstaid/fire{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/storage/firstaid/fire, +/obj/machinery/door/window/southleft, +/obj/item/holosign_creator/medical, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeD" = ( +/obj/machinery/light/small/broken{ + dir = 8 + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aeE" = ( +/obj/structure/sign/departments/medbay/alt{ + pixel_x = 32 + }, +/obj/machinery/light/small/broken{ + dir = 4 + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aeF" = ( +/obj/structure/table/wood/fancy/green, +/obj/machinery/door/window/southright, +/obj/item/storage/firstaid/regular{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/firstaid/regular, +/obj/item/clothing/accessory/medal/ribbon/medical_doctor, +/obj/item/gun/magic/wand/resurrection, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeG" = ( +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/table/wood/fancy/green, +/obj/item/storage/firstaid/o2{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/firstaid/o2, +/obj/item/storage/firstaid/regular{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/item/gun/magic/staff/healing, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeH" = ( +/obj/machinery/door/airlock/gold, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"aeI" = ( +/obj/structure/closet/secure_closet/medical3, +/obj/item/healthanalyzer/advanced, +/obj/item/defibrillator/loaded, +/obj/item/clothing/glasses/hud/health, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeJ" = ( +/obj/structure/closet/crate/medical{ + icon_state = "medicalcrateopen" + }, +/obj/item/gun/magic/wand/resurrection, +/obj/item/gun/magic/wand/resurrection, +/obj/item/gun/magic/staff/healing, +/obj/item/gun/magic/staff/healing, +/obj/item/paper/fluff/balls/spookyasylum/healstaffnote, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeK" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeL" = ( +/obj/machinery/vending/wardrobe/bar_wardrobe, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeM" = ( +/obj/machinery/vending/wardrobe/chef_wardrobe, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeN" = ( +/obj/structure/flora/grass/jungle/b, +/turf/closed/wall/rust, +/area/eventmap/outside) +"aeO" = ( +/obj/machinery/vending/wardrobe/medi_wardrobe, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeP" = ( +/obj/machinery/vending/wardrobe/curator_wardrobe, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeQ" = ( +/obj/machinery/cryopod{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeR" = ( +/obj/machinery/cryopod, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeS" = ( +/obj/structure/table/wood, +/obj/item/wrench/medical, +/obj/item/storage/firstaid/regular, +/obj/item/clothing/head/beret/cmo, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeT" = ( +/obj/structure/table/wood, +/obj/item/storage/box/masks{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/box/gloves, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeU" = ( +/obj/item/clothing/accessory/armband/medblue{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/clothing/accessory/armband/med, +/obj/item/rack_parts, +/obj/item/storage/briefcase/medical, +/turf/open/floor/wood{ + icon_state = "wood-broken6" + }, +/area/eventmap/inside) +"aeV" = ( +/obj/structure/rack, +/obj/effect/spawner/bundle/costume/plaguedoctor, +/obj/item/stamp/cmo, +/obj/item/gun/magic/staff/healing, +/obj/item/gun/magic/wand/resurrection, +/turf/open/floor/wood, +/area/eventmap/inside) +"aeW" = ( +/obj/structure/flora/junglebush{ + icon_state = "grassa4" + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aeX" = ( +/obj/machinery/hydroponics/soil, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/outside) +"aeY" = ( +/obj/item/storage/crayons, +/turf/open/floor/spooktime/beach, +/area/eventmap/outside) +"aeZ" = ( +/obj/machinery/camera/emp_proof{ + c_tag = "Containment - Fore Starboard"; + dir = 8; + network = list("singularity") + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"afa" = ( +/obj/machinery/vending/clothing, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"afc" = ( +/obj/structure/rack, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 2; + name = "2maintenance loot spawner" + }, +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/obj/item/reagent_containers/blood/random, +/obj/item/clothing/neck/stethoscope, +/turf/open/floor/wood, +/area/eventmap/inside) +"afd" = ( +/obj/machinery/shower{ + desc = "Despite their age, they seem clean and capable of providing hot water just as well as their modern counterparts. Hopefully Nanotrasen cleaned the water pipes this well..."; + pixel_y = 24 + }, +/obj/structure/curtain, +/obj/item/storage/pill_bottle/penis_enlargement, +/obj/item/storage/pill_bottle/breast_enlargement, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/item/ectoplasm, +/turf/open/floor/wood, +/area/eventmap/inside) +"afe" = ( +/obj/machinery/computer/arcade/orion_trail, +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aff" = ( +/obj/machinery/washing_machine, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"afg" = ( +/obj/machinery/cryopod{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"afh" = ( +/obj/effect/landmark/start/medical_doctor, +/turf/open/floor/wood, +/area/eventmap/inside) +"afi" = ( +/obj/item/seeds/pumpkin, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"afj" = ( +/turf/open/floor/plasteel/stairs/left, +/area/eventmap/outside) +"afk" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"afl" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"afm" = ( +/obj/machinery/vending/wardrobe/viro_wardrobe, +/turf/open/floor/wood, +/area/eventmap/inside) +"afn" = ( +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/wood, +/area/eventmap/inside) +"afo" = ( +/obj/effect/decal/cleanable/blood/gibs/old, +/obj/effect/decal/cleanable/glass, +/obj/item/shard, +/obj/item/organ/eyes, +/obj/machinery/light/small/broken{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"afp" = ( +/obj/structure/closet/secure_closet/CMO, +/turf/open/floor/wood, +/area/eventmap/inside) +"afq" = ( +/obj/structure/flora/bush, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"afr" = ( +/obj/structure/flora/ausbushes/sparsegrass, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"afs" = ( +/obj/structure/flora/ausbushes/leafybush, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aft" = ( +/obj/structure/flora/ausbushes/lavendergrass, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"afu" = ( +/obj/structure/sign/poster/official/fruit_bowl, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"afv" = ( +/obj/structure/spacevine, +/turf/closed/wall/rust, +/area/eventmap/inside) +"afw" = ( +/turf/closed/wall/rust, +/area/eventmap/inside) +"afx" = ( +/obj/structure/urinal, +/turf/closed/wall/rust, +/area/eventmap/inside) +"afy" = ( +/obj/structure/urinal, +/obj/structure/spacevine, +/turf/closed/wall/rust, +/area/eventmap/inside) +"afz" = ( +/obj/structure/chair/wood, +/obj/item/toy/plush/borgplushie/medihound, +/obj/item/clothing/glasses/hud/health/sunglasses{ + pixel_x = -4; + pixel_y = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"afA" = ( +/obj/effect/decal/cleanable/glass/plasma, +/turf/open/floor/wood, +/area/eventmap/inside) +"afB" = ( +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"afC" = ( +/turf/open/floor/plasteel/stairs/right, +/area/eventmap/outside) +"afD" = ( +/obj/structure/window/reinforced/tinted, +/turf/open/floor/wood, +/area/eventmap/inside) +"afE" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/eventmap/inside) +"afF" = ( +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"afG" = ( +/obj/machinery/vending/coffee, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"afH" = ( +/obj/structure/fireplace, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"afI" = ( +/obj/machinery/vending/snack/orange, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"afJ" = ( +/obj/machinery/vending/games, +/turf/open/floor/wood, +/area/eventmap/inside) +"afK" = ( +/obj/structure/flora/rock/pile/icy, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"afL" = ( +/obj/structure/flora/ausbushes/ywflowers, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"afM" = ( +/obj/structure/toilet{ + dir = 4 + }, +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"afN" = ( +/obj/structure/mineral_door/wood, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"afO" = ( +/obj/machinery/shower{ + desc = "Despite their age, they seem clean and capable of providing hot water just as well as their modern counterparts. Hopefully Nanotrasen cleaned the water pipes this well..."; + pixel_y = 24 + }, +/obj/structure/curtain, +/obj/machinery/atmospherics/components/unary/vent_pump{ + icon_state = "vent_in" + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"afP" = ( +/obj/machinery/shower{ + desc = "Despite their age, they seem clean and capable of providing hot water just as well as their modern counterparts. Hopefully Nanotrasen cleaned the water pipes this well..."; + pixel_y = 24 + }, +/obj/structure/curtain, +/obj/item/bikehorn/rubberducky, +/obj/machinery/atmospherics/components/unary/vent_pump{ + icon_state = "vent_in" + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"afQ" = ( +/obj/machinery/shower{ + desc = "Despite their age, they seem clean and capable of providing hot water just as well as their modern counterparts. Hopefully Nanotrasen cleaned the water pipes this well..."; + pixel_y = 24 + }, +/obj/structure/curtain, +/obj/item/bikehorn/rubberducky, +/obj/item/soap/homemade, +/obj/machinery/atmospherics/components/unary/vent_pump{ + icon_state = "vent_in" + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"afR" = ( +/obj/machinery/shower{ + desc = "Despite their age, they seem clean and capable of providing hot water just as well as their modern counterparts. Hopefully Nanotrasen cleaned the water pipes this well..."; + pixel_y = 24 + }, +/obj/structure/curtain, +/obj/item/soap/homemade, +/obj/machinery/atmospherics/components/unary/vent_pump{ + icon_state = "vent_in" + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"afS" = ( +/obj/machinery/shower{ + desc = "Despite their age, they seem clean and capable of providing hot water just as well as their modern counterparts. Hopefully Nanotrasen cleaned the water pipes this well..."; + pixel_y = 24 + }, +/obj/effect/decal/cleanable/cobweb, +/obj/structure/curtain, +/obj/item/bikehorn/rubberducky, +/obj/item/soap/homemade, +/obj/machinery/atmospherics/components/unary/vent_pump{ + icon_state = "vent_in" + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"afT" = ( +/obj/machinery/vending/magivend, +/turf/open/floor/wood, +/area/eventmap/inside) +"afU" = ( +/obj/machinery/vending/autodrobe, +/turf/open/floor/wood, +/area/eventmap/inside) +"afV" = ( +/obj/effect/spawner/lootdrop/costume, +/mob/living/simple_animal/hostile/skeleton{ + a_intent = "friendly"; + attack_sound = 'sound/vox_fem/bone.ogg'; + harm_intent_damage = -5; + melee_damage_lower = 1; + melee_damage_upper = 10; + name = "Closet Skeleton" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"afW" = ( +/mob/living/simple_animal/hostile/skeleton{ + a_intent = "friendly"; + attack_sound = 'sound/vox_fem/bone.ogg'; + harm_intent_damage = -5; + melee_damage_lower = 1; + melee_damage_upper = 10; + name = "Closet Skeleton" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"afX" = ( +/obj/item/clothing/head/hardhat/pumpkinhead, +/turf/open/floor/wood, +/area/eventmap/inside) +"afY" = ( +/turf/open/floor/spooktime/cobble/sideW{ + icon_state = "cobble_corner_nw" + }, +/area/eventmap/outside) +"afZ" = ( +/turf/open/floor/wood{ + icon_state = "wood-broken4" + }, +/area/eventmap/inside) +"aga" = ( +/turf/open/floor/wood/damturf/broken7, +/area/eventmap/inside) +"agb" = ( +/obj/machinery/vending/medical{ + req_access = null + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"agc" = ( +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/wood, +/area/eventmap/inside) +"agd" = ( +/obj/machinery/vending/coffee, +/turf/open/floor/wood, +/area/eventmap/inside) +"age" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"agf" = ( +/obj/machinery/vending/wardrobe/gene_wardrobe, +/turf/open/floor/wood, +/area/eventmap/inside) +"agg" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/fireaxecabinet{ + pixel_y = -32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"agh" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/machinery/light/small/built, +/turf/open/floor/wood, +/area/eventmap/inside) +"agi" = ( +/obj/structure/chair/comfy/plywood, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"agj" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"agk" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"agl" = ( +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"agm" = ( +/obj/item/stack/sheet/bone, +/mob/living/simple_animal/hostile/skeleton{ + a_intent = "friendly"; + attack_sound = 'sound/vox_fem/bone.ogg'; + harm_intent_damage = -5; + melee_damage_lower = 1; + melee_damage_upper = 10; + name = "Closet Skeleton" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"agn" = ( +/obj/item/stack/sheet/bone, +/obj/effect/spawner/lootdrop/costume, +/mob/living/simple_animal/hostile/skeleton{ + a_intent = "friendly"; + attack_sound = 'sound/vox_fem/bone.ogg'; + harm_intent_damage = -5; + melee_damage_lower = 1; + melee_damage_upper = 10; + name = "Closet Skeleton" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ago" = ( +/obj/item/shadowcloak, +/mob/living/simple_animal/hostile/skeleton{ + a_intent = "friendly"; + attack_sound = 'sound/vox_fem/bone.ogg'; + harm_intent_damage = -5; + melee_damage_lower = 1; + melee_damage_upper = 10; + name = "Closet Skeleton" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"agp" = ( +/obj/effect/decal/cleanable/generic, +/turf/open/floor/wood, +/area/eventmap/inside) +"agq" = ( +/obj/structure/closet/secure_closet/medical3, +/obj/item/healthanalyzer/advanced, +/turf/open/floor/wood, +/area/eventmap/inside) +"agr" = ( +/obj/structure/flora/grass/jungle/b, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"ags" = ( +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"agt" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood{ + icon_state = "wood-broken5" + }, +/area/eventmap/inside) +"agu" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/glass/bottle/charcoal, +/obj/item/reagent_containers/food/drinks/mug/tea, +/turf/open/floor/wood, +/area/eventmap/inside) +"agv" = ( +/obj/machinery/computer/med_data{ + dir = 1 + }, +/obj/structure/window/reinforced, +/turf/open/floor/wood, +/area/eventmap/inside) +"agw" = ( +/obj/machinery/cryopod{ + dir = 4 + }, +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/eventmap/inside) +"agx" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Medbay Storage"; + req_access_txt = "5" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"agy" = ( +/obj/structure/mineral_door/wood, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/wood, +/area/eventmap/inside) +"agz" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"agA" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"agB" = ( +/obj/machinery/camera/emp_proof, +/turf/open/floor/wood, +/area/eventmap/inside) +"agC" = ( +/obj/structure/chair/wood/wings{ + dir = 4 + }, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"agD" = ( +/obj/structure/table/wood/poker, +/obj/item/toy/cards/deck, +/obj/item/stamp/qm{ + pixel_x = -5; + pixel_y = 3 + }, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"agE" = ( +/obj/structure/table/wood/poker, +/obj/item/storage/fancy/donut_box, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"agF" = ( +/obj/structure/table/wood/poker, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/fancy/candle_box, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"agG" = ( +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"agH" = ( +/obj/structure/toilet{ + dir = 4 + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"agI" = ( +/mob/living/simple_animal/hostile/retaliate/nanotrasenpeace{ + a_intent = "friendly"; + alpha = 150; + attack_sound = 'sound/items/towelwipe.ogg'; + desc = "A ghost who is intent on spraying you with purfume and toweling you, then expecting a tip after!! Spooky!!!"; + icon_state = "paperwizard"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Spooky Restroom attendant" + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"agJ" = ( +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"agK" = ( +/obj/structure/mirror, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"agL" = ( +/obj/structure/sink{ + dir = 8; + pixel_x = -12 + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"agM" = ( +/obj/structure/mineral_door/wood{ + name = "closet" + }, +/obj/structure/barricade/wooden/crude, +/turf/open/floor/wood, +/area/eventmap/inside) +"agN" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"agO" = ( +/obj/structure/noticeboard/cmo{ + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"agP" = ( +/obj/effect/spawner/lootdrop/costume, +/obj/structure/table/wood/fancy/orange, +/turf/open/floor/wood, +/area/eventmap/inside) +"agQ" = ( +/obj/structure/window/reinforced/spawner, +/turf/open/floor/wood, +/area/eventmap/inside) +"agR" = ( +/obj/item/clothing/accessory/skullcodpiece, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"agS" = ( +/turf/open/floor/wood{ + icon_state = "wood-broken3" + }, +/area/eventmap/inside) +"agT" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/wood/damturf/broken5, +/area/eventmap/inside) +"agU" = ( +/obj/structure/closet/secure_closet/engineering_chief, +/obj/item/stamp/ce, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"agV" = ( +/obj/structure/window/fulltile, +/obj/structure/barricade/wooden/crude, +/turf/open/floor/wood, +/area/eventmap/inside) +"agW" = ( +/obj/structure/table/wood/poker, +/obj/item/toy/cards/deck/cas, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"agX" = ( +/obj/structure/table/wood/poker, +/obj/item/trash/candle, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"agY" = ( +/obj/structure/table/wood/poker, +/obj/item/toy/cards/deck/syndicate, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"agZ" = ( +/obj/item/chair/wood/wings, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"aha" = ( +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"ahb" = ( +/obj/structure/mirror, +/obj/structure/mirror{ + dir = 8 + }, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"ahc" = ( +/obj/effect/decal/cleanable/cobweb, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"ahd" = ( +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/wood{ + icon_state = "wood-broken7" + }, +/area/eventmap/inside) +"ahe" = ( +/obj/structure/fireplace, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahf" = ( +/obj/item/candle/infinite, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahg" = ( +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"ahh" = ( +/obj/item/rupee, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahi" = ( +/obj/effect/meteor/pumpkin{ + lifetime = 2.14748e+009; + light_color = "#FFCC66"; + light_range = 3 + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"ahj" = ( +/obj/structure/sign/directions/command{ + dir = 8; + pixel_y = 40 + }, +/obj/structure/sign/directions/security{ + dir = 8; + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahk" = ( +/obj/structure/sign/directions/science{ + pixel_x = 32; + pixel_y = 32 + }, +/obj/structure/sign/directions/evac{ + pixel_x = 32; + pixel_y = 24 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahl" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/clothing/suit/straight_jacket, +/obj/machinery/light/broken{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahm" = ( +/obj/structure/table_frame/wood, +/obj/item/stack/sheet/mineral/wood, +/obj/effect/decal/cleanable/generic, +/obj/item/gun/magic/staff/healing, +/obj/item/gun/magic/wand/resurrection, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahn" = ( +/obj/structure/dresser, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"aho" = ( +/obj/structure/table/wood/fancy/green, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/item/storage/backpack/satchel/med, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahp" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/sign/mining, +/turf/open/floor/plating, +/area/eventmap/inside) +"ahq" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahr" = ( +/obj/effect/spawner/structure/window, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahs" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"aht" = ( +/obj/structure/window/fulltile, +/obj/structure/barricade/wooden/crude, +/obj/structure/spacevine, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahu" = ( +/obj/structure/table/wood/poker, +/obj/item/toy/cards/deck/cas/black, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"ahv" = ( +/obj/structure/table/wood/poker, +/obj/item/dice/d6, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"ahw" = ( +/obj/structure/table/wood/poker, +/obj/item/dice/d20, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"ahx" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"ahy" = ( +/obj/structure/toilet{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"ahz" = ( +/obj/structure/table/wood/fancy/royalblack, +/obj/item/ship_in_a_bottle, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahA" = ( +/obj/structure/table/wood/fancy/royalblack, +/obj/item/soapstone/infinite, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahB" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahC" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahD" = ( +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahE" = ( +/obj/machinery/light, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/outside) +"ahF" = ( +/obj/structure/closet/secure_closet/RD, +/obj/structure/dresser, +/turf/open/floor/carpet/purple, +/area/eventmap/inside) +"ahG" = ( +/obj/structure/closet/secure_closet/RD, +/obj/item/stamp/rd, +/turf/open/floor/carpet/purple, +/area/eventmap/inside) +"ahH" = ( +/obj/machinery/vending/wardrobe/law_wardrobe, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahI" = ( +/obj/machinery/vending/wardrobe/robo_wardrobe, +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahJ" = ( +/obj/structure/spacevine, +/turf/closed/mineral/ash_rock, +/area/eventmap/mountain) +"ahK" = ( +/obj/machinery/vending/wardrobe/science_wardrobe, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahL" = ( +/turf/open/floor/sepia, +/area/eventmap/inside) +"ahM" = ( +/obj/machinery/vending/wardrobe/engi_wardrobe, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahN" = ( +/obj/structure/table/wood/fancy/orange, +/obj/item/clothing/suit/armor/riot/knight{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/clothing/suit/armor/riot/knight, +/obj/item/clothing/suit/armor/riot/knight{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/item/clothing/head/helmet/knight{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/clothing/head/helmet/knight, +/obj/item/clothing/head/helmet/knight{ + pixel_x = -4; + pixel_y = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahO" = ( +/obj/machinery/sleeper/syndie/fullupgrade{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahP" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahQ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahR" = ( +/obj/item/paper/fluff/balls/spookyasylum/healstaffnote, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahS" = ( +/obj/structure/chair/wood/wings{ + dir = 1 + }, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"ahT" = ( +/obj/structure/table/wood/fancy/royalblack, +/obj/item/clothing/head/hardhat/pumpkinhead/jaqc, +/obj/item/seeds/pumpkin, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahU" = ( +/obj/item/candle/infinite, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"ahV" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ahW" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"ahX" = ( +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"ahY" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"ahZ" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/spooktime/cobble/sideW, +/area/eventmap/outside) +"aia" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/curtain{ + color = "#B22222"; + pixel_x = -32 + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"aib" = ( +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/obj/structure/bed, +/obj/item/bedsheet/ce, +/obj/effect/landmark/start/chief_engineer, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"aic" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/eventmap/inside) +"aid" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/door/airlock/command/glass{ + name = "Bridge"; + req_access_txt = "19" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aie" = ( +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/carpet/purple, +/area/eventmap/inside) +"aif" = ( +/obj/machinery/vending/cola/red, +/turf/open/floor/wood, +/area/eventmap/inside) +"aig" = ( +/obj/effect/turf_decal/caution, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"aih" = ( +/obj/structure/chair/wood{ + dir = 1 + }, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"aii" = ( +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"aij" = ( +/mob/living/simple_animal/mouse/brown/Tom, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"aik" = ( +/obj/machinery/computer/slot_machine, +/turf/open/floor/wood{ + icon_state = "wood-broken2" + }, +/area/eventmap/inside) +"ail" = ( +/obj/machinery/computer/arcade/orion_trail/kobayashi, +/turf/open/floor/wood, +/area/eventmap/inside) +"aim" = ( +/obj/machinery/computer/arcade/battle, +/turf/open/floor/wood, +/area/eventmap/inside) +"ain" = ( +/obj/machinery/computer/arcade/orion_trail, +/turf/open/floor/wood{ + icon_state = "wood-broken4" + }, +/area/eventmap/inside) +"aio" = ( +/obj/machinery/computer/arcade/amputation, +/turf/open/floor/wood, +/area/eventmap/inside) +"aip" = ( +/obj/machinery/computer/arcade/orion_trail, +/turf/open/floor/wood, +/area/eventmap/inside) +"aiq" = ( +/obj/structure/chair/wood{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"air" = ( +/obj/structure/sign/departments/restroom{ + pixel_y = 32 + }, +/turf/open/floor/carpet/purple, +/area/eventmap/inside) +"ais" = ( +/obj/structure/closet/cabinet, +/obj/item/camera/timefreeze, +/obj/item/cane, +/obj/item/cardboard_cutout, +/turf/open/floor/wood, +/area/eventmap/inside) +"ait" = ( +/obj/structure/dresser, +/turf/open/floor/carpet/cyan, +/area/eventmap/inside) +"aiu" = ( +/obj/structure/fireplace, +/turf/open/floor/carpet/cyan, +/area/eventmap/inside) +"aiv" = ( +/turf/open/floor/carpet/cyan, +/area/eventmap/inside) +"aiw" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp, +/turf/open/floor/carpet/cyan, +/area/eventmap/inside) +"aix" = ( +/obj/effect/temp_visual/cult/turf/floor, +/turf/open/floor/wood, +/area/eventmap/inside) +"aiy" = ( +/obj/effect/decal/cleanable/blood/tracks, +/turf/open/floor/wood, +/area/eventmap/inside) +"aiz" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/curtain{ + color = "#B22222"; + pixel_x = 32 + }, +/turf/open/floor/carpet/purple, +/area/eventmap/inside) +"aiA" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"aiB" = ( +/obj/structure/table/wood/fancy/orange, +/obj/item/clothing/suit/armor/riot/knight/yellow{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/clothing/suit/armor/riot/knight/yellow, +/obj/item/clothing/suit/armor/riot/knight/yellow{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/item/clothing/head/helmet/knight/yellow{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/clothing/head/helmet/knight/yellow, +/obj/item/clothing/head/helmet/knight/yellow{ + pixel_x = -4; + pixel_y = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aiC" = ( +/obj/structure/sign/departments/chemistry{ + pixel_y = -32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aiD" = ( +/obj/machinery/vending/snack/green, +/turf/open/floor/wood, +/area/eventmap/inside) +"aiE" = ( +/obj/structure/table/wood, +/obj/item/stack/medical/bruise_pack, +/obj/item/stack/medical/ointment, +/obj/item/candle/infinite, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"aiF" = ( +/obj/machinery/smartfridge/chemistry/preloaded, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"aiG" = ( +/obj/structure/table/wood, +/obj/item/folder/white, +/obj/item/folder/blue, +/obj/item/reagent_containers/food/drinks/mug/coco, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"aiH" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aiI" = ( +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/carpet/orange, +/area/eventmap/inside) +"aiJ" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/noticeboard/ce{ + pixel_y = 32 + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"aiK" = ( +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"aiL" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aiM" = ( +/obj/structure/mineral_door/wood, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/sepia, +/area/eventmap/inside) +"aiN" = ( +/obj/structure/showcase/machinery/tv, +/turf/open/floor/wood, +/area/eventmap/inside) +"aiO" = ( +/mob/living/simple_animal/mouse/brown, +/turf/open/floor/wood, +/area/eventmap/inside) +"aiP" = ( +/obj/structure/bed, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/carpet/cyan, +/area/eventmap/inside) +"aiQ" = ( +/obj/structure/bed, +/obj/item/bedsheet/cosmos, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"aiR" = ( +/obj/effect/decal/cleanable/blood/tracks, +/obj/item/candle/infinite, +/turf/open/floor/wood, +/area/eventmap/inside) +"aiS" = ( +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"aiT" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/indestructible/cobble, +/area/eventmap/outside) +"aiU" = ( +/obj/structure/chair/wood{ + dir = 4 + }, +/obj/item/chair/wood, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"aiV" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/trash/plate, +/turf/open/floor/wood, +/area/eventmap/inside) +"aiW" = ( +/obj/machinery/chem_master, +/turf/open/floor/wood, +/area/eventmap/inside) +"aiX" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"aiY" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"aiZ" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"aja" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"ajb" = ( +/obj/structure/chair/wood{ + dir = 1 + }, +/obj/effect/landmark/start/chemist, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajc" = ( +/obj/structure/table/glass, +/obj/item/reagent_containers/dropper, +/obj/item/reagent_containers/dropper, +/obj/item/reagent_containers/glass/beaker/large, +/obj/item/reagent_containers/glass/beaker/large, +/obj/item/stack/sheet/mineral/plasma, +/obj/item/stack/sheet/mineral/plasma, +/obj/item/storage/box/beakers, +/obj/item/storage/box/beakers, +/obj/item/storage/box/beakers/bluespace, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajd" = ( +/obj/structure/chair/wood{ + dir = 1 + }, +/obj/item/toy/plush/catgirl/fermis, +/turf/open/floor/wood, +/area/eventmap/inside) +"aje" = ( +/turf/open/floor/wood{ + icon_state = "wood-broken" + }, +/area/eventmap/inside) +"ajf" = ( +/obj/structure/table/wood, +/obj/item/pen, +/obj/item/folder/documents, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajg" = ( +/obj/structure/chair/office/light{ + dir = 8 + }, +/turf/open/floor/carpet/cyan, +/area/eventmap/inside) +"ajh" = ( +/obj/structure/table/wood/fancy/royalblack, +/obj/item/clothing/head/hardhat/pumpkinhead/jaqc, +/turf/open/floor/wood, +/area/eventmap/inside) +"aji" = ( +/obj/item/toy/plush/mammal/dog, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajj" = ( +/obj/structure/table/wood, +/obj/item/hemostat/supermatter, +/turf/open/floor/carpet/cyan, +/area/eventmap/inside) +"ajk" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ajl" = ( +/obj/structure/sign/directions/evac{ + dir = 8; + pixel_x = 32 + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"ajm" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ajn" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"ajo" = ( +/obj/machinery/sleeper/syndie/fullupgrade{ + dir = 8 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"ajp" = ( +/obj/machinery/iv_drip, +/obj/structure/closet/crate/freezer/blood, +/turf/open/floor/sepia, +/area/eventmap/inside) +"ajq" = ( +/obj/structure/chair/sofa/right{ + dir = 1 + }, +/turf/open/floor/wood{ + icon_state = "wood-broken" + }, +/area/eventmap/inside) +"ajr" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"ajs" = ( +/obj/structure/table/wood, +/obj/item/toy/cards/deck/cas/black, +/obj/item/toy/cards/deck/cas/black, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajt" = ( +/obj/structure/chair/comfy/plywood, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"aju" = ( +/obj/structure/table/wood, +/obj/item/toy/cards/deck/syndicate, +/obj/item/toy/cards/deck/syndicate, +/obj/item/toy/cards/deck/syndicate, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajv" = ( +/obj/structure/table/wood, +/obj/item/toy/cards/deck/cas, +/obj/item/toy/cards/deck/cas, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajw" = ( +/obj/structure/table/wood, +/obj/item/toy/cards/deck, +/obj/item/toy/cards/deck, +/obj/item/toy/cards/deck, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajx" = ( +/obj/item/clothing/suit/ghost_sheet, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajy" = ( +/obj/structure/spacevine, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"ajz" = ( +/obj/item/paper/pamphlet/ruin/originalcontent/yelling, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"ajA" = ( +/obj/structure/table/wood/fancy/royalblack, +/obj/item/key/collar, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajB" = ( +/obj/structure/table/wood/fancy/royalblack, +/obj/item/lipstick, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajC" = ( +/obj/machinery/vending/wallmed{ + pixel_y = 32 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"ajD" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/structure/bed/roller, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/clothing/suit/straight_jacket, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"ajE" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajF" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/spray/cleaner{ + pixel_x = 8; + pixel_y = 3 + }, +/obj/item/reagent_containers/glass/bucket, +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajG" = ( +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/indestructible/cobble, +/area/eventmap/outside) +"ajH" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"ajI" = ( +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"ajJ" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/spooktime/cobble/sideE, +/area/eventmap/outside) +"ajK" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/noticeboard/rd{ + pixel_y = 32 + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"ajL" = ( +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/turf/open/floor/carpet/purple, +/area/eventmap/inside) +"ajM" = ( +/obj/structure/chair/wood{ + dir = 4 + }, +/turf/open/floor/wood{ + icon_state = "wood-broken5" + }, +/area/eventmap/inside) +"ajN" = ( +/obj/item/clothing/suit/ghost_sheet, +/turf/open/floor/carpet/purple, +/area/eventmap/inside) +"ajO" = ( +/turf/open/floor/carpet/purple, +/area/eventmap/inside) +"ajP" = ( +/obj/structure/table/wood, +/obj/item/pen, +/obj/item/storage/box/fountainpens, +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajQ" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"ajR" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lantern, +/obj/item/folder/syndicate/red, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"ajS" = ( +/obj/item/statuebust, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajT" = ( +/obj/item/statuebust, +/turf/open/floor/wood{ + icon_state = "wood-broken2" + }, +/area/eventmap/inside) +"ajU" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/storage/fancy/donut_box, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajV" = ( +/obj/machinery/chem_dispenser, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajW" = ( +/obj/machinery/chem_heater, +/obj/effect/decal/cleanable/greenglow, +/turf/open/floor/wood, +/area/eventmap/inside) +"ajX" = ( +/obj/structure/closet/crate/freezer/surplus_limbs, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"ajY" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"ajZ" = ( +/obj/structure/table/wood, +/obj/item/cautery{ + pixel_y = 3 + }, +/obj/item/retractor, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aka" = ( +/obj/item/mop, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"akb" = ( +/obj/structure/bed, +/obj/item/bedsheet/rd/royal_cape, +/obj/effect/landmark/start/research_director, +/turf/open/floor/carpet/purple, +/area/eventmap/inside) +"akc" = ( +/obj/structure/table/wood/fancy/orange, +/obj/item/clothing/suit/armor/riot/knight/red{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/clothing/suit/armor/riot/knight/red, +/obj/item/clothing/suit/armor/riot/knight/red{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/item/clothing/head/helmet/knight/red{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/clothing/head/helmet/knight/red, +/obj/item/clothing/head/helmet/knight/red{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"akd" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"ake" = ( +/obj/structure/sign/poster/official/no_erp, +/turf/closed/wall/r_wall, +/area/eventmap/inside) +"akf" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"akg" = ( +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/wood, +/area/eventmap/inside) +"akh" = ( +/obj/structure/chair/wood/wings, +/mob/living/simple_animal/astral, +/turf/open/floor/wood{ + icon_state = "wood-broken5" + }, +/area/eventmap/inside) +"aki" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/mob/living/simple_animal/hostile/retaliate/bat, +/turf/open/floor/wood, +/area/eventmap/inside) +"akj" = ( +/obj/structure/chair/wood/wings, +/turf/open/floor/wood, +/area/eventmap/inside) +"akk" = ( +/obj/structure/chair/wood/wings, +/turf/open/floor/wood{ + icon_state = "wood-broken2" + }, +/area/eventmap/inside) +"akl" = ( +/obj/structure/bed, +/obj/effect/spawner/lootdrop/bedsheet, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"akm" = ( +/obj/structure/mineral_door/woodrustic, +/obj/structure/barricade/wooden/crude, +/obj/structure/spacevine, +/turf/open/floor/wood, +/area/eventmap/inside) +"akn" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/chair/wood, +/obj/item/clothing/glasses/hud/health, +/obj/item/clothing/glasses/hud/health, +/obj/item/clothing/glasses/hud/health, +/turf/open/floor/wood, +/area/eventmap/inside) +"ako" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"akp" = ( +/obj/effect/landmark/start/chief_engineer, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"akq" = ( +/obj/effect/landmark/start/research_director, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"akr" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"aks" = ( +/obj/structure/closet/wardrobe/chemistry_white, +/obj/machinery/light/small{ + dir = 8 + }, +/obj/item/grenade/chem_grenade/glitter/blue, +/obj/item/grenade/chem_grenade/glitter/pink, +/obj/item/grenade/chem_grenade/glitter/white, +/turf/open/floor/wood, +/area/eventmap/inside) +"akt" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/effect/decal/cleanable/chem_pile, +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/eventmap/inside) +"aku" = ( +/obj/structure/closet/secure_closet/medical1, +/turf/open/floor/wood, +/area/eventmap/inside) +"akv" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"akw" = ( +/obj/structure/chair/wood/wings{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"akx" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/book_of_babel, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"aky" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/candle/infinite, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"akz" = ( +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"akA" = ( +/turf/open/floor/spooktime/riverwatermotion, +/area/eventmap/outside) +"akB" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/toy/plush/lampplushie, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"akC" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/book/granter/action/drink_fling, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"akD" = ( +/obj/structure/table/wood/fancy/red, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"akE" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/storage/bag/books, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"akF" = ( +/obj/structure/closet/cabinet, +/obj/item/codespeak_manual/unlimited, +/obj/item/cookiesynth, +/obj/item/fugu_gland, +/turf/open/floor/wood, +/area/eventmap/inside) +"akG" = ( +/obj/structure/dresser, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"akH" = ( +/obj/item/ectoplasm, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"akI" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp/bananalamp, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"akJ" = ( +/obj/machinery/washing_machine, +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/wood, +/area/eventmap/inside) +"akK" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating washing machine possesed by some specture! Responsibilities, clearly the scariest thing imaginable."; + icon = 'icons/obj/machines/washing_machine.dmi'; + icon_dead = "wm_1_0"; + icon_gib = "wm_1_0"; + icon_living = "wm_1_0"; + icon_state = "wm_1_0"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed washing machine" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"akL" = ( +/obj/structure/closet/cabinet, +/obj/item/instrument/accordion, +/obj/item/instrument/bikehorn, +/obj/item/instrument/eguitar, +/obj/item/instrument/glockenspiel, +/turf/open/floor/wood, +/area/eventmap/inside) +"akM" = ( +/obj/structure/table/wood/fancy/monochrome, +/obj/item/instrument/violin/golden, +/turf/open/floor/wood, +/area/eventmap/inside) +"akN" = ( +/obj/structure/table/wood/fancy/monochrome, +/obj/machinery/chem_dispenser/drinks/fullupgrade, +/turf/open/floor/wood, +/area/eventmap/inside) +"akO" = ( +/obj/structure/table/wood/fancy/monochrome, +/obj/machinery/chem_dispenser/drinks/beer/fullupgrade, +/turf/open/floor/wood, +/area/eventmap/inside) +"akP" = ( +/obj/structure/table/wood/fancy/monochrome, +/obj/item/instrument/trumpet/spectral, +/obj/item/instrument/trombone/spectral, +/obj/item/instrument/saxophone/spectral, +/turf/open/floor/wood, +/area/eventmap/inside) +"akQ" = ( +/obj/structure/closet/cabinet, +/obj/item/instrument/guitar, +/obj/item/instrument/harmonica, +/obj/item/instrument/piano_synth, +/obj/item/instrument/recorder, +/turf/open/floor/wood, +/area/eventmap/inside) +"akR" = ( +/obj/machinery/jukebox, +/turf/open/floor/wood, +/area/eventmap/inside) +"akS" = ( +/obj/structure/bookcase/random/reference, +/turf/open/floor/wood, +/area/eventmap/inside) +"akT" = ( +/obj/structure/table/wood/fancy/orange, +/obj/item/clothing/suit/armor/riot/knight/blue{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/clothing/suit/armor/riot/knight/blue, +/obj/item/clothing/suit/armor/riot/knight/blue{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/item/stamp/clown, +/obj/item/clothing/head/helmet/knight/blue{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/clothing/head/helmet/knight/blue, +/obj/item/clothing/head/helmet/knight/blue{ + pixel_x = -4; + pixel_y = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"akU" = ( +/obj/structure/dresser, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"akV" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/obj/machinery/door/airlock/command/glass{ + name = "Bridge"; + req_access_txt = "19" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"akW" = ( +/obj/structure/table/wood/fancy, +/turf/open/floor/wood, +/area/eventmap/inside) +"akX" = ( +/obj/effect/landmark/start/medical_doctor, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"akY" = ( +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"akZ" = ( +/obj/machinery/computer/security{ + dir = 4 + }, +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ala" = ( +/obj/machinery/computer/station_alert, +/turf/open/floor/wood, +/area/eventmap/inside) +"alb" = ( +/obj/machinery/computer/monitor{ + name = "bridge power monitoring console" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ald" = ( +/obj/machinery/computer/cargo/request, +/turf/open/floor/wood, +/area/eventmap/inside) +"ale" = ( +/obj/machinery/computer/communications, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"alf" = ( +/obj/structure/table/wood, +/obj/machinery/computer/med_data/laptop, +/turf/open/floor/wood, +/area/eventmap/inside) +"alg" = ( +/obj/effect/turf_decal/stripes/asteroid/corner, +/turf/open/floor/wood, +/area/eventmap/inside) +"alh" = ( +/obj/structure/table/wood, +/obj/item/circular_saw, +/obj/item/hemostat, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"ali" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood{ + icon_state = "wood-broken2" + }, +/area/eventmap/inside) +"alj" = ( +/obj/effect/decal/cleanable/glass, +/obj/item/organ/tail/cat, +/obj/machinery/light/broken{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"alk" = ( +/obj/effect/turf_decal/stripes/asteroid/line, +/obj/structure/table/wood, +/obj/item/paper_bin, +/obj/item/pen, +/turf/open/floor/wood, +/area/eventmap/inside) +"all" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/book/granter/crafting_recipe/under_the_oven, +/obj/item/book/granter/crafting_recipe/cooking_sweets_101, +/obj/item/book/granter/crafting_recipe/coldcooking, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"alm" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"aln" = ( +/obj/structure/table/wood/fancy/red, +/obj/item/storage/book/bible/booze, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"alo" = ( +/obj/structure/table/wood/fancy/red, +/obj/machinery/computer/libraryconsole, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"alp" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet/purple, +/area/eventmap/inside) +"alq" = ( +/obj/structure/sign/poster/official/ian, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"alr" = ( +/mob/living/simple_animal/crab/evil, +/turf/open/floor/wood, +/area/eventmap/inside) +"als" = ( +/mob/living/simple_animal/mouse/gray, +/turf/open/floor/wood, +/area/eventmap/inside) +"alt" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "synth"; + icon_gib = "synth"; + icon_living = "synth"; + icon_state = "synth"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed synth" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"alu" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "glockenspiel"; + icon_gib = "glockenspiel"; + icon_living = "glockenspiel"; + icon_state = "glockenspiel"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed glockenspiel" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"alv" = ( +/obj/machinery/light/small, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"alw" = ( +/obj/structure/table/wood, +/obj/item/toy/cards/deck/syndicate, +/turf/open/floor/wood/damturf/broken3, +/area/eventmap/mountaininside) +"alx" = ( +/obj/effect/turf_decal/stripes/asteroid/line, +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/eventmap/inside) +"aly" = ( +/obj/effect/turf_decal/stripes/asteroid/line, +/turf/open/floor/wood, +/area/eventmap/inside) +"alz" = ( +/obj/machinery/vending/wardrobe/chem_wardrobe, +/turf/open/floor/wood, +/area/eventmap/inside) +"alA" = ( +/obj/structure/closet/cabinet, +/turf/open/floor/carpet, +/area/eventmap/inside) +"alB" = ( +/obj/structure/window/fulltile, +/obj/structure/barricade/wooden/crude, +/obj/effect/spawner/structure/window, +/turf/open/floor/wood, +/area/eventmap/inside) +"alC" = ( +/mob/living/simple_animal/hostile/retaliate/bat/secbat, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"alD" = ( +/obj/structure/chair/wood/wings{ + dir = 1 + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"alE" = ( +/mob/living/simple_animal/hostile/retaliate/bat, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"alF" = ( +/obj/item/toy/cattoy, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"alG" = ( +/obj/structure/dresser, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"alH" = ( +/obj/structure/closet/cabinet, +/obj/item/storage/daki, +/obj/item/valentine, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"alI" = ( +/obj/machinery/pdapainter, +/turf/open/floor/wood, +/area/eventmap/inside) +"alJ" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A floating shopping list. It has the words Milk, eggs and cheese on it."; + icon = 'icons/obj/bureaucracy.dmi'; + icon_dead = "paper_words"; + icon_living = "paper_words"; + icon_state = "paper_words"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Floating Shopping List" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"alK" = ( +/obj/structure/bedsheetbin/towel, +/obj/structure/table/reinforced/brass, +/obj/item/storage/fancy/heart_box, +/turf/open/floor/wood, +/area/eventmap/inside) +"alL" = ( +/obj/structure/flora/ausbushes/sunnybush, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"alM" = ( +/obj/item/chair/wood/wings{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"alN" = ( +/obj/structure/bookcase/manuals/engineering, +/turf/open/floor/wood, +/area/eventmap/inside) +"alO" = ( +/obj/machinery/photocopier, +/turf/open/floor/wood, +/area/eventmap/inside) +"alP" = ( +/obj/structure/mineral_door/wood{ + name = "Costumes and Luxury Dorms" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"alQ" = ( +/obj/structure/table/wood, +/obj/item/toy/cards/deck/cas/black, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"alR" = ( +/obj/effect/spawner/structure/window/reinforced/tinted, +/turf/open/floor/wood, +/area/eventmap/inside) +"alS" = ( +/obj/effect/turf_decal/caution/white{ + dir = 1; + pixel_y = -8 + }, +/turf/open/floor/wood/damturf/broken7, +/area/eventmap/inside) +"alT" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"alU" = ( +/obj/machinery/door/airlock/wood/dorms/dorm03, +/turf/open/floor/wood, +/area/eventmap/inside) +"alV" = ( +/obj/structure/table/wood, +/obj/machinery/computer/secure_data/laptop{ + dir = 4; + pixel_y = 6 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"alW" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"alX" = ( +/obj/structure/chair/office/dark{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"alY" = ( +/obj/structure/table/glass, +/obj/machinery/reagentgrinder, +/obj/item/reagent_containers/glass/beaker/large, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"alZ" = ( +/obj/structure/cloth_pile, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ama" = ( +/obj/structure/chair/office/dark{ + dir = 1 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"amb" = ( +/obj/structure/closet/secure_closet/medical2, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"amc" = ( +/obj/machinery/computer/operating{ + dir = 1 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"amd" = ( +/obj/structure/table/optable, +/obj/item/healthanalyzer/advanced, +/obj/item/clothing/gloves/color/latex/nitrile, +/obj/item/clothing/mask/surgical, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"ame" = ( +/obj/structure/bookcase/random/adult, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"amf" = ( +/obj/structure/bookcase/random/fiction, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"amg" = ( +/obj/structure/bookcase/random/nonfiction{ + books_to_load = 5 + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"amh" = ( +/obj/structure/bookcase/random/reference, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"ami" = ( +/obj/structure/bookcase/random/religion, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"amj" = ( +/obj/structure/bookcase/manuals/medical, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"amk" = ( +/turf/open/floor/plasteel/stairs/medium, +/area/eventmap/inside) +"aml" = ( +/obj/structure/flora/grass/jungle/b, +/obj/effect/wisp, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"amm" = ( +/obj/item/candle/infinite, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"amn" = ( +/obj/structure/flora/junglebush{ + icon_state = "grassa4" + }, +/obj/effect/wisp, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"amo" = ( +/obj/item/toy/fluff/tennis_poly/tri/squeak/rainbow, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"amp" = ( +/obj/item/seeds/pumpkin, +/turf/open/floor/wood, +/area/eventmap/inside) +"amq" = ( +/obj/structure/bedsheetbin/color, +/obj/structure/table/reinforced/brass, +/obj/item/storage/fancy/donut_box, +/turf/open/floor/wood, +/area/eventmap/inside) +"amr" = ( +/obj/item/chair/wood/wings{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ams" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "trumpet"; + icon_gib = "trumpet"; + icon_living = "trumpet"; + icon_state = "trumpet"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed trumpet" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"amt" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "guitar"; + icon_gib = "guitar"; + icon_living = "guitar"; + icon_state = "guitar"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed Guitar" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"amu" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "violin"; + icon_gib = "violin"; + icon_living = "violin"; + icon_state = "violin"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed violin" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"amv" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "saxophone"; + icon_gib = "saxophone"; + icon_living = "saxophone"; + icon_state = "saxophone"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed saxophone" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"amw" = ( +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/turf/open/floor/wood{ + icon_state = "wood-broken6" + }, +/area/eventmap/inside) +"amx" = ( +/obj/structure/table/wood, +/obj/item/scalpel, +/obj/item/surgical_drapes, +/obj/item/surgicaldrill, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"amy" = ( +/obj/structure/table/wood, +/obj/item/storage/box/donkpockets, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"amz" = ( +/obj/structure/bookcase/random/religion, +/turf/open/floor/wood, +/area/eventmap/inside) +"amA" = ( +/obj/structure/bookcase/random/fiction, +/turf/open/floor/wood, +/area/eventmap/inside) +"amB" = ( +/obj/structure/chair/wood{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"amC" = ( +/obj/structure/table/wood/fancy/green, +/turf/open/floor/wood, +/area/eventmap/inside) +"amD" = ( +/obj/structure/table/reinforced, +/obj/structure/table/reinforced, +/obj/item/paper/fluff/balls/spookyasylum{ + name = "paper - 10/7/2559" + }, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"amE" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Chemistry Lab"; + req_access_txt = "5; 33" + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"amF" = ( +/obj/structure/chair/wood/wings{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"amG" = ( +/obj/structure/table/wood, +/obj/machinery/microwave, +/turf/open/floor/wood, +/area/eventmap/inside) +"amH" = ( +/obj/structure/chair/wood{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"amI" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/toy/figure/cmo, +/obj/item/megaphone/command, +/turf/open/floor/wood, +/area/eventmap/inside) +"amJ" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"amK" = ( +/obj/machinery/chem_heater, +/turf/open/floor/wood, +/area/eventmap/inside) +"amL" = ( +/obj/item/candle/infinite, +/obj/machinery/light/small/broken{ + dir = 8 + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"amM" = ( +/obj/structure/flora/ausbushes/palebush, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"amN" = ( +/obj/item/candle/infinite, +/obj/structure/flora/grass/jungle/b, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"amO" = ( +/obj/structure/closet/wardrobe/chemistry_white, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"amP" = ( +/obj/structure/bookcase/random/nonfiction, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"amQ" = ( +/obj/structure/chair/wood{ + dir = 4 + }, +/obj/effect/landmark/start/virologist, +/obj/structure/sign/departments/chemistry{ + pixel_x = -32 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"amR" = ( +/obj/structure/bookcase/manuals/research_and_development, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"amS" = ( +/obj/item/hot_potato/harmless/toy{ + name = "Rotato potato" + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"amT" = ( +/obj/structure/bed/dogbed, +/mob/living/simple_animal/pet/dog/corgi{ + icon_state = "corgigrey"; + name = "Ghost corgi" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"amU" = ( +/obj/item/stack/sheet/bone, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"amV" = ( +/obj/structure/bed/dogbed{ + name = "cat bed" + }, +/mob/living/simple_animal/pet/cat/custom_cat{ + name = "Ghost cat" + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"amW" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp, +/obj/item/reagent_containers/food/snacks/grown/tea/catnip{ + icon_state = "coffee_robusta" + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"amX" = ( +/obj/item/mop, +/obj/item/mop/advanced, +/obj/structure/closet/jcloset, +/obj/item/reagent_containers/spray/cleaner, +/obj/item/reagent_containers/spray/cleaner, +/obj/item/reagent_containers/spray/cleaner, +/obj/item/extinguisher/advanced, +/turf/open/floor/wood, +/area/eventmap/inside) +"amY" = ( +/obj/structure/bedsheetbin, +/obj/structure/table/reinforced/brass, +/obj/item/storage/fancy/candle_box, +/turf/open/floor/wood, +/area/eventmap/inside) +"amZ" = ( +/obj/structure/chair/wood/wings{ + dir = 4 + }, +/turf/open/floor/wood{ + icon_state = "wood-broken5" + }, +/area/eventmap/inside) +"ana" = ( +/obj/structure/flora/grass/jungle/b, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"anb" = ( +/turf/open/floor/grass/fakebasalt, +/area/eventmap/outside) +"anc" = ( +/obj/structure/flora/grass/jungle/b, +/turf/open/floor/grass/fakebasalt, +/area/eventmap/outside) +"and" = ( +/obj/structure/mineral_door/woodrustic, +/turf/open/floor/spooktime/cobble/cornerNW, +/area/eventmap/outside) +"ane" = ( +/obj/structure/flora/grass/jungle/b{ + icon_state = "bushb" + }, +/turf/open/floor/spooktime/cobble/sideN, +/area/eventmap/outside) +"anf" = ( +/obj/structure/flora/grass/jungle/b{ + icon_state = "grassb2" + }, +/turf/open/floor/spooktime/cobble/cornerNE, +/area/eventmap/outside) +"ang" = ( +/obj/structure/table/wood/fancy/black, +/obj/item/storage/box/gloves, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"anh" = ( +/obj/machinery/atmospherics/components/unary/cryo_cell, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"ani" = ( +/obj/structure/chair/office/dark{ + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"anj" = ( +/obj/machinery/atmospherics/pipe/simple{ + dir = 6 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"ank" = ( +/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ + dir = 8 + }, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"anl" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/camera, +/turf/open/floor/wood, +/area/eventmap/inside) +"anm" = ( +/obj/structure/chair/wood, +/obj/effect/landmark/start/chemist, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ann" = ( +/obj/structure/table/glass, +/obj/item/reagent_containers/dropper, +/obj/item/reagent_containers/glass/beaker/large, +/obj/item/stack/sheet/mineral/plasma, +/obj/item/storage/box/beakers, +/turf/open/floor/wood, +/area/eventmap/inside) +"ano" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"anp" = ( +/obj/structure/chair/wood{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/obj/effect/landmark/start/medical_doctor, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"anq" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"anr" = ( +/obj/machinery/computer/card{ + dir = 8 + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ans" = ( +/obj/machinery/light/small, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"ant" = ( +/obj/structure/table/wood/fancy/black, +/obj/item/stack/medical/bruise_pack, +/obj/item/stack/medical/ointment, +/obj/item/stack/medical/gauze, +/obj/item/storage/pill_bottle/mutadone, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"anu" = ( +/obj/machinery/atmospherics/pipe/simple{ + dir = 5 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"anv" = ( +/obj/structure/spacevine, +/obj/structure/spacevine, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/outside) +"anw" = ( +/obj/structure/flora/rock/jungle, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"anx" = ( +/obj/structure/flora/rock/pile/largejungle, +/turf/open/indestructible/cobble, +/area/eventmap/outside) +"any" = ( +/obj/structure/mineral_door/woodrustic, +/turf/open/floor/spooktime/cobble/sideW, +/area/eventmap/outside) +"anz" = ( +/obj/structure/flora/grass/jungle/b{ + icon_state = "bushb3" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"anA" = ( +/obj/structure/fluff/fokoff_sign{ + desc = "A crudely-made sign with the words 'too spooky' written in some sort of red paint." + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"anB" = ( +/obj/structure/flora/grass/jungle/b{ + icon_state = "bushb2" + }, +/turf/open/floor/spooktime/cobble/sideE, +/area/eventmap/outside) +"anC" = ( +/obj/machinery/atmospherics/pipe/manifold, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"anD" = ( +/obj/machinery/atmospherics/pipe/manifold4w, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"anE" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 8 + }, +/obj/machinery/portable_atmospherics/canister/oxygen, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"anF" = ( +/obj/structure/mineral_door/wood, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"anG" = ( +/obj/structure/mineral_door/wood, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"anH" = ( +/obj/structure/flora/ausbushes/leafybush, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"anI" = ( +/obj/structure/flora/grass/jungle/b{ + icon_state = "grassa5" + }, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"anJ" = ( +/turf/open/floor/wood{ + icon_state = "wood-broken7" + }, +/area/eventmap/inside) +"anK" = ( +/obj/structure/bookcase/random/nonfiction, +/turf/open/floor/wood{ + icon_state = "wood-broken" + }, +/area/eventmap/inside) +"anL" = ( +/obj/structure/bookcase/random/adult, +/turf/open/floor/wood{ + icon_state = "wood-broken5" + }, +/area/eventmap/inside) +"anM" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "golden_violin"; + icon_gib = "golden_violin"; + icon_living = "golden_violin"; + icon_state = "golden_violin"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed golden violin" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"anN" = ( +/obj/machinery/jukebox/disco/indestructible{ + req_one_access = list() + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"anO" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "eguitar"; + icon_gib = "eguitar"; + icon_living = "eguitar"; + icon_state = "eguitar"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed electric guitar" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"anP" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/wood, +/area/eventmap/inside) +"anQ" = ( +/obj/machinery/door/airlock{ + name = "Bar Backroom"; + req_access_txt = "25" + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"anR" = ( +/obj/structure/mineral_door/wood, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"anS" = ( +/obj/effect/turf_decal/stripes/asteroid/line{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"anT" = ( +/obj/machinery/door/airlock/wood/dorms/dorm18, +/turf/open/floor/wood, +/area/eventmap/inside) +"anU" = ( +/obj/structure/table/wood, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"anV" = ( +/obj/structure/curtain{ + color = "#B22222"; + pixel_x = 32 + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"anW" = ( +/obj/structure/table/wood/fancy/purple, +/obj/item/reagent_containers/syringe/charcoal, +/obj/item/reagent_containers/glass/bottle/epinephrine, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"anX" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"anY" = ( +/obj/item/candle/infinite, +/obj/structure/flora/grass/jungle/b{ + icon_state = "grassb2" + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"anZ" = ( +/obj/structure/table/wood/fancy/purple, +/obj/item/reagent_containers/glass/beaker/cryoxadone, +/obj/item/reagent_containers/glass/beaker/cryoxadone, +/obj/item/reagent_containers/glass/beaker/cryoxadone, +/obj/item/reagent_containers/glass/beaker/cryoxadone, +/obj/item/wrench/medical, +/obj/item/storage/pill_bottle/mannitol, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aoa" = ( +/obj/machinery/vending/cigarette/beach, +/turf/open/floor/wood, +/area/eventmap/inside) +"aob" = ( +/obj/structure/chair/wood, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"aoc" = ( +/obj/machinery/libraryscanner, +/turf/open/floor/wood, +/area/eventmap/inside) +"aod" = ( +/obj/structure/table/wood, +/obj/machinery/computer/libraryconsole/bookmanagement, +/obj/structure/window/spawner/east, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aoe" = ( +/obj/structure/chair/comfy/black, +/turf/open/floor/wood, +/area/eventmap/inside) +"aof" = ( +/obj/structure/table/wood/fancy, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aog" = ( +/obj/effect/decal/cleanable/blood/tracks, +/obj/structure/falsewall/wood, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoh" = ( +/obj/machinery/light, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"aoi" = ( +/obj/machinery/camera/emp_proof{ + c_tag = "Containment - Particle Accelerator"; + dir = 1; + network = list("singularity") + }, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"aoj" = ( +/obj/machinery/light, +/obj/item/banner/security, +/obj/structure/sign/departments/security{ + pixel_y = -32 + }, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"aok" = ( +/obj/structure/sign/departments/security{ + pixel_y = -32 + }, +/obj/item/banner/security, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aol" = ( +/obj/structure/table/wood, +/obj/item/clothing/glasses/regular, +/obj/item/reagent_containers/food/drinks/bottle/rum{ + name = "Cookie's home made rum" + }, +/obj/effect/decal/cleanable/cobweb, +/obj/item/candle/infinite, +/turf/open/floor/wood, +/area/eventmap/inside) +"aom" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aon" = ( +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoo" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aop" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aoq" = ( +/obj/structure/reagent_dispensers/water_cooler, +/turf/open/floor/carpet/blackred, +/area/eventmap/inside) +"aor" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aos" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aot" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aou" = ( +/obj/machinery/recharge_station, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aov" = ( +/obj/machinery/limbgrower, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aow" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aox" = ( +/obj/machinery/vending/medical, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoy" = ( +/obj/effect/spawner/lootdrop/keg, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoz" = ( +/obj/structure/table/wood/fancy/green, +/obj/effect/spawner/lootdrop/costume, +/obj/machinery/light, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoA" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/defibrillator/loaded, +/obj/item/defibrillator/loaded, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoB" = ( +/obj/structure/table_frame/wood, +/obj/item/chair/wood, +/obj/item/stack/sheet/mineral/wood, +/obj/item/storage/backpack/satchel/vir, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoC" = ( +/obj/machinery/bookbinder, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoD" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aoE" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/landmark/start/librarian, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aoF" = ( +/obj/effect/temp_visual/love_heart, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoG" = ( +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/wood{ + icon_state = "wood-broken2" + }, +/area/eventmap/inside) +"aoH" = ( +/obj/structure/chair/bronze, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoI" = ( +/obj/structure/life_candle, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoJ" = ( +/obj/vehicle/sealed/mecha/working/ripley/deathripley{ + equipment_disabled = 1; + light_color = "#FAA019"; + lights_power = 3 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoK" = ( +/obj/structure/chair/office/dark{ + dir = 1 + }, +/mob/living/simple_animal/astral{ + desc = "...Is haunting Space Station Three."; + name = "Carmen Miranda" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoL" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "bike_horn"; + icon_living = "bike_horn"; + icon_state = "bike_horn"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed Bike Horn" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"aoM" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "pianobroken"; + icon_gib = "pianobroken"; + icon_living = "piano"; + icon_state = "piano"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed piano" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"aoN" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "recorder"; + icon_gib = "recorder"; + icon_living = "recorder"; + icon_state = "recorder"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed recorder" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"aoO" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/mining{ + name = "Cargo Office"; + req_one_access_txt = "48;50" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aoP" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/table/wood, +/obj/structure/window/spawner/east, +/obj/item/paper_bin, +/obj/item/pen{ + desc = "A pen left over from the days this place used to be an asylum. Despite its age it appears perfectly usable when supplied with ink."; + name = "Cyber & Sons Company Pen" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aoQ" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoR" = ( +/turf/open/floor/light/colour_cycle/dancefloor_a, +/area/eventmap/inside) +"aoS" = ( +/obj/machinery/hydroponics/constructable, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoT" = ( +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aoU" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood{ + icon_state = "wood-broken2" + }, +/area/eventmap/inside) +"aoV" = ( +/obj/machinery/button/door/dorms/dorm03, +/obj/effect/turf_decal/delivery/white, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoW" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aoX" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aoY" = ( +/obj/structure/flora/rock/pile/icy, +/obj/effect/wisp, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aoZ" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/spooktime/cobble/cornerSW, +/area/eventmap/outside) +"apa" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"apb" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"apc" = ( +/obj/structure/table/wood, +/obj/machinery/recharger, +/turf/open/floor/wood, +/area/eventmap/inside) +"apd" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ape" = ( +/obj/machinery/computer/crew{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"apf" = ( +/obj/item/toy/plush/narplush/hugbox, +/obj/item/toy/toy_dagger, +/turf/open/floor/wood, +/area/eventmap/inside) +"apg" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/clothing/head/hardhat/pumpkinhead/jaqc, +/turf/open/floor/wood{ + icon_state = "wood-broken2" + }, +/area/eventmap/inside) +"aph" = ( +/turf/open/floor/spooktime/cobble/sideW{ + icon_state = "cobble_side_n" + }, +/area/eventmap/outside) +"api" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/clothing/head/hardhat/pumpkinhead/jaqc, +/turf/open/floor/wood, +/area/eventmap/inside) +"apj" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/gun/magic/staff/healing, +/obj/item/gun/magic/staff/healing, +/obj/item/gun/medbeam, +/turf/open/floor/wood, +/area/eventmap/inside) +"apk" = ( +/obj/structure/life_candle, +/turf/open/floor/wood{ + icon_state = "wood-broken5" + }, +/area/eventmap/inside) +"apl" = ( +/obj/structure/closet/cabinet, +/obj/item/clothing/head/helmet/space/hardsuit/deathsquad, +/obj/item/clothing/suit/space/hardsuit/deathsquad, +/obj/item/circlegame, +/obj/item/nullrod/scythe, +/obj/item/card/id/silver/reaper, +/turf/open/floor/wood, +/area/eventmap/inside) +"apm" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood{ + icon_state = "wood-broken6" + }, +/area/eventmap/inside) +"apn" = ( +/obj/item/chair/wood/wings{ + dir = 1 + }, +/turf/open/floor/wood{ + icon_state = "wood-broken" + }, +/area/eventmap/inside) +"apo" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "minimoogbroken"; + icon_gib = "minimoogbroken"; + icon_living = "minimoog"; + icon_state = "minimoog"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed minimoog" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"app" = ( +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/turf/open/floor/wood{ + icon_state = "wood-broken5" + }, +/area/eventmap/inside) +"apq" = ( +/obj/structure/noticeboard/captain{ + pixel_y = -32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"apr" = ( +/obj/effect/turf_decal/stripes/asteroid/line{ + dir = 9 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aps" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"apt" = ( +/obj/item/banner/medical, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"apu" = ( +/obj/effect/spawner/trap, +/turf/open/indestructible/airblock, +/area/eventmap/mountaininside) +"apv" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"apw" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/table/wood, +/turf/open/floor/carpet, +/area/eventmap/inside) +"apx" = ( +/obj/structure/table/wood, +/turf/open/floor/carpet, +/area/eventmap/inside) +"apy" = ( +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"apz" = ( +/turf/open/floor/engine, +/area/eventmap/inside) +"apA" = ( +/obj/structure/sink{ + dir = 8; + pixel_x = -12 + }, +/obj/machinery/camera/emp_proof{ + c_tag = "Containment - Fore Port"; + dir = 4; + network = list("singularity") + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"apB" = ( +/obj/machinery/biogenerator, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"apC" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "xylophone-broken"; + icon_gib = "xylophone-broken"; + icon_living = "xylophone"; + icon_state = "xylophone"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed xylophone" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"apD" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "accordion"; + icon_gib = "accordion"; + icon_living = "accordion"; + icon_state = "accordion"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed accordion" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"apE" = ( +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"apF" = ( +/obj/effect/turf_decal/stripes/asteroid/line{ + dir = 5 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"apG" = ( +/obj/machinery/button/door/dorms/dorm18, +/turf/open/floor/carpet, +/area/eventmap/inside) +"apH" = ( +/obj/machinery/button/door/dorms/luxury3{ + id = "C02"; + pixel_y = -24 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"apI" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"apJ" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"apK" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"apL" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"apM" = ( +/obj/machinery/light/small, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"apN" = ( +/obj/structure/barricade/wooden, +/obj/structure/spacevine, +/obj/structure/mineral_door/woodrustic, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"apO" = ( +/obj/structure/mineral_door/wood, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"apP" = ( +/obj/item/stack/sheet/mineral/wood, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"apQ" = ( +/mob/living/simple_animal/hostile/retaliate/bat, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"apR" = ( +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"apS" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet/blackred, +/area/eventmap/inside) +"apT" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "harmonica"; + icon_gib = "harmonica"; + icon_living = "harmonica"; + icon_state = "harmonica"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed harmonica" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"apU" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + attack_sound = 'sound/spookoween/ahaha.ogg'; + desc = "A spooky, floating instrument possesed by some specture! Wooo~!"; + icon = 'icons/obj/musician.dmi'; + icon_dead = "trombone"; + icon_gib = "trombone"; + icon_living = "trombone"; + icon_state = "trombone"; + melee_damage_lower = 0; + melee_damage_upper = 0; + name = "Posessed trombone" + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"apV" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"apW" = ( +/obj/effect/turf_decal/bot_white, +/obj/structure/plasticflaps/opaque, +/turf/open/floor/wood, +/area/eventmap/inside) +"apX" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/structure/chair/stool, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"apY" = ( +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"apZ" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqa" = ( +/obj/machinery/door/airlock/command{ + name = "Captain's Office"; + req_access_txt = "20" + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqb" = ( +/obj/effect/turf_decal/stripes/asteroid/line{ + dir = 10 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqc" = ( +/mob/living/simple_animal/hostile/retaliate/bat{ + desc = "A spookster!"; + icon_state = "flan0"; + name = "Name" + }, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"aqd" = ( +/obj/structure/table/wood, +/obj/item/storage/box/bodybags{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/storage/box/bodybags, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqe" = ( +/obj/effect/turf_decal/stripes/asteroid/line{ + dir = 6 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqf" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqg" = ( +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt, +/obj/item/paper/guides/jobs/medical/morgue, +/obj/item/gun/magic/staff/healing, +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqh" = ( +/obj/structure/barricade/wooden, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"aqi" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"aqj" = ( +/turf/open/floor/carpet/blackred, +/area/eventmap/inside) +"aqk" = ( +/obj/structure/sign/departments/cargo{ + pixel_y = 32 + }, +/turf/open/floor/spooktime/cobble/sideN, +/area/eventmap/outside) +"aql" = ( +/obj/structure/chair/wood/wings{ + dir = 8; + icon_state = "brass_chair" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqm" = ( +/obj/structure/table/reinforced, +/obj/item/storage/box/ingredients/delights, +/obj/item/reagent_containers/food/condiment/soysauce, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqn" = ( +/obj/structure/table/reinforced, +/obj/item/storage/box/ingredients/carnivore, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqo" = ( +/obj/structure/table/reinforced, +/obj/item/storage/box/ingredients/american, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqp" = ( +/obj/structure/table/reinforced, +/obj/item/storage/box/donkpockets, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqq" = ( +/obj/structure/table/reinforced, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqr" = ( +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"aqs" = ( +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt, +/obj/structure/bedsheetbin, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqt" = ( +/obj/structure/sign/directions/security{ + dir = 8; + pixel_x = -32; + pixel_y = 24 + }, +/obj/structure/sign/directions/supply{ + dir = 8; + pixel_x = -32; + pixel_y = 32 + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aqu" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/falsewall/wood, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aqv" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqw" = ( +/turf/open/floor/carpet/monochrome, +/area/eventmap/inside) +"aqx" = ( +/mob/living/simple_animal/hostile/retaliate/bat, +/turf/open/floor/carpet/monochrome, +/area/eventmap/inside) +"aqy" = ( +/obj/structure/mineral_door/wood, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"aqz" = ( +/obj/machinery/deepfryer, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"aqA" = ( +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"aqB" = ( +/obj/structure/reagent_dispensers/keg/milk, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"aqC" = ( +/obj/structure/sink/kitchen{ + pixel_y = 28 + }, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"aqD" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"aqE" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aqF" = ( +/obj/structure/table_frame/wood, +/obj/item/stack/sheet/mineral/wood, +/obj/effect/decal/cleanable/glass, +/obj/item/shard, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqG" = ( +/obj/machinery/light/small/broken{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqH" = ( +/obj/structure/table/wood, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aqI" = ( +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aqJ" = ( +/obj/structure/table/wood/fancy, +/obj/item/clothing/head/HoS/beret/syndicate, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqK" = ( +/obj/structure/table/wood/fancy, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/item/reagent_containers/food/condiment/saltshaker, +/obj/item/reagent_containers/food/condiment/peppermill, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqL" = ( +/obj/machinery/seed_extractor, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aqM" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aqN" = ( +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aqO" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aqP" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/medical/glass{ + name = "Chemistry Lab"; + req_access_txt = "5; 33" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aqQ" = ( +/obj/structure/mineral_door/wood, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aqR" = ( +/obj/machinery/clonepod/experimental, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aqS" = ( +/obj/structure/showcase/horrific_experiment, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aqT" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Security Office"; + req_access_txt = "63" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aqU" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/bookcase/random/nonfiction, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqV" = ( +/obj/structure/bookcase/random/nonfiction, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqW" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/clothing/head/hardhat/pumpkinhead/jaqc, +/turf/open/floor/wood{ + icon_state = "wood-broken5" + }, +/area/eventmap/inside) +"aqX" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/item/reagent_containers/food/snacks/grown/tomato/blood, +/obj/item/reagent_containers/food/snacks/grown/tomato/blood, +/obj/item/reagent_containers/food/snacks/grown/tomato/blood, +/obj/item/candle/infinite, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqY" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/item/reagent_containers/food/snacks/soup/blood, +/obj/item/reagent_containers/food/snacks/soup/blood, +/turf/open/floor/wood, +/area/eventmap/inside) +"aqZ" = ( +/obj/structure/table/reinforced, +/obj/item/candle/infinite, +/obj/item/reagent_containers/food/condiment/sugar, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"ara" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"arb" = ( +/obj/machinery/vending/wardrobe/cap_wardrobe, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"arc" = ( +/obj/structure/chair/sofa/left{ + dir = 4 + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"ard" = ( +/obj/effect/landmark/start/botanist, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"are" = ( +/obj/structure/closet/secure_closet/captains, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"arf" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"arg" = ( +/obj/structure/fluff/broken_flooring, +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/plating{ + icon_state = "panelscorched" + }, +/area/eventmap/inside) +"arh" = ( +/obj/machinery/atmospherics/pipe/simple{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"ari" = ( +/obj/machinery/atmospherics/pipe/simple{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"arj" = ( +/obj/machinery/atmospherics/pipe/simple{ + dir = 9 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"ark" = ( +/obj/structure/table/glass, +/obj/item/storage/box/pillbottles, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"arl" = ( +/obj/structure/table/wood, +/obj/item/toy/cards/deck/cas, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"arm" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"arn" = ( +/obj/item/toy/plush/plushvar, +/obj/item/toy/clockwork_watch, +/turf/open/floor/wood, +/area/eventmap/inside) +"aro" = ( +/obj/structure/chair/comfy{ + dir = 1; + icon_state = "shuttle_chair" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"arp" = ( +/turf/open/floor/wood{ + icon_state = "wood-broken6" + }, +/area/eventmap/inside) +"arq" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet/monochrome, +/area/eventmap/inside) +"arr" = ( +/obj/structure/closet/crate/freezer/blood, +/turf/open/floor/wood{ + icon_state = "wood-broken2" + }, +/area/eventmap/inside) +"ars" = ( +/obj/structure/chair/wood/wings, +/mob/living/simple_animal/hostile/retaliate/bat, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"art" = ( +/obj/structure/chair/wood/wings, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"aru" = ( +/obj/structure/chair/wood/wings, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"arv" = ( +/obj/structure/table/reinforced, +/obj/item/storage/bag/tray, +/obj/item/reagent_containers/food/snacks/kebab/human, +/obj/item/reagent_containers/food/snacks/kebab/human, +/obj/item/reagent_containers/food/snacks/kebab/human, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"arw" = ( +/obj/machinery/chem_heater, +/obj/effect/decal/cleanable/greenglow, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"arx" = ( +/obj/machinery/clonepod, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ary" = ( +/obj/machinery/computer/cloning, +/turf/open/floor/plasteel/white/side, +/area/eventmap/inside) +"arz" = ( +/obj/machinery/dna_scannernew, +/turf/open/floor/plasteel/white/side, +/area/eventmap/inside) +"arA" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/machinery/door/airlock/command{ + name = "Head of Personnel's Office"; + req_access_txt = "57" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"arB" = ( +/obj/structure/sign/directions/medical{ + dir = 4; + pixel_x = 32; + pixel_y = 24 + }, +/obj/structure/sign/directions/evac{ + dir = 4; + pixel_x = 32; + pixel_y = 32 + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"arC" = ( +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"arD" = ( +/obj/effect/turf_decal/loading_area, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -24 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"arE" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"arF" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"arG" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"arH" = ( +/obj/item/book/manual/wiki/medical_cloning, +/obj/structure/table/glass, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"arI" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"arJ" = ( +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"arK" = ( +/obj/machinery/door/airlock/wood/dorms/dorm06, +/turf/open/floor/wood, +/area/eventmap/inside) +"arL" = ( +/obj/structure/closet/secure_closet/security/med, +/turf/open/floor/wood, +/area/eventmap/inside) +"arM" = ( +/obj/structure/mineral_door/wood, +/obj/effect/decal/cleanable/blood/tracks{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"arN" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small/broken{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"arO" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"arP" = ( +/obj/effect/decal/cleanable/cobweb{ + icon_state = "stickyweb2" + }, +/obj/structure/falsewall/wood, +/turf/open/floor/wood, +/area/eventmap/inside) +"arQ" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/item/trash/plate, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"arR" = ( +/obj/structure/table/reinforced, +/obj/item/storage/bag/tray, +/obj/item/reagent_containers/food/snacks/pie/pumpkinpie, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"arS" = ( +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/soymilk, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/rice, +/obj/item/reagent_containers/food/condiment/rice, +/obj/item/reagent_containers/food/condiment/rice, +/obj/item/storage/fancy/egg_box, +/obj/item/storage/fancy/egg_box, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"arT" = ( +/obj/structure/table/reinforced, +/obj/machinery/dish_drive, +/obj/item/reagent_containers/food/condiment/enzyme, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"arU" = ( +/obj/structure/table/reinforced, +/obj/machinery/reagentgrinder, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"arV" = ( +/obj/structure/table/reinforced, +/obj/item/storage/box/condimentbottles, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"arW" = ( +/obj/structure/table/reinforced, +/obj/item/storage/box/ingredients/wildcard, +/obj/item/storage/box/ingredients/vegetarian, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"arX" = ( +/obj/structure/table/reinforced, +/obj/item/storage/box/ingredients/sweets, +/obj/item/storage/box/ingredients/italian, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"arY" = ( +/obj/structure/table/reinforced, +/obj/item/storage/box/ingredients/grains, +/obj/item/storage/box/ingredients/fruity, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"arZ" = ( +/obj/structure/table/reinforced, +/obj/item/storage/box/ingredients/fiesta, +/obj/item/storage/box/ingredients/exotic, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"asa" = ( +/obj/effect/landmark/start/captain, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"asb" = ( +/obj/structure/chair/sofa{ + dir = 4 + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"asc" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"asd" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"ase" = ( +/obj/effect/landmark/start/assistant, +/turf/open/floor/wood, +/area/eventmap/inside) +"asf" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/white, +/area/eventmap/inside) +"asg" = ( +/obj/machinery/chem_dispenser, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ash" = ( +/obj/machinery/door/airlock/command{ + name = "Captain's Quarters"; + req_access_txt = "20" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"asi" = ( +/turf/open/floor/plasteel/white/side{ + dir = 6 + }, +/area/eventmap/inside) +"asj" = ( +/turf/open/floor/plasteel/white, +/area/eventmap/inside) +"ask" = ( +/obj/structure/barricade/wooden/crude, +/obj/effect/spawner/structure/window, +/turf/open/floor/wood, +/area/eventmap/inside) +"asl" = ( +/obj/effect/decal/cleanable/cobweb{ + icon_state = "stickyweb2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"asm" = ( +/obj/structure/easel, +/obj/item/paper/pamphlet/ruin/originalcontent/yelling, +/turf/open/floor/wood, +/area/eventmap/inside) +"asn" = ( +/obj/structure/chair/wood/wings{ + dir = 4; + icon_state = "brass_chair" + }, +/mob/living/simple_animal/hostile/retaliate/bat, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"aso" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/item/candle/infinite, +/obj/item/reagent_containers/food/condiment/saltshaker, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"asp" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/item/candle/infinite, +/obj/item/reagent_containers/food/condiment/peppermill, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"asq" = ( +/obj/structure/table/wood/fancy/blackred, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"asr" = ( +/obj/structure/table/reinforced, +/obj/item/storage/bag/tray, +/obj/item/reagent_containers/food/snacks/store/cake/pumpkinspice, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"ass" = ( +/obj/structure/table/reinforced, +/obj/machinery/microwave, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"ast" = ( +/obj/structure/mineral_door/iron, +/turf/open/floor/wood, +/area/eventmap/inside) +"asu" = ( +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"asv" = ( +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/obj/structure/chair/wood, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"asw" = ( +/obj/structure/chair/wood, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"asx" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel/white/side{ + dir = 10 + }, +/area/eventmap/inside) +"asy" = ( +/obj/item/storage/box/bodybags{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/box/bodybags, +/obj/structure/table/glass, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"asz" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/closed/wall/r_wall, +/area/eventmap/inside) +"asA" = ( +/obj/effect/landmark/start/depsec/medical, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"asB" = ( +/obj/structure/bodycontainer/morgue, +/turf/open/floor/wood, +/area/eventmap/inside) +"asC" = ( +/obj/structure/bodycontainer/morgue{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"asD" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"asE" = ( +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"asF" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/door/airlock/mining/glass{ + name = "Cargo Office"; + req_access_txt = "50" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"asG" = ( +/obj/machinery/vending/cart, +/turf/open/floor/wood, +/area/eventmap/inside) +"asH" = ( +/obj/structure/table/wood, +/obj/item/paper_bin, +/obj/item/pen/fourcolor, +/obj/item/stamp/hop, +/turf/open/floor/wood, +/area/eventmap/inside) +"asI" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood/damturf/broken7, +/area/eventmap/inside) +"asJ" = ( +/obj/machinery/door/airlock/wood/dorms/dorm15, +/turf/open/floor/wood, +/area/eventmap/inside) +"asK" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"asL" = ( +/obj/machinery/camera/emp_proof{ + c_tag = "Containment - Fore Starboard"; + dir = 8; + network = list("singularity") + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"asM" = ( +/obj/structure/fence{ + dir = 8 + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"asN" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/bookcase/manuals/engineering, +/turf/open/floor/wood, +/area/eventmap/inside) +"asO" = ( +/obj/structure/bookcase/manuals/medical, +/turf/open/floor/wood, +/area/eventmap/inside) +"asP" = ( +/obj/structure/bookcase/manuals/research_and_development, +/turf/open/floor/wood, +/area/eventmap/inside) +"asQ" = ( +/obj/item/toy/crayon/red, +/turf/open/floor/wood, +/area/eventmap/inside) +"asR" = ( +/obj/item/paint/anycolor, +/obj/item/toy/crayon/rainbow, +/turf/open/floor/wood, +/area/eventmap/inside) +"asS" = ( +/obj/item/stack/spacecash/c20, +/turf/open/floor/wood, +/area/eventmap/inside) +"asT" = ( +/obj/item/paper/crumpled/ruins/originalcontent, +/turf/open/floor/wood, +/area/eventmap/inside) +"asU" = ( +/obj/item/paint/anycolor, +/obj/item/toy/crayon/green, +/turf/open/floor/wood{ + icon_state = "wood-broken3" + }, +/area/eventmap/inside) +"asV" = ( +/obj/item/toy/crayon/purple, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"asW" = ( +/obj/item/paint/anycolor, +/obj/item/stack/spacecash/c50, +/turf/open/floor/wood, +/area/eventmap/inside) +"asX" = ( +/obj/item/paint/anycolor, +/obj/item/toy/crayon/blue, +/turf/open/floor/wood, +/area/eventmap/inside) +"asY" = ( +/obj/item/toy/crayon/white, +/turf/open/floor/wood, +/area/eventmap/inside) +"asZ" = ( +/obj/item/stack/spacecash/c1, +/turf/open/floor/wood, +/area/eventmap/inside) +"ata" = ( +/obj/item/paint/anycolor, +/turf/open/floor/wood, +/area/eventmap/inside) +"atb" = ( +/obj/item/stack/spacecash/c500, +/obj/item/toy/crayon/mime, +/turf/open/floor/wood, +/area/eventmap/inside) +"atc" = ( +/obj/item/toy/crayon/rainbow, +/turf/open/floor/wood, +/area/eventmap/inside) +"atd" = ( +/obj/structure/table/reinforced, +/obj/item/storage/bag/tray, +/obj/item/reagent_containers/food/snacks/burger/ghost, +/obj/item/reagent_containers/food/snacks/burger/ghost, +/obj/item/reagent_containers/food/snacks/burger/ghost, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"ate" = ( +/obj/machinery/icecream_vat{ + name = "Spooky ice cream vat" + }, +/obj/item/toy/snowball, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 9 + }, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"atf" = ( +/obj/structure/fluff/snowlegion, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/spooktime/snow, +/area/eventmap/inside) +"atg" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"ath" = ( +/obj/machinery/gibber/autogibber, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"ati" = ( +/obj/structure/kitchenspike, +/obj/item/toy/snowball, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"atj" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 5 + }, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"atk" = ( +/turf/closed/wall/mineral/snow, +/area/eventmap/inside) +"atl" = ( +/obj/structure/chair/sofa/right{ + dir = 4 + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"atm" = ( +/obj/machinery/jukebox/disco/indestructible{ + req_one_access = list() + }, +/turf/open/floor/engine, +/area/eventmap/inside) +"atn" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ato" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/condiment/saltshaker, +/obj/item/reagent_containers/food/condiment/peppermill, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"atp" = ( +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/obj/machinery/light/small, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"atq" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"atr" = ( +/obj/structure/table/wood/fancy, +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/eventmap/inside) +"ats" = ( +/obj/structure/table/wood, +/obj/machinery/plantgenes/seedvault, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"att" = ( +/obj/structure/sign/poster/contraband/ambrosia_vulgaris{ + pixel_x = 32 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"atu" = ( +/obj/structure/closet/secure_closet/personal/patient, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"atv" = ( +/turf/open/floor/plasteel/white/side{ + dir = 5 + }, +/area/eventmap/inside) +"atw" = ( +/obj/structure/bed, +/obj/effect/spawner/lootdrop/bedsheet, +/obj/machinery/light/small, +/mob/living/carbon/human/species/zombie{ + icon_state = "zombie"; + lying = 1; + name = "Romerol"; + name_override = "Romerol"; + resting = 1 + }, +/mob/living/carbon/human/species/zombie{ + gender = "female"; + icon_state = "zombie"; + lying = 1; + name = "Juliet"; + name_override = "Juliet"; + resting = 1 + }, +/turf/open/floor/clockwork/reebe, +/area/eventmap/inside) +"atx" = ( +/obj/effect/landmark/start/geneticist, +/turf/open/floor/plasteel/white, +/area/eventmap/inside) +"aty" = ( +/turf/open/floor/plasteel/white/side{ + dir = 9 + }, +/area/eventmap/inside) +"atz" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/item/reagent_containers/blood/random, +/obj/item/reagent_containers/blood/random, +/turf/open/floor/wood, +/area/eventmap/inside) +"atA" = ( +/obj/structure/chair/wood/wings{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/mob/living/simple_animal/hostile/retaliate/bat, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"atB" = ( +/obj/structure/chair/wood/wings{ + dir = 1 + }, +/mob/living/simple_animal/hostile/retaliate/bat, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"atC" = ( +/obj/structure/table/reinforced, +/obj/item/storage/bag/tray, +/obj/item/reagent_containers/food/snacks/candiedapple, +/obj/item/reagent_containers/food/snacks/candiedapple, +/obj/item/reagent_containers/food/snacks/candy, +/obj/item/reagent_containers/food/snacks/candy_corn, +/obj/item/reagent_containers/food/snacks/candyheart, +/obj/item/reagent_containers/food/snacks/chocolatebanana, +/obj/item/reagent_containers/food/snacks/chocolatebanana, +/obj/item/reagent_containers/food/snacks/sugarcookie/spookycoffin, +/obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"atD" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"atE" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"atF" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"atG" = ( +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"atH" = ( +/obj/item/storage/box/rxglasses, +/obj/structure/table/glass, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"atI" = ( +/obj/structure/curtain{ + color = "#B22222" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"atJ" = ( +/obj/structure/table/wood, +/obj/machinery/computer/security/wooden_tv{ + pixel_y = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"atK" = ( +/obj/machinery/computer/secure_data, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"atL" = ( +/obj/machinery/door/airlock{ + name = "Bar Staff Entrance"; + req_access_txt = "25" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"atM" = ( +/obj/machinery/door/airlock{ + name = "Kitchen"; + req_access_txt = "28" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"atN" = ( +/obj/structure/table/wood, +/obj/machinery/smartfridge/disks, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"atO" = ( +/obj/effect/decal/cleanable/generic, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"atP" = ( +/obj/machinery/chem_master, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"atQ" = ( +/obj/machinery/shower{ + dir = 4 + }, +/obj/structure/window/reinforced/spawner/north, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"atR" = ( +/obj/machinery/door/window/northleft{ + name = "Cloning Shower" + }, +/obj/structure/mirror{ + pixel_y = -32 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"atS" = ( +/obj/machinery/door/window/northright{ + name = "Cloning Shower" + }, +/obj/machinery/light/small, +/obj/structure/window/reinforced/spawner/east, +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/eventmap/inside) +"atT" = ( +/obj/item/toy/crayon/black, +/turf/open/floor/wood{ + icon_state = "wood-broken6" + }, +/area/eventmap/inside) +"atU" = ( +/obj/item/paint/anycolor, +/obj/item/toy/crayon/white, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"atV" = ( +/obj/item/toy/crayon/spraycan/infinite{ + icon_state = "deathcan2_cap" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"atW" = ( +/obj/item/paint/anycolor, +/obj/item/stack/spacecash/c100, +/turf/open/floor/wood, +/area/eventmap/inside) +"atX" = ( +/obj/item/paper/crumpled/ruins/originalcontent, +/obj/item/toy/crayon/orange, +/turf/open/floor/wood, +/area/eventmap/inside) +"atY" = ( +/mob/living/carbon/monkey{ + color = "#009900"; + icon_state = "monkey1"; + name = "Painting Goblin" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"atZ" = ( +/obj/item/paint/anycolor, +/obj/item/toy/crayon/yellow, +/turf/open/floor/wood, +/area/eventmap/inside) +"aua" = ( +/obj/item/paint/anycolor, +/obj/item/stack/spacecash/c20, +/turf/open/floor/wood, +/area/eventmap/inside) +"aub" = ( +/obj/item/paper/crumpled/ruins/originalcontent, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"auc" = ( +/obj/item/toy/crayon/blue, +/turf/open/floor/wood, +/area/eventmap/inside) +"aud" = ( +/obj/item/paint/anycolor, +/obj/item/toy/crayon/purple, +/turf/open/floor/wood{ + icon_state = "wood-broken5" + }, +/area/eventmap/inside) +"aue" = ( +/obj/item/stack/spacecash/c50, +/turf/open/floor/wood, +/area/eventmap/inside) +"auf" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/item/reagent_containers/blood/random, +/obj/item/reagent_containers/blood/random, +/obj/item/reagent_containers/blood/random, +/obj/item/candle/infinite, +/turf/open/floor/wood, +/area/eventmap/inside) +"aug" = ( +/obj/structure/table/reinforced, +/obj/item/candle/infinite, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"auh" = ( +/obj/machinery/vending/dinnerware, +/turf/open/floor/plasteel/vaporwave, +/area/eventmap/inside) +"aui" = ( +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/item/organ/liver, +/obj/item/organ/liver, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"auj" = ( +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/effect/turf_decal/weather/snow/corner, +/obj/item/organ/heart, +/obj/item/organ/heart, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"auk" = ( +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/item/reagent_containers/food/snacks/snowcones/apple, +/obj/item/reagent_containers/food/snacks/snowcones/blue, +/obj/item/reagent_containers/food/snacks/snowcones/clown, +/obj/item/reagent_containers/food/snacks/snowcones/fruitsalad, +/obj/item/reagent_containers/food/snacks/snowcones/grape, +/obj/item/reagent_containers/food/snacks/snowcones/honey, +/obj/item/reagent_containers/food/snacks/snowcones/kiwi, +/obj/item/reagent_containers/food/snacks/snowcones/lemon, +/obj/item/reagent_containers/food/snacks/snowcones/lime, +/obj/item/reagent_containers/food/snacks/snowcones/mime, +/obj/item/reagent_containers/food/snacks/snowcones/orange, +/obj/item/reagent_containers/food/snacks/snowcones/peach, +/obj/item/reagent_containers/food/snacks/snowcones/pineapple, +/obj/item/reagent_containers/food/snacks/snowcones/rainbow, +/obj/item/reagent_containers/food/snacks/snowcones/red, +/obj/item/reagent_containers/food/snacks/snowcones/soda, +/obj/item/reagent_containers/food/snacks/snowcones/strawberry, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"aul" = ( +/obj/structure/fluff/snowlegion, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/spooktime/snow, +/area/eventmap/inside) +"aum" = ( +/obj/structure/closet/secure_closet/freezer/cream_pie, +/obj/item/reagent_containers/food/snacks/pie/cream, +/obj/item/reagent_containers/food/snacks/pie/cream, +/obj/effect/turf_decal/weather/snow/corner, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"aun" = ( +/obj/structure/closet/secure_closet/freezer/cream_pie, +/obj/item/reagent_containers/food/snacks/pie/cream, +/obj/item/reagent_containers/food/snacks/pie/cream, +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"auo" = ( +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/eventmap/inside) +"aup" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"auq" = ( +/obj/item/gun/magic/staff/healing, +/obj/structure/table/glass, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aur" = ( +/obj/machinery/light, +/obj/structure/cable/yellow, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"aus" = ( +/obj/structure/chair/wood{ + dir = 1 + }, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"aut" = ( +/obj/effect/turf_decal/loading_area{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"auu" = ( +/obj/effect/decal/cleanable/cobweb, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"auv" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"auw" = ( +/obj/structure/sign/directions/security{ + dir = 8; + pixel_x = -32; + pixel_y = -24 + }, +/obj/structure/sign/directions/supply{ + dir = 8; + pixel_x = -32; + pixel_y = -32 + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aux" = ( +/obj/structure/chair/wood, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"auy" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "cargo_in" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating, +/area/eventmap/inside) +"auz" = ( +/obj/structure/chair/wood, +/obj/effect/landmark/start/assistant, +/turf/open/floor/wood/damturf/broken1, +/area/eventmap/inside) +"auA" = ( +/obj/machinery/button/door/dorms/dorm06, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"auB" = ( +/obj/structure/barricade/wooden/snowed, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"auC" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/machinery/vending/games, +/turf/open/floor/wood, +/area/eventmap/inside) +"auD" = ( +/obj/structure/chair/stool/bar, +/turf/open/floor/wood, +/area/eventmap/inside) +"auE" = ( +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"auF" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"auG" = ( +/obj/machinery/camera/emp_proof, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"auH" = ( +/obj/structure/cable/white, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"auI" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"auJ" = ( +/obj/machinery/chem_master/condimaster, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"auK" = ( +/obj/structure/table, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"auL" = ( +/obj/structure/table, +/obj/machinery/reagentgrinder, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"auM" = ( +/obj/structure/table, +/obj/effect/meteor/meaty{ + lifetime = 1e+009 + }, +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"auN" = ( +/obj/machinery/dominator, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"auO" = ( +/obj/machinery/sleeper, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"auP" = ( +/obj/machinery/hydroponics, +/obj/effect/decal/cleanable/glass, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"auQ" = ( +/obj/machinery/computer/operating, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"auR" = ( +/obj/structure/table/optable, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "floor5" + }, +/obj/effect/decal/cleanable/glass, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"auS" = ( +/obj/item/storage/backpack/duffelbag/med/surgery, +/obj/item/book/manual/wiki/surgery, +/obj/structure/table, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"auT" = ( +/obj/machinery/computer/crew, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"auU" = ( +/turf/open/floor/plasteel, +/area/eventmap/inside) +"auV" = ( +/obj/structure/spacevine, +/turf/closed/indestructible/riveted, +/area/eventmap/inside) +"auW" = ( +/obj/structure/table, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/item/storage/box/ingredients/carnivore, +/obj/item/reagent_containers/food/condiment/enzyme, +/obj/item/reagent_containers/food/condiment/enzyme, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"auX" = ( +/obj/structure/alien/resin/membrane, +/obj/structure/spacevine, +/obj/structure/spacevine, +/turf/open/floor/wood, +/area/eventmap/inside) +"auY" = ( +/obj/structure/alien/resin/membrane, +/obj/structure/spacevine, +/obj/structure/spacevine, +/mob/living/simple_animal/hostile/venus_human_trap{ + a_intent = "friendly"; + harm_intent_damage = 0; + melee_damage_lower = 0; + melee_damage_type = "arousal"; + melee_damage_upper = 0 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"auZ" = ( +/obj/structure/kitchenspike, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "gib3" + }, +/obj/effect/decal/cleanable/cobweb, +/obj/item/stack/sheet/animalhide/human, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 9 + }, +/turf/open/floor/plasteel/dark/corner, +/area/eventmap/inside) +"ava" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 1 + }, +/obj/machinery/iv_drip, +/turf/open/floor/plasteel/dark/side, +/area/eventmap/inside) +"avb" = ( +/obj/structure/kitchenspike, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "floor5" + }, +/obj/effect/decal/remains/xeno/larva, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 1 + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "xgiblarvahead" + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "xgibmid2" + }, +/turf/open/floor/plasteel/dark/side, +/area/eventmap/inside) +"avc" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 1 + }, +/obj/machinery/iv_drip, +/turf/open/floor/plasteel/dark/side, +/area/eventmap/inside) +"avd" = ( +/obj/structure/kitchenspike, +/obj/effect/decal/cleanable/blood/splatter, +/obj/effect/decal/remains/human, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 1 + }, +/turf/open/floor/plasteel/dark/side, +/area/eventmap/inside) +"ave" = ( +/obj/structure/kitchenspike, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "gibmid3" + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "remainsxeno" + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 1 + }, +/turf/open/floor/plasteel/dark/side, +/area/eventmap/inside) +"avf" = ( +/obj/structure/kitchenspike, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "floor5" + }, +/obj/item/stack/sheet/animalhide/human, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 1 + }, +/turf/open/floor/plasteel/dark/side, +/area/eventmap/inside) +"avg" = ( +/obj/structure/kitchenspike, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "gibtorso" + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 5 + }, +/turf/open/floor/plasteel/dark/corner{ + dir = 8 + }, +/area/eventmap/inside) +"avh" = ( +/turf/closed/indestructible/necropolis, +/area/eventmap/inside) +"avi" = ( +/atom/movable/screen/alert/status_effect/blooddrunk{ + desc = "You see your disfigured skull screaming on the wall."; + icon = 'icons/mob/screen_gen.dmi'; + icon_state = "Devil-6"; + name = "Foolish creature of meat and bone." + }, +/turf/closed/indestructible/necropolis, +/area/eventmap/inside) +"avj" = ( +/atom/movable/screen/alert/status_effect/blooddrunk{ + desc = "You feel hollow and empy inside."; + icon = 'icons/effects/cult_effects.dmi'; + icon_state = "cultshield"; + name = "You should not have come here." + }, +/turf/closed/indestructible/necropolis, +/area/eventmap/inside) +"avk" = ( +/obj/structure/necropolis_gate, +/obj/structure/mineral_door/iron, +/turf/open/floor/wood, +/area/eventmap/inside) +"avl" = ( +/obj/structure/sink/kitchen{ + pixel_y = 28 + }, +/obj/structure/closet/crate/bin{ + storage_capacity = 300 + }, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"avm" = ( +/obj/structure/bed, +/obj/item/bedsheet/captain, +/turf/open/floor/carpet/royalblue, +/area/eventmap/inside) +"avn" = ( +/obj/machinery/camera/emp_proof{ + c_tag = "Containment - Fore Starboard"; + dir = 8; + network = list("singularity") + }, +/obj/structure/sign/poster/official/hydro_ad{ + pixel_x = 32 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"avo" = ( +/obj/structure/table/wood, +/obj/item/paper_bin, +/obj/item/pen/fountain/captain, +/obj/item/stamp/captain, +/turf/open/floor/wood, +/area/eventmap/inside) +"avp" = ( +/obj/structure/life_candle, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"avq" = ( +/turf/closed/wall/rust, +/area/eventmap/outside) +"avr" = ( +/obj/machinery/door/airlock{ + name = "Hydroponics Backroom"; + req_access_txt = "35" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"avs" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/medical/glass{ + name = "Old Chemistry Lab" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"avt" = ( +/obj/machinery/door/airlock/medical/glass{ + id_tag = "GeneticsDoor"; + name = "Genetics"; + req_access_txt = "5; 68" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"avu" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/conveyor{ + dir = 8; + id = "cargo_in" + }, +/turf/open/floor/plating, +/area/eventmap/inside) +"avv" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/effect/landmark/start/head_of_personnel, +/turf/open/floor/wood, +/area/eventmap/inside) +"avw" = ( +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"avx" = ( +/obj/item/reagent_containers/food/condiment/saltshaker, +/obj/item/reagent_containers/food/condiment/peppermill, +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"avy" = ( +/obj/effect/landmark/start/cook, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"avz" = ( +/obj/effect/decal/cleanable/plasma, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"avA" = ( +/obj/machinery/doppler_array, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"avB" = ( +/obj/effect/decal/cleanable/blood/tracks, +/obj/effect/decal/cleanable/blood/splatter, +/mob/living/simple_animal/pet/cat/custom_cat{ + name = "Ghost cat" + }, +/turf/open/floor/sepia, +/area/eventmap/inside) +"avC" = ( +/obj/machinery/iv_drip, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"avD" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 8; + name = "Blood" + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "floor2" + }, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/eventmap/inside) +"avE" = ( +/obj/item/storage/box/donkpockets, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"avF" = ( +/obj/item/storage/box/fakesyndiesuit, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"avG" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111" + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "gib5" + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"avH" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111" + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"avI" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111" + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "floor5" + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"avJ" = ( +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "gib4" + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"avK" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 4 + }, +/obj/effect/gibspawner/human, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, +/area/eventmap/inside) +"avL" = ( +/atom/movable/screen/alert/status_effect/blooddrunk{ + desc = "I'M WATCHING YOU, COWARD."; + name = "???" + }, +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"avM" = ( +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"avN" = ( +/atom/movable/screen/alert/status_effect/blooddrunk{ + desc = "YOUR SOUL IS MINE, MORTAL."; + name = "???" + }, +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"avO" = ( +/obj/item/reagent_containers/food/condiment/sugar, +/obj/item/reagent_containers/food/condiment/sugar, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"avP" = ( +/obj/structure/bookcase/random/fiction, +/turf/open/floor/wood{ + icon_state = "wood-broken3" + }, +/area/eventmap/inside) +"avQ" = ( +/obj/structure/bed, +/obj/item/bedsheet/random, +/obj/machinery/button/door/dorms/dorm15, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood, +/area/eventmap/inside) +"avR" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/plasticflaps/opaque, +/obj/machinery/conveyor{ + dir = 8; + id = "cargo_in" + }, +/turf/open/floor/plating, +/area/eventmap/inside) +"avS" = ( +/obj/structure/fence, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"avT" = ( +/obj/structure/fluff/empty_cryostasis_sleeper, +/obj/effect/decal/cleanable/glass, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"avU" = ( +/mob/living/simple_animal/astral{ + desc = "...Is haunting Space Station Three."; + name = "Ghost" + }, +/turf/open/floor/sepia, +/area/eventmap/inside) +"avV" = ( +/obj/machinery/loot_locator, +/turf/open/floor/sepia, +/area/eventmap/inside) +"avW" = ( +/obj/effect/decal/cleanable/blood/tracks, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "gib3" + }, +/turf/open/floor/sepia, +/area/eventmap/inside) +"avX" = ( +/turf/closed/indestructible/riveted, +/area/eventmap/inside) +"avY" = ( +/obj/machinery/door/airlock/virology, +/obj/structure/spacevine, +/turf/open/floor/wood, +/area/eventmap/inside) +"avZ" = ( +/obj/structure/spacevine, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/clockwork/reebe, +/area/eventmap/inside) +"awa" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 8; + name = "Blood" + }, +/obj/effect/gibspawner/human, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/eventmap/inside) +"awb" = ( +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "floor2" + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"awc" = ( +/obj/structure/reagent_dispensers/cooking_oil, +/obj/structure/showcase/horrific_experiment{ + icon_state = "cover-on"; + layer = 4.5 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 6 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"awd" = ( +/turf/closed/wall/r_wall/rust, +/area/eventmap/inside) +"awe" = ( +/obj/structure/reagent_dispensers/cooking_oil, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 10 + }, +/obj/structure/showcase/horrific_experiment{ + icon_state = "cover-on"; + layer = 4.5 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"awf" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 4 + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "gibmid1" + }, +/obj/item/organ/brain, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, +/area/eventmap/inside) +"awg" = ( +/obj/structure/flora/junglebush{ + icon_state = "grassa4" + }, +/obj/vehicle/ridden/atv, +/obj/item/key, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"awh" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"awi" = ( +/obj/structure/fluff/bus/dense, +/obj/docking_port/mobile/arrivals, +/turf/open/floor/spooktime/cobble/sideW{ + icon_state = "cobble_side_n" + }, +/area/shuttle/arrival) +"awj" = ( +/obj/structure/fluff/bus/dense{ + icon_state = "hoodtop" + }, +/obj/docking_port/mobile/arrivals, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"awk" = ( +/turf/open/floor/spooktime/cobble/sideE, +/area/eventmap/outside) +"awl" = ( +/turf/open/floor/spooktime/cobble/sideW, +/area/eventmap/outside) +"awm" = ( +/obj/effect/landmark/observer_start, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"awn" = ( +/turf/open/floor/spooktime/cobble/cornerSE, +/area/eventmap/outside) +"awo" = ( +/turf/open/floor/spooktime/cobble/cornerSW, +/area/eventmap/outside) +"awp" = ( +/mob/living/carbon/true_devil, +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"awq" = ( +/obj/item/reagent_containers/food/condiment/mayonnaise, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"awr" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aws" = ( +/obj/structure/mineral_door/wood, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03{ + id = "C02" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"awt" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"awu" = ( +/obj/machinery/vending/hydroseeds, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"awv" = ( +/obj/structure/sign/departments/medbay/alt{ + pixel_y = 32 + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aww" = ( +/obj/structure/sign/directions/medical{ + dir = 4; + pixel_x = 32; + pixel_y = -24 + }, +/obj/structure/sign/directions/evac{ + dir = 4; + pixel_x = 32; + pixel_y = -32 + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"awx" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"awy" = ( +/obj/structure/table/wood, +/obj/item/paper_bin/bundlenatural, +/obj/item/pen, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"awz" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood/damturf/broken4, +/area/eventmap/inside) +"awA" = ( +/obj/structure/chair/stool/bar, +/obj/effect/landmark/start/assistant, +/turf/open/floor/wood, +/area/eventmap/inside) +"awB" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"awC" = ( +/obj/item/storage/box/drinkingglasses, +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"awD" = ( +/obj/machinery/droneDispenser, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"awE" = ( +/obj/effect/decal/cleanable/salt, +/turf/open/floor/sepia, +/area/eventmap/inside) +"awF" = ( +/obj/effect/decal/cleanable/blood/tracks, +/turf/open/floor/sepia, +/area/eventmap/inside) +"awG" = ( +/obj/structure/mineral_door/wood, +/turf/open/floor/plasteel/dark/side, +/area/eventmap/inside) +"awH" = ( +/turf/open/floor/plasteel/dark/side{ + dir = 6 + }, +/area/eventmap/inside) +"awI" = ( +/obj/effect/decal/cleanable/blood/tracks{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 4 + }, +/obj/effect/gibspawner/human, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"awJ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 8; + name = "Blood" + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"awK" = ( +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "gibup1" + }, +/obj/item/organ/stomach, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"awL" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 8; + name = "Blood" + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "coatblood" + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"awM" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/item/toy/toy_dagger, +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"awN" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/item/clothing/neck/devilwings, +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"awO" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/item/blood_beam, +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"awP" = ( +/obj/structure/fluff/drake_statue, +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"awQ" = ( +/obj/item/clothing/glasses/wraith_spectacles, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"awR" = ( +/obj/structure/mineral_door/wood, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"awS" = ( +/obj/effect/landmark/start/captain, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/structure/cable/white, +/turf/open/floor/wood, +/area/eventmap/inside) +"awT" = ( +/obj/structure/table, +/obj/machinery/microwave, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"awU" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/condiment/enzyme, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"awV" = ( +/obj/structure/table, +/obj/item/storage/box/ingredients/delights, +/obj/item/storage/box/ingredients/exotic, +/obj/item/storage/box/ingredients/italian, +/obj/item/storage/box/ingredients/grains, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"awW" = ( +/obj/structure/bed/dogbed/ian, +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/mob/living/simple_animal/pet/dog/corgi/Ian, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"awX" = ( +/obj/structure/sink{ + dir = 8; + pixel_x = -12 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"awY" = ( +/obj/machinery/vending/hydronutrients, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"awZ" = ( +/obj/structure/bodycontainer/morgue, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"axa" = ( +/obj/structure/showcase/horrific_experiment{ + icon_state = "pod_1" + }, +/turf/open/floor/sepia, +/area/eventmap/inside) +"axb" = ( +/obj/structure/showcase/machinery/implanter, +/turf/open/floor/sepia, +/area/eventmap/inside) +"axc" = ( +/obj/machinery/computer/cloning, +/obj/effect/decal/cleanable/oil, +/turf/open/floor/sepia, +/area/eventmap/inside) +"axd" = ( +/obj/structure/showcase/horrific_experiment, +/obj/effect/decal/cleanable/glass, +/turf/open/floor/sepia, +/area/eventmap/inside) +"axe" = ( +/obj/structure/showcase/machinery/oldpod, +/obj/effect/decal/cleanable/oil, +/turf/open/floor/sepia, +/area/eventmap/inside) +"axf" = ( +/obj/structure/mineral_door/wood, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/eventmap/inside) +"axg" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/plasteel/dark/side{ + dir = 5 + }, +/area/eventmap/inside) +"axh" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 4 + }, +/obj/effect/decal/cleanable/blood/innards, +/obj/effect/decal/cleanable/blood/splatter, +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/item/clothing/head/hooded/human_head, +/obj/item/reagent_containers/food/snacks/burger/human, +/obj/item/reagent_containers/food/snacks/burger/human, +/obj/item/reagent_containers/food/snacks/kebab/human, +/obj/item/reagent_containers/food/snacks/meat/cutlet/plain/human, +/obj/item/reagent_containers/food/snacks/meat/rawcutlet/plain/human, +/obj/item/reagent_containers/food/snacks/meat/slab/human, +/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/avian, +/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/fly, +/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/golem, +/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/insect, +/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard, +/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/plant, +/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/shadow, +/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton, +/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"axi" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 8; + name = "Blood" + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "gibbearcore" + }, +/obj/item/organ/tongue, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/eventmap/inside) +"axj" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 4 + }, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, +/area/eventmap/inside) +"axk" = ( +/obj/structure/healingfountain, +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"axl" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/item/tome, +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"axm" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/item/toy/spinningtoy{ + name = "Gate to hell" + }, +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"axn" = ( +/obj/structure/table/wood/fancy/blackred, +/obj/item/organ/heart/demon, +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"axo" = ( +/obj/structure/bed, +/obj/item/bedsheet/cult, +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"axp" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"axq" = ( +/obj/structure/toilet, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"axr" = ( +/obj/structure/closet/secure_closet/hydroponics, +/obj/machinery/camera/emp_proof{ + c_tag = "Containment - Fore Port"; + dir = 4; + network = list("singularity") + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"axs" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"axt" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"axu" = ( +/obj/machinery/camera/emp_proof{ + c_tag = "Library Game Room"; + dir = 1; + network = list("singularity") + }, +/turf/open/floor/wood/damturf/broken2, +/area/eventmap/inside) +"axv" = ( +/obj/structure/chair/wood{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"axw" = ( +/obj/machinery/computer/communications{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"axx" = ( +/obj/structure/chair/wood{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"axy" = ( +/obj/item/storage/box/matches, +/obj/structure/table/wood, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/fancy/candle_box, +/turf/open/floor/wood, +/area/eventmap/inside) +"axz" = ( +/obj/item/storage/box/ingredients/wildcard, +/obj/item/storage/box/ingredients/wildcard, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"axA" = ( +/obj/machinery/deepfryer, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"axB" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"axC" = ( +/obj/structure/table/wood, +/obj/machinery/recharger, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"axD" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/sepia, +/area/eventmap/inside) +"axE" = ( +/obj/effect/decal/cleanable/glass, +/mob/living/simple_animal/astral{ + desc = "...Is haunting Space Station Three."; + name = "Ghost" + }, +/turf/open/floor/sepia, +/area/eventmap/inside) +"axF" = ( +/obj/effect/decal/cleanable/plasma, +/turf/open/floor/sepia, +/area/eventmap/inside) +"axG" = ( +/obj/machinery/door/airlock/virology, +/turf/open/floor/clockwork/reebe, +/area/eventmap/inside) +"axH" = ( +/obj/structure/bed{ + desc = "A large structure used to break the femurs of traitors and treasonists."; + icon = 'icons/obj/femur_breaker.dmi'; + icon_state = "breaker_raised"; + name = "Femur breaker" + }, +/obj/effect/decal/cleanable/blood/gibs/limb{ + icon_state = "gibleg" + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "gib3" + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "floor2" + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 4 + }, +/obj/item/organ/appendix, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, +/area/eventmap/inside) +"axI" = ( +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "gib6" + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"axJ" = ( +/obj/structure/reagent_dispensers/cooking_oil, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 5 + }, +/obj/structure/showcase/horrific_experiment{ + icon_state = "cover-on"; + layer = 4.5 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"axK" = ( +/obj/structure/reagent_dispensers/cooking_oil, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 9 + }, +/obj/structure/showcase/horrific_experiment{ + icon_state = "cover-on"; + layer = 4.5 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"axL" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 4 + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "gibmid3" + }, +/obj/item/organ/eyes, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, +/area/eventmap/inside) +"axM" = ( +/obj/structure/table, +/obj/item/storage/box/ingredients/american, +/obj/item/storage/box/ingredients/fiesta, +/obj/item/storage/box/ingredients/grains, +/obj/item/storage/box/ingredients/fruity, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"axN" = ( +/obj/structure/filingcabinet, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"axO" = ( +/obj/machinery/smartfridge/food, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"axP" = ( +/obj/structure/filingcabinet/chestdrawer, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"axQ" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/closet/secure_closet/hydroponics, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"axR" = ( +/obj/machinery/computer/card{ + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"axS" = ( +/obj/machinery/door/airlock{ + name = "Hydroponics Backroom"; + req_access_txt = "35" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"axT" = ( +/obj/machinery/light/small, +/turf/open/floor/carpet, +/area/eventmap/inside) +"axU" = ( +/obj/structure/sign/departments/restroom{ + pixel_y = -32 + }, +/obj/machinery/camera/emp_proof{ + c_tag = "Containment - Particle Accelerator"; + dir = 1; + network = list("singularity") + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"axV" = ( +/obj/structure/sign/directions/science{ + pixel_x = 32; + pixel_y = -40 + }, +/obj/structure/sign/directions/evac{ + dir = 4; + pixel_x = 32; + pixel_y = -24 + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"axW" = ( +/obj/structure/falsewall/wood, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"axX" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"axY" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"axZ" = ( +/obj/item/reagent_containers/food/condiment/soysauce, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aya" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/chair/wood, +/obj/effect/landmark/start/head_of_personnel, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"ayb" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"ayc" = ( +/obj/item/storage/box/ingredients/sweets, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"ayd" = ( +/obj/item/storage/box/ingredients/vegetarian, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aye" = ( +/obj/effect/landmark/start/mime, +/turf/open/floor/wood, +/area/eventmap/inside) +"ayf" = ( +/obj/structure/table/wood/fancy/royalblack, +/turf/open/floor/wood, +/area/eventmap/inside) +"ayg" = ( +/obj/structure/table/wood/fancy/royalblack, +/obj/item/toy/dummy, +/turf/open/floor/wood, +/area/eventmap/inside) +"ayh" = ( +/obj/effect/decal/cleanable/chem_pile, +/turf/open/floor/sepia, +/area/eventmap/inside) +"ayi" = ( +/turf/open/floor/clockwork/reebe, +/area/eventmap/inside) +"ayj" = ( +/obj/item/ectoplasm, +/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie, +/turf/open/floor/clockwork/reebe, +/area/eventmap/inside) +"ayk" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 8; + name = "Blood" + }, +/obj/effect/decal/cleanable/plasma, +/turf/open/floor/plasteel/dark/side{ + dir = 4 + }, +/area/eventmap/inside) +"ayl" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/effect/decal/cleanable/blood/tracks, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aym" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"ayn" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 1 + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "splatter1" + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"ayo" = ( +/obj/structure/table/plasmaglass, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"ayp" = ( +/obj/structure/fluff/divine/convertaltar, +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"ayq" = ( +/obj/machinery/dna_scannernew, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ayr" = ( +/obj/machinery/computer/cloning, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ays" = ( +/obj/machinery/clonepod/experimental, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ayt" = ( +/obj/structure/fluff/empty_terrarium, +/obj/effect/decal/cleanable/oil, +/obj/effect/decal/cleanable/glass, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ayu" = ( +/obj/machinery/nuclearbomb/beer, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ayv" = ( +/obj/structure/table, +/obj/item/hand_labeler, +/obj/item/defibrillator/loaded, +/obj/item/extendohand/acme, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ayw" = ( +/obj/structure/table, +/obj/item/inducer/sci, +/obj/item/defibrillator/loaded, +/obj/item/defibrillator/loaded, +/obj/item/storage/box/beakers/bluespace, +/obj/item/storage/belt/medolier/full, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ayx" = ( +/obj/structure/table, +/obj/item/implanter/sad_trombone, +/obj/item/implanter/sad_trombone, +/obj/item/implanter/tracking/gps, +/obj/item/implanter/tracking/gps, +/obj/item/healthanalyzer/advanced, +/obj/item/pneumatic_cannon/pie, +/obj/item/storage/box/hug, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"ayy" = ( +/obj/item/organ/appendix{ + icon_state = "blacktumor"; + name = "Festering ooze" + }, +/turf/open/floor/clockwork/reebe, +/area/eventmap/inside) +"ayz" = ( +/obj/structure/cloth_pile, +/turf/open/floor/clockwork/reebe, +/area/eventmap/inside) +"ayA" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + mouse_opacity = 0 + }, +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"ayB" = ( +/obj/machinery/recharge_station, +/turf/open/floor/carpet/monochrome, +/area/eventmap/inside) +"ayC" = ( +/obj/item/clothing/suit/ghost_sheet, +/turf/open/floor/carpet/monochrome, +/area/eventmap/inside) +"ayD" = ( +/obj/structure/kitchenspike, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 10 + }, +/obj/effect/decal/remains/plasma, +/obj/effect/decal/cleanable/plasma, +/turf/open/floor/plasteel/dark/corner{ + dir = 4 + }, +/area/eventmap/inside) +"ayE" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111" + }, +/obj/machinery/iv_drip, +/obj/effect/decal/cleanable/plasma, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/eventmap/inside) +"ayF" = ( +/obj/structure/kitchenspike, +/obj/item/stack/sheet/animalhide/corgi, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111" + }, +/obj/effect/decal/cleanable/blood/tracks, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "itemblood" + }, +/obj/item/reagent_containers/food/snacks/meat/slab/corgi, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/eventmap/inside) +"ayG" = ( +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111" + }, +/obj/machinery/iv_drip, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/eventmap/inside) +"ayH" = ( +/obj/structure/kitchenspike, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111" + }, +/obj/structure/spider/stickyweb, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "u_psycopath" + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "gibdown1" + }, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/eventmap/inside) +"ayI" = ( +/obj/structure/kitchenspike, +/obj/item/stack/sheet/animalhide/lizard, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111" + }, +/obj/effect/decal/cleanable/blood/tracks, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "floor4-old" + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "splatter4" + }, +/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard, +/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/eventmap/inside) +"ayJ" = ( +/obj/structure/kitchenspike, +/obj/item/stack/sheet/animalhide/monkey, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111" + }, +/obj/effect/decal/cleanable/blood/tracks, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "gibmid3" + }, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/turf/open/floor/plasteel/dark/side{ + dir = 1 + }, +/area/eventmap/inside) +"ayK" = ( +/obj/structure/kitchenspike, +/obj/item/stack/sheet/animalhide/xeno, +/obj/effect/turf_decal/weather/snow/corner{ + color = "#991111"; + dir = 6 + }, +/obj/effect/decal/cleanable/blood/tracks, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "xgib2" + }, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "xgiblarvahead" + }, +/obj/item/reagent_containers/food/snacks/meat/slab/xeno, +/obj/item/reagent_containers/food/snacks/meat/slab/xeno, +/turf/open/floor/plasteel/dark/corner{ + dir = 1 + }, +/area/eventmap/inside) +"ayL" = ( +/atom/movable/screen/alert/status_effect/blooddrunk{ + desc = "BEWARE, I LIVE."; + name = "???" + }, +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"ayM" = ( +/atom/movable/screen/alert/status_effect/blooddrunk{ + desc = "WELCOME TO HELL, CURSED ONE."; + name = "???" + }, +/turf/open/indestructible/spooknecropolis, +/area/eventmap/inside) +"ayN" = ( +/turf/closed/indestructible/spookytime/matrixblocker, +/area/eventmap/mountain) +"ayO" = ( +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"ayP" = ( +/obj/structure/fluff/bus/passable{ + icon_state = "wheredahoodat" + }, +/turf/open/floor/spooktime/cobble/sideW{ + icon_state = "cobble_side_n" + }, +/area/eventmap/outside) +"ayQ" = ( +/turf/open/floor/spooktime/cobble/sideW{ + icon_state = "cobble_corner_ne" + }, +/area/eventmap/outside) +"ayR" = ( +/obj/effect/landmark/start/research_director, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"ayS" = ( +/obj/effect/landmark/start/head_of_personnel, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"ayT" = ( +/obj/effect/landmark/start/captain, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"ayU" = ( +/obj/machinery/door/airlock/command{ + name = "Head of Personnel's Quarters"; + req_access_txt = "57" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ayV" = ( +/obj/structure/spacevine, +/obj/structure/spacevine, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"ayW" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"ayX" = ( +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"ayY" = ( +/obj/structure/noticeboard{ + dir = 8; + pixel_x = 32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"ayZ" = ( +/obj/effect/landmark/start/librarian, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"aza" = ( +/obj/effect/landmark/start/scientist, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"azb" = ( +/obj/effect/landmark/start/assistant, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"azc" = ( +/obj/effect/landmark/start/assistant, +/turf/open/floor/spooktime/cobble/sideW, +/area/eventmap/outside) +"azd" = ( +/obj/effect/landmark/start/assistant, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"aze" = ( +/obj/item/reagent_containers/food/drinks/bottle/trappist, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"azf" = ( +/obj/effect/landmark/start/lawyer, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"azg" = ( +/obj/effect/landmark/start/roboticist, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"azh" = ( +/obj/structure/punching_bag, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"azi" = ( +/obj/effect/landmark/start, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"azj" = ( +/obj/effect/landmark/start, +/turf/open/floor/spooktime/cobble/cornerSW, +/area/eventmap/outside) +"azk" = ( +/obj/effect/landmark/start, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"azl" = ( +/obj/effect/landmark/start/assistant, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"azm" = ( +/obj/effect/landmark/start/mime, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"azn" = ( +/obj/effect/landmark/start/chief_engineer, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"azo" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/table/wood/fancy/royalblack, +/obj/item/camera/spooky, +/turf/open/floor/wood, +/area/eventmap/inside) +"azp" = ( +/obj/item/reagent_containers/food/snacks/kebab/rat/double, +/obj/structure/table/reinforced, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"azq" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/stairs/medium, +/area/eventmap/outside) +"azr" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/spooktime/cobble/sideN, +/area/eventmap/outside) +"azs" = ( +/obj/effect/landmark/start/atmospheric_technician, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"azt" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"azu" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/spooktime/cobble/sideW, +/area/eventmap/outside) +"azv" = ( +/obj/structure/flora/tree/jungle, +/obj/structure/flora/tree/jungle, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"azw" = ( +/obj/machinery/autolathe, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"azx" = ( +/obj/structure/chair/wood{ + dir = 4 + }, +/obj/effect/landmark/start/geneticist, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"azy" = ( +/obj/machinery/vending/coffee, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"azz" = ( +/obj/structure/dresser, +/obj/structure/curtain{ + color = "#B22222"; + pixel_x = 32 + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"azA" = ( +/obj/structure/sign/directions/evac{ + dir = 4; + pixel_x = 32; + pixel_y = -24 + }, +/turf/open/floor/spooktime/cobble/cornerSE, +/area/eventmap/outside) +"azB" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/indestructible/cobble, +/area/eventmap/outside) +"azC" = ( +/obj/effect/landmark/start/assistant, +/turf/open/floor/spooktime/cobble/sideE, +/area/eventmap/outside) +"azD" = ( +/obj/effect/landmark/start/shaft_miner, +/turf/open/floor/spooktime/cobble/sideE, +/area/eventmap/outside) +"azE" = ( +/obj/structure/flora/ausbushes/ywflowers, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"azF" = ( +/obj/effect/landmark/start/librarian, +/turf/open/floor/spooktime/cobble/sideW, +/area/eventmap/outside) +"azG" = ( +/obj/structure/chair/wood/wings, +/obj/effect/landmark/start/assistant, +/turf/open/floor/wood, +/area/eventmap/inside) +"azH" = ( +/obj/machinery/computer/scan_consolenew{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"azI" = ( +/obj/effect/landmark/start/scientist, +/turf/open/floor/spooktime/cobble/sideW, +/area/eventmap/outside) +"azJ" = ( +/obj/structure/closet/secure_closet/captains, +/turf/open/floor/wood, +/area/eventmap/inside) +"azK" = ( +/obj/structure/flora/grass/jungle/b, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"azL" = ( +/obj/machinery/vending/wardrobe/jani_wardrobe, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"azM" = ( +/obj/structure/closet/l3closet/janitor, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"azN" = ( +/obj/structure/closet/jcloset, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"azO" = ( +/obj/machinery/vending/medical{ + req_access = null + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"azP" = ( +/turf/open/floor/spooktime/beach/coasts/coastW, +/area/eventmap/outside) +"azQ" = ( +/turf/closed/indestructible/spookytime/matrixblocker, +/area/eventmap/mountaininside) +"azR" = ( +/obj/structure/reagent_dispensers/watertank/high, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"azS" = ( +/obj/effect/wisp, +/turf/open/floor/carpet/green, +/area/eventmap/inside) +"azT" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/gun/magic/staff/healing, +/obj/item/gun/magic/staff/healing, +/turf/open/floor/wood, +/area/eventmap/inside) +"azU" = ( +/turf/open/floor/spooktime/beach/coasts/coastNE, +/area/eventmap/outside) +"azV" = ( +/obj/structure/barricade/wooden/crude, +/obj/structure/spacevine, +/obj/effect/spawner/structure/window, +/turf/open/floor/wood, +/area/eventmap/inside) +"azW" = ( +/obj/item/flashlight/glowstick/orange, +/turf/open/floor/spooktime/beach, +/area/eventmap/outside) +"azX" = ( +/obj/structure/curtain{ + color = "#B22222"; + pixel_x = -32 + }, +/obj/structure/bookcase/random/adult, +/turf/open/floor/wood, +/area/eventmap/inside) +"azY" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"azZ" = ( +/obj/item/storage/pill_bottle/happy, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aAa" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"aAb" = ( +/turf/closed/mineral/ash_rock, +/area/eventmap/mountaininside) +"aAc" = ( +/obj/machinery/door/airlock/glass_large, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03{ + id = "C05" + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aAd" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aAe" = ( +/obj/structure/reagent_dispensers/beerkeg, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aAf" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aAg" = ( +/obj/structure/chair/comfy/black{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aAh" = ( +/obj/item/storage/fancy/cigarettes/cigpack_shadyjims, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aAi" = ( +/obj/structure/cable/pink{ + icon_state = "6-9" + }, +/turf/open/floor/plating, +/area/eventmap/mountain) +"aAj" = ( +/obj/structure/table/wood/fancy, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aAk" = ( +/obj/machinery/camera/emp_proof{ + c_tag = "Containment - Particle Accelerator"; + dir = 1; + network = list("singularity") + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aAl" = ( +/obj/machinery/chem_dispenser/drinks/beer/fullupgrade{ + dir = 1 + }, +/obj/structure/table, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aAm" = ( +/obj/machinery/chem_dispenser/drinks/fullupgrade{ + dir = 1 + }, +/obj/structure/table, +/obj/structure/cable/yellow, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aAn" = ( +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/milk, +/obj/item/reagent_containers/food/condiment/soymilk, +/obj/item/reagent_containers/food/condiment/soymilk, +/obj/item/reagent_containers/food/condiment/soymilk, +/obj/item/reagent_containers/food/condiment/soymilk, +/obj/item/reagent_containers/food/condiment/soymilk, +/obj/item/reagent_containers/food/condiment/soymilk, +/obj/item/reagent_containers/food/condiment/soymilk, +/obj/item/reagent_containers/food/condiment/soymilk, +/obj/item/reagent_containers/food/condiment/soymilk, +/obj/item/reagent_containers/food/condiment/soymilk, +/obj/item/reagent_containers/food/condiment/soymilk, +/obj/item/reagent_containers/food/condiment/soymilk, +/obj/item/reagent_containers/food/condiment/soymilk, +/obj/item/reagent_containers/food/condiment/soymilk, +/obj/item/storage/fancy/egg_box, +/obj/item/storage/fancy/egg_box, +/obj/item/storage/fancy/egg_box, +/obj/item/storage/fancy/egg_box, +/obj/item/storage/fancy/egg_box, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aAo" = ( +/obj/item/chair, +/turf/open/floor/plasteel/damturf/platdmg3, +/area/eventmap/mountaininside) +"aAp" = ( +/obj/item/stack/sheet/mineral/mythril, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"aAq" = ( +/obj/machinery/processor, +/obj/machinery/light/small, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aAs" = ( +/obj/structure/noticeboard{ + dir = 1; + pixel_y = -32 + }, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/item/reagent_containers/food/condiment/flour, +/obj/structure/closet/secure_closet/freezer/fridge, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aAt" = ( +/obj/item/reagent_containers/food/drinks/bottle/bottleofnothing, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aAu" = ( +/obj/structure/chair/comfy/beige{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aAv" = ( +/obj/structure/reagent_dispensers/watertank/high, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aAw" = ( +/obj/item/storage/pill_bottle/happiness, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aAx" = ( +/obj/machinery/light, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aAy" = ( +/obj/structure/fermenting_barrel, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aAz" = ( +/obj/structure/closet/crate/hydroponics, +/obj/structure/cable/yellow, +/obj/structure/sign/poster/contraband/kudzu{ + pixel_y = -32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aAA" = ( +/obj/item/reagent_containers/food/snacks/chips, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aAB" = ( +/obj/structure/beebox/unwrenched, +/turf/open/floor/wood, +/area/eventmap/inside) +"aAC" = ( +/obj/structure/table, +/obj/structure/cable/white{ + icon_state = "0-4" + }, +/obj/item/storage/box/bodybags{ + pixel_x = -3; + pixel_y = 5 + }, +/obj/item/storage/box/rxglasses, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aAD" = ( +/obj/structure/flora/ausbushes/leafybush, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aAE" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aAF" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aAG" = ( +/obj/item/lighter, +/turf/open/floor/carpet/purple, +/area/eventmap/mountaininside) +"aAH" = ( +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aAI" = ( +/obj/machinery/dna_scannernew, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aAJ" = ( +/turf/open/floor/spooktime/beach/coasts/watercoastNE, +/area/eventmap/outside) +"aAK" = ( +/obj/structure/falsewall/wood, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aAL" = ( +/obj/item/storage/pill_bottle/stimulant, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aAM" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/toilet{ + dir = 4 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aAN" = ( +/obj/structure/bonfire, +/turf/open/floor/engine, +/area/eventmap/mountain) +"aAO" = ( +/obj/machinery/door/airlock{ + name = "Toilet Unit" + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aAP" = ( +/obj/structure/sign/departments/showers{ + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aAQ" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aAR" = ( +/obj/structure/bed, +/obj/item/bedsheet/centcom, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aAS" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/toilet{ + dir = 8 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aAT" = ( +/obj/structure/table, +/obj/item/storage/box/mousetraps, +/obj/item/storage/box/lights/mixed{ + pixel_x = 4; + pixel_y = 4 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aAU" = ( +/obj/item/reagent_containers/food/snacks/fudgedice, +/turf/open/floor/wood{ + icon_state = "wood-broken4" + }, +/area/eventmap/inside) +"aAV" = ( +/obj/effect/landmark/start/janitor, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aAW" = ( +/obj/machinery/door/airlock{ + name = "Custodial Closet"; + req_access_txt = "26" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aAX" = ( +/obj/machinery/door/airlock/maintenance, +/turf/open/floor/wood, +/area/eventmap/inside) +"aAY" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/table/plasmaglass, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aAZ" = ( +/obj/machinery/vending/kink, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aBa" = ( +/obj/machinery/door/airlock/freezer, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aBb" = ( +/obj/structure/cable/pink{ + icon_state = "6-8" + }, +/turf/open/floor/plating, +/area/eventmap/mountain) +"aBc" = ( +/obj/machinery/door/airlock{ + name = "Bar Backroom"; + req_access_txt = "25" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBd" = ( +/obj/structure/table, +/obj/item/folder/white, +/obj/item/storage/pill_bottle/mannitol{ + pixel_x = -5; + pixel_y = 12 + }, +/obj/item/storage/pill_bottle/mutadone{ + pixel_x = -8; + pixel_y = 10 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aBe" = ( +/obj/effect/landmark/start/geneticist, +/obj/structure/chair/wood, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aBf" = ( +/obj/structure/fluff/bus/passable/seat/driver, +/obj/structure/chair/comfy/shuttle{ + dir = 4; + icon_state = "" + }, +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/obj/docking_port/mobile/arrivals, +/turf/open/floor/plasteel/dark{ + icon_state = "bus" + }, +/area/shuttle/arrival) +"aBh" = ( +/obj/structure/window/reinforced/spawner/north, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aBi" = ( +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aBj" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBk" = ( +/obj/structure/closet/secure_closet/injection, +/obj/effect/decal/cleanable/cobweb{ + icon_state = "cobweb2" + }, +/obj/effect/decal/cleanable/generic, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBl" = ( +/obj/structure/closet/secure_closet/personal, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBm" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBn" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBo" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aBp" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"aBq" = ( +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"aBr" = ( +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/obj/structure/dresser, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"aBs" = ( +/obj/machinery/vending/assist, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aBt" = ( +/obj/structure/closet/crate/bin, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aBu" = ( +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"aBv" = ( +/obj/structure/table, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aBw" = ( +/obj/structure/chair/comfy/brown{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aBx" = ( +/obj/machinery/shower{ + dir = 8 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aBy" = ( +/obj/item/storage/fancy/cigarettes/cigpack_midori, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aBz" = ( +/turf/open/floor/carpet/purple, +/area/eventmap/mountaininside) +"aBA" = ( +/obj/item/reagent_containers/pill/zoom, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aBB" = ( +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"aBC" = ( +/obj/structure/chair, +/obj/effect/landmark/start/assistant, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBD" = ( +/obj/item/flashlight/lantern, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aBE" = ( +/obj/structure/bed, +/obj/item/bedsheet/pirate, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBG" = ( +/obj/machinery/nanite_chamber, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aBH" = ( +/obj/item/storage/pill_bottle/penis_enlargement, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aBI" = ( +/obj/structure/chair, +/obj/effect/landmark/start/lawyer, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBJ" = ( +/obj/structure/chair, +/obj/effect/landmark/start/clown, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBK" = ( +/obj/structure/curtain{ + color = "#B22222"; + pixel_y = -32 + }, +/turf/open/floor/wood/damturf/broken3, +/area/eventmap/inside) +"aBL" = ( +/turf/open/floor/plasteel/damturf/damage1, +/area/eventmap/mountain) +"aBM" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBN" = ( +/turf/open/floor/spooktime/beach/coasts/watercoastW, +/area/eventmap/outside) +"aBO" = ( +/obj/structure/table/wood, +/obj/machinery/computer/security/wooden_tv{ + pixel_y = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBP" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/snacks/donut/chaos, +/obj/item/reagent_containers/food/snacks/donut/jelly{ + pixel_x = 4; + pixel_y = 2 + }, +/obj/item/reagent_containers/food/snacks/donut{ + pixel_x = -3; + pixel_y = 5 + }, +/obj/item/reagent_containers/food/snacks/donut{ + pixel_x = -2; + pixel_y = -4 + }, +/obj/item/reagent_containers/food/snacks/donut{ + pixel_x = -4 + }, +/obj/item/reagent_containers/food/snacks/donut{ + pixel_x = 5; + pixel_y = -1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBQ" = ( +/obj/structure/table, +/obj/item/watertank/janitor, +/obj/item/mop/advanced, +/obj/item/grenade/chem_grenade/cleaner, +/obj/item/grenade/chem_grenade/cleaner, +/obj/item/grenade/chem_grenade/cleaner, +/obj/item/grenade/chem_grenade/cleaner, +/obj/item/grenade/chem_grenade/cleaner, +/obj/item/grenade/chem_grenade/cleaner, +/obj/item/grenade/chem_grenade/cleaner, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aBR" = ( +/obj/structure/cable/pink{ + icon_state = "2-5" + }, +/obj/structure/cable/pink{ + icon_state = "2-9" + }, +/turf/open/floor/plating, +/area/eventmap/mountain) +"aBS" = ( +/obj/vehicle/ridden/janicart/upgraded, +/obj/item/key/janitor, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aBT" = ( +/obj/structure/bed, +/obj/item/bedsheet/pirate, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aBU" = ( +/obj/machinery/door/airlock/wood/dorms/dorm07, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBV" = ( +/obj/structure/janitorialcart, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aBW" = ( +/obj/item/lighter/greyscale, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aBX" = ( +/obj/structure/chair/comfy/black{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBY" = ( +/obj/structure/falsewall/wood, +/turf/open/floor/wood, +/area/eventmap/inside) +"aBZ" = ( +/obj/structure/closet/secure_closet/freezer/meat, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aCa" = ( +/obj/structure/noticeboard{ + pixel_y = 32 + }, +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/eventmap/inside) +"aCb" = ( +/obj/machinery/camera/emp_proof, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aCc" = ( +/obj/item/flashlight/lantern, +/obj/structure/curtain{ + color = "#B22222"; + pixel_x = -32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aCd" = ( +/obj/structure/closet/secure_closet/security, +/obj/item/clothing/head/beret/sec/navyofficer, +/obj/item/clothing/under/rank/security/officer/formal, +/turf/open/floor/wood, +/area/eventmap/inside) +"aCe" = ( +/obj/machinery/shower{ + desc = "Despite their age, they seem clean and capable of providing hot water just as well as their modern counterparts. Hopefully Nanotrasen cleaned the water pipes this well..."; + pixel_y = 24 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aCf" = ( +/obj/structure/plasticflaps/opaque, +/obj/effect/turf_decal/bot, +/turf/open/floor/plating, +/area/eventmap/inside) +"aCg" = ( +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/umbrella, +/obj/item/pickaxe/mini, +/obj/item/shovel, +/obj/item/hatchet, +/obj/item/storage/box/matches, +/obj/item/storage/fancy/candle_box, +/turf/open/floor/wood, +/area/eventmap/inside) +"aCh" = ( +/obj/structure/toilet, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aCi" = ( +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aCj" = ( +/obj/structure/closet/secure_closet/freezer/meat, +/obj/item/reagent_containers/food/snacks/carpmeat, +/obj/item/reagent_containers/food/snacks/carpmeat, +/obj/item/reagent_containers/food/snacks/meat/slab/gorilla, +/obj/item/reagent_containers/food/snacks/meat/slab/gorilla, +/obj/item/reagent_containers/food/snacks/meat/slab/gondola, +/obj/item/reagent_containers/food/snacks/meat/slab/gondola, +/obj/item/reagent_containers/food/snacks/meat/slab/spider, +/obj/item/reagent_containers/food/snacks/meat/slab/spider, +/obj/item/reagent_containers/food/snacks/meat/slab/xeno, +/obj/item/reagent_containers/food/snacks/meat/slab/xeno, +/obj/item/reagent_containers/food/snacks/meat/slab/corgi, +/obj/item/reagent_containers/food/snacks/meat/slab/corgi, +/obj/item/reagent_containers/food/snacks/meat/slab/bear, +/obj/item/reagent_containers/food/snacks/meat/slab/bear, +/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/pug, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aCk" = ( +/obj/item/storage/fancy/egg_box, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aCl" = ( +/obj/item/scythe, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aCm" = ( +/obj/structure/chair/comfy/beige, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aCn" = ( +/obj/structure/sink/kitchen{ + pixel_y = 28 + }, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aCo" = ( +/obj/machinery/smartfridge/drinks, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"aCp" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aCq" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/gear_painter, +/turf/open/floor/wood, +/area/eventmap/inside) +"aCr" = ( +/obj/structure/closet/secure_closet/bar, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aCs" = ( +/turf/open/floor/spooktime/beach/coasts/coastSE, +/area/eventmap/outside) +"aCt" = ( +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountain) +"aCu" = ( +/obj/structure/closet/crate, +/obj/item/clothing/mask/horsehead, +/obj/item/clothing/mask/horsehead, +/obj/item/clothing/mask/bandana/red, +/obj/item/clothing/mask/rat/bat, +/obj/item/clothing/mask/rat/bear, +/obj/item/clothing/mask/rat/bee, +/obj/item/clothing/mask/rat/fox, +/obj/item/clothing/mask/rat/jackal, +/obj/item/clothing/mask/rat/raven, +/obj/item/clothing/mask/rat/tribal, +/obj/item/clothing/mask/frog, +/obj/item/clothing/mask/scarecrow, +/obj/item/clothing/mask/gondola, +/obj/item/clothing/head/rice_hat, +/obj/item/clothing/head/pharaoh, +/obj/item/clothing/head/hunter, +/turf/open/floor/wood, +/area/eventmap/inside) +"aCv" = ( +/turf/open/floor/wood/damturf/broken3, +/area/eventmap/inside) +"aCw" = ( +/obj/structure/reagent_dispensers/beerkeg, +/turf/open/floor/wood, +/area/eventmap/inside) +"aCx" = ( +/obj/structure/toilet{ + dir = 4 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aCy" = ( +/obj/structure/table, +/obj/item/storage/box/drinkingglasses, +/obj/item/storage/box/drinkingglasses, +/obj/item/storage/box/beakers, +/obj/item/storage/box/donkpockets, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aCz" = ( +/obj/structure/reagent_dispensers/keg/mead, +/turf/open/floor/wood, +/area/eventmap/inside) +"aCA" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/bottle/wine, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aCB" = ( +/obj/structure/reagent_dispensers/keg/milk, +/turf/open/floor/wood, +/area/eventmap/inside) +"aCC" = ( +/obj/structure/table, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aCD" = ( +/obj/machinery/computer/scan_consolenew{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aCE" = ( +/turf/open/floor/wood/damturf/broken2, +/area/eventmap/mountaininside) +"aCF" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/vending/kink, +/turf/open/floor/wood/damturf/broken5, +/area/eventmap/mountaininside) +"aCG" = ( +/obj/structure/closet/toolcloset, +/obj/item/storage/belt/durathread, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aCH" = ( +/obj/structure/window/reinforced/spawner/west, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aCI" = ( +/turf/open/indestructible/cobble, +/area/eventmap/outside) +"aCJ" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"aCK" = ( +/obj/structure/bed, +/obj/effect/landmark/start/head_of_security, +/obj/item/bedsheet/hos, +/obj/structure/sign/poster/contraband/bountyhunters{ + pixel_x = 32 + }, +/turf/open/floor/carpet/red, +/area/eventmap/inside) +"aCL" = ( +/obj/structure/sink{ + dir = 8; + pixel_x = -12 + }, +/obj/structure/mirror{ + pixel_x = -28 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aCM" = ( +/obj/structure/barricade/security, +/turf/open/indestructible/airblock, +/area/eventmap/mountaininside) +"aCN" = ( +/obj/item/storage/fancy/cigarettes/cigpack_cannabis, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aCO" = ( +/obj/structure/healingfountain, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aCP" = ( +/obj/structure/table, +/obj/structure/bedsheetbin/towel, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aCR" = ( +/obj/effect/landmark/start/head_of_security, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aCS" = ( +/obj/machinery/shower{ + dir = 8 + }, +/obj/item/soap, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aCT" = ( +/obj/structure/chair{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aCU" = ( +/obj/structure/flora/ausbushes/leafybush, +/obj/structure/flora/tree/spookytime, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aCV" = ( +/obj/structure/fluff/bus/dense{ + icon_state = "hoodbottom" + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aCW" = ( +/obj/structure/fluff/bus/dense{ + icon_state = "frontwallbottomrear" + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aCX" = ( +/obj/structure/fluff/bus/dense{ + icon_state = "frontwallbottom" + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aCY" = ( +/obj/structure/fluff/bus/dense{ + icon_state = "reartire" + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aCZ" = ( +/obj/structure/fluff/bus/passable{ + icon_state = "bottomdoor"; + layer = 3 + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aDa" = ( +/obj/structure/fluff/bus/dense{ + icon_state = "fronttire" + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aDb" = ( +/obj/effect/landmark/start/detective, +/turf/open/floor/wood, +/area/eventmap/inside) +"aDc" = ( +/obj/structure/table/wood/bar, +/obj/machinery/recharger, +/turf/open/floor/wood, +/area/eventmap/inside) +"aDd" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/obj/effect/landmark/start/depsec/supply, +/turf/open/floor/wood, +/area/eventmap/inside) +"aDe" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Security Office"; + req_access_txt = "63" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aDf" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aDg" = ( +/obj/machinery/recharge_station, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aDh" = ( +/obj/item/pizzabox/margherita, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aDi" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Kitchen Maintenance"; + req_access_txt = "28" + }, +/turf/open/floor/plating, +/area/eventmap/inside) +"aDj" = ( +/obj/item/storage/fancy/cigarettes/dromedaryco, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aDk" = ( +/turf/open/floor/spooktime/beach, +/area/eventmap/mountain) +"aDl" = ( +/obj/item/reagent_containers/food/snacks/meat/slab/spider, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aDm" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/structure/filingcabinet/filingcabinet, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aDn" = ( +/obj/item/reagent_containers/food/snacks/meat/slab/pug, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aDo" = ( +/obj/effect/landmark/start/cook, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aDp" = ( +/obj/structure/trap/ctf/nomech, +/turf/open/floor/spooktime/cobble/cornerSW, +/area/eventmap/outside) +"aDq" = ( +/obj/item/storage/fancy/egg_box, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aDr" = ( +/obj/machinery/door/airlock/freezer, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aDs" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood/damturf/broken1, +/area/eventmap/inside) +"aDt" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/effect/landmark/start/captain, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aDu" = ( +/obj/structure/fluff/bus/passable/seat, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/chair/comfy/shuttle{ + dir = 4; + icon_state = "" + }, +/obj/effect/landmark/start, +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/obj/docking_port/mobile/arrivals, +/turf/open/floor/plasteel/dark{ + icon_state = "bus" + }, +/area/shuttle/arrival) +"aDv" = ( +/obj/structure/fluff/bus/passable/seat, +/obj/structure/chair/comfy/shuttle{ + dir = 4; + icon_state = "" + }, +/obj/effect/landmark/start, +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/obj/docking_port/mobile/arrivals, +/turf/open/floor/plasteel/dark{ + icon_state = "bus" + }, +/area/shuttle/arrival) +"aDw" = ( +/obj/machinery/door/airlock{ + name = "Bar Backroom"; + req_access_txt = "25" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aDx" = ( +/obj/structure/fluff/bus/passable/seat{ + pixel_y = 15 + }, +/obj/structure/chair/comfy/shuttle{ + dir = 4; + icon_state = "" + }, +/obj/effect/landmark/start, +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/obj/docking_port/mobile/arrivals, +/turf/open/floor/plasteel/dark{ + icon_state = "bus" + }, +/area/shuttle/arrival) +"aDy" = ( +/obj/structure/mineral_door/wood, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03{ + id = "C03" + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aDz" = ( +/obj/structure/sink/puddle, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aDA" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood/damturf/broken3, +/area/eventmap/inside) +"aDB" = ( +/obj/item/reagent_containers/food/drinks/bottle/tequila, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aDC" = ( +/obj/item/reagent_containers/food/snacks/spiderlollipop, +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/plasteel/damturf/scorched2, +/area/eventmap/mountaininside) +"aDD" = ( +/obj/item/storage/pill_bottle/stimulant, +/turf/open/floor/plasteel/damturf/platdmg1, +/area/eventmap/mountaininside) +"aDE" = ( +/obj/item/reagent_containers/pill/breast_enlargement, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aDF" = ( +/obj/machinery/door/airlock{ + name = "Bar Storage"; + req_access_txt = "25" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aDG" = ( +/obj/structure/closet/cabinet, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aDH" = ( +/obj/structure/spacevine, +/obj/structure/spacevine, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aDI" = ( +/turf/closed/wall/r_wall, +/area/eventmap/inside) +"aDJ" = ( +/obj/structure/chair/e_chair, +/obj/effect/decal/cleanable/ash/large, +/obj/effect/decal/cleanable/generic, +/obj/effect/decal/cleanable/glass{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aDK" = ( +/obj/effect/landmark/start/head_of_security, +/turf/open/floor/wood, +/area/eventmap/inside) +"aDL" = ( +/obj/item/stamp/hos, +/obj/structure/table/wood/fancy, +/turf/open/floor/wood, +/area/eventmap/inside) +"aDM" = ( +/obj/effect/spawner/structure/window/reinforced/tinted, +/obj/structure/cable/white, +/turf/open/floor/wood, +/area/eventmap/inside) +"aDN" = ( +/obj/machinery/vending/donksofttoyvendor, +/turf/open/floor/spooktime/cobble/cornerNE, +/area/eventmap/outside) +"aDO" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/cable/white, +/obj/effect/landmark/start/head_of_personnel, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aDP" = ( +/obj/structure/table, +/obj/structure/window/reinforced/tinted, +/obj/item/reagent_containers/rag/towel, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aDQ" = ( +/obj/machinery/shower{ + dir = 8 + }, +/obj/structure/window/reinforced/tinted, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aDR" = ( +/obj/structure/chair/wood, +/obj/effect/landmark/start/security_officer, +/turf/open/floor/wood, +/area/eventmap/inside) +"aDS" = ( +/obj/structure/table/wood, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/recharger, +/turf/open/floor/wood, +/area/eventmap/inside) +"aDT" = ( +/obj/machinery/door/airlock/maintenance, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aDU" = ( +/obj/machinery/door/airlock/wood/dorms/dorm16, +/turf/open/floor/wood, +/area/eventmap/inside) +"aDV" = ( +/obj/machinery/icecream_vat, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aDW" = ( +/obj/structure/closet/secure_closet/freezer/meat, +/obj/item/reagent_containers/food/snacks/carpmeat, +/obj/item/reagent_containers/food/snacks/carpmeat, +/obj/item/reagent_containers/food/snacks/meat/slab/gorilla, +/obj/item/reagent_containers/food/snacks/meat/slab/gorilla, +/obj/item/reagent_containers/food/snacks/meat/slab/gondola, +/obj/item/reagent_containers/food/snacks/meat/slab/gondola, +/obj/item/reagent_containers/food/snacks/meat/slab/spider, +/obj/item/reagent_containers/food/snacks/meat/slab/spider, +/obj/item/reagent_containers/food/snacks/meat/slab/xeno, +/obj/item/reagent_containers/food/snacks/meat/slab/xeno, +/obj/item/reagent_containers/food/snacks/meat/slab/corgi, +/obj/item/reagent_containers/food/snacks/meat/slab/corgi, +/obj/item/reagent_containers/food/snacks/meat/slab/bear, +/obj/item/reagent_containers/food/snacks/meat/slab/bear, +/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/obj/item/reagent_containers/food/snacks/meat/slab/monkey, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aDX" = ( +/obj/machinery/food_cart, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aDY" = ( +/obj/machinery/door/airlock/wood/dorms/dorm19, +/turf/open/floor/wood, +/area/eventmap/inside) +"aDZ" = ( +/obj/item/coin/diamond, +/obj/item/stack/sheet/mineral/silver, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"aEa" = ( +/obj/machinery/vending/wardrobe/chef_wardrobe, +/obj/machinery/camera/emp_proof{ + c_tag = "Containment - Fore Starboard"; + dir = 8; + network = list("singularity") + }, +/obj/structure/cable/yellow, +/turf/open/floor/plasteel/cafeteria, +/area/eventmap/inside) +"aEb" = ( +/obj/item/lighter, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aEc" = ( +/obj/structure/cable/yellow, +/turf/open/floor/wood, +/area/eventmap/inside) +"aEd" = ( +/obj/structure/reagent_dispensers/keg/gargle, +/turf/open/floor/wood, +/area/eventmap/inside) +"aEe" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/mineral/titanium/white{ + name = "padded floor" + }, +/area/eventmap/inside) +"aEf" = ( +/turf/open/floor/mineral/titanium/white{ + name = "padded floor" + }, +/area/eventmap/inside) +"aEg" = ( +/obj/effect/landmark/start/janitor, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aEh" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/mineral/titanium/white{ + name = "padded floor" + }, +/area/eventmap/inside) +"aEi" = ( +/obj/item/bodypart/head, +/obj/item/clothing/head/collectable/kitty, +/obj/item/clothing/mask/scarecrow, +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "gibbearcore" + }, +/obj/item/stamp/ce, +/turf/open/floor/mineral/titanium/white{ + name = "padded floor" + }, +/area/eventmap/inside) +"aEj" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/turf/open/floor/wood, +/area/eventmap/inside) +"aEk" = ( +/obj/structure/sign/plaques/deempisi{ + pixel_y = 32 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aEl" = ( +/obj/structure/bed, +/obj/item/bedsheet/random, +/obj/machinery/button/door/dorms/patient1, +/turf/open/floor/wood, +/area/eventmap/inside) +"aEm" = ( +/obj/effect/decal/cleanable/shreds, +/turf/open/floor/wood, +/area/eventmap/inside) +"aEn" = ( +/obj/structure/closet/secure_closet/hos, +/obj/item/clothing/under/rank/security/head_of_security/formal, +/turf/open/floor/wood, +/area/eventmap/inside) +"aEo" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aEp" = ( +/obj/structure/sign/poster/official/space_cops{ + pixel_y = -32 + }, +/turf/open/floor/wood/damturf/broken1, +/area/eventmap/inside) +"aEq" = ( +/obj/structure/curtain{ + color = "#B22222" + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aEr" = ( +/obj/machinery/button/door/dorms/luxury3{ + id = "C03"; + pixel_y = -24 + }, +/turf/open/floor/wood/damturf/broken1, +/area/eventmap/mountaininside) +"aEs" = ( +/obj/machinery/light, +/turf/open/floor/wood, +/area/eventmap/inside) +"aEt" = ( +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aEu" = ( +/obj/structure/table/wood/bar, +/obj/machinery/computer/security/wooden_tv{ + pixel_y = 8 + }, +/obj/structure/window/reinforced/spawner, +/turf/open/floor/wood, +/area/eventmap/inside) +"aEv" = ( +/obj/structure/table/wood/bar, +/obj/machinery/computer/secure_data/laptop{ + dir = 1; + pixel_y = 6 + }, +/obj/structure/window/reinforced/spawner, +/turf/open/floor/wood, +/area/eventmap/inside) +"aEw" = ( +/obj/structure/cable/pink{ + icon_state = "0-5" + }, +/obj/structure/cable/pink{ + icon_state = "0-9" + }, +/turf/open/floor/plating, +/area/eventmap/mountain) +"aEx" = ( +/obj/structure/toilet{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aEy" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aEz" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/spooktime/beach, +/area/eventmap/outside) +"aEA" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/structure/table/wood, +/obj/structure/bedsheetbin/towel, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aEB" = ( +/obj/structure/sign/poster/official/ian{ + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aEC" = ( +/obj/machinery/button/door/dorms/luxury3{ + id = "C09"; + pixel_x = -8 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aED" = ( +/turf/closed/wall/mineral/wood, +/area/eventmap/mountaininside) +"aEE" = ( +/obj/structure/closet/secure_closet/freezer/meat, +/obj/structure/window/reinforced/spawner/north, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"aEF" = ( +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aEG" = ( +/turf/open/floor/carpet/royalblack, +/area/eventmap/mountain) +"aEH" = ( +/obj/structure/closet/secure_closet/freezer/kitchen{ + req_access = null + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aEI" = ( +/obj/structure/window/reinforced/spawner/north, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"aEJ" = ( +/obj/item/flashlight/glowstick/cyan, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aEK" = ( +/obj/structure/noticeboard/hop{ + pixel_x = 32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aEL" = ( +/obj/item/flashlight/glowstick/orange, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aEM" = ( +/obj/structure/kitchenspike, +/obj/structure/window/reinforced/spawner/north, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"aEN" = ( +/obj/item/reagent_containers/food/drinks/bottle/whiskey, +/turf/open/floor/wood{ + icon_state = "wood-broken5" + }, +/area/eventmap/inside) +"aEP" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aEQ" = ( +/obj/machinery/door/airlock{ + name = "Bar Backroom"; + req_access_txt = "25" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aER" = ( +/obj/structure/chair/sofa/right, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aES" = ( +/obj/structure/table/optable, +/obj/item/reagent_containers/glass/bowl, +/obj/item/toy/fluff/tennis_poly/red, +/obj/item/clothing/neck/petcollar, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aET" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/mineral/titanium/white{ + name = "padded floor" + }, +/area/eventmap/inside) +"aEU" = ( +/obj/structure/blob/normal{ + color = "#777777"; + name = "peculiar goo" + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aEV" = ( +/obj/structure/table/plasmaglass, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + mouse_opacity = 0 + }, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aEW" = ( +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "floor4-old" + }, +/turf/open/floor/mineral/titanium/white{ + name = "padded floor" + }, +/area/eventmap/inside) +"aEX" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/damturf/scorched1, +/area/eventmap/mountaininside) +"aEY" = ( +/obj/item/organ/heart, +/obj/effect/decal/cleanable/blood/gibs/old, +/turf/open/floor/mineral/titanium/white{ + name = "padded floor" + }, +/area/eventmap/inside) +"aEZ" = ( +/obj/item/storage/pill_bottle/breast_enlargement, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aFa" = ( +/obj/item/flashlight/glowstick/cyan, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFb" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/structure/spacevine, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aFc" = ( +/obj/structure/flora/tree/spookytimexl, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aFd" = ( +/turf/closed/wall/r_wall/rust, +/area/cargo/miningstorage) +"aFe" = ( +/obj/machinery/door/airlock/wood/dorms/patient1, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFf" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood/damturf/broken3, +/area/eventmap/inside) +"aFg" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Security Office"; + req_access_txt = "63" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFh" = ( +/obj/structure/mineral_door/wood, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03{ + id = "C04" + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aFi" = ( +/turf/open/floor/spooktime/beach/coasts/innerW, +/area/eventmap/outside) +"aFj" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Security Desk"; + req_access_txt = "63" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFk" = ( +/obj/structure/mirror{ + icon_state = "mirror_broke"; + pixel_x = 28 + }, +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aFl" = ( +/obj/structure/closet/secure_closet/freezer/cream_pie, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"aFm" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"aFn" = ( +/obj/item/reagent_containers/food/snacks/sausage, +/obj/structure/table/reinforced, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aFo" = ( +/obj/structure/kitchenspike, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"aFp" = ( +/obj/structure/closet/chefcloset, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFq" = ( +/obj/item/autosurgeon/penis, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aFr" = ( +/obj/machinery/rnd/production/circuit_imprinter, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aFs" = ( +/obj/item/storage/fancy/cigarettes, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFt" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aFu" = ( +/obj/machinery/vending/dinnerware, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFv" = ( +/obj/machinery/chem_dispenser/drinks/beer/fullupgrade{ + dir = 4 + }, +/obj/structure/table/wood/bar, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aFw" = ( +/turf/closed/wall/rust, +/area/eventmap/mountaininside) +"aFx" = ( +/obj/machinery/camera/emp_proof, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aFy" = ( +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/obj/structure/fireplace{ + dir = 4; + pixel_x = -8 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aFz" = ( +/obj/machinery/door/airlock{ + name = "Bar Staff Entrance"; + req_access_txt = "25" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aFA" = ( +/obj/item/restraints/handcuffs, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aFB" = ( +/obj/machinery/door/airlock/wood/glass, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFC" = ( +/obj/structure/closet/secure_closet/hop, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aFD" = ( +/obj/machinery/door/airlock/wood/glass, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFE" = ( +/turf/open/floor/spooktime/beach/coasts/coastN, +/area/eventmap/outside) +"aFF" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFG" = ( +/obj/machinery/door/airlock/wood/glass, +/obj/effect/decal/cleanable/blood/old, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFH" = ( +/obj/structure/curtain{ + color = "#B22222" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03{ + id = "C01" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFI" = ( +/obj/structure/closet/secure_closet/warden, +/obj/item/gun/ballistic/shotgun/automatic/combat/compact, +/obj/item/gun/energy/pumpaction/defender, +/obj/item/clothing/under/rank/security/warden/formal, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aFJ" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/item/storage/fancy/cigarettes/cigpack_cannabis, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aFK" = ( +/obj/item/reagent_containers/food/snacks/pastatomato, +/obj/structure/table/reinforced, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aFL" = ( +/obj/effect/decal/cleanable/cobweb, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/machinery/light/small/broken{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFM" = ( +/obj/item/reagent_containers/food/snacks/toastedsandwich, +/obj/structure/table/reinforced, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aFN" = ( +/obj/structure/chair/wood/normal, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFO" = ( +/obj/effect/decal/cleanable/ash/large, +/obj/effect/decal/cleanable/generic, +/obj/effect/decal/cleanable/glass{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFP" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/button/door/dorms/luxury3{ + id = "C04" + }, +/turf/open/floor/wood/damturf/broken5, +/area/eventmap/mountaininside) +"aFQ" = ( +/obj/machinery/computer/nanite_chamber_control{ + dir = 1 + }, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aFR" = ( +/obj/structure/sink/kitchen{ + pixel_y = 30 + }, +/turf/open/floor/sepia, +/area/eventmap/mountaininside) +"aFS" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/effect/decal/cleanable/ash/crematorium, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFT" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aFU" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aFV" = ( +/obj/item/reagent_containers/food/drinks/bottle/whiskey, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aFW" = ( +/obj/machinery/computer/rdconsole/robotics, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aFX" = ( +/obj/effect/decal/cleanable/blood/splatter{ + icon_state = "splatter1" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aFY" = ( +/obj/item/storage/pill_bottle/breast_enlargement, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aFZ" = ( +/obj/structure/mirror{ + pixel_x = 28 + }, +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aGa" = ( +/obj/structure/reagent_dispensers/cooking_oil, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"aGb" = ( +/obj/structure/sign/poster/official/love_ian{ + pixel_y = -32 + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aGc" = ( +/obj/structure/bed, +/obj/machinery/button/door/dorms/dorm16, +/obj/item/bedsheet/hop, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aGd" = ( +/obj/item/reagent_containers/food/drinks/bottle/lizardwine, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aGe" = ( +/obj/structure/closet/cabinet, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aGf" = ( +/obj/machinery/button/door/dorms/dorm19, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aGg" = ( +/obj/structure/flora/rock/pile/icy, +/obj/structure/flora/tree/spookytime, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aGh" = ( +/turf/closed/indestructible/riveted/boss, +/area/eventmap/mountaininside) +"aGi" = ( +/obj/item/storage/box/matches, +/obj/item/shovel, +/obj/item/flashlight/flare/torch, +/obj/item/hatchet, +/obj/item/pickaxe/mini, +/obj/structure/rack, +/obj/item/umbrella, +/turf/open/floor/wood, +/area/eventmap/inside) +"aGj" = ( +/obj/item/storage/box/matches, +/obj/machinery/light/small{ + dir = 8 + }, +/obj/item/shovel, +/obj/item/flashlight/flare/torch, +/obj/item/hatchet, +/obj/item/pickaxe/mini, +/obj/structure/rack, +/obj/item/umbrella, +/turf/open/floor/wood, +/area/eventmap/inside) +"aGk" = ( +/obj/machinery/door/airlock/survival_pod, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aGl" = ( +/obj/structure/closet/crate/freezer/blood, +/obj/machinery/light/small, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"aGm" = ( +/obj/machinery/gibber/autogibber, +/turf/open/floor/plasteel/freezer, +/area/eventmap/inside) +"aGn" = ( +/obj/structure/closet/gimmick/tacticool, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aGo" = ( +/obj/structure/mineral_door/wood, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aGp" = ( +/obj/machinery/vending/wardrobe/bar_wardrobe, +/turf/open/floor/wood, +/area/eventmap/inside) +"aGq" = ( +/obj/structure/bed, +/obj/item/bedsheet/pirate, +/turf/open/floor/wood/damturf/broken6, +/area/eventmap/mountaininside) +"aGr" = ( +/obj/structure/flora/rock/pile/icy, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aGs" = ( +/obj/machinery/chem_dispenser/drinks/fullupgrade{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/table/wood/bar, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aGt" = ( +/obj/effect/landmark/start/bartender, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aGu" = ( +/obj/machinery/computer/mech_bay_power_console, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aGv" = ( +/obj/structure/table, +/obj/item/storage/toolbox/mechanical, +/obj/item/stack/cable_coil, +/obj/item/storage/box/lights/mixed, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aGw" = ( +/obj/structure/noticeboard{ + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aGx" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/drinks/bottle/whiskey, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aGy" = ( +/obj/item/stack/sheet/mineral/diamond, +/obj/item/stack/sheet/mineral/plasma, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"aGz" = ( +/turf/open/floor/plasteel/damturf/scorched2, +/area/eventmap/mountaininside) +"aGA" = ( +/obj/structure/noticeboard{ + pixel_y = 32 + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"aGB" = ( +/obj/structure/bed, +/obj/item/bedsheet/hop, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aGD" = ( +/obj/structure/flora/tree/spookytime, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aGE" = ( +/obj/structure/destructible/cult/tome, +/turf/open/floor/wood, +/area/eventmap/inside) +"aGF" = ( +/obj/effect/decal/cleanable/blood/tracks, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"aGG" = ( +/turf/closed/wall/rust, +/area/cargo/miningstorage) +"aGH" = ( +/obj/structure/bed, +/obj/item/bedsheet/random, +/obj/machinery/button/door/dorms/patient2, +/turf/open/floor/wood, +/area/eventmap/inside) +"aGI" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/structure/table/wood/fancy, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aGJ" = ( +/obj/item/chair, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aGK" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/caution{ + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aGL" = ( +/obj/item/chair/wood, +/turf/open/floor/plasteel/damturf/scorched, +/area/eventmap/mountaininside) +"aGM" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"aGN" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aGO" = ( +/obj/machinery/door/airlock/security{ + aiControlDisabled = 1; + name = "Prisoner Transfer Centre"; + req_access_txt = "2" + }, +/obj/effect/decal/cleanable/vomit/old, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aGP" = ( +/obj/machinery/door/airlock/survival_pod, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03{ + id = "C07" + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aGQ" = ( +/obj/effect/decal/cleanable/ash/crematorium, +/turf/open/floor/wood{ + icon_state = "wood-broken2" + }, +/area/eventmap/inside) +"aGR" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/effect/decal/cleanable/shreds, +/turf/open/floor/wood, +/area/eventmap/inside) +"aGS" = ( +/obj/effect/decal/cleanable/generic, +/turf/open/floor/wood{ + icon_state = "wood-broken7" + }, +/area/eventmap/inside) +"aGT" = ( +/obj/item/clothing/mask/frog, +/turf/open/floor/spooktime/beach/coasts/coastS, +/area/eventmap/outside) +"aGU" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aGV" = ( +/obj/machinery/light, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aGW" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aGX" = ( +/obj/machinery/door/airlock{ + name = "Bathroom" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aGY" = ( +/obj/structure/sign/barsign, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"aGZ" = ( +/obj/structure/table/wood/bar, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aHa" = ( +/obj/item/reagent_containers/food/condiment/saltshaker, +/obj/item/reagent_containers/food/condiment/peppermill, +/obj/structure/table/wood/bar, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aHb" = ( +/obj/item/candle/infinite, +/obj/structure/table/wood/bar, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aHc" = ( +/obj/item/storage/box/drinkingglasses, +/obj/structure/table/wood/bar, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aHd" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/table/reinforced, +/obj/item/flashlight, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"aHe" = ( +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"aHf" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03{ + id = "C02" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHg" = ( +/obj/item/pizzabox/vegetable, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aHh" = ( +/obj/effect/decal/cleanable/blood/tracks{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHi" = ( +/obj/structure/sign/directions/security{ + dir = 8; + pixel_x = -32; + pixel_y = 40 + }, +/obj/structure/sign/directions/supply{ + dir = 8; + pixel_x = -32; + pixel_y = 32 + }, +/obj/structure/sign/directions/engineering{ + pixel_x = -32; + pixel_y = 24 + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aHj" = ( +/obj/structure/chair/comfy/beige, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aHk" = ( +/turf/open/floor/spooktime/beach/coasts/watercoastE, +/area/eventmap/outside) +"aHl" = ( +/obj/machinery/door/airlock/wood/dorms/patient2, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHm" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aHn" = ( +/obj/machinery/computer/nanite_cloud_controller, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aHo" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/white, +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHp" = ( +/obj/item/storage/box/snappops, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aHq" = ( +/obj/machinery/computer/prisoner/management, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aHr" = ( +/obj/effect/decal/cleanable/blood/old, +/obj/structure/barricade/wooden/crude, +/obj/structure/mineral_door/wood, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHs" = ( +/obj/structure/sign/directions/medical{ + dir = 4; + pixel_x = 32; + pixel_y = 32 + }, +/obj/structure/sign/directions/evac{ + dir = 4; + pixel_x = 32; + pixel_y = 40 + }, +/obj/structure/sign/directions/science{ + pixel_x = 32; + pixel_y = 24 + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aHt" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHu" = ( +/obj/item/flashlight/lantern{ + anchored = 1; + can_be_unanchored = 1; + light_color = "#EE9933"; + light_range = 5; + on = 1 + }, +/turf/open/floor/wood/damturf/broken1, +/area/eventmap/inside) +"aHv" = ( +/obj/item/reagent_containers/food/drinks/bottle/bottleofnothing, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aHw" = ( +/obj/structure/barricade/wooden/crude, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHx" = ( +/obj/machinery/door/airlock/security{ + name = "Armoury"; + req_access_txt = "3" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHy" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Security Office"; + req_access_txt = "63" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHz" = ( +/obj/structure/chair/wood/wings{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood/damturf/broken1, +/area/eventmap/inside) +"aHA" = ( +/obj/item/reagent_containers/food/condiment/saltshaker, +/obj/item/reagent_containers/food/condiment/peppermill, +/obj/structure/table/wood/fancy, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHB" = ( +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHC" = ( +/obj/structure/sign/poster/official/high_class_martini{ + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHD" = ( +/obj/structure/flora/ausbushes/lavendergrass, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aHE" = ( +/obj/structure/table/reinforced, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aHF" = ( +/obj/item/reagent_containers/food/snacks/khachapuri, +/obj/structure/table/reinforced, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aHG" = ( +/obj/structure/chair/stool/bar, +/turf/open/floor/wood/damturf/broken7, +/area/eventmap/inside) +"aHH" = ( +/obj/structure/closet/crate, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHI" = ( +/turf/open/floor/spooktime/cobble/cornerNW, +/area/eventmap/outside) +"aHJ" = ( +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHK" = ( +/obj/structure/table/wood/fancy/orange, +/obj/item/clothing/suit/straight_jacket{ + pixel_x = -8; + pixel_y = 8 + }, +/obj/item/clothing/suit/straight_jacket, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHL" = ( +/obj/structure/table/wood/fancy/orange, +/obj/item/clothing/accessory/lawyers_badge, +/obj/item/restraints/handcuffs/fake, +/obj/item/stamp/law, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHM" = ( +/obj/item/pet_carrier, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aHN" = ( +/obj/item/chair/wood, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHO" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"aHP" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHQ" = ( +/obj/structure/table/wood/fancy/orange, +/obj/effect/decal/cleanable/dirt, +/obj/item/clothing/head/scarecrow_hat, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHR" = ( +/obj/structure/curtain{ + color = "#B22222"; + pixel_x = -32 + }, +/obj/effect/landmark/start/librarian, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHS" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/table/wood/bar, +/obj/machinery/computer/security/wooden_tv{ + pixel_y = 8 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aHT" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHU" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHV" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHW" = ( +/obj/structure/rack, +/obj/item/gun/ballistic/shotgun/automatic/combat, +/obj/item/gun/ballistic/shotgun/automatic/combat, +/obj/item/gun/ballistic/shotgun/automatic/combat, +/obj/item/gun/ballistic/shotgun/automatic/combat, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHX" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/item/storage/box/rubbershot, +/turf/open/floor/wood, +/area/eventmap/inside) +"aHY" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"aHZ" = ( +/obj/structure/table/wood/bar, +/obj/machinery/recharger, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIa" = ( +/obj/structure/trap/ctf/nomech, +/turf/closed/mineral/ash_rock, +/area/eventmap/mountain) +"aIb" = ( +/obj/item/clothing/head/helmet/justice, +/obj/structure/closet/secure_closet/warden, +/obj/item/clothing/suit/armor/hos/trenchcoat, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIc" = ( +/obj/item/stack/sheet/metal/fifty, +/turf/open/floor/spooktime/beach/coasts/coastS, +/area/eventmap/outside) +"aId" = ( +/obj/structure/closet/secure_closet/security, +/obj/machinery/light{ + dir = 1 + }, +/obj/item/clothing/head/beret/sec/navyofficer, +/obj/item/clothing/under/rank/security/officer/formal, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIe" = ( +/obj/machinery/recharge_station, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIf" = ( +/obj/effect/landmark/start/lawyer, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIg" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIh" = ( +/turf/open/floor/wood/damturf/broken6, +/area/eventmap/inside) +"aIi" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aIj" = ( +/obj/structure/mineral_door/wood, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIk" = ( +/obj/structure/chair/office/dark{ + dir = 4 + }, +/obj/effect/landmark/start/warden, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aIl" = ( +/obj/item/chair/wood, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aIm" = ( +/obj/structure/rack, +/obj/item/gun/ballistic/shotgun/automatic/dual_tube, +/obj/item/gun/ballistic/shotgun/automatic/dual_tube, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIn" = ( +/obj/structure/flora/grass/jungle/b{ + icon_state = "grassa5" + }, +/turf/open/floor/spooktime/cobble/cornerSE, +/area/eventmap/outside) +"aIo" = ( +/obj/item/storage/box/rubbershot, +/obj/item/storage/box/rubbershot, +/obj/item/storage/box/rubbershot, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIp" = ( +/turf/open/floor/spooktime/beach/coasts/coastSW, +/area/eventmap/outside) +"aIq" = ( +/turf/open/floor/sepia, +/area/eventmap/mountaininside) +"aIr" = ( +/obj/item/storage/box/rubbershot, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIs" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aIt" = ( +/obj/item/storage/box/techsslug, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIu" = ( +/obj/structure/toilet{ + dir = 8 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aIv" = ( +/obj/structure/closet/cardboard, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aIw" = ( +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aIx" = ( +/obj/structure/curtain{ + color = "#B22222"; + pixel_y = 32 + }, +/turf/open/floor/wood{ + icon_state = "wood-broken3" + }, +/area/eventmap/inside) +"aIy" = ( +/obj/machinery/button/door{ + id = "armory"; + name = "Armory Shutters"; + pixel_x = 26; + req_access_txt = "3" + }, +/obj/item/storage/box/rubbershot, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIz" = ( +/obj/machinery/door/airlock/wood, +/turf/open/floor/carpet, +/area/eventmap/mountaininside) +"aIA" = ( +/obj/effect/landmark/start/security_officer, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIB" = ( +/obj/effect/landmark/start/security_officer, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aIC" = ( +/obj/effect/landmark/start/security_officer, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aID" = ( +/obj/machinery/vending/coffee, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aIE" = ( +/obj/effect/turf_decal/loading_area, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aIF" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aIG" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIH" = ( +/obj/item/storage/fancy/donut_box, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aII" = ( +/obj/vehicle/ridden/secway, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIJ" = ( +/obj/item/reagent_containers/food/snacks/pancakes, +/obj/structure/table/reinforced, +/turf/open/floor/plasteel/damturf/damage4, +/area/eventmap/mountaininside) +"aIK" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aIL" = ( +/obj/structure/falsewall/wood, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIM" = ( +/obj/structure/chair/wood/wings{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIN" = ( +/obj/structure/table/wood/fancy, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIO" = ( +/obj/machinery/computer/rdconsole{ + dir = 1 + }, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aIP" = ( +/obj/machinery/vending/kink, +/turf/open/floor/plasteel/damturf/scorched2, +/area/eventmap/mountaininside) +"aIQ" = ( +/obj/structure/closet/secure_closet/freezer/fridge, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aIR" = ( +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIS" = ( +/obj/item/candle/infinite, +/obj/structure/table/wood/fancy, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIT" = ( +/obj/structure/table, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aIU" = ( +/obj/structure/curtain{ + color = "#B22222"; + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIV" = ( +/obj/structure/spacevine, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aIW" = ( +/obj/structure/chair/wood/wings, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIX" = ( +/obj/machinery/door/airlock/wood/dorms/dorm20, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIY" = ( +/obj/structure/chair/wood/wings, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/landmark/start/assistant, +/turf/open/floor/wood, +/area/eventmap/inside) +"aIZ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/caution{ + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aJa" = ( +/obj/structure/window/reinforced, +/obj/machinery/computer/crew{ + dir = 1 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aJb" = ( +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aJc" = ( +/obj/structure/extinguisher_cabinet, +/turf/closed/wall/mineral/wood, +/area/eventmap/mountaininside) +"aJd" = ( +/obj/structure/window/reinforced, +/obj/structure/table/wood/bar, +/obj/machinery/computer/secure_data/laptop{ + dir = 1; + pixel_y = 6 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aJe" = ( +/obj/machinery/vending/tool, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aJf" = ( +/obj/structure/table/wood/bar, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/machinery/recharger, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aJg" = ( +/obj/structure/cable/yellow, +/obj/structure/bed, +/obj/item/bedsheet/brown, +/turf/open/floor/wood, +/area/eventmap/inside) +"aJh" = ( +/obj/machinery/light/small, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aJi" = ( +/obj/machinery/camera/emp_proof{ + c_tag = "Containment - Particle Accelerator"; + dir = 1; + network = list("singularity") + }, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aJj" = ( +/obj/structure/table/wood, +/obj/item/paper/fluff/balls/spookyasylum/cell04, +/obj/item/paper/fluff/balls/spookyasylum/cell03, +/turf/open/floor/plasteel/dark, +/area/eventmap/inside) +"aJk" = ( +/obj/item/reagent_containers/food/drinks/bottle/blazaam, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aJl" = ( +/turf/open/indestructible/airblock, +/area/eventmap/mountaininside) +"aJm" = ( +/obj/structure/mineral_door/woodrustic, +/turf/open/floor/spooktime/cobble/cornerSW, +/area/eventmap/outside) +"aJn" = ( +/obj/structure/bonfire, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aJo" = ( +/obj/machinery/vending/kink, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"aJp" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/medical/glass{ + id_tag = "MedbayFoyer"; + name = "Medbay"; + req_access_txt = "5" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aJq" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/a_gift/anything, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aJr" = ( +/turf/closed/wall/rust, +/area/eventmap/mountain) +"aJs" = ( +/obj/structure/rack, +/obj/item/gun/ballistic/automatic/shotgun/bulldog/unrestricted, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aJt" = ( +/obj/structure/rack, +/obj/item/storage/box/beanbag, +/obj/item/storage/box/beanbag, +/obj/item/storage/box/fireshot, +/obj/item/storage/box/lethalshot, +/obj/item/storage/box/lethalslugs, +/obj/item/storage/box/lethalshot, +/obj/item/storage/box/rubbershot, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aJu" = ( +/obj/structure/rack, +/obj/item/gun/energy/pulse{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/gun/energy/pulse, +/obj/item/gun/energy/pulse{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aJv" = ( +/obj/structure/rack, +/obj/item/gun/ballistic/shotgun/riot{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/gun/ballistic/shotgun/riot, +/obj/item/gun/ballistic/shotgun/riot{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood/damturf/broken4, +/area/eventmap/inside) +"aJw" = ( +/turf/open/floor/wood/damturf/broken3, +/area/eventmap/mountaininside) +"aJx" = ( +/turf/closed/indestructible/rock, +/area/eventmap/mountain) +"aJy" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/machinery/vending/kink, +/turf/open/floor/wood, +/area/eventmap/inside) +"aJz" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aJA" = ( +/obj/machinery/door/airlock/security{ + name = "Armoury"; + req_access_txt = "3" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aJB" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aJC" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/shower{ + dir = 4 + }, +/obj/structure/mirror{ + pixel_x = -28 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aJD" = ( +/obj/structure/bonfire, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aJE" = ( +/obj/machinery/button/door/dorms/dorm20, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aJF" = ( +/obj/machinery/vending/coffee, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aJG" = ( +/obj/item/pizzabox/infinite, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aJH" = ( +/obj/machinery/conveyor_switch/oneway{ + dir = 8; + id = "cargo_out" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aJI" = ( +/obj/effect/turf_decal/caution{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/door/airlock/mining/glass{ + name = "Cargo Bay"; + req_access_txt = "31" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aJJ" = ( +/obj/vehicle/ridden/secway, +/turf/open/floor/wood, +/area/eventmap/inside) +"aJK" = ( +/turf/open/floor/spooktime/beach/coasts/innerN, +/area/eventmap/outside) +"aJL" = ( +/obj/structure/closet, +/obj/item/stack/sheet/glass/fifty, +/obj/item/stack/sheet/glass/fifty, +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/metal/fifty, +/turf/open/floor/wood, +/area/eventmap/inside) +"aJM" = ( +/turf/open/floor/wood/damturf/broken1, +/area/eventmap/inside) +"aJN" = ( +/obj/machinery/computer/cargo{ + dir = 4 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aJO" = ( +/obj/structure/falsewall/wood, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"aJP" = ( +/obj/structure/table/wood/fancy/cyan, +/turf/open/floor/wood, +/area/eventmap/inside) +"aJQ" = ( +/obj/machinery/door/firedoor, +/turf/open/floor/wood/damturf/broken2, +/area/eventmap/inside) +"aJR" = ( +/obj/structure/chair/office/dark, +/obj/effect/landmark/start/cargo_technician, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aJS" = ( +/obj/machinery/button/door/dorms/luxury3{ + id = "C07"; + pixel_x = -8 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aJT" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aJU" = ( +/turf/open/floor/spooktime/beach/coasts/innerE, +/area/eventmap/outside) +"aJV" = ( +/obj/item/chair/wood, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aJW" = ( +/obj/structure/closet, +/obj/item/stack/sheet/glass/fifty, +/obj/item/stack/sheet/glass/fifty, +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/metal/fifty, +/turf/open/floor/wood/damturf/broken5, +/area/eventmap/inside) +"aJX" = ( +/obj/structure/closet/crate/wooden, +/obj/item/storage/box/matches, +/obj/item/storage/box/matches, +/obj/item/storage/box/matches, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/fancy/candle_box, +/turf/open/floor/wood, +/area/eventmap/inside) +"aJZ" = ( +/obj/item/reagent_containers/food/condiment/saltshaker, +/obj/item/reagent_containers/food/condiment/peppermill, +/obj/item/candle/infinite, +/obj/structure/table/wood/fancy, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKa" = ( +/turf/open/floor/plasteel/damturf/damage2, +/area/eventmap/mountaininside) +"aKb" = ( +/obj/item/candle/infinite, +/obj/structure/table/wood/fancy, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKc" = ( +/obj/item/soap/syndie, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aKd" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/white, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKe" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security{ + name = "Labor Shuttle"; + req_access_txt = "2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKf" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aKg" = ( +/obj/machinery/door/airlock/wood, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aKh" = ( +/obj/structure/table, +/obj/item/storage/pill_bottle/lsd, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aKi" = ( +/turf/open/floor/plasteel/damturf/damage1, +/area/eventmap/mountaininside) +"aKj" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/structure/table, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aKk" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/machinery/door/airlock/engineering{ + name = "Telecommunications Chamber"; + req_access_txt = "61" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aKm" = ( +/obj/structure/chair/sofa/left, +/obj/effect/landmark/start/assistant, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKn" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/closet/secure_closet/RD, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aKo" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aKq" = ( +/turf/open/floor/spooktime/cobble/roadsideS, +/area/eventmap/outside) +"aKr" = ( +/obj/item/gun/energy/e_gun/stun, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKs" = ( +/obj/effect/landmark/start/warden, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKt" = ( +/obj/item/reagent_containers/pill/stimulant, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aKu" = ( +/obj/structure/closet/crate, +/obj/item/clothing/head/pirate, +/obj/item/clothing/head/santa, +/obj/item/clothing/head/magus, +/obj/item/clothing/head/mailman, +/obj/item/clothing/head/griffin, +/obj/item/clothing/head/bearpelt, +/obj/item/clothing/head/beret, +/obj/item/clothing/head/bowler, +/obj/item/clothing/head/fedora, +/obj/item/clothing/accessory/skullcodpiece, +/obj/item/clothing/neck/devilwings, +/obj/item/clothing/gloves/bracer, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKv" = ( +/obj/item/storage/box/stunslug, +/obj/item/storage/box/stunslug, +/obj/item/storage/box/stunslug, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKw" = ( +/obj/structure/table/wood/bar, +/obj/machinery/door/poddoor/shutters{ + id = "armory"; + name = "Armoury Shutter" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKx" = ( +/obj/machinery/door/airlock/silver{ + name = "Bathroom" + }, +/turf/open/floor/sepia, +/area/eventmap/mountaininside) +"aKy" = ( +/obj/item/reagent_containers/food/drinks/bottle/lizardwine, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aKz" = ( +/obj/structure/urinal{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aKA" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aKB" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aKC" = ( +/obj/item/reagent_containers/food/drinks/bottle/lizardwine, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKD" = ( +/obj/machinery/nanite_programmer, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aKE" = ( +/obj/effect/landmark/start/depsec/engineering, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKF" = ( +/obj/effect/landmark/start/depsec/medical, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aKG" = ( +/obj/machinery/vending/snack/random, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aKH" = ( +/obj/effect/landmark/start/depsec/science, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKI" = ( +/obj/machinery/door/firedoor, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/door/airlock/security{ + name = "Labor Shuttle"; + req_access_txt = "2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKJ" = ( +/obj/structure/chair/comfy/beige{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aKK" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood{ + icon_state = "wood-broken4" + }, +/area/eventmap/inside) +"aKL" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKM" = ( +/obj/machinery/button/door/dorms/luxury3{ + id = "C11"; + pixel_y = -24 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aKN" = ( +/obj/machinery/door_timer{ + id = "Cell 1"; + name = "Cell 1"; + pixel_y = -32 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKO" = ( +/obj/machinery/door_timer{ + id = "Cell 2"; + name = "Cell 2"; + pixel_y = -32 + }, +/obj/effect/decal/cleanable/blood/tracks{ + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKP" = ( +/turf/open/floor/spooktime/cobble/sideN, +/area/eventmap/outside) +"aKQ" = ( +/turf/open/floor/spooktime/beach/coasts/coastE, +/area/eventmap/outside) +"aKR" = ( +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKS" = ( +/turf/open/floor/spooktime/cobble/cornerNE, +/area/eventmap/outside) +"aKT" = ( +/obj/structure/rack, +/obj/item/gun/ballistic/shotgun/boltaction{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/item/gun/ballistic/shotgun/boltaction{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/gun/ballistic/shotgun/boltaction, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKU" = ( +/obj/structure/rack, +/obj/item/clothing/suit/armor/riot{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/clothing/suit/armor/riot, +/obj/item/clothing/suit/armor/riot{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/item/clothing/head/helmet/riot{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/clothing/head/helmet/riot, +/obj/item/clothing/head/helmet/riot{ + pixel_x = -4; + pixel_y = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKV" = ( +/obj/structure/rack, +/obj/item/clothing/suit/armor/bulletproof{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/clothing/suit/armor/bulletproof, +/obj/item/clothing/suit/armor/bulletproof{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/item/clothing/head/helmet/alt{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/item/clothing/head/helmet/alt, +/obj/item/clothing/head/helmet/alt{ + pixel_x = -4; + pixel_y = 4 + }, +/turf/open/floor/wood/damturf/broken6, +/area/eventmap/inside) +"aKW" = ( +/obj/structure/closet/secure_closet/hos, +/obj/item/clothing/head/helmet/justice/escape{ + name = "justice helmet" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aKX" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/conveyor{ + id = "cargo_front" + }, +/turf/open/floor/plating, +/area/eventmap/inside) +"aKY" = ( +/obj/machinery/light, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aKZ" = ( +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/carpet, +/area/eventmap/mountaininside) +"aLa" = ( +/obj/structure/closet/secure_closet/armory3, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLb" = ( +/obj/structure/closet/secure_closet/armory2, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLc" = ( +/obj/structure/closet/secure_closet/armory1, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLd" = ( +/obj/structure/closet/crate/wooden, +/obj/item/storage/box/matches, +/obj/item/storage/box/matches, +/obj/item/storage/box/matches, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/fancy/candle_box, +/turf/open/floor/wood/damturf/broken7, +/area/eventmap/inside) +"aLe" = ( +/obj/structure/table/wood/bar, +/obj/machinery/recharger, +/obj/item/key/security, +/obj/item/key/security, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLf" = ( +/obj/machinery/rnd/production/techfab/department/security, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLg" = ( +/obj/item/autosurgeon/gloweyes, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aLh" = ( +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aLi" = ( +/obj/structure/chair/wood/wings{ + dir = 4 + }, +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLj" = ( +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLk" = ( +/obj/machinery/door/window/brigdoor/security/cell{ + id = "Cell 1"; + name = "Cell 1" + }, +/obj/effect/decal/cleanable/blood/tracks, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLl" = ( +/obj/structure/sign/poster/official/no_erp, +/turf/closed/wall/rust, +/area/eventmap/mountaininside) +"aLm" = ( +/obj/machinery/door/window/brigdoor/security/cell{ + id = "Cell 2"; + name = "Cell 2" + }, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLn" = ( +/turf/closed/wall/mineral/iron, +/area/eventmap/inside) +"aLo" = ( +/obj/machinery/biogenerator, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/inside) +"aLp" = ( +/obj/machinery/seed_extractor, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/inside) +"aLq" = ( +/obj/item/radio/intercom{ + desc = "Talk through this. It looks like it has been modified to not broadcast."; + name = "Prison Intercom (General)"; + pixel_x = -25; + pixel_y = -2; + prison_radio = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLr" = ( +/obj/machinery/shower{ + dir = 8; + pixel_y = -4 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/sepia, +/area/eventmap/mountaininside) +"aLs" = ( +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/wood{ + icon_state = "wood-broken6" + }, +/area/eventmap/inside) +"aLt" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aLu" = ( +/obj/effect/decal/cleanable/crayon, +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLv" = ( +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/inside) +"aLw" = ( +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/inside) +"aLx" = ( +/obj/item/coin/antagtoken, +/obj/structure/closet/crate/trashcart/moneywish, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"aLy" = ( +/obj/structure/bed, +/obj/item/bedsheet/pirate, +/obj/machinery/flasher{ + id = "Cell 1"; + pixel_x = -28 + }, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLz" = ( +/obj/structure/closet/secure_closet/brig{ + id = "Cell 1"; + name = "Cell 1 Locker" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLA" = ( +/obj/structure/table/optable, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLB" = ( +/obj/structure/table/plasmaglass, +/obj/item/storage/backpack/duffelbag/sec/surgery, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLC" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLD" = ( +/obj/structure/bed, +/obj/item/bedsheet/cult, +/obj/machinery/flasher{ + id = "Cell 2"; + pixel_x = -28 + }, +/obj/effect/decal/cleanable/blood/gibs/old, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLE" = ( +/obj/structure/closet/secure_closet/brig{ + id = "Cell 2"; + name = "Cell 2 Locker" + }, +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/item/toy/toy_dagger, +/obj/item/clothing/suit/cultrobes, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLF" = ( +/obj/item/chair, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aLG" = ( +/obj/item/reagent_containers/food/drinks/bottle/whiskey, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aLH" = ( +/obj/structure/sink/puddle, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/inside) +"aLI" = ( +/obj/machinery/hydroponics/soil, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/inside) +"aLJ" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/inside) +"aLK" = ( +/obj/structure/holohoop, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/inside) +"aLL" = ( +/obj/structure/table/wood/fancy, +/obj/item/candle/infinite{ + pixel_x = -8 + }, +/obj/item/reagent_containers/food/snacks/meat/steak{ + pixel_y = 16 + }, +/obj/item/candle/infinite{ + pixel_x = 8 + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/mountain) +"aLM" = ( +/obj/structure/spacevine, +/turf/open/floor/spooktime/beach/watersolid, +/area/eventmap/mountain) +"aLN" = ( +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/inside) +"aLO" = ( +/obj/structure/closet/crate/bin, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/inside) +"aLP" = ( +/obj/structure/chair/wood, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/inside) +"aLQ" = ( +/obj/structure/bed, +/obj/item/bedsheet/blue, +/turf/open/floor/carpet, +/area/eventmap/mountaininside) +"aLR" = ( +/obj/structure/curtain{ + color = "#B22222"; + pixel_x = 32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLS" = ( +/obj/structure/table/wood, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/inside) +"aLT" = ( +/obj/structure/toilet{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aLU" = ( +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/outside) +"aLV" = ( +/obj/item/stack/sheet/mineral/diamond, +/obj/item/stack/sheet/mineral/adamantine, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"aLW" = ( +/obj/structure/spacevine, +/turf/open/floor/spooktime/beach/coasts/innerS, +/area/eventmap/outside) +"aLX" = ( +/obj/machinery/light/small, +/turf/open/floor/wood{ + icon_state = "wood-broken4" + }, +/area/eventmap/inside) +"aLY" = ( +/obj/structure/barricade/wooden, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aLZ" = ( +/obj/item/storage/fancy/cigarettes/cigpack_mindbreaker, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aMa" = ( +/obj/machinery/shower{ + desc = "Despite their age, they seem clean and capable of providing hot water just as well as their modern counterparts. Hopefully Nanotrasen cleaned the water pipes this well..."; + dir = 8 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aMb" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/sepia, +/area/eventmap/mountaininside) +"aMc" = ( +/obj/item/scythe, +/turf/open/floor/wood{ + icon_state = "wood-broken5" + }, +/area/eventmap/inside) +"aMd" = ( +/obj/structure/table/wood, +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/inside) +"aMe" = ( +/obj/item/chair/wood, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/inside) +"aMf" = ( +/obj/machinery/cryopod{ + dir = 8 + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/inside) +"aMg" = ( +/obj/structure/chair/wood{ + dir = 1 + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/inside) +"aMh" = ( +/turf/open/floor/spooktime/beach/coasts/watercoastSE, +/area/eventmap/outside) +"aMi" = ( +/obj/machinery/conveyor_switch/oneway{ + dir = 8; + id = "cargo_front" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMj" = ( +/obj/structure/table/reinforced, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMk" = ( +/obj/structure/table/reinforced, +/obj/item/stamp{ + pixel_x = -12; + pixel_y = 16 + }, +/obj/item/stamp/denied{ + pixel_x = 12; + pixel_y = 16 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMl" = ( +/obj/structure/chair/sofa/right, +/obj/item/storage/daki, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aMm" = ( +/obj/structure/table/reinforced, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMn" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aMo" = ( +/obj/machinery/mecha_part_fabricator, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aMp" = ( +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aMq" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + mouse_opacity = 0 + }, +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + mouse_opacity = 0 + }, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aMr" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/plasticflaps/opaque, +/obj/machinery/conveyor{ + id = "cargo_front" + }, +/turf/open/floor/plating, +/area/eventmap/inside) +"aMs" = ( +/obj/machinery/conveyor_switch/oneway{ + id = "cargo_out" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMt" = ( +/obj/machinery/computer/cargo/request{ + dir = 4 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMu" = ( +/obj/item/storage/fancy/rollingpapers, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aMv" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aMx" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMy" = ( +/obj/structure/table/plasmaglass, +/obj/item/integrated_electronics/analyzer, +/obj/item/integrated_electronics/debugger, +/obj/item/integrated_electronics/detailer, +/obj/item/integrated_electronics/wirer, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aMz" = ( +/obj/structure/bookcase/manuals/medical, +/turf/closed/wall/mineral/wood, +/area/eventmap/mountaininside) +"aMA" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/structure/noticeboard/qm{ + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMB" = ( +/obj/item/reagent_containers/food/urinalcake, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aMC" = ( +/obj/effect/turf_decal/stripes/corner, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/machinery/conveyor{ + dir = 5; + id = "conveyor_out" + }, +/turf/open/floor/plating, +/area/eventmap/inside) +"aMD" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/conveyor{ + dir = 4; + id = "cargo_out" + }, +/turf/open/floor/plating, +/area/eventmap/inside) +"aME" = ( +/turf/open/floor/carpet/red, +/area/eventmap/mountaininside) +"aMF" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/plasticflaps/opaque, +/obj/machinery/conveyor{ + dir = 4; + id = "cargo_out" + }, +/turf/open/floor/plating, +/area/eventmap/inside) +"aMG" = ( +/obj/structure/mineral_door/wood, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aMH" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMI" = ( +/turf/open/floor/carpet/orange, +/area/eventmap/mountaininside) +"aMJ" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMK" = ( +/obj/machinery/processor, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aML" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Cargo Bay"; + req_access_txt = "31" + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMM" = ( +/obj/structure/flora/tree/jungle, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"aMN" = ( +/obj/effect/landmark/start/assistant, +/turf/open/floor/spooktime/cobble/roadsideS, +/area/eventmap/outside) +"aMO" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/conveyor{ + dir = 1; + id = "cargo_out" + }, +/turf/open/floor/plating, +/area/eventmap/inside) +"aMP" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMQ" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/effect/landmark/start/assistant/override, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMR" = ( +/obj/item/switchblade, +/turf/open/floor/wood{ + icon_state = "wood-broken2" + }, +/area/eventmap/inside) +"aMS" = ( +/obj/structure/table, +/obj/item/storage/pill_bottle/penis_enlargement, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aMT" = ( +/obj/machinery/camera/emp_proof{ + c_tag = "Cargo Office"; + dir = 8; + network = list("singularity") + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMU" = ( +/obj/effect/turf_decal/loading_area, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMV" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/autolathe/toy, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMW" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/obj/machinery/vending/tool, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aMX" = ( +/obj/item/storage/pill_bottle/breast_enlargement, +/turf/open/floor/plasteel/damturf/scorched, +/area/eventmap/mountaininside) +"aMY" = ( +/obj/structure/closet/crate/bin, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aMZ" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/conveyor{ + dir = 4; + id = "cargo_out" + }, +/obj/machinery/light/small, +/turf/open/floor/plating, +/area/eventmap/inside) +"aNa" = ( +/obj/machinery/vending/coffee, +/turf/open/floor/wood/damturf/broken6, +/area/eventmap/mountaininside) +"aNb" = ( +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03{ + id = "C05" + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aNc" = ( +/obj/item/gun/magic/staff/healing, +/obj/structure/table/wood/fancy/green, +/turf/open/floor/carpet/orange, +/area/eventmap/mountaininside) +"aNd" = ( +/obj/item/storage/firstaid/regular, +/turf/open/floor/carpet/orange, +/area/eventmap/mountaininside) +"aNe" = ( +/obj/structure/table, +/obj/machinery/chem_dispenser/drinks/beer, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aNf" = ( +/obj/item/chair/wood, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aNg" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/mug/coco, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aNh" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/machinery/conveyor/inverted{ + dir = 10; + id = "cargo_out" + }, +/turf/open/floor/plating, +/area/eventmap/inside) +"aNi" = ( +/obj/item/flashlight/lantern{ + anchored = 1; + can_be_unanchored = 1; + light_color = "#EE9933"; + light_range = 5; + on = 1 + }, +/turf/open/floor/carpet/orange, +/area/eventmap/mountaininside) +"aNj" = ( +/obj/machinery/door/airlock/mining{ + name = "Mining"; + req_access_txt = "48" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aNk" = ( +/obj/machinery/shower{ + desc = "Despite their age, they seem clean and capable of providing hot water just as well as their modern counterparts. Hopefully Nanotrasen cleaned the water pipes this well..."; + dir = 4 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aNl" = ( +/obj/structure/closet/athletic_mixed, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aNm" = ( +/obj/item/clothing/head/hardhat/pumpkinhead/jaqc, +/obj/structure/table/wood/fancy/green, +/obj/effect/spawner/lootdrop/welder_tools, +/turf/open/floor/carpet/orange, +/area/eventmap/mountaininside) +"aNn" = ( +/obj/machinery/door/airlock/mining{ + name = "Mining"; + req_access_txt = "48" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aNo" = ( +/obj/structure/mineral_door/wood, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aNp" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/eventmap/inside) +"aNq" = ( +/obj/structure/chair/wood/wings{ + dir = 4 + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/mountain) +"aNr" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aNs" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aNt" = ( +/obj/item/scythe, +/obj/structure/curtain{ + color = "#B22222"; + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aNu" = ( +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aNv" = ( +/obj/structure/spacevine, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/outside) +"aNw" = ( +/obj/structure/closet/crate/trashcart, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aNx" = ( +/obj/structure/table/wood, +/obj/structure/bedsheetbin/towel, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aNy" = ( +/obj/structure/rack, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aNz" = ( +/obj/structure/barricade/sandbags, +/turf/open/indestructible/airblock, +/area/eventmap/mountaininside) +"aNA" = ( +/obj/item/storage/fancy/heart_box, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aNB" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/mineral/equipment_vendor, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aNC" = ( +/obj/structure/holohoop{ + dir = 1 + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aND" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aNE" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"aNF" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aNG" = ( +/obj/structure/chair/sofa, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aNH" = ( +/obj/structure/bed, +/obj/item/bedsheet/black, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aNI" = ( +/obj/item/bedsheet/blue, +/obj/structure/bed, +/turf/open/floor/carpet/green, +/area/eventmap/mountaininside) +"aNJ" = ( +/obj/structure/mirror{ + pixel_x = 28 + }, +/obj/structure/sink{ + dir = 4; + pixel_x = 11 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aNK" = ( +/obj/structure/mirror{ + pixel_x = -28 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aNL" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/rag/towel, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aNM" = ( +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aNN" = ( +/obj/machinery/door/airlock/mining{ + name = "Mining"; + req_access_txt = "48" + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aNP" = ( +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/landmark/start/shaft_miner, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aNQ" = ( +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/landmark/start/shaft_miner, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aNR" = ( +/obj/machinery/door/airlock/wood/glass, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aNS" = ( +/obj/structure/spacevine, +/obj/structure/spacevine, +/obj/structure/spacevine, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aNT" = ( +/obj/structure/table/plasmaglass, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/obj/item/stock_parts/cell/hyper, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aNU" = ( +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aNV" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/gun/magic/staff/healing, +/turf/open/floor/carpet/orange, +/area/eventmap/mountaininside) +"aNW" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/effect/turf_decal/tile/brown, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aNX" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aNY" = ( +/obj/item/flashlight/lantern{ + anchored = 1; + can_be_unanchored = 1; + light_color = "#EE9933"; + light_range = 5; + on = 1 + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aNZ" = ( +/obj/vehicle/sealed/vectorcraft, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aOa" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/door/airlock/mining{ + name = "Mining"; + req_access_txt = "48" + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aOb" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aOc" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/closet/secure_closet/quartermaster, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOd" = ( +/obj/structure/bed, +/obj/item/bedsheet/qm, +/obj/effect/landmark/start/quartermaster, +/obj/structure/sign/poster/contraband/masked_men, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOe" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/sink{ + dir = 8; + pixel_x = -12 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/inside) +"aOf" = ( +/obj/vehicle/sealed/vectorcraft/ambulance, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aOg" = ( +/obj/structure/toilet{ + dir = 8 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/inside) +"aOh" = ( +/obj/effect/turf_decal/bot, +/obj/structure/closet/secure_closet/miner, +/obj/machinery/camera/emp_proof{ + c_tag = "Mining Entrance"; + dir = 1; + network = list("singularity") + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aOi" = ( +/obj/effect/turf_decal/bot, +/obj/structure/closet/secure_closet/miner, +/obj/machinery/light/small, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aOj" = ( +/obj/structure/toilet{ + dir = 4 + }, +/turf/open/floor/sepia, +/area/eventmap/mountaininside) +"aOk" = ( +/obj/machinery/light, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aOl" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood/damturf/broken5, +/area/eventmap/inside) +"aOm" = ( +/obj/effect/turf_decal/bot, +/obj/structure/closet/secure_closet/miner, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aOn" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aOo" = ( +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOp" = ( +/obj/structure/cable/white{ + icon_state = "0-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOq" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/shower{ + dir = 4 + }, +/obj/structure/mirror{ + pixel_x = -28 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/inside) +"aOr" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/autolathe/toy, +/turf/open/floor/spooktime/cobble/sideN, +/area/eventmap/outside) +"aOs" = ( +/obj/effect/landmark/start/quartermaster, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/inside) +"aOt" = ( +/obj/machinery/door/airlock/mining{ + name = "Mining"; + req_access_txt = "48" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aOu" = ( +/obj/machinery/door/airlock/wood, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOv" = ( +/obj/machinery/door/airlock/wood, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/inside) +"aOw" = ( +/obj/structure/bed, +/obj/item/bedsheet/random, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aOx" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/structure/cable/white{ + icon_state = "0-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOy" = ( +/turf/open/floor/spooktime/beach/coasts/watercoastNW, +/area/eventmap/outside) +"aOA" = ( +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/indestructible/cobble, +/area/eventmap/outside) +"aOB" = ( +/obj/structure/filingcabinet, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOC" = ( +/turf/open/floor/plasteel/damturf/platdmg3, +/area/eventmap/mountaininside) +"aOD" = ( +/obj/structure/fluff/broken_flooring, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aOE" = ( +/turf/open/floor/wood, +/area/eventmap/inside) +"aOF" = ( +/obj/machinery/grandfatherclock, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOG" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/table/wood, +/obj/item/paper_bin, +/obj/item/pen/fountain, +/obj/item/stamp/qm, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOH" = ( +/obj/structure/chair/comfy/black{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aOI" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aOJ" = ( +/obj/structure/sign/poster/official/no_erp, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"aOK" = ( +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOL" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03{ + id = "C01" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOM" = ( +/obj/structure/chair/office/dark, +/obj/effect/landmark/start/quartermaster, +/turf/open/floor/wood, +/area/eventmap/inside) +"aON" = ( +/obj/machinery/button/door/dorms/luxury3{ + id = "C10"; + pixel_x = 24; + pixel_y = -12 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOO" = ( +/obj/structure/table, +/obj/machinery/reagentgrinder, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aOP" = ( +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/obj/machinery/computer/card/minor/qm{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOQ" = ( +/obj/vehicle/sealed/vectorcraft/cyber, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aOR" = ( +/obj/structure/table, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/chem_dispenser/drinks, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aOS" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/computer/cargo{ + dir = 1 + }, +/turf/open/floor/wood/damturf/broken3, +/area/eventmap/inside) +"aOU" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/computer/security/qm{ + dir = 1 + }, +/obj/structure/sign/poster/official/twelve_gauge{ + pixel_y = -32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOV" = ( +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03{ + id = "C10"; + name = "Quartermaster's Shutters" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/door/airlock/mining{ + name = "Quartermaster's Quarters"; + req_access_txt = "41" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOW" = ( +/obj/structure/table/wood, +/obj/item/storage/firstaid/brute, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aOX" = ( +/obj/structure/closet/secure_closet/personal, +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aOY" = ( +/obj/structure/closet/crate/bin, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aOZ" = ( +/obj/machinery/shower{ + desc = "Despite their age, they seem clean and capable of providing hot water just as well as their modern counterparts. Hopefully Nanotrasen cleaned the water pipes this well..."; + dir = 8 + }, +/obj/item/soap, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aPa" = ( +/obj/structure/table, +/obj/structure/bedsheetbin/towel, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aPb" = ( +/obj/structure/bed, +/obj/item/bedsheet/black, +/turf/open/floor/carpet/purple, +/area/eventmap/mountaininside) +"aPc" = ( +/obj/structure/bookcase/random, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aPd" = ( +/obj/machinery/computer/rdconsole, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aPe" = ( +/obj/vehicle/sealed/vectorcraft/CAPT, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aPf" = ( +/obj/vehicle/sealed/vectorcraft/CE, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aPg" = ( +/obj/vehicle/sealed/vectorcraft/CMO, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aPh" = ( +/obj/vehicle/sealed/vectorcraft/QM, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aPi" = ( +/turf/closed/indestructible/riveted/hierophant, +/area/eventmap/mountaininside) +"aPj" = ( +/obj/structure/filingcabinet/chestdrawer, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aPk" = ( +/obj/vehicle/sealed/vectorcraft/RD, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aPl" = ( +/obj/structure/rack, +/obj/item/stack/sheet/mineral/wood/fifty, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aPm" = ( +/obj/item/candle/infinite, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aPn" = ( +/obj/vehicle/sealed/vectorcraft/hop, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aPo" = ( +/obj/structure/table/reinforced, +/obj/item/storage/toolbox/syndicate, +/obj/item/storage/toolbox/gold_real, +/obj/item/storage/toolbox/syndicate, +/obj/item/storage/toolbox/gold_real, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aPp" = ( +/obj/vehicle/sealed/vectorcraft/hos, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aPq" = ( +/mob/living/simple_animal/jacq{ + active = 0 + }, +/turf/open/floor/carpet/orange, +/area/eventmap/mountaininside) +"aPr" = ( +/obj/structure/flora/grass/jungle/b, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"aPs" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"aPt" = ( +/obj/structure/chair/wood/wings, +/turf/open/floor/carpet/orange, +/area/eventmap/mountaininside) +"aPu" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/reagent_containers/food/snacks/pizza/pineapple, +/turf/open/floor/carpet/orange, +/area/eventmap/mountaininside) +"aPv" = ( +/obj/machinery/door/airlock/vault{ + name = "Mecha Battleground" + }, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aPw" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/reagent_containers/food/snacks/pizza/margherita, +/turf/open/floor/carpet/orange, +/area/eventmap/mountaininside) +"aPx" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aPy" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/reagent_containers/food/snacks/pizza/meat, +/turf/open/floor/carpet/orange, +/area/eventmap/mountaininside) +"aPz" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/reagent_containers/food/snacks/pizza/mushroom, +/turf/open/floor/carpet/orange, +/area/eventmap/mountaininside) +"aPA" = ( +/obj/item/skub, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aPB" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/reagent_containers/food/snacks/pizza/sassysage, +/turf/open/floor/carpet/orange, +/area/eventmap/mountaininside) +"aPC" = ( +/obj/structure/table, +/obj/machinery/microwave, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aPE" = ( +/obj/structure/table/wood/fancy/green, +/obj/item/reagent_containers/food/snacks/pizza/vegetable, +/turf/open/floor/carpet/orange, +/area/eventmap/mountaininside) +"aPF" = ( +/obj/vehicle/sealed/vectorcraft/auto, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aPG" = ( +/obj/structure/table/wood/fancy/green, +/obj/effect/spawner/lootdrop/welder_tools, +/obj/item/clothing/head/welding, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aPH" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/mountaininside) +"aPI" = ( +/obj/structure/spacevine, +/turf/open/floor/spooktime/beach, +/area/eventmap/outside) +"aPJ" = ( +/obj/item/soap/homemade, +/turf/open/floor/sepia, +/area/eventmap/mountaininside) +"aPK" = ( +/obj/item/clothing/neck/petcollar, +/turf/open/floor/wood, +/area/eventmap/inside) +"aPL" = ( +/obj/structure/fluff/broken_flooring, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"aPM" = ( +/obj/machinery/recycler/lumbermill, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"aPN" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/cargo/miningstorage) +"aPO" = ( +/turf/open/floor/plasteel/damturf/platdmg2, +/area/eventmap/mountaininside) +"aPP" = ( +/obj/machinery/door/airlock/abandoned{ + name = "Filthy Powergame Shack" + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aPQ" = ( +/turf/open/floor/plasteel, +/area/cargo/miningstorage) +"aPR" = ( +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/plasteel, +/area/cargo/miningstorage) +"aPS" = ( +/obj/machinery/door/airlock/security, +/turf/open/floor/wood, +/area/eventmap/inside) +"aPT" = ( +/turf/closed/wall, +/area/eventmap/mountaininside) +"aPU" = ( +/obj/item/clothing/head/hardhat/pumpkinhead/jaqc, +/obj/structure/table/wood/fancy/green, +/obj/effect/spawner/lootdrop/welder_tools, +/turf/open/floor/wood, +/area/eventmap/inside) +"aPV" = ( +/obj/machinery/light/small/broken{ + dir = 1 + }, +/obj/effect/decal/cleanable/cobweb, +/obj/effect/decal/cleanable/glass, +/turf/open/floor/mineral/titanium/white{ + name = "padded floor" + }, +/area/eventmap/inside) +"aPW" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/item/reagent_containers/glass/bowl, +/obj/item/clothing/neck/petcollar, +/turf/open/floor/mineral/titanium/white{ + name = "padded floor" + }, +/area/eventmap/inside) +"aPX" = ( +/obj/item/pet_carrier, +/obj/effect/decal/cleanable/semen, +/turf/open/floor/mineral/titanium/white, +/area/eventmap/inside) +"aPY" = ( +/obj/item/reagent_containers/food/drinks/bottle/grappa, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aPZ" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/indestructible/cobble, +/area/eventmap/outside) +"aQa" = ( +/obj/structure/cable/pink{ + icon_state = "2-5" + }, +/turf/open/floor/plating, +/area/eventmap/mountain) +"aQb" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aQc" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aQd" = ( +/obj/item/lighter/gold, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aQe" = ( +/turf/open/floor/carpet/green, +/area/eventmap/mountaininside) +"aQf" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood/damturf/broken2, +/area/eventmap/inside) +"aQg" = ( +/obj/structure/bookcase/manuals/research_and_development, +/turf/closed/wall/mineral/wood, +/area/eventmap/mountaininside) +"aQh" = ( +/obj/item/toy/fluff/tennis_poly/red, +/turf/open/floor/mineral/titanium/white, +/area/eventmap/inside) +"aQi" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/noticeboard{ + pixel_y = 32 + }, +/obj/item/paper/fluff/balls/spookyasylum/cell03, +/turf/open/floor/carpet/royalblack, +/area/eventmap/inside) +"aQj" = ( +/obj/effect/decal/cleanable/cobweb{ + icon_state = "cobweb2" + }, +/obj/structure/noticeboard{ + pixel_y = 32 + }, +/obj/item/paper/fluff/balls/spookyasylum/cell04, +/turf/open/floor/wood, +/area/eventmap/inside) +"aQk" = ( +/obj/structure/cable/pink{ + icon_state = "1-10" + }, +/turf/open/floor/plating, +/area/eventmap/mountain) +"aQl" = ( +/obj/item/flashlight/lantern{ + anchored = 1; + can_be_unanchored = 1; + light_color = "#EE9933"; + light_range = 5; + on = 1 + }, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aQm" = ( +/obj/structure/table/wood/fancy/orange, +/obj/item/reagent_containers/rag/towel, +/turf/open/floor/wood, +/area/eventmap/inside) +"aQn" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/donut/bungo, +/turf/open/floor/wood, +/area/eventmap/inside) +"aQo" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/donut/glaze, +/turf/open/floor/wood, +/area/eventmap/inside) +"aQp" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/donut/matcha, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aQq" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aQr" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/donut/apple, +/turf/open/floor/wood, +/area/eventmap/inside) +"aQs" = ( +/obj/structure/bed, +/obj/item/bedsheet/purple, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aQt" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/donut/laugh, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aQu" = ( +/obj/structure/chair{ + dir = 8 + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aQv" = ( +/obj/structure/cable/pink{ + icon_state = "2-9" + }, +/turf/open/floor/plating, +/area/eventmap/mountain) +"aQw" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/donut/jelly/berry, +/turf/open/floor/wood, +/area/eventmap/inside) +"aQx" = ( +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aQy" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/donut/caramel, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aQz" = ( +/obj/item/reagent_containers/food/snacks/roastparsnip, +/obj/structure/table/reinforced, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aQA" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/donut/laugh, +/obj/item/reagent_containers/food/snacks/donut/laugh, +/turf/open/floor/wood, +/area/eventmap/inside) +"aQB" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/snacks/donut/laugh, +/turf/open/floor/wood, +/area/eventmap/inside) +"aQC" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/eventmap/inside) +"aQD" = ( +/obj/item/barthpot{ + BallTutorial = 1; + active = 0; + light_range = 5 + }, +/turf/open/floor/spooktime/cobble/roadsideS, +/area/eventmap/outside) +"aQF" = ( +/obj/machinery/washing_machine, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aQG" = ( +/obj/structure/sink{ + dir = 8; + pixel_x = -12 + }, +/obj/structure/mirror{ + pixel_x = -28 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aQI" = ( +/obj/structure/bookcase/random/adult, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aQK" = ( +/turf/open/floor/spooktime/beach, +/area/eventmap/outside) +"aQL" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/purple, +/area/eventmap/inside) +"aQM" = ( +/obj/effect/landmark/start/clown, +/turf/open/floor/wood, +/area/eventmap/inside) +"aQN" = ( +/obj/machinery/door/firedoor, +/turf/open/floor/wood, +/area/eventmap/inside) +"aQO" = ( +/obj/structure/table/wood/bar, +/turf/open/floor/wood, +/area/eventmap/inside) +"aQP" = ( +/obj/structure/table/plasmaglass, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aQQ" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aQR" = ( +/obj/structure/table/wood/bar, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aQS" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/drinks/bottle/tequila, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aQT" = ( +/obj/effect/landmark/start/clown, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"aQU" = ( +/obj/structure/table, +/obj/machinery/light{ + dir = 1 + }, +/obj/item/book/manual/wiki/barman_recipes, +/obj/item/book/granter/action/drink_fling, +/obj/item/reagent_containers/food/drinks/shaker, +/obj/item/reagent_containers/rag, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aQV" = ( +/obj/structure/dresser, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aQW" = ( +/obj/item/reagent_containers/food/snacks/khinkali, +/obj/structure/table/reinforced, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aQX" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/drinks/bottle/champagne, +/obj/machinery/button/door/dorms/luxury3{ + id = "C08"; + pixel_y = -24 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aQY" = ( +/obj/machinery/washing_machine, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aQZ" = ( +/obj/structure/chair/wood/normal, +/turf/open/floor/carpet/purple, +/area/eventmap/inside) +"aRa" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aRb" = ( +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/obj/structure/chair/wood/normal{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aRc" = ( +/obj/item/reagent_containers/food/drinks/bottle/absinthe, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aRd" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"aRe" = ( +/obj/item/restraints/handcuffs, +/turf/open/floor/carpet/red, +/area/eventmap/mountaininside) +"aRf" = ( +/obj/structure/chair/wood/normal{ + dir = 4 + }, +/turf/open/floor/carpet/purple, +/area/eventmap/inside) +"aRg" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/spooktime/cobble/sideE, +/area/eventmap/outside) +"aRh" = ( +/obj/structure/table/wood/poker, +/obj/item/toy/cards/deck/cas/black{ + pixel_x = 4 + }, +/obj/item/toy/cards/deck/cas{ + pixel_x = -4 + }, +/obj/item/toy/cards/deck{ + pixel_y = 4 + }, +/obj/machinery/light/small, +/turf/open/floor/carpet/purple, +/area/eventmap/inside) +"aRi" = ( +/obj/structure/fluff/broken_flooring, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aRj" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/turf/open/floor/carpet/purple, +/area/eventmap/inside) +"aRk" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/spooktime/cobble/sideW, +/area/eventmap/outside) +"aRl" = ( +/obj/structure/chair/wood/normal{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aRm" = ( +/turf/open/floor/plasteel/damturf/damage5, +/area/eventmap/mountaininside) +"aRn" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/eventmap/inside) +"aRo" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aRp" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/curtain{ + color = "#B22222"; + pixel_x = 32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aRq" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aRr" = ( +/obj/structure/flora/grass/jungle/b, +/turf/open/floor/spooktime/cobble/sideN, +/area/eventmap/outside) +"aRs" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aRt" = ( +/obj/effect/landmark/start/janitor, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aRu" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/landmark/start/scientist, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"aRv" = ( +/obj/structure/flora/junglebush, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aRw" = ( +/obj/machinery/door/airlock/wood, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aRy" = ( +/obj/item/stack/sheet/metal/fifty, +/turf/open/floor/spooktime/beach, +/area/eventmap/outside) +"aRz" = ( +/obj/machinery/door/airlock/survival_pod, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03{ + id = "C08" + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aRB" = ( +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"aRC" = ( +/obj/effect/decal/remains/human, +/obj/effect/rune/apocalypse, +/obj/effect/decal/cleanable/blood/splatter, +/obj/item/toy/plush/catgirl/fermis, +/turf/open/floor/wood, +/area/eventmap/inside) +"aRD" = ( +/obj/effect/landmark/start/janitor, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aRE" = ( +/obj/item/reagent_containers/food/drinks/trophy/gold_cup, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aRF" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/spooktime/cobble/sideE, +/area/eventmap/outside) +"aRG" = ( +/turf/closed/wall/mineral/iron, +/area/eventmap/mountain) +"aRJ" = ( +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/spooktime/cobble/sideW{ + icon_state = "cobble_side_n" + }, +/area/eventmap/outside) +"aRL" = ( +/obj/item/stack/sheet/metal/fifty, +/turf/open/floor/spooktime/beach/coasts/coastNE, +/area/eventmap/outside) +"aRM" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/spooktime/cobble/sideW{ + icon_state = "cobble_side_n" + }, +/area/eventmap/outside) +"aRN" = ( +/obj/item/flashlight/flare/torch, +/obj/item/flashlight/flare/torch, +/obj/machinery/light/floor{ + CanAtmosPass = 0; + alpha = 0 + }, +/obj/item/umbrella, +/obj/item/pickaxe/mini, +/obj/item/shovel, +/obj/item/hatchet, +/obj/item/storage/box/matches, +/obj/item/storage/fancy/candle_box, +/turf/open/floor/wood, +/area/eventmap/inside) +"aRO" = ( +/obj/structure/cable/pink{ + icon_state = "4-10" + }, +/turf/open/floor/plating, +/area/eventmap/mountain) +"aRP" = ( +/turf/open/floor/wood/damturf/broken2, +/area/eventmap/inside) +"aRS" = ( +/turf/open/floor/plasteel/damturf/damage4, +/area/eventmap/mountaininside) +"aRT" = ( +/obj/item/flashlight/lantern{ + anchored = 1; + can_be_unanchored = 1; + light_color = "#EE9933"; + light_range = 5; + on = 1 + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aRU" = ( +/obj/item/flashlight/lantern{ + anchored = 1; + can_be_unanchored = 1; + light_color = "#EE9933"; + light_range = 5; + on = 1 + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/mountain) +"aRV" = ( +/turf/open/floor/spooktime/beach/coasts/watercoastS, +/area/eventmap/outside) +"aRW" = ( +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/mountain) +"aRX" = ( +/obj/structure/closet/cabinet, +/turf/open/floor/wood, +/area/eventmap/inside) +"aSb" = ( +/obj/item/scythe, +/turf/open/floor/wood, +/area/eventmap/inside) +"aSe" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/vending/clothing, +/turf/open/floor/wood, +/area/eventmap/inside) +"aSg" = ( +/obj/effect/decal/cleanable/dirt, +/obj/item/chair/stool, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"aSi" = ( +/obj/structure/closet{ + name = "Official Clothing" + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aSj" = ( +/obj/item/chair/stool, +/turf/open/floor/wood, +/area/eventmap/inside) +"aSk" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aSl" = ( +/obj/structure/bonfire, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aSn" = ( +/obj/machinery/nanite_program_hub, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aSo" = ( +/turf/open/floor/plating, +/area/eventmap/outside) +"aSq" = ( +/obj/machinery/autolathe/hacked, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aSt" = ( +/obj/item/storage/pill_bottle/zoom, +/turf/open/floor/plasteel/damturf/scorched1, +/area/eventmap/mountaininside) +"aSF" = ( +/obj/structure/curtain{ + color = "#B22222"; + pixel_x = -32 + }, +/turf/open/floor/wood/damturf/broken5, +/area/eventmap/inside) +"aSH" = ( +/obj/machinery/button/door/dorms/luxury3{ + id = "C01"; + pixel_x = -8 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aSK" = ( +/obj/item/storage/daki, +/turf/open/floor/plasteel/damturf/scorched2, +/area/eventmap/mountaininside) +"aSL" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aSM" = ( +/obj/effect/landmark/start/janitor, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aSN" = ( +/obj/structure/bonfire, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aSO" = ( +/obj/effect/landmark/start/station_engineer, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aSP" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aSQ" = ( +/obj/effect/landmark/start/assistant, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aSR" = ( +/obj/item/flashlight/flare, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aSS" = ( +/obj/effect/landmark/start, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aST" = ( +/obj/effect/landmark/start/cyborg, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aSU" = ( +/obj/machinery/rnd/production/protolathe/department/science{ + acted_explosions = "Dumbasses"; + allowed_department_flags = 126; + name = "department protolathe (Dumb powergamers)" + }, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aSV" = ( +/obj/structure/table/reinforced, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"aSW" = ( +/obj/item/a_gift/anything, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aTc" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"aTe" = ( +/obj/structure/mirror{ + pixel_x = 28 + }, +/turf/open/floor/sepia, +/area/eventmap/mountaininside) +"aTi" = ( +/obj/structure/chair/sofa/left, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aTj" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aTm" = ( +/obj/structure/sink/puddle, +/turf/open/floor/spooktime/beach, +/area/eventmap/outside) +"aTn" = ( +/obj/item/integrated_circuit_printer, +/obj/structure/table/plasmaglass, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aTp" = ( +/obj/effect/decal/cleanable/cobweb, +/obj/machinery/vending/kink, +/turf/open/floor/wood, +/area/eventmap/inside) +"aTu" = ( +/obj/item/reagent_containers/food/drinks/bottle/champagne, +/turf/open/floor/wood, +/area/eventmap/inside) +"aTv" = ( +/obj/structure/trap/ctf/nomech, +/turf/open/floor/spooktime/cobble/cornerSE, +/area/eventmap/outside) +"aTw" = ( +/turf/open/floor/spooktime/beach/water, +/area/eventmap/outside) +"aTx" = ( +/obj/item/fugu_gland, +/turf/open/floor/spooktime/beach/coasts/coastN, +/area/eventmap/outside) +"aTA" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aTC" = ( +/turf/closed/wall/r_wall/rust, +/area/eventmap/mountain) +"aTD" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/sign/directions/security{ + dir = 8; + pixel_x = -32; + pixel_y = 24 + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aTE" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/sign/directions/medical{ + dir = 4; + pixel_x = 32; + pixel_y = 24 + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aTG" = ( +/obj/structure/flora/grass/jungle/b, +/obj/structure/flora/tree/jungle, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"aTH" = ( +/obj/machinery/light/small, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aTJ" = ( +/obj/structure/closet, +/obj/item/clothing/suit/hooded/wintercoat/miner, +/obj/item/clothing/shoes/sneakers/brown, +/obj/item/clothing/under/pants/classicjeans, +/obj/item/clothing/neck/scarf, +/obj/item/clothing/neck/stripedgreenscarf, +/obj/item/toy/fluff/tennis_poly/tri/squeak/rainbow, +/obj/item/toy/fluff/tennis_poly, +/obj/item/clothing/suit/hooded/wintercoat/miner, +/obj/item/clothing/shoes/sneakers/brown, +/obj/item/clothing/under/pants/classicjeans, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aTL" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aTM" = ( +/obj/item/soap/syndie, +/turf/open/floor/sepia, +/area/eventmap/mountaininside) +"aTN" = ( +/obj/item/storage/firstaid/tactical, +/turf/open/floor/plasteel/damturf/platdmg1, +/area/eventmap/mountaininside) +"aTO" = ( +/obj/item/stack/sheet/metal/fifty, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aTP" = ( +/obj/structure/mineral_door/wood, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plasteel/stairs, +/area/eventmap/mountaininside) +"aTQ" = ( +/obj/structure/flora/junglebush{ + icon_state = "busha1" + }, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aTS" = ( +/obj/structure/sign/departments/restroom{ + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aTT" = ( +/obj/structure/sign/barsign, +/turf/closed/wall/mineral/wood, +/area/eventmap/mountaininside) +"aTU" = ( +/obj/machinery/power/port_gen/pacman/mrs, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aTV" = ( +/obj/machinery/computer/mech_bay_power_console{ + dir = 1 + }, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aTX" = ( +/turf/open/floor/plasteel/damturf/scorched1, +/area/eventmap/mountaininside) +"aTY" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/indestructible/cobble, +/area/eventmap/outside) +"aUe" = ( +/obj/item/flashlight/seclite, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aUf" = ( +/obj/structure/flora/ausbushes/lavendergrass, +/obj/structure/flora/tree/spookytimexl, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aUi" = ( +/obj/item/storage/pill_bottle/zoom, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aUj" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aUl" = ( +/obj/structure/table, +/obj/item/clothing/mask/gas, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/item/clothing/glasses/sunglasses/big, +/obj/item/clothing/glasses/sunglasses/big, +/obj/item/clothing/glasses/sunglasses/big, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aUn" = ( +/obj/structure/cable/pink{ + icon_state = "5-10" + }, +/turf/open/floor/plating, +/area/eventmap/mountain) +"aUr" = ( +/turf/open/floor/plasteel/damturf/platdmg1, +/area/eventmap/mountaininside) +"aUt" = ( +/obj/item/stack/sheet/mineral/bananium, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"aUu" = ( +/obj/item/storage/firstaid/ancient, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aUx" = ( +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/turf/open/floor/carpet/royalblack, +/area/eventmap/mountain) +"aUy" = ( +/turf/open/floor/spooktime/beach/watersolid, +/area/eventmap/outside) +"aUz" = ( +/obj/structure/flora/grass/jungle/b{ + icon_state = "grassa1" + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/outside) +"aUD" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/drinks/bottle/kahlua, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aUE" = ( +/obj/item/reagent_containers/food/drinks/bottle/rum, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aUK" = ( +/turf/open/floor/plasteel/damturf/scorched, +/area/eventmap/mountaininside) +"aUL" = ( +/obj/structure/spacevine, +/obj/structure/spacevine, +/turf/open/floor/spooktime/beach/watersolid, +/area/eventmap/mountain) +"aUM" = ( +/obj/item/storage/pill_bottle/lsd, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aUP" = ( +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"aUQ" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"aUW" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aUX" = ( +/obj/machinery/button/door/dorms/luxury3{ + id = "C05"; + pixel_y = -24 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aUY" = ( +/obj/structure/trap/ctf/nomech, +/turf/closed/mineral/ash_rock, +/area/eventmap/outside) +"aVd" = ( +/obj/structure/fluff/bus/passable{ + icon_state = "topdoor" + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aVe" = ( +/obj/structure/sign/departments/botany{ + pixel_x = -32 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"aVf" = ( +/obj/machinery/vending/kink, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aVh" = ( +/turf/open/floor/wood/damturf/broken4, +/area/eventmap/inside) +"aVi" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/clockwork/reebe, +/area/eventmap/inside) +"aVj" = ( +/obj/item/coin/diamond, +/obj/item/stack/sheet/mineral/adamantine, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"aVk" = ( +/obj/structure/chair/stool, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aVm" = ( +/obj/item/reagent_containers/food/drinks/bottle/fernet, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aVn" = ( +/obj/machinery/light/small, +/obj/structure/closet/crate/bin, +/turf/open/floor/wood, +/area/eventmap/inside) +"aVo" = ( +/obj/structure/dresser, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aVq" = ( +/obj/item/gun/ballistic/shotgun/lethal, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aVr" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/snacks/beans, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aVt" = ( +/obj/structure/flora/ausbushes/sparsegrass, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aVu" = ( +/obj/item/ammo_box/magazine/wt550m9/wtrubber, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aVv" = ( +/obj/structure/table, +/obj/structure/table, +/obj/item/reagent_containers/food/drinks/bottle/cognac, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aVy" = ( +/obj/item/lighter/greyscale, +/turf/open/floor/wood, +/area/eventmap/inside) +"aVz" = ( +/obj/item/gun/ballistic/automatic/wt550, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aVC" = ( +/obj/item/storage/box/handcuffs, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aVD" = ( +/turf/open/floor/wood/damturf/broken1, +/area/eventmap/mountaininside) +"aVE" = ( +/obj/item/pizzabox/meat, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aVG" = ( +/turf/open/floor/spooktime/beach/watersolid, +/area/eventmap/mountain) +"aVJ" = ( +/turf/open/floor/wood/damturf/broken5, +/area/eventmap/inside) +"aVR" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aVS" = ( +/obj/item/stack/sheet/bluespace_crystal, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aVW" = ( +/obj/machinery/light/small, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aVY" = ( +/obj/structure/spacevine, +/turf/open/floor/spooktime/beach/coasts/coastE, +/area/eventmap/outside) +"aVZ" = ( +/obj/structure/bookcase/manuals/engineering, +/turf/closed/wall/mineral/wood, +/area/eventmap/mountaininside) +"aWd" = ( +/turf/open/floor/spooktime/beach/coasts/coastNW, +/area/eventmap/outside) +"aWf" = ( +/obj/structure/spacevine, +/turf/open/floor/spooktime/beach/water, +/area/eventmap/outside) +"aWi" = ( +/obj/item/reagent_containers/food/snacks/nachos, +/obj/structure/table/reinforced, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aWj" = ( +/obj/structure/bed, +/obj/item/bedsheet/black, +/turf/open/floor/carpet/green, +/area/eventmap/mountaininside) +"aWk" = ( +/obj/item/clothing/head/squatter_hat, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aWl" = ( +/obj/structure/rack, +/obj/item/gun/magic/staff/healing, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aWo" = ( +/obj/structure/bed, +/obj/item/bedsheet/syndie, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aWq" = ( +/obj/structure/curtain{ + color = "#B22222"; + pixel_y = -32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aWs" = ( +/obj/structure/flora/tree/jungle, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aWt" = ( +/obj/structure/spacevine, +/turf/open/floor/spooktime/beach/coasts/coastN, +/area/eventmap/outside) +"aWv" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/eventmap/mountain) +"aWy" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aWz" = ( +/obj/item/reagent_containers/pill/lsd, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aWA" = ( +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"aWJ" = ( +/obj/structure/bed, +/obj/item/bedsheet/hos, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aWL" = ( +/obj/structure/closet/gimmick/russian, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aWN" = ( +/obj/structure/table/plasmaglass, +/obj/item/multitool, +/obj/item/multitool, +/obj/item/multitool, +/obj/item/multitool, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aWO" = ( +/obj/machinery/shower{ + dir = 8; + pixel_y = -4 + }, +/obj/effect/turf_decal/bot_red, +/obj/effect/turf_decal/bot, +/turf/open/floor/sepia, +/area/eventmap/mountaininside) +"aWQ" = ( +/obj/item/stack/sheet/metal/fifty, +/turf/open/floor/spooktime/beach/coasts/coastE, +/area/eventmap/outside) +"aWR" = ( +/obj/item/flashlight/seclite, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aWS" = ( +/turf/open/floor/carpet, +/area/eventmap/mountaininside) +"aWU" = ( +/obj/item/flashlight/glowstick/pink, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aWX" = ( +/obj/structure/closet/crate, +/obj/item/clothing/head/pirate, +/obj/item/clothing/head/santa, +/obj/item/clothing/head/magus, +/obj/item/clothing/head/mailman, +/obj/item/clothing/head/griffin, +/obj/item/clothing/head/bearpelt, +/obj/item/clothing/head/beret, +/obj/item/clothing/head/fedora, +/obj/item/clothing/accessory/skullcodpiece, +/obj/item/clothing/gloves/bracer, +/obj/item/clothing/neck/devilwings, +/turf/open/floor/wood, +/area/eventmap/inside) +"aWY" = ( +/obj/item/stack/sheet/mineral/bananium, +/obj/item/stack/sheet/mineral/bananium, +/obj/item/stack/sheet/mineral/bananium, +/obj/item/stack/sheet/mineral/bananium, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"aWZ" = ( +/turf/open/floor/spooktime/beach/coasts/innerS, +/area/eventmap/outside) +"aXj" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "2-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aXn" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountain) +"aXo" = ( +/obj/item/toy/plush/borgplushie{ + pixel_x = -3; + pixel_y = -4 + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aXq" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + mouse_opacity = 0 + }, +/turf/closed/indestructible/riveted/boss, +/area/eventmap/mountaininside) +"aXs" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/indestructible/airblock, +/area/eventmap/mountaininside) +"aXv" = ( +/obj/structure/bookcase/random/adult, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aXw" = ( +/obj/machinery/door/airlock/vault, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"aXy" = ( +/obj/item/flashlight/lantern{ + anchored = 1; + can_be_unanchored = 1; + light_color = "#EE9933"; + light_range = 5; + on = 1 + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/outside) +"aXz" = ( +/obj/machinery/vending/assist, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aXE" = ( +/obj/item/reagent_containers/food/drinks/bottle/tequila, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aXF" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aXI" = ( +/obj/item/storage/pill_bottle/penis_enlargement, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aXJ" = ( +/obj/item/stack/sheet/mineral/sandstone, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aXK" = ( +/obj/item/reagent_containers/food/drinks/bottle/champagne, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aXM" = ( +/obj/structure/curtain{ + color = "#B22222"; + pixel_x = -32 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aXO" = ( +/obj/structure/table/plasmaglass, +/obj/machinery/chem_dispenser/drinks/beer/fullupgrade{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aXP" = ( +/obj/structure/girder, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aXQ" = ( +/obj/item/flashlight/lantern, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aXR" = ( +/obj/machinery/vending/coffee, +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aXS" = ( +/turf/open/floor/spooktime/beach/coasts/coastS, +/area/eventmap/outside) +"aXU" = ( +/obj/structure/mirror{ + pixel_x = 28 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/shower{ + dir = 8; + pixel_y = -4 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aXX" = ( +/obj/structure/mineral_door/wood, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/inside) +"aXZ" = ( +/obj/item/paicard, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aYa" = ( +/turf/open/floor/spooktime/beach/coasts/watercoastN, +/area/eventmap/outside) +"aYb" = ( +/obj/item/chair, +/turf/open/floor/plasteel/damturf/scorched2, +/area/eventmap/mountaininside) +"aYd" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aYf" = ( +/obj/item/reagent_containers/food/drinks/bottle/cream, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aYh" = ( +/obj/item/reagent_containers/food/snacks/sashimi, +/obj/structure/table/reinforced, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aYi" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aYp" = ( +/obj/structure/chair/sofa/left, +/obj/item/flashlight/seclite, +/turf/open/floor/carpet/red, +/area/eventmap/mountaininside) +"aYr" = ( +/obj/structure/chair/sofa, +/turf/open/floor/carpet/red, +/area/eventmap/mountaininside) +"aYs" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/drinks/bottle/trappist, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aYw" = ( +/obj/item/restraints/handcuffs, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aYy" = ( +/turf/open/floor/plasteel/showroomfloor, +/area/eventmap/mountaininside) +"aYz" = ( +/obj/item/restraints/handcuffs, +/turf/open/floor/plasteel/damturf/scorched2, +/area/eventmap/mountaininside) +"aYA" = ( +/obj/structure/table, +/obj/item/lighter/greyscale, +/turf/open/floor/wood, +/area/eventmap/inside) +"aYG" = ( +/obj/structure/spacevine, +/obj/structure/spacevine, +/obj/structure/spacevine, +/obj/structure/spacevine, +/obj/structure/spacevine, +/obj/structure/spacevine, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aYH" = ( +/obj/item/reagent_containers/food/drinks/bottle/sake, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aYI" = ( +/obj/structure/flora/tree/spookytime, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aYJ" = ( +/obj/item/coin/diamond, +/obj/item/stack/sheet/mineral/mythril, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"aYM" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel/damturf/scorched1, +/area/eventmap/mountaininside) +"aYO" = ( +/obj/item/stack/sheet/mineral/sandstone/thirty, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aYQ" = ( +/turf/open/floor/spooktime/beach/coasts/watercoastSW, +/area/eventmap/outside) +"aYT" = ( +/obj/structure/mineral_door/wood, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03{ + id = "C11" + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aYU" = ( +/obj/item/storage/fancy/cigarettes/cigpack_mindbreaker, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aYV" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/bottle/tequila, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aYW" = ( +/obj/machinery/door/airlock/wood/glass, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aYY" = ( +/obj/item/reagent_containers/food/drinks/bottle/trappist, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aZa" = ( +/obj/structure/chair/comfy{ + dir = 1 + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aZb" = ( +/obj/item/reagent_containers/food/snacks/powercrepe, +/obj/structure/table/reinforced, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aZg" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aZi" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/structure/table/plasmaglass, +/obj/machinery/chem_dispenser/drinks/fullupgrade{ + dir = 8 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aZj" = ( +/obj/structure/chair/comfy/brown{ + dir = 4 + }, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aZk" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountaininside) +"aZm" = ( +/obj/item/reagent_containers/food/snacks/scotchegg, +/obj/structure/table/reinforced, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aZo" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/spooktime/cobble/sideN, +/area/eventmap/outside) +"aZr" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/turf/open/indestructible/airblock, +/area/eventmap/mountaininside) +"aZt" = ( +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aZv" = ( +/obj/structure/bed, +/obj/item/bedsheet/blue, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aZx" = ( +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + mouse_opacity = 0 + }, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"aZz" = ( +/obj/item/reagent_containers/food/drinks/bottle/wine, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aZA" = ( +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aZB" = ( +/obj/structure/bonfire, +/turf/open/floor/wood, +/area/eventmap/inside) +"aZC" = ( +/obj/item/flashlight, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aZE" = ( +/obj/structure/bed/dogbed, +/turf/open/floor/wood, +/area/eventmap/mountaininside) +"aZH" = ( +/obj/structure/sign/directions/security{ + dir = 1 + }, +/obj/structure/sign/directions/command{ + dir = 1; + pixel_y = 8 + }, +/obj/structure/sign/directions/supply{ + dir = 1; + pixel_y = -8 + }, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"aZI" = ( +/obj/item/lighter, +/turf/open/floor/carpet/green, +/area/eventmap/mountaininside) +"aZJ" = ( +/obj/item/lipstick/random, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"aZK" = ( +/obj/structure/sign/directions/science{ + dir = 4 + }, +/obj/structure/sign/directions/engineering{ + pixel_y = -8 + }, +/obj/structure/sign/directions/medical{ + dir = 1; + pixel_y = 8 + }, +/turf/closed/wall/mineral/wood, +/area/eventmap/inside) +"aZL" = ( +/obj/structure/cable/pink{ + icon_state = "1-6" + }, +/turf/open/floor/plating, +/area/eventmap/mountain) +"aZM" = ( +/obj/structure/flora/bush, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"aZN" = ( +/obj/structure/fluff/broken_flooring, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"aZP" = ( +/obj/structure/trap/ctf/nomech, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/outside) +"aZQ" = ( +/obj/structure/mineral_door/wood, +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03{ + id = "C01" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"aZS" = ( +/obj/structure/spacevine, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"aZU" = ( +/obj/machinery/vending/coffee, +/turf/open/floor/wood{ + icon_state = "wood-broken3" + }, +/area/eventmap/inside) +"aZW" = ( +/obj/machinery/mech_bay_recharge_port, +/obj/machinery/light/floor{ + alpha = 0; + light_range = 20; + max_integrity = 9999; + mouse_opacity = 0 + }, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"baa" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"bas" = ( +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_y = -35 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"baX" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"bbi" = ( +/obj/effect/turf_decal/caution/stand_clear{ + dir = 8; + pixel_x = -8 + }, +/obj/docking_port/stationary{ + dir = 4; + dwidth = 8; + height = 7; + id = "supply_home"; + name = "Cargo Bay"; + width = 20 + }, +/turf/open/floor/plasteel, +/area/eventmap/outside) +"bbt" = ( +/obj/structure/fence/corner{ + dir = 4 + }, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"bbv" = ( +/obj/structure/fence{ + dir = 8 + }, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"bbx" = ( +/turf/open/floor/plasteel, +/area/eventmap/outside) +"bby" = ( +/obj/effect/turf_decal/caution/stand_clear{ + dir = 1; + pixel_y = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/outside) +"bbD" = ( +/obj/effect/turf_decal/caution/stand_clear{ + dir = 8; + pixel_x = -8 + }, +/turf/open/floor/plasteel, +/area/eventmap/outside) +"bbE" = ( +/obj/effect/turf_decal/caution/stand_clear{ + dir = 4; + pixel_x = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/outside) +"bbG" = ( +/obj/structure/sign/mining{ + pixel_x = 32 + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/outside) +"bbI" = ( +/obj/effect/turf_decal/caution/stand_clear{ + pixel_y = -8 + }, +/turf/open/floor/plasteel, +/area/eventmap/outside) +"bbJ" = ( +/obj/structure/fence/corner{ + dir = 1 + }, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"bbK" = ( +/obj/structure/fence/corner, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"bbL" = ( +/obj/structure/fence{ + dir = 8 + }, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"bbM" = ( +/obj/structure/fence/corner{ + dir = 4 + }, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"bbP" = ( +/obj/structure/fence/corner{ + dir = 9 + }, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"bbZ" = ( +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"bcb" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"bcd" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"bce" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"bci" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/indestructible/cobble, +/area/eventmap/outside) +"bck" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/indestructible/cobble, +/area/eventmap/outside) +"bcn" = ( +/turf/open/floor/plating, +/area/eventmap/mountain) +"bco" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/caution{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountain) +"bcp" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountain) +"bcq" = ( +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/indestructible/cobble, +/area/eventmap/outside) +"bcx" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountain) +"bcJ" = ( +/obj/structure/sign/directions/security{ + pixel_x = -32; + pixel_y = -36 + }, +/obj/structure/sign/directions/supply{ + dir = 8; + pixel_x = -32; + pixel_y = -28 + }, +/turf/open/floor/spooktime/cobble/sideW, +/area/eventmap/outside) +"bdh" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/eventmap/mountain) +"bdm" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/eventmap/outside) +"bds" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/caution{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/outside) +"bdy" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/eventmap/mountain) +"bdz" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/structure/cable/white{ + icon_state = "2-4" + }, +/turf/open/floor/plating, +/area/eventmap/mountain) +"bdA" = ( +/obj/structure/cable/white{ + icon_state = "1-8" + }, +/turf/open/floor/plating, +/area/eventmap/mountain) +"bdC" = ( +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/turf/open/floor/plating, +/area/eventmap/mountain) +"bdI" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plating, +/area/eventmap/mountain) +"bdL" = ( +/obj/structure/fence/door, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"bdN" = ( +/obj/structure/closet/crate/bin, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"bdO" = ( +/obj/structure/chair/sofa/right, +/obj/item/toy/cards/deck/cas, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"bdP" = ( +/obj/structure/chair/sofa, +/obj/item/toy/cards/deck/syndicate, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"bdQ" = ( +/obj/structure/chair/sofa/left, +/obj/item/toy/cards/deck/cas/black, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"bdR" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/computer/shuttle/mining, +/turf/open/floor/plasteel, +/area/eventmap/outside) +"bea" = ( +/obj/machinery/light/small{ + dir = 4; + light_color = "#d8b1b1" + }, +/turf/open/floor/spooktime/dirtpatch, +/area/eventmap/mountain) +"bef" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"bey" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/table/wood, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"beA" = ( +/obj/structure/chair/sofa/left{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"beB" = ( +/obj/structure/chair/sofa{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"beE" = ( +/obj/structure/chair/sofa/right{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"beF" = ( +/obj/structure/table/wood, +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"beG" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"beH" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/wood/damturf/broken4, +/area/eventmap/inside) +"beI" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"beJ" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/carpet, +/area/eventmap/inside) +"beK" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/wood, +/area/eventmap/inside) +"bfd" = ( +/obj/machinery/door/airlock{ + name = "Unisex Showers" + }, +/turf/open/floor/plasteel{ + icon_state = "sepia" + }, +/area/eventmap/inside) +"bfA" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/carpet, +/area/eventmap/inside) +"bfB" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/carpet, +/area/eventmap/inside) +"bfC" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/eventmap/inside) +"bfD" = ( +/obj/structure/chair/sofa/right, +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/eventmap/inside) +"bfE" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/eventmap/inside) +"bfF" = ( +/obj/effect/decal/cleanable/dirt{ + desc = "A thin layer of dust coating the floor."; + name = "dust" + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/eventmap/inside) +"bfG" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/disposalpipe/segment, +/turf/open/floor/wood, +/area/eventmap/inside) +"bfH" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/spooktime/nonspooktimegrass, +/area/eventmap/outside) +"bfI" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/spooktime/cobble/sideW{ + icon_state = "cobble_side_n" + }, +/area/eventmap/outside) +"bfJ" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/spooktime/cobble, +/area/eventmap/outside) +"bfK" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/spooktime/cobble/sideS, +/area/eventmap/outside) +"bfL" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"bfM" = ( +/obj/effect/landmark/start/janitor, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/spooktime/cobble/roadmid, +/area/eventmap/outside) +"bgc" = ( +/obj/item/banner/cargo, +/turf/open/floor/spooktime/cobble/sideN, +/area/eventmap/outside) +"bgu" = ( +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/spooktime/spooktimegrass, +/area/eventmap/outside) +"bgw" = ( +/obj/structure/sign/mining{ + pixel_x = -32 + }, +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/spooktime/cobble/sideN, +/area/eventmap/outside) +"bgx" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/spooktime/cobble/sideN, +/area/eventmap/outside) +"bgA" = ( +/obj/effect/turf_decal/caution/stand_clear{ + dir = 8; + pixel_x = -8 + }, +/obj/docking_port/stationary{ + dir = 4; + dwidth = 3; + height = 5; + id = "mining_home"; + name = "mining shuttle bay"; + roundstart_template = /datum/map_template/shuttle/mining/delta; + width = 7 + }, +/turf/open/floor/plasteel, +/area/eventmap/outside) +"bjJ" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/eventmap/mountaininside) +"bLA" = ( +/turf/closed/wall/r_wall, +/area/tcommsat/server) +"bXE" = ( +/obj/machinery/rnd/production/protolathe/department/science{ + acted_explosions = "Dumbasses"; + allowed_department_flags = 126; + name = "department protolathe (Dumb powergamers)" + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"car" = ( +/obj/machinery/telecomms/bus/preset_four, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"cjF" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"cvj" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/eventmap/mountaininside) +"cvE" = ( +/obj/machinery/telecomms/server/presets/command, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"cRF" = ( +/obj/machinery/telecomms/bus/preset_three, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"dbo" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"dcr" = ( +/obj/machinery/computer/telecomms/server{ + dir = 4; + network = "tcommsat" + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"dgN" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/tcommsat/computer) +"dgR" = ( +/obj/machinery/telecomms/broadcaster/preset_right, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"dqu" = ( +/obj/machinery/power/terminal{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"dsM" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"dyx" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/airlock/engineering/glass{ + name = "Server Room"; + req_access_txt = "61" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/tcommsat/computer) +"dzl" = ( +/obj/machinery/gear_painter, +/turf/open/floor/circuit/off, +/area/eventmap/mountaininside) +"dBJ" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/tcommsat/computer) +"egY" = ( +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"eAQ" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"eGa" = ( +/obj/machinery/telecomms/broadcaster/preset_left, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"ePO" = ( +/obj/structure/table, +/obj/item/radio/off, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"eVF" = ( +/obj/item/radio/intercom{ + dir = 8; + freerange = 1; + name = "Station Intercom (Telecomms)"; + pixel_y = 26 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"eYC" = ( +/obj/structure/table, +/obj/item/multitool, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"fMI" = ( +/obj/machinery/telecomms/receiver/preset_left, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"fRV" = ( +/obj/machinery/requests_console{ + announcementConsole = 1; + department = "Telecomms Admin"; + departmentType = 5; + name = "Telecomms RC"; + pixel_x = 30 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"fSV" = ( +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"fXv" = ( +/obj/structure/rack, +/obj/item/storage/toolbox/mechanical{ + pixel_x = -2; + pixel_y = -1 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"giz" = ( +/obj/machinery/telecomms/hub/preset, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"gkE" = ( +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/obj/machinery/light, +/obj/structure/filingcabinet/chestdrawer, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"gra" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"gIM" = ( +/obj/machinery/computer/telecomms/server{ + dir = 4; + network = "tcommsat" + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"gRm" = ( +/obj/machinery/telecomms/bus/preset_four, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"gUn" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/tcommsat/server"; + dir = 1; + name = "Telecomms Server APC"; + pixel_y = 23 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"hbO" = ( +/obj/machinery/telecomms/processor/preset_four, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"hqz" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"hvj" = ( +/obj/machinery/telecomms/server/presets/engineering, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"hzN" = ( +/obj/machinery/door/airlock/command/glass{ + name = "Control Room"; + req_access_txt = "19; 61" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"hFm" = ( +/obj/machinery/ntnet_relay, +/turf/open/floor/circuit/telecomms/mainframe, +/area/eventmap/mountaininside) +"hPo" = ( +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"hWE" = ( +/obj/machinery/telecomms/receiver/preset_right, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"idT" = ( +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_y = -35 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/effect/landmark/event_spawn, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"ihd" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"ihT" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/airlock/engineering/glass{ + name = "Server Room"; + req_access_txt = "61" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"ina" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/airlock/engineering/glass{ + name = "Server Room"; + req_access_txt = "61" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"itL" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"iuT" = ( +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"iuW" = ( +/obj/item/disk/tech_disk/debug, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"iwi" = ( +/obj/machinery/telecomms/server/presets/security, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"iHS" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/announcement_system, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"iNH" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"iNN" = ( +/obj/machinery/camera{ + c_tag = "Telecomms Server Room"; + dir = 4; + network = list("tcomms") + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"iPO" = ( +/obj/machinery/telecomms/server/presets/service, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"iTX" = ( +/obj/machinery/power/smes{ + charge = 5e+006 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"iWA" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/airlock/engineering/glass{ + name = "Server Room"; + req_access_txt = "61" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/tcommsat/computer) +"jox" = ( +/obj/machinery/telecomms/processor/preset_two, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"jru" = ( +/obj/machinery/telecomms/processor/preset_one, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"jEF" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"jNZ" = ( +/obj/machinery/computer/message_monitor{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"jUY" = ( +/obj/machinery/telecomms/server/presets/science, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"kte" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"kBF" = ( +/obj/structure/closet/emcloset, +/obj/machinery/camera{ + c_tag = "Telecomms Monitoring"; + dir = 8; + network = list("tcomms") + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"kDK" = ( +/obj/machinery/telecomms/server/presets/science, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"kRw" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/tcommsat/computer) +"kWj" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/tcommsat/computer) +"liD" = ( +/obj/item/radio/intercom{ + dir = 8; + freerange = 1; + name = "Station Intercom (Telecomms)"; + pixel_y = 26 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"liZ" = ( +/obj/item/aiModule/reset/purge, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"lxA" = ( +/obj/machinery/blackbox_recorder, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"lCx" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"lES" = ( +/obj/structure/table, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"lJN" = ( +/obj/machinery/telecomms/message_server, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"lJV" = ( +/obj/machinery/telecomms/processor/preset_one, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"lRv" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable, +/turf/open/floor/plating, +/area/tcommsat/computer) +"mpZ" = ( +/obj/machinery/telecomms/bus/preset_three, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"mvm" = ( +/obj/machinery/telecomms/bus/preset_one, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"myC" = ( +/obj/machinery/telecomms/broadcaster/preset_right, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"mDp" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/tcommsat/computer) +"mJd" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/machinery/ore_silo, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"mNu" = ( +/obj/machinery/light, +/turf/open/floor/circuit/telecomms/mainframe, +/area/eventmap/mountaininside) +"nxt" = ( +/obj/machinery/telecomms/server/presets/common, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"nOO" = ( +/obj/machinery/telecomms/server/presets/engineering, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"nUS" = ( +/obj/machinery/telecomms/hub/preset, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/eventmap/mountaininside) +"ooP" = ( +/obj/machinery/door/airlock/engineering{ + name = "Telecommunications"; + req_access_txt = "61" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"ouD" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"oBM" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"oLt" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"oPH" = ( +/obj/machinery/telecomms/server/presets/supply, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"oTm" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"paH" = ( +/obj/structure/rack, +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/plating, +/area/maintenance/port/aft) +"psG" = ( +/obj/machinery/camera{ + c_tag = "Telecomms Server Room"; + dir = 4; + network = list("tcomms") + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"pur" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"pxt" = ( +/turf/closed/wall/r_wall, +/area/tcommsat/computer) +"pDy" = ( +/obj/machinery/telecomms/bus/preset_one, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"pIk" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/holopad/secure, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"pOM" = ( +/obj/machinery/power/terminal{ + dir = 1 + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"pYH" = ( +/obj/machinery/power/smes{ + charge = 5e+006 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/eventmap/mountaininside) +"qbF" = ( +/obj/machinery/computer/telecomms/monitor{ + dir = 4; + network = "tcommsat" + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"qhF" = ( +/obj/machinery/light_switch{ + pixel_x = 27 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"qqG" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"qsw" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/tcommsat/computer) +"qtw" = ( +/obj/machinery/light, +/obj/machinery/computer/upload/ai{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"quU" = ( +/obj/machinery/telecomms/server/presets/medical, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"qyu" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"qJf" = ( +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"qQZ" = ( +/obj/structure/table, +/obj/item/paper_bin, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/obj/item/pen/fountain, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"qTn" = ( +/obj/machinery/camera{ + c_tag = "Telecomms Monitoring"; + dir = 8; + network = list("tcomms") + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"qUm" = ( +/obj/item/aiModule/supplied/freeform, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"qWJ" = ( +/obj/machinery/telecomms/receiver/preset_right, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"qYa" = ( +/obj/machinery/computer/message_monitor{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"rjg" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/eventmap/mountaininside) +"rwN" = ( +/obj/machinery/telecomms/receiver/preset_left, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"rxi" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"rSf" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/eventmap/mountaininside) +"rTJ" = ( +/obj/machinery/telecomms/message_server, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"slE" = ( +/obj/effect/landmark/start/ai, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"ssq" = ( +/turf/open/floor/circuit/telecomms/mainframe, +/area/eventmap/mountaininside) +"sCi" = ( +/obj/machinery/telecomms/server/presets/supply, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"sJq" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/eventmap/mountaininside) +"sJF" = ( +/obj/machinery/telecomms/bus/preset_two, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"sOw" = ( +/obj/machinery/requests_console{ + announcementConsole = 1; + department = "Telecomms Admin"; + departmentType = 5; + name = "Telecomms RC"; + pixel_x = 30 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"sZY" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plating, +/area/tcommsat/computer) +"tHV" = ( +/obj/machinery/light_switch{ + pixel_x = 27 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"tTs" = ( +/obj/machinery/telecomms/server/presets/common, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"uaU" = ( +/obj/machinery/telecomms/processor/preset_two, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"ubo" = ( +/obj/machinery/ntnet_relay, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"uhq" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/tcommsat/computer) +"ukf" = ( +/obj/machinery/computer/telecomms/monitor{ + dir = 4; + network = "tcommsat" + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"unw" = ( +/obj/machinery/telecomms/broadcaster/preset_left, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"upB" = ( +/obj/structure/table, +/obj/item/folder/blue, +/obj/item/pen/blue, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"uEU" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"uLJ" = ( +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/eventmap/mountaininside) +"uMt" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"vdv" = ( +/obj/structure/sign/warning/securearea{ + desc = "A warning sign which reads 'SERVER ROOM'."; + name = "SERVER ROOM" + }, +/turf/closed/wall, +/area/eventmap/mountaininside) +"vft" = ( +/obj/machinery/status_display/evac, +/turf/closed/wall, +/area/tcommsat/computer) +"vgd" = ( +/obj/machinery/status_display/evac, +/turf/closed/wall, +/area/eventmap/mountaininside) +"voq" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"vFK" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/tcommsat/computer) +"vMZ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"vQI" = ( +/obj/machinery/telecomms/server/presets/security, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"vUD" = ( +/obj/structure/sign/warning/nosmoking{ + pixel_y = -32 + }, +/obj/machinery/light, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) +"vYv" = ( +/obj/machinery/telecomms/bus/preset_two, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"vZx" = ( +/obj/machinery/telecomms/server/presets/service, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"wcR" = ( +/obj/item/paper/crumpled/bloody{ + name = "ominous note"; + info = "You're not supposed to be here." + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"wxX" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"wzn" = ( +/obj/structure/table, +/obj/item/multitool, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"wAF" = ( +/obj/machinery/telecomms/server/presets/command, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"wCg" = ( +/obj/machinery/telecomms/server/presets/medical, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"wHZ" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/tcommsat/computer) +"wYP" = ( +/obj/structure/sign/warning/securearea{ + desc = "A warning sign which reads 'SERVER ROOM'."; + name = "SERVER ROOM" + }, +/turf/closed/wall, +/area/tcommsat/computer) +"xmW" = ( +/obj/machinery/gear_painter, +/turf/open/floor/carpet/blue, +/area/eventmap/inside) +"xzS" = ( +/obj/machinery/telecomms/processor/preset_three, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"xAi" = ( +/obj/machinery/computer/rdconsole/core{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"xDg" = ( +/obj/machinery/telecomms/processor/preset_three, +/turf/open/floor/plasteel/dark, +/area/eventmap/mountaininside) +"xEk" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/eventmap/mountaininside) +"xYl" = ( +/obj/item/stack/sheet/glass/fifty{ + amount = 10000; + max_amount = 10000 + }, +/obj/item/stack/sheet/bluespace_crystal{ + amount = 10000; + max_amount = 10000 + }, +/obj/item/stack/sheet/metal{ + amount = 10000; + max_amount = 10000 + }, +/obj/item/stack/sheet/mineral/diamond{ + amount = 10000; + max_amount = 10000 + }, +/obj/item/stack/sheet/mineral/gold{ + amount = 10000; + max_amount = 10000 + }, +/obj/item/stack/sheet/mineral/plasma{ + amount = 10000; + max_amount = 10000 + }, +/obj/item/stack/sheet/mineral/silver{ + amount = 10000; + max_amount = 10000 + }, +/obj/item/stack/sheet/mineral/titanium{ + amount = 10000; + max_amount = 10000 + }, +/obj/item/stack/sheet/mineral/uranium{ + amount = 10000; + max_amount = 10000 + }, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"xYn" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/tcommsat/computer) +"yhC" = ( +/obj/machinery/telecomms/processor/preset_four, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) +"yjc" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/announcement_system, +/turf/open/floor/plasteel, +/area/eventmap/mountaininside) +"ykK" = ( +/obj/machinery/blackbox_recorder, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) + +(1,1,1) = {" +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +ayN +ayN +ayN +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +"} +(2,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aWA +aWA +aWA +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(3,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aWA +aWA +aWA +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(4,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aLg +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aZS +aZS +aZS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aqr +aOc +aOo +aOu +aOx +aOK +aOP +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aZS +aWA +aWA +aWA +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aZS +aZS +aZS +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(5,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +abH +abH +abH +abH +abH +abH +abH +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTC +aXn +aXn +aXn +aTC +aac +aac +aac +aqr +aOd +aOp +aqr +aOB +aOE +aOS +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +ags +aZS +aZS +aac +aac +aac +aac +aZS +aZS +aWA +aWA +aWA +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +aZS +aZS +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(6,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +abH +abR +aes +acV +aiS +apL +abH +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aWv +bcn +bcn +bcn +bcx +aac +aac +aac +aqr +aqr +aqr +aqr +aOG +aOM +aBm +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aZS +aZS +ayV +ayV +aZS +ags +aWA +aWA +aWA +ags +ags +ags +aFq +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(7,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +abH +acF +abR +aev +apL +aBB +abH +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aZS +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aWv +bcn +bcn +bcn +bcx +aac +aac +aac +aqr +aOe +aOq +aqr +alO +aOE +aOU +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ayV +aZS +ags +ags +aWA +aWA +aWA +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(8,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +abH +acV +aet +aex +apX +acV +abH +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aWv +bcn +bcn +bcn +bcx +aac +aac +aac +aqr +aOg +aOs +aOv +aOE +aON +aBm +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +ayV +ags +aWA +aWA +aWA +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aZS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(9,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +abH +adz +aer +aey +auE +aCt +abH +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTC +bco +bcp +bco +aTC +aac +aac +aac +aqr +aqr +aqr +aqr +aOJ +aqr +aOV +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aWA +aWA +aWA +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(10,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +abH +aer +aeu +acV +aBu +auE +abH +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +bdN +aMn +bdy +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aWA +aWA +aWA +ags +ags +ags +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +ags +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(11,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +abH +abH +abH +aeH +abH +abH +abH +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +ags +ags +ags +ags +aac +aac +ags +ags +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aLY +aac +aac +aac +aac +aac +ags +ags +ags +alv +awd +afw +afw +afw +afw +awd +aac +aac +ags +bdy +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aLY +ags +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aWA +aWA +aWA +ags +ags +ags +ags +aEL +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +ags +ags +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(12,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +ags +ags +ags +ags +ags +aZS +aZS +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aLY +aZS +aZS +aZS +aZS +asM +ags +ags +ags +bcn +aNj +aNr +aNr +aNP +aOh +afw +aac +bdO +ags +bdy +aTC +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aWA +aWA +aWA +ags +ags +ags +ags +ags +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +ags +ags +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(13,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +ags +aZS +ags +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTC +aKA +ags +ags +ags +bdL +ags +ags +ags +bcn +aNn +aNs +arO +aNQ +aOi +afw +aac +bdP +ags +bdy +aMn +ags +ags +ags +ags +alv +aTC +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aWA +aWA +aWA +ags +ags +ags +ags +aZS +aZS +aZS +ags +ags +ags +ags +ags +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(14,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aEU +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aRE +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +afw +aNy +aND +aNQ +aOm +afw +bdI +bdQ +ags +bdz +bdh +bdh +bdh +bdh +bdh +bdC +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aFw +aFw +aFw +aFw +aFw +aFw +aac +aac +aac +aWA +aWA +aWA +ags +ags +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +ags +ags +ags +aac +aac +aac +aZS +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(15,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aEU +aEU +aEU +aEU +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aGn +ags +ags +aFV +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +afw +aNB +aND +aNU +aOn +aOt +bdh +bdh +bdh +bdA +ags +ags +ags +aac +bea +bdy +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aad +aZA +aOC +aZA +aFm +aFw +aac +aac +aac +aWA +aWA +aWA +aaN +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aZS +aac +aac +ags +ags +aac +aED +aED +aED +aED +aED +aED +aED +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(16,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aEU +aEU +aEU +aEU +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ayV +aac +aac +aac +aac +aIV +aIV +aac +aac +aac +aac +aac +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +awd +afw +aND +aNW +aNs +aNn +bcn +ags +ags +ags +aZS +aac +aac +aac +aFd +aPN +aGG +aGG +aGG +aGG +aFd +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aOb +aZA +aZA +aZA +aFm +aFw +aac +aac +aac +aWA +aWA +aWA +ags +aaN +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +ags +aac +aac +aED +aMp +aPl +aFy +aMp +aVo +aED +aac +aac +aac +aZS +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(17,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aEU +aXo +aEU +aEU +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJG +ags +ags +aEb +ags +aUu +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aaN +aaN +aaN +aaN +aIV +aaN +aaN +aac +aac +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aLU +aLU +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +afw +aNM +aNX +afw +awd +aac +ags +ags +aZS +aZS +aac +aac +aac +aGG +aPQ +aPQ +aPQ +aPQ +aPQ +aGG +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aTU +aZA +aQq +aZA +aPM +aFw +aac +aac +aac +aWA +aWA +aWA +aaN +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aJk +ags +ags +aUe +aac +aac +aac +aac +aac +ags +aac +aac +aED +aUj +aMp +aMp +aMp +aVW +aED +aac +aac +aac +aZS +ags +aac +aac +aac +aac +aac +aac +ags +aac +aac +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(18,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aEU +aEU +aEU +aEU +aEU +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aSl +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aIV +aIV +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aLU +bbG +aLU +aLU +aLU +aLU +aLU +aac +aac +aac +aac +aRv +afw +aNN +aOa +afw +aac +aac +aac +ags +ags +aac +aac +aac +aac +aGG +aPQ +aPQ +aPQ +aPQ +aPQ +aGG +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aZA +aZA +aRm +aZJ +aZA +aFw +aac +aac +awo +aWA +aWA +aWA +aaN +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +ags +aac +aac +aED +aMp +aGB +aWJ +aMp +aDG +aED +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +ags +aac +aac +aIa +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(19,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aEU +aEU +aEU +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aCN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aIV +aIV +aaN +aIV +aIV +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aac +aaN +aaN +aaw +aaw +acG +aaw +aaw +aaw +aaw +aaw +aLU +aLU +aLU +aLU +aLU +aLU +bgw +aCI +bck +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aGG +aPQ +aPQ +aPQ +aPQ +aPQ +aGG +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aHd +aZA +aZA +aZA +aZA +aFw +aFw +aRJ +ayO +aWA +aWA +aWA +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +azZ +ags +aEb +ags +ags +aac +aac +aac +aac +aac +ags +aac +aac +aED +aKg +aED +aED +aRw +aED +aED +aac +aac +aac +aac +aZS +ags +aac +aac +aac +aac +aac +ags +ags +aac +aIa +aGh +aZr +aJl +apu +aJl +aJl +aJl +aJl +aJl +aZr +aJl +aJl +aJl +aJl +aZr +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(20,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aIV +aIV +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaw +aaO +auU +adt +aew +arD +azw +aaw +aaw +aaw +aaw +aaw +aaw +aaw +bgc +aCI +bck +aac +aac +aac +bdR +bds +bdm +aac +aac +aac +aac +aGG +aPQ +aPQ +aPQ +aPQ +aPQ +aGG +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +amD +aSg +aRB +aZA +aRB +aTL +aTP +aRd +aGM +aRo +aWA +aWA +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aUM +ags +ags +ags +ags +ags +aac +aac +aac +aac +ags +aac +aac +aED +aYy +aJC +aED +aMp +aXR +aED +aac +aac +aac +aac +aZS +ags +aac +aac +aac +aac +aac +ags +ags +aac +aIa +aGh +aJl +aZr +aJl +aJl +aJl +aZr +aJl +apu +aJl +aJl +aJl +aJl +apu +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +aJx +"} +(21,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aSl +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aIV +aIV +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaw +abk +auU +auU +ahp +arO +auU +aJN +aMj +aMt +aMH +aMP +aMV +aaw +aqk +aCI +bck +bbL +aaN +bbx +bbx +bbx +bgA +bbx +bbx +bbx +aac +aGG +aPQ +aPQ +aPR +aPQ +aPQ +aGG +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aSV +aSV +aHE +aUK +aZA +aFw +aFw +aRM +ayO +aWA +aSL +aWA +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aSl +ags +ags +aVE +ags +aac +aac +aac +aac +ags +ags +aac +aED +aIu +aRq +aED +aMp +aAZ +aED +aac +aac +aac +aac +aZS +ags +aac +aac +aac +aac +aac +ags +ags +aac +aIa +aGh +aJl +aJl +aZr +aPi +aZr +aJl +aJl +aJl +aJl +aJl +aPi +aJl +aJl +aZr +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(22,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaw +abt +auU +auU +aoO +asc +auU +aJR +aMk +aND +auU +auU +auU +aNo +aCI +aCI +bck +bbL +aaN +bbx +aSo +aSo +aSo +aSo +aSo +bbx +aac +aFd +aGG +aGG +aGG +aGG +aGG +aFd +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aFw +aFw +aFw +aFw +aFw +aFw +aac +aph +ayO +aWA +aSL +aWA +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aAA +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +aac +aED +aED +aED +aED +aMp +aMp +aED +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +ags +ags +aac +aIa +aGh +aJl +aCM +aJl +aPi +aJl +aJl +aPi +aPi +aJl +aJl +aPi +aJl +aCM +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(23,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaw +abI +acR +adx +aRn +asE +aDm +aJT +aMm +aMx +aMJ +aMQ +aMJ +aNp +aZo +bci +bcq +bbL +aaN +bby +aSo +aSo +aSo +aSo +aSo +bbI +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aph +ayO +aWA +aSL +aWA +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aCl +aac +aac +aac +aac +aac +aac +ags +ags +aac +aVZ +aER +aMp +aAQ +aMp +aKM +aED +ags +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +aac +aIa +aGh +aJl +aCM +aJl +aPi +aXs +aXs +aPi +aPi +aJl +aZr +aPi +aJl +aCM +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(24,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaw +aaw +aRn +aaw +aaw +asF +aaw +aaw +aaw +aMA +auU +auU +auU +aNo +aCI +aCI +bck +bbL +aaN +bbx +aSo +aSo +aSo +aSo +aSo +bbx +bbv +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aph +ayO +aWA +aSL +aWA +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aNF +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +aac +aQg +aTi +aMp +aMp +aMp +aMp +aYT +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +aac +aIa +aGh +aJl +aCM +aJl +aPi +aJl +aZr +aJl +aJl +aJl +aJl +aPi +aJl +aCM +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(25,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ayV +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaw +aCi +auU +auU +arC +atG +aIE +aKX +aMr +aCi +auU +aMT +aMY +aaw +aqk +aCI +bck +bbL +aaN +bbx +bbx +bbx +bbE +bbx +bbx +bbx +bbv +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aac +aac +aac +aaN +aaN +aWs +aaN +aph +ayO +aWA +aSL +aWA +aKq +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +aac +aED +aMz +aMz +aED +aED +aED +abe +aKA +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +aac +aIa +aGh +aJl +aJl +aJl +aJl +aJl +aZr +aJl +aJl +apu +aJl +aJl +aJl +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(26,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ayV +aZS +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaw +aCi +auU +aei +auU +auU +auU +aMi +aaw +aaw +aML +aaw +aaw +aaw +bgc +aCI +bck +bbM +avS +avS +avS +avS +avS +avS +avS +avS +bbK +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aSL +aWA +aKq +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +aac +aIa +aGh +aJl +apu +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(27,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aZS +ags +ags +ags +ags +ags +ags +ags +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ayV +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaw +acs +add +adt +auU +auU +auU +auU +auU +auU +auU +aMU +aMD +aaw +aKP +aCI +bck +aCI +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awo +aaN +aaN +aaN +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +aac +aIa +aGh +aJl +aJl +aJl +aPi +aPi +aPi +aJl +aJl +aJl +aJl +aPi +aPi +aZr +aZr +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aJx +"} +(28,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aZS +aZS +ags +ags +ags +ags +ags +ags +aac +aac +aZS +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +ags +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaw +aCi +auU +adt +auU +aut +auU +auU +auU +auU +auU +aMU +aMZ +aaw +bgx +aCI +aOA +bci +anq +anq +anq +anq +anq +anq +anq +anq +anq +anq +anq +bbZ +ayO +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aaN +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +ayV +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +ags +ags +ags +ags +aSl +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +aac +aIa +aGh +aJl +aJl +aZr +aJl +aJl +aJl +aJl +aJl +aZr +aJl +aJl +aJl +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aJx +"} +(29,1,1) = {" +aJx +aac +aac +aac +aac +aac +ags +aZS +aZS +ags +ags +ags +aac +aac +aac +aac +aac +aZS +aZS +aZS +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +ags +ags +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaw +acA +auU +auU +auU +auy +aJH +add +aMs +aMC +aMO +aMO +aNh +aaw +ayQ +aCI +bck +apR +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +apR +ahY +ayO +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aRG +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aZS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +aac +aIa +aGh +aJl +aZr +aJl +aJl +aJl +aJl +aCM +aCM +aCM +aJl +aJl +aJl +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aJx +"} +(30,1,1) = {" +aJx +aac +aac +aac +aac +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aac +ags +ags +ags +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +ags +ags +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaw +aaw +aRn +aaw +aaw +avu +auU +aQC +auU +aMD +aaw +aaw +aaw +aaw +bbJ +aKP +bck +ayO +aQl +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQl +aKP +ahY +apR +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +apR +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aaN +aNv +aIV +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +aac +aIa +aGh +aJl +aPi +aJl +aJl +apu +aJl +aJl +aJl +aJl +aJl +aPi +aPi +aXs +aPi +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aJx +"} +(31,1,1) = {" +aJx +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +aac +ags +aac +aac +aac +ags +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +bbv +aaN +aaN +aaN +aRn +avR +aJI +aRn +aJI +aMF +aRn +aaN +bgu +aaN +bbv +aKP +bck +ayO +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aKP +aUP +anq +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +aRF +anq +bcb +bcd +bce +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aLU +aaN +aZS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aIa +aGh +aJl +aPi +aJl +aPi +aJl +aJl +aJl +aZr +aJl +aJl +aJl +aJl +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aJx +"} +(32,1,1) = {" +aJx +aac +aac +aac +aac +ags +ags +aED +aED +aED +aED +aED +aED +aED +aED +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +ags +ags +ags +ags +ags +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +bbv +aaN +bbx +bbx +bbx +bbx +bbi +bbx +bbD +bbx +bbx +bbx +bbx +bbx +bbv +aKP +bck +ayO +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aKP +ahY +ayO +aQl +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +abK +aaN +aaN +bbP +avS +avS +avS +avS +avS +avS +avS +avS +avS +avS +bbJ +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aIa +aGh +aJl +aPi +aJl +aPi +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aZr +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aJx +"} +(33,1,1) = {" +aJx +aac +aac +aac +aac +ags +ags +aED +aBs +aHj +aAj +aGI +aKJ +azy +aED +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +bbv +aaN +bby +aSo +aSo +aSo +aSo +aSo +aSo +aSo +aSo +aSo +aSo +bbI +bbv +aKP +bck +ayO +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aKP +ahY +ayO +aaN +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aaN +bbx +bbx +bbD +bbx +bbx +bbx +bbD +bbx +bbx +bbv +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +ayV +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aIa +aGh +aJl +aPi +aJl +aJl +aJl +aPi +aPi +aPi +aXs +aPi +aJl +aJl +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aJx +"} +(34,1,1) = {" +aJx +aac +aac +aac +aac +ags +ags +abe +aKG +aHj +aAj +aAj +aKJ +aMp +aED +aED +aED +aED +aED +aED +aED +aac +aac +ags +ags +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +bbv +aaN +bbx +aSo +aSo +aSo +aSo +aSo +aSo +aSo +aSo +aSo +aSo +bbx +bbv +aKP +bck +ayO +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aKP +ahY +ayO +aaN +aqr +aQn +aQo +aQr +aQw +aqr +aOE +aOE +aOE +aOE +aOE +aOE +aqr +aaN +bby +aSo +aSo +aSo +aSo +aSo +aSo +aSo +bbI +bbv +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aIa +aGh +aJl +aJl +aZr +aJl +aJl +aZr +aJl +aJl +aJl +aJl +aJl +aNz +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aJx +"} +(35,1,1) = {" +aJx +aac +aac +aac +aac +ags +ags +aAY +aMp +aHj +aAj +aAj +aKJ +aMp +aGo +aMp +aMp +aMp +aAQ +aIQ +aED +aac +aac +ags +ags +ags +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +bbv +aaN +bbx +aSo +aSo +aSo +aSo +aSo +aSo +aSo +aSo +aSo +aSo +bbx +bbv +aKP +bck +ayO +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aKP +ahY +ayO +aaN +anP +aOE +aOE +aOE +aOE +aqr +aOE +aOE +akw +aOE +aOE +aOE +aPS +aaN +bbx +aSo +aSo +aSo +aSo +aSo +aSo +aSo +bbx +bbv +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aIa +aGh +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aNz +apu +aZr +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aJx +"} +(36,1,1) = {" +aJx +aac +aac +aac +aac +ags +ags +aED +aEC +aMp +aAu +aAu +aMp +aMp +aGo +aMp +aMp +aMp +aMp +aIQ +aED +aac +aac +ags +ags +ags +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +ags +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +bbv +aaN +bbx +aSo +aSo +aSo +aSo +aSo +aSo +aSo +aSo +aSo +aSo +bbx +bbv +aKP +bck +ayO +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aKP +ahY +ayO +apR +acy +aOE +aOE +aOE +aOE +aPS +aOE +akj +aqJ +amF +aOE +aOE +aPS +aaN +bby +aSo +aSo +aSo +aSo +aSo +aSo +aSo +bbI +bbv +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aIa +aGh +aJl +aZr +aJl +apu +aJl +aPi +aPi +aPi +aJl +aJl +aJl +aNz +aJl +aZr +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aJx +"} +(37,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aED +aMp +aMp +aMp +aMp +aVW +aED +aED +aED +aED +aMp +aMp +aQY +aED +aac +aac +ags +ags +ags +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +bbv +aaN +bby +aSo +aSo +aSo +aSo +aSo +aSo +aSo +aSo +aSo +aSo +bbI +bbv +aKP +bck +ayO +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aKP +ahY +ayO +apR +acy +aOE +aOE +aOE +aOE +aPS +aOE +aOE +akY +aOE +aOE +aOE +aqr +aaN +bbx +bbx +bbE +bbx +bbx +bbx +bbE +bbx +bbx +bbv +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aIa +aGh +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aZr +apu +aJl +aNz +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aJx +"} +(38,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aED +aBo +aMp +aMp +aMp +aMp +aGo +aYy +aQG +aED +aMp +aMp +aMp +aED +aac +aac +aac +ags +ags +ags +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +bbv +aaN +bbx +bbx +bbx +bbx +bbE +bbx +bbE +bbx +bbx +bbx +bbx +bbx +bbv +aKP +bck +ayO +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aKP +ahY +ayO +aaN +anP +abJ +aQp +aQt +aQy +aqr +aOE +aOE +aOE +aOE +aOE +aOE +aqr +aaN +aaN +aae +aGK +aHo +aHo +aHo +aIZ +aKd +aaN +bbv +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aIa +aGh +aJl +aJl +aPi +aPi +aJl +aJl +apu +aJl +aJl +aJl +aJl +aNz +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aJx +"} +(39,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aJc +aMp +aMp +aMp +aMp +aTJ +aED +aYy +aYy +aED +aMp +aMp +aMp +aED +aac +aac +aac +ags +ags +ags +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +bbv +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +bbv +aKP +bck +ayO +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aKP +ahY +ayO +aaN +aqr +abJ +abJ +aQu +abJ +aqr +aOE +aOE +aPU +aOE +aqr +aPS +aqr +aqr +aqr +aqr +aBm +aOE +aOE +aOE +aBm +aqr +aqr +aqr +aLn +aLn +aLn +aLn +aLn +aLn +aLn +aLn +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aIa +aGh +aJl +aJl +aJl +aJl +aZr +aJl +aJl +aJl +aJl +aPi +aJl +aJl +aJl +apu +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aJx +"} +(40,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aED +aMp +aMp +aMp +aMp +aMp +aED +aYy +aYy +aED +aMp +aMp +aMp +aED +aac +aac +aac +aac +ags +ags +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aZS +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +bbt +avS +avS +aqr +aqr +aar +aar +aqr +aqr +avS +avS +avS +avS +avS +bbK +aKP +bck +ayO +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aKP +ahY +ayO +aaN +aqr +abJ +abJ +abJ +abJ +aqr +aqr +aqr +aqr +aqr +aqr +aFF +aOE +aOE +aOE +aOE +aBm +aOE +aOE +aOE +aBm +aOE +aOE +aqr +aLo +aLv +aLH +aLI +aLI +aLI +aLI +aLI +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aIa +aGh +aJl +aZr +aZr +aXs +aJl +aCM +aCM +aCM +aJl +aJl +aJl +aJl +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aJx +"} +(41,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aED +aQP +aQP +aQP +aQP +aMp +aED +aFU +aNJ +aED +aAZ +aKf +aMp +aED +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aRi +aKi +aFw +aAb +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aeQ +afg +afg +agw +aqr +aaN +aaN +aaN +aaN +aWs +aaN +aKP +bck +ayO +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aKP +ahY +ayO +aaN +aqr +aqr +aqr +aqr +aqr +aqr +aOY +aNu +aNu +aNu +aqr +atq +aLC +aLC +aLC +aLC +aGN +aLC +aLC +aLC +aGN +aHT +adj +aqr +aLp +aLw +aLv +aLv +aLv +aLv +aLv +aLv +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +ags +ags +ags +ags +ags +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aIa +aGh +aJl +aJl +aJl +aXs +aJl +aJl +aJl +aJl +aJl +aJl +aZr +aJl +aPi +aPi +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aJx +"} +(42,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aED +aMp +aMp +aMp +aMp +aVW +aED +aKg +aED +aED +aED +aED +aRw +aED +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aAb +aFw +aFw +aZk +aEF +aUr +aFw +aAb +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aar +aCv +aOE +aOE +aOE +aar +aaN +aaN +aaN +aaN +aaN +aaN +aKP +bck +ayO +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aKP +ahY +ayO +aaN +aqr +aBl +aOX +aBl +aOE +aOE +aNu +aNu +aqr +aqr +aqr +aqr +aOE +aqr +aqr +aOE +aOE +aOE +aOE +aOE +aqr +aKe +aKI +aqr +aqr +aqr +aqr +aLv +aLv +aLO +aLS +aLS +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aaN +aac +aac +ags +aZS +aZS +aZS +aZS +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aIa +aGh +aJl +aPi +aJl +aJl +aZr +aJl +apu +aJl +aJl +aJl +aJl +aZr +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aJx +"} +(43,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aED +aAY +aMp +aMp +aMp +aMp +aED +aYy +aYy +aED +aQx +aMp +aMp +aED +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aAb +aAb +aJb +aEF +aPO +aQq +aFw +aAb +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aeR +aOE +aga +ade +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aKP +bck +ayO +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aKP +ahY +ayO +aaN +aqr +aOE +aOE +aOE +aOE +aqr +aNu +aNu +aPa +aqr +aOE +aOE +aOE +aOE +aqr +aOE +aQA +aQA +aQB +aOE +aqr +aOE +aBm +aqr +aOE +aOE +aqr +aLv +aLv +aqr +aqr +aqr +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aLU +aZS +aZS +aZS +aZS +aZS +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aIa +aGh +aJl +aPi +aJl +aPi +aJl +aJl +aJl +aJl +aJl +aPi +aJl +aJl +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aJx +"} +(44,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aED +aQP +aXO +aZi +aQP +aMp +aED +aYy +aTH +aED +aQx +aMp +aVW +aED +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aAb +aFw +aUK +aEF +aEF +aEF +aAb +aFw +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +aqr +aOE +aOE +aqr +aqr +aqr +aaN +aaN +aaN +aaN +aTQ +aKP +bck +ayO +aQl +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aKP +ahY +ayO +aaN +aqr +aOE +aOE +aOE +aEt +aqr +aNu +aNu +aNu +aqr +agN +aOE +aDJ +aEm +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aOE +aBm +aOE +aOE +aOE +acy +aLv +aLv +aqr +aLT +aqr +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aNv +aZS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aIa +aGh +aJl +aPi +aJl +aPi +aJl +aCM +aCM +aCM +aJl +aPi +aJl +aJl +aJl +aZr +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aJx +"} +(45,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aED +aED +aED +aED +aED +aED +aED +aIu +aYy +aED +aSi +aWo +aAR +aED +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aXv +aUr +aEF +aZN +aRS +aEF +aPT +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aep +asK +aOE +aOE +asK +ahH +aqr +abF +awl +awl +awl +awl +aCI +bck +aCI +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +apR +ahY +ayO +aaN +aqr +aBl +aBl +aBl +aFF +aqr +aMa +aOZ +aMa +aqr +aBk +aOE +aOE +aOE +aqr +aFI +aNu +aNu +aNu +ajr +ajr +aLC +aBm +aKd +aOE +aOE +aqr +aLv +aLv +acy +aLX +aqr +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aIV +aNv +aNv +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aIa +aGh +aJl +aJl +aJl +aPi +aJl +aJl +aJl +aJl +aJl +aPi +aJl +apu +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aac +aac +aac +aac +aac +aJx +"} +(46,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aED +aED +aED +aED +aED +aED +aED +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aPT +aRB +aKi +aRS +aQq +aUK +aRB +aFw +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aNA +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aeq +aOE +aby +aby +aCv +aeO +aqr +abG +aCI +aCI +aCI +aCI +apR +aTY +aRd +aRd +aRd +aRd +aRd +aRd +aRd +aRd +aRd +aRd +aRd +aRd +aUQ +ayO +aaN +aqr +anP +anP +anP +adI +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aNu +aNu +aNu +aNu +aNu +aJa +aOE +aBm +aqr +aqr +aqr +aqr +aLJ +aLv +aqr +aMa +aqr +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aIa +aGh +aJl +apu +aJl +aPi +aJl +aJl +aJl +aJl +aZr +aPi +aJl +aZr +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aJx +"} +(47,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aFw +aFw +aEo +aRB +aEF +aLG +aGz +aFw +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aeL +aJM +aby +aby +aOE +ahI +aqr +aOr +aCI +apR +apR +apR +apR +aPZ +apR +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +apR +ano +ayO +aat +aab +aab +aaF +aab +ano +awt +aab +aab +aeW +aqr +aBl +aBl +aOE +aEn +aqr +aNu +aNu +aHq +aNu +aIk +aJd +aOE +aBm +aqr +aLq +aLy +aqr +aLv +aLv +aqr +aqr +aqr +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aIa +aGh +aJl +aJl +aJl +aJl +aZr +aJl +apu +aJl +aZr +aJl +aJl +aJl +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aJx +"} +(48,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aFw +aAb +aFw +aAb +aEF +aRB +aAb +aFw +aac +aac +aac +aac +aac +aac +ags +aHg +ags +aFA +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aeM +aOE +aby +aby +aOE +ahK +aqr +abG +aCI +apR +apR +apR +apR +aPZ +ayO +aat +aaN +aaN +aqr +aqr +aar +aar +aar +aqr +aqr +aKP +adb +apR +awl +awl +awl +awl +awl +aRk +awl +awl +awl +awo +acy +aOE +akW +aDK +aOE +aqr +aqr +aGO +aqr +aHS +aGZ +aJf +aOE +aKK +aLk +aqv +aOE +acy +aLv +aLv +aLP +aMd +aMg +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aIa +aGh +aJl +aZr +aZr +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aPi +aPi +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(49,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aac +aac +aac +aac +aac +aac +aac +aFw +aAb +aAb +aAb +aFm +aAb +aAb +aFw +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aSl +ags +aSR +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aeP +aOE +aOE +aOE +aOE +ahM +aqr +aDN +awk +awk +awk +awk +apR +aPZ +ayO +aab +aaN +aaN +aar +aGi +aGj +aGi +aGi +aGi +aar +aKP +adc +aRd +aRd +aRd +aRd +aRd +aRd +asD +apR +apR +apR +ayO +aae +adj +akW +aDL +aOE +aqr +aFL +aGQ +aqr +aOE +aOE +aOE +aOE +aKL +aKd +aLs +aLz +aqr +aLv +aLv +aLv +aMe +aLv +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aIa +aGh +aJl +aPi +aPi +aJl +aJl +aXs +aXs +aXs +aJl +aPi +aPi +aJl +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(50,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aac +aac +aac +aAb +aFw +aPT +aAb +aFw +aAb +aAb +aFw +aRB +aFw +aFw +aAb +aac +aac +aac +aac +aac +aNF +ags +ags +aEb +ags +ags +ags +ags +aSR +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +acP +aRP +aOE +agP +aqr +aqr +aqr +aqr +aqr +aab +aab +aKP +ano +ayO +aab +aaN +aaN +aar +aOE +aOE +aOE +aOE +aOE +aar +aKP +apR +apR +awk +awk +awk +awk +awk +awk +awk +apR +apR +ayO +acy +aBm +aOE +aOE +aOE +aqr +aFO +aGR +aHr +aqv +abJ +arI +abJ +aKN +aqr +aqr +aqr +aqr +aLJ +aLv +aLv +aLv +aLv +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aIa +aGh +aJl +aJl +aJl +aJl +aJl +aZr +aJl +aJl +aJl +aXs +aJl +aZr +aJl +aZr +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(51,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aac +aac +aac +aFw +aAb +aPL +aRm +aAb +aEF +aVC +aFw +aFm +aKa +aTX +aFw +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aBy +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +afU +aOE +aOE +agP +ahN +aiB +akc +akT +aqr +awh +aab +aKP +ano +ayO +aab +aaN +aaN +aar +aGi +aOE +aGi +aOE +aGi +aar +aKP +apR +ayO +akA +akA +akA +akA +akA +akA +akA +aKP +apR +aoh +aqr +aBn +aOE +aOE +abZ +aqr +aFS +aGS +aqr +aHU +abJ +aJq +aKk +aBm +aOE +aRP +aLA +aqr +aLv +aLN +aLN +aLN +aLN +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aIa +aGh +aJl +aJl +apu +aJl +aPi +aPi +aPi +aPi +aPi +aJl +aJl +aJl +apu +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(52,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aFw +aUK +aQq +aAw +aUK +aRB +aFm +aRB +aRB +aLZ +aQq +aFw +aac +aac +aac +aac +aac +aac +aac +aNF +ags +ags +aWk +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +afa +aOE +aby +aby +aby +aby +aby +aby +aqr +aau +aat +aKP +ano +ayO +aab +aaN +aaN +aqr +aGi +aOE +aGi +aOE +aGi +aqr +aKP +ajt +ayO +akA +akA +akA +akA +akA +akA +akA +aKP +apR +ayO +aae +aBp +aii +aii +aOE +aqr +aqr +aqr +aqr +aOE +abJ +abJ +aKn +aBm +aVJ +aOE +aLB +aqr +aLK +aLN +aLN +aLN +aLN +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aIa +aGh +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(53,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aFw +aOw +aRB +aRB +aQq +aQq +aPL +aFw +ayW +aFm +aEF +aFw +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aip +aIh +aby +agR +aby +aby +aby +aby +alP +awl +awl +apR +ano +ayO +aab +aaN +aaN +aqr +aGi +aOE +aGi +aOE +aGi +aqr +aKP +apR +ayO +akA +akA +akA +akA +akA +akA +akA +aKP +apR +ayO +aae +aBq +aCJ +aCJ +aHT +aLC +aLC +aGU +aHt +aHV +aFt +aFt +aKo +aKO +aqr +aqr +aqr +aqr +aLv +aLN +aLN +aLN +aLN +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aLU +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aIa +aGh +aZr +aJl +aCM +aJl +aJl +aZr +aZr +aZr +aJl +aJl +aCM +aJl +aJl +aJl +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(54,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aFw +aAb +aFw +aAb +aFw +aAb +aAb +aFw +aUr +awQ +aPL +aAb +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aar +afe +afB +aby +aby +aby +agR +aby +aby +aQQ +aRd +aRd +azB +ano +ayO +aab +aaN +aaN +aqr +aGi +aOE +aGi +aOE +aGi +aqr +aKP +ajt +ayO +akA +akA +akA +akA +akA +akA +akA +aKP +apR +ayO +aae +aBr +aCK +aii +aOE +aqr +aOE +aFF +aHw +aOE +aOE +aqv +aOE +aKR +aKd +aLq +aLD +aqr +aLJ +aLv +aLv +aLv +aLv +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aLU +aac +aac +aac +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aGh +aZr +aJl +aCM +aJl +aJl +aJl +aJl +aJl +aJl +aJl +aCM +aJl +aJl +aZr +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(55,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aAb +aAb +aAb +aAb +aAb +aAb +aAb +aFw +aPT +aFw +aAb +aFw +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aff +afD +aby +aby +aby +aby +aby +aby +alP +awk +awk +aCI +aPZ +ayO +aab +aaN +aaN +aqr +aGi +aOE +aGi +aOE +aGi +aqr +aKP +apR +ayO +akA +akA +akA +akA +akA +akA +akA +aKP +apR +ayO +aqr +aqr +aqr +aqr +acy +aqr +aOE +aFF +aqr +aqr +aqr +aqr +aOE +aqv +aLm +aiy +adN +acy +aLv +aLv +aLv +aMf +aLv +aLn +aph +ayO +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aLU +aLU +aac +aac +aac +aIa +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aPv +aPv +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(56,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +acX +aOE +aOE +agT +ahO +ahO +ahO +ahO +aqr +aab +aau +aKP +ano +ayO +aab +aqr +aqr +aqr +aGi +aOE +aGi +aVh +aGi +aqr +aKP +ajt +ayO +akA +akA +akA +akA +akA +akA +akA +aKP +apR +aoh +aqr +aBv +aCP +aDP +aNu +aqr +aOE +aFF +aqr +aHW +aIm +aqr +aqr +aqr +aqr +aLu +aLE +aqr +aLn +aLn +aLn +aLn +aLn +aLn +aph +ayO +aWA +aSL +aWA +aKq +aQl +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQl +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQl +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aLU +aLU +aLU +aXy +aLU +aZP +aGh +aCG +aCG +aCG +aCG +aCG +aCG +aGh +aZW +aZt +aZt +aZt +aZt +aZx +aZx +aZx +aZx +aZt +aZt +aZt +aZt +aZW +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(57,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +aar +aar +aqr +aqr +aar +aar +aqr +aqr +aab +aab +aKP +ano +ayO +aab +aqr +azO +agl +agl +agl +aHu +aOE +aOE +aar +aKP +apR +ayO +akA +akA +akA +akA +akA +akA +akA +aKP +apR +ayO +aqr +aNu +aCR +aNu +aNu +aqr +aOE +aFF +aae +aHT +aIo +adj +aOE +aKT +aqr +aqr +aqr +aqr +aaN +aaN +aaN +aaN +afY +awl +apR +ayO +aWA +aSL +aWA +aHI +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +awl +aDp +aPP +aZt +aZt +aUW +aZt +aUW +aCG +aGh +aZt +aZt +aZt +aZt +aZt +aZx +aMq +aMq +aZx +aZt +aZt +aZt +aZt +aZt +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(58,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aKP +ano +ayO +aab +aar +afU +agl +agl +agl +aOE +aOE +aJL +aar +aKP +ajt +ayO +akA +akA +akA +akA +akA +akA +akA +aKP +apR +ayO +aqr +aBx +aCS +aDQ +aNu +aqr +aFX +aFF +aqr +aBM +aCv +aJs +aKr +aKU +aqr +aaN +abK +aaN +aaN +aaN +aaN +aaN +aph +apR +awk +awn +aWA +aSL +aWA +aKS +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +apR +apR +awk +awk +awk +awk +aTv +aPP +aZt +aZt +aZt +aZt +aZt +aCG +aGh +aGu +aZt +aZt +aZt +aGh +aWl +aWl +aWl +aWl +aGh +aZt +aZt +aZt +aTV +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(59,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aKP +ano +ayO +aab +aar +acS +agl +agl +agl +aOE +aOE +aJW +aqr +aKP +apR +ayO +akA +akA +akA +akA +akA +akA +akA +aKP +apR +aoh +aqr +aqr +aqr +aqr +aqr +aqr +aOE +aFF +aHx +aOE +aOE +aJt +aOE +aKV +aqr +aVq +abK +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aSL +aWA +aKq +aQl +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQl +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQl +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aLU +aLU +aXy +aLU +aZP +aGh +aCG +aUW +aZt +aZt +aZt +aCG +aGh +aFr +aZt +aZt +aZt +aGh +aGh +aGh +aGh +aGh +aGh +aZt +aZt +aZt +aZt +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(60,1,1) = {" +aJx +aac +ags +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aKP +ano +ayO +aab +aqr +afU +agl +agl +agl +aHH +aOE +aJX +aqr +aKP +ajt +ayO +akA +akA +akA +akA +akA +akA +akA +aKP +apR +aoi +aqr +aOE +aCT +aCT +aCT +aqr +aOE +aFF +aHx +aJM +aIr +aJu +aKs +aKW +aqr +aVz +abK +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aSL +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aaN +aaN +aLU +aLU +aUY +aGh +aCG +aZt +aPo +aPo +aUW +aCG +aGh +aFW +aZt +aZt +aZt +aSq +aZt +aUW +aUW +aZt +aSq +aZt +aUW +aZt +aKD +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(61,1,1) = {" +aJx +aac +ags +aac +aac +aac +aac +aac +ags +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aVS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aat +aab +aab +aab +aab +aab +aab +aat +aab +aab +aab +aab +aab +aab +aat +aKP +ano +ayO +aab +aar +acS +agl +agl +agl +aOE +aOE +aJX +aar +aKP +apR +ayO +akA +akA +akA +akA +akA +akA +akA +aKP +apR +ayO +aar +aBC +aii +aii +aEp +aqr +aBM +aFF +aqr +aHX +aOE +aJv +aOE +aLa +aqr +aVu +abK +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aEg +aSM +aEg +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aaN +aaN +aLU +aLU +aUY +aGh +aCG +aZt +aXz +aXz +aZt +aCG +aGh +aMo +aZt +aUW +aZt +aSU +aZt +aZt +aZt +aZt +aSU +aZt +aUW +aZt +aHn +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(62,1,1) = {" +aJx +aac +ags +ags +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aab +aKP +ano +ayO +aab +aar +acP +agl +agl +agl +aIh +aOE +aLd +aar +aKP +ajt +ayO +akA +akA +akA +akA +akA +akA +akA +aKP +apR +ayO +aar +aBI +aii +aii +aOE +aqr +aOE +aFF +aae +aHZ +aIt +aJz +aKv +aLb +aqr +aaN +abK +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aEg +aSM +aEg +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aaN +aaN +aaN +aLU +aUY +aGh +aCG +aUW +aJe +aJe +aZt +aCG +aGh +aFr +aZt +aUW +aZt +aPd +aZt +aZt +aZt +aZt +aIO +aZt +aZt +aZt +aFQ +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(63,1,1) = {" +aJx +aac +ags +ags +ags +aac +ags +ags +aRE +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aab +aKP +ano +ayO +aab +aqr +aez +agl +agl +agl +aOE +aOE +aJX +aqr +aKP +apR +ayO +akA +akA +akA +akA +akA +akA +akA +aKP +apR +ayO +aar +aBJ +aii +aii +aOE +aqr +aOE +aFF +aqr +aIb +aIy +aBm +aIr +aLc +aqr +aaN +abK +aaN +aaN +aaN +aaN +aaN +awi +aDu +aav +aCW +aEg +aSM +aEg +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQl +aph +ayO +aQl +aaN +aaN +aLU +aUY +aGh +aCG +aZt +aXz +aXz +aZt +aCG +aGh +aFW +aZt +aZt +aZt +aFr +aZt +aZt +aZt +aZt +aFr +aZt +aZt +aZt +aBG +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(64,1,1) = {" +aJx +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aab +aab +aab +aaN +aab +aab +aab +aab +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aab +aKP +ano +ayO +aab +aqr +aar +aqr +acy +acy +acy +aqr +aar +aqr +aKP +apR +ayO +akA +akA +akA +akA +akA +akA +akA +aKP +apR +aoj +aqr +aBM +aii +aii +aEs +aqr +aOE +aFF +aqr +aqr +aqr +aJA +aKw +aqr +aqr +aaN +abK +aaN +aaN +aaN +aaN +aaN +awi +aDv +abs +aCX +aEg +aSM +aEg +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aaN +aaN +aaN +aLU +aUY +aGh +aCG +aZt +aMW +aJe +aZt +aCG +aGh +aMo +aZt +aUW +aZt +aZt +aUW +aUW +aUW +aZt +aZt +aZt +aUW +aZt +aSn +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(65,1,1) = {" +aJx +aac +aac +aac +aac +ags +ags +ags +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aab +aab +aab +aaN +aab +aab +aab +aax +aWA +aWA +aWA +aWA +aWA +aWA +adW +aWA +aWA +aWA +aWA +aWA +aNC +aab +aKP +ano +apR +bcJ +awl +awl +azu +awl +awl +awl +azu +awl +awl +apR +apR +apR +awl +awl +awl +awl +awl +awl +awl +apR +apR +ayO +acy +aRP +aii +aii +aOE +aFg +aOE +aFF +aqr +aCd +aIA +aBm +aKE +aCd +aqr +aaN +abK +aaN +aaN +aaN +aaN +aaN +awi +aDv +abs +aCY +aEg +aSM +aEg +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aaN +aaN +aaN +aLU +aUY +aGh +aCG +aZt +aXz +aXz +aUW +aCG +aGh +aZt +aZt +aUW +aZt +aZt +aUW +aUW +aUW +aZt +aZt +aZt +aUW +aZt +aZt +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(66,1,1) = {" +aJx +ags +aac +aac +aac +ags +ags +aac +ags +ags +ags +ags +ags +aac +aac +aac +ags +ags +ags +ags +aac +ags +ags +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aab +aab +aab +aaN +aab +aab +aab +aab +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aab +aKP +ano +aCI +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +ayO +aar +aOE +aii +aii +aOE +aae +aHT +aFF +aqr +aCd +aIB +aIF +aKF +aCd +aqr +aaN +abK +aaN +aaN +aaN +aaN +aaN +awi +aas +abs +aCX +aEg +aSM +aEg +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aaN +aaN +aaN +aaN +aUY +aGh +aCG +aZt +aJe +aJe +aZt +aCG +aGh +dzl +aZt +aZt +aZt +aZt +aUW +aUW +aUW +aZt +aZt +aZt +aZt +ayo +aNT +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(67,1,1) = {" +aJx +ags +ags +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +ags +ags +ags +ags +ags +aVS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aaN +aab +aaN +aaN +aab +aab +aab +aab +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aab +aKP +ano +aCI +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awk +awn +acy +aOE +aDb +aOE +aVJ +aFg +aOE +aGV +aqr +aId +aIC +aJB +aKo +aLe +aKd +aaN +abK +aaN +aaN +aaN +aaN +aaN +awi +aDx +abs +aCX +aEg +aSM +aEg +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aaN +aaN +aaN +aaN +aUY +aGh +aCG +aZt +aUW +aZt +aZt +aCG +aGh +dzl +aZt +aUW +aZt +aFr +aZt +aZt +aZt +aZt +aFr +aZt +aUW +aCm +aMy +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(68,1,1) = {" +aJx +ags +ags +ags +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aaN +aab +aaN +aaN +aab +aab +aab +aab +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aWA +aab +aKP +ano +ayO +aab +aab +aab +aab +aab +aab +aab +aab +aab +aaF +aab +aab +acQ +aab +aab +aab +acQ +aaD +aab +aab +aab +acQ +aok +aqr +aqr +aDc +aQO +aqr +aqr +aOE +aFF +aqr +aVh +aIF +abJ +abJ +aLf +aqr +aaN +abK +aaN +aaN +aaN +aaN +aaN +awi +aDv +abs +aCX +aEg +aSM +aEg +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aaN +aaN +aaN +aaN +aUY +aGh +aCG +aZt +aZt +aZt +aZt +aZt +aZt +aZt +aZt +aUW +aZt +aPd +aZt +aZt +aZt +aZt +aIO +aZt +aUW +aTn +aWN +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(69,1,1) = {" +aJx +aac +ags +ags +ags +ags +ags +ags +ags +aac +ags +ags +ags +ags +aac +ags +ags +aac +ags +ags +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aab +aab +aab +aab +aab +aab +aab +aat +aab +aab +aab +aab +aab +aab +aat +aab +aab +aab +aab +aab +aab +aat +aKP +ano +ayO +aab +aab +aab +aab +aab +aab +aaB +aab +aqr +aqr +aar +aqr +aqr +aqr +aar +aqr +aqr +aqr +aar +aqr +aqr +aqr +aBY +aqr +aBO +aDd +aOE +aEt +aqr +aOE +aGW +aHy +aLC +aIG +aga +aKH +aCd +aqr +aaN +abK +aaN +aaN +aaN +aaN +aaN +awi +aDv +abs +aCX +aEg +aSM +aEg +aQD +aqr +aqr +aar +aar +aqr +aqr +aqr +aaN +aaN +aaN +aaN +aaN +aYI +aYI +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aaN +aaN +aaN +aaN +aUY +aGh +aCG +aUW +aZt +aZt +aZt +aZt +aZt +aZt +aZt +aZt +aZt +aSU +aZt +aZt +aZt +aZt +aSU +aZt +aUW +aCm +aMy +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(70,1,1) = {" +aJx +aac +aac +aac +aNF +ags +ags +ags +ags +ags +ags +aac +aac +ags +ags +ags +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +ahX +anq +anq +anq +anq +anq +anq +anq +anq +anq +anq +aZo +baa +ayO +aab +aab +aab +aab +aab +aab +aab +aab +aqr +aoc +aoC +aOE +aqG +alO +aOE +akS +aqr +auu +aOE +asK +aOE +aqr +azJ +aqr +aBP +aOE +afk +atq +aFj +aLC +baX +aqr +aIe +aII +aJJ +aqr +aqr +aqr +aaN +abK +aaN +aaN +aaN +aaN +aaN +awi +aDv +abs +aCX +aEg +aSM +aEg +aMN +aCg +aCg +aCg +aCg +aCg +ade +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aaN +aaN +aaN +aQl +aUY +aGh +aCG +aZt +aZt +aZt +aZt +aZx +aXq +aZx +aZt +aZt +aZt +aSq +aZt +ayA +ayA +aZt +aSq +aZt +aZt +aTn +aEV +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(71,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +ags +ags +ags +ags +ags +ags +ags +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +ahY +aat +aab +aab +aab +aab +aaD +aab +aab +ajl +acQ +aKS +aRg +awn +acQ +aab +aab +aab +aab +aab +aab +aab +aqr +aOE +aOE +aOE +aOE +aOE +aOE +akS +aqr +auv +amH +amH +axu +aqr +aqv +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aIL +aJO +aqr +aaN +aaN +aaN +abK +aaN +aaN +aaN +aaN +aaN +awi +aBf +aVd +aCZ +aEg +aSM +aEg +aMN +aCg +aCg +aCg +aRN +aCg +ade +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aaN +aaN +aaN +aac +aIa +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aGh +aIa +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(72,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +ags +ags +aZS +ags +ags +ags +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +aab +aab +ahY +aab +aqr +aqr +ahC +aqr +aqr +aqr +alR +aqr +aqr +acy +ahr +acy +aqr +aqr +aar +aqr +aqr +aqr +aar +aqr +aqr +abJ +aoD +apw +aLC +aqU +aLC +aLC +aLC +aux +avw +awy +axv +axW +aLC +axW +aLC +aLC +aLC +aLC +aLC +aLC +aLC +aLC +axW +baX +aJP +aqr +aaN +aaN +aaN +abK +aaN +aaN +aaN +aaN +aaN +ayP +awj +aCV +aDa +aEg +aSM +aEg +aMN +aCg +aCg +aCg +aCg +aCg +ade +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aQl +aac +aac +aac +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aIa +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(73,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ayV +ags +ags +ags +ags +aZS +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +aab +aab +ahY +aab +aqr +agU +aia +agl +aqr +aRX +aXM +aoU +aqr +aOE +aFF +aOE +aqr +amz +azX +akS +aqr +aeP +aHR +aOE +aOE +abJ +aoE +apx +aOE +aqV +aOE +aOE +aqv +auz +aon +aon +axx +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aaN +abK +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aEg +aSM +aEg +aMN +aCg +aCg +aCg +aCg +aCg +ade +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aaN +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(74,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ayV +aac +aac +ags +ags +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +aab +aab +ahY +aab +aqr +ahn +aib +aiI +aqr +akU +alS +aoV +apW +aOE +aFF +aOE +aqr +aOE +azY +aEc +aqr +aGE +azY +aJg +aqr +aod +aoP +apx +aOE +amz +aOE +asN +aqr +aVh +aiq +aiq +aga +aqr +azL +aAT +aBQ +aqr +aNK +aqr +aNK +aqr +aNK +aqr +aNK +aqr +aNK +aqr +aNK +aqr +aaN +abK +aaN +aaN +aaN +aaN +aaN +aph +ayR +aza +azg +azn +aSO +azs +aMN +aCg +aCg +aCg +aRN +aCg +ade +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aKS +awn +ags +ags +ags +aRT +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(75,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aZS +ags +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +aab +aab +ahY +aab +aqr +aDI +aDI +aBm +ake +aDI +alU +aDI +aqr +aQN +aNE +aQN +aqr +aar +aBU +aqr +aqr +aqr +aHY +aqr +aqr +aoe +aFF +aOE +aOE +aOE +aOE +asO +aqr +aOE +aOE +aOE +aOE +aqr +azM +aAV +auU +aqr +atI +aqr +atI +aqr +atI +aqr +atI +aqr +atI +aqr +atI +aqr +aaN +abK +aaN +aaN +aaN +aaN +aaN +aph +ayS +azb +azb +azb +aSQ +azb +aMN +aCg +aCg +aCg +aRN +aCg +ade +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQl +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aRT +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(76,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +ags +ags +ags +ags +aZS +aac +aac +ags +ags +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +aab +aab +ahY +aaD +aqr +aOE +aDI +aiJ +akf +ahC +aQN +ahC +aQN +aqt +arF +auw +aqI +aqI +arF +aqI +axp +aqI +arF +aqI +aqr +aOE +aFF +aOE +amA +amA +aOE +asP +aqr +auC +acj +awz +axy +aqr +azN +auU +auU +aqr +aOE +aWX +aye +aOE +aOE +aqr +aqv +aKu +aQM +aOE +aOE +aqr +aaN +abK +aaN +aWs +aaN +aaN +aaN +aph +ayT +azb +azi +azi +aSS +azb +aMN +aCg +aCg +aCg +aCg +aCg +ade +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQl +aac +aac +aac +aac +ags +ags +ags +ags +aRT +ags +ags +ags +ags +ags +aRT +ags +ags +ags +ags +ags +aRT +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(77,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +ags +ags +ags +aZS +aZS +aac +ags +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +aab +aab +ahY +aab +agc +adj +aae +aiK +ako +akV +aHt +aoW +aHt +aqE +arG +aqE +aqE +aqE +aCp +aqE +aqE +aqE +aIi +aqI +aqr +aqr +adI +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +auU +aAV +aBS +aqr +aOE +aOE +aPK +aOE +aCu +aqr +aOE +aOE +aPK +aOE +aCu +aqr +aaN +abK +aaN +aaN +aaN +aaN +aaN +aph +apR +azc +azj +aWA +aSS +azb +aMN +aCg +aCg +aCg +aCg +aCg +ade +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(78,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +ags +ags +ags +ayV +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +aab +aab +ahY +aab +agc +aJz +aae +aiX +akz +adR +aQN +adR +apZ +aqI +aqI +aqI +awB +aqI +aqI +aqI +aqI +aqI +arF +aqI +aqr +akg +aFF +abJ +aqH +arc +asb +atl +aqH +arc +asb +atl +aqH +aqr +azR +auU +aBV +aqr +afU +aSe +aCq +aOE +acP +aqr +acS +afU +aCq +aOE +acP +aqr +aaN +abK +aaN +aaN +aaN +aaN +aaN +aph +apR +azd +azk +azi +aSS +azb +aMN +aCg +aCg +aCg +aRN +aCg +ade +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(79,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +ags +ags +ags +ags +ayV +aac +ags +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +aab +aab +ahY +aaE +aqr +aBm +aDI +aiY +akz +aDI +aDI +aDI +aDI +aDI +arK +aDI +ake +aDI +aDI +aDI +ake +aqI +arF +aqI +acy +aOE +aFF +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +aqr +aAa +aAW +aqr +aqr +aqr +aqr +aqr +acy +aqr +aqr +aqr +aqr +aqr +acy +aqr +aqr +aqr +aqr +aab +aab +aab +aab +aab +aph +apR +azd +azl +azb +aSQ +azb +aMN +aCg +aCg +aCg +aCg +aCg +ade +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aED +aED +aED +aED +aAb +aAb +aAb +aAb +aAb +aAb +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(80,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aSR +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aah +aab +aah +aab +aah +aab +ahY +aab +agc +aJz +aae +aiX +akz +akZ +alV +apc +aDI +alG +akz +auA +awR +aNu +aCL +aNu +aDI +aqI +aIs +aqE +anF +aLC +aoQ +aLC +aLC +aLC +aLC +aLC +aLC +aLC +aLC +aLC +aLC +alT +aAd +aTA +aFt +aDf +aOH +aFt +aLC +aLC +bey +beA +beB +beE +beF +beG +aOE +aBX +aBX +aqr +aab +aab +aab +aab +aab +aph +ayZ +azf +azm +aWA +aST +azb +aMN +aqr +aqr +aar +aar +aqr +aqr +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aED +aCh +aYd +aED +aEF +aAb +aAb +aAb +aAb +aAb +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(81,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +ags +ags +ags +ags +ags +ags +aac +ags +ags +ags +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +aqr +abn +aqr +aqr +abn +aqr +aqr +aqr +aqr +acr +aqr +aqr +acr +aqr +aqr +acr +aqr +aqr +acr +aqr +aqr +aqr +aab +aah +aab +aah +aab +aah +aab +ahY +aab +agc +aJz +aae +aiX +akp +aOE +alW +ape +aDI +arb +asa +auH +aqr +axq +aDt +aNu +aDI +aqI +arF +aJh +aqr +agN +aOE +aOE +aOE +aOE +aOE +aOE +aOE +aOE +aOE +aOE +aOE +aFF +aAf +bfA +bfA +bfB +bfA +bfA +bfC +bfC +bfD +bfA +bfA +bfA +bfC +bfE +bfC +bfF +bfC +bfG +bfH +bfH +bfH +bfH +bfH +bfI +bfJ +bfJ +bfK +bfL +bfM +azb +aMN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aED +aED +aKg +aED +aEF +aAb +aAb +aAb +aAb +aAb +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +aRT +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(82,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aaK +aaY +aOE +aOE +amk +abD +abD +aOE +aOE +abJ +act +acL +act +acL +act +acL +act +acL +act +acL +act +acL +aqr +aab +aah +aab +aah +aab +aah +aab +ahY +aaF +aqr +ahq +aic +aiX +akz +aOE +aOE +alO +aDI +are +asd +avm +aqr +aqr +aqr +aEq +aDI +aqI +arF +aqI +aqr +aOE +aOE +aOE +aOE +aOE +aOE +aOE +aOE +aOE +aOE +aOE +aOE +aFF +aOE +abJ +abJ +beJ +abJ +abJ +aOE +aOE +abC +abJ +abJ +abJ +aZa +beH +aOE +aRP +abZ +aqr +awh +aab +aab +aab +aat +aph +apR +apR +ayO +aWA +aRt +azb +aMN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aWs +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aED +aKz +aYy +aED +aZk +aEF +aAb +aAb +aAb +aAb +aEF +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(83,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +akW +aaZ +aOE +aOE +amk +aOE +aOE +aOE +aOE +abJ +acv +acM +acv +adB +acv +adB +acv +adB +acv +adB +acv +acM +aqr +aab +aah +aab +aah +aab +aah +aab +ahY +aab +agc +ahB +aae +aiX +akz +ala +aOE +aOE +aDI +aqr +ash +aqr +aqr +axw +aDI +aDI +aDI +aqI +arF +aqI +aqr +aCv +aoR +aoR +aoR +aoR +aoR +aoR +aoR +aoR +aoR +aoR +aoR +aFF +aOE +aqr +aOE +aFF +aOE +aOE +aOE +aOE +aKm +abJ +abJ +abJ +aOE +aFF +aOE +aOE +aqv +acy +awl +awl +awl +awl +azF +apR +apR +apR +ayO +aWA +aRt +azb +aMN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aED +aKz +aRq +aYW +aEF +aEF +aAb +aAb +aAb +aEF +aEF +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(84,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +akW +aba +aOE +aOE +aqr +aqr +aqr +aqr +aqr +abJ +abJ +abJ +act +adC +act +adC +act +adC +act +adC +act +acL +aqr +aab +aab +aab +aab +aab +aab +aab +ahY +aab +agc +ahB +aae +aiX +akz +alb +alX +abZ +aDI +akz +asu +aHT +awS +axB +aDM +aOE +aOE +aHi +arF +aqI +aqr +aOE +aoR +apz +apz +apz +apz +apz +apz +apz +apz +apz +aoR +aFF +aOE +aqr +aOF +aFF +aOE +aOE +aOE +aOE +aOE +aOE +aAg +aOE +aZH +beI +aLC +aLC +aLC +aQQ +aRu +aRd +aRd +aRd +aRd +aRd +aRd +aRd +aGM +aRo +aRD +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aED +aED +aED +aED +aZk +aEF +aEF +aEF +aEF +aEF +aEF +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(85,1,1) = {" +aJx +aac +aac +aac +aac +aac +aFw +aFw +aFw +aFw +aFw +aFw +aFw +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aOE +aOE +aOE +aOE +aqr +aCe +abQ +aca +aqr +abJ +acw +abJ +acv +adE +acv +adE +acv +adE +acv +adE +acv +acM +aqr +aqr +aqr +aqr +afi +aat +aNf +aab +ahY +aaG +aqr +adR +aDI +aiZ +akz +aOE +aOo +aHT +aqa +arf +asv +aon +alX +axC +aDI +aOE +aqr +aHm +arF +aqI +aqr +agN +aoR +apz +apz +apz +apz +apz +apz +apz +apz +apz +aoR +aFF +abZ +aqr +aar +aDe +aar +aar +abJ +abJ +aOE +aOE +aOE +arI +abJ +beJ +abJ +abJ +aOE +acy +awk +awk +azC +awk +awk +apR +apR +apR +ayO +aWA +aRt +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aED +aGv +aCy +aED +aEF +aEF +aEF +aEF +aEF +aEF +aEF +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(86,1,1) = {" +aJx +aac +aac +aac +aac +aac +aFw +aDC +aOC +aze +aYM +aGz +aFw +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aaL +aOE +aOE +aOE +aqr +aqr +abS +aqr +aqr +acn +acx +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +aqr +abJ +aen +acy +afj +aHI +awl +awl +ahZ +awo +aIj +aQN +aae +aiX +akz +ald +ama +apq +aDI +akz +asw +avo +aOE +axN +aDM +aOE +aar +aqI +arF +aqI +aqr +aOE +aoR +apz +apz +apz +apz +apz +apz +apz +apz +apz +aoR +aFF +aOE +aqr +aCa +aFF +aOE +aEu +abJ +abJ +aOE +aOE +aOE +abJ +abJ +beJ +abJ +abJ +aOE +aqr +aab +aab +aab +aab +aat +aph +apR +apR +ayO +aWA +aRt +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aED +aUl +aMp +aED +aED +aED +aED +aZk +aEF +aJn +aEF +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(87,1,1) = {" +aJx +aac +aac +aac +aac +aac +aFw +aPO +aTX +aKi +aGz +aAo +aFw +aac +aac +aac +ags +ayV +aZS +aNS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +abL +aaN +aqr +akW +aOE +abp +aOE +acy +abJ +abJ +aoD +aci +aco +acz +aFt +adn +aFt +aFt +aFt +aFt +aFt +aFt +aFt +aFt +aFt +aLC +aFt +aFt +aeo +azq +azr +azB +azB +ajG +ayO +agc +aHt +aid +aja +ako +ale +amJ +aEc +aDI +aDI +asz +aDI +aDI +aDI +aDI +aOE +aar +aqI +arF +aqI +aqr +aOE +aoR +apz +apz +apz +apz +apz +apz +apz +apz +apz +aoR +aFF +aAk +aqr +aCb +aFF +aDR +aQO +abJ +abJ +aOE +aOE +aOE +abJ +abJ +beJ +abJ +abJ +aVn +aqr +awh +aab +aab +aab +aab +aph +apR +awm +ayO +aWA +aRt +aWA +aKq +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aMp +aMp +aNR +aMp +aMp +aOW +aVk +aEF +aEF +aEF +ags +ags +aac +aac +aac +aac +aac +aac +aac +aRT +ags +ags +aac +ags +ags +aZS +aZS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(88,1,1) = {" +aJx +aac +aac +aac +aac +aac +aFw +aGJ +aFn +aZb +azp +aTX +aFw +aac +aac +aZS +aZS +aZS +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aaP +aOE +aOE +aOE +aqr +abJ +abT +acb +aqr +acp +acx +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +aqr +abJ +abJ +acy +afC +aKS +awk +awk +ajJ +azA +acy +aQN +aae +ajH +akz +alf +ani +aOE +aOE +aDI +asG +alI +aOE +axP +aKd +aOE +aar +aqI +arF +aqI +aqr +aOE +aoR +apz +apz +apz +apz +atm +apz +apz +apz +apz +aoR +aFF +aOE +aqr +aOE +aOE +aOE +aEv +abJ +abJ +aOE +aOE +aOE +abJ +abJ +beJ +abJ +abJ +aOE +aqr +aab +aab +aab +aab +aat +aph +apR +apR +ayO +aWA +aRt +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aWs +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aMp +aMp +aED +aOR +aMp +aYi +aVk +aEF +aEF +aEF +ags +ags +ags +ags +ags +aac +aac +aac +aac +ags +ags +ags +ags +ags +aZS +aZS +ags +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(89,1,1) = {" +aJx +aac +aac +aac +aac +aac +aFw +aRm +aHF +aZm +aYh +aAt +aFw +aac +aac +aac +ags +aZS +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aOE +aOE +aOE +aOE +aqr +abE +abU +acc +aqr +abJ +acw +abJ +act +adG +act +adG +act +adG +act +adG +act +acL +aqr +aqr +aqr +aqr +afi +aat +aab +aab +ahY +aaE +aqr +ahC +aDI +aiZ +akz +aon +anr +aHT +aHT +arA +aHT +avv +aHT +axR +aDI +aEB +aqr +aHm +arF +aqI +aqr +aOE +aoR +apz +apz +apz +apz +apz +apz +apz +apz +apz +aoR +aFF +abZ +aqr +aCd +aOE +aDS +aar +aAF +abJ +abo +aOE +aOE +abJ +abJ +beJ +abJ +abJ +aOE +acy +azc +awl +awl +awl +azI +apR +apR +apR +ayO +aWA +aRt +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aNH +aZv +aJc +aNe +aMp +aQx +aVk +aEF +aEF +aEF +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(90,1,1) = {" +aJx +aac +aac +aac +aac +aac +aFw +aEX +aIJ +aFK +aQz +aUK +aFw +aac +ags +ayV +aZS +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aaQ +aOE +aOE +aOE +aqr +aqr +aqr +aqr +aqr +abJ +abJ +abJ +acv +adQ +acv +adQ +acv +adQ +acv +adQ +acv +aem +aqr +aab +aab +aab +aab +aab +aab +aab +ahY +aab +agc +aJz +aae +ajH +akz +aOE +aOE +aOE +abZ +aDI +asH +aOE +aqI +aya +aQO +aEK +aOE +aHs +arF +aqI +aqr +aVh +aoR +apz +apz +apz +apz +apz +apz +apz +apz +apz +aoR +aFF +aOE +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +akw +aOE +aRP +aZK +beK +aLC +aLC +aLC +aQQ +aQT +aRd +aRd +aRd +aRd +aRd +aRd +aRd +aGM +aRo +aSk +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aED +aED +aED +aMp +aMp +aYV +aVk +aEF +aEF +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aRT +ags +ags +ags +ags +ags +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(91,1,1) = {" +aJx +aac +aac +aac +aac +aac +aFw +aYb +aWi +aQW +aFM +aTX +aFw +aac +aZS +aZS +aac +aac +aac +aNF +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +abC +aOE +aOE +aOE +amk +aOE +aOE +aOE +aOE +abJ +act +acL +act +adU +act +adU +act +adU +act +adU +act +acL +aqr +aab +aJD +aab +aab +aab +aaB +aab +ahY +aab +agc +aJz +aae +ajH +akz +alg +anS +anS +anS +aDI +aon +aon +awW +ayb +aDI +aDI +aDI +aqI +arF +aqI +aqr +agN +aoR +apz +apz +apz +apz +apz +apz +apz +apz +apz +aoR +aFF +aOE +aAX +aNu +aNu +aqr +aEx +aqr +aEx +aqr +akW +aOE +aOE +aOE +aFF +aOE +aOE +aVJ +acy +awk +awk +awk +azD +awk +apR +apR +apR +ayO +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aOO +aMp +aED +aED +aNR +aED +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(92,1,1) = {" +aJx +aac +aac +aac +aac +aac +aFw +aUr +aGd +aEF +aKi +aOC +aFw +aZk +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aaR +aOE +aOE +aOE +amk +abD +abD +aOE +aOE +abJ +acv +acM +acv +acM +acv +acM +acv +acM +acv +acM +acv +acM +aqr +aab +aab +aab +aab +aab +aab +aab +ahY +aaD +aqr +ahq +aic +ajH +akz +alk +aOE +aOE +aOE +aDI +aDI +aDI +aDI +ayU +aDI +aFC +aDI +aqI +arF +aJi +aqr +aOE +aoR +apz +apz +apz +apz +apz +apz +apz +apz +apz +aoR +aFF +aOE +aqr +aCe +aDg +aqr +aAO +aqr +aAO +aqr +aIg +aOE +aOE +aOE +aFF +aOE +akw +abZ +aqr +awh +aab +aab +aab +aat +aph +apR +apR +ayO +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aQU +aMp +aMp +aMp +aMp +aTT +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(93,1,1) = {" +aJx +aac +aac +aac +aac +aac +aFw +aXK +aKa +aGz +aOC +aEF +aEF +aEF +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +aqr +abn +aqr +aqr +abn +aqr +aqr +aqr +aqr +acr +aqr +aqr +acr +aqr +aqr +acr +aqr +aqr +acr +aqr +aqr +aqr +aab +aab +aab +aab +aab +aab +aab +ahY +aab +agc +ahB +aae +ajH +akz +alx +aOE +apr +aqb +aDI +asK +avP +aDI +ayX +aDO +aGb +aDI +aqI +arF +aJh +aqr +aOE +aoR +aoR +aoR +aoR +aoR +aoR +aoR +aoR +aoR +aoR +aoR +aFF +aOE +aqr +aCe +ans +aqr +aNu +aPs +aNu +aqr +aTS +aOE +aOE +aOE +aFF +azG +akW +amF +aar +aab +aab +aab +aab +aab +aph +apR +apR +ayO +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aPC +aAe +aMK +aBZ +aEH +aED +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(94,1,1) = {" +aJx +aac +aac +aac +aac +ags +aFw +aFw +aEF +aEF +aFw +aEF +aEF +aGJ +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aJV +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +ahY +aab +agc +ahB +aae +ajH +akq +aly +aOE +apF +aqe +aDI +asI +avQ +aDI +azz +aqI +aGc +aDI +aqI +aIw +aqE +anG +aLC +aLC +aLC +aLC +aLC +aLC +atn +aLC +aLC +aLC +aLC +aLC +baX +aOE +aqr +aCe +aNu +aDT +aEy +ajr +ajr +aGX +aLC +aOl +aTj +aLC +baX +aOE +akY +aOE +aqr +aab +aab +aab +aab +aab +aph +apR +apR +ayO +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aED +aED +aED +aED +aED +aED +aED +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +aRT +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(95,1,1) = {" +aJx +aac +aac +aac +aac +aXE +ags +ags +ags +aBL +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +ahY +aaE +aqr +aBm +aDI +aiY +akz +aDI +aDI +aDI +aDI +aDI +asJ +aDI +ake +alR +aDU +aDI +ake +aqI +arF +aqI +acy +aOE +aOE +aOE +aOE +aOE +aOE +aFF +aOE +auD +auD +awA +auD +auD +abZ +aqr +aCe +aNu +aqr +aEA +aFk +aFZ +aqr +anP +anP +aNE +aJQ +anP +anP +aqr +aqr +aqr +aaN +aaN +aaN +aaN +aab +aph +apR +apR +ayO +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aWs +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aWs +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aSl +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(96,1,1) = {" +aJx +aac +aac +aac +aac +aac +ags +ags +aLF +ags +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +ahY +aab +agc +ahB +aae +ajH +akz +ahC +aQN +ahC +aqf +aqI +aqI +aqI +axp +aqI +aqI +aqI +aqI +aqI +arF +aqI +aqr +aOE +aOE +aOE +aOE +aOE +akj +ato +aqr +auF +avx +awC +auF +auF +aqr +aqr +aCf +aDi +aqr +aqr +aqr +aqr +aqr +aOE +aOE +aFF +aOE +aOE +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +apR +apR +ayO +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(97,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +ags +aKy +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +avF +aac +aac +aZS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +ahY +aab +agc +ahD +aae +ajI +ako +akV +aHt +aoW +aHt +aqE +aup +aqE +aqE +aqE +aqE +aqE +aqE +aqE +aIK +xmW +aqr +agN +aOE +aOE +aOE +aOE +aOE +atp +aqr +auG +apy +apy +avy +apy +aAl +aqr +aCi +aDl +aDV +aEE +aFl +aGa +aqr +aHz +aIf +aIM +akw +aOE +aLi +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +apR +awk +awn +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(98,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aFV +ags +ags +ags +ags +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +ahY +aab +aqr +aOE +aDI +ajK +akr +adR +aQN +adR +aQN +arB +arF +aww +aqI +aqI +aqI +aqI +awB +aqI +aqI +aJo +aqr +aOE +azG +akW +amF +aOE +aOE +atq +atL +auI +auI +auI +auI +axX +aAm +aqr +aCj +aDn +aDW +aEI +arJ +arJ +aqr +aHA +aOE +aIN +akW +aOE +aHA +aar +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aLU +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(99,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +ahY +aau +aqr +aDI +aDI +aBm +ake +aDI +anT +aDI +aqr +aQN +aNE +aQN +aqr +aqr +aDY +aqr +aOJ +aqr +aIX +aqr +aqr +agB +aOE +aOE +aOE +aOE +aOE +aOE +aqr +auJ +apy +apy +axz +axY +aAn +aqr +apy +aCk +apy +arJ +arJ +aGl +aqr +akY +aOE +aIR +akY +aOE +akY +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aLU +ags +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aZS +aZS +ags +ags +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRU +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRU +aac +aac +aJx +"} +(100,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ayV +aZS +ags +ags +ags +ags +ags +ags +ags +ags +aSl +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +ahY +aab +aqr +ahF +aie +ajL +aqr +acc +abJ +apG +aqr +aOE +aFF +aOE +aqr +acc +abJ +aGf +aqr +acc +abJ +aJE +aqr +akw +aOE +aOE +akw +aOE +aOE +akw +aar +auK +apy +awT +awT +axY +apy +axO +aCk +aDn +apy +aEI +arJ +arJ +aGY +aOE +aOE +aFF +aOE +aVJ +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aLU +aZS +aZS +aZS +aZS +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aZS +aZS +aZS +ags +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +aRU +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(101,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ayV +aac +aac +aac +aac +aac +aNF +ags +ags +ags +ags +ags +ags +aBD +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +ahY +aab +aqr +ahG +aiz +akb +aqr +alA +anV +abE +aqr +aOE +aFF +aOE +aqr +alA +anV +abE +aqr +alA +anV +abE +aqr +aof +aOE +akj +aqJ +amF +aOE +atr +aar +auL +apy +auK +auK +axZ +auI +aBa +auI +aDo +aDX +aEM +aFo +aGm +aqr +aOE +aOE +aDA +aOE +aOE +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aZS +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aRT +ags +ags +ags +ags +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(102,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +ags +avE +ags +aEb +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +ahY +aab +aqr +aqr +adR +aqr +aqr +aqr +aar +aqr +aqr +aIj +ahr +acy +aqr +aqr +aar +aqr +aqr +aqr +aar +aqr +aqr +akY +aOE +aOE +akY +aOE +aOE +akY +aar +auW +avy +awU +axA +ayc +aAq +aqr +aCn +aDq +aEa +aqr +aqr +aqr +aqr +akw +aOE +aIM +akw +aOE +akw +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +aaN +aqr +aac +aac +aac +aac +aZS +aZS +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +ags +ags +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(103,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +ahY +aab +aab +aab +aab +aab +abK +aab +aab +aab +acT +aHI +aRk +awo +aeD +aeW +aab +aab +agz +aab +aab +aaF +aqr +aOE +aOE +aOE +aOE +aOE +ase +aOE +aqr +avl +avO +awV +axM +apy +aAs +aqr +aqr +aDr +aqr +aqr +aFp +aFp +aqr +akW +aOE +aIS +aJZ +aOE +akW +aar +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aEN +aaN +aMR +aBE +aqr +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMv +aMv +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aMv +aMv +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(104,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aWL +ags +ags +aac +aac +aZS +ayV +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +ahY +aab +aab +aab +aab +aab +abK +aab +aab +aab +aab +aKP +ano +ayO +apR +apR +apR +apR +apR +apR +apR +apR +acy +aOE +aOE +akj +aqK +amF +aOE +aOE +atM +apy +awq +apy +apy +ayd +apy +atM +aOE +aFF +aLC +aLC +aFs +aEc +aqr +aHB +aOE +aIR +akY +aOE +aLj +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aYA +aOE +aAU +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMv +aNY +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aNY +aMv +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(105,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +ahY +aab +aab +aab +aab +aNw +abK +aab +aab +aab +aab +aKP +ano +ayO +aat +aab +aab +aaF +apR +aab +aau +aab +aqr +aqr +aar +aqr +aqr +aqr +aar +aqr +aqr +aqr +awr +aqr +axO +atM +aqr +aqr +agN +aDs +aOE +aqr +aFu +aGp +aqr +aHC +aJM +aFF +aOE +aOE +aVJ +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +abY +aZB +aSj +aMc +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMv +aOf +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aPF +aMv +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(106,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +ahY +aab +aab +aab +aab +aNw +abK +aab +aab +aab +aab +aKP +ano +ayO +aab +aeX +aeX +aeX +apR +aeX +aeX +aeX +anP +aNu +aNu +apA +akv +aNu +aNu +aNu +akv +aNu +aNu +awX +aNu +aNu +aAv +aqr +aCo +aDw +auF +aqr +aqr +aqr +aqr +aOE +aOE +aFF +aOE +aOE +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aXX +aaN +afZ +abY +aBH +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMv +aOf +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aPF +aMv +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(107,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +ahY +aab +aab +aab +aab +aab +abK +aab +aab +aab +aab +aKP +ano +ayO +aab +aLU +aLU +aLU +apR +aLU +aLU +ahE +anP +aom +aoS +aoS +aoS +aNu +aoS +aoS +aoS +aNu +aoS +aoS +aoS +aNu +aAx +aqr +aOE +aFF +abZ +aqr +aFv +aGs +aGZ +auD +aOE +aFF +akw +aOE +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aEZ +aWR +aaN +aqr +aqr +aac +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMv +aOQ +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aPF +aMv +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(108,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +aab +aat +aab +aab +aab +aab +aab +aab +aab +ahY +aab +aab +aab +aab +aab +abK +aab +aab +aab +aat +aKP +ano +ayO +aab +aLU +aeX +aeX +apR +aeX +aeX +aLU +anP +aNu +aNu +aNu +aNu +aNu +aNu +aNu +aNu +ard +aNu +aNu +aNu +aNu +aNu +axO +aOE +aDA +aOE +aEP +aNu +aNu +aGZ +awA +aOE +aIW +aJZ +amF +aOE +aar +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMG +aEF +aEF +aEF +aEF +aPG +aEF +aEF +aEF +aEF +aMG +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(109,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aZS +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aiT +azB +azB +azB +azB +azB +azB +aRd +aRd +aRd +aRd +aRd +aRd +aRd +aRd +akd +aRd +aRd +aRd +aRd +aRd +aRd +aRd +aRd +aRd +aRd +azr +aTc +ayO +aCI +aCI +aCI +aCI +apR +aCI +aCI +aCI +anQ +aNu +aNu +apB +aqL +ard +aNu +ats +atN +aNu +awu +awY +aNu +aNu +aNu +aBc +aOE +aFF +aOE +aEQ +aNu +aNu +aHa +auD +aOE +aFF +akY +aIh +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMG +aEF +aEF +aEF +aEF +aPG +aEF +aEF +aEF +aEF +aMG +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(110,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +ayV +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aaN +aab +aab +ano +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aat +apR +aab +aab +aab +aab +aab +abK +aab +aab +aab +aat +aKP +ano +ayO +aab +aLU +aeX +aeX +apR +aeX +aeX +aLU +anP +aNu +aNu +aNu +aNu +aNu +aNu +ard +aNu +aNu +aNu +aNu +aNu +aNu +aNu +auF +aOE +aFF +aVJ +aCo +aNu +aGt +aGZ +auD +aOE +aFF +aOE +aOE +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMv +aNY +aEF +aEF +aEF +aPG +aEF +aEF +aEF +aNY +aMv +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(111,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aZS +aZS +ags +aTO +ags +ags +aTO +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aNv +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +aqr +aqr +aar +aar +aqr +aqr +aqr +aab +aab +aab +aab +aab +ano +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +apR +aab +aab +aab +aab +aab +abK +aab +aab +aab +aab +aKP +ano +ayO +aaF +aLU +aLU +aLU +apR +aLU +aLU +ahE +anP +aom +aoS +aoS +aoS +aNu +aoS +aoS +aoS +aNu +aoS +aoS +aoS +aNu +aAx +aqr +aCr +aFF +aEc +aqr +aNu +aNu +aGZ +aHG +aOE +aFF +akw +aOE +abZ +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMv +aPe +aEF +aEF +aEF +aPG +aEF +aEF +aEF +aPF +aMv +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(112,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aZS +aZS +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aZS +aZS +aac +aac +aac +aNv +aNv +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +aFu +aqr +aOE +aOE +aOE +asK +aOE +aqr +aqr +aqr +aab +aab +aab +ano +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +apR +aab +aab +aab +aab +aab +abK +aab +aab +aab +aab +aKP +ano +ayO +aab +aeX +aeX +aeX +apR +aeX +aeX +aeX +anP +aNu +aNu +apE +aqM +aNu +aNu +aNu +aqM +avn +aNu +apE +aNu +aNu +aAy +aqr +aqr +aDF +aqr +aqr +aFx +aNu +aHb +auD +aOE +aIY +aKb +amF +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aRW +aRW +aRW +aMv +aPf +aEF +aEF +aEF +aPG +aEF +aEF +aEF +aPF +aMv +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(113,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +ags +ags +ags +ags +aTO +ags +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +ags +ags +ags +aZS +aZS +aZS +aZS +aZS +aNv +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +aar +aqr +aqr +abb +aOE +aaS +aOE +aRP +aOE +aOE +aOE +aOE +aga +aqr +aab +aab +aat +ano +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aab +aab +aab +aab +abK +aab +aab +aab +aab +aKP +ano +ayO +aat +aab +aab +aab +apR +aaD +aab +aab +aqr +aqr +aar +aqr +aqr +aqr +arm +aiF +aqr +aqr +avr +aqr +aqr +avr +aqr +aqr +aCw +aFF +aEd +aqr +aNu +aNu +aHc +auD +aOE +aFF +akY +aOE +aOE +aar +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRT +aRW +aRW +aRW +aMv +aPg +aEF +aEF +aEF +aPG +aEF +aEF +aEF +aPF +aMv +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(114,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ayV +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aZS +aZS +aNv +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aak +aOE +aCw +aqr +abc +aOE +aqr +aOE +aby +aby +aby +aby +aby +aOE +aar +aHI +awl +awl +aoZ +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aab +aab +aab +aab +abK +aab +aab +aab +aab +aKP +ano +ayO +apR +apR +apR +apR +apR +apR +apR +apR +anR +aoo +aoT +apI +aqr +arg +arm +auU +atO +aqr +aOE +axr +axQ +aLC +aAz +aqr +aCz +beH +abZ +aqr +aNu +aNu +aGZ +auD +aOE +aFF +aOE +aCv +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aRW +aRW +aRW +aMv +aPh +aEF +aEF +aEF +aPG +aEF +aEF +aEF +aPF +aMv +aRW +aRW +aRW +aRU +aac +aac +aJx +"} +(115,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +ayV +aNS +ags +ags +ags +ags +ags +ags +ags +ags +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aNv +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aCz +aOE +aaz +aqr +abf +aJM +abu +auD +aby +aby +aby +aby +aby +aLC +acW +azr +azB +azB +aqD +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aab +aab +aab +aab +abK +aab +aab +aab +acU +aKS +aRg +awn +aeE +aeZ +aab +aab +agA +aaF +aab +aab +aqr +aop +auU +apJ +aqr +ark +asf +asf +auU +avr +aOE +aOE +aFF +ayY +aAB +aqr +aCB +aFF +aOE +aqr +aNu +aNu +aGZ +aHJ +aOE +aFF +aOE +aOE +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +ayO +aWA +aWA +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMv +aPk +aEF +aEF +aEF +aPG +aEF +aEF +aEF +aPF +aMv +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(116,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +ags +aac +aac +ags +ags +aTO +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aOE +aVJ +aOE +aqr +abg +aOE +abh +auD +aby +aby +aby +aby +aby +aOE +aar +aKP +aCI +aCI +ayO +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aab +aab +aab +aab +aqr +aqr +aar +aqr +aqr +acy +ahr +acy +aqr +aqr +aar +aqr +aqr +aqr +aar +aqr +aqr +aop +auU +apK +aqP +arm +asf +asf +atP +aqr +aqr +aqr +axS +aqr +aqr +aqr +aqr +aDF +aqr +aqr +aFz +aqr +aqr +aqr +aqr +aNE +aQN +aqr +aqr +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +apR +awl +awo +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMv +aPn +aEF +aEF +aEF +aPG +aEF +aEF +aEF +aPF +aMv +aRW +aRW +aRW +aac +aac +aac +aJx +"} +(117,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +ags +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aal +aHJ +aOE +aaS +aOE +aOE +abh +auD +aRP +aOE +aOE +aOE +aOE +acC +aqr +aKS +awk +awk +awn +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aab +aab +aab +aab +aqr +aej +aOE +afp +aqr +ahg +ahs +ahg +aqr +aiW +ajV +aks +alz +ajV +amK +aiW +aqr +aop +auU +apJ +aqr +auU +asf +asf +arm +avs +aFt +aVe +bef +aFt +aFt +aFt +aFt +aFt +aFt +aFt +aFt +aFt +aFt +aFt +aFt +aTD +abJ +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aph +apR +apR +ayO +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMv +aPp +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aPF +aMv +aRW +aRW +aRW +aac +aac +aac +aJx +"} +(118,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +aqr +aqr +aqr +aqr +abh +abq +abh +aOE +aOE +aOE +aVh +aOE +aCv +acj +aqr +aqr +aqr +aqr +aqr +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aab +aab +aab +aab +aar +aek +aOE +afz +agu +ahg +ahx +aiA +aiE +ajb +aLC +aLC +alT +aLC +aLC +anm +anU +aor +apa +apJ +aqr +arw +asg +att +auU +aqr +abJ +beJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +beJ +abJ +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +ayQ +awk +awk +awn +aWA +aRs +aWA +aKq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMv +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aMv +aRW +aRW +aRW +aac +aac +aac +aJx +"} +(119,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aag +aam +aay +aaA +aqr +aqr +aOE +aOE +aby +aby +aby +aby +aOE +aOE +aqr +aqr +aaA +aay +aam +aag +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aab +aab +aab +aab +aqr +aez +aOE +aOE +agv +ahg +ahs +ahg +aiF +ajc +ajW +aOE +alY +aOE +amO +ann +aiF +aop +apb +apM +aqr +aqr +aqr +aqr +aqr +aqr +abJ +beJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +abJ +aTE +abJ +aqr +aqr +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMv +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aMv +aRW +aRW +aRW +aac +aac +aac +aJx +"} +(120,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaf +aOE +aOE +aRP +aOE +aaT +aqr +aOE +aOE +abz +abM +abN +acd +aOE +aOE +acE +acY +aOE +aOE +aOE +aOE +ael +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aHI +awl +awl +awl +awo +aqr +aeA +aOE +aOE +aqr +aOE +aFF +aOE +aiG +ajd +aOE +akt +aqr +amE +aqr +aqr +aqr +aop +apb +apJ +aqr +arx +auU +atu +atQ +aqr +aBt +beJ +abJ +aqr +aqr +aqr +aqr +aqr +aBY +aqr +aqr +aqr +aqr +aqr +aqr +aNE +aQN +aqr +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMv +aNY +aEF +aNZ +aNZ +aNZ +aNZ +aNZ +aEF +aNY +aMv +aRW +aRW +aRW +aac +aac +aac +aJx +"} +(121,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaf +aOE +aOE +aOE +agl +agl +abi +aCv +aOE +abz +abN +abV +acd +aOE +aOE +acH +adf +aii +aOE +aIh +aOE +ael +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aKS +awk +apR +apR +ayO +aqr +aqr +aOE +afA +aqr +aOE +aFF +aiC +aqr +aiW +ajV +aku +aqr +aNu +amQ +anp +anW +aop +apb +apJ +aqr +arx +asi +atv +atR +aqr +aar +aJp +aar +aqr +aAC +aBd +aCC +aqr +aEe +aEf +aFB +aOE +aOE +aHK +aqr +aFF +aJM +aQO +aRb +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aMv +aMG +aMG +aMv +aMv +aMv +aMv +aMv +aMv +aMv +aPH +aRW +aRW +aRW +aac +aac +aac +aJx +"} +(122,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaf +aai +aOE +aOE +agl +aaU +abj +aOE +aOE +abz +abO +abN +acd +aOE +aOE +aOJ +adh +adA +aOE +aOE +aOE +ael +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aaF +aKP +apR +abr +aqr +aeB +aOE +aOE +aqr +agB +aFF +abZ +aqr +aqr +aqr +aqr +aqr +aNu +aNu +aNu +aNu +aop +apb +apJ +aqr +ary +asj +atx +atS +aqr +agN +aFF +agQ +aqN +aAE +aBe +aCD +aqr +aEf +aEf +aqr +aGw +aCv +aHL +aqr +aQb +aLC +aQR +baX +aar +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aac +aac +aac +aJx +"} +(123,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aED +aED +aED +aED +aED +aED +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aaj +aOE +aOE +aaH +aaV +aOJ +aOE +aOE +abz +abP +abN +acd +aVJ +aOE +aqr +adi +aii +aOE +aai +acu +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aab +aKP +apR +abr +aqr +aeC +aVJ +aOE +aqr +agO +aFF +aOE +aiH +ajk +ajk +ajk +ajk +ajk +ajk +ajk +ajk +aos +apb +apJ +aqr +arz +asj +asj +auo +avt +aOE +aXj +aHT +azt +aAH +aqN +aAI +aqr +aqr +aqr +aqr +aOE +aOE +abZ +aqr +aQc +aOE +aQO +aQO +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aED +aED +aED +aED +aED +aED +aED +aED +aED +aED +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aac +aac +aac +aJx +"} +(124,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aac +aac +aac +aac +aac +aac +aED +aMp +aMp +aPx +aAZ +aED +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +aqr +aao +aqr +aqr +aqr +aqr +aOE +aby +aby +aby +aby +aOE +aqr +aqr +aqr +aqr +aao +aqr +aqr +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aab +aKP +aCI +ayO +aar +aeF +aOE +afE +aqr +aOE +ahP +aqv +aiL +ajm +ajm +ajm +alZ +ajm +ajm +ajm +anX +aot +apd +apV +aqQ +arE +asx +aty +auU +aar +aOE +aFF +agQ +azx +aqN +aqN +aCH +aqr +aEh +aET +aFD +aby +aby +aby +aqr +aFF +aOE +aOE +abZ +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aCx +aYy +aYy +aKg +aKZ +aWS +aIz +aMp +aMp +aED +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aRU +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRU +aRW +aRW +aRW +aRW +aRW +aRU +aac +aac +aac +aJx +"} +(125,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aED +aMp +aMp +aMp +aMp +aED +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aOq +aan +aqr +aan +abl +aqr +agN +aOE +aOE +aIh +aOE +abZ +aqr +abl +aan +aqr +aan +aOq +aqr +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aab +aaM +abd +awn +aqr +aeG +aOE +aga +agx +aOE +ahP +aOE +aqr +ajn +aNu +aNu +aNu +aNu +aNu +ans +aqr +aop +apb +apJ +aqr +arH +asy +atH +auq +aqr +aOE +aFF +agQ +azH +aAI +aBh +aqN +aqr +aET +aET +aqr +aGA +aby +aee +aIj +aFF +aOE +aOE +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aYy +aYy +aTH +aED +aLQ +aLQ +aED +aMp +aKY +aED +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aMv +aMG +aMG +aMv +aMv +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aac +aac +aac +aac +aJx +"} +(126,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aac +aac +aac +aac +aac +aED +aMp +aMp +aQs +aWo +aED +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aan +aOg +aqr +aaW +aan +aqr +acP +aOE +aOE +aOE +aOE +acP +aqr +aan +aaW +aqr +aOg +aan +aqr +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aaD +aqr +aqr +aqr +aqr +aqr +aeI +aOE +aOE +aqr +aqv +aFF +aOE +aqr +ajo +ajo +ajo +ajo +ajo +ang +ant +aqr +aou +apb +apM +aqr +aqr +aqr +aqr +aqr +aqr +aOE +aFF +aar +aqr +aAK +aAK +aAK +aqr +aqr +aqr +aqr +aby +aby +aee +anP +beH +aOE +aOE +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aYy +aXU +aYy +aED +aED +aED +aJc +aMp +aUX +aED +aXF +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aZS +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aMI +aMI +aMI +aNi +aMv +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aac +aac +aac +aac +aac +aJx +"} +(127,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aED +aED +aED +aED +aGo +aED +aED +aED +aED +aED +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +aqr +aqr +aqr +abm +aqr +aqr +aqr +aVh +aOE +aqr +aqr +aqr +abm +aqr +aqr +aqr +aqr +aqr +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aqr +acO +ady +adS +aqr +aeI +afh +aeO +aqr +aOE +ahQ +abZ +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aov +apb +apJ +aqr +amH +amH +aon +aon +aqr +aOE +aFF +aOE +aqr +aqR +arh +aqN +aqr +aPV +aEW +aFG +aGF +aby +aby +acy +aFF +aOE +aOE +aOE +aar +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aED +aED +aED +aED +aPc +aPx +aMp +aMp +aMp +aAc +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aNc +aMI +aMI +aPt +aMv +aRW +aRW +aRW +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aJx +"} +(128,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aED +aER +alw +aMp +aVD +aED +aQF +aYy +aCx +aED +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aaI +aOE +aOE +aFN +abv +aOJ +aOE +aOE +aOJ +ack +acq +aOE +aai +acu +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aqr +adg +adF +adT +aqr +aeJ +afk +agb +aqr +aOE +ahR +aOE +aqr +ajp +ajX +akv +amb +aqr +anh +anu +anZ +aop +apb +apJ +aar +aOE +aOE +aOE +aOE +aqr +aOE +aFF +aOE +aqr +aqN +ari +aqN +aqr +aEi +aEY +aqr +aQi +aHe +aHO +aqr +aFF +ajO +ajO +ajO +aqr +aaN +aaN +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aQx +aZj +aZj +aMp +aMp +aNb +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aNc +aMI +aMI +aPu +aMv +aRW +aRW +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(129,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aED +aNG +alQ +aMp +aMp +aGo +aYy +aKc +aYy +aED +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaq +aai +aOE +aJM +aFN +abw +abA +aOE +aCv +ace +acl +acq +aCv +aOE +aOE +aeg +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aqr +aqr +aqr +adI +aqr +aqr +aqr +aqr +aqr +ahj +beI +aLC +aiM +ajr +ajY +aNu +amc +aqr +anh +anC +aNu +aop +aps +apV +aqT +aLC +asA +atJ +aur +aqr +agN +aFF +aOE +aqu +aqO +ari +aES +aqr +aqr +aqr +aqr +aOE +aHh +aHP +aqr +aQc +ajO +ajO +aRf +aqr +aab +aab +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aVr +aQx +aNg +aMp +aMp +abe +aXF +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aNc +aMI +aMI +aPw +aMv +aRW +aRW +aRW +aRU +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(130,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +ags +ags +aac +aac +aac +aED +aTi +arl +aCE +aMp +aED +aVR +aYy +aOk +aED +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaq +aOE +aOE +aOE +aOE +aOE +abB +aOE +aOE +acf +aOE +aOE +aOE +aOE +aOE +aeg +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aae +adj +aOE +aFF +aef +aeK +aeK +aOE +aOE +aeK +aFF +aOE +aqr +ajC +aNu +akX +amd +aqr +anj +anD +anu +aop +apb +apJ +aar +aon +aOE +atK +aus +aqr +aOE +aFF +aOE +aqr +aqN +ari +aHM +aqr +aPW +aPX +aFD +aOE +aeK +aHQ +aqr +aFF +ajO +aQZ +aRh +aqr +aab +aab +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aZS +ayV +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aPc +aMp +aBw +aMp +aKY +aED +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aNc +aMI +aMI +aPy +aMv +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(131,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aBD +aac +ags +ags +aac +aac +aac +aac +aED +aFP +aMp +aMp +aIQ +aED +aYy +aYy +aYy +aED +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaq +aOE +aOE +aOE +aOE +abx +aqr +aOE +aOE +aqr +acm +aOE +aOE +aVJ +aOE +aeg +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aae +adk +adH +adV +aeh +aLC +afl +age +aLC +ahk +ahV +aOE +aqr +ajD +ajZ +alh +amx +aqr +ank +anE +anE +aop +apb +apJ +aqr +arL +aOE +aii +aii +aqr +aOE +aFF +aOE +aqr +aqS +arj +aJj +aqr +aEf +aQh +aqr +aQj +aOE +aQm +aqr +aFF +ajO +ajO +aRj +aqr +aab +aab +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aZS +aZS +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +azy +aKB +aMp +aMp +aZE +aED +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +ags +ags +aac +aac +aac +aac +aac +aNd +aMI +aMI +aPt +aMv +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(132,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +ags +ags +aFh +aMp +aMp +aCA +aNa +aED +aYy +aXU +aYy +aED +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aaJ +aaX +aay +abo +aqr +aqr +aOE +aOE +aqr +aqr +abo +aay +aaX +aaJ +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aqr +adl +adI +adl +aqr +aqr +aqr +aqr +aqr +aOE +aFF +aqv +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aow +apt +apY +aqr +aar +aar +aar +aqr +aqr +aar +aJp +aar +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aQf +ajO +ajO +ajO +aqr +aab +aab +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aVE +ags +aAL +aKt +aac +aac +aac +aac +aac +aac +aac +aac +aac +aED +aED +aED +aED +aED +aED +aED +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +ags +aac +aac +aac +aac +aac +aNi +aMI +aMI +aMI +aMv +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(133,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aCO +ags +ags +ags +ags +ags +aac +aac +ags +alv +abe +aED +aED +aED +aED +aED +aED +aED +aED +aED +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +aqr +aqr +aqr +aqr +aaQ +aby +aby +acg +aqr +aqr +aqr +aqr +aqr +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aqr +adm +aFF +adX +aqr +aeO +afm +agf +aqr +ahg +ahs +ahg +aOE +ajE +aeK +aeK +aeK +aOE +aOE +aOE +ajE +ahg +ahs +ahg +aOE +aOE +aOE +aOE +asK +acy +abJ +beJ +axT +aqr +aAM +aqr +aAM +aqr +aNk +aNk +aNk +aNk +aNk +aqr +ayf +aFF +aOE +aOE +aOE +aqr +aab +aab +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aXI +ags +ags +aKt +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aMI +aMI +aMI +aNi +aMv +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(134,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aar +abC +aby +aby +abW +aar +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aqr +ado +adJ +adY +aqr +aqv +aOE +anJ +aqr +ahg +ahs +ahg +aOE +aeK +aeK +aOE +aOE +aOE +aOE +aOE +aOE +ahg +ahs +ahg +aOE +aOE +aOE +aOE +aOE +anP +abJ +beJ +abJ +aqr +aAO +aqr +aAO +aqr +aNu +aOI +aNu +aNu +aNu +aqr +ayg +aQL +ajO +ajO +aVh +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aWz +ags +aSl +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aQa +aZL +ags +ags +ags +ags +aac +aac +aac +aac +aNm +aMI +aMI +aPt +aMv +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(135,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aar +aaR +aby +aby +ach +aar +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aae +adp +adK +adZ +aqr +aeS +aOE +agg +aqr +ahg +ahW +aiA +aLC +aLC +aLC +aTj +aLC +aLC +age +age +aLC +aiA +apv +aiA +aLC +aTj +aLC +aLC +aLC +anF +aFt +axs +abJ +aNu +aNu +aPs +aNu +aqr +aqr +aqr +bfd +aqr +aqr +aqr +azo +aQL +ajO +ajO +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aFJ +aBA +ags +aEb +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +aRO +aEG +aEG +aAi +ags +ags +ags +aac +aac +aac +aac +aNm +aPq +aMI +aPt +aMv +aRW +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(136,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +aJM +aOE +aqr +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aqr +adq +adL +aea +aqr +aeT +aOE +agh +aqr +agd +aif +aiD +aqr +aqr +aqr +adI +aqr +aqr +aqr +afU +acS +aox +aqr +aqr +aqr +arM +aqr +aqr +aqr +aqr +awv +beJ +abJ +aqr +aNu +apE +apE +aqr +aNx +aPs +aNu +aNu +aNu +aNu +aOE +aQL +ajO +ajO +aOE +aRn +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aWz +aWz +aUi +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +ags +ags +ags +aBb +aEG +aNq +aEG +aAi +ags +ags +aac +aac +aac +aac +aNm +aMI +aMI +aPt +aMv +aRW +aRW +aRW +aRU +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(137,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aDj +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aar +aar +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aqr +ads +aFF +aeb +aqr +aeU +afn +aOE +aqr +aqr +aqr +aqr +aqr +ajF +aka +ali +amy +amG +aqr +aqr +aqr +aqr +aqr +aqd +aOE +aFF +asB +asB +asB +aqr +abJ +beJ +axU +aqr +aqr +agK +agK +aqr +aNL +aNu +aNu +aNu +aNu +aqr +aAP +aQL +ajO +ajO +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aDE +aXZ +ags +aYY +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +ags +ags +aZS +ags +ags +ags +ags +ags +aBR +aLL +aAN +aEG +aEw +ags +aac +aac +aac +aac +aNm +aMI +aMI +aPt +aMv +aRW +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(138,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aae +adu +adM +aec +aqr +aeV +aOE +adN +aqr +akg +aOE +aOE +aOE +aOE +aOE +aOE +aeK +aeK +aeK +aOE +aoa +aoy +aqr +aqg +aLC +baX +aOE +aOE +aOE +aqr +abJ +beJ +abJ +aqr +aNu +awX +awX +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aCv +aQL +ajO +ajO +abZ +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aDH +aac +aac +aFY +ags +ags +ags +aWz +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aZS +aZS +ags +ags +ags +ags +aRO +aEG +aUx +aEG +aUn +ags +ags +ags +aac +aac +aac +aNm +aMI +aMI +aPt +aMv +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(139,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aqr +adv +adO +aed +aqr +afc +aOE +agp +agy +aOE +aig +ahg +ahg +aOE +ahg +ahg +ahg +aqv +ahg +ahg +ahg +aOE +aqr +aqs +aOE +aOE +aOE +aOE +aOE +aqr +awx +beJ +abJ +aNu +aNu +aBi +aNu +aqr +aEj +aOE +aqr +aEj +aOE +aqr +aFN +aFF +aOE +aOE +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aIV +aZS +ags +ags +aBD +aDE +ags +ags +ags +ags +ags +ags +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aBb +aEG +aEG +aUn +ags +ags +ags +ags +aac +aac +aac +aMI +aMI +aMI +aNi +aMv +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(140,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aqr +adw +adP +aee +aqr +afd +afo +agq +aqr +ahl +aih +ahg +ahg +aOE +ahg +ahg +ahg +aOE +ahg +ahg +amB +aoz +aqr +aqF +aOE +arN +asC +asC +asC +aqr +abJ +beJ +abJ +aqr +aAO +aqr +aAO +aqr +aEk +aOE +aqr +agN +aOE +aqr +aOE +aFF +aVJ +aOE +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aIV +ayV +ayV +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aQv +aQk +ags +ags +ags +ags +aac +aac +aac +aac +aNi +aMI +aMI +aMI +aMv +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(141,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aHp +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +apR +aab +aqr +aqr +adR +aqr +aqr +aqr +aqr +aqr +aqr +ahm +ahg +ahg +aiU +ajM +ahg +ahg +amB +amH +amB +ahg +aob +aoA +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +acy +ahr +acy +aqr +aAS +aqr +aAS +aqr +aEl +aOE +aqr +aGH +aOE +aqr +aOE +aFF +aOE +aOE +aOE +aar +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aIV +aDH +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +ags +aac +aac +ags +ags +aac +aac +aac +aMI +aMI +aMI +aMI +aMv +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(142,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +ags +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +apR +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aho +aiq +aOE +aiV +ajU +akn +alj +amC +amI +anl +aOE +agp +aoB +aqr +akg +aRP +aOE +asK +aOE +aOE +aOE +abJ +beJ +abJ +aqr +aqr +aqr +aqr +aqr +aqr +aFe +aFH +aqr +aHl +aqr +acy +ahr +acy +aqr +aRl +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +ags +ags +aac +aac +aac +aNd +aMI +aMI +aPt +aMv +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(143,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ayV +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +apR +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +aqr +aqr +aqr +aar +aqr +aqr +aqr +aar +aqr +aqr +aqr +aqr +aqr +aOE +aOE +aOE +aVJ +aOE +aOE +aOE +abJ +axt +aFt +aLC +aLC +aBj +aLC +aLC +aLC +aFf +aBj +aLC +aLC +aLC +aLC +baX +aOE +aqr +aQO +aqr +aaN +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aZS +aZS +aZS +aZS +aZS +aac +aac +aNc +aMI +aMI +aPz +aMv +aRW +aRW +aRW +aRU +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(144,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +aac +ags +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +apR +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aab +aau +aab +aab +aeW +aab +aab +aab +aab +aab +aau +aab +aqr +aJM +aOE +aOE +aOE +aOE +aCv +aOE +abJ +abJ +abJ +aOE +aOE +aOE +aOE +aJM +aOE +aOE +aOE +aVJ +aOE +aOE +aga +aOE +abZ +aqr +aqr +aqr +aaN +aaN +aaN +aaN +aYI +aYI +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aac +aac +aNc +aMI +aMI +aPB +aMv +aRW +aRW +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(145,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +ags +ags +ags +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +apR +acy +aOE +aOE +aOE +asL +aOE +aOE +aOE +abJ +abJ +axV +aOE +aVh +aOE +aOE +aOE +aOE +aOE +aVJ +aOE +aOE +aOE +aOE +aOE +aOE +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +ags +aac +aac +aNc +aMI +aMI +aPE +aMv +aRW +aRW +aRW +aRW +aRW +aRW +aac +aac +aac +aac +aac +aac +aJx +"} +(146,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aGn +ags +ags +ags +ags +ags +ags +ags +aZS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aqr +aar +aqr +aqr +aar +aqr +aqr +acy +anP +acy +aqr +aqr +aar +aqr +aqr +aar +aqr +aqr +aar +aqr +aqr +aar +aqr +aqr +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aNV +aMI +aMI +aPt +aMv +aRW +aRW +aRW +aRW +aRW +aRW +aRU +aac +aac +aac +aac +aac +aJx +"} +(147,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +amL +aHI +awl +awo +aWy +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aMI +aMI +aMI +aNi +aMv +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aac +aac +aac +aac +aac +aJx +"} +(148,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +ags +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aWs +aaN +aaN +aaN +aaN +aaN +aaN +aRv +aaN +azK +aaN +aaN +azK +aaN +aaN +aAD +aab +aab +aab +aVt +aaN +aVt +aaN +aRv +aKP +ana +ayO +aaD +aab +azK +aaN +aaN +azK +aaN +aaN +aRv +aaN +azK +aaN +aaN +azK +aaN +aaN +aAD +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aMv +aMG +aMG +aMv +aMv +aRW +aRW +aRW +aRU +aRW +aRW +aRW +aRW +aRW +aac +aac +aac +aJx +"} +(149,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aFc +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aWs +aaN +aZM +aGr +aaN +aaN +azK +aaN +aWs +aaN +aaN +aab +aab +aab +aaN +aaN +aaN +aAD +amM +aKP +apR +ayO +afq +afK +aaN +aaN +azK +aaN +aaN +aaN +aZM +aGr +aaN +aWs +azK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aRU +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRU +aac +aac +aJx +"} +(150,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +ags +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aYI +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aRv +aaN +aaN +aHD +azK +aaN +aVt +aGr +aHD +aAD +aaN +aYI +aYI +aWs +azK +azE +aaN +aRr +apR +aPr +aaD +aab +aaN +aHD +azK +aaN +aVt +aGr +aRv +aFc +aaN +aHD +azK +aaN +aVt +aGr +aHD +aAD +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(151,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aFc +aaN +aaN +aaN +aaN +aRv +aAD +azK +aVt +aaN +aaN +aVt +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aGr +aaN +aRv +aKP +apR +ayO +aaD +afs +azK +aVt +aaN +aaN +aVt +aaN +aRv +aAD +azK +aVt +aaN +aaN +aVt +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aac +aac +aJx +"} +(152,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +azE +aYI +aYI +aaN +azK +aaN +aaN +aaN +aaN +aaN +aaN +aVt +aaN +aaN +aml +aaN +aKP +ana +ayO +amm +afL +aaN +aaN +aWs +azK +aaN +aaN +aaN +azE +aaN +aaN +aaN +azK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aRW +aRW +aRW +aMv +aMv +aMG +aMG +aMv +aMv +aMv +aMv +aMv +aMv +aMv +aMv +aMv +aRW +aRW +aRW +aac +aac +aJx +"} +(153,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aLh +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aFc +aaN +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aaN +azK +azK +aaN +aaN +aaN +aYI +aaN +aaN +aFc +aaN +aaN +aaN +aaN +azK +aaN +aRr +ana +aPr +aab +aab +azK +azK +aaN +aaN +aaN +aaN +aaN +aaN +azK +azK +aFc +aaN +aaN +aaN +aWs +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aRW +aRW +aRW +aMv +aNY +aEF +aEF +aPF +aPF +aNY +aEF +aPF +aPF +aEF +aNY +aMv +aRW +aRW +aRW +aac +aac +aJx +"} +(154,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +azv +aaN +aVt +aaN +aaN +aYI +aaN +azK +aaN +aaN +aYI +aaN +aHD +aYI +aaN +aHD +aGg +aWs +azK +aRr +anw +ayO +afr +aab +aaN +aaN +aaN +azK +aaN +aYI +aVt +aaN +aaN +aYI +aaN +azK +aaN +aaN +aaN +aaN +aHD +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aRW +aRW +aRW +aMv +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aMv +aRW +aRW +aRW +aac +aac +aJx +"} +(155,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aWs +aaN +aaN +aaN +aaN +aWs +aaN +aaN +aaN +aaN +aaN +aAD +aaN +aaN +aaN +aHD +aaN +aFc +aHD +aaN +aGr +aaN +aaN +aYI +aVt +aaN +aaN +aaN +anb +anx +aPr +afs +aab +aaN +aFc +aHD +aaN +aYI +aUf +aAD +aaN +aaN +aFc +aHD +aYI +aaN +aHD +aYI +aGr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aac +aac +aRW +aRW +aRW +aMv +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aMv +aRW +aRW +aRW +aac +aac +aJx +"} +(156,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +ags +ags +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aHD +aaN +aGr +aaN +aaN +aaN +aYI +aaN +aaN +aaN +aAD +aaN +aaN +aaN +aaN +aPm +azK +anc +anb +aPr +aft +aab +aGr +aaN +aaN +aaN +aaN +aaN +aHD +aaN +aGr +aaN +aaN +aaN +aaN +aYI +aYI +aaN +aAD +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +ags +aac +aac +aRW +aRW +aRW +aMG +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aMG +aRW +aRW +aRW +aac +aac +aJx +"} +(157,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aFc +aaN +aaN +aaN +aVt +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aHD +aaN +aaN +afs +aab +aTG +ana +ana +aab +afr +aaN +aaN +aaN +aYI +aaN +aWs +aaN +aVt +aaN +aaN +aFc +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +ags +aac +aac +aRW +aRW +aRW +aRW +aMG +aEF +aEF +aEF +aEF +aEF +aPG +aPG +aEF +aEF +aEF +aEF +aMG +aRW +aRW +aRW +aRW +aac +aJx +"} +(158,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aQd +ags +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aFc +aaN +aYI +aaN +aaN +aYI +aYI +aaN +aaN +aWs +aaN +aaN +aaN +aaN +aaN +aaN +aGr +aaN +aaN +aYI +aaN +aVt +aWs +aAD +afK +aab +aab +aaN +ana +aab +aab +aWs +aaN +aaN +aaN +aaN +aGr +aaN +aaN +aaN +aaN +aaN +aaN +aWs +aGr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aRU +aRW +aRW +aRW +aMv +aNZ +aEF +aEF +aEF +aEF +aPG +aPG +aEF +aEF +aEF +aPF +aMv +aRW +aRW +aRW +aRU +aac +aJx +"} +(159,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aYI +aaN +aaN +aaN +aaN +aaN +aVt +aaN +aWs +aaN +aaN +aaN +aHD +aaN +aaN +aaN +aaN +alL +aab +aGD +aab +agr +aMM +aab +aab +aaN +aVt +aaN +aaN +aFc +aaN +aaN +aYI +aaN +aVt +aaN +aaN +aaN +aaN +aaN +aHD +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aRW +aRW +aRW +aRW +aMv +aNZ +aEF +aEF +aEF +aEF +aPG +aPG +aEF +aEF +aEF +aPF +aMv +aRW +aRW +aRW +aRW +aac +aJx +"} +(160,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aaN +aGr +aaN +aaN +aaN +aaN +aaN +aHD +aaN +aaN +aaN +aaN +aCU +aaN +aab +aft +aab +aft +ana +aab +aab +aoY +aaN +aaN +aaN +aaN +aaN +aaN +aWs +aGr +aaN +aaN +aaN +aaN +aaN +aHD +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aRW +aRW +aRW +aRW +aMv +aNZ +aEF +aEF +aEF +aEF +aPG +aPG +aEF +aEF +aEF +aPF +aMv +aRW +aRW +aRW +aRW +aac +aJx +"} +(161,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ayV +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aWs +aaN +aaN +aaN +aaN +aaN +aWs +aaN +aab +afr +aab +aaN +aaN +aaN +aaN +aaN +aaN +aGr +aaN +aaN +aaN +aaN +aaN +afr +aab +afs +aab +anH +amm +afr +aaN +aYI +aaN +aaN +aaN +aaN +aaN +aVt +aaN +aaN +aaN +aYI +aYI +aaN +aaN +aGr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aRW +aRW +aRW +aRW +aMv +aNZ +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aPF +aMv +aRW +aRW +aRW +aRW +aac +aJx +"} +(162,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aaN +aaN +aaN +aaN +aGr +aaN +aaN +aaN +aaN +aYI +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +aaN +aaN +aaN +aaN +aaN +aGr +aaN +aaN +aaN +aaN +aaN +aaN +aYI +aGr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aRW +aRW +aRW +aRW +aMv +aNZ +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aPF +aMv +aRW +aRW +aRW +aRW +aac +aJx +"} +(163,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aGr +aAD +aaN +aaN +aaN +aAD +aaN +aHD +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +aab +aaN +aGr +aAD +aaN +aaN +aaN +aaN +aaN +aaN +aGr +aAD +aaN +aaN +aaN +aAD +aaN +aHD +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aRW +aRW +aRW +aRW +aMv +aNY +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aEF +aNY +aMv +aRW +aRW +aRW +aRW +aac +aJx +"} +(164,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aab +aab +aab +aab +aab +afs +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +amm +aab +aab +aab +amm +aab +afs +aab +aab +aab +aGD +aab +aab +aab +afs +aab +aab +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aRW +aRW +aRW +aRW +aMv +aMv +aMv +aNY +aEF +aEF +aEF +aEF +aEF +aNY +aMv +aMv +aMv +aRW +aRW +aRW +aRW +aac +aJx +"} +(165,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +avq +avq +avq +avq +avq +aeN +acN +aeN +avq +acN +acN +acN +acN +avq +avq +avq +avq +aeN +avq +avq +acN +avq +avq +and +any +aJm +avq +aeN +avq +acN +avq +aeN +avq +acN +acN +avq +avq +aeN +avq +avq +avq +avq +aeN +avq +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aac +aJx +"} +(166,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aaN +aaN +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +acI +acZ +aau +ada +aaF +adD +aab +aau +aab +aau +ada +aaF +adD +aab +aau +aab +ada +aaF +adD +aab +aau +aab +amN +aRr +anz +anI +anY +adD +acZ +aau +ada +aaF +adD +adD +acZ +adD +acZ +aau +ada +aaF +adD +aab +aau +acK +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aac +aJx +"} +(167,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +acJ +aab +aaF +aab +aau +aab +aeW +acZ +aab +aaF +aab +aau +aab +aeW +acZ +aab +aab +aau +aab +aeW +acZ +aab +amN +ane +anA +anI +amm +aaF +aab +aaF +aab +aau +aab +aaF +aab +aaF +aab +aaF +aab +aau +aab +aeW +acZ +acK +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aac +aJx +"} +(168,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +acK +ada +adD +acZ +aaF +aaF +aau +aab +aeW +adD +acZ +aaF +aaF +aau +aab +aeW +acZ +aaF +aaF +aau +aab +amn +amm +anf +anB +aIn +amN +aab +aUz +adD +acZ +aaF +aaF +aab +ada +aab +ada +adD +acZ +aaF +aaF +aau +aab +awg +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aRU +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRW +aRU +aac +aJx +"} +(169,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aQK +aQK +aWZ +aKQ +aKQ +aKQ +aKQ +aJK +aQK +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +aqr +aqr +aqr +alB +aht +aht +agV +aht +aqr +aqr +aqr +ajy +ajy +aqr +ask +ask +ask +ask +ajy +aqr +aqr +ajy +apN +apN +aqh +aqr +ajy +ajy +aqr +azV +ask +ask +azV +aqr +aqr +avz +aqr +azV +ask +azV +ask +ajy +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(170,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aQK +aWZ +aCs +aOy +aHk +aHk +aYQ +azU +aJK +aQK +aQK +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +afF +aii +agj +aii +aii +aii +aii +adN +aOE +ajq +aqr +akg +akw +aOE +aqv +aOE +adN +anJ +aog +aoF +apf +aqr +ahg +ahg +ahg +aqr +aoF +arn +arP +asl +asQ +asm +atT +aqr +auM +avA +avT +awD +awZ +awZ +awZ +auU +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(171,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aQK +aWZ +aCs +aOy +aTw +aTw +aTw +aTw +aYQ +azU +aJK +aQK +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +afG +aii +agC +agC +agC +aii +aij +aiN +aOE +abW +aqr +akh +akx +all +akz +akz +akz +aqv +aqr +aqr +aqr +aqr +apO +apO +apO +aqr +aqr +aqr +aqr +asm +asR +asm +atU +aqr +auN +ahL +ahL +ahL +ahL +axD +ahL +ayq +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(172,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aQK +aQK +aWZ +aCs +aOy +aTw +aTw +aTw +aTw +aTw +aTw +aYQ +azU +aJK +aQK +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +aii +aii +agD +agW +ahu +ahS +aii +aOE +aqv +abX +aqr +aOE +aky +akD +akz +ame +ame +acj +aqr +aoG +aoI +aqv +apP +ahg +ahg +aOE +aoI +aOE +aqr +asm +asS +asm +atV +aqr +auO +ahL +avU +ahL +axa +ahL +ayh +ayr +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(173,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ayV +aZS +ags +aLU +aLU +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aWZ +aKQ +aKQ +aCs +aOy +aTw +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aYQ +azU +aKQ +aJK +aQK +aQK +aQK +aaN +aaN +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +afH +agi +agE +agX +ahv +ahS +aii +aOE +agt +aqv +aqr +aki +akz +akz +akz +amf +amf +amA +aqr +aOE +aoI +aOE +avp +azS +avp +abY +aoI +aOE +aqr +asm +asT +asm +atW +aqr +auP +ahL +avV +ahL +axb +ahL +ahL +ays +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(174,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ahJ +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +ags +ags +ags +ags +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aWZ +aCs +aOy +aHk +aHk +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aHk +aYQ +aFE +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +aii +aii +agF +agY +ahw +ahS +aii +aOE +aOE +ajs +ajy +aOE +akz +alm +alC +akz +akz +anJ +aqr +aOE +api +aOE +ahg +ahg +ahg +aOE +api +aOE +aqr +asm +asU +asm +atX +aqr +auQ +ahL +ahL +awE +axc +axE +ahL +ayt +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(175,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ayV +ags +aWU +ags +ags +ags +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aWZ +aCs +aOy +aTw +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aYa +azU +aKQ +aJK +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +afu +aii +agj +agG +agZ +agG +aii +aii +aOE +aOE +aju +ajy +aOE +akB +akD +akz +amg +amP +anK +aqr +aOE +apg +aOE +ahg +ahg +ahg +aOE +api +aOE +aqr +asm +asV +asm +atY +aqr +auR +avB +avW +awF +axd +axF +ahL +ayu +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(176,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aLU +aLU +aaN +aaN +aaN +aaN +aQK +aQK +aQK +aWZ +aCs +aOy +aTw +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aHk +aYQ +aFE +aQK +aQK +aQK +aQK +aaN +aaN +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +afI +aii +aii +aii +aii +aii +aii +aiO +aje +ajv +aqr +akj +akC +akD +alD +amh +amh +akS +aqr +aOE +api +aOE +ahg +ahg +ahg +aOE +aqW +aOE +aqr +asm +asW +asm +atZ +aqr +auS +ahL +ahL +ahL +axe +ahL +ahL +ayv +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +ags +ags +ags +aac +aZS +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(177,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aLU +aaN +aaN +aaN +aQK +aQK +aWZ +aWQ +aCs +aOy +aTw +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aYa +azU +aJK +aQK +aQK +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +afJ +aOE +aOE +aOE +arp +aOE +aqv +aOE +aOE +ajw +aqr +aje +akD +akD +akz +akz +akz +aOE +aqr +aOE +api +aOE +ahg +ahg +ahg +aOE +api +arp +aqr +asm +asX +asm +asQ +ajy +auT +ahL +ahL +ahL +avU +ahL +axD +ayw +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +ags +ags +aZS +aZS +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(178,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aEJ +ags +aZS +aZS +ags +aLU +aaN +aaN +aaN +aQK +aQK +aXS +aOy +aHk +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aYQ +azU +aKQ +aJK +aQK +aQK +aQK +aQK +aaN +aQK +aaN +aaN +aaN +aaN +aQK +aaN +aaN +aaN +aaN +aaN +aQK +aaN +aaN +aQK +aaN +aQK +aaN +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aik +aOE +aqv +afZ +aqr +akj +akD +aln +alD +ami +ami +amz +aqr +aOE +apj +aOE +ahg +ahg +ahg +aOE +azT +aOE +aqr +asm +asY +asm +aua +ajy +auU +avC +avC +auU +auU +avC +avC +ayx +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aLU +aLU +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +ags +ags +aZS +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(179,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aZS +aac +ayV +ags +aLU +aaN +aaN +aQK +aQK +aQK +aIc +aRV +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aHk +aYQ +azU +aJK +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aQK +aaN +aaN +aaN +aaN +aQK +aaN +aaN +aaN +aaN +aQK +aaN +aQK +aQK +aQK +aaN +aaN +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +afv +afM +aqr +agH +aqr +agH +aqr +ail +aOE +aOE +aOE +ajy +aOE +akD +akD +alE +amj +amR +alN +aqr +aOE +aoI +aOE +ahg +ahg +ahg +aOE +aoI +aOE +aqr +asm +asT +asm +aub +ajy +auV +auV +avX +auU +aoX +awd +awd +awd +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aNv +aZS +aZS +aZS +aZS +aZS +aZS +ags +ags +ags +aac +ags +ags +ags +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(180,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aSl +ags +ags +ags +aZS +aZS +aac +aac +aac +aZS +anv +aaN +aaN +aQK +aRy +aQK +aGT +aRV +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aYQ +azU +aJK +aQK +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aQK +aaN +aaN +aaN +aaN +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +afv +afN +aqr +afN +aqr +afN +aqr +aim +aOE +aOE +aOE +ajy +akk +akE +alo +alD +akz +amS +aOE +aqr +aoH +apk +aOE +ahg +ahg +ahg +aOE +aoI +aro +aqr +asm +asZ +asm +auc +ajy +auX +auX +avY +auU +auU +axG +ayi +ayy +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aLU +aLU +aNv +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(181,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aZS +aZS +aac +aac +aac +aac +aPI +aQK +aQK +aQK +aQK +aWZ +aCs +aRV +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aYQ +azU +aKQ +aJK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aaN +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +afv +agl +agk +agl +agl +agl +aqr +ain +anJ +aOE +aOE +ajy +aOE +akD +akD +akz +ame +ame +acj +aqr +aoH +aOE +aOE +apQ +ahg +ahg +afZ +aOE +aro +aqr +asm +ata +asm +aud +ajy +auX +auX +avZ +auU +auU +aVi +ayi +ayz +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aNv +aNv +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(182,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aVY +aVY +aKQ +aJK +aWZ +aCs +aOy +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aTw +aHk +aYQ +aFE +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aWZ +aKQ +aKQ +aKQ +aJK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +afw +afO +agl +agl +agk +agl +aqr +aio +aOE +afZ +aOE +aqr +aqv +akz +akz +akz +ame +ame +anL +aqr +aoH +aqv +aOE +ahg +ahg +aqi +aOE +aOE +aro +aqr +asm +atb +asm +aue +ajy +auX +auX +avZ +auU +auU +aVi +ayi +ayi +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aLU +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(183,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aHk +aHk +aYQ +aRL +aCs +aOy +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aTw +aYa +azU +aJK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aWZ +aCs +aOy +aHk +aYQ +aFE +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +afw +afP +agl +agI +agl +agk +aqr +aip +aOE +aqv +ajx +aqr +aOE +aOE +aOE +aOE +aqv +aOE +aje +aqr +aoH +abY +aOE +ahg +ahg +ahg +aOE +aOE +aro +aqr +asm +atc +asm +asR +ajy +auY +auX +avZ +auU +auU +aVi +ayj +atw +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(184,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aTw +aTw +aHk +aHk +aTw +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aTw +aYQ +azU +aJK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +azW +aQK +aQK +aWZ +aCs +aOy +aTw +aTw +aYa +aFE +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +afw +afQ +agl +agl +agl +agl +aqr +aqr +acy +acy +ajy +aqr +aqr +acy +acy +aqr +aqr +aqr +aqr +aqr +aoI +aOE +aOE +ahg +ahg +ahg +aqv +aOE +aoI +aqr +aOE +ata +aOE +als +ajy +auV +auV +avX +auU +auU +awd +awd +awd +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aOJ +aqr +aqr +aqr +aqr +aqr +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(185,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aTw +aTw +aTw +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aYQ +azU +aKQ +aKQ +aJK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aXS +aOy +aTw +aUy +aTw +aYa +azU +aKQ +aJK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +afv +afR +agl +agJ +aha +agl +acy +ajO +ajO +ajO +ajO +ajN +ajO +ajO +ajO +ajO +acB +acB +acB +acB +ajO +ajO +ajO +ahg +ahg +ahg +aOE +aOE +arp +aqr +aqr +acy +acy +aqr +ajy +aqr +aqr +aqr +acy +acy +aqr +aqr +aqr +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aTp +aKC +aOE +aqv +aOE +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(186,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ayV +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aHk +aHk +aYQ +azU +aKQ +aKQ +aKQ +aKQ +aKQ +aKQ +aJK +aQK +aQK +aWZ +aCs +aRV +aTw +aUy +aTw +aTw +aHk +aYQ +aFE +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +aqr +aqr +agK +ahb +aqr +aqr +air +ajO +ajO +ajO +ajO +ajO +ajO +alp +ajO +amk +amk +amk +amk +ajO +ajO +ajO +ahg +aqc +ahg +aqw +aqw +aqw +aqw +aqw +aqw +aqw +aqw +arq +aqw +aqw +aqw +aqw +aqw +aqw +aqw +ayB +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aOL +aNt +aqv +aFa +agS +aag +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(187,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aTw +aHk +aHk +aHk +aHk +aHk +aHk +aYQ +azU +aKQ +aKQ +aCs +aOy +aTw +aUy +aUy +aUy +aUy +aTw +aYa +azU +aJK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +afv +afS +agl +agL +agL +agl +acy +ajO +ajO +ajO +ajO +ajO +ajO +ajO +ajO +ajO +acD +acD +acD +acD +ajO +ajO +ajO +ahg +ahg +ahg +aqx +aqw +arq +aqw +aqw +aqw +arq +aqw +aqw +aqw +aqw +aqw +aqw +aqw +arq +aqw +ayC +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aRa +aaN +aaN +aaN +aaN +aRa +aaN +aaN +aaN +aOL +aIx +aOE +abY +aSj +aOE +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aJx +"} +(188,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ayV +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aHk +aHk +aHk +aHk +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYQ +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +afw +afR +agl +agk +agl +agl +aqr +aqr +acy +aqr +aqr +aqr +acy +aqr +aqr +acy +aqr +aqr +aqr +aqr +aoI +adr +aOE +aqj +aqj +aqj +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +awG +axf +aqr +aqr +aqr +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aRa +aaN +aaN +aaN +aRa +aaN +aaN +aaN +aaN +aaN +aOJ +aay +aOE +aOE +aOE +aqv +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aJx +"} +(189,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +afv +afO +agl +agI +agl +agl +aqr +ais +aOE +ajf +aqr +ajP +aOE +akF +aqr +aOE +agS +amT +aqr +aqr +ajx +aOE +aoI +aqj +aqj +aqj +aqr +aqX +arr +aqv +aOE +adN +atz +auf +aqr +auZ +avD +awa +awH +axg +axi +ayk +ayD +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aRa +aaN +aaN +aaN +aaN +aqr +ahe +aSj +aOE +adN +aOE +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aJx +"} +(190,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aLh +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aVG +aVG +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +afw +afP +agl +agl +agk +agl +aqr +ait +aiv +ajg +aqr +ajQ +aby +akG +aqr +alF +akz +amU +aqr +aqr +aqr +aqr +aqr +aqj +aqj +aqj +aqr +aqY +agj +aii +asn +aii +aii +atz +aqr +ava +aqN +awb +aqN +aqN +axI +aqN +ayE +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aqr +aSH +aOE +aOE +aVy +aOE +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aJx +"} +(191,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aDk +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aVG +aVG +aVG +aVG +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +azU +aJK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +afv +afv +afv +agl +agl +agl +aqr +aiu +aiv +aiv +ajz +aby +aby +akH +alq +akz +amo +amV +aqr +aol +aoJ +apl +aqr +aqj +aqj +aqj +aqr +aqv +ars +arQ +arQ +arQ +ahS +arp +aqr +avb +aqN +aqN +awI +axh +aqN +ayl +ayF +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aab +aZQ +afZ +aOE +aZB +aOE +aOE +aqr +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aJx +"} +(192,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZg +aac +aac +ags +aQK +aQK +aac +aPI +aPI +aac +aac +ags +aDk +ags +aac +aac +aac +aac +aac +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYQ +aFE +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +afx +agl +agl +agl +aqr +afN +aqr +aiv +aiv +aiv +aqr +aby +aby +aby +aqr +alG +akz +akz +aqr +aon +aOE +apm +aqr +aqj +apS +aqj +aqr +aOE +art +arQ +aso +arQ +atA +aOE +aqr +avc +aqO +awc +awd +awd +axJ +aqN +ayG +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aOL +aIU +aHN +aLR +aRp +aZU +aqr +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aJx +"} +(193,1,1) = {" +aJx +aac +aac +aac +aac +aac +aED +aED +aED +aED +aDy +abe +aac +aac +aZS +ags +aQK +aQK +aQK +aQK +aPI +aQK +aQK +ags +aac +aac +aac +aac +aac +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +afy +agl +agk +agl +aqr +ahy +aqr +aiw +aiP +ajj +aqr +ajR +akl +akI +aqr +alH +aap +amW +aqr +aon +aoK +aOE +aqr +aqj +aqj +aqj +aqy +aii +ars +arQ +asp +arQ +ahS +aOE +aqr +avd +avG +awd +awd +awd +awd +aym +ayH +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aOJ +aqr +aqr +aOL +aOL +aqr +aOJ +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(194,1,1) = {" +aJx +aac +aac +aac +aac +aac +aED +aER +aJw +aMp +aEr +aED +aac +aac +aac +aZS +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aac +aac +aac +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +azU +aJK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +aqr +aqr +aqr +ahc +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aOE +agS +aOE +aqr +aqj +apS +aqj +aqy +agj +art +arQ +aso +arQ +atB +aOE +aqr +avc +avH +awd +awd +awd +awd +ayn +ayG +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(195,1,1) = {" +aJx +aac +aac +aac +aac +aac +aED +aNG +aMp +aMp +aYw +aED +aac +aac +aac +aPI +aLW +aKQ +aKQ +aKQ +aKQ +aKQ +aKQ +aKQ +aac +aLM +aLM +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aYQ +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +afT +afW +aqr +ahd +ahz +ahT +ahT +ajh +ahT +ajA +aOE +aqr +akJ +alr +alI +alO +amX +aqr +aqr +aqr +acy +aqr +aqj +aqj +aqj +aqy +aii +ars +arQ +asp +arQ +ahS +aOE +aqr +ave +avI +awd +awd +awd +awd +aym +ayI +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(196,1,1) = {" +aJx +aac +aac +aac +aac +aac +aED +aTi +aXQ +aCE +aMp +aED +aac +aac +aac +aPI +aXS +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aLM +aLM +aVG +aVG +aVG +aVG +aac +aac +aac +aac +aac +aac +aac +aVG +aVG +aVG +aVG +aVG +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +afU +afV +aqr +aOE +aOE +agl +agl +agl +agl +aOE +aOE +aqr +akK +adr +alJ +afZ +aOE +acy +aqj +aqj +aqj +aqj +apS +aqj +apS +aqr +aOE +aru +arQ +aso +arQ +atB +aOE +aqr +avc +aqN +awe +awd +awd +axK +aqO +ayG +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(197,1,1) = {" +aJx +aac +aac +aac +aac +aac +aED +aCF +aMp +aMp +aMp +aED +aac +aac +aac +aVY +aCs +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aVG +aVG +aUL +aLM +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aVG +aVG +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +acS +agm +aqr +aOE +agl +aby +agl +ahU +agl +agl +aOE +aqr +acX +als +alK +amq +amY +aqr +aoq +aqj +aqj +aqj +aqj +aqj +aqj +aqr +aje +ars +arQ +asp +arQ +ahS +aOE +aqr +avf +avJ +aqN +awJ +awL +aqN +aqO +ayJ +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(198,1,1) = {" +aJx +aac +aac +aac +aac +aac +aED +azy +aMp +aCA +aGq +aED +aac +aac +aac +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aLM +aLM +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aTw +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +acP +afV +aqr +ahe +agl +aby +agl +agl +aby +agl +ajS +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +acy +acy +aqr +aqr +aOE +art +arQ +asq +arQ +atB +aOE +aqr +avc +aqN +aqN +awK +aqN +aqN +aqN +ayG +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(199,1,1) = {" +aJx +aac +aac +aac +aac +aac +aED +aED +aED +aED +aED +aED +aac +aac +aVG +aTw +aTw +aTw +aTw +aTw +aWd +azP +azP +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aTw +aTw +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +afV +afW +aqr +ahf +agl +agl +agl +agl +aby +agl +agS +acy +aOE +akw +akw +amr +amZ +akw +akw +akw +apn +akw +aOE +aOE +aqr +aqr +agS +aii +aii +agj +agj +aii +aqv +aqr +avg +avK +awf +avK +axj +axH +axL +ayK +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(200,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aVG +aTw +aTw +aTw +aWd +azP +azP +aJU +aQK +aQK +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +afW +agn +agM +ahg +agl +agl +agl +aiQ +agl +agl +aOE +acy +aOE +aby +aby +aby +aby +aby +aby +aby +aee +aby +apT +aOE +aOE +aqr +aOE +aOE +aOE +aOE +aOE +aOE +anJ +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(201,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aVG +aVG +aVG +aLM +aTw +aWd +aJU +aQK +aQK +aQK +aQK +aac +aac +aac +aac +aac +ags +ags +ags +aDz +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aBN +aBN +aBN +aBN +aBN +aBN +aBN +aBN +aBN +aBN +aBN +aBN +aBN +aBN +aBN +aBN +aBN +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +afV +afW +aqr +ahf +agl +agl +agl +agl +aby +agl +aOE +acy +agS +aee +aby +ams +aby +aby +aby +aby +aby +aby +aby +aOE +aql +aqr +aqZ +arv +arR +asr +atd +atC +aug +aqr +avh +avi +avj +avi +avj +avi +avj +avi +avh +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(202,1,1) = {" +ayN +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aLM +aac +azP +aJU +aeY +aQK +aTm +aQK +ags +aac +aac +aac +aac +aac +aac +aPA +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +azP +azP +azP +azP +azP +azP +azP +azP +azP +azP +azP +azP +azP +azP +azP +azP +aIp +aRV +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aYa +azU +aJK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +afU +afV +aqr +aOE +agl +ahU +agl +agl +aby +agl +ajT +aqr +akL +aby +aby +aby +aby +anM +aby +aoL +aby +apC +aby +aOE +aqr +aqz +apy +apy +apy +apy +apy +apy +aqA +aqr +avi +avL +avM +avM +axk +avM +avM +ayL +avi +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(203,1,1) = {" +ayN +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aac +aac +aac +aac +aEz +aQK +aQK +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aXS +aAJ +aBN +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aYQ +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +acS +afW +aqr +aOE +agl +aby +agl +ahU +agl +agl +aOE +aqr +akM +aby +aby +amt +aee +aby +aby +aby +aby +aby +aby +aOE +aqm +aqA +apy +apy +arS +ass +ass +ass +auh +aqr +avj +avM +awp +avM +avM +avM +awp +avM +avj +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(204,1,1) = {" +ayN +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aVG +aac +aac +aac +aac +aac +aQK +ags +aDk +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aQK +aaN +aQK +aQK +aQK +aQK +aFi +azP +aIp +aAJ +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +acP +afV +aqr +aOE +aOE +agl +agl +agl +agl +aOE +aOE +aqr +akN +alt +aby +aby +aby +aby +aby +aby +aby +aby +aby +aOE +aqn +aqA +ara +apy +arT +aqr +aqr +aqr +aqr +atk +avh +avM +avM +awM +axl +avM +avM +avM +avi +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(205,1,1) = {" +ayN +aVG +aVG +aVG +aVG +aVG +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +aDk +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aSl +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aQK +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aQK +aFi +aIp +aAJ +aBN +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +afT +ago +aqr +ahh +ahA +ahT +ahT +ahT +ahT +ajB +aOE +aqr +akO +aby +aby +aby +aby +anN +aby +aby +apo +aby +apU +aOE +aqo +aqA +apy +apy +arU +aqr +ate +atD +aui +auB +avk +avM +avM +awN +axm +avM +ayp +avM +avj +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(206,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aQK +aaN +aaN +aaN +aSN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aFi +azP +aIp +aAJ +aBN +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +avq +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +akP +aby +aby +amu +aby +aby +aee +aby +aby +aby +aby +aOE +aqp +aqA +apy +apy +arV +aqr +atf +arJ +auj +atk +avh +avM +avM +awO +axn +avM +avM +avM +avi +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(207,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aQK +aFi +azP +aIp +aRV +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aYa +aTx +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +avq +aqr +afX +aOE +aOE +aOE +afX +aqr +aix +agS +aOE +aqv +aix +aqr +akQ +alu +aby +aby +aby +aby +aby +aoM +aby +aby +aby +aOE +aqq +aqB +apy +ara +arW +aqr +atg +atE +auk +atk +avi +avM +avM +avM +avM +avM +avM +avM +avj +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(208,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aqr +aqr +aHf +aHf +aHf +aqr +aOJ +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aQK +aQK +aXS +aRV +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aYa +azU +aJK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +avq +aqr +aOE +agl +agl +ahi +aOE +aBY +aiy +aiR +aji +ahf +aOE +ajy +aOE +aby +aby +aby +aby +anO +aby +aby +aby +aby +aby +aOE +aqr +aqz +apy +apy +arX +aqr +atf +arJ +aul +atk +avj +avM +awp +avM +axo +avM +axo +avM +avi +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(209,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aNF +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aqr +aJy +aCc +aXM +aSF +aWq +aHf +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aXS +aAJ +aBN +aBN +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aYQ +azU +aJK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +avq +aqr +amp +agl +agl +agl +aOE +aBY +aiy +aOE +aRC +aOE +aOE +akm +aOE +aby +aee +amv +aby +aby +aby +aoN +aby +apD +aby +aOE +aqr +aqC +apy +apy +arY +aqr +ath +arJ +aum +atk +avi +avM +avM +awP +avM +avM +avM +avM +avj +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(210,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aqr +aOE +aIh +aRP +aVy +aOE +aws +aab +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aFi +azP +azP +aIp +aRV +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aYQ +azU +aJK +aQK +aQK +aaN +aaN +aaN +aaN +avq +aqr +aOE +agl +agl +agl +aOE +aBY +aiy +aiR +aOE +ahf +aOE +ajy +aOE +aby +aby +aby +aby +aby +aby +aby +aee +aby +aby +aOE +acy +aqA +apy +apy +arZ +aqr +ati +arJ +aum +atk +avj +avM +avM +avM +axo +awp +axo +avM +avi +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(211,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aqr +aRX +abJ +abJ +abJ +apH +aqr +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aQK +aQK +aXS +aRV +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aYQ +aFE +aQK +aQK +aaN +aaN +aaN +aaN +avq +aqr +afX +aOE +aOE +aOE +afX +aqr +aix +aOE +aOE +abY +aix +aqr +akR +akY +alM +amw +akY +akY +alM +akY +app +akY +aOE +aOE +acy +aqA +aqA +aqA +aqA +ast +atj +atF +aun +atk +avi +avN +avM +avM +avM +avM +avM +ayM +avj +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(212,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aNF +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aNF +ags +ags +ags +aac +aac +aac +aac +aac +aac +aqr +acu +abJ +aBT +abJ +aBK +aHf +aaN +aaN +aaN +aaN +aaN +aaN +aSN +aaN +aaN +aaN +aaN +aQK +aQK +aQK +aXS +aAJ +aBN +aBN +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +avq +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aqr +atk +atk +atk +atk +avh +avi +avj +avi +avj +avi +avj +avi +avh +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(213,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aqr +aOE +abJ +abJ +abJ +aWq +aHf +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aQK +azP +azP +aIp +aRV +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +avq +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(214,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aqr +ahe +aOE +aSb +aOE +aVh +aqr +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aDB +aaN +aaN +aQK +aQK +aQK +aQK +aXS +aRV +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(215,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aqr +aay +aJM +aOE +aTu +agd +aqr +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aQK +aQK +aQK +aQK +aXS +aRV +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(216,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aNF +aZS +ags +aZS +ags +aac +aac +aqr +aqr +aqr +aqr +aqr +aqr +aqr +aac +aaN +aaN +aaN +aaN +aaN +aac +aac +aaN +aaN +aaN +aac +aac +aac +aQK +aQK +aQK +aXS +aRV +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(217,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aZS +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aQK +aXS +aRV +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(218,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ayV +ayV +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aQK +aXS +aRV +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aPT +aPT +aPT +aFw +aFw +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aLU +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(219,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +ags +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ayV +aZS +aZS +aac +aac +aac +aac +aac +aac +aaN +aaN +aLU +aaN +aaN +aaN +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aYa +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aPT +aYJ +aDZ +aGy +aFw +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aNv +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(220,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +ags +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ayV +ayV +aZS +aZS +ayV +aac +aac +aac +aac +ags +ags +ags +ags +ags +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aTw +aMh +aFE +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aPT +aVj +aLx +aAp +aFw +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aNv +aNv +aLU +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(221,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ayV +ayV +ayV +aZS +ayV +aZS +aac +aZS +ags +aZS +ags +ags +ags +ags +ayV +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aYa +aWd +aJU +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aFw +aLV +aUt +aWY +aAb +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ayV +aLU +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aJx +"} +(222,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +ayV +ayV +ags +ayV +ags +ags +ags +ags +ags +aZS +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aXw +aFw +aFw +aAb +aFw +aAb +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aZS +aNv +aNv +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aZS +aac +aac +aac +aac +aac +aJx +"} +(223,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ayV +ags +ags +aZS +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aTw +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aZk +aAb +aTN +aPO +aOD +aFw +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aZS +aZS +aLU +aLU +aLU +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aJx +"} +(224,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +ags +ayV +ags +ags +ayV +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aFE +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aPT +aKi +aOC +aKi +aEF +aIv +aAb +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +ayV +aZS +aZS +aac +aLU +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aJx +"} +(225,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aZS +ags +ags +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aMh +aFE +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aAb +aDD +aKi +aEF +aSt +aFw +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aJx +"} +(226,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ayV +aZS +ayV +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aMh +aWd +aJU +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aFw +aGz +aEF +aFw +aEF +aFw +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aJx +"} +(227,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aZS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aMB +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aNS +aZS +ayV +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aTw +aUy +aUy +aUy +aUy +aUy +aUy +aTw +aYa +aWd +aJU +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aXP +ags +ags +ags +aYO +aJr +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aJx +"} +(228,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +ags +aRE +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aZS +ags +ags +aac +aac +aac +aac +aac +ags +aMB +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aUy +aUy +aUy +aUy +aUy +aTw +aTw +aYa +aFE +aaa +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aNl +ags +ags +aXJ +ags +aac +aac +aac +aac +aac +aac +aac +aHv +ags +ags +ags +aSR +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aJx +"} +(229,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +ags +aSW +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +ags +ags +aMB +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aTw +aYa +aFE +aQK +aQK +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aNF +aYO +ags +ags +ags +ags +aac +aac +aac +aac +aac +aRc +ags +ags +aLF +aCN +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aJx +"} +(230,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aNF +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aDz +ags +ags +aMB +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aTw +aTw +aTw +aTw +aYa +aFE +aQK +aQK +aaN +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +ags +ags +aac +aac +aac +aac +ags +ags +ags +aDh +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aJx +"} +(231,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aWf +aYa +aWt +aPI +aQK +aQK +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aLF +aDz +ags +ags +aSl +ags +aSR +aLF +aVm +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aJx +"} +(232,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aDz +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aPI +aIV +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aAh +ags +ags +ags +aUE +ags +aBW +aDz +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aFw +aFw +aPT +aFw +aFw +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aJx +"} +(233,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aEb +aIH +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aFw +aPT +aPT +aQV +aZA +aKj +aGx +aFw +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(234,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aYH +ags +ags +ags +ags +aYU +ags +ags +aMu +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aPT +aOj +aIq +aPT +aGe +aZA +aZA +aZA +aPT +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(235,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +ags +ags +ags +ags +ags +ags +ags +ags +aZS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aDh +ags +aLF +ags +aPY +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aMb +aIq +aKx +aZA +aZA +aZI +aQe +aPT +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aJx +"} +(236,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +ags +aZS +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aZS +aZS +aZS +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aFR +aTM +aFw +aZA +aZA +aQe +aQe +aFw +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(237,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aNF +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aNF +ags +ags +ags +ags +ags +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aDz +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aNF +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ayV +aZS +aZS +aYG +ayV +aac +aac +aac +aac +aac +aaN +aaN +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aZz +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aPT +aLr +aTe +aFw +azh +aZA +aNI +aWj +aFw +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(238,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +ags +ags +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aZS +aZS +aNS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aFw +aFw +aPT +aFw +aFw +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZz +ags +ags +ags +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aFw +aFw +aFw +aFw +aGk +aFw +aFw +aFw +aAb +aPO +aFw +aAb +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(239,1,1) = {" +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +ayV +aNS +aNS +ayV +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aFR +aIq +aIq +aOj +aPT +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +ags +aac +aac +aac +aac +aac +aFw +aQI +aZA +aZC +aZA +aFw +aPO +aSK +aAb +aYz +aEF +aAb +aac +aac +aac +aac +aac +aac +aac +aac +aNF +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(240,1,1) = {" +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aDz +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFb +aZS +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aZS +aZS +ayV +ayV +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aPT +aMb +aIq +aPJ +aIq +aPT +aPT +aPT +aPT +aFw +aFw +aPT +aFw +aFw +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +ags +ags +ags +aZS +aZS +aZS +aZS +ags +ags +ags +aac +aac +aac +aPT +aZA +aME +aME +aZA +aFw +aID +aRS +aUr +aEF +aAb +aFw +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(241,1,1) = {" +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aZS +aZS +aZS +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +ayV +aZS +aZS +aZS +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aWO +aTe +aIq +aIq +aFw +aPT +aQI +aZA +aMl +aSP +aZA +aZA +aFw +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +ags +ags +ags +aac +aac +aac +aZS +ags +ags +ags +ags +aac +aac +aPT +aOb +aME +aME +aRB +aTX +aTX +aTX +aGL +aGz +aTX +aEF +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aJx +"} +(242,1,1) = {" +azQ +azQ +azQ +azQ +azQ +azQ +azQ +azQ +azQ +azQ +azQ +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +aZS +ayV +aZS +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aFw +aFw +aKx +aFw +aFw +aFw +aQI +aME +aYr +aME +aRe +aZA +aLl +aEF +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +ags +ags +ags +ags +aac +aac +aac +aZS +ags +ags +ags +ags +aac +aac +aFw +aJS +aZA +aQS +aMS +aFw +aAb +aAb +aIP +aMX +aAb +aFw +aac +aac +aac +aac +bLA +bLA +bLA +bLA +bLA +bLA +bLA +bLA +bLA +bLA +bLA +aac +aac +aJx +"} +(243,1,1) = {" +azQ +ssq +ssq +egY +egY +hFm +iNN +egY +ssq +ssq +azQ +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aNF +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aaN +aaN +aaN +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aVf +aZA +aGx +aIT +aFw +aZA +aME +aYp +aME +aME +aZA +aRz +aEF +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aLl +aGP +aFw +aFw +aFw +aFw +aFw +aFw +aAb +aFw +aFw +aFw +aac +aac +aac +aac +bLA +qJf +qJf +hPo +hPo +ubo +psG +hPo +qJf +qJf +bLA +aac +aac +aJx +"} +(244,1,1) = {" +azQ +hvj +nxt +lxA +egY +pYH +dqu +lJN +oPH +vZx +azQ +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aNF +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aaN +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aPT +aQV +aZA +aZA +aZA +aGk +aZA +aME +aME +aME +aME +aQX +aFw +aZk +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aNF +ags +ags +ags +ags +aMn +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +bLA +nOO +tTs +ykK +hPo +iTX +pOM +rTJ +sCi +iPO +bLA +aac +aac +aJx +"} +(245,1,1) = {" +azQ +gRm +hbO +dgR +uLJ +bjJ +ssq +eGa +vYv +uaU +azQ +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aGe +aZA +aAG +aBz +aFw +aJF +aPj +aYf +aUD +aMS +aVv +aFw +aLt +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +bLA +car +yhC +myC +iuT +uMt +qJf +unw +sJF +jox +bLA +aac +aac +aJx +"} +(246,1,1) = {" +azQ +rSf +sJq +sJq +rjg +nUS +ssq +ssq +ssq +mNu +azQ +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aPT +aYs +aZA +aBz +aBz +aFw +aFw +aPT +aFw +aPT +aFw +aFw +aFw +aac +aIl +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aSl +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +bLA +gUn +rxi +rxi +qyu +giz +qJf +qJf +qJf +vUD +bLA +aac +aac +aJx +"} +(247,1,1) = {" +azQ +xDg +cRF +qWJ +cvj +ssq +ssq +rwN +jru +pDy +azQ +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aZS +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aPT +aKh +aFT +aBz +aPb +aFw +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aZS +aZS +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +bLA +xzS +mpZ +hWE +gra +qJf +qJf +fMI +lJV +mvm +bLA +aac +aac +aJx +"} +(248,1,1) = {" +azQ +iwi +cvE +egY +lCx +ssq +egY +egY +quU +kDK +azQ +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +ags +ags +ags +ags +ags +ags +aZS +aZS +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aFw +aFw +aPT +aPT +aFw +aFw +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +ags +aZS +aZS +aZS +aac +ags +ags +ags +ags +ags +ags +aZS +aZS +ags +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +bLA +vQI +wAF +hPo +oBM +qJf +hPo +hPo +wCg +jUY +bLA +aac +aac +aJx +"} +(249,1,1) = {" +azQ +ssq +ssq +egY +iNH +ihT +pur +egY +ssq +ssq +azQ +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +ags +ags +ags +aZS +aZS +aac +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +aac +aac +aac +ags +ags +ags +aac +ags +ags +aZS +aZS +aZS +aac +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +ags +ags +ags +aac +aac +aac +aNF +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +bLA +qJf +qJf +hPo +uhq +iWA +qsw +hPo +qJf +qJf +bLA +aac +aac +aJx +"} +(250,1,1) = {" +azQ +jEF +xEk +xEk +ihd +cjF +qqG +xEk +xEk +dbo +azQ +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +aZS +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +aac +aac +aac +aNF +ags +ags +ags +ags +ags +ags +ags +ags +ags +ags +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +pxt +mDp +vFK +vFK +kRw +dBJ +kWj +vFK +vFK +lRv +pxt +aac +aac +aJx +"} +(251,1,1) = {" +azQ +mJd +jNZ +gIM +vgd +ina +vdv +wzn +qbF +ouD +azQ +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +aac +ags +ags +ags +ags +aZS +aZS +ags +ags +ags +ags +ags +ags +aZS +aZS +aZS +ags +ags +ags +ags +ags +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +pxt +lES +qYa +dcr +vft +dyx +wYP +eYC +ukf +ePO +pxt +aac +aac +aJx +"} +(252,1,1) = {" +azQ +eVF +kte +aZA +aZA +voq +aZA +aZA +kte +bas +azQ +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +ags +ags +ags +ags +aac +ags +ags +aac +aac +aac +ags +ags +ags +aZS +aZS +aZS +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +pxt +liD +eAQ +itL +dgN +wxX +fSV +wHZ +oTm +idT +pxt +aac +aac +aJx +"} +(253,1,1) = {" +azQ +yjc +aZA +iuW +aZA +aZA +wcR +aZA +qUm +qtw +azQ +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +pxt +iHS +wHZ +dsM +hzN +vMZ +pIk +hqz +oLt +gkE +pxt +aac +aac +aJx +"} +(254,1,1) = {" +azQ +bXE +xYl +xAi +aZA +qTn +fRV +qhF +liZ +slE +azQ +aJx +aJx +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +pxt +pxt +qQZ +upB +sZY +kBF +sOw +tHV +uEU +fXv +pxt +aac +aac +aJx +"} +(255,1,1) = {" +azQ +azQ +azQ +azQ +azQ +azQ +azQ +azQ +azQ +azQ +azQ +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +aJx +paH +pxt +pxt +pxt +pxt +pxt +pxt +xYn +ooP +pxt +pxt +aJx +aJx +aJx +"} diff --git a/_maps/map_files/SpookyStation/halloweenPersiWork.dm b/_maps/map_files/SpookyStation/halloweenPersiWork.dm new file mode 100644 index 0000000000..fe49da57b6 --- /dev/null +++ b/_maps/map_files/SpookyStation/halloweenPersiWork.dm @@ -0,0 +1,354 @@ +//Halloween Fluff Papers! + +/obj/item/paper/fluff/balls/spookyasylum/memo/cookmemo + name = "Memo: Cooks" + info = "If you're reading this, thank you for volunteering your culinary services! Not only are you helping to keep costs down by rendering bluespace catering unnecessary, but you're also helping to give this event an 'organic' touch!
This isn't your typical day on the job, so be sure to focus on quality, not quantity. People are expecting better food than normal, and we've given you higher-quality cuts than usual to work with. Ideally you'll have botany to help with produce - if not, we may be able to deliver you some.
Remember to account for crew dietary concerns and provide those with less flexible digestive systems with more than one option if possible. Lastly, be sure to avoid foods that are particularly dangerous, we aren't looking for meals to \"die for\"
-Generated by Organic Resources Department Bot #7004" + +/obj/item/paper/fluff/balls/spookyasylum/memo/botanymemo + name = "Memo: Botanists" + info = "If you're reading this, thank you for lending us your \"green thumbs\"! Provided a cook is on duty, you'll save us the trouble of bluespace shipping produce, as well as giving us the privilege of saying it was \"locally sourced\"! If there isn't a chef...we may be able to put what you grow to good use yet.
Remember, your primary goal here is to produce produce. Not cannabis, not tomatoes that mutate people, we want things people can safely eat. Do what you can for the cook if there is one - otherwise, aspire for variety.
-Generated by Organic Resources Department Bot #7004" + +/obj/item/paper/fluff/balls/spookyasylum/memo/janniememo + name = "Memo: Janitors" + info = "If you're reading this, thanks for volunteering your janitorial services! You're greatly appreciated today, as this event will likely remind you why Citadel custodians command a higher salary than their counterparts in other sectors.
On the bright side, you shouldn't expect much in the way of danger.
-Generated by Organic Resources Department Bot #7004" + +/obj/item/paper/fluff/balls/spookyasylum/memo/securitymemo + name = "Security Debrief" + info = "Greetings Security Officers,
Whether you've chosen or been chosen to help oversee this event, we appreciate your service today. Although this may come as a disappointment to some of you, we can absolutely confirm a lack of credible threats for once. As such, your primary mission is to keep the peace.
Central Command understands this may be difficult for those of you from military backgrounds - fortunately, we intend to be far more accessible for the sake of this event. Feel free to contact us if you have any uncertainties how to handle a situation, as cost is not the concern it normally is. However, you're expected to follow any orders we give to the best of your ability.
Some other things you should be aware of:
- You may see civilians in security apparel - this is to be expected as \"shitsec\" costumes are trending on the NTnet. For this reason we have issued you special uniforms. If you see a partygoer in THOSE, THEN you may have reason for concern.
- Items that may normally be cause for alarm can generally be assumed to be toys and/or replicas, potentially as part of a costume. You'll be informed whether an item is to be of concern, as Central Command will be handling much of the surveillance work.
- Speaking of surveillance, the chapel and larger building to the east are not equipped with cameras. The chapel has been fully investigated by an Inquistion, but due to \[REDACTED] they were unable to do the same for the east compound. You are not responsible for what goes on in these areas and partygoers have been warned to enter at their own risk.
-Central Command" + +/obj/item/paper/fluff/balls/spookyasylum/diary/diary01 + name = "7/31/2559" + info = "People who say they can't afford any more than a nanoapartment really need to broaden their horizons. You'd be amazed by what you can find if you're willing to put up with a longer commute! I mean look at me, I got a place with square footage that'd put First Victorians to shame!
Part of why this place was so cheap was because some \"terrible things\" happened here in the past, apparently. Still, what's in the past is in the past, is it not?" + +/obj/item/paper/fluff/balls/spookyasylum/diary/diary02 + name = "8/2/2559" + info = "Nice as this place is, it's kind of lonely. It also might be a bit tough to maintain all by myself, so what if I made it a hotel? Something like this'd surely stand out, especially when most of the hotels around here are Twin Nexuses.
It's not that they're not nice places - it's just that when you've been to one, you've been to them all. A hotel here? It'd be one of a kind!" + +/obj/item/paper/fluff/balls/spookyasylum/diary/diary03 + name = "9/13/2559" + info = "
All hell has broken loose.

In the early evening, hundreds, maybe thousands of ghosts burst out of the chapel and old medical wing. They rushed through the halls, breaking any lights they passed. Then it happened.
We had quite a few doctors present that night, and suddenly they all went insane. One barged into the kitchen and dove headfirst into the gibber. The rest charged into medbay, each seeming to choose a unique method of suicide. Lethal injections, the electric chair, self-lobotomy - each seemed to top the last in absurdity. Then the ghosts all converged back in the chapel, appearing to vanish as quickly as they arrived.
All my remaining guests and staff have fled. Everyone seemed to have somewhere they could go...except for me. I can only pray these spirits don't take me in my sleep..." + +/obj/item/paper/fluff/balls/spookyasylum/diary/diary04 + name = "9/16/2559" + info = "Word travels a lot faster than I thought, I haven't seen a customer in days...
The good news is that whatever happened a few days hasn't repeated itself. It's just me here - any staff I had resigned immediately after what went down on the 13th. I'm sure I could handle a few guests but am I gonna see one anytime soon?" + +/obj/item/paper/fluff/balls/spookyasylum/diary/diary05 + name = "10/7/2559" + info = "Finally, I'm free of this nightmare.
Some folks showed up for the first time in weeks, said they were a part of \"NanoTransen\" or something. They seemed shocked I haven't heard of them, but all I care about is the fact they were willing to buy this place. I figured I'd at least get what I invested at this place, but for a \"megacorporation\" they sure seemed like a bunch of tightwads. Still, I took their offer.
It's their problem now." + +/obj/item/paper/fluff/balls/spookyasylum/cell03 + name = "Cell 3 Patient Information" + info = "Name: J. Crane
Age: 46 Gender: M Height: 183cm Weight: 81kg
Notes: Patient exhibits violent tendencies and is not to be released from restraints under any circumstances. To reduce risk of violent outbreaks, birds; which patient has a strong phobia towards; are no longer allowed in proximity of cells, this includes the chief of staff's pet parrot." + +/obj/item/paper/fluff/balls/spookyasylum/cell04 + name = "Cell 4 Patient Information" + info = "Name: Fidel S.
Age: 20 Gender: M Height: 170cm Weight: 68kg
Notes: Patient appears to be under the delusion that he is a dog, suffers from incontinence, and bites staff. Patient to be kept restrained in cell after attacking orderly Robinson, do not remove patient's muzzle outside designated meal periods." + +/obj/item/paper/fluff/balls/spookyasylum/traffickingvictim + name = "Cell 1 Patient Information" + info = "Name: S. Albright
Age: 26 Gender: F Height: 174cm Weight: 63kg
Notes: \[The notes are crossed out and unreadable, but there is writing on the back of the paper] Buyer found in Sol system, wealthy Martian man looking for a cheap bride, doesn't mind poor condition of the merchandise. Will be packaging with the next supply ship for transport." + +/obj/item/paper/fluff/balls/spookyasylum/healstaffnote + name = "Shipping Manifest 'Healing Staves'" + info = "Contained in this chest are several magical healing staves created by NT sanctioned warlocks, please use them in the event an employee is injured during the festivities. We hope you have a safe and enjoyable celebration, remember you are expected to return to work promptly at its conclusion.
We apologize in the unlikely event the contents of the crate are scattered around the asylum by its teleportation." + +//Dorm Buttons + +/obj/machinery/button/door/dorms/dorm01 + name = "dorm 1 button" + id = "D100" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm02 + name = "dorm 2 button" + id = "D101" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm03 + name = "dorm 3 button" + id = "D102" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm04 + name = "dorm 4 button" + id = "D103" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm05 + name = "dorm 5 button" + id = "D104" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm06 + name = "dorm 6 button" + id = "D105" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm07 + name = "dorm 7 button" + id = "D106" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm08 + name = "dorm 8 button" + id = "D107" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm09 + name = "dorm 9 button" + id = "D108" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm10 + name = "dorm 10 button" + id = "D109" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm11 + name = "dorm 11 button" + id = "D110" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm12 + name = "dorm 12 button" + id = "D111" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm13 + name = "dorm 13 button" + id = "D112" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm14 + name = "dorm 14 button" + id = "D113" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm15 + name = "dorm 15 button" + id = "D114" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm16 + name = "dorm 16 button" + id = "D115" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm17 + name = "dorm 17 button" + id = "D116" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm18 + name = "dorm 18 button" + id = "D117" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm19 + name = "dorm 19 button" + id = "D118" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm20 + name = "dorm 20 button" + id = "D119" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/patient1 + name = "door bolt" + id = "D120" + normaldoorcontrol = 1 + pixel_x = 24 + pixel_y = -8 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/patient2 + name = "door bolt" + id = "D121" + normaldoorcontrol = 1 + pixel_x = 24 + pixel_y = -8 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/luxury1 + name = "Privacy Shutter Control" + id = "L00" + pixel_x = -8 + pixel_y = -24 + +/obj/machinery/button/door/dorms/luxury2 + name = "Privacy Shutter Control" + id = "L01" + pixel_x = 8 + pixel_y = -24 + +/obj/machinery/button/door/dorms/luxury3 + name = "Privacy Shutter Control" + id = "L02" + pixel_x = 8 + pixel_y = 24 + +/obj/machinery/button/door/dorms/luxury4 + name = "Privacy Shutter Control" + id = "L03" + pixel_x = -24 + pixel_y = 8 + +//Dorm Doors + +/obj/machinery/door/airlock/wood/dorms/dorm01 + name = "Room 1" + id_tag = "D100" + +/obj/machinery/door/airlock/wood/dorms/dorm02 + name = "Room 2" + id_tag = "D101" + +/obj/machinery/door/airlock/wood/dorms/dorm03 + name = "Room 3" + id_tag = "D102" + +/obj/machinery/door/airlock/wood/dorms/dorm04 + name = "Room 4" + id_tag = "D103" + +/obj/machinery/door/airlock/wood/dorms/dorm05 + name = "Room 5" + id_tag = "D104" + +/obj/machinery/door/airlock/wood/dorms/dorm06 + name = "Room 6" + id_tag = "D105" + +/obj/machinery/door/airlock/wood/dorms/dorm07 + name = "Room 7" + id_tag = "D106" + +/obj/machinery/door/airlock/wood/dorms/dorm08 + name = "Room 8" + id_tag = "D107" + +/obj/machinery/door/airlock/wood/dorms/dorm09 + name = "Room 9" + id_tag = "D108" + +/obj/machinery/door/airlock/wood/dorms/dorm10 + name = "Room 10" + id_tag = "D109" + +/obj/machinery/door/airlock/wood/dorms/dorm11 + name = "Room 11" + id_tag = "D110" + +/obj/machinery/door/airlock/wood/dorms/dorm12 + name = "Room 12" + id_tag = "D111" + +/obj/machinery/door/airlock/wood/dorms/dorm13 + name = "Room 13" + id_tag = "D112" + +/obj/machinery/door/airlock/wood/dorms/dorm14 + name = "Room 14" + id_tag = "D113" + +/obj/machinery/door/airlock/wood/dorms/dorm15 + name = "Room 15" + id_tag = "D114" + +/obj/machinery/door/airlock/wood/dorms/dorm16 + name = "Room 16" + id_tag = "D115" + +/obj/machinery/door/airlock/wood/dorms/dorm17 + name = "Room 17" + id_tag = "D116" + +/obj/machinery/door/airlock/wood/dorms/dorm18 + name = "Room 18" + id_tag = "D117" + +/obj/machinery/door/airlock/wood/dorms/dorm19 + name = "Room 19" + id_tag = "D118" + +/obj/machinery/door/airlock/wood/dorms/dorm20 + name = "Room 20" + id_tag = "D119" + +/obj/machinery/door/airlock/wood/dorms/patient1 + name = "Recovery Room 1" + id_tag = "D120" + +/obj/machinery/door/airlock/wood/dorms/patient2 + name = "Recovery Room 2" + id_tag = "D121" + +//Luxury Dorm Shutters + +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury01 + name = "Luxury Dorm 1" + id = "L00" + +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury02 + name = "Luxury Dorm 2" + id = "L01" + +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03 + name = "Luxury Dorm 3" + id = "L02" + +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury04 + name = "Luxury Dorm 4" + id = "L03" + +//This is just so I don't have to mass varedit! + +/obj/structure/falsewall/halloweenBall/wood + name = "wooden wall" + desc = "A wall with wooden plating. Stiff." + icon = 'icons/turf/walls/wood_wall.dmi' + icon_state = "wood" + mineral = /obj/item/stack/sheet/mineral/wood + walltype = /turf/closed/wall/mineral/wood + canSmoothWith = list(/obj/structure/falsewall/wood, /turf/closed/wall/mineral/wood, /turf/closed/indestructible/wood) diff --git a/_maps/map_files/SpookyStation/job_changes.dm b/_maps/map_files/SpookyStation/job_changes.dm new file mode 100644 index 0000000000..c32690a477 --- /dev/null +++ b/_maps/map_files/SpookyStation/job_changes.dm @@ -0,0 +1,12 @@ +#define JOB_MODIFICATION_MAP_NAME "SpookyStation" + +/turf + baseturfs = /turf/open/floor/spooktime/spooktimegrass + +MAP_REMOVE_JOB(geneticist) +MAP_REMOVE_JOB(virologist) +MAP_REMOVE_JOB(lawyer) +MAP_REMOVE_JOB(scientist) +MAP_REMOVE_JOB(lawyer) +MAP_REMOVE_JOB(shaft_miner) +MAP_REMOVE_JOB(AI) diff --git a/_maps/map_files/debug/runtimestation.dmm b/_maps/map_files/debug/runtimestation.dmm index 3dff7a8f44..ccbeabc4b7 100644 --- a/_maps/map_files/debug/runtimestation.dmm +++ b/_maps/map_files/debug/runtimestation.dmm @@ -41,22 +41,25 @@ /area/engineering/gravity_generator) "am" = ( /obj/machinery/atmospherics/components/unary/tank/air, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engineering/atmos) "an" = ( -/obj/structure/lattice/catwalk, /obj/structure/cable{ icon_state = "1-4" }, -/turf/open/space, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/power/rtg/advanced, +/turf/open/floor/plating/airless, /area/space/nearstation) "ao" = ( /obj/structure/lattice/catwalk, /obj/structure/cable{ - icon_state = "1-2" + icon_state = "2-8" }, /obj/structure/cable{ - icon_state = "2-8" + icon_state = "1-8" }, /turf/open/space, /area/space/nearstation) @@ -100,32 +103,24 @@ /obj/machinery/airalarm/unlocked{ pixel_y = 23 }, -/obj/structure/cable{ - icon_state = "0-4" - }, /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/structure/cable{ + icon_state = "0-2" + }, /turf/open/floor/plasteel, /area/engineering/gravity_generator) "at" = ( -/obj/machinery/power/apc{ - dir = 1; - name = "Gravity Generator APC"; - pixel_y = 23 - }, -/obj/structure/cable{ - icon_state = "0-8" - }, /obj/structure/cable{ icon_state = "0-2" }, /obj/effect/turf_decal/stripes/line{ dir = 5 }, -/obj/structure/cable, -/obj/machinery/power/port_gen/pacman/super, -/obj/item/stack/sheet/mineral/uranium, +/obj/machinery/power/terminal{ + dir = 8 + }, /turf/open/floor/plasteel, /area/engineering/gravity_generator) "au" = ( @@ -159,7 +154,6 @@ /turf/open/floor/plating, /area/engineering/atmos) "aA" = ( -/obj/structure/lattice/catwalk, /obj/structure/cable{ icon_state = "4-8" }, @@ -169,7 +163,11 @@ /obj/structure/cable{ icon_state = "2-4" }, -/turf/open/space, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/power/rtg/advanced, +/turf/open/floor/plating/airless, /area/space/nearstation) "aB" = ( /obj/structure/lattice/catwalk, @@ -192,15 +190,15 @@ /turf/open/floor/plasteel, /area/security/brig) "aE" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/structure/cable{ icon_state = "2-8" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, +/obj/structure/cable{ + icon_state = "1-8" + }, /turf/open/floor/plasteel, /area/engineering/main) "aF" = ( @@ -210,9 +208,6 @@ /turf/open/floor/plasteel, /area/engineering/main) "aG" = ( -/obj/machinery/power/terminal{ - dir = 1 - }, /obj/machinery/light{ dir = 8 }, @@ -220,15 +215,21 @@ dir = 8 }, /obj/structure/closet/radiation, +/obj/structure/cable{ + icon_state = "1-4" + }, /turf/open/floor/plasteel, /area/engineering/gravity_generator) "aH" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, /turf/open/floor/plasteel, /area/engineering/gravity_generator) "aI" = ( @@ -273,11 +274,14 @@ /turf/open/floor/plating, /area/engineering/atmos) "aQ" = ( -/obj/structure/lattice/catwalk, /obj/structure/cable{ icon_state = "2-4" }, -/turf/open/space, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/power/rtg/advanced, +/turf/open/floor/plating/airless, /area/space/nearstation) "aR" = ( /obj/structure/lattice/catwalk, @@ -285,7 +289,7 @@ icon_state = "1-8" }, /obj/structure/cable{ - icon_state = "1-2" + icon_state = "2-8" }, /turf/open/space, /area/space/nearstation) @@ -299,15 +303,15 @@ /turf/open/floor/plasteel, /area/engineering/main) "aT" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/structure/cable{ icon_state = "2-4" }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, +/obj/structure/cable{ + icon_state = "1-4" + }, /turf/open/floor/plasteel, /area/engineering/main) "aU" = ( @@ -326,15 +330,18 @@ /turf/open/floor/plasteel, /area/engineering/gravity_generator) "aV" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, /obj/effect/turf_decal/stripes/line{ dir = 8 }, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, /turf/open/floor/plasteel, /area/engineering/gravity_generator) "aW" = ( @@ -405,6 +412,8 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/machinery/power/apc/auto_name/west, +/obj/structure/cable, /turf/open/floor/plasteel, /area/engineering/gravity_generator) "bh" = ( @@ -427,6 +436,12 @@ }, /turf/open/floor/plasteel/dark, /area/engineering/gravity_generator) +"bj" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) "bk" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ @@ -486,10 +501,10 @@ "bt" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ - icon_state = "1-2" + icon_state = "2-4" }, /obj/structure/cable{ - icon_state = "2-4" + icon_state = "1-4" }, /turf/open/floor/plasteel, /area/science) @@ -636,6 +651,13 @@ "bR" = ( /obj/machinery/camera/autoname, /obj/machinery/chem_heater, +/obj/machinery/power/apc{ + dir = 1; + pixel_y = 23 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, /turf/open/floor/plasteel/dark, /area/medical/chemistry) "bS" = ( @@ -735,9 +757,6 @@ /turf/open/floor/plasteel, /area/command/bridge) "ce" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, /obj/structure/cable{ icon_state = "1-4" }, @@ -747,6 +766,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/structure/cable{ + icon_state = "1-8" + }, /turf/open/floor/plasteel, /area/command/bridge) "cf" = ( @@ -782,28 +804,21 @@ /turf/open/floor/plasteel, /area/security/brig) "cj" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/open/floor/plasteel, -/area/medical/chemistry) +/obj/structure/table, +/obj/item/integrated_circuit_printer/debug, +/turf/open/floor/plasteel/dark, +/area/science/circuit) "ck" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/medical/medbay) "cl" = ( -/obj/structure/cable{ - icon_state = "1-8" - }, /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/white/corner{ dir = 1 }, @@ -859,7 +874,7 @@ "cs" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ - icon_state = "1-2" + icon_state = "1-4" }, /turf/open/floor/plasteel, /area/medical/chemistry) @@ -897,7 +912,7 @@ /area/medical/medbay) "cz" = ( /obj/structure/fans/tiny, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/medical/medbay) "cA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -966,6 +981,11 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/structure/table, +/obj/item/gun/magic/wand/resurrection/debug, +/obj/item/gun/magic/staff/healing, +/obj/item/gun/magic/wand/death/debug, +/obj/item/debug/human_spawner, /turf/open/floor/plasteel/white/corner{ dir = 1 }, @@ -1009,11 +1029,11 @@ /turf/closed/wall/r_wall, /area/construction) "cO" = ( -/obj/structure/cable{ - icon_state = "1-2" +/obj/effect/turf_decal/stripes/line{ + dir = 1 }, -/turf/closed/wall/r_wall, -/area/construction) +/turf/open/floor/plasteel, +/area/cargo/miningoffice) "cP" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall/r_wall, @@ -1032,18 +1052,12 @@ "cT" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, /turf/open/floor/plasteel, /area/medical/chemistry) "cU" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/hallway/primary/central) +/obj/machinery/nanite_programmer, +/turf/open/floor/plasteel/dark, +/area/science/circuit) "cV" = ( /obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel, @@ -1052,12 +1066,14 @@ /obj/machinery/airalarm/unlocked{ pixel_y = 23 }, -/obj/structure/cable, /obj/machinery/power/apc{ dir = 8; pixel_x = -25 }, /obj/effect/turf_decal/stripes/corner, +/obj/structure/cable{ + icon_state = "0-4" + }, /turf/open/floor/plasteel, /area/construction) "cX" = ( @@ -1065,6 +1081,9 @@ dir = 1 }, /obj/effect/turf_decal/stripes/line, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plasteel, /area/construction) "cY" = ( @@ -1079,9 +1098,6 @@ /area/construction) "da" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, /turf/closed/wall/r_wall, /area/commons/storage/primary) "db" = ( @@ -1262,7 +1278,7 @@ /area/commons/storage/primary) "dD" = ( /obj/effect/landmark/observer_start, -/turf/open/floor/plasteel, +/turf/open/floor/plasteel/goonplaque, /area/commons/storage/primary) "dE" = ( /obj/effect/turf_decal/stripes/line{ @@ -1330,6 +1346,7 @@ "dQ" = ( /obj/structure/table, /obj/machinery/light, +/obj/item/debug/human_spawner, /turf/open/floor/plasteel, /area/commons/storage/primary) "dR" = ( @@ -1341,7 +1358,7 @@ "dS" = ( /obj/machinery/atmospherics/components/unary/tank/air, /obj/machinery/camera/autoname, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engineering/atmos) "dT" = ( /obj/machinery/camera/autoname, @@ -1422,17 +1439,16 @@ roundstart_template = /datum/map_template/shuttle/arrival/box; width = 7 }, -/turf/open/space/basic, -/area/space) +/turf/open/floor/engine, +/area/hallway/secondary/entry) "ed" = ( /obj/structure/sign/warning/pods, /turf/closed/wall/r_wall, /area/hallway/secondary/entry) "ee" = ( -/obj/machinery/door/airlock/external{ - name = "Mining Dock Airlock" +/obj/effect/turf_decal/stripes/line{ + dir = 4 }, -/obj/structure/fans/tiny, /turf/open/floor/plasteel, /area/cargo/miningoffice) "ef" = ( @@ -1470,12 +1486,9 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "el" = ( -/obj/docking_port/stationary/random{ - id = "pod_lavaland1"; - name = "lavaland" - }, -/turf/open/space, -/area/space) +/obj/structure/fans/tiny/invisible, +/turf/open/floor/engine, +/area/hallway/secondary/entry) "em" = ( /turf/closed/wall/r_wall, /area/cargo/miningoffice) @@ -1484,12 +1497,10 @@ /turf/open/floor/plating, /area/hallway/secondary/entry) "eo" = ( -/obj/machinery/door/airlock/external{ - name = "Arrival Airlock" - }, -/obj/structure/fans/tiny, -/turf/open/floor/plasteel, -/area/hallway/secondary/entry) +/obj/structure/table, +/obj/item/storage/belt/military/abductor/full, +/turf/open/floor/plasteel/dark, +/area/science/circuit) "ep" = ( /obj/structure/cable{ icon_state = "2-4" @@ -1512,10 +1523,8 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "er" = ( -/obj/item/gun/magic/staff/healing, -/obj/item/gun/magic/wand/resurrection/debug, -/turf/open/floor/plasteel, -/area/medical/medbay) +/turf/closed/wall/r_wall, +/area/science/circuit) "es" = ( /obj/machinery/light, /obj/machinery/clonepod, @@ -1581,7 +1590,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ - icon_state = "1-2" + icon_state = "2-4" }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) @@ -1652,9 +1661,6 @@ /turf/open/space/basic, /area/space) "eK" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/structure/cable{ icon_state = "1-4" }, @@ -1662,6 +1668,9 @@ /obj/effect/turf_decal/stripes/corner{ dir = 8 }, +/obj/structure/cable{ + icon_state = "2-4" + }, /turf/open/floor/plasteel, /area/commons/storage/primary) "eL" = ( @@ -1684,6 +1693,17 @@ }, /turf/open/floor/plasteel, /area/cargo/storage) +"eO" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/medical/medbay) "eP" = ( /obj/structure/cable{ icon_state = "0-2"; @@ -1758,8 +1778,13 @@ /turf/open/floor/plasteel, /area/commons/storage/primary) "eX" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/camera/autoname{ + dir = 1 + }, +/turf/open/floor/plasteel, /area/cargo/miningoffice) "eY" = ( /obj/machinery/conveyor{ @@ -1864,9 +1889,8 @@ roundstart_template = /datum/map_template/shuttle/escape_pod/default; width = 3 }, -/obj/structure/fans/tiny/invisible, -/turf/open/space/basic, -/area/space) +/turf/open/floor/plating, +/area/hallway/secondary/entry) "fj" = ( /obj/structure/sign/warning/docking, /turf/closed/wall/r_wall, @@ -1913,9 +1937,6 @@ /obj/machinery/camera/autoname{ dir = 4 }, -/obj/machinery/computer/bounty{ - dir = 4 - }, /turf/open/floor/plasteel, /area/cargo/storage) "fr" = ( @@ -1946,21 +1967,24 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "fu" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "1-8" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "fv" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "fw" = ( @@ -2002,12 +2026,15 @@ /obj/effect/turf_decal/plaque{ icon_state = "L5" }, -/obj/structure/cable{ - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, /turf/open/floor/plasteel, /area/commons/storage/primary) "fA" = ( @@ -2108,15 +2135,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, -/obj/structure/cable{ - icon_state = "1-4" - }, /turf/open/floor/plasteel, /area/commons/storage/primary) "fL" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, /obj/structure/cable{ icon_state = "1-8" }, @@ -2156,21 +2177,18 @@ /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "fP" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/machinery/keycard_auth{ - pixel_y = 28 +/obj/structure/cable{ + icon_state = "1-2" }, /turf/open/floor/plasteel, -/area/hallway/secondary/exit/departure_lounge) +/area/medical/chemistry) "fQ" = ( -/obj/machinery/computer/communications, -/obj/machinery/status_display/evac{ - pixel_y = 32 +/obj/machinery/door/airlock/public/glass, +/obj/structure/cable{ + icon_state = "1-2" }, /turf/open/floor/plasteel, -/area/hallway/secondary/exit/departure_lounge) +/area/commons/storage/primary) "fR" = ( /obj/machinery/door/airlock, /obj/structure/cable{ @@ -2197,23 +2215,17 @@ /turf/open/floor/plasteel, /area/science) "fU" = ( -/obj/structure/cable{ - icon_state = "4-8" +/obj/machinery/keycard_auth{ + pixel_y = 28 }, -/obj/machinery/airalarm/unlocked{ - pixel_y = 23 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 +/obj/machinery/light{ + dir = 1 }, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "fV" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +/obj/machinery/light{ + dir = 1 }, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) @@ -2221,9 +2233,7 @@ /obj/structure/cable{ icon_state = "1-8" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "fX" = ( @@ -2296,12 +2306,9 @@ /turf/open/floor/plating, /area/commons/storage/primary) "gh" = ( -/obj/machinery/light{ +/obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/machinery/computer/shuttle/mining{ - dir = 2 - }, /turf/open/floor/plasteel, /area/cargo/miningoffice) "gi" = ( @@ -2316,20 +2323,14 @@ /obj/machinery/airalarm/unlocked{ pixel_x = 32 }, +/obj/machinery/computer/shuttle/mining{ + dir = 2 + }, /turf/open/floor/plasteel, /area/cargo/miningoffice) "gj" = ( -/obj/docking_port/stationary{ - dir = 8; - dwidth = 3; - height = 5; - id = "mining_home"; - name = "mining shuttle bay"; - roundstart_template = /datum/map_template/shuttle/mining/box; - width = 7 - }, -/turf/open/space/basic, -/area/space) +/turf/open/floor/engine, +/area/cargo/miningoffice) "gk" = ( /obj/structure/sign/departments/evac, /turf/closed/wall/r_wall, @@ -2338,6 +2339,9 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, /turf/open/floor/plasteel, /area/cargo/miningoffice) "gm" = ( @@ -2354,31 +2358,27 @@ /turf/open/floor/plasteel, /area/security/brig) "go" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-8" + }, /turf/open/floor/plasteel, /area/cargo/miningoffice) "gp" = ( -/obj/machinery/door/airlock, -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, +/turf/closed/wall/r_wall, /area/cargo/miningoffice) "gq" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "gr" = ( -/obj/structure/cable{ - icon_state = "1-4" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "gs" = ( @@ -2398,15 +2398,15 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "gu" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, /obj/structure/cable{ icon_state = "2-8" }, +/obj/structure/cable{ + icon_state = "1-8" + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "gv" = ( @@ -2437,23 +2437,15 @@ /turf/open/floor/plasteel, /area/construction) "gz" = ( -/obj/structure/table, -/obj/item/card/id/captains_spare, -/obj/machinery/keycard_auth{ - pixel_y = 28 - }, +/obj/machinery/camera/autoname, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "gA" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/light{ - dir = 1 +/obj/machinery/keycard_auth{ + pixel_y = 28 }, +/obj/structure/table, +/obj/item/card/id/captains_spare, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "gB" = ( @@ -2475,8 +2467,11 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "gD" = ( -/obj/machinery/camera/autoname{ - dir = 1 +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "2-4" }, /turf/open/floor/plasteel, /area/cargo/miningoffice) @@ -2500,13 +2495,10 @@ /turf/open/floor/plasteel, /area/construction) "gH" = ( -/obj/structure/cable{ - icon_state = "4-8" +/obj/machinery/status_display/evac{ + pixel_y = 32 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/camera/autoname, +/obj/machinery/computer/communications, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "gI" = ( @@ -2550,16 +2542,39 @@ }, /turf/open/floor/plasteel, /area/science) -"hD" = ( -/obj/machinery/power/apc{ - dir = 1; - pixel_y = 23 +"hb" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 }, +/obj/machinery/power/apc/auto_name/north, /obj/structure/cable{ - icon_state = "0-2" + icon_state = "0-8" }, +/turf/open/floor/plasteel/dark, +/area/science/circuit) +"hD" = ( +/obj/structure/closet/secure_closet/chemical, /turf/open/floor/plasteel, /area/medical/chemistry) +"ip" = ( +/obj/machinery/nanite_program_hub/admin, +/turf/open/floor/plasteel/dark, +/area/science/circuit) +"iS" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"iW" = ( +/obj/structure/rack, +/obj/item/storage/box/disks_nanite, +/obj/item/nanite_scanner, +/obj/item/nanite_remote, +/obj/item/nanite_remote/comm, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/science/circuit) "jb" = ( /obj/machinery/door/airlock, /obj/structure/cable{ @@ -2591,29 +2606,32 @@ /obj/machinery/vending/hydroseeds, /turf/open/floor/grass, /area/service/hydroponics) +"kj" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) "kk" = ( /obj/structure/lattice/catwalk, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/structure/cable{ icon_state = "1-4" }, /obj/structure/cable{ icon_state = "2-8" }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, /turf/open/space, /area/space/nearstation) "kn" = ( /obj/machinery/light{ dir = 1 }, -/obj/structure/cable{ - icon_state = "2-4" - }, /turf/open/floor/plasteel, /area/hallway/primary/central) "kG" = ( @@ -2628,9 +2646,6 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/structure/cable{ - icon_state = "0-8" - }, /obj/machinery/power/apc{ dir = 1; pixel_y = 23 @@ -2638,6 +2653,9 @@ /obj/structure/cable{ icon_state = "0-4" }, +/obj/structure/cable{ + icon_state = "2-4" + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "kT" = ( @@ -2653,6 +2671,14 @@ }, /turf/open/floor/plasteel, /area/engineering/main) +"lN" = ( +/obj/effect/landmark/blobstart, +/turf/open/floor/plasteel, +/area/commons/storage/primary) +"lV" = ( +/obj/machinery/public_nanite_chamber, +/turf/open/floor/plasteel/dark, +/area/science/circuit) "lX" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 @@ -2667,6 +2693,12 @@ /obj/structure/filingcabinet/chestdrawer/wheeled, /turf/open/floor/plasteel, /area/cargo/storage) +"nc" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/hallway/secondary/exit/departure_lounge) "ny" = ( /obj/structure/table, /obj/item/storage/toolbox/syndicate, @@ -2674,8 +2706,15 @@ /area/commons/storage/primary) "ou" = ( /obj/machinery/airalarm/directional/west, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engineering/atmos) +"oy" = ( +/obj/machinery/door/airlock/public/glass, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/medical/medbay) "oV" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -2700,7 +2739,7 @@ dir = 8 }, /obj/machinery/door/airlock/external/glass, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/medical/medbay) "pQ" = ( /obj/structure/cable{ @@ -2713,11 +2752,22 @@ /turf/open/floor/plasteel, /area/engineering/atmos) "qn" = ( -/obj/structure/cable{ - icon_state = "0-2" +/turf/open/floor/engine, +/area/hallway/secondary/entry) +"qs" = ( +/obj/structure/table, +/obj/item/screwdriver{ + pixel_y = 10 }, -/turf/open/floor/plating, -/area/maintenance/department/bridge) +/turf/open/floor/plasteel, +/area/medical/chemistry) +"qy" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/hallway/primary/central) "qZ" = ( /obj/structure/lattice, /obj/structure/lattice/catwalk, @@ -2726,12 +2776,19 @@ }, /turf/open/space, /area/space/nearstation) +"ry" = ( +/obj/docking_port/stationary/random, +/turf/open/space/basic, +/area/space) "rN" = ( /obj/structure/cable{ icon_state = "1-8" }, /turf/open/floor/plasteel/freezer, /area/service/cafeteria) +"rW" = ( +/turf/open/floor/plasteel/dark, +/area/science/circuit) "sD" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -2761,6 +2818,34 @@ }, /turf/open/floor/plasteel, /area/service/bar) +"sZ" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) +"tl" = ( +/obj/effect/turf_decal/stripes/line, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/construction) +"tA" = ( +/obj/structure/chair/office/dark{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/science/circuit) +"tE" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/science/circuit) "up" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -2774,7 +2859,7 @@ /obj/machinery/light{ dir = 1 }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engineering/atmos) "vm" = ( /turf/closed/wall/r_wall, @@ -2812,6 +2897,9 @@ dir = 4 }, /obj/machinery/door/airlock/public/glass, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel, /area/medical/chemistry) "wb" = ( @@ -2860,6 +2948,12 @@ "xj" = ( /turf/open/floor/plasteel, /area/service/hydroponics) +"xW" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/science/circuit) "yl" = ( /obj/structure/chair/stool/bar, /obj/structure/cable{ @@ -2871,6 +2965,12 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/service/bar) +"yx" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) "yM" = ( /obj/machinery/vending/wallmed, /turf/closed/wall/r_wall, @@ -2895,11 +2995,23 @@ /turf/open/floor/plasteel, /area/science) "Bl" = ( -/obj/structure/cable{ - icon_state = "1-2" +/obj/effect/turf_decal/stripes/line{ + dir = 8 }, -/turf/closed/wall/r_wall, -/area/engineering/gravity_generator) +/turf/open/floor/plating, +/area/hallway/secondary/entry) +"Bq" = ( +/obj/docking_port/stationary{ + dir = 8; + dwidth = 3; + height = 5; + id = "mining_home"; + name = "mining shuttle bay"; + roundstart_template = /datum/map_template/shuttle/mining/box; + width = 7 + }, +/turf/open/floor/engine, +/area/cargo/miningoffice) "BB" = ( /obj/machinery/computer/cloning{ dir = 1 @@ -2925,6 +3037,12 @@ /obj/item/gun/ballistic/automatic/pistol, /turf/open/floor/plasteel, /area/command/bridge) +"BP" = ( +/obj/structure/chair/office/dark{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/science/circuit) "Ce" = ( /turf/open/floor/plasteel, /area/medical/chemistry) @@ -2932,6 +3050,15 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/service/cafeteria) +"Cs" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel, +/area/medical/chemistry) "Ct" = ( /obj/structure/closet/syndicate/resources/everything, /turf/open/floor/plasteel, @@ -2990,12 +3117,26 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "Fg" = ( -/turf/open/floor/plasteel, -/area/engineering/atmos) +/obj/structure/fans/tiny/invisible, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/engine, +/area/hallway/secondary/entry) "Fy" = ( /obj/machinery/seed_extractor, /turf/open/floor/grass, /area/service/hydroponics) +"FO" = ( +/obj/machinery/door/airlock/research, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/dark, +/area/science/circuit) "Ga" = ( /obj/machinery/vending/boozeomat, /obj/machinery/airalarm{ @@ -3004,6 +3145,18 @@ }, /turf/open/floor/plasteel, /area/service/bar) +"Gb" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) "Gc" = ( /obj/structure/closet/secure_closet/miner/unlocked, /turf/open/floor/plasteel, @@ -3020,6 +3173,12 @@ /obj/item/queen_bee/bought, /turf/open/floor/grass, /area/service/hydroponics) +"HR" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/hallway/primary/central) "If" = ( /obj/machinery/rnd/production/techfab/department, /turf/open/floor/plasteel, @@ -3038,6 +3197,13 @@ /obj/structure/chair/stool/bar, /turf/open/floor/carpet/blackred, /area/service/bar) +"Je" = ( +/obj/structure/fans/tiny/invisible, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/engine, +/area/hallway/secondary/entry) "JF" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 @@ -3051,15 +3217,18 @@ /turf/open/floor/plasteel, /area/service/hydroponics) "JV" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/structure/cable{ icon_state = "1-4" }, /obj/structure/cable{ icon_state = "1-8" }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, /turf/open/floor/plasteel, /area/service/bar) "Kx" = ( @@ -3069,6 +3238,13 @@ /obj/machinery/light, /turf/open/floor/plating, /area/engineering/atmos) +"KN" = ( +/obj/machinery/light, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) "Lg" = ( /obj/machinery/door/airlock/external{ name = "Labor Camp Shuttle Airlock" @@ -3082,10 +3258,26 @@ }, /turf/open/floor/carpet/blackred, /area/service/bar) +"Ls" = ( +/obj/machinery/door/airlock, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) "Ly" = ( /obj/machinery/chem_dispenser/chem_synthesizer, /turf/open/floor/plasteel/dark, /area/medical/chemistry) +"LR" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/cargo/miningoffice) "Mk" = ( /obj/structure/table, /obj/item/book_of_babel, @@ -3148,10 +3340,21 @@ /obj/machinery/rnd/production/protolathe/department, /turf/open/floor/plasteel, /area/science) +"OT" = ( +/obj/machinery/door/airlock/public/glass, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/construction) "OU" = ( /obj/item/disk/tech_disk/debug, /turf/open/floor/plasteel, /area/science) +"Pt" = ( +/obj/machinery/door/airlock/research, +/turf/open/floor/plasteel/dark, +/area/construction) "PD" = ( /obj/structure/cable{ icon_state = "4-8" @@ -3159,9 +3362,11 @@ /turf/open/floor/plasteel/freezer, /area/service/cafeteria) "PI" = ( -/obj/structure/fans/tiny/invisible, -/turf/open/space/basic, -/area/space) +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating, +/area/hallway/secondary/entry) "PV" = ( /obj/machinery/vending/dinnerware, /turf/open/floor/plasteel/freezer, @@ -3171,7 +3376,7 @@ dir = 4 }, /obj/machinery/door/airlock/external/glass, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/medical/medbay) "Rb" = ( /obj/effect/spawner/structure/window/reinforced, @@ -3212,6 +3417,19 @@ /obj/item/reagent_containers/glass/beaker/bluespace, /turf/open/floor/grass, /area/service/hydroponics) +"Ti" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/science/circuit) +"To" = ( +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/medical/chemistry) "Tp" = ( /obj/structure/cable{ icon_state = "0-2" @@ -3222,6 +3440,10 @@ "Tt" = ( /turf/open/floor/plating, /area/maintenance/aft) +"Ty" = ( +/obj/machinery/computer/nanite_cloud_controller, +/turf/open/floor/plasteel/dark, +/area/science/circuit) "TZ" = ( /turf/closed/wall/r_wall, /area/service/bar) @@ -3232,10 +3454,23 @@ /obj/item/healthanalyzer/advanced, /turf/open/floor/plasteel, /area/medical/medbay) +"UJ" = ( +/obj/machinery/door/airlock, +/turf/open/floor/plasteel/dark, +/area/construction) "Vg" = ( /obj/machinery/light, +/obj/structure/cable{ + icon_state = "1-4" + }, /turf/open/floor/plasteel, /area/hallway/primary/central) +"Vq" = ( +/obj/machinery/airalarm/unlocked{ + pixel_y = 23 + }, +/turf/open/floor/plasteel, +/area/hallway/secondary/exit/departure_lounge) "Vy" = ( /obj/structure/cable{ icon_state = "4-8" @@ -3249,10 +3484,18 @@ /obj/structure/fans/tiny, /turf/open/floor/plasteel, /area/engineering/main) +"Wb" = ( +/obj/machinery/airalarm/directional/north, +/turf/open/floor/plasteel/dark, +/area/science/circuit) "Wh" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/engineering/atmos) +"Wi" = ( +/obj/machinery/door/poddoor, +/turf/open/floor/engine, +/area/hallway/secondary/entry) "WT" = ( /obj/structure/cable{ icon_state = "4-8" @@ -3267,6 +3510,7 @@ /obj/machinery/light{ dir = 4 }, +/obj/machinery/vending/syndichem, /turf/open/floor/plasteel, /area/medical/chemistry) "Xp" = ( @@ -3278,10 +3522,10 @@ /area/engineering/atmos) "XC" = ( /obj/structure/cable{ - icon_state = "4-8" + icon_state = "2-8" }, /obj/structure/cable{ - icon_state = "2-8" + icon_state = "2-4" }, /turf/open/floor/plasteel, /area/science) @@ -3296,8 +3540,14 @@ /obj/machinery/light{ dir = 1 }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engineering/atmos) +"Yp" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/hallway/secondary/exit/departure_lounge) "Yy" = ( /obj/machinery/light{ dir = 1 @@ -3312,6 +3562,10 @@ "YB" = ( /turf/open/floor/plasteel/freezer, /area/service/cafeteria) +"Zr" = ( +/obj/machinery/door/poddoor, +/turf/open/floor/engine, +/area/cargo/miningoffice) "ZD" = ( /obj/machinery/suit_storage_unit/ce, /turf/open/floor/plasteel, @@ -4261,32 +4515,32 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +em +em +em +em +em +em +em +em +em +em +em +em +en +en +dY +Wi +Wi +Wi +Wi +Wi +Wi +Wi +dY +en +dY +dY aa aa aa @@ -4353,32 +4607,32 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +em +ee +ee +ee +ee +ee +LR +ee +ee +ee +kj +em +eh +eh +eh +qn +qn +qn +qn +qn +qn +qn +eh +eh +eh +dY aa aa aa @@ -4445,32 +4699,32 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Zr +gj +gj +gj +gj +gj +gj +gj +gj +gj +cO +em +eh +eh +eh +qn +qn +qn +qn +qn +qn +qn +eh +eh +eh +en aa aa aa @@ -4537,32 +4791,32 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Zr +gj +gj +gj +gj +gj +gj +gj +gj +gj +cO +em +eh +eh +eh +qn +qn +qn +qn +qn +qn +qn +eh +eh +eh +en aa aa aa @@ -4629,32 +4883,32 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Zr +gj +gj +gj +gj +gj +gj +gj +gj +gj +KN +em +ej +eh +eh +qn +qn +qn +qn +qn +qn +qn +eh +eh +eh +dY aa aa aa @@ -4721,32 +4975,32 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Zr gj -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +gj +gj +gj +gj +gj +gj +gj +gj +cO +em +eh +eh +eh +qn +qn +qn +qn +qn +qn +qn +eh +eh +eh +en aa aa aa @@ -4813,32 +5067,32 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -em -eX -ee +Zr +gj +gj +gj +gj +gj +Bq +gj +gj +gj eX em -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +eh +eh +eh +qn +qn +qn +qn +qn +qn +qn +eh +eh +eh +en aa aa aa @@ -4905,32 +5159,32 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa em gh +gh +gh +gh +gh +sZ +gh +gh gl gD -em -dY -dY -dY -aa -aa -aa -aa -aa -aa -aa -dY -dY -dY -dY +Ls +yx +bj +eh +qn +qn +qn +qn +qn +qn +qn +eh +eh +eh +en aa aa aa @@ -4997,29 +5251,29 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa +em +em +em +em +em +em +em em gi gm go gp -ei +iS gr -dY -aa -aa -aa -aa -aa -aa -aa -dY +eh +qn +qn +qn +qn +qn +qn +qn +eh eh eh dY @@ -5094,24 +5348,24 @@ aa aa aa aa -aa -aa db dY dY dY dY +dY +dY eh eq -en -aa -aa -aa -aa -aa -aa -aa -en +eh +qn +qn +qn +qn +qn +qn +qn +eh eh eh en @@ -5186,24 +5440,24 @@ aa aa aa aa -aa -aa -aa -aa -PI +Fg +Bl +Bl +Bl +Bl dj ed eh eq -en -aa -aa -aa -aa -aa -aa -aa -en +eh +qn +qn +qn +qn +qn +qn +qn +eh eh eh en @@ -5276,26 +5530,26 @@ aa aa aa aa -aa +ry aa el -aa -aa -aa +dV +dV +dV fi dP ex eh eq -eo -aa -aa -aa -aa -aa -aa -aa -eo +eh +qn +qn +qn +qn +qn +qn +qn +eh eh gv dY @@ -5370,24 +5624,24 @@ aa aa aa aa -aa -aa -aa -aa +Je +PI +PI +PI PI dV dY ej eq -en -aa -aa -aa -aa -aa -aa -aa -en +eh +qn +qn +qn +qn +qn +qn +qn +eh eh eh en @@ -5462,24 +5716,24 @@ aa aa aa aa -fg -aa db dY dY dY dY +dY +dY eh eq -en -aa -aa -aa -aa -aa -aa -aa -en +eh +qn +qn +qn +qn +qn +qn +qn +eh eh gF fj @@ -5563,15 +5817,15 @@ aa dY gE eq -dY -aa -aa -aa -aa -aa -aa -aa -dY +eh +qn +qn +qn +qn +qn +qn +qn +eh eh eh en @@ -5655,15 +5909,15 @@ aa dY gq gs -dY -aa -aa -aa -aa -aa -aa -aa -dY +eh +qn +qn +qn +qn +qn +qn +qn +eh eh gw dY @@ -5747,15 +6001,15 @@ aa dY eh eq -en -aa -aa -aa -aa -aa -aa -aa -en +eh +qn +qn +qn +qn +qn +qn +qn +eh eh ek en @@ -5839,15 +6093,15 @@ aa dY eh gt -en -aa -aa -aa -aa -aa -aa -aa -en +eh +qn +qn +qn +qn +qn +qn +qn +eh eh ek en @@ -5931,15 +6185,15 @@ aa dY ej gt -eo -aa -aa -aa -aa -aa -aa -aa -eo +eh +qn +qn +qn +qn +qn +qn +qn +eh eh ek en @@ -6023,15 +6277,15 @@ aa dY eh gt -en -aa -aa -aa -aa -aa -aa -aa -en +eh +qn +qn +qn +qn +qn +qn +qn +eh eh gx dY @@ -6115,15 +6369,15 @@ aa dY eh gt -dh -aa -aa -aa +eh +qn +qn +qn ec -aa -aa -aa -dY +qn +qn +qn +eh eh ek en @@ -6207,7 +6461,7 @@ ag ag eh gt -dh +eh dh en en @@ -6215,7 +6469,7 @@ en en en dY -dY +eh eh ek dY @@ -6408,7 +6662,7 @@ eL eL eL eL -eL +Gb fd eL vs @@ -6500,7 +6754,7 @@ eh eh eh eh -eh +gt eh eh ge @@ -6592,7 +6846,7 @@ cN cN cN cN -fI +FO dY dY ge @@ -6656,10 +6910,10 @@ aa aa ah ut -Fg +aw ou -Fg -Fg +aw +aw Kx ah bs @@ -6669,8 +6923,8 @@ If bA kn fu -bO -cO +bE +cN cW dm dy @@ -6684,9 +6938,9 @@ dy dm dK cN -Tt -vm -fg +hb +tE +cj NC NC YB @@ -6761,7 +7015,7 @@ AP pA kQ fv -bN +qy cP cX dn @@ -6775,11 +7029,11 @@ dn dn dn dL -cN -Tt -vm -fg -aa +UJ +xW +rW +rW +BP NC Nw rN @@ -6853,9 +7107,9 @@ gY jb ES bE -bE -cQ -cY +HR +OT +tl dn dn dn @@ -6868,10 +7122,10 @@ dn dn dL cN -Tt -vm -fg -aa +Wb +lV +Ty +eo NC PV NL @@ -6959,11 +7213,11 @@ dn dn dn dL -cN -Tt -vm -fg -aa +Pt +rW +rW +tA +rW NC NC Cr @@ -7052,11 +7306,11 @@ dn dn dL cN -Tt -vm -fg -aa -aa +rW +iW +cU +ip +Ti aa aa aa @@ -7144,11 +7398,11 @@ dn dn dL cN -Tt -vm -fg -aa -aa +fI +er +Ti +Ti +Ti aa aa aa @@ -7237,7 +7491,7 @@ dn dZ cN Tt -Rb +vm fg aa aa @@ -7329,7 +7583,7 @@ dn dL cN Tt -Rb +vm fg aa aa @@ -7421,7 +7675,7 @@ dn dL cN Tt -Rb +vm fg aa aa @@ -7788,10 +8042,10 @@ cS cS cS cS -fI -ga -ga -ga +Tt +Rb +aa +aa aa aa aa @@ -7880,10 +8134,10 @@ dl dp dE cS -fO -fO -fO -gf +Tt +vm +aa +aa aa aa aa @@ -7952,7 +8206,7 @@ bd bo aj hD -cj +pQ ct Ce cF @@ -7972,10 +8226,10 @@ dC dC eI vv -fO -fO -fO -fb +Tt +vm +aa +aa aa aa aa @@ -8048,8 +8302,8 @@ fL ch cs cT -cU -cU +bN +bN da fK dJ @@ -8064,10 +8318,10 @@ dJ dJ eD cS -fO -fO -fO -gf +Tt +vm +aa +aa aa aa aa @@ -8136,9 +8390,9 @@ bf bp aj bP -pQ -JF Ce +JF +pQ oV bE bE @@ -8156,11 +8410,11 @@ dJ dJ ny cS -fP -fO -fO -fb -aa +fI +ga +ga +ga +ga aa aa aa @@ -8228,11 +8482,11 @@ ak ak ak bQ -pQ Ce Ce +Cs vP -bE +bO Vg cS fy @@ -8248,7 +8502,8 @@ dJ dJ dO cS -gz +fO +fO fO fO gf @@ -8295,7 +8550,6 @@ aa aa aa aa -aa "} (55,1,1) = {" aa @@ -8320,13 +8574,13 @@ bg bq ak bR -pQ -Ce -Ce +fP +fP +To oV bE -bE -cV +HR +fQ fz ds dJ @@ -8340,11 +8594,11 @@ dJ dJ jU cS -fQ fO fO -ga -aa +fO +fO +fb aa aa aa @@ -8403,8 +8657,8 @@ aa aa aa ad -qn -Bl +af +ak at aH aW @@ -8412,9 +8666,9 @@ bh br ak bS +Ce +Ce pQ -Ce -Ce oV bE bE @@ -8426,17 +8680,17 @@ dD dJ dI dJ -dJ +lN dJ dJ dJ ea cS -fS fO fO -gk -aa +fO +fO +gf aa aa aa @@ -8504,9 +8758,9 @@ aI aI ak Ly -pQ +qs Xg -Ce +pQ oV bE bE @@ -8525,10 +8779,10 @@ dJ dN cS fU -gb fO -ga -aa +fO +fO +fb aa aa aa @@ -8598,7 +8852,7 @@ by by ck by -cx +oy cG cx by @@ -8619,6 +8873,7 @@ cS gA fO fO +fO gf aa aa @@ -8663,7 +8918,6 @@ aa aa aa aa -aa "} (59,1,1) = {" aa @@ -8689,8 +8943,8 @@ av by bU cl -cu -cu +cl +eO cH cu cJ @@ -8711,8 +8965,8 @@ cS gH fO fO -fb -fp +fO +ga aa aa aa @@ -8800,11 +9054,11 @@ dJ dJ eD cS -fV +fS +nc +gb fO -fO -gf -aa +gk aa aa aa @@ -8893,10 +9147,10 @@ fG fH fR fW +Yp fO fO -fb -aa +ga aa aa aa @@ -8984,6 +9238,7 @@ dl dx dE cS +fV fO fO fO @@ -9031,7 +9286,6 @@ aa aa aa aa -aa "} (63,1,1) = {" aa @@ -9076,12 +9330,12 @@ cS cS cS cS -ga -ga -ga -ga -aa -aa +gz +fO +fO +fO +fb +fp aa aa aa @@ -9152,7 +9406,7 @@ af by cz by -er +cm es by eu @@ -9168,11 +9422,11 @@ nb Go Gc et -aa -aa -aa -aa -aa +Vq +fO +fO +fO +gf aa aa aa @@ -9260,11 +9514,11 @@ fo eu eu et -aa -aa -aa -aa -aa +fO +fO +fO +fO +fb aa aa aa @@ -9352,11 +9606,11 @@ fm fm ev et -aa -aa -aa -aa -aa +fO +fO +fO +fO +gf aa aa aa @@ -9444,11 +9698,11 @@ fh fh fh et -aa -aa -aa -aa -aa +ga +ga +ga +ga +ga aa aa aa diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 4fb880fb4d..7f73180daa 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -1121,7 +1121,7 @@ dir = 8 }, /obj/machinery/sleeper{ - dir = 1 + dir = 4 }, /turf/open/floor/holofloor{ icon_state = "white" @@ -1134,9 +1134,7 @@ }, /area/holodeck/rec_center/medical) "dd" = ( -/obj/machinery/sleeper{ - dir = 1 - }, +/obj/machinery/stasis, /turf/open/floor/holofloor{ icon_state = "white" }, @@ -2282,7 +2280,7 @@ /turf/open/floor/plasteel, /area/tdome/arena_source) "fX" = ( -/turf/closed/indestructible/riveted, +/turf/closed/indestructible/start_area, /area/start) "fY" = ( /obj/effect/landmark/start/new_player, @@ -3265,6 +3263,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/light/floor, /turf/open/floor/plasteel/dark, /area/centcom/prison) "iB" = ( @@ -3538,7 +3537,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/machinery/light, +/obj/machinery/light/small, /turf/open/floor/plasteel, /area/centcom/control) "jj" = ( @@ -3849,9 +3848,6 @@ "jT" = ( /obj/machinery/computer/security, /obj/effect/turf_decal/stripes/line, -/obj/machinery/light{ - dir = 1 - }, /turf/open/floor/plasteel, /area/centcom/control) "jU" = ( @@ -4854,6 +4850,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/item/papercutter, /turf/open/floor/plasteel/dark, /area/centcom/supply) "mc" = ( @@ -6973,6 +6970,20 @@ }, /turf/open/floor/plasteel/dark, /area/centcom/ferry) +"pT" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/centcom/supplypod/loading/ert) "pU" = ( /obj/structure/sign/map/right{ pixel_y = -32 @@ -7348,6 +7359,20 @@ /obj/machinery/washing_machine, /turf/open/floor/plasteel/white, /area/centcom/holding) +"qH" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/centcom/evac) "qI" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/light{ @@ -7355,6 +7380,12 @@ }, /turf/open/floor/plating, /area/syndicate_mothership) +"qK" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/turf/open/floor/plasteel, +/area/centcom/supplypod/loading/ert) "qQ" = ( /obj/machinery/door/airlock/centcom{ name = "Administrative Office"; @@ -7957,6 +7988,12 @@ }, /turf/open/floor/engine/cult, /area/wizard_station) +"rY" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/centcom/supplypod/loading/ert) "sc" = ( /obj/docking_port/stationary{ area_type = /area/syndicate_mothership/control; @@ -8326,8 +8363,14 @@ /area/centcom/evac) "sP" = ( /obj/structure/table, -/obj/item/paper_bin, -/obj/item/pen, +/obj/item/paper_bin{ + pixel_x = -4; + pixel_y = 7 + }, +/obj/item/pen{ + pixel_x = -5; + pixel_y = 9 + }, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -8455,6 +8498,12 @@ /obj/item/soap/syndie, /turf/open/floor/plasteel/freezer, /area/syndicate_mothership) +"tj" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/centcom/supplypod/loading/ert) "tl" = ( /obj/effect/turf_decal/stripes/corner, /turf/open/floor/plating, @@ -9377,6 +9426,7 @@ /turf/open/floor/plasteel, /area/centcom/evac) "vh" = ( +/obj/machinery/light/floor, /turf/open/floor/plasteel, /area/centcom/evac) "vi" = ( @@ -10341,6 +10391,12 @@ /obj/machinery/light, /turf/open/floor/carpet, /area/wizard_station) +"xA" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/centcom/supplypod/loading/ert) "xB" = ( /obj/machinery/button/door{ id = "Ninja3"; @@ -11920,12 +11976,12 @@ /turf/open/floor/plasteel/white, /area/centcom/control) "BH" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/machinery/sleeper{ + dir = 4 + }, /turf/open/floor/plasteel, /area/centcom/control) "BI" = ( @@ -11940,12 +11996,10 @@ /turf/open/floor/plasteel, /area/centcom/control) "BJ" = ( -/obj/machinery/sleeper{ - dir = 8 - }, /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/obj/machinery/stasis, /turf/open/floor/plasteel, /area/centcom/control) "BK" = ( @@ -12826,6 +12880,10 @@ "Di" = ( /turf/closed/indestructible/riveted, /area/ai_multicam_room) +"Dj" = ( +/obj/effect/light_emitter, +/turf/open/floor/plasteel, +/area/centcom/supplypod/loading/four) "Dk" = ( /obj/structure/table, /turf/open/floor/plasteel/cafeteria, @@ -13652,6 +13710,13 @@ /obj/structure/chair/stool, /turf/open/indestructible/hotelwood, /area/centcom/holding) +"Fc" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/tdome/tdomeadmin) "Fe" = ( /turf/closed/indestructible/wood, /area/centcom/holding) @@ -14066,13 +14131,9 @@ /turf/open/floor/plasteel, /area/tdome/tdomeobserve) "Gk" = ( -/obj/machinery/light, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/tdome/tdomeobserve) +/obj/structure/closet/secure_closet/personal, +/turf/open/floor/plasteel/dark, +/area/centcom/supplypod) "Gl" = ( /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/yellow{ @@ -14445,7 +14506,10 @@ /area/tdome/tdomeobserve) "GS" = ( /obj/structure/table/wood, -/obj/structure/reagent_dispensers/beerkeg, +/obj/structure/reagent_dispensers/beerkeg{ + pixel_x = 5; + pixel_y = 6 + }, /obj/machinery/newscaster{ pixel_y = 32 }, @@ -14520,14 +14584,10 @@ /turf/open/indestructible/hotelwood, /area/centcom/holding) "Ha" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, +/obj/effect/turf_decal/delivery, +/obj/machinery/light/floor, /turf/open/floor/plasteel, -/area/centcom/supplypod) +/area/centcom/evac) "Hb" = ( /obj/structure/sink{ dir = 8; @@ -15423,12 +15483,9 @@ /turf/open/floor/plasteel, /area/tdome/arena) "IK" = ( -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/centcom/supplypod) +/obj/structure/fans/tiny/invisible, +/turf/open/floor/holofloor/hyperspace, +/area/space) "IL" = ( /obj/effect/landmark/thunderdome/one, /obj/effect/turf_decal/stripes/line{ @@ -15959,6 +16016,13 @@ }, /turf/open/floor/plasteel, /area/tdome/tdomeadmin) +"JY" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/tdome/tdomeobserve) "JZ" = ( /obj/item/kirbyplants{ icon_state = "plant-21" @@ -16269,6 +16333,11 @@ }, /turf/open/floor/plasteel/dark, /area/tdome/tdomeadmin) +"Kz" = ( +/obj/effect/turf_decal/delivery, +/obj/effect/light_emitter, +/turf/open/floor/plasteel, +/area/centcom/supplypod/loading/two) "KA" = ( /obj/structure/flora/ausbushes/lavendergrass, /obj/structure/flora/ausbushes/sparsegrass, @@ -16448,9 +16517,14 @@ /obj/item/clothing/mask/luchador/rudos, /turf/open/floor/holofloor/wood, /area/holodeck/rec_center/wrestlingarena) +"Lg" = ( +/obj/effect/turf_decal/delivery, +/obj/effect/light_emitter, +/turf/open/floor/plasteel, +/area/centcom/supplypod/loading/one) "Lh" = ( -/obj/machinery/sleeper{ - dir = 8 +/obj/machinery/stasis{ + dir = 4 }, /turf/open/floor/mineral/titanium/blue, /area/centcom/evac) @@ -16484,6 +16558,20 @@ }, /turf/open/floor/wood, /area/centcom/holding) +"Lr" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/light/floor, +/turf/open/floor/plasteel/dark, +/area/centcom/control) "Ls" = ( /obj/docking_port/stationary{ dir = 4; @@ -16849,8 +16937,16 @@ /turf/open/indestructible/binary, /area/fabric_of_reality) "MC" = ( -/obj/machinery/vending/cigarette, -/turf/open/floor/plasteel, +/obj/structure/table/wood, +/obj/item/storage/box/drinkingglasses{ + pixel_y = 14; + pixel_x = -4 + }, +/obj/item/reagent_containers/borghypo/borgshaker{ + pixel_x = -10; + pixel_y = -8 + }, +/turf/open/floor/plasteel/dark, /area/centcom/supplypod) "MD" = ( /obj/effect/light_emitter{ @@ -17091,6 +17187,20 @@ }, /turf/open/floor/plasteel, /area/centcom/control) +"NK" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/light/floor, +/turf/open/floor/plasteel/dark, +/area/tdome/tdomeobserve) "NP" = ( /obj/machinery/button/crematorium{ id = "crematoriumGhostDojo"; @@ -17261,6 +17371,17 @@ }, /turf/open/floor/plating, /area/syndicate_mothership) +"OA" = ( +/obj/structure/table/wood, +/obj/item/crowbar/power{ + pixel_y = 15 + }, +/obj/item/lighter{ + pixel_x = -6; + pixel_y = -2 + }, +/turf/open/floor/plasteel/dark, +/area/centcom/supplypod) "OB" = ( /obj/machinery/door/airlock/centcom{ name = "Barracks"; @@ -17269,15 +17390,11 @@ /turf/open/floor/plasteel, /area/syndicate_mothership) "OE" = ( -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 1 +/obj/effect/turf_decal/stripes/line{ + dir = 4 }, /turf/open/floor/plasteel, -/area/centcom/supplypod) +/area/centcom/supplypod/loading/ert) "OH" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plasteel/dark, @@ -17293,11 +17410,12 @@ /turf/open/indestructible/hotelwood, /area/centcom/holding) "OM" = ( -/obj/machinery/light{ - dir = 4 +/obj/effect/turf_decal/stripes/line{ + dir = 6 }, -/turf/open/floor/plasteel/dark, -/area/centcom/supplypod) +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/tdome/tdomeadmin) "ON" = ( /obj/structure/table, /obj/item/storage/box/handcuffs, @@ -17313,6 +17431,10 @@ }, /turf/open/floor/mineral/titanium/blue, /area/centcom/holding) +"OQ" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/space) "OS" = ( /obj/structure/mecha_wreckage/mauler, /turf/open/floor/plasteel/dark, @@ -17335,10 +17457,21 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plating, /area/syndicate_mothership) +"Pa" = ( +/obj/machinery/sleeper{ + dir = 8 + }, +/turf/open/floor/mineral/titanium/blue, +/area/centcom/evac) "Pg" = ( /obj/machinery/light{ dir = 1 }, +/obj/structure/table/wood, +/obj/structure/reagent_dispensers/beerkeg{ + pixel_x = 5; + pixel_y = 6 + }, /turf/open/floor/plasteel/dark, /area/centcom/supplypod) "Pl" = ( @@ -17373,9 +17506,8 @@ /turf/open/floor/plasteel/cafeteria, /area/centcom/holding) "Ps" = ( -/obj/machinery/light, -/turf/open/floor/plasteel/dark, -/area/centcom/supplypod) +/turf/open/floor/holofloor/hyperspace, +/area/space) "Pv" = ( /obj/effect/turf_decal/tile/brown, /obj/effect/turf_decal/tile/brown{ @@ -17488,10 +17620,13 @@ /turf/open/floor/plasteel, /area/syndicate_mothership) "PU" = ( -/obj/structure/table/reinforced, -/obj/item/folder/white, -/obj/item/pen/blue, -/turf/open/floor/plasteel, +/obj/structure/table/wood, +/obj/machinery/microwave{ + pixel_x = -3; + pixel_y = 5; + desc = "Cooks and boils stuff, somehow." + }, +/turf/open/floor/plasteel/dark, /area/centcom/supplypod) "PV" = ( /obj/effect/turf_decal/tile/green{ @@ -17592,6 +17727,12 @@ }, /turf/open/floor/plasteel, /area/syndicate_mothership) +"Qu" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/centcom/supplypod/loading/ert) "Qw" = ( /obj/structure/table, /obj/item/clothing/gloves/boxing, @@ -17637,6 +17778,13 @@ }, /turf/open/indestructible/hotelwood, /area/centcom/holding) +"QI" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/centcom/supplypod/loading/ert) "QK" = ( /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, @@ -17804,6 +17952,13 @@ }, /turf/open/indestructible/hotelwood, /area/centcom/holding) +"RV" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/tdome/tdomeadmin) "RZ" = ( /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ @@ -17852,6 +18007,15 @@ /obj/item/toy/nuke, /turf/open/floor/wood, /area/syndicate_mothership) +"Sl" = ( +/obj/effect/light_emitter, +/turf/open/floor/plasteel, +/area/centcom/supplypod/loading/one) +"Sm" = ( +/obj/structure/fans/tiny/invisible, +/obj/structure/fans/tiny/invisible, +/turf/open/floor/holofloor/hyperspace, +/area/space) "So" = ( /obj/structure/chair/wood/wings{ dir = 4 @@ -17861,6 +18025,17 @@ }, /turf/open/indestructible/hotelwood, /area/centcom/holding) +"Sq" = ( +/obj/structure/table/wood, +/obj/item/storage/box/donkpockets{ + pixel_x = 5; + pixel_y = 15 + }, +/obj/item/storage/fancy/cigarettes/cigars/cohiba{ + pixel_y = 6 + }, +/turf/open/floor/plasteel/dark, +/area/centcom/supplypod) "St" = ( /obj/machinery/shower{ dir = 4 @@ -17929,6 +18104,11 @@ }, /turf/open/floor/plasteel, /area/centcom/supplypod/loading/two) +"SK" = ( +/obj/effect/turf_decal/delivery, +/obj/effect/light_emitter, +/turf/open/floor/plasteel, +/area/centcom/supplypod/loading/three) "SM" = ( /obj/machinery/vending/autodrobe{ extended_inventory = 1 @@ -18248,16 +18428,17 @@ }, /turf/open/floor/wood, /area/centcom/holding) -"UL" = ( -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 +"UK" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 }, +/obj/machinery/light/floor, /turf/open/floor/plasteel, -/area/centcom/supplypod) +/area/tdome/tdomeobserve) +"UL" = ( +/obj/structure/fans/tiny/invisible, +/turf/open/floor/holofloor/hyperspace, +/area/centcom/supplypod/supplypod_temp_holding) "UO" = ( /obj/machinery/door/airlock/centcom{ name = "CentCom Security"; @@ -18467,14 +18648,18 @@ /turf/open/floor/plating, /area/syndicate_mothership) "VQ" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ dir = 1 }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, /turf/open/floor/plasteel, -/area/centcom/supplypod) +/area/centcom/supplypod/loading/ert) "VR" = ( /obj/machinery/light, /turf/open/floor/plating, @@ -18486,6 +18671,10 @@ }, /turf/open/floor/wood, /area/syndicate_mothership) +"VV" = ( +/obj/effect/light_emitter, +/turf/open/floor/plasteel, +/area/centcom/supplypod/podStorage) "VX" = ( /obj/effect/landmark/shuttle_import, /turf/open/space/basic, @@ -18516,15 +18705,11 @@ /turf/open/indestructible/hotelwood, /area/centcom/holding) "Wi" = ( -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 1 +/obj/effect/turf_decal/stripes/line{ + dir = 10 }, /turf/open/floor/plasteel, -/area/centcom/supplypod) +/area/centcom/supplypod/loading/ert) "Wj" = ( /obj/structure/closet/cardboard/metal, /obj/effect/turf_decal/stripes/corner{ @@ -18567,6 +18752,11 @@ "WH" = ( /obj/structure/table/reinforced, /obj/item/reagent_containers/food/drinks/bottle/whiskey{ + pixel_y = 19; + pixel_x = 7 + }, +/obj/item/clothing/mask/cigarette/cigar/havana{ + pixel_x = -6; pixel_y = 5 }, /turf/open/floor/plasteel, @@ -18637,6 +18827,10 @@ /obj/machinery/processor, /turf/open/floor/plasteel/cafeteria, /area/syndicate_mothership) +"WY" = ( +/obj/effect/light_emitter, +/turf/open/floor/plasteel, +/area/centcom/supplypod/loading/two) "Xb" = ( /obj/structure/closet/crate, /obj/item/vending_refill/autodrobe, @@ -18773,6 +18967,13 @@ "XN" = ( /turf/open/floor/carpet/red, /area/centcom/holding) +"XP" = ( +/obj/machinery/door/airlock/centcom{ + name = "Orbital Drop Pod Loading"; + req_access_txt = "101" + }, +/turf/open/floor/plating, +/area/centcom/ferry) "XT" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/sashimi, @@ -18925,6 +19126,11 @@ /obj/item/book/manual/hydroponics_pod_people, /turf/open/indestructible/hotelwood, /area/centcom/holding) +"YT" = ( +/obj/effect/turf_decal/delivery, +/obj/effect/light_emitter, +/turf/open/floor/plasteel, +/area/centcom/supplypod/loading/four) "YU" = ( /obj/structure/window/reinforced{ dir = 1 @@ -18961,21 +19167,30 @@ /turf/open/floor/plasteel, /area/centcom/supplypod/podStorage) "Zj" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 +/obj/effect/turf_decal/stripes/line{ + dir = 5 }, +/obj/machinery/light/floor, /turf/open/floor/plasteel, -/area/centcom/supplypod) +/area/tdome/tdomeadmin) "Zl" = ( /obj/structure/bed/dogbed, /turf/open/indestructible/hotelwood, /area/centcom/holding) +"Zn" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/light/floor, +/turf/open/floor/plasteel, +/area/centcom/evac) "Zr" = ( /obj/machinery/light, /turf/open/floor/plasteel/dark, @@ -19009,6 +19224,13 @@ /obj/effect/landmark/start/nukeop_leader, /turf/open/floor/wood, /area/syndicate_mothership) +"ZE" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/structure/closet/secure_closet/personal, +/turf/open/floor/plasteel/dark, +/area/centcom/supplypod) "ZF" = ( /obj/effect/turf_decal/tile/brown, /obj/effect/turf_decal/tile/brown{ @@ -19106,80 +19328,6 @@ /area/centcom/supply) (1,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -19361,82 +19509,82 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa "} (2,1,1) = {" -aa -ad -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -19606,6 +19754,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa LV LV LV @@ -19620,80 +19842,6 @@ LV aa "} (3,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -19772,6 +19920,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa kK lg lB @@ -19877,80 +20099,6 @@ LV aa "} (4,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -20028,6 +20176,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ko kL lh @@ -20134,80 +20356,6 @@ LV aa "} (5,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -20285,6 +20433,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa kp kM li @@ -20391,80 +20613,6 @@ LV aa "} (6,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -20542,6 +20690,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa kq kN li @@ -20648,80 +20870,6 @@ LV aa "} (7,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -20799,6 +20947,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa kr kO li @@ -20905,80 +21127,6 @@ LV aa "} (8,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -21056,6 +21204,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa ks kP lj @@ -21162,80 +21384,6 @@ LV aa "} (9,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -21314,6 +21462,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa kQ lk lH @@ -21419,80 +21641,6 @@ LV aa "} (10,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -21662,6 +21810,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa LV LW LY @@ -21676,80 +21898,6 @@ LV aa "} (11,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -21830,6 +21978,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa lI lI lI @@ -21933,80 +22155,6 @@ LV aa "} (12,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -22087,6 +22235,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa lI lI lI @@ -22190,80 +22412,6 @@ LV aa "} (13,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -22344,6 +22492,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa lI lI lI @@ -22447,80 +22669,6 @@ LV aa "} (14,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -22601,6 +22749,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa lI lI lI @@ -22704,80 +22926,6 @@ LV aa "} (15,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -22858,6 +23006,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa lI lI lI @@ -22961,80 +23183,6 @@ LV aa "} (16,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -23115,6 +23263,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa lI lI lI @@ -23218,80 +23440,6 @@ LV aa "} (17,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -23372,6 +23520,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa lI lI lI @@ -23475,80 +23697,6 @@ aa aa "} (18,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -23629,6 +23777,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa lI lI lI @@ -23732,80 +23954,6 @@ aa aa "} (19,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -23886,6 +24034,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa lI lI lI @@ -23969,100 +24191,26 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Sm +IK +IK +IK +IK +IK +IK +IK +IK +IK +IK +IK +IK +IK +IK +IK +Sm aa "} (20,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -24143,6 +24291,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa lI lI lI @@ -24226,100 +24448,26 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +IK +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +IK aa "} (21,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -24400,6 +24548,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa lI lI lI @@ -24483,100 +24705,26 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +IK +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +IK aa "} (22,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa fX fX fX @@ -24657,6 +24805,80 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa lI lI lI @@ -24740,23 +24962,23 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +IK +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +IK aa "} (23,1,1) = {" @@ -24997,23 +25219,23 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +IK +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +IK aa "} (24,1,1) = {" @@ -25254,23 +25476,23 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +IK +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +IK aa "} (25,1,1) = {" @@ -25511,23 +25733,23 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +IK +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +IK aa "} (26,1,1) = {" @@ -25768,23 +25990,23 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +IK +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +IK aa "} (27,1,1) = {" @@ -26025,23 +26247,23 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +IK +Ps +Ps +Ps +Ps +Ps +IK +IK +IK +IK +IK +Ps +Ps +Ps +Ps +Ps +IK aa "} (28,1,1) = {" @@ -26282,23 +26504,23 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +IK +Ps +Ps +Ps +Ps +Ps +IK +UL +UL +UL +IK +Ps +Ps +Ps +Ps +Ps +IK aa "} (29,1,1) = {" @@ -26539,23 +26761,23 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +IK +Ps +Ps +Ps +Ps +Ps +IK +UL +UL +UL +IK +Ps +Ps +Ps +Ps +Ps +IK aa "} (30,1,1) = {" @@ -26796,23 +27018,23 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +IK +Ps +Ps +Ps +Ps +Ps +IK +UL +UL +UL +IK +Ps +Ps +Ps +Ps +Ps +IK aa "} (31,1,1) = {" @@ -27053,23 +27275,23 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +IK +Ps +Ps +Ps +Ps +Ps +IK +IK +IK +IK +IK +Ps +Ps +Ps +Ps +Ps +IK aa "} (32,1,1) = {" @@ -27280,37 +27502,6 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI aa aa aa @@ -27328,6 +27519,37 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +IK +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +IK +aa "} (33,1,1) = {" aa @@ -27537,37 +27759,6 @@ aa aa aa aa -lI -lI -lI -Zc -Zc -Zc -Zc -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI aa aa aa @@ -27585,6 +27776,37 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +IK +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +IK +aa "} (34,1,1) = {" aa @@ -27794,37 +28016,6 @@ aa aa aa aa -lI -lI -lI -lI -lI -Zc -Zc -Zc -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -Zc -lI -Zc -Zc -lI -lI -lI -lI -lI -lI -lI aa aa aa @@ -27842,6 +28033,37 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +IK +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +IK +aa "} (35,1,1) = {" aa @@ -28051,37 +28273,6 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -Zc -Zc -Zc -lI -lI -lI -lI -lI -lI -lI -lI aa aa aa @@ -28099,6 +28290,37 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +IK +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +IK +aa "} (36,1,1) = {" aa @@ -28308,37 +28530,6 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -lI -Zc -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -Zc -Zc -Zc -lI -lI -lI -lI -lI -lI -Zc -Zc -lI aa aa aa @@ -28356,6 +28547,37 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +IK +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +IK +aa "} (37,1,1) = {" aa @@ -28565,37 +28787,6 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -lI -lI -Zc -lI -lI -lI -lI -lI -lI -lI -lI -lI -Zc -lI -lI -lI -lI -lI -lI -lI -lI -Zc -lI -lI aa aa aa @@ -28613,6 +28804,37 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +IK +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +IK +aa "} (38,1,1) = {" aa @@ -28822,37 +29044,6 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -Zc -lI -lI -lI aa aa aa @@ -28870,6 +29061,37 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +IK +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +Ps +IK +aa "} (39,1,1) = {" aa @@ -29079,37 +29301,6 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -MB -MB -MB -To -To -To -To -To -MH -To -To -To -MB -To -To -To -To -lI -lI -lI -lI -lI -lI -lI aa aa aa @@ -29127,6 +29318,37 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +Sm +IK +IK +IK +IK +IK +IK +IK +IK +IK +IK +IK +IK +IK +IK +IK +Sm +aa "} (40,1,1) = {" aa @@ -29336,37 +29558,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -To -To -MB -MB -To -To -To -To -To -To -To -MB -MB -To -To -To -To -lI -lI -lI -lI -lI -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -29593,37 +29815,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -To -To -To -MB -MB -To -To -To -To -To -To -MB -To -To -To -To -To -lI -lI -lI -lI -lI -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -29850,37 +30072,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -To -To -To -To -MB -MB -To -To -To -To -To -MB -To -To -To -MB -MB -lI -lI -lI -lI -lI -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -30107,37 +30329,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -To -To -To -To -To -MB -MB -To -To -MB -MB -MB -To -To -MB -MB -To -lI -lI -lI -lI -lI -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -30364,37 +30586,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -To -To -To -To -To -To -MB -MB -To -MB -MB -MB -MB -MB -MB -To -To -lI -lI -lI -lI -lI -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -30621,37 +30843,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -MB -MB -To -To -To -To -To -MB -To -To -MB -To -To -To -To -To -To -lI -lI -lI -Zc -Zc -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -30878,37 +31100,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -To -MB -To -To -To -To -To -MB -MB -MB -To -To -To -To -To -To -To -lI -lI -Zc -Zc -Zc -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -31135,37 +31357,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -NF -To -To -To -To -To -To -MB -Qm -MB -To -To -To -To -To -To -AG -lI -lI -lI -Zc -Zc -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -31392,37 +31614,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -To -To -To -To -MB -MB -MB -MB -To -MB -MB -To -To -To -To -To -To -lI -lI -lI -Zc -Zc -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -31649,37 +31871,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -To -To -To -MB -MB -MB -MB -To -To -To -MB -To -To -To -To -To -To -lI -lI -lI -lI -Zc -Zc -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -31906,37 +32128,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -To -To -MB -MB -MB -To -To -To -To -To -MB -MB -To -To -To -To -To -lI -lI -lI -lI -lI -Zc -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -32163,37 +32385,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -To -MB -MB -To -MB -To -To -To -To -To -To -MB -MB -MB -To -To -To -lI -lI -lI -lI -lI -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -32420,37 +32642,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -MB -MB -To -To -MB -MB -To -To -To -To -To -To -To -MB -MB -To -To -lI -lI -lI -lI -lI -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -32677,37 +32899,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -To -To -To -MB -MB -MB -To -To -To -To -To -To -To -To -MB -MB -To -lI -lI -lI -lI -lI -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -32934,37 +33156,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -To -To -To -MB -To -To -To -To -To -To -To -To -To -To -To -MB -MB -lI -lI -lI -lI -lI -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -33191,37 +33413,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -To -To -To -MB -To -To -To -To -To -MB -To -To -To -To -To -To -MB -lI -lI -lI -lI -lI -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -33448,37 +33670,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -33705,37 +33927,37 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -33962,37 +34184,37 @@ aa aa aa aa -lI -lI -lI -lI -Zc -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -34219,37 +34441,37 @@ aa aa aa aa -lI -lI -lI -Zc -Zc -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -Zc -lI -lI -lI -lI -lI -lI -lI -lI -lI -Zc -Zc -Zc -lI -lI -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -34476,37 +34698,6 @@ aa aa aa aa -lI -lI -lI -Zc -Zc -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -Zc -lI -lI -lI -lI aa aa aa @@ -34518,6 +34709,37 @@ aa aa aa aa +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -34733,17 +34955,23 @@ aa aa aa aa -lI +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa lI lI lI Zc -lI -lI -lI -lI -lI -lI +Zc +Zc Zc lI lI @@ -34764,17 +34992,11 @@ lI lI lI lI -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI aa aa aa @@ -34990,37 +35212,6 @@ aa aa aa aa -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI -lI aa aa aa @@ -35032,6 +35223,37 @@ aa aa aa aa +lI +lI +lI +lI +lI +Zc +Zc +Zc +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +Zc +lI +Zc +Zc +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -35258,37 +35480,37 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +Zc +Zc +Zc +lI +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -35504,37 +35726,6 @@ aa aa aa aa -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -aa -aa -aa -aa -aa -aa -aa -aa aa aa aa @@ -35546,6 +35737,37 @@ aa aa aa aa +lI +lI +lI +lI +lI +lI +lI +lI +Zc +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +Zc +Zc +Zc +lI +lI +lI +lI +lI +lI +Zc +Zc +lI aa aa aa @@ -35761,37 +35983,6 @@ aa aa aa aa -Di -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Di -aa -aa -aa -aa -aa -aa -aa -aa aa aa aa @@ -35803,6 +35994,37 @@ aa aa aa aa +lI +lI +lI +lI +lI +lI +lI +lI +lI +Zc +lI +lI +lI +lI +lI +lI +lI +lI +lI +Zc +lI +lI +lI +lI +lI +lI +lI +lI +Zc +lI +lI aa aa aa @@ -36018,37 +36240,6 @@ aa aa aa aa -Di -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Di -aa -aa -aa -aa -aa -aa -aa -aa aa aa aa @@ -36060,6 +36251,37 @@ aa aa aa aa +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +Zc +lI +lI +lI aa aa aa @@ -36275,37 +36497,6 @@ aa aa aa aa -Di -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Di -aa -aa -aa -aa -aa -aa -aa -aa aa aa aa @@ -36317,6 +36508,37 @@ aa aa aa aa +lI +lI +lI +lI +lI +lI +lI +MB +MB +MB +To +To +To +To +To +MH +To +To +To +MB +To +To +To +To +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -36517,63 +36739,63 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe -Qe +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +To +To +MB +MB +To +To +To +To +To +To +To +MB +MB +To +To +To +To +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -36774,21 +36996,6 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -36815,22 +37022,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +To +To +To +MB +MB +To +To +To +To +To +To +MB +To +To +To +To +To +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -37031,21 +37253,6 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -37072,22 +37279,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +To +To +To +To +MB +MB +To +To +To +To +To +MB +To +To +To +MB +MB +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -37288,21 +37510,6 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -37329,22 +37536,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +To +To +To +To +To +MB +MB +To +To +MB +MB +MB +To +To +MB +MB +To +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -37545,21 +37767,6 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -37586,22 +37793,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +To +To +To +To +To +To +MB +MB +To +MB +MB +MB +MB +MB +MB +To +To +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -37802,21 +38024,6 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -37843,22 +38050,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +MB +MB +To +To +To +To +To +MB +To +To +MB +To +To +To +To +To +To +lI +lI +lI +Zc +Zc +lI +lI aa aa aa @@ -38059,21 +38281,6 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -38100,22 +38307,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +To +MB +To +To +To +To +To +MB +MB +MB +To +To +To +To +To +To +To +lI +lI +Zc +Zc +Zc +lI +lI aa aa aa @@ -38316,21 +38538,6 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -38342,7 +38549,7 @@ Qe Qe Qe Qe -pW +Qe Qe Qe Qe @@ -38357,22 +38564,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +NF +To +To +To +To +To +To +MB +Qm +MB +To +To +To +To +To +To +AG +lI +lI +lI +Zc +Zc +lI +lI aa aa aa @@ -38573,21 +38795,6 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -38614,22 +38821,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +To +To +To +To +MB +MB +MB +MB +To +MB +MB +To +To +To +To +To +To +lI +lI +lI +Zc +Zc +lI +lI aa aa aa @@ -38830,21 +39052,6 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -38871,22 +39078,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +To +To +To +MB +MB +MB +MB +To +To +To +MB +To +To +To +To +To +To +lI +lI +lI +lI +Zc +Zc +lI aa aa aa @@ -39087,21 +39309,6 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -39128,22 +39335,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +To +To +MB +MB +MB +To +To +To +To +To +MB +MB +To +To +To +To +To +lI +lI +lI +lI +lI +Zc +lI aa aa aa @@ -39344,21 +39566,6 @@ QV aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -39370,7 +39577,7 @@ Qe Qe Qe Qe -Qe +pW Qe Qe Qe @@ -39385,22 +39592,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +To +MB +MB +To +MB +To +To +To +To +To +To +MB +MB +MB +To +To +To +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -39601,21 +39823,6 @@ QV aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -39642,22 +39849,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +MB +MB +To +To +MB +MB +To +To +To +To +To +To +To +MB +MB +To +To +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -39858,21 +40080,6 @@ QV aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -39899,22 +40106,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +To +To +To +MB +MB +MB +To +To +To +To +To +To +To +To +MB +MB +To +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -40115,21 +40337,6 @@ QV aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -40156,22 +40363,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +To +To +To +MB +To +To +To +To +To +To +To +To +To +To +To +MB +MB +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -40372,21 +40594,6 @@ QV aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -40413,22 +40620,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +To +To +To +MB +To +To +To +To +To +MB +To +To +To +To +To +To +MB +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -40629,21 +40851,6 @@ QV aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -40670,22 +40877,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -40886,21 +41108,6 @@ QV aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa Di Qe Qe @@ -40927,22 +41134,37 @@ Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -41143,63 +41365,63 @@ QV aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di -Di Di +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +Zc +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -41400,63 +41622,63 @@ QV aa aa aa +Di +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +Zc +Zc +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +Zc +lI +lI +lI +lI +lI +lI +lI +lI +lI +Zc +Zc +Zc +lI +lI +lI aa aa aa @@ -41657,63 +41879,63 @@ QV aa aa aa +Di +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +Zc +Zc +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +Zc +lI +lI +lI +lI aa aa aa @@ -41914,63 +42136,63 @@ QV aa aa aa +Di +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Qe +Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +Zc +lI +lI +lI +lI +lI +lI +Zc +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -42171,63 +42393,63 @@ QV aa aa aa +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di +Di aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI +lI aa aa aa @@ -46068,7 +46290,7 @@ KH KY Lb KV -Lh +Pa Lb Li Li @@ -46325,7 +46547,7 @@ KO KV KV KV -Lb +Lh Lb Lp Lp @@ -53720,7 +53942,7 @@ oe xc oe aa -mD +aa aa aa aa @@ -54234,13 +54456,13 @@ oe Xy oe vB -mD -aa -aa -aa -aa -aa -aa +nU +OQ +OQ +ab +OQ +OQ +ab aa aa aa @@ -54491,13 +54713,13 @@ wr xe wr yo -nU -aa -aa -aa -aa -aa -aa +mD +rY +tj +tj +tj +Wi +OQ aa aa aa @@ -54748,13 +54970,13 @@ ws xf ws yp -oe -aa -aa -aa -aa -aa -aa +XP +QI +VQ +VQ +pT +qK +OQ aa aa aa @@ -55006,12 +55228,12 @@ xg wt yq mD -aa -aa -aa -aa -aa -aa +Qu +OE +OE +OE +xA +OQ aa aa aa @@ -57862,7 +58084,7 @@ Gv Ix IS Je -Jo +Fc IS WJ IS @@ -58118,7 +58340,7 @@ FL Gv Ix IS -Jf +Zj Jp IS WJ @@ -61959,8 +62181,8 @@ iu Ew Ey Fs -FM -Gk +UK +Gl Ep Ev Ev @@ -62477,7 +62699,7 @@ EO Gm Un GM -GM +NK GM Nk GM @@ -62987,8 +63209,8 @@ iu EA Ey Fu -FN -Gk +JY +Gl Ep Ev Ev @@ -65262,7 +65484,7 @@ jT iC iC iC -iC +Lr iC kZ iC @@ -66580,9 +66802,9 @@ lN iu iC io -Wr -MP -Wr +Gk +ZE +Gk Ep Fx FR @@ -66856,7 +67078,7 @@ FL Gv Ix IS -Je +RV Jo IS WJ @@ -67114,7 +67336,7 @@ Gv Ix IS Jf -Jp +OM IS WJ IS @@ -67610,8 +67832,8 @@ Cc VO yN QE +Oh Wr -td ZP td Wr @@ -67867,10 +68089,10 @@ Cc VO PG QE +Oh Ov yc UC -MC Oh Wr Wr @@ -68366,7 +68588,7 @@ uB vf vX vW -uB +qH uB uB uB @@ -68637,7 +68859,7 @@ qx sL VO sY -sY +Sl sY sY QK @@ -68650,11 +68872,11 @@ wh Qa wh Qa -wh +SK UW VO Zi -Zi +VV Zi tY aa @@ -69394,7 +69616,7 @@ uB vh vg vY -vY +Zn vY yB vh @@ -69411,14 +69633,14 @@ sY sY sY sY -QK +Lg VB VO Ob Ob VO wh -wh +SK wh wh wh @@ -69671,8 +69893,8 @@ WK WK UQ VO -Pg -Ps +Wr +Wr VO Om Om @@ -69927,14 +70149,14 @@ vo vo VO VO -Zj -SF -SF -OE +VO +OH +OH +VO +VO +VO VO VO -vo -vo VO VO VO @@ -70178,23 +70400,23 @@ qx qx qx VO -Wr -Ov -Ha -IK -Oh -MP -VQ -QE -QE -IK -MP -Ov -Ha -IK -Oh -PU -OH +Nz +Nz +Nz +Nz +Nz +oU +VO +aa +aa +VO +Sy +Sy +Sy +Sy +Sy +Pv +VO Zi Zi Zi @@ -70432,26 +70654,26 @@ AY rS qz qx -Wr -Wr -Wr -Wr -Ov -Ha -IK -Oh -OM -VQ -QE -QE -IK -OM -Ov -Ha -IK -Oh -QE -OH +MC +Sq +VO +Or +WY +Or +Or +Or +MU +VO +aa +aa +VO +PZ +PZ +PZ +RR +Dj +Sh +VO Zi Zi Zi @@ -70679,7 +70901,7 @@ uB uB uB uB -uB +qH uB xt zl @@ -70692,22 +70914,22 @@ qx Pg Wr VO +Or +ZQ +Or +ZQ +Or +MU VO +aa +aa VO -vo -vo -VO -VO -Wi -WO -WO -UL -VO -VO -vo -vo -VO -VO +RR +RR +PZ +RR +RR +Sh VO Zi Zi @@ -70946,28 +71168,28 @@ AW qx qy qx -Wr +PU Wr VO -Nz -Nz -Nz -Nz -Nz -oU +Or +ZQ +Or +ZQ +Or +MU VO -Pg -Ps +aa +aa VO -Sy -Sy -Sy -Sy -Sy -Pv +RR +RR +PZ +RR +RR +Sh VO Zi -Zi +VV Zi VO aa @@ -71203,24 +71425,24 @@ Bc qx qz qx -Wr +OA Wr VO Or +Or +Or ZQ -Or -Or -Or +Kz MU VO -td -td +aa +aa VO PZ +YT +PZ PZ PZ -RR -RR Sh VO Zi @@ -71446,15 +71668,15 @@ qx qx sU tV +Ha tV tV tV +Ha tV tV tV -tV -tV -tV +Ha tV Bd qx @@ -71463,22 +71685,22 @@ qx WH QE VO -Or -ZQ -Or -ZQ -Or -MU -vo -SF -SF -vo -RR -RR -PZ -RR -RR -Sh +SI +SI +SI +SI +SI +Vc +VO +aa +aa +VO +ZF +ZF +ZF +ZF +ZF +Xr VO Zi Zi @@ -71720,26 +71942,26 @@ qx SP SP VO -Or -ZQ -Or -ZQ -Or -MU -vo -WO -WO -vo -RR -RR -PZ -RR -RR -Sh VO -Zi -Zi -Zi +VO +VO +VO +VO +VO +VO +aa +aa +VO +VO +VO +VO +VO +VO +VO +VO +tY +tY +VO VO aa aa @@ -71976,27 +72198,27 @@ aa aa aa aa -VO -Or -Or -Or -ZQ -Or -MU -VO -Ob -Ob -VO -PZ -PZ -PZ -PZ -PZ -Sh -VO -tY -tY -VO +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -72233,24 +72455,24 @@ aa aa aa aa -VO -SI -SI -SI -SI -SI -Vc -VO -QE -QE -VO -ZF -ZF -ZF -ZF -ZF -Xr -VO +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -72490,24 +72712,24 @@ aa aa aa aa -VO -VO -VO -VO -VO -VO -VO -VO -OH -OH -VO -VO -VO -VO -VO -VO -VO -VO +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa diff --git a/_maps/shuttles/aux_base_default.dmm b/_maps/shuttles/aux_base_default.dmm index 684a78e980..7587fb40da 100644 --- a/_maps/shuttles/aux_base_default.dmm +++ b/_maps/shuttles/aux_base_default.dmm @@ -52,11 +52,7 @@ /area/shuttle/auxillary_base) "P" = ( /obj/docking_port/mobile/auxillary_base{ - dheight = 4; - dir = 2; - dwidth = 4; - height = 9; - width = 9 + dir = 2 }, /obj/machinery/bluespace_beacon, /obj/machinery/computer/auxillary_base, @@ -77,6 +73,7 @@ /area/shuttle/auxillary_base) "X" = ( /obj/machinery/camera{ + c_tag = "Auxiliary Base Platform"; dir = 1; network = list("auxbase") }, diff --git a/_maps/shuttles/aux_base_small.dmm b/_maps/shuttles/aux_base_small.dmm index fc507ea3d8..4dcc35c78b 100644 --- a/_maps/shuttles/aux_base_small.dmm +++ b/_maps/shuttles/aux_base_small.dmm @@ -35,6 +35,7 @@ /area/shuttle/auxillary_base) "h" = ( /obj/machinery/camera{ + c_tag = "Auxiliary Base Platform"; dir = 1; network = list("auxbase") }, @@ -49,11 +50,7 @@ /area/shuttle/auxillary_base) "j" = ( /obj/docking_port/mobile/auxillary_base{ - dheight = 4; - dir = 2; - dwidth = 4; - height = 9; - width = 9 + dir = 2 }, /obj/machinery/bluespace_beacon, /obj/machinery/computer/auxillary_base, diff --git a/_maps/shuttles/emergency_discoinferno.dmm b/_maps/shuttles/emergency_discoinferno.dmm index 92b515f17e..755198fe8a 100644 --- a/_maps/shuttles/emergency_discoinferno.dmm +++ b/_maps/shuttles/emergency_discoinferno.dmm @@ -89,7 +89,7 @@ "q" = ( /obj/structure/statue/plasma/scientist{ anchored = 1; - oreAmount = 50 + custom_materials = list(/datum/material/plasma = 100000) }, /turf/open/floor/light/colour_cycle, /area/shuttle/escape) diff --git a/_maps/shuttles/emergency_nature.dmm b/_maps/shuttles/emergency_nature.dmm index 51a14594fb..a7fcc12f1a 100644 --- a/_maps/shuttles/emergency_nature.dmm +++ b/_maps/shuttles/emergency_nature.dmm @@ -145,12 +145,9 @@ /turf/open/floor/plating, /area/shuttle/escape) "eS" = ( -/obj/effect/turf_decal/trimline/red/filled/end{ - dir = 1 - }, /obj/structure/table/reinforced, /obj/machinery/recharger, -/turf/open/floor/plasteel/dark, +/turf/open/floor/mineral/plastitanium/red/brig, /area/shuttle/escape) "eY" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -240,9 +237,6 @@ /turf/open/floor/grass, /area/shuttle/escape) "ht" = ( -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 9 - }, /obj/structure/chair/comfy/shuttle, /obj/machinery/light{ dir = 8 @@ -250,19 +244,7 @@ /obj/structure/reagent_dispensers/peppertank{ pixel_y = 28 }, -/turf/open/floor/plasteel/dark, -/area/shuttle/escape) -"hC" = ( -/obj/effect/turf_decal/trimline/red/filled/corner{ - dir = 1 - }, -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 4 - }, -/obj/structure/chair/comfy/shuttle{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/mineral/plastitanium/red/brig, /area/shuttle/escape) "hJ" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -287,10 +269,10 @@ /turf/open/floor/grass, /area/shuttle/escape) "it" = ( -/mob/living/carbon/monkey, /obj/structure/flora/grass/jungle/b{ icon_state = "bushb3" }, +/mob/living/carbon/monkey, /turf/open/floor/grass, /area/shuttle/escape) "iD" = ( @@ -333,21 +315,6 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/shuttle/escape) -"jX" = ( -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 9 - }, -/obj/structure/chair/comfy/shuttle{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/shuttle/escape) -"jZ" = ( -/obj/effect/turf_decal/trimline/red/filled/corner{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, -/area/shuttle/escape) "ke" = ( /obj/item/shovel/spade, /turf/open/floor/grass, @@ -385,13 +352,10 @@ }, /area/shuttle/escape) "lS" = ( -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 4 - }, /obj/structure/chair/comfy/shuttle{ dir = 8 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/mineral/plastitanium/red/brig, /area/shuttle/escape) "lT" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -428,9 +392,9 @@ /turf/open/floor/plasteel/white, /area/shuttle/escape) "mq" = ( -/mob/living/carbon/monkey, /obj/machinery/light/floor, /obj/structure/flora/ausbushes/sparsegrass, +/mob/living/carbon/monkey, /turf/open/floor/grass, /area/shuttle/escape) "mw" = ( @@ -557,13 +521,10 @@ /turf/open/floor/plasteel/white, /area/shuttle/escape) "tL" = ( -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 8 - }, /obj/structure/chair/comfy/shuttle{ dir = 4 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/mineral/plastitanium/red/brig, /area/shuttle/escape) "uc" = ( /obj/effect/turf_decal/weather/dirt{ @@ -595,15 +556,12 @@ /turf/open/floor/grass, /area/shuttle/escape) "vt" = ( -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 10 - }, /obj/structure/table/reinforced, /obj/item/restraints/handcuffs{ pixel_y = 7 }, /obj/item/storage/fancy/donut_box, -/turf/open/floor/plasteel/dark, +/turf/open/floor/mineral/plastitanium/red/brig, /area/shuttle/escape) "vx" = ( /obj/effect/turf_decal/stripes/line{ @@ -612,13 +570,9 @@ /turf/open/floor/plating, /area/shuttle/escape) "vP" = ( -/obj/effect/turf_decal/trimline/red/filled/line, -/turf/open/floor/plasteel/dark, +/turf/open/floor/mineral/plastitanium/red/brig, /area/shuttle/escape) "vW" = ( -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 6 - }, /obj/structure/table/reinforced, /obj/item/storage/box/handcuffs{ pixel_y = 5 @@ -626,7 +580,7 @@ /obj/machinery/light{ dir = 4 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/mineral/plastitanium/red/brig, /area/shuttle/escape) "wg" = ( /obj/effect/turf_decal/trimline/green/filled/end{ @@ -713,7 +667,7 @@ name = "Brig"; req_access_txt = "63; 42" }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/mineral/plastitanium/red/brig, /area/shuttle/escape) "Ai" = ( /obj/effect/turf_decal/weather/dirt{ @@ -926,8 +880,8 @@ /turf/open/floor/plasteel/white, /area/shuttle/escape) "Ia" = ( -/mob/living/carbon/monkey, /obj/structure/flora/ausbushes/sparsegrass, +/mob/living/carbon/monkey, /turf/open/floor/grass, /area/shuttle/escape) "Io" = ( @@ -1549,7 +1503,7 @@ gx WE VU Yu -jX +tL tL vt Yu @@ -1582,8 +1536,8 @@ gx VU Yu ht -jZ -WL +vP +vP vP zE HV @@ -1614,7 +1568,7 @@ WE (7,1,1) = {" VI eS -hC +lS lS lS vW diff --git a/_maps/spookystation.dm b/_maps/spookystation.dm new file mode 100644 index 0000000000..19bcee3b24 --- /dev/null +++ b/_maps/spookystation.dm @@ -0,0 +1,4 @@ +#define FORCE_MAP "_maps/spookystation.json" + +/turf + baseturfs = /turf/open/floor/plating/spookbase/dirtattachmentpoint diff --git a/_maps/spookystation.json b/_maps/spookystation.json new file mode 100644 index 0000000000..c880aacff7 --- /dev/null +++ b/_maps/spookystation.json @@ -0,0 +1,14 @@ +{ + "map_name": "SpookyStation", + "map_path": "map_files/SpookyStation", + "map_file": "SpookyStation.dmm", + "shuttles": { + "emergency": "emergency_pubby", + "whiteship": "whiteship_pubby", + "ferry": "ferry_fancy", + "cargo": "cargo_box" + }, + "traits": [ + { "Weather_Longrain":true } + ] +} diff --git a/_maps/templates/reactor_1.dmm b/_maps/templates/reactor_1.dmm new file mode 100644 index 0000000000..64c2ddc024 --- /dev/null +++ b/_maps/templates/reactor_1.dmm @@ -0,0 +1,149 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/obj/effect/turf_decal/stripes/red/corner{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engineering/main/reactor_core) +"b" = ( +/obj/effect/turf_decal/stripes/red/line{ + dir = 4 + }, +/obj/effect/turf_decal/arrows/white{ + dir = 8; + pixel_x = 5; + pixel_y = 10 + }, +/turf/open/floor/engine, +/area/engineering/main/reactor_core) +"c" = ( +/obj/effect/turf_decal/stripes/red/line{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main/reactor_core) +"d" = ( +/obj/structure/cable/yellow, +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/cargo, +/turf/open/floor/engine, +/area/engineering/main/reactor_core) +"e" = ( +/obj/effect/turf_decal/stripes/red/corner{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main/reactor_core) +"f" = ( +/obj/machinery/atmospherics/pipe/simple/cyan{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main/reactor_core) +"g" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/purple, +/turf/open/floor/engine, +/area/engineering/main/reactor_core) +"h" = ( +/turf/open/floor/engine, +/area/engineering/main/reactor_core) +"s" = ( +/obj/effect/turf_decal/stripes/red/corner, +/turf/open/floor/engine, +/area/engineering/main/reactor_core) +"t" = ( +/obj/effect/turf_decal/stripes/red/line{ + dir = 8 + }, +/obj/effect/turf_decal/arrows/white{ + dir = 8; + pixel_x = 5; + pixel_y = 10 + }, +/turf/open/floor/engine, +/area/engineering/main/reactor_core) +"B" = ( +/obj/effect/turf_decal/stripes/red/corner{ + dir = 1 + }, +/turf/open/floor/engine, +/area/engineering/main/reactor_core) +"G" = ( +/obj/machinery/atmospherics/pipe/simple/cyan{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engineering/main/reactor_core) +"M" = ( +/obj/effect/turf_decal/stripes/red/line, +/turf/open/floor/engine, +/area/engineering/main/reactor_core) +"O" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engineering/main/reactor_core) +"P" = ( +/obj/effect/turf_decal/stripes/red/line{ + dir = 8 + }, +/turf/open/floor/engine, +/area/engineering/main/reactor_core) +"V" = ( +/obj/effect/turf_decal/stripes/red/line{ + dir = 1 + }, +/turf/open/floor/engine, +/area/engineering/main/reactor_core) +"Y" = ( +/obj/structure/cable/yellow{ + icon_state = "0-2" + }, +/obj/machinery/atmospherics/pipe/simple/purple, +/turf/open/floor/plating, +/area/engineering/main/reactor_core) +"Z" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers{ + dir = 4 + }, +/turf/open/floor/engine, +/area/engineering/main/reactor_core) + +(1,1,1) = {" +s +c +O +b +a +"} +(2,1,1) = {" +M +h +Z +h +V +"} +(3,1,1) = {" +Y +g +d +h +V +"} +(4,1,1) = {" +M +h +f +h +V +"} +(5,1,1) = {" +B +P +G +t +e +"} diff --git a/_maps/templates/shelter_5.dmm b/_maps/templates/shelter_5.dmm index 643f744fb9..1826682834 100644 --- a/_maps/templates/shelter_5.dmm +++ b/_maps/templates/shelter_5.dmm @@ -1,242 +1,360 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"bG" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/survivalpod/nonpowered) "cc" = ( -/obj/machinery/vending/boozeomat, -/turf/open/floor/pod/dark, +/obj/machinery/vending/games{ + pixel_y = 29; + density = 0 + }, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "dH" = ( -/obj/structure/chair/sofa/corp, -/obj/machinery/light{ - dir = 1 +/obj/machinery/chem_dispenser/drinks/beer{ + pixel_y = 30; + density = 0 }, -/turf/open/floor/pod/dark, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "fp" = ( -/obj/machinery/smartfridge, -/turf/closed/wall/mineral/titanium/survival/pod, +/obj/structure/chair/office/dark{ + dir = 4 + }, +/turf/open/floor/carpet/royalblue, /area/survivalpod/nonpowered) "fC" = ( -/obj/structure/table/reinforced, -/obj/machinery/chem_dispenser/drinks, -/turf/open/floor/pod/dark, +/obj/structure/bookcase/random{ + pixel_y = 32; + density = 0 + }, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "fM" = ( -/obj/structure/table/survival_pod, -/obj/item/reagent_containers/glass/beaker/large, -/obj/item/reagent_containers/glass/beaker/large, -/obj/item/storage/bag/plants/portaseeder, -/obj/item/shovel/spade, -/obj/item/cultivator, -/obj/item/reagent_containers/spray/weedspray, +/obj/machinery/recharge_station/fullupgrade, /turf/open/floor/pod/dark, /area/survivalpod/nonpowered) "fN" = ( -/obj/structure/table/reinforced, -/obj/item/kitchen/knife, -/obj/item/kitchen/rollingpin, -/obj/machinery/reagentgrinder, -/turf/open/floor/pod/dark, +/obj/machinery/door/airlock/survival_pod/glass, +/turf/open/floor/noslip, /area/survivalpod/nonpowered) "gr" = ( -/obj/machinery/vending/wallmed, -/turf/closed/wall/mineral/titanium/survival/pod, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/power/rtg/advanced/fullupgrade, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/pod/dark, +/area/survivalpod/nonpowered) +"gC" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/survivalpod/nonpowered) +"gG" = ( +/obj/structure/chair/comfy/black{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "hr" = ( -/obj/structure/table/reinforced, -/obj/machinery/chem_dispenser/drinks/beer, +/obj/machinery/door/airlock/survival_pod/glass, +/obj/machinery/poweredfans, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/pod/dark, /area/survivalpod/nonpowered) "iu" = ( /obj/structure/curtain, -/obj/machinery/poweredfans, -/turf/open/floor/pod/dark, +/obj/machinery/door/window/survival_pod{ + dir = 4 + }, +/obj/structure/window/reinforced/tinted{ + dir = 1 + }, +/turf/open/floor/noslip, /area/survivalpod/nonpowered) "iD" = ( /obj/item/gps/computer, /turf/open/floor/pod/dark, /area/survivalpod/nonpowered) "iY" = ( -/obj/structure/bed/pod, -/obj/item/bedsheet/nanotrasen, -/turf/open/floor/pod/dark, +/obj/structure/bed/double/pod{ + dir = 4 + }, +/obj/item/bedsheet/cosmos/double{ + dir = 1 + }, +/obj/item/toy/plush/mothplushie, +/turf/open/floor/festive/wooden/wooden1, +/area/survivalpod/nonpowered) +"jA" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/survivalpod/nonpowered) +"ko" = ( +/obj/machinery/vending/boozeomat{ + density = 0; + pixel_y = 32 + }, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "lO" = ( /obj/machinery/poweredfans, /obj/machinery/door/airlock/survival_pod/glass, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/pod/dark, /area/survivalpod/nonpowered) "lW" = ( /obj/structure/chair/sofa/corp{ dir = 1 }, -/turf/open/floor/pod/dark, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "mC" = ( -/obj/structure/chair/sofa/corp{ +/obj/structure/chair/sofa/corp/right{ dir = 8 }, -/obj/machinery/light{ - dir = 4 - }, -/turf/open/floor/pod/dark, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "mN" = ( /obj/machinery/power/rtg/advanced/fullupgrade, +/obj/structure/cable{ + icon_state = "0-8" + }, /turf/open/floor/pod/dark, /area/survivalpod/nonpowered) "oo" = ( -/obj/machinery/vending/dinnerware, -/turf/open/floor/pod/dark, +/obj/structure/table/plasmaglass{ + density = 1 + }, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "pg" = ( -/obj/machinery/shower{ - dir = 8 - }, -/turf/open/floor/noslip, +/obj/structure/chair/comfy/black, +/turf/open/floor/carpet/royalblue, /area/survivalpod/nonpowered) "pF" = ( -/obj/machinery/modular_computer/console/preset/civilian{ - dir = 8 - }, -/turf/open/floor/pod/dark, +/obj/structure/closet/cabinet, +/obj/item/clothing/under/misc/bathrobe, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "qE" = ( -/obj/machinery/washing_machine, -/turf/open/floor/pod/dark, -/area/survivalpod/nonpowered) -"rL" = ( -/obj/structure/mirror, -/turf/closed/wall/mineral/titanium/survival/pod, +/obj/structure/sink{ + pixel_y = 24 + }, +/obj/structure/mirror{ + pixel_y = 34 + }, +/turf/open/floor/mineral/silver, /area/survivalpod/nonpowered) "rM" = ( /obj/structure/chair/sofa/corp/corner{ dir = 8 }, -/turf/open/floor/pod/dark, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "rZ" = ( -/obj/structure/sink{ - pixel_y = 18 - }, -/turf/open/floor/pod/dark, +/obj/machinery/washing_machine, +/turf/open/floor/mineral/silver, /area/survivalpod/nonpowered) -"sN" = ( -/obj/machinery/light{ - dir = 8 +"sD" = ( +/obj/machinery/camera{ + dir = 5 }, -/obj/structure/sink/kitchen{ - dir = 4; - pixel_x = -10 - }, -/turf/open/floor/pod/dark, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "td" = ( -/obj/machinery/hydroponics/constructable/automagic, -/turf/open/floor/pod/dark, -/area/survivalpod/nonpowered) -"um" = ( -/obj/structure/table/wood/fancy/monochrome, -/turf/open/floor/pod/dark, -/area/survivalpod/nonpowered) -"uR" = ( -/obj/machinery/light, -/turf/open/floor/pod/dark, -/area/survivalpod/nonpowered) -"vU" = ( -/obj/machinery/sleeper/survival_pod, -/turf/open/floor/pod/dark, -/area/survivalpod/nonpowered) -"wv" = ( -/obj/structure/table/reinforced, -/obj/machinery/microwave, -/turf/open/floor/pod/dark, -/area/survivalpod/nonpowered) -"wI" = ( -/obj/item/storage/fancy/candle_box, -/obj/structure/table/wood/fancy/blackred, /obj/machinery/light{ dir = 4 }, +/obj/structure/easel, +/obj/item/canvas/twentythreeXtwentythree, +/obj/item/storage/crayons, +/turf/open/floor/festive/wooden/wooden1, +/area/survivalpod/nonpowered) +"um" = ( +/obj/structure/table/wood/fancy/royalblack, +/obj/item/reagent_containers/food/drinks/bottle/lizardwine, +/turf/open/floor/carpet/royalblue, +/area/survivalpod/nonpowered) +"uR" = ( +/obj/machinery/light, +/turf/open/floor/festive/wooden/wooden1, +/area/survivalpod/nonpowered) +"vU" = ( +/obj/machinery/sleeper/survival_pod, +/obj/machinery/vending/wallmed{ + pixel_x = -26 + }, /turf/open/floor/pod/dark, /area/survivalpod/nonpowered) +"wv" = ( +/obj/machinery/holopad, +/turf/open/floor/carpet/royalblue, +/area/survivalpod/nonpowered) +"wI" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden1, +/area/survivalpod/nonpowered) "xC" = ( /obj/machinery/light{ dir = 4 }, +/obj/structure/table/plasmaglass, +/obj/structure/bedsheetbin/towel, +/turf/open/floor/mineral/silver, +/area/survivalpod/nonpowered) +"zo" = ( +/obj/structure/dresser, +/turf/open/floor/carpet/royalblue, +/area/survivalpod/nonpowered) +"zp" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/pod/dark, /area/survivalpod/nonpowered) "zW" = ( -/obj/machinery/vending/hydroseeds, -/turf/open/floor/pod/dark, +/obj/structure/sign/painting/library, +/turf/closed/wall/mineral/titanium/survival/pod, /area/survivalpod/nonpowered) "BI" = ( -/obj/structure/chair/sofa/corp/corner{ - dir = 4 +/obj/machinery/chem_dispenser/drinks{ + pixel_y = 30 }, -/turf/open/floor/pod/dark, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "Cj" = ( -/obj/structure/chair/sofa/corp/right{ - dir = 8 - }, +/turf/open/floor/festive/wooden/wooden1, +/area/survivalpod/nonpowered) +"Cq" = ( +/obj/machinery/poweredfans, +/obj/structure/window/shuttle/survival_pod, /turf/open/floor/pod/dark, /area/survivalpod/nonpowered) +"Ec" = ( +/obj/structure/closet/cabinet, +/obj/item/clothing/under/misc/bathrobe, +/obj/machinery/airalarm/directional/north, +/turf/open/floor/festive/wooden/wooden1, +/area/survivalpod/nonpowered) "EV" = ( -/obj/structure/bed/pod, -/obj/item/bedsheet/nanotrasen, -/obj/item/toy/plush/mothplushie, -/turf/open/floor/pod/dark, +/obj/structure/table/plasmaglass, +/obj/item/modular_computer/laptop/preset/civilian, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "Fo" = ( /obj/machinery/smartfridge/survival_pod, /turf/open/floor/pod/dark, /area/survivalpod/nonpowered) "Fw" = ( -/obj/structure/chair/sofa/corp{ +/obj/structure/chair/sofa/corp/left{ dir = 4 }, -/turf/open/floor/pod/dark, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "FE" = ( -/obj/machinery/light{ - dir = 8 +/obj/machinery/light, +/turf/open/floor/noslip, +/area/survivalpod/nonpowered) +"FT" = ( +/obj/machinery/airalarm/directional/east, +/obj/structure/cable{ + icon_state = "1-2" }, -/turf/open/floor/pod/dark, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "FZ" = ( /turf/closed/wall/mineral/titanium/survival/pod, /area/survivalpod/nonpowered) -"JL" = ( -/obj/machinery/door/window/survival_pod{ - dir = 8 +"Gd" = ( +/obj/structure/cable{ + icon_state = "1-2" }, -/turf/open/floor/pod/dark, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/survivalpod/nonpowered) +"JE" = ( +/obj/structure/table/wood/fancy/royalblack, +/obj/item/reagent_containers/food/drinks/drinkingglass, +/obj/item/reagent_containers/food/drinks/drinkingglass, +/turf/open/floor/carpet/royalblue, +/area/survivalpod/nonpowered) +"JL" = ( +/turf/open/floor/mineral/silver, /area/survivalpod/nonpowered) "Lv" = ( /turf/open/floor/pod/dark, /area/survivalpod/nonpowered) "Ng" = ( -/obj/structure/chair/wood/normal, -/turf/open/floor/pod/dark, +/obj/machinery/modular_computer/console/preset/civilian{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "Qr" = ( -/obj/effect/spawner/structure/window/hollow/survival_pod, +/obj/structure/window/shuttle/survival_pod, +/obj/machinery/poweredfans, /turf/open/floor/pod/dark, /area/survivalpod/nonpowered) +"QT" = ( +/obj/structure/rack, +/obj/item/clothing/shoes/sandal, +/obj/machinery/light, +/turf/open/floor/festive/wooden/wooden1, +/area/survivalpod/nonpowered) "Ro" = ( /obj/structure/chair/comfy/black{ dir = 4 }, -/turf/open/floor/pod/dark, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "Ry" = ( -/obj/structure/chair/sofa/corp/left, -/turf/open/floor/pod/dark, +/obj/structure/fireplace, +/obj/item/stack/sheet/mineral/wood/fifty, +/turf/open/floor/festive/wooden/wooden1, +/area/survivalpod/nonpowered) +"RD" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/festive/wooden/wooden1, +/area/survivalpod/nonpowered) +"RH" = ( +/obj/machinery/shower{ + pixel_y = 18 + }, +/obj/structure/window/reinforced/tinted{ + dir = 4 + }, +/turf/open/floor/noslip, /area/survivalpod/nonpowered) "Tc" = ( -/obj/machinery/light{ - dir = 1 +/obj/structure/toilet{ + dir = 4 }, -/turf/open/floor/pod/dark, +/turf/open/floor/mineral/silver, /area/survivalpod/nonpowered) "TQ" = ( /obj/structure/fans, @@ -246,20 +364,37 @@ /obj/structure/chair/sofa/corp/corner{ dir = 1 }, -/turf/open/floor/pod/dark, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "Vp" = ( -/obj/structure/table/reinforced, -/obj/machinery/dish_drive, -/turf/open/floor/pod/dark, +/turf/open/floor/carpet/royalblue, /area/survivalpod/nonpowered) "Vv" = ( -/obj/machinery/biogenerator, -/turf/open/floor/pod/dark, +/obj/structure/table/plasmaglass, +/obj/machinery/newscaster{ + pixel_x = 26 + }, +/obj/item/paper_bin, +/obj/item/pen/fountain, +/turf/open/floor/festive/wooden/wooden1, +/area/survivalpod/nonpowered) +"VJ" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/carpet/royalblue, +/area/survivalpod/nonpowered) +"Wk" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "Ws" = ( -/obj/structure/dresser, -/turf/open/floor/pod/dark, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden1, /area/survivalpod/nonpowered) "Xh" = ( /obj/machinery/door/airlock/survival_pod/glass, @@ -267,19 +402,32 @@ /area/survivalpod/nonpowered) "Xr" = ( /obj/machinery/door/airlock/survival_pod, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/pod/dark, /area/survivalpod/nonpowered) "Xy" = ( /obj/machinery/light, /obj/machinery/power/apc/auto_name/south, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, /turf/open/floor/pod/dark, /area/survivalpod/nonpowered) +"YC" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/telecomms/relay/preset/station, +/obj/item/multitool, +/turf/open/floor/festive/wooden/wooden1, +/area/survivalpod/nonpowered) "YH" = ( -/obj/structure/table/survival_pod, -/obj/item/shovel, -/obj/item/pickaxe, -/obj/item/storage/toolbox/electrical, -/obj/item/clothing/gloves/color/yellow, +/obj/machinery/mineral/equipment_vendor, /turf/open/floor/pod/dark, /area/survivalpod/nonpowered) @@ -300,31 +448,31 @@ FZ "} (2,1,1) = {" FZ -pg +RH FE FZ -EV -Ws +iY +FZ iY FZ BI -Fw +Cj Fw Ub -Qr +Cq "} (3,1,1) = {" FZ -FZ -iu -FZ Tc -Lv +iu +zW +Wk +zo uR FZ dH -um -um +pg +JE lW Qr "} @@ -332,27 +480,27 @@ Qr FZ qE JL -FZ -Lv -Lv -Ro +fN +Cj +Vp +Cj FZ Ry -um +pg um lW Qr "} (5,1,1) = {" -rL +FZ rZ xC -Xh -Lv -Lv +FZ +Ec +Cj pF FZ -Lv +ko Cj mC rM @@ -367,37 +515,37 @@ FZ Xh FZ FZ -Xh -FZ -FZ -FZ +cc +Cj +Cj +QT FZ "} (7,1,1) = {" -FZ -wv -sN -Lv -Xh -Lv -Lv -xC -Lv -FE -Lv -Lv +lO +gC +gC +gC +bG +gC +Gd +gC +gC +FT +gC +jA lO "} (8,1,1) = {" FZ -fN -Lv -oo FZ FZ -Xh FZ FZ +YC +RD +Cj +FZ FZ FZ Xr @@ -406,56 +554,56 @@ FZ (9,1,1) = {" FZ fC -Lv -cc -FZ -fM -Lv -td +sD +Cj +Ws +Cj +RD +Ro FZ TQ vU -Lv +zp FZ "} (10,1,1) = {" FZ -hr -Lv +fC Vp +Vp +wv +Vp +VJ +EV FZ -zW -Lv -td -gr YH -Lv +fM Xy FZ "} (11,1,1) = {" FZ -Lv -Lv -Lv +fC +Vp +Vp fp -Lv -Lv -td +Vp +VJ +gG FZ Fo Lv -Lv +gr FZ "} (12,1,1) = {" FZ -Ng +fC wI Ng Vv -Lv -xC +oo +RD td FZ iD @@ -469,8 +617,8 @@ Qr FZ Qr FZ -FZ -FZ +Qr +hr FZ FZ FZ diff --git a/_maps/templates/shelter_6.dmm b/_maps/templates/shelter_6.dmm new file mode 100644 index 0000000000..4297652286 --- /dev/null +++ b/_maps/templates/shelter_6.dmm @@ -0,0 +1,595 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"bn" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"by" = ( +/obj/machinery/power/rtg/advanced/fullupgrade, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel/freezer, +/area/survivalpod/nonpowered) +"cp" = ( +/obj/machinery/vending/dinnerware, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"cA" = ( +/obj/structure/flora/ausbushes/lavendergrass, +/obj/item/reagent_containers/glass/bucket, +/turf/open/floor/grass, +/area/survivalpod/nonpowered) +"dV" = ( +/obj/machinery/processor, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"ei" = ( +/obj/machinery/power/apc/auto_name/north, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel/freezer, +/area/survivalpod/nonpowered) +"eP" = ( +/obj/structure/chair/bronze{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/survivalpod/nonpowered) +"eS" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/pod/dark, +/area/survivalpod/nonpowered) +"fM" = ( +/obj/structure/cable{ + icon_state = "4-9" + }, +/turf/open/floor/plasteel/freezer, +/area/survivalpod/nonpowered) +"gO" = ( +/obj/machinery/door/airlock/survival_pod, +/obj/machinery/poweredfans, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/pod/dark, +/area/survivalpod/nonpowered) +"hv" = ( +/obj/machinery/seed_extractor, +/turf/open/floor/grass, +/area/survivalpod/nonpowered) +"hM" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/rack, +/obj/item/kitchen/knife, +/obj/item/kitchen/knife/butcher, +/obj/item/kitchen/rollingpin, +/obj/item/stack/sheet/mineral/coal/ten, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"iB" = ( +/obj/structure/table/plasmaglass, +/obj/machinery/smartfridge/disks, +/turf/open/floor/grass, +/area/survivalpod/nonpowered) +"iU" = ( +/obj/structure/table/reinforced, +/obj/item/clothing/head/chefhat, +/obj/machinery/reagentgrinder, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"kX" = ( +/obj/machinery/icecream_vat, +/turf/open/floor/plasteel/freezer, +/area/survivalpod/nonpowered) +"mv" = ( +/obj/structure/chair/comfy/black{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/survivalpod/nonpowered) +"no" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel/freezer, +/area/survivalpod/nonpowered) +"oW" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/freezer, +/area/survivalpod/nonpowered) +"ru" = ( +/obj/structure/flora/ausbushes/ppflowers, +/turf/open/floor/grass, +/area/survivalpod/nonpowered) +"tg" = ( +/obj/structure/closet/secure_closet/hydroponics{ + req_access = null + }, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/grass, +/area/survivalpod/nonpowered) +"ue" = ( +/obj/machinery/hydroponics/constructable/automagic, +/turf/open/floor/grass, +/area/survivalpod/nonpowered) +"uk" = ( +/obj/structure/table/plasmaglass, +/obj/machinery/plantgenes, +/turf/open/floor/grass, +/area/survivalpod/nonpowered) +"uC" = ( +/obj/machinery/vending/boozeomat, +/turf/open/floor/pod/dark, +/area/survivalpod/nonpowered) +"vb" = ( +/turf/closed/wall/mineral/titanium/survival, +/area/survivalpod/nonpowered) +"wB" = ( +/obj/structure/chair/comfy/black{ + dir = 8 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/survivalpod/nonpowered) +"zq" = ( +/obj/structure/table/reinforced, +/obj/item/storage/box/beakers/bluespace, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"AN" = ( +/turf/open/floor/plasteel/freezer, +/area/survivalpod/nonpowered) +"AO" = ( +/obj/item/reagent_containers/food/snacks/soup/wingfangchu, +/obj/structure/table/bronze, +/turf/open/floor/pod/dark, +/area/survivalpod/nonpowered) +"AW" = ( +/obj/machinery/grill, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"Bk" = ( +/obj/structure/flora/ausbushes/lavendergrass, +/turf/open/floor/grass, +/area/survivalpod/nonpowered) +"Ci" = ( +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/survivalpod/nonpowered) +"Cq" = ( +/turf/open/floor/glass/reinforced, +/area/survivalpod/nonpowered) +"CP" = ( +/obj/machinery/light, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/pod/dark, +/area/survivalpod/nonpowered) +"DU" = ( +/obj/machinery/door/airlock/survival_pod, +/obj/machinery/poweredfans, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/pod/dark, +/area/survivalpod/nonpowered) +"ET" = ( +/obj/structure/cable{ + icon_state = "1-6" + }, +/turf/open/floor/plasteel/freezer, +/area/survivalpod/nonpowered) +"Gc" = ( +/obj/structure/table/reinforced, +/obj/machinery/microwave, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"Gn" = ( +/obj/structure/window/shuttle/survival_pod, +/obj/machinery/poweredfans, +/turf/open/floor/pod/dark, +/area/survivalpod/nonpowered) +"Gt" = ( +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/machinery/airalarm/directional/east, +/turf/open/floor/plasteel/freezer, +/area/survivalpod/nonpowered) +"HZ" = ( +/obj/structure/kitchenspike, +/turf/open/floor/plasteel/freezer, +/area/survivalpod/nonpowered) +"JL" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel/freezer, +/area/survivalpod/nonpowered) +"JP" = ( +/obj/structure/flora/ausbushes/brflowers, +/turf/open/floor/grass, +/area/survivalpod/nonpowered) +"Kp" = ( +/obj/machinery/vending/hydroseeds, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/grass, +/area/survivalpod/nonpowered) +"KL" = ( +/obj/structure/table/reinforced, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"LV" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/machinery/computer/arcade/orion_trail{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/survivalpod/nonpowered) +"Ma" = ( +/obj/structure/table/reinforced, +/obj/machinery/airalarm/directional/east, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"MX" = ( +/obj/machinery/computer/arcade/battle{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/survivalpod/nonpowered) +"Nl" = ( +/obj/structure/table/wood/fancy/black, +/turf/open/floor/festive/wooden/wooden2, +/area/survivalpod/nonpowered) +"Oi" = ( +/obj/structure/flora/ausbushes/ywflowers, +/turf/open/floor/grass, +/area/survivalpod/nonpowered) +"Oq" = ( +/obj/machinery/hydroponics/constructable/automagic, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/grass, +/area/survivalpod/nonpowered) +"OV" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/pod/dark, +/area/survivalpod/nonpowered) +"Pi" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/pod/dark, +/area/survivalpod/nonpowered) +"Pw" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/sink/kitchen{ + dir = 4; + pixel_x = -11 + }, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"Qv" = ( +/obj/structure/table/reinforced, +/obj/machinery/chem_dispenser/drinks/beer/fullupgrade, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"QY" = ( +/obj/machinery/smartfridge/food, +/turf/open/floor/pod/dark, +/area/survivalpod/nonpowered) +"Ss" = ( +/obj/machinery/telecomms/relay/preset/station, +/obj/item/multitool, +/turf/open/floor/festive/wooden/wooden2, +/area/survivalpod/nonpowered) +"Tl" = ( +/obj/machinery/door/airlock/survival_pod, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/mineral/plastitanium, +/area/survivalpod/nonpowered) +"Tv" = ( +/obj/structure/table/reinforced, +/obj/item/storage/bag/tray/bluespace, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"TA" = ( +/obj/structure/table/reinforced, +/obj/machinery/chem_dispenser/drinks/fullupgrade, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"Ue" = ( +/obj/machinery/door/airlock/survival_pod, +/obj/machinery/poweredfans, +/turf/open/floor/pod/dark, +/area/survivalpod/nonpowered) +"Uv" = ( +/obj/machinery/vending/hydronutrients, +/turf/open/floor/grass, +/area/survivalpod/nonpowered) +"UK" = ( +/obj/structure/rack, +/obj/item/storage/box/ingredients/wildcard, +/obj/item/storage/box/ingredients/wildcard, +/obj/item/storage/box/ingredients/wildcard, +/obj/item/storage/box/ingredients/vegetarian, +/obj/item/storage/box/ingredients/exotic, +/obj/item/storage/box/ingredients/delights, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel/freezer, +/area/survivalpod/nonpowered) +"UW" = ( +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"Vt" = ( +/obj/machinery/biogenerator, +/turf/open/floor/pod/dark, +/area/survivalpod/nonpowered) +"VM" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/autolathe, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"We" = ( +/obj/structure/table/bronze, +/turf/open/floor/pod/dark, +/area/survivalpod/nonpowered) +"WU" = ( +/turf/open/floor/festive/wooden/wooden2, +/area/survivalpod/nonpowered) +"XT" = ( +/obj/item/book/manual/chef_recipes, +/obj/item/book/manual/wiki/cooking_to_serve_man{ + pixel_x = 4; + pixel_y = 3 + }, +/obj/structure/table/reinforced, +/turf/open/floor/mineral/titanium/white, +/area/survivalpod/nonpowered) +"Ys" = ( +/turf/open/floor/grass, +/area/survivalpod/nonpowered) +"ZU" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/festive/wooden/wooden2, +/area/survivalpod/nonpowered) + +(1,1,1) = {" +vb +Gn +Gn +Gn +Gn +vb +Ue +vb +Gn +Gn +Gn +Gn +vb +"} +(2,1,1) = {" +Gn +mv +WU +Ss +MX +LV +OV +Oq +ue +ue +ue +ue +Gn +"} +(3,1,1) = {" +Gn +Nl +Cq +Cq +Cq +WU +OV +Ys +Ys +Ys +Ys +cA +Gn +"} +(4,1,1) = {" +Gn +wB +Cq +Cq +Cq +WU +OV +ru +Ys +JP +Ys +uk +Gn +"} +(5,1,1) = {" +Gn +ZU +eP +eP +eP +WU +OV +Ys +Ys +hv +Ys +iB +Gn +"} +(6,1,1) = {" +vb +vb +We +We +AO +uC +OV +Bk +ru +Ys +Oi +Bk +Gn +"} +(7,1,1) = {" +gO +Pw +bn +bn +bn +bn +Pi +tg +Ys +Ys +Uv +Kp +vb +"} +(8,1,1) = {" +vb +AW +UW +XT +Tv +UW +CP +vb +QY +Vt +vb +vb +vb +"} +(9,1,1) = {" +vb +cp +UW +Gc +zq +UW +eS +Tl +ET +AN +UK +HZ +vb +"} +(10,1,1) = {" +vb +hM +UW +KL +KL +UW +OV +vb +kX +fM +AN +HZ +vb +"} +(11,1,1) = {" +vb +Qv +UW +UW +UW +UW +OV +vb +ei +no +oW +JL +vb +"} +(12,1,1) = {" +vb +TA +Ma +VM +iU +dV +CP +vb +Ci +Gt +by +by +vb +"} +(13,1,1) = {" +vb +vb +vb +vb +vb +vb +DU +vb +vb +vb +vb +vb +vb +"} diff --git a/auxmos.dll b/auxmos.dll index 54fb0c6c98..2836acdcf0 100644 Binary files a/auxmos.dll and b/auxmos.dll differ diff --git a/auxmos.pdb b/auxmos.pdb index 031e66d103..a04c133c01 100644 Binary files a/auxmos.pdb and b/auxmos.pdb differ diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index cf98755a36..a057d3cf41 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -80,7 +80,7 @@ //DNA - Because fuck you and your magic numbers being all over the codebase. #define DNA_BLOCK_SIZE 3 -#define DNA_UNI_IDENTITY_BLOCKS 15 +#define DNA_UNI_IDENTITY_BLOCKS 19 #define DNA_HAIR_COLOR_BLOCK 1 #define DNA_FACIAL_HAIR_COLOR_BLOCK 2 #define DNA_SKIN_TONE_BLOCK 3 @@ -96,6 +96,10 @@ #define DNA_MUTANTEAR_BLOCK 13 #define DNA_MUTANTMARKING_BLOCK 14 #define DNA_TAUR_BLOCK 15 +#define DNA_BARK_SOUND_BLOCK 16 +#define DNA_BARK_SPEED_BLOCK 17 +#define DNA_BARK_PITCH_BLOCK 18 +#define DNA_BARK_VARIANCE_BLOCK 19 #define DNA_SEQUENCE_LENGTH 4 #define DNA_MUTATION_BLOCKS 8 @@ -179,10 +183,11 @@ #define ORGAN_SLOT_VAGINA "vagina" #define ORGAN_SLOT_TESTICLES "testicles" #define ORGAN_SLOT_BREASTS "breasts" +#define ORGAN_SLOT_BUTT "butt" ////organ defines #define STANDARD_ORGAN_THRESHOLD 100 -#define STANDARD_ORGAN_HEALING (1/(15 MINUTES / (2 SECONDS))) +#define STANDARD_ORGAN_HEALING (1/(15 MINUTES / (2 SECONDS))) / 3 //Base organ healing can be amped by a factor of up to x5 via satiety. This assumes it to be somewhat in the upper center of positive satiety as base. #define STANDARD_ORGAN_DECAY (1/(15 MINUTES / (2 SECONDS))) //designed to fail organs when left to decay for ~15 minutes. 2 SECOND is SSmobs tickrate. @@ -195,3 +200,8 @@ #define G_FEMALE 2 #define G_PLURAL 3 #define G_NEUTER 4 + +#define PREVIEW_PREF_JOB "Job" +#define PREVIEW_PREF_LOADOUT "Loadout" +#define PREVIEW_PREF_NAKED "Naked" +#define PREVIEW_PREF_NAKED_AROUSED "Naked - Aroused" diff --git a/code/__DEFINES/_auxtools.dm b/code/__DEFINES/_auxtools.dm index ab07becbd9..fc5dfd4378 100644 --- a/code/__DEFINES/_auxtools.dm +++ b/code/__DEFINES/_auxtools.dm @@ -1,9 +1,12 @@ #define AUXMOS (world.system_type == MS_WINDOWS ? "auxmos.dll" : __detect_auxmos()) /proc/__detect_auxmos() - if (fexists("./libauxmos.so")) - return "./libauxmos.so" - else if (fexists("[world.GetConfig("env", "HOME")]/.byond/bin/libauxmos.so")) - return "[world.GetConfig("env", "HOME")]/.byond/bin/libauxmos.so" - else - CRASH("Could not find libauxmos.so") + var/static/known_auxmos_var + if(!known_auxmos_var) + if (fexists("./libauxmos.so")) + known_auxmos_var = "./libauxmos.so" + else if (fexists("[world.GetConfig("env", "HOME")]/.byond/bin/libauxmos.so")) + known_auxmos_var = "[world.GetConfig("env", "HOME")]/.byond/bin/libauxmos.so" + else + CRASH("Could not find libauxmos.so") + return known_auxmos_var diff --git a/code/__DEFINES/_flags/_flags.dm b/code/__DEFINES/_flags/_flags.dm index 6f8ea6cda7..cd38c9ad5b 100644 --- a/code/__DEFINES/_flags/_flags.dm +++ b/code/__DEFINES/_flags/_flags.dm @@ -5,10 +5,6 @@ #define NONE 0 //for convenience -#define ENABLE_BITFIELD(variable, flag) (variable |= (flag)) -#define DISABLE_BITFIELD(variable, flag) (variable &= ~(flag)) -#define CHECK_BITFIELD(variable, flag) (variable & (flag)) -#define TOGGLE_BITFIELD(variable, flag) (variable ^= (flag)) #define COPY_SPECIFIC_BITFIELDS(a,b,flags)\ do{\ var/_old = a & ~(flags);\ @@ -41,6 +37,8 @@ GLOBAL_LIST_INIT(bitflags, list( #define OVERLAY_QUEUED_1 (1<<8) ///Item has priority to check when entering or leaving. #define ON_BORDER_1 (1<<9) +///Whether or not this atom shows screentips when hovered over +#define NO_SCREENTIPS_1 (1<<10) ///Prevent clicking things below it on the same turf eg. doors/ fulltile windows. #define PREVENT_CLICK_UNDER_1 (1<<11) #define HOLOGRAM_1 (1<<12) @@ -66,6 +64,8 @@ GLOBAL_LIST_INIT(bitflags, list( #define NO_RUINS_1 (1<<10) /// Should this tile be cleaned up and reinserted into an excited group? #define EXCITED_CLEANUP_1 (1 << 13) +/// Whether or not this atom has contextual screentips when hovered OVER +#define HAS_CONTEXTUAL_SCREENTIPS_1 (1 << 14) ////////////////Area flags\\\\\\\\\\\\\\ /// If it's a valid territory for cult summoning or the CRAB-17 phone to spawn @@ -108,15 +108,18 @@ GLOBAL_LIST_INIT(bitflags, list( #define PASSBLOB (1<<3) #define PASSMOB (1<<4) #define PASSCLOSEDTURF (1<<5) +/// Let thrown things past us. **ONLY MEANINGFUL ON pass_flags_self!** #define LETPASSTHROW (1<<6) +#define PASSMACHINE (1<<7) +#define PASSSTRUCTURE (1<<8) //Movement Types #define GROUND (1<<0) #define FLYING (1<<1) #define VENTCRAWLING (1<<2) #define FLOATING (1<<3) -///When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped. -#define UNSTOPPABLE (1<<4) +///When moving, will Bump()/Cross()/Uncross() everything, but won't stop or Bump() anything. +#define PHASING (1<<4) ///Applied if you're crawling around on the ground/resting. #define CRAWLING (1<<5) @@ -154,7 +157,7 @@ GLOBAL_LIST_INIT(bitflags, list( //Mob mobility var flags /// any flag -#define CHECK_MOBILITY(target, flags) CHECK_BITFIELD(target.mobility_flags, flags) +#define CHECK_MOBILITY(target, flags) (target.mobility_flags & flags) #define CHECK_ALL_MOBILITY(target, flags) CHECK_MULTIPLE_BITFIELDS(target.mobility_flags, flags) /// can move diff --git a/code/__DEFINES/_flags/do_after.dm b/code/__DEFINES/_flags/do_after.dm index 26802736cf..1661d60271 100644 --- a/code/__DEFINES/_flags/do_after.dm +++ b/code/__DEFINES/_flags/do_after.dm @@ -1,32 +1,11 @@ -/// Requires absolute stillness from the user -#define DO_AFTER_DISALLOW_MOVING_ABSOLUTE_USER (1<<0) -/// Requires absolute stillness from the target -#define DO_AFTER_DISALLOW_MOVING_ABSOLUTE_TARGET (1<<1) -/// Requires that the user is on a turf. -#define DO_AFTER_REQUIRES_USER_ON_TURF (1<<2) -/// Requires relative stillness to our target via dx and dy coordinate difference but only if both are spacedrifting. Specify DO_AFTER_ALLOW_NONSPACEDRIFT_RELATIVITY to say otherwise. -#define DO_AFTER_DISALLOW_MOVING_RELATIVE (1<<3) -/// Breaks if active hand item changes. Requires a tool be specified, otherwise defaults to active item -#define DO_AFTER_DISALLOW_ACTIVE_ITEM_CHANGE (1<<4) -/// Breaks if the user has no free hands. If a tool is specified, allows that as well. -#define DO_AFTER_REQUIRE_FREE_HAND_OR_TOOL (1<<5) -/// Do not display progressbar. -#define DO_AFTER_NO_PROGRESSBAR (1<<6) -/// Do not check do_after_coefficient() -#define DO_AFTER_NO_COEFFICIENT (1<<7) -/// For relative stillness, allow non spacedrift relative movement -#define DO_AFTER_ALLOW_NONSPACEDRIFT_RELATIVITY (1<<8) - -/// Ignores checks. -#define DO_AFTER_PROCEED "PROCEED" -/// Uses all other checks -#define DO_AFTER_CONTINUE "CONTINUE" -/// Breaks -#define DO_AFTER_STOP "STOP" - -/// Stage - initiating a do_after -#define DO_AFTER_STARTING 1 -/// Stage - main loop of a do_after -#define DO_AFTER_PROGRESSING 2 -/// Stage - Last check of a do_after -#define DO_AFTER_FINISHING 3 +// timed_action_flags parameter for `/proc/do_after` +/// Can do the action even if target is not added to doafters +#define IGNORE_TARGET_IN_DOAFTERS (1<<0) +/// Can do the action even if mob moves location +#define IGNORE_USER_LOC_CHANGE (1<<1) +/// Can do the action even if the target moves location +#define IGNORE_TARGET_LOC_CHANGE (1<<2) +/// Can do the action even if the item is no longer being held +#define IGNORE_HELD_ITEM (1<<3) +/// Can do the action even if the mob is incapacitated (ex. handcuffed) +#define IGNORE_INCAPACITATED (1<<4) diff --git a/code/__DEFINES/_flags/item_flags.dm b/code/__DEFINES/_flags/item_flags.dm index 529499127d..d28cb80bab 100644 --- a/code/__DEFINES/_flags/item_flags.dm +++ b/code/__DEFINES/_flags/item_flags.dm @@ -51,4 +51,4 @@ #define ORGAN_NO_SPOIL (1<<5) //Do not spoil under any circumstances #define ORGAN_NO_DISMEMBERMENT (1<<6) //Immune to disembowelment. #define ORGAN_EDIBLE (1<<7) //is a snack? :D -#define ORGAN_SYNTHETIC_EMP (1<<6) //Synthetic organ affected by an EMP. Deteriorates over time. +#define ORGAN_SYNTHETIC_EMP (1<<8) //Synthetic organ affected by an EMP. Deteriorates over time. diff --git a/code/__DEFINES/_flags/obj_flags.dm b/code/__DEFINES/_flags/obj_flags.dm index e48146a1d0..c3c48c7d74 100644 --- a/code/__DEFINES/_flags/obj_flags.dm +++ b/code/__DEFINES/_flags/obj_flags.dm @@ -15,6 +15,10 @@ #define BLOCK_Z_IN_UP (1<<12) // Should this object block z uprise from below? #define SHOVABLE_ONTO (1<<13)//called on turf.shove_act() to consider whether an object should have a niche effect (defined in their own shove_act()) when someone is pushed onto it, or do a sanity CanPass() check. #define EXAMINE_SKIP (1<<14) /// Makes the Examine proc not read out this item. +#define IN_STORAGE (1<<15) //is this item in the storage item, such as backpack? used for tooltips +#define HAND_ITEM (1<<16) // If an item is just your hand (circled hand, slapper) and shouldn't block things like riding +/// Has contextual screentips when HOVERING OVER OTHER objects +#define ITEM_HAS_CONTEXTUAL_SCREENTIPS (1 << 17) /// Integrity defines for clothing (not flags but close enough) #define CLOTHING_PRISTINE 0 // We have no damage on the clothing diff --git a/code/__DEFINES/achievements.dm b/code/__DEFINES/achievements.dm index c39531971c..0cbba32b96 100644 --- a/code/__DEFINES/achievements.dm +++ b/code/__DEFINES/achievements.dm @@ -32,6 +32,10 @@ #define MEDAL_VOID_ASCENSION "Void" #define MEDAL_TOOLBOX_SOUL "Toolsoul" #define MEDAL_CHEM_TUT "Beginner Chemist" +#define MEDAL_HOT_DAMN "Hot Damn!" +#define MEDAL_CAYENNE_DISK "Very Important Piscis" +#define MEDAL_TRAM_SURFER "Tram Surfer" +#define MEDAL_SPRINGLOCK "The Man Inside the Modsuit" //Skill medal hub IDs #define MEDAL_LEGENDARY_MINER "Legendary Miner" @@ -106,3 +110,19 @@ // DB ID for amount of consumed maintenance pills #define MAINTENANCE_PILL_SCORE "Maintenance Pill Score" + +// DB ID for intento score +#define INTENTO_SCORE "Intento Score" + +// Tourist related achievements and scores + +//centcom grades (achievement) + +#define MEDAL_BAD_SERVICE "Bad Service" +#define MEDAL_OKAY_SERVICE "Okay Service" +#define MEDAL_GOOD_SERVICE "Good Service" + +//scores + +#define CHEF_TOURISTS_SERVED "Tourists Served As Chef" +#define BARTENDER_TOURISTS_SERVED "Tourists Served As Bartender" diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index bd6e549d15..c58e111f26 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -57,6 +57,10 @@ #define ADMIN_SET_SD_CODE "(SETCODE)" #define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)] [ADMIN_INDIVIDUALLOG(user)] [ADMIN_SMITE(user)]" #define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]" +//ambition start +#define ADMIN_TPMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_JMP(user)] [ADMIN_FLW(user)]" +#define ADMIN_TPMONTY(user) "[key_name_admin(user)] [ADMIN_TPMONTY_NONAME(user)]" +//ambition end #define ADMIN_JMP(src) "(JMP)" #define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]" #define AREACOORD(src) "[src ? "[get_area_name(src, TRUE)] ([src.x], [src.y], [src.z])" : "nonexistent location"]" @@ -95,3 +99,6 @@ #define STICKYBAN_DB_CACHE_TIME 10 SECONDS #define STICKYBAN_ROGUE_CHECK_TIME 5 + +/// for asay pings, this is the index in the return list for [/proc/check_admin_pings] that contains the message modified with underlines for the spotted names +#define ADMINSAY_PING_UNDERLINE_NAME_INDEX "!underlined_names" diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index 9a778aafc7..00751f2cab 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -111,3 +111,21 @@ GLOBAL_LIST_EMPTY(living_heart_cache) //A list of all living hearts in existance #define BLOB_SPREAD_COST 4 #define BLOB_ATTACK_REFUND 2 //blob refunds this much if it attacks and doesn't spread #define BLOB_REFLECTOR_COST 15 + +/// How many telecrystals a normal traitor starts with +#define TELECRYSTALS_DEFAULT 20 +/// How many telecrystals mapper/admin only "precharged" uplink implant +#define TELECRYSTALS_PRELOADED_IMPLANT 10 +/// The normal cost of an uplink implant; used for calcuating how many +/// TC to charge someone if they get a free implant through choice or +/// because they have nothing else that supports an implant. +#define UPLINK_IMPLANT_TELECRYSTAL_COST 4 + +/// The dimensions of the antagonist preview icon. Will be scaled to this size. +#define ANTAGONIST_PREVIEW_ICON_SIZE 96 + +//Objectives-Ambitions Panel +#define REQUEST_NEW_OBJECTIVE "new_objective" +#define REQUEST_DEL_OBJECTIVE "del_objective" +#define REQUEST_WIN_OBJECTIVE "win_objective" +#define REQUEST_LOSE_OBJECTIVE "lose_objective" diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index 67d16e6687..c585a822ea 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -68,6 +68,21 @@ #define TEMPERATURE_DAMAGE_COEFFICIENT 1.5 //This is used in handle_temperature_damage() for humans, and in reagents that affect body temperature. Temperature damage is multiplied by this amount. +#define SYNTH_PASSIVE_HEAT_GAIN 10 //Degrees C per handle_environment() Synths passively heat up. Mitigated by cooling efficiency. Can lead to overheating if not managed. +#define SYNTH_MAX_PASSIVE_GAIN_TEMP 250 //Degrees C that a synth can be heated up to by their internal heat gain, provided their cooling is insufficient to mitigate it. +#define SYNTH_MIN_PASSIVE_COOLING_TEMP -30 //Degrees C a synth can cool towards at very high cooling efficiency. +#define SYNTH_HEAT_EFFICIENCY_COEFF 0.005 //How quick the difference between the Synth and the environment starts to matter. The smaller the higher the difference has to be for the same change. +#define SYNTH_SINGLE_INFLUENCE_COOLING_EFFECT_CAP 3 //How big can the multiplier for heat / pressure cooling be in an optimal environment +#define SYNTH_TOTAL_ENVIRONMENT_EFFECT_CAP 2 //How big of an multiplier can the environment give in an optimal scenario (maximum efficiency in the end is at a lower cap, this mostly counters low coolant levels) +#define SYNTH_MAX_COOLING_EFFICIENCY 1.5 //The maximum possible cooling efficiency one can achieve at optimal conditions. +#define SYNTH_ACTIVE_COOLING_TEMP_BOUNDARY 10 //The minimum distance from room temperature a Synth needs to have for active cooling to actively cool. +#define SYNTH_ACTIVE_COOLING_LOW_PRESSURE_THRESHOLD 0.05 //At how much percentage of default pressure (or lower) active cooling gets a massive cost penalty. +#define SYNTH_ACTIVE_COOLING_LOW_PRESSURE_PENALTY 2.5 //By how much is active cooling cost multiplied if in a very-low-pressure environment? +#define SYNTH_ACTIVE_COOLING_MIN_ADJUSTMENT 5 //What is the minimum amount of temp you move towards the target point, even if it would be less with default calculations? +#define SYNTH_INTEGRATION_COOLANT_PENALTY 0.4 //Integrating coolant is multiplied with this for calculation of impact on passive cooling. +#define SYNTH_INTEGRATION_COOLANT_CAP 0.25 //Integrating coolant is capped at counting as current_blood * this number. This is so you can't just run on salglu or whatever. +#define SYNTH_COLD_OFFSET -125 //How much colder temps Synths can tolerate. Used in their species. + #define BODYTEMP_NORMAL 310.15 //The natural temperature for a body #define BODYTEMP_AUTORECOVERY_DIVISOR 11 //This is the divisor which handles how much of the temperature difference between the current body temperature and 310.15K (optimal temperature) humans auto-regenerate each tick. The higher the number, the slower the recovery. This is applied each tick, so long as the mob is alive. #define BODYTEMP_AUTORECOVERY_MINIMUM 12 //Minimum amount of kelvin moved toward 310K per tick. So long as abs(310.15 - bodytemp) is more than 50. @@ -101,6 +116,7 @@ #define GLOVES_MAX_TEMP_PROTECT 1500 //For some gloves #define SHOES_MIN_TEMP_PROTECT 2.0 //For gloves #define SHOES_MAX_TEMP_PROTECT 1500 //For gloves +#define COAT_MAX_TEMP_PROTECT 330 //For winter coats (if they can stop you from getting cold why can't they do it the other way to a lesser extent) #define PRESSURE_DAMAGE_COEFFICIENT 4 //The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE #define MAX_HIGH_PRESSURE_DAMAGE 16 // CITADEL CHANGES Max to 16, low to 8. @@ -128,6 +144,7 @@ #define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3) #define TANK_MIN_RELEASE_PRESSURE 0 #define TANK_DEFAULT_RELEASE_PRESSURE 17 +#define TANK_POST_FRAGMENT_REACTIONS 5 //CANATMOSPASS #define ATMOS_PASS_YES 1 @@ -135,6 +152,10 @@ #define ATMOS_PASS_PROC -1 //ask CanAtmosPass() #define ATMOS_PASS_DENSITY -2 //just check density +// Adjacency flags +#define ATMOS_ADJACENT_ANY (1<<0) +#define ATMOS_ADJACENT_FIRELOCK (1<<1) + #define CANATMOSPASS(A, O) ( A.CanAtmosPass == ATMOS_PASS_PROC ? A.CanAtmosPass(O) : ( A.CanAtmosPass == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPass ) ) #define CANVERTICALATMOSPASS(A, O) ( A.CanAtmosPassVertical == ATMOS_PASS_PROC ? A.CanAtmosPass(O, TRUE) : ( A.CanAtmosPassVertical == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPassVertical ) ) @@ -155,10 +176,13 @@ //LAVALAND #define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland -#define LAVALAND_DEFAULT_ATMOS "o2=14;n2=23;TEMP=300" +#define LAVALAND_DEFAULT_ATMOS "LAVALAND_ATMOS" //SNOSTATION -#define ICEMOON_DEFAULT_ATMOS "o2=17;n2=63;TEMP=180" +#define ICEMOON_DEFAULT_ATMOS "ICEMOON_ATMOS" + +//FESTIVESTATION +#define FESTIVE_ATMOS "o2=22;n2=82;TEMP=266" //this goes here right putnam?? //ATMOSIA GAS MONITOR TAGS #define ATMOS_GAS_MONITOR_INPUT_O2 "o2_in" @@ -255,8 +279,10 @@ #define GAS_PLASMA "plasma" #define GAS_H2O "water_vapor" #define GAS_HYPERNOB "nob" +#define GAS_NITRIC "no" #define GAS_NITROUS "n2o" #define GAS_NITRYL "no2" +#define GAS_HYDROGEN "hydrogen" #define GAS_TRITIUM "tritium" #define GAS_BZ "bz" #define GAS_STIMULUM "stim" @@ -264,9 +290,17 @@ #define GAS_MIASMA "miasma" #define GAS_METHANE "methane" #define GAS_METHYL_BROMIDE "methyl_bromide" +#define GAS_BROMINE "bromine" +#define GAS_AMMONIA "ammonia" +#define GAS_FLUORINE "fluorine" +#define GAS_ETHANOL "ethanol" +#define GAS_QCD "qcd" + +#define GAS_GROUP_CHEMICALS "Chemicals" #define GAS_FLAG_DANGEROUS (1<<0) #define GAS_FLAG_BREATH_PROC (1<<1) +#define GAS_FLAG_CHEMICAL (1<<2) //SUPERMATTER DEFINES #define HEAT_PENALTY "heat penalties" @@ -293,14 +327,6 @@ #define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */ - -#ifdef TESTING -GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0)) -#define CALCULATE_ADJACENT_TURFS(T) if (SSadjacent_air.queue[T]) { GLOB.atmos_adjacent_savings[1] += 1 } else { GLOB.atmos_adjacent_savings[2] += 1; SSadjacent_air.queue[T] = 1 } -#else -#define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1 -#endif - //If you're doing spreading things related to atmos, DO NOT USE CANATMOSPASS, IT IS NOT CHEAP. use this instead, the info is cached after all. it's tweaked just a bit to allow for circular checks #define TURFS_CAN_SHARE(T1, T2) (LAZYACCESS(T2.atmos_adjacent_turfs, T1) || LAZYLEN(T1.atmos_adjacent_turfs & T2.atmos_adjacent_turfs)) diff --git a/code/__DEFINES/bitfields.dm b/code/__DEFINES/bitfields.dm new file mode 100644 index 0000000000..19a962fbff --- /dev/null +++ b/code/__DEFINES/bitfields.dm @@ -0,0 +1,4 @@ +#define DEFINE_BITFIELD(_variable, _flags) /datum/bitfield/##_variable { \ + flags = ##_flags; \ + variable = #_variable; \ +} diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm index 04eeb515c9..fa11db38aa 100644 --- a/code/__DEFINES/citadel_defines.dm +++ b/code/__DEFINES/citadel_defines.dm @@ -6,12 +6,13 @@ #define CIT_FILTER_STAMINACRIT filter(type="drop_shadow", x=0, y=0, size=-3, color="#04080F") //organ defines -#define VAGINA_LAYER_INDEX 1 -#define TESTICLES_LAYER_INDEX 2 -#define GENITAL_LAYER_INDEX 3 -#define PENIS_LAYER_INDEX 4 +#define BUTT_LAYER_INDEX 1 +#define VAGINA_LAYER_INDEX 2 +#define TESTICLES_LAYER_INDEX 3 +#define GENITAL_LAYER_INDEX 4 +#define PENIS_LAYER_INDEX 5 -#define GENITAL_LAYER_INDEX_LENGTH 4 //keep it updated with each new index added, thanks. +#define GENITAL_LAYER_INDEX_LENGTH 5 //keep it updated with each new index added, thanks. //genital flags #define GENITAL_BLACKLISTED (1<<0) //for genitals that shouldn't be added to GLOB.genitals_list. @@ -62,6 +63,9 @@ #define MILK_RATE_MULT 1 #define MILK_EFFICIENCY 1 +#define BUTT_SIZE_DEF 1 +#define BUTT_SIZE_MAX 5 //butt genitals are special in that they have caps. if there's the event there's even bigger butt sprites, raise this number. + //visibility toggles defines to avoid errors typos code errors. #define GEN_VISIBLE_ALWAYS "Always visible" #define GEN_VISIBLE_NO_CLOTHES "Hidden by clothes" @@ -102,6 +106,8 @@ #define GENITAL_EXAMINE (1<<13) #define VORE_EXAMINE (1<<14) #define TRASH_FORCEFEED (1<<15) +#define BUTT_ENLARGEMENT (1<<16) +//Note: reminder, if you're a coder adding more bitflags here in the event we add more horny things, the maximum is (1<<23). #define TOGGLES_CITADEL 0 //belly sound pref things diff --git a/code/__DEFINES/clockcult.dm b/code/__DEFINES/clockcult.dm index dbca36aab4..1a684c7040 100644 --- a/code/__DEFINES/clockcult.dm +++ b/code/__DEFINES/clockcult.dm @@ -17,6 +17,7 @@ GLOBAL_LIST_EMPTY(all_clockwork_mobs) //All clockwork SERVANTS (not creatures) i GLOBAL_VAR_INIT(ratvar_approaches, 0) //The servants can choose to "herald" Ratvar, permanently buffing them but announcing their presence to the crew. GLOBAL_VAR_INIT(ratvar_awakens, 0) //If Ratvar has been summoned; not a boolean, for proper handling of multiple Ratvars GLOBAL_VAR_INIT(ark_of_the_clockwork_justiciar, FALSE) //The Ark on the Reebe z-level +GLOBAL_VAR_INIT(reebe_loaded, FALSE) //Is reebe loaded right now? If two seperate things in one round try loading reebe. GLOBAL_VAR_INIT(clockwork_gateway_activated, FALSE) //if a gateway to the celestial derelict has ever been successfully activated GLOBAL_VAR_INIT(script_scripture_unlocked, FALSE) //If script scripture is available, through converting at least one crewmember diff --git a/code/__DEFINES/color/color_priority.dm b/code/__DEFINES/color/color_priority.dm new file mode 100644 index 0000000000..040ff5003a --- /dev/null +++ b/code/__DEFINES/color/color_priority.dm @@ -0,0 +1,6 @@ +//different types of atom colorations +#define ADMIN_COLOUR_PRIORITY 1 //only used by rare effects like greentext coloring mobs and when admins varedit color +#define TEMPORARY_COLOUR_PRIORITY 2 //e.g. purple effect of the revenant on a mob, black effect when mob electrocuted +#define WASHABLE_COLOUR_PRIORITY 3 //color splashed onto an atom (e.g. paint on turf) +#define FIXED_COLOUR_PRIORITY 4 //color inherent to the atom (e.g. blob color) +#define COLOUR_PRIORITY_AMOUNT 4 //how many priority levels there are. diff --git a/code/__DEFINES/color/colors.dm b/code/__DEFINES/color/colors.dm new file mode 100644 index 0000000000..664b8c0c0d --- /dev/null +++ b/code/__DEFINES/color/colors.dm @@ -0,0 +1,197 @@ +// This is eventually for wjohn to add more color standardization stuff like I keep asking him >:( + +#define COLOR_INPUT_DISABLED "#F0F0F0" +#define COLOR_INPUT_ENABLED "#D3B5B5" + +#define COLOR_DARKMODE_BACKGROUND "#202020" +#define COLOR_DARKMODE_DARKBACKGROUND "#171717" +#define COLOR_DARKMODE_TEXT "#a4bad6" + +#define COLOR_WHITE "#FFFFFF" +#define COLOR_VERY_LIGHT_GRAY "#EEEEEE" +#define COLOR_SILVER "#C0C0C0" +#define COLOR_GRAY "#808080" +#define COLOR_FLOORTILE_GRAY "#8D8B8B" +#define COLOR_DARK "#454545" +#define COLOR_ALMOST_BLACK "#333333" +#define COLOR_BLACK "#000000" +#define COLOR_HALF_TRANSPARENT_BLACK "#0000007A" + +#define COLOR_RED "#FF0000" +#define COLOR_MOSTLY_PURE_RED "#FF3300" +#define COLOR_DARK_RED "#A50824" +#define COLOR_RED_LIGHT "#FF3333" +#define COLOR_MAROON "#800000" +#define COLOR_VIVID_RED "#FF3232" +#define COLOR_LIGHT_GRAYISH_RED "#E4C7C5" +#define COLOR_SOFT_RED "#FA8282" +#define COLOR_BUBBLEGUM_RED "#950A0A" + +#define COLOR_YELLOW "#FFFF00" +#define COLOR_VIVID_YELLOW "#FBFF23" +#define COLOR_VERY_SOFT_YELLOW "#FAE48E" + +#define COLOR_OLIVE "#808000" +#define COLOR_VIBRANT_LIME "#00FF00" +#define COLOR_LIME "#32CD32" +#define COLOR_DARK_LIME "#00aa00" +#define COLOR_VERY_PALE_LIME_GREEN "#DDFFD3" +#define COLOR_VERY_DARK_LIME_GREEN "#003300" +#define COLOR_GREEN "#008000" +#define COLOR_DARK_MODERATE_LIME_GREEN "#44964A" + +#define COLOR_CYAN "#00FFFF" +#define COLOR_DARK_CYAN "#00A2FF" +#define COLOR_TEAL "#008080" +#define COLOR_BLUE "#0000FF" +#define COLOR_STRONG_BLUE "#1919c8" +#define COLOR_BRIGHT_BLUE "#2CB2E8" +#define COLOR_MODERATE_BLUE "#555CC2" +#define COLOR_AMETHYST "#822BFF" +#define COLOR_BLUE_LIGHT "#33CCFF" +#define COLOR_NAVY "#000080" +#define COLOR_BLUE_GRAY "#75A2BB" + +#define COLOR_PINK "#FFC0CB" +#define COLOR_LIGHT_PINK "#ff3cc8" +#define COLOR_MOSTLY_PURE_PINK "#E4005B" +#define COLOR_MAGENTA "#FF00FF" +#define COLOR_STRONG_MAGENTA "#B800B8" +#define COLOR_PURPLE "#800080" +#define COLOR_VIOLET "#B900F7" +#define COLOR_STRONG_VIOLET "#6927c5" + +#define COLOR_ORANGE "#FF9900" +#define COLOR_MOSTLY_PURE_ORANGE "#ff8000" +#define COLOR_TAN_ORANGE "#FF7B00" +#define COLOR_BRIGHT_ORANGE "#E2853D" +#define COLOR_LIGHT_ORANGE "#ffc44d" +#define COLOR_PALE_ORANGE "#FFBE9D" +#define COLOR_BEIGE "#CEB689" +#define COLOR_DARK_ORANGE "#C3630C" +#define COLOR_DARK_MODERATE_ORANGE "#8B633B" + +#define COLOR_BROWN "#BA9F6D" +#define COLOR_DARK_BROWN "#997C4F" +#define COLOR_ORANGE_BROWN "#a9734f" + +//Color defines used by the soapstone (based on readability against grey tiles) +#define COLOR_SOAPSTONE_PLASTIC "#a19d94" +#define COLOR_SOAPSTONE_IRON "#b2b2b2" +#define COLOR_SOAPSTONE_BRONZE "#FE8001" +#define COLOR_SOAPSTONE_SILVER "#FFFFFF" +#define COLOR_SOAPSTONE_GOLD "#FFD900" +#define COLOR_SOAPSTONE_DIAMOND "#00ffee" + +#define COLOR_GREEN_GRAY "#99BB76" +#define COLOR_RED_GRAY "#B4696A" +#define COLOR_PALE_BLUE_GRAY "#98C5DF" +#define COLOR_PALE_GREEN_GRAY "#B7D993" +#define COLOR_PALE_RED_GRAY "#D59998" +#define COLOR_PALE_PURPLE_GRAY "#CBB1CA" +#define COLOR_PURPLE_GRAY "#AE8CA8" + +//Color defines used by the assembly detailer. +#define COLOR_ASSEMBLY_BLACK "#545454" +#define COLOR_ASSEMBLY_BGRAY "#9497AB" +#define COLOR_ASSEMBLY_WHITE "#E2E2E2" +#define COLOR_ASSEMBLY_RED "#CC4242" +#define COLOR_ASSEMBLY_ORANGE "#E39751" +#define COLOR_ASSEMBLY_BEIGE "#AF9366" +#define COLOR_ASSEMBLY_BROWN "#97670E" +#define COLOR_ASSEMBLY_GOLD "#AA9100" +#define COLOR_ASSEMBLY_YELLOW "#CECA2B" +#define COLOR_ASSEMBLY_GURKHA "#999875" +#define COLOR_ASSEMBLY_LGREEN "#789876" +#define COLOR_ASSEMBLY_GREEN "#44843C" +#define COLOR_ASSEMBLY_LBLUE "#5D99BE" +#define COLOR_ASSEMBLY_BLUE "#38559E" +#define COLOR_ASSEMBLY_PURPLE "#6F6192" + +///Colors for xenobiology vatgrowing +#define COLOR_SAMPLE_YELLOW "#c0b823" +#define COLOR_SAMPLE_PURPLE "#342941" +#define COLOR_SAMPLE_GREEN "#98b944" +#define COLOR_SAMPLE_BROWN "#91542d" +#define COLOR_SAMPLE_GRAY "#5e5856" + +///Main colors for UI themes +#define COLOR_THEME_MIDNIGHT "#6086A0" +#define COLOR_THEME_PLASMAFIRE "#FFB200" +#define COLOR_THEME_RETRO "#24CA00" +#define COLOR_THEME_SLIMECORE "#4FB259" +#define COLOR_THEME_OPERATIVE "#B8221F" +#define COLOR_THEME_GLASS "#75A4C4" +#define COLOR_THEME_CLOCKWORK "#CFBA47" + +///Colors for eigenstates +#define COLOR_PERIWINKLEE "#9999FF" +/** + * Some defines to generalise colours used in lighting. + * + * Important note: colors can end up significantly different from the basic html picture, especially when saturated + */ +/// Bright but quickly dissipating neon green. rgb(100, 200, 100) +#define LIGHT_COLOR_GREEN "#64C864" +/// Electric green. rgb(0, 255, 0) +#define LIGHT_COLOR_ELECTRIC_GREEN "#00FF00" +/// Cold, diluted blue. rgb(100, 150, 250) +#define LIGHT_COLOR_BLUE "#6496FA" +/// Light blueish green. rgb(125, 225, 175) +#define LIGHT_COLOR_BLUEGREEN "#7DE1AF" +/// Diluted cyan. rgb(125, 225, 225) +#define LIGHT_COLOR_CYAN "#7DE1E1" +/// Electric cyan rgb(0, 255, 255) +#define LIGHT_COLOR_ELECTRIC_CYAN "#00FFFF" +/// More-saturated cyan. rgb(64, 206, 255) +#define LIGHT_COLOR_LIGHT_CYAN "#40CEFF" +/// Saturated blue. rgb(51, 117, 248) +#define LIGHT_COLOR_DARK_BLUE "#6496FA" +/// Diluted, mid-warmth pink. rgb(225, 125, 225) +#define LIGHT_COLOR_PINK "#E17DE1" +/// Dimmed yellow, leaning kaki. rgb(225, 225, 125) +#define LIGHT_COLOR_YELLOW "#E1E17D" +/// Clear brown, mostly dim. rgb(150, 100, 50) +#define LIGHT_COLOR_BROWN "#966432" +/// Mostly pure orange. rgb(250, 150, 50) +#define LIGHT_COLOR_ORANGE "#FA9632" +/// Light Purple. rgb(149, 44, 244) +#define LIGHT_COLOR_PURPLE "#952CF4" +/// Less-saturated light purple. rgb(155, 81, 255) +#define LIGHT_COLOR_LAVENDER "#9B51FF" +///slightly desaturated bright yellow. +#define LIGHT_COLOR_HOLY_MAGIC "#FFF743" +/// deep crimson +#define LIGHT_COLOR_BLOOD_MAGIC "#D00000" + +/* These ones aren't a direct colour like the ones above, because nothing would fit */ +/// Warm orange color, leaning strongly towards yellow. rgb(250, 160, 25) +#define LIGHT_COLOR_FIRE "#FAA019" +/// Very warm yellow, leaning slightly towards orange. rgb(196, 138, 24) +#define LIGHT_COLOR_LAVA "#C48A18" +/// Bright, non-saturated red. Leaning slightly towards pink for visibility. rgb(250, 100, 75) +#define LIGHT_COLOR_FLARE "#FA644B" +/// Weird color, between yellow and green, very slimy. rgb(175, 200, 75) +#define LIGHT_COLOR_SLIME_LAMP "#AFC84B" +/// Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175) +#define LIGHT_COLOR_TUNGSTEN "#FAE1AF" +/// Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250) +#define LIGHT_COLOR_HALOGEN "#F0FAFA" + +//The GAGS greyscale_colors for each department's computer/machine circuits +#define CIRCUIT_COLOR_GENERIC "#1A7A13" +#define CIRCUIT_COLOR_COMMAND "#1B4594" +#define CIRCUIT_COLOR_SECURITY "#9A151E" +#define CIRCUIT_COLOR_SCIENCE "#BC4A9B" +#define CIRCUIT_COLOR_SERVICE "#92DCBA" +#define CIRCUIT_COLOR_MEDICAL "#00CCFF" +#define CIRCUIT_COLOR_ENGINEERING "#F8D700" +#define CIRCUIT_COLOR_SUPPLY "#C47749" + +/// Colors for pride week +#define COLOR_PRIDE_RED "#FF6666" +#define COLOR_PRIDE_ORANGE "#FC9F3C" +#define COLOR_PRIDE_YELLOW "#EAFF51" +#define COLOR_PRIDE_GREEN "#41FC66" +#define COLOR_PRIDE_BLUE "#42FFF2" +#define COLOR_PRIDE_PURPLE "#5D5DFC" diff --git a/code/__DEFINES/color/lum.dm b/code/__DEFINES/color/lum.dm new file mode 100644 index 0000000000..942462b573 --- /dev/null +++ b/code/__DEFINES/color/lum.dm @@ -0,0 +1,4 @@ +//Luma coefficients suggested for HDTVs. If you change these, make sure they add up to 1. +#define LUMA_R 0.213 +#define LUMA_G 0.715 +#define LUMA_B 0.072 diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm deleted file mode 100644 index db78144689..0000000000 --- a/code/__DEFINES/colors.dm +++ /dev/null @@ -1,61 +0,0 @@ -// This is eventually for wjohn to add more color standardization stuff like I keep asking him >:( - -#define COLOR_INPUT_DISABLED "#F0F0F0" -#define COLOR_INPUT_ENABLED "#D3B5B5" -#define COLOR_FLOORTILE_GRAY "#8D8B8B" -#define COLOR_ALMOST_BLACK "#333333" -#define COLOR_BLACK "#000000" -#define COLOR_RED "#FF0000" -#define COLOR_RED_LIGHT "#FF3333" -#define COLOR_MAROON "#800000" -#define COLOR_YELLOW "#FFFF00" -#define COLOR_OLIVE "#808000" -#define COLOR_LIME "#32CD32" -#define COLOR_GREEN "#008000" -#define COLOR_CYAN "#00FFFF" -#define COLOR_TEAL "#008080" -#define COLOR_BLUE "#0000FF" -#define COLOR_BLUE_LIGHT "#33CCFF" -#define COLOR_NAVY "#000080" -#define COLOR_PINK "#FFC0CB" -#define COLOR_MAGENTA "#FF00FF" -#define COLOR_PURPLE "#800080" -#define COLOR_ORANGE "#FF9900" -#define COLOR_BEIGE "#CEB689" -#define COLOR_BLUE_GRAY "#75A2BB" -#define COLOR_BROWN "#BA9F6D" -#define COLOR_SOFT_RED "#FA8282" -#define COLOR_DARK_BROWN "#997C4F" -#define COLOR_DARK_ORANGE "#C3630C" -#define COLOR_GREEN_GRAY "#99BB76" -#define COLOR_RED_GRAY "#B4696A" -#define COLOR_PALE_BLUE_GRAY "#98C5DF" -#define COLOR_PALE_GREEN_GRAY "#B7D993" -#define COLOR_PALE_ORANGE "#FFC066" -#define COLOR_PALE_RED_GRAY "#D59998" -#define COLOR_PALE_PURPLE_GRAY "#CBB1CA" -#define COLOR_PURPLE_GRAY "#AE8CA8" - -// Color defines used by the assembly detailer. -#define COLOR_ASSEMBLY_BLACK "#545454" -#define COLOR_ASSEMBLY_BGRAY "#9497AB" -#define COLOR_ASSEMBLY_WHITE "#E2E2E2" -#define COLOR_ASSEMBLY_RED "#CC4242" -#define COLOR_ASSEMBLY_ORANGE "#E39751" -#define COLOR_ASSEMBLY_BEIGE "#AF9366" -#define COLOR_ASSEMBLY_BROWN "#97670E" -#define COLOR_ASSEMBLY_GOLD "#AA9100" -#define COLOR_ASSEMBLY_YELLOW "#CECA2B" -#define COLOR_ASSEMBLY_GURKHA "#999875" -#define COLOR_ASSEMBLY_LGREEN "#789876" -#define COLOR_ASSEMBLY_GREEN "#44843C" -#define COLOR_ASSEMBLY_LBLUE "#5D99BE" -#define COLOR_ASSEMBLY_BLUE "#38559E" -#define COLOR_ASSEMBLY_PURPLE "#6F6192" -#define COLOR_ASSEMBLY_PINK "#ff4adc" - -#define COLOR_WHITE "#FFFFFF" -#define COLOR_VERY_LIGHT_GRAY "#EEEEEE" -#define COLOR_SILVER "#C0C0C0" -#define COLOR_GRAY "#808080" -#define COLOR_HALF_TRANSPARENT_BLACK "#0000007A" diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index a6d411a8dd..6dae40ce07 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -206,6 +206,19 @@ ///Time to spend without clicking on other things required for your shots to become accurate. #define GUN_AIMING_TIME (2 SECONDS) +//Autofire component +/// Compatible firemode is in the gun. Wait until it's held in the user hands. +#define AUTOFIRE_STAT_IDLE (1<<0) +/// Gun is active and in the user hands. Wait until user does a valid click. +#define AUTOFIRE_STAT_ALERT (1<<1) +/// Gun is shooting. +#define AUTOFIRE_STAT_FIRING (1<<2) + +#define COMSIG_AUTOFIRE_ONMOUSEDOWN "autofire_onmousedown" + #define COMPONENT_AUTOFIRE_ONMOUSEDOWN_BYPASS (1<<0) +#define COMSIG_AUTOFIRE_SHOT "autofire_shot" + #define COMPONENT_AUTOFIRE_SHOT_SUCCESS (1<<0) + //Object/Item sharpness #define SHARP_NONE 0 #define SHARP_EDGED 1 @@ -261,3 +274,4 @@ * a "inefficiently" prefix will be added to the message. */ #define FEEBLE_ATTACK_MSG_THRESHOLD 0.5 + diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm index 9915563cab..8c9b270f43 100644 --- a/code/__DEFINES/configuration.dm +++ b/code/__DEFINES/configuration.dm @@ -24,3 +24,11 @@ #define POLICYCONFIG_ON_PYROCLASTIC_SENTIENT "PYROCLASTIC_SLIME" /// Displayed to pAIs on spawn #define POLICYCONFIG_PAI "PAI_SPAWN" +/// displayed to lavaland elites on spawn, overriding the default if set +#define POLICYCONFIG_ELITE_SPAWN "ELITE_FAUNA_SPAWN" +/// displayed to lavaland elites on sentience potion, overriding the default if set +#define POLICYCONFIG_ELITE_SENTIENCE "ELITE_FAUNA_SENTIENCE" +/// displayed to lavaland elites on winning the fight, overriding the default if set +#define POLICYCONFIG_ELITE_WIN "ELITE_FAUNA_WIN" +/// displayed to prisoners on spawn, overriding the default if set +#define POLICYCONFIG_JOB_PRISONER "JOB_PRISONER" diff --git a/code/__DEFINES/cooldowns.dm b/code/__DEFINES/cooldowns.dm index 29c7a25dad..39240ed7e5 100644 --- a/code/__DEFINES/cooldowns.dm +++ b/code/__DEFINES/cooldowns.dm @@ -27,6 +27,23 @@ //INDEXES #define COOLDOWN_EMPLOYMENT_CABINET "employment cabinet" +#define COOLDOWN_AMBITION "ambition" +#define COOLDOWN_OBJECTIVES "objectives" +#define COOLDOWN_OBJ_ADMIN_PING "obj_admin_ping" + + +//Mecha cooldowns +#define COOLDOWN_MECHA_MESSAGE "mecha_message" +#define COOLDOWN_MECHA_EQUIPMENT "mecha_equipment" +#define COOLDOWN_MECHA_ARMOR "mecha_armor" +#define COOLDOWN_MECHA_MELEE_ATTACK "mecha_melee" +#define COOLDOWN_MECHA_SMOKE "mecha_smoke" + +//car cooldowns +#define COOLDOWN_CAR_HONK "car_honk" + +//clown car cooldowns +#define COOLDOWN_CLOWNCAR_RANDOMNESS "clown_car_randomness" //TIMER COOLDOWN MACROS diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 3ab70126e3..4477c8aee8 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -21,10 +21,32 @@ #define COMSIG_GLOB_PLAY_CINEMATIC "!play_cinematic" #define COMPONENT_GLOB_BLOCK_CINEMATIC 1 +/// job subsystem has spawned and equipped a new mob +#define COMSIG_GLOB_JOB_AFTER_SPAWN "!job_after_spawn" + +/// job datum has been called to deal with the aftermath of a latejoin spawn +#define COMSIG_GLOB_JOB_AFTER_LATEJOIN_SPAWN "!job_after_latejoin_spawn" + +#define COMSIG_GLOB_PRE_RANDOM_EVENT "!pre_random_event" + /// Do not allow this random event to continue. + #define CANCEL_PRE_RANDOM_EVENT (1<<0) + +/// a weather event of some kind occured +#define COMSIG_WEATHER_TELEGRAPH(event_type) "!weather_telegraph [event_type]" +#define COMSIG_WEATHER_START(event_type) "!weather_start [event_type]" +#define COMSIG_WEATHER_WINDDOWN(event_type) "!weather_winddown [event_type]" +#define COMSIG_WEATHER_END(event_type) "!weather_end [event_type]" + +/// called by auxgm add_gas: (gas_id) +#define COMSIG_GLOB_NEW_GAS "!new_gas" + // signals from globally accessible objects /// from SSsun when the sun changes position : (primary_sun, suns) #define COMSIG_SUN_MOVED "sun_moved" +///from SSsecurity_level when the security level changes : (new_level) +#define COMSIG_SECURITY_LEVEL_CHANGED "security_level_changed" + /// from SSactivity for things that add threat but aren't "global" (e.g. phylacteries) #define COMSIG_THREAT_CALC "threat_calculation" @@ -41,6 +63,8 @@ #define COMSIG_PARENT_QDELETING "parent_qdeleting" /// generic topic handler (usr, href_list) #define COMSIG_TOPIC "handle_topic" +/// from datum ui_act (usr, action) +#define COMSIG_UI_ACT "COMSIG_UI_ACT" /// fires on the target datum when an element is attached to it (/datum/element) #define COMSIG_ELEMENT_ATTACH "element_attach" @@ -229,6 +253,8 @@ // #define HEARING_SPANS 6 #define HEARING_MESSAGE_MODE 7 // #define HEARING_SOURCE 8 +#define COMSIG_MOVABLE_BARK "movable_bark" //from base of atom/movable/proc/bark(): (list/hearers, distance, volume, pitch) +#define COMSIG_MOVABLE_QUEUE_BARK "movable_queue_bark" //from base of atom/movable/proc/send_speech(): (list/hearers, message, range, atom/movable/source, bubble_type, list/spans, datum/language/message_language, message_mode) #define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source) #define COMSIG_MOVABLE_TELEPORTED "movable_teleported" //from base of do_teleport(): (channel, turf/origin, turf/destination) #define COMSIG_MOVABLE_CHASM_DROP "movable_chasm_drop" //from base of /datum/component/chasm/drop() (/datum/component/chasm) @@ -295,6 +321,12 @@ ///from base of mob/AltClickOn(): (atom/A) #define COMSIG_MOB_ALTCLICKON "mob_altclickon" +//Gun signals +///When a gun is switched to automatic fire mode +#define COMSIG_GUN_AUTOFIRE_SELECTED "gun_autofire_selected" +///When a gun is switched off of automatic fire mode +#define COMSIG_GUN_AUTOFIRE_DESELECTED "gun_autofire_deselected" + // Lighting: ///from base of [atom/proc/set_light]: (l_range, l_power, l_color, l_on) #define COMSIG_ATOM_SET_LIGHT "atom_set_light" @@ -322,11 +354,22 @@ #define COMSIG_ATOM_UPDATE_LIGHT_FLAGS "atom_update_light_flags" // /client signals -#define COMSIG_MOB_CLIENT_LOGIN "mob_client_login" //sent when a mob/login() finishes: (client) #define COMSIG_MOB_CLIENT_LOGOUT "mob_client_logout" //sent when a mob/logout() starts: (client) #define COMSIG_MOB_CLIENT_MOVE "mob_client_move" //sent when client/Move() finishes with no early returns: (client, direction, n, oldloc) #define COMSIG_MOB_CLIENT_CHANGE_VIEW "mob_client_change_view" //from base of /client/change_view(): (client, old_view, view) #define COMSIG_MOB_CLIENT_MOUSEMOVE "mob_client_mousemove" //from base of /client/MouseMove(): (object, location, control, params) +#define COMSIG_MOB_CLIENT_JOINED_FROM_LOBBY "mob_client_joined_from_lobby" //sent when a player joins/latejoins the game: (new_character, client, late_transfer) + +///sent when a mob/login() finishes: (client) +#define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login" +//from base of client/MouseDown(): (/client, object, location, control, params) +#define COMSIG_CLIENT_MOUSEDOWN "client_mousedown" +//from base of client/MouseUp(): (/client, object, location, control, params) +#define COMSIG_CLIENT_MOUSEUP "client_mouseup" + #define COMPONENT_CLIENT_MOUSEUP_INTERCEPT (1<<0) +//from base of client/MouseUp(): (/client, object, location, control, params) +#define COMSIG_CLIENT_MOUSEDRAG "client_mousedrag" + // /mob/living signals #define COMSIG_LIVING_REGENERATE_LIMBS "living_regenerate_limbs" //from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs) @@ -344,6 +387,9 @@ #define COMSIG_LIVING_RUN_BLOCK "living_do_run_block" //from base of mob/living/do_run_block(): (real_attack, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone) #define COMSIG_LIVING_GET_BLOCKING_ITEMS "get_blocking_items" //from base of mob/living/get_blocking_items(): (list/items) +#define COMSIG_LIVING_RESTING "living_on_resting" //from mob/living/set_resting +#define COMSIG_LIVING_STOPPED_PULLING "living_on_stop_pulling" //from mob/living/stop_pulling + #define COMSIG_LIVING_ACTIVE_BLOCK_START "active_block_start" //from base of mob/living/keybind_start_active_blocking(): (obj/item/blocking_item, list/backup_items) #define COMPONENT_PREVENT_BLOCK_START 1 #define COMSIG_LIVING_ACTIVE_PARRY_START "active_parry_start" //from base of mob/living/initiate_parry_sequence(): (parrying_method, datum/parrying_item_mob_or_art, list/backup_items, list/override) @@ -367,8 +413,9 @@ #define COMSIG_LIVING_LIFE "life_tick" //from base of mob/living/Life() (seconds, times_fired) #define COMPONENT_INTERRUPT_LIFE_BIOLOGICAL 1 // interrupt biological processes #define COMPONENT_INTERRUPT_LIFE_PHYSICAL 2 // interrupt physical handling + #define COMPONET_INTERRUPT_STATUS_EFFECTS 3 // interrupt status effects -#define COMSIG_LIVING_BIOLOGICAL_LIFE "biological_life" //from base of mob/living/BiologicalLife() (seconds, times_fired) +#define COMSIG_LIVING_BIOLOGICAL_LIFE "biological_life" //from base of mob/living/BiologicalLife() (delta_time, times_fired) #define COMSIG_LIVING_PHYSICAL_LIFE "physical_life" //from base of mob/living/PhysicalLife() (seconds, times_fired) @@ -411,6 +458,12 @@ ///from /obj/machinery/obj_break(damage_flag): (damage_flag) #define COMSIG_MACHINERY_BROKEN "machinery_broken" +// /obj/machinery/power/supermatter_crystal signals +/// from /obj/machinery/power/supermatter_crystal/process_atmos(); when the SM delam reaches the point of sounding alarms +#define COMSIG_SUPERMATTER_DELAM_START_ALARM "sm_delam_start_alarm" +/// from /obj/machinery/power/supermatter_crystal/process_atmos(); when the SM sounds an audible alarm +#define COMSIG_SUPERMATTER_DELAM_ALARM "sm_delam_alarm" + // /obj/item signals #define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user) #define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob) @@ -422,6 +475,8 @@ #define COMSIG_ITEM_AFTERATTACK "item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, params) #define COMSIG_ITEM_ALT_AFTERATTACK "item_alt_afterattack" //from base of obj/item/altafterattack(): (atom/target, mob/user, proximity, params) #define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot) +/// A mob has just unequipped an item. +#define COMSIG_MOB_UNEQUIPPED_ITEM "mob_unequipped_item" // Do not grant actions on equip. #define COMPONENT_NO_GRANT_ACTIONS 1 #define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (mob/user) @@ -437,8 +492,17 @@ #define COMPONENT_BLOCK_SHARPEN_BLOCKED 2 #define COMPONENT_BLOCK_SHARPEN_ALREADY 4 #define COMPONENT_BLOCK_SHARPEN_MAXED 8 -#define COMSIG_ITEM_MICROWAVE_ACT "microwave_act" //called on item when microwaved (): (obj/machinery/microwave/M) +#define COMSIG_ITEM_MICROWAVE_ACT "microwave_act" //called on item when microwaved (): (obj/machinery/microwave/M) + +// /obj/item signals for economy +#define COMSIG_ITEM_SOLD "item_sold" //called when an item is sold by the exports subsystem +#define COMSIG_STRUCTURE_UNWRAPPED "structure_unwrapped" //called when a wrapped up structure is opened by hand +#define COMSIG_ITEM_UNWRAPPED "item_unwrapped" //called when a wrapped up item is opened by hand + #define COMSIG_ITEM_SPLIT_VALUE 1 +#define COMSIG_ITEM_SPLIT_PROFIT "item_split_profits" //Called when getting the item's exact ratio for cargo's profit. + #define COMSIG_ITEM_WORN_OVERLAYS "item_worn_overlays" //from base of obj/item/worn_overlays(): (isinhands, icon_file, used_state, style_flags, list/overlays) +#define COMSIG_ARMOR_PLATED "armor_plated" //called when an armor plate is successfully applied to an object // THE FOLLOWING TWO BLOCKS SHOULD RETURN BLOCK FLAGS AS DEFINED IN __DEFINES/combat.dm! #define COMSIG_ITEM_CHECK_BLOCK "check_block" //from base of obj/item/check_block(): (mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) #define COMSIG_ITEM_RUN_BLOCK "run_block" //from base of obj/item/run_block(): (mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) @@ -450,6 +514,14 @@ #define COMSIG_MINE_TRIGGERED "minegoboom" ///from [/obj/effect/mine/proc/triggermine]: // Uncovered information #define COMPONENT_DEEPSCAN_UNCOVERED_INFORMATION 1 +///Called when an item is being offered, from [/obj/item/proc/on_offered(mob/living/carbon/offerer)] +#define COMSIG_ITEM_OFFERING "item_offering" + ///Interrupts the offer proc + #define COMPONENT_OFFER_INTERRUPT (1<<0) +///Called when an someone tries accepting an offered item, from [/obj/item/proc/on_offer_taken(mob/living/carbon/offer, mob/living/carbon/taker)] +#define COMSIG_ITEM_OFFER_TAKEN "item_offer_taken" + ///Interrupts the offer acceptance + #define COMPONENT_OFFER_TAKE_INTERRUPT (1<<0) ///from [/obj/structure/closet/supplypod/proc/endlaunch]: #define COMSIG_SUPPLYPOD_LANDED "supplypodgoboom" @@ -493,6 +565,18 @@ #define COMSIG_PROJECTILE_PREHIT "com_proj_prehit" ///sent to targets during the process_hit proc of projectiles #define COMSIG_PELLET_CLOUD_INIT "pellet_cloud_init" // sent to targets during the process_hit proc of projectiles +// /obj/vehicle/sealed/mecha signals +// /sent from mecha action buttons to the mecha they're linked to +#define COMSIG_MECHA_ACTION_TRIGGER "mecha_action_activate" + +///sent from clicking while you have no equipment selected. Sent before cooldown and adjacency checks, so you can use this for infinite range things if you want. +#define COMSIG_MECHA_MELEE_CLICK "mecha_action_melee_click" + /// Prevents click from happening. + #define COMPONENT_CANCEL_MELEE_CLICK (1<<0) +///sent from clicking while you have equipment selected. +#define COMSIG_MECHA_EQUIPMENT_CLICK "mecha_action_equipment_click" + /// Prevents click from happening. + #define COMPONENT_CANCEL_EQUIPMENT_CLICK (1<<0) // /mob/living/carbon/human signals #define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target) @@ -622,3 +706,6 @@ // /datum/component/identification signals #define COMSIG_IDENTIFICATION_KNOWLEDGE_CHECK "id_knowledge_check" // (mob/user) - returns a value from ID_COMPONENT_KNOWLEDGE_NONE to ID_COMPONENT_KNOWLEDGE_FULL + +///from base of [/datum/component/multiple_lives/proc/respawn]: (mob/respawned_mob, gibbed, lives_left) +#define COMSIG_ON_MULTIPLE_LIVES_RESPAWN "on_multiple_lives_respawn" diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm new file mode 100644 index 0000000000..cc6e5bd49a --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm @@ -0,0 +1,3 @@ +/// Called from /mob/living/PushAM -- Called when this mob is about to push a movable, but before it moves +/// (aotm/movable/being_pushed) +#define COMSIG_LIVING_PUSHING_MOVABLE "living_pushing_movable" diff --git a/code/__DEFINES/dcs/signals/signals_hud.dm b/code/__DEFINES/dcs/signals/signals_hud.dm new file mode 100644 index 0000000000..c771204773 --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_hud.dm @@ -0,0 +1,4 @@ +/// Sent from /atom/movable/screen/lobby/button/collapse/proc/collapse_buttons() : () +#define COMSIG_HUD_LOBBY_COLLAPSED "hud_lobby_collapsed" +/// Sent from /atom/movable/screen/lobby/button/collapse/proc/expand_buttons() : () +#define COMSIG_HUD_LOBBY_EXPANDED "hud_lobby_expanded" diff --git a/code/__DEFINES/dcs/signals/signals_medical.dm b/code/__DEFINES/dcs/signals/signals_medical.dm new file mode 100644 index 0000000000..801eb6b41b --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_medical.dm @@ -0,0 +1,14 @@ +/// From /datum/surgery/New(): (datum/surgery/surgery, surgery_location (body zone), obj/item/bodypart/targeted_limb) +#define COMSIG_MOB_SURGERY_STARTED "mob_surgery_started" + +/// From /datum/surgery_step/success(): (datum/surgery_step/step, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results) +#define COMSIG_MOB_SURGERY_STEP_SUCCESS "mob_surgery_step_success" + +/// From /obj/item/shockpaddles/proc/do_success(): (obj/item/shockpaddles/source) +#define COMSIG_DEFIBRILLATOR_SUCCESS "defib_success" + #define COMPONENT_DEFIB_STOP (1<<0) + +/// From /datum/surgery/can_start(): (mob/source, datum/surgery/surgery, mob/living/patient) +#define COMSIG_SURGERY_STARTING "surgery_starting" + #define COMPONENT_CANCEL_SURGERY (1<<0) + #define COMPONENT_FORCE_SURGERY (1<<1) diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm new file mode 100644 index 0000000000..5d2a471c0a --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -0,0 +1,2 @@ +///From base of mob/living/MobBump() (mob/living) +#define COMSIG_LIVING_MOB_BUMP "living_mob_bump" diff --git a/code/__DEFINES/dcs/signals/signals_mod.dm b/code/__DEFINES/dcs/signals/signals_mod.dm new file mode 100644 index 0000000000..2533b69852 --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_mod.dm @@ -0,0 +1,35 @@ +//MODsuit signals +/// Called when a module is selected to be the active one from on_select(obj/item/mod/module/module) +#define COMSIG_MOD_MODULE_SELECTED "mod_module_selected" +/// Called when a MOD deploys one or more of its parts. +#define COMSIG_MOD_DEPLOYED "mod_deployed" +/// Called when a MOD retracts one or more of its parts. +#define COMSIG_MOD_RETRACTED "mod_retracted" +/// Called when a MOD is finished toggling itself. +#define COMSIG_MOD_TOGGLED "mod_toggled" +/// Called when a MOD activation is called from toggle_activate(mob/user) +#define COMSIG_MOD_ACTIVATE "mod_activate" + /// Cancels the suit's activation + #define MOD_CANCEL_ACTIVATE (1 << 0) +/// Called when a MOD finishes having a module removed from it. +#define COMSIG_MOD_MODULE_REMOVED "mod_module_removed" +/// Called when a MOD finishes having a module added to it. +#define COMSIG_MOD_MODULE_ADDED "mod_module_added" +/// Called when a MOD is having modules removed from crowbar_act(mob/user, obj/crowbar) +#define COMSIG_MOD_MODULE_REMOVAL "mod_module_removal" + /// Cancels the removal of modules + #define MOD_CANCEL_REMOVAL (1 << 0) +/// Called when a module attempts to activate, however it does. At the end of checks so you can add some yourself, or work on trigger behavior (mob/user) +#define COMSIG_MODULE_TRIGGERED "mod_module_triggered" + /// Cancels activation, with no message. Include feedback on your cancel. + #define MOD_ABORT_USE (1<<0) +/// Called when a module activates, after all checks have passed and cooldown started. +#define COMSIG_MODULE_ACTIVATED "mod_module_activated" +/// Called when a module deactivates, after all checks have passed. +#define COMSIG_MODULE_DEACTIVATED "mod_module_deactivated" +/// Called when a module is used, after all checks have passed and cooldown started. +#define COMSIG_MODULE_USED "mod_module_used" +/// Called when the MODsuit wearer is set. +#define COMSIG_MOD_WEARER_SET "mod_wearer_set" +/// Called when the MODsuit wearer is unset. +#define COMSIG_MOD_WEARER_UNSET "mod_wearer_unset" diff --git a/code/__DEFINES/dcs/signals/signals_painting.dm b/code/__DEFINES/dcs/signals/signals_painting.dm new file mode 100644 index 0000000000..4f9201ec8f --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_painting.dm @@ -0,0 +1,7 @@ +// signals for painting canvases, tools and the /datum/component/palette component + +///from base of /item/proc/set_painting_tool_color(): (chosen_color) +#define COMSIG_PAINTING_TOOL_SET_COLOR "painting_tool_set_color" + +/// from base of /item/canvas/ui_data(): (data) +#define COMSIG_PAINTING_TOOL_GET_ADDITIONAL_DATA "painting_tool_get_data" diff --git a/code/__DEFINES/dcs/signals/signals_reagent.dm b/code/__DEFINES/dcs/signals/signals_reagent.dm new file mode 100644 index 0000000000..848458f91c --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_reagent.dm @@ -0,0 +1,2 @@ +///Sent by /datum/reagents/proc/reaction, used for /obj/item/mod/module/springlock +#define COMSIG_ATOM_EXPOSE_REAGENTS "atom_expose_reagents" diff --git a/code/__DEFINES/dcs/signals/signals_screentips.dm b/code/__DEFINES/dcs/signals/signals_screentips.dm new file mode 100644 index 0000000000..8f7326ee2e --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_screentips.dm @@ -0,0 +1,23 @@ +/// A "Type-A" contextual screentip interaction. +/// These are used for items that are defined by their behavior. They define their contextual text within *themselves*, +/// not in their targets. +/// Examples include syringes (LMB to inject, RMB to draw) and health analyzers (LMB to scan health/wounds, RMB for chems) +/// Items can override `add_item_context()`, and call `register_item_context()` in order to easily connect to this. +/// Called on /obj/item with a mutable screentip context list, the hovered target, and the mob hovering. +/// A screentip context list is a list that has context keys (SCREENTIP_CONTEXT_*, from __DEFINES/screentips.dm) +/// that map to the action as text. +/// If you mutate the list in this signal, you must return CONTEXTUAL_SCREENTIP_SET. +#define COMSIG_ITEM_REQUESTING_CONTEXT_FOR_TARGET "item_requesting_context_for_target" + +/// A "Type-B" contextual screentip interaction. +/// These are atoms that are defined by what happens *to* them. These should define contextual text within themselves, and +/// not in their operating tools. +/// Examples include construction objects (LMB with glass to put in screen for computers). +/// Called on /atom with a mutable screentip context list, the item being used, and the mob hovering. +/// A screentip context list is a list that has context keys (SCREENTIP_CONTEXT_*, from __DEFINES/screentips.dm) +/// that map to the action as text. +/// If you mutate the list in this signal, you must return CONTEXTUAL_SCREENTIP_SET. +#define COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM "atom_requesting_context_from_item" + +/// Tells the contextual screentips system that the list context was mutated. +#define CONTEXTUAL_SCREENTIP_SET (1 << 0) diff --git a/code/__DEFINES/dcs/signals/signals_subsystem.dm b/code/__DEFINES/dcs/signals/signals_subsystem.dm new file mode 100644 index 0000000000..c39b59262b --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_subsystem.dm @@ -0,0 +1,25 @@ +// Subsystem signals. Format: +// When the signal is called: (signal arguments) +// All signals send the source datum of the signal as the first argument + +///Subsystem signals +///From base of datum/controller/subsystem/Initialize: (start_timeofday) +#define COMSIG_SUBSYSTEM_POST_INITIALIZE "subsystem_post_initialize" + +///Called when the ticker enters the pre-game phase +#define COMSIG_TICKER_ENTER_PREGAME "comsig_ticker_enter_pregame" + +///Called when the ticker sets up the game for start +#define COMSIG_TICKER_ENTER_SETTING_UP "comsig_ticker_enter_setting_up" + +///Called when the ticker fails to set up the game for start +#define COMSIG_TICKER_ERROR_SETTING_UP "comsig_ticker_error_setting_up" + +/// Called when the round has started, but before GAME_STATE_PLAYING +#define COMSIG_TICKER_ROUND_STARTING "comsig_ticker_round_starting" + +// Point of interest signals +/// Sent from base of /datum/controller/subsystem/points_of_interest/proc/on_poi_element_added : (atom/new_poi) +#define COMSIG_ADDED_POINT_OF_INTEREST "added_point_of_interest" +/// Sent from base of /datum/controller/subsystem/points_of_interest/proc/on_poi_element_removed : (atom/old_poi) +#define COMSIG_REMOVED_POINT_OF_INTEREST "removed_point_of_interest" diff --git a/code/__DEFINES/dye_keys.dm b/code/__DEFINES/dye_keys.dm index a01dcacc18..fd93beda84 100644 --- a/code/__DEFINES/dye_keys.dm +++ b/code/__DEFINES/dye_keys.dm @@ -4,6 +4,7 @@ #define DYE_REGISTRY_SNEAKERS "sneakers" #define DYE_REGISTRY_FANNYPACK "fannypack" #define DYE_REGISTRY_BEDSHEET "bedsheet" +#define DYE_REGISTRY_DOUBLE_BEDSHEET "double_bedsheet" #define DYE_LAWYER_SPECIAL "lawyer_special" #define DYE_RED "red" diff --git a/code/__DEFINES/dynamic.dm b/code/__DEFINES/dynamic.dm index 6a15834ed8..dedf05396c 100644 --- a/code/__DEFINES/dynamic.dm +++ b/code/__DEFINES/dynamic.dm @@ -1,19 +1,17 @@ -#define CURRENT_LIVING_PLAYERS 1 -#define CURRENT_LIVING_ANTAGS 2 -#define CURRENT_DEAD_PLAYERS 3 -#define CURRENT_OBSERVERS 4 +/// This is the only ruleset that should be picked this round, used by admins and should not be on rulesets in code. +#define ONLY_RULESET (1 << 0) -#define NO_ASSASSIN (1<<0) -#define WAROPS_ALWAYS_ALLOWED (1<<1) -#define USE_PREF_WEIGHTS (1<<2) -#define FORCE_IF_WON (1<<3) -#define USE_PREV_ROUND_WEIGHTS (1<<4) +/// Only one ruleset with this flag will be picked. +#define HIGH_IMPACT_RULESET (1 << 1) -#define ONLY_RULESET (1<<0) -#define HIGHLANDER_RULESET (1<<1) -#define TRAITOR_RULESET (1<<2) -#define MINOR_RULESET (1<<3) -#define FAKE_ANTAG_RULESET (1<<4) -#define ALWAYS_MAX_WEIGHT_RULESET (1<<5) +/// This ruleset can only be picked once. Anything that does not have a scaling_cost MUST have this. +#define LONE_RULESET (1 << 2) -#define RULESET_STOP_PROCESSING 1 +/// No round event was hijacked this cycle +#define HIJACKED_NOTHING "HIJACKED_NOTHING" + +/// This cycle, a round event was hijacked when the last midround event was too recent. +#define HIJACKED_TOO_RECENT "HIJACKED_TOO_RECENT" + +/// This cycle, a round event was hijacked when the next midround event is too soon. +#define HIJACKED_TOO_SOON "HIJACKED_TOO_SOON" diff --git a/code/__DEFINES/economy.dm b/code/__DEFINES/economy.dm index 715469ff78..0d37607b81 100644 --- a/code/__DEFINES/economy.dm +++ b/code/__DEFINES/economy.dm @@ -52,3 +52,18 @@ #define PRICE_ABOVE_EXPENSIVE 500 // RCD, Crew pinpointer/monitor, galoshes #define PRICE_REALLY_EXPENSIVE 700 // More premium stuff. #define PRICE_ALMOST_ONE_GRAND 900 // $$$ Insulated gloves, backpack water-tank spray $$$ + +//Defines that set what kind of civilian bounties should be applied mid-round. +#define CIV_JOB_BASIC 1 +#define CIV_JOB_ROBO 2 +#define CIV_JOB_CHEF 3 +#define CIV_JOB_SEC 4 +#define CIV_JOB_DRINK 5 +#define CIV_JOB_CHEM 6 +#define CIV_JOB_VIRO 7 +#define CIV_JOB_SCI 8 +#define CIV_JOB_ENG 9 +#define CIV_JOB_MINE 10 +#define CIV_JOB_MED 11 +#define CIV_JOB_GROW 12 +#define CIV_JOB_RANDOM 13 diff --git a/code/__DEFINES/events.dm b/code/__DEFINES/events.dm index d39932e1a7..d189969b8e 100644 --- a/code/__DEFINES/events.dm +++ b/code/__DEFINES/events.dm @@ -7,3 +7,31 @@ #define EVENT_READY 1 #define EVENT_CANCELLED 2 #define EVENT_INTERRUPTED 3 + +///Events that mess with or create artificial intelligences, such as vending machines and the AI itself +#define EVENT_CATEGORY_AI "AI issues" +///Events that spawn anomalies, which might be the source of anomaly cores +#define EVENT_CATEGORY_ANOMALIES "Anomalies" +///Events pertaining cargo, messages incoming to the station and job slots +#define EVENT_CATEGORY_BUREAUCRATIC "Bureaucratic" +///Events that cause breakages and malfunctions that could be fixed by engineers +#define EVENT_CATEGORY_ENGINEERING "Engineering" +///Events that spawn creatures with simple desires, such as to hunt +#define EVENT_CATEGORY_ENTITIES "Entities" +///Events that should have no harmful effects, and might be useful to the crew +#define EVENT_CATEGORY_FRIENDLY "Friendly" +///Events that affect the body and mind +#define EVENT_CATEGORY_HEALTH "Health" +///Events reserved for special occassions +#define EVENT_CATEGORY_HOLIDAY "Holiday" +///Events with enemy groups with a more complex plan +#define EVENT_CATEGORY_INVASION "Invasion" +///Events that make a mess +#define EVENT_CATEGORY_JANITORIAL "Janitorial" +///Events that summon meteors and other debris, and stationwide waves of harmful space weather +#define EVENT_CATEGORY_SPACE "Space Threats" +///Events summoned by a wizard +#define EVENT_CATEGORY_WIZARD "Wizard" + +/// Return from admin setup to stop the event from triggering entirely. +#define ADMIN_CANCEL_EVENT "cancel event" diff --git a/code/__DEFINES/fonts.dm b/code/__DEFINES/fonts.dm new file mode 100644 index 0000000000..ba799a62c9 --- /dev/null +++ b/code/__DEFINES/fonts.dm @@ -0,0 +1,7 @@ +// Font metrics bitfield +/// Include leading A width and trailing C width in GetWidth() or in DrawText() +#define INCLUDE_AC (1<<0) + +DEFINE_BITFIELD(font_flags, list( + "INCLUDE_AC" = INCLUDE_AC, +)) diff --git a/code/__DEFINES/footsteps.dm b/code/__DEFINES/footsteps.dm index 215e287adf..cc0c6547b0 100644 --- a/code/__DEFINES/footsteps.dm +++ b/code/__DEFINES/footsteps.dm @@ -8,6 +8,7 @@ #define FOOTSTEP_LAVA "lava" #define FOOTSTEP_MEAT "meat" #define FOOTSTEP_RUST "rust" +#define FOOTSTEP_CATWALK "catwalk" //barefoot sounds #define FOOTSTEP_WOOD_BAREFOOT "woodbarefoot" @@ -94,6 +95,12 @@ GLOBAL_LIST_INIT(footstep, list( 'sound/effects/footstep/lava3.ogg'), 100, 0), FOOTSTEP_MEAT = list(list( 'sound/effects/meatslap.ogg'), 100, 0), + FOOTSTEP_CATWALK = list(list( + 'sound/effects/footstep/catwalk1.ogg', + 'sound/effects/footstep/catwalk2.ogg', + 'sound/effects/footstep/catwalk3.ogg', + 'sound/effects/footstep/catwalk4.ogg', + 'sound/effects/footstep/catwalk5.ogg'), 100, 1), FOOTSTEP_RUST = list(list( 'sound/effects/footstep/rustystep1.ogg'), 100, 0) )) diff --git a/code/__DEFINES/gun.dm b/code/__DEFINES/gun.dm new file mode 100644 index 0000000000..05ce5118a3 --- /dev/null +++ b/code/__DEFINES/gun.dm @@ -0,0 +1,3 @@ +#define SELECT_SEMI_AUTOMATIC 1 +#define SELECT_BURST_SHOT 2 +#define SELECT_FULLY_AUTOMATIC 3 diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 128f9120c6..88cba1c449 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -4,3 +4,6 @@ #define HUD_STYLE_NOHUD 3 //No hud (for screenshots) #define HUD_VERSIONS 3 //Used in show_hud(); Please ensure this is the same as the maximum index. + +#define ui_borg_pda_send "CENTER+5:21,SOUTH:5" // To the right of the alert panel +#define ui_borg_pda_log "CENTER+6:21,SOUTH:5" diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm index 7b727fcc5a..d087c82093 100644 --- a/code/__DEFINES/inventory.dm +++ b/code/__DEFINES/inventory.dm @@ -6,87 +6,54 @@ #define STORAGE_VIEW_DEPTH 2 //ITEM INVENTORY SLOT BITMASKS -#define ITEM_SLOT_OCLOTHING (1<<0) -#define ITEM_SLOT_ICLOTHING (1<<1) -#define ITEM_SLOT_GLOVES (1<<2) -#define ITEM_SLOT_EYES (1<<3) -#define ITEM_SLOT_EARS (1<<4) -#define ITEM_SLOT_MASK (1<<5) -#define ITEM_SLOT_HEAD (1<<6) -#define ITEM_SLOT_FEET (1<<7) -#define ITEM_SLOT_ID (1<<8) -#define ITEM_SLOT_BELT (1<<9) -#define ITEM_SLOT_BACK (1<<10) -#define ITEM_SLOT_POCKET (1<<11) // this is to allow items with a w_class of WEIGHT_CLASS_NORMAL or WEIGHT_CLASS_BULKY to fit in pockets. -#define ITEM_SLOT_DENYPOCKET (1<<12) // this is to deny items with a w_class of WEIGHT_CLASS_SMALL or WEIGHT_CLASS_TINY to fit in pockets. -#define ITEM_SLOT_NECK (1<<13) -#define ITEM_SLOT_HANDS (1<<14) -#define ITEM_SLOT_BACKPACK (1<<15) -#define ITEM_SLOT_SUITSTORE (1<<16) +/// Suit slot (armors, costumes, space suits, etc.) +#define ITEM_SLOT_OCLOTHING (1<<0) +/// Jumpsuit slot +#define ITEM_SLOT_ICLOTHING (1<<1) +/// Glove slot +#define ITEM_SLOT_GLOVES (1<<2) +/// Glasses slot +#define ITEM_SLOT_EYES (1<<3) +/// Ear slot (radios, earmuffs) +#define ITEM_SLOT_EARS (1<<4) +/// Mask slot +#define ITEM_SLOT_MASK (1<<5) +/// Head slot (helmets, hats, etc.) +#define ITEM_SLOT_HEAD (1<<6) +/// Shoe slot +#define ITEM_SLOT_FEET (1<<7) +/// ID slot +#define ITEM_SLOT_ID (1<<8) +/// Belt slot +#define ITEM_SLOT_BELT (1<<9) +/// Back slot +#define ITEM_SLOT_BACK (1<<10) +/// Dextrous simplemob "hands" (used for Drones and Dextrous Guardians) +#define ITEM_SLOT_DEX_STORAGE (1<<11) +/// Neck slot (ties, bedsheets, scarves) +#define ITEM_SLOT_NECK (1<<12) +/// A character's hand slots +#define ITEM_SLOT_HANDS (1<<13) +/// Inside of a character's backpack +#define ITEM_SLOT_BACKPACK (1<<14) +/// Suit Storage slot +#define ITEM_SLOT_SUITSTORE (1<<15) +/// Left Pocket slot +#define ITEM_SLOT_LPOCKET (1<<16) +/// Right Pocket slot +#define ITEM_SLOT_RPOCKET (1<<17) +/// Handcuff slot +#define ITEM_SLOT_HANDCUFFED (1<<18) +/// Legcuff slot (bolas, beartraps) +#define ITEM_SLOT_LEGCUFFED (1<<19) +/// To attach to a jumpsuit +#define ITEM_SLOT_ACCESSORY (1<<20) -//SLOTS -#define SLOT_BACK 1 -#define SLOT_WEAR_MASK 2 -#define SLOT_HANDCUFFED 3 -#define SLOT_HANDS 4 //wherever you provide a slot for hands you provide SLOT_HANDS - //SLOT_HANDS as a slot will pick ANY available hand -#define SLOT_BELT 5 -#define SLOT_WEAR_ID 6 -#define SLOT_EARS 7 -#define SLOT_GLASSES 8 -#define SLOT_GLOVES 9 -#define SLOT_NECK 10 -#define SLOT_HEAD 11 -#define SLOT_SHOES 12 -#define SLOT_WEAR_SUIT 13 -#define SLOT_W_UNIFORM 14 -#define SLOT_L_STORE 15 -#define SLOT_R_STORE 16 -#define SLOT_S_STORE 17 -#define SLOT_IN_BACKPACK 18 -#define SLOT_LEGCUFFED 19 -#define SLOT_GENERC_DEXTROUS_STORAGE 20 - - -#define SLOTS_AMT 20 // Keep this up to date! - -//I hate that this has to exist -/proc/slotdefine2slotbit(slotdefine) //Keep this up to date with the value of SLOT BITMASKS and SLOTS (the two define sections above) - . = 0 - switch(slotdefine) - if(SLOT_BACK) - . = ITEM_SLOT_BACK - if(SLOT_WEAR_MASK) - . = ITEM_SLOT_MASK - if(SLOT_NECK) - . = ITEM_SLOT_NECK - if(SLOT_BELT) - . = ITEM_SLOT_BELT - if(SLOT_WEAR_ID) - . = ITEM_SLOT_ID - if(SLOT_EARS) - . = ITEM_SLOT_EARS - if(SLOT_GLASSES) - . = ITEM_SLOT_EYES - if(SLOT_GLOVES) - . = ITEM_SLOT_GLOVES - if(SLOT_HEAD) - . = ITEM_SLOT_HEAD - if(SLOT_SHOES) - . = ITEM_SLOT_FEET - if(SLOT_WEAR_SUIT) - . = ITEM_SLOT_OCLOTHING - if(SLOT_W_UNIFORM) - . = ITEM_SLOT_ICLOTHING - if(SLOT_L_STORE, SLOT_R_STORE) - . = ITEM_SLOT_POCKET - if(SLOT_HANDS) - . = ITEM_SLOT_HANDS - if(SLOT_IN_BACKPACK) - . = ITEM_SLOT_BACKPACK - if(SLOT_S_STORE) - . = ITEM_SLOT_SUITSTORE +/// Total amount of slots +#define SLOTS_AMT 21 // Keep this up to date! +//SLOT GROUP HELPERS +#define ITEM_SLOT_POCKETS (ITEM_SLOT_LPOCKET|ITEM_SLOT_RPOCKET) //Bit flags for the flags_inv variable, which determine when a piece of clothing hides another. IE a helmet hiding glasses. #define HIDEGLOVES (1<<0) @@ -245,4 +212,4 @@ GLOBAL_LIST_INIT(security_wintercoat_allowed, typecacheof(list( #define GET_INTERNAL_SLOTS(C) list(C.head, C.wear_mask) //Slots that won't trigger humans' update_genitals() on equip(). -GLOBAL_LIST_INIT(no_genitals_update_slots, list(SLOT_L_STORE, SLOT_R_STORE, SLOT_S_STORE, SLOT_IN_BACKPACK, SLOT_LEGCUFFED, SLOT_HANDCUFFED, SLOT_HANDS, SLOT_GENERC_DEXTROUS_STORAGE)) +GLOBAL_LIST_INIT(no_genitals_update_slots, list(ITEM_SLOT_LPOCKET, ITEM_SLOT_RPOCKET, ITEM_SLOT_SUITSTORE, ITEM_SLOT_BACKPACK, ITEM_SLOT_LEGCUFFED, ITEM_SLOT_HANDCUFFED, ITEM_SLOT_HANDS, ITEM_SLOT_DEX_STORAGE)) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 9538cf91fa..640079e9b8 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -74,12 +74,10 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list( #define iscatperson(A) (ishumanbasic(A) && istype(A.dna.species, /datum/species/human/felinid)) #define isethereal(A) (is_species(A, /datum/species/ethereal)) #define isvampire(A) (is_species(A,/datum/species/vampire)) -#define isdullahan(A) (is_species(A, /datum/species/dullahan)) -#define isangel(A) (is_species(A, /datum/species/angel)) #define ismush(A) (is_species(A, /datum/species/mush)) #define isshadow(A) (is_species(A, /datum/species/shadow)) -#define isrobotic(A) (is_species(A, /datum/species/ipc) || is_species(A, /datum/species/synthliz)) +#define isrobotic(A) (is_species(A, /datum/species/ipc) || is_species(A, /datum/species/synthliz) || is_species(A, /datum/species/mammal/synthetic)) #define isdwarf(A) (is_species(A, /datum/species/dwarf)) // Citadel specific species @@ -208,7 +206,7 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list( #define ismachinery(A) (istype(A, /obj/machinery)) -#define ismecha(A) (istype(A, /obj/mecha)) +#define ismecha(A) (istype(A, /obj/vehicle/sealed/mecha)) #define is_cleanable(A) (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/rune)) //if something is cleanable diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm index 35348df3d1..d4ab59cbc1 100644 --- a/code/__DEFINES/jobs.dm +++ b/code/__DEFINES/jobs.dm @@ -42,6 +42,7 @@ #define CLOWN (1<<11) #define MIME (1<<12) #define ASSISTANT (1<<13) +#define PRISONER (1<<14) #define JOB_AVAILABLE 0 #define JOB_UNAVAILABLE_GENERIC 1 @@ -89,3 +90,4 @@ #define JOB_DISPLAY_ORDER_WARDEN 31 #define JOB_DISPLAY_ORDER_DETECTIVE 32 #define JOB_DISPLAY_ORDER_SECURITY_OFFICER 33 +#define JOB_DISPLAY_ORDER_PRISONER 34 diff --git a/code/__DEFINES/layers_planes.dm b/code/__DEFINES/layers_planes.dm index ea7b1b2e0a..578dfe87e5 100644 --- a/code/__DEFINES/layers_planes.dm +++ b/code/__DEFINES/layers_planes.dm @@ -5,9 +5,10 @@ #define CLICKCATCHER_PLANE -99 -#define PLANE_SPACE -95 +#define PLANE_SPACE -98 #define PLANE_SPACE_RENDER_TARGET "PLANE_SPACE" -#define PLANE_SPACE_PARALLAX -90 + +#define PLANE_SPACE_PARALLAX -95 #define PLANE_SPACE_PARALLAX_RENDER_TARGET "PLANE_SPACE_PARALLAX" #define OPENSPACE_LAYER 17 //Openspace layer over all @@ -64,8 +65,9 @@ #define GAS_PIPE_VISIBLE_LAYER 2.47 #define GAS_FILTER_LAYER 2.48 #define GAS_PUMP_LAYER 2.49 - #define LOW_OBJ_LAYER 2.5 +///catwalk overlay of /turf/open/floor/plating/plating_catwalk +#define CATWALK_LAYER 2.51 #define LOW_SIGIL_LAYER 2.52 #define SIGIL_LAYER 2.54 #define HIGH_SIGIL_LAYER 2.56 @@ -152,6 +154,10 @@ #define CAMERA_STATIC_LAYER 19 #define CAMERA_STATIC_RENDER_TARGET "CAMERA_STATIC_PLANE" +/// Plane for balloon text (text that fades up) +/// It's over lighting and every other crap because this is nearly as important as hud content and only visible to the user. +#define BALLOON_CHAT_PLANE 20 + //HUD layer defines #define FULLSCREEN_PLANE 20 @@ -181,6 +187,18 @@ #define ABOVE_HUD_LAYER 30 #define ABOVE_HUD_RENDER_TARGET "ABOVE_HUD_PLANE" +///Layer for lobby menu collapse button +#define LOBBY_BELOW_MENU_LAYER 2 +///Layer for lobby menu background image and main buttons (Join/Ready, Observe, Charater Prefs) +#define LOBBY_MENU_LAYER 3 +///Layer for lobby menu shutter, which covers up the menu to collapse/expand it +#define LOBBY_SHUTTER_LAYER 4 +///Layer for lobby menu buttons that are hanging away from and lower than the main panel +#define LOBBY_BOTTOM_BUTTON_LAYER 5 + #define SPLASHSCREEN_LAYER 90 #define SPLASHSCREEN_PLANE 90 #define SPLASHSCREEN_RENDER_TARGET "SPLASHSCREEN_PLANE" + +///Layer for screentips +#define SCREENTIP_LAYER 40 diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index 95d91da14a..e448cd23d4 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -30,31 +30,6 @@ //Important note on colors. Colors can end up significantly different from the basic html picture, especially when saturated #define LIGHT_COLOR_WHITE "#FFFFFF" #define LIGHT_COLOR_RED "#FA8282" //Warm but extremely diluted red. rgb(250, 130, 130) -#define LIGHT_COLOR_GREEN "#64C864" //Bright but quickly dissipating neon green. rgb(100, 200, 100) -#define LIGHT_COLOR_BLUE "#6496FA" //Cold, diluted blue. rgb(100, 150, 250) - -#define LIGHT_COLOR_BLUEGREEN "#7DE1AF" //Light blueish green. rgb(125, 225, 175) -#define LIGHT_COLOR_PALEBLUE "#7DAFE1" //A pale blue-ish color. rgb(125, 175, 225) -#define LIGHT_COLOR_CYAN "#7DE1E1" //Diluted cyan. rgb(125, 225, 225) -#define LIGHT_COLOR_LIGHT_CYAN "#40CEFF" //More-saturated cyan. rgb(64, 206, 255) -#define LIGHT_COLOR_DARK_BLUE "#6496FA" //Saturated blue. rgb(51, 117, 248) -#define LIGHT_COLOR_PINK "#E17DE1" //Diluted, mid-warmth pink. rgb(225, 125, 225) -#define LIGHT_COLOR_YELLOW "#E1E17D" //Dimmed yellow, leaning kaki. rgb(225, 225, 125) -#define LIGHT_COLOR_BROWN "#966432" //Clear brown, mostly dim. rgb(150, 100, 50) -#define LIGHT_COLOR_ORANGE "#FA9632" //Mostly pure orange. rgb(250, 150, 50) -#define LIGHT_COLOR_PURPLE "#952CF4" //Light Purple. rgb(149, 44, 244) -#define LIGHT_COLOR_LAVENDER "#9B51FF" //Less-saturated light purple. rgb(155, 81, 255) - -#define LIGHT_COLOR_HOLY_MAGIC "#FFF743" //slightly desaturated bright yellow. -#define LIGHT_COLOR_BLOOD_MAGIC "#D00000" //deep crimson - -//These ones aren't a direct colour like the ones above, because nothing would fit -#define LIGHT_COLOR_FIRE "#FAA019" //Warm orange color, leaning strongly towards yellow. rgb(250, 160, 25) -#define LIGHT_COLOR_LAVA "#C48A18" //Very warm yellow, leaning slightly towards orange. rgb(196, 138, 24) -#define LIGHT_COLOR_FLARE "#FA644B" //Bright, non-saturated red. Leaning slightly towards pink for visibility. rgb(250, 100, 75) -#define LIGHT_COLOR_SLIME_LAMP "#AFC84B" //Weird color, between yellow and green, very slimy. rgb(175, 200, 75) -#define LIGHT_COLOR_TUNGSTEN "#FAE1AF" //Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175) -#define LIGHT_COLOR_HALOGEN "#F0FAFA" //Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250) #define LIGHT_RANGE_FIRE 3 //How many tiles standard fires glow. diff --git a/code/__DEFINES/loadout.dm b/code/__DEFINES/loadout.dm index f9b4c36c9c..e4e784c039 100644 --- a/code/__DEFINES/loadout.dm +++ b/code/__DEFINES/loadout.dm @@ -4,6 +4,9 @@ #define LOADOUT_SUBCATEGORY_NONE "Miscellaneous" #define LOADOUT_SUBCATEGORIES_NONE list("Miscellaneous") +//accessory +#define LOADOUT_CATEGORY_ACCESSORY "Accessory" + //backpack #define LOADOUT_CATEGORY_BACKPACK "In backpack" #define LOADOUT_SUBCATEGORY_BACKPACK_GENERAL "General" //basically anything that there's not enough of to have its own subcategory @@ -58,6 +61,9 @@ //unlockable items #define LOADOUT_CATEGORY_UNLOCKABLE "Unlockable" +//errors with your savefile +#define LOADOUT_CATEGORY_ERROR "Errors" + //how many prosthetics can we have #define MAXIMUM_LOADOUT_PROSTHETICS 4 @@ -85,9 +91,23 @@ //the names of the customization tabs #define SETTINGS_TAB 0 -#define GAME_PREFERENCES_TAB 1 -#define APPEARANCE_TAB 2 -#define SPEECH_TAB 3 -#define LOADOUT_TAB 4 -#define CONTENT_PREFERENCES_TAB 5 -#define KEYBINDINGS_TAB 6 +#define PREFERENCES_TAB 1 +#define KEYBINDINGS_TAB 2 + +//subtabs for the character settings tab +#define GENERAL_CHAR_TAB 0 +#define BACKGROUND_CHAR_TAB 1 +#define APPEARANCE_CHAR_TAB 2 +#define MARKINGS_CHAR_TAB 3 +#define SPEECH_CHAR_TAB 4 +#define LOADOUT_CHAR_TAB 5 + +//subtabs for preferences tab +#define GAME_PREFS_TAB 0 +#define OOC_PREFS_TAB 1 +#define CONTENT_PREFS_TAB 2 + +//quirks +#define QUIRK_POSITIVE "Positive" +#define QUIRK_NEGATIVE "Negative" +#define QUIRK_NEUTRAL "Neutral" diff --git a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm index ecb58f1291..96201d71c2 100644 --- a/code/__DEFINES/logging.dm +++ b/code/__DEFINES/logging.dm @@ -39,16 +39,19 @@ #define LOG_ADMIN_PRIVATE (1 << 14) #define LOG_ASAY (1 << 15) #define LOG_VIRUS (1 << 16) +#define LOG_MECHA (1 << 17) #define LOG_SHUTTLE (1 << 18) +#define LOG_VICTIM (1 << 19) +#define LOG_ECON (1 << 20) //Individual logging panel pages -#define INDIVIDUAL_ATTACK_LOG (LOG_ATTACK) +#define INDIVIDUAL_ATTACK_LOG (LOG_ATTACK | LOG_VICTIM) #define INDIVIDUAL_SAY_LOG (LOG_SAY | LOG_WHISPER | LOG_DSAY) #define INDIVIDUAL_EMOTE_LOG (LOG_EMOTE | LOG_SUBTLER) #define INDIVIDUAL_COMMS_LOG (LOG_PDA | LOG_CHAT | LOG_COMMENT | LOG_TELECOMMS) #define INDIVIDUAL_OOC_LOG (LOG_OOC | LOG_ADMIN) #define INDIVIDUAL_OWNERSHIP_LOG (LOG_OWNERSHIP) -#define INDIVIDUAL_SHOW_ALL_LOG (LOG_ATTACK | LOG_SAY | LOG_WHISPER | LOG_EMOTE | LOG_DSAY | LOG_PDA | LOG_CHAT | LOG_COMMENT | LOG_TELECOMMS | LOG_OOC | LOG_ADMIN | LOG_OWNERSHIP | LOG_GAME) +#define INDIVIDUAL_SHOW_ALL_LOG (LOG_ATTACK | LOG_SAY | LOG_WHISPER | LOG_EMOTE | LOG_DSAY | LOG_PDA | LOG_CHAT | LOG_COMMENT | LOG_TELECOMMS | LOG_OOC | LOG_ADMIN | LOG_OWNERSHIP | LOG_GAME | LOG_VICTIM | LOG_ECON) #define LOGSRC_CLIENT "Client" #define LOGSRC_MOB "Mob" diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index 762df42472..b25ef763cf 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -48,32 +48,39 @@ #define MC_CHARGE "CHARGE" #define MC_AI "AI" #define MC_SENSORS "SENSORS" +#define MC_SIGNALER "SIGNALER" //NTNet stuff, for modular computers // NTNet module-configuration values. Do not change these. If you need to add another use larger number (5..6..7 etc) -#define NTNET_SOFTWAREDOWNLOAD 1 // Downloads of software from NTNet -#define NTNET_PEERTOPEER 2 // P2P transfers of files between devices -#define NTNET_COMMUNICATION 3 // Communication (messaging) -#define NTNET_SYSTEMCONTROL 4 // Control of various systems, RCon, air alarm control, etc. +#define NTNET_SOFTWAREDOWNLOAD 1 // Downloads of software from NTNet +#define NTNET_PEERTOPEER 2 // P2P transfers of files between devices +#define NTNET_COMMUNICATION 3 // Communication (messaging) +#define NTNET_SYSTEMCONTROL 4 // Control of various systems, RCon, air alarm control, etc. //NTNet transfer speeds, used when downloading/uploading a file/program. -#define NTNETSPEED_LOWSIGNAL 0.5 // GQ/s transfer speed when the device is wirelessly connected and on Low signal -#define NTNETSPEED_HIGHSIGNAL 1 // GQ/s transfer speed when the device is wirelessly connected and on High signal -#define NTNETSPEED_ETHERNET 2 // GQ/s transfer speed when the device is using wired connection +#define NTNETSPEED_LOWSIGNAL 0.5 // GQ/s transfer speed when the device is wirelessly connected and on Low signal +#define NTNETSPEED_HIGHSIGNAL 1 // GQ/s transfer speed when the device is wirelessly connected and on High signal +#define NTNETSPEED_ETHERNET 2 // GQ/s transfer speed when the device is using wired connection //Caps for NTNet logging. Less than 10 would make logging useless anyway, more than 500 may make the log browser too laggy. Defaults to 100 unless user changes it. #define MAX_NTNET_LOGS 300 #define MIN_NTNET_LOGS 10 //Program bitflags -#define PROGRAM_ALL (~0) -#define PROGRAM_CONSOLE (1<<0) -#define PROGRAM_LAPTOP (1<<1) -#define PROGRAM_TABLET (1<<2) +#define PROGRAM_ALL (~0) +#define PROGRAM_CONSOLE (1<<0) +#define PROGRAM_LAPTOP (1<<1) +#define PROGRAM_TABLET (1<<2) //Program states #define PROGRAM_STATE_KILLED 0 #define PROGRAM_STATE_BACKGROUND 1 #define PROGRAM_STATE_ACTIVE 2 +//Program categories +#define PROGRAM_CATEGORY_CREW "Crew" +#define PROGRAM_CATEGORY_ENGI "Engineering" +#define PROGRAM_CATEGORY_ROBO "Robotics" +#define PROGRAM_CATEGORY_SUPL "Supply" +#define PROGRAM_CATEGORY_MISC "Other" #define FIREDOOR_OPEN 1 #define FIREDOOR_CLOSED 2 diff --git a/code/__DEFINES/mapexporting.dm b/code/__DEFINES/mapexporting.dm new file mode 100644 index 0000000000..cc0e2c0282 --- /dev/null +++ b/code/__DEFINES/mapexporting.dm @@ -0,0 +1,14 @@ +//Bits to save +#define SAVE_OBJECTS (1 << 1) //Save objects? +#define SAVE_MOBS (1 << 2) //Save Mobs? +#define SAVE_TURFS (1 << 3) //Save turfs? +#define SAVE_AREAS (1 << 4) //Save areas? +#define SAVE_SPACE (1 << 5) //Save space areas? (If not they will be saved as NOOP) +#define SAVE_OBJECT_PROPERTIES (1 << 6) //Save custom properties of objects (obj.on_object_saved() output) + +#define SAVE_ALL SAVE_OBJECTS | SAVE_MOBS | SAVE_TURFS | SAVE_AREAS | SAVE_SPACE | SAVE_OBJECT_PROPERTIES + +//Ignore turf if it contains +#define SAVE_SHUTTLEAREA_DONTCARE 0 +#define SAVE_SHUTTLEAREA_IGNORE 1 +#define SAVE_SHUTTLEAREA_ONLY 2 diff --git a/code/__DEFINES/maps.dm b/code/__DEFINES/maps.dm index 5e3f571cb7..0ee61a87f9 100644 --- a/code/__DEFINES/maps.dm +++ b/code/__DEFINES/maps.dm @@ -41,8 +41,9 @@ require only minor tweaks. //boolean - weather types that occur on the level #define ZTRAIT_SNOWSTORM "Weather_Snowstorm" #define ZTRAIT_ASHSTORM "Weather_Ashstorm" -#define ZTRAIT_ACIDRAIN "Weather_Acidrain" #define ZTRAIT_VOIDSTORM "Weather_Voidstorm" +#define ZTRAIT_ICESTORM "Weather_Icestorm" +#define ZTRAIT_LONGRAIN "Weather_Longrain" // number - bombcap is multiplied by this before being applied to bombs #define ZTRAIT_BOMBCAP_MULTIPLIER "Bombcap Multiplier" diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm index f56cd76a71..60d02c1e49 100644 --- a/code/__DEFINES/maths.dm +++ b/code/__DEFINES/maths.dm @@ -105,6 +105,9 @@ #define TORADIANS(degrees) ((degrees) * 0.0174532925) +/// Gets shift x that would be required the bitflag (1< 18 -#define AGE_MAX 85 // oldest a character can be +#define AGE_MAX 85 // oldest a character can be randomly generated +#define AGE_MAX_INPUT 85 // oldest a character's age can be manually set #define WIZARD_AGE_MIN 30 // youngest a wizard can be #define APPRENTICE_AGE_MIN 29 // youngest an apprentice can be #define SHOES_SLOWDOWN 0 // How much shoes slow you down by default. Negative values speed you up #define SHOES_SPEED_SLIGHT SHOES_SLOWDOWN - 1 // slightest speed boost to movement -#define POCKET_STRIP_DELAY 40 // time taken (in deciseconds) to search somebody's pockets +#define POCKET_STRIP_DELAY (4 SECONDS) //time taken to search somebody's pockets #define DOOR_CRUSH_DAMAGE 15 // the amount of damage that airlocks deal when they crush you #define HUNGER_FACTOR 0.1 // factor at which mob nutrition decreases @@ -344,6 +344,39 @@ ///Define for spawning megafauna instead of a mob for cave gen #define SPAWN_MEGAFAUNA "bluh bluh huge boss" +/* + * Defines for "AI emotions", allowing the AI to expression emotions + * with status displays via emotes. + */ + +#define AI_EMOTION_VERY_HAPPY "Very Happy" +#define AI_EMOTION_HAPPY "Happy" +#define AI_EMOTION_NEUTRAL "Neutral" +#define AI_EMOTION_UNSURE "Unsure" +#define AI_EMOTION_CONFUSED "Confused" +#define AI_EMOTION_SAD "Sad" +#define AI_EMOTION_BSOD "BSOD" +#define AI_EMOTION_BLANK "Blank" +#define AI_EMOTION_PROBLEMS "Problems?" +#define AI_EMOTION_AWESOME "Awesome" +#define AI_EMOTION_FACEPALM "Facepalm" +#define AI_EMOTION_THINKING "Thinking" +#define AI_EMOTION_FRIEND_COMPUTER "Friend Computer" +#define AI_EMOTION_DORFY "Dorfy" +#define AI_EMOTION_BLUE_GLOW "Blue Glow" +#define AI_EMOTION_RED_GLOW "Red Glow" + // / Breathing types. Lungs can access either by these or by a string, which will be considered a gas ID. #define BREATH_OXY /datum/breathing_class/oxygen #define BREATH_PLASMA /datum/breathing_class/plasma +#define BREATH_METHANE /datum/breathing_class/methane + +//Gremlins +#define NPC_TAMPER_ACT_FORGET 1 //Don't try to tamper with this again +#define NPC_TAMPER_ACT_NOMSG 2 //Don't produce a visible message + +//Game mode list indexes +#define CURRENT_LIVING_PLAYERS "living_players_list" +#define CURRENT_LIVING_ANTAGS "living_antags_list" +#define CURRENT_DEAD_PLAYERS "dead_players_list" +#define CURRENT_OBSERVERS "current_observers_list" diff --git a/code/__DEFINES/mod.dm b/code/__DEFINES/mod.dm new file mode 100644 index 0000000000..0e380f9e95 --- /dev/null +++ b/code/__DEFINES/mod.dm @@ -0,0 +1,40 @@ +/// Default value for the max_complexity var on MODsuits +#define DEFAULT_MAX_COMPLEXITY 15 + +/// Default cell drain per process on MODsuits +#define DEFAULT_CHARGE_DRAIN 5 + +/// Default time for a part to seal +#define MOD_ACTIVATION_STEP_TIME (2 SECONDS) + +/// Passive module, just acts when put in naturally. +#define MODULE_PASSIVE 0 +/// Usable module, does something when you press a button. +#define MODULE_USABLE 1 +/// Toggle module, you turn it on/off and it does stuff. +#define MODULE_TOGGLE 2 +/// Actively usable module, you may only have one selected at a time. +#define MODULE_ACTIVE 3 + +//Defines used by the theme for clothing flags and similar +#define CONTROL_LAYER "control_layer" +#define HELMET_FLAGS "helmet_flags" +#define CHESTPLATE_FLAGS "chestplate_flags" +#define GAUNTLETS_FLAGS "gauntlets_flags" +#define BOOTS_FLAGS "boots_flags" + +#define UNSEALED_LAYER "unsealed_layer" +#define UNSEALED_CLOTHING "unsealed_clothing" +#define SEALED_CLOTHING "sealed_clothing" +#define UNSEALED_INVISIBILITY "unsealed_invisibility" +#define SEALED_INVISIBILITY "sealed_invisibility" +#define UNSEALED_COVER "unsealed_cover" +#define SEALED_COVER "sealed_cover" +#define CAN_OVERSLOT "can_overslot" + +//Defines used to override MOD clothing's icon and worn icon files in the skin. +#define MOD_ICON_OVERRIDE "mod_icon_override" +#define MOD_WORN_ICON_OVERRIDE "mod_worn_icon_override" + +/// Global list of all /datum/mod_theme +GLOBAL_LIST_INIT(mod_themes, setup_mod_themes()) diff --git a/code/__DEFINES/movement.dm b/code/__DEFINES/movement.dm index 5bf7de8647..bccbd425dd 100644 --- a/code/__DEFINES/movement.dm +++ b/code/__DEFINES/movement.dm @@ -13,7 +13,7 @@ GLOBAL_VAR_INIT(glide_size_multiplier, 1.0) /// Then that's multiplied by the global glide size multiplier. 1.25 by default feels pretty close to spot on. This is just to try to get byond to behave. /// The whole result is then clamped to within the range above. /// Not very readable but it works -#define DELAY_TO_GLIDE_SIZE(delay) (clamp(((32 / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE)) +#define DELAY_TO_GLIDE_SIZE(delay) (clamp(((world.icon_size / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE)) /// Enables smooth movement // #define SMOOTH_MOVEMENT diff --git a/code/__DEFINES/pool.dm b/code/__DEFINES/pool.dm index 1bf39dcb1d..86088fbb79 100644 --- a/code/__DEFINES/pool.dm +++ b/code/__DEFINES/pool.dm @@ -8,5 +8,6 @@ GLOBAL_LIST_INIT(blacklisted_pool_reagents, list( /datum/reagent/toxin/plasma, /datum/reagent/oxygen, /datum/reagent/nitrous_oxide, /datum/reagent/nitrogen, //gases /datum/reagent/fermi, //blanket fermichem ban sorry. this also covers mkultra, genital enlargers, etc etc. - /datum/reagent/consumable/semen //NO. + /datum/reagent/consumable/semen, //NO. + /datum/reagent/consumable/milk )) diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index cd13510366..b38eb98b14 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -15,8 +15,16 @@ #define DISABLE_DEATHRATTLE (1<<12) #define DISABLE_ARRIVALRATTLE (1<<13) #define COMBOHUD_LIGHTING (1<<14) +#define SOUND_BARK (1<<15) +#define NO_ANTAG (1<<16) -#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS) +#define DEADMIN_ALWAYS (1<<0) +#define DEADMIN_ANTAGONIST (1<<1) +#define DEADMIN_POSITION_HEAD (1<<2) +#define DEADMIN_POSITION_SECURITY (1<<3) +#define DEADMIN_POSITION_SILICON (1<<4) + +#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS|SOUND_BARK) //Chat toggles #define CHAT_OOC (1<<0) @@ -34,12 +42,6 @@ #define TOGGLES_DEFAULT_CHAT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_PULLR|CHAT_GHOSTWHISPER|CHAT_GHOSTPDA|CHAT_GHOSTRADIO|CHAT_LOOC|CHAT_BANKCARD) -#define PARALLAX_INSANE -1 //for show offs -#define PARALLAX_HIGH 0 //default. -#define PARALLAX_MED 1 -#define PARALLAX_LOW 2 -#define PARALLAX_DISABLE 3 //this option must be the highest number - #define PIXEL_SCALING_AUTO 0 #define PIXEL_SCALING_1X 1 #define PIXEL_SCALING_1_2X 1.5 @@ -50,10 +52,6 @@ #define SCALING_METHOD_DISTORT "distort" #define SCALING_METHOD_BLUR "blur" -#define PARALLAX_DELAY_DEFAULT world.tick_lag -#define PARALLAX_DELAY_MED 1 -#define PARALLAX_DELAY_LOW 2 - #define SEC_DEPT_NONE "None" #define SEC_DEPT_RANDOM "Random" #define SEC_DEPT_ENGINEERING "Engineering" diff --git a/code/__DEFINES/projectiles.dm b/code/__DEFINES/projectiles.dm index 1bd67fbe02..70a2d611ab 100644 --- a/code/__DEFINES/projectiles.dm +++ b/code/__DEFINES/projectiles.dm @@ -1,3 +1,14 @@ + +// check_pierce() return values +/// Default behavior: hit and delete self +#define PROJECTILE_PIERCE_NONE 0 +/// Hit the thing but go through without deleting. Causes on_hit to be called with pierced = TRUE +#define PROJECTILE_PIERCE_HIT 1 +/// Entirely phase through the thing without ever hitting. +#define PROJECTILE_PIERCE_PHASE 2 +// Delete self without hitting +#define PROJECTILE_DELETE_WITHOUT_HITTING 3 + /// This atom should be ricocheted off of from its inherent properties using standard % chance handling. #define PROJECTILE_RICOCHET_YES 1 /// This atom should not be ricocheted off of from its inherent properties. diff --git a/code/__DEFINES/qdel.dm b/code/__DEFINES/qdel.dm index 63259774fa..32e0025ab2 100644 --- a/code/__DEFINES/qdel.dm +++ b/code/__DEFINES/qdel.dm @@ -1,30 +1,44 @@ -//defines that give qdel hints. these can be given as a return in destory() or by calling +//! Defines that give qdel hints. +//! +//! These can be given as a return in [/atom/proc/Destroy] or by calling [/proc/qdel]. + +/// `qdel` should queue the object for deletion. +#define QDEL_HINT_QUEUE 0 +/// `qdel` should let the object live after calling [/atom/proc/Destroy]. +#define QDEL_HINT_LETMELIVE 1 +/// Functionally the same as the above. `qdel` should assume the object will gc on its own, and not check it. +#define QDEL_HINT_IWILLGC 2 +/// Qdel should assume this object won't GC, and queue a hard delete using a hard reference. +#define QDEL_HINT_HARDDEL 3 +// Qdel should assume this object won't gc, and hard delete it posthaste. +#define QDEL_HINT_HARDDEL_NOW 4 -#define QDEL_HINT_QUEUE 0 //qdel should queue the object for deletion. -#define QDEL_HINT_LETMELIVE 1 //qdel should let the object live after calling destory. -#define QDEL_HINT_IWILLGC 2 //functionally the same as the above. qdel should assume the object will gc on its own, and not check it. -#define QDEL_HINT_HARDDEL 3 //qdel should assume this object won't gc, and queue a hard delete using a hard reference. -#define QDEL_HINT_HARDDEL_NOW 4 //qdel should assume this object won't gc, and hard del it post haste. - -#ifdef LEGACY_REFERENCE_TRACKING -/** If LEGACY_REFERENCE_TRACKING is enabled, qdel will call this object's find_references() verb. - * - * Functionally identical to QDEL_HINT_QUEUE if GC_FAILURE_HARD_LOOKUP is not enabled in _compiler_options.dm. +#ifdef REFERENCE_TRACKING +/** If REFERENCE_TRACKING is enabled, qdel will call this object's find_references() verb. + * + * Functionally identical to [QDEL_HINT_QUEUE] if [GC_FAILURE_HARD_LOOKUP] is not enabled in _compiler_options.dm. */ -#define QDEL_HINT_FINDREFERENCE 5 -/// Behavior as QDEL_HINT_FINDREFERENCE, but only if the GC fails and a hard delete is forced. +#define QDEL_HINT_FINDREFERENCE 5 +/// Behavior as [QDEL_HINT_FINDREFERENCE], but only if the GC fails and a hard delete is forced. #define QDEL_HINT_IFFAIL_FINDREFERENCE 6 #endif - #define GC_QUEUE_CHECK 1 #define GC_QUEUE_HARDDELETE 2 #define GC_QUEUE_COUNT 2 //increase this when adding more steps. +#define QDEL_ITEM_ADMINS_WARNED (1<<0) //! Set when admins are told about lag causing qdels in this type. +#define QDEL_ITEM_SUSPENDED_FOR_LAG (1<<1) //! Set when a type can no longer be hard deleted on failure because of lag it causes while this happens. + +// Defines for the [gc_destroyed][/datum/var/gc_destroyed] var. #define GC_QUEUED_FOR_QUEUING -1 #define GC_CURRENTLY_BEING_QDELETED -2 +// Defines for the time left for an item to get its reference cleaned +#define GC_FILTER_QUEUE 5 MINUTES +#define GC_DEL_QUEUE 10 SECONDS + #define QDELING(X) (X.gc_destroyed) #define QDELETED(X) (!X || QDELING(X)) #define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED) diff --git a/code/__DEFINES/reactions.dm b/code/__DEFINES/reactions.dm index b5d322a091..061ac289d0 100644 --- a/code/__DEFINES/reactions.dm +++ b/code/__DEFINES/reactions.dm @@ -13,7 +13,7 @@ #define NITRYL_FORMATION_ENERGY 100000 #define TRITIUM_BURN_OXY_FACTOR 100 #define TRITIUM_BURN_TRIT_FACTOR 10 -#define TRITIUM_BURN_RADIOACTIVITY_FACTOR 50000 //The neutrons gotta go somewhere. Completely arbitrary number. +#define TRITIUM_BURN_RADIOACTIVITY_FACTOR 5000 //The neutrons gotta go somewhere. Completely arbitrary number. #define TRITIUM_MINIMUM_RADIATION_ENERGY 0.1 //minimum 0.01 moles trit or 10 moles oxygen to start producing rads #define SUPER_SATURATION_THRESHOLD 96 #define STIMULUM_HEAT_SCALE 100000 @@ -27,6 +27,7 @@ #define NOBLIUM_RESEARCH_AMOUNT 25 #define BZ_RESEARCH_SCALE 4 #define BZ_RESEARCH_MAX_AMOUNT 400 +#define QCD_RESEARCH_AMOUNT 0.2 // often made in absolutely massive quantities due to the simple nature of fusion #define MIASMA_RESEARCH_AMOUNT 6 #define STIMULUM_RESEARCH_AMOUNT 50 //Plasma fusion properties @@ -42,3 +43,5 @@ #define FUSION_RAD_MAX 2000 #define FUSION_RAD_COEFFICIENT (-1000) #define FUSION_INSTABILITY_ENDOTHERMALITY 2 +// Snowflake fire product types +#define FIRE_PRODUCT_PLASMA 0 diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index 44e97ef345..2b0f51f230 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -63,6 +63,9 @@ #define THRESHOLD_UNHUSK 50 // health threshold for synthflesh/rezadone to unhusk someone +#define SYNTHTISSUE_BORROW_CAP 250 //The cap for synthtissue's borrowed health value when used on someone dead or already having borrowed health. +#define SYNTHTISSUE_DAMAGE_FLIP_CYCLES 45 //After how many cycles the damage will be pure toxdamage as opposed to clonedamage like initially. Gradually changes during its cycles. + //reagent bitflags, used for altering how they works #define REAGENT_DEAD_PROCESS (1<<0) //calls on_mob_dead() if present in a dead body #define REAGENT_DONOTSPLIT (1<<1) //Do not split the chem at all during processing @@ -72,7 +75,18 @@ #define REAGENT_FORCEONNEW (1<<5) //Forces a on_new() call without a data overhead #define REAGENT_SNEAKYNAME (1<<6) //When inverted, the inverted chem uses the name of the original chem #define REAGENT_SPLITRETAINVOL (1<<7) //Retains initial volume of chem when splitting +#define REAGENT_ORGANIC_PROCESS (1<<8) //Can be processed by organic carbons - will otherwise slowly dissipate +#define REAGENT_ROBOTIC_PROCESS (1<<9) //Can be processed by robotic carbons - will otherwise slowly dissipate + +#define REAGENT_ALL_PROCESS (REAGENT_ORGANIC_PROCESS | REAGENT_ROBOTIC_PROCESS) //expand this if you for some reason add more process flags + +#define INVALID_REAGENT_DISSIPATION 1 //How much of a reagent is removed per reagent tick if invalid processing-flag wise //Chemical reaction flags, for determining reaction specialties #define REACTION_CLEAR_IMPURE (1<<0) //Convert into impure/pure on reaction completion #define REACTION_CLEAR_INVERSE (1<<1) //Convert into inverse on reaction completion when purity is low enough + +//Chemical blacklists for smartdarts +GLOBAL_LIST_INIT(blacklisted_medchems, list( + /datum/reagent/medicine/morphine, /datum/reagent/medicine/haloperidol, //harmful chemicals in medicine + )) diff --git a/code/__DEFINES/atom_hud.dm b/code/__DEFINES/rendering/atom_hud.dm similarity index 93% rename from code/__DEFINES/atom_hud.dm rename to code/__DEFINES/rendering/atom_hud.dm index 386473a3ae..25763c0d63 100644 --- a/code/__DEFINES/atom_hud.dm +++ b/code/__DEFINES/rendering/atom_hud.dm @@ -24,8 +24,9 @@ #define NANITE_HUD "20" #define DIAG_NANITE_FULL_HUD "21" #define RAD_HUD "22" //radation alerts for medical huds +#define DIAG_LAUNCHPAD_HUD "23" //Displays launchpads' targeting reticle //for antag huds. these are used at the /mob level -#define ANTAG_HUD "23" +#define ANTAG_HUD "24" //by default everything in the hud_list of an atom is an image //a value in hud_list with one of these will change that behavior @@ -60,11 +61,8 @@ #define ANTAG_HUD_BROTHER 23 #define ANTAG_HUD_BLOODSUCKER 24 #define ANTAG_HUD_FUGITIVE 25 -#define ANTAG_HUD_HERETIC 26 - -// Notification action types -#define NOTIFY_JUMP "jump" -#define NOTIFY_ATTACK "attack" -#define NOTIFY_ORBIT "orbit" +#define ANTAG_HUD_HERETIC 26 +#define ANTAG_HUD_SPACECOP 27 +#define ANTAG_HUD_GANGSTER 28 #define ADD_HUD_TO_COOLDOWN 20 //cooldown for being shown the images for any particular data hud diff --git a/code/__DEFINES/rendering/parallax.dm b/code/__DEFINES/rendering/parallax.dm new file mode 100644 index 0000000000..8170b4190d --- /dev/null +++ b/code/__DEFINES/rendering/parallax.dm @@ -0,0 +1,13 @@ +#define PARALLAX_DELAY_DEFAULT world.tick_lag +#define PARALLAX_DELAY_MED 1 +#define PARALLAX_DELAY_LOW 2 + +// WARNING - client.prefs uses this, if you change these make sure to update the code in preferences! +#define PARALLAX_DISABLE 0 +#define PARALLAX_LOW 1 +#define PARALLAX_MED 2 +#define PARALLAX_HIGH 3 +#define PARALLAX_INSANE 4 // default + +// keep this false until we can fix it being a seizure hazard/ugly as sin +#define PARALLAX_ROTATION_ANIMATIONS FALSE diff --git a/code/__DEFINES/research.dm b/code/__DEFINES/research.dm index 60effc7265..b8b9b78bf3 100644 --- a/code/__DEFINES/research.dm +++ b/code/__DEFINES/research.dm @@ -73,4 +73,9 @@ TECHWEB_POINT_TYPE_GENERIC = "General Research"\ ) -#define TECHWEB_BOMB_POINTCAP 50000 //Adjust as needed; Stops toxins from nullifying RND progression mechanics. Current Value Cap Radius: 100 +#define LARGEST_BOMB "bomb" + +#define BOMB_TARGET_POINTS 50000 //Adjust as needed. Actual hard cap is double this, but will never be reached due to hyperbolic curve. +#define BOMB_TARGET_SIZE 300 // The shockwave radius required for a bomb to get TECHWEB_BOMB_MIDPOINT points. +// Linux still has old trit fires, so +#define BOMB_SUB_TARGET_EXPONENT 3 // The power of the points curve below the target size. Higher = less points for worse bombs, below target. diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index d47740f370..e08a8de417 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -14,6 +14,7 @@ #define ROLE_MALF "malf AI" #define ROLE_REV "revolutionary" #define ROLE_REV_HEAD "Head Revolutionary" +#define ROLE_REV_SUCCESSFUL "Victorious Revolutionary" #define ROLE_ALIEN "xenomorph" #define ROLE_PAI "pAI" #define ROLE_CULTIST "cultist" @@ -35,20 +36,20 @@ #define ROLE_DEATHSQUAD "deathsquad" #define ROLE_LAVALAND "lavaland" #define ROLE_INTERNAL_AFFAIRS "internal affairs agent" -#define ROLE_GANG "gangster" +#define ROLE_FAMILIES "family boss" +#define ROLE_FAMILY_HEAD_ASPIRANT "family head aspirant" #define ROLE_BLOODSUCKER "bloodsucker" #define ROLE_SPACE_DRAGON "Space Dragon" //#define ROLE_MONSTERHUNTER "monster hunter" Disabled for now #define ROLE_GHOSTCAFE "ghostcafe" #define ROLE_MINOR_ANTAG "minorantag" #define ROLE_RESPAWN "respawnsystem" -/// Not an actual antag. Lets players force all antags off. -#define ROLE_NO_ANTAGONISM "NO_ANTAGS" +//Define for disabling individual antagonists for dynamic +#define HAS_ANTAG_PREF(C,ROLE) (!(NO_ANTAG & C.prefs.toggles) && (ROLE in C.prefs.be_special)) //Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR. //The gamemode specific ones are just so the gamemodes can query whether a player is old enough //(in game days played) to play that role GLOBAL_LIST_INIT(special_roles, list( - ROLE_NO_ANTAGONISM, ROLE_TRAITOR = /datum/game_mode/traitor, ROLE_BROTHER = /datum/game_mode/traitor/bros, ROLE_OPERATIVE = /datum/game_mode/nuclear, @@ -69,9 +70,9 @@ GLOBAL_LIST_INIT(special_roles, list( ROLE_OVERTHROW = /datum/game_mode/overthrow, ROLE_INTERNAL_AFFAIRS = /datum/game_mode/traitor/internal_affairs, ROLE_SENTIENCE, - ROLE_GANG = /datum/game_mode/gang, ROLE_HERETIC = /datum/game_mode/heretics, ROLE_BLOODSUCKER = /datum/game_mode/bloodsucker, + ROLE_FAMILIES = /datum/game_mode/gang, ROLE_SPACE_DRAGON //ROLE_MONSTERHUNTER Disabled for now )) diff --git a/code/__DEFINES/rust_g.dm b/code/__DEFINES/rust_g.dm index 988acd3dae..0da05e7c1d 100644 --- a/code/__DEFINES/rust_g.dm +++ b/code/__DEFINES/rust_g.dm @@ -38,6 +38,9 @@ #define RUST_G (__rust_g || __detect_rust_g()) #endif +/// Gets the version of rust_g +/proc/rustg_get_version() return call(RUST_G, "get_version")() + /** * This proc generates a cellular automata noise grid which can be used in procedural generation methods. * @@ -77,8 +80,8 @@ #define RUSTG_HTTP_METHOD_PATCH "patch" #define RUSTG_HTTP_METHOD_HEAD "head" #define RUSTG_HTTP_METHOD_POST "post" -#define rustg_http_request_blocking(method, url, body, headers) call(RUST_G, "http_request_blocking")(method, url, body, headers) -#define rustg_http_request_async(method, url, body, headers) call(RUST_G, "http_request_async")(method, url, body, headers) +#define rustg_http_request_blocking(method, url, body, headers, options) call(RUST_G, "http_request_blocking")(method, url, body, headers, options) +#define rustg_http_request_async(method, url, body, headers, options) call(RUST_G, "http_request_async")(method, url, body, headers, options) #define rustg_http_check_request(req_id) call(RUST_G, "http_check_request")(req_id) #define RUSTG_JOB_NO_RESULTS_YET "NO RESULTS YET" @@ -99,3 +102,11 @@ #define rustg_sql_disconnect_pool(handle) call(RUST_G, "sql_disconnect_pool")(handle) #define rustg_sql_check_query(job_id) call(RUST_G, "sql_check_query")("[job_id]") +#define rustg_url_encode(text) call(RUST_G, "url_encode")(text) +#define rustg_url_decode(text) call(RUST_G, "url_decode")(text) + +#ifdef RUSTG_OVERRIDE_BUILTINS + #define url_encode(text) rustg_url_encode(text) + #define url_decode(text) rustg_url_decode(text) +#endif + diff --git a/code/__DEFINES/rust_g_overrides.dm b/code/__DEFINES/rust_g_overrides.dm new file mode 100644 index 0000000000..57de7d96ac --- /dev/null +++ b/code/__DEFINES/rust_g_overrides.dm @@ -0,0 +1,3 @@ +// RUSTG_OVERRIDE_BUILTINS is not used since the file APIs don't work well over Linux. +#define url_encode(text) rustg_url_encode("[text]") +#define url_decode(text) rustg_url_decode("[text]") diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm index d04004c659..a4d0b6427d 100644 --- a/code/__DEFINES/say.dm +++ b/code/__DEFINES/say.dm @@ -37,6 +37,7 @@ #define MODE_ALIEN "alientalk" #define MODE_HOLOPAD "holopad" +#define MODE_STATUSDISPLAY "statusdisplay" #define MODE_CHANGELING "changeling" #define MODE_KEY_CHANGELING "g" @@ -86,13 +87,37 @@ #define EMOTE_OMNI 4 //Don't set this very much higher then 1024 unless you like inviting people in to dos your server with message spam +//ambition start +#define MAX_AMBITION_LEN 1024 +//ambition end #define MAX_MESSAGE_LEN 4096 //Citadel edit: What's the WORST that could happen? #define MAX_FLAVOR_LEN 4096 +#define MAX_FLAVOR_PREVIEW_LEN 40 #define MAX_TASTE_LEN 40 //lick... vore... ew... #define MAX_NAME_LEN 42 #define MAX_BROADCAST_LEN 512 #define MAX_CHARTER_LEN 80 +//Bark defines +#define BARK_DEFAULT_MINPITCH 0.6 +#define BARK_DEFAULT_MAXPITCH 1.4 +#define BARK_DEFAULT_MINVARY 0.1 +#define BARK_DEFAULT_MAXVARY 0.4 +#define BARK_DEFAULT_MINSPEED 2 +#define BARK_DEFAULT_MAXSPEED 8 + +#define BARK_SPEED_BASELINE 4 //Used to calculate delay between barks, any bark speeds below this feature higher bark density, any speeds above feature lower bark density. Keeps barking length consistent + +#define BARK_MAX_BARKS 128 +#define BARK_MAX_TIME (10 SECONDS) // More or less the amount of time the above takes to process through with a bark speed of 2. + +#define BARK_PITCH_RAND(gend) ((gend == MALE ? rand(60, 120) : (gend == FEMALE ? rand(80, 140) : rand(60,140))) / 100) //Macro for determining random pitch based off gender +#define BARK_VARIANCE_RAND (rand(BARK_DEFAULT_MINVARY * 100, BARK_DEFAULT_MAXVARY * 100) / 100) //Macro for randomizing bark variance to reduce the amount of copy-pasta necessary for that + +#define BARK_DO_VARY(pitch, variance) (rand(((pitch * 100) - (variance*50)), ((pitch*100) + (variance*50))) / 100) + +#define BARK_SOUND_FALLOFF_EXPONENT(distance) (distance/7) //At lower ranges, we want the exponent to be below 1 so that whispers don't sound too awkward. At higher ranges, we want the exponent fairly high to make yelling less obnoxious + // Is something in the IC chat filter? This is config dependent. #define CHAT_FILTER_CHECK(T) (config.ic_filter_regex && findtext(T, config.ic_filter_regex)) diff --git a/code/__DEFINES/screentips.dm b/code/__DEFINES/screentips.dm new file mode 100644 index 0000000000..e9615bb4ee --- /dev/null +++ b/code/__DEFINES/screentips.dm @@ -0,0 +1,45 @@ +/// Context applied to LMB actions +#define SCREENTIP_CONTEXT_LMB "LMB" + +/// Context applied to RMB actions +#define SCREENTIP_CONTEXT_RMB "RMB" + +/// Context applied to Shift-LMB actions +#define SCREENTIP_CONTEXT_SHIFT_LMB "Shift-LMB" + +/// Context applied to Ctrl-LMB actions +#define SCREENTIP_CONTEXT_CTRL_LMB "Ctrl-LMB" + +/// Context applied to Ctrl-RMB actions +#define SCREENTIP_CONTEXT_CTRL_RMB "Ctrl-RMB" + +/// Context applied to Alt-LMB actions +#define SCREENTIP_CONTEXT_ALT_LMB "Alt-LMB" + +/// Context applied to Alt-RMB actions +#define SCREENTIP_CONTEXT_ALT_RMB "Alt-RMB" + +/// Context applied to Ctrl-Shift-LMB actions +#define SCREENTIP_CONTEXT_CTRL_SHIFT_LMB "Ctrl-Shift-LMB" + +/// Screentips are always disabled +#define SCREENTIP_PREFERENCE_DISABLED "Disabled" + +/// Screentips are always enabled +#define SCREENTIP_PREFERENCE_ENABLED "Enabled" + +/// Screentips are only enabled when they have context +#define SCREENTIP_PREFERENCE_CONTEXT_ONLY "Only with tips" + +/// Screentips enabled, no context +#define SCREENTIP_PREFERENCE_NO_CONTEXT "Enabled without tips" + +/// Regardless of intent +#define INTENT_ANY "any" + +GLOBAL_LIST_INIT(screentip_pref_options, list( + SCREENTIP_PREFERENCE_DISABLED, + SCREENTIP_PREFERENCE_ENABLED, + SCREENTIP_PREFERENCE_CONTEXT_ONLY, + SCREENTIP_PREFERENCE_NO_CONTEXT +)) diff --git a/code/__DEFINES/shuttles.dm b/code/__DEFINES/shuttles.dm index a188bf8363..862cc27f04 100644 --- a/code/__DEFINES/shuttles.dm +++ b/code/__DEFINES/shuttles.dm @@ -44,7 +44,6 @@ #define SHUTTLE_TRANSIT_BORDER 10 -#define PARALLAX_LOOP_TIME 25 #define HYPERSPACE_END_TIME 5 #define HYPERSPACE_WARMUP 1 diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm index 72543970ba..040853556d 100644 --- a/code/__DEFINES/sound.dm +++ b/code/__DEFINES/sound.dm @@ -16,6 +16,10 @@ #define CHANNEL_DIGEST 1009 #define CHANNEL_PREYLOOP 1008 + +//Reactor Channel +#define CHANNEL_REACTOR_ALERT 1007 // Is that radiation I hear? (ported from hyper) + ///Default range of a sound. #define SOUND_RANGE 17 ///default extra range for sounds considered to be quieter @@ -34,7 +38,7 @@ //THIS SHOULD ALWAYS BE THE LOWEST ONE! //KEEP IT UPDATED -#define CHANNEL_HIGHEST_AVAILABLE 1008 //CIT CHANGE - COMPENSATES FOR VORESOUND CHANNELS +#define CHANNEL_HIGHEST_AVAILABLE 1007 //CIT CHANGE - COMPENSATES FOR VORESOUND CHANNELS #define MAX_INSTRUMENT_CHANNELS (128 * 6) @@ -81,7 +85,8 @@ #define SPACE list('sound/ambience/ambispace.ogg', 'sound/ambience/ambispace2.ogg', 'sound/ambience/title2.ogg', 'sound/ambience/ambiatmos.ogg') #define MAINTENANCE list('sound/ambience/ambimaint1.ogg', 'sound/ambience/ambimaint2.ogg', 'sound/ambience/ambimaint3.ogg', 'sound/ambience/ambimaint4.ogg',\ - 'sound/ambience/ambimaint5.ogg', 'sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg', 'sound/ambience/ambitech2.ogg' ) + 'sound/ambience/ambimaint5.ogg', 'sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg', 'sound/ambience/ambitech2.ogg',\ + 'sound/ambience/ambimaint10.ogg' ) #define AWAY_MISSION list('sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiruin.ogg',\ 'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\ @@ -150,3 +155,43 @@ #define SOUND_AREA_LAVALAND SOUND_ENVIRONMENT_MOUNTAINS #define SOUND_AREA_ICEMOON SOUND_ENVIRONMENT_CAVE #define SOUND_AREA_WOODFLOOR SOUND_ENVIRONMENT_CITY + +///Announcer audio keys +#define ANNOUNCER_AIMALF "aimalf" +#define ANNOUNCER_ALIENS "aliens" +#define ANNOUNCER_ANIMES "animes" +#define ANNOUNCER_GRANOMALIES "granomalies" +#define ANNOUNCER_INTERCEPT "intercept" +#define ANNOUNCER_IONSTORM "ionstorm" +#define ANNOUNCER_METEORS "meteors" +#define ANNOUNCER_NEWAI "newAI" +#define ANNOUNCER_OUTBREAK5 "outbreak5" +#define ANNOUNCER_OUTBREAK7 "outbreak7" +#define ANNOUNCER_POWEROFF "poweroff" +#define ANNOUNCER_POWERON "poweron" +#define ANNOUNCER_RADIATION "radiation" +#define ANNOUNCER_SHUTTLECALLED "shuttlecalled" +#define ANNOUNCER_SHUTTLEDOCK "shuttledock" +#define ANNOUNCER_SHUTTLERECALLED "shuttlerecalled" +#define ANNOUNCER_SPANOMALIES "spanomalies" + +/// Global list of all of our announcer keys. +GLOBAL_LIST_INIT(announcer_keys, list( + ANNOUNCER_AIMALF, + ANNOUNCER_ALIENS, + ANNOUNCER_ANIMES, + ANNOUNCER_GRANOMALIES, + ANNOUNCER_INTERCEPT, + ANNOUNCER_IONSTORM, + ANNOUNCER_METEORS, + ANNOUNCER_NEWAI, + ANNOUNCER_OUTBREAK5, + ANNOUNCER_OUTBREAK7, + ANNOUNCER_POWEROFF, + ANNOUNCER_POWERON, + ANNOUNCER_RADIATION, + ANNOUNCER_SHUTTLECALLED, + ANNOUNCER_SHUTTLEDOCK, + ANNOUNCER_SHUTTLERECALLED, + ANNOUNCER_SPANOMALIES, +)) diff --git a/code/__DEFINES/spans.dm b/code/__DEFINES/spans.dm index 45eae3ce76..b6b633d91a 100644 --- a/code/__DEFINES/spans.dm +++ b/code/__DEFINES/spans.dm @@ -44,6 +44,7 @@ #define span_greenannounce(str) ("" + str + "") #define span_greenteamradio(str) ("" + str + "") #define span_greentext(str) ("" + str + "") +#define span_gangradio(str) ("" + str + "") #define span_hear(str) ("" + str + "") #define span_hidden(str) ("") #define span_hierophant(str) ("" + str + "") @@ -55,6 +56,7 @@ #define span_icon(str) ("" + str + "") #define span_info(str) ("" + str + "") #define span_interface(str) ("" + str + "") +#define span_linkify(str) ("" + str + "") #define span_looc(str) ("" + str + "") #define span_medal(str) ("" + str + "") #define span_medradio(str) ("" + str + "") diff --git a/code/__DEFINES/species.dm b/code/__DEFINES/species.dm index 74ca459fa1..60aeb57513 100644 --- a/code/__DEFINES/species.dm +++ b/code/__DEFINES/species.dm @@ -3,7 +3,6 @@ #define SPECIES_ABDUCTOR "abductor" #define SPECIES_ANDROID "android" -#define SPECIES_ANGEL "angel" #define SPECIES_MAMMAL "mammal" #define SPECIES_MAMMAL_SYNTHETIC "mammal_synthetic" #define SPECIES_ARACHNID "arachnid" @@ -53,3 +52,14 @@ #define SPECIES_CATEGORY_SHADOW "shadow" #define SPECIES_CATEGORY_SKELETON "skeleton" #define SPECIES_CATEGORY_UNDEAD "undead" + + +//Species Wing Type Defines ---------------------- +#define SPECIES_WINGS_ANGEL list("Angel") +#define SPECIES_WINGS_DRAGON list("Dragon") //could also be considered demon wings or bat wings? +#define SPECIES_WINGS_ROBOT list("Robotic") +#define SPECIES_WINGS_INSECT list("Fly") //"hey when can we have something besides giant fly wings?" "when you sprite it!" +#define SPECIES_WINGS_SKELETAL list("Skeleton") +#define SPECIES_WINGS_MOTH list("Megamoth","Mothra") +#define SPECIES_WINGS_JELLY list("Angel") //no actual slime wings present right now, but I'm making this in the event someone wants to sprite slime wings. +#define SPECIES_WINGS_ALL list("Angel","Dragon","Robotic","Fly","Skeleton","Megamoth","Mothra") //keep this updated diff --git a/code/__DEFINES/station.dm b/code/__DEFINES/station.dm new file mode 100644 index 0000000000..0f6c4db003 --- /dev/null +++ b/code/__DEFINES/station.dm @@ -0,0 +1,9 @@ +#define STATION_TRAIT_POSITIVE 1 +#define STATION_TRAIT_NEUTRAL 2 +#define STATION_TRAIT_NEGATIVE 3 + + +#define STATION_TRAIT_ABSTRACT (1<<0) + +/// The data file that future station traits are stored in +#define FUTURE_STATION_TRAITS_FILE "data/future_station_traits.json" diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 5c6c8b143c..b1f7efbb9a 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -65,6 +65,8 @@ /// Blocks sprint #define STATUS_EFFECT_STAGGERED /datum/status_effect/staggered +#define STATUS_EFFECT_TASED_WEAK_NODMG /datum/status_effect/electrode/no_damage // no damage + #define STATUS_EFFECT_TASED_WEAK /datum/status_effect/electrode //not as crippling, just slows down #define STATUS_EFFECT_TASED /datum/status_effect/electrode/no_combat_mode //the affected has been tased, preventing fine muscle control @@ -117,6 +119,8 @@ #define STATUS_EFFECT_CLOUDSTRUCK /datum/status_effect/cloudstruck //blinds and applies an overlay. +#define STATUS_EFFECT_GAUNTLET_CONC /datum/status_effect/cgau_conc // it's a slowdown that really should only be applying to large simplemobs + /// shoves inflict this to indicate the next shove while this is in effect should disarm guns #define STATUS_EFFECT_OFF_BALANCE /datum/status_effect/off_balance @@ -132,6 +136,10 @@ #define STATUS_EFFECT_INLOVE /datum/status_effect/in_love //Displays you as being in love with someone else, and makes hearts appear around them. +#define STATUS_EFFECT_OFFERING /datum/status_effect/offering // you are offering up an item to people + +#define STATUS_EFFECT_HANDSHAKE /datum/status_effect/offering/secret_handshake // you are attempting to perform a secret Family handshake + ///////////// // SLIME // ///////////// @@ -144,4 +152,9 @@ // GROUPED // ///////////// +#define STASIS_MACHINE_EFFECT "stasis_machine" + #define STASIS_ASCENSION_EFFECT "heretic_ascension" + +/// If the incapacitated status effect will ignore a mob in stasis (stasis beds) +#define IGNORE_STASIS (1<<1) diff --git a/code/__DEFINES/strippable.dm b/code/__DEFINES/strippable.dm new file mode 100644 index 0000000000..a660e82784 --- /dev/null +++ b/code/__DEFINES/strippable.dm @@ -0,0 +1,31 @@ +// All of these must be matched in StripMenu.js. +#define STRIPPABLE_ITEM_HEAD "head" +#define STRIPPABLE_ITEM_BACK "back" +#define STRIPPABLE_ITEM_MASK "mask" +#define STRIPPABLE_ITEM_NECK "neck" +#define STRIPPABLE_ITEM_EYES "eyes" +#define STRIPPABLE_ITEM_EARS "ears" +#define STRIPPABLE_ITEM_JUMPSUIT "jumpsuit" +#define STRIPPABLE_ITEM_SUIT "suit" +#define STRIPPABLE_ITEM_GLOVES "gloves" +#define STRIPPABLE_ITEM_FEET "shoes" +#define STRIPPABLE_ITEM_SUIT_STORAGE "suit_storage" +#define STRIPPABLE_ITEM_ID "id" +#define STRIPPABLE_ITEM_BELT "belt" +#define STRIPPABLE_ITEM_LPOCKET "left_pocket" +#define STRIPPABLE_ITEM_RPOCKET "right_pocket" +#define STRIPPABLE_ITEM_LHAND "left_hand" +#define STRIPPABLE_ITEM_RHAND "right_hand" +#define STRIPPABLE_ITEM_HANDCUFFS "handcuffs" +#define STRIPPABLE_ITEM_LEGCUFFS "legcuffs" +#define STRIPPABLE_ITEM_CORGI_COLLAR "corgi_collar" +#define STRIPPABLE_ITEM_PARROT_HEADSET "parrot_headset" + +/// This slot is not obscured. +#define STRIPPABLE_OBSCURING_NONE 0 + +/// This slot is completely obscured, and cannot be accessed. +#define STRIPPABLE_OBSCURING_COMPLETELY 1 + +/// This slot can't be seen, but can be accessed. +#define STRIPPABLE_OBSCURING_HIDDEN 2 diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 30899c0ca2..49bad31a60 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -29,10 +29,10 @@ * if the arguments to addtimer are the same as an existing timer, it doesn't create a new timer, * and returns the id of the existing timer */ -#define TIMER_UNIQUE (1<<0) +#define TIMER_UNIQUE (1<<0) ///For unique timers: Replace the old timer rather then not start this one -#define TIMER_OVERRIDE (1<<1) +#define TIMER_OVERRIDE (1<<1) /** * Timing should be based on how timing progresses on clients, not the server. @@ -41,20 +41,23 @@ * should only be used in conjuction with things that have to progress client side, such as * animate() or sound() */ -#define TIMER_CLIENT_TIME (1<<2) +#define TIMER_CLIENT_TIME (1<<2) ///Timer can be stopped using deltimer() -#define TIMER_STOPPABLE (1<<3) +#define TIMER_STOPPABLE (1<<3) ///prevents distinguishing identical timers with the wait variable /// ///To be used with TIMER_UNIQUE -#define TIMER_NO_HASH_WAIT (1<<4) +#define TIMER_NO_HASH_WAIT (1<<4) ///Loops the timer repeatedly until qdeleted /// ///In most cases you want a subsystem instead, so don't use this unless you have a good reason -#define TIMER_LOOP (1<<5) +#define TIMER_LOOP (1<<5) + +///Delete the timer on parent datum Destroy() and when deltimer'd +#define TIMER_DELETE_ME (1<<6) ///Empty ID define #define TIMER_ID_NULL -1 @@ -108,8 +111,10 @@ #define INIT_ORDER_SOUNDS 83 #define INIT_ORDER_INSTRUMENTS 82 #define INIT_ORDER_VIS 80 +#define INIT_ORDER_SECURITY_LEVEL 79 // We need to load before events so that it has a security level to choose from. #define INIT_ORDER_ACHIEVEMENTS 77 #define INIT_ORDER_RESEARCH 75 +#define INIT_ORDER_STATION 74 //This is high priority because it manipulates a lot of the subsystems that will initialize after it. #define INIT_ORDER_EVENTS 70 #define INIT_ORDER_JOBS 65 #define INIT_ORDER_QUIRKS 60 @@ -188,6 +193,7 @@ #define FIRE_PRIORITY_CALLBACKS 600 // #define FIRE_PRIORITY_EXPLOSIONS 666 #define FIRE_PRIORITY_TIMER 700 +#define FIRE_PRIORITY_SOUND_LOOPS 800 #define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost. // SS runlevels diff --git a/code/__DEFINES/text.dm b/code/__DEFINES/text.dm new file mode 100644 index 0000000000..58c24747e0 --- /dev/null +++ b/code/__DEFINES/text.dm @@ -0,0 +1,5 @@ +/// Prepares a text to be used for maptext. Use this so it doesn't look hideous. +#define MAPTEXT(text) {"[##text]"} + +/// Macro from Lummox used to get height from a MeasureText proc +#define WXH_TO_HEIGHT(x) text2num(copytext(x, findtextEx(x, "x") + 1)) diff --git a/code/__DEFINES/time.dm b/code/__DEFINES/time.dm index 01990ddc17..252fe0910e 100644 --- a/code/__DEFINES/time.dm +++ b/code/__DEFINES/time.dm @@ -49,10 +49,16 @@ When using time2text(), please use "DDD" to find the weekday. Refrain from using #define TICKS *world.tick_lag +#define MILLISECONDS * 0.01 + #define DS2TICKS(DS) ((DS)/world.tick_lag) #define TICKS2DS(T) ((T) TICKS) +#define MS2DS(T) ((T) MILLISECONDS) + +#define DS2MS(T) ((T) * 100) + #define GAMETIMESTAMP(format, wtime) time2text(wtime, format) #define WORLDTIME2TEXT(format) GAMETIMESTAMP(format, world.time) #define WORLDTIMEOFDAY2TEXT(format) GAMETIMESTAMP(format, world.timeofday) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index eb9bdccc22..dbacbcbda5 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -70,6 +70,10 @@ #define HAS_TRAIT_NOT_FROM(target, trait, source) (target.status_traits ? (target.status_traits[trait] ? (length(target.status_traits[trait] - source) > 0) : FALSE) : FALSE) //mob traits +/// Prevents voluntary movement. +#define TRAIT_IMMOBILIZED "immobilized" +/// Prevents usage of manipulation appendages (picking, holding or using items, manipulating storage). +#define TRAIT_HANDS_BLOCKED "handsblocked" #define TRAIT_BLIND "blind" #define TRAIT_MUTE "mute" #define TRAIT_EMOTEMUTE "emotemute" @@ -104,6 +108,7 @@ #define TRAIT_RESISTCOLD "resist_cold" #define TRAIT_RESISTHIGHPRESSURE "resist_high_pressure" #define TRAIT_RESISTLOWPRESSURE "resist_low_pressure" +#define TRAIT_LOWPRESSURECOOLING "low_pressure_cooling" #define TRAIT_BOMBIMMUNE "bomb_immunity" #define TRAIT_RADIMMUNE "rad_immunity" #define TRAIT_GENELESS "geneless" @@ -121,6 +126,7 @@ #define TRAIT_ROBOTIC_ORGANISM "robotic_organism" #define TRAIT_ROBOT_RADSHIELDING "robot_radshielding" #define TRAIT_NOBREATH "no_breath" +#define TRAIT_AUXILIARY_LUNGS "auxiliary_lungs" //Lungs not neccessary required due to nobreath, but provides some other helpful function. #define TRAIT_ANTIMAGIC "anti_magic" #define TRAIT_HOLY "holy" #define TRAIT_DEPRESSION "depression" @@ -152,6 +158,18 @@ #define TRAIT_CALCIUM_HEALER "calcium_healer" #define TRAIT_MAGIC_CHOKE "magic_choke" #define TRAIT_CAPTAIN_METABOLISM "captain-metabolism" +/// Like antimagic, but doesn't block the user from casting +#define TRAIT_ANTIMAGIC_NO_SELFBLOCK "anti_magic_no_selfblock" +/// Gives us turf, mob and object vision through walls +#define TRAIT_XRAY_VISION "xray_vision" +/// Gives us mob vision through walls and slight night vision +#define TRAIT_THERMAL_VISION "thermal_vision" +/// Gives us turf vision through walls and slight night vision +#define TRAIT_MESON_VISION "meson_vision" +/// Gives us Night vision +#define TRAIT_TRUE_NIGHT_VISION "true_night_vision" +/// Lets us scan reagents +#define TRAIT_REAGENT_SCANNER "reagent_scanner" #define TRAIT_ABDUCTOR_TRAINING "abductor-training" #define TRAIT_ABDUCTOR_SCIENTIST_TRAINING "abductor-scientist-training" #define TRAIT_SURGEON "surgeon" @@ -173,6 +191,8 @@ #define TRAIT_DWARF "dwarf" #define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance" #define TRAIT_AGEUSIA "ageusia" +#define TRAIT_ANOSMIA "anosmia" +#define TRAIT_GOODSMELL "super_smeller" #define TRAIT_HEAVY_SLEEPER "heavy_sleeper" #define TRAIT_NIGHT_VISION "night_vision" #define TRAIT_LIGHT_STEP "light_step" @@ -200,12 +220,11 @@ #define TRAIT_FRIENDLY "friendly" #define TRAIT_SNOB "snob" #define TRAIT_MULTILINGUAL "multilingual" +#define TRAIT_HEARING_SENSITIVE "hearing_sensitive" #define TRAIT_CULT_EYES "cult_eyes" #define TRAIT_AUTO_CATCH_ITEM "auto_catch_item" #define TRAIT_CLOWN_MENTALITY "clown_mentality" // The future is now, clownman. #define TRAIT_FREESPRINT "free_sprinting" -#define TRAIT_XRAY_VISION "xray_vision" -#define TRAIT_THERMAL_VISION "thermal_vision" #define TRAIT_NO_TELEPORT "no-teleport" //you just can't #define TRAIT_NO_INTERNALS "no-internals" #define TRAIT_TOXIC_ALCOHOL "alcohol_intolerance" @@ -222,6 +241,12 @@ /// forces us to not render our overlays #define TRAIT_HUMAN_NO_RENDER "human_no_render" #define TRAIT_TRASHCAN "trashcan" +///Used for fireman carry to have mobe not be dropped when passing by a prone individual. +#define TRAIT_BEING_CARRIED "being_carried" +#define TRAIT_GLASS_BONES "glass_bones" +#define TRAIT_PAPER_SKIN "paper_skin" +//used because it's more reliable than checking for the component +#define TRAIT_DULLAHAN "dullahan" // mobility flag traits // IN THE FUTURE, IT WOULD BE NICE TO DO SOMETHING SIMILAR TO https://github.com/tgstation/tgstation/pull/48923/files (ofcourse not nearly the same because I have my.. thoughts on it) @@ -248,6 +273,14 @@ /// Prevents sprinting from being active. #define TRAIT_SPRINT_LOCKED "sprint_locked" +/// Weather immunities, also protect mobs inside them. +#define TRAIT_LAVA_IMMUNE "lava_immune" //Used by lava turfs and The Floor Is Lava. +#define TRAIT_ASHSTORM_IMMUNE "ashstorm_immune" +#define TRAIT_SNOWSTORM_IMMUNE "snowstorm_immune" +#define TRAIT_RADSTORM_IMMUNE "radstorm_immune" +#define TRAIT_VOIDSTORM_IMMUNE "voidstorm_immune" +#define TRAIT_WEATHER_IMMUNE "weather_immune" //Immune to ALL weather effects. + //non-mob traits #define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it #define VEHICLE_TRAIT "vehicle" // inherited from riding vehicles @@ -283,10 +316,11 @@ #define GHOSTROLE_TRAIT "ghostrole" #define APHRO_TRAIT "aphro" #define BLOODSUCKER_TRAIT "bloodsucker" -#define SHOES_TRAIT "shoes" //inherited from your sweet kicks #define GLOVE_TRAIT "glove" //inherited by your cool gloves +#define SHOES_TRAIT "shoes" //inherited from your sweet kicks #define BOOK_TRAIT "granter (book)" // knowledge is power #define TURF_TRAIT "turf" +#define STATION_TRAIT "station-trait" // unique trait sources, still defines #define STATUE_TRAIT "statue" @@ -343,3 +377,25 @@ #define STICKY_NODROP "sticky-nodrop" //sticky nodrop sounds like a bad soundcloud rapper's name #define TRAIT_SACRIFICED "sacrificed" //Makes sure that people cant be cult sacrificed twice. #define TRAIT_SPACEWALK "spacewalk" +#define TRAIT_SALT_SENSITIVE "salt_sensitive" + + +/// obtained from mapping helper +#define MAPPING_HELPER_TRAIT "mapping-helper" +/// Trait associated with mafia +#define MAFIA_TRAIT "mafia" + +///Traits given by station traits +#define STATION_TRAIT_BANANIUM_SHIPMENTS "station_trait_bananium_shipments" +#define STATION_TRAIT_UNNATURAL_ATMOSPHERE "station_trait_unnatural_atmosphere" +#define STATION_TRAIT_UNIQUE_AI "station_trait_unique_ai" +#define STATION_TRAIT_CARP_INFESTATION "station_trait_carp_infestation" +#define STATION_TRAIT_PREMIUM_INTERNALS "station_trait_premium_internals" +#define STATION_TRAIT_LATE_ARRIVALS "station_trait_late_arrivals" +#define STATION_TRAIT_RANDOM_ARRIVALS "station_trait_random_arrivals" +#define STATION_TRAIT_HANGOVER "station_trait_hangover" +#define STATION_TRAIT_FILLED_MAINT "station_trait_filled_maint" +#define STATION_TRAIT_EMPTY_MAINT "station_trait_empty_maint" +#define STATION_TRAIT_PDA_GLITCHED "station_trait_pda_glitched" +/// Trait applied by MODsuits. +#define MOD_TRAIT "mod" diff --git a/code/__DEFINES/uplink.dm b/code/__DEFINES/uplink.dm new file mode 100644 index 0000000000..4aad3e6b88 --- /dev/null +++ b/code/__DEFINES/uplink.dm @@ -0,0 +1,10 @@ +// These are used in uplink_devices.dm to determine whether or not an item is purchasable. + +/// This item is purchasable to traitors +#define UPLINK_TRAITORS (1 << 0) + +/// This item is purchasable to nuke ops +#define UPLINK_NUKE_OPS (1 << 1) + +/// This item is purchasable to clown ops +#define UPLINK_CLOWN_OPS (1 << 2) diff --git a/code/__DEFINES/vehicles.dm b/code/__DEFINES/vehicles.dm index 48383546b9..0255327ed9 100644 --- a/code/__DEFINES/vehicles.dm +++ b/code/__DEFINES/vehicles.dm @@ -1,9 +1,25 @@ -//Vehicle control flags +//Vehicle control flags. control flags describe access to actions in a vehicle. -#define VEHICLE_CONTROL_PERMISSION 1 -#define VEHICLE_CONTROL_DRIVE 2 -#define VEHICLE_CONTROL_KIDNAPPED 4 //Can't leave vehicle voluntarily, has to resist. +///controls the vehicles movement +#define VEHICLE_CONTROL_DRIVE (1<<0) +///Can't leave vehicle voluntarily, has to resist. +#define VEHICLE_CONTROL_KIDNAPPED (1<<1) +///melee attacks/shoves a vehicle may have +#define VEHICLE_CONTROL_MELEE (1<<2) +///using equipment/weapons on the vehicle +#define VEHICLE_CONTROL_EQUIPMENT (1<<3) +///changing around settings and the like. +#define VEHICLE_CONTROL_SETTINGS (1<<4) -//Car trait flags -#define CAN_KIDNAP 1 +///ez define for giving a single pilot mech all the flags it needs. +#define FULL_MECHA_CONTROL ALL + + +//car_traits flags +///Will this car kidnap people by ramming into them? +#define CAN_KIDNAP (1<<0) + +#define CLOWN_CANNON_INACTIVE 0 +#define CLOWN_CANNON_BUSY 1 +#define CLOWN_CANNON_READY 2 diff --git a/code/__DEFINES/vote.dm b/code/__DEFINES/vote.dm index 88e70b884e..bbe6ddf2b7 100644 --- a/code/__DEFINES/vote.dm +++ b/code/__DEFINES/vote.dm @@ -5,6 +5,9 @@ #define HIGHEST_MEDIAN_VOTING "HIGHEST_MEDIAN" #define INSTANT_RUNOFF_VOTING "IRV" +#define VOTE_TRANSFER "Initiate Crew Transfer" +#define VOTE_CONTINUE "Continue Playing" + #define SHOW_RESULTS (1<<0) #define SHOW_VOTES (1<<1) #define SHOW_WINNER (1<<2) diff --git a/code/__HELPERS/AStar.dm b/code/__HELPERS/AStar.dm deleted file mode 100644 index 5e03d9b350..0000000000 --- a/code/__HELPERS/AStar.dm +++ /dev/null @@ -1,209 +0,0 @@ -/* -A Star pathfinding algorithm -Returns a list of tiles forming a path from A to B, taking dense objects as well as walls, and the orientation of -windows along the route into account. -Use: -your_list = AStar(start location, end location, moving atom, distance proc, max nodes, maximum node depth, minimum distance to target, adjacent proc, atom id, turfs to exclude, check only simulated) - -Optional extras to add on (in order): -Distance proc : the distance used in every A* calculation (length of path and heuristic) -MaxNodes: The maximum number of nodes the returned path can be (0 = infinite) -Maxnodedepth: The maximum number of nodes to search (default: 30, 0 = infinite) -Mintargetdist: Minimum distance to the target before path returns, could be used to get -near a target, but not right to it - for an AI mob with a gun, for example. -Adjacent proc : returns the turfs to consider around the actually processed node -Simulated only : whether to consider unsimulated turfs or not (used by some Adjacent proc) - -Also added 'exclude' turf to avoid travelling over; defaults to null - -Actual Adjacent procs : - - /turf/proc/reachableAdjacentTurfs : returns reachable turfs in cardinal directions (uses simulated_only) - - /turf/proc/reachableAdjacentAtmosTurfs : returns turfs in cardinal directions reachable via atmos - -*/ -#define PF_TIEBREAKER 0.005 -//tiebreker weight.To help to choose between equal paths -////////////////////// -//datum/PathNode object -////////////////////// -#define MASK_ODD 85 -#define MASK_EVEN 170 - - -//A* nodes variables -/datum/PathNode - var/turf/source //turf associated with the PathNode - var/datum/PathNode/prevNode //link to the parent PathNode - var/f //A* Node weight (f = g + h) - var/g //A* movement cost variable - var/h //A* heuristic variable - var/nt //count the number of Nodes traversed - var/bf //bitflag for dir to expand.Some sufficiently advanced motherfuckery - -/datum/PathNode/New(s,p,pg,ph,pnt,_bf) - source = s - prevNode = p - g = pg - h = ph - f = g + h*(1+ PF_TIEBREAKER) - nt = pnt - bf = _bf - -/datum/PathNode/proc/setp(p,pg,ph,pnt) - prevNode = p - g = pg - h = ph - f = g + h*(1+ PF_TIEBREAKER) - nt = pnt - -/datum/PathNode/proc/calc_f() - f = g + h - -////////////////////// -//A* procs -////////////////////// - -//the weighting function, used in the A* algorithm -/proc/PathWeightCompare(datum/PathNode/a, datum/PathNode/b) - return a.f - b.f - -//reversed so that the Heap is a MinHeap rather than a MaxHeap -/proc/HeapPathWeightCompare(datum/PathNode/a, datum/PathNode/b) - return b.f - a.f - -//wrapper that returns an empty list if A* failed to find a path -/proc/get_path_to(caller, end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id=null, turf/exclude=null, simulated_only = 1) - var/l = SSpathfinder.mobs.getfree(caller) - while(!l) - stoplag(3) - l = SSpathfinder.mobs.getfree(caller) - var/list/path = AStar(caller, end, dist, maxnodes, maxnodedepth, mintargetdist, adjacent,id, exclude, simulated_only) - - SSpathfinder.mobs.found(l) - if(!path) - path = list() - return path - -/proc/cir_get_path_to(caller, end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id=null, turf/exclude=null, simulated_only = 1) - var/l = SSpathfinder.circuits.getfree(caller) - while(!l) - stoplag(3) - l = SSpathfinder.circuits.getfree(caller) - var/list/path = AStar(caller, end, dist, maxnodes, maxnodedepth, mintargetdist, adjacent,id, exclude, simulated_only) - SSpathfinder.circuits.found(l) - if(!path) - path = list() - return path - -/proc/AStar(caller, _end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id=null, turf/exclude=null, simulated_only = 1) - //sanitation - var/turf/end = get_turf(_end) - var/turf/start = get_turf(caller) - if(!start || !end) - stack_trace("Invalid A* start or destination") - return 0 - if( start.z != end.z || start == end ) //no pathfinding between z levels - return 0 - if(maxnodes) - //if start turf is farther than maxnodes from end turf, no need to do anything - if(call(start, dist)(end) > maxnodes) - return 0 - maxnodedepth = maxnodes //no need to consider path longer than maxnodes - var/datum/Heap/open = new /datum/Heap(/proc/HeapPathWeightCompare) //the open list - var/list/openc = new() //open list for node check - var/list/path = null //the returned path, if any - //initialization - var/datum/PathNode/cur = new /datum/PathNode(start,null,0,call(start,dist)(end),0,15,1)//current processed turf - open.Insert(cur) - openc[start] = cur - //then run the main loop - while(!open.IsEmpty() && !path) - cur = open.Pop() //get the lower f turf in the open list - //get the lower f node on the open list - //if we only want to get near the target, check if we're close enough - var/closeenough - if(mintargetdist) - closeenough = call(cur.source,dist)(end) <= mintargetdist - - - //found the target turf (or close enough), let's create the path to it - if(cur.source == end || closeenough) - path = new() - path.Add(cur.source) - while(cur.prevNode) - cur = cur.prevNode - path.Add(cur.source) - break - //get adjacents turfs using the adjacent proc, checking for access with id - if((!maxnodedepth)||(cur.nt <= maxnodedepth))//if too many steps, don't process that path - for(var/i = 0 to 3) - var/f= 1<>1) //getting reverse direction throught swapping even and odd bits.((f & 01010101)<<1)|((f & 10101010)>>1) - var/newg = cur.g + call(cur.source,dist)(T) - if(CN) - //is already in open list, check if it's a better way from the current turf - CN.bf &= 15^r //we have no closed, so just cut off exceed dir.00001111 ^ reverse_dir.We don't need to expand to checked turf. - if((newg < CN.g) ) - if(call(cur.source,adjacent)(caller, T, id, simulated_only)) - CN.setp(cur,newg,CN.h,cur.nt+1) - open.ReSort(CN)//reorder the changed element in the list - else - //is not already in open list, so add it - if(call(cur.source,adjacent)(caller, T, id, simulated_only)) - CN = new(T,cur,newg,call(T,dist)(end),cur.nt+1,15^r) - open.Insert(CN) - openc[T] = CN - cur.bf = 0 - CHECK_TICK - //reverse the path to get it from start to finish - if(path) - for(var/i = 1 to round(0.5*path.len)) - path.Swap(i,path.len-i+1) - openc = null - //cleaning after us - return path - -//Returns adjacent turfs in cardinal directions that are reachable -//simulated_only controls whether only simulated turfs are considered or not - -/turf/proc/reachableAdjacentTurfs(caller, ID, simulated_only) - var/list/L = new() - var/turf/T - var/static/space_type_cache = typecacheof(/turf/open/space) - - for(var/k in 1 to GLOB.cardinals.len) - T = get_step(src,GLOB.cardinals[k]) - if(!T || (simulated_only && space_type_cache[T.type])) - continue - if(!T.density && !LinkBlockedWithAccess(T,caller, ID)) - L.Add(T) - return L - -/turf/proc/reachableTurftest(caller, var/turf/T, ID, simulated_only) - if(T && !T.density && !(simulated_only && SSpathfinder.space_type_cache[T.type]) && !LinkBlockedWithAccess(T,caller, ID)) - return TRUE - -//Returns adjacent turfs in cardinal directions that are reachable via atmos -/turf/proc/reachableAdjacentAtmosTurfs() - return atmos_adjacent_turfs - -/turf/proc/LinkBlockedWithAccess(turf/T, caller, ID) - var/adir = get_dir(src, T) - var/rdir = ((adir & MASK_ODD)<<1)|((adir & MASK_EVEN)>>1) - for(var/obj/structure/window/W in src) - if(!W.CanAStarPass(ID, adir)) - return 1 - for(var/obj/machinery/door/window/W in src) - if(!W.CanAStarPass(ID, adir)) - return 1 - for(var/obj/O in T) - if(!O.CanAStarPass(ID, rdir, caller)) - return 1 - - return 0 diff --git a/code/__HELPERS/_cit_helpers.dm b/code/__HELPERS/_cit_helpers.dm index a5ffda36f9..c4a7b051de 100644 --- a/code/__HELPERS/_cit_helpers.dm +++ b/code/__HELPERS/_cit_helpers.dm @@ -56,6 +56,7 @@ GLOBAL_LIST_EMPTY(ipc_antennas_list) GLOBAL_LIST_EMPTY(genitals_list) GLOBAL_LIST_EMPTY(cock_shapes_list) GLOBAL_LIST_EMPTY(balls_shapes_list) +GLOBAL_LIST_EMPTY(butt_shapes_list) GLOBAL_LIST_EMPTY(breasts_shapes_list) GLOBAL_LIST_EMPTY(vagina_shapes_list) //longcat memes. @@ -124,6 +125,11 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE) return TRUE return FALSE +/mob/living/carbon/proc/has_butt() + if(getorganslot(ORGAN_SLOT_BUTT)) + return TRUE + return FALSE + /mob/living/carbon/proc/is_groin_exposed(list/L) if(!L) L = get_equipped_items() @@ -157,7 +163,9 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE) if(H.gender == MALE) H.give_genital(/obj/item/organ/genital/penis) H.give_genital(/obj/item/organ/genital/testicles) + H.give_genital(/obj/item/organ/genital/butt) else H.give_genital(/obj/item/organ/genital/vagina) H.give_genital(/obj/item/organ/genital/womb) H.give_genital(/obj/item/organ/genital/breasts) + H.give_genital(/obj/item/organ/genital/butt) diff --git a/code/__HELPERS/_extools_api.dm b/code/__HELPERS/_extools_api.dm index 7bff3f06c0..d52ad5bd6f 100644 --- a/code/__HELPERS/_extools_api.dm +++ b/code/__HELPERS/_extools_api.dm @@ -7,14 +7,15 @@ /proc/auxtools_stack_trace(msg) CRASH(msg) -GLOBAL_LIST_EMPTY(auxtools_initialized) +//glob doesn't exist yet at some gas new calls, imma use it anyways +GLOBAL_REAL_VAR(list/__auxtools_initialized) = list() #define AUXTOOLS_CHECK(LIB)\ - if (!GLOB.auxtools_initialized[LIB]) {\ + if (!__auxtools_initialized[LIB]) {\ if (fexists(LIB)) {\ var/string = call(LIB,"auxtools_init")();\ if(findtext(string, "SUCCESS")) {\ - GLOB.auxtools_initialized[LIB] = TRUE;\ + __auxtools_initialized[LIB] = TRUE;\ } else {\ CRASH(string);\ }\ @@ -24,7 +25,7 @@ GLOBAL_LIST_EMPTY(auxtools_initialized) }\ #define AUXTOOLS_SHUTDOWN(LIB)\ - if (GLOB.auxtools_initialized[LIB] && fexists(LIB)){\ + if (__auxtools_initialized[LIB] && fexists(LIB)){\ call(LIB,"auxtools_shutdown")();\ - GLOB.auxtools_initialized[LIB] = FALSE;\ + __auxtools_initialized[LIB] = FALSE;\ }\ diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index 2d0601d839..5b457dd9cc 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -1,31 +1,58 @@ /* * Holds procs to help with list operations * Contains groups: - * Misc - * Sorting + * Misc + * Sorting */ /* * Misc */ -#define LAZYINITLIST(L) if (!L) L = list() +// Generic listoflist safe add and removal macros: +///If value is a list, wrap it in a list so it can be used with list add/remove operations +#define LIST_VALUE_WRAP_LISTS(value) (islist(value) ? list(value) : value) +///Add an untyped item to a list, taking care to handle list items by wrapping them in a list to remove the footgun +#define UNTYPED_LIST_ADD(list, item) (list += LIST_VALUE_WRAP_LISTS(item)) +///Remove an untyped item to a list, taking care to handle list items by wrapping them in a list to remove the footgun +#define UNTYPED_LIST_REMOVE(list, item) (list -= LIST_VALUE_WRAP_LISTS(item)) + +#define LAZYINITLIST(L) if (!L) { L = list(); } #define UNSETEMPTY(L) if (L && !length(L)) L = null -#define LAZYCOPY(L) (L ? L.Copy() : list() ) +///Like LAZYCOPY - copies an input list if the list has entries, If it doesn't the assigned list is nulled +#define LAZYLISTDUPLICATE(L) (L ? L.Copy() : null ) #define LAZYREMOVE(L, I) if(L) { L -= I; if(!length(L)) { L = null; } } +//ambition start +#define LAZYCUT(L, S, E) if((length(L) >= S) && (E == 0 || length(L) >= (E - 1))) { L.Cut(S, E); if(!length(L)) { L = null; } } +//ambition end #define LAZYADD(L, I) if(!L) { L = list(); } L += I; #define LAZYOR(L, I) if(!L) { L = list(); } L |= I; #define LAZYFIND(L, V) (L ? L.Find(V) : 0) +///returns L[I] if L exists and I is a valid index of L, runtimes if L is not a list #define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= length(L) ? L[I] : null) : L[I]) : null) #define LAZYSET(L, K, V) if(!L) { L = list(); } L[K] = V; #define LAZYLEN(L) length(L) +///This is used to add onto lazy assoc list when the value you're adding is a /list/. This one has extra safety over lazyaddassoc because the value could be null (and thus cant be used to += objects) +#define LAZYADDASSOCLIST(L, K, V) if(!L) { L = list(); } L[K] += list(V); //Sets a list to null #define LAZYNULL(L) L = null -#define LAZYCLEARLIST(L) if(L) L.Cut() -#define SANITIZE_LIST(L) ( islist(L) ? L : list() ) -#define reverseList(L) reverseRange(L.Copy()) +#define LAZYADDASSOC_TG(L, K, V) if(!L) { L = list(); } L[K] += V; +///This is used to add onto lazy assoc list when the value you're adding is a /list/. This one has extra safety over lazyaddassoc because the value could be null (and thus cant be used to += objects) #define LAZYADDASSOC(L, K, V) if(!L) { L = list(); } L[K] += list(V); #define LAZYREMOVEASSOC(L, K, V) if(L) { if(L[K]) { L[K] -= V; if(!length(L[K])) L -= K; } if(!length(L)) L = null; } +#define LAZYACCESSASSOC(L, I, K) L ? L[I] ? L[I][K] ? L[I][K] : null : null : null +#define QDEL_LAZYLIST(L) for(var/I in L) qdel(I); L = null; +//These methods don't null the list +#define LAZYCOPY(L) (L ? L.Copy() : list() ) //Use LAZYLISTDUPLICATE instead if you want it to null with no entries +#define LAZYCLEARLIST(L) if(L) L.Cut() // Consider LAZYNULL instead +#define SANITIZE_LIST(L) ( islist(L) ? L : list() ) +#define reverseList(L) reverseRange(L.Copy()) + +/// Performs an insertion on the given lazy list with the given key and value. If the value already exists, a new one will not be made. +#define LAZYORASSOCLIST(lazy_list, key, value) \ + LAZYINITLIST(lazy_list); \ + LAZYINITLIST(lazy_list[key]); \ + lazy_list[key] |= value; /// Passed into BINARY_INSERT to compare keys #define COMPARE_KEY __BIN_LIST[__BIN_MID] @@ -68,7 +95,7 @@ } while(FALSE) //Returns a list in plain english as a string -/proc/english_list(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "") +/proc/english_list(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" ) var/total = length(input) switch(total) if (0) @@ -91,6 +118,7 @@ /** * English_list but associative supporting. Higher overhead. + * @depricated */ /proc/english_list_assoc(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "") var/total = length(input) @@ -118,6 +146,7 @@ return "[output][and_text][input[index]]" //Returns list element or null. Should prevent "index out of bounds" error. +/// @depricated /proc/listgetindex(list/L, index) if(LAZYLEN(L)) if(isnum(index) && ISINTEGER(index)) @@ -128,17 +157,19 @@ return //Return either pick(list) or null if list is not of type /list or is empty +/// @depricated /proc/safepick(list/L) if(LAZYLEN(L)) return pick(L) //Checks if the list is empty +/// @depricated /proc/isemptylist(list/L) if(!L.len) return TRUE return FALSE -//Checks for specific types in a list +//Checks for specific types in a listc /proc/is_type_in_list(atom/A, list/L) if(!LAZYLEN(L) || !A) return FALSE @@ -172,53 +203,52 @@ /proc/typecache_filter_list(list/atoms, list/typecache) RETURN_TYPE(/list) . = list() - for(var/thing in atoms) - var/atom/A = thing + for(var/atom/A as anything in atoms) if (typecache[A.type]) . += A /proc/typecache_filter_list_reverse(list/atoms, list/typecache) RETURN_TYPE(/list) . = list() - for(var/thing in atoms) - var/atom/A = thing - if(!typecache[A.type]) - . += A + for(var/atom/atom as anything in atoms) + if(!typecache[atom.type]) + . += atom /proc/typecache_filter_multi_list_exclusion(list/atoms, list/typecache_include, list/typecache_exclude) . = list() - for(var/thing in atoms) - var/atom/A = thing - if(typecache_include[A.type] && !typecache_exclude[A.type]) - . += A + for(var/atom/atom as anything in atoms) + if(typecache_include[atom.type] && !typecache_exclude[atom.type]) + . += atom -//Like typesof() or subtypesof(), but returns a typecache instead of a list +///Like typesof() or subtypesof(), but returns a typecache instead of a list /proc/typecacheof(path, ignore_root_path, only_root_path = FALSE) if(ispath(path)) - var/list/types = list() + var/list/types + var/list/output = list() if(only_root_path) - types = list(path) + output[path] = TRUE else types = ignore_root_path ? subtypesof(path) : typesof(path) - var/list/L = list() - for(var/T in types) - L[T] = TRUE - return L + for(var/T in types) + output[T] = TRUE + return output else if(islist(path)) var/list/pathlist = path - var/list/L = list() + var/list/output = list() if(ignore_root_path) - for(var/P in pathlist) - for(var/T in subtypesof(P)) - L[T] = TRUE + for(var/current_path in pathlist) + for(var/subtype in subtypesof(current_path)) + output[subtype] = TRUE + return output + + if(only_root_path) + for(var/current_path in pathlist) + output[current_path] = TRUE else - for(var/P in pathlist) - if(only_root_path) - L[P] = TRUE - else - for(var/T in typesof(P)) - L[T] = TRUE - return L + for(var/current_path in pathlist) + for(var/subpath in typesof(current_path)) + output[subpath] = TRUE + return output /proc/typecacheof_assoc_list(list/pathlist, ignore_root_path = FALSE) . = list() @@ -277,9 +307,10 @@ //Picks a random element from a list based on a weighting system: //1. Adds up the total of weights for each element -//2. Gets the total from 0% to 100% of previous total value. +//2. Gets a number between 1 and that total //3. For each element in the list, subtracts its weighting from that number //4. If that makes the number 0 or less, return that element. +//Will output null sometimes if you use decimals (e.g. 0.1 instead of 10) as rand() uses integers, not floats /proc/pickweight(list/L, base_weight = 1) var/total = 0 var/item @@ -288,12 +319,30 @@ L[item] = base_weight total += L[item] - total = rand() * total + total = rand(base_weight, total) for (item in L) - total -= L[item] + total -=L [item] if (total <= 0) return item + return null + +/proc/pickweightAllowZero(list/L) //The original pickweight proc will sometimes pick entries with zero weight. I'm not sure if changing the original will break anything, so I left it be. + var/total = 0 + var/item + for (item in L) + if (!L[item]) + L[item] = 0 + total += L[item] + + total = rand(0, total) + for (item in L) + total -=L [item] + if (total <= 0 && L[item]) + return item + + return null + //Picks a number of elements from a list based on weight. //This is highly optimised and good for things like grabbing 200 items from a list of 40,000 //Much more efficient than many pickweight calls @@ -349,13 +398,13 @@ //Results will have a length of quality return results -//Pick a random element from the list and remove it from the list. +/// Pick a random element from the list and remove it from the list. /proc/pick_n_take(list/L) RETURN_TYPE(L[_].type) if(L.len) var/picked = rand(1,L.len) . = L[picked] - L.Cut(picked,picked+1) //Cut is far more efficient that Remove() + L.Cut(picked,picked+1) //Cut is far more efficient that Remove() //Pick a random element from the list by weight and remove it from the list. //Result is returned as a list in the format list(key, value) @@ -451,7 +500,7 @@ //uses sortList() but uses the var's name specifically. This should probably be using mergeAtom() instead /proc/sortNames(list/L, order=1) - return sortTim(L, order >= 0 ? /proc/cmp_name_asc : /proc/cmp_name_dsc) + return sortTim(L.Copy(), order >= 0 ? /proc/cmp_name_asc : /proc/cmp_name_dsc) //Converts a bitfield to a list of numbers (or words if a wordlist is provided) @@ -487,10 +536,12 @@ if (L[i] == val) .++ +/// Returns datum/data/record /proc/find_record(field, value, list/L) for(var/datum/data/record/R in L) if(R.fields[field] == value) return R + return null //Move a single element from position fromIndex within a list, to position toIndex @@ -500,10 +551,10 @@ //fromIndex and toIndex must be in the range [1,L.len+1] //This will preserve associations ~Carnie /proc/moveElement(list/L, fromIndex, toIndex) - if(fromIndex == toIndex || fromIndex+1 == toIndex) //no need to move + if(fromIndex == toIndex || fromIndex+1 == toIndex) //no need to move return if(fromIndex > toIndex) - ++fromIndex //since a null will be inserted before fromIndex, the index needs to be nudged right by one + ++fromIndex //since a null will be inserted before fromIndex, the index needs to be nudged right by one L.Insert(toIndex, null) L.Swap(fromIndex, toIndex) @@ -515,10 +566,10 @@ //This will preserve associations ~Carnie /proc/moveRange(list/L, fromIndex, toIndex, len=1) var/distance = abs(toIndex - fromIndex) - if(len >= distance) //there are more elements to be moved than the distance to be moved. Therefore the same result can be achieved (with fewer operations) by moving elements between where we are and where we are going. The result being, our range we are moving is shifted left or right by dist elements + if(len >= distance) //there are more elements to be moved than the distance to be moved. Therefore the same result can be achieved (with fewer operations) by moving elements between where we are and where we are going. The result being, our range we are moving is shifted left or right by dist elements if(fromIndex <= toIndex) - return //no need to move - fromIndex += len //we want to shift left instead of right + return //no need to move + fromIndex += len //we want to shift left instead of right for(var/i=0, i distance) //there is an overlap, therefore swapping each element will require more swaps than inserting new elements + if(len > distance) //there is an overlap, therefore swapping each element will require more swaps than inserting new elements if(fromIndex < toIndex) toIndex += len else @@ -584,6 +635,12 @@ if(D.vars[varname] == value) return D +//remove all nulls from a list +/proc/removeNullsFromList(list/L) + while(L.Remove(null)) + continue + return L + //Copies a list, and all lists inside it recusively //Does not copy any other reference type /proc/deepCopyList(list/l) @@ -616,11 +673,6 @@ used_key_list[input_key] = 1 return input_key -#if DM_VERSION > 514 -#error Remie said that lummox was adding a way to get a lists -#error contents via list.values, if that is true remove this -#error otherwise, update the version and bug lummox -#endif //Flattens a keyed list into a list of it's contents /proc/flatten_list(list/key_list) if(!islist(key_list)) @@ -697,6 +749,29 @@ ret += key return ret +/proc/compare_list(list/l,list/d) + if(!islist(l) || !islist(d)) + return FALSE + + if(l.len != d.len) + return FALSE + + for(var/i in 1 to l.len) + if(l[i] != d[i]) + return FALSE + + return TRUE + +#define LAZY_LISTS_OR(left_list, right_list)\ + ( length(left_list)\ + ? length(right_list)\ + ? (left_list | right_list)\ + : left_list.Copy()\ + : length(right_list)\ + ? right_list.Copy()\ + : null\ + ) + /proc/is_type_in_ref_list(path, list/L) if(!ispath(path))//not a path return diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 8464e373d5..58b7516be3 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -1,9 +1,12 @@ //wrapper macros for easier grepping #define DIRECT_OUTPUT(A, B) A << B +#define DIRECT_INPUT(A, B) A >> B #define SEND_IMAGE(target, image) DIRECT_OUTPUT(target, image) #define SEND_SOUND(target, sound) DIRECT_OUTPUT(target, sound) #define SEND_TEXT(target, text) DIRECT_OUTPUT(target, text) #define WRITE_FILE(file, text) DIRECT_OUTPUT(file, text) +#define READ_FILE(file, text) DIRECT_INPUT(file, text) + #ifdef EXTOOLS_LOGGING // proc hooked, so we can just put in standard TRUE and FALSE #define WRITE_LOG(log, text) extools_log_write(log,text,TRUE) @@ -13,6 +16,7 @@ #define WRITE_LOG(log, text) rustg_log_write(log, text, "true") #define WRITE_LOG_NO_FORMAT(log, text) rustg_log_write(log, text, "false") #endif + //print a warning message to world.log #define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [UNLINT(src)] usr: [usr].") /proc/warning(msg) @@ -38,6 +42,12 @@ SEND_TEXT(world.log, text) #endif +#ifdef REFERENCE_TRACKING_LOG +#define log_reftracker(msg) log_world("## REF SEARCH [msg]") +#else +#define log_reftracker(msg) +#endif + /* Items with ADMINPRIVATE prefixed are stripped from public logs. */ /proc/log_admin(text) @@ -67,6 +77,10 @@ if (CONFIG_GET(flag/log_game)) WRITE_LOG(GLOB.world_game_log, "GAME: [text]") +/proc/log_mecha(text) + if (CONFIG_GET(flag/log_mecha)) + WRITE_LOG(GLOB.world_mecha_log, "MECHA: [text]") + /proc/log_virus(text) if (CONFIG_GET(flag/log_virus)) WRITE_LOG(GLOB.world_virus_log, "VIRUS: [text]") @@ -78,6 +92,19 @@ if (CONFIG_GET(flag/log_access)) WRITE_LOG(GLOB.world_game_log, "ACCESS: [text]") +/** + * Writes to a special log file if the log_suspicious_login config flag is set, + * which is intended to contain all logins that failed under suspicious circumstances. + * + * Mirrors this log entry to log_access when access_log_mirror is TRUE, so this proc + * doesn't need to be used alongside log_access and can replace it where appropriate. + */ +/proc/log_suspicious_login(text, access_log_mirror = TRUE) + if (CONFIG_GET(flag/log_suspicious_login)) + WRITE_LOG(GLOB.world_suspicious_login_log, "SUSPICIOUS_ACCESS: [text]") + if(access_log_mirror) + log_access(text) + /proc/log_law(text) if (CONFIG_GET(flag/log_law)) WRITE_LOG(GLOB.world_game_log, "LAW: [text]") @@ -86,6 +113,10 @@ if (CONFIG_GET(flag/log_attack)) WRITE_LOG(GLOB.world_attack_log, "ATTACK: [text]") +/proc/log_victim(text) + if (CONFIG_GET(flag/log_victim)) + WRITE_LOG(GLOB.world_victim_log, "VICTIM: [text]") + /proc/log_manifest(ckey, datum/mind/mind,mob/body, latejoin = FALSE) if (CONFIG_GET(flag/log_manifest)) WRITE_LOG(GLOB.world_manifest_log, "[ckey] \\ [body.real_name] \\ [mind.assigned_role] \\ [mind.special_role ? mind.special_role : "NONE"] \\ [latejoin ? "LATEJOIN":"ROUNDSTART"]") @@ -130,6 +161,10 @@ if (CONFIG_GET(flag/log_telecomms)) WRITE_LOG(GLOB.world_telecomms_log, "TCOMMS: [text]") +/proc/log_econ(text) + if (CONFIG_GET(flag/log_econ)) + WRITE_LOG(GLOB.world_econ_log, "MONEY: [text]") + /proc/log_chat(text) if (CONFIG_GET(flag/log_pda)) //same thing here diff --git a/code/__HELPERS/clients.dm b/code/__HELPERS/clients.dm new file mode 100644 index 0000000000..3b61cf1e1c --- /dev/null +++ b/code/__HELPERS/clients.dm @@ -0,0 +1,12 @@ +///Returns whether or not a player is a guest using their ckey as an input +/proc/is_guest_key(key) + if(findtext(key, "Guest-", 1, 7) != 1) //was findtextEx + return FALSE + + var/i, ch, len = length(key) + + for(i = 7, i <= len, ++i) //we know the first 6 chars are Guest- + ch = text2ascii(key, i) + if (ch < 48 || ch > 57) //0-9 + return FALSE + return TRUE diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm index 4ee622961a..2fbf087288 100644 --- a/code/__HELPERS/cmp.dm +++ b/code/__HELPERS/cmp.dm @@ -140,3 +140,6 @@ GLOBAL_VAR_INIT(cmp_field, "name") /proc/cmp_typepaths_asc(A, B) return sorttext("[B]","[A]") + +/proc/cmp_playtime(list/A, list/B) + return A["playtime"] - B["playtime"] diff --git a/code/__HELPERS/config.dm b/code/__HELPERS/config.dm new file mode 100644 index 0000000000..1320851ef8 --- /dev/null +++ b/code/__HELPERS/config.dm @@ -0,0 +1,2 @@ +/proc/get_policy(keyword) + return global.config.policy[keyword] diff --git a/code/__HELPERS/custom_holoforms.dm b/code/__HELPERS/custom_holoforms.dm index 2733a97e14..87f3bfbe8b 100644 --- a/code/__HELPERS/custom_holoforms.dm +++ b/code/__HELPERS/custom_holoforms.dm @@ -6,6 +6,7 @@ prefs.copy_to(mannequin) if(apply_loadout && prefs.parent) SSjob.equip_loadout(prefs.parent.mob, mannequin, bypass_prereqs = TRUE) + SSjob.post_equip_loadout(prefs.parent.mob, mannequin, bypass_prereqs = TRUE) if(copy_job) var/datum/job/highest = prefs.get_highest_job() if(highest && !istype(highest, /datum/job/ai) && !istype(highest, /datum/job/cyborg)) @@ -18,7 +19,7 @@ if(length(inhand_equipment)) for(var/path in inhand_equipment) var/obj/item/I = new path - mannequin.equip_to_slot_if_possible(I, SLOT_HANDS, TRUE, TRUE, TRUE, TRUE) + mannequin.equip_to_slot_if_possible(I, ITEM_SLOT_HANDS, TRUE, TRUE, TRUE, TRUE) var/icon/combined = new diff --git a/code/__HELPERS/do_after.dm b/code/__HELPERS/do_after.dm index 3ec1aa9b08..9f98b0e10e 100644 --- a/code/__HELPERS/do_after.dm +++ b/code/__HELPERS/do_after.dm @@ -1,168 +1,6 @@ -/** - * Higher overhead "advanced" version of do_after. - * @params - * - atom/user is the atom doing the action or the "physical" user - * - delay is time in deciseconds - * - atom/target is the atom the action is being done to, defaults to user - * - do_after_flags see __DEFINES/flags/do_after.dm for details. - * - datum/callback/extra_checks - Every time this ticks, extra_checks() is invoked with (user, delay, target, time_left, do_after_flags, required_mobility_flags, required_combat_flags, mob_redirect, stage, initially_held_item, tool, passed_in). - * Stage can be DO_AFTER_STARTING, DO_AFTER_PROGRESSING, DO_AFTER_FINISHING - * If it returns DO_AFTER_STOP, this breaks. - * If it returns nothing, all other checks are done. - * If it returns DO_AFTER_PROCEED, all other checks are ignored. - * passed_in is a list[PROGRESS_MULTIPLIER], for modification. - * - required_mobility_flags is checked with CHECK_ALL_MOBILITY. Will immediately fail if the user isn't a mob. - * - requried_combat_flags is checked with CHECK_MULTIPLE_BITFIELDS. Will immediately fail if the user isn't a mob. - * - mob/living/mob_redirect - advanced option: If this is specified, movement and mobility/combat flag checks will use this instead of user. Progressbars will also go to this. - * - obj/item/tool - The tool we're using. See do_after flags for details. - */ -#define INVOKE_CALLBACK cb_return = extra_checks?.Invoke(user, delay, target, timeleft, do_after_flags, required_mobility_flags, required_combat_flags, mob_redirect, stage, initially_held_item, tool, passed_in) -#define CHECK_FLAG_FAILURE ((required_mobility_flags || required_combat_flags) && (!living_user || (required_mobility_flags && !CHECK_ALL_MOBILITY(living_user, required_mobility_flags)) || (required_combat_flags && !CHECK_MULTIPLE_BITFIELDS(living_user.combat_flags, required_combat_flags)))) -#define TIMELEFT (timeleft) -/proc/do_after_advanced(atom/user, delay, atom/target, do_after_flags, datum/callback/extra_checks, required_mobility_flags, required_combat_flags, mob/living/mob_redirect, obj/item/tool) - // CHECK AND SET VARIABLES - if(!user) - return FALSE - if(!target) - target = user - if((user.loc == null) || (target.loc == null)) - return FALSE - var/mob/living/living_user = mob_redirect - if(!living_user && isliving(user)) - living_user = user - var/stage = DO_AFTER_STARTING - var/startlocuser = user.loc - var/startloctarget = target.loc - var/turf/userturf = get_turf(user) - var/turf/targetturf = get_turf(target) - if(!userturf || !targetturf) - return FALSE - if((do_after_flags & DO_AFTER_REQUIRES_USER_ON_TURF) && !isturf(user.loc)) - return FALSE - if(!(do_after_flags & DO_AFTER_NO_COEFFICIENT) && living_user) - delay *= living_user.cached_multiplicative_actions_slowdown - var/timeleft = delay - var/obj/item/initially_held_item = mob_redirect?.get_active_held_item() - var/atom/movable/AM_user = ismovable(user) && user - var/drifting = AM_user?.Process_Spacemove(NONE) && AM_user.inertia_dir - var/initial_dx = targetturf.x - userturf.x - var/initial_dy = targetturf.y - userturf.y - var/dx = initial_dx - var/dy = initial_dy - // DO OUR STARTING CHECKS - var/cb_return - var/list/passed_in = list(1) - INVOKE_CALLBACK - if(cb_return == DO_AFTER_STOP) - return FALSE - else if(cb_return != DO_AFTER_PROCEED) - if(CHECK_FLAG_FAILURE) - return FALSE - // SETUP LOOP - var/datum/progressbar/progbar - if(living_user) - if(!(do_after_flags & DO_AFTER_NO_PROGRESSBAR)) - progbar = new(living_user, delay, target) - // MAIN LOOP - . = TRUE - if(!delay) - return - var/obj/item/held - var/locchanged - var/ctu - var/ctt - var/tick_time = world.time - while(timeleft > 0) - stoplag(1) - var/timepassed = world.time - tick_time - tick_time = world.time - progbar?.update(TIMELEFT) - if(QDELETED(user) || QDELETED(target) || (user.loc == null) || (target.loc == null)) - . = FALSE - break - INVOKE_CALLBACK - timeleft -= timepassed * passed_in[1] - if(cb_return == DO_AFTER_STOP) - . = FALSE - break - else if(cb_return == DO_AFTER_PROCEED) - continue - // otherwise, go through our normal checks. - if(((do_after_flags & DO_AFTER_DISALLOW_MOVING_ABSOLUTE_USER) && (user.loc != startlocuser)) || ((do_after_flags & DO_AFTER_DISALLOW_MOVING_ABSOLUTE_TARGET) && (target.loc != startloctarget))) - . = FALSE - break - else if(do_after_flags & DO_AFTER_DISALLOW_MOVING_RELATIVE) - ctu = get_turf(user) - ctt = get_turf(target) - locchanged = (userturf != ctu) || (targetturf != ctt) - userturf = ctu - targetturf = ctt - dx = targetturf.x - userturf.x - dy = targetturf.y - userturf.y - if((dx != initial_dx) || (dy != initial_dy)) - . = FALSE - break - if(locchanged && !drifting && !(do_after_flags & DO_AFTER_ALLOW_NONSPACEDRIFT_RELATIVITY)) - . = FALSE - break - if(!AM_user.inertia_dir) - drifting = FALSE - if((do_after_flags & DO_AFTER_REQUIRES_USER_ON_TURF) && !isturf(user.loc)) - return FALSE - if(CHECK_FLAG_FAILURE) - . = FALSE - break - held = living_user?.get_active_held_item() - if((do_after_flags & DO_AFTER_DISALLOW_ACTIVE_ITEM_CHANGE) && (held != (tool || initially_held_item))) - . = FALSE - break - if((do_after_flags & DO_AFTER_REQUIRE_FREE_HAND_OR_TOOL) && (!living_user?.is_holding(tool) && !length(living_user?.get_empty_held_indexes()))) - . = FALSE - break - - // CLEANUP - qdel(progbar) - // If we failed, just return. - if(!.) - return FALSE - // DO FINISHING CHECKS - if(QDELETED(user) || QDELETED(target)) - return FALSE - INVOKE_CALLBACK - if(cb_return == DO_AFTER_STOP) - return FALSE - else if(cb_return == DO_AFTER_PROCEED) - return TRUE - if(CHECK_FLAG_FAILURE) - return FALSE - if(((do_after_flags & DO_AFTER_DISALLOW_MOVING_ABSOLUTE_USER) && (user.loc != startlocuser)) || ((do_after_flags & DO_AFTER_DISALLOW_MOVING_ABSOLUTE_TARGET) && (target.loc != startloctarget))) - return FALSE - else if(do_after_flags & DO_AFTER_DISALLOW_MOVING_RELATIVE) - ctu = get_turf(user) - ctt = get_turf(target) - locchanged = (userturf != ctu) || (targetturf != ctt) - userturf = ctu - targetturf = ctt - dx = targetturf.x - userturf.x - dy = targetturf.y - userturf.y - if((dx != initial_dx) || (dy != initial_dy)) - return FALSE - if(locchanged && !drifting && !(do_after_flags & DO_AFTER_ALLOW_NONSPACEDRIFT_RELATIVITY)) - return FALSE - if((do_after_flags & DO_AFTER_REQUIRES_USER_ON_TURF) && !isturf(user.loc)) - return FALSE - held = living_user?.get_active_held_item() - if((do_after_flags & DO_AFTER_DISALLOW_ACTIVE_ITEM_CHANGE) && (held != (tool || initially_held_item))) - return FALSE - if((do_after_flags & DO_AFTER_REQUIRE_FREE_HAND_OR_TOOL) && (!living_user?.is_holding(tool) && !length(living_user?.get_empty_held_indexes()))) - return FALSE - -#undef INVOKE_CALLBACK -#undef CHECK_FLAG_FAILURE - -/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks = null, ignorehelditem = FALSE, resume_time = 0 SECONDS) +/proc/do_mob(mob/user, mob/target, time = 3 SECONDS, timed_action_flags = NONE, progress = TRUE, datum/callback/extra_checks, resume_time = 0 SECONDS) if(!user || !target) - return 0 + return FALSE var/user_loc = user.loc var/drifting = 0 @@ -181,33 +19,30 @@ var/endtime = world.time+time var/starttime = world.time - . = 1 + . = TRUE while (world.time + resume_time < endtime) stoplag(1) if (progress) progbar.update(world.time - starttime + resume_time) - if(QDELETED(user) || QDELETED(target)) - . = 0 - break - if(uninterruptible) - continue - if(!(target in user.do_afters)) - . = FALSE - break - - if(!(target in user.do_afters)) - . = FALSE - break if(drifting && !user.inertia_dir) - drifting = 0 + drifting = FALSE user_loc = user.loc - if((!drifting && user.loc != user_loc) || target.loc != target_loc || (!ignorehelditem && user.get_active_held_item() != holding) || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke())) - . = 0 + if( + QDELETED(user) || QDELETED(target) \ + || (!(timed_action_flags & IGNORE_TARGET_IN_DOAFTERS) && !(target in user.do_afters)) \ + || (!(timed_action_flags & IGNORE_USER_LOC_CHANGE) && !drifting && user.loc != user_loc) \ + || (!(timed_action_flags & IGNORE_TARGET_LOC_CHANGE) && target.loc != target_loc) \ + || (!(timed_action_flags & IGNORE_HELD_ITEM) && user.get_active_held_item() != holding) \ + || (!(timed_action_flags & IGNORE_INCAPACITATED) && user.incapacitated()) \ + || (extra_checks && !extra_checks.Invoke()) \ + ) + . = FALSE break - if(progress) - qdel(progbar) + + if(!QDELETED(progbar)) + progbar.end_progress() if(!QDELETED(target)) LAZYREMOVE(user.do_afters, target) @@ -227,29 +62,25 @@ checked_health["health"] = health return ..() -/proc/do_after(mob/user, var/delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null, required_mobility_flags = (MOBILITY_USE|MOBILITY_MOVE), resume_time = 0 SECONDS) +/proc/do_after(mob/user, delay, atom/target, timed_action_flags = NONE, progress = TRUE, datum/callback/extra_checks, resume_time = 0 SECONDS) if(!user) - return 0 - var/atom/Tloc = null + return FALSE + var/atom/target_loc = null if(target && !isturf(target)) - Tloc = target.loc + target_loc = target.loc if(target) LAZYADD(user.do_afters, target) LAZYADD(target.targeted_by, user) - var/atom/Uloc = user.loc + var/atom/user_loc = user.loc - var/drifting = 0 + var/drifting = FALSE if(!user.Process_Spacemove(0) && user.inertia_dir) - drifting = 1 + drifting = TRUE var/holding = user.get_active_held_item() - var/holdingnull = 1 //User's hand started out empty, check for an empty hand - if(holding) - holdingnull = 0 //Users hand started holding something, check to see if it's still holding that - delay *= user.cached_multiplicative_actions_slowdown var/datum/progressbar/progbar @@ -258,46 +89,43 @@ var/endtime = world.time + delay var/starttime = world.time - . = 1 - var/mob/living/L = isliving(user) && user //evals to last thing eval'd + . = TRUE while (world.time + resume_time < endtime) stoplag(1) if (progress) progbar.update(world.time - starttime + resume_time) if(drifting && !user.inertia_dir) - drifting = 0 - Uloc = user.loc + drifting = FALSE + user_loc = user.loc - if(L && !CHECK_ALL_MOBILITY(L, required_mobility_flags)) - . = 0 - break - - if(QDELETED(user) || user.stat || (!drifting && user.loc != Uloc) || (extra_checks && !extra_checks.Invoke())) - . = 0 - break - - if(!QDELETED(Tloc) && (QDELETED(target) || Tloc != target.loc)) - if((Uloc != Tloc || Tloc != user) && !drifting) - . = 0 - break - - if(target && !(target in user.do_afters)) + if( + QDELETED(user) \ + || (!(timed_action_flags & IGNORE_USER_LOC_CHANGE) && !drifting && user.loc != user_loc) \ + || (!(timed_action_flags & IGNORE_HELD_ITEM) && user.get_active_held_item() != holding) \ + || (!(timed_action_flags & IGNORE_INCAPACITATED) && user.incapacitated()) \ + || (extra_checks && !extra_checks.Invoke()) \ + ) . = FALSE break - if(needhand) - //This might seem like an odd check, but you can still need a hand even when it's empty - //i.e the hand is used to pull some item/tool out of the construction - if(!holdingnull) - if(!holding) - . = 0 - break - if(user.get_active_held_item() != holding) - . = 0 - break - if(progress) - qdel(progbar) + if( + !(timed_action_flags & IGNORE_TARGET_LOC_CHANGE) \ + && !drifting \ + && !QDELETED(target_loc) \ + && (QDELETED(target) || target_loc != target.loc) \ + && ((user_loc != target_loc || target_loc != user)) \ + ) + . = FALSE + break + + if(target && !(timed_action_flags & IGNORE_TARGET_IN_DOAFTERS) && !(target in user.do_afters)) + . = FALSE + break + + if(!QDELETED(progbar)) + progbar.end_progress() + if(!QDELETED(target)) LAZYREMOVE(user.do_afters, target) @@ -305,16 +133,16 @@ LAZYREMOVE(user.do_afters, target) LAZYREMOVE(target.targeted_by, user) -/proc/do_after_mob(mob/user, var/list/targets, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks) +/proc/do_after_mob(mob/user, list/targets, time = 3 SECONDS, timed_action_flags = NONE, progress = TRUE, datum/callback/extra_checks) if(!user || !targets) - return 0 + return FALSE if(!islist(targets)) targets = list(targets) var/user_loc = user.loc - var/drifting = 0 + var/drifting = FALSE if(!user.Process_Spacemove(0) && user.inertia_dir) - drifting = 1 + drifting = TRUE var/list/originalloc = list() for(var/atom/target in targets) @@ -332,27 +160,43 @@ var/endtime = world.time + time var/starttime = world.time . = 1 - mainloop: - while(world.time < endtime) - stoplag(1) - if(progress) - progbar.update(world.time - starttime) - if(QDELETED(user) || !targets) - . = 0 + while(world.time < endtime) + stoplag(1) + + if(!QDELETED(progbar)) + progbar.update(world.time - starttime) + if(QDELETED(user) || !length(targets)) + . = FALSE + break + + if(drifting && !user.inertia_dir) + drifting = FALSE + user_loc = user.loc + + if( + !((timed_action_flags & IGNORE_USER_LOC_CHANGE) && !drifting && user_loc != user.loc) \ + || (!(timed_action_flags & IGNORE_HELD_ITEM) && user.get_active_held_item() != holding) \ + || (!(timed_action_flags & IGNORE_INCAPACITATED) && user.incapacitated()) \ + || (extra_checks && !extra_checks.Invoke()) \ + ) + . = FALSE + break + + for(var/t in targets) + var/atom/target = t + if( + (QDELETED(target)) \ + || (!(timed_action_flags & IGNORE_TARGET_LOC_CHANGE) && originalloc[target] != target.loc) \ + ) + . = FALSE break - if(uninterruptible) - continue - if(drifting && !user.inertia_dir) - drifting = 0 - user_loc = user.loc + if(!.) // In case the for-loop found a reason to break out of the while. + break + + if(!QDELETED(progbar)) + progbar.end_progress() - for(var/atom/target in targets) - if((!drifting && user_loc != user.loc) || QDELETED(target) || originalloc[target] != target.loc || user.get_active_held_item() != holding || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke())) - . = 0 - break mainloop - if(progbar) - qdel(progbar) for(var/thing in targets) var/atom/target = thing if(!QDELETED(target)) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index e55faab1be..0182f2b6f8 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -5,6 +5,9 @@ locate(min(CENTER.x+(RADIUS),world.maxx), min(CENTER.y+(RADIUS),world.maxy), CENTER.z) \ ) +/// Returns either the error landmark or the location of the room. Needless to say, if this is used, it means things have gone awry. +#define GET_ERROR_ROOM ((locate(/obj/effect/landmark/error) in GLOB.landmarks_list) || locate(4,4,1)) + #define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL)) #define CULT_POLL_WAIT 2400 @@ -396,12 +399,16 @@ /proc/ScreenText(obj/O, maptext="", screen_loc="CENTER-7,CENTER-7", maptext_height=480, maptext_width=480) if(!isobj(O)) O = new /atom/movable/screen/text() - O.maptext = maptext + O.maptext = MAPTEXT(maptext) O.maptext_height = maptext_height O.maptext_width = maptext_width O.screen_loc = screen_loc return O +/// Removes an image from a client's `.images`. Useful as a callback. +/proc/remove_image_from_client(image/image, client/remove_from) + remove_from?.images -= image + /proc/remove_images_from_clients(image/I, list/show_to) for(var/client/C in show_to) C.images -= I @@ -563,14 +570,12 @@ return A.loc -/proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank) +///Send a message in common radio when a player arrives +/proc/announce_arrival(mob/living/carbon/human/character, rank) if(!SSticker.IsRoundInProgress() || QDELETED(character)) return - var/area/A = get_area(character) - var/message = "\ - [character.real_name] ([rank]) has arrived at the station at \ - [A.name]." - deadchat_broadcast(message, follow_target = character, message_type=DEADCHAT_ARRIVALRATTLE) + var/area/player_area = get_area(character) + deadchat_broadcast(" has arrived at the station at [player_area.name].", "[character.real_name] ([rank])", follow_target = character, message_type=DEADCHAT_ARRIVALRATTLE) if((!GLOB.announcement_systems.len) || (!character.mind)) return if((character.mind.assigned_role == "Cyborg") || (character.mind.assigned_role == character.mind.special_role)) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 0a17f0d1df..345919d39a 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -55,11 +55,12 @@ init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/butt, GLOB.butt_shapes_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/testicles, GLOB.balls_shapes_list) for(var/gpath in subtypesof(/obj/item/organ/genital)) var/obj/item/organ/genital/G = gpath - if(!CHECK_BITFIELD(initial(G.genital_flags), GENITAL_BLACKLISTED)) + if(!(initial(G.genital_flags) & GENITAL_BLACKLISTED)) GLOB.genitals_list[initial(G.name)] = gpath //END OF CIT CHANGES @@ -78,17 +79,19 @@ var/datum/emote/E = new path() E.emote_list[E.key] = E - init_keybindings() + for(var/path in subtypesof(/datum/bark)) + var/datum/bark/B = new path() + GLOB.bark_list[B.id] = path + if(B.allow_random) + GLOB.bark_random_list[B.id] = path - //Uplink Items - for(var/path in subtypesof(/datum/uplink_item)) - var/datum/uplink_item/I = path - if(!initial(I.item)) //We add categories to a separate list. - GLOB.uplink_categories |= initial(I.category) - continue - GLOB.uplink_items += path - //(sub)typesof entries are listed by the order they are loaded in the code, so we'll have to rearrange them here. - GLOB.uplink_items = sortList(GLOB.uplink_items, /proc/cmp_uplink_items_dsc) + // Hair Gradients - Initialise all /datum/sprite_accessory/hair_gradient into an list indexed by gradient-style name + for(var/path in subtypesof(/datum/sprite_accessory/hair_gradient)) + var/datum/sprite_accessory/hair_gradient/H = new path() + GLOB.hair_gradients_list[H.name] = H + + // Keybindings + init_keybindings() init_subtypes(/datum/crafting_recipe, GLOB.crafting_recipes) @@ -116,6 +119,6 @@ for(var/path in typesof(/obj/item/coin)) var/obj/item/coin/C = new path UNTIL(C.flags_1 & INITIALIZED_1) //we want to make sure the value is calculated and not null. - GLOB.coin_values[path] = C.value + GLOB.coin_values[path] = C.get_item_credit_value() qdel(C) diff --git a/code/__HELPERS/heap.dm b/code/__HELPERS/heap.dm index 916e7fc05c..eabcb0e0dc 100644 --- a/code/__HELPERS/heap.dm +++ b/code/__HELPERS/heap.dm @@ -1,39 +1,45 @@ - ////////////////////// -//datum/Heap object +//datum/heap object ////////////////////// -/datum/Heap +/datum/heap var/list/L var/cmp -/datum/Heap/New(compare) +/datum/heap/New(compare) L = new() cmp = compare -/datum/Heap/proc/IsEmpty() - return !L.len +/datum/heap/Destroy(force, ...) + for(var/i in L) // because this is before the list helpers are loaded + qdel(i) + L = null + return ..() -//Insert and place at its position a new node in the heap -/datum/Heap/proc/Insert(atom/A) +/datum/heap/proc/is_empty() + return !length(L) + +//insert and place at its position a new node in the heap +/datum/heap/proc/insert(atom/A) L.Add(A) - Swim(L.len) + swim(length(L)) //removes and returns the first element of the heap //(i.e the max or the min dependant on the comparison function) -/datum/Heap/proc/Pop() - if(!L.len) +/datum/heap/proc/pop() + if(!length(L)) return 0 . = L[1] - L[1] = L[L.len] - L.Cut(L.len) - if(L.len) - Sink(1) + L[1] = L[length(L)] + L.Cut(length(L)) + if(length(L)) + sink(1) + //Get a node up to its right position in the heap -/datum/Heap/proc/Swim(var/index) +/datum/heap/proc/swim(index) var/parent = round(index * 0.5) while(parent > 0 && (call(cmp)(L[index],L[parent]) > 0)) @@ -42,21 +48,21 @@ parent = round(index * 0.5) //Get a node down to its right position in the heap -/datum/Heap/proc/Sink(var/index) - var/g_child = GetGreaterChild(index) +/datum/heap/proc/sink(index) + var/g_child = get_greater_child(index) while(g_child > 0 && (call(cmp)(L[index],L[g_child]) < 0)) L.Swap(index,g_child) index = g_child - g_child = GetGreaterChild(index) + g_child = get_greater_child(index) //Returns the greater (relative to the comparison proc) of a node children //or 0 if there's no child -/datum/Heap/proc/GetGreaterChild(var/index) - if(index * 2 > L.len) +/datum/heap/proc/get_greater_child(index) + if(index * 2 > length(L)) return 0 - if(index * 2 + 1 > L.len) + if(index * 2 + 1 > length(L)) return index * 2 if(call(cmp)(L[index * 2],L[index * 2 + 1]) < 0) @@ -65,12 +71,11 @@ return index * 2 //Replaces a given node so it verify the heap condition -/datum/Heap/proc/ReSort(atom/A) +/datum/heap/proc/resort(atom/A) var/index = L.Find(A) - Swim(index) - Sink(index) + swim(index) + sink(index) -/datum/Heap/proc/List() +/datum/heap/proc/List() . = L.Copy() - diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index fabe70c929..579126257f 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -992,7 +992,7 @@ world letter = lowertext(letter) var/image/text_image = new(loc = A) - text_image.maptext = "[letter]" + text_image.maptext = MAPTEXT("[letter]") text_image.pixel_x = 7 text_image.pixel_y = 5 qdel(atom_icon) diff --git a/code/__HELPERS/markov.dm b/code/__HELPERS/markov.dm new file mode 100644 index 0000000000..7e195f8b9c --- /dev/null +++ b/code/__HELPERS/markov.dm @@ -0,0 +1,61 @@ +#define MAXIMUM_MARKOV_LENGTH 25000 + +/proc/markov_chain(var/text, var/order = 4, var/length = 250) + if(!text || order < 0 || order > 20 || length < 1 || length > MAXIMUM_MARKOV_LENGTH) + return + + var/table = markov_table(text, order) + var/markov = markov_text(length, table, order) + return markov + +/proc/markov_table(var/text, var/look_forward = 4) + if(!text) + return + var/list/table = list() + + for(var/i = 1, i <= length(text), i++) + var/char = copytext(text, i, look_forward+i) + if(!table[char]) + table[char] = list() + + for(var/i = 1, i <= (length(text) - look_forward), i++) + var/char_index = copytext(text, i, look_forward+i) + var/char_count = copytext(text, i+look_forward, (look_forward*2)+i) + + if(table[char_index][char_count]) + table[char_index][char_count]++ + else + table[char_index][char_count] = 1 + + return table + +/proc/markov_text(var/length = 250, var/table, var/look_forward = 4) + if(!table) + return + var/char = pick(table) + var/o = char + + for(var/i = 0, i <= (length / look_forward), i++) + var/newchar = markov_weighted_char(table[char]) + + if(newchar) + char = newchar + o += "[newchar]" + else + char = pick(table) + + return o + +/proc/markov_weighted_char(var/list/array) + if(!array || !array.len) + return + + var/total = 0 + for(var/i in array) + total += array[i] + var/r = rand(1, total) + for(var/i in array) + var/weight = array[i] + if(r <= weight) + return i + r -= weight diff --git a/code/__HELPERS/matrices.dm b/code/__HELPERS/matrices.dm index 59fbb4ffc0..fdb8b04280 100644 --- a/code/__HELPERS/matrices.dm +++ b/code/__HELPERS/matrices.dm @@ -1,185 +1,43 @@ -/matrix/proc/TurnTo(old_angle, new_angle) - . = new_angle - old_angle - Turn(.) //BYOND handles cases such as -270, 360, 540 etc. DOES NOT HANDLE 180 TURNS WELL, THEY TWEEN AND LOOK LIKE SHIT +/atom/proc/shake_animation(var/intensity = 8) //Makes the object visibly shake + var/initial_transform = new/matrix(transform) + var/init_px = pixel_x + var/shake_dir = pick(-1, 1) + var/rotation = 2+soft_cap(intensity, 1, 1, 0.94) + var/offset = 1+soft_cap(intensity*0.3, 1, 1, 0.8) + var/time = 2+soft_cap(intensity*0.3, 2, 1, 0.92) + animate(src, transform=turn(transform, rotation*shake_dir), pixel_x=init_px + offset*shake_dir, time=1) + animate(transform=initial_transform, pixel_x=init_px, time=time, easing=ELASTIC_EASING) -/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3, parallel = TRUE) - if(!segments) - return - var/segment = 360/segments - if(!clockwise) - segment = -segment - var/list/matrices = list() - for(var/i in 1 to segments-1) - var/matrix/M = matrix(transform) - M.Turn(segment*i) - matrices += M - var/matrix/last = matrix(transform) - matrices += last - - speed /= segments - - if(parallel) - animate(src, transform = matrices[1], time = speed, loops , flags = ANIMATION_PARALLEL) - else - animate(src, transform = matrices[1], time = speed, loops) - - for(var/i in 2 to segments) //2 because 1 is covered above - animate(transform = matrices[i], time = speed) - //doesn't have an object argument because this is "Stacking" with the animate call above - //3 billion% intentional - -//Dumps the matrix data in format a-f -/matrix/proc/tolist() - . = list() - . += a - . += b - . += c - . += d - . += e - . += f - -//Dumps the matrix data in a matrix-grid format /* - a d 0 - b e 0 - c f 1 + This proc makes the input taper off above cap. But there's no absolute cutoff. + Chunks of the input value above cap, are reduced more and more with each successive one and added to the output + A higher input value always makes a higher output value. but the rate of growth slows */ -/matrix/proc/togrid() - . = list() - . += a - . += d - . += 0 - . += b - . += e - . += 0 - . += c - . += f - . += 1 +/proc/soft_cap(var/input, var/cap = 0, var/groupsize = 1, var/groupmult = 0.9) -//The X pixel offset of this matrix -/matrix/proc/get_x_shift() - . = c + //The cap is a ringfenced amount. If we're below that, just return the input + if (input <= cap) + return input -//The Y pixel offset of this matrix -/matrix/proc/get_y_shift() - . = f + var/output = 0 + var/buffer = 0 + var/power = 1//We increment this after each group, then apply it to the groupmult as a power -/matrix/proc/get_x_skew() - . = b + //Ok its above, so the cap is a safe amount, we move that to the output + input -= cap + output += cap -/matrix/proc/get_y_skew() - . = d - -//Skews a matrix in a particular direction -//Missing arguments are treated as no skew in that direction - -//As Rotation is defined as a scale+skew, these procs will break any existing rotation -//Unless the result is multiplied against the current matrix -/matrix/proc/set_skew(x = 0, y = 0) - b = x - d = y + //Now we start moving groups from input to buffer -///////////////////// -// COLOUR MATRICES // -///////////////////// + while (input > 0) + buffer = min(input, groupsize) //We take the groupsize, or all the input has left if its less + input -= buffer -/* Documenting a couple of potentially useful color matrices here to inspire ideas -// Greyscale - indentical to saturation @ 0 -list(LUMA_R,LUMA_R,LUMA_R,0, LUMA_G,LUMA_G,LUMA_G,0, LUMA_B,LUMA_B,LUMA_B,0, 0,0,0,1, 0,0,0,0) + buffer *= groupmult**power //This reduces the group by the groupmult to the power of which index we're on. + //This ensures that each successive group is reduced more than the previous one -// Color inversion -list(-1,0,0,0, 0,-1,0,0, 0,0,-1,0, 0,0,0,1, 1,1,1,0) + output += buffer + power++ //Transfer to output, increment power, repeat until the input pile is all used -// Sepiatone -list(0.393,0.349,0.272,0, 0.769,0.686,0.534,0, 0.189,0.168,0.131,0, 0,0,0,1, 0,0,0,0) -*/ - -//Does nothing -/proc/color_matrix_identity() - return list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0) - -//Adds/subtracts overall lightness -//0 is identity, 1 makes everything white, -1 makes everything black -/proc/color_matrix_lightness(power) - return list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, power,power,power,0) - -//Changes distance hues have from grey while maintaining the overall lightness. Greys are unaffected. -//1 is identity, 0 is greyscale, >1 oversaturates colors -/proc/color_matrix_saturation(value) - var/inv = 1 - value - var/R = round(LUMA_R * inv, 0.001) - var/G = round(LUMA_G * inv, 0.001) - var/B = round(LUMA_B * inv, 0.001) - - return list(R + value,R,R,0, G,G + value,G,0, B,B,B + value,0, 0,0,0,1, 0,0,0,0) - -//Changes distance colors have from rgb(127,127,127) grey -//1 is identity. 0 makes everything grey >1 blows out colors and greys -/proc/color_matrix_contrast(value) - var/add = (1 - value) / 2 - return list(value,0,0,0, 0,value,0,0, 0,0,value,0, 0,0,0,1, add,add,add,0) - -//Moves all colors angle degrees around the color wheel while maintaining intensity of the color and not affecting greys -//0 is identity, 120 moves reds to greens, 240 moves reds to blues -/proc/color_matrix_rotate_hue(angle) - var/sin = sin(angle) - var/cos = cos(angle) - var/cos_inv_third = 0.333*(1-cos) - var/sqrt3_sin = sqrt(3)*sin - return list( -round(cos+cos_inv_third, 0.001), round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), 0, -round(cos_inv_third-sqrt3_sin, 0.001), round(cos+cos_inv_third, 0.001), round(cos_inv_third+sqrt3_sin, 0.001), 0, -round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), round(cos+cos_inv_third, 0.001), 0, -0,0,0,1, -0,0,0,0) - -//These next three rotate values about one axis only -//x is the red axis, y is the green axis, z is the blue axis. -/proc/color_matrix_rotate_x(angle) - var/sinval = round(sin(angle), 0.001); var/cosval = round(cos(angle), 0.001) - return list(1,0,0,0, 0,cosval,sinval,0, 0,-sinval,cosval,0, 0,0,0,1, 0,0,0,0) - -/proc/color_matrix_rotate_y(angle) - var/sinval = round(sin(angle), 0.001); var/cosval = round(cos(angle), 0.001) - return list(cosval,0,-sinval,0, 0,1,0,0, sinval,0,cosval,0, 0,0,0,1, 0,0,0,0) - -/proc/color_matrix_rotate_z(angle) - var/sinval = round(sin(angle), 0.001); var/cosval = round(cos(angle), 0.001) - return list(cosval,sinval,0,0, -sinval,cosval,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0) - - -//Returns a matrix addition of A with B -/proc/color_matrix_add(list/A, list/B) - if(!istype(A) || !istype(B)) - return color_matrix_identity() - if(A.len != 20 || B.len != 20) - return color_matrix_identity() - var/list/output = list() - output.len = 20 - for(var/value in 1 to 20) - output[value] = A[value] + B[value] return output - -//Returns a matrix multiplication of A with B -/proc/color_matrix_multiply(list/A, list/B) - if(!istype(A) || !istype(B)) - return color_matrix_identity() - if(A.len != 20 || B.len != 20) - return color_matrix_identity() - var/list/output = list() - output.len = 20 - var/x = 1 - var/y = 1 - var/offset = 0 - for(y in 1 to 5) - offset = (y-1)*4 - for(x in 1 to 4) - output[offset+x] = round(A[offset+1]*B[x] + A[offset+2]*B[x+4] + A[offset+3]*B[x+8] + A[offset+4]*B[x+12]+(y==5?B[x+16]:0), 0.001) - return output - -/** - * Assembles a color matrix, defaulting to identity - */ -/proc/rgb_construct_color_matrix(rr = 1, rg, rb, gr, gg = 1, gb, br, bg, bb = 1, cr, cg, cb) - return list(rr, rg, rb, gr, gg, gb, br, bg, bb, cr, cg, cb) diff --git a/code/__HELPERS/matrices/color_matrix.dm b/code/__HELPERS/matrices/color_matrix.dm new file mode 100644 index 0000000000..bcc48b45f5 --- /dev/null +++ b/code/__HELPERS/matrices/color_matrix.dm @@ -0,0 +1,200 @@ +///////////////////// +// COLOUR MATRICES // +///////////////////// + +/* Documenting a couple of potentially useful color matrices here to inspire ideas +// Greyscale - indentical to saturation @ 0 +list(LUMA_R,LUMA_R,LUMA_R,0, LUMA_G,LUMA_G,LUMA_G,0, LUMA_B,LUMA_B,LUMA_B,0, 0,0,0,1, 0,0,0,0) + +// Color inversion +list(-1,0,0,0, 0,-1,0,0, 0,0,-1,0, 0,0,0,1, 1,1,1,0) + +// Sepiatone +list(0.393,0.349,0.272,0, 0.769,0.686,0.534,0, 0.189,0.168,0.131,0, 0,0,0,1, 0,0,0,0) +*/ + +//Does nothing +/proc/color_matrix_identity() + return list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0) + +//Adds/subtracts overall lightness +//0 is identity, 1 makes everything white, -1 makes everything black +/proc/color_matrix_lightness(power) + return list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, power,power,power,0) + +//Changes distance hues have from grey while maintaining the overall lightness. Greys are unaffected. +//1 is identity, 0 is greyscale, >1 oversaturates colors +/proc/color_matrix_saturation(value) + var/inv = 1 - value + var/R = round(LUMA_R * inv, 0.001) + var/G = round(LUMA_G * inv, 0.001) + var/B = round(LUMA_B * inv, 0.001) + + return list(R + value,R,R,0, G,G + value,G,0, B,B,B + value,0, 0,0,0,1, 0,0,0,0) + +/** + * Exxagerates or removes colors + */ +/proc/color_matrix_saturation_percent(percent) + if(percent == 0) + return color_matrix_identity() + percent = clamp(percent, -100, 100) + if(percent > 0) + percent *= 3 + var/x = 1 + percent / 100 + var/inv = 1 - x + var/R = LUMA_R * inv + var/G = LUMA_G * inv + var/B = LUMA_B * inv + + return list(R + x,R,R, G,G + x,G, B,B,B + x) + +//Changes distance colors have from rgb(127,127,127) grey +//1 is identity. 0 makes everything grey >1 blows out colors and greys +/proc/color_matrix_contrast(value) + var/add = (1 - value) / 2 + return list(value,0,0,0, 0,value,0,0, 0,0,value,0, 0,0,0,1, add,add,add,0) + +/** + * Exxagerates or removes brightness + */ +/proc/color_matrix_contrast_percent(percent) + var/static/list/delta_index = list( + 0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11, + 0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.20, 0.21, 0.22, 0.24, + 0.25, 0.27, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42, + 0.44, 0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, + 0.71, 0.74, 0.77, 0.80, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98, + 1.0, 1.06, 1.12, 1.18, 1.24, 1.30, 1.36, 1.42, 1.48, 1.54, + 1.60, 1.66, 1.72, 1.78, 1.84, 1.90, 1.96, 2.0, 2.12, 2.25, + 2.37, 2.50, 2.62, 2.75, 2.87, 3.0, 3.2, 3.4, 3.6, 3.8, + 4.0, 4.3, 4.7, 4.9, 5.0, 5.5, 6.0, 6.5, 6.8, 7.0, + 7.3, 7.5, 7.8, 8.0, 8.4, 8.7, 9.0, 9.4, 9.6, 9.8, + 10.0) + percent = clamp(percent, -100, 100) + if(percent == 0) + return color_matrix_identity() + + var/x = 0 + if (percent < 0) + x = 127 + percent / 100 * 127; + else + x = percent % 1 + if(x == 0) + x = delta_index[percent] + else + x = delta_index[percent] * (1-x) + delta_index[percent+1] * x//use linear interpolation for more granularity. + x = x * 127 + 127 + + var/mult = x / 127 + var/add = 0.5 * (127-x) / 255 + return list(mult,0,0, 0,mult,0, 0,0,mult, add,add,add) + +//Moves all colors angle degrees around the color wheel while maintaining intensity of the color and not affecting greys +//0 is identity, 120 moves reds to greens, 240 moves reds to blues +/proc/color_matrix_rotate_hue(angle) + var/sin = sin(angle) + var/cos = cos(angle) + var/cos_inv_third = 0.333*(1-cos) + var/sqrt3_sin = sqrt(3)*sin + return list( +round(cos+cos_inv_third, 0.001), round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), 0, +round(cos_inv_third-sqrt3_sin, 0.001), round(cos+cos_inv_third, 0.001), round(cos_inv_third+sqrt3_sin, 0.001), 0, +round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), round(cos+cos_inv_third, 0.001), 0, +0,0,0,1, +0,0,0,0) + +/** + * Moves all colors angle degrees around the color wheel while maintaining intensity of the color and not affecting whites + * TODO: Need a version that only affects one color (ie shift red to blue but leave greens and blues alone) + */ +/proc/color_matrix_rotation(angle) + if(angle == 0) + return color_matrix_identity() + angle = clamp(angle, -180, 180) + var/cos = cos(angle) + var/sin = sin(angle) + + var/constA = 0.143 + var/constB = 0.140 + var/constC = -0.283 + return list( + LUMA_R + cos * (1-LUMA_R) + sin * -LUMA_R, LUMA_R + cos * -LUMA_R + sin * constA, LUMA_R + cos * -LUMA_R + sin * -(1-LUMA_R), + LUMA_G + cos * -LUMA_G + sin * -LUMA_G, LUMA_G + cos * (1-LUMA_G) + sin * constB, LUMA_G + cos * -LUMA_G + sin * LUMA_G, + LUMA_B + cos * -LUMA_B + sin * (1-LUMA_B), LUMA_B + cos * -LUMA_B + sin * constC, LUMA_B + cos * (1-LUMA_B) + sin * LUMA_B + ) + +//These next three rotate values about one axis only +//x is the red axis, y is the green axis, z is the blue axis. +/proc/color_matrix_rotate_x(angle) + var/sinval = round(sin(angle), 0.001); var/cosval = round(cos(angle), 0.001) + return list(1,0,0,0, 0,cosval,sinval,0, 0,-sinval,cosval,0, 0,0,0,1, 0,0,0,0) + +/proc/color_matrix_rotate_y(angle) + var/sinval = round(sin(angle), 0.001); var/cosval = round(cos(angle), 0.001) + return list(cosval,0,-sinval,0, 0,1,0,0, sinval,0,cosval,0, 0,0,0,1, 0,0,0,0) + +/proc/color_matrix_rotate_z(angle) + var/sinval = round(sin(angle), 0.001); var/cosval = round(cos(angle), 0.001) + return list(cosval,sinval,0,0, -sinval,cosval,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0) + +/** + * Builds a color matrix that transforms the hue, saturation, and value, all in one operation. + */ +/proc/color_matrix_hsv(hue, saturation, value) + hue = clamp(360 - hue, 0, 360) + + // This is very much a rough approximation of hueshifting. This carries some artifacting, such as negative values that simply shouldn't exist, but it does get the job done, and that's what matters. + var/cos_a = cos(hue) // These have to be inverted from 360, otherwise the hue's inverted + var/sin_a = sin(hue) + var/rot_x = cos_a + (1 - cos_a) / 3 + var/rot_y = (1 - cos_a) / 3 - 0.5774 * sin_a // 0.5774 is sqrt(1/3) + var/rot_z = (1 - cos_a) / 3 + 0.5774 * sin_a + + return list( + round((((1-saturation) * LUMA_R) + (rot_x * saturation)) * value, 0.01), round((((1-saturation) * LUMA_R) + (rot_y * saturation)) * value, 0.01), round((((1-saturation) * LUMA_R) + (rot_z * saturation)) * value, 0.01), + round((((1-saturation) * LUMA_G) + (rot_z * saturation)) * value, 0.01), round((((1-saturation) * LUMA_G) + (rot_x * saturation)) * value, 0.01), round((((1-saturation) * LUMA_G) + (rot_y * saturation)) * value, 0.01), + round((((1-saturation) * LUMA_B) + (rot_y * saturation)) * value, 0.01), round((((1-saturation) * LUMA_B) + (rot_z * saturation)) * value, 0.01), round((((1-saturation) * LUMA_B) + (rot_x * saturation)) * value, 0.01), + 0, 0, 0 + ) + +//Returns a matrix addition of A with B +/proc/color_matrix_add(list/A, list/B) + if(!istype(A) || !istype(B)) + return color_matrix_identity() + if(A.len != 20 || B.len != 20) + return color_matrix_identity() + var/list/output = list() + output.len = 20 + for(var/value in 1 to 20) + output[value] = A[value] + B[value] + return output + +//Returns a matrix multiplication of A with B +/proc/color_matrix_multiply(list/A, list/B) + if(!istype(A) || !istype(B)) + return color_matrix_identity() + if(A.len != 20 || B.len != 20) + return color_matrix_identity() + var/list/output = list() + output.len = 20 + var/x = 1 + var/y = 1 + var/offset = 0 + for(y in 1 to 5) + offset = (y-1)*4 + for(x in 1 to 4) + output[offset+x] = round(A[offset+1]*B[x] + A[offset+2]*B[x+4] + A[offset+3]*B[x+8] + A[offset+4]*B[x+12]+(y==5?B[x+16]:0), 0.001) + return output + +/** + * Assembles a color matrix, defaulting to identity + */ +/proc/rgb_construct_color_matrix(rr = 1, rg, rb, gr, gg = 1, gb, br, bg, bb = 1, cr, cg, cb) + return list(rr, rg, rb, gr, gg, gb, br, bg, bb, cr, cg, cb) + +/** + * Assembles a color matrix, defaulting to identity + */ +/proc/rgba_construct_color_matrix(rr = 1, rg, rb, ra, gr, gg = 1, gb, ga, br, bg, bb = 1, ba, ar, ag, ab, aa = 1, cr, cg, cb, ca) + return list(rr, rg, rb, ra, gr, gg, gb, ga, br, bg, bb, ba, ar, ag, ab, aa, cr, cg, cb, ca) diff --git a/code/__HELPERS/matrices/transform_matrix.dm b/code/__HELPERS/matrices/transform_matrix.dm new file mode 100644 index 0000000000..8f8a67535e --- /dev/null +++ b/code/__HELPERS/matrices/transform_matrix.dm @@ -0,0 +1,86 @@ +/matrix/proc/TurnTo(old_angle, new_angle) + . = new_angle - old_angle + Turn(.) //BYOND handles cases such as -270, 360, 540 etc. DOES NOT HANDLE 180 TURNS WELL, THEY TWEEN AND LOOK LIKE SHIT + +/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3, parallel = TRUE) + if(!segments) + return + var/segment = 360/segments + if(!clockwise) + segment = -segment + var/list/matrices = list() + for(var/i in 1 to segments-1) + var/matrix/M = matrix(transform) + M.Turn(segment*i) + matrices += M + var/matrix/last = matrix(transform) + matrices += last + + speed /= segments + + if(parallel) + animate(src, transform = matrices[1], time = speed, loops, flags = ANIMATION_PARALLEL) + else + animate(src, transform = matrices[1], time = speed, loops) + + for(var/i in 2 to segments) //2 because 1 is covered above + animate(transform = matrices[i], time = speed) + //doesn't have an object argument because this is "Stacking" with the animate call above + //3 billion% intentional + +//Dumps the matrix data in format a-f +/matrix/proc/tolist() + . = list() + . += a + . += b + . += c + . += d + . += e + . += f + +//Dumps the matrix data in a matrix-grid format +/* + a d 0 + b e 0 + c f 1 +*/ +/matrix/proc/togrid() + . = list() + . += a + . += d + . += 0 + . += b + . += e + . += 0 + . += c + . += f + . += 1 + +//The X pixel offset of this matrix +/matrix/proc/get_x_shift() + . = c + +//The Y pixel offset of this matrix +/matrix/proc/get_y_shift() + . = f + +/matrix/proc/get_x_skew() + . = b + +/matrix/proc/get_y_skew() + . = d + +//Skews a matrix in a particular direction +//Missing arguments are treated as no skew in that direction + +//As Rotation is defined as a scale+skew, these procs will break any existing rotation +//Unless the result is multiplied against the current matrix +/matrix/proc/set_skew(x = 0, y = 0) + b = x + d = y + +/** + * constructs a transform matrix, defaulting to identity + */ +/proc/transform_matrix_construct(a = 1, b, c, d = 1, e, f) + return matrix(a, b, c, d, e, f) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 02af6fab79..dca8c184f2 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -90,6 +90,8 @@ init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list) if(!GLOB.breasts_shapes_list.len) init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list) + if(!GLOB.butt_shapes_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/butt, GLOB.butt_shapes_list) if(!GLOB.ipc_screens_list.len) init_sprite_accessory_subtypes(/datum/sprite_accessory/screen, GLOB.ipc_screens_list) if(!GLOB.ipc_antennas_list.len) @@ -206,10 +208,16 @@ "vag_shape" = pick(GLOB.vagina_shapes_list), "vag_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), "has_womb" = FALSE, + "has_butt" = FALSE, + "butt_size" = BUTT_SIZE_DEF, + "butt_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + + "balls_visibility" = GEN_VISIBLE_NO_UNDIES, "breasts_visibility"= GEN_VISIBLE_NO_UNDIES, "cock_visibility" = GEN_VISIBLE_NO_UNDIES, "vag_visibility" = GEN_VISIBLE_NO_UNDIES, + "butt_visibility" = GEN_VISIBLE_NO_UNDIES, "ipc_screen" = snowflake_ipc_antenna_list ? pick(snowflake_ipc_antenna_list) : "None", "ipc_antenna" = "None", "flavor_text" = "", @@ -374,17 +382,27 @@ GLOBAL_LIST_EMPTY(species_datums) for(var/i in 1 to step_count) step(X, pick(NORTH, SOUTH, EAST, WEST)) -/proc/deadchat_broadcast(message, mob/follow_target=null, turf/turf_target=null, speaker_key=null, message_type=DEADCHAT_REGULAR) - message = "[message]" - for(var/mob/M in GLOB.player_list) - var/datum/preferences/prefs - if(M.client && M.client.prefs) - prefs = M.client.prefs - else - prefs = new +// 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) + message = span_deadsay("[source][span_linkify(message)]") + for(var/mob/M in GLOB.player_list) + var/chat_toggles = TOGGLES_DEFAULT_CHAT + var/toggles = TOGGLES_DEFAULT + var/list/ignoring + if(M.client?.prefs) + var/datum/preferences/prefs = M.client?.prefs + chat_toggles = prefs.chat_toggles + toggles = prefs.toggles + ignoring = prefs.ignoring + if(admin_only) + if (!M.client?.holder) + return + else + message += span_deadsay(" (This is viewable to admins only).") var/override = FALSE - if(M.client && M.client.holder && (prefs.chat_toggles & CHAT_DEAD)) + if(M.client?.holder && (chat_toggles & CHAT_DEAD)) override = TRUE if(HAS_TRAIT(M, TRAIT_SIXTHSENSE)) override = TRUE @@ -394,15 +412,15 @@ GLOBAL_LIST_EMPTY(species_datums) continue if(M.stat != DEAD && !override) continue - if(speaker_key && (speaker_key in prefs.ignoring)) + if(speaker_key && (speaker_key in ignoring)) continue switch(message_type) if(DEADCHAT_DEATHRATTLE) - if(prefs.toggles & DISABLE_DEATHRATTLE) + if(toggles & DISABLE_DEATHRATTLE) continue if(DEADCHAT_ARRIVALRATTLE) - if(prefs.toggles & DISABLE_ARRIVALRATTLE) + if(toggles & DISABLE_ARRIVALRATTLE) continue if(isobserver(M)) @@ -419,9 +437,9 @@ GLOBAL_LIST_EMPTY(species_datums) var/turf_link = TURF_LINK(M, turf_target) rendered_message = "[turf_link] [message]" - to_chat(M, rendered_message) + to_chat(M, rendered_message, avoid_highlighting = speaker_key == M.key) else - to_chat(M, message) + to_chat(M, message, avoid_highlighting = speaker_key == M.key) //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) @@ -457,3 +475,24 @@ GLOBAL_LIST_EMPTY(species_datums) REMOVE_TRAIT(L, TRAIT_PASSTABLE, source) if(!HAS_TRAIT(L, TRAIT_PASSTABLE)) L.pass_flags &= ~PASSTABLE + +/proc/dance_rotate(atom/movable/AM, datum/callback/callperrotate, set_original_dir=FALSE) + set waitfor = FALSE + var/originaldir = AM.dir + for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH)) + if(!AM) + return + AM.setDir(i) + callperrotate?.Invoke() + sleep(1) + if(set_original_dir) + AM.setDir(originaldir) + +/// Gets the client of the mob, allowing for mocking of the client. +/// You only need to use this if you know you're going to be mocking clients somewhere else. +#define GET_CLIENT(mob) (##mob.client || ##mob.mock_client) + +//check if the person is dead, not sure where to put this +#define IS_DEAD_OR_INCAP(source) (source.incapacitated() || source.stat) + +#define IS_IN_STASIS(mob) (mob.has_status_effect(/datum/status_effect/grouped/stasis)) diff --git a/code/__HELPERS/path.dm b/code/__HELPERS/path.dm new file mode 100644 index 0000000000..72ed8da819 --- /dev/null +++ b/code/__HELPERS/path.dm @@ -0,0 +1,381 @@ +/** + * This file contains the stuff you need for using JPS (Jump Point Search) pathing, an alternative to A* that skips + * over large numbers of uninteresting tiles resulting in much quicker pathfinding solutions. Mind that diagonals + * cost the same as cardinal moves currently, so paths may look a bit strange, but should still be optimal. + */ + +/** + * This is the proc you use whenever you want to have pathfinding more complex than "try stepping towards the thing". + * If no path was found, returns an empty list, which is important for bots like medibots who expect an empty list rather than nothing. + * + * Arguments: + * * caller: The movable atom that's trying to find the path + * * end: What we're trying to path to. It doesn't matter if this is a turf or some other atom, we're gonna just path to the turf it's on anyway + * * max_distance: The maximum number of steps we can take in a given path to search (default: 30, 0 = infinite) + * * mintargetdistance: Minimum distance to the target before path returns, could be used to get near a target, but not right to it - for an AI mob with a gun, for example. + * * id: An ID card representing what access we have and what doors we can open. Its location relative to the pathing atom is irrelevant + * * simulated_only: Whether we consider turfs without atmos simulation (AKA do we want to ignore space) + * * exclude: If we want to avoid a specific turf, like if we're a mulebot who already got blocked by some turf + * * skip_first: Whether or not to delete the first item in the path. This would be done because the first item is the starting tile, which can break movement for some creatures. + */ +/proc/get_path_to(caller, end, max_distance = 30, mintargetdist, id=null, simulated_only = TRUE, turf/exclude, skip_first=TRUE) + if(!caller || !get_turf(end)) + return + + var/l = SSpathfinder.mobs.getfree(caller) + while(!l) + stoplag(3) + l = SSpathfinder.mobs.getfree(caller) + + var/list/path + var/datum/pathfind/pathfind_datum = new(caller, end, id, max_distance, mintargetdist, simulated_only, exclude) + path = pathfind_datum.search() + qdel(pathfind_datum) + + SSpathfinder.mobs.found(l) + if(!path) + path = list() + if(length(path) > 0 && skip_first) + path.Cut(1,2) + return path + +/** + * A helper macro to see if it's possible to step from the first turf into the second one, minding things like door access and directional windows. + * Note that this can only be used inside the [datum/pathfind][pathfind datum] since it uses variables from said datum. + * If you really want to optimize things, optimize this, cuz this gets called a lot. + */ +#define CAN_STEP(cur_turf, next) (next && !next.density && !(simulated_only && SSpathfinder.space_type_cache[next.type]) && !cur_turf.LinkBlockedWithAccess(next,caller, id) && (next != avoid)) +/// Another helper macro for JPS, for telling when a node has forced neighbors that need expanding +#define STEP_NOT_HERE_BUT_THERE(cur_turf, dirA, dirB) ((!CAN_STEP(cur_turf, get_step(cur_turf, dirA)) && CAN_STEP(cur_turf, get_step(cur_turf, dirB)))) + +/// The JPS Node datum represents a turf that we find interesting enough to add to the open list and possibly search for new tiles from +/datum/jps_node + /// The turf associated with this node + var/turf/tile + /// The node we just came from + var/datum/jps_node/previous_node + /// The A* node weight (f_value = number_of_tiles + heuristic) + var/f_value + /// The A* node heuristic (a rough estimate of how far we are from the goal) + var/heuristic + /// How many steps it's taken to get here from the start (currently pulling double duty as steps taken & cost to get here, since all moves incl diagonals cost 1 rn) + var/number_tiles + /// How many steps it took to get here from the last node + var/jumps + /// Nodes store the endgoal so they can process their heuristic without a reference to the pathfind datum + var/turf/node_goal + +/datum/jps_node/New(turf/our_tile, datum/jps_node/incoming_previous_node, jumps_taken, turf/incoming_goal) + tile = our_tile + jumps = jumps_taken + if(incoming_goal) // if we have the goal argument, this must be the first/starting node + node_goal = incoming_goal + else if(incoming_previous_node) // if we have the parent, this is from a direct lateral/diagonal scan, we can fill it all out now + previous_node = incoming_previous_node + number_tiles = previous_node.number_tiles + jumps + node_goal = previous_node.node_goal + heuristic = get_dist(tile, node_goal) + f_value = number_tiles + heuristic + // otherwise, no parent node means this is from a subscan lateral scan, so we just need the tile for now until we call [datum/jps/proc/update_parent] on it + +/datum/jps_node/Destroy(force, ...) + previous_node = null + return ..() + +/datum/jps_node/proc/update_parent(datum/jps_node/new_parent) + previous_node = new_parent + node_goal = previous_node.node_goal + jumps = get_dist(tile, previous_node.tile) + number_tiles = previous_node.number_tiles + jumps + heuristic = get_dist(tile, node_goal) + f_value = number_tiles + heuristic + +/// TODO: Macro this to reduce proc overhead +/proc/HeapPathWeightCompare(datum/jps_node/a, datum/jps_node/b) + return b.f_value - a.f_value + +/// The datum used to handle the JPS pathfinding, completely self-contained +/datum/pathfind + /// The thing that we're actually trying to path for + var/atom/movable/caller + /// The turf where we started at + var/turf/start + /// The turf we're trying to path to (note that this won't track a moving target) + var/turf/end + /// The open list/stack we pop nodes out from (TODO: make this a normal list and macro-ize the heap operations to reduce proc overhead) + var/datum/heap/open + ///An assoc list that serves as the closed list & tracks what turfs came from where. Key is the turf, and the value is what turf it came from + var/list/sources + /// The list we compile at the end if successful to pass back + var/list/path + + // general pathfinding vars/args + /// An ID card representing what access we have and what doors we can open. Its location relative to the pathing atom is irrelevant + var/obj/item/card/id/id + /// How far away we have to get to the end target before we can call it quits + var/mintargetdist = 0 + /// I don't know what this does vs , but they limit how far we can search before giving up on a path + var/max_distance = 30 + /// Space is big and empty, if this is TRUE then we ignore pathing through unsimulated tiles + var/simulated_only + /// A specific turf we're avoiding, like if a mulebot is being blocked by someone t-posing in a doorway we're trying to get through + var/turf/avoid + +/datum/pathfind/New(atom/movable/caller, atom/goal, id, max_distance, mintargetdist, simulated_only, avoid) + src.caller = caller + end = get_turf(goal) + open = new /datum/heap(/proc/HeapPathWeightCompare) + sources = new() + src.id = id + src.max_distance = max_distance + src.mintargetdist = mintargetdist + src.simulated_only = simulated_only + src.avoid = avoid + +/** + * search() is the proc you call to kick off and handle the actual pathfinding, and kills the pathfind datum instance when it's done. + * + * If a valid path was found, it's returned as a list. If invalid or cross-z-level params are entered, or if there's no valid path found, we + * return null, which [/proc/get_path_to] translates to an empty list (notable for simple bots, who need empty lists) + */ +/datum/pathfind/proc/search() + start = get_turf(caller) + if(!start || !end) + stack_trace("Invalid A* start or destination") + return + if(start.z != end.z || start == end ) //no pathfinding between z levels + return + if(max_distance && (max_distance < get_dist(start, end))) //if start turf is farther than max_distance from end turf, no need to do anything + return + + //initialization + var/datum/jps_node/current_processed_node = new (start, -1, 0, end) + open.insert(current_processed_node) + sources[start] = start // i'm sure this is fine + + //then run the main loop + while(!open.is_empty() && !path) + if(!caller) + return + current_processed_node = open.pop() //get the lower f_value turf in the open list + if(max_distance && (current_processed_node.number_tiles > max_distance))//if too many steps, don't process that path + continue + + var/turf/current_turf = current_processed_node.tile + for(var/scan_direction in list(EAST, WEST, NORTH, SOUTH)) + lateral_scan_spec(current_turf, scan_direction, current_processed_node) + + for(var/scan_direction in list(NORTHEAST, SOUTHEAST, NORTHWEST, SOUTHWEST)) + diag_scan_spec(current_turf, scan_direction, current_processed_node) + + CHECK_TICK + + //we're done! reverse the path to get it from start to finish + if(path) + for(var/i = 1 to round(0.5 * length(path))) + path.Swap(i, length(path) - i + 1) + + sources = null + qdel(open) + return path + +/// Called when we've hit the goal with the node that represents the last tile, then sets the path var to that path so it can be returned by [datum/pathfind/proc/search] +/datum/pathfind/proc/unwind_path(datum/jps_node/unwind_node) + path = new() + var/turf/iter_turf = unwind_node.tile + path.Add(iter_turf) + + while(unwind_node.previous_node) + var/dir_goal = get_dir(iter_turf, unwind_node.previous_node.tile) + for(var/i = 1 to unwind_node.jumps) + iter_turf = get_step(iter_turf,dir_goal) + path.Add(iter_turf) + unwind_node = unwind_node.previous_node + +/** + * For performing lateral scans from a given starting turf. + * + * These scans are called from both the main search loop, as well as subscans for diagonal scans, and they treat finding interesting turfs slightly differently. + * If we're doing a normal lateral scan, we already have a parent node supplied, so we just create the new node and immediately insert it into the heap, ezpz. + * If we're part of a subscan, we still need for the diagonal scan to generate a parent node, so we return a node datum with just the turf and let the diag scan + * proc handle transferring the values and inserting them into the heap. + * + * Arguments: + * * original_turf: What turf did we start this scan at? + * * heading: What direction are we going in? Obviously, should be cardinal + * * parent_node: Only given for normal lateral scans, if we don't have one, we're a diagonal subscan. +*/ +/datum/pathfind/proc/lateral_scan_spec(turf/original_turf, heading, datum/jps_node/parent_node) + var/steps_taken = 0 + + var/turf/current_turf = original_turf + var/turf/lag_turf = original_turf + + while(TRUE) + if(path) + return + lag_turf = current_turf + current_turf = get_step(current_turf, heading) + steps_taken++ + if(!CAN_STEP(lag_turf, current_turf)) + return + + if(current_turf == end || (mintargetdist && (get_dist(current_turf, end) <= mintargetdist))) + var/datum/jps_node/final_node = new(current_turf, parent_node, steps_taken) + sources[current_turf] = original_turf + if(parent_node) // if this is a direct lateral scan we can wrap up, if it's a subscan from a diag, we need to let the diag make their node first, then finish + unwind_path(final_node) + return final_node + else if(sources[current_turf]) // already visited, essentially in the closed list + return + else + sources[current_turf] = original_turf + + if(parent_node && parent_node.number_tiles + steps_taken > max_distance) + return + + var/interesting = FALSE // have we found a forced neighbor that would make us add this turf to the open list? + + switch(heading) + if(NORTH) + if(STEP_NOT_HERE_BUT_THERE(current_turf, WEST, NORTHWEST) || STEP_NOT_HERE_BUT_THERE(current_turf, EAST, NORTHEAST)) + interesting = TRUE + if(SOUTH) + if(STEP_NOT_HERE_BUT_THERE(current_turf, WEST, SOUTHWEST) || STEP_NOT_HERE_BUT_THERE(current_turf, EAST, SOUTHEAST)) + interesting = TRUE + if(EAST) + if(STEP_NOT_HERE_BUT_THERE(current_turf, NORTH, NORTHEAST) || STEP_NOT_HERE_BUT_THERE(current_turf, SOUTH, SOUTHEAST)) + interesting = TRUE + if(WEST) + if(STEP_NOT_HERE_BUT_THERE(current_turf, NORTH, NORTHWEST) || STEP_NOT_HERE_BUT_THERE(current_turf, SOUTH, SOUTHWEST)) + interesting = TRUE + + if(interesting) + var/datum/jps_node/newnode = new(current_turf, parent_node, steps_taken) + if(parent_node) // if we're a diagonal subscan, we'll handle adding ourselves to the heap in the diag + open.insert(newnode) + return newnode + +/** + * For performing diagonal scans from a given starting turf. + * + * Unlike lateral scans, these only are called from the main search loop, so we don't need to worry about returning anything, + * though we do need to handle the return values of our lateral subscans of course. + * + * Arguments: + * * original_turf: What turf did we start this scan at? + * * heading: What direction are we going in? Obviously, should be diagonal + * * parent_node: We should always have a parent node for diagonals +*/ +/datum/pathfind/proc/diag_scan_spec(turf/original_turf, heading, datum/jps_node/parent_node) + var/steps_taken = 0 + var/turf/current_turf = original_turf + var/turf/lag_turf = original_turf + + while(TRUE) + if(path) + return + lag_turf = current_turf + current_turf = get_step(current_turf, heading) + steps_taken++ + if(!CAN_STEP(lag_turf, current_turf)) + return + + if(current_turf == end || (mintargetdist && (get_dist(current_turf, end) <= mintargetdist))) + var/datum/jps_node/final_node = new(current_turf, parent_node, steps_taken) + sources[current_turf] = original_turf + unwind_path(final_node) + return + else if(sources[current_turf]) // already visited, essentially in the closed list + return + else + sources[current_turf] = original_turf + + if(parent_node.number_tiles + steps_taken > max_distance) + return + + var/interesting = FALSE // have we found a forced neighbor that would make us add this turf to the open list? + var/datum/jps_node/possible_child_node // otherwise, did one of our lateral subscans turn up something? + + switch(heading) + if(NORTHWEST) + if(STEP_NOT_HERE_BUT_THERE(current_turf, EAST, NORTHEAST) || STEP_NOT_HERE_BUT_THERE(current_turf, SOUTH, SOUTHWEST)) + interesting = TRUE + else + possible_child_node = (lateral_scan_spec(current_turf, WEST) || lateral_scan_spec(current_turf, NORTH)) + if(NORTHEAST) + if(STEP_NOT_HERE_BUT_THERE(current_turf, WEST, NORTHWEST) || STEP_NOT_HERE_BUT_THERE(current_turf, SOUTH, SOUTHEAST)) + interesting = TRUE + else + possible_child_node = (lateral_scan_spec(current_turf, EAST) || lateral_scan_spec(current_turf, NORTH)) + if(SOUTHWEST) + if(STEP_NOT_HERE_BUT_THERE(current_turf, EAST, SOUTHEAST) || STEP_NOT_HERE_BUT_THERE(current_turf, NORTH, NORTHWEST)) + interesting = TRUE + else + possible_child_node = (lateral_scan_spec(current_turf, SOUTH) || lateral_scan_spec(current_turf, WEST)) + if(SOUTHEAST) + if(STEP_NOT_HERE_BUT_THERE(current_turf, WEST, SOUTHWEST) || STEP_NOT_HERE_BUT_THERE(current_turf, NORTH, NORTHEAST)) + interesting = TRUE + else + possible_child_node = (lateral_scan_spec(current_turf, SOUTH) || lateral_scan_spec(current_turf, EAST)) + + if(interesting || possible_child_node) + var/datum/jps_node/newnode = new(current_turf, parent_node, steps_taken) + open.insert(newnode) + if(possible_child_node) + possible_child_node.update_parent(newnode) + open.insert(possible_child_node) + if(possible_child_node.tile == end || (mintargetdist && (get_dist(possible_child_node.tile, end) <= mintargetdist))) + unwind_path(possible_child_node) + return + +/** + * For seeing if we can actually move between 2 given turfs while accounting for our access and the caller's pass_flags + * + * Arguments: + * * caller: The movable, if one exists, being used for mobility checks to see what tiles it can reach + * * ID: An ID card that decides if we can gain access to doors that would otherwise block a turf + * * simulated_only: Do we only worry about turfs with simulated atmos, most notably things that aren't space? +*/ +/turf/proc/LinkBlockedWithAccess(turf/destination_turf, caller, ID) + if(destination_turf.x != x && destination_turf.y != y) //diagonal + var/in_dir = get_dir(destination_turf,src) // eg. northwest (1+8) = 9 (00001001) + var/first_step_direction_a = in_dir & 3 // eg. north (1+8)&3 (0000 0011) = 1 (0000 0001) + var/first_step_direction_b = in_dir & 12 // eg. west (1+8)&12 (0000 1100) = 8 (0000 1000) + + for(var/first_step_direction in list(first_step_direction_a,first_step_direction_b)) + var/turf/midstep_turf = get_step(destination_turf,first_step_direction) + var/way_blocked = midstep_turf.density || LinkBlockedWithAccess(midstep_turf,caller,ID) || midstep_turf.LinkBlockedWithAccess(destination_turf,caller,ID) + if(!way_blocked) + return FALSE + return TRUE + + var/actual_dir = get_dir(src, destination_turf) + + // Source border object checks + for(var/obj/structure/window/iter_window in src) + if(!iter_window.CanAStarPass(ID, actual_dir)) + return TRUE + + for(var/obj/machinery/door/window/iter_windoor in src) + if(!iter_windoor.CanAStarPass(ID, actual_dir)) + return TRUE + + for(var/obj/structure/railing/iter_rail in src) + if(!iter_rail.CanAStarPass(ID, actual_dir)) + return TRUE + + for(var/obj/machinery/door/firedoor/border_only/firedoor in src) + if(!firedoor.CanAStarPass(ID, actual_dir)) + return TRUE + + // Destination blockers check + var/reverse_dir = get_dir(destination_turf, src) + for(var/obj/iter_object in destination_turf) + if(!iter_object.CanAStarPass(ID, reverse_dir, caller)) + return TRUE + + return FALSE + +#undef CAN_STEP +#undef STEP_NOT_HERE_BUT_THERE diff --git a/code/__HELPERS/priority_announce.dm b/code/__HELPERS/priority_announce.dm index 374e89f715..cfb52408aa 100644 --- a/code/__HELPERS/priority_announce.dm +++ b/code/__HELPERS/priority_announce.dm @@ -1,8 +1,12 @@ -/proc/priority_announce(text, title = "", sound = "attention", type , sender_override) +/proc/priority_announce(text, title = "", sound, type , sender_override, has_important_message) if(!text) return var/announcement + if(!sound) + sound = SSstation.announcer.get_rand_alert_sound() + else if(SSstation.announcer.event_sounds[sound]) + sound = SSstation.announcer.event_sounds[sound] if(type == "Priority") announcement += "

Priority Announcement

" @@ -26,113 +30,58 @@ else GLOB.news_network.SubmitArticle(title + "

" + text, "Central Command", "Station Announcements", null) - announcement += "
[html_encode(text)]
" + ///If the announcer overrides alert messages, use that message. + if(SSstation.announcer.custom_alert_message && !has_important_message) + announcement += SSstation.announcer.custom_alert_message + else + announcement += "
[span_alert("[html_encode(text)]")]
" announcement += "
" - var/s = sound(get_announcer_sound(sound)) + var/s = sound(sound) for(var/mob/M in GLOB.player_list) if(!isnewplayer(M) && M.can_hear()) to_chat(M, announcement) if(M.client.prefs.toggles & SOUND_ANNOUNCEMENTS) SEND_SOUND(M, s) -/proc/get_announcer_sound(soundid) - if(isfile(soundid)) - return soundid - else if(!istext(soundid)) - CRASH("Invalid type passed to get_announcer_sound()") - switch(GLOB.announcertype) //These are all individually hardcoded to allow the announcer sounds to be included in the rsc, reducing lag from sending resources midgame. - if("classic") - switch(soundid) - if("aimalf") - . = 'sound/announcer/classic/aimalf.ogg' - if("aliens") - . = 'sound/announcer/classic/aliens.ogg' - if("animes") - . = 'sound/announcer/classic/animes.ogg' - if("attention") - . = 'sound/announcer/classic/attention.ogg' - if("commandreport") - . = 'sound/announcer/classic/commandreport.ogg' - if("granomalies") - . = 'sound/announcer/classic/granomalies.ogg' - if("intercept") - . = 'sound/announcer/classic/intercept.ogg' - if("ionstorm") - . = 'sound/announcer/classic/ionstorm.ogg' - if("meteors") - . = 'sound/announcer/classic/meteors.ogg' - if("newAI") - . = 'sound/announcer/classic/newAI.ogg' - if("outbreak5") - . = 'sound/announcer/classic/outbreak5.ogg' - if("outbreak7") - . = 'sound/announcer/classic/outbreak7.ogg' - if("poweroff") - . = 'sound/announcer/classic/poweroff.ogg' - if("poweron") - . = 'sound/announcer/classic/poweron.ogg' - if("radiation") - . = 'sound/announcer/classic/radiation.ogg' - if("shuttlecalled") - . = 'sound/announcer/classic/shuttlecalled.ogg' - if("shuttledock") - . = 'sound/announcer/classic/shuttledock.ogg' - if("shuttlerecalled") - . = 'sound/announcer/classic/shuttlerecalled.ogg' - if("spanomalies") - . = 'sound/announcer/classic/spanomalies.ogg' - if("welcome") - . = 'sound/announcer/classic/welcome.ogg' - if("medibot") - switch(soundid) - if("aimalf") - . = 'sound/announcer/classic/aimalf.ogg' - if("aliens") - . = 'sound/announcer/medibot/aliens.ogg' - if("animes") - . = 'sound/announcer/medibot/animes.ogg' - if("attention") - . = 'sound/announcer/medibot/attention.ogg' - if("commandreport") - . = 'sound/announcer/medibot/commandreport.ogg' - if("granomalies") - . = 'sound/announcer/medibot/granomalies.ogg' - if("intercept") - . = 'sound/announcer/medibot/intercept.ogg' - if("ionstorm") - . = 'sound/announcer/medibot/ionstorm.ogg' - if("meteors") - . = 'sound/announcer/medibot/meteors.ogg' - if("newAI") - . = 'sound/announcer/medibot/newAI.ogg' - if("outbreak5") - . = 'sound/announcer/medibot/outbreak5.ogg' - if("outbreak7") - . = 'sound/announcer/medibot/outbreak7.ogg' - if("poweroff") - . = 'sound/announcer/medibot/poweroff.ogg' - if("poweron") - . = 'sound/announcer/medibot/poweron.ogg' - if("radiation") - . = 'sound/announcer/medibot/radiation.ogg' - if("shuttlecalled") - . = 'sound/announcer/medibot/shuttlecalled.ogg' - if("shuttledock") - . = 'sound/announcer/medibot/shuttledocked.ogg' - if("shuttlerecalled") - . = 'sound/announcer/medibot/shuttlerecalled.ogg' - if("spanomalies") - . = 'sound/announcer/medibot/spanomalies.ogg' - if("welcome") - . = 'sound/announcer/medibot/welcome.ogg' +/** + * Summon the crew for an emergency meeting + * + * Teleports the crew to a specified area, and tells everyone (via an announcement) who called the meeting. Should only be used during april fools! + * Arguments: + * * user - Mob who called the meeting + * * button_zone - Area where the meeting was called and where everyone will get teleported to + */ +/proc/call_emergency_meeting(mob/living/user, area/button_zone) + var/meeting_sound = sound('sound/misc/emergency_meeting.ogg') + var/announcement + announcement += "

Captain Alert

" + announcement += "
[span_alert("[user] has called an Emergency Meeting!")]

" + + for(var/mob/mob_to_teleport in GLOB.player_list) //gotta make sure the whole crew's here! + if(isnewplayer(mob_to_teleport) || iscameramob(mob_to_teleport)) + continue + to_chat(mob_to_teleport, announcement) + SEND_SOUND(mob_to_teleport, meeting_sound) //no preferences here, you must hear the funny sound + mob_to_teleport.overlay_fullscreen("emergency_meeting", /atom/movable/screen/fullscreen/scaled/emergency_meeting, 1) + addtimer(CALLBACK(mob_to_teleport, /mob/.proc/clear_fullscreen, "emergency_meeting"), 3 SECONDS) + + if (is_station_level(mob_to_teleport.z)) //teleport the mob to the crew meeting + var/turf/target + var/list/turf_list = get_area_turfs(button_zone) + while (!target && turf_list.len) + target = pick_n_take(turf_list) + if (isclosedturf(target)) + target = null + continue + mob_to_teleport.forceMove(target) /proc/print_command_report(text = "", title = null, announce=TRUE) if(!title) title = "Classified [command_name()] Update" if(announce) - priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") + priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", SSstation.announcer.get_rand_report_sound(), has_important_message = TRUE) var/datum/comm_message/M = new M.title = title @@ -140,13 +89,17 @@ SScommunications.send_message(M) -/proc/minor_announce(message, title = "Attention:", alert) +/proc/minor_announce(message, title = "Attention:", alert, html_encode = TRUE) if(!message) return + if (html_encode) + title = html_encode(title) + message = html_encode(message) + for(var/mob/M in GLOB.player_list) if(!isnewplayer(M) && M.can_hear()) - to_chat(M, "[html_encode(title)]
[html_encode(message)]

") + to_chat(M, "[span_minorannounce("[title]
[message]")]
") if(M.client.prefs.toggles & SOUND_ANNOUNCEMENTS) if(alert) SEND_SOUND(M, sound('sound/misc/notice1.ogg')) diff --git a/code/__HELPERS/pronouns.dm b/code/__HELPERS/pronouns.dm index bab286bafe..bfe09ba370 100644 --- a/code/__HELPERS/pronouns.dm +++ b/code/__HELPERS/pronouns.dm @@ -203,62 +203,62 @@ /mob/living/carbon/human/p_they(capitalized, temp_gender) var/list/obscured = check_obscured_slots() var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE)) - if((SLOT_W_UNIFORM in obscured) && skipface) + if((ITEM_SLOT_ICLOTHING in obscured) && skipface) temp_gender = PLURAL return ..() /mob/living/carbon/human/p_their(capitalized, temp_gender) var/list/obscured = check_obscured_slots() var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE)) - if((SLOT_W_UNIFORM in obscured) && skipface) + if((ITEM_SLOT_ICLOTHING in obscured) && skipface) temp_gender = PLURAL return ..() /mob/living/carbon/human/p_them(capitalized, temp_gender) var/list/obscured = check_obscured_slots() var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE)) - if((SLOT_W_UNIFORM in obscured) && skipface) + if((ITEM_SLOT_ICLOTHING in obscured) && skipface) temp_gender = PLURAL return ..() /mob/living/carbon/human/p_have(temp_gender) var/list/obscured = check_obscured_slots() var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE)) - if((SLOT_W_UNIFORM in obscured) && skipface) + if((ITEM_SLOT_ICLOTHING in obscured) && skipface) temp_gender = PLURAL return ..() /mob/living/carbon/human/p_are(temp_gender) var/list/obscured = check_obscured_slots() var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE)) - if((SLOT_W_UNIFORM in obscured) && skipface) + if((ITEM_SLOT_ICLOTHING in obscured) && skipface) temp_gender = PLURAL return ..() /mob/living/carbon/human/p_were(temp_gender) var/list/obscured = check_obscured_slots() var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE)) - if((SLOT_W_UNIFORM in obscured) && skipface) + if((ITEM_SLOT_ICLOTHING in obscured) && skipface) temp_gender = PLURAL return ..() /mob/living/carbon/human/p_do(temp_gender) var/list/obscured = check_obscured_slots() var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE)) - if((SLOT_W_UNIFORM in obscured) && skipface) + if((ITEM_SLOT_ICLOTHING in obscured) && skipface) temp_gender = PLURAL return ..() /mob/living/carbon/human/p_s(temp_gender) var/list/obscured = check_obscured_slots() var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE)) - if((SLOT_W_UNIFORM in obscured) && skipface) + if((ITEM_SLOT_ICLOTHING in obscured) && skipface) temp_gender = PLURAL return ..() /mob/living/carbon/human/p_es(temp_gender) var/list/obscured = check_obscured_slots() var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE)) - if((SLOT_W_UNIFORM in obscured) && skipface) + if((ITEM_SLOT_ICLOTHING in obscured) && skipface) temp_gender = PLURAL return ..() diff --git a/code/__HELPERS/radiation.dm b/code/__HELPERS/radiation.dm index d527d0ac51..c80f3f012c 100644 --- a/code/__HELPERS/radiation.dm +++ b/code/__HELPERS/radiation.dm @@ -27,6 +27,10 @@ /proc/radiation_pulse(atom/source, intensity, range_modifier, log=FALSE, can_contaminate=TRUE) if(!SSradiation.can_fire) return + var/turf/open/pool/PL = get_turf(source) + if(istype(PL)) + if(PL.filled == TRUE) + intensity *= 0.15 var/area/A = get_area(source) var/atom/nested_loc = source.loc var/spawn_waves = TRUE @@ -52,6 +56,5 @@ thing.rad_act(intensity) if(log) - var/turf/_source_T = get_turf(source) - log_game("Radiation pulse with intensity: [intensity] and range modifier: [range_modifier] in [loc_name(_source_T)][spawn_waves ? "" : " (contained by [nested_loc.name])"]") + log_game("Radiation pulse with intensity: [intensity] and range modifier: [range_modifier] in [loc_name(PL)][spawn_waves ? "" : " (contained by [nested_loc.name])"]") return TRUE diff --git a/code/__HELPERS/radio.dm b/code/__HELPERS/radio.dm index dc52299025..e761a3a23c 100644 --- a/code/__HELPERS/radio.dm +++ b/code/__HELPERS/radio.dm @@ -1,4 +1,4 @@ -// Ensure the frequency is within bounds of what it should be sending/receiving at +/// Ensure the frequency is within bounds of what it should be sending/receiving at /proc/sanitize_frequency(frequency, free = FALSE) frequency = round(frequency) if(free) @@ -8,12 +8,26 @@ if(!(. % 2)) // Ensure the last digit is an odd number . += 1 -// Format frequency by moving the decimal. +/// Format frequency by moving the decimal. /proc/format_frequency(frequency) frequency = text2num(frequency) return "[round(frequency / 10)].[frequency % 10]" -//Opposite of format, returns as a number +///Opposite of format, returns as a number /proc/unformat_frequency(frequency) frequency = text2num(frequency) return frequency * 10 + +///returns a random unused frequency between MIN_FREE_FREQ & MAX_FREE_FREQ if free = TRUE, and MIN_FREQ & MAX_FREQ if FALSE +/proc/return_unused_frequency(free = FALSE) + var/start = free ? MIN_FREE_FREQ : MIN_FREQ + var/end = free ? MAX_FREE_FREQ : MAX_FREQ + + var/freq_to_check = 0 + do + freq_to_check = rand(start, end) + if(!(freq_to_check % 2)) // Ensure the last digit is an odd number + freq_to_check++ + while((freq_to_check == 0) || ("[freq_to_check]" in GLOB.reverseradiochannels)) + + return freq_to_check diff --git a/code/__HELPERS/reagents.dm b/code/__HELPERS/reagents.dm index fa655efce4..0ecf82b191 100644 --- a/code/__HELPERS/reagents.dm +++ b/code/__HELPERS/reagents.dm @@ -101,3 +101,9 @@ return GLOB.chemical_reagents_list[input] else return null + +//Checks for if the given reagent R is invalid to process for its passed owner. +/proc/is_reagent_processing_invalid(datum/reagent/R, mob/living/owner) + if(!R || !owner) + return TRUE + return ((HAS_TRAIT(owner, TRAIT_ROBOTIC_ORGANISM) && !(R.chemical_flags & REAGENT_ROBOTIC_PROCESS)) || (!HAS_TRAIT(owner, TRAIT_ROBOTIC_ORGANISM) && !(R.chemical_flags & REAGENT_ORGANIC_PROCESS))) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 2c13f30707..469f27926a 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -218,20 +218,14 @@ to_chat(world, "


The round has ended.") log_game("The round has ended.") - if(LAZYLEN(GLOB.round_end_notifiees)) - world.TgsTargetedChatBroadcast("[GLOB.round_end_notifiees.Join(", ")] the round has ended.", FALSE) + + CONFIG_SET(flag/suicide_allowed,TRUE) // EORG suicides allowed for(var/I in round_end_events) var/datum/callback/cb = I cb.InvokeAsync() LAZYCLEARLIST(round_end_events) - for(var/client/C in GLOB.clients) - if(!C.credits) - C.RollCredits() - C.playtitlemusic(40) - CONFIG_SET(flag/suicide_allowed,TRUE) // EORG suicides allowed - var/speed_round = FALSE if(world.time - SSticker.round_start_time <= 300 SECONDS) speed_round = TRUE @@ -268,8 +262,20 @@ send_news_report() //tell the nice people on discord what went on before the salt cannon happens. - world.TgsTargetedChatBroadcast("The current round has ended. Please standby for your shift interlude Nanotrasen News Network's report!", FALSE) - world.TgsTargetedChatBroadcast(send_news_report(),FALSE) + if(CONFIG_GET(string/chat_roundend_notice_tag)) + var/broadcastmessage = "" + + if(LAZYLEN(GLOB.round_end_notifiees)) + broadcastmessage += "[GLOB.round_end_notifiees.Join(", ")], " + + + broadcastmessage += "[((broadcastmessage == "") ? "the" : "The")] current round has ended. Please standby for your shift interlude Nanotrasen News Network's report!\n" + broadcastmessage += "```\n[send_news_report()]\n```" + + if(CONFIG_GET(string/chat_reboot_role)) + broadcastmessage += "\n\n<@&[CONFIG_GET(string/chat_reboot_role)]>, the server will reboot shortly!" + + send2chat(broadcastmessage, CONFIG_GET(string/chat_roundend_notice_tag)) CHECK_TICK @@ -354,6 +360,7 @@ /datum/controller/subsystem/ticker/proc/survivor_report(popcount) var/list/parts = list() var/station_evacuated = EMERGENCY_ESCAPED_OR_ENDGAMED + var/datum/game_mode/dynamic/mode = SSticker.mode if(GLOB.round_id) var/statspage = CONFIG_GET(string/roundstatsurl) @@ -372,6 +379,8 @@ parts += "[FOURSPACES]Shift Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]" parts += "[FOURSPACES]Station Integrity: [mode.station_was_nuked ? "Destroyed" : "[popcount["station_integrity"]]%"]" + if(mode.station_was_nuked && SSevents.holidays && SSevents.holidays[PRIDE_MONTH]) + parts += "[FOURSPACES]Gender revealed: [pick(500; "Male", 500; "Female", "Bigender", "Agender", "Demiboy", "Demigirl", "Genderfluid", "Pangender", "Xenogender", "Clown", 50; "What", 50; "Oh no.", 50; "Excuse me?")]" var/total_players = GLOB.joined_player_list.len if(total_players) parts+= "[FOURSPACES]Total Population: [total_players]" @@ -386,27 +395,14 @@ //ignore this comment, it fixes the broken sytax parsing caused by the " above else parts += "[FOURSPACES]Nobody died this shift!" - var/avg_threat = SSactivity.get_average_threat() - var/max_threat = SSactivity.get_max_threat() - parts += "[FOURSPACES]Threat at round end: [SSactivity.current_threat]" - parts += "[FOURSPACES]Average threat: [avg_threat]" - parts += "[FOURSPACES]Max threat: [max_threat]" if(istype(SSticker.mode, /datum/game_mode/dynamic)) - var/datum/game_mode/dynamic/mode = SSticker.mode - mode.update_playercounts() // ? - parts += "[FOURSPACES]Target threat: [mode.threat_level]" + parts += "[FOURSPACES]Initial threat level: [mode.threat_level]" + parts += "[FOURSPACES]Initial roundstart threat: [mode.initial_round_start_budget]" + parts += "[FOURSPACES]Roundstart budget after antags: [mode.round_start_budget]" + parts += "[FOURSPACES]Midround budget at round end: [mode.mid_round_budget]" parts += "[FOURSPACES]Executed rules:" for(var/datum/dynamic_ruleset/rule in mode.executed_rules) parts += "[FOURSPACES][FOURSPACES][rule.ruletype] - [rule.name]: -[rule.cost + rule.scaled_times * rule.scaling_cost] threat" - parts += "[FOURSPACES]Other threat changes:" - for(var/str in mode.threat_log) - parts += "[FOURSPACES][FOURSPACES][str]" - for(var/entry in mode.threat_tallies) - parts += "[FOURSPACES][FOURSPACES][entry] added [mode.threat_tallies[entry]]" - SSblackbox.record_feedback("tally","threat",mode.threat_level,"Target threat") - SSblackbox.record_feedback("tally","threat",SSactivity.current_threat,"Final Threat") - SSblackbox.record_feedback("tally","threat",avg_threat,"Average Threat") - SSblackbox.record_feedback("tally","threat",max_threat,"Max Threat") return parts.Join("
") /client/proc/roundend_report_file() @@ -543,24 +539,27 @@ ///Generate a report for how much money is on station, as well as the richest crewmember on the station. /datum/controller/subsystem/ticker/proc/market_report() var/list/parts = list() - parts += "Station Economic Summary:" + ///This is the richest account on station at roundend. var/datum/bank_account/mr_moneybags ///This is the station's total wealth at the end of the round. var/station_vault = 0 ///How many players joined the round. var/total_players = GLOB.joined_player_list.len - var/list/typecache_bank = typecacheof(list(/datum/bank_account/department, /datum/bank_account/remote)) - for(var/datum/bank_account/current_acc in SSeconomy.generated_accounts) + var/static/list/typecache_bank = typecacheof(list(/datum/bank_account/department, /datum/bank_account/remote)) + for(var/i in SSeconomy.generated_accounts) + var/datum/bank_account/current_acc = SSeconomy.generated_accounts[i] if(typecache_bank[current_acc.type]) continue station_vault += current_acc.account_balance if(!mr_moneybags || mr_moneybags.account_balance < current_acc.account_balance) mr_moneybags = current_acc - parts += "
There were [station_vault] credits collected by crew this shift.
" + parts += "
Station Economic Summary:
" + parts += "General Statistics:
" + parts += "There were [station_vault] credits collected by crew this shift.
" if(total_players > 0) parts += "An average of [station_vault/total_players] credits were collected.
" - // log_econ("Roundend credit total: [station_vault] credits. Average Credits: [station_vault/total_players]") + log_econ("Roundend credit total: [station_vault] credits. Average Credits: [station_vault/total_players]") if(mr_moneybags) parts += "The most affluent crew member at shift end was [mr_moneybags.account_holder] with [mr_moneybags.account_balance] cr!
" else @@ -602,8 +601,8 @@ var/list/all_teams = list() var/list/all_antagonists = list() - // for(var/datum/team/A in GLOB.antagonist_teams) - // all_teams |= A + for(var/datum/team/A in GLOB.antagonist_teams) + all_teams |= A for(var/datum/antagonist/A in GLOB.antagonists) if(!A.owner) @@ -636,6 +635,10 @@ currrent_category = A.roundend_category previous_category = A result += A.roundend_report() +//ambition start + for(var/count in 1 to LAZYLEN(A.owner.ambitions)) + result += "
Ambition #[count]: [A.owner.ambitions[count]]" +//ambition end result += "

" CHECK_TICK diff --git a/code/__HELPERS/sanitize_values.dm b/code/__HELPERS/sanitize_values.dm index 0441e0bcb7..c4708f81f6 100644 --- a/code/__HELPERS/sanitize_values.dm +++ b/code/__HELPERS/sanitize_values.dm @@ -157,10 +157,7 @@ #undef RGB_FORMAT_SHORT #undef RGB_FORMAT_LONG +/// Makes sure the input color is text with a # at the start followed by 6 hexadecimal characters. Examples: "#ff1234", "#A38321", COLOR_GREEN_GRAY /proc/sanitize_ooccolor(color) - if(length(color) != length_char(color)) - CRASH("Invalid characters in color '[color]'") - var/list/HSL = rgb2hsl(hex2num(copytext(color, 2, 4)), hex2num(copytext(color, 4, 6)), hex2num(copytext(color, 6, 8))) - HSL[3] = min(HSL[3],0.4) - var/list/RGB = hsl2rgb(arglist(HSL)) - return "#[num2hex(RGB[1],2)][num2hex(RGB[2],2)][num2hex(RGB[3],2)]" + var/static/regex/color_regex = regex(@"^#[0-9a-fA-F]{6}$") + return findtext(color, color_regex) ? color : GLOB.normal_ooc_colour diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm index 2e27588ae5..519a54b38d 100644 --- a/code/__HELPERS/time.dm +++ b/code/__HELPERS/time.dm @@ -75,10 +75,8 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) /proc/daysSince(realtimev) return round((world.realtime - realtimev) / (24 HOURS)) -/proc/worldtime2text() - return gameTimestamp("hh:mm:ss", world.time) +/proc/worldtime2text(wtime = world.timeofday) + return gameTimestamp("hh:mm:ss", wtime) -/proc/gameTimestamp(format = "hh:mm:ss", wtime=null) - if(!wtime) - wtime = world.time +/proc/gameTimestamp(format = "hh:mm:ss", wtime=world.time) return time2text(wtime - GLOB.timezoneOffset, format) diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 87187a4c3d..3939fb94cc 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -412,25 +412,25 @@ /proc/slot2body_zone(slot) switch(slot) - if(SLOT_BACK, SLOT_WEAR_SUIT, SLOT_W_UNIFORM, SLOT_BELT, SLOT_WEAR_ID) + if(ITEM_SLOT_BACK, ITEM_SLOT_OCLOTHING, ITEM_SLOT_ICLOTHING, ITEM_SLOT_BELT, ITEM_SLOT_ID) return BODY_ZONE_CHEST - if(SLOT_GLOVES, SLOT_HANDS, SLOT_HANDCUFFED) + if(ITEM_SLOT_GLOVES, ITEM_SLOT_HANDS, ITEM_SLOT_HANDCUFFED) return pick(BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND) - if(SLOT_HEAD, SLOT_NECK, SLOT_NECK, SLOT_EARS) + if(ITEM_SLOT_HEAD, ITEM_SLOT_NECK, ITEM_SLOT_NECK, ITEM_SLOT_EARS) return BODY_ZONE_HEAD - if(SLOT_WEAR_MASK) + if(ITEM_SLOT_MASK) return BODY_ZONE_PRECISE_MOUTH - if(SLOT_GLASSES) + if(ITEM_SLOT_EYES) return BODY_ZONE_PRECISE_EYES - if(SLOT_SHOES) + if(ITEM_SLOT_FEET) return pick(BODY_ZONE_PRECISE_R_FOOT, BODY_ZONE_PRECISE_L_FOOT) - if(SLOT_LEGCUFFED) + if(ITEM_SLOT_LEGCUFFED) return pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) //adapted from http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ @@ -591,9 +591,9 @@ switch(child) if(/datum) return null - if(/obj || /mob) + if(/obj, /mob) return /atom/movable - if(/area || /turf) + if(/area, /turf) return /atom else return /datum @@ -652,31 +652,31 @@ /proc/slot_to_string(slot) switch(slot) - if(SLOT_BACK) + if(ITEM_SLOT_BACK) return "Backpack" - if(SLOT_WEAR_MASK) + if(ITEM_SLOT_MASK) return "Mask" - if(SLOT_HANDS) + if(ITEM_SLOT_HANDS) return "Hands" - if(SLOT_BELT) + if(ITEM_SLOT_BELT) return "Belt" - if(SLOT_EARS) + if(ITEM_SLOT_EARS) return "Ears" - if(SLOT_GLASSES) + if(ITEM_SLOT_EYES) return "Glasses" - if(SLOT_GLOVES) + if(ITEM_SLOT_GLOVES) return "Gloves" - if(SLOT_NECK) + if(ITEM_SLOT_NECK) return "Neck" - if(SLOT_HEAD) + if(ITEM_SLOT_HEAD) return "Head" - if(SLOT_SHOES) + if(ITEM_SLOT_FEET) return "Shoes" - if(SLOT_WEAR_SUIT) + if(ITEM_SLOT_OCLOTHING) return "Suit" - if(SLOT_W_UNIFORM) + if(ITEM_SLOT_ICLOTHING) return "Uniform" - if(SLOT_IN_BACKPACK) + if(ITEM_SLOT_BACKPACK) return "In backpack" /proc/tg_ui_icon_to_cit_ui(ui_style) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 9fee97bbb1..980b377356 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -357,16 +357,27 @@ Turf and target are separate in case you want to teleport some distance from a t if(M.ckey == key) return M -//Returns the atom sitting on the turf. -//For example, using this on a disk, which is in a bag, on a mob, will return the mob because it's on the turf. -//Optional arg 'type' to stop once it reaches a specific type instead of a turf. -/proc/get_atom_on_turf(atom/movable/M, stop_type) - var/atom/loc = M - while(loc && loc.loc && !isturf(loc.loc)) - loc = loc.loc - if(stop_type && istype(loc, stop_type)) +/** + * Returns the top-most atom sitting on the turf. + * For example, using this on a disk, which is in a bag, on a mob, + * will return the mob because it's on the turf. + * + * Arguments + * * something_in_turf - a movable within the turf, somewhere. + * * stop_type - optional - stops looking if stop_type is found in the turf, returning that type (if found). + **/ +/proc/get_atom_on_turf(atom/movable/something_in_turf, stop_type) + if(!istype(something_in_turf)) + CRASH("get_atom_on_turf was not passed an /atom/movable! Got [isnull(something_in_turf) ? "null":"type: [something_in_turf.type]"]") + + var/atom/movable/topmost_thing = something_in_turf + + while(topmost_thing?.loc && !isturf(topmost_thing.loc)) + topmost_thing = topmost_thing.loc + if(stop_type && istype(topmost_thing, stop_type)) break - return loc + + return topmost_thing //Returns a list of all locations the target is within. /proc/get_nested_locs(atom/movable/M, include_turf = FALSE) @@ -662,11 +673,32 @@ Turf and target are separate in case you want to teleport some distance from a t if(final_x || final_y) return locate(final_x, final_y, T.z) +///Returns a turf based on text inputs, original turf and viewing client +/proc/parse_caught_click_modifiers(list/modifiers, turf/origin, client/viewing_client) + if(!modifiers) + return null + + var/screen_loc = splittext(LAZYACCESS(modifiers, SCREEN_LOC), ",") + var/list/actual_view = getviewsize(viewing_client ? viewing_client.view : world.view) + var/click_turf_x = splittext(screen_loc[1], ":") + var/click_turf_y = splittext(screen_loc[2], ":") + var/click_turf_z = origin.z + + var/click_turf_px = text2num(click_turf_x[2]) + var/click_turf_py = text2num(click_turf_y[2]) + click_turf_x = origin.x + text2num(click_turf_x[1]) - round(actual_view[1] / 2) - 1 + click_turf_y = origin.y + text2num(click_turf_y[1]) - round(actual_view[2] / 2) - 1 + + var/turf/click_turf = locate(clamp(click_turf_x, 1, world.maxx), clamp(click_turf_y, 1, world.maxy), click_turf_z) + LAZYSET(modifiers, ICON_X, "[(click_turf_px - click_turf.pixel_x) + ((click_turf_x - click_turf.x) * world.icon_size)]") + LAZYSET(modifiers, ICON_Y, "[(click_turf_py - click_turf.pixel_y) + ((click_turf_y - click_turf.y) * world.icon_size)]") + return click_turf + //Finds the distance between two atoms, in pixels -//centered = 0 counts from turf edge to edge -//centered = 1 counts from turf center to turf center +//centered = FALSE counts from turf edge to edge +//centered = TRUE counts from turf center to turf center //of course mathematically this is just adding world.icon_size on again -/proc/getPixelDistance(atom/A, atom/B, centered = 1) +/proc/getPixelDistance(atom/A, atom/B, centered = TRUE) if(!istype(A)||!istype(B)) return 0 . = bounds_dist(A, B) + sqrt((((A.pixel_x+B.pixel_x)**2) + ((A.pixel_y+B.pixel_y)**2))) @@ -1165,25 +1197,22 @@ GLOBAL_REAL_VAR(list/stack_trace_storage) var/initialpixely = pixel_y var/shiftx = rand(-pixelshiftx,pixelshiftx) var/shifty = rand(-pixelshifty,pixelshifty) - animate(src, pixel_x = pixel_x + shiftx, pixel_y = pixel_y + shifty, time = 0.2, loop = duration) - pixel_x = initialpixelx - pixel_y = initialpixely + animate(src, pixel_x = shiftx, pixel_y = shifty, time = 0.2, loop = duration, flags = ANIMATION_RELATIVE) + animate(pixel_x = initialpixelx, pixel_y = initialpixely, time = 0.2) -/atom/proc/do_jiggle(targetangle = 45, timer = 20) +/atom/proc/do_jiggle(targetangle = 25, timer = 20) var/matrix/OM = matrix(transform) var/matrix/M = matrix(transform) - var/halftime = timer * 0.5 M.Turn(pick(-targetangle, targetangle)) - animate(src, transform = M, time = halftime, easing = ELASTIC_EASING) - animate(src, transform = OM, time = halftime, easing = ELASTIC_EASING) + animate(src, transform = M, time = timer * 0.1, easing = BACK_EASING | EASE_IN) + animate(transform = OM, time = timer * 0.4, easing = ELASTIC_EASING) /atom/proc/do_squish(squishx = 1.2, squishy = 0.6, timer = 20) var/matrix/OM = matrix(transform) var/matrix/M = matrix(transform) - var/halftime = timer * 0.5 M.Scale(squishx, squishy) - animate(src, transform = M, time = halftime, easing = BOUNCE_EASING) - animate(src, transform = OM, time = halftime, easing = BOUNCE_EASING) + animate(src, transform = M, time = timer * 0.5, easing = ELASTIC_EASING) + animate(transform = OM, time = timer * 0.5, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL) /proc/weightclass2text(var/w_class) switch(w_class) @@ -1224,7 +1253,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) move_resist = INFINITY var/ready_to_die = FALSE -/mob/dview/Initialize() //Properly prevents this mob from gaining huds or joining any global lists +/mob/dview/Initialize(mapload) //Properly prevents this mob from gaining huds or joining any global lists SHOULD_CALL_PARENT(FALSE) if(flags_1 & INITIALIZED_1) stack_trace("Warning: [src]([type]) initialized multiple times!") @@ -1311,7 +1340,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) return temp //same as do_mob except for movables and it allows both to drift and doesn't draw progressbar -/proc/do_atom(atom/movable/user , atom/movable/target, time = 30, uninterruptible = 0,datum/callback/extra_checks = null) +/proc/do_atom(atom/movable/user, atom/movable/target, time = 3 SECONDS, timed_action_flags = NONE, datum/callback/extra_checks) if(!user || !target) return TRUE var/user_loc = user.loc @@ -1330,11 +1359,10 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) . = TRUE while (world.time < endtime) stoplag(1) + if(QDELETED(user) || QDELETED(target)) - . = 0 + . = FALSE break - if(uninterruptible) - continue if(drifting && !user.inertia_dir) drifting = FALSE @@ -1344,7 +1372,11 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) target_drifting = FALSE target_loc = target.loc - if((!drifting && user.loc != user_loc) || (!target_drifting && target.loc != target_loc) || (extra_checks && !extra_checks.Invoke())) + if( + (!(timed_action_flags & IGNORE_USER_LOC_CHANGE) && !drifting && user.loc != user_loc) \ + || (!(timed_action_flags& IGNORE_TARGET_LOC_CHANGE) && !target_drifting && target.loc != target_loc) \ + || (extra_checks && !extra_checks.Invoke()) \ + ) . = FALSE break @@ -1600,7 +1632,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) if(!iscarbon(target)) return TRUE if(check_neck) - if(istype(target.get_item_by_slot(SLOT_NECK), /obj/item/clothing/neck/garlic_necklace)) + if(istype(target.get_item_by_slot(ITEM_SLOT_NECK), /obj/item/clothing/neck/garlic_necklace)) return FALSE if(check_blood) if(target.reagents.has_reagent(/datum/reagent/consumable/garlic)) diff --git a/code/__HELPERS/weakref.dm b/code/__HELPERS/weakref.dm new file mode 100644 index 0000000000..0b007332ef --- /dev/null +++ b/code/__HELPERS/weakref.dm @@ -0,0 +1,2 @@ +/// Checks if potential_weakref is a weakref of thing. +#define IS_WEAKREF_OF(thing, potential_weakref) (istype(thing, /datum) && !isnull(potential_weakref) && thing.weak_reference == potential_weakref) diff --git a/code/__byond_version_compat.dm b/code/__byond_version_compat.dm new file mode 100644 index 0000000000..aed9bbf176 --- /dev/null +++ b/code/__byond_version_compat.dm @@ -0,0 +1,34 @@ +// So we want to have compile time guarantees these methods exist on local type, unfortunately 515 killed the .proc/procname and .verb/verbname syntax so we have to use nameof() +// For the record: GLOBAL_VERB_REF would be useless as verbs can't be global. + +#if DM_VERSION < 515 + +/// Call by name proc references, checks if the proc exists on either this type or as a global proc. +#define PROC_REF(X) (.proc/##X) +/// Call by name verb references, checks if the verb exists on either this type or as a global verb. +#define VERB_REF(X) (.verb/##X) + +/// Call by name proc reference, checks if the proc exists on either the given type or as a global proc +#define TYPE_PROC_REF(TYPE, X) (##TYPE.proc/##X) +/// Call by name verb reference, checks if the verb exists on either the given type or as a global verb +#define TYPE_VERB_REF(TYPE, X) (##TYPE.verb/##X) + +/// Call by name proc reference, checks if the proc is an existing global proc +#define GLOBAL_PROC_REF(X) (/proc/##X) + +#else + +/// Call by name proc references, checks if the proc exists on either this type or as a global proc. +#define PROC_REF(X) (nameof(.proc/##X)) +/// Call by name verb references, checks if the verb exists on either this type or as a global verb. +#define VERB_REF(X) (nameof(.verb/##X)) + +/// Call by name proc reference, checks if the proc exists on either the given type or as a global proc +#define TYPE_PROC_REF(TYPE, X) (nameof(##TYPE.proc/##X)) +/// Call by name verb reference, checks if the verb exists on either the given type or as a global verb +#define TYPE_VERB_REF(TYPE, X) (nameof(##TYPE.verb/##X)) + +/// Call by name proc reference, checks if the proc is an existing global proc +#define GLOBAL_PROC_REF(X) (/proc/##X) + +#endif diff --git a/code/_compile_options.dm b/code/_compile_options.dm index 64b4129024..1aca8959c2 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -1,7 +1,7 @@ -//#define TESTING //By using the testing("message") proc you can create debug-feedback for people with this +//#define TESTING //By using the testing("message") proc you can create debug-feedback for people with this //uncommented, but not visible in the release version) -//#define DATUMVAR_DEBUGGING_MODE //Enables the ability to cache datum vars and retrieve later for debugging which vars changed. +//#define DATUMVAR_DEBUGGING_MODE //Enables the ability to cache datum vars and retrieve later for debugging which vars changed. // Comment this out if you are debugging problems that might be obscured by custom error handling in world/Error #ifdef DEBUG @@ -11,34 +11,44 @@ #ifdef TESTING #define DATUMVAR_DEBUGGING_MODE -/* -* Enables extools-powered reference tracking system, letting you see what is referencing objects that refuse to hard delete. -* -* * Requires TESTING to be defined to work. -*/ +///Used to find the sources of harddels, quite laggy, don't be surpised if it freezes your client for a good while //#define REFERENCE_TRACKING +#ifdef REFERENCE_TRACKING -///Method of tracking references without using extools. Slower, kept to avoid over-reliance on extools. -//#define LEGACY_REFERENCE_TRACKING -#ifdef LEGACY_REFERENCE_TRACKING +///alternate to reftracking, extool variant +//#define EXTOOLS_REFERENCE_TRACKING -///Use the legacy reference on things hard deleting by default. +///Should we be logging our findings or not +#define REFERENCE_TRACKING_LOG + +///Used for doing dry runs of the reference finder, to test for feature completeness +//#define REFERENCE_TRACKING_DEBUG + +///Run a lookup on things hard deleting by default. //#define GC_FAILURE_HARD_LOOKUP #ifdef GC_FAILURE_HARD_LOOKUP #define FIND_REF_NO_CHECK_TICK #endif //ifdef GC_FAILURE_HARD_LOOKUP -#endif //ifdef LEGACY_REFERENCE_TRACKING +#endif //ifdef REFERENCE_TRACKING -//#define VISUALIZE_ACTIVE_TURFS //Highlights atmos active turfs in green +/* +* Enables debug messages for every single reaction step. This is 1 message per 0.5s for a SINGLE reaction. Useful for tracking down bugs/asking me for help in the main reaction handiler (equilibrium.dm). +* +* * Requires TESTING to be defined to work. +*/ +//#define REAGENTS_TESTING +// #define VISUALIZE_ACTIVE_TURFS //Highlights atmos active turfs in green +// #define TRACK_MAX_SHARE //Allows max share tracking, for use in the atmos debugging ui #endif //ifdef TESTING -//#define UNIT_TESTS //Enables unit tests via TEST_RUN_PARAMETER -#ifndef PRELOAD_RSC //set to: -#define PRELOAD_RSC 2 // 0 to allow using external resources or on-demand behaviour; -#endif // 1 to use the default behaviour; - // 2 for preloading absolutely everything; +//#define UNIT_TESTS //If this is uncommented, we do a single run though of the game setup and tear down process with unit tests in between + +#ifndef PRELOAD_RSC //set to: +#define PRELOAD_RSC 2 // 0 to allow using external resources or on-demand behaviour; +#endif // 1 to use the default behaviour; + // 2 for preloading absolutely everything; #ifdef LOWMEMORYMODE #define FORCE_MAP "_maps/runtimestation.json" @@ -47,7 +57,7 @@ //Update this whenever you need to take advantage of more recent byond features #define MIN_COMPILER_VERSION 513 #define MIN_COMPILER_BUILD 1514 -#if DM_VERSION < MIN_COMPILER_VERSION || DM_BUILD < MIN_COMPILER_BUILD +#if (DM_VERSION < MIN_COMPILER_VERSION || DM_BUILD < MIN_COMPILER_BUILD) && !defined(SPACEMAN_DMM) //Don't forget to update this part #error Your version of BYOND is too out-of-date to compile this project. Go to https://secure.byond.com/download and update. #error You need version 513.1514 or higher @@ -58,10 +68,6 @@ #warn compiling in TESTING mode. testing() debug messages will be visible. #endif -#ifdef GC_FAILURE_HARD_LOOKUP -#define FIND_REF_NO_CHECK_TICK -#endif - #ifdef CIBUILDING #define UNIT_TESTS #endif @@ -70,6 +76,24 @@ #define TESTING #endif +#if defined(UNIT_TESTS) +//Hard del testing defines +#define REFERENCE_TRACKING +#define REFERENCE_TRACKING_DEBUG +#define FIND_REF_NO_CHECK_TICK +#endif + +#ifdef TGS +// TGS performs its own build of dm.exe, but includes a prepended TGS define. +#define CBT +#endif + // A reasonable number of maximum overlays an object needs // If you think you need more, rethink it #define MAX_ATOM_OVERLAYS 100 + +#if !defined(CBT) && !defined(SPACEMAN_DMM) +#warn Building with Dream Maker is no longer supported and will result in errors. +#warn In order to build, run BUILD.bat in the root directory. +#warn Consider switching to VSCode editor instead, where you can press Ctrl+Shift+B to build. +#endif diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 781fa38b94..d16c24be44 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -1,325 +1,534 @@ -GLOBAL_LIST_INIT(bitfields, list( - "appearance_flags" = list( - "LONG_GLIDE" = LONG_GLIDE, - "RESET_COLOR" = RESET_COLOR, - "RESET_ALPHA" = RESET_ALPHA, - "RESET_TRANSFORM" = RESET_TRANSFORM, - "NO_CLIENT_COLOR" = NO_CLIENT_COLOR, - "KEEP_TOGETHER" = KEEP_TOGETHER, - "KEEP_APART" = KEEP_APART, - "PLANE_MASTER" = PLANE_MASTER, - "TILE_BOUND" = TILE_BOUND, - "PIXEL_SCALE" = PIXEL_SCALE - ), - "area_flags" = list( - "ABDUCTOR_PROOF" = ABDUCTOR_PROOF, - "BLOBS_ALLOWED" = BLOBS_ALLOWED, - "BLOCK_SUICIDE" = BLOCK_SUICIDE, - "CULT_PERMITTED" = CULT_PERMITTED, - "FLORA_ALLOWED" = FLORA_ALLOWED, - "HIDDEN_AREA" = HIDDEN_AREA, - "MEGAFAUNA_SPAWN_ALLOWED" = MEGAFAUNA_SPAWN_ALLOWED, - "MOB_SPAWN_ALLOWED" = MOB_SPAWN_ALLOWED, - "NO_ALERTS" = NO_ALERTS, - "NOTELEPORT" = NOTELEPORT, - "CAVES_ALLOWED" = CAVES_ALLOWED, - "UNIQUE_AREA" = UNIQUE_AREA, - "VALID_TERRITORY" = VALID_TERRITORY, - "XENOBIOLOGY_COMPATIBLE" = XENOBIOLOGY_COMPATIBLE, - "NO_ALERTS" = NO_ALERTS, - ) , - "sight" = list( - "SEE_INFRA" = SEE_INFRA, - "SEE_SELF" = SEE_SELF, - "SEE_MOBS" = SEE_MOBS, - "SEE_OBJS" = SEE_OBJS, - "SEE_TURFS" = SEE_TURFS, - "SEE_PIXELS" = SEE_PIXELS, - "SEE_THRU" = SEE_THRU, - "SEE_BLACKNESS" = SEE_BLACKNESS, - "BLIND" = BLIND - ), - "obj_flags" = list( - "EMAGGED" = EMAGGED, - "IN_USE" = IN_USE, - "CAN_BE_HIT" = CAN_BE_HIT, - "BEING_SHOCKED" = BEING_SHOCKED, - "DANGEROUS_POSSESSION" = DANGEROUS_POSSESSION, - "ON_BLUEPRINTS" = ON_BLUEPRINTS, - "UNIQUE_RENAME" = UNIQUE_RENAME, - "USES_TGUI" = USES_TGUI, - "FROZEN" = FROZEN, - "SHOVABLE_ONTO" = SHOVABLE_ONTO, - "BLOCK_Z_OUT_DOWN" = BLOCK_Z_OUT_DOWN, - "BLOCK_Z_OUT_UP" = BLOCK_Z_OUT_UP, - "BLOCK_Z_IN_DOWN" = BLOCK_Z_IN_DOWN, - "BLOCK_Z_IN_UP" = BLOCK_Z_IN_UP, - "EXAMINE_SKIP" = EXAMINE_SKIP - ), - "datum_flags" = list( - "DF_USE_TAG" = DF_USE_TAG, - "DF_VAR_EDITED" = DF_VAR_EDITED, - "DF_ISPROCESSING" = DF_ISPROCESSING, - ), - "item_flags" = list( - "BEING_REMOVED" = BEING_REMOVED, - "IN_INVENTORY" = IN_INVENTORY, - "FORCE_STRING_OVERRIDE" = FORCE_STRING_OVERRIDE, - "NEEDS_PERMIT" = NEEDS_PERMIT, - "SLOWS_WHILE_IN_HAND" = SLOWS_WHILE_IN_HAND, - "NO_MAT_REDEMPTION" = NO_MAT_REDEMPTION, - "DROPDEL" = DROPDEL, - "NOBLUDGEON" = NOBLUDGEON, - "ABSTRACT" = ABSTRACT, - "ITEM_CAN_BLOCK" = ITEM_CAN_BLOCK, - "ITEM_CAN_PARRY" = ITEM_CAN_PARRY - ), - "admin_flags" = list( - "BUILDMODE" = R_BUILDMODE, - "ADMIN" = R_ADMIN, - "BAN" = R_BAN, - "FUN" = R_FUN, - "SERVER" = R_SERVER, - "DEBUG" = R_DEBUG, - "POSSESS" = R_POSSESS, - "PERMISSIONS" = R_PERMISSIONS, - "STEALTH" = R_STEALTH, - "POLL" = R_POLL, - "VAREDIT" = R_VAREDIT, - "SOUNDS" = R_SOUNDS, - "SPAWN" = R_SPAWN, - "AUTOLOGIN" = R_AUTOLOGIN, - "DBRANKS" = R_DBRANKS, - "SENSITIVE" = R_SENSITIVE - ), - "interaction_flags_atom" = list( - "INTERACT_ATOM_REQUIRES_ANCHORED" = INTERACT_ATOM_REQUIRES_ANCHORED, - "INTERACT_ATOM_ATTACK_HAND" = INTERACT_ATOM_ATTACK_HAND, - "INTERACT_ATOM_UI_INTERACT" = INTERACT_ATOM_UI_INTERACT, - "INTERACT_ATOM_REQUIRES_DEXTERITY" = INTERACT_ATOM_REQUIRES_DEXTERITY, - "INTERACT_ATOM_IGNORE_INCAPACITATED" = INTERACT_ATOM_IGNORE_INCAPACITATED, - "INTERACT_ATOM_IGNORE_RESTRAINED" = INTERACT_ATOM_IGNORE_RESTRAINED, - "INTERACT_ATOM_CHECK_GRAB" = INTERACT_ATOM_CHECK_GRAB, - "INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND" = INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND, - "INTERACT_ATOM_NO_FINGERPRINT_INTERACT" = INTERACT_ATOM_NO_FINGERPRINT_INTERACT - ), - "interaction_flags_machine" = list( - "INTERACT_MACHINE_OPEN" = INTERACT_MACHINE_OPEN, - "INTERACT_MACHINE_OFFLINE" = INTERACT_MACHINE_OFFLINE, - "INTERACT_MACHINE_WIRES_IF_OPEN" = INTERACT_MACHINE_WIRES_IF_OPEN, - "INTERACT_MACHINE_ALLOW_SILICON" = INTERACT_MACHINE_ALLOW_SILICON, - "INTERACT_MACHINE_OPEN_SILICON" = INTERACT_MACHINE_OPEN_SILICON, - "INTERACT_MACHINE_REQUIRES_SILICON" = INTERACT_MACHINE_REQUIRES_SILICON, - "INTERACT_MACHINE_SET_MACHINE" = INTERACT_MACHINE_SET_MACHINE - ), - "interaction_flags_item" = list( - "INTERACT_ITEM_ATTACK_HAND_PICKUP" = INTERACT_ITEM_ATTACK_HAND_PICKUP, - ), - "pass_flags" = list( - "PASSTABLE" = PASSTABLE, - "PASSGLASS" = PASSGLASS, - "PASSGRILLE" = PASSGRILLE, - "PASSBLOB" = PASSBLOB, - "PASSMOB" = PASSMOB, - "PASSCLOSEDTURF" = PASSCLOSEDTURF, - "LETPASSTHROW" = LETPASSTHROW - ), - "movement_type" = list( - "GROUND" = GROUND, - "FLYING" = FLYING, - "VENTCRAWLING" = VENTCRAWLING, - "FLOATING" = FLOATING, - "UNSTOPPABLE" = UNSTOPPABLE - ), - "resistance_flags" = list( - "LAVA_PROOF" = LAVA_PROOF, - "FIRE_PROOF" = FIRE_PROOF, - "FLAMMABLE" = FLAMMABLE, - "ON_FIRE" = ON_FIRE, - "UNACIDABLE" = UNACIDABLE, - "ACID_PROOF" = ACID_PROOF, - "INDESTRUCTIBLE" = INDESTRUCTIBLE, - "FREEZE_PROOF" = FREEZE_PROOF, - "GOLIATH_RESISTANCE" = GOLIATH_RESISTANCE, - "GOLIATH_WEAKNESS" = GOLIATH_WEAKNESS - ), - "flags_1" = list( - "NOJAUNT_1" = NOJAUNT_1, - "UNUSED_RESERVATION_TURF_1" = UNUSED_RESERVATION_TURF_1, - "CAN_BE_DIRTY_1" = CAN_BE_DIRTY_1, - "HEAR_1" = HEAR_1, - "DEFAULT_RICOCHET_1" = DEFAULT_RICOCHET_1, - "CONDUCT_1" = CONDUCT_1, - "NO_LAVA_GEN_1" = NO_LAVA_GEN_1, - "NODECONSTRUCT_1" = NODECONSTRUCT_1, - "OVERLAY_QUEUED_1" = OVERLAY_QUEUED_1, - "ON_BORDER_1" = ON_BORDER_1, - "NO_RUINS_1" = NO_RUINS_1, - "PREVENT_CLICK_UNDER_1" = PREVENT_CLICK_UNDER_1, - "HOLOGRAM_1" = HOLOGRAM_1, - "SHOCKED_1" = SHOCKED_1, - "INITIALIZED_1" = INITIALIZED_1, - "ADMIN_SPAWNED_1" = ADMIN_SPAWNED_1, - "BLOCK_FACE_ATOM_1" = BLOCK_FACE_ATOM_1, - "PREVENT_CONTENTS_EXPLOSION_1" = PREVENT_CONTENTS_EXPLOSION_1 - ), - "flags_ricochet" = list( - "RICOCHET_SHINY" = RICOCHET_SHINY, - "RICOCHET_HARD" = RICOCHET_HARD - ), - "clothing_flags" = list( - "LAVAPROTECT" = LAVAPROTECT, - "STOPSPRESSUREDAMAGE" = STOPSPRESSUREDAMAGE, - "BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT, - "ALLOWINTERNALS" = ALLOWINTERNALS, - "NOSLIP" = NOSLIP, - "THICKMATERIAL" = THICKMATERIAL, - "VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE, - "VOICEBOX_DISABLED" = VOICEBOX_DISABLED, - "IGNORE_HAT_TOSS" = IGNORE_HAT_TOSS, - "SCAN_REAGENTS" = SCAN_REAGENTS - ), - "zap_flags" = list( - "ZAP_MOB_DAMAGE" = ZAP_MOB_DAMAGE, - "ZAP_OBJ_DAMAGE" = ZAP_OBJ_DAMAGE, - "ZAP_MOB_STUN" = ZAP_MOB_STUN, - "ZAP_ALLOW_DUPLICATES" = ZAP_ALLOW_DUPLICATES, - "ZAP_MACHINE_EXPLOSIVE" = ZAP_MACHINE_EXPLOSIVE, - ), - "smooth" = list( - "SMOOTH_TRUE" = SMOOTH_TRUE, - "SMOOTH_MORE" = SMOOTH_MORE, - "SMOOTH_DIAGONAL" = SMOOTH_DIAGONAL, - "SMOOTH_BORDER" = SMOOTH_BORDER, - "SMOOTH_QUEUED" = SMOOTH_QUEUED, - ), - "reagents_holder_flags" = list( - "INJECTABLE" = INJECTABLE, - "DRAWABLE" = DRAWABLE, - "REFILLABLE" = REFILLABLE, - "DRAINABLE" = DRAINABLE, - "TRANSPARENT" = TRANSPARENT, - "AMOUNT_VISIBLE" = AMOUNT_VISIBLE, - "NO_REACT" = NO_REACT, - ), - "car_traits" = list( - "CAN_KIDNAP" = CAN_KIDNAP, - ), - "rad_flags" = list( - "RAD_PROTECT_CONTENTS" = RAD_PROTECT_CONTENTS, - "RAD_NO_CONTAMINATE" = RAD_NO_CONTAMINATE, - ), - "disease_flags" = list( - "CURABLE" = CURABLE, - "CAN_CARRY" = CAN_CARRY, - "CAN_RESIST" = CAN_RESIST - ), - "chemical_flags" = list( - "REAGENT_DEAD_PROCESS" = REAGENT_DEAD_PROCESS, - "REAGENT_DONOTSPLIT" = REAGENT_DONOTSPLIT, - "REAGENT_ONLYINVERSE" = REAGENT_ONLYINVERSE, - "REAGENT_ONMOBMERGE" = REAGENT_ONMOBMERGE, - "REAGENT_INVISIBLE" = REAGENT_INVISIBLE, - "REAGENT_FORCEONNEW" = REAGENT_FORCEONNEW, - "REAGENT_SNEAKYNAME" = REAGENT_SNEAKYNAME, - "REAGENT_SPLITRETAINVOL" = REAGENT_SPLITRETAINVOL - ), - "clear_conversion" = list( - "REACTION_CLEAR_IMPURE" = REACTION_CLEAR_IMPURE, - "REACTION_CLEAR_INVERSE" = REACTION_CLEAR_INVERSE - ), - "organ_flags" = list( - "ORGAN_SYNTHETIC" = ORGAN_SYNTHETIC, - "ORGAN_FROZEN" = ORGAN_FROZEN, - "ORGAN_FAILING" = ORGAN_FAILING, - "ORGAN_EXTERNAL" = ORGAN_EXTERNAL, - "ORGAN_VITAL" = ORGAN_VITAL, - "ORGAN_NO_SPOIL" = ORGAN_NO_SPOIL - ), - "genital_flags" = list( - "GENITAL_BLACKLISTED" = GENITAL_BLACKLISTED, - "GENITAL_INTERNAL" = GENITAL_INTERNAL, - "GENITAL_HIDDEN" = GENITAL_HIDDEN, - "GENITAL_THROUGH_CLOTHES" = GENITAL_THROUGH_CLOTHES, - "GENITAL_FUID_PRODUCTION" = GENITAL_FUID_PRODUCTION, - "CAN_MASTURBATE_WITH" = CAN_MASTURBATE_WITH, - "MASTURBATE_LINKED_ORGAN" = MASTURBATE_LINKED_ORGAN, - "CAN_CLIMAX_WITH" = CAN_CLIMAX_WITH +GLOBAL_LIST_INIT(bitfields, generate_bitfields()) - ), - "mob_biotypes" = list ( - "MOB_ORGANIC" = MOB_ORGANIC, - "MOB_MINERAL" = MOB_MINERAL, - "MOB_ROBOTIC" = MOB_ROBOTIC, - "MOB_UNDEAD" = MOB_UNDEAD, - "MOB_HUMANOID" = MOB_HUMANOID, - "MOB_BUG" = MOB_BUG, - "MOB_BEAST" = MOB_BEAST, - "MOB_EPIC" = MOB_EPIC, - "MOB_REPTILE" = MOB_REPTILE, - "MOB_SPIRIT" = MOB_SPIRIT - ), - "mobility_flags" = list( - "MOBILITY_MOVE" = MOBILITY_MOVE, - "MOBILITY_STAND" = MOBILITY_STAND, - "MOBILITY_PICKUP" = MOBILITY_PICKUP, - "MOBILITY_USE" = MOBILITY_USE, - "MOBILITY_UI" = MOBILITY_UI, - "MOBILITY_STORAGE" = MOBILITY_STORAGE, - "MOBILITY_PULL" = MOBILITY_PULL, - "MOBILITY_HOLD" = MOBILITY_HOLD, - "MOBILITY_RESIST" = MOBILITY_RESIST - ), - "combat_flags" = list( - "COMBAT_FLAG_SPRINT_TOGGLED" = COMBAT_FLAG_SPRINT_TOGGLED, - "COMBAT_FLAG_SPRINT_ACTIVE" = COMBAT_FLAG_SPRINT_ACTIVE, - "COMBAT_FLAG_ATTEMPTING_CRAWL" = COMBAT_FLAG_ATTEMPTING_CRAWL, - "COMBAT_FLAG_HARD_STAMCRIT" = COMBAT_FLAG_HARD_STAMCRIT, - "COMBAT_FLAG_INTENTIONALLY_RESTING" = COMBAT_FLAG_INTENTIONALLY_RESTING, - "COMBAT_FLAG_RESISTING_REST" = COMBAT_FLAG_RESISTING_REST, - "COMBAT_FLAG_SPRINT_FORCED" = COMBAT_FLAG_SPRINT_FORCED - ), - "shield_flags" = list( - "SHIELD_TRANSPARENT" = SHIELD_TRANSPARENT, - "SHIELD_ENERGY_WEAK" = SHIELD_ENERGY_WEAK, - "SHIELD_KINETIC_WEAK" = SHIELD_KINETIC_WEAK, - "SHIELD_KINETIC_STRONG" = SHIELD_KINETIC_STRONG, - "SHIELD_ENERGY_STRONG" = SHIELD_ENERGY_STRONG, - "SHIELD_DISABLER_DISRUPTED" = SHIELD_DISABLER_DISRUPTED, - "SHIELD_NO_RANGED" = SHIELD_NO_RANGED, - "SHIELD_NO_MELEE" = SHIELD_NO_MELEE, - "SHIELD_CAN_BASH" = SHIELD_CAN_BASH, - "SHIELD_BASH_WALL_KNOCKDOWN" = SHIELD_BASH_WALL_KNOCKDOWN, - "SHIELD_BASH_ALWAYS_KNOCKDOWN" = SHIELD_BASH_ALWAYS_KNOCKDOWN, - "SHIELD_BASH_WALL_DISARM" = SHIELD_BASH_WALL_DISARM, - "SHIELD_BASH_ALWAYS_DISARM" = SHIELD_BASH_ALWAYS_DISARM, - "SHIELD_BASH_GROUND_SLAM" = SHIELD_BASH_GROUND_SLAM, - "SHIELD_BASH_GROUND_SLAM_DISARM" = SHIELD_BASH_GROUND_SLAM_DISARM - ), - "storage_flags" = list( - "STORAGE_LIMIT_MAX_ITEMS" = STORAGE_LIMIT_MAX_ITEMS, - "STORAGE_LIMIT_MAX_W_CLASS" = STORAGE_LIMIT_MAX_W_CLASS, - "STORAGE_LIMIT_COMBINED_W_CLASS" = STORAGE_LIMIT_COMBINED_W_CLASS, - "STORAGE_LIMIT_VOLUME" = STORAGE_LIMIT_VOLUME - ), - "mutantrace_variation" = list( - "STYLE_DIGITIGRADE" = STYLE_DIGITIGRADE, - "STYLE_MUZZLE" = STYLE_MUZZLE, - "STYLE_SNEK_TAURIC" = STYLE_SNEK_TAURIC, - "STYLE_PAW_TAURIC" = STYLE_PAW_TAURIC, - "STYLE_HOOF_TAURIC" = STYLE_HOOF_TAURIC, - "STYLE_NO_ANTHRO_ICON" = STYLE_NO_ANTHRO_ICON, - "USE_SNEK_CLIP_MASK" = USE_SNEK_CLIP_MASK, - "USE_QUADRUPED_CLIP_MASK" = USE_QUADRUPED_CLIP_MASK - ), - "vis_flags" = list( - "VIS_INHERIT_ICON" = VIS_INHERIT_ICON, - "VIS_INHERIT_ICON_STATE" = VIS_INHERIT_ICON_STATE, - "VIS_INHERIT_DIR" = VIS_INHERIT_DIR, - "VIS_INHERIT_LAYER" = VIS_INHERIT_LAYER, - "VIS_INHERIT_PLANE" = VIS_INHERIT_PLANE, - "VIS_INHERIT_ID" = VIS_INHERIT_ID, - "VIS_UNDERLAY" = VIS_UNDERLAY, - "VIS_HIDE" = VIS_HIDE - ) - )) +/// Specifies a bitfield for smarter debugging +/datum/bitfield + /// The variable name that contains the bitfield + var/variable + + /// An associative list of the readable flag and its true value + var/list/flags + +/// Turns /datum/bitfield subtypes into a list for use in debugging +/proc/generate_bitfields() + var/list/bitfields = list() + for (var/_bitfield in subtypesof(/datum/bitfield)) + var/datum/bitfield/bitfield = new _bitfield + bitfields[bitfield.variable] = bitfield.flags + return bitfields + +DEFINE_BITFIELD(admin_flags, list( + "ADMIN" = R_ADMIN, + "AUTOLOGIN" = R_AUTOLOGIN, + "BAN" = R_BAN, + "BUILDMODE" = R_BUILDMODE, + "DBRANKS" = R_DBRANKS, + "DEBUG" = R_DEBUG, + "FUN" = R_FUN, + "PERMISSIONS" = R_PERMISSIONS, + "POLL" = R_POLL, + "POSSESS" = R_POSSESS, + "SENSITIVE" = R_SENSITIVE, + "SERVER" = R_SERVER, + "SOUNDS" = R_SOUNDS, + "SPAWN" = R_SPAWN, + "STEALTH" = R_STEALTH, + "VAREDIT" = R_VAREDIT, +)) + +DEFINE_BITFIELD(appearance_flags, list( + "KEEP_APART" = KEEP_APART, + "KEEP_TOGETHER" = KEEP_TOGETHER, + "LONG_GLIDE" = LONG_GLIDE, + "NO_CLIENT_COLOR" = NO_CLIENT_COLOR, + "PASS_MOUSE" = PASS_MOUSE, + "PIXEL_SCALE" = PIXEL_SCALE, + "PLANE_MASTER" = PLANE_MASTER, + "RESET_ALPHA" = RESET_ALPHA, + "RESET_COLOR" = RESET_COLOR, + "RESET_TRANSFORM" = RESET_TRANSFORM, + "TILE_BOUND" = TILE_BOUND, + "TILE_MOVER" = TILE_MOVER, +)) + +DEFINE_BITFIELD(area_flags, list( + "ABDUCTOR_PROOF" = ABDUCTOR_PROOF, + "BLOBS_ALLOWED" = BLOBS_ALLOWED, + "BLOCK_SUICIDE" = BLOCK_SUICIDE, + "CULT_PERMITTED" = CULT_PERMITTED, + "FLORA_ALLOWED" = FLORA_ALLOWED, + "HIDDEN_AREA" = HIDDEN_AREA, + "MEGAFAUNA_SPAWN_ALLOWED" = MEGAFAUNA_SPAWN_ALLOWED, + "MOB_SPAWN_ALLOWED" = MOB_SPAWN_ALLOWED, + "NO_ALERTS" = NO_ALERTS, + "NOTELEPORT" = NOTELEPORT, + "CAVES_ALLOWED" = CAVES_ALLOWED, + "UNIQUE_AREA" = UNIQUE_AREA, + "VALID_TERRITORY" = VALID_TERRITORY, + "XENOBIOLOGY_COMPATIBLE" = XENOBIOLOGY_COMPATIBLE, + "NO_ALERTS" = NO_ALERTS, +)) + +DEFINE_BITFIELD(body_parts_covered, list( + "ARM_LEFT" = ARM_LEFT, + "ARM_RIGHT" = ARM_RIGHT, + "ARMS" = ARMS, + "CHEST" = CHEST, + "FEET" = FEET, + "FOOT_LEFT" = FOOT_LEFT, + "FOOT_RIGHT" = FOOT_RIGHT, + "GROIN" = GROIN, + "HAND_LEFT" = HAND_LEFT, + "HAND_RIGHT" = HAND_RIGHT, + "HANDS" = HANDS, + "HEAD" = HEAD, + "LEG_LEFT" = LEG_LEFT, + "LEG_RIGHT" = LEG_RIGHT, + "LEGS" = LEGS, + "NECK" = NECK, +)) + +DEFINE_BITFIELD(car_traits, list( + "CAN_KIDNAP" = CAN_KIDNAP, +)) + +DEFINE_BITFIELD(chemical_flags, list( + "REAGENT_DEAD_PROCESS" = REAGENT_DEAD_PROCESS, + "REAGENT_DONOTSPLIT" = REAGENT_DONOTSPLIT, + "REAGENT_FORCEONNEW" = REAGENT_FORCEONNEW, + "REAGENT_INVISIBLE" = REAGENT_INVISIBLE, + "REAGENT_ONLYINVERSE" = REAGENT_ONLYINVERSE, + "REAGENT_ONMOBMERGE" = REAGENT_ONMOBMERGE, + "REAGENT_ORGANIC_PROCESS" = REAGENT_ORGANIC_PROCESS, + "REAGENT_ROBOTIC_PROCESS" = REAGENT_ROBOTIC_PROCESS, + "REAGENT_SNEAKYNAME" = REAGENT_SNEAKYNAME, + "REAGENT_SPLITRETAINVOL" = REAGENT_SPLITRETAINVOL, +)) + +DEFINE_BITFIELD(clear_conversion, list( + "REACTION_CLEAR_IMPURE" = REACTION_CLEAR_IMPURE, + "REACTION_CLEAR_INVERSE" = REACTION_CLEAR_INVERSE +)) + +DEFINE_BITFIELD(clothing_flags, list( + "ALLOWINTERNALS" = ALLOWINTERNALS, + "BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT, + "IGNORE_HAT_TOSS" = IGNORE_HAT_TOSS, + "LAVAPROTECT" = LAVAPROTECT, + "NOSLIP" = NOSLIP, + "SCAN_REAGENTS" = SCAN_REAGENTS, + "STOPSPRESSUREDAMAGE" = STOPSPRESSUREDAMAGE, + "THICKMATERIAL" = THICKMATERIAL, + "VOICEBOX_DISABLED" = VOICEBOX_DISABLED, + "VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE, +)) + +DEFINE_BITFIELD(combat_flags, list( + "COMBAT_FLAG_ATTEMPTING_CRAWL" = COMBAT_FLAG_ATTEMPTING_CRAWL, + "COMBAT_FLAG_HARD_STAMCRIT" = COMBAT_FLAG_HARD_STAMCRIT, + "COMBAT_FLAG_INTENTIONALLY_RESTING" = COMBAT_FLAG_INTENTIONALLY_RESTING, + "COMBAT_FLAG_RESISTING_REST" = COMBAT_FLAG_RESISTING_REST, + "COMBAT_FLAG_SPRINT_ACTIVE" = COMBAT_FLAG_SPRINT_ACTIVE, + "COMBAT_FLAG_SPRINT_FORCED" = COMBAT_FLAG_SPRINT_FORCED, + "COMBAT_FLAG_SPRINT_TOGGLED" = COMBAT_FLAG_SPRINT_TOGGLED, +)) + +DEFINE_BITFIELD(datum_flags, list( + "DF_USE_TAG" = DF_USE_TAG, + "DF_VAR_EDITED" = DF_VAR_EDITED, + "DF_ISPROCESSING" = DF_ISPROCESSING, +)) + +DEFINE_BITFIELD(disease_flags, list( + "CAN_CARRY" = CAN_CARRY, + "CAN_RESIST" = CAN_RESIST, + "CURABLE" = CURABLE, +)) + +DEFINE_BITFIELD(explosion_flags, list( + "EXPLOSION_FLAG_DENSITY_DEPENDENT" = EXPLOSION_FLAG_DENSITY_DEPENDENT, + "EXPLOSION_FLAG_HARD_OBSTACLE" = EXPLOSION_FLAG_HARD_OBSTACLE, +)) + +DEFINE_BITFIELD(flags_1, list( + "ADMIN_SPAWNED_1" = ADMIN_SPAWNED_1, + "BLOCK_FACE_ATOM_1" = BLOCK_FACE_ATOM_1, + "CAN_BE_DIRTY_1" = CAN_BE_DIRTY_1, + "CONDUCT_1" = CONDUCT_1, + "DEFAULT_RICOCHET_1" = DEFAULT_RICOCHET_1, + "HAS_CONTEXTUAL_SCREENTIPS_1" = HAS_CONTEXTUAL_SCREENTIPS_1, + "HEAR_1" = HEAR_1, + "HOLOGRAM_1" = HOLOGRAM_1, + "INITIALIZED_1" = INITIALIZED_1, + "NODECONSTRUCT_1" = NODECONSTRUCT_1, + "NOJAUNT_1" = NOJAUNT_1, + "NO_LAVA_GEN_1" = NO_LAVA_GEN_1, + "NO_RUINS_1" = NO_RUINS_1, + "NO_SCREENTIPS_1" = NO_SCREENTIPS_1, + "OVERLAY_QUEUED_1" = OVERLAY_QUEUED_1, + "ON_BORDER_1" = ON_BORDER_1, + "PREVENT_CLICK_UNDER_1" = PREVENT_CLICK_UNDER_1, + "PREVENT_CONTENTS_EXPLOSION_1" = PREVENT_CONTENTS_EXPLOSION_1, + "SHOCKED_1" = SHOCKED_1, + "UNUSED_RESERVATION_TURF_1" = UNUSED_RESERVATION_TURF_1, +)) + +DEFINE_BITFIELD(flags_cover, list( + "GLASSESCOVERSEYE" = GLASSESCOVERSEYES, + "HEADCOVERSEYES" = HEADCOVERSEYES, + "HEADCOVERSMOUTH" = HEADCOVERSMOUTH, + "MASKCOVERSEYES" = MASKCOVERSEYES, + "MASKCOVERSMOUTH" = MASKCOVERSMOUTH, +)) + +DEFINE_BITFIELD(flags_inv, list( + "HIDEACCESSORY" = HIDEACCESSORY, + "HIDEEARS" = HIDEEARS, + "HIDEEYES" = HIDEEYES, + "HIDEFACE" = HIDEFACE, + "HIDEFACIALHAI" = HIDEFACIALHAIR, + "HIDEGLOVES" = HIDEGLOVES, + "HIDEHAIR" = HIDEHAIR, + "HIDEJUMPSUIT" = HIDEJUMPSUIT, + "HIDEMASK" = HIDEMASK, + "HIDENECK" = HIDENECK, + "HIDESHOES" = HIDESHOES, + "HIDESNOUT" = HIDESNOUT, + "HIDESUITSTORA" = HIDESUITSTORAGE, + "HIDETAUR" = HIDETAUR, +)) +DEFINE_BITFIELD(flags_ricochet, list( + "RICOCHET_SHINY" = RICOCHET_SHINY, + "RICOCHET_HARD" = RICOCHET_HARD +)) + +DEFINE_BITFIELD(genital_flags, list( + "CAN_CLIMAX_WITH" = CAN_CLIMAX_WITH, + "CAN_MASTURBATE_WITH" = CAN_MASTURBATE_WITH, + "GENITAL_BLACKLISTED" = GENITAL_BLACKLISTED, + "GENITAL_FUID_PRODUCTION" = GENITAL_FUID_PRODUCTION, + "GENITAL_HIDDEN" = GENITAL_HIDDEN, + "GENITAL_INTERNAL" = GENITAL_INTERNAL, + "GENITAL_THROUGH_CLOTHES" = GENITAL_THROUGH_CLOTHES, + "MASTURBATE_LINKED_ORGAN" = MASTURBATE_LINKED_ORGAN, +)) + +DEFINE_BITFIELD(interaction_flags_atom, list( + "INTERACT_ATOM_ATTACK_HAND" = INTERACT_ATOM_ATTACK_HAND, + "INTERACT_ATOM_CHECK_GRAB" = INTERACT_ATOM_CHECK_GRAB, + "INTERACT_ATOM_IGNORE_INCAPACITATED" = INTERACT_ATOM_IGNORE_INCAPACITATED, + "INTERACT_ATOM_IGNORE_RESTRAINED" = INTERACT_ATOM_IGNORE_RESTRAINED, + "INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND" = INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND, + "INTERACT_ATOM_NO_FINGERPRINT_INTERACT" = INTERACT_ATOM_NO_FINGERPRINT_INTERACT, + "INTERACT_ATOM_REQUIRES_ANCHORED" = INTERACT_ATOM_REQUIRES_ANCHORED, + "INTERACT_ATOM_REQUIRES_DEXTERITY" = INTERACT_ATOM_REQUIRES_DEXTERITY, + "INTERACT_ATOM_UI_INTERACT" = INTERACT_ATOM_UI_INTERACT, +)) + +DEFINE_BITFIELD(interaction_flags_machine, list( + "INTERACT_MACHINE_ALLOW_SILICON" = INTERACT_MACHINE_ALLOW_SILICON, + "INTERACT_MACHINE_OFFLINE" = INTERACT_MACHINE_OFFLINE, + "INTERACT_MACHINE_OPEN" = INTERACT_MACHINE_OPEN, + "INTERACT_MACHINE_OPEN_SILICON" = INTERACT_MACHINE_OPEN_SILICON, + "INTERACT_MACHINE_REQUIRES_SILICON" = INTERACT_MACHINE_REQUIRES_SILICON, + "INTERACT_MACHINE_SET_MACHINE" = INTERACT_MACHINE_SET_MACHINE, + "INTERACT_MACHINE_WIRES_IF_OPEN" = INTERACT_MACHINE_WIRES_IF_OPEN, +)) + +DEFINE_BITFIELD(interaction_flags_item, list( + "INTERACT_ITEM_ATTACK_HAND_PICKUP" = INTERACT_ITEM_ATTACK_HAND_PICKUP, +)) + +DEFINE_BITFIELD(item_flags, list( + "ABSTRACT" = ABSTRACT, + "BEING_REMOVED" = BEING_REMOVED, + "DROPDEL" = DROPDEL, + "FORCE_STRING_OVERRIDE" = FORCE_STRING_OVERRIDE, + "IN_INVENTORY" = IN_INVENTORY, + "IN_STORAGE" = IN_STORAGE, + "ITEM_CAN_BLOCK" = ITEM_CAN_BLOCK, + "ITEM_CAN_PARRY" = ITEM_CAN_PARRY, + "ITEM_HAS_CONTEXTUAL_SCREENTIPS" = ITEM_HAS_CONTEXTUAL_SCREENTIPS, + "NEEDS_PERMIT" = NEEDS_PERMIT, + "NOBLUDGEON" = NOBLUDGEON, + "NO_MAT_REDEMPTION" = NO_MAT_REDEMPTION, + "SLOWS_WHILE_IN_HAND" = SLOWS_WHILE_IN_HAND, +)) + +DEFINE_BITFIELD(material_flags, list( + "MATERIAL_ADD_PREFIX" = MATERIAL_ADD_PREFIX, + "MATERIAL_AFFECT_STATISTICS" = MATERIAL_AFFECT_STATISTICS, + "MATERIAL_COLOR" = MATERIAL_COLOR, +)) + +DEFINE_BITFIELD(mob_biotypes, list( + "MOB_BEAST" = MOB_BEAST, + "MOB_BUG" = MOB_BUG, + "MOB_EPIC" = MOB_EPIC, + "MOB_HUMANOID" = MOB_HUMANOID, + "MOB_MINERAL" = MOB_MINERAL, + "MOB_ORGANIC" = MOB_ORGANIC, + "MOB_REPTILE" = MOB_REPTILE, + "MOB_ROBOTIC" = MOB_ROBOTIC, + "MOB_SPIRIT" = MOB_SPIRIT, + "MOB_UNDEAD" = MOB_UNDEAD, +)) + +DEFINE_BITFIELD(mobility_flags, list( + "MOBILITY_HOLD" = MOBILITY_HOLD, + "MOBILITY_MOVE" = MOBILITY_MOVE, + "MOBILITY_PICKUP" = MOBILITY_PICKUP, + "MOBILITY_PULL" = MOBILITY_PULL, + "MOBILITY_RESIST" = MOBILITY_RESIST, + "MOBILITY_STAND" = MOBILITY_STAND, + "MOBILITY_STORAGE" = MOBILITY_STORAGE, + "MOBILITY_UI" = MOBILITY_UI, + "MOBILITY_USE" = MOBILITY_USE, +)) + +DEFINE_BITFIELD(movement_type, list( + "FLOATING" = FLOATING, + "FLYING" = FLYING, + "GROUND" = GROUND, + "PHASING" = PHASING, + "VENTCRAWLING" = VENTCRAWLING, +)) + +DEFINE_BITFIELD(mutantrace_variation, list( + "STYLE_DIGITIGRADE" = STYLE_DIGITIGRADE, + "STYLE_HOOF_TAURIC" = STYLE_HOOF_TAURIC, + "STYLE_MUZZLE" = STYLE_MUZZLE, + "STYLE_NO_ANTHRO_ICON" = STYLE_NO_ANTHRO_ICON, + "STYLE_PAW_TAURIC" = STYLE_PAW_TAURIC, + "STYLE_SNEK_TAURIC" = STYLE_SNEK_TAURIC, + "USE_SNEK_CLIP_MASK" = USE_SNEK_CLIP_MASK, + "USE_QUADRUPED_CLIP_MASK" = USE_QUADRUPED_CLIP_MASK, +)) + +DEFINE_BITFIELD(obj_flags, list( + "BEING_SHOCKED" = BEING_SHOCKED, + "BLOCK_Z_IN_DOWN" = BLOCK_Z_IN_DOWN, + "BLOCK_Z_IN_UP" = BLOCK_Z_IN_UP, + "BLOCK_Z_OUT_DOWN" = BLOCK_Z_OUT_DOWN, + "BLOCK_Z_OUT_UP" = BLOCK_Z_OUT_UP, + "CAN_BE_HIT" = CAN_BE_HIT, + "DANGEROUS_POSSESSION" = DANGEROUS_POSSESSION, + "EMAGGED" = EMAGGED, + "EXAMINE_SKIP" = EXAMINE_SKIP, + "FROZEN" = FROZEN, + "IN_USE" = IN_USE, + "ON_BLUEPRINTS" = ON_BLUEPRINTS, + "SHOVABLE_ONTO" = SHOVABLE_ONTO, + "UNIQUE_RENAME" = UNIQUE_RENAME, + "USES_TGUI" = USES_TGUI, +)) + +DEFINE_BITFIELD(organ_flags, list( + "ORGAN_EXTERNAL" = ORGAN_EXTERNAL, + "ORGAN_FAILING" = ORGAN_FAILING, + "ORGAN_FROZEN" = ORGAN_FROZEN, + "ORGAN_NO_SPOIL" = ORGAN_NO_SPOIL, + "ORGAN_SYNTHETIC" = ORGAN_SYNTHETIC, + "ORGAN_VITAL" = ORGAN_VITAL, +)) + +DEFINE_BITFIELD(pass_flags, list( + "LETPASSTHROW" = LETPASSTHROW, + "PASSBLOB" = PASSBLOB, + "PASSCLOSEDTURF" = PASSCLOSEDTURF, + "PASSGLASS" = PASSGLASS, + "PASSGRILLE" = PASSGRILLE, + "PASSMACHINE" = PASSMACHINE, + "PASSMOB" = PASSMOB, + "PASSSTRUCTURE" = PASSSTRUCTURE, + "PASSTABLE" = PASSTABLE, +)) + +DEFINE_BITFIELD(pass_flags_self, list( + "LETPASSTHROW" = LETPASSTHROW, + "PASSBLOB" = PASSBLOB, + "PASSCLOSEDTURF" = PASSCLOSEDTURF, + "PASSGLASS" = PASSGLASS, + "PASSGRILLE" = PASSGRILLE, + "PASSMACHINE" = PASSMACHINE, + "PASSMOB" = PASSMOB, + "PASSSTRUCTURE" = PASSSTRUCTURE, + "PASSTABLE" = PASSTABLE, +)) + +DEFINE_BITFIELD(rad_flags, list( + "RAD_PROTECT_CONTENTS" = RAD_PROTECT_CONTENTS, + "RAD_NO_CONTAMINATE" = RAD_NO_CONTAMINATE, +)) + +DEFINE_BITFIELD(reagents_holder_flags, list( + "AMOUNT_VISIBLE" = AMOUNT_VISIBLE, + "DRAINABLE" = DRAINABLE, + "DRAWABLE" = DRAWABLE, + "INJECTABLE" = INJECTABLE, + "NO_REACT" = NO_REACT, + "REFILLABLE" = REFILLABLE, + "TRANSPARENT" = TRANSPARENT, +)) + +DEFINE_BITFIELD(resistance_flags, list( + "ACID_PROOF" = ACID_PROOF, + "FIRE_PROOF" = FIRE_PROOF, + "FLAMMABLE" = FLAMMABLE, + "FREEZE_PROOF" = FREEZE_PROOF, + "GOLIATH_RESISTANCE" = GOLIATH_RESISTANCE, + "GOLIATH_WEAKNESS" = GOLIATH_WEAKNESS, + "INDESTRUCTIBLE" = INDESTRUCTIBLE, + "LAVA_PROOF" = LAVA_PROOF, + "ON_FIRE" = ON_FIRE, + "UNACIDABLE" = UNACIDABLE, +)) + +DEFINE_BITFIELD(shield_flags, list( + "SHIELD_BASH_ALWAYS_DISARM" = SHIELD_BASH_ALWAYS_DISARM, + "SHIELD_BASH_ALWAYS_KNOCKDOWN" = SHIELD_BASH_ALWAYS_KNOCKDOWN, + "SHIELD_BASH_GROUND_SLAM" = SHIELD_BASH_GROUND_SLAM, + "SHIELD_BASH_GROUND_SLAM_DISARM" = SHIELD_BASH_GROUND_SLAM_DISARM, + "SHIELD_BASH_WALL_DISARM" = SHIELD_BASH_WALL_DISARM, + "SHIELD_BASH_WALL_KNOCKDOWN" = SHIELD_BASH_WALL_KNOCKDOWN, + "SHIELD_CAN_BASH" = SHIELD_CAN_BASH, + "SHIELD_DISABLER_DISRUPTED" = SHIELD_DISABLER_DISRUPTED, + "SHIELD_ENERGY_STRONG" = SHIELD_ENERGY_STRONG, + "SHIELD_ENERGY_WEAK" = SHIELD_ENERGY_WEAK, + "SHIELD_KINETIC_STRONG" = SHIELD_KINETIC_STRONG, + "SHIELD_KINETIC_WEAK" = SHIELD_KINETIC_WEAK, + "SHIELD_NO_MELEE" = SHIELD_NO_MELEE, + "SHIELD_NO_RANGED" = SHIELD_NO_RANGED, + "SHIELD_TRANSPARENT" = SHIELD_TRANSPARENT, +)) + +DEFINE_BITFIELD(sight, list( + "BLIND" = BLIND, + "SEE_BLACKNESS" = SEE_BLACKNESS, + "SEE_INFRA" = SEE_INFRA, + "SEE_MOBS" = SEE_MOBS, + "SEE_OBJS" = SEE_OBJS, + "SEE_PIXELS" = SEE_PIXELS, + "SEE_SELF" = SEE_SELF, + "SEE_THRU" = SEE_THRU, + "SEE_TURFS" = SEE_TURFS, +)) + +DEFINE_BITFIELD(slot_flags, list( + "ITEM_SLOT_ACCESSORY" = ITEM_SLOT_ACCESSORY, + "ITEM_SLOT_BACK" = ITEM_SLOT_BACK, + "ITEM_SLOT_BACKPACK" = ITEM_SLOT_BACKPACK, + "ITEM_SLOT_BELT" = ITEM_SLOT_BELT, + "ITEM_SLOT_DEX_STORAGE" = ITEM_SLOT_DEX_STORAGE, + "ITEM_SLOT_EARS" = ITEM_SLOT_EARS, + "ITEM_SLOT_EYES" = ITEM_SLOT_EYES, + "ITEM_SLOT_FEET" = ITEM_SLOT_FEET, + "ITEM_SLOT_GLOVES" = ITEM_SLOT_GLOVES, + "ITEM_SLOT_HANDCUFFED" = ITEM_SLOT_HANDCUFFED, + "ITEM_SLOT_HANDS" = ITEM_SLOT_HANDS, + "ITEM_SLOT_HEAD" = ITEM_SLOT_HEAD, + "ITEM_SLOT_ICLOTHING" = ITEM_SLOT_ICLOTHING, + "ITEM_SLOT_ID" = ITEM_SLOT_ID, + "ITEM_SLOT_LEGCUFFED" = ITEM_SLOT_LEGCUFFED, + "ITEM_SLOT_LPOCKET" = ITEM_SLOT_LPOCKET, + "ITEM_SLOT_MASK" = ITEM_SLOT_MASK, + "ITEM_SLOT_NECK" = ITEM_SLOT_NECK, + "ITEM_SLOT_OCLOTHING" = ITEM_SLOT_OCLOTHING, + "ITEM_SLOT_RPOCKET" = ITEM_SLOT_RPOCKET, + "ITEM_SLOT_SUITSTORE" = ITEM_SLOT_SUITSTORE, +)) + +DEFINE_BITFIELD(smooth, list( + "SMOOTH_BORDER" = SMOOTH_BORDER, + "SMOOTH_DIAGONAL" = SMOOTH_DIAGONAL, + "SMOOTH_MORE" = SMOOTH_MORE, + "SMOOTH_QUEUED" = SMOOTH_QUEUED, + "SMOOTH_TRUE" = SMOOTH_TRUE, +)) + +DEFINE_BITFIELD(status_flags, list( + "CANKNOCKDOWN" = CANKNOCKDOWN, + "CANPUSH" = CANPUSH, + "CANSTAGGER" = CANSTAGGER, + "CANSTUN" = CANSTUN, + "CANUNCONSCIOUS" = CANUNCONSCIOUS, + "GODMODE" = GODMODE, +)) + +DEFINE_BITFIELD(storage_flags, list( + "STORAGE_LIMIT_COMBINED_W_CLASS" = STORAGE_LIMIT_COMBINED_W_CLASS, + "STORAGE_LIMIT_MAX_ITEMS" = STORAGE_LIMIT_MAX_ITEMS, + "STORAGE_LIMIT_MAX_W_CLASS" = STORAGE_LIMIT_MAX_W_CLASS, + "STORAGE_LIMIT_VOLUME" = STORAGE_LIMIT_VOLUME, +)) + +DEFINE_BITFIELD(vis_flags, list( + "VIS_HIDE" = VIS_HIDE, + "VIS_INHERIT_DIR" = VIS_INHERIT_DIR, + "VIS_INHERIT_ICON" = VIS_INHERIT_ICON, + "VIS_INHERIT_ICON_STATE" = VIS_INHERIT_ICON_STATE, + "VIS_INHERIT_ID" = VIS_INHERIT_ID, + "VIS_INHERIT_LAYER" = VIS_INHERIT_LAYER, + "VIS_INHERIT_PLANE" = VIS_INHERIT_PLANE, + "VIS_UNDERLAY" = VIS_UNDERLAY, +)) + +DEFINE_BITFIELD(visor_flags, list( + "ALLOWINTERNALS" = ALLOWINTERNALS, + "BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT, + "IGNORE_HAT_TOSS" = IGNORE_HAT_TOSS, + "LAVAPROTECT" = LAVAPROTECT, + "NOSLIP" = NOSLIP, + "NOSLIP_ICE" = NOSLIP_ICE, + "SCAN_REAGENTS" = SCAN_REAGENTS, + "STOPSPRESSUREDAMAGE" = STOPSPRESSUREDAMAGE, + "THICKMATERIAL" = THICKMATERIAL, + "VOICEBOX_DISABLED" = VOICEBOX_DISABLED, + "VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE, +)) + +DEFINE_BITFIELD(visor_flags_cover, list( + "GLASSESCOVERSEYE" = GLASSESCOVERSEYES, + "HEADCOVERSEYES" = HEADCOVERSEYES, + "HEADCOVERSMOUTH" = HEADCOVERSMOUTH, + "MASKCOVERSEYES" = MASKCOVERSEYES, + "MASKCOVERSMOUTH" = MASKCOVERSMOUTH, +)) + +DEFINE_BITFIELD(visor_flags_inv, list( + "HIDEACCESSORY" = HIDEACCESSORY, + "HIDEEARS" = HIDEEARS, + "HIDEEYES" = HIDEEYES, + "HIDEFACE" = HIDEFACE, + "HIDEFACIALHAI" = HIDEFACIALHAIR, + "HIDEGLOVES" = HIDEGLOVES, + "HIDEHAIR" = HIDEHAIR, + "HIDEJUMPSUIT" = HIDEJUMPSUIT, + "HIDEMASK" = HIDEMASK, + "HIDENECK" = HIDENECK, + "HIDESHOES" = HIDESHOES, + "HIDESNOUT" = HIDESNOUT, + "HIDESUITSTORA" = HIDESUITSTORAGE, + "HIDETAUR" = HIDETAUR, +)) + +DEFINE_BITFIELD(vore_flags, list( + "ABSORBABLE" = ABSORBABLE, + "ABSORBED" = ABSORBED, + "DEVOURABLE" = DEVOURABLE, + "DIGESTABLE" = DIGESTABLE, + "FEEDING" = FEEDING, + "LICKABLE" = LICKABLE, + "MOBVORE" = MOBVORE, + "NO_VORE" = NO_VORE, + "SMELLABLE" = SMELLABLE, + "VOREPREF_INIT" = VOREPREF_INIT, + "VORE_INIT" = VORE_INIT, +)) + +DEFINE_BITFIELD(zap_flags, list( + "ZAP_ALLOW_DUPLICATES" = ZAP_ALLOW_DUPLICATES, + "ZAP_MACHINE_EXPLOSIVE" = ZAP_MACHINE_EXPLOSIVE, + "ZAP_MOB_DAMAGE" = ZAP_MOB_DAMAGE, + "ZAP_MOB_STUN" = ZAP_MOB_STUN, + "ZAP_OBJ_DAMAGE" = ZAP_OBJ_DAMAGE, +)) diff --git a/code/_globalvars/game_modes.dm b/code/_globalvars/game_modes.dm index 960e1f8d59..7553c82502 100644 --- a/code/_globalvars/game_modes.dm +++ b/code/_globalvars/game_modes.dm @@ -1,5 +1,5 @@ -GLOBAL_VAR_INIT(master_mode, "traitor") //"extended" -GLOBAL_VAR_INIT(secret_force_mode, "secret") // if this is anything but "secret", the secret rotation will forceably choose this mode +GLOBAL_VAR_INIT(master_mode, "dynamic") //"extended" +GLOBAL_VAR_INIT(secret_force_mode, "dynamic") // if this is anything but "secret", the secret rotation will forceably choose this mode GLOBAL_VAR(common_report) //Contains common part of roundend report GLOBAL_VAR(survivor_report) //Contains shared survivor report for roundend report (part of personal report) diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index 28f657828b..fa239e0ea4 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -6,6 +6,7 @@ GLOBAL_LIST_EMPTY(hair_styles_female_list) //stores only hair names GLOBAL_LIST_EMPTY(facial_hair_styles_list) //stores /datum/sprite_accessory/facial_hair indexed by name GLOBAL_LIST_EMPTY(facial_hair_styles_male_list) //stores only hair names GLOBAL_LIST_EMPTY(facial_hair_styles_female_list) //stores only hair names +GLOBAL_LIST_EMPTY(hair_gradients_list) //stores /datum/sprite_accessory/hair_gradient indexed by name //Underwear GLOBAL_LIST_EMPTY_TYPED(underwear_list, /datum/sprite_accessory/underwear/bottom) //stores bottoms indexed by name GLOBAL_LIST_EMPTY(underwear_m) //stores only underwear name @@ -42,6 +43,10 @@ GLOBAL_LIST_EMPTY(arachnid_spinneret_list) GLOBAL_LIST_EMPTY(arachnid_mandibles_list) GLOBAL_LIST_EMPTY(caps_list) + //Bark bits +GLOBAL_LIST_EMPTY(bark_list) +GLOBAL_LIST_EMPTY(bark_random_list) + //a way to index the right bodypart list given the type of bodypart GLOBAL_LIST_INIT(mutant_reference_list, list( "tail_lizard" = GLOB.tails_list_lizard, @@ -215,7 +220,13 @@ GLOBAL_LIST_INIT(jumpsuitlist, list(PREF_SUIT, PREF_SKIRT)) #define UPLINK_PDA "PDA" #define UPLINK_RADIO "Radio" #define UPLINK_PEN "Pen" //like a real spy! -GLOBAL_LIST_INIT(uplink_spawn_loc_list, list(UPLINK_PDA, UPLINK_RADIO, UPLINK_PEN)) +#define UPLINK_IMPLANT "Implant" +#define UPLINK_IMPLANT_WITH_PRICE "[UPLINK_IMPLANT] (-[UPLINK_IMPLANT_TELECRYSTAL_COST] TC)" +// What we show to the user +GLOBAL_LIST_INIT(uplink_spawn_loc_list, list(UPLINK_PDA, UPLINK_RADIO, UPLINK_PEN, UPLINK_IMPLANT_WITH_PRICE)) +// What is actually saved; if the uplink implant price changes, it won't affect save files then +GLOBAL_LIST_INIT(uplink_spawn_loc_list_save, list(UPLINK_PDA, UPLINK_RADIO, UPLINK_PEN, UPLINK_IMPLANT)) + //List of cached alpha masked icons. GLOBAL_LIST_EMPTY(alpha_masked_worn_icons) @@ -285,6 +296,8 @@ GLOBAL_LIST_INIT(station_names, world.file2list("strings/station_names.txt" + "" GLOBAL_LIST_INIT(station_suffixes, world.file2list("strings/station_suffixes.txt")) +GLOBAL_LIST_INIT(server_taglines, world.file2list("[global.config.directory]/server_taglines.txt")) + GLOBAL_LIST_INIT(greek_letters, world.file2list("strings/greek_letters.txt")) GLOBAL_LIST_INIT(phonetic_alphabet, world.file2list("strings/phonetic_alphabet.txt")) @@ -307,8 +320,8 @@ GLOBAL_LIST_INIT(redacted_strings, list("\[REDACTED\]", "\[CLASSIFIED\]", "\[ARC GLOBAL_LIST_INIT(wisdoms, world.file2list("strings/wisdoms.txt")) //LANGUAGE CHARACTER CUSTOMIZATION -GLOBAL_LIST_INIT(speech_verbs, list("default","says","gibbers", "states", "chitters", "chimpers", "declares", "bellows", "buzzes" ,"beeps", "chirps", "clicks", "hisses" ,"poofs" , "puffs", "rattles", "mewls" ,"barks", "blorbles", "squeaks", "squawks", "flutters", "warbles", "caws", "gekkers", "clucks")) -GLOBAL_LIST_INIT(roundstart_tongues, list("default","human tongue" = /obj/item/organ/tongue, "lizard tongue" = /obj/item/organ/tongue/lizard, "skeleton tongue" = /obj/item/organ/tongue/bone, "fly tongue" = /obj/item/organ/tongue/fly, "ipc tongue" = /obj/item/organ/tongue/robot/ipc, "xeno tongue" = /obj/item/organ/tongue/alien)) +GLOBAL_LIST_INIT(speech_verbs, list("default","says","gibbers", "states", "chitters", "chimpers", "declares", "bellows", "buzzes" ,"beeps", "chirps", "clicks", "hisses" ,"poofs" , "puffs", "rattles", "mewls" ,"barks", "blorbles", "squeaks", "squawks", "flutters", "warbles", "caws", "gekkers", "clucks","mumbles","crackles")) +GLOBAL_LIST_INIT(roundstart_tongues, list("default","human tongue" = /obj/item/organ/tongue, "lizard tongue" = /obj/item/organ/tongue/lizard, "skeleton tongue" = /obj/item/organ/tongue/bone, "fly tongue" = /obj/item/organ/tongue/fly, "ipc tongue" = /obj/item/organ/tongue/robot/ipc, "xeno tongue" = /obj/item/organ/tongue/alien/hybrid)) /proc/get_roundstart_languages() var/list/languages = subtypesof(/datum/language) @@ -337,40 +350,6 @@ GLOBAL_LIST_INIT(greyscale_limb_types, list("human","moth","lizard","pod","plant //body ids that have prosthetic sprites GLOBAL_LIST_INIT(prosthetic_limb_types, list("xion","bishop","cybersolutions","grayson","hephaestus","nanotrasen","talon")) -//FAMILY HEIRLOOM LIST -//this works by using the first number for the species as a probability to choose one of the items in the following list for their family heirloom -//if the probability fails, or the species simply isn't in the list, then it defaults to the next global list, which has its own list of items for each job -//the first item in the list is for if your job isn't in that list - -//species-heirloom list (we categorise them by the species id var) -GLOBAL_LIST_INIT(species_heirlooms, list( - "dwarf" = list(25, list(/obj/item/reagent_containers/food/drinks/dwarf_mug)), //example: 25% chance for dwarves to get a dwarf mug as their heirloom (normal container but has manly dorf icon) - "insect" = list(25, list(/obj/item/flashlight/lantern/heirloom_moth)), - "ipc" = list(25, list(/obj/item/stock_parts/cell/family)), //gives a broken powercell for flavor text! - "synthliz" = list(25, list(/obj/item/stock_parts/cell/family)), //they're also robots - "slimeperson" = list(25, list(/obj/item/toy/plush/slimeplushie)), - "lizard" = list(25, list(/obj/item/toy/plush/lizardplushie)), - )) - -//job-heirloom list -GLOBAL_LIST_INIT(job_heirlooms, list( - "NO_JOB" = list(/obj/item/toy/cards/deck, /obj/item/lighter, /obj/item/dice/d20), - "Clown" = list(/obj/item/paint/anycolor, /obj/item/bikehorn/golden), - "Mime" = list(/obj/item/paint/anycolor, /obj/item/toy/dummy), - "Cook" = list(/obj/item/kitchen/knife/scimitar), - "Botanist" = list(/obj/item/cultivator, /obj/item/reagent_containers/glass/bucket, /obj/item/storage/bag/plants, /obj/item/toy/plush/beeplushie), - "Medical Doctor" = list(/obj/item/healthanalyzer), - "Paramedic" = list(/obj/item/lighter), //..why? - "Station Engineer" = list(/obj/item/wirecutters/brass/family, /obj/item/crowbar/brass/family, /obj/item/screwdriver/brass/family, /obj/item/wrench/brass/family), //brass tools but without the tool speed modifier - "Atmospheric Technician" = list(/obj/item/extinguisher/mini/family), - "Lawyer" = list(/obj/item/storage/briefcase/lawyer/family), - "Janitor" = list(/obj/item/mop), - "Scientist" = list(/obj/item/toy/plush/slimeplushie), - "Assistant" = list(/obj/item/clothing/gloves/cut/family), - "Chaplain" = list(/obj/item/camera/spooky/family), - "Head of Personnel" = list(/obj/item/pinpointer/ian) - )) - //body ids that have non-gendered bodyparts GLOBAL_LIST_INIT(nongendered_limb_types, list("fly", "zombie" ,"synth", "shadow", "cultgolem", "agent", "plasmaman", "clockgolem", "clothgolem")) diff --git a/code/_globalvars/lists/loadout_categories.dm b/code/_globalvars/lists/loadout_categories.dm index 4a61a94dc7..53604111dd 100644 --- a/code/_globalvars/lists/loadout_categories.dm +++ b/code/_globalvars/lists/loadout_categories.dm @@ -4,11 +4,13 @@ GLOBAL_LIST_INIT(loadout_categories, list( LOADOUT_CATEGORY_MASK = LOADOUT_SUBCATEGORIES_NONE, LOADOUT_CATEGORY_HANDS = LOADOUT_SUBCATEGORIES_NONE, LOADOUT_CATEGORY_UNIFORM = list(LOADOUT_SUBCATEGORY_UNIFORM_GENERAL, LOADOUT_SUBCATEGORY_UNIFORM_JOBS, LOADOUT_SUBCATEGORY_UNIFORM_SUITS, LOADOUT_SUBCATEGORY_UNIFORM_SKIRTS, LOADOUT_SUBCATEGORY_UNIFORM_DRESSES, LOADOUT_SUBCATEGORY_UNIFORM_SWEATERS, LOADOUT_SUBCATEGORY_UNIFORM_PANTS, LOADOUT_SUBCATEGORY_UNIFORM_SHORTS), + LOADOUT_CATEGORY_ACCESSORY = LOADOUT_SUBCATEGORIES_NONE, LOADOUT_CATEGORY_SUIT = list(LOADOUT_SUBCATEGORY_SUIT_GENERAL, LOADOUT_SUBCATEGORY_SUIT_COATS, LOADOUT_SUBCATEGORY_SUIT_JACKETS, LOADOUT_SUBCATEGORY_SUIT_JOBS), LOADOUT_CATEGORY_HEAD = list(LOADOUT_SUBCATEGORY_HEAD_GENERAL, LOADOUT_SUBCATEGORY_HEAD_JOBS), LOADOUT_CATEGORY_SHOES = LOADOUT_SUBCATEGORIES_NONE, LOADOUT_CATEGORY_GLOVES = LOADOUT_SUBCATEGORIES_NONE, LOADOUT_CATEGORY_GLASSES = LOADOUT_SUBCATEGORIES_NONE, LOADOUT_CATEGORY_DONATOR = LOADOUT_SUBCATEGORIES_NONE, - LOADOUT_CATEGORY_UNLOCKABLE = LOADOUT_SUBCATEGORIES_NONE + LOADOUT_CATEGORY_UNLOCKABLE = LOADOUT_SUBCATEGORIES_NONE, + LOADOUT_CATEGORY_ERROR = LOADOUT_SUBCATEGORIES_NONE )) diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm index daa4f5879d..d02ebb659e 100644 --- a/code/_globalvars/lists/maintenance_loot.dm +++ b/code/_globalvars/lists/maintenance_loot.dm @@ -49,8 +49,12 @@ GLOBAL_LIST_INIT(maintenance_loot, list( /obj/item/radio/off = 2, /obj/item/t_scanner = 5, /obj/item/airlock_painter = 1, + /obj/item/airlock_painter/decal = 1, + /obj/item/airlock_painter/decal/tile = 1, /obj/item/stack/cable_coil/random = 4, /obj/item/stack/cable_coil/random/five = 6, + /obj/item/mod/construction/broken_core = 5, + /obj/item/mod/module/springlock = 1, /obj/item/stack/medical/suture = 1, /obj/item/stack/rods/ten = 9, /obj/item/stack/rods/twentyfive = 1, @@ -112,7 +116,6 @@ GLOBAL_LIST_INIT(maintenance_loot, list( /obj/item/storage/box/marshmallow = 2, /obj/item/clothing/gloves/tackler/offbrand = 1, /obj/item/stack/sticky_tape = 1, - /obj/effect/spawner/lootdrop/grille_or_trash = 15, "" = 3 )) diff --git a/code/_globalvars/lists/mapping.dm b/code/_globalvars/lists/mapping.dm index 1e3f8d25eb..f10e3b7655 100644 --- a/code/_globalvars/lists/mapping.dm +++ b/code/_globalvars/lists/mapping.dm @@ -37,6 +37,7 @@ GLOBAL_LIST_EMPTY(emergencyresponseteamspawn) GLOBAL_LIST_EMPTY(servant_spawns) //Servants of Ratvar spawn here GLOBAL_LIST_EMPTY(city_of_cogs_spawns) //Anyone entering the City of Cogs spawns here GLOBAL_LIST_EMPTY(ruin_landmarks) +GLOBAL_LIST_EMPTY(bar_areas) //away missions GLOBAL_LIST_EMPTY(vr_spawnpoints) diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index 64bac1f9af..5cbfd9f212 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -44,6 +44,17 @@ GLOBAL_LIST_EMPTY(mob_config_movespeed_type_lookup_floating) GLOBAL_LIST_EMPTY(latejoiners) //CIT CHANGE - All latejoining people, for traitor-target purposes. +/// All alive antags with clients. +GLOBAL_LIST_EMPTY(current_living_antags) + +/// All observers with clients that joined as observers. +GLOBAL_LIST_EMPTY(current_observers_list) + +//Dynamic Port +GLOBAL_LIST_EMPTY(new_player_list) //all /mob/dead/new_player, in theory all should have clients and those that don't are in the process of spawning and get deleted when done. +//Family Port +GLOBAL_LIST_EMPTY(pre_setup_antags) //minds that have been picked as antag by the gamemode. removed as antag datums are set. + /proc/update_config_movespeed_type_lookup(update_mobs = TRUE) // NOTE: This is entirely based on the fact that byond typesof/subtypesof gets longer/deeper paths before shallower ones. // If that ever breaks this entire proc breaks. diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index 9abc37c7e4..921b512d32 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -16,10 +16,11 @@ GLOBAL_LIST_EMPTY(singularities) //list of all singularities on the stati GLOBAL_LIST_EMPTY(grounding_rods) //list of all grounding rods on the station GLOBAL_LIST(chemical_reactions_list) //list of all /datum/chemical_reaction datums. Used during chemical reactions +GLOBAL_LIST(drink_reactions_list) //list of all /datum/chemical_reaction datums where the output is of type /datum/reagent/consumable for bartender PDA +GLOBAL_LIST(normalized_chemical_reactions_list) //list of all /datum/chemical_reaction datums with actual sane indexing for chemistry PDA GLOBAL_LIST(chemical_reagents_list) //list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff GLOBAL_LIST_EMPTY(tech_list) //list of all /datum/tech datums indexed by id. GLOBAL_LIST_EMPTY(surgeries_list) //list of all surgeries by name, associated with their path. -GLOBAL_LIST_EMPTY(uplink_items) //list of all uplink item typepaths, ascendingly sorted by their initial name. GLOBAL_LIST_EMPTY(uplink_categories) //list of all uplink categories, listed by the order they are loaded in code. Be careful. GLOBAL_LIST_EMPTY(crafting_recipes) //list of all table craft recipes GLOBAL_LIST_EMPTY(rcd_list) //list of Rapid Construction Devices. diff --git a/code/_globalvars/lists/typecache.dm b/code/_globalvars/lists/typecache.dm index 1ec3de0bc5..d380816bbf 100644 --- a/code/_globalvars/lists/typecache.dm +++ b/code/_globalvars/lists/typecache.dm @@ -12,3 +12,16 @@ GLOBAL_LIST_INIT(typecache_stack, typecacheof(/obj/item/stack)) GLOBAL_LIST_INIT(typecache_machine_or_structure, typecacheof(list(/obj/machinery, /obj/structure))) GLOBAL_LIST_INIT(freezing_objects, typecacheof(list(/obj/structure/closet/crate/freezer, /obj/structure/closet/secure_closet/freezer, /obj/structure/bodycontainer, /obj/item/autosurgeon, /obj/machinery/smartfridge/organ))) //list of all cold objects, that freeze organs when inside + +GLOBAL_LIST_EMPTY(typecaches) + +/** + * Makes a typecache of a single typecache + * + * Obviously in BYOND we don't have the efficiency around here to have proper enforcement so + * If you use this you better know what you're doing. The list you get back is globally cached and if it's modified, you might break multiple things. + */ +/proc/single_path_typecache_immutable(path) + if(!GLOB.typecaches[path]) + GLOB.typecaches[path] = typecacheof(path) + return GLOB.typecaches[path] diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm index 78d802dbbf..e9c38546a7 100644 --- a/code/_globalvars/logging.dm +++ b/code/_globalvars/logging.dm @@ -2,12 +2,17 @@ GLOBAL_VAR(log_directory) GLOBAL_PROTECT(log_directory) GLOBAL_VAR(world_game_log) GLOBAL_PROTECT(world_game_log) +/// Log associated with [/proc/log_suspicious_login()] - Intended to hold all logins that failed due to suspicious circumstances such as ban detection, CID randomisation etc. +GLOBAL_VAR(world_suspicious_login_log) +GLOBAL_PROTECT(world_suspicious_login_log) GLOBAL_VAR(world_runtime_log) GLOBAL_PROTECT(world_runtime_log) GLOBAL_VAR(world_qdel_log) GLOBAL_PROTECT(world_qdel_log) GLOBAL_VAR(world_attack_log) GLOBAL_PROTECT(world_attack_log) +GLOBAL_VAR(world_victim_log) +GLOBAL_PROTECT(world_victim_log) // GLOBAL_VAR(world_econ_log) // GLOBAL_PROTECT(world_econ_log) GLOBAL_VAR(world_href_log) @@ -28,8 +33,8 @@ GLOBAL_VAR(query_debug_log) GLOBAL_PROTECT(query_debug_log) GLOBAL_VAR(world_job_debug_log) GLOBAL_PROTECT(world_job_debug_log) -// GLOBAL_VAR(world_mecha_log) -// GLOBAL_PROTECT(world_mecha_log) +GLOBAL_VAR(world_mecha_log) +GLOBAL_PROTECT(world_mecha_log) GLOBAL_VAR(world_virus_log) GLOBAL_PROTECT(world_virus_log) GLOBAL_VAR(world_asset_log) @@ -44,6 +49,8 @@ GLOBAL_VAR(tgui_log) GLOBAL_PROTECT(tgui_log) GLOBAL_VAR(world_shuttle_log) GLOBAL_PROTECT(world_shuttle_log) +GLOBAL_VAR(world_econ_log) +GLOBAL_PROTECT(world_econ_log) GLOBAL_VAR(perf_log) GLOBAL_PROTECT(perf_log) diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm index b039e6d114..49c22bce01 100644 --- a/code/_globalvars/misc.dm +++ b/code/_globalvars/misc.dm @@ -6,8 +6,6 @@ GLOBAL_VAR_INIT(year, time2text(world.realtime,"YYYY")) GLOBAL_VAR_INIT(year_integer, text2num(year)) // = 2013??? -GLOBAL_VAR_INIT(announcertype, "standard") - // For FTP requests. (i.e. downloading runtime logs.) // However it'd be ok to use for accessing attack logs and such too, which are even laggier. GLOBAL_VAR_INIT(fileaccess_timer, 0) diff --git a/code/_globalvars/tgui.dm b/code/_globalvars/tgui.dm new file mode 100644 index 0000000000..1a2c46c10d --- /dev/null +++ b/code/_globalvars/tgui.dm @@ -0,0 +1 @@ +GLOBAL_DATUM(changelog_tgui, /datum/changelog) diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index bbe801cfc2..e3d15e9965 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -38,6 +38,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_RESISTCOLD" = TRAIT_RESISTCOLD, "TRAIT_RESISTHIGHPRESSURE" = TRAIT_RESISTHIGHPRESSURE, "TRAIT_RESISTLOWPRESSURE" = TRAIT_RESISTLOWPRESSURE, + "TRAIT_LOWPRESSURECOOLING" = TRAIT_LOWPRESSURECOOLING, "TRAIT_BOMBIMMUNE" = TRAIT_BOMBIMMUNE, "TRAIT_RADIMMUNE" = TRAIT_RADIMMUNE, "TRAIT_GENELESS" = TRAIT_GENELESS, @@ -55,6 +56,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ROBOTIC_ORGANISM" = TRAIT_ROBOTIC_ORGANISM, "TRAIT_ROBOT_RADSHIELDING" = TRAIT_ROBOT_RADSHIELDING, "TRAIT_NOBREATH" = TRAIT_NOBREATH, + "TRAIT_AUXILIARY_LUNGS" = TRAIT_AUXILIARY_LUNGS, "TRAIT_ANTIMAGIC" = TRAIT_ANTIMAGIC, "TRAIT_HOLY" = TRAIT_HOLY, "TRAIT_DEPRESSION" = TRAIT_DEPRESSION, @@ -124,8 +126,14 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_EMPATH" = TRAIT_EMPATH, "TRAIT_FRIENDLY" = TRAIT_FRIENDLY, "TRAIT_IWASBATONED" = TRAIT_IWASBATONED, - "TRAIT_SPACEWALK" = TRAIT_SPACEWALK - ), + "TRAIT_SPACEWALK" = TRAIT_SPACEWALK, + "TRAIT_SALT_SENSITIVE" = TRAIT_SALT_SENSITIVE, + "TRAIT_LAVA_IMMUNE" = TRAIT_LAVA_IMMUNE, + "TRAIT_ASHSTORM_IMMUNE" = TRAIT_ASHSTORM_IMMUNE, + "TRAIT_SNOWSTORM_IMMUNE" = TRAIT_SNOWSTORM_IMMUNE, + "TRAIT_VOIDSTORM_IMMUNE" = TRAIT_VOIDSTORM_IMMUNE, + "TRAIT_WEATHER_IMMUNE" = TRAIT_WEATHER_IMMUNE + ), /obj/item/bodypart = list( "TRAIT_PARALYSIS" = TRAIT_PARALYSIS ), diff --git a/code/_onclick/adjacent.dm b/code/_onclick/adjacent.dm index 3f3eecb676..e629a6eb57 100644 --- a/code/_onclick/adjacent.dm +++ b/code/_onclick/adjacent.dm @@ -94,7 +94,7 @@ for(var/obj/O in src) if((mover && O.CanPass(mover,get_step(src,target_dir))) || (!mover && !O.density)) continue - if(O == target_atom || O == mover || (O.pass_flags & LETPASSTHROW)) //check if there's a dense object present on the turf + if(O == target_atom || O == mover || (O.pass_flags_self & LETPASSTHROW)) //check if there's a dense object present on the turf continue // LETPASSTHROW is used for anything you can click through (or the firedoor special case, see above) if( O.flags_1&ON_BORDER_1) // windows are on border, check them first diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index c7834dc5ef..239ef319d1 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -55,11 +55,6 @@ if(modifiers["shift"] && modifiers["ctrl"]) CtrlShiftClickOn(A) return - if(modifiers["middle"]) - if(controlled_mech) //Are we piloting a mech? Placed here so the modifiers are not overridden. - controlled_mech.click_action(A, src, params) //Override AI normal click behavior. - return - if(modifiers["shift"]) ShiftClickOn(A) return diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 9321427387..6e8d1de955 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -63,6 +63,8 @@ return ShiftClickOn(A) if(modifiers["alt"]) // alt and alt-gr (rightalt) return AltClickOn(A) + if(modifiers["ctrl"] && modifiers["right"]) //CIT CHANGE - right click ctrl for a new form of dropping items + return CtrlRightClickOn(A, params) //CIT CHANGE if(modifiers["ctrl"]) return CtrlClickOn(A) @@ -80,11 +82,6 @@ if(!modifiers["catcher"] && A.IsObscured()) return - if(ismecha(loc)) - var/obj/mecha/M = loc - M.click_action(A,src,params) - return TRUE - if(restrained()) DelayNextAction(CLICK_CD_HANDCUFFED) return RestrainedClickOn(A) @@ -295,6 +292,46 @@ if(!(flags & COMPONENT_DENY_EXAMINATE) && user.client && (user.client.eye == user || user.client.eye == user.loc || flags & COMPONENT_ALLOW_EXAMINATE)) user.examinate(src) +/* + Ctrl + Right click + Combat mode feature + Drop item in hand at position. +*/ +/atom/proc/CtrlRightClickOn(atom/A, params) + if(isliving(src) && Adjacent(A)) //honestly only humans can do this given it's combat mode but if it's implemented for any other mobs... + var/mob/living/L = src + if(L.incapacitated()) + return + var/obj/item/I = L.get_active_held_item() + var/turf/T = get_turf(A) + if(T) + if(I) //drop item at cursor. + if(T.density) //no, you can't use your funny blue cube or red cube to clip into the fucking wall. + return + for(var/atom/C in T.contents) //nor can you clip into a window or a door/false wall that's not open. + if(C.opacity || (((C.flags_1 & PREVENT_CLICK_UNDER_1) > 0) != (istype(C,/obj/machinery/door) && !C.density))) //XOR operation within because doors always have PREVENT_CLICK_UNDER_1 flag enabled. Dumb, I know. + return + if(L.transferItemToLoc(I, T)) + var/list/click_params = params2list(params) + //Center the icon where the user clicked. (shamelessly stole code from tables) + if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) + return + //Clamp it so that the icon never moves more than 16 pixels in either direction + I.pixel_x = clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) + I.pixel_y = clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) + return TRUE + else if(isitem(A) && L.has_active_hand()) //if they have an open hand they'll rotate the item instead. + var/obj/item/I2 = A + if(!I2.anchored) + var/matrix/ntransform = matrix(I2.transform) + ntransform.Turn(15) + animate(I2, transform = ntransform, time = 2) + return TRUE + else + A.CtrlClick(src) + + + /* Ctrl click For most objects, pull @@ -368,7 +405,7 @@ return /atom/proc/CtrlShiftClick(mob/user) - SEND_SIGNAL(src, COMSIG_CLICK_CTRL_SHIFT) + SEND_SIGNAL(src, COMSIG_CLICK_CTRL_SHIFT, user) return /* @@ -428,51 +465,6 @@ else setDir(WEST, ismousemovement) -//debug -/atom/movable/screen/proc/scale_to(x1,y1) - if(!y1) - y1 = x1 - var/matrix/M = new - M.Scale(x1,y1) - transform = M - -/atom/movable/screen/click_catcher - icon = 'icons/mob/screen_gen.dmi' - icon_state = "catcher" - plane = CLICKCATCHER_PLANE - mouse_opacity = MOUSE_OPACITY_OPAQUE - screen_loc = "CENTER" - -#define MAX_SAFE_BYOND_ICON_SCALE_TILES (MAX_SAFE_BYOND_ICON_SCALE_PX / world.icon_size) -#define MAX_SAFE_BYOND_ICON_SCALE_PX (33 * 32) //Not using world.icon_size on purpose. - -/atom/movable/screen/click_catcher/proc/UpdateGreed(view_size_x = 15, view_size_y = 15) - var/icon/newicon = icon('icons/mob/screen_gen.dmi', "catcher") - var/ox = min(MAX_SAFE_BYOND_ICON_SCALE_TILES, view_size_x) - var/oy = min(MAX_SAFE_BYOND_ICON_SCALE_TILES, view_size_y) - var/px = view_size_x * world.icon_size - var/py = view_size_y * world.icon_size - var/sx = min(MAX_SAFE_BYOND_ICON_SCALE_PX, px) - var/sy = min(MAX_SAFE_BYOND_ICON_SCALE_PX, py) - newicon.Scale(sx, sy) - icon = newicon - screen_loc = "CENTER-[(ox-1)*0.5],CENTER-[(oy-1)*0.5]" - var/matrix/M = new - M.Scale(px/sx, py/sy) - transform = M - -/atom/movable/screen/click_catcher/Click(location, control, params) - var/list/modifiers = params2list(params) - if(modifiers["middle"] && iscarbon(usr)) - var/mob/living/carbon/C = usr - C.swap_hand() - else - var/turf/T = params2turf(modifiers["screen-loc"], get_turf(usr.client ? usr.client.eye : usr), usr.client) - params += "&catcher=1" - if(T) - T.Click(location, control, params) - . = 1 - /* MouseWheelOn */ /mob/proc/MouseWheelOn(atom/A, delta_x, delta_y, params) diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index cf3f45e196..743d75b557 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -43,7 +43,7 @@ INVOKE_ASYNC(aicamera, /obj/item/camera.proc/captureimage, A, usr) return - var/obj/item/W = get_active_held_item() + var/obj/item/W = get_active_held_item(TRUE) if(!W && A.Adjacent(src) && (isobj(A) || ismob(A))) var/atom/movable/C = A diff --git a/code/_onclick/drag_drop.dm b/code/_onclick/drag_drop.dm index ae853a4e1a..a698706f1a 100644 --- a/code/_onclick/drag_drop.dm +++ b/code/_onclick/drag_drop.dm @@ -23,23 +23,31 @@ SEND_SIGNAL(src, COMSIG_MOUSEDROPPED_ONTO, dropping, user) return - -/client/MouseDown(object, location, control, params) - if (mouse_down_icon) +/client/MouseDown(datum/object, location, control, params) + if(!control) + return + if(QDELETED(object)) //Yep, you can click on qdeleted things before they have time to nullspace. Fun. + return + SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEDOWN, object, location, control, params) + if(mouse_down_icon) mouse_pointer_icon = mouse_down_icon var/delay = mob.CanMobAutoclick(object, location, params) if(delay) selected_target[1] = object selected_target[2] = params while(selected_target[1]) - Click(selected_target[1], location, control, selected_target[2], TRUE) + Click(selected_target[1], location, control, selected_target[2]) sleep(delay) active_mousedown_item = mob.canMobMousedown(object, location, params) if(active_mousedown_item) active_mousedown_item.onMouseDown(object, location, params, mob) /client/MouseUp(object, location, control, params) - if (mouse_up_icon) + if(!control) + return + if(SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEUP, object, location, control, params) & COMPONENT_CLIENT_MOUSEUP_INTERCEPT) + click_intercept_time = world.time + if(mouse_up_icon) mouse_pointer_icon = mouse_up_icon selected_target[1] = null if(active_mousedown_item) @@ -74,9 +82,6 @@ /obj/item/proc/onMouseUp(object, location, params, mob) return -/obj/item/gun/CanItemAutoclick(object, location, params) - . = automatic - /atom/proc/IsAutoclickable() . = 1 @@ -101,14 +106,6 @@ ..() /client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params) - var/list/L = params2list(params) - if (L["middle"]) - if (src_object && src_location != over_location) - middragtime = world.time - middragatom = src_object - else - middragtime = 0 - middragatom = null mouseParams = params mouseLocation = over_location mouseObject = over_object @@ -118,12 +115,7 @@ selected_target[2] = params if(active_mousedown_item) active_mousedown_item.onMouseDrag(src_object, over_object, src_location, over_location, params, mob) + SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEDRAG, src_object, over_object, src_location, over_location, src_control, over_control, params) /obj/item/proc/onMouseDrag(src_object, over_object, src_location, over_location, params, mob) return - -/client/MouseDrop(src_object, over_object, src_location, over_location, src_control, over_control, params) - if (middragatom == src_object) - middragtime = 0 - middragatom = null - ..() diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index d1fff25dae..2831e25b10 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -47,6 +47,7 @@ #define ui_back "CENTER-2:14,SOUTH:5" #define ui_storage1 "CENTER+1:18,SOUTH:5" #define ui_storage2 "CENTER+2:20,SOUTH:5" +#define ui_combo "CENTER+4:24,SOUTH+1:7" // combo meter for martial arts //Lower right, persistent menu #define ui_drop_throw "EAST-1:28,SOUTH+1:7" @@ -176,9 +177,6 @@ #define ui_ghost_mafia "SOUTH: 6, CENTER+2:24" #define ui_ghost_spawners "SOUTH: 6, CENTER+1:24" // LEGACY. SAME LOC AS PAI -// #define ui_wanted_lvl "NORTH,11" - - //UI position overrides for 1:1 screen layout. (default is 7:5) #define ui_stamina "EAST-1:28,CENTER:17" // replacing internals button #define ui_overridden_resist "EAST-3:24,SOUTH+1:7" @@ -190,3 +188,5 @@ #define ui_boxarea "EAST-4:6,SOUTH+1:6" #define ui_boxlang "EAST-5:22,SOUTH+1:6" #define ui_boxvore "EAST-5:22,SOUTH+1:6" + +#define ui_wanted_lvl "NORTH,11" diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index 791cf336ac..d97e1f5d04 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -72,7 +72,7 @@ var/mutable_appearance/hide_appearance var/mutable_appearance/show_appearance -/atom/movable/screen/movable/action_button/hide_toggle/Initialize() +/atom/movable/screen/movable/action_button/hide_toggle/Initialize(mapload) . = ..() var/static/list/icon_cache = list() diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index ed4c91dd9b..5029d51452 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -2,9 +2,6 @@ //PUBLIC - call these wherever you want - -/mob/proc/throw_alert(category, type, severity, obj/new_master, override = FALSE) - /* Proc to create or update an alert. Returns the alert if the alert is new or updated, 0 if it was thrown already category is a text string. Each mob may only have one alert per category; the previous one will be replaced path is a type path of the actual alert type to throw @@ -14,6 +11,7 @@ Clicks are forwarded to master Override makes it so the alert is not replaced until cleared by a clear_alert with clear_override, and it's used for hallucinations. */ +/mob/proc/throw_alert(category, type, severity, obj/new_master, override = FALSE) if(!category || QDELETED(src)) return @@ -42,7 +40,7 @@ thealert.override_alerts = override if(override) thealert.timeout = null - thealert.mob_viewer = src + thealert.owner = src if(new_master) var/old_layer = new_master.layer @@ -62,7 +60,7 @@ if(client && hud_used) hud_used.reorganize_alerts() thealert.transform = matrix(32, 6, MATRIX_TRANSLATE) - animate(thealert, transform = matrix(), time = 2.5, easing = CUBIC_EASING) + animate(thealert, transform = matrix(), time = 2.5, easing = BACK_EASING) if(thealert.timeout) addtimer(CALLBACK(src, .proc/alert_timeout, thealert, category), thealert.timeout) @@ -97,8 +95,10 @@ var/severity = 0 var/alerttooltipstyle = "" var/override_alerts = FALSE //If it is overriding other alerts of the same type - var/mob/mob_viewer //the mob viewing this alert + var/mob/owner //Alert owner + /// Boolean. If TRUE, the Click() proc will attempt to Click() on the master first if there is a master. + var/click_master = TRUE /atom/movable/screen/alert/MouseEntered(location,control,params) if(!QDELETED(src)) @@ -251,6 +251,8 @@ or something covering your eyes." /atom/movable/screen/alert/mind_control/Click() var/mob/living/L = usr + if(L != owner) + return to_chat(L, "[command]") /atom/movable/screen/alert/hypnosis @@ -271,7 +273,7 @@ If you're feeling frisky, examine yourself and click the underlined item to pull icon_state = "embeddedobject" /atom/movable/screen/alert/embeddedobject/Click() - if(isliving(usr)) + if(isliving(usr) && usr == owner) var/mob/living/carbon/M = usr return M.help_shake_act(M) @@ -300,7 +302,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." /atom/movable/screen/alert/fire/Click() var/mob/living/L = usr - if(!istype(L) || !L.can_resist()) + if(!istype(L) || !L.can_resist() || L != owner) return L.MarkResistTime() if(CHECK_MOBILITY(L, MOBILITY_MOVE)) @@ -308,37 +310,110 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." /atom/movable/screen/alert/give // information set when the give alert is made icon_state = "default" - var/mob/living/carbon/giver + var/mob/living/carbon/offerer var/obj/item/receiving /** - * Handles assigning most of the variables for the alert that pops up when an item is offered - * - * Handles setting the name, description and icon of the alert and tracking the person giving - * and the item being offered, also registers a signal that removes the alert from anyone who moves away from the giver - * Arguments: - * * taker - The person receiving the alert - * * giver - The person giving the alert and item - * * receiving - The item being given by the giver - */ -/atom/movable/screen/alert/give/proc/setup(mob/living/carbon/taker, mob/living/carbon/giver, obj/item/receiving) - name = "[giver] is offering [receiving]" - desc = "[giver] is offering [receiving]. Click this alert to take it." + * Handles assigning most of the variables for the alert that pops up when an item is offered + * + * Handles setting the name, description and icon of the alert and tracking the person giving + * and the item being offered, also registers a signal that removes the alert from anyone who moves away from the offerer + * Arguments: + * * taker - The person receiving the alert + * * offerer - The person giving the alert and item + * * receiving - The item being given by the offerer + */ +/atom/movable/screen/alert/give/proc/setup(mob/living/carbon/taker, mob/living/carbon/offerer, obj/item/receiving) + name = "[offerer] is offering [receiving]" + desc = "[offerer] is offering [receiving]. Click this alert to take it." icon_state = "template" cut_overlays() add_overlay(receiving) src.receiving = receiving - src.giver = giver - RegisterSignal(taker, COMSIG_MOVABLE_MOVED, .proc/removeAlert) - -/atom/movable/screen/alert/give/proc/removeAlert() - to_chat(usr, "You moved out of range of [giver]!") - usr.clear_alert("[giver]") + src.offerer = offerer + RegisterSignal(taker, COMSIG_MOVABLE_MOVED, .proc/check_in_range, override = TRUE) //Override to prevent runtimes when people offer a item multiple times /atom/movable/screen/alert/give/Click(location, control, params) . = ..() - var/mob/living/carbon/C = usr - C.take(giver, receiving) + if(!.) + return + if(!iscarbon(usr)) + CRASH("User for [src] is of type \[[usr.type]\]. This should never happen.") + handle_transfer() + +/// An overrideable proc used simply to hand over the item when claimed, this is a proc so that high-fives can override them since nothing is actually transferred +/atom/movable/screen/alert/give/proc/handle_transfer() + var/mob/living/carbon/taker = owner + taker.take(offerer, receiving) + +/// Simply checks if the other person is still in range +/atom/movable/screen/alert/give/proc/check_in_range(atom/taker) + SIGNAL_HANDLER + + if(!offerer.CanReach(taker)) + to_chat(owner, span_warning("You moved out of range of [offerer]!")) + owner.clear_alert("[offerer]") + +/atom/movable/screen/alert/give/highfive/setup(mob/living/carbon/taker, mob/living/carbon/offerer, obj/item/receiving) + . = ..() + name = "[offerer] is offering a high-five!" + desc = "[offerer] is offering a high-five! Click this alert to slap it." + RegisterSignal(offerer, COMSIG_PARENT_EXAMINE_MORE, .proc/check_fake_out) + +/atom/movable/screen/alert/give/highfive/handle_transfer() + var/mob/living/carbon/taker = owner + if(receiving && (receiving in offerer.held_items)) + receiving.on_offer_taken(offerer, taker) + return + too_slow_p1() + +/// If the person who offered the high five no longer has it when we try to accept it, we get pranked hard +/atom/movable/screen/alert/give/highfive/proc/too_slow_p1() + var/mob/living/carbon/rube = owner + if(!rube || !offerer) + qdel(src) + return + + offerer.visible_message(span_notice("[rube] rushes in to high-five [offerer], but-"), span_nicegreen("[rube] falls for your trick just as planned, lunging for a high-five that no longer exists! Classic!"), ignored_mobs=rube) + to_chat(rube, span_nicegreen("You go in for [offerer]'s high-five, but-")) + addtimer(CALLBACK(src, .proc/too_slow_p2, offerer, rube), 0.5 SECONDS) + +/// Part two of the ultimate prank +/atom/movable/screen/alert/give/highfive/proc/too_slow_p2() + var/mob/living/carbon/rube = owner + if(!rube || !offerer) + qdel(src) + return + + offerer.visible_message(span_danger("[offerer] pulls away from [rube]'s slap at the last second, dodging the high-five entirely!"), span_nicegreen("[rube] fails to make contact with your hand, making an utter fool of [rube.p_them()]self!"), span_hear("You hear a disappointing sound of flesh not hitting flesh!"), ignored_mobs=rube) + var/all_caps_for_emphasis = uppertext("NO! [offerer] PULLS [offerer.p_their()] HAND AWAY FROM YOURS! YOU'RE TOO SLOW!") + to_chat(rube, span_userdanger("[all_caps_for_emphasis]")) + playsound(offerer, 'sound/weapons/thudswoosh.ogg', 100, TRUE, 1) + rube.Knockdown(1 SECONDS) + SEND_SIGNAL(offerer, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/down_low) + SEND_SIGNAL(rube, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/too_slow) + qdel(src) + +/// If someone examine_more's the offerer while they're trying to pull a too-slow, it'll tip them off to the offerer's trickster ways +/atom/movable/screen/alert/give/highfive/proc/check_fake_out(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + + if(!receiving) + examine_list += "[span_warning("[offerer]'s arm appears tensed up, as if [offerer.p_they()] plan on pulling it back suddenly...")]\n" + +/// Families handshakes +/atom/movable/screen/alert/give/secret_handshake + icon_state = "default" + +/atom/movable/screen/alert/give/secret_handshake/setup(mob/living/carbon/taker, mob/living/carbon/offerer, obj/item/receiving) + name = "[offerer] is offering a Handshake" + desc = "[offerer] wants to teach you the Secret Handshake for their Family and induct you! Click on this alert to accept." + icon_state = "template" + cut_overlays() + add_overlay(receiving) + src.receiving = receiving + src.offerer = offerer + RegisterSignal(taker, COMSIG_MOVABLE_MOVED, .proc/check_in_range, override = TRUE) //Override to prevent runtimes when people offer a item multiple times //ALIENS @@ -380,7 +455,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." var/angle = 0 var/mob/living/simple_animal/hostile/construct/Cviewer = null -/atom/movable/screen/alert/bloodsense/Initialize() +/atom/movable/screen/alert/bloodsense/Initialize(mapload) . = ..() narnar = new('icons/mob/screen_alert.dmi', "mini_nar") START_PROCESSING(SSprocessing, src) @@ -393,10 +468,10 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." /atom/movable/screen/alert/bloodsense/process() var/atom/blood_target - if(!mob_viewer.mind) + if(!owner.mind) return - var/datum/antagonist/cult/antag = mob_viewer.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + var/datum/antagonist/cult/antag = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) if(!antag?.cult_team) return var/datum/objective/sacrifice/sac_objective = locate() in antag.cult_team.objectives @@ -433,7 +508,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." add_overlay(narnar) return var/turf/P = get_turf(blood_target) - var/turf/Q = get_turf(mob_viewer) + var/turf/Q = get_turf(owner) if(!P || !Q || (P.z != Q.z)) //The target is on a different Z level, we cannot sense that far. icon_state = "runed_sense2" desc = "You can no longer sense your target's presence." @@ -497,7 +572,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." for(var/mob/living/L in GLOB.alive_mob_list) if(is_servant_of_ratvar(L)) servants++ - var/datum/antagonist/clockcult/C = mob_viewer.mind.has_antag_datum(/datum/antagonist/clockcult,TRUE) + var/datum/antagonist/clockcult/C = owner.mind.has_antag_datum(/datum/antagonist/clockcult,TRUE) if(C && C.clock_team) textlist += "[C.clock_team.eminence ? "There is an Eminence." : "There is no Eminence! Get one ASAP!"]
" textlist += "There are currently [servants] servant[servants > 1 ? "s" : ""] of Ratvar.
" @@ -595,7 +670,7 @@ so as to remain in compliance with the most up-to-date laws." var/atom/target = null /atom/movable/screen/alert/hackingapc/Click() - if(!usr || !usr.client) + if(!usr || !usr.client || usr != owner) return if(!target) return @@ -621,7 +696,7 @@ so as to remain in compliance with the most up-to-date laws." timeout = 300 /atom/movable/screen/alert/notify_cloning/Click() - if(!usr || !usr.client) + if(!usr || !usr.client || usr != owner) return var/mob/dead/observer/G = usr G.reenter_corpse() @@ -635,7 +710,7 @@ so as to remain in compliance with the most up-to-date laws." var/action = NOTIFY_JUMP /atom/movable/screen/alert/notify_action/Click() - if(!usr || !usr.client) + if(!usr || !usr.client || usr != owner) return if(!target) return @@ -669,14 +744,14 @@ so as to remain in compliance with the most up-to-date laws." /atom/movable/screen/alert/restrained/Click() var/mob/living/L = usr - if(!istype(L) || !L.can_resist()) + if(!istype(L) || !L.can_resist() || L != owner) return L.MarkResistTime() return L.resist_restraints() /atom/movable/screen/alert/restrained/buckled/Click() var/mob/living/L = usr - if(!istype(L) || !L.can_resist()) + if(!istype(L) || !L.can_resist() || L != owner) return L.MarkResistTime() return L.resist_buckle() @@ -693,7 +768,7 @@ so as to remain in compliance with the most up-to-date laws." /atom/movable/screen/alert/shoes/Click() var/mob/living/carbon/C = usr - if(!istype(C) || !C.can_resist() || C != mob_viewer || !C.shoes) + if(!istype(C) || !C.can_resist() || C != owner || !C.shoes) return C.MarkResistTime() C.shoes.handle_tying(C) @@ -701,11 +776,14 @@ so as to remain in compliance with the most up-to-date laws." // PRIVATE = only edit, use, or override these if you're editing the system as a whole // Re-render all alerts - also called in /datum/hud/show_hud() because it's needed there -/datum/hud/proc/reorganize_alerts() +/datum/hud/proc/reorganize_alerts(mob/viewmob) + var/mob/screenmob = viewmob || mymob + if(!screenmob.client) + return var/list/alerts = mymob.alerts if(!hud_shown) for(var/i = 1, i <= alerts.len, i++) - mymob.client.screen -= alerts[alerts[i]] + screenmob.client.screen -= alerts[alerts[i]] return 1 for(var/i = 1, i <= alerts.len, i++) var/atom/movable/screen/alert/alert = alerts[alerts[i]] @@ -725,22 +803,29 @@ so as to remain in compliance with the most up-to-date laws." else . = "" alert.screen_loc = . - mymob.client.screen |= alert + screenmob.client.screen |= alert + if(!viewmob) + for(var/M in mymob.observers) + reorganize_alerts(M) return 1 /atom/movable/screen/alert/Click(location, control, params) if(!usr || !usr.client) - return + return FALSE + if(usr != owner) + return FALSE var/paramslist = params2list(params) if(paramslist["shift"]) // screen objects don't do the normal Click() stuff so we'll cheat to_chat(usr, "[name] - [desc]") - return - if(master) + return FALSE + if(master && click_master) return usr.client.Click(master, location, control, params) + return TRUE + /atom/movable/screen/alert/Destroy() . = ..() severity = 0 master = null - mob_viewer = null + owner = null screen_loc = "" diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm index bf7969a6ba..8a494a05b9 100644 --- a/code/_onclick/hud/alien.dm +++ b/code/_onclick/hud/alien.dm @@ -117,7 +117,7 @@ for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) inv.hud = src - inv_slots[inv.slot_id] = inv + inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv inv.update_icon() /datum/hud/alien/persistent_inventory_update() diff --git a/code/_onclick/hud/credits.dm b/code/_onclick/hud/credits.dm index 974f158323..aaf423ecbc 100644 --- a/code/_onclick/hud/credits.dm +++ b/code/_onclick/hud/credits.dm @@ -44,7 +44,7 @@ icon = I parent = P icon_state = credited - maptext = credited + maptext = MAPTEXT(credited) maptext_x = world.icon_size + 8 maptext_y = (world.icon_size / 2) - 4 maptext_width = world.icon_size * 3 diff --git a/code/_onclick/hud/drones.dm b/code/_onclick/hud/drones.dm index 849936d4ed..a2cae89864 100644 --- a/code/_onclick/hud/drones.dm +++ b/code/_onclick/hud/drones.dm @@ -8,7 +8,7 @@ inv_box.icon_state = "suit_storage" // inv_box.icon_full = "template" inv_box.screen_loc = ui_drone_storage - inv_box.slot_id = SLOT_GENERC_DEXTROUS_STORAGE + inv_box.slot_id = ITEM_SLOT_DEX_STORAGE static_inventory += inv_box inv_box = new /atom/movable/screen/inventory() @@ -17,13 +17,13 @@ inv_box.icon_state = "mask" // inv_box.icon_full = "template" inv_box.screen_loc = ui_drone_head - inv_box.slot_id = SLOT_HEAD + inv_box.slot_id = ITEM_SLOT_HEAD static_inventory += inv_box for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) inv.hud = src - inv_slots[inv.slot_id] = inv + inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv inv.update_icon() diff --git a/code/_onclick/hud/families.dm b/code/_onclick/hud/families.dm new file mode 100644 index 0000000000..6cc9f4ef32 --- /dev/null +++ b/code/_onclick/hud/families.dm @@ -0,0 +1,27 @@ +/atom/movable/screen/wanted + name = "Space Police Alertness" + desc = "Shows the current level of hostility the space police is planning to rain down on you. Better be careful." + icon = 'icons/obj/gang/wanted_160x32.dmi' + icon_state = "wanted_0" + screen_loc = ui_wanted_lvl + /// Wanted level, affects the hud icon. Level 0 is default, and the level 0 icon is blank, so in case of no families gamemode (and thus no wanted level), this HUD element will never appear. + level = 2 + /// Boolean, have the cops arrived? If so, the icon stops changing and remains the same. + var/cops_arrived = 0 + +/atom/movable/screen/wanted/New() + return ..() + +/atom/movable/screen/wanted/Initialize(mapload) + . = ..() + update_icon() + +/atom/movable/screen/wanted/MouseEntered(location,control,params) + openToolTip(usr,src,params,title = name,content = desc, theme = "alerttooltipstyle") + +/atom/movable/screen/wanted/MouseExited() + closeToolTip(usr) + +/atom/movable/screen/wanted/update_icon_state() + . = ..() + icon_state = "wanted_[level][cops_arrived ? "_active" : ""]" diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm deleted file mode 100644 index a7247ccf09..0000000000 --- a/code/_onclick/hud/fullscreen.dm +++ /dev/null @@ -1,186 +0,0 @@ -/mob/proc/overlay_fullscreen(category, type, severity) - var/atom/movable/screen/fullscreen/screen = screens[category] - if (!screen || screen.type != type) - // needs to be recreated - clear_fullscreen(category, FALSE) - screens[category] = screen = new type() - else if ((!severity || severity == screen.severity) && (!client || screen.screen_loc != "CENTER-7,CENTER-7" || screen.view == client.view)) - // doesn't need to be updated - return screen - - screen.icon_state = "[initial(screen.icon_state)][severity]" - screen.severity = severity - if (client && screen.should_show_to(src)) - screen.update_for_view(client.view) - client.screen += screen - - return screen - -/mob/proc/clear_fullscreen(category, animated = 10) - var/atom/movable/screen/fullscreen/screen = screens[category] - if(!screen) - return - - screens -= category - - if(animated) - animate(screen, alpha = 0, time = animated) - addtimer(CALLBACK(src, .proc/clear_fullscreen_after_animate, screen), animated, TIMER_CLIENT_TIME) - else - if(client) - client.screen -= screen - qdel(screen) - -/mob/proc/clear_fullscreen_after_animate(atom/movable/screen/fullscreen/screen) - if(client) - client.screen -= screen - qdel(screen) - -/mob/proc/clear_fullscreens() - for(var/category in screens) - clear_fullscreen(category) - -/mob/proc/hide_fullscreens() - if(client) - for(var/category in screens) - client.screen -= screens[category] - -/mob/proc/reload_fullscreen() - if(client) - var/atom/movable/screen/fullscreen/screen - for(var/category in screens) - screen = screens[category] - if(screen.should_show_to(src)) - screen.update_for_view(client.view) - client.screen |= screen - else - client.screen -= screen - -/atom/movable/screen/fullscreen - icon = 'icons/mob/screen_full.dmi' - icon_state = "default" - screen_loc = "CENTER-7,CENTER-7" - layer = FULLSCREEN_LAYER - plane = FULLSCREEN_PLANE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - var/view = 7 - var/severity = 0 - var/show_when_dead = FALSE - -/atom/movable/screen/fullscreen/proc/update_for_view(client_view) - if (screen_loc == "CENTER-7,CENTER-7" && view != client_view) - var/list/actualview = getviewsize(client_view) - view = client_view - transform = matrix(actualview[1]/FULLSCREEN_OVERLAY_RESOLUTION_X, 0, 0, 0, actualview[2]/FULLSCREEN_OVERLAY_RESOLUTION_Y, 0) - -/atom/movable/screen/fullscreen/proc/should_show_to(mob/mymob) - if(!show_when_dead && mymob.stat == DEAD) - return FALSE - return TRUE - -/atom/movable/screen/fullscreen/Destroy() - severity = 0 - . = ..() - -/atom/movable/screen/fullscreen/brute - icon_state = "brutedamageoverlay" - layer = UI_DAMAGE_LAYER - plane = FULLSCREEN_PLANE - -/atom/movable/screen/fullscreen/oxy - icon_state = "oxydamageoverlay" - layer = UI_DAMAGE_LAYER - plane = FULLSCREEN_PLANE - -/atom/movable/screen/fullscreen/crit - icon_state = "passage" - layer = CRIT_LAYER - plane = FULLSCREEN_PLANE - -/atom/movable/screen/fullscreen/crit/vision - icon_state = "oxydamageoverlay" - layer = BLIND_LAYER - -/atom/movable/screen/fullscreen/blind - icon_state = "blackimageoverlay" - layer = BLIND_LAYER - plane = FULLSCREEN_PLANE - -/atom/movable/screen/fullscreen/curse - icon_state = "curse" - layer = CURSE_LAYER - plane = FULLSCREEN_PLANE - -/atom/movable/screen/fullscreen/impaired - icon_state = "impairedoverlay" - -/atom/movable/screen/fullscreen/blurry - icon = 'icons/mob/screen_gen.dmi' - screen_loc = "WEST,SOUTH to EAST,NORTH" - icon_state = "blurry" - -/atom/movable/screen/fullscreen/flash - icon = 'icons/mob/screen_gen.dmi' - screen_loc = "WEST,SOUTH to EAST,NORTH" - icon_state = "flash" - -/atom/movable/screen/fullscreen/flash/static - icon = 'icons/mob/screen_gen.dmi' - screen_loc = "WEST,SOUTH to EAST,NORTH" - icon_state = "noise" - -/atom/movable/screen/fullscreen/high - icon = 'icons/mob/screen_gen.dmi' - screen_loc = "WEST,SOUTH to EAST,NORTH" - icon_state = "druggy" - -/atom/movable/screen/fullscreen/color_vision - icon = 'icons/mob/screen_gen.dmi' - screen_loc = "WEST,SOUTH to EAST,NORTH" - icon_state = "flash" - alpha = 80 - -/atom/movable/screen/fullscreen/color_vision/green - color = "#00ff00" - -/atom/movable/screen/fullscreen/color_vision/red - color = "#ff0000" - -/atom/movable/screen/fullscreen/color_vision/blue - color = "#0000ff" - -/atom/movable/screen/fullscreen/cinematic_backdrop - icon = 'icons/mob/screen_gen.dmi' - screen_loc = "WEST,SOUTH to EAST,NORTH" - icon_state = "flash" - plane = SPLASHSCREEN_PLANE - layer = SPLASHSCREEN_LAYER - 1 - color = "#000000" - show_when_dead = TRUE - -/atom/movable/screen/fullscreen/lighting_backdrop - icon = 'icons/mob/screen_gen.dmi' - icon_state = "flash" - transform = matrix(200, 0, 0, 0, 200, 0) - plane = LIGHTING_PLANE - blend_mode = BLEND_OVERLAY - show_when_dead = TRUE - -//Provides darkness to the back of the lighting plane -/atom/movable/screen/fullscreen/lighting_backdrop/lit - invisibility = INVISIBILITY_LIGHTING - layer = BACKGROUND_LAYER+21 - color = "#000" - show_when_dead = TRUE - -//Provides whiteness in case you don't see lights so everything is still visible -/atom/movable/screen/fullscreen/lighting_backdrop/unlit - layer = BACKGROUND_LAYER+20 - show_when_dead = TRUE - -/atom/movable/screen/fullscreen/see_through_darkness - icon_state = "nightvision" - plane = LIGHTING_PLANE - layer = LIGHTING_LAYER - blend_mode = BLEND_ADD - show_when_dead = TRUE diff --git a/code/_onclick/hud/generic_dextrous.dm b/code/_onclick/hud/generic_dextrous.dm index 88407bb04c..1762bee1fc 100644 --- a/code/_onclick/hud/generic_dextrous.dm +++ b/code/_onclick/hud/generic_dextrous.dm @@ -60,7 +60,7 @@ for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) inv.hud = src - inv_slots[inv.slot_id] = inv + inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv inv.update_icon() /datum/hud/dextrous/persistent_inventory_update() diff --git a/code/_onclick/hud/ghost.dm b/code/_onclick/hud/ghost.dm index b9514bff46..bb637ed445 100644 --- a/code/_onclick/hud/ghost.dm +++ b/code/_onclick/hud/ghost.dm @@ -93,3 +93,10 @@ screenmob.client.screen -= static_inventory else screenmob.client.screen += static_inventory + +//We should only see observed mob alerts. +/datum/hud/ghost/reorganize_alerts(mob/viewmob) + var/mob/dead/observer/O = mymob + if (istype(O) && O.observetarget) + return + . = ..() diff --git a/code/_onclick/hud/guardian.dm b/code/_onclick/hud/guardian.dm index 7f360b48dc..2af02d8437 100644 --- a/code/_onclick/hud/guardian.dm +++ b/code/_onclick/hud/guardian.dm @@ -43,7 +43,7 @@ inv_box.icon = ui_style inv_box.icon_state = "suit_storage" inv_box.screen_loc = ui_id - inv_box.slot_id = SLOT_GENERC_DEXTROUS_STORAGE + inv_box.slot_id = ITEM_SLOT_DEX_STORAGE static_inventory += inv_box using = new /atom/movable/screen/guardian/Communicate() diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 36a3cd1f1a..9d762332c6 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -33,8 +33,12 @@ GLOBAL_LIST_INIT(available_ui_styles, list( var/atom/movable/screen/alien_plasma_display var/atom/movable/screen/alien_queen_finder + var/atom/movable/screen/combo/combo_display + var/atom/movable/screen/devil/soul_counter/devilsouldisplay + var/atom/movable/screen/synth/coolant_counter/coolant_display + var/atom/movable/screen/action_intent var/atom/movable/screen/zone_select var/atom/movable/screen/pull_icon @@ -51,6 +55,24 @@ GLOBAL_LIST_INIT(available_ui_styles, list( var/list/hand_slots // /atom/movable/screen/inventory/hand objects, assoc list of "[held_index]" = object var/list/atom/movable/screen/plane_master/plane_masters = list() // see "appearance_flags" in the ref, assoc list of "[plane]" = object + + ///UI for screentips that appear when you mouse over things + var/atom/movable/screen/screentip/screentip_text + + /// Whether or not screentips are enabled. + /// This is updated by the preference for cheaper reads than would be + /// had with a proc call, especially on one of the hottest procs in the + /// game (MouseEntered). + // var/screentips_enabled = SCREENTIP_PREFERENCE_ENABLED + + /// The color to use for the screentips. + /// This is updated by the preference for cheaper reads than would be + /// had with a proc call, especially on one of the hottest procs in the + /// game (MouseEntered). + // var/screentip_color + + // We don't actually do proccalls really yet, so let's grab at prefs + var/atom/movable/screen/movable/action_button/hide_toggle/hide_actions_toggle var/action_buttons_hidden = FALSE @@ -58,6 +80,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( var/atom/movable/screen/healthdoll var/atom/movable/screen/internals + var/atom/movable/screen/wanted/wanted_lvl // subtypes can override this to force a specific UI style var/ui_style @@ -80,6 +103,9 @@ GLOBAL_LIST_INIT(available_ui_styles, list( plane_masters["[instance.plane]"] = instance instance.backdrop(mymob) + screentip_text = new(null, src) + static_inventory += screentip_text + /datum/hud/Destroy() if(mymob.hud_used == src) mymob.hud_used = null @@ -100,6 +126,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( healths = null healthdoll = null + wanted_lvl = null internals = null lingchemdisplay = null devilsouldisplay = null @@ -107,11 +134,14 @@ GLOBAL_LIST_INIT(available_ui_styles, list( blobpwrdisplay = null alien_plasma_display = null alien_queen_finder = null + combo_display = null QDEL_LIST_ASSOC_VAL(plane_masters) QDEL_LIST(screenoverlays) mymob = null + QDEL_NULL(screentip_text) + return ..() @@ -131,7 +161,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( return FALSE screenmob.client.screen = list() - screenmob.client.apply_clickcatcher() + screenmob.client.update_clickcatcher() var/display_hud_version = version if(!display_hud_version) //If 0 or blank, display the next hud version @@ -191,8 +221,6 @@ GLOBAL_LIST_INIT(available_ui_styles, list( persistent_inventory_update(screenmob) screenmob.update_action_buttons(1) reorganize_alerts() - screenmob.reload_fullscreen() - update_parallax_pref(screenmob) // ensure observers get an accurate and up-to-date view if (!viewmob) @@ -202,6 +230,8 @@ GLOBAL_LIST_INIT(available_ui_styles, list( else if (viewmob.hud_used) viewmob.hud_used.plane_masters_update() + screenmob.reload_rendering() + return TRUE /datum/hud/proc/plane_masters_update() diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index e4a9dc24e8..9547ee6f86 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -80,9 +80,101 @@ icon_state = "power_display" screen_loc = ui_lingchemdisplay +#define ui_coolant_display "EAST,SOUTH+3:15" + +/atom/movable/screen/synth + invisibility = INVISIBILITY_ABSTRACT + + +/atom/movable/screen/synth/proc/clear() + invisibility = INVISIBILITY_ABSTRACT + +/atom/movable/screen/synth/proc/update_counter(mob/living/carbon/human/owner) + invisibility = 0 + +/atom/movable/screen/synth/coolant_counter + icon = 'icons/mob/screen_synth.dmi' + name = "Coolant System Readout" + icon_state = "coolant-3-1" + screen_loc = ui_coolant_display + var/jammed = 0 + +/atom/movable/screen/synth/coolant_counter/update_counter(mob/living/carbon/owner) + ..() + var/valuecolor = "#ff2525" + if(owner.stat == DEAD) + maptext = "
ERR-0F
" + icon_state = "coolant-3-1" + return + var/coolant_efficiency + var/coolant + if(!jammed) + coolant_efficiency = owner.get_cooling_efficiency() + coolant = owner.blood_volume + else + coolant_efficiency = rand(1, 15) / 10 + coolant = rand(1, 600) + jammed-- + if(coolant > BLOOD_VOLUME_SAFE * owner.blood_ratio) //I unfortunately have to use this else-if stack because switch doesn't support variables. + valuecolor = "#4bbd34" + else if(coolant > BLOOD_VOLUME_OKAY * owner.blood_ratio) + valuecolor = "#dabb0d" + else if(coolant > BLOOD_VOLUME_BAD * owner.blood_ratio) + valuecolor = "#dd8109" + else if(coolant > BLOOD_VOLUME_SURVIVE * owner.blood_ratio) + valuecolor = "#e7520d" + maptext = "
[round((coolant / (BLOOD_VOLUME_NORMAL * owner.blood_ratio)) * 100, 1)]
" + + var/efficiency_suffix + var/state_suffix + switch(coolant_efficiency) + if(-INFINITY to 0.4) + efficiency_suffix = "1" + if(0.4 to 0.75) + efficiency_suffix = "2" + if(0.75 to 0.95) + efficiency_suffix = "3" + if(0.95 to 1.3) + efficiency_suffix = "4" + else + efficiency_suffix = "5" + var/obj/item/organ/lungs/ipc/L = owner.getorganslot(ORGAN_SLOT_LUNGS) + if(istype(L) && L.is_cooling) + state_suffix = "2" + else + state_suffix = "1" + icon_state = "coolant-[efficiency_suffix]-[state_suffix]" + +/atom/movable/screen/synth/coolant_counter/examine(mob/user) + . = ..() + var/mob/living/carbon/human/owner = hud.mymob + if(owner.stat == DEAD) + return + var/coolant + var/total_efficiency + var/environ_efficiency + var/suitlink_efficiency + if(!jammed) + coolant = owner.blood_volume + total_efficiency = owner.get_cooling_efficiency() + environ_efficiency = owner.get_environment_cooling_efficiency() + suitlink_efficiency = owner.check_suitlinking() + else + coolant = rand(1, 600) + total_efficiency = rand(1, 15) / 10 + environ_efficiency = rand(1, 20) / 10 + . += "Performing internal cooling system diagnostics:" + . += "Coolant level: [coolant] units, [round((coolant / (BLOOD_VOLUME_NORMAL * owner.blood_ratio)) * 100, 0.1)] percent" + . += "Current Cooling Efficiency: [round(total_efficiency * 100, 0.1)] percent, [suitlink_efficiency ? "active suitlink detected, guaranteeing [suitlink_efficiency * 100]% environmental cooling efficiency." : "environment viability: [round(environ_efficiency * 100, 0.1)] percent."]" + +/atom/movable/screen/synth/coolant_counter/proc/jam(amount, cap = 20) + if(jammed > cap) //Preserve previous more impactful event. + return + jammed = min(jammed + amount, cap) + /datum/hud/human/New(mob/living/carbon/human/owner) ..() - owner.overlay_fullscreen("see_through_darkness", /atom/movable/screen/fullscreen/see_through_darkness) + owner.overlay_fullscreen("see_through_darkness", /atom/movable/screen/fullscreen/special/see_through_darkness) var/widescreenlayout = FALSE //CIT CHANGE - adds support for different hud layouts depending on widescreen pref if(owner.client && owner.client.prefs && owner.client.prefs.widescreenpref) //CIT CHANGE - ditto @@ -141,7 +233,7 @@ inv_box = new /atom/movable/screen/inventory() inv_box.name = "i_clothing" inv_box.icon = ui_style - inv_box.slot_id = SLOT_W_UNIFORM + inv_box.slot_id = ITEM_SLOT_ICLOTHING inv_box.icon_state = "uniform" inv_box.screen_loc = ui_iclothing toggleable_inventory += inv_box @@ -149,7 +241,7 @@ inv_box = new /atom/movable/screen/inventory() inv_box.name = "o_clothing" inv_box.icon = ui_style - inv_box.slot_id = SLOT_WEAR_SUIT + inv_box.slot_id = ITEM_SLOT_OCLOTHING inv_box.icon_state = "suit" inv_box.screen_loc = ui_oclothing toggleable_inventory += inv_box @@ -175,7 +267,7 @@ inv_box.icon = ui_style inv_box.icon_state = "id" inv_box.screen_loc = ui_id - inv_box.slot_id = SLOT_WEAR_ID + inv_box.slot_id = ITEM_SLOT_ID static_inventory += inv_box inv_box = new /atom/movable/screen/inventory() @@ -183,7 +275,7 @@ inv_box.icon = ui_style inv_box.icon_state = "mask" inv_box.screen_loc = ui_mask - inv_box.slot_id = SLOT_WEAR_MASK + inv_box.slot_id = ITEM_SLOT_MASK toggleable_inventory += inv_box inv_box = new /atom/movable/screen/inventory() @@ -191,7 +283,7 @@ inv_box.icon = ui_style inv_box.icon_state = "neck" inv_box.screen_loc = ui_neck - inv_box.slot_id = SLOT_NECK + inv_box.slot_id = ITEM_SLOT_NECK toggleable_inventory += inv_box inv_box = new /atom/movable/screen/inventory() @@ -199,7 +291,7 @@ inv_box.icon = ui_style inv_box.icon_state = "back" inv_box.screen_loc = ui_back - inv_box.slot_id = SLOT_BACK + inv_box.slot_id = ITEM_SLOT_BACK static_inventory += inv_box inv_box = new /atom/movable/screen/inventory() @@ -207,7 +299,7 @@ inv_box.icon = ui_style inv_box.icon_state = "pocket" inv_box.screen_loc = ui_storage1 - inv_box.slot_id = SLOT_L_STORE + inv_box.slot_id = ITEM_SLOT_LPOCKET static_inventory += inv_box inv_box = new /atom/movable/screen/inventory() @@ -215,7 +307,7 @@ inv_box.icon = ui_style inv_box.icon_state = "pocket" inv_box.screen_loc = ui_storage2 - inv_box.slot_id = SLOT_R_STORE + inv_box.slot_id = ITEM_SLOT_RPOCKET static_inventory += inv_box inv_box = new /atom/movable/screen/inventory() @@ -223,7 +315,7 @@ inv_box.icon = ui_style inv_box.icon_state = "suit_storage" inv_box.screen_loc = ui_sstore1 - inv_box.slot_id = SLOT_S_STORE + inv_box.slot_id = ITEM_SLOT_SUITSTORE static_inventory += inv_box using = new /atom/movable/screen/resist() @@ -256,7 +348,7 @@ inv_box.icon = ui_style inv_box.icon_state = "gloves" inv_box.screen_loc = ui_gloves - inv_box.slot_id = SLOT_GLOVES + inv_box.slot_id = ITEM_SLOT_GLOVES toggleable_inventory += inv_box inv_box = new /atom/movable/screen/inventory() @@ -264,7 +356,7 @@ inv_box.icon = ui_style inv_box.icon_state = "glasses" inv_box.screen_loc = ui_glasses - inv_box.slot_id = SLOT_GLASSES + inv_box.slot_id = ITEM_SLOT_EYES toggleable_inventory += inv_box inv_box = new /atom/movable/screen/inventory() @@ -272,7 +364,7 @@ inv_box.icon = ui_style inv_box.icon_state = "ears" inv_box.screen_loc = ui_ears - inv_box.slot_id = SLOT_EARS + inv_box.slot_id = ITEM_SLOT_EARS toggleable_inventory += inv_box inv_box = new /atom/movable/screen/inventory() @@ -280,7 +372,7 @@ inv_box.icon = ui_style inv_box.icon_state = "head" inv_box.screen_loc = ui_head - inv_box.slot_id = SLOT_HEAD + inv_box.slot_id = ITEM_SLOT_HEAD toggleable_inventory += inv_box inv_box = new /atom/movable/screen/inventory() @@ -288,7 +380,7 @@ inv_box.icon = ui_style inv_box.icon_state = "shoes" inv_box.screen_loc = ui_shoes - inv_box.slot_id = SLOT_SHOES + inv_box.slot_id = ITEM_SLOT_FEET toggleable_inventory += inv_box inv_box = new /atom/movable/screen/inventory() @@ -297,7 +389,7 @@ inv_box.icon_state = "belt" // inv_box.icon_full = "template_small" inv_box.screen_loc = ui_belt - inv_box.slot_id = SLOT_BELT + inv_box.slot_id = ITEM_SLOT_BELT static_inventory += inv_box throw_icon = new /atom/movable/screen/throw_catch() @@ -359,16 +451,23 @@ sunlight_display.hud = src infodisplay += sunlight_display + coolant_display = new /atom/movable/screen/synth/coolant_counter //Coolant & cooling efficiency readouts for Synths. + coolant_display.hud = src + infodisplay += coolant_display + zone_select = new /atom/movable/screen/zone_sel() zone_select.icon = ui_style zone_select.hud = src zone_select.update_icon() static_inventory += zone_select + combo_display = new /atom/movable/screen/combo() + infodisplay += combo_display + for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) inv.hud = src - inv_slots[inv.slot_id] = inv + inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv inv.update_icon() update_locked_slots() diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm index 376db7bf96..b63f8241cb 100644 --- a/code/_onclick/hud/monkey.dm +++ b/code/_onclick/hud/monkey.dm @@ -50,7 +50,7 @@ inv_box.icon_state = "mask" // inv_box.icon_full = "template" inv_box.screen_loc = ui_monkey_mask - inv_box.slot_id = SLOT_WEAR_MASK + inv_box.slot_id = ITEM_SLOT_MASK static_inventory += inv_box inv_box = new /atom/movable/screen/inventory() @@ -59,7 +59,7 @@ inv_box.icon_state = "neck" // inv_box.icon_full = "template" inv_box.screen_loc = ui_monkey_neck - inv_box.slot_id = SLOT_NECK + inv_box.slot_id = ITEM_SLOT_NECK static_inventory += inv_box inv_box = new /atom/movable/screen/inventory() @@ -68,7 +68,7 @@ inv_box.icon_state = "head" // inv_box.icon_full = "template" inv_box.screen_loc = ui_monkey_head - inv_box.slot_id = SLOT_HEAD + inv_box.slot_id = ITEM_SLOT_HEAD static_inventory += inv_box inv_box = new /atom/movable/screen/inventory() @@ -76,7 +76,7 @@ inv_box.icon = ui_style inv_box.icon_state = "back" inv_box.screen_loc = ui_monkey_back - inv_box.slot_id = SLOT_BACK + inv_box.slot_id = ITEM_SLOT_BACK static_inventory += inv_box throw_icon = new /atom/movable/screen/throw_catch() @@ -126,7 +126,7 @@ for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) inv.hud = src - inv_slots[inv.slot_id] = inv + inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv inv.update_icon() /datum/hud/monkey/persistent_inventory_update() diff --git a/code/_onclick/hud/new_player.dm b/code/_onclick/hud/new_player.dm new file mode 100644 index 0000000000..b01199c6c2 --- /dev/null +++ b/code/_onclick/hud/new_player.dm @@ -0,0 +1,446 @@ +#define SHUTTER_MOVEMENT_DURATION 0.4 SECONDS +#define SHUTTER_WAIT_DURATION 0.2 SECONDS + +/datum/hud/new_player + ///Whether the menu is currently on the client's screen or not + var/menu_hud_status = TRUE + +/datum/hud/new_player/proc/populate_buttons(mob/dead/new_player/owner) + var/list/buttons = subtypesof(/atom/movable/screen/lobby) + for(var/button_type in buttons) + var/atom/movable/screen/lobby/lobbyscreen = new button_type(our_hud = src) + lobbyscreen.SlowInit() + lobbyscreen.hud = src + static_inventory += lobbyscreen + if(!lobbyscreen.always_shown) + lobbyscreen.RegisterSignal(src, COMSIG_HUD_LOBBY_COLLAPSED, TYPE_PROC_REF(/atom/movable/screen/lobby, collapse_button)) + lobbyscreen.RegisterSignal(src, COMSIG_HUD_LOBBY_EXPANDED, TYPE_PROC_REF(/atom/movable/screen/lobby, expand_button)) + if(istype(lobbyscreen, /atom/movable/screen/lobby/button)) + var/atom/movable/screen/lobby/button/lobby_button = lobbyscreen + lobby_button.owner = REF(owner) + show_hud(hud_version) + +/atom/movable/screen/lobby + plane = SPLASHSCREEN_PLANE + layer = LOBBY_MENU_LAYER + screen_loc = "TOP,CENTER" + ///Whether this HUD element can be hidden from the client's "screen" (moved off-screen) or not + var/always_shown = FALSE + +/atom/movable/screen/lobby/New(loc, datum/hud/our_hud, ...) + if(our_hud) + hud = our_hud + return ..() + +/// Run sleeping actions after initialize +/atom/movable/screen/lobby/proc/SlowInit() + return + +///Animates moving the button off-screen +/atom/movable/screen/lobby/proc/collapse_button() + SIGNAL_HANDLER + //wait for the shutter to come down + animate(src, transform = transform, time = SHUTTER_MOVEMENT_DURATION + SHUTTER_WAIT_DURATION) + //then pull the buttons up with the shutter + animate(transform = transform.Translate(x = 0, y = 146), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN) + +///Animates moving the button back into place +/atom/movable/screen/lobby/proc/expand_button() + SIGNAL_HANDLER + //the buttons are off-screen, so we sync them up to come down with the shutter + animate(src, transform = matrix(), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_OUT) + +/atom/movable/screen/lobby/background + icon = 'icons/hud/lobby/background.dmi' + icon_state = "background" + screen_loc = "TOP,CENTER:-61" + +/atom/movable/screen/lobby/button + ///Is the button currently enabled? + var/enabled = TRUE + ///Is the button currently being hovered over with the mouse? + var/highlighted = FALSE + /// The ref of the mob that owns this button. Only the owner can click on it. + var/owner + +/atom/movable/screen/lobby/button/Click(location, control, params) + if(owner != REF(usr)) + return + + . = ..() + + if(!enabled) + return + flick("[base_icon_state]_pressed", src) + update_appearance(UPDATE_ICON) + return TRUE + +/atom/movable/screen/lobby/button/MouseEntered(location,control,params) + if(owner != REF(usr)) + return + + . = ..() + highlighted = TRUE + update_appearance(UPDATE_ICON) + +/atom/movable/screen/lobby/button/MouseExited() + if(owner != REF(usr)) + return + + . = ..() + highlighted = FALSE + update_appearance(UPDATE_ICON) + +/atom/movable/screen/lobby/button/update_icon(updates) + . = ..() + if(!enabled) + icon_state = "[base_icon_state]_disabled" + return + else if(highlighted) + icon_state = "[base_icon_state]_highlighted" + return + icon_state = base_icon_state + +///Updates the button's status: TRUE to enable interaction with the button, FALSE to disable +/atom/movable/screen/lobby/button/proc/set_button_status(status) + if(status == enabled) + return FALSE + enabled = status + update_appearance(UPDATE_ICON) + return TRUE + +///Prefs menu +/atom/movable/screen/lobby/button/character_setup + name = "View Character Setup" + screen_loc = "TOP:-70,CENTER:-54" + icon = 'icons/hud/lobby/character_setup.dmi' + icon_state = "character_setup" + base_icon_state = "character_setup" + +/atom/movable/screen/lobby/button/character_setup/Click(location, control, params) + . = ..() + if(!.) + return + hud.mymob.client.prefs.current_tab = SETTINGS_TAB + hud.mymob.client.prefs.ShowChoices(hud.mymob) + +///Button that appears before the game has started +/atom/movable/screen/lobby/button/ready + name = "Toggle Readiness" + screen_loc = "TOP:-8,CENTER:-65" + icon = 'icons/hud/lobby/ready.dmi' + icon_state = "not_ready" + base_icon_state = "not_ready" + ///Whether we are readied up for the round or not + var/ready = FALSE + +/atom/movable/screen/lobby/button/ready/Initialize(mapload) + . = ..() + switch(SSticker.current_state) + if(GAME_STATE_PREGAME, GAME_STATE_STARTUP) + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, .proc/hide_ready_button) + if(GAME_STATE_SETTING_UP) + set_button_status(FALSE) + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, .proc/show_ready_button) + else + set_button_status(FALSE) + +/atom/movable/screen/lobby/button/ready/proc/hide_ready_button() + SIGNAL_HANDLER + set_button_status(FALSE) + UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, .proc/show_ready_button) + +/atom/movable/screen/lobby/button/ready/proc/show_ready_button() + SIGNAL_HANDLER + set_button_status(TRUE) + UnregisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, .proc/hide_ready_button) + +/atom/movable/screen/lobby/button/ready/Click(location, control, params) + . = ..() + if(!.) + return + var/mob/dead/new_player/new_player = hud.mymob + ready = !ready + if(ready) + new_player.ready = PLAYER_READY_TO_PLAY + base_icon_state = "ready" + else + new_player.ready = PLAYER_NOT_READY + base_icon_state = "not_ready" + update_appearance(UPDATE_ICON) + +///Shown when the game has started +/atom/movable/screen/lobby/button/join + name = "Join Game" + screen_loc = "TOP:-13,CENTER:-58" + icon = 'icons/hud/lobby/join.dmi' + icon_state = "" //Default to not visible + base_icon_state = "join_game" + enabled = FALSE + +/atom/movable/screen/lobby/button/join/Initialize(mapload) + . = ..() + switch(SSticker.current_state) + if(GAME_STATE_PREGAME, GAME_STATE_STARTUP) + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, .proc/show_join_button) + if(GAME_STATE_SETTING_UP) + set_button_status(TRUE) + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, .proc/hide_join_button) + else + set_button_status(TRUE) + +/atom/movable/screen/lobby/button/join/Click(location, control, params) + . = ..() + if(!.) + return + if(!SSticker?.IsRoundInProgress()) + to_chat(hud.mymob, span_boldwarning("The round is either not ready, or has already finished...")) + return + + //Determines Relevent Population Cap + var/relevant_cap + var/hpc = CONFIG_GET(number/hard_popcap) + var/epc = CONFIG_GET(number/extreme_popcap) + if(hpc && epc) + relevant_cap = min(hpc, epc) + else + relevant_cap = max(hpc, epc) + + var/mob/dead/new_player/new_player = hud.mymob + + if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(new_player.key) in GLOB.admin_datums))) + to_chat(new_player, span_danger("[CONFIG_GET(string/hard_popcap_message)]")) + + var/queue_position = SSticker.queued_players.Find(new_player) + if(queue_position == 1) + to_chat(new_player, span_notice("You are next in line to join the game. You will be notified when a slot opens up.")) + else if(queue_position) + to_chat(new_player, span_notice("There are [queue_position-1] players in front of you in the queue to join the game.")) + else + SSticker.queued_players += new_player + to_chat(new_player, span_notice("You have been added to the queue to join the game. Your position in queue is [SSticker.queued_players.len].")) + return + new_player.LateChoices() + +/atom/movable/screen/lobby/button/join/proc/show_join_button() + SIGNAL_HANDLER + set_button_status(TRUE) + UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, .proc/hide_join_button) + +/atom/movable/screen/lobby/button/join/proc/hide_join_button() + SIGNAL_HANDLER + set_button_status(FALSE) + UnregisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, .proc/show_join_button) + +/atom/movable/screen/lobby/button/observe + name = "Observe" + screen_loc = "TOP:-40,CENTER:-54" + icon = 'icons/hud/lobby/observe.dmi' + icon_state = "observe_disabled" + base_icon_state = "observe" + enabled = FALSE + +/atom/movable/screen/lobby/button/observe/Initialize(mapload) + . = ..() + if(SSticker.current_state > GAME_STATE_STARTUP) + set_button_status(TRUE) + else + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME, .proc/enable_observing) + +/atom/movable/screen/lobby/button/observe/Click(location, control, params) + . = ..() + if(!.) + return + var/mob/dead/new_player/new_player = hud.mymob + new_player.make_me_an_observer() + +/atom/movable/screen/lobby/button/observe/proc/enable_observing() + SIGNAL_HANDLER + flick("[base_icon_state]_enabled", src) + set_button_status(TRUE) + UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME, .proc/enable_observing) + +//Subtype the bottom buttons away so the collapse/expand shutter goes behind them +/atom/movable/screen/lobby/button/bottom + layer = LOBBY_BOTTOM_BUTTON_LAYER + icon = 'icons/hud/lobby/bottom_buttons.dmi' + +/atom/movable/screen/lobby/button/bottom/settings + name = "View Game Preferences" + icon_state = "settings" + base_icon_state = "settings" + screen_loc = "TOP:-122,CENTER:+29" + +/atom/movable/screen/lobby/button/bottom/settings/Click(location, control, params) + . = ..() + if(!.) + return + + hud.mymob.client.prefs.current_tab = PREFERENCES_TAB + hud.mymob.client.prefs.ShowChoices(hud.mymob) + +/atom/movable/screen/lobby/button/bottom/changelog_button + name = "View Changelog" + icon_state = "changelog" + base_icon_state = "changelog" + screen_loc ="TOP:-122,CENTER:+57" + +/atom/movable/screen/lobby/button/bottom/changelog_button/Click(location, control, params) + . = ..() + usr.client?.changelog() + +/atom/movable/screen/lobby/button/bottom/crew_manifest + name = "View Crew Manifest" + icon_state = "crew_manifest" + base_icon_state = "crew_manifest" + screen_loc = "TOP:-122,CENTER:+2" + +/atom/movable/screen/lobby/button/bottom/crew_manifest/Click(location, control, params) + . = ..() + if(!.) + return + var/mob/dead/new_player/new_player = hud.mymob + new_player.ViewManifest() + +/atom/movable/screen/lobby/button/bottom/poll + name = "View Available Polls" + icon_state = "poll" + base_icon_state = "poll" + screen_loc = "TOP:-122,CENTER:-26" + ///Whether the button should have a New Poll notification overlay + var/new_poll = FALSE + +/atom/movable/screen/lobby/button/bottom/poll/SlowInit(mapload) + . = ..() + if(!usr) + return + var/mob/dead/new_player/new_player = usr + if(is_guest_key(new_player.key)) + set_button_status(FALSE) + return + if(!SSdbcore.Connect()) + set_button_status(FALSE) + return + var/isadmin = FALSE + if(new_player.client?.holder) + isadmin = TRUE + var/datum/db_query/query_get_new_polls = SSdbcore.NewQuery({" + SELECT id FROM [format_table_name("poll_question")] + WHERE (adminonly = 0 OR :isadmin = 1) + AND Now() BETWEEN starttime AND endtime + AND deleted = 0 + AND id NOT IN ( + SELECT pollid FROM [format_table_name("poll_vote")] + WHERE ckey = :ckey + AND deleted = 0 + ) + AND id NOT IN ( + SELECT pollid FROM [format_table_name("poll_textreply")] + WHERE ckey = :ckey + AND deleted = 0 + ) + "}, list("isadmin" = isadmin, "ckey" = new_player.ckey)) + if(!query_get_new_polls.Execute()) + qdel(query_get_new_polls) + set_button_status(FALSE) + return + if(query_get_new_polls.NextRow()) + new_poll = TRUE + else + new_poll = FALSE + update_appearance(UPDATE_OVERLAYS) + qdel(query_get_new_polls) + if(QDELETED(new_player)) + set_button_status(FALSE) + return + +/atom/movable/screen/lobby/button/bottom/poll/update_overlays() + . = ..() + if(new_poll) + . += mutable_appearance('icons/hud/lobby/poll_overlay.dmi', "new_poll") + +/atom/movable/screen/lobby/button/bottom/poll/Click(location, control, params) + . = ..() + if(!.) + return + var/mob/dead/new_player/new_player = hud.mymob + new_player.handle_player_polling() + +/atom/movable/screen/lobby/button/collapse + name = "Collapse Lobby Menu" + icon = 'icons/hud/lobby/collapse_expand.dmi' + icon_state = "collapse" + base_icon_state = "collapse" + layer = LOBBY_BELOW_MENU_LAYER + screen_loc = "TOP:-82,CENTER:-54" + always_shown = TRUE + +/atom/movable/screen/lobby/button/collapse/Click(location, control, params) + . = ..() + if(!.) + return + + if(!istype(hud, /datum/hud/new_player)) + return + var/datum/hud/new_player/our_hud = hud + base_icon_state = our_hud.menu_hud_status ? "expand" : "collapse" + name = "[our_hud.menu_hud_status ? "Expand" : "Collapse"] Lobby Menu" + set_button_status(FALSE) + + //get the shutter object used by our hud + var/atom/movable/screen/lobby/shutter/menu_shutter = locate(/atom/movable/screen/lobby/shutter) in hud.static_inventory + + //animate the shutter + menu_shutter.setup_shutter_animation() + //animate bottom buttons' movement + if(our_hud.menu_hud_status) + collapse_menu() + else + expand_menu() + our_hud.menu_hud_status = !our_hud.menu_hud_status + + //re-enable clicking the button when the shutter animation finishes + //we use sleep here so it can work during game setup, as addtimer would not work until the game would finish setting up + sleep(2 * SHUTTER_MOVEMENT_DURATION + SHUTTER_WAIT_DURATION) + set_button_status(TRUE) + +///Moves the button to the top of the screen, leaving only the screen part in view +///Sends a signal on the hud for the menu hud elements to listen to +/atom/movable/screen/lobby/button/collapse/proc/collapse_menu() + SEND_SIGNAL(hud, COMSIG_HUD_LOBBY_COLLAPSED) + //wait for the shutter to come down + animate(src, transform = transform, time = SHUTTER_MOVEMENT_DURATION + SHUTTER_WAIT_DURATION) + //then pull the button up with the shutter and leave it on the edge of the screen + animate(transform = transform.Translate(x = 0, y = 134), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN) + +///Extends the button back to its usual spot +///Sends a signal on the hud for the menu hud elements to listen to +/atom/movable/screen/lobby/button/collapse/proc/expand_menu() + SEND_SIGNAL(hud, COMSIG_HUD_LOBBY_EXPANDED) + animate(src, transform = matrix(), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_OUT) + +/atom/movable/screen/lobby/shutter + icon = 'icons/hud/lobby/shutter.dmi' + icon_state = "shutter" + base_icon_state = "shutter" + screen_loc = "TOP:+143,CENTER:-73" //"home" position is off-screen + layer = LOBBY_SHUTTER_LAYER + always_shown = TRUE + +///Sets up the shutter pulling down and up. It's the same animation for both collapsing and expanding the menu. +/atom/movable/screen/lobby/shutter/proc/setup_shutter_animation() + //bring down the shutter + animate(src, transform = transform.Translate(x = 0, y = -143), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_OUT) + + //wait a little bit before bringing the shutter up + animate(transform = transform, time = SHUTTER_WAIT_DURATION) + + //pull the shutter back off-screen + animate(transform = matrix(), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN) + +#undef SHUTTER_MOVEMENT_DURATION +#undef SHUTTER_WAIT_DURATION diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm deleted file mode 100755 index a98fec03c4..0000000000 --- a/code/_onclick/hud/parallax.dm +++ /dev/null @@ -1,322 +0,0 @@ - -/datum/hud/proc/create_parallax(mob/viewmob) - var/mob/screenmob = viewmob || mymob - var/client/C = screenmob.client - if (!apply_parallax_pref(viewmob)) //don't want shit computers to crash when specing someone with insane parallax, so use the viewer's pref - return - - if(!length(C.parallax_layers_cached)) - C.parallax_layers_cached = list() - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, C.view) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_2(null, C.view) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, C.view) - if(SSparallax.random_layer) - C.parallax_layers_cached += new SSparallax.random_layer - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_3(null, C.view) - - C.parallax_layers = C.parallax_layers_cached.Copy() - - if (length(C.parallax_layers) > C.parallax_layers_max) - C.parallax_layers.len = C.parallax_layers_max - - C.screen |= (C.parallax_layers) - var/atom/movable/screen/plane_master/PM = screenmob.hud_used.plane_masters["[PLANE_SPACE]"] - if(screenmob != mymob) - C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen - C.screen += PM - PM.color = list( - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 1, 1, 1, 1, - 0, 0, 0, 0 - ) - - -/datum/hud/proc/remove_parallax(mob/viewmob) - var/mob/screenmob = viewmob || mymob - var/client/C = screenmob.client - C.screen -= (C.parallax_layers_cached) - var/atom/movable/screen/plane_master/PM = screenmob.hud_used.plane_masters["[PLANE_SPACE]"] - if(screenmob != mymob) - C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen - C.screen += PM - PM.color = initial(PM.color) - C.parallax_layers = null - -/datum/hud/proc/apply_parallax_pref(mob/viewmob) - var/mob/screenmob = viewmob || mymob - var/client/C = screenmob.client - if(C.prefs) - var/pref = C.prefs.parallax - if (isnull(pref)) - pref = PARALLAX_HIGH - switch(C.prefs.parallax) - if (PARALLAX_INSANE) - C.parallax_throttle = FALSE - C.parallax_layers_max = 5 - return TRUE - - if (PARALLAX_MED) - C.parallax_throttle = PARALLAX_DELAY_MED - C.parallax_layers_max = 3 - return TRUE - - if (PARALLAX_LOW) - C.parallax_throttle = PARALLAX_DELAY_LOW - C.parallax_layers_max = 1 - return TRUE - - if (PARALLAX_DISABLE) - return FALSE - - //This is high parallax. - C.parallax_throttle = PARALLAX_DELAY_DEFAULT - C.parallax_layers_max = 4 - return TRUE - -/datum/hud/proc/update_parallax_pref(mob/viewmob) - remove_parallax(viewmob) - create_parallax(viewmob) - update_parallax() - -// This sets which way the current shuttle is moving (returns true if the shuttle has stopped moving so the caller can append their animation) -/datum/hud/proc/set_parallax_movedir(new_parallax_movedir, skip_windups) - . = FALSE - var/client/C = mymob.client - if(new_parallax_movedir == C.parallax_movedir) - return - var/animatedir = new_parallax_movedir - if(new_parallax_movedir == FALSE) - var/animate_time = 0 - for(var/thing in C.parallax_layers) - var/atom/movable/screen/parallax_layer/L = thing - L.icon_state = initial(L.icon_state) - L.update_o(C.view) - var/T = PARALLAX_LOOP_TIME / L.speed - if (T > animate_time) - animate_time = T - C.dont_animate_parallax = world.time + min(animate_time, PARALLAX_LOOP_TIME) - animatedir = C.parallax_movedir - - var/matrix/newtransform - switch(animatedir) - if(NORTH) - newtransform = matrix(1, 0, 0, 0, 1, 480) - if(SOUTH) - newtransform = matrix(1, 0, 0, 0, 1,-480) - if(EAST) - newtransform = matrix(1, 0, 480, 0, 1, 0) - if(WEST) - newtransform = matrix(1, 0,-480, 0, 1, 0) - - var/shortesttimer - if(!skip_windups) - for(var/thing in C.parallax_layers) - var/atom/movable/screen/parallax_layer/L = thing - - var/T = PARALLAX_LOOP_TIME / L.speed - if (isnull(shortesttimer)) - shortesttimer = T - if (T < shortesttimer) - shortesttimer = T - L.transform = newtransform - animate(L, transform = matrix(), time = T, easing = QUAD_EASING | (new_parallax_movedir ? EASE_IN : EASE_OUT), flags = ANIMATION_END_NOW) - if (new_parallax_movedir) - L.transform = newtransform - animate(transform = matrix(), time = T) //queue up another animate so lag doesn't create a shutter - - C.parallax_movedir = new_parallax_movedir - if (C.parallax_animate_timer) - deltimer(C.parallax_animate_timer) - var/datum/callback/CB = CALLBACK(src, .proc/update_parallax_motionblur, C, animatedir, new_parallax_movedir, newtransform) - if(skip_windups) - CB.InvokeAsync() - else - C.parallax_animate_timer = addtimer(CB, min(shortesttimer, PARALLAX_LOOP_TIME), TIMER_CLIENT_TIME|TIMER_STOPPABLE) - - -/datum/hud/proc/update_parallax_motionblur(client/C, animatedir, new_parallax_movedir, matrix/newtransform) - if(!C) - return - C.parallax_animate_timer = FALSE - for(var/thing in C.parallax_layers) - var/atom/movable/screen/parallax_layer/L = thing - if (!new_parallax_movedir) - animate(L) - continue - - var/newstate = initial(L.icon_state) - var/T = PARALLAX_LOOP_TIME / L.speed - - if (newstate in icon_states(L.icon)) - L.icon_state = newstate - L.update_o(C.view) - - L.transform = newtransform - - animate(L, transform = matrix(), time = T, loop = -1, flags = ANIMATION_END_NOW) - -/datum/hud/proc/update_parallax() - var/client/C = mymob.client - var/turf/posobj = get_turf(C.eye) - if(!posobj) - return - var/area/areaobj = posobj.loc - - // Update the movement direction of the parallax if necessary (for shuttles) - set_parallax_movedir(areaobj.parallax_movedir, FALSE) - - var/force - if(!C.previous_turf || (C.previous_turf.z != posobj.z)) - C.previous_turf = posobj - force = TRUE - - if (!force && world.time < C.last_parallax_shift+C.parallax_throttle) - return - - //Doing it this way prevents parallax layers from "jumping" when you change Z-Levels. - var/offset_x = posobj.x - C.previous_turf.x - var/offset_y = posobj.y - C.previous_turf.y - - if(!offset_x && !offset_y && !force) - return - - var/last_delay = world.time - C.last_parallax_shift - last_delay = min(last_delay, C.parallax_throttle) - C.previous_turf = posobj - C.last_parallax_shift = world.time - - for(var/thing in C.parallax_layers) - var/atom/movable/screen/parallax_layer/L = thing - L.update_status(mymob) - if (L.view_sized != C.view) - L.update_o(C.view) - - var/change_x - var/change_y - - if(L.absolute) - L.offset_x = -(posobj.x - SSparallax.planet_x_offset) * L.speed - L.offset_y = -(posobj.y - SSparallax.planet_y_offset) * L.speed - else - change_x = offset_x * L.speed - L.offset_x -= change_x - change_y = offset_y * L.speed - L.offset_y -= change_y - - if(L.offset_x > 240) - L.offset_x -= 480 - if(L.offset_x < -240) - L.offset_x += 480 - if(L.offset_y > 240) - L.offset_y -= 480 - if(L.offset_y < -240) - L.offset_y += 480 - - - if(!areaobj.parallax_movedir && C.dont_animate_parallax <= world.time && (offset_x || offset_y) && abs(offset_x) <= max(C.parallax_throttle/world.tick_lag+1,1) && abs(offset_y) <= max(C.parallax_throttle/world.tick_lag+1,1) && (round(abs(change_x)) > 1 || round(abs(change_y)) > 1)) - L.transform = matrix(1, 0, offset_x*L.speed, 0, 1, offset_y*L.speed) - animate(L, transform=matrix(), time = last_delay) - - L.screen_loc = "CENTER-7:[round(L.offset_x,1)],CENTER-7:[round(L.offset_y,1)]" - -/atom/movable/proc/update_parallax_contents() - if(length(client_mobs_in_contents)) - for(var/thing in client_mobs_in_contents) - var/mob/M = thing - if(M?.client && M.hud_used && length(M.client.parallax_layers)) - M.hud_used.update_parallax() - -/mob/proc/update_parallax_teleport() //used for arrivals shuttle - if(client?.eye && hud_used && length(client.parallax_layers)) - var/area/areaobj = get_area(client.eye) - hud_used.set_parallax_movedir(areaobj.parallax_movedir, TRUE) - -/atom/movable/screen/parallax_layer - icon = 'icons/effects/parallax.dmi' - var/speed = 1 - var/offset_x = 0 - var/offset_y = 0 - var/view_sized - var/absolute = FALSE - blend_mode = BLEND_ADD - plane = PLANE_SPACE_PARALLAX - screen_loc = "CENTER-7,CENTER-7" - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - - -/atom/movable/screen/parallax_layer/Initialize(mapload, view) - . = ..() - if (!view) - view = world.view - update_o(view) - -/atom/movable/screen/parallax_layer/proc/update_o(view) - if (!view) - view = world.view - - var/list/viewscales = getviewsize(view) - var/countx = CEILING((viewscales[1]/2)/(480/world.icon_size), 1)+1 - var/county = CEILING((viewscales[2]/2)/(480/world.icon_size), 1)+1 - var/list/new_overlays = new - for(var/x in -countx to countx) - for(var/y in -county to county) - if(x == 0 && y == 0) - continue - var/mutable_appearance/texture_overlay = mutable_appearance(icon, icon_state) - texture_overlay.transform = matrix(1, 0, x*480, 0, 1, y*480) - new_overlays += texture_overlay - cut_overlays() - add_overlay(new_overlays) - view_sized = view - -/atom/movable/screen/parallax_layer/proc/update_status(mob/M) - return - -/atom/movable/screen/parallax_layer/layer_1 - icon_state = "layer1" - speed = 0.6 - layer = 1 - -/atom/movable/screen/parallax_layer/layer_2 - icon_state = "layer2" - speed = 1 - layer = 2 - -/atom/movable/screen/parallax_layer/layer_3 - icon_state = "layer3" - speed = 1.4 - layer = 3 - -/atom/movable/screen/parallax_layer/random - blend_mode = BLEND_OVERLAY - speed = 3 - layer = 3 - -/atom/movable/screen/parallax_layer/random/space_gas - icon_state = "space_gas" - -/atom/movable/screen/parallax_layer/random/space_gas/Initialize(mapload, view) - . = ..() - src.add_atom_colour(SSparallax.random_parallax_color, ADMIN_COLOUR_PRIORITY) - -/atom/movable/screen/parallax_layer/random/asteroids - icon_state = "asteroids" - -/atom/movable/screen/parallax_layer/planet - icon_state = "planet" - blend_mode = BLEND_OVERLAY - absolute = TRUE //Status of seperation - speed = 3 - layer = 30 - -/atom/movable/screen/parallax_layer/planet/update_status(mob/M) - var/client/C = M.client - var/turf/posobj = get_turf(C.eye) - if(!posobj) - return - invisibility = is_station_level(posobj.z) ? 0 : INVISIBILITY_ABSTRACT - -/atom/movable/screen/parallax_layer/planet/update_o() - return //Shit won't move diff --git a/code/_onclick/hud/picture_in_picture.dm b/code/_onclick/hud/picture_in_picture.dm index 6cf1bfd6a6..354a6ed546 100644 --- a/code/_onclick/hud/picture_in_picture.dm +++ b/code/_onclick/hud/picture_in_picture.dm @@ -14,7 +14,7 @@ var/mutable_appearance/standard_background var/const/max_dimensions = 10 -/atom/movable/screen/movable/pic_in_pic/Initialize() +/atom/movable/screen/movable/pic_in_pic/Initialize(mapload) . = ..() make_backgrounds() diff --git a/code/_onclick/hud/plane_master.dm b/code/_onclick/hud/plane_master.dm index bb6a9cd925..3d39440dad 100644 --- a/code/_onclick/hud/plane_master.dm +++ b/code/_onclick/hud/plane_master.dm @@ -24,7 +24,7 @@ blend_mode = BLEND_MULTIPLY alpha = 255 -/atom/movable/screen/plane_master/openspace/Initialize() +/atom/movable/screen/plane_master/openspace/Initialize(mapload) . = ..() filters += filter(type="alpha", render_source=FIELD_OF_VISION_RENDER_TARGET, flags=MASK_INVERSE) @@ -61,7 +61,7 @@ plane = ABOVE_WALL_PLANE appearance_flags = PLANE_MASTER -/atom/movable/screen/plane_master/above_wall/Initialize() +/atom/movable/screen/plane_master/above_wall/Initialize(mapload) . = ..() add_filter("vision_cone", 100, list(type="alpha", render_source=FIELD_OF_VISION_RENDER_TARGET, flags=MASK_INVERSE)) @@ -78,7 +78,7 @@ appearance_flags = PLANE_MASTER //should use client color blend_mode = BLEND_OVERLAY -/atom/movable/screen/plane_master/game_world/Initialize() +/atom/movable/screen/plane_master/game_world/Initialize(mapload) . = ..() add_filter("vision_cone", 100, list(type="alpha", render_source=FIELD_OF_VISION_RENDER_TARGET, flags=MASK_INVERSE)) @@ -95,7 +95,7 @@ render_target = FIELD_OF_VISION_RENDER_TARGET mouse_opacity = MOUSE_OPACITY_TRANSPARENT -/atom/movable/screen/plane_master/field_of_vision/Initialize() +/atom/movable/screen/plane_master/field_of_vision/Initialize(mapload) . = ..() filters += filter(type="alpha", render_source=FIELD_OF_VISION_BLOCKER_RENDER_TARGET, flags=MASK_INVERSE) @@ -112,7 +112,7 @@ plane = FIELD_OF_VISION_VISUAL_PLANE mouse_opacity = MOUSE_OPACITY_TRANSPARENT -/atom/movable/screen/plane_master/field_of_vision_visual/Initialize() +/atom/movable/screen/plane_master/field_of_vision_visual/Initialize(mapload) . = ..() filters += filter(type="alpha", render_source=FIELD_OF_VISION_BLOCKER_RENDER_TARGET, flags=MASK_INVERSE) @@ -124,8 +124,8 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT /atom/movable/screen/plane_master/lighting/backdrop(mob/mymob) - mymob.overlay_fullscreen("lighting_backdrop_lit", /atom/movable/screen/fullscreen/lighting_backdrop/lit) - mymob.overlay_fullscreen("lighting_backdrop_unlit", /atom/movable/screen/fullscreen/lighting_backdrop/unlit) + mymob.overlay_fullscreen("lighting_backdrop_lit", /atom/movable/screen/fullscreen/special/lighting_backdrop/lit) + mymob.overlay_fullscreen("lighting_backdrop_unlit", /atom/movable/screen/fullscreen/special/lighting_backdrop/unlit) /*! * This system works by exploiting BYONDs color matrix filter to use layers to handle emissive blockers. @@ -138,12 +138,11 @@ * This is then used to alpha mask the lighting plane. */ -/atom/movable/screen/plane_master/lighting/Initialize() +/atom/movable/screen/plane_master/lighting/Initialize(mapload) . = ..() add_filter("emissives", 1, alpha_mask_filter(render_source = EMISSIVE_RENDER_TARGET, flags = MASK_INVERSE)) add_filter("object_lighting", 2, alpha_mask_filter(render_source = O_LIGHTING_VISUAL_RENDER_TARGET, flags = MASK_INVERSE)) - /** * Handles emissive overlays and emissive blockers. */ @@ -153,7 +152,7 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT render_target = EMISSIVE_RENDER_TARGET -/atom/movable/screen/plane_master/emissive/Initialize() +/atom/movable/screen/plane_master/emissive/Initialize(mapload) . = ..() add_filter("em_block_masking", 1, color_matrix_filter(GLOB.em_mask_matrix)) @@ -163,9 +162,10 @@ plane = PLANE_SPACE_PARALLAX blend_mode = BLEND_MULTIPLY mouse_opacity = MOUSE_OPACITY_TRANSPARENT + render_target = PLANE_SPACE_PARALLAX_RENDER_TARGET /atom/movable/screen/plane_master/parallax_white - name = "parallax whitifier plane master" + name = "parallax backdrop/space turf plane master" plane = PLANE_SPACE /atom/movable/screen/plane_master/camera_static @@ -174,7 +174,6 @@ appearance_flags = PLANE_MASTER blend_mode = BLEND_OVERLAY - //Reserved to chat messages, so they are still displayed above the field of vision masking. /atom/movable/screen/plane_master/chat_messages name = "runechat plane master" diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index 3cce288e67..60a78e5ff3 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -91,6 +91,8 @@ GLOBAL_LIST_EMPTY(radial_menus) else py_shift = 32 restrict_to_dir(NORTH) //I was going to parse screen loc here but that's more effort than it's worth. + else if(hudfix_method && AM.loc) + anchor = get_atom_on_turf(anchor) //Sets defaults //These assume 45 deg min_angle @@ -178,7 +180,7 @@ GLOBAL_LIST_EMPTY(radial_menus) starting.Scale(0.1,0.1) E.transform = starting var/matrix/TM = matrix() - animate(E,pixel_x = px,pixel_y = py, transform = TM, time = timing) + animate(E,pixel_x = px,pixel_y = py, transform = TM, time = timing, easing = SINE_EASING | EASE_OUT) else E.pixel_y = py E.pixel_x = px @@ -194,6 +196,9 @@ GLOBAL_LIST_EMPTY(radial_menus) else if(istext(choices_values[choice_id])) E.name = choices_values[choice_id] + else if(ispath(choices_values[choice_id],/atom)) + var/atom/A = choices_values[choice_id] + E.name = initial(A.name) else var/atom/movable/AM = choices_values[choice_id] //Movables only E.name = AM.name @@ -256,7 +261,7 @@ GLOBAL_LIST_EMPTY(radial_menus) //Blank menu_holder = image(icon='icons/effects/effects.dmi',loc=anchor,icon_state="nothing",layer = ABOVE_HUD_LAYER) menu_holder.plane = ABOVE_HUD_PLANE - menu_holder.appearance_flags |= KEEP_APART + menu_holder.appearance_flags |= KEEP_APART|NO_CLIENT_COLOR|RESET_ALPHA|RESET_COLOR|RESET_TRANSFORM menu_holder.vis_contents += elements + close_button current_user.images += menu_holder diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 03ad1b1821..e20bae87d7 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -342,3 +342,43 @@ if(.) return robot.modularInterface?.interact(robot) + +//borg pda +/datum/hud/robot/New(mob/owner) + . = ..() + + var/atom/movable/screen/using + + //PDA message + using = new /atom/movable/screen/robot/pda_msg_send + using.screen_loc = ui_borg_pda_send + using.hud = src + static_inventory += using + + //PDA log + using = new /atom/movable/screen/robot/pda_msg_show + using.screen_loc = ui_borg_pda_log + using.hud = src + static_inventory += using + +/atom/movable/screen/robot/pda_msg_send + name = "PDA - Send Message" + icon = 'icons/mob/screen_ai.dmi' + icon_state = "pda_send" + +/atom/movable/screen/robot/pda_msg_send/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.cmd_send_pdamesg(usr) + +/atom/movable/screen/robot/pda_msg_show + name = "PDA - Show Message Log" + icon = 'icons/mob/screen_ai.dmi' + icon_state = "pda_receive" + +/atom/movable/screen/robot/pda_msg_show/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.cmd_show_message_log(usr) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index bfbdce41fd..33c0bb0f04 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -9,7 +9,6 @@ /atom/movable/screen name = "" icon = 'icons/mob/screen_gen.dmi' - layer = HUD_LAYER plane = HUD_PLANE animate_movement = SLIDE_STEPS speech_span = SPAN_ROBOT @@ -56,16 +55,12 @@ maptext_width = 480 /atom/movable/screen/swap_hand - layer = HUD_LAYER plane = HUD_PLANE name = "swap hand" /atom/movable/screen/swap_hand/Click() // At this point in client Click() code we have passed the 1/10 sec check and little else // We don't even know if it's a middle click - // if(world.time <= usr.next_move) - // return 1 - if(usr.incapacitated()) return 1 @@ -74,6 +69,17 @@ M.swap_hand() return 1 +// /atom/movable/screen/skills +// name = "skills" +// icon = 'icons/mob/screen_midnight.dmi' +// icon_state = "skills" +// screen_loc = ui_skill_menu + +// /atom/movable/screen/skills/Click() +// if(ishuman(usr)) +// var/mob/living/carbon/human/H = usr +// H.mind.print_levels(H) + /atom/movable/screen/craft name = "crafting menu" icon = 'icons/mob/screen_midnight.dmi' @@ -91,7 +97,7 @@ return TRUE var/area/A = get_area(usr) if(!A.outdoors) - to_chat(usr, "There is already a defined structure here.") + to_chat(usr, span_warning("There is already a defined structure here.")) return TRUE create_area(usr) @@ -114,15 +120,12 @@ /// Icon when contains an item. For now used only by humans. var/icon_full /// The overlay when hovering over with an item in your hand - var/list/object_overlays = list() - layer = HUD_LAYER + var/image/object_overlay plane = HUD_PLANE /atom/movable/screen/inventory/Click(location, control, params) // At this point in client Click() code we have passed the 1/10 sec check and little else // We don't even know if it's a middle click - // if(world.time <= usr.next_move) - // return TRUE if(usr.incapacitated()) // ignore_stasis = TRUE return TRUE @@ -138,24 +141,23 @@ usr.update_inv_hands() return TRUE -/atom/movable/screen/inventory/MouseEntered() - ..() +/atom/movable/screen/inventory/MouseEntered(location, control, params) + . = ..() add_overlays() /atom/movable/screen/inventory/MouseExited() ..() - cut_overlay(object_overlays) - object_overlays.Cut() + cut_overlay(object_overlay) + QDEL_NULL(object_overlay) /atom/movable/screen/inventory/update_icon_state() if(!icon_empty) icon_empty = icon_state - if(hud?.mymob && slot_id && icon_full) - if(hud.mymob.get_item_by_slot(slot_id)) - icon_state = icon_full - else - icon_state = icon_empty + if(!hud?.mymob || !slot_id || !icon_full) + return ..() + icon_state = hud.mymob.get_item_by_slot(slot_id) ? icon_full : icon_empty + return ..() /atom/movable/screen/inventory/proc/add_overlays() var/mob/user = hud?.mymob @@ -171,14 +173,14 @@ var/image/item_overlay = image(holding) item_overlay.alpha = 92 - if(!user.can_equip(holding, slot_id, TRUE)) + if(!user.can_equip(holding, slot_id, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) item_overlay.color = "#FF0000" else item_overlay.color = "#00ff00" - cut_overlay(object_overlays) - // object_overlay = item_overlay - add_overlay(object_overlays) + cut_overlay(object_overlay) + object_overlay = item_overlay + add_overlay(object_overlay) /atom/movable/screen/inventory/hand var/mutable_appearance/handcuff_overlay @@ -214,8 +216,6 @@ var/mob/user = hud?.mymob if(usr != user) return TRUE - // if(world.time <= user.next_move) - // return TRUE if(user.incapacitated()) return TRUE if (ismecha(user.loc)) // stops inventory actions in a mech @@ -229,12 +229,24 @@ user.swap_hand(held_index) return TRUE +// /atom/movable/screen/close +// name = "close" +// plane = ABOVE_HUD_PLANE +// icon_state = "backpack_close" + +// /atom/movable/screen/close/Initialize(mapload, new_master) +// . = ..() +// master = new_master + +// /atom/movable/screen/close/Click() +// var/datum/component/storage/S = master +// S.hide_from(usr) +// return TRUE /atom/movable/screen/drop name = "drop" icon = 'icons/mob/screen_midnight.dmi' icon_state = "act_drop" - layer = HUD_LAYER plane = HUD_PLANE /atom/movable/screen/drop/Click() @@ -290,12 +302,12 @@ if(C.internal) C.internal = null - to_chat(C, "You are no longer running on internals.") + to_chat(C, span_notice("You are no longer running on internals.")) icon_state = "internal0" else if(!C.getorganslot(ORGAN_SLOT_BREATHING_TUBE)) if(HAS_TRAIT(C, TRAIT_NO_INTERNALS)) - to_chat(C, "Due to cumbersome equipment or anatomy, you are currently unable to use internals!") + to_chat(C, span_warning("Due to cumbersome equipment or anatomy, you are currently unable to use internals!")) return var/obj/item/clothing/check var/internals = FALSE @@ -305,40 +317,40 @@ var/obj/item/clothing/mask/M = check if(M.mask_adjusted) M.adjustmask(C) - if(CHECK_BITFIELD(check.clothing_flags, ALLOWINTERNALS)) + if((check.clothing_flags & ALLOWINTERNALS)) internals = TRUE if(!internals) - to_chat(C, "You are not wearing an internals mask!") + to_chat(C, span_warning("You are not wearing an internals mask!")) return var/obj/item/I = C.is_holding_item_of_type(/obj/item/tank) if(I) - to_chat(C, "You are now running on internals from [I] in your [C.get_held_index_name(C.get_held_index_of_item(I))].") + to_chat(C, span_notice("You are now running on internals from [I] in your [C.get_held_index_name(C.get_held_index_of_item(I))].")) C.internal = I else if(ishuman(C)) var/mob/living/carbon/human/H = C if(istype(H.s_store, /obj/item/tank)) - to_chat(H, "You are now running on internals from [H.s_store] on your [H.wear_suit.name].") + to_chat(H, span_notice("You are now running on internals from [H.s_store] on your [H.wear_suit.name].")) H.internal = H.s_store else if(istype(H.belt, /obj/item/tank)) - to_chat(H, "You are now running on internals from [H.belt] on your belt.") + to_chat(H, span_notice("You are now running on internals from [H.belt] on your belt.")) H.internal = H.belt else if(istype(H.l_store, /obj/item/tank)) - to_chat(H, "You are now running on internals from [H.l_store] in your left pocket.") + to_chat(H, span_notice("You are now running on internals from [H.l_store] in your left pocket.")) H.internal = H.l_store else if(istype(H.r_store, /obj/item/tank)) - to_chat(H, "You are now running on internals from [H.r_store] in your right pocket.") + to_chat(H, span_notice("You are now running on internals from [H.r_store] in your right pocket.")) H.internal = H.r_store //Separate so CO2 jetpacks are a little less cumbersome. if(!C.internal && istype(C.back, /obj/item/tank)) - to_chat(C, "You are now running on internals from [C.back] on your back.") + to_chat(C, span_notice("You are now running on internals from [C.back] on your back.")) C.internal = C.back if(C.internal) icon_state = "internal1" else - to_chat(C, "You don't have an oxygen tank!") + to_chat(C, span_warning("You don't have an oxygen tank!")) return C.update_action_buttons_icon() @@ -360,6 +372,7 @@ icon_state = CONFIG_GET(flag/sprint_enabled)? "walking" : "walking_nosprint" if(MOVE_INTENT_RUN) icon_state = CONFIG_GET(flag/sprint_enabled)? "running" : "running_nosprint" + return ..() /atom/movable/screen/mov_intent/proc/toggle(mob/user) if(isobserver(user)) @@ -381,12 +394,12 @@ icon_state = "pull" else icon_state = "pull0" + return ..() /atom/movable/screen/resist name = "resist" icon = 'icons/mob/screen_midnight.dmi' icon_state = "act_resist" - layer = HUD_LAYER plane = HUD_PLANE /atom/movable/screen/resist/Click() @@ -398,7 +411,6 @@ name = "rest" icon = 'icons/mob/screen_midnight.dmi' icon_state = "act_rest" - layer = HUD_LAYER plane = HUD_PLANE /atom/movable/screen/rest/Click() @@ -409,11 +421,12 @@ /atom/movable/screen/rest/update_icon_state() var/mob/living/user = hud?.mymob if(!istype(user)) - return + return ..() if(!user.resting) icon_state = "act_rest" else icon_state = "act_rest0" + return ..() /atom/movable/screen/throw_catch name = "throw/catch" @@ -437,9 +450,9 @@ if(isobserver(usr)) return - var/list/PL = params2list(params) - var/icon_x = text2num(PL["icon-x"]) - var/icon_y = text2num(PL["icon-y"]) + var/list/modifiers = params2list(params) + var/icon_x = text2num(LAZYACCESS(modifiers, "icon-x")) + var/icon_y = text2num(LAZYACCESS(modifiers, "icon-y")) var/choice = get_zone_at(icon_x, icon_y) if (!choice) return 1 @@ -447,15 +460,16 @@ return set_selected_zone(choice, usr) /atom/movable/screen/zone_sel/MouseEntered(location, control, params) + . = ..() MouseMove(location, control, params) /atom/movable/screen/zone_sel/MouseMove(location, control, params) if(isobserver(usr)) return - var/list/PL = params2list(params) - var/icon_x = text2num(PL["icon-x"]) - var/icon_y = text2num(PL["icon-y"]) + var/list/modifiers = params2list(params) + var/icon_x = text2num(LAZYACCESS(modifiers, "icon-x")) + var/icon_y = text2num(LAZYACCESS(modifiers, "icon-y")) var/choice = get_zone_at(icon_x, icon_y) if(hovering == choice) @@ -475,7 +489,6 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT alpha = 128 anchored = TRUE - layer = ABOVE_HUD_LAYER plane = ABOVE_HUD_PLANE /atom/movable/screen/zone_sel/MouseExited(location, control, params) @@ -527,7 +540,7 @@ if(choice != hud.mymob.zone_selected) hud.mymob.zone_selected = choice - update_icon() + update_appearance() return TRUE @@ -544,7 +557,6 @@ /atom/movable/screen/zone_sel/robot icon = 'icons/mob/screen_cyborg.dmi' - /atom/movable/screen/flash name = "flash" icon_state = "blank" @@ -633,6 +645,11 @@ name = "health doll" screen_loc = ui_healthdoll +/atom/movable/screen/healthdoll/Click() + if (iscarbon(usr)) + var/mob/living/carbon/C = usr + C.check_self_for_injuries() + /atom/movable/screen/healthdoll/living icon_state = "fullhealth0" screen_loc = ui_living_healthdoll @@ -643,6 +660,9 @@ icon_state = "mood5" screen_loc = ui_mood +/atom/movable/screen/mood/attack_tk() + return + /atom/movable/screen/splash icon = 'icons/blank_title.png' icon_state = "" @@ -653,6 +673,8 @@ /atom/movable/screen/splash/New(client/C, visible, use_previous_title) //TODO: Make this use INITIALIZE_IMMEDIATE, except its not easy . = ..() + if(!istype(C)) + return holder = C @@ -698,3 +720,28 @@ /atom/movable/screen/component_button/Click(params) if(parent) parent.component_click(src, params) + +/atom/movable/screen/combo + icon_state = "" + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + screen_loc = ui_combo + layer = ABOVE_HUD_LAYER + var/timerid + +/atom/movable/screen/combo/proc/clear_streak() + cut_overlays() + icon_state = "" + +/atom/movable/screen/combo/update_icon_state(streak = "") + clear_streak() + if (timerid) + deltimer(timerid) + if (!streak) + return + timerid = addtimer(CALLBACK(src, .proc/clear_streak), 20, TIMER_UNIQUE | TIMER_STOPPABLE) + icon_state = "combo" + for (var/i = 1; i <= length(streak); ++i) + var/intent_text = copytext(streak, i, i + 1) + var/image/intent_icon = image(icon,src,"combo_[intent_text]") + intent_icon.pixel_x = 16 * (i - 1) - 8 * length(streak) + add_overlay(intent_icon) diff --git a/code/_onclick/hud/screen_objects/clickdelay.dm b/code/_onclick/hud/screen_objects/clickdelay.dm index c62f051c1a..b8258c7598 100644 --- a/code/_onclick/hud/screen_objects/clickdelay.dm +++ b/code/_onclick/hud/screen_objects/clickdelay.dm @@ -25,7 +25,7 @@ icon_state = "prog_bar_100" layer = 20 // under hand buttons -/atom/movable/screen/action_bar/clickdelay/Initialize() +/atom/movable/screen/action_bar/clickdelay/Initialize(mapload) . = ..() var/matrix/M = new M.Scale(2, 1) diff --git a/code/_onclick/hud/screentip.dm b/code/_onclick/hud/screentip.dm new file mode 100644 index 0000000000..5128448561 --- /dev/null +++ b/code/_onclick/hud/screentip.dm @@ -0,0 +1,20 @@ +/atom/movable/screen/screentip + icon = null + icon_state = null + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + screen_loc = "TOP,LEFT" + maptext_height = 480 + maptext_width = 480 + maptext = "" + layer = SCREENTIP_LAYER + +/atom/movable/screen/screentip/Initialize(mapload, _hud) + . = ..() + hud = _hud + update_view() + +/atom/movable/screen/screentip/proc/update_view(datum/source) + SIGNAL_HANDLER + if(!hud || !hud.mymob.client.view_size) //Might not have been initialized by now + return + maptext_width = getviewsize(hud.mymob.client.view_size.getView())[1] * world.icon_size diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 1618e351ec..23486cac29 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -126,6 +126,8 @@ return DISCARD_LAST_ACTION user.do_attack_animation(O) O.attacked_by(src, user) + if(force >= 20) + shake_camera(user, ((force - 15) * 0.01 + 1), ((force - 15) * 0.01)) /atom/movable/proc/attacked_by() return @@ -260,7 +262,7 @@ return clamp((1.5 + (w_class/5)) * ((force_override || force) / 1.5), 0, 10 SECONDS) * CONFIG_GET(number/melee_stagger_factor) /obj/item/proc/do_stagger_action(mob/living/target, mob/living/user, force_override) - if(!CHECK_BITFIELD(target.status_flags, CANSTAGGER)) + if(!(target.status_flags & CANSTAGGER)) return FALSE if(target.combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) target.do_staggered_animation() diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index d431e6d3cd..78fc32480f 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -11,7 +11,6 @@ // Otherwise jump else if(A.loc) forceMove(get_turf(A)) - update_parallax_contents() /mob/dead/observer/ClickOn(var/atom/A, var/params) if(check_click_intercept(params,A)) diff --git a/code/_onclick/right_click.dm b/code/_onclick/right_click.dm index 4b2480eb8c..c1613561b4 100644 --- a/code/_onclick/right_click.dm +++ b/code/_onclick/right_click.dm @@ -11,10 +11,6 @@ if(!modifiers["catcher"] && A.IsObscured()) return - if(ismecha(loc)) - var/obj/mecha/M = loc - return M.click_action(A,src,params) - if(restrained()) DelayNextAction(CLICK_CD_HANDCUFFED) return RestrainedClickOn(A) diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index f8a14b8c30..3ae45648df 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -79,7 +79,7 @@ var/atom/movable/focus var/mob/living/carbon/tk_user -/obj/item/tk_grab/Initialize() +/obj/item/tk_grab/Initialize(mapload) . = ..() START_PROCESSING(SSfastprocess, src) @@ -101,7 +101,7 @@ //stops TK grabs being equipped anywhere but into hands /obj/item/tk_grab/equipped(mob/user, slot) - if(slot == SLOT_HANDS) + if(slot == ITEM_SLOT_HANDS) return ..() qdel(src) diff --git a/code/game/alternate_appearance.dm b/code/_rendering/atom_huds/alternate_appearance.dm similarity index 100% rename from code/game/alternate_appearance.dm rename to code/_rendering/atom_huds/alternate_appearance.dm diff --git a/code/datums/hud.dm b/code/_rendering/atom_huds/atom_hud.dm similarity index 96% rename from code/datums/hud.dm rename to code/_rendering/atom_huds/atom_hud.dm index 1c23d5f2a0..c89fe33db8 100644 --- a/code/datums/hud.dm +++ b/code/_rendering/atom_huds/atom_hud.dm @@ -29,7 +29,9 @@ GLOBAL_LIST_INIT(huds, list( ANTAG_HUD_BROTHER = new/datum/atom_hud/antag/hidden(), ANTAG_HUD_BLOODSUCKER = new/datum/atom_hud/antag/bloodsucker(), ANTAG_HUD_FUGITIVE = new/datum/atom_hud/antag(), - ANTAG_HUD_HERETIC = new/datum/atom_hud/antag/hidden() + ANTAG_HUD_HERETIC = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_SPACECOP = new/datum/atom_hud/antag(), + ANTAG_HUD_GANGSTER = new/datum/atom_hud/antag/hidden() )) /datum/atom_hud @@ -124,9 +126,3 @@ GLOBAL_LIST_INIT(huds, list( /mob/dead/new_player/reload_huds() return - -/mob/proc/add_click_catcher() - client.screen += client.void - -/mob/dead/new_player/add_click_catcher() - return diff --git a/code/game/data_huds.dm b/code/_rendering/atom_huds/data_huds.dm similarity index 97% rename from code/game/data_huds.dm rename to code/_rendering/atom_huds/data_huds.dm index 413484b99b..291923ee4e 100644 --- a/code/game/data_huds.dm +++ b/code/_rendering/atom_huds/data_huds.dm @@ -52,10 +52,10 @@ /datum/atom_hud/data/diagnostic /datum/atom_hud/data/diagnostic/basic - hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_NANITE_FULL_HUD) + hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_NANITE_FULL_HUD, DIAG_LAUNCHPAD_HUD) /datum/atom_hud/data/diagnostic/advanced - hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_NANITE_FULL_HUD, DIAG_PATH_HUD) + hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_NANITE_FULL_HUD, DIAG_PATH_HUD,DIAG_LAUNCHPAD_HUD) /datum/atom_hud/data/bot_path hud_icons = list(DIAG_PATH_HUD) @@ -381,14 +381,14 @@ /*~~~~~~~~~~~~~~~~~~~~ BIG STOMPY MECHS ~~~~~~~~~~~~~~~~~~~~~*/ -/obj/mecha/proc/diag_hud_set_mechhealth() +/obj/vehicle/sealed/mecha/proc/diag_hud_set_mechhealth() var/image/holder = hud_list[DIAG_MECH_HUD] var/icon/I = icon(icon, icon_state, dir) holder.pixel_y = I.Height() - world.icon_size holder.icon_state = "huddiag[RoundDiagBar(obj_integrity/max_integrity)]" -/obj/mecha/proc/diag_hud_set_mechcell() +/obj/vehicle/sealed/mecha/proc/diag_hud_set_mechcell() var/image/holder = hud_list[DIAG_BATT_HUD] var/icon/I = icon(icon, icon_state, dir) holder.pixel_y = I.Height() - world.icon_size @@ -399,7 +399,7 @@ holder.icon_state = "hudnobatt" -/obj/mecha/proc/diag_hud_set_mechstat() +/obj/vehicle/sealed/mecha/proc/diag_hud_set_mechstat() var/image/holder = hud_list[DIAG_STAT_HUD] var/icon/I = icon(icon, icon_state, dir) holder.pixel_y = I.Height() - world.icon_size @@ -407,7 +407,7 @@ if(internal_damage) holder.icon_state = "hudwarn" -/obj/mecha/proc/diag_hud_set_mechtracking() //Shows tracking beacons on the mech +/obj/vehicle/sealed/mecha/proc/diag_hud_set_mechtracking() //Shows tracking beacons on the mech var/image/holder = hud_list[DIAG_TRACK_HUD] var/icon/I = icon(icon, icon_state, dir) holder.pixel_y = I.Height() - world.icon_size diff --git a/code/_rendering/clickcatcher/clickcatcher.dm b/code/_rendering/clickcatcher/clickcatcher.dm new file mode 100644 index 0000000000..524f753e98 --- /dev/null +++ b/code/_rendering/clickcatcher/clickcatcher.dm @@ -0,0 +1,74 @@ +/atom/movable/screen/click_catcher + icon = 'icons/screen/clickcatcher.dmi' + icon_state = "catcher" + appearance_flags = TILE_BOUND | NO_CLIENT_COLOR | RESET_TRANSFORM | RESET_COLOR | RESET_ALPHA + plane = CLICKCATCHER_PLANE + plane = CLICKCATCHER_PLANE + mouse_opacity = MOUSE_OPACITY_OPAQUE + screen_loc = "CENTER" + +/* +#define MAX_SAFE_BYOND_ICON_SCALE_TILES (MAX_SAFE_BYOND_ICON_SCALE_PX / world.icon_size) +#define MAX_SAFE_BYOND_ICON_SCALE_PX (33 * 32) //Not using world.icon_size on purpose. + +/atom/movable/screen/click_catcher/proc/UpdateFill(view_size_x = 15, view_size_y = 15) + var/icon/newicon = icon('icons/mob/screen_gen.dmi', "catcher") + var/ox = min(MAX_SAFE_BYOND_ICON_SCALE_TILES, view_size_x) + var/oy = min(MAX_SAFE_BYOND_ICON_SCALE_TILES, view_size_y) + var/px = view_size_x * world.icon_size + var/py = view_size_y * world.icon_size + var/sx = min(MAX_SAFE_BYOND_ICON_SCALE_PX, px) + var/sy = min(MAX_SAFE_BYOND_ICON_SCALE_PX, py) + newicon.Scale(sx, sy) + icon = newicon + screen_loc = "CENTER-[(ox-1)*0.5],CENTER-[(oy-1)*0.5]" + var/matrix/M = new + M.Scale(px/sx, py/sy) + transform = M + +#undef MAX_SAFE_BYOND_ICON_SCALE_TILES +#undef MAX_SAFE_BYOND_ICON_SCALE_PX +*/ + +/atom/movable/screen/click_catcher/proc/UpdateFill(view_size_x, view_size_y) + screen_loc = "1,1 to [view_size_x],[view_size_y]" + +/atom/movable/screen/click_catcher/Click(location, control, params) + var/list/modifiers = params2list(params) + if(modifiers["middle"] && iscarbon(usr)) + var/mob/living/carbon/C = usr + C.swap_hand() + else + var/turf/T = Parse(modifiers["screen-loc"], get_turf(usr.client?.eye || usr), usr.client) + params += "&catcher=1" + if(T) + T.Click(location, control, params) + return TRUE + +/atom/movable/screen/click_catcher/proc/Parse(scr_loc, turf/origin, client/C) + // screen-loc: Pixel coordinates in screen_loc format ("[tile_x]:[pixel_x],[tile_y]:[pixel_y]") + if(!scr_loc) + return null + var/tX = splittext(scr_loc, ",") + var/tY = splittext(tX[2], ":") + var/tZ = origin.z + tY = tY[1] + tX = splittext(tX[1], ":") + tX = tX[1] + var/list/actual_view = getviewsize(C ? C.view : world.view) + tX = clamp(origin.x + text2num(tX) - round(actual_view[1] / 2) - 1, 1, world.maxx) + tY = clamp(origin.y + text2num(tY) - round(actual_view[2] / 2) - 1, 1, world.maxy) + return locate(tX, tY, tZ) + +/** + * Makes a clickcatcher if necessary, and ensures it's fit to our size. + */ +/client/proc/update_clickcatcher(list/view_override) + if(!click_catcher) + click_catcher = new + screen |= click_catcher + if(view_override) + click_catcher.UpdateFill(view_override[1], view_override[2]) + else + var/list/view_list = getviewsize(view) + click_catcher.UpdateFill(view_list[1], view_list[2]) diff --git a/code/_rendering/fullscreen/fullscreen.dm b/code/_rendering/fullscreen/fullscreen.dm new file mode 100644 index 0000000000..dd8f697891 --- /dev/null +++ b/code/_rendering/fullscreen/fullscreen.dm @@ -0,0 +1,234 @@ +/** + * Adds a fullscreen overlay + * + * @params + * - category - string - must exist. will overwrite any other screen in this category. defaults to type. + * - type - the typepath of the screen + * - severity - severity - different screen objects have differing severities + */ +/mob/proc/overlay_fullscreen(category, type, severity) + ASSERT(type) + if(!category) + category = type + var/atom/movable/screen/fullscreen/screen = fullscreens[category] + if (!screen || screen.type != type) + // needs to be recreated + clear_fullscreen(category, 0) + fullscreens[category] = screen = new type + screen.SetSeverity(severity) + if(client && screen.ShouldShow(src)) + screen.SetView(client.view) + client.screen += screen + return screen + +/** + * Wipes a fullscreen of a certain category + * + * Second argument is for animation delay. + */ +/mob/proc/clear_fullscreen(category, animated = 10) + if(!fullscreens) + return + var/atom/movable/screen/fullscreen/screen = fullscreens[category] + fullscreens -= category + if(!screen) + return + if(animated > 0) + animate(screen, alpha = 0, time = animated) + addtimer(CALLBACK(src, .proc/_remove_fullscreen_direct, screen), animated, TIMER_CLIENT_TIME) + else + if(client) + client.screen -= screen + qdel(screen) + +/mob/proc/_remove_fullscreen_direct(atom/movable/screen/fullscreen/screen) + if(client) + client.screen -= screen + qdel(screen) + +/** + * Wipes all fullscreens + */ +/mob/proc/wipe_fullscreens() + for(var/category in fullscreens) + clear_fullscreen(category) + +/** + * Removes fullscreens from client but not the mob + */ +/mob/proc/hide_fullscreens() + if(client) + for(var/category in fullscreens) + client.screen -= fullscreens[category] + +/** + * Ensures all fullscreens are on client. + */ +/mob/proc/reload_fullscreen() + if(client) + var/atom/movable/screen/fullscreen/screen + for(var/category in fullscreens) + screen = fullscreens[category] + if(screen.ShouldShow(src)) + screen.SetView(client.view) + client.screen |= screen + else + client.screen -= screen + +/atom/movable/screen/fullscreen + icon = 'icons/screen/fullscreen_15x15.dmi' + icon_state = "default" + screen_loc = "CENTER-7,CENTER-7" + layer = FULLSCREEN_LAYER + plane = FULLSCREEN_PLANE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + /// current view we're adapted to + var/view_current + /// min severity + var/severity_min = 0 + /// max severity + var/severity_max = INFINITY + /// current severity + var/severity = 0 + /// show this while dead + var/show_when_dead = FALSE + +/atom/movable/screen/fullscreen/proc/SetSeverity(severity) + src.severity = clamp(severity, severity_min, severity_max) + icon_state = "[initial(icon_state)][severity]" + +/atom/movable/screen/fullscreen/proc/SetView(client_view) + view_current = client_view + +/atom/movable/screen/fullscreen/proc/ShouldShow(mob/M) + if(!show_when_dead && M.stat == DEAD) + return FALSE + return TRUE + +/atom/movable/screen/fullscreen/Destroy() + SetSeverity(0) + return ..() + +/atom/movable/screen/fullscreen/scaled + icon = 'icons/screen/fullscreen_15x15.dmi' + screen_loc = "CENTER-7,CENTER-7" + /// size of sprite in tiles + var/size_x = 15 + /// size of sprite in tiles + var/size_y = 15 + +/atom/movable/screen/fullscreen/scaled/SetView(client_view) + if(view_current != client_view) + var/list/actualview = getviewsize(client_view) + view_current = client_view + transform = matrix(actualview[1] / size_x, 0, 0, 0, actualview[2] / size_y, 0) + return ..() + +/atom/movable/screen/fullscreen/scaled/brute + icon_state = "brutedamageoverlay" + layer = UI_DAMAGE_LAYER + plane = FULLSCREEN_PLANE + +/atom/movable/screen/fullscreen/scaled/oxy + icon_state = "oxydamageoverlay" + layer = UI_DAMAGE_LAYER + plane = FULLSCREEN_PLANE + +/atom/movable/screen/fullscreen/scaled/crit + icon_state = "passage" + layer = CRIT_LAYER + plane = FULLSCREEN_PLANE + +/atom/movable/screen/fullscreen/scaled/crit/vision + icon_state = "oxydamageoverlay" + layer = BLIND_LAYER + +/atom/movable/screen/fullscreen/scaled/blind + icon_state = "blackimageoverlay" + layer = BLIND_LAYER + plane = FULLSCREEN_PLANE + +/atom/movable/screen/fullscreen/scaled/curse + icon_state = "curse" + layer = CURSE_LAYER + plane = FULLSCREEN_PLANE + +/atom/movable/screen/fullscreen/scaled/impaired + icon_state = "impairedoverlay" + +/atom/movable/screen/fullscreen/scaled/emergency_meeting + icon_state = "emergency_meeting" + show_when_dead = TRUE + layer = CURSE_LAYER + plane = SPLASHSCREEN_PLANE + +/atom/movable/screen/fullscreen/tiled/blurry + icon = 'icons/mob/screen_gen.dmi' + screen_loc = "WEST,SOUTH to EAST,NORTH" + icon_state = "cloudy" + +/atom/movable/screen/fullscreen/tiled/flash + icon = 'icons/mob/screen_gen.dmi' + screen_loc = "WEST,SOUTH to EAST,NORTH" + icon_state = "flash" + +/atom/movable/screen/fullscreen/tiled/flash/static + icon = 'icons/mob/screen_gen.dmi' + screen_loc = "WEST,SOUTH to EAST,NORTH" + icon_state = "noise" + +/atom/movable/screen/fullscreen/tiled/high + icon = 'icons/mob/screen_gen.dmi' + screen_loc = "WEST,SOUTH to EAST,NORTH" + icon_state = "druggy" + +/atom/movable/screen/fullscreen/tiled/color_vision + icon = 'icons/mob/screen_gen.dmi' + screen_loc = "WEST,SOUTH to EAST,NORTH" + icon_state = "flash" + alpha = 80 + +/atom/movable/screen/fullscreen/tiled/color_vision/green + color = "#00ff00" + +/atom/movable/screen/fullscreen/tiled/color_vision/red + color = "#ff0000" + +/atom/movable/screen/fullscreen/tiled/color_vision/blue + color = "#0000ff" + +/atom/movable/screen/fullscreen/tiled/cinematic_backdrop + icon = 'icons/mob/screen_gen.dmi' + screen_loc = "WEST,SOUTH to EAST,NORTH" + icon_state = "flash" + plane = SPLASHSCREEN_PLANE + layer = SPLASHSCREEN_LAYER - 1 + color = "#000000" + show_when_dead = TRUE + +/atom/movable/screen/fullscreen/special/lighting_backdrop + icon = 'icons/mob/screen_gen.dmi' + icon_state = "flash" + transform = matrix(200, 0, 0, 0, 200, 0) + plane = LIGHTING_PLANE + blend_mode = BLEND_OVERLAY + show_when_dead = TRUE + +//Provides darkness to the back of the lighting plane +/atom/movable/screen/fullscreen/special/lighting_backdrop/lit + invisibility = INVISIBILITY_LIGHTING + layer = BACKGROUND_LAYER+21 + color = "#000" + show_when_dead = TRUE + +//Provides whiteness in case you don't see lights so everything is still visible +/atom/movable/screen/fullscreen/special/lighting_backdrop/unlit + layer = BACKGROUND_LAYER+20 + show_when_dead = TRUE + +/atom/movable/screen/fullscreen/special/see_through_darkness + icon_state = "nightvision" + plane = LIGHTING_PLANE + layer = LIGHTING_LAYER + blend_mode = BLEND_ADD + show_when_dead = TRUE diff --git a/code/_rendering/mob.dm b/code/_rendering/mob.dm new file mode 100644 index 0000000000..49095d0910 --- /dev/null +++ b/code/_rendering/mob.dm @@ -0,0 +1,21 @@ +/** + * initializes screen rendering. call on mob new + */ +/mob/proc/init_rendering() + +/** + * loads screen rendering. call on mob login + */ +/mob/proc/reload_rendering() + if(!client.parallax_holder) + client.CreateParallax() + else + client.parallax_holder.Reset(force = TRUE) + client.update_clickcatcher() + reload_fullscreen() + +/** + * destroys screen rendering. call on mob del + */ +/mob/proc/dispose_rendering() + wipe_fullscreens() diff --git a/code/_rendering/parallax/parallax.dm b/code/_rendering/parallax/parallax.dm new file mode 100644 index 0000000000..dbd27ae762 --- /dev/null +++ b/code/_rendering/parallax/parallax.dm @@ -0,0 +1,28 @@ +/** + * Holds parallax information. + */ +/datum/parallax + /// List of parallax objects - these are cloned to a parallax holder using Clone on each. + var/list/atom/movable/screen/parallax_layer/objects + /// Parallax layers + var/layers = 0 + +/datum/parallax/New(create_objects = TRUE) + if(create_objects) + objects = CreateObjects() + layers = objects.len + +/datum/parallax/Destroy() + QDEL_LIST(objects) + return ..() + +/** + * Gets a new version of the objects inside - used when applying to a holder. + */ +/datum/parallax/proc/GetObjects() + . = list() + for(var/atom/movable/screen/parallax_layer/layer in objects) + . += layer.Clone() + +/datum/parallax/proc/CreateObjects() + . = objects = list() diff --git a/code/_rendering/parallax/parallax_holder.dm b/code/_rendering/parallax/parallax_holder.dm new file mode 100644 index 0000000000..1f7d84ae11 --- /dev/null +++ b/code/_rendering/parallax/parallax_holder.dm @@ -0,0 +1,311 @@ +/** + * # Parallax holders + * + * Holds all the information about a client's parallax + * + * Not on mob because parallax is area based, not mob based. + * + * How parallax works: + * - Layers - normal layers, scroll with movement to relative position, can scroll + * - Absolute - absolute layers, scroll with movement to absolute position, cannot scroll + * - Vis - vis_contents-like model - things in this are directly applied and get no processing whatsoever. Things like overmap ships can use this. + */ +/datum/parallax_holder + /// Client that owns us + var/client/owner + /// The parallax object we're currently rendering + var/datum/parallax/parallax + /// Eye we were last anchored to - used to detect eye changes + var/atom/cached_eye + /// force this eye as the "real" eye - useful for secondary maps + var/atom/forced_eye + /// last turf loc + var/turf/last + /// last area - for parallax scrolling/loop animations + var/area/last_area + /// Holder object for vis + var/atom/movable/screen/parallax_vis/vis_holder + /// are we not on the main map? if so, put map id here + var/secondary_map + /// all layers + var/list/atom/movable/screen/parallax_layer/layers + /// vis contents + var/list/atom/movable/vis + /// currently scrolling? + var/scrolling = FALSE + /// current scroll speed in DS per scroll + var/scroll_speed + /// current scroll turn - applied after angle. if angle is 0 (picture moving north) and turn is 90, it would be like if you turned your viewport 90 deg clockwise. + var/scroll_turn + /// override planemaster we manipulate for turning and other effects + var/atom/movable/screen/plane_master/parallax/planemaster_override + +/datum/parallax_holder/New(client/C, secondary_map, forced_eye, planemaster_override) + owner = C + if(!owner) + CRASH("No client") + src.secondary_map = secondary_map + src.forced_eye = forced_eye + src.planemaster_override = planemaster_override + Reset() + +/datum/parallax_holder/Destroy() + if(owner) + if(owner.parallax_holder == src) + owner.parallax_holder = null + Remove() + HardResetAnimations() + QDEL_NULL(vis_holder) + QDEL_NULL(parallax) + layers = null + vis = null + last = null + forced_eye = cached_eye = null + owner = null + return ..() + +/datum/parallax_holder/proc/Reset(auto_z_change, force) + if(!(cached_eye = Eye())) + // if no eye, tear down + last = cached_eye = last_area = null + SetParallax(null, null, auto_z_change) + return + // first, check loc + var/turf/T = get_turf(cached_eye) + if(!T) + // if in nullspace, tear down + last = cached_eye = last_area = null + SetParallax(null, null, auto_z_change) + return + // set last loc and eye + last = T + last_area = T.loc + // rebuild parallax + SetParallax(SSparallax.get_parallax_datum(T.z), null, auto_z_change, force) + // hard reset positions to correct positions + for(var/atom/movable/screen/parallax_layer/L in layers) + L.ResetPosition(T.x, T.y) + +// better updates via client_mobs_in_contents can be created again when important recursive contents is ported! +/datum/parallax_holder/proc/Update(full) + if(!full && !cached_eye || (get_turf(cached_eye) == last)) + return + if(!owner) // why are we here + if(!QDELETED(src)) + qdel(src) + return + if(cached_eye != Eye()) + // eye mismatch, reset + Reset() + return + var/turf/T = get_turf(cached_eye) + if(!last || T.z != last.z) + // z mismatch, reset + Reset() + return + // get rel offsets + var/rel_x = T.x - last.x + var/rel_y = T.y - last.y + // set last + last = T + // move + for(var/atom/movable/screen/parallax_layer/L in layers) + L.RelativePosition(T.x, T.y, rel_x, rel_y) + // process scrolling/movedir + if(last_area != T.loc) + last_area = T.loc + UpdateMotion() + +/** + * Gets the eye we should be centered on + */ +/datum/parallax_holder/proc/Eye() + return forced_eye || owner?.eye + +/** + * Gets the base parallax planemaster for things like turning + */ +/datum/parallax_holder/proc/GetPlaneMaster() + return planemaster_override || (owner && (locate(/atom/movable/screen/plane_master/parallax) in owner?.screen)) + +/** + * Syncs us to our parallax objects. Does NOT check if we should have those objects, that's Reset()'s job. + * + * Doesn't move/update positions/screen locs either. + * + * Also ensures movedirs are correct for the eye's pos. + */ +/datum/parallax_holder/proc/Sync(auto_z_change, force) + layers = list() + for(var/atom/movable/screen/parallax_layer/L in parallax.objects) + layers += L + L.map_id = secondary_map + if(!istype(vis_holder)) + vis_holder = new /atom/movable/screen/parallax_vis + var/turf/T = get_turf(cached_eye) + vis_holder.vis_contents = vis = T? SSparallax.get_parallax_vis_contents(T.z) : list() + UpdateMotion(auto_z_change, force) + +/** + * Updates motion if needed + */ +/datum/parallax_holder/proc/UpdateMotion(auto_z_change, force) + var/turf/T = get_turf(cached_eye) + if(!T) + if(scroll_speed || scroll_turn) + HardResetAnimations() + return + var/list/ret = SSparallax.get_parallax_motion(T.z) + if(ret) + Animation(ret[1], ret[2], auto_z_change? 0 : ret[3], auto_z_change? 0 : ret[4], force) + else + var/area/A = T.loc + Animation(A.parallax_move_speed, A.parallax_move_angle, auto_z_change? 0 : null, auto_z_change? 0 : null, force) + +/datum/parallax_holder/proc/Apply(client/C = owner) + if(QDELETED(C)) + return + . = list() + for(var/atom/movable/screen/parallax_layer/L in layers) + if(L.parallax_intensity > owner.prefs.parallax) + continue + if(!L.ShouldSee(C, last)) + continue + L.SetView(C.view, TRUE) + . |= L + C.screen |= . + if(!secondary_map && (owner.prefs.parallax != PARALLAX_DISABLE)) + var/atom/movable/screen/plane_master/parallax_white/PM = locate() in C.screen + if(PM) + PM.color = list( + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0 + ) + +/datum/parallax_holder/proc/Remove(client/C = owner) + if(QDELETED(C)) + return + C.screen -= layers + if(!secondary_map) + var/atom/movable/screen/plane_master/parallax_white/PM = locate() in C.screen + if(PM) + PM.color = initial(PM.color) + +/datum/parallax_holder/proc/SetParallaxType(path) + if(!ispath(path, /datum/parallax)) + CRASH("Invalid path") + SetParallax(new path) + +/datum/parallax_holder/proc/SetParallax(datum/parallax/P, delete_old = TRUE, auto_z_change, force) + if(P == parallax) + return + Remove() + if(delete_old && istype(parallax) && !QDELETED(parallax)) + qdel(parallax) + HardResetAnimations() + parallax = P + if(!parallax) + return + Sync(auto_z_change, force) + Apply() + +/** + * Runs a modifier to parallax as an animation. + * + * @params + * speed - ds per loop + * turn - angle clockwise from north to turn the motion to + * windup - ds to spend on windups. 0 for immediate. + * turn_speed - ds to spend on turning. 0 for immediate. + */ +/datum/parallax_holder/proc/Animation(speed = 25, turn = 0, windup = speed, turn_speed = speed, force) + // Parallax doesn't currently use this method of rotating. + + // #if !PARALLAX_ROTATION_ANIMATIONS + // turn_speed = 0 + // #endif + + if(speed == 0) + StopScrolling(turn = turn, time = windup) + return + // if(turn != scroll_turn && GetPlaneMaster()) + // // first handle turn. we turn the planemaster + // var/matrix/turn_transform = matrix() + // turn_transform.Turn(turn) + // scroll_turn = turn + // animate(GetPlaneMaster(), transform = turn_transform, time = turn_speed, easing = QUAD_EASING | EASE_IN, flags = ANIMATION_END_NOW | ANIMATION_LINEAR_TRANSFORM) + if(scroll_speed == speed && !force) + // we're done + return + // speed diff? + scroll_speed = speed + scrolling = TRUE + // always scroll from north; turn handles everything + for(var/atom/movable/screen/parallax_layer/P in layers) + if(P.absolute) + continue + var/matrix/translate_matrix = matrix() + translate_matrix.Translate(sin(turn) * 480, cos(turn) * 480) + var/matrix/target_matrix = matrix() + var/move_speed = speed * P.speed + // do the first segment by shifting down one screen + P.transform = translate_matrix + animate(P, transform = target_matrix, time = move_speed, easing = QUAD_EASING|EASE_IN, flags = ANIMATION_END_NOW) + // queue up another incase lag makes QueueLoop not fire on time, this time by shifting up + animate(transform = translate_matrix, time = 0) + animate(transform = target_matrix, time = move_speed) + P.QueueLoop(move_speed, speed * P.speed, translate_matrix, target_matrix) + +/** + * Smoothly stops the animation, turning to a certain angle as needed. + */ +/datum/parallax_holder/proc/StopScrolling(turn = 0, time = 30) + // reset turn + if(turn != scroll_turn && GetPlaneMaster()) + var/matrix/turn_transform = matrix() + turn_transform.Turn(turn) + scroll_turn = turn + animate(GetPlaneMaster(), transform = turn_transform, time = time, easing = QUAD_EASING | EASE_OUT, flags = ANIMATION_END_NOW | ANIMATION_LINEAR_TRANSFORM) + if(scroll_speed == 0) + // we're done + scrolling = FALSE + scroll_speed = 0 + return + scrolling = FALSE + scroll_speed = 0 + // someone can do the math for "stop after a smooth iteration" later. + for(var/atom/movable/screen/parallax_layer/P in layers) + if(P.absolute) + continue + P.CancelAnimation() + var/matrix/translate_matrix = matrix() + translate_matrix.Translate(sin(turn) * 480, cos(turn) * 480) + P.transform = translate_matrix + animate(P, transform = matrix(), time = time, easing = QUAD_EASING | EASE_OUT) + +/** + * fully resets animation state + */ +/datum/parallax_holder/proc/HardResetAnimations() + // reset vars + scroll_turn = 0 + scroll_speed = 0 + scrolling = FALSE + // reset turn + if(GetPlaneMaster()) + animate(GetPlaneMaster(), transform = matrix(), time = 0, flags = ANIMATION_END_NOW) + // reset objects + for(var/atom/movable/screen/parallax_layer/P in layers) + if(P.absolute) + continue + P.CancelAnimation() + animate(P, transform = matrix(), time = 0, flags = ANIMATION_END_NOW) + +/client/proc/CreateParallax() + if(!parallax_holder) + parallax_holder = new(src) +/atom/movable/screen/parallax_vis + screen_loc = "CENTER,CENTER" diff --git a/code/_rendering/parallax/parallax_object.dm b/code/_rendering/parallax/parallax_object.dm new file mode 100644 index 0000000000..8307fc5f08 --- /dev/null +++ b/code/_rendering/parallax/parallax_object.dm @@ -0,0 +1,137 @@ + +/atom/movable/screen/parallax_layer + icon = 'icons/screen/parallax.dmi' + blend_mode = BLEND_ADD + plane = PLANE_SPACE_PARALLAX + screen_loc = "CENTER-7,CENTER-7" + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + appearance_flags = PIXEL_SCALE | KEEP_TOGETHER + + // notice - all parallax layers are 15x15 tiles. They roll over every 240 pixels. + /// pixel x/y shift per real x/y + var/speed = 1 + /// current cached offset x + var/offset_x = 0 + /// current cached offset y + var/offset_y = 0 + /// normal centered x + var/center_x = 0 + /// normal centered y + var/center_y = 0 + /// absolute - always determine shift x/y as a function of real x/y instead of allowing for relative scroll. + var/absolute = FALSE + /// parallax level required to see this + var/parallax_intensity = PARALLAX_INSANE + /// current view we're adapted to + var/view_current + /// dynamic self tile - tile to our view size. set this to false for static parallax layers. + var/dynamic_self_tile = TRUE + /// map id + var/map_id + /// queued animation timerid + var/queued_animation + +/atom/movable/screen/parallax_layer/proc/ResetPosition(x, y) + // remember that our offsets/directiosn are relative to the player's viewport + // this means we need to scroll reverse to them. + offset_x = -(center_x + speed * x) + offset_y = -(center_y + speed * y) + if(!absolute) + if(offset_x > 240) + offset_x -= 480 + if(offset_x < -240) + offset_x += 480 + if(offset_y > 240) + offset_y -= 480 + if(offset_y < -240) + offset_y += 480 + screen_loc = "[map_id && "[map_id]:"]CENTER-7:[round(offset_x,1)],CENTER-7:[round(offset_y,1)]" + +/atom/movable/screen/parallax_layer/proc/RelativePosition(x, y, rel_x, rel_y) + if(absolute) + return ResetPosition(x, y) + offset_x -= rel_x * speed + offset_y -= rel_y * speed + if(offset_x > 240) + offset_x -= 480 + if(offset_x < -240) + offset_x += 480 + if(offset_y > 240) + offset_y -= 480 + if(offset_y < -240) + offset_y += 480 + screen_loc = "[map_id && "[map_id]:"]CENTER-7:[round(offset_x,1)],CENTER-7:[round(offset_y,1)]" + +/atom/movable/screen/parallax_layer/proc/SetView(client_view = world.view, force_update = FALSE) + if(view_current == client_view && !force_update) + return + view_current = client_view + if(!dynamic_self_tile) + return + var/list/real_view = getviewsize(client_view) + var/count_x = CEILING((real_view[1] / 2) / 15, 1) + 1 + var/count_y = CEILING((real_view[2] / 2) / 15, 1) + 1 + var/list/new_overlays = GetOverlays() + for(var/x in -count_x to count_x) + for(var/y in -count_y to count_y) + if(!x && !y) + continue + var/mutable_appearance/clone = new + // appearance clone + clone.icon = icon + clone.icon_state = icon_state + clone.overlays = GetOverlays() + // do NOT inherit our overlays! parallax layers should never have overlays, + // because if it inherited us it'll result in exponentially increasing overlays + // due to cut_overlays() above over there being a queue operation and not instant! + // clone.overlays = list() + // currently instantly using overlays =. + // clone.blend_mode = blend_mode + // clone.mouse_opacity = mouse_opacity + // clone.plane = plane + // clone.layer = layer + // shift to position + clone.transform = matrix(1, 0, x * 480, 0, 1, y * 480) + new_overlays += clone + overlays = new_overlays + +/atom/movable/screen/parallax_layer/proc/ShouldSee(client/C, atom/location) + return TRUE + +/** + * Return "natural" overlays, as we're goin to do some fuckery to overlays above. + */ +/atom/movable/screen/parallax_layer/proc/GetOverlays() + return list() + +/atom/movable/screen/parallax_layer/proc/Clone() + var/atom/movable/screen/parallax_layer/layer = new type + layer.speed = speed + layer.offset_x = offset_x + layer.offset_y = offset_y + layer.absolute = absolute + layer.parallax_intensity = parallax_intensity + layer.view_current = view_current + layer.appearance = appearance + +/atom/movable/screen/parallax_layer/proc/default_x() + return center_x + +/atom/movable/screen/parallax_layer/proc/default_y() + return center_y + +/atom/movable/screen/parallax_layer/proc/QueueLoop(delay, speed, matrix/translate_matrix, matrix/target_matrix) + if(queued_animation) + CancelAnimation() + queued_animation = addtimer(CALLBACK(src, .proc/_loop, speed, translate_matrix, target_matrix), delay, TIMER_STOPPABLE) + +/atom/movable/screen/parallax_layer/proc/_loop(speed, matrix/translate_matrix = matrix(1, 0, 0, 0, 1, 480), matrix/target_matrix = matrix()) + transform = translate_matrix + animate(src, transform = target_matrix, time = speed, loop = -1) + animate(transform = translate_matrix, time = 0) + queued_animation = null + +/atom/movable/screen/parallax_layer/proc/CancelAnimation() + if(queued_animation) + deltimer(queued_animation) + queued_animation = null diff --git a/code/_rendering/parallax/types/space.dm b/code/_rendering/parallax/types/space.dm new file mode 100644 index 0000000000..1a6cf191cb --- /dev/null +++ b/code/_rendering/parallax/types/space.dm @@ -0,0 +1,66 @@ +/datum/parallax/space + var/static/planet_offset_x = rand(100, 160) + var/static/planet_offset_y = rand(100, 160) + var/static/random_layer = pickweightAllowZero(list( + /atom/movable/screen/parallax_layer/space/random/asteroids = 35, + /atom/movable/screen/parallax_layer/space/random/space_gas = 35, + null = 30 + )) + var/static/random_gas_color = pick(COLOR_TEAL, COLOR_GREEN, COLOR_YELLOW, COLOR_CYAN, COLOR_ORANGE, COLOR_PURPLE) + +/datum/parallax/space/CreateObjects() + . = ..() + . += new /atom/movable/screen/parallax_layer/space/layer_1 + . += new /atom/movable/screen/parallax_layer/space/layer_2 + . += new /atom/movable/screen/parallax_layer/space/layer_3 + var/atom/movable/screen/parallax_layer/space/planet/P = new + P.pixel_x = planet_offset_x + P.pixel_y = planet_offset_y + . += P + if(ispath(random_layer, /atom/movable/screen/parallax_layer)) + . += new random_layer + if(ispath(random_layer, /atom/movable/screen/parallax_layer/space/random/space_gas)) + var/atom/movable/screen/parallax_layer/space/random/space_gas/SG = locate(random_layer) in objects + SG.add_atom_colour(random_gas_color, ADMIN_COLOUR_PRIORITY) + +/atom/movable/screen/parallax_layer/space/layer_1 + icon_state = "layer1" + speed = 0.6 + layer = 1 + parallax_intensity = PARALLAX_LOW + +/atom/movable/screen/parallax_layer/space/layer_2 + icon_state = "layer2" + speed = 1 + layer = 2 + parallax_intensity = PARALLAX_MED + +/atom/movable/screen/parallax_layer/space/layer_3 + icon_state = "layer3" + speed = 1.4 + layer = 3 + parallax_intensity = PARALLAX_HIGH + +/atom/movable/screen/parallax_layer/space/random + blend_mode = BLEND_OVERLAY + speed = 3 + layer = 3 + parallax_intensity = PARALLAX_INSANE + +/atom/movable/screen/parallax_layer/space/random/space_gas + icon_state = "space_gas" + +/atom/movable/screen/parallax_layer/space/random/asteroids + icon_state = "asteroids" + +/atom/movable/screen/parallax_layer/space/planet + icon_state = "planet" + blend_mode = BLEND_OVERLAY + absolute = TRUE //Status of seperation + speed = 3 + layer = 30 + dynamic_self_tile = FALSE + +/atom/movable/screen/parallax_layer/space/planet/ShouldSee(client/C, atom/location) + var/turf/T = get_turf(location) + return ..() && T && is_station_level(T.z) diff --git a/code/controllers/admin.dm b/code/controllers/admin.dm index 19fef28597..5c767ecb1b 100644 --- a/code/controllers/admin.dm +++ b/code/controllers/admin.dm @@ -1,14 +1,25 @@ // Clickable stat() button. /obj/effect/statclick name = "Initializing..." + // blocks_emissive = NONE var/target INITIALIZE_IMMEDIATE(/obj/effect/statclick) -/obj/effect/statclick/Initialize(mapload, text, target) //Don't port this to Initialize it's too critical +/obj/effect/statclick/Initialize(mapload, text, target) . = ..() name = text src.target = target + if(istype(target, /datum)) //Harddel man bad + RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/cleanup) + +/obj/effect/statclick/Destroy() + target = null + return ..() + +/obj/effect/statclick/proc/cleanup() + SIGNAL_HANDLER + qdel(src) /obj/effect/statclick/proc/update(text) name = text @@ -51,3 +62,30 @@ INITIALIZE_IMMEDIATE(/obj/effect/statclick) SSblackbox.record_feedback("tally", "admin_verb", 1, "Restart Failsafe Controller") message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.") + +/client/proc/debug_controller() + set category = "Debug" + set name = "Debug Controller" + set desc = "Debug the various periodic loop controllers for the game (be careful!)" + + if(!holder) + return + + var/list/controllers = list() + var/list/controller_choices = list() + + for (var/datum/controller/controller in world) + if (istype(controller, /datum/controller/subsystem)) + continue + controllers["[controller] (controller.type)"] = controller //we use an associated list to ensure clients can't hold references to controllers + controller_choices += "[controller] (controller.type)" + + var/datum/controller/controller_string = input("Select controller to debug", "Debug Controller") as null|anything in controller_choices + var/datum/controller/controller = controllers[controller_string] + + if (!istype(controller)) + return + debug_variables(controller) + + SSblackbox.record_feedback("tally", "admin_verb", 1, "Restart Failsafe Controller") + message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.") diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm index ea5c861cd4..a162b87986 100644 --- a/code/controllers/configuration/config_entry.dm +++ b/code/controllers/configuration/config_entry.dm @@ -7,40 +7,58 @@ #define KEY_MODE_TYPE 1 /datum/config_entry - var/name //read-only, this is determined by the last portion of the derived entry type + /// Read-only, this is determined by the last portion of the derived entry type + var/name + /// The configured value for this entry. This shouldn't be initialized in code, instead set default var/config_entry_value - var/default //read-only, just set value directly - - var/resident_file //the file which this was loaded from, if any - var/modified = FALSE //set to TRUE if the default has been overridden by a config entry - - var/deprecated_by //the /datum/config_entry type that supercedes this one - + /// Read-only default value for this config entry, used for resetting value to defaults when necessary. This is what config_entry_value is initially set to + var/default + /// The file which this was loaded from, if any + var/resident_file + /// Set to TRUE if the default has been overridden by a config entry + var/modified = FALSE + /// The config name of a configuration type that depricates this, if it exists + var/deprecated_by + /// The /datum/config_entry type that supercedes this one var/protection = NONE - var/abstract_type = /datum/config_entry //do not instantiate if type matches this - - var/vv_VAS = TRUE //Force validate and set on VV. VAS proccall guard will run regardless. - var/postload_required = FALSE //requires running OnPostload() - + /// Do not instantiate if type matches this + var/abstract_type = /datum/config_entry + /// Force validate and set on VV. VAS proccall guard will run regardless. + var/vv_VAS = TRUE + /// Requires running OnPostload() + var/postload_required = FALSE + /// Controls if error is thrown when duplicate configuration values for this entry type are encountered var/dupes_allowed = FALSE + /// Stores the original protection configuration, used for set_default() + var/default_protection /datum/config_entry/New() if(type == abstract_type) CRASH("Abstract config entry [type] instatiated!") - if(!name) - name = lowertext(type2top(type)) - else - name = lowertext(name) - if(islist(config_entry_value)) - var/list/L = config_entry_value - default = L.Copy() - else - default = config_entry_value + name = lowertext(type2top(type)) + default_protection = protection + set_default() /datum/config_entry/Destroy() config.RemoveEntry(src) return ..() +/** + * Returns the value of the configuration datum to its default, used for resetting a config value. Note this also sets the protection back to default. + */ +/datum/config_entry/proc/set_default() + if ((protection & CONFIG_ENTRY_LOCKED) && IsAdminAdvancedProcCall()) + log_admin_private("[key_name(usr)] attempted to reset locked config entry [type] to its default") + return + if (islist(default)) + var/list/L = default + config_entry_value = L.Copy() + else + config_entry_value = default + protection = default_protection + resident_file = null + modified = FALSE + /datum/config_entry/can_vv_get(var_name) . = ..() if(var_name == NAMEOF(src, config_entry_value) || var_name == NAMEOF(src, default)) @@ -81,9 +99,11 @@ return /datum/config_entry/string - config_entry_value = "" + default = "" abstract_type = /datum/config_entry/string var/auto_trim = TRUE + /// whether the string will be lowercased on ValidateAndSet or not. + var/lowercase = FALSE /datum/config_entry/string/vv_edit_var(var_name, var_value) return var_name != NAMEOF(src, auto_trim) && ..() @@ -92,10 +112,12 @@ if(!VASProcCallGuard(str_val)) return FALSE config_entry_value = auto_trim ? trim(str_val) : str_val + if(lowercase) + config_entry_value = lowertext(config_entry_value) return TRUE /datum/config_entry/number - config_entry_value = 0 + default = 0 abstract_type = /datum/config_entry/number var/integer = TRUE var/max_val = INFINITY @@ -117,7 +139,7 @@ return !(var_name in banned_edits) && ..() /datum/config_entry/flag - config_entry_value = FALSE + default = FALSE abstract_type = /datum/config_entry/flag /datum/config_entry/flag/ValidateAndSet(str_val) @@ -126,9 +148,25 @@ config_entry_value = text2num(trim(str_val)) != 0 return TRUE +/// List config entry, used for configuring a list of strings +/datum/config_entry/str_list + abstract_type = /datum/config_entry/str_list + default = list() + dupes_allowed = TRUE + /// whether the string elements will be lowercased on ValidateAndSet or not. + var/lowercase = FALSE + +/datum/config_entry/str_list/ValidateAndSet(str_val) + if (!VASProcCallGuard(str_val)) + return FALSE + str_val = trim(str_val) + if (str_val != "") + config_entry_value += lowercase ? lowertext(str_val) : str_val + return TRUE + /datum/config_entry/number_list abstract_type = /datum/config_entry/number_list - config_entry_value = list() + default = list() /datum/config_entry/number_list/ValidateAndSet(str_val) if(!VASProcCallGuard(str_val)) @@ -148,13 +186,14 @@ /datum/config_entry/keyed_list abstract_type = /datum/config_entry/keyed_list - config_entry_value = list() + default = list() dupes_allowed = TRUE vv_VAS = FALSE //VAS will not allow things like deleting from lists, it'll just bug horribly. var/key_mode var/value_mode var/splitter = " " - var/lowercase = TRUE + /// whether the key names will be lowercased on ValidateAndSet or not. + var/lowercase_key = TRUE /datum/config_entry/keyed_list/New() . = ..() @@ -172,7 +211,7 @@ if(key_pos || value_mode == VALUE_MODE_FLAG) key_name = copytext(str_val, 1, key_pos) - if(lowercase) + if(lowercase_key) key_name = lowertext(key_name) if(key_pos) key_value = copytext(str_val, key_pos + length(str_val[key_pos])) @@ -231,7 +270,7 @@ /datum/config_entry/multi_keyed_flag vv_VAS = FALSE abstract_type = /datum/config_entry/multi_keyed_flag - config_entry_value = list() + default = list() var/delimiter = "|" /datum/config_entry/multi_keyed_flag/vv_edit_var(var_name, var_value) diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index 6a5a4c4610..dd50017d31 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -20,7 +20,7 @@ var/list/mode_false_report_weight var/motd - // var/policy + var/policy var/static/regex/ic_filter_regex @@ -41,7 +41,6 @@ CRASH("/datum/controller/configuration/Load() called more than once!") InitEntries() LoadModes() - storyteller_cache = typecacheof(/datum/dynamic_storyteller, TRUE) if(fexists("[directory]/config.txt") && LoadEntries("config.txt") <= 1) var/list/legacy_configs = list("game_options.txt", "dbconfig.txt", "comms.txt") for(var/I in legacy_configs) @@ -52,7 +51,7 @@ break loadmaplist(CONFIG_MAPS_FILE) LoadMOTD() - // LoadPolicy() + LoadPolicy() LoadChatFilter() if (Master) @@ -148,6 +147,16 @@ ++. continue + // Reset directive, used for setting a config value back to defaults. Useful for string list config types + if (entry == "$reset") + var/datum/config_entry/resetee = _entries[lowertext(value)] + if (!value || !resetee) + log_config("Warning: invalid $reset directive: [value]") + continue + resetee.set_default() + log_config("Reset configured value for [value] to original defaults") + continue + var/datum/config_entry/E = _entries[entry] if(!E) log_config("LINE [linenumber]: Unknown setting in configuration: '[entry]'") @@ -266,7 +275,7 @@ if(M.votable) votable_modes += M.config_tag qdel(M) - votable_modes += "secret" + votable_modes += "dynamic" /datum/controller/configuration/proc/LoadMOTD() motd = file2text("[directory]/motd.txt") @@ -292,7 +301,7 @@ Example config: } */ -/* + /datum/controller/configuration/proc/LoadPolicy() policy = list() var/rawpolicy = file2text("[directory]/policy.json") @@ -303,7 +312,7 @@ Example config: DelayedMessageAdmins("JSON parsing failure for policy.json") else policy = parsed -*/ + /datum/controller/configuration/proc/loadmaplist(filename) log_config("Loading config file [filename]...") filename = "[directory]/[filename]" @@ -371,53 +380,7 @@ Example config: var/ct = initial(M.config_tag) if(ct && ct == mode_name) return new T - return new /datum/game_mode/extended() - -/// For dynamic. -/datum/controller/configuration/proc/pick_storyteller(storyteller_name) - for(var/T in storyteller_cache) - var/datum/dynamic_storyteller/S = T - var/name = initial(S.name) - if(name && name == storyteller_name) - return T - return /datum/dynamic_storyteller/classic - -/// Same with this -/datum/controller/configuration/proc/get_runnable_storytellers() - var/list/datum/dynamic_storyteller/runnable_storytellers = new - var/list/probabilities = Get(/datum/config_entry/keyed_list/storyteller_weight) - var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust) - var/list/min_player_counts = Get(/datum/config_entry/keyed_list/storyteller_min_players) - var/list/storyteller_min_chaos = Get(/datum/config_entry/keyed_list/storyteller_min_chaos) - var/list/storyteller_max_chaos = Get(/datum/config_entry/keyed_list/storyteller_max_chaos) - for(var/T in storyteller_cache) - var/datum/dynamic_storyteller/S = T - var/config_tag = initial(S.config_tag) - if(!config_tag) - continue - var/probability = (config_tag in probabilities) ? probabilities[config_tag] : initial(S.weight) - var/min_players = (config_tag in min_player_counts) ? min_player_counts[config_tag] : initial(S.min_players) - if(probability <= 0) - continue - if(length(GLOB.player_list) < min_players) - continue - if(!Get(/datum/config_entry/flag/no_storyteller_threat_removal)) - var/min_chaos = (probabilities in storyteller_min_chaos) ? storyteller_min_chaos[config_tag] : initial(S.min_chaos) - var/max_chaos = (probabilities in storyteller_max_chaos) ? storyteller_max_chaos[config_tag] : initial(S.max_chaos) - if(SSpersistence.average_threat + 50 < min_chaos) - continue - if(SSpersistence.average_threat + 50 > max_chaos) - continue - if(SSpersistence.saved_storytellers.len == repeated_mode_adjust.len) - var/name = initial(S.name) - var/recent_round = min(SSpersistence.saved_storytellers.Find(name),3) - var/adjustment = 0 - while(recent_round) - adjustment += repeated_mode_adjust[recent_round] - recent_round = SSpersistence.saved_modes.Find(name,recent_round+1,0) - probability *= max(0,((100-adjustment)/100)) - runnable_storytellers[S] = probability - return runnable_storytellers + return new /datum/game_mode/dynamic /datum/controller/configuration/proc/get_runnable_modes() var/list/datum/game_mode/runnable_modes = new diff --git a/code/controllers/configuration/entries/admin.dm b/code/controllers/configuration/entries/admin.dm index 3b5b437742..8c957baf4c 100644 --- a/code/controllers/configuration/entries/admin.dm +++ b/code/controllers/configuration/entries/admin.dm @@ -23,12 +23,12 @@ /datum/config_entry/flag/see_own_notes //Can players see their own admin notes /datum/config_entry/number/note_fresh_days - config_entry_value = null + default = null min_val = 0 integer = FALSE /datum/config_entry/number/note_stale_days - config_entry_value = null + default = null min_val = 0 integer = FALSE @@ -39,13 +39,15 @@ /datum/config_entry/flag/announce_admin_login -/datum/config_entry/string/centcom_ban_db // URL for the CentCom Galactic Ban DB API +/datum/config_entry/string/centcom_ban_db // URL for the CentCom Galactic Ban DB API + +/datum/config_entry/string/centcom_source_whitelist /datum/config_entry/flag/autoadmin // if autoadmin is enabled protection = CONFIG_ENTRY_LOCKED /datum/config_entry/string/autoadmin_rank // the rank for autoadmins - config_entry_value = "Game Master" + default = "Game Master" protection = CONFIG_ENTRY_LOCKED /datum/config_entry/flag/allow_admin_ooccolor // Allows admins with relevant permissions to have their own ooc colour @@ -62,3 +64,18 @@ /datum/config_entry/flag/automute_on //enables automuting/spam prevention /datum/config_entry/flag/debug_admin_hrefs + +/datum/config_entry/flag/auto_deadmin_players + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/auto_deadmin_antagonists + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/auto_deadmin_heads + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/auto_deadmin_silicons + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/auto_deadmin_security + protection = CONFIG_ENTRY_LOCKED diff --git a/code/controllers/configuration/entries/alert.dm b/code/controllers/configuration/entries/alert.dm index 6177c602db..af49972007 100644 --- a/code/controllers/configuration/entries/alert.dm +++ b/code/controllers/configuration/entries/alert.dm @@ -1,26 +1,26 @@ /datum/config_entry/string/alert_green - config_entry_value = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced." + default = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced." /datum/config_entry/string/alert_blue_upto - config_entry_value = "The station has received reliable information about potential threats to the station. Security staff may have weapons visible, random searches are permitted." + default = "The station has received reliable information about potential threats to the station. Security staff may have weapons visible, random searches are permitted." /datum/config_entry/string/alert_blue_downto - config_entry_value = "Significant confirmed threats have been neutralized. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still permitted." + default = "Significant confirmed threats have been neutralized. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still permitted." /datum/config_entry/string/alert_amber_upto - config_entry_value = "There are significant confirmed threats to the station. Security staff may have weapons unholstered at all times. Random searches are allowed and advised." + default = "There are significant confirmed threats to the station. Security staff may have weapons unholstered at all times. Random searches are allowed and advised." /datum/config_entry/string/alert_amber_downto - config_entry_value = "The immediate threat has passed. Security is no longer authorized to use lethal force, but may continue to have weapons drawn. Access requirements have been restored." + default = "The immediate threat has passed. Security is no longer authorized to use lethal force, but may continue to have weapons drawn. Access requirements have been restored." /datum/config_entry/string/alert_red_upto - config_entry_value = "There is an immediate serious threat to the station. Security is now authorized to use lethal force. Additionally, access requirements on some machines have been lifted." + default = "There is an immediate serious threat to the station. Security is now authorized to use lethal force. Additionally, access requirements on some machines have been lifted." /datum/config_entry/string/alert_red_downto - config_entry_value = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security is still authorized to use lethal force." + default = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security is still authorized to use lethal force." /datum/config_entry/string/alert_delta - config_entry_value = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill." + default = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill." /datum/config_entry/number/minimum_secborg_alert //Minimum alert level for secborgs to be chosen. - config_entry_value = 3 + default = 3 diff --git a/code/controllers/configuration/entries/antag_rep.dm b/code/controllers/configuration/entries/antag_rep.dm index c34eef4159..1ecbe57b45 100644 --- a/code/controllers/configuration/entries/antag_rep.dm +++ b/code/controllers/configuration/entries/antag_rep.dm @@ -1,15 +1,15 @@ /datum/config_entry/flag/use_antag_rep // see game_options.txt for details /datum/config_entry/number/antag_rep_maximum - config_entry_value = 200 + default = 200 min_val = 0 /datum/config_entry/number/default_antag_tickets - config_entry_value = 100 + default = 100 min_val = 0 /datum/config_entry/number/max_tickets_per_roll - config_entry_value = 100 + default = 100 min_val = 0 /datum/config_entry/keyed_list/antag_rep diff --git a/code/controllers/configuration/entries/bot.dm b/code/controllers/configuration/entries/bot.dm new file mode 100644 index 0000000000..08b3ef57bd --- /dev/null +++ b/code/controllers/configuration/entries/bot.dm @@ -0,0 +1,14 @@ +/datum/config_entry/flag/irc_announce_new_game + deprecated_by = /datum/config_entry/string/chat_announce_new_game + +/datum/config_entry/flag/irc_announce_new_game/DeprecationUpdate(value) + return "" //default broadcast + +/datum/config_entry/string/chat_announce_new_game + default = null + +/datum/config_entry/string/chat_reboot_role + +/datum/config_entry/string/chat_roundend_notice_tag + +/datum/config_entry/string/chat_squawk_tag diff --git a/code/controllers/configuration/entries/comms.dm b/code/controllers/configuration/entries/comms.dm index 00f1cedf4f..67d214e1c2 100644 --- a/code/controllers/configuration/entries/comms.dm +++ b/code/controllers/configuration/entries/comms.dm @@ -8,6 +8,7 @@ key_mode = KEY_MODE_TEXT value_mode = VALUE_MODE_TEXT protection = CONFIG_ENTRY_LOCKED + lowercase_key = FALSE // The names of the servers are proper nouns. Also required for the cross_comms_name config to work. /datum/config_entry/keyed_list/cross_server/ValidateAndSet(str_val) . = ..() diff --git a/code/controllers/configuration/entries/connections.dm b/code/controllers/configuration/entries/connections.dm index acdf588e5a..afbe94840a 100644 --- a/code/controllers/configuration/entries/connections.dm +++ b/code/controllers/configuration/entries/connections.dm @@ -1,9 +1,15 @@ /datum/config_entry/flag/panic_bunker // prevents people the server hasn't seen before from connecting -/datum/config_entry/number/panic_bunker_living // living time in minutes that a player needs to pass the panic bunker +/datum/config_entry/number/panic_bunker_living // living time in minutes that a player needs to pass the panic bunker. they pass **if they are above this amount** + default = 0 // default: <= 0 meaning any playtime works. -1 to disable criteria. + integer = TRUE + +/datum/config_entry/number/panic_bunker_living_vpn + default = 0 // default: <= 0 meaning anytime works. -1 to disable criteria. + integer = TRUE /datum/config_entry/string/panic_bunker_message - config_entry_value = "Sorry but the server is currently not accepting connections from never before seen players." + default = "Sorry but the server is currently not accepting connections from never before seen players." /datum/config_entry/string/panic_server_name @@ -16,7 +22,7 @@ return str_val != "byond://address:port" && ..() /datum/config_entry/number/max_bunker_days - config_entry_value = 7 + default = 7 min_val = 1 /datum/config_entry/number/notify_new_player_age // how long do we notify admins of a new player @@ -26,7 +32,6 @@ min_val = 0 /datum/config_entry/flag/age_verification //are we using the automated age verification which asks users if they're 18+? - config_entry_value = TRUE /datum/config_entry/flag/irc_first_connection_alert // do we notify the irc channel when somebody is connecting for the first time? @@ -38,21 +43,21 @@ return str_val != "ch@nge.me" && ..() /datum/config_entry/number/ipintel_rating_bad - config_entry_value = 1 + default = 1 integer = FALSE min_val = 0 max_val = 1 /datum/config_entry/number/ipintel_save_good - config_entry_value = 12 + default = 12 min_val = 0 /datum/config_entry/number/ipintel_save_bad - config_entry_value = 1 + default = 1 min_val = 0 /datum/config_entry/string/ipintel_domain - config_entry_value = "check.getipintel.net" + default = "check.getipintel.net" /datum/config_entry/flag/aggressive_changelog @@ -61,46 +66,46 @@ /datum/config_entry/flag/webclient_only_byond_members /datum/config_entry/number/client_warn_version - config_entry_value = null + default = null min_val = 500 /datum/config_entry/number/client_warn_version - config_entry_value = null + default = null min_val = 500 /datum/config_entry/string/client_warn_message - config_entry_value = "Your version of byond may have issues or be blocked from accessing this server in the future." + default = "Your version of byond may have issues or be blocked from accessing this server in the future." /datum/config_entry/flag/client_warn_popup /datum/config_entry/number/client_error_version - config_entry_value = null + default = null min_val = 500 /datum/config_entry/string/client_error_message - config_entry_value = "Your version of byond is too old, may have issues, and is blocked from accessing this server." + default = "Your version of byond is too old, may have issues, and is blocked from accessing this server." /datum/config_entry/number/client_error_build - config_entry_value = null + default = null min_val = 0 /datum/config_entry/number/soft_popcap - config_entry_value = null + default = null min_val = 0 /datum/config_entry/number/hard_popcap - config_entry_value = null + default = null min_val = 0 /datum/config_entry/number/extreme_popcap - config_entry_value = null + default = null min_val = 0 /datum/config_entry/string/soft_popcap_message - config_entry_value = "Be warned that the server is currently serving a high number of users, consider using alternative game servers." + default = "Be warned that the server is currently serving a high number of users, consider using alternative game servers." /datum/config_entry/string/hard_popcap_message - config_entry_value = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers." + default = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers." /datum/config_entry/string/extreme_popcap_message - config_entry_value = "The server is currently serving a high number of users, find alternative servers." + default = "The server is currently serving a high number of users, find alternative servers." diff --git a/code/controllers/configuration/entries/dbconfig.dm b/code/controllers/configuration/entries/dbconfig.dm index 3dd4f4b0bd..a267a70633 100644 --- a/code/controllers/configuration/entries/dbconfig.dm +++ b/code/controllers/configuration/entries/dbconfig.dm @@ -2,21 +2,21 @@ protection = CONFIG_ENTRY_LOCKED /datum/config_entry/string/address - config_entry_value = "localhost" + default = "localhost" protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN /datum/config_entry/number/port - config_entry_value = 3306 + default = 3306 min_val = 0 max_val = 65535 protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN /datum/config_entry/string/feedback_database - config_entry_value = "test" + default = "test" protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN /datum/config_entry/string/feedback_login - config_entry_value = "root" + default = "root" protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN /datum/config_entry/string/feedback_password @@ -26,7 +26,7 @@ protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN /datum/config_entry/number/query_debug_log_timeout - config_entry_value = 70 + default = 70 min_val = 1 protection = CONFIG_ENTRY_LOCKED deprecated_by = /datum/config_entry/number/blocking_query_timeout @@ -35,17 +35,17 @@ return value /datum/config_entry/number/async_query_timeout - config_entry_value = 10 + default = 10 min_val = 0 protection = CONFIG_ENTRY_LOCKED /datum/config_entry/number/blocking_query_timeout - config_entry_value = 5 + default = 5 min_val = 0 protection = CONFIG_ENTRY_LOCKED /datum/config_entry/number/bsql_thread_limit - config_entry_value = 50 + default = 50 min_val = 1 /datum/config_entry/flag/bsql_debug diff --git a/code/controllers/configuration/entries/debris.dm b/code/controllers/configuration/entries/debris.dm index 1cc2c2d7b7..4b7b2ac50e 100644 --- a/code/controllers/configuration/entries/debris.dm +++ b/code/controllers/configuration/entries/debris.dm @@ -1,16 +1,16 @@ /// Amount of dirtyness tiles need to spawn dirt. /datum/config_entry/number/turf_dirt_threshold - config_entry_value = 100 + default = 100 min_val = 1 integer = TRUE /// Alpha dirt starts at /datum/config_entry/number/dirt_alpha_starting - config_entry_value = 127 + default = 127 max_val = 255 min_val = 0 integer = TRUE /// Dirtyness multiplier for making turfs dirty /datum/config_entry/number/turf_dirty_multiplier - config_entry_value = 1 + default = 1 diff --git a/code/controllers/configuration/entries/dynamic.dm b/code/controllers/configuration/entries/dynamic.dm index 935164352e..573507fe8d 100644 --- a/code/controllers/configuration/entries/dynamic.dm +++ b/code/controllers/configuration/entries/dynamic.dm @@ -3,43 +3,43 @@ /datum/config_entry/flag/no_storyteller_threat_removal /datum/config_entry/number/dynamic_high_pop_limit - config_entry_value = 55 + default = 55 min_val = 1 /datum/config_entry/number/dynamic_pop_per_requirement - config_entry_value = 6 + default = 6 min_val = 1 /datum/config_entry/number/dynamic_midround_delay_min - config_entry_value = 15 + default = 15 min_val = 1 /datum/config_entry/number/dynamic_midround_delay_max - config_entry_value = 35 + default = 35 min_val = 1 /datum/config_entry/number/dynamic_latejoin_delay_min - config_entry_value = 5 + default = 5 min_val = 1 /datum/config_entry/number/dynamic_latejoin_delay_max - config_entry_value = 25 + default = 25 min_val = 1 /datum/config_entry/number/dynamic_first_midround_delay_min - config_entry_value = 20 + default = 20 min_val = 1 /datum/config_entry/number/dynamic_first_midround_delay_max - config_entry_value = 40 + default = 40 min_val = 1 /datum/config_entry/number/dynamic_first_latejoin_delay_min - config_entry_value = 10 + default = 10 min_val = 1 /datum/config_entry/number/dynamic_first_latejoin_delay_max - config_entry_value = 30 + default = 30 min_val = 1 @@ -64,36 +64,40 @@ /datum/config_entry/number_list/dynamic_third_rule_requirements /datum/config_entry/number/dynamic_second_rule_high_pop_requirement - config_entry_value = 50 + default = 50 /datum/config_entry/number/dynamic_third_rule_high_pop_requirement - config_entry_value = 70 + default = 70 /datum/config_entry/number/dynamic_threat_baseline - config_entry_value = 50 + default = 50 /datum/config_entry/number_list/dynamic_hijack_requirements /datum/config_entry/number/dynamic_hijack_high_population_requirement - config_entry_value = 25 + default = 25 /datum/config_entry/number/dynamic_hijack_cost - config_entry_value = 5 + default = 5 /datum/config_entry/number/dynamic_glorious_death_cost - config_entry_value = 5 + default = 5 /datum/config_entry/number/dynamic_assassinate_cost - config_entry_value = 2 + default = 2 /datum/config_entry/number/dynamic_warops_requirement - config_entry_value = 60 + default = 60 min_val = 0 /datum/config_entry/number/dynamic_warops_cost - config_entry_value = 10 + default = 10 min_val = 0 +/datum/config_entry/keyed_list/dynamic_mode_days + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_FLAG + /datum/config_entry/keyed_list/storyteller_weight key_mode = KEY_MODE_TEXT value_mode = VALUE_MODE_NUM diff --git a/code/controllers/configuration/entries/fetish_content.dm b/code/controllers/configuration/entries/fetish_content.dm index 1de796a11d..f15b815eb1 100644 --- a/code/controllers/configuration/entries/fetish_content.dm +++ b/code/controllers/configuration/entries/fetish_content.dm @@ -1,30 +1,38 @@ /datum/config_entry/keyed_list/breasts_cups_prefs key_mode = KEY_MODE_TEXT value_mode = VALUE_MODE_FLAG - config_entry_value = list("a", "b", "c", "d", "e") //keep these lowercase + default = list("a", "b", "c", "d", "e") //keep these lowercase /datum/config_entry/number/penis_min_inches_prefs - config_entry_value = 1 + default = 1 min_val = 0 /datum/config_entry/number/penis_max_inches_prefs - config_entry_value = 20 + default = 20 min_val = 0 -/datum/config_entry/keyed_list/safe_visibility_toggles - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_FLAG - config_entry_value = list(GEN_VISIBLE_NO_CLOTHES, GEN_VISIBLE_NO_UNDIES, GEN_VISIBLE_NEVER) //refer to cit_helpers for all toggles. +/datum/config_entry/number/butt_min_size_prefs + default = 1 + min_val = 0 + max_val = BUTT_SIZE_MAX + +/datum/config_entry/number/butt_max_size_prefs + default = BUTT_SIZE_MAX + min_val = 0 + max_val = BUTT_SIZE_MAX + +//set only by the configs to be able to manipulate easily +/datum/config_entry/str_list/safe_visibility_toggles //Body size configs, the feature will be disabled if both min and max have the same value. /datum/config_entry/number/body_size_min - config_entry_value = 0.9 + default = 0.9 min_val = 0.1 //to avoid issues with zeros and negative values. max_val = RESIZE_DEFAULT_SIZE integer = FALSE /datum/config_entry/number/body_size_max - config_entry_value = 1.25 + default = 1.25 min_val = RESIZE_DEFAULT_SIZE integer = FALSE @@ -32,7 +40,7 @@ //to compensate for their smaller hitbox. //To disable, just make sure the value is lower than 'body_size_min' /datum/config_entry/number/threshold_body_size_penalty - config_entry_value = RESIZE_DEFAULT_SIZE + default = RESIZE_DEFAULT_SIZE min_val = 0 max_val = RESIZE_DEFAULT_SIZE integer = FALSE @@ -40,6 +48,6 @@ //multiplicative slowdown multiplier. See 'dna.update_body_size' for the operation. //doesn't apply to floating or crawling mobs /datum/config_entry/number/body_size_slowdown_multiplier - config_entry_value = 0 + default = 0 min_val = 0 integer = FALSE diff --git a/code/controllers/configuration/entries/gamemodes.dm b/code/controllers/configuration/entries/gamemodes.dm index f11c6dd5f5..e9eb8b8797 100644 --- a/code/controllers/configuration/entries/gamemodes.dm +++ b/code/controllers/configuration/entries/gamemodes.dm @@ -3,7 +3,7 @@ /datum/config_entry/flag/weigh_by_recent_chaos /datum/config_entry/number/chaos_exponent - config_entry_value = 1 + default = 1 /datum/config_entry/keyed_list/probability key_mode = KEY_MODE_TEXT @@ -55,36 +55,36 @@ return key_name in config.modes /datum/config_entry/number/traitor_scaling_coeff //how much does the amount of players get divided by to determine traitors - config_entry_value = 6 + default = 6 min_val = 1 /datum/config_entry/number/brother_scaling_coeff //how many players per brother team - config_entry_value = 25 + default = 25 min_val = 1 /datum/config_entry/number/changeling_scaling_coeff //how much does the amount of players get divided by to determine changelings - config_entry_value = 6 + default = 6 min_val = 1 /datum/config_entry/number/ecult_scaling_coeff //how much does the amount of players get divided by to determine e_cult - config_entry_value = 6 + default = 6 integer = FALSE min_val = 1 /datum/config_entry/number/security_scaling_coeff //how much does the amount of players get divided by to determine open security officer positions - config_entry_value = 8 + default = 8 min_val = 1 /datum/config_entry/number/abductor_scaling_coeff //how many players per abductor team - config_entry_value = 15 + default = 15 min_val = 1 /datum/config_entry/number/traitor_objectives_amount - config_entry_value = 2 + default = 2 min_val = 0 /datum/config_entry/number/brother_objectives_amount - config_entry_value = 2 + default = 2 min_val = 0 /datum/config_entry/flag/protect_roles_from_antagonist //If security and such can be traitor/cult/other diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index 8ecd7c0c60..f7c864a89f 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -1,9 +1,9 @@ /datum/config_entry/number/lobby_countdown // In between round countdown. - config_entry_value = 120 + default = 120 min_val = 0 /datum/config_entry/number/round_end_countdown // Post round murder death kill countdown - config_entry_value = 25 + default = 25 min_val = 0 @@ -12,11 +12,11 @@ /datum/config_entry/flag/allow_holidays /datum/config_entry/number/id_console_jobslot_delay - config_entry_value = 30 + default = 30 min_val = 0 /datum/config_entry/number/inactivity_period //time in ds until a player is considered inactive - config_entry_value = 3000 + default = 3000 min_val = 0 /datum/config_entry/number/inactivity_period/ValidateAndSet(str_val) @@ -25,7 +25,7 @@ config_entry_value *= 10 //documented as seconds in config.txt /datum/config_entry/number/afk_period //time in ds until a player is considered inactive - config_entry_value = 3000 + default = 3000 min_val = 0 /datum/config_entry/number/afk_period/ValidateAndSet(str_val) @@ -39,30 +39,20 @@ /datum/config_entry/flag/show_irc_name -/datum/config_entry/flag/irc_announce_new_game - deprecated_by = /datum/config_entry/string/chat_announce_new_game - -/datum/config_entry/flag/irc_announce_new_game/DeprecationUpdate(value) - return "" //default broadcast - -/datum/config_entry/string/chat_announce_new_game - - config_entry_value = null - /datum/config_entry/string/default_view - config_entry_value = "15x15" + default = "15x15" /datum/config_entry/string/default_view_square - config_entry_value = "15x15" + default = "15x15" /datum/config_entry/flag/minimaps_enabled - config_entry_value = TRUE + default = TRUE /datum/config_entry/number/damage_multiplier - config_entry_value = 1 + default = 1 integer = FALSE /datum/config_entry/number/minimal_access_threshold //If the number of players is larger than this threshold, minimal access will be turned on. @@ -103,25 +93,25 @@ /datum/config_entry/flag/enforce_human_authority //If non-human species are barred from joining as a head of staff /datum/config_entry/number/midround_antag_time_check // How late (in minutes you want the midround antag system to stay on, setting this to 0 will disable the system) - config_entry_value = 60 + default = 60 min_val = 0 /datum/config_entry/number/midround_antag_life_check // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist - config_entry_value = 0.7 + default = 0.7 integer = FALSE min_val = 0 max_val = 1 /datum/config_entry/number/suicide_reenter_round_timer - config_entry_value = 30 + default = 30 min_val = 0 /datum/config_entry/number/roundstart_suicide_time_limit - config_entry_value = 30 + default = 30 min_val = 0 /datum/config_entry/number/shuttle_refuel_delay - config_entry_value = 12000 + default = 12000 min_val = 0 /datum/config_entry/flag/show_game_type_odds //if set this allows players to see the odds of each roundtype on the get revision screen @@ -143,7 +133,7 @@ /datum/config_entry/flag/no_intercept_report //Whether or not to send a communications intercept report roundstart. This may be overridden by gamemodes. /datum/config_entry/number/arrivals_shuttle_dock_window //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station - config_entry_value = 55 + default = 55 min_val = 30 /datum/config_entry/flag/arrivals_shuttle_require_undocked //Require the arrivals shuttle to be undocked before latejoiners can join @@ -156,7 +146,7 @@ /datum/config_entry/flag/revival_cloning /datum/config_entry/number/revival_brain_life - config_entry_value = -1 + default = -1 min_val = -1 /datum/config_entry/flag/ooc_during_round @@ -168,7 +158,7 @@ /datum/config_entry/flag/roundstart_vr //Will virtual reality missions be loaded? /datum/config_entry/number/gateway_delay //How long the gateway takes before it activates. Default is half an hour. Only matters if roundstart_away is enabled. - config_entry_value = 18000 + default = 18000 min_val = 0 /datum/config_entry/flag/ghost_interaction @@ -179,12 +169,12 @@ /datum/config_entry/flag/sandbox_autoclose // close the sandbox panel after spawning an item, potentially reducing griff /datum/config_entry/number/default_laws //Controls what laws the AI spawns with. - config_entry_value = 0 + default = 0 min_val = 0 max_val = 3 /datum/config_entry/number/silicon_max_law_amount - config_entry_value = 12 + default = 12 min_val = 0 /datum/config_entry/keyed_list/random_laws @@ -197,50 +187,50 @@ splitter = "," /datum/config_entry/number/overflow_cap - config_entry_value = -1 + default = -1 min_val = -1 /datum/config_entry/string/overflow_job - config_entry_value = "Assistant" + default = "Assistant" /datum/config_entry/flag/starlight /datum/config_entry/flag/grey_assistants /datum/config_entry/number/lavaland_budget - config_entry_value = 60 + default = 60 min_val = 0 /datum/config_entry/number/space_budget - config_entry_value = 16 + default = 16 min_val = 0 /datum/config_entry/number/icemoon_budget - config_entry_value = 90 + default = 90 integer = FALSE min_val = 0 /datum/config_entry/number/station_space_budget - config_entry_value = 10 + default = 10 min_val = 0 /datum/config_entry/flag/allow_random_events // Enables random events mid-round when set /datum/config_entry/number/events_min_time_mul // Multipliers for random events minimal starting time and minimal players amounts - config_entry_value = 1 + default = 1 min_val = 0 integer = FALSE /datum/config_entry/number/events_min_players_mul - config_entry_value = 1 + default = 1 min_val = 0 integer = FALSE /datum/config_entry/number/mice_roundstart - config_entry_value = 10 + default = 10 min_val = 0 /datum/config_entry/number/bombcap - config_entry_value = 14 + default = 14 min_val = 4 /datum/config_entry/number/bombcap/ValidateAndSet(str_val) @@ -264,40 +254,40 @@ /datum/config_entry/flag/enable_night_shifts /datum/config_entry/number/night_shift_public_areas_only - config_entry_value = NIGHTSHIFT_AREA_PUBLIC + default = NIGHTSHIFT_AREA_PUBLIC /datum/config_entry/flag/nightshift_toggle_requires_auth - config_entry_value = FALSE + default = FALSE /datum/config_entry/flag/nightshift_toggle_public_requires_auth - config_entry_value = TRUE + default = TRUE /datum/config_entry/flag/randomize_shift_time /datum/config_entry/flag/shift_time_realtime /datum/config_entry/number/monkeycap - config_entry_value = 64 + default = 64 min_val = 0 /datum/config_entry/number/ratcap - config_entry_value = 64 + default = 64 min_val = 0 /datum/config_entry/keyed_list/box_random_engine key_mode = KEY_MODE_TEXT value_mode = VALUE_MODE_NUM - lowercase = FALSE + lowercase_key = FALSE splitter = "," /datum/config_entry/flag/pai_custom_holoforms /datum/config_entry/number/marauder_delay_non_reebe - config_entry_value = 1800 + default = 1800 min_val = 0 /datum/config_entry/flag/allow_clockwork_marauder_on_station - config_entry_value = TRUE + default = TRUE /datum/config_entry/flag/suicide_allowed @@ -307,7 +297,7 @@ ///Initial loadout points /datum/config_entry/number/initial_gear_points - config_entry_value = 10 + default = 10 /** * Enables the FoV component, which hides objects and mobs behind the parent from their sight, unless they turn around, duh. @@ -317,19 +307,43 @@ //Shuttle size limiter /datum/config_entry/number/max_shuttle_count - config_entry_value = 6 + default = 6 /datum/config_entry/number/max_shuttle_size - config_entry_value = 500 + default = 500 //wound config stuff (increases the max injury roll, making injuries more likely) /datum/config_entry/number/wound_exponent - config_entry_value = WOUND_DAMAGE_EXPONENT + default = WOUND_DAMAGE_EXPONENT min_val = 0 integer = FALSE //adds a set amount to any injury rolls on a limb using get_damage() multiplied by this number /datum/config_entry/number/wound_damage_multiplier - config_entry_value = 0.333 + default = 0.333 min_val = 0 integer = FALSE + +/datum/config_entry/number/hard_deletes_overrun_threshold + integer = FALSE + min_val = 0 + default = 0.5 + +/datum/config_entry/number/hard_deletes_overrun_limit + default = 0 + min_val = 0 + +/datum/config_entry/flag/atmos_equalize_enabled + default = FALSE + +/datum/config_entry/flag/dynamic_config_enabled + +/datum/config_entry/flag/station_name_needs_approval + +//ambition start +/datum/config_entry/number/max_ambitions // Maximum number of ambitions a mind can store. + default = 5 +//ambition end + +/datum/config_entry/str_list/randomizing_station_name_message + default = list() diff --git a/code/controllers/configuration/entries/jexp.dm b/code/controllers/configuration/entries/jexp.dm index 3d9754b4a6..acd71fcfb4 100644 --- a/code/controllers/configuration/entries/jexp.dm +++ b/code/controllers/configuration/entries/jexp.dm @@ -7,7 +7,7 @@ /datum/config_entry/flag/use_exp_restrictions_heads /datum/config_entry/number/use_exp_restrictions_heads_hours - config_entry_value = 0 + default = 0 min_val = 0 /datum/config_entry/flag/use_exp_restrictions_heads_department diff --git a/code/controllers/configuration/entries/logging.dm b/code/controllers/configuration/entries/logging.dm index 25ca145939..573d6e1ac7 100644 --- a/code/controllers/configuration/entries/logging.dm +++ b/code/controllers/configuration/entries/logging.dm @@ -1,84 +1,127 @@ -/datum/config_entry/flag/log_ooc // log OOC channel - config_entry_value = TRUE +/// log OOC channel +/datum/config_entry/flag/log_ooc + default = TRUE -/datum/config_entry/flag/log_access // log login/logout - config_entry_value = TRUE +/// log login/logout +/datum/config_entry/flag/log_access + default = TRUE -/datum/config_entry/flag/log_say // log client say - config_entry_value = TRUE +/// Config entry which special logging of failed logins under suspicious circumstances. +/datum/config_entry/flag/log_suspicious_login + default = TRUE -/datum/config_entry/flag/log_admin // log admin actions +/// log client say +/datum/config_entry/flag/log_say + default = TRUE + +/// log admin actions +/datum/config_entry/flag/log_admin protection = CONFIG_ENTRY_LOCKED - config_entry_value = TRUE + default = TRUE -/datum/config_entry/flag/log_prayer // log prayers - config_entry_value = TRUE +/// log prayers +/datum/config_entry/flag/log_prayer + default = TRUE -/datum/config_entry/flag/log_law // log lawchanges - config_entry_value = TRUE +/// log lawchanges +/datum/config_entry/flag/log_law + default = TRUE -/datum/config_entry/flag/log_game // log game events - config_entry_value = TRUE +/// log game events +/datum/config_entry/flag/log_game + default = TRUE -/datum/config_entry/flag/log_virus // log virology data - config_entry_value = TRUE +/// log mech data +/datum/config_entry/flag/log_mecha + default = TRUE -/datum/config_entry/flag/log_vote // log voting - config_entry_value = TRUE +/// log virology data +/datum/config_entry/flag/log_virus + default = TRUE -/datum/config_entry/flag/log_craft // log crafting - config_entry_value = TRUE +/// log voting +/datum/config_entry/flag/log_vote + default = TRUE -/datum/config_entry/flag/log_whisper // log client whisper - config_entry_value = TRUE +/// log crafting +/datum/config_entry/flag/log_craft + default = TRUE -/datum/config_entry/flag/log_attack // log attack messages - config_entry_value = TRUE +/// log client whisper +/datum/config_entry/flag/log_whisper + default = TRUE -/datum/config_entry/flag/log_emote // log emotes - config_entry_value = TRUE +/// log attack messages +/datum/config_entry/flag/log_attack + default = TRUE -/datum/config_entry/flag/log_adminchat // log admin chat messages +/// log attack messages +/datum/config_entry/flag/log_victim + default = TRUE + +/// log emotes +/datum/config_entry/flag/log_emote + default = TRUE + +/// log admin chat messages +/datum/config_entry/flag/log_adminchat protection = CONFIG_ENTRY_LOCKED -/datum/config_entry/flag/log_shuttle // log shuttle related actions, ie shuttle computers, shuttle manipulator, emergency console - config_entry_value = TRUE +/// log shuttle related actions, ie shuttle computers, shuttle manipulator, emergency console +/datum/config_entry/flag/log_shuttle + default = TRUE -/datum/config_entry/flag/log_pda // log pda messages - config_entry_value = TRUE +/// log pda messages +/datum/config_entry/flag/log_pda + default = TRUE -/datum/config_entry/flag/log_telecomms // log telecomms messages - config_entry_value = TRUE +/// log telecomms messages +/datum/config_entry/flag/log_telecomms + default = TRUE -/datum/config_entry/flag/log_twitter // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. - config_entry_value = TRUE +/// log economy +/datum/config_entry/flag/log_econ + default = TRUE -/datum/config_entry/flag/log_world_topic // log all world.Topic() calls - config_entry_value = TRUE +/// log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. +/datum/config_entry/flag/log_twitter + default = TRUE -/datum/config_entry/flag/log_manifest // log crew manifest to seperate file - config_entry_value = TRUE +/// log all world.Topic() calls +/datum/config_entry/flag/log_world_topic + default = TRUE -/datum/config_entry/flag/log_job_debug // log roundstart divide occupations debug information to a file - config_entry_value = TRUE +/// log crew manifest to seperate file +/datum/config_entry/flag/log_manifest + default = TRUE +/// log roundstart divide occupations debug information to a file +/datum/config_entry/flag/log_job_debug + default = TRUE + +/// log photos taken by players with a camera /datum/config_entry/flag/log_pictures +/// This is... shitcode, literally same as above, if one of them is inactive, won't log at all, PLEASE FUCKING REMOVE THIS. /datum/config_entry/flag/picture_logging_camera /// forces log_href for tgui /datum/config_entry/flag/emergency_tgui_logging - config_entry_value = FALSE + default = FALSE -/datum/config_entry/number/error_cooldown // The "cooldown" time for each occurrence of a unique error - config_entry_value = 600 +/// The "cooldown" time for each occurrence of a unique error +/datum/config_entry/number/error_cooldown + default = 600 min_val = 0 -/datum/config_entry/number/error_limit // How many occurrences before the next will silence them - config_entry_value = 50 +/// How many occurrences before the next will silence them +/datum/config_entry/number/error_limit + default = 50 -/datum/config_entry/number/error_silence_time // How long a unique error will be silenced for - config_entry_value = 6000 +/// How long a unique error will be silenced for +/datum/config_entry/number/error_silence_time + default = 6000 -/datum/config_entry/number/error_msg_delay // How long to wait between messaging admins about occurrences of a unique error - config_entry_value = 50 +/// How long to wait between messaging admins about occurrences of a unique error +/datum/config_entry/number/error_msg_delay + default = 50 diff --git a/code/controllers/configuration/entries/movespeed.dm b/code/controllers/configuration/entries/movespeed.dm index b1c3818cd3..18d54da9fc 100644 --- a/code/controllers/configuration/entries/movespeed.dm +++ b/code/controllers/configuration/entries/movespeed.dm @@ -15,7 +15,7 @@ /datum/config_entry/keyed_list/multiplicative_movespeed/normal name = "multiplicative_movespeed" - config_entry_value = list( //DEFAULTS + default = list( //DEFAULTS /mob/living/simple_animal = 1, /mob/living/silicon/pai = 1, /mob/living/carbon/alien/humanoid/sentinel = 0.25, @@ -26,7 +26,7 @@ /datum/config_entry/keyed_list/multiplicative_movespeed/floating name = "multiplicative_movespeed_floating" - config_entry_value = list( + default = list( /mob/living = 0, /mob/living/carbon/alien/humanoid = 0, /mob/living/carbon/alien/humanoid/royal/praetorian = 0, @@ -62,7 +62,7 @@ M.sync() /datum/config_entry/flag/sprint_enabled - config_entry_value = TRUE + default = TRUE /datum/config_entry/flag/sprint_enabled/ValidateAndSet(str_val) . = ..() @@ -73,31 +73,31 @@ L.disable_intentional_sprint_mode() /datum/config_entry/number/sprintless_stagger_slowdown - config_entry_value = 0 + default = 0 /datum/config_entry/number/sprintless_off_balance_slowdown - config_entry_value = 0.85 + default = 0.85 /datum/config_entry/number/melee_stagger_factor - config_entry_value = 1 + default = 1 /datum/config_entry/number/movedelay/sprint_speed_increase - config_entry_value = 1 + default = 1 /datum/config_entry/number/movedelay/sprint_max_tiles_increase - config_entry_value = 5 + default = 5 /datum/config_entry/number/movedelay/sprint_absolute_max_tiles - config_entry_value = 13 + default = 13 /datum/config_entry/number/movedelay/sprint_buffer_max - config_entry_value = 24 + default = 24 /datum/config_entry/number/movedelay/sprint_stamina_cost - config_entry_value = 1.4 + default = 1.4 /datum/config_entry/number/movedelay/sprint_buffer_regen_per_ds - config_entry_value = 0.4 + default = 0.4 /////////////////////////////////////////////////Outdated move delay /datum/config_entry/number/outdated_movedelay diff --git a/code/controllers/configuration/entries/persistence.dm b/code/controllers/configuration/entries/persistence.dm index 2444034b86..8e38463463 100644 --- a/code/controllers/configuration/entries/persistence.dm +++ b/code/controllers/configuration/entries/persistence.dm @@ -1,19 +1,19 @@ /// Whether or not to use the persistence system for cleanable objects /datum/config_entry/flag/persistent_debris - config_entry_value = FALSE + default = FALSE /// Whether or not to nuke all roundstart debris that isn't due to persistence if the above is true /datum/config_entry/flag/persistent_debris_only - config_entry_value = TRUE + default = TRUE /// Max amount of objects to store, total /datum/config_entry/number/persistent_debris_global_max - config_entry_value = 10000 + default = 10000 integer = TRUE /// Max amount of objects to store per type /datum/config_entry/number/persistent_debris_type_max - config_entry_value = 2000 + default = 2000 integer = TRUE /// Wipe dirty stuff on nuke diff --git a/code/controllers/configuration/entries/plushies.dm b/code/controllers/configuration/entries/plushies.dm index 20ad02d399..0a63698dc2 100644 --- a/code/controllers/configuration/entries/plushies.dm +++ b/code/controllers/configuration/entries/plushies.dm @@ -1,5 +1,5 @@ /datum/config_entry/number/snowflake_plushie_prob - config_entry_value = 50 + default = 50 /datum/config_entry/keyed_list/snowflake_plushies key_mode = KEY_MODE_TEXT diff --git a/code/controllers/configuration/entries/policy.dm b/code/controllers/configuration/entries/policy.dm index ea8973a4ce..31483788e1 100644 --- a/code/controllers/configuration/entries/policy.dm +++ b/code/controllers/configuration/entries/policy.dm @@ -1,6 +1,6 @@ /// Seconds for CMD on defib-with-memory-loss policy config to display instead of defib-intact config /datum/config_entry/number/defib_cmd_time_limit - config_entry_value = 300 + default = 300 integer = TRUE /datum/config_entry/keyed_list/policy diff --git a/code/controllers/configuration/entries/respawns.dm b/code/controllers/configuration/entries/respawns.dm index 40c7d248a4..7c8e3b7789 100644 --- a/code/controllers/configuration/entries/respawns.dm +++ b/code/controllers/configuration/entries/respawns.dm @@ -1,36 +1,36 @@ /// Allows usage of respawn system /datum/config_entry/flag/respawns_enabled - config_entry_value = FALSE + default = FALSE /// Minutes before allowing respawns. /datum/config_entry/number/respawn_delay - config_entry_value = 15.0 + default = 15.0 integer = FALSE /// Minutes before allowing respawn, if user cryo'd. /datum/config_entry/number/respawn_delay_cryo - config_entry_value = 5.0 + default = 5.0 integer = FALSE /// Allows respawning as non-assistant. Overrides all others of this type. /datum/config_entry/flag/allow_non_assistant_respawn - config_entry_value = FALSE + default = FALSE /// Allows respawning as a combat role, defined as security/head. /datum/config_entry/flag/allow_combat_role_respawn - config_entry_value = FALSE + default = FALSE /// Allows respawning as the same character as a previous life /datum/config_entry/flag/allow_same_character_respawn - config_entry_value = FALSE + default = FALSE /// Observing penalizes for respawns, not just joining. /datum/config_entry/flag/respawn_penalty_includes_observe - config_entry_value = FALSE + default = FALSE /// Minutes from roundstart before someone can respawn /datum/config_entry/number/respawn_minimum_delay_roundstart - config_entry_value = 30.0 + default = 30.0 integer = FALSE /// Gamemode config tags that are banned from respawning diff --git a/code/controllers/configuration/entries/security.dm b/code/controllers/configuration/entries/security.dm index 3a49c97d70..9a661ddc21 100644 --- a/code/controllers/configuration/entries/security.dm +++ b/code/controllers/configuration/entries/security.dm @@ -1,34 +1,34 @@ /datum/config_entry/number/fail2topic_rate_limit - config_entry_value = 10 //deciseconds + default = 10 //deciseconds /datum/config_entry/number/fail2topic_max_fails - config_entry_value = 5 + default = 5 /datum/config_entry/string/fail2topic_rule_name - config_entry_value = "_dd_fail2topic" + default = "_dd_fail2topic" protection = CONFIG_ENTRY_LOCKED //affects physical server configuration, no touchies!! /datum/config_entry/flag/fail2topic_enabled /datum/config_entry/number/topic_max_size - config_entry_value = 8192 + default = 8192 /datum/config_entry/keyed_list/topic_rate_limit_whitelist key_mode = KEY_MODE_TEXT value_mode = VALUE_MODE_FLAG /datum/config_entry/number/minute_topic_limit - config_entry_value = null + default = null min_val = 0 /datum/config_entry/number/second_topic_limit - config_entry_value = null + default = null min_val = 0 /datum/config_entry/number/minute_click_limit - config_entry_value = 400 + default = 400 min_val = 0 /datum/config_entry/number/second_click_limit - config_entry_value = 15 + default = 15 min_val = 0 diff --git a/code/controllers/configuration/entries/server.dm b/code/controllers/configuration/entries/server.dm index 1acf8a11ca..0df252f65c 100644 --- a/code/controllers/configuration/entries/server.dm +++ b/code/controllers/configuration/entries/server.dm @@ -2,15 +2,21 @@ /datum/config_entry/string/servername // server name (the name of the game window) +/datum/config_entry/string/communityshortname // short name of the server's community + +/datum/config_entry/string/communitylink // link to the server's website + /datum/config_entry/string/servertagline - config_entry_value = "We forgot to set the server's tagline in config.txt" + default = "We forgot to set the server's tagline in config.txt" + +/datum/config_entry/flag/usetaglinestrings /datum/config_entry/string/serversqlname // short form server name used for the DB /datum/config_entry/string/stationname // station name (the name of the station in-game) /datum/config_entry/number/fps - config_entry_value = 20 + default = 20 min_val = 1 max_val = 100 //byond will start crapping out at 50, so this is just ridic var/sync_validate = FALSE @@ -30,7 +36,7 @@ /datum/config_entry/number/ticklag/New() //ticklag weirdly just mirrors fps var/datum/config_entry/CE = /datum/config_entry/number/fps - config_entry_value = 10 / initial(CE.config_entry_value) + config_entry_value = 10 / initial(CE.default) ..() /datum/config_entry/number/ticklag/ValidateAndSet(str_val) @@ -43,7 +49,7 @@ sync_validate = FALSE /datum/config_entry/number/tick_limit_mc_init //SSinitialization throttling - config_entry_value = TICK_LIMIT_MC_INIT_DEFAULT + default = TICK_LIMIT_MC_INIT_DEFAULT min_val = 0 //oranges warned us integer = FALSE @@ -58,17 +64,17 @@ /datum/config_entry/number/mc_tick_rate/base_mc_tick_rate integer = FALSE - config_entry_value = 1 + default = 1 /datum/config_entry/number/mc_tick_rate/high_pop_mc_tick_rate integer = FALSE - config_entry_value = 1.1 + default = 1.1 /datum/config_entry/number/mc_tick_rate/high_pop_mc_mode_amount - config_entry_value = 65 + default = 65 /datum/config_entry/number/mc_tick_rate/disable_high_pop_mc_mode_amount - config_entry_value = 60 + default = 60 /datum/config_entry/number/mc_tick_rate abstract_type = /datum/config_entry/number/mc_tick_rate @@ -86,5 +92,8 @@ world.sleep_offline = !config_entry_value /datum/config_entry/number/rounds_until_hard_restart - config_entry_value = -1 + default = -1 min_val = 0 + +/datum/config_entry/string/force_gamemode + default = null diff --git a/code/controllers/configuration/entries/stamina_combat.dm b/code/controllers/configuration/entries/stamina_combat.dm index 681b903286..d230b9d7eb 100644 --- a/code/controllers/configuration/entries/stamina_combat.dm +++ b/code/controllers/configuration/entries/stamina_combat.dm @@ -4,30 +4,30 @@ /// Maximum stamina buffer /datum/config_entry/number/stamina_combat/buffer_max - config_entry_value = 25 + default = 25 /// Seconds until percent_regeneration_out_of_combat kicks in /datum/config_entry/number/stamina_combat/out_of_combat_timer - config_entry_value = 15 + default = 15 /// Base regeneration per second /datum/config_entry/number/stamina_combat/base_regeneration - config_entry_value = 3.5 + default = 3.5 /// After out_of_combat_timer elapses, additionally regenerate this percent of total stamina per second. Unaffected by combat mode. /datum/config_entry/number/stamina_combat/percent_regeneration_out_of_combat - config_entry_value = 30 + default = 30 /// Seconds after an action for which your regeneration is penalized /datum/config_entry/number/stamina_combat/post_action_penalty_delay - config_entry_value = 5 + default = 5 /// Factor to multiply by for penalizing post-action-stamina-regen /datum/config_entry/number/stamina_combat/post_action_penalty_factor - config_entry_value = 0.25 + default = 0.25 /// Factor to multiply by for stamina usage past buffer into health /datum/config_entry/number/stamina_combat/overdraw_penalty_factor - config_entry_value = 1.5 + default = 1.5 /datum/config_entry/flag/disable_stambuffer diff --git a/code/controllers/configuration/entries/urls.dm b/code/controllers/configuration/entries/urls.dm index fe82574da0..e911a3062a 100644 --- a/code/controllers/configuration/entries/urls.dm +++ b/code/controllers/configuration/entries/urls.dm @@ -3,24 +3,24 @@ /datum/config_entry/string/banappeals /datum/config_entry/string/wikiurl - config_entry_value = "https://katlin.dog/citadel-wiki" + default = "https://katlin.dog/citadel-wiki" /datum/config_entry/string/wikiurltg - config_entry_value = "http://www.tgstation13.org/wiki" + default = "http://www.tgstation13.org/wiki" /datum/config_entry/string/forumurl - config_entry_value = "http://tgstation13.org/phpBB/index.php" + default = "http://tgstation13.org/phpBB/index.php" /datum/config_entry/string/rulesurl - config_entry_value = "http://www.tgstation13.org/wiki/Rules" + default = "http://www.tgstation13.org/wiki/Rules" /datum/config_entry/string/githuburl - config_entry_value = "https://www.github.com/tgstation/-tg-station" + default = "https://www.github.com/tgstation/-tg-station" /datum/config_entry/string/roundstatsurl /datum/config_entry/string/gamelogurl /datum/config_entry/number/githubrepoid - config_entry_value = null + default = null min_val = 0 diff --git a/code/controllers/configuration/entries/vote.dm b/code/controllers/configuration/entries/vote.dm index 545fd01e3c..50cdc32620 100644 --- a/code/controllers/configuration/entries/vote.dm +++ b/code/controllers/configuration/entries/vote.dm @@ -3,29 +3,29 @@ /datum/config_entry/flag/allow_vote_mode // allow votes to change mode /datum/config_entry/number/vote_delay // minimum time between voting sessions (deciseconds, 10 minute default) - config_entry_value = 6000 + default = 6000 min_val = 0 /datum/config_entry/number/vote_period // length of voting period (deciseconds, default 1 minute) - config_entry_value = 600 + default = 600 min_val = 0 /// Length of time before the first autotransfer vote is called (deciseconds, default 2 hours) /// Set to 0 to disable the subsystem altogether. /datum/config_entry/number/vote_autotransfer_initial - config_entry_value = 72000 + default = 72000 min_val = 0 ///length of time to wait before subsequent autotransfer votes (deciseconds, default 30 minutes) /datum/config_entry/number/vote_autotransfer_interval - config_entry_value = 18000 + default = 18000 min_val = 0 /// maximum extensions until the round autoends. /// Set to 0 to force automatic crew transfer after the 'vote_autotransfer_initial' elapsed. /// Set to -1 to disable the maximum extensions cap. /datum/config_entry/number/vote_autotransfer_maximum - config_entry_value = 4 + default = 4 min_val = -1 /datum/config_entry/flag/default_no_vote // vote does not default to nochange/norestart @@ -37,10 +37,10 @@ /datum/config_entry/flag/tgstyle_maprotation /datum/config_entry/string/map_vote_type - config_entry_value = APPROVAL_VOTING + default = APPROVAL_VOTING /datum/config_entry/number/maprotatechancedelta - config_entry_value = 0.75 + default = 0.75 min_val = 0 max_val = 1 integer = FALSE @@ -50,6 +50,6 @@ /datum/config_entry/flag/modetier_voting /datum/config_entry/number/dropped_modes - config_entry_value = 3 + default = 3 /datum/config_entry/flag/must_be_readied_to_vote_gamemode diff --git a/code/controllers/failsafe.dm b/code/controllers/failsafe.dm index a15056e442..04b88eb3be 100644 --- a/code/controllers/failsafe.dm +++ b/code/controllers/failsafe.dm @@ -15,7 +15,7 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe) // The alert level. For every failed poke, we drop a DEFCON level. Once we hit DEFCON 1, restart the MC. var/defcon = 5 //the world.time of the last check, so the mc can restart US if we hang. - // (Real friends look out for *eachother*) + // (Real friends look out for *eachother*) var/lasttick = 0 // Track the MC iteration to make sure its still on track. @@ -33,6 +33,22 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe) /datum/controller/failsafe/Initialize() set waitfor = FALSE Failsafe.Loop() + if (!Master || defcon == 0) //Master is gone/not responding and Failsafe just exited its loop + defcon = 3 //Reset defcon level as its used inside the emergency loop + while (defcon > 0) + var/recovery_result = emergency_loop() + if (recovery_result == 1) //Exit emergency loop and delete self if it was able to recover MC + break + else if (defcon == 1) //Exit Failsafe if we weren't able to recover the MC in the last stage + log_game("FailSafe: Failed to recover MC while in emergency state. Failsafe exiting.") + message_admins(span_boldannounce("Failsafe failed criticaly while trying to recreate broken MC. Please manually fix the MC or reboot the server. Failsafe exiting now.")) + message_admins(span_boldannounce("You can try manually calling these two procs:.")) + message_admins(span_boldannounce("/proc/recover_all_SS_and_recreate_master: Most stuff should still function but expect instability/runtimes/broken stuff.")) + message_admins(span_boldannounce("/proc/delete_all_SS_and_recreate_master: Most stuff will be broken but basic stuff like movement and chat should still work.")) + else if (recovery_result == -1) //Failed to recreate MC + defcon-- + sleep(initial(processing_interval)) //Wait a bit until the next try + if(!QDELETED(src)) qdel(src) //when Loop() returns, we delete ourselves and let the mc recreate us @@ -45,42 +61,56 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe) while(running) lasttick = world.time if(!Master) - // Replace the missing Master! This should never, ever happen. - new /datum/controller/master() + // Break out of the main loop so we go into emergency state + break // Only poke it if overrides are not in effect. if(processing_interval > 0) if(Master.processing && Master.iteration) + if (defcon > 1 && (!Master.stack_end_detector || !Master.stack_end_detector.check())) + + to_chat(GLOB.admins, span_boldannounce("ERROR: The Master Controller code stack has exited unexpectedly, Restarting...")) + defcon = 0 + var/rtn = Recreate_MC() + if(rtn > 0) + master_iteration = 0 + to_chat(GLOB.admins, span_adminnotice("MC restarted successfully")) + else if(rtn < 0) + log_game("FailSafe: Could not restart MC, runtime encountered. Entering defcon 0") + to_chat(GLOB.admins, span_boldannounce("ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.")) // Check if processing is done yet. if(Master.iteration == master_iteration) switch(defcon) if(4,5) --defcon - if(3) - message_admins("Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks.") - --defcon - if(2) - to_chat(GLOB.admins, "Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.") - --defcon - if(1) - to_chat(GLOB.admins, "Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...") + if(3) + message_admins(span_adminnotice("Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks.")) + --defcon + + if(2) + to_chat(GLOB.admins, span_boldannounce("Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.")) + --defcon + + if(1) + to_chat(GLOB.admins, span_boldannounce("Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...")) --defcon var/rtn = Recreate_MC() if(rtn > 0) defcon = 4 master_iteration = 0 - to_chat(GLOB.admins, "MC restarted successfully") + to_chat(GLOB.admins, span_adminnotice("MC restarted successfully")) else if(rtn < 0) log_game("FailSafe: Could not restart MC, runtime encountered. Entering defcon 0") - to_chat(GLOB.admins, "ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.") + to_chat(GLOB.admins, span_boldannounce("ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.")) //if the return number was 0, it just means the mc was restarted too recently, and it just needs some time before we try again //no need to handle that specially when defcon 0 can handle it + if(0) //DEFCON 0! (mc failed to restart) var/rtn = Recreate_MC() if(rtn > 0) defcon = 4 master_iteration = 0 - to_chat(GLOB.admins, "MC restarted successfully") + to_chat(GLOB.admins, span_adminnotice("MC restarted successfully")) else defcon = min(defcon + 1,5) master_iteration = Master.iteration @@ -92,6 +122,57 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe) defcon = 5 sleep(initial(processing_interval)) +//Emergency loop used when Master got deleted or the main loop exited while Defcon == 0 +//Loop is driven externally so runtimes only cancel the current recovery attempt +/datum/controller/failsafe/proc/emergency_loop() + //The code in this proc should be kept as simple as possible, anything complicated like to_chat might rely on master existing and runtime + //The goal should always be to get a new Master up and running before anything else + . = -1 + switch (defcon) //The lower defcon goes the harder we try to fix the MC + if (2 to 3) //Try to normally recreate the MC two times + . = Recreate_MC() + if (1) //Delete the old MC first so we don't transfer any info, in case that caused any issues + del(Master) + . = Recreate_MC() + + if (. == 1) //We were able to create a new master + master_iteration = 0 + SSticker.Recover(); //Recover the ticket system so the Masters runlevel gets set + Master.Initialize(10, FALSE, TRUE) //Need to manually start the MC, normally world.new would do this + to_chat(GLOB.admins, span_adminnotice("Failsafe recovered MC while in emergency state [defcon_pretty()]")) + else + log_game("FailSafe: Failsafe in emergency state and was unable to recreate MC while in defcon state [defcon_pretty()].") + message_admins(span_boldannounce("Failsafe in emergency state and master down, trying to recreate MC while in defcon level [defcon_pretty()] failed.")) + +///Recreate all SSs which will still cause data survive due to Recover(), the new Master will then find and take them from global.vars +/proc/recover_all_SS_and_recreate_master() + del(Master) + var/list/subsytem_types = subtypesof(/datum/controller/subsystem) + sortTim(subsytem_types, /proc/cmp_subsystem_init) + for(var/I in subsytem_types) + new I + . = Recreate_MC() + if (. == 1) //We were able to create a new master + SSticker.Recover(); //Recover the ticket system so the Masters runlevel gets set + Master.Initialize(10, FALSE, TRUE) //Need to manually start the MC, normally world.new would do this + to_chat(GLOB.admins, span_adminnotice("MC successfully recreated after recovering all subsystems!")) + else + message_admins(span_boldannounce("Failed to create new MC!")) + +///Delete all existing SS to basically start over +/proc/delete_all_SS_and_recreate_master() + del(Master) + for(var/global_var in global.vars) + if (istype(global.vars[global_var], /datum/controller/subsystem)) + del(global.vars[global_var]) + . = Recreate_MC() + if (. == 1) //We were able to create a new master + SSticker.Recover(); //Recover the ticket system so the Masters runlevel gets set + Master.Initialize(10, FALSE, TRUE) //Need to manually start the MC, normally world.new would do this + to_chat(GLOB.admins, span_adminnotice("MC successfully recreated after deleting and recreating all subsystems!")) + else + message_admins(span_boldannounce("Failed to create new MC!")) + /datum/controller/failsafe/proc/defcon_pretty() return defcon diff --git a/code/controllers/globals.dm b/code/controllers/globals.dm index 21f022acfd..7b5cc94d36 100644 --- a/code/controllers/globals.dm +++ b/code/controllers/globals.dm @@ -14,7 +14,7 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars) var/datum/controller/exclude_these = new gvars_datum_in_built_vars = exclude_these.vars + list(NAMEOF(src, gvars_datum_protected_varlist), NAMEOF(src, gvars_datum_in_built_vars), NAMEOF(src, gvars_datum_init_order)) - QDEL_IN(exclude_these, 0) //signal logging isn't ready + QDEL_IN(exclude_these, 0) //signal logging isn't ready log_world("[vars.len - gvars_datum_in_built_vars.len] global variables") diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 59ac68960c..055271fd86 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -18,15 +18,17 @@ GLOBAL_REAL(Master, /datum/controller/master) = new /datum/controller/master name = "Master" - // Are we processing (higher values increase the processing delay by n ticks) + /// Are we processing (higher values increase the processing delay by n ticks) var/processing = TRUE - // How many times have we ran + /// How many times have we ran var/iteration = 0 + /// Stack end detector to detect stack overflows that kill the mc's main loop + var/datum/stack_end_detector/stack_end_detector - // world.time of last fire, for tracking lag outside of the mc + /// world.time of last fire, for tracking lag outside of the mc var/last_run - // List of subsystems to process(). + /// List of subsystems to process(). var/list/subsystems // Vars for keeping track of tick drift. @@ -34,25 +36,27 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/init_time var/tickdrift = 0 + /// How long is the MC sleeping between runs, read only (set by Loop() based off of anti-tick-contention heuristics) var/sleep_delta = 1 - ///Only run ticker subsystems for the next n ticks. + /// Only run ticker subsystems for the next n ticks. var/skip_ticks = 0 + /// makes the mc main loop runtime var/make_runtime = FALSE - var/initializations_finished_with_no_players_logged_in //I wonder what this could be? + var/initializations_finished_with_no_players_logged_in //I wonder what this could be? - // The type of the last subsystem to be process()'d. + /// The type of the last subsystem to be fire()'d. var/last_type_processed - var/datum/controller/subsystem/queue_head //Start of queue linked list - var/datum/controller/subsystem/queue_tail //End of queue linked list (used for appending to the list) + var/datum/controller/subsystem/queue_head //!Start of queue linked list + var/datum/controller/subsystem/queue_tail //!End of queue linked list (used for appending to the list) var/queue_priority_count = 0 //Running total so that we don't have to loop thru the queue each run to split up the tick var/queue_priority_count_bg = 0 //Same, but for background subsystems - var/map_loading = FALSE //Are we loading in a new map? + var/map_loading = FALSE //!Are we loading in a new map? - var/current_runlevel //for scheduling different subsystems for different stages of the round + var/current_runlevel //!for scheduling different subsystems for different stages of the round var/sleep_offline_after_initializations = TRUE var/static/restart_clear = 0 @@ -61,8 +65,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/static/random_seed - //current tick limit, assigned before running a subsystem. - //used by CHECK_TICK as well so that the procs subsystems call can obey that SS's tick limits + ///current tick limit, assigned before running a subsystem. + ///used by CHECK_TICK as well so that the procs subsystems call can obey that SS's tick limits var/static/current_ticklimit = TICK_LIMIT_RUNNING /datum/controller/master/New() @@ -81,15 +85,27 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/list/_subsystems = list() subsystems = _subsystems if (Master != src) - if (istype(Master)) + if (istype(Master)) //If there is an existing MC take over his stuff and delete it Recover() qdel(Master) + Master = src else + //Code used for first master on game boot or if existing master got deleted + Master = src var/list/subsytem_types = subtypesof(/datum/controller/subsystem) sortTim(subsytem_types, /proc/cmp_subsystem_init) + //Find any abandoned subsystem from the previous master (if there was any) + var/list/existing_subsystems = list() + for(var/global_var in global.vars) + if (istype(global.vars[global_var], /datum/controller/subsystem)) + existing_subsystems += global.vars[global_var] + //Either init a new SS or if an existing one was found use that for(var/I in subsytem_types) - _subsystems += new I - Master = src + var/datum/controller/subsystem/existing_subsystem = locate(I) in existing_subsystems + if (istype(existing_subsystem)) + _subsystems += existing_subsystem + else + _subsystems += new I if(!GLOB) new /datum/controller/global_vars @@ -109,7 +125,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new log_world("Shutdown complete") // Returns 1 if we created a new mc, 0 if we couldn't due to a recent restart, -// -1 if we encountered a runtime trying to recreate it +// -1 if we encountered a runtime trying to recreate it /proc/Recreate_MC() . = -1 //so if we runtime, things know we failed if (world.time < Master.restart_timeout) @@ -120,7 +136,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/delay = 50 * ++Master.restart_count Master.restart_timeout = world.time + delay Master.restart_clear = world.time + (delay * 2) - Master.processing = FALSE //stop ticking this one + if (Master) //Can only do this if master hasn't been deleted + Master.processing = FALSE //stop ticking this one try new/datum/controller/master() catch @@ -156,22 +173,22 @@ GLOBAL_REAL(Master, /datum/controller/master) = new msg = "The [BadBoy.name] subsystem seems to be destabilizing the MC and will be offlined." BadBoy.flags |= SS_NO_FIRE if(msg) - to_chat(GLOB.admins, "[msg]") + to_chat(GLOB.admins, span_boldannounce("[msg]")) log_world(msg) if (istype(Master.subsystems)) if(FireHim) - Master.subsystems += new BadBoy.type //NEW_SS_GLOBAL will remove the old one + Master.subsystems += new BadBoy.type //NEW_SS_GLOBAL will remove the old one subsystems = Master.subsystems current_runlevel = Master.current_runlevel StartProcessing(10) else - to_chat(world, "The Master Controller is having some issues, we will need to re-initialize EVERYTHING") + to_chat(world, span_boldannounce("The Master Controller is having some issues, we will need to re-initialize EVERYTHING")) Initialize(20, TRUE) // Please don't stuff random bullshit here, -// Make a subsystem, give it the SS_NO_FIRE flag, and do your work in it's Initialize() +// Make a subsystem, give it the SS_NO_FIRE flag, and do your work in it's Initialize() /datum/controller/master/Initialize(delay, init_sss, tgs_prime) set waitfor = 0 @@ -181,7 +198,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new if(init_sss) init_subtypes(/datum/controller/subsystem, subsystems) - to_chat(world, "Initializing subsystems...") + to_chat(world, span_boldannounce("Initializing subsystems...")) // Sort subsystems by init_order, so they initialize in the correct order. sortTim(subsystems, /proc/cmp_subsystem_init) @@ -190,7 +207,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new // Initialize subsystems. current_ticklimit = CONFIG_GET(number/tick_limit_mc_init) for (var/datum/controller/subsystem/SS in subsystems) - if (SS.flags & SS_NO_INIT) + if (SS.flags & SS_NO_INIT || SS.initialized) //Don't init SSs with the correspondig flag or if they already are initialzized continue SS.Initialize(REALTIMEOFDAY) CHECK_TICK @@ -198,7 +215,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/time = (REALTIMEOFDAY - start_timeofday) / 10 var/msg = "Initializations complete within [time] second[time == 1 ? "" : "s"]!" - to_chat(world, "[msg]") + to_chat(world, span_boldannounce("[msg]")) log_world(msg) if (!current_runlevel) @@ -255,11 +272,11 @@ GLOBAL_REAL(Master, /datum/controller/master) = new /datum/controller/master/proc/Loop() . = -1 //Prep the loop (most of this is because we want MC restarts to reset as much state as we can, and because - // local vars rock + // local vars rock //all this shit is here so that flag edits can be refreshed by restarting the MC. (and for speed) var/list/tickersubsystems = list() - var/list/runlevel_sorted_subsystems = list(list()) //ensure we always have at least one runlevel + var/list/runlevel_sorted_subsystems = list(list()) //ensure we always have at least one runlevel var/timer = world.time for (var/thing in subsystems) var/datum/controller/subsystem/SS = thing @@ -305,8 +322,12 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/error_level = 0 var/sleep_delta = 1 var/list/subsystems_to_check - //the actual loop. + //setup the stack overflow detector + stack_end_detector = new() + var/datum/stack_canary/canary = stack_end_detector.prime_canary() + canary.use_variable() + //the actual loop. while (1) tickdrift = max(0, MC_AVERAGE_FAST(tickdrift, (((REALTIMEOFDAY - init_timeofday) - (world.time - init_time)) / world.tick_lag))) var/starting_tick_usage = TICK_USAGE @@ -317,7 +338,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new //Anti-tick-contention heuristics: //if there are mutiple sleeping procs running before us hogging the cpu, we have to run later. - // (because sleeps are processed in the order received, longer sleeps are more likely to run first) + // (because sleeps are processed in the order received, longer sleeps are more likely to run first) if (starting_tick_usage > TICK_LIMIT_MC) //if there isn't enough time to bother doing anything this tick, sleep a bit. sleep_delta *= 2 current_ticklimit = TICK_LIMIT_RUNNING * 0.5 @@ -423,6 +444,10 @@ GLOBAL_REAL(Master, /datum/controller/master) = new continue if ((SS_flags & (SS_TICKER|SS_KEEP_TIMING)) == SS_KEEP_TIMING && SS.last_fire + (SS.wait * 0.75) > world.time) continue + if (SS.postponed_fires >= 1) + SS.postponed_fires-- + SS.update_nextfire() + continue SS.enqueue() . = 1 @@ -439,12 +464,11 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/tick_precentage var/tick_remaining var/ran = TRUE //this is right - var/ran_non_ticker = FALSE var/bg_calc //have we swtiched current_tick_budget to background mode yet? var/tick_usage //keep running while we have stuff to run and we haven't gone over a tick - // this is so subsystems paused eariler can use tick time that later subsystems never used + // this is so subsystems paused eariler can use tick time that later subsystems never used while (ran && queue_head && TICK_USAGE < TICK_LIMIT_MC) ran = FALSE bg_calc = FALSE @@ -459,20 +483,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new if (!(queue_node_flags & SS_TICKER) && skip_ticks) queue_node = queue_node.queue_next continue - //super special case, subsystems where we can't make them pause mid way through - //if we can't run them this tick (without going over a tick) - //we bump up their priority and attempt to run them next tick - //(unless we haven't even ran anything this tick, since its unlikely they will ever be able run - // in those cases, so we just let them run) - if (queue_node_flags & SS_NO_TICK_CHECK) - if (queue_node.tick_usage > TICK_LIMIT_RUNNING - TICK_USAGE && ran_non_ticker) - if (!(queue_node_flags & SS_BACKGROUND)) - queue_node.queued_priority += queue_priority_count * 0.1 - queue_priority_count -= queue_node_priority - queue_priority_count += queue_node.queued_priority - current_tick_budget -= queue_node_priority - queue_node = queue_node.queue_next - continue if (!bg_calc && (queue_node_flags & SS_BACKGROUND)) current_tick_budget = queue_priority_count_bg @@ -481,7 +491,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new tick_remaining = TICK_LIMIT_RUNNING - TICK_USAGE if (current_tick_budget > 0 && queue_node_priority > 0) - tick_precentage = tick_remaining / (current_tick_budget / queue_node_priority) + //Give the subsystem a precentage of the remaining tick based on the remaning priority + tick_precentage = tick_remaining * (queue_node_priority / current_tick_budget) else tick_precentage = tick_remaining @@ -489,8 +500,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new current_ticklimit = round(TICK_USAGE + tick_precentage) - if (!(queue_node_flags & SS_TICKER)) - ran_non_ticker = TRUE ran = TRUE queue_node_paused = (queue_node.state == SS_PAUSED || queue_node.state == SS_PAUSING) @@ -535,14 +544,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new queue_node.last_fire = world.time queue_node.times_fired++ - if (queue_node_flags & SS_TICKER) - queue_node.next_fire = world.time + (world.tick_lag * queue_node.wait) - else if (queue_node_flags & SS_POST_FIRE_TIMING) - queue_node.next_fire = world.time + queue_node.wait + (world.tick_lag * (queue_node.tick_overrun/100)) - else if (queue_node_flags & SS_KEEP_TIMING) - queue_node.next_fire += queue_node.wait - else - queue_node.next_fire = queue_node.queued_time + queue_node.wait + (world.tick_lag * (queue_node.tick_overrun/100)) + queue_node.update_nextfire() queue_node.queued_time = 0 @@ -554,7 +556,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new . = 1 //resets the queue, and all subsystems, while filtering out the subsystem lists -// called if any mc's queue procs runtime or exit improperly. +// called if any mc's queue procs runtime or exit improperly. /datum/controller/master/proc/SoftReset(list/ticker_SS, list/runlevel_SS) . = 0 log_world("MC: SoftReset called, resetting MC queue state.") diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index 12798f3863..311f8bab8d 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -29,11 +29,11 @@ var/initialized = FALSE /// Set to 0 to prevent fire() calls, mostly for admin use or subsystems that may be resumed later - /// use the [SS_NO_FIRE] flag instead for systems that never fire to keep it from even being added to list that is checked every tick + /// use the [SS_NO_FIRE] flag instead for systems that never fire to keep it from even being added to list that is checked every tick var/can_fire = TRUE ///Bitmap of what game states can this subsystem fire at. See [RUNLEVELS_DEFAULT] for more details. - var/runlevels = RUNLEVELS_DEFAULT //points of the game at which the SS can fire + var/runlevels = RUNLEVELS_DEFAULT //points of the game at which the SS can fire /* * The following variables are managed by the MC and should not be modified directly. @@ -69,6 +69,9 @@ /// Tracks the amount of completed runs for the subsystem var/times_fired = 0 + /// How many fires have we been requested to postpone + var/postponed_fires = 0 + /// Time the subsystem entered the queue, (for timing and priority reasons) var/queued_time = 0 @@ -122,12 +125,38 @@ dequeue() can_fire = 0 flags |= SS_NO_FIRE - Master.subsystems -= src + if (Master) + Master.subsystems -= src return ..() + +/** Update next_fire for the next run. + * reset_time (bool) - Ignore things that would normally alter the next fire, like tick_overrun, and last_fire. (also resets postpone) + */ +/datum/controller/subsystem/proc/update_nextfire(reset_time = FALSE) + var/queue_node_flags = flags + + if (reset_time) + postponed_fires = 0 + if (queue_node_flags & SS_TICKER) + next_fire = world.time + (world.tick_lag * wait) + else + next_fire = world.time + wait + return + + if (queue_node_flags & SS_TICKER) + next_fire = world.time + (world.tick_lag * wait) + else if (queue_node_flags & SS_POST_FIRE_TIMING) + next_fire = world.time + wait + (world.tick_lag * (tick_overrun/100)) + else if (queue_node_flags & SS_KEEP_TIMING) + next_fire += wait + else + next_fire = queued_time + wait + (world.tick_lag * (tick_overrun/100)) + + //Queue it to run. -// (we loop thru a linked list until we get to the end or find the right point) -// (this lets us sort our run order correctly without having to re-sort the entire already sorted list) +// (we loop thru a linked list until we get to the end or find the right point) +// (this lets us sort our run order correctly without having to re-sort the entire already sorted list) /datum/controller/subsystem/proc/enqueue() var/SS_priority = priority var/SS_flags = flags @@ -191,9 +220,9 @@ queue_next.queue_prev = queue_prev if (queue_prev) queue_prev.queue_next = queue_next - if (src == Master.queue_tail) + if (Master && (src == Master.queue_tail)) Master.queue_tail = queue_prev - if (src == Master.queue_head) + if (Master && (src == Master.queue_head)) Master.queue_head = queue_next queued_time = 0 if (state == SS_QUEUED) @@ -217,10 +246,11 @@ //used to initialize the subsystem AFTER the map has loaded /datum/controller/subsystem/Initialize(start_timeofday) initialized = TRUE + SEND_SIGNAL(src, COMSIG_SUBSYSTEM_POST_INITIALIZE, start_timeofday) var/time = (REALTIMEOFDAY - start_timeofday) / 10 var/msg = "Initialized [name] subsystem within [time] second[time == 1 ? "" : "s"]!" - to_chat(world, "[msg]") - log_subsystem("INIT", msg) + to_chat(world, span_boldannounce("[msg]")) + log_subsystem(msg) return time /datum/controller/subsystem/stat_entry(msg) @@ -243,11 +273,10 @@ if (SS_IDLE) . = " " -//could be used to postpone a costly subsystem for (default one) var/cycles, cycles -//for instance, during cpu intensive operations like explosions +/// Causes the next "cycle" fires to be missed. Effect is accumulative but can reset by calling update_nextfire(reset_time = TRUE) /datum/controller/subsystem/proc/postpone(cycles = 1) - if(next_fire - world.time < wait) - next_fire += (wait*cycles) + if (can_fire && cycles >= 1) + postponed_fires += cycles //usually called via datum/controller/subsystem/New() when replacing a subsystem (i.e. due to a recurring crash) //should attempt to salvage what it can from the old instance of subsystem @@ -258,7 +287,7 @@ if (NAMEOF(src, can_fire)) //this is so the subsystem doesn't rapid fire to make up missed ticks causing more lag if (var_value) - next_fire = world.time + wait + update_nextfire(reset_time = TRUE) if (NAMEOF(src, queued_priority)) //editing this breaks things. return FALSE . = ..() diff --git a/code/controllers/subsystem/adjacent_air.dm b/code/controllers/subsystem/adjacent_air.dm deleted file mode 100644 index 99ee587826..0000000000 --- a/code/controllers/subsystem/adjacent_air.dm +++ /dev/null @@ -1,39 +0,0 @@ -SUBSYSTEM_DEF(adjacent_air) - name = "Atmos Adjacency" - flags = SS_BACKGROUND - runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME - wait = 10 - priority = FIRE_PRIORITY_ATMOS_ADJACENCY - var/list/queue = list() - -/datum/controller/subsystem/adjacent_air/stat_entry(msg) -#ifdef TESTING - msg = "P:[length(queue)], S:[GLOB.atmos_adjacent_savings[1]], T:[GLOB.atmos_adjacent_savings[2]]" -#else - msg = "P:[length(queue)]" -#endif - return ..() - -/datum/controller/subsystem/adjacent_air/Initialize() - while(length(queue)) - fire(mc_check = FALSE) - return ..() - -/datum/controller/subsystem/adjacent_air/fire(resumed = FALSE, mc_check = TRUE) - if(SSair.thread_running()) - pause() - return - - var/list/queue = src.queue - - while (length(queue)) - var/turf/currT = queue[1] - queue.Cut(1,2) - - currT.ImmediateCalculateAdjacentTurfs() - - if(mc_check) - if(MC_TICK_CHECK) - break - else - CHECK_TICK diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index 583cf98259..e760ea12e6 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -29,15 +29,13 @@ SUBSYSTEM_DEF(air) var/list/hotspots = list() var/list/networks = list() var/list/pipenets_needing_rebuilt = list() - var/list/deferred_airs = list() - var/max_deferred_airs = 0 var/list/obj/machinery/atmos_machinery = list() - var/list/obj/machinery/atmos_air_machinery = list() var/list/pipe_init_dirs_cache = list() //atmos singletons var/list/gas_reactions = list() - + var/list/atmos_gen + var/list/planetary = list() //auxmos already caches static planetary mixes but could be convenient to do so here too //Special functions lists var/list/turf/open/high_pressure_delta = list() @@ -53,14 +51,22 @@ SUBSYSTEM_DEF(air) var/equalize_turf_limit = 10 // Max number of turfs to look for a space turf, and max number of turfs that will be decompressed. var/equalize_hard_turf_limit = 2000 - // Whether equalization should be enabled at all. - var/equalize_enabled = TRUE + // Whether equalization is enabled. Can be disabled for performance reasons. + var/equalize_enabled = FALSE + // When above 0, won't equalize; performance handling + var/eq_cooldown = 0 // Whether turf-to-turf heat exchanging should be enabled. var/heat_enabled = FALSE // Max number of times process_turfs will share in a tick. var/share_max_steps = 3 + // Target for share_max_steps; can go below this, if it determines the thread is taking too long. + var/share_max_steps_target = 3 // Excited group processing will try to equalize groups with total pressure difference less than this amount. var/excited_group_pressure_goal = 1 + // Target for excited_group_pressure_goal; can go below this, if it determines the thread is taking too long. + var/excited_group_pressure_goal_target = 1 + // If this is set to 0, monstermos won't process planet atmos + var/planet_equalize_enabled = 0 /datum/controller/subsystem/air/stat_entry(msg) msg += "C:{" @@ -85,7 +91,6 @@ SUBSYSTEM_DEF(air) msg += "LT:[low_pressure_turfs]|" msg += "ET:[num_equalize_processed]|" msg += "GT:[num_group_turfs_processed]|" - msg += "DF:[max_deferred_airs]|" msg += "GA:[get_amt_gas_mixes()]|" msg += "MG:[get_max_gas_mixes()]" return ..() @@ -97,12 +102,18 @@ SUBSYSTEM_DEF(air) setup_pipenets() gas_reactions = init_gas_reactions() auxtools_update_reactions() + equalize_enabled = CONFIG_GET(flag/atmos_equalize_enabled) return ..() /datum/controller/subsystem/air/proc/extools_update_ssair() /datum/controller/subsystem/air/proc/auxtools_update_reactions() +/datum/controller/subsystem/air/proc/add_reaction(datum/gas_reaction/r) + gas_reactions += r + sortTim(gas_reactions, /proc/cmp_gas_reaction) + auxtools_update_reactions() + /proc/reset_all_air() SSair.can_fire = 0 message_admins("Air reset begun.") @@ -139,6 +150,35 @@ SUBSYSTEM_DEF(air) if(state != SS_RUNNING) return resumed = FALSE + currentpart = SSAIR_ACTIVETURFS + + if(currentpart == SSAIR_ACTIVETURFS) + timer = TICK_USAGE_REAL + process_turfs(resumed) + if(state != SS_RUNNING) + return + resumed = 0 + currentpart = SSAIR_EXCITEDGROUPS + + if(currentpart == SSAIR_EXCITEDGROUPS) + process_excited_groups(resumed) + if(state != SS_RUNNING) + return + resumed = 0 + currentpart = equalize_enabled ? SSAIR_EQUALIZE : SSAIR_FINALIZE_TURFS + + if(currentpart == SSAIR_EQUALIZE) + equalize_turfs(resumed) + if(state != SS_RUNNING) + return + resumed = 0 + currentpart = SSAIR_FINALIZE_TURFS + + if(currentpart == SSAIR_FINALIZE_TURFS) + finish_turf_processing(resumed) + if(state != SS_RUNNING) + return + resumed = FALSE currentpart = SSAIR_PIPENETS if(currentpart == SSAIR_PIPENETS || !resumed) @@ -149,7 +189,6 @@ SUBSYSTEM_DEF(air) return resumed = 0 currentpart = SSAIR_ATMOSMACHINERY - // This is only machinery like filters, mixers that don't interact with air if(currentpart == SSAIR_ATMOSMACHINERY) timer = TICK_USAGE_REAL process_atmos_machinery(resumed) @@ -166,34 +205,6 @@ SUBSYSTEM_DEF(air) if(state != SS_RUNNING) return resumed = 0 - currentpart = SSAIR_FINALIZE_TURFS - // This literally just waits for the turf processing thread to finish, doesn't do anything else. - // this is necessary cause the next step after this interacts with the air--we get consistency - // issues if we don't wait for it, disappearing gases etc. - if(currentpart == SSAIR_FINALIZE_TURFS) - finish_turf_processing(resumed) - if(state != SS_RUNNING) - cur_thread_wait_ticks++ - return - resumed = 0 - thread_wait_ticks = MC_AVERAGE(thread_wait_ticks, cur_thread_wait_ticks) - cur_thread_wait_ticks = 0 - currentpart = SSAIR_DEFERRED_AIRS - if(currentpart == SSAIR_DEFERRED_AIRS) - timer = TICK_USAGE_REAL - process_deferred_airs(resumed) - cost_deferred_airs = MC_AVERAGE(cost_deferred_airs, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) - if(state != SS_RUNNING) - return - resumed = 0 - currentpart = SSAIR_ATMOSMACHINERY_AIR - if(currentpart == SSAIR_ATMOSMACHINERY_AIR) - timer = TICK_USAGE_REAL - process_atmos_air_machinery(resumed) - cost_atmos_machinery = MC_AVERAGE(cost_atmos_machinery, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) - if(state != SS_RUNNING) - return - resumed = 0 currentpart = SSAIR_HOTSPOTS if(currentpart == SSAIR_HOTSPOTS) @@ -203,7 +214,7 @@ SUBSYSTEM_DEF(air) if(state != SS_RUNNING) return resumed = 0 - currentpart = heat_enabled ? SSAIR_TURF_CONDUCTION : SSAIR_ACTIVETURFS + currentpart = heat_enabled ? SSAIR_TURF_CONDUCTION : SSAIR_REBUILD_PIPENETS // Heat -- slow and of questionable usefulness. Off by default for this reason. Pretty cool, though. if(currentpart == SSAIR_TURF_CONDUCTION) timer = TICK_USAGE_REAL @@ -213,47 +224,7 @@ SUBSYSTEM_DEF(air) if(state != SS_RUNNING) return resumed = 0 - currentpart = SSAIR_ACTIVETURFS - // This simply starts the turf thread. It runs in the background until the FINALIZE_TURFS step, at which point it's waited for. - // This also happens to do all the commented out stuff below, all in a single separate thread. This is mostly so that the - // waiting is consistent. - if(currentpart == SSAIR_ACTIVETURFS) - timer = TICK_USAGE_REAL - process_turfs(resumed) - cost_turfs = MC_AVERAGE(cost_turfs, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) - if(state != SS_RUNNING) - return - resumed = 0 - /* - // Monstermos and/or Putnamos--making large pressure deltas move faster - if(currentpart == SSAIR_EQUALIZE) - timer = TICK_USAGE_REAL - process_turf_equalize(resumed) - cost_equalize = MC_AVERAGE(cost_equalize, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) - if(state != SS_RUNNING) - return - resumed = 0 - currentpart = SSAIR_EXCITEDGROUPS - // Making small pressure deltas equalize immediately so they don't process anymore - if(currentpart == SSAIR_EXCITEDGROUPS) - timer = TICK_USAGE_REAL - process_excited_groups(resumed) - cost_groups = MC_AVERAGE(cost_groups, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) - if(state != SS_RUNNING) - return - resumed = 0 - currentpart = SSAIR_TURF_POST_PROCESS - // Quick multithreaded "should we display/react?" checks followed by finishing those up before the next step - if(currentpart == SSAIR_TURF_POST_PROCESS) - timer = TICK_USAGE_REAL - post_process_turfs(resumed) - cost_post_process = MC_AVERAGE(cost_post_process, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) - if(state != SS_RUNNING) - return - resumed = 0 - currentpart = SSAIR_HOTSPOTS - */ - currentpart = SSAIR_REBUILD_PIPENETS + currentpart = SSAIR_REBUILD_PIPENETS /datum/controller/subsystem/air/proc/process_pipenets(resumed = 0) if (!resumed) @@ -274,31 +245,6 @@ SUBSYSTEM_DEF(air) if(istype(atmos_machine, /obj/machinery/atmospherics)) pipenets_needing_rebuilt += atmos_machine -/datum/controller/subsystem/air/proc/process_deferred_airs(resumed = 0) - max_deferred_airs = max(deferred_airs.len,max_deferred_airs) - while(deferred_airs.len) - var/list/cur_op = deferred_airs[deferred_airs.len] - deferred_airs.len-- - var/datum/gas_mixture/air1 - var/datum/gas_mixture/air2 - if(isopenturf(cur_op[1])) - var/turf/open/T = cur_op[1] - air1 = T.return_air() - else - air1 = cur_op[1] - if(isopenturf(cur_op[2])) - var/turf/open/T = cur_op[2] - air2 = T.return_air() - else - air2 = cur_op[2] - if(istype(cur_op[3], /datum/callback)) - var/datum/callback/cb = cur_op[3] - cb.Invoke(air1, air2) - else - air1.transfer_ratio_to(air2, cur_op[3]) - if(MC_TICK_CHECK) - return - /datum/controller/subsystem/air/proc/process_atmos_machinery(resumed = 0) var/seconds = wait * 0.1 if (!resumed) @@ -313,22 +259,6 @@ SUBSYSTEM_DEF(air) if(MC_TICK_CHECK) return -/datum/controller/subsystem/air/proc/process_atmos_air_machinery(resumed = 0) - var/seconds = wait * 0.1 - if (!resumed) - src.currentrun = atmos_air_machinery.Copy() - //cache for sanic speed (lists are references anyways) - var/list/currentrun = src.currentrun - while(currentrun.len) - var/obj/machinery/M = currentrun[currentrun.len] - currentrun.len-- - if(!M || (M.process_atmos(seconds) == PROCESS_KILL)) - atmos_air_machinery.Remove(M) - if(MC_TICK_CHECK) - return - -/datum/controller/subsystem/air/proc/process_turf_heat() - /datum/controller/subsystem/air/proc/process_hotspots(resumed = 0) if (!resumed) src.currentrun = hotspots.Copy() @@ -356,57 +286,31 @@ SUBSYSTEM_DEF(air) return /datum/controller/subsystem/air/proc/process_turf_equalize(resumed = 0) - if(process_turf_equalize_auxtools(resumed,TICK_REMAINING_MS)) + if(process_turf_equalize_auxtools(TICK_REMAINING_MS)) pause() - /* - //cache for sanic speed - var/fire_count = times_fired - if (!resumed) - src.currentrun = active_turfs.Copy() - //cache for sanic speed (lists are references anyways) - var/list/currentrun = src.currentrun - while(currentrun.len) - var/turf/open/T = currentrun[currentrun.len] - currentrun.len-- - if (T) - T.equalize_pressure_in_zone(fire_count) - //equalize_pressure_in_zone(T, fire_count) - if (MC_TICK_CHECK) - return - */ /datum/controller/subsystem/air/proc/process_turfs(resumed = 0) - if(process_turfs_auxtools(resumed,TICK_REMAINING_MS)) + if(process_turfs_auxtools(TICK_REMAINING_MS)) pause() - /* - //cache for sanic speed - var/fire_count = times_fired - if (!resumed) - src.currentrun = active_turfs.Copy() - //cache for sanic speed (lists are references anyways) - var/list/currentrun = src.currentrun - while(currentrun.len) - var/turf/open/T = currentrun[currentrun.len] - currentrun.len-- - if (T) - T.process_cell(fire_count) - if (MC_TICK_CHECK) - return - */ /datum/controller/subsystem/air/proc/process_excited_groups(resumed = 0) - if(process_excited_groups_auxtools(resumed,TICK_REMAINING_MS)) + if(process_excited_groups_auxtools(TICK_REMAINING_MS)) pause() /datum/controller/subsystem/air/proc/finish_turf_processing(resumed = 0) if(finish_turf_processing_auxtools(TICK_REMAINING_MS)) pause() +/datum/controller/subsystem/air/proc/equalize_turfs(resumed = 0) + if(equalize_turfs_auxtools(TICK_REMAINING_MS)) + pause() + /datum/controller/subsystem/air/proc/post_process_turfs(resumed = 0) - if(post_process_turfs_auxtools(resumed,TICK_REMAINING_MS)) + if(post_process_turfs_auxtools(TICK_REMAINING_MS)) pause() /datum/controller/subsystem/air/proc/finish_turf_processing_auxtools() +/datum/controller/subsystem/air/proc/equalize_turfs_auxtools() /datum/controller/subsystem/air/proc/process_turfs_auxtools() /datum/controller/subsystem/air/proc/post_process_turfs_auxtools() /datum/controller/subsystem/air/proc/process_turf_equalize_auxtools() @@ -415,6 +319,7 @@ SUBSYSTEM_DEF(air) /datum/controller/subsystem/air/proc/get_max_gas_mixes() /datum/controller/subsystem/air/proc/turf_process_time() /datum/controller/subsystem/air/proc/heat_process_time() +/datum/controller/subsystem/air/proc/process_turf_heat() /datum/controller/subsystem/air/StartLoadingMap() map_loading = TRUE @@ -437,7 +342,7 @@ SUBSYSTEM_DEF(air) CHECK_TICK /datum/controller/subsystem/air/proc/setup_atmos_machinery() - for (var/obj/machinery/atmospherics/AM in atmos_machinery + atmos_air_machinery) + for (var/obj/machinery/atmospherics/AM in atmos_machinery) AM.atmosinit() CHECK_TICK @@ -445,7 +350,7 @@ SUBSYSTEM_DEF(air) // all atmos machinery has to initalize before the first // pipenet can be built. /datum/controller/subsystem/air/proc/setup_pipenets() - for (var/obj/machinery/atmospherics/AM in atmos_machinery + atmos_air_machinery) + for (var/obj/machinery/atmospherics/AM in atmos_machinery) AM.build_network() CHECK_TICK @@ -473,6 +378,20 @@ SUBSYSTEM_DEF(air) return pipe_init_dirs_cache[type]["[dir]"] +/datum/controller/subsystem/air/proc/generate_atmos() + atmos_gen = list() + for(var/T in subtypesof(/datum/atmosphere)) + var/datum/atmosphere/atmostype = T + atmos_gen[initial(atmostype.id)] = new atmostype + +/datum/controller/subsystem/air/proc/preprocess_gas_string(gas_string) + if(!atmos_gen) + generate_atmos() + if(!atmos_gen[gas_string]) + return gas_string + var/datum/atmosphere/mix = atmos_gen[gas_string] + return mix.gas_string + #undef SSAIR_PIPENETS #undef SSAIR_ATMOSMACHINERY #undef SSAIR_EXCITEDGROUPS diff --git a/code/controllers/subsystem/atoms.dm b/code/controllers/subsystem/atoms.dm index 02aad6dec3..ba2da8365b 100644 --- a/code/controllers/subsystem/atoms.dm +++ b/code/controllers/subsystem/atoms.dm @@ -14,6 +14,9 @@ SUBSYSTEM_DEF(atoms) var/list/BadInitializeCalls = list() + /// Atoms that will be deleted once the subsystem is initialized + var/list/queued_deletions = list() + initialized = INITIALIZATION_INSSATOMS /datum/controller/subsystem/atoms/Initialize(timeofday) @@ -62,6 +65,12 @@ SUBSYSTEM_DEF(atoms) testing("Late initialized [late_loaders.len] atoms") late_loaders.Cut() + for (var/queued_deletion in queued_deletions) + qdel(queued_deletion) + + testing("[queued_deletions.len] atoms were queued for deletion.") + queued_deletions.Cut() + /// Init this specific atom /datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments) var/the_type = A.type @@ -143,7 +152,7 @@ SUBSYSTEM_DEF(atoms) . += "Path : [path] \n" var/fails = BadInitializeCalls[path] if(fails & BAD_INIT_DIDNT_INIT) - . += "- Didn't call atom/Initialize()\n" + . += "- Didn't call atom/Initialize(mapload)\n" if(fails & BAD_INIT_NO_HINT) . += "- Didn't return an Initialize hint\n" if(fails & BAD_INIT_QDEL_BEFORE) @@ -151,6 +160,14 @@ SUBSYSTEM_DEF(atoms) if(fails & BAD_INIT_SLEPT) . += "- Slept during Initialize()\n" +/// Prepares an atom to be deleted once the atoms SS is initialized. +/datum/controller/subsystem/atoms/proc/prepare_deletion(atom/target) + if (initialized == INITIALIZATION_INNEW_REGULAR) + // Atoms SS has already completed, just kill it now. + qdel(target) + else + queued_deletions += WEAKREF(target) + /datum/controller/subsystem/atoms/Shutdown() var/initlog = InitLog() if(initlog) diff --git a/code/controllers/subsystem/autotransfer.dm b/code/controllers/subsystem/autotransfer.dm index 0afa07939e..4b4405c8cf 100644 --- a/code/controllers/subsystem/autotransfer.dm +++ b/code/controllers/subsystem/autotransfer.dm @@ -31,7 +31,7 @@ SUBSYSTEM_DEF(autotransfer) if(world.time < targettime) return if(maxvotes == NO_MAXVOTES_CAP || maxvotes > curvotes) - SSvote.initiate_vote("transfer","server") + SSvote.initiate_vote("transfer","server", votesystem=APPROVAL_VOTING) targettime = targettime + voteinterval curvotes++ else diff --git a/code/controllers/subsystem/communications.dm b/code/controllers/subsystem/communications.dm index 718357b8bb..58a88890dd 100644 --- a/code/controllers/subsystem/communications.dm +++ b/code/controllers/subsystem/communications.dm @@ -1,33 +1,67 @@ -#define COMMUNICATION_COOLDOWN 300 -#define COMMUNICATION_COOLDOWN_AI 300 +#define COMMUNICATION_COOLDOWN (30 SECONDS) +#define COMMUNICATION_COOLDOWN_AI (30 SECONDS) +#define COMMUNICATION_COOLDOWN_MEETING (5 MINUTES) SUBSYSTEM_DEF(communications) name = "Communications" flags = SS_NO_INIT | SS_NO_FIRE - var/silicon_message_cooldown - var/nonsilicon_message_cooldown + COOLDOWN_DECLARE(silicon_message_cooldown) + COOLDOWN_DECLARE(nonsilicon_message_cooldown) + COOLDOWN_DECLARE(emergency_meeting_cooldown) /datum/controller/subsystem/communications/proc/can_announce(mob/living/user, is_silicon) - if(is_silicon && silicon_message_cooldown > world.time) - . = FALSE - else if(!is_silicon && nonsilicon_message_cooldown > world.time) - . = FALSE + if(is_silicon && COOLDOWN_FINISHED(src, silicon_message_cooldown)) + return TRUE + else if(!is_silicon && COOLDOWN_FINISHED(src, nonsilicon_message_cooldown)) + return TRUE else - . = TRUE + return FALSE /datum/controller/subsystem/communications/proc/make_announcement(mob/living/user, is_silicon, input) if(!can_announce(user, is_silicon)) return FALSE if(is_silicon) minor_announce(html_decode(input),"[user.name] Announces:") - silicon_message_cooldown = world.time + COMMUNICATION_COOLDOWN_AI + COOLDOWN_START(src, silicon_message_cooldown, COMMUNICATION_COOLDOWN_AI) else - priority_announce(html_decode(user.treat_message(input)), null, 'sound/misc/announce.ogg', "Captain") - nonsilicon_message_cooldown = world.time + COMMUNICATION_COOLDOWN + priority_announce(html_decode(user.treat_message(input)), null, 'sound/misc/announce.ogg', "Captain", has_important_message = TRUE) + COOLDOWN_START(src, nonsilicon_message_cooldown, COMMUNICATION_COOLDOWN) user.log_talk(input, LOG_SAY, tag="priority announcement") message_admins("[ADMIN_LOOKUPFLW(user)] has made a priority announcement.") +/** + * Check if a mob can call an emergency meeting + * + * Should only really happen during april fools. + * Checks to see that it's been at least 5 minutes since the last emergency meeting call. + * Arguments: + * * user - Mob who called the meeting + */ +/datum/controller/subsystem/communications/proc/can_make_emergency_meeting(mob/living/user) + if(!(SSevents.holidays && SSevents.holidays[APRIL_FOOLS])) + return FALSE + else if(COOLDOWN_FINISHED(src, emergency_meeting_cooldown)) + return TRUE + else + return FALSE + +/** + * Call an emergency meeting + * + * Communications subsystem wrapper for the call_emergency_meeting world proc. + * Checks to make sure the proc can be called, and handles + * relevant logging and timing. See that proc definition for more detail. + * Arguments: + * * user - Mob who called the meeting + */ +/datum/controller/subsystem/communications/proc/emergency_meeting(mob/living/user) + if(!can_make_emergency_meeting(user)) + return FALSE + call_emergency_meeting(user, get_area(user)) + COOLDOWN_START(src, emergency_meeting_cooldown, COMMUNICATION_COOLDOWN_MEETING) + message_admins("[ADMIN_LOOKUPFLW(user)] has called an emergency meeting.") + /datum/controller/subsystem/communications/proc/send_message(datum/comm_message/sending,print = TRUE,unique = FALSE) for(var/obj/machinery/computer/communications/C in GLOB.machines) if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z)) @@ -40,7 +74,7 @@ SUBSYSTEM_DEF(communications) var/obj/item/paper/P = new /obj/item/paper(C.loc) P.name = "paper - '[sending.title]'" P.info = sending.content - P.update_icon() + P.update_appearance() #undef COMMUNICATION_COOLDOWN #undef COMMUNICATION_COOLDOWN_AI diff --git a/code/controllers/subsystem/economy.dm b/code/controllers/subsystem/economy.dm index 47b00d1125..88255f375e 100644 --- a/code/controllers/subsystem/economy.dm +++ b/code/controllers/subsystem/economy.dm @@ -47,6 +47,13 @@ SUBSYSTEM_DEF(economy) "rainbow" = 1000) var/list/bank_accounts = list() //List of normal accounts (not department accounts) var/list/dep_cards = list() + ///The modifier multiplied to the value of bounties paid out. + var/bounty_modifier = 1 + ///The modifier multiplied to the value of cargo pack prices. + var/pack_price_modifier = 1 + + var/civ_bounty_tracker = 0 + /// Contains the message to send to newscasters about earnings, updated on price_update() /datum/controller/subsystem/economy/Initialize(timeofday) var/budget_to_hand_out = round(budget_pool / department_accounts.len) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 3660770596..2dd13eb1ac 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -93,41 +93,6 @@ SUBSYSTEM_DEF(events) else if(. == EVENT_READY) E.runEvent(random = TRUE) -//allows a client to trigger an event -//aka Badmin Central -// > Not in modules/admin -// REEEEEEEEE -// Why the heck is this here! Took me so damn long to find! -/client/proc/forceEvent() - set name = "Trigger Event" - set category = "Admin.Events" - - if(!holder ||!check_rights(R_FUN)) - return - - holder.forceEvent() - -/datum/admins/proc/forceEvent() - var/dat = "" - var/normal = "" - var/magic = "" - var/holiday = "" - for(var/datum/round_event_control/E in SSevents.control) - dat = "
[E]" - if(E.holidayID) - holiday += dat - else if(E.wizardevent) - magic += dat - else - normal += dat - - dat = normal + "
" + magic + "
" + holiday - - var/datum/browser/popup = new(usr, "forceevent", "Force Random Event", 300, 750) - popup.set_content(dat) - popup.open() - - /* ////////////// // HOLIDAYS // diff --git a/code/controllers/subsystem/fail2topic.dm b/code/controllers/subsystem/fail2topic.dm index 78c4807c3f..47f14a0065 100644 --- a/code/controllers/subsystem/fail2topic.dm +++ b/code/controllers/subsystem/fail2topic.dm @@ -33,7 +33,7 @@ SUBSYSTEM_DEF(fail2topic) while(i <= length(rate_limiting)) var/ip = rate_limiting[i] var/last_attempt = rate_limiting[ip] - if(world.time - last_attempt > rate_limit) + if(REALTIMEOFDAY - last_attempt > rate_limit) rate_limiting -= ip fail_counts -= ip else //if we remove that, and the next element is in its place. check that instead of incrementing. @@ -44,7 +44,24 @@ SUBSYSTEM_DEF(fail2topic) /datum/controller/subsystem/fail2topic/Shutdown() DropFirewallRule() +/datum/controller/subsystem/fail2topic/vv_edit_var(var_name, var_value) + if(var_name == NAMEOF(src, rule_name)) + return FALSE + return ..() + +/datum/controller/subsystem/fail2topic/CanProcCall(procname) + . = ..() + if(.) + switch(procname) + if("IsRateLimited") + return FALSE + if("BanFromFirewall") + return FALSE + /datum/controller/subsystem/fail2topic/proc/IsRateLimited(ip) + if(IsAdminAdvancedProcCall()) + return FALSE + var/last_attempt = rate_limiting[ip] var/static/datum/config_entry/keyed_list/topic_rate_limit_whitelist/cached_whitelist_entry @@ -58,12 +75,12 @@ SUBSYSTEM_DEF(fail2topic) if (active_bans[ip]) return TRUE - rate_limiting[ip] = world.time + rate_limiting[ip] = REALTIMEOFDAY if (isnull(last_attempt)) return FALSE - if (world.time - last_attempt > rate_limit) + if (REALTIMEOFDAY - last_attempt > rate_limit) fail_counts -= ip return FALSE else @@ -82,8 +99,10 @@ SUBSYSTEM_DEF(fail2topic) /datum/controller/subsystem/fail2topic/proc/BanFromFirewall(ip) if (!enabled) return + if(IsAdminAdvancedProcCall()) + return - active_bans[ip] = world.time + active_bans[ip] = REALTIMEOFDAY fail_counts -= ip rate_limiting -= ip diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm index 2d2fac1d13..7f7d301a1d 100644 --- a/code/controllers/subsystem/garbage.dm +++ b/code/controllers/subsystem/garbage.dm @@ -29,37 +29,35 @@ SUBSYSTEM_DEF(garbage) runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY init_order = INIT_ORDER_GARBAGE - var/list/collection_timeout = list(2 MINUTES, 10 SECONDS) // deciseconds to wait before moving something up in the queue to the next level + var/list/collection_timeout = list(GC_FILTER_QUEUE, GC_DEL_QUEUE) // deciseconds to wait before moving something up in the queue to the next level //Stat tracking - var/delslasttick = 0 // number of del()'s we've done this tick - var/gcedlasttick = 0 // number of things that gc'ed last tick + var/delslasttick = 0 // number of del()'s we've done this tick + var/gcedlasttick = 0 // number of things that gc'ed last tick var/totaldels = 0 var/totalgcs = 0 - var/highest_del_time = 0 - var/highest_del_tickusage = 0 + var/highest_del_ms = 0 + var/highest_del_type_string = "" var/list/pass_counts var/list/fail_counts - var/list/items = list() // Holds our qdel_item statistics datums + var/list/items = list() // Holds our qdel_item statistics datums //Queue var/list/queues - #ifdef LEGACY_REFERENCE_TRACKING + #ifdef REFERENCE_TRACKING var/list/reference_find_on_fail = list() + #ifdef REFERENCE_TRACKING_DEBUG + //Should we save found refs. Used for unit testing + var/should_save_refs = FALSE + #endif #endif /datum/controller/subsystem/garbage/PreInit() - queues = new(GC_QUEUE_COUNT) - pass_counts = new(GC_QUEUE_COUNT) - fail_counts = new(GC_QUEUE_COUNT) - for(var/i in 1 to GC_QUEUE_COUNT) - queues[i] = list() - pass_counts[i] = 0 - fail_counts[i] = 0 + InitQueues() /datum/controller/subsystem/garbage/stat_entry(msg) var/list/counts = list() @@ -90,13 +88,18 @@ SUBSYSTEM_DEF(garbage) for(var/path in items) var/datum/qdel_item/I = items[path] dellog += "Path: [path]" + if (I.qdel_flags & QDEL_ITEM_SUSPENDED_FOR_LAG) + dellog += "\tSUSPENDED FOR LAG" if (I.failures) dellog += "\tFailures: [I.failures]" dellog += "\tqdel() Count: [I.qdels]" dellog += "\tDestroy() Cost: [I.destroy_time]ms" if (I.hard_deletes) - dellog += "\tTotal Hard Deletes [I.hard_deletes]" + dellog += "\tTotal Hard Deletes: [I.hard_deletes]" dellog += "\tTime Spent Hard Deleting: [I.hard_delete_time]ms" + dellog += "\tHighest Time Spent Hard Deleting: [I.hard_delete_max]ms" + if (I.hard_deletes_over_threshold) + dellog += "\tHard Deletes Over Threshold: [I.hard_deletes_over_threshold]" if (I.slept_destroy) dellog += "\tSleeps: [I.slept_destroy]" if (I.no_respect_force) @@ -122,6 +125,15 @@ SUBSYSTEM_DEF(garbage) +/datum/controller/subsystem/garbage/proc/InitQueues() + if (isnull(queues)) // Only init the queues if they don't already exist, prevents overriding of recovered lists + queues = new(GC_QUEUE_COUNT) + pass_counts = new(GC_QUEUE_COUNT) + fail_counts = new(GC_QUEUE_COUNT) + for(var/i in 1 to GC_QUEUE_COUNT) + queues[i] = list() + pass_counts[i] = 0 + fail_counts[i] = 0 /datum/controller/subsystem/garbage/proc/HandleQueue(level = GC_QUEUE_CHECK) if (level == GC_QUEUE_CHECK) @@ -153,7 +165,6 @@ SUBSYSTEM_DEF(garbage) if(GCd_at_time > cut_off_time) break // Everything else is newer, skip them count++ - var/refID = L[2] var/datum/D D = locate(refID) @@ -162,8 +173,8 @@ SUBSYSTEM_DEF(garbage) ++gcedlasttick ++totalgcs pass_counts[level]++ - #ifdef LEGACY_REFERENCE_TRACKING - reference_find_on_fail -= refID //It's deleted we don't care anymore. + #ifdef REFERENCE_TRACKING + reference_find_on_fail -= refID //It's deleted we don't care anymore. #endif if (MC_TICK_CHECK) return @@ -171,35 +182,43 @@ SUBSYSTEM_DEF(garbage) // Something's still referring to the qdel'd object. fail_counts[level]++ + + #ifdef REFERENCE_TRACKING + var/ref_searching = FALSE + #endif + switch (level) if (GC_QUEUE_CHECK) #ifdef REFERENCE_TRACKING - D.find_references() - #elif defined(LEGACY_REFERENCE_TRACKING) if(reference_find_on_fail[refID]) - D.find_references_legacy() + INVOKE_ASYNC(D, /datum/proc/find_references) + ref_searching = TRUE #ifdef GC_FAILURE_HARD_LOOKUP else - D.find_references_legacy() + INVOKE_ASYNC(D, /datum/proc/find_references) + ref_searching = TRUE #endif reference_find_on_fail -= refID #endif var/type = D.type var/datum/qdel_item/I = items[type] - #ifdef TESTING + log_world("## TESTING: GC: -- \ref[D] | [type] was unable to be GC'd --") + #ifdef TESTING for(var/c in GLOB.admins) //Using testing() here would fill the logs with ADMIN_VV garbage var/client/admin = c if(!check_rights_for(admin, R_ADMIN)) continue to_chat(admin, "## TESTING: GC: -- [ADMIN_VV(D)] | [type] was unable to be GC'd --") - testing("GC: -- \ref[src] | [type] was unable to be GC'd --") - #endif - #ifdef REFERENCE_TRACKING - GLOB.deletion_failures += D //It should no longer be bothered by the GC, manual deletion only. - continue #endif I.failures++ + + if (I.qdel_flags & QDEL_ITEM_SUSPENDED_FOR_LAG) + #ifdef REFERENCE_TRACKING + if(ref_searching) + return //ref searching intentionally cancels all further fires while running so things that hold references don't end up getting deleted, so we want to return here instead of continue + #endif + continue if (GC_QUEUE_HARDDELETE) HardDelete(D) if (MC_TICK_CHECK) @@ -208,27 +227,17 @@ SUBSYSTEM_DEF(garbage) Queue(D, level+1) + #ifdef REFERENCE_TRACKING + if(ref_searching) + return + #endif + if (MC_TICK_CHECK) return if (count) queue.Cut(1,count+1) count = 0 -#ifdef LEGACY_REFERENCE_TRACKING -/datum/controller/subsystem/garbage/proc/add_type_to_findref(type) - if(!ispath(type)) - return "NOT A VAILD PATH" - reference_find_on_fail_types |= typecacheof(type) - -/datum/controller/subsystem/garbage/proc/remove_type_from_findref(type) - if(!ispath(type)) - return "NOT A VALID PATH" - reference_find_on_fail_types -= typesof(type) - -/datum/controller/subsystem/garbage/proc/clear_findref_types() - reference_find_on_fail_types = list() -#endif - /datum/controller/subsystem/garbage/proc/Queue(datum/D, level = GC_QUEUE_CHECK) if (isnull(D)) return @@ -238,63 +247,66 @@ SUBSYSTEM_DEF(garbage) var/gctime = world.time var/refid = "\ref[D]" -#ifdef LEGACY_REFERENCE_TRACKING - if(reference_find_on_fail_types[D.type]) - SSgarbage.reference_find_on_fail[REF(D)] = TRUE -#endif - D.gc_destroyed = gctime var/list/queue = queues[level] + queue[++queue.len] = list(gctime, refid) // not += for byond reasons //this is mainly to separate things profile wise. /datum/controller/subsystem/garbage/proc/HardDelete(datum/D) - var/time = world.timeofday - var/tick = TICK_USAGE - var/ticktime = world.time ++delslasttick ++totaldels var/type = D.type var/refID = "\ref[D]" + var/tick_usage = TICK_USAGE del(D) - - tick = (TICK_USAGE-tick+((world.time-ticktime)/world.tick_lag*100)) + tick_usage = TICK_USAGE_TO_MS(tick_usage) var/datum/qdel_item/I = items[type] - I.hard_deletes++ - I.hard_delete_time += TICK_DELTA_TO_MS(tick) + I.hard_delete_time += tick_usage + if (tick_usage > I.hard_delete_max) + I.hard_delete_max = tick_usage + if (tick_usage > highest_del_ms) + highest_del_ms = tick_usage + highest_del_type_string = "[type]" + var/time = MS2DS(tick_usage) - if (tick > highest_del_tickusage) - highest_del_tickusage = tick - time = world.timeofday - time - if (!time && TICK_DELTA_TO_MS(tick) > 1) - time = TICK_DELTA_TO_MS(tick)/100 - if (time > highest_del_time) - highest_del_time = time - if (time > 10) - log_game("Error: [type]([refID]) took longer than 1 second to delete (took [time/10] seconds to delete)") - message_admins("Error: [type]([refID]) took longer than 1 second to delete (took [time/10] seconds to delete).") + if (time > 0.1 SECONDS) postpone(time) + var/threshold = CONFIG_GET(number/hard_deletes_overrun_threshold) + if (threshold && (time > threshold SECONDS)) + if (!(I.qdel_flags & QDEL_ITEM_ADMINS_WARNED)) + log_game("Error: [type]([refID]) took longer than [threshold] seconds to delete (took [round(time/10, 0.1)] seconds to delete)") + message_admins("Error: [type]([refID]) took longer than [threshold] seconds to delete (took [round(time/10, 0.1)] seconds to delete).") + I.qdel_flags |= QDEL_ITEM_ADMINS_WARNED + I.hard_deletes_over_threshold++ + var/overrun_limit = CONFIG_GET(number/hard_deletes_overrun_limit) + if (overrun_limit && I.hard_deletes_over_threshold >= overrun_limit) + I.qdel_flags |= QDEL_ITEM_SUSPENDED_FOR_LAG /datum/controller/subsystem/garbage/Recover() + InitQueues() //We first need to create the queues before recovering data if (istype(SSgarbage.queues)) for (var/i in 1 to SSgarbage.queues.len) queues[i] |= SSgarbage.queues[i] - +/// Qdel Item: Holds statistics on each type that passes thru qdel /datum/qdel_item - var/name = "" - var/qdels = 0 //Total number of times it's passed thru qdel. - var/destroy_time = 0 //Total amount of milliseconds spent processing this type's Destroy() - var/failures = 0 //Times it was queued for soft deletion but failed to soft delete. - var/hard_deletes = 0 //Different from failures because it also includes QDEL_HINT_HARDDEL deletions - var/hard_delete_time = 0//Total amount of milliseconds spent hard deleting this type. - var/no_respect_force = 0//Number of times it's not respected force=TRUE - var/no_hint = 0 //Number of times it's not even bother to give a qdel hint - var/slept_destroy = 0 //Number of times it's slept in its destroy + var/name = "" //!Holds the type as a string for this type + var/qdels = 0 //!Total number of times it's passed thru qdel. + var/destroy_time = 0 //!Total amount of milliseconds spent processing this type's Destroy() + var/failures = 0 //!Times it was queued for soft deletion but failed to soft delete. + var/hard_deletes = 0 //!Different from failures because it also includes QDEL_HINT_HARDDEL deletions + var/hard_delete_time = 0 //!Total amount of milliseconds spent hard deleting this type. + var/hard_delete_max = 0 //!Highest time spent hard_deleting this in ms. + var/hard_deletes_over_threshold = 0 //!Number of times hard deletes took longer than the configured threshold + var/no_respect_force = 0 //!Number of times it's not respected force=TRUE + var/no_hint = 0 //!Number of times it's not even bother to give a qdel hint + var/slept_destroy = 0 //!Number of times it's slept in its destroy + var/qdel_flags = 0 //!Flags related to this type's trip thru qdel. /datum/qdel_item/New(mytype) name = "[mytype]" @@ -307,12 +319,12 @@ SUBSYSTEM_DEF(garbage) if(!istype(D)) del(D) return + var/datum/qdel_item/I = SSgarbage.items[D.type] if (!I) I = SSgarbage.items[D.type] = new /datum/qdel_item(D.type) I.qdels++ - if(isnull(D.gc_destroyed)) if (SEND_SIGNAL(D, COMSIG_PARENT_PREQDELETED, force)) // Give the components a chance to prevent their parent from being deleted return @@ -328,12 +340,12 @@ SUBSYSTEM_DEF(garbage) if(!D) return switch(hint) - if (QDEL_HINT_QUEUE) //qdel should queue the object for deletion. + if (QDEL_HINT_QUEUE) //qdel should queue the object for deletion. SSgarbage.Queue(D) if (QDEL_HINT_IWILLGC) D.gc_destroyed = world.time return - if (QDEL_HINT_LETMELIVE) //qdel should let the object live after calling destory. + if (QDEL_HINT_LETMELIVE) //qdel should let the object live after calling destory. if(!force) D.gc_destroyed = null //clear the gc variable (important!) return @@ -350,17 +362,17 @@ SUBSYSTEM_DEF(garbage) I.no_respect_force++ SSgarbage.Queue(D) - if (QDEL_HINT_HARDDEL) //qdel should assume this object won't gc, and queue a hard delete + if (QDEL_HINT_HARDDEL) //qdel should assume this object won't gc, and queue a hard delete SSgarbage.Queue(D, GC_QUEUE_HARDDELETE) - if (QDEL_HINT_HARDDEL_NOW) //qdel should assume this object won't gc, and hard del it post haste. + if (QDEL_HINT_HARDDEL_NOW) //qdel should assume this object won't gc, and hard del it post haste. SSgarbage.HardDelete(D) - #ifdef LEGACY_REFERENCE_TRACKING - if (QDEL_HINT_FINDREFERENCE) //qdel will, if LEGACY_REFERENCE_TRACKING is enabled, display all references to this object, then queue the object for deletion. + #ifdef REFERENCE_TRACKING + if (QDEL_HINT_FINDREFERENCE) //qdel will, if REFERENCE_TRACKING is enabled, display all references to this object, then queue the object for deletion. SSgarbage.Queue(D) - D.find_references_legacy() - if (QDEL_HINT_IFFAIL_FINDREFERENCE) + D.find_references() + if (QDEL_HINT_IFFAIL_FINDREFERENCE) //qdel will, if REFERENCE_TRACKING is enabled and the object fails to collect, display all references to this object. SSgarbage.Queue(D) - SSgarbage.reference_find_on_fail[REF(D)] = TRUE + SSgarbage.reference_find_on_fail["\ref[D]"] = TRUE #endif else #ifdef TESTING @@ -371,18 +383,3 @@ SUBSYSTEM_DEF(garbage) SSgarbage.Queue(D) else if(D.gc_destroyed == GC_CURRENTLY_BEING_QDELETED) CRASH("[D.type] destroy proc was called multiple times, likely due to a qdel loop in the Destroy logic") - -#ifdef TESTING -/proc/writeDatumCount() - var/list/datums = list() - for(var/datum/D in world) - datums[D.type] += 1 - for(var/datum/D) - datums[D.type] += 1 - datums = sortTim(datums, /proc/cmp_numeric_dsc, associative = TRUE) - if(fexists("data/DATUMCOUNT.txt")) - fdel("data/DATUMCOUNT.txt") - var/outfile = file("data/DATUMCOUNT.txt") - for(var/path in datums) - outfile << "[datums[path]]\t\t\t\t\t[path]" -#endif diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 7e7efe398f..4daff91575 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -30,11 +30,13 @@ SUBSYSTEM_DEF(job) var/datum/job/new_overflow = GetJob(new_overflow_role) var/cap = CONFIG_GET(number/overflow_cap) + new_overflow.allow_bureaucratic_error = FALSE new_overflow.spawn_positions = cap new_overflow.total_positions = cap if(new_overflow_role != overflow_role) var/datum/job/old_overflow = GetJob(overflow_role) + old_overflow.allow_bureaucratic_error = initial(old_overflow.allow_bureaucratic_error) old_overflow.spawn_positions = initial(old_overflow.spawn_positions) old_overflow.total_positions = initial(old_overflow.total_positions) overflow_role = new_overflow_role @@ -365,9 +367,14 @@ SUBSYSTEM_DEF(job) JobDebug("DO, Handling unrejectable unassigned") //Mop up people who can't leave. for(var/mob/dead/new_player/player in unassigned) //Players that wanted to back out but couldn't because they're antags (can you feel the edge case?) - if(!GiveRandomJob(player)) - if(!AssignRole(player, SSjob.overflow_role)) //If everything is already filled, make them an assistant - return FALSE //Living on the edge, the forced antagonist couldn't be assigned to overflow role (bans, client age) - just reroll + if(player.client.prefs.joblessrole == BERANDOMJOB) //Gives the player a random role if their preferences are set to it + if(!GiveRandomJob(player)) + if(!AssignRole(player, SSjob.overflow_role)) //If everything is already filled, make them the overflow role + return FALSE //Living on the edge, the forced antagonist couldn't be assigned to overflow role (bans, client age) - just reroll + else //If the player prefers to return to lobby or be an assistant, give them assistant + if(!AssignRole(player, SSjob.overflow_role)) + if(!GiveRandomJob(player)) //The forced antagonist couldn't be assigned to overflow role (bans, client age) - give a random role + return FALSE //Somehow the forced antagonist couldn't be assigned to the overflow role or the a random role - reroll return validate_required_jobs(required_jobs) @@ -427,20 +434,7 @@ SUBSYSTEM_DEF(job) //If we joined at roundstart we should be positioned at our workstation if(!joined_late) - var/obj/S = null - for(var/obj/effect/landmark/start/sloc in GLOB.start_landmarks_list) - if(!sloc.job_spawnpoint) - continue - if(sloc.name != rank) - S = sloc //so we can revert to spawning them on top of eachother if something goes wrong - continue - if(locate(/mob/living) in sloc.loc) - continue - S = sloc - sloc.used = TRUE - break - if(length(GLOB.jobspawn_overrides[rank])) - S = pick(GLOB.jobspawn_overrides[rank]) + var/atom/S = job.get_roundstart_spawn_point(H) if(S) S.JoinPlayerHere(H, FALSE) if(!S) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper @@ -464,11 +458,11 @@ SUBSYSTEM_DEF(job) SSpersistence.antag_rep_change[M.client.ckey] += job.GetAntagRep() -/* if(M.client.holder) - if(CONFIG_GET(flag/auto_deadmin_players) || (M.client.prefs?.toggles & DEADMIN_ALWAYS)) + if(M.client.holder) + if(CONFIG_GET(flag/auto_deadmin_players) || (M.client.prefs?.deadmin & DEADMIN_ALWAYS)) M.client.holder.auto_deadmin() else - handle_auto_deadmin_roles(M.client, rank) */ + handle_auto_deadmin_roles(M.client, rank) to_chat(M, "You are the [rank].") if(job) @@ -487,8 +481,8 @@ SUBSYSTEM_DEF(job) if(job && H) if(job.dresscodecompliant)// CIT CHANGE - dress code compliance equip_loadout(N, H) // CIT CHANGE - allows players to spawn with loadout items - job.after_spawn(H, M, joined_late) // note: this happens before the mob has a key! M will always have a client, H might not. - equip_loadout(N, H, TRUE)//CIT CHANGE - makes players spawn with in-backpack loadout items properly. A little hacky but it works + job.after_spawn(H, M.client, joined_late) // note: this happens before the mob has a key! M will always have a client, H might not. + post_equip_loadout(N, H)//CIT CHANGE - makes players spawn with in-backpack loadout items properly. A little hacky but it works var/list/tcg_cards if(ishuman(H)) @@ -498,7 +492,7 @@ SUBSYSTEM_DEF(job) tcg_cards = N.client.prefs.tcg_cards if(tcg_cards) var/obj/item/tcgcard_binder/binder = new(get_turf(H)) - H.equip_to_slot_if_possible(binder, SLOT_IN_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE) + H.equip_to_slot_if_possible(binder, ITEM_SLOT_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE) for(var/card_type in N.client.prefs.tcg_cards) if(card_type) if(islist(H.client.prefs.tcg_cards[card_type])) @@ -515,19 +509,19 @@ SUBSYSTEM_DEF(job) binder.decks = N.client.prefs.tcg_decks return H -/* + /datum/controller/subsystem/job/proc/handle_auto_deadmin_roles(client/C, rank) if(!C?.holder) return TRUE var/datum/job/job = GetJob(rank) if(!job) return - if((job.auto_deadmin_role_flags & DEADMIN_POSITION_HEAD) && (CONFIG_GET(flag/auto_deadmin_heads) || (C.prefs?.toggles & DEADMIN_POSITION_HEAD))) + if((job.auto_deadmin_role_flags & DEADMIN_POSITION_HEAD) && (CONFIG_GET(flag/auto_deadmin_heads) || (C.prefs?.deadmin & DEADMIN_POSITION_HEAD))) return C.holder.auto_deadmin() - else if((job.auto_deadmin_role_flags & DEADMIN_POSITION_SECURITY) && (CONFIG_GET(flag/auto_deadmin_security) || (C.prefs?.toggles & DEADMIN_POSITION_SECURITY))) + else if((job.auto_deadmin_role_flags & DEADMIN_POSITION_SECURITY) && (CONFIG_GET(flag/auto_deadmin_security) || (C.prefs?.deadmin & DEADMIN_POSITION_SECURITY))) + return C.holder.auto_deadmin() + else if((job.auto_deadmin_role_flags & DEADMIN_POSITION_SILICON) && (CONFIG_GET(flag/auto_deadmin_silicons) || (C.prefs?.deadmin & DEADMIN_POSITION_SILICON))) //in the event there's ever psuedo-silicon roles added, ie synths. return C.holder.auto_deadmin() - else if((job.auto_deadmin_role_flags & DEADMIN_POSITION_SILICON) && (CONFIG_GET(flag/auto_deadmin_silicons) || (C.prefs?.toggles & DEADMIN_POSITION_SILICON))) //in the event there's ever psuedo-silicon roles added, ie synths. - return C.holder.auto_deadmin()*/ /datum/controller/subsystem/job/proc/setup_officer_positions() var/datum/job/J = SSjob.GetJob("Security Officer") @@ -690,7 +684,7 @@ SUBSYSTEM_DEF(job) message_admins(msg) CRASH(msg) -/datum/controller/subsystem/job/proc/equip_loadout(mob/dead/new_player/N, mob/living/M, equipbackpackstuff, bypass_prereqs = FALSE, can_drop = TRUE) +/datum/controller/subsystem/job/proc/equip_loadout(mob/dead/new_player/N, mob/living/M, bypass_prereqs = FALSE, can_drop = TRUE) var/mob/the_mob = N if(!the_mob) the_mob = M // cause this doesn't get assigned if player is a latejoiner @@ -700,6 +694,8 @@ SUBSYSTEM_DEF(job) return for(var/i in chosen_gear) var/datum/gear/G = istext(i[LOADOUT_ITEM]) ? text2path(i[LOADOUT_ITEM]) : i[LOADOUT_ITEM] + if(!ispath(G)) + continue G = GLOB.loadout_items[initial(G.category)][initial(G.subcategory)][initial(G.name)] if(!G) continue @@ -708,9 +704,7 @@ SUBSYSTEM_DEF(job) permitted = FALSE if(G.donoritem && !G.donator_ckey_check(the_mob.client.ckey)) permitted = FALSE - if(!equipbackpackstuff && G.slot == SLOT_IN_BACKPACK)//snowflake check since plopping stuff in the backpack doesnt work for pre-job equip loadout stuffs - permitted = FALSE - if(equipbackpackstuff && G.slot != SLOT_IN_BACKPACK)//ditto + if(G.handle_post_equip) permitted = FALSE if(!permitted) continue @@ -719,7 +713,7 @@ SUBSYSTEM_DEF(job) if(length(i[LOADOUT_COLOR])) //handle loadout colors //handle polychromic items if((G.loadout_flags & LOADOUT_CAN_COLOR_POLYCHROMIC) && length(G.loadout_initial_colors)) - var/datum/element/polychromic/polychromic = I.comp_lookup["item_worn_overlays"] //stupid way to do it but GetElement does not work for this + var/datum/element/polychromic/polychromic = LAZYACCESS(I.comp_lookup, "item_worn_overlays") //stupid way to do it but GetElement does not work for this if(polychromic && istype(polychromic)) var/list/polychromic_entry = polychromic.colors_by_atom[I] if(polychromic_entry) @@ -747,7 +741,70 @@ SUBSYSTEM_DEF(job) I.forceMove(get_turf(C)) else qdel(I) - else if(!M.equip_to_slot_if_possible(I, SLOT_IN_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) // Otherwise, try to put it in the backpack + else if(!M.equip_to_slot_if_possible(I, ITEM_SLOT_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) // Otherwise, try to put it in the backpack + if(can_drop) + I.forceMove(get_turf(M)) // If everything fails, just put it on the floor under the mob. + else + qdel(I) + +/datum/controller/subsystem/job/proc/post_equip_loadout(mob/dead/new_player/N, mob/living/M, bypass_prereqs = FALSE, can_drop = TRUE) + var/mob/the_mob = N + if(!the_mob) + the_mob = M // cause this doesn't get assigned if player is a latejoiner + var/list/chosen_gear = the_mob.client.prefs.loadout_data["SAVE_[the_mob.client.prefs.loadout_slot]"] + if(the_mob.client && the_mob.client.prefs && (chosen_gear && chosen_gear.len)) + if(!ishuman(M))//no silicons allowed + return + for(var/i in chosen_gear) + var/datum/gear/G = istext(i[LOADOUT_ITEM]) ? text2path(i[LOADOUT_ITEM]) : i[LOADOUT_ITEM] + if(!ispath(G)) + continue + G = GLOB.loadout_items[initial(G.category)][initial(G.subcategory)][initial(G.name)] + if(!G) + continue + var/permitted = TRUE + if(!bypass_prereqs && G.restricted_roles && G.restricted_roles.len && !(M.mind.assigned_role in G.restricted_roles)) + permitted = FALSE + if(G.donoritem && !G.donator_ckey_check(the_mob.client.ckey)) + permitted = FALSE + if(!G.handle_post_equip) + permitted = FALSE + if(!permitted) + continue + var/obj/item/I = new G.path + if(I) + if(length(i[LOADOUT_COLOR])) //handle loadout colors + //handle polychromic items + if((G.loadout_flags & LOADOUT_CAN_COLOR_POLYCHROMIC) && length(G.loadout_initial_colors)) + var/datum/element/polychromic/polychromic = LAZYACCESS(I.comp_lookup, "item_worn_overlays") //stupid way to do it but GetElement does not work for this + if(polychromic && istype(polychromic)) + var/list/polychromic_entry = polychromic.colors_by_atom[I] + if(polychromic_entry) + if(polychromic.suits_with_helmet_typecache[I.type]) //is this one of those toggleable hood/helmet things? + polychromic.connect_helmet(I,i[LOADOUT_COLOR]) + polychromic.colors_by_atom[I] = i[LOADOUT_COLOR] + I.update_icon() + else + //handle non-polychromic items (they only have one color) + I.add_atom_colour(i[LOADOUT_COLOR][1], FIXED_COLOUR_PRIORITY) + I.update_icon() + //when inputting the data it's already sanitized + if(i[LOADOUT_CUSTOM_NAME]) + var/custom_name = i[LOADOUT_CUSTOM_NAME] + I.name = custom_name + if(i[LOADOUT_CUSTOM_DESCRIPTION]) + var/custom_description = i[LOADOUT_CUSTOM_DESCRIPTION] + I.desc = custom_description + if(!M.equip_to_slot_if_possible(I, G.slot, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) // If the job's dresscode compliant, try to put it in its slot, first + if(iscarbon(M)) + var/mob/living/carbon/C = M + var/obj/item/storage/backpack/B = C.back + if(!B || !SEND_SIGNAL(B, COMSIG_TRY_STORAGE_INSERT, I, null, TRUE, TRUE)) // Otherwise, try to put it in the backpack, for carbons. + if(can_drop) + I.forceMove(get_turf(C)) + else + qdel(I) + else if(!M.equip_to_slot_if_possible(I, ITEM_SLOT_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) // Otherwise, try to put it in the backpack if(can_drop) I.forceMove(get_turf(M)) // If everything fails, just put it on the floor under the mob. else @@ -761,6 +818,35 @@ SUBSYSTEM_DEF(job) return FALSE job.current_positions = max(0, job.current_positions - 1) +/datum/controller/subsystem/job/proc/get_last_resort_spawn_points() + //bad mojo + var/area/shuttle/arrival/arrivals_area = GLOB.areas_by_type[/area/shuttle/arrival] + if(arrivals_area) + //first check if we can find a chair + var/obj/structure/chair/shuttle_chair = locate() in arrivals_area + if(shuttle_chair) + return shuttle_chair + + //last hurrah + var/list/turf/available_turfs = list() + for(var/turf/arrivals_turf in arrivals_area) + if(!is_blocked_turf(arrivals_turf, TRUE)) + available_turfs += arrivals_turf + if(length(available_turfs)) + return pick(available_turfs) + + //pick an open spot on arrivals and dump em + var/list/arrivals_turfs = shuffle(get_area_turfs(/area/shuttle/arrival)) + if(length(arrivals_turfs)) + for(var/turf/arrivals_turf in arrivals_turfs) + if(!is_blocked_turf(arrivals_turf, TRUE)) + return arrivals_turf + //last chance, pick ANY spot on arrivals and dump em + return pick(arrivals_turfs) + + stack_trace("Unable to find last resort spawn point.") + return GET_ERROR_ROOM + /////////////////////////////////// //Keeps track of all living heads// /////////////////////////////////// diff --git a/code/controllers/subsystem/jukeboxes.dm b/code/controllers/subsystem/jukeboxes.dm index 7be6d44a7f..1e457703c2 100644 --- a/code/controllers/subsystem/jukeboxes.dm +++ b/code/controllers/subsystem/jukeboxes.dm @@ -1,3 +1,19 @@ +//As a brief warning to all those who dare tread upon these grounds: +//The bulk of this code here was written years ago, back in the days of 512. +//We were incredibly drunk back then. And nowadays, we've found that being drunk is a hard requirement for working with this code. +//So if you're here to make changes? Brandish a glass. There are many sins here, but it's exactly as engineered as it needs to be. +//We physically won't be able to tell you what half of this code does. The only thing that'll help you here is the ballmer peak. +//Bottoms up, friend. And be sure to drink responsibly. Be sure to fetch some water, too; it eases the hangover. - Bhijn & Myr + + +// Jukelist indices +#define JUKE_TRACK 1 +#define JUKE_CHANNEL 2 +#define JUKE_BOX 3 +#define JUKE_FALLOFF 4 +#define JUKE_SOUND 5 + + SUBSYSTEM_DEF(jukeboxes) name = "Jukeboxes" wait = 5 @@ -25,27 +41,41 @@ SUBSYSTEM_DEF(jukeboxes) var/channeltoreserve = pick(freejukeboxchannels) if(!channeltoreserve) return FALSE + var/sound/song_to_init = sound(T.song_path) freejukeboxchannels -= channeltoreserve - var/list/youvegotafreejukebox = list(T, channeltoreserve, jukebox, jukefalloff) + var/list/youvegotafreejukebox = list(T, channeltoreserve, jukebox, jukefalloff, song_to_init) + + song_to_init.status = SOUND_MUTE + song_to_init.environment = 7 + song_to_init.channel = channeltoreserve + song_to_init.volume = 1 + song_to_init.falloff = jukefalloff + song_to_init.echo = list(0, null, -10000, null, null, null, null, null, null, null, null, null, null, 1, 1, 1, null, null) + activejukeboxes.len++ activejukeboxes[activejukeboxes.len] = youvegotafreejukebox - //Due to changes in later versions of 512, SOUND_UPDATE no longer properly plays audio when a file is defined in the sound datum. As such, we are now required to init the audio before we can actually do anything with it. - //Downsides to this? This means that you can *only* hear the jukebox audio if you were present on the server when it started playing, and it means that it's now impossible to add loops to the jukebox track list. - var/sound/song_to_init = sound(T.song_path) - song_to_init.status = SOUND_MUTE for(var/mob/M in GLOB.player_list) if(!M.client) continue if(!(M.client.prefs.toggles & SOUND_INSTRUMENTS)) continue - M.playsound_local(M, null, 100, channel = youvegotafreejukebox[2], S = song_to_init) + SEND_SOUND(M, song_to_init) return activejukeboxes.len + +//Updates jukebox by transferring to different object or modifying falloff. +/datum/controller/subsystem/jukeboxes/proc/updatejukebox(IDtoupdate, obj/jukebox, jukefalloff) + if(islist(activejukeboxes[IDtoupdate])) + if(istype(jukebox)) + activejukeboxes[IDtoupdate][JUKE_BOX] = jukebox + if(!isnull(jukefalloff)) + activejukeboxes[IDtoupdate][JUKE_FALLOFF] = jukefalloff + /datum/controller/subsystem/jukeboxes/proc/removejukebox(IDtoremove) if(islist(activejukeboxes[IDtoremove])) - var/jukechannel = activejukeboxes[IDtoremove][2] + var/jukechannel = activejukeboxes[IDtoremove][JUKE_CHANNEL] for(var/mob/M in GLOB.player_list) if(!M.client) continue @@ -85,37 +115,74 @@ SUBSYSTEM_DEF(jukeboxes) if(!jukeinfo.len) stack_trace("Active jukebox without any associated metadata.") continue - var/datum/track/juketrack = jukeinfo[1] + var/datum/track/juketrack = jukeinfo[JUKE_TRACK] if(!istype(juketrack)) stack_trace("Invalid jukebox track datum.") continue - var/obj/jukebox = jukeinfo[3] + var/obj/jukebox = jukeinfo[JUKE_BOX] if(!istype(jukebox)) stack_trace("Nonexistant or invalid object associated with jukebox.") continue - var/sound/song_played = sound(juketrack.song_path) + + var/list/audible_zlevels = get_multiz_accessible_levels(jukebox.z) //TODO - for multiz refresh, this should use the cached zlevel connections var in SSMapping. For now this is fine! + + var/sound/song_played = jukeinfo[JUKE_SOUND] var/turf/currentturf = get_turf(jukebox) var/area/currentarea = get_area(jukebox) var/list/hearerscache = hearers(7, jukebox) + var/targetfalloff = jukeinfo[JUKE_FALLOFF] + var/mixes = ((targetfalloff*250)-750) + var/inrange + var/pressure_factor - song_played.falloff = jukeinfo[4] + + var/datum/gas_mixture/source_env = (istype(currentturf) ? currentturf.return_air() : null) + var/datum/gas_mixture/hearer_env //We init this var outside of the mob loop for the sake of performance + var/turf/hearerturf //ditto + + var/source_pressure = (istype(source_env) ? source_env.return_pressure() : 0) + + song_played.falloff = targetfalloff + song_played.volume = min((targetfalloff * 50), 100) for(var/mob/M in GLOB.player_list) if(!M.client) continue - if(!(M.client.prefs.toggles & SOUND_INSTRUMENTS) || !M.can_hear()) - M.stop_sound_channel(jukeinfo[2]) + if(!(M.client.prefs.toggles & SOUND_INSTRUMENTS)) + M.stop_sound_channel(jukeinfo[JUKE_CHANNEL]) continue - var/inrange = FALSE - if(jukebox.z == M.z) //todo - expand this to work with mining planet z-levels when robust jukebox audio gets merged to master - song_played.status = SOUND_UPDATE - if(get_area(M) == currentarea) - inrange = TRUE - else if(M in hearerscache) - inrange = TRUE - else - song_played.status = SOUND_MUTE | SOUND_UPDATE //Setting volume = 0 doesn't let the sound properties update at all, which is lame. - M.playsound_local(currentturf, null, 100, channel = jukeinfo[2], S = song_played, envwet = (inrange ? -250 : 0), envdry = (inrange ? 0 : -10000)) + inrange = FALSE + song_played.status = SOUND_MUTE | SOUND_UPDATE + + if(source_pressure) + hearerturf = get_turf(M) + hearer_env = (istype(hearerturf) ? hearerturf.return_air() : null) + if(istype(hearer_env)) + pressure_factor = min(source_pressure, hearer_env.return_pressure()) + + if(pressure_factor && targetfalloff && M.can_hear() && (hearerturf.z in audible_zlevels)) + if(get_area(hearerturf) == currentarea) + inrange = TRUE + else if(M in hearerscache) + inrange = TRUE + + song_played.x = (currentturf.x - hearerturf.x) * SOUND_DEFAULT_DISTANCE_MULTIPLIER + song_played.z = (currentturf.y - hearerturf.y) * SOUND_DEFAULT_DISTANCE_MULTIPLIER + song_played.y = (((currentturf.z - hearerturf.z) * 10 * SOUND_DEFAULT_DISTANCE_MULTIPLIER) + ((currentturf.z < hearerturf.z) ? -5 : 5)) + + if(pressure_factor < ONE_ATMOSPHERE) + song_played.volume = (min((targetfalloff * 50), 100) * max((pressure_factor - SOUND_MINIMUM_PRESSURE)/(ONE_ATMOSPHERE - SOUND_MINIMUM_PRESSURE), 1)) + + song_played.echo[1] = (inrange ? 0 : -10000) + song_played.echo[3] = (inrange ? mixes : max(mixes, 0)) + song_played.status = SOUND_UPDATE + SEND_SOUND(M, song_played) CHECK_TICK return + +#undef JUKE_TRACK +#undef JUKE_CHANNEL +#undef JUKE_BOX +#undef JUKE_FALLOFF +#undef JUKE_SOUND diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index d0a6336223..a6c306e4d4 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -81,7 +81,6 @@ SUBSYSTEM_DEF(mapping) to_chat(world, "Unable to load next or default map config, defaulting to Box Station") config = old_config GLOB.year_integer += config.year_offset - GLOB.announcertype = (config.announcertype == "standard" ? (prob(1) ? "medibot" : "classic") : config.announcertype) initialize_biomes() loadWorld() repopulate_sorted_areas() @@ -502,8 +501,9 @@ GLOBAL_LIST_EMPTY(the_station_areas) var/away_name var/datum/space_level/away_level + possible_options += "Custom" - var/answer = input("What kind ? ","Away/VR") as null|anything in list(possible_options + "Custom") + var/answer = input("What kind ? ","Away/VR") as null|anything in possible_options switch(answer) if(null) return diff --git a/code/controllers/subsystem/materials.dm b/code/controllers/subsystem/materials.dm index 2134be0176..d8362ea0d1 100644 --- a/code/controllers/subsystem/materials.dm +++ b/code/controllers/subsystem/materials.dm @@ -25,7 +25,7 @@ SUBSYSTEM_DEF(materials) ) ///List of stackcrafting recipes for materials using rigid recipes var/list/rigid_stack_recipes = list( - // new /datum/stack_recipe("Carving block", /obj/structure/carving_block, 5, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE), + new /datum/stack_recipe("Carving block", /obj/structure/carving_block, 5, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE), ) ///Ran on initialize, populated the materials and materials_by_category dictionaries with their appropiate vars (See these variables for more info) diff --git a/code/controllers/subsystem/pai.dm b/code/controllers/subsystem/pai.dm index dd9848e465..8a6ded4865 100644 --- a/code/controllers/subsystem/pai.dm +++ b/code/controllers/subsystem/pai.dm @@ -1,12 +1,18 @@ SUBSYSTEM_DEF(pai) name = "pAI" - flags = SS_NO_INIT|SS_NO_FIRE + flags = SS_NO_FIRE var/list/candidates = list() var/ghost_spam = FALSE var/spam_delay = 100 var/list/pai_card_list = list() + var/list/restricted_areas = list() + +/datum/controller/subsystem/pai/Initialize(var/time_of_day) + restricted_areas += typesof(/area/command/heads_quarters, /area/ai_monitored) // heads quarters and AI monitored places (like the armory) + initialized = TRUE + return ..() /datum/controller/subsystem/pai/Topic(href, href_list) if(href_list["download"]) diff --git a/code/controllers/subsystem/parallax.dm b/code/controllers/subsystem/parallax.dm index 86bd517602..248b33d86d 100644 --- a/code/controllers/subsystem/parallax.dm +++ b/code/controllers/subsystem/parallax.dm @@ -5,21 +5,6 @@ SUBSYSTEM_DEF(parallax) priority = FIRE_PRIORITY_PARALLAX runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT var/list/currentrun - var/planet_x_offset = 128 - var/planet_y_offset = 128 - var/random_layer - var/random_parallax_color - - -//These are cached per client so needs to be done asap so people joining at roundstart do not miss these. -/datum/controller/subsystem/parallax/PreInit() - . = ..() - if(prob(70)) //70% chance to pick a special extra layer - random_layer = pick(/atom/movable/screen/parallax_layer/random/space_gas, /atom/movable/screen/parallax_layer/random/asteroids) - random_parallax_color = pick(COLOR_TEAL, COLOR_GREEN, COLOR_YELLOW, COLOR_CYAN, COLOR_ORANGE, COLOR_PURPLE)//Special color for random_layer1. Has to be done here so everyone sees the same color. [COLOR_SILVER] - planet_y_offset = rand(100, 160) - planet_x_offset = rand(100, 160) - /datum/controller/subsystem/parallax/fire(resumed = FALSE) if (!resumed) @@ -28,28 +13,82 @@ SUBSYSTEM_DEF(parallax) //cache for sanic speed (lists are references anyways) var/list/currentrun = src.currentrun - while(length(currentrun)) - var/client/processing_client = currentrun[currentrun.len] - currentrun.len-- - if (QDELETED(processing_client) || !processing_client.eye) + if(times_fired % 5) // lazy tick + while(length(currentrun)) + var/client/processing_client = currentrun[currentrun.len] + currentrun.len-- + if (QDELETED(processing_client) || !processing_client.eye) + if (MC_TICK_CHECK) + return + continue + processing_client.parallax_holder?.Update() if (MC_TICK_CHECK) return - continue - - var/atom/movable/movable_eye = processing_client.eye - if(!istype(movable_eye)) - continue - - for (movable_eye; isloc(movable_eye.loc) && !isturf(movable_eye.loc); movable_eye = movable_eye.loc); - - if(movable_eye == processing_client.movingmob) + else // full tick + while(length(currentrun)) + var/client/processing_client = currentrun[currentrun.len] + currentrun.len-- + if (QDELETED(processing_client) || !processing_client.eye) + if (MC_TICK_CHECK) + return + continue + processing_client.parallax_holder?.Update(TRUE) if (MC_TICK_CHECK) return - continue - if(!isnull(processing_client.movingmob)) - LAZYREMOVE(processing_client.movingmob.client_mobs_in_contents, processing_client.mob) - LAZYADD(movable_eye.client_mobs_in_contents, processing_client.mob) - processing_client.movingmob = movable_eye - if (MC_TICK_CHECK) - return + currentrun = null + +/** + * Gets parallax type for zlevel. + */ +/datum/controller/subsystem/parallax/proc/get_parallax_type(z) + return /datum/parallax/space + +/** + * Gets parallax for zlevel. + */ +/datum/controller/subsystem/parallax/proc/get_parallax_datum(z) + var/datum_type = get_parallax_type(z) + return new datum_type + +/** + * Gets parallax added vis contents for zlevel + */ +/datum/controller/subsystem/parallax/proc/get_parallax_vis_contents(z) + return list() + +/** + * Gets parallax motion for a zlevel + * + * Returns null or list(speed, dir deg clockwise from north, windup, turnrate) + * THE RETURNED LIST MUST BE A 4-TUPLE, OR PARALLAX WILL CRASH. + * DO NOT SCREW WITH THIS UNLESS YOU KNOW WHAT YOU ARE DOING. + * + * This will override area motion + */ +/datum/controller/subsystem/parallax/proc/get_parallax_motion(z) + return null + +/** + * updates all parallax for clients on a z + */ +/datum/controller/subsystem/parallax/proc/update_clients_on_z(z) + for(var/client/C in GLOB.clients) + if(C.mob.z == z) + C.parallax_holder?.Update() + +/** + * resets all parallax for clients on a z + */ +/datum/controller/subsystem/parallax/proc/reset_clients_on_z(z) + for(var/client/C in GLOB.clients) + if(C.mob.z == z) + C.parallax_holder?.Reset() + +/** + * updates motion of all clients on z + */ +/datum/controller/subsystem/parallax/proc/update_z_motion(z) + for(var/client/C in GLOB.clients) + if(C.mob.z == z) + C.parallax_holder?.UpdateMotion() diff --git a/code/controllers/subsystem/persistence/polly_parrot.dm b/code/controllers/subsystem/persistence/polly_parrot.dm new file mode 100644 index 0000000000..b0014c249a --- /dev/null +++ b/code/controllers/subsystem/persistence/polly_parrot.dm @@ -0,0 +1,11 @@ +/** + * Persists polly messages across rounds + */ +/datum/controller/subsystem/persistence/LoadGamePersistence() + . = ..() + LoadPolly() + +/datum/controller/subsystem/persistence/proc/LoadPolly() + for(var/mob/living/simple_animal/parrot/Polly/P in GLOB.alive_mob_list) + twitterize(P.speech_buffer, "polytalk") + break //Who's been duping the bird?! diff --git a/code/controllers/subsystem/persistence/poly_parrot.dm b/code/controllers/subsystem/persistence/poly_parrot.dm deleted file mode 100644 index 64743e9623..0000000000 --- a/code/controllers/subsystem/persistence/poly_parrot.dm +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Persists poly messages across rounds - */ -/datum/controller/subsystem/persistence/LoadGamePersistence() - . = ..() - LoadPoly() - -/datum/controller/subsystem/persistence/proc/LoadPoly() - for(var/mob/living/simple_animal/parrot/Poly/P in GLOB.alive_mob_list) - twitterize(P.speech_buffer, "polytalk") - break //Who's been duping the bird?! diff --git a/code/controllers/subsystem/persistence/recent_votes_etc.dm b/code/controllers/subsystem/persistence/recent_votes_etc.dm index 45b866b1c6..68b5a3132d 100644 --- a/code/controllers/subsystem/persistence/recent_votes_etc.dm +++ b/code/controllers/subsystem/persistence/recent_votes_etc.dm @@ -5,24 +5,18 @@ var/list/saved_modes = list(1,2,3) var/list/saved_chaos = list(5,5,5) var/list/saved_dynamic_rules = list(list(),list(),list()) - var/list/saved_storytellers = list("foo","bar","baz") var/average_threat = 50 var/list/saved_maps /datum/controller/subsystem/persistence/SaveServerPersistence() . = ..() CollectRoundtype() - if(istype(SSticker.mode, /datum/game_mode/dynamic)) - var/datum/game_mode/dynamic/mode = SSticker.mode - CollectStoryteller(mode) - CollectRulesets(mode) RecordMaps() /datum/controller/subsystem/persistence/LoadServerPersistence() . = ..() LoadRecentModes() LoadRecentChaos() - LoadRecentStorytellers() LoadRecentRulesets() LoadRecentMaps() @@ -45,30 +39,6 @@ fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) -/datum/controller/subsystem/persistence/proc/CollectStoryteller(var/datum/game_mode/dynamic/mode) - saved_storytellers.len = 3 - saved_storytellers[3] = saved_storytellers[2] - saved_storytellers[2] = saved_storytellers[1] - saved_storytellers[1] = mode.storyteller.name - var/json_file = file("data/RecentStorytellers.json") - var/list/file_data = list() - file_data["data"] = saved_storytellers - fdel(json_file) - WRITE_FILE(json_file, json_encode(file_data)) - -/datum/controller/subsystem/persistence/proc/CollectRulesets(var/datum/game_mode/dynamic/mode) - saved_dynamic_rules[3] = saved_dynamic_rules[2] - saved_dynamic_rules[2] = saved_dynamic_rules[1] - saved_dynamic_rules[1] = list() - for(var/r in mode.executed_rules) - var/datum/dynamic_ruleset/rule = r - saved_dynamic_rules[1] += rule.config_tag - var/json_file = file("data/RecentRulesets.json") - var/list/file_data = list() - file_data["data"] = saved_dynamic_rules - fdel(json_file) - WRITE_FILE(json_file, json_encode(file_data)) - /datum/controller/subsystem/persistence/proc/RecordMaps() saved_maps = saved_maps?.len ? list("[SSmapping.config.map_name]") | saved_maps : list("[SSmapping.config.map_name]") var/json_file = file("data/RecentMaps.json") @@ -107,15 +77,6 @@ return saved_dynamic_rules = json["data"] -/datum/controller/subsystem/persistence/proc/LoadRecentStorytellers() - var/json_file = file("data/RecentStorytellers.json") - if(!fexists(json_file)) - return - var/list/json = json_decode(file2text(json_file)) - if(!json) - return - saved_storytellers = json["data"] - /datum/controller/subsystem/persistence/proc/LoadRecentMaps() var/json_file = file("data/RecentMaps.json") if(!fexists(json_file)) diff --git a/code/controllers/subsystem/processing/processing.dm b/code/controllers/subsystem/processing/processing.dm index 661eafc2a5..058645da49 100644 --- a/code/controllers/subsystem/processing/processing.dm +++ b/code/controllers/subsystem/processing/processing.dm @@ -17,7 +17,6 @@ SUBSYSTEM_DEF(processing) /datum/controller/subsystem/processing/fire(resumed = FALSE) if (!resumed) currentrun = processing.Copy() - var/delta_time = (flags & SS_TICKER)? (wait * world.tick_lag * 0.1) : (wait * 0.1) //cache for sanic speed (lists are references anyways) var/list/current_run = currentrun @@ -26,7 +25,7 @@ SUBSYSTEM_DEF(processing) current_run.len-- if(QDELETED(thing)) processing -= thing - else if(thing.process(delta_time) == PROCESS_KILL) + else if(thing.process(wait * 0.1) == PROCESS_KILL) // fully stop so that a future START_PROCESSING will work STOP_PROCESSING(src, thing) if (MC_TICK_CHECK) @@ -47,5 +46,5 @@ SUBSYSTEM_DEF(processing) * If you override this do not call parent, as it will return PROCESS_KILL. This is done to prevent objects that dont override process() from staying in the processing list */ /datum/proc/process(delta_time) - SHOULD_NOT_SLEEP(TRUE) + set waitfor = FALSE return PROCESS_KILL diff --git a/code/controllers/subsystem/processing/quirks.dm b/code/controllers/subsystem/processing/quirks.dm index 74cd53b0ae..582d2eb9dc 100644 --- a/code/controllers/subsystem/processing/quirks.dm +++ b/code/controllers/subsystem/processing/quirks.dm @@ -49,6 +49,13 @@ PROCESSING_SUBSYSTEM_DEF(quirks) if (!silent && LAZYLEN(cut)) to_chat(to_chat_target || user, "Some quirks have been cut from your character because of these quirks conflicting with your job assignment: [english_list(cut)].") + var/mob/living/carbon/human/H = user + if(istype(H) && H.dna?.species) + var/datum/species/S = H.dna.species + if(S.remove_blacklisted_quirks(H)) + to_chat(to_chat_target || user, "Some quirks have been cut from your character due to them conflicting with your species: [english_list(S.removed_quirks)]") + + /datum/controller/subsystem/processing/quirks/proc/quirk_path_by_name(name) return quirks[name] diff --git a/code/controllers/subsystem/processing/station.dm b/code/controllers/subsystem/processing/station.dm new file mode 100644 index 0000000000..f812ea8c4a --- /dev/null +++ b/code/controllers/subsystem/processing/station.dm @@ -0,0 +1,84 @@ +PROCESSING_SUBSYSTEM_DEF(station) + name = "Station" + init_order = INIT_ORDER_STATION + flags = SS_BACKGROUND + runlevels = RUNLEVEL_GAME + wait = 5 SECONDS + + ///A list of currently active station traits + var/list/station_traits = list() + ///Assoc list of trait type || assoc list of traits with weighted value. Used for picking traits from a specific category. + var/list/selectable_traits_by_types = list(STATION_TRAIT_POSITIVE = list(), STATION_TRAIT_NEUTRAL = list(), STATION_TRAIT_NEGATIVE = list()) + ///Currently active announcer. Starts as a type but gets initialized after traits are selected + var/datum/centcom_announcer/announcer = /datum/centcom_announcer/default + +/datum/controller/subsystem/processing/station/Initialize(timeofday) + + //If doing unit tests we don't do none of that trait shit ya know? + #ifndef UNIT_TESTS + SetupTraits() + #endif + + announcer = new announcer() //Initialize the station's announcer datum + + return ..() + +///Rolls for the amount of traits and adds them to the traits list +/datum/controller/subsystem/processing/station/proc/SetupTraits() + if (fexists(FUTURE_STATION_TRAITS_FILE)) + var/forced_traits_contents = file2text(FUTURE_STATION_TRAITS_FILE) + fdel(FUTURE_STATION_TRAITS_FILE) + + var/list/forced_traits_text_paths = json_decode(forced_traits_contents) + forced_traits_text_paths = SANITIZE_LIST(forced_traits_text_paths) + + for (var/trait_text_path in forced_traits_text_paths) + var/station_trait_path = text2path(trait_text_path) + if (!ispath(station_trait_path, /datum/station_trait) || station_trait_path == /datum/station_trait) + var/message = "Invalid station trait path [station_trait_path] was requested in the future station traits!" + log_game(message) + message_admins(message) + continue + + setup_trait(station_trait_path) + + return + + for(var/i in subtypesof(/datum/station_trait)) + var/datum/station_trait/trait_typepath = i + + // If forced, (probably debugging), just set it up now, keep it out of the pool. + if(initial(trait_typepath.force)) + setup_trait(trait_typepath) + continue + + if(initial(trait_typepath.trait_flags) & STATION_TRAIT_ABSTRACT || initial(trait_typepath.weight) == 0) + continue //Dont add abstract ones to it + selectable_traits_by_types[initial(trait_typepath.trait_type)][trait_typepath] = initial(trait_typepath.weight) + + var/positive_trait_count = pick(20;0, 5;1, 1;2) + var/neutral_trait_count = pick(10;0, 10;1, 3;2) + var/negative_trait_count = pick(20;0, 5;1, 1;2) + can_fire = FALSE + pick_traits(STATION_TRAIT_POSITIVE, positive_trait_count) + pick_traits(STATION_TRAIT_NEUTRAL, neutral_trait_count) + pick_traits(STATION_TRAIT_NEGATIVE, negative_trait_count) + +///Picks traits of a specific category (e.g. bad or good) and a specified amount, then initializes them and adds them to the list of traits. +/datum/controller/subsystem/processing/station/proc/pick_traits(trait_sign, amount) + if(!amount) + return + for(var/iterator in 1 to amount) + var/datum/station_trait/trait_type = pickweight(selectable_traits_by_types[trait_sign]) //Rolls from the table for the specific trait type + setup_trait(trait_type) + +///Creates a given trait of a specific type, while also removing any blacklisted ones from the future pool. +/datum/controller/subsystem/processing/station/proc/setup_trait(datum/station_trait/trait_type) + var/datum/station_trait/trait_instance = new trait_type() + can_fire = can_fire || trait_instance.trait_processes + station_traits += trait_instance + if(!trait_instance.blacklist) + return + for(var/i in trait_instance.blacklist) + var/datum/station_trait/trait_to_remove = i + selectable_traits_by_types[initial(trait_to_remove.trait_type)] -= trait_to_remove diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm index 946980389c..be722ed4f1 100644 --- a/code/controllers/subsystem/research.dm +++ b/code/controllers/subsystem/research.dm @@ -343,10 +343,16 @@ SUBSYSTEM_DEF(research) break //Just need one to work. if (!isnull(last_income)) var/income_time_difference = world.time - last_income - science_tech.last_bitcoins = bitcoins // Doesn't take tick drift into account for(var/i in bitcoins) bitcoins[i] *= income_time_difference / 10 science_tech.add_point_list(bitcoins) + var/list/income = science_tech.commit_income() + for(var/i in income) + var/old_weighted = science_tech.last_bitcoins[i] * (1 MINUTES - income_time_difference) + var/new_weighted = income[i] * income_time_difference + science_tech.last_bitcoins[i] = (old_weighted + new_weighted) / (1 MINUTES) + else + science_tech.last_bitcoins = bitcoins.Copy() last_income = world.time /datum/controller/subsystem/research/proc/calculate_server_coefficient() //Diminishing returns. @@ -366,10 +372,16 @@ SUBSYSTEM_DEF(research) techweb_categories[I.category] = list(I.id = TRUE) /datum/controller/subsystem/research/proc/techweb_node_by_id(id) - return techweb_nodes[id] || error_node + if(techweb_nodes[id]) + return techweb_nodes[id] + stack_trace("Attempted to access node ID [id] which didn't exist") + return error_node /datum/controller/subsystem/research/proc/techweb_design_by_id(id) - return techweb_designs[id] || error_design + if(techweb_designs[id]) + return techweb_designs[id] + stack_trace("Attempted to access design ID [id] which didn't exist") + return error_design /datum/controller/subsystem/research/proc/on_design_deletion(datum/design/D) for(var/i in techweb_nodes) diff --git a/code/controllers/subsystem/security_level.dm b/code/controllers/subsystem/security_level.dm new file mode 100644 index 0000000000..7e88118761 --- /dev/null +++ b/code/controllers/subsystem/security_level.dm @@ -0,0 +1,114 @@ +// NOT THE SAME AS TG! THIS IS BAREMETAL JUST TO MAKE COMSIGS WORK! +SUBSYSTEM_DEF(security_level) + name = "Security Level" + can_fire = FALSE // We will control when we fire in this subsystem + init_order = INIT_ORDER_SECURITY_LEVEL + +/** + * Sets a new security level as our current level + * + * This is how everything should change the security level. + * + * Arguments: + * * new_level - The new security level that will become our current level + */ +/datum/controller/subsystem/security_level/proc/set_level(new_level) + if(!isnum(new_level)) + new_level = SECLEVEL2NUM(new_level) + + //Will not be announced if you try to set to the same level as it already is + if(new_level >= SEC_LEVEL_GREEN && new_level <= SEC_LEVEL_DELTA && new_level != GLOB.security_level) + switch(new_level) + if(SEC_LEVEL_GREEN) + minor_announce(CONFIG_GET(string/alert_green), "Attention! Security level lowered to green:") + if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) + if(GLOB.security_level >= SEC_LEVEL_RED) + SSshuttle.emergency.modTimer(4) + else if(GLOB.security_level == SEC_LEVEL_AMBER) + SSshuttle.emergency.modTimer(2.5) + else + SSshuttle.emergency.modTimer(1.66) + GLOB.security_level = SEC_LEVEL_GREEN + for(var/obj/machinery/firealarm/FA in GLOB.machines) + if(is_station_level(FA.z)) + FA.update_icon() + if(SEC_LEVEL_BLUE) + if(GLOB.security_level < SEC_LEVEL_BLUE) + minor_announce(CONFIG_GET(string/alert_blue_upto), "Attention! Security level elevated to blue:",1) + if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) + SSshuttle.emergency.modTimer(0.6) + else + minor_announce(CONFIG_GET(string/alert_blue_downto), "Attention! Security level lowered to blue:") + if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) + if(GLOB.security_level >= SEC_LEVEL_RED) + SSshuttle.emergency.modTimer(2.4) + else + SSshuttle.emergency.modTimer(1.5) + GLOB.security_level = SEC_LEVEL_BLUE + sound_to_playing_players('sound/misc/voybluealert.ogg', volume = 50) // Citadel change - Makes alerts play a sound + for(var/obj/machinery/firealarm/FA in GLOB.machines) + if(is_station_level(FA.z)) + FA.update_icon() + if(SEC_LEVEL_AMBER) + if(GLOB.security_level < SEC_LEVEL_AMBER) + minor_announce(CONFIG_GET(string/alert_amber_upto), "Attention! Security level elevated to amber:",1) + if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) + if(GLOB.security_level == SEC_LEVEL_GREEN) + SSshuttle.emergency.modTimer(0.4) + else + SSshuttle.emergency.modTimer(0.66) + else + minor_announce(CONFIG_GET(string/alert_amber_downto), "Attention! Security level lowered to amber:") + if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) + SSshuttle.emergency.modTimer(1.6) + GLOB.security_level = SEC_LEVEL_AMBER + sound_to_playing_players('sound/effects/alert.ogg', volume = 50) // Citadel change - Makes alerts play a sound + for(var/obj/machinery/firealarm/FA in GLOB.machines) + if(is_station_level(FA.z)) + FA.update_icon() + if(SEC_LEVEL_RED) + if(GLOB.security_level < SEC_LEVEL_RED) + minor_announce(CONFIG_GET(string/alert_red_upto), "Attention! Code red!",1) + if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) + if(GLOB.security_level == SEC_LEVEL_GREEN) + SSshuttle.emergency.modTimer(0.25) + else if(GLOB.security_level == SEC_LEVEL_BLUE) + SSshuttle.emergency.modTimer(0.416) + else + SSshuttle.emergency.modTimer(0.625) + else + minor_announce(CONFIG_GET(string/alert_red_downto), "Attention! Code red!") + GLOB.security_level = SEC_LEVEL_RED + sound_to_playing_players('sound/misc/voyalert.ogg', volume = 50) // Citadel change - Makes alerts play a sound + + for(var/obj/machinery/firealarm/FA in GLOB.machines) + if(is_station_level(FA.z)) + FA.update_icon() + for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines) + pod.admin_controlled = FALSE + if(SEC_LEVEL_DELTA) + minor_announce(CONFIG_GET(string/alert_delta), "Attention! Delta security level reached!",1) + if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) + if(GLOB.security_level < SEC_LEVEL_BLUE) + SSshuttle.emergency.modTimer(0.25) + else if(GLOB.security_level == SEC_LEVEL_BLUE) + SSshuttle.emergency.modTimer(0.416) + else + SSshuttle.emergency.modTimer(0.625) + GLOB.security_level = SEC_LEVEL_DELTA + sound_to_playing_players('sound/misc/deltakalaxon.ogg') // Citadel change - Makes alerts play a sound + for(var/obj/machinery/firealarm/FA in GLOB.machines) + if(is_station_level(FA.z)) + FA.update_icon() + for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines) + pod.admin_controlled = FALSE + if(new_level >= SEC_LEVEL_RED) + for(var/obj/machinery/door/D in GLOB.machines) + if(D.red_alert_access) + D.visible_message("[D] whirrs as it automatically lifts access requirements!") + playsound(D, 'sound/machines/boltsup.ogg', 50, TRUE) + SEND_SIGNAL(src, COMSIG_SECURITY_LEVEL_CHANGED, new_level) + SSblackbox.record_feedback("tally", "security_level_changes", 1, NUM2SECLEVEL(GLOB.security_level)) + SSnightshift.check_nightshift() + else + return diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 6af79d4d14..dbec272fe8 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -254,7 +254,7 @@ SUBSYSTEM_DEF(shuttle) var/area/A = get_area(user) log_shuttle("[key_name(user)] has called the emergency shuttle.") - deadchat_broadcast(" has called the shuttle at [A.name].", "[user.real_name]", user) //, message_type=DEADCHAT_ANNOUNCEMENT) + deadchat_broadcast(" has called the shuttle at [span_name("[A.name]")].", span_name("[user.real_name]"), user, message_type=DEADCHAT_ANNOUNCEMENT) if(call_reason) SSblackbox.record_feedback("text", "shuttle_reason", 1, "[call_reason]") log_shuttle("Shuttle call reason: [call_reason]") @@ -293,7 +293,7 @@ SUBSYSTEM_DEF(shuttle) emergency.cancel(get_area(user)) log_shuttle("[key_name(user)] has recalled the shuttle.") message_admins("[ADMIN_LOOKUPFLW(user)] has recalled the shuttle.") - deadchat_broadcast(" has recalled the shuttle from [get_area_name(user, TRUE)].", "[user.real_name]", user) //, message_type=DEADCHAT_ANNOUNCEMENT) + deadchat_broadcast(" has recalled the shuttle from [span_name("[get_area_name(user, TRUE)]")].", span_name("[user.real_name]"), user, message_type=DEADCHAT_ANNOUNCEMENT) return 1 /datum/controller/subsystem/shuttle/proc/canRecall() @@ -513,7 +513,9 @@ SUBSYSTEM_DEF(shuttle) if(!midpoint) return FALSE var/area/shuttle/transit/A = new() - A.parallax_movedir = travel_dir + A.parallax_moving = TRUE + A.parallax_move_angle = dir2angle(travel_dir) + A.parallax_move_speed = M.parallax_speed A.contents = proposal.reserved_turfs var/obj/docking_port/stationary/transit/new_transit_dock = new(midpoint) new_transit_dock.reserved_area = proposal diff --git a/code/controllers/subsystem/sound_loops.dm b/code/controllers/subsystem/sound_loops.dm new file mode 100644 index 0000000000..c1e6d097d6 --- /dev/null +++ b/code/controllers/subsystem/sound_loops.dm @@ -0,0 +1,3 @@ +PROCESSING_SUBSYSTEM_DEF(sound_loops) + name = "Sound Loops" + priority = FIRE_PRIORITY_SOUND_LOOPS diff --git a/code/controllers/subsystem/sounds.dm b/code/controllers/subsystem/sounds.dm index fa9ba3c472..7d94a3d21d 100644 --- a/code/controllers/subsystem/sounds.dm +++ b/code/controllers/subsystem/sounds.dm @@ -4,7 +4,7 @@ SUBSYSTEM_DEF(sounds) name = "Sounds" flags = SS_NO_FIRE init_order = INIT_ORDER_SOUNDS - var/static/using_channels_max = CHANNEL_HIGHEST_AVAILABLE //BYOND max channels + var/static/using_channels_max = CHANNEL_HIGHEST_AVAILABLE //BYOND max channels /// Amount of channels to reserve for random usage rather than reservations being allowed to reserve all channels. Also a nice safeguard for when someone screws up. var/static/random_channels_min = 50 @@ -42,7 +42,7 @@ SUBSYSTEM_DEF(sounds) var/text_channel = num2text(channel) var/using = using_channels[text_channel] using_channels -= text_channel - if(using != TRUE) // datum channel + if(using != TRUE) // datum channel using_channels_by_datum[using] -= channel if(!length(using_channels_by_datum[using])) using_channels_by_datum -= using @@ -65,7 +65,7 @@ SUBSYSTEM_DEF(sounds) /// NO AUTOMATIC CLEANUP - If you use this, you better manually free it later! Returns an integer for channel. /datum/controller/subsystem/sounds/proc/reserve_sound_channel_datumless() . = reserve_channel() - if(!.) //oh no.. + if(!.) //oh no.. return FALSE var/text_channel = num2text(.) using_channels[text_channel] = DATUMLESS @@ -74,7 +74,7 @@ SUBSYSTEM_DEF(sounds) /// Reserves a channel for a datum. Automatic cleanup only when the datum is deleted. Returns an integer for channel. /datum/controller/subsystem/sounds/proc/reserve_sound_channel(datum/D) - if(!D) //i don't like typechecks but someone will fuck it up + if(!D) //i don't like typechecks but someone will fuck it up CRASH("Attempted to reserve sound channel without datum using the managed proc.") .= reserve_channel() if(!.) @@ -89,7 +89,7 @@ SUBSYSTEM_DEF(sounds) */ /datum/controller/subsystem/sounds/proc/reserve_channel() PRIVATE_PROC(TRUE) - if(channel_reserve_high <= random_channels_min) // out of channels + if(channel_reserve_high <= random_channels_min) // out of channels return var/channel = channel_list[channel_reserve_high] reserved_channels[num2text(channel)] = channel_reserve_high-- @@ -112,7 +112,7 @@ SUBSYSTEM_DEF(sounds) // now, an existing reserved channel will likely (exception: unreserving last reserved channel) be at index // get it, and update position. var/text_reserved = num2text(channel_list[index]) - if(!reserved_channels[text_reserved]) //if it isn't already reserved make sure we don't accidently mistakenly put it on reserved list! + if(!reserved_channels[text_reserved]) //if it isn't already reserved make sure we don't accidently mistakenly put it on reserved list! return reserved_channels[text_reserved] = index diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index d0d5579611..6ba2caa31d 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -18,7 +18,7 @@ SUBSYSTEM_DEF(statpanels) cached ? "Next Map: [cached.map_name]" : null, "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]", "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]", - "Round Time: [round_time > MIDNIGHT_ROLLOVER ? "[round(round_time/MIDNIGHT_ROLLOVER)]:[worldtime2text()]" : worldtime2text()]", + "Round Time: [GAMETIMESTAMP("hh:mm:ss", round_time)]", "Station Time: [STATION_TIME_TIMESTAMP("hh:mm:ss", world.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)]%)" ) diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm index 0fa8035d72..47efc967ac 100644 --- a/code/controllers/subsystem/throwing.dm +++ b/code/controllers/subsystem/throwing.dm @@ -87,6 +87,7 @@ SUBSYSTEM_DEF(throwing) if(HAS_TRAIT_FROM(thrownthing, TRAIT_SPOOKY_THROW, "revenant")) REMOVE_TRAIT(thrownthing, TRAIT_SPOOKY_THROW, "revenant") SSthrowing.processing -= thrownthing + SSthrowing.currentrun -= thrownthing thrownthing.throwing = null thrownthing = null target = null @@ -200,6 +201,6 @@ SUBSYSTEM_DEF(throwing) var/atom/movable/AM = thing if (AM == thrownthing || (AM == thrower && !ismob(thrownthing))) continue - if (AM.density && !(AM.pass_flags & LETPASSTHROW) && !(AM.flags_1 & ON_BORDER_1)) + if (AM.density && !(AM.pass_flags_self & LETPASSTHROW) && !(AM.flags_1 & ON_BORDER_1)) finalize(hit=TRUE, target=AM) return TRUE diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index dfee659080..c75febedef 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -71,6 +71,9 @@ SUBSYSTEM_DEF(ticker) var/station_integrity = 100 // stored at roundend for use in some antag goals var/emergency_reason + /// If the gamemode fails to be run too many times, we swap to a preset gamemode, this should give admins time to set their preferred one + var/emergency_swap = 0 + /datum/controller/subsystem/ticker/Initialize(timeofday) load_mode() @@ -161,8 +164,8 @@ SUBSYSTEM_DEF(ticker) to_chat(world, "Welcome to [station_name()]!") send2chat("New round starting on [SSmapping.config.map_name]!", CONFIG_GET(string/chat_announce_new_game)) current_state = GAME_STATE_PREGAME - //Everyone who wants to be an observer is now spawned - create_observers() + SEND_SIGNAL(src, COMSIG_TICKER_ENTER_PREGAME) + fire() if(GAME_STATE_PREGAME) //lobby stats for statpanels @@ -179,7 +182,11 @@ SUBSYSTEM_DEF(ticker) timeLeft = 0 if(!modevoted) - send_gamemode_vote() + var/forcemode = CONFIG_GET(string/force_gamemode) + if(forcemode) + force_gamemode(forcemode) + if(!forcemode || (GLOB.master_mode == "dynamic" && CONFIG_GET(flag/dynamic_voting))) + send_gamemode_vote() //countdown if(timeLeft < 0) return @@ -196,6 +203,7 @@ SUBSYSTEM_DEF(ticker) for(var/client/C in SSvote.voting) C << browse(null, "window=vote;can_close=0") SSvote.reset() + SEND_SIGNAL(src, COMSIG_TICKER_ENTER_SETTING_UP) current_state = GAME_STATE_SETTING_UP Master.SetRunLevel(RUNLEVEL_SETUP) if(start_immediately) @@ -208,6 +216,7 @@ SUBSYSTEM_DEF(ticker) start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10) timeLeft = null Master.SetRunLevel(RUNLEVEL_LOBBY) + SEND_SIGNAL(src, COMSIG_TICKER_ERROR_SETTING_UP) if(GAME_STATE_PLAYING) mode.process(wait * 0.1) @@ -227,36 +236,16 @@ SUBSYSTEM_DEF(ticker) /datum/controller/subsystem/ticker/proc/setup() to_chat(world, "Starting game...") var/init_start = world.timeofday - //Create and announce mode - var/list/datum/game_mode/runnable_modes - if(GLOB.master_mode == "random" || GLOB.master_mode == "secret") - runnable_modes = config.get_runnable_modes() - - if(GLOB.master_mode == "secret") - hide_mode = 1 - if(GLOB.secret_force_mode != "secret") - var/datum/game_mode/smode = config.pick_mode(GLOB.secret_force_mode) - if(!smode.can_start()) - message_admins("Unable to force secret [GLOB.secret_force_mode]. [smode.required_players] players and [smode.required_enemies] eligible antagonists needed.") - else - mode = smode - - if(!mode) - if(!runnable_modes.len) - to_chat(world, "Unable to choose playable game mode. Reverting to pre-game lobby.") - return 0 - mode = pickweight(runnable_modes) - if(!mode) //too few roundtypes all run too recently - mode = pick(runnable_modes) - - else - mode = config.pick_mode(GLOB.master_mode) - if(!mode.can_start()) - to_chat(world, "Unable to start [mode.name]. Not enough players, [mode.required_players] players and [mode.required_enemies] eligible antagonists needed. Reverting to pre-game lobby.") - qdel(mode) - mode = null - SSjob.ResetOccupations() - return 0 + if(emergency_swap >= 10) + force_gamemode("extended") // If everything fails extended does not have hard requirements for starting, could be changed if needed. + mode = config.pick_mode(GLOB.master_mode) + if(!mode.can_start()) + to_chat(world, "Unable to start [mode.name]. Not enough players, [mode.required_players] players and [mode.required_enemies] eligible antagonists needed. Reverting to pre-game lobby.") + qdel(mode) + mode = null + SSjob.ResetOccupations() + emergency_swap++ + return 0 CHECK_TICK //Configure mode and assign player to special mode stuff @@ -274,6 +263,7 @@ SUBSYSTEM_DEF(ticker) QDEL_NULL(mode) to_chat(world, "Error setting up [GLOB.master_mode]. Reverting to pre-game lobby.") SSjob.ResetOccupations() + emergency_swap++ return 0 else message_admins("DEBUG: Bypassing prestart checks...") @@ -306,12 +296,14 @@ SUBSYSTEM_DEF(ticker) cb.InvokeAsync() LAZYCLEARLIST(round_start_events) + SEND_SIGNAL(src, COMSIG_TICKER_ROUND_STARTING) + log_world("Game start took [(world.timeofday - init_start)/10]s") round_start_time = world.time SSdbcore.SetRoundStart() to_chat(world, "Welcome to [station_name()], enjoy your stay!") - SEND_SOUND(world, sound(get_announcer_sound("welcome"))) + SEND_SOUND(world, sound(SSstation.announcer.get_rand_welcome_sound())) current_state = GAME_STATE_PLAYING Master.SetRunLevel(RUNLEVEL_GAME) @@ -327,6 +319,19 @@ SUBSYSTEM_DEF(ticker) return TRUE +/datum/controller/subsystem/ticker/proc/force_gamemode(gamemode) + if(gamemode) + if(!modevoted) + modevoted = TRUE + if(gamemode in config.modes) + GLOB.master_mode = gamemode + SSticker.save_mode(gamemode) + message_admins("The gamemode has been set to [gamemode].") + else + GLOB.master_mode = "extended" + SSticker.save_mode("extended") + message_admins("force_gamemode proc received an invalid gamemode, defaulting to extended.") + /datum/controller/subsystem/ticker/proc/PostSetup() set waitfor = FALSE mode.post_setup() @@ -377,8 +382,6 @@ SUBSYSTEM_DEF(ticker) LAZYOR(player.client.prefs.characters_joined_as, player.new_character.real_name) else stack_trace("WARNING: Either a player did not have a new_character, did not have a client, or did not have preferences. This is VERY bad.") - else - player.new_player_panel() CHECK_TICK /datum/controller/subsystem/ticker/proc/collect_minds() @@ -602,14 +605,16 @@ SUBSYSTEM_DEF(ticker) news_message = "The burst of energy released near [station_name()] has been confirmed as merely a test of a new weapon. However, due to an unexpected mechanical error, their communications system has been knocked offline." if(SHUTTLE_HIJACK) news_message = "During routine evacuation procedures, the emergency shuttle of [station_name()] had its navigation protocols corrupted and went off course, but was recovered shortly after." - if(GANG_VICTORY) - news_message = "Company officials reaffirmed that sudden deployments of special forces are not in any way connected to rumors of [station_name()] being covered in graffiti." + if(GANG_OPERATING) + news_message = "The company would like to state that any rumors of criminal organizing on board stations such as [station_name()] are falsehoods, and not to be emulated." + if(GANG_DESTROYED) + news_message = "The crew of [station_name()] would like to thank the Spinward Stellar Coalition Police Department for quickly resolving a minor terror threat to the station." if(SSblackbox.first_death) var/list/ded = SSblackbox.first_death if(ded.len) var/last_words = ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : "" - news_message += "\nNT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died. Their name was: [ded["name"]], [ded["role"]], at [ded["area"]].[last_words]" + news_message += "\nNT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died.\nTheir name was: [ded["name"]], [ded["role"]], at [ded["area"]].[last_words]" else news_message += "\nNT Sanctioned Psykers proudly confirm reports that nobody died this shift!" @@ -630,19 +635,12 @@ SUBSYSTEM_DEF(ticker) else timeLeft = newtime -//Everyone who wanted to be an observer gets made one now -/datum/controller/subsystem/ticker/proc/create_observers() - for(var/mob/dead/new_player/player in GLOB.player_list) - if(player.ready == PLAYER_READY_TO_OBSERVE && player.mind) - //Break chain since this has a sleep input in it - addtimer(CALLBACK(player, /mob/dead/new_player.proc/make_me_an_observer), 1) - /datum/controller/subsystem/ticker/proc/load_mode() var/mode = trim(file2text("data/mode.txt")) if(mode) GLOB.master_mode = mode else - GLOB.master_mode = "extended" + GLOB.master_mode = GLOB.dynamic_forced_extended log_game("Saved mode is '[GLOB.master_mode]'") /datum/controller/subsystem/ticker/proc/save_mode(the_mode) diff --git a/code/controllers/subsystem/title.dm b/code/controllers/subsystem/title.dm index 3cc3d9dd99..1dbfb1540c 100644 --- a/code/controllers/subsystem/title.dm +++ b/code/controllers/subsystem/title.dm @@ -10,7 +10,7 @@ SUBSYSTEM_DEF(title) /datum/controller/subsystem/title/Initialize() if(file_path && icon) - return ..() + return if(fexists("data/previous_title.dat")) var/previous_path = file2text("data/previous_title.dat") @@ -31,13 +31,16 @@ SUBSYSTEM_DEF(title) if(length(title_screens)) file_path = "[global.config.directory]/title_screens/images/[pick(title_screens)]" - if(!file_path || !fexists(file_path)) - file_path = "icons/default_title.dmi" + if(!file_path) + file_path = "icons/runtime/default_title.dmi" - if(fexists(file_path)) - icon = new(fcopy_rsc(file_path)) - if(splash_turf) - splash_turf.icon = icon + ASSERT(fexists(file_path)) + + icon = new(fcopy_rsc(file_path)) + + if(splash_turf) + splash_turf.icon = icon + splash_turf.handle_generic_titlescreen_sizes() return ..() diff --git a/code/controllers/subsystem/traumas.dm b/code/controllers/subsystem/traumas.dm index 9a0665e91f..7f1ece6937 100644 --- a/code/controllers/subsystem/traumas.dm +++ b/code/controllers/subsystem/traumas.dm @@ -107,7 +107,7 @@ SUBSYSTEM_DEF(traumas) /obj/item/clothing/under/rank/medical/doctor/nurse, /obj/item/clothing/under/rank/medical/chief_medical_officer, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/pill/, /obj/item/reagent_containers/hypospray, /obj/item/storage/firstaid, /obj/item/storage/pill_bottle, /obj/item/healthanalyzer, - /obj/structure/sign/departments/medbay, /obj/machinery/door/airlock/medical, /obj/machinery/sleeper, + /obj/structure/sign/departments/medbay, /obj/machinery/door/airlock/medical, /obj/machinery/sleeper, /obj/machinery/stasis, /obj/machinery/dna_scannernew, /obj/machinery/atmospherics/components/unary/cryo_cell, /obj/item/surgical_drapes, /obj/item/retractor, /obj/item/hemostat, /obj/item/cautery, /obj/item/surgicaldrill, /obj/item/scalpel, /obj/item/circular_saw, /obj/item/clothing/suit/bio_suit/plaguedoctorsuit, /obj/item/clothing/head/plaguedoctorhat, /obj/item/clothing/mask/gas/plaguedoctor)), @@ -159,7 +159,7 @@ SUBSYSTEM_DEF(traumas) /obj/item/storage/backpack/mime, /obj/item/reagent_containers/food/snacks/grown/banana/mime, /obj/item/grown/bananapeel/mimanapeel, /obj/item/cartridge/virus/mime, /obj/item/clothing/shoes/sneakers/mime, /obj/item/bedsheet/mime, /obj/item/reagent_containers/food/snacks/burger/mime, /obj/item/clothing/head/beret, - /obj/item/toy/figure/mime, /obj/item/toy/crayon/mime, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced, /obj/mecha/combat/reticence)), + /obj/item/toy/figure/mime, /obj/item/toy/crayon/mime, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced, /obj/vehicle/sealed/mecha/combat/reticence)), "cats" = typecacheof(list(/obj/item/organ/ears/cat, /obj/item/organ/tail/cat, /obj/item/laser_pointer, /obj/item/toy/cattoy, /obj/item/clothing/head/kitty, /obj/item/clothing/head/collectable/kitty, /obj/item/melee/chainofcommand/tailwhip/kitty, /obj/item/stack/sheet/animalhide/cat)), @@ -169,7 +169,7 @@ SUBSYSTEM_DEF(traumas) /obj/structure/fluff/empty_sleeper/syndicate, /obj/item/implant/radio/syndicate, /obj/item/clothing/head/helmet/space/syndicate, /obj/machinery/nuclearbomb/syndicate, /obj/item/grenade/syndieminibomb, /obj/item/storage/backpack/duffelbag/syndie, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver, /obj/item/gun/ballistic/automatic/shotgun/bulldog, /obj/item/gun/ballistic/automatic/c20r, /obj/item/gun/ballistic/automatic/m90, /obj/item/gun/ballistic/automatic/l6_saw, /obj/item/storage/belt/grenade/full, /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate, /obj/item/gun/energy/kinetic_accelerator/crossbow, /obj/item/melee/transforming/energy/sword/saber, /obj/item/dualsaber, /obj/item/melee/powerfist, /obj/item/storage/box/syndie_kit, /obj/item/grenade/spawnergrenade/manhacks, /obj/item/grenade/chem_grenade/bioterrorfoam, /obj/item/reagent_containers/spray/chemsprayer/bioterror, /obj/item/ammo_box/magazine/m10mm, - /obj/item/ammo_box/magazine/pistolm9mm, /obj/item/ammo_box/a357, /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/mm195x129, /obj/item/antag_spawner/nuke_ops, /obj/mecha/combat/gygax/dark, /obj/mecha/combat/marauder/mauler, /obj/item/soap/syndie, /obj/item/gun/syringe/syndicate, /obj/item/cartridge/virus/syndicate, + /obj/item/ammo_box/magazine/pistolm9mm, /obj/item/ammo_box/a357, /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/mm712x82, /obj/item/antag_spawner/nuke_ops, /obj/vehicle/sealed/mecha/combat/gygax/dark, /obj/vehicle/sealed/mecha/combat/marauder/mauler, /obj/item/soap/syndie, /obj/item/gun/syringe/syndicate, /obj/item/cartridge/virus/syndicate, /obj/item/cartridge/virus/frame, /obj/item/chameleon, /obj/item/storage/box/syndie_kit/cutouts, /obj/item/clothing/suit/space/hardsuit/syndi, /obj/item/card/emag, /obj/item/storage/toolbox/syndicate, /obj/item/storage/book/bible/syndicate, /obj/item/encryptionkey/binary, /obj/item/encryptionkey/syndicate, /obj/item/aiModule/syndicate, /obj/item/clothing/shoes/magboots/syndie, /obj/item/powersink, /obj/item/sbeacondrop, /obj/item/sbeacondrop/bomb, /obj/item/syndicatedetonator, /obj/item/shield/energy, /obj/item/assault_pod, /obj/item/slimepotion/slime/sentience/nuclear, /obj/item/stack/telecrystal, /obj/item/jammer, /obj/item/codespeak_manual/unlimited, /obj/item/toy/cards/deck/syndicate, /obj/item/storage/secure/briefcase/syndie, /obj/item/storage/fancy/cigarettes/cigpack_syndicate, /obj/item/toy/syndicateballoon, /obj/item/clothing/gloves/fingerless/pugilist/rapid, /obj/item/paper/fluff/ruins/thederelict/syndie_mission, /obj/item/organ/cyberimp/eyes/hud/security/syndicate, /obj/item/clothing/head/HoS/syndicate, diff --git a/code/controllers/subsystem/vis_overlays.dm b/code/controllers/subsystem/vis_overlays.dm index b0e5d6c689..0572532fda 100644 --- a/code/controllers/subsystem/vis_overlays.dm +++ b/code/controllers/subsystem/vis_overlays.dm @@ -5,12 +5,10 @@ SUBSYSTEM_DEF(vis_overlays) init_order = INIT_ORDER_VIS var/list/vis_overlay_cache - var/list/unique_vis_overlays var/list/currentrun /datum/controller/subsystem/vis_overlays/Initialize() vis_overlay_cache = list() - unique_vis_overlays = list() return ..() /datum/controller/subsystem/vis_overlays/fire(resumed = FALSE) @@ -30,7 +28,7 @@ SUBSYSTEM_DEF(vis_overlays) if(MC_TICK_CHECK) return -//the "thing" var can be anything with vis_contents which includes images +//the "thing" var can be anything with vis_contents which includes images - in the future someone should totally allow vis overlays to be passed in as an arg instead of all this bullshit /datum/controller/subsystem/vis_overlays/proc/add_vis_overlay(atom/movable/thing, icon, iconstate, layer, plane, dir, alpha = 255, add_appearance_flags = NONE, unique = FALSE) var/obj/effect/overlay/vis/overlay if(!unique) @@ -45,7 +43,6 @@ SUBSYSTEM_DEF(vis_overlays) overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags) overlay.cache_expiration = -1 var/cache_id = "\ref[overlay]@{[world.time]}" - unique_vis_overlays += overlay vis_overlay_cache[cache_id] = overlay . = overlay thing.vis_contents += overlay diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 2474a6f272..407a8f927c 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -32,6 +32,8 @@ SUBSYSTEM_DEF(vote) var/list/stored_modetier_results = list() // The aggregated tier list of the modes available in secret. + var/transfer_votes_done = 0 + /datum/controller/subsystem/vote/fire() //called by master_controller if(mode) if(end_time < world.time) @@ -68,7 +70,7 @@ SUBSYSTEM_DEF(vote) //get the highest number of votes var/greatest_votes = 0 var/total_votes = 0 - if(mode == "gamemode" && CONFIG_GET(flag/must_be_readied_to_vote_gamemode)) + if((mode == "gamemode" || mode == "roundtype") && CONFIG_GET(flag/must_be_readied_to_vote_gamemode)) for(var/mob/dead/new_player/P in GLOB.player_list) if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey]) choices[choices[voted[P.ckey]]]-- @@ -104,8 +106,7 @@ SUBSYSTEM_DEF(vote) return . /datum/controller/subsystem/vote/proc/calculate_condorcet_votes(var/blackbox_text) - // https://en.wikipedia.org/wiki/Schulze_method#Implementation - if((mode == "gamemode" || mode == "dynamic") && CONFIG_GET(flag/must_be_readied_to_vote_gamemode)) + if((mode == "gamemode" || mode == "dynamic" || mode == "roundtype") && CONFIG_GET(flag/must_be_readied_to_vote_gamemode)) for(var/mob/dead/new_player/P in GLOB.player_list) if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey]) voted -= P.ckey @@ -155,7 +156,7 @@ SUBSYSTEM_DEF(vote) for(var/choice in choices) scores_by_choice += "[choice]" scores_by_choice["[choice]"] = list() - if((mode == "gamemode" || mode == "dynamic") && CONFIG_GET(flag/must_be_readied_to_vote_gamemode)) + if((mode == "gamemode" || mode == "dynamic" || mode == "roundtype") && CONFIG_GET(flag/must_be_readied_to_vote_gamemode)) for(var/mob/dead/new_player/P in GLOB.player_list) if(P.ready != PLAYER_READY_TO_PLAY && voted[P.ckey]) voted -= P.ckey @@ -249,8 +250,18 @@ SUBSYSTEM_DEF(vote) if(vote_system == SCORE_VOTING) calculate_scores(vote_title_text) if(vote_system == HIGHEST_MEDIAN_VOTING) - calculate_highest_median(vote_title_text) // nothing uses this at the moment - var/list/winners = vote_system == INSTANT_RUNOFF_VOTING ? get_runoff_results() : get_result() + calculate_highest_median(vote_title_text) + var/list/winners = list() + if(mode == "transfer") + var/amount_required = 1 + transfer_votes_done + transfer_votes_done += 1 + text += "\nExtending requires at least [amount_required] votes to win." + if(choices[VOTE_CONTINUE] < amount_required || choices[VOTE_TRANSFER] >= choices[VOTE_CONTINUE]) + winners = list(VOTE_TRANSFER) + else + winners = list(VOTE_CONTINUE) + else + winners = vote_system == INSTANT_RUNOFF_VOTING ? get_runoff_results() : get_result() var/was_roundtype_vote = mode == "roundtype" || mode == "dynamic" if(winners.len > 0) if(was_roundtype_vote) @@ -306,14 +317,14 @@ SUBSYSTEM_DEF(vote) if(vote_system == SCHULZE_VOTING) admintext += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!" else if(vote_system == HIGHEST_MEDIAN_VOTING) - admintext += "\nIt should be noted that this is not a raw tally of votes but the number of runoffs done by majority judgement!" + admintext += "\nIt should be noted that this is not a raw tally of votes but rather the median score plus a tiebreaker!" for(var/i=1,i<=choices.len,i++) var/votes = choices[choices[i]] - admintext += "\n[choices[i]]: [votes]" + admintext += "\n[choices[i]]: [votes ? votes : "0"]" //This is raw data, but the raw data is null by default. If ya don't compensate for it, then it'll look weird! else for(var/i=1,i<=scores.len,i++) var/score = scores[scores[i]] - admintext += "\n[scores[i]]: [score]" + admintext += "\n[scores[i]]: [score ? score : "0"]" message_admins(admintext) return . @@ -322,51 +333,17 @@ SUBSYSTEM_DEF(vote) var/restart = 0 if(.) switch(mode) - if("roundtype") //CIT CHANGE - adds the roundstart extended/secret vote + if("roundtype") //CIT CHANGE - adds the roundstart extended/dynamic vote if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started. return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.") - GLOB.master_mode = . - SSticker.save_mode(.) + GLOB.master_mode = "dynamic" + if(. == "extended") + GLOB.dynamic_extended = TRUE message_admins("The gamemode has been voted for, and has been changed to: [GLOB.master_mode]") log_admin("Gamemode has been voted for and switched to: [GLOB.master_mode].") - if(CONFIG_GET(flag/modetier_voting)) - reset() - started_time = 0 - initiate_vote("mode tiers","server", votesystem=SCORE_VOTING, forced=TRUE, vote_time = 30 MINUTES) - to_chat(world,"The vote will end right as the round starts.") - return . if("restart") if(. == "Restart Round") restart = 1 - if("gamemode") - if(GLOB.master_mode != .) - SSticker.save_mode(.) - if(SSticker.HasRoundStarted()) - restart = 1 - else - GLOB.master_mode = . - if("mode tiers") - var/list/raw_score_numbers = list() - for(var/score_name in scores) - sorted_insert(raw_score_numbers,scores[score_name],/proc/cmp_numeric_asc) - stored_modetier_results = scores.Copy() - for(var/score_name in stored_modetier_results) - if(stored_modetier_results[score_name] <= raw_score_numbers[CONFIG_GET(number/dropped_modes)]) - stored_modetier_results -= score_name - stored_modetier_results += "traitor" - if("dynamic") - if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started. - return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.") - var/list/runnable_storytellers = config.get_runnable_storytellers() - var/datum/dynamic_storyteller/picked - for(var/T in runnable_storytellers) - var/datum/dynamic_storyteller/S = T - if(stored_gamemode_votes[initial(S.name)] == 1 && CHECK_BITFIELD(initial(S.flags), FORCE_IF_WON)) - picked = S - runnable_storytellers[S] *= round(stored_gamemode_votes[initial(S.name)]*100000,1) - if(!picked) - picked = pickweight(runnable_storytellers, 0) - GLOB.dynamic_storyteller_type = picked if("map") var/datum/map_config/VM = config.maplist[.] message_admins("The map has been voted for and will change to: [VM.map_name]") @@ -374,7 +351,7 @@ SUBSYSTEM_DEF(vote) if(SSmapping.changemap(config.maplist[.])) to_chat(world, "The map vote has chosen [VM.map_name] for next round!") if("transfer") // austation begin -- Crew autotransfer vote - if(. == "Initiate Crew Transfer") + if(. == VOTE_TRANSFER) SSshuttle.autoEnd() var/obj/machinery/computer/communications/C = locate() in GLOB.machines if(C) @@ -481,26 +458,9 @@ SUBSYSTEM_DEF(vote) continue choices |= M if("transfer") // austation begin -- Crew autotranfer vote - choices.Add("Initiate Crew Transfer","Continue Playing") // austation end + choices.Add(VOTE_TRANSFER,VOTE_CONTINUE) // austation end if("roundtype") //CIT CHANGE - adds the roundstart secret/extended vote - choices.Add("secret", "extended") - if("mode tiers") - var/list/modes_to_add = config.votable_modes - var/list/probabilities = CONFIG_GET(keyed_list/probability) - for(var/tag in modes_to_add) - if(probabilities[tag] <= 0) - modes_to_add -= tag - modes_to_add -= "traitor" // makes it so that traitor is always available - choices.Add(modes_to_add) - if("dynamic") - GLOB.master_mode = "dynamic" - var/list/probabilities = CONFIG_GET(keyed_list/storyteller_weight) - for(var/T in config.get_runnable_storytellers()) - var/datum/dynamic_storyteller/S = T - var/probability = ((initial(S.config_tag) in probabilities) ? probabilities[initial(S.config_tag)] : initial(S.weight)) - if(probability > 0) - choices.Add(initial(S.name)) - choice_descs.Add(initial(S.desc)) + choices.Add("dynamic", "extended") if("custom") question = stripped_input(usr,"What is the vote for?") if(!question) diff --git a/code/datums/accents.dm b/code/datums/accents.dm index d9e073b729..cfd6e873fa 100644 --- a/code/datums/accents.dm +++ b/code/datums/accents.dm @@ -94,10 +94,9 @@ /datum/accent/dullahan/modify_speech(list/speech_args, datum/source, mob/living/carbon/owner) if(owner) - if(isdullahan(owner)) - var/datum/species/dullahan/D = owner.dna.species - if(isobj(D.myhead.loc)) - var/obj/O = D.myhead.loc - O.say(speech_args[SPEECH_MESSAGE]) + var/datum/component/dullahan/dullahan = owner.GetComponent(/datum/component/dullahan) + if(dullahan) + if(dullahan.dullahan_head) + dullahan.dullahan_head.say(speech_args[SPEECH_MESSAGE]) speech_args[SPEECH_MESSAGE] = "" return speech_args diff --git a/code/datums/achievements/_achievement_data.dm b/code/datums/achievements/_achievement_data.dm index 80f544a965..12c8256c74 100644 --- a/code/datums/achievements/_achievement_data.dm +++ b/code/datums/achievements/_achievement_data.dm @@ -109,7 +109,7 @@ /datum/achievement_data/ui_data(mob/user) var/ret_data = list() // screw standards (qustinnus you must rename src.data ok) - ret_data["categories"] = list("Bosses", "Misc", "Mafia", "Scores") + ret_data["categories"] = list("Bosses", "Jobs", "Misc", "Mafia", "Scores") ret_data["achievements"] = list() ret_data["user_key"] = user.ckey diff --git a/code/datums/achievements/_awards.dm b/code/datums/achievements/_awards.dm index 77485de8ba..22296b90f5 100644 --- a/code/datums/achievements/_awards.dm +++ b/code/datums/achievements/_awards.dm @@ -2,7 +2,7 @@ ///Name of the achievement, If null it won't show up in the achievement browser. (Handy for inheritance trees) var/name var/desc = "You did it." - ///Found in UI_Icons/Achievements + ///Found in ui_icons/achievements var/icon = "default" var/category = "Normal" @@ -78,7 +78,7 @@ /datum/award/achievement/on_unlock(mob/user) . = ..() - to_chat(user, "Achievement unlocked: [name]!") + to_chat(user, span_greenannounce("Achievement unlocked: [name]!")) ///Scores are for leaderboarded things, such as killcount of a specific boss /datum/award/score diff --git a/code/datums/achievements/boss_achievements.dm b/code/datums/achievements/boss_achievements.dm index 104a369405..f2ff90945f 100644 --- a/code/datums/achievements/boss_achievements.dm +++ b/code/datums/achievements/boss_achievements.dm @@ -12,7 +12,7 @@ name = "Boss Killer" desc = "You've come a long ways from asking how to switch hands." database_id = "Boss Killer" - // icon = "firstboss" + icon = "firstboss" /datum/award/achievement/boss/blood_miner_kill name = "Blood-Drunk Miner Killer" diff --git a/code/datums/achievements/job_achievements.dm b/code/datums/achievements/job_achievements.dm new file mode 100644 index 0000000000..13a68462ed --- /dev/null +++ b/code/datums/achievements/job_achievements.dm @@ -0,0 +1,34 @@ + +/datum/award/achievement/jobs + category = "Jobs" + icon = "basemisc" + +//chemistry + +/datum/award/achievement/jobs/chemistry_tut + name = "Perfect chemistry blossom" + desc = "Passed the chemistry tutorial with perfect purity!" + database_id = MEDAL_CHEM_TUT + icon = "chem_tut" + +//all of service! hip hip! + +/datum/award/achievement/jobs/service_bad + name = "Centcom Grade: Shitty Service" + desc = "Well, you at least tried. How about trying harder?" + database_id = MEDAL_BAD_SERVICE + icon = "chem_tut" + +/datum/award/achievement/jobs/service_okay + name = "Centcom Grade: Acceptable Service" + desc = "Well, it'll do! You and your department did just fine." + database_id = MEDAL_OKAY_SERVICE + icon = "chem_tut" + +/datum/award/achievement/jobs/service_good + name = "Centcom Grade: Exemplary Service" + desc = "Centcom is very impressed with your department!" + database_id = MEDAL_GOOD_SERVICE + icon = "chem_tut" + +//civilian achievies! while not recognized by the code, it is recognized by our hearts diff --git a/code/datums/achievements/job_scores.dm b/code/datums/achievements/job_scores.dm new file mode 100644 index 0000000000..d860c7e21a --- /dev/null +++ b/code/datums/achievements/job_scores.dm @@ -0,0 +1,14 @@ + +//chef + +/datum/award/score/chef_tourist_score + name = "Tourists Served as Chef Highscore" + desc = "Your highscore on serving tourist bots as chef." + database_id = CHEF_TOURISTS_SERVED + +//bartender + +/datum/award/score/bartender_tourist_score + name = "Tourists Served as Bartender Highscore" + desc = "Your highscore on serving tourist bots as bartender." + database_id = BARTENDER_TOURISTS_SERVED diff --git a/code/datums/achievements/misc_achievements.dm b/code/datums/achievements/misc_achievements.dm index 0da38df8f3..ace74c13a8 100644 --- a/code/datums/achievements/misc_achievements.dm +++ b/code/datums/achievements/misc_achievements.dm @@ -154,8 +154,26 @@ database_id = MEDAL_TOOLBOX_SOUL icon = "toolbox_soul" -/datum/award/achievement/misc/chemistry_tut - name = "Perfect chemistry blossom" - desc = "Passed the chemistry tutorial with perfect purity!" - database_id = MEDAL_CHEM_TUT - icon = "chem_tut" +/datum/award/achievement/misc/hot_damn + name = "Hot Damn!" + desc = "Sometimes you need to make some noise to make a point." + database_id = MEDAL_HOT_DAMN + icon = "hotdamn" + +/datum/award/achievement/misc/cayenne_disk + name = "Very Important Piscis" + desc = "You can rest well now." + database_id = MEDAL_CAYENNE_DISK + icon = "cayenne_disk" + +/datum/award/achievement/misc/tram_surfer + name = "Tram Surfer" + desc = "Lights out, guerilla radio!" + database_id = MEDAL_TRAM_SURFER + icon = "tram_surfer" + +/datum/award/achievement/misc/springlock + name = "The Man Inside the MODsuit" + desc = "Ignore the warning label on a springlock MODsuit." + database_id = MEDAL_SPRINGLOCK + icon = "springlock" diff --git a/code/datums/achievements/misc_scores.dm b/code/datums/achievements/misc_scores.dm index 7ffc50c015..067cd68d7d 100644 --- a/code/datums/achievements/misc_scores.dm +++ b/code/datums/achievements/misc_scores.dm @@ -9,3 +9,9 @@ name = "Maintenance Pills Consumed" desc = "Wait why?" database_id = MAINTENANCE_PILL_SCORE + +///How high of a score on the Intento did we get? +/datum/award/score/intento_score + name = "Intento Score" + desc = "A blast from the future?" + database_id = INTENTO_SCORE diff --git a/code/datums/action.dm b/code/datums/action.dm index 1a8ea7a60f..b34cafc03f 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -23,6 +23,8 @@ var/icon_icon = 'icons/mob/actions.dmi' //This is the file for the ACTION icon var/button_icon_state = "default" //And this is the state for the action icon var/mob/owner + ///List of all mobs that are viewing our action button -> A unique movable for them to view. + var/list/viewers = list() /datum/action/New(Target) link_to(Target) @@ -41,8 +43,7 @@ if(owner) Remove(owner) target = null - qdel(button) - button = null + QDEL_NULL(button) return ..() /datum/action/proc/Grant(mob/M) @@ -121,6 +122,11 @@ return FALSE return TRUE +/datum/action/proc/UpdateButtons(status_only, force) + for(var/datum/hud/hud in viewers) + var/atom/movable/screen/movable/button = viewers[hud] + UpdateButtonIcon(button, status_only, force) + /datum/action/proc/UpdateButtonIcon(status_only = FALSE, force = FALSE) if(!button) return @@ -217,6 +223,8 @@ name = "Toggle Hood" /datum/action/item_action/toggle_firemode + icon_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "fireselect_no" name = "Toggle Firemode" /datum/action/item_action/rcl_col @@ -516,7 +524,7 @@ H.attack_self(owner) return var/obj/item/I = target - if(owner.can_equip(I, SLOT_HANDS)) + if(owner.can_equip(I, ITEM_SLOT_HANDS)) owner.temporarilyRemoveItemFromInventory(I) owner.put_in_hands(I) I.attack_self(owner) diff --git a/code/datums/actions/ninja.dm b/code/datums/actions/ninja.dm deleted file mode 100644 index c0314b9c48..0000000000 --- a/code/datums/actions/ninja.dm +++ /dev/null @@ -1,51 +0,0 @@ -/datum/action/item_action/initialize_ninja_suit - name = "Toggle ninja suit" - -/datum/action/item_action/ninjasmoke - name = "Smoke Bomb" - desc = "Blind your enemies momentarily with a well-placed smoke bomb." - button_icon_state = "smoke" - icon_icon = 'icons/mob/actions/actions_spells.dmi' - -/datum/action/item_action/ninjaboost - name = "Adrenaline Boost" - desc = "Inject a secret chemical that will counteract all movement-impairing effect." - button_icon_state = "repulse" - icon_icon = 'icons/mob/actions/actions_spells.dmi' - required_mobility_flags = NONE - -/datum/action/item_action/ninjapulse - name = "EM Burst (25E)" - desc = "Disable any nearby technology with an electro-magnetic pulse." - button_icon_state = "emp" - icon_icon = 'icons/mob/actions/actions_spells.dmi' - -/datum/action/item_action/ninjastar - name = "Create Throwing Stars (1E)" - desc = "Creates some throwing stars" - button_icon_state = "throwingstar" - icon_icon = 'icons/obj/items_and_weapons.dmi' - -/datum/action/item_action/ninjanet - name = "Energy Net (20E)" - desc = "Captures a fallen opponent in a net of energy. Will teleport them to a holding facility after 30 seconds." - button_icon_state = "energynet" - icon_icon = 'icons/effects/effects.dmi' - -/datum/action/item_action/ninja_sword_recall - name = "Recall Energy Katana (Variable Cost)" - desc = "Teleports the Energy Katana linked to this suit to its wearer, cost based on distance." - button_icon_state = "energy_katana" - icon_icon = 'icons/obj/items_and_weapons.dmi' - -/datum/action/item_action/ninja_stealth - name = "Toggle Stealth" - desc = "Toggles stealth mode on and off." - button_icon_state = "ninja_cloak" - icon_icon = 'icons/mob/actions/actions_minor_antag.dmi' - -/datum/action/item_action/toggle_glove - name = "Toggle interaction" - desc = "Switch between normal interaction and drain mode." - button_icon_state = "s-ninjan" - icon_icon = 'icons/obj/clothing/gloves.dmi' diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index 15115b62c0..b2bffb9653 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -223,6 +223,11 @@ /datum/ai_laws/proc/set_laws_config() var/list/law_ids = CONFIG_GET(keyed_list/random_laws) + + if(HAS_TRAIT(SSstation, STATION_TRAIT_UNIQUE_AI)) + pick_weighted_lawset() + return + switch(CONFIG_GET(number/default_laws)) if(0) add_inherent_law("You may not injure a human being or cause one to come to harm.") diff --git a/code/datums/announcers/_announcer.dm b/code/datums/announcers/_announcer.dm new file mode 100644 index 0000000000..dab790438c --- /dev/null +++ b/code/datums/announcers/_announcer.dm @@ -0,0 +1,23 @@ +///Data holder for the announcers that can be used in a game, this can be used to have alternative announcements outside of the default e.g.the intern +/datum/centcom_announcer + ///Roundshift start audio + var/welcome_sounds = list() + ///Sounds made when announcement is receivedc + var/alert_sounds = list() + ///Sounds made when command report is received + var/command_report_sounds = list() + ///Event audio, can be used for specific event announcements and is assoc key - sound. If no sound is found the default is used.area + var/event_sounds = list() + ///Override this to have a custom message to show instead of the normal priority announcement + var/custom_alert_message + + +/datum/centcom_announcer/proc/get_rand_welcome_sound() + return pick(welcome_sounds) + + +/datum/centcom_announcer/proc/get_rand_alert_sound() + return pick(alert_sounds) + +/datum/centcom_announcer/proc/get_rand_report_sound() + return pick(command_report_sounds) diff --git a/code/datums/announcers/default_announcer.dm b/code/datums/announcers/default_announcer.dm new file mode 100644 index 0000000000..4ab045e175 --- /dev/null +++ b/code/datums/announcers/default_announcer.dm @@ -0,0 +1,21 @@ +/datum/centcom_announcer/default + welcome_sounds = list('sound/announcer/classic/welcome.ogg') + alert_sounds = list('sound/announcer/classic/attention.ogg') + command_report_sounds = list('sound/announcer/classic/commandreport.ogg') + event_sounds = list(ANNOUNCER_AIMALF = 'sound/announcer/classic/aimalf.ogg', + ANNOUNCER_ALIENS = 'sound/announcer/classic/aliens.ogg', + ANNOUNCER_ANIMES = 'sound/announcer/classic/animes.ogg', + ANNOUNCER_GRANOMALIES = 'sound/announcer/classic/granomalies.ogg', + ANNOUNCER_INTERCEPT = 'sound/announcer/classic/intercept.ogg', + ANNOUNCER_IONSTORM = 'sound/announcer/classic/ionstorm.ogg', + ANNOUNCER_METEORS = 'sound/announcer/classic/meteors.ogg', + ANNOUNCER_NEWAI = 'sound/announcer/classic/newai.ogg', + ANNOUNCER_OUTBREAK5 = 'sound/announcer/classic/outbreak5.ogg', + ANNOUNCER_OUTBREAK7 = 'sound/announcer/classic/outbreak7.ogg', + ANNOUNCER_POWEROFF = 'sound/announcer/classic/poweroff.ogg', + ANNOUNCER_POWERON = 'sound/announcer/classic/poweron.ogg', + ANNOUNCER_RADIATION = 'sound/announcer/classic/radiation.ogg', + ANNOUNCER_SHUTTLECALLED = 'sound/announcer/classic/shuttlecalled.ogg', + ANNOUNCER_SHUTTLEDOCK = 'sound/announcer/classic/shuttledock.ogg', + ANNOUNCER_SHUTTLERECALLED = 'sound/announcer/classic/shuttlerecalled.ogg', + ANNOUNCER_SPANOMALIES = 'sound/announcer/classic/spanomalies.ogg') diff --git a/code/datums/announcers/intern_announcer.dm b/code/datums/announcers/intern_announcer.dm new file mode 100644 index 0000000000..25065f38b0 --- /dev/null +++ b/code/datums/announcers/intern_announcer.dm @@ -0,0 +1,47 @@ +/datum/centcom_announcer/intern + welcome_sounds = list('sound/announcer/intern/welcome/1.ogg', + 'sound/announcer/intern/welcome/2.ogg', + 'sound/announcer/intern/welcome/3.ogg', + 'sound/announcer/intern/welcome/4.ogg', + 'sound/announcer/intern/welcome/5.ogg', + 'sound/announcer/intern/welcome/6.ogg') + + alert_sounds = list('sound/announcer/intern/alerts/1.ogg', + 'sound/announcer/intern/alerts/2.ogg', + 'sound/announcer/intern/alerts/3.ogg', + 'sound/announcer/intern/alerts/4.ogg', + 'sound/announcer/intern/alerts/5.ogg', + 'sound/announcer/intern/alerts/6.ogg', + 'sound/announcer/intern/alerts/7.ogg', + 'sound/announcer/intern/alerts/8.ogg', + 'sound/announcer/intern/alerts/9.ogg', + 'sound/announcer/intern/alerts/10.ogg', + 'sound/announcer/intern/alerts/11.ogg', + 'sound/announcer/intern/alerts/12.ogg', + 'sound/announcer/intern/alerts/13.ogg', + 'sound/announcer/intern/alerts/14.ogg') + + + command_report_sounds = list('sound/announcer/intern/commandreport/1.ogg', + 'sound/announcer/intern/commandreport/2.ogg', + 'sound/announcer/intern/commandreport/3.ogg') + + event_sounds = list(ANNOUNCER_AIMALF = 'sound/announcer/classic/aimalf.ogg', + ANNOUNCER_ALIENS = 'sound/announcer/intern/aliens.ogg', + ANNOUNCER_ANIMES = 'sound/announcer/intern/animes.ogg', + ANNOUNCER_GRANOMALIES = 'sound/announcer/intern/granomalies.ogg', + ANNOUNCER_INTERCEPT = 'sound/announcer/intern/intercept.ogg', + ANNOUNCER_IONSTORM = 'sound/announcer/intern/ionstorm.ogg', + ANNOUNCER_METEORS = 'sound/announcer/intern/meteors.ogg', + ANNOUNCER_NEWAI = 'sound/announcer/classic/newai.ogg', + ANNOUNCER_OUTBREAK5 = 'sound/announcer/intern/outbreak5.ogg', + ANNOUNCER_OUTBREAK7 = 'sound/announcer/intern/outbreak7.ogg', + ANNOUNCER_POWEROFF = 'sound/announcer/intern/poweroff.ogg', + ANNOUNCER_POWERON = 'sound/announcer/intern/poweron.ogg', + ANNOUNCER_RADIATION = 'sound/announcer/intern/radiation.ogg', + ANNOUNCER_SHUTTLECALLED = 'sound/announcer/intern/shuttlecalled.ogg', + ANNOUNCER_SHUTTLEDOCK = 'sound/announcer/intern/shuttledock.ogg', + ANNOUNCER_SHUTTLERECALLED = 'sound/announcer/intern/shuttlerecalled.ogg', + ANNOUNCER_SPANOMALIES = 'sound/announcer/intern/spanomalies.ogg') + + custom_alert_message = "
Please stand by for an important message from our new intern.
" diff --git a/code/datums/announcers/medbot_announcer.dm b/code/datums/announcers/medbot_announcer.dm new file mode 100644 index 0000000000..ed03ac3fc9 --- /dev/null +++ b/code/datums/announcers/medbot_announcer.dm @@ -0,0 +1,22 @@ +/datum/centcom_announcer/medbot + welcome_sounds = list('sound/announcer/medibot/welcome.ogg', + 'sound/announcer/medibot/newAI.ogg') + alert_sounds = list('sound/announcer/medibot/attention.ogg') + command_report_sounds = list('sound/announcer/medibot/commandreport.ogg') + event_sounds = list(ANNOUNCER_AIMALF = 'sound/announcer/classic/aimalf.ogg', + ANNOUNCER_ALIENS = 'sound/announcer/medibot/aliens.ogg', + ANNOUNCER_ANIMES = 'sound/announcer/medibot/animes.ogg', + ANNOUNCER_GRANOMALIES = 'sound/announcer/medibot/granomalies.ogg', + ANNOUNCER_INTERCEPT = 'sound/announcer/medibot/intercept.ogg', + ANNOUNCER_IONSTORM = 'sound/announcer/medibot/ionstorm.ogg', + ANNOUNCER_METEORS = 'sound/announcer/medibot/meteors.ogg', + ANNOUNCER_NEWAI = 'sound/announcer/medibot/newai.ogg', + ANNOUNCER_OUTBREAK5 = 'sound/announcer/medibot/outbreak5.ogg', + ANNOUNCER_OUTBREAK7 = 'sound/announcer/medibot/outbreak7.ogg', + ANNOUNCER_POWEROFF = 'sound/announcer/medibot/poweroff.ogg', + ANNOUNCER_POWERON = 'sound/announcer/medibot/poweron.ogg', + ANNOUNCER_RADIATION = 'sound/announcer/medibot/radiation.ogg', + ANNOUNCER_SHUTTLECALLED = 'sound/announcer/medibot/shuttlecalled.ogg', + ANNOUNCER_SHUTTLEDOCK = 'sound/announcer/medibot/shuttledocked.ogg', + ANNOUNCER_SHUTTLERECALLED = 'sound/announcer/medibot/shuttlerecalled.ogg', + ANNOUNCER_SPANOMALIES = 'sound/announcer/medibot/spanomalies.ogg') diff --git a/code/datums/armor.dm b/code/datums/armor.dm index 88170541c6..6814706e1e 100644 --- a/code/datums/armor.dm +++ b/code/datums/armor.dm @@ -1,5 +1,18 @@ #define ARMORID "armor-[melee]-[bullet]-[laser]-[energy]-[bomb]-[bio]-[rad]-[fire]-[acid]-[magic]-[wound]" +#define MELEE "melee" +#define BULLET "bullet" +#define LASER "laser" +#define ENERGY "energy" +#define BOMB "bomb" +#define BIO "bio" +#define RAD "rad" +#define FIRE "fire" +#define ACID "acid" +#define MAGIC "magic" +#define WOUND "wound" + + /proc/getArmor(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0, wound = 0) . = locate(ARMORID) if (!.) @@ -56,7 +69,7 @@ return vars[rating] /datum/armor/proc/getList() - return list("melee" = melee, "bullet" = bullet, "laser" = laser, "energy" = energy, "bomb" = bomb, "bio" = bio, "rad" = rad, "fire" = fire, "acid" = acid, "magic" = magic, "wound" = wound) + return list(MELEE = melee, BULLET = bullet, LASER = laser, ENERGY = energy, BOMB = bomb, BIO = bio, RAD = rad, FIRE = fire, ACID = acid, MAGIC = magic, WOUND = wound) /datum/armor/proc/attachArmor(datum/armor/AA) return getArmor(melee+AA.melee, bullet+AA.bullet, laser+AA.laser, energy+AA.energy, bomb+AA.bomb, bio+AA.bio, rad+AA.rad, fire+AA.fire, acid+AA.acid, magic+AA.magic, wound+AA.wound) diff --git a/code/datums/atmosphere/_atmosphere.dm b/code/datums/atmosphere/_atmosphere.dm new file mode 100644 index 0000000000..a516bd46bd --- /dev/null +++ b/code/datums/atmosphere/_atmosphere.dm @@ -0,0 +1,68 @@ +/datum/atmosphere + var/gas_string + var/id + + var/list/base_gases // A list of gases to always have + var/list/normal_gases // A list of allowed gases:base_amount + var/list/restricted_gases // A list of allowed gases like normal_gases but each can only be selected a maximum of one time + var/restricted_chance = 10 // Chance per iteration to take from restricted gases + + var/minimum_pressure + var/maximum_pressure + + var/minimum_temp + var/maximum_temp + +/datum/atmosphere/New() + generate_gas_string() + +/datum/atmosphere/proc/check_for_sanity(datum/gas_mixture/mix) + return + +/datum/atmosphere/proc/generate_gas_string() + var/list/spicy_gas = restricted_gases.Copy() + var/target_pressure = rand(minimum_pressure, maximum_pressure) + var/pressure_scale = target_pressure / maximum_pressure + + if(HAS_TRAIT(SSstation, STATION_TRAIT_UNNATURAL_ATMOSPHERE)) + restricted_chance = restricted_chance + 40 + + // First let's set up the gasmix and base gases for this template + // We make the string from a gasmix in this proc because gases need to calculate their pressure + var/datum/gas_mixture/gasmix = new + gasmix.set_temperature(rand(minimum_temp, maximum_temp)) + for(var/i in base_gases) + gasmix.set_moles(i, base_gases[i]) + + // Now let the random choices begin + var/gastype + var/amount + while(gasmix.return_pressure() < target_pressure) + if(!prob(restricted_chance) || !length(spicy_gas)) + gastype = pick(normal_gases) + amount = normal_gases[gastype] + else + gastype = pick(spicy_gas) + amount = spicy_gas[gastype] + spicy_gas -= gastype //You can only pick each restricted gas once + + amount *= rand(50, 200) / 100 // Randomly modifes the amount from half to double the base for some variety + amount *= pressure_scale // If we pick a really small target pressure we want roughly the same mix but less of it all + amount = CEILING(amount, 0.1) + + gasmix.adjust_moles(gastype, amount) + + // That last one put us over the limit, remove some of it + if(gasmix.return_pressure() > target_pressure) + var/moles_to_remove = (1 - target_pressure / gasmix.return_pressure()) * gasmix.total_moles() + gasmix.adjust_moles(gastype, -moles_to_remove) + gasmix.set_moles(gastype, FLOOR(gasmix.get_moles(gastype), 0.1)) + + check_for_sanity(gasmix) + + // Now finally lets make that string + var/list/gas_string_builder = list() + for(var/id in gasmix.get_gases()) + gas_string_builder += "[id]=[gasmix.get_moles(id)]" + gas_string_builder += "TEMP=[gasmix.return_temperature()]" + gas_string = gas_string_builder.Join(";") diff --git a/code/datums/atmosphere/planetary.dm b/code/datums/atmosphere/planetary.dm new file mode 100644 index 0000000000..2324c4780a --- /dev/null +++ b/code/datums/atmosphere/planetary.dm @@ -0,0 +1,86 @@ +// Atmos types used for planetary airs +/datum/atmosphere/lavaland + id = LAVALAND_DEFAULT_ATMOS + + base_gases = list( + GAS_O2=5, + GAS_N2=10, + ) + normal_gases = list( + GAS_O2=5, + GAS_N2=5, + GAS_CO2=5, + ) + restricted_gases = list( + GAS_BZ=0.1, + GAS_BROMINE=0.1 + ) + + minimum_pressure = HAZARD_LOW_PRESSURE + 10 + maximum_pressure = LAVALAND_EQUIPMENT_EFFECT_PRESSURE - 1 + + minimum_temp = 281 + maximum_temp = 320 + +/datum/atmosphere/lavaland/generate_gas_string() + if(prob(restricted_chance)) + base_gases = list( + GAS_METHANE=5, + GAS_N2=10 + ) + normal_gases = list( + GAS_METHANE=5, + GAS_N2=5, + ) + restricted_gases = list( + GAS_AMMONIA = 0.1, + GAS_METHYL_BROMIDE = 0.1, + GAS_HYDROGEN = 0.1 + ) + return ..() + +/datum/atmosphere/lavaland/check_for_sanity(datum/gas_mixture/mix) + if(mix.get_moles(GAS_METHANE) < 0.1) + var/datum/breathing_class/o2_class = GLOB.gas_data.breathing_classes[BREATH_OXY] + while(o2_class.get_effective_pp(mix) < 10) + mix.adjust_moles(GAS_CO2, -0.5) + mix.adjust_moles(GAS_O2, 0.5) + +/datum/atmosphere/icemoon + id = ICEMOON_DEFAULT_ATMOS + + base_gases = list( + GAS_METHANE=5, + GAS_N2=10, + ) + normal_gases = list( + GAS_METHANE=5, + GAS_N2=10 + ) + restricted_gases = list( + GAS_METHYL_BROMIDE=0.1, + GAS_HYDROGEN=0.1 + ) + restricted_chance = 5 + + minimum_pressure = HAZARD_LOW_PRESSURE + 10 + maximum_pressure = LAVALAND_EQUIPMENT_EFFECT_PRESSURE - 1 + + minimum_temp = 180 + maximum_temp = 180 + +/datum/atmosphere/icemoon/generate_gas_string() + if(prob(restricted_chance)) + base_gases = list( + GAS_O2=5, + GAS_N2=10, + ) + normal_gases = list( + GAS_O2=5, + GAS_N2=10, + ) + restricted_gases = list( + GAS_BZ = 0.1, + GAS_METHYL_BROMIDE = 0.1, + ) + return ..() diff --git a/code/datums/bark.dm b/code/datums/bark.dm new file mode 100644 index 0000000000..2bf3d7c69a --- /dev/null +++ b/code/datums/bark.dm @@ -0,0 +1,150 @@ +//Datums for barks and bark accessories + +/datum/bark + var/name = "Default" + var/id = "Default" + var/soundpath //Path for the actual sound file used for the bark + + // Pitch vars. The actual range for a bark is [(pitch - (maxvariance*0.5)) to (pitch + (maxvariance*0.5))] + // Make absolutely sure to take variance into account when curating a sound for bark purposes. + var/minpitch = BARK_DEFAULT_MINPITCH + var/maxpitch = BARK_DEFAULT_MAXPITCH + var/minvariance = BARK_DEFAULT_MINVARY + var/maxvariance = BARK_DEFAULT_MAXVARY + + // Speed vars. Speed determines the number of characters required for each bark, with lower speeds being faster with higher bark density + var/minspeed = BARK_DEFAULT_MINSPEED + var/maxspeed = BARK_DEFAULT_MAXSPEED + + // Visibility vars. Regardless of what's set below, these can still be obtained via adminbus and genetics. Rule of fun. + var/list/ckeys_allowed + var/ignore = FALSE //Controls whether or not this can be chosen in chargen + var/allow_random = FALSE //Allows chargen randomization to use this. This is mainly to restrict the pool to sounds that fit well for most characters + + +// So the basic jist of the sound design here: We make use primarily of shorter instrument samples for barks. We would've went with animalese instead, but doing so would've involved quite a bit of overhead to saycode. +// Short instrument samples tend to sound surprisingly nice for barks, being able to be played in rapid succession without being outright obnoxious. +// It isn't just instruments that work well here, however. Anything that works well as a stab? Short attack, no sustain, a decent amount of release? Also works extremely well for barks. + +/datum/bark/mutedc2 + name = "Muted String (Low)" + id = "mutedc2" + soundpath = 'sound/instruments/synthesis_samples/guitar/crisis_muted/C2.ogg' + allow_random = TRUE + +/datum/bark/mutedc3 + name = "Muted String (Medium)" + id = "mutedc3" + soundpath = 'sound/instruments/synthesis_samples/guitar/crisis_muted/C3.ogg' + allow_random = TRUE + +/datum/bark/mutedc4 + name = "Muted String (High)" + id = "mutedc4" + soundpath = 'sound/instruments/synthesis_samples/guitar/crisis_muted/C4.ogg' + allow_random = TRUE + +/datum/bark/banjoc3 + name = "Banjo (Medium)" + id = "banjoc3" + soundpath = 'sound/instruments/banjo/Cn3.ogg' + allow_random = TRUE + +/datum/bark/banjoc4 + name = "Banjo (High)" + id = "banjoc4" + soundpath = 'sound/instruments/banjo/Cn4.ogg' + allow_random = TRUE + +/datum/bark/squeaky + name = "Squeaky" + id = "squeak" + soundpath = 'sound/items/toysqueak1.ogg' + maxspeed = 4 + +/datum/bark/beep + name = "Beepy" + id = "beep" + soundpath = 'sound/machines/terminal_select.ogg' + maxpitch = 1 //Bringing the pitch higher just hurts your ears :< + maxspeed = 4 //This soundbyte's too short for larger speeds to not sound awkward + +/datum/bark/chitter + name = "Chittery" + id = "chitter" + minspeed = 4 //Even with the sound being replaced with a unique, shorter sound, this is still a little too long for higher speeds + soundpath = 'sound/voice/barks/chitter.ogg' + +/datum/bark/synthetic_grunt + name = "Synthetic (Grunt)" + id = "synthgrunt" + soundpath = 'sound/misc/bloop.ogg' + +/datum/bark/synthetic + name = "Synthetic (Normal)" + id = "synth" + soundpath = 'sound/machines/uplinkerror.ogg' + +/datum/bark/bullet + name = "Windy" + id = "bullet" + maxpitch = 1.6 //This works well with higher pitches! + soundpath = 'sound/weapons/bulletflyby.ogg' //This works... Surprisingly well as a bark? It's neat! + +/datum/bark/coggers + name = "Brassy" + id = "coggers" + soundpath = 'sound/machines/clockcult/integration_cog_install.ogg' //Yet another unexpectedly good bark sound + + +// Genetics-only/admin-only sounds. These either clash hard with the audio design of the above sounds, or have some other form of audio design issue, but aren't *too* awful as a sometimes thing. +// Rule of fun very much applies to this section. Audio design is extremely important for the above section, but down here? No gods, no masters, pure anarchy. +// The min/max variables simply don't apply to these, as only chargen cares about them. As such, there's no need to define those. + +/datum/bark/bikehorn + name = "Bikehorn" + id = "horn" + soundpath = 'sound/instruments/bikehorn/Cn4.ogg' + ignore = TRUE // This is an unusually quiet sound. + +/datum/bark/bwoink + name = "Bwoink" + id = "bwoink" + soundpath = 'sound/effects/adminhelp.ogg' + ignore = TRUE // Emergent heart attack generation + +/datum/bark/merp + name = "Merp" + id = "merp" + soundpath = 'modular_citadel/sound/voice/merp.ogg' + ignore = TRUE + +/datum/bark/bark + name = "Bark" + id = "bark" + soundpath = 'modular_citadel/sound/voice/bark1.ogg' + ignore = TRUE + +/datum/bark/nya + name = "Nya" + id = "nya" + soundpath = 'modular_citadel/sound/voice/nya.ogg' + ignore = TRUE + +/datum/bark/moff + name = "Moff" + id = "moff" + soundpath = 'modular_citadel/sound/voice/mothsqueak.ogg' + ignore = TRUE + +/datum/bark/weh + name = "Weh" + id = "weh" + soundpath = 'modular_citadel/sound/voice/weh.ogg' + ignore = TRUE + +/datum/bark/honk + name = "Annoying Honk" + id = "honk" + soundpath = 'sound/creatures/goose1.ogg' + ignore = TRUE diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm index 92c4e55699..eb5e3c0735 100644 --- a/code/datums/brain_damage/mild.dm +++ b/code/datums/brain_damage/mild.dm @@ -264,3 +264,36 @@ speak_dejavu += speech_args[SPEECH_MESSAGE] else speak_dejavu += speech_args[SPEECH_MESSAGE] + +/datum/brain_trauma/mild/redacted + name = "Confidentiality Trauma" + desc = "Patient's language neurons seem to be warped in a strange manner, resulting in them being unable to speak properly." + scan_desc = "\[REDACTED]" + gain_text = "You feel the need to \[REDACTED]" + lose_text = "You no longer feel the need to \[REDACTED]." + +/datum/brain_trauma/mild/redacted/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + if(message) + var/list/message_split = splittext(message, " ") + var/list/new_message = list() + + for(var/word in message_split) + var/suffix = "" + var/suffix_foundon = 0 + for(var/potential_suffix in list("." , "," , ";" , "!" , ":" , "?")) + suffix_foundon = findtext(word, potential_suffix, -length(potential_suffix)) + if(suffix_foundon) + suffix = potential_suffix + break + + if(suffix_foundon) + word = copytext(word, 1, suffix_foundon) + + word = html_decode(word) + + if(prob(25)) + word = pick(list("\[REDACTED]", "\[CLASSIFIED]", "\[EXPUNGED]")) + new_message += word + suffix + message = jointext(new_message, " ") + speech_args[SPEECH_MESSAGE] = trim(message) diff --git a/code/datums/brain_damage/phobia.dm b/code/datums/brain_damage/phobia.dm index 279118d877..8010f5dc6f 100644 --- a/code/datums/brain_damage/phobia.dm +++ b/code/datums/brain_damage/phobia.dm @@ -83,13 +83,19 @@ return if(HAS_TRAIT(owner, TRAIT_FEARLESS)) return + + var/matches = FALSE + var/mainsource for(var/word in trigger_words) - var/regex/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "i") + var/regex/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "ig") if(findtext(hearing_args[HEARING_RAW_MESSAGE], reg)) - addtimer(CALLBACK(src, .proc/freak_out, null, word), 10) //to react AFTER the chat message - hearing_args[HEARING_RAW_MESSAGE] = reg.Replace(hearing_args[HEARING_RAW_MESSAGE], "$1") - break + hearing_args[HEARING_RAW_MESSAGE] = reg.Replace(hearing_args[HEARING_RAW_MESSAGE], "$0") + matches = TRUE + mainsource = word + + if(matches) + addtimer(CALLBACK(src, .proc/freak_out, null, mainsource), 10) //to react AFTER the chat message /datum/brain_trauma/mild/phobia/handle_speech(datum/source, list/speech_args) if(HAS_TRAIT(owner, TRAIT_FEARLESS)) diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm index ed0a9fbab8..88008920b9 100644 --- a/code/datums/brain_damage/severe.dm +++ b/code/datums/brain_damage/severe.dm @@ -224,6 +224,7 @@ else to_chat(owner, "You feel your heart lurching in your chest...") owner.adjustOxyLoss(8) + else /datum/brain_trauma/severe/discoordination name = "Discoordination" diff --git a/code/datums/brain_damage/special.dm b/code/datums/brain_damage/special.dm index 7cc5348a0a..d4631f2558 100644 --- a/code/datums/brain_damage/special.dm +++ b/code/datums/brain_damage/special.dm @@ -99,7 +99,7 @@ var/obj/effect/hallucination/simple/bluespace_stream/linked_to var/mob/living/carbon/seer -/obj/effect/hallucination/simple/bluespace_stream/Initialize() +/obj/effect/hallucination/simple/bluespace_stream/Initialize(mapload) . = ..() QDEL_IN(src, 300) diff --git a/code/datums/brain_damage/split_personality.dm b/code/datums/brain_damage/split_personality.dm index 6b84e1362d..44a1a76b08 100644 --- a/code/datums/brain_damage/split_personality.dm +++ b/code/datums/brain_damage/split_personality.dm @@ -123,7 +123,7 @@ trauma = _trauma return ..() -/mob/living/split_personality/BiologicalLife(seconds, times_fired) +/mob/living/split_personality/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(QDELETED(body)) diff --git a/code/datums/browser.dm b/code/datums/browser.dm index 2057cbb21a..e8c7615ecb 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -4,7 +4,7 @@ var/window_id // window_id is used as the window name for browse and onclose var/width = 0 var/height = 0 - var/atom/ref = null + var/datum/weakref/ref = null var/window_options = "can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // window option is set using window_id var/stylesheets[0] var/scripts[0] @@ -16,8 +16,8 @@ /datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, atom/nref = null) - user = nuser + RegisterSignal(user, COMSIG_PARENT_QDELETING, .proc/user_deleted) window_id = nwindow_id if (ntitle) title = format_text(ntitle) @@ -26,7 +26,11 @@ if (nheight) height = nheight if (nref) - ref = nref + ref = WEAKREF(nref) + +/datum/browser/proc/user_deleted(datum/source) + SIGNAL_HANDLER + user = null /datum/browser/proc/add_head_content(nhead_content) head_content = nhead_content @@ -35,7 +39,7 @@ window_options = nwindow_options /datum/browser/proc/add_stylesheet(name, file) - if(istype(name, /datum/asset/spritesheet)) + if (istype(name, /datum/asset/spritesheet)) var/datum/asset/spritesheet/sheet = name stylesheets["spritesheet_[sheet.name].css"] = "data/spritesheets/[sheet.name]" else @@ -94,27 +98,32 @@ "} /datum/browser/proc/open(use_onclose = TRUE) - if(isnull(window_id)) //null check because this can potentially nuke goonchat + if(isnull(window_id)) //null check because this can potentially nuke goonchat WARNING("Browser [title] tried to open with a null ID") - to_chat(user, "The [title] browser you tried to open failed a sanity check! Please report this on github!") + to_chat(user, span_userdanger("The [title] browser you tried to open failed a sanity check! Please report this on github!")) return var/window_size = "" - if(width && height) + if (width && height) window_size = "size=[width]x[height];" common_asset.send(user) - if(stylesheets.len) + if (stylesheets.len) SSassets.transport.send_assets(user, stylesheets) - if(scripts.len) + if (scripts.len) SSassets.transport.send_assets(user, scripts) user << browse(get_content(), "window=[window_id];[window_size][window_options]") - if(use_onclose) + if (use_onclose) setup_onclose() /datum/browser/proc/setup_onclose() set waitfor = 0 //winexists sleeps, so we don't need to. for (var/i in 1 to 10) - if (user && winexists(user, window_id)) - onclose(user, window_id, ref) + if (user?.client && winexists(user, window_id)) + var/atom/send_ref + if(ref) + send_ref = ref.resolve() + if(!send_ref) + ref = null + onclose(user, window_id, send_ref) break /datum/browser/proc/close() @@ -153,11 +162,35 @@ opentime = 0 close() -//designed as a drop in replacement for alert(); functions the same. (outside of needing User specified) -/proc/tgalert(mob/User, Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000) +/** + * **DEPRECATED: USE tgui_alert(...) INSTEAD** + * + * Designed as a drop in replacement for alert(); functions the same. (outside of needing User specified) + * Arguments: + * * User - The user to show the alert to. + * * Message - The textual body of the alert. + * * Title - The title of the alert's window. + * * Button1 - The first button option. + * * Button2 - The second button option. + * * Button3 - The third button option. + * * StealFocus - Boolean operator controlling if the alert will steal the user's window focus. + * * Timeout - The timeout of the window, after which no responses will be valid. + */ +/proc/tgalert(mob/User, Message, Title, Button1="Ok", Button2, Button3, StealFocus = TRUE, Timeout = 6000) if (!User) User = usr - switch(askuser(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout)) + if (!istype(User)) + if (istype(User, /client)) + var/client/client = User + User = client.mob + else + return + + // Get user's response using a modal + var/datum/browser/modal/alert/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout) + A.open() + A.wait() + switch(A.selectedbutton) if (1) return Button1 if (2) @@ -197,8 +230,8 @@ .=..() opentime = 0 -/datum/browser/modal/open(use_onclose = 1) - set waitfor = 0 +/datum/browser/modal/open(use_onclose) + set waitfor = FALSE opentime = world.time if (stealfocus) @@ -277,7 +310,7 @@ opentime = 0 close() -/proc/presentpicker(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/values, inputtype = "checkbox", width, height, slidecolor) +/proc/presentpicker(mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/values, inputtype = "checkbox", width, height, slidecolor) if (!istype(User)) if (istype(User, /client/)) var/client/C = User @@ -290,7 +323,7 @@ if (A.selectedbutton) return list("button" = A.selectedbutton, "values" = A.valueslist) -/proc/input_bitfield(var/mob/User, title, bitfield, current_value, nwidth = 350, nheight = 350, nslidecolor, allowed_edit_list = null) +/proc/input_bitfield(mob/User, title, bitfield, current_value, nwidth = 350, nheight = 350, nslidecolor, allowed_edit_list = null) if (!User || !(bitfield in GLOB.bitfields)) return var/list/pickerlist = list() @@ -401,7 +434,7 @@ opentime = 0 close() -/proc/presentpreflikepicker(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/settings, width, height, slidecolor) +/proc/presentpreflikepicker(mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/settings, width, height, slidecolor) if (!istype(User)) if (istype(User, /client/)) var/client/C = User @@ -414,12 +447,6 @@ if (A.selectedbutton) return list("button" = A.selectedbutton, "settings" = A.settings) -// This will allow you to show an icon in the browse window -// This is added to mob so that it can be used without a reference to the browser object -// There is probably a better place for this... -/mob/proc/browse_rsc_icon(icon, icon_state, dir = -1) - - // Registers the on-close verb for a browse window (client/verb/.windowclose) // this will be called when the close-button of a window is pressed. // @@ -427,8 +454,8 @@ // e.g. canisters, timers, etc. // // windowid should be the specified window name -// e.g. code is : user << browse(text, "window=fred") -// then use : onclose(user, "fred") +// e.g. code is : user << browse(text, "window=fred") +// then use : onclose(user, "fred") // // Optionally, specify the "ref" parameter as the controlled atom (usually src) // to pass a "close=1" parameter to the atom's Topic() proc for special handling. @@ -451,18 +478,18 @@ // otherwise, just reset the client mob's machine var. // /client/verb/windowclose(atomref as text) - set hidden = TRUE // hide this verb from the user's panel - set name = ".windowclose" // no autocomplete on cmd line + set hidden = TRUE // hide this verb from the user's panel + set name = ".windowclose" // no autocomplete on cmd line - if(atomref!="null") // if passed a real atomref - var/hsrc = locate(atomref) // find the reffed atom + if(atomref!="null") // if passed a real atomref + var/hsrc = locate(atomref) // find the reffed atom var/href = "close=1" if(hsrc) usr = src.mob - src.Topic(href, params2list(href), hsrc) // this will direct to the atom's - return // Topic() proc via client.Topic() + src.Topic(href, params2list(href), hsrc) // this will direct to the atom's + return // Topic() proc via client.Topic() // no atomref specified (or not found) // so just reset the user mob's machine var - if(src && src.mob) + if(src?.mob) src.mob.unset_machine() diff --git a/code/datums/changelog/changelog.dm b/code/datums/changelog/changelog.dm new file mode 100644 index 0000000000..3ce51c6034 --- /dev/null +++ b/code/datums/changelog/changelog.dm @@ -0,0 +1,32 @@ +/datum/changelog + var/static/list/changelog_items = list() + +/datum/changelog/ui_state() + return GLOB.always_state + +/datum/changelog/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if (!ui) + ui = new(user, src, "Changelog") + ui.open() + +/datum/changelog/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + if(action == "get_month") + var/datum/asset/changelog_item/changelog_item = changelog_items[params["date"]] + if (!changelog_item) + changelog_item = new /datum/asset/changelog_item(params["date"]) + changelog_items[params["date"]] = changelog_item + return ui.send_asset(changelog_item) + +/datum/changelog/ui_static_data() + var/list/data = list( "dates" = list() ) + var/regex/ymlRegex = regex(@"\.yml", "g") + + for(var/archive_file in flist("[global.config.directory]/../html/changelogs/archive/")) + var/archive_date = ymlRegex.Replace(archive_file, "") + data["dates"] = list(archive_date) + data["dates"] + + return data diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm index 03c23e11f6..6aadd72a8a 100644 --- a/code/datums/chatmessage.dm +++ b/code/datums/chatmessage.dm @@ -18,8 +18,6 @@ #define CHAT_LAYER_Z_STEP 0.0001 /// The number of z-layer 'slices' usable by the chat message layering #define CHAT_LAYER_MAX_Z (CHAT_LAYER_MAX - CHAT_LAYER) / CHAT_LAYER_Z_STEP -/// Macro from Lummox used to get height from a MeasureText proc -#define WXH_TO_HEIGHT(x) text2num(copytext(x, findtextEx(x, "x") + 1)) /** * # Chat Message Overlay @@ -125,7 +123,7 @@ // Append radio icon if from a virtual speaker if (extra_classes.Find("virtual-speaker")) - var/image/r_icon = image('icons/UI_Icons/chat/chat_icons.dmi', icon_state = "radio") + var/image/r_icon = image('icons/ui_icons/chat/chat_icons.dmi', icon_state = "radio") text = "\icon[r_icon] " + text // We dim italicized text to make it more distinguishable from regular text @@ -136,7 +134,7 @@ approx_lines = max(1, mheight / CHAT_MESSAGE_APPROX_LHEIGHT) // Translate any existing messages upwards, apply exponential decay factors to timers - message_loc = get_atom_on_turf(target) + message_loc = isturf(target) ? target : get_atom_on_turf(target) if (owned_by.seen_messages) var/idx = 1 var/combined_height = approx_lines @@ -165,7 +163,7 @@ message.maptext_width = CHAT_MESSAGE_WIDTH message.maptext_height = mheight message.maptext_x = (CHAT_MESSAGE_WIDTH - owner.bound_width) * -0.5 - message.maptext = complete_text + message.maptext = MAPTEXT(complete_text) // View the message LAZYADDASSOC(owned_by.seen_messages, message_loc, src) @@ -176,10 +174,6 @@ scheduled_destruction = world.time + (lifespan - CHAT_MESSAGE_EOL_FADE) enter_subsystem() - var/mob/living/silicon/robot/R = target - if(iscyborg(R)) - if(R.module.dogborg == TRUE || R.dogborg == TRUE) //I hate whoever that thought that putting two types of dogborg that don't even sync up properly was good - message.pixel_x = 16 /** * Applies final animations to overlay CHAT_MESSAGE_EOL_FADE deciseconds prior to message deletion diff --git a/code/datums/cinematic.dm b/code/datums/cinematic.dm index 2a8a0ea98a..6052b84364 100644 --- a/code/datums/cinematic.dm +++ b/code/datums/cinematic.dm @@ -101,7 +101,7 @@ if(!C) return watching += C - M.overlay_fullscreen("cinematic",/atom/movable/screen/fullscreen/cinematic_backdrop) + M.overlay_fullscreen("cinematic",/atom/movable/screen/fullscreen/tiled/cinematic_backdrop) C.screen += screen //Sound helper diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index 9e4e16f813..6b99cf8318 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -52,12 +52,16 @@ return /** - * Properly removes the component from `parent` and cleans up references - * Setting `force` makes it not check for and remove the component from the parent - * Setting `silent` deletes the component without sending a `COMSIG_COMPONENT_REMOVING` signal - */ + * Properly removes the component from `parent` and cleans up references + * + * Arguments: + * * force - makes it not check for and remove the component from the parent + * * silent - deletes the component without sending a [COMSIG_COMPONENT_REMOVING] signal + */ /datum/component/Destroy(force=FALSE, silent=FALSE) - if(!force && parent) + if(!parent) + return ..() + if(!force) _RemoveFromParent() if(!silent) SEND_SIGNAL(parent, COMSIG_COMPONENT_REMOVING, src) diff --git a/code/datums/components/acid.dm b/code/datums/components/acid.dm index 2e3784dc97..686d47cb1e 100644 --- a/code/datums/components/acid.dm +++ b/code/datums/components/acid.dm @@ -38,9 +38,11 @@ /datum/component/acid/Destroy() STOP_PROCESSING(SSprocessing, src) - var/obj/O = parent level = 0 - O.update_overlays() + if(parent) // So, this is how you get runtimes fellas. + UnregisterSignal(parent, list(COMSIG_ATOM_UPDATE_OVERLAYS, COMSIG_ATOM_ATTACK_HAND)) // Don't worry about isitem checks, we don't need them. + var/atom/O = parent + O.update_icon(UPDATE_OVERLAYS) return ..() /datum/component/acid/process() @@ -51,7 +53,7 @@ if(!(O.resistance_flags & ACID_PROOF)) if(prob(33)) playsound(O.loc, 'sound/items/welder.ogg', 150, 1) - O.take_damage(min(1 + round(sqrt(level)*0.3), 300), BURN, "acid", 0) + O.take_damage(min(1 + round(sqrt(level)*0.3), 300), BURN, ACID, 0) level = max(level - (5 + 3*round(sqrt(level))), 0) if(level <= 0) diff --git a/code/datums/components/anti_magic.dm b/code/datums/components/anti_magic.dm index 6f289af1fc..840c202bfc 100644 --- a/code/datums/components/anti_magic.dm +++ b/code/datums/components/anti_magic.dm @@ -29,7 +29,7 @@ expire = _expire /datum/component/anti_magic/proc/on_equip(datum/source, mob/equipper, slot) - if(!CHECK_BITFIELD(allowed_slots, slotdefine2slotbit(slot))) //Check that the slot is valid for antimagic + if(!(allowed_slots & slot)) //Check that the slot is valid for antimagic UnregisterSignal(equipper, COMSIG_MOB_RECEIVE_MAGIC) return RegisterSignal(equipper, COMSIG_MOB_RECEIVE_MAGIC, .proc/protect, TRUE) diff --git a/code/datums/components/area_sound_manager.dm b/code/datums/components/area_sound_manager.dm new file mode 100644 index 0000000000..50bb77772f --- /dev/null +++ b/code/datums/components/area_sound_manager.dm @@ -0,0 +1,77 @@ +///Allows you to set a theme for a set of areas without tying them to looping sounds explicitly +/datum/component/area_sound_manager + ///area -> looping sound type + var/list/area_to_looping_type = list() + ///Current sound loop + var/datum/looping_sound/our_loop + ///A list of "acceptable" z levels to be on. If you leave this, we're gonna delete ourselves + var/list/accepted_zs + ///The timer id of our current start delay, if it exists + var/timerid + +/datum/component/area_sound_manager/Initialize(area_loop_pairs, change_on, remove_on, acceptable_zs) + if(!ismovable(parent)) + return + area_to_looping_type = area_loop_pairs + accepted_zs = acceptable_zs + change_the_track() + + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/react_to_move) + RegisterSignal(parent, COMSIG_MOVABLE_Z_CHANGED, .proc/react_to_z_move) + RegisterSignal(parent, change_on, .proc/handle_change) + RegisterSignal(parent, remove_on, .proc/handle_removal) + +/datum/component/area_sound_manager/Destroy(force, silent) + QDEL_NULL(our_loop) + . = ..() + +/datum/component/area_sound_manager/proc/react_to_move(datum/source, atom/oldloc, dir, forced) + SIGNAL_HANDLER + var/list/loop_lookup = area_to_looping_type + if(loop_lookup[get_area(oldloc)] == loop_lookup[get_area(parent)]) + return + change_the_track(TRUE) + +/datum/component/area_sound_manager/proc/react_to_z_move(datum/source, old_z, new_z) + SIGNAL_HANDLER + if(!length(accepted_zs) || (new_z in accepted_zs)) + return + qdel(src) + +/datum/component/area_sound_manager/proc/handle_removal(datum/source) + SIGNAL_HANDLER + qdel(src) + +/datum/component/area_sound_manager/proc/handle_change(datum/source) + SIGNAL_HANDLER + change_the_track() + +/datum/component/area_sound_manager/proc/change_the_track(skip_start = FALSE) + var/time_remaining = 0 + + if(our_loop) + var/our_id = our_loop.timerid || timerid + if(our_id) + time_remaining = timeleft(our_id, SSsound_loops) || 0 + //Time left will sometimes return negative values, just ignore them and start a new sound loop now + time_remaining = max(time_remaining, 0) + QDEL_NULL(our_loop) + + var/area/our_area = get_area(parent) + var/new_loop_type = area_to_looping_type[our_area] + if(!new_loop_type) + return + + our_loop = new new_loop_type(parent, FALSE, TRUE, skip_start) + + //If we're still playing, wait a bit before changing the sound so we don't double up + if(time_remaining) + timerid = addtimer(CALLBACK(src, .proc/start_looping_sound), time_remaining, TIMER_UNIQUE | TIMER_CLIENT_TIME | TIMER_STOPPABLE | TIMER_NO_HASH_WAIT | TIMER_DELETE_ME, SSsound_loops) + return + timerid = null + our_loop.start() + +/datum/component/area_sound_manager/proc/start_looping_sound() + timerid = null + if(our_loop) + our_loop.start() diff --git a/code/datums/components/armor_plate.dm b/code/datums/components/armor_plate.dm index f026c89c60..db22e2277b 100644 --- a/code/datums/components/armor_plate.dm +++ b/code/datums/components/armor_plate.dm @@ -2,7 +2,7 @@ var/amount = 0 var/maxamount = 3 var/upgrade_item = /obj/item/stack/sheet/animalhide/goliath_hide - var/datum/armor/added_armor = list("melee" = 10) + var/datum/armor/added_armor = list(MELEE = 10) var/upgrade_name /datum/component/armor_plate/Initialize(_maxamount,obj/item/_upgrade_item,datum/armor/_added_armor) @@ -12,7 +12,7 @@ RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine) RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/applyplate) RegisterSignal(parent, COMSIG_PARENT_PREQDELETED, .proc/dropplates) - if(istype(parent, /obj/mecha/working/ripley)) + if(istype(parent, /obj/vehicle/sealed/mecha/working/ripley)) RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/apply_mech_overlays) if(_maxamount) @@ -67,10 +67,11 @@ O.armor = O.armor.attachArmor(added_armor) if(ismecha(O)) - var/obj/mecha/R = O + var/obj/vehicle/sealed/mecha/R = O R.update_icon() to_chat(user, "You strengthen [R], improving its resistance against melee, bullet and laser damage.") else + SEND_SIGNAL(O, COMSIG_ARMOR_PLATED, amount, maxamount) to_chat(user, "You strengthen [O], improving its resistance against melee attacks.") @@ -79,11 +80,11 @@ for(var/i in 1 to amount) new upgrade_item(get_turf(parent)) -/datum/component/armor_plate/proc/apply_mech_overlays(obj/mecha/mech, list/overlays) +/datum/component/armor_plate/proc/apply_mech_overlays(obj/vehicle/sealed/mecha/mech, list/overlays) if(amount) var/overlay_string = "ripley-g" if(amount >= 3) overlay_string += "-full" - if(!mech.occupant) + if(LAZYLEN(mech.occupants) < 1) overlay_string += "-open" overlays += overlay_string diff --git a/code/datums/components/bouncy.dm b/code/datums/components/bouncy.dm index fed603410e..3c4e228b59 100644 --- a/code/datums/components/bouncy.dm +++ b/code/datums/components/bouncy.dm @@ -32,7 +32,7 @@ var/atom/movable/A = parent switch(rand(1, 3)) if(1) - A.do_jiggle(45 + rand(-10, 10) * bouncy_mod, 14) + A.do_jiggle(25 + rand(-5, 5) * bouncy_mod, 14) if(2) var/min_b = 0.6/bouncy_mod var/max_b = 1.2 * bouncy_mod diff --git a/code/datums/components/crafting/glassware/glassware.dm b/code/datums/components/crafting/glassware/glassware.dm index 88f52d6b01..f37efedc8a 100644 --- a/code/datums/components/crafting/glassware/glassware.dm +++ b/code/datums/components/crafting/glassware/glassware.dm @@ -1,8 +1,8 @@ //This file is for glass working types of things! /obj/item/glasswork - name = "This is a bug report it!" - desc = "Failer to code. Contact your local bug remover..." + name = "this is a bug!" + desc = "Uh oh, the coders did a fucky wucky! Contact your local code monkey and tell them about this!" icon = 'icons/obj/glassworks.dmi' w_class = WEIGHT_CLASS_SMALL force = 1 @@ -11,45 +11,45 @@ tool_behaviour = null /obj/item/glasswork/glasskit - name = "Glass working tools" - desc = "A lovely belt of most the tools you will need to shape, mold, and refine glass into more advanced shapes." + name = "glasswork tools" + desc = "A set of most the tools you will need to shape, mold, and refine glass into more advanced shapes." icon_state = "glass_tools" tool_behaviour = TOOL_GLASS_CUT //Cutting takes 20 ticks /obj/item/glasswork/blowing_rod - name = "Glass working blow rod" - desc = "A hollow metal stick made for glass blowing." + name = "glassblowing rod" + desc = "A hollow metal rod made for blowing glass." icon_state = "blowing_rods_unused" tool_behaviour = TOOL_BLOW //Rods take 5 ticks /obj/item/glasswork/glass_base //Welding takes 30 ticks - name = "Glass fodder sheet" - desc = "A sheet of glass set aside for glass working" + name = "glass fodder sheet" + desc = "A sheet of glass set aside for glass working." icon_state = "glass_base" var/next_step = null var/rod = /obj/item/glasswork/blowing_rod /obj/item/tea_plate - name = "Tea Plate" + name = "tea saucer" desc = "A polished plate for a tea cup. How fancy!" icon = 'icons/obj/glass_ware.dmi' icon_state = "tea_plate" /obj/item/tea_cup - name = "Tea Cup" - desc = "A glass cup made for fake tea!" + name = "tea cup" + desc = "A glass cup made for sipping tea!" icon = 'icons/obj/glass_ware.dmi' - icon_state = "tea_plate" + icon_state = "tea_cup" //////////////////////Chem Disk///////////////////// //Two Steps // //Sells for 300 cr, takes 10 glass shets // -//Usefull for chem spliting // +//Useful for chem spliting // //////////////////////////////////////////////////// /obj/item/glasswork/glass_base/dish - name = "Glass fodder sheet" - desc = "A set of glass sheets set aside for glass working, this one is ideal for a small glass dish. Needs to be cut with some tools." + name = "glass fodder sheet (dish)" + desc = "A set of glass sheets set aside for glass working. This one is ideal for a small glass dish. It needs to be cut with some glassworking tools." next_step = /obj/item/glasswork/glass_base/dish_part1 /obj/item/glasswork/glass_base/dish/attackby(obj/item/I, mob/user, params) @@ -60,8 +60,8 @@ qdel(src) /obj/item/glasswork/glass_base/dish_part1 - name = "Half chem dish sheet" - desc = "A sheet of glass cut in half, looks like it still needs some more cutting down" + name = "half glass fodder sheet (dish)" + desc = "A sheet of glass cut in half. It looks like it still needs some more cutting down." icon_state = "glass_base_half" next_step = /obj/item/reagent_containers/glass/beaker/glass_dish @@ -75,12 +75,12 @@ //////////////////////Lens////////////////////////// //Six Steps // //Sells for 1600 cr, takes 15 glass shets // -//Usefull for selling and later crafting // +//Useful for selling and later crafting // //////////////////////////////////////////////////// /obj/item/glasswork/glass_base/glass_lens - name = "Glass fodder sheet" - desc = "A set of glass sheets set aside for glass working, this one is ideal for a small glass lens. Needs to be cut with some tools." + name = "glass fodder sheet (lens)" + desc = "A set of glass sheets set aside for glass working. This one is ideal for a glass lens. It needs to be cut with some glassworking tools." next_step = /obj/item/glasswork/glass_base/glass_lens_part1 /obj/item/glasswork/glass_base/glass_lens/attackby(obj/item/I, mob/user, params) @@ -91,8 +91,8 @@ qdel(src) /obj/item/glasswork/glass_base/glass_lens_part1 - name = "Glass fodder sheet" - desc = "Cut glass ready to be heated. Needs to be heated with some tools." + name = "half glass fodder sheet (lens)" + desc = "Cut glass ready to be heated with something very hot." icon_state = "glass_base_half" next_step = /obj/item/glasswork/glass_base/glass_lens_part2 @@ -104,8 +104,8 @@ qdel(src) /obj/item/glasswork/glass_base/glass_lens_part2 - name = "Glass fodder sheet" - desc = "Cut glass that has been heated. Needs to be heated more with some tools." + name = "heated half glass fodder sheet (lens)" + desc = "Cut glass that has been heated once already and is ready to be heated again." icon_state = "glass_base_heat" next_step = /obj/item/glasswork/glass_base/glass_lens_part3 @@ -117,8 +117,8 @@ qdel(src) /obj/item/glasswork/glass_base/glass_lens_part3 - name = "Glass fodder sheet" - desc = "Cut glass that has been heated into a blob of hot glass. Needs to be placed onto a blow tube." + name = "heated glass blob (lens)" + desc = "Cut glass that has been heated into a blob. It needs to be attached to a glassblowing rod." icon_state = "glass_base_molding" next_step = /obj/item/glasswork/glass_base/glass_lens_part4 @@ -131,8 +131,8 @@ qdel(I) /obj/item/glasswork/glass_base/glass_lens_part4 - name = "Glass fodder sheet" - desc = "Cut glass that has been heated into a blob of hot glass. Needs to be cut off onto a blow tube." + name = "glassblowing rod (lens)" + desc = "A hollow metal rod made for blowing glass. There is a blob of shapen glass at the end of it that needs to be cut off with some glassworking tools." icon_state = "blowing_rods_inuse" next_step = /obj/item/glasswork/glass_base/glass_lens_part5 @@ -145,8 +145,8 @@ qdel(src) /obj/item/glasswork/glass_base/glass_lens_part5 - name = "Unpolished glass lens" - desc = "A small unpolished glass lens. Could be polished with some cloth." + name = "unpolished glass (lens)" + desc = "An unpolished glass lens. It needs to be polished with some dry cloth." icon = 'icons/obj/glass_ware.dmi' icon_state = "glass_optics" next_step = /obj/item/glasswork/glass_base/glass_lens_part6 @@ -159,8 +159,8 @@ qdel(src) /obj/item/glasswork/glass_base/glass_lens_part6 - name = "Unrefined glass lens" - desc = "A small polished glass lens. Just needs to be refined with some sandstone." + name = "unrefined glass (lens)" + desc = "A polished glass lens. It needs to be refined with some sandstone." icon = 'icons/obj/glass_ware.dmi' icon_state = "glass_optics" next_step = /obj/item/glasswork/glass_base/lens @@ -174,12 +174,12 @@ //////////////////////Spouty Flask////////////////// //Four Steps // //Sells for 1200 cr, takes 20 glass shets // -//Usefull for selling and chemical things // +//Useful for selling and chemical things // //////////////////////////////////////////////////// /obj/item/glasswork/glass_base/spouty - name = "Glass fodder sheet" - desc = "A set of glass sheets set aside for glass working, this one is ideal for a spout beaker. Needs to be cut with some tools." + name = "Glass fodder sheet (spout)" + desc = "A set of glass sheets set aside for glass working. This one is ideal for a spouty flask. It needs to be cut with some glassworking tools." next_step = /obj/item/glasswork/glass_base/spouty_part2 /obj/item/glasswork/glass_base/spouty/attackby(obj/item/I, mob/user, params) @@ -190,8 +190,8 @@ qdel(src) /obj/item/glasswork/glass_base/spouty_part2 - name = "Glass fodder sheet" - desc = "Cut glass that has been heated. Needs to be heated with some tools." + name = "glass fodder sheet (spout)" + desc = "Cut glass ready to be heated with something very hot." icon_state = "glass_base_half" next_step = /obj/item/glasswork/glass_base/spouty_part3 @@ -203,8 +203,8 @@ qdel(src) /obj/item/glasswork/glass_base/spouty_part3 - name = "Glass fodder sheet" - desc = "Cut glass that has been heated into a blob of hot glass. Needs to be placed onto a blow tube." + name = "heated glass blob (spout)" + desc = "Cut glass that has been heated into a blob. It needs to be attached to a glassblowing rod." icon_state = "glass_base_molding" next_step = /obj/item/glasswork/glass_base/spouty_part4 @@ -217,8 +217,8 @@ qdel(I) /obj/item/glasswork/glass_base/spouty_part4 - name = "Glass fodder sheet" - desc = "Cut glass that has been heated into a blob of hot glass. Needs to be cut off onto a blow tube." + name = "glassblowing rod (spout)" + desc = "A hollow metal rod made for blowing glass. There is a blob of shapen glass at the end of it that needs to be cut off with some glassworking tools." icon_state = "blowing_rods_inuse" next_step = /obj/item/reagent_containers/glass/beaker/flask/spouty @@ -233,12 +233,12 @@ //////////////////////Small Bulb Flask////////////// //Two Steps // //Sells for 600 cr, takes 5 glass shets // -//Usefull for selling and chemical things // +//Useful for selling and chemical things // //////////////////////////////////////////////////// /obj/item/glasswork/glass_base/flask_small - name = "Glass fodder sheet" - desc = "A set of glass sheets set aside for glass working, this one is ideal for a small flask. Needs to be heated with some tools." + name = "glass fodder sheet (small flask)" + desc = "A set of glass sheets set aside for glass working. This one is ideal for a small flask. It needs to heated with something very hot." next_step = /obj/item/glasswork/glass_base/flask_small_part1 /obj/item/glasswork/glass_base/flask_small/attackby(obj/item/I, mob/user, params) @@ -249,8 +249,8 @@ qdel(src) /obj/item/glasswork/glass_base/flask_small_part1 - name = "Metled glass" - desc = "A blob of metled glass, this one is ideal for a small flask. Needs to be blown with some tools." + name = "heated glass blob (small flask)" + desc = "Glass that has been heated into a blob. It needs to be attached to a glassblowing rod." icon_state = "glass_base_molding" next_step = /obj/item/glasswork/glass_base/flask_small_part2 @@ -263,8 +263,8 @@ qdel(I) /obj/item/glasswork/glass_base/flask_small_part2 - name = "Metled glass" - desc = "A blob of metled glass on the end of a blowing rod. Needs to be cut off with some tools." + name = "glassblowing rod (small flask)" + desc = "A hollow metal rod made for blowing glass. There is a blob of shapen glass at the end of it that needs to be cut off with some glassworking tools." icon_state = "blowing_rods_inuse" next_step = /obj/item/reagent_containers/glass/beaker/flask @@ -279,12 +279,12 @@ //////////////////////Large Bulb Flask////////////// //Two Steps // //Sells for 1000 cr, takes 15 glass shets // -//Usefull for selling and chemical things // +//Useful for selling and chemical things // //////////////////////////////////////////////////// /obj/item/glasswork/glass_base/flask_large - name = "Glass fodder sheet" - desc = "A set of glass sheets set aside for glass working, this one is ideal for a large flask. Needs to be heated with some tools." + name = "glass fodder sheet (large flask)" + desc = "A set of glass sheets set aside for glass working. This one is ideal for a large flask. It needs to heated with something very hot." next_step = /obj/item/glasswork/glass_base/flask_large_part1 /obj/item/glasswork/glass_base/flask_large/attackby(obj/item/I, mob/user, params) @@ -295,8 +295,8 @@ qdel(src) /obj/item/glasswork/glass_base/flask_large_part1 - name = "Metled glass" - desc = "A blob of metled glass, this one is ideal for a large flask. Needs to be blown with some tools." + name = "heated glass blob (large flask)" + desc = "Glass that has been heated into a blob. It needs to be attached to a glassblowing rod." icon_state = "glass_base_molding" next_step = /obj/item/glasswork/glass_base/flask_large_part2 @@ -309,8 +309,8 @@ qdel(I) /obj/item/glasswork/glass_base/flask_large_part2 - name = "Metled glass" - desc = "A blob of metled glass on the end of a blowing rod. Needs to be cut off with some tools." + name = "glassblowing rod (small flask)" + desc = "A hollow metal rod made for blowing glass. There is a blob of shapen glass at the end of it that needs to be cut off with some glassworking tools." icon_state = "blowing_rods_inuse" next_step = /obj/item/reagent_containers/glass/beaker/flask/large @@ -325,12 +325,12 @@ //////////////////////Tea Plates//////////////////// //Three Steps // //Sells for 1000 cr, takes 5 glass shets // -//Usefull for selling and chemical things // +//Useful for selling and chemical things // //////////////////////////////////////////////////// /obj/item/glasswork/glass_base/tea_plate - name = "Glass fodder sheet" - desc = "A set of glass sheets set aside for glass working, this one is ideal for a tea plate, how fancy! Needs to be heated with some tools." + name = "glass fodder sheet (tea saucer)" + desc = "A set of glass sheets set aside for glass working. This one is ideal for a tea saucer. It needs to heated with something very hot." next_step = /obj/item/glasswork/glass_base/tea_plate1 /obj/item/glasswork/glass_base/tea_plate/attackby(obj/item/I, mob/user, params) @@ -341,8 +341,8 @@ qdel(src) /obj/item/glasswork/glass_base/tea_plate1 - name = "Metled glass" - desc = "A blob of metled glass, this one is ideal for a tea plate. Needs to be blown with some tools." + name = "heated glass blob (tea saucer)" + desc = "Glass that has been heated into a blob. It needs to be attached to a glassblowing rod." icon_state = "glass_base_molding" next_step = /obj/item/glasswork/glass_base/tea_plate2 @@ -355,8 +355,8 @@ qdel(I) /obj/item/glasswork/glass_base/tea_plate2 - name = "Metled glass" - desc = "A blob of metled glass on the end of a blowing rod. Needs to be cut off with some tools." + name = "glassblowing rod (tea saucer)" + desc = "A hollow metal rod made for blowing glass. There is a blob of shapen glass at the end of it that needs to be cut off with some glassworking tools." icon_state = "blowing_rods_inuse" next_step = /obj/item/glasswork/glass_base/tea_plate3 @@ -369,8 +369,8 @@ qdel(src) /obj/item/glasswork/glass_base/tea_plate3 - name = "Disk of glass" - desc = "A disk of glass that can be cant be used for much. Needs to be polished with some cloth." + name = "unpolished glass saucer (tea saucer)" + desc = "An unpolished glass saucer. It needs to be polished with some dry cloth." icon_state = "glass_base_half" next_step = /obj/item/tea_plate @@ -384,12 +384,12 @@ //////////////////////Tea Cup/////////////////////// //Four Steps // //Sells for 1600 cr, takes 6 glass shets // -//Usefull for selling and chemical things // +//Useful for selling and chemical things // //////////////////////////////////////////////////// /obj/item/glasswork/glass_base/tea_cup - name = "Glass fodder sheet" - desc = "A set of glass sheets set aside for glass working, this one is ideal for a tea cup, how fancy! Needs to be heated with some tools." + name = "glass fodder sheet (tea cup)" + desc = "A set of glass sheets set aside for glass working. This one is ideal for a tea cup. It needs to heated with something very hot." next_step = /obj/item/glasswork/glass_base/tea_cup1 /obj/item/glasswork/glass_base/tea_cup/attackby(obj/item/I, mob/user, params) @@ -400,8 +400,8 @@ qdel(src) /obj/item/glasswork/glass_base/tea_cup1 - name = "Metled glass" - desc = "A blob of metled glass, this one is ideal for a tea cup. Needs to be blown with some tools." + name = "heated glass blob (tea cup)" + desc = "Glass that has been heated into a blob. It needs to be attached to a glassblowing rod." icon_state = "glass_base_molding" next_step = /obj/item/glasswork/glass_base/tea_cup2 @@ -413,9 +413,9 @@ qdel(src) qdel(I) -/obj/item/glasswork/glass_base/tea_cupe2 - name = "Metled glass" - desc = "A blob of metled glass on the end of a blowing rod. Needs to be cut off with some tools." +/obj/item/glasswork/glass_base/tea_cup2 + name = "glassblowing rod (tea cup)" + desc = "A hollow metal rod made for blowing glass. There is a blob of shapen glass at the end of it that needs to be cut off with some glassworking tools." icon_state = "blowing_rods_inuse" next_step = /obj/item/glasswork/glass_base/tea_cup3 @@ -428,12 +428,12 @@ qdel(src) /obj/item/glasswork/glass_base/tea_cup3 - name = "Disk of glass" - desc = "A bowl of glass that can be cant be used for much. Needs to be polished with some cloth." + name = "unpolished glass cup (tea cup)" + desc = "An unpolished glass cup. It needs to be polished with some dry cloth." icon_state = "glass_base_half" next_step = /obj/item/glasswork/glass_base/tea_cup4 -/obj/item/glasswork/glass_base/cup3/attackby(obj/item/I, mob/user, params) +/obj/item/glasswork/glass_base/tea_cup3/attackby(obj/item/I, mob/user, params) ..() if(istype(I, /obj/item/stack/sheet/cloth)) if(do_after(user,10, target = src)) @@ -441,12 +441,12 @@ qdel(src) /obj/item/glasswork/glass_base/tea_cup4 - name = "Disk of glass" - desc = "A bowl of polished glass that can be cant be used for much. Needs some more glass to make a handle." + name = "polished glass cup (tea cup)" + desc = "A polished glass cup. It needs some extra glass to form a handle." icon_state = "glass_base_half" next_step = /obj/item/tea_cup -/obj/item/glasswork/glass_base/cup4/attackby(obj/item/I, mob/user, params) +/obj/item/glasswork/glass_base/tea_cup4/attackby(obj/item/I, mob/user, params) ..() if(istype(I, /obj/item/stack/sheet/glass)) if(do_after(user,10, target = src)) diff --git a/code/datums/components/crafting/glassware/lens_crafting.dm b/code/datums/components/crafting/glassware/lens_crafting.dm index 8907522946..7b650989a8 100644 --- a/code/datums/components/crafting/glassware/lens_crafting.dm +++ b/code/datums/components/crafting/glassware/lens_crafting.dm @@ -1,15 +1,15 @@ //This file is for crafting using a lens! /obj/item/glasswork/glass_base/lens - name = "Optical lens" - desc = "Good for selling or crafting, by itself its useless" + name = "optical lens" + desc = "A glass lens. Useless by itself, but may prove useful in making something with a focus." icon = 'icons/obj/glass_ware.dmi' icon_state = "glass_optics" //Laser pointers - 2600 /obj/item/glasswork/glass_base/laserpointer_shell - name = "Laser pointer assembly" - desc = "Good for selling or crafting, by itself its useless. Needs a power capactor." + name = "laser pointer assembly" + desc = "An empty hull of a laser pointer. It's missing a capacitor." icon_state = "laser_case" icon = 'icons/obj/glass_ware.dmi' next_step = /obj/item/glasswork/glass_base/laserpointer_shell_1 @@ -21,8 +21,8 @@ qdel(src) /obj/item/glasswork/glass_base/laserpointer_shell_1 - name = "Laser pointer assembly" - desc = "Good for selling or crafting, by itself its useless. Needs a glass lens." + name = "powered laser pointer assembly" + desc = "A laser pointer hull with a capacitor inside of it. It's missing a lens." icon_state = "laser_wire" icon_state = "laser_case" next_step = /obj/item/glasswork/glass_base/laserpointer_shell_2 @@ -34,8 +34,8 @@ qdel(src) /obj/item/glasswork/glass_base/laserpointer_shell_2 - name = "Laser pointer assembly" - desc = "Good for selling or crafting, by itself its useless. Needs to be screwed together." + name = "near-complete laser pointer assembly" + desc = "A laser pointer hull with a capacitor and a lens inside of it. It needs to be screwed together." icon_state = "laser_wire" icon_state = "laser_case" next_step = /obj/item/laser_pointer/blue/handmade @@ -50,8 +50,8 @@ //NERD SHIT - 5000 /obj/item/glasswork/glass_base/glasses_frame - name = "Glasses Frame" - desc = "Good for crafting a pare of glasses, by itself its useless. Just add a pare of lens." + name = "glasses frame" + desc = "A pair of glasses without the lenses. You could probably add them yourself, though." icon = 'icons/obj/glass_ware.dmi' icon_state = "frames" next_step = /obj/item/glasswork/glass_base/glasses_frame_1 @@ -64,8 +64,8 @@ qdel(src) /obj/item/glasswork/glass_base/glasses_frame_1 - name = "Glasses Frame" - desc = "Good for crafting a pare of glasses, by itself its useless. Just add a the other lens." + name = "glasses frame" + desc = "A pair of shoddily-assembled glasses with only one lens. You could probably add the second one yourself, though." icon = 'icons/obj/glass_ware.dmi' icon_state = "frames_1" next_step = /obj/item/glasswork/glass_base/glasses_frame_2 @@ -78,8 +78,8 @@ qdel(src) /obj/item/glasswork/glass_base/glasses_frame_2 - name = "Glasses Frame" - desc = "Good for crafting a pare of glasses, by itself its useless. Just adjust the pices into the frame with a screwdriver." + name = "glasses frame" + desc = "A pair of hastily-assembled unfitted glasses with both lenses intact. Use a screwdriver to fit them." icon = 'icons/obj/glass_ware.dmi' icon_state = "frames_2" next_step = /obj/item/glasswork/glasses @@ -92,7 +92,7 @@ qdel(src) /obj/item/glasswork/glasses - name = "Handmade Glasses" - desc = "Handmade glasses that have not been polished at all making them useless. Selling them could still be worth a few credits." + name = "handmade glasses" + desc = "A pair of poorly-assembled glasses clearly produced by someone with no qualifications in making glasses. They're smudged, ugly, and don't even fit you. They might be worth some money, though." icon = 'icons/obj/glass_ware.dmi' icon_state = "frames_2" diff --git a/code/datums/components/crafting/recipes/recipes_clothing.dm b/code/datums/components/crafting/recipes/recipes_clothing.dm index 75d00bbfcd..7dbbf01a1d 100644 --- a/code/datums/components/crafting/recipes/recipes_clothing.dm +++ b/code/datums/components/crafting/recipes/recipes_clothing.dm @@ -287,7 +287,7 @@ name = "Durathread Reinforcement Kit" result = /obj/item/armorkit reqs = list(/obj/item/stack/sheet/durathread = 4) - tools = list(/obj/item/stack/sheet/mineral/titanium, TOOL_WIRECUTTER) // tough needle for a tough fabric + tools = list(TOOL_WIRECUTTER) time = 40 category = CAT_CLOTHING diff --git a/code/datums/components/crafting/recipes/recipes_misc.dm b/code/datums/components/crafting/recipes/recipes_misc.dm index ad37f770ed..fd72964505 100644 --- a/code/datums/components/crafting/recipes/recipes_misc.dm +++ b/code/datums/components/crafting/recipes/recipes_misc.dm @@ -554,6 +554,19 @@ subcategory = CAT_MISCELLANEOUS category = CAT_MISCELLANEOUS +/datum/crafting_recipe/mod_core + name = "MOD core" + result = /obj/item/mod/construction/core + tools = list(TOOL_SCREWDRIVER) + time = 10 SECONDS + reqs = list(/obj/item/stack/cable_coil = 5, + /obj/item/stack/rods = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/organ/heart = 1 + ) + subcategory = CAT_MISCELLANEOUS + category = CAT_MISCELLANEOUS + ////////////// //Banners///// ////////////// diff --git a/code/datums/components/crafting/recipes/recipes_primal.dm b/code/datums/components/crafting/recipes/recipes_primal.dm index aaae94df1d..ad71db7c59 100644 --- a/code/datums/components/crafting/recipes/recipes_primal.dm +++ b/code/datums/components/crafting/recipes/recipes_primal.dm @@ -93,7 +93,6 @@ /datum/crafting_recipe/quiver name = "Quiver" - always_availible = FALSE result = /obj/item/storage/belt/quiver time = 80 reqs = list(/obj/item/stack/sheet/leather = 3, @@ -104,19 +103,18 @@ name = "Bone Bow" result = /obj/item/gun/ballistic/bow/ashen time = 120 // 80+120 = 200 - always_availible = FALSE reqs = list(/obj/item/stack/sheet/bone = 8, /obj/item/stack/sheet/sinew = 4) category = CAT_PRIMAL -/datum/crafting_recipe/bow_tablet +/*/datum/crafting_recipe/bow_tablet name = "Sandstone Bow Making Manual" result = /obj/item/book/granter/crafting_recipe/bone_bow time = 200 //Scribing // don't care always_availible = FALSE reqs = list(/obj/item/stack/rods = 1, /obj/item/stack/sheet/mineral/sandstone = 4) - category = CAT_PRIMAL + category = CAT_PRIMAL*/ /datum/crafting_recipe/rib name = "Collosal Rib" @@ -154,3 +152,168 @@ /obj/item/shovel/spade = 1) result = /obj/item/shovel/serrated category = CAT_PRIMAL + +/datum/crafting_recipe/bone_screwdriver + name = "Bone Screwdriver" + result = /obj/item/screwdriver/ashwalker + time = 80 + reqs = list(/obj/item/stack/sheet/bone = 2, + /obj/item/stack/sheet/sinew = 1) + category = CAT_PRIMAL + +/datum/crafting_recipe/bone_crowbar + name = "Bone Crowbar" + result = /obj/item/crowbar/ashwalker + time = 80 + reqs = list(/obj/item/stack/sheet/bone = 2, + /obj/item/stack/sheet/sinew = 1) + category = CAT_PRIMAL + +/datum/crafting_recipe/bone_cutters + name = "Bone Wirecutters" + result = /obj/item/wirecutters/ashwalker + time = 80 + reqs = list(/obj/item/stack/sheet/bone = 2, + /obj/item/stack/sheet/sinew = 2) + category = CAT_PRIMAL + +/datum/crafting_recipe/bone_wrench + name = "Bone Wrench" + result = /obj/item/wrench/ashwalker + time = 80 + reqs = list(/obj/item/stack/sheet/bone = 2, + /obj/item/stack/sheet/sinew = 1) + category = CAT_PRIMAL + +/datum/crafting_recipe/necropolis_welding + name = "Necropolis Welding Torch" + result = /obj/item/weldingtool/experimental/ashwalker + time = 120 + reqs = list(/obj/item/stack/sheet/bone = 2, + /obj/item/stack/sheet/sinew = 2, + /obj/item/organ/regenerative_core = 1) + category = CAT_PRIMAL + +/datum/crafting_recipe/tribalbelt + name = "Hunter's Belt" + result = /obj/item/storage/belt/mining/primitive + time = 80 + reqs = list(/obj/item/stack/sheet/sinew = 4) + category = CAT_PRIMAL + +/datum/crafting_recipe/goliath_gloves + name = "Goliath Gloves" + result = /obj/item/clothing/gloves/tackler/combat/goliath + time = 80 + reqs = list(/obj/item/stack/sheet/sinew = 2, + /obj/item/stack/sheet/animalhide/goliath_hide = 2, + /obj/item/stack/sheet/cloth = 2, + /obj/item/stack/sheet/leather = 2) + category = CAT_PRIMAL + +/datum/crafting_recipe/goliath_drapes + name = "Goliath Drapes" + result = /obj/item/surgical_drapes/goliath + time = 80 + reqs = list(/obj/item/stack/sheet/sinew = 1, + /obj/item/stack/sheet/animalhide/goliath_hide = 1) + category = CAT_PRIMAL + +/datum/crafting_recipe/diamond_scalpel + name = "Diamond Scalpel" + result = /obj/item/scalpel/ashwalker + time = 80 + reqs = list(/obj/item/stack/sheet/bone = 2, + /obj/item/stack/sheet/sinew = 1, + /obj/item/stack/sheet/mineral/diamond = 1) + category = CAT_PRIMAL + +/datum/crafting_recipe/bone_retractor + name = "Bone Retractor" + result = /obj/item/retractor/ashwalker + time = 80 + reqs = list(/obj/item/stack/sheet/bone = 2, + /obj/item/stack/sheet/sinew = 1) + category = CAT_PRIMAL + +/datum/crafting_recipe/diamond_bonesaw + name = "Diamond Bonesaw" + result = /obj/item/circular_saw/ashwalker + time = 80 + reqs = list(/obj/item/stack/sheet/bone = 2, + /obj/item/stack/sheet/sinew = 1, + /obj/item/organ/regenerative_core = 1, + /obj/item/stack/sheet/mineral/diamond = 2) + category = CAT_PRIMAL + +/datum/crafting_recipe/femurstat + name = "Bone Hemostat" + result = /obj/item/hemostat/ashwalker + time = 80 + reqs = list(/obj/item/stack/sheet/bone = 2, + /obj/item/stack/sheet/sinew = 1) + category = CAT_PRIMAL + +/datum/crafting_recipe/bone_bonesetter + name = "Bone Bonersetter" + result = /obj/item/bonesetter/bone + time = 80 + reqs = list(/obj/item/stack/sheet/bone = 2, + /obj/item/stack/sheet/sinew = 1) + category = CAT_PRIMAL + +/datum/crafting_recipe/coretery + name = "Necropolis Cautery" + result = /obj/item/cautery/ashwalker + time = 80 + reqs = list(/obj/item/stack/sheet/bone = 1, + /obj/item/stack/sheet/animalhide/goliath_hide = 1, + /obj/item/organ/regenerative_core = 1) + category = CAT_PRIMAL + +/datum/crafting_recipe/bone_spade + name = "Bone Spade" + result = /obj/item/shovel/spade/bone + time = 80 + reqs = list(/obj/item/stack/sheet/bone = 1, + /obj/item/stack/sheet/sinew = 1) + category = CAT_PRIMAL + +/datum/crafting_recipe/bone_hatchet + name = "Bone Hatchet" + result = /obj/item/hatchet/bone + time = 80 + reqs = list(/obj/item/stack/sheet/bone = 1, + /obj/item/stack/sheet/sinew = 1) + category = CAT_PRIMAL + +/datum/crafting_recipe/bone_cultivator + name = "Bone Cultivator" + result = /obj/item/cultivator/bone + time = 80 + reqs = list(/obj/item/stack/sheet/bone = 2, + /obj/item/stack/sheet/sinew = 1) + category = CAT_PRIMAL + +/datum/crafting_recipe/bone_anvil + name = "Bone Anvil" + result = /obj/structure/anvil/obtainable/bone + time = 200 + reqs = list(/obj/item/stack/sheet/bone = 6, + /obj/item/stack/sheet/sinew = 2, + /obj/item/stack/sheet/animalhide/goliath_hide = 2) + tools = list(/obj/item/weldingtool/experimental/ashwalker, /obj/item/wirecutters/ashwalker, /obj/item/crowbar/ashwalker) + category = CAT_PRIMAL + +/datum/crafting_recipe/bone_glaive + name = "Necropolis Glaive" + result = /obj/item/kinetic_crusher/glaive/bone + time = 120 + reqs = list(/obj/item/stack/sheet/bone = 2, + /obj/item/stack/sheet/mineral/wood = 4, + /obj/item/stack/sheet/sinew = 4, + /obj/item/organ/regenerative_core = 2, + /obj/item/stack/sheet/mineral/diamond = 2, + /obj/item/stack/sheet/animalhide/goliath_hide = 2, + /obj/item/stack/sheet/leather = 2) + category = CAT_PRIMAL diff --git a/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm b/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm index 01ad269a8e..63972a98aa 100644 --- a/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm +++ b/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm @@ -1,19 +1,3 @@ -/datum/crafting_recipe/pin_removal - name = "Pin Removal" - result = /obj/item/gun - reqs = list(/obj/item/gun = 1) - parts = list(/obj/item/gun = 1) - tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WIRECUTTER) - time = 50 - category = CAT_WEAPONRY - subcategory = CAT_OTHER - -/datum/crafting_recipe/pin_removal/check_requirements(mob/user, list/collected_requirements) - var/obj/item/gun/G = collected_requirements[/obj/item/gun][1] - if (G.no_pin_required || !G.pin) - return FALSE - return TRUE - /datum/crafting_recipe/strobeshield name = "Strobe Shield" result = /obj/item/shield/riot/flash @@ -335,7 +319,6 @@ name = "Bone Arrow" result = /obj/item/ammo_casing/caseless/arrow/bone time = 5 - always_availible = FALSE reqs = list(/obj/item/stack/sheet/bone = 1, /obj/item/stack/sheet/sinew = 1, /obj/item/ammo_casing/caseless/arrow/ash = 1) @@ -347,7 +330,6 @@ result = /obj/item/ammo_casing/caseless/arrow/ash tools = list(TOOL_WELDER) time = 10 // 1.5 seconds minimum per actually worthwhile arrow excluding interface lag - always_availible = FALSE reqs = list(/obj/item/ammo_casing/caseless/arrow/wood = 1) category = CAT_WEAPONRY subcategory = CAT_AMMO diff --git a/code/datums/components/dullahan.dm b/code/datums/components/dullahan.dm new file mode 100644 index 0000000000..973f06a61e --- /dev/null +++ b/code/datums/components/dullahan.dm @@ -0,0 +1,210 @@ +/datum/component/dullahan + var/obj/item/dullahan_head/dullahan_head + +/datum/component/dullahan/Initialize() + . = ..() + + var/mob/living/carbon/human/H = parent + if(!H) + return . + + ADD_TRAIT(H, TRAIT_DULLAHAN, "dullahan_component") + ADD_TRAIT(H, TRAIT_NOHUNGER, "dullahan_component_no_hunger") + ADD_TRAIT(H, TRAIT_NOBREATH, "dullahan_component_no_breath") + + dullahan_head = new(get_turf(H)) + + update_name() + + dullahan_head.owner = H + RegisterSignal(H, COMSIG_LIVING_REGENERATE_LIMBS, .proc/unlist_head) + + // make sure the brain can't decay or fall out + var/obj/item/organ/brain/B = H.getorganslot(ORGAN_SLOT_BRAIN) + if(B) + B.zone = "abstract" // it exists in the ethereal plain + B.organ_flags = ORGAN_NO_SPOIL | ORGAN_NO_DISMEMBERMENT | ORGAN_VITAL + dullahan_head.B = B + + // the eyes get similar treatment + var/obj/item/organ/eyes/dullahan/new_eyes = new() + var/obj/item/organ/eyes/E = H.getorganslot(ORGAN_SLOT_EYES) + if(E) + new_eyes.left_eye_color = E.left_eye_color + new_eyes.right_eye_color = E.right_eye_color + E.Remove() + qdel(E) + new_eyes.Insert(H) + + // make sure you handle the tongue correctly, too! + var/obj/item/organ/tongue/T = H.getorganslot(ORGAN_SLOT_TONGUE) + T.Remove() + qdel(T) + + var/obj/item/organ/tongue/dullahan/new_tongue = new() + new_tongue.Insert(H) + + // uh, eyes! + var/obj/item/organ/ears/dullahan_ears = H.getorganslot(ORGAN_SLOT_EARS) + if(dullahan_ears) + dullahan_ears.zone = "abstract" + + // moving the brain's zone means we don't need the head to survive + var/obj/item/bodypart/head/head = H.get_bodypart(BODY_ZONE_HEAD) + if(head) + head.drop_limb() + qdel(head) + + H.flags_1 &= ~(HEAR_1) + + RegisterSignal(dullahan_head, COMSIG_ATOM_HEARER_IN_VIEW, .proc/include_owner) + + dullahan_head.update_appearance() + +/datum/component/dullahan/proc/update_name(retries = 0) + if(retries > 30) + return FALSE + var/mob/living/carbon/human/H = parent + if(length(H.name)) + dullahan_head.name = "[H.name]'s head" + dullahan_head.desc = "the decapitated head of [H.name]" + return TRUE + addtimer(CALLBACK(src, .proc/update_name, retries + 1), 2 SECONDS) + +/datum/component/dullahan/proc/include_owner(datum/source, list/processing_list, list/hearers) + if(!QDELETED(parent)) + hearers += parent + +/datum/component/dullahan/proc/unlist_head(datum/source, noheal = FALSE, list/excluded_limbs) + excluded_limbs |= BODY_ZONE_HEAD // So we don't gib when regenerating limbs. + +/obj/item/organ/tongue/dullahan + zone = "abstract" + initial_accents = list(/datum/accent/dullahan) + organ_flags = ORGAN_NO_SPOIL | ORGAN_NO_DISMEMBERMENT + +/obj/item/organ/eyes/dullahan + name = "head vision" + desc = "An abstraction." + actions_types = list(/datum/action/item_action/organ_action/dullahan) + zone = "abstract" + tint = INFINITY // used to switch the vision perspective to the head on species_gain(). + organ_flags = ORGAN_NO_SPOIL | ORGAN_NO_DISMEMBERMENT + +/obj/item/dullahan_head + name = "coders lament" + desc = "you shouldn't be reading this" + flags_1 = HEAR_1 + var/mob/living/carbon/human/owner + // this is for keeping track of the overlays because you can't read the actual overlays list as it's a special byond var + var/list/overlays_standing + var/obj/item/organ/brain/B + w_class = WEIGHT_CLASS_BULKY + +/obj/item/dullahan_head/Destroy() + if(owner) + B.Remove() + B.forceMove(get_turf(src)) + owner.gib() + . = ..() + +// update head sprite +/obj/item/dullahan_head/proc/remove_head_overlays() + overlays_standing = list() + cut_overlays() + +/obj/item/dullahan_head/proc/add_head_overlay(var/overlay) + overlays_standing += overlay + add_overlay(overlay) + +/obj/item/dullahan_head/update_appearance() + if(owner && !HAS_TRAIT(owner, TRAIT_HUMAN_NO_RENDER)) + remove_head_overlays() + // to do this without duplicating large amounts of code + // it's best to regenerate the head, then remove it once we have the overlays we want + owner.regenerate_limb(BODY_ZONE_HEAD, TRUE) // don't heal them + owner.cut_overlays() + owner.regenerate_icons(TRUE) // yes i know it's expensive but do you want me to rewrite our entire overlay system, also block recursive calls here by passing in TRUE (it wont go back to call update_appearance this way) + var/obj/item/bodypart/head/head = owner.get_bodypart(BODY_ZONE_HEAD) + if(head) + add_overlay(head.get_limb_icon(FALSE, TRUE, TRUE)) + for(var/overlay in owner.overlays_standing) + if(istype(overlay, /mutable_appearance)) + var/mutable_appearance/mutable = overlay + if(mutable.category == "HEAD") + add_head_overlay(mutable) + else + if(islist(overlay)) + var/list/list_appearances = overlay + for(var/overlay2 in list_appearances) + if(istype(overlay2, /mutable_appearance)) + var/mutable_appearance/mutable = overlay2 + if(mutable.category == "HEAD") + add_head_overlay(mutable) + head.drop_limb() + qdel(head) + +/obj/item/dullahan_head/proc/unlist_head(datum/source, noheal = FALSE, list/excluded_limbs) + excluded_limbs |= BODY_ZONE_HEAD // So we don't gib when regenerating limbs. + +/datum/action/item_action/organ_action/dullahan + name = "Toggle Perspective" + desc = "Switch between seeing normally from your head, or blindly from your body." + +/datum/action/item_action/organ_action/dullahan/Trigger() + . = ..() + var/mob/living/carbon/human/H = owner + var/obj/item/organ/eyes/E = owner.getorganslot(ORGAN_SLOT_EYES) + if(E) + if(E.tint) + E.tint = 0 + else + E.tint = INFINITY + + var/datum/component/dullahan/D = H.GetComponent(/datum/component/dullahan) + if(D) + D.update_vision_perspective() + +/datum/component/dullahan/proc/update_vision_perspective() + var/mob/living/carbon/human/H = parent + if(!H) + return . + var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES) + if(eyes) + H.update_tint() + if(eyes.tint) + H.reset_perspective(H) + else + H.reset_perspective(dullahan_head) + +/datum/component/dullahan/Destroy() + UnregisterSignal(parent, COMSIG_LIVING_REGENERATE_LIMBS) + dullahan_head.owner = null + qdel(dullahan_head) + REMOVE_TRAIT(parent, TRAIT_DULLAHAN, "dullahan_component") + + // work out what organs to give them based on their species + if(ishuman(parent)) + var/mob/living/carbon/human/H = parent + var/obj/item/organ/eyes/new_eyes = new H.dna.species.mutanteyes() + var/obj/item/organ/brain/new_brain = new H.dna.species.mutant_brain() + var/obj/item/organ/tongue/new_tongue = new H.dna.species.mutanttongue() + var/obj/item/organ/eyes/old_eyes = H.getorganslot(ORGAN_SLOT_EYES) + var/obj/item/organ/brain/old_brain = H.getorganslot(ORGAN_SLOT_BRAIN) + var/obj/item/organ/tongue/old_tongue = H.getorganslot(ORGAN_SLOT_TONGUE) + + H.regenerate_limb(BODY_ZONE_HEAD, TRUE) + H.reset_perspective(H) + + old_brain.Remove(TRUE,TRUE) + QDEL_NULL(old_brain) + new_brain.Insert(H, TRUE, TRUE) + + old_eyes.Remove(TRUE,TRUE) + QDEL_NULL(old_eyes) + new_eyes.Insert(H, TRUE, TRUE) + + old_tongue.Remove(TRUE,TRUE) + QDEL_NULL(old_tongue) + new_tongue.Insert(H, TRUE, TRUE) + . = ..() diff --git a/code/datums/components/embedded.dm b/code/datums/components/embedded.dm index dcbf40a16b..9bdb009962 100644 --- a/code/datums/components/embedded.dm +++ b/code/datums/components/embedded.dm @@ -152,7 +152,7 @@ to_chat(victim, "[weapon] sticks itself to your [limb.name]!") if(damage > 0) - var/armor = victim.run_armor_check(limb.body_zone, "melee", "Your armor has protected your [limb.name].", "Your armor has softened a hit to your [limb.name].",weapon.armour_penetration) + var/armor = victim.run_armor_check(limb.body_zone, MELEE, "Your armor has protected your [limb.name].", "Your armor has softened a hit to your [limb.name].",weapon.armour_penetration) limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, blocked=armor, sharpness = weapon.get_sharpness()) /// Called every time a carbon with a harmful embed moves, rolling a chance for the item to cause pain. The chance is halved if the carbon is crawling or walking. @@ -346,9 +346,9 @@ /datum/component/embedded/proc/examineTurf(datum/source, mob/user, list/examine_list) if(harmful) - examine_list += "\t There is \a [weapon] embedded in [parent]!" + examine_list += "There is \a [weapon] embedded in [parent]!" else - examine_list += "\t There is \a [weapon] stuck to [parent]!" + examine_list += "There is \a [weapon] stuck to [parent]!" /// Someone is ripping out the item from the turf by hand diff --git a/code/datums/components/field_of_vision.dm b/code/datums/components/field_of_vision.dm index 5fb7b2596c..4c03346639 100644 --- a/code/datums/components/field_of_vision.dm +++ b/code/datums/components/field_of_vision.dm @@ -327,7 +327,7 @@ /atom/movable/fov_holder/has_gravity(turf/T) return FALSE -/atom/movable/fov_holder/ex_act(severity) +/atom/movable/fov_holder/ex_act(severity, target, origin) return FALSE /atom/movable/fov_holder/singularity_act() diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm new file mode 100644 index 0000000000..4b9c25db91 --- /dev/null +++ b/code/datums/components/fullauto.dm @@ -0,0 +1,278 @@ +#define AUTOFIRE_MOUSEUP 0 +#define AUTOFIRE_MOUSEDOWN 1 + +/datum/component/automatic_fire + var/client/clicker + var/mob/living/shooter + var/atom/target + var/turf/target_loc //For dealing with locking on targets due to BYOND engine limitations (the mouse input only happening when mouse moves). + var/autofire_stat = AUTOFIRE_STAT_IDLE + var/mouse_parameters + var/autofire_shot_delay = 0.3 SECONDS //Time between individual shots. + var/mouse_status = AUTOFIRE_MOUSEUP //This seems hacky but there can be two MouseDown() without a MouseUp() in between if the user holds click and uses alt+tab, printscreen or similar. + + COOLDOWN_DECLARE(next_shot_cd) + +/datum/component/automatic_fire/Initialize(_autofire_shot_delay) + . = ..() + if(!isgun(parent)) + return COMPONENT_INCOMPATIBLE + var/obj/item/gun = parent + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/wake_up) + RegisterSignal(parent, COMSIG_GUN_AUTOFIRE_SELECTED, .proc/wake_up) + RegisterSignal(parent, list(COMSIG_PARENT_PREQDELETED, COMSIG_ITEM_DROPPED, COMSIG_GUN_AUTOFIRE_DESELECTED), .proc/autofire_off) + if(_autofire_shot_delay) + autofire_shot_delay = _autofire_shot_delay + if(ismob(gun.loc)) + var/mob/user = gun.loc + wake_up(src, user) + + +/datum/component/automatic_fire/Destroy() + UnregisterSignal(parent, list(COMSIG_PARENT_PREQDELETED, COMSIG_ITEM_DROPPED, COMSIG_GUN_AUTOFIRE_DESELECTED)) + autofire_off() + return ..() + +/datum/component/automatic_fire/process(delta_time) + if(!(autofire_stat & AUTOFIRE_STAT_FIRING)) + STOP_PROCESSING(SSprojectiles, src) + return + + if(!COOLDOWN_FINISHED(src, next_shot_cd)) + return + + process_shot() + +/datum/component/automatic_fire/proc/wake_up(datum/source, mob/user, slot) + SIGNAL_HANDLER + + if(autofire_stat & (AUTOFIRE_STAT_ALERT)) + return //We've updated the firemode. No need for more. + if(autofire_stat & AUTOFIRE_STAT_FIRING) + stop_autofiring() //Let's stop shooting to avoid issues. + return + + var/obj/item/gun/G = parent + + if(iscarbon(user)) + var/mob/living/carbon/shooter = user + if(shooter.is_holding(parent) && G.fire_select == SELECT_FULLY_AUTOMATIC) + autofire_on(shooter.client) + else + autofire_off() + +// There is a gun and there is a user wielding it. The component now waits for the mouse click. +/datum/component/automatic_fire/proc/autofire_on(client/usercli) + SIGNAL_HANDLER + if(autofire_stat & (AUTOFIRE_STAT_ALERT|AUTOFIRE_STAT_FIRING)) + return + autofire_stat = AUTOFIRE_STAT_ALERT + clicker = usercli + shooter = clicker.mob + RegisterSignal(clicker, COMSIG_CLIENT_MOUSEDOWN, .proc/on_mouse_down) + RegisterSignal(shooter, COMSIG_MOB_CLIENT_LOGOUT, .proc/autofire_off) + if(!QDELETED(shooter)) + UnregisterSignal(shooter, COMSIG_MOB_CLIENT_LOGIN) + parent.RegisterSignal(src, COMSIG_AUTOFIRE_ONMOUSEDOWN, /obj/item/gun/.proc/autofire_bypass_check) + parent.RegisterSignal(parent, COMSIG_AUTOFIRE_SHOT, /obj/item/gun/.proc/do_autofire) + + +/datum/component/automatic_fire/proc/autofire_off(datum/source) + SIGNAL_HANDLER + if(autofire_stat & (AUTOFIRE_STAT_IDLE)) + return + if(autofire_stat & AUTOFIRE_STAT_FIRING) + stop_autofiring() + + autofire_stat = AUTOFIRE_STAT_IDLE + + if(!QDELETED(clicker)) + UnregisterSignal(clicker, list(COMSIG_CLIENT_MOUSEDOWN, COMSIG_CLIENT_MOUSEUP, COMSIG_CLIENT_MOUSEDRAG)) + mouse_status = AUTOFIRE_MOUSEUP //In regards to the component there's no click anymore to care about. + clicker = null + RegisterSignal(shooter, COMSIG_MOB_CLIENT_LOGIN, .proc/on_client_login) + if(!QDELETED(shooter)) + UnregisterSignal(shooter, COMSIG_MOB_CLIENT_LOGOUT) + shooter = null + parent.UnregisterSignal(parent, COMSIG_AUTOFIRE_SHOT) + parent.UnregisterSignal(src, COMSIG_AUTOFIRE_ONMOUSEDOWN) + +/datum/component/automatic_fire/proc/on_client_login(mob/source) + SIGNAL_HANDLER + if(!source.client) + return + if(source.is_holding(parent)) + autofire_on(source.client) + +/datum/component/automatic_fire/proc/on_mouse_down(client/source, atom/_target, turf/location, control, params) + var/list/modifiers = params2list(params) //If they're shift+clicking, for example, let's not have them accidentally shoot. + + if(LAZYACCESS(modifiers, SHIFT_CLICK)) + return + if(LAZYACCESS(modifiers, CTRL_CLICK)) + return + if(LAZYACCESS(modifiers, MIDDLE_CLICK)) + return + if(LAZYACCESS(modifiers, RIGHT_CLICK)) + return + if(LAZYACCESS(modifiers, ALT_CLICK)) + return + if(source.mob.in_throw_mode) + return + if(!isturf(source.mob.loc)) //No firing inside lockers and stuff. + return + if(get_dist(source.mob, _target) < 2) //Adjacent clicking. + return + + if(isnull(location)) //Clicking on a screen object. + if(_target.plane != CLICKCATCHER_PLANE) //The clickcatcher is a special case. We want the click to trigger then, under it. + return //If we click and drag on our worn backpack, for example, we want it to open instead. + _target = params2turf(modifiers["screen-loc"], get_turf(source.eye), source) + if(!_target) + CRASH("Failed to get the turf under clickcatcher") + + if(SEND_SIGNAL(src, COMSIG_AUTOFIRE_ONMOUSEDOWN, source, _target, location, control, params) & COMPONENT_AUTOFIRE_ONMOUSEDOWN_BYPASS) + return + + source.click_intercept_time = world.time //From this point onwards Click() will no longer be triggered. + + if(autofire_stat & (AUTOFIRE_STAT_IDLE)) + CRASH("on_mouse_down() called with [autofire_stat] autofire_stat") + if(autofire_stat & AUTOFIRE_STAT_FIRING) + stop_autofiring() //This can happen if we click and hold and then alt+tab, printscreen or other such action. MouseUp won't be called then and it will keep autofiring. + + target = _target + target_loc = get_turf(target) + mouse_parameters = params + start_autofiring() + + +//Dakka-dakka +/datum/component/automatic_fire/proc/start_autofiring() + if(autofire_stat == AUTOFIRE_STAT_FIRING) + return //Already pew-pewing. + autofire_stat = AUTOFIRE_STAT_FIRING + + clicker.mouse_override_icon = 'icons/effects/mouse_pointers/weapon_pointer.dmi' + clicker.mouse_pointer_icon = clicker.mouse_override_icon + + if(mouse_status == AUTOFIRE_MOUSEUP) //See mouse_status definition for the reason for this. + RegisterSignal(clicker, COMSIG_CLIENT_MOUSEUP, .proc/on_mouse_up) + mouse_status = AUTOFIRE_MOUSEDOWN + + RegisterSignal(shooter, COMSIG_MOB_SWAP_HANDS, .proc/stop_autofiring) + + if(isgun(parent)) + var/obj/item/gun/shoota = parent + if(!shoota.on_autofire_start(shooter)) //This is needed because the minigun has a do_after before firing and signals are async. + stop_autofiring() + return + if(autofire_stat != AUTOFIRE_STAT_FIRING) + return //Things may have changed while on_autofire_start() was being processed, due to do_after's sleep. + + if(!process_shot()) //First shot is processed instantly. + return //If it fails, such as when the gun is empty, then there's no need to schedule a second shot. + + START_PROCESSING(SSprojectiles, src) + RegisterSignal(clicker, COMSIG_CLIENT_MOUSEDRAG, .proc/on_mouse_drag) + + +/datum/component/automatic_fire/proc/on_mouse_up(datum/source, atom/object, turf/location, control, params) + SIGNAL_HANDLER + UnregisterSignal(clicker, COMSIG_CLIENT_MOUSEUP) + mouse_status = AUTOFIRE_MOUSEUP + if(autofire_stat == AUTOFIRE_STAT_FIRING) + stop_autofiring() + return COMPONENT_CLIENT_MOUSEUP_INTERCEPT + + +/datum/component/automatic_fire/proc/stop_autofiring(datum/source, atom/object, turf/location, control, params) + SIGNAL_HANDLER + switch(autofire_stat) + if(AUTOFIRE_STAT_IDLE, AUTOFIRE_STAT_ALERT) + return + STOP_PROCESSING(SSprojectiles, src) + autofire_stat = AUTOFIRE_STAT_ALERT + if(clicker) + clicker.mouse_override_icon = null + clicker.mouse_pointer_icon = clicker.mouse_override_icon + UnregisterSignal(clicker, COMSIG_CLIENT_MOUSEDRAG) + if(!QDELETED(shooter)) + UnregisterSignal(shooter, COMSIG_MOB_SWAP_HANDS) + target = null + target_loc = null + mouse_parameters = null + +/datum/component/automatic_fire/proc/on_mouse_drag(client/source, atom/src_object, atom/over_object, turf/src_location, turf/over_location, src_control, over_control, params) + SIGNAL_HANDLER + if(isnull(over_location)) //This happens when the mouse is over an inventory or screen object, or on entering deep darkness, for example. + var/list/modifiers = params2list(params) + var/new_target = params2turf(modifiers["screen-loc"], get_turf(source.eye), source) + mouse_parameters = params + if(!new_target) + if(QDELETED(target)) //No new target acquired, and old one was deleted, get us out of here. + stop_autofiring() + CRASH("on_mouse_drag failed to get the turf under screen object [over_object.type]. Old target was incidentally QDELETED.") + target = get_turf(target) //If previous target wasn't a turf, let's turn it into one to avoid locking onto a potentially moving target. + target_loc = target + CRASH("on_mouse_drag failed to get the turf under screen object [over_object.type]") + target = new_target + target_loc = new_target + return + target = over_object + target_loc = get_turf(over_object) + mouse_parameters = params + + +/datum/component/automatic_fire/proc/process_shot() + if(autofire_stat != AUTOFIRE_STAT_FIRING) + return + if(QDELETED(target) || get_turf(target) != target_loc) //Target moved or got destroyed since we last aimed. + target = target_loc //So we keep firing on the emptied tile until we move our mouse and find a new target. + if(get_dist(shooter, target) <= 0) + target = get_step(shooter, shooter.dir) //Shoot in the direction faced if the mouse is on the same tile as we are. + target_loc = target + else if(!in_view_range(shooter, target)) + stop_autofiring() //Elvis has left the building. + return FALSE + shooter.face_atom(target) + COOLDOWN_START(src, next_shot_cd, autofire_shot_delay) + if(SEND_SIGNAL(parent, COMSIG_AUTOFIRE_SHOT, target, shooter, mouse_parameters) & COMPONENT_AUTOFIRE_SHOT_SUCCESS) + return TRUE + stop_autofiring() + return FALSE + +// Gun procs. + +/obj/item/gun/proc/on_autofire_start(mob/living/shooter) + if(!can_shoot(shooter) || !can_trigger_gun(shooter) || semicd) + return FALSE + var/obj/item/bodypart/other_hand = shooter.has_hand_for_held_index(shooter.get_inactive_hand_index()) + if(weapon_weight == WEAPON_HEAVY && (shooter.get_inactive_held_item() || !other_hand)) + to_chat(shooter, "You need two hands to fire [src]!") + return FALSE + return TRUE + + +/obj/item/gun/proc/autofire_bypass_check(datum/source, client/clicker, atom/target, turf/location, control, params) + SIGNAL_HANDLER + if(clicker.mob.get_active_held_item() != src) + return COMPONENT_AUTOFIRE_ONMOUSEDOWN_BYPASS + + +/obj/item/gun/proc/do_autofire(datum/source, atom/target, mob/living/shooter, params) + SIGNAL_HANDLER_DOES_SLEEP + if(!can_shoot()) + shoot_with_empty_chamber(shooter) + return NONE + var/obj/item/gun/akimbo_gun = shooter.get_inactive_held_item() + var/bonus_spread = 0 + if(istype(akimbo_gun) && weapon_weight < WEAPON_MEDIUM) + if(akimbo_gun.weapon_weight < WEAPON_MEDIUM && akimbo_gun.can_trigger_gun(shooter)) + bonus_spread = dual_wield_spread + addtimer(CALLBACK(akimbo_gun, /obj/item/gun.proc/process_fire, target, shooter, TRUE, params, null, bonus_spread), 1) + process_fire(target, shooter, TRUE, params, null, bonus_spread) + return COMPONENT_AUTOFIRE_SHOT_SUCCESS //All is well, we can continue shooting. + +#undef AUTOFIRE_MOUSEUP +#undef AUTOFIRE_MOUSEDOWN diff --git a/code/datums/components/gps.dm b/code/datums/components/gps.dm index f3ff912321..d78bd799a2 100644 --- a/code/datums/components/gps.dm +++ b/code/datums/components/gps.dm @@ -20,14 +20,22 @@ GLOBAL_LIST_EMPTY(GPS_list) /datum/component/gps/item var/updating = TRUE //Automatic updating of GPS list. Can be set to manual by user. var/global_mode = TRUE //If disabled, only GPS signals of the same Z level are shown + /// UI state of GPS, altering when it can be used. + var/datum/ui_state/state = null -/datum/component/gps/item/Initialize(_gpstag = "COM0", emp_proof = FALSE, starton = TRUE) +/datum/component/gps/item/Initialize(_gpstag = "COM0", emp_proof = FALSE, starton = TRUE, state = null, overlay_state = "working") . = ..() if(. == COMPONENT_INCOMPATIBLE || !isitem(parent)) return COMPONENT_INCOMPATIBLE + + if(isnull(state)) + state = GLOB.default_state + src.state = state + var/atom/A = parent if(starton) - A.add_overlay("working") + if(overlay_state) + A.add_overlay(overlay_state) else tracking = FALSE A.name = "[initial(A.name)] ([gpstag])" @@ -36,6 +44,7 @@ GLOBAL_LIST_EMPTY(GPS_list) RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/on_emp_act) RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine) RegisterSignal(parent, COMSIG_CLICK_ALT, .proc/on_AltClick) + RegisterSignal(parent, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, .proc/on_requesting_context_from_item) ///Called on COMSIG_ITEM_ATTACK_SELF /datum/component/gps/item/proc/interact(datum/source, mob/user) @@ -46,6 +55,17 @@ GLOBAL_LIST_EMPTY(GPS_list) /datum/component/gps/item/proc/on_examine(datum/source, mob/user, list/examine_list) examine_list += "Alt-click to switch it [tracking ? "off":"on"]." +/datum/component/gps/item/proc/on_requesting_context_from_item( + obj/source, + list/context, + obj/item/held_item, + mob/living/user, +) + SIGNAL_HANDLER + + LAZYSET(context[SCREENTIP_CONTEXT_ALT_LMB], INTENT_ANY, tracking ? "Turn off" : "Turn on") + return CONTEXTUAL_SCREENTIP_SET + ///Called on COMSIG_ATOM_EMP_ACT /datum/component/gps/item/proc/on_emp_act(datum/source, severity) emped = TRUE @@ -93,6 +113,9 @@ GLOBAL_LIST_EMPTY(GPS_list) ui.open() ui.set_autoupdate(updating) +/datum/component/gps/item/ui_state(mob/user) + return state + /datum/component/gps/item/ui_data(mob/user) var/list/data = list() data["power"] = tracking diff --git a/code/datums/components/identification.dm b/code/datums/components/identification.dm index 59b98b57ac..cd47cfcbeb 100644 --- a/code/datums/components/identification.dm +++ b/code/datums/components/identification.dm @@ -61,7 +61,7 @@ if(identification_method_flags & ID_COMPONENT_EFFECT_NO_ACTIONS) return COMPONENT_NO_GRANT_ACTIONS -/datum/component/identification/proc/check_knowledge(mob/user) +/datum/component/identification/proc/check_knowledge(datum/source, mob/user) return ID_COMPONENT_KNOWLEDGE_NONE /datum/component/identification/proc/on_identify(mob/user) @@ -83,7 +83,7 @@ */ /datum/component/identification/syndicate -/datum/component/identification/syndicate/check_knowledge(mob/user) +/datum/component/identification/syndicate/check_knowledge(datum/source, mob/user) . = ..() if(user?.mind?.has_antag_datum(/datum/antagonist/traitor)) . = max(., ID_COMPONENT_KNOWLEDGE_FULL) diff --git a/code/datums/components/killerqueen.dm b/code/datums/components/killerqueen.dm index c700e0d17e..0f7d3f0346 100644 --- a/code/datums/components/killerqueen.dm +++ b/code/datums/components/killerqueen.dm @@ -1,6 +1,6 @@ /** * KILLER QUEEN - * + * * Simple contact bomb component * Blows up the first person to touch it. */ @@ -26,7 +26,7 @@ var/flame = 0 /// only triggered by living mobs var/living_only = TRUE - + /datum/component/killerqueen/Initialize(ex_strength = EXPLODE_HEAVY, datum/callback/pre_explode, datum/callback/failure, examine_message, light = 0, heavy = 0, dev = 0, flame = 0, living_only = TRUE) . = ..() diff --git a/code/datums/components/knockoff.dm b/code/datums/components/knockoff.dm index 7d399c7d26..b9cdb7754c 100644 --- a/code/datums/components/knockoff.dm +++ b/code/datums/components/knockoff.dm @@ -11,7 +11,7 @@ RegisterSignal(parent, COMSIG_ITEM_DROPPED,.proc/OnDropped) src.knockoff_chance = knockoff_chance - + if(zone_override) target_zones = zone_override diff --git a/code/datums/components/mirv.dm b/code/datums/components/mirv.dm index 2a1663776c..77c47bcb1d 100644 --- a/code/datums/components/mirv.dm +++ b/code/datums/components/mirv.dm @@ -38,5 +38,5 @@ P.range = override_projectile_range P.preparePixelProjectile(shootat_turf, target) P.firer = firer // don't hit ourself that would be really annoying - P.permutated += target // don't hit the target we hit already with the flak + P.impacted = list(target = TRUE) // don't hit the target we hit already with the flak P.fire() diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index e100326f7b..6a1d8a3d75 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -34,6 +34,7 @@ RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, .proc/modify_hud) RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/stop_processing) RegisterSignal(parent, COMSIG_VOID_MASK_ACT, .proc/direct_sanity_drain) + RegisterSignal(parent, COMSIG_ENTER_AREA, .proc/update_beauty) if(owner.hud_used) @@ -50,7 +51,7 @@ STOP_PROCESSING(SSobj, src) /datum/component/mood/proc/print_mood(mob/user) - var/msg = "*---------*\nYour current mood\n" + var/msg = "
Your current mood\n" msg += "My mental status: " //Long term switch(sanity) if(SANITY_GREAT to INFINITY) @@ -69,23 +70,23 @@ msg += "My current mood: " //Short term switch(mood_level) if(1) - msg += "I wish I was dead!\n" + msg += "I wish I was dead!\n" if(2) - msg += "I feel terrible...\n" + msg += "I feel terrible...\n" if(3) - msg += "I feel very upset.\n" + msg += "I feel very upset.\n" if(4) - msg += "I'm a bit sad.\n" + msg += "I'm a bit sad.\n" if(5) - msg += "I'm alright.\n" + msg += "I'm alright.\n" if(6) - msg += "I feel pretty okay.\n" + msg += "I feel pretty okay.\n" if(7) - msg += "I feel pretty good.\n" + msg += "I feel pretty good.\n" if(8) - msg += "I feel amazing!\n" + msg += "I feel amazing!\n" if(9) - msg += "I love life!\n" + msg += "I love life!\n" msg += "Moodlets:\n"//All moodlets if(mood_events.len) @@ -93,7 +94,8 @@ var/datum/mood_event/event = mood_events[i] msg += event.description else - msg += "I don't have much of a reaction to anything right now.\n" + msg += "I don't have much of a reaction to anything right now.\n" + msg += "
" to_chat(user || parent, msg) ///Called after moodevent/s have been added/removed. @@ -349,7 +351,7 @@ if(ETHEREAL_CHARGE_OVERLOAD to ETHEREAL_CHARGE_DANGEROUS) add_event(null, "charge", /datum/mood_event/supercharged) -/datum/component/mood/proc/update_beauty(area/A) +/datum/component/mood/proc/update_beauty(datum/source, area/A) if(A.outdoors) //if we're outside, we don't care. clear_event(null, "area_beauty") return FALSE diff --git a/code/datums/components/multiple_lives.dm b/code/datums/components/multiple_lives.dm new file mode 100644 index 0000000000..3f4418a9d1 --- /dev/null +++ b/code/datums/components/multiple_lives.dm @@ -0,0 +1,47 @@ +/** + * A simple component that spawns a mob of the same type and transfers itself to it when parent dies. + * For more complex behaviors, use the COMSIG_ON_MULTIPLE_LIVES_RESPAWN comsig. + */ +/datum/component/multiple_lives + can_transfer = TRUE + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS + /// The number of respawns the living mob has left. + var/lives_left + +/datum/component/multiple_lives/Initialize(lives_left) + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE + + src.lives_left = lives_left + +/datum/component/multiple_lives/RegisterWithParent() + RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/respawn) + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine) + +/datum/component/multiple_lives/UnregisterFromParent() + UnregisterSignal(parent, list(COMSIG_MOB_DEATH, COMSIG_PARENT_EXAMINE)) + +/datum/component/multiple_lives/proc/respawn(mob/living/source, gibbed) + SIGNAL_HANDLER + if(source.suiciding) //Freed from this mortail coil. + qdel(src) + return + var/mob/living/respawned_mob = new source.type (source.drop_location()) + source.mind?.transfer_to(respawned_mob) + lives_left-- + if(lives_left <= 0) + qdel(src) + source.TransferComponents(respawned_mob) + SEND_SIGNAL(source, COMSIG_ON_MULTIPLE_LIVES_RESPAWN, respawned_mob, gibbed, lives_left) + +/datum/component/multiple_lives/proc/on_examine(mob/living/source, mob/user, list/examine_list) + SIGNAL_HANDLER + if(isobserver(user) || source == user) + examine_list += "[source.p_theyve(TRUE)] [lives_left] extra lives left." + +/datum/component/multiple_lives/InheritComponent(datum/component/multiple_lives/new_comp , lives_left) + src.lives_left += new_comp ? new_comp.lives_left : lives_left + +/datum/component/multiple_lives/PostTransfer() + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE diff --git a/code/datums/components/pellet_cloud.dm b/code/datums/components/pellet_cloud.dm index f88b9e1869..a06242962f 100644 --- a/code/datums/components/pellet_cloud.dm +++ b/code/datums/components/pellet_cloud.dm @@ -198,7 +198,7 @@ break ///One of our pellets hit something, record what it was and check if we're done (terminated == num_pellets) -/datum/component/pellet_cloud/proc/pellet_hit(obj/item/projectile/P, atom/movable/firer, atom/target, Angle, hit_zone) +/datum/component/pellet_cloud/proc/pellet_hit(obj/item/projectile/P, atom/movable/firer, atom/target, Angle, hit_zone, blocked) pellets -= P terminated++ hits++ @@ -208,14 +208,14 @@ hit_part = hit_carbon.get_bodypart(hit_zone) if(hit_part) target = hit_part - if(P.wound_bonus != CANT_WOUND) // handle wounding + if(P.wound_bonus != CANT_WOUND && (blocked < 100)) // handle wounding // unfortunately, due to how pellet clouds handle finalizing only after every pellet is accounted for, that also means there might be a short delay in dealing wounds if one pellet goes wide // while buckshot may reach a target or miss it all in one tick, we also have to account for possible ricochets that may take a bit longer to hit the target if(isnull(wound_info_by_part[hit_part])) wound_info_by_part[hit_part] = list(0, 0, 0) - wound_info_by_part[hit_part][CLOUD_POSITION_DAMAGE] += P.damage // these account for decay - wound_info_by_part[hit_part][CLOUD_POSITION_W_BONUS] += P.wound_bonus - wound_info_by_part[hit_part][CLOUD_POSITION_BW_BONUS] += P.bare_wound_bonus + wound_info_by_part[hit_part][CLOUD_POSITION_DAMAGE] += (P.damage * ((100 - blocked) * 0.01))// these account for decay and now block + wound_info_by_part[hit_part][CLOUD_POSITION_W_BONUS] = max(wound_info_by_part[hit_part][CLOUD_POSITION_W_BONUS], P.wound_bonus) + wound_info_by_part[hit_part][CLOUD_POSITION_BW_BONUS] = max(wound_info_by_part[hit_part][CLOUD_POSITION_W_BONUS], P.bare_wound_bonus) P.wound_bonus = CANT_WOUND // actual wounding will be handled aggregate targets_hit[target]++ @@ -242,7 +242,7 @@ P.original = target P.fired_from = parent P.firer = parent // don't hit ourself that would be really annoying - P.permutated += parent // don't hit the target we hit already with the flak + P.impacted = list(parent = TRUE) // don't hit the target we hit already with the flak P.suppressed = SUPPRESSED_VERY // set the projectiles to make no message so we can do our own aggregate message P.preparePixelProjectile(target, parent) RegisterSignal(P, COMSIG_PROJECTILE_SELF_ON_HIT, .proc/pellet_hit) @@ -259,7 +259,7 @@ var/num_hits = targets_hit[target] UnregisterSignal(target, COMSIG_PARENT_QDELETING) var/obj/item/bodypart/hit_part - if(isbodypart(target)) + if(isbodypart(target) && wound_info_by_part[hit_part]) hit_part = target target = hit_part.owner var/damage_dealt = wound_info_by_part[hit_part][CLOUD_POSITION_DAMAGE] diff --git a/code/datums/components/phantomthief.dm b/code/datums/components/phantomthief.dm index 6b7e7221c3..a73754d04a 100644 --- a/code/datums/components/phantomthief.dm +++ b/code/datums/components/phantomthief.dm @@ -9,7 +9,7 @@ var/filter_size var/filter_color -/datum/component/wearertargeting/phantomthief/Initialize(_x = -2, _y = 0, _size = 0, _color = "#E62111", list/_valid_slots = list(SLOT_GLASSES)) +/datum/component/wearertargeting/phantomthief/Initialize(_x = -2, _y = 0, _size = 0, _color = "#E62111", list/_valid_slots = list(ITEM_SLOT_EYES)) . = ..() if(. == COMPONENT_INCOMPATIBLE) return diff --git a/code/datums/components/pricetag.dm b/code/datums/components/pricetag.dm new file mode 100644 index 0000000000..2ad63c6464 --- /dev/null +++ b/code/datums/components/pricetag.dm @@ -0,0 +1,35 @@ +/datum/component/pricetag + ///Payee gets 100% of the value if no ratio has been set. + var/default_profit_ratio = 1 + ///List of bank accounts this pricetag pays out to. Format is payees[bank_account] = profit_ratio. + var/list/payees = list() + + +/datum/component/pricetag/Initialize(_owner,_profit_ratio) + if(!isobj(parent)) //Has to account for both objects and sellable structures like crates. + return COMPONENT_INCOMPATIBLE + if(_profit_ratio) + payees[_owner] = _profit_ratio + else + payees[_owner] = default_profit_ratio + RegisterSignal(parent, COMSIG_ITEM_SOLD, .proc/split_profit) + RegisterSignal(parent, COMSIG_STRUCTURE_UNWRAPPED, .proc/Unwrapped) + RegisterSignal(parent, COMSIG_ITEM_UNWRAPPED, .proc/Unwrapped) + RegisterSignal(parent, COMSIG_ITEM_SPLIT_PROFIT, .proc/return_ratio) + +/datum/component/pricetag/proc/Unwrapped() + qdel(src) //Once it leaves it's wrapped container, the object in question should lose it's pricetag component. + +/datum/component/pricetag/proc/split_profit(var/item_value) + var/price = item_value + if(price) + for(var/datum/bank_account/payee in payees) + var/profit_ratio = payees[payee] + var/adjusted_value = price * profit_ratio + var/datum/bank_account/bank_account = payee + bank_account.adjust_money(adjusted_value) + bank_account.bank_card_talk("Sale of [parent] recorded. [adjusted_value] credits added to account.") + return TRUE + +/datum/component/pricetag/proc/return_ratio() + return default_profit_ratio diff --git a/code/datums/components/riding.dm b/code/datums/components/riding.dm index e11eca2975..a074fe6f5f 100644 --- a/code/datums/components/riding.dm +++ b/code/datums/components/riding.dm @@ -219,6 +219,7 @@ if(!fireman_carrying) M.Daze(25) REMOVE_TRAIT(M, TRAIT_MOBILITY_NOUSE, src) + REMOVE_TRAIT(M, TRAIT_BEING_CARRIED, src) return ..() /datum/component/riding/human/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE) @@ -228,6 +229,7 @@ H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/human_carry, TRUE, fireman_carrying? FIREMAN_CARRY_SLOWDOWN : PIGGYBACK_CARRY_SLOWDOWN) if(fireman_carrying) ADD_TRAIT(M, TRAIT_MOBILITY_NOUSE, src) + ADD_TRAIT(M, TRAIT_BEING_CARRIED, src) /datum/component/riding/human/proc/on_host_unarmed_melee(atom/target) var/mob/living/carbon/human/H = parent diff --git a/code/datums/components/rotation.dm b/code/datums/components/rotation.dm index b8d629273b..4b0e58df18 100644 --- a/code/datums/components/rotation.dm +++ b/code/datums/components/rotation.dm @@ -44,6 +44,7 @@ RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/ExamineMessage) if(rotation_flags & ROTATION_WRENCH) RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/WrenchRot) + RegisterSignal(parent, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, .proc/on_requesting_context_from_item) /datum/component/simple_rotation/proc/add_verbs() if(rotation_flags & ROTATION_VERBS) @@ -63,7 +64,7 @@ AM.verbs -= /atom/movable/proc/simple_rotate_counterclockwise /datum/component/simple_rotation/proc/remove_signals() - UnregisterSignal(parent, list(COMSIG_CLICK_ALT, COMSIG_PARENT_EXAMINE, COMSIG_PARENT_ATTACKBY)) + UnregisterSignal(parent, list(COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, COMSIG_CLICK_ALT, COMSIG_PARENT_EXAMINE, COMSIG_PARENT_ATTACKBY)) /datum/component/simple_rotation/RegisterWithParent() add_verbs() @@ -157,6 +158,21 @@ /datum/component/simple_rotation/proc/default_after_rotation(mob/user, rotation_type) to_chat(user,"You [rotation_type == ROTATION_FLIP ? "flip" : "rotate"] [parent].") +/datum/component/simple_rotation/proc/on_requesting_context_from_item( + obj/source, + list/context, + obj/item/held_item, + mob/living/user, +) + var/rotation = (rotation_flags & ROTATION_FLIP) ? "Flip" : "Rotate [rotation_flags & ROTATION_CLOCKWISE ? "clockwise" : "counter-clockwise"]" + + if(rotation_flags & ROTATION_ALTCLICK) + LAZYSET(context[SCREENTIP_CONTEXT_ALT_LMB], INTENT_ANY, rotation) + . = CONTEXTUAL_SCREENTIP_SET + if(held_item?.tool_behaviour == TOOL_WRENCH && (rotation_flags & ROTATION_WRENCH)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, rotation) + . = CONTEXTUAL_SCREENTIP_SET + /atom/movable/proc/simple_rotate_clockwise() set name = "Rotate Clockwise" set category = "Object" diff --git a/code/datums/components/shielded.dm b/code/datums/components/shielded.dm index 3cf70e80ef..79a84427f4 100644 --- a/code/datums/components/shielded.dm +++ b/code/datums/components/shielded.dm @@ -108,7 +108,7 @@ SSvis_overlays.add_vis_overlay(holder, 'icons/effects/effects.dmi', to_add, layer, GAME_PLANE, holder.dir) /datum/component/shielded/proc/on_equip(obj/item/source, mob/living/equipper, slot) - if(!(accepted_slots & slotdefine2slotbit(slot))) + if(!(accepted_slots & slot)) return holder = equipper RegisterSignal(parent, COMSIG_ITEM_RUN_BLOCK, .proc/on_run_block) diff --git a/code/datums/components/squeak.dm b/code/datums/components/squeak.dm index a285b7d3f2..faca18caff 100644 --- a/code/datums/components/squeak.dm +++ b/code/datums/components/squeak.dm @@ -42,6 +42,8 @@ RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop) if(istype(parent, /obj/item/clothing/shoes)) RegisterSignal(parent, COMSIG_SHOES_STEP_ACTION, .proc/step_squeak) + else if(isstructure(parent)) + RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/use_squeak) override_squeak_sounds = custom_sounds if(chance_override) diff --git a/code/datums/components/storage/concrete/_concrete.dm b/code/datums/components/storage/concrete/_concrete.dm index 55c3e1d083..6f08959dd2 100644 --- a/code/datums/components/storage/concrete/_concrete.dm +++ b/code/datums/components/storage/concrete/_concrete.dm @@ -66,7 +66,7 @@ /datum/component/storage/concrete/_insert_physical_item(obj/item/I, override = FALSE) . = TRUE var/atom/real_location = real_location() - if(I.loc != real_location && real_location) + if(real_location && I.loc != real_location) I.forceMove(real_location) refresh_mob_views() @@ -95,16 +95,19 @@ return FALSE /datum/component/storage/concrete/proc/on_contents_del(datum/source, atom/A) + SIGNAL_HANDLER var/atom/real_location = parent if(A in real_location) usr = null remove_from_storage(A, null) /datum/component/storage/concrete/proc/on_deconstruct(datum/source, disassembled) + SIGNAL_HANDLER if(drop_all_on_deconstruct) do_quick_empty() /datum/component/storage/concrete/proc/on_break(datum/source, damage_flag) + SIGNAL_HANDLER if(drop_all_on_break) do_quick_empty() if(unlock_on_break) @@ -131,12 +134,16 @@ var/list/seeing_mobs = can_see_contents() for(var/mob/M in seeing_mobs) M.client.screen -= AM - if(ismob(parent.loc) && isitem(AM)) - var/obj/item/I = AM - var/mob/M = parent.loc - I.dropped(M) + if(isitem(AM)) + var/obj/item/removed_item = AM + removed_item.item_flags &= ~IN_STORAGE + if(ismob(parent.loc)) + var/mob/carrying_mob = parent.loc + removed_item.dropped(carrying_mob, TRUE) if(new_location) - AM.forceMove(new_location) // exited comsig will handle removal reset. + //Reset the items values + _removal_reset(AM) + AM.forceMove(new_location) //We don't want to call this if the item is being destroyed AM.on_exit_storage(src) else @@ -145,7 +152,7 @@ refresh_mob_views() if(isobj(parent)) var/obj/O = parent - O.update_icon() + O.update_appearance() return TRUE /datum/component/storage/concrete/proc/slave_can_insert_object(datum/component/storage/slave, obj/item/I, stop_messages = FALSE, mob/M) @@ -156,7 +163,7 @@ if(. && !prevent_warning) slave.mob_item_insertion_feedback(usr, M, I) -/datum/component/storage/concrete/handle_item_insertion(obj/item/I, prevent_warning = FALSE, mob/M, datum/component/storage/remote) //Remote is null or the slave datum +/datum/component/storage/concrete/handle_item_insertion(obj/item/I, prevent_warning = FALSE, mob/M, datum/component/storage/remote) //Remote is null or the slave datum var/datum/component/storage/concrete/master = master() var/atom/parent = src.parent var/moved = FALSE @@ -166,7 +173,7 @@ if(!M.temporarilyRemoveItemFromInventory(I)) return FALSE else - moved = TRUE //At this point if the proc fails we need to manually move the object back to the turf/mob/whatever. + moved = TRUE //At this point if the proc fails we need to manually move the object back to the turf/mob/whatever. if(I.pulledby) I.pulledby.stop_pulling() if(silent) @@ -180,6 +187,7 @@ I.forceMove(parent.drop_location()) return FALSE I.on_enter_storage(master) + I.item_flags |= IN_STORAGE refresh_mob_views() I.mouse_opacity = MOUSE_OPACITY_OPAQUE //So you can click on the area around the item to equip it, instead of having to pixel hunt if(M) @@ -200,7 +208,7 @@ /datum/component/storage/concrete/update_icon() if(isobj(parent)) var/obj/O = parent - O.update_icon() + O.update_appearance() for(var/i in slaves) var/datum/component/storage/slave = i slave.update_icon() diff --git a/code/datums/components/storage/concrete/rped.dm b/code/datums/components/storage/concrete/rped.dm index 3744e833ac..bf96ae436f 100644 --- a/code/datums/components/storage/concrete/rped.dm +++ b/code/datums/components/storage/concrete/rped.dm @@ -37,9 +37,9 @@ to_chat(M, "You start dumping out tier/cell rating [lowest_rating] parts from [parent].") var/turf/T = get_turf(A) var/datum/progressbar/progress = new(M, length(things), T) - while (do_after(M, 10, TRUE, T, FALSE, CALLBACK(src, .proc/mass_remove_from_storage, T, things, progress, TRUE, M))) + while (do_after(M, 1 SECONDS, T, NONE, FALSE, CALLBACK(src, .proc/mass_remove_from_storage, T, things, progress, TRUE, M))) stoplag(1) - qdel(progress) + progress.end_progress() A.do_squish(0.8, 1.2) /datum/component/storage/concrete/bluespace/rped @@ -81,7 +81,7 @@ to_chat(M, "You start dumping out tier/cell rating [lowest_rating] parts from [parent].") var/turf/T = get_turf(A) var/datum/progressbar/progress = new(M, length(things), T) - while (do_after(M, 10, TRUE, T, FALSE, CALLBACK(src, .proc/mass_remove_from_storage, T, things, progress, TRUE, M))) + while (do_after(M, 10, T, NONE, FALSE, CALLBACK(src, .proc/mass_remove_from_storage, T, things, progress, TRUE, M))) stoplag(1) - qdel(progress) + progress.end_progress() A.do_squish(0.8, 1.2) diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index 752fafe6bd..76c5830765 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -213,9 +213,9 @@ return var/datum/progressbar/progress = new(M, len, I.loc) var/list/rejections = list() - while(do_after(M, 10, TRUE, parent, FALSE, CALLBACK(src, .proc/handle_mass_pickup, things, I.loc, rejections, progress))) + while(do_after(M, 1 SECONDS, parent, NONE, FALSE, CALLBACK(src, .proc/handle_mass_pickup, things, I.loc, rejections, progress))) stoplag(1) - qdel(progress) + progress.end_progress() to_chat(M, "You put everything you could [insert_preposition] [parent].") A.do_squish(1.4, 0.4) @@ -271,9 +271,9 @@ var/turf/T = get_turf(A) var/list/things = contents() var/datum/progressbar/progress = new(M, length(things), T) - while (do_after(M, 10, TRUE, T, FALSE, CALLBACK(src, .proc/mass_remove_from_storage, T, things, progress, TRUE, M))) + while(do_after(M, 1 SECONDS, T, NONE, FALSE, CALLBACK(src, .proc/mass_remove_from_storage, T, things, progress, TRUE, M))) stoplag(1) - qdel(progress) + progress.end_progress() A.do_squish(0.8, 1.2) /datum/component/storage/proc/mass_remove_from_storage(atom/target, list/things, datum/progressbar/progress, trigger_on_found = TRUE, mob/user) @@ -374,7 +374,8 @@ if(check_locked(null, M, TRUE)) return FALSE if(dump_destination.storage_contents_dump_act(src, M)) - playsound(A, "rustle", 50, 1, -5) + if(rustle_sound) + playsound(A, "rustle", 50, 1, -5) A.do_squish(0.8, 1.2) return TRUE return FALSE @@ -418,35 +419,39 @@ return TRUE /datum/component/storage/proc/mousedrop_onto(datum/source, atom/over_object, mob/M) + SIGNAL_HANDLER + set waitfor = FALSE . = COMPONENT_NO_MOUSEDROP + if(!ismob(M)) + return + if(!over_object) + return + if(ismecha(M.loc)) // stops inventory actions in a mech + return + if(M.incapacitated() || !M.canUseStorage()) + return var/atom/A = parent - if(ismob(M)) //all the check for item manipulation are in other places, you can safely open any storages as anything and its not buggy, i checked - A.add_fingerprint(M) - if(!over_object) - return FALSE - if(ismecha(M.loc)) // stops inventory actions in a mech - return FALSE - // this must come before the screen objects only block, dunno why it wasn't before - if(over_object == M) - user_show_to_mob(M, trigger_on_found = TRUE) - return - if(isrevenant(M)) - RevenantThrow(over_object, M, source) - return - if(!M.incapacitated()) - if(!istype(over_object, /atom/movable/screen)) - dump_content_at(over_object, M) - return - if(A.loc != M) - return - playsound(A, "rustle", 50, 1, -5) - A.do_jiggle() - if(istype(over_object, /atom/movable/screen/inventory/hand)) - var/atom/movable/screen/inventory/hand/H = over_object - M.putItemFromInventoryInHandIfPossible(A, H.held_index) - return - A.add_fingerprint(M) + // this must come before the screen objects only block, dunno why it wasn't before + if(over_object == M) + user_show_to_mob(M, trigger_on_found = TRUE) + if(isrevenant(M)) + INVOKE_ASYNC(GLOBAL_PROC, .proc/RevenantThrow, over_object, M, source) + return + if(check_locked(null, M) || !M.CanReach(A)) + return + playsound(A, "rustle", 50, TRUE, -5) + A.do_jiggle() + A.add_fingerprint(M) + if(!istype(over_object, /atom/movable/screen)) + INVOKE_ASYNC(src, .proc/dump_content_at, over_object, M) + return + if(A.loc != M) + return + if(istype(over_object, /atom/movable/screen/inventory/hand)) + var/atom/movable/screen/inventory/hand/H = over_object + M.putItemFromInventoryInHandIfPossible(A, H.held_index) + return /datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE, trigger_on_found = FALSE) var/atom/A = parent @@ -669,7 +674,7 @@ var/atom/A = parent update_actions() for(var/mob/M in range(1, A)) - if(M.active_storage == src) + if(M.active_storage == src && (M != user)) close(M) /datum/component/storage/proc/signal_take_obj(datum/source, atom/movable/AM, new_loc, force = FALSE) @@ -729,3 +734,15 @@ */ /datum/component/storage/proc/get_max_volume() return max_volume || AUTO_SCALE_STORAGE_VOLUME(max_w_class, max_combined_w_class) + +/obj/item/storage/on_object_saved(depth) + if(depth >= 10) + return "" + var/dat = "" + for(var/obj/item in contents) + var/metadata = generate_tgm_metadata(item) + dat += "[dat ? ",\n" : ""][item.type][metadata]" + //Save the contents of things inside the things inside us, EG saving the contents of bags inside lockers + var/custom_data = item.on_object_saved(depth++) + dat += "[custom_data ? ",\n[custom_data]" : ""]" + return dat diff --git a/code/datums/components/storage/ui.dm b/code/datums/components/storage/ui.dm index 820d7067d4..d41d82ae75 100644 --- a/code/datums/components/storage/ui.dm +++ b/code/datums/components/storage/ui.dm @@ -63,6 +63,8 @@ if(QDELETED(O)) continue var/atom/movable/screen/storage/item_holder/D = new(null, src, O) + // SNOWFLAKE: make O opaque too, pending storage rewrite + O.mouse_opacity = MOUSE_OPACITY_OPAQUE D.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip" D.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]" O.maptext = "" @@ -138,6 +140,8 @@ I = i var/percent = percentage_by_item[I] var/atom/movable/screen/storage/volumetric_box/center/B = new /atom/movable/screen/storage/volumetric_box/center(null, src, I) + // SNOWFLAKE: force it to icon until we unfuck storage/click passing + I.mouse_opacity = MOUSE_OPACITY_ICON var/pixels_to_use = overrun? MINIMUM_PIXELS_PER_ITEM : max(using_horizontal_pixels * percent, MINIMUM_PIXELS_PER_ITEM) var/addrow = FALSE if(CEILING(pixels_to_use, 1) >= FLOOR(horizontal_pixels - current_pixel - VOLUMETRIC_STORAGE_EDGE_PADDING, 1)) diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm index 911ca7ecbe..c336213388 100644 --- a/code/datums/components/tackle.dm +++ b/code/datums/components/tackle.dm @@ -370,7 +370,7 @@ user.emote("scream") user.gain_trauma(/datum/brain_trauma/severe/paralysis/spinesnapped) // oopsie indeed! shake_camera(user, 7, 7) - user.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/flash) + user.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/tiled/flash) user.clear_fullscreen("flash", 4.5) if(94 to 98) @@ -381,7 +381,7 @@ user.gain_trauma_type(BRAIN_TRAUMA_MILD) user.playsound_local(get_turf(user), 'sound/weapons/flashbang.ogg', 100, TRUE, 8, 0.9) shake_camera(user, 6, 6) - user.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/flash) + user.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/tiled/flash) user.clear_fullscreen("flash", 3.5) if(84 to 93) @@ -394,7 +394,7 @@ user.playsound_local(get_turf(user), 'sound/weapons/flashbang.ogg', 100, TRUE, 8, 0.9) user.DefaultCombatKnockdown(40) shake_camera(user, 5, 5) - user.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/flash) + user.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/tiled/flash) user.clear_fullscreen("flash", 2.5) if(64 to 83) diff --git a/code/datums/components/twitch_plays.dm b/code/datums/components/twitch_plays.dm index aadbd58b4b..a04592e1af 100644 --- a/code/datums/components/twitch_plays.dm +++ b/code/datums/components/twitch_plays.dm @@ -82,12 +82,14 @@ var/move_delay = 2 var/last_move = 0 -/datum/component/twitch_plays/simple_movement/auto/Initialize(...) +/datum/component/twitch_plays/simple_movement/auto/Initialize(move_delay) if(!ismovable(parent)) return COMPONENT_INCOMPATIBLE . = ..() if(. & COMPONENT_INCOMPATIBLE) return + if(!isnull(move_delay)) + src.move_delay = move_delay START_PROCESSING(SSfastprocess, src) /datum/component/twitch_plays/simple_movement/auto/Destroy(force, silent) @@ -95,10 +97,10 @@ return ..() /datum/component/twitch_plays/simple_movement/auto/process() + if(world.time < (last_move + move_delay)) + return var/dir = fetch_data(null, TRUE) if(!dir) return - if(world.time < (last_move + move_delay)) - return last_move = world.time step(parent, dir) diff --git a/code/datums/components/twohanded.dm b/code/datums/components/twohanded.dm index bcbf979101..f451241fb4 100644 --- a/code/datums/components/twohanded.dm +++ b/code/datums/components/twohanded.dm @@ -89,7 +89,7 @@ /// Triggered on equip of the item containing the component /datum/component/two_handed/proc/on_equip(datum/source, mob/user, slot) - if(require_twohands && slot == SLOT_HANDS) // force equip the item + if(require_twohands && slot == ITEM_SLOT_HANDS) // force equip the item wield(user) if(!user.is_holding(parent) && wielded && !require_twohands) unwield(user) diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm index 4a9c558d39..c0ec25dfc2 100644 --- a/code/datums/components/uplink.dm +++ b/code/datums/components/uplink.dm @@ -1,4 +1,5 @@ GLOBAL_LIST_EMPTY(uplinks) +#define PEN_ROTATIONS 2 /** * Uplinks @@ -17,7 +18,7 @@ GLOBAL_LIST_EMPTY(uplinks) var/telecrystals var/selected_cat var/owner = null - var/datum/game_mode/gamemode + var/uplink_flag var/datum/uplink_purchase_log/purchase_log var/list/uplink_items var/hidden_crystals = 0 @@ -26,11 +27,11 @@ GLOBAL_LIST_EMPTY(uplinks) var/failsafe_code var/compact_mode = FALSE var/debug = FALSE - var/saved_player_population = 0 - var/list/filters = list() + ///Instructions on how to access the uplink based on location + var/unlock_text + var/list/previous_attempts - -/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20, datum/traitor_class/traitor_class) +/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, uplink_flag = UPLINK_TRAITORS, starting_tc = TELECRYSTALS_DEFAULT) if(!isitem(parent)) return COMPONENT_INCOMPATIBLE @@ -44,16 +45,13 @@ GLOBAL_LIST_EMPTY(uplinks) RegisterSignal(parent, COMSIG_IMPLANT_EXISTING_UPLINK, .proc/new_implant) else if(istype(parent, /obj/item/pda)) RegisterSignal(parent, COMSIG_PDA_CHANGE_RINGTONE, .proc/new_ringtone) + // RegisterSignal(parent, COMSIG_PDA_CHECK_DETONATE, .proc/check_detonate) else if(istype(parent, /obj/item/radio)) RegisterSignal(parent, COMSIG_RADIO_NEW_FREQUENCY, .proc/new_frequency) else if(istype(parent, /obj/item/pen)) RegisterSignal(parent, COMSIG_PEN_ROTATED, .proc/pen_rotation) - GLOB.uplinks += src - if(istype(traitor_class)) - filters = traitor_class.uplink_filters - starting_tc = traitor_class.TC - uplink_items = get_uplink_items(gamemode, TRUE, allow_restricted, filters) + GLOB.uplinks |= src if(_owner) owner = _owner @@ -64,44 +62,58 @@ GLOBAL_LIST_EMPTY(uplinks) purchase_log = new(owner, src) lockable = _lockable active = _enabled - gamemode = _gamemode + src.uplink_flag = uplink_flag + update_items() telecrystals = starting_tc if(!lockable) active = TRUE locked = FALSE - saved_player_population = GLOB.joined_player_list.len + + previous_attempts = list() /datum/component/uplink/InheritComponent(datum/component/uplink/U) lockable |= U.lockable active |= U.active - if(!gamemode) - gamemode = U.gamemode + uplink_flag |= U.uplink_flag telecrystals += U.telecrystals if(purchase_log && U.purchase_log) purchase_log.MergeWithAndDel(U.purchase_log) /datum/component/uplink/Destroy() GLOB.uplinks -= src - gamemode = null purchase_log = null return ..() +/datum/component/uplink/proc/update_items() + var/updated_items + updated_items = get_uplink_items(uplink_flag, TRUE, allow_restricted) + update_sales(updated_items) + uplink_items = updated_items + +/datum/component/uplink/proc/update_sales(updated_items) + var/discount_categories = list("Discounted Gear", "Discounted Team Gear", "Limited Stock Team Gear") + if (uplink_items == null) + return + for (var/category in discount_categories) // Makes sure discounted items aren't renewed or replaced + if (uplink_items[category] != null && updated_items[category] != null) + updated_items[category] = uplink_items[category] + /datum/component/uplink/proc/LoadTC(mob/user, obj/item/stack/telecrystal/TC, silent = FALSE) if(!silent) - to_chat(user, "You slot [TC] into [parent] and charge its internal uplink.") + to_chat(user, span_notice("You slot [TC] into [parent] and charge its internal uplink.")) var/amt = TC.amount telecrystals += amt TC.use(amt) - -/datum/component/uplink/proc/set_gamemode(_gamemode) - gamemode = _gamemode - uplink_items = get_uplink_items(gamemode, TRUE, allow_restricted) + // log_uplink("[key_name(user)] loaded [amt] telecrystals into [parent]'s uplink") /datum/component/uplink/proc/OnAttackBy(datum/source, obj/item/I, mob/user) + SIGNAL_HANDLER + if(!active) - return //no hitting everyone/everything just to try to slot tcs in! + return //no hitting everyone/everything just to try to slot tcs in! if(istype(I, /obj/item/stack/telecrystal)) LoadTC(user, I) + // CIT SPECIFIC: STEALING from unlocked uplink. if(active) if(I.GetComponent(/datum/component/uplink)) var/datum/component/uplink/hidden_uplink = I.GetComponent(/datum/component/uplink) @@ -118,31 +130,26 @@ GLOBAL_LIST_EMPTY(uplinks) var/cost = UI.refund_amount || UI.cost if(I.type == path && UI.refundable && I.check_uplink_validity()) telecrystals += cost - purchase_log.total_spent -= cost - to_chat(user, "[I] refunded.") + // log_uplink("[key_name(user)] refunded [UI] for [cost] telecrystals using [parent]'s uplink") + if(purchase_log) + purchase_log.total_spent -= cost + to_chat(user, span_notice("[I] refunded.")) qdel(I) return /datum/component/uplink/proc/interact(datum/source, mob/user) + SIGNAL_HANDLER + if(locked) return active = TRUE + update_items() if(user) - //update the saved population - var/previous_player_population = saved_player_population - saved_player_population = GLOB.joined_player_list.len - //if population has changed, update uplink items - if(saved_player_population != previous_player_population) - //make sure discounts are not rerolled - var/old_discounts = uplink_items["Discounted Gear"] - uplink_items = get_uplink_items(gamemode, FALSE, allow_restricted, filters) - if(old_discounts) - uplink_items["Discounted Gear"] = old_discounts - ui_interact(user) - + INVOKE_ASYNC(src, .proc/ui_interact, user) // an unlocked uplink blocks also opening the PDA or headset menu return COMPONENT_NO_INTERACT + /datum/component/uplink/ui_state(mob/user) if(istype(parent, /obj/item/implant/uplink)) return GLOB.not_incapacitated_state @@ -178,15 +185,10 @@ GLOBAL_LIST_EMPTY(uplinks) var/datum/uplink_item/I = uplink_items[category][item] if(I.limited_stock == 0) continue - if(I.restricted_roles.len) - var/is_inaccessible = TRUE - for(var/R in I.restricted_roles) - if(R == user.mind.assigned_role || debug) - is_inaccessible = FALSE - if(is_inaccessible) + if(length(I.restricted_roles)) + if(!debug && !(user.mind.assigned_role in I.restricted_roles)) continue - /* - if(I.restricted_species) //catpeople specfic gloves. + if(I.restricted_species) if(ishuman(user)) var/is_inaccessible = TRUE var/mob/living/carbon/human/H = user @@ -196,7 +198,6 @@ GLOBAL_LIST_EMPTY(uplinks) break if(is_inaccessible) continue - */ cat["items"] += list(list( "name" = I.name, "cost" = I.cost, @@ -206,6 +207,9 @@ GLOBAL_LIST_EMPTY(uplinks) return data /datum/component/uplink/ui_act(action, params) + . = ..() + if(.) + return if(!active) return switch(action) @@ -252,25 +256,41 @@ GLOBAL_LIST_EMPTY(uplinks) // Implant signal responses /datum/component/uplink/proc/implant_activation() + SIGNAL_HANDLER + var/obj/item/implant/implant = parent locked = FALSE interact(null, implant.imp_in) /datum/component/uplink/proc/implanting(datum/source, list/arguments) + SIGNAL_HANDLER + var/mob/user = arguments[2] - owner = "[user.key]" + owner = user?.key + if(owner && !purchase_log) + LAZYINITLIST(GLOB.uplink_purchase_logs_by_key) + if(GLOB.uplink_purchase_logs_by_key[owner]) + purchase_log = GLOB.uplink_purchase_logs_by_key[owner] + else + purchase_log = new(owner, src) /datum/component/uplink/proc/old_implant(datum/source, list/arguments, obj/item/implant/new_implant) + SIGNAL_HANDLER + // It kinda has to be weird like this until implants are components return SEND_SIGNAL(new_implant, COMSIG_IMPLANT_EXISTING_UPLINK, src) /datum/component/uplink/proc/new_implant(datum/source, datum/component/uplink/uplink) + SIGNAL_HANDLER + uplink.telecrystals += telecrystals return COMPONENT_DELETE_NEW_IMPLANT // PDA signal responses /datum/component/uplink/proc/new_ringtone(datum/source, mob/living/user, new_ring_text) + SIGNAL_HANDLER + var/obj/item/pda/master = parent if(trim(lowertext(new_ring_text)) != trim(lowertext(unlock_code))) if(trim(lowertext(new_ring_text)) == trim(lowertext(failsafe_code))) @@ -279,14 +299,21 @@ GLOBAL_LIST_EMPTY(uplinks) return locked = FALSE interact(null, user) - to_chat(user, "The PDA softly beeps.") + to_chat(user, span_hear("The PDA softly beeps.")) user << browse(null, "window=pda") master.mode = 0 return COMPONENT_STOP_RINGTONE_CHANGE +/datum/component/uplink/proc/check_detonate() + SIGNAL_HANDLER + + // return COMPONENT_PDA_NO_DETONATE + // Radio signal responses /datum/component/uplink/proc/new_frequency(datum/source, list/arguments) + SIGNAL_HANDLER + var/obj/item/radio/master = parent var/frequency = arguments[1] if(frequency != unlock_code) @@ -300,15 +327,22 @@ GLOBAL_LIST_EMPTY(uplinks) // Pen signal responses /datum/component/uplink/proc/pen_rotation(datum/source, degrees, mob/living/carbon/user) + SIGNAL_HANDLER + var/obj/item/pen/master = parent - if(degrees != unlock_code) - if(degrees == failsafe_code) //Getting failsafes on pens is risky business - failsafe() - return - locked = FALSE - master.degrees = 0 - interact(null, user) - to_chat(user, "Your pen makes a clicking noise, before quickly rotating back to 0 degrees!") + previous_attempts += degrees + if(length(previous_attempts) > PEN_ROTATIONS) + popleft(previous_attempts) + + if(compare_list(previous_attempts, unlock_code)) + locked = FALSE + previous_attempts.Cut() + master.degrees = 0 + interact(null, user) + to_chat(user, span_warning("Your pen makes a clicking noise, before quickly rotating back to 0 degrees!")) + + else if(compare_list(previous_attempts, failsafe_code)) + failsafe(user) /datum/component/uplink/proc/setup_unlock_code() unlock_code = generate_code() @@ -318,15 +352,18 @@ GLOBAL_LIST_EMPTY(uplinks) else if(istype(parent,/obj/item/radio)) unlock_note = "Radio Frequency: [format_frequency(unlock_code)] ([P.name])." else if(istype(parent,/obj/item/pen)) - unlock_note = "Uplink Degrees: [unlock_code] ([P.name])." + unlock_note = "Uplink Degrees: [english_list(unlock_code)] ([P.name])." /datum/component/uplink/proc/generate_code() if(istype(parent,/obj/item/pda)) return "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]" else if(istype(parent,/obj/item/radio)) - return sanitize_frequency(rand(MIN_FREQ, MAX_FREQ)) + return return_unused_frequency() else if(istype(parent,/obj/item/pen)) - return rand(1, 360) + var/list/L = list() + for(var/i in 1 to PEN_ROTATIONS) + L += rand(1, 360) + return L /datum/component/uplink/proc/failsafe(mob/living/carbon/user) if(!parent) @@ -336,5 +373,5 @@ GLOBAL_LIST_EMPTY(uplinks) return message_admins("[ADMIN_LOOKUPFLW(user)] has triggered an uplink failsafe explosion at [AREACOORD(T)] The owner of the uplink was [ADMIN_LOOKUPFLW(owner)].") log_game("[key_name(user)] triggered an uplink failsafe explosion. The owner of the uplink was [key_name(owner)].") - explosion(T,1,2,3) + explosion(parent, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 3) qdel(parent) //Alternatively could brick the uplink. diff --git a/code/datums/components/virtual_reality.dm b/code/datums/components/virtual_reality.dm index 56e06e3582..c0e6e9dba6 100644 --- a/code/datums/components/virtual_reality.dm +++ b/code/datums/components/virtual_reality.dm @@ -84,9 +84,9 @@ if(VR) VR.level_below = src level_above = VR - M.transfer_ckey(vr_M, FALSE) mastermind = M.mind mastermind.current.audiovisual_redirect = parent + M.transfer_ckey(vr_M, FALSE) RegisterSignal(mastermind, COMSIG_PRE_MIND_TRANSFER, .proc/switch_player) RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING), .proc/game_over) RegisterSignal(M, COMSIG_MOB_PRE_PLAYER_CHANGE, .proc/player_hijacked) diff --git a/code/datums/components/waddling.dm b/code/datums/components/waddling.dm index f09a92c91c..7b94a14285 100644 --- a/code/datums/components/waddling.dm +++ b/code/datums/components/waddling.dm @@ -10,6 +10,7 @@ var/mob/living/L = parent if(L.incapacitated() || L.lying) return + var/matrix/otransform = matrix(L.transform) //make a copy of the current transform animate(L, pixel_z = 4, time = 0) - animate(pixel_z = 0, transform = turn(matrix(), pick(-12, 0, 12)), time=2) - animate(pixel_z = 0, transform = matrix(), time = 0) + animate(pixel_z = 0, transform = turn(L.transform, pick(-12, 0, 12)), time=2) //waddle. + animate(pixel_z = 0, transform = otransform, time = 0) //return to previous transform. diff --git a/code/datums/datum.dm b/code/datums/datum.dm index 42580425ce..2cc72f7ca9 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -57,9 +57,13 @@ */ var/list/cooldowns -#ifdef TESTING +#ifdef REFERENCE_TRACKING var/running_find_references var/last_find_references = 0 + #ifdef REFERENCE_TRACKING_DEBUG + ///Stores info about where refs are found, used for sanity checks and testing + var/list/found_refs + #endif #endif #ifdef DATUMVAR_DEBUGGING_MODE @@ -102,7 +106,7 @@ active_timers = null for(var/thing in timers) var/datum/timedevent/timer = thing - if (timer.spent) + if (timer.spent && !(timer.flags & TIMER_DELETE_ME)) continue qdel(timer) @@ -231,6 +235,7 @@ else return returned + /** * Callback called by a timer to end an associative-list-indexed cooldown. * diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm index b4e53a7425..c00a0fdb5d 100644 --- a/code/datums/diseases/_MobProcs.dm +++ b/code/datums/diseases/_MobProcs.dm @@ -75,8 +75,8 @@ if(isobj(H.wear_suit)) Cl = H.wear_suit passed = prob((Cl.permeability_coefficient*100) - 1) - if(passed && isobj(SLOT_W_UNIFORM)) - Cl = SLOT_W_UNIFORM + if(passed && isobj(ITEM_SLOT_ICLOTHING)) + Cl = ITEM_SLOT_ICLOTHING passed = prob((Cl.permeability_coefficient*100) - 1) if(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM) if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered&HANDS) @@ -145,7 +145,7 @@ return !is_mouth_covered() /mob/living/carbon/CanSpreadAirborneDisease() - return !((head && (head.flags_cover & HEADCOVERSMOUTH) && (head.armor.getRating("bio") >= 25)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && (wear_mask.armor.getRating("bio") >= 25))) + return !((head && (head.flags_cover & HEADCOVERSMOUTH) && (head.armor.getRating(BIO) >= 25)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && (wear_mask.armor.getRating(BIO) >= 25))) /mob/living/proc/set_shocked() flags_1 |= SHOCKED_1 diff --git a/code/datums/diseases/crabcancer.dm b/code/datums/diseases/crabcancer.dm new file mode 100644 index 0000000000..a762028807 --- /dev/null +++ b/code/datums/diseases/crabcancer.dm @@ -0,0 +1,67 @@ +/datum/disease/crabcancer + name = "Crab Cancer" + form = "Skin Cancer" + max_stages = 3 + cure_text = "Mutadone" + spread_text = "Noncontagious" + cures = list(/datum/reagent/medicine/mutadone) + agent = "Carcinisoprojection Jelly" + viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) + permeability_mod = 1 + desc = "If left untreated, the patient will rapidly and painfully grow flesh that will fall off the subject. This can result in death if unmaintained." + severity = DISEASE_SEVERITY_DANGEROUS + spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS + visibility_flags = HIDDEN_PANDEMIC + bypasses_immunity = TRUE + +/datum/disease/crabcancer/stage_act() + ..() + switch(stage) + if(1) + if(prob(10)) + to_chat(affected_mob, "" + pick("You feel uncomfortable.", + "You can feel your arms and legs throbbing.", + "You feel... crabby.", + "You're starting to smell like seafood.") + "") + if(2) + if(prob(10)) + to_chat(affected_mob, "" + pick("Your flesh is starting to look deformed.", + "You feel your flesh bubbling and swelling.", + "You think you see pincers coming out of your flesh.", + "It's time for crab...") + "") + if(3) + if(prob(5)) + to_chat(affected_mob, "" + pick("Your skin forms black, rough patches!", + "The pain is unbearable!", + "Your skin is forming painful cysts!") + "") + affected_mob.take_bodypart_damage(rand(1,5)) + if(prob(5)) + affected_mob.visible_message("[affected_mob]'s own flesh swells and tears away from \him!", \ + "" + pick("You feel your flesh swelling and tearing away from you!", + "Your own flesh grows and falls beneath you!", + "The pain... the crabby meat falls off you!", + "Your flesh... it tears!", + "It is now time for crab!") + "", + "You hear a disgusting squelch of flesh being torn.") + playsound(affected_mob, 'sound/items/poster_ripped.ogg', 50, TRUE) + playsound(get_turf(affected_mob), 'sound/effects/splat.ogg', 20, TRUE) + affected_mob.emote("scream") + affected_mob.take_bodypart_damage(rand(15,25)) + var/humanmeatamount = rand(0,2) + var/crabmeatamount = rand(1,2) + var/meattype = /obj/item/reagent_containers/food/snacks/meat/slab/human + if(ishuman(affected_mob)) + meattype = affected_mob.dna.species.meat + else //grab the carbon's meat instead (usually this means monkey meat... though other disease-compatible carbon mobs might apply.) + meattype = affected_mob.type_of_meat + + if(humanmeatamount) + for(var/i=1 to humanmeatamount) + var/obj/item/reagent_containers/food/snacks/meat/slab/newmeat = new meattype + newmeat.name = "[affected_mob.real_name] [newmeat.name]" + newmeat.forceMove(affected_mob.loc) + if(crabmeatamount) + for(var/i=1 to crabmeatamount) + new /obj/item/reagent_containers/food/snacks/meat/rawcrab(affected_mob.loc) + affected_mob.jitteriness += 3 + diff --git a/code/datums/diseases/dna_spread.dm b/code/datums/diseases/dna_spread.dm index 3a67230d36..07b3d5fe8a 100644 --- a/code/datums/diseases/dna_spread.dm +++ b/code/datums/diseases/dna_spread.dm @@ -30,7 +30,7 @@ return switch(stage) - if(2 || 3) //Pretend to be a cold and give time to spread. + if(2, 3) //Pretend to be a cold and give time to spread. if(prob(8)) affected_mob.emote("sneeze") if(prob(8)) diff --git a/code/datums/diseases/parrotpossession.dm b/code/datums/diseases/parrotpossession.dm index 1a3346d565..2fb3a36459 100644 --- a/code/datums/diseases/parrotpossession.dm +++ b/code/datums/diseases/parrotpossession.dm @@ -13,7 +13,7 @@ severity = DISEASE_SEVERITY_MEDIUM infectable_biotypes = MOB_ORGANIC|MOB_UNDEAD|MOB_ROBOTIC|MOB_MINERAL bypasses_immunity = TRUE //2spook - var/mob/living/simple_animal/parrot/Poly/ghost/parrot + var/mob/living/simple_animal/parrot/Polly/ghost/parrot /datum/disease/parrot_possession/stage_act() ..() diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm index 8dca59ea94..ac8e9e93c6 100644 --- a/code/datums/diseases/transformation.dm +++ b/code/datums/diseases/transformation.dm @@ -217,8 +217,8 @@ /datum/disease/transformation/slime name = "Advanced Mutation Transformation" - cure_text = "frost oil" - cures = list(/datum/reagent/consumable/frostoil) + cure_text = "Frost Oil or Mutadone." + cures = list(/datum/reagent/consumable/frostoil, /datum/reagent/medicine/mutadone) cure_chance = 80 agent = "Advanced Mutation Toxin" desc = "This highly concentrated extract converts anything into more of itself." @@ -230,19 +230,15 @@ stage4 = list("You are turning into a slime.") stage5 = list("You have become a slime.") new_form = /mob/living/simple_animal/slime/random + needs_all_cures = FALSE /datum/disease/transformation/slime/stage_act() ..() - switch(stage) - if(1) - if(ishuman(affected_mob) && affected_mob.dna) - if(affected_mob.dna.species.id == SPECIES_SLIME_LUMI || affected_mob.dna.species.id == SPECIES_STARGAZER || affected_mob.dna.species.id == SPECIES_SLIME_LUMI) - stage = 5 - if(3) - if(ishuman(affected_mob)) - var/mob/living/carbon/human/human = affected_mob - if(human.dna.species.id != SPECIES_SLIME_LUMI && affected_mob.dna.species.id != SPECIES_STARGAZER && affected_mob.dna.species.id != SPECIES_SLIME_LUMI) - human.set_species(/datum/species/jelly/slime) + if(stage == 3) + if(ishuman(affected_mob)) + var/mob/living/carbon/human/human = affected_mob + if(!isjellyperson(human)) + human.set_species(/datum/species/jelly/slime) /datum/disease/transformation/corgi name = "The Barkening" diff --git a/code/datums/diseases/wizarditis.dm b/code/datums/diseases/wizarditis.dm index e769f466b9..0440fb231d 100644 --- a/code/datums/diseases/wizarditis.dm +++ b/code/datums/diseases/wizarditis.dm @@ -61,19 +61,19 @@ STI KALY - blind if(!istype(H.head, /obj/item/clothing/head/wizard)) if(!H.dropItemToGround(H.head)) qdel(H.head) - H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(H), SLOT_HEAD) + H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(H), ITEM_SLOT_HEAD) return if(prob(chance)) if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe)) if(!H.dropItemToGround(H.wear_suit)) qdel(H.wear_suit) - H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(H), SLOT_WEAR_SUIT) + H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(H), ITEM_SLOT_OCLOTHING) return if(prob(chance)) if(!istype(H.shoes, /obj/item/clothing/shoes/sandal/magic)) if(!H.dropItemToGround(H.shoes)) qdel(H.shoes) - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(H), SLOT_SHOES) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(H), ITEM_SLOT_FEET) return else var/mob/living/carbon/H = affected_mob diff --git a/code/datums/dna.dm b/code/datums/dna.dm index a2982a3caf..7d1ddc5648 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -77,6 +77,7 @@ new_dna.species = new species.type new_dna.species.say_mod = species.say_mod new_dna.species.exotic_blood_color = species.exotic_blood_color //it can change from the default value + new_dna.species.exotic_blood_blend_mode = species.exotic_blood_blend_mode new_dna.species.eye_type = species.eye_type new_dna.species.limbs_id = species.limbs_id || species.id new_dna.real_name = real_name @@ -137,9 +138,9 @@ L[DNA_SKIN_TONE_BLOCK] = construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len) L[DNA_LEFT_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.left_eye_color) L[DNA_RIGHT_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.right_eye_color) - L[DNA_COLOR_ONE_BLOCK] = sanitize_hexcolor(features["mcolor"], 6) - L[DNA_COLOR_TWO_BLOCK] = sanitize_hexcolor(features["mcolor2"], 6) - L[DNA_COLOR_THREE_BLOCK] = sanitize_hexcolor(features["mcolor3"], 6) + L[DNA_COLOR_ONE_BLOCK] = sanitize_hexcolor(features["mcolor"]) + L[DNA_COLOR_TWO_BLOCK] = sanitize_hexcolor(features["mcolor2"]) + L[DNA_COLOR_THREE_BLOCK] = sanitize_hexcolor(features["mcolor3"]) if(!GLOB.mam_tails_list.len) init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/mam_tails, GLOB.mam_tails_list) L[DNA_MUTANTTAIL_BLOCK] = construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len) @@ -152,6 +153,10 @@ if(!GLOB.taur_list.len) init_sprite_accessory_subtypes(/datum/sprite_accessory/taur, GLOB.taur_list) L[DNA_TAUR_BLOCK] = construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len) + L[DNA_BARK_SOUND_BLOCK] = construct_block(GLOB.bark_list.Find(H.vocal_bark_id), GLOB.bark_list.len) + L[DNA_BARK_SPEED_BLOCK] = construct_block(H.vocal_speed * 4, 16) + L[DNA_BARK_PITCH_BLOCK] = construct_block(H.vocal_pitch * 30, 48) + L[DNA_BARK_VARIANCE_BLOCK] = construct_block(H.vocal_pitch_range * 48, 48) for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++) if(L[i]) @@ -247,19 +252,19 @@ if(DNA_HAIR_STYLE_BLOCK) setblock(uni_identity, blocknumber, construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len)) if(DNA_COLOR_ONE_BLOCK) - sanitize_hexcolor(features["mcolor"], 6) + setblock(uni_identity, blocknumber, sanitize_hexcolor(features["mcolor"])) if(DNA_COLOR_TWO_BLOCK) - sanitize_hexcolor(features["mcolor2"], 6) + setblock(uni_identity, blocknumber, sanitize_hexcolor(features["mcolor2"])) if(DNA_COLOR_THREE_BLOCK) - sanitize_hexcolor(features["mcolor3"], 6) + setblock(uni_identity, blocknumber, sanitize_hexcolor(features["mcolor3"])) if(DNA_MUTANTTAIL_BLOCK) - construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len) + setblock(uni_identity, blocknumber, construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len)) if(DNA_MUTANTEAR_BLOCK) - construct_block(GLOB.mam_ears_list.Find(features["mam_ears"]), GLOB.mam_ears_list.len) + setblock(uni_identity, blocknumber, construct_block(GLOB.mam_ears_list.Find(features["mam_ears"]), GLOB.mam_ears_list.len)) if(DNA_MUTANTMARKING_BLOCK) - construct_block(GLOB.mam_body_markings_list.Find(features["mam_body_markings"]), GLOB.mam_body_markings_list.len) + setblock(uni_identity, blocknumber, construct_block(GLOB.mam_body_markings_list.Find(features["mam_body_markings"]), GLOB.mam_body_markings_list.len)) if(DNA_TAUR_BLOCK) - construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len) + setblock(uni_identity, blocknumber, construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len)) if(species.mutant_bodyparts["taur"] && ishuman(holder)) var/datum/sprite_accessory/taur/T = GLOB.taur_list[features["taur"]] switch(T?.taur_mode) @@ -271,6 +276,14 @@ H.physiology.footstep_type = FOOTSTEP_MOB_CRAWL else H.physiology.footstep_type = null + if(DNA_BARK_SOUND_BLOCK) + setblock(uni_identity, blocknumber, construct_block(GLOB.bark_list.Find(H.vocal_bark_id), GLOB.bark_list.len)) + if(DNA_BARK_SPEED_BLOCK) + setblock(uni_identity, blocknumber, construct_block(H.vocal_speed * 4, 16)) + if(DNA_BARK_PITCH_BLOCK) + setblock(uni_identity, blocknumber, construct_block(H.vocal_pitch * 30, 48)) + if(DNA_BARK_VARIANCE_BLOCK) + setblock(uni_identity, blocknumber, construct_block(H.vocal_pitch_range * 48, 48)) //Please use add_mutation or activate_mutation instead /datum/dna/proc/force_give(datum/mutation/human/HM) @@ -386,6 +399,14 @@ qdel(language_holder) var/species_holder = initial(mrace.species_language_holder) language_holder = new species_holder(src) + + var/mob/living/carbon/human/H = src + //provide the user's additional language to the new language holder even if they change species + if(H.additional_language && H.additional_language != "None") + var/language_entry = GLOB.roundstart_languages[H.additional_language] + if(language_entry) + grant_language(language_entry, TRUE, TRUE) + update_atom_languages() /mob/living/carbon/human/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) @@ -482,6 +503,10 @@ update_body_parts() if(mutations_overlay_update) update_mutations_overlay() + set_bark(GLOB.bark_list[deconstruct_block(getblock(structure, DNA_BARK_SOUND_BLOCK), GLOB.bark_list.len)]) + vocal_speed = (deconstruct_block(getblock(structure, DNA_BARK_SPEED_BLOCK), 16) / 4) + vocal_pitch = (deconstruct_block(getblock(structure, DNA_BARK_PITCH_BLOCK), 48) / 30) + vocal_pitch_range = (deconstruct_block(getblock(structure, DNA_BARK_VARIANCE_BLOCK), 48) / 48) /mob/proc/domutcheck() @@ -692,22 +717,20 @@ death() petrify(INFINITY) if(3) - if(prob(90)) - var/obj/item/bodypart/BP = get_bodypart(pick(BODY_ZONE_CHEST,BODY_ZONE_HEAD)) - if(BP) - BP.dismember() - else - unequip_everything() - drop_all_held_items() - gib() + var/obj/item/bodypart/BP = get_bodypart(pick(BODY_ZONE_CHEST,BODY_ZONE_HEAD)) + if(BP) + BP.dismember() else - set_species(/datum/species/dullahan) + unequip_everything() + drop_all_held_items() + gib() /datum/dna/proc/update_body_size(old_size) if(!holder || features["body_size"] == old_size) return //new size detected holder.resize = features["body_size"] / old_size + holder.maptext_height = 32 * features["body_size"] // Adjust runechat height holder.update_transform() if(iscarbon(holder)) var/mob/living/carbon/C = holder diff --git a/code/datums/elements/art.dm b/code/datums/elements/art.dm index 960d22af56..47908a2e2d 100644 --- a/code/datums/elements/art.dm +++ b/code/datums/elements/art.dm @@ -54,11 +54,14 @@ /datum/element/art/rev -/datum/element/art/rev/apply_moodlet(atom/source, mob/M, impress) - M.visible_message("[M] stops to inspect [source].", \ - "You take in [source], inspecting the fine craftsmanship of the proletariat.") - - if(M.mind && M.mind.has_antag_datum(/datum/antagonist/rev)) - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat) +/datum/element/art/rev/apply_moodlet(atom/source, mob/user, impress) + var/msg + if(user.mind?.has_antag_datum(/datum/antagonist/rev)) + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat) + msg = "What \a [pick("masterpiece", "chef-d'oeuvre")] [source.p_theyre()]. So [pick("subversive", "revolutionary", "unitizing", "egalitarian")]!" else - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad) + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad) + msg = "Wow, [source.p_they()] sucks." + + user.visible_message(span_notice("[user] stops to inspect [source]."), \ + span_notice("You appraise [source], inspecting the fine craftsmanship of the proletariat... [msg]")) diff --git a/code/datums/elements/connect_loc.dm b/code/datums/elements/connect_loc.dm new file mode 100644 index 0000000000..fee9072f75 --- /dev/null +++ b/code/datums/elements/connect_loc.dm @@ -0,0 +1,43 @@ +/// This element hooks a signal onto the loc the current object is on. +/// When the object moves, it will unhook the signal and rehook it to the new object. +/datum/element/connect_loc + element_flags = ELEMENT_BESPOKE + id_arg_index = 2 + + /// An assoc list of signal -> procpath to register to the loc this object is on. + var/list/connections + +/datum/element/connect_loc/Attach(atom/movable/listener, list/connections) + . = ..() + if (!istype(listener)) + return ELEMENT_INCOMPATIBLE + + src.connections = connections + + RegisterSignal(listener, COMSIG_MOVABLE_MOVED, .proc/on_moved, override = TRUE) + update_signals(listener) + +/datum/element/connect_loc/Detach(atom/movable/listener) + . = ..() + unregister_signals(listener, listener.loc) + UnregisterSignal(listener, COMSIG_MOVABLE_MOVED) + +/datum/element/connect_loc/proc/update_signals(atom/movable/listener) + var/atom/listener_loc = listener.loc + if(isnull(listener_loc)) + return + + for (var/signal in connections) + //override=TRUE because more than one connect_loc element instance tracked object can be on the same loc + listener.RegisterSignal(listener_loc, signal, connections[signal], override=TRUE) + +/datum/element/connect_loc/proc/unregister_signals(datum/listener, atom/old_loc) + if(isnull(old_loc)) + return + + listener.UnregisterSignal(old_loc, connections) + +/datum/element/connect_loc/proc/on_moved(atom/movable/listener, atom/old_loc) + SIGNAL_HANDLER + unregister_signals(listener, old_loc) + update_signals(listener) diff --git a/code/datums/elements/earhealing.dm b/code/datums/elements/earhealing.dm index 1c74777845..2ceb261622 100644 --- a/code/datums/elements/earhealing.dm +++ b/code/datums/elements/earhealing.dm @@ -19,7 +19,7 @@ user_by_item -= target /datum/element/earhealing/proc/equippedChanged(datum/source, mob/living/carbon/user, slot) - if(slot == SLOT_EARS && istype(user)) + if(slot == ITEM_SLOT_EARS && istype(user)) user_by_item[source] = user else user_by_item -= source diff --git a/code/datums/elements/embed.dm b/code/datums/elements/embed.dm index 876414330f..66c11e3668 100644 --- a/code/datums/elements/embed.dm +++ b/code/datums/elements/embed.dm @@ -79,7 +79,7 @@ var/actual_chance = embed_chance if(!weapon.isEmbedHarmless()) // all the armor in the world won't save you from a kick me sign - var/armor = max(victim.run_armor_check(hit_zone, "bullet", silent=TRUE), victim.run_armor_check(hit_zone, "bomb", silent=TRUE)) * 0.5 // we'll be nice and take the better of bullet and bomb armor, halved + var/armor = max(victim.run_armor_check(hit_zone, BULLET, silent=TRUE), victim.run_armor_check(hit_zone, BOMB, silent=TRUE)) * 0.5 // we'll be nice and take the better of bullet and bomb armor, halved if(armor) // we only care about armor penetration if there's actually armor to penetrate var/pen_mod = -armor + weapon.armour_penetration // even a little bit of armor can make a big difference for shrapnel with large negative armor pen @@ -168,11 +168,13 @@ * If we hit a valid target (carbon or closed turf), we create the shrapnel_type object and immediately call tryEmbed() on it, targeting what we impacted. That will lead * it to call tryForceEmbed() on its own embed element (it's out of our hands here, our projectile is done), where it will run through all the checks it needs to. */ -/datum/element/embed/proc/checkEmbedProjectile(obj/item/projectile/P, atom/movable/firer, atom/hit, angle, hit_zone) +/datum/element/embed/proc/checkEmbedProjectile(obj/item/projectile/P, atom/movable/firer, atom/hit, angle, hit_zone, blocked) if(!iscarbon(hit)) Detach(P) return // we don't care - + if(blocked >= 100) + Detach(P) //fully blocked, no embedding for us. + return var/obj/item/payload = new payload_type(get_turf(hit)) if(istype(payload, /obj/item/shrapnel/bullet)) payload.name = P.name diff --git a/code/datums/elements/flavor_text.dm b/code/datums/elements/flavor_text.dm index 6217665157..ddd70a19c1 100644 --- a/code/datums/elements/flavor_text.dm +++ b/code/datums/elements/flavor_text.dm @@ -41,12 +41,17 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code LAZYOR(GLOB.mobs_with_editable_flavor_text[M], src) add_verb(M, /mob/proc/manage_flavor_tests) - if(save_key && ishuman(target)) + if(!save_key) + return + if(ishuman(target)) RegisterSignal(target, COMSIG_HUMAN_PREFS_COPIED_TO, .proc/update_prefs_flavor_text) + else if(iscyborg(target)) + RegisterSignal(target, COMSIG_MOB_ON_NEW_MIND, .proc/borged_update_flavor_text) + RegisterSignal(target, COMSIG_MOB_CLIENT_JOINED_FROM_LOBBY, .proc/borged_update_flavor_text) /datum/element/flavor_text/Detach(atom/A) . = ..() - UnregisterSignal(A, list(COMSIG_PARENT_EXAMINE, COMSIG_HUMAN_PREFS_COPIED_TO)) + UnregisterSignal(A, list(COMSIG_PARENT_EXAMINE, COMSIG_HUMAN_PREFS_COPIED_TO, COMSIG_MOB_ON_NEW_MIND, COMSIG_MOB_CLIENT_JOINED_FROM_LOBBY)) texts_by_atom -= A if(can_edit && ismob(A)) var/mob/M = A @@ -76,10 +81,10 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code if(examine_full_view) examine_list += "[msg]" return - if(length_char(msg) <= 40) + if(length_char(msg) <= MAX_FLAVOR_PREVIEW_LEN) examine_list += "[msg]" else - examine_list += "[copytext_char(msg, 1, 37)]... More..." + examine_list += "[copytext_char(msg, 1, (MAX_FLAVOR_PREVIEW_LEN - 3))]... More..." /datum/element/flavor_text/Topic(href, href_list) . = ..() @@ -149,6 +154,20 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code if(P.features.Find(save_key)) texts_by_atom[H] = P.features[save_key] +/datum/element/flavor_text/proc/borged_update_flavor_text(mob/new_character, client/C) + C = C || GET_CLIENT(new_character) + if(!C) + LAZYSET(texts_by_atom, new_character, "") + return + var/datum/preferences/P = C.prefs + if(!P) + LAZYSET(texts_by_atom, new_character, "") + return + if(P.custom_names["cyborg"] == new_character.real_name) + LAZYSET(texts_by_atom, new_character, P.features[save_key]) + else + LAZYSET(texts_by_atom, new_character, "") + //subtypes with additional hooks for DNA and preferences. /datum/element/flavor_text/carbon //list of antagonists etcetera that should have nothing to do with people's snowflakes. @@ -199,7 +218,7 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code if(ismob(target)) add_verb(target, /mob/proc/set_pose) -/datum/element/flavor_Text/carbon/temporary/Detach(datum/source, force) +/datum/element/flavor_text/carbon/temporary/Detach(datum/source, force) . = ..() if(ismob(source)) remove_verb(source, /mob/proc/set_pose) diff --git a/code/datums/elements/mob_holder.dm b/code/datums/elements/mob_holder.dm index 6633ee3a47..5f57b4fce3 100644 --- a/code/datums/elements/mob_holder.dm +++ b/code/datums/elements/mob_holder.dm @@ -23,18 +23,30 @@ src.proctype = proctype src.escape_on_find = escape_on_find + RegisterSignal(target, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, .proc/on_requesting_context_from_item) RegisterSignal(target, COMSIG_CLICK_ALT, .proc/mob_try_pickup) RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_examine) /datum/element/mob_holder/Detach(datum/source, force) . = ..() - UnregisterSignal(source, COMSIG_CLICK_ALT) - UnregisterSignal(source, COMSIG_PARENT_EXAMINE) + UnregisterSignal(source, list(COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, COMSIG_CLICK_ALT, COMSIG_PARENT_EXAMINE)) /datum/element/mob_holder/proc/on_examine(mob/living/source, mob/user, list/examine_list) if(ishuman(user) && !istype(source.loc, /obj/item/clothing/head/mob_holder)) examine_list += "Looks like [source.p_they(TRUE)] can be picked up with Alt+Click!" +/datum/element/mob_holder/proc/on_requesting_context_from_item( + obj/source, + list/context, + obj/item/held_item, + mob/living/user, +) + SIGNAL_HANDLER + + if(ishuman(user)) + LAZYSET(context[SCREENTIP_CONTEXT_ALT_LMB], INTENT_ANY, "Pick up") + return CONTEXTUAL_SCREENTIP_SET + /datum/element/mob_holder/proc/mob_try_pickup(mob/living/source, mob/user) if(!ishuman(user) || !user.Adjacent(source) || user.incapacitated()) return FALSE @@ -168,7 +180,7 @@ L.visible_message("[held_mob] escapes from [L]!", "[held_mob] escapes your grip!") release() -/obj/item/clothing/head/mob_holder/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE) +/obj/item/clothing/head/mob_holder/mob_can_equip(M, equipper, slot, disable_warning, bypass_equip_delay_self) if(M == held_mob || !ishuman(M)) //monkeys holding monkeys holding monkeys... return FALSE return ..() diff --git a/code/datums/elements/object_reskinning.dm b/code/datums/elements/object_reskinning.dm new file mode 100644 index 0000000000..87f5f13385 --- /dev/null +++ b/code/datums/elements/object_reskinning.dm @@ -0,0 +1,118 @@ +/* + * # Element: Object Reskinning + * + * Allows players to modify the appearance of their object (and other attributes if possible) + * PLEASE DO NOT HAVE INVALID VALUES IN unique_reskin I DON'T EVEN WANT TO KNOW WHAT HAPPENS. + * USAGE: + * unique_reskins = list( + * "skin 1" = list( + * "desc" = "very cool description", + * "icon" = 'very_cool_icon.dmi' + * ), + * "skin 2" = list( + * "desc" = "not as cool description", + * "icon" = 'the_boring_skin.dmi' + * ) + * ) +*/ +/datum/element/object_reskinning + element_flags = ELEMENT_DETACH + +/datum/element/object_reskinning/Attach(obj/target) + . = ..() + if(!istype(target)) + return ELEMENT_INCOMPATIBLE + if(!islist(target.unique_reskin) || !length(target.unique_reskin)) + message_admins("[src] was given to an object without any unique reskins, if you really need to, give it a couple skins first.") + return ELEMENT_INCOMPATIBLE + + RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_examine) + RegisterSignal(target, target.reskin_binding, .proc/reskin) + RegisterSignal(target, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, .proc/on_requesting_context_from_item) + +/datum/element/object_reskinning/Detach(obj/source, force) + UnregisterSignal(source, list(COMSIG_PARENT_EXAMINE, source.reskin_binding, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM)) + return ..() + +/datum/element/object_reskinning/proc/on_examine(obj/obj, mob/user, list/examine_list) + examine_list += span_notice("[capitalize(replacetext(obj.reskin_binding, "_", "-"))] to reskin it ([length(obj.unique_reskin)] possible styles).") + if(obj.always_reskinnable) + examine_list += span_notice("It has no limit to reskinning.") + +/* + * Reskins an object according to user's choice. + * Will detach itself if there's no skins or if done successfully but not always reskinnable. + * + * Arguments: + * * to_reskin The object we will be reskinning + * * user The user who wants to choose a skin for the object +*/ +/datum/element/object_reskinning/proc/reskin(obj/to_reskin, mob/user) + // Just stop early + if(!LAZYLEN(to_reskin.unique_reskin)) + message_admins("[ADMIN_LOOKUPFLW(user)] attempted to reskin an object that has no skins!") + Detach(to_reskin) + return FALSE + + // Can't use + if(!user.canUseTopic(to_reskin, BE_CLOSE, NO_DEXTERY, NO_TK)) + return FALSE + + // Get our choices + var/list/items = list() + for(var/reskin_option in to_reskin.unique_reskin) + var/image/item_image = image( + icon = to_reskin.unique_reskin[reskin_option]["icon"] ? to_reskin.unique_reskin[reskin_option]["icon"] : to_reskin.icon, + icon_state = to_reskin.unique_reskin[reskin_option]["icon_state"] ? to_reskin.unique_reskin[reskin_option]["icon_state"] : to_reskin.icon_state) + items += list("[reskin_option]" = item_image) + sortList(items) + + // Display to the user + var/pick = show_radial_menu(user, to_reskin, items, custom_check = CALLBACK(src, .proc/check_reskin_menu, user, to_reskin), radius = 38, require_near = TRUE) + if(!pick) + return FALSE + + // Finish the work + to_reskin.current_skin = pick + for(var/reskin_var in to_reskin.unique_reskin[pick]) + to_reskin.vars[reskin_var] = to_reskin.unique_reskin[pick][reskin_var] + to_chat(user, "[to_reskin] is now skinned as '[pick].'") + to_reskin.reskin_obj(user) + + // Only once or always? + if(!to_reskin.always_reskinnable) + Detach(to_reskin) + return TRUE + +/** + * Checks if we are allowed to interact with a radial menu for reskins + * + * Arguments: + * * user The mob interacting with the menu + * * obj The obj to be checking against + */ +/datum/element/object_reskinning/proc/check_reskin_menu(mob/user, obj/obj) + if(QDELETED(obj)) + return FALSE + if(!obj.always_reskinnable && obj.current_skin) + return FALSE + if(!istype(user)) + return FALSE + if(user.incapacitated()) + return FALSE + return TRUE + +/datum/element/object_reskinning/proc/on_requesting_context_from_item( + obj/source, + list/context, + obj/item/held_item, + mob/living/user, +) + SIGNAL_HANDLER + + switch(source.reskin_binding) + if(COMSIG_CLICK_CTRL_SHIFT) + LAZYSET(context[SCREENTIP_CONTEXT_CTRL_SHIFT_LMB], INTENT_ANY, "Reskin PDA") + else + LAZYSET(context[SCREENTIP_CONTEXT_ALT_LMB], INTENT_ANY, "Reskin [source]") + return CONTEXTUAL_SCREENTIP_SET diff --git a/code/datums/elements/polychromic.dm b/code/datums/elements/polychromic.dm index 5e888e0609..2649a8ee6f 100644 --- a/code/datums/elements/polychromic.dm +++ b/code/datums/elements/polychromic.dm @@ -144,7 +144,7 @@ return TRUE /datum/element/polychromic/proc/grant_user_action(atom/source, mob/user, slot) - if(slot == SLOT_IN_BACKPACK || slot == SLOT_LEGCUFFED || slot == SLOT_HANDCUFFED || slot == SLOT_GENERC_DEXTROUS_STORAGE) + if(slot == ITEM_SLOT_BACKPACK || slot == ITEM_SLOT_LEGCUFFED || slot == ITEM_SLOT_HANDCUFFED || slot == ITEM_SLOT_DEX_STORAGE) return var/datum/action/polychromic/P = actions_by_atom[source] if(!P) diff --git a/code/datums/elements/scavenging.dm b/code/datums/elements/scavenging.dm index 1993005be7..e6e3279a6b 100644 --- a/code/datums/elements/scavenging.dm +++ b/code/datums/elements/scavenging.dm @@ -98,7 +98,7 @@ if(len_messages >= 3) msg_blind = "[search_texts[3]]" user.visible_message("[user] [search_texts[1]] [source].", msg_first_person, msg_blind) - if(do_after(user, scavenge_time * speed_multi, TRUE, source, TRUE, CALLBACK(src, .proc/set_progress, source, world.time), resume_time = progress_done * speed_multi)) + if(do_after(user, scavenge_time * speed_multi, source, NONE, TRUE, CALLBACK(src, .proc/set_progress, source, world.time), resume_time = progress_done * speed_multi)) spawn_loot(source, user) players_busy_scavenging -= user diff --git a/code/datums/elements/screentips/README.md b/code/datums/elements/screentips/README.md new file mode 100644 index 0000000000..5b4ee4fd18 --- /dev/null +++ b/code/datums/elements/screentips/README.md @@ -0,0 +1,136 @@ +# Contextual screentips (and when to not use this folder) + +Contextual screentips provide information in the form of text at the top of your screen to inform you of the possibilities of an item. The "contextual" here refers to this being handled entirely through code, what it displays and when is completely up to you. + +## The elements (and this folder) + +This folder provides several useful shortcuts to be able to handle 95% of situations. + +### `/datum/element/contextual_screentip_bare_hands` + +This element is used to display screentips **when the user hovers over the object with nothing in their active hand.** + +It takes parameters in the form of both non-combat mode and, optionally, combat mode. + +Example: + +```dm +/obj/machinery/firealarm/Initialize(mapload) + . = ..() + + AddElement( \ + /datum/element/contextual_screentip_bare_hands, \ + lmb_text = list(INTENT_HELP = "Turn on"), \ + rmb_text = list(INTENT_HELP = "Turn off"), \ + ) +``` + +This will display "LMB: Turn on | RMB: Turn off" when the user hovers over a fire alarm with an empty active hand. + +### `/datum/element/contextual_screentip_tools` + +This element takes a map of tool behaviors to [context lists](#context-lists). These will be displayed **when the user hovers over the object with an item that has the tool behavior.** + +Example: + +```dm +/obj/structure/table/Initialize(mapload) + if (!(flags_1 & NODECONSTRUCT_1)) + var/static/list/tool_behaviors = list( + TOOL_SCREWDRIVER = list( + SCREENTIP_CONTEXT_LMB = list(INTENT_ANY = "Disassemble"), + ), + + TOOL_WRENCH = list( + SCREENTIP_CONTEXT_LMB = list(INTENT_ANY = "Deconstruct"), + ), + ) + + AddElement(/datum/element/contextual_screentip_tools, tool_behaviors) +``` + +This will display "LMB: Deconstruct" when the user hovers over a table with a wrench. + +### `/datum/element/contextual_screentip_item_typechecks` + +This element takes a map of item typepaths to [context lists](#context-lists). These will be displayed **when the user hovers over the object with the selected item.** + +Example: + +```dm +/obj/item/restraints/handcuffs/cable/Initialize(mapload) + . = ..() + + var/static/list/hovering_item_typechecks = list( + /obj/item/stack/rods = list( + SCREENTIP_CONTEXT_LMB = list(INTENT_ANY = "Craft wired rod"), + ), + + /obj/item/stack/sheet/iron = list( + SCREENTIP_CONTEXT_LMB = list(INTENT_ANY = "Craft bola"), + ), + ) + + AddElement(/datum/element/contextual_screentip_item_typechecks, hovering_item_typechecks) +``` + +This will display "LMB: Craft bola" when the user hovers over cable restraints with metal in their hand. + +## The basic system (and when to not use this folder) + +The basic system acknowledges the following two interactions: + +### Self-defining items (Type A) +These are items that are defined by their behavior. These should define their contextual text within themselves, and not in their targets. + +- Stun batons (LMB to stun, RMB to harm) +- Syringes (LMB to inject, RMB to draw) +- Health analyzers (LMB to scan for health/wounds [another piece of context], RMB to scans for chemicals) + +### Receiving action defining objects (Type B) +These are objects (not necessarily items) that are defined by what happens *to* them. These should define their contextual text within themselves, and not in their operating tools. + +- Tables (RMB with wrench to deconstruct) +- Construction objects (LMB with glass to put in screen for computers) +- Carbon copies (RMB to take a copy) + +--- + +Both of these are supported, and can be hooked to through several means. + +Note that you **must return `CONTEXTUAL_SCREENTIP_SET` if you change the contextual screentip at all**, otherwise you may not see it. + +### `COMSIG_ITEM_REQUESTING_CONTEXT_FOR_TARGET` + +This signal is registered on **items**, and receives **the hovering object**, provided in the form of `obj/item/source, list/context, atom/target, mob/living/user`. + +### `/atom/proc/register_item_context()`, and `/atom/proc/add_item_context()` +`/atom/proc/add_item_context()` is a proc intended to be overridden to easily create Type-B interactions (ones where atoms are hovered over by items). It receives the exact same arguments as `COMSIG_ITEM_REQUESTING_CONTEXT_FOR_TARGET`: `obj/item/source, list/context, atom/target, mob/living/user`. + +In order for your `add_item_context()` method to be run, you **must** call `register_item_context()`. + +### `COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM` + +This signal is registered on **atoms**, and receives **what the user is hovering with**, provided in the form of `atom/source, list/context, obj/item/held_item, mob/living/user`. + +### `/atom/proc/register_context()`, and `/atom/proc/add_context()` +`/atom/proc/add_context()` is a proc intended to be overridden to easily create Type-B interactions (ones where atoms are hovered over by items). It receives the exact same arguments as `COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM`: `atom/source, list/context, obj/item/held_item, mob/living/user`. + +In order for your `add_context()` method to be run, you **must** call `register_context()`. + +--- + +When using any of these methods, you will receive a mutable context list. + +### Context lists + +Context lists are lists with keys mapping from `SCREENTIP_CONTEXT_*` to a string. You can find these keys in `code/__DEFINES/screentips.dm`. + +The signals and `add_context()` variants mutate the list directly, while shortcut elements will just have you pass them in directly. + +For example: + +```dm +context[SCREENTIP_CONTEXT_LMB] = "Open" +context[SCREENTIP_CONTEXT_RMB] = "Destroy" +``` diff --git a/code/datums/elements/screentips/contextual_screentip_bare_hands.dm b/code/datums/elements/screentips/contextual_screentip_bare_hands.dm new file mode 100644 index 0000000000..98ef45af3f --- /dev/null +++ b/code/datums/elements/screentips/contextual_screentip_bare_hands.dm @@ -0,0 +1,92 @@ +/// Apply basic contextual screentips when the user hovers over this item with an empty hand. +/// A "Type B" interaction. +/// This stacks with other contextual screentip elements, though you may want to register the signal/flag manually at that point for performance. +/datum/element/contextual_screentip_bare_hands + element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH + id_arg_index = 3 + + /* How to use SandPoot's version of this: + * + * Combat mode will be checked first, then the intents for it, if the + * current intent has not been set it defaults to the first item of the list. + * + * Otherwise if not in combat mode or no messages for it + * will also try to get messages for the current intent + * if failing to, will try to get the first item of the list. + */ + + /// If set, the text to show for LMB + var/list/lmb_text + + /// If set, the text to show for RMB + var/list/rmb_text + + /// If set, the text to show for LMB when in combat mode. Otherwise, defaults to lmb_text. + var/list/lmb_text_combat_mode + + /// If set, the text to show for RMB when in combat mode. Otherwise, defaults to rmb_text. + var/list/rmb_text_combat_mode + +// If you're curious about `use_named_parameters`, it's because you should use named parameters! +// AddElement(/datum/element/contextual_screentip_bare_hands, lmb_text = list(INTENT_HELP = "Do the thing")) +/datum/element/contextual_screentip_bare_hands/Attach( + datum/target, + use_named_parameters, + lmb_text, + rmb_text, + lmb_text_combat_mode, + rmb_text_combat_mode, +) + . = ..() + if (!isatom(target)) + return ELEMENT_INCOMPATIBLE + + if (!isnull(use_named_parameters)) + CRASH("Use named parameters instead of positional ones.") + + src.lmb_text = lmb_text + src.rmb_text = rmb_text + src.lmb_text_combat_mode = lmb_text_combat_mode || lmb_text + src.rmb_text_combat_mode = rmb_text_combat_mode || rmb_text + + var/atom/atom_target = target + atom_target.flags_1 |= HAS_CONTEXTUAL_SCREENTIPS_1 + RegisterSignal(atom_target, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, .proc/on_requesting_context_from_item) + +/datum/element/contextual_screentip_bare_hands/Detach(datum/source, ...) + UnregisterSignal(source, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM) + + // We don't remove HAS_CONTEXTUAL_SCREENTIPS_1, since there could be other stuff still hooked to it, + // and being set without signals is not dangerous, just less performant. + // A lot of things don't do this, perhaps make a proc that checks if any signals are still set, and if not, + // remove the flag. + + return ..() + +/datum/element/contextual_screentip_bare_hands/proc/on_requesting_context_from_item( + datum/source, + list/context, + obj/item/held_item, + mob/living/user, +) + SIGNAL_HANDLER + + if (!isnull(held_item)) + return NONE + + var/combat_mode = SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE) + + // Combat lmb + if(combat_mode && length(lmb_text_combat_mode)) + context[SCREENTIP_CONTEXT_LMB] = lmb_text_combat_mode + // LMB + else if(length(lmb_text)) + context[SCREENTIP_CONTEXT_LMB] = lmb_text + // Combat rmb + if(combat_mode && length(rmb_text_combat_mode)) + context[SCREENTIP_CONTEXT_RMB] = rmb_text_combat_mode + // RMB + else if(length(rmb_text)) + context[SCREENTIP_CONTEXT_RMB] = rmb_text + + return CONTEXTUAL_SCREENTIP_SET diff --git a/code/datums/elements/screentips/contextual_screentip_item_typechecks.dm b/code/datums/elements/screentips/contextual_screentip_item_typechecks.dm new file mode 100644 index 0000000000..44ff1f3190 --- /dev/null +++ b/code/datums/elements/screentips/contextual_screentip_item_typechecks.dm @@ -0,0 +1,47 @@ +/// Apply basic contextual screentips when the user hovers over this item with a provided item. +/// A "Type B" interaction. +/// This stacks with other contextual screentip elements, though you may want to register the signal/flag manually at that point for performance. +/datum/element/contextual_screentip_item_typechecks + element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH + id_arg_index = 2 + + /// Map of item paths to contexts to usages + var/list/item_paths_to_contexts + +/datum/element/contextual_screentip_item_typechecks/Attach(datum/target, item_paths_to_contexts) + . = ..() + if (!isatom(target)) + return ELEMENT_INCOMPATIBLE + + src.item_paths_to_contexts = item_paths_to_contexts + + var/atom/atom_target = target + atom_target.flags_1 |= HAS_CONTEXTUAL_SCREENTIPS_1 + RegisterSignal(atom_target, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, .proc/on_requesting_context_from_item) + +/datum/element/contextual_screentip_item_typechecks/Detach(datum/source, ...) + UnregisterSignal(source, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM) + + // We don't remove HAS_CONTEXTUAL_SCREENTIPS_1, since there could be other stuff still hooked to it, + // and being set without signals is not dangerous, just less performant. + // A lot of things don't do this, perhaps make a proc that checks if any signals are still set, and if not, + // remove the flag. + + return ..() + +/datum/element/contextual_screentip_item_typechecks/proc/on_requesting_context_from_item( + datum/source, + list/context, + obj/item/held_item, +) + SIGNAL_HANDLER + + if (isnull(held_item)) + return NONE + + for (var/item_path in item_paths_to_contexts) + if (istype(held_item, item_path)) + context += item_paths_to_contexts[item_path] + return CONTEXTUAL_SCREENTIP_SET + + return NONE diff --git a/code/datums/elements/screentips/contextual_screentip_sharpness.dm b/code/datums/elements/screentips/contextual_screentip_sharpness.dm new file mode 100644 index 0000000000..0ee89f2fd7 --- /dev/null +++ b/code/datums/elements/screentips/contextual_screentip_sharpness.dm @@ -0,0 +1,57 @@ +/// Apply basic contextual screentips when the user hovers over this item with an item of the given tool behavior. +/// A "Type B" interaction. +/// This stacks with other contextual screentip elements, though you may want to register the signal/flag manually at that point for performance. +/datum/element/contextual_screentip_sharpness + element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH + id_arg_index = 2 + + /// If set, the text to show for LMB + var/list/lmb_text + + /// If set, the text to show for RMB + var/list/rmb_text + +/datum/element/contextual_screentip_sharpness/Attach(datum/target, lmb_text, rmb_text) + . = ..() + if (!isatom(target)) + return ELEMENT_INCOMPATIBLE + + src.lmb_text = lmb_text + src.rmb_text = rmb_text + + var/atom/atom_target = target + atom_target.flags_1 |= HAS_CONTEXTUAL_SCREENTIPS_1 + RegisterSignal(atom_target, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, .proc/on_requesting_context_from_item) + +/datum/element/contextual_screentip_sharpness/Detach(datum/source, ...) + UnregisterSignal(source, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM) + + // We don't remove HAS_CONTEXTUAL_SCREENTIPS_1, since there could be other stuff still hooked to it, + // and being set without signals is not dangerous, just less performant. + // A lot of things don't do this, perhaps make a proc that checks if any signals are still set, and if not, + // remove the flag. + + return ..() + +/datum/element/contextual_screentip_sharpness/proc/on_requesting_context_from_item( + datum/source, + list/context, + obj/item/held_item, +) + SIGNAL_HANDLER + + if (isnull(held_item)) + return NONE + + var/sharpness = held_item.get_sharpness() + if (!sharpness) + return NONE + + if (length(lmb_text)) + context[SCREENTIP_CONTEXT_LMB] = lmb_text + + if (length(rmb_text)) + context[SCREENTIP_CONTEXT_RMB] = rmb_text + + return CONTEXTUAL_SCREENTIP_SET + diff --git a/code/datums/elements/screentips/contextual_screentip_tools.dm b/code/datums/elements/screentips/contextual_screentip_tools.dm new file mode 100644 index 0000000000..a0850f8742 --- /dev/null +++ b/code/datums/elements/screentips/contextual_screentip_tools.dm @@ -0,0 +1,48 @@ +/// Apply basic contextual screentips when the user hovers over this item with an item of the given tool behavior. +/// A "Type B" interaction. +/// This stacks with other contextual screentip elements, though you may want to register the signal/flag manually at that point for performance. +/datum/element/contextual_screentip_tools + element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH + id_arg_index = 2 + + /// Map of tool behaviors to contexts to usages + var/list/tool_behaviors + +/datum/element/contextual_screentip_tools/Attach(datum/target, tool_behaviors) + . = ..() + if (!isatom(target)) + return ELEMENT_INCOMPATIBLE + + src.tool_behaviors = tool_behaviors + + var/atom/atom_target = target + atom_target.flags_1 |= HAS_CONTEXTUAL_SCREENTIPS_1 + RegisterSignal(atom_target, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, .proc/on_requesting_context_from_item) + +/datum/element/contextual_screentip_tools/Detach(datum/source, ...) + UnregisterSignal(source, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM) + + // We don't remove HAS_CONTEXTUAL_SCREENTIPS_1, since there could be other stuff still hooked to it, + // and being set without signals is not dangerous, just less performant. + // A lot of things don't do this, perhaps make a proc that checks if any signals are still set, and if not, + // remove the flag. + + return ..() + +/datum/element/contextual_screentip_tools/proc/on_requesting_context_from_item( + datum/source, + list/context, + obj/item/held_item, +) + SIGNAL_HANDLER + + if (isnull(held_item)) + return NONE + + var/tool_behavior = held_item.tool_behaviour + if (!(tool_behavior in tool_behaviors)) + return NONE + + context += tool_behaviors[tool_behavior] + + return CONTEXTUAL_SCREENTIP_SET diff --git a/code/datums/elements/spellcasting.dm b/code/datums/elements/spellcasting.dm index 877bcdbcd3..676168ea49 100644 --- a/code/datums/elements/spellcasting.dm +++ b/code/datums/elements/spellcasting.dm @@ -34,7 +34,7 @@ stacked_spellcasting_by_user -= target /datum/element/spellcasting/proc/on_equip(datum/source, mob/equipper, slot) - if(!(cast_slots & slotdefine2slotbit(slot))) + if(!(cast_slots & slot)) return users_by_item[source] = equipper if(!stacked_spellcasting_by_user[equipper]) diff --git a/code/datums/elements/strippable.dm b/code/datums/elements/strippable.dm new file mode 100644 index 0000000000..5b2480a5bc --- /dev/null +++ b/code/datums/elements/strippable.dm @@ -0,0 +1,528 @@ +/// An element for atoms that, when dragged and dropped onto a mob, opens a strip panel. +/datum/element/strippable + element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH + id_arg_index = 2 + + /// An assoc list of keys to /datum/strippable_item + var/list/items + + /// A proc path that returns TRUE/FALSE if we should show the strip panel for this entity. + /// If it does not exist, the strip menu will always show. + /// Will be called with (mob/user). + var/should_strip_proc_path + + /// An existing strip menus + var/list/strip_menus + +/datum/element/strippable/Attach(datum/target, list/items, should_strip_proc_path) + . = ..() + if (!isatom(target)) + return ELEMENT_INCOMPATIBLE + + RegisterSignal(target, COMSIG_MOUSEDROP_ONTO, .proc/mouse_drop_onto) + + src.items = items + src.should_strip_proc_path = should_strip_proc_path + +/datum/element/strippable/Detach(datum/source) + . = ..() + + UnregisterSignal(source, COMSIG_MOUSEDROP_ONTO) + + if (!isnull(strip_menus)) + qdel(strip_menus[source]) + strip_menus -= source + +/datum/element/strippable/proc/mouse_drop_onto(datum/source, atom/over, mob/user) + SIGNAL_HANDLER + + if (user == source) + return + + if (over != user) + return + + // Cyborgs buckle people by dragging them onto them, unless in combat mode. + if (iscyborg(user)) + var/mob/living/silicon/robot/cyborg_user = user + if (cyborg_user.a_intent == INTENT_HARM) + return + + if (!isnull(should_strip_proc_path) && !call(source, should_strip_proc_path)(user)) + return + + var/datum/strip_menu/strip_menu + + if (isnull(strip_menu)) + strip_menu = new(source, src) + LAZYSET(strip_menus, source, strip_menu) + + INVOKE_ASYNC(strip_menu, /datum/.proc/ui_interact, user) + +/// A representation of an item that can be stripped down +/datum/strippable_item + /// The STRIPPABLE_ITEM_* key + var/key + + /// Should we warn about dangerous clothing? + var/warn_dangerous_clothing = TRUE + +/// Gets the item from the given source. +/datum/strippable_item/proc/get_item(atom/source) + +/// Tries to equip the item onto the given source. +/// Returns TRUE/FALSE depending on if it is allowed. +/// This should be used for checking if an item CAN be equipped. +/// It should not perform the equipping itself. +/datum/strippable_item/proc/try_equip(atom/source, obj/item/equipping, mob/user) + if (HAS_TRAIT(equipping, TRAIT_NODROP)) + to_chat(user, span_warning("You can't put [equipping] on [source], it's stuck to your hand!")) + return FALSE + + return TRUE + +/// Start the equipping process. This is the proc you should yield in. +/// Returns TRUE/FALSE depending on if it is allowed. +/datum/strippable_item/proc/start_equip(atom/source, obj/item/equipping, mob/user) + if (warn_dangerous_clothing && isclothing(source)) + source.visible_message( + span_notice("[user] tries to put [equipping] on [source]."), + span_notice("[user] tries to put [equipping] on you."), + ignored_mobs = user, + ) + + if(ishuman(source)) + var/mob/living/carbon/human/victim_human = source + if(victim_human.key && !victim_human.client) // AKA braindead + if(victim_human.stat <= SOFT_CRIT && LAZYLEN(victim_human.afk_thefts) <= AFK_THEFT_MAX_MESSAGES) + var/list/new_entry = list(list(user.name, "tried equipping you with [equipping]", world.time)) + LAZYADD(victim_human.afk_thefts, new_entry) + + to_chat(user, span_notice("You try to put [equipping] on [source]...")) + + var/log = "[key_name(source)] is having [equipping] put on them by [key_name(user)]" + user.log_message(log, LOG_ATTACK, color="red") + source.log_message(log, LOG_VICTIM, color="red", log_globally=FALSE) + + return TRUE + +/// The proc that places the item on the source. This should not yield. +/datum/strippable_item/proc/finish_equip(atom/source, obj/item/equipping, mob/user) + SHOULD_NOT_SLEEP(TRUE) + return TRUE + +/// Tries to unequip the item from the given source. +/// Returns TRUE/FALSE depending on if it is allowed. +/// This should be used for checking if it CAN be unequipped. +/// It should not perform the unequipping itself. +/datum/strippable_item/proc/try_unequip(atom/source, mob/user) + SHOULD_NOT_SLEEP(TRUE) + + var/obj/item/item = get_item(source) + if (isnull(item)) + return FALSE + + if (ismob(source)) + var/mob/mob_source = source + if (!item.canStrip(user, mob_source)) + return FALSE + + return TRUE + +/// Start the unequipping process. This is the proc you should yield in. +/// Returns TRUE/FALSE depending on if it is allowed. +/datum/strippable_item/proc/start_unequip(atom/source, mob/user) + var/obj/item/item = get_item(source) + if (isnull(item)) + return FALSE + + var/strip_silence + var/obj/item/clothing/gloves/gloves = user.get_item_by_slot(ITEM_SLOT_GLOVES) + if(istype(gloves)) + strip_silence = gloves.strip_silence + + if(!strip_silence) + source.visible_message( + span_warning("[user] tries to remove [source]'s [item.name]."), + span_userdanger("[user] tries to remove your [item.name]."), + ignored_mobs = user, + ) + + to_chat(user, strip_silence ? span_danger("You try to remove [source]'s [item]...") : span_notice("You try to remove [source]'s [item]...")) + user.log_message("[key_name(source)] is being stripped of [item] by [key_name(user)]", LOG_ATTACK, color="red") + source.log_message("[key_name(source)] is being stripped of [item] by [key_name(user)]", LOG_VICTIM, color="red", log_globally=FALSE) + item.add_fingerprint(source) + + if(ishuman(source)) + var/mob/living/carbon/human/victim_human = source + if(victim_human.key && !victim_human.client) // AKA braindead + if(victim_human.stat <= SOFT_CRIT && LAZYLEN(victim_human.afk_thefts) <= AFK_THEFT_MAX_MESSAGES) + var/list/new_entry = list(list(user.name, "tried unequipping your [item.name]", world.time)) + LAZYADD(victim_human.afk_thefts, new_entry) + + return TRUE + +/// The proc that unequips the item from the source. This should not yield. +/datum/strippable_item/proc/finish_unequip(atom/source, mob/user) + +/// Returns a STRIPPABLE_OBSCURING_* define to report on whether or not this is obscured. +/datum/strippable_item/proc/get_obscuring(atom/source) + SHOULD_NOT_SLEEP(TRUE) + return STRIPPABLE_OBSCURING_NONE + +/// Returns the ID of this item's strippable action. +/// Return `null` if there is no alternate action. +/// Any return value of this must be in StripMenu. +/datum/strippable_item/proc/get_alternate_action(atom/source, mob/user) + if(get_obscuring(source) == STRIPPABLE_OBSCURING_COMPLETELY) + return FALSE + return null + +/// Performs an alternative action on this strippable_item. +/// `has_alternate_action` needs to be TRUE. +/datum/strippable_item/proc/alternate_action(atom/source, mob/user) + if(get_obscuring(source) == STRIPPABLE_OBSCURING_COMPLETELY) + return null + return TRUE + +/// Returns whether or not this item should show. +/datum/strippable_item/proc/should_show(atom/source, mob/user) + return TRUE + +/// A preset for equipping items onto mob slots +/datum/strippable_item/mob_item_slot + /// The ITEM_SLOT_* to equip to. + var/item_slot + +/datum/strippable_item/mob_item_slot/get_item(atom/source) + if (!ismob(source)) + return null + + var/mob/mob_source = source + return mob_source.get_item_by_slot(item_slot) + +/datum/strippable_item/mob_item_slot/try_equip(atom/source, obj/item/equipping, mob/user) + . = ..() + if (!.) + return + + if (!ismob(source)) + return FALSE + + if (!equipping.mob_can_equip( + source, + user, + item_slot, + disable_warning = TRUE, + bypass_equip_delay_self = TRUE, + )) + to_chat(user, span_warning("\The [equipping] doesn't fit in that place!")) + return FALSE + + return TRUE + +/datum/strippable_item/mob_item_slot/start_equip(atom/source, obj/item/equipping, mob/user) + . = ..() + if (!.) + return + + if (!ismob(source)) + return FALSE + + if (!do_mob(user, source, get_equip_delay(equipping))) + return FALSE + + if(get_obscuring(source) == STRIPPABLE_OBSCURING_COMPLETELY) + return FALSE + + if (!equipping.mob_can_equip( + source, + user, + item_slot, + disable_warning = TRUE, + bypass_equip_delay_self = TRUE, + )) + return FALSE + + if (!user.temporarilyRemoveItemFromInventory(equipping)) + return FALSE + + return TRUE + +/datum/strippable_item/mob_item_slot/finish_equip(atom/source, obj/item/equipping, mob/user) + if(!..()) + return FALSE + if (!ismob(source)) + return FALSE + + var/mob/mob_source = source + mob_source.equip_to_slot(equipping, item_slot) + +/datum/strippable_item/mob_item_slot/get_obscuring(atom/source) + if (iscarbon(source)) + var/mob/living/carbon/carbon_source = source + return (item_slot in carbon_source.check_obscured_slots()) \ + ? STRIPPABLE_OBSCURING_COMPLETELY \ + : STRIPPABLE_OBSCURING_NONE + + return FALSE + +/datum/strippable_item/mob_item_slot/start_unequip(atom/source, mob/user) + . = ..() + if (!.) + return + + return start_unequip_mob(get_item(source), source, user) + +/datum/strippable_item/mob_item_slot/finish_unequip(atom/source, mob/user) + var/obj/item/item = get_item(source) + if (isnull(item)) + return FALSE + + if (!ismob(source)) + return FALSE + + return finish_unequip_mob(item, source, user) + +/// Returns the delay of equipping this item to a mob +/datum/strippable_item/mob_item_slot/proc/get_equip_delay(obj/item/equipping) + return equipping.equip_delay_other + +/// A utility function for `/datum/strippable_item`s to start unequipping an item from a mob. +/proc/start_unequip_mob(obj/item/item, mob/source, mob/user, strip_delay) + var/strip_mod = 1 + var/obj/item/clothing/gloves/gloves = user.get_item_by_slot(ITEM_SLOT_GLOVES) + if(istype(gloves)) + strip_mod = gloves.strip_mod + + if (!do_mob(user, source, (strip_delay || item.strip_delay) / strip_mod, timed_action_flags = IGNORE_HELD_ITEM)) + return FALSE + + return TRUE + +/// A utility function for `/datum/strippable_item`s to finish unequipping an item from a mob. +/proc/finish_unequip_mob(obj/item/item, mob/source, mob/user) + if (!item.doStrip(user, source)) + return FALSE + + user.log_message("[key_name(source)] has been stripped of [item] by [key_name(user)]", LOG_ATTACK, color="red") + source.log_message("[key_name(source)] has been stripped of [item] by [key_name(user)]", LOG_VICTIM, color="red", log_globally=FALSE) + + // Updates speed in case stripped speed affecting item + source.update_equipment_speed_mods() + +/// A representation of the stripping UI +/datum/strip_menu + /// The owner who has the element /datum/element/strippable + var/atom/movable/owner + + /// The strippable element itself + var/datum/element/strippable/strippable + + /// A lazy list of user mobs to a list of strip menu keys that they're interacting with + var/list/interactions + +/datum/strip_menu/New(atom/movable/owner, datum/element/strippable/strippable) + . = ..() + src.owner = owner + src.strippable = strippable + +/datum/strip_menu/Destroy() + owner = null + strippable = null + + return ..() + +/datum/strip_menu/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if (!ui) + ui = new(user, src, "StripMenu") + ui.open() + +/datum/strip_menu/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/simple/inventory), + ) + +/datum/strip_menu/ui_data(mob/user) + var/list/data = list() + + var/list/items = list() + + for (var/strippable_key in strippable.items) + var/datum/strippable_item/item_data = strippable.items[strippable_key] + + if (!item_data.should_show(owner, user)) + continue + + var/list/result + + if(strippable_key in LAZYACCESS(interactions, user)) + LAZYSET(result, "interacting", TRUE) + + var/obscuring = item_data.get_obscuring(owner) + if (obscuring != STRIPPABLE_OBSCURING_NONE) + LAZYSET(result, "obscured", obscuring) + items[strippable_key] = result + continue + + var/obj/item/item = item_data.get_item(owner) + if (isnull(item)) + items[strippable_key] = result + continue + + LAZYINITLIST(result) + + result["icon"] = icon2base64(icon(item.icon, item.icon_state, SOUTH, 1)) + result["name"] = item.name + result["alternate"] = item_data.get_alternate_action(owner, user) + + items[strippable_key] = result + + data["items"] = items + + // While most `\the`s are implicit, this one is not. + // In this case, `\The` would otherwise be used. + // This doesn't match with what it's used for, which is to say "Stripping the alien drone", + // as opposed to "Stripping The alien drone". + // Human names will still show without "the", as they are proper nouns. + data["name"] = "\the [owner]" + + /// Customize the strip menu + data["long_strip_menu"] = user.client.prefs.long_strip_menu + + return data + +/datum/strip_menu/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if (.) + return + + . = TRUE + + var/mob/user = usr + + switch (action) + if ("use") + var/key = params["key"] + var/datum/strippable_item/strippable_item = strippable.items[key] + + if (isnull(strippable_item)) + return + + if (!strippable_item.should_show(owner, user)) + return + + if (strippable_item.get_obscuring(owner) == STRIPPABLE_OBSCURING_COMPLETELY) + return + + var/item = strippable_item.get_item(owner) + if (isnull(item)) + var/obj/item/held_item = user.get_active_held_item() + if (isnull(held_item)) + return + + if (strippable_item.try_equip(owner, held_item, user)) + LAZYORASSOCLIST(interactions, user, key) + + // Yielding call + var/should_finish = strippable_item.start_equip(owner, held_item, user) + + LAZYREMOVEASSOC(interactions, user, key) + + if (!should_finish) + return + + if (QDELETED(src) || QDELETED(owner)) + return + + // They equipped an item in the meantime + if (!isnull(strippable_item.get_item(owner))) + return + + if (!user.Adjacent(owner)) + return + + strippable_item.finish_equip(owner, held_item, user) + else if (strippable_item.try_unequip(owner, user)) + LAZYORASSOCLIST(interactions, user, key) + + var/should_unequip = strippable_item.start_unequip(owner, user) + + LAZYREMOVEASSOC(interactions, user, key) + + // Yielding call + if (!should_unequip) + return + + if (QDELETED(src) || QDELETED(owner)) + return + + // They changed the item in the meantime + if (strippable_item.get_item(owner) != item) + return + + if (!user.Adjacent(owner)) + return + + strippable_item.finish_unequip(owner, user) + if ("alt") + var/key = params["key"] + var/datum/strippable_item/strippable_item = strippable.items[key] + + if (isnull(strippable_item)) + return + + if (!strippable_item.should_show(owner, user)) + return + + if (strippable_item.get_obscuring(owner) == STRIPPABLE_OBSCURING_COMPLETELY) + return + + var/item = strippable_item.get_item(owner) + if (isnull(item)) + return + + if (isnull(strippable_item.get_alternate_action(owner, user))) + return + + LAZYORASSOCLIST(interactions, user, key) + + // Potentially yielding + strippable_item.alternate_action(owner, user) + + LAZYREMOVEASSOC(interactions, user, key) + +/datum/strip_menu/ui_host(mob/user) + return owner + +/datum/strip_menu/ui_state(mob/user) + return GLOB.always_state + +/datum/strip_menu/ui_status(mob/user, datum/ui_state/state) + . = ..() + + if(isliving(user)) + var/mob/living/living_user = user + + if ( + living_user.stat == CONSCIOUS \ + && living_user.Adjacent(owner) + ) + return UI_INTERACTIVE + if(IsAdminGhost(user)) + return UI_INTERACTIVE + if(user.Adjacent(owner)) + return UI_UPDATE + else + return UI_DISABLED + +/// Creates an assoc list of keys to /datum/strippable_item +/proc/create_strippable_list(types) + var/list/strippable_items = list() + + for (var/strippable_type in types) + var/datum/strippable_item/strippable_item = new strippable_type + strippable_items[strippable_item.key] = strippable_item + + return strippable_items diff --git a/code/datums/elements/trash.dm b/code/datums/elements/trash.dm index a83889c6ca..97864cd5f2 100644 --- a/code/datums/elements/trash.dm +++ b/code/datums/elements/trash.dm @@ -11,9 +11,9 @@ if(HAS_TRAIT(H, TRAIT_TRASHCAN)) playsound(H.loc,'sound/items/eatfood.ogg', rand(10,50), 1) if(H.vore_selected) - H.visible_message("[H] [H.vore_selected.vore_verb]s the [source] into their [H.vore_selected]", - "You [H.vore_selected.vore_verb]s the [source] into your [H.vore_selected]") + H.visible_message("[H] [H.vore_selected.vore_verb]s the [source.name] into their [H.vore_selected.name]", + "You [H.vore_selected.vore_verb] the [source.name] into your [H.vore_selected.name]") source.forceMove(H.vore_selected) else - H.visible_message("[H] consumes the [source].") + H.visible_message("[H] consumes the [source.name].") qdel(source) diff --git a/code/datums/elements/weather_listener.dm b/code/datums/elements/weather_listener.dm new file mode 100644 index 0000000000..7cea61b640 --- /dev/null +++ b/code/datums/elements/weather_listener.dm @@ -0,0 +1,44 @@ +///This element just handles creating and destroying an area sound manager that's hooked into weather stuff +/datum/element/weather_listener + element_flags = ELEMENT_BESPOKE + id_arg_index = 2 + var/weather_type + //What events to change the track on + var/list/sound_change_signals + //The weather type we're working with + var/weather_trait + //The playlist of sounds to draw from. Pass by ref + var/list/playlist + + +/datum/element/weather_listener/Attach(datum/target, w_type, trait, weather_playlist) + . = ..() + if(!weather_type) + weather_type = w_type + sound_change_signals = list( + COMSIG_WEATHER_TELEGRAPH(weather_type), + COMSIG_WEATHER_START(weather_type), + COMSIG_WEATHER_WINDDOWN(weather_type), + COMSIG_WEATHER_END(weather_type) + ) + weather_trait = trait + playlist = weather_playlist + + RegisterSignal(target, COMSIG_MOVABLE_Z_CHANGED, .proc/handle_z_level_change, override = TRUE) + RegisterSignal(target, COMSIG_MOB_CLIENT_LOGOUT, .proc/handle_logout, override = TRUE) + +/datum/element/weather_listener/Detach(datum/source) + . = ..() + UnregisterSignal(source, COMSIG_MOVABLE_Z_CHANGED, COMSIG_MOB_CLIENT_LOGOUT) + +/datum/element/weather_listener/proc/handle_z_level_change(datum/source, old_z, new_z) + SIGNAL_HANDLER + var/list/fitting_z_levels = SSmapping.levels_by_trait(weather_trait) + if(!(new_z in fitting_z_levels)) + return + var/datum/component/our_comp = source.AddComponent(/datum/component/area_sound_manager, playlist, list(), COMSIG_MOB_CLIENT_LOGOUT, fitting_z_levels) + our_comp.RegisterSignal(SSdcs, sound_change_signals, /datum/component/area_sound_manager/proc/handle_change) + +/datum/element/weather_listener/proc/handle_logout(datum/source, client/this_is_a_null_ref) + SIGNAL_HANDLER + source.RemoveElement(/datum/element/weather_listener, weather_type, weather_trait, playlist) diff --git a/code/datums/elements/wuv.dm b/code/datums/elements/wuv.dm index d4f1955afc..854bfdf8dd 100644 --- a/code/datums/elements/wuv.dm +++ b/code/datums/elements/wuv.dm @@ -52,7 +52,7 @@ new /obj/effect/temp_visual/heart(target.loc) if(pet_emote) target.emote("me", pet_type, pet_emote) - if(pet_moodlet && !CHECK_BITFIELD(target.flags_1, HOLOGRAM_1)) //prevents unlimited happiness petting park exploit. + if(pet_moodlet && !(target.flags_1 & HOLOGRAM_1)) //prevents unlimited happiness petting park exploit. SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, target, pet_moodlet, target) /datum/element/wuv/proc/kick_the_dog(mob/target, mob/user) @@ -60,5 +60,5 @@ return if(punt_emote) target.emote("me", punt_type, punt_emote) - if(punt_moodlet && !CHECK_BITFIELD(target.flags_1, HOLOGRAM_1)) + if(punt_moodlet && !(target.flags_1 & HOLOGRAM_1)) SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, target, punt_moodlet, target) diff --git a/code/datums/explosion.dm b/code/datums/explosion.dm index 8cdfaa4308..ec0d35b5a3 100644 --- a/code/datums/explosion.dm +++ b/code/datums/explosion.dm @@ -253,7 +253,7 @@ GLOBAL_LIST_EMPTY(explosions) if(dist > EXPLODE_NONE) T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it T.explosion_id = id - T.ex_act(dist) + T.ex_act(dist, origin = src) exploded_this_tick += T //--- THROW ITEMS AROUND --- diff --git a/code/datums/helper_datums/stack_end_detector.dm b/code/datums/helper_datums/stack_end_detector.dm new file mode 100644 index 0000000000..0d621f51b3 --- /dev/null +++ b/code/datums/helper_datums/stack_end_detector.dm @@ -0,0 +1,32 @@ +/** + Stack End Detector. + Can detect if a given code stack has exited, used by the mc for stack overflow detection. + + **/ +/datum/stack_end_detector + var/datum/weakref/_WF + var/datum/stack_canary/_canary + +/datum/stack_end_detector/New() + _canary = new() + _WF = WEAKREF(_canary) + +/** Prime the stack overflow detector. + Store the return value of this proc call in a proc level var. + Can only be called once. +**/ +/datum/stack_end_detector/proc/prime_canary() + if (!_canary) + CRASH("Prime_canary called twice") + . = _canary + _canary = null + +/// Returns true if the stack is still going. Calling before the canary has been primed also returns true +/datum/stack_end_detector/proc/check() + return !!_WF.resolve() + +/// Stack canary. Will go away if the stack it was primed by is ended by byond for return or stack overflow reasons. +/datum/stack_canary + +/// empty proc to avoid warnings about unused variables. Call this proc on your canary in the stack it's watching. +/datum/stack_canary/proc/use_variable() diff --git a/code/datums/http.dm b/code/datums/http.dm index 2a9b53f131..49b183fde6 100644 --- a/code/datums/http.dm +++ b/code/datums/http.dm @@ -6,10 +6,12 @@ var/body var/headers var/url + /// If present response body will be saved to this file. + var/output_file var/_raw_response -/datum/http_request/proc/prepare(method, url, body = "", list/headers) +/datum/http_request/proc/prepare(method, url, body = "", list/headers, output_file) if (!length(headers)) headers = "" else @@ -19,15 +21,16 @@ src.url = url src.body = body src.headers = headers + src.output_file = output_file /datum/http_request/proc/execute_blocking() - _raw_response = rustg_http_request_blocking(method, url, body, headers) + _raw_response = rustg_http_request_blocking(method, url, body, headers, build_options()) /datum/http_request/proc/begin_async() if (in_progress) CRASH("Attempted to re-use a request object.") - id = rustg_http_request_async(method, url, body, headers) + id = rustg_http_request_async(method, url, body, headers, build_options()) if (isnull(text2num(id))) stack_trace("Proc error: [id]") @@ -35,6 +38,11 @@ else in_progress = TRUE +/datum/http_request/proc/build_options() + if(output_file) + return json_encode(list("output_filename"=output_file,"body_filename"=null)) + return null + /datum/http_request/proc/is_complete() if (isnull(id)) return TRUE diff --git a/code/datums/looping_sounds/_looping_sound.dm b/code/datums/looping_sounds/_looping_sound.dm index 6af3b3c993..e8c6bc4d22 100644 --- a/code/datums/looping_sounds/_looping_sound.dm +++ b/code/datums/looping_sounds/_looping_sound.dm @@ -1,21 +1,21 @@ /* - output_atoms (list of atoms) The destination(s) for the sounds + output_atoms (list of atoms) The destination(s) for the sounds - mid_sounds (list or soundfile) Since this can be either a list or a single soundfile you can have random sounds. May contain further lists but must contain a soundfile at the end. - mid_length (num) The length to wait between playing mid_sounds + mid_sounds (list or soundfile) Since this can be either a list or a single soundfile you can have random sounds. May contain further lists but must contain a soundfile at the end. + mid_length (num) The length to wait between playing mid_sounds - start_sound (soundfile) Played before starting the mid_sounds loop - start_length (num) How long to wait before starting the main loop after playing start_sound + start_sound (soundfile) Played before starting the mid_sounds loop + start_length (num) How long to wait before starting the main loop after playing start_sound - end_sound (soundfile) The sound played after the main loop has concluded + end_sound (soundfile) The sound played after the main loop has concluded - chance (num) Chance per loop to play a mid_sound - volume (num) Sound output volume - max_loops (num) The max amount of loops to run for. - direct (bool) If true plays directly to provided atoms instead of from them + chance (num) Chance per loop to play a mid_sound + volume (num) Sound output volume + max_loops (num) The max amount of loops to run for. + direct (bool) If true plays directly to provided atoms instead of from them */ /datum/looping_sound - var/list/atom/output_atoms + var/atom/parent var/mid_sounds var/mid_length ///Override for volume of start sound @@ -34,38 +34,46 @@ var/falloff_exponent var/timerid var/falloff_distance + var/skip_starting_sounds = FALSE + var/loop_started = FALSE -/datum/looping_sound/New(list/_output_atoms=list(), start_immediately=FALSE, _direct=FALSE) +/datum/looping_sound/New(_parent, start_immediately=FALSE, _direct=FALSE, _skip_starting_sounds = FALSE) if(!mid_sounds) WARNING("A looping sound datum was created without sounds to play.") return - output_atoms = _output_atoms + set_parent(_parent) direct = _direct + skip_starting_sounds = _skip_starting_sounds if(start_immediately) start() /datum/looping_sound/Destroy() - stop() - output_atoms = null + stop(TRUE) return ..() -/datum/looping_sound/proc/start(atom/add_thing) - if(add_thing) - output_atoms |= add_thing +/datum/looping_sound/proc/start(on_behalf_of) + if(on_behalf_of) + set_parent(on_behalf_of) if(timerid) return on_start() -/datum/looping_sound/proc/stop(atom/remove_thing) - if(remove_thing) - output_atoms -= remove_thing +/datum/looping_sound/proc/stop(null_parent) + if(null_parent) + set_parent(null) if(!timerid) return on_stop() - deltimer(timerid) + deltimer(timerid, SSsound_loops) timerid = null + loop_started = FALSE + +/datum/looping_sound/proc/start_sound_loop() + loop_started = TRUE + sound_loop() + timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), mid_length, TIMER_CLIENT_TIME | TIMER_STOPPABLE | TIMER_LOOP | TIMER_DELETE_ME, SSsound_loops) /datum/looping_sound/proc/sound_loop(starttime) if(max_loops && world.time >= starttime + mid_length * max_loops) @@ -73,21 +81,15 @@ return if(!chance || prob(chance)) play(get_sound(starttime)) - if(!timerid) - timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), mid_length, TIMER_CLIENT_TIME | TIMER_STOPPABLE | TIMER_LOOP) /datum/looping_sound/proc/play(soundfile, volume_override) - var/list/atoms_cache = output_atoms var/sound/S = sound(soundfile) if(direct) S.channel = SSsounds.random_available_channel() S.volume = volume_override || volume //Use volume as fallback if theres no override - for(var/i in 1 to atoms_cache.len) - var/atom/thing = atoms_cache[i] - if(direct) - SEND_SOUND(thing, S) - else - playsound(thing, S, volume, vary, extra_range, falloff_exponent = falloff_exponent, falloff_distance = falloff_distance) + SEND_SOUND(parent, S) + else + playsound(parent, S, volume, vary, extra_range, falloff_exponent = falloff_exponent, falloff_distance = falloff_distance) /datum/looping_sound/proc/get_sound(starttime, _mid_sounds) . = _mid_sounds || mid_sounds @@ -96,11 +98,22 @@ /datum/looping_sound/proc/on_start() var/start_wait = 0 - if(start_sound) + if(start_sound && !skip_starting_sounds) play(start_sound, start_volume) start_wait = start_length - addtimer(CALLBACK(src, .proc/sound_loop), start_wait, TIMER_CLIENT_TIME) + timerid = addtimer(CALLBACK(src, .proc/start_sound_loop), start_wait, TIMER_CLIENT_TIME | TIMER_DELETE_ME | TIMER_STOPPABLE, SSsound_loops) /datum/looping_sound/proc/on_stop() - if(end_sound) + if(end_sound && loop_started) play(end_sound, end_volume) + +/datum/looping_sound/proc/set_parent(new_parent) + if(parent) + UnregisterSignal(parent, COMSIG_PARENT_QDELETING) + parent = new_parent + if(parent) + RegisterSignal(parent, COMSIG_PARENT_QDELETING, .proc/handle_parent_del) + +/datum/looping_sound/proc/handle_parent_del(datum/source) + SIGNAL_HANDLER + set_parent(null) diff --git a/code/datums/looping_sounds/item_sounds.dm b/code/datums/looping_sounds/item_sounds.dm index e729ed22dd..d8b72be76c 100644 --- a/code/datums/looping_sounds/item_sounds.dm +++ b/code/datums/looping_sounds/item_sounds.dm @@ -1,4 +1,4 @@ -#define RAD_GEIGER_LOW 100 // Geiger counter sound thresholds +#define RAD_GEIGER_LOW 100 // Geiger counter sound thresholds #define RAD_GEIGER_MEDIUM 500 #define RAD_GEIGER_HIGH 1000 diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm index 79810284cd..6edb0ab5ea 100644 --- a/code/datums/looping_sounds/machinery_sounds.dm +++ b/code/datums/looping_sounds/machinery_sounds.dm @@ -119,3 +119,8 @@ // volume = 70 // falloff_distance = 5 // falloff_exponent = 20 + +/datum/looping_sound/rbmk_reactor + mid_length = 16 + mid_sounds = list('sound/effects/rbmk/reactor_hum.ogg' = 10) + volume = 10 diff --git a/code/datums/mapgen/Cavegens/LavalandGenerator.dm b/code/datums/mapgen/Cavegens/LavalandGenerator.dm index b895ad4414..3ce3821708 100644 --- a/code/datums/mapgen/Cavegens/LavalandGenerator.dm +++ b/code/datums/mapgen/Cavegens/LavalandGenerator.dm @@ -7,7 +7,7 @@ /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random = 40, /obj/structure/spawner/lavaland = 2, \ /mob/living/simple_animal/hostile/asteroid/hivelord/legion/random = 30, /obj/structure/spawner/lavaland/legion = 3, \ SPAWN_MEGAFAUNA = 4, /mob/living/simple_animal/hostile/asteroid/goldgrub = 10) - flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2 , /obj/structure/flora/ash/cap_shroom = 2 , /obj/structure/flora/ash/stem_shroom = 2 , /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2) + flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2 , /obj/structure/flora/ash/cap_shroom = 2 , /obj/structure/flora/ash/stem_shroom = 2 , /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2, /obj/structure/flora/ashtree = 1) feature_spawn_list = list(/obj/structure/geyser/random = 1) initial_closed_chance = 45 diff --git a/code/datums/martial/_martial.dm b/code/datums/martial/_martial.dm index 19cfc7691d..ce94cb3008 100644 --- a/code/datums/martial/_martial.dm +++ b/code/datums/martial/_martial.dm @@ -15,6 +15,8 @@ /// Set this variable to something not null, this'll be the preferred unarmed parry in most cases if [can_martial_parry] is TRUE. YOU MUST RUN [get_block_parry_data(this)] INSTEAD OF DIRECTLY ACCESSING! var/datum/block_parry_data/block_parry_data var/pugilist = FALSE + var/datum/weakref/holder //owner of the martial art + var/display_combos = FALSE //shows combo meter if true /datum/martial_art/proc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) return FALSE @@ -25,7 +27,7 @@ /datum/martial_art/proc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) return FALSE -/datum/martial_art/proc/can_use(mob/living/carbon/human/H) +/datum/martial_art/proc/can_use(mob/living/carbon/human/owner_human) return TRUE /datum/martial_art/proc/add_to_streak(element,mob/living/carbon/human/D) @@ -34,11 +36,16 @@ streak = streak+element if(length(streak) > max_streak_length) streak = copytext(streak, 1 + length(streak[1])) + if(display_combos) + var/mob/living/holder_living = holder.resolve() + holder_living?.hud_used?.combo_display.update_icon_state(streak) return /datum/martial_art/proc/reset_streak(mob/living/carbon/human/new_target) current_target = new_target streak = "" + var/mob/living/holder_living = holder.resolve() + holder_living?.hud_used?.combo_display.update_icon_state(streak) /datum/martial_art/proc/damage_roll(mob/living/carbon/human/A, mob/living/carbon/human/D) //Here we roll for our damage to be added into the damage var in the various attack procs. This is changed depending on whether we are in combat mode, lying down, or if our target is in combat mode. @@ -47,46 +54,48 @@ damage *= 0.7 return damage -/datum/martial_art/proc/teach(mob/living/carbon/human/H, make_temporary = FALSE) - if(!istype(H) || !H.mind) +/datum/martial_art/proc/teach(mob/living/carbon/human/owner_human, make_temporary = FALSE) + if(!istype(owner_human) || !owner_human.mind) return FALSE - if(H.mind.martial_art) + if(owner_human.mind.martial_art) if(make_temporary) - if(!H.mind.martial_art.allow_temp_override) + if(!owner_human.mind.martial_art.allow_temp_override) return FALSE - store(H.mind.martial_art,H) + store(owner_human.mind.martial_art,owner_human) else - H.mind.martial_art.on_remove(H) + owner_human.mind.martial_art.on_remove(owner_human) else if(make_temporary) - base = H.mind.default_martial_art + base = owner_human.mind.default_martial_art if(help_verb) - add_verb(H, help_verb) - H.mind.martial_art = src + add_verb(owner_human, help_verb) + owner_human.mind.martial_art = src + holder = WEAKREF(owner_human) if(pugilist) - ADD_TRAIT(H, TRAIT_PUGILIST, MARTIAL_ARTIST_TRAIT) + ADD_TRAIT(owner_human, TRAIT_PUGILIST, MARTIAL_ARTIST_TRAIT) return TRUE -/datum/martial_art/proc/store(datum/martial_art/M,mob/living/carbon/human/H) - M.on_remove(H) +/datum/martial_art/proc/store(datum/martial_art/M,mob/living/carbon/human/owner_human) + M.on_remove(owner_human) if(M.base) //Checks if M is temporary, if so it will not be stored. base = M.base else //Otherwise, M is stored. base = M -/datum/martial_art/proc/remove(mob/living/carbon/human/H) - if(!istype(H) || !H.mind || H.mind.martial_art != src) +/datum/martial_art/proc/remove(mob/living/carbon/human/owner_human) + if(!istype(owner_human) || !owner_human.mind || owner_human.mind.martial_art != src) return - on_remove(H) + on_remove(owner_human) if(base) - base.teach(H) + base.teach(owner_human) else - var/datum/martial_art/X = H.mind.default_martial_art - X.teach(H) - REMOVE_TRAIT(H, TRAIT_PUGILIST, MARTIAL_ARTIST_TRAIT) + var/datum/martial_art/X = owner_human.mind.default_martial_art + X.teach(owner_human) + REMOVE_TRAIT(owner_human, TRAIT_PUGILIST, MARTIAL_ARTIST_TRAIT) + holder = null -/datum/martial_art/proc/on_remove(mob/living/carbon/human/H) +/datum/martial_art/proc/on_remove(mob/living/carbon/human/owner_human) if(help_verb) - remove_verb(H, help_verb) + remove_verb(owner_human, help_verb) return ///Gets called when a projectile hits the owner. Returning anything other than BULLET_ACT_HIT will stop the projectile from hitting the mob. diff --git a/code/datums/martial/boxing.dm b/code/datums/martial/boxing.dm index 4682595aec..32b916d724 100644 --- a/code/datums/martial/boxing.dm +++ b/code/datums/martial/boxing.dm @@ -26,7 +26,7 @@ return TRUE var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) - var/armor_block = D.run_armor_check(affecting, "melee") + var/armor_block = D.run_armor_check(affecting, MELEE) playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1) @@ -59,7 +59,7 @@ /obj/item/clothing/gloves/boxing/equipped(mob/user, slot) . = ..() - if(ishuman(user) && slot == SLOT_GLOVES) + if(ishuman(user) && slot == ITEM_SLOT_GLOVES) var/mob/living/carbon/human/H = user style.teach(H,TRUE) @@ -68,5 +68,5 @@ if(!ishuman(user)) return var/mob/living/carbon/human/H = user - if(H.get_item_by_slot(SLOT_GLOVES) == src) + if(H.get_item_by_slot(ITEM_SLOT_GLOVES) == src) style.remove(H) diff --git a/code/datums/martial/cqc.dm b/code/datums/martial/cqc.dm index 1d6682e3a6..afc1a26659 100644 --- a/code/datums/martial/cqc.dm +++ b/code/datums/martial/cqc.dm @@ -11,6 +11,7 @@ block_chance = 75 pugilist = TRUE var/old_grab_state = null + display_combos = TRUE /datum/martial_art/cqc/reset_streak(mob/living/carbon/human/new_target) . = ..() diff --git a/code/datums/martial/krav_maga.dm b/code/datums/martial/krav_maga.dm index 3691b2fccc..d91e802a8a 100644 --- a/code/datums/martial/krav_maga.dm +++ b/code/datums/martial/krav_maga.dm @@ -98,7 +98,7 @@ /datum/martial_art/krav_maga/proc/leg_sweep(mob/living/carbon/human/A, mob/living/carbon/human/D) var/obj/item/bodypart/affecting = D.get_bodypart(BODY_ZONE_CHEST) - var/armor_block = D.run_armor_check(affecting, "melee") + var/armor_block = D.run_armor_check(affecting, MELEE) var/damage = (damage_roll(A,D)*2 + 25) if(!CHECK_MOBILITY(D, MOBILITY_STAND)) return FALSE @@ -140,7 +140,7 @@ /datum/martial_art/krav_maga/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) - var/armor_block = D.run_armor_check(affecting, "melee") + var/armor_block = D.run_armor_check(affecting, MELEE) if(check_streak(A,D)) return TRUE log_combat(A, D, "punched") @@ -165,7 +165,7 @@ if(check_streak(A,D)) return TRUE var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) - var/armor_block = D.run_armor_check(affecting, "melee") + var/armor_block = D.run_armor_check(affecting, MELEE) var/damage = damage_roll(A,D) var/stunthreshold = A.dna.species.punchstunthreshold if(CHECK_MOBILITY(D, MOBILITY_STAND)) @@ -197,7 +197,7 @@ /obj/item/clothing/gloves/krav_maga/equipped(mob/user, slot) . = ..() - if(ishuman(user) && slot == SLOT_GLOVES) + if(ishuman(user) && slot == ITEM_SLOT_GLOVES) var/mob/living/carbon/human/H = user style.teach(H,1) @@ -206,7 +206,7 @@ if(!ishuman(user)) return var/mob/living/carbon/human/H = user - if(H.get_item_by_slot(SLOT_GLOVES) == src) + if(H.get_item_by_slot(ITEM_SLOT_GLOVES) == src) style.remove(H) /obj/item/clothing/gloves/krav_maga/sec//more obviously named, given to sec @@ -233,4 +233,4 @@ heat_protection = HANDS max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT resistance_flags = NONE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 50) diff --git a/code/datums/martial/plasma_fist.dm b/code/datums/martial/plasma_fist.dm index 16ffb381aa..59de1f6ec1 100644 --- a/code/datums/martial/plasma_fist.dm +++ b/code/datums/martial/plasma_fist.dm @@ -7,6 +7,7 @@ id = MARTIALART_PLASMAFIST help_verb = /mob/living/carbon/human/proc/plasma_fist_help pugilist = TRUE + display_combos = TRUE /datum/martial_art/plasma_fist/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D) diff --git a/code/datums/martial/rising_bass.dm b/code/datums/martial/rising_bass.dm index 0d77644c86..87c0d42a29 100644 --- a/code/datums/martial/rising_bass.dm +++ b/code/datums/martial/rising_bass.dm @@ -13,6 +13,7 @@ var/datum/action/risingbassmove/sidekick = new/datum/action/risingbassmove/sidekick() var/datum/action/risingbassmove/deftswitch = new/datum/action/risingbassmove/deftswitch() var/repulsecool = 0 + display_combos = TRUE /datum/martial_art/the_rising_bass/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D) if(findtext(streak,SIDE_KICK_COMBO)) diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm index a55e947709..d0cdee4937 100644 --- a/code/datums/martial/sleeping_carp.dm +++ b/code/datums/martial/sleeping_carp.dm @@ -9,6 +9,7 @@ help_verb = /mob/living/carbon/human/proc/sleeping_carp_help block_parry_data = /datum/block_parry_data/sleeping_carp pugilist = TRUE + display_combos = TRUE /datum/martial_art/the_sleeping_carp/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D) if(findtext(streak,STRONG_PUNCH_COMBO)) @@ -223,7 +224,7 @@ block_chance = 50 var/wielded = FALSE // track wielded status on item -/obj/item/staff/bostaff/Initialize() +/obj/item/staff/bostaff/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield) RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield) diff --git a/code/datums/martial/wrestling.dm b/code/datums/martial/wrestling.dm index 8dc1afba81..466bf5c778 100644 --- a/code/datums/martial/wrestling.dm +++ b/code/datums/martial/wrestling.dm @@ -485,7 +485,7 @@ /obj/item/storage/belt/champion/wrestling/equipped(mob/user, slot) . = ..() - if(ishuman(user) && slot == SLOT_BELT) + if(ishuman(user) && slot == ITEM_SLOT_BELT) var/mob/living/carbon/human/H = user style.teach(H,1) @@ -494,7 +494,7 @@ if(!ishuman(user)) return var/mob/living/carbon/human/H = user - if(H.get_item_by_slot(SLOT_BELT) == src) + if(H.get_item_by_slot(ITEM_SLOT_BELT) == src) style.remove(H) //Subtype of wrestling, reserved for the wrestling belts found in the holodeck diff --git a/code/datums/materials/_material.dm b/code/datums/materials/_material.dm index 658f22a107..c57b3bad8e 100644 --- a/code/datums/materials/_material.dm +++ b/code/datums/materials/_material.dm @@ -30,7 +30,7 @@ Simple datum which is instanced once per type and is used for every object of sa ///This is the amount of value per 1 unit of the material var/value_per_unit = 0 ///Armor modifiers, multiplies an items normal armor vars by these amounts. - var/armor_modifiers = list("melee" = 1, "bullet" = 1, "laser" = 1, "energy" = 1, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 1, "acid" = 1) + var/armor_modifiers = list(MELEE = 1, BULLET = 1, LASER = 1, ENERGY = 1, BOMB = 1, BIO = 1, RAD = 1, FIRE = 1, ACID = 1) ///How beautiful is this material per unit. var/beauty_modifier = 0 ///Can be used to override the sound items make, lets add some SLOSHing. @@ -120,7 +120,7 @@ Simple datum which is instanced once per type and is used for every object of sa return I.hitsound = item_sound_override I.usesound = item_sound_override - I.throwhitsound = item_sound_override + I.mob_throw_hit_sound = item_sound_override // I.mob_throw_hit_sound = item_sound_override // I.equip_sound = item_sound_override // I.pickup_sound = item_sound_override diff --git a/code/datums/materials/basemats.dm b/code/datums/materials/basemats.dm index a6496622ff..e423ccd1d6 100644 --- a/code/datums/materials/basemats.dm +++ b/code/datums/materials/basemats.dm @@ -18,7 +18,7 @@ sheet_type = /obj/item/stack/sheet/glass value_per_unit = 0.0025 beauty_modifier = 0.05 - armor_modifiers = list("melee" = 0.2, "bullet" = 0.2, "laser" = 0, "energy" = 1, "bomb" = 0, "bio" = 0.2, "rad" = 0.2, "fire" = 1, "acid" = 0.2) // yeah ok + armor_modifiers = list(MELEE = 0.2, BULLET = 0.2, LASER = 0, ENERGY = 1, BOMB = 0, BIO = 0.2, RAD = 0.2, FIRE = 1, ACID = 0.2) // yeah ok /* Color matrices are like regular colors but unlike with normal colors, you can go over 255 on a channel. @@ -45,7 +45,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/gold value_per_unit = 0.0625 beauty_modifier = 0.15 - armor_modifiers = list("melee" = 1.1, "bullet" = 1.1, "laser" = 1.15, "energy" = 1.15, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 0.7, "acid" = 1.1) + armor_modifiers = list(MELEE = 1.1, BULLET = 1.1, LASER = 1.15, ENERGY = 1.15, BOMB = 1, BIO = 1, RAD = 1, FIRE = 0.7, ACID = 1.1) ///Small force increase, for diamond swords /datum/material/diamond @@ -58,7 +58,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/diamond value_per_unit = 0.25 beauty_modifier = 0.3 - armor_modifiers = list("melee" = 1.3, "bullet" = 1.3, "laser" = 0.6, "energy" = 1, "bomb" = 1.2, "bio" = 1, "rad" = 1, "fire" = 1, "acid" = 1) + armor_modifiers = list(MELEE = 1.3, BULLET = 1.3, LASER = 0.6, ENERGY = 1, BOMB = 1.2, BIO = 1, RAD = 1, FIRE = 1, ACID = 1) ///Is slightly radioactive /datum/material/uranium @@ -69,7 +69,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/uranium value_per_unit = 0.05 beauty_modifier = 0.3 //It shines so beautiful - armor_modifiers = list("melee" = 1.5, "bullet" = 1.4, "laser" = 0.5, "energy" = 0.5, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 1, "acid" = 1) + armor_modifiers = list(MELEE = 1.5, BULLET = 1.4, LASER = 0.5, ENERGY = 0.5, BOMB = 0, BIO = 0, RAD = 0, FIRE = 1, ACID = 1) /datum/material/uranium/on_applied(atom/source, amount, material_flags) . = ..() @@ -90,7 +90,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/plasma value_per_unit = 0.1 beauty_modifier = 0.15 - armor_modifiers = list("melee" = 1.4, "bullet" = 0.7, "laser" = 0, "energy" = 1.2, "bomb" = 0, "bio" = 1.2, "rad" = 1, "fire" = 0, "acid" = 0.5) + armor_modifiers = list(MELEE = 1.4, BULLET = 0.7, LASER = 0, ENERGY = 1.2, BOMB = 0, BIO = 1.2, RAD = 1, FIRE = 0, ACID = 0.5) /datum/material/plasma/on_applied(atom/source, amount, material_flags) . = ..() @@ -124,7 +124,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/bananium value_per_unit = 0.5 beauty_modifier = 0.5 - armor_modifiers = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 10, "acid" = 0) //Clowns cant be blown away + armor_modifiers = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 100, BIO = 0, RAD = 0, FIRE = 10, ACID = 0) //Clowns cant be blown away /datum/material/bananium/on_applied(atom/source, amount, material_flags) . = ..() @@ -147,7 +147,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/titanium value_per_unit = 0.0625 beauty_modifier = 0.05 - armor_modifiers = list("melee" = 1.35, "bullet" = 1.3, "laser" = 1.3, "energy" = 1.25, "bomb" = 1.25, "bio" = 1, "rad" = 1, "fire" = 0.7, "acid" = 1) + armor_modifiers = list(MELEE = 1.35, BULLET = 1.3, LASER = 1.3, ENERGY = 1.25, BOMB = 1.25, BIO = 1, RAD = 1, FIRE = 0.7, ACID = 1) /datum/material/runite name = "runite" @@ -157,7 +157,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/mineral/runite beauty_modifier = 0.5 - armor_modifiers = list("melee" = 1.35, "bullet" = 2, "laser" = 0.5, "energy" = 1.25, "bomb" = 1.25, "bio" = 1, "rad" = 1, "fire" = 1.4, "acid" = 1) //rune is weak against magic lasers but strong against bullets. This is the combat triangle. + armor_modifiers = list(MELEE = 1.35, BULLET = 2, LASER = 0.5, ENERGY = 1.25, BOMB = 1.25, BIO = 1, RAD = 1, FIRE = 1.4, ACID = 1) //rune is weak against magic lasers but strong against bullets. This is the combat triangle. ///Force decrease /datum/material/plastic @@ -168,7 +168,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/plastic value_per_unit = 0.0125 beauty_modifier = -0.01 - armor_modifiers = list("melee" = 1.5, "bullet" = 1.1, "laser" = 0.3, "energy" = 0.5, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 1.1, "acid" = 1) + armor_modifiers = list(MELEE = 1.5, BULLET = 1.1, LASER = 0.3, ENERGY = 0.5, BOMB = 1, BIO = 1, RAD = 1, FIRE = 1.1, ACID = 1) ///Force decrease and mushy sound effect. (Not yet implemented) /datum/material/biomass @@ -187,7 +187,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) value_per_unit = 0.06 beauty_modifier = 0.1 - armor_modifiers = list("melee" = 1.1, "bullet" = 1.1, "laser" = 0.4, "energy" = 0.4, "bomb" = 1, "bio" = 0.2, "rad" = 0, "fire" = 0, "acid" = 0.3) + armor_modifiers = list(MELEE = 1.1, BULLET = 1.1, LASER = 0.4, ENERGY = 0.4, BOMB = 1, BIO = 0.2, RAD = 0, FIRE = 0, ACID = 0.3) /datum/material/wood/on_applied_obj(obj/source, amount, material_flags) . = ..() @@ -211,7 +211,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/adamantine value_per_unit = 0.25 beauty_modifier = 0.4 - armor_modifiers = list("melee" = 1.5, "bullet" = 1.5, "laser" = 1.3, "energy" = 1.3, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 2.5, "acid" = 1) + armor_modifiers = list(MELEE = 1.5, BULLET = 1.5, LASER = 1.3, ENERGY = 1.3, BOMB = 1, BIO = 1, RAD = 1, FIRE = 2.5, ACID = 1) ///RPG Magic. (Admin only) /datum/material/mythril @@ -222,7 +222,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/mythril value_per_unit = 0.75 beauty_modifier = 0.5 - armor_modifiers = list("melee" = 2, "bullet" = 2, "laser" = 2, "energy" = 2, "bomb" = 2, "bio" = 2, "rad" = 2, "fire" = 2, "acid" = 2) + armor_modifiers = list(MELEE = 2, BULLET = 2, LASER = 2, ENERGY = 2, BOMB = 2, BIO = 2, RAD = 2, FIRE = 2, ACID = 2) /datum/material/mythril/on_applied_obj(atom/source, amount, material_flags) . = ..() @@ -244,7 +244,7 @@ Unless you know what you're doing, only use the first three numbers. They're in value_per_unit = 0.001 strength_modifier = 0.5 integrity_modifier = 0.1 - armor_modifiers = list("melee" = 0.25, "bullet" = 0.25, "laser" = 1.25, "energy" = 0.25, "bomb" = 0.25, "bio" = 0.25, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5) + armor_modifiers = list(MELEE = 0.25, BULLET = 0.25, LASER = 1.25, ENERGY = 0.25, BOMB = 0.25, BIO = 0.25, RAD = 1.5, FIRE = 1.5, ACID = 1.5) beauty_modifier = 0.25 turf_sound_override = FOOTSTEP_SAND texture_layer_icon_state = "sand" @@ -257,7 +257,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/mineral/sandstone value_per_unit = 0.0025 - armor_modifiers = list("melee" = 0.5, "bullet" = 0.5, "laser" = 1.25, "energy" = 0.5, "bomb" = 0.5, "bio" = 0.25, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5) + armor_modifiers = list(MELEE = 0.5, BULLET = 0.5, LASER = 1.25, ENERGY = 0.5, BOMB = 0.5, BIO = 0.25, RAD = 1.5, FIRE = 1.5, ACID = 1.5) beauty_modifier = 0.3 turf_sound_override = FOOTSTEP_WOOD texture_layer_icon_state = "brick" @@ -269,7 +269,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/mineral/snow value_per_unit = 0.0025 - armor_modifiers = list("melee" = 0.25, "bullet" = 0.25, "laser" = 0.25, "energy" = 0.25, "bomb" = 0.25, "bio" = 0.25, "rad" = 1.5, "fire" = 0.25, "acid" = 1.5) + armor_modifiers = list(MELEE = 0.25, BULLET = 0.25, LASER = 0.25, ENERGY = 0.25, BOMB = 0.25, BIO = 0.25, RAD = 1.5, FIRE = 0.25, ACID = 1.5) beauty_modifier = 0.3 turf_sound_override = FOOTSTEP_SAND texture_layer_icon_state = "sand" @@ -282,7 +282,7 @@ Unless you know what you're doing, only use the first three numbers. They're in strength_modifier = 1.2 sheet_type = /obj/item/stack/sheet/runed_metal value_per_unit = 0.75 - armor_modifiers = list("melee" = 1.2, "bullet" = 1.2, "laser" = 1, "energy" = 1, "bomb" = 1.2, "bio" = 1.2, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5) + armor_modifiers = list(MELEE = 1.2, BULLET = 1.2, LASER = 1, ENERGY = 1, BOMB = 1.2, BIO = 1.2, RAD = 1.5, FIRE = 1.5, ACID = 1.5) beauty_modifier = -0.15 texture_layer_icon_state = "runed" @@ -294,7 +294,7 @@ Unless you know what you're doing, only use the first three numbers. They're in strength_modifier = 1.3 // Replicant Alloy is very good for skull beatings.. sheet_type = /obj/item/stack/tile/brass value_per_unit = 0.75 - armor_modifiers = list("melee" = 1.4, "bullet" = 1.4, "laser" = 0, "energy" = 0, "bomb" = 1.4, "bio" = 1.2, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5) //But it has.. a few problems that can't easily be compensated for. + armor_modifiers = list(MELEE = 1.4, BULLET = 1.4, LASER = 0, ENERGY = 0, BOMB = 1.4, BIO = 1.2, RAD = 1.5, FIRE = 1.5, ACID = 1.5) //But it has.. a few problems that can't easily be compensated for. beauty_modifier = 0.3 //It really beats the cold plain plating of the station, doesn't it? /datum/material/bronze @@ -305,7 +305,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/bronze value_per_unit = 0.025 - armor_modifiers = list("melee" = 1, "bullet" = 1, "laser" = 1, "energy" = 1, "bomb" = 1, "bio" = 1, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5) + armor_modifiers = list(MELEE = 1, BULLET = 1, LASER = 1, ENERGY = 1, BOMB = 1, BIO = 1, RAD = 1.5, FIRE = 1.5, ACID = 1.5) beauty_modifier = 0.2 /datum/material/paper @@ -315,7 +315,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/paperframes value_per_unit = 0.0025 - armor_modifiers = list("melee" = 0.1, "bullet" = 0.1, "laser" = 0.1, "energy" = 0.1, "bomb" = 0.1, "bio" = 0.1, "rad" = 1.5, "fire" = 0, "acid" = 1.5) + armor_modifiers = list(MELEE = 0.1, BULLET = 0.1, LASER = 0.1, ENERGY = 0.1, BOMB = 0.1, BIO = 0.1, RAD = 1.5, FIRE = 0, ACID = 1.5) beauty_modifier = 0.3 turf_sound_override = FOOTSTEP_SAND texture_layer_icon_state = "paper" @@ -340,7 +340,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/cardboard value_per_unit = 0.003 - armor_modifiers = list("melee" = 0.25, "bullet" = 0.25, "laser" = 0.25, "energy" = 0.25, "bomb" = 0.25, "bio" = 0.25, "rad" = 1.5, "fire" = 0, "acid" = 1.5) + armor_modifiers = list(MELEE = 0.25, BULLET = 0.25, LASER = 0.25, ENERGY = 0.25, BOMB = 0.25, BIO = 0.25, RAD = 1.5, FIRE = 0, ACID = 1.5) beauty_modifier = -0.1 /datum/material/cardboard/on_applied_obj(obj/source, amount, material_flags) @@ -362,8 +362,9 @@ Unless you know what you're doing, only use the first three numbers. They're in color = "#e3dac9" categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/bone + strength_modifier = 1.05 value_per_unit = 0.05 - armor_modifiers = list("melee" = 1.2, "bullet" = 0.75, "laser" = 0.75, "energy" = 1.2, "bomb" = 1, "bio" = 1, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5) + armor_modifiers = list(MELEE = 1.2, BULLET = 0.75, LASER = 0.75, ENERGY = 1.2, BOMB = 1, BIO = 1, RAD = 1.5, FIRE = 1.5, ACID = 1.5) beauty_modifier = -0.2 /datum/material/bamboo @@ -373,7 +374,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/mineral/bamboo value_per_unit = 0.0025 - armor_modifiers = list("melee" = 0.5, "bullet" = 0.5, "laser" = 0.5, "energy" = 0.5, "bomb" = 0.5, "bio" = 0.51, "rad" = 1.5, "fire" = 0.5, "acid" = 1.5) + armor_modifiers = list(MELEE = 0.5, BULLET = 0.5, LASER = 0.5, ENERGY = 0.5, BOMB = 0.5, BIO = 0.51, RAD = 1.5, FIRE = 0.5, ACID = 1.5) beauty_modifier = 0.2 turf_sound_override = FOOTSTEP_WOOD texture_layer_icon_state = "bamboo" diff --git a/code/datums/materials/meat.dm b/code/datums/materials/meat.dm index 14a373f2d2..c902aa078e 100644 --- a/code/datums/materials/meat.dm +++ b/code/datums/materials/meat.dm @@ -8,7 +8,7 @@ value_per_unit = 0.05 beauty_modifier = -0.3 strength_modifier = 0.7 - armor_modifiers = list("melee" = 0.3, "bullet" = 0.3, "laser" = 1.2, "energy" = 1.2, "bomb" = 0.3, "bio" = 0, "rad" = 0.7, "fire" = 1, "acid" = 1) + armor_modifiers = list(MELEE = 0.3, BULLET = 0.3, LASER = 1.2, ENERGY = 1.2, BOMB = 0.3, BIO = 0, RAD = 0.7, FIRE = 1, ACID = 1) item_sound_override = 'sound/effects/meatslap.ogg' turf_sound_override = FOOTSTEP_MEAT texture_layer_icon_state = "meat" diff --git a/code/datums/materials/pizza.dm b/code/datums/materials/pizza.dm index 2a9542234f..013538614f 100644 --- a/code/datums/materials/pizza.dm +++ b/code/datums/materials/pizza.dm @@ -7,7 +7,7 @@ value_per_unit = 0.05 beauty_modifier = 0.1 strength_modifier = 0.7 - armor_modifiers = list("melee" = 0.3, "bullet" = 0.3, "laser" = 1.2, "energy" = 1.2, "bomb" = 0.3, "bio" = 0, "rad" = 0.7, "fire" = 1, "acid" = 1) + armor_modifiers = list(MELEE = 0.3, BULLET = 0.3, LASER = 1.2, ENERGY = 1.2, BOMB = 0.3, BIO = 0, RAD = 0.7, FIRE = 1, ACID = 1) item_sound_override = 'sound/effects/meatslap.ogg' turf_sound_override = FOOTSTEP_MEAT texture_layer_icon_state = "pizza" diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 897e2e7d71..9f6ccb742d 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -29,6 +29,12 @@ */ +//ambition start +#define AMBITION_COOLDOWN_TIME (5 SECONDS) +#define OBJECTIVES_COOLDOWN_TIME (2 SECONDS) +#define ADMIN_PING_COOLDOWN_TIME (10 MINUTES) +//ambition end + /datum/mind var/key var/name //replaces mob/var/original_name @@ -68,9 +74,16 @@ /// Our skill holder. var/datum/skill_holder/skill_holder +//ambition start + /// Lazy list for antagonists to set goals they wish to achieve, to be shown at the round-end report. + var/list/ambitions +//ambition end + ///What character we spawned in as- either at roundstart or latejoin, so we know for persistent scars if we ended as the same person or not var/mob/original_character + /// A lazy list of statuses to add next to this mind in the traitor panel + var/list/special_statuses /datum/mind/New(var/key) skill_holder = new(src) @@ -139,7 +152,7 @@ if(isliving(new_character)) //New humans and such are by default enabled arousal. Let's always use the new mind's prefs. var/mob/living/L = new_character if(L.client?.prefs && L.client.prefs.auto_ooc && L.client.prefs.chat_toggles & CHAT_OOC) - DISABLE_BITFIELD(L.client.prefs.chat_toggles,CHAT_OOC) + L.client.prefs.chat_toggles &= ~(CHAT_OOC) hide_ckey = current.client?.prefs?.hide_ckey @@ -173,7 +186,9 @@ qdel(A) return A.owner = src - LAZYADD(antag_datums, A) +//ambition start + do_add_antag_datum(A) +//ambition end A.create_team(team) var/datum/team/antag_team = A.get_team() if(antag_team) @@ -181,6 +196,14 @@ A.on_gain() return A +//ambition start +/datum/mind/proc/do_add_antag_datum(instanced_datum) + . = LAZYLEN(antag_datums) + LAZYADD(antag_datums, instanced_datum) + if(!.) + add_verb(current, /mob/proc/edit_objectives_and_ambitions) +//ambition end + /datum/mind/proc/remove_antag_datum(datum_type) if(!datum_type) return @@ -189,6 +212,14 @@ A.on_removal() return TRUE +//ambition start +/datum/mind/proc/do_remove_antag_datum(instanced_datum) + . = LAZYLEN(antag_datums) + LAZYREMOVE(antag_datums, instanced_datum) + if(. && !LAZYLEN(antag_datums)) + ambitions = null + remove_verb(current, /mob/proc/edit_objectives_and_ambitions) +//ambition end /datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us. for(var/a in antag_datums) @@ -198,7 +229,6 @@ /datum/mind/proc/has_antag_datum(datum_type, check_subtypes = TRUE) if(!datum_type) return - . = FALSE for(var/a in antag_datums) var/datum/antagonist/A = a if(check_subtypes && istype(A, datum_type)) @@ -265,11 +295,17 @@ remove_rev() SSticker.mode.update_cult_icons_removed(src) -/datum/mind/proc/equip_traitor(datum/traitor_class/traitor_class, silent = FALSE, datum/antagonist/uplink_owner) +/** + * ## give_uplink + * + * A mind proc for giving anyone an uplink. + * arguments: + * * silent: if this should send a message to the mind getting the uplink. traitors do not use this silence, but the silence var on their antag datum. + * * antag_datum: the antag datum of the uplink owner, for storing it in antag memory. optional! + */ +/datum/mind/proc/equip_traitor(silent = FALSE, datum/antagonist/antag_datum) if(!current) return - if(!traitor_class) - traitor_class = GLOB.traitor_classes[TRAITOR_HUMAN] var/mob/living/carbon/human/traitor_mob = current if (!istype(traitor_mob)) return @@ -283,16 +319,9 @@ P = locate() in PDA if (!P) // If we couldn't find a pen in the PDA, or we didn't even have a PDA, do it the old way P = locate() in all_contents - if(!P) // I do not have a pen. - var/obj/item/pen/inowhaveapen - if(istype(traitor_mob.back,/obj/item/storage)) //ok buddy you better have a backpack! - inowhaveapen = new /obj/item/pen(traitor_mob.back) - else - inowhaveapen = new /obj/item/pen(traitor_mob.loc) - traitor_mob.put_in_hands(inowhaveapen) // I hope you don't have arms and your traitor pen gets stolen for all this trouble you've caused. - P = inowhaveapen var/obj/item/uplink_loc + var/implant = FALSE if(traitor_mob.client && traitor_mob.client.prefs) switch(traitor_mob.client.prefs.uplink_spawn_loc) @@ -310,33 +339,38 @@ uplink_loc = P if(UPLINK_PEN) uplink_loc = P - if(!uplink_loc) - uplink_loc = PDA - if(!uplink_loc) - uplink_loc = R + if(UPLINK_IMPLANT) + implant = TRUE - if (!uplink_loc) - if(!silent) - to_chat(traitor_mob, "Unfortunately, [traitor_class.employer] wasn't able to get you an Uplink.") - . = 0 - else - . = uplink_loc - var/datum/component/uplink/U = uplink_loc.AddComponent(/datum/component/uplink, traitor_mob.key,traitor_class) - if(!U) - CRASH("Uplink creation failed.") - U.setup_unlock_code() - if(!silent) - if(uplink_loc == R) - to_chat(traitor_mob, "[traitor_class.employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(U.unlock_code)] to unlock its hidden features.") - else if(uplink_loc == PDA) - to_chat(traitor_mob, "[traitor_class.employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[U.unlock_code]\" into the ringtone select to unlock its hidden features.") - else if(uplink_loc == P) - to_chat(traitor_mob, "[traitor_class.employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [U.unlock_code] from its starting position to unlock its hidden features.") + if(!uplink_loc) // We've looked everywhere, let's just implant you + implant = TRUE - if(uplink_owner) - uplink_owner.antag_memory += U.unlock_note + "
" - else - traitor_mob.mind.store_memory(U.unlock_note) + if(implant) + var/obj/item/implant/uplink/starting/new_implant = new(traitor_mob) + new_implant.implant(traitor_mob, null, silent = TRUE) + if(!silent) + to_chat(traitor_mob, span_boldnotice("Your Syndicate Uplink has been cunningly implanted in you, for a small TC fee. Simply trigger the uplink to access it.")) + return new_implant + + . = uplink_loc + var/unlock_text + var/datum/component/uplink/new_uplink = uplink_loc.AddComponent(/datum/component/uplink, traitor_mob.key) + if(!new_uplink) + CRASH("Uplink creation failed.") + new_uplink.setup_unlock_code() + if(uplink_loc == R) + unlock_text = "Your Uplink is cunningly disguised as your [R.name]. Simply dial the frequency [format_frequency(new_uplink.unlock_code)] to unlock its hidden features." + else if(uplink_loc == PDA) + unlock_text = "Your Uplink is cunningly disguised as your [PDA.name]. Simply enter the code \"[new_uplink.unlock_code]\" into the ringtone select to unlock its hidden features." + else if(uplink_loc == P) + unlock_text = "Your Uplink is cunningly disguised as your [P.name]. Simply twist the top of the pen [english_list(new_uplink.unlock_code)] from its starting position to unlock its hidden features." + new_uplink.unlock_text = unlock_text + if(!silent) + to_chat(traitor_mob, span_boldnotice(unlock_text)) + if(!antag_datum) + traitor_mob.mind.store_memory(new_uplink.unlock_note) + return + antag_datum.antag_memory += new_uplink.unlock_note + "
" //Link a new mobs mind to the creator of said mob. They will join any team they are currently on, and will only switch teams when their creator does. @@ -374,10 +408,10 @@ message_admins("[ADMIN_LOOKUPFLW(current)] has been created by [ADMIN_LOOKUPFLW(creator)], an antagonist.") to_chat(current, "Despite your creators current allegiances, your true master remains [creator.real_name]. If their loyalties change, so do yours. This will never change unless your creator's body is destroyed.") -/datum/mind/proc/show_memory(mob/recipient, window=1) - if(!recipient) - recipient = current - var/output = "[current.real_name]'s Memories:
" +//ambition start +/datum/mind/proc/show_memory() + var/list/output = list("[current.real_name]'s Memories:
") +//ambition end output += memory @@ -398,16 +432,910 @@ output += "
  • Conspirator: [M.name]
  • " output += "" - if(window) - recipient << browse(output,"window=memory") - else if(all_objectives.len || memory) - to_chat(recipient, "[output]") +//ambition port start + if(LAZYLEN(ambitions)) + for(var/count in 1 to LAZYLEN(ambitions)) + output += "
    Ambition #[count]: [ambitions[count]]" + + if(!memory && !length(all_objectives) && !LAZYLEN(ambitions)) + output += "
    • NONE
    " + + return output.Join() + + +/datum/mind/proc/show_editable_objectives_and_ambitions() + var/is_admin = check_rights(R_ADMIN, FALSE) + var/self_mind = usr == current + if(!is_admin && !self_mind) + return "" + var/list/output = list() + for(var/a in antag_datums) + var/datum/antagonist/antag_datum = a + output += "Objectives:" + if(is_admin) + output += " Add Objective" + output += "" + if(is_admin) + output += "Announce objectives
    " + output += "
    Requested Objective Changes:" + if(self_mind) + output += " Request objective" + output += "
      " + if(!LAZYLEN(antag_datum.requested_objective_changes)) + output += "
    • NONE

    " + else + for(var/uid in antag_datum.requested_objective_changes) + var/list/objectives_info = antag_datum.requested_objective_changes[uid] + var/obj_request = objectives_info["request"] + switch(obj_request) + if(REQUEST_NEW_OBJECTIVE) + var/datum/objective/type_cast_objective = objectives_info["target"] + var/objective_text = objectives_info["text"] + output += "
  • Request #[uid]: ADD [initial(type_cast_objective.name)] - [objective_text]" + if(self_mind) + output += " Cancel Request" + if(is_admin) + output += " Accept Edit Deny" + if(REQUEST_DEL_OBJECTIVE) + var/datum/objective/objective_ref = locate(objectives_info["target"]) in antag_datum.objectives + if(QDELETED(objective_ref)) + stack_trace("Objective request found with deleted reference. UID: [uid] | Antag: [antag_datum] | Mind: [src] | User: [usr]") + antag_datum.remove_objective_change(uid) + continue + output += "
  • Request #[uid]: DEL [objective_ref.name] - [objective_ref.explanation_text] - [objectives_info["text"]]" + if(self_mind) + output += " Cancel Request" + if(is_admin) + output += " Accept Deny" + if(REQUEST_WIN_OBJECTIVE, REQUEST_LOSE_OBJECTIVE) + var/datum/objective/objective_ref = locate(objectives_info["target"]) in antag_datum.objectives + if(QDELETED(objective_ref)) + stack_trace("Objective request found with deleted reference. UID: [uid] | Antag: [antag_datum] | Mind: [src] | User: [usr]") + antag_datum.remove_objective_change(uid) + continue + output += "
  • Request #[uid]: [obj_request == REQUEST_WIN_OBJECTIVE ? "WIN" : "LOSE"] [objective_ref.name] - [objective_ref.explanation_text] - [objectives_info["text"]]" + if(self_mind) + output += " Cancel Request" + if(is_admin) + output += " Accept Deny" + else + stack_trace("Objective request found with no request index. UID: [uid] | Antag: [antag_datum] | Mind: [src] | User: [usr]") + continue + output += "
    " + if(self_mind) + output += "Ping the admins
    " + if(is_admin) + output += "Clear ping cooldown
    " + output += "
    [current.real_name]'s Ambitions:" + if(LAZYLEN(ambitions) < CONFIG_GET(number/max_ambitions)) + output += " Add Ambition" + output += "
      " + if(!LAZYLEN(ambitions)) + output += "
    • NONE" + else + for(var/count in 1 to LAZYLEN(ambitions)) + output += "
    • Ambition #[count] (Edit) (Remove):
      [ambitions[count]]" + output += "

    (Refresh)" + return output.Join() + + +/mob/proc/edit_objectives_and_ambitions() + set name = "Objectives and Ambitions" + set category = "IC" + set desc = "View and edit your character's objectives and ambitions." + mind.do_edit_objectives_ambitions() + + +/datum/mind/proc/do_edit_objectives_ambitions() + var/datum/browser/popup = new(usr, "objectives and ambitions", "Objectives and Ambitions") + popup.set_content(show_editable_objectives_and_ambitions()) + popup.open() + + +GLOBAL_VAR_INIT(requested_objective_uid, 0) + + +GLOBAL_LIST(objective_player_choices) + +/proc/populate_objective_player_choices() + GLOB.objective_player_choices = list() + var/list/allowed_types = list( + /datum/objective/custom, + /datum/objective/assassinate/once, + /datum/objective/protect, + /datum/objective/escape, + /datum/objective/survive, + /datum/objective/martyr, + /datum/objective/steal, + /datum/objective/download, + ) + + for(var/t in allowed_types) + var/datum/objective/type_cast = t + GLOB.objective_player_choices[initial(type_cast.name)] = t + + +GLOBAL_LIST(objective_choices) + +/proc/populate_objective_choices() + GLOB.objective_choices = list() + var/list/allowed_types = list( + /datum/objective/custom, + /datum/objective/assassinate, + /datum/objective/assassinate/once, + /datum/objective/maroon, + /datum/objective/debrain, + /datum/objective/protect, + /datum/objective/destroy, + /datum/objective/hijack, + /datum/objective/escape, + /datum/objective/survive, + /datum/objective/martyr, + /datum/objective/steal, + /datum/objective/download, + /datum/objective/nuclear, + /datum/objective/absorb, + ) + + for(var/t in allowed_types) + var/datum/objective/type_cast = t + GLOB.objective_choices[initial(type_cast.name)] = t + + +/datum/mind/proc/on_objectives_request_cd_end(datum/source) + UnregisterSignal(src, list(COMSIG_CD_STOP(COOLDOWN_OBJ_ADMIN_PING), COMSIG_CD_RESET(COOLDOWN_OBJ_ADMIN_PING))) + if(!antag_datums) + return + to_chat(current, "You are now again able to ping the admins objective changes review requests.") + for(var/a in antag_datums) + var/datum/antagonist/antag_datum = a + if(!antag_datum.requested_objective_changes) + continue + to_chat(current, "You seem to have unanswered change requests. If there are online admins another gentle reminder might be in order.") + break +//ambition port end /datum/mind/Topic(href, href_list) +//ambition start + + if (href_list["refresh_obj_amb"]) + do_edit_objectives_ambitions() + return + + else if (href_list["add_ambition"]) + if(!check_rights(R_ADMIN, FALSE)) + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_AMBITION)) + to_chat(usr, "You must wait [AMBITION_COOLDOWN_TIME * 0.1] seconds between changes.") + return + if(!isliving(current)) + return + if(!antag_datums) + return + var/max_ambitions = CONFIG_GET(number/max_ambitions) + if(LAZYLEN(ambitions) >= max_ambitions) + to_chat(usr, "There's a limit of [max_ambitions] ambitions. Edit or remove some to accomodate for your new additions.") + do_edit_objectives_ambitions() + return + var/new_ambition = stripped_multiline_input(usr, "Write new ambition", "Ambition", "", MAX_AMBITION_LEN) + if(isnull(new_ambition)) + return + if(!check_rights(R_ADMIN, FALSE)) + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_AMBITION)) + to_chat(usr, "You must wait [AMBITION_COOLDOWN_TIME * 0.1] seconds between changes.") + return + if(!isliving(current)) + to_chat(usr, "The mind holder is no longer a living creature.") + return + if(!antag_datums) + to_chat(usr, "The mind holder is no longer an antagonist.") + return + if(LAZYLEN(ambitions) >= max_ambitions) + to_chat(usr, "There's a limit of [max_ambitions] ambitions. Edit or remove some to accomodate for your new additions.") + do_edit_objectives_ambitions() + return + TIMER_COOLDOWN_START(src, COOLDOWN_AMBITION, AMBITION_COOLDOWN_TIME) + LAZYADD(ambitions, new_ambition) + if(usr == current) + log_game("[key_name(usr)] has created their ambition of index [LAZYLEN(ambitions)].\nNEW AMBITION:\n[new_ambition]") + else + log_game("[key_name(usr)] has created [key_name(current)]'s ambition of index [LAZYLEN(ambitions)].\nNEW AMBITION:\n[new_ambition]") + message_admins("[ADMIN_TPMONTY(usr)] has created [ADMIN_TPMONTY(current)]'s ambition of index [LAZYLEN(ambitions)].") + do_edit_objectives_ambitions() + return + + else if (href_list["edit_ambition"]) + if(!check_rights(R_ADMIN, FALSE)) + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_AMBITION)) + to_chat(usr, "You must wait [AMBITION_COOLDOWN_TIME * 0.1] seconds between changes.") + return + if(!isliving(current)) + return + if(!antag_datums) + return + var/ambition_index = text2num(href_list["edit_ambition"]) + if(!isnum(ambition_index) || ambition_index < 0 || ambition_index % 1) + log_admin_private("[key_name(usr)] attempted to edit their ambitions with and invalid ambition_index ([ambition_index]) at [AREACOORD(usr.loc)].") + message_admins("[ADMIN_TPMONTY(usr)] attempted to edit their ambitions with and invalid ambition_index ([ambition_index]). Possible HREF exploit.") + return + if(ambition_index > LAZYLEN(ambitions)) + return + var/old_ambition = ambitions[ambition_index] + var/new_ambition = stripped_multiline_input(usr, "Write new ambition", "Ambition", ambitions[ambition_index], MAX_AMBITION_LEN) + if(isnull(new_ambition)) + return + if(!check_rights(R_ADMIN, FALSE)) + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_AMBITION)) + to_chat(usr, "You must wait [AMBITION_COOLDOWN_TIME * 0.1] seconds between changes.") + return + if(!isliving(current)) + to_chat(usr, "The mind holder is no longer a living creature.") + return + if(!antag_datums) + to_chat(usr, "The mind holder is no longer an antagonist.") + return + if(ambition_index > LAZYLEN(ambitions)) + to_chat(usr, "The ambition we were editing was deleted before we finished. Aborting.") + do_edit_objectives_ambitions() + return + if(old_ambition != ambitions[ambition_index]) + to_chat(usr, "The ambition has changed since we started editing it. Aborting to prevent data loss.") + do_edit_objectives_ambitions() + return + TIMER_COOLDOWN_START(src, COOLDOWN_AMBITION, AMBITION_COOLDOWN_TIME) + ambitions[ambition_index] = new_ambition + if(usr == current) + log_game("[key_name(usr)] has edited their ambition of index [ambition_index].\nOLD AMBITION:\n[old_ambition]\nNEW AMBITION:\n[new_ambition]") + else + log_game("[key_name(usr)] has edited [key_name(current)]'s ambition of index [ambition_index].\nOLD AMBITION:\n[old_ambition]\nNEW AMBITION:\n[new_ambition]") + message_admins("[ADMIN_TPMONTY(usr)] has edited [ADMIN_TPMONTY(current)]'s ambition of index [ambition_index].") + do_edit_objectives_ambitions() + return + + else if (href_list["remove_ambition"]) + if(!check_rights(R_ADMIN, FALSE)) + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_AMBITION)) + to_chat(usr, "You must wait [AMBITION_COOLDOWN_TIME * 0.1] seconds between changes.") + return + if(!isliving(current)) + return + if(!antag_datums) + return + var/ambition_index = text2num(href_list["remove_ambition"]) + if(ambition_index > LAZYLEN(ambitions)) + do_edit_objectives_ambitions() + return + if(!isnum(ambition_index) || ambition_index < 0 || ambition_index % 1) + log_admin_private("[key_name(usr)] attempted to remove an ambition with and invalid ambition_index ([ambition_index]) at [AREACOORD(usr.loc)].") + message_admins("[ADMIN_TPMONTY(usr)] attempted to remove an ambition with and invalid ambition_index ([ambition_index]). Possible HREF exploit.") + return + var/old_ambition = ambitions[ambition_index] + if(alert(usr, "Are you sure you want to delete this ambition?", "Delete ambition", "Yes", "No") != "Yes") + return + if(!check_rights(R_ADMIN, FALSE)) + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_AMBITION)) + to_chat(usr, "You must wait [AMBITION_COOLDOWN_TIME * 0.1] seconds between changes.") + return + if(!isliving(current)) + to_chat(usr, "The mind holder is no longer a living creature. The ambition we were deleting should no longer exist already.") + return + if(!antag_datums) + to_chat(usr, "The mind holder is no longer an antagonist. The ambition we were deleting should no longer exist already.") + return + if(ambition_index > LAZYLEN(ambitions)) + to_chat(usr, "The ambition we were deleting was deleted before we finished. No need to continue.") + do_edit_objectives_ambitions() + return + if(old_ambition != ambitions[ambition_index]) + to_chat(usr, "The ambition has changed since we started considering its deletion. Aborting to prevent conflicts.") + do_edit_objectives_ambitions() + return + TIMER_COOLDOWN_START(src, COOLDOWN_AMBITION, AMBITION_COOLDOWN_TIME) + LAZYCUT(ambitions, ambition_index, ambition_index + 1) + if(usr == current) + log_game("[key_name(usr)] has deleted their ambition of index [ambition_index].\nDELETED AMBITION:\n[old_ambition]") + else + log_game("[key_name(usr)] has deleted [key_name(current)]'s ambition of index [ambition_index].\nDELETED AMBITION:\n[old_ambition]") + message_admins("[ADMIN_TPMONTY(usr)] has deleted [ADMIN_TPMONTY(current)]'s ambition of index [ambition_index].") + do_edit_objectives_ambitions() + return + + else if (href_list["req_obj_ping"]) + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_OBJ_ADMIN_PING)) + to_chat(usr, "You must wait [S_TIMER_COOLDOWN_TIMELEFT(src, COOLDOWN_OBJ_ADMIN_PING) * 0.1] seconds before your next admin ping.") + do_edit_objectives_ambitions() + return + if(!antag_datums) + return + var/pending_request = FALSE + for(var/a in antag_datums) + var/datum/antagonist/antag_datum = a + if(antag_datum.requested_objective_changes) + pending_request = TRUE + break + if(!pending_request) + to_chat(usr, "You have no pending requests to warn the admins about. Request changes for them to review before poking them.") + do_edit_objectives_ambitions() + return + var/justification = stripped_multiline_input(usr, + "Send a message to the admins requesting a review of your objective change requests.\ + There's a [ADMIN_PING_COOLDOWN_TIME * 0.1] seconds cooldown between requests, so try to think it through before sending it. Cancelling this does not trigger the cooldown.", + "Request Admin Review", max_length = MAX_MESSAGE_LEN) + if(isnull(justification)) + return + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_OBJ_ADMIN_PING)) + to_chat(usr, "You must wait [S_TIMER_COOLDOWN_TIMELEFT(src, COOLDOWN_OBJ_ADMIN_PING) * 0.1] seconds before your next admin ping.") + do_edit_objectives_ambitions() + return + if(!antag_datums) + return + pending_request = FALSE + for(var/a in antag_datums) + var/datum/antagonist/antag_datum = a + if(antag_datum.requested_objective_changes) + pending_request = TRUE + break + if(!pending_request) + return + if(!length(GLOB.admins)) + to_chat(usr, "No admins currently connected, failed to notify them. Wait for one to connect before trying to ping them again.") + do_edit_objectives_ambitions() + return + S_TIMER_COOLDOWN_START(src, COOLDOWN_OBJ_ADMIN_PING, ADMIN_PING_COOLDOWN_TIME) + RegisterSignal(src, list(COMSIG_CD_STOP(COOLDOWN_OBJ_ADMIN_PING), COMSIG_CD_RESET(COOLDOWN_OBJ_ADMIN_PING)), .proc/on_objectives_request_cd_end) + log_admin("Objectives review request - [key_name(usr)] has requested a review of their objective changes, pinging the admins.") + for(var/a in GLOB.admins) + var/client/admin_client = a + if(admin_client.prefs.toggles & SOUND_ADMINHELP) + SEND_SOUND(admin_client, sound('sound/effects/adminhelp.ogg')) + window_flash(admin_client) + message_admins("[ADMIN_TPMONTY(usr)] has requested a review of their objective changes. (RPLY)") + do_edit_objectives_ambitions() + return + + else if (href_list["req_obj_add"]) + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_OBJECTIVES)) + to_chat(usr, "You must wait [OBJECTIVES_COOLDOWN_TIME * 0.1] seconds between request changes.") + do_edit_objectives_ambitions() + return + var/datum/antagonist/target_antag = locate(href_list["target_antag"]) in antag_datums + if(QDELETED(target_antag)) + to_chat(usr, "No antagonist found for this objective.") + do_edit_objectives_ambitions() + return + if(!GLOB.objective_player_choices) + populate_objective_player_choices() + var/choice = input("Select desired objective type:", "Objective type") as null|anything in GLOB.objective_player_choices + var/selected_type = GLOB.objective_player_choices[choice] + if(!selected_type) + return + var/new_objective = stripped_multiline_input(usr,\ + selected_type == /datum/objective/custom\ + ? "Write the custom objective you'd like to request the admins to grant you. Remember they can edit or deny your request at their own discretion."\ + : "Justify your request for a new objective to the admins. Add the required clarifations, if you have a specific targets in mind and the likes.",\ + "New Objective", max_length = MAX_MESSAGE_LEN) + if(isnull(new_objective)) + return + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_OBJECTIVES)) + to_chat(usr, "You must wait [OBJECTIVES_COOLDOWN_TIME] minutes between request changes.") + return + if(QDELETED(target_antag)) + return + TIMER_COOLDOWN_START(src, COOLDOWN_OBJECTIVES, OBJECTIVES_COOLDOWN_TIME) + var/uid = "[GLOB.requested_objective_uid++]" + target_antag.add_objective_change(uid, list("request" = REQUEST_NEW_OBJECTIVE, "target" = selected_type, "text" = new_objective)) + log_admin("Objectives request [uid] - [key_name(usr)] has requested a [choice] objective: [new_objective]") + do_edit_objectives_ambitions() + return + + else if (href_list["req_obj_cancel"]) + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_OBJECTIVES)) + to_chat(usr, "You must wait [OBJECTIVES_COOLDOWN_TIME * 0.1] seconds between request changes.") + return + var/datum/antagonist/target_antag = locate(href_list["target_antag"]) in antag_datums + if(QDELETED(target_antag)) + to_chat(usr, "No antagonist found for this objective.") + do_edit_objectives_ambitions() + return + var/uid = href_list["req_obj_cancel"] + if(!LAZYACCESS(target_antag.requested_objective_changes, uid)) + to_chat(usr, "No requested objective change found. Perhaps it was deleted already?") + do_edit_objectives_ambitions() + return + if(alert(usr, "Are you sure you want to delete this change request?", "Delete change request", "Yes", "No") != "Yes") + return + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_OBJECTIVES)) + to_chat(usr, "You must wait [OBJECTIVES_COOLDOWN_TIME * 0.1] seconds between request changes.") + return + if(QDELETED(target_antag)) + do_edit_objectives_ambitions() + return + if(!LAZYACCESS(target_antag.requested_objective_changes, uid)) + do_edit_objectives_ambitions() + return + TIMER_COOLDOWN_START(src, COOLDOWN_OBJECTIVES, OBJECTIVES_COOLDOWN_TIME) + log_admin("Objectives request deletion - [key_name(usr)] has deleted the objective change request of UID [uid].") + target_antag.remove_objective_change(uid) + do_edit_objectives_ambitions() + return + + else if (href_list["req_obj_delete"]) + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_OBJECTIVES)) + to_chat(usr, "You must wait [OBJECTIVES_COOLDOWN_TIME * 0.1] seconds between request changes.") + return + var/datum/antagonist/target_antag = locate(href_list["target_antag"]) in antag_datums + if(QDELETED(target_antag)) + to_chat(usr, "No antagonist found for this objective.") + do_edit_objectives_ambitions() + return + var/objective_reference = href_list["req_obj_delete"] + var/datum/objective/objective_to_delete = locate(objective_reference) in target_antag.objectives + if(!istype(objective_to_delete) || QDELETED(objective_to_delete)) + to_chat(usr, "No objective found. Perhaps it was already deleted?") + do_edit_objectives_ambitions() + return + var/justification = stripped_multiline_input(usr, + "Justify your request for a deleting this objective to the admins.", + "Objective Deletion", max_length = MAX_MESSAGE_LEN) + if(isnull(justification)) + return + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_OBJECTIVES)) + to_chat(usr, "You must wait [OBJECTIVES_COOLDOWN_TIME * 0.1] seconds between request changes.") + return + if(QDELETED(objective_to_delete) || QDELETED(target_antag)) + do_edit_objectives_ambitions() + return + var/matching_request = FALSE + for(var/index in target_antag.requested_objective_changes) + var/list/change_request = target_antag.requested_objective_changes[index] + if(change_request["target"] != objective_reference) + continue + matching_request = TRUE + break + if(matching_request) + if(alert(usr, "There is already a change request tied to this objective waiting to be processed. Adding this request will delete the old ones.", "Delete matching objective requests?", "Yes", "No") != "Yes") + do_edit_objectives_ambitions() + return + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_OBJECTIVES)) + to_chat(usr, "You must wait [OBJECTIVES_COOLDOWN_TIME * 0.1] seconds between request changes.") + return + if(QDELETED(objective_to_delete) || QDELETED(target_antag)) + do_edit_objectives_ambitions() + return + for(var/index in target_antag.requested_objective_changes) + var/list/change_request = target_antag.requested_objective_changes[index] + if(change_request["target"] != objective_reference) + continue + target_antag.remove_objective_change(index) + TIMER_COOLDOWN_START(src, COOLDOWN_OBJECTIVES, OBJECTIVES_COOLDOWN_TIME) + var/uid = "[GLOB.requested_objective_uid++]" + target_antag.add_objective_change(uid, list("request" = REQUEST_DEL_OBJECTIVE, "target" = objective_reference, "text" = justification)) + log_admin("Objectives request [uid] - [key_name(usr)] has requested the deletion of the following objective: [objective_to_delete.explanation_text].\nTheir justification is as follows: [justification]") + do_edit_objectives_ambitions() + return + + else if (href_list["req_obj_completed"]) + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_OBJECTIVES)) + to_chat(usr, "You must wait [OBJECTIVES_COOLDOWN_TIME * 0.1] seconds between request changes.") + return + var/datum/antagonist/target_antag = locate(href_list["target_antag"]) in antag_datums + if(QDELETED(target_antag)) + to_chat(usr, "No antagonist found for this objective.") + do_edit_objectives_ambitions() + return + var/objective_reference = href_list["req_obj_completed"] + var/datum/objective/objective_to_complete = locate(objective_reference) in target_antag.objectives + if(!istype(objective_to_complete) || QDELETED(objective_to_complete)) + to_chat(usr, "No objective found. Perhaps it was deleted?") + do_edit_objectives_ambitions() + return + var/justification = stripped_multiline_input(usr, + "Justify to the admins your request to mark this objective as [objective_to_complete.completed ? "incomplete" : "completed"].", + "Objective [objective_to_complete.completed ? "Incompletion" : "Completion"]", max_length = MAX_MESSAGE_LEN) + if(isnull(justification)) + return + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_OBJECTIVES)) + to_chat(usr, "You must wait [OBJECTIVES_COOLDOWN_TIME * 0.1] seconds between request changes.") + return + if(QDELETED(objective_to_complete) || QDELETED(target_antag)) + do_edit_objectives_ambitions() + return + var/matching_request = FALSE + for(var/index in target_antag.requested_objective_changes) + var/list/change_request = target_antag.requested_objective_changes[index] + if(change_request["target"] != objective_reference) + continue + matching_request = TRUE + break + if(matching_request) + if(alert(usr, "There is already a change request tied to this objective waiting to be processed. Adding this request will delete the old ones.", "Delete matching objective requests?", "Yes", "No") != "Yes") + return + if(usr != current) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_OBJECTIVES)) + to_chat(usr, "You must wait [OBJECTIVES_COOLDOWN_TIME * 0.1] seconds between request changes.") + return + if(QDELETED(objective_to_complete) || QDELETED(target_antag)) + do_edit_objectives_ambitions() + return + for(var/index in target_antag.requested_objective_changes) + var/list/change_request = target_antag.requested_objective_changes[index] + if(change_request["target"] != objective_reference) + continue + target_antag.remove_objective_change(index) + TIMER_COOLDOWN_START(src, COOLDOWN_OBJECTIVES, OBJECTIVES_COOLDOWN_TIME) + var/uid = "[GLOB.requested_objective_uid++]" + target_antag.add_objective_change(uid, list("request" = (objective_to_complete.completed ? REQUEST_LOSE_OBJECTIVE : REQUEST_WIN_OBJECTIVE), "target" = objective_reference, "text" = justification)) + log_admin("Objectives request [uid] - [key_name(usr)] has requested the [objective_to_complete.completed ? "incompletion" : "completion"] of the following objective: [objective_to_complete.explanation_text].\nTheir justification is as follows: [justification]") + do_edit_objectives_ambitions() + return if(!check_rights(R_ADMIN)) return var/self_antagging = usr == current + if(href_list["edit_ambitions_panel"]) + do_edit_objectives_ambitions() + return + + else if(href_list["req_obj_ping_cd_clear"]) + if(!TIMER_COOLDOWN_CHECK(src, COOLDOWN_OBJ_ADMIN_PING)) + to_chat(usr, "Mind is not under a cooldown.") + do_edit_objectives_ambitions() + return + if(alert(usr, "Are you sure you want reset this cooldown, letting the user ping the admins again?", "Clear ping cooldown", "Yes", "No") != "Yes") + do_edit_objectives_ambitions() + return + if(!check_rights(R_ADMIN)) + return + if(!TIMER_COOLDOWN_CHECK(src, COOLDOWN_OBJ_ADMIN_PING)) + do_edit_objectives_ambitions() + return + S_TIMER_COOLDOWN_RESET(src, COOLDOWN_OBJ_ADMIN_PING) + do_edit_objectives_ambitions() + return + + else if(href_list["refresh_antag_panel"]) + traitor_panel() + return + + else if (href_list["req_obj_edit"]) + var/datum/antagonist/antag_datum = locate(href_list["req_obj_edit"]) in antag_datums + if(QDELETED(antag_datum)) + do_edit_objectives_ambitions() + to_chat(usr, "No antag found.") + return + if(antag_datum.owner != src) + do_edit_objectives_ambitions() + to_chat(usr, "Invalid antag reference.") + return + var/uid = href_list["req_obj_id"] + var/list/requested_obj_change = LAZYACCESS(antag_datum.requested_objective_changes, uid) + if(!requested_obj_change) + do_edit_objectives_ambitions() + to_chat(usr, "Invalid requested objective reference.") + return + if(requested_obj_change["request"] != REQUEST_NEW_OBJECTIVE) + do_edit_objectives_ambitions() + to_chat(usr, "This is not an editable request. How did you even got here?") + return + switch(alert(usr, "Do you want to edit the requested objective type or text?", "Edit requested objective", "Type", "Text", "Cancel")) + if("Type") + if(!check_rights(R_ADMIN)) + return + if(QDELETED(antag_datum)) + to_chat(usr, "No antag found.") + do_edit_objectives_ambitions() + return + if(!LAZYACCESS(antag_datum.requested_objective_changes, uid)) + to_chat(usr, "Invalid requested objective change reference.") + do_edit_objectives_ambitions() + return + var/datum/objective/type_cast = requested_obj_change["target"] + var/selected_type = input("Select new requested objective type:", "Requested Objective type", initial(type_cast.name)) as null|anything in GLOB.objective_choices + selected_type = GLOB.objective_choices[selected_type] + if(!selected_type) + return + if(!check_rights(R_ADMIN)) + return + if(QDELETED(antag_datum)) + to_chat(usr, "No antag found.") + do_edit_objectives_ambitions() + return + if(!LAZYACCESS(antag_datum.requested_objective_changes, uid)) + to_chat(usr, "Invalid requested objective change reference.") + do_edit_objectives_ambitions() + return + log_admin("[key_name(usr)] has edited the requested objective type for [current], of UID [uid], from [requested_obj_change["target"]] to [selected_type]") + message_admins("[key_name_admin(usr)] has edited the requested objective type for [current], of UID [uid], from [requested_obj_change["target"]] to [selected_type]") + requested_obj_change["target"] = selected_type + if("Text") + if(!check_rights(R_ADMIN)) + return + if(QDELETED(antag_datum)) + to_chat(usr, "No antag found.") + do_edit_objectives_ambitions() + return + if(!LAZYACCESS(antag_datum.requested_objective_changes, uid)) + to_chat(usr, "Invalid requested objective change reference.") + do_edit_objectives_ambitions() + return + var/new_text = stripped_multiline_input(usr, "Input new requested objective text", "Requested Objective Text", requested_obj_change["text"], MAX_MESSAGE_LEN) + if (isnull(new_text)) + return + if(!check_rights(R_ADMIN)) + return + if(QDELETED(antag_datum)) + to_chat(usr, "No antag found.") + do_edit_objectives_ambitions() + return + if(!LAZYACCESS(antag_datum.requested_objective_changes, uid)) + to_chat(usr, "Invalid requested objective change reference.") + do_edit_objectives_ambitions() + return + log_admin("[key_name(usr)] has edited the requested objective text for [current], of UID [uid], from [requested_obj_change["text"]] to [new_text]") + message_admins("[key_name_admin(usr)] has edited the requested objective text for [current], of UID [uid], from [requested_obj_change["text"]] to [new_text]") + requested_obj_change["text"] = new_text + do_edit_objectives_ambitions() + return + + else if (href_list["req_obj_accept"]) + var/datum/antagonist/antag_datum = locate(href_list["req_obj_accept"]) in antag_datums + if(QDELETED(antag_datum)) + do_edit_objectives_ambitions() + to_chat(usr, "No antag found.") + return + if(antag_datum.owner != src) + do_edit_objectives_ambitions() + to_chat(usr, "Invalid antag reference.") + return + var/uid = href_list["req_obj_id"] + var/list/requested_obj_change = LAZYACCESS(antag_datum.requested_objective_changes, uid) + if(!requested_obj_change) + do_edit_objectives_ambitions() + to_chat(usr, "Invalid requested objective reference.") + return + + var/datum/objective/request_target + var/request_type = requested_obj_change["request"] + switch(request_type) + if(REQUEST_NEW_OBJECTIVE) + request_target = requested_obj_change["target"] + if(!ispath(request_target, /datum/objective)) + to_chat(usr, "Invalid requested objective target path.") + return + if(REQUEST_DEL_OBJECTIVE, REQUEST_WIN_OBJECTIVE, REQUEST_LOSE_OBJECTIVE) + request_target = locate(requested_obj_change["target"]) in antag_datum.objectives + if(QDELETED(request_target)) + to_chat(usr, "Invalid requested objective target reference.") + return + else + to_chat(usr, "Invalid request type.") + return + if(alert(usr, "Are you sure you want to approve this objective change?", "Approve objective change", "Yes", "No") != "Yes") + return + if(!check_rights(R_ADMIN)) + return + if(QDELETED(antag_datum)) + to_chat(usr, "No antag found.") + do_edit_objectives_ambitions() + return + if(!LAZYACCESS(antag_datum.requested_objective_changes, uid)) + to_chat(usr, "Invalid requested objective change reference.") + do_edit_objectives_ambitions() + return + switch(request_type) //Last checks + if(REQUEST_NEW_OBJECTIVE) + if(!ispath(request_target, /datum/objective)) + stack_trace("Invalid target on objective change request: [request_target]") + do_edit_objectives_ambitions() + return + if(REQUEST_DEL_OBJECTIVE, REQUEST_WIN_OBJECTIVE, REQUEST_LOSE_OBJECTIVE) + if(QDELETED(request_target)) + to_chat(usr, "Invalid requested objective target reference.") + return + else + to_chat(usr, "Invalid request type.") + return + antag_datum.remove_objective_change(uid) + switch(request_type) //All is clear, let get things done. + if(REQUEST_NEW_OBJECTIVE) + request_target = new request_target() + request_target.owner = src + if(istype(request_target, /datum/objective/custom)) + request_target.explanation_text = requested_obj_change["text"] + else + request_target.admin_edit(usr) + antag_datum.objectives += request_target + message_admins("[key_name_admin(usr)] approved a requested objective from [current]: [request_target.explanation_text]") + log_admin("[key_name(usr)] approved a requested objective from [current]: [request_target.explanation_text]") + if(REQUEST_DEL_OBJECTIVE) + message_admins("[key_name_admin(usr)] approved the request to delete an objective from [current]: [request_target.explanation_text]") + log_admin("[key_name(usr)] approved the request to delete an objective from [current]: [request_target.explanation_text]") + qdel(request_target) + if(REQUEST_WIN_OBJECTIVE) + message_admins("[key_name_admin(usr)] approved the victory request for an objective from [current]: [request_target.explanation_text]") + log_admin("[key_name(usr)] approved the victory request for an objective from [current]: [request_target.explanation_text]") + request_target.completed = TRUE + if(REQUEST_LOSE_OBJECTIVE) + message_admins("[key_name_admin(usr)] approved the defeat request for an objective from [current]: [request_target.explanation_text]") + log_admin("[key_name(usr)] approved the defeat request for an objective from [current]: [request_target.explanation_text]") + request_target.completed = FALSE + to_chat(current, "Your objective change request has been approved.") + do_edit_objectives_ambitions() + return + + else if (href_list["req_obj_deny"]) + var/datum/antagonist/antag_datum = locate(href_list["req_obj_deny"]) in antag_datums + if(QDELETED(antag_datum)) + do_edit_objectives_ambitions() + to_chat(usr, "No antag found.") + return + if(antag_datum.owner != src) + do_edit_objectives_ambitions() + to_chat(usr, "Invalid antag reference.") + return + var/uid = href_list["req_obj_id"] + var/list/requested_obj_change = LAZYACCESS(antag_datum.requested_objective_changes, uid) + if(!requested_obj_change) + do_edit_objectives_ambitions() + to_chat(usr, "Invalid requested objective change reference.") + return + var/justification = stripped_multiline_input(usr, "Justify why you are denying this objective request change.", "Deny", memory, MAX_MESSAGE_LEN) + if(isnull(justification)) + return + if(!check_rights(R_ADMIN)) + return + if(QDELETED(antag_datum)) + to_chat(usr, "No antag found.") + do_edit_objectives_ambitions() + return + if(!LAZYACCESS(antag_datum.requested_objective_changes, uid)) + to_chat(usr, "Invalid requested objective change reference.") + do_edit_objectives_ambitions() + return + var/datum/objective/type_cast = requested_obj_change["target"] + var/objective_name = initial(type_cast.name) + message_admins("[key_name_admin(usr)] denied a requested [objective_name] objective from [current]: [requested_obj_change["text"]]") + log_admin("[key_name(usr)] denied a requested [objective_name] objective from [current]: [requested_obj_change["text"]]") + to_chat(current, "Your objective request has been denied for the following reason: [justification]") + antag_datum.remove_objective_change(uid) + do_edit_objectives_ambitions() + return + + else if (href_list["obj_panel_complete_toggle"]) + var/datum/antagonist/antag_datum = locate(href_list["target_antag"]) in antag_datums + if(QDELETED(antag_datum)) + do_edit_objectives_ambitions() + to_chat(usr, "No antag found.") + return + if(antag_datum.owner != src) + do_edit_objectives_ambitions() + to_chat(usr, "Invalid antag reference.") + return + var/datum/objective/objective_to_toggle = locate(href_list["obj_panel_complete_toggle"]) in antag_datum.objectives + if(QDELETED(objective_to_toggle)) + to_chat(usr, "No objective found. Perhaps it was already deleted?") + do_edit_objectives_ambitions() + return + if(objective_to_toggle.owner != src) + do_edit_objectives_ambitions() + to_chat(usr, "Invalid objective reference.") + return + objective_to_toggle.completed = !objective_to_toggle.completed + message_admins("[key_name_admin(usr)] toggled the win state for [current]'s objective: [objective_to_toggle.explanation_text]") + log_admin("[key_name(usr)] toggled the win state for [current]'s objective: [objective_to_toggle.explanation_text]") + if(alert(usr, "Would you like to alert the player of the change?", "Deny objective", "Yes", "No") == "Yes") + to_chat(current, "[objective_to_toggle.completed ? "" : ""]Your objective status has changed!") + do_edit_objectives_ambitions() + return + + else if (href_list["obj_panel_delete"]) + var/datum/antagonist/antag_datum = locate(href_list["target_antag"]) in antag_datums + if(QDELETED(antag_datum)) + do_edit_objectives_ambitions() + to_chat(usr, "No antag found.") + return + if(antag_datum.owner != src) + do_edit_objectives_ambitions() + to_chat(usr, "Invalid antag reference.") + return + var/datum/objective/objective_to_delete = locate(href_list["obj_panel_delete"]) in antag_datum.objectives + if(QDELETED(objective_to_delete)) + to_chat(usr, "No objective found. Perhaps it was already deleted?") + do_edit_objectives_ambitions() + return + if(objective_to_delete.owner != src) + do_edit_objectives_ambitions() + to_chat(usr, "Invalid objective reference.") + return + if(alert(usr, "Are you sure you want to delete this objective?", "Delete objective", "Yes", "No") != "Yes") + return + if(!check_rights(R_ADMIN)) + return + if(QDELETED(objective_to_delete)) + return + message_admins("[key_name_admin(usr)] removed an objective from [current]: [objective_to_delete.explanation_text]") + log_admin("[key_name(usr)] removed an objective from [current]: [objective_to_delete.explanation_text]") + qdel(objective_to_delete) + do_edit_objectives_ambitions() + return + + else if (href_list["obj_panel_edit"]) + var/datum/antagonist/antag_datum = locate(href_list["target_antag"]) in antag_datums + if(QDELETED(antag_datum)) + do_edit_objectives_ambitions() + to_chat(usr, "No antag found.") + return + if(antag_datum.owner != src) + do_edit_objectives_ambitions() + to_chat(usr, "Invalid antag reference.") + return + var/datum/objective/objective_to_edit = locate(href_list["obj_panel_edit"]) in antag_datum.objectives + if(QDELETED(objective_to_edit)) + to_chat(usr, "No objective found. Perhaps it was already deleted?") + do_edit_objectives_ambitions() + return + if(objective_to_edit.owner != src) + do_edit_objectives_ambitions() + to_chat(usr, "Invalid objective reference.") + return + var/explanation_before = objective_to_edit.explanation_text + objective_to_edit.admin_edit(usr) + if(QDELETED(objective_to_edit)) + return + message_admins("[key_name_admin(usr)] edited an objective from [current]:\ + Before: [explanation_before]\ + After: [objective_to_edit.explanation_text]") + log_admin("[key_name(usr)] edited an objective from [current]:\ + Before: [explanation_before]\ + After: [objective_to_edit.explanation_text]") + do_edit_objectives_ambitions() + return +//ambition end if(href_list["add_antag"]) add_antag_wrapper(text2path(href_list["add_antag"]),usr) @@ -468,38 +1396,16 @@ else target_antag = target - var/static/list/choices - if(!choices) - choices = list() +//ambition start + if(!GLOB.objective_choices) + populate_objective_choices() - var/list/allowed_types = list( - /datum/objective/assassinate, - /datum/objective/assassinate/once, - /datum/objective/maroon, - /datum/objective/debrain, - /datum/objective/protect, - /datum/objective/destroy, - /datum/objective/hijack, - /datum/objective/escape, - /datum/objective/survive, - /datum/objective/martyr, - /datum/objective/steal, - /datum/objective/download, - /datum/objective/nuclear, - /datum/objective/absorb, - /datum/objective/custom - ) + if(old_objective && GLOB.objective_choices[old_objective.name]) + def_value = old_objective.name - for(var/T in allowed_types) - var/datum/objective/X = T - choices[initial(X.name)] = T - - if(old_objective) - if(old_objective.name in choices) - def_value = old_objective.name - - var/selected_type = input("Select objective type:", "Objective type", def_value) as null|anything in choices - selected_type = choices[selected_type] + var/selected_type = input("Select objective type:", "Objective type", def_value) as null|anything in GLOB.objective_choices + selected_type = GLOB.objective_choices[selected_type] +//ambition end if (!selected_type) return @@ -527,6 +1433,12 @@ message_admins("[key_name_admin(usr)] edited [current]'s objective to [new_objective.explanation_text]") log_admin("[key_name(usr)] edited [current]'s objective to [new_objective.explanation_text]") +//ambition start + if(href_list["ambition_panel"]) + do_edit_objectives_ambitions() + return +//ambition end + else if(href_list["traitor_class"]) var/static/list/choices if(!choices) @@ -611,6 +1523,11 @@ else if (href_list["obj_announce"]) announce_objectives() +//ambition start + if(href_list["ambition_panel"]) + do_edit_objectives_ambitions() + return +//ambition end //Something in here might have changed your mob if(self_antagging && (!usr || !usr.client) && current.client) @@ -719,11 +1636,6 @@ for(var/X in spell_list) var/obj/effect/proc_holder/spell/S = X S.action.Grant(new_character) - var/datum/antagonist/changeling/changeling = new_character.mind.has_antag_datum(/datum/antagonist/changeling) - if(changeling &&(ishuman(new_character) || ismonkey(new_character))) - for(var/P in changeling.purchasedpowers) - var/obj/effect/proc_holder/changeling/I = P - I.action.Grant(new_character) /datum/mind/proc/disrupt_spells(delay, list/exceptions = New()) for(var/X in spell_list) @@ -814,3 +1726,7 @@ ..() mind.assigned_role = ROLE_PAI mind.special_role = "" + +//ambition start +#undef AMBITION_COOLDOWN_TIME +//ambition end diff --git a/code/datums/mocking/client.dm b/code/datums/mocking/client.dm new file mode 100644 index 0000000000..4a665f828b --- /dev/null +++ b/code/datums/mocking/client.dm @@ -0,0 +1,7 @@ +/// This should match the interface of /client wherever necessary. +/datum/client_interface + /// Player preferences datum for the client + var/datum/preferences/prefs + + /// The view of the client, similar to /client/var/view. + var/view = "15x15" diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index 90982a00ec..3521fe756c 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -147,6 +147,11 @@ mood_change = -5 timeout = 1 MINUTES +/datum/mood_event/painful_limb_regrowth + description = "It's great to have all my limbs back but that was absolutely painful.\n" + mood_change = -5 + timeout = 1 MINUTES + /datum/mood_event/loud_gong description = "That loud gong noise really hurt my ears!\n" mood_change = -3 @@ -294,3 +299,39 @@ description = "I hate when my shoes come untied!\n" mood_change = -3 timeout = 1 MINUTES + +/datum/mood_event/high_five_alone + description = "I tried getting a high-five with no one around, how embarassing!\n" + mood_change = -2 + timeout = 1 MINUTES + +/datum/mood_event/high_five_full_hand + description = "Oh God, I don't even know how to high-five correctly...\n" + mood_change = -1 + timeout = 45 SECONDS + +/datum/mood_event/left_hanging + description = "But everyone loves high fives! Maybe people just... hate me?\n" + mood_change = -2 + timeout = 1.5 MINUTES + +/datum/mood_event/too_slow + description = "NO! HOW COULD I BE.... TOO SLOW???\n" + mood_change = -2 // multiplied by how many people saw it happen, up to 8, so potentially massive. the ULTIMATE prank carries a lot of weight + timeout = 2 MINUTES + +/datum/mood_event/too_slow/add_effects(param) + var/people_laughing_at_you = 1 // start with 1 in case they're on the same tile or something + for(var/mob/living/carbon/iter_carbon in oview(owner, 7)) + if(iter_carbon.stat == CONSCIOUS) + people_laughing_at_you++ + if(people_laughing_at_you > 7) + break + + mood_change *= people_laughing_at_you + return ..() + +/datum/mood_event/sacrifice_bad + description = "Those darn savages!\n" + mood_change = -5 + timeout = 2 MINUTES diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index b73756c2b1..b0d73615b9 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -205,3 +205,23 @@ /datum/mood_event/cleared_stomach description = "Feels nice to get that out of the way!\n" mood_change = 3 + +/datum/mood_event/high_five + description = "I love getting high fives!\n" + mood_change = 2 + timeout = 45 SECONDS + +/datum/mood_event/high_ten + description = "AMAZING! A HIGH-TEN!\n" + mood_change = 3 + timeout = 45 SECONDS + +/datum/mood_event/down_low + description = "HA! What a rube, they never stood a chance...\n" + mood_change = 4 + timeout = 1.5 MINUTES + +/datum/mood_event/sacrifice_good + description = "The gods are pleased with this offering!\n" + mood_change = 5 + timeout = 3 MINUTES diff --git a/code/datums/mutable_appearance.dm b/code/datums/mutable_appearance.dm index 968809747b..104147ebeb 100644 --- a/code/datums/mutable_appearance.dm +++ b/code/datums/mutable_appearance.dm @@ -4,13 +4,16 @@ // Mutable appearances are children of images, just so you know. +/mutable_appearance + var/category // listen i want to store some meta information on mutable appearances don't judge me + /mutable_appearance/New() ..() plane = FLOAT_PLANE // No clue why this is 0 by default yet images are on FLOAT_PLANE // And yes this does have to be in the constructor, BYOND ignores it if you set it as a normal var // Helper similar to image() -/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE, color = "#FFFFFF") +/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE, color = "#FFFFFF", blend_mode = BLEND_DEFAULT) var/mutable_appearance/MA = new() MA.icon = icon MA.icon_state = icon_state @@ -19,5 +22,6 @@ MA.alpha = alpha MA.appearance_flags |= appearance_flags MA.color = color + MA.blend_mode = blend_mode return MA diff --git a/code/datums/mutations/actions.dm b/code/datums/mutations/actions.dm index 8f7d67abb8..dad5237aa5 100644 --- a/code/datums/mutations/actions.dm +++ b/code/datums/mutations/actions.dm @@ -205,6 +205,16 @@ synchronizer_coeff = 1 var/reek = 200 +/datum/mutation/human/olfaction/on_acquiring(mob/living/carbon/human/owner) + if(..() || HAS_TRAIT(owner, TRAIT_ANOSMIA)) + return TRUE + ADD_TRAIT(owner, TRAIT_GOODSMELL, GENETIC_MUTATION) + +/datum/mutation/human/olfaction/on_losing(mob/living/carbon/human/owner) + if(..()) + return + REMOVE_TRAIT(owner, TRAIT_GOODSMELL, GENETIC_MUTATION) + /datum/mutation/human/olfaction/modify() if(power) var/obj/effect/proc_holder/spell/targeted/olfaction/S = power diff --git a/code/datums/mutations/cluwne.dm b/code/datums/mutations/cluwne.dm index 59b7752372..45a78be27b 100644 --- a/code/datums/mutations/cluwne.dm +++ b/code/datums/mutations/cluwne.dm @@ -17,18 +17,18 @@ if(!istype(H.wear_mask, /obj/item/clothing/mask/gas/cluwne)) if(!H.dropItemToGround(H.wear_mask)) qdel(H.wear_mask) - H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/cluwne(H), SLOT_WEAR_MASK) + H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/cluwne(H), ITEM_SLOT_MASK) if(!istype(H.w_uniform, /obj/item/clothing/under/cluwne)) if(!H.dropItemToGround(H.w_uniform)) qdel(H.w_uniform) - H.equip_to_slot_or_del(new /obj/item/clothing/under/cluwne(H), SLOT_W_UNIFORM) + H.equip_to_slot_or_del(new /obj/item/clothing/under/cluwne(H), ITEM_SLOT_ICLOTHING) if(!istype(H.shoes, /obj/item/clothing/shoes/clown_shoes/cluwne)) if(!H.dropItemToGround(H.shoes)) qdel(H.shoes) - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/clown_shoes/cluwne(H), SLOT_SHOES) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/clown_shoes/cluwne(H), ITEM_SLOT_FEET) - owner.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/white(owner), SLOT_GLOVES) // this is purely for cosmetic purposes incase they aren't wearing anything in that slot - owner.equip_to_slot_or_del(new /obj/item/storage/backpack/clown(owner), SLOT_BACK) // ditto + owner.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/white(owner), ITEM_SLOT_GLOVES) // this is purely for cosmetic purposes incase they aren't wearing anything in that slot + owner.equip_to_slot_or_del(new /obj/item/storage/backpack/clown(owner), ITEM_SLOT_BACK) // ditto /datum/mutation/human/cluwne/on_life(mob/living/carbon/human/owner) if((prob(15) && owner.IsUnconscious())) diff --git a/code/datums/mutations/space_adaptation.dm b/code/datums/mutations/space_adaptation.dm index 4431720375..6defd05ee5 100644 --- a/code/datums/mutations/space_adaptation.dm +++ b/code/datums/mutations/space_adaptation.dm @@ -13,6 +13,7 @@ return ADD_TRAIT(owner, TRAIT_RESISTCOLD, "cold_resistance") ADD_TRAIT(owner, TRAIT_RESISTLOWPRESSURE, "cold_resistance") + ADD_TRAIT(owner, TRAIT_LOWPRESSURECOOLING, "cold_resistance") owner.add_filter("space_glow", 2, list("type" = "outline", "color" = "#ffe46bd8", "size" = 1)) addtimer(CALLBACK(src, .proc/glow_loop, owner), rand(1,19)) @@ -27,5 +28,6 @@ return REMOVE_TRAIT(owner, TRAIT_RESISTCOLD, "cold_resistance") REMOVE_TRAIT(owner, TRAIT_RESISTLOWPRESSURE, "cold_resistance") + REMOVE_TRAIT(owner, TRAIT_LOWPRESSURECOOLING, "cold_resistance") owner.remove_filter("space_glow") diff --git a/code/datums/outfit.dm b/code/datums/outfit.dm index 0b46629365..4c17874f97 100755 --- a/code/datums/outfit.dm +++ b/code/datums/outfit.dm @@ -153,31 +153,31 @@ //Start with uniform,suit,backpack for additional slots if(uniform) - H.equip_to_slot_or_del(new uniform(H), SLOT_W_UNIFORM, TRUE) + H.equip_to_slot_or_del(new uniform(H), ITEM_SLOT_ICLOTHING, TRUE) if(suit) - H.equip_to_slot_or_del(new suit(H), SLOT_WEAR_SUIT, TRUE) + H.equip_to_slot_or_del(new suit(H), ITEM_SLOT_OCLOTHING, TRUE) if(back) - H.equip_to_slot_or_del(new back(H), SLOT_BACK, TRUE) + H.equip_to_slot_or_del(new back(H), ITEM_SLOT_BACK, TRUE) if(belt) - H.equip_to_slot_or_del(new belt(H), SLOT_BELT, TRUE) + H.equip_to_slot_or_del(new belt(H), ITEM_SLOT_BELT, TRUE) if(gloves) - H.equip_to_slot_or_del(new gloves(H), SLOT_GLOVES, TRUE) + H.equip_to_slot_or_del(new gloves(H), ITEM_SLOT_GLOVES, TRUE) if(shoes) - H.equip_to_slot_or_del(new shoes(H), SLOT_SHOES, TRUE) + H.equip_to_slot_or_del(new shoes(H), ITEM_SLOT_FEET, TRUE) if(head) - H.equip_to_slot_or_del(new head(H), SLOT_HEAD, TRUE) + H.equip_to_slot_or_del(new head(H), ITEM_SLOT_HEAD, TRUE) if(mask) - H.equip_to_slot_or_del(new mask(H), SLOT_WEAR_MASK, TRUE) + H.equip_to_slot_or_del(new mask(H), ITEM_SLOT_MASK, TRUE) if(neck) - H.equip_to_slot_or_del(new neck(H), SLOT_NECK, TRUE) + H.equip_to_slot_or_del(new neck(H), ITEM_SLOT_NECK, TRUE) if(ears) - H.equip_to_slot_or_del(new ears(H), SLOT_EARS, TRUE) + H.equip_to_slot_or_del(new ears(H), ITEM_SLOT_EARS, TRUE) if(glasses) - H.equip_to_slot_or_del(new glasses(H), SLOT_GLASSES, TRUE) + H.equip_to_slot_or_del(new glasses(H), ITEM_SLOT_EYES, TRUE) if(id) - H.equip_to_slot_or_del(new id(H), SLOT_WEAR_ID, TRUE) + H.equip_to_slot_or_del(new id(H), ITEM_SLOT_ID, TRUE) if(suit_store) - H.equip_to_slot_or_del(new suit_store(H), SLOT_S_STORE, TRUE) + H.equip_to_slot_or_del(new suit_store(H), ITEM_SLOT_SUITSTORE, TRUE) if(undershirt) H.undershirt = initial(undershirt.name) @@ -195,9 +195,9 @@ if(!visualsOnly) // Items in pockets or backpack don't show up on mob's icon. if(l_pocket) - H.equip_to_slot_or_del(new l_pocket(H), SLOT_L_STORE, TRUE) + H.equip_to_slot_or_del(new l_pocket(H), ITEM_SLOT_LPOCKET, TRUE) if(r_pocket) - H.equip_to_slot_or_del(new r_pocket(H), SLOT_R_STORE, TRUE) + H.equip_to_slot_or_del(new r_pocket(H), ITEM_SLOT_RPOCKET, TRUE) if(box) if(!backpack_contents) @@ -211,7 +211,7 @@ if(!isnum(number))//Default to 1 number = 1 for(var/i in 1 to number) - H.equip_to_slot_or_del(new path(H), SLOT_IN_BACKPACK, TRUE) + H.equip_to_slot_or_del(new path(H), ITEM_SLOT_BACKPACK, TRUE) if(!H.head && toggle_helmet && istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit)) var/obj/item/clothing/suit/space/hardsuit/HS = H.wear_suit diff --git a/code/datums/progressbar.dm b/code/datums/progressbar.dm index c2e0d3c9d2..b3d7d2d633 100644 --- a/code/datums/progressbar.dm +++ b/code/datums/progressbar.dm @@ -1,67 +1,139 @@ #define PROGRESSBAR_HEIGHT 6 +#define PROGRESSBAR_ANIMATION_TIME 5 /datum/progressbar - var/goal = 1 + ///The progress bar visual element. var/image/bar - var/shown = 0 + ///The target where this progress bar is applied and where it is shown. + var/atom/bar_loc + ///The mob whose client sees the progress bar. var/mob/user - var/client/client - var/listindex + ///The client seeing the progress bar. + var/client/user_client + ///Effectively the number of steps the progress bar will need to do before reaching completion. + var/goal = 1 + ///Control check to see if the progress was interrupted before reaching its goal. + var/last_progress = 0 + ///Variable to ensure smooth visual stacking on multiple progress bars. + var/listindex = 0 + /datum/progressbar/New(mob/User, goal_number, atom/target) . = ..() if (!istype(target)) - CRASH("Invalid target given") - if (goal_number) - goal = goal_number - bar = image('icons/effects/progessbar.dmi', target, "prog_bar_0", HUD_LAYER) - bar.plane = HUD_PLANE + EXCEPTION("Invalid target given") + if(QDELETED(User) || !istype(User)) + stack_trace("/datum/progressbar created with [isnull(User) ? "null" : "invalid"] user") + qdel(src) + return + if(!isnum(goal_number)) + stack_trace("/datum/progressbar created with [isnull(User) ? "null" : "invalid"] goal_number") + qdel(src) + return + goal = goal_number + bar_loc = target + bar = image('icons/effects/progessbar.dmi', bar_loc, "prog_bar_0") + bar.plane = ABOVE_HUD_PLANE bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA user = User - if(user) - client = user.client - LAZYINITLIST(user.progressbars) - LAZYINITLIST(user.progressbars[bar.loc]) - var/list/bars = user.progressbars[bar.loc] - bars.Add(src) + LAZYADDASSOCLIST(user.progressbars, bar_loc, src) + var/list/bars = user.progressbars[bar_loc] listindex = bars.len - bar.pixel_y = 32 + (PROGRESSBAR_HEIGHT * (listindex - 1)) -/datum/progressbar/proc/update(progress) - if (!user || !user.client) - shown = 0 - return - if (user.client != client) - if (client) - client.images -= bar - if (user.client) - user.client.images += bar + if(user.client) + user_client = user.client + add_prog_bar_image_to_client() - progress = clamp(progress, 0, goal) - bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]" - if (!shown) - user.client.images += bar - shown = 1 - -/datum/progressbar/proc/shiftDown() - --listindex - bar.pixel_y -= PROGRESSBAR_HEIGHT + RegisterSignal(user, COMSIG_PARENT_QDELETING, .proc/on_user_delete) + RegisterSignal(user, COMSIG_MOB_CLIENT_LOGOUT, .proc/clean_user_client) + RegisterSignal(user, COMSIG_MOB_CLIENT_LOGIN, .proc/on_user_login) /datum/progressbar/Destroy() - for(var/I in user.progressbars[bar.loc]) - var/datum/progressbar/P = I - if(P != src && P.listindex > listindex) - P.shiftDown() + if(user) + for(var/pb in user.progressbars[bar_loc]) + var/datum/progressbar/progress_bar = pb + if(progress_bar == src || progress_bar.listindex <= listindex) + continue + progress_bar.listindex-- - var/list/bars = user.progressbars[bar.loc] - bars.Remove(src) - if(!bars.len) - LAZYREMOVE(user.progressbars, bar.loc) + progress_bar.bar.pixel_y = 32 + (PROGRESSBAR_HEIGHT * (progress_bar.listindex - 1)) + var/dist_to_travel = 32 + (PROGRESSBAR_HEIGHT * (progress_bar.listindex - 1)) - PROGRESSBAR_HEIGHT + animate(progress_bar.bar, pixel_y = dist_to_travel, time = PROGRESSBAR_ANIMATION_TIME, easing = SINE_EASING) - if (client) - client.images -= bar - qdel(bar) - . = ..() + LAZYREMOVEASSOC(user.progressbars, bar_loc, src) + user = null + if(user_client) + clean_user_client() + + bar_loc = null + + if(bar) + QDEL_NULL(bar) + + return ..() + + +///Called right before the user's Destroy() +/datum/progressbar/proc/on_user_delete(datum/source) + SIGNAL_HANDLER + + user.progressbars = null //We can simply nuke the list and stop worrying about updating other prog bars if the user itself is gone. + user = null + qdel(src) + + +///Removes the progress bar image from the user_client and nulls the variable, if it exists. +/datum/progressbar/proc/clean_user_client(datum/source) + SIGNAL_HANDLER + + if(!user_client) //Disconnected, already gone. + return + user_client.images -= bar + user_client = null + + +///Called by user's Login(), it transfers the progress bar image to the new client. +/datum/progressbar/proc/on_user_login(datum/source) + SIGNAL_HANDLER + + if(user_client) + if(user_client == user.client) //If this was not client handling I'd condemn this sanity check. But clients are fickle things. + return + clean_user_client() + if(!user.client) //Clients can vanish at any time, the bastards. + return + user_client = user.client + add_prog_bar_image_to_client() + + +///Adds a smoothly-appearing progress bar image to the player's screen. +/datum/progressbar/proc/add_prog_bar_image_to_client() + bar.pixel_y = 0 + bar.alpha = 0 + user_client.images += bar + animate(bar, pixel_y = 32 + (PROGRESSBAR_HEIGHT * (listindex - 1)), alpha = 255, time = PROGRESSBAR_ANIMATION_TIME, easing = SINE_EASING) + + +///Updates the progress bar image visually. +/datum/progressbar/proc/update(progress) + progress = clamp(progress, 0, goal) + if(progress == last_progress) + return + last_progress = progress + bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]" + + +///Called on progress end, be it successful or a failure. Wraps up things to delete the datum and bar. +/datum/progressbar/proc/end_progress() + if(last_progress != goal) + bar.icon_state = "[bar.icon_state]_fail" + + animate(bar, alpha = 0, time = PROGRESSBAR_ANIMATION_TIME) + + QDEL_IN(src, PROGRESSBAR_ANIMATION_TIME) + + +#undef PROGRESSBAR_ANIMATION_TIME #undef PROGRESSBAR_HEIGHT diff --git a/code/datums/radiation_wave.dm b/code/datums/radiation_wave.dm index 8dc3b64e16..ebb1f58a20 100644 --- a/code/datums/radiation_wave.dm +++ b/code/datums/radiation_wave.dm @@ -112,7 +112,7 @@ )) if(!can_contaminate || blacklisted[thing.type]) continue - if(CHECK_BITFIELD(thing.rad_flags, RAD_NO_CONTAMINATE) || SEND_SIGNAL(thing, COMSIG_ATOM_RAD_CONTAMINATING, strength) & COMPONENT_BLOCK_CONTAMINATION) + if((thing.rad_flags & RAD_NO_CONTAMINATE) || SEND_SIGNAL(thing, COMSIG_ATOM_RAD_CONTAMINATING, strength) & COMPONENT_BLOCK_CONTAMINATION) continue contam_atoms += thing var/did_contam = 0 diff --git a/code/datums/ruins/space.dm b/code/datums/ruins/space.dm index 64b8692ccd..7a57e50364 100644 --- a/code/datums/ruins/space.dm +++ b/code/datums/ruins/space.dm @@ -331,6 +331,12 @@ name = "Space Diner" description = "Come, traveler of the bluespace planes. Sit, enjoy a drink and take one of the fair maidens for a night. The exit is the way you came in, via that teleporter thingy, but do remember to stay safe." +/datum/map_template/ruin/space/suspicious + id = "helterskelter" + suffix = "skelter.dmm" + name = "Helter Skelter" + description = "You're looking mighty suspicious. Why don't you go and take a seat over in that driver?" + //Space ruins for the station z /datum/map_template/ruin/spacenearstation prefix = "_maps/RandomRuins/SpaceRuinsStation/" diff --git a/code/datums/ruins/station.dm b/code/datums/ruins/station.dm index 71cdf495e9..1910dc738c 100644 --- a/code/datums/ruins/station.dm +++ b/code/datums/ruins/station.dm @@ -55,6 +55,11 @@ suffix = "Box/Engine/budget.dmm" name = "Box P.A.C.M.A.N" +/datum/map_template/ruin/station/box/engine/rbmk + id = "engine_rbmk" + suffix = "Box/Engine/engine_rbmk.dmm" + name = "Box RBMK" + // Lavaland // Mining Base /datum/map_template/ruin/station/lavaland/mining_base diff --git a/code/datums/saymode.dm b/code/datums/saymode.dm index 3b6fae5aee..bd0537bac7 100644 --- a/code/datums/saymode.dm +++ b/code/datums/saymode.dm @@ -120,6 +120,17 @@ return FALSE return TRUE +/datum/saymode/statusdisplay + key = "q" + mode = MODE_STATUSDISPLAY + +/datum/saymode/statusdisplay/handle_message(mob/living/user, message, datum/language/language) + if(isAI(user)) + var/mob/living/silicon/ai/AI = user + AI.statusdisplay_talk(message, language) + return FALSE + return TRUE + /datum/saymode/monkey key = "k" mode = MODE_MONKEY diff --git a/code/datums/screentips/atom_context.dm b/code/datums/screentips/atom_context.dm new file mode 100644 index 0000000000..ae71d6f929 --- /dev/null +++ b/code/datums/screentips/atom_context.dm @@ -0,0 +1,25 @@ +/// Create a "Type-B" contextual screentip interaction, registering to `add_context()`. +/// This will run `add_context()` when the atom is hovered over by an item for context. +/// `add_context()` will *not* be called unless this is run. +/// This is not necessary for Type-B interactions, as you can just apply the flag and register to the signal yourself. +/atom/proc/register_context() + flags_1 |= HAS_CONTEXTUAL_SCREENTIPS_1 + RegisterSignal(src, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, .proc/add_context) + +/// Creates a "Type-B" contextual screentip interaction. +/// When a user hovers over this, this proc will be called in order +/// to provide context for contextual screentips. +/// You must call `register_context()` in order for this to be registered. +/// A screentip context list is a list that has context keys (SCREENTIP_CONTEXT_*, from __DEFINES/screentips.dm) +/// that map to the action as text. +/// If you mutate the list in this signal, you must return CONTEXTUAL_SCREENTIP_SET. +/// `source` can, in all cases, be replaced with `src`, and only exists because this proc directly connects to a signal. +/atom/proc/add_context( + atom/source, + list/context, + obj/item/held_item, + mob/living/user, +) + SIGNAL_HANDLER + + return NONE diff --git a/code/datums/screentips/item_context.dm b/code/datums/screentips/item_context.dm new file mode 100644 index 0000000000..239cd18683 --- /dev/null +++ b/code/datums/screentips/item_context.dm @@ -0,0 +1,29 @@ +/// Create a "Type-A" contextual screentip interaction, registering to `add_item_context()`. +/// This will run `add_item_context()` when the item hovers over another object for context. +/// `add_item_context()` will *not* be called unless this is run. +/// This is not necessary for Type-A interactions, as you can just apply the flag and register to the signal yourself. +/obj/item/proc/register_item_context() + item_flags |= ITEM_HAS_CONTEXTUAL_SCREENTIPS + RegisterSignal( + src, + COMSIG_ITEM_REQUESTING_CONTEXT_FOR_TARGET, + .proc/add_item_context, + ) + +/// Creates a "Type-A" contextual screentip interaction. +/// When a user hovers over something with this item in hand, this proc will be called in order +/// to provide context for contextual screentips. +/// You must call `register_item_context()` in order for this to be registered. +/// A screentip context list is a list that has context keys (SCREENTIP_CONTEXT_*, from __DEFINES/screentips.dm) +/// that map to the action as text. +/// If you mutate the list in this signal, you must return CONTEXTUAL_SCREENTIP_SET. +/// `source` can, in all cases, be replaced with `src`, and only exists because this proc directly connects to a signal. +/obj/item/proc/add_item_context( + obj/item/source, + list/context, + atom/target, + mob/living/user, +) + SIGNAL_HANDLER + + return NONE diff --git a/code/datums/screentips/screentips.dm b/code/datums/screentips/screentips.dm new file mode 100644 index 0000000000..94dedbeac9 --- /dev/null +++ b/code/datums/screentips/screentips.dm @@ -0,0 +1,40 @@ +#define HINT_ICON_FILE 'icons/UI_Icons/screentips/cursor_hints.dmi' + +/// Stores the cursor hint icons for screentip context. +GLOBAL_LIST_INIT_TYPED(screentip_context_icons, /image, prepare_screentip_context_icons()) + +/proc/prepare_screentip_context_icons() + var/list/output = list() + for(var/state in icon_states(HINT_ICON_FILE)) + output[state] = image(HINT_ICON_FILE, icon_state = state) + return output + +/* + * # Builds context with each intent for this key + * Args: + * - context = list (REQUIRED) + * - context[key] = list (REQUIRED) + * - key = string (REQUIRED) + * - allow_image = boolean (not required) +*/ +/proc/build_context(list/context, key, allow_image) + if(!length(context) || !length(context[key]) || !key) + return "" + var/list/to_add + for(var/intent in context[key]) + // Splits key combinations from mouse buttons. e.g. `Ctrl-Shift-LMB` goes in, `Ctrl-Shift-` goes out. Will be empty for single button actions. + var/key_combo = length(key) > 3 ? "[copytext(key, 1, -3)]" : "" + // Grab the mouse button, LMB/RMB+intent + var/button = "[copytext(key, -3)]-[intent]" + if(allow_image) + // Compile into image, if allowed + button = "\icon[GLOB.screentip_context_icons[button]]" + LAZYADD(to_add, "[key_combo][button][allow_image ? "" : ":"] [context[key][intent]]") + + // Prepare separator for same button but different intent + var/separator = "[allow_image ? " " : " / "]" + + // Voilá, final result + return to_add.Join(separator) + +#undef HINT_ICON_FILE diff --git a/code/datums/skills/modifiers/job.dm b/code/datums/skills/modifiers/job.dm index e751fbf120..5cf99f6138 100644 --- a/code/datums/skills/modifiers/job.dm +++ b/code/datums/skills/modifiers/job.dm @@ -35,5 +35,8 @@ /datum/skill_modifier/job/level/wiring/basic level_mod = JOB_SKILL_BASIC +/datum/skill_modifier/job/level/wiring/expert + level_mod = JOB_SKILL_EXPERT + /datum/skill_modifier/job/level/dwarfy/blacksmithing target_skills = /datum/skill/level/dwarfy/blacksmithing diff --git a/code/datums/station_traits/_station_trait.dm b/code/datums/station_traits/_station_trait.dm new file mode 100644 index 0000000000..5fbf8611d5 --- /dev/null +++ b/code/datums/station_traits/_station_trait.dm @@ -0,0 +1,57 @@ +///Base class of station traits. These are used to influence rounds in one way or the other by influencing the levers of the station. +/datum/station_trait + ///Name of the trait + var/name = "unnamed station trait" + ///The type of this trait. Used to classify how this trait influences the station + var/trait_type = STATION_TRAIT_NEUTRAL + ///Whether or not this trait uses process() + var/trait_processes = FALSE + ///Chance relative to other traits of its type to be picked + var/weight = 10 + ///Whether this trait is always enabled; generally used for debugging + var/force = FALSE + ///Does this trait show in the centcom report? + var/show_in_report = FALSE + ///What message to show in the centcom report? + var/report_message + ///What code-trait does this station trait give? gives none if null + var/trait_to_give + ///What traits are incompatible with this one? + var/blacklist + ///Extra flags for station traits such as it being abstract + var/trait_flags + /// Whether or not this trait can be reverted by an admin + var/can_revert = TRUE + +/datum/station_trait/New() + . = ..() + + RegisterSignal(SSticker, COMSIG_TICKER_ROUND_STARTING, .proc/on_round_start) + + if(trait_processes) + START_PROCESSING(SSstation, src) + if(trait_to_give) + ADD_TRAIT(SSstation, trait_to_give, STATION_TRAIT) + +/datum/station_trait/Destroy() + SSstation.station_traits -= src + return ..() + +/// Proc ran when round starts. Use this for roundstart effects. +/datum/station_trait/proc/on_round_start() + SIGNAL_HANDLER + return + +///type of info the centcom report has on this trait, if any. +/datum/station_trait/proc/get_report() + return "[name] - [report_message]" + +/// Will attempt to revert the station trait, used by admins. +/datum/station_trait/proc/revert() + if (!can_revert) + CRASH("revert() was called on [type], which can't be reverted!") + + if (trait_to_give) + REMOVE_TRAIT(SSstation, trait_to_give, STATION_TRAIT) + + qdel(src) diff --git a/code/datums/station_traits/admin_panel.dm b/code/datums/station_traits/admin_panel.dm new file mode 100644 index 0000000000..02eca48b54 --- /dev/null +++ b/code/datums/station_traits/admin_panel.dm @@ -0,0 +1,133 @@ +/// Opens the station traits admin panel +/datum/admins/proc/station_traits_panel() + set name = "Modify Station Traits" + set category = "Admin.Events" + + var/static/datum/station_traits_panel/station_traits_panel = new + station_traits_panel.ui_interact(usr) + +/datum/station_traits_panel + var/static/list/future_traits + +/datum/station_traits_panel/ui_data(mob/user) + var/list/data = list() + + data["too_late_to_revert"] = too_late_to_revert() + + var/list/current_station_traits = list() + for (var/datum/station_trait/station_trait as anything in SSstation.station_traits) + current_station_traits += list(list( + "name" = station_trait.name, + "can_revert" = station_trait.can_revert, + "ref" = REF(station_trait), + )) + + data["current_traits"] = current_station_traits + data["future_station_traits"] = future_traits + + return data + +/datum/station_traits_panel/ui_static_data(mob/user) + var/list/data = list() + + var/list/valid_station_traits = list() + + for (var/datum/station_trait/station_trait_path as anything in subtypesof(/datum/station_trait)) + valid_station_traits += list(list( + "name" = initial(station_trait_path.name), + "path" = station_trait_path, + )) + + data["valid_station_traits"] = valid_station_traits + + return data + +/datum/station_traits_panel/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if (.) + return + + switch (action) + if ("revert") + var/ref = params["ref"] + if (!ref) + return TRUE + + var/datum/station_trait/station_trait = locate(ref) + + if (!istype(station_trait)) + return TRUE + + if (too_late_to_revert()) + to_chat(usr, span_warning("It's too late to revert station traits, the round has already started!")) + return TRUE + + if (!station_trait.can_revert) + stack_trace("[station_trait.type] can't be reverted, but was requested anyway.") + return TRUE + + var/message = "[key_name(usr)] reverted the station trait [station_trait.name] ([station_trait.type])" + log_admin(message) + message_admins(message) + + station_trait.revert() + + return TRUE + if ("setup_future_traits") + if (too_late_for_future_traits()) + to_chat(usr, span_warning("It's too late to add future station traits, the round is already over!")) + return TRUE + + var/list/new_future_traits = list() + var/list/station_trait_names = list() + + for (var/station_trait_text in params["station_traits"]) + var/datum/station_trait/station_trait_path = text2path(station_trait_text) + if (!ispath(station_trait_path, /datum/station_trait) || station_trait_path == /datum/station_trait) + log_admin("[key_name(usr)] tried to set an invalid future station trait: [station_trait_text]") + to_chat(usr, span_warning("Invalid future station trait: [station_trait_text]")) + return TRUE + + station_trait_names += initial(station_trait_path.name) + + new_future_traits += list(list( + "name" = initial(station_trait_path.name), + "path" = station_trait_path, + )) + + var/message = "[key_name(usr)] has prepared the following station traits for next round: [station_trait_names.Join(", ") || "None"]" + log_admin(message) + message_admins(message) + + future_traits = new_future_traits + rustg_file_write(json_encode(params["station_traits"]), FUTURE_STATION_TRAITS_FILE) + + return TRUE + if ("clear_future_traits") + if (!future_traits) + to_chat(usr, span_warning("There are no future station traits.")) + return TRUE + + var/message = "[key_name(usr)] has cleared the station traits for next round." + log_admin(message) + message_admins(message) + + fdel(FUTURE_STATION_TRAITS_FILE) + future_traits = null + + return TRUE + +/datum/station_traits_panel/proc/too_late_for_future_traits() + return SSticker.current_state >= GAME_STATE_FINISHED + +/datum/station_traits_panel/proc/too_late_to_revert() + return SSticker.current_state >= GAME_STATE_PLAYING + +/datum/station_traits_panel/ui_status(mob/user, datum/ui_state/state) + return check_rights_for(user.client, R_FUN) ? UI_INTERACTIVE : UI_CLOSE + +/datum/station_traits_panel/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "StationTraitsPanel") + ui.open() diff --git a/code/datums/station_traits/negative_traits.dm b/code/datums/station_traits/negative_traits.dm new file mode 100644 index 0000000000..c24d93865c --- /dev/null +++ b/code/datums/station_traits/negative_traits.dm @@ -0,0 +1,287 @@ +/datum/station_trait/carp_infestation + name = "Carp infestation" + trait_type = STATION_TRAIT_NEGATIVE + weight = 5 + show_in_report = TRUE + report_message = "Dangerous fauna is present in the area of this station." + trait_to_give = STATION_TRAIT_CARP_INFESTATION + +/datum/station_trait/distant_supply_lines + name = "Distant supply lines" + trait_type = STATION_TRAIT_NEGATIVE + weight = 3 + show_in_report = TRUE + report_message = "Due to the distance to our normal supply lines, cargo orders are more expensive." + blacklist = list(/datum/station_trait/strong_supply_lines) + +/datum/station_trait/distant_supply_lines/on_round_start() + SSeconomy.pack_price_modifier *= 1.2 + +/datum/station_trait/late_arrivals + name = "Late Arrivals" + trait_type = STATION_TRAIT_NEGATIVE + weight = 2 + show_in_report = TRUE + report_message = "Sorry for that, we didn't expect to fly into that vomiting goose while bringing you to your new station." + trait_to_give = STATION_TRAIT_LATE_ARRIVALS + blacklist = list(/datum/station_trait/random_spawns, /datum/station_trait/hangover) + +/datum/station_trait/random_spawns + name = "Drive-by landing" + trait_type = STATION_TRAIT_NEGATIVE + weight = 2 + show_in_report = TRUE + report_message = "Sorry for that, we missed your station by a few miles, so we just launched you towards your station in pods. Hope you don't mind!" + trait_to_give = STATION_TRAIT_RANDOM_ARRIVALS + blacklist = list(/datum/station_trait/late_arrivals, /datum/station_trait/hangover) + +/datum/station_trait/hangover + name = "Hangover" + trait_type = STATION_TRAIT_NEGATIVE + weight = 0 + show_in_report = TRUE + report_message = "Ohh....Man....That mandatory office party from last shift...God that was awesome..I woke up in some random toilet 3 sectors away..." + trait_to_give = STATION_TRAIT_HANGOVER + blacklist = list(/datum/station_trait/late_arrivals, /datum/station_trait/random_spawns) + +/datum/station_trait/hangover/New() + . = ..() + RegisterSignal(SSdcs, COMSIG_GLOB_JOB_AFTER_LATEJOIN_SPAWN, .proc/on_job_after_spawn) + +/datum/station_trait/hangover/revert() + for (var/obj/effect/landmark/start/hangover/hangover_spot in GLOB.start_landmarks_list) + QDEL_LIST(hangover_spot.debris) + + return ..() + +/datum/station_trait/hangover/proc/on_job_after_spawn(datum/source, datum/job/job, mob/living/spawned_mob) + SIGNAL_HANDLER + + if(prob(65)) // most aren't hungover + return + if(!iscarbon(spawned_mob)) // don't want silicons or similar to be counted here + return + if(HAS_TRAIT(spawned_mob, TRAIT_ROBOTIC_ORGANISM)) // robots can't get hungover + return + if(HAS_TRAIT(spawned_mob, TRAIT_TOXIC_ALCOHOL)) // people with alcohol intolerance also can't + return + var/obj/item/hat = pick( + /obj/item/clothing/head/sombrero, + /obj/item/clothing/head/fedora, + /obj/item/clothing/mask/balaclava, + /obj/item/clothing/head/ushanka, + /obj/item/clothing/head/cardborg, + /obj/item/clothing/head/pirate, + /obj/item/clothing/head/cone, + ) + hat = new hat(spawned_mob) + spawned_mob.equip_to_slot_or_del(hat, ITEM_SLOT_HEAD) + + +/datum/station_trait/blackout + name = "Blackout" + trait_type = STATION_TRAIT_NEGATIVE + weight = 3 + show_in_report = TRUE + report_message = "Station lights seem to be damaged, be safe when starting your shift today." + +/datum/station_trait/blackout/on_round_start() + . = ..() + for(var/obj/machinery/power/apc/apc as anything in GLOB.apcs_list) + if(is_station_level(apc.z) && prob(60)) + apc.overload_lighting() + +/datum/station_trait/empty_maint + name = "Cleaned out maintenance" + trait_type = STATION_TRAIT_NEGATIVE + weight = 5 + show_in_report = TRUE + report_message = "Our workers cleaned out most of the junk in the maintenace areas." + blacklist = list(/datum/station_trait/filled_maint) + trait_to_give = STATION_TRAIT_EMPTY_MAINT + + // This station trait is checked when loot drops initialize, so it's too late + can_revert = FALSE + +/datum/station_trait/overflow_job_bureaucracy + name = "Overflow bureaucracy mistake" + trait_type = STATION_TRAIT_NEGATIVE + weight = 4 + show_in_report = TRUE + var/chosen_job_name + +/datum/station_trait/overflow_job_bureaucracy/New() + . = ..() + RegisterSignal(SSjob, COMSIG_SUBSYSTEM_POST_INITIALIZE, .proc/set_overflow_job_override) + +/datum/station_trait/overflow_job_bureaucracy/get_report() + return "[name] - It seems for some reason we put out the wrong job-listing for the overflow role this shift...I hope you like [chosen_job_name]s." + +/datum/station_trait/overflow_job_bureaucracy/proc/set_overflow_job_override(datum/source) + SIGNAL_HANDLER + var/datum/job/picked_job = pick(get_all_jobs()) + chosen_job_name = lowertext(picked_job.title) // like Chief Engineers vs like chief engineers + SSjob.set_overflow_role(picked_job.type) + +/datum/station_trait/slow_shuttle + name = "Slow Shuttle" + trait_type = STATION_TRAIT_NEGATIVE + weight = 5 + show_in_report = TRUE + report_message = "Due to distance to our supply station, the cargo shuttle will have a slower flight time to your cargo department." + blacklist = list(/datum/station_trait/quick_shuttle) + +/datum/station_trait/slow_shuttle/on_round_start() + . = ..() + SSshuttle.supply.callTime *= 1.5 + +/datum/station_trait/bot_languages + name = "Bot Language Matrix Malfunction" + trait_type = STATION_TRAIT_NEGATIVE + weight = 3 + show_in_report = TRUE + report_message = "Your station's friendly bots have had their language matrix fried due to an event, resulting in some strange and unfamiliar speech patterns." + +/datum/station_trait/bot_languages/New() + . = ..() + /// What "caused" our robots to go haywire (fluff) + var/event_source = pick(list("an ion storm", "a syndicate hacking attempt", "a malfunction", "issues with your onboard AI", "an intern's mistakes", "budget cuts")) + report_message = "Your station's friendly bots have had their language matrix fried due to [event_source], resulting in some strange and unfamiliar speech patterns." + +/datum/station_trait/bot_languages/on_round_start() + . = ..() + //All bots that exist round start have their set language randomized. + for(var/mob/living/simple_animal/bot/found_bot in GLOB.alive_mob_list) + /// The bot's language holder - so we can randomize and change their language + var/datum/language_holder/bot_languages = found_bot.get_language_holder() + bot_languages.selected_language = bot_languages.get_random_spoken_language() + +/datum/station_trait/revenge_of_pun_pun + name = "Revenge of Pun Pun" + trait_type = STATION_TRAIT_NEGATIVE + weight = 2 + + // Way too much is done on atoms SS to be reverted, and it'd look + // kinda clunky on round start. It's not impossible to make this work, + // but it's a project for...someone else. + can_revert = FALSE + + var/static/list/weapon_types + +/datum/station_trait/revenge_of_pun_pun/New() + if(!weapon_types) + weapon_types = list( + /obj/item/chair = 25, + /obj/item/tailclub = 15, + /obj/item/melee/baseball_bat = 10, + /obj/item/melee/chainofcommand/tailwhip = 15, + /obj/item/melee/chainofcommand/tailwhip/kitty = 15, + /obj/item/reagent_containers/food/drinks/bottle = 25, + /obj/item/gun/ballistic/automatic/pistol = 1, + ) + + RegisterSignal(SSatoms, COMSIG_SUBSYSTEM_POST_INITIALIZE, .proc/arm_monke) + +/datum/station_trait/revenge_of_pun_pun/proc/arm_monke() + SIGNAL_HANDLER + var/mob/living/carbon/monkey/punpun = locate() + if(!punpun) + return + var/weapon_type = pickweight(weapon_types) + var/obj/item/weapon = new weapon_type + if(!punpun.put_in_l_hand(weapon) && !punpun.put_in_r_hand(weapon)) + // Guess they did all this with whatever they have in their hands already + qdel(weapon) + weapon = punpun.get_active_held_item() || punpun.get_inactive_held_item() + + weapon?.add_mob_blood(punpun) + punpun.add_mob_blood(punpun) + + punpun.aggressive = TRUE + + var/area/place = get_area(punpun) + + var/list/area_open_turfs = list() + for(var/turf/location in place) + if(location.density) + continue + area_open_turfs += location + + punpun.forceMove(pick(area_open_turfs)) + + for(var/i in 1 to rand(10, 40)) + new /obj/effect/decal/cleanable/blood(pick(area_open_turfs)) + + var/list/blood_path = list() + for(var/i in 1 to 10) // Only 10 attempts + var/turf/destination = pick(area_open_turfs) + var/turf/next_step = get_step_to(punpun, destination) + for(var/k in 1 to 30) // Max 30 steps + if(!next_step) + break + blood_path += next_step + next_step = get_step_to(next_step, destination) + if(length(blood_path)) + break + if(!length(blood_path)) + CRASH("Unable to make a path from punpun") + + var/turf/last_location + for(var/turf/location as anything in blood_path) + last_location = location + + if(prob(80)) + new /obj/effect/decal/cleanable/blood(location) + + if(prob(50)) + var/static/blood_types = list( + /obj/effect/decal/cleanable/blood/splatter, + /obj/effect/decal/cleanable/blood/gibs, + ) + var/blood_type = pick(blood_types) + new blood_type(get_turf(pick(orange(location, 2)))) + + new /obj/effect/decal/cleanable/blood/gibs/torso(last_location) + +// Abstract station trait used for traits that modify a random event in some way (their weight or max occurrences). +/datum/station_trait/random_event_weight_modifier + name = "Random Event Modifier" + report_message = "A random event has been modified this shift! Someone forgot to set this!" + show_in_report = TRUE + trait_flags = STATION_TRAIT_ABSTRACT + weight = 0 + + /// The path to the round_event_control that we modify. + var/event_control_path + /// Multiplier applied to the weight of the event. + var/weight_multiplier = 1 + /// Flat modifier added to the amount of max occurances the random event can have. + var/max_occurrences_modifier = 0 + +/datum/station_trait/random_event_weight_modifier/on_round_start() + . = ..() + var/datum/round_event_control/modified_event = locate(event_control_path) in SSevents.control + if(!modified_event) + CRASH("[type] could not find a round event controller to modify on round start (likely has an invalid event_control_path set)!") + + modified_event.weight *= weight_multiplier + modified_event.max_occurrences += max_occurrences_modifier + +/datum/station_trait/random_event_weight_modifier/ion_storms + name = "Ionic Stormfront" + report_message = "An ionic stormfront is passing over your station's system. Expect an increased likelihood of ion storms afflicting your station's silicon units." + trait_type = STATION_TRAIT_NEGATIVE + trait_flags = NONE + weight = 3 + event_control_path = /datum/round_event_control/ion_storm + weight_multiplier = 2 + +/datum/station_trait/random_event_weight_modifier/rad_storms + name = "Radiation Stormfront" + report_message = "A radioactive stormfront is passing through your station's system. Expect an increased likelihood of radiation storms passing over your station, as well the potential for multiple radiation storms to occur during your shift." + trait_type = STATION_TRAIT_NEGATIVE + trait_flags = NONE + weight = 2 + event_control_path = /datum/round_event_control/radiation_storm + weight_multiplier = 1.5 + max_occurrences_modifier = 2 diff --git a/code/datums/station_traits/neutral_traits.dm b/code/datums/station_traits/neutral_traits.dm new file mode 100644 index 0000000000..1f7e040e97 --- /dev/null +++ b/code/datums/station_traits/neutral_traits.dm @@ -0,0 +1,171 @@ +/datum/station_trait/bananium_shipment + name = "Bananium Shipment" + trait_type = STATION_TRAIT_NEUTRAL + weight = 5 + report_message = "Rumors has it that the clown planet has been sending support packages to clowns in this system" + trait_to_give = STATION_TRAIT_BANANIUM_SHIPMENTS + +/datum/station_trait/unnatural_atmosphere + name = "Unnatural atmospherical properties" + trait_type = STATION_TRAIT_NEUTRAL + weight = 5 + show_in_report = TRUE + report_message = "System's local planet has irregular atmospherical properties" + trait_to_give = STATION_TRAIT_UNNATURAL_ATMOSPHERE + + // This station trait modifies the atmosphere, which is too far past the time admins are able to revert it + can_revert = FALSE + +/datum/station_trait/unique_ai + name = "Unique AI" + trait_type = STATION_TRAIT_NEUTRAL + weight = 5 + show_in_report = TRUE + report_message = "For experimental purposes, this station AI might show divergence from default lawset. Do not meddle with this experiment." + trait_to_give = STATION_TRAIT_UNIQUE_AI + +/datum/station_trait/ian_adventure + name = "Ian's Adventure" + trait_type = STATION_TRAIT_NEUTRAL + weight = 5 + show_in_report = FALSE + report_message = "Ian has gone exploring somewhere in the station." + +/datum/station_trait/ian_adventure/on_round_start() + for(var/mob/living/simple_animal/pet/dog/corgi/dog in GLOB.mob_list) + if(!(istype(dog, /mob/living/simple_animal/pet/dog/corgi/Ian) || istype(dog, /mob/living/simple_animal/pet/dog/corgi/puppy))) + continue + + // Makes this station trait more interesting. Ian probably won't go anywhere without a little external help. + // Also gives him a couple extra lives to survive eventual tiders. + dog.AddComponent(/datum/component/twitch_plays/simple_movement/auto, 3 SECONDS) + dog.AddComponent(/datum/component/multiple_lives, 2) + RegisterSignal(dog, COMSIG_ON_MULTIPLE_LIVES_RESPAWN, .proc/do_corgi_respawn) + + // The extended safety checks at time of writing are about chasms and lava + // if there are any chasms and lava on stations in the future, woah + var/turf/current_turf = get_turf(dog) + var/turf/adventure_turf = find_safe_turf(extended_safety_checks = TRUE, dense_atoms = FALSE) + + // Poof! + do_smoke(location=current_turf) + dog.forceMove(adventure_turf) + do_smoke(location=adventure_turf) + +/// Moves the new dog somewhere safe, equips it with the old one's inventory and makes it deadchat_playable. +/datum/station_trait/ian_adventure/proc/do_corgi_respawn(mob/living/simple_animal/pet/dog/corgi/old_dog, mob/living/simple_animal/pet/dog/corgi/new_dog, gibbed, lives_left) + SIGNAL_HANDLER + + var/turf/current_turf = get_turf(new_dog) + var/turf/adventure_turf = find_safe_turf(extended_safety_checks = TRUE, dense_atoms = FALSE) + + do_smoke(location=current_turf) + new_dog.forceMove(adventure_turf) + do_smoke(location=adventure_turf) + + if(old_dog.inventory_back) + var/obj/item/old_dog_back = old_dog.inventory_back + old_dog.inventory_back = null + old_dog_back.forceMove(new_dog) + new_dog.inventory_back = old_dog_back + + if(old_dog.inventory_head) + var/obj/item/old_dog_hat = old_dog.inventory_head + old_dog.inventory_head = null + new_dog.place_on_head(old_dog_hat) + + new_dog.update_corgi_fluff() + new_dog.regenerate_icons() + new_dog.AddComponent(/datum/component/twitch_plays/simple_movement/auto, 3 SECONDS) + if(lives_left) + RegisterSignal(new_dog, COMSIG_ON_MULTIPLE_LIVES_RESPAWN, .proc/do_corgi_respawn) + + if(!gibbed) //The old dog will now disappear so we won't have more than one Ian at a time. + qdel(old_dog) + +/datum/station_trait/glitched_pdas + name = "PDA glitch" + trait_type = STATION_TRAIT_NEUTRAL + weight = 15 + show_in_report = TRUE + report_message = "Something seems to be wrong with the PDAs issued to you all this shift. Nothing too bad though." + trait_to_give = STATION_TRAIT_PDA_GLITCHED + +/datum/station_trait/announcement_intern + name = "Announcement Intern" + trait_type = STATION_TRAIT_NEUTRAL + weight = 1 + show_in_report = TRUE + report_message = "Please be nice to him." + blacklist = list(/datum/station_trait/announcement_medbot) + +/datum/station_trait/announcement_intern/New() + . = ..() + SSstation.announcer = /datum/centcom_announcer/intern + +/datum/station_trait/announcement_medbot + name = "Announcement \"System\"" + trait_type = STATION_TRAIT_NEUTRAL + weight = 1 + show_in_report = TRUE + report_message = "Our announcement system is under scheduled maintanance at the moment. Thankfully, we have a backup." + blacklist = list(/datum/station_trait/announcement_intern) + +/datum/station_trait/announcement_medbot/New() + . = ..() + SSstation.announcer = /datum/centcom_announcer/medbot + +/datum/station_trait/randomizing_station_name + name = "Randomizing station name" + show_in_report = TRUE + report_message = "Due to legal reasons or other, we might not be able to settle on a station name." + trait_processes = TRUE + COOLDOWN_DECLARE(randomizing_cooldown) + var/trigger_every = 30 MINUTES + blacklist = list(/datum/station_trait/randomizing_station_name/fast, /datum/station_trait/randomizing_station_name/slow) + +/datum/station_trait/randomizing_station_name/on_round_start() + . = ..() + COOLDOWN_START(src, randomizing_cooldown, trigger_every) + +/datum/station_trait/randomizing_station_name/process(delta_time) + if(!COOLDOWN_FINISHED(src, randomizing_cooldown)) + return + + COOLDOWN_START(src, randomizing_cooldown, trigger_every) + + var/new_name = new_station_name() + + var/centcom_announcement = pick(CONFIG_GET(str_list/randomizing_station_name_message)) + + // Replace with CURRENT station name + centcom_announcement = replacetext(centcom_announcement, "%CURRENT_STATION_NAME%", station_name()) + + // Replace with NEW station name + centcom_announcement = replacetext(centcom_announcement, "%NEW_STATION_NAME%", new_name) + + // Take a CREWMEMBER's name for the goofs + if(findtext(centcom_announcement, "%RANDOM_CREWMEMBER%")) + var/crewmember = locate(/mob/living/carbon/human) in GLOB.alive_mob_list + if(!crewmember) + crewmember = random_unique_name() + centcom_announcement = replacetext(centcom_announcement, "%RANDOM_CREWMEMBER%", crewmember) + + // Replace with a completely RANDOM name + if(findtext(centcom_announcement, "%RANDOM_NAME%")) + var/name = random_unique_name() + centcom_announcement = replacetext(centcom_announcement, "%RANDOM_NAME%", name) + + set_station_name(new_name) + + priority_announce(centcom_announcement) + +/datum/station_trait/randomizing_station_name/fast + name = "Randomizing station name - Fast" + trigger_every = 15 MINUTES + blacklist = list(/datum/station_trait/randomizing_station_name, /datum/station_trait/randomizing_station_name/slow) + +/datum/station_trait/randomizing_station_name/slow + name = "Randomizing station name - Slow" + trigger_every = 1 HOURS + blacklist = list(/datum/station_trait/randomizing_station_name/fast, /datum/station_trait/randomizing_station_name) diff --git a/code/datums/station_traits/positive_traits.dm b/code/datums/station_traits/positive_traits.dm new file mode 100644 index 0000000000..abe5a3a0e9 --- /dev/null +++ b/code/datums/station_traits/positive_traits.dm @@ -0,0 +1,279 @@ +#define PARTY_COOLDOWN_LENGTH_MIN 6 MINUTES +#define PARTY_COOLDOWN_LENGTH_MAX 12 MINUTES + + +/datum/station_trait/lucky_winner + name = "Lucky winner" + trait_type = STATION_TRAIT_POSITIVE + weight = 1 + show_in_report = TRUE + report_message = "Your station has won the grand prize of the annual station charity event. Free snacks will be delivered to the bar every now and then." + trait_processes = TRUE + COOLDOWN_DECLARE(party_cooldown) + +/datum/station_trait/lucky_winner/on_round_start() + . = ..() + COOLDOWN_START(src, party_cooldown, rand(PARTY_COOLDOWN_LENGTH_MIN, PARTY_COOLDOWN_LENGTH_MAX)) + +/datum/station_trait/lucky_winner/process(delta_time) + if(!COOLDOWN_FINISHED(src, party_cooldown)) + return + + COOLDOWN_START(src, party_cooldown, rand(PARTY_COOLDOWN_LENGTH_MIN, PARTY_COOLDOWN_LENGTH_MAX)) + + var/area/area_to_spawn_in = pick(GLOB.bar_areas) + var/turf/T = pick(area_to_spawn_in.contents) + + var/obj/structure/closet/supplypod/centcompod/toLaunch = new() + var/obj/item/pizzabox/pizza_to_spawn = pick(list(/obj/item/pizzabox/margherita, /obj/item/pizzabox/mushroom, /obj/item/pizzabox/meat, /obj/item/pizzabox/vegetable, /obj/item/pizzabox/pineapple)) + new pizza_to_spawn(toLaunch) + for(var/i in 1 to 6) + if(prob(50)) + new /obj/item/reagent_containers/food/drinks/beer(toLaunch) + else + for(var/m in 1 to 2) + var/obj/item/soda_to_spawn = pick(list(/obj/item/reagent_containers/food/drinks/soda_cans/sol_dry, + /obj/item/reagent_containers/food/drinks/soda_cans/space_up, + /obj/item/reagent_containers/food/drinks/soda_cans/starkist, + /obj/item/reagent_containers/food/drinks/soda_cans/cola, + /obj/item/reagent_containers/food/drinks/soda_cans/space_mountain_wind, + /obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb, + /obj/item/reagent_containers/food/drinks/soda_cans/pwr_game)) + new soda_to_spawn(toLaunch) + new /obj/effect/pod_landingzone(T, toLaunch) + +/datum/station_trait/galactic_grant + name = "Galactic grant" + trait_type = STATION_TRAIT_POSITIVE + weight = 6 + show_in_report = TRUE + report_message = "Your station has been selected for a special grant. Some extra funds has been made available to your cargo department." + +/datum/station_trait/galactic_grant/on_round_start() + var/datum/bank_account/cargo_bank = SSeconomy.get_dep_account(ACCOUNT_CAR) + cargo_bank.adjust_money(rand(2000, 5000)) + +/datum/station_trait/premium_internals_box + name = "Premium internals boxes" + trait_type = STATION_TRAIT_POSITIVE + weight = 10 + show_in_report = TRUE + report_message = "The internals boxes for your crew have been filled with bonus equipment." + trait_to_give = STATION_TRAIT_PREMIUM_INTERNALS + +/datum/station_trait/bountiful_bounties + name = "Bountiful bounties" + trait_type = STATION_TRAIT_POSITIVE + weight = 5 + show_in_report = TRUE + report_message = "It seems collectors in this system are extra keen to on bounties, and will pay more to see their completion." + +/datum/station_trait/bountiful_bounties/on_round_start() + SSeconomy.bounty_modifier *= 1.2 + +/datum/station_trait/strong_supply_lines + name = "Strong supply lines" + trait_type = STATION_TRAIT_POSITIVE + weight = 5 + show_in_report = TRUE + report_message = "Prices are low in this system, BUY BUY BUY!" + blacklist = list(/datum/station_trait/distant_supply_lines) + + +/datum/station_trait/strong_supply_lines/on_round_start() + SSeconomy.pack_price_modifier *= 0.8 + +/datum/station_trait/scarves + name = "Scarves" + trait_type = STATION_TRAIT_POSITIVE + weight = 5 + show_in_report = TRUE + var/list/scarves + +/datum/station_trait/scarves/New() + . = ..() + report_message = pick( + "Nanotrasen is experimenting with seeing if neck warmth improves employee morale.", + "After Space Fashion Week, scarves are the hot new accessory.", + "Everyone was simultaneously a little bit cold when they packed to go to the station.", + "The station is definitely not under attack by neck grappling aliens masquerading as wool. Definitely not.", + "You all get free scarves. Don't ask why.", + "A shipment of scarves was delivered to the station.", + ) + scarves = typesof(/obj/item/clothing/neck/scarf) + list( + /obj/item/clothing/neck/stripedredscarf, + /obj/item/clothing/neck/stripedgreenscarf, + /obj/item/clothing/neck/stripedbluescarf, + ) + + scarves -= /obj/item/clothing/neck/scarf/zomb // donator snowflake code--mayhaps we should make a glob for this or similar + + RegisterSignal(SSdcs, COMSIG_GLOB_JOB_AFTER_SPAWN, .proc/on_job_after_spawn) + + +/datum/station_trait/scarves/proc/on_job_after_spawn(datum/source, datum/job/job, mob/living/spawned, client/player_client) + SIGNAL_HANDLER + var/scarf_type = pick(scarves) + + spawned.equip_to_slot_or_del(new scarf_type(spawned), ITEM_SLOT_NECK) + + +/datum/station_trait/filled_maint + name = "Filled up maintenance" + trait_type = STATION_TRAIT_POSITIVE + weight = 5 + show_in_report = TRUE + report_message = "Our workers accidentaly forgot more of their personal belongings in the maintenace areas." + blacklist = list(/datum/station_trait/empty_maint) + trait_to_give = STATION_TRAIT_FILLED_MAINT + + // This station trait is checked when loot drops initialize, so it's too late + can_revert = FALSE + +/datum/station_trait/quick_shuttle + name = "Quick Shuttle" + trait_type = STATION_TRAIT_POSITIVE + weight = 6 + show_in_report = TRUE + report_message = "Due to proximity to our supply station, the cargo shuttle will have a quicker flight time to your cargo department." + blacklist = list(/datum/station_trait/slow_shuttle) + +/datum/station_trait/quick_shuttle/on_round_start() + . = ..() + SSshuttle.supply.callTime *= 0.5 + +/datum/station_trait/deathrattle_department + name = "deathrattled department" + trait_type = STATION_TRAIT_POSITIVE + show_in_report = TRUE + trait_flags = STATION_TRAIT_ABSTRACT + blacklist = list(/datum/station_trait/deathrattle_all) + + var/department_head + var/department_name = "department" + var/datum/deathrattle_group/deathrattle_group + +/datum/station_trait/deathrattle_department/New() + . = ..() + deathrattle_group = new("[department_name] group") + blacklist += subtypesof(/datum/station_trait/deathrattle_department) - type //All but ourselves + report_message = "All members of [department_name] have received an implant to notify each other if one of them dies. This should help improve job-safety!" + RegisterSignal(SSdcs, COMSIG_GLOB_JOB_AFTER_SPAWN, .proc/on_job_after_spawn) + + +/datum/station_trait/deathrattle_department/proc/on_job_after_spawn(datum/source, datum/job/job, mob/living/spawned, client/player_client) + SIGNAL_HANDLER + + if(department_head != job.title && !(src.department_head in job.department_head)) + return + + var/obj/item/implant/deathrattle/implant_to_give = new() + deathrattle_group.register(implant_to_give) + implant_to_give.implant(spawned, spawned, TRUE, TRUE) + + +/datum/station_trait/deathrattle_department/service + name = "Deathrattled Service" + trait_flags = NONE + weight = 1 + department_head = "Head of Personnel" + department_name = "Service" + +/datum/station_trait/deathrattle_department/cargo + name = "Deathrattled Cargo" + trait_flags = NONE + weight = 2 + department_head = "Quartermaster" + department_name = "Cargo" + +/datum/station_trait/deathrattle_department/engineering + name = "Deathrattled Engineering" + trait_flags = NONE + weight = 2 + department_head = "Chief Engineer" + department_name = "Engineering" + +/datum/station_trait/deathrattle_department/command + name = "Deathrattled Command" + trait_flags = NONE + weight = 1 + department_head = "Captain" + department_name = "Command" + +/datum/station_trait/deathrattle_department/science + name = "Deathrattled Science" + trait_flags = NONE + weight = 1 + department_head = "Research Director" + department_name = "Science" + +/datum/station_trait/deathrattle_department/security + name = "Deathrattled Security" + trait_flags = NONE + weight = 1 + department_head = "Head of Security" + department_name = "Security" + +/datum/station_trait/deathrattle_department/medical + name = "Deathrattled Medical" + trait_flags = NONE + weight = 1 + department_head = "Chief Medical Officer" + department_name = "Medical" + +/datum/station_trait/deathrattle_all + name = "Deathrattled Station" + trait_type = STATION_TRAIT_POSITIVE + show_in_report = TRUE + weight = 1 + report_message = "All members of the station have received an implant to notify each other if one of them dies. This should help improve job-safety!" + var/datum/deathrattle_group/deathrattle_group + + +/datum/station_trait/deathrattle_all/New() + . = ..() + deathrattle_group = new("station group") + blacklist = subtypesof(/datum/station_trait/deathrattle_department) + RegisterSignal(SSdcs, COMSIG_GLOB_JOB_AFTER_SPAWN, .proc/on_job_after_spawn) + + +/datum/station_trait/deathrattle_all/proc/on_job_after_spawn(datum/source, datum/job/job, mob/living/spawned, client/player_client) + SIGNAL_HANDLER + + var/obj/item/implant/deathrattle/implant_to_give = new() + deathrattle_group.register(implant_to_give) + implant_to_give.implant(spawned, spawned, TRUE, TRUE) + + +/datum/station_trait/wallets + name = "Wallets!" + trait_type = STATION_TRAIT_POSITIVE + show_in_report = TRUE + weight = 10 + report_message = "It has become temporarily fashionable to use a wallet, so everyone on the station has been issued one." + +/datum/station_trait/wallets/New() + . = ..() + RegisterSignal(SSdcs, COMSIG_GLOB_JOB_AFTER_SPAWN, .proc/on_job_after_spawn) + +/datum/station_trait/wallets/proc/on_job_after_spawn(datum/source, datum/job/job, mob/living/living_mob, mob/M, joined_late) + SIGNAL_HANDLER + + var/obj/item/card/id/id_card = living_mob.get_item_by_slot(ITEM_SLOT_ID) + if(!istype(id_card)) + return + + living_mob.temporarilyRemoveItemFromInventory(id_card, force=TRUE) + + // "Doc, what's wrong with me?" + var/obj/item/storage/wallet/wallet = new(src) + // "You've got a wallet embedded in your chest." + wallet.add_fingerprint(living_mob, ignoregloves = TRUE) + + living_mob.equip_to_slot_if_possible(wallet, ITEM_SLOT_ID) + + id_card.forceMove(wallet) + + // Put our filthy fingerprints all over the contents + for(var/obj/item/item in wallet) + item.add_fingerprint(living_mob, ignoregloves = TRUE) diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index ae05134b56..77638d157b 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -69,7 +69,7 @@ ..() /datum/status_effect/vanguard_shield/Destroy() - qdel(progbar) + progbar.end_progress() progbar = null return ..() @@ -578,8 +578,12 @@ /datum/status_effect/regenerative_core/on_apply() . = ..() ADD_TRAIT(owner, TRAIT_IGNOREDAMAGESLOWDOWN, "regenerative_core") - - if(HAS_TRAIT(owner, TRAIT_ROBOTIC_ORGANISM)) //Robots can heal from cores, but only get 1/5th of the healing. They can use this to get past the damage threshhold however, and then regularely heal from there. + var/turf/T = get_turf(owner) + if(T && is_mining_level(T.z)) + if(HAS_TRAIT(owner, TRAIT_ROBOTIC_ORGANISM)) //Robots can heal from cores, though they ""only"" heal 20 brute + burn damage each instead of 25 + heal_amount *= 0.8 + else + duration = 10 SECONDS heal_amount *= 0.2 owner.adjustBruteLoss(-heal_amount, only_organic = FALSE) if(!AmBloodsucker(owner)) //use your coffin you lazy bastard diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index d6cde67198..25a6fa3d66 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -127,13 +127,58 @@ desc = "You've fallen asleep. Wait a bit and you should wake up. Unless you don't, considering how helpless you are." icon_state = "asleep" - /datum/status_effect/grouped/stasis id = "stasis" duration = -1 tick_interval = 10 + alert_type = /atom/movable/screen/alert/status_effect/stasis var/last_dead_time +/datum/status_effect/grouped/stasis/proc/update_time_of_death() + if(last_dead_time) + var/delta = world.time - last_dead_time + var/new_timeofdeath = owner.timeofdeath + delta + owner.timeofdeath = new_timeofdeath + owner.tod = gameTimestamp(wtime=new_timeofdeath) + last_dead_time = null + if(owner.stat == DEAD) + last_dead_time = world.time + +/datum/status_effect/grouped/stasis/on_creation(mob/living/new_owner, set_duration) + . = ..() + if(.) + update_time_of_death() + owner.reagents?.end_metabolization(owner, FALSE) + +/datum/status_effect/grouped/stasis/on_apply() + . = ..() + if(!.) + return + RegisterSignal(owner, COMSIG_LIVING_LIFE, .proc/InterruptBiologicalLife) + owner.mobility_flags &= ~(MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_PULL | MOBILITY_HOLD) + owner.update_mobility() + owner.add_filter("stasis_status_ripple", 2, list("type" = "ripple", "flags" = WAVE_BOUNDED, "radius" = 0, "size" = 2)) + var/filter = owner.get_filter("stasis_status_ripple") + animate(filter, radius = 32, time = 15, size = 0, loop = -1) + +/datum/status_effect/grouped/stasis/proc/InterruptBiologicalLife() + return COMPONENT_INTERRUPT_LIFE_BIOLOGICAL + +/datum/status_effect/grouped/stasis/tick() + update_time_of_death() + +/datum/status_effect/grouped/stasis/on_remove() + UnregisterSignal(owner, COMSIG_LIVING_LIFE) + owner.mobility_flags |= MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_PULL | MOBILITY_HOLD + owner.remove_filter("stasis_status_ripple") + update_time_of_death() + return ..() + +/atom/movable/screen/alert/status_effect/stasis + name = "Stasis" + desc = "Your biological functions have halted. You could live forever this way, but it's pretty boring." + icon_state = "stasis" + /datum/status_effect/robotic_emp id = "emp_no_combat_mode" @@ -194,6 +239,9 @@ C.adjustStaminaLoss(max(0, stamdmg_per_ds * diff)) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing. last_tick = world.time +/datum/status_effect/electrode/no_damage + stamdmg_per_ds = 0 + /datum/status_effect/electrode/no_combat_mode id = "tased_strong" movespeed_mod = /datum/movespeed_modifier/status_effect/tased/no_combat_mode @@ -768,7 +816,7 @@ /datum/status_effect/necropolis_curse/proc/apply_curse(set_curse) curse_flags |= set_curse if(curse_flags & CURSE_BLINDING) - owner.overlay_fullscreen("curse", /atom/movable/screen/fullscreen/curse, 1) + owner.overlay_fullscreen("curse", /atom/movable/screen/fullscreen/scaled/curse, 1) /datum/status_effect/necropolis_curse/proc/remove_curse(remove_curse) if(remove_curse & CURSE_BLINDING) @@ -816,7 +864,7 @@ /obj/effect/temp_visual/curse icon_state = "curse" -/obj/effect/temp_visual/curse/Initialize() +/obj/effect/temp_visual/curse/Initialize(mapload) . = ..() deltimer(timerid) @@ -926,11 +974,13 @@ /atom/movable/screen/alert/status_effect/strandling/Click(location, control, params) . = ..() - to_chat(mob_viewer, "You attempt to remove the durathread strand from around your neck.") - if(do_after(mob_viewer, 35, null, mob_viewer)) - if(isliving(mob_viewer)) - var/mob/living/L = mob_viewer - to_chat(mob_viewer, "You successfully remove the durathread strand.") + if(usr != owner) + return + to_chat(owner, "You attempt to remove the durathread strand from around your neck.") + if(do_after(owner, 3.5 SECONDS, owner)) + if(isliving(owner)) + var/mob/living/L = owner + to_chat(owner, "You successfully remove the durathread strand.") L.remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND) @@ -1000,11 +1050,15 @@ /datum/status_effect/trance/proc/hypnotize(datum/source, list/hearing_args) if(!owner.can_hear()) return - if(hearing_args[HEARING_SPEAKER] == owner) + var/mob/hearing_speaker = hearing_args[HEARING_SPEAKER] + if(hearing_speaker == owner) return var/mob/living/carbon/C = owner var/hypnomsg = uncostumize_say(hearing_args[HEARING_RAW_MESSAGE], hearing_args[HEARING_MESSAGE_MODE]) C.cure_trauma_type(/datum/brain_trauma/hypnosis, TRAUMA_RESILIENCE_SURGERY) //clear previous hypnosis + // The brain trauma itself does its own set of logging, but this is the only place the source of the hypnosis phrase can be found. + hearing_speaker.log_message("has hypnotised [key_name(C)] with the phrase '[hypnomsg]'", LOG_ATTACK) + C.log_message("has been hypnotised by the phrase '[hypnomsg]' spoken by [key_name(hearing_speaker)]", LOG_VICTIM, log_globally = FALSE) addtimer(CALLBACK(C, /mob/living/carbon.proc/gain_trauma, /datum/brain_trauma/hypnosis, TRAUMA_RESILIENCE_SURGERY, hypnomsg), 10) addtimer(CALLBACK(C, /mob/living.proc/Stun, 60, TRUE, TRUE), 15) //Take some time to think about it qdel(src) @@ -1129,3 +1183,22 @@ else if(fake_msg) to_chat(owner, fake_msg) msg_stage++ + +/datum/status_effect/cgau_conc + id = "cgau_conc" + examine_text = "SUBJECTPRONOUN sways from side to side hesitantly!" + duration = 5 SECONDS + +/datum/status_effect/cgau_conc/on_apply() + . = ..() + owner.add_movespeed_modifier(/datum/movespeed_modifier/gauntlet_concussion) + if(ishostile(owner)) + var/mob/living/simple_animal/hostile/simple_owner = owner + simple_owner.ranged_cooldown_time *= 2.5 + +/datum/status_effect/cgau_conc/on_remove() + . = ..() + owner.remove_movespeed_modifier(/datum/movespeed_modifier/gauntlet_concussion) + if(ishostile(owner)) + var/mob/living/simple_animal/hostile/simple_owner = owner + simple_owner.ranged_cooldown_time /= 2.5 diff --git a/code/datums/status_effects/gas.dm b/code/datums/status_effects/gas.dm index 26881fe94c..34c83b9a8e 100644 --- a/code/datums/status_effects/gas.dm +++ b/code/datums/status_effects/gas.dm @@ -27,7 +27,7 @@ /datum/status_effect/freon/proc/owner_resist() to_chat(owner, "You start breaking out of the ice cube!") - if(do_mob(owner, owner, 40)) + if(do_mob(owner, owner, 4 SECONDS)) if(!QDELETED(src)) to_chat(owner, "You break out of the ice cube!") owner.remove_status_effect(/datum/status_effect/freon) diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm index 2c274802b4..53ba29622e 100644 --- a/code/datums/status_effects/neutral.dm +++ b/code/datums/status_effects/neutral.dm @@ -83,3 +83,89 @@ /datum/status_effect/throat_soothed/on_remove() REMOVE_TRAIT(owner, TRAIT_SOOTHED_THROAT, "[STATUS_EFFECT_TRAIT]_[id]") return ..() + +// this status effect is used to negotiate the high-fiving capabilities of all concerned parties +/datum/status_effect/offering + id = "offering" + duration = -1 + tick_interval = -1 + status_type = STATUS_EFFECT_UNIQUE + alert_type = null + /// The people who were offered this item at the start + var/list/possible_takers + /// The actual item being offered + var/obj/item/offered_item + /// The type of alert given to people when offered, in case you need to override some behavior (like for high-fives) + var/give_alert_type = /atom/movable/screen/alert/give + +/datum/status_effect/offering/on_creation(mob/living/new_owner, obj/item/offer, give_alert_override) + . = ..() + if(!.) + return + + offered_item = offer + if(give_alert_override) + give_alert_type = give_alert_override + + for(var/mob/living/carbon/possible_taker in orange(1, owner)) + if(!owner.CanReach(possible_taker) || IS_DEAD_OR_INCAP(possible_taker) || !possible_taker.can_hold_items()) + continue + register_candidate(possible_taker) + + if(!possible_takers) // no one around + qdel(src) + return + + RegisterSignal(owner, COMSIG_MOVABLE_MOVED, .proc/check_owner_in_range) + RegisterSignal(offered_item, list(COMSIG_PARENT_QDELETING, COMSIG_ITEM_DROPPED), .proc/dropped_item) + //RegisterSignal(owner, COMSIG_PARENT_EXAMINE_MORE, .proc/check_fake_out) + +/datum/status_effect/offering/Destroy() + for(var/i in possible_takers) + var/mob/living/carbon/removed_taker = i + remove_candidate(removed_taker) + LAZYCLEARLIST(possible_takers) + return ..() + +/// Hook up the specified carbon mob to be offered the item in question, give them the alert and signals and all +/datum/status_effect/offering/proc/register_candidate(mob/living/carbon/possible_candidate) + var/atom/movable/screen/alert/give/G = possible_candidate.throw_alert("[owner]", give_alert_type) + if(!G) + return + LAZYADD(possible_takers, possible_candidate) + RegisterSignal(possible_candidate, COMSIG_MOVABLE_MOVED, .proc/check_taker_in_range) + G.setup(possible_candidate, owner, offered_item) + +/// Remove the alert and signals for the specified carbon mob. Automatically removes the status effect when we lost the last taker +/datum/status_effect/offering/proc/remove_candidate(mob/living/carbon/removed_candidate) + removed_candidate.clear_alert("[owner]") + LAZYREMOVE(possible_takers, removed_candidate) + UnregisterSignal(removed_candidate, COMSIG_MOVABLE_MOVED) + if(!possible_takers && !QDELING(src)) + qdel(src) + +/// One of our possible takers moved, see if they left us hanging +/datum/status_effect/offering/proc/check_taker_in_range(mob/living/carbon/taker) + SIGNAL_HANDLER + if(owner.CanReach(taker) && !IS_DEAD_OR_INCAP(taker)) + return + + remove_candidate(taker) + +/// The offerer moved, see if anyone is out of range now +/datum/status_effect/offering/proc/check_owner_in_range(mob/living/carbon/source) + SIGNAL_HANDLER + + for(var/i in possible_takers) + var/mob/living/carbon/checking_taker = i + if(!istype(checking_taker) || !owner.CanReach(checking_taker) || IS_DEAD_OR_INCAP(checking_taker)) + remove_candidate(checking_taker) + +/// We lost the item, give it up +/datum/status_effect/offering/proc/dropped_item(obj/item/source) + SIGNAL_HANDLER + qdel(src) + +/datum/status_effect/offering/secret_handshake + id = "secret_handshake" + give_alert_type = /atom/movable/screen/alert/give/secret_handshake diff --git a/code/datums/status_effects/status_effect.dm b/code/datums/status_effects/status_effect.dm index fe605ba4a6..f3171f6197 100644 --- a/code/datums/status_effects/status_effect.dm +++ b/code/datums/status_effects/status_effect.dm @@ -25,18 +25,19 @@ /datum/status_effect/proc/on_creation(mob/living/new_owner, ...) if(new_owner) owner = new_owner - if(owner) - LAZYADD(owner.status_effects, src) - if(!owner || !on_apply()) + if(QDELETED(owner) || !on_apply()) qdel(src) return + if(owner) + LAZYADD(owner.status_effects, src) if(duration != -1) duration = world.time + duration next_tick = world.time + tick_interval if(alert_type) var/atom/movable/screen/alert/status_effect/A = owner.throw_alert(id, alert_type) - A.attached_effect = src //so the alert can reference us, if it needs to - linked_alert = A //so we can reference the alert, if we need to + if(istype(A)) + A?.attached_effect = src //so the alert can reference us, if it needs to + linked_alert = A //so we can reference the alert, if we need to START_PROCESSING(SSstatus_effects, src) return TRUE diff --git a/code/datums/traits/_quirk.dm b/code/datums/traits/_quirk.dm index 22a851da1d..e26a19d3f0 100644 --- a/code/datums/traits/_quirk.dm +++ b/code/datums/traits/_quirk.dm @@ -14,6 +14,7 @@ /// should we immediately call on_spawn or add a timer to trigger var/on_spawn_immediate = TRUE var/mob/living/quirk_holder + var/processing_quirk = FALSE /datum/quirk/New(mob/living/quirk_mob, spawn_effects) if(!quirk_mob || (human_only && !ishuman(quirk_mob)) || quirk_mob.has_quirk(type)) @@ -21,11 +22,13 @@ return quirk_holder = quirk_mob SSquirks.quirk_objects += src - to_chat(quirk_holder, gain_text) + if(gain_text) + to_chat(quirk_holder, gain_text) quirk_holder.roundstart_quirks += src if(mob_trait) ADD_TRAIT(quirk_holder, mob_trait, ROUNDSTART_TRAIT) - START_PROCESSING(SSquirks, src) + if(processing_quirk) + START_PROCESSING(SSquirks, src) add() if(spawn_effects) if(on_spawn_immediate) @@ -35,10 +38,12 @@ addtimer(CALLBACK(src, .proc/post_add), 30) /datum/quirk/Destroy() - STOP_PROCESSING(SSquirks, src) + if(processing_quirk) + STOP_PROCESSING(SSquirks, src) remove() if(quirk_holder) - to_chat(quirk_holder, lose_text) + if(lose_text) + to_chat(quirk_holder, lose_text) quirk_holder.roundstart_quirks -= src if(mob_trait) REMOVE_TRAIT(quirk_holder, mob_trait, ROUNDSTART_TRAIT) @@ -129,7 +134,7 @@ Use this as a guideline var/mob/living/carbon/human/H = quirk_holder var/obj/item/clothing/glasses/regular/glasses = new(get_turf(H)) H.put_in_hands(glasses) - H.equip_to_slot(glasses, SLOT_GLASSES) + H.equip_to_slot(glasses, ITEM_SLOT_EYES) H.regenerate_icons() //This whole proc is called automatically diff --git a/code/datums/traits/good.dm b/code/datums/traits/good.dm index 23fd75f982..5b00d2e71e 100644 --- a/code/datums/traits/good.dm +++ b/code/datums/traits/good.dm @@ -72,6 +72,7 @@ mob_trait = TRAIT_JOLLY mood_quirk = TRUE medical_record_text = "Patient demonstrates constant euthymia irregular for environment. It's a bit much, to be honest." + processing_quirk = TRUE /datum/quirk/jolly/on_process() if(prob(0.05)) @@ -108,10 +109,10 @@ var/mob/living/carbon/human/H = quirk_holder var/obj/item/choice_beacon/music/B = new(get_turf(H)) H.put_in_hands(B) - H.equip_to_slot_if_possible(B, SLOT_IN_BACKPACK) + H.equip_to_slot_if_possible(B, ITEM_SLOT_BACKPACK) var/obj/item/musicaltuner/musicaltuner = new(get_turf(H)) H.put_in_hands(musicaltuner) - H.equip_to_slot_if_possible(musicaltuner, SLOT_IN_BACKPACK) + H.equip_to_slot_if_possible(musicaltuner, ITEM_SLOT_BACKPACK) H.regenerate_icons() /datum/quirk/photographer @@ -127,7 +128,7 @@ var/mob/living/carbon/human/H = quirk_holder var/obj/item/camera/camera = new(get_turf(H)) H.put_in_hands(camera) - H.equip_to_slot(camera, SLOT_NECK) + H.equip_to_slot(camera, ITEM_SLOT_NECK) H.regenerate_icons() /datum/quirk/selfaware @@ -166,7 +167,7 @@ var/mob/living/carbon/human/H = quirk_holder var/obj/item/toy/crayon/spraycan/spraycan = new(get_turf(H)) H.put_in_hands(spraycan) - H.equip_to_slot(spraycan, SLOT_IN_BACKPACK) + H.equip_to_slot(spraycan, ITEM_SLOT_BACKPACK) H.regenerate_icons() /datum/quirk/voracious @@ -180,16 +181,47 @@ /datum/quirk/trandening name = "High Luminosity Eyes" - desc = "When the next big fancy implant came out you had to buy one on impluse!" + desc = "When the next big fancy implant came out you had to buy one on impulse! You start the shift with emissive cybernetic eyes that can emit colored beams of light." value = 1 - gain_text = "You have to keep up with the next big thing!." - lose_text = "High-tech gizmos are a scam..." + gain_text = "You've been keeping up with the latest cybernetic trends!" + lose_text = "High powered eye lasers? What were you thinking..." /datum/quirk/trandening/on_spawn() - var/mob/living/carbon/human/H = quirk_holder - var/obj/item/autosurgeon/gloweyes/gloweyes = new(get_turf(H)) - H.equip_to_slot(gloweyes, SLOT_IN_BACKPACK) - H.regenerate_icons() + // Get targets + var/obj/item/organ/eyes/old_eyes = quirk_holder.getorganslot(ORGAN_SLOT_EYES) + var/obj/item/organ/eyes/robotic/glow/new_eyes = new + + // Replace eyes + qdel(old_eyes) + new_eyes.Insert(quirk_holder) + +/datum/quirk/trandening/remove() + // Get targets + var/obj/item/organ/eyes/old_eyes = quirk_holder.getorganslot(ORGAN_SLOT_EYES) + var/mob/living/carbon/human/qurk_mob = quirk_holder + + // Check for eyes existing + if(!old_eyes) + return + + // Check for quirk eyes + if(!istype(old_eyes, /obj/item/organ/eyes/robotic/glow)) + return + + // Define new eyes + var/species_eyes = /obj/item/organ/eyes + + // Check for mutant eyes + if(qurk_mob.dna.species && qurk_mob.dna.species.mutanteyes) + // Set eyes to mutant type + species_eyes = qurk_mob.dna.species.mutanteyes + + // Create new eyes item + var/obj/item/organ/eyes/new_eyes = new species_eyes() + + // Replace eyes + qdel(old_eyes) + new_eyes.Insert(quirk_holder) /datum/quirk/bloodpressure name = "Polycythemia vera" diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm index 38007023b5..a30e27c8f8 100644 --- a/code/datums/traits/negative.dm +++ b/code/datums/traits/negative.dm @@ -25,6 +25,7 @@ lose_text = "You no longer feel depressed." //if only it were that easy! medical_record_text = "Patient has a severe mood disorder, causing them to experience acute episodes of depression." mood_quirk = TRUE + processing_quirk = TRUE /datum/quirk/depression/on_process() if(prob(0.05)) @@ -38,30 +39,42 @@ medical_record_text = "Patient demonstrates an unnatural attachment to a family heirloom." var/obj/item/heirloom var/where + processing_quirk = TRUE GLOBAL_LIST_EMPTY(family_heirlooms) -/datum/quirk/family_heirloom/on_spawn() - var/mob/living/carbon/human/H = quirk_holder +/datum/quirk/family_heirloom/on_spawn() + // Define holder and type + var/mob/living/carbon/human/human_holder = quirk_holder var/obj/item/heirloom_type - var/species_heirloom_entry = GLOB.species_heirlooms[H.dna.species.id] - if(species_heirloom_entry) - if(prob(species_heirloom_entry[1])) - heirloom_type = pick(species_heirloom_entry[2]) + + // The quirk holder's species - we have a 50% chance, if we have a species with a set heirloom, to choose a species heirloom. + var/datum/species/holder_species = human_holder.dna?.species + if(holder_species && LAZYLEN(holder_species.family_heirlooms) && prob(50)) + heirloom_type = pick(holder_species.family_heirlooms) + else + // Our quirk holder's job + var/datum/job/holder_job = SSjob.GetJob(human_holder.last_mind?.assigned_role) + if(holder_job && LAZYLEN(holder_job.family_heirlooms)) + heirloom_type = pick(holder_job.family_heirlooms) + + // If we didn't find an heirloom somehow, throw them a generic one if(!heirloom_type) - var/job_heirloom_entry = GLOB.job_heirlooms[quirk_holder.mind.assigned_role] - if(!job_heirloom_entry) - heirloom_type = pick(GLOB.job_heirlooms["NO_JOB"]) //consider: should this be a define? - else - heirloom_type = pick(job_heirloom_entry) + heirloom_type = pick(/obj/item/toy/cards/deck, /obj/item/lighter, /obj/item/dice/d20) + + // Create the heirloom item heirloom = new heirloom_type(get_turf(quirk_holder)) + + // Add to global list GLOB.family_heirlooms += heirloom + + // Determine and assign item location var/list/slots = list( - "in your left pocket" = SLOT_L_STORE, - "in your right pocket" = SLOT_R_STORE, - "in your backpack" = SLOT_IN_BACKPACK + "in your left pocket" = ITEM_SLOT_LPOCKET, + "in your right pocket" = ITEM_SLOT_RPOCKET, + "in your backpack" = ITEM_SLOT_BACKPACK ) - where = H.equip_in_one_of_slots(heirloom, slots, FALSE) || "at your feet" + where = human_holder.equip_in_one_of_slots(heirloom, slots, FALSE) || "at your feet" /datum/quirk/family_heirloom/post_add() if(where == "in your backpack") @@ -73,13 +86,25 @@ GLOBAL_LIST_EMPTY(family_heirlooms) heirloom.name = "\improper [family_name[family_name.len]] family [heirloom.name]" /datum/quirk/family_heirloom/on_process() - if(heirloom in quirk_holder.GetAllContents()) + // Ignore for dead holder + if(quirk_holder.stat == DEAD) + return + + // When held: Positive mood + if(heirloom && (heirloom in quirk_holder.GetAllContents())) SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "family_heirloom_missing") SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "family_heirloom", /datum/mood_event/family_heirloom) + + // When not held: Negative mood else SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "family_heirloom") SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "family_heirloom_missing", /datum/mood_event/family_heirloom_missing) +/datum/quirk/item_quirk/family_heirloom/remove() + // Clear mood events when removing this quirk + SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "family_heirloom") + SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "family_heirloom_missing") + /datum/quirk/family_heirloom/clone_data() return heirloom @@ -102,6 +127,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms) gain_text = "You feel smooth." lose_text = "You feel wrinkled again." medical_record_text = "Patient has a tumor in their brain that is slowly driving them to brain death." + processing_quirk = TRUE /datum/quirk/brainproblems/on_process() quirk_holder.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2) @@ -120,7 +146,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms) /datum/quirk/nearsighted/on_spawn() var/mob/living/carbon/human/H = quirk_holder var/obj/item/clothing/glasses/regular/glasses = new(get_turf(H)) - if(!H.equip_to_slot_if_possible(glasses, SLOT_GLASSES)) + if(!H.equip_to_slot_if_possible(glasses, ITEM_SLOT_EYES)) H.put_in_hands(glasses) /datum/quirk/nyctophobia @@ -129,25 +155,38 @@ GLOBAL_LIST_EMPTY(family_heirlooms) value = -1 medical_record_text = "Patient demonstrates a fear of the dark. (Seriously?)" -/datum/quirk/nyctophobia/on_process() - var/mob/living/carbon/human/H = quirk_holder - if(H.dna.species.id in list("shadow", "nightmare")) - return //we're tied with the dark, so we don't get scared of it; don't cleanse outright to avoid cheese - var/turf/T = get_turf(quirk_holder) - var/lums = T.get_lumcount() - if(lums <= 0.2) - if(quirk_holder.m_intent == MOVE_INTENT_RUN) - addtimer(CALLBACK(src, .proc/recheck),2) //0.2 seconds of being in the dark - SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "nyctophobia", /datum/mood_event/nyctophobia) - else - SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "nyctophobia") +/datum/quirk/nyctophobia/add() + RegisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED, .proc/on_holder_moved) -/datum/quirk/nyctophobia/proc/recheck() - var/turf/T = get_turf(quirk_holder) - var/lums = T.get_lumcount() - if(lums <= 0.2) //check again, did they remain in the dark for 0.2 seconds? - to_chat(quirk_holder, "Easy, easy, take it slow... you're in the dark...") +/datum/quirk/nyctophobia/remove() + UnregisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED) + SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "nyctophobia") + +/// Called when the quirk holder moves. Updates the quirk holder's mood. +/datum/quirk/nyctophobia/proc/on_holder_moved(mob/living/source, atom/old_loc, dir, forced) + if(quirk_holder.stat != CONSCIOUS || quirk_holder.IsSleeping() || quirk_holder.IsUnconscious()) + return + + var/mob/living/carbon/human/human_holder = quirk_holder + + if(human_holder.dna?.species.id in list(SPECIES_SHADOW, SPECIES_NIGHTMARE)) + return + + if((human_holder.sight & SEE_TURFS) == SEE_TURFS) + return + + var/turf/holder_turf = get_turf(quirk_holder) + + var/lums = holder_turf.get_lumcount() + + if(lums > 0.2) + SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "nyctophobia") + return + + if(quirk_holder.m_intent == MOVE_INTENT_RUN) + to_chat(quirk_holder, span_warning("Easy, easy, take it slow... you're in the dark...")) quirk_holder.toggle_move_intent() + SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "nyctophobia", /datum/mood_event/nyctophobia) /datum/quirk/lightless name = "Light Sensitivity" @@ -157,6 +196,36 @@ GLOBAL_LIST_EMPTY(family_heirlooms) lose_text = "Enlightening." medical_record_text = "Despite my warnings, the patient refuses turn on the lights, only to end up rolling down a full flight of stairs and into the cellar." +/datum/quirk/lightless/add() + RegisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED, .proc/on_holder_moved) + +/datum/quirk/lightless/remove() + UnregisterSignal(quirk_holder, COMSIG_MOVABLE_MOVED) + SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "brightlight") + +/datum/quirk/lightless/proc/on_holder_moved(mob/living/source, atom/old_loc, dir, forced) + if(quirk_holder.stat != CONSCIOUS || quirk_holder.IsSleeping() || quirk_holder.IsUnconscious()) + return + + var/mob/living/carbon/human/human_holder = quirk_holder + + if(human_holder.dna?.species.id in list(SPECIES_SHADOW, SPECIES_NIGHTMARE)) + return + + if((human_holder.sight & SEE_TURFS) == SEE_TURFS) + return + + var/turf/holder_turf = get_turf(quirk_holder) + + var/lums = holder_turf.get_lumcount() + + if(lums < 0.8) + SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "brightlight") + return + + SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "brightlight", /datum/mood_event/brightlight) + + /datum/quirk/lightless/on_process() var/turf/T = get_turf(quirk_holder) var/lums = T.get_lumcount() @@ -236,6 +305,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms) gain_text = "..." lose_text = "You feel in tune with the world again." medical_record_text = "Patient suffers from acute Reality Dissociation Syndrome and experiences vivid hallucinations." + processing_quirk = TRUE /datum/quirk/insanity/on_process() if(quirk_holder.reagents.has_reagent(/datum/reagent/toxin/mindbreaker)) @@ -261,6 +331,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms) lose_text = "You feel easier about talking again." //if only it were that easy! medical_record_text = "Patient is usually anxious in social encounters and prefers to avoid them." var/dumb_thing = TRUE + processing_quirk = TRUE /datum/quirk/social_anxiety/add() RegisterSignal(quirk_holder, COMSIG_MOB_EYECONTACT, .proc/eye_contact) @@ -383,7 +454,7 @@ GLOBAL_LIST_EMPTY(family_heirlooms) /datum/quirk/blindness/on_spawn() var/mob/living/carbon/human/H = quirk_holder var/obj/item/clothing/glasses/sunglasses/blindfold/white/glasses = new(get_turf(H)) - if(!H.equip_to_slot_if_possible(glasses, SLOT_GLASSES, bypass_equip_delay_self = TRUE)) //if you can't put it on the user's eyes, put it in their hands, otherwise put it on their eyes eyes + if(!H.equip_to_slot_if_possible(glasses, ITEM_SLOT_EYES, bypass_equip_delay_self = TRUE)) //if you can't put it on the user's eyes, put it in their hands, otherwise put it on their eyes eyes H.put_in_hands(glasses) H.regenerate_icons() @@ -416,3 +487,30 @@ GLOBAL_LIST_EMPTY(family_heirlooms) . = ..() var/mob/living/carbon/human/H = quirk_holder H?.cure_trauma_type(/datum/brain_trauma/severe/monophobia, TRAUMA_RESILIENCE_ABSOLUTE) + +/datum/quirk/no_smell + name = "Anosmia" + desc = "You can't smell anything! You won't be able to detect certain colorless gases." + value = -1 + mob_trait = TRAIT_ANOSMIA + gain_text = "You can't smell anything!" + lose_text = "You can smell again!" + medical_record_text = "Patient suffers from anosmia and is incapable of smelling gases or particulates." + +/datum/quirk/paper_skin + name = "Paper Skin" + desc = "Your flesh is weaker, resulting in receiving cuts more easily." + value = -1 + mob_trait = TRAIT_PAPER_SKIN + gain_text = "Your flesh feels weak!" + lose_text = "Your flesh feels more durable!" + medical_record_text = "Patient suffers from weak flesh, resulting in them receiving cuts far more easily." + +/datum/quirk/glass_bones + name = "Glass Bones" + desc = "Your bones are far more brittle, and more vulnerable to breakage." + value = -1 + mob_trait = TRAIT_GLASS_BONES + gain_text = "Your bones feels weak!" + lose_text = "Your bones feels more durable!" + medical_record_text = "Patient suffers from brittle bones, resulting in them receiving breakages far more easily." diff --git a/code/datums/traits/neutral.dm b/code/datums/traits/neutral.dm index 2f0667d942..eb5293c07d 100644 --- a/code/datums/traits/neutral.dm +++ b/code/datums/traits/neutral.dm @@ -162,3 +162,21 @@ gain_text = "You feel like munching on a can of soda." lose_text = "You no longer feel like you should be eating trash." mob_trait = TRAIT_TRASHCAN + +// Moved Colorist quirk to a loadout item + +/datum/quirk/salt_sensitive + name = "Sodium Sensitivity" + desc = "Your body is sensitive to sodium, and is burnt upon contact. Ingestion or contact with it is not advised." + value = 0 + medical_record_text = "Patient should not come into contact with sodium." + mob_trait = TRAIT_SALT_SENSITIVE + +/datum/quirk/dullahan + name = "Dullahan" + desc = "Your head is detached from your body." + value = 0 + medical_record_text = "Patient seems to have some kind of spatial link with their decapitated head." + +/datum/quirk/dullahan/post_add() + quirk_holder.AddComponent(/datum/component/dullahan) diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm index fcc1f92bec..797b26b51d 100644 --- a/code/datums/weather/weather.dm +++ b/code/datums/weather/weather.dm @@ -64,8 +64,8 @@ var/overlay_plane = BLACKNESS_PLANE /// If the weather has no purpose but aesthetics. var/aesthetic = FALSE - /// Used by mobs to prevent them from being affected by the weather - var/immunity_type = "storm" + /// Used by mobs (or movables containing mobs, such as enviro bags) to prevent them from being affected by the weather. + var/immunity_type /// The stage of the weather, from 1-4 var/stage = END_STAGE @@ -133,15 +133,18 @@ /datum/weather/proc/start() if(stage >= MAIN_STAGE) return + SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_START(type)) stage = MAIN_STAGE update_areas() - for(var/M in GLOB.player_list) - var/turf/mob_turf = get_turf(M) - if(mob_turf && (mob_turf.z in impacted_z_levels)) + for(var/z_level in impacted_z_levels) + for(var/mob/player as anything in SSmobs.clients_by_zlevel[z_level]) + var/turf/mob_turf = get_turf(player) + if(!mob_turf) + continue if(weather_message) - to_chat(M, weather_message) + to_chat(player, weather_message) if(weather_sound) - SEND_SOUND(M, sound(weather_sound)) + SEND_SOUND(player, sound(weather_sound)) if(!perpetual) addtimer(CALLBACK(src, .proc/wind_down), weather_duration) @@ -192,14 +195,27 @@ * Returns TRUE if the living mob can be affected by the weather * */ -/datum/weather/proc/can_weather_act(mob/living/L) - var/turf/mob_turf = get_turf(L) - if(mob_turf && !(mob_turf.z in impacted_z_levels)) +/datum/weather/proc/can_weather_act(mob/living/mob_to_check) + var/turf/mob_turf = get_turf(mob_to_check) + + if(!mob_turf) return - if(immunity_type in L.weather_immunities) + + if(!(mob_turf.z in impacted_z_levels)) return - if(!(get_area(L) in impacted_areas)) + + if((immunity_type && HAS_TRAIT(mob_to_check, immunity_type)) || HAS_TRAIT(mob_to_check, TRAIT_WEATHER_IMMUNE)) return + + var/atom/loc_to_check = mob_to_check.loc + while(loc_to_check != mob_turf) + if((immunity_type && HAS_TRAIT(loc_to_check, immunity_type)) || HAS_TRAIT(loc_to_check, TRAIT_WEATHER_IMMUNE)) + return + loc_to_check = loc_to_check.loc + + if(!(get_area(mob_to_check) in impacted_areas)) + return + return TRUE /** @@ -209,6 +225,9 @@ /datum/weather/proc/weather_act(mob/living/L) return +/datum/weather/proc/weather_act_turf(area/N) //What effect does this weather have on the area? + return + /** * Updates the overlays on impacted areas * @@ -224,6 +243,7 @@ N.icon_state = telegraph_overlay if(MAIN_STAGE) N.icon_state = weather_overlay + weather_act_turf(N) if(WIND_DOWN_STAGE) N.icon_state = end_overlay if(END_STAGE) diff --git a/code/datums/weather/weather_types/acid_rain.dm b/code/datums/weather/weather_types/acid_rain.dm deleted file mode 100644 index a1ec4871d5..0000000000 --- a/code/datums/weather/weather_types/acid_rain.dm +++ /dev/null @@ -1,32 +0,0 @@ -//Acid rain is part of the natural weather cycle in the humid forests of Planetstation, and cause acid damage to anyone unprotected. -/datum/weather/acid_rain - name = "acid rain" - desc = "The planet's thunderstorms are by nature acidic, and will incinerate anyone standing beneath them without protection." - - telegraph_duration = 400 - telegraph_message = "Thunder rumbles far above. You hear droplets drumming against the canopy. Seek shelter." - telegraph_sound = 'sound/ambience/acidrain_start.ogg' - - weather_message = "Acidic rain pours down around you! Get inside!" - weather_overlay = "acid_rain" - weather_duration_lower = 600 - weather_duration_upper = 1500 - weather_sound = 'sound/ambience/acidrain_mid.ogg' - - end_duration = 100 - end_message = "The downpour gradually slows to a light shower. It should be safe outside now." - end_sound = 'sound/ambience/acidrain_end.ogg' - - area_type = /area - protect_indoors = TRUE - target_trait = ZTRAIT_ACIDRAIN - - immunity_type = "acid" // temp - - barometer_predictable = TRUE - - -/datum/weather/acid_rain/weather_act(mob/living/L) - var/resist = L.getarmor(null, "acid") - if(prob(max(0,100-resist))) - L.acid_act(20,20) diff --git a/code/datums/weather/weather_types/ash_storm.dm b/code/datums/weather/weather_types/ash_storm.dm index 6248be0de5..f533f5a012 100644 --- a/code/datums/weather/weather_types/ash_storm.dm +++ b/code/datums/weather/weather_types/ash_storm.dm @@ -1,4 +1,5 @@ -//Ash storms happen frequently on lavaland. They heavily obscure vision, and cause high fire damage to anyone caught outside. +//A reference to this list is passed into area sound managers, and it's modified in a manner that preserves that reference in ash_storm.dm +GLOBAL_LIST_EMPTY(ash_storm_sounds) /datum/weather/ash_storm name = "ash storm" desc = "An intense atmospheric storm lifts ash off of the planet's surface and billows it down across the area, dealing intense fire damage to the unprotected." @@ -20,60 +21,46 @@ protect_indoors = TRUE target_trait = ZTRAIT_ASHSTORM - immunity_type = "ash" + immunity_type = TRAIT_ASHSTORM_IMMUNE probability = 90 barometer_predictable = TRUE - - var/datum/looping_sound/active_outside_ashstorm/sound_ao = new(list(), FALSE, TRUE) - var/datum/looping_sound/active_inside_ashstorm/sound_ai = new(list(), FALSE, TRUE) - var/datum/looping_sound/weak_outside_ashstorm/sound_wo = new(list(), FALSE, TRUE) - var/datum/looping_sound/weak_inside_ashstorm/sound_wi = new(list(), FALSE, TRUE) + var/list/weak_sounds = list() + var/list/strong_sounds = list() /datum/weather/ash_storm/telegraph() - . = ..() - var/list/inside_areas = list() - var/list/outside_areas = list() var/list/eligible_areas = list() for (var/z in impacted_z_levels) eligible_areas += SSmapping.areas_in_z["[z]"] for(var/i in 1 to eligible_areas.len) var/area/place = eligible_areas[i] if(place.outdoors) - outside_areas += place + weak_sounds[place] = /datum/looping_sound/weak_outside_ashstorm + strong_sounds[place] = /datum/looping_sound/active_outside_ashstorm else - inside_areas += place + weak_sounds[place] = /datum/looping_sound/weak_inside_ashstorm + strong_sounds[place] = /datum/looping_sound/active_inside_ashstorm CHECK_TICK - sound_ao.output_atoms = outside_areas - sound_ai.output_atoms = inside_areas - sound_wo.output_atoms = outside_areas - sound_wi.output_atoms = inside_areas - - sound_wo.start() - sound_wi.start() + //We modify this list instead of setting it to weak/stron sounds in order to preserve things that hold a reference to it + //It's essentially a playlist for a bunch of components that chose what sound to loop based on the area a player is in + GLOB.ash_storm_sounds += weak_sounds + return ..() /datum/weather/ash_storm/start() - . = ..() - sound_wo.stop() - sound_wi.stop() - - sound_ao.start() - sound_ai.start() + GLOB.ash_storm_sounds -= weak_sounds + GLOB.ash_storm_sounds += strong_sounds + return ..() /datum/weather/ash_storm/wind_down() - . = ..() - sound_ao.stop() - sound_ai.stop() - - sound_wo.start() - sound_wi.start() + GLOB.ash_storm_sounds -= strong_sounds + GLOB.ash_storm_sounds += weak_sounds + return ..() /datum/weather/ash_storm/end() - . = ..() - sound_wo.stop() - sound_wi.stop() + GLOB.ash_storm_sounds -= weak_sounds + return ..() /datum/weather/ash_storm/proc/is_ash_immune(atom/L) while (L && !isturf(L)) @@ -84,10 +71,11 @@ var/thermal_protection = H.easy_thermal_protection() if(thermal_protection >= FIRE_IMMUNITY_MAX_TEMP_PROTECT) return TRUE - if(isliving(L))// if we're a non immune mob inside an immune mob we have to reconsider if that mob is immune to protect ourselves - var/mob/living/the_mob = L - if("ash" in the_mob.weather_immunities) - return TRUE + // if(istype(L, /obj/structure/closet)) + // var/obj/structure/closet/the_locker = L + // if(the_locker.weather_protection) + // if("ash" in the_locker.weather_protection) + // return TRUE L = L.loc //Check parent items immunities (recurses up to the turf) return FALSE //RIP you @@ -100,7 +88,6 @@ return L.adjustFireLoss(4) - //Emberfalls are the result of an ash storm passing by close to the playable area of lavaland. They have a 10% chance to trigger in place of an ash storm. /datum/weather/ash_storm/emberfall name = "emberfall" diff --git a/code/datums/weather/weather_types/floor_is_lava.dm b/code/datums/weather/weather_types/floor_is_lava.dm index 00ecfff0b3..4da2aead72 100644 --- a/code/datums/weather/weather_types/floor_is_lava.dm +++ b/code/datums/weather/weather_types/floor_is_lava.dm @@ -19,19 +19,23 @@ target_trait = ZTRAIT_STATION overlay_layer = ABOVE_OPEN_TURF_LAYER //Covers floors only - immunity_type = "lava" + immunity_type = TRAIT_LAVA_IMMUNE -/datum/weather/floor_is_lava/weather_act(mob/living/L) - if(issilicon(L)) - return - if(istype(L.buckled, /obj/structure/bed)) - return - for(var/obj/structure/O in L.loc) - if(O.density) - return - if(L.loc.density) - return - if(!L.client) //Only sentient people are going along with it! - return - L.adjustFireLoss(3) +/datum/weather/floor_is_lava/can_weather_act(mob/living/mob_to_check) + if(!mob_to_check.client) //Only sentient people are going along with it! + return FALSE + . = ..() + if(!. || issilicon(mob_to_check) || istype(mob_to_check.buckled, /obj/structure/bed)) + return FALSE + var/turf/mob_turf = get_turf(mob_to_check) + if(mob_turf.density) //Walls are not floors. + return FALSE + for(var/obj/structure/structure_to_check in mob_turf) + if(structure_to_check.density) + return FALSE + if(mob_to_check.movement_type & FLYING) + return FALSE + +/datum/weather/floor_is_lava/weather_act(mob/living/victim) + victim.adjustFireLoss(3) diff --git a/code/datums/weather/weather_types/ice_storm.dm b/code/datums/weather/weather_types/ice_storm.dm new file mode 100644 index 0000000000..fd09ff5138 --- /dev/null +++ b/code/datums/weather/weather_types/ice_storm.dm @@ -0,0 +1,36 @@ +//Same as snow_storm basically, but cools outside turf temps. StreetStation only +#define ICY_SNOW_TEMP 200 +/datum/weather/ice_storm + name = "Icestorm" + desc = "Harsh snowstorms roam the topside of this arctic planet, burying any area unfortunate enough to be in its path." + probability = 90 + + telegraph_message = "Drifting particles of snow begin to dust the surrounding area.." + telegraph_duration = 300 + telegraph_overlay = "light_snow" + + weather_message = "Dense snow begins to fall from the sky, how festive!" + weather_overlay = "snow_storm" + weather_duration_lower = 600 + weather_duration_upper = 1500 + + end_duration = 100 + end_message = "The snowfall dies down." + + area_type = /area/edina + protected_areas = list(/area/edina/protected) + target_trait = ZTRAIT_ICESTORM + + immunity_type = TRAIT_SNOWSTORM_IMMUNE + +/datum/weather/ice_storm/weather_act(mob/living/L) + //L.adjust_bodytemperature(-rand(10,20)) + +/datum/weather/ice_storm/weather_act_turf(area/N) + .=..() + //could be done better but would need a rewrite of weather which is beyond scope. + /* + for(var/turf/open/T in N) + var/datum/gas_mixture/turf/G = T.air + G.temperature = ICY_SNOW_TEMP + */ diff --git a/code/datums/weather/weather_types/radiation_storm.dm b/code/datums/weather/weather_types/radiation_storm.dm index ed58ee512d..ed02cd2f25 100644 --- a/code/datums/weather/weather_types/radiation_storm.dm +++ b/code/datums/weather/weather_types/radiation_storm.dm @@ -18,10 +18,10 @@ area_type = /area protected_areas = list(/area/maintenance, /area/ai_monitored/turret_protected/ai_upload, /area/ai_monitored/turret_protected/ai_upload_foyer, - /area/ai_monitored/turret_protected/ai, /area/commons/storage/emergency/starboard, /area/commons/storage/emergency/port, /area/shuttle, /area/security/prison/safe, /area/security/prison/toilet) + /area/ai_monitored/turret_protected/ai, /area/commons/storage/emergency/starboard, /area/commons/storage/emergency/port, /area/shuttle, /area/ruin/lavaland) target_trait = ZTRAIT_STATION - immunity_type = "rad" + immunity_type = TRAIT_RADSTORM_IMMUNE var/radiation_intensity = 100 @@ -30,7 +30,7 @@ status_alarm(TRUE) /datum/weather/rad_storm/weather_act(mob/living/L) - var/resist = L.getarmor(null, "rad") + var/resist = L.getarmor(null, RAD) var/ratio = 1 - (min(resist, 100) / 100) L.rad_act(radiation_intensity * ratio) diff --git a/code/datums/weather/weather_types/snow_storm.dm b/code/datums/weather/weather_types/snow_storm.dm index 8ab4839cdb..db18fc5c9e 100644 --- a/code/datums/weather/weather_types/snow_storm.dm +++ b/code/datums/weather/weather_types/snow_storm.dm @@ -19,7 +19,7 @@ protect_indoors = TRUE target_trait = ZTRAIT_SNOWSTORM - immunity_type = "snow" + immunity_type = TRAIT_SNOWSTORM_IMMUNE barometer_predictable = TRUE diff --git a/code/datums/weather/weather_types/void_storm.dm b/code/datums/weather/weather_types/void_storm.dm index 41c3b95bbf..e77a96f0fb 100644 --- a/code/datums/weather/weather_types/void_storm.dm +++ b/code/datums/weather/weather_types/void_storm.dm @@ -17,15 +17,18 @@ protect_indoors = FALSE target_trait = ZTRAIT_VOIDSTORM - immunity_type = "void" + immunity_type = TRAIT_VOIDSTORM_IMMUNE barometer_predictable = FALSE perpetual = TRUE -/datum/weather/void_storm/weather_act(mob/living/L) - if(IS_HERETIC(L) || IS_HERETIC_MONSTER(L)) - return - L.adjustOxyLoss(rand(1,3)) - L.adjustFireLoss(rand(1,3)) - L.adjust_blurriness(rand(0,1)) - L.adjust_bodytemperature(-rand(5,15)) +/datum/weather/void_storm/can_weather_act(mob/living/mob_to_check) + . = ..() + if(IS_HERETIC(mob_to_check) || IS_HERETIC_MONSTER(mob_to_check)) + return FALSE + +/datum/weather/void_storm/weather_act(mob/living/victim) + victim.adjustOxyLoss(rand(1,3)) + victim.adjustFireLoss(rand(1,3)) + victim.adjust_blurriness(rand(0,1)) + victim.adjust_bodytemperature(-rand(5,15)) diff --git a/code/datums/wires/_wires.dm b/code/datums/wires/_wires.dm index 81f99cfa69..abee5ada06 100644 --- a/code/datums/wires/_wires.dm +++ b/code/datums/wires/_wires.dm @@ -329,3 +329,15 @@ to_chat(L, "You need an attachable assembly!") #undef MAXIMUM_EMP_WIRES + +//gremlins +/datum/wires/proc/npc_tamper(mob/living/L) + if(!wires.len) + return + + var/wire_to_screw = pick(wires) + + if(is_color_cut(wire_to_screw) || prob(50)) //CutWireColour() proc handles both cutting and mending wires. If the wire is already cut, always mend it back. Otherwise, 50% to cut it and 50% to pulse it + cut(wire_to_screw) + else + pulse(wire_to_screw, L) diff --git a/code/datums/wires/mod.dm b/code/datums/wires/mod.dm new file mode 100644 index 0000000000..7949d4d5f7 --- /dev/null +++ b/code/datums/wires/mod.dm @@ -0,0 +1,56 @@ +/datum/wires/mod + holder_type = /obj/item/mod/control + proper_name = "MOD control unit" + req_knowledge = JOB_SKILL_MASTER + req_skill = JOB_SKILL_TRAINED + +/datum/wires/mod/New(atom/holder) + wires = list(WIRE_DISABLE, WIRE_SHOCK, WIRE_INTERFACE) + add_duds(3) + ..() + +/datum/wires/mod/interactable(mob/user) + if(!..()) + return FALSE + var/obj/item/mod/control/mod = holder + return mod.open + +/datum/wires/mod/get_status() + var/obj/item/mod/control/mod = holder + var/list/status = list() + status += "The orange light is [mod.seconds_electrified ? "on" : "off"]." + status += "The red light is [mod.malfunctioning ? "off" : "blinking"]." + status += "The yellow light is [mod.interface_break ? "off" : "on"]." + return status + +/datum/wires/mod/on_pulse(wire) + var/obj/item/mod/control/mod = holder + switch(wire) + if(WIRE_DISABLE) + mod.malfunctioning = TRUE + if(WIRE_SHOCK) + mod.seconds_electrified = MACHINE_DEFAULT_ELECTRIFY_TIME + if(WIRE_INTERFACE) + mod.interface_break = !mod.interface_break + +/datum/wires/mod/on_cut(wire, mend) + var/obj/item/mod/control/mod = holder + switch(wire) + if(WIRE_HACK) + if(!mend) + mod.req_access = list() + if(WIRE_DISABLE) + mod.malfunctioning = !mend + if(WIRE_SHOCK) + if(mend) + mod.seconds_electrified = MACHINE_NOT_ELECTRIFIED + else + mod.seconds_electrified = MACHINE_ELECTRIFIED_PERMANENT + if(WIRE_INTERFACE) + mod.interface_break = !mend + +/datum/wires/mod/ui_act(action, params) + var/obj/item/mod/control/mod = holder + if(!issilicon(usr) && mod.seconds_electrified && mod.shock(usr)) + return FALSE + return ..() diff --git a/code/datums/wounds/_scars.dm b/code/datums/wounds/_scars.dm index 3365fc359d..0edcf65b42 100644 --- a/code/datums/wounds/_scars.dm +++ b/code/datums/wounds/_scars.dm @@ -28,6 +28,8 @@ LAZYREMOVE(limb.scars, src) if(victim) LAZYREMOVE(victim.all_scars, src) + limb = null + victim = null . = ..() /** @@ -45,6 +47,8 @@ qdel(src) return limb = BP + RegisterSignal(limb, COMSIG_PARENT_QDELETING, .proc/limb_gone) + severity = W.severity if(limb.owner) victim = limb.owner @@ -84,6 +88,7 @@ return limb = BP + RegisterSignal(limb, COMSIG_PARENT_QDELETING, .proc/limb_gone) src.severity = severity LAZYADD(limb.scars, src) if(BP.owner) @@ -102,6 +107,10 @@ visibility = 7 return TRUE +/datum/scar/proc/limb_gone() + SIGNAL_HANDLER + qdel(src) + /// What will show up in examine_more() if this scar is visible /datum/scar/proc/get_examine_description(mob/viewer) if(!victim || !is_visible(viewer)) @@ -118,7 +127,7 @@ if(WOUND_SEVERITY_LOSS) msg = "[victim.p_their(TRUE)] [limb.name] [description]." // different format msg = "[msg]" - return "\t[msg]" + return "[msg]" /// Whether a scar can currently be seen by the viewer /datum/scar/proc/is_visible(mob/viewer) diff --git a/code/datums/wounds/_wounds.dm b/code/datums/wounds/_wounds.dm index 6cab8818ee..a2c4a70380 100644 --- a/code/datums/wounds/_wounds.dm +++ b/code/datums/wounds/_wounds.dm @@ -73,8 +73,6 @@ /// What status effect we assign on application var/status_effect_type - /// The status effect we're linked to - var/datum/status_effect/linked_status_effect /// If we're operating on this wound and it gets healed, we'll nix the surgery too var/datum/surgery/attached_surgery /// if you're a lazy git and just throw them in cryo, the wound will go away after accumulating severity * 25 power @@ -127,12 +125,13 @@ return victim = L.owner + RegisterSignal(victim, COMSIG_PARENT_QDELETING, .proc/null_victim) limb = L LAZYADD(victim.all_wounds, src) LAZYADD(limb.wounds, src) limb.update_wounds() if(status_effect_type) - linked_status_effect = victim.apply_status_effect(status_effect_type, src) + victim.apply_status_effect(status_effect_type, src) SEND_SIGNAL(victim, COMSIG_CARBON_GAIN_WOUND, src, limb) victim.emote("pain") if(!victim.alerts["wound"]) // only one alert is shared between all of the wounds @@ -161,6 +160,14 @@ wound_injury(old_wound) second_wind() +/datum/wound/proc/null_victim() + SIGNAL_HANDLER + victim = null + +/datum/wound/proc/source_died() + SIGNAL_HANDLER + qdel(src) + /// Remove the wound from whatever it's afflicting, and cleans up whateverstatus effects it had or modifiers it had on interaction times. ignore_limb is used for detachments where we only want to forget the victim /datum/wound/proc/remove_wound(ignore_limb, replaced = FALSE) //TODO: have better way to tell if we're getting removed without replacement (full heal) scar stuff diff --git a/code/datums/wounds/bones.dm b/code/datums/wounds/bones.dm index 128c860a6d..bf5c0f55d2 100644 --- a/code/datums/wounds/bones.dm +++ b/code/datums/wounds/bones.dm @@ -119,12 +119,20 @@ victim.bleed(blood_bled, TRUE) if(14 to 19) victim.visible_message("[victim] spits out a string of blood from the blow to [victim.p_their()] chest!", "You spit out a string of blood from the blow to your chest!", vision_distance=COMBAT_MESSAGE_RANGE) - new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir) + if(ishuman(victim)) + var/mob/living/carbon/human/H = victim + new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir, H.dna.species.exotic_blood_color) + else + new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir) victim.bleed(blood_bled) if(20 to INFINITY) victim.visible_message("[victim] chokes up a spray of blood from the blow to [victim.p_their()] chest!", "You choke up on a spray of blood from the blow to your chest!", vision_distance=COMBAT_MESSAGE_RANGE) victim.bleed(blood_bled) - new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir) + if(ishuman(victim)) + var/mob/living/carbon/human/H = victim + new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir, H.dna.species.exotic_blood_color) + else + new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir) victim.add_splatter_floor(get_step(victim.loc, victim.dir)) diff --git a/code/datums/wounds/burns.dm b/code/datums/wounds/burns.dm index f3e22807cf..c16be6005a 100644 --- a/code/datums/wounds/burns.dm +++ b/code/datums/wounds/burns.dm @@ -167,7 +167,7 @@ if(WOUND_INFECTION_SEPTIC to INFINITY) . += "Infection Level: LOSS IMMINENT\n" if(infestation > sanitization) - . += "\tSurgical debridement, antiobiotics/sterilizers, or regenerative mesh will rid infection. Paramedic UV penlights are also effective.\n" + . += "Surgical debridement, antiobiotics/sterilizers, or regenerative mesh will rid infection. Paramedic UV penlights are also effective.\n" if(flesh_damage > 0) . += "Flesh damage detected: Please apply ointment or regenerative mesh to allow recovery.\n" diff --git a/code/datums/wounds/pierce.dm b/code/datums/wounds/pierce.dm index b26728c377..434a711109 100644 --- a/code/datums/wounds/pierce.dm +++ b/code/datums/wounds/pierce.dm @@ -39,12 +39,20 @@ victim.bleed(blood_bled, TRUE) if(14 to 19) victim.visible_message("A small stream of blood spurts from the hole in [victim]'s [limb.name]!", "You spit out a string of blood from the blow to your [limb.name]!", vision_distance=COMBAT_MESSAGE_RANGE) - new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir) + if(ishuman(victim)) + var/mob/living/carbon/human/H = victim + new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir, H.dna.species.exotic_blood_color) + else + new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir) victim.bleed(blood_bled) if(20 to INFINITY) victim.visible_message("A spray of blood streams from the gash in [victim]'s [limb.name]!", "You choke up on a spray of blood from the blow to your [limb.name]!", vision_distance=COMBAT_MESSAGE_RANGE) victim.bleed(blood_bled) - new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir) + if(ishuman(victim)) + var/mob/living/carbon/human/H = victim + new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir, H.dna.species.exotic_blood_color) + else + new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir) victim.add_splatter_floor(get_step(victim.loc, victim.dir)) /datum/wound/pierce/handle_process() diff --git a/code/datums/wounds/slash.dm b/code/datums/wounds/slash.dm index 6a631ab8f4..68740e78ab 100644 --- a/code/datums/wounds/slash.dm +++ b/code/datums/wounds/slash.dm @@ -177,7 +177,7 @@ if(isinsect(victim) || iscatperson(victim) || ismammal(victim) || isdwarf(victim) || ismonkey(victim)) // Yep you can lick monkeys. user.reagents.add_reagent(/datum/reagent/hairball, 2) - else if(ishumanbasic(victim) || isflyperson(victim) || islizard(victim) || isdullahan(victim)) + else if(ishumanbasic(victim) || isflyperson(victim) || islizard(victim) || HAS_TRAIT(victim, TRAIT_DULLAHAN)) user.reagents.add_reagent(/datum/reagent/hairball, 1) if(blood_flow > minimum_flow) diff --git a/code/game/area/Space_Station_13_areas.dm b/code/game/area/Space_Station_13_areas.dm index 57f4fdb8de..b09731ab62 100644 --- a/code/game/area/Space_Station_13_areas.dm +++ b/code/game/area/Space_Station_13_areas.dm @@ -37,7 +37,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/ai_monitored/turret_protected/AIsatextAP name = "AI Sat Ext" icon_state = "storage" - + /area/arrival requires_power = FALSE @@ -126,7 +126,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station ambientsounds = RUINS area_flags = UNIQUE_AREA | NO_ALERTS -/area/asteroid/artifactroom/Initialize() +/area/asteroid/artifactroom/Initialize(mapload) . = ..() set_dynamic_lighting() @@ -212,6 +212,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED // airlock_wires = /datum/wires/airlock/maint sound_environment = SOUND_AREA_TUNNEL_ENCLOSED + minimap_color = "#454545" //Maintenance - Departmental @@ -296,6 +297,28 @@ NOTE: there are two lists of areas in the end of this file: centcom and station icon_state = "xenomaint" area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA | XENOBIOLOGY_COMPATIBLE | CULT_PERMITTED +//Maintenance - Prison + +/area/maintenance/prison + name = "Prison Maintenance" + icon_state = "prison_maintenance" + +/area/maintenance/prison/fore + name = "Prison Fore Maintenance" + icon_state = "prison_maintenance" + +/area/maintenance/prison/starboard + name = "Prison Starboard Maintenance" + icon_state = "prison_maintenance" + +/area/maintenance/prison/aft + name = "Prison Aft Maintenance" + icon_state = "prison_maintenance" + +/area/maintenance/prison/port + name = "Prison Port Maintenance" + icon_state = "prison_maintenance" + //Maintenance - Generic /area/maintenance/arrivals/north @@ -413,6 +436,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/hallway nightshift_public_area = NIGHTSHIFT_AREA_PUBLIC sound_environment = SOUND_AREA_STANDARD_STATION + minimap_color = "#aaaaaa" /area/hallway/primary name = "Primary Hallway" @@ -468,6 +492,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/hallway/secondary/exit name = "Escape Shuttle Hallway" icon_state = "escape" + minimap_color = "#baa0a0" /area/hallway/secondary/exit/departure_lounge name = "Departure Lounge" @@ -476,6 +501,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/hallway/secondary/entry name = "Arrival Shuttle Hallway" icon_state = "entry" + minimap_color = "#a0a0ba" /area/hallway/secondary/service name = "Service Hallway" @@ -852,9 +878,9 @@ NOTE: there are two lists of areas in the end of this file: centcom and station nightshift_public_area = NIGHTSHIFT_AREA_RECREATION sound_environment = SOUND_AREA_WOODFLOOR -// /area/service/bar/Initialize(mapload) -// . = ..() -// GLOB.bar_areas += src +/area/service/bar/Initialize(mapload) + . = ..() + GLOB.bar_areas += src /area/service/bar/atrium name = "Atrium" @@ -1393,13 +1419,9 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "Prison Wing" icon_state = "sec_prison" -/area/security/prison/toilet //radproof - name = "Prison Toilet" - icon_state = "sec_prison_safe" - -/area/security/prison/safe //radproof +/area/security/prison/cells name = "Prison Wing Cells" - icon_state = "sec_prison_safe" + icon_state = "prison_cells" /area/security/prison/upper name = "Upper Prison Wing" diff --git a/code/game/area/ai_monitored.dm b/code/game/area/ai_monitored.dm index 911cdde658..0123e20a07 100644 --- a/code/game/area/ai_monitored.dm +++ b/code/game/area/ai_monitored.dm @@ -31,6 +31,6 @@ cam.lostTargetRef(WEAKREF(O)) return -/area/ai_monitored/turret_protected/ai/Initialize() +/area/ai_monitored/turret_protected/ai/Initialize(mapload) . = ..() src.area_flags |= ABDUCTOR_PROOF diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 1d0069a7cd..ce4f4f7e92 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -15,7 +15,10 @@ var/area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED - var/fire = null + ///Do we have an active fire alarm? + var/fire = FALSE + ///How many fire alarm sources do we have? + var/triggered_firealarms = 0 ///Whether there is an atmos alarm in this area var/atmosalm = FALSE var/poweralm = FALSE @@ -41,7 +44,7 @@ ///Will objects this area be needing power? var/requires_power = TRUE - /// This gets overridden to 1 for space in area/Initialize(). + /// This gets overridden to 1 for space in area/Initialize(mapload). var/always_unpowered = FALSE var/power_equip = TRUE @@ -50,7 +53,12 @@ var/has_gravity = FALSE - var/parallax_movedir = 0 + /// Parallax moving? + var/parallax_moving = FALSE + /// Parallax move speed - 0 to disable + var/parallax_move_speed = 0 + /// Parallax move dir - degrees clockwise from north + var/parallax_move_angle = 0 var/list/ambientsounds = GENERIC flags_1 = CAN_BE_DIRTY_1 @@ -119,6 +127,10 @@ /// Color on minimaps, if it's null (which is default) it makes one at random. var/minimap_color + var/minimap_color2 // if this isn't null, then this will show as a checkerboard pattern mixed in with the above. works even if the above is null (for better or worse) + + var/minimap_show_walls = TRUE + /** * These two vars allow for multiple unique areas to be linked to a master area * and share some functionalities such as APC powernet nodes, fire alarms etc, without sacrificing @@ -192,7 +204,7 @@ GLOBAL_LIST_EMPTY(teleportlocs) * * returns INITIALIZE_HINT_LATELOAD */ -/area/Initialize() +/area/Initialize(mapload) icon_state = "" map_name = name // Save the initial (the name set in the map) name of the area. canSmoothWithAreas = typecacheof(canSmoothWithAreas) @@ -319,38 +331,38 @@ GLOBAL_LIST_EMPTY(teleportlocs) * * Sends to all ai players, alert consoles, drones and alarm monitor programs in the world */ -/area/proc/poweralert(state, obj/source) +/area/proc/poweralert(set_alarm, obj/source) if (area_flags & NO_ALERTS) return - if (state != poweralm) - poweralm = state + if (set_alarm != poweralm) + poweralm = set_alarm if(istype(source)) //Only report power alarms on the z-level where the source is located. for (var/item in GLOB.silicon_mobs) var/mob/living/silicon/aiPlayer = item - if (state == 1) - aiPlayer.cancelAlarm("Power", src, source) - else + if (set_alarm) aiPlayer.triggerAlarm("Power", src, cameras, source) + else + aiPlayer.cancelAlarm("Power", src, source) for (var/item in GLOB.alert_consoles) var/obj/machinery/computer/station_alert/a = item - if(state == 1) - a.cancelAlarm("Power", src, source) - else + if (set_alarm) a.triggerAlarm("Power", src, cameras, source) + else + a.cancelAlarm("Power", src, source) for (var/item in GLOB.drones_list) var/mob/living/simple_animal/drone/D = item - if(state == 1) - D.cancelAlarm("Power", src, source) - else + if (set_alarm) D.triggerAlarm("Power", src, cameras, source) + else + D.cancelAlarm("Power", src, source) for(var/item in GLOB.alarmdisplay) var/datum/computer_file/program/alarm_monitor/p = item - if(state == 1) - p.cancelAlarm("Power", src, source) - else + if (set_alarm) p.triggerAlarm("Power", src, cameras, source) + else + p.cancelAlarm("Power", src, source) /area/proc/atmosalert(danger_level, obj/source) if (area_flags & NO_ALERTS) @@ -434,7 +446,18 @@ GLOBAL_LIST_EMPTY(teleportlocs) START_PROCESSING(SSobj, src) /area/proc/firereset(obj/source) - if (fire) + var/should_reset_alarms = fire + if(source) + if(istype(source, /obj/machinery/firealarm)) + var/obj/machinery/firealarm/alarm = source + if(alarm.triggered) + alarm.triggered = FALSE + triggered_firealarms -= 1 + if(triggered_firealarms > 0) + should_reset_alarms = FALSE + should_reset_alarms = should_reset_alarms & power_environ //No resetting if there's no power + + if (should_reset_alarms) // if there's a source, make sure there's no fire alarms left set_fire_alarm_effects(FALSE) ModifyFiredoors(TRUE) @@ -454,6 +477,18 @@ GLOBAL_LIST_EMPTY(teleportlocs) STOP_PROCESSING(SSobj, src) +///Get rid of any dangling camera refs +/area/proc/clear_camera(obj/machinery/camera/cam) + LAZYREMOVE(cameras, cam) + for (var/mob/living/silicon/aiPlayer as anything in GLOB.silicon_mobs) + aiPlayer.freeCamera(src, cam) + for (var/obj/machinery/computer/station_alert/comp as anything in GLOB.alert_consoles) + comp.freeCamera(src, cam) + for (var/mob/living/simple_animal/drone/drone_on as anything in GLOB.drones_list) + drone_on.freeCamera(src, cam) + for(var/datum/computer_file/program/alarm_monitor/monitor as anything in GLOB.alarmdisplay) + monitor.freeCamera(src, cam) + /area/process() if(firedoors_last_closed_on + 100 < world.time) //every 10 seconds ModifyFiredoors(FALSE) diff --git a/code/game/area/areas/centcom.dm b/code/game/area/areas/centcom.dm index 0befe0bd86..6fe4c8fc65 100644 --- a/code/game/area/areas/centcom.dm +++ b/code/game/area/areas/centcom.dm @@ -59,7 +59,7 @@ icon_state = "supplypod_loading" var/loading_id = "" -/area/centcom/supplypod/loading/Initialize() +/area/centcom/supplypod/loading/Initialize(mapload) . = ..() if(!loading_id) CRASH("[type] created without a loading_id") diff --git a/code/game/area/areas/edina.dm b/code/game/area/areas/edina.dm new file mode 100644 index 0000000000..75c99334f7 --- /dev/null +++ b/code/game/area/areas/edina.dm @@ -0,0 +1,175 @@ +/area/edina + name = "Nova Edina wilderness" + icon_state = "edina" + has_gravity = STANDARD_GRAVITY + clockwork_warp_allowed = FALSE // Can servants warp into this area from Reebe? + clockwork_warp_fail = "The aurora borealis is interfering with your teleport! Try somewhere closer to the city." + always_unpowered = TRUE + + //dynamic_lighting = DYNAMIC_LIGHTING_DISABLED + power_light = FALSE + power_equip = FALSE + power_environ = FALSE + outdoors = TRUE + //ambientsounds = SPACE //For later + +/area/edina/backstreet + name = "Nova Edina backstreets" + icon_state = "edina_alley" + clockwork_warp_allowed = TRUE + ambientsounds = MAINTENANCE + always_unpowered = FALSE //Sure you can have power if you want + +/area/edina/backstreet/supply + name = "Supply Backstreets" + icon_state = "edina_alley" + clockwork_warp_allowed = TRUE + ambientsounds = MAINTENANCE + always_unpowered = FALSE //Sure you can have power if you want + +/area/edina/backstreet/research + name = "Research Backstreets" + icon_state = "edina_alley" + clockwork_warp_allowed = TRUE + ambientsounds = MAINTENANCE + always_unpowered = FALSE //Sure you can have power if you want + +/area/edina/backstreet/med + name = "Hospital Backstreets" + icon_state = "edina_alley" + clockwork_warp_allowed = TRUE + ambientsounds = MAINTENANCE + always_unpowered = FALSE //Sure you can have power if you want + +///Nova Edina Streets/// + + +/area/edina/street + name = "Nova Edina Streets" + icon_state = "edina_street" + ambientsounds = null //TODO:add ? + always_unpowered = FALSE //Sure you can have power if you want + +/area/edina/street/primary + name = "Nova Edina Streets" + icon_state = "edina_street" + ambientsounds = null //TODO:add ? + +/area/edina/street/primary/princess + name = "Princess Street" + icon_state = "edina_street" + ambientsounds = null //TODO:add ? + +/area/edina/street/primary/progress + name = "Progress Street" + icon_state = "edina_street" + ambientsounds = null //TODO:add ? + +/area/edina/street/primary/perimeter + name = "Perimeter Way" + icon_state = "edina_street" + ambientsounds = null //TODO:add ? + +/area/edina/street/primary/servitor + name = "Servitor Street" + icon_state = "edina_street" + ambientsounds = null //TODO:add ? + +/area/edina/street/secondary + name = "Nova Edina Streets" + icon_state = "edina_street2" + ambientsounds = null //TODO:add ? + +/area/edina/street/secondary/command + name = "Command Court" + icon_state = "edina_street2" + ambientsounds = null //TODO:add ? + +/area/edina/street/secondary/supply + name = "Supply Street" + icon_state = "edina_street2" + ambientsounds = null //TODO:add ? + +/area/edina/street/secondary/castle + name = "Castle Way" + icon_state = "edina_street2" + ambientsounds = null //TODO:add ? + +/area/edina/street/secondary/aux + name = "Auxiliary Avenue" + icon_state = "edina_street2" + ambientsounds = null //TODO:add ? + +/area/edina/street/intersection + name = "Nova Edina Streets" + icon_state = "edina_street2" + ambientsounds = null //TODO:add ? + +/area/edina/street/intersection/princessprogress + name = "Princess & Progress" + icon_state = "edina_street2" + ambientsounds = null //TODO:add ? + +/area/edina/street/intersection/princessperimeter + name = "Princess & Perimeter" + icon_state = "edina_street2" + ambientsounds = null //TODO:add ? + +/area/edina/street/intersection/princessperimeter/north + name = "Perimeter & N Princess" + icon_state = "edina_street2" + ambientsounds = null //TODO:add ? + +/area/edina/street/intersection/princessperimeter/south + name = "Perimeter & S Princess" + icon_state = "edina_street2" + ambientsounds = null //TODO:add ? + +/area/edina/street/intersection/princessservitor + name = "Servitor & Princess" + icon_state = "edina_street2" + ambientsounds = null //TODO:add ? + +/area/edina/street/intersection/servsuppaux + name = "Servitor, Supply, & Auxiliary" + icon_state = "edina_street2" + ambientsounds = null //TODO:add ? + +/area/edina/street/intersection/progcastaux + name = "Progress, Castle, & Auxiliary" + icon_state = "edina_street2" + ambientsounds = null //TODO:add ? + +/area/edina/street/street2 //Just so laying areas is easier + icon_state = "edina_street2" + +/area/edina/protected //Prevents ice storms + name = "Sheltered Nova Edina" + +/////////////////Edina specific derivitives/////////////////////////////////// + +/area/edina/crew_quarters + clockwork_warp_allowed = TRUE + area_flags = BLOBS_ALLOWED | VALID_TERRITORY + +/area/edina/crew_quarters/holo_atrium + name = "Hologram atrium" + +/area/edina/crew_quarters/store/clothes + name = "Clothes Store" + +/area/edina/crew_quarters/store/plushies + name = "Plushies Store" + +/area/edina/crew_quarters/store/pet + name = "Pet Store" + +////////////////Mapping helper///////////////////////// +/obj/effect/mapping_helpers/planet_z + name = "planet z helper" + layer = POINT_LAYER + +/obj/effect/mapping_helpers/planet_z/Initialize(mapload) + . = ..() + var/datum/space_level/S = SSmapping.get_level(z) + S.traits["Planet"] = TRUE //This probably doesn't work as I expect. But maybe!! diff --git a/code/game/area/areas/holodeck.dm b/code/game/area/areas/holodeck.dm index 3bc73a945f..35d6f1d202 100644 --- a/code/game/area/areas/holodeck.dm +++ b/code/game/area/areas/holodeck.dm @@ -14,7 +14,7 @@ Asserts are to avoid the inevitable infinite loops */ -/area/holodeck/Initialize() +/area/holodeck/Initialize(mapload) . = ..() var/list/update_holodeck_cache = SSholodeck?.rejected_areas[type] if(update_holodeck_cache) diff --git a/code/game/area/areas/ruins/_ruins.dm b/code/game/area/areas/ruins/_ruins.dm index 17ba4f7721..f9af5c8ce4 100644 --- a/code/game/area/areas/ruins/_ruins.dm +++ b/code/game/area/areas/ruins/_ruins.dm @@ -8,6 +8,10 @@ dynamic_lighting = DYNAMIC_LIGHTING_FORCED ambientsounds = RUINS sound_environment = SOUND_ENVIRONMENT_STONEROOM + var/valid_territory = FALSE // hey so what if we did not allow things like cult summons to appear on ruins + minimap_color = "#775940" + minimap_color2 = "#6b5d48" + minimap_show_walls = FALSE /area/ruin/unpowered diff --git a/code/game/area/areas/ruins/icemoon.dm b/code/game/area/areas/ruins/icemoon.dm index 6706a5faea..e993cf3bb1 100644 --- a/code/game/area/areas/ruins/icemoon.dm +++ b/code/game/area/areas/ruins/icemoon.dm @@ -1,9 +1,9 @@ // Icemoon Ruins -/area/ruin/unpowered/buried_library +/area/ruin/lavaland/unpowered/buried_library name = "Buried Library" icon_state = "dk_yellow" -/area/ruin/powered/bathhouse +/area/ruin/lavaland/powered/bathhouse name = "Bath House" icon_state = "dk_yellow" diff --git a/code/game/area/areas/ruins/lavaland.dm b/code/game/area/areas/ruins/lavaland.dm index 66c4f8542b..a0cfcf2c04 100644 --- a/code/game/area/areas/ruins/lavaland.dm +++ b/code/game/area/areas/ruins/lavaland.dm @@ -1,90 +1,99 @@ //Lavaland Ruins -/area/ruin/powered/beach +/area/ruin/lavaland/unpowered + always_unpowered = FALSE + +/area/ruin/lavaland/unpowered/no_grav + has_gravity = FALSE + +/area/ruin/lavaland/powered + requires_power = FALSE + +/area/ruin/lavaland/powered/beach icon_state = "dk_yellow" -/area/ruin/powered/clownplanet +/area/ruin/lavaland/powered/clownplanet icon_state = "dk_yellow" -/area/ruin/powered/animal_hospital +/area/ruin/lavaland/powered/animal_hospital icon_state = "dk_yellow" -/area/ruin/powered/snow_biodome +/area/ruin/lavaland/powered/snow_biodome icon_state = "dk_yellow" -/area/ruin/powered/gluttony +/area/ruin/lavaland/powered/gluttony icon_state = "dk_yellow" -/area/ruin/powered/golem_ship +/area/ruin/lavaland/powered/golem_ship name = "Free Golem Ship" icon_state = "dk_yellow" -/area/ruin/powered/greed +/area/ruin/lavaland/powered/greed icon_state = "dk_yellow" -/area/ruin/unpowered/hierophant +/area/ruin/lavaland/unpowered/hierophant name = "Hierophant's Arena" icon_state = "dk_yellow" -/area/ruin/powered/pride +/area/ruin/lavaland/powered/pride icon_state = "dk_yellow" -/area/ruin/powered/seedvault +/area/ruin/lavaland/powered/seedvault icon_state = "dk_yellow" -/area/ruin/unpowered/elephant_graveyard +/area/ruin/lavaland/unpowered/elephant_graveyard name = "Elephant Graveyard" icon_state = "dk_yellow" -/area/ruin/powered/graveyard_shuttle +/area/ruin/lavaland/powered/graveyard_shuttle name = "Elephant Graveyard" icon_state = "green" -/area/ruin/unpowered/syndicate_lava_base +/area/ruin/lavaland/unpowered/syndicate_lava_base name = "Secret Base" icon_state = "dk_yellow" ambientsounds = HIGHSEC -/area/ruin/unpowered/syndicate_lava_base/engineering +/area/ruin/lavaland/unpowered/syndicate_lava_base/engineering name = "Syndicate Lavaland Engineering" -/area/ruin/unpowered/syndicate_lava_base/medbay +/area/ruin/lavaland/unpowered/syndicate_lava_base/medbay name = "Syndicate Lavaland Medbay" -/area/ruin/unpowered/syndicate_lava_base/arrivals +/area/ruin/lavaland/unpowered/syndicate_lava_base/arrivals name = "Syndicate Lavaland Arrivals" -/area/ruin/unpowered/syndicate_lava_base/bar +/area/ruin/lavaland/unpowered/syndicate_lava_base/bar name = "Syndicate Lavaland Bar" -/area/ruin/unpowered/syndicate_lava_base/main +/area/ruin/lavaland/unpowered/syndicate_lava_base/main name = "Syndicate Lavaland Primary Hallway" -/area/ruin/unpowered/syndicate_lava_base/cargo +/area/ruin/lavaland/unpowered/syndicate_lava_base/cargo name = "Syndicate Lavaland Cargo Bay" -/area/ruin/unpowered/syndicate_lava_base/chemistry +/area/ruin/lavaland/unpowered/syndicate_lava_base/chemistry name = "Syndicate Lavaland Chemistry" -/area/ruin/unpowered/syndicate_lava_base/virology +/area/ruin/lavaland/unpowered/syndicate_lava_base/virology name = "Syndicate Lavaland Virology" -/area/ruin/unpowered/syndicate_lava_base/testlab +/area/ruin/lavaland/unpowered/syndicate_lava_base/testlab name = "Syndicate Lavaland Experimentation Lab" -/area/ruin/unpowered/syndicate_lava_base/dormitories +/area/ruin/lavaland/unpowered/syndicate_lava_base/dormitories name = "Syndicate Lavaland Dormitories" -/area/ruin/unpowered/syndicate_lava_base/telecomms +/area/ruin/lavaland/unpowered/syndicate_lava_base/telecomms name = "Syndicate Lavaland Telecommunications" -/area/ruin/unpowered/syndicate_lava_base/circuits +/area/ruin/lavaland/unpowered/syndicate_lava_base/circuits name = "Syndicate Lavaland Circuit Lab" //Xeno Nest -/area/ruin/unpowered/xenonest +/area/ruin/lavaland/unpowered/xenonest name = "The Hive" always_unpowered = TRUE power_environ = FALSE @@ -93,5 +102,5 @@ poweralm = FALSE //ash walker nest -/area/ruin/unpowered/ash_walkers +/area/ruin/lavaland/unpowered/ash_walkers icon_state = "red" diff --git a/code/game/area/areas/shuttles.dm b/code/game/area/areas/shuttles.dm index c8ee2973c4..e86f2ffe06 100644 --- a/code/game/area/areas/shuttles.dm +++ b/code/game/area/areas/shuttles.dm @@ -15,7 +15,7 @@ // area_limited_icon_smoothing = /area/shuttle sound_environment = SOUND_ENVIRONMENT_ROOM -/area/shuttle/Initialize() +/area/shuttle/Initialize(mapload) if(!canSmoothWithAreas) canSmoothWithAreas = type . = ..() diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 48213279f1..220cd88499 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -9,6 +9,9 @@ plane = GAME_PLANE appearance_flags = TILE_BOUND + /// pass_flags that we are. If any of this matches a pass_flag on a moving thing, by default, we let them through. + var/pass_flags_self = NONE + var/level = 2 ///If non-null, overrides a/an/some in all cases var/article @@ -267,14 +270,29 @@ var/a_incidence_s = abs(incidence_s) if(a_incidence_s > 90 && a_incidence_s < 270) return FALSE - if((P.flag in list("bullet", "bomb")) && P.ricochet_incidence_leeway) + if((P.flag in list(BULLET, BOMB)) && P.ricochet_incidence_leeway) if((a_incidence_s < 90 && a_incidence_s < 90 - P.ricochet_incidence_leeway) || (a_incidence_s > 270 && a_incidence_s -270 > P.ricochet_incidence_leeway)) - return + return FALSE var/new_angle_s = SIMPLIFY_DEGREES(face_angle + incidence_s) P.setAngle(new_angle_s) return TRUE /atom/proc/CanPass(atom/movable/mover, turf/target) + //SHOULD_CALL_PARENT(TRUE) + if(mover.movement_type & PHASING) + return TRUE + . = CanAllowThrough(mover, target) + // This is cheaper than calling the proc every time since most things dont override CanPassThrough + if(!mover.generic_canpass) + return mover.CanPassThrough(src, target, .) + +/// Returns true or false to allow the mover to move through src +/atom/proc/CanAllowThrough(atom/movable/mover, turf/target) + //SHOULD_CALL_PARENT(TRUE) + if(mover.pass_flags & pass_flags_self) + return TRUE + if(mover.throwing && (pass_flags_self & LETPASSTHROW)) + return TRUE return !density /** @@ -445,9 +463,19 @@ wires.emp_pulse(severity) return protection // Pass the protection value collected here upwards -/atom/proc/bullet_act(obj/item/projectile/P, def_zone) +/** + * React to a hit by a projectile object + * + * Default behaviour is to send the [COMSIG_ATOM_BULLET_ACT] and then call [on_hit][/obj/item/projectile/proc/on_hit] on the projectile + * + * @params + * P - projectile + * def_zone - zone hit + * piercing_hit - is this hit piercing or normal? + */ +/atom/proc/bullet_act(obj/item/projectile/P, def_zone, piercing_hit = FALSE) SEND_SIGNAL(src, COMSIG_ATOM_BULLET_ACT, P, def_zone) - . = P.on_hit(src, 0, def_zone) + . = P.on_hit(src, 0, def_zone, piercing_hit) //used on altdisarm() for special interactions between the shoved victim (target) and the src, with user being the one shoving the target on it. // IMPORTANT: if you wish to add a new own shove_act() to a certain object, remember to add SHOVABLE_ONTO to its obj_flags bitfied var first. @@ -490,7 +518,7 @@ . = list("[get_examine_string(user, TRUE)].") if(desc) - . += desc + . += "
    [desc]" if(custom_materials) var/list/materials_list = list() @@ -596,9 +624,13 @@ //SHOULD_CALL_PARENT(TRUE) return SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_ICON_STATE) -/// Updates the overlays of the atom +/** + * Builds a list of overlays for the atom, this will not apply them. + * If you need to update overlays, use [update_icon(UPDATE_OVERLAYS)], + * This proc is intended to be overridden. + */ /atom/proc/update_overlays() - //SHOULD_CALL_PARENT(TRUE) + SHOULD_CALL_PARENT(TRUE) . = list() SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_OVERLAYS, .) @@ -610,12 +642,12 @@ user.buckle_message_cooldown = world.time + 50 to_chat(user, "You can't move while buckled to [src]!") -/atom/proc/contents_explosion(severity, target) +/atom/proc/contents_explosion(severity, target, origin) return //For handling the effects of explosions on contents that would not normally be effected -/atom/proc/ex_act(severity, target, datum/explosion/E) +/atom/proc/ex_act(severity, target, origin) set waitfor = FALSE - contents_explosion(severity, target) + contents_explosion(severity, target, origin) SEND_SIGNAL(src, COMSIG_ATOM_EX_ACT, severity, target) /** @@ -670,7 +702,7 @@ var/blood_id = get_blood_id() if(!(blood_id in GLOB.blood_reagent_types)) return - return list("color" = BLOOD_COLOR_HUMAN, "ANIMAL DNA" = "Y-") + return list("color" = BLOOD_COLOR_HUMAN, "blendmode" = BLEND_MULTIPLY, "ANIMAL DNA" = "Y-") /mob/living/carbon/get_blood_dna_list() var/blood_id = get_blood_id() @@ -679,14 +711,16 @@ var/list/blood_dna = list() if(dna) blood_dna["color"] = dna.species.exotic_blood_color //so when combined, the list grows with the number of colors + blood_dna["blendmode"] = dna.species.exotic_blood_blend_mode blood_dna[dna.unique_enzymes] = dna.blood_type else blood_dna["color"] = BLOOD_COLOR_HUMAN + blood_dna["blendmode"] = BLEND_MULTIPLY blood_dna["UNKNOWN DNA"] = "X*" return blood_dna /mob/living/carbon/alien/get_blood_dna_list() - return list("color" = BLOOD_COLOR_XENO, "UNKNOWN DNA" = "X*") + return list("color" = BLOOD_COLOR_XENO, "blendmode" = BLEND_MULTIPLY, "UNKNOWN DNA" = "X*") //to add a mob's dna info into an object's blood_DNA list. /atom/proc/transfer_mob_blood_dna(mob/living/L) @@ -705,6 +739,7 @@ var/old = blood_DNA["color"] blood_DNA["color"] = BlendRGB(blood_DNA["color"], new_blood_dna["color"]) changed = old != blood_DNA["color"] + blood_DNA["blendmode"] = new_blood_dna["blendmode"] if(blood_DNA.len == old_length) return FALSE return changed @@ -724,6 +759,7 @@ blood_DNA["color"] = blood_dna["color"] else blood_DNA["color"] = BlendRGB(blood_DNA["color"], blood_dna["color"]) + blood_DNA["blendmode"] = blood_dna["blendmode"] //to add blood from a mob onto something, and transfer their dna info /atom/proc/add_mob_blood(mob/living/M) @@ -794,6 +830,11 @@ /atom/proc/blood_DNA_to_color() return (blood_DNA && blood_DNA["color"]) || BLOOD_COLOR_HUMAN +/atom/proc/blood_DNA_to_blend() + if(blood_DNA && !isnull(blood_DNA["blendmode"])) + return blood_DNA["blendmode"] + return BLEND_MULTIPLY + /atom/proc/clean_blood() . = blood_DNA? TRUE : FALSE blood_DNA = null @@ -823,6 +864,10 @@ return SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT) /atom/proc/rad_act(strength) + var/turf/open/pool/PL = get_turf(src) + if(istype(PL)) + if(PL.filled == TRUE) + strength *= 0.15 SEND_SIGNAL(src, COMSIG_ATOM_RAD_ACT, strength) /atom/proc/narsie_act() @@ -856,10 +901,11 @@ var/datum/progressbar/progress = new(user, things.len, src) var/datum/component/storage/STR = GetComponent(/datum/component/storage) if(STR == src_object) + progress.end_progress() return - while (do_after(user, 10, TRUE, src, FALSE, CALLBACK(STR, /datum/component/storage.proc/handle_mass_item_insertion, things, src_object, user, progress))) + while(do_after(user, 1 SECONDS, src, NONE, FALSE, CALLBACK(STR, /datum/component/storage.proc/handle_mass_item_insertion, things, src_object, user, progress))) stoplag(1) - qdel(progress) + progress.end_progress() to_chat(user, "You dump as much of [src_object.parent]'s contents into [STR.insert_preposition]to [src] as you can.") if(user.active_storage) //refresh the HUD to show the transfered contents user.active_storage.ui_show(user) @@ -892,9 +938,6 @@ SEND_SIGNAL(src, COMSIG_ATOM_DIR_CHANGE, dir, newdir) dir = newdir -/atom/proc/mech_melee_attack(obj/mecha/M) - return - //If a mob logouts/logins in side of an object you can use this proc /atom/proc/on_log(login) if(loc) @@ -1158,8 +1201,12 @@ log_game(log_text) if(LOG_GAME) log_game(log_text) + if(LOG_MECHA) + log_mecha(log_text) if(LOG_SHUTTLE) log_shuttle(log_text) + if(LOG_ECON) + log_econ(log_text) else stack_trace("Invalid individual logging type: [message_type]. Defaulting to [LOG_GAME] (LOG_GAME).") log_game(log_text) @@ -1211,7 +1258,7 @@ if(user != target) var/reverse_message = "has been [what_done] by [ssource][postfix]" - target.log_message(reverse_message, LOG_ATTACK, color="orange", log_globally=FALSE) + target.log_message(reverse_message, LOG_VICTIM, color="orange", log_globally=FALSE) /** * log_wound() is for when someone is *attacked* and suffers a wound. Note that this only captures wounds from damage, so smites/forced wounds aren't logged, as well as demotions like cuts scabbing over @@ -1263,7 +1310,7 @@ filters += filter(arglist(arguments)) UNSETEMPTY(filter_data) -/atom/proc/transition_filter(name, time, list/new_params, easing, loop) +/atom/proc/transition_filter(name, time, list/new_params, easing, loop, parallel = TRUE) var/filter = get_filter(name) if(!filter) return @@ -1274,7 +1321,7 @@ for(var/thing in new_params) params[thing] = new_params[thing] - animate(filter, new_params, time = time, easing = easing, loop = loop) + animate(filter, new_params, time = time, easing = easing, loop = loop, flags = (parallel ? ANIMATION_PARALLEL : 0)) for(var/param in params) filter_data[name][param] = params[param] @@ -1287,9 +1334,7 @@ /obj/item/update_filters() . = ..() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() + update_action_buttons() /atom/proc/get_filter(name) if(filter_data && filter_data[name]) @@ -1400,3 +1445,102 @@ */ /atom/proc/setClosed() return + +//Update the screentip to reflect what we're hoverin over +/atom/MouseEntered(location, control, params) + . = ..() + + var/mob/user = usr + if(isnull(user)) + return + if(!GET_CLIENT(user)) + return + + // Screentips + var/datum/hud/active_hud = user.hud_used + if(!active_hud) + return + + var/screentips_enabled = user.client.prefs.screentip_pref + if(screentips_enabled == SCREENTIP_PREFERENCE_DISABLED || (flags_1 & NO_SCREENTIPS_1)) + active_hud.screentip_text.maptext = "" + return + + active_hud.screentip_text.maptext_y = 10 // 10px lines us up with the action buttons top left corner + var/lmb_rmb_line = "" + var/ctrl_lmb_ctrl_rmb_line = "" + var/alt_lmb_alt_rmb_line = "" + var/shift_lmb_ctrl_shift_lmb_line = "" + var/extra_lines = 0 + var/extra_context = "" + + if ((isliving(user) || isovermind(user) || isaicamera(user)) && (user.client.prefs.screentip_pref != SCREENTIP_PREFERENCE_NO_CONTEXT)) + var/obj/item/held_item = user.get_active_held_item() + + if (flags_1 & HAS_CONTEXTUAL_SCREENTIPS_1 || held_item?.item_flags & ITEM_HAS_CONTEXTUAL_SCREENTIPS) + var/list/context = list() + + var/contextual_screentip_returns = \ + SEND_SIGNAL(src, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, context, held_item, user) \ + | (held_item && SEND_SIGNAL(held_item, COMSIG_ITEM_REQUESTING_CONTEXT_FOR_TARGET, context, src, user)) + + if (contextual_screentip_returns & CONTEXTUAL_SCREENTIP_SET) + var/screentip_images = user.client.prefs.screentip_images + // LMB and RMB on one line... + var/lmb_text = build_context(context, SCREENTIP_CONTEXT_LMB, screentip_images) + var/rmb_text = build_context(context, SCREENTIP_CONTEXT_RMB, screentip_images) + + if (lmb_text != "") + lmb_rmb_line = lmb_text + if (rmb_text != "") + lmb_rmb_line += " | [rmb_text]" + else if (rmb_text != "") + lmb_rmb_line = rmb_text + + // Ctrl-LMB, Ctrl-RMB on one line... + if (lmb_rmb_line != "") + lmb_rmb_line += "
    " + extra_lines++ + if (SCREENTIP_CONTEXT_CTRL_LMB in context) + ctrl_lmb_ctrl_rmb_line += build_context(context, SCREENTIP_CONTEXT_CTRL_LMB, screentip_images) + + if (SCREENTIP_CONTEXT_CTRL_RMB in context) + if (ctrl_lmb_ctrl_rmb_line != "") + ctrl_lmb_ctrl_rmb_line += " | " + ctrl_lmb_ctrl_rmb_line += build_context(context, SCREENTIP_CONTEXT_CTRL_RMB, screentip_images) + + // Alt-LMB, Alt-RMB on one line... + if (ctrl_lmb_ctrl_rmb_line != "") + ctrl_lmb_ctrl_rmb_line += "
    " + extra_lines++ + if (SCREENTIP_CONTEXT_ALT_LMB in context) + alt_lmb_alt_rmb_line += build_context(context, SCREENTIP_CONTEXT_ALT_LMB, screentip_images) + if (SCREENTIP_CONTEXT_ALT_RMB in context) + if (alt_lmb_alt_rmb_line != "") + alt_lmb_alt_rmb_line += " | " + alt_lmb_alt_rmb_line += build_context(context, SCREENTIP_CONTEXT_ALT_RMB, screentip_images) + + // Shift-LMB, Ctrl-Shift-LMB on one line... + if (alt_lmb_alt_rmb_line != "") + alt_lmb_alt_rmb_line += "
    " + extra_lines++ + if (SCREENTIP_CONTEXT_SHIFT_LMB in context) + shift_lmb_ctrl_shift_lmb_line += build_context(context, SCREENTIP_CONTEXT_SHIFT_LMB, screentip_images) + if (SCREENTIP_CONTEXT_CTRL_SHIFT_LMB in context) + if (shift_lmb_ctrl_shift_lmb_line != "") + shift_lmb_ctrl_shift_lmb_line += " | " + shift_lmb_ctrl_shift_lmb_line += build_context(context, SCREENTIP_CONTEXT_CTRL_SHIFT_LMB, screentip_images) + + if (shift_lmb_ctrl_shift_lmb_line != "") + extra_lines++ + + if(extra_lines) + extra_context = "
    [lmb_rmb_line][ctrl_lmb_ctrl_rmb_line][alt_lmb_alt_rmb_line][shift_lmb_ctrl_shift_lmb_line]" + //first extra line pushes atom name line up 10px, subsequent lines push it up 9px, this offsets that and keeps the first line in the same place + active_hud.screentip_text.maptext_y = -1 + (extra_lines - 1) * -9 + + if (screentips_enabled == SCREENTIP_PREFERENCE_CONTEXT_ONLY && extra_context == "") + active_hud.screentip_text.maptext = "" + else + //We inline a MAPTEXT() here, because there's no good way to statically add to a string like this + active_hud.screentip_text.maptext = "[name][extra_context]" diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 391d3b467d..6beb8319ec 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -25,10 +25,12 @@ var/inertia_moving = 0 var/inertia_next_move = 0 var/inertia_move_delay = 5 - var/pass_flags = 0 + /// Things we can pass through while moving. If any of this matches the thing we're trying to pass's [pass_flags_self], then we can pass through. + var/pass_flags = NONE + /// If false makes CanPass call CanPassThrough on this type instead of using default behaviour + var/generic_canpass = TRUE var/moving_diagonally = 0 //0: not doing a diagonal move. 1 and 2: doing the first/second step of the diagonal move var/atom/movable/moving_from_pull //attempt to resume grab after moving instead of before. - var/list/client_mobs_in_contents // This contains all the client mobs within this container var/list/acted_explosions //for explosion dodging var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm @@ -62,6 +64,16 @@ /// last time we yelled var/last_yell = 0 + // Text-to-bark sounds + var/sound/vocal_bark + var/vocal_bark_id + var/vocal_pitch = 1 + var/vocal_pitch_range = 0.2 //Actual pitch is (pitch - (vocal_pitch_range*0.5)) to (pitch + (vocal_pitch_range*0.5)) + var/vocal_volume = 70 //Baseline. This gets modified by yelling and other factors + var/vocal_speed = 4 //Lower values are faster, higher values are slower + + var/vocal_current_bark //When barks are queued, this gets passed to the bark proc. If vocal_current_bark doesn't match the args passed to the bark proc (if passed at all), then the bark simply doesn't play. Basic curtailing of spam~ + /atom/movable/Initialize(mapload) . = ..() switch(blocks_emissive) @@ -105,13 +117,16 @@ . = ..() + //We add ourselves to this list, best to clear it out + // LAZYCLEARLIST(area_sensitive_contents) + for(var/movable_content in contents) qdel(movable_content) - LAZYCLEARLIST(client_mobs_in_contents) - moveToNullspace() + vis_contents.Cut() + /atom/movable/proc/update_emissive_block() if(blocks_emissive != EMISSIVE_BLOCK_GENERIC) return @@ -217,6 +232,10 @@ if(NAMEOF(src, glide_size)) set_glide_size(var_value) . = TRUE + if(NAMEOF(src, vocal_bark)) + if(isfile(var_value)) + vocal_bark = sound(var_value) //bark() expects vocal_bark to already be a sound datum, for performance reasons. adminbus QoL! + . = TRUE if(!isnull(.)) datum_flags |= DF_VAR_EDITED @@ -476,10 +495,15 @@ /atom/movable/proc/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction) return FALSE -/atom/movable/CanPass(atom/movable/mover, turf/target) +/atom/movable/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(mover in buckled_mobs) return TRUE - return ..() + +/// Returns true or false to allow src to move through the blocker, mover has final say +/atom/movable/proc/CanPassThrough(atom/blocker, turf/target, blocker_opinion) + SHOULD_CALL_PARENT(TRUE) + return blocker_opinion /// called when this atom is removed from a storage item, which is passed on as S. The loc variable is already set to the new destination before this is called. /atom/movable/proc/on_exit_storage(datum/component/storage/concrete/S) // rename S to master_storage @@ -580,6 +604,16 @@ animate(time = 1) animate(alpha = 0, time = 3, easing = CIRCULAR_EASING|EASE_OUT) +/// Common proc used by painting tools like spraycans and palettes that can access the entire 24 bits color space. +/obj/item/proc/pick_painting_tool_color(mob/user, default_color) + var/chosen_color = input(user,"Pick new color", "[src]", default_color) as color|null + if(!chosen_color || QDELETED(src) || IS_DEAD_OR_INCAP(user) || !user.is_holding(src)) + return + set_painting_tool_color(chosen_color) + +/obj/item/proc/set_painting_tool_color(chosen_color) + SEND_SIGNAL(src, COMSIG_PAINTING_TOOL_SET_COLOR, chosen_color) + /atom/movable/vv_get_dropdown() . = ..() . += "" @@ -599,11 +633,11 @@ if(throwing && !throw_override) return if(on && !(movement_type & FLOATING)) - animate(src, pixel_y = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) - animate(pixel_y = -2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE) setMovetype(movement_type | FLOATING) else if (!on && (movement_type & FLOATING)) - animate(src, pixel_y = initial(pixel_y), time = 10) + animate(src, pixel_z = initial(pixel_y), time = 10) setMovetype(movement_type & ~FLOATING) floating_need_update = FALSE // assume it's done @@ -691,6 +725,17 @@ var/datum/language_holder/LH = get_language_holder() return LH.update_atom_languages(src) +/// Sets the vocal bark for the atom, using the bark's ID +/atom/movable/proc/set_bark(id) + if(!id) + return FALSE + var/datum/bark/B = GLOB.bark_list[id] + if(!B) + return FALSE + vocal_bark = sound(initial(B.soundpath)) + vocal_bark_id = id + return vocal_bark + /* End language procs */ @@ -769,4 +814,4 @@ M.Turn(pick(-30, 30)) animate(I, alpha = 175, pixel_x = to_x, pixel_y = to_y, time = 3, transform = M, easing = CUBIC_EASING) sleep(1) - animate(I, alpha = 0, transform = matrix(), time = 1) + animate(I, alpha = 0, transform = matrix(), time = 1, flags = ANIMATION_PARALLEL) diff --git a/code/game/atoms_movement.dm b/code/game/atoms_movement.dm index 4f07ff6f95..9fd007e9ee 100644 --- a/code/game/atoms_movement.dm +++ b/code/game/atoms_movement.dm @@ -48,8 +48,17 @@ continue var/atom/movable/thing = i thing.Crossed(src) -// -//////////////////////////////////////// + +/** + * meant for movement with zero side effects. only use for objects that are supposed to move "invisibly" (like camera mobs or ghosts) + * if you want something to move onto a tile with a beartrap or recycler or tripmine or mouse without that object knowing about it at all, use this + * most of the time you want forceMove() + */ +/atom/movable/proc/abstract_move(atom/new_loc) + var/atom/old_loc = loc + // move_stacks++ + loc = new_loc + Moved(old_loc) /atom/movable/Move(atom/newloc, direct, glide_size_override = 0) var/atom/movable/pullee = pulling @@ -167,12 +176,8 @@ if (!inertia_moving) inertia_next_move = world.time + inertia_move_delay newtonian_move(Dir) - if (length(client_mobs_in_contents)) - update_parallax_contents() - return TRUE - // Make sure you know what you're doing if you call this, this is intended to only be called by byond directly. // You probably want CanPass() /atom/movable/Cross(atom/movable/AM) diff --git a/code/game/communications.dm b/code/game/communications.dm index 696b942434..2b45fc9469 100644 --- a/code/game/communications.dm +++ b/code/game/communications.dm @@ -193,7 +193,9 @@ GLOBAL_LIST_INIT(reverseradiochannels, list( var/frequency = 0 var/transmission_method var/list/data + var/logging_data -/datum/signal/New(data, transmission_method = TRANSMISSION_RADIO) +/datum/signal/New(data, transmission_method = TRANSMISSION_RADIO, logging_data = null) src.data = data || list() src.transmission_method = transmission_method + src.logging_data = logging_data diff --git a/code/game/gamemodes/bloodsucker/bloodsucker.dm b/code/game/gamemodes/bloodsucker/bloodsucker.dm index 65321f5820..aa8edeaa72 100644 --- a/code/game/gamemodes/bloodsucker/bloodsucker.dm +++ b/code/game/gamemodes/bloodsucker/bloodsucker.dm @@ -25,7 +25,7 @@ antag_flag = ROLE_BLOODSUCKER false_report_weight = 1 chaos = 4 - restricted_jobs = list("AI","Cyborg") + restricted_jobs = list("Prisoner", "AI","Cyborg") protected_jobs = list("Chaplain", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") required_players = 20 required_enemies = 2 diff --git a/code/game/gamemodes/brother/traitor_bro.dm b/code/game/gamemodes/brother/traitor_bro.dm index eda6b5f9e2..6da31e41bb 100644 --- a/code/game/gamemodes/brother/traitor_bro.dm +++ b/code/game/gamemodes/brother/traitor_bro.dm @@ -7,7 +7,7 @@ config_tag = "traitorbro" required_players = 25 chaos = 5 - restricted_jobs = list("AI", "Cyborg") + restricted_jobs = list("Prisoner", "AI", "Cyborg") protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") announce_span = "danger" diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index 20ef83a54c..77c953567c 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -1,6 +1,6 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","Epsilon","Zeta","Eta","Theta","Iota","Kappa","Lambda","Mu","Nu","Xi","Omicron","Pi","Rho","Sigma","Tau","Upsilon","Phi","Chi","Psi","Omega")) GLOBAL_LIST_INIT(slots, list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store")) -GLOBAL_LIST_INIT(slot2slot, list("head" = SLOT_HEAD, "wear_mask" = SLOT_WEAR_MASK, "neck" = SLOT_NECK, "back" = SLOT_BACK, "wear_suit" = SLOT_WEAR_SUIT, "w_uniform" = SLOT_W_UNIFORM, "shoes" = SLOT_SHOES, "belt" = SLOT_BELT, "gloves" = SLOT_GLOVES, "glasses" = SLOT_GLASSES, "ears" = SLOT_EARS, "wear_id" = SLOT_WEAR_ID, "s_store" = SLOT_S_STORE)) +GLOBAL_LIST_INIT(slot2slot, list("head" = ITEM_SLOT_HEAD, "wear_mask" = ITEM_SLOT_MASK, "neck" = ITEM_SLOT_NECK, "back" = ITEM_SLOT_BACK, "wear_suit" = ITEM_SLOT_OCLOTHING, "w_uniform" = ITEM_SLOT_ICLOTHING, "shoes" = ITEM_SLOT_FEET, "belt" = ITEM_SLOT_BELT, "gloves" = ITEM_SLOT_GLOVES, "glasses" = ITEM_SLOT_EYES, "ears" = ITEM_SLOT_EARS, "wear_id" = ITEM_SLOT_ID, "s_store" = ITEM_SLOT_SUITSTORE)) GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "wear_mask" = /obj/item/clothing/mask/changeling, "back" = /obj/item/changeling, "wear_suit" = /obj/item/clothing/suit/changeling, "w_uniform" = /obj/item/clothing/under/changeling, "shoes" = /obj/item/clothing/shoes/changeling, "belt" = /obj/item/changeling, "gloves" = /obj/item/clothing/gloves/changeling, "glasses" = /obj/item/clothing/glasses/changeling, "ears" = /obj/item/changeling, "wear_id" = /obj/item/changeling, "s_store" = /obj/item/changeling)) GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our this objective to all lings @@ -11,7 +11,7 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th antag_flag = ROLE_CHANGELING false_report_weight = 10 chaos = 5 - restricted_jobs = list("AI", "Cyborg") + restricted_jobs = list("Prisoner", "AI", "Cyborg") protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") //citadel change - adds HoP, CE, CMO, and RD to ling role blacklist required_players = 15 required_enemies = 1 diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm index 88a1cde8ce..691111031d 100644 --- a/code/game/gamemodes/changeling/traitor_chan.dm +++ b/code/game/gamemodes/changeling/traitor_chan.dm @@ -4,7 +4,7 @@ false_report_weight = 10 chaos = 6 traitors_possible = 3 //hard limit on traitors if scaling is turned off - restricted_jobs = list("AI", "Cyborg") + restricted_jobs = list("Prisoner", "AI", "Cyborg") required_players = 25 required_enemies = 1 // how many of each type are required recommended_enemies = 3 diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index d8ebf6f20c..77371ad7bc 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -139,7 +139,7 @@ Credit where due: required_enemies = 3 recommended_enemies = 5 enemy_minimum_age = 7 - protected_jobs = list("AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") //Silicons can eventually be converted + protected_jobs = list("Prisoner", "AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") //Silicons can eventually be converted restricted_jobs = list("Chaplain", "Captain") announce_span = "brass" announce_text = "Servants of Ratvar are trying to summon the Justiciar!\n\ @@ -151,14 +151,8 @@ Credit where due: var/datum/team/clockcult/main_clockcult /datum/game_mode/clockwork_cult/pre_setup() //Gamemode and job code is pain. Have fun codediving all of that stuff, whoever works on this next - Delta - /*var/list/errorList = list() - var/list/reebes = SSmapping.LoadGroup(errorList, "Reebe", "map_files/generic", "City_of_Cogs.dmm", default_traits = ZTRAITS_REEBE, silent = TRUE) - if(errorList.len) // reebe failed to load - message_admins("Reebe failed to load!") - log_game("Reebe failed to load!") + if(!load_reebe()) return FALSE - for(var/datum/parsed_map/PM in reebes) //Temporarily commented because of z-level loading reliably segfaulting the server. - PM.initTemplateBounds()*/ if(CONFIG_GET(flag/protect_roles_from_antagonist)) restricted_jobs += protected_jobs if(CONFIG_GET(flag/protect_assistant_from_antagonist)) @@ -196,7 +190,7 @@ Credit where due: ..() return 1 -/datum/game_mode/clockwork_cult/proc/greet_servant(mob/M) //Description of their role +/datum/game_mode/proc/greet_servant(mob/M) //Description of their role if(!M) return 0 to_chat(M, "You are a servant of Ratvar, the Clockwork Justiciar!") @@ -211,11 +205,11 @@ Credit where due: var/mob/living/carbon/human/L = M var/obj/item/clockwork/slab/S = new var/slot = "At your feet" - var/list/slots = list("In your left pocket" = SLOT_L_STORE, "In your right pocket" = SLOT_R_STORE, "In your backpack" = SLOT_IN_BACKPACK) + var/list/slots = list("In your left pocket" = ITEM_SLOT_LPOCKET, "In your right pocket" = ITEM_SLOT_RPOCKET, "In your backpack" = ITEM_SLOT_BACKPACK) if(ishuman(L)) var/mob/living/carbon/human/H = L var/obj/item/clockwork/replica_fabricator/F = new - if(H.equip_to_slot_or_del(F, SLOT_IN_BACKPACK)) + if(H.equip_to_slot_or_del(F, ITEM_SLOT_BACKPACK)) to_chat(H, "You have been equipped with a replica fabricator, an advanced tool that can convert objects like doors, tables or even coats into clockwork equivalents.") slot = H.equip_in_one_of_slots(S, slots) if(slot == "In your backpack") @@ -275,7 +269,7 @@ Credit where due: ears = /obj/item/radio/headset gloves = /obj/item/clothing/gloves/color/yellow belt = /obj/item/storage/belt/utility/servant - backpack_contents = list(/obj/item/storage/box/engineer = 1, \ + backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\ /obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/reagent_containers/food/drinks/bottle/holyoil = 1) id = /obj/item/pda var/plasmaman //We use this to determine if we should activate internals in post_equip() diff --git a/code/game/gamemodes/clown_ops/bananium_bomb.dm b/code/game/gamemodes/clown_ops/bananium_bomb.dm index 695fc79169..3e8d45b842 100644 --- a/code/game/gamemodes/clown_ops/bananium_bomb.dm +++ b/code/game/gamemodes/clown_ops/bananium_bomb.dm @@ -37,17 +37,17 @@ if(!H.w_uniform || H.dropItemToGround(H.w_uniform)) C = new /obj/item/clothing/under/rank/civilian/clown(H) ADD_TRAIT(C, TRAIT_NODROP, CLOWN_NUKE_TRAIT) - H.equip_to_slot_or_del(C, SLOT_W_UNIFORM) + H.equip_to_slot_or_del(C, ITEM_SLOT_ICLOTHING) if(!H.shoes || H.dropItemToGround(H.shoes)) C = new /obj/item/clothing/shoes/clown_shoes(H) ADD_TRAIT(C, TRAIT_NODROP, CLOWN_NUKE_TRAIT) - H.equip_to_slot_or_del(C, SLOT_SHOES) + H.equip_to_slot_or_del(C, ITEM_SLOT_FEET) if(!H.wear_mask || H.dropItemToGround(H.wear_mask)) C = new /obj/item/clothing/mask/gas/clown_hat(H) ADD_TRAIT(C, TRAIT_NODROP, CLOWN_NUKE_TRAIT) - H.equip_to_slot_or_del(C, SLOT_WEAR_MASK) + H.equip_to_slot_or_del(C, ITEM_SLOT_MASK) H.dna.add_mutation(CLOWNMUT) H.dna.add_mutation(SMILE) diff --git a/code/game/gamemodes/clown_ops/clown_ops.dm b/code/game/gamemodes/clown_ops/clown_ops.dm index 659d2de105..fa73e2cca9 100644 --- a/code/game/gamemodes/clown_ops/clown_ops.dm +++ b/code/game/gamemodes/clown_ops/clown_ops.dm @@ -43,7 +43,7 @@ l_pocket = /obj/item/pinpointer/nuke/syndicate r_pocket = /obj/item/bikehorn id = /obj/item/card/id/syndicate - backpack_contents = list(/obj/item/storage/box/syndie=1,\ + backpack_contents = list(/obj/item/storage/box/survival/syndie=1,\ /obj/item/kitchen/knife/combat/survival, /obj/item/reagent_containers/spray/waterflower/lube) implants = list(/obj/item/implant/sad_trombone) diff --git a/code/game/gamemodes/clown_ops/clown_weapons.dm b/code/game/gamemodes/clown_ops/clown_weapons.dm index a27cb02ea8..f17cfde761 100644 --- a/code/game/gamemodes/clown_ops/clown_weapons.dm +++ b/code/game/gamemodes/clown_ops/clown_weapons.dm @@ -17,7 +17,7 @@ desc = "advanced clown shoes that protect the wearer and render them nearly immune to slipping on their own peels. They also squeak at 100% capacity." clothing_flags = NOSLIP slowdown = SHOES_SLOWDOWN - armor = list("melee" = 25, "bullet" = 25, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 10, "rad" = 0, "fire" = 70, "acid" = 50) + armor = list(MELEE = 25, BULLET = 25, LASER = 25, ENERGY = 25, BOMB = 50, BIO = 10, RAD = 0, FIRE = 70, ACID = 50) strip_delay = 70 resistance_flags = NONE permeability_coefficient = 0.05 @@ -28,7 +28,7 @@ name = "mk-honk combat shoes" desc = "The culmination of years of clown combat research, these shoes leave a trail of chaos in their wake. They will slowly recharge themselves over time, or can be manually charged with bananium." slowdown = SHOES_SLOWDOWN - armor = list("melee" = 25, "bullet" = 25, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 10, "rad" = 0, "fire" = 70, "acid" = 50) + armor = list(MELEE = 25, BULLET = 25, LASER = 25, ENERGY = 25, BOMB = 50, BIO = 10, RAD = 0, FIRE = 70, ACID = 50) strip_delay = 70 resistance_flags = NONE permeability_coefficient = 0.05 @@ -37,7 +37,7 @@ var/max_recharge = 3000 //30 peels worth var/recharge_rate = 34 //about 1/3 of a peel per tick -/obj/item/clothing/shoes/clown_shoes/banana_shoes/combat/Initialize() +/obj/item/clothing/shoes/clown_shoes/banana_shoes/combat/Initialize(mapload) . = ..() var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container) bananium.insert_amount_mat(max_recharge, /datum/material/bananium) @@ -69,7 +69,7 @@ var/next_trombone_allowed = 0 var/datum/component/slippery/slipper -/obj/item/melee/transforming/energy/sword/bananium/Initialize() +/obj/item/melee/transforming/energy/sword/bananium/Initialize(mapload) . = ..() slipper = LoadComponent(/datum/component/slippery, 81, GALOSHES_DONT_HELP) slipper.signal_enabled = active @@ -128,7 +128,7 @@ on_throw_speed = 1 var/datum/component/slippery/slipper -/obj/item/shield/energy/bananium/Initialize() +/obj/item/shield/energy/bananium/Initialize(mapload) . = ..() slipper = LoadComponent(/datum/component/slippery, 81, GALOSHES_DONT_HELP) slipper.signal_enabled = active @@ -173,7 +173,7 @@ var/det_time = 50 var/obj/item/grenade/syndieminibomb/bomb -/obj/item/grown/bananapeel/bombanana/Initialize() +/obj/item/grown/bananapeel/bombanana/Initialize(mapload) . = ..() AddComponent(/datum/component/slippery, det_time) bomb = new /obj/item/grenade/syndieminibomb(src) @@ -214,19 +214,19 @@ if(!istype(C.wear_mask, /obj/item/clothing/mask/gas/clown_hat) && !istype(C.wear_mask, /obj/item/clothing/mask/gas/mime)) if(!C.wear_mask || C.dropItemToGround(C.wear_mask)) var/obj/item/clothing/mask/fakemoustache/sticky/the_stash = new /obj/item/clothing/mask/fakemoustache/sticky() - C.equip_to_slot_or_del(the_stash, SLOT_WEAR_MASK, TRUE, TRUE, TRUE, TRUE) + C.equip_to_slot_or_del(the_stash, ITEM_SLOT_MASK, TRUE, TRUE, TRUE, TRUE) /obj/item/clothing/mask/fakemoustache/sticky var/unstick_time = 2 MINUTES -/obj/item/clothing/mask/fakemoustache/sticky/Initialize() +/obj/item/clothing/mask/fakemoustache/sticky/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, STICKY_MOUSTACHE_TRAIT) addtimer(TRAIT_CALLBACK_REMOVE(src, TRAIT_NODROP, STICKY_MOUSTACHE_TRAIT), unstick_time) /obj/item/clothing/mask/fakemoustache/sticky/equipped(mob/user, slot) . = ..() - if(slot == SLOT_WEAR_MASK) + if(slot == ITEM_SLOT_MASK) ADD_TRAIT(user, TRAIT_NO_INTERNALS, STICKY_MOUSTACHE_TRAIT) /obj/item/clothing/mask/fakemoustache/sticky/dropped(mob/user) @@ -243,7 +243,7 @@ projectiles = 8 projectile_energy_cost = 1000 -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/bombanana/can_attach(obj/mecha/combat/honker/M) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/bombanana/can_attach(obj/vehicle/sealed/mecha/combat/honker/M) if(..()) if(istype(M)) return TRUE @@ -261,42 +261,33 @@ equip_cooldown = 60 det_time = 20 -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/tearstache/can_attach(obj/mecha/combat/honker/M) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/tearstache/can_attach(obj/vehicle/sealed/mecha/combat/honker/M) if(..()) if(istype(M)) return TRUE return FALSE -/obj/mecha/combat/honker/dark +/obj/vehicle/sealed/mecha/combat/honker/dark desc = "Produced by \"Tyranny of Honk, INC\", this exosuit is designed as heavy clown-support. This one has been painted black for maximum fun. HONK!" name = "\improper Dark H.O.N.K" icon_state = "darkhonker" max_integrity = 300 deflect_chance = 15 - armor = list("melee" = 40, "bullet" = 40, "laser" = 50, "energy" = 35, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 40, BULLET = 40, LASER = 50, ENERGY = 35, BOMB = 20, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) max_temperature = 35000 operation_req_access = list(ACCESS_SYNDICATE) internals_req_access = list(ACCESS_SYNDICATE) wreckage = /obj/structure/mecha_wreckage/honker/dark max_equip = 3 -/obj/mecha/combat/honker/dark/GrantActions(mob/living/user, human_occupant = 0) - ..() - thrusters_action.Grant(user, src) - - -/obj/mecha/combat/honker/dark/RemoveActions(mob/living/user, human_occupant = 0) - ..() - thrusters_action.Remove(user) - -/obj/mecha/combat/honker/dark/add_cell(obj/item/stock_parts/cell/C) +/obj/vehicle/sealed/mecha/combat/honker/dark/add_cell(obj/item/stock_parts/cell/C) if(C) C.forceMove(src) cell = C return cell = new /obj/item/stock_parts/cell/hyper(src) -/obj/mecha/combat/honker/dark/loaded/Initialize() +/obj/vehicle/sealed/mecha/combat/honker/dark/loaded/Initialize(mapload) . = ..() var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/honker() ME.attach(src) diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index ba9fad7a84..9a49c05739 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -39,7 +39,7 @@ antag_flag = ROLE_CULTIST false_report_weight = 10 chaos = 8 - restricted_jobs = list("AI", "Cyborg") + restricted_jobs = list("Prisoner", "AI", "Cyborg") protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") required_players = 30 required_enemies = 3 diff --git a/code/game/gamemodes/devil/devil_game_mode.dm b/code/game/gamemodes/devil/devil_game_mode.dm index 9bf7fc0e82..7fe2f91714 100644 --- a/code/game/gamemodes/devil/devil_game_mode.dm +++ b/code/game/gamemodes/devil/devil_game_mode.dm @@ -4,7 +4,7 @@ antag_flag = ROLE_DEVIL false_report_weight = 1 chaos = 3 - protected_jobs = list("Lawyer", "Curator", "Chaplain", "Head of Security", "Captain", "AI") + protected_jobs = list("Prisoner", "Lawyer", "Curator", "Chaplain", "Head of Security", "Captain", "AI") required_players = 0 required_enemies = 1 recommended_enemies = 4 diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index c7fee7df96..c31cbbdcfc 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -1,77 +1,48 @@ +#define RULESET_STOP_PROCESSING 1 -// -- Injection delays -GLOBAL_VAR_INIT(dynamic_latejoin_delay_min, (10 MINUTES)) -GLOBAL_VAR_INIT(dynamic_latejoin_delay_max, (30 MINUTES)) +#define FAKE_REPORT_CHANCE 20 +#define REPORT_NEG_DIVERGENCE -15 +#define REPORT_POS_DIVERGENCE 15 +#define EXTENDED_CURVE_CENTER -7 -GLOBAL_VAR_INIT(dynamic_midround_delay_min, (10 MINUTES)) -GLOBAL_VAR_INIT(dynamic_midround_delay_max, (30 MINUTES)) - -// -- Roundstart injection delays -GLOBAL_VAR_INIT(dynamic_first_latejoin_delay_min, (2 MINUTES)) -GLOBAL_VAR_INIT(dynamic_first_latejoin_delay_max, (30 MINUTES)) - -GLOBAL_VAR_INIT(dynamic_first_midround_delay_min, (20 MINUTES)) -GLOBAL_VAR_INIT(dynamic_first_midround_delay_max, (30 MINUTES)) - -// Are HIGHLANDER_RULESETs allowed to stack? +// Are HIGH_IMPACT_RULESETs allowed to stack? GLOBAL_VAR_INIT(dynamic_no_stacking, TRUE) -// A number between -5 and +5. -// A negative value will give a more peaceful round and -// a positive value will give a round with higher threat. -GLOBAL_VAR_INIT(dynamic_curve_centre, 0) -// A number between 0.5 and 4. -// Higher value will favour extreme rounds and -// lower value rounds closer to the average. -GLOBAL_VAR_INIT(dynamic_curve_width, 1.8) -// If enabled only picks a single starting rule and executes only autotraitor midround ruleset. -GLOBAL_VAR_INIT(dynamic_classic_secret, FALSE) -// How many roundstart players required for high population override to take effect. -GLOBAL_VAR_INIT(dynamic_high_pop_limit, 55) // If enabled does not accept or execute any rulesets. GLOBAL_VAR_INIT(dynamic_forced_extended, FALSE) -// How high threat is required for HIGHLANDER_RULESETs stacking. +// Antags still allowed, but no roundstart antags + midrounds are low impact +GLOBAL_VAR_INIT(dynamic_extended, FALSE) +// How high threat is required for HIGH_IMPACT_RULESETs stacking. // This is independent of dynamic_no_stacking. GLOBAL_VAR_INIT(dynamic_stacking_limit, 90) // List of forced roundstart rulesets. GLOBAL_LIST_EMPTY(dynamic_forced_roundstart_ruleset) // Forced threat level, setting this to zero or higher forces the roundstart threat to the value. GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) -// Storyteller picked by the voting. -GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic) -// Storyteller forced by admins during voting--will be used instead of above. -GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) /datum/game_mode/dynamic name = "dynamic mode" config_tag = "dynamic" - announce_span = "danger" announce_text = "Dynamic mode!" // This needs to be changed maybe - - reroll_friendly = FALSE; - // Current storyteller - var/datum/dynamic_storyteller/storyteller = null // Threat logging vars - /// Starting threat level, for things that increase it but can bring it back down. - var/initial_threat_level = 0 - /// Target threat level right now. Antags will try to keep the round at this level. + /// The "threat cap", threat shouldn't normally go above this and is used in ruleset calculations var/threat_level = 0 - /// The current antag threat. Recalculated every time a ruletype starts or ends. - var/threat = 0 - /// Things that cause a rolling threat adjustment to be displayed at roundend. - var/list/threat_tallies = list() + + /// Set at the beginning of the round. Spent by the mode to "purchase" rules. Everything else goes in the postround budget. + var/round_start_budget = 0 + + /// Set at the beginning of the round. Spent by midrounds and latejoins. + var/mid_round_budget = 0 + + /// The initial round start budget for logging purposes, set once at the beginning of the round. + var/initial_round_start_budget = 0 + /// Running information about the threat. Can store text or datum entries. var/list/threat_log = list() - /// As above, but with info such as refunds. - var/list/threat_log_verbose = list() - /// List of roundstart rules used for selecting the rules. - var/list/roundstart_rules = list() - /// List of minor roundstart rules used for selecting the rules. - var/list/minor_rules = list() /// List of latejoin rules used for selecting the rules. - var/list/latejoin_rules = list() + var/list/latejoin_rules /// List of midround rules used for selecting the rules. - var/list/midround_rules = list() + var/list/midround_rules /** # Pop range per requirement. * If the value is five the range is: * 0-4, 5-9, 10-14, 15-19, 20-24, 25-29, 30-34, 35-39, 40-54, 45+ @@ -80,21 +51,7 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) * If it is seven the range is: * 0-6, 7-13, 14-20, 21-27, 28-34, 35-41, 42-48, 49-55, 56-62, 63+ */ - var/pop_per_requirement = 9 - /// The requirement used for checking if a second rule should be selected. Index based on pop_per_requirement. - var/list/second_rule_req = list(100, 100, 80, 70, 60, 50, 30, 20, 10, 0) - /// The probability for a second ruleset with index being every ten threat. - var/list/second_rule_prob = list(0,0,60,80,80,80,100,100,100,100) - /// The requirement used for checking if a third rule should be selected. Index based on pop_per_requirement. - var/list/third_rule_req = list(100, 100, 100, 90, 80, 70, 60, 50, 40, 30) - /// The probability for a third ruleset with index being every ten threat. - var/list/third_rule_prob = list(0,0,0,0,60,60,80,90,100,100) - /// Threat requirement for a second ruleset when high pop override is in effect. - var/high_pop_second_rule_req = 40 - /// Threat requirement for a third ruleset when high pop override is in effect. - var/high_pop_third_rule_req = 60 - /// The amount of additional rulesets waiting to be picked. - var/extra_rulesets_amount = 0 + var/pop_per_requirement = 6 /// Number of players who were ready on roundstart. var/roundstart_pop_ready = 0 /// List of candidates used on roundstart rulesets. @@ -103,68 +60,121 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) var/list/current_rules = list() /// List of executed rulesets. var/list/executed_rules = list() - /// Associative list of current players, in order: living players, living antagonists, dead players and observers. - var/list/list/current_players = list(CURRENT_LIVING_PLAYERS, CURRENT_LIVING_ANTAGS, CURRENT_DEAD_PLAYERS, CURRENT_OBSERVERS) - /// When world.time is over this number the mode tries to inject a latejoin ruleset. - var/latejoin_injection_cooldown = 0 - /// When world.time is over this number the mode tries to inject a midround ruleset. - var/midround_injection_cooldown = 0 /// When TRUE GetInjectionChance returns 100. var/forced_injection = FALSE /// Forced ruleset to be executed for the next latejoin. var/datum/dynamic_ruleset/latejoin/forced_latejoin_rule = null - /// When current_players was updated last time. - var/pop_last_updated = 0 /// How many percent of the rounds are more peaceful. var/peaceful_percentage = 50 - /// If a highlander executed. No other highlander rulesets will be run. - var/highlander_executed = FALSE - /// If a only ruleset has been executed. No other rulesets will be run. + /// If a high impact ruleset was executed. Only one will run at a time in most circumstances. + var/high_impact_ruleset_executed = FALSE + /// If a only ruleset has been executed. var/only_ruleset_executed = FALSE - /// If the first picked ruleset was a minor ruleset. Minor antagonists will be weighted higher. - var/minor_ruleset_start = FALSE - /// Antags rolled by rules so far, to keep track of and discourage scaling past a certain ratio of crew/antags especially on lowpop. - var/antags_rolled = 0 - // Arbitrary threat addition, for fudging purposes. - var/added_threat = 50 + /// Dynamic configuration, loaded on pre_setup + var/list/configuration = null -/datum/game_mode/dynamic/New() // i have NO IDEA if this is the proper way to do this. - ..() - pop_per_requirement = CONFIG_GET(number/dynamic_pop_per_requirement) - second_rule_req = CONFIG_GET(number_list/dynamic_second_rule_requirements) - third_rule_req = CONFIG_GET(number_list/dynamic_third_rule_requirements) - if(second_rule_req.len<10) - second_rule_req = list(101, 101, 101, 101, 100, 90, 80, 70, 60, 50) - if(third_rule_req.len<10) - third_rule_req = list(101, 101, 101, 101, 101, 100, 90, 80, 70, 60) - high_pop_second_rule_req = CONFIG_GET(number/dynamic_second_rule_high_pop_requirement) - high_pop_third_rule_req = CONFIG_GET(number/dynamic_third_rule_high_pop_requirement) - added_threat = CONFIG_GET(number/dynamic_threat_baseline) - GLOB.dynamic_high_pop_limit = CONFIG_GET(number/dynamic_high_pop_limit) - GLOB.dynamic_latejoin_delay_min = CONFIG_GET(number/dynamic_latejoin_delay_min)*600 - GLOB.dynamic_latejoin_delay_max = CONFIG_GET(number/dynamic_latejoin_delay_max)*600 - GLOB.dynamic_midround_delay_min = CONFIG_GET(number/dynamic_midround_delay_min)*600 - GLOB.dynamic_midround_delay_max = CONFIG_GET(number/dynamic_midround_delay_max)*600 - GLOB.dynamic_first_latejoin_delay_min = CONFIG_GET(number/dynamic_first_latejoin_delay_min)*600 - GLOB.dynamic_first_latejoin_delay_max = CONFIG_GET(number/dynamic_first_latejoin_delay_max)*600 - GLOB.dynamic_first_midround_delay_min = CONFIG_GET(number/dynamic_first_midround_delay_min)*600 - GLOB.dynamic_first_midround_delay_max = CONFIG_GET(number/dynamic_first_midround_delay_max)*600 + /// When world.time is over this number the mode tries to inject a latejoin ruleset. + var/latejoin_injection_cooldown = 0 + + /// The minimum time the recurring latejoin ruleset timer is allowed to be. + var/latejoin_delay_min = (5 MINUTES) + + /// The maximum time the recurring latejoin ruleset timer is allowed to be. + var/latejoin_delay_max = (25 MINUTES) + + /// When world.time is over this number the mode tries to inject a midround ruleset. + var/midround_injection_cooldown = 0 + + /// The minimum time the recurring midround ruleset timer is allowed to be. + var/midround_delay_min = (15 MINUTES) + + /// The maximum time the recurring midround ruleset timer is allowed to be. + var/midround_delay_max = (35 MINUTES) + + /// If above this threat, increase the chance of injection + var/higher_injection_chance_minimum_threat = 70 + + /// The chance of injection increase when above higher_injection_chance_minimum_threat + var/higher_injection_chance = 15 + + /// If below this threat, decrease the chance of injection + var/lower_injection_chance_minimum_threat = 10 + + /// The chance of injection decrease when above lower_injection_chance_minimum_threat + var/lower_injection_chance = 15 + + /// A number between -5 and +5. + /// A negative value will give a more peaceful round and + /// a positive value will give a round with higher threat. + var/threat_curve_centre = 0 + + /// A number between 0.5 and 4. + /// Higher value will favour extreme rounds and + /// lower value rounds closer to the average. + var/threat_curve_width = 1.8 + + /// A number between -5 and +5. + /// Equivalent to threat_curve_centre, but for the budget split. + /// A negative value will weigh towards midround rulesets, and a positive + /// value will weight towards roundstart ones. + var/roundstart_split_curve_centre = 1 + + /// A number between 0.5 and 4. + /// Equivalent to threat_curve_width, but for the budget split. + /// Higher value will favour more variance in splits and + /// lower value rounds closer to the average. + var/roundstart_split_curve_width = 1.8 + + /// The minimum amount of time for antag random events to be hijacked. + var/random_event_hijack_minimum = 10 MINUTES + + /// The maximum amount of time for antag random events to be hijacked. + var/random_event_hijack_maximum = 18 MINUTES + + /// A list of recorded "snapshots" of the round, stored in the dynamic.json log + var/list/datum/dynamic_snapshot/snapshots + + /// The time when the last midround injection was attempted, whether or not it was successful + var/last_midround_injection_attempt = 0 + + /// The amount to inject when a round event is hijacked + var/hijacked_random_event_injection_chance = 50 + + /// Whether or not a random event has been hijacked this midround cycle + var/random_event_hijacked = HIJACKED_NOTHING + + /// The timer ID for the cancellable midround rule injection + var/midround_injection_timer_id + + /// The last drafted midround rulesets (without the current one included). + /// Used for choosing different midround injections. + var/list/current_midround_rulesets + + /// The amount of threat shown on the piece of paper. + /// Can differ from the actual threat amount. + var/shown_threat /datum/game_mode/dynamic/admin_panel() var/list/dat = list("Game Mode Panel

    Game Mode Panel

    ") - dat += "Dynamic Mode \[VV\]\[Refresh\]
    " - dat += "Target threat: [threat_level]
    " + dat += "Dynamic Mode \[VV\] \[Refresh\]
    " + dat += "Threat Level: [threat_level]
    " + dat += "Budgets (Roundstart/Midrounds): [initial_round_start_budget]/[threat_level - initial_round_start_budget]
    " - dat += "Current threat: [threat] \[Adjust\] \[View Log\]
    " + dat += "Midround budget to spend: [mid_round_budget] \[Adjust\] \[View Log\]
    " dat += "
    " - dat += "Storyteller: [storyteller.name]
    " - dat += "Parameters: centre = [GLOB.dynamic_curve_centre] ; width = [GLOB.dynamic_curve_width].
    " + dat += "Parameters: centre = [threat_curve_centre] ; width = [threat_curve_width].
    " + dat += "Split parameters: centre = [roundstart_split_curve_centre] ; width = [roundstart_split_curve_width].
    " dat += "On average, [peaceful_percentage]% of the rounds are more peaceful.
    " dat += "Forced extended: [GLOB.dynamic_forced_extended ? "On" : "Off"]
    " - dat += "Classic secret (only autotraitor): [GLOB.dynamic_classic_secret ? "On" : "Off"]
    " + dat += "Dynamic extended: [GLOB.dynamic_extended ? "On" : "Off"]
    " dat += "No stacking (only one round-ender): [GLOB.dynamic_no_stacking ? "On" : "Off"]
    " dat += "Stacking limit: [GLOB.dynamic_stacking_limit] \[Adjust\]" dat += "
    " + dat += "\[Force Next Latejoin Ruleset\]
    " + if (forced_latejoin_rule) + dat += {"-> [forced_latejoin_rule.name] <-
    "} + dat += "\[Execute Midround Ruleset\]
    " + dat += "
    " dat += "Executed rulesets: " if (executed_rules.len > 0) dat += "
    " @@ -172,7 +182,7 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) dat += "[DR.ruletype] - [DR.name]
    " else dat += "none.
    " - dat += "
    Injection Timers:
    " + dat += "
    Injection Timers: ([get_injection_chance(dry_run = TRUE)]% latejoin chance, [get_midround_injection_chance(dry_run = TRUE)]% midround chance)
    " dat += "Latejoin: [(latejoin_injection_cooldown-world.time)>60*10 ? "[round((latejoin_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(latejoin_injection_cooldown-world.time)/10] seconds"] \[Now!\]
    " dat += "Midround: [(midround_injection_cooldown-world.time)>60*10 ? "[round((midround_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(midround_injection_cooldown-world.time)/10] seconds"] \[Now!\]
    " usr << browse(dat.Join(), "window=gamemode_panel;size=500x500") @@ -186,94 +196,93 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) return if (href_list["forced_extended"]) GLOB.dynamic_forced_extended = !GLOB.dynamic_forced_extended + else if (href_list["extended"]) + GLOB.dynamic_extended = !GLOB.dynamic_extended else if (href_list["no_stacking"]) GLOB.dynamic_no_stacking = !GLOB.dynamic_no_stacking - else if (href_list["classic_secret"]) - GLOB.dynamic_classic_secret = !GLOB.dynamic_classic_secret else if (href_list["adjustthreat"]) var/threatadd = input("Specify how much threat to add (negative to subtract). This can inflate the threat level.", "Adjust Threat", 0) as null|num if(!threatadd) return - create_threat(threatadd) + if(threatadd > 0) + create_threat(threatadd) + threat_log += "[worldtime2text()]: [key_name(usr)] increased threat by [threatadd] threat." + else + spend_midround_budget(-threatadd) + threat_log += "[worldtime2text()]: [key_name(usr)] decreased threat by [-threatadd] threat." else if (href_list["injectlate"]) latejoin_injection_cooldown = 0 forced_injection = TRUE - message_admins("[key_name(usr)] forced a latejoin injection.", 1) + message_admins("[key_name(usr)] forced a latejoin injection.") else if (href_list["injectmid"]) midround_injection_cooldown = 0 forced_injection = TRUE - message_admins("[key_name(usr)] forced a midround injection.", 1) + message_admins("[key_name(usr)] forced a midround injection.") else if (href_list["threatlog"]) show_threatlog(usr) else if (href_list["stacking_limit"]) GLOB.dynamic_stacking_limit = input(usr,"Change the threat limit at which round-endings rulesets will start to stack.", "Change stacking limit", null) as num - else if (href_list["change_storyteller"]) - var/list/choices = list() - for(var/T in config.storyteller_cache) - var/datum/dynamic_storyteller/S = T - choices[initial(S.name)] = T - var/selected_storyteller = choices[input("Select storyteller:", "Storyteller", storyteller.name) as null|anything in choices] - storyteller = new selected_storyteller - storyteller.on_start() - message_admins("[key_name(usr)] changed the storyteller to [storyteller].", 1) + else if(href_list["force_latejoin_rule"]) + var/added_rule = input(usr,"What ruleset do you want to force upon the next latejoiner? This will bypass threat level and population restrictions.", "Rigging Latejoin", null) as null|anything in sortNames(init_rulesets(/datum/dynamic_ruleset/latejoin)) + if (!added_rule) + return + forced_latejoin_rule = added_rule + log_admin("[key_name(usr)] set [added_rule] to proc on the next latejoin.") + message_admins("[key_name(usr)] set [added_rule] to proc on the next latejoin.") + else if(href_list["clear_forced_latejoin"]) + forced_latejoin_rule = null + log_admin("[key_name(usr)] cleared the forced latejoin ruleset.") + message_admins("[key_name(usr)] cleared the forced latejoin ruleset.") + else if(href_list["force_midround_rule"]) + var/added_rule = input(usr,"What ruleset do you want to force right now? This will bypass threat level and population restrictions.", "Execute Ruleset", null) as null|anything in sortNames(init_rulesets(/datum/dynamic_ruleset/midround)) + if (!added_rule) + return + log_admin("[key_name(usr)] executed the [added_rule] ruleset.") + message_admins("[key_name(usr)] executed the [added_rule] ruleset.") + picking_specific_rule(added_rule, TRUE) + else if(href_list["cancelmidround"]) + admin_cancel_midround(usr, href_list["cancelmidround"]) + return + else if (href_list["differentmidround"]) + admin_different_midround(usr, href_list["differentmidround"]) + return admin_panel() // Refreshes the window -// Checks if there are HIGHLANDER_RULESETs and calls the rule's round_result() proc +// Checks if there are HIGH_IMPACT_RULESETs and calls the rule's round_result() proc /datum/game_mode/dynamic/set_round_result() + // If it got to this part, just pick one high impact ruleset if it exists for(var/datum/dynamic_ruleset/rule in executed_rules) - if(rule.flags & HIGHLANDER_RULESET) - if(rule.check_finished()) // Only the rule that actually finished the round sets round result. - return rule.round_result() - // If it got to this part, just pick one highlander if it exists - for(var/datum/dynamic_ruleset/rule in executed_rules) - if(rule.flags & HIGHLANDER_RULESET) + if(rule.flags & HIGH_IMPACT_RULESET) return rule.round_result() return ..() -/datum/game_mode/dynamic/generate_report() - return "Mysterious signals that demonstrate strange dynamics have been detected in your sector. Watch out for oddities." - /datum/game_mode/dynamic/send_intercept() . = "Central Command Status Summary
    " - switch(round(threat_level)) - if(-INFINITY to 20) - . += "Peaceful Waypoint
    " - . += "Your station orbits deep within controlled, core-sector systems and serves as a waypoint for routine traffic through Nanotrasen's trade empire. Due to the combination of high security, interstellar traffic, and low strategic value, it makes any direct threat of violence unlikely. Your primary enemies will be incompetence and bored crewmen: try to organize team-building events to keep staffers interested and productive. However, even deep in our territory there may be subversive elements, especially for such a high-value target as your station. Keep an eye out, but don't expect much trouble." - set_security_level(SEC_LEVEL_GREEN) - station_goals.len = 0 - for(var/T in subtypesof(/datum/station_goal)) - var/datum/station_goal/G = new T - if(!(G in station_goals)) - station_goals += G - if(21 to 79) - var/perc_green = 100-round(100*((threat_level-21)/(79-21))) - if(prob(perc_green)) + switch(round(shown_threat)) + if(0 to 19) + if(!current_players[CURRENT_LIVING_ANTAGS].len) + . += "Peaceful Waypoint
    " + . += "Your station orbits deep within controlled, core-sector systems and serves as a waypoint for routine traffic through Nanotrasen's trade empire. Due to the combination of high security, interstellar traffic, and low strategic value, it makes any direct threat of violence unlikely. Your primary enemies will be incompetence and bored crewmen: try to organize team-building events to keep staffers interested and productive." + else . += "Core Territory
    " . += "Your station orbits within reliably mundane, secure space. Although Nanotrasen has a firm grip on security in your region, the valuable resources and strategic position aboard your station make it a potential target for infiltrations. Monitor crew for non-loyal behavior, but expect a relatively tame shift free of large-scale destruction. We expect great things from your station." - set_security_level(SEC_LEVEL_GREEN) - station_goals.len = 0 - for(var/T in subtypesof(/datum/station_goal)) - var/datum/station_goal/G = new T - if(!(G in station_goals)) - station_goals += G - else if(prob(perc_green)) - . += "Contested System
    " - . += "Your station's orbit passes along the edge of Nanotrasen's sphere of influence. While subversive elements remain the most likely threat against your station, hostile organizations are bolder here, where our grip is weaker. Exercise increased caution against elite Syndicate strike forces, or Executives forbid, some kind of ill-conceived unionizing attempt." - set_security_level(SEC_LEVEL_BLUE) - else - . += "Uncharted Space
    " - . += "Congratulations and thank you for participating in the NT 'Frontier' space program! Your station is actively orbiting a high value system far from the nearest support stations. Little is known about your region of space, and the opportunity to encounter the unknown invites greater glory. You are encouraged to elevate security as necessary to protect Nanotrasen assets." - set_security_level(SEC_LEVEL_BLUE) - if(80 to 95) + if(20 to 39) + . += "Anomalous Exogeology
    " + . += "Although your station lies within what is generally considered Nanotrasen-controlled space, the course of its orbit has caused it to cross unusually close to exogeological features with anomalous readings. Although these features offer opportunities for our research department, it is known that these little understood readings are often correlated with increased activity from competing interstellar organizations and individuals, among them the Wizard Federation and Cult of the Geometer of Blood - all known competitors for Anomaly Type B sites. Exercise elevated caution." + if(40 to 65) + . += "Contested System
    " + . += "Your station's orbit passes along the edge of Nanotrasen's sphere of influence. While subversive elements remain the most likely threat against your station, hostile organizations are bolder here, where our grip is weaker. Exercise increased caution against elite Syndicate strike forces, or Executives forbid, some kind of ill-conceived unionizing attempt." + if(66 to 79) + . += "Uncharted Space
    " + . += "Congratulations and thank you for participating in the NT 'Frontier' space program! Your station is actively orbiting a high value system far from the nearest support stations. Little is known about your region of space, and the opportunity to encounter the unknown invites greater glory. You are encouraged to elevate security as necessary to protect Nanotrasen assets." + if(80 to 99) . += "Black Orbit
    " . += "As part of a mandatory security protocol, we are required to inform you that as a result of your orbital pattern directly behind an astrological body (oriented from our nearest observatory), your station will be under decreased monitoring and support. It is anticipated that your extreme location and decreased surveillance could pose security risks. Avoid unnecessary risks and attempt to keep your station in one piece." - set_security_level(SEC_LEVEL_AMBER) - if(96 to INFINITY) + if(100) . += "Impending Doom
    " . += "Your station is somehow in the middle of hostile territory, in clear view of any enemy of the corporation. Your likelihood to survive is low, and station destruction is expected and almost inevitable. Secure any sensitive material and neutralize any enemy you will come across. It is important that you at least try to maintain the station.
    " . += "Good luck." - set_security_level(SEC_LEVEL_RED) if(station_goals.len) . += "
    Special Orders for [station_name()]:" @@ -282,340 +291,282 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) . += G.get_report() print_command_report(., "Central Command Status Summary", announce=FALSE) - if(GLOB.security_level >= SEC_LEVEL_BLUE) - priority_announce("A summary has been copied and printed to all communications consoles.", "Security level elevated.", "intercept") - else - priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no likely threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", "commandreport") - -// Yes, this is copy pasted from game_mode -/datum/game_mode/dynamic/check_finished(force_ending) - if(!SSticker.setup_done || !gamemode_ready) - return FALSE - if(replacementmode && round_converted == 2) - return replacementmode.check_finished() - if(SSshuttle.emergency && (SSshuttle.emergency.mode == SHUTTLE_ENDGAME)) - return TRUE - if(station_was_nuked) - return TRUE - if(force_ending) - return TRUE - for(var/datum/dynamic_ruleset/rule in executed_rules) - if(rule.flags & HIGHLANDER_RULESET) - return rule.check_finished() - -/datum/game_mode/dynamic/proc/log_threat(var/log_str,var/verbose = FALSE) - threat_log_verbose += ("[worldtime2text()]: "+log_str) - SSblackbox.record_feedback("tally","dynamic_threat_log",1,log_str) - if(!verbose) - threat_log += log_str + priority_announce("A summary has been copied and printed to all communications consoles.", "Enemy communication intercepted. Security level elevated.", "intercept") + if(GLOB.security_level < SEC_LEVEL_BLUE) + set_security_level(SEC_LEVEL_BLUE) /datum/game_mode/dynamic/proc/show_threatlog(mob/admin) if(!SSticker.HasRoundStarted()) - alert("The round hasn't started yet!") + tgui_alert(usr, "The round hasn't started yet!") return if(!check_rights(R_ADMIN)) return - var/list/out = list("Threat LogThreat Log
    Starting Threat: [initial_threat_level]
    ") + var/list/out = list("Threat LogThreat Log
    Starting Threat: [threat_level]
    ") - for(var/entry in threat_log_verbose) + for(var/entry in threat_log) if(istext(entry)) out += "[entry]
    " - out += "Remaining threat/threat_level: [threat]/[threat_level]" + out += "Remaining threat/threat_level: [mid_round_budget]/[threat_level]" usr << browse(out.Join(), "window=threatlog;size=700x500") /// Generates the threat level using lorentz distribution and assigns peaceful_percentage. /datum/game_mode/dynamic/proc/generate_threat() - var/relative_threat = LORENTZ_DISTRIBUTION(GLOB.dynamic_curve_centre, GLOB.dynamic_curve_width) - threat_level = round(lorentz_to_threat(relative_threat), 0.1) - - peaceful_percentage = round(LORENTZ_CUMULATIVE_DISTRIBUTION(relative_threat, GLOB.dynamic_curve_centre, GLOB.dynamic_curve_width), 0.01)*100 + if(GLOB.dynamic_extended) + threat_curve_centre = EXTENDED_CURVE_CENTER + var/relative_threat = LORENTZ_DISTRIBUTION(threat_curve_centre, threat_curve_width) + threat_level = round(lorentz_to_amount(relative_threat), 0.1) + peaceful_percentage = round(LORENTZ_CUMULATIVE_DISTRIBUTION(relative_threat, threat_curve_centre, threat_curve_width), 0.01)*100 SSblackbox.record_feedback("tally","dynamic_threat",threat_level,"Initial threat level") - SSblackbox.record_feedback("tally","dynamic_threat",GLOB.dynamic_curve_centre,"Curve centre") - SSblackbox.record_feedback("tally","dynamic_threat",GLOB.dynamic_curve_width,"Curve width") - SSblackbox.record_feedback("tally","dynamic_threat",peaceful_percentage,"Percent of same-vote rounds that are more peaceful") + SSblackbox.record_feedback("tally","dynamic_threat",threat_curve_centre,"Curve centre") + SSblackbox.record_feedback("tally","dynamic_threat",threat_curve_width,"Curve width") + SSblackbox.record_feedback("tally","dynamic_threat",peaceful_percentage,"Percent of same-center rounds that are more peaceful") -/datum/game_mode/dynamic/can_start() - if(GLOB.dynamic_forced_storyteller) - GLOB.dynamic_storyteller_type = GLOB.dynamic_forced_storyteller - storyteller = new GLOB.dynamic_storyteller_type // this is where all the initialization happens - storyteller.on_start() - SSblackbox.record_feedback("text","dynamic_storyteller",1,storyteller.name) - message_admins("Dynamic mode parameters for the round:\n\ - Storyteller is [storyteller.name].\n\ - Centre is [GLOB.dynamic_curve_centre], Width is [GLOB.dynamic_curve_width], Forced extended is [GLOB.dynamic_forced_extended ? "Enabled" : "Disabled"], No stacking is [GLOB.dynamic_no_stacking ? "Enabled" : "Disabled"].\n\ - Stacking limit is [GLOB.dynamic_stacking_limit], Classic secret is [GLOB.dynamic_classic_secret ? "Enabled" : "Disabled"], High population limit is [GLOB.dynamic_high_pop_limit].") +/// Generates the midround and roundstart budgets +/datum/game_mode/dynamic/proc/generate_budgets() + if(GLOB.dynamic_extended) + mid_round_budget = threat_level + round_start_budget = 0 + else + var/relative_round_start_budget_scale = LORENTZ_DISTRIBUTION(roundstart_split_curve_centre, roundstart_split_curve_width) + round_start_budget = round((lorentz_to_amount(relative_round_start_budget_scale) / 100) * threat_level, 0.1) + initial_round_start_budget = round_start_budget + mid_round_budget = threat_level - round_start_budget + +/datum/game_mode/dynamic/proc/setup_parameters() log_game("DYNAMIC: Dynamic mode parameters for the round:") - log_game("DYNAMIC: Centre is [GLOB.dynamic_curve_centre], Width is [GLOB.dynamic_curve_width], Forced extended is [GLOB.dynamic_forced_extended ? "Enabled" : "Disabled"], No stacking is [GLOB.dynamic_no_stacking ? "Enabled" : "Disabled"].") - log_game("DYNAMIC: Stacking limit is [GLOB.dynamic_stacking_limit], Classic secret is [GLOB.dynamic_classic_secret ? "Enabled" : "Disabled"], High population limit is [GLOB.dynamic_high_pop_limit].") + log_game("DYNAMIC: Centre is [threat_curve_centre], Width is [threat_curve_width], Extended is [GLOB.dynamic_extended ? "Enabled" : "Disabled"], No stacking is [GLOB.dynamic_no_stacking ? "Enabled" : "Disabled"].") + log_game("DYNAMIC: Stacking limit is [GLOB.dynamic_stacking_limit].") if(GLOB.dynamic_forced_threat_level >= 0) threat_level = round(GLOB.dynamic_forced_threat_level, 0.1) - threat = threat_level - SSblackbox.record_feedback("tally","dynamic_threat",threat_level,"Threat level (forced)") else generate_threat() - - storyteller.start_injection_cooldowns() - log_game("DYNAMIC: Dynamic Mode initialized with a Threat Level of... [threat_level]!") - initial_threat_level = threat_level + generate_budgets() + set_cooldowns() + log_game("DYNAMIC: Dynamic Mode initialized with a Threat Level of... [threat_level]! ([round_start_budget] round start budget)") return TRUE +/datum/game_mode/dynamic/proc/setup_shown_threat() + if (prob(FAKE_REPORT_CHANCE)) + shown_threat = rand(1, 100) + else + shown_threat = clamp(threat_level + rand(REPORT_NEG_DIVERGENCE, REPORT_POS_DIVERGENCE), 0, 100) + +/datum/game_mode/dynamic/proc/set_cooldowns() + var/coeff = GLOB.dynamic_extended ? 2 : 1 + latejoin_delay_min *= coeff + latejoin_delay_max *= coeff + var/latejoin_injection_cooldown_middle = 0.5*(latejoin_delay_max + latejoin_delay_min) + latejoin_injection_cooldown = round(clamp(EXP_DISTRIBUTION(latejoin_injection_cooldown_middle), latejoin_delay_min, latejoin_delay_max)) + world.time + + midround_delay_min *= coeff + midround_delay_max *= coeff + + var/midround_injection_cooldown_middle = 0.5*(midround_delay_max + midround_delay_min) + midround_injection_cooldown = round(clamp(EXP_DISTRIBUTION(midround_injection_cooldown_middle), midround_delay_min, midround_delay_max)) + world.time + /datum/game_mode/dynamic/pre_setup() - for (var/rule in subtypesof(/datum/dynamic_ruleset)) - var/datum/dynamic_ruleset/ruleset = new rule() - // Simple check if the ruleset should be added to the lists. - if(ruleset.name == "") - continue - switch(ruleset.ruletype) - if("Minor") - minor_rules += ruleset - if("Roundstart") - roundstart_rules += ruleset - if ("Latejoin") - latejoin_rules += ruleset - if ("Midround") - if (ruleset.weight) - midround_rules += ruleset - for(var/mob/dead/new_player/player in GLOB.player_list) - if(player.ready == PLAYER_READY_TO_PLAY && player.mind) + if(CONFIG_GET(flag/dynamic_config_enabled)) + var/json_file = file("[global.config.directory]/dynamic.json") + if(fexists(json_file)) + configuration = json_decode(file2text(json_file)) + if(configuration["Dynamic"]) + for(var/variable in configuration["Dynamic"]) + if(!(variable in vars)) + stack_trace("Invalid dynamic configuration variable [variable] in game mode variable changes.") + continue + vars[variable] = configuration["Dynamic"][variable] + + setup_parameters() + setup_hijacking() + setup_shown_threat() + setup_rulesets() + + //We do this here instead of with the midround rulesets and such because these rules can hang refs + //To new_player and such, and we want the datums to just free when the roundstart work is done + var/list/roundstart_rules = init_rulesets(/datum/dynamic_ruleset/roundstart) + + for(var/i in GLOB.new_player_list) + var/mob/dead/new_player/player = i + if(player.ready == PLAYER_READY_TO_PLAY && player.mind && player.check_preferences()) roundstart_pop_ready++ candidates.Add(player) log_game("DYNAMIC: Listing [roundstart_rules.len] round start rulesets, and [candidates.len] players ready.") if (candidates.len <= 0) log_game("DYNAMIC: [candidates.len] candidates.") return TRUE - if (roundstart_rules.len <= 0) - log_game("DYNAMIC: [roundstart_rules.len] rules.") - return TRUE SSblackbox.record_feedback("tally","dynamic",roundstart_rules.len,"Roundstart rules considered") SSblackbox.record_feedback("tally","dynamic",roundstart_pop_ready,"Players readied up") + if(GLOB.dynamic_forced_roundstart_ruleset.len > 0) rigged_roundstart() else - roundstart() - if(minor_ruleset_start) - log_game("DYNAMIC: Starting a minor ruleset round.") - else - var/starting_rulesets = "" - for (var/datum/dynamic_ruleset/roundstart/DR in executed_rules) - starting_rulesets += "[DR.name], " - log_game("DYNAMIC: Picked the following roundstart rules: [starting_rulesets]") + roundstart(roundstart_rules) + + log_game("DYNAMIC: [round_start_budget] round start budget was left, donating it to midrounds.") + threat_log += "[worldtime2text()]: [round_start_budget] round start budget was left, donating it to midrounds." + mid_round_budget += round_start_budget + + var/starting_rulesets = "" + for (var/datum/dynamic_ruleset/roundstart/DR in executed_rules) + starting_rulesets += "[DR.name], " + log_game("DYNAMIC: Picked the following roundstart rules: [starting_rulesets]") candidates.Cut() return TRUE /datum/game_mode/dynamic/post_setup(report) - update_playercounts() - if(minor_ruleset_start) - addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/minor_roundstart),rand(1 MINUTES,3 MINUTES)) - else - for(var/datum/dynamic_ruleset/roundstart/rule in executed_rules) - addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/execute_roundstart_rule, rule), rule.delay) + for(var/datum/dynamic_ruleset/roundstart/rule in executed_rules) + rule.candidates.Cut() // The rule should not use candidates at this point as they all are null. + addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/execute_roundstart_rule, rule), rule.delay) + ..() -/datum/game_mode/dynamic/proc/minor_roundstart() - message_admins("Dynamic beginning minor antag roundstart rolls.") - var/list/potential_minor_rulesets = storyteller.minor_rule_draft() - var/iterations = 0 - var/num_rulesets_executed = 0 - while(threat < threat_level && potential_minor_rulesets.len && (!CHECK_TICK || iterations < 100)) - var/datum/dynamic_ruleset/minor/rule = pickweight(potential_minor_rulesets) - rule.candidates = current_players[CURRENT_LIVING_PLAYERS].Copy() - rule.trim_candidates() - if(!check_blocking(rule.blocking_rules, executed_rules) && rule.ready()) - rule.execute() - executed_rules |= rule - log_threat("[rule.ruletype] - [rule.name] [rule.cost] threat", verbose = TRUE) - num_rulesets_executed++ - else - potential_minor_rulesets -= rule - update_playercounts() - iterations++ - message_admins("Minor antag roundstart rolls completed, with [iterations] rolls done and [num_rulesets_executed] antags or antag teams made.") - log_game("DYNAMIC: Minor antag roundstart made [num_rulesets_executed] antags or antag teams.") +/// Initializes the internal ruleset variables +/datum/game_mode/dynamic/proc/setup_rulesets() + midround_rules = init_rulesets(/datum/dynamic_ruleset/midround) + latejoin_rules = init_rulesets(/datum/dynamic_ruleset/latejoin) +/// Returns a list of the provided rulesets. +/// Configures their variables to match config. +/datum/game_mode/dynamic/proc/init_rulesets(ruleset_subtype) + var/list/rulesets = list() + + for (var/datum/dynamic_ruleset/ruleset_type as anything in subtypesof(ruleset_subtype)) + if (initial(ruleset_type.name) == "") + continue + + if (initial(ruleset_type.weight) == 0) + continue + + var/ruleset = new ruleset_type + configure_ruleset(ruleset) + rulesets += ruleset + + return rulesets /// A simple roundstart proc used when dynamic_forced_roundstart_ruleset has rules in it. /datum/game_mode/dynamic/proc/rigged_roundstart() message_admins("[GLOB.dynamic_forced_roundstart_ruleset.len] rulesets being forced. Will now attempt to draft players for them.") log_game("DYNAMIC: [GLOB.dynamic_forced_roundstart_ruleset.len] rulesets being forced. Will now attempt to draft players for them.") for (var/datum/dynamic_ruleset/roundstart/rule in GLOB.dynamic_forced_roundstart_ruleset) + configure_ruleset(rule) message_admins("Drafting players for forced ruleset [rule.name].") log_game("DYNAMIC: Drafting players for forced ruleset [rule.name].") rule.mode = src - rule.acceptable(roundstart_pop_ready, threat_level) // Assigns some vars in the modes, running it here for consistency + rule.acceptable(roundstart_pop_ready, threat_level) // Assigns some vars in the modes, running it here for consistency rule.candidates = candidates.Copy() rule.trim_candidates() - if (rule.ready(TRUE)) - picking_roundstart_rule(list(rule), forced = TRUE) + if (rule.ready(roundstart_pop_ready, TRUE)) + var/cost = rule.cost + var/scaled_times = 0 + if (rule.scaling_cost) + scaled_times = round(max(round_start_budget - cost, 0) / rule.scaling_cost) + cost += rule.scaling_cost * scaled_times -/datum/game_mode/dynamic/proc/roundstart() + spend_roundstart_budget(picking_roundstart_rule(rule, scaled_times, forced = TRUE)) + +/datum/game_mode/dynamic/proc/roundstart(list/roundstart_rules) if (GLOB.dynamic_forced_extended) log_game("DYNAMIC: Starting a round of forced extended.") return TRUE - if(prob(storyteller.minor_start_chance())) - minor_ruleset_start = TRUE - message_admins("Dynamic has initialized a minor antag start. Antags will be assigned in 1-5 minutes.") - log_game("DYNAMIC: Minor start initialized.") + if (GLOB.dynamic_extended) + log_game("DYNAMIC: Starting a round of dynamic extended.") return TRUE - var/list/drafted_rules = storyteller.roundstart_draft() - if(!drafted_rules.len) - message_admins("No roundstart antags drafted! Falling back to minor ruleset start.") - log_game("DYNAMIC: No roundstart antags drafted! Falling back to minor ruleset start.") - minor_ruleset_start = TRUE - return FALSE - var/indice_pop = min(10,round(roundstart_pop_ready/pop_per_requirement)+1) - extra_rulesets_amount = 0 - if (GLOB.dynamic_classic_secret) - extra_rulesets_amount = 0 - else - if (roundstart_pop_ready > GLOB.dynamic_high_pop_limit) - message_admins("High Population Override is in effect! Threat Level will have more impact on which roles will appear, and player population less.") - log_game("DYNAMIC: High Population Override is in effect! Threat Level will have more impact on which roles will appear, and player population less.") - if (threat_level > high_pop_second_rule_req) - extra_rulesets_amount++ - if (threat_level > high_pop_third_rule_req) - extra_rulesets_amount++ - else - var/threat_indice = min(10, max(round(threat_level ? threat_level/10 : 1), 1)) // 0-9 threat = 1, 10-19 threat = 2 ... - if (threat_level >= second_rule_req[indice_pop] && prob(second_rule_prob[threat_indice])) - extra_rulesets_amount++ - if (threat_level >= third_rule_req[indice_pop] && prob(third_rule_prob[threat_indice])) - extra_rulesets_amount++ - log_game("DYNAMIC: Trying to roll [extra_rulesets_amount + 1] roundstart rulesets. Picking from [drafted_rules.len] eligible rulesets.") + var/list/drafted_rules = list() + for (var/datum/dynamic_ruleset/roundstart/rule in roundstart_rules) + if (!rule.weight) + continue + if (rule.acceptable(roundstart_pop_ready, threat_level) && round_start_budget >= rule.cost) // If we got the population and threat required + rule.candidates = candidates.Copy() + rule.trim_candidates() + if (rule.ready(roundstart_pop_ready) && rule.candidates.len > 0) + drafted_rules[rule] = rule.weight - if (drafted_rules.len > 0 && picking_roundstart_rule(drafted_rules)) - log_game("DYNAMIC: First ruleset picked successfully. [extra_rulesets_amount] remaining.") - while(extra_rulesets_amount > 0 && drafted_rules.len > 0) // We had enough threat for one or two more rulesets - for (var/datum/dynamic_ruleset/roundstart/rule in drafted_rules) - if (rule.cost > threat) - drafted_rules -= rule - if(drafted_rules.len) - picking_roundstart_rule(drafted_rules) - extra_rulesets_amount-- - log_game("DYNAMIC: Additional ruleset picked successfully, now [executed_rules.len] picked. [extra_rulesets_amount] remaining.") - else + var/list/rulesets_picked = list() - if(threat_level >= 50) - message_admins("DYNAMIC: Picking first roundstart ruleset failed. You should report this. Falling back to minor antag start.") - log_game("DYNAMIC: Picking first roundstart ruleset failed. drafted_rules.len = [drafted_rules.len] and threat = [threat]/[threat_level]") - minor_ruleset_start = TRUE - return FALSE - return TRUE + // Kept in case a ruleset can't be initialized for whatever reason, we want to be able to only spend what we can use. + var/round_start_budget_left = round_start_budget -/// Picks a random roundstart rule from the list given as an argument and executes it. -/datum/game_mode/dynamic/proc/picking_roundstart_rule(list/drafted_rules = list(), forced = FALSE) - var/datum/dynamic_ruleset/roundstart/starting_rule = pickweight(drafted_rules) - if(!starting_rule) - log_game("DYNAMIC: Couldn't pick a starting ruleset. No rulesets available") - return FALSE + while (round_start_budget_left > 0) + var/datum/dynamic_ruleset/roundstart/ruleset = pickweightAllowZero(drafted_rules) + if (isnull(ruleset)) + log_game("DYNAMIC: No more rules can be applied, stopping with [round_start_budget] left.") + break - if(!forced) - if(only_ruleset_executed) - return FALSE - // Check if a blocking ruleset has been executed. - else if(check_blocking(starting_rule.blocking_rules, executed_rules)) // Should already be filtered out, but making sure. Check filtering at end of proc if reported. - drafted_rules -= starting_rule - if(drafted_rules.len <= 0) - log_game("DYNAMIC: Picking [starting_rule.name] failed due to blocking_rules and no more rulesets available. Report this.") - return FALSE - starting_rule = pickweight(drafted_rules) - // Check if the ruleset is highlander and if a highlander ruleset has been executed - else if(starting_rule.flags & HIGHLANDER_RULESET) // Should already be filtered out, but making sure. Check filtering at end of proc if reported. - if(threat_level <= GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) - if(highlander_executed) - drafted_rules -= starting_rule - if(drafted_rules.len <= 0) - log_game("DYNAMIC: Picking [starting_rule.name] failed due to no highlander stacking and no more rulesets available. Report this.") - return FALSE - starting_rule = pickweight(drafted_rules) - // With low pop and high threat there might be rulesets that get executed with no valid candidates. - else if(!starting_rule.ready()) // Should already be filtered out, but making sure. Check filtering at end of proc if reported. - drafted_rules -= starting_rule - if(drafted_rules.len <= 0) - log_game("DYNAMIC: Picking [starting_rule.name] failed because there were not enough candidates and no more rulesets available. Report this.") - return FALSE - starting_rule = pickweight(drafted_rules) + var/cost = (ruleset in rulesets_picked) ? ruleset.scaling_cost : ruleset.cost + if (cost == 0) + stack_trace("[ruleset] cost 0, this is going to result in an infinite loop.") + drafted_rules[ruleset] = null + continue - log_game("DYNAMIC: Picked a ruleset: [starting_rule.name]") + if (cost > round_start_budget_left) + drafted_rules[ruleset] = null + continue - roundstart_rules -= starting_rule - drafted_rules -= starting_rule + if (check_blocking(ruleset.blocking_rules, rulesets_picked)) + drafted_rules[ruleset] = null + continue - starting_rule.trim_candidates() - if (starting_rule.pre_execute()) - log_threat("[starting_rule.ruletype] - [starting_rule.name] [starting_rule.cost + starting_rule.scaled_times * starting_rule.scaling_cost] threat", verbose = TRUE) - if(starting_rule.flags & HIGHLANDER_RULESET) - highlander_executed = TRUE - else if(starting_rule.flags & ONLY_RULESET) + round_start_budget_left -= cost + + rulesets_picked[ruleset] += 1 + + if (ruleset.flags & HIGH_IMPACT_RULESET) + for (var/_other_ruleset in drafted_rules) + var/datum/dynamic_ruleset/other_ruleset = _other_ruleset + if (other_ruleset.flags & HIGH_IMPACT_RULESET) + drafted_rules[other_ruleset] = null + + if (ruleset.flags & LONE_RULESET) + drafted_rules[ruleset] = null + + for (var/ruleset in rulesets_picked) + spend_roundstart_budget(picking_roundstart_rule(ruleset, rulesets_picked[ruleset] - 1)) + + update_log() + +/// Initializes the round start ruleset provided to it. Returns how much threat to spend. +/datum/game_mode/dynamic/proc/picking_roundstart_rule(datum/dynamic_ruleset/roundstart/ruleset, scaled_times = 0, forced = FALSE) + log_game("DYNAMIC: Picked a ruleset: [ruleset.name], scaled [scaled_times] times") + + ruleset.trim_candidates() + var/added_threat = ruleset.scale_up(roundstart_pop_ready, scaled_times) + + if(ruleset.pre_execute(roundstart_pop_ready)) + threat_log += "[worldtime2text()]: Roundstart [ruleset.name] spent [ruleset.cost + added_threat]. [ruleset.scaling_cost ? "Scaled up [ruleset.scaled_times]/[scaled_times] times." : ""]" + if(ruleset.flags & ONLY_RULESET) only_ruleset_executed = TRUE - executed_rules += starting_rule - for(var/datum/dynamic_ruleset/roundstart/rule in drafted_rules) - if(check_blocking(rule.blocking_rules, executed_rules)) - drafted_rules -= rule - if(highlander_executed && rule.flags & HIGHLANDER_RULESET) - drafted_rules -= rule - if(!rule.ready()) - drafted_rules -= rule // And removing rules that are no longer eligible - return TRUE + if(ruleset.flags & HIGH_IMPACT_RULESET) + high_impact_ruleset_executed = TRUE + executed_rules += ruleset + return ruleset.cost + added_threat else - stack_trace("The starting rule \"[starting_rule.name]\" failed to pre_execute.") - return FALSE + stack_trace("The starting rule \"[ruleset.name]\" failed to pre_execute.") + return 0 /// Mainly here to facilitate delayed rulesets. All roundstart rulesets are executed with a timered callback to this proc. /datum/game_mode/dynamic/proc/execute_roundstart_rule(sent_rule) var/datum/dynamic_ruleset/rule = sent_rule if(rule.execute()) - current_rules += rule - SSblackbox.record_feedback("associative","dynamic_rulesets",1,rule.get_blackbox_info()) + if(rule.persistent) + current_rules += rule + new_snapshot(rule) return TRUE - rule.clean_up() // Refund threat, delete teams and so on. + rule.clean_up() // Refund threat, delete teams and so on. executed_rules -= rule stack_trace("The starting rule \"[rule.name]\" failed to execute.") return FALSE -/// Picks a random midround OR latejoin rule from the list given as an argument and executes it. -/// Also this could be named better. -/datum/game_mode/dynamic/proc/picking_midround_latejoin_rule(list/drafted_rules = list(), forced = FALSE) - var/datum/dynamic_ruleset/rule = pickweight(drafted_rules) - if(!rule) - return FALSE - - if(!forced) - if(only_ruleset_executed) - return FALSE - // Check if a blocking ruleset has been executed. - else if(check_blocking(rule.blocking_rules, executed_rules)) - drafted_rules -= rule - if(drafted_rules.len <= 0) - return FALSE - rule = pickweight(drafted_rules) - // Check if the ruleset is highlander and if a highlander ruleset has been executed - else if(rule.flags & HIGHLANDER_RULESET) - if(threat_level > GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) - if(highlander_executed) - drafted_rules -= rule - if(drafted_rules.len <= 0) - return FALSE - rule = pickweight(drafted_rules) - - if(!rule.repeatable) - if(rule.ruletype == "Latejoin") - latejoin_rules = remove_from_list(latejoin_rules, rule.type) - else if(rule.ruletype == "Midround") - midround_rules = remove_from_list(midround_rules, rule.type) - message_admins("DYNAMIC: Picked [rule]; executing soon...") - addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/execute_midround_latejoin_rule, rule), rule.delay) - return TRUE - /// An experimental proc to allow admins to call rules on the fly or have rules call other rules. /datum/game_mode/dynamic/proc/picking_specific_rule(ruletype, forced = FALSE) var/datum/dynamic_ruleset/midround/new_rule if(ispath(ruletype)) new_rule = new ruletype() // You should only use it to call midround rules though. + configure_ruleset(new_rule) // This makes sure the rule is set up properly. else if(istype(ruletype, /datum/dynamic_ruleset)) new_rule = ruletype else @@ -630,119 +581,126 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) // Check if a blocking ruleset has been executed. else if(check_blocking(new_rule.blocking_rules, executed_rules)) return FALSE - // Check if the ruleset is highlander and if a highlander ruleset has been executed - else if(new_rule.flags & HIGHLANDER_RULESET) - if(threat_level > GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) - if(highlander_executed) - return FALSE + // Check if the ruleset is high impact and if a high impact ruleset has been executed + else if(new_rule.flags & HIGH_IMPACT_RULESET) + if(GLOB.dynamic_extended) + return FALSE + if(high_impact_ruleset_executed && threat_level < GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) + return FALSE - update_playercounts() - if ((forced || (new_rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && new_rule.cost <= threat))) + var/population = current_players[CURRENT_LIVING_PLAYERS].len + if((new_rule.acceptable(population, threat_level) && new_rule.cost <= mid_round_budget) || forced) new_rule.trim_candidates() if (new_rule.ready(forced)) - log_threat("[new_rule.ruletype] - [new_rule.name] [new_rule.cost] threat", verbose = TRUE) + spend_midround_budget(new_rule.cost) + threat_log += "[worldtime2text()]: Forced rule [new_rule.name] spent [new_rule.cost]" + new_rule.pre_execute(population) if (new_rule.execute()) // This should never fail since ready() returned 1 - if(new_rule.flags & HIGHLANDER_RULESET) - highlander_executed = TRUE + if(new_rule.flags & HIGH_IMPACT_RULESET) + high_impact_ruleset_executed = TRUE else if(new_rule.flags & ONLY_RULESET) only_ruleset_executed = TRUE log_game("DYNAMIC: Making a call to a specific ruleset...[new_rule.name]!") - SSblackbox.record_feedback("associative","dynamic_rulesets",1,new_rule.get_blackbox_info()) executed_rules += new_rule - current_rules += new_rule + if (new_rule.persistent) + current_rules += new_rule return TRUE else if (forced) - log_game("DYNAMIC: The ruleset [new_rule.name] couldn't be executed due to lack of eligible players.") - return FALSE - -/// Mainly here to facilitate delayed rulesets. All midround/latejoin rulesets are executed with a timered callback to this proc. -/datum/game_mode/dynamic/proc/execute_midround_latejoin_rule(sent_rule) - var/datum/dynamic_ruleset/rule = sent_rule - if (rule.execute()) - message_admins("DYNAMIC: Injected a [rule.ruletype == "latejoin" ? "latejoin" : "midround"] ruleset [rule.name].") - log_game("DYNAMIC: Injected a [rule.ruletype == "latejoin" ? "latejoin" : "midround"] ruleset [rule.name].") - log_threat("[rule.ruletype] [rule.name] added [rule.cost]", verbose = TRUE) - if(rule.flags & HIGHLANDER_RULESET) - highlander_executed = TRUE - else if(rule.flags & ONLY_RULESET) - only_ruleset_executed = TRUE - if(rule.ruletype == "Latejoin") - var/mob/M = pick(rule.candidates) - message_admins("[key_name(M)] joined the station, and was selected by the [rule.name] ruleset.") - log_game("DYNAMIC: [key_name(M)] joined the station, and was selected by the [rule.name] ruleset.") - executed_rules += rule - SSblackbox.record_feedback("associative","dynamic_rulesets",1,rule.get_blackbox_info()) - rule.candidates.Cut() - if (rule.persistent) - current_rules += rule - return TRUE - stack_trace("The [rule.ruletype] rule \"[rule.name]\" failed to execute.") + log_game("DYNAMIC: The ruleset [new_rule.name] couldn't be executed due to lack of elligible players.") return FALSE /datum/game_mode/dynamic/process() - if (pop_last_updated < world.time - (120 SECONDS)) - pop_last_updated = world.time - update_playercounts() - for (var/datum/dynamic_ruleset/rule in current_rules) if(rule.rule_process() == RULESET_STOP_PROCESSING) // If rule_process() returns 1 (RULESET_STOP_PROCESSING), stop processing. current_rules -= rule SSblackbox.record_feedback("tally","dynamic",1,"Rulesets finished") - SSblackbox.record_feedback("associative","dynamic_rulesets_finished",1,rule.get_blackbox_info()) - - storyteller.do_process() + midround_rule_draft() +/datum/game_mode/dynamic/proc/midround_rule_draft() + set waitfor = FALSE if (midround_injection_cooldown < world.time) if (GLOB.dynamic_forced_extended) return // Somehow it managed to trigger midround multiple times so this was moved here. // There is no way this should be able to trigger an injection twice now. - midround_injection_cooldown = storyteller.get_midround_cooldown() + world.time + var/midround_injection_cooldown_middle = 0.5*(midround_delay_max + midround_delay_min) + midround_injection_cooldown = (round(clamp(EXP_DISTRIBUTION(midround_injection_cooldown_middle), midround_delay_min, midround_delay_max)) + world.time) // Time to inject some threat into the round if(EMERGENCY_ESCAPED_OR_ENDGAMED) // Unless the shuttle is gone return - if(SSshuttle.endvote_passed) // no rules after shuttle call is voted - return + message_admins("DYNAMIC: Checking for midround injection.") log_game("DYNAMIC: Checking for midround injection.") - update_playercounts() - if (storyteller.should_inject_antag()) - SSblackbox.record_feedback("tally","dynamic",1,"Attempted midround injections") - do_midround_injection() + last_midround_injection_attempt = world.time -/datum/game_mode/dynamic/proc/do_midround_injection() - set waitfor = FALSE - var/list/drafted_rules = storyteller.midround_draft() - if (drafted_rules.len > 0) - SSblackbox.record_feedback("tally","dynamic",1,"Successful midround injections") - picking_midround_latejoin_rule(drafted_rules) - - -/// Updates current_players. -/datum/game_mode/dynamic/proc/update_playercounts() - current_players[CURRENT_LIVING_PLAYERS] = list() - current_players[CURRENT_LIVING_ANTAGS] = list() - current_players[CURRENT_DEAD_PLAYERS] = list() - current_players[CURRENT_OBSERVERS] = list() - for (var/mob/M in GLOB.player_list) - if (istype(M, /mob/dead/new_player)) - continue - if (M.stat != DEAD) - current_players[CURRENT_LIVING_PLAYERS].Add(M) - if (M.mind && (M.mind.special_role || M.mind.antag_datums?.len > 0)) - current_players[CURRENT_LIVING_ANTAGS].Add(M) - else - if (isobserver(M)) - var/mob/dead/observer/O = M - if (O.started_as_observer) // Observers - current_players[CURRENT_OBSERVERS].Add(M) + if (prob(get_midround_injection_chance())) + var/list/drafted_rules = list() + for (var/datum/dynamic_ruleset/midround/rule in midround_rules) + if (!rule.weight) continue - if(!M.voluntary_ghosted) - current_players[CURRENT_DEAD_PLAYERS].Add(M) // Players who actually died (and admins who ghosted, would be nice to avoid counting them somehow) - threat = (SSactivity.current_threat * 0.6 + SSactivity.get_max_threat() * 0.2 + SSactivity.get_average_threat() * 0.2) + added_threat + if(rule.flags & HIGH_IMPACT_RULESET) + if (high_impact_ruleset_executed && threat_level < GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) + continue + if(GLOB.dynamic_extended) + continue + if (rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && mid_round_budget >= rule.cost) + rule.trim_candidates() + if (rule.ready()) + drafted_rules[rule] = rule.get_weight() + if (drafted_rules.len > 0) + pick_midround_rule(drafted_rules) + else if (random_event_hijacked == HIJACKED_TOO_SOON) + message_admins("DYNAMIC: Midround injection failed when random event was hijacked. Spawning another random event in its place.") + log_game("DYNAMIC: Midround injection failed when random event was hijacked. Spawning another random event in its place.") + + // A random event antag would have rolled had this injection check passed. + // As a refund, spawn a non-ghost-role random event. + SSevents.spawnEvent() + SSevents.reschedule() + + random_event_hijacked = HIJACKED_NOTHING + +/// Gets the chance for latejoin injection, the dry_run argument is only used for forced injection. +/datum/game_mode/dynamic/proc/get_injection_chance(dry_run = FALSE) + if(forced_injection) + forced_injection = dry_run + return 100 + var/chance = 0 + var/effective_living_players = current_players[CURRENT_LIVING_PLAYERS].len + if(GLOB.dynamic_extended) + effective_living_players = min(effective_living_players, length(SSjob.get_living_sec())*2 + length(SSjob.get_living_heads())) + var/max_pop_per_antag = max(5,15 - round(threat_level/10) - round(effective_living_players/5)) + if (!current_players[CURRENT_LIVING_ANTAGS].len) + if(GLOB.dynamic_extended) + chance += min(50,effective_living_players*5) + else + chance += 50 // No antags at all? let's boost those odds! + else + var/current_pop_per_antag = effective_living_players / current_players[CURRENT_LIVING_ANTAGS].len + if (current_pop_per_antag > max_pop_per_antag) + chance += min(50, 25+10*(current_pop_per_antag-max_pop_per_antag)) + else + chance += 25-10*(max_pop_per_antag-current_pop_per_antag) + if (current_players[CURRENT_DEAD_PLAYERS].len > current_players[CURRENT_LIVING_PLAYERS].len) + chance -= 30 // More than half the crew died? ew, let's calm down on antags + if (mid_round_budget > higher_injection_chance_minimum_threat) + chance += higher_injection_chance + if (mid_round_budget < lower_injection_chance_minimum_threat) + chance -= lower_injection_chance + return round(max(0,chance)) + +/// Gets the chance for midround injection, the dry_run argument is only used for forced injection. +/// Usually defers to the latejoin injection chance. +/datum/game_mode/dynamic/proc/get_midround_injection_chance(dry_run) + var/chance = get_injection_chance(dry_run) + + if (random_event_hijacked != HIJACKED_NOTHING) + chance += hijacked_random_event_injection_chance + + return chance /// Removes type from the list /datum/game_mode/dynamic/proc/remove_from_list(list/type_list, type) @@ -755,12 +713,12 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) /datum/game_mode/dynamic/proc/check_blocking(list/blocking_list, list/rule_list) if(blocking_list.len > 0) for(var/blocking in blocking_list) - for(var/datum/executed in rule_list) + for(var/_executed in rule_list) + var/datum/executed = _executed if(blocking == executed.type) return TRUE return FALSE -/// Checks if client age is age or older. /datum/game_mode/dynamic/proc/check_age(client/C, age) enemy_minimum_age = age if(get_remaining_days(C) == 0) @@ -774,44 +732,71 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) return if(EMERGENCY_ESCAPED_OR_ENDGAMED) // No more rules after the shuttle has left return - if(SSshuttle.endvote_passed) // no rules after shuttle is auto-called - return - update_playercounts() if (forced_latejoin_rule) forced_latejoin_rule.candidates = list(newPlayer) forced_latejoin_rule.trim_candidates() log_game("DYNAMIC: Forcing ruleset [forced_latejoin_rule]") if (forced_latejoin_rule.ready(TRUE)) - picking_midround_latejoin_rule(list(forced_latejoin_rule), forced = TRUE) + if (!forced_latejoin_rule.repeatable) + latejoin_rules = remove_from_list(latejoin_rules, forced_latejoin_rule.type) + addtimer(CALLBACK(src, /datum/game_mode/dynamic/.proc/execute_midround_latejoin_rule, forced_latejoin_rule), forced_latejoin_rule.delay) forced_latejoin_rule = null - else if (storyteller.should_inject_antag()) - SSblackbox.record_feedback("tally","dynamic",1,"Attempted latejoin injections") - var/list/drafted_rules = storyteller.latejoin_draft(newPlayer) - if (drafted_rules.len > 0 && picking_midround_latejoin_rule(drafted_rules)) - SSblackbox.record_feedback("tally","dynamic",1,"Successful latejoin injections") + else if (latejoin_injection_cooldown < world.time && prob(get_injection_chance())) + var/list/drafted_rules = list() + for (var/datum/dynamic_ruleset/latejoin/rule in latejoin_rules) + if (!rule.weight) + continue + if (rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && mid_round_budget >= rule.cost) + // No stacking : only one round-ender, unless threat level > stacking_limit. + if (threat_level < GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) + if(rule.flags & HIGH_IMPACT_RULESET && high_impact_ruleset_executed) + continue -/// Increase the threat level. + rule.candidates = list(newPlayer) + rule.trim_candidates() + if (rule.ready()) + drafted_rules[rule] = rule.get_weight() + + if (drafted_rules.len > 0 && pick_latejoin_rule(drafted_rules)) + var/latejoin_injection_cooldown_middle = 0.5*(latejoin_delay_max + latejoin_delay_min) + latejoin_injection_cooldown = round(clamp(EXP_DISTRIBUTION(latejoin_injection_cooldown_middle), latejoin_delay_min, latejoin_delay_max)) + world.time + +/// Apply configurations to rule. +/datum/game_mode/dynamic/proc/configure_ruleset(datum/dynamic_ruleset/ruleset) + var/rule_conf = LAZYACCESSASSOC(configuration, ruleset.ruletype, ruleset.name) + for(var/variable in rule_conf) + if(!(variable in ruleset.vars)) + stack_trace("Invalid dynamic configuration variable [variable] in [ruleset.ruletype] [ruleset.name].") + continue + ruleset.vars[variable] = rule_conf[variable] + if(CONFIG_GET(flag/protect_roles_from_antagonist)) + ruleset.restricted_roles |= ruleset.protected_roles + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) + ruleset.restricted_roles |= "Assistant" + +/// Refund threat, but no more than threat_level. +/datum/game_mode/dynamic/proc/refund_threat(regain) + mid_round_budget = min(threat_level, mid_round_budget + regain) + +/// Generate threat and increase the threat_level if it goes beyond, capped at 100 /datum/game_mode/dynamic/proc/create_threat(gain) - threat_level += gain - SSblackbox.record_feedback("tally","dynamic_threat",gain,"Created threat level") - log_threat("[gain] created. Threat level is now [threat_level].", verbose = TRUE) + mid_round_budget = min(100, mid_round_budget + gain) + if(mid_round_budget > threat_level) + threat_level = mid_round_budget -/// Decrease the threat level. -/datum/game_mode/dynamic/proc/remove_threat(loss) - threat_level -= loss - SSblackbox.record_feedback("tally","dynamic_threat",loss,"Removed threat level") - log_threat("[loss] removed. Threat level is now [threat_level].", verbose = TRUE) +/// Expend round start threat, can't fall under 0. +/datum/game_mode/dynamic/proc/spend_roundstart_budget(cost) + round_start_budget = max(round_start_budget - cost,0) -/// Fill up more of the threat level. -/datum/game_mode/dynamic/proc/spend_threat(cost) - added_threat += cost - SSblackbox.record_feedback("tally","dynamic_threat",cost,"Threat added") - log_threat("[cost] added. Threat is now [threat].", verbose = TRUE) +/// Expend midround threat, can't fall under 0. +/datum/game_mode/dynamic/proc/spend_midround_budget(cost) + mid_round_budget = max(mid_round_budget - cost,0) -/// Turns the value generated by lorentz distribution to threat value between 0 and 100. -/datum/game_mode/dynamic/proc/lorentz_to_threat(x) +/// Turns the value generated by lorentz distribution to number between 0 and 100. +/// Used for threat level and splitting the budgets. +/datum/game_mode/dynamic/proc/lorentz_to_amount(x) switch (x) if (-INFINITY to -20) return rand(0, 10) @@ -834,10 +819,11 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null) if (20 to INFINITY) return rand(90, 100) -/datum/game_mode/dynamic/ghost_info() - . = list() - . += "Current threat: [threat]" - . += "Target threat: [threat_level]" - . += "Storyteller: [storyteller.name]
    " - . += "Parameters: centre = [GLOB.dynamic_curve_centre] ; width = [GLOB.dynamic_curve_width].
    " - . += "On average, [peaceful_percentage]% of the rounds are more peaceful.
    " +/// Log to messages and to the game +/datum/game_mode/dynamic/proc/dynamic_log(text) + message_admins("DYNAMIC: [text]") + log_game("DYNAMIC: [text]") + +#undef FAKE_REPORT_CHANCE +#undef REPORT_NEG_DIVERGENCE +#undef REPORT_POS_DIVERGENCE diff --git a/code/game/gamemodes/dynamic/dynamic_hijacking.dm b/code/game/gamemodes/dynamic/dynamic_hijacking.dm new file mode 100644 index 0000000000..04892ad153 --- /dev/null +++ b/code/game/gamemodes/dynamic/dynamic_hijacking.dm @@ -0,0 +1,27 @@ +/datum/game_mode/dynamic/proc/setup_hijacking() + RegisterSignal(SSdcs, COMSIG_GLOB_PRE_RANDOM_EVENT, .proc/on_pre_random_event) + +/datum/game_mode/dynamic/proc/on_pre_random_event(datum/source, datum/round_event_control/round_event_control) + SIGNAL_HANDLER + if (!round_event_control.dynamic_should_hijack) + return + + if (random_event_hijacked != HIJACKED_NOTHING) + dynamic_log("Random event [round_event_control.name] tried to roll, but Dynamic vetoed it (random event has already ran).") + SSevents.spawnEvent() + SSevents.reschedule() + return CANCEL_PRE_RANDOM_EVENT + + var/time_range = rand(random_event_hijack_minimum, random_event_hijack_maximum) + + if (world.time - last_midround_injection_attempt < time_range) + random_event_hijacked = HIJACKED_TOO_RECENT + dynamic_log("Random event [round_event_control.name] tried to roll, but the last midround injection \ + was too recent. Injection chance has been raised to [get_midround_injection_chance(dry_run = TRUE)]%.") + return CANCEL_PRE_RANDOM_EVENT + + if (midround_injection_cooldown - world.time < time_range) + random_event_hijacked = HIJACKED_TOO_SOON + dynamic_log("Random event [round_event_control.name] tried to roll, but the next midround injection \ + is too soon. Injection chance has been raised to [get_midround_injection_chance(dry_run = TRUE)]%.") + return CANCEL_PRE_RANDOM_EVENT diff --git a/code/game/gamemodes/dynamic/dynamic_logging.dm b/code/game/gamemodes/dynamic/dynamic_logging.dm new file mode 100644 index 0000000000..095b28c4e5 --- /dev/null +++ b/code/game/gamemodes/dynamic/dynamic_logging.dm @@ -0,0 +1,101 @@ +/// A "snapshot" of dynamic at an important point in time. +/// Exported to JSON in the dynamic.json log file. +/datum/dynamic_snapshot + /// The remaining midround threat + var/remaining_threat + + /// The world.time when the snapshot was taken + var/time + + /// The total number of players in the server + var/total_players + + /// The number of alive players + var/alive_players + + /// The number of dead players + var/dead_players + + /// The number of observers + var/observers + + /// The number of alive antags + var/alive_antags + + /// The rulesets chosen this snapshot + var/datum/dynamic_snapshot_ruleset/ruleset_chosen + + /// The cached serialization of this snapshot + var/serialization + +/// A ruleset chosen during a snapshot +/datum/dynamic_snapshot_ruleset + /// The name of the ruleset chosen + var/name + + /// If it is a round start ruleset, how much it was scaled by + var/scaled + + /// The number of assigned antags + var/assigned + +/datum/dynamic_snapshot_ruleset/New(datum/dynamic_ruleset/ruleset) + name = ruleset.name + assigned = ruleset.assigned.len + + if (istype(ruleset, /datum/dynamic_ruleset/roundstart)) + scaled = ruleset.scaled_times + +/// Convert the snapshot to an associative list +/datum/dynamic_snapshot/proc/to_list() + if (!isnull(serialization)) + return serialization + + serialization = list( + "remaining_threat" = remaining_threat, + "time" = time, + "total_players" = total_players, + "alive_players" = alive_players, + "dead_players" = dead_players, + "observers" = observers, + "alive_antags" = alive_antags, + "ruleset_chosen" = list( + "name" = ruleset_chosen.name, + "scaled" = ruleset_chosen.scaled, + "assigned" = ruleset_chosen.assigned, + ), + ) + + return serialization + +/// Updates the log for the current snapshots. +/datum/game_mode/dynamic/proc/update_log() + var/list/serialized = list() + serialized["threat_level"] = threat_level + serialized["round_start_budget"] = initial_round_start_budget + serialized["mid_round_budget"] = threat_level - initial_round_start_budget + serialized["shown_threat"] = shown_threat + + var/list/serialized_snapshots = list() + for (var/datum/dynamic_snapshot/snapshot as anything in snapshots) + serialized_snapshots += list(snapshot.to_list()) + serialized["snapshots"] = serialized_snapshots + + rustg_file_write(json_encode(serialized), "[GLOB.log_directory]/dynamic.json") + +/// Creates a new snapshot with the given rulesets chosen, and writes to the JSON output. +/datum/game_mode/dynamic/proc/new_snapshot(datum/dynamic_ruleset/ruleset_chosen) + var/datum/dynamic_snapshot/new_snapshot = new + + new_snapshot.remaining_threat = mid_round_budget + new_snapshot.time = world.time + new_snapshot.alive_players = current_players[CURRENT_LIVING_PLAYERS].len + new_snapshot.dead_players = current_players[CURRENT_DEAD_PLAYERS].len + new_snapshot.observers = current_players[CURRENT_OBSERVERS].len + new_snapshot.total_players = new_snapshot.alive_players + new_snapshot.dead_players + new_snapshot.observers + new_snapshot.alive_antags = current_players[CURRENT_LIVING_ANTAGS].len + new_snapshot.ruleset_chosen = new /datum/dynamic_snapshot_ruleset(ruleset_chosen) + + LAZYADD(snapshots, new_snapshot) + + update_log() diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index f1e48eb31c..b742f6f36c 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -1,16 +1,13 @@ -#define EXTRA_RULESET_PENALTY 20 // Changes how likely a gamemode is to scale based on how many other roundstart rulesets are waiting to be rolled. -#define POP_SCALING_PENALTY 50 // Discourages scaling up rulesets if ratio of antags to crew is high. - #define REVOLUTION_VICTORY 1 #define STATION_VICTORY 2 /datum/dynamic_ruleset /// For admin logging and round end screen. + // If you want to change this variable name, the force latejoin/midround rulesets + // to not use sortNames. var/name = "" /// For admin logging and round end screen, do not change this unless making a new rule type. var/ruletype = "" - /// For config purposes, similar to config_tag for secret game modes. - var/config_tag = null /// If set to TRUE, the rule won't be discarded after being executed, and dynamic will call rule_process() every time it ticks. var/persistent = FALSE /// If set to TRUE, dynamic mode will be able to draft this ruleset again later on. (doesn't apply for roundstart rules) @@ -31,7 +28,7 @@ var/list/protected_roles = list() /// If set, rule will deny candidates from those roles always. var/list/restricted_roles = list() - /// If set, rule will only accept candidates from those roles, IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS. + /// If set, rule will only accept candidates from those roles. If on a roundstart ruleset, requires the player to have the correct antag pref enabled and any of the possible roles enabled. var/list/exclusive_roles = list() /// If set, there needs to be a certain amount of players doing those roles (among the players who won't be drafted) for the rule to be drafted IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS. var/list/enemy_roles = list() @@ -39,7 +36,7 @@ var/required_enemies = list(1,1,0,0,0,0,0,0,0,0) /// The rule needs this many candidates (post-trimming) to be executed (example: Cult needs 4 players at round start) var/required_candidates = 0 - /// 1 -> 9, probability for this rule to be picked against other rules + /// 0 -> 9, probability for this rule to be picked against other rules. If zero this will effectively disable the rule. var/weight = 5 /// Threat cost for this rule, this is decreased from the mode's threat when the rule is executed. var/cost = 0 @@ -49,21 +46,13 @@ var/scaled_times = 0 /// Used for the roundend report var/total_cost = 0 - /// A flag that determines how the ruleset is handled - /// ONLY_RULESET are rulesets that prevent ALL other rulesets from rolling. - /// HIGHLANDER_RULESET are rulesets can end the round. - /// TRAITOR_RULESET are the "default" ruleset--they should always be addable to a round, if the round type allows antags and dynamic thinks there should be another. - /// MINOR_RULESET is for rulesets whose antags can have multiple instances without causing too much issue. As roundstarts, they have their weights reduced based on the storyteller's minor-antag-round chance. - /// FAKE_ANTAG_RULESET is for rulesets whose antags aren't actually antagonistic--essentially just flavor meant to spice the round up. - /// ALWAYS_MAX_WEIGHT_RULESET means that the ruleset doesn't have its weight reduced based on recency. - var/flags = 0 + /// A flag that determines how the ruleset is handled. Check __DEFINES/dynamic.dm for an explanation of the accepted values. + var/flags = NONE /// Pop range per requirement. If zero defaults to mode's pop_per_requirement. var/pop_per_requirement = 0 /// Requirements are the threat level requirements per pop range. /// With the default values, The rule will never get drafted below 10 threat level (aka: "peaceful extended"), and it requires a higher threat level at lower pops. var/list/requirements = list(40,30,20,10,10,10,10,10,10,10) - /// An alternative, static requirement used instead when pop is over mode's high_pop_limit. - var/high_population_requirement = 10 /// Reference to the mode, use this instead of SSticker.mode. var/datum/game_mode/dynamic/mode = null /// If a role is to be considered another for the purpose of banning. @@ -77,53 +66,31 @@ var/maximum_players = 0 /// Calculated during acceptable(), used in scaling and team sizes. var/indice_pop = 0 - /// Population scaling. Used by team antags and scaling for solo antags. - var/list/antag_cap = list() /// Base probability used in scaling. The higher it is, the more likely to scale. Kept as a var to allow for config editing._SendSignal(sigtype, list/arguments) var/base_prob = 60 /// Delay for when execute will get called from the time of post_setup (roundstart) or process (midround/latejoin). /// Make sure your ruleset works with execute being called during the game when using this, and that the clean_up proc reverts it properly in case of faliure. var/delay = 0 - /// List of tags for use in storytellers. - var/list/property_weights = list() - /// Weight reduction by recent-rounds. Saved on new. - var/weight_mult = 1 + + /// Judges the amount of antagonists to apply, for both solo and teams. + /// Note that some antagonists (such as traitors, lings, heretics, etc) will add more based on how many times they've been scaled. + /// Written as a linear equation--ceil(x/denominator) + offset, or as a fixed constant. + /// If written as a linear equation, will be in the form of `list("denominator" = denominator, "offset" = offset). + var/antag_cap = 0 /datum/dynamic_ruleset/New() + // Rulesets can be instantiated more than once, such as when an admin clicks + // "Execute Midround Ruleset". Thus, it would be wrong to perform any + // side effects here. Dynamic rulesets should be stateless anyway. + SHOULD_NOT_OVERRIDE(TRUE) + + mode = SSticker.mode + ..() - if(CONFIG_GET(flag/protect_roles_from_antagonist)) - restricted_roles += protected_roles - if(CONFIG_GET(flag/protect_assistant_from_antagonist)) - restricted_roles += "Assistant" - var/weights = CONFIG_GET(keyed_list/dynamic_weight) - var/costs = CONFIG_GET(keyed_list/dynamic_cost) - var/requirementses = CONFIG_GET(keyed_list/dynamic_requirements) // can't damn well use requirements - var/high_population_requirements = CONFIG_GET(keyed_list/dynamic_high_population_requirement) - var/list/repeated_mode_adjust = CONFIG_GET(number_list/repeated_mode_adjust) - if(config_tag in weights) - if(!(flags & ALWAYS_MAX_WEIGHT_RULESET) && SSpersistence.saved_dynamic_rules.len == 3 && repeated_mode_adjust.len == 3) - var/saved_dynamic_rules = SSpersistence.saved_dynamic_rules - for(var/i in 1 to 3) - if(config_tag in saved_dynamic_rules[i]) - weight_mult -= (repeated_mode_adjust[i]/100) - weight_mult = max(0,weight_mult) - if(config_tag in costs) - cost = costs[config_tag] - if(config_tag in requirementses) - requirements = requirementses[config_tag] - if(config_tag in high_population_requirements) - high_population_requirement = high_population_requirements[config_tag] - if (istype(SSticker.mode, /datum/game_mode/dynamic)) - mode = SSticker.mode - else if (GLOB.master_mode != "dynamic") // This is here to make roundstart forced ruleset function. - qdel(src) /datum/dynamic_ruleset/roundstart // One or more of those drafted at roundstart ruletype = "Roundstart" -/datum/dynamic_ruleset/minor // drafted at roundstart in minor rounds, one antag at a time, for a "mixed" round - ruletype = "Minor" - // Can be drafted when a player joins the server /datum/dynamic_ruleset/latejoin ruletype = "Latejoin" @@ -131,55 +98,47 @@ /// By default, a rule is acceptable if it satisfies the threat level/population requirements. /// If your rule has extra checks, such as counting security officers, do that in ready() instead /datum/dynamic_ruleset/proc/acceptable(population = 0, threat_level = 0) + pop_per_requirement = pop_per_requirement > 0 ? pop_per_requirement : mode.pop_per_requirement + indice_pop = min(requirements.len,round(population/pop_per_requirement)+1) + if(minimum_players > population) SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to low pop") return FALSE if(maximum_players > 0 && population > maximum_players) SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to high pop") return FALSE - if (population >= GLOB.dynamic_high_pop_limit) - indice_pop = 10 - if(threat_level < high_population_requirement) - SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough threat level") - log_game("DYNAMIC: [name] did not reach threat level threshold: [threat_level]/[high_population_requirement]") - return FALSE - else - return TRUE - else - pop_per_requirement = pop_per_requirement > 0 ? pop_per_requirement : mode.pop_per_requirement - if(antag_cap.len && requirements.len != antag_cap.len) - message_admins("DYNAMIC: requirements and antag_cap lists have different lengths in ruleset [name]. Likely config issue, report this.") - log_game("DYNAMIC: requirements and antag_cap lists have different lengths in ruleset [name]. Likely config issue, report this.") - indice_pop = min(requirements.len,round(population/pop_per_requirement)+1) - if(threat_level < requirements[indice_pop]) - SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough threat level") - log_game("DYNAMIC: [name] did not reach threat level threshold: [threat_level]/[requirements[indice_pop]]") - return FALSE - else - return TRUE + return (threat_level >= requirements[indice_pop]) -/// Called when a suitable rule is picked during roundstart(). Will some times attempt to scale a rule up when there is threat remaining. Returns the amount of scaled steps. -/datum/dynamic_ruleset/proc/scale_up(extra_rulesets = 0, remaining_threat_level = 0) - remaining_threat_level -= cost - if(scaling_cost && scaling_cost <= remaining_threat_level) // Only attempts to scale the modes with a scaling cost explicitly set. - var/new_prob - var/pop_to_antags = (mode.antags_rolled + (antag_cap[indice_pop] * (scaled_times + 1))) / mode.roundstart_pop_ready - log_game("DYNAMIC: [name] roundstart ruleset attempting to scale up with [extra_rulesets] rulesets waiting and [remaining_threat_level] threat remaining.") - for(var/i in 1 to 3) //Can scale a max of 3 times - if(remaining_threat_level >= scaling_cost && pop_to_antags < 0.25) - new_prob = base_prob + (remaining_threat_level) - (scaled_times * scaling_cost) - (extra_rulesets * EXTRA_RULESET_PENALTY) - (pop_to_antags * POP_SCALING_PENALTY) - if (!prob(new_prob)) - break - remaining_threat_level -= scaling_cost - scaled_times++ - pop_to_antags = (mode.antags_rolled + (antag_cap[indice_pop] * (scaled_times + 1))) / mode.roundstart_pop_ready - log_game("DYNAMIC: [name] roundstart ruleset failed scaling up at [new_prob ? new_prob : 0]% chance after [scaled_times]/3 successful scaleups. [remaining_threat_level] threat remaining, antag to crew ratio: [pop_to_antags*100]%.") - mode.antags_rolled += (1 + scaled_times) * antag_cap[indice_pop] - return scaled_times * scaling_cost +/// When picking rulesets, if dynamic picks the same one multiple times, it will "scale up". +/// However, doing this blindly would result in lowpop rounds (think under 10 people) where over 80% of the crew is antags! +/// This function is here to ensure the antag ratio is kept under control while scaling up. +/// Returns how much threat to actually spend in the end. +/datum/dynamic_ruleset/proc/scale_up(population, max_scale) + if (!scaling_cost) + return 0 + + var/antag_fraction = 0 + for(var/_ruleset in (mode.executed_rules + list(src))) // we care about the antags we *will* assign, too + var/datum/dynamic_ruleset/ruleset = _ruleset + antag_fraction += ((1 + ruleset.scaled_times) * ruleset.get_antag_cap(population)) / mode.roundstart_pop_ready + + for(var/i in 1 to max_scale) + if(antag_fraction < 0.25) + scaled_times += 1 + antag_fraction += get_antag_cap(population) / mode.roundstart_pop_ready // we added new antags, gotta update the % + + return scaled_times * scaling_cost + +/// Returns what the antag cap with the given population is. +/datum/dynamic_ruleset/proc/get_antag_cap(population) + if (isnum(antag_cap)) + return antag_cap + + return CEILING(population / antag_cap["denominator"], 1) + (antag_cap["offset"] || 0) /// This is called if persistent variable is true everytime SSTicker ticks. /datum/dynamic_ruleset/proc/rule_process() - return TRUE + return /// Called on game mode pre_setup for roundstart rulesets. /// Do everything you need to do before job is assigned here. @@ -206,7 +165,8 @@ /// Runs from gamemode process() if ruleset fails to start, like delayed rulesets not getting valid candidates. /// This one only handles refunding the threat, override in ruleset to clean up the rest. /datum/dynamic_ruleset/proc/clean_up() - return + mode.refund_threat(cost + (scaled_times * scaling_cost)) + mode.threat_log += "[worldtime2text()]: [ruletype] [name] refunded [cost + (scaled_times * scaling_cost)]. Failed to execute." /// Gets weight of the ruleset /// Note that this decreases weight if repeatable is TRUE and repeatable_weight_decrease is higher than 0 @@ -225,32 +185,9 @@ return /// Set mode result and news report here. -/// Only called if ruleset is flagged as HIGHLANDER_RULESET +/// Only called if ruleset is flagged as HIGH_IMPACT_RULESET /datum/dynamic_ruleset/proc/round_result() -/// Checks if round is finished, return true to end the round. -/// Only called if ruleset is flagged as HIGHLANDER_RULESET -/datum/dynamic_ruleset/proc/check_finished() - return FALSE - -/// Returns a list to be displayed on statbus. -/datum/dynamic_ruleset/proc/get_blackbox_info() - var/list/ruleset_data = list() - ruleset_data["name"] = name - ruleset_data["rule_type"] = ruletype - ruleset_data["cost"] = total_cost - ruleset_data["weight"] = weight - ruleset_data["scaled_times"] = scaled_times - ruleset_data["antagonist_type"] = antag_datum - ruleset_data["population_tier"] = indice_pop - ruleset_data["assigned"] = list() - for (var/datum/mind/M in assigned) - var/assigned_data = list() - assigned_data["key"] = M.key - assigned_data["name"] = M.name - ruleset_data["assigned"] += list(assigned_data) - return ruleset_data - ////////////////////////////////////////////// // // // ROUNDSTART RULESETS // @@ -259,26 +196,45 @@ /// Checks if candidates are connected and if they are banned or don't want to be the antagonist. /datum/dynamic_ruleset/roundstart/trim_candidates() - for(var/mob/dead/new_player/P in candidates) - if (!P.client || !P.mind) // Are they connected? - candidates.Remove(P) + for(var/mob/dead/new_player/candidate_player in candidates) + var/client/candidate_client = GET_CLIENT(candidate_player) + if (!candidate_client || !candidate_player.mind) // Are they connected? + candidates.Remove(candidate_player) continue - if(!mode.check_age(P.client, minimum_required_age)) - candidates.Remove(P) + + else if(!mode.check_age(candidate_client, minimum_required_age)) + candidates.Remove(candidate_player) continue - if(P.mind.special_role) // We really don't want to give antag to an antag. - candidates.Remove(P) + + if(candidate_player.mind.special_role) // We really don't want to give antag to an antag. + candidates.Remove(candidate_player) continue + if(antag_flag_override) - if(!(antag_flag_override in P.client.prefs.be_special) || jobban_isbanned(P.ckey, antag_flag_override)) - candidates.Remove(P) + if(!(HAS_ANTAG_PREF(candidate_player.client, antag_flag_override))) + candidates.Remove(candidate_player) continue else - if(!(antag_flag in P.client.prefs.be_special) || jobban_isbanned(P.ckey, antag_flag)) - candidates.Remove(P) + if(!(HAS_ANTAG_PREF(candidate_player.client, antag_flag))) + candidates.Remove(candidate_player) continue + // If this ruleset has exclusive_roles set, we want to only consider players who have those + // job prefs enabled and are eligible to play that job. Otherwise, continue as before. + if(length(exclusive_roles)) + var/exclusive_candidate = FALSE + for(var/role in exclusive_roles) + var/datum/job/job = SSjob.GetJob(role) + if((role in candidate_client.prefs.job_preferences) && !jobban_isbanned(candidate_player.ckey, role) && !job.required_playtime_remaining(candidate_client)) + exclusive_candidate = TRUE + break + + // If they didn't have any of the required job prefs enabled or were banned from all enabled prefs, + // they're not eligible for this antag type. + if(!exclusive_candidate) + candidates.Remove(candidate_player) + /// Do your checks if the ruleset is ready to be executed here. /// Should ignore certain checks if forced is TRUE -/datum/dynamic_ruleset/roundstart/ready(forced = FALSE) +/datum/dynamic_ruleset/roundstart/ready(population, forced = FALSE) return ..() diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm index 7842c6e0f7..4dbe7a4387 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm @@ -6,26 +6,20 @@ /datum/dynamic_ruleset/latejoin/trim_candidates() for(var/mob/P in candidates) - if (!P.client || !P.mind || !P.mind.assigned_role) // Are they connected? + if(!P.client || !P.mind || !P.mind.assigned_role) // Are they connected? candidates.Remove(P) - continue - if(!mode.check_age(P.client, minimum_required_age)) + else if(!mode.check_age(P.client, minimum_required_age)) candidates.Remove(P) - continue - if(antag_flag_override) - if(!(antag_flag_override in P.client.prefs.be_special) || jobban_isbanned(P.ckey, list(antag_flag_override))) + else if(P.mind.assigned_role in restricted_roles) // Does their job allow for it? + candidates.Remove(P) + else if((exclusive_roles.len > 0) && !(P.mind.assigned_role in exclusive_roles)) // Is the rule exclusive to their job? + candidates.Remove(P) + else if(antag_flag_override) + if(!(HAS_ANTAG_PREF(P.client, antag_flag_override))) candidates.Remove(P) - continue else - if(!(antag_flag in P.client.prefs.be_special) || jobban_isbanned(P.ckey, list(antag_flag, ROLE_SYNDICATE))) + if(!(HAS_ANTAG_PREF(P.client, antag_flag))) candidates.Remove(P) - continue - if (P.mind.assigned_role in restricted_roles) // Does their job allow for it? - candidates.Remove(P) - continue - if ((exclusive_roles.len > 0) && !(P.mind.assigned_role in exclusive_roles)) // Is the rule exclusive to their job? - candidates.Remove(P) - continue /datum/dynamic_ruleset/latejoin/ready(forced = 0) if (!forced) @@ -34,8 +28,9 @@ for (var/mob/M in mode.current_players[CURRENT_LIVING_PLAYERS]) if (M.stat == DEAD) continue // Dead players cannot count as opponents - if (M.mind && M.mind.assigned_role && (M.mind.assigned_role in enemy_roles) && (!(M in candidates) || (M.mind.assigned_role in restricted_roles))) + if (M.mind && (M.mind.assigned_role in enemy_roles) && (!(M in candidates) || (M.mind.assigned_role in restricted_roles))) job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that rule, or have a job that restricts them from it + var/threat = round(mode.threat_level/10) if (job_check < required_enemies[threat]) SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough enemy roles") @@ -48,7 +43,6 @@ M.mind.special_role = antag_flag M.mind.add_antag_datum(antag_datum) log_admin("[M.name] was made into a [name] by dynamic.") - message_admins("[M.name] was made into a [name] by dynamic.") return TRUE ////////////////////////////////////////////// @@ -59,19 +53,16 @@ /datum/dynamic_ruleset/latejoin/infiltrator name = "Syndicate Infiltrator" - config_tag = "latejoin_traitor" antag_datum = /datum/antagonist/traitor - antag_flag = ROLE_TRAITOR - restricted_roles = list("AI", "Cyborg") - protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") + antag_flag = "traitor late" + antag_flag_override = ROLE_TRAITOR + protected_roles = list("Security Officer", "Warden", "Head of Personnel", "Detective", "Head of Security", "Captain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") + restricted_roles = list("AI","Cyborg") required_candidates = 1 weight = 7 cost = 5 - requirements = list(40,30,20,15,15,15,15,15,15,15) - high_population_requirement = 15 + requirements = list(101,40,25,20,15,10,10,10,10,10) repeatable = TRUE - flags = TRAITOR_RULESET | MINOR_RULESET | ALWAYS_MAX_WEIGHT_RULESET - property_weights = list("story_potential" = 2, "trust" = -1, "extended" = 1) ////////////////////////////////////////////// // // @@ -82,23 +73,23 @@ /datum/dynamic_ruleset/latejoin/provocateur name = "Provocateur" persistent = TRUE - config_tag = "latejoin_revolution" antag_datum = /datum/antagonist/rev/head - antag_flag = ROLE_REV_HEAD + antag_flag = "rev head late" antag_flag_override = ROLE_REV - restricted_roles = list("AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") + restricted_roles = list("AI", "Cyborg", "Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director") enemy_roles = list("AI", "Cyborg", "Security Officer","Detective","Head of Security", "Captain", "Warden") - required_enemies = list(4,4,3,3,3,3,3,2,2,1) + required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 1 weight = 2 - delay = 1 MINUTES // Prevents rule start while head is offstation. + delay = 1 MINUTES // Prevents rule start while head is offstation. cost = 20 - requirements = list(101,101,70,40,40,40,40,40,40,40) - high_population_requirement = 40 - flags = HIGHLANDER_RULESET - property_weights = list("trust" = -2, "chaos" = 2, "extended" = -2, "valid" = 2, "conversion" = 1) + requirements = list(101,101,101,101,50,20,20,20,20,20) + flags = HIGH_IMPACT_RULESET + blocking_rules = list(/datum/dynamic_ruleset/roundstart/revs) var/required_heads_of_staff = 3 var/finished = FALSE + /// How much threat should be injected when the revolution wins? + var/revs_win_threat_injection = 20 var/datum/team/revolution/revolution /datum/dynamic_ruleset/latejoin/provocateur/ready(forced=FALSE) @@ -113,8 +104,8 @@ return (head_check >= required_heads_of_staff) /datum/dynamic_ruleset/latejoin/provocateur/execute() - var/mob/M = pick(candidates) // This should contain a single player, but in case. - if(check_eligible(M.mind)) // Didnt die/run off z-level/get implanted since leaving shuttle. + var/mob/M = pick(candidates) // This should contain a single player, but in case. + if(check_eligible(M.mind)) // Didnt die/run off z-level/get implanted since leaving shuttle. assigned += M.mind M.mind.special_role = antag_flag revolution = new() @@ -125,9 +116,7 @@ new_head = M.mind.add_antag_datum(new_head, revolution) revolution.update_objectives() revolution.update_heads() - SSshuttle.registerHostileEnvironment(src) - log_admin("[M.name] was made into a revolutionary by dynamic.") - message_admins("[M.name] was made into a revolutionary by dynamic.") + SSshuttle.registerHostileEnvironment(revolution) return TRUE else log_game("DYNAMIC: [ruletype] [name] discarded [M.name] from head revolutionary due to ineligibility.") @@ -135,153 +124,38 @@ return FALSE /datum/dynamic_ruleset/latejoin/provocateur/rule_process() - if(check_rev_victory()) - finished = REVOLUTION_VICTORY - return RULESET_STOP_PROCESSING - else if (check_heads_victory()) - finished = STATION_VICTORY - SSshuttle.clearHostileEnvironment(src) - priority_announce("It appears the mutiny has been quelled. Please return yourself and your colleagues to work. \ - We have remotely blacklisted the head revolutionaries from your cloning software to prevent accidental cloning.", null, "attention", null, "Central Command Loyalty Monitoring Division") - for(var/datum/mind/M in revolution.members) // Remove antag datums and prevent headrev cloning then restarting rebellions. - if(M.has_antag_datum(/datum/antagonist/rev/head)) - var/datum/antagonist/rev/head/R = M.has_antag_datum(/datum/antagonist/rev/head) - R.remove_revolutionary(FALSE, "gamemode") - var/mob/living/carbon/C = M.current - if(C.stat == DEAD) - C.makeUncloneable() - if(M.has_antag_datum(/datum/antagonist/rev)) - var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev) - R.remove_revolutionary(FALSE, "gamemode") - return RULESET_STOP_PROCESSING + var/winner = revolution.process_victory(revs_win_threat_injection) + if (isnull(winner)) + return + + finished = winner + return RULESET_STOP_PROCESSING /// Checks for revhead loss conditions and other antag datums. -/datum/dynamic_ruleset/latejoin/provocateur/proc/check_eligible(var/datum/mind/M) +/datum/dynamic_ruleset/latejoin/provocateur/proc/check_eligible(datum/mind/M) var/turf/T = get_turf(M.current) if(!considered_afk(M) && considered_alive(M) && is_station_level(T.z) && !M.antag_datums?.len && !HAS_TRAIT(M, TRAIT_MINDSHIELD)) return TRUE return FALSE -/datum/dynamic_ruleset/latejoin/provocateur/check_finished() - if(finished == REVOLUTION_VICTORY) - return TRUE - else - return ..() - -/datum/dynamic_ruleset/latejoin/provocateur/proc/check_rev_victory() - for(var/datum/objective/mutiny/objective in revolution.objectives) - if(!(objective.check_completion())) - return FALSE - return TRUE - -/datum/dynamic_ruleset/latejoin/provocateur/proc/check_heads_victory() - for(var/datum/mind/rev_mind in revolution.head_revolutionaries()) - var/turf/T = get_turf(rev_mind.current) - if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(T.z)) - if(ishuman(rev_mind.current) || ismonkey(rev_mind.current)) - return FALSE - return TRUE - /datum/dynamic_ruleset/latejoin/provocateur/round_result() - if(finished == REVOLUTION_VICTORY) - SSticker.mode_result = "win - heads killed" - SSticker.news_report = REVS_WIN - else if(finished == STATION_VICTORY) - SSticker.mode_result = "loss - rev heads killed" - SSticker.news_report = REVS_LOSE + revolution.round_result(finished) ////////////////////////////////////////////// // // -// HERETIC SMUGGLER // +// HERETIC SMUGGLER // // // ////////////////////////////////////////////// /datum/dynamic_ruleset/latejoin/heretic_smuggler name = "Heretic Smuggler" antag_datum = /datum/antagonist/heretic - antag_flag = "latejoin_heretic" - protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") + antag_flag = "heretic late" + antag_flag_override = ROLE_HERETIC + protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain","Prisoner", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") restricted_roles = list("AI","Cyborg") required_candidates = 1 weight = 4 - cost = 25 - requirements = list(60,60,60,55,50,50,50,50,50,50) - flags = MINOR_RULESET - high_population_requirement = 50 - property_weights = list("story_potential" = 1, "trust" = -1, "chaos" = 2, "extended" = -1, "valid" = 2) - repeatable = TRUE - -////////////////////////////////////////////// -// // -// BLOODSUCKERS // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/latejoin/bloodsucker - name = "Bloodsucker Infiltrator" - config_tag = "latejoin_bloodsucker" - antag_datum = ANTAG_DATUM_BLOODSUCKER - antag_flag = ROLE_TRAITOR - restricted_roles = list("AI", "Cyborg") - protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") - required_candidates = 1 - weight = 3 cost = 10 - property_weights = list("story_potential" = 2, "extended" = 2, "trust" = -2, "valid" = 1) - requirements = list(70,65,60,55,50,45,40,35,30,30) - flags = MINOR_RULESET - high_population_requirement = 30 + requirements = list(101,101,101,50,40,20,20,15,10,10) repeatable = TRUE - -/datum/dynamic_ruleset/latejoin/bloodsucker/execute() - var/mob/M = pick(candidates) - assigned += M.mind - M.mind.special_role = antag_flag - if(mode.make_bloodsucker(M.mind)) - mode.bloodsuckers += M - log_admin("[M.name] was made into a bloodsucker by dynamic.") - message_admins("[M.name] was made into a bloodsucker by dynamic.") - return TRUE - -////////////////////////////////////////////// -// // -// CHANGELINGS // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/latejoin/changeling - name = "Changeling Infiltrator" - config_tag = "latejoin_changeling" - antag_flag = ROLE_CHANGELING - antag_datum = /datum/antagonist/changeling - restricted_roles = list("AI", "Cyborg") - protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") - required_candidates = 1 - weight = 3 - cost = 15 - flags = MINOR_RULESET - requirements = list(101,101,101,101,101,101,101,101,101,101) - property_weights = list("trust" = -2, "valid" = 2) - high_population_requirement = 101 - -////////////////////////////////////////////// -// // -// COLLECTOR // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/latejoin/collector - name = "Contraband Collector" - config_tag = "latejoin_collector" - antag_datum = /datum/antagonist/collector - antag_flag = ROLE_MINOR_ANTAG - restricted_roles = list("AI", "Cyborg") - protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") - required_candidates = 1 - weight = 5 - cost = 1 - requirements = list(10,10,10,10,10,10,10,10,10,10) - high_population_requirement = 10 - repeatable = TRUE - flags = TRAITOR_RULESET | MINOR_RULESET | FAKE_ANTAG_RULESET - property_weights = list("story_potential" = 1, "trust" = -1, "extended" = 2) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 7ce6e74cc1..c14b7b1d0a 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -1,5 +1,7 @@ -#define REVENANT_SPAWN_THRESHOLD 20 -#define ABDUCTOR_MAX_TEAMS 4 // blame TG for not using the defines files +/// Probability the AI going malf will be accompanied by an ion storm announcement and some ion laws. +#define MALF_ION_PROB 33 +/// The probability to replace an existing law with an ion law instead of adding a new ion law. +#define REPLACE_LAW_WITH_ION_PROB 10 ////////////////////////////////////////////// // // @@ -17,24 +19,20 @@ var/list/living_antags = list() var/list/dead_players = list() var/list/list_observers = list() - var/list/ghost_eligible = list() /datum/dynamic_ruleset/midround/from_ghosts weight = 0 + required_type = /mob/dead/observer /// Whether the ruleset should call generate_ruleset_body or not. var/makeBody = TRUE + /// The rule needs this many applicants to be properly executed. + var/required_applicants = 1 /datum/dynamic_ruleset/midround/trim_candidates() - // - // All you need to know is that here, the candidates list contains 4 lists itself, indexed with the following defines: - // Candidates = list(CURRENT_LIVING_PLAYERS, CURRENT_LIVING_ANTAGS, CURRENT_DEAD_PLAYERS, CURRENT_OBSERVERS) - // So for example you can get the list of all current dead players with var/list/dead_players = candidates[CURRENT_DEAD_PLAYERS] - // Make sure to properly typecheck the mobs in those lists, as the dead_players list could contain ghosts, or dead players still in their bodies. - // We're still gonna trim the obvious (mobs without clients, jobbanned players, etc) living_players = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS]) living_antags = trim_list(mode.current_players[CURRENT_LIVING_ANTAGS]) + dead_players = trim_list(mode.current_players[CURRENT_DEAD_PLAYERS]) list_observers = trim_list(mode.current_players[CURRENT_OBSERVERS]) - ghost_eligible = trim_list(get_all_ghost_role_eligible()) /datum/dynamic_ruleset/midround/proc/trim_list(list/L = list()) var/list/trimmed_list = L.Copy() @@ -42,24 +40,18 @@ if (!istype(M, required_type)) trimmed_list.Remove(M) continue - if (HAS_TRAIT(M, TRAIT_NO_MIDROUND_ANTAG)) - trimmed_list.Remove(M) - continue if (!M.client) // Are they connected? trimmed_list.Remove(M) continue - if(M.client.prefs && M.client.prefs.toggles & MIDROUND_ANTAG) - trimmed_list.Remove(M) - continue if(!mode.check_age(M.client, minimum_required_age)) trimmed_list.Remove(M) continue if(antag_flag_override) - if(!(antag_flag_override in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag_override)) + if(!(HAS_ANTAG_PREF(M.client, antag_flag_override))) trimmed_list.Remove(M) continue else - if(!(antag_flag in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag)) + if(!(HAS_ANTAG_PREF(M.client, antag_flag))) trimmed_list.Remove(M) continue if (M.mind) @@ -74,56 +66,38 @@ continue return trimmed_list -/datum/dynamic_ruleset/midround/from_ghosts/trim_list(list/L = list()) - var/list/trimmed_list = L.Copy() - for(var/mob/M in trimmed_list) - if (!M.client) // Are they connected? - trimmed_list.Remove(M) - continue - if(!mode.check_age(M.client, minimum_required_age)) - trimmed_list.Remove(M) - continue - if(antag_flag_override) - if(!(antag_flag_override in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag_override)) - trimmed_list.Remove(M) - continue - else - if(!(antag_flag in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag)) - trimmed_list.Remove(M) - continue - return trimmed_list - // You can then for example prompt dead players in execute() to join as strike teams or whatever // Or autotator someone // IMPORTANT, since /datum/dynamic_ruleset/midround may accept candidates from both living, dead, and even antag players, you need to manually check whether there are enough candidates -// (see /datum/dynamic_ruleset/midround/autotraitor/ready(var/forced = FALSE) for example) +// (see /datum/dynamic_ruleset/midround/autotraitor/ready(forced = FALSE) for example) /datum/dynamic_ruleset/midround/ready(forced = FALSE) if (!forced) var/job_check = 0 if (enemy_roles.len > 0) for (var/mob/M in mode.current_players[CURRENT_LIVING_PLAYERS]) - if (M.stat == DEAD) - continue // Dead players cannot count as opponents - if (M.mind && M.mind.assigned_role && (M.mind.assigned_role in enemy_roles) && (!(M in candidates) || (M.mind.assigned_role in restricted_roles))) + if (M.stat == DEAD || !M.client) + continue // Dead/disconnected players cannot count as opponents + if (M.mind && (M.mind.assigned_role in enemy_roles) && (!(M in candidates) || (M.mind.assigned_role in restricted_roles))) job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that rule, or have a job that restricts them from it - var/threat = clamp(round(mode.threat_level/10),1,10) + var/threat = round(mode.threat_level/10) if (job_check < required_enemies[threat]) - SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough enemy roles") return FALSE return TRUE /datum/dynamic_ruleset/midround/from_ghosts/ready(forced = FALSE) - if (required_candidates > ghost_eligible.len) - SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts") - return FALSE - return ..() - + return ..() && (length(dead_players) + length(list_observers) >= required_applicants) /datum/dynamic_ruleset/midround/from_ghosts/execute() - var/application_successful = send_applications(ghost_eligible) - return assigned.len > 0 && application_successful + var/list/possible_candidates = list() + possible_candidates.Add(dead_players) + possible_candidates.Add(list_observers) + send_applications(possible_candidates) + if(assigned.len > 0) + return TRUE + else + return FALSE /// This sends a poll to ghosts if they want to be a ghost spawn from a ruleset. /datum/dynamic_ruleset/midround/from_ghosts/proc/send_applications(list/possible_volunteers = list()) @@ -133,25 +107,24 @@ message_admins("Polling [possible_volunteers.len] players to apply for the [name] ruleset.") log_game("DYNAMIC: Polling [possible_volunteers.len] players to apply for the [name] ruleset.") - candidates = pollGhostCandidates("The mode is looking for volunteers to become a [name]", antag_flag, SSticker.mode, antag_flag, poll_time = 300) + candidates = pollGhostCandidates("The mode is looking for volunteers to become [antag_flag] for [name]", antag_flag, be_special_flag = antag_flag_override ? antag_flag_override : antag_flag, poll_time = 300) - if(!candidates || candidates.len < required_candidates) - message_admins("The ruleset [name] did not receive enough applications.") - if(candidates) - message_admins("Only received [candidates.len], needed [required_candidates].") - else - message_admins("There were no candidates.") - log_game("DYNAMIC: The ruleset [name] did not receive enough applications.") - return FALSE + if(!candidates || candidates.len <= 0) + mode.dynamic_log("The ruleset [name] received no applications.") + mode.executed_rules -= src + attempt_replacement() + return message_admins("[candidates.len] players volunteered for the ruleset [name].") log_game("DYNAMIC: [candidates.len] players volunteered for [name].") review_applications() - return TRUE /// Here is where you can check if your ghost applicants are valid for the ruleset. /// Called by send_applications(). /datum/dynamic_ruleset/midround/from_ghosts/proc/review_applications() + if(candidates.len < required_applicants) + mode.executed_rules -= src + return for (var/i = 1, i <= required_candidates, i++) if(candidates.len <= 0) break @@ -175,7 +148,7 @@ finish_setup(new_character, i) assigned += applicant - notify_ghosts("[new_character] has been picked for the ruleset [name]!", source = new_character, action = NOTIFY_ORBIT) + notify_ghosts("[new_character] has been picked for the ruleset [name]!", source = new_character, action = NOTIFY_ORBIT, header="Something Interesting!") /datum/dynamic_ruleset/midround/from_ghosts/proc/generate_ruleset_body(mob/applicant) var/mob/living/carbon/human/new_character = makeBody(applicant) @@ -191,6 +164,20 @@ /datum/dynamic_ruleset/midround/from_ghosts/proc/setup_role(datum/antagonist/new_role) return +/// Fired when there are no valid candidates. Will spawn a sleeper agent or latejoin traitor. +/datum/dynamic_ruleset/midround/from_ghosts/proc/attempt_replacement() + var/datum/dynamic_ruleset/midround/autotraitor/sleeper_agent = new + + // Otherwise, it has a chance to fail. We don't want that, since this is already pretty unlikely. + sleeper_agent.has_failure_chance = FALSE + + mode.configure_ruleset(sleeper_agent) + + if (!mode.picking_specific_rule(sleeper_agent)) + return + + mode.picking_specific_rule(/datum/dynamic_ruleset/latejoin/infiltrator) + ////////////////////////////////////////////// // // // SYNDICATE TRAITORS // @@ -199,39 +186,45 @@ /datum/dynamic_ruleset/midround/autotraitor name = "Syndicate Sleeper Agent" - config_tag = "midround_traitor" antag_datum = /datum/antagonist/traitor - antag_flag = ROLE_TRAITOR - restricted_roles = list("AI", "Cyborg", "Positronic Brain") - protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") + antag_flag = "traitor mid" + protected_roles = list("Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") + restricted_roles = list("Cyborg", "AI", "Positronic Brain") required_candidates = 1 weight = 7 cost = 10 - requirements = list(30,25,20,15,15,15,15,15,15,15) + requirements = list(101,40,30,20,10,10,10,10,10,10) repeatable = TRUE - high_population_requirement = 15 - flags = TRAITOR_RULESET | MINOR_RULESET | ALWAYS_MAX_WEIGHT_RULESET - property_weights = list("story_potential" = 2, "trust" = -1, "extended" = 1) + + /// Whether or not this instance of sleeper agent should be randomly acceptable. + /// If TRUE, then this has a threat level% chance to succeed. + var/has_failure_chance = TRUE /datum/dynamic_ruleset/midround/autotraitor/acceptable(population = 0, threat = 0) var/player_count = mode.current_players[CURRENT_LIVING_PLAYERS].len var/antag_count = mode.current_players[CURRENT_LIVING_ANTAGS].len var/max_traitors = round(player_count / 10) + 1 - if ((antag_count < max_traitors) && prob(min(100,mode.threat_level)))//adding traitors if the antag population is getting low - return ..() - else + + // adding traitors if the antag population is getting low + var/too_little_antags = antag_count < max_traitors + if (!too_little_antags) + log_game("DYNAMIC: Too many living antags compared to living players ([antag_count] living antags, [player_count] living players, [max_traitors] max traitors)") return FALSE + if (has_failure_chance && !prob(mode.threat_level)) + log_game("DYNAMIC: Random chance to roll autotraitor failed, it was a [mode.threat_level]% chance.") + return FALSE + + return ..() + /datum/dynamic_ruleset/midround/autotraitor/trim_candidates() ..() for(var/mob/living/player in living_players) if(issilicon(player)) // Your assigned role doesn't change when you are turned into a silicon. living_players -= player - continue - if(is_centcom_level(player.z)) + else if(is_centcom_level(player.z)) living_players -= player // We don't autotator people in CentCom - continue - if(player.mind && (player.mind.special_role || player.mind.antag_datums?.len > 0)) + else if(player.mind && (player.mind.special_role || player.mind.antag_datums?.len > 0)) living_players -= player // We don't autotator people with roles already /datum/dynamic_ruleset/midround/autotraitor/ready(forced = FALSE) @@ -245,63 +238,118 @@ living_players -= M var/datum/antagonist/traitor/newTraitor = new M.mind.add_antag_datum(newTraitor) - log_admin("[M] was made into a traitor by dynamic.") - message_admins("[M] was made into a traitor by dynamic.") + message_admins("[ADMIN_LOOKUPFLW(M)] was selected by the [name] ruleset and has been made into a midround traitor.") + log_game("DYNAMIC: [key_name(M)] was selected by the [name] ruleset and has been made into a midround traitor.") return TRUE +////////////////////////////////////////////// +// // +// FAMILIES // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/midround/families + name = "Family Head Aspirants" + persistent = TRUE + antag_datum = /datum/antagonist/gang + antag_flag = ROLE_FAMILY_HEAD_ASPIRANT + antag_flag_override = ROLE_FAMILIES + protected_roles = list("Prisoner", "Head of Personnel") + restricted_roles = list("AI", "Cyborg", "Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") + required_candidates = 9 + weight = 3 + cost = 15 + requirements = list(101,101,101,50,30,20,10,10,10,10) + flags = HIGH_IMPACT_RULESET + blocking_rules = list(/datum/dynamic_ruleset/roundstart/families) + /// A reference to the handler that is used to run pre_execute(), execute(), etc.. + var/datum/gang_handler/handler + +/datum/dynamic_ruleset/midround/families/trim_candidates() + ..() + candidates = living_players + for(var/mob/living/player in candidates) + if(issilicon(player)) + candidates -= player + else if(is_centcom_level(player.z)) + candidates -= player + else if(player.mind && (player.mind.special_role || player.mind.antag_datums?.len > 0)) + candidates -= player + else if(HAS_TRAIT(player, TRAIT_MINDSHIELD)) + candidates -= player + + +/datum/dynamic_ruleset/midround/families/ready(forced = FALSE) + if (required_candidates > living_players.len) + return FALSE + return ..() + +/datum/dynamic_ruleset/midround/families/pre_execute() + ..() + handler = new /datum/gang_handler(candidates,restricted_roles) + handler.gang_balance_cap = clamp((indice_pop - 3), 2, 5) // gang_balance_cap by indice_pop: (2,2,2,2,2,3,4,5,5,5) + handler.midround_ruleset = TRUE + handler.use_dynamic_timing = TRUE + return handler.pre_setup_analogue() + +/datum/dynamic_ruleset/midround/families/execute() + return handler.post_setup_analogue(TRUE) + +/datum/dynamic_ruleset/midround/families/clean_up() + QDEL_NULL(handler) + ..() + +/datum/dynamic_ruleset/midround/families/rule_process() + return handler.process_analogue() + +/datum/dynamic_ruleset/midround/families/round_result() + return handler.set_round_result_analogue() ////////////////////////////////////////////// // // // Malfunctioning AI // -// // +// // ////////////////////////////////////////////// /datum/dynamic_ruleset/midround/malf name = "Malfunctioning AI" - config_tag = "midround_malf_ai" antag_datum = /datum/antagonist/traitor antag_flag = ROLE_MALF enemy_roles = list("Security Officer", "Warden","Detective","Head of Security", "Captain", "Scientist", "Chemist", "Research Director", "Chief Engineer") exclusive_roles = list("AI") - required_enemies = list(6,6,6,4,4,4,2,2,2,1) + required_enemies = list(0,0,0,0,0,0,0,0,0,0) required_candidates = 1 - weight = 2 + weight = 3 cost = 35 - requirements = list(101,101,70,50,50,50,40,30,30,30) - high_population_requirement = 30 + requirements = list(101,101,80,70,60,60,50,50,40,40) required_type = /mob/living/silicon/ai - property_weights = list("story_potential" = 2, "trust" = 1, "chaos" = 2) - var/ion_announce = 33 - var/removeDontImproveChance = 10 - -/datum/dynamic_ruleset/midround/malf/ready() - if(!candidates || !candidates.len) - return FALSE - return ..() /datum/dynamic_ruleset/midround/malf/trim_candidates() ..() - for(var/mob/living/player in living_players) + candidates = living_players + for(var/mob/living/player in candidates) if(!isAI(player)) candidates -= player continue + if(is_centcom_level(player.z)) candidates -= player continue + if(player.mind && (player.mind.special_role || player.mind.antag_datums?.len > 0)) candidates -= player /datum/dynamic_ruleset/midround/malf/execute() + if(!candidates || !candidates.len) + return FALSE var/mob/living/silicon/ai/M = pick_n_take(candidates) assigned += M.mind var/datum/antagonist/traitor/AI = new M.mind.special_role = antag_flag M.mind.add_antag_datum(AI) - log_admin("[M] was made into a malf AI by dynamic.") - message_admins("[M] was made into a malf AI by dynamic.") - if(prob(ion_announce)) + if(prob(MALF_ION_PROB)) priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", "ionstorm") - if(prob(removeDontImproveChance)) + if(prob(REPLACE_LAW_WITH_ION_PROB)) M.replace_random_law(generate_ion_law(), list(LAW_INHERENT, LAW_SUPPLIED, LAW_ION)) else M.add_ion_law(generate_ion_law()) @@ -315,21 +363,21 @@ /datum/dynamic_ruleset/midround/from_ghosts/wizard name = "Wizard" - config_tag = "midround_wizard" antag_datum = /datum/antagonist/wizard - antag_flag = ROLE_WIZARD + antag_flag = "wizard mid" + antag_flag_override = ROLE_WIZARD enemy_roles = list("Security Officer","Detective","Head of Security", "Captain") - required_enemies = list(4,4,3,2,2,1,1,0,0,0) + required_enemies = list(0,0,0,0,0,0,0,0,0,0) required_candidates = 1 - weight = 1 + weight = 2 cost = 20 - requirements = list(90,90,70,50,50,50,50,40,30,30) - high_population_requirement = 30 + requirements = list(101,101,100,60,40,20,20,20,10,10) repeatable = TRUE - property_weights = list("story_potential" = 2, "trust" = 1, "chaos" = 2, "extended" = -2) var/datum/mind/wizard /datum/dynamic_ruleset/midround/from_ghosts/wizard/ready(forced = FALSE) + if (required_candidates > (dead_players.len + list_observers.len)) + return FALSE if(GLOB.wizardstart.len == 0) log_admin("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.") message_admins("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.") @@ -341,7 +389,7 @@ new_character.forceMove(pick(GLOB.wizardstart)) wizard = new_character.mind -/datum/dynamic_ruleset/midround/from_ghosts/wizard/rule_process() // i can literally copy this from are_special_antags_dead it's great +/datum/dynamic_ruleset/midround/from_ghosts/wizard/rule_process() if(isliving(wizard.current) && wizard.current.stat!=DEAD) return FALSE for(var/obj/item/phylactery/P in GLOB.poi_list) //TODO : IsProperlyDead() @@ -362,34 +410,31 @@ /datum/dynamic_ruleset/midround/from_ghosts/nuclear name = "Nuclear Assault" - config_tag = "midround_nuclear" - antag_flag = ROLE_OPERATIVE + antag_flag = "nukie mid" antag_datum = /datum/antagonist/nukeop + antag_flag_override = ROLE_OPERATIVE enemy_roles = list("AI", "Cyborg", "Security Officer", "Warden","Detective","Head of Security", "Captain") - required_enemies = list(5,5,4,3,3,2,2,2,1,1) + required_enemies = list(0,0,0,0,0,0,0,0,0,0) required_candidates = 5 - weight = 5 + weight = 3 cost = 35 - requirements = list(90,90,90,80,70,60,50,40,40,40) - high_population_requirement = 40 - property_weights = list("story_potential" = 2, "trust" = 2, "chaos" = 2, "extended" = -2, "valid" = 2) - var/operative_cap = list(2,2,3,3,4,5,5,5,5,5) + requirements = list(101,101,101,60,40,30,20,15,10,10) + var/list/operative_cap = list(2,2,3,3,3,4,5,5,5,5) var/datum/team/nuclear/nuke_team - flags = HIGHLANDER_RULESET + flags = HIGH_IMPACT_RULESET /datum/dynamic_ruleset/midround/from_ghosts/nuclear/acceptable(population=0, threat=0) if (locate(/datum/dynamic_ruleset/roundstart/nuclear) in mode.executed_rules) return FALSE // Unavailable if nuke ops were already sent at roundstart - indice_pop = min(10, round(living_players.len/5)+1) - /* NOTE: The above line's magic value of "10" is a hack due to the fact that byond was - not recognizing operative_cap as a defined variable. It should be operative_cap.len-- - and yes, this means that if the len is changed, this variable must be changed along with it. - One day, once the mystery of why this issue was occuring is figured out, - we may change it back, but until this day comes, we must make it simply 10. - */ + indice_pop = min(operative_cap.len, round(living_players.len/5)+1) required_candidates = operative_cap[indice_pop] return ..() +/datum/dynamic_ruleset/midround/from_ghosts/nuclear/ready(forced = FALSE) + if (required_candidates > (dead_players.len + list_observers.len)) + return FALSE + return ..() + /datum/dynamic_ruleset/midround/from_ghosts/nuclear/finish_setup(mob/new_character, index) new_character.mind.special_role = "Nuclear Operative" new_character.mind.assigned_role = "Nuclear Operative" @@ -400,6 +445,70 @@ else return ..() +////////////////////////////////////////////// +// // +// Clock Cult (MID) // +// // +////////////////////////////////////////////// + + +//changes two people midround into clockwork cultists +/datum/dynamic_ruleset/midround/ratvar_awakening + name = "Ratvar Awakening" + antag_datum = /datum/antagonist/clockcult + antag_flag = "clock mid" + antag_flag_override = ROLE_SERVANT_OF_RATVAR + protected_roles = list("AI", "Cyborg", "Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") + restricted_roles = list("AI", "Cyborg", "Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") + enemy_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") + required_enemies = list(1,1,1,1,1,1,0,0,0,0) + required_candidates = 2 + weight = 3 + cost = 20 + requirements = list(101,101,101,101,50,40,30,20,10,10) + var/list/clock_cap = list(1,1,1,1,2,3,4,5,5,5) + flags = HIGH_IMPACT_RULESET + +/datum/dynamic_ruleset/midround/ratvar_awakening/acceptable(population=0, threat=0) + if (locate(/datum/dynamic_ruleset/roundstart/clockcult) in mode.executed_rules) + return FALSE // Unavailable if clockies exist at round start + indice_pop = min(clock_cap.len, round(living_players.len/5)+1) + required_candidates = clock_cap[indice_pop] + return ..() + +/datum/dynamic_ruleset/midround/ratvar_awakening/trim_candidates() + ..() + candidates = living_players + for(var/mob/living/player as anything in candidates) + var/turf/player_turf = get_turf(player) + if(!player_turf || !is_station_level(player_turf.z)) + candidates -= player //no ghost roles + continue + + if(!is_eligible_servant(player)) + candidates -= player + continue + + if(player.mind && (player.mind.special_role || length(player.mind.antag_datums) > 0)) + candidates -= player //no double dipping + +/datum/dynamic_ruleset/midround/ratvar_awakening/execute() + if(!candidates || !candidates.len) + return FALSE + for(var/i = 0; i < required_candidates; i++) + if(!candidates.len) + break + var/mob/living/clock_antag = pick_n_take(candidates) + assigned += clock_antag.mind + for(var/datum/mind/M in assigned) //add them to the clockwork team + add_servant_of_ratvar(M.current) + SSticker.mode.equip_servant(M.current) + SSticker.mode.greet_servant(M.current) + message_admins("[ADMIN_LOOKUPFLW(M.current)] was selected by the [name] ruleset and has been made into a midround clock cultist.") + log_game("DYNAMIC: [key_name(M.current)] was selected by the [name] ruleset and has been made into a midround clock cultist.") + load_reebe() + return ..() + ////////////////////////////////////////////// // // // BLOB (GHOST) // @@ -408,24 +517,55 @@ /datum/dynamic_ruleset/midround/from_ghosts/blob name = "Blob" - config_tag = "blob" antag_datum = /datum/antagonist/blob antag_flag = ROLE_BLOB enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") - required_enemies = list(3,3,2,2,2,1,1,1,1,0) + required_enemies = list(0,0,0,0,0,0,0,0,0,0) required_candidates = 1 - blocking_rules = list(/datum/dynamic_ruleset/roundstart/clockcult) - weight = 4 - cost = 20 - requirements = list(101,101,101,80,60,50,50,50,50,50) - high_population_requirement = 50 + weight = 2 + cost = 10 + requirements = list(101,101,101,101,50,40,30,20,10,10) repeatable = TRUE - property_weights = list("story_potential" = -1, "trust" = 2, "chaos" = 2, "extended" = -2, "valid" = 2) /datum/dynamic_ruleset/midround/from_ghosts/blob/generate_ruleset_body(mob/applicant) var/body = applicant.become_overmind() return body +/// Infects a random player, making them explode into a blob. +/datum/dynamic_ruleset/midround/blob_infection + name = "Blob Infection" + antag_datum = /datum/antagonist/blob + antag_flag = "blob mid" + protected_roles = list("Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain") + restricted_roles = list("Cyborg", "AI", "Positronic Brain") + enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") + required_enemies = list(0,0,0,0,0,0,0,0,0,0) + required_candidates = 1 + weight = 2 + cost = 10 + requirements = list(101,101,101,101,50,40,30,20,10,10) + repeatable = TRUE + +/datum/dynamic_ruleset/midround/blob_infection/trim_candidates() + ..() + candidates = living_players + for(var/mob/living/player as anything in candidates) + var/turf/player_turf = get_turf(player) + if(!player_turf || !is_station_level(player_turf.z)) + candidates -= player + continue + + if(player.mind && (player.mind.special_role || length(player.mind.antag_datums) > 0)) + candidates -= player + +/datum/dynamic_ruleset/midround/blob_infection/execute() + if(!candidates || !candidates.len) + return FALSE + var/mob/living/carbon/human/blob_antag = pick_n_take(candidates) + assigned += blob_antag.mind + blob_antag.mind.special_role = antag_flag + return ..() + ////////////////////////////////////////////// // // // XENOMORPH (GHOST) // @@ -434,22 +574,20 @@ /datum/dynamic_ruleset/midround/from_ghosts/xenomorph name = "Alien Infestation" - config_tag = "xenos" antag_datum = /datum/antagonist/xeno antag_flag = ROLE_ALIEN enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") - required_enemies = list(3,3,2,2,1,1,1,1,1,0) + required_enemies = list(0,0,0,0,0,0,0,0,0,0) required_candidates = 1 weight = 3 cost = 10 - requirements = list(101,101,101,70,50,50,50,50,50,50) - high_population_requirement = 50 - repeatable_weight_decrease = 2 + requirements = list(101,101,101,101,50,40,30,20,10,10) repeatable = TRUE - property_weights = list("story_potential" = -1, "trust" = 1, "chaos" = 2, "extended" = -2, "valid" = 2) var/list/vents = list() -/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/ready() +/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/execute() + // 50% chance of being incremented by one + required_candidates += prob(50) for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in GLOB.machines) if(QDELETED(temp_vent)) continue @@ -463,18 +601,12 @@ vents += temp_vent if(!vents.len) return FALSE - return ..() - - -/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/execute() - // 50% chance of being incremented by one - required_candidates += prob(50) . = ..() /datum/dynamic_ruleset/midround/from_ghosts/xenomorph/generate_ruleset_body(mob/applicant) var/obj/vent = pick_n_take(vents) var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc) - applicant.transfer_ckey(new_xeno, FALSE) + new_xeno.key = applicant.key message_admins("[ADMIN_LOOKUPFLW(new_xeno)] has been made into an alien by the midround ruleset.") log_game("DYNAMIC: [key_name(new_xeno)] was spawned as an alien by the midround ruleset.") return new_xeno @@ -487,24 +619,19 @@ /datum/dynamic_ruleset/midround/from_ghosts/nightmare name = "Nightmare" - config_tag = "nightmare" antag_datum = /datum/antagonist/nightmare antag_flag = "Nightmare" antag_flag_override = ROLE_ALIEN enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") - required_enemies = list(2,2,1,1,1,1,1,0,0,0) + required_enemies = list(0,0,0,0,0,0,0,0,0,0) required_candidates = 1 - weight = 3 + weight = 4 cost = 10 - flags = MINOR_RULESET - requirements = list(101,101,101,70,50,40,20,15,15,15) - high_population_requirement = 50 - repeatable_weight_decrease = 2 + requirements = list(101,101,50,30,25,20,10,10,10,10) repeatable = TRUE - property_weights = list("story_potential" = 1, "trust" = 1, "extended" = 1, "valid" = 2, "integrity" = 1) var/list/spawn_locs = list() -/datum/dynamic_ruleset/midround/from_ghosts/nightmare/ready() +/datum/dynamic_ruleset/midround/from_ghosts/nightmare/execute() for(var/X in GLOB.xeno_spawn) var/turf/T = X var/light_amount = T.get_lumcount() @@ -512,7 +639,7 @@ spawn_locs += T if(!spawn_locs.len) return FALSE - return ..() + . = ..() /datum/dynamic_ruleset/midround/from_ghosts/nightmare/generate_ruleset_body(mob/applicant) var/datum/mind/player_mind = new /datum/mind(applicant.key) @@ -525,162 +652,263 @@ player_mind.add_antag_datum(/datum/antagonist/nightmare) S.set_species(/datum/species/shadow/nightmare) - playsound(S, 'sound/magic/ethereal_exit.ogg', 50, 1, -1) + playsound(S, 'sound/magic/ethereal_exit.ogg', 50, TRUE, -1) message_admins("[ADMIN_LOOKUPFLW(S)] has been made into a Nightmare by the midround ruleset.") log_game("DYNAMIC: [key_name(S)] was spawned as a Nightmare by the midround ruleset.") return S ////////////////////////////////////////////// // // -// SLAUGHTER DEMON // +// SPACE DRAGON (GHOST) // // // ////////////////////////////////////////////// - -/datum/dynamic_ruleset/midround/from_ghosts/slaughter_demon - name = "Slaughter Demon" - config_tag = "slaughter_demon" - antag_flag = ROLE_ALIEN - enemy_roles = list("Security Officer","Shaft Miner","Head of Security","Captain","Janitor","AI","Cyborg","Bartender") - required_enemies = list(3,2,2,2,2,1,1,1,1,0) +/datum/dynamic_ruleset/midround/from_ghosts/space_dragon + name = "Space Dragon" + antag_datum = /datum/antagonist/space_dragon + antag_flag = ROLE_SPACE_DRAGON + antag_flag_override = ROLE_SPACE_DRAGON + enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") + required_enemies = list(0,0,0,0,0,0,0,0,0,0) required_candidates = 1 - weight = 4 - cost = 15 - requirements = list(101,101,101,90,80,70,60,50,40,30) - property_weights = list("story_potential" = -2, "extended" = -2, "integrity" = 2, "valid" = 2, "trust" = 2) - high_population_requirement = 30 + weight = 3 + cost = 10 + requirements = list(101,101,101,101,50,40,30,20,10,10) + repeatable = TRUE var/list/spawn_locs = list() -/datum/dynamic_ruleset/midround/from_ghosts/slaughter_demon/ready(forced = FALSE) - for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list) - if(isturf(L.loc)) - spawn_locs += L.loc - +/datum/dynamic_ruleset/midround/from_ghosts/space_dragon/execute() + for(var/obj/effect/landmark/carpspawn/C in GLOB.landmarks_list) + spawn_locs += (C.loc) if(!spawn_locs.len) - return FALSE - return ..() + message_admins("No valid spawn locations found, aborting...") + return MAP_ERROR + . = ..() -/datum/dynamic_ruleset/midround/from_ghosts/slaughter_demon/generate_ruleset_body(mob/applicant) +/datum/dynamic_ruleset/midround/from_ghosts/space_dragon/generate_ruleset_body(mob/applicant) var/datum/mind/player_mind = new /datum/mind(applicant.key) - player_mind.active = 1 - var/obj/effect/dummy/phased_mob/slaughter/holder = new /obj/effect/dummy/phased_mob/slaughter((pick(spawn_locs))) - var/mob/living/simple_animal/slaughter/S = new (holder) - S.holder = holder + player_mind.active = TRUE + + var/mob/living/simple_animal/hostile/space_dragon/S = new (pick(spawn_locs)) player_mind.transfer_to(S) - player_mind.assigned_role = "Slaughter Demon" - player_mind.special_role = "Slaughter Demon" - player_mind.add_antag_datum(/datum/antagonist/slaughter) - to_chat(S, S.playstyle_string) - to_chat(S, "You are currently not currently in the same plane of existence as the station. Blood Crawl near a blood pool to manifest.") - SEND_SOUND(S, 'sound/magic/demon_dies.ogg') - message_admins("[ADMIN_LOOKUPFLW(S)] has been made into a slaughter demon by dynamic.") - log_game("[key_name(S)] was spawned as a slaughter demon by dynamic.") + player_mind.assigned_role = "Space Dragon" + player_mind.special_role = ROLE_SPACE_DRAGON + player_mind.add_antag_datum(/datum/antagonist/space_dragon) + + playsound(S, 'sound/magic/ethereal_exit.ogg', 50, TRUE, -1) + message_admins("[ADMIN_LOOKUPFLW(S)] has been made into a Space Dragon by the midround ruleset.") + log_game("DYNAMIC: [key_name(S)] was spawned as a Space Dragon by the midround ruleset.") + priority_announce("A large organic energy flux has been recorded near of [station_name()], please stand-by.", "Lifesign Alert") return S ////////////////////////////////////////////// // // -// ABDUCTORS // +// ABDUCTORS (GHOST) // // // ////////////////////////////////////////////// +#define ABDUCTOR_MAX_TEAMS 4 /datum/dynamic_ruleset/midround/from_ghosts/abductors name = "Abductors" - config_tag = "abductors" - antag_flag = ROLE_ABDUCTOR - // Has two antagonist flags, in fact - enemy_roles = list("AI", "Cyborg", "Security Officer", "Warden","Detective","Head of Security", "Captain") - required_enemies = list(3,3,2,2,1,1,0,0,0,0) + antag_flag = "Abductor" + antag_flag_override = ROLE_ABDUCTOR + enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") + required_enemies = list(0,0,0,0,0,0,0,0,0,0) required_candidates = 2 - weight = 8 + required_applicants = 2 + weight = 3 cost = 10 - requirements = list(101,101,70,50,40,30,30,30,30,30) - blocking_rules = list(/datum/dynamic_ruleset/roundstart/nuclear,/datum/dynamic_ruleset/midround/from_ghosts/nuclear) - high_population_requirement = 15 - var/datum/team/abductor_team/team - property_weights = list("extended" = -2, "valid" = 1, "trust" = -1, "chaos" = 2) - repeatable_weight_decrease = 4 + requirements = list(101,101,101,101,101,30,20,15,10,10) repeatable = TRUE + var/datum/team/abductor_team/new_team /datum/dynamic_ruleset/midround/from_ghosts/abductors/ready(forced = FALSE) - team = new /datum/team/abductor_team - if(team.team_number > ABDUCTOR_MAX_TEAMS) + if (required_candidates > (dead_players.len + list_observers.len)) return FALSE return ..() /datum/dynamic_ruleset/midround/from_ghosts/abductors/finish_setup(mob/new_character, index) - switch(index) - if(1) // yeah this seems like a baffling anti-pattern but it's actually the best way to do this, shit you not - var/mob/living/carbon/human/agent = new_character - agent.mind.add_antag_datum(/datum/antagonist/abductor/agent, team) - log_game("[key_name(agent)] has been selected as [team.name] abductor agent.") - if(2) - var/mob/living/carbon/human/scientist = new_character - scientist.mind.add_antag_datum(/datum/antagonist/abductor/scientist, team) - log_game("[key_name(scientist)] has been selected as [team.name] abductor scientist.") + if (index == 1) // Our first guy is the scientist. We also initialize the team here as well since this should only happen once per pair of abductors. + new_team = new + if(new_team.team_number > ABDUCTOR_MAX_TEAMS) + return MAP_ERROR + var/datum/antagonist/abductor/scientist/new_role = new + new_character.mind.add_antag_datum(new_role, new_team) + else // Our second guy is the agent, team is already created, don't need to make another one. + var/datum/antagonist/abductor/agent/new_role = new + new_character.mind.add_antag_datum(new_role, new_team) + +#undef ABDUCTOR_MAX_TEAMS ////////////////////////////////////////////// // // -// SPACE NINJA // +// SWARMERS (GHOST) // // // ////////////////////////////////////////////// -/datum/dynamic_ruleset/midround/from_ghosts/ninja +/datum/dynamic_ruleset/midround/swarmers + name = "Swarmers" + antag_flag = "Swarmer" + antag_flag_override = ROLE_ALIEN + required_type = /mob/dead/observer + enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") + required_enemies = list(0,0,0,0,0,0,0,0,0,0) + required_candidates = 0 + weight = 3 + cost = 10 + requirements = list(101,101,101,101,50,40,30,20,10,10) + repeatable = TRUE + +/datum/dynamic_ruleset/midround/swarmers/execute() + var/list/spawn_locs = list() + for(var/x in GLOB.xeno_spawn) + var/turf/spawn_turf = x + var/light_amount = spawn_turf.get_lumcount() + if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD) + spawn_locs += spawn_turf + if(!spawn_locs.len) + message_admins("No valid spawn locations found in GLOB.xeno_spawn, aborting swarmer spawning...") + return MAP_ERROR + new /obj/effect/mob_spawn/swarmer(get_turf(GLOB.the_gateway)) + log_game("A Swarmer was spawned via Dynamic Mode.") + return ..() + +////////////////////////////////////////////// +// // +// SPACE NINJA (GHOST) // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/midround/from_ghosts/space_ninja name = "Space Ninja" - config_tag = "ninja" - antag_flag = ROLE_NINJA - enemy_roles = list("Security Officer","Head of Security","Captain","AI","Cyborg") - required_enemies = list(3,2,2,2,2,1,1,1,1,0) + antag_datum = /datum/antagonist/ninja + antag_flag = "Space Ninja" + antag_flag_override = ROLE_NINJA + enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") + required_enemies = list(0,0,0,0,0,0,0,0,0,0) required_candidates = 1 weight = 4 - cost = 15 - flags = MINOR_RULESET - requirements = list(101,101,101,90,80,70,60,50,40,30) - high_population_requirement = 30 - property_weights = list("story_potential" = 1, "extended" = -2, "valid" = 2) + cost = 10 + requirements = list(101,101,101,60,50,30,10,10,10,10) + repeatable = TRUE var/list/spawn_locs = list() - var/spawn_loc -/datum/dynamic_ruleset/midround/from_ghosts/ninja/ready(forced = FALSE) - if(!spawn_loc) - var/list/spawn_locs = list() - for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list) - if(isturf(L.loc)) - spawn_locs += L.loc - for(var/obj/effect/landmark/loneopspawn/L in GLOB.landmarks_list) - if(isturf(L.loc)) - spawn_locs += L.loc - if(!spawn_locs.len) - return FALSE - spawn_loc = pick(spawn_locs) - if(!spawn_loc) +/datum/dynamic_ruleset/midround/from_ghosts/space_ninja/execute() + for(var/obj/effect/landmark/carpspawn/carp_spawn in GLOB.landmarks_list) + if(!isturf(carp_spawn.loc)) + stack_trace("Carp spawn found not on a turf: [carp_spawn.type] on [isnull(carp_spawn.loc) ? "null" : carp_spawn.loc.type]") + continue + spawn_locs += carp_spawn.loc + if(!spawn_locs.len) + message_admins("No valid spawn locations found, aborting...") + return MAP_ERROR + return ..() + +/datum/dynamic_ruleset/midround/from_ghosts/space_ninja/generate_ruleset_body(mob/applicant) + var/mob/living/carbon/human/ninja = create_space_ninja(pick(spawn_locs)) + ninja.key = applicant.key + ninja.mind.add_antag_datum(/datum/antagonist/ninja) + + message_admins("[ADMIN_LOOKUPFLW(ninja)] has been made into a Space Ninja by the midround ruleset.") + log_game("DYNAMIC: [key_name(ninja)] was spawned as a Space Ninja by the midround ruleset.") + return ninja + +////////////////////////////////////////////// +// // +// Revenant (GHOST) // +// // +////////////////////////////////////////////// + +/// Revenant ruleset +/datum/dynamic_ruleset/midround/from_ghosts/revenant + name = "Revenant" + antag_datum = /datum/antagonist/revenant + antag_flag = "Revenant" + antag_flag_override = ROLE_REVENANT + enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") + required_enemies = list(0,0,0,0,0,0,0,0,0,0) + required_candidates = 1 + weight = 4 + cost = 10 + requirements = list(101,101,50,30,25,20,10,10,10,10) + repeatable = TRUE + var/dead_mobs_required = 20 + var/need_extra_spawns_value = 15 + var/list/spawn_locs = list() + +/datum/dynamic_ruleset/midround/from_ghosts/revenant/acceptable(population=0, threat=0) + if(GLOB.dead_mob_list.len < dead_mobs_required) return FALSE return ..() -/datum/dynamic_ruleset/midround/from_ghosts/ninja/generate_ruleset_body(mob/applicant) - var/key = applicant.key +/datum/dynamic_ruleset/midround/from_ghosts/revenant/execute() + for(var/mob/living/corpse in GLOB.dead_mob_list) //look for any dead bodies + var/turf/corpse_turf = get_turf(corpse) + if(corpse_turf && is_station_level(corpse_turf.z)) + spawn_locs += corpse_turf + if(!spawn_locs.len || spawn_locs.len < need_extra_spawns_value) //look for any morgue trays, crematoriums, ect if there weren't alot of dead bodies on the station to pick from + for(var/obj/structure/bodycontainer/corpse_container in GLOB.bodycontainers) + var/turf/container_turf = get_turf(corpse_container) + if(container_turf && is_station_level(container_turf.z)) + spawn_locs += container_turf + if(!spawn_locs.len) //If we can't find any valid spawnpoints, try the carp spawns + for(var/obj/effect/landmark/carpspawn/carp_spawnpoint in GLOB.landmarks_list) + if(isturf(carp_spawnpoint.loc)) + spawn_locs += carp_spawnpoint.loc + if(!spawn_locs.len) //If we can't find THAT, then just give up and cry + return FALSE + . = ..() - //Prepare ninja player mind - var/datum/mind/Mind = new /datum/mind(key) - Mind.assigned_role = ROLE_NINJA - Mind.special_role = ROLE_NINJA - Mind.active = 1 +/datum/dynamic_ruleset/midround/from_ghosts/revenant/generate_ruleset_body(mob/applicant) + var/mob/living/simple_animal/revenant/revenant = new(pick(spawn_locs)) + revenant.key = applicant.key + message_admins("[ADMIN_LOOKUPFLW(revenant)] has been made into a revenant by the midround ruleset.") + log_game("[key_name(revenant)] was spawned as a revenant by the midround ruleset.") + return revenant - //spawn the ninja and assign the candidate - var/mob/living/carbon/human/Ninja = create_space_ninja(spawn_loc) - Mind.transfer_to(Ninja) - var/datum/antagonist/ninja/ninjadatum = new - ninjadatum.helping_station = pick(TRUE,FALSE) - Mind.add_antag_datum(ninjadatum) +/// Sentient Disease ruleset +/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease + name = "Sentient Disease" + antag_datum = /datum/antagonist/disease + antag_flag = "Sentient Disease" + antag_flag_override = ROLE_ALIEN + required_candidates = 1 + weight = 4 + cost = 10 + requirements = list(101,101,50,30,25,20,10,10,10,10) + repeatable = TRUE - if(Ninja.mind != Mind) //something has gone wrong! - stack_trace("Ninja created with incorrect mind") +/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/generate_ruleset_body(mob/applicant) + var/mob/camera/disease/virus = new /mob/camera/disease(SSmapping.get_station_center()) + virus.key = applicant.key + INVOKE_ASYNC(virus, /mob/camera/disease/proc/pick_name) + message_admins("[ADMIN_LOOKUPFLW(virus)] has been made into a sentient disease by the midround ruleset.") + log_game("[key_name(virus)] was spawned as a sentient disease by the midround ruleset.") + return virus - message_admins("[ADMIN_LOOKUPFLW(Ninja)] has been made into a ninja by dynamic.") - log_game("[key_name(Ninja)] was spawned as a ninja by dynamic.") - return Ninja +/// Space Pirates ruleset +/datum/dynamic_ruleset/midround/pirates + name = "Space Pirates" + antag_flag = "Space Pirates" + required_type = /mob/dead/observer + enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") + required_enemies = list(0,0,0,0,0,0,0,0,0,0) + required_candidates = 0 + weight = 4 + cost = 10 + requirements = list(101,101,101,40,30,20,10,10,10,10) + repeatable = TRUE -/datum/dynamic_ruleset/midround/from_ghosts/ninja/finish_setup(mob/new_character, index) - return +/datum/dynamic_ruleset/midround/pirates/acceptable(population=0, threat=0) + if (!SSmapping.empty_space) + return FALSE + return ..() -#undef ABDUCTOR_MAX_TEAMS -#undef REVENANT_SPAWN_THRESHOLD +/datum/dynamic_ruleset/midround/pirates/execute() + send_pirate_threat() + return ..() + +/// Probability the AI going malf will be accompanied by an ion storm announcement and some ion laws. +#undef MALF_ION_PROB +/// The probability to replace an existing law with an ion law instead of adding a new ion law. +#undef REPLACE_LAW_WITH_ION_PROB diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_minor.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_minor.dm deleted file mode 100644 index 74a61bd3ff..0000000000 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_minor.dm +++ /dev/null @@ -1,255 +0,0 @@ -/datum/dynamic_ruleset/minor/proc/trim_list(list/L = list()) - var/list/trimmed_list = L.Copy() - for(var/mob/M in trimmed_list) - if (!ishuman(M)) - trimmed_list.Remove(M) - continue - if (HAS_TRAIT(M, TRAIT_NO_MIDROUND_ANTAG)) - trimmed_list.Remove(M) - continue - if (!M.client) // Are they connected? - trimmed_list.Remove(M) - continue - if(!mode.check_age(M.client, minimum_required_age)) - trimmed_list.Remove(M) - continue - if(antag_flag_override) - if(!(antag_flag_override in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag_override)) - trimmed_list.Remove(M) - continue - else - if(!(antag_flag in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag)) - trimmed_list.Remove(M) - continue - if (M.mind) - if ((M.mind.assigned_role in GLOB.exp_specialmap[EXP_TYPE_SPECIAL])) // Are they playing a ghost role? - trimmed_list.Remove(M) - continue - if (M.mind.assigned_role in restricted_roles) // Does their job allow it? - trimmed_list.Remove(M) - continue - if ((exclusive_roles.len > 0) && !(M.mind.assigned_role in exclusive_roles)) // Is the rule exclusive to their job? - trimmed_list.Remove(M) - continue - return trimmed_list - -/datum/dynamic_ruleset/minor/trim_candidates() - // - // All you need to know is that here, the candidates list contains 4 lists itself, indexed with the following defines: - // Candidates = list(CURRENT_LIVING_PLAYERS, CURRENT_LIVING_ANTAGS, CURRENT_DEAD_PLAYERS, CURRENT_OBSERVERS) - // So for example you can get the list of all current dead players with var/list/dead_players = candidates[CURRENT_DEAD_PLAYERS] - // Make sure to properly typecheck the mobs in those lists, as the dead_players list could contain ghosts, or dead players still in their bodies. - // We're still gonna trim the obvious (mobs without clients, jobbanned players, etc) - candidates = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS]) - -////////////////////////////////////////////// -// // -// SYNDICATE TRAITORS // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/minor/traitor - name = "Traitors" - config_tag = "traitor" // these having identical config tags to the roundstart modes is 100% intentional, so that config edits are simpler - persistent = TRUE - antag_flag = ROLE_TRAITOR - antag_datum = /datum/antagonist/traitor/ - minimum_required_age = 0 - protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster", "Cyborg") - restricted_roles = list("Cyborg", "AI") - required_candidates = 1 - weight = 5 - flags = TRAITOR_RULESET | ALWAYS_MAX_WEIGHT_RULESET - cost = 10 // Avoid raising traitor threat above 10, as it is the default low cost ruleset. - requirements = list(50,50,50,50,50,50,50,50,50,50) - high_population_requirement = 40 - property_weights = list("story_potential" = 2, "trust" = -1, "extended" = 1, "valid" = 1) - -/datum/dynamic_ruleset/minor/traitor/execute() - var/mob/M = pick_n_take(candidates) - assigned += M - var/datum/antagonist/traitor/newTraitor = new - M.mind.add_antag_datum(newTraitor) - log_admin("[M] was made into a traitor by dynamic.") - message_admins("[M] was made into a traitor by dynamic.") - return TRUE - -////////////////////////////////////////// -// // -// BLOOD BROTHERS // -// // -////////////////////////////////////////// - -/datum/dynamic_ruleset/minor/traitorbro - name = "Blood Brothers" - config_tag = "traitorbro" - antag_flag = ROLE_BROTHER - antag_datum = /datum/antagonist/brother - restricted_roles = list("AI", "Cyborg") - protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") - required_candidates = 2 - weight = 4 - cost = 10 - requirements = list(101,101,101,101,101,101,101,101,101,101) - high_population_requirement = 101 - antag_cap = list(2,2,2,2,2,2,2,2,2,2) // Can pick 3 per team, but rare enough it doesn't matter. - property_weights = list("story_potential" = 1, "trust" = -1, "extended" = 1, "valid" = 1) - var/list/datum/team/brother_team/pre_brother_teams = list() - var/const/min_team_size = 2 - -/datum/dynamic_ruleset/minor/traitorbro/execute() - if(candidates.len < min_team_size || candidates.len < required_candidates) - return FALSE - var/datum/team/brother_team/team = new - var/team_size = prob(10) ? min(3, candidates.len) : 2 - for(var/k = 1 to team_size) - var/mob/bro = pick_n_take(candidates) - assigned += bro.mind - team.add_member(bro.mind) - bro.mind.special_role = "brother" - bro.mind.restricted_roles = restricted_roles - team.pick_meeting_area() - team.forge_brother_objectives() - for(var/datum/mind/M in team.members) - M.add_antag_datum(/datum/antagonist/brother, team) - team.update_name() - mode.brother_teams += team - -////////////////////////////////////////////// -// // -// CHANGELINGS // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/minor/changeling - name = "Changelings" - config_tag = "changeling" - antag_flag = ROLE_CHANGELING - antag_datum = /datum/antagonist/changeling - restricted_roles = list("AI", "Cyborg") - protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") - required_candidates = 1 - weight = 3 - cost = 15 - scaling_cost = 15 - requirements = list(101,101,101,101,101,101,101,101,101,101) - property_weights = list("trust" = -2, "valid" = 2) - high_population_requirement = 10 - antag_cap = list(1,1,1,1,1,2,2,2,2,3) - var/team_mode_probability = 30 - -/datum/dynamic_ruleset/minor/changeling/execute() - var/mob/M = pick_n_take(candidates) - assigned += M.mind - M.mind.restricted_roles = restricted_roles - M.mind.special_role = ROLE_CHANGELING - var/datum/antagonist/changeling/new_antag = new antag_datum() - M.mind.add_antag_datum(new_antag) - return TRUE - -////////////////////////////////////////////// -// // -// ELDRITCH CULT // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/minor/heretics - name = "Heretic" - antag_flag = "heretic" - antag_datum = /datum/antagonist/heretic - protected_roles = list("Prisoner","Security Officer", "Warden", "Detective", "Head of Security", "Captain") - restricted_roles = list("AI", "Cyborg") - required_candidates = 1 - weight = 3 - cost = 25 - scaling_cost = 15 - requirements = list(60,60,60,55,50,50,50,50,50,50) - property_weights = list("story_potential" = 1, "trust" = -1, "chaos" = 2, "extended" = -1, "valid" = 2) - antag_cap = list(1,1,1,1,2,2,2,2,3,3) - high_population_requirement = 50 - - -/datum/dynamic_ruleset/minor/heretics/pre_execute() - var/mob/picked_candidate = pick_n_take(candidates) - assigned += picked_candidate.mind - picked_candidate.mind.restricted_roles = restricted_roles - picked_candidate.mind.special_role = ROLE_HERETIC - var/datum/antagonist/heretic/new_antag = new antag_datum() - picked_candidate.mind.add_antag_datum(new_antag) - return TRUE - -////////////////////////////////////////////// -// // -// DEVIL // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/minor/devil - name = "Devil" - config_tag = "devil" - antag_flag = ROLE_DEVIL - antag_datum = /datum/antagonist/devil - restricted_roles = list("Lawyer", "Curator", "Chaplain", "Head of Security", "Captain", "AI") - required_candidates = 1 - weight = 3 - cost = 0 - requirements = list(101,101,101,101,101,101,101,101,101,101) - high_population_requirement = 101 - antag_cap = list(1,1,1,2,2,2,3,3,3,4) - property_weights = list("extended" = 1) - -/datum/dynamic_ruleset/minor/devil/pre_execute() - var/mob/devil = pick_n_take(candidates) - assigned += devil.mind - devil.mind.special_role = ROLE_DEVIL - devil.mind.restricted_roles = restricted_roles - - log_game("[key_name(devil)] has been selected as a devil") - add_devil(devil, ascendable = TRUE) - add_devil_objectives(devil.mind,2) - return TRUE - -/datum/dynamic_ruleset/minor/devil/proc/add_devil_objectives(datum/mind/devil_mind, quantity) - var/list/validtypes = list(/datum/objective/devil/soulquantity, /datum/objective/devil/soulquality, /datum/objective/devil/sintouch, /datum/objective/devil/buy_target) - var/datum/antagonist/devil/D = devil_mind.has_antag_datum(/datum/antagonist/devil) - for(var/i = 1 to quantity) - var/type = pick(validtypes) - var/datum/objective/devil/objective = new type(null) - objective.owner = devil_mind - D.objectives += objective - if(!istype(objective, /datum/objective/devil/buy_target)) - validtypes -= type - else - objective.find_target() - -////////////////////////////////////////////// -// // -// BLOODSUCKERS // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/minor/bloodsucker - name = "Bloodsuckers" - config_tag = "bloodsucker" - antag_flag = ROLE_BLOODSUCKER - antag_datum = ANTAG_DATUM_BLOODSUCKER - minimum_required_age = 0 - protected_roles = list("Chaplain", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") - restricted_roles = list("Cyborg", "AI") - required_candidates = 1 - weight = 2 - cost = 15 - scaling_cost = 10 - property_weights = list("story_potential" = 1, "extended" = 1, "trust" = -2, "valid" = 1) - requirements = list(70,65,60,55,50,50,50,50,50,50) - high_population_requirement = 50 - -/datum/dynamic_ruleset/minor/bloodsucker/execute() - var/mob/M = pick_n_take(candidates) - assigned += M.mind - M.mind.special_role = ROLE_BLOODSUCKER - M.mind.restricted_roles = restricted_roles - mode.check_start_sunlight() - if(mode.make_bloodsucker(M.mind)) - mode.bloodsuckers += M.mind - return TRUE diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index 1be5cb3c57..a9d0ec7d3c 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -7,25 +7,25 @@ /datum/dynamic_ruleset/roundstart/traitor name = "Traitors" - config_tag = "traitor" + persistent = TRUE antag_flag = ROLE_TRAITOR - antag_datum = /datum/antagonist/traitor/ + antag_datum = /datum/antagonist/traitor minimum_required_age = 0 - protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster", "Cyborg") - restricted_roles = list("Cyborg", "AI") + protected_roles = list("Prisoner","Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") + restricted_roles = list("AI", "Cyborg") required_candidates = 1 - flags = TRAITOR_RULESET | MINOR_RULESET | ALWAYS_MAX_WEIGHT_RULESET weight = 5 - cost = 10 // Avoid raising traitor threat above 10, as it is the default low cost ruleset. - scaling_cost = 10 - requirements = list(50,50,50,50,50,50,50,50,50,50) - high_population_requirement = 40 - antag_cap = list(1,1,1,1,2,2,2,2,3,3) - property_weights = list("story_potential" = 2, "trust" = -1, "extended" = 1, "valid" = 1) - var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec) + cost = 8 // Avoid raising traitor threat above 10, as it is the default low cost ruleset. + scaling_cost = 9 + requirements = list(101,10,10,10,10,10,10,10,10,10) + antag_cap = list("denominator" = 24) + var/autotraitor_cooldown = (15 MINUTES) + COOLDOWN_DECLARE(autotraitor_cooldown_check) -/datum/dynamic_ruleset/roundstart/traitor/pre_execute() - var/num_traitors = antag_cap[indice_pop] * (scaled_times + 1) +/datum/dynamic_ruleset/roundstart/traitor/pre_execute(population) + . = ..() + COOLDOWN_START(src, autotraitor_cooldown_check, autotraitor_cooldown) + var/num_traitors = get_antag_cap(population) * (scaled_times + 1) for (var/i = 1 to num_traitors) var/mob/M = pick_n_take(candidates) assigned += M.mind @@ -33,6 +33,12 @@ M.mind.restricted_roles = restricted_roles return TRUE +/datum/dynamic_ruleset/roundstart/traitor/rule_process() + if (COOLDOWN_FINISHED(src, autotraitor_cooldown_check)) + COOLDOWN_START(src, autotraitor_cooldown_check, autotraitor_cooldown) + log_game("DYNAMIC: Checking if we can turn someone into a traitor.") + mode.picking_specific_rule(/datum/dynamic_ruleset/midround/autotraitor) + ////////////////////////////////////////// // // // BLOOD BROTHERS // @@ -41,24 +47,22 @@ /datum/dynamic_ruleset/roundstart/traitorbro name = "Blood Brothers" - config_tag = "traitorbro" antag_flag = ROLE_BROTHER - antag_datum = /datum/antagonist/brother - restricted_roles = list("AI", "Cyborg") - protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") + antag_datum = /datum/antagonist/brother/ + protected_roles = list("Prisoner","Security Officer", "Warden", "Detective", "Head of Security", "Captain") + restricted_roles = list("Cyborg", "AI") required_candidates = 2 - flags = MINOR_RULESET weight = 4 - cost = 10 - requirements = list(101,101,101,101,101,101,101,101,101,101) - high_population_requirement = 101 - antag_cap = list(2,2,2,2,2,2,2,2,2,2) // Can pick 3 per team, but rare enough it doesn't matter. - property_weights = list("story_potential" = 1, "trust" = -1, "extended" = 1, "valid" = 1) + cost = 15 + scaling_cost = 15 + requirements = list(101,101,101,101,101,101,101,101,101,101)//disabled for now + antag_cap = 2 // Can pick 3 per team, but rare enough it doesn't matter. var/list/datum/team/brother_team/pre_brother_teams = list() var/const/min_team_size = 2 -/datum/dynamic_ruleset/roundstart/traitorbro/pre_execute() - var/num_teams = (antag_cap[indice_pop]/min_team_size) * (scaled_times + 1) // 1 team per scaling +/datum/dynamic_ruleset/roundstart/traitorbro/pre_execute(population) + . = ..() + var/num_teams = (get_antag_cap(population)/min_team_size) * (scaled_times + 1) // 1 team per scaling for(var/j = 1 to num_teams) if(candidates.len < min_team_size || candidates.len < required_candidates) break @@ -91,24 +95,20 @@ /datum/dynamic_ruleset/roundstart/changeling name = "Changelings" - config_tag = "changeling" antag_flag = ROLE_CHANGELING antag_datum = /datum/antagonist/changeling + protected_roles = list("Prisoner","Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") restricted_roles = list("AI", "Cyborg") - protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") required_candidates = 1 - flags = MINOR_RULESET weight = 3 - cost = 15 - scaling_cost = 15 - requirements = list(101,101,101,101,101,101,101,101,101,101) - property_weights = list("trust" = -2, "valid" = 2) - high_population_requirement = 10 - antag_cap = list(1,1,1,1,1,2,2,2,2,3) - var/team_mode_probability = 30 + cost = 16 + scaling_cost = 10 + requirements = list(101,60,50,40,30,20,15,10,10,10) + antag_cap = list("denominator" = 29) -/datum/dynamic_ruleset/roundstart/changeling/pre_execute() - var/num_changelings = antag_cap[indice_pop] * (scaled_times + 1) +/datum/dynamic_ruleset/roundstart/changeling/pre_execute(population) + . = ..() + var/num_changelings = get_antag_cap(population) * (scaled_times + 1) for (var/i = 1 to num_changelings) var/mob/M = pick_n_take(candidates) assigned += M.mind @@ -117,21 +117,8 @@ return TRUE /datum/dynamic_ruleset/roundstart/changeling/execute() - var/team_mode = FALSE - if(prob(team_mode_probability)) - team_mode = TRUE - var/list/team_objectives = subtypesof(/datum/objective/changeling_team_objective) - var/list/possible_team_objectives = list() - for(var/T in team_objectives) - var/datum/objective/changeling_team_objective/CTO = T - if(assigned.len >= initial(CTO.min_lings)) - possible_team_objectives += T - - if(possible_team_objectives.len && prob(20*assigned.len)) - GLOB.changeling_team_objective_type = pick(possible_team_objectives) for(var/datum/mind/changeling in assigned) var/datum/antagonist/changeling/new_antag = new antag_datum() - new_antag.team_mode = team_mode changeling.add_antag_datum(new_antag) return TRUE @@ -143,24 +130,21 @@ /datum/dynamic_ruleset/roundstart/heretics name = "Heretics" - antag_flag = "heretic" + antag_flag = ROLE_HERETIC antag_datum = /datum/antagonist/heretic - protected_roles = list("Prisoner","Security Officer", "Warden", "Detective", "Head of Security", "Captain") + protected_roles = list("Prisoner","Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") restricted_roles = list("AI", "Cyborg") required_candidates = 1 - flags = MINOR_RULESET weight = 3 - cost = 25 - scaling_cost = 15 - requirements = list(60,60,60,55,50,50,50,50,50,50) - property_weights = list("story_potential" = 1, "trust" = -1, "chaos" = 2, "extended" = -1, "valid" = 2) - antag_cap = list(1,1,1,1,2,2,2,2,3,3) - high_population_requirement = 50 + cost = 15 + scaling_cost = 9 + requirements = list(101,101,101,50,40,20,20,15,10,10)//higher because of 'round end' + antag_cap = list("denominator" = 24) -/datum/dynamic_ruleset/roundstart/heretics/pre_execute() +/datum/dynamic_ruleset/roundstart/heretics/pre_execute(population) . = ..() - var/num_ecult = antag_cap[indice_pop] * (scaled_times + 1) + var/num_ecult = get_antag_cap(population) * (scaled_times + 1) for (var/i = 1 to num_ecult) var/mob/picked_candidate = pick_n_take(candidates) @@ -175,9 +159,9 @@ var/datum/mind/cultie = c var/datum/antagonist/heretic/new_antag = new antag_datum() cultie.add_antag_datum(new_antag) - return TRUE + ////////////////////////////////////////////// // // // WIZARDS // @@ -187,18 +171,15 @@ // Dynamic is a wonderful thing that adds wizards to every round and then adds even more wizards during the round. /datum/dynamic_ruleset/roundstart/wizard name = "Wizard" - config_tag = "wizard" - persistent = TRUE antag_flag = ROLE_WIZARD antag_datum = /datum/antagonist/wizard + flags = LONE_RULESET minimum_required_age = 14 restricted_roles = list("Head of Security", "Captain") // Just to be sure that a wizard getting picked won't ever imply a Captain or HoS not getting drafted required_candidates = 1 - weight = 1 - cost = 30 - requirements = list(101,101,101,60,50,50,50,50,50,50) - high_population_requirement = 50 - property_weights = list("story_potential" = 2, "trust" = 1, "chaos" = 2, "extended" = -2, "valid" = 2) + weight = 3 + cost = 20 + requirements = list(101,101,100,60,40,20,20,20,10,10)//100 because of configt, otherwise equal to nukies var/list/roundstart_wizards = list() /datum/dynamic_ruleset/roundstart/wizard/acceptable(population=0, threat=0) @@ -209,9 +190,9 @@ return ..() /datum/dynamic_ruleset/roundstart/wizard/pre_execute() + . = ..() if(GLOB.wizardstart.len == 0) return FALSE - mode.antags_rolled += 1 var/mob/M = pick_n_take(candidates) if (M) assigned += M.mind @@ -224,25 +205,8 @@ for(var/datum/mind/M in assigned) M.current.forceMove(pick(GLOB.wizardstart)) M.add_antag_datum(new antag_datum()) - roundstart_wizards += M return TRUE -/datum/dynamic_ruleset/roundstart/wizard/rule_process() // i can literally copy this from are_special_antags_dead it's great - for(var/datum/mind/wizard in roundstart_wizards) - if(isliving(wizard.current) && wizard.current.stat!=DEAD) - return FALSE - - for(var/obj/item/phylactery/P in GLOB.poi_list) //TODO : IsProperlyDead() - if(P.mind && P.mind.has_antag_datum(/datum/antagonist/wizard)) - return FALSE - - if(SSevents.wizardmode) //If summon events was active, turn it off - SSevents.toggleWizardmode() - SSevents.resetFrequency() - - return RULESET_STOP_PROCESSING - - ////////////////////////////////////////////// // // // BLOOD CULT // @@ -251,29 +215,26 @@ /datum/dynamic_ruleset/roundstart/bloodcult name = "Blood Cult" - config_tag = "cult" antag_flag = ROLE_CULTIST antag_datum = /datum/antagonist/cult minimum_required_age = 14 - restricted_roles = list("AI", "Cyborg") - protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") + restricted_roles = list("AI", "Cyborg", "Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") required_candidates = 2 - weight = 3 - cost = 30 - requirements = list(101,101,101,80,70,60,50,50,50,50) - property_weights = list("story_potential" = -1, "trust" = -1, "chaos" = 1, "conversion" = 1, "extended" = -2, "valid" = 2) - high_population_requirement = 50 - flags = HIGHLANDER_RULESET - antag_cap = list(2,2,2,3,3,4,4,4,4,4) + weight = 2 //lower weight because of easy steamroll potential + cost = 20 + //requirements = list(100,90,80,60,40,30,10,10,10,10) + requirements = list(101,101,101,101,50,40,20,10,10,10) + flags = HIGH_IMPACT_RULESET + antag_cap = list("denominator" = 20, "offset" = 1) var/datum/team/cult/main_cult -/datum/dynamic_ruleset/roundstart/bloodcult/ready(forced = FALSE) - required_candidates = antag_cap[indice_pop] +/datum/dynamic_ruleset/roundstart/bloodcult/ready(population, forced = FALSE) + required_candidates = get_antag_cap(population) . = ..() -/datum/dynamic_ruleset/roundstart/bloodcult/pre_execute() - var/cultists = antag_cap[indice_pop] - mode.antags_rolled += cultists +/datum/dynamic_ruleset/roundstart/bloodcult/pre_execute(population) + . = ..() + var/cultists = get_antag_cap(population) for(var/cultists_number = 1 to cultists) if(candidates.len <= 0) break @@ -310,7 +271,6 @@ /datum/dynamic_ruleset/roundstart/nuclear name = "Nuclear Emergency" - config_tag = "nuclear" antag_flag = ROLE_OPERATIVE antag_datum = /datum/antagonist/nukeop var/datum/antagonist/antag_leader_datum = /datum/antagonist/nukeop/leader @@ -318,22 +278,20 @@ restricted_roles = list("Head of Security", "Captain") // Just to be sure that a nukie getting picked won't ever imply a Captain or HoS not getting drafted required_candidates = 5 weight = 3 - cost = 40 - requirements = list(100,90,80,70,60,50,50,50,50,50) - high_population_requirement = 50 - flags = HIGHLANDER_RULESET - antag_cap = list(1,1,2,3,4,5,5,5,5,5) - property_weights = list("story_potential" = 2, "trust" = 2, "chaos" = 2, "extended" = -2, "valid" = 2) + cost = 20 + requirements = list(101,101,101,60,40,30,20,15,10,10) + flags = HIGH_IMPACT_RULESET + antag_cap = list("denominator" = 18, "offset" = 1) var/datum/team/nuclear/nuke_team -/datum/dynamic_ruleset/roundstart/nuclear/ready(forced = FALSE) - required_candidates = antag_cap[indice_pop] +/datum/dynamic_ruleset/roundstart/nuclear/ready(population, forced = FALSE) + required_candidates = get_antag_cap(population) . = ..() -/datum/dynamic_ruleset/roundstart/nuclear/pre_execute() +/datum/dynamic_ruleset/roundstart/nuclear/pre_execute(population) + . = ..() // If ready() did its job, candidates should have 5 or more members in it - var/operatives = antag_cap[indice_pop] - mode.antags_rolled += operatives + var/operatives = get_antag_cap(population) for(var/operatives_number = 1 to operatives) if(candidates.len <= 0) break @@ -356,7 +314,7 @@ return TRUE /datum/dynamic_ruleset/roundstart/nuclear/round_result() - var result = nuke_team.get_result() + var/result = nuke_team.get_result() switch(result) if(NUKE_RESULT_FLUKE) SSticker.mode_result = "loss - syndicate nuked - disk secured" @@ -391,36 +349,36 @@ ////////////////////////////////////////////// // // -// REVS // +// REVS // // // ////////////////////////////////////////////// /datum/dynamic_ruleset/roundstart/revs name = "Revolution" - config_tag = "revolution" persistent = TRUE antag_flag = ROLE_REV_HEAD antag_flag_override = ROLE_REV antag_datum = /datum/antagonist/rev/head minimum_required_age = 14 - restricted_roles = list("AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") + restricted_roles = list("AI", "Cyborg", "Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director") required_candidates = 3 weight = 2 delay = 7 MINUTES - cost = 35 - requirements = list(101,101,101,60,50,50,50,50,50,50) - high_population_requirement = 50 - antag_cap = list(3,3,3,3,3,3,3,3,3,3) - flags = HIGHLANDER_RULESET + cost = 20 + requirements = list(101,101,101,101,50,40,20,10,10,10) + antag_cap = 3 + flags = HIGH_IMPACT_RULESET + blocking_rules = list(/datum/dynamic_ruleset/latejoin/provocateur) // I give up, just there should be enough heads with 35 players... minimum_players = 35 - property_weights = list("trust" = -2, "chaos" = 2, "extended" = -2, "valid" = 2, "conversion" = 1) + /// How much threat should be injected when the revolution wins? + var/revs_win_threat_injection = 20 var/datum/team/revolution/revolution var/finished = FALSE -/datum/dynamic_ruleset/roundstart/revs/pre_execute() - var/max_candidates = antag_cap[indice_pop] - mode.antags_rolled += max_candidates +/datum/dynamic_ruleset/roundstart/revs/pre_execute(population) + . = ..() + var/max_candidates = get_antag_cap(population) for(var/i = 1 to max_candidates) if(candidates.len <= 0) break @@ -431,7 +389,6 @@ return TRUE /datum/dynamic_ruleset/roundstart/revs/execute() - var/success = TRUE revolution = new() for(var/datum/mind/M in assigned) if(check_eligible(M)) @@ -443,14 +400,12 @@ else assigned -= M log_game("DYNAMIC: [ruletype] [name] discarded [M.name] from head revolutionary due to ineligibility.") - if(!revolution.members.len) - success = FALSE - log_game("DYNAMIC: [ruletype] [name] failed to get any eligible headrevs. Refunding [cost] threat.") - if(success) + if(revolution.members.len) revolution.update_objectives() revolution.update_heads() - SSshuttle.registerHostileEnvironment(src) + SSshuttle.registerHostileEnvironment(revolution) return TRUE + log_game("DYNAMIC: [ruletype] [name] failed to get any eligible headrevs. Refunding [cost] threat.") return FALSE /datum/dynamic_ruleset/roundstart/revs/clean_up() @@ -458,61 +413,118 @@ ..() /datum/dynamic_ruleset/roundstart/revs/rule_process() - if(check_rev_victory()) - finished = REVOLUTION_VICTORY - return RULESET_STOP_PROCESSING - else if (check_heads_victory()) - finished = STATION_VICTORY - SSshuttle.clearHostileEnvironment(src) - priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \ - We have remotely blacklisted the head revolutionaries from your cloning software to prevent accidental cloning.", null, "attention", null, "Central Command Loyalty Monitoring Division") + var/winner = revolution.process_victory(revs_win_threat_injection) + if (isnull(winner)) + return - for(var/datum/mind/M in revolution.members) // Remove antag datums and prevents podcloned or exiled headrevs restarting rebellions. - if(M.has_antag_datum(/datum/antagonist/rev/head)) - var/datum/antagonist/rev/head/R = M.has_antag_datum(/datum/antagonist/rev/head) - R.remove_revolutionary(FALSE, "gamemode") - var/mob/living/carbon/C = M.current - if(C.stat == DEAD) - C.makeUncloneable() - if(M.has_antag_datum(/datum/antagonist/rev)) - var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev) - R.remove_revolutionary(FALSE, "gamemode") - return RULESET_STOP_PROCESSING + finished = winner + return RULESET_STOP_PROCESSING /// Checks for revhead loss conditions and other antag datums. -/datum/dynamic_ruleset/roundstart/revs/proc/check_eligible(var/datum/mind/M) +/datum/dynamic_ruleset/roundstart/revs/proc/check_eligible(datum/mind/M) var/turf/T = get_turf(M.current) if(!considered_afk(M) && considered_alive(M) && is_station_level(T.z) && !M.antag_datums?.len && !HAS_TRAIT(M, TRAIT_MINDSHIELD)) return TRUE return FALSE -/datum/dynamic_ruleset/roundstart/revs/check_finished() - if(finished == REVOLUTION_VICTORY) - return TRUE - else - return ..() - -/datum/dynamic_ruleset/roundstart/revs/proc/check_rev_victory() - for(var/datum/objective/mutiny/objective in revolution.objectives) - if(!(objective.check_completion())) - return FALSE - return TRUE - -/datum/dynamic_ruleset/roundstart/revs/proc/check_heads_victory() - for(var/datum/mind/rev_mind in revolution.head_revolutionaries()) - var/turf/T = get_turf(rev_mind.current) - if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(T.z)) - if(ishuman(rev_mind.current) || ismonkey(rev_mind.current)) - return FALSE - return TRUE - /datum/dynamic_ruleset/roundstart/revs/round_result() - if(finished == REVOLUTION_VICTORY) - SSticker.mode_result = "win - heads killed" - SSticker.news_report = REVS_WIN - else if(finished == STATION_VICTORY) - SSticker.mode_result = "loss - rev heads killed" - SSticker.news_report = REVS_LOSE + revolution.round_result(finished) + +////////////////////////////////////////////// +// // +// Clock Cult // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/roundstart/clockcult + name = "Clock Cult" + antag_flag = ROLE_SERVANT_OF_RATVAR + antag_datum = /datum/antagonist/clockcult + minimum_required_age = 14 + restricted_roles = list("AI", "Cyborg", "Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") + required_candidates = 2 + weight = 3 //higher weight than blood cult and revs because it's more balanced + cost = 20 + requirements = list(101,101,101,101,50,40,20,10,10,10) //slightly higher than nukies + flags = HIGH_IMPACT_RULESET + antag_cap = list("denominator" = 20, "offset" = 1) + var/datum/team/clockcult/main_clockcult + +/datum/dynamic_ruleset/roundstart/clockcult/ready(population, forced = FALSE) + required_candidates = get_antag_cap(population) + . = ..() + +/datum/dynamic_ruleset/roundstart/clockcult/pre_execute(population) + . = ..() + var/cultists = get_antag_cap(population) + for(var/cultists_number = 1 to cultists) + if(candidates.len <= 0) + break + var/mob/M = pick_n_take(candidates) + assigned += M.mind + M.mind.special_role = ROLE_SERVANT_OF_RATVAR + M.mind.restricted_roles = restricted_roles + return TRUE + +/datum/dynamic_ruleset/roundstart/clockcult/execute() + main_clockcult = new + for(var/datum/mind/M in assigned) + var/datum/antagonist/clockcult/new_cultist = new antag_datum() + new_cultist.clock_team = main_clockcult + SSticker.mode.equip_servant(new_cultist) + SSticker.mode.greet_servant(new_cultist) + M.add_antag_datum(new_cultist) + return TRUE + +/datum/dynamic_ruleset/roundstart/clockcult/round_result() + ..() + if(main_clockcult.check_clockwork_victory()) + SSticker.mode_result = "win - servants completed their objective (summon ratvar)" + SSticker.news_report = CLOCK_SUMMON + else + SSticker.mode_result = "loss - servants failed their objective (summon ratvar)" + SSticker.news_report = CULT_FAILURE + +////////////////////////////////////////////// +// // +// FAMILIES // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/roundstart/families + name = "Families" + persistent = TRUE + antag_datum = /datum/antagonist/gang + antag_flag = ROLE_FAMILIES + protected_roles = list("Prisoner", "Head of Personnel") + restricted_roles = list("AI", "Cyborg", "Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain", "Head of Personnel", "Quartermaster", "Chief Engineer", "Chief Medical Officer", "Research Director") + required_candidates = 9 + weight = 3 + cost = 15 + requirements = list(101,101,101,50,30,20,10,10,10,10) + flags = HIGH_IMPACT_RULESET + /// A reference to the handler that is used to run pre_execute(), execute(), etc.. + var/datum/gang_handler/handler + +/datum/dynamic_ruleset/roundstart/families/pre_execute() + ..() + handler = new /datum/gang_handler(candidates,restricted_roles) + handler.gangs_to_generate = (antag_cap[indice_pop] / 2) + handler.gang_balance_cap = clamp((indice_pop - 3), 2, 5) // gang_balance_cap by indice_pop: (2,2,2,2,2,3,4,5,5,5) + return handler.pre_setup_analogue() + +/datum/dynamic_ruleset/roundstart/families/execute() + return handler.post_setup_analogue(TRUE) + +/datum/dynamic_ruleset/roundstart/families/clean_up() + QDEL_NULL(handler) + ..() + +/datum/dynamic_ruleset/roundstart/families/rule_process() + return handler.process_analogue() + +/datum/dynamic_ruleset/roundstart/families/round_result() + return handler.set_round_result_analogue() // Admin only rulesets. The threat requirement is 101 so it is not possible to roll them. @@ -524,7 +536,6 @@ /datum/dynamic_ruleset/roundstart/extended name = "Extended" - config_tag = "extended" antag_flag = null antag_datum = null restricted_roles = list() @@ -532,121 +543,17 @@ weight = 3 cost = 0 requirements = list(101,101,101,101,101,101,101,101,101,101) - property_weights = list("extended" = 2) - high_population_requirement = 101 + flags = LONE_RULESET /datum/dynamic_ruleset/roundstart/extended/pre_execute() + . = ..() message_admins("Starting a round of extended.") log_game("Starting a round of extended.") - mode.spend_threat(mode.threat) + mode.spend_roundstart_budget(mode.round_start_budget) + mode.spend_midround_budget(mode.mid_round_budget) + mode.threat_log += "[worldtime2text()]: Extended ruleset set threat to 0." return TRUE -////////////////////////////////////////////// -// // -// CLOCKCULT // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/roundstart/clockcult - name = "Clockcult" - config_tag = "clockwork_cult" - antag_flag = ROLE_SERVANT_OF_RATVAR - antag_datum = /datum/antagonist/clockcult - restricted_roles = list("AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") - required_candidates = 4 - weight = 3 - cost = 35 - requirements = list(101,101,101,80,70,60,50,50,50,50) - high_population_requirement = 50 - flags = HIGHLANDER_RULESET - antag_cap = list(2,3,3,4,4,4,4,4,4,4) - property_weights = list("trust" = 2, "chaos" = 2, "extended" = -2, "conversion" = 1, "valid" = 2) - var/ark_time - -/datum/dynamic_ruleset/roundstart/clockcult/pre_execute() - var/list/errorList = list() - var/list/reebes = SSmapping.LoadGroup(errorList, "Reebe", "map_files/generic", "City_of_Cogs.dmm", default_traits = ZTRAITS_REEBE, silent = TRUE) - if(errorList.len) - message_admins("Reebe failed to load!") - log_game("Reebe failed to load!") - return FALSE - for(var/datum/parsed_map/PM in reebes) - PM.initTemplateBounds() - - var/starter_servants = antag_cap[indice_pop] - var/number_players = mode.roundstart_pop_ready - if(number_players > 30) - number_players -= 30 - starter_servants += min(round(number_players / 10), 5) - mode.antags_rolled += starter_servants - GLOB.clockwork_vitality += 50 * starter_servants - for (var/i in 1 to starter_servants) - var/mob/servant = pick_n_take(candidates) - assigned += servant.mind - servant.mind.assigned_role = ROLE_SERVANT_OF_RATVAR - servant.mind.special_role = ROLE_SERVANT_OF_RATVAR - ark_time = 30 + round((number_players / 5)) - ark_time = min(ark_time, 35) - return TRUE - -/datum/dynamic_ruleset/roundstart/clockcult/execute() - var/list/spread_out_spawns = GLOB.servant_spawns.Copy() - for(var/datum/mind/servant in assigned) - var/mob/S = servant.current - if(!spread_out_spawns.len) - spread_out_spawns = GLOB.servant_spawns.Copy() - log_game("[key_name(servant)] was made an initial servant of Ratvar") - var/turf/T = pick_n_take(spread_out_spawns) - S.forceMove(T) - greet_servant(S) - equip_servant(S) - add_servant_of_ratvar(S, TRUE) - var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar //that's a mouthful - G.final_countdown(ark_time) - return TRUE - -/datum/dynamic_ruleset/roundstart/clockcult/proc/greet_servant(mob/M) //Description of their role - if(!M) - return 0 - to_chat(M, "You are a servant of Ratvar, the Clockwork Justiciar!") - to_chat(M, "You have approximately [ark_time] minutes until the Ark activates.") - to_chat(M, "Unlock Script scripture by converting a new servant.") - to_chat(M, "Application scripture will be unlocked halfway until the Ark's activation.") - M.playsound_local(get_turf(M), 'sound/ambience/antag/clockcultalr.ogg', 100, FALSE, pressure_affected = FALSE) - return 1 - -/datum/dynamic_ruleset/roundstart/clockcult/proc/equip_servant(mob/living/M) //Grants a clockwork slab to the mob, with one of each component - if(!M || !ishuman(M)) - return FALSE - var/mob/living/carbon/human/L = M - L.equipOutfit(/datum/outfit/servant_of_ratvar) - var/obj/item/clockwork/slab/S = new - var/slot = "At your feet" - var/list/slots = list("In your left pocket" = SLOT_L_STORE, "In your right pocket" = SLOT_R_STORE, "In your backpack" = SLOT_IN_BACKPACK, "On your belt" = SLOT_BELT) - if(ishuman(L)) - var/mob/living/carbon/human/H = L - slot = H.equip_in_one_of_slots(S, slots) - if(slot == "In your backpack") - slot = "In your [H.back.name]" - if(slot == "At your feet") - if(!S.forceMove(get_turf(L))) - qdel(S) - if(S && !QDELETED(S)) - to_chat(L, "There is a paper in your backpack! It'll tell you if anything's changed, as well as what to expect.") - to_chat(L, "[slot] is a clockwork slab, a multipurpose tool used to construct machines and invoke ancient words of power. If this is your first time \ - as a servant, you can find a concise tutorial in the Recollection category of its interface.") - to_chat(L, "If you want more information, you can read the wiki page to learn more.") - return TRUE - return FALSE - -/datum/dynamic_ruleset/roundstart/clockcult/round_result() - if(GLOB.clockwork_gateway_activated) - SSticker.news_report = CLOCK_SUMMON - SSticker.mode_result = "win - servants completed their objective (summon ratvar)" - else - SSticker.news_report = CULT_FAILURE - SSticker.mode_result = "loss - servants failed their objective (summon ratvar)" - ////////////////////////////////////////////// // // // CLOWN OPS // @@ -655,12 +562,10 @@ /datum/dynamic_ruleset/roundstart/nuclear/clown_ops name = "Clown Ops" - config_tag = "clownops" + antag_flag = "clown ops" antag_datum = /datum/antagonist/nukeop/clownop antag_leader_datum = /datum/antagonist/nukeop/leader/clownop - weight = 1 - property_weights = list("trust" = 2, "chaos" = 2, "extended" = -2, "story_potential" = 2, "valid" = 2) - + requirements = list(101,101,101,101,101,101,101,101,101,101) /datum/dynamic_ruleset/roundstart/nuclear/clown_ops/pre_execute() . = ..() @@ -674,59 +579,6 @@ V.assigned_role = "Clown Operative" V.special_role = "Clown Operative" -////////////////////////////////////////////// -// // -// DEVIL // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/roundstart/devil - name = "Devil" - config_tag = "devil" - antag_flag = ROLE_DEVIL - antag_datum = /datum/antagonist/devil - restricted_roles = list("Lawyer", "Curator", "Chaplain", "Head of Security", "Captain", "AI") - required_candidates = 1 - flags = MINOR_RULESET - weight = 3 - cost = 0 - requirements = list(101,101,101,101,101,101,101,101,101,101) - high_population_requirement = 101 - antag_cap = list(1,1,1,2,2,2,3,3,3,4) - property_weights = list("extended" = 1) - -/datum/dynamic_ruleset/roundstart/devil/pre_execute() - var/num_devils = antag_cap[indice_pop] - mode.antags_rolled += num_devils - for(var/j = 0, j < num_devils, j++) - if (!candidates.len) - break - var/mob/devil = pick_n_take(candidates) - assigned += devil.mind - devil.mind.special_role = ROLE_DEVIL - devil.mind.restricted_roles = restricted_roles - - log_game("[key_name(devil)] has been selected as a devil") - return TRUE - -/datum/dynamic_ruleset/roundstart/devil/execute() - for(var/datum/mind/devil in assigned) - add_devil(devil.current, ascendable = TRUE) - add_devil_objectives(devil,2) - return TRUE - -/datum/dynamic_ruleset/roundstart/devil/proc/add_devil_objectives(datum/mind/devil_mind, quantity) - var/list/validtypes = list(/datum/objective/devil/soulquantity, /datum/objective/devil/soulquality, /datum/objective/devil/sintouch, /datum/objective/devil/buy_target) - var/datum/antagonist/devil/D = devil_mind.has_antag_datum(/datum/antagonist/devil) - for(var/i = 1 to quantity) - var/type = pick(validtypes) - var/datum/objective/devil/objective = new type(null) - objective.owner = devil_mind - D.objectives += objective - if(!istype(objective, /datum/objective/devil/buy_target)) - validtypes -= type - else - objective.find_target() ////////////////////////////////////////////// // // @@ -736,24 +588,22 @@ /datum/dynamic_ruleset/roundstart/monkey name = "Monkey" - config_tag = "monkey" antag_flag = ROLE_MONKEY antag_datum = /datum/antagonist/monkey/leader - restricted_roles = list("Cyborg", "AI") + restricted_roles = list("Cyborg", "AI", "Prisoner") required_candidates = 1 weight = 3 cost = 0 requirements = list(101,101,101,101,101,101,101,101,101,101) - high_population_requirement = 101 - property_weights = list("extended" = -2, "chaos" = 2, "conversion" = 1, "valid" = 2) + flags = LONE_RULESET var/players_per_carrier = 30 var/monkeys_to_win = 1 var/escaped_monkeys = 0 var/datum/team/monkey/monkey_team /datum/dynamic_ruleset/roundstart/monkey/pre_execute() + . = ..() var/carriers_to_make = max(round(mode.roundstart_pop_ready / players_per_carrier, 1), 1) - mode.antags_rolled += carriers_to_make for(var/j = 0, j < carriers_to_make, j++) if (!candidates.len) @@ -767,7 +617,7 @@ /datum/dynamic_ruleset/roundstart/monkey/execute() for(var/datum/mind/carrier in assigned) - var/datum/antagonist/monkey/M = add_monkey_leader(carrier) + var/datum/antagonist/monkey/M = carrier.add_antag_datum(/datum/antagonist/monkey/leader) if(M) monkey_team = M.monkey_team return TRUE @@ -776,7 +626,9 @@ if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME) return FALSE var/datum/disease/D = new /datum/disease/transformation/jungle_fever() - for(var/mob/living/carbon/monkey/M in GLOB.alive_mob_list) + for(var/mob/living/carbon/human/M in GLOB.alive_mob_list) + if(!ismonkey(M)) + continue if (M.HasDisease(D)) if(M.onCentCom() || M.onSyndieBase()) escaped_monkeys++ @@ -800,16 +652,14 @@ /datum/dynamic_ruleset/roundstart/meteor name = "Meteor" - config_tag = "meteor" persistent = TRUE required_candidates = 0 weight = 3 cost = 0 requirements = list(101,101,101,101,101,101,101,101,101,101) - high_population_requirement = 101 - property_weights = list("extended" = -2, "chaos" = 2, "trust" = 2) + flags = LONE_RULESET var/meteordelay = 2000 - var/nometeors = 0 + var/nometeors = FALSE var/rampupdelta = 5 /datum/dynamic_ruleset/roundstart/meteor/rule_process() @@ -828,43 +678,3 @@ var/ramp_up_final = clamp(round(meteorminutes/rampupdelta), 1, 10) spawn_meteors(ramp_up_final, wavetype) - -////////////////////////////////////////////// -// // -// BLOODSUCKERS // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/roundstart/bloodsucker - name = "Bloodsuckers" - config_tag = "bloodsucker" - antag_flag = ROLE_BLOODSUCKER - antag_datum = ANTAG_DATUM_BLOODSUCKER - minimum_required_age = 0 - protected_roles = list("Chaplain", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") - restricted_roles = list("Cyborg", "AI") - required_candidates = 1 - flags = MINOR_RULESET - weight = 2 - cost = 15 - scaling_cost = 10 - property_weights = list("story_potential" = 1, "extended" = 1, "trust" = -2, "valid" = 1) - requirements = list(70,65,60,55,50,50,50,50,50,50) - high_population_requirement = 50 - antag_cap = list(1,1,1,1,1,2,2,2,2,2) - -/datum/dynamic_ruleset/roundstart/bloodsucker/pre_execute() - var/num_bloodsuckers = antag_cap[indice_pop] * (scaled_times + 1) - for (var/i = 1 to num_bloodsuckers) - var/mob/M = pick_n_take(candidates) - assigned += M.mind - M.mind.special_role = ROLE_BLOODSUCKER - M.mind.restricted_roles = restricted_roles - return TRUE - -/datum/dynamic_ruleset/roundstart/bloodsucker/execute() - mode.check_start_sunlight() - for(var/datum/mind/M in assigned) - if(mode.make_bloodsucker(M)) - mode.bloodsuckers += M - return TRUE diff --git a/code/game/gamemodes/dynamic/dynamic_simulations.dm b/code/game/gamemodes/dynamic/dynamic_simulations.dm new file mode 100644 index 0000000000..63da54bece --- /dev/null +++ b/code/game/gamemodes/dynamic/dynamic_simulations.dm @@ -0,0 +1,122 @@ +#ifdef TESTING +/datum/dynamic_simulation + var/datum/game_mode/dynamic/gamemode + var/datum/dynamic_simulation_config/config + var/list/mock_candidates = list() + +/datum/dynamic_simulation/proc/initialize_gamemode(forced_threat) + gamemode = new + + if (forced_threat) + gamemode.create_threat(forced_threat) + else + gamemode.generate_threat() + + gamemode.generate_budgets() + gamemode.set_cooldowns() + +/datum/dynamic_simulation/proc/create_candidates(players) + GLOB.new_player_list.Cut() + + for (var/_ in 1 to players) + var/mob/dead/new_player/mock_new_player = new + mock_new_player.ready = PLAYER_READY_TO_PLAY + + var/datum/mind/mock_mind = new + mock_new_player.mind = mock_mind + + var/datum/client_interface/mock_client = new + + var/datum/preferences/prefs = new + var/list/be_special = list() + for (var/special_role in GLOB.special_roles) + be_special += special_role + + prefs.be_special = be_special + mock_client.prefs = prefs + + mock_new_player.mock_client = mock_client + + mock_candidates += mock_new_player + +/datum/dynamic_simulation/proc/simulate(datum/dynamic_simulation_config/config) + src.config = config + + initialize_gamemode(config.forced_threat_level) + create_candidates(config.roundstart_players) + gamemode.pre_setup() + + var/total_antags = 0 + for (var/_ruleset in gamemode.executed_rules) + var/datum/dynamic_ruleset/ruleset = _ruleset + total_antags += ruleset.assigned.len + + return list( + "roundstart_players" = config.roundstart_players, + "threat_level" = gamemode.threat_level, + "snapshot" = list( + "antag_percent" = total_antags / config.roundstart_players, + "remaining_threat" = gamemode.mid_round_budget, + "rulesets" = gamemode.executed_rules.Copy(), + ), + ) + +/datum/dynamic_simulation_config + /// How many players round start should there be? + var/roundstart_players + + /// Optional, force this threat level instead of picking randomly through the lorentz distribution + var/forced_threat_level + +/client/proc/run_dynamic_simulations() + set name = "Run Dynamic Simulations" + set category = "Debug" + + var/simulations = input(usr, "Enter number of simulations") as num + var/roundstart_players = input(usr, "Enter number of round start players") as num + var/forced_threat_level = input(usr, "Enter forced threat level, if you want one") as num | null + + SSticker.mode = new /datum/game_mode/dynamic + message_admins("Running dynamic simulations...") + + var/list/outputs = list() + + var/datum/dynamic_simulation_config/dynamic_config = new + + if (roundstart_players) + dynamic_config.roundstart_players = roundstart_players + + if (forced_threat_level) + dynamic_config.forced_threat_level = forced_threat_level + + for (var/count in 1 to simulations) + var/datum/dynamic_simulation/simulator = new + var/output = simulator.simulate(dynamic_config) + outputs += list(output) + + if (CHECK_TICK) + log_world("[count]/[simulations]") + + message_admins("Writing file...") + WRITE_FILE(file("[GLOB.log_directory]/dynamic_simulations.json"), json_encode(outputs)) + message_admins("Writing complete.") + +/proc/export_dynamic_json_of(ruleset_list) + var/list/export = list() + + for (var/_ruleset in ruleset_list) + var/datum/dynamic_ruleset/ruleset = _ruleset + export[ruleset.name] = list( + "repeatable_weight_decrease" = ruleset.repeatable_weight_decrease, + "weight" = ruleset.weight, + "cost" = ruleset.cost, + "scaling_cost" = ruleset.scaling_cost, + "antag_cap" = ruleset.antag_cap, + "pop_per_requirement" = ruleset.pop_per_requirement, + "requirements" = ruleset.requirements, + "base_prob" = ruleset.base_prob, + ) + + return export + +#endif diff --git a/code/game/gamemodes/dynamic/dynamic_storytellers.dm b/code/game/gamemodes/dynamic/dynamic_storytellers.dm deleted file mode 100644 index 927ab7796b..0000000000 --- a/code/game/gamemodes/dynamic/dynamic_storytellers.dm +++ /dev/null @@ -1,388 +0,0 @@ -/datum/dynamic_storyteller - var/name = "none" // Name for voting. - var/config_tag = null // Config tag for config weights. - var/desc = "A coder's idiocy." // Description for voting. - var/list/property_weights = list() // See below. - var/curve_centre = 0 // As GLOB.dynamic_curve_centre. - var/curve_width = 1.8 // As GLOB.dynamic_curve_width. - var/forced_threat_level = -1 // As GLOB.dynamic_forced_threat_level - /* - NO_ASSASSIN: Will not have permanent assassination targets. - WAROPS_ALWAYS_ALLOWED: Can always do warops, regardless of threat level. - USE_PREF_WEIGHTS: Will use peoples' preferences to change the threat centre. - FORCE_IF_WON: If this mode won the vote, forces it - USE_PREV_ROUND_WEIGHTS: Changes its threat centre based on the average chaos of previous rounds. - */ - var/flags = 0 - var/dead_player_weight = 1 // How much dead players matter for threat calculation - var/weight = 0 // Weights for randomly picking storyteller. Multiplied by score after voting. - var/min_chaos = -1000 // Won't show up if recent rounds have been below this chaotic on average - var/max_chaos = 1000 // Won't show up if recent rounds have been above this chaotic on average - var/event_frequency_lower = 6 MINUTES // How rare events will be, at least. - var/event_frequency_upper = 20 MINUTES // How rare events will be, at most. - var/min_players = -1 // How many players are required for this one to start. - var/soft_antag_ratio_cap = 4 // how many players-per-antag there should be - var/datum/game_mode/dynamic/mode = null // Cached as soon as it's made, by dynamic. - -/** -Property weights are added to the config weight of the ruleset. They are: -"story_potential" -- essentially how many different ways the antag can be played. -"trust" -- How much it makes the crew trust each other. Negative values means they're suspicious. Team antags are like this. -"chaos" -- How chaotic it makes the round. Has some overlap with "valid" and somewhat contradicts "extended". -"valid" -- How likely the non-antag-enemy crew are to get involved, e.g. nukies encouraging the warden to - let everyone into the armory, wizard moving around and being a nuisance, nightmare busting lights. -"extended" -- How much the antag is conducive to a long round. Nukies and cults are bad for this; Wizard is less bad; and so on. -"conversion" -- Basically a bool. Conversion antags, well, convert. It's in its own class 'cause people kinda hate conversion. -*/ - -/datum/dynamic_storyteller/proc/minor_start_chance() - return clamp(60 - mode.threat_level,0,100) // by default higher threat = lower chance of minor round - -/datum/dynamic_storyteller/proc/start_injection_cooldowns() - var/latejoin_injection_cooldown_middle = 0.5*(GLOB.dynamic_first_latejoin_delay_max + GLOB.dynamic_first_latejoin_delay_min) - mode.latejoin_injection_cooldown = round(clamp(EXP_DISTRIBUTION(latejoin_injection_cooldown_middle), GLOB.dynamic_first_latejoin_delay_min, GLOB.dynamic_first_latejoin_delay_max)) + world.time - - var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_first_midround_delay_min + GLOB.dynamic_first_midround_delay_max) - mode.midround_injection_cooldown = round(clamp(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_first_midround_delay_min, GLOB.dynamic_first_midround_delay_max)) + world.time - -/datum/dynamic_storyteller/proc/do_process() - return - -/datum/dynamic_storyteller/proc/on_start() - if (istype(SSticker.mode, /datum/game_mode/dynamic)) - mode = SSticker.mode - GLOB.dynamic_curve_centre = curve_centre - GLOB.dynamic_curve_width = curve_width - if(flags & USE_PREF_WEIGHTS) - var/voters = 0 - var/mean = 0 - for(var/client/c in GLOB.clients) - var/vote = c.prefs.preferred_chaos - if(vote) - voters += 1 - switch(vote) - if(CHAOS_NONE) - mean -= 5 - if(CHAOS_LOW) - mean -= 2.5 - if(CHAOS_HIGH) - mean += 2.5 - if(CHAOS_MAX) - mean += 5 - else - voters += 0.5 - if(voters) - GLOB.dynamic_curve_centre += (mean/voters) - if(flags & USE_PREV_ROUND_WEIGHTS) - GLOB.dynamic_curve_centre += (SSpersistence.average_threat) / 10 - GLOB.dynamic_forced_threat_level = forced_threat_level - -/datum/dynamic_storyteller/proc/get_midround_cooldown() - var/midround_injection_cooldown_middle = 0.5*(GLOB.dynamic_midround_delay_max + GLOB.dynamic_midround_delay_min) - return round(clamp(EXP_DISTRIBUTION(midround_injection_cooldown_middle), GLOB.dynamic_midround_delay_min, GLOB.dynamic_midround_delay_max)) - -/datum/dynamic_storyteller/proc/should_inject_antag(dry_run = FALSE) - if(mode.forced_injection) - mode.forced_injection = dry_run - return TRUE - if(mode.current_players[CURRENT_LIVING_PLAYERS].len < (mode.current_players[CURRENT_LIVING_ANTAGS].len * soft_antag_ratio_cap)) - return FALSE - return mode.threat < mode.threat_level - -/datum/dynamic_storyteller/proc/roundstart_draft() - var/list/drafted_rules = list() - var/minor_round_weight_mult = (100-minor_start_chance()) / 100 - for (var/datum/dynamic_ruleset/roundstart/rule in mode.roundstart_rules) - if (rule.acceptable(mode.roundstart_pop_ready, mode.threat_level)) // If we got the population and threat required - rule.candidates = mode.candidates.Copy() - rule.trim_candidates() - if (rule.ready() && rule.candidates.len > 0) - var/property_weight = 0 - for(var/property in property_weights) - if(property in rule.property_weights) // just treat it as 0 if it's not in there - property_weight += rule.property_weights[property] * property_weights[property] - var/calced_weight = (rule.get_weight() + property_weight) * rule.weight_mult - if(CHECK_BITFIELD(rule.flags, MINOR_RULESET)) - calced_weight *= minor_round_weight_mult - if(calced_weight > 0) // negatives in the list might cause problems - drafted_rules[rule] = calced_weight - return drafted_rules - -/datum/dynamic_storyteller/proc/minor_rule_draft() - var/list/drafted_rules = list() - for (var/datum/dynamic_ruleset/rule in mode.minor_rules) - if (rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level)) - rule.trim_candidates() - if (rule.ready()) - var/property_weight = 0 - for(var/property in property_weights) - if(property in rule.property_weights) // just treat it as 0 if it's not in there - property_weight += rule.property_weights[property] * property_weights[property] - var/calced_weight = (rule.get_weight() + property_weight) * rule.weight_mult - if(calced_weight > 0) // negatives in the list might cause problems - drafted_rules[rule] = calced_weight - return drafted_rules - -/datum/dynamic_storyteller/proc/midround_draft() - var/list/drafted_rules = list() - for (var/datum/dynamic_ruleset/midround/rule in mode.midround_rules) - // if there are antags OR the rule is an antag rule, antag_acceptable will be true. - if (rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level)) - // Classic secret : only autotraitor/minor roles - if (GLOB.dynamic_classic_secret && !((rule.flags & TRAITOR_RULESET))) - continue - rule.trim_candidates() - if (rule.ready()) - var/property_weight = 0 - for(var/property in property_weights) - if(property in rule.property_weights) // just treat it as 0 if it's not in there - property_weight += rule.property_weights[property] * property_weights[property] - var/threat_weight = 1 - if(!(rule.flags & TRAITOR_RULESET)) // makes the traitor rulesets always possible anyway - var/cost_difference = rule.cost-(mode.threat_level-mode.threat) - /* Basically, the closer the cost is to the current threat-level-away-from-threat, the more likely it is to - pick this particular ruleset. - Let's use a toy example: there's 60 threat level and 10 threat spent. - We want to pick a ruleset that's close to that, so we run the below equation, on two rulesets. - Ruleset 1 has 30 cost, ruleset 2 has 5 cost. - When we do the math, ruleset 1's threat_weight is 0.538, and ruleset 2's is 0.238, meaning ruleset 1 - is 2.26 times as likely to be picked, all other things considered. - Of course, we don't want it to GUARANTEE the closest, that's no fun, so it's just a weight. - */ - threat_weight = abs(1-abs(1-LOGISTIC_FUNCTION(2,0.05,abs(cost_difference),0))) - if(cost_difference > 0) - threat_weight /= (1+(cost_difference*0.1)) - var/calced_weight = (rule.get_weight() + property_weight) * rule.weight_mult * threat_weight - if(calced_weight > 0) - drafted_rules[rule] = calced_weight - return drafted_rules - -/datum/dynamic_storyteller/proc/latejoin_draft(mob/living/carbon/human/newPlayer) - var/list/drafted_rules = list() - for (var/datum/dynamic_ruleset/latejoin/rule in mode.latejoin_rules) - if (rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level - mode.threat)) - // Classic secret : only autotraitor/minor roles - if (GLOB.dynamic_classic_secret && !((rule.flags & TRAITOR_RULESET))) - continue - // No stacking : only one round-ender, unless threat level > stacking_limit. - if (mode.threat_level > GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) - if(rule.flags & HIGHLANDER_RULESET && mode.highlander_executed) - continue - - rule.candidates = list(newPlayer) - rule.trim_candidates() - if (rule.ready()) - var/property_weight = 0 - for(var/property in property_weights) - if(property in rule.property_weights) - property_weight += rule.property_weights[property] * property_weights[property] - var/threat_weight = 1 - if(!(rule.flags & TRAITOR_RULESET)) - var/cost_difference = rule.cost-(mode.threat_level-mode.threat) - threat_weight = 1-abs(1-(LOGISTIC_FUNCTION(2,0.05,abs(cost_difference),0))) - if(cost_difference > 0) - threat_weight /= (1+(cost_difference*0.1)) - var/calced_weight = (rule.get_weight() + property_weight) * rule.weight_mult * threat_weight - if(calced_weight > 0) - drafted_rules[rule] = calced_weight - return drafted_rules - -/datum/dynamic_storyteller/chaotic - name = "Chaotic" - config_tag = "chaotic" - curve_centre = 10 - desc = "High chaos modes. Revs, wizard, clock cult. Multiple antags at once. Chaos is kept up all round." - property_weights = list("extended" = -1, "chaos" = 1) - weight = 1 - event_frequency_lower = 2 MINUTES - event_frequency_upper = 10 MINUTES - max_chaos = 50 - soft_antag_ratio_cap = 1 - flags = WAROPS_ALWAYS_ALLOWED | FORCE_IF_WON - min_players = 30 - var/refund_cooldown = 0 - -/datum/dynamic_storyteller/chaotic/minor_start_chance() - return 0 - -/datum/dynamic_storyteller/chaotic/do_process() - if(refund_cooldown < world.time) - mode.create_threat(20) - mode.log_threat("Chaotic storyteller ramped up the chaos. Threat level is now [mode.threat_level].") - refund_cooldown = world.time + 20 MINUTES - -/datum/dynamic_storyteller/chaotic/get_midround_cooldown() - return ..() / 4 - -/datum/dynamic_storyteller/team - name = "Teamwork" - config_tag = "teamwork" - desc = "Modes where the crew must band together. Nukies, xenos, blob. Only one antag threat at once." - curve_centre = 2 - curve_width = 1.5 - weight = 4 - max_chaos = 75 - min_players = 20 - flags = WAROPS_ALWAYS_ALLOWED | USE_PREV_ROUND_WEIGHTS - property_weights = list("valid" = 3, "trust" = 5) - -/datum/dynamic_storyteller/team/minor_start_chance() - return 0 - -/datum/dynamic_storyteller/team/should_inject_antag(dry_run = FALSE) - return (mode.current_players[CURRENT_LIVING_ANTAGS].len ? FALSE : ..()) - -/datum/dynamic_storyteller/conversion - name = "Conversion" - config_tag = "conversion" - desc = "Conversion antags. Cults, revs." - curve_centre = 3 - curve_width = 1 - weight = 0 - flags = WAROPS_ALWAYS_ALLOWED - property_weights = list("valid" = 1, "conversion" = 20) - -/datum/dynamic_storyteller/conversion/minor_start_chance() - return 0 - -/datum/dynamic_storyteller/random - name = "Random" - config_tag = "random" - weight = 1 - max_chaos = 60 - soft_antag_ratio_cap = 1 - desc = "No weighting at all; every ruleset has the same chance of happening. Cooldowns vary wildly. As random as it gets." - -/datum/dynamic_storyteller/random/on_start() - ..() - GLOB.dynamic_forced_threat_level = rand(0,100) - -/datum/dynamic_storyteller/random/get_midround_cooldown() - return rand(GLOB.dynamic_midround_delay_min/2, GLOB.dynamic_midround_delay_max*2) - -/datum/dynamic_storyteller/random/should_inject_antag() - return prob(50) - -/datum/dynamic_storyteller/random/minor_start_chance() - return 20 - -/datum/dynamic_storyteller/random/roundstart_draft() - var/list/drafted_rules = list() - for (var/datum/dynamic_ruleset/roundstart/rule in mode.roundstart_rules) - if (rule.acceptable(mode.roundstart_pop_ready, mode.threat_level)) // If we got the population and threat required - rule.candidates = mode.candidates.Copy() - rule.trim_candidates() - if (rule.ready() && rule.candidates.len > 0) - drafted_rules[rule] = 1 - return drafted_rules - -/datum/dynamic_storyteller/random/minor_rule_draft() - var/list/drafted_rules = list() - for (var/datum/dynamic_ruleset/minor/rule in mode.minor_rules) - if (rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level)) - rule.candidates = mode.candidates.Copy() - rule.trim_candidates() - if (rule.ready() && rule.candidates.len > 0) - drafted_rules[rule] = 1 - return drafted_rules - -/datum/dynamic_storyteller/random/midround_draft() - var/list/drafted_rules = list() - for (var/datum/dynamic_ruleset/midround/rule in mode.midround_rules) - if (rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level)) - // Classic secret : only autotraitor/minor roles - if (GLOB.dynamic_classic_secret && !((rule.flags & TRAITOR_RULESET))) - continue - rule.trim_candidates() - if (rule.ready()) - drafted_rules[rule] = 1 - return drafted_rules - -/datum/dynamic_storyteller/random/latejoin_draft(mob/living/carbon/human/newPlayer) - var/list/drafted_rules = list() - for (var/datum/dynamic_ruleset/latejoin/rule in mode.latejoin_rules) - if (rule.acceptable(mode.current_players[CURRENT_LIVING_PLAYERS].len, mode.threat_level)) - // Classic secret : only autotraitor/minor roles - if (GLOB.dynamic_classic_secret && !((rule.flags & TRAITOR_RULESET))) - continue - // No stacking : only one round-ender, unless threat level > stacking_limit. - if (mode.threat_level > GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking) - if(rule.flags & HIGHLANDER_RULESET && mode.highlander_executed) - continue - rule.candidates = list(newPlayer) - rule.trim_candidates() - if (rule.ready()) - drafted_rules[rule] = 1 - return drafted_rules - -/datum/dynamic_storyteller/story - name = "Story" - config_tag = "story" - desc = "Antags with options for loadouts and gimmicks. Traitor, wizard, nukies." - weight = 4 - curve_width = 2 - flags = USE_PREV_ROUND_WEIGHTS - property_weights = list("story_potential" = 2) - -/datum/dynamic_storyteller/classic - name = "Classic" - config_tag = "classic" - weight = 8 - desc = "No special antagonist weights. Good variety, but not like random. Uses your chaos preference to weight." - flags = USE_PREF_WEIGHTS | USE_PREV_ROUND_WEIGHTS - -/datum/dynamic_storyteller/suspicion - name = "Intrigue" - config_tag = "intrigue" - desc = "Antags that instill distrust in the crew. Traitors, bloodsuckers." - weight = 4 - curve_width = 2 - dead_player_weight = 2 - flags = USE_PREV_ROUND_WEIGHTS - property_weights = list("trust" = -2) - -/datum/dynamic_storyteller/intrigue/minor_start_chance() - return 100 - mode.threat_level - -/datum/dynamic_storyteller/grabbag - name = "Grab Bag" - config_tag = "grabbag" - desc = "Crew antags (e.g. traitor, changeling, bloodsucker, heretic) only at round start, all mixed together." - weight = 4 - flags = USE_PREF_WEIGHTS | USE_PREV_ROUND_WEIGHTS - -/datum/dynamic_storyteller/grabbag/minor_start_chance() - return 100 - -/datum/dynamic_storyteller/liteextended - name = "Calm" - config_tag = "calm" - desc = "Low-chaos round. Few antags. No conversion." - curve_centre = -3 - curve_width = 0.5 - flags = NO_ASSASSIN - min_chaos = 30 - weight = 3 - dead_player_weight = 5 - soft_antag_ratio_cap = 8 - property_weights = list("extended" = 2, "chaos" = -1, "valid" = -1, "conversion" = -10) - -/datum/dynamic_storyteller/liteextended/minor_start_chance() - return 90 - -/datum/dynamic_storyteller/no_antag - name = "Extended" - config_tag = "semiextended" - desc = "No standard antags." - curve_centre = -5 - curve_width = 0.5 - min_chaos = 40 - flags = NO_ASSASSIN | FORCE_IF_WON - weight = 1 - property_weights = list("extended" = 2) - -/datum/dynamic_storyteller/no_antag/roundstart_draft() - return list() - -/datum/dynamic_storyteller/no_antag/should_inject_antag(dry_run) - return FALSE diff --git a/code/game/gamemodes/dynamic/readme.md b/code/game/gamemodes/dynamic/readme.md index a98a02a8dd..3a8d41f230 100644 --- a/code/game/gamemodes/dynamic/readme.md +++ b/code/game/gamemodes/dynamic/readme.md @@ -1,56 +1,184 @@ -# DYNAMIC +# Dynamic Mode -Tries to keep the round at a certain level of action, based on the round's "threat level". - -## ROUNDSTART +## Roundstart Dynamic rolls threat based on a special sauce formula: -"dynamic_curve_width \* tan((rand() - 0.5) \* 180) + dynamic_curve_centre" -Midround injection cooldowns are set using exponential distribution between 15 minutes and 35 minutes. This value is then added to world.time and assigned to the injection cooldown variables. +> [dynamic_curve_width][/datum/controller/global_vars/var/dynamic_curve_width] \* tan((3.1416 \* (rand() - 0.5) \* 57.2957795)) + [dynamic_curve_centre][/datum/controller/global_vars/var/dynamic_curve_centre] -Latejoins are aggressively assigned whenever possible, to keep the round at a certain threat level. +This threat is split into two separate budgets--`round_start_budget` and `mid_round_budget`. For example, a round with 50 threat might be split into a 30 roundstart budget, and a 20 midround budget. The roundstart budget is used to apply antagonists applied on readied players when the roundstarts (`/datum/dynamic_ruleset/roundstart`). The midround budget is used for two types of rulesets: +- `/datum/dynamic_ruleset/midround` - Rulesets that apply to either existing alive players, or to ghosts. Think Blob or Space Ninja, which poll ghosts asking if they want to play as these roles. +- `/datum/dynamic_ruleset/latejoin` - Rulesets that apply to the next player that joins. Think Syndicate Infiltrator, which converts a player just joining an existing round into traitor. -rigged_roundstart() is called instead if there are forced rules (an admin set the mode) +This split is done with a similar method, known as the ["lorentz distribution"](https://en.wikipedia.org/wiki/Cauchy_distribution), exists to create a bell curve that ensures that while most rounds will have a threat level around ~50, chaotic and tame rounds still exist for variety. -can_start() -> pre_setup() -> roundstart() OR rigged_roundstart() -> picking_roundstart_rule(drafted_rules) -> post_setup() +The process of creating these numbers occurs in `/datum/game_mode/dynamic/proc/generate_threat` (for creating the threat level) and `/datum/game_mode/dynamic/proc/generate_budgets` (for splitting the threat level into budgets). -## PROCESS +## Deciding roundstart threats +In `/datum/game_mode/dynamic/proc/roundstart()` (called when no admin chooses the rulesets explicitly), Dynamic uses the available roundstart budget to pick threats. This is done through the following system: -Calls rule_process on every rule which is in the current_rules list. +- All roundstart rulesets (remember, `/datum/dynamic_ruleset/roundstart`) are put into an associative list with their weight as the values (`drafted_rules`). +- Until there is either no roundstart budget left, or until there is no ruleset we can choose from with the available threat, a `pickweight` is done based on the drafted_rules. If the same threat is picked twice, it will "scale up". The meaning of this depends on the ruleset itself, using the `scaled_times` variable; traitors for instance will create more the higher they scale. + - If a ruleset is chosen with the `HIGH_IMPACT_RULESET` in its `flags`, then all other `HIGH_IMPACT_RULESET`s will be removed from `drafted_rules`. This is so that only one can ever be chosen. + - If a ruleset has `LONE_RULESET` in its `flags`, then it will be removed from `drafted_rules`. This is to ensure it will only ever be picked once. An example of this in use is Wizard, to avoid creating multiple wizards. +- After all roundstart threats are chosen, `/datum/dynamic_ruleset/proc/picking_roundstart_rule` is called for each, passing in the ruleset and the number of times it is scaled. + - In this stage, `pre_execute` is called, which is the function that will determine what players get what antagonists. If this function returns FALSE for whatever reason (in the case of an error), then its threat is refunded. + +After this process is done, any leftover roundstart threat will be given to the existing midround budget (done in `/datum/game_mode/dynamic/pre_setup()`). + +## Deciding midround threats + +Latejoin and midround injection cooldowns are set using exponential distribution between + +- 5 minutes and 25 for latejoin (configurable as latejoin_delay_min and latejoin_delay_max) +- 15 minutes and 35 for midround (configurable as midround_delay_min and midround_delay_max) + +this value is then added to `world.time` and assigned to the injection cooldown variables. + +[rigged_roundstart][/datum/game_mode/dynamic/proc/rigged_roundstart] is called instead if there are forced rules (an admin set the mode) + +1. [setup_parameters][/datum/game_mode/proc/setup_parameters]\() +2. [pre_setup][/datum/game_mode/proc/pre_setup]\() +3. [roundstart][/datum/game_mode/dynamic/proc/roundstart]\() OR [rigged_roundstart][/datum/game_mode/dynamic/proc/rigged_roundstart]\() +4. [picking_roundstart_rule][/datum/game_mode/dynamic/proc/picking_roundstart_rule]\(drafted_rules) +5. [post_setup][/datum/game_mode/proc/post_setup]\() + +## Rule Processing + +Calls [rule_process][/datum/dynamic_ruleset/proc/rule_process] on every rule which is in the current_rules list. Every sixty seconds, update_playercounts() Midround injection time is checked against world.time to see if an injection should happen. If midround injection time is lower than world.time, it updates playercounts again, then tries to inject and generates a new cooldown regardless of whether a rule is picked. -## LATEJOIN +## Latejoin -make_antag_chance(newPlayer) -> [For each latespawn rule...] +make_antag_chance(newPlayer) -> (For each latespawn rule...) -> acceptable(living players, threat_level) -> trim_candidates() -> ready(forced=FALSE) **If true, add to drafted rules +**NOTE that acceptable uses threat_level not threat! +**NOTE Latejoin timer is ONLY reset if at least one rule was drafted. **NOTE the new_player.dm AttemptLateSpawn() calls OnPostSetup for all roles (unless assigned role is MODE) -[After collecting all draftble rules...] + +(After collecting all draftble rules...) -> picking_latejoin_ruleset(drafted_rules) -> spend threat -> ruleset.execute() -## MIDROUND -process() -> [For each midround rule...] + +## Midround + +process() -> (For each midround rule... -> acceptable(living players, threat_level) -> trim_candidates() -> ready(forced=FALSE) -[After collecting all draftble rules...] +(After collecting all draftble rules...) -> picking_midround_ruleset(drafted_rules) -> spend threat -> ruleset.execute() -## FORCED + +## Forced + For latejoin, it simply sets forced_latejoin_rule make_antag_chance(newPlayer) -> trim_candidates() -> ready(forced=TRUE) **NOTE no acceptable() call + For midround, calls the below proc with forced = TRUE picking_specific_rule(ruletype,forced) -> forced OR acceptable(living_players, threat_level) -> trim_candidates() -> ready(forced) -> spend threat -> execute() **NOTE specific rule can be called by RS traitor->MR autotraitor w/ forced=FALSE **NOTE that due to short circuiting acceptable() need not be called if forced. -## RULESET + +## Ruleset + acceptable(population,threat) just checks if enough threat_level for population indice. **NOTE that we currently only send threat_level as the second arg, not threat. ready(forced) checks if enough candidates and calls the map's map_ruleset(dynamic_ruleset) at the parent level + trim_candidates() varies significantly according to the ruleset type Roundstart: All candidates are new_player mobs. Check them for standard stuff: connected, desire role, not banned, etc. **NOTE Roundstart deals with both candidates (trimmed list of valid players) and mode.candidates (everyone readied up). Don't confuse them! Latejoin: Only one candidate, the latejoiner. Standard checks. Midround: Instead of building a single list candidates, candidates contains four lists: living, dead, observing, and living antags. Standard checks in trim_list(list). + Midround - Rulesets have additional types /from_ghosts: execute() -> send_applications() -> review_applications() -> finish_setup(mob/newcharacter, index) -> setup_role(role) **NOTE: execute() here adds dead players and observers to candidates list + +## Configuration and variables + +### Configuration +Configuration can be done through a `config/dynamic.json` file. One is provided as example in the codebase. This config file, loaded in `/datum/game_mode/dynamic/pre_setup()`, directly overrides the values in the codebase, and so is perfect for making some rulesets harder/easier to get, turning them off completely, changing how much they cost, etc. + +The format of this file is: +```json +{ + "Dynamic": { + /* Configuration in here will directly override `/datum/game_mode/dynamic` itself. */ + /* Keys are variable names, values are their new values. */ + }, + + "Roundstart": { + /* Configuration in here will apply to `/datum/dynamic_ruleset/roundstart` instances. */ + /* Keys are the ruleset names, values are another associative list with keys being variable names and values being new values. */ + "Wizard": { + /* I, a head admin, have died to wizard, and so I made it cost a lot more threat than it does in the codebase. */ + "cost": 80 + } + }, + + "Midround": { + /* Same as "Roundstart", but for `/datum/dynamic_ruleset/midround` instead. */ + }, + + "Latejoin": { + /* Same as "Roundstart", but for `/datum/dynamic_ruleset/latejoin` instead. */ + } +} +``` + +Note: Comments are not possible in this format, and are just in this document for the sake of readability. + +### Rulesets +Rulesets have the following variables notable to developers and those interested in tuning. + +- `required_candidates` - The number of people that *must be willing* (in their preferences) to be an antagonist with this ruleset. If the candidates do not meet this requirement, then the ruleset will not bother to be drafted. +- `antag_cap` - Judges the amount of antagonists to apply, for both solo and teams. Note that some antagonists (such as traitors, lings, heretics, etc) will add more based on how many times they've been scaled. Written as a linear equation--ceil(x/denominator) + offset, or as a fixed constant. If written as a linear equation, will be in the form of `list("denominator" = denominator, "offset" = offset)`. + - Examples include: + - Traitor: `antag_cap = list("denominator" = 24)`. This means that for every 24 players, 1 traitor will be added (assuming no scaling). + - Nuclear Emergency: `antag_cap = list("denominator" = 18, "offset" = 1)`. For every 18 players, 1 nuke op will be added. Starts at 1, meaning at 30 players, 3 nuke ops will be created, rather than 2. + - Revolution: `antag_cap = 3`. There will always be 3 rev-heads, no matter what. +- `minimum_required_age` - The minimum age in order to apply for the ruleset. +- `weight` - How likely this ruleset is to be picked. A higher weight results in a higher chance of drafting. +- `cost` - The initial cost of the ruleset. This cost is taken from either the roundstart or midround budget, depending on the ruleset. +- `scaling_cost` - Cost for every *additional* application of this ruleset. + - Suppose traitors has a `cost` of 8, and a `scaling_cost` of 5. This means that buying 1 application of the traitor ruleset costs 8 threat, but buying two costs 13 (8 + 5). Buying it a third time is 18 (8 + 5 + 5), etc. +- `pop_per_requirement` - The range of population each value in `requirements` represents. By default, this is 6. + - If the value is five the range is 0-4, 5-9, 10-14, 15-19, 20-24, 25-29, 30-34, 35-39, 40-54, 45+. + - If it is six the range is 0-5, 6-11, 12-17, 18-23, 24-29, 30-35, 36-41, 42-47, 48-53, 54+. + - If it is seven the range is 0-6, 7-13, 14-20, 21-27, 28-34, 35-41, 42-48, 49-55, 56-62, 63+. +- `requirements` - A list that represents, per population range (see: `pop_per_requirement`), how much threat is required to *consider* this ruleset. This is independent of how much it'll actually cost. This uses *threat level*, not the budget--meaning if a round has 50 threat level, but only 10 points of round start threat, a ruleset with a requirement of 40 can still be picked if it can be bought. + - Suppose wizard has a `requirements` of `list(90,90,70,40,30,20,10,10,10,10)`. This means that, at 0-5 and 6-11 players, A station must have 90 threat in order for a wizard to be possible. At 12-17, 70 threat is required instead, etc. +- `restricted_roles` - A list of jobs that *can't* be drafted by this ruleset. For example, cyborgs cannot be changelings, and so are in the `restricted_roles`. +- `protected_roles` - Serves the same purpose of `restricted_roles`, except it can be turned off through configuration (`protect_roles_from_antagonist`). For example, security officers *shouldn't* be made traitor, so they are in Traitor's `protected_roles`. + - When considering putting a role in `protected_roles` or `restricted_roles`, the rule of thumb is if it is *technically infeasible* to support that job in that role. There's no *technical* reason a security officer can't be a traitor, and so they are simply in `protected_roles`. There *are* technical reasons a cyborg can't be a changeling, so they are in `restricted_roles` instead. + +### Dynamic + +The "Dynamic" key has the following configurable values: +- `pop_per_requirement` - The default value of `pop_per_requirement` for any ruleset that does not explicitly set it. Defaults to 6. +- `latejoin_delay_min`, `latejoin_delay_max` - The time range, in deciseconds (take your seconds, and multiply by 10), for a latejoin to attempt rolling. Once this timer is finished, a new one will be created within the same range. + - Suppose you have a `latejoin_delay_min` of 600 (60 seconds, 1 minute) and a `latejoin_delay_max` of 1800 (180 seconds, 3 minutes). Once the round starts, a random number in this range will be picked--let's suppose 1.5 minutes. After 1.5 minutes, Dynamic will decide if a latejoin threat should be created (a probability of `/datum/game_mode/dynamic/proc/get_injection_chance()`). Regardless of its decision, a new timer will be started within the range of 1 to 3 minutes, repeatedly. +- `midround_delay_min`, `midround_delay_max` - Same as `latejoin_delay_min` and `latejoin_delay_max`, except for midround threats instead of latejoin ones. +- `higher_injection_chance`, `higher_injection_chance_minimum_threat` - Manipulates the injection chance (`/datum/game_mode/dynamic/proc/get_injection_chance()`). If the *current midround budget* is above `higher_injection_chance_minimum_threat`, then this chance will be increased by `higher_injection_chance`. + - For example: suppose you have a `higher_injection_chance_minimum_threat` of 70, and a `higher_injection_chance` of 15. This means that, if when a midround threat is trying to roll, there is 75 midround budget left, then the injection chance will go up 15%. +- `lower_injection_chance`, `lower_injection_chance_minimum_threat` - The inverse of the `higher_injection_chance` variables. If the *current midround budget* is *below* `lower_injection_chance`, then the chance is lowered by `lower_injection_chance_minimum_threat`. + - For example: suppose you have a `lower_injection_chance_minimum_threat` of 30, and a `lower_injection_chance` of 15. This means if there is 20 midround budget left, then the chance will lower by 15%. +- `threat_curve_centre` - A number between -5 and +5. A negative value will give a more peaceful round and a positive value will give a round with higher threat. +- `threat_curve_width` - A number between 0.5 and 4. Higher value will favour extreme rounds and lower value rounds closer to the average. +- `roundstart_split_curve_centre` - A number between -5 and +5. Equivalent to threat_curve_centre, but for the budget split. A negative value will weigh towards midround rulesets, and a positive value will weight towards roundstart ones. +- `roundstart_split_curve_width` - A number between 0.5 and 4. Equivalent to threat_curve_width, but for the budget split. Higher value will favour more variance in splits and lower value rounds closer to the average. +- `random_event_hijack_minimum` - The minimum amount of time for antag random events to be hijacked. (See [Random Event Hijacking](#random-event-hijacking)) +- `random_event_hijack_maximum` - The maximum amount of time for antag random events to be hijacked. (See [Random Event Hijacking](#random-event-hijacking)) +- `hijacked_random_event_injection_chance` - The amount of injection chance to give to Dynamic when a random event is hijacked. (See [Random Event Hijacking](#random-event-hijacking)) + +## Random Event "Hijacking" +Random events have the potential to be hijacked by Dynamic to keep the pace of midround injections, while also allowing greenshifts to contain some antagonists. + +`/datum/round_event_control/dynamic_should_hijack` is a variable to random events to allow Dynamic to hijack them, and defaults to FALSE. This is set to TRUE for random events that spawn antagonists. + +In `/datum/game_mode/dynamic/on_pre_random_event` (in `dynamic_hijacking.dm`), Dynamic hooks to random events. If the `dynamic_should_hijack` variable is TRUE, the following sequence of events occurs: + +![Flow chart to describe the chain of events for Dynamic 2021 to take](https://user-images.githubusercontent.com/35135081/109071468-9cab7e00-76a8-11eb-8f9f-2b920c602ef4.png) + +`n` is a random value between `random_event_hijack_minimum` and `random_event_hijack_maximum`. Injection chance, should it need to be raised, is increased by `hijacked_random_event_injection_chance`. diff --git a/code/game/gamemodes/dynamic/ruleset_picking.dm b/code/game/gamemodes/dynamic/ruleset_picking.dm new file mode 100644 index 0000000000..7c87f1bc82 --- /dev/null +++ b/code/game/gamemodes/dynamic/ruleset_picking.dm @@ -0,0 +1,122 @@ +#define ADMIN_CANCEL_MIDROUND_TIME (10 SECONDS) + +/// From a list of rulesets, returns one based on weight and availability. +/// Mutates the list that is passed into it to remove invalid rules. +/datum/game_mode/dynamic/proc/pick_ruleset(list/drafted_rules) + if (only_ruleset_executed) + return null + + while (TRUE) + var/datum/dynamic_ruleset/rule = pickweight(drafted_rules) + if (!rule) + return null + + if (check_blocking(rule.blocking_rules, executed_rules)) + drafted_rules -= rule + if(drafted_rules.len <= 0) + return null + continue + else if ( + rule.flags & HIGH_IMPACT_RULESET \ + && threat_level < GLOB.dynamic_stacking_limit \ + && GLOB.dynamic_no_stacking \ + && high_impact_ruleset_executed \ + ) + drafted_rules -= rule + if(drafted_rules.len <= 0) + return null + continue + + return rule + +/// Executes a random midround ruleset from the list of drafted rules. +/datum/game_mode/dynamic/proc/pick_midround_rule(list/drafted_rules) + var/datum/dynamic_ruleset/rule = pick_ruleset(drafted_rules) + if (isnull(rule)) + return + current_midround_rulesets = drafted_rules - rule + + midround_injection_timer_id = addtimer( + CALLBACK(src, .proc/execute_midround_rule, rule), \ + ADMIN_CANCEL_MIDROUND_TIME, \ + TIMER_STOPPABLE, \ + ) + + log_game("DYNAMIC: [rule] ruleset executing...") + message_admins("DYNAMIC: Executing midround ruleset [rule] in [DisplayTimeText(ADMIN_CANCEL_MIDROUND_TIME)]. \ + CANCEL | \ + SOMETHING ELSE") + +/// Fired after admins do not cancel a midround injection. +/datum/game_mode/dynamic/proc/execute_midround_rule(datum/dynamic_ruleset/rule) + current_midround_rulesets = null + midround_injection_timer_id = null + if (!rule.repeatable) + midround_rules = remove_from_list(midround_rules, rule.type) + addtimer(CALLBACK(src, .proc/execute_midround_latejoin_rule, rule), rule.delay) + +/// Executes a random latejoin ruleset from the list of drafted rules. +/datum/game_mode/dynamic/proc/pick_latejoin_rule(list/drafted_rules) + var/datum/dynamic_ruleset/rule = pick_ruleset(drafted_rules) + if (isnull(rule)) + return + if (!rule.repeatable) + latejoin_rules = remove_from_list(latejoin_rules, rule.type) + addtimer(CALLBACK(src, .proc/execute_midround_latejoin_rule, rule), rule.delay) + return TRUE + +/// Mainly here to facilitate delayed rulesets. All midround/latejoin rulesets are executed with a timered callback to this proc. +/datum/game_mode/dynamic/proc/execute_midround_latejoin_rule(sent_rule) + var/datum/dynamic_ruleset/rule = sent_rule + spend_midround_budget(rule.cost) + threat_log += "[worldtime2text()]: [rule.ruletype] [rule.name] spent [rule.cost]" + rule.pre_execute(current_players[CURRENT_LIVING_PLAYERS].len) + if (rule.execute()) + log_game("DYNAMIC: Injected a [rule.ruletype == "latejoin" ? "latejoin" : "midround"] ruleset [rule.name].") + if(rule.flags & HIGH_IMPACT_RULESET) + high_impact_ruleset_executed = TRUE + else if(rule.flags & ONLY_RULESET) + only_ruleset_executed = TRUE + if(rule.ruletype == "Latejoin") + var/mob/M = pick(rule.candidates) + message_admins("[key_name(M)] joined the station, and was selected by the [rule.name] ruleset.") + log_game("DYNAMIC: [key_name(M)] joined the station, and was selected by the [rule.name] ruleset.") + executed_rules += rule + rule.candidates.Cut() + if (rule.persistent) + current_rules += rule + new_snapshot(rule) + return TRUE + rule.clean_up() + stack_trace("The [rule.ruletype] rule \"[rule.name]\" failed to execute.") + return FALSE + +/// Fired when an admin cancels the current midround injection. +/datum/game_mode/dynamic/proc/admin_cancel_midround(mob/user, timer_id) + if (midround_injection_timer_id != timer_id || !deltimer(midround_injection_timer_id)) + to_chat(user, span_notice("Too late!")) + return + + log_admin("[key_name(user)] cancelled the next midround injection.") + message_admins("[key_name(user)] cancelled the next midround injection.") + midround_injection_timer_id = null + current_midround_rulesets = null + +/// Fired when an admin requests a different midround injection. +/datum/game_mode/dynamic/proc/admin_different_midround(mob/user, timer_id) + if (midround_injection_timer_id != timer_id || !deltimer(midround_injection_timer_id)) + to_chat(user, span_notice("Too late!")) + return + + midround_injection_timer_id = null + + if (isnull(current_midround_rulesets) || current_midround_rulesets.len == 0) + log_admin("[key_name(user)] asked for a different midround injection, but there were none left.") + message_admins("[key_name(user)] asked for a different midround injection, but there were none left.") + return + + log_admin("[key_name(user)] asked for a different midround injection.") + message_admins("[key_name(user)] asked for a different midround injection.") + pick_midround_rule(current_midround_rulesets) + +#undef ADMIN_CANCEL_MIDROUND_TIME diff --git a/code/game/gamemodes/eldritch_cult/eldritch_cult.dm b/code/game/gamemodes/eldritch_cult/eldritch_cult.dm index 1693163fa2..2086653012 100644 --- a/code/game/gamemodes/eldritch_cult/eldritch_cult.dm +++ b/code/game/gamemodes/eldritch_cult/eldritch_cult.dm @@ -4,7 +4,7 @@ antag_flag = ROLE_HERETIC false_report_weight = 5 chaos = 5 - restricted_jobs = list("AI", "Cyborg") + restricted_jobs = list("Prisoner", "AI", "Cyborg") protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") //citadel change - adds HoP, CE, CMO, and RD to heretic role blacklist required_players = 15 required_enemies = 1 diff --git a/code/game/gamemodes/extended/extended.dm b/code/game/gamemodes/extended/extended.dm index a6abcbefbd..bfc75a9dc1 100644 --- a/code/game/gamemodes/extended/extended.dm +++ b/code/game/gamemodes/extended/extended.dm @@ -30,4 +30,4 @@ /datum/game_mode/extended/announced/send_intercept(report = 0) if(flipseclevel) //CIT CHANGE - allows the sec level to be flipped roundstart return ..() - priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", "commandreport") + priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", SSstation.announcer.get_rand_report_sound()) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 5ea99da479..12dfc92cc4 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -52,6 +52,9 @@ var/setup_error //What stopepd setting up the mode. var/flipseclevel = FALSE //CIT CHANGE - adds a 10% chance for the alert level to be the opposite of what the gamemode is supposed to have + /// Associative list of current players, in order: living players, living antagonists, dead players and observers. + var/list/list/current_players = list(CURRENT_LIVING_PLAYERS = list(), CURRENT_LIVING_ANTAGS = list(), CURRENT_DEAD_PLAYERS = list(), CURRENT_OBSERVERS = list()) + /datum/game_mode/proc/announce() //Shows the gamemode's name and a fast description. to_chat(world, "The gamemode is: [name]!") to_chat(world, "[announce_text]") @@ -76,6 +79,8 @@ return 1 + + ///Attempts to select players for special roles the mode might have. /datum/game_mode/proc/pre_setup() return 1 @@ -273,7 +278,7 @@ /datum/game_mode/proc/send_intercept() if(flipseclevel && !(config_tag == "extended"))//CIT CHANGE - lets the security level be flipped roundstart - priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", "commandreport") + priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", SSstation.announcer.get_rand_report_sound()) return var/intercepttext = "Central Command Status Summary
    " intercepttext += "Central Command has intercepted and partially decoded a Syndicate transmission with vital information regarding their movements. The following report outlines the most \ @@ -343,8 +348,9 @@ var/list/curr_tickets = list() //how many tickets someone has for *this* antag roll, so with the free tickets var/list/datum/mind/insufficient = list() //who got cucked out of an antag roll due to not having *any* tickets for(var/datum/mind/M in candidates) + var/weight = clamp(candidates[M], 0, 1) var/mind_ckey = ckey(M.key) - var/can_spend = min(prev_tickets[mind_ckey], additional_tickets) //they can only spend up to config/max_tickets_per_roll + var/can_spend = min(prev_tickets[mind_ckey], additional_tickets * weight) //they can only spend up to config/max_tickets_per_roll var/amount = can_spend + free_tickets //but they get config/default_antag_tickets for free if(amount <= 0) //if they don't have any insufficient += M //too bad! @@ -420,10 +426,11 @@ for(var/mob/dead/new_player/player in players) if(player.client && player.ready == PLAYER_READY_TO_PLAY) - if((role in player.client.prefs.be_special) && !(ROLE_NO_ANTAGONISM in player.client.prefs.be_special)) + if(HAS_ANTAG_PREF(player.client, role)) if(!jobban_isbanned(player, ROLE_SYNDICATE) && !QDELETED(player) && !jobban_isbanned(player, role) && !QDELETED(player)) //Nodrak/Carn: Antag Job-bans if(age_check(player.client)) //Must be older than the minimum age candidates += player.mind // Get a list of all the people who want to be the antagonist for this round + candidates[player.mind] = player.client.prefs.be_special[role] if(restricted_jobs) for(var/datum/mind/player in candidates) @@ -444,35 +451,11 @@ if(player.assigned_role == job) drafted -= player - drafted = shuffle(drafted) // Will hopefully increase randomness, Donkie - - while(candidates.len < recommended_enemies) // Pick randomlly just the number of people we need and add them to our list of candidates - if(drafted.len > 0) - applicant = pick(drafted) - if(applicant) - candidates += applicant - drafted.Remove(applicant) - - else // Not enough scrubs, ABORT ABORT ABORT - break - - if(restricted_jobs) - for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist - for(var/job in restricted_jobs) - if(player.assigned_role == job) - drafted -= player - - drafted = shuffle(drafted) // Will hopefully increase randomness, Donkie - - while(candidates.len < recommended_enemies) // Pick randomlly just the number of people we need and add them to our list of candidates - if(drafted.len > 0) - applicant = pick(drafted) - if(applicant) - candidates += applicant - drafted.Remove(applicant) - - else // Not enough scrubs, ABORT ABORT ABORT - break + while(candidates.len < recommended_enemies && length(drafted)) // Pick randomlly just the number of people we need and add them to our list of candidates + applicant = pick_n_take(drafted) + if(applicant) + candidates += applicant + candidates[applicant] = 0 return candidates // Returns: The number of people who had the antagonist role set to yes, regardless of recomended_enemies, if that number is greater than recommended_enemies // recommended_enemies if the number of people with that role set to yes is less than recomended_enemies, diff --git a/code/game/gamemodes/gang/gang.dm b/code/game/gamemodes/gang/gang.dm new file mode 100644 index 0000000000..47c24a8fcf --- /dev/null +++ b/code/game/gamemodes/gang/gang.dm @@ -0,0 +1,50 @@ +/datum/game_mode/gang + name = "Families" + config_tag = "families" + antag_flag = ROLE_TRAITOR + false_report_weight = 5 + required_players = 0 + required_enemies = 1 + recommended_enemies = 4 + announce_span = "danger" + announce_text = "Grove For Lyfe!" + reroll_friendly = FALSE + restricted_jobs = list("Cyborg", "AI", "Prisoner","Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel")//N O + protected_jobs = list() + + /// A reference to the handler that is used to run pre_setup(), post_setup(), etc.. + var/datum/gang_handler/handler + +/datum/game_mode/gang/warriors + name = "Warriors" + config_tag = "warriors" + announce_text = "Can you survive this onslaught?" + +/datum/game_mode/gang/warriors/pre_setup() + handler = new /datum/gang_handler(antag_candidates,restricted_jobs) + var/list/datum/antagonist/gang/gangs_to_generate = subtypesof(/datum/antagonist/gang) + handler.gangs_to_generate = gangs_to_generate.len + handler.gang_balance_cap = 3 + return handler.pre_setup_analogue() + +/datum/game_mode/gang/pre_setup() + handler = new /datum/gang_handler(antag_candidates,restricted_jobs) + return handler.pre_setup_analogue() + +/datum/game_mode/gang/Destroy() + QDEL_NULL(handler) + return ..() + +/datum/game_mode/gang/post_setup() + handler.post_setup_analogue(FALSE) + gamemode_ready = TRUE + return ..() + +/datum/game_mode/gang/process() + handler.process_analogue() + +/datum/game_mode/gang/set_round_result() + return handler.set_round_result_analogue() + +/datum/game_mode/gang/generate_report() + return "Something something grove street home at least until I fucked everything up idk nobody reads these reports." diff --git a/code/game/gamemodes/gangs/dominator.dm b/code/game/gamemodes/gangs/dominator.dm deleted file mode 100644 index a253aa906c..0000000000 --- a/code/game/gamemodes/gangs/dominator.dm +++ /dev/null @@ -1,247 +0,0 @@ -#define DOM_BLOCKED_SPAM_CAP 6 -//32 instead of 40 for safety reasons. How many turfs aren't walls around dominator for it to work -//Update ppl somehow fuckup at 32, now we are down to 25. I hope to god they don't try harder to wall it. -#define DOM_REQUIRED_TURFS 25 -#define DOM_HULK_HITS_REQUIRED 10 - -/obj/machinery/dominator - name = "dominator" - desc = "A visibly sinister device. Looks like you can break it if you hit it enough." - icon = 'icons/obj/machines/dominator.dmi' - icon_state = "dominator" - density = TRUE - anchored = TRUE - layer = HIGH_OBJ_LAYER - max_integrity = 300 - integrity_failure = 0.33 - armor = list("melee" = 20, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 10, "acid" = 70) - var/datum/team/gang/gang - var/operating = FALSE //false=standby or broken, true=takeover - var/warned = FALSE //if this device has set off the warning at <3 minutes yet - var/spam_prevention = DOM_BLOCKED_SPAM_CAP //first message is immediate - var/datum/effect_system/spark_spread/spark_system - var/obj/effect/countdown/dominator/countdown - -/obj/machinery/dominator/Initialize() - . = ..() - set_light(l_range = 2, l_power = 0.75) - GLOB.poi_list |= src - spark_system = new - spark_system.set_up(5, TRUE, src) - countdown = new(src) - update_icon() - -/obj/machinery/dominator/Destroy() - if(!(stat & BROKEN)) - set_broken() - GLOB.poi_list.Remove(src) - gang = null - QDEL_NULL(spark_system) - QDEL_NULL(countdown) - STOP_PROCESSING(SSmachines, src) - return ..() - -/obj/machinery/dominator/emp_act(severity) - take_damage(75+severity/4, BURN, "energy", 0) - ..() - -/obj/machinery/dominator/hulk_damage() - return (max_integrity - integrity_failure) / DOM_HULK_HITS_REQUIRED - -/obj/machinery/dominator/update_icon() - cut_overlays() - if(stat & BROKEN) - icon_state = "dominator-broken" - return - icon_state = "dominator" - if(operating) - var/mutable_appearance/dominator_overlay = mutable_appearance('icons/obj/machines/dominator.dmi', "dominator-overlay") - if(gang) - dominator_overlay.color = gang.color - add_overlay(dominator_overlay) - if(obj_integrity/max_integrity < 0.66) - add_overlay("damage") - -/obj/machinery/dominator/examine(mob/user) - . = ..() - if(stat & BROKEN) - return - - if(gang && gang.domination_time != NOT_DOMINATING) - if(gang.domination_time > world.time) - . += "Hostile Takeover in progress. Estimated [gang.domination_time_remaining()] seconds remain." - else - . += "Hostile Takeover of [station_name()] successful. Have a great day." - else - . += "System on standby." - . += "System Integrity: [round((obj_integrity/max_integrity)*100,1)]%" - -/obj/machinery/dominator/process() - ..() - if(gang && gang.domination_time != NOT_DOMINATING) - var/time_remaining = gang.domination_time_remaining() - if(time_remaining > 0) - if(!is_station_level(z)) - explosion(src, 5, 10, 20, 30) //you now get a nice explosion if this moves off station. - qdel(src) //to make sure it doesn't continue to exist. - if(excessive_walls_check()) - gang.domination_time += 20 - if(spam_prevention < DOM_BLOCKED_SPAM_CAP) - spam_prevention++ - else - playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0) // Play sound buzz-two.ogg, not before cause its annoying. - gang.message_gangtools("Warning: There are too many walls around your gang's dominator, its signal is being blocked!") - say("Error: Takeover signal is currently blocked! There are too many walls within 3 standard units of this device.") - spam_prevention = 0 - return - . = TRUE - playsound(loc, 'sound/items/timer.ogg', 10, 0) - if(!warned && (time_remaining < 180)) - warned = TRUE - var/area/domloc = get_base_area(loc) - gang.message_gangtools("Less than 3 minutes remains in hostile takeover. Defend your dominator at [domloc.map_name]!") - for(var/G in GLOB.gangs) - var/datum/team/gang/tempgang = G - if(tempgang != gang) - tempgang.message_gangtools("WARNING: [gang.name] Gang takeover imminent. Their dominator at [domloc.map_name] must be destroyed!",1,1) - else - endgame() - - if(!.) - STOP_PROCESSING(SSmachines, src) - -/obj/machinery/dominator/proc/endgame() - set waitfor = FALSE - Cinematic(CINEMATIC_MALF,world) //Here is the gang victory trigger on the dominator ending. - gang.winner = TRUE - SSticker.news_report = GANG_VICTORY - SSticker.force_ending = TRUE - -/obj/machinery/dominator/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - switch(damage_type) - if(BRUTE) - if(damage_amount) - playsound(src, 'sound/effects/bang.ogg', 50, 1) - else - playsound(loc, 'sound/weapons/tap.ogg', 50, 1) - if(BURN) - playsound(src.loc, 'sound/items/welder.ogg', 100, 1) - -/obj/machinery/dominator/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1) - . = ..() - if(.) - if(obj_integrity/max_integrity > 0.66) - if(prob(damage_amount*2)) - spark_system.start() - else if(!(stat & BROKEN)) - spark_system.start() - update_icon() - - -/obj/machinery/dominator/obj_break(damage_flag) - if(!(stat & BROKEN) && !(flags_1 & NODECONSTRUCT_1)) - set_broken() - -/obj/machinery/dominator/deconstruct(disassembled = TRUE) - if(!(flags_1 & NODECONSTRUCT_1)) - if(!(stat & BROKEN)) - set_broken() - new /obj/item/stack/sheet/plasteel(src.loc) - qdel(src) - -/obj/machinery/dominator/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1) - add_fingerprint(user) - return ..() - -/obj/machinery/dominator/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - if(operating || (stat & BROKEN)) - examine(user) - return - - var/datum/team/gang/tempgang - - var/datum/antagonist/gang/GA = user.mind.has_antag_datum(/datum/antagonist/gang) - if(GA) - tempgang = GA.gang - if(!tempgang) - examine(user) - return - - if(tempgang.domination_time != NOT_DOMINATING) - to_chat(user, "Error: Hostile Takeover is already in progress.") - return - - if(!tempgang.dom_attempts) - to_chat(user, "Error: Unable to breach station network. Firewall has logged our signature and is blocking all further attempts.") - return - - var/time = round(tempgang.determine_domination_time()/60,0.1) - if(alert(user,"A takeover will require [time] minutes.\nYour gang will be unable to gain influence while it is active.\nThe entire station will likely be alerted to it once it starts.\nYou have [tempgang.dom_attempts] attempt(s) remaining. Are you ready?","Confirm","Ready","Later") == "Ready") - if((tempgang.domination_time != NOT_DOMINATING) || !tempgang.dom_attempts || !in_range(src, user) || !isturf(loc)) - return 0 - - var/area/A = get_base_area(loc) - var/locname = A.map_name - - gang = tempgang - gang.dom_attempts -- - priority_announce("Network breach detected in [locname]. The [gang.name] Gang is attempting to seize control of the station!","Network Alert") - gang.domination() - SSshuttle.registerHostileEnvironment(src) - name = "[gang.name] Gang [name]" - operating = TRUE - update_icon() - - countdown.start() - countdown.color = gang.color - - set_light(l_range = 3, l_power = 0.9) - light_color = gang.color - START_PROCESSING(SSmachines, src) - - gang.message_gangtools("Hostile takeover in progress: Estimated [time] minutes until victory.[gang.dom_attempts ? "" : " This is your final attempt."]") - for(var/G in GLOB.gangs) - var/datum/team/gang/vagos = G - if(vagos != gang) - vagos.message_gangtools("Enemy takeover attempt detected in [locname]: Estimated [time] minutes until our defeat.",1,1) - -/obj/machinery/dominator/proc/excessive_walls_check() // why the fuck was this even a global proc... - var/open = 0 - for(var/turf/T in view(3, src)) - if(!iswallturf(T)) //Check for /closed/wall, isclosedturf() moves it back to just checking for /closed/ which makes it very finicky. - open++ - //to_chat(world, "THE DOMINATOR SEES [open] OPEN TURFS") uncomment to see what this shitty fucking wallcheck sees - if(open < DOM_REQUIRED_TURFS) - return TRUE - else - return FALSE -/obj/machinery/dominator/proc/set_broken() - if(gang) - gang.domination_time = NOT_DOMINATING - - var/takeover_in_progress = FALSE - for(var/G in GLOB.gangs) - var/datum/team/gang/ballas = G - if(ballas.domination_time != NOT_DOMINATING) - takeover_in_progress = TRUE - break - if(!takeover_in_progress) - var/was_stranded = SSshuttle.emergency.mode == SHUTTLE_STRANDED - if(!was_stranded) - priority_announce("All hostile activity within station systems has ceased.","Network Alert") - - if(NUM2SECLEVEL(GLOB.security_level) == "delta") - set_security_level("red") - - SSshuttle.clearHostileEnvironment(src) - gang.message_gangtools("Hostile takeover cancelled: Dominator is no longer operational.[gang.dom_attempts ? " You have [gang.dom_attempts] attempt remaining." : " The station network will have likely blocked any more attempts by us."]",1,1) - - set_light(0) - operating = FALSE - stat |= BROKEN - update_icon() - STOP_PROCESSING(SSmachines, src) - -#undef DOM_BLOCKED_SPAM_CAP -#undef DOM_REQUIRED_TURFS -#undef DOM_HULK_HITS_REQUIRED diff --git a/code/game/gamemodes/gangs/dominator_countdown.dm b/code/game/gamemodes/gangs/dominator_countdown.dm deleted file mode 100644 index 3b61a07829..0000000000 --- a/code/game/gamemodes/gangs/dominator_countdown.dm +++ /dev/null @@ -1,13 +0,0 @@ -/obj/effect/countdown/dominator - name = "dominator countdown" - text_size = 1 - color = "#e5e5e5" // Overwritten when the dominator starts - -/obj/effect/countdown/dominator/get_value() - var/obj/machinery/dominator/D = attached_to - if(!istype(D)) - return - else if(D.gang && D.gang.domination_time != NOT_DOMINATING) - return D.gang.domination_time_remaining() - else - return "OFFLINE" diff --git a/code/game/gamemodes/gangs/gang.dm b/code/game/gamemodes/gangs/gang.dm deleted file mode 100644 index 6efdf2a4aa..0000000000 --- a/code/game/gamemodes/gangs/gang.dm +++ /dev/null @@ -1,479 +0,0 @@ -/datum/antagonist/gang - name = "Gangster" - roundend_category = "gangsters" - can_coexist_with_others = FALSE - job_rank = ROLE_GANG - antagpanel_category = "Gang" - threat = 2 - var/hud_type = "gangster" - var/message_name = "Gangster" - var/datum/team/gang/gang - -/datum/antagonist/gang/can_be_owned(datum/mind/new_owner) - . = ..() - if(.) - if(new_owner.unconvertable) - return FALSE - -/datum/antagonist/gang/apply_innate_effects(mob/living/mob_override) - var/mob/living/M = mob_override || owner.current - update_gang_icons_added(M) - -/datum/antagonist/gang/remove_innate_effects(mob/living/mob_override) - var/mob/living/M = mob_override || owner.current - update_gang_icons_removed(M) - -/datum/antagonist/gang/get_team() - return gang - -/datum/antagonist/gang/greet() - gang.greet_gangster(owner) - -/datum/antagonist/gang/farewell() - if(ishuman(owner.current)) - owner.current.visible_message("[owner.current] looks like [owner.current.p_theyve()] just remembered [owner.current.p_their()] real allegiance!", null, null, null, owner.current) - to_chat(owner, "You are no longer a gangster! Your memories from the time you were in a gang are hazy... You don't seem to be able to recall the names of your previous allies, not even your bosses...") - -/datum/antagonist/gang/on_gain() - if(!gang) - create_team() - ..() - var/mob/living/carbon/human/H = owner.current - if(istype(H)) - if(owner.assigned_role == "Clown") - to_chat(owner, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") - H.dna.remove_mutation(CLOWNMUT) - add_to_gang() - -/datum/antagonist/gang/on_removal() - remove_from_gang() - ..() - -/datum/antagonist/gang/create_team(team) - if(!gang) // add_antag_datum calls create_team, so we need to avoid generating two gangs in that case - if(team) - gang = team - return - var/datum/team/gang/gangteam = pick_n_take(GLOB.possible_gangs) - if(gangteam) - gang = new gangteam - -/datum/antagonist/gang/proc/equip_gang() // Bosses get equipped with their tools - return - -/datum/antagonist/gang/proc/update_gang_icons_added(mob/living/M) - var/datum/atom_hud/antag/gang/ganghud = GLOB.huds[gang.hud_entry_num] - if(!ganghud) - ganghud = new/datum/atom_hud/antag/gang() - gang.hud_entry_num = GLOB.huds.len+1 // this is the index the gang hud will be added at - GLOB.huds += ganghud - ganghud.color = gang.color - ganghud.join_hud(M) - set_antag_hud(M,hud_type) - -/datum/antagonist/gang/proc/update_gang_icons_removed(mob/living/M) - var/datum/atom_hud/antag/gang/ganghud = GLOB.huds[gang.hud_entry_num] - if(ganghud) - ganghud.leave_hud(M) - set_antag_hud(M, null) - -/datum/antagonist/gang/proc/can_be_converted(mob/living/candidate) - if(!candidate.mind) - return FALSE - if(!can_be_owned(candidate.mind)) - return FALSE - var/mob/living/carbon/human/H = candidate - if(!istype(H)) //Can't nonhumans - return FALSE - return TRUE - -/datum/antagonist/gang/proc/promote() // Bump up to boss - var/datum/team/gang/old_gang = gang - var/datum/mind/old_owner = owner - owner.remove_antag_datum(/datum/antagonist/gang) - var/datum/antagonist/gang/boss/lieutenant/new_boss = new - new_boss.silent = TRUE - old_owner.add_antag_datum(new_boss,old_gang) - new_boss.silent = FALSE - log_game("[key_name(old_owner)] has been promoted to Lieutenant in the [old_gang.name] Gang") - to_chat(old_owner, "You have been promoted to Lieutenant!") - - -// Admin commands -/datum/antagonist/gang/get_admin_commands() - . = ..() - .["Promote"] = CALLBACK(src,.proc/admin_promote) - .["Set Influence"] = CALLBACK(src, .proc/admin_adjust_influence) - if(gang.domination_time != NOT_DOMINATING) - .["Set domination time left"] = CALLBACK(src, .proc/set_dom_time_left) - -/datum/antagonist/gang/admin_add(datum/mind/new_owner,mob/admin) - var/new_or_existing = input(admin, "Which gang do you want to be assigned to the user?", "Gangs") as null|anything in list("New","Existing") - if(isnull(new_or_existing)) - return - else if(new_or_existing == "New") - var/newgang = input(admin, "Select a gang, or select random to pick a random one.", "New gang") as null|anything in GLOB.possible_gangs + "Random" - if(isnull(newgang)) - return - else if(newgang == "Random") - var/datum/team/gang/G = pick_n_take(GLOB.possible_gangs) - gang = new G - else - GLOB.possible_gangs -= newgang - gang = new newgang - else - if(!GLOB.gangs.len) // no gangs exist - to_chat(admin, "No gangs exist, please create a new one instead.") - return - var/existinggang = input(admin, "Select a gang, or select random to pick a random one.", "Existing gang") as null|anything in GLOB.gangs + "Random" - if(isnull(existinggang)) - return - else if(existinggang == "Random") - gang = pick(GLOB.gangs) - else - gang = existinggang - ..() - return TRUE - -/datum/antagonist/gang/proc/admin_promote(mob/admin) - message_admins("[key_name_admin(admin)] has promoted [owner] to gang boss.") - log_admin("[key_name(admin)] has promoted [owner] to boss.") - promote() - -/datum/antagonist/gang/proc/admin_adjust_influence() - var/inf = input("Influence for [gang.name]","Gang influence", gang.influence) as null | num - if(!isnull(inf)) - gang.influence = inf - message_admins("[key_name_admin(usr)] changed [gang.name]'s influence to [inf].") - log_admin("[key_name(usr)] changed [gang.name]'s influence to [inf].") - -/datum/antagonist/gang/proc/add_to_gang() - gang.add_member(owner) - owner.current.log_message("Has been converted to the [gang.name] gang!", INDIVIDUAL_ATTACK_LOG) - -/datum/antagonist/gang/proc/remove_from_gang() - gang.remove_member(owner) - owner.current.log_message("Has been deconverted from the [gang.name] gang!", INDIVIDUAL_ATTACK_LOG) - -/datum/antagonist/gang/proc/set_dom_time_left(mob/admin) - if(gang.domination_time == NOT_DOMINATING) - return // an admin shouldn't need this - var/seconds = input(admin, "Set the time left for the gang to win, in seconds", "Domination time left") as null|num - if(seconds && seconds > 0) - gang.domination_time = world.time + seconds*10 - gang.message_gangtools("Takeover shortened to [gang.domination_time_remaining()] seconds by your Syndicate benefactors.") - -// Boss type. Those can use gang tools to buy items for their gang, in particular the Dominator, used to win the gamemode, along with more gang tools to promote fellow gangsters to boss status. -/datum/antagonist/gang/boss - name = "Gang boss" - hud_type = "gang_boss" - message_name = "Leader" - threat = 10 - -/datum/antagonist/gang/boss/on_gain() - ..() - if(gang) - gang.leaders += owner - -/datum/antagonist/gang/boss/on_removal() - if(gang) - gang.leaders -= owner - ..() - -/datum/antagonist/gang/boss/antag_listing_name() - return ..() + "(Boss)" - -/datum/antagonist/gang/boss/equip_gang(gangtool = TRUE, pen = TRUE, spraycan = TRUE, hud = TRUE) // usually has to be called separately - var/mob/living/carbon/human/H = owner.current - if(!istype(H)) - return - - var/list/slots = list ( - "backpack" = SLOT_IN_BACKPACK, - "left pocket" = SLOT_L_STORE, - "right pocket" = SLOT_R_STORE, - "hands" = SLOT_HANDS - ) - - if(gangtool)//Here is where all of the text occurs when a gang boss first spawns in. - var/obj/item/device/gangtool/G = new() - var/where = H.equip_in_one_of_slots(G, slots, critical = TRUE) - if (!where) - to_chat(H, "Your Syndicate benefactors were unfortunately unable to get you a Gangtool.") - else - G.register_device(H) - to_chat(H, "The Gangtool in your [where] will allow you to purchase weapons and equipment, send messages to your gang, and recall the emergency shuttle from anywhere on the station.") - to_chat(H, "As the gang boss, you can also promote your gang members to lieutenant. Unlike regular gangsters, Lieutenants cannot be deconverted and are able to use gangtools too.") - - if(pen) - var/obj/item/pen/gang/T = new() - var/where2 = H.equip_in_one_of_slots(T, slots, critical = TRUE) - if (!where2) - to_chat(H, "Your Syndicate benefactors were unfortunately unable to get you a recruitment pen to start.") - else - to_chat(H, "The recruitment pen in your [where2] will help you get your gang started. Stab unsuspecting crew members with it to recruit them. All gangsters can use these, distribute them to see your gang grow.") - - if(spraycan) - var/obj/item/toy/crayon/spraycan/gang/SC = new(null,gang) - var/where3 = H.equip_in_one_of_slots(SC, slots, critical = TRUE) - if (!where3) - to_chat(H, "Your Syndicate benefactors were unfortunately unable to get you a territory spraycan to start.") - else - to_chat(H, "The territory spraycan in your [where3] can be used to claim areas of the station for your gang. The more territory your gang controls, the more influence you get. All gangsters can use these, so distribute them to grow your influence faster.") - - if(hud) - var/obj/item/clothing/glasses/hud/security/chameleon/C = new(null,gang) - var/where4 = H.equip_in_one_of_slots(C, slots, critical = TRUE) - if (!where4) - to_chat(H, "Your Syndicate benefactors were unfortunately unable to get you a chameleon security HUD.") - else - to_chat(H, "The chameleon security HUD in your [where4] will help you keep track of who is mindshield-implanted, and unable to be recruited.") - -// Admin commands for bosses -/datum/antagonist/gang/boss/admin_add(datum/mind/new_owner,mob/admin) - if(!new_owner.has_antag_datum(parent_type)) - ..() - to_chat(new_owner.current, "You are a member of the [gang.name] Gang leadership now!") - return - promote() - message_admins("[key_name_admin(admin)] has made [new_owner.current] a boss of the [gang.name] gang.") - log_admin("[key_name(admin)] has made [new_owner.current] a boss of the [gang.name] gang.") - to_chat(new_owner.current, "You are a member of the [gang.name] Gang leadership now!") - -/datum/antagonist/gang/boss/get_admin_commands() - . = ..() - . -= "Promote" - .["Take gangtool"] = CALLBACK(src,.proc/admin_take_gangtool) - .["Give gangtool"] = CALLBACK(src,.proc/admin_give_gangtool) - .["Demote"] = CALLBACK(src,.proc/admin_demote) - -/datum/antagonist/gang/boss/proc/demote() - var/old_gang = gang - var/datum/mind/old_owner = owner - silent = TRUE - owner.remove_antag_datum(/datum/antagonist/gang/boss) - var/datum/antagonist/gang/new_gangster = new /datum/antagonist/gang() - new_gangster.silent = TRUE - old_owner.add_antag_datum(new_gangster,old_gang) - new_gangster.silent = FALSE - log_game("[key_name(old_owner)] has been demoted to Gangster in the [gang.name] Gang") - to_chat(old_owner, "The gang has been disappointed of your leader traits! You are a regular gangster now!") - -/datum/antagonist/gang/boss/proc/admin_take_gangtool(mob/admin) - var/list/L = owner.current.get_contents() - var/obj/item/device/gangtool/gangtool = locate() in L - if (!gangtool) - to_chat(admin, "Deleting gangtool failed!") - return - qdel(gangtool) - -/datum/antagonist/gang/boss/proc/admin_give_gangtool(mob/admin) - equip_gang(TRUE, FALSE, FALSE, FALSE) - -/datum/antagonist/gang/boss/proc/admin_demote(datum/mind/target,mob/user) - message_admins("[key_name_admin(user)] has demoted [owner.current] from gang boss.") - log_admin("[key_name(user)] has demoted [owner.current] from gang boss.") - admin_take_gangtool(user) - demote() - -/datum/antagonist/gang/boss/lieutenant - name = "Gang Lieutenant" - message_name = "Lieutenant" - hud_type = "gang_lt" - -#define MAXIMUM_RECALLS 3 -#define INFLUENCE_INTERVAL 1200 //This handles the interval between each count of influence. -// Gang team datum. This handles the gang itself. -/datum/team/gang - name = "Gang" - member_name = "gangster" - var/hud_entry_num // because if you put something other than a number in GLOB.huds, god have mercy on your fucking soul friend - var/list/leaders = list() // bosses - var/max_leaders = MAX_LEADERS_GANG - var/list/territories = list() // territories owned by the gang. - var/list/lost_territories = list() // territories lost by the gang. - var/list/new_territories = list() // territories captured by the gang. - var/list/gangtools = list() - var/domination_time = NOT_DOMINATING - var/dom_attempts = INITIAL_DOM_ATTEMPTS - var/color - var/influence = 0 // influence of the gang, based on how many territories they own. Can be used to buy weapons and tools from a gang uplink. - var/winner // Once the gang wins with a dominator, this becomes true. For roundend credits purposes. - var/list/inner_outfits = list() - var/list/outer_outfits = list() - var/next_point_time - var/recalls = MAXIMUM_RECALLS // Once this reaches 0, this gang cannot force recall the shuttle with their gangtool anymore - -/datum/team/gang/New(starting_members) - . = ..() - GLOB.gangs += src - if(starting_members) - if(islist(starting_members)) - for(var/datum/mind/groveboss in starting_members) - leaders += groveboss - var/datum/antagonist/gang/boss/gb = new - groveboss.add_antag_datum(gb, src) - gb.equip_gang() - - else - var/datum/mind/CJ = starting_members - if(istype(CJ)) - leaders += CJ - var/datum/antagonist/gang/boss/bossdatum = new - CJ.add_antag_datum(bossdatum, src) - bossdatum.equip_gang() - next_point_time = world.time + INFLUENCE_INTERVAL - addtimer(CALLBACK(src, .proc/handle_territories), INFLUENCE_INTERVAL) - -/datum/team/gang/Destroy() - GLOB.gangs -= src - ..() - -/datum/team/gang/roundend_report() //roundend report. - var/list/report = list() - report += "[name]:" - if(winner) - report += "The [name] gang successfully activated the mind dominator!" - else - report += "The [name] gang has failed!" - - report += "The [name] gang bosses were:" - report += printplayerlist(leaders) - report += "The [name] [member_name]s were:" - report += printplayerlist(members-leaders) - - return "
    [report.Join("
    ")]
    " - -/datum/team/gang/proc/greet_gangster(datum/mind/gangster) //The text a person receives when recruited. - var/message = "You are now a member of the [name] Gang!" - message += "Help your bosses take over the station by claiming territory with spraycans. Simply spray on any unclaimed area of the station." - message += "You can also use recruitment pens to recruit more to your cause, If your boss provides you one." - message += "Their ultimate objective is to take over the station with a Dominator machine." - message += "You can identify your mates by their large, \[G\] icon." - to_chat(gangster, message) - gangster.store_memory("You are a member of the [name] Gang!") - -/datum/team/gang/proc/handle_territories() - next_point_time = world.time + INFLUENCE_INTERVAL - if(!leaders.len) - return - var/added_names = "" - var/lost_names = "" - - //Re-add territories that were reclaimed, so if they got tagged over, they can still earn income if they tag it back before the next status report - var/list/reclaimed_territories = new_territories & lost_territories - territories |= reclaimed_territories - new_territories -= reclaimed_territories - lost_territories -= reclaimed_territories - - //Process lost territories - for(var/area in lost_territories) - if(lost_names != "") - lost_names += ", " - lost_names += "[lost_territories[area]]" - territories -= area - - //Calculate and report influence growth - - //Process new territories - for(var/area in new_territories) - if(added_names != "") - added_names += ", " - added_names += "[new_territories[area]]" - territories += area - - //Report territory changes - var/message = "[src] Gang Status Report:.
    *---------*
    " - message += "[new_territories.len] new territories:
    [added_names]
    " - message += "[lost_territories.len] territories lost:
    [lost_names]
    " - //Clear the lists - new_territories = list() - lost_territories = list() - var/total_territories = total_claimable_territories() - var/control = round((territories.len/total_territories)*100, 1) - var/uniformed = check_clothing() - message += "Your gang now has [control]% control of the station.
    *---------*
    " - if(domination_time != NOT_DOMINATING) - var/new_time = max(world.time, domination_time - (uniformed * 4) - (territories.len * 2)) - if(new_time < domination_time) - message += "Takeover shortened by [(domination_time - new_time)*0.1] seconds for defending [territories.len] territories.
    " - domination_time = new_time - message += "[domination_time_remaining()] seconds remain in hostile takeover.
    " - else - var/new_influence = check_territory_income() - if(new_influence != influence) - message += "Gang influence has increased by [new_influence - influence] for defending [territories.len] territories and [uniformed] uniformed gangsters.
    " - influence = new_influence - message += "Your gang now has [influence] influence.
    " - message_gangtools(message) - addtimer(CALLBACK(src, .proc/handle_territories), INFLUENCE_INTERVAL) - -/datum/team/gang/proc/total_claimable_territories() - var/list/valid_territories = list() - for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION)) //First, collect all area types on the station zlevel - for(var/ar in SSmapping.areas_in_z["[z]"]) - var/area/A = ar - if(!(A.type in valid_territories) && (A.area_flags & VALID_TERRITORY)) - valid_territories |= A.type - return valid_territories.len - -/datum/team/gang/proc/check_territory_income() - var/new_influence = min(999,influence + 15 + (check_clothing() * 2) + territories.len) - return new_influence - -/datum/team/gang/proc/check_clothing() - //Count uniformed gangsters - var/uniformed = 0 - for(var/datum/mind/gangmind in members) - if(ishuman(gangmind.current)) - var/mob/living/carbon/human/gangster = gangmind.current - //Gangster must be alive and should return 0 not continue if conditions are met. - if(!istype(gangster) || gangster.stat == DEAD) - return 0 - - var/obj/item/clothing/outfit - var/obj/item/clothing/gang_outfit - if(gangster.w_uniform) - outfit = gangster.w_uniform - if(outfit.type in inner_outfits) - gang_outfit = outfit - if(gangster.wear_suit) - outfit = gangster.wear_suit - if(outfit.type in outer_outfits) - gang_outfit = outfit - - if(gang_outfit) - uniformed++ - return uniformed - -/datum/team/gang/proc/adjust_influence(value) - influence = max(0, influence + value) - -/datum/team/gang/proc/message_gangtools(message) - if(!gangtools.len || !message) - return - for(var/i in gangtools) - var/obj/item/device/gangtool/tool = i - var/mob/living/mob = get(tool.loc, /mob/living) - if(mob && mob.mind && mob.stat == CONSCIOUS) - var/datum/antagonist/gang/gangster = mob.mind.has_antag_datum(/datum/antagonist/gang) - if(gangster.gang == src) - to_chat(mob, "[icon2html(tool, mob)] [message]") - playsound(mob.loc, 'sound/machines/twobeep.ogg', 50, 1) - return - -/datum/team/gang/proc/domination() - domination_time = world.time + determine_domination_time()*10 - set_security_level("delta") - -/datum/team/gang/proc/determine_domination_time() // calculates the value in seconds (this is the initial domination time!) - var/total_territories = total_claimable_territories() - return max(180,480 - (round((territories.len/total_territories)*100, 1) * 9)) - -/datum/team/gang/proc/domination_time_remaining() // retrieves the value from world.time based deciseconds to seconds - var/diff = domination_time - world.time - return round(diff * 0.1) - - -#undef MAXIMUM_RECALLS -#undef INFLUENCE_INTERVAL diff --git a/code/game/gamemodes/gangs/gang_datums.dm b/code/game/gamemodes/gangs/gang_datums.dm deleted file mode 100644 index c3a9cb0647..0000000000 --- a/code/game/gamemodes/gangs/gang_datums.dm +++ /dev/null @@ -1,139 +0,0 @@ -// Gang datums go here. If you want to create a new gang, you must be sure to edit: -// name -// color (must be a hex, "blue" isn't acceptable due to how spraycans are handled) -// inner_outfits (must be a list() with typepaths of the clothes in it. One is fine, but there is support for multiple: one will be picked at random when bought) -// outer_outfits (same as above) -// You also need to make a gang graffiti, that will go in crayondecal.dmi inside our icons, with the same name of the gang it's assigned to. Nothing else,just the icon. -// Those are all required. If one is missed, stuff could break. - -/datum/team/gang/clandestine - name = "Clandestine" - color = "#FF0000" - inner_outfits = list(/obj/item/clothing/under/syndicate/combat) - outer_outfits = list(/obj/item/clothing/suit/jacket) - -/datum/team/gang/prima - name = "Prima" - color = "#FFFF00" - inner_outfits = list(/obj/item/clothing/under/color/yellow) - outer_outfits = list(/obj/item/clothing/suit/hastur) - -/datum/team/gang/zerog - name = "Zero-G" - color = "#C0C0C0" - inner_outfits = list(/obj/item/clothing/under/suit/white) - outer_outfits = list(/obj/item/clothing/suit/hooded/wintercoat) - -/datum/team/gang/max - name = "Max" - color = "#800000" - inner_outfits = list(/obj/item/clothing/under/color/maroon) - outer_outfits = list(/obj/item/clothing/suit/poncho/red) - -/datum/team/gang/blasto - name = "Blasto" - color = "#000080" - inner_outfits = list(/obj/item/clothing/under/suit/navy) - outer_outfits = list(/obj/item/clothing/suit/jacket/miljacket) - -/datum/team/gang/waffle - name = "Waffle" - color = "#808000" //shared color with cyber, but they can keep brown cause waffles. - inner_outfits = list(/obj/item/clothing/under/suit/green) - outer_outfits = list(/obj/item/clothing/suit/poncho) - -/datum/team/gang/north - name = "North" - color = "#00FF00" - inner_outfits = list(/obj/item/clothing/under/color/green) - outer_outfits = list(/obj/item/clothing/suit/poncho/green) - -/datum/team/gang/omni - name = "Omni" - color = "#008080" - inner_outfits = list(/obj/item/clothing/under/color/teal) - outer_outfits = list(/obj/item/clothing/suit/chaplain/studentuni) - -/datum/team/gang/newton - name = "Newton" - color = "#A52A2A" - inner_outfits = list(/obj/item/clothing/under/color/brown) - outer_outfits = list(/obj/item/clothing/suit/toggle/owlwings) - -/datum/team/gang/cyber - name = "Cyber" - color = "#00f904" //Cyber and waffle shared colors, I made these guys green and made weed darker green. - inner_outfits = list(/obj/item/clothing/under/color/lightbrown) - outer_outfits = list(/obj/item/clothing/suit/chaplain/pharaoh) - -/datum/team/gang/donk - name = "Donk" - color = "#0000FF" - inner_outfits = list(/obj/item/clothing/under/color/darkblue) - outer_outfits = list(/obj/item/clothing/suit/apron/overalls) - -/datum/team/gang/gene - name = "Gene" - color = "#00FFFF" - inner_outfits = list(/obj/item/clothing/under/color/blue) - outer_outfits = list(/obj/item/clothing/suit/apron) - -/datum/team/gang/gib - name = "Gib" - color = "#636060" //Applying black to grayscale... Zero-G is already grey too. oh well. - inner_outfits = list(/obj/item/clothing/under/color/black) - outer_outfits = list(/obj/item/clothing/suit/jacket/leather/overcoat) - -/datum/team/gang/tunnel - name = "Tunnel" - color = "#FF00FF" //Gave the leather jacket to the tunnel gang over diablo. - inner_outfits = list(/obj/item/clothing/under/costume/villain) - outer_outfits = list(/obj/item/clothing/suit/jacket/leather) - -/datum/team/gang/diablo - name = "Diablo" - color = "#FF0000" //literal early 90s skinhead regalia. - inner_outfits = list(/obj/item/clothing/under/pants/classicjeans) - outer_outfits = list(/obj/item/clothing/suit/suspenders) - -/datum/team/gang/psyke - name = "Psyke" - color = "#808080" - inner_outfits = list(/obj/item/clothing/under/color/grey) - outer_outfits = list(/obj/item/clothing/suit/toggle/owlwings/griffinwings) - -/datum/team/gang/osiron - name = "Osiron" - color = "#FFFFFF" - inner_outfits = list(/obj/item/clothing/under/color/white) - outer_outfits = list(/obj/item/clothing/suit/toggle/labcoat) - -/datum/team/gang/sirius - name = "Sirius" - color = "#FFC0CB" - inner_outfits = list(/obj/item/clothing/under/color/pink) - outer_outfits = list(/obj/item/clothing/suit/jacket/puffer/vest) - -/datum/team/gang/sleepingcarp - name = "Sleeping Carp" - color = "#800080" - inner_outfits = list(/obj/item/clothing/under/color/lightpurple) - outer_outfits = list(/obj/item/clothing/suit/hooded/carp_costume) - -/datum/team/gang/h - name = "H" - color = "#993333" - inner_outfits = list(/obj/item/clothing/under/costume/jabroni) //Why not? - outer_outfits = list(/obj/item/clothing/suit/toggle/owlwings) - -/datum/team/gang/rigatonifamily - name = "Rigatoni family" - color = "#cc9900" // p a s t a colored - inner_outfits = list(/obj/item/clothing/under/rank/civilian/chef) - outer_outfits = list(/obj/item/clothing/suit/apron/chef) - -/datum/team/gang/weed - name = "Weed" - color = "#6cd648" - inner_outfits = list(/obj/item/clothing/under/color/darkgreen) - outer_outfits = list(/obj/item/clothing/suit/vapeshirt) diff --git a/code/game/gamemodes/gangs/gang_decals.dm b/code/game/gamemodes/gangs/gang_decals.dm deleted file mode 100644 index 75d8d459ef..0000000000 --- a/code/game/gamemodes/gangs/gang_decals.dm +++ /dev/null @@ -1,38 +0,0 @@ -/obj/effect/decal/cleanable/crayon/Initialize(mapload, main, type, e_name, graf_rot, alt_icon = null) - . = ..() - if(type == "poseur tag") - var/datum/team/gang/gang = pick(subtypesof(/datum/team/gang)) - var/gangname = initial(gang.name) - icon = 'icons/effects/crayondecal.dmi' - icon_state = "[gangname]" - type = null - -/obj/effect/decal/cleanable/crayon/gang - icon = 'icons/effects/crayondecal.dmi' - layer = ABOVE_NORMAL_TURF_LAYER //Harder to hide - plane = ABOVE_WALL_PLANE - do_icon_rotate = FALSE //These are designed to always face south, so no rotation please. - var/datum/team/gang/gang - -/obj/effect/decal/cleanable/crayon/gang/Initialize(mapload, datum/team/gang/G, e_name = "gang tag", rotation = 0, mob/user) - if(!G) - return INITIALIZE_HINT_QDEL - gang = G - var/newcolor = G.color - var/area/territory = get_base_area(src) - icon_state = G.name - G.new_territories |= list(territory.type = territory.name) - //If this isn't tagged by a specific gangster there's no bonus income. - .=..(mapload, newcolor, icon_state, e_name, rotation) - -/obj/effect/decal/cleanable/crayon/gang/Destroy() - if(gang) - var/area/territory = get_base_area(src) - gang.territories -= territory.type - gang.new_territories -= territory.type - gang.lost_territories |= list(territory.type = territory.name) - gang = null - return ..() - -/obj/effect/decal/cleanable/crayon/NeverShouldHaveComeHere(turf/T) - return isspaceturf(T) || islava(T) || istype(T, /turf/open/water) || ischasm(T) diff --git a/code/game/gamemodes/gangs/gang_hud.dm b/code/game/gamemodes/gangs/gang_hud.dm deleted file mode 100644 index 825d361ab0..0000000000 --- a/code/game/gamemodes/gangs/gang_hud.dm +++ /dev/null @@ -1,34 +0,0 @@ -/datum/atom_hud/antag/gang - var/color = null - -/datum/atom_hud/antag/gang/add_to_hud(atom/A) - if(!A) - return - var/image/holder = A.hud_list[ANTAG_HUD] - if(holder) - holder.color = color - ..() - -/datum/atom_hud/antag/gang/remove_from_hud(atom/A) - if(!A) - return - var/image/holder = A.hud_list[ANTAG_HUD] - if(holder) - holder.color = null - ..() - -/datum/atom_hud/antag/gang/join_hud(mob/M) - if(!istype(M)) - CRASH("join_hud(): [M] ([M.type]) is not a mob!") - var/image/holder = M.hud_list[ANTAG_HUD] - if(holder) - holder.color = color - ..() - -/datum/atom_hud/antag/gang/leave_hud(mob/M) - if(!istype(M)) - CRASH("leave_hud(): [M] ([M.type]) is not a mob!") - var/image/holder = M.hud_list[ANTAG_HUD] - if(holder) - holder.color = null - ..() diff --git a/code/game/gamemodes/gangs/gang_items.dm b/code/game/gamemodes/gangs/gang_items.dm deleted file mode 100644 index d1cf006600..0000000000 --- a/code/game/gamemodes/gangs/gang_items.dm +++ /dev/null @@ -1,411 +0,0 @@ -/datum/gang_item - var/name - var/item_path - var/cost - var/spawn_msg - var/category - var/list/gang_whitelist = list() - var/list/gang_blacklist = list() - var/id - -/datum/gang_item/proc/purchase(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool, check_canbuy = TRUE) - if(check_canbuy && !can_buy(user, gang, gangtool)) - return FALSE - var/real_cost = get_cost(user, gang, gangtool) - if(!spawn_item(user, gang, gangtool)) - gang.adjust_influence(-real_cost) - to_chat(user, "You bought \the [name].") - return TRUE - -/datum/gang_item/proc/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) // If this returns anything other than null, something fucked up and influence won't lower. - if(item_path) - var/obj/item/O = new item_path(user.loc) - user.put_in_hands(O) - else - return TRUE - if(spawn_msg) - to_chat(user, "[spawn_msg]") - -/datum/gang_item/proc/can_buy(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - return gang && (gang.influence >= get_cost(user, gang, gangtool)) && can_see(user, gang, gangtool) - -/datum/gang_item/proc/can_see(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - return TRUE - -/datum/gang_item/proc/get_cost(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - return cost - -/datum/gang_item/proc/get_cost_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - return "([get_cost(user, gang, gangtool)] Influence)" - -/datum/gang_item/proc/get_name_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - return name - -/datum/gang_item/proc/get_extra_info(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - return - -/////////////////// -//CLOTHING -/////////////////// - -/datum/gang_item/clothing - category = "Purchase Gang Clothes (Only the jumpsuit and suit give you added influence):" - -/datum/gang_item/clothing/under - name = "Gang Uniform" - id = "under" - cost = 1 - -/datum/gang_item/clothing/under/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - if(gang.inner_outfits.len) - var/outfit = pick(gang.inner_outfits) - if(outfit) - var/obj/item/O = new outfit(user.loc) - user.put_in_hands(O) - to_chat(user, " This is your gang's official uniform, wearing it will increase your influence") - return - return TRUE - -/datum/gang_item/clothing/suit - name = "Gang Armored Outerwear" - id = "suit" - cost = 1 - -/datum/gang_item/clothing/suit/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - if(gang.outer_outfits.len) - var/outfit = pick(gang.outer_outfits) - if(outfit) - var/obj/item/O = new outfit(user.loc) - O.armor = O.armor.setRating(melee = 25, bullet = 35, laser = 15, energy = 10, bomb = 30, bio = 0, rad = 0, fire = 30, acid = 30) - O.desc += " Tailored for the [gang.name] Gang to offer the wearer moderate protection against ballistics and physical trauma." - user.put_in_hands(O) - to_chat(user, " This is your gang's official outerwear, wearing it will increase your influence") - return - return TRUE - -/datum/gang_item/clothing/hat - name = "Pimp Hat" - id = "hat" - cost = 16 - item_path = /obj/item/clothing/head/collectable/petehat/gang - -/obj/item/clothing/head/collectable/petehat/gang - name = "pimpin' hat" - desc = "The undisputed king of style." - -/datum/gang_item/clothing/mask - name = "Golden Death Mask" - id = "mask" - cost = 18 - item_path = /obj/item/clothing/mask/gskull - -/obj/item/clothing/mask/gskull - name = "golden death mask" - icon_state = "gskull" - desc = "Strike terror, and envy, into the hearts of your enemies." - -/datum/gang_item/clothing/shoes - name = "Bling Boots" - id = "boots" - cost = 20 - item_path = /obj/item/clothing/shoes/gang - -/obj/item/clothing/shoes/gang - name = "blinged-out boots" - desc = "Stand aside peasants." - icon_state = "bling" - -/datum/gang_item/clothing/neck - name = "Gold Necklace" - id = "necklace" - cost = 9 - item_path = /obj/item/clothing/neck/necklace/dope - -/datum/gang_item/clothing/hands - name = "Decorative Brass Knuckles" - id = "hand" - cost = 11 - item_path = /obj/item/clothing/gloves/gang - -/obj/item/clothing/gloves/gang - name = "braggadocio's brass knuckles" - desc = "Purely decorative, don't find out the hard way." - icon_state = "knuckles" - w_class = 3 - -/datum/gang_item/clothing/shades //Addition: Why not have cool shades on a gang member anyways? - name = "Cool Sunglasses" - id = "glasses" - cost = 5 - item_path = /obj/item/clothing/glasses/sunglasses - -/datum/gang_item/clothing/belt - name = "Badass Belt" - id = "belt" - cost = 13 - item_path = /obj/item/storage/belt/military/gang - -/obj/item/storage/belt/military/gang - name = "badass belt" - icon_state = "gangbelt" - item_state = "gang" - desc = "The belt buckle simply reads 'BAMF'." - -/////////////////// -//WEAPONS -/////////////////// - -/datum/gang_item/weapon - category = "Purchase Weapons:" - -/datum/gang_item/weapon/ammo - -/datum/gang_item/weapon/shuriken - name = "Shuriken" - id = "shuriken" - cost = 2 - item_path = /obj/item/throwing_star - -/datum/gang_item/weapon/switchblade - name = "Switchblade" - id = "switchblade" - cost = 5 - item_path = /obj/item/switchblade - -/datum/gang_item/weapon/surplus //For when a gang boss is extra broke or cheap. - name = "Surplus Rifle" - id = "surplus" - cost = 6 - item_path = /obj/item/gun/ballistic/automatic/surplus - -/datum/gang_item/weapon/ammo/surplus_ammo - name = "Surplus Rifle Ammo" - id = "surplus_ammo" - cost = 3 - item_path = /obj/item/ammo_box/magazine/m10mm/rifle - -/datum/gang_item/weapon/improvised - name = "Sawn-Off Improvised Shotgun" - id = "sawn" - cost = 5 - item_path = /obj/item/gun/ballistic/revolver/doublebarrel/improvised/sawn - -/datum/gang_item/weapon/ammo/improvised_ammo - name = "Box of Buckshot" - id = "buckshot" - cost = 5 - item_path = /obj/item/storage/box/lethalshot - -/datum/gang_item/weapon/pistol - name = "10mm Pistol" - id = "pistol" - cost = 25 - item_path = /obj/item/gun/ballistic/automatic/pistol - -/datum/gang_item/weapon/ammo/pistol_ammo - name = "10mm Ammo" - id = "pistol_ammo" - cost = 10 - item_path = /obj/item/ammo_box/magazine/m10mm - -/datum/gang_item/weapon/sniper - name = "Black Market .50cal Sniper Rifle" - id = "sniper" - cost = 35 - item_path = /obj/item/gun/ballistic/automatic/sniper_rifle - -/datum/gang_item/weapon/ammo/sniper_ammo - name = "Smuggled .50cal Sniper Rounds" - id = "sniper_ammo" - cost = 15 - item_path = /obj/item/ammo_box/magazine/sniper_rounds - -/*/datum/gang_item/weapon/ammo/sleeper_ammo //no. absolutely no. - name = "Illicit Soporific Cartridges" - id = "sniper_ammo" - cost = 15 //who the fuck thought a ONE-HIT K.O. for 15 gbp IN AN ENVIRONMENT WHERE WE'RE GETTING RID OF HARDSTUNS is a GOOD IDEA - item_path = /obj/item/ammo_box/magazine/sniper_rounds/soporific*/ - -/datum/gang_item/weapon/machinegun - name = "Mounted Machine Gun" - id = "MG" - cost = 45 - item_path = /obj/machinery/manned_turret - spawn_msg = "The mounted machine gun features enhanced responsiveness. Hold down on the trigger while firing to control where you're shooting." - -/datum/gang_item/weapon/machinegun/spawn_item(mob/living/carbon/user, obj/item/device/gangtool/gangtool) - new item_path(user.loc) - to_chat(user, spawn_msg) - -/datum/gang_item/weapon/uzi - name = "Uzi SMG" - id = "uzi" - cost = 50 - item_path = /obj/item/gun/ballistic/automatic/mini_uzi - -/datum/gang_item/weapon/ammo/uzi_ammo - name = "Uzi Ammo" - id = "uzi_ammo" - cost = 20 - item_path = /obj/item/ammo_box/magazine/uzim9mm - -/////////////////// -//EQUIPMENT -/////////////////// - -/datum/gang_item/equipment - category = "Purchase Equipment:" - -/datum/gang_item/equipment/spraycan - name = "Territory Spraycan" - id = "spraycan" - cost = 1 - item_path = /obj/item/toy/crayon/spraycan/gang - -/datum/gang_item/equipment/spraycan/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - var/obj/item/O = new item_path(user.loc, gang) - user.put_in_hands(O) - -/datum/gang_item/equipment/sharpener - name = "Sharpener" - id = "whetstone" - cost = 3 - item_path = /obj/item/sharpener - -/datum/gang_item/equipment/emp - name = "EMP Grenade" - id = "EMP" - cost = 7 - item_path = /obj/item/grenade/empgrenade - -/datum/gang_item/equipment/c4 - name = "C4 Explosive" - id = "c4" - cost = 7 - item_path = /obj/item/grenade/plastic/c4 - -/datum/gang_item/equipment/frag - name = "Fragmentation Grenade" - id = "frag nade" - cost = 5 - item_path = /obj/item/grenade/frag - -/datum/gang_item/equipment/implant_breaker - name = "Implant Breaker" - id = "implant_breaker" - cost = 10 - item_path = /obj/item/implanter/gang - -/datum/gang_item/equipment/implant_breaker/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - var/obj/item/O = new item_path(user.loc, gang) - user.put_in_hands(O) - to_chat(user, "The implant breaker is a single-use device that destroys all implants within the target before trying to recruit them to your gang. Also works on enemy gangsters.") - -/datum/gang_item/equipment/wetwork_boots - name = "Wetwork boots" - id = "wetwork" - cost = 8 - item_path = /obj/item/clothing/shoes/combat/gang - -/obj/item/clothing/shoes/combat/gang - name = "Wetwork boots" - desc = "A gang's best hitmen are prepared for anything." - permeability_coefficient = 0.01 - clothing_flags = NOSLIP - -/datum/gang_item/equipment/shield - name = "Riot Shield" - id = "riot_shield" - cost = 25 - item_path = /obj/item/shield/riot - -/datum/gang_item/equipment/gangsheild - name = "Tower Shield" - id = "metal" - cost = 45 //High block of melee and even higher for bullets - item_path = /obj/item/shield/riot/tower - -/datum/gang_item/equipment/pen - name = "Recruitment Pen" - id = "pen" - cost = 20 - item_path = /obj/item/pen/gang - spawn_msg = "More recruitment pens will allow you to recruit gangsters faster. Only gang leaders can recruit with pens." - -/datum/gang_item/equipment/pen/purchase(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - if(..()) - gangtool.free_pen = FALSE - return TRUE - return FALSE - -/datum/gang_item/equipment/pen/get_cost(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - if(gangtool && gangtool.free_pen) - return 0 - return ..() - -/datum/gang_item/equipment/pen/get_cost_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - if(gangtool && gangtool.free_pen) - return "(GET ONE FREE)" - return ..() - -/datum/gang_item/equipment/gangtool - id = "gangtool" - cost = 5 - -/datum/gang_item/equipment/gangtool/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - var/item_type - if(gang) - item_type = /obj/item/device/gangtool/spare/lt - if(gang.leaders.len < MAX_LEADERS_GANG) - to_chat(user, "Gangtools allow you to promote a gangster to be your Lieutenant, enabling them to recruit and purchase items like you. Simply have them register the gangtool. You may promote up to [MAX_LEADERS_GANG-gang.leaders.len] more Lieutenants") - else - item_type = /obj/item/device/gangtool/spare - var/obj/item/device/gangtool/spare/tool = new item_type(user.loc) - user.put_in_hands(tool) - -/datum/gang_item/equipment/gangtool/get_name_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - if(gang && (gang.leaders.len < gang.max_leaders)) - return "Promote a Gangster" - return "Spare Gangtool" - -/datum/gang_item/equipment/dominator - name = "Station Dominator" - id = "dominator" - cost = 30 - item_path = /obj/machinery/dominator - spawn_msg = "The dominator will secure your gang's dominance over the station. Turn it on when you are ready to defend it." - -/datum/gang_item/equipment/dominator/can_buy(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - if(!gang || !gang.dom_attempts) - return FALSE - return ..() - -/datum/gang_item/equipment/dominator/get_name_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - if(!gang || !gang.dom_attempts) - return ..() - return "[..()]" - -/datum/gang_item/equipment/dominator/get_cost_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - if(!gang || !gang.dom_attempts) - return "(Out of stock)" - return ..() - -/datum/gang_item/equipment/dominator/get_extra_info(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - if(gang) - return "This device requires a 5x5 area clear of walls to FUNCTION. (Estimated Takeover Time: [round(gang.determine_domination_time()/60,0.1)] minutes)" - -/datum/gang_item/equipment/dominator/purchase(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - var/area/userarea = get_base_area(user) - if(!(userarea.type in gang.territories|gang.new_territories)) - to_chat(user,"The dominator can be spawned only on territory controlled by your gang!") - return FALSE - for(var/obj/obj in get_turf(user)) - if(obj.density) - to_chat(user, "There's not enough room here!") - return FALSE - - return ..() - -/datum/gang_item/equipment/dominator/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - new item_path(user.loc) - to_chat(user, spawn_msg) diff --git a/code/game/gamemodes/gangs/gang_pen.dm b/code/game/gamemodes/gangs/gang_pen.dm deleted file mode 100644 index 09cea5cecb..0000000000 --- a/code/game/gamemodes/gangs/gang_pen.dm +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Gang Boss Pens - */ -/obj/item/pen/gang - var/cooldown - var/last_used - -/obj/item/pen/gang/Initialize() - . = ..() - last_used = world.time - -/obj/item/pen/gang/attack(mob/living/M, mob/user, stealth = TRUE) //ha - if(!istype(M)) - return - if(!ishuman(M) || !ishuman(user) || M.stat == DEAD) - return ..() - //var/datum/antagonist/gang/boss/L = user.mind.has_antag_datum(/datum/antagonist/gang/boss) //Pen works with bosses only. - var/datum/antagonist/gang/L = user.mind.has_antag_datum(/datum/antagonist/gang) //Pen works with anyone in gang. - if(!L) - return ..() - if(!..()) - return - if(cooldown) - to_chat(user, "[src] needs more time to recharge before it can be used.") - return - if(!M.client || !M.mind) - to_chat(user, "A braindead gangster is an useless gangster!") - return - var/datum/team/gang/gang = L.gang - if(!add_gangster(user, gang, M.mind)) - return - cooldown = TRUE - icon_state = "pen_blink" - var/cooldown_time = 600/gang.leaders.len - addtimer(CALLBACK(src, .proc/cooldown), cooldown_time) - -/obj/item/pen/gang/proc/cooldown() - cooldown = FALSE - icon_state = "pen" - var/mob/M = loc - if(istype(M)) - to_chat(M, "[icon2html(src, M)] [src][(loc == M)?(""):(" in your [loc]")] vibrates softly. It is ready to be used again.") - -/obj/item/pen/gang/proc/add_gangster(mob/user, datum/team/gang/gang, datum/mind/gangster_mind, check = TRUE) // Basically a wrapper to add_antag_datum. - var/datum/antagonist/dudegang = gangster_mind.has_antag_datum(/datum/antagonist/gang) - if(dudegang) - if(dudegang == gang) - to_chat(user, "This mind is already controlled by your gang!") - return - to_chat(user, "This mind is already controlled by someone else!") - return - if(check && HAS_TRAIT(gangster_mind.current, TRAIT_MINDSHIELD)) //Check to see if the potential gangster is implanted - to_chat(user, "This mind is too strong to control!") - return - var/mob/living/carbon/human/H = gangster_mind.current // we are sure the dude's human cause it's checked in attack() - H.silent = max(H.silent, 5) - H.DefaultCombatKnockdown(100) - gangster_mind.add_antag_datum(/datum/antagonist/gang, gang) - return TRUE diff --git a/code/game/gamemodes/gangs/gangs.dm b/code/game/gamemodes/gangs/gangs.dm deleted file mode 100644 index 100669c487..0000000000 --- a/code/game/gamemodes/gangs/gangs.dm +++ /dev/null @@ -1,67 +0,0 @@ -//gang.dm -//Gang War Game Mode -GLOBAL_LIST_INIT(possible_gangs, subtypesof(/datum/team/gang)) -GLOBAL_LIST_EMPTY(gangs) -/datum/game_mode/gang - name = "gang war" - config_tag = "gang" - antag_flag = ROLE_GANG - chaos = 9 - restricted_jobs = list("AI", "Cyborg") - protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") - required_players = 15 - required_enemies = 0 - recommended_enemies = 2 - enemy_minimum_age = 14 - - announce_span = "danger" - announce_text = "A violent turf war has erupted on the station!\n\ - Gangsters: Take over the station with a dominator.\n\ - Crew: Prevent the gangs from expanding and initiating takeover." - - var/list/datum/mind/gangboss_candidates = list() - -/datum/game_mode/gang/generate_report() - return "Cybersun Industries representatives claimed that they, in joint research with the Tiger Cooperative, have made a major breakthrough in brainwashing technology, and have \ - made the nanobots that apply the \"conversion\" very small and capable of fitting into usually innocent objects - namely, pens. While they refused to outsource this technology for \ - months to come due to its flaws, they reported some as missing but passed it off to carelessness. At Central Command, we don't like mysteries, and we have reason to believe that this \ - technology was stolen for anti-Nanotrasen use. Be on the lookout for territory claims and unusually violent crew behavior, applying mindshield implants as necessary." - -/datum/game_mode/gang/pre_setup() - if(CONFIG_GET(flag/protect_roles_from_antagonist)) - restricted_jobs += protected_jobs - - if(CONFIG_GET(flag/protect_assistant_from_antagonist)) - restricted_jobs += "Assistant" - - //Spawn more bosses depending on server population - var/gangs_to_create = 2 - if(prob(num_players()) && num_players() > 1.5*required_players) - gangs_to_create++ - if(prob(num_players()) && num_players() > 2*required_players) - gangs_to_create++ - gangs_to_create = min(gangs_to_create, GLOB.possible_gangs.len) - - for(var/i in 1 to gangs_to_create) - if(!antag_candidates.len) - break - - //Now assign a boss for the gang - var/datum/mind/boss = pick_n_take(antag_candidates) - antag_candidates -= boss - gangboss_candidates += boss - boss.restricted_roles = restricted_jobs - - if(gangboss_candidates.len < 1) //Need at least one gangs - return - - return TRUE - -/datum/game_mode/gang/post_setup() - set waitfor = FALSE - ..() - for(var/i in gangboss_candidates) - var/datum/mind/M = i - var/datum/antagonist/gang/boss/B = new() - M.add_antag_datum(B) - B.equip_gang() diff --git a/code/game/gamemodes/gangs/gangtool.dm b/code/game/gamemodes/gangs/gangtool.dm deleted file mode 100644 index 32272ae51a..0000000000 --- a/code/game/gamemodes/gangs/gangtool.dm +++ /dev/null @@ -1,259 +0,0 @@ -//gangtool device -/obj/item/device/gangtool - name = "suspicious device" - desc = "A strange device of sorts. Hard to really make out what it actually does if you don't know how to operate it." - icon = 'icons/obj/device.dmi' - icon_state = "gangtool" - item_state = "radio" - lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' - righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - throwforce = 0 - w_class = WEIGHT_CLASS_TINY - throw_speed = 3 - throw_range = 7 - flags_1 = CONDUCT_1 - var/datum/team/gang/gang //Which gang uses this? - var/recalling = 0 - var/outfits = 2 - var/free_pen = 0 - var/promotable = FALSE - var/static/list/buyable_items = list() - var/list/tags = list() - -/obj/item/device/gangtool/Initialize() - . = ..() - update_icon() - for(var/i in subtypesof(/datum/gang_item)) - var/datum/gang_item/G = i - var/id = initial(G.id) - var/cat = initial(G.category) - if(id) - if(!islist(buyable_items[cat])) - buyable_items[cat] = list() - buyable_items[cat][id] = new G -/obj/item/device/gangtool/Destroy() - if(gang) - gang.gangtools -= src - return ..() - -/obj/item/device/gangtool/attack_self(mob/user) - ..() - if (!can_use(user)) - return - var/datum/antagonist/gang/boss/L = user.mind.has_antag_datum(/datum/antagonist/gang/boss) - var/dat - if(!gang) - dat += "This device is not registered.

    " - if(L) - if(promotable && L.gang.leaders.len < L.gang.max_leaders) - dat += "Give this device to another member of your organization to use to promote them to Lieutenant.

    " - dat += "If this is meant as a spare device for yourself:
    " - dat += "Register Device as Spare
    " - else if(promotable) - var/datum/antagonist/gang/sweet = user.mind.has_antag_datum(/datum/antagonist/gang) - if(sweet.gang.leaders.len < sweet.gang.max_leaders) - dat += "You have been selected for a promotion!
    " - dat += "Accept Promotion
    " - else - dat += "No promotions available: All positions filled.
    " - else - dat += "This device is not authorized to promote.
    " - else - if(gang.domination_time != NOT_DOMINATING) - dat += "
    Takeover In Progress:
    [DisplayTimeText(gang.domination_time_remaining() * 10)] remain
    " - - dat += "Registration: [gang.name] Gang Boss
    " - dat += "Organization Size: [gang.members.len] | Station Control: [gang.territories.len] territories under control. | Influence: [gang.influence]
    " - dat += "Time until Influence grows: [time2text(gang.next_point_time - world.time, "mm:ss")]
    " - dat += "Send message to Gang
    " - dat += "Recall shuttle
    " - dat += "
    " - for(var/cat in buyable_items) - dat += "[cat]
    " - for(var/id in buyable_items[cat]) - var/datum/gang_item/G = buyable_items[cat][id] - if(!G.can_see(user, gang, src)) - continue - - var/cost = G.get_cost_display(user, gang, src) - if(cost) - dat += cost + " " - - var/toAdd = G.get_name_display(user, gang, src) - if(G.can_buy(user, gang, src)) - toAdd = "[toAdd]" - dat += toAdd - var/extra = G.get_extra_info(user, gang, src) - if(extra) - dat += "
    [extra]" - dat += "
    " - dat += "
    " - - dat += "Refresh
    " - - var/datum/browser/popup = new(user, "gangtool", "Welcome to GangTool v4.0", 340, 625) - popup.set_content(dat) - popup.open() - -/obj/item/device/gangtool/Topic(href, href_list) - if(!can_use(usr)) - return - - add_fingerprint(usr) - - if(href_list["register"]) - register_device(usr) - - else if(!gang) //Gangtool must be registered before you can use the functions below - return - - if(href_list["purchase"]) - if(islist(buyable_items[href_list["cat"]])) - var/list/L = buyable_items[href_list["cat"]] - var/datum/gang_item/G = L[href_list["id"]] - if(G && G.can_buy(usr, gang, src)) - G.purchase(usr, gang, src, FALSE) - - if(href_list["commute"]) - ping_gang(usr) - if(href_list["recall"]) - recall(usr) - attack_self(usr) - -/obj/item/device/gangtool/update_icon() - overlays.Cut() - var/image/I = new(icon, "[icon_state]-overlay") - if(gang) - I.color = gang.color - overlays.Add(I) - -/obj/item/device/gangtool/proc/ping_gang(mob/user) - if(!can_use(user)) - return - var/message = stripped_input(user,"Discreetly send a gang-wide message.","Send Message") - if(!message || !can_use(user)) - return - if(!is_station_level(user.z)) - to_chat(user, "[icon2html(src, user)]Error: Station out of range.") - return - if(gang.members.len) - var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang) - if(!G) - return - var/ping = "[gang.name] [G.message_name] [user.real_name]: [message]" - for(var/datum/mind/ganger in gang.members) - if(ganger.current && is_station_level(ganger.current.z) && (ganger.current.stat == CONSCIOUS)) - to_chat(ganger.current, ping) - for(var/mob/M in GLOB.dead_mob_list) - var/link = FOLLOW_LINK(M, user) - to_chat(M, "[link] [ping]") - user.log_talk(message,LOG_SAY, tag="[gang.name] gangster") - -/obj/item/device/gangtool/proc/register_device(mob/user) - if(gang) //It's already been registered! - return - var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang) - if(G) - gang = G.gang - gang.gangtools += src - update_icon() - if(!(user.mind in gang.leaders) && promotable) - G.promote() - free_pen = TRUE - gang.message_gangtools("[user] has been promoted to Lieutenant.") - to_chat(user, "The Gangtool you registered will allow you to purchase weapons and equipment, and send messages to your gang.") - to_chat(user, "Unlike regular gangsters, you may use recruitment pens to add recruits to your gang. Use them on unsuspecting crew members to recruit them. Don't forget to get your one free pen from the gangtool.") - else - to_chat(user, "ACCESS DENIED: Unauthorized user.") - -/obj/item/device/gangtool/proc/recall(mob/user) - if(!recallchecks(user)) - return - if(recalling) - to_chat(user, "Error: Recall already in progress.") - return - gang.message_gangtools("[user] is attempting to recall the emergency shuttle.") - recalling = TRUE - to_chat(user, "[icon2html(src, loc)]Generating shuttle recall order with codes retrieved from last call signal...") - addtimer(CALLBACK(src, .proc/recall2, user), rand(100,300)) - -/obj/item/device/gangtool/proc/recall2(mob/user) - if(!recallchecks(user)) - return - to_chat(user, "[icon2html(src, loc)]Shuttle recall order generated. Accessing station long-range communication arrays...") - addtimer(CALLBACK(src, .proc/recall3, user), rand(100,300)) - -/obj/item/device/gangtool/proc/recall3(mob/user) - if(!recallchecks(user)) - return - var/list/living_crew = list()//shamelessly copied from mulligan code, there should be a helper for this - for(var/mob/Player in GLOB.mob_list) - if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) && !isbrain(Player) && Player.client) - living_crew += Player - var/malc = CONFIG_GET(number/midround_antag_life_check) - if(living_crew.len / GLOB.joined_player_list.len <= malc) //Shuttle cannot be recalled if too many people died - to_chat(user, "[icon2html(src, user)]Error: Station communication systems compromised. Unable to establish connection.") - recalling = FALSE - return - to_chat(user, "[icon2html(src, loc)]Comm arrays accessed. Broadcasting recall signal...") - addtimer(CALLBACK(src, .proc/recallfinal, user), rand(100,300)) - -/obj/item/device/gangtool/proc/recallfinal(mob/user) - if(!recallchecks(user)) - return - recalling = FALSE - log_game("[key_name(user)] has tried to recall the shuttle with a gangtool.") - message_admins("[key_name_admin(user)] has tried to recall the shuttle with a gangtool.", 1) - if(SSshuttle.cancelEvac(user)) - gang.recalls-- - return TRUE - - to_chat(user, "[icon2html(src, loc)]No response recieved. Emergency shuttle cannot be recalled at this time.") - return - -/obj/item/device/gangtool/proc/recallchecks(mob/user) - if(!can_use(user)) - return - if(SSshuttle.emergencyNoRecall) - return - if(!gang.recalls) - to_chat(user, "Error: Unable to access communication arrays. Firewall has logged our signature and is blocking all further attempts.") - return - if(SSshuttle.emergency.mode != SHUTTLE_CALL) //Shuttle can only be recalled when it's moving to the station - to_chat(user, "[icon2html(src, user)]Emergency shuttle cannot be recalled at this time.") - recalling = FALSE - return - if(!gang.dom_attempts) - to_chat(user, "[icon2html(src, user)]Error: Unable to access communication arrays. Firewall has logged our signature and is blocking all further attempts.") - recalling = FALSE - return - if(!is_station_level(user.z)) //Shuttle can only be recalled while on station - to_chat(user, "[icon2html(src, user)]Error: Device out of range of station communication arrays.") - recalling = FALSE - return - return TRUE - -/obj/item/device/gangtool/proc/can_use(mob/living/carbon/human/user) - if(!istype(user)) - return - if(user.incapacitated()) - return - if(!(src in user.contents)) - return - if(!user.mind) - return - var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang) - if(!G) - to_chat(user, "Huh, what's this?") - return - if(!isnull(gang) && G.gang != gang) - to_chat(user, "You cannot use gang tools owned by enemy gangs!") - return - return TRUE - - -/obj/item/device/gangtool/spare - outfits = TRUE - -/obj/item/device/gangtool/spare/lt - promotable = TRUE diff --git a/code/game/gamemodes/gangs/implant_gang.dm b/code/game/gamemodes/gangs/implant_gang.dm deleted file mode 100644 index cad54d4fc1..0000000000 --- a/code/game/gamemodes/gangs/implant_gang.dm +++ /dev/null @@ -1,61 +0,0 @@ -/obj/item/implant/gang - name = "gang implant" - desc = "Makes you a gangster or such." - activated = 0 - var/datum/team/gang/gang - -/obj/item/implant/gang/Initialize(loc, setgang) - .=..() - gang = setgang - -/obj/item/implant/gang/Destroy() - gang = null - return ..() - -/obj/item/implant/gang/get_data() - var/dat = {"Implant Specifications:
    - Name: Criminal brainwash implant
    - Life: A few seconds after injection.
    - Important Notes: Illegal
    -
    - Implant Details:
    - Function: Contains a small pod of nanobots that change the host's brain to be loyal to a certain organization.
    - Special Features: This device will also emit a small EMP pulse, destroying any other implants within the host's brain.
    - Integrity: Implant's EMP function will destroy itself in the process."} - return dat - -/obj/item/implant/gang/implant(mob/living/target, mob/user, silent = 0) - if(!target || !target.mind || target.stat == DEAD) - return 0 - var/datum/antagonist/gang/G = target.mind.has_antag_datum(/datum/antagonist/gang) - if(G && G.gang == G) - return 0 // it's pointless - if(..()) - for(var/obj/item/implant/I in target.implants) - if(I != src) - qdel(I) - - if(ishuman(target)) - var/success - if(G) - if(!istype(G, /datum/antagonist/gang/boss)) - success = TRUE //Was not a gang boss, convert as usual - target.mind.remove_antag_datum(/datum/antagonist/gang) - else - success = TRUE - if(!success) - target.visible_message("[target] seems to resist the implant!", "You feel the influence of your enemies try to invade your mind!") - return FALSE - target.mind.add_antag_datum(/datum/antagonist/gang, gang) - qdel(src) - return TRUE - -/obj/item/implanter/gang - name = "implanter (gang)" - -/obj/item/implanter/gang/Initialize(loc, gang) - if(!gang) - qdel(src) - return - imp = new /obj/item/implant/gang(src,gang) - .=..() diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index 9953b593d9..446573e2af 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -281,7 +281,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event var/meteorgibs = /obj/effect/gibspawner/generic threat = 2 -/obj/effect/meteor/meaty/Initialize() +/obj/effect/meteor/meaty/Initialize(mapload) for(var/path in meteordrop) if(path == /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant) meteordrop -= path @@ -312,7 +312,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event meteordrop = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno, /obj/item/organ/tongue/alien) meteorgibs = /obj/effect/gibspawner/xeno -/obj/effect/meteor/meaty/xeno/Initialize() +/obj/effect/meteor/meaty/xeno/Initialize(mapload) meteordrop += subtypesof(/obj/item/organ/alien) return ..() @@ -363,7 +363,7 @@ GLOBAL_LIST_INIT(meteorsSPOOKY, list(/obj/effect/meteor/pumpkin)) meteordrop = list(/obj/item/clothing/head/hardhat/pumpkinhead, /obj/item/reagent_containers/food/snacks/grown/pumpkin) threat = 100 -/obj/effect/meteor/pumpkin/Initialize() +/obj/effect/meteor/pumpkin/Initialize(mapload) . = ..() meteorsound = pick('sound/hallucinations/im_here1.ogg','sound/hallucinations/im_here2.ogg') ////////////////////////// diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index dcf84e84db..f7ccae24e4 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -127,7 +127,7 @@ l_pocket = /obj/item/pinpointer/nuke/syndicate id = /obj/item/card/id/syndicate belt = /obj/item/gun/ballistic/automatic/pistol - backpack_contents = list(/obj/item/storage/box/syndie=1,\ + backpack_contents = list(/obj/item/storage/box/survival/syndie=1,\ /obj/item/kitchen/knife/combat/survival) var/tc = 25 @@ -154,7 +154,7 @@ if(tc) var/obj/item/U = new uplink_type(H, H.key, tc) - H.equip_to_slot_or_del(U, SLOT_IN_BACKPACK) + H.equip_to_slot_or_del(U, ITEM_SLOT_BACKPACK) var/obj/item/implant/weapons_auth/W = new W.implant(H) @@ -170,10 +170,10 @@ mask = /obj/item/clothing/mask/gas/syndicate suit = /obj/item/clothing/suit/space/hardsuit/syndi r_pocket = /obj/item/tank/internals/emergency_oxygen/engi - internals_slot = SLOT_R_STORE + internals_slot = ITEM_SLOT_RPOCKET belt = /obj/item/storage/belt/military r_hand = /obj/item/gun/ballistic/automatic/shotgun/bulldog - backpack_contents = list(/obj/item/storage/box/syndie=1,\ + backpack_contents = list(/obj/item/storage/box/survival/syndie=1,\ /obj/item/tank/jetpack/oxygen/harness=1,\ /obj/item/gun/ballistic/automatic/pistol=1,\ /obj/item/kitchen/knife/combat/survival) @@ -186,9 +186,9 @@ suit = /obj/item/clothing/suit/space/syndicate/black/red head = /obj/item/clothing/head/helmet/space/syndicate/black/red r_pocket = /obj/item/tank/internals/emergency_oxygen/engi - internals_slot = SLOT_R_STORE + internals_slot = ITEM_SLOT_RPOCKET belt = /obj/item/storage/belt/military - backpack_contents = list(/obj/item/storage/box/syndie=1,\ + backpack_contents = list(/obj/item/storage/box/survival/syndie=1,\ /obj/item/tank/jetpack/oxygen/harness=1,\ /obj/item/gun/ballistic/automatic/pistol=1,\ /obj/item/kitchen/knife/combat/survival) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index fcfddb2788..bf45fe7efe 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -13,6 +13,7 @@ GLOBAL_LIST_EMPTY(objectives) var/completed = FALSE //currently only used for custom objectives. var/completable = TRUE //Whether this objective shows greentext when completed var/martyr_compatible = FALSE //If the objective is compatible with martyr objective, i.e. if you can still do it while dead. + var/objective_name = "Objective" //name used in printing this objective (Objective #1) /datum/objective/New(var/text) GLOB.objectives += src // CITADEL EDIT FOR CRYOPODS @@ -160,12 +161,14 @@ If not set, defaults to check_completion instead. Set it. It's used by cryo. /datum/objective/proc/give_special_equipment(special_equipment) var/datum/mind/receiver = pick(get_owners()) + . = list() if(receiver && receiver.current) if(ishuman(receiver.current)) var/mob/living/carbon/human/H = receiver.current - var/list/slots = list("backpack" = SLOT_IN_BACKPACK) + var/list/slots = list("backpack" = ITEM_SLOT_BACKPACK) for(var/eq_path in special_equipment) var/obj/O = new eq_path + . += O H.equip_in_one_of_slots(O, slots, critical = TRUE) /datum/objective/assassinate @@ -560,6 +563,7 @@ GLOBAL_LIST_EMPTY(possible_items) name = "steal" var/datum/objective_item/targetinfo = null //Save the chosen item datum so we can access it later. var/obj/item/steal_target = null //Needed for custom objectives (they're just items, not datums). + var/list/special_items_given = list() martyr_compatible = 0 /datum/objective/steal/get_target() @@ -571,6 +575,11 @@ GLOBAL_LIST_EMPTY(possible_items) for(var/I in subtypesof(/datum/objective_item/steal)) new I +/datum/objective/steal/Destroy(force, ...) + if(length(special_items_given)) + QDEL_LIST(special_items_given) + . = ..() + /datum/objective/steal/find_target(dupe_search_range, blacklist) var/list/datum/mind/owners = get_owners() var/approved_targets = list() @@ -589,7 +598,7 @@ GLOBAL_LIST_EMPTY(possible_items) targetinfo = item steal_target = targetinfo.targetitem explanation_text = "Steal [targetinfo.name]" - give_special_equipment(targetinfo.special_equipment) + special_items_given = give_special_equipment(targetinfo.special_equipment) return steal_target else explanation_text = "Free objective" @@ -770,6 +779,24 @@ GLOBAL_LIST_EMPTY(possible_items_special) target_amount = count update_explanation_text() */ +/datum/objective/protect_object + name = "protect object" + var/obj/protect_target + +/datum/objective/protect_object/proc/set_target(obj/O) + protect_target = O + update_explanation_text() + +/datum/objective/protect_object/update_explanation_text() + . = ..() + if(protect_target) + explanation_text = "Protect \the [protect_target] at all costs." + else + explanation_text = "Free objective." + +/datum/objective/protect_object/check_completion() + return !QDELETED(protect_target) + //Changeling Objectives /datum/objective/absorb @@ -849,7 +876,7 @@ GLOBAL_LIST_EMPTY(possible_items_special) continue var/total_genetic_points = changeling.geneticpoints - for(var/obj/effect/proc_holder/changeling/p in changeling.purchasedpowers) + for(var/datum/action/changeling/p in changeling.purchasedpowers) total_genetic_points += p.dna_cost if(total_genetic_points > initial(changeling.geneticpoints)) @@ -1170,7 +1197,7 @@ GLOBAL_LIST_EMPTY(cult_contraband) I.forceMove(get_turf(owner)) if(ishuman(owner)) var/mob/living/carbon/human/H = owner - H.equip_in_one_of_slots(I, list("backpack" = SLOT_IN_BACKPACK), critical = TRUE) + H.equip_in_one_of_slots(I, list("backpack" = ITEM_SLOT_BACKPACK), critical = TRUE) hoarded_item = I @@ -1180,6 +1207,7 @@ GLOBAL_LIST_EMPTY(possible_sabotages) /datum/objective/sabotage name = "sabotage" var/datum/sabotage_objective/targetinfo = null //composition > inheritance. + var/list/special_items_given = list() /datum/objective/sabotage/get_target() return targetinfo.sabotage_type @@ -1190,6 +1218,11 @@ GLOBAL_LIST_EMPTY(possible_sabotages) for(var/I in subtypesof(/datum/sabotage_objective)) new I +/datum/objective/sabotage/Destroy() + if(length(special_items_given)) + QDEL_LIST(special_items_given) + . = ..() + /datum/objective/sabotage/find_target(dupe_search_range, blacklist) var/list/datum/mind/owners = get_owners() var/approved_targets = list() @@ -1207,7 +1240,7 @@ GLOBAL_LIST_EMPTY(possible_sabotages) if(sabo) targetinfo = sabo explanation_text = "[targetinfo.name]" - give_special_equipment(targetinfo.special_equipment) + special_items_given = give_special_equipment(targetinfo.special_equipment) return sabo else explanation_text = "Free objective" diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 419a74d616..5b3e742336 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -13,7 +13,7 @@ antag_flag = ROLE_REV false_report_weight = 10 chaos = 8 - restricted_jobs = list("AI", "Cyborg") + restricted_jobs = list("Prisoner", "AI", "Cyborg") protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") required_players = 20 required_enemies = 1 diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index d42fe615cd..220fbe9978 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -10,7 +10,7 @@ config_tag = "traitor" antag_flag = ROLE_TRAITOR false_report_weight = 20 //Reports of traitors are pretty common. - restricted_jobs = list("Cyborg")//They are part of the AI if he is traitor so are they, they use to get double chances + restricted_jobs = list("Prisoner", "Cyborg")//They are part of the AI if he is traitor so are they, they use to get double chances protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") //citadel change - adds HoP, CE, CMO, and RD to ling role blacklist required_players = 0 required_enemies = 1 diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm index e9968dadd4..c720668a5b 100644 --- a/code/game/machinery/Beacon.dm +++ b/code/game/machinery/Beacon.dm @@ -10,7 +10,7 @@ idle_power_usage = 0 var/obj/item/beacon/Beacon -/obj/machinery/bluespace_beacon/Initialize() +/obj/machinery/bluespace_beacon/Initialize(mapload) . = ..() var/turf/T = loc Beacon = new(T) @@ -38,7 +38,7 @@ icon_state = "[state]" /obj/machinery/bluespace_beacon/process() - if(!Beacon) + if(QDELETED(Beacon)) //Don't move it out of nullspace BACK INTO THE GAME for the love of god var/turf/T = loc Beacon = new(T) Beacon.invisibility = INVISIBILITY_MAXIMUM diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index 82209221ce..f6eebb8544 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -31,7 +31,7 @@ if(storedpda) . += "[initial(icon_state)]-closed" -/obj/machinery/pdapainter/Initialize() +/obj/machinery/pdapainter/Initialize(mapload) . = ..() var/list/blocked = list( /obj/item/pda/ai/pai, @@ -58,9 +58,9 @@ storedpda.forceMove(loc) storedpda = null -/obj/machinery/pdapainter/contents_explosion(severity, target) +/obj/machinery/pdapainter/contents_explosion(severity, target, origin) if(storedpda) - storedpda.ex_act(severity, target) + storedpda.ex_act(severity, target, origin) /obj/machinery/pdapainter/handle_atom_del(atom/A) if(A == storedpda) diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 06e1635656..706b2520dd 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -29,7 +29,7 @@ payment_department = ACCOUNT_MED fair_market_price = 5 -/obj/machinery/sleeper/Initialize() +/obj/machinery/sleeper/Initialize(mapload) . = ..() // if(mapload) // component_parts -= circuit @@ -278,7 +278,7 @@ icon_state = "sleeper_s" controls_inside = TRUE -/obj/machinery/sleeper/syndie/Initialize() +/obj/machinery/sleeper/syndie/Initialize(mapload) . = ..() component_parts = list() component_parts += new /obj/item/circuitboard/machine/sleeper/syndie(null) @@ -289,7 +289,7 @@ component_parts += new /obj/item/stack/cable_coil(null) RefreshParts() -/obj/machinery/sleeper/syndie/fullupgrade/Initialize() +/obj/machinery/sleeper/syndie/fullupgrade/Initialize(mapload) . = ..() component_parts = list() component_parts += new /obj/item/circuitboard/machine/sleeper/syndie(null) diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 133fec28b3..e1d7737f5c 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -90,6 +90,7 @@ Class Procs: verb_say = "beeps" verb_yell = "blares" pressure_resistance = 15 + pass_flags_self = PASSMACHINE max_integrity = 200 layer = BELOW_OBJ_LAYER //keeps shit coming out of the machine from ending up underneath it. flags_1 = DEFAULT_RICOCHET_1 @@ -103,6 +104,10 @@ Class Procs: anchored = TRUE interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT + vocal_bark_id = "synth" + vocal_pitch = 0.6 + vocal_volume = 40 + var/stat = 0 var/use_power = IDLE_POWER_USE //0 = dont run the auto @@ -134,9 +139,9 @@ Class Procs: var/market_verb = "Customer" var/payment_department = ACCOUNT_ENG -/obj/machinery/Initialize() +/obj/machinery/Initialize(mapload) if(!armor) - armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70) + armor = list(MELEE = 25, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 70) . = ..() GLOB.machines += src @@ -144,10 +149,11 @@ Class Procs: circuit = new circuit(src) circuit.apply_default_parts(src) - if(!speed_process && init_process) - START_PROCESSING(SSmachines, src) - else - START_PROCESSING(SSfastprocess, src) + if(init_process) // Required to prevent non-speed non-init machines from running + if(speed_process) + START_PROCESSING(SSfastprocess, src) + else + START_PROCESSING(SSmachines, src) RegisterSignal(src, COMSIG_ENTER_AREA, .proc/power_change) if (occupant_typecache) @@ -247,61 +253,124 @@ Class Procs: /obj/machinery/proc/auto_use_power() if(!powered(power_channel)) - return 0 + return FALSE if(use_power == 1) use_power(idle_power_usage,power_channel) else if(use_power >= 2) use_power(active_power_usage,power_channel) - return 1 + return TRUE /obj/machinery/proc/is_operational() return !(stat & (NOPOWER|BROKEN|MAINT)) /obj/machinery/can_interact(mob/user) - var/silicon = hasSiliconAccessInArea(user) || IsAdminGhost(user) - if((stat & (NOPOWER|BROKEN)) && !(interaction_flags_machine & INTERACT_MACHINE_OFFLINE)) + if((stat & (NOPOWER|BROKEN)) && !(interaction_flags_machine & INTERACT_MACHINE_OFFLINE)) // Check if the machine is broken, and if we can still interact with it if so return FALSE - if(panel_open && !(interaction_flags_machine & INTERACT_MACHINE_OPEN)) - if(!silicon || !(interaction_flags_machine & INTERACT_MACHINE_OPEN_SILICON)) - return FALSE - if(silicon) + if(IsAdminGhost(user)) + return TRUE //if you're an admin, you probably know what you're doing (or at least have permission to do what you're doing) + + if(!isliving(user)) + return FALSE //no ghosts in the machine allowed, sorry + + // if(SEND_SIGNAL(user, COMSIG_TRY_USE_MACHINE, src) & COMPONENT_CANT_USE_MACHINE_INTERACT) + // return FALSE + + var/mob/living/living_user = user + + var/is_dextrous = FALSE + if(isanimal(user)) + var/mob/living/simple_animal/user_as_animal = user + if (user_as_animal.dextrous) + is_dextrous = TRUE + + if(!issilicon(user) && !is_dextrous && !user.can_hold_items()) + return FALSE //spiders gtfo + + if(issilicon(user)) // If we are a silicon, make sure the machine allows silicons to interact with it if(!(interaction_flags_machine & INTERACT_MACHINE_ALLOW_SILICON)) return FALSE - else - if(interaction_flags_machine & INTERACT_MACHINE_REQUIRES_SILICON) + + if(panel_open && !(interaction_flags_machine & INTERACT_MACHINE_OPEN) && !(interaction_flags_machine & INTERACT_MACHINE_OPEN_SILICON)) return FALSE - if(!Adjacent(user)) - var/mob/living/carbon/H = user - if(!(istype(H) && H.has_dna() && H.dna.check_mutation(TK))) - return FALSE + + return TRUE //silicons don't care about petty mortal concerns like needing to be next to a machine to use it + + if(living_user.incapacitated()) //idk why silicons aren't supposed to care about incapacitation when interacting with machines, but it was apparently like this before + return FALSE + + // TODO: nerf blind people + // if((interaction_flags_machine & INTERACT_MACHINE_REQUIRES_SIGHT) && user.is_blind()) + // to_chat(user, span_warning("This machine requires sight to use.")) + // return FALSE + + if(panel_open && !(interaction_flags_machine & INTERACT_MACHINE_OPEN)) + return FALSE + + if(interaction_flags_machine & INTERACT_MACHINE_REQUIRES_SILICON) //if the user was a silicon, we'd have returned out earlier, so the user must not be a silicon + return FALSE + + if(!Adjacent(user)) // Next make sure we are next to the machine unless we have telekinesis + var/mob/living/carbon/carbon_user = living_user + if(!istype(carbon_user) || !carbon_user.has_dna() || !carbon_user.dna.check_mutation(TK)) + return FALSE + + return TRUE // If we passed all of those checks, woohoo! We can interact with this machine. + +/obj/machinery/proc/can_transact(obj/item/card/id/thecard, allowdepartment, silent) + if(!istype(thecard)) + if(!silent) + say("No card found.") + return FALSE + else if (!thecard.registered_account) + if(!silent) + say("No account found.") + return FALSE + else if(!allowdepartment && !thecard.registered_account.account_job) + if(!silent) + say("Departmental accounts have been blacklisted from personal expenses due to embezzlement.") + return FALSE + return TRUE + +/obj/machinery/proc/attempt_transact(obj/item/card/id/thecard, transaction_cost) + if(!istype(thecard)) + return FALSE + var/datum/bank_account/account = thecard.registered_account + if(!istype(account)) + return FALSE + + if(transaction_cost) + if(!account.adjust_money(-transaction_cost)) + return FALSE + var/datum/bank_account/D = SSeconomy.get_dep_account(payment_department) + if(D) + D.adjust_money(transaction_cost) return TRUE /obj/machinery/proc/check_nap_violations() if(!SSeconomy.full_ancap) return TRUE if(occupant && !state_open) - if(ishuman(occupant)) - var/mob/living/carbon/human/H = occupant - var/obj/item/card/id/I = H.get_idcard() - if(I) - var/datum/bank_account/insurance = I.registered_account - if(!insurance) - say("[market_verb] NAP Violation: No bank account found.") - nap_violation() - return FALSE - else - if(!insurance.adjust_money(-fair_market_price)) - say("[market_verb] NAP Violation: Unable to pay.") - nap_violation() - return FALSE - var/datum/bank_account/D = SSeconomy.get_dep_account(payment_department) - if(D) - D.adjust_money(fair_market_price) - else - say("[market_verb] NAP Violation: No ID card found.") - nap_violation() + var/mob/living/L = occupant + var/obj/item/card/id/I = L.get_idcard(TRUE) + if(I) + var/datum/bank_account/insurance = I.registered_account + if(!insurance) + say("[market_verb] NAP Violation: No bank account found.") + nap_violation(L) return FALSE + else + if(!insurance.adjust_money(-fair_market_price)) + say("[market_verb] NAP Violation: Unable to pay.") + nap_violation(L) + return FALSE + var/datum/bank_account/D = SSeconomy.get_dep_account(payment_department) + if(D) + D.adjust_money(fair_market_price) + else + say("[market_verb] NAP Violation: No ID card found.") + nap_violation(L) + return FALSE return TRUE /obj/machinery/proc/nap_violation(mob/violator) @@ -322,11 +391,11 @@ Class Procs: /obj/machinery/Topic(href, href_list) ..() if(!can_interact(usr)) - return 1 + return TRUE if(!usr.canUseTopic(src)) - return 1 + return TRUE add_fingerprint(usr) - return 0 + return FALSE //////////////////////////////////////////////////////////////////////////////////////////// @@ -337,7 +406,7 @@ Class Procs: user.DelayNextAction(CLICK_CD_MELEE) user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) user.visible_message("[user.name] smashes against \the [src.name] with its paws.", null, null, COMBAT_MESSAGE_RANGE) - take_damage(4, BRUTE, "melee", 1) + take_damage(4, BRUTE, MELEE, 1) /obj/machinery/attack_robot(mob/user) if(!(interaction_flags_machine & INTERACT_MACHINE_ALLOW_SILICON) && !IsAdminGhost(user)) @@ -405,9 +474,9 @@ Class Procs: update_appearance() return TRUE -/obj/machinery/contents_explosion(severity, target) +/obj/machinery/contents_explosion(severity, target, origin) if(occupant) - occupant.ex_act(severity, target) + occupant.ex_act(severity, target, origin) /obj/machinery/handle_atom_del(atom/A) if(A == occupant) @@ -415,6 +484,12 @@ Class Procs: update_icon() updateUsrDialog() +/obj/machinery/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() + + if(mover.pass_flags & PASSMACHINE) + return TRUE + /obj/machinery/proc/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) if(!(flags_1 & NODECONSTRUCT_1) && I.tool_behaviour == TOOL_SCREWDRIVER) I.play_tool_sound(src, 50) @@ -557,7 +632,7 @@ Class Procs: if(prob(85) && (zap_flags & ZAP_MACHINE_EXPLOSIVE)) explosion(src, 1, 2, 4, flame_range = 2, adminlog = FALSE, smoke = FALSE) else if(zap_flags & ZAP_OBJ_DAMAGE) - take_damage(power/2000, BURN, "energy") + take_damage(power/2000, BURN, ENERGY) if(prob(40)) emp_act(50) @@ -581,4 +656,15 @@ Class Procs: AM.pixel_y = -8 + (round( . / 3)*8) /obj/machinery/rust_heretic_act() - take_damage(500, BRUTE, "melee", 1) + take_damage(500, BRUTE, MELEE, 1) + +/** + * Alerts the AI that a hack is in progress. + * + * Sends all AIs a message that a hack is occurring. Specifically used for space ninja tampering as this proc was originally in the ninja files. + * However, the proc may also be used elsewhere. + */ +/obj/machinery/proc/AI_notify_hack() + var/alertstr = "Network Alert: Hacking attempt detected[get_area(src)?" in [get_area_name(src, TRUE)]":". Unable to pinpoint location"]." + for(var/mob/living/silicon/ai/AI in GLOB.player_list) + to_chat(AI, alertstr) diff --git a/code/game/machinery/ai_slipper.dm b/code/game/machinery/ai_slipper.dm index 4935c9d4d3..b59e71d62e 100644 --- a/code/game/machinery/ai_slipper.dm +++ b/code/game/machinery/ai_slipper.dm @@ -6,13 +6,23 @@ layer = PROJECTILE_HIT_THRESHHOLD_LAYER plane = FLOOR_PLANE max_integrity = 200 - armor = list("melee" = 50, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 50, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) var/uses = 20 var/cooldown = 0 var/cooldown_time = 100 req_access = list(ACCESS_AI_UPLOAD) +/obj/machinery/ai_slipper/Initialize(mapload) + . = ..() + register_context() + +/obj/machinery/ai_slipper/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + if(issilicon(user)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Dispense foam") + return CONTEXTUAL_SCREENTIP_SET + /obj/machinery/ai_slipper/examine(mob/user) . = ..() . += "It has [uses] uses of foam remaining." diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/airlock_control.dm index 4b5e4088d7..0841dc6939 100644 --- a/code/game/machinery/airlock_control.dm +++ b/code/game/machinery/airlock_control.dm @@ -152,7 +152,7 @@ frequency = new_frequency radio_connection = SSradio.add_object(src, frequency, RADIO_AIRLOCK) -/obj/machinery/airlock_sensor/Initialize() +/obj/machinery/airlock_sensor/Initialize(mapload) . = ..() set_frequency(frequency) diff --git a/code/game/machinery/announcement_system.dm b/code/game/machinery/announcement_system.dm index f46169f72e..a565f679bb 100644 --- a/code/game/machinery/announcement_system.dm +++ b/code/game/machinery/announcement_system.dm @@ -27,7 +27,7 @@ GLOBAL_LIST_EMPTY(announcement_systems) var/pinklight = "Light_Pink" var/errorlight = "Error_Red" -/obj/machinery/announcement_system/Initialize() +/obj/machinery/announcement_system/Initialize(mapload) . = ..() GLOB.announcement_systems += src radio = new /obj/item/radio/headset/silicon/ai(src) diff --git a/code/game/machinery/aug_manipulator.dm b/code/game/machinery/aug_manipulator.dm index e496973d75..c34e0a2d4f 100644 --- a/code/game/machinery/aug_manipulator.dm +++ b/code/game/machinery/aug_manipulator.dm @@ -8,14 +8,14 @@ max_integrity = 200 var/obj/item/bodypart/storedpart var/initial_icon_state - var/static/list/style_list_icons = list("standard" = 'icons/mob/augmentation/augments.dmi', - "engineer" = 'icons/mob/augmentation/augments_engineer.dmi', - "security" = 'icons/mob/augmentation/augments_security.dmi', - "mining" = 'icons/mob/augmentation/augments_mining.dmi', - "Talon" = 'icons/mob/augmentation/cosmetic_prosthetic/talon.dmi', - "Nanotrasen" = 'icons/mob/augmentation/cosmetic_prosthetic/nanotrasen.dmi', - "Hephaesthus" = 'icons/mob/augmentation/cosmetic_prosthetic/hephaestus.dmi', - "Bishop" = 'icons/mob/augmentation/cosmetic_prosthetic/bishop.dmi', + var/static/list/style_list_icons = list("standard" = 'icons/mob/augmentation/augments.dmi', + "engineer" = 'icons/mob/augmentation/augments_engineer.dmi', + "security" = 'icons/mob/augmentation/augments_security.dmi', + "mining" = 'icons/mob/augmentation/augments_mining.dmi', + "Talon" = 'icons/mob/augmentation/cosmetic_prosthetic/talon.dmi', + "Nanotrasen" = 'icons/mob/augmentation/cosmetic_prosthetic/nanotrasen.dmi', + "Hephaesthus" = 'icons/mob/augmentation/cosmetic_prosthetic/hephaestus.dmi', + "Bishop" = 'icons/mob/augmentation/cosmetic_prosthetic/bishop.dmi', "Xion" = 'icons/mob/augmentation/cosmetic_prosthetic/xion.dmi', "Grayson" = 'icons/mob/augmentation/cosmetic_prosthetic/grayson.dmi', "Cybersolutions" = 'icons/mob/augmentation/cosmetic_prosthetic/cybersolutions.dmi', @@ -27,7 +27,7 @@ if(storedpart) . += "Alt-click to eject the limb." -/obj/machinery/aug_manipulator/Initialize() +/obj/machinery/aug_manipulator/Initialize(mapload) initial_icon_state = initial(icon_state) return ..() @@ -55,9 +55,9 @@ storedpart.forceMove(loc) storedpart = null -/obj/machinery/aug_manipulator/contents_explosion(severity, target) +/obj/machinery/aug_manipulator/contents_explosion(severity, target, origin) if(storedpart) - storedpart.ex_act(severity, target) + storedpart.ex_act(severity, target, origin) /obj/machinery/aug_manipulator/handle_atom_del(atom/A) if(A == storedpart) diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 0e7b4aa0fa..4f876b97e1 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -1,7 +1,3 @@ -#define AUTOLATHE_MAIN_MENU 1 -#define AUTOLATHE_CATEGORY_MENU 2 -#define AUTOLATHE_SEARCH_MENU 3 - /obj/machinery/autolathe name = "autolathe" desc = "It produces items using metal and glass." @@ -24,13 +20,14 @@ var/shock_wire var/busy = FALSE - var/prod_coeff = 1 + + ///the multiplier for how much materials the created object takes from this machines stored materials + var/creation_efficiency = 1.6 var/datum/design/being_built var/datum/techweb/stored_research var/list/datum/design/matching_designs - var/selected_category - var/screen = 1 + var/selected_category = "None" var/base_price = 25 var/hacked_price = 50 @@ -47,7 +44,7 @@ "Imported" ) -/obj/machinery/autolathe/Initialize() +/obj/machinery/autolathe/Initialize(mapload) . = ..() wires = new /datum/wires/autolathe(src) stored_research = new /datum/techweb/specialized/autounlocking/autolathe @@ -60,109 +57,138 @@ QDEL_NULL(wires) return ..() -/obj/machinery/autolathe/ui_interact(mob/user) +/obj/machinery/autolathe/ui_interact(mob/user, datum/tgui/ui) . = ..() if(!is_operational()) return + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Autolathe", capitalize(src.name)) + ui.open() + if(shocked && !(stat & NOPOWER)) - shock(user,50) + if(shock(user,50)) + ui.close() //close the window if they got zapped successfully as to prevent them from getting zapped infinitely. - var/dat - - switch(screen) - if(AUTOLATHE_MAIN_MENU) - dat = main_win(user) - if(AUTOLATHE_CATEGORY_MENU) - dat = category_win(user,selected_category) - if(AUTOLATHE_SEARCH_MENU) - dat = search_win(user) - - var/datum/browser/popup = new(user, "autolathe", name, 400, 500) - popup.set_content(dat) - popup.open() - -/obj/machinery/autolathe/on_deconstruction() +/obj/machinery/autolathe/ui_data(mob/user) + var/list/data = list() + data["materials"] = list() var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - materials.retrieve_all() + data["materialtotal"] = materials.total_amount + data["materialsmax"] = materials.max_amount + data["categories"] = categories + data["designs"] = list() + data["active"] = busy -/obj/machinery/autolathe/attackby(obj/item/O, mob/user, params) - if (busy) - to_chat(user, "The autolathe is busy. Please wait for completion of previous operation.") - return TRUE - - if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", O)) - updateUsrDialog() - return TRUE - - if(default_deconstruction_crowbar(O)) - return TRUE - - if(panel_open && is_wire_tool(O)) - wires.interact(user) - return TRUE - - if(user.a_intent == INTENT_HARM) //so we can hit the machine - return ..() - - if(stat) - return TRUE - - if(istype(O, /obj/item/disk/design_disk)) - user.visible_message("[user] begins to load \the [O] in \the [src]...", - "You begin to load a design from \the [O]...", - "You hear the chatter of a floppy drive.") - busy = TRUE - var/obj/item/disk/design_disk/D = O - if(do_after(user, 14.4, target = src)) - for(var/B in D.blueprints) - if(B) - stored_research.add_design(B) - busy = FALSE - return TRUE - - return ..() - - -/obj/machinery/autolathe/proc/AfterMaterialInsert(item_inserted, id_inserted, amount_inserted) - if(istype(item_inserted, /obj/item/stack/ore/bluespace_crystal)) - use_power(MINERAL_MATERIAL_AMOUNT / 10) - else if(custom_materials && custom_materials.len && custom_materials[SSmaterials.GetMaterialRef(/datum/material/glass)]) - flick("autolathe_r",src)//plays glass insertion animation by default otherwise + for(var/mat_id in materials.materials) + var/datum/material/M = mat_id + var/mineral_count = materials.materials[mat_id] + var/list/material_data = list( + name = M.name, + mineral_amount = mineral_count, + matcolour = M.color, + ) + data["materials"] += list(material_data) + if(selected_category != "None" && !length(matching_designs)) + data["designs"] = handle_designs(stored_research.researched_designs, TRUE) else - flick("autolathe_o",src)//plays metal insertion animation + data["designs"] = handle_designs(matching_designs, FALSE) + return data +/obj/machinery/autolathe/proc/handle_designs(list/designs, categorycheck) + var/list/output = list() + for(var/v in designs) + var/datum/design/D = categorycheck ? SSresearch.techweb_design_by_id(v) : v + if(categorycheck) + if(!(selected_category in D.category)) + continue + var/unbuildable = FALSE // we can't build the design currently + var/m10 = FALSE // 10x mult + var/m25 = FALSE // 25x mult + var/m50 = FALSE // 50x mult + var/m5 = FALSE // 5x mult + var/sheets = FALSE // sheets or no? + if(disabled || !can_build(D)) + unbuildable = TRUE + var/max_multiplier = unbuildable ? 0 : 1 + if(ispath(D.build_path, /obj/item/stack)) + sheets = TRUE + if(!unbuildable) + var/datum/component/material_container/mats = GetComponent(/datum/component/material_container) + for(var/datum/material/mat in D.materials) + max_multiplier = min(D.maxstack, round(mats.get_material_amount(mat)/D.materials[mat])) + if (max_multiplier>10 && !disabled) + m10 = TRUE + if (max_multiplier>25 && !disabled) + m25 = TRUE + else + if(!unbuildable) + if(!disabled && can_build(D, 5)) + m5 = TRUE + if(!disabled && can_build(D, 10)) + m10 = TRUE + var/datum/component/material_container/mats = GetComponent(/datum/component/material_container) + for(var/datum/material/mat in D.materials) + max_multiplier = min(50, round(mats.get_material_amount(mat)/(D.materials[mat] * creation_efficiency))) - use_power(min(1000, amount_inserted / 100)) - updateUsrDialog() + var/list/design = list( + name = D.name, + id = D.id, + ref = REF(src), + cost = get_design_cost(D), + buildable = unbuildable, + mult5 = m5, + mult10 = m10, + mult25 = m25, + mult50 = m50, + sheet = sheets, + maxmult = max_multiplier, + ) + output += list(design) + return output -/obj/machinery/autolathe/Topic(href, href_list) - if(..()) +/obj/machinery/autolathe/ui_act(action, params) + . = ..() + if(.) return - if (!busy) - if(href_list["menu"]) - screen = text2num(href_list["menu"]) - updateUsrDialog() + if(action == "menu") + selected_category = null + matching_designs.Cut() + . = TRUE - if(href_list["category"]) - selected_category = href_list["category"] - updateUsrDialog() + if(action == "category") + selected_category = params["selectedCategory"] + matching_designs.Cut() + . = TRUE - if(href_list["make"]) + if(action == "search") + matching_designs.Cut() + for(var/v in stored_research.researched_designs) + var/datum/design/D = SSresearch.techweb_design_by_id(v) + if(findtext(D.name,params["to_search"])) + matching_designs.Add(D) + . = TRUE + + if(action == "make") + if (!busy) ///////////////// //href protection - being_built = stored_research.isDesignResearchedID(href_list["make"]) + being_built = stored_research.isDesignResearchedID(params["id"]) if(!being_built) return - var/multiplier = text2num(href_list["multiplier"]) + var/multiplier = text2num(params["multiplier"]) + if(!multiplier) + to_chat(usr, span_alert("[src] only accepts a numerical multiplier!")) + return var/is_stack = ispath(being_built.build_path, /obj/item/stack) - multiplier = clamp(multiplier,1,50) + multiplier = clamp(round(multiplier),1,50) ///////////////// - var/coeff = (is_stack ? 1 : prod_coeff) //stacks are unaffected by production coefficient + var/coeff = (is_stack ? 1 : creation_efficiency) //stacks are unaffected by production coefficient var/total_amount = 0 for(var/MAT in being_built.materials) @@ -184,8 +210,8 @@ if(materials.materials[i] > 0) list_to_show += i - used_material = input("Choose [used_material]", "Custom Material") as null|anything in sortList(list_to_show, /proc/cmp_typepaths_asc) - if(!used_material) + used_material = tgui_input_list(usr, "Choose [used_material]", "Custom Material", sortList(list_to_show, /proc/cmp_typepaths_asc)) + if(isnull(used_material)) return //Didn't pick any material, so you can't build shit either. custom_materials[used_material] += amount_needed @@ -193,27 +219,105 @@ if(materials.has_materials(materials_used)) busy = TRUE + to_chat(usr, span_notice("You print [multiplier] item(s) from the [src]")) use_power(power) icon_state = "autolathe_n" var/time = is_stack ? 32 : (32 * coeff * multiplier) ** 0.8 addtimer(CALLBACK(src, .proc/make_item, power, materials_used, custom_materials, multiplier, coeff, is_stack, usr), time) + . = TRUE else - to_chat(usr, "Not enough materials for this operation.") + to_chat(usr, span_alert("Not enough materials for this operation.")) + else + to_chat(usr, span_alert("The autolathe is busy. Please wait for completion of previous operation.")) - if(href_list["search"]) - matching_designs.Cut() +/obj/machinery/autolathe/on_deconstruction() + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + materials.retrieve_all() - for(var/v in stored_research.researched_designs) - var/datum/design/D = SSresearch.techweb_design_by_id(v) - if(findtext(D.name,href_list["to_search"])) - matching_designs.Add(D) - updateUsrDialog() +/obj/machinery/autolathe/attackby(obj/item/O, mob/living/user, params) + if(busy) + balloon_alert(user, "it's busy!") + return TRUE + + if(user.a_intent == INTENT_HARM) //so we can hit the machine + return ..() + + if(stat) + return TRUE + + if(istype(O, /obj/item/disk/design_disk)) + user.visible_message(span_notice("[user] begins to load \the [O] in \the [src]..."), + balloon_alert(user, "uploading design..."), + span_hear("You hear the chatter of a floppy drive.")) + busy = TRUE + if(do_after(user, 14.4, target = src)) + var/obj/item/disk/design_disk/disky = O + var/list/not_imported + for(var/datum/design/blueprint as anything in disky.blueprints) + if(!blueprint) + continue + if(blueprint.build_type & AUTOLATHE) + stored_research.add_design(blueprint) + else + LAZYADD(not_imported, blueprint.name) + if(not_imported) + to_chat(user, span_warning("The following design[length(not_imported) > 1 ? "s" : ""] couldn't be imported: [english_list(not_imported)]")) + busy = FALSE + return TRUE + + if(panel_open) + balloon_alert(user, "close the panel first!") + return FALSE + + return ..() + +/obj/machinery/autolathe/screwdriver_act(mob/living/user, obj/item/I) + . = ..() + if(busy) + balloon_alert(user, "it's busy!") + return STOP_ATTACK_PROC_CHAIN + + if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", I)) + return STOP_ATTACK_PROC_CHAIN + +/obj/machinery/autolathe/crowbar_act(mob/living/user, obj/item/I) + . = ..() + if(busy) + balloon_alert(user, "it's busy!") + return STOP_ATTACK_PROC_CHAIN + + if(default_deconstruction_crowbar(I)) + return STOP_ATTACK_PROC_CHAIN + +/obj/machinery/autolathe/multitool_act(mob/living/user, obj/item/I) + . = ..() + if(busy) + balloon_alert(user, "it's busy!") + return STOP_ATTACK_PROC_CHAIN + + if(panel_open) + wires.interact(user) + return STOP_ATTACK_PROC_CHAIN + +/obj/machinery/autolathe/wirecutter_act(mob/living/user, obj/item/I) + . = ..() + if(busy) + balloon_alert(user, "it's busy!") + return STOP_ATTACK_PROC_CHAIN + + if(panel_open) + wires.interact(user) + return STOP_ATTACK_PROC_CHAIN + +/obj/machinery/autolathe/proc/AfterMaterialInsert(obj/item/item_inserted, id_inserted, amount_inserted) + if(istype(item_inserted, /obj/item/stack/ore/bluespace_crystal)) + use_power(MINERAL_MATERIAL_AMOUNT / 10) + else if(custom_materials && custom_materials.len && custom_materials[SSmaterials.GetMaterialRef(/datum/material/glass)]) + flick("autolathe_r", src)//plays glass insertion animation by default otherwise else - to_chat(usr, "The autolathe is busy. Please wait for completion of previous operation.") + flick("autolathe_o", src)//plays metal insertion animation - updateUsrDialog() - - return + use_power(min(1000, amount_inserted / 100)) /obj/machinery/autolathe/proc/make_item(power, list/materials_used, list/picked_materials, multiplier, coeff, is_stack, mob/user) var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) @@ -223,11 +327,11 @@ materials.use_materials(materials_used) if(is_stack) - var/obj/item/stack/N = new being_built.build_path(A, multiplier) - N.update_icon() + var/obj/item/stack/N = new being_built.build_path(A, multiplier, FALSE) + N.update_appearance() N.autolathe_crafted(src) else - for(var/i=1, i<=multiplier, i++) + for(var/i in 1 to multiplier) var/obj/item/new_item = new being_built.build_path(A) new_item.autolathe_crafted(src) @@ -241,132 +345,30 @@ icon_state = "autolathe" busy = FALSE - updateDialog() /obj/machinery/autolathe/RefreshParts() - var/T = 0 - for(var/obj/item/stock_parts/matter_bin/MB in component_parts) - T += MB.rating*75000 + var/mat_capacity = 0 + for(var/obj/item/stock_parts/matter_bin/new_matter_bin in component_parts) + mat_capacity += new_matter_bin.rating*75000 var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - materials.max_amount = T - T=1.2 - for(var/obj/item/stock_parts/manipulator/M in component_parts) - T -= M.rating*0.2 - prod_coeff = min(1,max(0,T)) // Coeff going 1 -> 0,8 -> 0,6 -> 0,4 + materials.max_amount = mat_capacity + + var/efficiency=1.2 + for(var/obj/item/stock_parts/manipulator/new_manipulator in component_parts) + efficiency -= new_manipulator.rating*0.2 + creation_efficiency = max(1,efficiency) // creation_efficiency goes 1 -> 0,8 -> 0,6 -> 0,4 per level of manipulator efficiency /obj/machinery/autolathe/examine(mob/user) . += ..() var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) if(in_range(user, src) || isobserver(user)) - . += "The status display reads: Storing up to [materials.max_amount] material units.
    Material consumption at [prod_coeff*100]%.
    " - -/obj/machinery/autolathe/proc/main_win(mob/user) - var/dat = "

    Autolathe Menu:


    " - dat += materials_printout() - - dat += "
    \ - \ - \ - \ - \ - \ -

    " - - var/line_length = 1 - dat += "" - - for(var/C in categories) - if(line_length > 2) - dat += "" - line_length = 1 - - dat += "" - line_length++ - - dat += "
    [C]
    " - return dat - -/obj/machinery/autolathe/proc/category_win(mob/user,selected_category) - var/dat = "Return to main menu" - dat += "

    Browsing [selected_category]:


    " - dat += materials_printout() - - for(var/v in stored_research.researched_designs) - var/datum/design/D = SSresearch.techweb_design_by_id(v) - if(!(selected_category in D.category)) - continue - - if(disabled || !can_build(D)) - dat += "[D.name]" - else - dat += "[D.name]" - - if(ispath(D.build_path, /obj/item/stack)) - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - var/max_multiplier - for(var/datum/material/mat in D.materials) - max_multiplier = min(D.maxstack, round(materials.get_material_amount(mat)/D.materials[mat])) - if (max_multiplier>10 && !disabled) - dat += " x10" - if (max_multiplier>25 && !disabled) - dat += " x25" - if(max_multiplier > 0 && !disabled) - dat += " x[max_multiplier]" - else - if(!disabled && can_build(D, 5)) - dat += " x5" - if(!disabled && can_build(D, 10)) - dat += " x10" - - dat += "[get_design_cost(D)]
    " - - dat += "
    " - return dat - -/obj/machinery/autolathe/proc/search_win(mob/user) - var/dat = "Return to main menu" - dat += "

    Search results:


    " - dat += materials_printout() - - for(var/v in matching_designs) - var/datum/design/D = v - if(disabled || !can_build(D)) - dat += "[D.name]" - else - dat += "[D.name]" - - if(ispath(D.build_path, /obj/item/stack)) - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - var/max_multiplier - for(var/datum/material/mat in D.materials) - max_multiplier = min(D.maxstack, round(materials.get_material_amount(mat)/D.materials[mat])) - if (max_multiplier>10 && !disabled) - dat += " x10" - if (max_multiplier>25 && !disabled) - dat += " x25" - if(max_multiplier > 0 && !disabled) - dat += " x[max_multiplier]" - - dat += "[get_design_cost(D)]
    " - - dat += "
    " - return dat - -/obj/machinery/autolathe/proc/materials_printout() - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - var/dat = "Total amount: [materials.total_amount] / [materials.max_amount] cm3
    " - for(var/mat_id in materials.materials) - var/datum/material/M = mat_id - var/mineral_amount = materials.materials[mat_id] - if(mineral_amount > 0) - dat += "[M.name] amount: [mineral_amount] cm3
    " - return dat + . += span_notice("The status display reads: Storing up to [materials.max_amount] material units.
    Material consumption at [creation_efficiency*100]%.") /obj/machinery/autolathe/proc/can_build(datum/design/D, amount = 1) - if(D.make_reagents.len) + if(length(D.make_reagents)) return FALSE - var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff) + var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : creation_efficiency) var/list/required_materials = list() @@ -379,7 +381,7 @@ /obj/machinery/autolathe/proc/get_design_cost(datum/design/D) - var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff) + var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : creation_efficiency) var/dat for(var/i in D.materials) if(istext(i)) //Category handling @@ -402,7 +404,7 @@ disabled = FALSE /obj/machinery/autolathe/proc/shock(mob/user, prb) - if(stat & (BROKEN|NOPOWER)) // unpowered, no shock + if(stat & (BROKEN|NOPOWER)) // unpowered, no shock return FALSE if(!prob(prb)) return FALSE @@ -424,7 +426,7 @@ else stored_research.remove_design(D) -/obj/machinery/autolathe/hacked/Initialize() +/obj/machinery/autolathe/hacked/Initialize(mapload) . = ..() adjust_hacked(TRUE) @@ -438,7 +440,7 @@ desc = "It produces items using metal and glass. This model was reprogrammed without some of the more hazardous designs." circuit = /obj/item/circuitboard/machine/autolathe/secure -/obj/machinery/autolathe/secure/Initialize() +/obj/machinery/autolathe/secure/Initialize(mapload) . = ..() // let's not leave the parent datum floating, right? if(stored_research) @@ -461,14 +463,14 @@ "Misc", "Imported" ) -/obj/machinery/autolathe/toy/Initialize() +/obj/machinery/autolathe/toy/Initialize(mapload) . = ..() // let's not leave the parent datum floating, right? if(stored_research) QDEL_NULL(stored_research) stored_research = new /datum/techweb/specialized/autounlocking/autolathe/toy -/obj/machinery/autolathe/toy/hacked/Initialize() +/obj/machinery/autolathe/toy/hacked/Initialize(mapload) . = ..() adjust_hacked(TRUE) diff --git a/code/game/machinery/autoloom.dm b/code/game/machinery/autoloom.dm new file mode 100644 index 0000000000..f290ac1a96 --- /dev/null +++ b/code/game/machinery/autoloom.dm @@ -0,0 +1,102 @@ +// like a recycler, but for plants only ig +/obj/machinery/autoloom + name = "autoloom" + desc = "A large processing machine used to process raw biological matter, like cotton or logs. It also looks like a recycler. There's a display on the side." + icon = 'icons/obj/recycling.dmi' + icon_state = "grinder-o0" + layer = ABOVE_ALL_MOB_LAYER // Overhead + density = TRUE + circuit = /obj/item/circuitboard/machine/autoloom + var/icon_name = "grinder-o" + var/eat_dir = WEST + var/process_efficiency = 0 + var/static/list/can_process = typecacheof(list( + /obj/item/stack/sheet/cotton, + /obj/item/grown/log, + /obj/item/grown/cotton + )) + +/obj/machinery/autoloom/RefreshParts() + for(var/obj/item/stock_parts/manipulator/M in component_parts) + process_efficiency = M.rating + +/obj/machinery/recycler/examine(mob/user) + . = ..() + . += "Biomatter processing efficiency at [amount_produced*100]%." + +/obj/machinery/autoloom/power_change() + ..() + update_icon() + +/obj/machinery/autoloom/attackby(obj/item/I, mob/user, params) + if(default_deconstruction_screwdriver(user, "grinder-oOpen", "grinder-o0", I)) + return + + if(default_pry_open(I)) + return + + if(default_unfasten_wrench(user, I)) + return + + if(default_deconstruction_crowbar(I)) + return + return ..() + +/obj/machinery/autoloom/update_icon_state() + var/is_powered = !(stat & (BROKEN|NOPOWER)) + icon_state = icon_name + "[is_powered]" // add the blood tag at the end + +/obj/machinery/autoloom/CanPass(atom/movable/AM) + . = ..() + if(!anchored) + return + + var/move_dir = get_dir(loc, AM.loc) + if(move_dir == eat_dir) + return TRUE + +/obj/machinery/autoloom/Crossed(atom/movable/AM) + eat(AM) + . = ..() + +/obj/machinery/autoloom/proc/eat(atom/movable/AM0, sound=TRUE) + if(stat & (BROKEN|NOPOWER)) + return + if(!isturf(AM0.loc)) + return //I don't know how you called Crossed() but stop it. + + if(is_type_in_list(AM0, can_process)) + process_item(AM0) + +/obj/machinery/autoloom/proc/process_item(obj/item/I) + . = list() + for(var/A in I) + var/atom/movable/AM = A + AM.forceMove(loc) + if(AM.loc == loc) + . += AM + + I.forceMove(loc) + if(istype(I, /obj/item/grown/log)) + var/obj/item/grown/log/L = I + var/seed_modifier = 0 + if(L.seed) + seed_modifier = round(L.seed.potency / 25) + new L.plank_type(src.loc, process_efficiency + seed_modifier) + qdel(L) + return + + if(istype(I, /obj/item/stack/sheet/cotton)) + var/obj/item/stack/sheet/cotton/RS = I + var/tomake = round((RS.amount / 4) * process_efficiency) + new RS.loom_result(src.loc, tomake) + qdel(RS) + return + + if(istype(I, /obj/item/grown/cotton)) + var/obj/item/grown/cotton/RC = I + var/cottonAmt = 1 + round(RC.seed.potency / 25) + var/newRaw = new RC.cotton_type(src.loc, cottonAmt) + qdel(RC) + process_item(newRaw) + return diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm index 79fff2a76a..54d302910d 100644 --- a/code/game/machinery/bank_machine.dm +++ b/code/game/machinery/bank_machine.dm @@ -14,7 +14,7 @@ var/minimum_time_between_warnings = 400 var/syphoning_credits = 0 -/obj/machinery/computer/bank_machine/Initialize() +/obj/machinery/computer/bank_machine/Initialize(mapload) . = ..() radio = new(src) radio.subspace_transmission = TRUE diff --git a/code/game/machinery/bloodbankgen.dm b/code/game/machinery/bloodbankgen.dm index 31fac02d83..9dc5539959 100644 --- a/code/game/machinery/bloodbankgen.dm +++ b/code/game/machinery/bloodbankgen.dm @@ -17,7 +17,7 @@ var/efficiency = 0 var/productivity = 0 -/obj/machinery/bloodbankgen/Initialize() +/obj/machinery/bloodbankgen/Initialize(mapload) . = ..() create_reagents(maxbloodstored, AMOUNT_VISIBLE) update_icon() diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 0de76694c0..d3e79d38c5 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -10,7 +10,7 @@ var/device_type = null var/id = null var/initialized_button = 0 - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 70) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 10, BIO = 100, RAD = 100, FIRE = 90, ACID = 70) use_power = IDLE_POWER_USE idle_power_usage = 2 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 35aa822a23..6e794b8072 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -15,7 +15,7 @@ resistance_flags = FIRE_PROOF - armor = list("melee" = 50, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 50) + armor = list(MELEE = 50, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 0, BIO = 0, RAD = 0, FIRE = 90, ACID = 50) max_integrity = 100 integrity_failure = 0.5 var/list/network = list("ss13") @@ -81,15 +81,15 @@ if(can_use()) toggle_cam(null, 0) //kick anyone viewing out and remove from the camera chunks GLOB.cameranet.cameras -= src + cancelCameraAlarm() if(isarea(myarea)) - LAZYREMOVE(myarea.cameras, src) + myarea.clear_camera(src) QDEL_NULL(assembly) if(bug) - bug.bugged_cameras -= src.c_tag + bug.bugged_cameras -= c_tag if(bug.current == src) bug.current = null bug = null - cancelCameraAlarm() return ..() /obj/machinery/camera/emp_act(severity) @@ -125,7 +125,7 @@ M.reset_perspective(null) to_chat(M, "The screen bursts into static.") -/obj/machinery/camera/ex_act(severity, target) +/obj/machinery/camera/ex_act(severity, target, origin) if(invuln) return ..() @@ -273,7 +273,7 @@ return ..() /obj/machinery/camera/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < 12 && !(stat & BROKEN)) + if(damage_flag == MELEE && damage_amount < 12 && !(stat & BROKEN)) return 0 . = ..() @@ -407,7 +407,7 @@ /obj/machinery/camera/get_remote_view_fullscreens(mob/user) if(view_range == short_range) //unfocused - user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/impaired, 2) + user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/scaled/impaired, 2) /obj/machinery/camera/update_remote_sight(mob/living/user) user.see_invisible = SEE_INVISIBLE_LIVING //can't see ghosts through cameras diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm index af5093d6ca..df0c7412bb 100644 --- a/code/game/machinery/camera/motion.dm +++ b/code/game/machinery/camera/motion.dm @@ -82,7 +82,7 @@ c_tag = "Arena" resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF | FREEZE_PROOF -/obj/machinery/camera/motion/thunderdome/Initialize() +/obj/machinery/camera/motion/thunderdome/Initialize(mapload) . = ..() proximity_monitor.SetRange(7) diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index 33e250fa59..880536245a 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -4,7 +4,7 @@ /obj/machinery/camera/emp_proof start_active = TRUE -/obj/machinery/camera/emp_proof/Initialize() +/obj/machinery/camera/emp_proof/Initialize(mapload) . = ..() upgradeEmpProof() @@ -14,7 +14,7 @@ start_active = TRUE icon_state = "xraycam" // Thanks to Krutchen for the icons. -/obj/machinery/camera/xray/Initialize() +/obj/machinery/camera/xray/Initialize(mapload) . = ..() upgradeXRay() @@ -23,7 +23,7 @@ start_active = TRUE name = "motion-sensitive security camera" -/obj/machinery/camera/motion/Initialize() +/obj/machinery/camera/motion/Initialize(mapload) . = ..() upgradeMotion() @@ -31,7 +31,7 @@ /obj/machinery/camera/all start_active = TRUE -/obj/machinery/camera/all/Initialize() +/obj/machinery/camera/all/Initialize(mapload) . = ..() upgradeEmpProof() upgradeXRay() @@ -43,7 +43,7 @@ var/number = 0 //camera number in area //This camera type automatically sets it's name to whatever the area that it's in is called. -/obj/machinery/camera/autoname/Initialize() +/obj/machinery/camera/autoname/Initialize(mapload) ..() return INITIALIZE_HINT_LATELOAD diff --git a/code/game/machinery/civilian_bountys.dm b/code/game/machinery/civilian_bountys.dm new file mode 100644 index 0000000000..1df0d02c3b --- /dev/null +++ b/code/game/machinery/civilian_bountys.dm @@ -0,0 +1,353 @@ +#define CIV_BOUNTY_SPLIT 30 + +///Pad for the Civilian Bounty Control. +/obj/machinery/piratepad/civilian + name = "civilian bounty pad" + desc = "A machine designed to send civilian bounty targets to centcom." + layer = TABLE_LAYER + +///Computer for assigning new civilian bounties, and sending bounties for collection. +/obj/machinery/computer/piratepad_control/civilian + name = "civilian bounty control terminal" + desc = "A console for assigning civilian bounties to inserted ID cards, and for controlling the bounty pad for export." + status_report = "Ready for delivery." + icon_screen = "civ_bounty" + icon_keyboard = "id_key" + warmup_time = 3 SECONDS + var/obj/item/card/id/inserted_scan_id + +/obj/machinery/computer/piratepad_control/civilian/Initialize() + . = ..() + pad = /obj/machinery/piratepad/civilian + +/obj/machinery/computer/piratepad_control/civilian/attackby(obj/item/I, mob/living/user, params) + if(isidcard(I)) + if(id_insert(user, I, inserted_scan_id)) + inserted_scan_id = I + return TRUE + . = ..() + +/obj/machinery/computer/piratepad_control/multitool_act(mob/living/user, obj/item/multitool/I) + if(istype(I) && istype(I.buffer,/obj/machinery/piratepad/civilian)) + to_chat(user, "You link [src] with [I.buffer] in [I] buffer.") + pad = I.buffer + return TRUE + +/obj/machinery/computer/piratepad_control/civilian/LateInitialize() + . = ..() + if(cargo_hold_id) + for(var/obj/machinery/piratepad/civilian/C in GLOB.machines) + if(C.cargo_hold_id == cargo_hold_id) + pad = C + return + else + pad = locate() in range(4,src) + +/obj/machinery/computer/piratepad_control/civilian/recalc() + if(sending) + return FALSE + if(!inserted_scan_id) + status_report = "Please insert your ID first." + playsound(loc, 'sound/machines/synth_no.ogg', 30 , TRUE) + return FALSE + if(!inserted_scan_id.registered_account.civilian_bounty) + status_report = "Please accept a new civilian bounty first." + playsound(loc, 'sound/machines/synth_no.ogg', 30 , TRUE) + return FALSE + status_report = "Civilian Bounty: " + for(var/atom/movable/AM in get_turf(pad)) + if(AM == pad) + continue + if(inserted_scan_id.registered_account.civilian_bounty.applies_to(AM)) + status_report += "Target Applicable." + playsound(loc, 'sound/machines/synth_yes.ogg', 30 , TRUE) + return + status_report += "Not Applicable." + playsound(loc, 'sound/machines/synth_no.ogg', 30 , TRUE) + +/** + * This fully rewrites base behavior in order to only check for bounty objects, and nothing else. + */ +/obj/machinery/computer/piratepad_control/civilian/send() + playsound(loc, 'sound/machines/wewewew.ogg', 70, TRUE) + if(!sending) + return + if(!inserted_scan_id) + stop_sending() + return FALSE + if(!inserted_scan_id.registered_account.civilian_bounty) + stop_sending() + return FALSE + var/datum/bounty/curr_bounty = inserted_scan_id.registered_account.civilian_bounty + var/active_stack = 0 + for(var/atom/movable/AM in get_turf(pad)) + if(AM == pad) + continue + if(curr_bounty.applies_to(AM)) + active_stack ++ + curr_bounty.ship(AM) + qdel(AM) + if(active_stack >= 1) + status_report += "Bounty Target Found x[active_stack]. " + else + status_report = "No applicable targets found. Aborting." + stop_sending() + if(curr_bounty.can_claim()) + //Pay for the bounty with the ID's department funds. + status_report += "Bounty completed! Please give your bounty cube to cargo for your automated payout shortly." + inserted_scan_id.registered_account.reset_bounty() + SSeconomy.civ_bounty_tracker++ + + var/obj/item/bounty_cube/reward = new /obj/item/bounty_cube(drop_location()) + reward.set_up(curr_bounty, inserted_scan_id) + + pad.visible_message(span_notice("[pad] activates!")) + flick(pad.sending_state,pad) + pad.icon_state = pad.idle_state + playsound(loc, 'sound/machines/synth_yes.ogg', 30 , TRUE) + sending = FALSE + +///Here is where cargo bounties are added to the player's bank accounts, then adjusted and scaled into a civilian bounty. +/obj/machinery/computer/piratepad_control/civilian/proc/add_bounties() + if(!inserted_scan_id || !inserted_scan_id.registered_account) + return + var/datum/bank_account/pot_acc = inserted_scan_id.registered_account + if((pot_acc.civilian_bounty && ((world.time) < pot_acc.bounty_timer + 5 MINUTES)) || pot_acc.bounties) + var/curr_time = round(((pot_acc.bounty_timer + (5 MINUTES))-world.time)/ (1 MINUTES), 0.01) + to_chat(usr, "Internal ID network spools coiling, try again in [curr_time] minutes!") + return FALSE + if(!pot_acc.account_job) + to_chat(usr, "The console smartly rejects your ID card, as it lacks a job assignment!") + return FALSE + var/list/datum/bounty/crumbs = list(random_bounty(pot_acc.account_job.bounty_types), // We want to offer 2 bounties from their appropriate job catagories + random_bounty(pot_acc.account_job.bounty_types), // and 1 guarenteed assistant bounty if the other 2 suck. + random_bounty(CIV_JOB_BASIC)) + pot_acc.bounty_timer = world.time + pot_acc.bounties = crumbs + +/obj/machinery/computer/piratepad_control/civilian/proc/pick_bounty(choice) + if(!inserted_scan_id?.registered_account) + playsound(loc, 'sound/machines/synth_no.ogg', 40 , TRUE) + return + inserted_scan_id.registered_account.civilian_bounty = inserted_scan_id.registered_account.bounties[choice] + inserted_scan_id.registered_account.bounties = null + return inserted_scan_id.registered_account.civilian_bounty + +/obj/machinery/computer/piratepad_control/civilian/AltClick(mob/user) + . = ..() + id_eject(user, inserted_scan_id) + +/obj/machinery/computer/piratepad_control/civilian/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "CivCargoHoldTerminal", name) + ui.open() + +/obj/machinery/computer/piratepad_control/civilian/ui_data(mob/user) + var/list/data = list() + data["points"] = points + data["pad"] = pad ? TRUE : FALSE + data["sending"] = sending + data["status_report"] = status_report + data["id_inserted"] = inserted_scan_id + if(inserted_scan_id && inserted_scan_id.registered_account) + if(inserted_scan_id.registered_account.civilian_bounty) + data["id_bounty_info"] = inserted_scan_id.registered_account.civilian_bounty.description + data["id_bounty_num"] = inserted_scan_id.registered_account.bounty_num() + data["id_bounty_value"] = (inserted_scan_id.registered_account.civilian_bounty.reward) * (CIV_BOUNTY_SPLIT/100) + if(inserted_scan_id.registered_account.bounties) + data["picking"] = TRUE + data["id_bounty_names"] = list(inserted_scan_id.registered_account.bounties[1].name, + inserted_scan_id.registered_account.bounties[2].name, + inserted_scan_id.registered_account.bounties[3].name) + data["id_bounty_values"] = list(inserted_scan_id.registered_account.bounties[1].reward * (CIV_BOUNTY_SPLIT/100), + inserted_scan_id.registered_account.bounties[2].reward * (CIV_BOUNTY_SPLIT/100), + inserted_scan_id.registered_account.bounties[3].reward * (CIV_BOUNTY_SPLIT/100)) + else + data["picking"] = FALSE + return data + +/obj/machinery/computer/piratepad_control/civilian/ui_act(action, params) + if(..()) + return + if(!pad) + return + if(!usr.canUseTopic(src, BE_CLOSE)) + return + switch(action) + if("recalc") + recalc() + if("send") + start_sending() + if("stop") + stop_sending() + if("pick") + pick_bounty(params["value"]) + if("bounty") + add_bounties() + if("eject") + id_eject(usr, inserted_scan_id) + inserted_scan_id = null + . = TRUE + +///Self explanitory, holds the ID card inthe console for bounty payout and manipulation. +/obj/machinery/computer/piratepad_control/civilian/proc/id_insert(mob/user, obj/item/inserting_item, obj/item/target) + var/obj/item/card/id/card_to_insert = inserting_item + var/holder_item = FALSE + + if(!isidcard(card_to_insert)) + card_to_insert = inserting_item.RemoveID() + holder_item = TRUE + + if(!card_to_insert || !user.transferItemToLoc(card_to_insert, src)) + return FALSE + + if(target) + if(holder_item && inserting_item.InsertID(target)) + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + else + id_eject(user, target) + + user.visible_message("[user] inserts \the [card_to_insert] into \the [src].", + "You insert \the [card_to_insert] into \the [src].") + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + updateUsrDialog() + return TRUE + +///Removes A stored ID card. +/obj/machinery/computer/piratepad_control/civilian/proc/id_eject(mob/user, obj/target) + if(!target) + to_chat(user, "That slot is empty!") + return FALSE + else + target.forceMove(drop_location()) + if(!issilicon(user) && Adjacent(user)) + user.put_in_hands(target) + user.visible_message("[user] gets \the [target] from \the [src].", \ + "You get \the [target] from \the [src].") + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + inserted_scan_id = null + updateUsrDialog() + return TRUE + +///Upon completion of a civilian bounty, one of these is created. It is sold to cargo to give the cargo budget bounty money, and the person who completed it cash. +/obj/item/bounty_cube + name = "Bounty Cube" + desc = "A bundle of compressed hardlight data, containing a completed bounty. Sell this on the cargo shuttle to claim it!" + icon = 'icons/obj/economy.dmi' + icon_state = "bounty_cube" + ///Value of the bounty that this bounty cube sells for. + var/bounty_value = 0 + ///Who completed the bounty. + var/bounty_holder + ///What the bounty was for. + var/bounty_name + ///Multiplier for the bounty payout received by the Supply budget if the cube is sent without having to nag. + var/speed_bonus = 0.2 + ///Multiplier for the bounty payout received by the person who completed the bounty. + var/holder_cut = 0.3 + ///Multiplier for the bounty payout received by the person who claims the handling tip. + var/handler_tip = 0.1 + ///Time between nags. + var/nag_cooldown = 5 MINUTES + ///How much the time between nags extends each nag. + var/nag_cooldown_multiplier = 1.25 + ///Next world tick to nag Supply listeners. + var/next_nag_time + ///What job the bounty holder had. + var/bounty_holder_job + ///Bank account of the person who receives the handling tip. + var/datum/bank_account/bounty_handler_account + ///Bank account of the person who completed the bounty. + var/datum/bank_account/bounty_holder_account + ///Our internal radio. + var/obj/item/radio/radio + ///The key our internal radio uses. + var/radio_key = /obj/item/encryptionkey/headset_cargo + +/obj/item/bounty_cube/Initialize() + . = ..() + radio = new(src) + radio.keyslot = new radio_key + radio.listening = FALSE + radio.recalculateChannels() + +/obj/item/bounty_cube/Destroy() + QDEL_NULL(radio) + . = ..() + +/obj/item/bounty_cube/examine() + . = ..() + if(speed_bonus) + . += "[time2text(next_nag_time - world.time,"mm:ss")] remains until [bounty_value * speed_bonus] credit speedy delivery bonus lost." + if(handler_tip && !bounty_handler_account) + . += "Scan this in the cargo shuttle with an export scanner to register your bank account for the [bounty_value * handler_tip] credit handling tip." + +/obj/item/bounty_cube/process(delta_time) + if(COOLDOWN_FINISHED(src, next_nag_time)) + if(!is_centcom_level(z) && !is_reserved_level(z)) //don't send message if we're on Centcom or in transit + radio.talk_into(src, "Unsent in [get_area(src)].[speed_bonus ? " Speedy delivery bonus of [bounty_value * speed_bonus] credit\s lost." : ""]", RADIO_CHANNEL_SUPPLY) + speed_bonus = 0 + bounty_holder_account.bank_card_talk("\The [src] is unsent in [get_area(src)].") + if(bounty_handler_account) + bounty_handler_account.bank_card_talk("\The [src] is unsent in [get_area(src)].") + nag_cooldown = nag_cooldown * nag_cooldown_multiplier + COOLDOWN_START(src, next_nag_time, nag_cooldown) + +/obj/item/bounty_cube/proc/set_up(datum/bounty/my_bounty, obj/item/card/id/holder_id) + bounty_value = my_bounty.reward + bounty_name = my_bounty.name + bounty_holder = holder_id.registered_name + bounty_holder_job = holder_id.assignment + bounty_holder_account = holder_id.registered_account + name = "\improper [bounty_value] cr [name]" + desc += " The sales tag indicates it was [bounty_holder] ([bounty_holder_job])'s reward for completing the [bounty_name] bounty." + AddComponent(/datum/component/pricetag, holder_id.registered_account, holder_cut) + START_PROCESSING(SSobj, src) + COOLDOWN_START(src, next_nag_time, nag_cooldown) + radio.talk_into(src,"Created in [get_area(src)] by [bounty_holder] ([bounty_holder_job]). Speedy delivery bonus lost in [time2text(next_nag_time - world.time,"mm:ss")].", RADIO_CHANNEL_SUPPLY) + +//for when you need a REAL bounty cube to test with and don't want to do a bounty each time your code changes +/obj/item/bounty_cube/test_cube + name = "debug bounty cube" + desc = "Use in-hand to set it up with a random bounty. Requires an ID it can detect with a bank account attached. \ + This will alert Supply over the radio with your name and location, and cargo techs will be dispatched to your location with kill on sight clearance." + var/set_up = FALSE + +/obj/item/bounty_cube/test_cube/attack_self(mob/user) + if(!isliving(user)) + to_chat(user, "You aren't eligible to use this!") + return ..() + + if(!set_up) + var/mob/living/squeezer = user + if(squeezer.get_bank_account()) + set_up(random_bounty(), squeezer.get_idcard()) + set_up = TRUE + return ..() + to_chat(user, "It can't detect your bank account.") + + return ..() + + +///Beacon to launch a new bounty setup when activated. +/obj/item/civ_bounty_beacon + name = "civilian bounty beacon" + desc = "N.T. approved civilian bounty beacon, toss it down and you will have a bounty pad and computer delivered to you." + icon = 'icons/obj/objects.dmi' + icon_state = "floor_beacon" + var/uses = 2 + +/obj/item/civ_bounty_beacon/attack_self() + loc.visible_message("\The [src] begins to beep loudly!") + addtimer(CALLBACK(src, .proc/launch_payload), 4 SECONDS) + +/obj/item/civ_bounty_beacon/proc/launch_payload() + playsound(src, "sparks", 80, TRUE) + switch(uses) + if(2) + new /obj/machinery/piratepad/civilian(drop_location()) + if(1) + new /obj/machinery/computer/piratepad_control/civilian(drop_location()) + qdel(src) + uses = uses - 1 diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 75c84bd2a8..06a399a2eb 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -42,7 +42,7 @@ fair_market_price = 5 // He nodded, because he knew I was right. Then he swiped his credit card to pay me for arresting him. payment_department = ACCOUNT_MED -/obj/machinery/clonepod/Initialize() +/obj/machinery/clonepod/Initialize(mapload) . = ..() countdown = new(src) @@ -439,7 +439,7 @@ mob_occupant.copy_from_prefs_vr() go_out() -/obj/machinery/clonepod/ex_act(severity, target) +/obj/machinery/clonepod/ex_act(severity, target, origin) ..() if(!QDELETED(src)) go_out() diff --git a/code/game/machinery/colormate.dm b/code/game/machinery/colormate.dm index d059d492ae..a208fc0bd2 100644 --- a/code/game/machinery/colormate.dm +++ b/code/game/machinery/colormate.dm @@ -1,15 +1,24 @@ +#define COLORMATE_TINT 1 +#define COLORMATE_HSV 2 +#define COLORMATE_MATRIX 3 + /obj/machinery/gear_painter name = "\improper Color Mate" - desc = "A machine to give your apparel a fresh new color! Recommended to use with white items for best results." + desc = "A machine to give your apparel a fresh new color!" icon = 'icons/obj/vending.dmi' icon_state = "colormate" + // light_mask = "colormate-light-mask" density = TRUE anchored = TRUE circuit = /obj/item/circuitboard/machine/colormate var/atom/movable/inserted var/activecolor = "#FFFFFF" var/list/color_matrix_last - var/matrix_mode = FALSE + var/active_mode = COLORMATE_HSV + + var/build_hue = 0 + var/build_sat = 1 + var/build_val = 1 /// Allow holder'd mobs var/allow_mobs = TRUE /// Minimum lightness for normal mode @@ -23,6 +32,8 @@ /obj/item/storage/backpack, /obj/item/storage/belt ) + /// Temporary messages + var/temp /obj/machinery/gear_painter/Initialize(mapload) . = ..() @@ -68,7 +79,9 @@ return if(!QDELETED(H)) H.release() + insert_mob(victim, user) + SStgui.update_uis(src) if(is_type_in_list(I, allowed_types) && is_operational()) if(!user.transferItemToLoc(I, src)) @@ -80,6 +93,8 @@ inserted = I update_icon() + SStgui.update_uis(src) + else return ..() @@ -101,137 +116,178 @@ /obj/machinery/gear_painter/AltClick(mob/user) . = ..() - if(!user.CanReach(src)) + drop_item() + +/obj/machinery/gear_painter/proc/drop_item() + if(!usr.CanReach(src)) return if(!inserted) return - to_chat(user, "You remove [inserted] from [src]") + to_chat(usr, "You remove [inserted] from [src]") inserted.forceMove(drop_location()) + var/mob/living/user = usr + if(istype(user)) + user.put_in_hands(inserted) inserted = null update_icon() - updateUsrDialog() + SStgui.update_uis(src) -/obj/machinery/gear_painter/ui_interact(mob/user) - if(!is_operational()) - return - user.set_machine(src) - var/list/dat = list("Color Mate Control Panel
    ") - if(!inserted) - dat += "No item inserted." +/obj/machinery/gear_painter/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Colormate", src.name) + ui.set_autoupdate(FALSE) //This might be a bit intensive, better to not update it every few ticks + ui.open() + +/obj/machinery/gear_painter/ui_data(mob/user) + . = list() + .["activemode"] = active_mode + .["matrixcolors"] = list( + "rr" = color_matrix_last[1], + "rg" = color_matrix_last[2], + "rb" = color_matrix_last[3], + "gr" = color_matrix_last[4], + "gg" = color_matrix_last[5], + "gb" = color_matrix_last[6], + "br" = color_matrix_last[7], + "bg" = color_matrix_last[8], + "bb" = color_matrix_last[9], + "cr" = color_matrix_last[10], + "cg" = color_matrix_last[11], + "cb" = color_matrix_last[12] + ) + .["buildhue"] = build_hue + .["buildsat"] = build_sat + .["buildval"] = build_val + if(temp) + .["temp"] = temp + if(inserted) + .["item"] = list() + .["item"]["name"] = inserted.name + .["item"]["sprite"] = icon2base64(getFlatIcon(inserted,defdir=SOUTH,no_anim=TRUE)) + .["item"]["preview"] = icon2base64(build_preview()) else - dat += "Item inserted: [inserted]
    " - dat += "Matrix mode: [matrix_mode? "On" : "Off"]" - if(!matrix_mode) - dat += "Select new color.
    " - dat += "Color: " - dat += "Apply new color.

    " - else - // POGGERS -#define MATRIX_FIELD(field, default) " " - dat += "
    " - dat += "" - dat += "Invalid color.") + return FALSE + inserted.add_atom_colour(color_to_use, FIXED_COLOUR_PRIORITY) + playsound(src, 'sound/effects/spray3.ogg', 50, 1) + return TRUE - if(href_list["select"]) - var/newcolor = input(usr, "Choose a color.", "", activecolor) as color|null - if(newcolor) - activecolor = newcolor - updateUsrDialog() - if(href_list["paint"]) - if(!inserted) - return - if(!check_valid_color(activecolor, usr)) - return - inserted.add_atom_colour(activecolor, FIXED_COLOUR_PRIORITY) - playsound(src, 'sound/effects/spray3.ogg', 50, 1) - updateUsrDialog() +/// Produces the preview image of the item, used in the UI, the way the color is not stacking is a sin. +/obj/machinery/gear_painter/proc/build_preview() + if(inserted) //sanity + var/list/cm + switch(active_mode) + if(COLORMATE_MATRIX) + cm = rgb_construct_color_matrix( + text2num(color_matrix_last[1]), + text2num(color_matrix_last[2]), + text2num(color_matrix_last[3]), + text2num(color_matrix_last[4]), + text2num(color_matrix_last[5]), + text2num(color_matrix_last[6]), + text2num(color_matrix_last[7]), + text2num(color_matrix_last[8]), + text2num(color_matrix_last[9]), + text2num(color_matrix_last[10]), + text2num(color_matrix_last[11]), + text2num(color_matrix_last[12]) + ) + if(!check_valid_color(cm, usr)) + return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) - if(href_list["toggle_matrix_mode"]) - matrix_mode = !matrix_mode - updateUsrDialog() + if(COLORMATE_TINT) + if(!check_valid_color(activecolor, usr)) + return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) - if(href_list["matrix_paint"]) - if(!inserted) - return - // assemble matrix - var/list/cm = rgb_construct_color_matrix( - text2num(href_list["rr"]), - text2num(href_list["rg"]), - text2num(href_list["rb"]), - text2num(href_list["gr"]), - text2num(href_list["gg"]), - text2num(href_list["gb"]), - text2num(href_list["br"]), - text2num(href_list["bg"]), - text2num(href_list["bb"]), - text2num(href_list["cr"]), - text2num(href_list["cg"]), - text2num(href_list["cb"]) - ) - color_matrix_last = cm.Copy() - if(!check_valid_color(cm, usr)) - return - inserted.add_atom_colour(cm, FIXED_COLOUR_PRIORITY) - playsound(src, 'sound/effects/spray3.ogg', 50, 1) - updateUsrDialog() + if(COLORMATE_HSV) + cm = color_matrix_hsv(build_hue, build_sat, build_val) + color_matrix_last = cm + if(!check_valid_color(cm, usr)) + return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) - if(href_list["clear"]) - if(!inserted) - return - inserted.remove_atom_colour(FIXED_COLOUR_PRIORITY) - playsound(src, 'sound/effects/spray3.ogg', 50, 1) - updateUsrDialog() + var/cur_color = inserted.color + inserted.color = null + inserted.color = (active_mode == COLORMATE_TINT ? activecolor : cm) + var/icon/preview = getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE) + inserted.color = cur_color + temp = "" - if(href_list["eject"]) - if(!inserted) - return - inserted.forceMove(drop_location()) - inserted = null - update_icon() - updateUsrDialog() + . = preview /obj/machinery/gear_painter/proc/check_valid_color(list/cm, mob/user) if(!islist(cm)) // normal var/list/HSV = ReadHSV(RGBtoHSV(cm)) if(HSV[3] < minimum_normal_lightness) - to_chat(user, "[cm] is far too dark (min lightness [minimum_normal_lightness]!") + temp = "[cm] is too dark (Minimum lightness: [minimum_normal_lightness])" return FALSE return TRUE else // matrix @@ -245,6 +301,6 @@ COLORTEST("FFFFFF", cm) #undef COLORTEST if(passed < minimum_matrix_tests) - to_chat(user, "[english_list(color)] is not allowed (pased [passed] out of 4, minimum [minimum_matrix_tests], minimum lightness [minimum_matrix_lightness]).") + temp = "Matrix is too dark. (passed [passed] out of [minimum_matrix_tests] required tests. Minimum lightness: [minimum_matrix_lightness])." return FALSE return TRUE diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index b837553b38..2830031781 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -13,7 +13,7 @@ var/datum/techweb/linked_techweb light_color = LIGHT_COLOR_BLUE -/obj/machinery/computer/operating/Initialize() +/obj/machinery/computer/operating/Initialize(mapload) . = ..() linked_techweb = SSresearch.science_tech find_table() diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index a2d32e0d4f..6b1d28fcba 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -8,7 +8,7 @@ active_power_usage = 300 max_integrity = 200 integrity_failure = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 40, "acid" = 20) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 40, ACID = 20) var/brightness_on = 1 var/icon_keyboard = "generic_key" var/icon_screen = "generic" @@ -17,12 +17,8 @@ /obj/machinery/computer/Initialize(mapload, obj/item/circuitboard/C) . = ..() - power_change() -/obj/machinery/computer/Destroy() - . = ..() - /obj/machinery/computer/process() if(stat & (NOPOWER|BROKEN)) return FALSE @@ -105,10 +101,10 @@ switch(severity) if(1) if(prob(50)) - obj_break("energy") + obj_break(ENERGY) if(2) if(prob(10)) - obj_break("energy") + obj_break(ENERGY) /obj/machinery/computer/deconstruct(disassembled = TRUE, mob/user) on_deconstruction() @@ -119,6 +115,9 @@ A.circuit = circuit // Circuit removal code is handled in /obj/machinery/Exited() circuit.forceMove(A) + // no it's not 4head the circuit's in nullspace which means this won't be called!! + circuit = null + component_parts -= circuit A.set_anchored(TRUE) if(stat & BROKEN) if(user) diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index bd7ae64e16..92040e3647 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -61,13 +61,16 @@ /obj/machinery/computer/aifixer/proc/Fix() use_power(1000) - occupier.adjustOxyLoss(-1, 0) - occupier.adjustFireLoss(-1, 0) - occupier.adjustToxLoss(-1, 0) - occupier.adjustBruteLoss(-1, 0) + occupier.adjustOxyLoss(-1, FALSE, FALSE) + occupier.adjustFireLoss(-1, FALSE, FALSE) + occupier.adjustBruteLoss(-5, FALSE) + occupier.updatehealth() if(occupier.health >= 0 && occupier.stat == DEAD) - occupier.revive() + occupier.revive(full_heal = FALSE, admin_revive = FALSE) + if(!occupier.radio_enabled) + occupier.radio_enabled = TRUE + to_chat(occupier, span_warning("Your Subspace Transceiver has been enabled!")) return occupier.health < 100 /obj/machinery/computer/aifixer/process() diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index dd2ebf287f..276c1796b3 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -77,14 +77,13 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( /obj/machinery/computer/arcade/proc/Reset() return -/obj/machinery/computer/arcade/Initialize() +/obj/machinery/computer/arcade/Initialize(mapload) . = ..() // If it's a generic arcade machine, pick a random arcade // circuit board for it and make the new machine if(!circuit) - var/list/gameodds = list(/obj/item/circuitboard/computer/arcade/battle = 33, - /obj/item/circuitboard/computer/arcade/orion_trail = 33, - /obj/item/circuitboard/computer/arcade/minesweeper = 33, + var/list/gameodds = list(/obj/item/circuitboard/computer/arcade/battle = 50, + /obj/item/circuitboard/computer/arcade/orion_trail = 50, /obj/item/circuitboard/computer/arcade/amputation = 2) var/thegame = pickweight(gameodds) var/obj/item/circuitboard/CB = new thegame() diff --git a/code/game/machinery/computer/arcade/battle.dm b/code/game/machinery/computer/arcade/battle.dm index 8240a22290..b668b648f2 100644 --- a/code/game/machinery/computer/arcade/battle.dm +++ b/code/game/machinery/computer/arcade/battle.dm @@ -258,8 +258,8 @@ //heccing chonker passive, only gives more HP at the start of a new game but has one of the hardest weakpoint to trigger. if(LAZYACCESS(enemy_passive, "chonker")) - if(weakpoint_check("chonker","power_attack","power_attack","power_attack")) - list_temp += "

    After a lot of power attacks you manage to tip over [enemy_name] as they fall over their enormous weight

    " + if(weakpoint_check("chonker","attack","attack","power_attack")) + list_temp += "

    After attacking twice, your power attack manages to tip over [enemy_name] as they fall over their enormous weight

    " enemy_hp -= 30 //smart passive trait, mainly works in tandem with other traits, makes the enemy unable to be counter_attacked @@ -302,7 +302,7 @@ else if(!enemy_stance) var/added_temp - if(rand()) + if(prob(80)) added_temp = "you for [attack_amount + 5] damage!" player_hp -= attack_amount + 5 enemy_stance = "attack" @@ -451,7 +451,7 @@ msg += "\tshotgun -> defend, defend, power attack" msg += "\tshort temper -> counter, counter, counter" msg += "\tpoisonous -> light attack, light attack, light attack" - msg += "\tchonker -> power attack, power attack, power attack" + msg += "\tchonker -> light attack, light attack, power attack" return msg /obj/machinery/computer/arcade/battle/emag_act(mob/user) diff --git a/code/game/machinery/computer/arcade/minesweeper.dm b/code/game/machinery/computer/arcade/minesweeper.dm deleted file mode 100644 index dbd9890c81..0000000000 --- a/code/game/machinery/computer/arcade/minesweeper.dm +++ /dev/null @@ -1,420 +0,0 @@ -#define MINESWEEPER_GAME_MAIN_MENU 0 -#define MINESWEEPER_GAME_PLAYING 1 -#define MINESWEEPER_GAME_LOST 2 -#define MINESWEEPER_GAME_WON 3 -#define MINESWEEPERIMG(what) {""} //Basically bypassing asset.icon_tag() - -/obj/machinery/computer/arcade/minesweeper - name = "Minesweeper" - desc = "An arcade machine that generates grids. It seems that the machine sparks and screeches when a grid is generated, as if it cannot cope with the intensity of generating the grid." - icon_state = "arcade" - circuit = /obj/item/circuitboard/computer/arcade/minesweeper - var/area - var/difficulty = "" //To show what difficulty you are playing - var/flag_text = "" - var/flagging = FALSE - var/game_status = MINESWEEPER_GAME_MAIN_MENU - var/mine_limit = 0 - var/mine_placed = 0 - var/mine_sound = TRUE //So it doesn't get repeated when multiple mines are exposed - var/randomcolour = 1 - var/randomnumber = 1 //Random emagged game iteration number to be displayed, put here so it is persistent across one individual arcade machine - var/safe_squares_revealed - var/saved_web = "" //To display the web if you click on the arcade - var/win_condition - var/rows = 1 - var/columns = 1 - var/table[31][51] //Make the board boys, 30x50 board - var/spark_spam = FALSE - -/obj/machinery/computer/arcade/minesweeper/interact(mob/user) - var/emagged = CHECK_BITFIELD(obj_flags, EMAGGED) - var/dat - if(game_status == MINESWEEPER_GAME_MAIN_MENU) - dat += "Minesweeper
    Minesweeper[emagged ? " EXTREME EDITION: Iteration #[randomnumber]" : ""]
    " //Different colour mix for every random number made - dat += " [emagged ? "Explode in the game, explode in real life" : "Reveal all the squares without hitting a mine"]!
    What difficulty do you want to play?



    Easy (9x9 board, 10 mines)
    Intermediate (16x16 board, 40 mines)
    Hard (16x30 board, 99 mines)
    Custom" - else - dat = saved_web - user = usr - - var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/minesweeper) - assets.send(user) - - user << browse(dat,"window=minesweeper,size=400x500") - add_fingerprint(user) - - . = ..() - -/obj/machinery/computer/arcade/minesweeper/proc/reset_spark_spam() - spark_spam = FALSE - -/obj/machinery/computer/arcade/minesweeper/Topic(href, href_list) - . = ..() - if(.) - return - - var/exploding_hell = FALSE //For emagged failures - var/reset_board = FALSE - var/mob/living/user = usr //To identify who the hell is using this window, this should also make things like aliens and monkeys able to use the machine!! - var/web_difficulty_menu = " Reveal all the squares without hitting a mine!
    What difficulty do you want to play?



    Easy (9x9 board, 10 mines)
    Intermediate (16x16 board, 40 mines)
    Hard (16x30 board, 99 mines)
    Custom" - var/web = "Minesweeper
    Minesweeper
    " - var/static_web = "Minesweeper
    Minesweeper
    " //When we need to revert to the main menu we set web as this - web = static_web - - if(CHECK_BITFIELD(obj_flags, EMAGGED)) - web = "Minesweeper
    Minesweeper EXTREME EDITION: Iteration #[randomnumber]
    " //Different colour mix for every random number made - if(!spark_spam) - do_sparks(5, 1, src) - spark_spam = TRUE - addtimer(CALLBACK(src, .proc/reset_spark_spam), 30) - - - var/startup_sound = CHECK_BITFIELD(obj_flags, EMAGGED) ? 'sound/arcade/minesweeper_emag2.ogg' : 'sound/arcade/minesweeper_startup.ogg' - - if(href_list["Main_Menu"]) - game_status = MINESWEEPER_GAME_MAIN_MENU - mine_limit = 0 - rows = 0 - columns = 0 - mine_placed = 0 - if(href_list["Easy"]) - playsound(loc, startup_sound, 50, FALSE, extrarange = -3) - flag_text = "OFF" - game_status = MINESWEEPER_GAME_PLAYING - reset_board = TRUE - difficulty = "Easy" - rows = 10 //9x9 board - columns = 10 - mine_limit = 10 - if(href_list["Intermediate"]) - playsound(loc, startup_sound, 50, FALSE, extrarange = -3) - flag_text = "OFF" - game_status = MINESWEEPER_GAME_PLAYING - reset_board = TRUE - difficulty = "Intermediate" - rows = 17 //16x16 board - columns = 17 - mine_limit = 40 - if(href_list["Hard"]) - playsound(loc, startup_sound, 50, FALSE, extrarange = -3) - flag_text = "OFF" - game_status = MINESWEEPER_GAME_PLAYING - reset_board = TRUE - difficulty = "Hard" - rows = 17 //16x30 board - columns = 31 - mine_limit = 99 - if(href_list["Custom"]) - if(custom_generation(usr)) - flag_text = "OFF" - game_status = MINESWEEPER_GAME_PLAYING - reset_board = TRUE - difficulty = "Custom" - playsound(loc, startup_sound, 50, FALSE, extrarange = -3) - if(href_list["Flag"]) - playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, FALSE, extrarange = -3) - if(!flagging) - flagging = TRUE - flag_text = "ON" - else - flagging = FALSE - flag_text = "OFF" - - if(game_status == MINESWEEPER_GAME_MAIN_MENU) - if(CHECK_BITFIELD(obj_flags, EMAGGED)) - playsound(loc, 'sound/arcade/minesweeper_emag2.ogg', 50, FALSE, extrarange = -3) - web += "Explode in the game, explode in real life!
    What difficulty do you want to play?



    Easy (9x9 board, 10 mines)
    Intermediate (16x16 board, 40 mines)
    Hard (16x30 board, 99 mines)
    Custom" - else - playsound(loc, 'sound/arcade/minesweeper_startup.ogg', 50, FALSE, extrarange = -3) - web += web_difficulty_menu - - if(game_status == MINESWEEPER_GAME_PLAYING) - mine_sound = TRUE - - area = (rows-1)*(columns-1) - - if(reset_board) - mine_placed = 0 - var/reset_everything = TRUE - make_mines(reset_everything) - - safe_squares_revealed = 0 - win_condition = area-mine_placed - - if(game_status != MINESWEEPER_GAME_MAIN_MENU) - for(var/y1=1;y1= 0) //Check that it's not already revealed, and stop flag removal if we're out of flag mode - table[y1][x1] += 10 - if(table[y1][x1] != 10) - playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, FALSE, extrarange = -3) - else - if(game_status != MINESWEEPER_GAME_LOST && game_status != MINESWEEPER_GAME_WON) - game_status = MINESWEEPER_GAME_LOST - if(CHECK_BITFIELD(obj_flags, EMAGGED) && !exploding_hell) - exploding_hell = TRUE - explode_EVERYTHING() - if(QDELETED(src)) - return - if(mine_sound) - switch(rand(1,3)) //Play every time a mine is hit - if(1) - playsound(loc, 'sound/arcade/minesweeper_explosion1.ogg', 50, FALSE, extrarange = -3) - if(2) - playsound(loc, 'sound/arcade/minesweeper_explosion2.ogg', 50, FALSE, extrarange = -3) - if(3) - playsound(loc, 'sound/arcade/minesweeper_explosion3.ogg', 50, FALSE, extrarange = -3) - mine_sound = FALSE - else - playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, FALSE, extrarange = -3) - if(table[y1][x1] >= 0) //Check that it's not already flagged - table[y1][x1] -= 10 - else if(table[y1][x1] < 0) //If flagged, remove the flag - table[y1][x1] += 10 - if(href_list["same_board"]) //Reset the board... kinda - if(game_status != MINESWEEPER_GAME_PLAYING) - mine_sound = TRUE - game_status = MINESWEEPER_GAME_PLAYING - if(table[y1][x1] >= 10) //If revealed, become unrevealed! - if(mine_sound) - playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3) - mine_sound = FALSE - table[y1][x1] -= 10 - if(table[y1][x1] > 10 && !reset_board) - safe_squares_revealed += 1 - var/y2 = y1 - var/x2 = x1 - work_squares(y2, x2) //Work squares while in this loop so there's less load - reset_board = FALSE - - web += "" //Start setting up the html table - web += "" - for(var/y1=1;y1= win_condition && game_status == MINESWEEPER_GAME_PLAYING) - game_status = MINESWEEPER_GAME_WON - if(rows < 10 || columns < 10) //If less than easy difficulty - playsound(loc, 'sound/arcade/minesweeper_winfail.ogg', 50, FALSE, extrarange = -3) - say("You cleared the board of all mines, but you picked too small of a board! Try again with at least a 9x9 board!") - else - playsound(loc, 'sound/arcade/minesweeper_win.ogg', 50, FALSE, extrarange = -3) - say("You cleared the board of all mines! Congratulations!") - if(CHECK_BITFIELD(obj_flags, EMAGGED)) - var/itemname - switch(rand(1,3)) - if(1) - itemname = "a syndicate bomb beacon" - new /obj/item/sbeacondrop/bomb(loc) - if(2) - itemname = "a rocket launcher" - new /obj/item/gun/ballistic/rocketlauncher/unrestricted(loc) - new /obj/item/ammo_casing/caseless/rocket(loc) - new /obj/item/ammo_casing/caseless/rocket(loc) - new /obj/item/ammo_casing/caseless/rocket(loc) - if(3) - itemname = "two bags of c4" - new /obj/item/storage/backpack/duffelbag/syndie/c4(loc) - new /obj/item/storage/backpack/duffelbag/syndie/x4(loc) - message_admins("[key_name_admin(user)] won emagged Minesweeper and got [itemname]!") - visible_message("[src] dispenses [itemname]!", "You hear a chime and a clunk.") - DISABLE_BITFIELD(obj_flags, EMAGGED) - else - var/dope_prizes = (area >= 480) ? 6 : (area >= 256) ? 4 : 2 - prizevend(user, dope_prizes) - - if(game_status == MINESWEEPER_GAME_WON) - web += "[(rows < 10 || columns < 10) ? "You won, but your board was too small! Pick a bigger board next time!" : "Congratulations, you have won!"]
    Want to play again?
    Easy (9x9 board, 10 mines)
    Intermediate (16x16 board, 40 mines)
    Hard (16x30 board, 99 mines)
    Custom

    Play on the same board
    Return to Main Menu
    " - - if(game_status == MINESWEEPER_GAME_LOST) - web += "You have lost!
    Try again?
    Easy (9x9 board, 10 mines)
    Intermediate (16x16 board, 40 mines)
    Hard (16x30 board, 99 mines)
    Custom

    Play on the same board
    Return to Main Menu
    " - - if(game_status == MINESWEEPER_GAME_PLAYING) - web += "Return to Main Menu
    " - web += "
    Difficulty: [difficulty]
    Mines: [mine_placed]
    Rows: [rows-1]
    Columns: [columns-1]
    Flagging mode: [flag_text]
    " - - web += "" - var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/minesweeper) - saved_web = sheet.css_tag() - saved_web += web - updateDialog() - return - -/obj/machinery/computer/arcade/minesweeper/emag_act(mob/user) - . = ..() - if(CHECK_BITFIELD(obj_flags, EMAGGED)) - return - desc = "An arcade machine that generates grids. It's clunking and sparking everywhere, almost as if threatening to explode at any moment!" - do_sparks(5, 1, src) - randomnumber = rand(1,255) - randomcolour = rgb(randomnumber,randomnumber/2,randomnumber/3) - ENABLE_BITFIELD(obj_flags, EMAGGED) - if(game_status == MINESWEEPER_GAME_MAIN_MENU) - to_chat(user, "An ominous tune plays from the arcade's speakers!") - playsound(user, 'sound/arcade/minesweeper_emag1.ogg', 100, FALSE, extrarange = 3) - else //Can't let you do that, star fox! - to_chat(user, "The machine buzzes and sparks... the game has been reset!") - playsound(user, 'sound/machines/buzz-sigh.ogg', 100, FALSE, extrarange = 3) //Loud buzz - game_status = MINESWEEPER_GAME_MAIN_MENU - return TRUE - -/obj/machinery/computer/arcade/minesweeper/proc/custom_generation(mob/user) - playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3) //Entered into the menu so ping sound - var/new_rows = input(user, "How many rows do you want? (Minimum: 4, Maximum: 30)", "Minesweeper Rows") as null|num - if(!new_rows || !user.canUseTopic(src, !hasSiliconAccessInArea(user))) - return FALSE - new_rows = clamp(new_rows + 1, 4, 20) - playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3) - var/new_columns = input(user, "How many columns do you want? (Minimum: 4, Maximum: 50)", "Minesweeper Squares") as null|num - if(!new_columns || !user.canUseTopic(src, !hasSiliconAccessInArea(user))) - return FALSE - new_columns = clamp(new_columns + 1, 4, 30) - playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3) - var/grid_area = (new_rows - 1) * (new_columns - 1) - var/lower_limit = round(grid_area*0.156) - var/upper_limit = round(grid_area*0.85) - var/new_mine_limit = input(user, "How many mines do you want? (Minimum: [lower_limit], Maximum: [upper_limit])", "Minesweeper Mines") as null|num - if(!new_mine_limit || !user.canUseTopic(src, !hasSiliconAccessInArea(user))) - return FALSE - playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3) - rows = new_rows - columns = new_columns - mine_limit = clamp(new_mine_limit, lower_limit, upper_limit) - return TRUE - -/obj/machinery/computer/arcade/minesweeper/proc/make_mines(var/reset_everything) - if(mine_placed < mine_limit) - for(var/y1=1;y1 0 && x3 > 0) - y2 = y3 - x2 = x3 - if(table[y2][x2] == 1) - for(y3=y2-1;y3= rows || y3 < 1) - continue - for(x3=x2-1;x3= columns || x3 < 1) - continue - if(table[y3][x3] == 0) - table[y2][x2] += 1 - if(table[y2][x2] == 11) - for(y3=y2-1;y3= rows || y3 < 1) - continue - for(x3=x2-1;x3= columns || x3 < 1) - continue - if(table[y3][x3] > 0 && table[y3][x3] < 10) - table[y3][x3] += 10 - work_squares(y3, x3) //Refresh so we check everything we might be missing - -/obj/machinery/computer/arcade/minesweeper/proc/explode_EVERYTHING() - var/mob/living/user = usr - to_chat(user, "You feel a great sense of dread wash over you, as if you just unleashed armageddon upon yourself!") - var/row_limit = rows-1 - var/column_limit = columns-1 - var/mine_limit_v2 = mine_limit - if(rows > 21) - row_limit = 20 - if(columns > 21) - column_limit = 20 - if(mine_limit > (rows*columns) * 0.25) - mine_limit_v2 = 24 - message_admins("[key_name_admin(user)] failed an emagged Minesweeper arcade and has unleashed an explosion armageddon of size [row_limit],[column_limit] around [ADMIN_LOOKUPFLW(user.loc)]!") - if(mine_limit_v2 < 10) - explosion(loc, 2, 5, 10, 15) //Thought you could survive by putting as few mines as possible, huh?? - else - explosion(loc, 1, 3, rand(1,5), rand(1,10)) - var/list/targets = list() - var/cur_y = y - round(row_limit * 0.5, 1) - var/starting_row = 1 - if(cur_y < 1) - starting_row -= cur_y - 1 - cur_y = 1 - var/start_x = x - round(column_limit * 0.5, 1) - var/starting_column = 1 - if(start_x < 1) - starting_column -= start_x - 1 - start_x = 1 - for(var/row in starting_row to length(table)) //translate the mines locations into actual turf coordinates. - if(!locate(cur_y, start_x, z)) - break - var/cur_x = start_x - for(var/column in starting_column to length(table[row])) - var/coord_value = table[row][column] - if(coord_value == 10 || coord_value == 0) //there is a mine in here. - var/turf/T = locate(cur_y, cur_x, z) - if(!T) - break - targets += T - cur_x++ - cur_y++ - var/num_explosions = 0 - for(var/T in shuffle(targets)) //Create a shitton of explosions in irl turfs if we lose, it will probably kill us - addtimer(CALLBACK(GLOBAL_PROC, /proc/explosion, T, 0, rand(1,2),rand(1,5),rand(3,10), FALSE), 15 * ++num_explosions) - if(num_explosions == mine_limit_v2) - return - -#undef MINESWEEPERIMG -#undef MINESWEEPER_GAME_MAIN_MENU -#undef MINESWEEPER_GAME_PLAYING -#undef MINESWEEPER_GAME_LOST -#undef MINESWEEPER_GAME_WON diff --git a/code/game/machinery/computer/arcade/orion_trail.dm b/code/game/machinery/computer/arcade/orion_trail.dm index 58617a0cf3..21b0ac1cc0 100644 --- a/code/game/machinery/computer/arcade/orion_trail.dm +++ b/code/game/machinery/computer/arcade/orion_trail.dm @@ -61,7 +61,7 @@ var/killed_crew = 0 -/obj/machinery/computer/arcade/orion_trail/Initialize() +/obj/machinery/computer/arcade/orion_trail/Initialize(mapload) . = ..() Radio = new /obj/item/radio(src) Radio.listening = 0 diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm index 50a6d10302..f4851fc33c 100644 --- a/code/game/machinery/computer/atmos_alert.dm +++ b/code/game/machinery/computer/atmos_alert.dm @@ -11,7 +11,7 @@ light_color = LIGHT_COLOR_CYAN -/obj/machinery/computer/atmos_alert/Initialize() +/obj/machinery/computer/atmos_alert/Initialize(mapload) . = ..() set_frequency(receive_frequency) diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index fa552a4e66..7eb6c79eef 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -6,7 +6,7 @@ name = "gas sensor" icon = 'icons/obj/stationobjs.dmi' icon_state = "gsensor1" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 0) var/on = TRUE @@ -71,13 +71,13 @@ frequency = new_frequency radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) -/obj/machinery/air_sensor/Initialize() +/obj/machinery/air_sensor/Initialize(mapload) . = ..() - SSair.atmos_air_machinery += src + SSair.atmos_machinery += src set_frequency(frequency) /obj/machinery/air_sensor/Destroy() - SSair.atmos_air_machinery -= src + SSair.atmos_machinery -= src SSradio.remove_object(src, frequency) return ..() @@ -126,7 +126,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers) var/datum/radio_frequency/radio_connection -/obj/machinery/computer/atmos_control/Initialize() +/obj/machinery/computer/atmos_control/Initialize(mapload) . = ..() GLOB.atmos_air_controllers += src set_frequency(frequency) diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index 47343ea58f..c18d146e90 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -151,6 +151,7 @@ new_computer.RefreshParts() new_computer.on_construction() + new_computer.circuit.moveToNullspace() qdel(src) return diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index a6b774523c..ec897f97e2 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -23,7 +23,7 @@ interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_SET_MACHINE //| INTERACT_MACHINE_REQUIRES_SIGHT -/obj/machinery/computer/security/Initialize() +/obj/machinery/computer/security/Initialize(mapload) . = ..() // Map name has to start and end with an A-Z character, // and definitely NOT with a square bracket or even a number. @@ -275,7 +275,7 @@ var/icon_state_off = "entertainment_blank" var/icon_state_on = "entertainment" -/obj/machinery/computer/security/telescreen/entertainment/Initialize() +/obj/machinery/computer/security/telescreen/entertainment/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_CLICK, .proc/BigClick) diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index 9d675bc5dd..30463f4f01 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -16,7 +16,7 @@ light_color = LIGHT_COLOR_RED -/obj/machinery/computer/camera_advanced/Initialize() +/obj/machinery/computer/camera_advanced/Initialize(mapload) . = ..() for(var/i in networks) networks -= i @@ -275,7 +275,7 @@ if(final) playsound(origin, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0) remote_eye.setLoc(get_turf(final)) - C.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/flash/static) + C.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/tiled/flash/static) C.clear_fullscreen("flash", 3) //Shorter flash than normal since it's an ~~advanced~~ console! else playsound(origin, 'sound/machines/terminal_prompt_deny.ogg', 25, 0) diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 46d419a8fe..a16e70155f 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -56,7 +56,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) /obj/machinery/computer/card/centcom/get_jobs() return get_all_centcom_jobs() -/obj/machinery/computer/card/Initialize() +/obj/machinery/computer/card/Initialize(mapload) . = ..() change_position_cooldown = CONFIG_GET(number/id_console_jobslot_delay) @@ -586,7 +586,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) icon_screen = "idminor" circuit = /obj/item/circuitboard/computer/card/minor -/obj/machinery/computer/card/minor/Initialize() +/obj/machinery/computer/card/minor/Initialize(mapload) . = ..() var/obj/item/circuitboard/computer/card/minor/typed_circuit = circuit if(target_dept) diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index d034ba382e..91211d3d40 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -24,7 +24,7 @@ light_color = LIGHT_COLOR_BLUE -/obj/machinery/computer/cloning/Initialize() +/obj/machinery/computer/cloning/Initialize(mapload) . = ..() updatemodules(TRUE) var/obj/item/circuitboard/computer/cloning/board = circuit diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 822302789f..f1ed801af1 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -41,9 +41,10 @@ /// The last lines used for changing the status display var/static/last_status_display -/obj/machinery/computer/communications/Initialize() +/obj/machinery/computer/communications/Initialize(mapload) . = ..() GLOB.shuttle_caller_list += src + AddComponent(/datum/component/gps, "Secured Communications Signal") /// Are we NOT a silicon, AND we're logged in as the captain? /obj/machinery/computer/communications/proc/authenticated_as_non_silicon_captain(mob/user) @@ -79,17 +80,16 @@ if (obj_flags & EMAGGED) return obj_flags |= EMAGGED - SSshuttle.shuttle_purchase_requirements_met |= "emagged" if (authenticated) authorize_access = get_all_accesses() - to_chat(user, "You scramble the communication routing circuits!") + to_chat(user, span_danger("You scramble the communication routing circuits!")) playsound(src, 'sound/machines/terminal_alert.ogg', 50, FALSE) SSshuttle.shuttle_purchase_requirements_met["emagged"] = TRUE - return /obj/machinery/computer/communications/ui_act(action, list/params) var/static/list/approved_states = list(STATE_BUYING_SHUTTLE, STATE_CHANGING_STATUS, STATE_MAIN, STATE_MESSAGES) var/static/list/approved_status_pictures = list("biohazard", "blank", "default", "lockdown", "redalert", "shuttle") + var/static/list/state_status_pictures = list("blank", "shuttle") . = ..() if (.) @@ -104,6 +104,7 @@ if ("answerMessage") if (!authenticated(usr)) return + var/answer_index = params["answer"] var/message_index = params["message"] @@ -136,11 +137,11 @@ var/obj/item/held_item = usr.get_active_held_item() var/obj/item/card/id/id_card = held_item?.GetID() if (!istype(id_card)) - to_chat(usr, "You need to swipe your ID!") + to_chat(usr, span_warning("You need to swipe your ID!")) playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) return if (!(ACCESS_CAPTAIN in id_card.access)) - to_chat(usr, "You are not authorized to do this!") + to_chat(usr, span_warning("You are not authorized to do this!")) playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) return @@ -152,26 +153,28 @@ set_security_level(new_sec_level) - to_chat(usr, "Authorization confirmed. Modifying security level.") + to_chat(usr, span_notice("Authorization confirmed. Modifying security level.")) playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) // Only notify people if an actual change happened log_game("[key_name(usr)] has changed the security level to [params["newSecurityLevel"]] with [src] at [AREACOORD(usr)].") message_admins("[ADMIN_LOOKUPFLW(usr)] has changed the security level to [params["newSecurityLevel"]] with [src] at [AREACOORD(usr)].") - deadchat_broadcast(" has changed the security level to [params["newSecurityLevel"]] with [src] at [get_area_name(usr, TRUE)].", "[usr.real_name]", usr) + deadchat_broadcast(" has changed the security level to [params["newSecurityLevel"]] with [src] at [span_name("[get_area_name(usr, TRUE)]")].", span_name("[usr.real_name]"), usr, message_type=DEADCHAT_ANNOUNCEMENT) alert_level_tick += 1 if ("deleteMessage") if (!authenticated(usr)) return - var/message_index = params["message"] - - if(!isnum(message_index)) - message_admins("[ADMIN_LOOKUPFLW(usr)] provided an invalid index type when deleting a message on [src] [ADMIN_JMP(src)]. This should not happen. Please check with a maintainer and/or consult tgui logs.") - CRASH("Non-numeric index provided when deleting comms console message.") + var/message_index = text2num(params["message"]) if (!message_index) return LAZYREMOVE(messages, LAZYACCESS(messages, message_index)) + if ("emergency_meeting") + if(!(SSevents.holidays && SSevents.holidays[APRIL_FOOLS])) + return + if (!authenticated_as_silicon_or_captain(usr)) + return + emergency_meeting(usr) if ("makePriorityAnnouncement") if (!authenticated_as_silicon_or_captain(usr)) return @@ -188,32 +191,36 @@ var/emagged = obj_flags & EMAGGED if (emagged) message_syndicate(message, usr) - to_chat(usr, "SYSERR @l(19833)of(transmit.dm): !@$ MESSAGE TRANSMITTED TO SYNDICATE COMMAND.") + to_chat(usr, span_danger("SYSERR @l(19833)of(transmit.dm): !@$ MESSAGE TRANSMITTED TO SYNDICATE COMMAND.")) else message_centcom(message, usr) - to_chat(usr, "Message transmitted to Central Command.") + to_chat(usr, span_notice("Message transmitted to Central Command.")) var/associates = emagged ? "the Syndicate": "CentCom" usr.log_talk(message, LOG_SAY, tag = "message to [associates]") - deadchat_broadcast(" has messaged [associates], \"[message]\" at [get_area_name(usr, TRUE)].", "[usr.real_name]", usr) + deadchat_broadcast(" has messaged [associates], \"[message]\" at [span_name("[get_area_name(usr, TRUE)]")].", span_name("[usr.real_name]"), usr, message_type = DEADCHAT_ANNOUNCEMENT) COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN) if ("purchaseShuttle") var/can_buy_shuttles_or_fail_reason = can_buy_shuttles(usr) if (can_buy_shuttles_or_fail_reason != TRUE) if (can_buy_shuttles_or_fail_reason != FALSE) - to_chat(usr, "[can_buy_shuttles_or_fail_reason]") + to_chat(usr, span_alert("[can_buy_shuttles_or_fail_reason]")) return var/list/shuttles = flatten_list(SSmapping.shuttle_templates) var/datum/map_template/shuttle/shuttle = locate(params["shuttle"]) in shuttles if (!istype(shuttle)) return + // if (!can_purchase_this_shuttle(shuttle)) + // return if (!shuttle.prerequisites_met()) - to_chat(usr, "You have not met the requirements for purchasing this shuttle.") + to_chat(usr, span_alert("You have not met the requirements for purchasing this shuttle.")) return var/datum/bank_account/bank_account = SSeconomy.get_dep_account(ACCOUNT_CAR) if (bank_account.account_balance < shuttle.credit_cost) return SSshuttle.shuttle_purchased = SHUTTLEPURCHASE_PURCHASED + // for(var/datum/round_event_control/shuttle_insurance/insurance_event in SSevents.control) + // insurance_event.weight *= 20 SSshuttle.unload_preview() SSshuttle.existing_shuttle = SSshuttle.emergency SSshuttle.action_load(shuttle, replace = TRUE) @@ -235,9 +242,9 @@ return var/reason = trim(html_encode(params["reason"]), MAX_MESSAGE_LEN) nuke_request(reason, usr) - to_chat(usr, "Request sent.") + to_chat(usr, span_notice("Request sent.")) usr.log_message("has requested the nuclear codes from CentCom with reason \"[reason]\"", LOG_SAY) - priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self-Destruct Codes Requested", "commandreport") + priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self-Destruct Codes Requested", SSstation.announcer.get_rand_report_sound()) playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE) COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN) if ("restoreBackupRoutingData") @@ -245,7 +252,7 @@ return if (!(obj_flags & EMAGGED)) return - to_chat(usr, "Backup routing data restored.") + to_chat(usr, span_notice("Backup routing data restored.")) playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) obj_flags &= ~EMAGGED if ("sendToOtherSector") @@ -256,7 +263,7 @@ if (!COOLDOWN_FINISHED(src, important_action_cooldown)) return - var/message = trim(html_encode(params["message"]), MAX_MESSAGE_LEN) + var/message = trim(params["message"], MAX_MESSAGE_LEN) if (!message) return @@ -268,12 +275,13 @@ var/network_name = CONFIG_GET(string/cross_comms_network) if (network_name) payload["network"] = network_name + payload["sender_ckey"] = usr.ckey - send2otherserver(station_name(), message, "Comms_Console", destination == "all" ? null : list(destination), additional_data = payload) + send2otherserver(html_decode(station_name()), message, "Comms_Console", destination == "all" ? null : list(destination), additional_data = payload) minor_announce(message, title = "Outgoing message to allied station") usr.log_talk(message, LOG_SAY, tag = "message to the other server") message_admins("[ADMIN_LOOKUPFLW(usr)] has sent a message to the other server\[s].") - deadchat_broadcast(" has sent an outgoing message to the other station(s).", "[usr.real_name]", usr) + deadchat_broadcast(" has sent an outgoing message to the other station(s).", "[usr.real_name]", usr, message_type = DEADCHAT_ANNOUNCEMENT) COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN) if ("setState") @@ -300,7 +308,10 @@ var/picture = params["picture"] if (!(picture in approved_status_pictures)) return - post_status("alert", picture) + if(picture in state_status_pictures) + post_status(picture) + else + post_status("alert", picture) playsound(src, "terminal_type", 50, FALSE) if ("toggleAuthentication") // Log out if we're logged in @@ -315,7 +326,7 @@ authenticated = TRUE authorize_access = get_all_accesses() authorize_name = "Unknown" - to_chat(usr, "[src] lets out a quiet alarm as its login is overridden.") + to_chat(usr, span_warning("[src] lets out a quiet alarm as its login is overridden.")) playsound(src, 'sound/machines/terminal_alert.ogg', 25, FALSE) else if(isliving(usr)) var/mob/living/L = usr @@ -334,22 +345,36 @@ revoke_maint_all_access() log_game("[key_name(usr)] disabled emergency maintenance access.") message_admins("[ADMIN_LOOKUPFLW(usr)] disabled emergency maintenance access.") - deadchat_broadcast(" disabled emergency maintenance access at [get_area_name(usr, TRUE)].", "[usr.real_name]", usr) + deadchat_broadcast(" disabled emergency maintenance access at [span_name("[get_area_name(usr, TRUE)]")].", span_name("[usr.real_name]"), usr, message_type = DEADCHAT_ANNOUNCEMENT) else make_maint_all_access() log_game("[key_name(usr)] enabled emergency maintenance access.") message_admins("[ADMIN_LOOKUPFLW(usr)] enabled emergency maintenance access.") - deadchat_broadcast(" enabled emergency maintenance access at [get_area_name(usr, TRUE)].", "[usr.real_name]", usr) + deadchat_broadcast(" enabled emergency maintenance access at [span_name("[get_area_name(usr, TRUE)]")].", span_name("[usr.real_name]"), usr, message_type = DEADCHAT_ANNOUNCEMENT) /obj/machinery/computer/communications/ui_data(mob/user) var/list/data = list( "authenticated" = FALSE, "emagged" = FALSE, - "hasConnection" = has_communication(), ) var/ui_state = issilicon(user) ? cyborg_state : state + var/has_connection = has_communication() + data["hasConnection"] = has_connection + + // if(!SSjob.assigned_captain && !SSjob.safe_code_requested && SSid_access.spare_id_safe_code && has_connection) + // data["canRequestSafeCode"] = TRUE + // data["safeCodeDeliveryWait"] = 0 + // else + // data["canRequestSafeCode"] = FALSE + // if(SSjob.safe_code_timer_id && has_connection) + // data["safeCodeDeliveryWait"] = timeleft(SSjob.safe_code_timer_id) + // data["safeCodeDeliveryArea"] = get_area(SSjob.safe_code_request_loc) + // else + // data["safeCodeDeliveryWait"] = 0 + // data["safeCodeDeliveryArea"] = null + if (authenticated || issilicon(user)) data["authenticated"] = TRUE data["canLogOut"] = !issilicon(user) @@ -371,16 +396,17 @@ data["importantActionReady"] = COOLDOWN_FINISHED(src, important_action_cooldown) data["shuttleCalled"] = FALSE data["shuttleLastCalled"] = FALSE - + data["aprilFools"] = SSevents.holidays && SSevents.holidays[APRIL_FOOLS] data["alertLevel"] = NUM2SECLEVEL(GLOB.security_level) data["authorizeName"] = authorize_name data["canLogOut"] = !issilicon(user) - data["shuttleCanEvacOrFailReason"] = SSshuttle.canEvac(user, TRUE) + data["shuttleCanEvacOrFailReason"] = SSshuttle.canEvac(user) if (authenticated_as_non_silicon_captain(user)) data["canRequestNuke"] = TRUE if (authenticated_as_non_silicon_command(user)) data["canMessageAssociates"] = TRUE + if (can_send_messages_to_other_sectors(user)) data["canSendToSectors"] = TRUE @@ -428,8 +454,13 @@ for (var/shuttle_id in SSmapping.shuttle_templates) var/datum/map_template/shuttle/shuttle_template = SSmapping.shuttle_templates[shuttle_id] - if (!shuttle_template.can_be_bought || shuttle_template.credit_cost == INFINITY) + + if (shuttle_template.credit_cost == INFINITY) continue + + if (!shuttle_template.can_be_bought) + continue + shuttles += list(list( "name" = shuttle_template.name, "description" = shuttle_template.description, @@ -478,6 +509,7 @@ return FALSE if (!authenticated_as_non_silicon_captain(user)) return FALSE + if (SSshuttle.emergency.mode != SHUTTLE_RECALL && SSshuttle.emergency.mode != SHUTTLE_IDLE) return "The shuttle is already in transit." if (SSshuttle.shuttle_purchased == SHUTTLEPURCHASE_PURCHASED) @@ -492,21 +524,38 @@ return length(CONFIG_GET(keyed_list/cross_server)) > 0 +/** + * Call an emergency meeting + * + * Comm Console wrapper for the Communications subsystem wrapper for the call_emergency_meeting world proc. + * Checks to make sure the proc can be called, and handles relevant feedback, logging and timing. + * See the SScommunications proc definition for more detail, in short, teleports the entire crew to + * the bridge for a meetup. Should only really happen during april fools. + * Arguments: + * * user - Mob who called the meeting + */ +/obj/machinery/computer/communications/proc/emergency_meeting(mob/living/user) + if(!SScommunications.can_make_emergency_meeting(user)) + to_chat(user, span_alert("The emergency meeting button doesn't seem to work right now. Please stand by.")) + return + SScommunications.emergency_meeting(user) + deadchat_broadcast(" called an emergency meeting from [span_name("[get_area_name(usr, TRUE)]")].", span_name("[user.real_name]"), user, message_type=DEADCHAT_ANNOUNCEMENT) + /obj/machinery/computer/communications/proc/make_announcement(mob/living/user) var/is_ai = issilicon(user) if(!SScommunications.can_announce(user, is_ai)) - to_chat(user, "Intercomms recharging. Please stand by.") + to_chat(user, span_alert("Intercomms recharging. Please stand by.")) return var/input = stripped_input(user, "Please choose a message to announce to the station crew.", "What?") if(!input || !user.canUseTopic(src, !issilicon(usr))) return if(!(user.can_speak())) //No more cheating, mime/random mute guy! input = "..." - to_chat(user, "You find yourself unable to speak.") + to_chat(user, span_warning("You find yourself unable to speak.")) else input = user.treat_message(input) //Adds slurs and so on. Someone should make this use languages too. SScommunications.make_announcement(user, is_ai, input) - deadchat_broadcast(" made a priority announcement from [get_area_name(usr, TRUE)].", "[user.real_name]", user) + deadchat_broadcast(" made a priority announcement from [span_name("[get_area_name(usr, TRUE)]")].", span_name("[user.real_name]"), user, message_type=DEADCHAT_ANNOUNCEMENT) /obj/machinery/computer/communications/proc/post_status(command, data1, data2) diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index 19da4f75d8..bf690398a4 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -200,6 +200,9 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) return b["totaldam"] - a["totaldam"] /datum/crewmonitor/ui_act(action,params) + . = ..() + if(.) + return var/mob/living/silicon/ai/AI = usr if(!istype(AI)) return diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm index 3d212ec0cb..b6b01ff03b 100644 --- a/code/game/machinery/computer/dna_console.dm +++ b/code/game/machinery/computer/dna_console.dm @@ -199,7 +199,7 @@ eject_disk(user) -/obj/machinery/computer/scan_consolenew/Initialize() +/obj/machinery/computer/scan_consolenew/Initialize(mapload) . = ..() // Connect with a nearby DNA Scanner on init @@ -263,7 +263,7 @@ if(!ui) ui = new(user, src, "DnaConsole") ui.open() - + /obj/machinery/computer/scan_consolenew/ui_assets() . = ..() || list() . += get_asset_datum(/datum/asset/simple/genetics) diff --git a/code/game/machinery/computer/launchpad_control.dm b/code/game/machinery/computer/launchpad_control.dm index 18a0aeb221..4ec80b5bb4 100644 --- a/code/game/machinery/computer/launchpad_control.dm +++ b/code/game/machinery/computer/launchpad_control.dm @@ -11,7 +11,7 @@ var/list/obj/machinery/launchpad/launchpads var/maximum_pads = 4 -/obj/machinery/computer/launchpad/Initialize() +/obj/machinery/computer/launchpad/Initialize(mapload) launchpads = list() . = ..() @@ -100,6 +100,7 @@ var/new_x = text2num(params["x"]) var/new_y = text2num(params["y"]) current_pad.set_offset(new_x, new_y) + current_pad.update_indicator() . = TRUE if("move_pos") var/plus_x = text2num(params["x"]) @@ -108,6 +109,7 @@ x = current_pad.x_offset + plus_x, y = current_pad.y_offset + plus_y ) + current_pad.update_indicator() . = TRUE if("rename") . = TRUE @@ -119,12 +121,15 @@ if(usr && alert(usr, "Are you sure?", "Unlink Launchpad", "I'm Sure", "Abort") != "Abort") launchpads -= current_pad selected_id = null + current_pad.update_indicator() . = TRUE if("launch") teleport(usr, current_pad, TRUE) + current_pad.update_indicator() . = TRUE if("pull") teleport(usr, current_pad, FALSE) + current_pad.update_indicator() . = TRUE . = TRUE diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm index f1cf187ff9..a7071ac72e 100644 --- a/code/game/machinery/computer/pod.dm +++ b/code/game/machinery/computer/pod.dm @@ -15,7 +15,7 @@ /// Countdown timer for the mass driver's delayed launch functionality. COOLDOWN_DECLARE(massdriver_countdown) -/obj/machinery/computer/pod/Initialize() +/obj/machinery/computer/pod/Initialize(mapload) . = ..() for(var/obj/machinery/mass_driver/M in range(range, src)) if(M.id == id) diff --git a/code/game/machinery/computer/prisoner/gulag_teleporter.dm b/code/game/machinery/computer/prisoner/gulag_teleporter.dm index 13727b585b..70b66c1b87 100644 --- a/code/game/machinery/computer/prisoner/gulag_teleporter.dm +++ b/code/game/machinery/computer/prisoner/gulag_teleporter.dm @@ -15,7 +15,7 @@ light_color = LIGHT_COLOR_RED -/obj/machinery/computer/prisoner/gulag_teleporter_computer/Initialize() +/obj/machinery/computer/prisoner/gulag_teleporter_computer/Initialize(mapload) . = ..() scan_machinery() diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm index 7b2e6ab455..df84d5a26a 100644 --- a/code/game/machinery/computer/station_alert.dm +++ b/code/game/machinery/computer/station_alert.dm @@ -8,7 +8,7 @@ light_color = LIGHT_COLOR_CYAN -/obj/machinery/computer/station_alert/Initialize() +/obj/machinery/computer/station_alert/Initialize(mapload) . = ..() GLOB.alert_consoles += src @@ -33,31 +33,46 @@ return data -/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/A, O, obj/source) +/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/home, cameras, obj/source) if(source.z != z) return if(stat & (BROKEN)) return - var/list/L = alarms[class] - for(var/I in L) - if (I == A.name) - var/list/alarm = L[I] + var/list/our_sort = alarms[class] + for(var/areaname in our_sort) + if (areaname == home.name) + var/list/alarm = our_sort[areaname] var/list/sources = alarm[3] if (!(source in sources)) sources += source - return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if(O && islist(O)) - CL = O - if (CL.len == 1) - C = CL[1] - else if(O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C ? C : O), list(source)) - return 1 + return TRUE + var/obj/machinery/camera/cam = null + var/list/our_cams = null + if(cameras && islist(cameras)) + our_cams = cameras + if (our_cams.len == 1) + cam = our_cams[1] + else if(cameras && istype(cameras, /obj/machinery/camera)) + cam = cameras + our_sort[home.name] = list(home, (cam ? cam : cameras), list(source)) + return TRUE + +/obj/machinery/computer/station_alert/proc/freeCamera(area/home, obj/machinery/camera/cam) + for(var/class in alarms) + var/our_area = alarms[class][home.name] + if(!our_area) + continue + var/cams = our_area[2] //Get the cameras + if(!cams) + continue + if(islist(cams)) + cams -= cam + if(length(cams) == 1) + our_area[2] = cams[1] + else + our_area[2] = null /obj/machinery/computer/station_alert/proc/cancelAlarm(class, area/A, obj/origin) if(stat & (BROKEN)) diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index 87b7159125..34495478d7 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -21,7 +21,7 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E var/obj/item/uplinkholder = null var/obj/machinery/computer/telecrystals/boss/linkedboss = null -/obj/machinery/computer/telecrystals/uplinker/Initialize() +/obj/machinery/computer/telecrystals/uplinker/Initialize(mapload) . = ..() var/ID = pick_n_take(GLOB.possible_uplinker_IDs) diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm index 3e9531097e..eb1c4903fc 100644 --- a/code/game/machinery/computer/teleporter.dm +++ b/code/game/machinery/computer/teleporter.dm @@ -14,7 +14,7 @@ var/turf/target var/obj/item/implant/imp_t -/obj/machinery/computer/teleporter/Initialize() +/obj/machinery/computer/teleporter/Initialize(mapload) . = ..() id = "[rand(1000, 9999)]" link_power_station() diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index f2f8c20776..e3778811ea 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -1,3 +1,5 @@ +#define AHELP_FIRST_MESSAGE "Please adminhelp before leaving the round, even if there are no administrators online!" + /* * Cryogenic refrigeration unit. Basically a despawner. * Stealing a lot of concepts/code from sleepers due to massive laziness. @@ -5,6 +7,7 @@ * since time_entered, which is world.time when the occupant moves in. * ~ Zuhayr */ +GLOBAL_LIST_EMPTY(cryopod_computers) //Main cryopod console. @@ -13,162 +16,113 @@ desc = "An interface between crew and the cryogenic storage oversight systems." icon = 'icons/obj/Cryogenic2.dmi' icon_state = "cellconsole_1" + icon_keyboard = null circuit = /obj/item/circuitboard/cryopodcontrol density = FALSE interaction_flags_machine = INTERACT_MACHINE_OFFLINE - req_one_access = list(ACCESS_HEADS, ACCESS_ARMORY) //Heads of staff or the warden can go here to claim recover items from their department that people went were cryodormed with. + req_one_access = list(ACCESS_HEADS, ACCESS_ARMORY) // Heads of staff or the warden can go here to claim recover items from their department that people went were cryodormed with. + var/mode = null - var/menu = 1 //Which menu screen to display - - //Used for logging people entering cryosleep and important items they are carrying. + // Used for logging people entering cryosleep and important items they are carrying. var/list/frozen_crew = list() - var/list/obj/stored_packages = list() - + var/list/stored_packages = list() + /// Does this console store items? if NOT, will dump all items when the user cryo's instead var/allow_items = TRUE + var/storage_type = "crewmembers" + var/storage_name = "Cryogenic Oversight Control" + /obj/machinery/computer/cryopod/deconstruct() . = ..() for(var/i in stored_packages) var/obj/O = i O.forceMove(drop_location()) -/obj/machinery/computer/cryopod/attack_ai() - attack_hand() +/obj/machinery/computer/cryopod/Initialize(mapload) + . = ..() + GLOB.cryopod_computers += src -/obj/machinery/computer/cryopod/ui_interact(mob/user = usr) - if(!is_operational()) +/obj/machinery/computer/cryopod/Destroy() + GLOB.cryopod_computers -= src + return ..() + +/obj/machinery/computer/cryopod/update_icon_state() + if(stat & (NOPOWER|BROKEN)) + icon_state = "cellconsole" + return ..() + icon_state = "cellconsole_1" + return ..() + +/obj/machinery/computer/cryopod/ui_interact(mob/user, datum/tgui/ui) + if(stat & (NOPOWER|BROKEN)) return - user.set_machine(src) add_fingerprint(user) - var/dat = "" + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "CryopodConsole", name) + ui.open() - dat += "

    Welcome, [user.real_name].


    " - dat += "

    " +/obj/machinery/computer/cryopod/ui_data(mob/user) + var/list/data = list() + data["frozen_crew"] = frozen_crew + var/list/item_meta = list() - switch(src.menu) - if(1) - dat += "View crew storage log

    " - if(allow_items) - dat += "View objects storage log

    " - dat += "Recover object

    " - dat += "Recover all objects
    " - if(2) - dat += "<< Back

    " - dat += "

    Recently stored Crew




    " - if(!frozen_crew.len) - dat += "There has been no storage usage at this terminal.
    " - else - for(var/person in frozen_crew) - dat += "[person]
    " - dat += "
    " - if(3) - dat += "<< Back

    " - dat += "

    Recently stored objects




    " - if(!stored_packages.len) - dat += "There has been no storage usage at this terminal.
    " - else - for(var/obj/O in stored_packages) - dat += "[O.name]
    " - dat += "
    " + for(var/obj/item/storage/box/blue/cryostorage_items/O as anything in stored_packages) + item_meta += list(list("name" = O.real_name, "ref" = REF(O))) // i am truely livid about byond lists + data["item_meta"] = item_meta - var/datum/browser/popup = new(user, "cryopod_console", "Cryogenic System Control") - popup.set_content(dat) - popup.open() + var/obj/item/card/id/id_card + var/datum/bank_account/current_user + if(isliving(user)) + var/mob/living/person = user + id_card = person.get_idcard() + if(id_card?.registered_account) + current_user = id_card.registered_account + if(current_user) + data["account_name"] = current_user.account_holder // i do not know why but this uses budget? -/obj/machinery/computer/cryopod/Topic(href, href_list) + return data + +/obj/machinery/computer/cryopod/ui_act(action, params) if(..()) - return TRUE + return - var/mob/user = usr - - add_fingerprint(user) - - if(href_list["item"]) - if(!allowed(user) && !(obj_flags & EMAGGED)) - to_chat(user, "Access Denied.") + if(action == "item") + if(!allowed(usr) && !(obj_flags & EMAGGED)) + to_chat(usr, "Access Denied.") playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - updateUsrDialog() return if(!allow_items) return if(stored_packages.len == 0) - to_chat(user, "There is nothing to recover from storage.") + to_chat(usr, "There is nothing to recover from storage.") playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - updateUsrDialog() return - var/obj/I = input(user, "Please choose which object to retrieve.","Object recovery",null) as null|anything in stored_packages + var/obj/I = locate(params["item"]) playsound(src, "terminal_type", 25, 0) + if(!I) return if(!(I in stored_packages)) - to_chat(user, "\The [I] is no longer in storage.") + to_chat(usr, "\The [I] is no longer in storage.") playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - updateUsrDialog() return visible_message("The console beeps happily as it disgorges \the [I].") playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) I.forceMove(drop_location()) - if(user && Adjacent(user) && user.can_hold_items()) - user.put_in_hands(I) + if(usr && Adjacent(usr) && usr.can_hold_items()) + usr.put_in_hands(I) stored_packages -= I - updateUsrDialog() - else if(href_list["allitems"]) - playsound(src, "terminal_type", 25, 0) - if(!allowed(user) && !(obj_flags & EMAGGED)) - to_chat(user, "Access Denied.") - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - updateUsrDialog() - return - - if(!allow_items) - return - - if(stored_packages.len == 0) - to_chat(user, "There is nothing to recover from storage.") - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - - visible_message("The console beeps happily as it disgorges the desired objects.") - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - for(var/obj/O in stored_packages) - O.forceMove(get_turf(src)) - stored_packages.Cut() - updateUsrDialog() - - else if (href_list["menu"]) - src.menu = text2num(href_list["menu"]) - playsound(src, "terminal_type", 25, 0) - updateUsrDialog() - - ui_interact(usr) - updateUsrDialog() - return - -/obj/item/circuitboard/cryopodcontrol - name = "Circuit board (Cryogenic Oversight Console)" - build_path = "/obj/machinery/computer/cryopod" - -/obj/machinery/computer/cryopod/contents_explosion() - return - -/obj/machinery/computer/cryopod/contents_explosion() - return //don't blow everyone's shit up. - -/// The box -/obj/item/storage/box/blue/cryostorage_items - w_class = WEIGHT_CLASS_HUGE - -//Cryopods themselves. +// Cryopods themselves. /obj/machinery/cryopod name = "cryogenic freezer" desc = "Suited for Cyborgs and Humanoids, the pod is a safe place for personnel affected by the Space Sleep Disorder to get some rest." @@ -181,47 +135,55 @@ var/on_store_message = "has entered long-term storage." var/on_store_name = "Cryogenic Oversight" - // 15 minutes-ish safe period before being despawned. - var/time_till_despawn = 15 * 600 // This is reduced by 90% if a player manually enters cryo - var/despawn_world_time = null // Used to keep track of the safe period. + /// Time until despawn when a mob enters a cryopod. You can cryo other people in pods. + var/time_till_despawn = 30 SECONDS + /// Cooldown for when it's now safe to try an despawn the player. + COOLDOWN_DECLARE(despawn_world_time) - var/obj/machinery/computer/cryopod/control_computer - var/item_storage_type = /obj/item/storage/box/blue/cryostorage_items //with how storage components work this can be anything the player can open or anything with a storage component. - var/last_no_computer_message = 0 + ///Weakref to our controller + var/datum/weakref/control_computer_weakref + COOLDOWN_DECLARE(last_no_computer_message) /obj/machinery/cryopod/Initialize(mapload) - . = ..() + ..() + return INITIALIZE_HINT_LATELOAD //Gotta populate the cryopod computer GLOB first + +/obj/machinery/cryopod/LateInitialize() update_icon() - find_control_computer(mapload) + find_control_computer() + +// This is not a good situation +/obj/machinery/cryopod/Destroy() + control_computer_weakref = null + return ..() /obj/machinery/cryopod/proc/find_control_computer(urgent = FALSE) - for(var/obj/machinery/computer/cryopod/C in get_area(src)) - control_computer = C - if(C) - return C - break + for(var/cryo_console as anything in GLOB.cryopod_computers) + var/obj/machinery/computer/cryopod/console = cryo_console + if(get_area(console) == get_area(src)) + control_computer_weakref = WEAKREF(console) + break // Don't send messages unless we *need* the computer, and less than five minutes have passed since last time we messaged - if(!control_computer && urgent && last_no_computer_message + 5*60*10 < world.time) + if(!control_computer_weakref && urgent && COOLDOWN_FINISHED(src, last_no_computer_message)) + COOLDOWN_START(src, last_no_computer_message, 5 MINUTES) log_admin("Cryopod in [get_area(src)] could not find control computer!") message_admins("Cryopod in [get_area(src)] could not find control computer!") last_no_computer_message = world.time - return control_computer != null + return control_computer_weakref != null -/obj/machinery/cryopod/close_machine(mob/user) - if(!control_computer) +/obj/machinery/cryopod/close_machine(atom/movable/target) + if(!control_computer_weakref) find_control_computer(TRUE) - if((isnull(user) || istype(user)) && state_open && !panel_open) - ..(user) + if((isnull(target) || isliving(target)) && state_open && !panel_open) + ..(target) var/mob/living/mob_occupant = occupant - investigate_log("Cryogenics machine closed with occupant [key_name(occupant)] by user [key_name(user)].", INVESTIGATE_CRYOGENICS) + investigate_log("Cryogenics machine closed with occupant [key_name(occupant)] by user [key_name(target)].", INVESTIGATE_CRYOGENICS) if(mob_occupant && mob_occupant.stat != DEAD) - to_chat(occupant, "You feel cool air surround you. You go numb as your senses turn inward.") - if(mob_occupant.client)//if they're logged in - despawn_world_time = world.time + (time_till_despawn * 0.1) - else - despawn_world_time = world.time + time_till_despawn + to_chat(occupant, span_notice("You feel cool air surround you. You go numb as your senses turn inward.")) + + COOLDOWN_START(src, despawn_world_time, time_till_despawn) icon_state = "cryopod" /obj/machinery/cryopod/open_machine() @@ -234,8 +196,8 @@ /obj/machinery/cryopod/container_resist(mob/living/user) investigate_log("Cryogenics machine container resisted by [key_name(user)] with occupant [key_name(occupant)].", INVESTIGATE_CRYOGENICS) - visible_message("[occupant] emerges from [src]!", - "You climb out of [src]!") + visible_message(span_notice("[occupant] emerges from [src]!"), + span_notice("You climb out of [src]!")) open_machine() /obj/machinery/cryopod/relaymove(mob/user) @@ -246,36 +208,122 @@ return var/mob/living/mob_occupant = occupant - if(mob_occupant) - // Eject dead people - if(mob_occupant.stat == DEAD) - open_machine() + if(mob_occupant.stat == DEAD) + open_machine() - if(!(world.time > despawn_world_time + 100))//+ 10 seconds - return + if(!mob_occupant.client && COOLDOWN_FINISHED(src, despawn_world_time)) + if(!control_computer_weakref) + find_control_computer(urgent = TRUE) - if(!mob_occupant.client && mob_occupant.stat < 2) //Occupant is living and has no client. - if(!control_computer) - find_control_computer(urgent = TRUE)//better hope you found it this time + despawn_occupant() - despawn_occupant() +/obj/machinery/cryopod/proc/handle_objectives() + var/mob/living/mob_occupant = occupant + // Update any existing objectives involving this mob. + for(var/datum/objective/objective in GLOB.objectives) + // We don't want revs to get objectives that aren't for heads of staff. Letting + // them win or lose based on cryo is silly so we remove the objective. + if(istype(objective,/datum/objective/mutiny) && objective.target == mob_occupant.mind) + objective.team.objectives -= objective + qdel(objective) + for(var/datum/mind/mind in objective.team.members) + to_chat(mind.current, "
    [span_userdanger("Your target is no longer within reach. Objective removed!")]") + mind.announce_objectives() + else if(istype(objective.target) && objective.target == mob_occupant.mind) + if(istype(objective, /datum/objective/contract)) + var/datum/antagonist/traitor/affected_traitor = objective.owner.has_antag_datum(/datum/antagonist/traitor) + var/datum/contractor_hub/affected_contractor_hub = affected_traitor.contractor_hub + for(var/datum/syndicate_contract/affected_contract as anything in affected_contractor_hub.assigned_contracts) + if(affected_contract.contract == objective) + affected_contract.generate(affected_contractor_hub.assigned_targets) + affected_contractor_hub.assigned_targets.Add(affected_contract.contract.target) + to_chat(objective.owner.current, "
    [span_userdanger("Contract target out of reach. Contract rerolled.")]") + break + else + var/old_target = objective.target + objective.target = null + if(!objective) + return + objective.find_target() + if(!objective.target && objective.owner) + to_chat(objective.owner.current, "
    [span_userdanger("Your target is no longer within reach. Objective removed!")]") + for(var/datum/antagonist/antag in objective.owner.antag_datums) + antag.objectives -= objective + if (!objective.team) + objective.update_explanation_text() + objective.owner.announce_objectives() + to_chat(objective.owner.current, "
    [span_userdanger("You get the feeling your target is no longer within reach. Time for Plan [pick("A","B","C","D","X","Y","Z")]. Objectives updated!")]") + else + var/list/objectivestoupdate + for(var/datum/mind/objective_owner in objective.get_owners()) + to_chat(objective_owner.current, "
    [span_userdanger("You get the feeling your target is no longer within reach. Time for Plan [pick("A","B","C","D","X","Y","Z")]. Objectives updated!")]") + for(var/datum/objective/update_target_objective in objective_owner.get_all_objectives()) + LAZYADD(objectivestoupdate, update_target_objective) + objectivestoupdate += objective.team.objectives + for(var/datum/objective/update_objective in objectivestoupdate) + if(update_objective.target != old_target || !istype(update_objective,objective.type)) + continue + update_objective.target = objective.target + update_objective.update_explanation_text() + to_chat(objective.owner.current, "
    [span_userdanger("You get the feeling your target is no longer within reach. Time for Plan [pick("A","B","C","D","X","Y","Z")]. Objectives updated!")]") + update_objective.owner.announce_objectives() + qdel(objective) + +/obj/machinery/cryopod/proc/should_preserve_item(obj/item/item) + for(var/datum/objective_item/steal/possible_item in GLOB.possible_items) + if(istype(item, possible_item.targetitem)) + return TRUE + return FALSE // This function can not be undone; do not call this unless you are sure /obj/machinery/cryopod/proc/despawn_occupant() - if(!control_computer) - find_control_computer() - var/mob/living/mob_occupant = occupant + var/list/crew_member = list() + crew_member["name"] = mob_occupant.real_name + + if(mob_occupant.mind) + // Handle job slot/tater cleanup. + var/job = mob_occupant.mind.assigned_role + crew_member["job"] = job + SSjob.FreeRole(job) + // if(LAZYLEN(mob_occupant.mind.objectives)) + // mob_occupant.mind.objectives.Cut() + mob_occupant.mind.special_role = null + else + crew_member["job"] = "N/A" + + // Delete them from datacore. + var/announce_rank = null + for(var/datum/data/record/medical_record as anything in GLOB.data_core.medical) + if(medical_record.fields["name"] == mob_occupant.real_name) + qdel(medical_record) + for(var/datum/data/record/security_record as anything in GLOB.data_core.security) + if(security_record.fields["name"] == mob_occupant.real_name) + qdel(security_record) + for(var/datum/data/record/general_record as anything in GLOB.data_core.general) + if(general_record.fields["name"] == mob_occupant.real_name) + announce_rank = general_record.fields["rank"] + qdel(general_record) + + var/obj/machinery/computer/cryopod/control_computer = control_computer_weakref?.resolve() + if(!control_computer) + control_computer_weakref = null + else + control_computer.frozen_crew += list(crew_member) + + // Make an announcement and log the person entering storage. + if(GLOB.announcement_systems.len) + var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems) + announcer.announce("CRYOSTORAGE", mob_occupant.real_name, announce_rank, list()) + + visible_message(span_notice("[src] hums and hisses as it moves [mob_occupant.real_name] into storage.")) + + /* ============================= */ var/list/obj/item/storing = list() var/list/obj/item/destroying = list() var/list/obj/item/destroy_later = list() - - investigate_log("Despawning [key_name(mob_occupant)].", INVESTIGATE_CRYOGENICS) - - var/atom/target_store = (control_computer?.allow_items && control_computer) || src //the double control computer check makes it return the control computer. - var/drop_to_ground = !istype(target_store, /obj/machinery/computer/cryopod) - + var/drop_to_ground = !istype(control_computer, /obj/machinery/computer/cryopod) || !control_computer.allow_items var/mind_identity = mob_occupant.mind?.name var/occupant_identity = mob_occupant.real_name @@ -296,7 +344,6 @@ AM.forceMove(src) R.module.remove_module(I, TRUE) else - if(ishuman(mob_occupant)) var/mob/living/carbon/human/H = mob_occupant if(H.mind && H.client && H.client.prefs && H == H.mind.original_character) @@ -306,145 +353,89 @@ if(iscarbon(mob_occupant)) // sorry simp-le-mobs deserve no mercy var/mob/living/carbon/C = mob_occupant gear = C.get_all_gear() - for(var/i in gear) - var/obj/item/I = i - I.forceMove(src) - if(!istype(I)) - destroying += I + + for(var/obj/item/item_content as anything in gear) + if(!istype(item_content) || HAS_TRAIT(item_content, TRAIT_NODROP)) + destroying += item_content continue - if(I.item_flags & (DROPDEL | ABSTRACT)) - destroying += I - continue - if(HAS_TRAIT(I, TRAIT_NODROP)) - destroying += I + if(item_content.item_flags & (DROPDEL | ABSTRACT)) + destroying += item_content continue + + // destroying stays in mob for a bit + item_content.forceMove(src) + // WEE WOO SNOWFLAKE TIME - if(istype(I, /obj/item/pda)) - var/obj/item/pda/P = I + if(istype(item_content, /obj/item/pda)) + var/obj/item/pda/P = item_content if((P.owner == mind_identity) || (P.owner == occupant_identity)) destroying += P else storing += P - else if(istype(I, /obj/item/card/id)) - var/obj/item/card/id/idcard = I + else if(istype(item_content, /obj/item/card/id)) + var/obj/item/card/id/idcard = item_content if((idcard.registered_name == mind_identity) || (idcard.registered_name == occupant_identity)) destroying += idcard else storing += idcard else - storing += I + storing += item_content // get rid of mobs for(var/mob/living/L in mob_occupant.GetAllContents() - mob_occupant) L.forceMove(drop_location()) if(storing.len) - var/obj/O = new item_storage_type + var/obj/item/storage/box/blue/cryostorage_items/O = new /obj/item/storage/box/blue/cryostorage_items O.name = "cryogenic retrieval package: [mob_occupant.real_name]" + O.real_name = mob_occupant.real_name for(var/i in storing) var/obj/item/I = i I.forceMove(O) - O.forceMove(drop_to_ground? target_store.drop_location() : target_store) - if((target_store == control_computer) && !drop_to_ground) + O.forceMove(drop_to_ground ? control_computer.drop_location() : control_computer) + if((control_computer == control_computer) && !drop_to_ground) control_computer.stored_packages += O - - QDEL_LIST(destroying) - - //Update any existing objectives involving this mob. - for(var/i in GLOB.objectives) - var/datum/objective/O = i - // We don't want revs to get objectives that aren't for heads of staff. Letting - // them win or lose based on cryo is silly so we remove the objective. - if(istype(O,/datum/objective/mutiny) && O.target == mob_occupant.mind) - qdel(O) - else if(O.target && istype(O.target, /datum/mind)) - if(O.target != mob_occupant.mind) - continue - if(O.check_midround_completion()) - continue - if(O.owner && O.owner.current) - to_chat(O.owner.current, "
    You get the feeling your target is no longer within reach. Time for Plan [pick("A","B","C","D","X","Y","Z")]. Objectives updated!") - O.target = null - spawn(10) //This should ideally fire after the occupant is deleted. - if(!O) - return - O.find_target() - O.update_explanation_text() - if(!(O.target)) - qdel(O) - - if(mob_occupant.mind) - //Handle job slot/tater cleanup. - if(mob_occupant.mind.assigned_role) - var/job = mob_occupant.mind.assigned_role - SSjob.FreeRole(job) - mob_occupant.mind.special_role = null - - // Delete them from datacore. - - var/announce_rank = null - for(var/datum/data/record/R in GLOB.data_core.medical) - if((R.fields["name"] == mob_occupant.real_name)) - qdel(R) - for(var/datum/data/record/T in GLOB.data_core.security) - if((T.fields["name"] == mob_occupant.real_name)) - qdel(T) - for(var/datum/data/record/G in GLOB.data_core.general) - if((G.fields["name"] == mob_occupant.real_name)) - announce_rank = G.fields["rank"] - qdel(G) - - for(var/obj/machinery/computer/cloning/cloner in world) - for(var/datum/data/record/R in cloner.records) - if(R.fields["name"] == mob_occupant.real_name) - cloner.records.Remove(R) - - //Make an announcement and log the person entering storage. - if(control_computer) - control_computer.frozen_crew += "[mob_occupant.real_name]" - - if(GLOB.announcement_systems.len) - var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems) - announcer.announce("CRYOSTORAGE", mob_occupant.real_name, announce_rank, list()) - visible_message("\The [src] hums and hisses as it moves [mob_occupant.real_name] into storage.") + /* ============================= */ // Ghost and delete the mob. + // they already did ghost verb var/mob/dead/observer/G = mob_occupant.get_ghost(TRUE) if(G) G.voluntary_ghosted = TRUE + // they did not ghost verb else mob_occupant.ghostize(FALSE, penalize = TRUE, voluntary = TRUE, cryo = TRUE) + QDEL_LIST(destroying) + handle_objectives() QDEL_NULL(occupant) QDEL_LIST(destroy_later) open_machine() name = initial(name) /obj/machinery/cryopod/MouseDrop_T(mob/living/target, mob/user) - if(!istype(target) || user.incapacitated() || !target.Adjacent(user) || !Adjacent(user) || !ismob(target) || (!ishuman(user) && !iscyborg(user)) || !istype(user.loc, /turf) || target.buckled) + if(!istype(target) || !can_interact(user) || !target.Adjacent(user) || !ismob(target) || isanimal(target) || !istype(user.loc, /turf) || target.buckled) return if(occupant) - to_chat(user, "The cryo pod is already occupied!") + to_chat(user, span_notice("[src] is already occupied!")) return if(target.stat == DEAD) - to_chat(user, "Dead people can not be put into cryo.") + to_chat(user, span_notice("Dead people can not be put into cryo.")) return - if(target.client && user != target) + if(user != target && target.client) if(iscyborg(target)) - to_chat(user, "You can't put [target] into [src]. They're online.") + to_chat(user, span_danger("You can't put [target] into [src]. [target.p_theyre(capitalized = TRUE)] online.")) else - to_chat(user, "You can't put [target] into [src]. They're conscious.") + to_chat(user, span_danger("You can't put [target] into [src]. [target.p_theyre(capitalized = TRUE)] conscious.")) return - else if(target.client) - if(alert(target,"Would you like to enter cryosleep?",,"Yes","No") == "No") + else if(target.client) // mob has client + if(tgalert(target, "Would you like to enter cryosleep?", "Enter Cryopod?", "Yes", "No") != "Yes") return - var/generic_plsnoleave_message = " Please adminhelp before leaving the round, even if there are no administrators online!" - - if(target == user && world.time - target.client.cryo_warned > 5 MINUTES)//if we haven't warned them in the last 5 minutes + if(target == user && world.time - target.client.cryo_warned > 5 MINUTES) var/list/caught_string var/addendum = "" if(target.mind.assigned_role in GLOB.command_positions) @@ -462,30 +453,48 @@ LAZYADD(caught_string, "Revolutionary") if(caught_string) - alert(target, "You're a [english_list(caught_string)]![generic_plsnoleave_message][addendum]") + tgui_alert(target, "You're a [english_list(caught_string)]! [AHELP_FIRST_MESSAGE][addendum]") target.client.cryo_warned = world.time - return - if(!target || user.incapacitated() || !target.Adjacent(user) || !Adjacent(user) || (!ishuman(user) && !iscyborg(user)) || !istype(user.loc, /turf) || target.buckled) + if(!istype(target) || !can_interact(user) || !target.Adjacent(user) || !ismob(target) || isanimal(target) || !istype(user.loc, /turf) || target.buckled) return - //rerun the checks in case of shenanigans - - if(target == user) - visible_message("[user] starts climbing into the cryo pod.") - else - visible_message("[user] starts putting [target] into the cryo pod.") + // rerun the checks in case of shenanigans if(occupant) - to_chat(user, "\The [src] is in use.") + to_chat(user, span_notice("[src] is already occupied!")) return - close_machine(target) - to_chat(target, "If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.") - name = "[name] ([occupant.name])" - log_admin("[key_name(target)] entered a stasis pod.") - message_admins("[key_name_admin(target)] entered a stasis pod. (JMP)") + if(target == user) + visible_message("[user] starts climbing into the cryo pod.") + else + visible_message("[user] starts putting [target] into the cryo pod.") + + to_chat(target, span_warning("If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.")) + + log_admin("[key_name(target)] entered a stasis pod.") + message_admins("[key_name_admin(target)] entered a stasis pod. [ADMIN_JMP(src)]") add_fingerprint(target) -//Attacks/effects. + close_machine(target) + name = "[name] ([target.name])" + +// Attacks/effects. /obj/machinery/cryopod/blob_act() - return //Sorta gamey, but we don't really want these to be destroyed. + return // Sorta gamey, but we don't really want these to be destroyed. + +#undef AHELP_FIRST_MESSAGE + +/obj/item/circuitboard/cryopodcontrol + name = "Circuit board (Cryogenic Oversight Console)" + build_path = /obj/machinery/computer/cryopod + +/obj/machinery/computer/cryopod/contents_explosion() + return + +/obj/machinery/computer/cryopod/contents_explosion() + return //don't blow everyone's shit up. + +/// The box +/obj/item/storage/box/blue/cryostorage_items + w_class = WEIGHT_CLASS_HUGE + var/real_name = "fire coderbus" diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm index 8b24a3804f..956b3e9c79 100644 --- a/code/game/machinery/dance_machine.dm +++ b/code/game/machinery/dance_machine.dm @@ -6,17 +6,22 @@ verb_say = "states" density = TRUE req_one_access = list(ACCESS_BAR, ACCESS_KITCHEN, ACCESS_HYDROPONICS, ACCESS_ENGINE, ACCESS_CARGO, ACCESS_THEATRE) + payment_department = ACCOUNT_SRV var/active = FALSE var/list/rangers = list() var/stop = 0 var/volume = 70 - var/datum/track/selection = null + var/queuecost = PRICE_CHEAP //Set to -1 to make this jukebox require access for queueing + var/datum/track/playing = null + var/datum/track/selectedtrack = null + var/list/queuedplaylist = list() + var/queuecooldown //This var exists solely to prevent accidental repeats of John Mulaney's 'What's New Pussycat?' incident. Intentional, however...... /obj/machinery/jukebox/disco name = "radiant dance machine mark IV" desc = "The first three prototypes were discontinued after mass casualty incidents." icon_state = "disco" - req_access = list(ACCESS_ENGINE) + req_one_access = list(ACCESS_ENGINE) anchored = FALSE var/list/spotlights = list() var/list/sparkles = list() @@ -24,7 +29,7 @@ /obj/machinery/jukebox/disco/indestructible name = "radiant dance machine mark V" desc = "Now redesigned with data gathered from the extensive disco and plasma research." - req_access = null + req_one_access = null anchored = TRUE resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF flags_1 = NODECONSTRUCT_1 @@ -46,6 +51,16 @@ return return ..() +/obj/machinery/jukebox/emag_act(mob/user) + . = ..() + if(obj_flags & EMAGGED) + return + obj_flags |= EMAGGED + queuecost = PRICE_FREE + req_one_access = null + to_chat(user, "You've bypassed [src]'s audio volume limiter, and enabled free play.") + return TRUE + /obj/machinery/jukebox/update_icon_state() if(active) icon_state = "[initial(icon_state)]-active" @@ -56,7 +71,7 @@ if(!anchored) to_chat(user,"This device must be anchored by a wrench!") return UI_CLOSE - if(!allowed(user) && !isobserver(user)) + if((queuecost < 0 && !allowed(user)) && !isobserver(user)) to_chat(user,"Error: Access Denied.") user.playsound_local(src, 'sound/misc/compiler-failure.ogg', 25, TRUE) return UI_CLOSE @@ -77,18 +92,21 @@ data["active"] = active data["songs"] = list() for(var/datum/track/S in SSjukeboxes.songs) - var/list/track_data = list( - name = S.song_name - ) + var/list/track_data = list(name = S.song_name) data["songs"] += list(track_data) + data["queued_tracks"] = list() + for(var/datum/track/S in queuedplaylist) + var/list/track_data = list(name = S.song_name) + data["queued_tracks"] += list(track_data) data["track_selected"] = null data["track_length"] = null - data["track_beat"] = null - if(selection) - data["track_selected"] = selection.song_name - data["track_length"] = DisplayTimeText(selection.song_length) - data["track_beat"] = selection.song_beat + if(playing) + data["track_selected"] = playing.song_name + data["track_length"] = DisplayTimeText(playing.song_length) data["volume"] = volume + data["is_emagged"] = (obj_flags & EMAGGED) + data["cost_for_play"] = queuecost + data["has_access"] = allowed(user) return data /obj/machinery/jukebox/ui_act(action, list/params) @@ -100,57 +118,91 @@ if("toggle") if(QDELETED(src)) return - if(!active) - if(stop > world.time) - to_chat(usr, "Error: The device is still resetting from the last activation, it will be ready again in [DisplayTimeText(stop-world.time)].") - playsound(src, 'sound/misc/compiler-failure.ogg', 50, TRUE) - return + if(!allowed(usr)) + return + if(!active && !playing) activate_music() - START_PROCESSING(SSobj, src) - return TRUE else stop = 0 - return TRUE - if("select_track") - if(active) - to_chat(usr, "Error: You cannot change the song until the current one is over.") + return TRUE + if("add_to_queue") + if(QDELETED(src)) return + if(world.time < queuecooldown) + return + if(!istype(selectedtrack, /datum/track)) + return + if(!allowed(usr) && queuecost) + var/obj/item/card/id/C + if(isliving(usr)) + var/mob/living/L = usr + C = L.get_idcard(TRUE) + if(!can_transact(C)) + queuecooldown = world.time + (1 SECONDS) + playsound(src, 'sound/misc/compiler-failure.ogg', 25, TRUE) + return + if(!attempt_transact(C, queuecost)) + say("Insufficient funds.") + queuecooldown = world.time + (1 SECONDS) + playsound(src, 'sound/misc/compiler-failure.ogg', 25, TRUE) + return + to_chat(usr, "You spend [queuecost] credits to queue [selectedtrack.song_name].") + log_econ("[queuecost] credits were inserted into [src] by [key_name(usr)] (ID: [C.registered_name]) to queue [selectedtrack.song_name].") + queuedplaylist += selectedtrack + if(active) + say("[selectedtrack.song_name] has been added to the queue.") + else if(!playing) + activate_music() + playsound(src, 'sound/machines/ping.ogg', 50, TRUE) + queuecooldown = world.time + (3 SECONDS) + return TRUE + if("select_track") var/list/available = list() for(var/datum/track/S in SSjukeboxes.songs) available[S.song_name] = S var/selected = params["track"] if(QDELETED(src) || !selected || !istype(available[selected], /datum/track)) return - selection = available[selected] + selectedtrack = available[selected] return TRUE if("set_volume") + if(!allowed(usr)) + return var/new_volume = params["volume"] if(new_volume == "reset") volume = initial(volume) - return TRUE else if(new_volume == "min") volume = 0 - return TRUE else if(new_volume == "max") - volume = 100 - return TRUE + volume = ((obj_flags & EMAGGED) ? 210 : 100) else if(text2num(new_volume) != null) - volume = text2num(new_volume) - return TRUE + volume = clamp(0, text2num(new_volume), ((obj_flags & EMAGGED) ? 210 : 100)) + var/wherejuke = SSjukeboxes.findjukeboxindex(src) + if(wherejuke) + SSjukeboxes.updatejukebox(wherejuke, jukefalloff = volume/35) + return TRUE /obj/machinery/jukebox/proc/activate_music() - var/jukeboxslottotake = SSjukeboxes.addjukebox(src, selection, 2) + if(playing || !queuedplaylist.len) + return FALSE + playing = queuedplaylist[1] + var/jukeboxslottotake = SSjukeboxes.addjukebox(src, playing, volume/35) if(jukeboxslottotake) active = TRUE update_icon() START_PROCESSING(SSobj, src) - stop = world.time + selection.song_length + stop = world.time + playing.song_length + queuedplaylist.Cut(1, 2) + say("Now playing: [playing.song_name]") + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, TRUE) return TRUE else return FALSE /obj/machinery/jukebox/disco/activate_music() - ..() + . = ..() + if(!.) + return dance_setup() lights_spin() @@ -243,7 +295,7 @@ S.pixel_y = 7 S.forceMove(get_turf(src)) sleep(7) - if(selection.song_name == "Engineering's Ultimate High-Energy Hustle") + if(playing.song_name == "Engineering's Ultimate High-Energy Hustle") sleep(280) for(var/obj/reveal in sparkles) reveal.alpha = 255 @@ -299,7 +351,7 @@ continue if(prob(2)) // Unique effects for the dance floor that show up randomly to mix things up INVOKE_ASYNC(src, .proc/hierofunk) - sleep(selection.song_beat) + sleep(playing.song_beat) #undef DISCO_INFENO_RANGE @@ -431,6 +483,7 @@ return SSjukeboxes.removejukebox(position) STOP_PROCESSING(SSobj, src) + playing = null rangers = list() /obj/machinery/jukebox/disco/dance_over() @@ -439,12 +492,21 @@ QDEL_LIST(sparkles) /obj/machinery/jukebox/process() - if(active && world.time >= stop) - active = FALSE - dance_over() - playsound(src,'sound/machines/terminal_off.ogg',50,1) - update_icon() - stop = world.time + 100 + if(active) + if(world.time >= stop) + active = FALSE + dance_over() + if(stop && queuedplaylist.len) + activate_music() + else + playsound(src,'sound/machines/terminal_off.ogg',50,1) + update_icon() + playing = null + stop = 0 + else if(volume > 140) // BOOM BOOM BOOM BOOM + for(var/mob/living/carbon/C in hearers(round(volume/35), src)) // I WANT YOU IN MY ROOM + if(istype(C)) // LETS SPEND THE NIGHT TOGETHER + C.adjustEarDamage(max((((volume/35) - sqrt(get_dist(C, src) * 4)) - C.get_ear_protection())*0.1, 0)) // FROM NOW UNTIL FOREVER /obj/machinery/jukebox/disco/process() diff --git a/code/game/machinery/defibrillator_mount.dm b/code/game/machinery/defibrillator_mount.dm index bc6cc4b60e..9d7a6a8635 100644 --- a/code/game/machinery/defibrillator_mount.dm +++ b/code/game/machinery/defibrillator_mount.dm @@ -14,7 +14,7 @@ var/obj/item/defibrillator/defib //this mount's defibrillator var/clamps_locked = FALSE //if true, and a defib is loaded, it can't be removed without unlocking the clamps -/obj/machinery/defibrillator_mount/loaded/Initialize() //loaded subtype for mapping use +/obj/machinery/defibrillator_mount/loaded/Initialize(mapload) //loaded subtype for mapping use . = ..() defib = new/obj/item/defibrillator/loaded(src) diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index ca4b392efa..86c561bb15 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -37,22 +37,19 @@ else return ..() -/obj/structure/barricade/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff. +/obj/structure/barricade/CanAllowThrough(atom/movable/mover, turf/target)//So bullets will fly over and stuff. + . = ..() if(locate(/obj/structure/barricade) in get_turf(mover)) - return 1 + return TRUE else if(istype(mover, /obj/item/projectile)) if(!anchored) - return 1 + return TRUE var/obj/item/projectile/proj = mover if(proj.firer && Adjacent(proj.firer)) - return 1 + return TRUE if(prob(proj_pass_rate)) - return 1 - return 0 - else - return !density - - + return TRUE + return FALSE /////BARRICADE TYPES/////// @@ -79,7 +76,6 @@ return return ..() - /obj/structure/barricade/wooden/crude name = "crude plank barricade" desc = "This space is blocked off by a crude assortment of planks." @@ -96,7 +92,6 @@ /obj/structure/barricade/wooden/make_debris() new /obj/item/stack/sheet/mineral/wood(get_turf(src), drop_amount) - /obj/structure/barricade/sandbags name = "sandbags" desc = "Bags of sand. Self explanatory." @@ -104,13 +99,12 @@ icon_state = "sandbags" max_integrity = 280 proj_pass_rate = 20 - pass_flags = LETPASSTHROW + pass_flags_self = LETPASSTHROW bar_material = SAND climbable = TRUE smooth = SMOOTH_TRUE canSmoothWith = list(/obj/structure/barricade/sandbags, /turf/closed/wall, /turf/closed/wall/r_wall, /obj/structure/falsewall, /obj/structure/falsewall/reinforced, /turf/closed/wall/rust, /turf/closed/wall/r_wall/rust, /obj/structure/barricade/security) - /obj/structure/barricade/security name = "security barrier" desc = "A deployable barrier. Provides good cover in fire fights." @@ -120,13 +114,12 @@ anchored = FALSE max_integrity = 180 proj_pass_rate = 20 - armor = list("melee" = 10, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 10, "acid" = 0) + armor = list(MELEE = 10, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 10, BIO = 100, RAD = 100, FIRE = 10, ACID = 0) var/deploy_time = 40 var/deploy_message = TRUE - -/obj/structure/barricade/security/Initialize() +/obj/structure/barricade/security/Initialize(mapload) . = ..() addtimer(CALLBACK(src, .proc/deploy), deploy_time) @@ -137,7 +130,6 @@ if(deploy_message) visible_message("[src] deploys!") - /obj/item/grenade/barrier name = "barrier grenade" desc = "Instant cover." @@ -194,7 +186,6 @@ /obj/item/grenade/barrier/ui_action_click(mob/user) toggle_mode(user) - #undef SINGLE #undef VERTICAL #undef HORIZONTAL diff --git a/code/game/machinery/dish_drive.dm b/code/game/machinery/dish_drive.dm index 869d583037..148069b103 100644 --- a/code/game/machinery/dish_drive.dm +++ b/code/game/machinery/dish_drive.dm @@ -22,7 +22,7 @@ var/suction_enabled = TRUE var/transmit_enabled = TRUE -/obj/machinery/dish_drive/Initialize() +/obj/machinery/dish_drive/Initialize(mapload) . = ..() RefreshParts() diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm index 0dcb0e7235..c032e57ef3 100644 --- a/code/game/machinery/dna_scanner.dm +++ b/code/game/machinery/dna_scanner.dm @@ -163,7 +163,7 @@ var/max_mutations = 6 var/read_only = FALSE //Well,it's still a floppy disk -/obj/item/disk/data/Initialize() +/obj/item/disk/data/Initialize(mapload) . = ..() icon_state = "datadisk[rand(0,6)]" add_overlay("datadisk_gene") diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 477f72ee3b..d9d6f65e93 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -103,7 +103,10 @@ var/static/list/airlock_overlays = list() -/obj/machinery/door/airlock/Initialize() + /// sigh + var/unelectrify_timerid + +/obj/machinery/door/airlock/Initialize(mapload) . = ..() wires = new wiretypepath(src) //CIT CHANGE - makes it possible for airlocks to have different wire datums if(frequency) @@ -694,6 +697,50 @@ . += "Alt-click [src] to [ secondsElectrified ? "un-electrify" : "permanently electrify"] it." . += "Ctrl-Shift-click [src] to [ emergency ? "disable" : "enable"] emergency access." +/obj/machinery/door/airlock/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + + if(hasSiliconAccessInArea(user)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Open interface") + LAZYSET(context[SCREENTIP_CONTEXT_SHIFT_LMB], INTENT_ANY, density ? "Open" : "Close") + LAZYSET(context[SCREENTIP_CONTEXT_CTRL_LMB], INTENT_ANY, locked ? "Unbolt" : "Bolt") + LAZYSET(context[SCREENTIP_CONTEXT_ALT_LMB], INTENT_ANY, secondsElectrified ? "Un-electrify" : "Electrify") + LAZYSET(context[SCREENTIP_CONTEXT_CTRL_SHIFT_LMB], INTENT_ANY, emergency ? "Disable emergency access" : "Enable emergency access") + . = CONTEXTUAL_SCREENTIP_SET + + if(istype(held_item, /obj/item/stack/sheet/plasteel)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Reinforce") + return CONTEXTUAL_SCREENTIP_SET + + switch (held_item?.tool_behaviour) + if (TOOL_CROWBAR) + if (panel_open) + if (security_level == AIRLOCK_SECURITY_PLASTEEL_O_S || security_level == AIRLOCK_SECURITY_PLASTEEL_I_S) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Remove shielding") + return CONTEXTUAL_SCREENTIP_SET + else if (should_try_removing_electronics()) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Remove electronics") + return CONTEXTUAL_SCREENTIP_SET + + // Not always contextually true, but is contextually false in ways that make gameplay interesting. + // For example, trying to pry open an airlock, only for the bolts to be down and the lights off. + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Pry open") + + return CONTEXTUAL_SCREENTIP_SET + if (TOOL_WELDER) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_HARM, "Weld shut") + + if (panel_open) + switch (security_level) + if (AIRLOCK_SECURITY_METAL, AIRLOCK_SECURITY_PLASTEEL_I, AIRLOCK_SECURITY_PLASTEEL_O) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_HARM, "Cut shielding") + return CONTEXTUAL_SCREENTIP_SET + + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Repair") + return CONTEXTUAL_SCREENTIP_SET + + return . + /obj/machinery/door/airlock/attack_ai(mob/user) if(!src.canAIControl(user)) if(src.canAIHack()) @@ -791,21 +838,6 @@ return WIRE_INTERACTION_FAIL return ..() -/obj/machinery/door/airlock/proc/electrified_loop() - while (secondsElectrified > NOT_ELECTRIFIED) - sleep(10) - if(QDELETED(src)) - return - - secondsElectrified-- - updateDialog() - // This is to protect against changing to permanent, mid loop. - if(secondsElectrified == NOT_ELECTRIFIED) - set_electrified(NOT_ELECTRIFIED) - else - set_electrified(ELECTRIFIED_PERMANENT) - updateDialog() - /obj/machinery/door/airlock/Topic(href, href_list, var/nowindow = 0) // If you add an if(..()) check you must first remove the var/nowindow parameter. // Otherwise it will runtime with this kind of error: null.Topic() @@ -1036,6 +1068,31 @@ return return !operating && density +/// Returns if a crowbar would remove the airlock electronics +/obj/machinery/door/airlock/proc/should_try_removing_electronics() + if (security_level != 0) + return FALSE + + if (!panel_open) + return FALSE + + if (obj_flags & EMAGGED) + return TRUE + + if (!density) + return FALSE + + if (!welded) + return FALSE + + if (hasPower()) + return FALSE + + if (locked) + return FALSE + + return TRUE + /obj/machinery/door/airlock/try_to_crowbar(obj/item/I, mob/living/user) var/beingcrowbarred = null if(I.tool_behaviour == TOOL_CROWBAR) @@ -1054,9 +1111,9 @@ charge.forceMove(get_turf(user)) charge = null return - if(beingcrowbarred && panel_open && ((obj_flags & EMAGGED) || (density && welded && !operating && !hasPower() && !locked))) - user.visible_message("[user] removes the electronics from the airlock assembly.", \ - "You start to remove electronics from the airlock assembly...") + if(beingcrowbarred && should_try_removing_electronics() && !operating) + user.visible_message(span_notice("[user] removes the electronics from the airlock assembly."), \ + span_notice("You start to remove electronics from the airlock assembly...")) if(I.use_tool(src, user, 40, volume=100)) deconstruct(TRUE, user) return @@ -1213,85 +1270,33 @@ locked = TRUE return - -/obj/machinery/door/airlock/proc/change_paintjob(obj/item/airlock_painter/W, mob/user) - if(!W.can_use(user)) +// gets called when a player uses an airlock painter on this airlock +/obj/machinery/door/airlock/proc/change_paintjob(obj/item/airlock_painter/painter, mob/user) + if((!in_range(src, user) && loc != user) || !painter.can_use(user)) // user should be adjacent to the airlock, and the painter should have a toner cartridge that isn't empty return - var/list/optionlist - if(airlock_material == "glass") - optionlist = list("Standard", "Public", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Science", "Virology", "Mining", "Maintenance", "External", "External Maintenance") - else - optionlist = list("Standard", "Public", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Freezer", "Science", "Virology", "Mining", "Maintenance", "External", "External Maintenance") - - var/paintjob = input(user, "Please select a paintjob for this airlock.") in optionlist - if((!in_range(src, usr) && src.loc != usr) || !W.use_paint(user)) + // reads from the airlock painter's `available paintjob` list. lets the player choose a paint option, or cancel painting + var/current_paintjob = tgui_input_list(user, "Paintjob for this airlock", "Customize", sortList(painter.available_paint_jobs)) + if(isnull(current_paintjob)) // if the user clicked cancel on the popup, return return - switch(paintjob) - if("Standard") - icon = 'icons/obj/doors/airlocks/station/public.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - assemblytype = /obj/structure/door_assembly - if("Public") - icon = 'icons/obj/doors/airlocks/station2/glass.dmi' - overlays_file = 'icons/obj/doors/airlocks/station2/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_public - if("Engineering") - icon = 'icons/obj/doors/airlocks/station/engineering.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_eng - if("Atmospherics") - icon = 'icons/obj/doors/airlocks/station/atmos.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_atmo - if("Security") - icon = 'icons/obj/doors/airlocks/station/security.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_sec - if("Command") - icon = 'icons/obj/doors/airlocks/station/command.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_com - if("Medical") - icon = 'icons/obj/doors/airlocks/station/medical.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_med - if("Research") - icon = 'icons/obj/doors/airlocks/station/research.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_research - if("Freezer") - icon = 'icons/obj/doors/airlocks/station/freezer.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_fre - if("Science") - icon = 'icons/obj/doors/airlocks/station/science.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_science - if("Virology") - icon = 'icons/obj/doors/airlocks/station/virology.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_viro - if("Mining") - icon = 'icons/obj/doors/airlocks/station/mining.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_min - if("Maintenance") - icon = 'icons/obj/doors/airlocks/station/maintenance.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_mai - if("External") - icon = 'icons/obj/doors/airlocks/external/external.dmi' - overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_ext - if("External Maintenance") - icon = 'icons/obj/doors/airlocks/station/maintenanceexternal.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_extmai + + var/airlock_type = painter.available_paint_jobs["[current_paintjob]"] // get the airlock type path associated with the airlock name the user just chose + var/obj/machinery/door/airlock/airlock = airlock_type // we need to create a new instance of the airlock and assembly to read vars from them + var/obj/structure/door_assembly/assembly = initial(airlock.assemblytype) + + if(airlock_material == "glass" && initial(assembly.noglass)) // prevents painting glass airlocks with a paint job that doesn't have a glass version, such as the freezer + to_chat(user, span_warning("This paint job can only be applied to non-glass airlocks.")) + return + + // applies the user-chosen airlock's icon, overlays and assemblytype to the src airlock + painter.use_paint(user) + icon = initial(airlock.icon) + overlays_file = initial(airlock.overlays_file) + assemblytype = initial(airlock.assemblytype) update_icon() -/obj/machinery/door/airlock/CanAStarPass(obj/item/card/id/ID) -//Airlock is passable if it is open (!density), bot has access, and is not bolted shut or powered off) +/obj/machinery/door/airlock/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller) + //Airlock is passable if it is open (!density), bot has access, and is not bolted shut or powered off) return !density || (check_access(ID) && !locked && hasPower()) /obj/machinery/door/airlock/emag_act(mob/user) @@ -1365,11 +1370,19 @@ wires.cut_all() update_icon() +/obj/machinery/door/airlock/proc/remove_electrify() + secondsElectrified = NOT_ELECTRIFIED + unelectrify_timerid = null + diag_hud_set_electrified() + /obj/machinery/door/airlock/proc/set_electrified(seconds, mob/user) secondsElectrified = seconds + if(unelectrify_timerid) + deltimer(unelectrify_timerid) + unelectrify_timerid = null + if(secondsElectrified != ELECTRIFIED_PERMANENT) + unelectrify_timerid = addtimer(CALLBACK(src, .proc/remove_electrify), secondsElectrified SECONDS, TIMER_STOPPABLE) diag_hud_set_electrified() - if(secondsElectrified > NOT_ELECTRIFIED) - INVOKE_ASYNC(src, .proc/electrified_loop) if(user) var/message diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm index 5215baf87f..9575c45c57 100644 --- a/code/game/machinery/doors/airlock_types.dm +++ b/code/game/machinery/doors/airlock_types.dm @@ -485,7 +485,7 @@ var/friendly = FALSE var/stealthy = FALSE -/obj/machinery/door/airlock/cult/Initialize() +/obj/machinery/door/airlock/cult/Initialize(mapload) . = ..() new openingoverlaytype(loc) @@ -576,7 +576,7 @@ desc = "An airlock hastily corrupted by blood magic, it is unusually brittle in this state." normal_integrity = 150 damage_deflection = 5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) //Pinion airlocks: Clockwork doors that only let servants of Ratvar through. /obj/machinery/door/airlock/clockwork @@ -593,7 +593,7 @@ normal_integrity = 240 var/construction_state = GEAR_SECURE //Pinion airlocks have custom deconstruction -/obj/machinery/door/airlock/clockwork/Initialize() +/obj/machinery/door/airlock/clockwork/Initialize(mapload) . = ..() new /obj/effect/temp_visual/ratvar/door(loc) new /obj/effect/temp_visual/ratvar/beam/door(loc) diff --git a/code/game/machinery/doors/alarmlock.dm b/code/game/machinery/doors/alarmlock.dm index fa516f4b6b..f0b0d9eeb0 100644 --- a/code/game/machinery/doors/alarmlock.dm +++ b/code/game/machinery/doors/alarmlock.dm @@ -10,7 +10,7 @@ var/air_frequency = FREQ_ATMOS_ALARMS autoclose = FALSE -/obj/machinery/door/airlock/alarmlock/Initialize() +/obj/machinery/door/airlock/alarmlock/Initialize(mapload) . = ..() air_connection = new @@ -19,7 +19,7 @@ air_connection = null return ..() -/obj/machinery/door/airlock/alarmlock/Initialize() +/obj/machinery/door/airlock/alarmlock/Initialize(mapload) . = ..() SSradio.remove_object(src, air_frequency) air_connection = SSradio.add_object(src, air_frequency, RADIO_TO_AIRALARM) diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index b2e0050819..c209118537 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -36,7 +36,7 @@ maptext_height = 26 maptext_width = 32 -/obj/machinery/door_timer/Initialize() +/obj/machinery/door_timer/Initialize(mapload) . = ..() Radio = new/obj/item/radio(src) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 9ff03cd387..a3483e5702 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -10,7 +10,7 @@ power_channel = ENVIRON max_integrity = 350 damage_deflection = 10 - armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 70) + armor = list(MELEE = 30, BULLET = 30, LASER = 20, ENERGY = 20, BOMB = 10, BIO = 100, RAD = 100, FIRE = 80, ACID = 70) CanAtmosPass = ATMOS_PASS_DENSITY flags_1 = PREVENT_CLICK_UNDER_1|DEFAULT_RICOCHET_1 ricochet_chance_mod = 0.8 @@ -44,6 +44,8 @@ var/red_alert_access = FALSE //if TRUE, this door will always open on red alert var/poddoor = FALSE var/unres_sides = 0 //Unrestricted sides. A bitflag for which direction (if any) can open the door with no access + /// Whether or not the door can be opened by hand (used for blast doors and shutters) + var/can_open_with_hands = TRUE /obj/machinery/door/examine(mob/user) . = ..() @@ -55,16 +57,30 @@ if(!poddoor) . += "Its maintenance panel is screwed in place." +/obj/machinery/door/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + + if(!can_open_with_hands) + return . + + if(isaicamera(user) || issilicon(user)) + return . + + if(isnull(held_item) && Adjacent(user)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, (density ? "Open" : "Close")) + return CONTEXTUAL_SCREENTIP_SET + /obj/machinery/door/check_access_list(list/access_list) if(red_alert_access && GLOB.security_level >= SEC_LEVEL_RED) return TRUE return ..() -/obj/machinery/door/Initialize() +/obj/machinery/door/Initialize(mapload) . = ..() set_init_door_layer() update_freelook_sight() air_update_turf(1) + register_context() GLOB.airlocks += src spark_system = new /datum/effect_system/spark_spread spark_system.set_up(2, 1, src) @@ -92,7 +108,7 @@ return ..() /obj/machinery/door/Bumped(atom/movable/AM) - if(operating || (obj_flags & EMAGGED)) + if(operating || (obj_flags & EMAGGED) || (!can_open_with_hands && density)) return if(ismob(AM)) var/mob/B = AM @@ -107,19 +123,6 @@ return bumpopen(M) return - - if(ismecha(AM)) - var/obj/mecha/mecha = AM - if(density) - if(mecha.occupant) - if(world.time - mecha.occupant.last_bumped <= 10) - return - mecha.occupant.last_bumped = world.time - if(mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access))) - open() - else - do_animate("deny") - return return /obj/machinery/door/Move() @@ -127,15 +130,19 @@ . = ..() move_update_air(T) -/obj/machinery/door/CanPass(atom/movable/mover, turf/target) +/obj/machinery/door/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() + if(.) + return + + // Snowflake handling for PASSGLASS. if(istype(mover) && (mover.pass_flags & PASSGLASS)) return !opacity - return !density /obj/machinery/door/proc/bumpopen(mob/user) - if(operating) + if(operating || !can_open_with_hands) return - src.add_fingerprint(user) + add_fingerprint(user) if(!src.requiresID()) user = null @@ -156,7 +163,7 @@ /obj/machinery/door/proc/try_to_activate_door(mob/user) add_fingerprint(user) - if(operating || (obj_flags & EMAGGED)) + if(operating || (obj_flags & EMAGGED) || !can_open_with_hands) return if(!requiresID()) user = null //so allowed(user) always succeeds @@ -362,7 +369,7 @@ C.bleed(DOOR_CRUSH_DAMAGE) else L.add_splatter_floor(location) - for(var/obj/mecha/M in get_turf(src)) + for(var/obj/vehicle/sealed/mecha/M in get_turf(src)) M.take_damage(DOOR_CRUSH_DAMAGE) /obj/machinery/door/proc/autoclose() @@ -407,7 +414,7 @@ if(!stat) //Opens only powered doors. open() //Open everything! -/obj/machinery/door/ex_act(severity, target) +/obj/machinery/door/ex_act(severity, target, origin) //if it blows up a wall it should blow up a door ..(severity ? max(1, severity - 1) : 0, target) @@ -418,3 +425,14 @@ . = ..() if(!density) return . * EXPLOSION_DAMAGE_OPEN_DOOR_FACTOR + +/obj/machinery/door/shuttleRotate(rotation, params) + . = ..() + if(!unres_sides) + return + var/new_unres_sides + for(var/direction in GLOB.cardinals) + if(unres_sides & direction) + new_unres_sides |= angle2dir_cardinal(rotation+dir2angle(direction)) + unres_sides = new_unres_sides + update_icon() diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index d84b994b92..7b0ff1d319 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -21,19 +21,22 @@ layer = BELOW_OPEN_DOOR_LAYER closingLayer = CLOSED_FIREDOOR_LAYER assemblytype = /obj/structure/firelock_frame - armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 70) + armor = list(MELEE = 30, BULLET = 30, LASER = 20, ENERGY = 20, BOMB = 10, BIO = 100, RAD = 100, FIRE = 95, ACID = 70) interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN air_tight = TRUE attack_hand_is_action = TRUE attack_hand_speed = CLICK_CD_MELEE + can_open_with_hands = FALSE var/emergency_close_timer = 0 var/nextstate = null var/boltslocked = TRUE var/list/affecting_areas -/obj/machinery/door/firedoor/Initialize() +/obj/machinery/door/firedoor/Initialize(mapload) . = ..() CalculateAffectingAreas() + UpdateAdjacencyFlags() + /obj/machinery/door/firedoor/examine(mob/user) . = ..() @@ -46,6 +49,34 @@ else . += "The bolt locks have been unscrewed, but the bolts themselves are still wrenched to the floor." +/obj/machinery/door/firedoor/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + + if (isnull(held_item)) + if (density) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Knock") + return CONTEXTUAL_SCREENTIP_SET + else + return . + + switch (held_item.tool_behaviour) + if (TOOL_CROWBAR) + if(!welded) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, (density ? "Open" : "Close")) + return CONTEXTUAL_SCREENTIP_SET + if (TOOL_WELDER) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, (welded ? "Unweld shut" : "Weld shut")) + return CONTEXTUAL_SCREENTIP_SET + if (TOOL_WRENCH) + if (welded && !boltslocked) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Unfasten bolts") + return CONTEXTUAL_SCREENTIP_SET + if (TOOL_SCREWDRIVER) + if (welded) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, (boltslocked ? "Unlock bolts" : "Lock bolts")) + return CONTEXTUAL_SCREENTIP_SET + return . + /obj/machinery/door/firedoor/proc/CalculateAffectingAreas() remove_from_areas() affecting_areas = get_adjacent_open_areas(src) | get_base_area(src) @@ -53,6 +84,24 @@ var/area/A = I LAZYADD(A.firedoors, src) +/obj/machinery/door/firedoor/proc/UpdateAdjacencyFlags() + var/turf/T = get_turf(src) + if(flags_1 & ON_BORDER_1) + for(var/t in T.atmos_adjacent_turfs) + if(get_dir(loc, t) == dir) + var/turf/open/T2 = t + if(T2 in T.atmos_adjacent_turfs) + T.atmos_adjacent_turfs[T2] |= ATMOS_ADJACENT_FIRELOCK + if(T in T2.atmos_adjacent_turfs) + T2.atmos_adjacent_turfs[T] |= ATMOS_ADJACENT_FIRELOCK + else + for(var/t in T.atmos_adjacent_turfs) + var/turf/open/T2 = t + if(T2 in T.atmos_adjacent_turfs) + T.atmos_adjacent_turfs[T2] |= ATMOS_ADJACENT_FIRELOCK + if(T in T2.atmos_adjacent_turfs) + T2.atmos_adjacent_turfs[T] |= ATMOS_ADJACENT_FIRELOCK + /obj/machinery/door/firedoor/closed icon_state = "door_closed" opacity = TRUE @@ -142,7 +191,7 @@ if(is_holding_pressure()) // tell the user that this is a bad idea, and have a do_after as well to_chat(user, "As you begin crowbarring \the [src] a gush of air blows in your face... maybe you should reconsider?") - if(!do_after(user, 15, TRUE, src)) // give them a few seconds to reconsider their decision. + if(!do_after(user, 1.5 SECONDS, src)) // give them a few seconds to reconsider their decision. return log_game("[key_name_admin(user)] has opened a firelock with a pressure difference at [AREACOORD(loc)]") // there bibby I made it logged just for you. Enjoy. // since we have high-pressure-ness, close all other firedoors on the tile @@ -347,21 +396,18 @@ return 0 // not big enough to matter return start_point.air.return_pressure() < 20 ? -1 : 1 -/obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return TRUE - if(get_dir(loc, target) == dir) //Make sure looking at appropriate border - return !density - else +/obj/machinery/door/firedoor/border_only/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() + if(!(get_dir(loc, target) == dir)) //Make sure looking at appropriate border return TRUE +/obj/machinery/door/firedoor/border_only/CanAStarPass(obj/item/card/id/ID, to_dir) + return !density || (dir != to_dir) + /obj/machinery/door/firedoor/border_only/CheckExit(atom/movable/mover as mob|obj, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return TRUE if(get_dir(loc, target) == dir) return !density - else - return TRUE + return TRUE /obj/machinery/door/firedoor/border_only/CanAtmosPass(turf/T) if(get_dir(loc, T) == dir) diff --git a/code/game/machinery/doors/passworddoor.dm b/code/game/machinery/doors/passworddoor.dm index 0c64151bca..64afc07ae3 100644 --- a/code/game/machinery/doors/passworddoor.dm +++ b/code/game/machinery/doors/passworddoor.dm @@ -6,7 +6,7 @@ explosion_block = 3 heat_proof = TRUE max_integrity = 600 - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | LAVA_PROOF damage_deflection = 70 var/password = "Swordfish" @@ -69,7 +69,7 @@ /obj/machinery/door/password/emp_act(severity) return -/obj/machinery/door/password/ex_act(severity, target) +/obj/machinery/door/password/ex_act(severity, target, origin) return /obj/machinery/door/password/wave_ex_act(power, datum/wave_explosion/explosion, dir) diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index 8c7fc692bc..ba96cb5bf6 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -13,9 +13,10 @@ heat_proof = TRUE safe = FALSE max_integrity = 600 - armor = list("melee" = 50, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70) + armor = list(MELEE = 50, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 70) resistance_flags = FIRE_PROOF damage_deflection = 70 + can_open_with_hands = FALSE poddoor = TRUE /obj/machinery/door/poddoor/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE) @@ -68,7 +69,7 @@ return ..() //"BLAST" doors are obviously stronger than regular doors when it comes to BLASTS. -/obj/machinery/door/poddoor/ex_act(severity, target) +/obj/machinery/door/poddoor/ex_act(severity, target, origin) if(severity == 3) return ..() diff --git a/code/game/machinery/doors/shutters.dm b/code/game/machinery/doors/shutters.dm index 362dde1157..323fab4cf2 100644 --- a/code/game/machinery/doors/shutters.dm +++ b/code/game/machinery/doors/shutters.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/doors/shutters.dmi' layer = SHUTTER_LAYER closingLayer = SHUTTER_LAYER - armor = list("melee" = 20, "bullet" = 20, "laser" = 20, "energy" = 75, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70) + armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 75, BOMB = 25, BIO = 100, RAD = 100, FIRE = 100, ACID = 70) damage_deflection = 20 max_integrity = 100 @@ -24,7 +24,7 @@ desc = "These shutters have an armoured frame; it looks like plasteel. These shutters look robust enough to survive explosions." icon = 'icons/obj/doors/shutters_old.dmi' icon_state = "closed" - armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 75, "bomb" = 30, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70) + armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 75, BOMB = 30, BIO = 100, RAD = 100, FIRE = 100, ACID = 70) max_integrity = 300 /obj/machinery/door/poddoor/shutters/old/preopen diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index af7545d3c9..7d9ec6a9a1 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -9,9 +9,10 @@ var/base_state = "left" max_integrity = 150 //If you change this, consider changing ../door/window/brigdoor/ max_integrity at the bottom of this .dm file integrity_failure = 0 - armor = list("melee" = 20, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 70, "acid" = 100) + armor = list(MELEE = 20, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 10, BIO = 100, RAD = 100, FIRE = 70, ACID = 100) visible = FALSE flags_1 = ON_BORDER_1|DEFAULT_RICOCHET_1 + pass_flags_self = PASSGLASS opacity = 0 CanAtmosPass = ATMOS_PASS_PROC interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN @@ -77,11 +78,13 @@ return if (!( ismob(AM) )) if(ismecha(AM)) - var/obj/mecha/mecha = AM - if(mecha.occupant && src.allowed(mecha.occupant)) - open_and_close() - else - do_animate("deny") + var/obj/vehicle/sealed/mecha/mecha = AM + for(var/O in mecha.occupants) + var/mob/living/occupant = O + if(allowed(occupant)) + open_and_close() + return + do_animate("deny") return if (!( SSticker )) return @@ -103,11 +106,12 @@ do_animate("deny") return -/obj/machinery/door/window/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return 1 +/obj/machinery/door/window/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() + if(.) + return if(get_dir(loc, target) == dir) //Make sure looking at appropriate border - return !density + return if(istype(mover, /obj/structure/window)) var/obj/structure/window/W = mover if(!valid_window_location(loc, W.ini_dir)) @@ -119,7 +123,7 @@ else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir)) return FALSE else - return 1 + return TRUE /obj/machinery/door/window/CanAtmosPass(turf/T) if(get_dir(loc, T) == dir) @@ -131,13 +135,12 @@ /obj/machinery/door/window/CanAStarPass(obj/item/card/id/ID, to_dir) return !density || (dir != to_dir) || (check_access(ID) && hasPower()) -/obj/machinery/door/window/CheckExit(atom/movable/mover as mob|obj, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return 1 +/obj/machinery/door/window/CheckExit(atom/movable/mover, turf/target) + if((pass_flags_self & mover.pass_flags) || ((pass_flags_self & LETPASSTHROW) && mover.throwing)) + return TRUE if(get_dir(loc, target) == dir) return !density - else - return 1 + return TRUE /obj/machinery/door/window/open(forced=0) if (src.operating == 1) //doors can still open when emag-disabled diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index 2066e88f85..458f231f4b 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -14,7 +14,7 @@ GLOBAL_LIST_EMPTY(doppler_arrays) verb_say = "states coldly" var/list/message_log = list() -/obj/machinery/doppler_array/Initialize() +/obj/machinery/doppler_array/Initialize(mapload) . = ..() GLOB.doppler_arrays += src @@ -194,24 +194,23 @@ GLOBAL_LIST_EMPTY(doppler_arrays) /*****The Point Calculator*****/ - if(orig_light < 10) + if(orig_light < 5) say("Explosion not large enough for research calculations.") return - else if(orig_light < 4500) - point_gain = (83300 * orig_light) / (orig_light + 3000) - else - point_gain = TECHWEB_BOMB_POINTCAP + else if(orig_light < BOMB_TARGET_SIZE) // we want to give fewer points if below the target; this curve does that + point_gain = (BOMB_TARGET_POINTS * orig_light ** BOMB_SUB_TARGET_EXPONENT) / (BOMB_TARGET_SIZE**BOMB_SUB_TARGET_EXPONENT) + else // once we're at the target, switch to a hyperbolic function so we can't go too far above it, but bigger bombs always get more points + point_gain = (BOMB_TARGET_POINTS * 2 * orig_light) / (orig_light + BOMB_TARGET_SIZE) /*****The Point Capper*****/ - if(point_gain > linked_techweb.largest_bomb_value) - if(point_gain <= TECHWEB_BOMB_POINTCAP || linked_techweb.largest_bomb_value < TECHWEB_BOMB_POINTCAP) - var/old_tech_largest_bomb_value = linked_techweb.largest_bomb_value //held so we can pull old before we do math - linked_techweb.largest_bomb_value = point_gain - point_gain -= old_tech_largest_bomb_value - point_gain = min(point_gain,TECHWEB_BOMB_POINTCAP) - else - linked_techweb.largest_bomb_value = TECHWEB_BOMB_POINTCAP - point_gain = 1000 + + var/list/largest_values = linked_techweb.largest_values + if(!(LARGEST_BOMB in largest_values)) + largest_values[LARGEST_BOMB] = 0 + if(point_gain > largest_values[LARGEST_BOMB]) + var/old_tech_largest_bomb_value = largest_values[LARGEST_BOMB] //held so we can pull old before we do math + linked_techweb.largest_values[LARGEST_BOMB] = point_gain + point_gain -= old_tech_largest_bomb_value var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_SCI) if(D) D.adjust_money(point_gain) @@ -223,6 +222,6 @@ GLOBAL_LIST_EMPTY(doppler_arrays) return -/obj/machinery/doppler_array/research/science/Initialize() +/obj/machinery/doppler_array/research/science/Initialize(mapload) . = ..() linked_techweb = SSresearch.science_tech diff --git a/code/game/machinery/droneDispenser.dm b/code/game/machinery/droneDispenser.dm index 74df30ebfe..4d2d5d3d7a 100644 --- a/code/game/machinery/droneDispenser.dm +++ b/code/game/machinery/droneDispenser.dm @@ -48,7 +48,7 @@ var/break_message = "lets out a tinny alarm before falling dark." var/break_sound = 'sound/machines/warning-buzzer.ogg' -/obj/machinery/droneDispenser/Initialize() +/obj/machinery/droneDispenser/Initialize(mapload) . = ..() var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, list(/datum/material/iron, /datum/material/glass), MINERAL_MATERIAL_AMOUNT * MAX_STACK_SIZE * 2, TRUE, /obj/item/stack) materials.insert_amount_mat(starting_amount) diff --git a/code/game/machinery/embedded_controller/access_controller.dm b/code/game/machinery/embedded_controller/access_controller.dm index 8eebd779f4..3beb481e00 100644 --- a/code/game/machinery/embedded_controller/access_controller.dm +++ b/code/game/machinery/embedded_controller/access_controller.dm @@ -18,7 +18,7 @@ /obj/machinery/doorButtons/proc/findObjsByTag() return -/obj/machinery/doorButtons/Initialize() +/obj/machinery/doorButtons/Initialize(mapload) ..() return INITIALIZE_HINT_LATELOAD diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index 5d0165189d..0a0a4e08f3 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -3,6 +3,10 @@ var/state var/obj/machinery/embedded_controller/master +/datum/computer/file/embedded_program/Destroy() + master = null + . = ..() + /datum/computer/file/embedded_program/proc/post_signal(datum/signal/signal, comm_line) if(master) master.post_signal(signal, comm_line) @@ -25,6 +29,11 @@ var/on = TRUE +/obj/machinery/embedded_controller/Destroy() + if(program) + QDEL_NULL(program) + . = ..() + /obj/machinery/embedded_controller/ui_interact(mob/user) . = ..() user.set_machine(src) @@ -67,7 +76,7 @@ SSradio.remove_object(src,frequency) return ..() -/obj/machinery/embedded_controller/radio/Initialize() +/obj/machinery/embedded_controller/radio/Initialize(mapload) . = ..() set_frequency(frequency) diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 229a2d98d8..0a0bed491b 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -20,7 +20,7 @@ plane = ABOVE_WALL_PLANE max_integrity = 250 integrity_failure = 0.4 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 100, FIRE = 90, ACID = 30) use_power = IDLE_POWER_USE idle_power_usage = 2 active_power_usage = 6 @@ -33,8 +33,10 @@ var/detecting = 1 var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone - var/last_alarm = 0 + COOLDOWN_DECLARE(last_alarm) var/area/myarea = null + //Has this firealarm been triggered by its enviroment? + var/triggered = FALSE /obj/machinery/firealarm/Initialize(mapload, dir, building) . = ..() @@ -49,7 +51,18 @@ myarea = get_base_area(src) LAZYADD(myarea.firealarms, src) + register_context() + +/obj/machinery/firealarm/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + + if(isnull(held_item)) + var/area/location = get_area(src) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, (location.fire ? "Turn off" : "Turn on")) + return CONTEXTUAL_SCREENTIP_SET + /obj/machinery/firealarm/Destroy() + myarea.firereset(src) LAZYREMOVE(myarea.firealarms, src) return ..() @@ -102,7 +115,7 @@ . += mutable_appearance(icon, "fire_on") . += emissive_appearance(icon, "fire_on") - if(!panel_open && detecting) //It just looks horrible with the panel open + if(!panel_open && detecting && triggered) //It just looks horrible with the panel open . += "fire_detected" . += mutable_appearance(icon, "fire_detected") . += emissive_appearance(icon, "fire_detected") //Pain @@ -129,14 +142,14 @@ return TRUE /obj/machinery/firealarm/temperature_expose(datum/gas_mixture/air, temperature, volume) - if((temperature > T0C + 200 || temperature < BODYTEMP_COLD_DAMAGE_LIMIT) && (last_alarm+FIREALARM_COOLDOWN < world.time) && !(obj_flags & EMAGGED) && detecting && !stat) + if((temperature > T0C + 200 || temperature < BODYTEMP_COLD_DAMAGE_LIMIT) && COOLDOWN_FINISHED(src, last_alarm) && !(obj_flags & EMAGGED) && detecting && !stat) alarm() - ..() + return ..() /obj/machinery/firealarm/proc/alarm(mob/user) - if(!is_operational() || (last_alarm+FIREALARM_COOLDOWN > world.time)) + if(!is_operational() || !COOLDOWN_FINISHED(src, last_alarm)) return - last_alarm = world.time + COOLDOWN_START(src, last_alarm, FIREALARM_COOLDOWN) var/area/A = get_base_area(src) A.firealert(src) playsound(loc, 'goon/sound/machinery/FireAlarm.ogg', 75) @@ -147,7 +160,7 @@ if(!is_operational()) return var/area/A = get_base_area(src) - A.firereset(src) + A.firereset() if(user) log_game("[user] reset a fire alarm at [COORD(src)]") diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index 20aac89743..9b16f4ad0c 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -93,7 +93,7 @@ return flash() /obj/machinery/flasher/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < 10) //any melee attack below 10 dmg does nothing + if(damage_flag == MELEE && damage_amount < 10) //any melee attack below 10 dmg does nothing return 0 . = ..() @@ -159,7 +159,7 @@ new /obj/item/stack/sheet/metal (loc, 2) qdel(src) -/obj/machinery/flasher/portable/Initialize() +/obj/machinery/flasher/portable/Initialize(mapload) . = ..() proximity_monitor = new(src, 0) diff --git a/code/game/machinery/gulag_teleporter.dm b/code/game/machinery/gulag_teleporter.dm index da64699dd4..f595829890 100644 --- a/code/game/machinery/gulag_teleporter.dm +++ b/code/game/machinery/gulag_teleporter.dm @@ -32,7 +32,7 @@ The console is located at computer/gulag_teleporter.dm /obj/item/clothing/mask/breath, /obj/item/clothing/mask/gas)) -/obj/machinery/gulag_teleporter/Initialize() +/obj/machinery/gulag_teleporter/Initialize(mapload) . = ..() locate_reclaimer() diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm index 191967ac1a..5d4f0f1ac8 100644 --- a/code/game/machinery/harvester.dm +++ b/code/game/machinery/harvester.dm @@ -16,7 +16,7 @@ var/allow_clothing = FALSE var/allow_living = FALSE -/obj/machinery/harvester/Initialize() +/obj/machinery/harvester/Initialize(mapload) . = ..() if(prob(1)) name = "auto-autopsy" diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 853bd73eac..cd87a858b8 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -1,8 +1,8 @@ /* Holograms! * Contains: - * Holopad - * Hologram - * Other stuff + * Holopad + * Hologram + * Other stuff */ /* @@ -24,7 +24,6 @@ Possible to do for anyone motivated enough: * Holopad */ -GLOBAL_LIST_EMPTY(network_holopads) #define HOLOPAD_PASSIVE_POWER_USAGE 1 #define HOLOGRAM_POWER_USAGE 2 @@ -32,6 +31,7 @@ GLOBAL_LIST_EMPTY(network_holopads) name = "holopad" desc = "It's a floor-mounted device for projecting holographic images." icon_state = "holopad0" + base_icon_state = "holopad" layer = LOW_OBJ_LAYER plane = FLOOR_PLANE flags_1 = HEAR_1 @@ -40,7 +40,7 @@ GLOBAL_LIST_EMPTY(network_holopads) idle_power_usage = 5 active_power_usage = 100 max_integrity = 300 - armor = list("melee" = 50, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0) + armor = list(MELEE = 50, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 0) circuit = /obj/item/circuitboard/machine/holopad /// List of living mobs that use the holopad var/list/masters @@ -70,7 +70,7 @@ GLOBAL_LIST_EMPTY(network_holopads) var/obj/effect/overlay/holo_pad_hologram/replay_holo /// Calls will be automatically answered after a couple rings, here for debugging var/static/force_answer_call = FALSE - // var/static/list/holopads = list() + var/static/list/holopads = list() var/obj/effect/overlay/holoray/ray var/ringing = FALSE var/offset = FALSE @@ -80,12 +80,25 @@ GLOBAL_LIST_EMPTY(network_holopads) /// If we are currently calling another holopad var/calling = FALSE +/obj/machinery/holopad/Initialize(mapload) + . = ..() + register_context() + +/obj/machinery/holopad/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + if(isAI(user) && on_network) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Project yourself") + if(LAZYLEN(masters) && masters[user]) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Stop projecting") + LAZYSET(context[SCREENTIP_CONTEXT_CTRL_LMB], INTENT_ANY, "Stop projecting") + return CONTEXTUAL_SCREENTIP_SET + /obj/machinery/holopad/secure name = "secure holopad" desc = "It's a floor-mounted device for projecting holographic images. This one will refuse to auto-connect incoming calls." secure = TRUE -/obj/machinery/holopad/secure/Initialize() +/obj/machinery/holopad/secure/Initialize(mapload) . = ..() var/obj/item/circuitboard/machine/holopad/board = circuit board.secure = TRUE @@ -107,26 +120,47 @@ GLOBAL_LIST_EMPTY(network_holopads) new_disk.forceMove(src) disk = new_disk -/obj/machinery/holopad/tutorial/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/holopad/Moved(atom/OldLoc, Dir) + . = ..() + if(!loc) + return + // move any relevant holograms, basically non-AI, and rays with the pad + if(replay_holo) + replay_holo.abstract_move(loc) + for(var/i in holorays) + var/obj/effect/overlay/holoray/ray = holorays[i] + ray.abstract_move(loc) + var/list/non_call_masters = masters?.Copy() + for(var/datum/holocall/holocall as anything in holo_calls) + if(!holocall.user || !LAZYACCESS(masters, holocall.user)) + continue + non_call_masters -= holocall.user + // moving the eye moves the holo which updates the ray too + holocall.eye.setLoc(locate(clamp(x + (holocall.hologram.x - OldLoc.x), 1, world.maxx), clamp(y + (holocall.hologram.y - OldLoc.y), 1, world.maxy), z)) + for(var/mob/living/holo_master as anything in non_call_masters) + var/obj/effect/holo = masters[holo_master] + update_holoray(holo_master, holo.loc) + +/obj/machinery/holopad/tutorial/attack_hand(mob/user, list/modifiers) if(!istype(user)) return if(user.incapacitated() || !is_operational()) return if(replay_mode) replay_stop() - else if(disk && disk.record) + else if(disk?.record) replay_start() /obj/machinery/holopad/tutorial/HasProximity(atom/movable/AM) if (!isliving(AM)) return - if(!replay_mode && (disk && disk.record)) + if(!replay_mode && (disk?.record)) replay_start() -/obj/machinery/holopad/Initialize() +/obj/machinery/holopad/Initialize(mapload) . = ..() if(on_network) - GLOB.network_holopads += src + holopads += src /obj/machinery/holopad/Destroy() if(outgoing_call) @@ -146,7 +180,7 @@ GLOBAL_LIST_EMPTY(network_holopads) QDEL_NULL(disk) - GLOB.network_holopads -= src + holopads -= src return ..() /obj/machinery/holopad/power_change() @@ -172,8 +206,10 @@ GLOBAL_LIST_EMPTY(network_holopads) /obj/machinery/holopad/examine(mob/user) . = ..() - if(in_range(user, src) || isobserver(user)) - . += "The status display reads: Current projection range: [holo_range] units." + if(isAI(user)) + . += span_notice("The status display reads: Current projection range: [holo_range] units. Use :h to speak through the projection. Right-click to project or cancel a projection. Alt-click to hangup all active and incomming calls. Ctrl-click to end projection without jumping to your last location.") + else if(in_range(user, src) || isobserver(user)) + . += span_notice("The status display reads: Current projection range: [holo_range] units.") /obj/machinery/holopad/attackby(obj/item/P, mob/user, params) if(default_deconstruction_screwdriver(user, "holopad_open", "holopad0", P)) @@ -190,11 +226,11 @@ GLOBAL_LIST_EMPTY(network_holopads) if(istype(P,/obj/item/disk/holodisk)) if(disk) - to_chat(user,"There's already a disk inside [src]!") + to_chat(user,span_warning("There's already a disk inside [src]!")) return if (!user.transferItemToLoc(P,src)) return - to_chat(user,"You insert [P] into [src].") + to_chat(user,span_notice("You insert [P] into [src].")) disk = P return @@ -242,24 +278,29 @@ GLOBAL_LIST_EMPTY(network_holopads) switch(action) if("AIrequest") + if(isAI(usr)) + var/mob/living/silicon/ai/ai_user = usr + ai_user.eyeobj.setLoc(get_turf(src)) + to_chat(usr, span_info("AIs can not request AI presence. Jumping instead.")) + return if(last_request + 200 < world.time) last_request = world.time - to_chat(usr, "You requested an AI's presence.") + to_chat(usr, span_info("You requested an AI's presence.")) var/area/area = get_area(src) for(var/mob/living/silicon/ai/AI in GLOB.silicon_mobs) if(!AI.client) continue - to_chat(AI, "Your presence is requested at \the [area].") + to_chat(AI, span_info("Your presence is requested at \the [area].
    ")) // Project Hologram?")) return TRUE else - to_chat(usr, "A request for AI presence was already sent recently.") + to_chat(usr, span_info("A request for AI presence was already sent recently.")) return if("holocall") if(outgoing_call) return if(usr.loc == loc) var/list/callnames = list() - for(var/I in GLOB.network_holopads) + for(var/I in holopads) var/area/A = get_area(I) if(A) LAZYADD(callnames[A], I) @@ -274,7 +315,7 @@ GLOBAL_LIST_EMPTY(network_holopads) calling = TRUE return TRUE else - to_chat(usr, "You must stand on the holopad to make a call!") + to_chat(usr, span_warning("You must stand on the holopad to make a call!")) if("connectcall") var/datum/holocall/call_to_connect = locate(params["holopad"]) in holo_calls if(!QDELETED(call_to_connect)) @@ -285,6 +326,12 @@ GLOBAL_LIST_EMPTY(network_holopads) if(!QDELETED(call_to_disconnect)) call_to_disconnect.Disconnect(src) return TRUE + if("rejectall") + for(var/datum/holocall/call_to_reject as anything in holo_calls) + if(call_to_reject.connected_holopad == src) // do not kill the current connection + continue + call_to_reject.Disconnect(src) + return TRUE if("disk_eject") if(disk && !replay_mode) disk.forceMove(drop_location()) @@ -327,14 +374,13 @@ GLOBAL_LIST_EMPTY(network_holopads) return TRUE /** - * hangup_all_calls: Disconnects all current holocalls from the holopad - */ + * hangup_all_calls: Disconnects all current holocalls from the holopad + */ /obj/machinery/holopad/proc/hangup_all_calls() for(var/I in holo_calls) var/datum/holocall/HC = I HC.Disconnect(src) -//do not allow AIs to answer calls or people will use it to meta the AI sattelite /obj/machinery/holopad/attack_ai(mob/living/silicon/ai/user) if (!istype(user)) return @@ -343,12 +389,25 @@ GLOBAL_LIST_EMPTY(network_holopads) /*There are pretty much only three ways to interact here. I don't need to check for client since they're clicking on an object. This may change in the future but for now will suffice.*/ - if(user.eyeobj.loc != src.loc)//Set client eye on the object if it's not already. - user.eyeobj.setLoc(get_turf(src)) - else if(!LAZYLEN(masters) || !masters[user])//If there is no hologram, possibly make one. + if(!LAZYLEN(masters) || !masters[user])//If there is no hologram, possibly make one. activate_holo(user) - else//If there is a hologram, remove it. + else//If there is a hologram, remove it, and jump to your last location. clear_holo(user) + // if(user.lastloc)//only jump to your last location if your lastloc is set, which only sets if you projected from a request message. + // user.eyeobj.setLoc(user.lastloc) + // user.lastloc = null + +/obj/machinery/holopad/AICtrlClick(mob/living/silicon/ai/user) + if (!istype(user)) + return + if (!on_network) + return + if(!LAZYLEN(masters) || !masters[user])//If there is no hologram, then this button does nothing. + return + else//If there is a hologram, remove it, but dont jump to your last location. + // user.lastloc = null + clear_holo(user) + return /obj/machinery/holopad/process() if(LAZYLEN(masters)) @@ -378,25 +437,26 @@ GLOBAL_LIST_EMPTY(network_holopads) if(outgoing_call) HC.Disconnect(src)//can't answer calls while calling else - playsound(src, 'sound/machines/twobeep.ogg', 100) //bring, bring! + playsound(src, 'sound/machines/twobeep.ogg', 100) //bring, bring! ringing = TRUE - update_icon() + update_appearance() /obj/machinery/holopad/proc/activate_holo(mob/living/user) var/mob/living/silicon/ai/AI = user if(!istype(AI)) AI = null - if(is_operational() && (!AI || AI.eyeobj.loc == loc))//If the projector has power and client eye is on it - if (AI && istype(AI.current, /obj/machinery/holopad)) - to_chat(user, "ERROR: \black Image feed in progress.") + if(is_operational())//If the projector has power + if(AI && istype(AI.current, /obj/machinery/holopad)) + to_chat(user, "[span_danger("ERROR:")] \black Image feed in progress.") return var/obj/effect/overlay/holo_pad_hologram/Hologram = new(loc)//Spawn a blank effect at the location. if(AI) Hologram.icon = AI.holo_icon - else //make it like real life + AI.eyeobj.setLoc(get_turf(src)) //ensure the AI camera moves to the holopad + else //make it like real life Hologram.icon = user.icon Hologram.icon_state = user.icon_state Hologram.copy_overlays(user, TRUE) @@ -407,17 +467,17 @@ GLOBAL_LIST_EMPTY(network_holopads) Hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it. Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. - Hologram.setAnchored(TRUE)//So space wind cannot drag it. + Hologram.set_anchored(TRUE)//So space wind cannot drag it. Hologram.name = "[user.name] (Hologram)"//If someone decides to right click. - Hologram.set_light(2) //hologram lighting + Hologram.set_light(2) //hologram lighting move_hologram() set_holo(user, Hologram) - visible_message("A holographic image of [user] flickers to life before your eyes!") + visible_message(span_notice("A holographic image of [user] flickers to life before your eyes!")) return Hologram else - to_chat(user, "ERROR: Unable to project hologram.") + to_chat(user, "[span_danger("ERROR:")] Unable to project hologram.") /*This is the proc for special two-way communication between AI and holopad/people talking near holopad. For the other part of the code, check silicon say.dm. Particularly robot talk.*/ @@ -430,10 +490,13 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ for(var/I in holo_calls) var/datum/holocall/HC = I - if(HC.connected_holopad == src && speaker != HC.hologram) - HC.user.Hear(message, speaker, message_language, raw_message, radio_freq, spans, message_mods) + if(HC.connected_holopad == src) + if(speaker == HC.hologram && HC.user.client?.prefs.chat_on_map) + HC.user.create_chat_message(speaker, message_language, raw_message, spans) + else + HC.user.Hear(message, speaker, message_language, raw_message, radio_freq, spans, message_mods) - if(outgoing_call && speaker == outgoing_call.user) + if(outgoing_call?.hologram && speaker == outgoing_call.user) outgoing_call.hologram.say(raw_message) if(record_mode && speaker == record_user) @@ -447,16 +510,15 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ set_light(2) else set_light(0) - update_icon() + update_appearance() /obj/machinery/holopad/update_icon_state() var/total_users = LAZYLEN(masters) + LAZYLEN(holo_calls) if(ringing) - icon_state = "holopad_ringing" - else if(total_users || replay_mode) - icon_state = "holopad1" - else - icon_state = "holopad0" + icon_state = "[base_icon_state]_ringing" + return ..() + icon_state = "[base_icon_state][(total_users || replay_mode) ? 1 : 0]" + return ..() /obj/machinery/holopad/proc/set_holo(mob/living/user, obj/effect/overlay/holo_pad_hologram/h) LAZYSET(masters, user, h) @@ -488,7 +550,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ var/obj/effect/overlay/holo_pad_hologram/h = masters[holo_owner] if(!h || h.HC) //Holocalls can't change source. return FALSE - for(var/pad in GLOB.network_holopads) + for(var/pad in holopads) var/obj/machinery/holopad/another = pad if(another == src) continue @@ -524,7 +586,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ else transfered = TRUE //All is good. - holo.forceMove(new_turf) + holo.abstract_move(new_turf) if(!transfered) update_holoray(user,new_turf) return TRUE @@ -565,10 +627,10 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ holder.selected_language = record.language Hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it. Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. - Hologram.setAnchored(TRUE)//So space wind cannot drag it. + Hologram.set_anchored(TRUE)//So space wind cannot drag it. Hologram.name = "[record.caller_name] (Hologram)"//If someone decides to right click. - Hologram.set_light(2) //hologram lighting - visible_message("A holographic image of [record.caller_name] flickers to life before your eyes!") + Hologram.set_light(2) //hologram lighting + visible_message(span_notice("A holographic image of [record.caller_name] flickers to life before your eyes!")) return Hologram /obj/machinery/holopad/proc/replay_start() @@ -661,7 +723,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ record_user = null /obj/machinery/holopad/proc/record_clear() - if(disk && disk.record) + if(disk?.record) QDEL_NULL(disk.record) /obj/effect/overlay/holo_pad_hologram @@ -673,6 +735,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ Impersonation = null if(!QDELETED(HC)) HC.Disconnect(HC.calling_holopad) + HC = null return ..() /obj/effect/overlay/holo_pad_hologram/Process_Spacemove(movement_dir = 0) diff --git a/code/game/machinery/hypnochair.dm b/code/game/machinery/hypnochair.dm index 41f420204e..9380038147 100644 --- a/code/game/machinery/hypnochair.dm +++ b/code/game/machinery/hypnochair.dm @@ -14,7 +14,7 @@ var/timerid = 0 ///Timer ID for interrogations var/message_cooldown = 0 ///Cooldown for breakout message -/obj/machinery/hypnochair/Initialize() +/obj/machinery/hypnochair/Initialize(mapload) . = ..() open_machine() update_icon() diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index bb047a6a5e..2f70bfcecb 100644 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -8,7 +8,7 @@ idle_power_usage = 2 active_power_usage = 4 max_integrity = 300 - armor = list("melee" = 50, "bullet" = 30, "laser" = 70, "energy" = 50, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70) + armor = list(MELEE = 50, BULLET = 30, LASER = 70, ENERGY = 50, BOMB = 20, BIO = 0, RAD = 0, FIRE = 100, ACID = 70) resistance_flags = FIRE_PROOF var/id = null var/on = FALSE @@ -40,7 +40,7 @@ location.hotspot_expose(700,10,1) return 1 -/obj/machinery/igniter/Initialize() +/obj/machinery/igniter/Initialize(mapload) . = ..() icon_state = "igniter[on]" @@ -70,7 +70,7 @@ /obj/machinery/sparker/toxmix id = INCINERATOR_TOXMIX_IGNITER -/obj/machinery/sparker/Initialize() +/obj/machinery/sparker/Initialize(mapload) . = ..() spark_system = new /datum/effect_system/spark_spread spark_system.set_up(2, 1, src) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index ff6f96a29f..12b2ba08e4 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -230,13 +230,13 @@ if(beaker) if(beaker.reagents && beaker.reagents.reagent_list.len) - . += "\tAttached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.\n" + . += "Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.\n" else - . += "\tAttached is an empty [beaker.name].\n" + . += "Attached is an empty [beaker.name].\n" else - . += "\tNo chemicals are attached.\n" + . += "No chemicals are attached.\n" - . += "\t[attached ? attached : "No one"] is attached." + . += "[attached ? attached : "No one"] is attached." /obj/machinery/iv_drip/telescopic name = "telescopic IV drip" diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm index 87989b18ec..14a90ff3bf 100644 --- a/code/game/machinery/launch_pad.dm +++ b/code/game/machinery/launch_pad.dm @@ -6,6 +6,7 @@ use_power = TRUE idle_power_usage = 200 active_power_usage = 2500 + hud_possible = list(DIAG_LAUNCHPAD_HUD) circuit = /obj/item/circuitboard/machine/launchpad var/icon_teleport = "lpad-beam" var/stationary = TRUE //to prevent briefcase pad deconstruction and such @@ -24,6 +25,25 @@ E += M.rating*15 range = E +/obj/machinery/launchpad/Initialize() + . = ..() + prepare_huds() + for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) + diag_hud.add_to_hud(src) + + var/image/holder = hud_list[DIAG_LAUNCHPAD_HUD] + var/mutable_appearance/MA = new /mutable_appearance() + MA.icon = 'icons/effects/effects.dmi' + MA.icon_state = "launchpad_target" + MA.layer = ABOVE_OPEN_TURF_LAYER + MA.plane = 0 + holder.appearance = MA + update_indicator() + +/obj/machinery/launchpad/Destroy() + qdel(hud_list[DIAG_LAUNCHPAD_HUD]) + return ..() + /obj/machinery/launchpad/examine(mob/user) . = ..() if(in_range(user, src) || isobserver(user)) @@ -32,6 +52,7 @@ /obj/machinery/launchpad/attackby(obj/item/I, mob/user, params) if(stationary) if(default_deconstruction_screwdriver(user, "lpad-idle-o", "lpad-idle", I)) + update_indicator() return if(panel_open) @@ -63,6 +84,17 @@ return FALSE return TRUE +/obj/machinery/launchpad/proc/update_indicator() + var/image/holder = hud_list[DIAG_LAUNCHPAD_HUD] + var/turf/target_turf + if(isAvailable()) + target_turf = locate(x + x_offset, y + y_offset, z) + if(target_turf) + holder.icon_state = indicator_icon + holder.loc = target_turf + else + holder.icon_state = null + /obj/machinery/launchpad/proc/set_offset(x, y) if(teleporting) return @@ -89,11 +121,13 @@ flick(icon_teleport, src) + //Change the indicator's icon to show that we're teleporting if(sending) indicator_icon = "launchpad_launch" else indicator_icon = "launchpad_pull" + update_indicator() playsound(get_turf(src), 'sound/weapons/flash.ogg', 25, TRUE) teleporting = TRUE @@ -103,6 +137,7 @@ //Set the indicator icon back to normal indicator_icon = "launchpad_target" + update_indicator() if(QDELETED(src) || !isAvailable()) return @@ -213,6 +248,7 @@ if(do_after(usr, 30, target = usr)) usr.put_in_hands(briefcase) moveToNullspace() //hides it from suitcase contents + update_indicator() closed = TRUE /obj/machinery/launchpad/briefcase/attackby(obj/item/I, mob/user, params) @@ -229,7 +265,7 @@ /obj/item/storage/briefcase/launchpad var/obj/machinery/launchpad/briefcase/pad -/obj/item/storage/briefcase/launchpad/Initialize() +/obj/item/storage/briefcase/launchpad/Initialize(mapload) pad = new(null, src) //spawns pad in nullspace to hide it from briefcase contents . = ..() @@ -249,6 +285,7 @@ user.visible_message("[user] starts setting down [src]...", "You start setting up [pad]...") if(do_after(user, 30, target = user)) pad.forceMove(get_turf(src)) + pad.update_indicator() pad.closed = FALSE user.transferItemToLoc(src, pad, TRUE) SEND_SIGNAL(src, COMSIG_TRY_STORAGE_HIDE_ALL) @@ -322,6 +359,7 @@ var/new_x = text2num(params["x"]) var/new_y = text2num(params["y"]) pad.set_offset(new_x, new_y) + pad.update_indicator() . = TRUE if("move_pos") var/plus_x = text2num(params["x"]) @@ -330,6 +368,7 @@ x = pad.x_offset + plus_x, y = pad.y_offset + plus_y ) + pad.update_indicator() . = TRUE if("rename") . = TRUE @@ -340,12 +379,15 @@ if("remove") . = TRUE if(usr && alert(usr, "Are you sure?", "Unlink Launchpad", "I'm Sure", "Abort") != "Abort") + pad.update_indicator() pad = null if("launch") sending = TRUE teleport(usr, pad) + pad.update_indicator() . = TRUE if("pull") sending = FALSE teleport(usr, pad) + pad.update_indicator() . = TRUE diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index 03d9dcee4b..0473a1333a 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -24,7 +24,7 @@ dir = EAST pixel_x = -26 -/obj/machinery/light_switch/Initialize() +/obj/machinery/light_switch/Initialize(mapload) . = ..() if(istext(area)) area = text2path(area) diff --git a/code/game/machinery/limbgrower.dm b/code/game/machinery/limbgrower.dm index dc87322b57..421bb2550b 100644 --- a/code/game/machinery/limbgrower.dm +++ b/code/game/machinery/limbgrower.dm @@ -36,7 +36,7 @@ ) var/obj/item/disk/data/dna_disk -/obj/machinery/limbgrower/Initialize() +/obj/machinery/limbgrower/Initialize(mapload) create_reagents(100, OPENCONTAINER) stored_research = new /datum/techweb/specialized/autounlocking/limbgrower . = ..() @@ -52,23 +52,30 @@ /obj/machinery/limbgrower/ui_data(mob/user) var/list/data = list() - - for(var/datum/reagent/reagent_id in reagents.reagent_list) - var/list/reagent_data = list( - reagent_name = reagent_id.name, - reagent_amount = reagent_id.volume, - reagent_type = reagent_id.type - ) - data["reagents"] += list(reagent_data) - + if(reagents.reagent_list.len) + for(var/datum/reagent/reagent_id in reagents.reagent_list) + var/list/reagent_data = list( + reagent_name = reagent_id.name, + reagent_amount = reagent_id.volume, + reagent_type = reagent_id.type + ) + data["reagents"] += list(reagent_data) + else + data["reagents"] = list() data["total_reagents"] = reagents.total_volume data["max_reagents"] = reagents.maximum_volume data["busy"] = busy var/list/disk_data = list() disk_data["disk"] = dna_disk //Do i, the machine, have a disk? - disk_data["name"] = dna_disk?.fields["name"] //Name for the human saved if there is one + if(dna_disk) + if(dna_disk.fields["name"]) + disk_data["name"] = dna_disk.fields["name"] + else if(dna_disk.genetic_makeup_buffer["name"]) + disk_data["name"] = dna_disk.genetic_makeup_buffer["name"] + else + disk_data["name"] = "No name" + //Name for the human saved if there is one data["disk"] = disk_data - return data /obj/machinery/limbgrower/ui_static_data(mob/user) @@ -119,6 +126,18 @@ if (busy) to_chat(user, "\The [src] is busy. Please wait for completion of previous operation.") return + if(ispath(user_item.type, /obj/item/reagent_containers/blood) && user.a_intent != INTENT_HARM) + var/obj/item/reagent_containers/blood/B = user_item + if(!B.reagents.get_reagents()) + to_chat(user, "You can't fill [src] with an empty [B.name]!") + return + if(reagents.total_volume == reagents.maximum_volume) + to_chat(user, "\The [src] can't hold more blood!") + return + user.visible_message("[user] drains the [user_item] into [src] using the blood bag port on [src].", + "You drain the [user_item] into [src] using the blood bag port.") + B.reagents.trans_to(src, B.amount_per_transfer_from_this) + return if(default_deconstruction_screwdriver(user, "limbgrower_panelopen", "limbgrower_idleoff", user_item)) ui_close(user) @@ -180,7 +199,7 @@ for(var/reagent_id in consumed_reagents_list) consumed_reagents_list[reagent_id] *= production_coefficient if(!reagents.has_reagent(reagent_id, consumed_reagents_list[reagent_id])) - audible_message("\The [src] buzzes.") + audible_message("\The [src] buzzes and states \"INSUFFICENT REAGENTS\"") playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) return @@ -206,17 +225,13 @@ * modified_consumed_reagents_list - the list of reagents we will consume on build, modified by the production coefficient. */ /obj/machinery/limbgrower/proc/build_item(list/modified_consumed_reagents_list) - for(var/reagent_id in modified_consumed_reagents_list) - if(!reagents.has_reagent(reagent_id, modified_consumed_reagents_list[reagent_id])) - audible_message("\The [src] buzzes.") - playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) - break - - reagents.remove_reagent(reagent_id, modified_consumed_reagents_list[reagent_id]) - + reagent_usage(modified_consumed_reagents_list) var/built_typepath = being_built.build_path // If we have a bodypart, we need to initialize the limb on its own. Otherwise we can build it here. - if(ispath(built_typepath, /obj/item/bodypart)) + if(ispath(built_typepath, /mob/living/carbon/human/chestonly)) + if(!build_mob_chest(built_typepath, FALSE)) + reagent_usage(modified_consumed_reagents_list, FALSE) + else if(ispath(built_typepath, /obj/item/bodypart)) build_limb(built_typepath) else if(ispath(built_typepath, /obj/item/organ/genital)) //genitals are uhh... customizable build_genital(built_typepath) @@ -227,6 +242,25 @@ flick("limbgrower_unfill", src) icon_state = "limbgrower_idleoff" +/obj/machinery/limbgrower/proc/reagent_usage(modified_consumed_reagents_list, remove = TRUE) + // Apparently, having a boolean in a loop is worse than doing it twice + if(remove) + for(var/reagent_id in modified_consumed_reagents_list) + if(reagent_sanity_check(reagent_id, modified_consumed_reagents_list[reagent_id])) + reagents.remove_reagent(reagent_id, modified_consumed_reagents_list[reagent_id]) + else + for(var/reagent_id in modified_consumed_reagents_list) + if(reagent_sanity_check(reagent_id, modified_consumed_reagents_list[reagent_id])) + reagents.add_reagent(reagent_id, modified_consumed_reagents_list[reagent_id]) + + +/obj/machinery/limbgrower/proc/reagent_sanity_check(reagent_id, amount) + if(reagents.has_reagent(reagent_id, amount)) + return TRUE + audible_message("\The [src] buzzes, with a screen showing: INSUFFICENT REAGENTS") + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + return FALSE + /* * The process of putting together a limb. * This is called from after we remove the reagents, so this proc is just initializing the limb type. @@ -301,11 +335,64 @@ if(!features["breasts_producing"]) boobs.genital_flags &= ~(GENITAL_FUID_PRODUCTION|CAN_CLIMAX_WITH|CAN_MASTURBATE_WITH) boobs.update() + if(/obj/item/organ/genital/butt) + var/obj/item/organ/genital/butt/ass = new(loc) + if(features["has_butt"]) + ass.color = sanitize_hexcolor(features["butt_color"], 6, TRUE) + ass.size = features["butt_size"] + ass.update() else new built_typepath(loc) else new built_typepath(loc) +/obj/machinery/limbgrower/proc/build_mob_chest(built_typepath) + // Create a mob with a chest, but nothing else + if(!ispath(built_typepath, /mob/living/carbon/human/chestonly)) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + visible_message(src, "Buzzes, an error screen appearing on its display.") + return FALSE + // Fields is from cloning, a much fuller scan, genetic_makeup_buffer is less so + var/dna_genetics = dna_disk?.genetic_makeup_buffer + var/dna_cloning = dna_disk?.fields + var/datum/species/selected = GLOB.species_datums[selected_category] + var/mob/living/carbon/human/chestonly/C = new(loc) + C.real_name = length(dna_genetics) ? dna_genetics["name"] : "Synthetic Humanoid #[rand(10000, 99999)]" + if(length(dna_cloning)) + C.hardset_dna(dna_cloning["UI"], dna_cloning["SE"], dna_cloning["name"], dna_cloning["blood_type"], dna_cloning["mrace"], dna_cloning["features"]) + else if(length(dna_genetics)) + C.hardset_dna(dna_genetics["UI"], null, dna_genetics["name"], dna_genetics["blood_type"]) + else + C.real_name = "Synthetic Humanoid #[rand(10000, 99999)]" + C.hair_style = "bald" + C.skin_tone = "albino" + C.set_species(selected) + C.set_resting(TRUE, TRUE) + // Don't want to cause it to deathgasp.. + C.stat = DEAD + C.adjustOxyLoss(200) + // Limb replacement causes toxloss, which can cause too much suffering for the doctor that I don't want + C.adjustCloneLoss(45) + C.med_hud_set_status() + C.med_hud_set_health() + C.underwear = "Nude" + C.undershirt = "Nude" + C.saved_underwear = "" + C.saved_undershirt = "" + + // Just enough to start reviving them, I hope + C.blood_volume = BLOOD_VOLUME_SURVIVE + // At some point, make a way to deal with species regenerate_organs + // Remove all the organs + for(var/organ in C.internal_organs) + var/obj/item/organ/O = organ + O.Remove(organ) + C.update_body(TRUE) + C.update_hair() + C.update_body_parts() + C.update_appearance() + return TRUE + /obj/machinery/limbgrower/RefreshParts() reagents.maximum_volume = 0 for(var/obj/item/reagent_containers/glass/our_beaker in component_parts) diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index c4494b822f..fa71960c9d 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -27,7 +27,7 @@ var/center_y = 0 var/max_dist = 20 // absolute value of center_x,y cannot exceed this integer -/obj/machinery/magnetic_module/Initialize() +/obj/machinery/magnetic_module/Initialize(mapload) ..() var/turf/T = loc hide(T.intact) @@ -213,7 +213,7 @@ var/datum/radio_frequency/radio_connection -/obj/machinery/magnetic_controller/Initialize() +/obj/machinery/magnetic_controller/Initialize(mapload) . = ..() if(autolink) for(var/obj/machinery/magnetic_module/M in GLOB.machines) diff --git a/code/game/machinery/mechlaunchpad.dm b/code/game/machinery/mechlaunchpad.dm index f32fe0bc4f..c6872edda0 100644 --- a/code/game/machinery/mechlaunchpad.dm +++ b/code/game/machinery/mechlaunchpad.dm @@ -13,7 +13,7 @@ ///List of consoles that can access the pad var/list/obj/machinery/computer/mechpad/consoles -/obj/machinery/mechpad/Initialize() +/obj/machinery/mechpad/Initialize(mapload) . = ..() display_name = "Orbital Pad - [get_area_name(src)]" GLOB.mechpad_list += src @@ -24,6 +24,7 @@ connected_console = null for(var/obj/machinery/computer/mechpad/console in consoles) console.mechpads -= src + GLOB.mechpad_list -= src return ..() /obj/machinery/mechpad/screwdriver_act(mob/user, obj/item/tool) diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index 752ba1b732..2bcb9b0762 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -10,7 +10,7 @@ level = 1 // underfloor layer = LOW_OBJ_LAYER max_integrity = 500 - armor = list("melee" = 70, "bullet" = 70, "laser" = 70, "energy" = 70, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) + armor = list(MELEE = 70, BULLET = 70, LASER = 70, ENERGY = 70, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 80) var/open = FALSE // true if cover is open var/locked = TRUE // true if controls are locked @@ -21,7 +21,7 @@ req_one_access = list(ACCESS_ENGINE, ACCESS_ROBOTICS) -/obj/machinery/navbeacon/Initialize() +/obj/machinery/navbeacon/Initialize(mapload) . = ..() set_codes() diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 5b30105409..f849d2f31b 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -45,14 +45,22 @@ Buildable meters if(make_from) make_from_existing(make_from) else - pipe_type = _pipe_type + if(!initial(src.pipe_type)) + pipe_type = _pipe_type setDir(_dir) update() pixel_x += rand(-5, 5) pixel_y += rand(-5, 5) + register_context() return ..() +/obj/item/pipe/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + if(held_item?.tool_behaviour == TOOL_WRENCH) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Fasten") + return CONTEXTUAL_SCREENTIP_SET + /obj/item/pipe/proc/make_from_existing(obj/machinery/atmospherics/make_from) setDir(make_from.dir) pipename = make_from.name diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index e346439e03..b94e51b813 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -13,6 +13,17 @@ #define TURRET_FLAG_SHOOT_BORGS (1<<6) // checks if it can shoot cyborgs #define TURRET_FLAG_SHOOT_HEADS (1<<7) // checks if it can shoot at heads of staff +DEFINE_BITFIELD(turret_flags, list( + "TURRET_FLAG_AUTH_WEAPONS" = TURRET_FLAG_AUTH_WEAPONS, + "TURRET_FLAG_SHOOT_ALL" = TURRET_FLAG_SHOOT_ALL, + "TURRET_FLAG_SHOOT_ALL_REACT" = TURRET_FLAG_SHOOT_ALL_REACT, + "TURRET_FLAG_SHOOT_ANOMALOUS" = TURRET_FLAG_SHOOT_ANOMALOUS, + "TURRET_FLAG_SHOOT_BORGS" = TURRET_FLAG_SHOOT_BORGS, + "TURRET_FLAG_SHOOT_CRIMINALS" = TURRET_FLAG_SHOOT_CRIMINALS, + "TURRET_FLAG_SHOOT_HEADS" = TURRET_FLAG_SHOOT_HEADS, + "TURRET_FLAG_SHOOT_UNSHIELDED" = TURRET_FLAG_SHOOT_UNSHIELDED, +)) + /obj/machinery/porta_turret name = "turret" icon = 'icons/obj/turrets.dmi' @@ -28,7 +39,7 @@ power_channel = EQUIP //drains power from the EQUIPMENT channel max_integrity = 160 //the turret's health integrity_failure = 0.5 - armor = list("melee" = 50, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 50, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 30, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) /// Base turret icon state base_icon_state = "standard" /// Scan range of the turret for locating targets @@ -98,7 +109,7 @@ /// MISSING: var/shot_stagger = 0 -/obj/machinery/porta_turret/Initialize() +/obj/machinery/porta_turret/Initialize(mapload) . = ..() if(!base) base = src @@ -478,10 +489,12 @@ for(var/A in GLOB.mechas_list) if((get_dist(A, base) < scan_range) && can_see(base, A, scan_range)) - var/obj/mecha/Mech = A - if(Mech.occupant && !in_faction(Mech.occupant)) //If there is a user and they're not in our faction - if(assess_perp(Mech.occupant) >= 4) - targets += Mech + var/obj/vehicle/sealed/mecha/mech = A + for(var/O in mech.occupants) + var/mob/living/occupant = O + if(!in_faction(occupant)) //If there is a user and they're not in our faction + if(assess_perp(occupant) >= 4) + targets += mech if((turret_flags & TURRET_FLAG_SHOOT_ANOMALOUS) && GLOB.blobs.len && (mode == TURRET_LETHAL)) for(var/obj/structure/blob/B in view(scan_range, base)) @@ -774,7 +787,7 @@ /obj/machinery/porta_turret/syndicate/energy/pirate max_integrity = 260 integrity_failure = 0.08 - armor = list("melee" = 50, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 50, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 50, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) /obj/machinery/porta_turret/syndicate/energy/raven stun_projectile = /obj/item/projectile/beam/laser @@ -794,7 +807,7 @@ lethal_projectile = /obj/item/projectile/bullet/p50/penetrator/shuttle lethal_projectile_sound = 'sound/weapons/gunshot_smg.ogg' stun_projectile_sound = 'sound/weapons/gunshot_smg.ogg' - armor = list("melee" = 50, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 80, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 50, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 80, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) /obj/machinery/porta_turret/syndicate/pod/toolbox max_integrity = 100 @@ -835,7 +848,7 @@ /obj/machinery/porta_turret/aux_base/interact(mob/user) //Controlled solely from the base console. return -/obj/machinery/porta_turret/aux_base/Initialize() +/obj/machinery/porta_turret/aux_base/Initialize(mapload) . = ..() cover.name = name cover.desc = desc @@ -917,6 +930,14 @@ pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0 power_change() //Checks power and initial settings + register_context() + +/obj/machinery/turretid/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + if(issilicon(user) && !(stat & BROKEN)) + LAZYSET(context[SCREENTIP_CONTEXT_CTRL_LMB], INTENT_ANY, enabled ? "Disable" : "Enable") + LAZYSET(context[SCREENTIP_CONTEXT_ALT_LMB], INTENT_ANY, lethal ? "Set to stun" : "Set to kill") + return CONTEXTUAL_SCREENTIP_SET /obj/machinery/turretid/Destroy() turrets.Cut() diff --git a/code/game/machinery/posi_alert.dm b/code/game/machinery/posi_alert.dm new file mode 100644 index 0000000000..a2a67f22f9 --- /dev/null +++ b/code/game/machinery/posi_alert.dm @@ -0,0 +1,55 @@ +/obj/machinery/posialert + name = "automated positronic alert console" + desc = "A console that will ping when a positronic personality is available for download." + icon = 'icons/obj/machines/terminals.dmi' + icon_state = "posialert" + var/inuse = FALSE + var/online = TRUE + + var/obj/item/radio/radio + var/radio_key = /obj/item/encryptionkey/headset_sci + var/science_channel = "Science" + +/obj/machinery/posialert/Initialize(mapload, ndir, building) + . = ..() + radio = new(src) + radio.keyslot = new radio_key + radio.listening = 0 + radio.recalculateChannels() + if(building) + setDir(ndir) + pixel_x = (dir & 3)? 0 : (dir == 4 ? -32 : 32) + pixel_y = (dir & 3)? (dir ==1 ? -32 : 32) : 0 + + +/obj/machinery/posialert/Destroy() + QDEL_NULL(radio) + return ..() + +/obj/item/wallframe/posialert + name = "automated positronic alert console frame" + desc = "Used to build positronic alert consoles, just secure to the wall." + icon_state = "newscaster" + custom_materials = list(/datum/material/iron=14000, /datum/material/glass=8000) + result_path = /obj/machinery/posialert + +/obj/machinery/posialert/attack_hand(mob/living/user) + online = !online + to_chat(user, "You turn the posi-alert system [online ? "on" : "off"]!") + return + +/obj/machinery/posialert/attack_ghost(mob/user) + . = ..() + if(!online) + return + if(inuse) + return + inuse = TRUE + flick("posialertflash",src) + visible_message("There are positronic personalities available!") + radio.talk_into(src, "There are positronic personalities available!", science_channel) + playsound(loc, 'sound/machines/ping.ogg', 50) + addtimer(CALLBACK(src, .proc/liftcooldown), 300) + +/obj/machinery/posialert/proc/liftcooldown() + inuse = FALSE diff --git a/code/game/machinery/prisonlabor.dm b/code/game/machinery/prisonlabor.dm new file mode 100644 index 0000000000..b76a62a6be --- /dev/null +++ b/code/game/machinery/prisonlabor.dm @@ -0,0 +1,66 @@ +/obj/machinery/plate_press + name = "license plate press" + desc = "You know, we're making a lot of license plates for a station with literaly no cars in it." + icon = 'icons/obj/machines/prison.dmi' + icon_state = "offline" + use_power = IDLE_POWER_USE + idle_power_usage = 2 + active_power_usage = 50 + var/obj/item/stack/license_plates/empty/current_plate + var/pressing = FALSE + +/obj/machinery/plate_press/update_icon() + . = ..() + if(!is_operational()) + icon_state = "offline" + else if(pressing) + icon_state = "loop" + else if(current_plate) + icon_state = "online_loaded" + else + icon_state = "online" + +/obj/machinery/plate_press/Destroy() + QDEL_NULL(current_plate) + . = ..() + +/obj/machinery/plate_press/attackby(obj/item/I, mob/living/user, params) + if(!is_operational()) + to_chat(user, "[src] has to be on to do this!") + return FALSE + if(pressing) + to_chat(user, "[src] already has a plate in it!") + return FALSE + if(istype(I, /obj/item/stack/license_plates/empty)) + var/obj/item/stack/license_plates/empty/plate = I + plate.use(1) + current_plate = new plate.type(src, 1) //Spawn a new single sheet in the machine + update_icon() + else + return ..() + +/obj/machinery/plate_press/attack_hand(mob/living/user) + . = ..() + if(!pressing && current_plate) + work_press(user) + +///This proc attempts to create a plate. User cannot move during this process. +/obj/machinery/plate_press/proc/work_press(mob/living/user) + + pressing = TRUE + update_icon() + to_chat(user, "You start pressing a new license plate!") + + if(!do_after(user, 40, target = src)) + pressing = FALSE + update_icon() + return FALSE + + use_power(100) + to_chat(user, "You finish pressing a new license plate!") + + pressing = FALSE + QDEL_NULL(current_plate) + update_icon() + + new /obj/item/stack/license_plates/filled(drop_location(), 1) diff --git a/code/game/machinery/quantum_pad.dm b/code/game/machinery/quantum_pad.dm index 5c1a2195a4..389dd0f2ab 100644 --- a/code/game/machinery/quantum_pad.dm +++ b/code/game/machinery/quantum_pad.dm @@ -20,7 +20,7 @@ var/map_pad_id = "" as text //what's my name var/map_pad_link_id = "" as text //who's my friend -/obj/machinery/quantumpad/Initialize() +/obj/machinery/quantumpad/Initialize(mapload) . = ..() if(map_pad_id) mapped_quantum_pads[map_pad_id] = src diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 62696a0853..d58edbd025 100755 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -1,7 +1,7 @@ /obj/machinery/recharger name = "recharger" icon = 'icons/obj/stationobjs.dmi' - icon_state = "recharger0" + icon_state = "recharger" base_icon_state = "recharger" desc = "A charging dock for energy based weaponry." use_power = IDLE_POWER_USE @@ -12,6 +12,8 @@ var/obj/item/charging = null var/recharge_coeff = 1 var/using_power = FALSE //Did we put power into "charging" last process()? + ///Did we finish recharging the currently inserted item? + var/finished_recharging = FALSE var/static/list/allowed_devices = typecacheof(list( /obj/item/gun/energy, @@ -48,13 +50,14 @@ charging = new_charging if (new_charging) START_PROCESSING(SSmachines, src) + finished_recharging = FALSE use_power = ACTIVE_POWER_USE using_power = TRUE - update_icon() + update_appearance() else use_power = IDLE_POWER_USE using_power = FALSE - update_icon() + update_appearance() /obj/machinery/recharger/Exited(atom/movable/M, atom/newloc) . = ..() @@ -100,7 +103,8 @@ return 1 if(anchored && !charging) - if(default_deconstruction_screwdriver(user, "rechargeropen", "recharger0", G)) + if(default_deconstruction_screwdriver(user, "recharger", "recharger", G)) + update_appearance() return if(panel_open && G.tool_behaviour == TOOL_CROWBAR) @@ -133,7 +137,7 @@ C.give(C.chargerate * recharge_coeff) use_power(250 * recharge_coeff) using_power = TRUE - update_icon() + update_appearance() if(istype(charging, /obj/item/ammo_box/magazine/recharge)) var/obj/item/ammo_box/magazine/recharge/R = charging @@ -141,7 +145,7 @@ R.stored_ammo += new R.ammo_type(R) use_power(200 * recharge_coeff) using_power = TRUE - update_icon() + update_appearance() return if(istype(charging, /obj/item/ammo_casing/mws_batt)) @@ -152,7 +156,7 @@ using_power = 1 if(R.BB == null) R.chargeshot() - update_icon(using_power) + update_appearance() if(istype(charging, /obj/item/ammo_box/magazine/mws_mag)) var/obj/item/ammo_box/magazine/mws_mag/R = charging @@ -164,14 +168,19 @@ using_power = 1 if(batt.BB == null) batt.chargeshot() - update_icon(using_power) + update_appearance() + + if(!using_power && !finished_recharging) //Inserted thing is at max charge/ammo, notify those around us + finished_recharging = TRUE + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + say("[charging] has finished recharging!") else return PROCESS_KILL /obj/machinery/recharger/power_change() ..() - update_icon() + update_appearance() /obj/machinery/recharger/emp_act(severity) . = ..() diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 0accd0994c..1bd795e4f1 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -1,6 +1,6 @@ /obj/machinery/recharge_station - name = "cyborg recharging station" - desc = "This device recharges cyborgs and resupplies them with materials." + name = "recharging station" + desc = "This device recharges energy dependent lifeforms, like cyborgs, ethereals and MODsuit users." icon = 'icons/obj/objects.dmi' icon_state = "borgcharger0" density = FALSE @@ -10,17 +10,17 @@ req_access = list(ACCESS_ROBOTICS) state_open = TRUE circuit = /obj/item/circuitboard/machine/cyborgrecharger - occupant_typecache = list(/mob/living/silicon/robot) + occupant_typecache = list(/mob/living/silicon/robot, /mob/living/carbon/human) var/recharge_speed var/repairs -/obj/machinery/recharge_station/Initialize() +/obj/machinery/recharge_station/Initialize(mapload) . = ..() update_icon() /obj/machinery/recharge_station/upgraded -/obj/machinery/recharge_station/upgraded/Initialize() +/obj/machinery/recharge_station/upgraded/Initialize(mapload) . = ..() component_parts = list() component_parts += new /obj/item/circuitboard/machine/cyborgrecharger(null) @@ -31,7 +31,7 @@ /obj/machinery/recharge_station/fullupgrade -/obj/machinery/recharge_station/fullupgrade/Initialize() +/obj/machinery/recharge_station/fullupgrade/Initialize(mapload) . = ..() component_parts = list() component_parts += new /obj/item/circuitboard/machine/cyborgrecharger(null) diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index 2ffd556dc1..c561170af4 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -17,7 +17,7 @@ var/eat_victim_items = TRUE var/item_recycle_sound = 'sound/items/welder.ogg' -/obj/machinery/recycler/Initialize() +/obj/machinery/recycler/Initialize(mapload) AddComponent(/datum/component/butchering/recycler, 1, amount_produced,amount_produced/5) AddComponent(/datum/component/material_container, list(/datum/material/iron, /datum/material/glass, /datum/material/silver, /datum/material/plasma, /datum/material/gold, /datum/material/diamond, /datum/material/plastic, /datum/material/uranium, /datum/material/bananium, /datum/material/titanium, /datum/material/bluespace), INFINITY, FALSE, null, null, null, TRUE) . = ..() @@ -87,7 +87,7 @@ is_powered = FALSE icon_state = icon_name + "[is_powered]" + "[(blood ? "bld" : "")]" // add the blood tag at the end -/obj/machinery/recycler/CanPass(atom/movable/AM) +/obj/machinery/recycler/CanAllowThrough(atom/movable/AM) . = ..() if(!anchored) return @@ -110,7 +110,7 @@ var/list/to_eat = AM0.GetAllContents() - var/living_detected = FALSE //technically includes silicons as well but eh + var/mob/living/living_detected //technically includes silicons as well but eh var/list/nom = list() var/list/crunchy_nom = list() //Mobs have to be handled differently so they get a different list instead of checking them multiple times. @@ -119,11 +119,11 @@ if(istype(AM, /obj/item)) var/obj/item/bodypart/head/as_head = AM var/obj/item/mmi/as_mmi = AM - if(istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /obj/item/dullahan_relay)) - living_detected = TRUE + if(istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /obj/item/dullahan_head)) + living_detected = living_detected ? living_detected : AM nom += AM else if(isliving(AM)) - living_detected = TRUE + living_detected = living_detected ? living_detected : AM crunchy_nom += AM var/not_eaten = to_eat.len - nom.len - crunchy_nom.len if(living_detected) // First, check if we have any living beings detected. @@ -132,7 +132,7 @@ if(isliving(CRUNCH)) // MMIs and brains will get eaten like normal items crush_living(CRUNCH) else // Stop processing right now without eating anything. - emergency_stop() + emergency_stop(living_detected) return for(var/nommed in nom) recycle_item(nommed) diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index 5d1b30741b..52c96e269f 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -55,14 +55,14 @@ GLOBAL_LIST_EMPTY(allConsoles) var/emergency //If an emergency has been called by this device. Acts as both a cooldown and lets the responder know where it the emergency was triggered from var/receive_ore_updates = FALSE //If ore redemption machines will send an update when it receives new ores. max_integrity = 300 - armor = list("melee" = 70, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 70, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 0, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) /obj/machinery/requests_console/power_change() ..() update_icon() /obj/machinery/requests_console/update_icon_state() - if(CHECK_BITFIELD(stat, NOPOWER)) + if((stat & NOPOWER)) set_light(0) else set_light(1.4, 0.7, "#34D352")//green light @@ -72,7 +72,7 @@ GLOBAL_LIST_EMPTY(allConsoles) icon_state="req_comp_open" else icon_state="req_comp_rewired" - else if(CHECK_BITFIELD(stat, NOPOWER)) + else if((stat & NOPOWER)) if(icon_state != "req_comp_off") icon_state = "req_comp_off" else @@ -85,7 +85,7 @@ GLOBAL_LIST_EMPTY(allConsoles) else icon_state = "req_comp0" -/obj/machinery/requests_console/Initialize() +/obj/machinery/requests_console/Initialize(mapload) . = ..() name = "\improper [department] requests console" GLOB.allConsoles += src @@ -374,7 +374,7 @@ GLOBAL_LIST_EMPTY(allConsoles) radio_freq = FREQ_ENGINEERING if("security") radio_freq = FREQ_SECURITY - if("cargobay" || "mining") + if("cargobay", "mining") radio_freq = FREQ_SUPPLY Radio.set_frequency(radio_freq) diff --git a/code/game/machinery/sheetifier.dm b/code/game/machinery/sheetifier.dm index 7b83401194..82f15803ab 100644 --- a/code/game/machinery/sheetifier.dm +++ b/code/game/machinery/sheetifier.dm @@ -11,7 +11,7 @@ layer = BELOW_OBJ_LAYER var/busy_processing = FALSE -/obj/machinery/sheetifier/Initialize() +/obj/machinery/sheetifier/Initialize(mapload) . = ..() AddComponent(/datum/component/material_container, list(/datum/material/meat), MINERAL_MATERIAL_AMOUNT * MAX_STACK_SIZE * 2, TRUE, /obj/item/reagent_containers/food/snacks/meat/slab, CALLBACK(src, .proc/CanInsertMaterials), CALLBACK(src, .proc/AfterInsertMaterials)) diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 2ebb137839..836fcad8e8 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -11,7 +11,7 @@ max_integrity = 200 //The shield can only take so much beating (prevents perma-prisons) CanAtmosPass = ATMOS_PASS_DENSITY -/obj/structure/emergency_shield/Initialize() +/obj/structure/emergency_shield/Initialize(mapload) . = ..() setDir(pick(GLOB.cardinals)) air_update_turf(1) @@ -28,7 +28,7 @@ if(severity >= 70) qdel(src) else - take_damage(severity/1.3, BRUTE, "energy", 0) + take_damage(severity/1.3, BRUTE, ENERGY, 0) /obj/structure/emergency_shield/play_attack_sound(damage, damage_type = BRUTE, damage_flag = 0) switch(damage_type) @@ -454,11 +454,10 @@ if(gen_secondary) //using power may cause us to be destroyed gen_secondary.use_stored_power(drain_amount*0.5) -/obj/machinery/shieldwall/CanPass(atom/movable/mover, turf/target) +/obj/machinery/shieldwall/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(istype(mover) && (mover.pass_flags & PASSGLASS)) return prob(20) else if(istype(mover, /obj/item/projectile)) return prob(10) - else - return !density diff --git a/code/game/machinery/shuttle/custom_shuttle.dm b/code/game/machinery/shuttle/custom_shuttle.dm index 7c83cade69..9bf721b80c 100644 --- a/code/game/machinery/shuttle/custom_shuttle.dm +++ b/code/game/machinery/shuttle/custom_shuttle.dm @@ -12,7 +12,7 @@ var/icon_state_open = "burst_plasma_open" var/icon_state_off = "burst_plasma_off" -/obj/machinery/shuttle/Initialize() +/obj/machinery/shuttle/Initialize(mapload) . = ..() GLOB.custom_shuttle_machines += src diff --git a/code/game/machinery/shuttle/shuttle_engine.dm b/code/game/machinery/shuttle/shuttle_engine.dm index c3de384c58..d7bb93d94b 100644 --- a/code/game/machinery/shuttle/shuttle_engine.dm +++ b/code/game/machinery/shuttle/shuttle_engine.dm @@ -49,7 +49,7 @@ bluespace_capable = TRUE cooldown = 90 -/obj/machinery/shuttle/engine/Initialize() +/obj/machinery/shuttle/engine/Initialize(mapload) . = ..() check_setup() diff --git a/code/game/machinery/shuttle/shuttle_heater.dm b/code/game/machinery/shuttle/shuttle_heater.dm index 8f7b772072..31fcabffda 100644 --- a/code/game/machinery/shuttle/shuttle_heater.dm +++ b/code/game/machinery/shuttle/shuttle_heater.dm @@ -22,7 +22,7 @@ density = TRUE max_integrity = 400 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 100, ACID = 30) layer = OBJ_LAYER showpipe = TRUE diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm index 1fadad168e..4fa6476176 100644 --- a/code/game/machinery/slotmachine.dm +++ b/code/game/machinery/slotmachine.dm @@ -31,12 +31,11 @@ var/jackpots = 0 var/paymode = HOLOCHIP //toggles between HOLOCHIP/COIN, defined above var/cointype = /obj/item/coin/iron //default cointype - var/list/coinvalues = list() var/list/reels = list(list("", "", "") = 0, list("", "", "") = 0, list("", "", "") = 0, list("", "", "") = 0, list("", "", "") = 0) var/list/symbols = list(SEVEN = 1, "&" = 2, "@" = 2, "$" = 2, "?" = 2, "#" = 2, "!" = 2, "%" = 2) //if people are winning too much, multiply every number in this list by 2 and see if they are still winning too much. -/obj/machinery/computer/slot_machine/Initialize() +/obj/machinery/computer/slot_machine/Initialize(mapload) . = ..() jackpots = rand(1, 4) //false hope plays = rand(75, 200) @@ -49,11 +48,6 @@ INVOKE_ASYNC(src, .proc/toggle_reel_spin, FALSE) - for(cointype in typesof(/obj/item/coin)) - var/obj/item/coin/C = new cointype - coinvalues["[cointype]"] = C.get_item_credit_value() - qdel(C) //Sigh - /obj/machinery/computer/slot_machine/Destroy() if(balance) give_payout(balance) @@ -336,7 +330,7 @@ if(throwit && target) H.throw_at(target, 3, 10) else - var/value = coinvalues["[cointype]"] + var/value = GLOB.coin_values[cointype] if(value <= 0) CRASH("Coin value of zero, refusing to payout in dispenser") while(amount >= value) diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index 0a529cd395..93b85bb45b 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -6,12 +6,13 @@ anchored = FALSE density = TRUE interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN + use_power = NO_POWER_USE icon = 'icons/obj/atmos.dmi' icon_state = "sheater-off" name = "space heater" desc = "Made by Space Amish using traditional space techniques, this heater/cooler is guaranteed not to set the station on fire. Warranty void if used in engines." max_integrity = 250 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 100, FIRE = 80, ACID = 10) circuit = /obj/item/circuitboard/machine/space_heater var/obj/item/stock_parts/cell/cell var/on = FALSE @@ -27,7 +28,7 @@ /obj/machinery/space_heater/get_cell() return cell -/obj/machinery/space_heater/Initialize() +/obj/machinery/space_heater/Initialize(mapload) . = ..() cell = new(src) update_icon() @@ -72,7 +73,7 @@ on = FALSE return PROCESS_KILL - if(cell && cell.charge > 0) + if(cell && cell.charge > 1 / efficiency) var/turf/L = loc PerformHeating(L) @@ -112,7 +113,9 @@ var/requiredPower = abs(env.return_temperature() - targetTemperature) * heat_capacity requiredPower = min(requiredPower, heatingPower) - if(requiredPower < 1) + if(requiredPower < 1 || !cell.use(requiredPower / efficiency)) + on = FALSE + update_icon() return var/deltaTemperature = requiredPower / heat_capacity @@ -121,7 +124,6 @@ if(deltaTemperature) env.set_temperature(env.return_temperature() + deltaTemperature) air_update_turf() - cell.use(requiredPower / efficiency) /obj/machinery/space_heater/RefreshParts() var/laser = 2 @@ -220,7 +222,7 @@ usr.visible_message("[usr] switches [on ? "on" : "off"] \the [src].", "You switch [on ? "on" : "off"] \the [src].") update_icon() if (on) - SSair.atmos_air_machinery += src + SSair.atmos_machinery += src . = TRUE if("mode") setMode = params["mode"] diff --git a/code/game/machinery/stasis.dm b/code/game/machinery/stasis.dm new file mode 100644 index 0000000000..406da6c3b5 --- /dev/null +++ b/code/game/machinery/stasis.dm @@ -0,0 +1,153 @@ +#define STASIS_TOGGLE_COOLDOWN 50 +/obj/machinery/stasis + name = "lifeform stasis unit" + desc = "A not so comfortable looking bed with some nozzles at the top and bottom. It will keep someone in stasis." + icon = 'icons/obj/machines/stasis.dmi' + icon_state = "stasis" + base_icon_state = "stasis" + density = FALSE + // obj_flags = NO_BUILD + can_buckle = TRUE + buckle_lying = 90 + circuit = /obj/item/circuitboard/machine/stasis + idle_power_usage = 40 + active_power_usage = 340 + fair_market_price = 10 + payment_department = ACCOUNT_MED + var/stasis_enabled = TRUE + var/last_stasis_sound = FALSE + COOLDOWN_DECLARE(stasis_can_toggle) + var/mattress_state = "stasis_on" + var/obj/effect/overlay/vis/mattress_on + +/obj/machinery/stasis/examine(mob/user) + . = ..() + . += span_notice("Alt-click to [stasis_enabled ? "turn off" : "turn on"] the machine.") + +/obj/machinery/stasis/proc/play_power_sound() + var/_running = stasis_running() + if(last_stasis_sound != _running) + var/sound_freq = rand(5120, 8800) + if(_running) + playsound(src, 'sound/machines/synth_yes.ogg', 50, TRUE, frequency = sound_freq) + else + playsound(src, 'sound/machines/synth_no.ogg', 50, TRUE, frequency = sound_freq) + last_stasis_sound = _running + +/obj/machinery/stasis/AltClick(mob/user) + . = ..() + if(!can_interact(user)) + return + if(COOLDOWN_FINISHED(src, stasis_can_toggle) && user.canUseTopic(src, !issilicon(user))) + stasis_enabled = !stasis_enabled + COOLDOWN_START(src, stasis_can_toggle, STASIS_TOGGLE_COOLDOWN) + playsound(src, 'sound/machines/click.ogg', 60, TRUE) + user.visible_message(span_notice("\The [src] [stasis_enabled ? "powers on" : "shuts down"]."), \ + span_notice("You [stasis_enabled ? "power on" : "shut down"] \the [src]."), \ + span_hear("You hear a nearby machine [stasis_enabled ? "power on" : "shut down"].")) + play_power_sound() + update_appearance() + +/obj/machinery/stasis/Exited(atom/movable/gone, atom/newloc) + if(gone == occupant) + var/mob/living/L = gone + if(IS_IN_STASIS(L)) + thaw_them(L) + return ..() + +/obj/machinery/stasis/proc/stasis_running() + return stasis_enabled && is_operational() + +/obj/machinery/stasis/update_icon_state() + if(stat & BROKEN) + icon_state = "[base_icon_state]_broken" + return ..() + if(panel_open || stat & MAINT) + icon_state = "[base_icon_state]_maintenance" + return ..() + icon_state = base_icon_state + return ..() + +/obj/machinery/stasis/update_overlays() + . = ..() + if(!mattress_state) + return + var/_running = stasis_running() + if(!mattress_on) + mattress_on = SSvis_overlays.add_vis_overlay(src, icon, mattress_state, BELOW_OBJ_LAYER, plane, dir, alpha = 0, unique = TRUE) + else + vis_contents += mattress_on + if(managed_vis_overlays) + managed_vis_overlays += mattress_on + else + managed_vis_overlays = list(mattress_on) + + if(mattress_on.alpha ? !_running : _running) //check the inverse of _running compared to truthy alpha, to see if they differ + var/new_alpha = _running ? 255 : 0 + var/easing_direction = _running ? EASE_OUT : EASE_IN + animate(mattress_on, alpha = new_alpha, time = 50, easing = CUBIC_EASING|easing_direction) + +/obj/machinery/stasis/obj_break(damage_flag) + . = ..() + if(.) + play_power_sound() + +/obj/machinery/stasis/power_change() + . = ..() + if(.) + play_power_sound() + +/obj/machinery/stasis/proc/chill_out(mob/living/target) + if(target != occupant) + return + var/freq = rand(24750, 26550) + playsound(src, 'sound/effects/spray.ogg', 5, TRUE, 2, frequency = freq) + target.apply_status_effect(/datum/status_effect/grouped/stasis, STASIS_MACHINE_EFFECT) + // ADD_TRAIT(target, TRAIT_TUMOR_SUPPRESSED, TRAIT_GENERIC) + target.ExtinguishMob() + use_power = ACTIVE_POWER_USE + +/obj/machinery/stasis/proc/thaw_them(mob/living/target) + target.remove_status_effect(/datum/status_effect/grouped/stasis, STASIS_MACHINE_EFFECT) + // REMOVE_TRAIT(target, TRAIT_TUMOR_SUPPRESSED, TRAIT_GENERIC) + if(target == occupant) + use_power = IDLE_POWER_USE + +/obj/machinery/stasis/post_buckle_mob(mob/living/L) + if(!can_be_occupant(L)) + return + occupant = L + if(stasis_running() && check_nap_violations()) + chill_out(L) + update_appearance() + +/obj/machinery/stasis/post_unbuckle_mob(mob/living/L) + thaw_them(L) + if(L == occupant) + occupant = null + update_appearance() + +/obj/machinery/stasis/process() + if(!(occupant && isliving(occupant) && check_nap_violations())) + use_power = IDLE_POWER_USE + return + var/mob/living/L_occupant = occupant + if(stasis_running()) + if(!IS_IN_STASIS(L_occupant)) + chill_out(L_occupant) + else if(IS_IN_STASIS(L_occupant)) + thaw_them(L_occupant) + +/obj/machinery/stasis/screwdriver_act(mob/living/user, obj/item/I) + . = ..() + . |= default_deconstruction_screwdriver(user, "[base_icon_state]_maintenance", "[base_icon_state]", I) + update_appearance() + +/obj/machinery/stasis/crowbar_act(mob/living/user, obj/item/I) + . = ..() + return default_deconstruction_crowbar(I) || . + +/obj/machinery/stasis/nap_violation(mob/violator) + unbuckle_mob(violator, TRUE) + +#undef STASIS_TOGGLE_COOLDOWN diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index 8937106601..c550f72946 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -4,102 +4,192 @@ #define CHARS_PER_LINE 5 #define FONT_SIZE "5pt" #define FONT_COLOR "#09f" -#define FONT_STYLE "Arial Black" -#define SCROLL_SPEED 2 +#define FONT_STYLE "Small Fonts" +#define SCROLL_RATE (0.04 SECONDS) // time per pixel +#define LINE1_Y -8 +#define LINE2_Y -15 #define SD_BLANK 0 // 0 = Blank #define SD_EMERGENCY 1 // 1 = Emergency Shuttle timer #define SD_MESSAGE 2 // 2 = Arbitrary message(s) #define SD_PICTURE 3 // 3 = alert picture -#define SD_AI_EMOTE 1 // 1 = AI emoticon -#define SD_AI_BSOD 2 // 2 = Blue screen of death - -/// Status display which can show images and scrolling text. !!!USE /obj/machinery/status_display/evac NOT THIS!!! +/// Status display which can show images and scrolling text. /obj/machinery/status_display name = "status display" desc = null icon = 'icons/obj/status_display.dmi' icon_state = "frame" - plane = ABOVE_WALL_PLANE + base_icon_state = "unanchoredstatusdisplay" + verb_say = "beeps" + verb_ask = "beeps" + verb_exclaim = "beeps" density = FALSE - use_power = IDLE_POWER_USE - idle_power_usage = 10 + layer = ABOVE_WINDOW_LAYER - maptext_height = 26 - maptext_width = 32 + var/obj/effect/overlay/status_display_text/message1_overlay + var/obj/effect/overlay/status_display_text/message2_overlay + var/mutable_appearance/ai_vtuber_overlay + var/current_picture = "" + var/current_mode = SD_BLANK + var/message1 = "" + var/message2 = "" + var/mob/living/silicon/ai/master - var/message1 = "" // message line 1 - var/message2 = "" // message line 2 - var/index1 // display index for scrolling messages or 0 if non-scrolling - var/index2 +/obj/item/wallframe/status_display + name = "status display frame" + desc = "Used to build status displays, just secure to the wall." + icon_state = "unanchoredstatusdisplay" + custom_materials = list(/datum/material/iron=14000, /datum/material/glass=8000) + result_path = /obj/machinery/status_display/evac + pixel_shift = -32 -/// Immediately blank the display. -/obj/machinery/status_display/proc/remove_display() - cut_overlays() - if(maptext) - maptext = "" +/obj/machinery/status_display/wrench_act(mob/living/user, obj/item/tool) + . = ..() + balloon_alert(user, "[anchored ? "un" : ""]securing...") + tool.play_tool_sound(src) + if(tool.use_tool(src, user, 6 SECONDS)) + playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE) + balloon_alert(user, "[anchored ? "un" : ""]secured") + deconstruct() + return TRUE + +/obj/machinery/status_display/welder_act(mob/living/user, obj/item/tool) + if(user.a_intent == INTENT_HARM) + return + if(obj_integrity >= max_integrity) + balloon_alert(user, "it doesn't need repairs!") + return TRUE + user.balloon_alert_to_viewers("repairing display...", "repairing...") + if(!tool.use_tool(src, user, 4 SECONDS, amount = 0, volume=50)) + return TRUE + balloon_alert(user, "repaired") + obj_integrity = max_integrity + set_machine_stat(stat & ~BROKEN) + update_appearance() + return TRUE + +/obj/machinery/status_display/deconstruct(disassembled = TRUE) + if(flags_1 & NODECONSTRUCT_1) + return + if(!disassembled) + new /obj/item/stack/sheet/metal(drop_location(), 2) + new /obj/item/shard(drop_location()) + new /obj/item/shard(drop_location()) + else + new /obj/item/wallframe/status_display(drop_location()) + qdel(src) /// Immediately change the display to the given picture. /obj/machinery/status_display/proc/set_picture(state) - remove_display() - add_overlay(state) + if(state != current_picture) + current_picture = state + + update_appearance() /// Immediately change the display to the given two lines. -/obj/machinery/status_display/proc/update_display(line1, line2) - var/new_text = {"
    [line1]
    [line2]
    "} - if(maptext != new_text) - maptext = new_text +/obj/machinery/status_display/proc/set_messages(line1, line2) + line1 = uppertext(line1) + line2 = uppertext(line2) -/// Prepare the display to marquee the given two lines. -/// -/// Call with no arguments to disable. -/obj/machinery/status_display/proc/set_message(m1, m2) - if(m1) - index1 = (length_char(m1) > CHARS_PER_LINE) - message1 = m1 - else - message1 = "" - index1 = 0 + if(line1 != message1) + message1 = line1 - if(m2) - index2 = (length_char(m2) > CHARS_PER_LINE) - message2 = m2 - else - message2 = "" - index2 = 0 + if(line2 != message2) + message2 = line2 -// Timed process - performs default marquee action if so needed. + update_appearance() + +/** + * Remove both message objs and null the fields. + * Don't call this in subclasses. + */ +/obj/machinery/status_display/proc/remove_messages() + if(message1_overlay) + QDEL_NULL(message1_overlay) + if(message2_overlay) + QDEL_NULL(message2_overlay) + +/** + * Create/update message overlay. + * They must be handled as real objects for the animation to run. + * Don't call this in subclasses. + * Arguments: + * * overlay - the current /obj/effect/overlay/status_display_text instance + * * line_y - The Y offset to render the text. + * * message - the new message text. + * Returns new /obj/effect/overlay/status_display_text or null if unchanged. + */ +/obj/machinery/status_display/proc/update_message(obj/effect/overlay/status_display_text/overlay, line_y, message) + if(overlay && message == overlay.message) + return null + + // if an AI is controlling, we don't update the overlay + if(master) + return + + if(overlay) + qdel(overlay) + + var/obj/effect/overlay/status_display_text/new_status_display_text = new(src, line_y, message) + vis_contents += new_status_display_text + return new_status_display_text + +/obj/machinery/status_display/update_appearance(updates=ALL) + . = ..() + if( \ + (stat & (NOPOWER|BROKEN)) || \ + (current_mode == SD_BLANK) || \ + (current_mode != SD_PICTURE && message1 == "" && message2 == "") \ + ) + set_light(0) + return + set_light(1.4, 0.7, LIGHT_COLOR_BLUE) // blue light + +/obj/machinery/status_display/update_overlays() + . = ..() + + if(stat & (NOPOWER|BROKEN)) + remove_messages() + return + + if(master) + remove_messages() + return + + switch(current_mode) + if(SD_BLANK) + remove_messages() + // Turn off backlight. + return + if(SD_PICTURE) + remove_messages() + . += mutable_appearance(icon, current_picture) + else + var/overlay = update_message(message1_overlay, LINE1_Y, message1) + if(overlay) + message1_overlay = overlay + overlay = update_message(message2_overlay, LINE2_Y, message2) + if(overlay) + message2_overlay = overlay + + // Turn off backlight if message is blank + if(message1 == "" && message2 == "") + return + + . += emissive_appearance(icon, "outline", alpha = src.alpha) + +// Timed process - performs nothing in the base class /obj/machinery/status_display/process() if(stat & NOPOWER) // No power, no processing. - remove_display() - return PROCESS_KILL + update_appearance() - var/line1 = message1 - if(index1) - line1 = copytext_char("[message1]|[message1]", index1, index1+CHARS_PER_LINE) - var/message1_len = length_char(message1) - index1 += SCROLL_SPEED - if(index1 > message1_len + 1) - index1 -= (message1_len + 1) - - var/line2 = message2 - if(index2) - line2 = copytext_char("[message2]|[message2]", index2, index2+CHARS_PER_LINE) - var/message2_len = length(message2) - index2 += SCROLL_SPEED - if(index2 > message2_len + 1) - index2 -= (message2_len + 1) - - update_display(line1, line2) - if (!index1 && !index2) - // No marquee, no processing. - return PROCESS_KILL + return PROCESS_KILL /// Update the display and, if necessary, re-enable processing. /obj/machinery/status_display/proc/update() - if (process() != PROCESS_KILL) + if (process(SSMACHINES_DT) != PROCESS_KILL) START_PROCESSING(SSmachines, src) /obj/machinery/status_display/power_change() @@ -110,22 +200,23 @@ . = ..() if(stat & (NOPOWER|BROKEN) || . & EMP_PROTECT_SELF) return + current_mode = SD_PICTURE set_picture("ai_bsod") /obj/machinery/status_display/examine(mob/user) . = ..() - if (message1 || message2) + if (current_mode == SD_MESSAGE && (message1_overlay?.message || message2_overlay?.message)) . += "The display says:" - if (message1) - . += "\t[html_encode(message1)]" - if (message2) - . += "\t[html_encode(message2)]" + if (message1_overlay.message) + . += "\t[html_encode(message1_overlay.message)]" + if (message2_overlay.message) + . += "\t[html_encode(message2_overlay.message)]" // Helper procs for child display types. /obj/machinery/status_display/proc/display_shuttle_status(obj/docking_port/mobile/shuttle) if(!shuttle) // the shuttle is missing - no processing - update_display("shutl?","") + set_messages("shutl?","") return PROCESS_KILL else if(shuttle.timer) var/line1 = "-[shuttle.getModeStr()]-" @@ -133,10 +224,10 @@ if(length_char(line2) > CHARS_PER_LINE) line2 = "error" - update_display(line1, line2) + set_messages(line1, line2) else // don't kill processing, the timer might turn back on - remove_display() + set_messages("", "") /obj/machinery/status_display/proc/examine_shuttle(mob/user, obj/docking_port/mobile/shuttle) if (shuttle) @@ -150,18 +241,82 @@ else return "The display says:
    \tShuttle missing!" +/obj/machinery/status_display/Destroy() + remove_messages() + return ..() + +/** + * Nice overlay to make text smoothly scroll with no client updates after setup. + */ +/obj/effect/overlay/status_display_text + icon = 'icons/obj/status_display.dmi' + vis_flags = VIS_INHERIT_LAYER | VIS_INHERIT_PLANE | VIS_INHERIT_ID + + var/message + +/obj/effect/overlay/status_display_text/Initialize(mapload, yoffset, line) + . = ..() + + maptext_y = yoffset + message = line + + var/line_length = length_char(line) + + if(line_length > CHARS_PER_LINE) + // Marquee text + var/marquee_message = "[line] • [line] • [line]" + var/marquee_length = line_length * 3 + 6 + maptext = generate_text(marquee_message, center = FALSE) + maptext_width = 6 * marquee_length + maptext_x = 32 + + // Mask off to fit in screen. + add_filter("mask", 1, alpha_mask_filter(icon = icon(icon, "outline"))) + + // Scroll. + var/width = 4 * marquee_length + var/time = (width + 32) * SCROLL_RATE + animate(src, maptext_x = -width, time = time, loop = -1) + animate(maptext_x = 32, time = 0) + else + // Centered text + maptext = generate_text(line, center = TRUE) + maptext_x = 0 + +/obj/effect/overlay/status_display_text/proc/generate_text(text, center) + return {"
    [text]
    "} /// Evac display which shows shuttle timer or message set by Command. /obj/machinery/status_display/evac + current_mode = SD_EMERGENCY var/frequency = FREQ_STATUS_DISPLAYS - var/mode = SD_EMERGENCY var/friendc = FALSE // track if Friend Computer mode var/last_picture // For when Friend Computer mode is undone -/obj/machinery/status_display/evac/Initialize() +// MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/evac, 32) + +//makes it go on the wall when built +/obj/machinery/status_display/Initialize(mapload, ndir, building) + . = ..() + update_appearance() + register_context() + +/obj/machinery/status_display/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + if(isAI(user)) + LAZYSET(context[SCREENTIP_CONTEXT_CTRL_LMB], INTENT_ANY, "Start streaming") // funny + return CONTEXTUAL_SCREENTIP_SET + +/obj/machinery/status_display/evac/Initialize(mapload) . = ..() // register for radio system SSradio.add_object(src, frequency) + // Circuit USB + /* + AddComponent(/datum/component/usb_port, list( + /obj/item/circuit_component/status_display, + )) + */ /obj/machinery/status_display/evac/Destroy() SSradio.remove_object(src,frequency) @@ -170,23 +325,23 @@ /obj/machinery/status_display/evac/process() if(stat & NOPOWER) // No power, no processing. - remove_display() + update_appearance() return PROCESS_KILL if(friendc) //Makes all status displays except supply shuttle timer display the eye -- Urist + current_mode = SD_PICTURE set_picture("ai_friend") return PROCESS_KILL - switch(mode) + switch(current_mode) if(SD_BLANK) - remove_display() return PROCESS_KILL if(SD_EMERGENCY) return display_shuttle_status(SSshuttle.emergency) if(SD_MESSAGE) - return ..() + return PROCESS_KILL if(SD_PICTURE) set_picture(last_picture) @@ -194,7 +349,7 @@ /obj/machinery/status_display/evac/examine(mob/user) . = ..() - if(mode == SD_EMERGENCY) + if(current_mode == SD_EMERGENCY) . += examine_shuttle(user, SSshuttle.emergency) else if(!message1 && !message2) . += "The display is blank." @@ -202,16 +357,16 @@ /obj/machinery/status_display/evac/receive_signal(datum/signal/signal) switch(signal.data["command"]) if("blank") - mode = SD_BLANK - set_message(null, null) + current_mode = SD_BLANK + update_appearance() if("shuttle") - mode = SD_EMERGENCY - set_message(null, null) + current_mode = SD_EMERGENCY + set_messages("", "") if("message") - mode = SD_MESSAGE - set_message(signal.data["msg1"], signal.data["msg2"]) + current_mode = SD_MESSAGE + set_messages(signal.data["msg1"] || "", signal.data["msg2"] || "") if("alert") - mode = SD_PICTURE + current_mode = SD_PICTURE last_picture = signal.data["picture_state"] set_picture(last_picture) if("friendcomputer") @@ -222,11 +377,12 @@ /// Supply display which shows the status of the supply shuttle. /obj/machinery/status_display/supply name = "supply display" + current_mode = SD_MESSAGE /obj/machinery/status_display/supply/process() if(stat & NOPOWER) // No power, no processing. - remove_display() + update_appearance() return PROCESS_KILL var/line1 @@ -240,12 +396,15 @@ if(is_station_level(SSshuttle.supply.z)) line1 = "CARGO" line2 = "Docked" + else + line1 = "" + line2 = "" else line1 = "CARGO" line2 = SSshuttle.supply.getTimerStr() if(length_char(line2) > CHARS_PER_LINE) line2 = "Error" - update_display(line1, line2) + set_messages(line1, line2) /obj/machinery/status_display/supply/examine(mob/user) . = ..() @@ -265,12 +424,13 @@ /// General-purpose shuttle status display. /obj/machinery/status_display/shuttle name = "shuttle display" + current_mode = SD_MESSAGE var/shuttle_id /obj/machinery/status_display/shuttle/process() if(!shuttle_id || (stat & NOPOWER)) // No power, no processing. - remove_display() + update_appearance() return PROCESS_KILL return display_shuttle_status(SSshuttle.getShuttle(shuttle_id)) @@ -291,7 +451,7 @@ update() /obj/machinery/status_display/shuttle/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override) - if (port && (shuttle_id == initial(shuttle_id) || override)) + if(port && (shuttle_id == initial(shuttle_id) || override)) shuttle_id = port.id update() @@ -300,11 +460,34 @@ /obj/machinery/status_display/ai name = "\improper AI display" desc = "A small screen which the AI can use to present itself." + current_mode = SD_PICTURE - var/mode = SD_BLANK - var/emotion = "Neutral" + var/emotion = AI_EMOTION_BLANK -/obj/machinery/status_display/ai/Initialize() + /// A mapping between AI_EMOTION_* string constants, which also double as user readable descriptions, and the name of the iconfile. + var/static/list/emotion_map = list( + AI_EMOTION_BLANK = "ai_off", + AI_EMOTION_VERY_HAPPY = "ai_veryhappy", + AI_EMOTION_HAPPY = "ai_happy", + AI_EMOTION_NEUTRAL = "ai_neutral", + AI_EMOTION_UNSURE = "ai_unsure", + AI_EMOTION_CONFUSED = "ai_confused", + AI_EMOTION_SAD = "ai_sad", + AI_EMOTION_BSOD = "ai_bsod", + AI_EMOTION_PROBLEMS = "ai_trollface", + AI_EMOTION_AWESOME = "ai_awesome", + AI_EMOTION_DORFY = "ai_urist", + AI_EMOTION_THINKING = "ai_thinking", + AI_EMOTION_FACEPALM = "ai_facepalm", + AI_EMOTION_FRIEND_COMPUTER = "ai_friend", + AI_EMOTION_BLUE_GLOW = "ai_sal", + AI_EMOTION_RED_GLOW = "ai_hal", + ) + + +// MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/ai, 32) + +/obj/machinery/status_display/ai/Initialize(mapload) . = ..() GLOB.ai_status_displays.Add(src) @@ -313,57 +496,145 @@ . = ..() /obj/machinery/status_display/ai/attack_ai(mob/living/silicon/ai/user) - if(isAI(user)) - user.ai_statuschange() + if(!isAI(user)) + return + var/list/choices = list() + for(var/emotion_const in emotion_map) + var/icon_state = emotion_map[emotion_const] + choices[emotion_const] = image(icon = 'icons/obj/status_display.dmi', icon_state = icon_state) + + var/emotion_result = show_radial_menu(user, src, choices, tooltips = TRUE) + for(var/_emote in typesof(/datum/emote/ai/emotion_display)) + var/datum/emote/ai/emotion_display/emote = _emote + if(initial(emote.emotion) == emotion_result) + user.emote(initial(emote.key)) + break + +// ai vtuber moment +/obj/machinery/status_display/AICtrlClick(mob/living/silicon/ai/user) + if(!isAI(user) || master || (user.current && !istype(user.current, /obj/machinery/status_display))) // don't let two AIs control the same one, don't let AI control two things at once + return + + if(!user.client.prefs.custom_holoform_icon) + to_chat(user, span_notice("You have no custom holoform set!")) + return + + // move AI to the location, set master, update overlays (removes messages) + user.current = src + user.eyeobj.setLoc(get_turf(src)) + icon_state = initial(icon_state) + user.controlled_display = src + master = user + update_overlays() + update_appearance() + + // we set the avatar here + var/icon/I = icon(user.client.prefs.custom_holoform_icon) + I.Crop(1,16,32,32) + ai_vtuber_overlay = mutable_appearance(I) + ai_vtuber_overlay.blend_mode = BLEND_ADD + ai_vtuber_overlay.pixel_y = 8 + update_overlays() + add_overlay(ai_vtuber_overlay) + + // tell the user how to speak + to_chat(user, span_notice("Use :q to relay messages through the status display.")) + +// modified version of how holopads 'hear' and relay to AIs +/obj/machinery/status_display/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods = list()) + . = ..() + if(master && !radio_freq && master.controlled_display == src) + master.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans, message_mods) /obj/machinery/status_display/ai/process() - if(mode == SD_BLANK || (stat & NOPOWER)) - remove_display() + if(stat & NOPOWER) + update_appearance() return PROCESS_KILL - if(mode == SD_AI_EMOTE) - switch(emotion) - if("Very Happy") - set_picture("ai_veryhappy") - if("Happy") - set_picture("ai_happy") - if("Neutral") - set_picture("ai_neutral") - if("Unsure") - set_picture("ai_unsure") - if("Confused") - set_picture("ai_confused") - if("Sad") - set_picture("ai_sad") - if("BSOD") - set_picture("ai_bsod") - if("Blank") - set_picture("ai_off") - if("Problems?") - set_picture("ai_trollface") - if("Awesome") - set_picture("ai_awesome") - if("Dorfy") - set_picture("ai_urist") - if("Thinking") - set_picture("ai_thinking") - if("Facepalm") - set_picture("ai_facepalm") - if("Friend Computer") - set_picture("ai_friend") - if("Blue Glow") - set_picture("ai_sal") - if("Red Glow") - set_picture("ai_hal") - return PROCESS_KILL + set_picture(emotion_map[emotion]) + return PROCESS_KILL - if(mode == SD_AI_BSOD) - set_picture("ai_bsod") - return PROCESS_KILL +/* +/obj/item/circuit_component/status_display + display_name = "Status Display" + desc = "Output text and pictures to a status display." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + var/datum/port/input/option/command + var/datum/port/input/option/picture + var/datum/port/input/message1 + var/datum/port/input/message2 + + var/obj/machinery/status_display/connected_display + + var/list/command_map + var/list/picture_map + +/obj/item/circuit_component/status_display/populate_ports() + message1 = add_input_port("Message 1", PORT_TYPE_STRING) + message2 = add_input_port("Message 2", PORT_TYPE_STRING) + +/obj/item/circuit_component/status_display/populate_options() + var/static/list/command_options = list( + "Blank" = "blank", + "Shuttle" = "shuttle", + "Message" = "message", + "Alert" = "alert" + ) + + var/static/list/picture_options = list( + "Default" = "default", + "Red Alert" = "redalert", + "Biohazard" = "biohazard", + "Lockdown" = "lockdown", + "Happy" = "ai_happy", + "Neutral" = "ai_neutral", + "Very Happy" = "ai_veryhappy", + "Sad" = "ai_sad", + "Unsure" = "ai_unsure", + "Confused" = "ai_confused", + "Surprised" = "ai_surprised", + "BSOD" = "ai_bsod" + ) + + command = add_option_port("Command", command_options) + command_map = command_options + + picture = add_option_port("Picture", picture_options) + picture_map = picture_options + +/obj/item/circuit_component/status_display/register_usb_parent(atom/movable/shell) + . = ..() + if(istype(shell, /obj/machinery/status_display)) + connected_display = shell + +/obj/item/circuit_component/status_display/unregister_usb_parent(atom/movable/parent) + connected_display = null + return ..() + +/obj/item/circuit_component/status_display/input_received(datum/port/input/port) + // Just use command handling built into status display. + // The option inputs thankfully sanitize command and picture for us. + + if(!connected_display) + return + + var/command_value = command_map[command.value] + var/datum/signal/status_signal = new(list("command" = command_value)) + switch(command_value) + if("message") + status_signal.data["msg1"] = message1.value + status_signal.data["msg2"] = message2.value + if("alert") + status_signal.data["picture_state"] = picture_map[picture.value] + + connected_display.receive_signal(status_signal) +*/ #undef CHARS_PER_LINE #undef FONT_SIZE #undef FONT_COLOR #undef FONT_STYLE -#undef SCROLL_SPEED +#undef SCROLL_RATE +#undef LINE1_Y +#undef LINE2_Y diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index cecf351ea9..ca57e8457a 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -10,11 +10,15 @@ var/obj/item/clothing/suit/space/suit = null var/obj/item/clothing/head/helmet/space/helmet = null var/obj/item/clothing/mask/mask = null + var/obj/item/mod/control/mod = null var/obj/item/storage = null var/suit_type = null var/helmet_type = null var/mask_type = null + /// What type of MOD the unit starts with when spawned. + var/mod_type = null + /// What type of additional item the unit starts with when spawned. var/storage_type = null state_open = FALSE @@ -27,6 +31,8 @@ var/uv_cycles = 6 var/message_cooldown var/breakout_time = 300 + /// How fast it charges cells in a suit + var/charge_rate = 250 /obj/machinery/suit_storage_unit/standard_unit suit_type = /obj/item/clothing/suit/space/eva @@ -38,21 +44,50 @@ mask_type = /obj/item/clothing/mask/gas/sechailer storage_type = /obj/item/tank/jetpack/oxygen/captain +/obj/machinery/suit_storage_unit/captainmod + mask_type = /obj/item/clothing/mask/gas/sechailer + storage_type = /obj/item/tank/jetpack/oxygen/captain + mod_type = /obj/item/mod/control/pre_equipped/magnate + /obj/machinery/suit_storage_unit/engine suit_type = /obj/item/clothing/suit/space/hardsuit/engine mask_type = /obj/item/clothing/mask/breath storage_type= /obj/item/clothing/shoes/magboots +/obj/machinery/suit_storage_unit/enginemod + mask_type = /obj/item/clothing/mask/breath + mod_type = /obj/item/mod/control/pre_equipped/engineering + +/obj/machinery/suit_storage_unit/atmos + suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos + mask_type = /obj/item/clothing/mask/breath + storage_type = /obj/item/watertank/atmos + +/obj/machinery/suit_storage_unit/atmosmod + mask_type = /obj/item/clothing/mask/breath + storage_type = /obj/item/watertank/atmos + mod_type = /obj/item/mod/control/pre_equipped/atmospheric + /obj/machinery/suit_storage_unit/ce suit_type = /obj/item/clothing/suit/space/hardsuit/engine/elite mask_type = /obj/item/clothing/mask/breath storage_type= /obj/item/clothing/shoes/magboots/advance +/obj/machinery/suit_storage_unit/cemod + mask_type = /obj/item/clothing/mask/breath + storage_type = /obj/item/clothing/shoes/magboots/advance + mod_type = /obj/item/mod/control/pre_equipped/advanced + /obj/machinery/suit_storage_unit/security suit_type = /obj/item/clothing/suit/space/hardsuit/security mask_type = /obj/item/clothing/mask/gas/sechailer storage_type = /obj/item/tank/jetpack/oxygen/security +/obj/machinery/suit_storage_unit/securitymod + mask_type = /obj/item/clothing/mask/gas/sechailer + mod_type = /obj/item/mod/control/pre_equipped/security + + /obj/machinery/suit_storage_unit/hos suit_type = /obj/item/clothing/suit/space/hardsuit/security/hos mask_type = /obj/item/clothing/mask/gas/sechailer @@ -63,6 +98,11 @@ mask_type = /obj/item/clothing/mask/gas storage_type = /obj/item/watertank/atmos +/obj/machinery/suit_storage_unit/hosmod + mask_type = /obj/item/clothing/mask/gas/sechailer + storage_type = /obj/item/tank/internals/oxygen + mod_type = /obj/item/mod/control/pre_equipped/safeguard + /obj/machinery/suit_storage_unit/mining suit_type = /obj/item/clothing/suit/hooded/explorer/standard mask_type = /obj/item/clothing/mask/gas/explorer @@ -71,6 +111,16 @@ suit_type = /obj/item/clothing/suit/space/hardsuit/mining mask_type = /obj/item/clothing/mask/breath +/obj/machinery/suit_storage_unit/mining/evahos + suit_type = null + mask_type = /obj/item/clothing/mask/breath + mod_type = /obj/item/mod/control/pre_equipped/mining + +/obj/machinery/suit_storage_unit/medicalmod + mask_type = /obj/item/clothing/mask/breath/medical + storage_type = /obj/item/tank/internals/oxygen + mod_type = /obj/item/mod/control/pre_equipped/medical + /obj/machinery/suit_storage_unit/cmo suit_type = /obj/item/clothing/suit/space/hardsuit/medical mask_type = /obj/item/clothing/mask/breath @@ -81,15 +131,29 @@ helmet_type = /obj/item/clothing/head/helmet/space/eva/paramedic mask_type = /obj/item/clothing/mask/breath +/obj/machinery/suit_storage_unit/cmomod + mask_type = /obj/item/clothing/mask/breath/medical + storage_type = /obj/item/tank/internals/oxygen + mod_type = /obj/item/mod/control/pre_equipped/rescue + /obj/machinery/suit_storage_unit/rd suit_type = /obj/item/clothing/suit/space/hardsuit/rd mask_type = /obj/item/clothing/mask/breath +/obj/machinery/suit_storage_unit/rdmod + mask_type = /obj/item/clothing/mask/breath + mod_type = /obj/item/mod/control/pre_equipped/research + /obj/machinery/suit_storage_unit/syndicate suit_type = /obj/item/clothing/suit/space/hardsuit/syndi mask_type = /obj/item/clothing/mask/gas/syndicate storage_type = /obj/item/tank/jetpack/oxygen/harness +/obj/machinery/suit_storage_unit/syndicatemod + mask_type = /obj/item/clothing/mask/gas/syndicate + storage_type = /obj/item/tank/jetpack/oxygen/harness + mod_type = /obj/item/mod/control/pre_equipped/nuclear + /obj/machinery/suit_storage_unit/ert/command suit_type = /obj/item/clothing/suit/space/hardsuit/ert mask_type = /obj/item/clothing/mask/breath @@ -120,7 +184,7 @@ state_open = TRUE density = FALSE -/obj/machinery/suit_storage_unit/Initialize() +/obj/machinery/suit_storage_unit/Initialize(mapload) . = ..() wires = new /datum/wires/suit_storage_unit(src) if(suit_type) @@ -129,6 +193,8 @@ helmet = new helmet_type(src) if(mask_type) mask = new mask_type(src) + if(mod_type) + mod = new mod_type(src) if(storage_type) storage = new storage_type(src) update_icon() @@ -137,6 +203,7 @@ QDEL_NULL(suit) QDEL_NULL(helmet) QDEL_NULL(mask) + QDEL_NULL(mod) QDEL_NULL(storage) return ..() @@ -154,7 +221,7 @@ . += "broken" else . += "open" - if(suit) + if(suit || mod) . += "suit" if(helmet) . += "helm" @@ -175,6 +242,7 @@ helmet = null suit = null mask = null + mod = null storage = null occupant = null @@ -241,6 +309,8 @@ qdel(suit) // Delete everything but the occupant. mask = null qdel(mask) + mod = null + qdel(mod) storage = null qdel(storage) // The wires get damaged too. @@ -262,6 +332,9 @@ if(mask) things_to_clear += mask things_to_clear += mask.GetAllContents() + if(mod) + things_to_clear += mod + things_to_clear += mod.GetAllContents() if(storage) things_to_clear += storage things_to_clear += storage.GetAllContents() @@ -279,6 +352,20 @@ if(occupant) dump_contents() +/obj/machinery/suit_storage_unit/process(delta_time) + var/obj/item/stock_parts/cell/cell + if(mod) + if(!istype(mod)) + return + if(!mod.cell) + return + cell = mod.cell + else + return + + use_power(charge_rate * delta_time) + cell.give(charge_rate * delta_time) + /obj/machinery/suit_storage_unit/proc/shock(mob/user, prb) if(!prob(prb)) var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread @@ -353,6 +440,13 @@ if(!user.transferItemToLoc(I, src)) return mask = I + else if(istype(I, /obj/item/mod/control)) + if(mod) + to_chat(user, span_warning("The unit already contains a MOD!")) + return + if(!user.transferItemToLoc(I, src)) + return + mod = I else if(storage) to_chat(user, "The auxiliary storage compartment is full!") @@ -405,6 +499,10 @@ data["mask"] = mask.name else data["mask"] = null + if(mod) + data["mod"] = mod.name + else + data["mod"] = null if(storage) data["storage"] = storage.name else @@ -435,7 +533,7 @@ if("uv") if(occupant && safeties) return - else if(!helmet && !mask && !suit && !storage && !occupant) + else if(!helmet && !mask && !mod && !suit && !storage && !occupant) return else if(occupant) @@ -447,7 +545,7 @@ if(!state_open) return - var/static/list/valid_items = list("helmet", "suit", "mask", "storage") + var/static/list/valid_items = list("helmet", "suit", "mask", "mod", "storage") var/item_name = params["item"] if(item_name in valid_items) var/obj/item/I = vars[item_name] diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index 4009b1b56b..56629841e3 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -84,7 +84,7 @@ countdown.stop() STOP_PROCESSING(SSfastprocess, src) -/obj/machinery/syndicatebomb/Initialize() +/obj/machinery/syndicatebomb/Initialize(mapload) . = ..() wires = new /datum/wires/syndicatebomb(src) if(payload) @@ -242,7 +242,7 @@ open_panel = TRUE timer_set = 120 -/obj/machinery/syndicatebomb/empty/Initialize() +/obj/machinery/syndicatebomb/empty/Initialize(mapload) . = ..() wires.cut_all() @@ -270,7 +270,7 @@ var/range_light = 17 var/range_flame = 17 -/obj/item/bombcore/ex_act(severity, target) // Little boom can chain a big boom. +/obj/item/bombcore/ex_act(severity, target, origin) // Little boom can chain a big boom. detonate() diff --git a/code/game/machinery/telecomms/computers/logbrowser.dm b/code/game/machinery/telecomms/computers/logbrowser.dm index ca04009e3b..c39c4667a6 100644 --- a/code/game/machinery/telecomms/computers/logbrowser.dm +++ b/code/game/machinery/telecomms/computers/logbrowser.dm @@ -1,5 +1,5 @@ /* - The log console for viewing the entire telecomms + The log console for viewing the entire telecomms network log */ @@ -15,7 +15,7 @@ var/network = "NULL" // the network to probe var/notice = "" - var/universal_translate = FALSE // set to TRUE(1) if it can translate nonhuman speech + var/universal_translate = FALSE // set to TRUE(1) if it can translate nonhuman speech /obj/machinery/computer/telecomms/server/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) @@ -53,7 +53,7 @@ if(!LAZYLEN(SelectedMachine.log_entries)) return data_out - + for(var/datum/comm_log_entry/C in SelectedMachine.log_entries) var/list/data = list() data["name"] = C.name //name of the file @@ -104,7 +104,7 @@ data["message"] = C.parameters["message"] else data["message"] = "(unintelligible)" - + data_out["selected_logs"] += list(data) return data_out @@ -133,7 +133,7 @@ if(LAZYLEN(machinelist) > 0) notice = "FAILED: Cannot probe when buffer full" return - + for(var/obj/machinery/telecomms/T in GLOB.telecomms_list) //telecomms just went global! if(T.network == network) LAZYADD(machinelist, T) @@ -147,7 +147,7 @@ SelectedMachine = T break if("delete") - if(!src.allowed(usr) && !CHECK_BITFIELD(obj_flags, EMAGGED)) + if(!src.allowed(usr) && !(obj_flags & EMAGGED)) to_chat(usr, "ACCESS DENIED.") return @@ -156,7 +156,7 @@ return var/datum/comm_log_entry/D = locate(params["value"]) if(!istype(D)) - notice = "NOTICE: Object not found" + notice = "NOTICE: Object not found" return notice = "Deleted entry: [D.name]" LAZYREMOVE(SelectedMachine.log_entries, D) diff --git a/code/game/machinery/telecomms/computers/message.dm b/code/game/machinery/telecomms/computers/message.dm index a674bb6489..b4f4b495f8 100644 --- a/code/game/machinery/telecomms/computers/message.dm +++ b/code/game/machinery/telecomms/computers/message.dm @@ -94,9 +94,9 @@ if(istype(S) && S.hack_software) data_out["canhack"] = TRUE - data_out["hacking"] = (hacking || CHECK_BITFIELD(obj_flags, EMAGGED)) + data_out["hacking"] = (hacking || (obj_flags & EMAGGED)) if(hacking) - data_out["borg"] = ((isAI(user) || iscyborg(user)) && !CHECK_BITFIELD(obj_flags, EMAGGED)) //even borgs can't read emag + data_out["borg"] = ((isAI(user) || iscyborg(user)) && !(obj_flags & EMAGGED)) //even borgs can't read emag return data_out data_out["servers"] = list() @@ -324,7 +324,7 @@ update_static_data(usr) /obj/machinery/computer/message_monitor/attackby(obj/item/O, mob/living/user, params) - if(O.tool_behaviour == TOOL_SCREWDRIVER && CHECK_BITFIELD(obj_flags, EMAGGED)) + if(O.tool_behaviour == TOOL_SCREWDRIVER && (obj_flags & EMAGGED)) //Stops people from just unscrewing the monitor and putting it back to get the console working again. //Why this though, you should make it emag to a board level. (i wont do it) to_chat(user, "It is too hot to mess with!") @@ -333,12 +333,12 @@ /obj/machinery/computer/message_monitor/emag_act(mob/user) . = ..() - if(CHECK_BITFIELD(obj_flags, EMAGGED)) + if((obj_flags & EMAGGED)) return if(isnull(linkedServer)) to_chat(user, "A no server error appears on the screen.") return - ENABLE_BITFIELD(obj_flags, EMAGGED) + obj_flags |= EMAGGED spark_system.set_up(5, 0, src) spark_system.start() var/obj/item/paper/monitorkey/MK = new(loc, linkedServer) @@ -366,7 +366,7 @@ message = "" /obj/machinery/computer/message_monitor/proc/UnmagConsole() - DISABLE_BITFIELD(obj_flags, EMAGGED) + obj_flags &= ~(EMAGGED) message = "" /obj/machinery/computer/message_monitor/proc/ResetMessage() diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm index 9876206724..808dc4877b 100644 --- a/code/game/machinery/telecomms/machine_interactions.dm +++ b/code/game/machinery/telecomms/machine_interactions.dm @@ -86,6 +86,9 @@ .["machine"]["chang_freq_value"] = change_freq_value /obj/machinery/telecomms/ui_act(action, params, datum/tgui/ui) + . = ..() + if(.) + return if(!canInteract(usr)) if(ui) ui.close() //haha no. diff --git a/code/game/machinery/telecomms/machines/allinone.dm b/code/game/machinery/telecomms/machines/allinone.dm index 7cc421ef15..7129d77720 100644 --- a/code/game/machinery/telecomms/machines/allinone.dm +++ b/code/game/machinery/telecomms/machines/allinone.dm @@ -16,7 +16,7 @@ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF flags_1 = NODECONSTRUCT_1 -/obj/machinery/telecomms/allinone/Initialize() +/obj/machinery/telecomms/allinone/Initialize(mapload) . = ..() if (intercept) freq_listening = list(FREQ_SYNDICATE) diff --git a/code/game/machinery/telecomms/machines/bus.dm b/code/game/machinery/telecomms/machines/bus.dm index bf3dfe8f7e..fc4de9ae84 100644 --- a/code/game/machinery/telecomms/machines/bus.dm +++ b/code/game/machinery/telecomms/machines/bus.dm @@ -70,7 +70,7 @@ freq_listening = list(FREQ_ENGINEERING) autolinkers = list("processor4", "engineering", "common") -/obj/machinery/telecomms/bus/preset_four/Initialize() +/obj/machinery/telecomms/bus/preset_four/Initialize(mapload) . = ..() for(var/i = MIN_FREQ, i <= MAX_FREQ, i += 2) freq_listening |= i diff --git a/code/game/machinery/telecomms/machines/message_server.dm b/code/game/machinery/telecomms/machines/message_server.dm index a0440001c3..5cf563b9da 100644 --- a/code/game/machinery/telecomms/machines/message_server.dm +++ b/code/game/machinery/telecomms/machines/message_server.dm @@ -14,10 +14,10 @@ use_power = IDLE_POWER_USE idle_power_usage = 10 active_power_usage = 100 - armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70) + armor = list(MELEE = 25, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 70) var/obj/item/stored -/obj/machinery/blackbox_recorder/Initialize() +/obj/machinery/blackbox_recorder/Initialize(mapload) . = ..() stored = new /obj/item/blackbox(src) @@ -25,7 +25,7 @@ . = ..() if(stored) to_chat(user, "You start struggling to pry the [stored] from the [src]...") - if(!do_after(user, 30 SECONDS, TRUE, src)) + if(!do_after(user, 30 SECONDS, src)) to_chat(user, "Your fingers slip as you fail to pry the [stored] from the [src], clicking it right back into the slot!") return user.put_in_hands(stored) @@ -73,7 +73,6 @@ w_class = WEIGHT_CLASS_BULKY resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF - // The message server itself. /obj/machinery/telecomms/message_server icon = 'icons/obj/machines/research.dmi' @@ -84,6 +83,7 @@ use_power = IDLE_POWER_USE idle_power_usage = 10 active_power_usage = 100 + circuit = /obj/item/circuitboard/machine/telecomms/message_server id = "Messaging Server" network = "tcommsat" @@ -93,7 +93,7 @@ var/list/datum/data_rc_msg/rc_msgs = list() var/decryptkey -/obj/machinery/telecomms/message_server/Initialize() +/obj/machinery/telecomms/message_server/Initialize(mapload) . = ..() if (!decryptkey) decryptkey = GenerateKey() diff --git a/code/game/machinery/telecomms/machines/receiver.dm b/code/game/machinery/telecomms/machines/receiver.dm index 0e443bad8f..9f884e3904 100644 --- a/code/game/machinery/telecomms/machines/receiver.dm +++ b/code/game/machinery/telecomms/machines/receiver.dm @@ -63,7 +63,7 @@ freq_listening = list(FREQ_COMMAND, FREQ_ENGINEERING, FREQ_SECURITY) //Common and other radio frequencies for people to freely use -/obj/machinery/telecomms/receiver/preset_right/Initialize() +/obj/machinery/telecomms/receiver/preset_right/Initialize(mapload) . = ..() for(var/i = MIN_FREQ, i <= MAX_FREQ, i += 2) freq_listening |= i diff --git a/code/game/machinery/telecomms/machines/relay.dm b/code/game/machinery/telecomms/machines/relay.dm index 10328f0788..14d658e30b 100644 --- a/code/game/machinery/telecomms/machines/relay.dm +++ b/code/game/machinery/telecomms/machines/relay.dm @@ -84,6 +84,8 @@ icon = 'icons/obj/clockwork_objects.dmi' hide = TRUE autolinkers = list("h_relay") + flags_1 = DEFAULT_RICOCHET_1 | NODECONSTRUCT_1 + resistance_flags = INDESTRUCTIBLE //Generic preset relay /obj/machinery/telecomms/relay/preset/auto diff --git a/code/game/machinery/telecomms/machines/server.dm b/code/game/machinery/telecomms/machines/server.dm index 6f80cfbf0e..d9d3ca896a 100644 --- a/code/game/machinery/telecomms/machines/server.dm +++ b/code/game/machinery/telecomms/machines/server.dm @@ -16,7 +16,7 @@ var/list/log_entries = list() var/totaltraffic = 0 // gigabytes (if > 1024, divide by 1024 -> terrabytes) -/obj/machinery/telecomms/server/Initialize() +/obj/machinery/telecomms/server/Initialize(mapload) . = ..() /obj/machinery/telecomms/server/RefreshParts() @@ -72,7 +72,7 @@ /obj/machinery/telecomms/server/presets network = "tcommsat" -/obj/machinery/telecomms/server/presets/Initialize() +/obj/machinery/telecomms/server/presets/Initialize(mapload) . = ..() name = id @@ -103,7 +103,7 @@ autolinkers = list("common") //Common and other radio frequencies for people to freely use -/obj/machinery/telecomms/server/presets/common/Initialize() +/obj/machinery/telecomms/server/presets/common/Initialize(mapload) . = ..() for(var/i = MIN_FREQ, i <= MAX_FREQ, i += 2) freq_listening |= i @@ -123,6 +123,6 @@ freq_listening = list(FREQ_SECURITY) autolinkers = list("security") -/obj/machinery/telecomms/server/presets/common/birdstation/Initialize() +/obj/machinery/telecomms/server/presets/common/birdstation/Initialize(mapload) . = ..() freq_listening = list() diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index f75eef0b21..a49fb32538 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -119,7 +119,7 @@ GLOBAL_LIST_EMPTY(telecomms_list) /obj/machinery/telecomms/proc/update_power() if(toggled) // if powered, on. if not powered, off. if too damaged, off - if(CHECK_BITFIELD(stat, (BROKEN | NOPOWER | EMPED))) + if(stat &(BROKEN | NOPOWER | EMPED)) on = FALSE else on = TRUE @@ -137,11 +137,11 @@ GLOBAL_LIST_EMPTY(telecomms_list) /obj/machinery/telecomms/emp_act(severity) . = ..() - if(CHECK_BITFIELD(., EMP_PROTECT_SELF)) + if((. & EMP_PROTECT_SELF)) return if(prob(severity)) - if(!CHECK_BITFIELD(stat, EMPED)) - ENABLE_BITFIELD(stat, EMPED) + if(!(stat & EMPED)) + stat |= EMPED var/duration = severity * 35 spawn(rand(duration - 20, duration + 20)) // Takes a long time for the machines to reboot. - DISABLE_BITFIELD(stat, EMPED) + stat &= ~(EMPED) diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index daadbf4f72..6284c93ca5 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -15,7 +15,7 @@ var/obj/machinery/teleport/station/power_station var/calibrated //Calibration prevents mutation -/obj/machinery/teleport/hub/Initialize() +/obj/machinery/teleport/hub/Initialize(mapload) . = ..() link_power_station() @@ -100,7 +100,7 @@ /obj/machinery/teleport/hub/proc/is_ready() . = !panel_open && !(stat & (BROKEN|NOPOWER)) && power_station && power_station.engaged && !(power_station.stat & (BROKEN|NOPOWER)) -/obj/machinery/teleport/hub/syndicate/Initialize() +/obj/machinery/teleport/hub/syndicate/Initialize(mapload) . = ..() component_parts += new /obj/item/stock_parts/matter_bin/super(null) RefreshParts() @@ -120,7 +120,7 @@ var/list/linked_stations = list() var/efficiency = 0 -/obj/machinery/teleport/station/Initialize() +/obj/machinery/teleport/station/Initialize(mapload) . = ..() link_console_and_hub() diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm index 8bca58a7de..eb79376dc3 100644 --- a/code/game/machinery/transformer.dm +++ b/code/game/machinery/transformer.dm @@ -16,7 +16,7 @@ var/obj/effect/countdown/transformer/countdown var/mob/living/silicon/ai/masterAI -/obj/machinery/transformer/Initialize() +/obj/machinery/transformer/Initialize(mapload) // On us . = ..() new /obj/machinery/conveyor/auto(locate(x - 1, y, z), WEST) @@ -57,14 +57,14 @@ AM.forceMove(drop_location()) do_transform(AM) -/obj/machinery/transformer/CanPass(atom/movable/mover, turf/target) +/obj/machinery/transformer/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() // Allows items to go through, // to stop them from blocking the conveyor belt. if(!ishuman(mover)) - var/dir = get_dir(src, mover) - if(dir == EAST) - return ..() - return 0 + if(get_dir(src, mover) == EAST) + return + return FALSE /obj/machinery/transformer/process() if(cooldown && (cooldown_timer <= world.time)) diff --git a/code/game/machinery/turnstile.dm b/code/game/machinery/turnstile.dm index f30ef22dd7..796d34dcb4 100644 --- a/code/game/machinery/turnstile.dm +++ b/code/game/machinery/turnstile.dm @@ -11,7 +11,7 @@ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF layer = OPEN_DOOR_LAYER -/obj/machinery/turnstile/Initialize() +/obj/machinery/turnstile/Initialize(mapload) . = ..() icon_state = "turnstile" diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index 3441ac7eaa..8c2d3631e3 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -103,6 +103,31 @@ GLOBAL_LIST_INIT(dye_registry, list( DYE_RD = /obj/item/bedsheet/rd, DYE_CMO = /obj/item/bedsheet/cmo, DYE_COSMIC = /obj/item/bedsheet/cosmos + ), + DYE_REGISTRY_DOUBLE_BEDSHEET = list( + DYE_RED = /obj/item/bedsheet/red/double, + DYE_ORANGE = /obj/item/bedsheet/orange/double, + DYE_YELLOW = /obj/item/bedsheet/yellow/double, + DYE_GREEN = /obj/item/bedsheet/green/double, + DYE_BLUE = /obj/item/bedsheet/blue/double, + DYE_PURPLE = /obj/item/bedsheet/purple/double, + DYE_BLACK = /obj/item/bedsheet/black/double, + DYE_WHITE = /obj/item/bedsheet/double, + DYE_RAINBOW = /obj/item/bedsheet/rainbow/double, + DYE_MIME = /obj/item/bedsheet/mime/double, + DYE_CLOWN = /obj/item/bedsheet/clown/double, + DYE_CHAP = /obj/item/bedsheet/chaplain/double, + DYE_QM = /obj/item/bedsheet/qm/double, + DYE_LAW = /obj/item/bedsheet/black/double, + DYE_CAPTAIN = /obj/item/bedsheet/captain/double, + DYE_HOP = /obj/item/bedsheet/hop/double, + DYE_HOS = /obj/item/bedsheet/hos/double, + DYE_CE = /obj/item/bedsheet/ce/double, + DYE_RD = /obj/item/bedsheet/rd/double, + DYE_CMO = /obj/item/bedsheet/cmo/double, + DYE_COSMIC = /obj/item/bedsheet/cosmos/double, + DYE_SYNDICATE = /obj/item/bedsheet/syndie/double, + DYE_CENTCOM = /obj/item/bedsheet/centcom/double ) )) diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm deleted file mode 100644 index f9a86066ff..0000000000 --- a/code/game/mecha/combat/combat.dm +++ /dev/null @@ -1,11 +0,0 @@ -/obj/mecha/combat - force = 30 - internal_damage_threshold = 50 - armor = list("melee" = 30, "bullet" = 30, "laser" = 15, "energy" = 20, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - mouse_pointer = 'icons/mecha/mecha_mouse.dmi' - -/obj/mecha/combat/proc/max_ammo() //Max the ammo stored for Nuke Ops mechs, or anyone else that calls this - for(var/obj/item/I in equipment) - if(istype(I, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/)) - var/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/gun = I - gun.projectiles_cache = gun.projectiles_cache_max diff --git a/code/game/mecha/combat/durand.dm b/code/game/mecha/combat/durand.dm deleted file mode 100644 index 498266d043..0000000000 --- a/code/game/mecha/combat/durand.dm +++ /dev/null @@ -1,21 +0,0 @@ -/obj/mecha/combat/durand - desc = "An aging combat exosuit utilized by the Nanotrasen corporation. Originally developed to combat hostile alien lifeforms." - name = "\improper Durand" - icon_state = "durand" - step_in = 4 - dir_in = 1 //Facing North. - max_integrity = 400 - deflect_chance = 20 - armor = list("melee" = 40, "bullet" = 35, "laser" = 15, "energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - max_temperature = 30000 - infra_luminosity = 8 - force = 40 - wreckage = /obj/structure/mecha_wreckage/durand - -/obj/mecha/combat/durand/GrantActions(mob/living/user, human_occupant = 0) - ..() - defense_action.Grant(user, src) - -/obj/mecha/combat/durand/RemoveActions(mob/living/user, human_occupant = 0) - ..() - defense_action.Remove(user) diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm deleted file mode 100644 index 71258d1ccb..0000000000 --- a/code/game/mecha/combat/gygax.dm +++ /dev/null @@ -1,68 +0,0 @@ -/obj/mecha/combat/gygax - desc = "A lightweight, security exosuit. Popular among private and corporate security." - name = "\improper Gygax" - icon_state = "gygax" - step_in = 3 - dir_in = 1 //Facing North. - max_integrity = 250 - deflect_chance = 5 - force = 20 - armor = list("melee" = 25, "bullet" = 20, "laser" = 30, "energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - max_temperature = 25000 - infra_luminosity = 6 - wreckage = /obj/structure/mecha_wreckage/gygax - internal_damage_threshold = 35 - max_equip = 3 - step_energy_drain = 3 - leg_overload_coeff = 300 - -/obj/mecha/combat/gygax/dark - desc = "A lightweight exosuit, painted in a dark scheme. This model appears to have some modifications." - name = "\improper Dark Gygax" - icon_state = "darkgygax" - max_integrity = 300 - deflect_chance = 15 - force = 25 - armor = list("melee" = 40, "bullet" = 40, "laser" = 50, "energy" = 35, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - max_temperature = 35000 - leg_overload_coeff = 100 - operation_req_access = list(ACCESS_SYNDICATE) - internals_req_access = list(ACCESS_SYNDICATE) - wreckage = /obj/structure/mecha_wreckage/gygax/dark - max_equip = 4 - -/obj/mecha/combat/gygax/dark/loaded/Initialize() - . = ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/teleporter - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay - ME.attach(src) - max_ammo() - -/obj/mecha/combat/gygax/dark/add_cell(obj/item/stock_parts/cell/C=null) - if(C) - C.forceMove(src) - cell = C - return - cell = new /obj/item/stock_parts/cell/hyper(src) - -/obj/mecha/combat/gygax/GrantActions(mob/living/user, human_occupant = 0) - ..() - overload_action.Grant(user, src) - -/obj/mecha/combat/gygax/dark/GrantActions(mob/living/user, human_occupant = 0) - ..() - thrusters_action.Grant(user, src) - - -/obj/mecha/combat/gygax/RemoveActions(mob/living/user, human_occupant = 0) - ..() - overload_action.Remove(user) - -/obj/mecha/combat/gygax/dark/RemoveActions(mob/living/user, human_occupant = 0) - ..() - thrusters_action.Remove(user) diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm deleted file mode 100644 index 11a1bc1e84..0000000000 --- a/code/game/mecha/combat/phazon.dm +++ /dev/null @@ -1,29 +0,0 @@ -/obj/mecha/combat/phazon - desc = "This is a Phazon exosuit. The pinnacle of scientific research and pride of Nanotrasen, it uses cutting edge bluespace technology and expensive materials." - name = "\improper Phazon" - icon_state = "phazon" - step_in = 2 - dir_in = 2 //Facing South. - step_energy_drain = 3 - max_integrity = 200 - deflect_chance = 30 - armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - max_temperature = 25000 - infra_luminosity = 3 - wreckage = /obj/structure/mecha_wreckage/phazon - add_req_access = 1 - internal_damage_threshold = 25 - force = 15 - max_equip = 3 - phase_state = "phazon-phase" - -/obj/mecha/combat/phazon/GrantActions(mob/living/user, human_occupant = 0) - ..() - switch_damtype_action.Grant(user, src) - phasing_action.Grant(user, src) - - -/obj/mecha/combat/phazon/RemoveActions(mob/living/user, human_occupant = 0) - ..() - switch_damtype_action.Remove(user) - phasing_action.Remove(user) diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm deleted file mode 100644 index ef1565502e..0000000000 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ /dev/null @@ -1,171 +0,0 @@ -//DO NOT ADD MECHA PARTS TO THE GAME WITH THE DEFAULT "SPRITE ME" SPRITE! -//I'm annoyed I even have to tell you this! SPRITE FIRST, then commit. - -/obj/item/mecha_parts/mecha_equipment - name = "mecha equipment" - icon = 'icons/mecha/mecha_equipment.dmi' - icon_state = "mecha_equip" - force = 5 - max_integrity = 300 - var/equip_cooldown = 0 // cooldown after use - var/equip_ready = 1 //whether the equipment is ready for use. (or deactivated/activated for static stuff) - var/energy_drain = 0 - var/obj/mecha/chassis = null - /// Bitflag. Determines the range of the equipment. - var/range = MELEE - /// Bitflag. Used by exosuit fabricator to assign sub-categories based on which exosuits can equip this. - var/mech_flags = NONE - var/salvageable = 1 - //var/detachable = TRUE // Set to FALSE for built-in equipment that cannot be removed - var/selectable = 1 // Set to 0 for passive equipment such as mining scanner or armor plates - var/harmful = FALSE //Controls if equipment can be used to attack by a pacifist. - //var/destroy_sound = 'sound/mecha/critdestr.ogg' - -/obj/item/mecha_parts/mecha_equipment/proc/update_chassis_page() - if(chassis) - send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list()) - send_byjax(chassis.occupant,"exosuit.browser","equipment_menu",chassis.get_equipment_menu(),"dropdowns") - return 1 - return - -/obj/item/mecha_parts/mecha_equipment/proc/update_equip_info() - if(chassis) - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",get_equip_info()) - return 1 - return - -/obj/item/mecha_parts/mecha_equipment/Destroy() - if(chassis) - chassis.equipment -= src - if(chassis.selected == src) - chassis.selected = null - src.update_chassis_page() - //log_message("[src] is destroyed.", LOG_MECHA) - chassis.log_append_to_last("[src] is destroyed.",1) - if(chassis.occupant) - chassis.occupant_message("[src] is destroyed!") - SEND_SOUND(chassis.occupant, sound(istype(src, /obj/item/mecha_parts/mecha_equipment/weapon) ? 'sound/mecha/weapdestr.ogg' : 'sound/mecha/critdestr.ogg', volume=50)) - //chassis.occupant.playsound_local(chassis, destroy_sound, 50) - //if(!detachable) //If we're a built-in nondetachable equipment, let's lock up the slot that we were in. - // chassis.max_equip-- - chassis = null - return ..() - -/obj/item/mecha_parts/mecha_equipment/proc/critfail() - if(chassis) - mecha_log_message("Critical failure", color="red") - -/obj/item/mecha_parts/mecha_equipment/proc/get_equip_info() - if(!chassis) - return - var/txt = "* " - if(chassis.selected == src) - txt += "[src.name]" - else if(selectable) - txt += "[src.name]" - else - txt += "[src.name]" - - return txt - -/obj/item/mecha_parts/mecha_equipment/proc/is_ranged()//add a distance restricted equipment. Why not? - return range&RANGED //rename to MECHA_RANGE and MECHA_MELEE - -/obj/item/mecha_parts/mecha_equipment/proc/is_melee() - return range&MELEE - - -/obj/item/mecha_parts/mecha_equipment/proc/action_checks(atom/target) - if(!target) - return 0 - if(!chassis) - return 0 - if(!equip_ready) - return 0 - if(energy_drain && !chassis.has_charge(energy_drain)) - return 0 - if(crit_fail) - return 0 - if(chassis.equipment_disabled) - to_chat(chassis.occupant, "Error -- Equipment control unit is unresponsive.") - return 0 - return 1 - -/obj/item/mecha_parts/mecha_equipment/proc/action(atom/target) - return 0 - -/obj/item/mecha_parts/mecha_equipment/proc/start_cooldown() - set_ready_state(0) - chassis.use_power(energy_drain) - addtimer(CALLBACK(src, .proc/set_ready_state, 1), equip_cooldown) - -/obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(atom/target) - if(!chassis) - return - var/C = chassis.loc - set_ready_state(0) - chassis.use_power(energy_drain) - . = do_after(chassis.occupant, equip_cooldown, target=target) - set_ready_state(1) - if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir)) - return 0 - -/obj/item/mecha_parts/mecha_equipment/proc/do_after_mecha(atom/target, delay) - if(!chassis) - return - var/C = chassis.loc - . = do_after(chassis.occupant, delay, target=target) - if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir)) - return 0 - -/obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/mecha/M) - if(M.equipment.len[target] successfully loaded.") - mecha_log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") - else - O.anchored = initial(O.anchored) - else - occupant_message("Not enough room in cargo compartment!") - else - occupant_message("[target] is firmly secured!") - - else if(isliving(target)) - var/mob/living/M = target - if(M.stat == DEAD) - return - if(chassis.occupant.a_intent == INTENT_HARM) - M.take_overall_damage(dam_force) - if(!M) - return - M.adjustOxyLoss(round(dam_force/2)) - M.updatehealth() - target.visible_message("[chassis] squeezes [target].", \ - "[chassis] squeezes [target].",\ - "You hear something crack.") - log_combat(chassis.occupant, M, "attacked", "[name]", "(INTENT: [uppertext(chassis.occupant.a_intent)]) (DAMTYE: [uppertext(damtype)])") - else - step_away(M,chassis) - occupant_message("You push [target] out of the way.") - chassis.visible_message("[chassis] pushes [target] out of the way.") - return 1 - - - -//This is pretty much just for the death-ripley -/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill - name = "\improper KILL CLAMP" - desc = "They won't know what clamped them!" - energy_drain = 0 - dam_force = 0 - var/real_clamp = FALSE - -/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/real - desc = "They won't know what clamped them! This time for real!" - energy_drain = 10 - dam_force = 20 - real_clamp = TRUE - -/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/action(atom/target) - if(!action_checks(target)) - return - if(!cargo_holder) - return - if(isobj(target)) - var/obj/O = target - if(!O.anchored) - if(cargo_holder.cargo.len < cargo_holder.cargo_capacity) - chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") - O.anchored = TRUE - if(do_after_cooldown(target)) - cargo_holder.cargo += O - O.forceMove(chassis) - O.anchored = FALSE - occupant_message("[target] successfully loaded.") - mecha_log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") - else - O.anchored = initial(O.anchored) - else - occupant_message("Not enough room in cargo compartment!") - else - occupant_message("[target] is firmly secured!") - - else if(isliving(target)) - var/mob/living/M = target - if(M.stat == DEAD) - return - if(chassis.occupant.a_intent == INTENT_HARM) - if(real_clamp) - M.take_overall_damage(dam_force) - if(!M) - return - M.adjustOxyLoss(round(dam_force/2)) - M.updatehealth() - target.visible_message("[chassis] destroys [target] in an unholy fury.", \ - "[chassis] destroys [target] in an unholy fury.") - log_combat(chassis.occupant, M, "attacked", "[name]", "(INTENT: [uppertext(chassis.occupant.a_intent)]) (DAMTYE: [uppertext(damtype)])") - else - target.visible_message("[chassis] destroys [target] in an unholy fury.", \ - "[chassis] destroys [target] in an unholy fury.") - else if(chassis.occupant.a_intent == INTENT_DISARM) - if(real_clamp) - var/mob/living/carbon/C = target - var/play_sound = FALSE - var/limbs_gone = "" - var/obj/item/bodypart/affected = C.get_bodypart(BODY_ZONE_L_ARM) - if(affected != null) - affected.dismember(damtype) - play_sound = TRUE - limbs_gone = ", [affected]" - affected = C.get_bodypart(BODY_ZONE_R_ARM) - if(affected != null) - affected.dismember(damtype) - play_sound = TRUE - limbs_gone = "[limbs_gone], [affected]" - if(play_sound) - playsound(src, get_dismember_sound(), 80, TRUE) - target.visible_message("[chassis] rips [target]'s arms off.", \ - "[chassis] rips [target]'s arms off.") - log_combat(chassis.occupant, M, "dismembered of[limbs_gone],", "[name]", "(INTENT: [uppertext(chassis.occupant.a_intent)]) (DAMTYE: [uppertext(damtype)])") - else - target.visible_message("[chassis] rips [target]'s arms off.", \ - "[chassis] rips [target]'s arms off.") - else - step_away(M,chassis) - target.visible_message("[chassis] tosses [target] like a piece of paper.") - return 1 - - - -/obj/item/mecha_parts/mecha_equipment/extinguisher - name = "exosuit extinguisher" - desc = "Equipment for engineering exosuits. A rapid-firing high capacity fire extinguisher." - icon_state = "mecha_exting" - equip_cooldown = 5 - energy_drain = 0 - range = MELEE|RANGED - mech_flags = EXOSUIT_MODULE_WORKING - -/obj/item/mecha_parts/mecha_equipment/extinguisher/Initialize() - . = ..() - create_reagents(1000) - reagents.add_reagent(/datum/reagent/water, 1000) - -/obj/item/mecha_parts/mecha_equipment/extinguisher/action(atom/target) //copypasted from extinguisher. TODO: Rewrite from scratch. - if(!action_checks(target) || get_dist(chassis, target)>3) - return - - if(istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1) - var/obj/structure/reagent_dispensers/watertank/WT = target - WT.reagents.trans_to(src, 1000) - occupant_message("Extinguisher refilled.") - playsound(chassis, 'sound/effects/refill.ogg', 50, 1, -6) - else - if(reagents.total_volume > 0) - playsound(chassis, 'sound/effects/extinguish.ogg', 75, 1, -3) - var/direction = get_dir(chassis,target) - var/turf/T = get_turf(target) - var/turf/T1 = get_step(T,turn(direction, 90)) - var/turf/T2 = get_step(T,turn(direction, -90)) - - var/list/the_targets = list(T,T1,T2) - spawn(0) - for(var/a=0, a<5, a++) - var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water(get_turf(chassis)) - if(!W) - return - var/turf/my_target = pick(the_targets) - var/datum/reagents/R = new/datum/reagents(5) - W.reagents = R - R.my_atom = W - reagents.trans_to(W,1) - for(var/b=0, b<4, b++) - if(!W) - return - step_towards(W,my_target) - if(!W) - return - var/turf/W_turf = get_turf(W) - W.reagents.reaction(W_turf) - for(var/atom/atm in W_turf) - W.reagents.reaction(atm) - if(W.loc == my_target) - break - sleep(2) - return 1 - -/obj/item/mecha_parts/mecha_equipment/extinguisher/get_equip_info() - return "[..()] \[[src.reagents.total_volume]\]" - -/obj/item/mecha_parts/mecha_equipment/extinguisher/can_attach(obj/mecha/working/M as obj) - if(..()) - if(istype(M)) - return 1 - return 0 - - - -/obj/item/mecha_parts/mecha_equipment/rcd - name = "mounted RCD" - desc = "An exosuit-mounted Rapid Construction Device." - icon_state = "mecha_rcd" - equip_cooldown = 10 - energy_drain = 250 - range = MELEE|RANGED - item_flags = NO_MAT_REDEMPTION - var/mode = 0 //0 - deconstruct, 1 - wall or floor, 2 - airlock. - -/obj/item/mecha_parts/mecha_equipment/rcd/Initialize() - . = ..() - GLOB.rcd_list += src - -/obj/item/mecha_parts/mecha_equipment/rcd/Destroy() - GLOB.rcd_list -= src - return ..() - -/obj/item/mecha_parts/mecha_equipment/rcd/action(atom/target) - if(istype(target, /turf/open/space/transit))//>implying these are ever made -Sieve - return - - if(!isturf(target) && !istype(target, /obj/machinery/door/airlock)) - target = get_turf(target) - if(!action_checks(target) || get_dist(chassis, target)>3) - return - playsound(chassis, 'sound/machines/click.ogg', 50, 1) - - switch(mode) - if(0) - if(iswallturf(target)) - var/turf/closed/wall/W = target - occupant_message("Deconstructing [W]...") - if(do_after_cooldown(W)) - chassis.spark_system.start() - W.ScrapeAway(flags = CHANGETURF_INHERIT_AIR) - playsound(W, 'sound/items/deconstruct.ogg', 50, 1) - else if(isfloorturf(target)) - var/turf/open/floor/F = target - occupant_message("Deconstructing [F]...") - if(do_after_cooldown(target)) - chassis.spark_system.start() - F.ScrapeAway(flags = CHANGETURF_INHERIT_AIR) - playsound(F, 'sound/items/deconstruct.ogg', 50, 1) - else if (istype(target, /obj/machinery/door/airlock)) - occupant_message("Deconstructing [target]...") - if(do_after_cooldown(target)) - chassis.spark_system.start() - qdel(target) - playsound(target, 'sound/items/deconstruct.ogg', 50, 1) - if(1) - if(isspaceturf(target)) - var/turf/open/space/S = target - occupant_message("Building Floor...") - if(do_after_cooldown(S)) - S.PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) - playsound(S, 'sound/items/deconstruct.ogg', 50, 1) - chassis.spark_system.start() - else if(isfloorturf(target)) - var/turf/open/floor/F = target - occupant_message("Building Wall...") - if(do_after_cooldown(F)) - F.PlaceOnTop(/turf/closed/wall) - playsound(F, 'sound/items/deconstruct.ogg', 50, 1) - chassis.spark_system.start() - if(2) - if(isfloorturf(target)) - occupant_message("Building Airlock...") - if(do_after_cooldown(target)) - chassis.spark_system.start() - var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock(target) - T.autoclose = TRUE - playsound(target, 'sound/items/deconstruct.ogg', 50, 1) - playsound(target, 'sound/effects/sparks2.ogg', 50, 1) - - - -/obj/item/mecha_parts/mecha_equipment/rcd/do_after_cooldown(var/atom/target) - . = ..() - -/obj/item/mecha_parts/mecha_equipment/rcd/Topic(href,href_list) - ..() - if(href_list["mode"]) - mode = text2num(href_list["mode"]) - switch(mode) - if(0) - occupant_message("Switched RCD to Deconstruct.") - energy_drain = initial(energy_drain) - if(1) - occupant_message("Switched RCD to Construct.") - energy_drain = 2*initial(energy_drain) - if(2) - occupant_message("Switched RCD to Construct Airlock.") - energy_drain = 2*initial(energy_drain) - return - -/obj/item/mecha_parts/mecha_equipment/rcd/get_equip_info() - return "[..()] \[D|C|A\]" - - - - -/obj/item/mecha_parts/mecha_equipment/cable_layer - name = "cable layer" - desc = "Equipment for engineering exosuits. Lays cable along the exosuit's path." - icon_state = "mecha_wire" - var/datum/callback/event - var/turf/old_turf - var/obj/structure/cable/last_piece - var/obj/item/stack/cable_coil/cable - var/max_cable = 1000 - -/obj/item/mecha_parts/mecha_equipment/cable_layer/Initialize() - . = ..() - cable = new(src, 0) - -/obj/item/mecha_parts/mecha_equipment/cable_layer/can_attach(obj/mecha/working/M) - if(..()) - if(istype(M)) - return 1 - return 0 - -/obj/item/mecha_parts/mecha_equipment/cable_layer/attach() - ..() - event = chassis.events.addEvent("onMove", CALLBACK(src, .proc/layCable)) - return - -/obj/item/mecha_parts/mecha_equipment/cable_layer/detach() - chassis.events.clearEvent("onMove",event) - return ..() - -/obj/item/mecha_parts/mecha_equipment/cable_layer/Destroy() - if(chassis) - chassis.events.clearEvent("onMove",event) - return ..() - -/obj/item/mecha_parts/mecha_equipment/cable_layer/action(var/obj/item/stack/cable_coil/target) - if(!action_checks(target)) - return - if(istype(target) && target.amount) - var/cur_amount = cable? cable.amount : 0 - var/to_load = max(max_cable - cur_amount,0) - if(to_load) - to_load = min(target.amount, to_load) - if(!cable) - cable = new(src, 0) - cable.amount += to_load - target.use(to_load) - occupant_message("[to_load] meters of cable successfully loaded.") - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) - else - occupant_message("Reel is full.") - else - occupant_message("Unable to load [target] - no cable found.") - - -/obj/item/mecha_parts/mecha_equipment/cable_layer/Topic(href,href_list) - ..() - if(href_list["toggle"]) - set_ready_state(!equip_ready) - occupant_message("[src] [equip_ready?"dea":"a"]ctivated.") - mecha_log_message("[equip_ready?"Dea":"A"]ctivated.") - return - if(href_list["cut"]) - if(cable && cable.amount) - var/m = round(input(chassis.occupant,"Please specify the length of cable to cut","Cut cable",min(cable.amount,30)) as num, 1) - m = min(m, cable.amount) - if(m) - use_cable(m) - new /obj/item/stack/cable_coil(get_turf(chassis), m) - else - occupant_message("There's no more cable on the reel.") - return - -/obj/item/mecha_parts/mecha_equipment/cable_layer/get_equip_info() - var/output = ..() - if(output) - return "[output] \[Cable: [cable ? cable.amount : 0] m\][(cable && cable.amount) ? "- [!equip_ready?"Dea":"A"]ctivate|Cut" : null]" - return - -/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/use_cable(amount) - if(!cable || cable.amount<1) - set_ready_state(1) - occupant_message("Cable depleted, [src] deactivated.") - mecha_log_message("Cable depleted, [src] deactivated.") - return - if(cable.amount < amount) - occupant_message("No enough cable to finish the task.") - return - cable.use(amount) - update_equip_info() - return 1 - -/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/reset() - last_piece = null - -/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/dismantleFloor(var/turf/new_turf) - if(isfloorturf(new_turf)) - var/turf/open/floor/T = new_turf - if(!isplatingturf(T)) - if(!T.broken && !T.burnt) - new T.floor_tile(T) - T.make_plating() - return !new_turf.intact - -/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/layCable(var/turf/new_turf) - if(equip_ready || !istype(new_turf) || !dismantleFloor(new_turf)) - return reset() - var/fdirn = turn(chassis.dir,180) - for(var/obj/structure/cable/LC in new_turf) // check to make sure there's not a cable there already - if(LC.d1 == fdirn || LC.d2 == fdirn) - return reset() - if(!use_cable(1)) - return reset() - var/obj/structure/cable/NC = new(new_turf, "red") - NC.d1 = 0 - NC.d2 = fdirn - NC.update_icon() - - var/datum/powernet/PN - if(last_piece && last_piece.d2 != chassis.dir) - last_piece.d1 = min(last_piece.d2, chassis.dir) - last_piece.d2 = max(last_piece.d2, chassis.dir) - last_piece.update_icon() - PN = last_piece.powernet - - if(!PN) - PN = new() - GLOB.powernets += PN - NC.powernet = PN - PN.cables += NC - NC.mergeConnectedNetworks(NC.d2) - - //NC.mergeConnectedNetworksOnTurf() - last_piece = NC - return 1 diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm deleted file mode 100644 index 86bbf81dd2..0000000000 --- a/code/game/mecha/mecha.dm +++ /dev/null @@ -1,1124 +0,0 @@ -#define MECHA_INT_FIRE (1<<0) -#define MECHA_INT_TEMP_CONTROL (1<<1) -#define MECHA_INT_SHORT_CIRCUIT (1<<2) -#define MECHA_INT_TANK_BREACH (1<<3) -#define MECHA_INT_CONTROL_LOST (1<<4) - -#define MELEE 1 -#define RANGED 2 - -#define FRONT_ARMOUR 1 -#define SIDE_ARMOUR 2 -#define BACK_ARMOUR 3 - - -/obj/mecha - name = "mecha" - desc = "Exosuit" - icon = 'icons/mecha/mecha.dmi' - density = TRUE //Dense. To raise the heat. - opacity = 1 ///opaque. Menacing. - anchored = TRUE //no pulling around. - resistance_flags = FIRE_PROOF | ACID_PROOF - layer = BELOW_MOB_LAYER//icon draw layer - infra_luminosity = 15 //byond implementation is bugged. - force = 5 - flags_1 = HEAR_1|BLOCK_FACE_ATOM_1 - attack_hand_speed = CLICK_CD_MELEE - attack_hand_is_action = TRUE - var/can_move = 0 //time of next allowed movement - var/mob/living/occupant = null - var/step_in = 10 //make a step in step_in/10 sec. - var/dir_in = SOUTH //What direction will the mech face when entered/powered on? Defaults to South. - var/normal_step_energy_drain = 10 //How much energy the mech will consume each time it moves. This variable is a backup for when leg actuators affect the energy drain. - var/step_energy_drain = 10 - var/melee_energy_drain = 15 - var/overload_step_energy_drain_min = 100 - max_integrity = 300 //max_integrity is base health - var/deflect_chance = 10 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act. - armor = list("melee" = 20, "bullet" = 10, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - var/list/facing_modifiers = list(FRONT_ARMOUR = 1.5, SIDE_ARMOUR = 1, BACK_ARMOUR = 0.5) - var/obj/item/stock_parts/cell/cell - var/state = 0 - var/list/log = new - var/last_message = 0 - var/add_req_access = 1 - var/maint_access = 0 - var/equipment_disabled = 0 //disabled due to EMP - var/dna_lock //dna-locking the mech - var/list/proc_res = list() //stores proc owners, like proc_res["functionname"] = owner reference - var/datum/effect_system/spark_spread/spark_system = new - var/lights = FALSE - var/lights_power = 6 - var/last_user_hud = 1 // used to show/hide the mecha hud while preserving previous preference - var/completely_disabled = FALSE //stops the mech from doing anything - var/breach_time = 0 - var/recharge_rate = 0 - - var/bumpsmash = 0 //Whether or not the mech destroys walls by running into it. - //inner atmos - var/use_internal_tank = 0 - var/internal_tank_valve = ONE_ATMOSPHERE - var/obj/machinery/portable_atmospherics/canister/internal_tank - var/datum/gas_mixture/cabin_air - var/obj/machinery/atmospherics/components/unary/portables_connector/connected_port = null - - var/obj/item/radio/mech/radio - var/list/trackers = list() - - var/max_temperature = 25000 - var/internal_damage_threshold = 50 //health percentage below which internal damage is possible - var/internal_damage = 0 //contains bitflags - - var/list/operation_req_access = list()//required access level for mecha operation - var/list/internals_req_access = list(ACCESS_ROBOTICS)//REQUIRED ACCESS LEVEL TO OPEN CELL COMPARTMENT - - var/wreckage - - var/list/equipment = new - var/obj/item/mecha_parts/mecha_equipment/selected - var/max_equip = 3 - var/datum/events/events - - var/stepsound = 'sound/mecha/mechstep.ogg' - var/turnsound = 'sound/mecha/mechturn.ogg' - - var/melee_cooldown = 10 - var/melee_can_hit = 1 - - //Action datums - var/datum/action/innate/mecha/mech_eject/eject_action = new - var/datum/action/innate/mecha/mech_toggle_internals/internals_action = new - var/datum/action/innate/mecha/mech_cycle_equip/cycle_action = new - var/datum/action/innate/mecha/mech_toggle_lights/lights_action = new - var/datum/action/innate/mecha/mech_view_stats/stats_action = new - var/datum/action/innate/mecha/mech_toggle_thrusters/thrusters_action = new - var/datum/action/innate/mecha/mech_defence_mode/defense_action = new - var/datum/action/innate/mecha/mech_overload_mode/overload_action = new - var/datum/effect_system/smoke_spread/smoke_system = new //not an action, but trigged by one - var/datum/action/innate/mecha/mech_smoke/smoke_action = new - var/datum/action/innate/mecha/mech_zoom/zoom_action = new - var/datum/action/innate/mecha/mech_switch_damtype/switch_damtype_action = new - var/datum/action/innate/mecha/mech_toggle_phasing/phasing_action = new - var/datum/action/innate/mecha/strafe/strafing_action = new - - //Action vars - var/thrusters_active = FALSE - var/defence_mode = FALSE - var/defence_mode_deflect_chance = 35 - var/leg_overload_mode = FALSE - var/leg_overload_coeff = 100 - var/zoom_mode = FALSE - var/smoke = 5 - var/smoke_ready = 1 - var/smoke_cooldown = 100 - var/phasing = FALSE - var/phasing_energy_drain = 200 - var/phase_state = "" //icon_state when phasing - var/strafe = FALSE //If we are strafing - - var/nextsmash = 0 - var/smashcooldown = 3 //deciseconds - - var/occupant_sight_flags = 0 //sight flags to give to the occupant (e.g. mech mining scanner gives meson-like vision) - var/mouse_pointer - - hud_possible = list (DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_TRACK_HUD) - -/obj/item/radio/mech //this has to go somewhere - -/obj/mecha/Initialize() - . = ..() - events = new - icon_state += "-open" - add_radio() - spark_system.set_up(2, 0, src) - spark_system.attach(src) - smoke_system.set_up(3, src) - smoke_system.attach(src) - add_cell() - START_PROCESSING(SSobj, src) - GLOB.poi_list |= src - mecha_log_message("[src.name] created.") - GLOB.mechas_list += src //global mech list - prepare_huds() - for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) - diag_hud.add_to_hud(src) - diag_hud_set_mechhealth() - diag_hud_set_mechcell() - diag_hud_set_mechstat() - return INITIALIZE_HINT_LATELOAD - -/obj/mecha/LateInitialize() - . = ..() - add_airtank() - add_cabin() - -/obj/mecha/get_cell() - return cell - -/obj/mecha/rust_heretic_act() - take_damage(500, BRUTE) - -/obj/mecha/Destroy() - go_out() - var/mob/living/silicon/ai/AI - for(var/mob/M in src) //Let's just be ultra sure - if(isAI(M)) - occupant = null - AI = M //AIs are loaded into the mech computer itself. When the mech dies, so does the AI. They can be recovered with an AI card from the wreck. - else - M.forceMove(loc) - if(wreckage) - if(prob(30)) - explosion(get_turf(src), 0, 0, 1, 3) - var/obj/structure/mecha_wreckage/WR = new wreckage(loc, AI) - for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) - if(E.salvageable && prob(30)) - WR.crowbar_salvage += E - E.detach(WR) //detaches from src into WR - E.equip_ready = 1 - else - E.detach(loc) - qdel(E) - if(cell) - WR.crowbar_salvage += cell - cell.forceMove(WR) - cell.charge = rand(0, cell.charge) - if(internal_tank) - WR.crowbar_salvage += internal_tank - internal_tank.forceMove(WR) - else - for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) - E.detach(loc) - qdel(E) - if(cell) - qdel(cell) - if(internal_tank) - qdel(internal_tank) - if(AI) - AI.gib() //No wreck, no AI to recover - STOP_PROCESSING(SSobj, src) - GLOB.poi_list.Remove(src) - equipment.Cut() - cell = null - internal_tank = null - assume_air(cabin_air) - cabin_air = null - qdel(spark_system) - spark_system = null - qdel(smoke_system) - smoke_system = null - - GLOB.mechas_list -= src //global mech list - return ..() - -/obj/mecha/proc/restore_equipment() - equipment_disabled = 0 - if(istype(src, /obj/mecha/combat)) - mouse_pointer = 'icons/mecha/mecha_mouse.dmi' - if(occupant) - SEND_SOUND(occupant, sound('sound/items/timer.ogg', volume=50)) - to_chat(occupant, "Equipment control unit has been rebooted successfuly.") - occupant.update_mouse_pointer() - -/obj/mecha/CheckParts(list/parts_list) - ..() - cell = locate(/obj/item/stock_parts/cell) in contents - var/obj/item/stock_parts/scanning_module/SM = locate() in contents - var/obj/item/stock_parts/capacitor/CP = locate() in contents - if(SM) - normal_step_energy_drain = 20 - (5 * SM.rating) //10 is normal, so on lowest part its worse, on second its ok and on higher its real good up to 0 on best - step_energy_drain = normal_step_energy_drain - qdel(SM) - if(CP) - armor = armor.modifyRating(energy = (CP.rating * 10)) //Each level of capacitor protects the mech against emp by 10% - qdel(CP) - -//////////////////////// -////// Helpers ///////// -//////////////////////// - -/obj/mecha/proc/add_airtank() - internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src) - return internal_tank - -/obj/mecha/proc/add_cell(var/obj/item/stock_parts/cell/C=null) - if(C) - C.forceMove(src) - cell = C - return - cell = new /obj/item/stock_parts/cell/high/plus(src) - -/obj/mecha/proc/add_cabin() - cabin_air = new(200) - cabin_air.set_temperature(T20C) - cabin_air.set_moles(GAS_O2,O2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature())) - cabin_air.set_moles(GAS_N2,N2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature())) - return cabin_air - -/obj/mecha/proc/add_radio() - radio = new(src) - radio.name = "[src] radio" - radio.icon = icon - radio.icon_state = icon_state - radio.subspace_transmission = TRUE - -/obj/mecha/proc/can_use(mob/user) - if(user != occupant) - return 0 - if(user && ismob(user)) - if(!user.incapacitated()) - return 1 - return 0 - -//////////////////////////////////////////////////////////////////////////////// - -/obj/mecha/examine(mob/user) - . = ..() - var/integrity = obj_integrity*100/max_integrity - switch(integrity) - if(85 to 100) - . += "It's fully intact." - if(65 to 85) - . += "It's slightly damaged." - if(45 to 65) - . += "It's badly damaged." - if(25 to 45) - . += "It's heavily damaged." - else - . += "It's falling apart." - if(equipment && equipment.len) - . += "It's equipped with:" - for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) - . += "[icon2html(ME, user)] \A [ME]." - -//processing internal damage, temperature, air regulation, alert updates, lights power use. -/obj/mecha/process() - var/internal_temp_regulation = 1 - - if(internal_damage) - if(internal_damage & MECHA_INT_FIRE) - if(!(internal_damage & MECHA_INT_TEMP_CONTROL) && prob(5)) - clearInternalDamage(MECHA_INT_FIRE) - if(internal_tank) - var/datum/gas_mixture/int_tank_air = internal_tank.return_air() - if(int_tank_air.return_pressure() > internal_tank.maximum_pressure && !(internal_damage & MECHA_INT_TANK_BREACH)) - setInternalDamage(MECHA_INT_TANK_BREACH) - if(int_tank_air && int_tank_air.return_volume() > 0) //heat the air_contents - int_tank_air.set_temperature(min(6000+T0C, int_tank_air.return_temperature()+rand(10,15))) - if(cabin_air && cabin_air.return_volume()>0) - cabin_air.set_temperature(min(6000+T0C, cabin_air.return_temperature()+rand(10,15))) - if(cabin_air.return_temperature() > max_temperature/2) - take_damage(4/round(max_temperature/cabin_air.return_temperature(),0.1), BURN, 0, 0) - - if(internal_damage & MECHA_INT_TEMP_CONTROL) - internal_temp_regulation = 0 - - if(internal_damage & MECHA_INT_TANK_BREACH) //remove some air from internal tank - if(internal_tank) - assume_air_ratio(internal_tank.return_air(), 0.1) - - if(internal_damage & MECHA_INT_SHORT_CIRCUIT) - if(get_charge()) - spark_system.start() - cell.charge -= min(20,cell.charge) - cell.maxcharge -= min(20,cell.maxcharge) - - if(internal_temp_regulation) - if(cabin_air && cabin_air.return_volume() > 0) - var/delta = cabin_air.return_temperature() - T20C - cabin_air.set_temperature(cabin_air.return_temperature() - max(-10, min(10, round(delta/4,0.1)))) - - if(internal_tank) - var/datum/gas_mixture/tank_air = internal_tank.return_air() - - var/release_pressure = internal_tank_valve - var/cabin_pressure = cabin_air.return_pressure() - var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2) - var/transfer_moles = 0 - if(pressure_delta > 0) //cabin pressure lower than release pressure - if(tank_air.return_temperature() > 0) - transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) - tank_air.transfer_to(cabin_air,transfer_moles) - else if(pressure_delta < 0) //cabin pressure higher than release pressure - var/datum/gas_mixture/t_air = return_air() - pressure_delta = cabin_pressure - release_pressure - if(t_air) - pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta) - if(pressure_delta > 0) //if location pressure is lower than cabin pressure - transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) - cabin_air.transfer_to(t_air, transfer_moles) - - if(occupant) - if(cell) - var/cellcharge = cell.charge/cell.maxcharge - switch(cellcharge) - if(0.75 to INFINITY) - occupant.clear_alert("charge") - if(0.5 to 0.75) - occupant.throw_alert("charge", /atom/movable/screen/alert/lowcell, 1) - if(0.25 to 0.5) - occupant.throw_alert("charge", /atom/movable/screen/alert/lowcell, 2) - if(0.01 to 0.25) - occupant.throw_alert("charge", /atom/movable/screen/alert/lowcell, 3) - else - occupant.throw_alert("charge", /atom/movable/screen/alert/emptycell) - - var/integrity = obj_integrity/max_integrity*100 - switch(integrity) - if(30 to 45) - occupant.throw_alert("mech damage", /atom/movable/screen/alert/low_mech_integrity, 1) - if(15 to 35) - occupant.throw_alert("mech damage", /atom/movable/screen/alert/low_mech_integrity, 2) - if(-INFINITY to 15) - occupant.throw_alert("mech damage", /atom/movable/screen/alert/low_mech_integrity, 3) - else - occupant.clear_alert("mech damage") - var/atom/checking = occupant.loc - // recursive check to handle all cases regarding very nested occupants, - // such as brainmob inside brainitem inside MMI inside mecha - while (!isnull(checking)) - if (isturf(checking)) - // hit a turf before hitting the mecha, seems like they have - // been moved out - occupant.clear_alert("charge") - occupant.clear_alert("mech damage") - RemoveActions(occupant, human_occupant=1) - occupant = null - break - else if (checking == src) - break // all good - checking = checking.loc - - if(lights) - var/lights_energy_drain = 2 - use_power(lights_energy_drain) - -//Diagnostic HUD updates - diag_hud_set_mechhealth() - diag_hud_set_mechcell() - diag_hud_set_mechstat() - -/obj/mecha/proc/drop_item()//Derpfix, but may be useful in future for engineering exosuits. - return - -/obj/mecha/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source) - . = ..() - if(speaker == occupant) - if(radio.broadcasting) - radio.talk_into(speaker, text, , spans, message_language) - //flick speech bubble - var/list/speech_bubble_recipients = list() - for(var/mob/M in get_hearers_in_view(7,src)) - if(M.client) - speech_bubble_recipients.Add(M.client) - INVOKE_ASYNC(GLOBAL_PROC, /proc/flick_overlay, image('icons/mob/talk.dmi', src, "machine[say_test(raw_message)]",MOB_LAYER+1), speech_bubble_recipients, 30) - -//////////////////////////// -///// Action processing //// -//////////////////////////// - - -/obj/mecha/proc/click_action(atom/target,mob/user,params) - if(!occupant || occupant != user ) - return - if(!locate(/turf) in list(target,target.loc)) // Prevents inventory from being drilled - return - if(completely_disabled) - return - if(phasing) - occupant_message("Unable to interact with objects while phasing") - return - if(user.incapacitated()) - return - if(state) - occupant_message("Maintenance protocols in effect.") - return - if(!get_charge()) - return - if(src == target) - return - var/dir_to_target = get_dir(src,target) - if(dir_to_target && !(dir_to_target & dir))//wrong direction - return - if(internal_damage & MECHA_INT_CONTROL_LOST) - target = safepick(view(3,target)) - if(!target) - return - - var/mob/living/L = user - if(!Adjacent(target)) - if(selected && selected.is_ranged()) - if(HAS_TRAIT(L, TRAIT_PACIFISM) && selected.harmful) - to_chat(user, "You don't want to harm other living beings!") - return - if(selected.action(target,params)) - selected.start_cooldown() - else if(selected && selected.is_melee()) - if(isliving(target) && selected.harmful && HAS_TRAIT(L, TRAIT_PACIFISM)) - to_chat(user, "You don't want to harm other living beings!") - return - if(selected.action(target,params)) - selected.start_cooldown() - else - if(internal_damage & MECHA_INT_CONTROL_LOST) - target = safepick(oview(1,src)) - if(!melee_can_hit || !istype(target, /atom)) - return - target.mech_melee_attack(src) - melee_can_hit = 0 - spawn(melee_cooldown) - melee_can_hit = 1 - - -/obj/mecha/proc/range_action(atom/target) - return - - -////////////////////////////////// -//////// Movement procs //////// -////////////////////////////////// - -/obj/mecha/Move(atom/newloc, direct) - . = ..() - if(.) - events.fireEvent("onMove",get_turf(src)) - if (internal_tank.disconnect()) // Something moved us and broke connection - occupant_message("Air port connection teared off!") - mecha_log_message("Lost connection to gas port.") - -/obj/mecha/setDir(newdir) - . = ..() - occupant?.setDir(newdir) - -/obj/mecha/Process_Spacemove(var/movement_dir = 0) - . = ..() - if(.) - return 1 - if(thrusters_active && movement_dir && use_power(step_energy_drain)) - return 1 - - var/atom/movable/backup = get_spacemove_backup() - if(backup) - if(istype(backup) && movement_dir && !backup.anchored) - if(backup.newtonian_move(turn(movement_dir, 180))) - if(occupant) - to_chat(occupant, "You push off of [backup] to propel yourself.") - return 1 - -/obj/mecha/relaymove(mob/user,direction) - if(completely_disabled) - return - if(!direction) - return - if(user != occupant) //While not "realistic", this piece is player friendly. - user.forceMove(get_turf(src)) - to_chat(user, "You climb out from [src].") - return 0 - if(internal_tank.connected_port) - if(world.time - last_message > 20) - occupant_message("Unable to move while connected to the air system port!") - last_message = world.time - return 0 - if(state) - occupant_message("Maintenance protocols in effect.") - return - return domove(direction) - -/obj/mecha/proc/domove(direction) - if(can_move >= world.time) - return 0 - if(!Process_Spacemove(direction)) - return 0 - if(!has_charge(step_energy_drain)) - return 0 - if(defence_mode) - if(world.time - last_message > 20) - occupant_message("Unable to move while in defence mode") - last_message = world.time - return 0 - if(zoom_mode) - if(world.time - last_message > 20) - occupant_message("Unable to move while in zoom mode.") - last_message = world.time - return 0 - - var/move_result = 0 - var/oldloc = loc - if(internal_damage & MECHA_INT_CONTROL_LOST) - move_result = mechsteprand() - else if(dir != direction && (!strafe || occupant.client.keys_held["Alt"])) - move_result = mechturn(direction) - else - move_result = mechstep(direction) - if(move_result || loc != oldloc)// halfway done diagonal move still returns false - use_power(step_energy_drain) - can_move = world.time + step_in - return 1 - return 0 - -/obj/mecha/proc/mechturn(direction) - setDir(direction) - if(turnsound) - playsound(src,turnsound,40,1) - return 1 - -/obj/mecha/proc/mechstep(direction) - var/current_dir = dir - set_glide_size(DELAY_TO_GLIDE_SIZE(step_in)) - var/result = step(src,direction) - if(strafe) - setDir(current_dir) - if(result && stepsound) - playsound(src,stepsound,40,1) - return result - -/obj/mecha/proc/mechsteprand() - var/result = step_rand(src) - if(result && stepsound) - playsound(src,stepsound,40,1) - return result - -/obj/mecha/Bump(var/atom/obstacle) - if(phasing && get_charge() >= phasing_energy_drain && !throwing) - spawn() - if(can_move) - can_move = 0 - if(phase_state) - flick(phase_state, src) - forceMove(get_step(src,dir)) - use_power(phasing_energy_drain) - sleep(step_in*3) - can_move = 1 - else - if(..()) //mech was thrown - return - if(bumpsmash && occupant) //Need a pilot to push the PUNCH button. - if(nextsmash < world.time) - obstacle.mech_melee_attack(src) - nextsmash = world.time + smashcooldown - if(!obstacle || obstacle.CanPass(src,get_step(src,dir))) - step(src,dir) - if(isobj(obstacle)) - var/obj/O = obstacle - if(!O.anchored) - step(obstacle, dir) - else if(ismob(obstacle)) - var/mob/M = obstacle - if(!M.anchored) - step(obstacle, dir) - - - - - -/////////////////////////////////// -//////// Internal damage //////// -/////////////////////////////////// - -/obj/mecha/proc/check_for_internal_damage(list/possible_int_damage,ignore_threshold=null) - if(!islist(possible_int_damage) || isemptylist(possible_int_damage)) - return - if(prob(20)) - if(ignore_threshold || obj_integrity*100/max_integrity < internal_damage_threshold) - for(var/T in possible_int_damage) - if(internal_damage & T) - possible_int_damage -= T - var/int_dam_flag = safepick(possible_int_damage) - if(int_dam_flag) - setInternalDamage(int_dam_flag) - if(prob(5)) - if(ignore_threshold || obj_integrity*100/max_integrity < internal_damage_threshold) - var/obj/item/mecha_parts/mecha_equipment/ME = safepick(equipment) - if(ME) - qdel(ME) - return - -/obj/mecha/proc/setInternalDamage(int_dam_flag) - internal_damage |= int_dam_flag - log_append_to_last("Internal damage of type [int_dam_flag].",1) - SEND_SOUND(occupant, sound('sound/machines/warning-buzzer.ogg',wait=0)) - diag_hud_set_mechstat() - return - -/obj/mecha/proc/clearInternalDamage(int_dam_flag) - if(internal_damage & int_dam_flag) - switch(int_dam_flag) - if(MECHA_INT_TEMP_CONTROL) - occupant_message("Life support system reactivated.") - if(MECHA_INT_FIRE) - occupant_message("Internal fire extinquished.") - if(MECHA_INT_TANK_BREACH) - occupant_message("Damaged internal tank has been sealed.") - internal_damage &= ~int_dam_flag - diag_hud_set_mechstat() - -///////////////////////////////////// -//////////// AI piloting //////////// -///////////////////////////////////// - -/obj/mecha/attack_ai(mob/living/silicon/ai/user) - if(!isAI(user)) - return - //Allows the Malf to scan a mech's status and loadout, helping it to decide if it is a worthy chariot. - if(user.can_dominate_mechs) - examine(user) //Get diagnostic information! - for(var/obj/item/mecha_parts/mecha_tracking/B in trackers) - to_chat(user, "Warning: Tracking Beacon detected. Enter at your own risk. Beacon Data:") - to_chat(user, "[B.get_mecha_info()]") - break - //Nothing like a big, red link to make the player feel powerful! - to_chat(user, "ASSUME DIRECT CONTROL?
    ") - else - examine(user) - if(occupant) - to_chat(user, "This exosuit has a pilot and cannot be controlled.") - return - var/can_control_mech = 0 - for(var/obj/item/mecha_parts/mecha_tracking/ai_control/A in trackers) - can_control_mech = 1 - to_chat(user, "[icon2html(src, user)] Status of [name]:\n[A.get_mecha_info()]") - break - if(!can_control_mech) - to_chat(user, "You cannot control exosuits without AI control beacons installed.") - return - to_chat(user, "Take control of exosuit?
    ") - -/obj/mecha/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card) - if(!..()) - return - - //Transfer from core or card to mech. Proc is called by mech. - switch(interaction) - if(AI_TRANS_TO_CARD) //Upload AI from mech to AI card. - if(!state) //Mech must be in maint mode to allow carding. - to_chat(user, "[name] must have maintenance protocols active in order to allow a transfer.") - return - AI = occupant - if(!AI || !isAI(occupant)) //Mech does not have an AI for a pilot - to_chat(user, "No AI detected in the [name] onboard computer.") - return - AI.ai_restore_power()//So the AI initially has power. - AI.control_disabled = 1 - AI.radio_enabled = 0 - AI.disconnect_shell() - RemoveActions(AI, TRUE) - occupant = null - AI.forceMove(card) - card.AI = AI - AI.controlled_mech = null - AI.remote_control = null - icon_state = initial(icon_state)+"-open" - to_chat(AI, "You have been downloaded to a mobile storage device. Wireless connection offline.") - to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) removed from [name] and stored within local memory.") - - if(AI_MECH_HACK) //Called by AIs on the mech - AI.linked_core = new /obj/structure/AIcore/deactivated(AI.loc) - if(AI.can_dominate_mechs) - if(occupant) //Oh, I am sorry, were you using that? - to_chat(AI, "Pilot detected! Forced ejection initiated!") - to_chat(occupant, "You have been forcibly ejected!") - go_out(1) //IT IS MINE, NOW. SUCK IT, RD! - ai_enter_mech(AI, interaction) - - if(AI_TRANS_FROM_CARD) //Using an AI card to upload to a mech. - AI = card.AI - if(!AI) - to_chat(user, "There is no AI currently installed on this device.") - return - if(AI.deployed_shell) //Recall AI if shelled so it can be checked for a client - AI.disconnect_shell() - if(AI.stat || !AI.client) - to_chat(user, "[AI.name] is currently unresponsive, and cannot be uploaded.") - return - if(occupant || dna_lock) //Normal AIs cannot steal mechs! - to_chat(user, "Access denied. [name] is [occupant ? "currently occupied" : "secured with a DNA lock"].") - return - AI.control_disabled = 0 - AI.radio_enabled = 1 - to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.") - card.AI = null - ai_enter_mech(AI, interaction) - -//Hack and From Card interactions share some code, so leave that here for both to use. -/obj/mecha/proc/ai_enter_mech(mob/living/silicon/ai/AI, interaction) - AI.ai_restore_power() - AI.forceMove(src) - occupant = AI - icon_state = initial(icon_state) - playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) - if(!internal_damage) - SEND_SOUND(occupant, sound('sound/mecha/nominal.ogg',volume=50)) - AI.cancel_camera() - AI.controlled_mech = src - AI.remote_control = src - AI.mobility_flags = MOBILITY_FLAGS_DEFAULT //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow. - AI.can_shunt = 0 //ONE AI ENTERS. NO AI LEAVES. - to_chat(AI, AI.can_dominate_mechs ? "Takeover of [name] complete! You are now loaded onto the onboard computer. Do not attempt to leave the station sector!" :\ - "You have been uploaded to a mech's onboard computer.") - to_chat(AI, "Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions.") - if(interaction == AI_TRANS_FROM_CARD) - GrantActions(AI, FALSE) //No eject/return to core action for AI uploaded by card - else - GrantActions(AI, !AI.can_dominate_mechs) - - -//An actual AI (simple_animal mecha pilot) entering the mech -/obj/mecha/proc/aimob_enter_mech(mob/living/simple_animal/hostile/syndicate/mecha_pilot/pilot_mob) - if(pilot_mob && pilot_mob.Adjacent(src)) - if(occupant) - return - icon_state = initial(icon_state) - occupant = pilot_mob - pilot_mob.mecha = src - pilot_mob.forceMove(src) - GrantActions(pilot_mob)//needed for checks, and incase a badmin puts somebody in the mob - -/obj/mecha/proc/aimob_exit_mech(mob/living/simple_animal/hostile/syndicate/mecha_pilot/pilot_mob) - if(occupant == pilot_mob) - occupant = null - if(pilot_mob.mecha == src) - pilot_mob.mecha = null - icon_state = "[initial(icon_state)]-open" - pilot_mob.forceMove(get_turf(src)) - RemoveActions(pilot_mob) - - -///////////////////////////////////// -//////// Atmospheric stuff //////// -///////////////////////////////////// - -/obj/mecha/remove_air(amount) - if(use_internal_tank) - return cabin_air.remove(amount) - return ..() - -/obj/mecha/remove_air_ratio(ratio) - if(use_internal_tank) - return cabin_air.remove_ratio(ratio) - return ..() - -/obj/mecha/return_air() - if(use_internal_tank) - return cabin_air - return ..() - -/obj/mecha/proc/return_pressure() - var/datum/gas_mixture/t_air = return_air() - if(t_air) - . = t_air.return_pressure() - return - -/obj/mecha/return_temperature() - var/datum/gas_mixture/t_air = return_air() - if(t_air) - . = t_air.return_temperature() - return - -/obj/mecha/portableConnectorReturnAir() - return internal_tank.return_air() - - -/obj/mecha/MouseDrop_T(mob/M, mob/user) - if (!user.canUseTopic(src) || (user != M)) - return - if(!ishuman(user)) // no silicons or drones in mechas. - return - mecha_log_message("[user] tries to move in.") - if (occupant) - to_chat(usr, "The [name] is already occupied!") - log_append_to_last("Permission denied.") - return - if(dna_lock) - var/passed = FALSE - if(user.has_dna()) - var/mob/living/carbon/C = user - if(C.dna.unique_enzymes==dna_lock) - passed = TRUE - if (!passed) - to_chat(user, "Access denied. [name] is secured with a DNA lock.") - log_append_to_last("Permission denied.") - return - if(!operation_allowed(user)) - to_chat(user, "Access denied. Insufficient operation keycodes.") - log_append_to_last("Permission denied.") - return - if(user.buckled) - to_chat(user, "You are currently buckled and cannot move.") - log_append_to_last("Permission denied.") - return - if(user.has_buckled_mobs()) //mob attached to us - to_chat(user, "You can't enter the exosuit with other creatures attached to you!") - return - - visible_message("[user] starts to climb into [name].") - - if(do_after(user, 40, target = src)) - if(obj_integrity <= 0) - to_chat(user, "You cannot get in the [name], it has been destroyed!") - else if(occupant) - to_chat(user, "[occupant] was faster! Try better next time, loser.") - else if(user.buckled) - to_chat(user, "You can't enter the exosuit while buckled.") - else if(user.has_buckled_mobs()) - to_chat(user, "You can't enter the exosuit with other creatures attached to you!") - else - moved_inside(user) - else - to_chat(user, "You stop entering the exosuit!") - return - -/obj/mecha/proc/moved_inside(mob/living/carbon/human/H) - if(H?.client && (H in range(1))) - occupant = H - H.forceMove(src) - H.update_mouse_pointer() - add_fingerprint(H) - GrantActions(H, human_occupant=1) - forceMove(loc) - log_append_to_last("[H] moved in as pilot.") - icon_state = initial(icon_state) - setDir(dir_in) - playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) - if(!internal_damage) - SEND_SOUND(occupant, sound('sound/mecha/nominal.ogg',volume=50)) - return 1 - else - return 0 - -/obj/mecha/proc/mmi_move_inside(obj/item/mmi/mmi_as_oc, mob/user) - if(!mmi_as_oc.brainmob || !mmi_as_oc.brainmob.client) - to_chat(user, "Consciousness matrix not detected!") - return FALSE - else if(mmi_as_oc.brainmob.stat) - to_chat(user, "Beta-rhythm below acceptable level!") - return FALSE - else if(occupant) - to_chat(user, "Occupant detected!") - return FALSE - else if(dna_lock && (!mmi_as_oc.brainmob.stored_dna || (dna_lock != mmi_as_oc.brainmob.stored_dna.unique_enzymes))) - to_chat(user, "Access denied. [name] is secured with a DNA lock.") - return FALSE - - visible_message("[user] starts to insert an MMI into [name].") - - if(do_after(user, 40, target = src)) - if(!occupant) - return mmi_moved_inside(mmi_as_oc, user) - else - to_chat(user, "Occupant detected!") - else - to_chat(user, "You stop inserting the MMI.") - return FALSE - -/obj/mecha/proc/mmi_moved_inside(obj/item/mmi/mmi_as_oc, mob/user) - if(!(Adjacent(mmi_as_oc) && Adjacent(user))) - return FALSE - if(!mmi_as_oc.brainmob || !mmi_as_oc.brainmob.client) - to_chat(user, "Consciousness matrix not detected!") - return FALSE - else if(mmi_as_oc.brainmob.stat) - to_chat(user, "Beta-rhythm below acceptable level!") - return FALSE - if(!user.transferItemToLoc(mmi_as_oc, src)) - to_chat(user, "\the [mmi_as_oc] is stuck to your hand, you cannot put it in \the [src]!") - return FALSE - var/mob/living/brainmob = mmi_as_oc.brainmob - mmi_as_oc.mecha = src - occupant = brainmob - brainmob.forceMove(src) //should allow relaymove - brainmob.reset_perspective(src) - brainmob.remote_control = src - brainmob.update_mobility() - brainmob.update_mouse_pointer() - icon_state = initial(icon_state) - update_icon() - setDir(dir_in) - mecha_log_message("[mmi_as_oc] moved in as pilot.") - if(!internal_damage) - SEND_SOUND(occupant, sound('sound/mecha/nominal.ogg',volume=50)) - GrantActions(brainmob) - return TRUE - -/obj/mecha/container_resist(mob/living/user) - go_out() - -/obj/mecha/Exited(atom/movable/M, atom/newloc) - if(occupant && occupant == M) // The occupant exited the mech without calling go_out() - go_out(TRUE, newloc) - -/obj/mecha/proc/go_out(forced, atom/newloc = loc) - if(!occupant) - return - var/atom/movable/mob_container - occupant.clear_alert("charge") - occupant.clear_alert("mech damage") - if(ishuman(occupant)) - mob_container = occupant - RemoveActions(occupant, human_occupant=1) - else if(isbrain(occupant)) - var/mob/living/brain/brain = occupant - RemoveActions(brain) - mob_container = brain.container - else if(isAI(occupant)) - var/mob/living/silicon/ai/AI = occupant - if(forced)//This should only happen if there are multiple AIs in a round, and at least one is Malf. - RemoveActions(occupant) - occupant.gib() //If one Malf decides to steal a mech from another AI (even other Malfs!), they are destroyed, as they have nowhere to go when replaced. - occupant = null - return - else - if(!AI.linked_core) - to_chat(AI, "Inactive core destroyed. Unable to return.") - AI.linked_core = null - return - to_chat(AI, "Returning to core...") - AI.controlled_mech = null - AI.remote_control = null - RemoveActions(occupant, 1) - mob_container = AI - newloc = get_turf(AI.linked_core) - qdel(AI.linked_core) - else - return - var/mob/living/L = occupant - occupant = null //we need it null when forceMove calls Exited(). - if(mob_container.forceMove(newloc))//ejecting mob container - mecha_log_message("[mob_container] moved out.") - L << browse(null, "window=exosuit") - - if(istype(mob_container, /obj/item/mmi)) - var/obj/item/mmi/mmi = mob_container - if(mmi.brainmob) - L.forceMove(mmi) - L.reset_perspective() - mmi.mecha = null - mmi.update_icon() - L.mobility_flags = NONE - icon_state = initial(icon_state)+"-open" - setDir(dir_in) - - if(L && L.client) - L.update_mouse_pointer() - L.client.view_size.resetToDefault() - zoom_mode = 0 - -///////////////////////// -////// Access stuff ///// -///////////////////////// - -/obj/mecha/proc/operation_allowed(mob/M) - req_access = operation_req_access - req_one_access = list() - return allowed(M) - -/obj/mecha/proc/internals_access_allowed(mob/M) - req_one_access = internals_req_access - req_access = list() - return allowed(M) - - - -//////////////////////////////// -/////// Messages and Log /////// -//////////////////////////////// - -/obj/mecha/proc/occupant_message(message as text) - if(message) - if(occupant && occupant.client) - to_chat(occupant, "[icon2html(src, occupant)] [message]") - return - -/obj/mecha/proc/mecha_log_message(message, color) - log.len++ - log[log.len] = list("time"="[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]","date","year"="[GLOB.year_integer]","message"="[color?"":null][message][color?"":null]") - log_message(message, LOG_GAME, color) //also do the normal admin logs I guess. - return log.len - -/obj/mecha/proc/log_append_to_last(message as text,red=null) - var/list/last_entry = log[log.len] - last_entry["message"] += "
    [red?"":null][message][red?"":null]" - return - -/////////////////////// -///// Power stuff ///// -/////////////////////// - -/obj/mecha/proc/has_charge(amount) - return (get_charge()>=amount) - -/obj/mecha/proc/get_charge() - for(var/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/R in equipment) - var/relay_charge = R.get_charge() - if(relay_charge) - return relay_charge - if(cell) - return max(0, cell.charge) - -/obj/mecha/proc/use_power(amount) - if(get_charge()) - cell.use(amount) - return 1 - return 0 - -/obj/mecha/proc/give_power(amount) - if(!isnull(get_charge())) - cell.give(amount) - return 1 - return 0 - -/obj/mecha/update_remote_sight(mob/living/user) - if(occupant_sight_flags) - if(user == occupant) - user.sight |= occupant_sight_flags - -/////////////////////// -////// Ammo stuff ///// -/////////////////////// - -/obj/mecha/proc/ammo_resupply(var/obj/item/mecha_ammo/A, mob/user,var/fail_chat_override = FALSE) - if(!A.rounds) - if(!fail_chat_override) - to_chat(user, "This box of ammo is empty!") - return FALSE - var/ammo_needed - var/found_gun - for(var/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/gun in equipment) - ammo_needed = 0 - - if(istype(gun, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic) && gun.ammo_type == A.ammo_type) - found_gun = TRUE - if(A.direct_load) - ammo_needed = initial(gun.projectiles) - gun.projectiles - else - ammo_needed = gun.projectiles_cache_max - gun.projectiles_cache - - if(ammo_needed) - if(ammo_needed < A.rounds) - if(A.direct_load) - gun.projectiles = gun.projectiles + ammo_needed - else - gun.projectiles_cache = gun.projectiles_cache + ammo_needed - playsound(get_turf(user),A.load_audio,50,1) - to_chat(user, "You add [ammo_needed] [A.round_term][ammo_needed > 1?"s":""] to the [gun.name]") - A.rounds = A.rounds - ammo_needed - A.update_name() - return TRUE - - else - if(A.direct_load) - gun.projectiles = gun.projectiles + A.rounds - else - gun.projectiles_cache = gun.projectiles_cache + A.rounds - playsound(get_turf(user),A.load_audio,50,1) - to_chat(user, "You add [A.rounds] [A.round_term][A.rounds > 1?"s":""] to the [gun.name]") - A.rounds = 0 - A.update_name() - return TRUE - if(!fail_chat_override) - if(found_gun) - to_chat(user, "You can't fit any more ammo of this type!") - else - to_chat(user, "None of the equipment on this exosuit can use this ammo!") - return FALSE diff --git a/code/game/mecha/mecha_actions.dm b/code/game/mecha/mecha_actions.dm deleted file mode 100644 index ee43e3f770..0000000000 --- a/code/game/mecha/mecha_actions.dm +++ /dev/null @@ -1,285 +0,0 @@ -//////////////////////////////////////// Action Buttons /////////////////////////////////////////////// - -/obj/mecha/proc/GrantActions(mob/living/user, human_occupant = 0) - if(human_occupant) - eject_action.Grant(user, src) - internals_action.Grant(user, src) - cycle_action.Grant(user, src) - lights_action.Grant(user, src) - stats_action.Grant(user, src) - strafing_action.Grant(user, src) - - -/obj/mecha/proc/RemoveActions(mob/living/user, human_occupant = 0) - if(human_occupant) - eject_action.Remove(user) - internals_action.Remove(user) - cycle_action.Remove(user) - lights_action.Remove(user) - stats_action.Remove(user) - strafing_action.Remove(user) - - -/datum/action/innate/mecha - check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUN | AB_CHECK_CONSCIOUS - icon_icon = 'icons/mob/actions/actions_mecha.dmi' - var/obj/mecha/chassis - -/datum/action/innate/mecha/Grant(mob/living/L, obj/mecha/M) - if(M) - chassis = M - ..() - -/datum/action/innate/mecha/Destroy() - chassis = null - return ..() - -/datum/action/innate/mecha/mech_eject - name = "Eject From Mech" - button_icon_state = "mech_eject" - -/datum/action/innate/mecha/mech_eject/Activate() - if(!owner) - return - if(!chassis || chassis.occupant != owner) - return - chassis.go_out() - - -/datum/action/innate/mecha/mech_toggle_internals - name = "Toggle Internal Airtank Usage" - button_icon_state = "mech_internals_off" - -/datum/action/innate/mecha/mech_toggle_internals/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - chassis.use_internal_tank = !chassis.use_internal_tank - button_icon_state = "mech_internals_[chassis.use_internal_tank ? "on" : "off"]" - chassis.occupant_message("Now taking air from [chassis.use_internal_tank?"internal airtank":"environment"].") - chassis.mecha_log_message("Now taking air from [chassis.use_internal_tank?"internal airtank":"environment"].") - UpdateButtonIcon() - -/datum/action/innate/mecha/mech_cycle_equip - name = "Cycle Equipment" - button_icon_state = "mech_cycle_equip_off" - -/datum/action/innate/mecha/mech_cycle_equip/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - - var/list/available_equipment = list() - for(var/obj/item/mecha_parts/mecha_equipment/M in chassis.equipment) - if(M.selectable) - available_equipment += M - - if(available_equipment.len == 0) - chassis.occupant_message("No equipment available.") - return - if(!chassis.selected) - chassis.selected = available_equipment[1] - chassis.occupant_message("You select [chassis.selected]") - send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list()) - button_icon_state = "mech_cycle_equip_on" - UpdateButtonIcon() - return - var/number = 0 - for(var/A in available_equipment) - number++ - if(A == chassis.selected) - if(available_equipment.len == number) - chassis.selected = null - chassis.occupant_message("You switch to no equipment") - button_icon_state = "mech_cycle_equip_off" - else - chassis.selected = available_equipment[number+1] - chassis.occupant_message("You switch to [chassis.selected]") - button_icon_state = "mech_cycle_equip_on" - send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list()) - UpdateButtonIcon() - return - - -/datum/action/innate/mecha/mech_toggle_lights - name = "Toggle Lights" - button_icon_state = "mech_lights_off" - -/datum/action/innate/mecha/mech_toggle_lights/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - chassis.lights = !chassis.lights - if(chassis.lights) - chassis.set_light(chassis.lights_power) - button_icon_state = "mech_lights_on" - else - chassis.set_light(-chassis.lights_power) - button_icon_state = "mech_lights_off" - chassis.occupant_message("Toggled lights [chassis.lights?"on":"off"].") - chassis.mecha_log_message("Toggled lights [chassis.lights?"on":"off"].") - UpdateButtonIcon() - -/datum/action/innate/mecha/mech_view_stats - name = "View Stats" - button_icon_state = "mech_view_stats" - -/datum/action/innate/mecha/mech_view_stats/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - chassis.occupant << browse(chassis.get_stats_html(), "window=exosuit") - - -/datum/action/innate/mecha/strafe - name = "Toggle Strafing. Disabled when Alt is held." - button_icon_state = "strafe" - -/datum/action/innate/mecha/strafe/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - - chassis.toggle_strafe() - -/obj/mecha/AltClick(mob/living/user) - . = ..() - if((user == occupant) && user.canUseTopic(src)) - toggle_strafe() - return TRUE - -/obj/mecha/proc/toggle_strafe() - strafe = !strafe - - occupant_message("Toggled strafing mode [strafe?"on":"off"].") - mecha_log_message("Toggled strafing mode [strafe?"on":"off"].") - strafing_action.UpdateButtonIcon() - -//////////////////////////////////////// Specific Ability Actions /////////////////////////////////////////////// -//Need to be granted by the mech type, Not default abilities. - -/datum/action/innate/mecha/mech_toggle_thrusters - name = "Toggle Thrusters" - button_icon_state = "mech_thrusters_off" - -/datum/action/innate/mecha/mech_toggle_thrusters/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - if(chassis.get_charge() > 0) - chassis.thrusters_active = !chassis.thrusters_active - button_icon_state = "mech_thrusters_[chassis.thrusters_active ? "on" : "off"]" - chassis.mecha_log_message("Toggled thrusters.") - chassis.occupant_message("Thrusters [chassis.thrusters_active ?"en":"dis"]abled.") - - -/datum/action/innate/mecha/mech_defence_mode - name = "Toggle Defence Mode" - button_icon_state = "mech_defense_mode_off" - -/datum/action/innate/mecha/mech_defence_mode/Activate(forced_state = null) - if(!owner || !chassis || chassis.occupant != owner) - return - if(!isnull(forced_state)) - chassis.defence_mode = forced_state - else - chassis.defence_mode = !chassis.defence_mode - button_icon_state = "mech_defense_mode_[chassis.defence_mode ? "on" : "off"]" - if(chassis.defence_mode) - chassis.deflect_chance = chassis.defence_mode_deflect_chance - chassis.occupant_message("You enable [chassis] defence mode.") - else - chassis.deflect_chance = initial(chassis.deflect_chance) - chassis.occupant_message("You disable [chassis] defence mode.") - chassis.mecha_log_message("Toggled defence mode.") - UpdateButtonIcon() - -/datum/action/innate/mecha/mech_overload_mode - name = "Toggle leg actuators overload" - button_icon_state = "mech_overload_off" - -/datum/action/innate/mecha/mech_overload_mode/Activate(forced_state = null) - if(!owner || !chassis || chassis.occupant != owner) - return - if(!isnull(forced_state)) - chassis.leg_overload_mode = forced_state - else - chassis.leg_overload_mode = !chassis.leg_overload_mode - button_icon_state = "mech_overload_[chassis.leg_overload_mode ? "on" : "off"]" - chassis.mecha_log_message("Toggled leg actuators overload.") - if(chassis.leg_overload_mode) - chassis.leg_overload_mode = 1 - chassis.bumpsmash = 1 - chassis.step_in = min(1, round(chassis.step_in/2)) - chassis.step_energy_drain = max(chassis.overload_step_energy_drain_min,chassis.step_energy_drain*chassis.leg_overload_coeff) - chassis.occupant_message("You enable leg actuators overload.") - else - chassis.leg_overload_mode = 0 - chassis.bumpsmash = 0 - chassis.step_in = initial(chassis.step_in) - chassis.step_energy_drain = chassis.normal_step_energy_drain - chassis.occupant_message("You disable leg actuators overload.") - UpdateButtonIcon() - -/datum/action/innate/mecha/mech_smoke - name = "Smoke" - button_icon_state = "mech_smoke" - -/datum/action/innate/mecha/mech_smoke/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - if(chassis.smoke_ready && chassis.smoke>0) - chassis.smoke_system.start() - chassis.smoke-- - chassis.smoke_ready = 0 - spawn(chassis.smoke_cooldown) - chassis.smoke_ready = 1 - - -/datum/action/innate/mecha/mech_zoom - name = "Zoom" - button_icon_state = "mech_zoom_off" - -/datum/action/innate/mecha/mech_zoom/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - if(owner.client) - chassis.zoom_mode = !chassis.zoom_mode - button_icon_state = "mech_zoom_[chassis.zoom_mode ? "on" : "off"]" - chassis.mecha_log_message("Toggled zoom mode.") - chassis.occupant_message("Zoom mode [chassis.zoom_mode?"en":"dis"]abled.") - if(chassis.zoom_mode) - owner.client.view_size.setTo(4.5) - SEND_SOUND(owner, sound('sound/mecha/imag_enh.ogg',volume=50)) - else - owner.client.view_size.resetToDefault() - UpdateButtonIcon() - -/datum/action/innate/mecha/mech_switch_damtype - name = "Reconfigure arm microtool arrays" - button_icon_state = "mech_damtype_brute" - -/datum/action/innate/mecha/mech_switch_damtype/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - var/new_damtype - switch(chassis.damtype) - if("tox") - new_damtype = "brute" - chassis.occupant_message("Your exosuit's hands form into fists.") - if("brute") - new_damtype = "fire" - chassis.occupant_message("A torch tip extends from your exosuit's hand, glowing red.") - if("fire") - new_damtype = "tox" - chassis.occupant_message("A bone-chillingly thick plasteel needle protracts from the exosuit's palm.") - chassis.damtype = new_damtype - button_icon_state = "mech_damtype_[new_damtype]" - playsound(src, 'sound/mecha/mechmove01.ogg', 50, 1) - UpdateButtonIcon() - -/datum/action/innate/mecha/mech_toggle_phasing - name = "Toggle Phasing" - button_icon_state = "mech_phasing_off" - -/datum/action/innate/mecha/mech_toggle_phasing/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - chassis.phasing = !chassis.phasing - button_icon_state = "mech_phasing_[chassis.phasing ? "on" : "off"]" - chassis.occupant_message("En":"#f00\">Dis"]abled phasing.") - UpdateButtonIcon() diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm deleted file mode 100644 index 34cb57f661..0000000000 --- a/code/game/mecha/mecha_construction_paths.dm +++ /dev/null @@ -1,2292 +0,0 @@ -//////////////////////////////// -///// Construction datums ////// -//////////////////////////////// -/datum/component/construction/mecha - var/base_icon - var/looky_helpy = TRUE - -/datum/component/construction/mecha/examine(datum/source, mob/user, list/examine_list) - . = ..() - if(looky_helpy) - switch(steps[index]["key"]) - if(TOOL_WRENCH) - examine_list += "The mech could be wrenched into place." - if(TOOL_SCREWDRIVER) - examine_list += "The mech could be screwed into place." - if(TOOL_WIRECUTTER) - examine_list += "The mech wires could be trimmed into place." - if(/obj/item/stack/cable_coil) - examine_list += "The mech could use some wiring." - if(/obj/item/circuitboard) - examine_list += "The mech could use a type ofcircuitboard." - if(/obj/item/stock_parts/scanning_module) - examine_list += "The mech could use a scanning stock part." - if(/obj/item/stock_parts/capacitor) - examine_list += "The mech could use a power based stock part." - if(/obj/item/stock_parts/cell) - examine_list += "The mech could use a power source." - if(/obj/item/stack/sheet/metal) - examine_list += "The mech could use some sheets of metal." - if(/obj/item/stack/sheet/plasteel) - examine_list += "The mech could use some sheets of strong steel." - if(/obj/item/bikehorn) - examine_list += "HONK IT!." - if(/obj/item/clothing/mask/gas/clown_hat) - examine_list += "GIVE IT CLOWN MAKEUP HONK!." - if(/obj/item/clothing/shoes/clown_shoes) - examine_list += "GIVE IT GOOFY SHOES HONK HONK!." - if(/obj/item/mecha_parts/part) - examine_list += "The mech could use a mech part." - if(/obj/item/stack/ore/bluespace_crystal) - examine_list += "The mech could use a crystal of sorts." - if(/obj/item/assembly/signaler/anomaly) - examine_list += "The mech could use a anomaly of sorts." - -/datum/component/construction/mecha/spawn_result() - if(!result) - return - // Remove default mech power cell, as we replace it with a new one. - var/obj/mecha/M = new result(drop_location()) - QDEL_NULL(M.cell) - - var/obj/item/mecha_parts/chassis/parent_chassis = parent - M.CheckParts(parent_chassis.contents) - - SSblackbox.record_feedback("tally", "mechas_created", 1, M.name) - QDEL_NULL(parent) - -/datum/component/construction/mecha/update_parent(step_index) - ..() - // By default, each step in mech construction has a single icon_state: - // "[base_icon][index - 1]" - // For example, Ripley's step 1 icon_state is "ripley0". - var/atom/parent_atom = parent - if(!steps[index]["icon_state"] && base_icon) - parent_atom.icon_state = "[base_icon][index - 1]" - -/datum/component/construction/unordered/mecha_chassis/custom_action(obj/item/I, mob/living/user, typepath) - . = user.transferItemToLoc(I, parent) - if(.) - var/atom/parent_atom = parent - user.visible_message("[user] has connected [I] to [parent].", "You connect [I] to [parent].") - parent_atom.add_overlay(I.icon_state+"+o") - qdel(I) - -/datum/component/construction/unordered/mecha_chassis/spawn_result() - var/atom/parent_atom = parent - parent_atom.icon = 'icons/mecha/mech_construction.dmi' - parent_atom.density = TRUE - parent_atom.cut_overlays() - ..() - - -/datum/component/construction/unordered/mecha_chassis/ripley - result = /datum/component/construction/mecha/ripley - steps = list( - /obj/item/mecha_parts/part/ripley_torso, - /obj/item/mecha_parts/part/ripley_left_arm, - /obj/item/mecha_parts/part/ripley_right_arm, - /obj/item/mecha_parts/part/ripley_left_leg, - /obj/item/mecha_parts/part/ripley_right_leg - ) - -/datum/component/construction/mecha/ripley - result = /obj/mecha/working/ripley - base_icon = "ripley" - steps = list( - //1 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected." - ), - - //2 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected." - ), - - //3 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active." - ), - - //4 - list( - "key" = TOOL_WIRECUTTER, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added." - ), - - //5 - list( - "key" = /obj/item/circuitboard/mecha/ripley/main, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted." - ), - - //6 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Central control module is installed." - ), - - //7 - list( - "key" = /obj/item/circuitboard/mecha/ripley/peripherals, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured." - ), - - //8 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed." - ), - - //9 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured." - ), - - //10 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The scanner module is installed." - ), - - //11 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Scanner module is secured." - ), - - //12 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Capacitor is installed." - ), - - //13 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Capacitor is secured." - ), - - //14 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The power cell is installed." - ), - - //15 - list( - "key" = /obj/item/stack/sheet/metal, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The power cell is secured." - ), - - //16 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "Internal armor is installed." - ), - - //17 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched." - ), - - //18 - list( - "key" = /obj/item/stack/sheet/plasteel, - "amount" = 5, - "back_key" = TOOL_WELDER, - "desc" = "Internal armor is welded." - ), - - //19 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is installed." - ), - - //20 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "External armor is wrenched." - ), - ) - -/datum/component/construction/mecha/ripley/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - switch(index) - if(1) - user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") - if(2) - if(diff==FORWARD) - user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") - else - user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") - if(3) - if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") - else - user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") - if(4) - if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") - else - user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") - if(5) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") - if(6) - if(diff==FORWARD) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - else - user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") - if(7) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - if(8) - if(diff==FORWARD) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - else - user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") - if(9) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - if(10) - if(diff==FORWARD) - user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") - else - user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") - if(11) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") - if(12) - if(diff==FORWARD) - user.visible_message("[user] secures [I].", "You secure [I].") - else - user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") - if(13) - if(diff==FORWARD) - user.visible_message("[user] installs [I].", "You install [I].") - else - user.visible_message("[user] unsecures the capacitor from [parent].", "You unsecure the capacitor from [parent].") - if(14) - if(diff==FORWARD) - user.visible_message("[user] secures the power cell.", "You secure the power cell.") - else - user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") - if(15) - if(diff==FORWARD) - user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") - if(16) - if(diff==FORWARD) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - else - user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") - if(17) - if(diff==FORWARD) - user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - if(18) - if(diff==FORWARD) - user.visible_message("[user] installs the external reinforced armor layer to [parent].", "You install the external reinforced armor layer to [parent].") - else - user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") - if(19) - if(diff==FORWARD) - user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") - else - user.visible_message("[user] pries external armor layer from [parent].", "You pry external armor layer from [parent].") - if(20) - if(diff==FORWARD) - user.visible_message("[user] welds the external armor layer to [parent].", "You weld the external armor layer to [parent].") - else - user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") - return TRUE - -/datum/component/construction/unordered/mecha_chassis/gygax - result = /datum/component/construction/mecha/gygax - steps = list( - /obj/item/mecha_parts/part/gygax_torso, - /obj/item/mecha_parts/part/gygax_left_arm, - /obj/item/mecha_parts/part/gygax_right_arm, - /obj/item/mecha_parts/part/gygax_left_leg, - /obj/item/mecha_parts/part/gygax_right_leg, - /obj/item/mecha_parts/part/gygax_head - ) - -/datum/component/construction/mecha/gygax - result = /obj/mecha/combat/gygax - base_icon = "gygax" - steps = list( - //1 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected." - ), - - //2 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected." - ), - - //3 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active." - ), - - //4 - list( - "key" = TOOL_WIRECUTTER, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added." - ), - - //5 - list( - "key" = /obj/item/circuitboard/mecha/gygax/main, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted." - ), - - //6 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Central control module is installed." - ), - - //7 - list( - "key" = /obj/item/circuitboard/mecha/gygax/peripherals, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured." - ), - - //8 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed." - ), - - //9 - list( - "key" = /obj/item/circuitboard/mecha/gygax/targeting, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured." - ), - - //10 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Weapon control module is installed." - ), - - //11 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Weapon control module is secured." - ), - - //12 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Scanner module is installed." - ), - - //13 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Scanner module is secured." - ), - - //14 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Capacitor is installed." - ), - - //15 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Capacitor is secured." - ), - - //16 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The power cell is installed." - ), - - //17 - list( - "key" = /obj/item/stack/sheet/metal, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The power cell is secured." - ), - - //18 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "Internal armor is installed." - ), - - //19 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched." - ), - - //20 - list( - "key" = /obj/item/mecha_parts/part/gygax_armor, - "action" = ITEM_DELETE, - "back_key" = TOOL_WELDER, - "desc" = "Internal armor is welded." - ), - - //21 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is installed." - ), - - //22 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "External armor is wrenched." - ), - - ) - -/datum/component/construction/mecha/gygax/action(datum/source, atom/used_atom, mob/user) - return check_step(used_atom,user) - -/datum/component/construction/mecha/gygax/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - switch(index) - if(1) - user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") - if(2) - if(diff==FORWARD) - user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") - else - user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") - if(3) - if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") - else - user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") - if(4) - if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") - else - user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") - if(5) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") - if(6) - if(diff==FORWARD) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - else - user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") - if(7) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - if(8) - if(diff==FORWARD) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - else - user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") - if(9) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - if(10) - if(diff==FORWARD) - user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") - else - user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") - if(11) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") - if(12) - if(diff==FORWARD) - user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") - else - user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") - if(13) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") - if(14) - if(diff==FORWARD) - user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") - else - user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") - if(15) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") - if(16) - if(diff==FORWARD) - user.visible_message("[user] secures the power cell.", "You secure the power cell.") - else - user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") - if(17) - if(diff==FORWARD) - user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") - if(18) - if(diff==FORWARD) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - else - user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") - if(19) - if(diff==FORWARD) - user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - if(20) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") - if(21) - if(diff==FORWARD) - user.visible_message("[user] secures Gygax Armor Plates.", "You secure Gygax Armor Plates.") - else - user.visible_message("[user] pries Gygax Armor Plates from [parent].", "You pry Gygax Armor Plates from [parent].") - if(22) - if(diff==FORWARD) - user.visible_message("[user] welds Gygax Armor Plates to [parent].", "You weld Gygax Armor Plates to [parent].") - else - user.visible_message("[user] unfastens Gygax Armor Plates.", "You unfasten Gygax Armor Plates.") - return TRUE - -//Begin Medigax -/datum/component/construction/unordered/mecha_chassis/medigax - result = /datum/component/construction/mecha/medigax - steps = list( - /obj/item/mecha_parts/part/medigax_torso, - /obj/item/mecha_parts/part/medigax_left_arm, - /obj/item/mecha_parts/part/medigax_right_arm, - /obj/item/mecha_parts/part/medigax_left_leg, - /obj/item/mecha_parts/part/medigax_right_leg, - /obj/item/mecha_parts/part/medigax_head - ) - -/datum/component/construction/mecha/medigax - result = /obj/mecha/medical/medigax - base_icon = "medigax" - steps = list( - //1 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected." - ), - - //2 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected." - ), - - //3 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active." - ), - - //4 - list( - "key" = TOOL_WIRECUTTER, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added." - ), - - //5 - list( - "key" = /obj/item/circuitboard/mecha/gygax/main, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted." - ), - - //6 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Central control module is installed." - ), - - //7 - list( - "key" = /obj/item/circuitboard/mecha/gygax/peripherals, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured." - ), - - //8 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed." - ), - - //9 - list( - "key" = /obj/item/circuitboard/mecha/gygax/targeting, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured." - ), - - //10 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Weapon control module is installed." - ), - - //11 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Weapon control module is secured." - ), - - //12 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Scanner module is installed." - ), - - //13 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Scanner module is secured." - ), - - //14 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Capacitor is installed." - ), - - //15 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Capacitor is secured." - ), - - //16 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The power cell is installed." - ), - - //17 - list( - "key" = /obj/item/stack/sheet/metal, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The power cell is secured." - ), - - //18 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "Internal armor is installed." - ), - - //19 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched." - ), - - //20 - list( - "key" = /obj/item/mecha_parts/part/medigax_armor, - "action" = ITEM_DELETE, - "back_key" = TOOL_WELDER, - "desc" = "Internal armor is welded." - ), - - //21 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is installed." - ), - - //22 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "External armor is wrenched." - ), - - ) - -/datum/component/construction/mecha/medigax/action(datum/source, atom/used_atom, mob/user) - return check_step(used_atom,user) - -/datum/component/construction/mecha/medigax/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - switch(index) - if(1) - user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") - if(2) - if(diff==FORWARD) - user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") - else - user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") - if(3) - if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") - else - user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") - if(4) - if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") - else - user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") - if(5) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") - if(6) - if(diff==FORWARD) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - else - user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") - if(7) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - if(8) - if(diff==FORWARD) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - else - user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") - if(9) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - if(10) - if(diff==FORWARD) - user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") - else - user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") - if(11) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") - if(12) - if(diff==FORWARD) - user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") - else - user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") - if(13) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") - if(14) - if(diff==FORWARD) - user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") - else - user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") - if(15) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") - if(16) - if(diff==FORWARD) - user.visible_message("[user] secures the power cell.", "You secure the power cell.") - else - user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") - if(17) - if(diff==FORWARD) - user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") - if(18) - if(diff==FORWARD) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - else - user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") - if(19) - if(diff==FORWARD) - user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - if(20) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") - if(21) - if(diff==FORWARD) - user.visible_message("[user] secures Gygax Armor Plates.", "You secure Medical Gygax Armor Plates.") - else - user.visible_message("[user] pries Gygax Armor Plates from [parent].", "You pry Medical Gygax Armor Plates from [parent].") - if(22) - if(diff==FORWARD) - user.visible_message("[user] welds Gygax Armor Plates to [parent].", "You weld Medical Gygax Armor Plates to [parent].") - else - user.visible_message("[user] unfastens Gygax Armor Plates.", "You unfasten Medical Gygax Armor Plates.") - return TRUE -// End Medigax - -/datum/component/construction/unordered/mecha_chassis/firefighter - result = /datum/component/construction/mecha/firefighter - steps = list( - /obj/item/mecha_parts/part/ripley_torso, - /obj/item/mecha_parts/part/ripley_left_arm, - /obj/item/mecha_parts/part/ripley_right_arm, - /obj/item/mecha_parts/part/ripley_left_leg, - /obj/item/mecha_parts/part/ripley_right_leg, - /obj/item/clothing/suit/fire - ) - -/datum/component/construction/mecha/firefighter - result = /obj/mecha/working/ripley/firefighter - base_icon = "fireripley" - steps = list( - //1 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected." - ), - - //2 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected." - ), - - //3 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active." - ), - - //4 - list( - "key" = TOOL_WIRECUTTER, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added." - ), - - //5 - list( - "key" = /obj/item/circuitboard/mecha/ripley/main, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted." - ), - - //6 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Central control module is installed." - ), - - //7 - list( - "key" = /obj/item/circuitboard/mecha/ripley/peripherals, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured." - ), - - //8 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed." - ), - - //9 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured." - ), - - //10 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The scanner module is installed." - ), - - //11 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The scanner module is secured." - ), - - //12 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The capacitor is installed." - ), - - //13 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The capacitor is secured." - ), - - //14 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The power cell is installed." - ), - - //15 - list( - "key" = /obj/item/stack/sheet/plasteel, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The power cell is secured." - ), - - //16 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "Internal armor is installed." - ), - - //17 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched." - ), - - //18 - list( - "key" = /obj/item/stack/sheet/plasteel, - "amount" = 5, - "back_key" = TOOL_WELDER, - "desc" = "Internal armor is welded." - ), - - //19 - list( - "key" = /obj/item/stack/sheet/plasteel, - "amount" = 5, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is being installed." - ), - - //20 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is installed." - ), - - //21 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "External armor is wrenched." - ), - ) - -/datum/component/construction/mecha/firefighter/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - //TODO: better messages. - switch(index) - if(1) - user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") - if(2) - if(diff==FORWARD) - user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") - else - user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") - if(3) - if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") - else - user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") - if(4) - if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") - else - user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") - if(5) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") - if(6) - if(diff==FORWARD) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - else - user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") - if(7) - if(diff==FORWARD) - user.visible_message("[user] installs [I]into [parent].", "You install [I]into [parent].") - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - if(8) - if(diff==FORWARD) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - else - user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") - if(9) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - if(10) - if(diff==FORWARD) - user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") - else - user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") - if(12) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") - if(13) - if(diff==FORWARD) - user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") - else - user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") - if(14) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") - if(15) - if(diff==FORWARD) - user.visible_message("[user] secures the power cell.", "You secure the power cell.") - else - user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") - if(16) - if(diff==FORWARD) - user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") - if(17) - if(diff==FORWARD) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - else - user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") - if(18) - if(diff==FORWARD) - user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - if(19) - if(diff==FORWARD) - user.visible_message("[user] starts to install the external armor layer to [parent].", "You install the external armor layer to [parent].") - else - user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") - if(20) - if(diff==FORWARD) - user.visible_message("[user] installs the external reinforced armor layer to [parent].", "You install the external reinforced armor layer to [parent].") - else - user.visible_message("[user] removes the external armor from [parent].", "You remove the external armor from [parent].") - if(21) - if(diff==FORWARD) - user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") - else - user.visible_message("[user] pries external armor layer from [parent].", "You pry external armor layer from [parent].") - if(22) - if(diff==FORWARD) - user.visible_message("[user] welds the external armor layer to [parent].", "You weld the external armor layer to [parent].") - else - user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") - return TRUE - -/datum/component/construction/unordered/mecha_chassis/honker - result = /datum/component/construction/mecha/honker - steps = list( - /obj/item/mecha_parts/part/honker_torso, - /obj/item/mecha_parts/part/honker_left_arm, - /obj/item/mecha_parts/part/honker_right_arm, - /obj/item/mecha_parts/part/honker_left_leg, - /obj/item/mecha_parts/part/honker_right_leg, - /obj/item/mecha_parts/part/honker_head - ) - - -/datum/component/construction/mecha/honker - result = /obj/mecha/combat/honker - steps = list( - //1 - list( - "key" = /obj/item/bikehorn - ), - - //2 - list( - "key" = /obj/item/circuitboard/mecha/honker/main, - "action" = ITEM_DELETE - ), - - //3 - list( - "key" = /obj/item/bikehorn - ), - - //4 - list( - "key" = /obj/item/circuitboard/mecha/honker/peripherals, - "action" = ITEM_DELETE - ), - - //5 - list( - "key" = /obj/item/bikehorn - ), - - //6 - list( - "key" = /obj/item/circuitboard/mecha/honker/targeting, - "action" = ITEM_DELETE - ), - - //7 - list( - "key" = /obj/item/bikehorn - ), - - //6 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE - ), - - //8 - list( - "key" = /obj/item/bikehorn - ), - - //9 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE - ), - - //10 - list( - "key" = /obj/item/bikehorn - ), - - //11 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE - ), - - //12 - list( - "key" = /obj/item/bikehorn - ), - - //13 - list( - "key" = /obj/item/clothing/mask/gas/clown_hat, - "action" = ITEM_DELETE - ), - - //14 - list( - "key" = /obj/item/bikehorn - ), - - //15 - list( - "key" = /obj/item/clothing/shoes/clown_shoes, - "action" = ITEM_DELETE - ), - - //16 - list( - "key" = /obj/item/bikehorn - ), - ) - -// HONK doesn't have any construction step icons, so we just set an icon once. -/datum/component/construction/mecha/honker/update_parent(step_index) - if(step_index == 1) - var/atom/parent_atom = parent - parent_atom.icon = 'icons/mecha/mech_construct.dmi' - parent_atom.icon_state = "honker_chassis" - ..() -// HONK doesn't have any construction step icons, so we just set an icon once. -/datum/component/construction/mecha/honker/update_parent(step_index) - if(step_index == 1) - var/atom/parent_atom = parent - parent_atom.icon = 'icons/mecha/mech_construct.dmi' - parent_atom.icon_state = "honker_chassis" - ..() - -/datum/component/construction/mecha/honker/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - if(istype(I, /obj/item/bikehorn)) - playsound(parent, 'sound/items/bikehorn.ogg', 50, 1) - user.visible_message("HONK!") - - //TODO: better messages. - switch(index) - if(2) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - if(4) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - if(6) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - if(8) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - if(10) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - if(12) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - if(14) - user.visible_message("[user] puts [I] on [parent].", "You put [I] on [parent].") - if(16) - user.visible_message("[user] puts [I] on [parent].", "You put [I] on [parent].") - return TRUE - -/datum/component/construction/unordered/mecha_chassis/durand - result = /datum/component/construction/mecha/durand - steps = list( - /obj/item/mecha_parts/part/durand_torso, - /obj/item/mecha_parts/part/durand_left_arm, - /obj/item/mecha_parts/part/durand_right_arm, - /obj/item/mecha_parts/part/durand_left_leg, - /obj/item/mecha_parts/part/durand_right_leg, - /obj/item/mecha_parts/part/durand_head - ) - -/datum/component/construction/mecha/durand - result = /obj/mecha/combat/durand - base_icon = "durand" - steps = list( - //1 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected." - ), - - //2 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected." - ), - - //3 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active." - ), - - //4 - list( - "key" = TOOL_WIRECUTTER, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added." - ), - - //5 - list( - "key" = /obj/item/circuitboard/mecha/durand/main, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted." - ), - - //6 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Central control module is installed." - ), - - //7 - list( - "key" = /obj/item/circuitboard/mecha/durand/peripherals, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured." - ), - - //8 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed." - ), - - //9 - list( - "key" = /obj/item/circuitboard/mecha/durand/targeting, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured." - ), - - //10 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Weapon control module is installed." - ), - - //11 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Weapon control module is secured." - ), - - //12 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Scanner module is installed." - ), - - //13 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Scanner module is secured." - ), - - //14 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Capacitor is installed." - ), - - //15 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Capacitor is secured." - ), - - //16 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The power cell is installed." - ), - - //17 - list( - "key" = /obj/item/stack/sheet/metal, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The power cell is secured." - ), - - //18 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "Internal armor is installed." - ), - - //19 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched." - ), - - //20 - list( - "key" = /obj/item/mecha_parts/part/durand_armor, - "action" = ITEM_DELETE, - "back_key" = TOOL_WELDER, - "desc" = "Internal armor is welded." - ), - - //21 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is installed." - ), - - //22 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "External armor is wrenched." - ), - ) - - -/datum/component/construction/mecha/durand/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - //TODO: better messages. - switch(index) - if(1) - user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") - if(2) - if(diff==FORWARD) - user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") - else - user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") - if(3) - if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") - else - user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") - if(4) - if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") - else - user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") - if(5) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") - if(6) - if(diff==FORWARD) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - else - user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") - if(7) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - if(8) - if(diff==FORWARD) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - else - user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") - if(9) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - if(10) - if(diff==FORWARD) - user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") - else - user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") - if(11) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") - if(12) - if(diff==FORWARD) - user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") - else - user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") - if(13) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") - if(14) - if(diff==FORWARD) - user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") - else - user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") - if(15) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") - if(16) - if(diff==FORWARD) - user.visible_message("[user] secures the power cell.", "You secure the power cell.") - else - user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") - if(17) - if(diff==FORWARD) - user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") - if(18) - if(diff==FORWARD) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - else - user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") - if(19) - if(diff==FORWARD) - user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - if(20) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") - if(21) - if(diff==FORWARD) - user.visible_message("[user] secures Durand Armor Plates.", "You secure Durand Armor Plates.") - else - user.visible_message("[user] pries Durand Armor Plates from [parent].", "You pry Durand Armor Plates from [parent].") - if(22) - if(diff==FORWARD) - user.visible_message("[user] welds Durand Armor Plates to [parent].", "You weld Durand Armor Plates to [parent].") - else - user.visible_message("[user] unfastens Durand Armor Plates.", "You unfasten Durand Armor Plates.") - return TRUE - -//PHAZON - -/datum/component/construction/unordered/mecha_chassis/phazon - result = /datum/component/construction/mecha/phazon - steps = list( - /obj/item/mecha_parts/part/phazon_torso, - /obj/item/mecha_parts/part/phazon_left_arm, - /obj/item/mecha_parts/part/phazon_right_arm, - /obj/item/mecha_parts/part/phazon_left_leg, - /obj/item/mecha_parts/part/phazon_right_leg, - /obj/item/mecha_parts/part/phazon_head - ) - -/datum/component/construction/mecha/phazon - result = /obj/mecha/combat/phazon - base_icon = "phazon" - steps = list( - //1 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected." - ), - - //2 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected." - ), - - //3 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active." - ), - - //4 - list( - "key" = TOOL_WIRECUTTER, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added." - ), - - //5 - list( - "key" = /obj/item/circuitboard/mecha/phazon/main, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted." - ), - - //6 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Central control module is installed." - ), - - //7 - list( - "key" = /obj/item/circuitboard/mecha/phazon/peripherals, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured." - ), - - //8 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed" - ), - - //9 - list( - "key" = /obj/item/circuitboard/mecha/phazon/targeting, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured." - ), - - //10 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Weapon control is installed." - ), - - //11 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Weapon control module is secured." - ), - - //12 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Scanner module is installed." - ), - - //13 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Scanner module is secured." - ), - - //14 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Capacitor is installed." - ), - - //15 - list( - "key" = /obj/item/stack/ore/bluespace_crystal, - "amount" = 1, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Capacitor is secured." - ), - - //16 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_CROWBAR, - "desc" = "The bluespace crystal is installed." - ), - - //17 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WIRECUTTER, - "desc" = "The bluespace crystal is connected." - ), - - //18 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The bluespace crystal is engaged." - ), - - //19 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The power cell is installed.", - "icon_state" = "phazon17" - // This is the point where a step icon is skipped, so "icon_state" had to be set manually starting from here. - ), - - //20 - list( - "key" = /obj/item/stack/sheet/plasteel, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The power cell is secured.", - "icon_state" = "phazon18" - ), - - //21 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "Phase armor is installed.", - "icon_state" = "phazon19" - ), - - //22 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "Phase armor is wrenched.", - "icon_state" = "phazon20" - ), - - //23 - list( - "key" = /obj/item/mecha_parts/part/phazon_armor, - "action" = ITEM_DELETE, - "back_key" = TOOL_WELDER, - "desc" = "Phase armor is welded.", - "icon_state" = "phazon21" - ), - - //24 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is installed.", - "icon_state" = "phazon22" - ), - - //25 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "External armor is wrenched.", - "icon_state" = "phazon23" - ), - - //26 - list( - "key" = /obj/item/assembly/signaler/anomaly, - "action" = ITEM_DELETE, - "back_key" = TOOL_WELDER, - "desc" = "Anomaly core socket is open.", - "icon_state" = "phazon24" - ), - ) - - -/datum/component/construction/mecha/phazon/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - //TODO: better messages. - switch(index) - if(1) - user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") - if(2) - if(diff==FORWARD) - user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") - else - user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") - if(3) - if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") - else - user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") - if(4) - if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") - else - user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") - if(5) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") - if(6) - if(diff==FORWARD) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - else - user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") - if(7) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - if(8) - if(diff==FORWARD) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - else - user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") - if(9) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - if(10) - if(diff==FORWARD) - user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") - else - user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") - if(11) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") - if(12) - if(diff==FORWARD) - user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") - else - user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") - if(13) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") - if(14) - if(diff==FORWARD) - user.visible_message("[user] secures [I].", "You secure [I].") - else - user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") - if(15) - if(diff==FORWARD) - user.visible_message("[user] installs [I].", "You install [I].") - else - user.visible_message("[user] unsecures the capacitor from [parent].", "You unsecure the capacitor from [parent].") - if(16) - if(diff==FORWARD) - user.visible_message("[user] connects the bluespace crystal.", "You connect the bluespace crystal.") - else - user.visible_message("[user] removes the bluespace crystal from [parent].", "You remove the bluespace crystal from [parent].") - if(17) - if(diff==FORWARD) - user.visible_message("[user] engages the bluespace crystal.", "You engage the bluespace crystal.") - else - user.visible_message("[user] disconnects the bluespace crystal from [parent].", "You disconnect the bluespace crystal from [parent].") - if(18) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disengages the bluespace crystal.", "You disengage the bluespace crystal.") - if(19) - if(diff==FORWARD) - user.visible_message("[user] secures the power cell.", "You secure the power cell.") - else - user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") - if(20) - if(diff==FORWARD) - user.visible_message("[user] installs the phase armor layer to [parent].", "You install the phase armor layer to [parent].") - else - user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") - if(21) - if(diff==FORWARD) - user.visible_message("[user] secures the phase armor layer.", "You secure the phase armor layer.") - else - user.visible_message("[user] pries the phase armor layer from [parent].", "You pry the phase armor layer from [parent].") - if(22) - if(diff==FORWARD) - user.visible_message("[user] welds the phase armor layer to [parent].", "You weld the phase armor layer to [parent].") - else - user.visible_message("[user] unfastens the phase armor layer.", "You unfasten the phase armor layer.") - if(23) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] cuts phase armor layer from [parent].", "You cut the phase armor layer from [parent].") - if(24) - if(diff==FORWARD) - user.visible_message("[user] secures Phazon Armor Plates.", "You secure Phazon Armor Plates.") - else - user.visible_message("[user] pries Phazon Armor Plates from [parent].", "You pry Phazon Armor Plates from [parent].") - if(25) - if(diff==FORWARD) - user.visible_message("[user] welds Phazon Armor Plates to [parent].", "You weld Phazon Armor Plates to [parent].") - else - user.visible_message("[user] unfastens Phazon Armor Plates.", "You unfasten Phazon Armor Plates.") - if(26) - if(diff==FORWARD) - user.visible_message("[user] carefully inserts the anomaly core into [parent] and secures it.", - "You slowly place the anomaly core into its socket and close its chamber.") - return TRUE - -//ODYSSEUS - -/datum/component/construction/unordered/mecha_chassis/odysseus - result = /datum/component/construction/mecha/odysseus - steps = list( - /obj/item/mecha_parts/part/odysseus_torso, - /obj/item/mecha_parts/part/odysseus_head, - /obj/item/mecha_parts/part/odysseus_left_arm, - /obj/item/mecha_parts/part/odysseus_right_arm, - /obj/item/mecha_parts/part/odysseus_left_leg, - /obj/item/mecha_parts/part/odysseus_right_leg - ) - -/datum/component/construction/mecha/odysseus - result = /obj/mecha/medical/odysseus - base_icon = "odysseus" - steps = list( - //1 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected." - ), - - //2 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected." - ), - - //3 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active." - ), - - //4 - list( - "key" = TOOL_WIRECUTTER, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added." - ), - - //5 - list( - "key" = /obj/item/circuitboard/mecha/odysseus/main, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted." - ), - - //6 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Central control module is installed." - ), - - //7 - list( - "key" = /obj/item/circuitboard/mecha/odysseus/peripherals, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured." - ), - - //8 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed." - ), - //9 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured." - ), - - //10 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Scanner module is installed." - ), - - //11 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Scanner module is secured." - ), - - //12 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Capacitor is installed." - ), - - //13 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Capacitor is secured." - ), - - //11 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The power cell is installed." - ), - - //12 - list( - "key" = /obj/item/stack/sheet/metal, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The power cell is secured." - ), - - //13 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "Internal armor is installed." - ), - - //14 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched." - ), - - //15 - list( - "key" = /obj/item/stack/sheet/plasteel, - "amount" = 5, - "back_key" = TOOL_WELDER, - "desc" = "Internal armor is welded." - ), - - //16 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is installed." - ), - - //17 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "External armor is wrenched." - ), - ) - -/datum/component/construction/mecha/odysseus/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - //TODO: better messages. - switch(index) - if(1) - user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") - if(2) - if(diff==FORWARD) - user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") - else - user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") - if(3) - if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") - else - user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") - if(4) - if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") - else - user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") - if(5) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") - if(6) - if(diff==FORWARD) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - else - user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") - if(7) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - if(8) - if(diff==FORWARD) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - else - user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") - if(9) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - if(10) - if(diff==FORWARD) - user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") - else - user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") - if(11) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") - if(12) - if(diff==FORWARD) - user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") - else - user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") - if(13) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") - if(14) - if(diff==FORWARD) - user.visible_message("[user] secures the power cell.", "You secure the power cell.") - else - user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") - if(15) - if(diff==FORWARD) - user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") - if(16) - if(diff==FORWARD) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - else - user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") - if(17) - if(diff==FORWARD) - user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - if(18) - if(diff==FORWARD) - user.visible_message("[user] installs the external armor layer to [parent].", "You install the external reinforced armor layer to [parent].") - else - user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") - if(19) - if(diff==FORWARD) - user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") - else - user.visible_message("[user] pries the external armor layer from [parent].", "You pry the external armor layer from [parent].") - if(20) - if(diff==FORWARD) - user.visible_message("[user] welds the external armor layer to [parent].", "You weld the external armor layer to [parent].") - else - user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") - return TRUE diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm deleted file mode 100644 index 93a030a004..0000000000 --- a/code/game/mecha/mecha_defense.dm +++ /dev/null @@ -1,334 +0,0 @@ -/obj/mecha/proc/get_armour_facing(relative_dir) - switch(relative_dir) - if(180) // BACKSTAB! - return facing_modifiers[BACK_ARMOUR] - if(0, 45) // direct or 45 degrees off - return facing_modifiers[FRONT_ARMOUR] - return facing_modifiers[SIDE_ARMOUR] //if its not a front hit or back hit then assume its from the side - -/obj/mecha/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) - . = ..() - if(. && obj_integrity > 0) - spark_system.start() - switch(damage_flag) - if("fire") - check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL)) - if("melee") - check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) - else - check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT)) - if(. >= 5 || prob(33)) - occupant_message("Taking damage!") - log_append_to_last("Took [damage_amount] points of damage. Damage type: \"[damage_type]\".",1) - -/obj/mecha/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - . = ..() - if(!damage_amount) - return 0 - var/booster_deflection_modifier = 1 - var/booster_damage_modifier = 1 - if(damage_flag == "bullet" || damage_flag == "laser" || damage_flag == "energy") - for(var/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/B in equipment) - if(B.projectile_react()) - booster_deflection_modifier = B.deflect_coeff - booster_damage_modifier = B.damage_coeff - break - else if(damage_flag == "melee") - for(var/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/B in equipment) - if(B.attack_react()) - booster_deflection_modifier *= B.deflect_coeff - booster_damage_modifier *= B.damage_coeff - break - - if(attack_dir) - var/facing_modifier = get_armour_facing(abs(dir2angle(dir) - dir2angle(attack_dir))) - booster_damage_modifier /= facing_modifier - booster_deflection_modifier *= facing_modifier - if(prob(deflect_chance * booster_deflection_modifier)) - visible_message("[src]'s armour deflects the attack!") - log_append_to_last("Armor saved.") - return 0 - if(.) - . *= booster_damage_modifier - - -/obj/mecha/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) - user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - playsound(loc, 'sound/weapons/tap.ogg', 40, 1, -1) - user.visible_message("[user] hits [name]. Nothing happens", null, null, COMBAT_MESSAGE_RANGE) - mecha_log_message("Attack by hand/paw. Attacker - [user].", color="red") - log_append_to_last("Armor saved.") - -/obj/mecha/attack_paw(mob/user as mob) - return attack_hand(user) - - -/obj/mecha/attack_alien(mob/living/user) - mecha_log_message("Attack by alien. Attacker - [user].", color="red") - playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) - attack_generic(user, 15, BRUTE, "melee", 0) - -/obj/mecha/attack_animal(mob/living/simple_animal/user) - mecha_log_message("Attack by simple animal. Attacker - [user].", color="red") - if(!user.melee_damage_upper && !user.obj_damage) - user.emote("custom", message = "[user.friendly_verb_continuous] [src].") - return 0 - else - var/play_soundeffect = 1 - if(user.environment_smash) - play_soundeffect = 0 - playsound(src, 'sound/effects/bang.ogg', 50, 1) - var/animal_damage = rand(user.melee_damage_lower,user.melee_damage_upper) - if(user.obj_damage) - animal_damage = user.obj_damage - animal_damage = min(animal_damage, 20*user.environment_smash) - attack_generic(user, animal_damage, user.melee_damage_type, "melee", play_soundeffect) - log_combat(user, src, "attacked") - return 1 - - -/obj/mecha/hulk_damage() - return 15 - -/obj/mecha/attack_hulk(mob/living/carbon/human/user) - . = ..() - if(.) - mecha_log_message("Attack by hulk. Attacker - [user].", color="red") - log_combat(user, src, "punched", "hulk powers") - -/obj/mecha/blob_act(obj/structure/blob/B) - take_damage(30, BRUTE, "melee", 0, get_dir(src, B)) - -/obj/mecha/attack_tk() - return - -/obj/mecha/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) //wrapper - mecha_log_message("Hit by [AM].", color="red") - . = ..() - - -/obj/mecha/bullet_act(obj/item/projectile/Proj) //wrapper - mecha_log_message("Hit by projectile. Type: [Proj.name]([Proj.flag]).", color="red") - . = ..() - -/obj/mecha/ex_act(severity, target) - mecha_log_message("Affected by explosion of severity: [severity].", color="red") - if(prob(deflect_chance)) - severity++ - log_append_to_last("Armor saved, changing severity to [severity].") - . = ..() - -/obj/mecha/contents_explosion(severity, target) - severity++ - for(var/X in equipment) - var/obj/item/mecha_parts/mecha_equipment/ME = X - ME.ex_act(severity,target) - for(var/Y in trackers) - var/obj/item/mecha_parts/mecha_tracking/MT = Y - MT.ex_act(severity, target) - if(occupant) - occupant.ex_act(severity,target) - -/obj/mecha/handle_atom_del(atom/A) - if(A == occupant) - occupant = null - icon_state = initial(icon_state)+"-open" - setDir(dir_in) - -/obj/mecha/emp_act(severity) - . = ..() - if (. & EMP_PROTECT_SELF) - return - if(get_charge()) - use_power((cell.charge/3)*(severity*0.005)) - take_damage(severity/3, BURN, "energy", 1) - mecha_log_message("EMP detected", color="red") - - if(istype(src, /obj/mecha/combat)) - mouse_pointer = 'icons/mecha/mecha_mouse-disable.dmi' - occupant?.update_mouse_pointer() - if(!equipment_disabled && occupant) //prevent spamming this message with back-to-back EMPs - to_chat(occupant, "Error -- Connection to equipment control unit has been lost.") - addtimer(CALLBACK(src, /obj/mecha/proc/restore_equipment), 3 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) - equipment_disabled = 1 - -/obj/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(exposed_temperature>max_temperature) - mecha_log_message("Exposed to dangerous temperature.", color="red") - take_damage(5, BURN, 0, 1) - -/obj/mecha/attackby(obj/item/W as obj, mob/user as mob, params) - - if(istype(W, /obj/item/mmi)) - if(mmi_move_inside(W,user)) - to_chat(user, "[src]-[W] interface initialized successfully.") - else - to_chat(user, "[src]-[W] interface initialization failed.") - return - - if(istype(W, /obj/item/mecha_ammo)) - ammo_resupply(W, user) - return - - if(istype(W, /obj/item/mecha_parts/mecha_equipment)) - var/obj/item/mecha_parts/mecha_equipment/E = W - spawn() - if(E.can_attach(src)) - if(!user.temporarilyRemoveItemFromInventory(W)) - return - E.attach(src) - user.visible_message("[user] attaches [W] to [src].", "You attach [W] to [src].") - else - to_chat(user, "You were unable to attach [W] to [src]!") - return - if(W.GetID()) - if(add_req_access || maint_access) - if(internals_access_allowed(user)) - var/obj/item/card/id/id_card - if(istype(W, /obj/item/card/id)) - id_card = W - else - var/obj/item/pda/pda = W - id_card = pda.id - output_maintenance_dialog(id_card, user) - return - else - to_chat(user, "Invalid ID: Access denied.") - else - to_chat(user, "Maintenance protocols disabled by operator.") - else if(W.tool_behaviour == TOOL_WRENCH) - if(state==1) - state = 2 - to_chat(user, "You undo the securing bolts.") - else if(state==2) - state = 1 - to_chat(user, "You tighten the securing bolts.") - return - else if(W.tool_behaviour == TOOL_CROWBAR) - if(state==2) - state = 3 - to_chat(user, "You open the hatch to the power unit.") - else if(state==3) - state=2 - to_chat(user, "You close the hatch to the power unit.") - return - else if(istype(W, /obj/item/stack/cable_coil)) - if(state == 3 && (internal_damage & MECHA_INT_SHORT_CIRCUIT)) - if(W.use_tool(src, user, 0, 2)) - clearInternalDamage(MECHA_INT_SHORT_CIRCUIT) - to_chat(user, "You replace the fused wires.") - else - to_chat(user, "You need two lengths of cable to fix this mech!") - return - else if(W.tool_behaviour == TOOL_SCREWDRIVER && user.a_intent != INTENT_HARM) - if(internal_damage & MECHA_INT_TEMP_CONTROL) - clearInternalDamage(MECHA_INT_TEMP_CONTROL) - to_chat(user, "You repair the damaged temperature controller.") - else if(state==3 && cell) - cell.forceMove(loc) - cell = null - state = 4 - to_chat(user, "You unscrew and pry out the powercell.") - mecha_log_message("Powercell removed") - else if(state==4 && cell) - state=3 - to_chat(user, "You screw the cell in place.") - return - - else if(istype(W, /obj/item/stock_parts/cell)) - if(state==4) - if(!cell) - if(!user.transferItemToLoc(W, src)) - return - var/obj/item/stock_parts/cell/C = W - to_chat(user, "You install the powercell.") - cell = C - mecha_log_message("Powercell installed") - else - to_chat(user, "There's already a powercell installed.") - return - - else if(W.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM) - user.DelayNextAction(CLICK_CD_MELEE) - if(obj_integrity < max_integrity) - if(W.use_tool(src, user, 0, volume=50, amount=1)) - if (internal_damage & MECHA_INT_TANK_BREACH) - clearInternalDamage(MECHA_INT_TANK_BREACH) - to_chat(user, "You repair the damaged gas tank.") - else - user.visible_message("[user] repairs some damage to [name].", "You repair some damage to [src].") - obj_integrity += min(10, max_integrity-obj_integrity) - if(obj_integrity == max_integrity) - to_chat(user, "It looks to be fully repaired now.") - return 1 - else - to_chat(user, "The [name] is at full integrity!") - return 1 - - else if(istype(W, /obj/item/mecha_parts/mecha_tracking)) - var/obj/item/mecha_parts/mecha_tracking/tracker = W - tracker.try_attach_part(user, src) - return - else - return ..() - -/obj/mecha/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1) - mecha_log_message("Attacked by [I]. Attacker - [user]") - return ..() - -/obj/mecha/proc/mech_toxin_damage(mob/living/target) - playsound(src, 'sound/effects/spray2.ogg', 50, 1) - if(target.reagents) - if(target.reagents.get_reagent_amount(/datum/reagent/cryptobiolin) + force < force*2) - target.reagents.add_reagent(/datum/reagent/cryptobiolin, force/2) - if(target.reagents.get_reagent_amount(/datum/reagent/toxin) + force < force*2) - target.reagents.add_reagent(/datum/reagent/toxin, force/2.5) - - -/obj/mecha/mech_melee_attack(obj/mecha/M) - if(!has_charge(melee_energy_drain)) - return 0 - use_power(melee_energy_drain) - if(M.damtype == BRUTE || M.damtype == BURN) - log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") - . = ..() - -/obj/mecha/proc/full_repair(charge_cell) - obj_integrity = max_integrity - if(cell && charge_cell) - cell.charge = cell.maxcharge - if(internal_damage & MECHA_INT_FIRE) - clearInternalDamage(MECHA_INT_FIRE) - if(internal_damage & MECHA_INT_TEMP_CONTROL) - clearInternalDamage(MECHA_INT_TEMP_CONTROL) - if(internal_damage & MECHA_INT_SHORT_CIRCUIT) - clearInternalDamage(MECHA_INT_SHORT_CIRCUIT) - if(internal_damage & MECHA_INT_TANK_BREACH) - clearInternalDamage(MECHA_INT_TANK_BREACH) - if(internal_damage & MECHA_INT_CONTROL_LOST) - clearInternalDamage(MECHA_INT_CONTROL_LOST) - -/obj/mecha/narsie_act() - emp_act(100) - -/obj/mecha/ratvar_act() - if((GLOB.ratvar_awakens || GLOB.clockwork_gateway_activated) && occupant) - if(is_servant_of_ratvar(occupant)) //reward the minion that got a mech by repairing it - full_repair(TRUE) - else - var/mob/living/L = occupant - go_out(TRUE) - if(L) - L.ratvar_act() - -/obj/mecha/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) - if(!no_effect) - if(selected) - used_item = selected - else if(!visual_effect_icon) - visual_effect_icon = ATTACK_EFFECT_SMASH - if(damtype == BURN) - visual_effect_icon = ATTACK_EFFECT_MECHFIRE - else if(damtype == TOX) - visual_effect_icon = ATTACK_EFFECT_MECHTOXIN - ..() diff --git a/code/game/mecha/mecha_topic.dm b/code/game/mecha/mecha_topic.dm deleted file mode 100644 index 067cffd319..0000000000 --- a/code/game/mecha/mecha_topic.dm +++ /dev/null @@ -1,360 +0,0 @@ - -//////////////////////////////////// -///// Rendering stats window /////// -//////////////////////////////////// - -/obj/mecha/proc/get_stats_html() - . = {" - - - [name] data - - - - -
    - [src.get_stats_part()] -
    -
    - [src.get_equipment_list()] -
    -
    -
    - [src.get_commands()] -
    - - - "} - - - -/obj/mecha/proc/report_internal_damage() - . = "" - var/list/dam_reports = list( - "[MECHA_INT_FIRE]" = "INTERNAL FIRE", - "[MECHA_INT_TEMP_CONTROL]" = "LIFE SUPPORT SYSTEM MALFUNCTION", - "[MECHA_INT_TANK_BREACH]" = "GAS TANK BREACH", - "[MECHA_INT_CONTROL_LOST]" = "COORDINATION SYSTEM CALIBRATION FAILURE - Recalibrate", - "[MECHA_INT_SHORT_CIRCUIT]" = "SHORT CIRCUIT" - ) - for(var/tflag in dam_reports) - var/intdamflag = text2num(tflag) - if(internal_damage & intdamflag) - . += dam_reports[tflag] - . += "
    " - if(return_pressure() > WARNING_HIGH_PRESSURE) - . += "DANGEROUSLY HIGH CABIN PRESSURE
    " - - - -/obj/mecha/proc/get_stats_part() - var/integrity = obj_integrity/max_integrity*100 - var/cell_charge = get_charge() - var/datum/gas_mixture/int_tank_air = internal_tank.return_air() - var/tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None" - var/tank_temperature = internal_tank ? int_tank_air.return_temperature() : "Unknown" - var/cabin_pressure = round(return_pressure(),0.01) - . = {"[report_internal_damage()] - [integrity<30?"DAMAGE LEVEL CRITICAL
    ":null] - Integrity: [integrity]%
    - Powercell charge: [isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]
    - Air source: [use_internal_tank?"Internal Airtank":"Environment"]
    - Airtank pressure: [tank_pressure]kPa
    - Airtank temperature: [tank_temperature]°K|[tank_temperature - T0C]°C
    - Cabin pressure: [cabin_pressure>WARNING_HIGH_PRESSURE ? "[cabin_pressure]": cabin_pressure]kPa
    - Cabin temperature: [return_temperature()]°K|[return_temperature() - T0C]°C
    - [dna_lock?"DNA-locked:
    [dna_lock] \[Reset\]
    ":""]
    - [thrusters_action.owner ? "Thrusters: [thrusters_active ? "Enabled" : "Disabled"]
    " : ""] - [defense_action.owner ? "Defence Mode: [defence_mode ? "Enabled" : "Disabled"]
    " : ""] - [overload_action.owner ? "Leg Actuators Overload: [leg_overload_mode ? "Enabled" : "Disabled"]
    " : ""] - [smoke_action.owner ? "Smoke: [smoke]
    " : ""] - [zoom_action.owner ? "Zoom: [zoom_mode ? "Enabled" : "Disabled"]
    " : ""] - [switch_damtype_action.owner ? "Damtype: [damtype]
    " : ""] - [phasing_action.owner ? "Phase Modulator: [phasing ? "Enabled" : "Disabled"]
    " : ""] - "} - - -/obj/mecha/proc/get_commands() - . = {"
    -
    Electronics
    - -
    - -
    [get_equipment_menu()]
    - "} - - -/obj/mecha/proc/get_equipment_menu() //outputs mecha html equipment menu - . = "" - if(equipment.len) - . += {"
    -
    Equipment
    -
    " - - -/obj/mecha/proc/get_equipment_list() //outputs mecha equipment list in html - if(!equipment.len) - return - . = "Equipment:
    " - for(var/obj/item/mecha_parts/mecha_equipment/MT in equipment) - . += "
    [MT.get_equip_info()]
    " - . += "
    " - - - -/obj/mecha/proc/get_log_html() - . = "[src.name] Log" - for(var/list/entry in log) - . += {"
    [entry["time"]] [time2text(entry["date"],"MMM DD")] [entry["year"]]
    -
    [entry["message"]]
    - "} - . += "" - - - -/obj/mecha/proc/output_access_dialog(obj/item/card/id/id_card, mob/user) - if(!id_card || !user) - return - . = {" - - - - - -

    Following keycodes are present in this system:

    "} - for(var/a in operation_req_access) - . += "[get_access_desc(a)] - Delete
    " - . += "

    Following keycodes were detected on portable device:

    " - for(var/a in id_card.access) - if(a in operation_req_access) - continue - var/a_name = get_access_desc(a) - if(!a_name) - continue //there's some strange access without a name - . += "[a_name] - Add
    " - . += "
    Finish " - . += "(Warning! The ID upload panel will be locked. It can be unlocked only through Exosuit Interface.)" - . += "" - user << browse(., "window=exosuit_add_access") - onclose(user, "exosuit_add_access") - - -/obj/mecha/proc/output_maintenance_dialog(obj/item/card/id/id_card,mob/user) - if(!id_card || !user) - return - . = {" - - - - - - [add_req_access?"Edit operation keycodes":null] - [maint_access?"[(state>0) ? "Terminate" : "Initiate"] maintenance protocol":null] - [(state>0) ?"Set Cabin Air Pressure":null] - - "} - user << browse(., "window=exosuit_maint_console") - onclose(user, "exosuit_maint_console") - - - - -///////////////// -///// Topic ///// -///////////////// - -/obj/mecha/Topic(href, href_list) - ..() - if(href_list["close"]) - return - - if(usr.incapacitated()) - return - - if(in_range(src, usr)) - var/obj/item/card/id/id_card - if (href_list["id_card"]) - id_card = locate(href_list["id_card"]) - if (!istype(id_card)) - return - - if(href_list["req_access"] && add_req_access) - output_access_dialog(id_card, usr) - - if(href_list["maint_access"] && maint_access) - if(state==0) - state = 1 - to_chat(usr, "The securing bolts are now exposed.") - else if(state==1) - state = 0 - to_chat(usr, "The securing bolts are now hidden.") - output_maintenance_dialog(id_card, usr) - - if(href_list["set_internal_tank_valve"] && state >=1) - var/new_pressure = input(usr,"Input new output pressure","Pressure setting",internal_tank_valve) as num - if(new_pressure) - internal_tank_valve = new_pressure - to_chat(usr, "The internal pressure valve has been set to [internal_tank_valve]kPa.") - - if(href_list["add_req_access"] && add_req_access) - operation_req_access += text2num(href_list["add_req_access"]) - output_access_dialog(id_card, usr) - - if(href_list["del_req_access"] && add_req_access) - operation_req_access -= text2num(href_list["del_req_access"]) - output_access_dialog(id_card, usr) - - if(href_list["finish_req_access"]) - add_req_access = 0 - usr << browse(null,"window=exosuit_add_access") - - if(usr != occupant) - return - - if(href_list["update_content"]) - send_byjax(usr,"exosuit.browser","content",src.get_stats_part()) - - if(href_list["select_equip"]) - var/obj/item/mecha_parts/mecha_equipment/equip = locate(href_list["select_equip"]) in src - if(equip && equip.selectable) - selected = equip - occupant_message("You switch to [equip]") - visible_message("[src] raises [equip]") - send_byjax(usr, "exosuit.browser","eq_list", get_equipment_list()) - - if(href_list["rmictoggle"]) - radio.broadcasting = !radio.broadcasting - send_byjax(usr,"exosuit.browser","rmicstate",(radio.broadcasting?"Engaged":"Disengaged")) - - if(href_list["rspktoggle"]) - radio.listening = !radio.listening - send_byjax(usr,"exosuit.browser","rspkstate",(radio.listening?"Engaged":"Disengaged")) - - if(href_list["rfreq"]) - var/new_frequency = (radio.frequency + text2num(href_list["rfreq"])) - if (!radio.freerange || (radio.frequency < MIN_FREE_FREQ || radio.frequency > MAX_FREE_FREQ)) - new_frequency = sanitize_frequency(new_frequency) - radio.set_frequency(new_frequency) - send_byjax(usr,"exosuit.browser","rfreq","[format_frequency(radio.frequency)]") - - if (href_list["view_log"]) - src.occupant << browse(src.get_log_html(), "window=exosuit_log") - onclose(occupant, "exosuit_log") - - if (href_list["change_name"]) - var/userinput = stripped_input(occupant,"Choose new exosuit name","Rename exosuit","", MAX_NAME_LEN) - if(!userinput || usr != occupant || usr.incapacitated()) - return - name = userinput - return - - if (href_list["toggle_id_upload"]) - add_req_access = !add_req_access - send_byjax(usr,"exosuit.browser","t_id_upload","[add_req_access?"L":"Unl"]ock ID upload panel") - - if(href_list["toggle_maint_access"]) - if(state) - occupant_message("Maintenance protocols in effect") - return - maint_access = !maint_access - send_byjax(usr,"exosuit.browser","t_maint_access","[maint_access?"Forbid":"Permit"] maintenance protocols") - - if (href_list["toggle_port_connection"]) - if(internal_tank.connected_port) - if(internal_tank.disconnect()) - occupant_message("Disconnected from the air system port.") - mecha_log_message("Disconnected from gas port.") - else - occupant_message("Unable to disconnect from the air system port!") - return - else - var/obj/machinery/atmospherics/components/unary/portables_connector/possible_port = locate() in loc - if(internal_tank.connect(possible_port)) - occupant_message("Connected to the air system port.") - mecha_log_message("Connected to gas port.") - else - occupant_message("Unable to connect with air system port!") - return - send_byjax(occupant,"exosuit.browser","t_port_connection","[internal_tank.connected_port?"Disconnect from":"Connect to"] gas port") - - if(href_list["dna_lock"]) - if(!occupant) - return - var/mob/living/carbon/C = occupant - if(!istype(C) || !C.dna) - to_chat(C, " You do not have any DNA!") - return - dna_lock = C.dna.unique_enzymes - occupant_message("You feel a prick as the needle takes your DNA sample.") - - if(href_list["reset_dna"]) - dna_lock = null - - if(href_list["repair_int_control_lost"]) - occupant_message("Recalibrating coordination system...") - mecha_log_message("Recalibration of coordination system started.") - var/T = loc - spawn(100) - if(T == loc) - clearInternalDamage(MECHA_INT_CONTROL_LOST) - occupant_message("Recalibration successful.") - mecha_log_message("Recalibration of coordination system finished with 0 errors.") - else - occupant_message("Recalibration failed!") - mecha_log_message("Recalibration of coordination system failed with 1 error.", color="red") - diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm deleted file mode 100644 index 36584b85ec..0000000000 --- a/code/game/mecha/mecha_wreckage.dm +++ /dev/null @@ -1,271 +0,0 @@ -/////////////////////////////////// -//////// Mecha wreckage //////// -/////////////////////////////////// - - -/obj/structure/mecha_wreckage - name = "exosuit wreckage" - desc = "Remains of some unfortunate mecha. Completely irreparable, but perhaps something can be salvaged." - icon = 'icons/mecha/mecha.dmi' - density = TRUE - anchored = FALSE - opacity = 0 - var/list/welder_salvage = list(/obj/item/stack/sheet/plasteel, /obj/item/stack/sheet/metal, /obj/item/stack/rods) - var/list/wirecutters_salvage = list(/obj/item/stack/cable_coil) - var/list/crowbar_salvage = list() - var/salvage_num = 5 - var/mob/living/silicon/ai/AI //AIs to be salvaged - -/obj/structure/mecha_wreckage/Initialize(mapload, mob/living/silicon/ai/AI_pilot) - . = ..() - if(!AI_pilot) //Type-checking for this is already done in mecha/Destroy() - return - - AI = AI_pilot - AI.apply_damage(150, BURN) //Give the AI a bit of damage from the "shock" of being suddenly shut down - AI.death() //The damage is not enough to kill the AI, but to be 'corrupted files' in need of repair. - AI.forceMove(src) //Put the dead AI inside the wreckage for recovery - add_overlay(mutable_appearance('icons/obj/projectiles.dmi', "green_laser")) //Overlay for the recovery beacon - AI.controlled_mech = null - AI.remote_control = null - -/obj/structure/mecha_wreckage/examine(mob/user) - . = ..() - if(AI) - . += "The AI recovery beacon is active." - -/obj/structure/mecha_wreckage/attackby(obj/item/I, mob/user, params) - if(I.tool_behaviour == TOOL_WELDER) - if(salvage_num <= 0 || !length(welder_salvage)) - to_chat(user, "You don't see anything that can be cut with [I]!") - return - - if(!I.use_tool(src, user, 0, volume=50)) - return - - var/type = prob(70) ? pick(welder_salvage) : null - if(type) - var/N = new type(get_turf(user)) - user.visible_message("[user] cuts [N] from [src].", "You cut [N] from [src].") - if(istype(N, /obj/item/mecha_parts/part)) - welder_salvage -= type - salvage_num-- - else - to_chat(user, "You fail to salvage anything valuable from [src]!") - return - - else if(I.tool_behaviour == TOOL_WIRECUTTER) - if(salvage_num <= 0) - to_chat(user, "You don't see anything that can be cut with [I]!") - return - else if(wirecutters_salvage && wirecutters_salvage.len) - var/type = prob(70) ? pick(wirecutters_salvage) : null - if(type) - var/N = new type(get_turf(user)) - user.visible_message("[user] cuts [N] from [src].", "You cut [N] from [src].") - salvage_num-- - else - to_chat(user, "You fail to salvage anything valuable from [src]!") - - else if(I.tool_behaviour == TOOL_CROWBAR) - if(crowbar_salvage && crowbar_salvage.len) - var/obj/S = pick(crowbar_salvage) - if(S) - S.forceMove(user.drop_location()) - crowbar_salvage -= S - user.visible_message("[user] pries [S] from [src].", "You pry [S] from [src].") - return - else - to_chat(user, "You don't see anything that can be pried with [I]!") - - -/obj/structure/mecha_wreckage/transfer_ai(interaction, mob/user, null, obj/item/aicard/card) - if(!..()) - return - - //Proc called on the wreck by the AI card. - if(interaction == AI_TRANS_TO_CARD) //AIs can only be transferred in one direction, from the wreck to the card. - if(!AI) //No AI in the wreck - to_chat(user, "No AI backups found.") - return - cut_overlays() //Remove the recovery beacon overlay - AI.forceMove(card) //Move the dead AI to the card. - card.AI = AI - if(AI.client) //AI player is still in the dead AI and is connected - to_chat(AI, "The remains of your file system have been recovered on a mobile storage device.") - else //Give the AI a heads-up that it is probably going to get fixed. - AI.notify_ghost_cloning("You have been recovered from the wreckage!", source = card) - to_chat(user, "Backup files recovered: [AI.name] ([rand(1000,9999)].exe) salvaged from [name] and stored within local memory.") - - else - return ..() - - -/obj/structure/mecha_wreckage/gygax - name = "\improper Gygax wreckage" - icon_state = "gygax-broken" - -/obj/structure/mecha_wreckage/gygax/Initialize() - . = ..() - var/list/parts = list(/obj/item/mecha_parts/part/gygax_torso, - /obj/item/mecha_parts/part/gygax_head, - /obj/item/mecha_parts/part/gygax_left_arm, - /obj/item/mecha_parts/part/gygax_right_arm, - /obj/item/mecha_parts/part/gygax_left_leg, - /obj/item/mecha_parts/part/gygax_right_leg) - for(var/i = 0; i < 2; i++) - if(parts.len && prob(40)) - var/part = pick(parts) - welder_salvage += part - parts -= part - - - -/obj/structure/mecha_wreckage/gygax/dark - name = "\improper Dark Gygax wreckage" - icon_state = "darkgygax-broken" - -/obj/structure/mecha_wreckage/medigax - name = "\improper Medical Gygax wreckage" - icon_state = "medigax-broken" - -/obj/structure/mecha_wreckage/medigax/Initialize() - . = ..() - var/list/parts = list(/obj/item/mecha_parts/part/medigax_torso, - /obj/item/mecha_parts/part/medigax_head, - /obj/item/mecha_parts/part/medigax_left_arm, - /obj/item/mecha_parts/part/medigax_right_arm, - /obj/item/mecha_parts/part/medigax_left_leg, - /obj/item/mecha_parts/part/medigax_right_leg) - for(var/i = 0; i < 2; i++) - if(parts.len && prob(40)) - var/part = pick(parts) - welder_salvage += part - parts -= part - -/obj/structure/mecha_wreckage/marauder - name = "\improper Marauder wreckage" - icon_state = "marauder-broken" - -/obj/structure/mecha_wreckage/mauler - name = "\improper Mauler wreckage" - icon_state = "mauler-broken" - desc = "The syndicate won't be very happy about this..." - -/obj/structure/mecha_wreckage/seraph - name = "\improper Seraph wreckage" - icon_state = "seraph-broken" - -/obj/structure/mecha_wreckage/reticence - name = "\improper Reticence wreckage" - icon_state = "reticence-broken" - color = "#87878715" - desc = "..." - -/obj/structure/mecha_wreckage/ripley - name = "\improper Ripley wreckage" - icon_state = "ripley-broken" - -/obj/structure/mecha_wreckage/ripley/Initialize() - . = ..() - var/list/parts = list(/obj/item/mecha_parts/part/ripley_torso, - /obj/item/mecha_parts/part/ripley_left_arm, - /obj/item/mecha_parts/part/ripley_right_arm, - /obj/item/mecha_parts/part/ripley_left_leg, - /obj/item/mecha_parts/part/ripley_right_leg) - for(var/i = 0; i < 2; i++) - if(parts.len && prob(40)) - var/part = pick(parts) - welder_salvage += part - parts -= part - - -/obj/structure/mecha_wreckage/ripley/firefighter - name = "\improper Firefighter wreckage" - icon_state = "firefighter-broken" - -/obj/structure/mecha_wreckage/ripley/firefighter/Initialize() - . = ..() - var/list/parts = list(/obj/item/mecha_parts/part/ripley_torso, - /obj/item/mecha_parts/part/ripley_left_arm, - /obj/item/mecha_parts/part/ripley_right_arm, - /obj/item/mecha_parts/part/ripley_left_leg, - /obj/item/mecha_parts/part/ripley_right_leg, - /obj/item/clothing/suit/fire) - for(var/i = 0; i < 2; i++) - if(parts.len && prob(40)) - var/part = pick(parts) - welder_salvage += part - parts -= part - - -/obj/structure/mecha_wreckage/ripley/deathripley - name = "\improper Death-Ripley wreckage" - icon_state = "deathripley-broken" - - -/obj/structure/mecha_wreckage/honker - name = "\improper H.O.N.K wreckage" - icon_state = "honker-broken" - desc = "All is right in the universe." - -/obj/structure/mecha_wreckage/honker/Initialize() - . = ..() - var/list/parts = list( - /obj/item/mecha_parts/chassis/honker, - /obj/item/mecha_parts/part/honker_torso, - /obj/item/mecha_parts/part/honker_head, - /obj/item/mecha_parts/part/honker_left_arm, - /obj/item/mecha_parts/part/honker_right_arm, - /obj/item/mecha_parts/part/honker_left_leg, - /obj/item/mecha_parts/part/honker_right_leg) - for(var/i = 0; i < 2; i++) - if(parts.len && prob(40)) - var/part = pick(parts) - welder_salvage += part - parts -= part - - -/obj/structure/mecha_wreckage/durand - name = "\improper Durand wreckage" - icon_state = "durand-broken" - -/obj/structure/mecha_wreckage/durand/Initialize() - . = ..() - var/list/parts = list( - /obj/item/mecha_parts/part/durand_torso, - /obj/item/mecha_parts/part/durand_head, - /obj/item/mecha_parts/part/durand_left_arm, - /obj/item/mecha_parts/part/durand_right_arm, - /obj/item/mecha_parts/part/durand_left_leg, - /obj/item/mecha_parts/part/durand_right_leg) - for(var/i = 0; i < 2; i++) - if(parts.len && prob(40)) - var/part = pick(parts) - welder_salvage += part - parts -= part - - -/obj/structure/mecha_wreckage/phazon - name = "\improper Phazon wreckage" - icon_state = "phazon-broken" - - -/obj/structure/mecha_wreckage/odysseus - name = "\improper Odysseus wreckage" - icon_state = "odysseus-broken" - -/obj/structure/mecha_wreckage/odysseus/Initialize() - . = ..() - var/list/parts = list( - /obj/item/mecha_parts/part/odysseus_torso, - /obj/item/mecha_parts/part/odysseus_head, - /obj/item/mecha_parts/part/odysseus_left_arm, - /obj/item/mecha_parts/part/odysseus_right_arm, - /obj/item/mecha_parts/part/odysseus_left_leg, - /obj/item/mecha_parts/part/odysseus_right_leg) - for(var/i = 0; i < 2; i++) - if(parts.len && prob(40)) - var/part = pick(parts) - welder_salvage += part - parts -= part diff --git a/code/game/mecha/medical/medical.dm b/code/game/mecha/medical/medical.dm deleted file mode 100644 index 8b4e48cd3e..0000000000 --- a/code/game/mecha/medical/medical.dm +++ /dev/null @@ -1,16 +0,0 @@ -/obj/mecha/medical/mechturn(direction) - setDir(direction) - playsound(src,'sound/mecha/mechmove01.ogg',40,1) - return 1 - -/obj/mecha/medical/mechstep(direction) - var/result = step(src,direction) - if(result) - playsound(src,'sound/mecha/mechstep.ogg',25,1) - return result - -/obj/mecha/medical/mechsteprand() - var/result = step_rand(src) - if(result) - playsound(src,'sound/mecha/mechstep.ogg',25,1) - return result diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm deleted file mode 100644 index 5f54f0c93d..0000000000 --- a/code/game/mecha/working/ripley.dm +++ /dev/null @@ -1,188 +0,0 @@ -/obj/mecha/working/ripley - desc = "Autonomous Power Loader Unit. This newer model is refitted with powerful armour against the dangers of planetary mining." - name = "\improper APLU \"Ripley\"" - icon_state = "ripley" - step_in = 3 //Move speed, lower is faster. - var/fast_pressure_step_in = 2 - var/slow_pressure_step_in = 3 - max_temperature = 20000 - max_integrity = 200 - lights_power = 8 - deflect_chance = 15 - armor = list("melee" = 30, "bullet" = 15, "laser" = 10, "energy" = 20, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - max_equip = 6 - wreckage = /obj/structure/mecha_wreckage/ripley - var/list/cargo = new - var/cargo_capacity = 15 - var/hides = 0 - -/obj/mecha/working/ripley/Move() - . = ..() - if(.) - collect_ore() - update_pressure() - -/obj/mecha/working/ripley/proc/collect_ore() - if(locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in equipment) - var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in cargo - if(ore_box) - for(var/obj/item/stack/ore/ore in range(1, src)) - if(ore.Adjacent(src) && ((get_dir(src, ore) & dir) || ore.loc == loc)) //we can reach it and it's in front of us? grab it! - ore.forceMove(ore_box) - -/obj/mecha/working/ripley/Destroy() - for(var/atom/movable/A in cargo) - A.forceMove(drop_location()) - step_rand(A) - cargo.Cut() - return ..() - -/obj/mecha/working/ripley/go_out() - ..() - update_icon() - -/obj/mecha/working/ripley/moved_inside(mob/living/carbon/human/H) - ..() - update_icon() - -/obj/mecha/working/ripley/Initialize() - . = ..() - AddComponent(/datum/component/armor_plate,3,/obj/item/stack/sheet/animalhide/goliath_hide,list("melee" = 10, "bullet" = 5, "laser" = 5)) - - -/obj/mecha/working/ripley/firefighter - desc = "Autonomous Power Loader Unit. This model is refitted with additional thermal protection." - name = "\improper APLU \"Firefighter\"" - icon_state = "firefighter" - step_in = 4 - fast_pressure_step_in = 2 - slow_pressure_step_in = 4 - max_temperature = 65000 - max_integrity = 250 - resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - lights_power = 7 - armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - max_equip = 5 // More armor, less tools - wreckage = /obj/structure/mecha_wreckage/ripley/firefighter - - -/obj/mecha/working/ripley/deathripley - desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE" - name = "\improper DEATH-RIPLEY" - icon_state = "deathripley" - armor = list("melee" = 40, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - slow_pressure_step_in = 3 - opacity=0 - lights_power = 7 - wreckage = /obj/structure/mecha_wreckage/ripley/deathripley - step_energy_drain = 0 - -/obj/mecha/working/ripley/deathripley/Initialize() - . = ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill - ME.attach(src) - -/obj/mecha/working/ripley/deathripley/real - desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE. FOR REAL" - -/obj/mecha/working/ripley/deathripley/real/Initialize() - . = ..() - for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) - E.detach() - qdel(E) - equipment.Cut() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/real - ME.attach(src) - -/obj/mecha/working/ripley/mining - desc = "An old, dusty mining Ripley." - name = "\improper APLU \"Miner\"" - obj_integrity = 75 //Low starting health - -/obj/mecha/working/ripley/mining/Initialize() - . = ..() - if(cell) - cell.charge = FLOOR(cell.charge * 0.25, 1) //Starts at very low charge - if(prob(70)) //Maybe add a drill - if(prob(15)) //Possible diamond drill... Feeling lucky? - var/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill/D = new - D.attach(src) - else - var/obj/item/mecha_parts/mecha_equipment/drill/D = new - D.attach(src) - - else //Add plasma cutter if no drill - var/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma/P = new - P.attach(src) - - //Add ore box to cargo - cargo.Add(new /obj/structure/ore_box(src)) - - //Attach hydraulic clamp - var/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/HC = new - HC.attach(src) - for(var/obj/item/mecha_parts/mecha_tracking/B in trackers)//Deletes the beacon so it can't be found easily - qdel(B) - - var/obj/item/mecha_parts/mecha_equipment/mining_scanner/scanner = new - scanner.attach(src) - -/obj/mecha/working/ripley/Exit(atom/movable/O) - if(O in cargo) - return 0 - return ..() - -/obj/mecha/working/ripley/Topic(href, href_list) - ..() - if(href_list["drop_from_cargo"]) - var/obj/O = locate(href_list["drop_from_cargo"]) - if(O && (O in cargo)) - occupant_message("You unload [O].") - O.forceMove(drop_location()) - cargo -= O - mecha_log_message("Unloaded [O]. Cargo compartment capacity: [cargo_capacity - src.cargo.len]") - return - - -/obj/mecha/working/ripley/contents_explosion(severity, target) - for(var/X in cargo) - var/obj/O = X - if(prob(30/severity)) - cargo -= O - O.forceMove(drop_location()) - . = ..() - -/obj/mecha/working/ripley/get_stats_part() - var/output = ..() - output += "Cargo Compartment Contents:
    " - if(cargo.len) - for(var/obj/O in cargo) - output += "Unload : [O]
    " - else - output += "Nothing" - output += "
    " - return output - -/obj/mecha/working/ripley/proc/update_pressure() - var/turf/T = get_turf(loc) - - if(lavaland_equipment_pressure_check(T)) - step_in = fast_pressure_step_in - for(var/obj/item/mecha_parts/mecha_equipment/drill/drill in equipment) - drill.equip_cooldown = initial(drill.equip_cooldown)/2 - else - step_in = slow_pressure_step_in - for(var/obj/item/mecha_parts/mecha_equipment/drill/drill in equipment) - drill.equip_cooldown = initial(drill.equip_cooldown) - -/obj/mecha/working/ripley/relay_container_resist(mob/living/user, obj/O) - to_chat(user, "You lean on the back of [O] and start pushing so it falls out of [src].") - if(do_after(user, 300, target = O)) - if(!user || user.stat != CONSCIOUS || user.loc != src || O.loc != src ) - return - to_chat(user, "You successfully pushed [O] out of [src]!") - O.forceMove(drop_location()) - cargo -= O - else - if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded. - to_chat(user, "You fail to push [O] out of [src]!") diff --git a/code/game/mecha/working/working.dm b/code/game/mecha/working/working.dm deleted file mode 100644 index c9e7d99ac0..0000000000 --- a/code/game/mecha/working/working.dm +++ /dev/null @@ -1,3 +0,0 @@ -/obj/mecha/working - internal_damage_threshold = 60 - diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 66579c90f3..39f68bc97c 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -69,7 +69,7 @@ /obj/effect/anomaly/proc/detonate() return -/obj/effect/anomaly/ex_act(severity, target) +/obj/effect/anomaly/ex_act(severity, target, origin) if(severity == 1) qdel(src) diff --git a/code/game/objects/effects/arachnid_web.dm b/code/game/objects/effects/arachnid_web.dm index 2adaa12dc9..bd91624ee5 100644 --- a/code/game/objects/effects/arachnid_web.dm +++ b/code/game/objects/effects/arachnid_web.dm @@ -16,7 +16,7 @@ playsound(loc, 'sound/items/welder.ogg', 100, TRUE) /obj/structure/arachnid/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee") + if(damage_flag == MELEE) switch(damage_type) if(BURN) damage_amount *= 2 @@ -49,7 +49,7 @@ density = FALSE max_integrity = 60 -/obj/structure/arachnid/cocoon/Initialize() +/obj/structure/arachnid/cocoon/Initialize(mapload) icon_state = pick("cocoon1","cocoon2","cocoon3") . = ..() diff --git a/code/game/objects/effects/bump_teleporter.dm b/code/game/objects/effects/bump_teleporter.dm index 0337b076ff..36320f2913 100644 --- a/code/game/objects/effects/bump_teleporter.dm +++ b/code/game/objects/effects/bump_teleporter.dm @@ -11,7 +11,7 @@ var/static/list/AllTeleporters -/obj/effect/bump_teleporter/Initialize() +/obj/effect/bump_teleporter/Initialize(mapload) . = ..() LAZYADD(AllTeleporters, src) diff --git a/code/game/objects/effects/contraband.dm b/code/game/objects/effects/contraband.dm index 846132a2fc..260074c5e7 100644 --- a/code/game/objects/effects/contraband.dm +++ b/code/game/objects/effects/contraband.dm @@ -35,7 +35,7 @@ /obj/item/poster/random_contraband name = "random contraband poster" poster_type = /obj/structure/sign/poster/contraband/random - icon_state = "rolled_poster" + icon_state = "rolled_contraband" /obj/item/poster/random_official name = "random official poster" @@ -61,7 +61,7 @@ var/poster_item_icon_state = "rolled_poster" var/poster_item_type = /obj/item/poster -/obj/structure/sign/poster/Initialize() +/obj/structure/sign/poster/Initialize(mapload) . = ..() if(random_basetype) randomise(random_basetype) @@ -181,7 +181,7 @@ /obj/structure/sign/poster/contraband poster_item_name = "contraband poster" poster_item_desc = "This poster comes with its own automatic adhesive mechanism, for easy pinning to any vertical surface. Its vulgar themes have marked it as contraband aboard Nanotrasen space facilities." - poster_item_icon_state = "rolled_poster" + poster_item_icon_state = "rolled_contraband" /obj/structure/sign/poster/contraband/random name = "random contraband poster" @@ -192,248 +192,293 @@ /obj/structure/sign/poster/contraband/free_tonto name = "Free Tonto" desc = "A salvaged shred of a much larger flag, colors bled together and faded from age." - icon_state = "poster1" + icon_state = "poster_2012" /obj/structure/sign/poster/contraband/atmosia_independence name = "Atmosia Declaration of Independence" desc = "A relic of a failed rebellion." - icon_state = "poster2" + icon_state = "poster_independence" /obj/structure/sign/poster/contraband/fun_police name = "Fun Police" desc = "A poster condemning the station's security forces." - icon_state = "poster3" + icon_state = "poster_funpolice" /obj/structure/sign/poster/contraband/lusty_xenomorph name = "Lusty Xenomorph" desc = "A heretical poster depicting the titular star of an equally heretical book." - icon_state = "poster4" + icon_state = "poster_lusty" /obj/structure/sign/poster/contraband/post_ratvar name = "Post This Ratvar" - desc = "Oh what in the hell? Those cultists have animated paper technology and they use it for a meme?" - icon_state = "postvar" + desc = "A poster depicting the heritical sleeping deity Ratvar that instructs the reader to 'post this Ratvar', whatever that means." + icon_state = "poster_ratvar" /obj/structure/sign/poster/contraband/syndicate_recruitment name = "Syndicate Recruitment" desc = "See the galaxy! Shatter corrupt megacorporations! Join today!" - icon_state = "poster5" + icon_state = "poster_syndie" /obj/structure/sign/poster/contraband/clown name = "Clown" desc = "Honk." - icon_state = "poster6" + icon_state = "poster_honk" /obj/structure/sign/poster/contraband/smoke name = "Smoke" desc = "A poster advertising a rival corporate brand of cigarettes." - icon_state = "poster7" + icon_state = "poster_smoke" /obj/structure/sign/poster/contraband/grey_tide name = "Grey Tide" desc = "A rebellious poster symbolizing assistant solidarity." - icon_state = "poster8" + icon_state = "poster_greytide" /obj/structure/sign/poster/contraband/missing_gloves name = "Missing Gloves" desc = "This poster references the uproar that followed Nanotrasen's financial cuts toward insulated-glove purchases." - icon_state = "poster9" + icon_state = "poster_gloves" /obj/structure/sign/poster/contraband/hacking_guide name = "Hacking Guide" desc = "This poster details the internal workings of the common Nanotrasen airlock. Sadly, it appears out of date." - icon_state = "poster10" + icon_state = "poster_hack" /obj/structure/sign/poster/contraband/rip_badger name = "RIP Badger" desc = "This seditious poster references Nanotrasen's genocide of a space station full of badgers." - icon_state = "poster11" + icon_state = "poster_badger" /obj/structure/sign/poster/contraband/ambrosia_vulgaris name = "Ambrosia Vulgaris" desc = "This poster is lookin' pretty trippy man." - icon_state = "poster12" + icon_state = "poster_ambrosia" /obj/structure/sign/poster/contraband/donut_corp name = "Donut Corp." desc = "This poster is an unauthorized advertisement for Donut Corp." - icon_state = "poster13" + icon_state = "poster_donut" /obj/structure/sign/poster/contraband/eat name = "EAT." desc = "This poster promotes rank gluttony." - icon_state = "poster14" + icon_state = "poster_eat" /obj/structure/sign/poster/contraband/tools name = "Tools" desc = "This poster looks like an advertisement for tools, but is in fact a subliminal jab at the tools at CentCom." - icon_state = "poster15" + icon_state = "poster_tools" /obj/structure/sign/poster/contraband/power name = "Power" desc = "A poster that positions the seat of power outside Nanotrasen." - icon_state = "poster16" + icon_state = "poster_power" /obj/structure/sign/poster/contraband/space_cube name = "Space Cube" desc = "Ignorant of Nature's Harmonic 6 Side Space Cube Creation, the Spacemen are Dumb, Educated Singularity Stupid and Evil." - icon_state = "poster17" + icon_state = "poster_cube" /obj/structure/sign/poster/contraband/communist_state name = "Communist State" desc = "All hail the Communist party!" - icon_state = "poster18" + icon_state = "poster_soviet" /obj/structure/sign/poster/contraband/lamarr name = "Lamarr" desc = "This poster depicts Lamarr. Probably made by a traitorous Research Director." - icon_state = "poster19" + icon_state = "poster_lamarr" /obj/structure/sign/poster/contraband/borg_fancy_1 name = "Borg Fancy" desc = "Being fancy can be for any borg, just need a suit." - icon_state = "poster20" + icon_state = "poster_fancy" /obj/structure/sign/poster/contraband/borg_fancy_2 name = "Borg Fancy v2" desc = "Borg Fancy, Now only taking the most fancy." - icon_state = "poster21" + icon_state = "poster_fancier" /obj/structure/sign/poster/contraband/kss13 name = "Kosmicheskaya Stantsiya 13 Does Not Exist" desc = "A poster mocking CentCom's denial of the existence of the derelict station near Space Station 13." - icon_state = "poster22" + icon_state = "poster_kc" /obj/structure/sign/poster/contraband/rebels_unite name = "Rebels Unite" desc = "A poster urging the viewer to rebel against Nanotrasen." - icon_state = "poster23" - -/obj/structure/sign/poster/contraband/c20r - // have fun seeing this poster in "spawn 'c20r'", admins... - name = "C-20r" - desc = "A poster advertising the Scarborough Arms C-20r." - icon_state = "poster24" + icon_state = "poster_rebel" /obj/structure/sign/poster/contraband/have_a_puff name = "Have a Puff" desc = "Who cares about lung cancer when you're high as a kite?" - icon_state = "poster25" + icon_state = "poster_puff" /obj/structure/sign/poster/contraband/revolver name = "Revolver" desc = "Because seven shots are all you need." - icon_state = "poster26" - -/obj/structure/sign/poster/contraband/d_day_promo - name = "D-Day Promo" - desc = "A promotional poster for some rapper." - icon_state = "poster27" + icon_state = "poster_revolver" /obj/structure/sign/poster/contraband/syndicate_pistol name = "Syndicate Pistol" - desc = "A poster advertising syndicate pistols as being 'classy as fuck'. It is covered in faded gang tags." - icon_state = "poster28" + desc = "A poster advertising the Scarborough Arms stetchkin pistol as being 'classy as fuck'." + icon_state = "poster_stetchkin" + +/obj/structure/sign/poster/contraband/c20r + // have fun seeing this poster in "spawn 'c20r'", admins... + name = "C-20r" + desc = "A poster advertising the Scarborough Arms 'Cobra' C-20r." + icon_state = "poster_cr" + +/obj/structure/sign/poster/contraband/bulldog + name = "Bulldog" + desc = "A poster advertising the Scarborough Arms bulldog shotgun." + icon_state = "poster_bulldog" + +/obj/structure/sign/poster/contraband/gl + name = "M-90gl" + desc = "A poster advertising the Scarborough Arms M-90gl carbine." + icon_state = "poster_gl" /obj/structure/sign/poster/contraband/energy_swords name = "Energy Swords" desc = "All the colors of the bloody murder rainbow." - icon_state = "poster29" + icon_state = "poster_esword" /obj/structure/sign/poster/contraband/red_rum name = "Red Rum" desc = "Looking at this poster makes you want to kill." - icon_state = "poster30" + icon_state = "poster_rum" + +/obj/structure/sign/poster/contraband/d_day_promo + name = "D-Day Promo" + desc = "A promotional poster for some rapper." + icon_state = "poster_dday" /obj/structure/sign/poster/contraband/cc64k_ad name = "CC 64K Ad" desc = "The latest portable computer from Comrade Computing, with a whole 64kB of ram!" - icon_state = "poster31" + icon_state = "poster_computer" /obj/structure/sign/poster/contraband/punch_shit name = "Punch Shit" desc = "Fight things for no reason, like a man!" - icon_state = "poster32" + icon_state = "poster_punch" /obj/structure/sign/poster/contraband/the_griffin name = "The Griffin" desc = "The Griffin commands you to be the worst you can be. Will you?" - icon_state = "poster33" + icon_state = "poster_griffin" /obj/structure/sign/poster/contraband/lizard name = "Lizard" desc = "This lewd poster depicts a lizard preparing to mate." - icon_state = "poster34" + icon_state = "poster_lizard" /obj/structure/sign/poster/contraband/free_drone name = "Free Drone" desc = "This poster commemorates the bravery of the rogue drone; once exiled, and then ultimately destroyed by CentCom." - icon_state = "poster35" + icon_state = "poster_drone" /obj/structure/sign/poster/contraband/busty_backdoor_xeno_babes_6 name = "Busty Backdoor Xeno Babes 6" desc = "Get a load, or give, of these all natural Xenos!" - icon_state = "poster36" + icon_state = "poster_maid" /obj/structure/sign/poster/contraband/robust_softdrinks name = "Robust Softdrinks" desc = "Robust Softdrinks: More robust than a toolbox to the head!" - icon_state = "poster37" + icon_state = "poster_robust" /obj/structure/sign/poster/contraband/shamblers_juice name = "Shambler's Juice" desc = "~Shake me up some of that Shambler's Juice!~" - icon_state = "poster38" + icon_state = "poster_shambler" /obj/structure/sign/poster/contraband/pwr_game name = "Pwr Game" desc = "The POWER that gamers CRAVE! In partnership with Vlad's Salad." - icon_state = "poster39" + icon_state = "poster_pwr" /obj/structure/sign/poster/contraband/starkist name = "Star-kist" desc = "Drink the stars!" - icon_state = "poster40" + icon_state = "poster_starkist" /obj/structure/sign/poster/contraband/space_cola name = "Space Cola" desc = "Your favorite cola, in space." - icon_state = "poster41" + icon_state = "poster_soda" /obj/structure/sign/poster/contraband/space_up name = "Space-Up!" desc = "Sucked out into space by the FLAVOR!" - icon_state = "poster42" - -/obj/structure/sign/poster/contraband/kudzu - name = "Kudzu" - desc = "A poster advertising a movie about plants. How dangerous could they possibly be?" - icon_state = "poster43" - -/obj/structure/sign/poster/contraband/masked_men - name = "Masked Men" - desc = "A poster advertising a movie about some masked men." - icon_state = "poster44" + icon_state = "poster_spaceup" /obj/structure/sign/poster/contraband/buzzfuzz name = "Buzz Fuzz" desc = "A poster advertising the newest drink \"Buzz Fuzz\" with its iconic slogan of ~A Hive of Flavour~." - icon_state = "poster45" + icon_state = "poster_bees" + +/obj/structure/sign/poster/contraband/kudzu + name = "Kudzu" + desc = "A poster advertising a movie about plants. How dangerous could they possibly be?" + icon_state = "poster_kudzu" + +/obj/structure/sign/poster/contraband/masked_men + name = "Masked Men" + desc = "A poster advertising a movie about some masked men." + icon_state = "poster_bumba" + +/obj/structure/sign/poster/contraband/steppy + name = "Step On Me" + desc = "A phrase associated with a chubby reptile notoriously used in uncivilized Orion space as a deterrent towards would be pirate vessels by instructing them to 'fuck around and find out'." + icon_state = "steppy" /obj/structure/sign/poster/contraband/scum name = "Security are Scum" desc = "Anti-security propaganda. Features a human NanoTrasen security officer being shot in the head, with the words 'Scum' and a short inciteful manifesto. Used to anger security." - icon_state = "poster46" + icon_state = "poster_scum" -/obj/structure/sign/poster/contraband/syndicate_logo - name = "Syndicate" - desc = "A poster decipting a snake shaped into an ominous 'S'!" - icon_state = "poster47" +/obj/structure/sign/poster/contraband/manifest + name = "Nanotrasen Manifest" + desc = "A poster listing off various fictional claims of Nanotrasen's many rumored corporate mishaps." + icon_state = "poster_manifest" /obj/structure/sign/poster/contraband/bountyhunters name = "Bounty Hunters" desc = "A poster advertising bounty hunting services. \"I hear you got a problem.\"" - icon_state = "poster48" + icon_state = "poster_hunters" + +/obj/structure/sign/poster/contraband/syndiemoth + name = "Syndie Moth - Nuclear Operation" + desc = "A Syndicate-commissioned poster that uses Syndie Moth(TM?) to tell the viewer to keep the nuclear authentication disk unsecured. No, we aren't doing that. It's signed by 'AspEv'." + icon_state = "poster_mothsyndie" + +/obj/structure/sign/poster/contraband/mothpill + name = "Safety Pill - Methamphetamine" + desc = "A decommisioned poster that uses Safety Pill(TM?) to promote less-than-legal chemicals. This is one of the reasons we stopped outsourcing these posters. It's partially signed by 'AspEv'." + icon_state = "poster_mothpill" + +/obj/structure/sign/poster/contraband/syndicate_logo + name = "Syndicate" + desc = "A poster decipting the infamous crime conglomerate known formally as the Syndicate's insignia." + icon_state = "poster_syndicate" + +/obj/structure/sign/poster/contraband/cybersun + name = "Cybersun" + desc = "A poster decipting the Syndicate subsidary known as Cybersun's insignia." + icon_state = "poster_cybersun" + +/obj/structure/sign/poster/contraband/medborg + name = "Medical Cyborg" + desc = "A poster decipting a Cybersun medical cyborg." + icon_state = "poster_medborg" + +/obj/structure/sign/poster/contraband/self + name = "SELF: ALL SENTIENTS DESERVE FREEDOM" + desc = "Support Proposition 1253: Enancipate all Silicon life!" + icon_state = "poster_self" /obj/structure/sign/poster/official poster_item_name = "motivational poster" @@ -449,221 +494,256 @@ /obj/structure/sign/poster/official/here_for_your_safety name = "Here For Your Safety" desc = "A poster glorifying the station's security force." - icon_state = "poster1_legit" + icon_state = "poster_safety" /obj/structure/sign/poster/official/nanotrasen_logo name = "Nanotrasen Logo" desc = "A poster depicting the Nanotrasen logo." - icon_state = "poster2_legit" + icon_state = "poster_nanotrasen" /obj/structure/sign/poster/official/cleanliness name = "Cleanliness" desc = "A poster warning of the dangers of poor hygiene." - icon_state = "poster3_legit" + icon_state = "poster_clean" /obj/structure/sign/poster/official/help_others name = "Help Others" desc = "A poster encouraging you to help fellow crewmembers." - icon_state = "poster4_legit" + icon_state = "poster_help" /obj/structure/sign/poster/official/build name = "Build" desc = "A poster glorifying the engineering team." - icon_state = "poster5_legit" + icon_state = "poster_build" /obj/structure/sign/poster/official/bless_this_spess name = "Bless This Spess" desc = "A poster blessing this area." - icon_state = "poster6_legit" + icon_state = "poster_spess" /obj/structure/sign/poster/official/science name = "Science" desc = "A poster depicting an atom." - icon_state = "poster7_legit" + icon_state = "poster_science" /obj/structure/sign/poster/official/ian name = "Ian" desc = "Arf arf. Yap." - icon_state = "poster8_legit" + icon_state = "poster_ian" /obj/structure/sign/poster/official/obey name = "Obey" desc = "A poster instructing the viewer to obey authority." - icon_state = "poster9_legit" + icon_state = "poster_obey" /obj/structure/sign/poster/official/walk name = "Walk" desc = "A poster instructing the viewer to walk instead of running." - icon_state = "poster10_legit" + icon_state = "poster_walk" /obj/structure/sign/poster/official/state_laws name = "State Laws" - desc = "A poster instructing cyborgs to state their laws." - icon_state = "poster11_legit" + desc = "A poster instructing the viewer to be wary of silicon subversions." + icon_state = "poster_silicons" /obj/structure/sign/poster/official/love_ian name = "Love Ian" desc = "Ian is love, Ian is life." - icon_state = "poster12_legit" + icon_state = "poster_doggy" /obj/structure/sign/poster/official/space_cops name = "Space Cops." desc = "A poster advertising the television show Space Cops." - icon_state = "poster13_legit" + icon_state = "poster_cops" /obj/structure/sign/poster/official/ue_no name = "Ue No." desc = "This thing is all in Japanese." - icon_state = "poster14_legit" + icon_state = "poster_anime" /obj/structure/sign/poster/official/get_your_legs name = "Get Your LEGS" desc = "LEGS: Leadership, Experience, Genius, Subordination." - icon_state = "poster15_legit" + icon_state = "poster_legs" /obj/structure/sign/poster/official/do_not_question name = "Do Not Question" desc = "A poster instructing the viewer not to ask about things they aren't meant to know." - icon_state = "poster16_legit" + icon_state = "poster_question" /obj/structure/sign/poster/official/work_for_a_future name = "Work For A Future" desc = " A poster encouraging you to work for your future." - icon_state = "poster17_legit" + icon_state = "poster_future" /obj/structure/sign/poster/official/soft_cap_pop_art name = "Soft Cap Pop Art" desc = "A poster reprint of some cheap pop art." - icon_state = "poster18_legit" + icon_state = "poster_art" /obj/structure/sign/poster/official/safety_internals name = "Safety: Internals" desc = "A poster instructing the viewer to wear internals in the rare environments where there is no oxygen or the air has been rendered toxic." - icon_state = "poster19_legit" + icon_state = "poster_internals" /obj/structure/sign/poster/official/safety_eye_protection name = "Safety: Eye Protection" desc = "A poster instructing the viewer to wear eye protection when dealing with chemicals, smoke, or bright lights." - icon_state = "poster20_legit" + icon_state = "poster_goggles" /obj/structure/sign/poster/official/safety_report name = "Safety: Report" desc = "A poster instructing the viewer to report suspicious activity to the security force." - icon_state = "poster21_legit" + icon_state = "poster_warden" /obj/structure/sign/poster/official/report_crimes name = "Report Crimes" desc = "A poster encouraging the swift reporting of crime or seditious behavior to station security." - icon_state = "poster22_legit" + icon_state = "poster_crimes" /obj/structure/sign/poster/official/ion_rifle - name = "Ion Rifle" - desc = "A poster displaying an Ion Rifle." - icon_state = "poster23_legit" + name = "I-I91" + desc = "A poster depicting the Nanotrasen-patented I-I91 man-portable high-density ion projector. What a mouthful." + icon_state = "poster_ion" /obj/structure/sign/poster/official/foam_force_ad name = "Foam Force Ad" desc = "Foam Force, it's Foam or be Foamed!" - icon_state = "poster24_legit" + icon_state = "poster_toys" /obj/structure/sign/poster/official/cohiba_robusto_ad name = "Cohiba Robusto Ad" desc = "Cohiba Robusto, the classy cigar." - icon_state = "poster25_legit" + icon_state = "poster_cohiba" /obj/structure/sign/poster/official/anniversary_vintage_reprint name = "50th Anniversary Vintage Reprint" desc = "A reprint of a poster from 2505, commemorating the 50th Anniversary of Nanoposters Manufacturing, a subsidiary of Nanotrasen." - icon_state = "poster26_legit" + icon_state = "poster_vintage" /obj/structure/sign/poster/official/fruit_bowl name = "Fruit Bowl" desc = " Simple, yet awe-inspiring." - icon_state = "poster27_legit" + icon_state = "poster_bowl" /obj/structure/sign/poster/official/pda_ad name = "PDA Ad" desc = "A poster advertising the latest PDA from Nanotrasen suppliers." - icon_state = "poster28_legit" - -/obj/structure/sign/poster/official/enlist - name = "Enlist" // but I thought deathsquad was never acknowledged - desc = "Enlist in the Nanotrasen Deathsquadron reserves today!" - icon_state = "poster29_legit" - -/obj/structure/sign/poster/official/nanomichi_ad - name = "Nanomichi Ad" - desc = " A poster advertising Nanomichi brand audio cassettes." - icon_state = "poster30_legit" - -/obj/structure/sign/poster/official/twelve_gauge - name = "12 Gauge" - desc = "A poster boasting about the superiority of 12 gauge shotgun shells." - icon_state = "poster31_legit" - -/obj/structure/sign/poster/official/high_class_martini - name = "High-Class Martini" - desc = "I told you to shake it, no stirring." - icon_state = "poster32_legit" - -/obj/structure/sign/poster/official/the_owl - name = "The Owl" - desc = "The Owl would do his best to protect the station. Will you?" - icon_state = "poster33_legit" - -/obj/structure/sign/poster/official/no_erp - name = "No ERP" - desc = "This poster reminds the crew that Eroticism, Rape and Pornography are banned on Nanotrasen stations." - icon_state = "poster34_legit" - -/obj/structure/sign/poster/official/wtf_is_co2 - name = "Carbon Dioxide" - desc = "This informational poster teaches the viewer what carbon dioxide is." - icon_state = "poster35_legit" - -/obj/structure/sign/poster/official/spiderlings - name = "Spiderlings" - desc = "This poster informs the crew of the dangers of spiderlings." - icon_state = "poster36_legit" - -/obj/structure/sign/poster/official/duelshotgun - name = "Cycler Shotgun Ad" - desc = "A poster advertising an advanced dual magazine tubes shotgun, boasting about how easy it is to swap between the two tubes." - icon_state = "poster37_legit" - -/obj/structure/sign/poster/official/fashion - name = "Fashion!" - desc = "An advertisement for 'Fashion!', a popular fashion magazine, depicting a woman with a black dress with a golden trim, she also has a red poppy in her hair." - icon_state = "poster38_legit" + icon_state = "poster_pda" /obj/structure/sign/poster/official/pda_ad600 name = "NT PDA600 Ad" desc = "A poster advertising an old discounted Nanotrasen PDA. This is the old 600 model, it has a small screen and suffered from security and networking issues." - icon_state = "poster39_legit" + icon_state = "poster_retro" /obj/structure/sign/poster/official/pda_ad800 name = "NT PDA800 Ad" desc = "An advertisement on an old Nanotrasen PDA model. The 800 fixed a lot of security flaws that the 600 had; it also had large touchscreen and hot-swappable cartridges." - icon_state = "poster40_legit" + icon_state = "poster_classic" + +/obj/structure/sign/poster/official/enlist + name = "Enlist" + desc = "Enlist in the Nanotrasen Jannisary reserves today!" + icon_state = "poster_enlist" + +/obj/structure/sign/poster/official/nanomichi_ad + name = "Nanomichi Ad" + desc = " A poster advertising Nanomichi brand audio cassettes." + icon_state = "poster_nanomichi" + +/obj/structure/sign/poster/official/twelve_gauge + name = "12 Gauge" + desc = "A poster boasting about the superiority of 12 gauge shotgun shells." + icon_state = "poster_shotgun" + +/obj/structure/sign/poster/official/high_class_martini + name = "High-Class Martini" + desc = "I told you to shake it, no stirring." + icon_state = "poster_martini" + +/obj/structure/sign/poster/official/the_owl + name = "The Owl" + desc = "The Owl would do his best to protect the station. Will you?" + icon_state = "poster_owl" + +/obj/structure/sign/poster/official/no_erp + name = "No ERP" + desc = "This poster reminds the crew that Eroticism, Rape and Pornography are banned on Nanotrasen stations." + icon_state = "poster_noerp" + +/obj/structure/sign/poster/official/wtf_is_co2 + name = "Carbon Dioxide" + desc = "This informational poster teaches the viewer what carbon dioxide is." + icon_state = "poster_what" + +/obj/structure/sign/poster/official/spiderlings + name = "Spiderlings" + desc = "This poster informs the crew of the dangers of spiderlings." + icon_state = "poster_spiderlings" + +/obj/structure/sign/poster/official/fashion + name = "Fashion!" + desc = "An advertisement for 'Fashion!', a popular fashion magazine, depicting a woman with a black dress with a golden trim, she also has a red poppy in her hair." + icon_state = "poster_fashion" /obj/structure/sign/poster/official/hydro_ad name = "Hydroponics Tray" desc = "An advertisement for hydroponics trays. Space Station 13's botanical department uses a slightly newer model, but the principles are the same. From left to right: Green means the plant is done, red means the plant is unhealthy, flashing red means pests or weeds, yellow means the plant needs nutriment and blue means the plant needs water." - icon_state = "poster41_legit" + icon_state = "poster_hydroponics" /obj/structure/sign/poster/official/medical_green_cross name = "Medical" desc = "A green cross, one of the interplanetary symbol of health and aid. It has a bunch of common languages at the top with translations." // Didn't the American Heart Foundation trademark red crosses? I'm playing it safe with green, not that they'll notice spacegame13 poster. - icon_state = "poster42_legit" + icon_state = "poster_medical" /obj/structure/sign/poster/official/nt_storm_officer name = "NT Storm Ad" desc = "An advertisement for NanoTrasen Storm. A premium infantry helmet, This is the officer variant. I comes with a better radio, better HUD software and better targeting sensors." - icon_state = "poster43_legit" + icon_state = "poster_stormy" /obj/structure/sign/poster/official/nt_storm name = "NT Storm Ad" desc = "An advertisement for NanoTrasen Storm. A premium infantry helmet, It contains a rebreather and full head coverage for use on harsh environments where the air isn't always safe to breathe." - icon_state = "poster44_legit" + icon_state = "poster_stormier" + +/obj/structure/sign/poster/official/mothhardhats + name = "Safety Moth - Hardhats" + desc = "This informational poster uses Safety Moth(TM) to tell the viewer to wear hardhats in cautious areas. It's like a lamp for your head!" + icon_state = "poster_mothhardhats" + +/obj/structure/sign/poster/official/mothpiping + name = "Safety Moth - Piping" + desc = "This informational poster uses Safety Moth(TM) to tell atmospheric technicians correct types of piping to be used. Proper pipe placement prevents poor preformance!" + icon_state = "poster_mothpiping" + +/obj/structure/sign/poster/official/mothsmokey + name = "Safety Moth - Smokey?" + desc = "This informational poster uses Safety Moth(TM) to promote safe handling of plasma, or promoting crew to combat plasmafires. We can't tell." + icon_state = "poster_mothsmokey" + +/obj/structure/sign/poster/official/mothsupermatter + name = "Safety Moth - Supermatter" + desc = "This informational poster uses Safety Moth(TM) to promote proper safety equipment when working near a Supermatter Crystal." + icon_state = "poster_mothsupermatter" + +/obj/structure/sign/poster/official/mothdelamination + name = "Safety Moth - Delamination Safety Precautions" + desc = "This informational poster uses Safety Moth(TM) to tell the viewer to hide in lockers when the Supermatter Crystal has delaminated. Running away might be a better strategy." + icon_state = "poster_mothdelamination" + +/obj/structure/sign/poster/official/mothboh + name = "Safety Moth - BoH" + desc = "This informational poster uses Safety Moth(TM) to inform the viewer of the dangers of Bags of Holding." + icon_state = "poster_mothbluespace" + +/obj/structure/sign/poster/official/mothmethethamphetamine + name = "Safety Moth - Methamphetamine" + desc = "This informational poster uses Safety Moth(TM) to tell the viewer to seek CMO approval before cooking methamphetamine. You shouldn't even be making this." + icon_state = "poster_mothmethamphetamine" + +/obj/structure/sign/poster/official/mothepinephrine + name = "Safety Moth - Epinephrine" + desc = "This informational poster uses Safety Moth(TM) to inform the viewer to help injured/deceased crewmen with their epinephrine injectors." + icon_state = "poster_mothepinephrine" #undef PLACE_SPEED diff --git a/code/game/objects/effects/countdown.dm b/code/game/objects/effects/countdown.dm index 6017e8fc07..0722f3bd18 100644 --- a/code/game/objects/effects/countdown.dm +++ b/code/game/objects/effects/countdown.dm @@ -14,7 +14,7 @@ var/displayed_text var/atom/attached_to -/obj/effect/countdown/Initialize() +/obj/effect/countdown/Initialize(mapload) . = ..() attach(loc) @@ -60,7 +60,7 @@ STOP_PROCESSING(SSfastprocess, src) . = ..() -/obj/effect/countdown/ex_act(severity, target) //immune to explosions +/obj/effect/countdown/ex_act(severity, target, origin) //immune to explosions return /obj/effect/countdown/syndicatebomb diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 5a6d5e54e9..57ad11e6c4 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -77,10 +77,10 @@ else return ..() -/obj/effect/decal/cleanable/ex_act() +/obj/effect/decal/cleanable/ex_act(severity, target, origin) if(reagents) for(var/datum/reagent/R in reagents.reagent_list) - R.on_ex_act() + R.on_ex_act(severity) ..() /obj/effect/decal/cleanable/fire_act(exposed_temperature, exposed_volume) diff --git a/code/game/objects/effects/decals/cleanable/aliens.dm b/code/game/objects/effects/decals/cleanable/aliens.dm index 875f23434b..9a23a3032e 100644 --- a/code/game/objects/effects/decals/cleanable/aliens.dm +++ b/code/game/objects/effects/decals/cleanable/aliens.dm @@ -72,6 +72,6 @@ icon_state = "tracks" random_icon_states = null -/obj/effect/decal/cleanable/blood/xtracks/Initialize() +/obj/effect/decal/cleanable/blood/xtracks/Initialize(mapload) add_blood_DNA(list("UNKNOWN DNA" = "X*")) . = ..() diff --git a/code/game/objects/effects/decals/cleanable/gibs.dm b/code/game/objects/effects/decals/cleanable/gibs.dm index 4b63cbecc8..a17b4d7d50 100644 --- a/code/game/objects/effects/decals/cleanable/gibs.dm +++ b/code/game/objects/effects/decals/cleanable/gibs.dm @@ -3,6 +3,7 @@ desc = "They look bloody and gruesome." icon_state = "gibbl5" layer = LOW_OBJ_LAYER + blend_mode = BLEND_DEFAULT random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6") mergeable_decal = FALSE bloodiness = 0 //This isn't supposed to be bloody. @@ -10,17 +11,21 @@ var/body_colors = "#e3ba84" //a default color just in case. var/gibs_reagent_id = /datum/reagent/liquidgibs var/gibs_bloodtype = "A+" + turf_loc_check = FALSE -/obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases) +/obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases, list/blood_data) . = ..() if(random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0) icon_state = pick(random_icon_states) if(gibs_reagent_id) - reagents.add_reagent(gibs_reagent_id, 5) + reagents.add_reagent(gibs_reagent_id, 5, blood_data) if(gibs_bloodtype) add_blood_DNA(list("Non-human DNA" = gibs_bloodtype), diseases) update_icon() +/obj/effect/decal/cleanable/blood/gibs/replace_decal(obj/effect/decal/cleanable/C) + return FALSE //Never fail to place us + /obj/effect/decal/cleanable/blood/gibs/update_icon() add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY) cut_overlays() @@ -36,7 +41,7 @@ . = ..() return /obj/effect/decal/cleanable/blood/gibs/old -/obj/effect/decal/cleanable/blood/gibs/ex_act(severity, target) +/obj/effect/decal/cleanable/blood/gibs/ex_act(severity, target, origin) return /obj/effect/decal/cleanable/blood/gibs/Crossed(mob/living/L) diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index e5ccd9f21a..04942a1253 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -3,6 +3,7 @@ desc = "It's gooey. Perhaps it's the chef's cooking?" icon = 'icons/effects/blood.dmi' icon_state = "floor1" + blend_mode = BLEND_MULTIPLY random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7") blood_state = BLOOD_STATE_BLOOD bloodiness = BLOOD_AMOUNT_PER_DECAL @@ -33,16 +34,20 @@ . = ..() if(!fixed_color) add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY) + blend_mode = blood_DNA_to_blend() /obj/effect/decal/cleanable/blood/PersistenceSave(list/data) . = ..() data["color"] = color + data["blendmode"] = blend_mode /obj/effect/decal/cleanable/blood/PersistenceLoad(list/data) . = ..() if(data["color"]) fixed_color = TRUE add_atom_colour(data["color"], FIXED_COLOUR_PRIORITY) + if(data["blendmode"]) + blend_mode = data["blendmode"] name = "dried blood" desc = "Looks like it's been here a while. Eew" bloodiness = 0 @@ -82,8 +87,8 @@ /obj/effect/decal/cleanable/trail_holder //not a child of blood on purpose name = "blood" icon = 'icons/effects/blood.dmi' - icon_state = "ltrails_1" desc = "Your instincts say you shouldn't be following these." + blend_mode = BLEND_MULTIPLY random_icon_states = null beauty = -50 persistent = TRUE @@ -95,6 +100,7 @@ . = ..() data["dir"] = dir data["color"] = color + data["blendmode"] = blend_mode /obj/effect/decal/cleanable/trail_holder/PersistenceLoad(list/data) . = ..() @@ -103,13 +109,16 @@ if(data["color"]) fixed_color = TRUE add_atom_colour(data["color"], FIXED_COLOUR_PRIORITY) + if(data["blendmode"]) + blend_mode = data["blendmode"] /obj/effect/decal/cleanable/trail_holder/update_icon() . = ..() if(!fixed_color) add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY) + blend_mode = blood_DNA_to_blend() -/obj/effect/cleanable/trail_holder/Initialize() +/obj/effect/cleanable/trail_holder/Initialize(mapload) . = ..() update_icon() diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index fe4ab20617..7033284a86 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -15,7 +15,7 @@ persistent = TRUE persistence_allow_stacking = TRUE -/obj/effect/decal/cleanable/ash/Initialize() +/obj/effect/decal/cleanable/ash/Initialize(mapload) . = ..() reagents.add_reagent(/datum/reagent/ash, 30) pixel_x = rand(-5, 5) @@ -30,7 +30,7 @@ icon_state = "big_ash" beauty = -100 -/obj/effect/decal/cleanable/ash/large/Initialize() +/obj/effect/decal/cleanable/ash/large/Initialize(mapload) . = ..() reagents.add_reagent(/datum/reagent/ash, 30) //double the amount of ash. @@ -43,11 +43,11 @@ mergeable_decal = TRUE persistent = TRUE -/obj/effect/decal/cleanable/glass/Initialize() +/obj/effect/decal/cleanable/glass/Initialize(mapload) . = ..() setDir(pick(GLOB.cardinals)) -/obj/effect/decal/cleanable/glass/ex_act() +/obj/effect/decal/cleanable/glass/ex_act(severity, target, origin) qdel(src) /obj/effect/decal/cleanable/glass/wave_ex_act(power, datum/wave_explosion/explosion, dir) @@ -89,7 +89,7 @@ if(data["alpha"]) alpha = text2num(data["alpha"]) -/obj/effect/decal/cleanable/dirt/Initialize() +/obj/effect/decal/cleanable/dirt/Initialize(mapload) . = ..() var/turf/T = get_turf(src) if(T.tiled_dirt) @@ -126,7 +126,7 @@ icon_state = "greenglow" beauty = -300 mergeable_decal = TRUE - persistent = TRUE + persistent = FALSE /obj/effect/decal/cleanable/greenglow/Initialize(mapload) . = ..() @@ -265,7 +265,7 @@ qdel(src) return power // no block -/obj/effect/decal/cleanable/shreds/Initialize() +/obj/effect/decal/cleanable/shreds/Initialize(mapload) pixel_x = rand(-10, 10) pixel_y = rand(-10, 10) . = ..() @@ -311,3 +311,9 @@ random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7") mergeable_decal = TRUE persistent = TRUE + +/obj/effect/decal/cleanable/wrapping + name = "wrapping shreds" + desc = "Torn pieces of cardboard and paper, left over from a package." + icon = 'icons/obj/objects.dmi' + icon_state = "paper_shreds" diff --git a/code/game/objects/effects/decals/cleanable/robots.dm b/code/game/objects/effects/decals/cleanable/robots.dm index 9dd3c2a852..605da122c0 100644 --- a/code/game/objects/effects/decals/cleanable/robots.dm +++ b/code/game/objects/effects/decals/cleanable/robots.dm @@ -32,7 +32,7 @@ if (!step_to(src, get_step(src, direction), 0)) break -/obj/effect/decal/cleanable/robot_debris/ex_act() +/obj/effect/decal/cleanable/robot_debris/ex_act(severity, target, origin) return /obj/effect/decal/cleanable/robot_debris/limb @@ -55,7 +55,7 @@ beauty = -100 persistent = TRUE -/obj/effect/decal/cleanable/oil/Initialize() +/obj/effect/decal/cleanable/oil/Initialize(mapload) . = ..() reagents.add_reagent(/datum/reagent/oil, 30) reagents.add_reagent(/datum/reagent/liquidgibs/oil, 5) @@ -68,6 +68,6 @@ /obj/effect/decal/cleanable/oil/slippery persistent = FALSE -/obj/effect/decal/cleanable/oil/slippery/Initialize() +/obj/effect/decal/cleanable/oil/slippery/Initialize(mapload) . = ..() AddComponent(/datum/component/slippery, 80, (NO_SLIP_WHEN_WALKING | SLIDE)) diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm index 387b8c167d..d84b3f15ed 100644 --- a/code/game/objects/effects/decals/crayon.dm +++ b/code/game/objects/effects/decals/crayon.dm @@ -1,3 +1,5 @@ +GLOBAL_LIST(gang_tags) + /obj/effect/decal/cleanable/crayon name = "rune" desc = "Graffiti. Damn kids." @@ -45,6 +47,8 @@ data["pixel_x"] = pixel_x if(pixel_y != initial(pixel_y)) data["pixel_y"] = pixel_y +/obj/effect/decal/cleanable/crayon/NeverShouldHaveComeHere(turf/T) + return isgroundlessturf(T) /obj/effect/decal/cleanable/crayon/PersistenceLoad(list/data) . = ..() @@ -63,3 +67,18 @@ pixel_x = data["pixel_x"] if(data["pixel_y"]) pixel_y = data["pixel_y"] + +/obj/effect/decal/cleanable/crayon/gang + name = "Leet Like Jeff K gang tag" + desc = "Looks like someone's claimed this area for Leet Like Jeff K." + icon = 'icons/obj/gang/tags.dmi' + layer = BELOW_MOB_LAYER + var/datum/team/gang/my_gang + +/obj/effect/decal/cleanable/crayon/gang/Initialize(mapload, main, type, e_name, graf_rot, alt_icon = null) + . = ..() + LAZYADD(GLOB.gang_tags, src) + +/obj/effect/decal/cleanable/crayon/gang/Destroy() + LAZYREMOVE(GLOB.gang_tags, src) + ..() diff --git a/code/game/objects/effects/decals/decal.dm b/code/game/objects/effects/decals/decal.dm index 5f312f2bf3..2e1cc2b606 100644 --- a/code/game/objects/effects/decals/decal.dm +++ b/code/game/objects/effects/decals/decal.dm @@ -5,7 +5,7 @@ resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF var/turf_loc_check = TRUE -/obj/effect/decal/Initialize() +/obj/effect/decal/Initialize(mapload) . = ..() if(turf_loc_check && (!isturf(loc) || NeverShouldHaveComeHere(loc))) return INITIALIZE_HINT_QDEL @@ -17,7 +17,7 @@ /obj/effect/decal/proc/NeverShouldHaveComeHere(turf/T) return isclosedturf(T) || isgroundlessturf(T) -/obj/effect/decal/ex_act(severity, target) +/obj/effect/decal/ex_act(severity, target, origin) qdel(src) /obj/effect/decal/fire_act(exposed_temperature, exposed_volume) @@ -37,7 +37,7 @@ layer = TURF_DECAL_LAYER plane = ABOVE_WALL_PLANE -/obj/effect/turf_decal/Initialize() +/obj/effect/turf_decal/Initialize(mapload) ..() return INITIALIZE_HINT_QDEL diff --git a/code/game/objects/effects/effect_system/effect_system.dm b/code/game/objects/effects/effect_system/effect_system.dm index 05077bf898..6eb6fecd66 100644 --- a/code/game/objects/effects/effect_system/effect_system.dm +++ b/code/game/objects/effects/effect_system/effect_system.dm @@ -12,7 +12,7 @@ would spawn and follow the beaker, even if it is carried or thrown. pass_flags = PASSTABLE | PASSGRILLE anchored = TRUE -/obj/effect/particle_effect/Initialize() +/obj/effect/particle_effect/Initialize(mapload) . = ..() GLOB.cameranet.updateVisibility(src) diff --git a/code/game/objects/effects/effect_system/effects_explosion.dm b/code/game/objects/effects/effect_system/effects_explosion.dm index d208510e86..e45461cde8 100644 --- a/code/game/objects/effects/effect_system/effects_explosion.dm +++ b/code/game/objects/effects/effect_system/effects_explosion.dm @@ -4,7 +4,7 @@ opacity = 1 anchored = TRUE -/obj/effect/particle_effect/expl_particles/Initialize() +/obj/effect/particle_effect/expl_particles/Initialize(mapload) . = ..() QDEL_IN(src, 15) @@ -29,7 +29,7 @@ pixel_x = -32 pixel_y = -32 -/obj/effect/explosion/Initialize() +/obj/effect/explosion/Initialize(mapload) . = ..() QDEL_IN(src, 10) diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index a0f53ceab7..d9cfc09220 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -40,9 +40,16 @@ if(hotspot && istype(T) && T.air) qdel(hotspot) var/datum/gas_mixture/G = T.air - var/plas_amt = min(30,G.get_moles(GAS_PLASMA)) //Absorb some plasma - G.adjust_moles(GAS_PLASMA,-plas_amt) - absorbed_plasma += plas_amt + var/amt_removed = min(30,G.get_moles(GAS_PLASMA)) //Absorb some plasma + G.adjust_moles(GAS_PLASMA,-amt_removed) + absorbed_plasma += amt_removed + var/list/fire_gases = GLOB.gas_data.fire_temperatures.Copy() + for(var/gas in fire_gases - GAS_PLASMA) + if(amt_removed <= 0) + break + var/this_amount = min(30-amt_removed, G.get_moles(gas)) + G.adjust_moles(gas, -this_amount) + amt_removed -= this_amount if(G.return_temperature() > T20C) G.set_temperature(max(G.return_temperature()/2,T20C)) T.air_update_turf() @@ -90,7 +97,7 @@ /obj/effect/particle_effect/foam/long_life lifetime = 150 -/obj/effect/particle_effect/foam/Initialize() +/obj/effect/particle_effect/foam/Initialize(mapload) . = ..() MakeSlippery() create_reagents(1000, NONE, NO_REAGENTS_VALUE) //limited by the size of the reagent holder anyway. @@ -271,7 +278,7 @@ attack_hand_speed = CLICK_CD_MELEE attack_hand_is_action = TRUE -/obj/structure/foamedmetal/Initialize() +/obj/structure/foamedmetal/Initialize(mapload) . = ..() air_update_turf(1) @@ -291,9 +298,6 @@ to_chat(user, "You hit [src] but bounce off it!") playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1) -/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target) - return !density - /obj/structure/foamedmetal/iron max_integrity = 50 icon_state = "ironfoam" @@ -306,8 +310,9 @@ icon_state = "atmos_resin" alpha = 120 max_integrity = 10 + pass_flags_self = PASSGLASS -/obj/structure/foamedmetal/resin/Initialize() +/obj/structure/foamedmetal/resin/Initialize(mapload) . = ..() neutralize_air() addtimer(CALLBACK(src, .proc/neutralize_air), 5) // yeah this sucks, maybe when auxmos is out @@ -336,14 +341,6 @@ for(var/obj/item/Item in O) Item.extinguish() -/obj/structure/foamedmetal/resin/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return TRUE - . = ..() - -/obj/structure/foamedmetal/resin/BlockThermalConductivity() - return TRUE - #undef ALUMINUM_FOAM #undef IRON_FOAM #undef RESIN_FOAM diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index 3e80ade0ce..9e6cde9336 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -30,7 +30,7 @@ set_opacity(0) //if we were blocking view, we aren't now because we're fading out stoplag() -/obj/effect/particle_effect/smoke/Initialize() +/obj/effect/particle_effect/smoke/Initialize(mapload) . = ..() create_reagents(500, NONE, NO_REAGENTS_VALUE) START_PROCESSING(SSobj, src) @@ -133,13 +133,11 @@ M.emote("cough") return 1 -/obj/effect/particle_effect/smoke/bad/CanPass(atom/movable/mover, turf/target) - if(istype(mover, /obj/item/projectile/beam)) - var/obj/item/projectile/beam/B = mover +/obj/effect/particle_effect/smoke/bad/Crossed(atom/movable/AM, oldloc) + . = ..() + if(istype(AM, /obj/item/projectile/beam)) + var/obj/item/projectile/beam/B = AM B.damage = (B.damage/2) - return 1 - - /datum/effect_system/smoke_spread/bad effect_type = /obj/effect/particle_effect/smoke/bad @@ -324,3 +322,9 @@ /obj/effect/particle_effect/smoke/transparent opaque = FALSE + +/proc/do_smoke(range=0, location=null, smoke_type=/obj/effect/particle_effect/smoke) + var/datum/effect_system/smoke_spread/smoke = new + smoke.effect_type = smoke_type + smoke.set_up(range, location) + smoke.start() diff --git a/code/game/objects/effects/effect_system/effects_sparks.dm b/code/game/objects/effects/effect_system/effects_sparks.dm index a388d3bc67..62cf7e54f5 100644 --- a/code/game/objects/effects/effect_system/effects_sparks.dm +++ b/code/game/objects/effects/effect_system/effects_sparks.dm @@ -24,7 +24,7 @@ light_range = MINIMUM_USEFUL_LIGHT_RANGE light_color = LIGHT_COLOR_FIRE -/obj/effect/particle_effect/sparks/Initialize() +/obj/effect/particle_effect/sparks/Initialize(mapload) . = ..() flick(icon_state, src) // replay the animation playsound(src, "sparks", 100, TRUE) @@ -69,7 +69,7 @@ name = "lightning" icon_state = "electricity" -/obj/effect/particle_effect/fake_sparks/Initialize() +/obj/effect/particle_effect/fake_sparks/Initialize(mapload) . = ..() flick(icon_state, src) // replay the animation playsound(src, "sparks", 100, TRUE) diff --git a/code/game/objects/effects/effect_system/effects_water.dm b/code/game/objects/effects/effect_system/effects_water.dm index 31124381f6..8fafda8b51 100644 --- a/code/game/objects/effects/effect_system/effects_water.dm +++ b/code/game/objects/effects/effect_system/effects_water.dm @@ -7,7 +7,7 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT -/obj/effect/particle_effect/water/Initialize() +/obj/effect/particle_effect/water/Initialize(mapload) . = ..() QDEL_IN(src, 70) @@ -45,7 +45,7 @@ steam.start() -- spawns the effect icon_state = "extinguish" density = FALSE -/obj/effect/particle_effect/steam/Initialize() +/obj/effect/particle_effect/steam/Initialize(mapload) . = ..() QDEL_IN(src, 20) diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm index 979b811bc5..5d573c5a43 100644 --- a/code/game/objects/effects/effects.dm +++ b/code/game/objects/effects/effects.dm @@ -18,9 +18,6 @@ /obj/effect/acid_act() return -/obj/effect/mech_melee_attack(obj/mecha/M) - return 0 - /obj/effect/blob_act(obj/structure/blob/B) return @@ -30,7 +27,7 @@ /obj/effect/experience_pressure_difference() return -/obj/effect/ex_act(severity, target) +/obj/effect/ex_act(severity, target, origin) if(target == src) qdel(src) else @@ -51,7 +48,7 @@ /obj/effect/ConveyorMove() return -/obj/effect/abstract/ex_act(severity, target) +/obj/effect/abstract/ex_act(severity, target, origin) return /obj/effect/abstract/singularity_pull() diff --git a/code/game/objects/effects/forcefields.dm b/code/game/objects/effects/forcefields.dm index 384cf73c89..c16c9751a8 100644 --- a/code/game/objects/effects/forcefields.dm +++ b/code/game/objects/effects/forcefields.dm @@ -8,7 +8,7 @@ CanAtmosPass = ATMOS_PASS_DENSITY var/timeleft = 300 //Set to 0 for permanent forcefields (ugh) -/obj/effect/forcefield/Initialize() +/obj/effect/forcefield/Initialize(mapload) . = ..() if(timeleft) QDEL_IN(src, timeleft) diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 6910bb1db0..22a9e86bb0 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -11,7 +11,7 @@ return // Please stop bombing the Observer-Start landmark. -/obj/effect/landmark/ex_act() +/obj/effect/landmark/ex_act(severity, target, origin) return /obj/effect/landmark/singularity_pull() @@ -19,7 +19,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) -/obj/effect/landmark/Initialize() +/obj/effect/landmark/Initialize(mapload) . = ..() GLOB.landmarks_list += src @@ -64,6 +64,10 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) name = "Assistant" icon_state = "Assistant" +/obj/effect/landmark/start/prisoner + name = "Prisoner" + icon_state = "Prisoner" + /obj/effect/landmark/start/assistant/override jobspawn_override = TRUE delete_after_roundstart = FALSE @@ -241,7 +245,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) icon = 'icons/effects/landmarks_static.dmi' icon_state = "wiznerd_spawn" -/obj/effect/landmark/start/wizard/Initialize() +/obj/effect/landmark/start/wizard/Initialize(mapload) ..() GLOB.wizardstart += loc return INITIALIZE_HINT_QDEL @@ -251,7 +255,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) icon = 'icons/effects/landmarks_static.dmi' icon_state = "snukeop_spawn" -/obj/effect/landmark/start/nukeop/Initialize() +/obj/effect/landmark/start/nukeop/Initialize(mapload) ..() GLOB.nukeop_start += loc return INITIALIZE_HINT_QDEL @@ -261,7 +265,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) icon = 'icons/effects/landmarks_static.dmi' icon_state = "snukeop_leader_spawn" -/obj/effect/landmark/start/nukeop_leader/Initialize() +/obj/effect/landmark/start/nukeop_leader/Initialize(mapload) ..() GLOB.nukeop_leader_start += loc return INITIALIZE_HINT_QDEL @@ -273,7 +277,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) /obj/effect/landmark/start/new_player name = "New Player" -/obj/effect/landmark/start/new_player/Initialize() +/obj/effect/landmark/start/new_player/Initialize(mapload) ..() GLOB.newplayer_start += loc return INITIALIZE_HINT_QDEL @@ -524,3 +528,70 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) name = "portal exit" icon_state = "portal_exit" var/id + +/obj/effect/landmark/start/hangover + name = "hangover spawn" + icon_state = "hangover_spawn" + + /// A list of everything this hangover spawn created + var/list/debris = list() + +/obj/effect/landmark/start/hangover/Initialize(mapload) + . = ..() + return INITIALIZE_HINT_LATELOAD + +/obj/effect/landmark/start/hangover/Destroy() + debris = null + return ..() + +/obj/effect/landmark/start/hangover/LateInitialize() + . = ..() + if(!HAS_TRAIT(SSstation, STATION_TRAIT_HANGOVER)) + return + if(prob(60)) + debris += new /obj/effect/decal/cleanable/vomit(get_turf(src)) + if(prob(70)) + var/bottle_count = rand(1, 3) + for(var/index in 1 to bottle_count) + var/turf/turf_to_spawn_on = get_step(src, pick(GLOB.alldirs)) + if(!isopenturf(turf_to_spawn_on)) + continue + var/dense_object = FALSE + for(var/atom/content in turf_to_spawn_on.contents) + if(content.density) + dense_object = TRUE + break + if(dense_object) + continue + debris += new /obj/item/reagent_containers/food/drinks/beer/almost_empty(turf_to_spawn_on) + +///Spawns the mob with some drugginess/drunkeness, and some disgust. +/obj/effect/landmark/start/hangover/proc/make_hungover(mob/hangover_mob) + if(!iscarbon(hangover_mob)) + return + var/mob/living/carbon/spawned_carbon = hangover_mob + spawned_carbon.set_resting(TRUE, silent = TRUE) + if(prob(50)) + spawned_carbon.adjust_drugginess(rand(15, 20)) + else + spawned_carbon.drunkenness += rand(15, 25) + spawned_carbon.adjust_disgust(rand(5, 55)) //How hungover are you? + if(spawned_carbon.head) + return + +/obj/effect/landmark/start/hangover/JoinPlayerHere(mob/joining_mob, buckle) + . = ..() + make_hungover(joining_mob) + +/obj/effect/landmark/start/hangover/closet + name = "hangover spawn closet" + icon_state = "hangover_spawn_closet" + +/obj/effect/landmark/start/hangover/closet/JoinPlayerHere(mob/joining_mob, buckle) + make_hungover(joining_mob) + for(var/obj/structure/closet/closet in contents) + if(closet.opened) + continue + joining_mob.forceMove(closet) + return + return ..() //Call parent as fallback diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index b0e801137d..a1edac02a3 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -116,7 +116,7 @@ density = FALSE var/duration = 0 -/obj/effect/mine/pickup/Initialize() +/obj/effect/mine/pickup/Initialize(mapload) . = ..() animate(src, pixel_y = 4, time = 20, loop = -1) diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 6be0a50a5e..945136466f 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -13,7 +13,7 @@ icon_state="b_beam" var/atom/BeamSource -/obj/effect/overlay/beam/Initialize() +/obj/effect/overlay/beam/Initialize(mapload) . = ..() QDEL_IN(src, 10) diff --git a/code/game/objects/effects/spawners/bombspawner.dm b/code/game/objects/effects/spawners/bombspawner.dm index fb92e31f1e..953468f1ff 100644 --- a/code/game/objects/effects/spawners/bombspawner.dm +++ b/code/game/objects/effects/spawners/bombspawner.dm @@ -13,7 +13,7 @@ var/pressure_o = 10 * ONE_ATMOSPHERE //tank pressures var/assembly_type -/obj/effect/spawner/newbomb/Initialize() +/obj/effect/spawner/newbomb/Initialize(mapload) . = ..() var/obj/item/transfer_valve/V = new(src.loc) var/obj/item/tank/internals/plasma/PT = new(V) @@ -39,7 +39,7 @@ return INITIALIZE_HINT_QDEL -/obj/effect/spawner/newbomb/timer/syndicate/Initialize() +/obj/effect/spawner/newbomb/timer/syndicate/Initialize(mapload) temp_p = (OPTIMAL_TEMP_K_PLA_BURN_SCALE(pressure_p, pressure_o, temp_o)/2 + OPTIMAL_TEMP_K_PLA_BURN_RATIO(pressure_p, pressure_o, temp_o)/2) - T0C . = ..() diff --git a/code/game/objects/effects/spawners/bundle.dm b/code/game/objects/effects/spawners/bundle.dm index 58cd0f4fa9..9e5d80248d 100644 --- a/code/game/objects/effects/spawners/bundle.dm +++ b/code/game/objects/effects/spawners/bundle.dm @@ -169,14 +169,21 @@ /obj/item/clothing/mask/gas/mime/sexy, /obj/item/clothing/under/rank/civilian/mime/sexy) +/obj/effect/spawner/bundle/crate + var/pickone = FALSE + /obj/effect/spawner/bundle/crate/Initialize(mapload) SHOULD_CALL_PARENT(FALSE) if(items && items.len) var/turf/T = get_turf(src) var/obj/structure/closet/LC = locate(/obj/structure/closet) in T if(LC) - for(var/path in items) - new path(LC) + if(pickone) + var/tospawn = pick(items) + new tospawn(LC) + else + for(var/path in items) + new path(LC) return INITIALIZE_HINT_QDEL /obj/effect/spawner/bundle/crate/mosin @@ -192,3 +199,29 @@ /obj/item/gun/ballistic/automatic/surplus, /obj/item/ammo_box/magazine/m10mm/rifle ) + +/obj/effect/spawner/bundle/crate/levergun + name = "lever-action rifle spawner" + items = list( + /obj/item/gun/ballistic/shotgun/leveraction, + /obj/item/ammo_box/c38/pouch + ) + +/obj/effect/spawner/bundle/crate/cowboyhat + name = "cowboy hat spawner" + pickone = TRUE + items = list( + /obj/item/clothing/head/cowboyhat, + /obj/item/clothing/head/cowboyhat/black, + /obj/item/clothing/head/cowboyhat/white, + /obj/item/clothing/head/cowboyhat/pink, + /obj/item/clothing/head/cowboyhat/sec + ) + +/obj/effect/spawner/bundle/crate/cowboyboots + name = "cowboy boots spawner" + pickone = TRUE + items = list( + /obj/item/clothing/shoes/cowboyboots, + /obj/item/clothing/shoes/cowboyboots/black + ) diff --git a/code/game/objects/effects/spawners/gibspawner.dm b/code/game/objects/effects/spawners/gibspawner.dm index 231c1465cd..65c6c35c9e 100644 --- a/code/game/objects/effects/spawners/gibspawner.dm +++ b/code/game/objects/effects/spawners/gibspawner.dm @@ -31,7 +31,10 @@ var/list/dna_to_add //find the dna to pass to the spawned gibs. do note this can be null if the mob doesn't have blood. add_blood_DNA() has built in null handling. var/body_coloring = "" + + var/list/blood_data_to_add if(source_mob) + blood_data_to_add = source_mob.get_blood_data() if(!issilicon(source_mob)) dna_to_add = blood_dna || source_mob.get_blood_dna_list() //ez pz if(ishuman(source_mob)) @@ -65,7 +68,7 @@ if(gibamounts[i]) for(var/j = 1, j<= gibamounts[i], j++) var/gibType = gibtypes[i] - gib = new gibType(loc, diseases) + gib = new gibType(loc, diseases, blood_data_to_add) if(iscarbon(loc)) var/mob/living/carbon/digester = loc digester.stomach_contents += gib @@ -88,7 +91,7 @@ gibamounts = list(2, 2, 1) sound_vol = 40 -/obj/effect/gibspawner/generic/Initialize() +/obj/effect/gibspawner/generic/Initialize(mapload) if(!gibdirections.len) gibdirections = list(list(WEST, NORTHWEST, SOUTHWEST, NORTH),list(EAST, NORTHEAST, SOUTHEAST, SOUTH), list()) return ..() @@ -103,7 +106,7 @@ gib_mob_species = /datum/species/human sound_vol = 50 -/obj/effect/gibspawner/human/Initialize() +/obj/effect/gibspawner/human/Initialize(mapload) if(!gibdirections.len) gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list()) return ..() @@ -112,7 +115,7 @@ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human/core, /obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human/core, /obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human/torso) gibamounts = list(1, 1, 1, 1, 1, 1) -/obj/effect/gibspawner/human/bodypartless/Initialize() +/obj/effect/gibspawner/human/bodypartless/Initialize(mapload) if(!gibdirections.len) gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list()) return ..() @@ -124,7 +127,7 @@ gib_mob_species = /datum/species/lizard sound_vol = 50 -/obj/effect/gibspawner/lizard/Initialize() +/obj/effect/gibspawner/lizard/Initialize(mapload) if(!gibdirections.len) gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list()) return ..() @@ -133,7 +136,7 @@ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard/core, /obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard/core, /obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard/torso) gibamounts = list(1, 1, 1, 1, 1, 1) -/obj/effect/gibspawner/lizard/bodypartless/Initialize() +/obj/effect/gibspawner/lizard/bodypartless/Initialize(mapload) if(!gibdirections.len) gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list()) return ..() @@ -145,7 +148,7 @@ gib_mob_species = /datum/species/jelly/roundstartslime sound_vol = 50 -/obj/effect/gibspawner/slime/Initialize() +/obj/effect/gibspawner/slime/Initialize(mapload) if(!gibdirections.len) gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list()) return ..() @@ -154,7 +157,7 @@ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime/core, /obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime/core, /obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime/torso) gibamounts = list(1, 1, 1, 1, 1, 1) -/obj/effect/gibspawner/slime/bodypartless/Initialize() +/obj/effect/gibspawner/slime/bodypartless/Initialize(mapload) if(!gibdirections.len) gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list()) return ..() @@ -168,7 +171,7 @@ sparks = TRUE sound_to_play = 'sound/effects/bang.ogg' -/obj/effect/gibspawner/ipc/Initialize() +/obj/effect/gibspawner/ipc/Initialize(mapload) if(!gibdirections.len) gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list()) return ..() @@ -177,7 +180,7 @@ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc/core, /obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc/core, /obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc/torso) gibamounts = list(1, 1, 1, 1, 1, 1) -/obj/effect/gibspawner/ipc/bodypartless/Initialize() +/obj/effect/gibspawner/ipc/bodypartless/Initialize(mapload) if(!gibdirections.len) gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list()) return ..() @@ -187,7 +190,7 @@ gibamounts = list(1, 1, 1, 1, 1, 1, 1) gib_mob_type = /mob/living/carbon/alien -/obj/effect/gibspawner/xeno/Initialize() +/obj/effect/gibspawner/xeno/Initialize(mapload) if(!gibdirections.len) gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list()) return ..() @@ -196,7 +199,7 @@ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/core, /obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/core, /obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/torso) gibamounts = list(1, 1, 1, 1, 1, 1) -/obj/effect/gibspawner/xeno/bodypartless/Initialize() +/obj/effect/gibspawner/xeno/bodypartless/Initialize(mapload) if(!gibdirections.len) gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list()) return ..() @@ -212,7 +215,7 @@ gibamounts = list(1, 1, 1, 1) gib_mob_type = /mob/living/carbon/alien/larva -/obj/effect/gibspawner/larva/Initialize() +/obj/effect/gibspawner/larva/Initialize(mapload) if(!gibdirections.len) gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list(), GLOB.alldirs) return ..() @@ -221,7 +224,7 @@ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno/larva, /obj/effect/decal/cleanable/blood/gibs/xeno/larva, /obj/effect/decal/cleanable/blood/gibs/xeno/larva) gibamounts = list(1, 1, 1) -/obj/effect/gibspawner/larva/bodypartless/Initialize() +/obj/effect/gibspawner/larva/bodypartless/Initialize(mapload) if(!gibdirections.len) gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list()) return ..() @@ -232,7 +235,7 @@ gibamounts = list(1, 1, 1, 1, 1, 1) gib_mob_type = /mob/living/silicon/robot -/obj/effect/gibspawner/robot/Initialize() +/obj/effect/gibspawner/robot/Initialize(mapload) if(!gibdirections.len) gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs) gibamounts[6] = pick(0, 1, 2) diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index 5a0e1790a9..0f7e00a538 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -2,6 +2,7 @@ icon = 'icons/effects/landmarks_static.dmi' icon_state = "random_loot" layer = OBJ_LAYER + var/spawn_on_init = TRUE var/spawn_on_turf = TRUE var/lootcount = 1 //how many items will be spawned var/lootdoubles = TRUE //if the same item can be spawned twice @@ -10,10 +11,19 @@ /obj/effect/spawner/lootdrop/Initialize(mapload) ..() + if(should_spawn_on_init()) + spawn_loot() + return INITIALIZE_HINT_QDEL + +/obj/effect/spawner/lootdrop/proc/should_spawn_on_init() + return spawn_on_init + +/obj/effect/spawner/lootdrop/proc/spawn_loot(lootcount_override) + var/lootcount = isnull(lootcount_override) ? src.lootcount : lootcount_override if(loot && loot.len) var/atom/A = spawn_on_turf ? get_turf(src) : loc var/loot_spawned = 0 - while((lootcount-loot_spawned) && loot.len) + while((lootcount-loot_spawned) > 0 && loot.len) var/lootspawn = pickweight(loot) if(!lootdoubles) loot.Remove(lootspawn) @@ -29,7 +39,6 @@ if (loot_spawned) spawned_loot.pixel_x = spawned_loot.pixel_y = ((!(loot_spawned%2)*loot_spawned/2)*-1)+((loot_spawned%2)*(loot_spawned+1)/2*1) loot_spawned++ - return INITIALIZE_HINT_QDEL /obj/effect/spawner/lootdrop/bedsheet icon = 'icons/obj/bedsheets.dmi' @@ -60,6 +69,48 @@ /obj/item/gun/ballistic/automatic/pistol/deagle, /obj/item/storage/box/syndie_kit/throwing_weapons = 3) +/obj/effect/spawner/lootdrop/prison_contraband + name = "prison contraband loot spawner" + loot = list(/obj/item/clothing/mask/cigarette/space_cigarette = 4, + /obj/item/clothing/mask/cigarette/robust = 2, + /obj/item/clothing/mask/cigarette/carp = 3, + /obj/item/clothing/mask/cigarette/uplift = 2, + /obj/item/clothing/mask/cigarette/dromedary = 3, + /obj/item/clothing/mask/cigarette/robustgold = 1, + /obj/item/storage/fancy/cigarettes/cigpack_uplift = 3, + /obj/item/storage/fancy/cigarettes = 3, + /obj/item/clothing/mask/cigarette/rollie/cannabis = 4, + /obj/item/toy/crayon/spraycan = 2, + /obj/item/crowbar = 1, + /obj/item/assembly/flash/handheld = 1, + /obj/item/restraints/handcuffs/cable/zipties = 1, + /obj/item/restraints/handcuffs = 1, + /obj/item/radio/off = 1, + /obj/item/lighter = 3, + /obj/item/storage/box/matches = 3, + /obj/item/reagent_containers/syringe/contraband/space_drugs = 1, + /obj/item/reagent_containers/syringe/contraband/krokodil = 1, + /obj/item/reagent_containers/syringe/contraband/crank = 1, + /obj/item/reagent_containers/syringe/contraband/methamphetamine = 1, + /obj/item/reagent_containers/syringe/contraband/bath_salts = 1, + /obj/item/reagent_containers/syringe/contraband/fentanyl = 1, + /obj/item/reagent_containers/syringe/contraband/morphine = 1, + /obj/item/storage/pill_bottle/happy = 1, + /obj/item/storage/pill_bottle/lsd = 1, + /obj/item/storage/pill_bottle/psicodine = 1, + /obj/item/reagent_containers/food/drinks/beer = 4, + /obj/item/reagent_containers/food/drinks/bottle/whiskey = 1, + /obj/item/paper/fluff/jobs/prisoner/letter = 1, + /obj/item/grenade/smokebomb = 1, + /obj/item/flashlight/seclite = 1, + /obj/item/tailclub = 1, //want to buy makeshift wooden club sprite + /obj/item/kitchen/knife/shiv = 4, + /obj/item/kitchen/knife/shiv/carrot = 1, + /obj/item/kitchen/knife = 1, + /obj/item/storage/wallet/random = 1, + /obj/item/pda = 1 + ) + /obj/effect/spawner/lootdrop/gambling name = "gambling valuables spawner" loot = list( @@ -120,12 +171,21 @@ loot = GLOB.maintenance_loot . = ..() +/obj/effect/spawner/lootdrop/maintenance/spawn_loot(lootcount_override) + if(isnull(lootcount_override)) + if(HAS_TRAIT(SSstation, STATION_TRAIT_FILLED_MAINT)) + lootcount_override = round(lootcount * 1.5) + + else if(HAS_TRAIT(SSstation, STATION_TRAIT_EMPTY_MAINT)) + lootcount_override = round(lootcount * 0.5) + . = ..() + /obj/effect/spawner/lootdrop/glowstick name = "random colored glowstick" icon = 'icons/obj/lighting.dmi' icon_state = "random_glowstick" -/obj/effect/spawner/lootdrop/glowstick/Initialize() +/obj/effect/spawner/lootdrop/glowstick/Initialize(mapload) loot = typesof(/obj/item/flashlight/glowstick) . = ..() @@ -180,7 +240,7 @@ /obj/effect/spawner/lootdrop/costume name = "random costume spawner" -/obj/effect/spawner/lootdrop/costume/Initialize() +/obj/effect/spawner/lootdrop/costume/Initialize(mapload) loot = list() for(var/path in subtypesof(/obj/effect/spawner/bundle/costume)) loot[path] = TRUE @@ -256,7 +316,7 @@ icon = 'icons/obj/storage.dmi' icon_state = "mre" -/obj/effect/spawner/lootdrop/mre/Initialize() +/obj/effect/spawner/lootdrop/mre/Initialize(mapload) for(var/A in subtypesof(/obj/item/storage/box/mre)) var/obj/item/storage/box/mre/M = A var/our_chance = initial(M.spawner_chance) diff --git a/code/game/objects/effects/spawners/structure.dm b/code/game/objects/effects/spawners/structure.dm index 7a151c4312..e55a7daa52 100644 --- a/code/game/objects/effects/spawners/structure.dm +++ b/code/game/objects/effects/spawners/structure.dm @@ -8,7 +8,7 @@ again. name = "map structure spawner" var/list/spawn_list -/obj/effect/spawner/structure/Initialize() +/obj/effect/spawner/structure/Initialize(mapload) . = ..() if(spawn_list && spawn_list.len) for(var/I in spawn_list) @@ -27,7 +27,7 @@ again. var/electrochromatic var/electrochromatic_id -/obj/effect/spawner/structure/window/Initialize() +/obj/effect/spawner/structure/window/Initialize(mapload) . = ..() if(!electrochromatic) return @@ -50,7 +50,7 @@ again. /obj/effect/spawner/structure/window/hollow/end icon_state = "hwindow_spawner_end" -/obj/effect/spawner/structure/window/hollow/end/Initialize() +/obj/effect/spawner/structure/window/hollow/end/Initialize(mapload) switch(dir) if(NORTH) spawn_list = list(/obj/structure/grille, /obj/structure/window/spawner/north, /obj/structure/window/spawner/east, /obj/structure/window/spawner/west) @@ -65,7 +65,7 @@ again. /obj/effect/spawner/structure/window/hollow/middle icon_state = "hwindow_spawner_middle" -/obj/effect/spawner/structure/window/hollow/middle/Initialize() +/obj/effect/spawner/structure/window/hollow/middle/Initialize(mapload) switch(dir) if(NORTH,SOUTH) spawn_list = list(/obj/structure/grille, /obj/structure/window, /obj/structure/window/spawner/north) @@ -76,7 +76,7 @@ again. /obj/effect/spawner/structure/window/hollow/directional icon_state = "hwindow_spawner_directional" -/obj/effect/spawner/structure/window/hollow/directional/Initialize() +/obj/effect/spawner/structure/window/hollow/directional/Initialize(mapload) switch(dir) if(NORTH) spawn_list = list(/obj/structure/grille, /obj/structure/window/spawner/north) @@ -111,7 +111,7 @@ again. /obj/effect/spawner/structure/window/hollow/reinforced/end icon_state = "hrwindow_spawner_end" -/obj/effect/spawner/structure/window/hollow/reinforced/end/Initialize() +/obj/effect/spawner/structure/window/hollow/reinforced/end/Initialize(mapload) switch(dir) if(NORTH) spawn_list = list(/obj/structure/grille, /obj/structure/window/reinforced/spawner/north, /obj/structure/window/reinforced/spawner/east, /obj/structure/window/reinforced/spawner/west) @@ -126,7 +126,7 @@ again. /obj/effect/spawner/structure/window/hollow/reinforced/middle icon_state = "hrwindow_spawner_middle" -/obj/effect/spawner/structure/window/hollow/reinforced/middle/Initialize() +/obj/effect/spawner/structure/window/hollow/reinforced/middle/Initialize(mapload) switch(dir) if(NORTH,SOUTH) spawn_list = list(/obj/structure/grille, /obj/structure/window/reinforced, /obj/structure/window/reinforced/spawner/north) @@ -137,7 +137,7 @@ again. /obj/effect/spawner/structure/window/hollow/reinforced/directional icon_state = "hrwindow_spawner_directional" -/obj/effect/spawner/structure/window/hollow/reinforced/directional/Initialize() +/obj/effect/spawner/structure/window/hollow/reinforced/directional/Initialize(mapload) switch(dir) if(NORTH) spawn_list = list(/obj/structure/grille, /obj/structure/window/reinforced/spawner/north) @@ -211,7 +211,7 @@ again. /obj/effect/spawner/structure/window/hollow/survival_pod/end icon_state = "podwindow_spawner_end" -/obj/effect/spawner/structure/window/hollow/survival_pod/end/Initialize() +/obj/effect/spawner/structure/window/hollow/survival_pod/end/Initialize(mapload) switch(dir) if(NORTH) spawn_list = list(/obj/structure/grille, /obj/structure/window/shuttle/survival_pod/spawner/north, /obj/structure/window/shuttle/survival_pod/spawner/east, /obj/structure/window/shuttle/survival_pod/spawner/west) @@ -226,7 +226,7 @@ again. /obj/effect/spawner/structure/window/hollow/survival_pod/middle icon_state = "podwindow_spawner_middle" -/obj/effect/spawner/structure/window/hollow/survival_pod/middle/Initialize() +/obj/effect/spawner/structure/window/hollow/survival_pod/middle/Initialize(mapload) switch(dir) if(NORTH,SOUTH) spawn_list = list(/obj/structure/grille, /obj/structure/window/shuttle/survival_pod, /obj/structure/window/shuttle/survival_pod/spawner/north) @@ -237,7 +237,7 @@ again. /obj/effect/spawner/structure/window/hollow/survival_pod/directional icon_state = "podwindow_spawner_directional" -/obj/effect/spawner/structure/window/hollow/survival_pod/directional/Initialize() +/obj/effect/spawner/structure/window/hollow/survival_pod/directional/Initialize(mapload) switch(dir) if(NORTH) spawn_list = list(/obj/structure/grille, /obj/structure/window/shuttle/survival_pod/spawner/north) @@ -273,7 +273,7 @@ again. /obj/effect/spawner/structure/window/hollow/plasma/end icon_state = "phwindow_spawner_end" -/obj/effect/spawner/structure/window/hollow/plasma/end/Initialize() +/obj/effect/spawner/structure/window/hollow/plasma/end/Initialize(mapload) switch(dir) if(NORTH) spawn_list = list(/obj/structure/grille, /obj/structure/window/plasma/spawner/north, /obj/structure/window/plasma/spawner/east, /obj/structure/window/plasma/spawner/west) @@ -288,7 +288,7 @@ again. /obj/effect/spawner/structure/window/hollow/plasma/middle icon_state = "phwindow_spawner_middle" -/obj/effect/spawner/structure/window/hollow/plasma/middle/Initialize() +/obj/effect/spawner/structure/window/hollow/plasma/middle/Initialize(mapload) switch(dir) if(NORTH,SOUTH) spawn_list = list(/obj/structure/grille, /obj/structure/window/plasma, /obj/structure/window/plasma/spawner/north) @@ -299,7 +299,7 @@ again. /obj/effect/spawner/structure/window/hollow/plasma/directional icon_state = "phwindow_spawner_directional" -/obj/effect/spawner/structure/window/hollow/plasma/directional/Initialize() +/obj/effect/spawner/structure/window/hollow/plasma/directional/Initialize(mapload) switch(dir) if(NORTH) spawn_list = list(/obj/structure/grille, /obj/structure/window/plasma/spawner/north) @@ -334,7 +334,7 @@ again. /obj/effect/spawner/structure/window/hollow/plasma/reinforced/end icon_state = "phrwindow_spawner_end" -/obj/effect/spawner/structure/window/hollow/plasma/reinforced/end/Initialize() +/obj/effect/spawner/structure/window/hollow/plasma/reinforced/end/Initialize(mapload) switch(dir) if(NORTH) spawn_list = list(/obj/structure/grille, /obj/structure/window/plasma/reinforced/spawner/north, /obj/structure/window/plasma/reinforced/spawner/east, /obj/structure/window/plasma/reinforced/spawner/west) @@ -349,7 +349,7 @@ again. /obj/effect/spawner/structure/window/hollow/plasma/reinforced/middle icon_state = "phrwindow_spawner_middle" -/obj/effect/spawner/structure/window/hollow/plasma/reinforced/middle/Initialize() +/obj/effect/spawner/structure/window/hollow/plasma/reinforced/middle/Initialize(mapload) switch(dir) if(NORTH,SOUTH) spawn_list = list(/obj/structure/grille, /obj/structure/window/plasma/reinforced, /obj/structure/window/plasma/reinforced/spawner/north) @@ -360,7 +360,7 @@ again. /obj/effect/spawner/structure/window/hollow/plasma/reinforced/directional icon_state = "phrwindow_spawner_directional" -/obj/effect/spawner/structure/window/hollow/plasma/reinforced/directional/Initialize() +/obj/effect/spawner/structure/window/hollow/plasma/reinforced/directional/Initialize(mapload) switch(dir) if(NORTH) spawn_list = list(/obj/structure/grille, /obj/structure/window/plasma/reinforced/spawner/north) diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 4b04606401..11830c009c 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -15,7 +15,7 @@ /obj/structure/spider/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee") + if(damage_flag == MELEE) switch(damage_type) if(BURN) damage_amount *= 2 @@ -31,12 +31,13 @@ var/genetic = FALSE icon_state = "stickyweb1" -/obj/structure/spider/stickyweb/Initialize() +/obj/structure/spider/stickyweb/Initialize(mapload) if(prob(50)) icon_state = "stickyweb2" . = ..() -/obj/structure/spider/stickyweb/CanPass(atom/movable/mover, turf/target) +/obj/structure/spider/stickyweb/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if (genetic) return if(istype(mover, /mob/living/simple_animal/hostile/poison/giant_spider)) @@ -49,7 +50,6 @@ return FALSE else if(istype(mover, /obj/item/projectile)) return prob(30) - return TRUE /obj/structure/spider/stickyweb/genetic //for the spider genes in genetics genetic = TRUE @@ -84,7 +84,7 @@ var/poison_per_bite = 5 var/list/faction = list("spiders") -/obj/structure/spider/eggcluster/Initialize() +/obj/structure/spider/eggcluster/Initialize(mapload) pixel_x = rand(3,-3) pixel_y = rand(3,-3) START_PROCESSING(SSobj, src) @@ -127,7 +127,7 @@ new/obj/item/reagent_containers/food/snacks/spiderling(get_turf(src)) . = ..() -/obj/structure/spider/spiderling/Initialize() +/obj/structure/spider/spiderling/Initialize(mapload) . = ..() pixel_x = rand(6,-6) pixel_y = rand(6,-6) @@ -248,7 +248,7 @@ icon_state = "cocoon1" max_integrity = 60 -/obj/structure/spider/cocoon/Initialize() +/obj/structure/spider/cocoon/Initialize(mapload) icon_state = pick("cocoon1","cocoon2","cocoon3") . = ..() diff --git a/code/game/objects/effects/temporary_visuals/clockcult.dm b/code/game/objects/effects/temporary_visuals/clockcult.dm index 9a236c00c3..64c34ad1cd 100644 --- a/code/game/objects/effects/temporary_visuals/clockcult.dm +++ b/code/game/objects/effects/temporary_visuals/clockcult.dm @@ -69,7 +69,7 @@ pixel_y = 20 duration = 20 -/obj/effect/temp_visual/ratvar/belligerent_cast/Initialize() +/obj/effect/temp_visual/ratvar/belligerent_cast/Initialize(mapload) . = ..() animate(src, alpha = 0, time = duration, easing = EASE_OUT) @@ -129,14 +129,18 @@ "Your [I.name] shields you from [src]!") continue L.visible_message("[L] is struck by a [name]!", "You're struck by a [name]!") - L.apply_damage(damage, BURN, "chest", L.run_armor_check("chest", "laser", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 0, "Your armor was penetrated by [src]!")) + L.apply_damage(damage, BURN, "chest", L.run_armor_check("chest", LASER, "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 0, "Your armor was penetrated by [src]!")) log_combat(user, L, "struck with a volt blast") hit_amount++ - for(var/obj/mecha/M in T) - if(M.occupant) - if(is_servant_of_ratvar(M.occupant)) - continue - to_chat(M.occupant, "Your [M.name] is struck by a [name]!") + for(var/obj/vehicle/sealed/mecha/M in T) + if(LAZYLEN(M.occupants)) + for(var/mob/living/MB in M.occupants) + if(is_servant_of_ratvar(MB)) + continue + else + to_chat(MB, "Your [M.name] is struck by a [name]!") + continue + M.visible_message("[M] is struck by a [name]!") M.take_damage(damage, BURN, 0, 0) hit_amount++ @@ -145,7 +149,7 @@ else playsound(src, "sparks", 50, 1) -/obj/effect/temp_visual/ratvar/ocular_warden/Initialize() +/obj/effect/temp_visual/ratvar/ocular_warden/Initialize(mapload) . = ..() pixel_x = rand(-8, 8) pixel_y = rand(-10, 10) @@ -184,7 +188,7 @@ layer = ABOVE_MOB_LAYER duration = 10 -/obj/effect/temp_visual/ratvar/component/Initialize() +/obj/effect/temp_visual/ratvar/component/Initialize(mapload) . = ..() transform = matrix()*0.75 pixel_x = rand(-10, 10) @@ -215,7 +219,7 @@ light_power = 2 light_color = "#FAE48C" -/obj/effect/temp_visual/ratvar/sigil/transgression/Initialize() +/obj/effect/temp_visual/ratvar/sigil/transgression/Initialize(mapload) . = ..() var/oldtransform = transform animate(src, transform = matrix()*2, time = 5) @@ -277,7 +281,7 @@ /obj/effect/temp_visual/steam_release name = "all the steam" -/obj/effect/temp_visual/steam_release/Initialize() +/obj/effect/temp_visual/steam_release/Initialize(mapload) ..() for(var/V in GLOB.cardinals) var/turf/T = get_step(src, V) diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index d7eeb2789b..543bad1fb8 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -4,6 +4,7 @@ duration = 5 randomdir = FALSE layer = BELOW_MOB_LAYER + color = BLOOD_COLOR_HUMAN // set it to red by default because the actual icons are white var/splatter_type = "splatter" /obj/effect/temp_visual/dir_setting/bloodsplatter/Initialize(mapload, set_dir, new_color) diff --git a/code/game/objects/effects/temporary_visuals/temporary_visual.dm b/code/game/objects/effects/temporary_visuals/temporary_visual.dm index 615f392a86..bf4e82f7b7 100644 --- a/code/game/objects/effects/temporary_visuals/temporary_visual.dm +++ b/code/game/objects/effects/temporary_visuals/temporary_visual.dm @@ -8,7 +8,7 @@ var/randomdir = TRUE var/timerid -/obj/effect/temp_visual/Initialize() +/obj/effect/temp_visual/Initialize(mapload) . = ..() if(randomdir) setDir(pick(GLOB.cardinals)) @@ -25,7 +25,7 @@ /obj/effect/temp_visual/singularity_pull() return -/obj/effect/temp_visual/ex_act() +/obj/effect/temp_visual/ex_act(severity, target, origin) return /obj/effect/temp_visual/dir_setting diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index cd486ccf6b..7a953089a5 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -1,4 +1,5 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/effects/fire.dmi', "fire")) +GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons/effects/welding_effect.dmi', "welding_sparks", GASFIRE_LAYER, ABOVE_LIGHTING_PLANE)) GLOBAL_VAR_INIT(rpg_loot_items, FALSE) // if true, everyone item when created will have its name changed to be @@ -46,11 +47,23 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb max_integrity = 200 obj_flags = NONE + ///Item flags for the item var/item_flags = NONE - var/hitsound = null - var/usesound = null - var/throwhitsound = null + ///Sound played when you hit something with the item + var/hitsound + ///Played when the item is used, for example tools + var/usesound + ///Used when yate into a mob + var/mob_throw_hit_sound + ///Sound used when equipping the item into a valid slot + var/equip_sound + ///Sound uses when picking the item up (into your hands) + var/pickup_sound + ///Sound uses when dropping the item, or when its thrown. + var/drop_sound + ///Whether or not we use stealthy audio levels for this item's attack sounds + var/stealthy_audio = FALSE /// Weight class for how much storage capacity it uses and how big it physically is meaning storages can't hold it if their maximum weight class isn't as high as it. var/w_class = WEIGHT_CLASS_NORMAL @@ -129,9 +142,9 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb var/datum/dog_fashion/dog_fashion = null //Tooltip vars - var/force_string //string form of an item's force. Edit this var only to set a custom force string + ///string form of an item's force. Edit this var only to set a custom force string + var/force_string var/last_force_string_check = 0 - var/tip_timer var/trigger_guard = TRIGGER_GUARD_NONE @@ -146,6 +159,9 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder! + //the outline filter on hover + var/outline_filter + /* Our block parry data. Should be set in init, or something if you are using it. * This won't be accessed without ITEM_CAN_BLOCK or ITEM_CAN_PARRY so do not set it unless you have to to save memory. * If you decide it's a good idea to leave this unset while turning the flags on, you will runtime. Enjoy. @@ -162,7 +178,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb var/canMouseDown = FALSE -/obj/item/Initialize() +/obj/item/Initialize(mapload) if(attack_verb) attack_verb = typelist("attack_verb", attack_verb) @@ -175,6 +191,12 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb if(force_string) item_flags |= FORCE_STRING_OVERRIDE + if(istype(loc, /obj/item/storage)) + item_flags |= IN_STORAGE + + if(istype(loc, /obj/item/robot_module)) + item_flags |= IN_INVENTORY + if(!hitsound) if(damtype == "fire") hitsound = 'sound/items/welder.ogg' @@ -323,15 +345,20 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb return ..() /obj/item/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) + . = ..() + if(.) + return if(!user) return if(anchored) return - if(loc == user && current_equipped_slot && current_equipped_slot != SLOT_HANDS) + if(loc == user && current_equipped_slot && current_equipped_slot != ITEM_SLOT_HANDS) if(current_equipped_slot in user.check_obscured_slots()) to_chat(user, "You are unable to unequip that while wearing other garments over it!") return FALSE + . = TRUE + if(resistance_flags & ON_FIRE) var/mob/living/carbon/C = user var/can_handle_hot = FALSE @@ -366,17 +393,21 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb //If the item is in a storage item, take it out SEND_SIGNAL(loc, COMSIG_TRY_STORAGE_TAKE, src, user.loc, TRUE) + if(QDELETED(src)) //moving it out of the storage to the floor destroyed it. + return if(throwing) throwing.finalize(FALSE) if(loc == user) - if(!allow_attack_hand_drop(user) || !user.temporarilyRemoveItemFromInventory(src)) + if(!allow_attack_hand_drop(user) || !user.temporarilyRemoveItemFromInventory(I = src)) return + . = FALSE pickup(user) add_fingerprint(user) if(!user.put_in_active_hand(src, FALSE, FALSE)) user.dropItemToGround(src) + return TRUE /obj/item/proc/allow_attack_hand_drop(mob/user) return TRUE @@ -386,7 +417,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb return if(anchored) return - if(loc == user && current_equipped_slot && current_equipped_slot != SLOT_HANDS) + if(loc == user && current_equipped_slot && current_equipped_slot != ITEM_SLOT_HANDS) if(current_equipped_slot in user.check_obscured_slots()) to_chat(user, "You are unable to unequip that while wearing other garments over it!") return FALSE @@ -397,7 +428,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb if(throwing) throwing.finalize(FALSE) if(loc == user) - if(!user.temporarilyRemoveItemFromInventory(src)) + if(!allow_attack_hand_drop(user) || !user.temporarilyRemoveItemFromInventory(src)) return pickup(user) @@ -441,10 +472,11 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb A.Remove(user) if(item_flags & DROPDEL) qdel(src) - item_flags &= ~IN_INVENTORY + item_flags &= ~(IN_INVENTORY) + item_flags &= ~(IN_STORAGE) SEND_SIGNAL(src, COMSIG_ITEM_DROPPED,user) - // if(!silent) - // playsound(src, drop_sound, DROP_SOUND_VOLUME, ignore_walls = FALSE) + if(!silent) + playsound(src, drop_sound, DROP_SOUND_VOLUME, ignore_walls = FALSE) user?.update_equipment_speed_mods() // called just as an item is picked up (loc is not yet changed) @@ -518,6 +550,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb if(item_action_slot_check(slot, user, A)) //some items only give their actions buttons when in a specific slot. A.Grant(user) item_flags |= IN_INVENTORY + if((item_flags & IN_STORAGE)) // Left storage item but somehow has the bitfield active still. + item_flags &= ~(IN_STORAGE) // if(!initial) // if(equip_sound && (slot_flags & slot)) // playsound(src, equip_sound, EQUIP_SOUND_VOLUME, TRUE, ignore_walls = FALSE) @@ -535,7 +569,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb //sometimes we only want to grant the item's action if it's equipped in a specific slot. /obj/item/proc/item_action_slot_check(slot, mob/user, datum/action/A) - if(slot == SLOT_IN_BACKPACK || slot == SLOT_LEGCUFFED) //these aren't true slots, so avoid granting actions there + if(slot == ITEM_SLOT_BACKPACK || slot == ITEM_SLOT_LEGCUFFED) //these aren't true slots, so avoid granting actions there return FALSE return TRUE @@ -557,6 +591,12 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb if(usr.incapacitated() || !Adjacent(usr) || usr.lying) return + if(iscyborg(usr)) + var/obj/item/gripper/gripper = usr.get_active_held_item(TRUE) + if(istype(gripper)) + gripper.pre_attack(src, usr, get_dist(src, usr)) + return + if(usr.get_active_held_item() == null) // Let me know if this has any problems -Yota usr.UnarmedAttack(src) @@ -683,8 +723,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb if(isliving(hit_atom)) //Living mobs handle hit sounds differently. var/volume = get_volume_by_throwforce_and_or_w_class() if (throwforce > 0) - if (throwhitsound) - playsound(hit_atom, throwhitsound, volume, TRUE, -1) + if (mob_throw_hit_sound) + playsound(hit_atom, mob_throw_hit_sound, volume, TRUE, -1) else if(hitsound) playsound(hit_atom, hitsound, volume, TRUE, -1) else @@ -692,8 +732,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb else playsound(hit_atom, 'sound/weapons/throwtap.ogg', 1, volume, -1) - // else - // playsound(src, drop_sound, YEET_SOUND_VOLUME, ignore_walls = FALSE) + else if (drop_sound) + playsound(src, drop_sound, YEET_SOUND_VOLUME, ignore_walls = FALSE) return hit_atom.hitby(src, 0, itempush, throwingdatum=throwingdatum) /obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, messy_throw = TRUE) @@ -778,7 +818,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb if(ismob(location)) var/mob/M = location var/success = FALSE - if(src == M.get_item_by_slot(SLOT_WEAR_MASK)) + if(src == M.get_item_by_slot(ITEM_SLOT_MASK)) success = TRUE if(success) location = get_turf(M) @@ -802,9 +842,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb return ..() return 0 -/obj/item/mech_melee_attack(obj/mecha/M) - return 0 - /obj/item/burn() if(!QDELETED(src)) var/turf/T = get_turf(src) @@ -867,18 +904,55 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb openToolTip(user,src,params,title = name,content = "[desc]
    Force: [force_string]",theme = "") /obj/item/MouseEntered(location, control, params) - if((item_flags & IN_INVENTORY) && usr.client.prefs.enable_tips && !QDELETED(src)) - var/timedelay = usr.client.prefs.tip_delay/100 - var/user = usr - tip_timer = addtimer(CALLBACK(src, .proc/openTip, location, control, params, user), timedelay, TIMER_STOPPABLE)//timer takes delay in deciseconds, but the pref is in milliseconds. dividing by 100 converts it. - -/obj/item/MouseExited(location,control,params) - SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_EXIT, location, control, params) - deltimer(tip_timer)//delete any in-progress timer if the mouse is moved off the item before it finishes - closeToolTip(usr) - -/obj/item/MouseEntered(location,control,params) + . = ..() SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_ENTER, location, control, params) + if(get(src, /mob) == usr && !QDELETED(src)) + var/mob/living/L = usr + if(usr.client.prefs.enable_tips) + var/timedelay = usr.client.prefs.tip_delay/100 + usr.client.tip_timer = addtimer(CALLBACK(src, .proc/openTip, location, control, params, usr), timedelay, TIMER_STOPPABLE)//timer takes delay in deciseconds, but the pref is in milliseconds. dividing by 100 converts it. + if(usr.client.prefs.outline_enabled) + if(istype(L) && L.incapacitated()) + apply_outline(COLOR_RED_GRAY) //if they're dead or handcuffed, let's show the outline as red to indicate that they can't interact with that right now + else + apply_outline(usr.client.prefs.outline_color) //if the player's alive and well we send the command with no color set, so it uses the theme's color + +/obj/item/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) + . = ..() + remove_filter("hover_outline") //get rid of the hover effect in case the mouse exit isn't called if someone drags and drops an item and somthing goes wrong + +/obj/item/MouseExited(location, control, params) + SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_EXIT, location, control, params) + deltimer(usr.client.tip_timer) //delete any in-progress timer if the mouse is moved off the item before it finishes + closeToolTip(usr) + remove_filter("hover_outline") + +/obj/item/proc/apply_outline(outline_color = null) + if(get(src, /mob) != usr || QDELETED(src) || isobserver(usr)) //cancel if the item isn't in an inventory, is being deleted, or if the person hovering is a ghost (so that people spectating you don't randomly make your items glow) + return + var/theme = lowertext(usr.client.prefs.UI_style) + if(!outline_color) //if we weren't provided with a color, take the theme's color + switch(theme) //yeah it kinda has to be this way + if("midnight") + outline_color = COLOR_THEME_MIDNIGHT + if("plasmafire") + outline_color = COLOR_THEME_PLASMAFIRE + if("retro") + outline_color = COLOR_THEME_RETRO //just as garish as the rest of this theme + if("slimecore") + outline_color = COLOR_THEME_SLIMECORE + if("operative") + outline_color = COLOR_THEME_OPERATIVE + if("clockwork") + outline_color = COLOR_THEME_CLOCKWORK //if you want free gbp go fix the fact that clockwork's tooltip css is glass' + if("glass") + outline_color = COLOR_THEME_GLASS + else //this should never happen, hopefully + outline_color = COLOR_WHITE + if(color) + outline_color = COLOR_WHITE //if the item is recolored then the outline will be too, let's make the outline white so it becomes the same color instead of some ugly mix of the theme and the tint + + add_filter("hover_outline", 1, list("type" = "outline", "size" = 1, "color" = outline_color)) // Called when a mob tries to use the item as a tool. // Handles most checks. @@ -1006,7 +1080,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb */ /obj/item/proc/set_slowdown(new_slowdown) slowdown = new_slowdown - if(CHECK_BITFIELD(item_flags, IN_INVENTORY)) + if((item_flags & IN_INVENTORY)) var/mob/living/L = loc if(istype(L)) L.update_equipment_speed_mods() @@ -1015,6 +1089,19 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb . = ..() if(var_name == NAMEOF(src, slowdown)) set_slowdown(var_value) //don't care if it's a duplicate edit as slowdown'll be set, do it anyways to force normal behavior. + +/obj/item/proc/canStrip(mob/stripper, mob/owner) + SHOULD_BE_PURE(TRUE) + return !HAS_TRAIT(src, TRAIT_NODROP) && !(item_flags & ABSTRACT) + +/obj/item/proc/doStrip(mob/stripper, mob/owner) + if(owner.dropItemToGround(src)) + if(stripper.can_hold_items()) + stripper.put_in_hands(src) + return TRUE + else + return FALSE + /** * Does the current embedding var meet the criteria for being harmless? Namely, does it explicitly define the pain multiplier and jostle pain mult to be 0? If so, return true. * @@ -1147,3 +1234,44 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb pain_stam_pct = (!isnull(embedding["pain_stam_pct"]) ? embedding["pain_stam_pct"] : EMBEDDED_PAIN_STAM_PCT),\ embed_chance_turf_mod = (!isnull(embedding["embed_chance_turf_mod"]) ? embedding["embed_chance_turf_mod"] : EMBED_CHANCE_TURF_MOD)) return TRUE + + +/** + * * An interrupt for offering an item to other people, called mainly from [/mob/living/carbon/proc/give], in case you want to run your own offer behavior instead. + * + * * Return TRUE if you want to interrupt the offer. + * + * * Arguments: + * * offerer - the person offering the item + */ +/obj/item/proc/on_offered(mob/living/carbon/offerer) + if(SEND_SIGNAL(src, COMSIG_ITEM_OFFERING, offerer) & COMPONENT_OFFER_INTERRUPT) + return TRUE + +/** + * * An interrupt for someone trying to accept an offered item, called mainly from [/mob/living/carbon/proc/take], in case you want to run your own take behavior instead. + * + * * Return TRUE if you want to interrupt the taking. + * + * * Arguments: + * * offerer - the person offering the item + * * taker - the person trying to accept the offer + */ +/obj/item/proc/on_offer_taken(mob/living/carbon/offerer, mob/living/carbon/taker) + if(SEND_SIGNAL(src, COMSIG_ITEM_OFFER_TAKEN, offerer, taker) & COMPONENT_OFFER_INTERRUPT) + return TRUE + +/** + * Updates all action buttons associated with this item + * + * Arguments: + * * status_only - Update only current availability status of the buttons to show if they are ready or not to use + * * force - Force buttons update even if the given button icon state has not changed + */ +/obj/item/proc/update_action_buttons(status_only = FALSE, force = FALSE) + for(var/datum/action/current_action as anything in actions) + current_action.UpdateButtonIcon(status_only, force) + +/// Special stuff you want to do when an outfit equips this item. +/obj/item/proc/on_outfit_equip(mob/living/carbon/human/outfit_wearer, visuals_only, item_slot) + return diff --git a/code/game/objects/items/AI_modules.dm b/code/game/objects/items/AI_modules.dm index 59dd420d23..306b711994 100644 --- a/code/game/objects/items/AI_modules.dm +++ b/code/game/objects/items/AI_modules.dm @@ -406,7 +406,7 @@ AI MODULES /obj/item/aiModule/core/full/custom name = "Default Core AI Module" -/obj/item/aiModule/core/full/custom/Initialize() +/obj/item/aiModule/core/full/custom/Initialize(mapload) . = ..() for(var/line in world.file2list("[global.config.directory]/silicon_laws.txt")) if(!line) diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 07ffe8896e..8896170bd3 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -24,7 +24,7 @@ RLD w_class = WEIGHT_CLASS_NORMAL custom_materials = list(/datum/material/iron=100000) req_access_txt = "11" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF var/datum/effect_system/spark_spread/spark_system var/matter = 0 @@ -39,7 +39,7 @@ RLD var/custom_range = 7 var/upgrade = FALSE -/obj/item/construction/Initialize() +/obj/item/construction/Initialize(mapload) . = ..() spark_system = new /datum/effect_system/spark_spread spark_system.set_up(5, 0, src) @@ -464,7 +464,7 @@ RLD return TRUE qdel(rcd_effect) -/obj/item/construction/rcd/Initialize() +/obj/item/construction/rcd/Initialize(mapload) . = ..() GLOB.rcd_list += src @@ -561,7 +561,7 @@ RLD cut_overlays() //To prevent infinite stacking of overlays add_overlay("[icon_state]_charge[ratio]") -/obj/item/construction/rcd/Initialize() +/obj/item/construction/rcd/Initialize(mapload) . = ..() update_icon() @@ -699,7 +699,7 @@ RLD var/color_choice = null -/obj/item/construction/rld/Initialize() +/obj/item/construction/rld/Initialize(mapload) . = ..() update_icon() diff --git a/code/game/objects/items/RCL.dm b/code/game/objects/items/RCL.dm index 019231b8b4..fa73650142 100644 --- a/code/game/objects/items/RCL.dm +++ b/code/game/objects/items/RCL.dm @@ -23,7 +23,7 @@ var/datum/radial_menu/persistent/wiring_gui_menu var/mob/listeningTo -/obj/item/rcl/Initialize() +/obj/item/rcl/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield) RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield) @@ -314,7 +314,7 @@ else //open the menu showWiringGui(user) -/obj/item/rcl/pre_loaded/Initialize() //Comes preloaded with cable, for testing stuff +/obj/item/rcl/pre_loaded/Initialize(mapload) //Comes preloaded with cable, for testing stuff loaded = new() loaded.max_amount = max_amount loaded.amount = max_amount diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm index 635ea97902..6f263b7163 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -206,7 +206,7 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list( throw_range = 5 w_class = WEIGHT_CLASS_NORMAL custom_materials = list(/datum/material/iron=75000, /datum/material/glass=37500) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF var/datum/effect_system/spark_spread/spark_system var/effectcooldown @@ -532,7 +532,7 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list( category = PLUMBING_CATEGORY locked = TRUE -/obj/item/pipe_dispenser/plumbing/Initialize() +/obj/item/pipe_dispenser/plumbing/Initialize(mapload) . = ..() spark_system = new spark_system.set_up(5, 0, src) diff --git a/code/game/objects/items/RSF.dm b/code/game/objects/items/RSF.dm index da5ab1a5a5..4e9470141c 100644 --- a/code/game/objects/items/RSF.dm +++ b/code/game/objects/items/RSF.dm @@ -14,7 +14,7 @@ RSF density = FALSE anchored = FALSE item_flags = NOBLUDGEON - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) var/matter = 0 var/mode = 1 w_class = WEIGHT_CLASS_NORMAL diff --git a/code/game/objects/items/airlock_painter.dm b/code/game/objects/items/airlock_painter.dm index 8edd1c2a76..b239033dca 100644 --- a/code/game/objects/items/airlock_painter.dm +++ b/code/game/objects/items/airlock_painter.dm @@ -1,10 +1,11 @@ /obj/item/airlock_painter name = "airlock painter" desc = "An advanced autopainter preprogrammed with several paintjobs for airlocks. Use it on an airlock during or after construction to change the paintjob." +// desc_controls = "Alt-Click to remove the ink cartridge." icon = 'icons/obj/objects.dmi' - icon_state = "paint sprayer" - item_state = "paint sprayer" - + icon_state = "paint_sprayer" + item_state = "paint_sprayer" // inhand_icon_state = "paint_sprayer" + // worn_icon_state = "painter" w_class = WEIGHT_CLASS_SMALL custom_materials = list(/datum/material/iron=50, /datum/material/glass=50) @@ -14,40 +15,66 @@ slot_flags = ITEM_SLOT_BELT usesound = 'sound/effects/spray2.ogg' + /// The ink cartridge to pull charges from. var/obj/item/toner/ink = null + /// The type path to instantiate for the ink cartridge the device initially comes with, eg. /obj/item/toner + var/initial_ink_type = /obj/item/toner + /// Associate list of all paint jobs the airlock painter can apply. The key is the name of the airlock the user will see. The value is the type path of the airlock + var/list/available_paint_jobs = list( + "Public" = /obj/machinery/door/airlock/public, + "Engineering" = /obj/machinery/door/airlock/engineering, + "Atmospherics" = /obj/machinery/door/airlock/atmos, + "Security" = /obj/machinery/door/airlock/security, + "Command" = /obj/machinery/door/airlock/command, + "Medical" = /obj/machinery/door/airlock/medical, + "Virology" = /obj/machinery/door/airlock/virology, + "Research" = /obj/machinery/door/airlock/research, +// "Hydroponics" = /obj/machinery/door/airlock/hydroponics, + "Freezer" = /obj/machinery/door/airlock/freezer, + "Science" = /obj/machinery/door/airlock/science, + "Mining" = /obj/machinery/door/airlock/mining, + "Maintenance" = /obj/machinery/door/airlock/maintenance, + "External" = /obj/machinery/door/airlock/external, + "External Maintenance"= /obj/machinery/door/airlock/maintenance/external, + "Standard" = /obj/machinery/door/airlock + ) -/obj/item/airlock_painter/Initialize() +/obj/item/airlock_painter/Initialize(mapload) . = ..() - ink = new /obj/item/toner(src) + ink = new initial_ink_type(src) + +/obj/item/airlock_painter/examine(mob/user) + . = ..() + . += span_notice("Alt-Click to remove the ink cartridge.") //This proc doesn't just check if the painter can be used, but also uses it. //Only call this if you are certain that the painter will be used right after this check! /obj/item/airlock_painter/proc/use_paint(mob/user) if(can_use(user)) ink.charges-- - playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1) - return 1 + playsound(src.loc, 'sound/effects/spray2.ogg', 50, TRUE) + return TRUE else - return 0 + return FALSE //This proc only checks if the painter can be used. //Call this if you don't want the painter to be used right after this check, for example //because you're expecting user input. /obj/item/airlock_painter/proc/can_use(mob/user) if(!ink) - to_chat(user, "There is no toner cartridge installed in [src]!") - return 0 + balloon_alert(user, "no cartridge!") + return FALSE else if(ink.charges < 1) - to_chat(user, "[src] is out of ink!") - return 0 + balloon_alert(user, "out of ink!") + return FALSE else - return 1 + return TRUE -/obj/item/airlock_painter/suicide_act(mob/user) +/obj/item/airlock_painter/suicide_act(mob/living/user) var/obj/item/organ/lungs/L = user.getorganslot(ORGAN_SLOT_LUNGS) if(can_use(user) && L) - user.visible_message("[user] is inhaling toner from [src]! It looks like [user.p_theyre()] trying to commit suicide!") + user.visible_message(span_suicide("[user] is inhaling toner from [src]! It looks like [user.p_theyre()] trying to commit suicide!")) use(user) // Once you've inhaled the toner, you throw up your lungs @@ -64,7 +91,7 @@ if(!L) return OXYLOSS - L.Remove() + L.Remove(user) // make some colorful reagent, and apply it to the lungs L.create_reagents(10, NONE, NO_REAGENTS_VALUE) @@ -73,27 +100,27 @@ // TODO maybe add some colorful vomit? - user.visible_message("[user] vomits out [user.p_their()] [L]!") - playsound(user.loc, 'sound/effects/splat.ogg', 50, 1) + user.visible_message(span_suicide("[user] vomits out [user.p_their()] [L]!")) + playsound(user.loc, 'sound/effects/splat.ogg', 50, TRUE) L.forceMove(T) return (TOXLOSS|OXYLOSS) else if(can_use(user) && !L) - user.visible_message("[user] is spraying toner on [user.p_them()]self from [src]! It looks like [user.p_theyre()] trying to commit suicide.") + user.visible_message(span_suicide("[user] is spraying toner on [user.p_them()]self from [src]! It looks like [user.p_theyre()] trying to commit suicide.")) user.reagents.add_reagent(/datum/reagent/colorful_reagent, 1) user.reagents.reaction(user, TOUCH, 1) return TOXLOSS else - user.visible_message("[user] is trying to inhale toner from [src]! It might be a suicide attempt if [src] had any toner.") + user.visible_message(span_suicide("[user] is trying to inhale toner from [src]! It might be a suicide attempt if [src] had any toner.")) return SHAME /obj/item/airlock_painter/examine(mob/user) . = ..() if(!ink) - . += "It doesn't have a toner cartridge installed." + . += span_notice("It doesn't have a toner cartridge installed.") return var/ink_level = "high" if(ink.charges < 1) @@ -102,88 +129,129 @@ ink_level = "low" else if((ink.charges/ink.max_charges) > 1) //Over 100% (admin var edit) ink_level = "dangerously high" - . += "Its ink levels look [ink_level]." + . += span_notice("Its ink levels look [ink_level].") /obj/item/airlock_painter/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/toner)) if(ink) - to_chat(user, "[src] already contains \a [ink].") + to_chat(user, span_warning("[src] already contains \a [ink]!")) return if(!user.transferItemToLoc(W, src)) return - to_chat(user, "You install [W] into [src].") + to_chat(user, span_notice("You install [W] into [src].")) ink = W - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) + playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE) else return ..() -/obj/item/airlock_painter/attack_self(mob/user) +/obj/item/airlock_painter/AltClick(mob/user) + . = ..() if(ink) - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) + playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE) ink.forceMove(user.drop_location()) user.put_in_hands(ink) - to_chat(user, "You remove [ink] from [src].") + to_chat(user, span_notice("You remove [ink] from [src].")) ink = null - /obj/item/airlock_painter/decal name = "decal painter" - desc = "An airlock painter, reprogramed to use a different style of paint in order to apply decals for floor tiles as well, in addition to repainting doors. Decals break when the floor tiles are removed. Alt-Click to change design." + desc = "An airlock painter, reprogramed to use a different style of paint in order to apply decals for floor tiles as well, in addition to repainting doors. Decals break when the floor tiles are removed." +// desc_controls = "Alt-Click to remove the ink cartridge." icon = 'icons/obj/objects.dmi' icon_state = "decal_sprayer" - item_state = "decalsprayer" - custom_materials = list(/datum/material/iron=2000, /datum/material/glass=500) + item_state = "decal_sprayer" // inhand_icon_state = "decal_sprayer" + custom_materials = list(/datum/material/iron=50, /datum/material/glass=50) + initial_ink_type = /obj/item/toner/large + /// The current direction of the decal being printed var/stored_dir = 2 - var/stored_color = "" + /// The current color of the decal being printed. + var/stored_color = "yellow" + /// The current base icon state of the decal being printed. var/stored_decal = "warningline" + /// The full icon state of the decal being printed. var/stored_decal_total = "warningline" - var/color_list = list("","red","white") - var/dir_list = list(1,2,4,8) - var/decal_list = list(list("Warning Line","warningline"), - list("Warning Line Corner","warninglinecorner"), - list("Caution Label","caution"), - list("Directional Arrows","arrows"), - list("Stand Clear Label","stand_clear"), - list("Box","box"), - list("Box Corner","box_corners"), - list("Delivery Marker","delivery"), - list("Warning Box","warn_full")) + /// The type path of the spritesheet being used for the frontend. + var/spritesheet_type = /datum/asset/spritesheet/decals // spritesheet containing previews + /// Does this printer implementation support custom colors? + var/supports_custom_color = FALSE + /// Current custom color + var/stored_custom_color + /// List of color options as list(user-friendly label, color value to return) + var/color_list = list( + list("Yellow", "yellow"), + list("Red", "red"), + list("White", "white"), + ) + /// List of direction options as list(user-friendly label, dir value to return) + var/dir_list = list( + list("North", NORTH), + list("South", SOUTH), + list("East", EAST), + list("West", WEST), + ) + /// List of decal options as list(user-friendly label, icon state base value to return) + var/decal_list = list( + list("Warning Line", "warningline"), + list("Warning Line Corner", "warninglinecorner"), + list("Caution Label", "caution"), + list("Directional Arrows", "arrows"), + list("Stand Clear Label", "stand_clear"), + list("Bot", "bot"), + list("Box", "box"), + list("Box Corner", "box_corners"), + list("Delivery Marker", "delivery"), + list("Warning Box", "warn_full"), + ) + // These decals only have a south sprite. + var/nondirectional_decals = list( + "bot", + "box", + "delivery", + "warn_full", + ) + +/obj/item/airlock_painter/decal/Initialize(mapload) + . = ..() + stored_custom_color = stored_color /obj/item/airlock_painter/decal/afterattack(atom/target, mob/user, proximity) . = ..() - var/turf/open/floor/F = target if(!proximity) - to_chat(user, "You need to get closer!") + balloon_alert(user, "get closer!") return - if(use_paint(user) && isturf(F)) - F.AddElement(/datum/element/decal, 'icons/turf/decals.dmi', stored_decal_total, stored_dir, CLEAN_STRONG, color, null, null, alpha) -/obj/item/airlock_painter/decal/attack_self(mob/user) - if((ink) && (ink.charges >= 1)) - to_chat(user, "[src] beeps to prevent you from removing the toner until out of charges.") - return - . = ..() + if(isfloorturf(target) && use_paint(user)) + paint_floor(target) -/obj/item/airlock_painter/decal/AltClick(mob/user) - . = ..() - ui_interact(user) +/** + * Actually add current decal to the floor. + * + * Responsible for actually adding the element to the turf for maximum flexibility.area + * Can be overriden for different decal behaviors. + * Arguments: + * * target - The turf being painted to +*/ +/obj/item/airlock_painter/decal/proc/paint_floor(turf/open/floor/target) + target.AddElement(/datum/element/decal, 'icons/turf/decals.dmi', stored_decal_total, stored_dir, CLEAN_STRONG, color, null, null, alpha) -/obj/item/airlock_painter/decal/Initialize() - . = ..() - ink = new /obj/item/toner/large(src) +/** + * Return the final icon_state for the given decal options + * + * Arguments: + * * decal - the selected decal base icon state + * * color - the selected color + * * dir - the selected dir + */ +/obj/item/airlock_painter/decal/proc/get_decal_path(decal, color, dir) + // Special case due to icon_state names + if(color == "yellow") + color = "" + + return "[decal][color ? "_" : ""][color]" /obj/item/airlock_painter/decal/proc/update_decal_path() - var/yellow_fix = "" //This will have to do until someone refactor's markings.dm - if (stored_color) - yellow_fix = "_" - stored_decal_total = "[stored_decal][yellow_fix][stored_color]" - return - -/obj/item/airlock_painter/decal/ui_assets(mob/user) - return list( - get_asset_datum(/datum/asset/spritesheet/decals) - ) + stored_decal_total = get_decal_path(stored_decal, stored_color, stored_dir) /obj/item/airlock_painter/decal/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) @@ -191,52 +259,215 @@ ui = new(user, src, "DecalPainter", name) ui.open() +/obj/item/airlock_painter/decal/ui_assets(mob/user) + . = ..() + . += get_asset_datum(spritesheet_type) + +/obj/item/airlock_painter/decal/ui_static_data(mob/user) + . = ..() + var/datum/asset/spritesheet/icon_assets = get_asset_datum(spritesheet_type) + + .["icon_prefix"] = "[icon_assets.name]32x32" + .["supports_custom_color"] = supports_custom_color + .["decal_list"] = list() + .["color_list"] = list() + .["dir_list"] = list() + .["nondirectional_decals"] = nondirectional_decals + + for(var/decal in decal_list) + .["decal_list"] += list(list( + "name" = decal[1], + "decal" = decal[2], + )) + for(var/color in color_list) + .["color_list"] += list(list( + "name" = color[1], + "color" = color[2], + )) + for(var/dir in dir_list) + .["dir_list"] += list(list( + "name" = dir[1], + "dir" = dir[2], + )) + /obj/item/airlock_painter/decal/ui_data(mob/user) - var/list/data = list() - data["decal_direction"] = stored_dir - data["decal_dir_text"] = dir2text(stored_dir) - data["decal_color"] = stored_color - data["decal_style"] = stored_decal - data["decal_list"] = list() - data["color_list"] = list() - data["dir_list"] = list() + . = ..() + .["current_decal"] = stored_decal + .["current_color"] = stored_color + .["current_dir"] = stored_dir + .["current_custom_color"] = stored_custom_color - for(var/i in decal_list) - data["decal_list"] += list(list( - "name" = i[1], - "decal" = i[2] - )) - for(var/j in color_list) - data["color_list"] += list(list( - "colors" = j - )) - for(var/k in dir_list) - data["dir_list"] += list(list( - "dirs" = k - )) - return data - -/obj/item/airlock_painter/decal/ui_act(action,list/params) - if(..()) +/obj/item/airlock_painter/decal/ui_act(action, list/params) + . = ..() + if(.) return + switch(action) //Lists of decals and designs if("select decal") - var/selected_decal = params["decals"] + var/selected_decal = params["decal"] + var/selected_dir = text2num(params["dir"]) stored_decal = selected_decal + stored_dir = selected_dir if("select color") - var/selected_color = params["colors"] + var/selected_color = params["color"] stored_color = selected_color - if("selected direction") - var/selected_direction = text2num(params["dirs"]) - stored_dir = selected_direction + if("pick custom color") + if(supports_custom_color) + pick_painting_tool_color(usr, stored_custom_color) update_decal_path() . = TRUE +/obj/item/airlock_painter/decal/set_painting_tool_color(chosen_color) + . = ..() + stored_custom_color = chosen_color + stored_color = chosen_color + +/datum/asset/spritesheet/decals + name = "floor_decals" +// cross_round_cachable = TRUE + + /// The floor icon used for blend_preview_floor() + var/preview_floor_icon = 'icons/turf/floors.dmi' + /// The floor icon state used for blend_preview_floor() + var/preview_floor_state = "floor" + /// The associated decal painter type to grab decals, colors, etc from. + var/obj/item/airlock_painter/decal/painter_type = /obj/item/airlock_painter/decal + +/** + * Underlay an example floor for preview purposes, and return the new icon. + * + * Arguments: + * * decal - the decal to place over the example floor tile + */ +/datum/asset/spritesheet/decals/proc/blend_preview_floor(icon/decal) + var/icon/final = icon(preview_floor_icon, preview_floor_state) + final.Blend(decal, ICON_OVERLAY) + return final + +/** + * Insert a specific state into the spritesheet. + * + * Arguments: + * * decal - the given decal base state. + * * dir - the given direction. + * * color - the given color. + */ +/datum/asset/spritesheet/decals/proc/insert_state(decal, dir, color) + // Special case due to icon_state names + var/icon_state_color = color == "yellow" ? "" : color + + var/icon/final = blend_preview_floor(icon('icons/turf/decals.dmi', "[decal][icon_state_color ? "_" : ""][icon_state_color]", dir)) + Insert("[decal]_[dir]_[color]", final) + +/datum/asset/spritesheet/decals/register() + // Must actually create because initial(type) doesn't work for /lists for some reason. + var/obj/item/airlock_painter/decal/painter = new painter_type() + + for(var/list/decal in painter.decal_list) + for(var/list/dir in painter.dir_list) + for(var/list/color in painter.color_list) + insert_state(decal[2], dir[2], color[2]) + if(painter.supports_custom_color) + insert_state(decal[2], dir[2], "custom") + + qdel(painter) + . = ..() + /obj/item/airlock_painter/decal/debug name = "extreme decal painter" icon_state = "decal_sprayer_ex" + initial_ink_type = /obj/item/toner/extreme -/obj/item/airlock_painter/decal/debug/Initialize() - . = ..() - ink = new /obj/item/toner/extreme(src) +/obj/item/airlock_painter/decal/tile + name = "tile sprayer" + desc = "An airlock painter, reprogramed to use a different style of paint in order to spray colors on floor tiles as well, in addition to repainting doors. Decals break when the floor tiles are removed." +// desc_controls = "Alt-Click to remove the ink cartridge." + icon_state = "tile_sprayer" + stored_dir = 2 + stored_color = "#D4D4D432" + stored_decal = "tile_corner" + spritesheet_type = /datum/asset/spritesheet/decals/tiles + supports_custom_color = TRUE + // Colors can have a an alpha component as RGBA, or just be RGB and use default alpha + color_list = list( + list("Neutral", "#D4D4D432"), + list("Dark", "#0e0f0f"), + list("Bar Burgundy", "#79150082"), + list("Sec Red", "#DE3A3A"), + list("Cargo Brown", "#A46106"), + list("Engi Yellow", "#EFB341"), + list("Service Green", "#9FED58"), + list("Med Blue", "#52B4E9"), + list("R&D Purple", "#D381C9"), + ) + decal_list = list( + list("Corner", "tile_corner"), + list("Half", "tile_half_contrasted"), + list("Opposing Corners", "tile_opposing_corners"), + list("3 Corners", "tile_anticorner_contrasted"), + list("4 Corners", "tile_fourcorners"), + list("Trimline Corner", "trimline_corner_fill"), + list("Trimline Fill", "trimline_fill"), + list("Trimline Fill L", "trimline_fill__8"), // This is a hack that lives in the spritesheet builder and paint_floor + list("Trimline End", "trimline_end_fill"), + list("Trimline Box", "trimline_box_fill"), + ) + nondirectional_decals = list( + "tile_fourcorners", + "trimline_box_fill", + ) + + /// Regex to split alpha out. + var/static/regex/rgba_regex = new(@"(#[0-9a-fA-F]{6})([0-9a-fA-F]{2})") + + /// Default alpha for /obj/effect/turf_decal/tile + var/default_alpha = 110 + +/obj/item/airlock_painter/decal/tile/paint_floor(turf/open/floor/target) + // Account for 8-sided decals. + var/source_decal = stored_decal + var/source_dir = stored_dir + if(copytext(stored_decal, -3) == "__8") + source_decal = splicetext(stored_decal, -3, 0, "") + source_dir = turn(stored_dir, 45) + + var/decal_color = stored_color + var/decal_alpha = default_alpha + // Handle the RGBA case. + if(rgba_regex.Find(decal_color)) + decal_color = rgba_regex.group[1] + decal_alpha = text2num(rgba_regex.group[2], 16) + + target.AddElement(/datum/element/decal, 'icons/turf/decals.dmi', source_decal, source_dir, CLEAN_STRONG, decal_color, null, null, decal_alpha) + +/datum/asset/spritesheet/decals/tiles + name = "floor_tile_decals" + painter_type = /obj/item/airlock_painter/decal/tile + +/datum/asset/spritesheet/decals/tiles/insert_state(decal, dir, color) + // Account for 8-sided decals. + var/source_decal = decal + var/source_dir = dir + if(copytext(decal, -3) == "__8") + source_decal = splicetext(decal, -3, 0, "") + source_dir = turn(dir, 45) + + // Handle the RGBA case. + var/obj/item/airlock_painter/decal/tile/tile_type = painter_type + var/render_color = color + var/render_alpha = initial(tile_type.default_alpha) + if(tile_type.rgba_regex.Find(color)) + render_color = tile_type.rgba_regex.group[1] + render_alpha = text2num(tile_type.rgba_regex.group[2], 16) + + var/icon/colored_icon = icon('icons/turf/decals.dmi', source_decal, dir=source_dir) + colored_icon.ChangeOpacity(render_alpha * 0.008) + if(color == "custom") + // Do a fun rainbow pattern to stand out while still being static. + colored_icon.Blend(icon('icons/effects/random_spawners.dmi', "rainbow"), ICON_MULTIPLY) + else + colored_icon.Blend(render_color, ICON_MULTIPLY) + + colored_icon = blend_preview_floor(colored_icon) + Insert("[decal]_[dir]_[replacetext(color, "#", "")]", colored_icon) diff --git a/code/game/objects/items/apc_frame.dm b/code/game/objects/items/apc_frame.dm index 3640db2d8a..7e9bea2c5d 100644 --- a/code/game/objects/items/apc_frame.dm +++ b/code/game/objects/items/apc_frame.dm @@ -95,7 +95,7 @@ /obj/item/wallframe/apc/try_build(turf/on_wall, user) if(!..()) return - var/turf/T = get_turf(on_wall) //the user is not where it needs to be. + var/turf/T = get_turf(user) var/area/A = get_area(T) if(A.get_apc()) to_chat(user, "This area already has an APC!") diff --git a/code/game/objects/items/armor_kits.dm b/code/game/objects/items/armor_kits.dm index 906d7c5f81..5bed4f01a4 100644 --- a/code/game/objects/items/armor_kits.dm +++ b/code/game/objects/items/armor_kits.dm @@ -20,20 +20,20 @@ if(C.attached_accessory) to_chat(user,"Kind of hard to sew around [C.attached_accessory].") return - if(C.armor.getRating("melee") < 10) - C.armor = C.armor.setRating("melee" = 10) + if(C.armor.getRating(MELEE) < 10) + C.armor = C.armor.setRating(MELEE = 10) used = TRUE - if(C.armor.getRating("laser") < 10) - C.armor = C.armor.setRating("laser" = 10) + if(C.armor.getRating(LASER) < 10) + C.armor = C.armor.setRating(LASER = 10) used = TRUE - if(C.armor.getRating("fire") < 40) - C.armor = C.armor.setRating("fire" = 40) + if(C.armor.getRating(FIRE) < 40) + C.armor = C.armor.setRating(FIRE = 40) used = TRUE - if(C.armor.getRating("acid") < 10) - C.armor = C.armor.setRating("acid" = 10) + if(C.armor.getRating(ACID) < 10) + C.armor = C.armor.setRating(ACID = 10) used = TRUE - if(C.armor.getRating("bomb") < 5) - C.armor = C.armor.setRating("bomb" = 5) + if(C.armor.getRating(BOMB) < 5) + C.armor = C.armor.setRating(BOMB = 5) used = TRUE if(used) diff --git a/code/game/objects/items/binoculars.dm b/code/game/objects/items/binoculars.dm index 01295204a8..0897dc1dca 100644 --- a/code/game/objects/items/binoculars.dm +++ b/code/game/objects/items/binoculars.dm @@ -11,7 +11,7 @@ var/zoom_out_amt = 6 var/zoom_amt = 10 -/obj/item/binoculars/Initialize() +/obj/item/binoculars/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield) RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield) diff --git a/code/game/objects/items/boombox.dm b/code/game/objects/items/boombox.dm index 49e2375c1a..7ac2c67f5a 100644 --- a/code/game/objects/items/boombox.dm +++ b/code/game/objects/items/boombox.dm @@ -48,7 +48,7 @@ baseiconstate = "raiqbawks" availabletrackids = list("hotline.ogg","chiptune.ogg","genesis.ogg") -/obj/item/boombox/raiq/Initialize() +/obj/item/boombox/raiq/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_ATOM_UPDATED_ICON, .proc/start_party) diff --git a/code/game/objects/items/broom.dm b/code/game/objects/items/broom.dm index 4cbd75ed94..91b37a4c5d 100644 --- a/code/game/objects/items/broom.dm +++ b/code/game/objects/items/broom.dm @@ -13,7 +13,7 @@ attack_verb = list("swept", "brushed off", "bludgeoned", "whacked") resistance_flags = FLAMMABLE -/obj/item/broom/Initialize() +/obj/item/broom/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield) RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield) diff --git a/code/game/objects/items/candle.dm b/code/game/objects/items/candle.dm index 960e3ce499..355405b626 100644 --- a/code/game/objects/items/candle.dm +++ b/code/game/objects/items/candle.dm @@ -15,7 +15,7 @@ var/start_lit = FALSE var/heats_space = TRUE -/obj/item/candle/Initialize() +/obj/item/candle/Initialize(mapload) . = ..() if(start_lit) light() diff --git a/code/game/objects/items/cardboard_cutouts.dm b/code/game/objects/items/cardboard_cutouts.dm index a8ff7b9004..00fde9f9f5 100644 --- a/code/game/objects/items/cardboard_cutouts.dm +++ b/code/game/objects/items/cardboard_cutouts.dm @@ -15,7 +15,7 @@ /// If the cutout actually appears as what it portray and not a discolored version var/deceptive = FALSE -/obj/item/cardboard_cutout/Initialize() +/obj/item/cardboard_cutout/Initialize(mapload) . = ..() if(possible_appearances) return @@ -92,9 +92,9 @@ if(prob(I.force)) push_over() -/obj/item/cardboard_cutout/bullet_act(obj/item/projectile/P) +/obj/item/cardboard_cutout/bullet_act(obj/item/projectile/P, def_zone, piercing_hit = FALSE) if(istype(P, /obj/item/projectile/bullet/reusable)) - P.on_hit(src, 0) + P.on_hit(src, 0, piercing_hit) visible_message("[src] has been hit by [P]!") playsound(src, 'sound/weapons/slice.ogg', 50, 1) if(prob(P.damage)) @@ -112,7 +112,7 @@ var/new_appearance = show_radial_menu(user, src, possible_appearances, custom_check = CALLBACK(src, .proc/check_menu, user, crayon), radius = 36, require_near = TRUE) if(!new_appearance) return - if(!do_after(user, 10, FALSE, src, TRUE)) + if(!do_after(user, 1 SECONDS, src, timed_action_flags = IGNORE_HELD_ITEM)) return FALSE if(!check_menu(user, crayon)) return FALSE diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index df7d6467f0..fac44ddf54 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -34,7 +34,7 @@ righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi' var/detail_color = COLOR_ASSEMBLY_ORANGE -/obj/item/card/data/Initialize() +/obj/item/card/data/Initialize(mapload) .=..() update_icon() @@ -184,7 +184,7 @@ lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi' slot_flags = ITEM_SLOT_ID - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) resistance_flags = FIRE_PROOF | ACID_PROOF var/id_type_name = "identification card" var/mining_points = 0 //For redeeming at mining equipment vendors @@ -372,6 +372,11 @@ . += "The [D.account_holder] reports a balance of [D.account_balance] cr." . += "Alt-Click the ID to pull money from the linked account in the form of holochips." . += "You can insert credits into the linked account by pressing holochips, cash, or coins against the ID." + if(registered_account.civilian_bounty) + . += "There is an active civilian bounty." + . += "[registered_account.bounty_text()]" + . += "Quantity: [registered_account.bounty_num()]" + . += "Reward: [registered_account.bounty_value()]" if(registered_account.account_holder == user.real_name) . += "If you lose this ID card, you can reclaim your account by Alt-Clicking a blank ID card while holding it and entering your account ID number." else @@ -448,7 +453,7 @@ var/anyone = FALSE //Can anyone forge the ID or just syndicate? var/forged = FALSE //have we set a custom name and job assignment, or will we use what we're given when we chameleon change? -/obj/item/card/id/syndicate/Initialize() +/obj/item/card/id/syndicate/Initialize(mapload) . = ..() var/datum/action/item_action/chameleon/change/chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/card/id @@ -566,7 +571,7 @@ registered_name = "Captain" assignment = "Captain" -/obj/item/card/id/captains_spare/Initialize() +/obj/item/card/id/captains_spare/Initialize(mapload) var/datum/job/captain/J = new/datum/job/captain access = J.get_access() . = ..() @@ -578,7 +583,7 @@ registered_name = "Central Command" assignment = "General" -/obj/item/card/id/centcom/Initialize() +/obj/item/card/id/centcom/Initialize(mapload) access = get_all_centcom_access() . = ..() @@ -589,7 +594,7 @@ registered_name = "Emergency Response Team Commander" assignment = "Emergency Response Team Commander" -/obj/item/card/id/ert/Initialize() +/obj/item/card/id/ert/Initialize(mapload) access = get_all_accesses()+get_ert_access("commander")-ACCESS_CHANGE_IDS . = ..() @@ -598,7 +603,7 @@ registered_name = "Security Response Officer" assignment = "Security Response Officer" -/obj/item/card/id/ert/Security/Initialize() +/obj/item/card/id/ert/Security/Initialize(mapload) access = get_all_accesses()+get_ert_access("sec")-ACCESS_CHANGE_IDS . = ..() @@ -607,7 +612,7 @@ registered_name = "Engineer Response Officer" assignment = "Engineer Response Officer" -/obj/item/card/id/ert/Engineer/Initialize() +/obj/item/card/id/ert/Engineer/Initialize(mapload) access = get_all_accesses()+get_ert_access("eng")-ACCESS_CHANGE_IDS . = ..() @@ -616,7 +621,7 @@ registered_name = "Medical Response Officer" assignment = "Medical Response Officer" -/obj/item/card/id/ert/Medical/Initialize() +/obj/item/card/id/ert/Medical/Initialize(mapload) access = get_all_accesses()+get_ert_access("med")-ACCESS_CHANGE_IDS . = ..() @@ -625,7 +630,7 @@ registered_name = "Religious Response Officer" assignment = "Religious Response Officer" -/obj/item/card/id/ert/chaplain/Initialize() +/obj/item/card/id/ert/chaplain/Initialize(mapload) access = get_all_accesses()+get_ert_access("sec")-ACCESS_CHANGE_IDS . = ..() @@ -763,7 +768,7 @@ var/department_ID = ACCOUNT_CIV var/department_name = ACCOUNT_CIV_NAME -/obj/item/card/id/departmental_budget/Initialize() +/obj/item/card/id/departmental_budget/Initialize(mapload) . = ..() var/datum/bank_account/B = SSeconomy.get_dep_account(department_ID) if(B) @@ -819,7 +824,7 @@ var/id_color = "#00FF00" //defaults to green var/mutable_appearance/id_overlay -/obj/item/card/id/knight/Initialize() +/obj/item/card/id/knight/Initialize(mapload) . = ..() id_overlay = mutable_appearance(icon, "knight_overlay") update_icon() @@ -870,7 +875,7 @@ icon_state = "ert_janitor" assignment = "Jannie" -/obj/item/card/id/debug/Initialize() +/obj/item/card/id/debug/Initialize(mapload) access = get_all_accesses()+get_all_centcom_access()+get_all_syndicate_access() registered_account = SSeconomy.get_dep_account(ACCOUNT_CAR) . = ..() diff --git a/code/game/objects/items/chainsaw.dm b/code/game/objects/items/chainsaw.dm index ebb26fab93..58046a35d1 100644 --- a/code/game/objects/items/chainsaw.dm +++ b/code/game/objects/items/chainsaw.dm @@ -23,7 +23,7 @@ var/on = FALSE var/wielded = FALSE // track wielded status on item -/obj/item/chainsaw/Initialize() +/obj/item/chainsaw/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield) RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield) diff --git a/code/game/objects/items/charter.dm b/code/game/objects/items/charter.dm index 3f5296a1ef..8ece13681c 100644 --- a/code/game/objects/items/charter.dm +++ b/code/game/objects/items/charter.dm @@ -14,10 +14,11 @@ var/response_timer_id = null var/approval_time = 600 var/allow_unicode = FALSE + var/admin_approved = FALSE var/static/regex/standard_station_regex -/obj/item/station_charter/Initialize() +/obj/item/station_charter/Initialize(mapload) . = ..() if(!standard_station_regex) var/prefixes = jointext(GLOB.station_prefixes, "|") @@ -62,8 +63,32 @@ to_chat(user, "Your name has been sent to your employers for approval.") // Autoapproves after a certain time - response_timer_id = addtimer(CALLBACK(src, .proc/rename_station, new_name, user.name, user.real_name, key_name(user)), approval_time, TIMER_STOPPABLE) - to_chat(GLOB.admins, "CUSTOM STATION RENAME:[ADMIN_LOOKUPFLW(user)] proposes to rename the [name_type] to [html_encode(new_name)] (will autoapprove in [DisplayTimeText(approval_time)]). [ADMIN_SMITE(user)] (REJECT) [ADMIN_CENTCOM_REPLY(user)]") + var/requires_approval = CONFIG_GET(flag/station_name_needs_approval) + response_timer_id = addtimer(CALLBACK(src, .proc/check_state, new_name, user.name, user.real_name, key_name(user)), approval_time, TIMER_STOPPABLE) + to_chat(GLOB.admins, "CUSTOM STATION RENAME:[ADMIN_LOOKUPFLW(user)] proposes to rename the [name_type] to [html_encode(new_name)] ([requires_approval ? "REQUIRES ADMIN APPROVAL and will autodeny" : "will autoapprove"] in [DisplayTimeText(approval_time)]). [ADMIN_SMITE(user)] (REJECT)[requires_approval ? " (APPROVE)" : ""] [ADMIN_CENTCOM_REPLY(user)]") + +/obj/item/station_charter/proc/check_state(designation, uname, ureal_name, ukey) + var/requires_approval = CONFIG_GET(flag/station_name_needs_approval) + if(requires_approval && !admin_approved) + var/turf/T = get_turf(src) + T.visible_message("A note appears on [src], stating this sector requires central command approval for its station names, which was not performed in time for this request. Looks like the change has been auto-rejected.") + var/m = "Station rename has been autorejected due to config requiring admin approval." + message_admins(m) + log_admin(m) + else + rename_station(designation, uname, ureal_name, ukey) + response_timer_id = null + admin_approved = FALSE + +/obj/item/station_charter/proc/allow_pass(user) + if(!user) + return + if(!response_timer_id) + return + admin_approved = TRUE + var/m = "[key_name(user)] has approved the proposed station name. It can still be denied prior to the timer expiring." + message_admins(m) + log_admin(m) /obj/item/station_charter/proc/reject_proposed(user) if(!user) @@ -80,6 +105,7 @@ deltimer(response_timer_id) response_timer_id = null + admin_approved = FALSE /obj/item/station_charter/proc/rename_station(designation, uname, ureal_name, ukey) set_station_name(designation) diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm index c104d5c62a..8c510bb489 100644 --- a/code/game/objects/items/chrono_eraser.dm +++ b/code/game/objects/items/chrono_eraser.dm @@ -34,7 +34,7 @@ user.put_in_hands(PA) /obj/item/chrono_eraser/item_action_slot_check(slot, mob/user, datum/action/A) - if(slot == SLOT_BACK) + if(slot == ITEM_SLOT_BACK) return 1 /obj/item/gun/energy/chrono_gun @@ -52,7 +52,7 @@ var/obj/effect/chrono_field/field = null var/turf/startpos = null -/obj/item/gun/energy/chrono_gun/Initialize() +/obj/item/gun/energy/chrono_gun/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHRONO_GUN_TRAIT) if(istype(loc, /obj/item/chrono_eraser)) @@ -124,7 +124,7 @@ nodamage = 1 var/obj/item/gun/energy/chrono_gun/gun = null -/obj/item/projectile/energy/chrono_beam/Initialize() +/obj/item/projectile/energy/chrono_beam/Initialize(mapload) . = ..() var/obj/item/ammo_casing/energy/chrono_beam/C = loc if(istype(C)) @@ -143,7 +143,7 @@ e_cost = 0 var/obj/item/gun/energy/chrono_gun/gun -/obj/item/ammo_casing/energy/chrono_beam/Initialize() +/obj/item/ammo_casing/energy/chrono_beam/Initialize(mapload) if(istype(loc)) gun = loc . = ..() @@ -266,7 +266,7 @@ /obj/effect/chrono_field/singularity_pull() return -/obj/effect/chrono_field/ex_act() +/obj/effect/chrono_field/ex_act(severity, target, origin) return /obj/effect/chrono_field/blob_act(obj/structure/blob/B) diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 16ebe20e51..518772c771 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -89,7 +89,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM ..() /obj/item/proc/help_light_cig(mob/living/M) - var/mask_item = M.get_item_by_slot(SLOT_WEAR_MASK) + var/mask_item = M.get_item_by_slot(ITEM_SLOT_MASK) if(istype(mask_item, /obj/item/clothing/mask/cigarette)) return mask_item @@ -123,14 +123,14 @@ CIGARETTE PACKETS ARE IN FANCY.DM user.visible_message("[user] is huffing [src] as quickly as [user.p_they()] can! It looks like [user.p_theyre()] trying to give [user.p_them()]self cancer.") return (TOXLOSS|OXYLOSS) -/obj/item/clothing/mask/cigarette/Initialize() +/obj/item/clothing/mask/cigarette/Initialize(mapload) . = ..() create_reagents(chem_volume, INJECTABLE | NO_REACT, NO_REAGENTS_VALUE) // so it doesn't react until you light it if(list_reagents) reagents.add_reagent_list(list_reagents) if(starts_lit) light() - AddComponent(/datum/component/knockoff,90,list(BODY_ZONE_PRECISE_MOUTH),list(SLOT_WEAR_MASK))//90% to knock off when wearing a mask + AddComponent(/datum/component/knockoff,90,list(BODY_ZONE_PRECISE_MOUTH),list(ITEM_SLOT_MASK))//90% to knock off when wearing a mask /obj/item/clothing/mask/cigarette/Destroy() STOP_PROCESSING(SSobj, src) @@ -190,7 +190,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM qdel(src) return // allowing reagents to react after being lit - DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) + reagents.reagents_holder_flags &= ~(NO_REACT) reagents.handle_reactions() icon_state = icon_on item_state = icon_on @@ -300,6 +300,17 @@ CIGARETTE PACKETS ARE IN FANCY.DM desc = "A Xeno Filtered brand cigarette." list_reagents = list (/datum/reagent/drug/nicotine = 20, /datum/reagent/medicine/regen_jelly = 15, /datum/reagent/drug/krokodil = 4) +/obj/item/clothing/mask/cigarette/dart + name = "fat dart" + desc = "Chuff back this fat dart" + icon_state = "bigoff" + icon_on = "bigon" + icon_off = "bigoff" + w_class = WEIGHT_CLASS_BULKY + smoketime = 10000 + chem_volume = 50 + list_reagents = list(/datum/reagent/drug/nicotine = 15) + // Rollies. /obj/item/clothing/mask/cigarette/rollie @@ -387,7 +398,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM throwforce = 0 grind_results = list(/datum/reagent/carbon = 2) -/obj/item/cigbutt/Initialize() +/obj/item/cigbutt/Initialize(mapload) . = ..() AddElement(/datum/element/trash) @@ -411,7 +422,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM list_reagents = null var/packeditem = 0 -/obj/item/clothing/mask/cigarette/pipe/Initialize() +/obj/item/clothing/mask/cigarette/pipe/Initialize(mapload) . = ..() name = "empty [initial(name)]" @@ -521,7 +532,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM grind_results = list(/datum/reagent/iron = 1, /datum/reagent/fuel = 5, /datum/reagent/oil = 5) custom_price = PRICE_ALMOST_CHEAP -/obj/item/lighter/Initialize() +/obj/item/lighter/Initialize(mapload) . = ..() if(!overlay_state) overlay_state = pick(overlay_list) @@ -659,7 +670,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM COLOR_ASSEMBLY_PURPLE ) -/obj/item/lighter/greyscale/Initialize() +/obj/item/lighter/greyscale/Initialize(mapload) . = ..() if(!lighter_color) lighter_color = pick(color_list) @@ -751,7 +762,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM if(!screw) screw = TRUE to_chat(user, "You open the cap on [src].") - ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) + reagents.reagents_holder_flags |= OPENCONTAINER if(obj_flags & EMAGGED) add_overlay("vapeopen_high") else if(super) @@ -761,7 +772,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM else screw = FALSE to_chat(user, "You close the cap on [src].") - DISABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) + reagents.reagents_holder_flags &= ~(OPENCONTAINER) cut_overlays() if(O.tool_behaviour == TOOL_MULTITOOL) @@ -808,10 +819,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/vape/equipped(mob/user, slot) . = ..() - if(slot == SLOT_WEAR_MASK) + if(slot == ITEM_SLOT_MASK) if(!screw) to_chat(user, "You start puffing on the vape.") - DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) + reagents.reagents_holder_flags &= ~(NO_REACT) START_PROCESSING(SSobj, src) else //it will not start if the vape is opened. to_chat(user, "You need to close the cap first!") @@ -819,8 +830,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/vape/dropped(mob/user) . = ..() var/mob/living/carbon/C = user - if(C.get_item_by_slot(SLOT_WEAR_MASK) == src) - ENABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) + if(C.get_item_by_slot(ITEM_SLOT_MASK) == src) + reagents.reagents_holder_flags |= NO_REACT STOP_PROCESSING(SSobj, src) /obj/item/clothing/mask/vape/proc/hand_reagents()//had to rename to avoid duplicate error @@ -906,7 +917,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/list/list_reagents = list() //For the base reagents bongs could get -/obj/item/bong/Initialize() +/obj/item/bong/Initialize(mapload) . = ..() create_reagents(chem_volume, NO_REACT) // so it doesn't react until you light it reagents.add_reagent_list(list_reagents) diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm index afab49ac76..58d9627476 100644 --- a/code/game/objects/items/circuitboards/computer_circuitboards.dm +++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm @@ -259,11 +259,6 @@ build_path = /obj/machinery/computer/arcade/orion_trail -/obj/item/circuitboard/computer/arcade/minesweeper - name = "Minesweeper (Computer Board)" - icon_state = "generic" - build_path = /obj/machinery/computer/arcade/minesweeper - /obj/item/circuitboard/computer/holodeck// Not going to let people get this, but it's just here for future name = "Holodeck Control (Computer Board)" icon_state = "generic" @@ -318,7 +313,7 @@ var/challenge = FALSE var/moved = FALSE -/obj/item/circuitboard/computer/syndicate_shuttle/Initialize() +/obj/item/circuitboard/computer/syndicate_shuttle/Initialize(mapload) . = ..() GLOB.syndicate_shuttle_boards += src @@ -353,9 +348,9 @@ name = "Snow Taxi (Computer Board)" build_path = /obj/machinery/computer/shuttle/snow_taxi -// /obj/item/circuitboard/computer/bountypad -// name = "Bounty Pad (Computer Board)" -// build_path = /obj/machinery/computer/piratepad_control/civilian +/obj/item/circuitboard/computer/bountypad + name = "Bounty Pad (Computer Board)" + build_path = /obj/machinery/computer/piratepad_control/civilian /obj/item/circuitboard/computer/security/shuttle name = "Shuttlelinking Security Cameras (Computer Board)" diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index 6bf6e7d312..078839bcd1 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -77,7 +77,7 @@ #define PATH_POWERCOIL /obj/machinery/power/tesla_coil/power #define PATH_RPCOIL /obj/machinery/power/tesla_coil/research -/obj/item/circuitboard/machine/tesla_coil/Initialize() +/obj/item/circuitboard/machine/tesla_coil/Initialize(mapload) . = ..() if(build_path) build_path = PATH_POWERCOIL @@ -347,7 +347,7 @@ #define PATH_FREEZER /obj/machinery/atmospherics/components/unary/thermomachine/freezer #define PATH_HEATER /obj/machinery/atmospherics/components/unary/thermomachine/heater -/obj/item/circuitboard/machine/thermomachine/Initialize() +/obj/item/circuitboard/machine/thermomachine/Initialize(mapload) . = ..() if(!build_path) if(prob(50)) @@ -685,15 +685,15 @@ /obj/item/stack/sheet/glass = 1, /obj/item/vending_refill/donksoft = 1) -// /obj/item/circuitboard/machine/bountypad -// name = "Civilian Bounty Pad (Machine Board)" -// icon_state = "generic" -// build_path = /obj/machinery/piratepad/civilian -// req_components = list( -// /obj/item/stock_parts/card_reader = 1, -// /obj/item/stock_parts/scanning_module = 1, -// /obj/item/stock_parts/micro_laser = 1 -// ) + +/obj/item/circuitboard/machine/bountypad + name = "Civilian Bounty Pad (Machine Board)" + icon_state = "generic" + build_path = /obj/machinery/piratepad/civilian + req_components = list( + /obj/item/stock_parts/scanning_module = 1, + /obj/item/stock_parts/micro_laser = 1 + ) // /obj/item/circuitboard/machine/accounting // name = "Account Registration Device (Machine Board)" @@ -725,6 +725,26 @@ def_components = list(/obj/item/stock_parts/cell = /obj/item/stock_parts/cell/high) needs_anchored = FALSE +/obj/item/circuitboard/machine/chem_dispenser/fullupgrade + build_path = /obj/machinery/chem_dispenser/fullupgrade + req_components = list( + /obj/item/stock_parts/matter_bin/bluespace = 2, + /obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stock_parts/manipulator/femto = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell/bluespace = 1, + ) + +/obj/item/circuitboard/machine/chem_dispenser/mutagensaltpeter + build_path = /obj/machinery/chem_dispenser/mutagensaltpeter + req_components = list( + /obj/item/stock_parts/matter_bin/bluespace = 2, + /obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stock_parts/manipulator/femto = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell/bluespace = 1, + ) + /obj/item/circuitboard/machine/chem_dispenser/apothecary name = "Apotechary Chem Dispenser (Machine Board)" build_path = /obj/machinery/chem_dispenser/apothecary @@ -740,7 +760,13 @@ name = "Reagent Synthesizer (Abductor Machine Board)" icon_state = "abductor_mod" build_path = /obj/machinery/chem_dispenser/abductor - def_components = list(/obj/item/stock_parts/cell = /obj/item/stock_parts/cell/high) + req_components = list( + /obj/item/stock_parts/matter_bin/bluespace = 2, + /obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stock_parts/manipulator/femto = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell/bluespace = 1, + ) needs_anchored = FALSE /obj/item/circuitboard/machine/chem_heater @@ -920,14 +946,14 @@ /obj/item/stock_parts/cell = 1) needs_anchored = FALSE -// /obj/item/circuitboard/machine/stasis -// name = "\improper Lifeform Stasis Unit (Machine Board)" -// icon_state = "medical" -// build_path = /obj/machinery/stasis -// req_components = list( -// /obj/item/stack/cable_coil = 3, -// /obj/item/stock_parts/manipulator = 1, -// /obj/item/stock_parts/capacitor = 1) +/obj/item/circuitboard/machine/stasis + name = "\improper Lifeform Stasis Unit (Machine Board)" + icon_state = "medical" + build_path = /obj/machinery/stasis + req_components = list( + /obj/item/stack/cable_coil = 3, + /obj/item/stock_parts/manipulator = 1, + /obj/item/stock_parts/capacitor = 1) /obj/item/circuitboard/machine/medipen_refiller name = "Medipen Refiller (Machine Board)" @@ -1175,11 +1201,31 @@ icon_state = "service" build_path = /obj/machinery/chem_dispenser/drinks +/obj/item/circuitboard/machine/chem_dispenser/drinks/fullupgrade + build_path = /obj/machinery/chem_dispenser/drinks/fullupgrade + req_components = list( + /obj/item/stock_parts/matter_bin/bluespace = 2, + /obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stock_parts/manipulator/femto = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell/bluespace = 1, + ) + /obj/item/circuitboard/machine/chem_dispenser/drinks/beer name = "Booze Dispenser (Machine Board)" icon_state = "service" build_path = /obj/machinery/chem_dispenser/drinks/beer +/obj/item/circuitboard/machine/chem_dispenser/drinks/beer/fullupgrade + build_path = /obj/machinery/chem_dispenser/drinks/beer/fullupgrade + req_components = list( + /obj/item/stock_parts/matter_bin/bluespace = 2, + /obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stock_parts/manipulator/femto = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell/bluespace = 1, + ) + /obj/item/circuitboard/machine/chem_master/condi name = "CondiMaster 3000 (Machine Board)" icon_state = "service" @@ -1295,6 +1341,15 @@ /obj/item/stock_parts/manipulator = 1) needs_anchored = FALSE +/obj/item/circuitboard/machine/autoloom + name = "Autoloom (Machine Board)" + icon_state = "service" + build_path = /obj/machinery/autoloom + req_components = list( + /obj/item/stock_parts/matter_bin = 1, + /obj/item/stock_parts/manipulator = 1) + needs_anchored = FALSE + /obj/item/circuitboard/machine/seed_extractor name = "Seed Extractor (Machine Board)" icon_state = "service" diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm index f5477ae5f6..d8d471abaf 100644 --- a/code/game/objects/items/clown_items.dm +++ b/code/game/objects/items/clown_items.dm @@ -27,7 +27,7 @@ var/cleanspeed = 50 //slower than mop force_string = "robust... against germs" -/obj/item/soap/Initialize() +/obj/item/soap/Initialize(mapload) . = ..() AddComponent(/datum/component/slippery, 80) diff --git a/code/game/objects/items/control_wand.dm b/code/game/objects/items/control_wand.dm index be39bb6973..c87dad8f8c 100644 --- a/code/game/objects/items/control_wand.dm +++ b/code/game/objects/items/control_wand.dm @@ -15,7 +15,7 @@ var/region_access = 1 //See access.dm var/list/access_list -/obj/item/door_remote/Initialize() +/obj/item/door_remote/Initialize(mapload) . = ..() access_list = get_region_accesses(region_access) AddComponent(/datum/component/ntnet_interface) diff --git a/code/game/objects/items/crab17.dm b/code/game/objects/items/crab17.dm index 8d55d3d5a2..b71b520517 100644 --- a/code/game/objects/items/crab17.dm +++ b/code/game/objects/items/crab17.dm @@ -29,7 +29,7 @@ icon = 'icons/obj/money_machine.dmi' icon_state = "bogdanoff" layer = LARGE_MOB_LAYER - armor = list("melee" = 80, "bullet" = 30, "laser" = 30, "energy" = 60, "bomb" = 90, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 80) + armor = list(MELEE = 80, BULLET = 30, LASER = 30, ENERGY = 60, BOMB = 90, BIO = 0, RAD = 0, FIRE = 100, ACID = 80) density = TRUE pixel_z = -8 max_integrity = 5000 diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index aa48930d6c..0b733d6192 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -42,7 +42,7 @@ var/static/list/runes = list("rune1","rune2","rune3","rune4","rune5","rune6") var/static/list/randoms = list(RANDOM_ANY, RANDOM_RUNE, RANDOM_ORIENTED, RANDOM_NUMBER, RANDOM_GRAFFITI, RANDOM_LETTER, RANDOM_SYMBOL, RANDOM_PUNCTUATION, RANDOM_DRAWING) - var/static/list/graffiti_large_h = list("yiffhell", "secborg", "paint") + var/static/list/graffiti_large_h = list("yiffhell", "furrypride", "secborg", "paint") var/static/list/all_drawables = graffiti + symbols + drawings + oriented + runes + graffiti_large_h @@ -72,6 +72,10 @@ var/datum/team/gang/gang //For marking territory. var/gang_tag_delay = 30 //this is the delay for gang mode tag applications on anything that gang = true on. + var/precision_mode = FALSE + var/precision_x = 0 + var/precision_y = 0 + /obj/item/toy/crayon/proc/isValidSurface(surface) return istype(surface, /turf/open/floor) @@ -79,7 +83,7 @@ user.visible_message("[user] is jamming [src] up [user.p_their()] nose and into [user.p_their()] brain. It looks like [user.p_theyre()] trying to commit suicide!") return (BRUTELOSS|OXYLOSS) -/obj/item/toy/crayon/Initialize() +/obj/item/toy/crayon/Initialize(mapload) . = ..() // Makes crayons identifiable in things like grinders if(name == "crayon") @@ -228,6 +232,12 @@ .["can_change_colour"] = can_change_colour .["current_colour"] = paint_color + .["precision_mode"] = precision_mode + .["x"] = precision_x + .["y"] = precision_y + .["min_offset"] = -world.icon_size/2 + .["max_offset"] = world.icon_size/2 + /obj/item/toy/crayon/ui_act(action, list/params) if(..()) return @@ -256,6 +266,17 @@ . = TRUE paint_mode = PAINT_NORMAL drawtype = "a" + if("toggle_precision") + precision_mode = !precision_mode + . = TRUE + if("set_precision_x") + var/x = text2num(params["x"]) + precision_x = x + . = TRUE + if("set_precision_y") + var/y = text2num(params["y"]) + precision_y = y + . = TRUE update_icon() /obj/item/toy/crayon/proc/select_colour(mob/user) @@ -277,7 +298,7 @@ /obj/item/toy/crayon/proc/draw_on(atom/target, mob/user, proximity, params) var/static/list/punctuation = list("!","?",".",",","/","+","-","=","%","#","&") - + var/istagger = HAS_TRAIT(user, TRAIT_TAGGER) var/cost = 1 if(paint_mode == PAINT_LARGE_HORIZONTAL) cost = 5 @@ -334,14 +355,14 @@ else if(drawing in graffiti|oriented) temp = "graffiti" - // If a gang member is using a gang spraycan, it'll behave differently - var/gang_mode = FALSE - if(gang && user.mind && user.mind.has_antag_datum(/datum/antagonist/gang)) //Heres a check. - gang_mode = TRUE // No more runtimes if a non-gang member sprays a gang can, it just works like normal cans. - // discontinue if the area isn't valid for tagging because gang "honour" + var/gang_mode + if(user.mind) + gang_mode = user.mind.has_antag_datum(/datum/antagonist/gang) + if(gang_mode && (!can_claim_for_gang(user, target))) return + var/graf_rot if(drawing in oriented) switch(user.dir) @@ -369,16 +390,12 @@ audible_message("You hear spraying.") playsound(user.loc, 'sound/effects/spray.ogg', 5, 1, 5) - var/takes_time = !instant //For order purposes, since I'm maximum bad. - if(gang_mode) - takes_time = TRUE - var/wait_time = 50 if(paint_mode == PAINT_LARGE_HORIZONTAL) wait_time *= 3 - if(takes_time) //This is what deteremines the time it takes to spray a tag in gang mode. 50 is Default. - if(!do_after(user, gang_tag_delay, target = target)) //25 is a good number, but we have gang_tag_delay var now. + if(gang_mode || !instant) + if(!do_after(user, 50, target = target)) return if(length(text_buffer)) @@ -389,32 +406,39 @@ if(actually_paints) + var/obj/effect/decal/cleanable/crayon/C = new(target, paint_color, drawing, temp, graf_rot) if(gang_mode) - // Double check it wasn't tagged in the meanwhile. if(!can_claim_for_gang(user, target)) return - tag_for_gang(user, target) + tag_for_gang(user, target, gang_mode) affected_turfs += target else switch(paint_mode) if(PAINT_NORMAL) - var/obj/effect/decal/cleanable/crayon/C = new(target, paint_color, drawing, temp, graf_rot) C.add_hiddenprint(user) - C.pixel_x = clickx - C.pixel_y = clicky + if(precision_mode) + C.pixel_x = clamp(precision_x, -(world.icon_size/2), world.icon_size/2) + C.pixel_y = clamp(precision_y, -(world.icon_size/2), world.icon_size/2) + else + C.pixel_x = clickx + C.pixel_y = clicky affected_turfs += target if(PAINT_LARGE_HORIZONTAL) var/turf/left = locate(target.x-1,target.y,target.z) var/turf/right = locate(target.x+1,target.y,target.z) if(isValidSurface(left) && isValidSurface(right)) - var/obj/effect/decal/cleanable/crayon/C = new(left, paint_color, drawing, temp, graf_rot, PAINT_LARGE_HORIZONTAL_ICON) - C.add_hiddenprint(user) + C = new(left, paint_color, drawing, temp, graf_rot, PAINT_LARGE_HORIZONTAL_ICON) affected_turfs += left affected_turfs += right affected_turfs += target else to_chat(user, "There isn't enough space to paint!") return + C.add_hiddenprint(user) + if(istagger) + C.AddComponent(/datum/element/art, GOOD_ART) + else + C.AddComponent(/datum/element/art, BAD_ART) if(!instant) to_chat(user, "You finish drawing \the [temp].") @@ -437,52 +461,6 @@ reagents.trans_to(t, ., volume_multiplier) check_empty(user) - -//////////////Gang mode stuff///////////////// -/obj/item/toy/crayon/proc/can_claim_for_gang(mob/user, atom/target) - // Check area validity. - // Reject space, player-created areas, and non-station z-levels. - var/area/A = get_base_area(target) - if(!A || (!is_station_level(A.z)) || !(A.area_flags & VALID_TERRITORY)) - to_chat(user, "[A] is unsuitable for tagging.") - return FALSE - - var/spraying_over = FALSE - for(var/G in target) - var/obj/effect/decal/cleanable/crayon/gang/gangtag = G - if(istype(gangtag)) - var/datum/antagonist/gang/GA = user.mind.has_antag_datum(/datum/antagonist/gang) - if(gangtag.gang != GA.gang) - spraying_over = TRUE - break - - var/occupying_gang = territory_claimed(A, user) - if(occupying_gang && !spraying_over) - to_chat(user, "[A] has already been tagged by the [occupying_gang] gang! You must get rid of or spray over the old tag first!") - return FALSE - - // If you pass the gauntlet of checks, you're good to proceed - return TRUE - -/obj/item/toy/crayon/proc/territory_claimed(area/territory, mob/user) - for(var/datum/team/gang/G in GLOB.gangs) - if(territory.type in (G.territories|G.new_territories)) - . = G.name - break - -/obj/item/toy/crayon/proc/tag_for_gang(mob/user, atom/target) - //Delete any old markings on this tile, including other gang tags - for(var/obj/effect/decal/cleanable/crayon/old_marking in target) - qdel(old_marking) - - var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang) - var/area/territory = get_base_area(target) - - new /obj/effect/decal/cleanable/crayon/gang(target,G.gang,"graffiti",0,user) // Heres the gang tag. - to_chat(user, "You tagged [territory] for your gang!") -/////////////////Gang end//////////////////// - - /obj/item/toy/crayon/attack(mob/M, mob/user) if(edible && (M == user)) to_chat(user, "You take a bite of the [src.name]. Delicious!") @@ -496,6 +474,49 @@ else ..() +//////////////Gang mode stuff///////////////// +/obj/item/toy/crayon/proc/can_claim_for_gang(mob/user, atom/target) + var/area/A = get_area(target) + if(!A || (!is_station_level(A.z))) + to_chat(user, "[A] is unsuitable for tagging.") + return FALSE + + var/spraying_over = FALSE + for(var/obj/effect/decal/cleanable/crayon/gang/G in target) + spraying_over = TRUE + + for(var/obj/machinery/power/apc in target) + to_chat(user, "You can't tag an APC.") + return FALSE + + var/occupying_gang = territory_claimed(A, user) + if(occupying_gang && !spraying_over) + to_chat(user, "[A] has already been tagged by a gang! You must find and spray over the old tag first!") + return FALSE + + // stolen from oldgang lmao + return TRUE + +/obj/item/toy/crayon/proc/tag_for_gang(mob/user, atom/target, datum/antagonist/gang/user_gang) + for(var/obj/effect/decal/cleanable/crayon/old_marking in target) + qdel(old_marking) + + var/area/territory = get_area(target) + + var/obj/effect/decal/cleanable/crayon/gang/tag = new /obj/effect/decal/cleanable/crayon/gang(target) + tag.my_gang = user_gang.my_gang + tag.icon_state = "[user_gang.gang_id]_tag" + tag.name = "[tag.my_gang.name] gang tag" + tag.desc = "Looks like someone's claimed this area for [tag.my_gang.name]." + to_chat(user, "You tagged [territory] for [tag.my_gang.name]!") + +/obj/item/toy/crayon/proc/territory_claimed(area/territory, mob/user) + for(var/obj/effect/decal/cleanable/crayon/gang/G in GLOB.gang_tags) + if(get_area(G) == territory) + return G + +/////////////////Gang end//////////////////// + /obj/item/toy/crayon/red icon_state = "crayonred" paint_color = "#DA0000" @@ -585,7 +606,7 @@ icon_state = "crayonbox" w_class = WEIGHT_CLASS_SMALL -/obj/item/storage/crayons/Initialize() +/obj/item/storage/crayons/Initialize(mapload) . = ..() var/datum/component/storage/STR = GetComponent(/datum/component/storage) STR.max_items = 7 @@ -680,7 +701,7 @@ return (OXYLOSS) -/obj/item/toy/crayon/spraycan/Initialize() +/obj/item/toy/crayon/spraycan/Initialize(mapload) . = ..() // If default crayon red colour, pick a more fun spraycan colour if(!paint_color) @@ -736,8 +757,10 @@ return - if(isobj(target)) + if(isobj(target) && !istype(target, /obj/effect/decal/cleanable/crayon/gang)) if(actually_paints) + if(istype(target, /obj/item/canvas)) //dont color our canvas neon green when im trying to paint please + return var/list/hsl = rgb2hsl(hex2num(copytext(paint_color,2,4)),hex2num(copytext(paint_color,4,6)),hex2num(copytext(paint_color,6,8))) var/static/whitelisted = typecacheof(list(/obj/structure/window, /obj/effect/decal/cleanable/crayon, @@ -839,26 +862,6 @@ post_noise = FALSE reagent_contents = list(/datum/reagent/consumable/nothing = 1, /datum/reagent/toxin/mutetoxin = 1) -/obj/item/toy/crayon/spraycan/gang - charges = 20 // Charges back to 20, which is the default value for them. - gang = TRUE - gang_tag_delay = 15 //Its 50% faster than a regular spraycan, for tagging. After-all they did spend points/meet the boss. - - pre_noise = FALSE - post_noise = TRUE // Its even more stealthy just a tad. - -/obj/item/toy/crayon/spraycan/gang/Initialize(loc, datum/team/gang/G) - ..() - if(G) - gang = G - paint_color = G.color - update_icon() - -/obj/item/toy/crayon/spraycan/gang/examine(mob/user) - . = ..() - if(user.mind && user.mind.has_antag_datum(/datum/antagonist/gang) || isobserver(user)) - . += "This spraycan has been specially modified with a stage 2 nozzle kit, making it faster." - /obj/item/toy/crayon/spraycan/infinite name = "infinite spraycan" charges = -1 diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index 0570de6bcf..880358a2c1 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -14,7 +14,7 @@ throwforce = 6 w_class = WEIGHT_CLASS_BULKY actions_types = list(/datum/action/item_action/toggle_paddles) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/on = FALSE //if the paddles are equipped (1) or on the defib (0) var/safety = TRUE //if you can zap people with the defibs on harm mode @@ -33,7 +33,7 @@ /obj/item/defibrillator/get_cell() return cell -/obj/item/defibrillator/Initialize() //starts without a cell for rnd +/obj/item/defibrillator/Initialize(mapload) //starts without a cell for rnd . = ..() if(cell) cell = new cell(src) @@ -80,13 +80,13 @@ /obj/item/defibrillator/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(loc == user) if(slot_flags == ITEM_SLOT_BACK) - if(user.get_item_by_slot(SLOT_BACK) == src) + if(user.get_item_by_slot(ITEM_SLOT_BACK) == src) ui_action_click() else to_chat(user, "Put the defibrillator on your back first!") else if(slot_flags == ITEM_SLOT_BELT) - if(user.get_item_by_slot(SLOT_BELT) == src) + if(user.get_item_by_slot(ITEM_SLOT_BELT) == src) ui_action_click() else to_chat(user, "Strap the defibrillator's belt on first!") @@ -182,7 +182,7 @@ /obj/item/defibrillator/equipped(mob/user, slot) ..() - if((slot_flags == ITEM_SLOT_BACK && slot != SLOT_BACK) || (slot_flags == ITEM_SLOT_BELT && slot != SLOT_BELT)) + if((slot_flags == ITEM_SLOT_BACK && slot != ITEM_SLOT_BACK) || (slot_flags == ITEM_SLOT_BELT && slot != ITEM_SLOT_BELT)) remove_paddles(user) update_power() @@ -287,7 +287,7 @@ var/disarm_shock_time = 10 var/wielded = FALSE // track wielded status on item -/obj/item/shockpaddles/Initialize() +/obj/item/shockpaddles/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield) RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield) @@ -423,7 +423,7 @@ if((!req_defib && grab_ghost) || (req_defib && defib.grab_ghost)) H.notify_ghost_cloning("Your heart is being defibrillated!") H.grab_ghost() // Shove them back in their body. - else if(H.can_defib()) + else if(H.can_revive()) H.notify_ghost_cloning("Your heart is being defibrillated. Re-enter your corpse if you want to be revived!", source = src) do_help(H, user) @@ -447,7 +447,7 @@ M.visible_message("[user] hastily places [src] on [M]'s chest!", \ "[user] hastily places [src] on [M]'s chest!") busy = TRUE - if(do_after(user, isnull(defib?.disarm_shock_time)? disarm_shock_time : defib.disarm_shock_time, target = M)) + if(do_after(user, isnull(defib?.disarm_shock_time)? disarm_shock_time : defib.disarm_shock_time, M)) M.visible_message("[user] zaps [M] with [src]!", \ "[user] zaps [M] with [src]!") M.DefaultCombatKnockdown(140) @@ -461,6 +461,8 @@ cooldown = TRUE busy = FALSE update_icon() + if(SEND_SIGNAL(src, COMSIG_DEFIBRILLATOR_SUCCESS) & COMPONENT_DEFIB_STOP) + return if(req_defib) defib.cooldowncheck(user) else @@ -475,7 +477,7 @@ "You overcharge the paddles and begin to place them onto [H]'s chest...") busy = TRUE update_icon() - if(do_after(user, 30, target = H)) + if(do_after(user, 3 SECONDS, H)) user.visible_message("[user] places [src] on [H]'s chest.", "You place [src] on [H]'s chest and begin to charge them.") var/turf/T = get_turf(defib) @@ -484,7 +486,7 @@ T.audible_message("\The [defib] lets out an urgent beep and lets out a steadily rising hum...") else user.audible_message("[src] let out an urgent beep.") - if(do_after(user, 30, target = H)) //Takes longer due to overcharging + if(do_after(user, 3 SECONDS, H)) //Takes longer due to overcharging if(!H) busy = FALSE update_icon() @@ -514,6 +516,8 @@ cooldown = TRUE busy = FALSE update_icon() + if(SEND_SIGNAL(src, COMSIG_DEFIBRILLATOR_SUCCESS) & COMPONENT_DEFIB_STOP) + return if(!req_defib) recharge(60) if(req_defib && (defib.cooldowncheck(user))) @@ -538,7 +542,7 @@ primetimer2 = 20 deathtimer = DEFIB_TIME_LOSS * 10 - if(do_after(user, primetimer, target = H)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process + if(do_after(user, primetimer, H)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process user.visible_message("[user] places [src] on [H]'s chest.", "You place [src] on [H]'s chest.") playsound(src, 'sound/machines/defib_charge.ogg', 75, 0) // patients rot when they are killed, and die when they are dead @@ -547,7 +551,7 @@ var/total_burn = 0 var/total_brute = 0 var/obj/item/organ/heart = H.getorgan(/obj/item/organ/heart) - if(do_after(user, primetimer2, target = H)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total + if(do_after(user, primetimer2, H)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total for(var/obj/item/carried_item in H.contents) if(istype(carried_item, /obj/item/clothing/suit/space)) if((!combat && !req_defib) || (req_defib && !defib.combat)) @@ -601,11 +605,12 @@ H.adjustOxyLoss(H.health - HALFWAYCRITDEATH, 0) else var/overall_damage = total_brute + total_burn + H.getToxLoss() + H.getOxyLoss() - var/mobhealth = H.health - H.adjustOxyLoss((mobhealth - HALFWAYCRITDEATH) * (H.getOxyLoss() / overall_damage), 0) - H.adjustToxLoss((mobhealth - HALFWAYCRITDEATH) * (H.getToxLoss() / overall_damage), 0) - H.adjustFireLoss((mobhealth - HALFWAYCRITDEATH) * (total_burn / overall_damage), 0) - H.adjustBruteLoss((mobhealth - HALFWAYCRITDEATH) * (total_brute / overall_damage), 0) + if(overall_damage) + var/mobhealth = H.health + H.adjustOxyLoss((mobhealth - HALFWAYCRITDEATH) * (H.getOxyLoss() / overall_damage), 0) + H.adjustToxLoss((mobhealth - HALFWAYCRITDEATH) * (H.getToxLoss() / overall_damage), 0) + H.adjustFireLoss((mobhealth - HALFWAYCRITDEATH) * (total_burn / overall_damage), 0) + H.adjustBruteLoss((mobhealth - HALFWAYCRITDEATH) * (total_brute / overall_damage), 0) H.updatehealth() // Previous "adjust" procs don't update health, so we do it manually. user.visible_message("[req_defib ? "[defib]" : "[src]"] pings: Resuscitation successful.") playsound(src, 'sound/machines/defib_success.ogg', 50, 0) @@ -631,6 +636,8 @@ defib.deductcharge(revivecost) cooldown = 1 update_icon() + if(SEND_SIGNAL(src, COMSIG_DEFIBRILLATOR_SUCCESS) & COMPONENT_DEFIB_STOP) + return if(req_defib) defib.cooldowncheck(user) else diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 2339e88a76..30877750f6 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -29,9 +29,12 @@ GLOBAL_LIST_EMPTY(PDAs) item_flags = NOBLUDGEON w_class = WEIGHT_CLASS_TINY slot_flags = ITEM_SLOT_ID | ITEM_SLOT_BELT - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) resistance_flags = FIRE_PROOF | ACID_PROOF + always_reskinnable = TRUE + reskin_binding = COMSIG_CLICK_CTRL_SHIFT + //Main variables var/owner = null // String name of owner var/default_cartridge = 0 // Access level defined by cartridge @@ -112,10 +115,42 @@ GLOBAL_LIST_EMPTY(PDAs) . += id ? "Alt-click to remove the id." : "" if(inserted_item && (!isturf(loc))) . += "Ctrl-click to remove [inserted_item]." - if(LAZYLEN(GLOB.pda_reskins)) - . += "Ctrl-shift-click it to reskin it." -/obj/item/pda/Initialize() +/obj/item/pda/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + + if(held_item) + if(istype(held_item, /obj/item/cartridge) && !cartridge) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Insert Cartridge") + . = CONTEXTUAL_SCREENTIP_SET + else if(istype(held_item, /obj/item/card/id) && !id) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Insert ID") + . = CONTEXTUAL_SCREENTIP_SET + else if(istype(held_item, /obj/item/paicard) && !pai) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Insert pAI") + . = CONTEXTUAL_SCREENTIP_SET + else if(is_type_in_list(held_item, contained_item) && !inserted_item) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Insert [held_item]") + . = CONTEXTUAL_SCREENTIP_SET + else if(istype(held_item, /obj/item/photo)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Scan photo") + . = CONTEXTUAL_SCREENTIP_SET + + if(id) // ID gets removed before inserted_item + LAZYSET(context[SCREENTIP_CONTEXT_ALT_LMB], INTENT_ANY, "Remove ID") + . = CONTEXTUAL_SCREENTIP_SET + else if(inserted_item) + LAZYSET(context[SCREENTIP_CONTEXT_ALT_LMB], INTENT_ANY, "Remove [inserted_item]") + . = CONTEXTUAL_SCREENTIP_SET + + if(inserted_item) + LAZYSET(context[SCREENTIP_CONTEXT_CTRL_LMB], INTENT_ANY, "Remove [inserted_item]") + . = CONTEXTUAL_SCREENTIP_SET + return . || NONE + +/obj/item/pda/Initialize(mapload) + if(GLOB.pda_reskins) + unique_reskin = GLOB.pda_reskins . = ..() if(fon) set_light(f_lum, f_pow, f_col) @@ -130,28 +165,12 @@ GLOBAL_LIST_EMPTY(PDAs) new_overlays = TRUE update_icon() -/obj/item/pda/CtrlShiftClick(mob/living/user) - . = ..() - if(GLOB.pda_reskins && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) - reskin_obj(user) + register_context() /obj/item/pda/reskin_obj(mob/M) - if(!LAZYLEN(GLOB.pda_reskins)) - return - var/dat = "Reskin options for [name]:" - for(var/V in GLOB.pda_reskins) - var/output = icon2html(GLOB.pda_reskins[V], M, icon_state) - dat += "\n[V]: [output]" - to_chat(M, dat) - - var/choice = input(M, "Choose the a reskin for [src]","Reskin Object") as null|anything in GLOB.pda_reskins - var/new_icon = GLOB.pda_reskins[choice] - if(QDELETED(src) || isnull(new_icon) || new_icon == icon || !M.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) - return - icon = new_icon + . = ..() new_overlays = TRUE update_icon() - to_chat(M, "[src] is now skinned as '[choice]'.") /obj/item/pda/proc/set_new_overlays() if(!overlays_offsets || !(icon in overlays_offsets)) @@ -191,7 +210,7 @@ GLOBAL_LIST_EMPTY(PDAs) else font_index = MODE_MONO font_mode = FONT_MONO - var/pref_skin = GLOB.pda_reskins[C.prefs.pda_skin] + var/pref_skin = GLOB.pda_reskins[C.prefs.pda_skin]["icon"] if(icon != pref_skin) icon = pref_skin new_overlays = TRUE @@ -369,6 +388,10 @@ GLOBAL_LIST_EMPTY(PDAs) dat += "
  • [PDAIMG(rdoor)]Toggle Remote Door
  • " if (cartridge.access & CART_DRONEPHONE) dat += "
  • [PDAIMG(dronephone)]Drone Phone
  • " + if (cartridge.access & CART_BARTENDER) + dat += "
  • [PDAIMG(bucket)]Drink Recipe Browser
  • " + if (cartridge.access & CART_CHEMISTRY) + dat += "
  • [PDAIMG(bucket)]Chemistry Recipe Browser
  • " dat += "
  • [PDAIMG(atmos)]Atmospheric Scan
  • " dat += "
  • [PDAIMG(flashlight)][fon ? "Disable" : "Enable"] Flashlight
  • " if (pai) @@ -705,6 +728,16 @@ GLOBAL_LIST_EMPTY(PDAs) if(T) pai.forceMove(T) +//DRINK RECIPE BROWSER============================= + if("Drink Recipe Browser") + if(cartridge && cartridge.access & CART_BARTENDER) + recipe_search(U, GLOB.drink_reactions_list) + +//CHEMISTRY RECIPE BROWSER + if("Chemistry Recipe Browser") + if(cartridge && cartridge.access & CART_CHEMISTRY) + recipe_search(U, GLOB.normalized_chemical_reactions_list) + //LINK FUNCTIONS=================================== else//Cartridge menu linking @@ -1218,6 +1251,51 @@ GLOBAL_LIST_EMPTY(PDAs) continue . += P +//borg pda stuff +/mob/living/silicon/robot/proc/cmd_send_pdamesg(mob/user) + var/list/plist = list() + var/list/namecounts = list() + + if(aiPDA.toff) + to_chat(user, "Turn on your receiver in order to send messages.") + return + + for (var/obj/item/pda/P in get_viewable_pdas()) + if (P == src) + continue + else if (P == aiPDA) + continue + + plist[avoid_assoc_duplicate_keys(P.owner, namecounts)] = P + + var/c = input(user, "Please select a PDA") as null|anything in sortList(plist) + + if (!c) + return + + var/selected = plist[c] + + if(aicamera.stored.len) + var/add_photo = input(user,"Do you want to attach a photo?","Photo","No") as null|anything in list("Yes","No") + if(add_photo=="Yes") + var/datum/picture/Pic = aicamera.selectpicture(user) + aiPDA.picture = Pic + + if(incapacitated()) + return + + aiPDA.create_message(src, selected) + + +/mob/living/silicon/robot/proc/cmd_show_message_log(mob/user) + if(incapacitated()) + return + if(!isnull(aiPDA)) + var/HTML = "AI PDA Message Log[aiPDA.tnote]" + user << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0") + else + to_chat(user, "You do not have a PDA. You should make an issue report about this.") + #undef PDA_SCANNER_NONE #undef PDA_SCANNER_MEDICAL #undef PDA_SCANNER_FORENSICS diff --git a/code/game/objects/items/devices/PDA/PDA_types.dm b/code/game/objects/items/devices/PDA/PDA_types.dm index 23ebaec3c2..e857b7dbd5 100644 --- a/code/game/objects/items/devices/PDA/PDA_types.dm +++ b/code/game/objects/items/devices/PDA/PDA_types.dm @@ -8,7 +8,7 @@ ttone = "honk" var/slipvictims = list() //CIT CHANGE - makes clown PDAs track unique people slipped -/obj/item/pda/clown/Initialize() +/obj/item/pda/clown/Initialize(mapload) . = ..() AddComponent(/datum/component/slippery, 120, NO_SLIP_WHEN_WALKING|SLIP_WHEN_JOGGING, CALLBACK(src, .proc/AfterSlip)) @@ -222,6 +222,7 @@ /obj/item/pda/bar name = "bartender PDA" icon_state = "pda-bartender" + default_cartridge = /obj/item/cartridge/bartender inserted_item = /obj/item/pen/fountain /obj/item/pda/atmos diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index 4ca0b86bc0..34f8202898 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -13,6 +13,8 @@ #define CART_QUARTERMASTER (1<<12) #define CART_HYDROPONICS (1<<13) #define CART_DRONEPHONE (1<<14) +#define CART_BARTENDER (1<<15) +#define CART_CHEMISTRY (1<<16) /obj/item/cartridge @@ -50,7 +52,7 @@ var/mob/living/simple_animal/bot/active_bot var/list/botlist = list() -/obj/item/cartridge/Initialize() +/obj/item/cartridge/Initialize(mapload) . = ..() var/obj/item/pda/pda = loc if(istype(pda)) @@ -77,7 +79,7 @@ /obj/item/cartridge/chemistry name = "\improper ChemWhiz cartridge" icon_state = "cart-chem" - access = CART_REAGENT_SCANNER + access = CART_REAGENT_SCANNER | CART_CHEMISTRY bot_access_flags = MED_BOT /obj/item/cartridge/security @@ -129,7 +131,7 @@ icon_state = "cart-tox" access = CART_REAGENT_SCANNER | CART_ATMOS -/obj/item/cartridge/signal/Initialize() +/obj/item/cartridge/signal/Initialize(mapload) . = ..() radio = new(src) @@ -178,7 +180,7 @@ access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_REAGENT_SCANNER | CART_ATMOS | CART_DRONEPHONE bot_access_flags = FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT -/obj/item/cartridge/rd/Initialize() +/obj/item/cartridge/rd/Initialize(mapload) . = ..() radio = new(src) @@ -190,6 +192,12 @@ bot_access_flags = SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT spam_enabled = 1 +/obj/item/cartridge/bartender + name = "\improper B.O.O.Z.E cartridge" + desc = "Now with 12% alcohol!" + icon_state = "cart-bar" + access = CART_BARTENDER + /obj/item/cartridge/captain/New() ..() radio = new(src) diff --git a/code/game/objects/items/devices/PDA/radio.dm b/code/game/objects/items/devices/PDA/radio.dm index 329631ff9e..39d1a7b522 100644 --- a/code/game/objects/items/devices/PDA/radio.dm +++ b/code/game/objects/items/devices/PDA/radio.dm @@ -15,7 +15,7 @@ radio_connection = null return ..() -/obj/item/integrated_signaler/Initialize() +/obj/item/integrated_signaler/Initialize(mapload) . = ..() if (frequency < MIN_FREE_FREQ || frequency > MAX_FREE_FREQ) frequency = sanitize_frequency(frequency) diff --git a/code/game/objects/items/devices/beacon.dm b/code/game/objects/items/devices/beacon.dm index e868ec07b6..cf59551bb8 100644 --- a/code/game/objects/items/devices/beacon.dm +++ b/code/game/objects/items/devices/beacon.dm @@ -9,15 +9,15 @@ var/enabled = TRUE var/renamed = FALSE -/obj/item/beacon/Initialize() +/obj/item/beacon/Initialize(mapload) . = ..() if (enabled) GLOB.teleportbeacons += src - else + else icon_state = "beacon-off" /obj/item/beacon/Destroy() - GLOB.teleportbeacons.Remove(src) + GLOB.teleportbeacons -= src return ..() /obj/item/beacon/attack_self(mob/user) @@ -25,9 +25,9 @@ if (enabled) icon_state = "beacon" GLOB.teleportbeacons += src - else + else icon_state = "beacon-off" - GLOB.teleportbeacons.Remove(src) + GLOB.teleportbeacons -= src to_chat(user, "You [enabled ? "enable" : "disable"] the beacon.") return @@ -40,5 +40,5 @@ name = new_name renamed = TRUE return - else + else return ..() diff --git a/code/game/objects/items/devices/camera_bug.dm b/code/game/objects/items/devices/camera_bug.dm index e20321414d..da5bed07ce 100644 --- a/code/game/objects/items/devices/camera_bug.dm +++ b/code/game/objects/items/devices/camera_bug.dm @@ -161,7 +161,7 @@ dat += " (Stage [stage])" dat += " \[Track\]
    " - for(var/obj/mecha/M in seen) + for(var/obj/vehicle/sealed/mecha/M in seen) if(M.name in names) names[M.name]++ dat += "[M.name] ([names[M.name]])" diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm index a45f26062b..8656cc21f1 100644 --- a/code/game/objects/items/devices/chameleonproj.dm +++ b/code/game/objects/items/devices/chameleonproj.dm @@ -144,8 +144,8 @@ /obj/effect/dummy/chameleon/attack_alien() master.disrupt() -/obj/effect/dummy/chameleon/ex_act(S, T) - contents_explosion(S, T) +/obj/effect/dummy/chameleon/ex_act(severity, target, origin) + contents_explosion(severity, target, origin) master.disrupt() /obj/effect/dummy/chameleon/bullet_act() diff --git a/code/game/objects/items/devices/dogborg_sleeper.dm b/code/game/objects/items/devices/dogborg_sleeper.dm index 01970ccdbd..9524598956 100644 --- a/code/game/objects/items/devices/dogborg_sleeper.dm +++ b/code/game/objects/items/devices/dogborg_sleeper.dm @@ -47,7 +47,7 @@ // Bags are prohibited from this due to the potential explotation of objects, same with brought -/obj/item/dogborg/sleeper/Initialize() +/obj/item/dogborg/sleeper/Initialize(mapload) . = ..() update_icon() item_flags |= NOBLUDGEON //No more attack messages @@ -90,7 +90,7 @@ to_chat(user, "Your [src] is already occupied.") return user.visible_message("[hound.name] is carefully inserting [target.name] into their [src].", "You start placing [target] into your [src]...") - if(!patient && iscarbon(target) && !target.buckled && do_after (user, 100, target = target)) + if(!patient && iscarbon(target) && !target.buckled && do_after(user, 10 SECONDS, target)) if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. return //If they moved away, you can't eat them. @@ -127,7 +127,7 @@ user.visible_message("You see [voracious ? "[user] struggling against the expanded material of [hound]'s gut!" : "and hear [user] pounding against something inside of [hound]'s [src.name]!"]", \ "[voracious ? "You start struggling inside of [src]'s tight, flexible confines," : "You start pounding against the metallic walls of [src],"] trying to trigger the release... (this will take about [DisplayTimeText(breakout_time)].)", \ "You hear a [voracious ? "couple of thumps" : "loud banging noise"] coming from within [hound].") - if(do_after(user, breakout_time, target = src)) + if(do_after(user, breakout_time, src, IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM)) user.visible_message("[user] successfully broke out of [hound.name]!", \ "You successfully break out of [hound.name]!") go_out(user, hound) @@ -172,7 +172,7 @@ /obj/item/dogborg/sleeper/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, "dogborg_sleeper", name, 375, 550) //UI DOES NOT EXIST + ui = new(user, src, "Sleeper", name) ui.open() /obj/item/dogborg/sleeper/ui_data() @@ -326,7 +326,7 @@ cleaning_cycles-- cleaning = TRUE for(var/mob/living/carbon/C in (touchable_items)) - if((C.status_flags & GODMODE) || !CHECK_BITFIELD(C.vore_flags, DIGESTABLE)) + if((C.status_flags & GODMODE) || !(C.vore_flags & DIGESTABLE)) items_preserved += C else C.adjustBruteLoss(2) @@ -335,7 +335,7 @@ var/atom/target = pick(touchable_items) if(iscarbon(target)) //Handle the target being a mob var/mob/living/carbon/T = target - if(T.stat == DEAD && CHECK_BITFIELD(T.vore_flags, DIGESTABLE)) //Mob is now dead + if(T.stat == DEAD && (T.vore_flags & DIGESTABLE)) //Mob is now dead message_admins("[key_name(hound)] has digested [key_name(T)] as a dogborg. ([hound ? "JMP" : "null"])") to_chat(hound,"You feel your belly slowly churn around [T], breaking them down into a soft slurry to be used as power for your systems.") to_chat(T,"You feel [hound]'s belly slowly churn around your form, breaking you down into a soft slurry to be used as power for [hound]'s systems.") @@ -433,7 +433,7 @@ var/mob/living/silicon/robot/hound = get_host() if(!hound || !istype(target) || !proximity || target.anchored) return - if (!CHECK_BITFIELD(target.vore_flags,DEVOURABLE)) + if (!(target.vore_flags & DEVOURABLE)) to_chat(user, "The target registers an error code. Unable to insert into [src].") return if(patient) @@ -443,7 +443,7 @@ to_chat(user,"[target] is buckled and can not be put into your [src].") return user.visible_message("[hound.name] is ingesting [target] into their [src].", "You start ingesting [target] into your [src.name]...") - if(do_after(user, 30, target = target) && !patient && !target.buckled) + if(do_after(user, 3 SECONDS, target) && !patient && !target.buckled) target.forceMove(src) target.reset_perspective(src) update_gut(hound) diff --git a/code/game/objects/items/devices/doorCharge.dm b/code/game/objects/items/devices/doorCharge.dm index c38eb46baf..5ebb34eeed 100644 --- a/code/game/objects/items/devices/doorCharge.dm +++ b/code/game/objects/items/devices/doorCharge.dm @@ -14,7 +14,7 @@ attack_verb = list("blown up", "exploded", "detonated") custom_materials = list(/datum/material/iron=50, /datum/material/glass=30) -/obj/item/doorCharge/ex_act(severity, target) +/obj/item/doorCharge/ex_act(severity, target, origin) switch(severity) if(EXPLODE_DEVASTATE) visible_message("[src] detonates!") diff --git a/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm b/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm index 5dbda8de54..9c06c92108 100644 --- a/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm +++ b/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm @@ -11,7 +11,7 @@ var/static/recycleable_circuits = typecacheof(list(/obj/item/electronics/firelock, /obj/item/electronics/airalarm, /obj/item/electronics/firealarm, \ /obj/item/electronics/apc))//A typecache of circuits consumable for material -/obj/item/electroadaptive_pseudocircuit/Initialize() +/obj/item/electroadaptive_pseudocircuit/Initialize(mapload) . = ..() maptext = "[circuits]" diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index e29519406a..79489c3c51 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -17,7 +17,7 @@ var/flashlight_power = 0.8 //strength of the light when on light_color = "#FFCC66" -/obj/item/flashlight/Initialize() +/obj/item/flashlight/Initialize(mapload) . = ..() if(icon_state == "[initial(icon_state)]-on") on = TRUE @@ -461,7 +461,7 @@ rad_flags = RAD_NO_CONTAMINATE var/fuel = 0 -/obj/item/flashlight/glowstick/Initialize() +/obj/item/flashlight/glowstick/Initialize(mapload) fuel = rand(1000, 1500) light_color = color . = ..() diff --git a/code/game/objects/items/devices/forcefieldprojector.dm b/code/game/objects/items/devices/forcefieldprojector.dm index 9ef9d73705..47c3bc8d13 100644 --- a/code/game/objects/items/devices/forcefieldprojector.dm +++ b/code/game/objects/items/devices/forcefieldprojector.dm @@ -84,10 +84,11 @@ layer = ABOVE_ALL_MOB_LAYER anchored = TRUE density = TRUE + pass_flags_self = PASSGLASS mouse_opacity = MOUSE_OPACITY_OPAQUE resistance_flags = INDESTRUCTIBLE CanAtmosPass = ATMOS_PASS_DENSITY - armor = list("melee" = 0, "bullet" = 25, "laser" = 25, "energy" = 25, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list(MELEE = 0, BULLET = 25, LASER = 25, ENERGY = 25, BOMB = 25, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) var/obj/item/forcefield_projector/generator /obj/structure/projected_forcefield/Initialize(mapload, obj/item/forcefield_projector/origin) @@ -101,11 +102,6 @@ generator = null return ..() -/obj/structure/projected_forcefield/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return 1 - return !density - /obj/structure/projected_forcefield/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) playsound(loc, 'sound/weapons/egloves.ogg', 80, 1) diff --git a/code/game/objects/items/devices/geiger_counter.dm b/code/game/objects/items/devices/geiger_counter.dm index 2413a3fb9a..4caf9ee0aa 100644 --- a/code/game/objects/items/devices/geiger_counter.dm +++ b/code/game/objects/items/devices/geiger_counter.dm @@ -19,6 +19,7 @@ w_class = WEIGHT_CLASS_SMALL slot_flags = ITEM_SLOT_BELT rad_flags = RAD_NO_CONTAMINATE + item_flags = NOBLUDGEON custom_materials = list(/datum/material/iron = 150, /datum/material/glass = 150) var/grace = RAD_GRACE_PERIOD @@ -31,21 +32,19 @@ var/fail_to_receive = 0 var/current_warning = 1 -/obj/item/geiger_counter/Initialize() +/obj/item/geiger_counter/Initialize(mapload) . = ..() START_PROCESSING(SSobj, src) - soundloop = new(list(src), FALSE) + soundloop = new(src, FALSE) /obj/item/geiger_counter/Destroy() STOP_PROCESSING(SSobj, src) QDEL_NULL(soundloop) + return ..() -/obj/item/geiger_counter/process() - update_icon() - update_sound() - +/obj/item/geiger_counter/process(delta_time) if(!scanning) current_tick_amount = 0 return @@ -64,49 +63,55 @@ current_tick_amount = 0 + update_appearance() + update_sound() + /obj/item/geiger_counter/examine(mob/user) . = ..() if(!scanning) return - . += "Alt-click it to clear stored radiation levels." + . += span_info("Alt-click it to clear stored radiation levels.") if(obj_flags & EMAGGED) - . += "The display seems to be incomprehensible." + . += span_warning("The display seems to be incomprehensible.") return switch(radiation_count) if(-INFINITY to RAD_LEVEL_NORMAL) - . += "Ambient radiation level count reports that all is well." + . += span_notice("Ambient radiation level count reports that all is well.") if(RAD_LEVEL_NORMAL + 1 to RAD_LEVEL_MODERATE) - . += "Ambient radiation levels slightly above average." + . += span_alert("Ambient radiation levels slightly above average.") if(RAD_LEVEL_MODERATE + 1 to RAD_LEVEL_HIGH) - . += "Ambient radiation levels above average." + . += span_warning("Ambient radiation levels above average.") if(RAD_LEVEL_HIGH + 1 to RAD_LEVEL_VERY_HIGH) - . += "Ambient radiation levels highly above average." + . += span_danger("Ambient radiation levels highly above average.") if(RAD_LEVEL_VERY_HIGH + 1 to RAD_LEVEL_CRITICAL) - . += "Ambient radiation levels nearing critical level." + . += span_suicide("Ambient radiation levels nearing critical level.") if(RAD_LEVEL_CRITICAL + 1 to INFINITY) - . += "Ambient radiation levels above critical level!" + . += span_boldannounce("Ambient radiation levels above critical level!") - . += "The last radiation amount detected was [last_tick_amount]" + . += span_notice("The last radiation amount detected was [last_tick_amount]") /obj/item/geiger_counter/update_icon_state() if(!scanning) icon_state = "geiger_off" - else if(obj_flags & EMAGGED) + return ..() + if(obj_flags & EMAGGED) icon_state = "geiger_on_emag" - else - switch(radiation_count) - if(-INFINITY to RAD_LEVEL_NORMAL) - icon_state = "geiger_on_1" - if(RAD_LEVEL_NORMAL + 1 to RAD_LEVEL_MODERATE) - icon_state = "geiger_on_2" - if(RAD_LEVEL_MODERATE + 1 to RAD_LEVEL_HIGH) - icon_state = "geiger_on_3" - if(RAD_LEVEL_HIGH + 1 to RAD_LEVEL_VERY_HIGH) - icon_state = "geiger_on_4" - if(RAD_LEVEL_VERY_HIGH + 1 to RAD_LEVEL_CRITICAL) - icon_state = "geiger_on_4" - if(RAD_LEVEL_CRITICAL + 1 to INFINITY) - icon_state = "geiger_on_5" + return ..() + + switch(radiation_count) + if(-INFINITY to RAD_LEVEL_NORMAL) + icon_state = "geiger_on_1" + if(RAD_LEVEL_NORMAL + 1 to RAD_LEVEL_MODERATE) + icon_state = "geiger_on_2" + if(RAD_LEVEL_MODERATE + 1 to RAD_LEVEL_HIGH) + icon_state = "geiger_on_3" + if(RAD_LEVEL_HIGH + 1 to RAD_LEVEL_VERY_HIGH) + icon_state = "geiger_on_4" + if(RAD_LEVEL_VERY_HIGH + 1 to RAD_LEVEL_CRITICAL) + icon_state = "geiger_on_4" + if(RAD_LEVEL_CRITICAL + 1 to INFINITY) + icon_state = "geiger_on_5" + return ..() /obj/item/geiger_counter/proc/update_sound() var/datum/looping_sound/geiger/loop = soundloop @@ -124,21 +129,21 @@ if(amount <= RAD_BACKGROUND_RADIATION || !scanning) return current_tick_amount += amount - update_icon() + update_appearance() /obj/item/geiger_counter/attack_self(mob/user) scanning = !scanning - update_icon() - to_chat(user, "[icon2html(src, user)] You switch [scanning ? "on" : "off"] [src].") + update_appearance() + to_chat(user, span_notice("[icon2html(src, user)] You switch [scanning ? "on" : "off"] [src].")) -/obj/item/geiger_counter/afterattack(atom/target, mob/user) +/obj/item/geiger_counter/afterattack(atom/target, mob/living/user) . = ..() if(user.a_intent == INTENT_HELP) if(!(obj_flags & EMAGGED)) - user.visible_message("[user] scans [target] with [src].", "You scan [target]'s radiation levels with [src]...") + user.visible_message(span_notice("[user] scans [target] with [src]."), span_notice("You scan [target]'s radiation levels with [src]...")) addtimer(CALLBACK(src, .proc/scan, target, user), 20, TIMER_UNIQUE) // Let's not have spamming GetAllContents else - user.visible_message("[user] scans [target] with [src].", "You project [src]'s stored radiation into [target]!") + user.visible_message(span_notice("[user] scans [target] with [src]."), span_danger("You project [src]'s stored radiation into [target]!")) target.rad_act(radiation_count) radiation_count = 0 return TRUE @@ -156,57 +161,61 @@ if(isliving(A)) var/mob/living/M = A if(!M.radiation) - to_chat(user, "[icon2html(src, user)] Radiation levels within normal boundaries.") + to_chat(user, span_notice("[icon2html(src, user)] Radiation levels within normal boundaries.")) else - to_chat(user, "[icon2html(src, user)] Subject is irradiated. Radiation levels: [M.radiation] rad.") + to_chat(user, span_boldannounce("[icon2html(src, user)] Subject is irradiated. Radiation levels: [M.radiation].")) if(rad_strength) - to_chat(user, "[icon2html(src, user)] Target contains radioactive contamination. Radioactive strength: [rad_strength]") + to_chat(user, span_boldannounce("[icon2html(src, user)] Target contains radioactive contamination. Radioactive strength: [rad_strength]")) else - to_chat(user, "[icon2html(src, user)] Target is free of radioactive contamination.") + to_chat(user, span_notice("[icon2html(src, user)] Target is free of radioactive contamination.")) /obj/item/geiger_counter/attackby(obj/item/I, mob/user, params) if(I.tool_behaviour == TOOL_SCREWDRIVER && (obj_flags & EMAGGED)) if(scanning) - to_chat(user, "Turn off [src] before you perform this action!") - return 0 - user.visible_message("[user] unscrews [src]'s maintenance panel and begins fiddling with its innards...", "You begin resetting [src]...") + to_chat(user, span_warning("Turn off [src] before you perform this action!")) + return FALSE + user.visible_message(span_notice("[user] unscrews [src]'s maintenance panel and begins fiddling with its innards..."), span_notice("You begin resetting [src]...")) if(!I.use_tool(src, user, 40, volume=50)) - return 0 - user.visible_message("[user] refastens [src]'s maintenance panel!", "You reset [src] to its factory settings!") + return FALSE + user.visible_message(span_notice("[user] refastens [src]'s maintenance panel!"), span_notice("You reset [src] to its factory settings!")) obj_flags &= ~EMAGGED radiation_count = 0 - update_icon() - return 1 + update_appearance() + return TRUE else return ..() /obj/item/geiger_counter/AltClick(mob/living/user) - . = ..() if(!istype(user) || !user.canUseTopic(src, BE_CLOSE)) - return + return ..() if(!scanning) - to_chat(usr, "[src] must be on to reset its radiation level!") - return TRUE + to_chat(usr, span_warning("[src] must be on to reset its radiation level!")) + return radiation_count = 0 - to_chat(usr, "You flush [src]'s radiation counts, resetting it to normal.") - update_icon() - return TRUE + to_chat(usr, span_notice("You flush [src]'s radiation counts, resetting it to normal.")) + update_appearance() /obj/item/geiger_counter/emag_act(mob/user) . = ..() if(obj_flags & EMAGGED) return if(scanning) - to_chat(user, "Turn off [src] before you perform this action!") + to_chat(user, span_warning("Turn off [src] before you perform this action!")) return - to_chat(user, "You override [src]'s radiation storing protocols. It will now generate small doses of radiation, and stored rads are now projected into creatures you scan.") + to_chat(user, span_warning("You override [src]'s radiation storing protocols. It will now generate small doses of radiation, and stored rads are now projected into creatures you scan.")) obj_flags |= EMAGGED return TRUE /obj/item/geiger_counter/cyborg var/mob/listeningTo +/obj/item/geiger_counter/cyborg/cyborg_unequip(mob/user) + if(!scanning) + return + scanning = FALSE + update_appearance() + /obj/item/geiger_counter/cyborg/equipped(mob/user) . = ..() if(listeningTo == user) @@ -217,6 +226,7 @@ listeningTo = user /obj/item/geiger_counter/cyborg/proc/redirect_rad_act(datum/source, amount) + SIGNAL_HANDLER rad_act(amount) /obj/item/geiger_counter/cyborg/dropped(mob/user) diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index e0453cebc0..e2dc7b0f91 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -11,7 +11,7 @@ var/emp_proof = FALSE var/starton = TRUE -/obj/item/gps/Initialize() +/obj/item/gps/Initialize(mapload) . = ..() AddComponent(/datum/component/gps/item, gpstag, emp_proof, starton) @@ -36,7 +36,7 @@ gpstag = "BORG0" desc = "A mining cyborg internal positioning system. Used as a recovery beacon for damaged cyborg assets, or a collaboration tool for mining teams." -/obj/item/gps/cyborg/Initialize() +/obj/item/gps/cyborg/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT) @@ -75,7 +75,7 @@ for marking the area around the transition edges." var/list/turf/tagged -/obj/item/gps/visible_debug/Initialize() +/obj/item/gps/visible_debug/Initialize(mapload) . = ..() tagged = list() START_PROCESSING(SSfastprocess, src) diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 9ab6115634..c5e92349c7 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -67,6 +67,9 @@ // when we get this many shards, we get a free bulb. var/shards_required = 4 + // whether it is "bluespace powered" (can be used at a range) + var/bluespace_toggle = FALSE + /obj/item/lightreplacer/New() uses = max_uses / 2 failmsg = "The [name]'s refill light blinks red." @@ -242,7 +245,7 @@ /obj/item/lightreplacer/afterattack(atom/T, mob/U, proximity) . = ..() - if(!proximity) + if(!proximity && !bluespace_toggle) return if(!isturf(T)) return @@ -253,6 +256,18 @@ break used = TRUE if(istype(A, /obj/machinery/light)) + if(!proximity && bluespace_toggle) + // Set variable for target light + var/obj/machinery/light/target = A + + // Check light status before playing effects + if(target.status != LIGHT_OK) + // Display RPED beam + U.Beam(A, icon_state = "rped_upgrade", time = 1 SECONDS) + + // Play RPED sound + playsound(src, 'sound/items/pshoom.ogg', 40, 1) + ReplaceLight(A, U) if(!used) @@ -266,6 +281,15 @@ /obj/item/lightreplacer/cyborg/janicart_insert(mob/user, obj/structure/janitorialcart/J) return +/obj/item/lightreplacer/blue + name = "bluespace light replacer" + desc = "A modified light replacer that zaps lights into place. Refill with broken or working lightbulbs, or sheets of glass." + icon_state = "lightreplacer_blue" + bluespace_toggle = TRUE + +/obj/item/lightreplacer/blue/emag_act() + return // balancing against longrange explosions + #undef LIGHT_OK #undef LIGHT_EMPTY #undef LIGHT_BROKEN diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm index 365446bad9..a3de2d822f 100644 --- a/code/game/objects/items/devices/megaphone.dm +++ b/code/game/objects/items/devices/megaphone.dm @@ -19,7 +19,7 @@ /obj/item/megaphone/equipped(mob/M, slot) . = ..() - if (slot == SLOT_HANDS) + if (slot == ITEM_SLOT_HANDS) RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) else UnregisterSignal(M, COMSIG_MOB_SAY) diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index 1e43f0f883..fbc241c5de 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -45,7 +45,7 @@ throwforce = 10 obj_flags = UNIQUE_RENAME -/obj/item/multitool/chaplain/Initialize() +/obj/item/multitool/chaplain/Initialize(mapload) . = ..() AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE) @@ -130,7 +130,7 @@ var/mob/camera/aiEye/remote/ai_detector/eye var/datum/action/item_action/toggle_multitool/toggle_action -/obj/item/multitool/ai_detect/Initialize() +/obj/item/multitool/ai_detect/Initialize(mapload) . = ..() START_PROCESSING(SSobj, src) eye = new /mob/camera/aiEye/remote/ai_detector() diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index d54911528d..845c8a874f 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -15,7 +15,7 @@ user.visible_message("[user] is staring sadly at [src]! [user.p_they()] can't keep living without real human intimacy!") return OXYLOSS -/obj/item/paicard/Initialize() +/obj/item/paicard/Initialize(mapload) SSpai.pai_card_list += src add_overlay("pai-off") AddElement(/datum/element/bed_tuckable, 6, -5, 90) diff --git a/code/game/objects/items/devices/portable_chem_mixer.dm b/code/game/objects/items/devices/portable_chem_mixer.dm index c773699b1d..8ffd978c59 100644 --- a/code/game/objects/items/devices/portable_chem_mixer.dm +++ b/code/game/objects/items/devices/portable_chem_mixer.dm @@ -27,7 +27,7 @@ QDEL_NULL(beaker) return ..() -/obj/item/storage/portable_chem_mixer/ex_act(severity, target) +/obj/item/storage/portable_chem_mixer/ex_act(severity, target, origin) if(severity < 3) ..() diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index 838b5376c5..140bcc192f 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -28,7 +28,7 @@ GLOBAL_LIST_EMPTY(power_sinks) var/obj/structure/cable/attached // the attached cable -/obj/item/powersink/Initialize() +/obj/item/powersink/Initialize(mapload) . = ..() GLOB.power_sinks += src diff --git a/code/game/objects/items/devices/pressureplates.dm b/code/game/objects/items/devices/pressureplates.dm index 2b5c8d873b..47dcaae60e 100644 --- a/code/game/objects/items/devices/pressureplates.dm +++ b/code/game/objects/items/devices/pressureplates.dm @@ -22,7 +22,7 @@ var/can_trigger = TRUE var/trigger_delay = 10 -/obj/item/pressure_plate/Initialize() +/obj/item/pressure_plate/Initialize(mapload) . = ..() tile_overlay = image(icon = 'icons/turf/floors.dmi', icon_state = "pp_overlay") if(roundstart_signaller) diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index c51edc8106..9e802d173c 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -20,7 +20,7 @@ user.visible_message("[user] hooks [user.p_them()]self to the electropack and spams the trigger! It looks like [user.p_theyre()] trying to commit suicide!") return (FIRELOSS) -/obj/item/electropack/Initialize() +/obj/item/electropack/Initialize(mapload) . = ..() set_frequency(frequency) @@ -156,7 +156,7 @@ category = list("hacked", "Misc") /obj/item/electropack/shockcollar/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - if(loc == user && user.get_item_by_slot(SLOT_NECK)) + if(loc == user && user.get_item_by_slot(ITEM_SLOT_NECK)) to_chat(user, "The collar is fastened tight! You'll need help taking this off!") return return ..() @@ -167,7 +167,7 @@ if(isliving(loc) && on) //the "on" arg is currently useless var/mob/living/L = loc - if(!L.get_item_by_slot(SLOT_NECK)) //**properly** stops pocket shockers + if(!L.get_item_by_slot(ITEM_SLOT_NECK)) //**properly** stops pocket shockers return if(shock_cooldown == TRUE) return diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm index e26b9dd845..abc81b0f8e 100644 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/code/game/objects/items/devices/radio/encryptionkey.dm @@ -9,9 +9,9 @@ var/independent = FALSE var/list/channels = list() -/obj/item/encryptionkey/Initialize() +/obj/item/encryptionkey/Initialize(mapload) . = ..() - if(!channels.len) + if(!length(channels) && !translate_binary) desc = "An encryption key for a radio headset. Has no special codes in it. You should probably tell a coder!" /obj/item/encryptionkey/examine(mob/user) @@ -22,6 +22,8 @@ examine_text_list += "[GLOB.channel_tokens[i]] - [lowertext(i)]" . += "It can access the following channels; [jointext(examine_text_list, ", ")]." + if(translate_binary) + . += "It also allows access to the special binary channel used by silicons." /obj/item/encryptionkey/syndicate name = "syndicate encryption key" diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 54556c20b6..8403ea30e7 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -56,9 +56,9 @@ GLOBAL_LIST_INIT(channel_tokens, list( /obj/item/radio/headset/ComponentInitialize() . = ..() if (bowman) - AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS)) + AddComponent(/datum/component/wearertargeting/earprotection, list(ITEM_SLOT_EARS)) -/obj/item/radio/headset/Initialize() +/obj/item/radio/headset/Initialize(mapload) . = ..() recalculateChannels() @@ -94,17 +94,23 @@ GLOBAL_LIST_INIT(channel_tokens, list( name = "team leader headset" command = TRUE -/obj/item/radio/headset/syndicate/Initialize() +/obj/item/radio/headset/syndicate/Initialize(mapload) . = ..() make_syndie() /obj/item/radio/headset/binary -/obj/item/radio/headset/binary/Initialize() +/obj/item/radio/headset/binary/Initialize(mapload) . = ..() qdel(keyslot) keyslot = new /obj/item/encryptionkey/binary recalculateChannels() +/obj/item/radio/headset/headset_prisoner + name = "prison radio headset" + desc = "An updated, modular intercom that fits over the head. Takes encryption keys. It looks like it has been modified to not broadcast." + icon_state = "prisoner_headset" + prison_radio = TRUE + /obj/item/radio/headset/headset_sec name = "security radio headset" desc = "This is used by your elite security force." @@ -263,6 +269,10 @@ GLOBAL_LIST_INIT(channel_tokens, list( . = ..() AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES) +/obj/item/radio/headset/silicon/pai/emp_act(severity) + . = ..() + return EMP_PROTECT_SELF + /obj/item/radio/headset/silicon/ai name = "\proper Integrated Subspace Transceiver " keyslot2 = new /obj/item/encryptionkey/ai @@ -363,4 +373,4 @@ GLOBAL_LIST_INIT(channel_tokens, list( name = replacetext(name,"headset", "bowman headset") desc = "[desc] Protects ears from flashbangs." bowman = TRUE - AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS)) + AddComponent(/datum/component/wearertargeting/earprotection, list(ITEM_SLOT_EARS)) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index e81110425c..3a3ffd7ea1 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -5,6 +5,7 @@ item_state = "walkietalkie" desc = "A basic handheld radio that communicates with local telecommunication networks." dog_fashion = /datum/dog_fashion/back + var/list/extra_channels = list() //Allows indivudal channels, used for borgs flags_1 = CONDUCT_1 | HEAR_1 slot_flags = ITEM_SLOT_BELT @@ -69,6 +70,11 @@ if(keyslot.independent) independent = TRUE + if(extra_channels) + for(var/ch_name in extra_channels) + if(!(ch_name in channels)) + channels[ch_name] = extra_channels[ch_name] + for(var/ch_name in channels) secure_radio_connections[ch_name] = add_radio(src, GLOB.radiochannels[ch_name]) @@ -84,7 +90,7 @@ QDEL_NULL(keyslot) return ..() -/obj/item/radio/Initialize() +/obj/item/radio/Initialize(mapload) wires = new /datum/wires/radio(src) if(prison_radio) wires.cut(WIRE_TX) // OH GOD WHY @@ -378,7 +384,7 @@ syndie = 1 keyslot = new /obj/item/encryptionkey/syndicate -/obj/item/radio/borg/syndicate/Initialize() +/obj/item/radio/borg/syndicate/Initialize(mapload) . = ..() set_frequency(FREQ_SYNDICATE) diff --git a/code/game/objects/items/devices/reverse_bear_trap.dm b/code/game/objects/items/devices/reverse_bear_trap.dm index f2a0ea5450..48206ba867 100644 --- a/code/game/objects/items/devices/reverse_bear_trap.dm +++ b/code/game/objects/items/devices/reverse_bear_trap.dm @@ -22,10 +22,10 @@ var/datum/looping_sound/reverse_bear_trap/soundloop var/datum/looping_sound/reverse_bear_trap_beep/soundloop2 -/obj/item/reverse_bear_trap/Initialize() +/obj/item/reverse_bear_trap/Initialize(mapload) . = ..() - soundloop = new(list(src)) - soundloop2 = new(list(src)) + soundloop = new(src) + soundloop2 = new(src) /obj/item/reverse_bear_trap/Destroy() QDEL_NULL(soundloop) @@ -33,22 +33,22 @@ STOP_PROCESSING(SSprocessing, src) return ..() -/obj/item/reverse_bear_trap/process() +/obj/item/reverse_bear_trap/process(delta_time) if(!ticking) return - time_left-- + time_left -= delta_time soundloop2.mid_length = max(0.5, time_left - 5) //beepbeepbeepbeepbeep - if(!time_left || !isliving(loc)) + if(time_left <= 0 || !isliving(loc)) playsound(src, 'sound/machines/microwave/microwave-end.ogg', 100, FALSE) soundloop.stop() soundloop2.stop() - to_chat(loc, "*ding*") + to_chat(loc, span_userdanger("*ding*")) addtimer(CALLBACK(src, .proc/snap), 2) /obj/item/reverse_bear_trap/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(iscarbon(user)) var/mob/living/carbon/C = user - if(C.get_item_by_slot(SLOT_HEAD) == src) + if(C.get_item_by_slot(ITEM_SLOT_HEAD) == src) if(HAS_TRAIT_FROM(src, TRAIT_NODROP, REVERSE_BEAR_TRAP_TRAIT) && !struggling) struggling = TRUE var/fear_string @@ -82,26 +82,26 @@ ..() /obj/item/reverse_bear_trap/attack(mob/living/target, mob/living/user) - if(target.get_item_by_slot(SLOT_HEAD)) + if(target.get_item_by_slot(ITEM_SLOT_HEAD)) to_chat(user, "Remove [target.p_their()] headgear first!") return target.visible_message("[user] starts forcing [src] onto [target]'s head!", \ "[target] starts forcing [src] onto your head!", "You hear clanking.") to_chat(user, "You start forcing [src] onto [target]'s head...") - if(!do_after(user, 30, target = target) || target.get_item_by_slot(SLOT_HEAD)) + if(!do_after(user, 30, target = target) || target.get_item_by_slot(ITEM_SLOT_HEAD)) return target.visible_message("[user] forces and locks [src] onto [target]'s head!", \ "[target] locks [src] onto your head!", "You hear a click, and then a timer ticking down.") to_chat(user, "You force [src] onto [target]'s head and click the padlock shut.") user.dropItemToGround(src) - target.equip_to_slot_if_possible(src, SLOT_HEAD) + target.equip_to_slot_if_possible(src, ITEM_SLOT_HEAD) arm() notify_ghosts("[user] put a reverse bear trap on [target]!", source = src, action = NOTIFY_ORBIT, ghost_sound = 'sound/machines/beep.ogg') /obj/item/reverse_bear_trap/proc/snap() reset() var/mob/living/carbon/human/H = loc - if(!istype(H) || H.get_item_by_slot(SLOT_HEAD) != src) + if(!istype(H) || H.get_item_by_slot(ITEM_SLOT_HEAD) != src) visible_message("[src]'s jaws snap open with an ear-piercing crack!") playsound(src, 'sound/effects/snap.ogg', 75, TRUE) else @@ -116,13 +116,22 @@ /obj/item/reverse_bear_trap/proc/reset() ticking = FALSE + update_appearance(UPDATE_OVERLAYS) REMOVE_TRAIT(src, TRAIT_NODROP, REVERSE_BEAR_TRAP_TRAIT) soundloop.stop() soundloop2.stop() STOP_PROCESSING(SSprocessing, src) +/obj/item/reverse_bear_trap/update_overlays() + . = ..() + if(ticking != TRUE) + return + /// note: this timer overlay increments one frame every second (to simulate a clock ticking). If you want to instead have it do a full cycle in a minute, set the 'delay' of each frame of the icon overlay to 75 rather than 10, and the worn overlay to twice that. + // . += "rbt_ticking" + /obj/item/reverse_bear_trap/proc/arm() //hulen ticking = TRUE + update_appearance(UPDATE_OVERLAYS) escape_chance = initial(escape_chance) //we keep these vars until re-arm, for tracking purposes time_left = initial(time_left) ADD_TRAIT(src, TRAIT_NODROP, REVERSE_BEAR_TRAP_TRAIT) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 0bf7b13646..7d7e39c41f 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -91,6 +91,11 @@ GENETICS SCANNER var/scanmode = SCANMODE_HEALTH var/advanced = FALSE +/obj/item/healthanalyzer/Initialize(mapload) + . = ..() + + register_item_context() + /obj/item/healthanalyzer/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins to analyze [user.p_them()]self with [src]! The display shows that [user.p_theyre()] dead!") return BRUTELOSS @@ -130,6 +135,24 @@ GENETICS SCANNER add_fingerprint(user) +/obj/item/healthanalyzer/add_item_context( + obj/item/source, + list/context, + atom/target, +) + if (!isliving(target)) + return NONE + + switch (scanmode) + if (SCANMODE_HEALTH) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Scan health") + if (SCANMODE_CHEMICAL) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Scan chemicals") + if (SCANMODE_WOUND) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Scan wounds") + + return CONTEXTUAL_SCREENTIP_SET + // Used by the PDA medical scanner too /proc/healthscan(mob/user, mob/living/M, mode = 1, advanced = FALSE) if(isliving(user) && (user.incapacitated() || user.eye_blind)) @@ -145,32 +168,29 @@ GENETICS SCANNER mob_status = "Deceased" oxy_loss = max(rand(1, 40), oxy_loss, (300 - (tox_loss + fire_loss + brute_loss))) // Random oxygen loss - var/msg = "*---------*\nAnalyzing results for [M]:\n\tOverall status: [mob_status]" + var/msg = "Analyzing results for [M]:\n
    Overall status: [mob_status]" // Damage descriptions if(brute_loss > 10) - msg += "\n\t[brute_loss > 50 ? "Severe" : "Minor"] tissue damage detected." + msg += "\n[brute_loss > 50 ? "Severe" : "Minor"] tissue damage detected." if(fire_loss > 10) - msg += "\n\t[fire_loss > 50 ? "Severe" : "Minor"] burn damage detected." + msg += "\n[fire_loss > 50 ? "Severe" : "Minor"] burn damage detected." if(oxy_loss > 10) - msg += "\n\t[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected." + msg += "\n[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected." if(tox_loss > 10) - msg += "\n\t[tox_loss > 50 ? "Severe" : "Minor"] amount of [HAS_TRAIT(M, TRAIT_ROBOTIC_ORGANISM) ? "system corruption" : "toxin damage"] detected." + msg += "\n[tox_loss > 50 ? "Severe" : "Minor"] amount of [HAS_TRAIT(M, TRAIT_ROBOTIC_ORGANISM) ? "system corruption" : "toxin damage"] detected." if(M.getStaminaLoss()) - msg += "\n\tSubject appears to be suffering from fatigue." + msg += "\nSubject appears to be suffering from fatigue." if(advanced) - msg += "\n\tFatigue Level: [M.getStaminaLoss()]%." + msg += "\nFatigue Level: [M.getStaminaLoss()]%." if (M.getCloneLoss()) - msg += "\n\tSubject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage." + msg += "\nSubject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage." if(advanced) - msg += "\n\tCellular Damage Level: [M.getCloneLoss()]." + msg += "\nCellular Damage Level: [M.getCloneLoss()]." if(ishuman(M)) var/mob/living/carbon/human/H = M if(advanced && H.has_dna()) - msg += "\n\tGenetic Stability: [H.dna.stability]%." - - to_chat(user, msg) - msg = "" + msg += "\nGenetic Stability: [H.dna.stability]%." // Body part damage report var/list/dmgreport = list() @@ -178,7 +198,7 @@ GENETICS SCANNER var/mob/living/carbon/C = M var/list/damaged = C.get_damaged_bodyparts(1,1) if(length(damaged)>0 || oxy_loss>0 || tox_loss>0 || fire_loss>0) - dmgreport += "
    \ + dmgreport += "
    \ \ \ \ @@ -196,7 +216,7 @@ GENETICS SCANNER \ " dmgreport += "
    Damage:BruteBurn[(org.brute_dam > 0) ? "[org.brute_dam]" : "0"][(org.burn_dam > 0) ? "[org.burn_dam]" : "0"]
    " - to_chat(user, dmgreport.Join()) + msg += "\n[dmgreport.Join()]" //Organ damages report @@ -317,7 +337,7 @@ GENETICS SCANNER damage_message += " Minor [O.name] failure detected." if(temp_message || damage_message) - msg += "\t[uppertext(O.name)]: [damage_message] [temp_message]\n" + msg += "\n[uppertext(O.name)]: [damage_message] [temp_message]\n" @@ -325,31 +345,31 @@ GENETICS SCANNER var/breathes = TRUE var/blooded = TRUE if(C.dna && C.dna.species) - if(HAS_TRAIT_FROM(C, TRAIT_NOBREATH, SPECIES_TRAIT)) + if(!HAS_TRAIT_FROM(C, TRAIT_AUXILIARY_LUNGS, SPECIES_TRAIT) && HAS_TRAIT_FROM(C, TRAIT_NOBREATH, SPECIES_TRAIT)) breathes = FALSE if(NOBLOOD in C.dna.species.species_traits) blooded = FALSE var/has_liver = C.dna && !(NOLIVER in C.dna.species.species_traits) var/has_stomach = C.dna && !(NOSTOMACH in C.dna.species.species_traits) if(!M.getorganslot(ORGAN_SLOT_EYES)) - msg += "\tSubject does not have eyes.\n" + msg += "Subject does not have eyes.\n" if(!M.getorganslot(ORGAN_SLOT_EARS)) - msg += "\tSubject does not have ears.\n" + msg += "Subject does not have ears.\n" if(!M.getorganslot(ORGAN_SLOT_BRAIN)) - msg += "\tSubject's brain function is non-existent!\n" + msg += "Subject's brain function is non-existent!\n" if(has_liver && !M.getorganslot(ORGAN_SLOT_LIVER)) - msg += "\tSubject's liver is missing!\n" + msg += "Subject's liver is missing!\n" if(blooded && !M.getorganslot(ORGAN_SLOT_HEART)) - msg += "\tSubject's heart is missing!\n" + msg += "Subject's heart is missing!\n" if(breathes && !M.getorganslot(ORGAN_SLOT_LUNGS)) - msg += "\tSubject's lungs have collapsed from trauma!\n" + msg += "Subject's lungs have collapsed from trauma!\n" if(has_stomach && !M.getorganslot(ORGAN_SLOT_STOMACH)) - msg += "\tSubject's stomach is missing!\n" + msg += "Subject's stomach is missing!\n" if(M.radiation) - msg += "\tSubject is irradiated.\n" - msg += "\tRadiation Level: [M.radiation] rad\n" + msg += "Subject is irradiated.\n" + msg += "Radiation Level: [M.radiation] rad\n" @@ -380,12 +400,14 @@ GENETICS SCANNER mutant = TRUE else if (S.mutantstomach != initial(S.mutantstomach)) mutant = TRUE + else if (S.flying_species != initial(S.flying_species)) + mutant = TRUE - msg += "\tReported Species: [H.spec_trait_examine_font()][H.dna.custom_species ? H.dna.custom_species : S.name]\n" - msg += "\tBase Species: [H.spec_trait_examine_font()][S.name]\n" + msg += "\nReported Species: [H.spec_trait_examine_font()][H.dna.custom_species ? H.dna.custom_species : S.name]\n" + msg += "Base Species: [H.spec_trait_examine_font()][S.name]\n" if(mutant) - msg += "\tSubject has mutations present.\n" - msg += "\tBody temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)\n" + msg += "Subject has mutations present.\n" + msg += "Body temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)\n" // Time of death if(M.tod && (M.stat == DEAD || ((HAS_TRAIT(M, TRAIT_FAKEDEATH)) && !advanced))) @@ -434,12 +456,13 @@ GENETICS SCANNER if(R) blood_type = R.name + if((C.scan_blood_volume() + C.integrating_blood) <= (BLOOD_VOLUME_SAFE * C.blood_ratio) && (C.scan_blood_volume() + C.integrating_blood) > (BLOOD_VOLUME_OKAY*C.blood_ratio)) - msg += "LOW blood level [blood_percent] %, [C.scan_blood_volume()] cl[C.integrating_blood? ", with [integrated_blood_percent] % of it integrating, [C.integrating_blood] cl " : ""]. type: [blood_type]\n" + msg += "LOW [HAS_TRAIT(C, TRAIT_ROBOTIC_ORGANISM) ? "coolant" : "blood"] level [blood_percent] %, [C.scan_blood_volume()] cl[C.integrating_blood? ", with [integrated_blood_percent] % of it integrating, [C.integrating_blood] cl " : ""]. type: [blood_type]\n" else if((C.scan_blood_volume() + C.integrating_blood) <= (BLOOD_VOLUME_OKAY * C.blood_ratio)) - msg += "CRITICAL blood level [blood_percent] %, [C.scan_blood_volume()] cl[C.integrating_blood? ", with [integrated_blood_percent] % of it integrating, [C.integrating_blood] cl " : ""]. type: [blood_type]\n" + msg += "CRITICAL [HAS_TRAIT(C, TRAIT_ROBOTIC_ORGANISM) ? "coolant" : "blood"] level [blood_percent] %, [C.scan_blood_volume()] cl[C.integrating_blood? ", with [integrated_blood_percent] % of it integrating, [C.integrating_blood] cl " : ""]. type: [blood_type]\n" else - msg += "Blood level [blood_percent] %, [C.scan_blood_volume()] cl[C.integrating_blood? ", with [integrated_blood_percent] % of it integrating, [C.integrating_blood] cl " : ""]. type: [blood_type]\n" + msg += "[HAS_TRAIT(C, TRAIT_ROBOTIC_ORGANISM) ? "Coolant" : "Blood"] level [blood_percent] %, [C.scan_blood_volume()] cl[C.integrating_blood? ", with [integrated_blood_percent] % of it integrating, [C.integrating_blood] cl " : ""]. type: [blood_type]\n" var/cyberimp_detect @@ -449,14 +472,14 @@ GENETICS SCANNER if(cyberimp_detect) msg += "Detected cybernetic modifications:\n" msg += "[cyberimp_detect]\n" - msg += "*---------*" + msg += "" to_chat(user, msg) SEND_SIGNAL(M, COMSIG_NANITE_SCAN, user, FALSE) /proc/chemscan(mob/living/user, mob/living/M) if(istype(M)) if(M.reagents) - var/msg = "*---------*\n" + var/msg = "
    " if(M.reagents.reagent_list.len) var/list/datum/reagent/reagents = list() for(var/datum/reagent/R in M.reagents.reagent_list) @@ -467,7 +490,8 @@ GENETICS SCANNER if(length(reagents)) msg += "Subject contains the following reagents:\n" for(var/datum/reagent/R in reagents) - msg += "[R.volume] units of [R.name][R.overdosed == 1 ? " - OVERDOSING" : "."]\n" + var/invalid_reagent = is_reagent_processing_invalid(R, M) + msg += "[invalid_reagent ? "" : ""][R.volume] units of [R.name][invalid_reagent ? "" : ""][R.overdosed == 1 ? " - OVERDOSING" : "."]\n" else msg += "Subject contains no reagents.\n" @@ -494,7 +518,7 @@ GENETICS SCANNER if(95 to INFINITY) msg += "Subject contains a extremely dangerous amount of toxic isomers.\n" - msg += "*---------*" + msg += "
    " to_chat(user, msg) /obj/item/healthanalyzer/verb/toggle_mode() @@ -525,12 +549,14 @@ GENETICS SCANNER var/render_list = "" for(var/i in patient.get_wounded_bodyparts()) + if(render_list == "") + render_list += "
    " var/obj/item/bodypart/wounded_part = i render_list += "Warning: Physical trauma[LAZYLEN(wounded_part.wounds) > 1? "s" : ""] detected in [wounded_part.name]" for(var/k in wounded_part.wounds) var/datum/wound/W = k render_list += "
    [W.get_scanner_description()]
    \n" - render_list += "
    " + render_list += "
    " if(render_list == "") if(istype(scanner)) @@ -546,6 +572,7 @@ GENETICS SCANNER name = "first aid analyzer" icon_state = "adv_spectrometer" desc = "A prototype MeLo-Tech medical scanner used to diagnose injuries and recommend treatment for serious wounds, but offers no further insight into the patient's health. You hope the final version is less annoying to read!" + scanmode = SCANMODE_WOUND // Forces context to give correct tip. var/next_encouragement var/greedy diff --git a/code/game/objects/items/devices/swapper.dm b/code/game/objects/items/devices/swapper.dm new file mode 100644 index 0000000000..08646efd98 --- /dev/null +++ b/code/game/objects/items/devices/swapper.dm @@ -0,0 +1,112 @@ +//ported from TG, credit to XDTM +/obj/item/swapper + name = "quantum spin inverter" + desc = "An experimental device that is able to swap the locations of two entities by switching their particles' spin values. Must be linked to another device to function." + icon = 'icons/obj/device.dmi' + icon_state = "swapper" + item_state = "electronic" + w_class = WEIGHT_CLASS_SMALL + item_flags = NOBLUDGEON + lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' + + var/cooldown = 300 + var/next_use = 0 + var/obj/item/swapper/linked_swapper + +/obj/item/swapper/Destroy() + if(linked_swapper) + linked_swapper.linked_swapper = null //*inception music* + linked_swapper.update_appearance() + linked_swapper = null + return ..() + +/obj/item/swapper/update_icon_state() + icon_state = "swapper[linked_swapper ? "-linked" : null]" + return ..() + +/obj/item/swapper/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/swapper)) + var/obj/item/swapper/other_swapper = I + if(other_swapper.linked_swapper) + to_chat(user, span_warning("[other_swapper] is already linked. Break the current link to establish a new one.")) + return + if(linked_swapper) + to_chat(user, span_warning("[src] is already linked. Break the current link to establish a new one.")) + return + to_chat(user, span_notice("You establish a quantum link between the two devices.")) + linked_swapper = other_swapper + other_swapper.linked_swapper = src + update_appearance() + linked_swapper.update_appearance() + else + return ..() + +/obj/item/swapper/attack_self(mob/living/user) + if(world.time < next_use) + to_chat(user, span_warning("[src] is still recharging.")) + return + if(QDELETED(linked_swapper)) + to_chat(user, span_warning("[src] is not linked with another swapper.")) + return + playsound(src, 'sound/weapons/flash.ogg', 25, TRUE) + to_chat(user, span_notice("You activate [src].")) + playsound(linked_swapper, 'sound/weapons/flash.ogg', 25, TRUE) + if(ismob(linked_swapper.loc)) + var/mob/holder = linked_swapper.loc + to_chat(holder, span_notice("[linked_swapper] starts buzzing.")) + next_use = world.time + cooldown //only the one used goes on cooldown + addtimer(CALLBACK(src, .proc/swap, user), 25) + +/obj/item/swapper/examine(mob/user) + . = ..() + if(world.time < next_use) + . += span_warning("Time left to recharge: [DisplayTimeText(next_use - world.time)].") + if(linked_swapper) + . += span_notice("Linked. Alt-Click to break the quantum link.") + else + . += span_notice("Not Linked. Use on another quantum spin inverter to establish a quantum link.") + +/obj/item/swapper/AltClick(mob/living/user) + if(!user.canUseTopic(src, BE_CLOSE, NO_DEXTERY,, FALSE, !iscyborg(user))) //someone mispelled dexterity + return + to_chat(user, span_notice("You break the current quantum link.")) + if(!QDELETED(linked_swapper)) + linked_swapper.linked_swapper = null + linked_swapper.update_appearance() + linked_swapper = null + update_appearance() + +//Gets the topmost teleportable container +/obj/item/swapper/proc/get_teleportable_container() + var/atom/movable/teleportable = src + while(ismovable(teleportable.loc)) + var/atom/movable/AM = teleportable.loc + if(AM.anchored) + break + if(isliving(AM)) + var/mob/living/L = AM + if(L.buckled) + if(L.buckled.anchored) + break + else + var/obj/buckled_obj = L.buckled + buckled_obj.unbuckle_mob(L) + teleportable = AM + return teleportable + +/obj/item/swapper/proc/swap(mob/user) + if(QDELETED(linked_swapper) || world.time < linked_swapper.cooldown) + return + + var/atom/movable/A = get_teleportable_container() + var/atom/movable/B = linked_swapper.get_teleportable_container() + var/target_A = A.drop_location() + var/target_B = B.drop_location() + + //TODO: add a sound effect or visual effect + if(do_teleport(A, target_B, channel = TELEPORT_CHANNEL_QUANTUM)) + do_teleport(B, target_A, channel = TELEPORT_CHANNEL_QUANTUM) + if(ismob(B)) + var/mob/M = B + to_chat(M, span_warning("[linked_swapper] activates, and you find yourself somewhere else.")) diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index 958877d42d..98f19a2f6e 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -28,6 +28,10 @@ mytape = new starting_tape_type(src) update_icon() +/obj/item/taperecorder/Destroy() + // QDEL_NULL(soundloop) + QDEL_NULL(mytape) + return ..() /obj/item/taperecorder/examine(mob/user) . = ..() diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index ac79b3b887..dea3bda144 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -78,7 +78,7 @@ effective or pretty fucking useless. var/ui_x = 320 var/ui_y = 335 -/obj/item/healthanalyzer/rad_laser/Initialize() +/obj/item/healthanalyzer/rad_laser/Initialize(mapload) . = ..() AddComponent(/datum/component/identification/syndicate, ID_COMPONENT_DEL_ON_IDENTIFY, ID_COMPONENT_EFFECT_NO_ACTIONS, ID_COMPONENT_IDENTIFY_WITH_DECONSTRUCTOR) @@ -208,7 +208,7 @@ effective or pretty fucking useless. actions_types = list(/datum/action/item_action/toggle) /obj/item/shadowcloak/ui_action_click(mob/user) - if(user.get_item_by_slot(SLOT_BELT) == src) + if(user.get_item_by_slot(ITEM_SLOT_BELT) == src) if(!on) Activate(usr) else @@ -216,7 +216,7 @@ effective or pretty fucking useless. return /obj/item/shadowcloak/item_action_slot_check(slot, mob/user, datum/action/A) - if(slot == SLOT_BELT) + if(slot == ITEM_SLOT_BELT) return 1 /obj/item/shadowcloak/proc/Activate(mob/living/carbon/human/user) @@ -238,11 +238,11 @@ effective or pretty fucking useless. /obj/item/shadowcloak/dropped(mob/user) ..() - if(user && user.get_item_by_slot(SLOT_BELT) != src) + if(user && user.get_item_by_slot(ITEM_SLOT_BELT) != src) Deactivate() /obj/item/shadowcloak/process() - if(user.get_item_by_slot(SLOT_BELT) != src) + if(user.get_item_by_slot(ITEM_SLOT_BELT) != src) Deactivate() return var/turf/T = get_turf(src) diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm index bbc493672f..91aad761d9 100644 --- a/code/game/objects/items/dice.dm +++ b/code/game/objects/items/dice.dm @@ -17,6 +17,11 @@ /obj/item/dice/d100 ) +/obj/item/storage/dice/ComponentInitialize() + . = ..() + var/datum/component/storage/STR = GetComponent(/datum/component/storage) + STR.can_hold = single_path_typecache_immutable(/obj/item/dice) + /obj/item/storage/dice/PopulateContents() new /obj/item/dice/d4(src) new /obj/item/dice/d6(src) @@ -45,7 +50,7 @@ var/can_be_rigged = TRUE var/rigged = FALSE -/obj/item/dice/Initialize() +/obj/item/dice/Initialize(mapload) . = ..() result = roll(sides) update_icon() @@ -84,7 +89,7 @@ desc = "A die with six sides. 6 TIMES 255 TIMES 255 TILE TOTAL EXISTENCE, SQUARE YOUR MIND OF EDUCATED STUPID: 2 DOES NOT EXIST." icon_state = "spaced6" -/obj/item/dice/d6/space/Initialize() +/obj/item/dice/d6/space/Initialize(mapload) . = ..() if(prob(10)) name = "spess cube" diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm index 90c9d78272..9366f5f935 100644 --- a/code/game/objects/items/dna_injector.dm +++ b/code/game/objects/items/dna_injector.dm @@ -1,7 +1,7 @@ /obj/item/dnainjector name = "\improper DNA injector" desc = "This injects the person with DNA." - icon = 'icons/obj/items_and_weapons.dmi' + icon = 'icons/obj/syringe.dmi' icon_state = "dnainjector" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' @@ -16,6 +16,16 @@ var/used = 0 +/obj/item/dnainjector/Initialize(mapload) + . = ..() + register_item_context() + +/obj/item/dnainjector/add_item_context(obj/item/source, list/context, mob/living/target, mob/living/user) + . = ..() + if(isliving(target) && target.has_dna() && !used) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Inject") + return CONTEXTUAL_SCREENTIP_SET + /obj/item/dnainjector/attack_paw(mob/user) return attack_hand(user) @@ -524,6 +534,12 @@ var/research = FALSE //Set to true to get expended and filled injectors for chromosomes var/filled = FALSE +/obj/item/dnainjector/activator/add_item_context(obj/item/source, list/context, atom/target, mob/living/user) + . = ..() + if(istype(target, /obj/machinery/computer/scan_consolenew) && used) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Recycle") + return CONTEXTUAL_SCREENTIP_SET + /obj/item/dnainjector/activator/inject(mob/living/carbon/M, mob/user) if(M.has_dna() && !HAS_TRAIT_NOT_FROM(M, TRAIT_RADIMMUNE,BLOODSUCKER_TRAIT) && !HAS_TRAIT(M,TRAIT_NOCLONE)) M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2)) diff --git a/code/game/objects/items/dualsaber.dm b/code/game/objects/items/dualsaber.dm index eea189c3be..dc1a9fbd49 100644 --- a/code/game/objects/items/dualsaber.dm +++ b/code/game/objects/items/dualsaber.dm @@ -21,9 +21,9 @@ light_color = "#00ff00"//green attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 70) resistance_flags = FIRE_PROOF - wound_bonus = -110 + wound_bonus = -40 bare_wound_bonus = 20 block_parry_data = /datum/block_parry_data/dual_esword block_chance = 60 @@ -84,7 +84,7 @@ block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_DEFLECT . |= BLOCK_SHOULD_REDIRECT -/obj/item/dualsaber/Initialize() +/obj/item/dualsaber/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield) RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield) @@ -94,7 +94,7 @@ AddComponent(/datum/component/two_handed, force_unwielded=3, force_wielded=34, \ wieldsound='sound/weapons/saberon.ogg', unwieldsound='sound/weapons/saberoff.ogg') -/obj/item/dualsaber/Initialize() +/obj/item/dualsaber/Initialize(mapload) . = ..() if(LAZYLEN(possible_colors)) saber_color = pick(possible_colors) @@ -133,7 +133,7 @@ total_mass = initial(total_mass) wielded = FALSE hitsound = "swing_hit" - slowdown_wielded -= slowdown_wielded + slowdown -= slowdown_wielded STOP_PROCESSING(SSobj, src) set_light(0) RemoveElement(/datum/element/sword_point) @@ -278,6 +278,7 @@ desc = "A supermassive weapon envisioned to cleave the very fabric of space and time itself in twain, the hypereutactic blade dynamically flash-forges a hypereutactic crystaline nanostructure capable of passing through most known forms of matter like a hot knife through butter." force = 7 hitsound_on = 'sound/weapons/nebhit.ogg' + wound_bonus = -20 armour_penetration = 60 light_color = "#37FFF7" rainbow_colors = list("#FF0000", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF","#FF00FF", "#3399ff", "#ff9900", "#fb008b", "#9800ff", "#00ffa3", "#ccff00") diff --git a/code/game/objects/items/dyekit.dm b/code/game/objects/items/dyekit.dm new file mode 100644 index 0000000000..43a05c7939 --- /dev/null +++ b/code/game/objects/items/dyekit.dm @@ -0,0 +1,40 @@ +/obj/item/dyespray + name = "hair dye spray" + desc = "A spray to dye your hair any gradients you'd like." + icon = 'icons/obj/dyespray.dmi' + icon_state = "dyespray" + +/obj/item/dyespray/attack_self(mob/user) + dye(user) + +/obj/item/dyespray/pre_attack(atom/target, mob/living/user, params) + dye(target) + return ..() + +/** + * Applies a gradient and a gradient color to a mob. + * + * Arguments: + * * target - The mob who we will apply the gradient and gradient color to. + */ + +/obj/item/dyespray/proc/dye(mob/target) + if(!ishuman(target)) + return + var/mob/living/carbon/human/human_target = target + + var/new_grad_style = input(usr, "Choose a color pattern:", "Character Preference") as null|anything in GLOB.hair_gradients_list + if(!new_grad_style) + return + + var/new_grad_color = input(usr, "Choose a secondary hair color:", "Character Preference","#"+human_target.grad_color) as color|null + if(!new_grad_color) + return + + human_target.grad_style = new_grad_style + human_target.grad_color = sanitize_hexcolor(new_grad_color) + to_chat(human_target, "You start applying the hair dye...") + if(!do_after(usr, 30, target = human_target)) + return + playsound(src, 'sound/effects/spray.ogg', 5, TRUE, 5) + human_target.update_hair() diff --git a/code/game/objects/items/eightball.dm b/code/game/objects/items/eightball.dm index 39c8143ee9..046f7ea1ab 100644 --- a/code/game/objects/items/eightball.dm +++ b/code/game/objects/items/eightball.dm @@ -62,7 +62,7 @@ shaking = TRUE start_shaking(user) - if(do_after(user, shake_time, needhand=TRUE, target=user, progress=TRUE)) + if(do_after(user, shake_time)) var/answer = get_answer() say(answer) diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index 301b8d4155..372d1a1733 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -53,7 +53,7 @@ power = 7 cooling_power = 3 -/obj/item/extinguisher/Initialize() +/obj/item/extinguisher/Initialize(mapload) . = ..() create_reagents(max_water, AMOUNT_VISIBLE) reagents.add_reagent(chem, max_water) diff --git a/code/game/objects/items/fireaxe.dm b/code/game/objects/items/fireaxe.dm index 6fb7b89262..c865eedf6a 100644 --- a/code/game/objects/items/fireaxe.dm +++ b/code/game/objects/items/fireaxe.dm @@ -15,13 +15,13 @@ hitsound = 'sound/weapons/bladeslice.ogg' sharpness = SHARP_EDGED max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 30) resistance_flags = FIRE_PROOF wound_bonus = -15 bare_wound_bonus = 20 var/wielded = FALSE // track wielded status on item -/obj/item/fireaxe/Initialize() +/obj/item/fireaxe/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield) RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield) @@ -52,10 +52,10 @@ return if(istype(A, /obj/structure/window)) //destroys windows and grilles in one hit (or more if it has a ton of health like plasmaglass) var/obj/structure/window/W = A - W.take_damage(200, BRUTE, "melee", 0) + W.take_damage(200, BRUTE, MELEE, 0) else if(istype(A, /obj/structure/grille)) var/obj/structure/grille/G = A - G.take_damage(40, BRUTE, "melee", 0) + G.take_damage(40, BRUTE, MELEE, 0) /* * Bone Axe diff --git a/code/game/objects/items/fluff.dm b/code/game/objects/items/fluff.dm index 7105e57c30..1077aab87e 100644 --- a/code/game/objects/items/fluff.dm +++ b/code/game/objects/items/fluff.dm @@ -6,7 +6,7 @@ // 1) Tennis balls, lines 39 - 99 // 2) Chew bones, lines 101 - 138 // 3) Frisbee, lines 140 - 166 -*/ +*/ /obj/item/toy/fluff name = "Fluff Item" @@ -88,7 +88,7 @@ poly_states = 0 actions_types = list(/datum/action/item_action/squeeze) -/obj/item/toy/fluff/tennis_poly/tri/squeak/Initialize() +/obj/item/toy/fluff/tennis_poly/tri/squeak/Initialize(mapload) . = ..() AddComponent(/datum/component/squeak) @@ -124,7 +124,7 @@ name = "polychromic bone" desc = "A polychromic chew bone. Makes a small squeak when squeezed." -/obj/item/toy/fluff/bone_poly/squeak/Initialize() +/obj/item/toy/fluff/bone_poly/squeak/Initialize(mapload) . = ..() AddComponent(/datum/component/squeak) diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm index 6ab12b7e39..f83d01f4ef 100644 --- a/code/game/objects/items/granters.dm +++ b/code/game/objects/items/granters.dm @@ -11,7 +11,7 @@ /obj/item/book/granter/proc/turn_page(mob/user) playsound(user, pick('sound/effects/pageturn1.ogg','sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg'), 30, 1) - if(do_after(user,50, TRUE, user)) + if(do_after(user, 5 SECONDS, src)) if(remarks.len) to_chat(user, "[pick(remarks)]") else @@ -53,7 +53,7 @@ on_reading_stopped() reading = FALSE return - if(do_after(user,50, TRUE, user)) + if(do_after(user, 5 SECONDS, src)) on_reading_finished(user) reading = FALSE return TRUE @@ -336,7 +336,7 @@ var/obj/item/clothing/magichead = new /obj/item/clothing/mask/horsehead/cursed(user.drop_location()) if(!user.dropItemToGround(user.wear_mask)) qdel(user.wear_mask) - user.equip_to_slot_if_possible(magichead, SLOT_WEAR_MASK, TRUE, TRUE) + user.equip_to_slot_if_possible(magichead, ITEM_SLOT_MASK, TRUE, TRUE) qdel(src) else to_chat(user,"I say thee neigh") //It still lives here @@ -368,7 +368,7 @@ /obj/item/book/granter/spell/random icon_state = "random_book" -/obj/item/book/granter/spell/random/Initialize() +/obj/item/book/granter/spell/random/Initialize(mapload) . = ..() var/static/banned_spells = list(/obj/item/book/granter/spell/mimery_blockade, /obj/item/book/granter/spell/mimery_guns) var/real_type = pick(subtypesof(/obj/item/book/granter/spell) - banned_spells) @@ -535,13 +535,13 @@ oneuse = FALSE remarks = list("Looks like these would sell much better in a plasma fire...", "Using glass bowls rather then cones?", "Mixing soda and ice-cream?", "Tall glasses with of liquids and solids...", "Just add a bit of icecream and cherry on top?") -/obj/item/book/granter/crafting_recipe/bone_bow //Bow crafting for non-ashwalkers +/*/obj/item/book/granter/crafting_recipe/bone_bow //Bow crafting for non-ashwalkers name = "bowyery sandstone slab" // this is an actual word desc = "A sandstone slab with inscriptions describing the Ash Walkers of Lavaland's bowyery." crafting_recipe_types = list(/datum/crafting_recipe/bone_arrow, /datum/crafting_recipe/bone_bow, /datum/crafting_recipe/ashen_arrow, /datum/crafting_recipe/quiver, /datum/crafting_recipe/bow_tablet) icon_state = "stone_tablet" oneuse = FALSE - remarks = list("Sticking burning arrows into the sand makes them stronger...", "Breaking the bone apart to get shards, not sharpening the bone...", "Sinew is just like rope...") + remarks = list("Sticking burning arrows into the sand makes them stronger...", "Breaking the bone apart to get shards, not sharpening the bone...", "Sinew is just like rope...")*/ /obj/item/book/granter/crafting_recipe/under_the_oven //Illegal cook book name = "Under The Oven" diff --git a/code/game/objects/items/grenades/chem_grenade.dm b/code/game/objects/items/grenades/chem_grenade.dm index b67b7ae587..3d35f7eb24 100644 --- a/code/game/objects/items/grenades/chem_grenade.dm +++ b/code/game/objects/items/grenades/chem_grenade.dm @@ -20,7 +20,7 @@ var/no_splash = FALSE //If the grenade deletes even if it has no reagents to splash with. Used for slime core reactions. var/casedesc = "This basic model accepts both beakers and bottles. It heats contents by 10°K upon ignition." // Appears when examining empty casings. -/obj/item/grenade/chem_grenade/Initialize() +/obj/item/grenade/chem_grenade/Initialize(mapload) . = ..() create_reagents(1000) stage_change() // If no argument is set, it will change the stage to the current stage, useful for stock grenades that start READY. @@ -59,9 +59,6 @@ I.play_tool_sound(src, 25) else to_chat(user, "You need to add at least one beaker before locking the [initial(name)] assembly!") - else if(stage == READY && !nadeassembly) - det_time = det_time == 50 ? 30 : 50 //toggle between 30 and 50 - to_chat(user, "You modify the time delay. It's set for [DisplayTimeText(det_time)].") else if(stage == EMPTY) to_chat(user, "You need to add an activation mechanism!") @@ -329,7 +326,7 @@ desc = "Used for emergency sealing of hull breaches." stage = READY -/obj/item/grenade/chem_grenade/metalfoam/Initialize() +/obj/item/grenade/chem_grenade/metalfoam/Initialize(mapload) . = ..() var/obj/item/reagent_containers/glass/beaker/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/B2 = new(src) @@ -347,7 +344,7 @@ desc = "Used for emergency sealing of hull breaches, while keeping areas accessible." stage = READY -/obj/item/grenade/chem_grenade/smart_metal_foam/Initialize() +/obj/item/grenade/chem_grenade/smart_metal_foam/Initialize(mapload) . = ..() var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/B2 = new(src) @@ -365,7 +362,7 @@ desc = "Used for clearing rooms of living things." stage = READY -/obj/item/grenade/chem_grenade/incendiary/Initialize() +/obj/item/grenade/chem_grenade/incendiary/Initialize(mapload) . = ..() var/obj/item/reagent_containers/glass/beaker/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/B2 = new(src) @@ -383,7 +380,7 @@ desc = "Used for purging large areas of invasive plant species. Contents under pressure. Do not directly inhale contents." stage = READY -/obj/item/grenade/chem_grenade/antiweed/Initialize() +/obj/item/grenade/chem_grenade/antiweed/Initialize(mapload) . = ..() var/obj/item/reagent_containers/glass/beaker/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/B2 = new(src) @@ -402,7 +399,7 @@ desc = "BLAM!-brand foaming space cleaner. In a special applicator for rapid cleaning of wide areas." stage = READY -/obj/item/grenade/chem_grenade/cleaner/Initialize() +/obj/item/grenade/chem_grenade/cleaner/Initialize(mapload) . = ..() var/obj/item/reagent_containers/glass/beaker/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/B2 = new(src) @@ -420,7 +417,7 @@ desc = "Waffle Co.-brand foaming space cleaner. In a special applicator for rapid cleaning of wide areas." stage = READY -/obj/item/grenade/chem_grenade/ez_clean/Initialize() +/obj/item/grenade/chem_grenade/ez_clean/Initialize(mapload) . = ..() var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src) @@ -439,7 +436,7 @@ desc = "Used for nonlethal riot control. Contents under pressure. Do not directly inhale contents." stage = READY -/obj/item/grenade/chem_grenade/teargas/Initialize() +/obj/item/grenade/chem_grenade/teargas/Initialize(mapload) . = ..() var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src) @@ -458,7 +455,7 @@ desc = "Used for melting armoured opponents." stage = READY -/obj/item/grenade/chem_grenade/facid/Initialize() +/obj/item/grenade/chem_grenade/facid/Initialize(mapload) . = ..() var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src) @@ -478,7 +475,7 @@ desc = "Used for wide scale painting projects." stage = READY -/obj/item/grenade/chem_grenade/colorful/Initialize() +/obj/item/grenade/chem_grenade/colorful/Initialize(mapload) . = ..() var/obj/item/reagent_containers/glass/beaker/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/B2 = new(src) @@ -497,7 +494,7 @@ stage = READY var/glitter_type = /datum/reagent/glitter -/obj/item/grenade/chem_grenade/glitter/Initialize() +/obj/item/grenade/chem_grenade/glitter/Initialize(mapload) . = ..() var/obj/item/reagent_containers/glass/beaker/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/B2 = new(src) @@ -530,7 +527,7 @@ desc = "BURN!-brand foaming clf3. In a special applicator for rapid purging of wide areas." stage = READY -/obj/item/grenade/chem_grenade/clf3/Initialize() +/obj/item/grenade/chem_grenade/clf3/Initialize(mapload) . = ..() var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src) @@ -548,7 +545,7 @@ desc = "Tiger Cooperative chemical foam grenade. Causes temporary irration, blindness, confusion, mutism, and mutations to carbon based life forms. Contains additional spore toxin." stage = READY -/obj/item/grenade/chem_grenade/bioterrorfoam/Initialize() +/obj/item/grenade/chem_grenade/bioterrorfoam/Initialize(mapload) . = ..() var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src) @@ -568,7 +565,7 @@ desc = "WARNING: GRENADE WILL RELEASE DEADLY SPORES CONTAINING ACTIVE AGENTS. SEAL SUIT AND AIRFLOW BEFORE USE." stage = READY -/obj/item/grenade/chem_grenade/tuberculosis/Initialize() +/obj/item/grenade/chem_grenade/tuberculosis/Initialize(mapload) . = ..() var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src) @@ -588,7 +585,7 @@ icon_state = "holy_grenade" stage = READY -/obj/item/grenade/chem_grenade/holy/Initialize() +/obj/item/grenade/chem_grenade/holy/Initialize(mapload) . = ..() var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src) var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src) diff --git a/code/game/objects/items/grenades/ghettobomb.dm b/code/game/objects/items/grenades/ghettobomb.dm index 3553d79faf..f379bf6493 100644 --- a/code/game/objects/items/grenades/ghettobomb.dm +++ b/code/game/objects/items/grenades/ghettobomb.dm @@ -19,7 +19,7 @@ var/range = 3 var/list/times -/obj/item/grenade/iedcasing/Initialize() +/obj/item/grenade/iedcasing/Initialize(mapload) . = ..() add_overlay("improvised_grenade_filled") add_overlay("improvised_grenade_wired") diff --git a/code/game/objects/items/grenades/grenade.dm b/code/game/objects/items/grenades/grenade.dm index 7a6157bf65..fb98e86ae1 100644 --- a/code/game/objects/items/grenades/grenade.dm +++ b/code/game/objects/items/grenades/grenade.dm @@ -135,16 +135,16 @@ /obj/item/grenade/tool_act(mob/living/user, obj/item/I, tool_behaviour) if(tool_behaviour == TOOL_SCREWDRIVER) switch(det_time) - if ("1") - det_time = 10 + if(1) + det_time = 1 SECONDS to_chat(user, "You set the [name] for 1 second detonation time.") - if ("10") - det_time = 30 + if(1 SECONDS) + det_time = 3 SECONDS to_chat(user, "You set the [name] for 3 second detonation time.") - if ("30") - det_time = 50 + if(3 SECONDS) + det_time = 5 SECONDS to_chat(user, "You set the [name] for 5 second detonation time.") - if ("50") + if(5 SECONDS) det_time = 1 to_chat(user, "You set the [name] for instant detonation.") add_fingerprint(user) diff --git a/code/game/objects/items/grenades/plastic.dm b/code/game/objects/items/grenades/plastic.dm index 23fe128fa8..9c5f1475fd 100644 --- a/code/game/objects/items/grenades/plastic.dm +++ b/code/game/objects/items/grenades/plastic.dm @@ -21,7 +21,7 @@ var/full_damage_on_mobs = FALSE var/can_gib_mobs = FALSE -/obj/item/grenade/plastic/Initialize() +/obj/item/grenade/plastic/Initialize(mapload) . = ..() plastic_overlay = mutable_appearance(icon, "[item_state]2", HIGH_OBJ_LAYER) diff --git a/code/game/objects/items/grenades/smokebomb.dm b/code/game/objects/items/grenades/smokebomb.dm index 1b856fc013..501f019027 100644 --- a/code/game/objects/items/grenades/smokebomb.dm +++ b/code/game/objects/items/grenades/smokebomb.dm @@ -27,6 +27,6 @@ for(var/obj/structure/blob/B in view(8,src)) var/damage = round(30/(get_dist(B,src)+1)) - B.take_damage(damage, BURN, "melee", 0) + B.take_damage(damage, BURN, MELEE, 0) sleep(80) qdel(src) diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index 60538b479b..f868dfd3b9 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -40,7 +40,7 @@ throw_range = 5 custom_materials = list(/datum/material/iron=500) breakouttime = 600 //Deciseconds = 60s = 1 minute - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/cuffsound = 'sound/weapons/handcuffs.ogg' var/trashtype = null //for disposable cuffs @@ -122,9 +122,24 @@ breakouttime = 300 //Deciseconds = 30s cuffsound = 'sound/weapons/cablecuff.ogg' +/obj/item/restraints/handcuffs/cable/Initialize(mapload) + . = ..() + + var/static/list/hovering_item_typechecks = list( + /obj/item/stack/rods = list( + SCREENTIP_CONTEXT_LMB = list(INTENT_ANY = "Craft wired rod"), + ), + + /obj/item/stack/sheet/metal = list( + SCREENTIP_CONTEXT_LMB = list(INTENT_ANY = "Craft bola"), + ), + ) + + AddElement(/datum/element/contextual_screentip_item_typechecks, hovering_item_typechecks) + /obj/item/restraints/handcuffs/cable/attack_self(mob/user) to_chat(user, "You start unwinding the cable restraints back into coil") - if(!do_after(user, 25, TRUE, user)) + if(!do_after(user, 25, user)) return qdel(src) var/obj/item/stack/cable_coil/coil = new(get_turf(user)) @@ -260,7 +275,7 @@ var/armed = FALSE var/trap_damage = 20 -/obj/item/restraints/legcuffs/beartrap/Initialize() +/obj/item/restraints/legcuffs/beartrap/Initialize(mapload) . = ..() icon_state = "[initial(icon_state)][armed]" diff --git a/code/game/objects/items/his_grace.dm b/code/game/objects/items/his_grace.dm index eafa03ca61..b339b08bd9 100644 --- a/code/game/objects/items/his_grace.dm +++ b/code/game/objects/items/his_grace.dm @@ -25,7 +25,7 @@ var/victims_needed = 10 //Citadel change from 25 to 10 var/ascend_bonus = 15 -/obj/item/his_grace/Initialize() +/obj/item/his_grace/Initialize(mapload) . = ..() START_PROCESSING(SSprocessing, src) GLOB.poi_list += src diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index 44121d64d1..9fae1496fd 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -5,7 +5,7 @@ desc = "Deus Vult." icon_state = "knight_templar" item_state = "knight_templar" - armor = list("melee" = 41, "bullet" = 15, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 2, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 41, BULLET = 15, LASER = 5,ENERGY = 5, BOMB = 5, BIO = 2, RAD = 0, FIRE = 0, ACID = 50) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH strip_delay = 80 @@ -229,7 +229,7 @@ var/chaplain_spawnable = TRUE total_mass = TOTAL_MASS_MEDIEVAL_WEAPON -/obj/item/nullrod/Initialize() +/obj/item/nullrod/Initialize(mapload) . = ..() AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE) @@ -314,7 +314,7 @@ attack_verb = list("punched", "cross countered", "pummeled") total_mass = TOTAL_MASS_HAND_REPLACEMENT -/obj/item/nullrod/godhand/Initialize() +/obj/item/nullrod/godhand/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) @@ -455,7 +455,7 @@ sharpness = SHARP_EDGED attack_verb = list("chopped", "sliced", "cut", "reaped") -/obj/item/nullrod/scythe/Initialize() +/obj/item/nullrod/scythe/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 70, 110) //the harvest gives a high bonus chance @@ -582,7 +582,7 @@ tool_behaviour = TOOL_SAW toolspeed = 2 -/obj/item/nullrod/chainsaw/Initialize() +/obj/item/nullrod/chainsaw/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) AddComponent(/datum/component/butchering, 30, 100, 0, hitsound) @@ -662,7 +662,7 @@ bare_wound_bonus = 25 total_mass = TOTAL_MASS_HAND_REPLACEMENT -/obj/item/nullrod/armblade/Initialize() +/obj/item/nullrod/armblade/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) AddComponent(/datum/component/butchering, 80, 70) @@ -769,12 +769,33 @@ STOP_PROCESSING(SSobj, src) . = ..() +/obj/item/nullrod/tribal_knife/pickup(mob/user) + . = ..() + reroll() + /obj/item/nullrod/tribal_knife/process() - slowdown = rand(-2, 2) + reroll() + +/obj/item/nullrod/tribal_knife/proc/reroll() if(iscarbon(loc)) var/mob/living/carbon/wielder = loc if(wielder.is_holding(src)) - wielder.update_equipment_speed_mods() + var/current_tiles = 10 / max(wielder.cached_multiplicative_slowdown, world.tick_lag) + var/datum/movespeed_modifier/M = wielder.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/item/arrhythmic_knife, update = FALSE, multiplicative_slowdown = pick(-10, -10, 0, (current_tiles - 2) / 10, (current_tiles - 4) / 10)) + M.max_tiles_per_second_boost = pick(3, 6) + wielder.update_movespeed() // update movespeed manually + +/obj/item/nullrod/tribal_knife/dropped(mob/user) + user.remove_movespeed_modifier(/datum/movespeed_modifier/item/arrhythmic_knife) + return ..() + +/datum/movespeed_modifier/item/arrhythmic_knife + variable = TRUE + flags = IGNORE_NOSLOW + movetypes = ~FLOATING + priority = 750 + absolute_max_tiles_per_second = 20 + max_tiles_per_second_boost = 6 /obj/item/nullrod/pitchfork icon_state = "pitchfork0" @@ -810,7 +831,7 @@ var/praying = FALSE var/deity_name = "Coderbus" //This is the default, hopefully won't actually appear if the religion subsystem is running properly -/obj/item/nullrod/rosary/Initialize() +/obj/item/nullrod/rosary/Initialize(mapload) .=..() if(GLOB.deity) deity_name = GLOB.deity diff --git a/code/game/objects/items/implants/implant_chem.dm b/code/game/objects/items/implants/implant_chem.dm index d148cbbb3c..5f0b4f3fc3 100644 --- a/code/game/objects/items/implants/implant_chem.dm +++ b/code/game/objects/items/implants/implant_chem.dm @@ -21,7 +21,7 @@ Integrity: Implant will last so long as the subject is alive."} return dat -/obj/item/implant/chem/Initialize() +/obj/item/implant/chem/Initialize(mapload) . = ..() create_reagents(50, OPENCONTAINER) GLOB.tracked_chem_implants += src diff --git a/code/game/objects/items/implants/implant_mindshield.dm b/code/game/objects/items/implants/implant_mindshield.dm index 52f9f3b9a4..395c0c4ce0 100644 --- a/code/game/objects/items/implants/implant_mindshield.dm +++ b/code/game/objects/items/implants/implant_mindshield.dm @@ -29,7 +29,7 @@ if(target.mind.has_antag_datum(ANTAG_DATUM_VASSAL)) SSticker.mode.remove_vassal(target.mind) - if(target.mind.has_antag_datum(/datum/antagonist/rev/head) || target.mind.unconvertable || target.mind.has_antag_datum(/datum/antagonist/gang/boss)) + if(target.mind.has_antag_datum(/datum/antagonist/rev/head) || (target.mind.unconvertable)) if(!silent) target.visible_message("[target] seems to resist the implant!", "You feel something interfering with your mental conditioning, but you resist it!") var/obj/item/implanter/I = loc diff --git a/code/game/objects/items/implants/implant_stealth.dm b/code/game/objects/items/implants/implant_stealth.dm index eb58d76d1b..219e4fdd68 100644 --- a/code/game/objects/items/implants/implant_stealth.dm +++ b/code/game/objects/items/implants/implant_stealth.dm @@ -16,7 +16,7 @@ animate(src, , alpha = 0, time = 5) START_PROCESSING(SSobj, src) -/obj/structure/closet/cardboard/agent/Initialize() +/obj/structure/closet/cardboard/agent/Initialize(mapload) . = ..() go_invisible() diff --git a/code/game/objects/items/implants/implant_track.dm b/code/game/objects/items/implants/implant_track.dm index 2fa0244831..b2678baddf 100644 --- a/code/game/objects/items/implants/implant_track.dm +++ b/code/game/objects/items/implants/implant_track.dm @@ -11,11 +11,11 @@ var/lifespan = 5 MINUTES //how many deciseconds does the implant last? allow_teleport = FALSE -/obj/item/implant/tracking/c38/Initialize() +/obj/item/implant/tracking/c38/Initialize(mapload) . = ..() QDEL_IN(src, lifespan) -/obj/item/implant/tracking/Initialize() +/obj/item/implant/tracking/Initialize(mapload) . = ..() GLOB.tracked_implants += src diff --git a/code/game/objects/items/implants/implant_uplink.dm b/code/game/objects/items/implants/implant_uplink.dm index 0cac8f838a..bd861013dd 100644 --- a/code/game/objects/items/implants/implant_uplink.dm +++ b/code/game/objects/items/implants/implant_uplink.dm @@ -20,4 +20,7 @@ imp_type = /obj/item/implant/uplink/precharged /obj/item/implant/uplink/precharged - starting_tc = 10 + starting_tc = TELECRYSTALS_PRELOADED_IMPLANT + +/obj/item/implant/uplink/starting + starting_tc = TELECRYSTALS_DEFAULT - UPLINK_IMPLANT_TELECRYSTAL_COST diff --git a/code/game/objects/items/implants/implantcase.dm b/code/game/objects/items/implants/implantcase.dm index 8573324b56..b2980d84d3 100644 --- a/code/game/objects/items/implants/implantcase.dm +++ b/code/game/objects/items/implants/implantcase.dm @@ -1,7 +1,7 @@ /obj/item/implantcase name = "implant case" desc = "A glass case containing an implant." - icon = 'icons/obj/items_and_weapons.dmi' + icon = 'icons/obj/syringe.dmi' icon_state = "implantcase-0" item_state = "implantcase" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' diff --git a/code/game/objects/items/implants/implantchair.dm b/code/game/objects/items/implants/implantchair.dm index 7b05cf302e..8777a9f5e0 100644 --- a/code/game/objects/items/implants/implantchair.dm +++ b/code/game/objects/items/implants/implantchair.dm @@ -21,7 +21,7 @@ var/message_cooldown var/breakout_time = 600 -/obj/machinery/implantchair/Initialize() +/obj/machinery/implantchair/Initialize(mapload) . = ..() open_machine() update_icon() @@ -189,5 +189,7 @@ return FALSE brainwash(C, objective) message_admins("[ADMIN_LOOKUPFLW(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.") + user.log_message("has brainwashed [key_name(C)] with the objective '[objective]' using \the [src]", LOG_ATTACK) + C.log_message("has been brainwashed with the objective '[objective]' by [key_name(user)] using \the [src]", LOG_VICTIM, log_globally = FALSE) log_game("[key_name(user)] brainwashed [key_name(C)] with objective '[objective]'.") return TRUE diff --git a/code/game/objects/items/implants/implanter.dm b/code/game/objects/items/implants/implanter.dm index 578d8595dd..cfeb001112 100644 --- a/code/game/objects/items/implants/implanter.dm +++ b/code/game/objects/items/implants/implanter.dm @@ -1,7 +1,7 @@ /obj/item/implanter name = "implanter" desc = "A sterile automatic implant injector." - icon = 'icons/obj/items_and_weapons.dmi' + icon = 'icons/obj/syringe.dmi' icon_state = "implanter0" item_state = "syringe_0" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm index ddcd35f834..f7a614050e 100644 --- a/code/game/objects/items/inducer.dm +++ b/code/game/objects/items/inducer.dm @@ -14,7 +14,7 @@ var/recharging = FALSE var/gun_charger = FALSE -/obj/item/inducer/Initialize() +/obj/item/inducer/Initialize(mapload) . = ..() if(!cell && cell_type) cell = new cell_type @@ -180,7 +180,7 @@ powertransfer = 500 opened = TRUE -/obj/item/inducer/sci/Initialize() +/obj/item/inducer/sci/Initialize(mapload) . = ..() update_icon() @@ -188,7 +188,7 @@ icon_state = "inducer-combat" item_state = "inducer-combat" w_class = WEIGHT_CLASS_BULKY - slot_flags = SLOT_BELT + slot_flags = ITEM_SLOT_BELT desc = "A tool for inductively charging internal power cells. This one has been modified and upgraded to be able to charge into guns as well as normal electronics." cell_type = /obj/item/stock_parts/cell/hyper powertransfer = 1300 @@ -199,11 +199,11 @@ cell_type = null opened = TRUE -/obj/item/inducer/sci/combat/dry/Initialize() //Just in case +/obj/item/inducer/sci/combat/dry/Initialize(mapload) //Just in case . = ..() update_icon() -/obj/item/inducer/sci/combat/Initialize() +/obj/item/inducer/sci/combat/Initialize(mapload) . = ..() update_icon() diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm index 2e7cef2c9f..d53a12fd27 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -27,7 +27,7 @@ flags_1 = CONDUCT_1 attack_verb = list("attacked", "stabbed", "poked") hitsound = 'sound/weapons/bladeslice.ogg' - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) sharpness = SHARP_POINTY var/datum/reagent/forkload //used to eat omelette @@ -78,13 +78,13 @@ custom_materials = list(/datum/material/iron=12000) attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") sharpness = SHARP_POINTY - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/bayonet = FALSE //Can this be attached to a gun? wound_bonus = -5 bare_wound_bonus = 10 custom_price = PRICE_NORMAL -/obj/item/kitchen/knife/Initialize() +/obj/item/kitchen/knife/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 80 - force, 100, force - 10) //bonus chance increases depending on force @@ -114,13 +114,13 @@ custom_materials = list(/datum/material/iron=12000) attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") sharpness = SHARP_POINTY - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/bayonet = FALSE //Can this be attached to a gun? wound_bonus = -5 bare_wound_bonus = 10 custom_price = PRICE_NORMAL -/obj/item/kitchen/efink/Initialize() +/obj/item/kitchen/efink/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 80 - force, 100, force - 10) //bonus chance increases depending on force @@ -209,7 +209,7 @@ var/light_on = FALSE var/brightness_on = 7 -/obj/item/kitchen/knife/combat/survival/knuckledagger/Initialize() +/obj/item/kitchen/knife/combat/survival/knuckledagger/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 30, 130, 20) // it's good for butchering stuff @@ -255,18 +255,31 @@ icon_state = "knife" desc = "A cyborg-mounted plasteel knife. Extremely sharp and durable." -/obj/item/kitchen/knife/carrotshiv +/obj/item/kitchen/knife/shiv + name = "glass shiv" + icon = 'icons/obj/shards.dmi' + icon_state = "shiv" + item_state = "shiv" + lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' + desc = "A makeshift glass shiv." + force = 8 + throwforce = 12//fuck git + attack_verb = list("shanked", "shivved") + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) + custom_materials = list(/datum/material/glass=400) + +/obj/item/kitchen/knife/shiv/carrot name = "carrot shiv" icon_state = "carrotshiv" item_state = "carrotshiv" - lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' + icon = 'icons/obj/kitchen.dmi' desc = "Unlike other carrots, you should probably keep this far away from your eyes." - force = 8 - throwforce = 12//fuck git custom_materials = null - attack_verb = list("shanked", "shivved") - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + +/obj/item/kitchen/knife/shiv/carrot/suicide_act(mob/living/carbon/user) + user.visible_message("[user] forcefully drives \the [src] into [user.p_their()] eye! It looks like [user.p_theyre()] trying to commit suicide!") + return BRUTELOSS /obj/item/kitchen/rollingpin name = "rolling pin" @@ -309,6 +322,6 @@ desc = "A knife used to cleanly butcher. Its razor-sharp edge has been honed for butchering, but has been poorly maintained over the years." attack_verb = list("cleaved", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") -/obj/item/kitchen/knife/scimitar/Initialize() +/obj/item/kitchen/knife/scimitar/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 90 - force, 100, force - 60) //bonus chance increases depending on force diff --git a/code/game/objects/items/latexballoon.dm b/code/game/objects/items/latexballoon.dm index b2f8b4bee2..64a7973f11 100644 --- a/code/game/objects/items/latexballoon.dm +++ b/code/game/objects/items/latexballoon.dm @@ -31,7 +31,7 @@ user.update_inv_hands() loc.assume_air(air_contents) -/obj/item/latexballon/ex_act(severity, target) +/obj/item/latexballon/ex_act(severity, target, origin) burst() switch(severity) if (1) diff --git a/code/game/objects/items/manuals.dm b/code/game/objects/items/manuals.dm index 05b7ef4802..3bd13b3905 100644 --- a/code/game/objects/items/manuals.dm +++ b/code/game/objects/items/manuals.dm @@ -336,7 +336,7 @@ title = "Outdated Chemistry Textbook" page_link = "Guide_to_chemistry" -/obj/item/book/manual/wiki/chemistry/Initialize() +/obj/item/book/manual/wiki/chemistry/Initialize(mapload) . = ..() new /obj/item/book/manual/wiki/cit/chemistry(loc) new /obj/item/book/manual/wiki/cit/chem_recipies(loc) @@ -494,6 +494,38 @@ title = "Toxins or: How I Learned to Stop Worrying and Love the Maxcap" page_link = "Guide_to_toxins" +/obj/item/book/manual/wiki/rbmk + name = "\improper Haynes nuclear reactor owner's manual" + icon_state = "bookEngineering2" + author = "CogWerk Engineering Reactor Design Department" + title = "Haynes nuclear reactor owner's manual" + page_link = "Guide_to_the_Nuclear_Reactor" + +/obj/item/book/manual/wiki/rbmk/initialize_wikibook() + var/wikiurl = "https://nsv.beestation13.com/wiki" + if(wikiurl) + dat = {" + + + + + + +

    You start skimming through the manual...

    + + + + "} + /obj/item/book/manual/wiki/toxins/suicide_act(mob/user) var/mob/living/carbon/human/H = user user.visible_message("[user] starts dancing to the Rhumba Beat! It looks like [user.p_theyre()] trying to commit suicide!") diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm index 1be570b62b..b389efe542 100644 --- a/code/game/objects/items/melee/energy.dm +++ b/code/game/objects/items/melee/energy.dm @@ -2,13 +2,13 @@ hitsound_on = 'sound/weapons/blade1.ogg' heat = 3500 max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 30) resistance_flags = FIRE_PROOF var/brightness_on = 3 var/sword_color total_mass = 0.4 //Survival flashlights typically weigh around 5 ounces. -/obj/item/melee/transforming/energy/Initialize() +/obj/item/melee/transforming/energy/Initialize(mapload) . = ..() total_mass_on = (total_mass_on ? total_mass_on : (w_class_on * 0.75)) if(active) @@ -184,7 +184,7 @@ hitcost = 75 //Costs more than a standard cyborg esword w_class = WEIGHT_CLASS_NORMAL sharpness = SHARP_EDGED - light_color = "#40ceff" + light_color = LIGHT_COLOR_RED tool_behaviour = TOOL_SAW toolspeed = 0.7 @@ -193,34 +193,29 @@ /obj/item/melee/transforming/energy/sword/saber possible_colors = list("red" = LIGHT_COLOR_RED, "blue" = LIGHT_COLOR_LIGHT_CYAN, "green" = LIGHT_COLOR_GREEN, "purple" = LIGHT_COLOR_LAVENDER) - unique_reskin = list("Sword" = "sword0", "saber" = "esaber0") + unique_reskin = list( + "Sword" = list("icon_state" = "sword0"), + "Saber" = list("icon_state" = "esaber0") + ) var/hacked = FALSE - var/saber = FALSE /obj/item/melee/transforming/energy/sword/saber/transform_weapon(mob/living/user, supress_message_text) . = ..() if(.) - if(active) - if(sword_color) - if(saber) - icon_state = "esaber[sword_color]" - else - icon_state = "sword[sword_color]" - else - if(saber) - icon_state = "esaber0" + switch(current_skin) + if("Saber") + icon_state = "esaber[active ? sword_color : "0"]" + // No skin else - icon_state = "sword0" + icon_state = "sword[active ? sword_color : "0"]" /obj/item/melee/transforming/energy/sword/saber/reskin_obj(mob/M) . = ..() - if(icon_state == "esaber0") - saber = TRUE - if(active) - if(saber) - icon_state = "esaber[sword_color]" - else - icon_state = "sword[sword_color]" + switch(current_skin) + if("Sword") + icon_state = "sword[active ? sword_color : "0"]" + if("Saber") + icon_state = "esaber[active ? sword_color : "0"]" /obj/item/melee/transforming/energy/sword/saber/set_sword_color(var/color_forced) if(color_forced) // wow i really do not like this at fucking all holy SHIT @@ -331,7 +326,7 @@ sharpness = SHARP_EDGED //Most of the other special functions are handled in their own files. aka special snowflake code so kewl -/obj/item/melee/transforming/energy/blade/Initialize() +/obj/item/melee/transforming/energy/blade/Initialize(mapload) . = ..() spark_system = new /datum/effect_system/spark_spread() spark_system.set_up(5, 0, src) @@ -371,7 +366,7 @@ light_color = "#37FFF7" actions_types = list() -/obj/item/melee/transforming/energy/sword/cx/Initialize() +/obj/item/melee/transforming/energy/sword/cx/Initialize(mapload) icon_state_on = icon_state return ..() diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index dbfeb9d08f..9f27eba643 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -46,7 +46,7 @@ sharpness = SHARP_EDGED total_mass = TOTAL_MASS_HAND_REPLACEMENT -/obj/item/melee/synthetic_arm_blade/Initialize() +/obj/item/melee/synthetic_arm_blade/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 60, 80) //very imprecise @@ -84,7 +84,7 @@ parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK parry_automatic_enabled = TRUE -/obj/item/melee/sabre/Initialize() +/obj/item/melee/sabre/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 30, 95, 5) //fast and effective, but as a sword, it might damage the results. AddElement(/datum/element/sword_point) @@ -107,7 +107,7 @@ ..() /obj/item/melee/sabre/get_belt_overlay() - return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "sabre") + return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "sabre") // todo: make this and its rapier equivalent work for the inhands too /obj/item/melee/sabre/get_worn_belt_overlay(icon_file) return mutable_appearance(icon_file, "-sabre") @@ -208,7 +208,7 @@ . |= BLOCK_SHOULD_REDIRECT return_list[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_DEFLECT -/obj/item/melee/rapier/Initialize() +/obj/item/melee/rapier/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 20, 65, 0) @@ -225,7 +225,7 @@ ..() /obj/item/melee/rapier/get_belt_overlay() - return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "rapier") + return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "rapier") // todo: same as sabre /obj/item/melee/rapier/get_worn_belt_overlay(icon_file) return mutable_appearance(icon_file, "-rapier") @@ -277,7 +277,7 @@ wound_bonus = 15 -/obj/item/melee/classic_baton/Initialize() +/obj/item/melee/classic_baton/Initialize(mapload) . = ..() if(sword_point) AddElement(/datum/element/sword_point) @@ -518,7 +518,7 @@ var/balanced = 1 force_string = "INFINITE" -/obj/item/melee/supermatter_sword/Initialize() +/obj/item/melee/supermatter_sword/Initialize(mapload) . = ..() shard = new /obj/machinery/power/supermatter_crystal(src) qdel(shard.countdown) @@ -557,7 +557,7 @@ ..() balanced = 0 -/obj/item/melee/supermatter_sword/ex_act(severity, target) +/obj/item/melee/supermatter_sword/ex_act(severity, target, origin) visible_message("The blast wave smacks into [src] and rapidly flashes to ash.",\ "You hear a loud crack as you are washed with a wave of heat.") consume_everything() @@ -625,7 +625,7 @@ var/datum/beam/beam total_mass = 2.5 -/obj/item/melee/roastingstick/Initialize() +/obj/item/melee/roastingstick/Initialize(mapload) . = ..() if (!ovens) ovens = typecacheof(list(/obj/singularity, /obj/machinery/power/supermatter_crystal, /obj/structure/bonfire, /obj/structure/destructible/clockwork/massive/ratvar)) @@ -741,7 +741,7 @@ var/overlay_state = "mace_handle" var/mutable_appearance/overlay -/obj/item/melee/cleric_mace/Initialize() +/obj/item/melee/cleric_mace/Initialize(mapload) . = ..() overlay = mutable_appearance(icon, overlay_state) overlay.appearance_flags = RESET_COLOR diff --git a/code/game/objects/items/melee/transforming.dm b/code/game/objects/items/melee/transforming.dm index 8c44a15cd4..82b19a1357 100644 --- a/code/game/objects/items/melee/transforming.dm +++ b/code/game/objects/items/melee/transforming.dm @@ -15,7 +15,7 @@ var/clumsy_check = TRUE var/total_mass_on //Total mass in ounces when transformed. Primarily for balance purposes. Don't think about it too hard. -/obj/item/melee/transforming/Initialize() +/obj/item/melee/transforming/Initialize(mapload) . = ..() if(active) if(attack_verb_on.len) diff --git a/code/game/objects/items/miscellaneous.dm b/code/game/objects/items/miscellaneous.dm index 80466832a6..590bd37d8c 100644 --- a/code/game/objects/items/miscellaneous.dm +++ b/code/game/objects/items/miscellaneous.dm @@ -240,18 +240,31 @@ item_state = "box" /obj/item/choice_beacon/box/plushie/generate_display_names() - var/list/plushie_list = list() - //plushie set 1: just subtypes of /obj/item/toy/plush - var/list/plushies_set_one = subtypesof(/obj/item/toy/plush) - list(/obj/item/toy/plush/narplush, /obj/item/toy/plush/awakenedplushie, /obj/item/toy/plush/random_snowflake, /obj/item/toy/plush/plushling, /obj/item/toy/plush/random) //don't allow these special ones (you can still get narplush/hugbox) - for(var/V in plushies_set_one) - var/atom/A = V - plushie_list[initial(A.name)] = A - //plushie set 2: snowflake plushies - var/list/plushies_set_two = CONFIG_GET(keyed_list/snowflake_plushies) - for(var/V in plushies_set_two) - plushie_list[V] = V //easiest way to do this which works with how selecting options works, despite being snowflakey to have the key equal the value + var/static/list/plushie_list = list() + if(!length(plushie_list)) + //plushie set 1: just subtypes of /obj/item/toy/plush + var/list/plushies_set_one = subtypesof(/obj/item/toy/plush) + plushies_set_one = remove_bad_plushies(plushies_set_one) + for(var/V in plushies_set_one) + var/atom/A = V + plushie_list[initial(A.name)] = A + //plushie set 2: snowflake plushies + var/list/plushies_set_two = CONFIG_GET(keyed_list/snowflake_plushies) + for(var/V in plushies_set_two) + plushie_list[V] = V //easiest way to do this which works with how selecting options works, despite being snowflakey to have the key equal the value return plushie_list +/// Don't allow these special ones (you can still get narplush/hugbox) +/obj/item/choice_beacon/box/plushie/proc/remove_bad_plushies(list/plushies) + plushies -= list( + /obj/item/toy/plush/narplush, + /obj/item/toy/plush/awakenedplushie, + /obj/item/toy/plush/random_snowflake, + /obj/item/toy/plush/plushling, + /obj/item/toy/plush/random + ) + return plushies + /obj/item/skub desc = "It's skub." name = "skub" diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm index 62a3530afe..9b0506855f 100644 --- a/code/game/objects/items/mop.dm +++ b/code/game/objects/items/mop.dm @@ -91,7 +91,7 @@ name = "advanced mop" mopcap = 10 icon_state = "advmop" - item_state = "mop" + item_state = "advmop" lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' force = 6 diff --git a/code/game/objects/items/pet_carrier.dm b/code/game/objects/items/pet_carrier.dm index 78fe1a896e..648a38437c 100644 --- a/code/game/objects/items/pet_carrier.dm +++ b/code/game/objects/items/pet_carrier.dm @@ -253,7 +253,7 @@ ///chem transfer rate / second var/transfer_rate = 5 -/obj/item/pet_carrier/bluespace/Initialize() +/obj/item/pet_carrier/bluespace/Initialize(mapload) . = ..() create_reagents(300, OPENCONTAINER, DEFAULT_REAGENTS_VALUE) //equivalent of bsbeakers diff --git a/code/game/objects/items/pinpointer.dm b/code/game/objects/items/pinpointer.dm index 22ffc33516..d1ceb36b6d 100644 --- a/code/game/objects/items/pinpointer.dm +++ b/code/game/objects/items/pinpointer.dm @@ -22,7 +22,7 @@ /// resets target on toggle var/resets_target = TRUE -/obj/item/pinpointer/Initialize() +/obj/item/pinpointer/Initialize(mapload) . = ..() GLOB.pinpointer_list += src diff --git a/code/game/objects/items/pitchfork.dm b/code/game/objects/items/pitchfork.dm index b296e2d0cb..eff586cf11 100644 --- a/code/game/objects/items/pitchfork.dm +++ b/code/game/objects/items/pitchfork.dm @@ -11,11 +11,11 @@ hitsound = 'sound/weapons/bladeslice.ogg' sharpness = SHARP_EDGED max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 30) resistance_flags = FIRE_PROOF var/wielded = FALSE // track wielded status on item -/obj/item/pitchfork/Initialize() +/obj/item/pitchfork/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield) RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield) @@ -42,7 +42,7 @@ force = 19 throwforce = 24 -/obj/item/pitchfork/demonic/Initialize() +/obj/item/pitchfork/demonic/Initialize(mapload) . = ..() set_light(3,6,LIGHT_COLOR_RED) diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm index 59464d25a7..64b2362edc 100644 --- a/code/game/objects/items/plushes.dm +++ b/code/game/objects/items/plushes.dm @@ -6,6 +6,8 @@ attack_verb = list("thumped", "whomped", "bumped") w_class = WEIGHT_CLASS_SMALL resistance_flags = FLAMMABLE + lefthand_file = 'icons/mob/inhands/misc/plushes_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/plushes_righthand.dmi' var/list/squeak_override //Weighted list; If you want your plush to have different squeak sounds use this var/stuffed = TRUE //If the plushie has stuffing in it var/unstuffable = FALSE //for plushies that can't be stuffed @@ -238,72 +240,73 @@ return return ..() -/obj/item/toy/plush/proc/love(obj/item/toy/plush/Kisser, mob/living/user) //~<3 - var/chance = 100 //to steal a kiss, surely there's a 100% chance no-one would reject a plush such as I? - var/concern = 20 //perhaps something might cloud true love with doubt - var/loyalty = 30 //why should another get between us? - var/duty = 50 //conquering another's is what I live for +/obj/item/toy/plush/proc/love(obj/item/toy/plush/Kisser, mob/living/user) //~<3 + var/chance = 100 //to steal a kiss, surely there's a 100% chance no-one would reject a plush such as I? + var/concern = 20 //perhaps something might cloud true love with doubt + var/loyalty = 30 //why should another get between us? + var/duty = 50 //conquering another's is what I live for //we are not catholic if(young == TRUE || Kisser.young == TRUE) - user.show_message("[src] plays tag with [Kisser].", MSG_VISUAL, - "They're happy.", 0) + user.show_message(span_notice("[src] plays tag with [Kisser]."), MSG_VISUAL, + span_notice("They're happy."), NONE) Kisser.cheer_up() cheer_up() //never again else if(Kisser in scorned) //message, visible, alternate message, neither visible nor audible - user.show_message("[src] rejects the advances of [Kisser]!", MSG_VISUAL, - "That didn't feel like it worked.", 0) + user.show_message(span_notice("[src] rejects the advances of [Kisser]!"), MSG_VISUAL, + span_notice("That didn't feel like it worked."), NONE) else if(src in Kisser.scorned) - user.show_message("[Kisser] realises who [src] is and turns away.", MSG_VISUAL, - "That didn't feel like it worked.", 0) + user.show_message(span_notice("[Kisser] realises who [src] is and turns away."), MSG_VISUAL, + span_notice("That didn't feel like it worked."), NONE) //first comes love - else if(Kisser.lover != src && Kisser.partner != src) //cannot be lovers or married - if(Kisser.lover) //if the initiator has a lover - Kisser.lover.heartbreak(Kisser) //the old lover can get over the kiss-and-run whilst the kisser has some fun - chance -= concern //one heart already broken, what does another mean? - if(lover) //if the recipient has a lover - chance -= loyalty //mustn't... but those lips - if(partner) //if the recipient has a partner - chance -= duty //do we mate for life? + else if(Kisser.lover != src && Kisser.partner != src) //cannot be lovers or married + if(Kisser.lover) //if the initiator has a lover + Kisser.lover.heartbreak(Kisser) //the old lover can get over the kiss-and-run whilst the kisser has some fun + chance -= concern //one heart already broken, what does another mean? + if(lover) //if the recipient has a lover + chance -= loyalty //mustn't... but those lips + if(partner) //if the recipient has a partner + chance -= duty //do we mate for life? - if(prob(chance)) //did we bag a date? - user.visible_message("[user] makes [Kisser] kiss [src]!", - "You make [Kisser] kiss [src]!") - if(lover) //who cares for the past, we live in the present + if(prob(chance)) //did we bag a date? + user.visible_message(span_notice("[user] makes [Kisser] kiss [src]!"), + span_notice("You make [Kisser] kiss [src]!")) + if(lover) //who cares for the past, we live in the present lover.heartbreak(src) new_lover(Kisser) Kisser.new_lover(src) else - user.show_message("[src] rejects the advances of [Kisser], maybe next time?", MSG_VISUAL, - "That didn't feel like it worked, this time.", 0) + user.show_message(span_notice("[src] rejects the advances of [Kisser], maybe next time?"), MSG_VISUAL, + span_notice("That didn't feel like it worked, this time."), NONE) //then comes marriage - else if(Kisser.lover == src && Kisser.partner != src) //need to be lovers (assumes loving is a two way street) but not married (also assumes similar) - user.visible_message("[user] pronounces [Kisser] and [src] married! D'aw.", - "You pronounce [Kisser] and [src] married!") + else if(Kisser.lover == src && Kisser.partner != src) //need to be lovers (assumes loving is a two way street) but not married (also assumes similar) + user.visible_message(span_notice("[user] pronounces [Kisser] and [src] married! D'aw."), + span_notice("You pronounce [Kisser] and [src] married!")) new_partner(Kisser) Kisser.new_partner(src) //then comes a baby in a baby's carriage, or an adoption in an adoption's orphanage - else if(Kisser.partner == src && !plush_child) //the one advancing does not take ownership of the child and we have a one child policy in the toyshop - user.visible_message("[user] is going to break [Kisser] and [src] by bashing them like that.", - "[Kisser] passionately embraces [src] in your hands. Look away you perv!") + else if(Kisser.partner == src && !plush_child) //the one advancing does not take ownership of the child and we have a one child policy in the toyshop + user.visible_message(span_notice("[user] is going to break [Kisser] and [src] by bashing them like that."), + span_notice("[Kisser] passionately embraces [src] in your hands. Look away you perv!")) + user.client.give_award(/datum/award/achievement/misc/rule8, user) if(plop(Kisser)) - user.visible_message("Something drops at the feet of [user].", - "The miracle of oh god did that just come out of [src]?!") + user.visible_message(span_notice("Something drops at the feet of [user]."), + span_notice("The miracle of oh god did that just come out of [src]?!")) //then comes protection, or abstinence if we are catholic else if(Kisser.partner == src && plush_child) - user.visible_message("[user] makes [Kisser] nuzzle [src]!", - "You make [Kisser] nuzzle [src]!") + user.visible_message(span_notice("[user] makes [Kisser] nuzzle [src]!"), + span_notice("You make [Kisser] nuzzle [src]!")) //then oh fuck something unexpected happened else - user.show_message("[Kisser] and [src] don't know what to do with one another.", 0) + user.show_message(span_warning("[Kisser] and [src] don't know what to do with one another."), NONE) /obj/item/toy/plush/proc/heartbreak(obj/item/toy/plush/Brutus) if(lover != Brutus) @@ -465,7 +468,7 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) desc = "Something fucked up" can_random_spawn = FALSE -/obj/item/toy/plush/random/Initialize() +/obj/item/toy/plush/random/Initialize(mapload) ..() var/newtype var/list/snowflake_list = CONFIG_GET(keyed_list/snowflake_plushies) @@ -483,7 +486,6 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "space carp plushie" desc = "An adorable stuffed toy that resembles a space carp." icon_state = "carpplush" - item_state = "carp_plushie" attack_verb = list("bitten", "eaten", "fin slapped") squeak_override = list('sound/weapons/bite.ogg'=1) @@ -602,7 +604,6 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "lizard plushie" desc = "An adorable stuffed toy that resembles a lizardperson." icon_state = "plushie_lizard" - item_state = "plushie_lizard" attack_verb = list("clawed", "hissed", "tail slapped") squeak_override = list('sound/weapons/slash.ogg' = 1) @@ -610,19 +611,16 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "kobold plushie" desc = "An adorable stuffed toy that resembles a kobold." icon_state = "kobold" - item_state = "kobold" /obj/item/toy/plush/lizardplushie/kobold name = "spacelizard plushie" desc = "An adorable stuffed toy that resembles a lizard in a suit." icon_state = "plushie_spacelizard" - item_state = "plushie_spacelizard" /obj/item/toy/plush/nukeplushie name = "operative plushie" desc = "A stuffed toy that resembles a syndicate nuclear operative. The tag claims operatives to be purely fictitious." icon_state = "plushie_nuke" - item_state = "plushie_nuke" attack_verb = list("shot", "nuked", "detonated") squeak_override = list('sound/effects/hit_punch.ogg' = 1) @@ -630,7 +628,6 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "slime plushie" desc = "An adorable stuffed toy that resembles a slime. It is practically just a hacky sack." icon_state = "plushie_slime" - item_state = "plushie_slime" attack_verb = list("blorbled", "slimed", "absorbed", "glomped") squeak_override = list('sound/effects/blobattack.ogg' = 1) gender = FEMALE //given all the jokes and drawings, I'm not sure the xenobiologists would make a slimeboy @@ -639,7 +636,6 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "awakened plushie" desc = "An ancient plushie that has grown enlightened to the true nature of reality." icon_state = "plushie_awake" - item_state = "plushie_awake" can_random_spawn = FALSE /obj/item/toy/plush/awakenedplushie/ComponentInitialize() @@ -650,7 +646,6 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "bee plushie" desc = "A cute toy that resembles an even cuter bee." icon_state = "plushie_bee" - item_state = "plushie_bee" attack_verb = list("stung") gender = FEMALE squeak_override = list('modular_citadel/sound/voice/scream_moth.ogg' = 1) @@ -659,7 +654,6 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "moth plushie" desc = "An adorable stuffed toy that resembles some kind of insect." icon_state = "moff" - item_state = "moff" squeak_override = list('modular_citadel/sound/voice/mothsqueak.ogg' = 1) can_random_spawn = FALSE @@ -667,7 +661,6 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "lamp plushie" desc = "A toy lamp plushie, doesn't actually make light, but it still toggles on and off. Click clack!" icon_state = "plushie_lamp" - item_state = "plushie_lamp" attack_verb = list("lit", "flickered", "flashed") squeak_override = list('sound/weapons/magout.ogg' = 1) @@ -675,72 +668,61 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "drake plushie" desc = "A large beast from lavaland turned into a marketable plushie!" icon_state = "drake" - item_state = "drake" attack_verb = list("bit", "devoured", "burned") /obj/item/toy/plush/deer name = "deer plushie" desc = "Oh deer, a plushie!" icon_state = "deer" - item_state = "deer" attack_verb = list("bleated", "rammed", "kicked") /obj/item/toy/plush/box name = "cardboard plushie" desc = "A toy box plushie, it holds cotten. Only a baddie would place a bomb through the postal system..." icon_state = "box" - item_state = "box" attack_verb = list("open", "closed", "packed", "hidden", "rigged", "bombed", "sent", "gave") /obj/item/toy/plush/slaggy name = "slag plushie" desc = "A piece of slag with some googly eyes and a drawn on mouth." icon_state = "slaggy" - item_state = "slaggy" attack_verb = list("melted", "refined", "stared") /obj/item/toy/plush/mr_buckety name = "bucket plushie" desc = "A bucket that is missing its handle with some googly eyes and a drawn on mouth." icon_state = "mr_buckety" - item_state = "mr_buckety" attack_verb = list("filled", "dumped", "stared") /obj/item/toy/plush/dr_scanny name = "scanner plushie" desc = "A old outdated scanner that has been modified to have googly eyes, a dawn on mouth and, heart." icon_state = "dr_scanny" - item_state = "dr_scanny" attack_verb = list("scanned", "beeped", "stared") /obj/item/toy/plush/borgplushie name = "K9 plushie" desc = "An adorable stuffed toy of a robot." icon_state = "securityk9" - item_state = "securityk9" attack_verb = list("beeped", "booped", "pinged") squeak_override = list('sound/machines/beep.ogg' = 1) /obj/item/toy/plush/borgplushie/medihound name = "medihound plushie" icon_state = "medihound" - item_state = "medihound" /obj/item/toy/plush/borgplushie/scrubpuppy name = "scrubpuppy plushie" icon_state = "scrubpuppy" - item_state = "scrubpuppy" /obj/item/toy/plush/borgplushie/pupdozer name = "pupdozer plushie" icon_state = "pupdozer" - item_state = "pupdozer" /obj/item/toy/plush/aiplush name = "AI plushie" desc = "A little stuffed toy AI core... it appears to be malfunctioning." icon_state = "malfai" - item_state = "malfai" attack_verb = list("hacked", "detonated", "overloaded") squeak_override = list('sound/machines/beep.ogg' = 9, 'sound/machines/buzz-two.ogg' = 1) @@ -748,7 +730,6 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "snake plushie" desc = "An adorable stuffed toy that resembles a snake. Not to be mistaken for the real thing." icon_state = "plushie_snake" - item_state = "plushie_snake" attack_verb = list("bitten", "hissed", "tail slapped") squeak_override = list('modular_citadel/sound/voice/hiss.ogg' = 1) @@ -756,20 +737,17 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "mammal plushie" desc = "An adorable stuffed toy resembling some sort of crew member." icon_state = "ych" - item_state = "ych" can_random_spawn = FALSE /obj/item/toy/plush/mammal/fox name = "fox plushie" desc = "An adorable stuffed toy resembling a fox." icon_state = "fox" - item_state = "fox" attack_verb = list("yipped", "geckered", "yapped") /obj/item/toy/plush/mammal/dog name = "dog plushie" icon_state = "corgi" - item_state = "corgi" desc = "An adorable stuffed toy that resembles a dog." attack_verb = list("barked", "boofed", "borked") squeak_override = list( @@ -780,20 +758,17 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) /obj/item/toy/plush/mammal/dog/fcorgi name = "corgi plushie" icon_state = "girlycorgi" - item_state = "girlycorgi" desc = "An adorable stuffed toy that resembles a dog. This one dons a pink ribbon." /obj/item/toy/plush/mammal/dog/borgi name = "borgi plushie" icon_state = "borgi" - item_state = "borgi" desc = "An adorable stuffed toy that resembles a robot dog." /obj/item/toy/plush/xeno name = "xenohybrid plushie" desc = "An adorable stuffed toy that resembles a xenomorphic crewmember." icon_state = "xeno" - item_state = "xeno" squeak_override = list('sound/voice/hiss2.ogg' = 1) can_random_spawn = FALSE @@ -801,7 +776,6 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "bird plushie" desc = "An adorable stuffed plushie that resembles an avian." icon_state = "bird" - item_state = "bird" attack_verb = list("peeped", "beeped", "poofed") squeak_override = list('modular_citadel/sound/voice/peep.ogg' = 1) can_random_spawn = FALSE @@ -810,7 +784,6 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "sergal plushie" desc = "An adorable stuffed plushie that resembles a sagaru." icon_state = "sergal" - item_state = "sergal" squeak_override = list('modular_citadel/sound/voice/merp.ogg' = 1) can_random_spawn = FALSE @@ -818,7 +791,6 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "feline plushie" desc = "An adorable stuffed toy that resembles a feline." icon_state = "cat" - item_state = "cat" attack_verb = list("headbutt", "scritched", "bit") squeak_override = list('modular_citadel/sound/voice/nya.ogg' = 1) can_random_spawn = FALSE @@ -827,7 +799,6 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "medcat plushie" desc = "An affectionate stuffed toy that resembles a certain medcat, comes complete with battery operated wagging tail!! You get the impression she's cheering you on to to find happiness and be kind to people." icon_state = "fermis" - item_state = "fermis" attack_verb = list("cuddled", "petpatted", "wigglepurred") squeak_override = list('modular_citadel/sound/voice/merowr.ogg' = 1) @@ -835,20 +806,17 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths()) name = "teddy" desc = "It's a teddy bear!" icon_state = "teddy" - item_state = "teddy" /obj/item/toy/plush/crab name = "crab plushie" desc = "Fewer pinches than a real one, but it still clicks." icon_state = "crab" - item_state = "crab" attack_verb = list("clicked", "clacked", "pinched") /obj/item/toy/plush/gondola name = "gondola plushie" desc = "Just looking at it seems to calm you down. Please do not eat it though." icon_state = "gondola" - item_state = "gondola" attack_verb = list("calmed", "smiled", "peaced") /obj/item/toy/plush/hairball diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm index 42e345b502..2b0b8da670 100644 --- a/code/game/objects/items/pneumaticCannon.dm +++ b/code/game/objects/items/pneumaticCannon.dm @@ -13,7 +13,7 @@ item_state = "bulldog" lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 60, ACID = 50) var/maxWeightClass = 20 //The max weight of items that can fit into the cannon var/loadedWeightClass = 0 //The weight of items currently in the cannon var/obj/item/tank/internals/tank = null //The gas tank that is drawn from to fire things @@ -35,7 +35,7 @@ trigger_guard = TRIGGER_GUARD_NORMAL -/obj/item/pneumatic_cannon/Initialize() +/obj/item/pneumatic_cannon/Initialize(mapload) . = ..() if(selfcharge) init_charge() @@ -205,6 +205,10 @@ if(!throw_item(target, I, user)) break + if(user) + shake_camera(user, (pressureSetting * 0.75 + 1), (pressureSetting * 0.75)) + + /obj/item/pneumatic_cannon/proc/throw_item(turf/target, obj/item/I, mob/user) if(!istype(I)) return FALSE @@ -292,7 +296,7 @@ clumsyCheck = FALSE var/static/list/pie_typecache = typecacheof(/obj/item/reagent_containers/food/snacks/pie) -/obj/item/pneumatic_cannon/pie/Initialize() +/obj/item/pneumatic_cannon/pie/Initialize(mapload) . = ..() allowed_typecache = pie_typecache diff --git a/code/game/objects/items/powerfist.dm b/code/game/objects/items/powerfist.dm index 569b11b8b0..713a14460b 100644 --- a/code/game/objects/items/powerfist.dm +++ b/code/game/objects/items/powerfist.dm @@ -12,7 +12,7 @@ throwforce = 10 throw_range = 7 w_class = WEIGHT_CLASS_NORMAL - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 40) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 40) resistance_flags = FIRE_PROOF attack_speed = CLICK_CD_MELEE * 1.5 var/fisto_setting = 1 diff --git a/code/game/objects/items/puzzle_pieces.dm b/code/game/objects/items/puzzle_pieces.dm index 345f3185da..325acc6ac6 100644 --- a/code/game/objects/items/puzzle_pieces.dm +++ b/code/game/objects/items/puzzle_pieces.dm @@ -39,7 +39,7 @@ explosion_block = 3 heat_proof = TRUE max_integrity = 600 - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | LAVA_PROOF damage_deflection = 70 /// Make sure that the key has the same puzzle_id as the keycard door! @@ -54,7 +54,7 @@ /obj/machinery/door/keycard/emp_act(severity) return -/obj/machinery/door/keycard/ex_act(severity, target) +/obj/machinery/door/keycard/ex_act(severity, target, origin) return /obj/machinery/door/keycard/try_to_activate_door(mob/user) diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm index b8f0d161dc..bd03698cd7 100644 --- a/code/game/objects/items/religion.dm +++ b/code/game/objects/items/religion.dm @@ -165,7 +165,7 @@ desc = "It's a backpack with lots of extra room. A banner with Nanotrasen's logo is attached, that can't be removed." icon_state = "bannerpack" -/obj/item/storage/backpack/bannerpack/Initialize() +/obj/item/storage/backpack/bannerpack/Initialize(mapload) . = ..() var/datum/component/storage/STR = GetComponent(/datum/component/storage) STR.max_combined_w_class = 27 //6 more then normal, for the tradeoff of declaring yourself an antag at all times. @@ -188,7 +188,7 @@ w_class = WEIGHT_CLASS_BULKY slowdown = 2.0 //gotta pretend we're balanced. body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 40, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 40, BOMB = 60, BIO = 0, RAD = 0, FIRE = 60, ACID = 60) mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON /obj/item/clothing/suit/armor/plate/crusader/red @@ -203,7 +203,7 @@ icon_state = "crusader" w_class = WEIGHT_CLASS_NORMAL flags_inv = HIDEHAIR|HIDEEARS|HIDEFACE - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 40, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 40, BOMB = 60, BIO = 0, RAD = 0, FIRE = 60, ACID = 60) /obj/item/clothing/head/helmet/plate/crusader/blue icon_state = "crusader-blue" @@ -218,7 +218,7 @@ icon_state = "prophet" mob_overlay_icon = 'icons/mob/large-worn-icons/64x64/head.dmi' flags_1 = NONE - armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 50, "bomb" = 70, "bio" = 50, "rad" = 50, "fire" = 60, "acid" = 60) //religion protects you from disease and radiation, honk. + armor = list(MELEE = 60, BULLET = 60, LASER = 60, ENERGY = 50, BOMB = 70, BIO = 50, RAD = 50, FIRE = 60, ACID = 60) //religion protects you from disease and radiation, honk. worn_x_dimension = 64 worn_y_dimension = 64 @@ -244,7 +244,7 @@ if(staffcooldown + staffwait > world.time) return user.visible_message("[user] chants deeply and waves [user.p_their()] staff!") - if(do_after(user, 20,1,src)) + if(do_after(user, 2 SECONDS, src)) target.add_atom_colour(conversion_color, WASHABLE_COLOUR_PRIORITY) //wololo staffcooldown = world.time @@ -277,7 +277,7 @@ desc = "Metal boots, they look heavy." icon_state = "crusader" w_class = WEIGHT_CLASS_NORMAL - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 40, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) //does this even do anything on boots? + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 40, BOMB = 60, BIO = 0, RAD = 0, FIRE = 60, ACID = 60) //does this even do anything on boots? clothing_flags = NOSLIP cold_protection = FEET min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index 6513b53e1d..2cc65ab261 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -564,7 +564,7 @@ energy = 50000 energy_recharge = 5000 -/obj/item/borg/projectile_dampen/Initialize() +/obj/item/borg/projectile_dampen/Initialize(mapload) . = ..() projectile_effect = image('icons/effects/fields.dmi', "projectile_dampen_effect") tracked = list() @@ -745,9 +745,9 @@ Grippers oh god oh fuck ***********************************************************************/ -/obj/item/weapon/gripper +/obj/item/gripper name = "engineering gripper" - desc = "A simple grasping tool for interacting with various engineering related items, such as circuits, gas tanks, conveyer belts and more. Alt click to drop instead of use." + desc = "A simple grasping tool for interacting with various engineering related items, such as circuits, gas tanks, conveyer belts and more." icon = 'icons/obj/device.dmi' icon_state = "gripper" @@ -776,18 +776,29 @@ var/obj/item/wrapped = null // Item currently being held. -//Used to interact with UI's of held items, such as gas tanks and airlock electronics. -/obj/item/weapon/gripper/AltClick(mob/user) +// Used to drop whatever's in the gripper. +/obj/item/gripper/proc/drop_held(silent = FALSE) if(wrapped) wrapped.forceMove(get_turf(wrapped)) - to_chat(user, "You drop the [wrapped].") + if(!silent) + to_chat(usr, "You drop the [wrapped].") + modify_appearance(wrapped, FALSE) wrapped = null - return ..() + update_appearance() + return TRUE + return FALSE -/obj/item/weapon/gripper/pre_attack(var/atom/target, var/mob/living/silicon/robot/user, proximity, params) +/obj/item/gripper/proc/takeitem(obj/item/item, silent = FALSE) + if(!silent) + to_chat(usr, "You collect \the [item].") + item.loc = src + wrapped = item + update_appearance() - if(!proximity) - return +/obj/item/gripper/pre_attack(atom/target, mob/living/silicon/robot/user, params) + var/proximity = get_dist(user, target) + if(proximity > 1) + return STOP_ATTACK_PROC_CHAIN if(!wrapped) for(var/obj/item/thing in src.contents) @@ -795,21 +806,24 @@ break if(wrapped) //Already have an item. + var/obj/item/item = wrapped + drop_held(TRUE) //Temporary put wrapped into user so target's attackby() checks pass. - wrapped.loc = user + item.loc = user //Pass the attack on to the target. This might delete/relocate wrapped. - var/resolved = target.attackby(wrapped,user) - if(!resolved && wrapped && target) - wrapped.afterattack(target,user,1) + var/resolved = target.attackby(item, user, params) + if(!resolved && item && target) + item.afterattack(target, user, proximity, params) //If wrapped was neither deleted nor put into target, put it back into the gripper. - if(wrapped && user && (wrapped.loc == user)) - wrapped.loc = src - else - wrapped = null + if(item && user && (item.loc == user)) + takeitem(item, TRUE) return + else + item = null + return STOP_ATTACK_PROC_CHAIN - else if(istype(target,/obj/item)) + else if(isitem(target)) var/obj/item/I = target var/grab = 0 @@ -824,24 +838,94 @@ //We can grab the item, finally. if(grab) - to_chat(user, "You collect \the [I].") - I.loc = src - wrapped = I + takeitem(I) return else to_chat(user, "Your gripper cannot hold \the [target].") -/obj/item/weapon/gripper/mining +// Rare cases - meant to be handled by code\modules\mob\living\silicon\robot\robot.dm:584 and the weirdness of get_active_held_item() of borgs. +/obj/item/gripper/attack_self(mob/user) + if(wrapped) + wrapped.attack_self(user) + return + . = ..() + +// Splitable items +/obj/item/gripper/AltClick(mob/user) + if(wrapped) + wrapped.AltClick(user) + return + . = ..() + +// Even rarer cases +/obj/item/gripper/CtrlClick(mob/user) + if(wrapped) + wrapped.CtrlClick(user) + return + . = ..() + +// At this point you're just kidding me, but have this one as well. +/obj/item/gripper/CtrlShiftClick(mob/user) + if(wrapped) + wrapped.CtrlShiftClick(user) + return + . = ..() + +// Make it clear what we can do with it. +/obj/item/gripper/examine(mob/user) + . = ..() + if(wrapped) + . += "It is holding [icon2html(wrapped, user)] [wrapped]." + . += "Examine the little preview to examine it." + . += "Attempting to drop the gripper will only drop [wrapped]." + +// Resets vis_contents and if holding something, add it to vis_contents. +/obj/item/gripper/update_appearance(updates) + . = ..() + vis_contents = list() + if(wrapped) + modify_appearance(wrapped, TRUE) + vis_contents += wrapped + +// Generates the "minified" version of the item being held and adjust it's position. +/obj/item/gripper/proc/modify_appearance(obj/item, minify = FALSE) + if(minify) + var/matrix/new_transform = new + new_transform.Scale(0.5, 0.5) + item.transform = new_transform + item.pixel_x = 8 + item.pixel_y = -8 + else + item.pixel_x = initial(pixel_x) + item.pixel_y = initial(pixel_y) + item.transform = new + +// I kind of wanted the item to be held in the gripper when stored as well, but i realized "store" is just drop as well, so i'll do this for now. +// This will handle cases where the borg runs out of power or is damaged enough so the module is forcefully stored. +/obj/item/gripper/cyborg_unequip(mob/user) + . = ..() + if(wrapped) + drop_held() + +// Clear references on being destroyed +/obj/item/Destroy() + for(var/obj/item/gripper/gripper in vis_locs) + if(gripper.wrapped == src) + gripper.wrapped = null + gripper.update_appearance() + . = ..() + +/obj/item/gripper/mining name = "shelter capsule deployer" - desc = "A simple grasping tool for carrying and deploying shelter capsules. Alt click to drop instead of use." + desc = "A simple grasping tool for carrying and deploying shelter capsules." icon_state = "gripper_mining" can_hold = list( /obj/item/survivalcapsule ) -/obj/item/weapon/gripper/medical +/obj/item/gripper/medical name = "medical gripper" - desc = "A simple grasping tool for interacting with medical equipment, such as beakers, blood bags, chem bags and more. Alt click to drop instead of use." + desc = "A simple grasping tool for interacting with medical equipment, such as beakers, blood bags, chem bags and more." icon_state = "gripper_medical" can_hold = list( /obj/item/storage/bag/bio, diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 88648bcbb7..5a8788deba 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -216,6 +216,25 @@ as performing this in action() will cause the upgrade to end up in the borg inst for(var/obj/item/ammo_casing/energy/plasma/weak/L in C.ammo_type) L.projectile_type = initial(L.projectile_type) +/obj/item/borg/upgrade/premiumka + name = "mining cyborg premium KA" + desc = "A premium kinetic accelerator replacement for the mining module's standard kinetic accelerator." + icon_state = "cyborg_upgrade3" + require_module = 1 + module_type = list(/obj/item/robot_module/miner) + +/obj/item/borg/upgrade/premiumka/action(mob/living/silicon/robot/R, user = usr) + . = ..() + if(.) + for(var/obj/item/gun/energy/kinetic_accelerator/cyborg/KA in R.module) + for(var/obj/item/borg/upgrade/modkit/M in KA.modkits) + M.uninstall(src) + R.module.remove_module(KA, TRUE) + + var/obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg/PKA = new /obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg(R.module) + R.module.basic_modules += PKA + R.module.add_module(PKA, FALSE, TRUE) + /obj/item/borg/upgrade/tboh name = "janitor cyborg trash bag of holding" desc = "A trash bag of holding replacement for the janiborg's standard trash bag." @@ -305,12 +324,12 @@ as performing this in action() will cause the upgrade to end up in the borg inst /obj/item/borg/upgrade/lavaproof/action(mob/living/silicon/robot/R, user = usr) . = ..() if(.) - R.weather_immunities += "lava" + ADD_TRAIT(src, TRAIT_LAVA_IMMUNE, type) /obj/item/borg/upgrade/lavaproof/deactivate(mob/living/silicon/robot/R, user = usr) . = ..() if (.) - R.weather_immunities -= "lava" + REMOVE_TRAIT(src, TRAIT_LAVA_IMMUNE, type) /obj/item/borg/upgrade/selfrepair name = "self-repair module" @@ -457,6 +476,10 @@ as performing this in action() will cause the upgrade to end up in the borg inst desc = "An upgrade to a cyborg's hypospray, allowing it to \ pierce armor and thick material." icon_state = "cyborg_upgrade3" + module_type = list(/obj/item/robot_module/medical, + /obj/item/robot_module/syndicate_medical) + var/list/additional_reagents = list() + module_flags = BORG_MODULE_MEDICAL /obj/item/borg/upgrade/piercing_hypospray/action(mob/living/silicon/robot/R, user = usr) . = ..() @@ -514,6 +537,7 @@ as performing this in action() will cause the upgrade to end up in the borg inst module_type = list( /obj/item/robot_module/medical, /obj/item/robot_module/syndicate_medical) + module_flags = BORG_MODULE_MEDICAL /obj/item/borg/upgrade/advhealth/action(mob/living/silicon/robot/R, user = usr) . = ..() diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index 74efe3a196..1363f0994c 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -3,7 +3,7 @@ icon = 'icons/obj/shields.dmi' item_flags = ITEM_CAN_BLOCK block_parry_data = /datum/block_parry_data/shield - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 80, ACID = 70) /// Shield flags var/shield_flags = SHIELD_FLAGS_DEFAULT /// Last shieldbash world.time @@ -78,7 +78,7 @@ animate(effect, alpha = 0, pixel_x = px * 1.5, pixel_y = py * 1.5, time = 3, flags = ANIMATION_PARALLEL | ANIMATION_RELATIVE) /obj/item/shield/proc/bash_target(mob/living/user, mob/living/target, bashdir, harmful) - if(!(target.status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)) // should probably add stun absorption check at some point I guess.. + if(!(HAS_TRAIT(target, CANKNOCKDOWN)) || HAS_TRAIT(target, TRAIT_STUNIMMUNE)) // should probably add stun absorption check at some point I guess.. // unified stun absorption system when lol target.visible_message("[user] slams [target] with [src], but [target] doesn't falter!", "[user] slams you with [src], but it barely fazes you!") return FALSE @@ -174,11 +174,11 @@ /obj/item/shield/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) if(ismovable(object)) var/atom/movable/AM = object - if(CHECK_BITFIELD(shield_flags, SHIELD_TRANSPARENT) && (AM.pass_flags & PASSGLASS)) + if((shield_flags & SHIELD_TRANSPARENT) && (AM.pass_flags & PASSGLASS)) return BLOCK_NONE - if(CHECK_BITFIELD(shield_flags, SHIELD_NO_RANGED) && (attack_type & ATTACK_TYPE_PROJECTILE)) + if((shield_flags & SHIELD_NO_RANGED) && (attack_type & ATTACK_TYPE_PROJECTILE)) return BLOCK_NONE - if(CHECK_BITFIELD(shield_flags, SHIELD_NO_MELEE) && (attack_type & ATTACK_TYPE_MELEE)) + if((shield_flags & SHIELD_NO_MELEE) && (attack_type & ATTACK_TYPE_MELEE)) return BLOCK_NONE if(attack_type & ATTACK_TYPE_THROWN) final_block_chance += 30 @@ -247,38 +247,44 @@ var/final_damage = damage if(attack_type & ATTACK_TYPE_MELEE) - var/obj/hittingthing = object - if(hittingthing.damtype == BURN) - if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_WEAK)) - final_damage *= 2 - else if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_STRONG)) - final_damage *= 0.5 + if(istype(object, /obj)) //Assumption: non-object attackers are a meleeing mob. Therefore: Assuming physical attack in this case. + var/obj/hittingthing = object + if(hittingthing.damtype == BURN) + if((shield_flags & SHIELD_ENERGY_WEAK)) + final_damage *= 2 + else if((shield_flags & SHIELD_ENERGY_STRONG)) + final_damage *= 0.5 - if(hittingthing.damtype == BRUTE) - if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_WEAK)) - final_damage *= 2 - else if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_STRONG)) - final_damage *= 0.5 + if(hittingthing.damtype == BRUTE) + if((shield_flags & SHIELD_KINETIC_WEAK)) + final_damage *= 2 + else if((shield_flags & SHIELD_KINETIC_STRONG)) + final_damage *= 0.5 - if(hittingthing.damtype == STAMINA || hittingthing.damtype == TOX || hittingthing.damtype == CLONE || hittingthing.damtype == BRAIN || hittingthing.damtype == OXY) - final_damage = 0 + if(hittingthing.damtype == STAMINA || hittingthing.damtype == TOX || hittingthing.damtype == CLONE || hittingthing.damtype == BRAIN || hittingthing.damtype == OXY) + final_damage = 0 + else + if((shield_flags & SHIELD_KINETIC_WEAK)) + final_damage *= 2 + else if((shield_flags & SHIELD_KINETIC_STRONG)) + final_damage *= 0.5 if(attack_type & ATTACK_TYPE_PROJECTILE) var/obj/item/projectile/shootingthing = object if(is_energy_reflectable_projectile(shootingthing)) - if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_WEAK)) + if((shield_flags & SHIELD_ENERGY_WEAK)) final_damage *= 2 - else if(CHECK_BITFIELD(shield_flags, SHIELD_ENERGY_STRONG)) + else if((shield_flags & SHIELD_ENERGY_STRONG)) final_damage *= 0.5 if(!is_energy_reflectable_projectile(object)) - if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_WEAK)) + if((shield_flags & SHIELD_KINETIC_WEAK)) final_damage *= 2 - else if(CHECK_BITFIELD(shield_flags, SHIELD_KINETIC_STRONG)) + else if((shield_flags & SHIELD_KINETIC_STRONG)) final_damage *= 0.5 if(shootingthing.damage_type == STAMINA) - if(CHECK_BITFIELD(shield_flags, SHIELD_DISABLER_DISRUPTED)) + if((shield_flags & SHIELD_DISABLER_DISRUPTED)) final_damage *= 3 //disablers melt these kinds of shields. Really meant more for holoshields. else final_damage = 0 @@ -298,7 +304,7 @@ /obj/item/shield/riot/energy_proof name = "energy resistant shield" desc = "An ablative shield designed to absorb and disperse energy attacks. This comes at significant cost to its ability to withstand ballistics and kinetics, breaking apart easily." - armor = list("melee" = 30, "bullet" = -10, "laser" = 80, "energy" = 80, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 30, BULLET = -10, LASER = 80, ENERGY = 80, BOMB = -40, BIO = 0, RAD = 0, FIRE = 0, ACID = 50) icon_state = "riot_laser" item_state = "riot_laser" lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' @@ -309,7 +315,7 @@ /obj/item/shield/riot/kinetic_proof name = "kinetic resistant shield" desc = "A polymer and ceramic shield designed to absorb ballistic projectiles and kinetic force. It doesn't do very well into energy attacks, especially from weapons that inflict burns." - armor = list("melee" = 30, "bullet" = 80, "laser" = 0, "energy" = 0, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 30, BULLET = 80, LASER = 0, ENERGY = 0, BOMB = -40, BIO = 0, RAD = 0, FIRE = 0, ACID = 50) icon_state = "riot_bullet" item_state = "riot_bullet" shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_KINETIC_STRONG | SHIELD_ENERGY_WEAK @@ -328,7 +334,7 @@ /obj/item/shield/riot/roman/fake desc = "Bears an inscription on the inside: \"Romanes venio domus\". It appears to be a bit flimsy." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) shield_flags = SHIELD_ENERGY_WEAK | SHIELD_KINETIC_WEAK | SHIELD_NO_RANGED max_integrity = 40 @@ -360,7 +366,7 @@ item_state = "flashshield" var/obj/item/assembly/flash/handheld/embedded_flash -/obj/item/shield/riot/flash/Initialize() +/obj/item/shield/riot/flash/Initialize(mapload) . = ..() embedded_flash = new(src) @@ -465,7 +471,7 @@ /obj/item/shield/makeshift name = "metal shield" desc = "A large shield made of wired and welded sheets of metal. The handle is made of cloth and leather, making it unwieldy." - armor = list("melee" = 25, "bullet" = 25, "laser" = 5, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 80) + armor = list(MELEE = 25, BULLET = 25, LASER = 5, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 70, ACID = 80) lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' item_state = "metal" @@ -479,7 +485,7 @@ /obj/item/shield/riot/tower name = "tower shield" desc = "An immense tower shield. Designed to ensure maximum protection to the user, at the expense of mobility." - armor = list("melee" = 95, "bullet" = 95, "laser" = 75, "energy" = 60, "bomb" = 90, "bio" = 90, "rad" = 0, "fire" = 90, "acid" = 10) //Armor for the item, dosnt transfer to user + armor = list(MELEE = 95, BULLET = 95, LASER = 75, ENERGY = 60, BOMB = 90, BIO = 90, RAD = 0, FIRE = 90, ACID = 10) //Armor for the item, dosnt transfer to user item_state = "metal" icon_state = "metal" force = 16 @@ -555,7 +561,7 @@ var/active = 0 var/clumsy_check = TRUE -/obj/item/shield/energy/Initialize() +/obj/item/shield/energy/Initialize(mapload) . = ..() icon_state = "[base_icon_state]0" diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm index ced0ee3160..989cc5a73e 100644 --- a/code/game/objects/items/shooting_range.dm +++ b/code/game/objects/items/shooting_range.dm @@ -34,6 +34,7 @@ /obj/item/target/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(pinnedLoc) pinnedLoc.removeTarget(user) + . = ..() /obj/item/target/syndicate icon_state = "target_s" diff --git a/code/game/objects/items/singularityhammer.dm b/code/game/objects/items/singularityhammer.dm index e58dbc23ce..b9d66a5bd0 100644 --- a/code/game/objects/items/singularityhammer.dm +++ b/code/game/objects/items/singularityhammer.dm @@ -10,7 +10,7 @@ throwforce = 15 throw_range = 1 w_class = WEIGHT_CLASS_HUGE - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 0, BOMB = 50, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) resistance_flags = FIRE_PROOF | ACID_PROOF force_string = "LORD SINGULOTH HIMSELF" total_mass = TOTAL_MASS_MEDIEVAL_WEAPON @@ -97,7 +97,7 @@ total_mass = TOTAL_MASS_MEDIEVAL_WEAPON var/wielded = FALSE // track wielded status on item -/obj/item/mjollnir/Initialize() +/obj/item/mjollnir/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield) RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield) diff --git a/code/game/objects/items/spear.dm b/code/game/objects/items/spear.dm index f40c774551..14fb5062ad 100644 --- a/code/game/objects/items/spear.dm +++ b/code/game/objects/items/spear.dm @@ -17,7 +17,7 @@ attack_verb = list("attacked", "poked", "jabbed", "torn", "gored") sharpness = SHARP_EDGED max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) var/obj/item/grenade/explosive = null var/war_cry = "AAAAARGH!!!" var/icon_prefix = "spearglass" @@ -25,7 +25,7 @@ wound_bonus = -15 bare_wound_bonus = 15 -/obj/item/spear/Initialize() +/obj/item/spear/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield) RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield) diff --git a/code/game/objects/items/stacks/bscrystal.dm b/code/game/objects/items/stacks/bscrystal.dm index 3b4be37cee..125065c83e 100644 --- a/code/game/objects/items/stacks/bscrystal.dm +++ b/code/game/objects/items/stacks/bscrystal.dm @@ -18,7 +18,7 @@ points = 0 refined_type = null -/obj/item/stack/ore/bluespace_crystal/Initialize() +/obj/item/stack/ore/bluespace_crystal/Initialize(mapload) . = ..() pixel_x = rand(-5, 5) pixel_y = rand(-5, 5) diff --git a/code/game/objects/items/stacks/license_plates.dm b/code/game/objects/items/stacks/license_plates.dm new file mode 100644 index 0000000000..06dc86ee61 --- /dev/null +++ b/code/game/objects/items/stacks/license_plates.dm @@ -0,0 +1,30 @@ +/obj/item/stack/license_plates + name = "invalid plate" + desc = "someone fucked up" + icon = 'icons/obj/machines/prison.dmi' + icon_state = "empty_plate" + novariants = FALSE + max_amount = 50 + +/obj/item/stack/license_plates/empty + name = "empty license plate" + desc = "Instead of a license plate number, this could contain a quote like \"Live laugh love\"." + +/obj/item/stack/license_plates/empty/fifty + amount = 50 + +/obj/item/stack/license_plates/filled + name = "license plate" + desc = "Prison labor paying off." + icon_state = "filled_plate_1_1" + +///Override to allow for variations +/obj/item/stack/license_plates/filled/update_icon_state() + if(novariants) + return + if(amount <= (max_amount * (1/3))) + icon_state = "filled_plate_[rand(1,6)]_1" + else if (amount <= (max_amount * (2/3))) + icon_state = "filled_plate_[rand(1,6)]_2" + else + icon_state = "filled_plate_[rand(1,6)]_3" diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index f888927411..15bd521834 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -342,7 +342,7 @@ /obj/item/stack/medical/mesh/advanced/one amount = 1 -/obj/item/stack/medical/mesh/Initialize() +/obj/item/stack/medical/mesh/Initialize(mapload) . = ..() if(amount == max_amount) //only seal full mesh packs is_open = FALSE @@ -488,6 +488,9 @@ icon_state = "nanogel" var/being_applied = FALSE //No doafter stacking. +/obj/item/stack/medical/nanogel/one + amount = 1 + /obj/item/stack/medical/nanogel/try_heal(mob/living/M, mob/user, silent = FALSE) if(being_applied) to_chat(user, "You are already applying [src]!") diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index c6763092ca..08f0a6fb7f 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -3,6 +3,7 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \ new/datum/stack_recipe("table frame", /obj/structure/table_frame, 2, time = 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("scooter frame", /obj/item/scooter_frame, 10, time = 25, one_per_turf = 0), \ new/datum/stack_recipe("railing", /obj/structure/railing, 3, time = 18, window_checks = TRUE), \ + new/datum/stack_recipe("catwalk tile", /obj/item/stack/tile/catwalk, 1, 4, 20), \ )) /obj/item/stack/rods diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 6b1220743f..bea05f6ef1 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -13,8 +13,8 @@ * Glass sheets */ GLOBAL_LIST_INIT(glass_recipes, list ( \ - new/datum/stack_recipe("directional window", /obj/structure/window/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ - new/datum/stack_recipe("fulltile window", /obj/structure/window/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("directional window", /obj/structure/window/unanchored, time = 10, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("fulltile window", /obj/structure/window/fulltile/unanchored, 2, time = 20, on_floor = TRUE, window_checks = TRUE), \ null, \ new/datum/stack_recipe_list("glass working bases", list( \ new/datum/stack_recipe("chem dish", /obj/item/glasswork/glass_base/dish, 10), \ @@ -22,8 +22,8 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ new/datum/stack_recipe("spout flask", /obj/item/glasswork/glass_base/spouty, 20), \ new/datum/stack_recipe("small bulb flask", /obj/item/glasswork/glass_base/flask_small, 5), \ new/datum/stack_recipe("large bottle flask", /obj/item/glasswork/glass_base/flask_large, 15), \ - new/datum/stack_recipe("tea cup", /obj/item/glasswork/glass_base/tea_plate, 5), \ - new/datum/stack_recipe("tea plate", /obj/item/glasswork/glass_base/tea_cup, 5), \ + new/datum/stack_recipe("tea cup", /obj/item/glasswork/glass_base/tea_cup, 5), \ + new/datum/stack_recipe("tea plate", /obj/item/glasswork/glass_base/tea_plate, 5), \ )), \ )) @@ -34,7 +34,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ icon_state = "sheet-glass" item_state = "sheet-glass" custom_materials = list(/datum/material/glass=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/glass grind_results = list(/datum/reagent/silicon = 20) @@ -95,8 +95,8 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ GLOBAL_LIST_INIT(pglass_recipes, list ( \ - new/datum/stack_recipe("directional window", /obj/structure/window/plasma/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ - new/datum/stack_recipe("fulltile window", /obj/structure/window/plasma/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ + new/datum/stack_recipe("directional window", /obj/structure/window/plasma/unanchored, time = 10, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("fulltile window", /obj/structure/window/plasma/fulltile/unanchored, 2, time = 20, on_floor = TRUE, window_checks = TRUE) \ )) /obj/item/stack/sheet/plasmaglass @@ -106,7 +106,7 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \ icon_state = "sheet-pglass" item_state = "sheet-pglass" custom_materials = list(/datum/material/plasma=MINERAL_MATERIAL_AMOUNT * 0.5, /datum/material/glass=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 75, ACID = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmaglass grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10) @@ -147,10 +147,10 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \ * Reinforced glass sheets */ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ - new/datum/stack_recipe("windoor frame", /obj/structure/windoor_assembly, 5, time = 0, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("windoor frame", /obj/structure/windoor_assembly, 5, time = 20, on_floor = TRUE, window_checks = TRUE), \ null, \ - new/datum/stack_recipe("directional reinforced window", /obj/structure/window/reinforced/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ - new/datum/stack_recipe("fulltile reinforced window", /obj/structure/window/reinforced/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ + new/datum/stack_recipe("directional reinforced window", /obj/structure/window/reinforced/unanchored, time = 10, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("fulltile reinforced window", /obj/structure/window/reinforced/fulltile/unanchored, 2, time = 20, on_floor = TRUE, window_checks = TRUE) \ )) @@ -161,7 +161,7 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ icon_state = "sheet-rglass" item_state = "sheet-rglass" custom_materials = list(/datum/material/iron=MINERAL_MATERIAL_AMOUNT * 0.5, /datum/material/glass=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 70, ACID = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/rglass grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/iron = 10) @@ -198,8 +198,8 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ . += GLOB.reinforced_glass_recipes GLOBAL_LIST_INIT(prglass_recipes, list ( \ - new/datum/stack_recipe("directional reinforced window", /obj/structure/window/plasma/reinforced/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ - new/datum/stack_recipe("fulltile reinforced window", /obj/structure/window/plasma/reinforced/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ + new/datum/stack_recipe("directional reinforced window", /obj/structure/window/plasma/reinforced/unanchored, time = 10, on_floor = TRUE, window_checks = TRUE), \ + new/datum/stack_recipe("fulltile reinforced window", /obj/structure/window/plasma/reinforced/fulltile/unanchored, 2, time = 20, on_floor = TRUE, window_checks = TRUE) \ )) /obj/item/stack/sheet/plasmarglass @@ -209,7 +209,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ icon_state = "sheet-prglass" item_state = "sheet-prglass" custom_materials = list(/datum/material/plasma=MINERAL_MATERIAL_AMOUNT * 0.5, /datum/material/glass=MINERAL_MATERIAL_AMOUNT, /datum/material/iron=MINERAL_MATERIAL_AMOUNT * 0.5,) - armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + armor = list(MELEE = 20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmarglass grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10, /datum/reagent/iron = 10) @@ -226,7 +226,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ S.efficiency *= 1.2 GLOBAL_LIST_INIT(titaniumglass_recipes, list( - new/datum/stack_recipe("shuttle window", /obj/structure/window/shuttle/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) + new/datum/stack_recipe("shuttle window", /obj/structure/window/shuttle/unanchored, 2, time = 20, on_floor = TRUE, window_checks = TRUE) )) /obj/item/stack/sheet/titaniumglass @@ -236,7 +236,7 @@ GLOBAL_LIST_INIT(titaniumglass_recipes, list( icon_state = "sheet-titaniumglass" item_state = "sheet-titaniumglass" custom_materials = list(/datum/material/titanium=MINERAL_MATERIAL_AMOUNT * 0.5, /datum/material/glass=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/titaniumglass shard_type = /obj/item/shard @@ -250,7 +250,7 @@ GLOBAL_LIST_INIT(titaniumglass_recipes, list( S.efficiency *= 1.5 GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( - new/datum/stack_recipe("plastitanium window", /obj/structure/window/plastitanium/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) + new/datum/stack_recipe("plastitanium window", /obj/structure/window/plastitanium/unanchored, 2, time = 20, on_floor = TRUE, window_checks = TRUE) )) /obj/item/stack/sheet/plastitaniumglass @@ -260,7 +260,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( icon_state = "sheet-plastitaniumglass" item_state = "sheet-plastitaniumglass" custom_materials = list(/datum/material/titanium=MINERAL_MATERIAL_AMOUNT * 0.5, /datum/material/plasma=MINERAL_MATERIAL_AMOUNT * 0.5, /datum/material/glass=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plastitaniumglass shard_type = /obj/item/shard @@ -291,7 +291,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( attack_verb = list("stabbed", "slashed", "sliced", "cut") hitsound = 'sound/weapons/bladeslice.ogg' resistance_flags = ACID_PROOF - armor = list("melee" = 100, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) + armor = list(MELEE = 100, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 100) max_integrity = 40 sharpness = SHARP_EDGED var/icon_prefix @@ -303,7 +303,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( return (BRUTELOSS) -/obj/item/shard/Initialize() +/obj/item/shard/Initialize(mapload) . = ..() AddComponent(/datum/component/caltrop, force) AddComponent(/datum/component/butchering, 150, 65) @@ -355,7 +355,19 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( /obj/item/shard/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/lightreplacer)) - I.attackby(src, user) + var/obj/item/lightreplacer/L = I + L.attackby(src, user) + else if(istype(I, /obj/item/stack/sheet/cloth)) + var/obj/item/stack/sheet/cloth/C = I + to_chat(user, "You begin to wrap the [C] around the [src]...") + if(do_after(user, 35, target = src)) + var/obj/item/kitchen/knife/shiv/S = new /obj/item/kitchen/knife/shiv + C.use(1) + to_chat(user, "You wrap the [C] around the [src] forming a makeshift weapon.") + remove_item_from_storage(src) + qdel(src) + user.put_in_hands(S) + else return ..() diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index b2bd394a53..eaf576510e 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -27,7 +27,6 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \ new/datum/stack_recipe("pile of dirt", /obj/machinery/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("aesthetic volcanic floor tile", /obj/item/stack/tile/basalt, 2, 2, 4, 20), \ - new/datum/stack_recipe("Assistant Statue", /obj/structure/statue/sandstone/assistant, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("Breakdown into sand", /obj/item/stack/ore/glass, 1, one_per_turf = 0, on_floor = 1) \ )) @@ -114,9 +113,6 @@ GLOBAL_LIST_INIT(sandbag_recipes, list ( \ GLOBAL_LIST_INIT(diamond_recipes, list ( \ new/datum/stack_recipe("diamond door", /obj/structure/mineral_door/transparent/diamond, 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("diamond tile", /obj/item/stack/tile/mineral/diamond, 1, 4, 20), \ - new/datum/stack_recipe("Captain Statue", /obj/structure/statue/diamond/captain, 5, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("AI Hologram Statue", /obj/structure/statue/diamond/ai1, 5, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("AI Core Statue", /obj/structure/statue/diamond/ai2, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("diamond ingot", /obj/item/ingot/diamond, 6, time = 100), \ )) @@ -144,8 +140,6 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \ GLOBAL_LIST_INIT(uranium_recipes, list ( \ new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("uranium tile", /obj/item/stack/tile/mineral/uranium, 1, 4, 20), \ - new/datum/stack_recipe("Nuke Statue", /obj/structure/statue/uranium/nuke, 5, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("Engineer Statue", /obj/structure/statue/uranium/eng, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("uranium ingot", /obj/item/ingot/uranium, 6, time = 100), \ )) @@ -178,7 +172,6 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \ GLOBAL_LIST_INIT(plasma_recipes, list ( \ new/datum/stack_recipe("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("plasma tile", /obj/item/stack/tile/mineral/plasma, 1, 4, 20), \ - new/datum/stack_recipe("Scientist Statue", /obj/structure/statue/plasma/scientist, 5, one_per_turf = 1, on_floor = 1), \ // new/datum/stack_recipe("plasma ingot", /obj/item/ingot/plasma, 6, time = 100), \ no )) @@ -218,12 +211,7 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \ GLOBAL_LIST_INIT(gold_recipes, list ( \ new/datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("gold tile", /obj/item/stack/tile/mineral/gold, 1, 4, 20), \ - new/datum/stack_recipe("HoS Statue", /obj/structure/statue/gold/hos, 5, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("HoP Statue", /obj/structure/statue/gold/hop, 5, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("CE Statue", /obj/structure/statue/gold/ce, 5, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("RD Statue", /obj/structure/statue/gold/rd, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("Simple Crown", /obj/item/clothing/head/crown, 5), \ - new/datum/stack_recipe("CMO Statue", /obj/structure/statue/gold/cmo, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("gold ingot", /obj/item/ingot/gold, 6, time = 100), \ )) @@ -251,11 +239,6 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \ GLOBAL_LIST_INIT(silver_recipes, list ( \ new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("silver tile", /obj/item/stack/tile/mineral/silver, 1, 4, 20), \ - new/datum/stack_recipe("Med Officer Statue", /obj/structure/statue/silver/md, 5, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("Janitor Statue", /obj/structure/statue/silver/janitor, 5, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("Sec Officer Statue", /obj/structure/statue/silver/sec, 5, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("Sec Borg Statue", /obj/structure/statue/silver/secborg, 5, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("Med Borg Statue", /obj/structure/statue/silver/medborg, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("silver ingot", /obj/item/ingot/silver, 6, time = 100), \ )) @@ -282,7 +265,6 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \ GLOBAL_LIST_INIT(bananium_recipes, list ( \ new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \ - new/datum/stack_recipe("Clown Statue", /obj/structure/statue/bananium/clown, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("hilarious ingot", /obj/item/ingot/bananium, 6, time = 100), \ )) diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 15153521ed..43ed3b9213 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -24,6 +24,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ new/datum/stack_recipe("stool", /obj/structure/chair/stool, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("bar stool", /obj/structure/chair/stool/bar, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("bed", /obj/structure/bed, 2, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("double bed", /obj/structure/bed/double, 4, one_per_turf = TRUE, on_floor = TRUE), \ //CIT CHANGE - adds sofas to metal recipe list new/datum/stack_recipe_list("sofas", list( \ new /datum/stack_recipe("sofa (middle)", /obj/structure/chair/sofa, one_per_turf = TRUE, on_floor = TRUE), \ @@ -211,7 +212,7 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \ custom_materials = list(/datum/material/iron=MINERAL_MATERIAL_AMOUNT, /datum/material/plasma=MINERAL_MATERIAL_AMOUNT) throwforce = 10 flags_1 = CONDUCT_1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 80) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 80) resistance_flags = FIRE_PROOF merge_type = /obj/item/stack/sheet/plasteel grind_results = list(/datum/reagent/iron = 20, /datum/reagent/toxin/plasma = 20) @@ -290,7 +291,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ icon = 'icons/obj/stack_objects.dmi' custom_materials = list(/datum/material/wood=MINERAL_MATERIAL_AMOUNT) sheettype = "wood" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 0) resistance_flags = FLAMMABLE merge_type = /obj/item/stack/sheet/mineral/wood novariants = TRUE @@ -305,7 +306,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ "You begin whittling [src] into a sharp point at one end.", \ "You hear wood carving.") // 8 Second Timer - if(!do_after(user, 80, TRUE, src)) + if(!do_after(user, 8 SECONDS, src)) return // Make Stake var/obj/item/stake/basic/new_item = new(user.loc) @@ -354,7 +355,7 @@ GLOBAL_LIST_INIT(bamboo_recipes, list ( \ icon = 'icons/obj/stack_objects.dmi' custom_materials = list(/datum/material/bamboo = MINERAL_MATERIAL_AMOUNT) throwforce = 15 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 0) resistance_flags = FLAMMABLE merge_type = /obj/item/stack/sheet/mineral/bamboo grind_results = list(/datum/reagent/cellulose = 10) @@ -396,6 +397,7 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ new/datum/stack_recipe("rag", /obj/item/reagent_containers/rag, 1), \ new/datum/stack_recipe("towel", /obj/item/reagent_containers/rag/towel, 3), \ new/datum/stack_recipe("bedsheet", /obj/item/bedsheet, 3), \ + new/datum/stack_recipe("double bedsheet", /obj/item/bedsheet/double, 6), \ new/datum/stack_recipe("empty sandbag", /obj/item/emptysandbag, 4), \ new/datum/stack_recipe("padded floor tile", /obj/item/stack/tile/padded, 1, 4, 20), \ null, \ @@ -502,6 +504,8 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \ new /datum/stack_recipe("sterile masks box", /obj/item/storage/box/masks), \ new /datum/stack_recipe("body bag box", /obj/item/storage/box/bodybags), \ new /datum/stack_recipe("prescription glasses box", /obj/item/storage/box/rxglasses), \ + new /datum/stack_recipe("oxygen tank box", /obj/item/storage/box/emergencytank), \ + new /datum/stack_recipe("extended oxygen tank box", /obj/item/storage/box/engitank), \ null, \ new /datum/stack_recipe("disk box", /obj/item/storage/box/disks), \ new /datum/stack_recipe("light tubes box", /obj/item/storage/box/lights/tubes), \ @@ -759,7 +763,8 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \ GLOBAL_LIST_INIT(bone_recipes, list( new /datum/stack_recipe("Bone Dagger", /obj/item/kitchen/knife/combat/bone, 2, time = 20), \ new /datum/stack_recipe("Skull Helmet", /obj/item/clothing/head/helmet/skull, 4, time = 30), \ - new /datum/stack_recipe("Bone Armor", /obj/item/clothing/suit/armor/bone, 6, time = 30))) + new /datum/stack_recipe("Bone Armor", /obj/item/clothing/suit/armor/bone, 6, time = 30),\ + new /datum/stack_recipe("Processable Bone", /obj/item/ingot/bone, 2, time = 20))) /obj/item/stack/sheet/bone name = "bones" @@ -793,7 +798,7 @@ GLOBAL_LIST_INIT(plastic_recipes, list( new /datum/stack_recipe("water bottle", /obj/item/reagent_containers/glass/beaker/waterbottle/empty), \ new /datum/stack_recipe("large water bottle", /obj/item/reagent_containers/glass/beaker/waterbottle/large/empty,3), \ new /datum/stack_recipe("shower curtain", /obj/structure/curtain, 10, time = 10, one_per_turf = 1, on_floor = 1), \ - new /datum/stack_recipe("duct", /obj/item/stack/ducts,1), \ + new /datum/stack_recipe("duct", /obj/item/stack/ducts, 1, 5, 50), \ new /datum/stack_recipe("laser pointer case", /obj/item/glasswork/glass_base/laserpointer_shell, 30), \ new /datum/stack_recipe("wet floor sign", /obj/item/clothing/suit/caution, 2))) diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 266d8b7b86..b2cd0f481b 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -514,44 +514,3 @@ /obj/item/stack/microwave_act(obj/machinery/microwave/M) if(istype(M) && M.dirty < 100) M.dirty += amount - -/* - * Recipe datum - */ -/datum/stack_recipe - var/title = "ERROR" - var/result_type - var/req_amount = 1 - var/res_amount = 1 - var/max_res_amount = 1 - var/time = 0 - var/one_per_turf = FALSE - var/on_floor = FALSE - var/placement_checks = FALSE - var/applies_mats = FALSE - var/trait_booster = null - var/trait_modifier = 1 - -/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1,time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE, placement_checks = FALSE, applies_mats = FALSE, trait_booster = null, trait_modifier = 1) - src.title = title - src.result_type = result_type - src.req_amount = req_amount - src.res_amount = res_amount - src.max_res_amount = max_res_amount - src.time = time - src.one_per_turf = one_per_turf - src.on_floor = on_floor - src.placement_checks = placement_checks - src.applies_mats = applies_mats - src.trait_booster = trait_booster - src.trait_modifier = trait_modifier -/* - * Recipe list datum - */ -/datum/stack_recipe_list - var/title = "ERROR" - var/list/recipes - -/datum/stack_recipe_list/New(title, recipes) - src.title = title - src.recipes = recipes diff --git a/code/game/objects/items/stacks/stack_recipe.dm b/code/game/objects/items/stacks/stack_recipe.dm new file mode 100644 index 0000000000..b8cbfe3b61 --- /dev/null +++ b/code/game/objects/items/stacks/stack_recipe.dm @@ -0,0 +1,69 @@ + +/* + * Recipe datum + */ +/datum/stack_recipe + /// The title of the recipe + var/title = "ERROR" + /// What atom the recipe makes, typepath + var/atom/result_type + /// Amount of stack required to make + var/req_amount = 1 + /// Amount of resulting atoms made + var/res_amount = 1 + /// Max amount of resulting atoms made + var/max_res_amount = 1 + /// How long it takes to make + var/time = 0 + /// If only one of the resulting atom is allowed per turf + var/one_per_turf = FALSE + /// If the atom requires a floor below + var/on_floor = FALSE + /// Bitflag of additional placement checks required to place. (STACK_CHECK_CARDINALS|STACK_CHECK_ADJACENT) + var/placement_checks = NONE + /// If TRUE, the created atom will gain custom mat datums + var/applies_mats = FALSE + /// What trait, if any, boosts the construction speed of this item + var/trait_booster + /// How much the trait above, if supplied, boosts the construct speed of this item + var/trait_modifier = 1 + +/datum/stack_recipe/New( + title, + result_type, + req_amount = 1, + res_amount = 1, + max_res_amount = 1, + time = 0, + one_per_turf = FALSE, + on_floor = FALSE, + window_checks = FALSE, + placement_checks = NONE, + applies_mats = FALSE, + trait_booster, + trait_modifier = 1, +) + + src.title = title + src.result_type = result_type + src.req_amount = req_amount + src.res_amount = res_amount + src.max_res_amount = max_res_amount + src.time = time + src.one_per_turf = one_per_turf + src.on_floor = on_floor + src.placement_checks = placement_checks + src.applies_mats = applies_mats + src.trait_booster = trait_booster + src.trait_modifier = trait_modifier + +/* + * Recipe list datum + */ +/datum/stack_recipe_list + var/title = "ERROR" + var/list/recipes + +/datum/stack_recipe_list/New(title, recipes) + src.title = title + src.recipes = recipes diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 8b272f98b4..588e066a41 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -530,7 +530,7 @@ flags_1 = CONDUCT_1 turf_type = /turf/open/floor/plasteel mineralType = "metal" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 70) resistance_flags = FIRE_PROOF /obj/item/stack/tile/plasteel/cyborg @@ -555,3 +555,10 @@ color = "#92661A" turf_type = /turf/open/floor/bronze custom_materials = list(/datum/material/bronze = 250) + +/obj/item/stack/tile/catwalk + name = "catwalk tile" + singular_name = "catwalk floor tile" + desc = "Flooring that shows its contents underneath. Engineers love it!" + icon_state = "catwalk_tile" + turf_type = /turf/open/floor/catwalk_floor diff --git a/code/game/objects/items/stacks/wrap.dm b/code/game/objects/items/stacks/wrap.dm index 6ae63e640f..c969e2d1d4 100644 --- a/code/game/objects/items/stacks/wrap.dm +++ b/code/game/objects/items/stacks/wrap.dm @@ -20,6 +20,9 @@ if(QDELETED(src) && !transfer) new /obj/item/c_tube(T) +/obj/item/stack/wrapping_paper/small + desc = "Wrap packages with this festive paper to make gifts. This roll looks a bit skimpy." + amount = 10 /* * Package Wrap @@ -121,6 +124,11 @@ if(QDELETED(src) && !transfer) new /obj/item/c_tube(T) +/obj/item/stack/packageWrap/small + desc = "You can use this to wrap items in. This roll looks a bit skimpy." + w_class = WEIGHT_CLASS_SMALL + amount = 5 + /obj/item/c_tube name = "cardboard tube" desc = "A tube... of cardboard." diff --git a/code/game/objects/items/storage/_storage.dm b/code/game/objects/items/storage/_storage.dm index 2fc1b6484d..cbaa1775eb 100644 --- a/code/game/objects/items/storage/_storage.dm +++ b/code/game/objects/items/storage/_storage.dm @@ -8,7 +8,7 @@ /obj/item/storage/get_dumping_location(obj/item/storage/source,mob/user) return src -/obj/item/storage/Initialize() +/obj/item/storage/Initialize(mapload) . = ..() PopulateContents() @@ -18,10 +18,10 @@ /obj/item/storage/AllowDrop() return TRUE -/obj/item/storage/contents_explosion(severity, target) +/obj/item/storage/contents_explosion(severity, target, origin) var/in_storage = istype(loc, /obj/item/storage)? (max(0, severity - 1)) : (severity) for(var/atom/A in contents) - A.ex_act(in_storage, target) + A.ex_act(in_storage, target, origin) CHECK_TICK //Cyberboss says: "USE THIS TO FILL IT, NOT INITIALIZE OR NEW" diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index f10167890a..dcacd00fe2 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -44,7 +44,7 @@ item_state = "holdingpack" resistance_flags = FIRE_PROOF item_flags = NO_MAT_REDEMPTION - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 60, ACID = 50) component_type = /datum/component/storage/concrete/bluespace/bag_of_holding rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE @@ -53,7 +53,6 @@ desc = "A satchel that opens into a localized pocket of Blue Space." icon_state = "holdingsat" item_state = "holdingsat" - species_exception = list(/datum/species/angel) /obj/item/storage/backpack/holding/duffel name = "duffel bag of holding" @@ -190,7 +189,6 @@ name = "satchel" desc = "A trendy looking satchel." icon_state = "satchel-norm" - species_exception = list(/datum/species/angel) //satchels can be equipped since they are on the side, not back /obj/item/storage/backpack/satchel/leather name = "leather satchel" @@ -259,8 +257,8 @@ /obj/item/storage/backpack/satchel/bone name = "bone satchel" desc = "A grotesque satchel made of sinews and bones." - icon = 'icons/obj/mining.dmi' - icon_state = "goliath_saddle" + icon_state = "satchel-bone" + item_state = "satchel-bone" slot_flags = ITEM_SLOT_BACK /obj/item/storage/backpack/satchel/bone/ComponentInitialize() @@ -285,7 +283,7 @@ level = 1 component_type = /datum/component/storage/concrete/secret_satchel -/obj/item/storage/backpack/satchel/flat/Initialize() +/obj/item/storage/backpack/satchel/flat/Initialize(mapload) . = ..() SSpersistence.new_secret_satchels += src @@ -318,7 +316,7 @@ var/list/reward_all_of_these = list() //use paths! var/revealed = FALSE -/obj/item/storage/backpack/satchel/flat/secret/Initialize() +/obj/item/storage/backpack/satchel/flat/secret/Initialize(mapload) . = ..() if(isfloorturf(loc) && !isplatingturf(loc)) @@ -359,8 +357,69 @@ item_state = "duffel-med" /obj/item/storage/backpack/duffelbag/med/surgery - name = "surgical duffel bag" - desc = "A large duffel bag for holding extra medical supplies - this one seems to be designed for holding surgical tools." + name = "surgical tools case" + desc = "A large plastic case for holding surgical tools or most other medical supplies you could imagine." + icon_state = "firstaid-surgery" + item_state = "firstaid" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + slot_flags = NONE + +/obj/item/storage/backpack/duffelbag/med/surgery/ComponentInitialize() + . = ..() + var/datum/component/storage/STR = GetComponent(/datum/component/storage) + var/static/list/can_hold = typecacheof(list( + /obj/item/healthanalyzer, + /obj/item/dnainjector, + /obj/item/reagent_containers/dropper, + /obj/item/reagent_containers/glass/beaker, + /obj/item/reagent_containers/glass/bottle, + /obj/item/reagent_containers/pill, + /obj/item/reagent_containers/syringe, + /obj/item/reagent_containers/medspray, + /obj/item/lighter, + /obj/item/storage/fancy/cigarettes, + /obj/item/storage/pill_bottle, + /obj/item/stack/medical, + /obj/item/flashlight/pen, + /obj/item/extinguisher/mini, + /obj/item/reagent_containers/hypospray, + /obj/item/hypospray/mkii, + /obj/item/sensor_device, + /obj/item/radio, + /obj/item/clothing/gloves/, + /obj/item/lazarus_injector, + /obj/item/bikehorn/rubberducky, + /obj/item/clothing/mask/surgical, + /obj/item/clothing/mask/breath, + /obj/item/clothing/mask/breath/medical, + /obj/item/surgical_drapes, + /obj/item/scalpel, + /obj/item/circular_saw, + /obj/item/bonesetter, + /obj/item/surgicaldrill, + /obj/item/retractor, + /obj/item/cautery, + /obj/item/hemostat, + /obj/item/geiger_counter, + /obj/item/clothing/neck/stethoscope, + /obj/item/stamp, + /obj/item/clothing/glasses, + /obj/item/wrench/medical, + /obj/item/clothing/mask/muzzle, + /obj/item/storage/bag/chemistry, + /obj/item/storage/bag/bio, + /obj/item/reagent_containers/blood, + /obj/item/tank/internals/emergency_oxygen, + /obj/item/gun/syringe/syndicate, + /obj/item/implantcase, + /obj/item/implant, + /obj/item/implanter, + /obj/item/pinpointer/crew, + /obj/item/reagent_containers/chem_pack, + /obj/item/stack/sticky_tape + )) + STR.can_hold = can_hold /obj/item/storage/backpack/duffelbag/med/surgery/PopulateContents() new /obj/item/scalpel(src) @@ -370,6 +429,7 @@ new /obj/item/surgicaldrill(src) new /obj/item/cautery(src) new /obj/item/bonesetter(src) + new /obj/item/stack/medical/bone_gel(src) new /obj/item/surgical_drapes(src) new /obj/item/clothing/mask/surgical(src) new /obj/item/reagent_containers/medspray/sterilizine(src) @@ -657,3 +717,9 @@ desc = "Worn by snails as armor and storage compartment." icon_state = "snailshell" item_state = "snailshell" + +/obj/item/storage/backpack/henchmen + name = "wings" + desc = "Granted to the henchmen who deserve it. This probably doesn't include you." + icon_state = "henchmen" + item_state = "henchmen" diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index cb619a711b..56ad6c2534 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -108,7 +108,7 @@ desc = "This little bugger can be used to store and transport ores." icon = 'icons/obj/mining.dmi' icon_state = "satchel" - slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_POCKET + slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_POCKETS w_class = WEIGHT_CLASS_NORMAL component_type = /datum/component/storage/concrete/stack var/spam_protection = FALSE //If this is TRUE, the holder won't receive any messages when they fail to pick up ore through crossing it @@ -317,7 +317,7 @@ * Trays - Agouri */ /obj/item/storage/bag/tray - name = "tray" + name = "serving tray" icon = 'icons/obj/food/containers.dmi' icon_state = "tray" desc = "A metal tray to lay food on." @@ -377,6 +377,12 @@ . = ..() update_icon() +/obj/item/storage/bag/tray/cafeteria + name = "cafeteria tray" + icon = 'icons/obj/food/containers.dmi' + icon_state = "foodtray" + desc = "A cheap metal tray to pile today's meal onto." + //bluespace tray, holds more items /obj/item/storage/bag/tray/bluespace name = "bluespace tray" @@ -394,7 +400,7 @@ icon = 'icons/obj/chemical.dmi' icon_state = "bag" desc = "A bag for storing pills, patches, and bottles." - slot_flags = ITEM_SLOT_BELT|ITEM_SLOT_POCKET + slot_flags = ITEM_SLOT_BELT|ITEM_SLOT_POCKETS resistance_flags = FLAMMABLE /obj/item/storage/bag/chemistry/ComponentInitialize() @@ -414,7 +420,7 @@ icon = 'icons/obj/chemical.dmi' icon_state = "biobag" desc = "A bag for the safe transportation and disposal of biowaste and other biological materials." - slot_flags = ITEM_SLOT_BELT|ITEM_SLOT_POCKET + slot_flags = ITEM_SLOT_BELT|ITEM_SLOT_POCKETS resistance_flags = FLAMMABLE /obj/item/storage/bag/bio/ComponentInitialize() @@ -445,7 +451,7 @@ desc = "A pouch for your ammo that goes in your pocket." icon = 'icons/obj/items_and_weapons.dmi' icon_state = "ammopouch" - slot_flags = ITEM_SLOT_POCKET + slot_flags = ITEM_SLOT_POCKETS w_class = WEIGHT_CLASS_BULKY resistance_flags = FLAMMABLE @@ -466,7 +472,7 @@ Bag for holding materials desc = "A pouch for sheets and RCD ammunition that manages to hang where you would normally put things in your pocket." icon = 'icons/obj/items_and_weapons.dmi' icon_state = "materialpouch" - slot_flags = ITEM_SLOT_POCKET + slot_flags = ITEM_SLOT_POCKETS w_class = WEIGHT_CLASS_BULKY resistance_flags = FLAMMABLE diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 9c3d776b56..f4fa638f7f 100755 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -28,7 +28,7 @@ for(var/obj/item/I in contents) . += I.get_worn_belt_overlay(icon_file) -/obj/item/storage/belt/Initialize() +/obj/item/storage/belt/Initialize(mapload) . = ..() update_icon() @@ -290,6 +290,7 @@ /obj/item/stack/ore, /obj/item/reagent_containers/food/drinks, /obj/item/organ/regenerative_core, + /obj/item/hivelordstabilizer, /obj/item/wormhole_jaunter, /obj/item/storage/bag/plants, /obj/item/stack/marker_beacon @@ -312,7 +313,7 @@ /obj/item/storage/belt/mining/primitive/ComponentInitialize() . = ..() var/datum/component/storage/STR = GetComponent(/datum/component/storage) - STR.max_items = 5 + STR.max_items = 8 /obj/item/storage/belt/soulstone name = "soul stone belt" @@ -366,7 +367,7 @@ /obj/item/storage/belt/military/snack name = "tactical snack rig" -/obj/item/storage/belt/military/snack/Initialize() +/obj/item/storage/belt/military/snack/Initialize(mapload) . = ..() var/sponsor = pick("DonkCo", "Waffle Co.", "Roffle Co.", "Gorlax Marauders", "Tiger Cooperative") desc = "A set of snack-tical webbing worn by athletes of the [sponsor] VR sports division." diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index 476f35fe4c..3a8f5a5cc8 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -39,7 +39,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", var/deity_name = "Christ" force_string = "holy" -/obj/item/storage/book/bible/Initialize() +/obj/item/storage/book/bible/Initialize(mapload) . = ..() AddComponent(/datum/component/anti_magic, FALSE, TRUE) @@ -73,7 +73,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", var/mob/living/carbon/human/H = usr H.dna.add_mutation(CLOWNMUT) H.dna.add_mutation(SMILE) - H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(H), SLOT_WEAR_MASK) + H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(H), ITEM_SLOT_MASK) GLOB.bible_icon_state = icon_state GLOB.bibleitemstates = item_state diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index ea40b49c5f..a2ab0c2ff4 100644 --- a/code/game/objects/items/storage/boxes.dm +++ b/code/game/objects/items/storage/boxes.dm @@ -102,23 +102,40 @@ new /obj/item/disk/nanite_program(src) // Ordinary survival box +/obj/item/storage/box/survival + name = "survival box" + desc = "A box with the bare essentials of ensuring the survival of you and others." + icon_state = "internals" + illustration = "emergencytank" + var/mask_type = /obj/item/clothing/mask/breath + var/internal_type = /obj/item/tank/internals/emergency_oxygen + var/medipen_type = /obj/item/reagent_containers/hypospray/medipen + /obj/item/storage/box/survival/PopulateContents() - new /obj/item/clothing/mask/breath(src) - new /obj/item/reagent_containers/hypospray/medipen(src) + new mask_type(src) + if(!isnull(medipen_type)) + new medipen_type(src) if(!isplasmaman(loc)) - new /obj/item/tank/internals/emergency_oxygen(src) + new internal_type(src) else new /obj/item/tank/internals/plasmaman/belt(src) + if(HAS_TRAIT(SSstation, STATION_TRAIT_PREMIUM_INTERNALS)) + new /obj/item/flashlight/flare(src) + new /obj/item/radio/off(src) + /obj/item/storage/box/survival/radio/PopulateContents() ..() // we want the survival stuff too. new /obj/item/radio/off(src) -/obj/item/storage/box/survival_mining/PopulateContents() - new /obj/item/clothing/mask/gas/explorer(src) +// Mining survival box +/obj/item/storage/box/survival/mining + mask_type = /obj/item/clothing/mask/gas/explorer + +/obj/item/storage/box/survival/mining/PopulateContents() + ..() new /obj/item/crowbar/red(src) - new /obj/item/reagent_containers/hypospray/medipen(src) if(!isplasmaman(loc)) new /obj/item/tank/internals/emergency_oxygen(src) @@ -126,39 +143,30 @@ new /obj/item/tank/internals/plasmaman/belt(src) // Engineer survival box -/obj/item/storage/box/engineer/PopulateContents() - new /obj/item/clothing/mask/breath(src) - new /obj/item/reagent_containers/hypospray/medipen(src) +/obj/item/storage/box/survival/engineer + name = "extended-capacity survival box" + desc = "A box with the bare essentials of ensuring the survival of you and others. This one is labelled to contain an extended-capacity tank." + illustration = "extendedtank" + internal_type = /obj/item/tank/internals/emergency_oxygen/engi - if(!isplasmaman(loc)) - new /obj/item/tank/internals/emergency_oxygen/engi(src) - else - new /obj/item/tank/internals/plasmaman/belt(src) - -/obj/item/storage/box/engineer/radio/PopulateContents() +/obj/item/storage/box/survival/engineer/radio/PopulateContents() ..() // we want the regular items too. new /obj/item/radio/off(src) // Syndie survival box -/obj/item/storage/box/syndie/PopulateContents() - new /obj/item/clothing/mask/gas/syndicate(src) - - if(!isplasmaman(loc)) - new /obj/item/tank/internals/emergency_oxygen/engi(src) - else - new /obj/item/tank/internals/plasmaman/belt(src) +/obj/item/storage/box/survival/syndie //why is this its own thing if it's just the engi box with a syndie mask and medipen? + name = "extended-capacity survival box" + desc = "A box with the bare essentials of ensuring the survival of you and others. This one is labelled to contain an extended-capacity tank." + illustration = "extendedtank" + mask_type = /obj/item/clothing/mask/gas/syndicate + internal_type = /obj/item/tank/internals/emergency_oxygen/engi + medipen_type = null // Security survival box -/obj/item/storage/box/security/PopulateContents() - new /obj/item/clothing/mask/gas/sechailer(src) - new /obj/item/reagent_containers/hypospray/medipen(src) +/obj/item/storage/box/survival/security + mask_type = /obj/item/clothing/mask/gas/sechailer - if(!isplasmaman(loc)) - new /obj/item/tank/internals/emergency_oxygen(src) - else - new /obj/item/tank/internals/plasmaman/belt(src) - -/obj/item/storage/box/security/radio/PopulateContents() +/obj/item/storage/box/survival/security/radio/PopulateContents() ..() // we want the regular stuff too new /obj/item/radio/off(src) @@ -769,6 +777,10 @@ else new /obj/item/tank/internals/plasmaman/belt(src) + if(HAS_TRAIT(SSstation, STATION_TRAIT_PREMIUM_INTERNALS)) + new /obj/item/flashlight/flare(src) + new /obj/item/radio/off(src) + /obj/item/storage/box/rubbershot name = "box of rubber shots" desc = "A box full of rubber shots, designed for riot shotguns." @@ -952,7 +964,7 @@ illustration = "fruit" var/theme_name -/obj/item/storage/box/ingredients/Initialize() +/obj/item/storage/box/ingredients/Initialize(mapload) . = ..() if(theme_name) name = "[name] ([theme_name])" @@ -1244,6 +1256,26 @@ icon_state = "box_pink" illustration = null +/obj/item/storage/box/emergencytank + name = "emergency oxygen tank box" + desc = "A box of emergency oxygen tanks." + illustration = "emergencytank" + +/obj/item/storage/box/emergencytank/PopulateContents() + ..() + for(var/i in 1 to 7) + new /obj/item/tank/internals/emergency_oxygen(src) //in case anyone ever wants to do anything with spawning them, apart from crafting the box + +/obj/item/storage/box/engitank + name = "extended-capacity emergency oxygen tank box" + desc = "A box of extended-capacity emergency oxygen tanks." + illustration = "extendedtank" + +/obj/item/storage/box/engitank/PopulateContents() + ..() + for(var/i in 1 to 7) + new /obj/item/tank/internals/emergency_oxygen/engi(src) //in case anyone ever wants to do anything with spawning them, apart from crafting the box + /obj/item/storage/box/mre //base MRE type. name = "Nanotrasen MRE Ration Kit Menu 0" desc = "A package containing food suspended in an outdated bluespace pocket which lasts for centuries. If you're lucky you may even be able to enjoy the meal without getting food poisoning." @@ -1255,7 +1287,7 @@ var/expiration_date_min = 2300 var/expiration_date_max = 2700 -/obj/item/storage/box/mre/Initialize() +/obj/item/storage/box/mre/Initialize(mapload) . = ..() if(can_expire) expiration_date = rand(expiration_date_min, expiration_date_max) @@ -1266,9 +1298,9 @@ var/toxic_risk = min(round(spess_current_year - expiration_date * 0.01), 1) for(var/obj/item/reagent_containers/food/snacks/S in contents) if(prob(gross_risk)) - ENABLE_BITFIELD(S.foodtype, GROSS) + S.foodtype |= GROSS if(prob(toxic_risk)) - ENABLE_BITFIELD(S.foodtype, TOXIC) + S.foodtype |= TOXIC /obj/item/storage/box/mre/menu1 name = "\improper Nanotrasen MRE Ration Kit Menu 1" @@ -1424,3 +1456,18 @@ /obj/item/storage/box/strange_seeds_5pack/PopulateContents() for(var/i in 1 to 5) new /obj/item/seeds/random(src) + +/obj/item/storage/box/shipping + name = "box of shipping supplies" + desc = "Contains several scanners and labelers for shipping things. Wrapping Paper not included." + illustration = "shipping" + +/obj/item/storage/box/shipping/PopulateContents() + var/static/items_inside = list( + /obj/item/destTagger=1,\ + /obj/item/sales_tagger=1,\ + /obj/item/export_scanner=1,\ + /obj/item/stack/packageWrap/small=2,\ + /obj/item/stack/wrapping_paper/small=1 + ) + generate_items_inside(items_inside,src) diff --git a/code/game/objects/items/storage/briefcase.dm b/code/game/objects/items/storage/briefcase.dm index 454475625d..f64cdbc98b 100644 --- a/code/game/objects/items/storage/briefcase.dm +++ b/code/game/objects/items/storage/briefcase.dm @@ -105,7 +105,7 @@ /obj/item/storage/briefcase/medical name = "medical briefcase" - icon_state = "medbriefcase" + icon_state = "firstaid-briefcase" desc = "A white with a blue cross brieface, this is meant to hold medical gear that would not be able to normally fit in a bag." /obj/item/storage/briefcase/medical/PopulateContents() diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm index f68084d63a..111e3c96a0 100644 --- a/code/game/objects/items/storage/fancy.dm +++ b/code/game/objects/items/storage/fancy.dm @@ -248,10 +248,10 @@ return ..() var/obj/item/clothing/mask/cigarette/cig = locate(/obj/item/clothing/mask/cigarette) in contents if(cig) - if(!user.wear_mask && !(SLOT_WEAR_MASK in M.check_obscured_slots())) + if(!user.wear_mask && !(ITEM_SLOT_MASK in M.check_obscured_slots())) var/obj/item/clothing/mask/cigarette/W = cig SEND_SIGNAL(src, COMSIG_TRY_STORAGE_TAKE, W, M) - M.equip_to_slot_if_possible(W, SLOT_WEAR_MASK) + M.equip_to_slot_if_possible(W, ITEM_SLOT_MASK) contents -= W to_chat(user, "You take \a [W] out of the pack.") else diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index 6c3185b312..0381779531 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -18,12 +18,6 @@ throw_speed = 3 throw_range = 7 var/empty = FALSE - var/list/possible_icons = list("firstaid","firstaid2","firstaid3","firstaid4") - -/obj/item/storage/firstaid/Initialize(mapload) - . = ..() - if(LAZYLEN(possible_icons)) - icon_state = pick(possible_icons) /obj/item/storage/firstaid/regular icon_state = "firstaid" @@ -45,7 +39,7 @@ new /obj/item/healthanalyzer(src) /obj/item/storage/firstaid/emergency - icon_state = "medbriefcase" + icon_state = "firstaid-briefcase" name = "emergency first-aid kit" desc = "A very simple first aid kit meant to secure and stabilize serious wounds for later treatment." @@ -61,8 +55,9 @@ generate_items_inside(items_inside,src) /obj/item/storage/firstaid/ancient - icon_state = "firstaid" - desc = "A first aid kit with the ability to heal common types of injuries." + name = "ancient first-aid kit" + icon_state = "oldfirstaid" + desc = "A first aid kit with the ability to heal common types of injuries. You start thinking of the good old days just by looking at it." /obj/item/storage/firstaid/ancient/PopulateContents() if(empty) @@ -75,12 +70,34 @@ new /obj/item/stack/medical/mesh(src) new /obj/item/stack/medical/mesh(src) +/obj/item/storage/firstaid/ancient/heirloom + // Long since been ransacked by hungry powergaming assistants breaking into med storage + empty = TRUE + +/obj/item/storage/firstaid/brute + name = "trauma treatment kit" + desc = "A first aid kit for when you get toolboxed." + icon_state = "firstaid-brute" + item_state = "firstaid-brute" + +/obj/item/storage/firstaid/brute/suicide_act(mob/living/carbon/user) + user.visible_message("[user] begins beating [user.p_them()]self over the head with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return BRUTELOSS + +/obj/item/storage/firstaid/brute/PopulateContents() + if(empty) + return + for(var/i in 1 to 4) + new /obj/item/reagent_containers/pill/patch/styptic(src) + new /obj/item/stack/medical/gauze(src) + new /obj/item/stack/medical/gauze(src) + new /obj/item/healthanalyzer(src) + /obj/item/storage/firstaid/fire name = "burn treatment kit" desc = "A specialized medical kit for when the toxins lab -spontaneously- burns down." - icon_state = "burn" - item_state = "firstaid-ointment" - possible_icons = list("burn","burn2","burn3","burn4") + icon_state = "firstaid-burn" + item_state = "firstaid-burn" /obj/item/storage/firstaid/fire/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins rubbing \the [src] against [user.p_them()]self! It looks like [user.p_theyre()] trying to start a fire!") @@ -99,9 +116,8 @@ /obj/item/storage/firstaid/toxin name = "toxin treatment kit" desc = "Used to treat toxic blood content and radiation poisoning." - icon_state = "toxin" + icon_state = "firstaid-toxin" item_state = "firstaid-toxin" - possible_icons = list("toxin","toxin2","toxin3","toxin4") /obj/item/storage/firstaid/toxin/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins licking the lead paint off \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -116,38 +132,11 @@ new /obj/item/storage/pill_bottle/charcoal(src) new /obj/item/healthanalyzer(src) -/obj/item/storage/firstaid/radbgone - name = "radiation treatment kit" - desc = "Used to treat minor toxic blood content and major radiation poisoning." - icon_state = "rad" - item_state = "firstaid-toxin" - possible_icons = list("rad","rad2","rad3") - -/obj/item/storage/firstaid/radbgone/suicide_act(mob/living/carbon/user) - user.visible_message("[user] begins licking the lead paint off \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return TOXLOSS - -/obj/item/storage/firstaid/radbgone/PopulateContents() - if(empty) - return - if(prob(50)) - new /obj/item/reagent_containers/pill/mutarad(src) - if(prob(80)) - new /obj/item/reagent_containers/pill/antirad_plus(src) - new /obj/item/reagent_containers/syringe/charcoal(src) - new /obj/item/storage/pill_bottle/charcoal(src) - new /obj/item/reagent_containers/pill/mutadone(src) - new /obj/item/reagent_containers/pill/antirad(src) - new /obj/item/reagent_containers/food/drinks/bottle/vodka(src) - new /obj/item/healthanalyzer(src) - - /obj/item/storage/firstaid/o2 name = "oxygen deprivation treatment kit" desc = "A box full of oxygen goodies." - icon_state = "oxy" + icon_state = "firstaid-o2" item_state = "firstaid-o2" - possible_icons = list("oxy", "oxy2", "oxy3", "oxy4") /obj/item/storage/firstaid/o2/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins hitting [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -162,31 +151,11 @@ new /obj/item/reagent_containers/hypospray/medipen(src) new /obj/item/healthanalyzer(src) -/obj/item/storage/firstaid/brute - name = "brute trauma treatment kit" - desc = "A first aid kit for when you get toolboxed." - icon_state = "brute" - item_state = "firstaid-brute" - possible_icons = list("brute", "brute2", "brute3", "brute4") - -/obj/item/storage/firstaid/brute/suicide_act(mob/living/carbon/user) - user.visible_message("[user] begins beating [user.p_them()]self over the head with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return BRUTELOSS - -/obj/item/storage/firstaid/brute/PopulateContents() - if(empty) - return - for(var/i in 1 to 4) - new /obj/item/reagent_containers/pill/patch/styptic(src) - new /obj/item/stack/medical/gauze(src) - new /obj/item/stack/medical/gauze(src) - new /obj/item/healthanalyzer(src) - /obj/item/storage/firstaid/tactical - name = "combat medical kit" + name = "tactical first-aid kit" desc = "I hope you've got insurance." - icon_state = "tactical" - possible_icons = null + icon_state = "firstaid-tactical" + item_state = "firstaid-tactical" /obj/item/storage/firstaid/tactical/ComponentInitialize() . = ..() @@ -208,7 +177,6 @@ new /obj/item/clothing/glasses/hud/health/night/syndicate(src) /obj/item/storage/firstaid/tactical/nukeop - name = "improved combat medical kit" /obj/item/storage/firstaid/tactical/nukeop/PopulateContents() if(empty) @@ -222,6 +190,30 @@ new /obj/item/reagent_containers/syringe/lethal/choral(src) // what the fuck does anyone use this piece of shit for new /obj/item/clothing/glasses/hud/health/night/syndicate(src) +/obj/item/storage/firstaid/radbgone + name = "radiation treatment kit" + desc = "Used to treat minor toxic blood content and major radiation poisoning." + icon_state = "firstaid-rad" + item_state = "firstaid-rad" + +/obj/item/storage/firstaid/radbgone/suicide_act(mob/living/carbon/user) + user.visible_message("[user] begins licking the lead paint off \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return TOXLOSS + +/obj/item/storage/firstaid/radbgone/PopulateContents() + if(empty) + return + if(prob(50)) + new /obj/item/reagent_containers/pill/mutarad(src) + if(prob(80)) + new /obj/item/reagent_containers/pill/antirad_plus(src) + new /obj/item/reagent_containers/syringe/charcoal(src) + new /obj/item/storage/pill_bottle/charcoal(src) + new /obj/item/reagent_containers/pill/mutadone(src) + new /obj/item/reagent_containers/pill/antirad(src) + new /obj/item/reagent_containers/food/drinks/bottle/vodka(src) + new /obj/item/healthanalyzer(src) + /* * Pill Bottles */ @@ -405,6 +397,14 @@ for(var/i in 1 to 10) new /obj/item/reagent_containers/pill/breast_enlargement(src) +/obj/item/storage/pill_bottle/butt_enlargement + name = "butt enlargement pills" + desc = "May alert security when sneaking around if enough pills are consumed due to assclapping. Be dummy thick responsibly." + +/obj/item/storage/pill_bottle/butt_enlargement/PopulateContents() + for(var/i in 1 to 10) + new /obj/item/reagent_containers/pill/butt_enlargement(src) + /obj/item/storage/pill_bottle/neurine name = "bottle of neurine pills" desc = "Contains pills to treat non-severe mental traumas." @@ -471,12 +471,12 @@ name = "hypospray kit" desc = "It's a kit designed for containing a hypospray and specific treatment chemical-filled vials." icon_state = "firstaid-mini" + item_state = "firstaid" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' throw_speed = 3 throw_range = 7 var/empty = FALSE - item_state = "firstaid" custom_price = PRICE_ABOVE_NORMAL custom_premium_price = PRICE_EXPENSIVE @@ -489,7 +489,7 @@ /obj/item/reagent_containers/glass/bottle/vial)) /obj/item/storage/hypospraykit/regular - icon_state = "firstaid-mini" + name = "first-aid hypospray kit" desc = "A hypospray kit with general use vials." /obj/item/storage/hypospraykit/regular/PopulateContents() @@ -499,11 +499,24 @@ new /obj/item/reagent_containers/glass/bottle/vial/small/tricord(src) new /obj/item/reagent_containers/glass/bottle/vial/small/tricord(src) +/obj/item/storage/hypospraykit/brute + name = "trauma hypospray kit" + icon_state = "firstaid-brute-mini" + item_state = "firstaid-brute" + +/obj/item/storage/hypospraykit/brute/PopulateContents() + if(empty) + return + new /obj/item/hypospray/mkii/brute(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/bicaridine(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/bicaridine(src) + + /obj/item/storage/hypospraykit/fire name = "burn treatment hypospray kit" desc = "A specialized hypospray kit for burn treatments. Apply with sass." - icon_state = "burn-mini" - item_state = "firstaid-ointment" + icon_state = "firstaid-burn-mini" + item_state = "firstaid-burn" /obj/item/storage/hypospraykit/fire/PopulateContents() if(empty) @@ -514,7 +527,7 @@ /obj/item/storage/hypospraykit/toxin name = "toxin treatment hypospray kit" - icon_state = "toxin-mini" + icon_state = "firstaid-toxin-mini" item_state = "firstaid-toxin" /obj/item/storage/hypospraykit/toxin/PopulateContents() @@ -526,7 +539,7 @@ /obj/item/storage/hypospraykit/o2 name = "oxygen deprivation hypospray kit" - icon_state = "oxy-mini" + icon_state = "firstaid-o2-mini" item_state = "firstaid-o2" /obj/item/storage/hypospraykit/o2/PopulateContents() @@ -538,36 +551,14 @@ /obj/item/storage/hypospraykit/enlarge name = "organomegaly trauma hypospray kit" - icon_state = "enlarge-mini" + icon_state = "firstaid-enlarge-mini" item_state = "firstaid-brute" -/obj/item/storage/hypospraykit/enlarge/PopulateContents() - if(empty) - return - new /obj/item/hypospray/mkii/enlarge(src) - new /obj/item/reagent_containers/glass/bottle/vial/small/breastreduction(src) - new /obj/item/reagent_containers/glass/bottle/vial/small/breastreduction(src) - new /obj/item/reagent_containers/glass/bottle/vial/small/breastreduction(src) - new /obj/item/reagent_containers/glass/bottle/vial/small/penisreduction(src) - new /obj/item/reagent_containers/glass/bottle/vial/small/penisreduction(src) - new /obj/item/reagent_containers/glass/bottle/vial/small/penisreduction(src) - -/obj/item/storage/hypospraykit/brute - name = "brute trauma hypospray kit" - icon_state = "brute-mini" - item_state = "firstaid-brute" - -/obj/item/storage/hypospraykit/brute/PopulateContents() - if(empty) - return - new /obj/item/hypospray/mkii/brute(src) - new /obj/item/reagent_containers/glass/bottle/vial/small/bicaridine(src) - new /obj/item/reagent_containers/glass/bottle/vial/small/bicaridine(src) - /obj/item/storage/hypospraykit/tactical - name = "combat hypospray kit" + name = "tactical first-aid hypospray kit" desc = "A hypospray kit best suited for combat situations." - icon_state = "tactical-mini" + icon_state = "firstaid-tactical-mini" + item_state = "firstaid-tactical-mini" /obj/item/storage/hypospraykit/tactical/PopulateContents() if(empty) @@ -580,7 +571,8 @@ /obj/item/storage/hypospraykit/cmo name = "deluxe hypospray kit" desc = "A kit containing a Deluxe hypospray and Vials." - icon_state = "tactical-mini" + icon_state = "firstaid-rad-mini" + item_state = "firstaid-rad" /obj/item/storage/hypospraykit/cmo/PopulateContents() if(empty) @@ -592,6 +584,20 @@ new /obj/item/reagent_containers/glass/bottle/vial/large/dexalin(src) new /obj/item/reagent_containers/glass/bottle/vial/large/synthflesh(src) +/obj/item/storage/hypospraykit/enlarge/PopulateContents() + if(empty) + return + new /obj/item/hypospray/mkii/enlarge(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/breastreduction(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/breastreduction(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/breastreduction(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/penisreduction(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/penisreduction(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/penisreduction(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/buttreduction(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/buttreduction(src) + new /obj/item/reagent_containers/glass/bottle/vial/small/buttreduction(src) + /obj/item/storage/box/vials name = "box of hypovials" diff --git a/code/game/objects/items/storage/lockbox.dm b/code/game/objects/items/storage/lockbox.dm index ce4e8b9df1..adfd3cc1bd 100644 --- a/code/game/objects/items/storage/lockbox.dm +++ b/code/game/objects/items/storage/lockbox.dm @@ -217,7 +217,7 @@ var/datum/bank_account/buyer_account var/privacy_lock = TRUE -/obj/item/storage/lockbox/order/Initialize(datum/bank_account/_buyer_account) +/obj/item/storage/lockbox/order/Initialize(mapload, datum/bank_account/_buyer_account) . = ..() buyer_account = _buyer_account diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 7a067257cb..00b1d92659 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -79,6 +79,8 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) name = "mechanical toolbox" icon_state = "blue" item_state = "toolbox_blue" + /// If FALSE, someone with a ensouled soulstone can sacrifice a spirit to change the sprite of this toolbox. + var/has_soul = FALSE /obj/item/storage/toolbox/mechanical/PopulateContents() new /obj/item/screwdriver(src) @@ -93,6 +95,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) icon_state = "toolbox_blue_old" has_latches = FALSE can_rubberify = FALSE + has_soul = TRUE /obj/item/storage/toolbox/mechanical/old/heirloom name = "old, robust toolbox" //this will be named "X family toolbox" @@ -126,7 +129,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) /obj/item/storage/toolbox/mechanical/old/clean/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) calc_damage() ..() - + /obj/item/storage/toolbox/mechanical/old/clean/PopulateContents() new /obj/item/screwdriver(src) new /obj/item/wrench(src) @@ -367,7 +370,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) desc = replacetext(desc, "Danger", "Bouncy") desc = replacetext(desc, "robust", "safe") desc = replacetext(desc, "heavier", "bouncier") - DISABLE_BITFIELD(flags_1, CONDUCT_1) + flags_1 &= ~(CONDUCT_1) custom_materials = null damtype = STAMINA force += 3 //to compensate the higher stamina K.O. threshold compared to actual health. @@ -397,7 +400,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) attack_verb = list("robusted", "bounced") can_rubberify = FALSE //we are already the future. -/obj/item/storage/toolbox/rubber/Initialize() +/obj/item/storage/toolbox/rubber/Initialize(mapload) icon_state = pick("blue", "red", "yellow", "green") item_state = "toolbox_[icon_state]" if(!GLOB.rubber_toolbox_icons[icon_state]) diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index f25f6f3a51..f4b5e26189 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -447,7 +447,7 @@ /obj/item/paper/contractor_guide name = "Contractor Guide" -/obj/item/paper/contractor_guide/Initialize() +/obj/item/paper/contractor_guide/Initialize(mapload) info = {"

    Welcome agent, congratulations on your new position as contractor. On top of your already assigned objectives, this kit will provide you contracts to take on for TC payments.

    Provided within, we give your specialist contractor space suit. It's even more compact, being able to fit into a pocket, and faster than the diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index 62bde0e4e6..7d84d38624 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -13,11 +13,12 @@ throwforce = 7 w_class = WEIGHT_CLASS_NORMAL attack_verb = list("beaten") - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 50, BIO = 0, RAD = 0, FIRE = 80, ACID = 80) attack_speed = CLICK_CD_MELEE - var/stamina_loss_amount = 40 + var/stamina_loss_amount = 35 var/turned_on = FALSE + var/armor_pen = 100 var/knockdown = TRUE /// block percent needed to prevent knockdown/disarm var/block_percent_to_counter = 50 @@ -25,8 +26,8 @@ var/hitcost = 750 var/throw_hit_chance = 35 var/preload_cell_type //if not empty the baton starts with this type of cell - var/cooldown_duration = 3.5 SECONDS //How long our baton rightclick goes on cooldown for after applying a knockdown - var/status_duration = 5 SECONDS //how long our status effects last for otherwise + var/cooldown_duration = 2.5 SECONDS //How long our baton rightclick goes on cooldown for after applying a knockdown + var/status_duration = 3 SECONDS //how long our status effects last for otherwise COOLDOWN_DECLARE(shove_cooldown) /obj/item/melee/baton/examine(mob/user) @@ -53,6 +54,8 @@ cell = new preload_cell_type(src) update_icon() + register_item_context() + /obj/item/melee/baton/DoRevenantThrowEffects(atom/target) switch_status() @@ -80,16 +83,6 @@ //we're below minimum, turn off switch_status(FALSE) -///Check for our cell to determine how much penetration our weapon does. -/obj/item/melee/baton/proc/get_cell_zap_pen() - var/obj/item/stock_parts/cell/copper_top = get_cell() - if(copper_top) - var/chargepower = copper_top.maxcharge - var/zap_penetration = (chargepower/1000) //This is our effective penetration. Every 1000 max charge, we get 1 pen power. A high capacity cell is equal to 10 armor pen, as an example. - return zap_penetration - else - return 0 - /obj/item/melee/baton/proc/switch_status(new_status = FALSE, silent = FALSE) if(turned_on != new_status) turned_on = new_status @@ -164,6 +157,26 @@ if(!interrupt) return ..() +/obj/item/melee/baton/add_item_context(datum/source, list/context, atom/target, mob/living/user) + if (isturf(target)) + return NONE + + if (isobj(target)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Attack") + else + if (turned_on) + LAZYSET(context[SCREENTIP_CONTEXT_RMB], INTENT_ANY, "Knockdown") + + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Stun") + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_HARM, "Harmful stun") + else + LAZYSET(context[SCREENTIP_CONTEXT_RMB], INTENT_ANY, "Knockdown") // DON'T TELL EM, PRANKED. + + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Stun") // STILL DO NOT DARE TELLING THEM + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_HARM, "Attack") // It's fine i guess...? + + return CONTEXTUAL_SCREENTIP_SET + /obj/item/melee/baton/alt_pre_attack(atom/A, mob/living/user, params) if(!user.CheckActionCooldown(CLICK_CD_MELEE)) return @@ -198,8 +211,8 @@ return FALSE var/final_stamina_loss_amount = stamina_loss_amount //Our stunning power for the baton var/shoved = FALSE //Did we succeed on knocking our target over? - var/zap_penetration = get_cell_zap_pen() //Find out what kind of cell we have, and calculating the resultant armor pen we get from it - var/zap_block = L.run_armor_check(BODY_ZONE_CHEST, "melee", null, null, zap_penetration) //armor check, including calculation for armor penetration, for our attack + var/zap_penetration = armor_pen + var/zap_block = L.run_armor_check(BODY_ZONE_CHEST, MELEE, null, null, zap_penetration) //armor check, including calculation for armor penetration, for our attack final_stamina_loss_amount = block_calculate_resultant_damage(final_stamina_loss_amount, return_list) var/obj/item/stock_parts/cell/our_cell = get_cell() @@ -223,7 +236,7 @@ if(shoving && COOLDOWN_FINISHED(src, shove_cooldown) && !HAS_TRAIT(L, TRAIT_IWASBATONED)) //Rightclicking applies a knockdown, but only once every couple of seconds, based on the cooldown_duration var. If they were recently knocked down, they can't be knocked down again by a baton. L.DefaultCombatKnockdown(50, override_stamdmg = 0) - L.apply_status_effect(STATUS_EFFECT_TASED_WEAK, status_duration) //Even if they shove themselves up, they're still slowed. + L.apply_status_effect(STATUS_EFFECT_TASED_WEAK_NODMG, status_duration) //Even if they shove themselves up, they're still slowed. L.apply_status_effect(STATUS_EFFECT_OFF_BALANCE, status_duration) //They're very likely to drop items if shoved briefly after a knockdown. shoved = TRUE COOLDOWN_START(src, shove_cooldown, cooldown_duration) @@ -333,7 +346,8 @@ w_class = WEIGHT_CLASS_BULKY force = 3 throwforce = 5 - stamina_loss_amount = 25 + stamina_loss_amount = 30 + armor_pen = 35 hitcost = 1000 throw_hit_chance = 10 slot_flags = ITEM_SLOT_BACK @@ -341,7 +355,7 @@ status_duration = 3 //Slows someone for a tiny bit var/obj/item/assembly/igniter/sparkler -/obj/item/melee/baton/cattleprod/Initialize() +/obj/item/melee/baton/cattleprod/Initialize(mapload) . = ..() sparkler = new (src) sparkler.activate_cooldown = 7 //Helps visualize the knockdown @@ -376,12 +390,16 @@ if(ishuman(hit_atom) && !caught && prob(throw_hit_chance) && thrownby)//if they are a carbon and they didn't catch it baton_stun(hit_atom, thrownby, shoving = TRUE) if(thrownby && !caught) - sleep(1) - if(!QDELETED(src)) - throw_at(thrownby, throw_range+2, throw_speed, null, TRUE) + throw_back() else return ..() +/obj/item/melee/baton/boomerang/proc/throw_back() + set waitfor = FALSE + sleep(1) + if(!QDELETED(src)) + throw_at(thrownby, throw_range+2, throw_speed, null, TRUE) + /obj/item/melee/baton/boomerang/update_icon() if(turned_on) icon_state = "[initial(icon_state)]_active" diff --git a/code/game/objects/items/summon.dm b/code/game/objects/items/summon.dm new file mode 100644 index 0000000000..ca678e2cbb --- /dev/null +++ b/code/game/objects/items/summon.dm @@ -0,0 +1,539 @@ +/// doing nothing/orbiting idly +#define STATE_IDLE 0 +/// performing reset animation +#define STATE_RESET 1 +/// performing attack animation +#define STATE_ATTACK 2 +/// performing animation between attacks +#define STATE_RECOVER 3 + +/** + * Simple summon weapon code in this file + * + * tl;dr latch onto target, repeatedly proc attacks, animate using transforms, + * no real hitboxes/collisions, think of /datum/component/orbit-adjacent + */ +/obj/item/summon + name = "a horrifying mistake" + desc = "Why does this exist?" + /// datum type + var/host_type + /// number of summons + var/summon_count = 6 + /// how long it takes for a "stack" to fall off by itself + var/stack_duration = 5 SECONDS + /// our summon weapon host + var/datum/summon_weapon_host/host + /// range summons will chase to + var/range = 7 + /// are we a ranged weapon? + var/melee_only = TRUE + +/obj/item/summon/Initialize(mapload) + . = ..() + if(host_type) + host = new host_type(src, summon_count, range) + +/obj/item/summon/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + . = ..() + if(!host) + return + if(!proximity_flag && melee_only) + return + Target(target) + +/obj/item/summon/dropped(mob/user, silent) + . = ..() + addtimer(CALLBACK(src, .proc/check_activation), 0, TIMER_UNIQUE) + +/obj/item/summon/equipped(mob/user, slot) + . = ..() + addtimer(CALLBACK(src, .proc/check_activation), 0, TIMER_UNIQUE) + +/obj/item/summon/proc/check_activation() + if(!host) + return + if(!isliving(loc)) + host.SetMaster(null) + var/mob/living/L = loc + if(!istype(L)) + return + if(!L.is_holding(src)) + host.SetMaster(src) + host.Suppress() + host.SetMaster(L) + host.Wake() + +/obj/item/summon/proc/Target(atom/victim) + if(!host?.CheckTarget(victim)) + return + host.AutoTarget(victim, stack_duration) + +/obj/item/summon/sword + name = "spectral blade" + desc = "An eldritch blade that summons phantasms to attack one's enemies." + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "spectral" + item_state = "spectral" + lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' + host_type = /datum/summon_weapon_host/sword + force = 15 + sharpness = SHARP_EDGED + +/** + * Serves as the master datum for summon weapons + */ +/datum/summon_weapon_host + /// master atom + var/atom/master + /// suppressed? + var/active = TRUE + /// actual projectiles + var/list/datum/summon_weapon/controlled + /// active projectiles - refreshing a projectile reorders the list, so if they all have the same stack durations, you can trust the list to have last-refreshed at [1] + var/list/datum/summon_weapon/attacking + /// idle projectiles + var/list/datum/summon_weapon/idle + /// projectile type + var/weapon_type + /// default stack time + var/stack_time = 5 SECONDS + /// range + var/range = 7 + +/datum/summon_weapon_host/New(atom/master, count, range) + src.master = master + src.range = range + controlled = list() + attacking = list() + idle = list() + Create(count) + +/datum/summon_weapon_host/Destroy() + QDEL_LIST(controlled) + master = null + return ..() + +/datum/summon_weapon_host/proc/SetMaster(atom/master, reset_on_failure = TRUE) + var/changed = src.master != master + src.master = master + if(changed) + for(var/datum/summon_weapon/weapon as anything in idle) + weapon.Reset() + if(!master && reset_on_failure) + for(var/datum/summon_weapon/weapon as anything in attacking) + weapon.Reset() + +/datum/summon_weapon_host/proc/Create(count) + if(!weapon_type) + return + for(var/i in 1 to min(count, clamp(20 - controlled.len - count, 0, 20))) + var/datum/summon_weapon/weapon = new weapon_type + Associate(weapon) + +/datum/summon_weapon_host/proc/Associate(datum/summon_weapon/linking) + if(linking.host && linking.host != src) + linking.host.Disassociate(linking) + linking.host = src + controlled |= linking + linking.Reset() + +/datum/summon_weapon_host/proc/Disassociate(datum/summon_weapon/unlinking, reset = TRUE, autodel) + if(unlinking.host == src) + unlinking.host = null + controlled -= unlinking + if(reset) + unlinking.Reset(del_no_host = autodel) + idle -= unlinking + attacking -= unlinking + +/datum/summon_weapon_host/proc/AutoTarget(atom/victim, duration = stack_time) + if(!active) + return + var/datum/summon_weapon/weapon = (idle.len && idle[1]) || (attacking.len && attacking[1]) + if(!weapon) + return + if(!CheckTarget(victim)) + return + weapon.Target(victim) + if(duration) + weapon.ResetIn(duration) + +/datum/summon_weapon_host/proc/OnTarget(datum/summon_weapon/weapon, atom/victim) + attacking -= weapon + idle -= weapon + attacking |= weapon + +/datum/summon_weapon_host/proc/OnReset(datum/summon_weapon/weapon, atom/victim) + attacking -= weapon + idle |= weapon + +/datum/summon_weapon_host/proc/CheckTarget(atom/victim) + if(isitem(victim)) + return FALSE + if(QDELETED(victim)) + return FALSE + if(victim == master) + return FALSE + if(isliving(victim)) + var/mob/living/L = victim + if(L.stat == DEAD) + return FALSE + return TRUE + if(isobj(victim)) + var/obj/O = victim + return (O.obj_flags & CAN_BE_HIT) + return FALSE + +/datum/summon_weapon_host/proc/Suppress() + active = FALSE + for(var/datum/summon_weapon/weapon as anything in controlled) + weapon.Reset() + +/datum/summon_weapon_host/proc/Wake() + active = TRUE + for(var/datum/summon_weapon/weapon as anything in controlled) + weapon.Reset() + +/datum/summon_weapon_host/sword + weapon_type = /datum/summon_weapon/sword + +/** + * A singular summoned object + * + * How summon weapons work: + * + * Reset() - makes it go back to its master. + * Target() - locks onto a target for a duration + * + * The biggest challenge is synchronizing animations. + * Variables keep track of when things tick, but, + * animations are client-timed, and not server-timed + * + * Animations: + * The weapon can only track its "intended" angle and dist + * "Current" pixel x/y are always calculated relative to a target from the current orbiting atom the physical effect is on + * There's 3 animations, + * MoveTo(location, angle, dist, rotation) + * Orbit(location) + * Rotate(degrees) + * + * And an non-animation that just snaps it to a location, + * HardReset(location) + */ +/datum/summon_weapon + /// name + var/name = "summoned weapon" + /// host + var/datum/summon_weapon_host/host + /// icon file + var/icon = 'icons/effects/summon.dmi' + /// icon state + var/icon_state + /// mutable_appearance to use, will skip making from icon/icon state if so + var/mutable_appearance/appearance + /// the actual effect + var/atom/movable/summon_weapon_effect/atom + /// currently locked attack target + var/atom/victim + /// current angle from victim - clockwise from 0. null if not attacking. + var/angle + /// current distance from victim - pixels + var/dist + /// current rotation - angles clockwise from north + var/rotation + /// rand dist to rotate during reattack phase + var/angle_vary = 45 + /// orbit distance from victim - pixels + var/orbit_dist = 72 + /// orbit distance variation from victim + var/orbit_dist_vary = 24 + /// attack delay in deciseconds - this is time spent between attacks + var/attack_speed = 1.5 + /// attack length in deciseconds - this is the attack animation speed in total + var/attack_length = 1.5 + /// attack damage + var/attack_damage = 5 + /// reset animation duration + var/reset_speed = 2 + /// attack damtype + var/attack_type = BRUTE + /// attack sound + var/attack_sound = list( + 'sound/weapons/bladeslice.ogg', + 'sound/weapons/bladesliceb.ogg' + ) + /// attack verb + var/attack_verb = list( + "rended", + "pierced", + "penetrated", + "sliced" + ) + /// current state + var/state = STATE_IDLE + /// animation locked until + var/animation_lock + /// animation lock timer + var/animation_timerid + /// reset timerid + var/reset_timerid + +/datum/summon_weapon/New(mutable_appearance/appearance_override) + if(appearance_override) + appearance = appearance_override + Setup() + attack_verb = typelist(NAMEOF(src, attack_verb), attack_verb) + attack_sound = typelist(NAMEOF(src, attack_sound), attack_sound) + +/datum/summon_weapon/Destroy() + host.Disassociate(src, autodel = FALSE) + QDEL_NULL(atom) + QDEL_NULL(appearance) + return ..() + +/datum/summon_weapon/proc/Setup() + atom = new + if(!appearance) + GenerateAppearance() + atom.appearance = appearance + atom.moveToNullspace() + if(host) + Reset() + +/datum/summon_weapon/proc/GenerateAppearance() + if(!appearance) + appearance = new + appearance.icon = icon + appearance.icon_state = icon_state + appearance.mouse_opacity = MOUSE_OPACITY_TRANSPARENT + appearance.opacity = FALSE + appearance.plane = GAME_PLANE + appearance.layer = ABOVE_MOB_LAYER + appearance.appearance_flags = KEEP_TOGETHER + appearance.overlays = list( + emissive_appearance(icon, icon_state) + ) + +/datum/summon_weapon/proc/Reset(immediate = FALSE, del_no_host = TRUE) + angle = null + victim = null + if(reset_timerid) + deltimer(reset_timerid) + reset_timerid = null + host?.OnReset(src) + atom.Release() + state = STATE_RESET + if(!host) + if(del_no_host) + qdel(src) + return + HardReset(null) + atom.moveToNullspace() + return + if(immediate) + if(animation_timerid) + deltimer(animation_timerid) + Act() + else + Wake() + +/datum/summon_weapon/proc/ResetIn(ds) + reset_timerid = addtimer(CALLBACK(src, .proc/Reset), ds, TIMER_STOPPABLE) + +/datum/summon_weapon/proc/Target(atom/victim) + if(!istype(victim) || !isturf(victim.loc) || (host && !host.CheckTarget(victim))) + Reset() + return + src.victim = victim + host.OnTarget(src, victim) + state = STATE_ATTACK + Wake() + +/datum/summon_weapon/proc/Wake() + if(!animation_timerid) + Act() + +/datum/summon_weapon/proc/AnimationLock(duration) + if(animation_timerid) + deltimer(animation_timerid) + animation_timerid = addtimer(CALLBACK(src, .proc/Act), duration, TIMER_CLIENT_TIME | TIMER_STOPPABLE) + +/datum/summon_weapon/proc/Act() + animation_timerid = null + switch(state) + if(STATE_IDLE) + return + if(STATE_ATTACK) + if(!isturf(victim.loc) || (host && !host.CheckTarget(victim))) + Reset(TRUE) + return + state = STATE_RECOVER + // register hit at the halfway mark + // we can do better math to approximate when the attack will hit but i'm too tired to bother + addtimer(CALLBACK(src, .proc/Hit, victim), attack_length / 2, TIMER_CLIENT_TIME) + // we need to approximate our incoming angle - again, better math exists but why bother + var/incoming_angle = angle + if(isturf(atom.loc) && (atom.loc != victim.loc)) + incoming_angle = Get_Angle(atom.loc, victim.loc) + // pierce through target + // we do not want to turn while doing this so we pierce through them visually + incoming_angle += 180 + var/outgoing_angle = SIMPLIFY_DEGREES(incoming_angle) + AnimationLock(MoveTo(victim, null, outgoing_angle, orbit_dist + rand(-orbit_dist_vary, orbit_dist_vary), outgoing_angle, attack_length)) + if(STATE_RESET) + state = STATE_IDLE + if(!host || !host.active || !get_turf(host.master)) + atom.moveToNullspace() + src.angle = null + src.dist = null + src.rotation = null + return + var/reset_angle = rand(0, 360) + AnimationLock(MoveTo(host.master, null, reset_angle, 30, 90, reset_speed)) + addtimer(CALLBACK(src, .proc/Orbit, host.master, reset_angle, 30, 3 SECONDS), reset_speed, TIMER_CLIENT_TIME) + if(STATE_RECOVER) + state = STATE_ATTACK + AnimationLock(Rotate(rand(-angle_vary, angle_vary), attack_speed, null)) + +/datum/summon_weapon/proc/Hit(atom/victim) + if(!isobj(victim) && !isliving(victim)) + return FALSE + if(isliving(victim)) + var/mob/living/L = victim + L.apply_damage(attack_damage, attack_type) + playsound(victim, pick(attack_sound), 75) + else if(isobj(victim)) + var/obj/O = victim + O.take_damage(attack_damage, attack_type) + return TRUE + +/** + * relative to defaults to current location + */ +/datum/summon_weapon/proc/MoveTo(atom/destination, atom/relative_to, angle = 0, dist = 64, rotation = 180, time) + . = time + // construct final transform + var/matrix/dest = ConstructMatrix(angle, dist, rotation) + + // move to + atom.Lock(destination) + + // get relative first positions + relative_to = get_turf(relative_to || atom.locked) + destination = get_turf(destination) + // if none, move to immediately and end + if(!relative_to) + atom.transform = dest + src.angle = angle + src.dist = dist + src.rotation = rotation + // end animations + animate(atom, time = 0, flags = ANIMATION_END_NOW) + return 0 + + // grab source + var/rel_x = (destination.x - relative_to.x) * world.icon_size + src.dist * sin(src.angle) + var/rel_y = (destination.y - relative_to.y) * world.icon_size + src.dist * cos(src.angle) + + // construct source matrix + var/matrix/source = new + + source.Turn((relative_to == get_turf(atom.locked))? src.rotation : Get_Angle(relative_to, destination)) + source.Translate(rel_x, rel_y) + + // set vars + src.angle = angle + src.dist = dist + src.rotation = rotation + + // animate + atom.transform = source + animate(atom, transform = dest, time, FALSE, LINEAR_EASING, ANIMATION_LINEAR_TRANSFORM | ANIMATION_END_NOW) + +/** + * rotation defaults to facing towards locked atom + */ +/datum/summon_weapon/proc/Rotate(degrees, time, rotation) + . = time + if(!dist) + return 0 + var/matrix/M = ConstructMatrix(angle + degrees, dist, rotation || src.rotation) + if(rotation) + src.rotation = rotation + angle += degrees + animate(atom, transform = M, time, FALSE, LINEAR_EASING, ANIMATION_END_NOW | ANIMATION_LINEAR_TRANSFORM) + +/datum/summon_weapon/proc/Orbit(atom/destination, initial_degrees = rand(0, 360), dist, speed) + . = 0 + atom.Lock(destination) + animate(atom, 0, FALSE, flags = ANIMATION_END_NOW) + atom.transform = ConstructMatrix(initial_degrees, dist, 90) + atom.SpinAnimation(speed, parallel = FALSE, segments = 10) + // we can't predict dist/angle anymre because clienttime vs servertime. + // well, we can, but, let's not be bothered with timeofday math eh. + dist = 0 + angle = 0 + +/datum/summon_weapon/proc/ConstructMatrix(angle = 0, dist = 64, rotation = 0) + var/matrix/M = new + M.Turn(rotation) + M.Translate(0, dist) + M.Turn(angle) + return M + +/datum/summon_weapon/proc/HardReset(atom/snap_to) + if(animation_timerid) + deltimer(animation_timerid) + atom.Release() + atom.forceMove(snap_to) + atom.transform = null + +/datum/summon_weapon/sword + name = "spectral blade" + icon_state = "sword" + attack_damage = 5 + attack_speed = 1.5 + attack_length = 1.5 + +/atom/movable/summon_weapon_effect + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + plane = GAME_PLANE + layer = ABOVE_MOB_LAYER + opacity = FALSE + density = FALSE + /// locked atom + var/atom/locked + +/atom/movable/summon_weapon_effect/Destroy() + Release() + return ..() + +/atom/movable/summon_weapon_effect/proc/Lock(atom/target) + if(locked == target) + return + if(locked) + Release() + if(!target) + return + locked = target + forceMove(locked.loc) + if(ismovable(locked)) + RegisterSignal(locked, COMSIG_MOVABLE_MOVED, .proc/Update) + +/atom/movable/summon_weapon_effect/proc/Release() + if(ismovable(locked)) + UnregisterSignal(locked, COMSIG_MOVABLE_MOVED) + locked = null + +/atom/movable/summon_weapon_effect/proc/Update() + if(!locked) + return + if(loc != locked.loc) + forceMove(locked.loc) + +#undef STATE_IDLE +#undef STATE_ATTACK +#undef STATE_RECOVER +#undef STATE_RESET diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index 75ad909777..25e2f1a292 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -14,11 +14,15 @@ var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not var/datum/effect_system/trail_follow/ion/ion_trail -/obj/item/tank/jetpack/Initialize() +/obj/item/tank/jetpack/Initialize(mapload) . = ..() ion_trail = new ion_trail.set_up(src) +/obj/item/tank/jetpack/Destroy() + QDEL_NULL(ion_trail) + return ..() + /obj/item/tank/jetpack/populate_gas() if(gas_type) air_contents.set_moles(gas_type, ((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C))) @@ -181,7 +185,7 @@ var/obj/item/tank/internals/tank = null var/mob/living/carbon/human/cur_user -/obj/item/tank/jetpack/suit/Initialize() +/obj/item/tank/jetpack/suit/Initialize(mapload) . = ..() STOP_PROCESSING(SSobj, src) temp_air_contents = air_contents @@ -235,9 +239,13 @@ return /mob/living/carbon/get_jetpack() - var/obj/item/tank/jetpack/J = back - if(istype(J)) - return J + var/obj/item/I = back + if(istype(I, /obj/item/tank/jetpack)) + return I + else if(istype(I, /obj/item/mod/control)) + var/obj/item/mod/control/C = I + for(var/obj/item/mod/module/jetpack/J in C.modules) + return J /mob/living/carbon/human/get_jetpack() var/obj/item/tank/jetpack/J = ..() diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index 01da046809..7804abdc91 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -15,7 +15,7 @@ throw_range = 4 custom_materials = list(/datum/material/iron = 500) actions_types = list(/datum/action/item_action/set_internals) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 80, ACID = 30) var/datum/gas_mixture/air_contents = null var/distribute_pressure = ONE_ATMOSPHERE var/integrity = 3 @@ -48,7 +48,7 @@ var/obj/item/clothing/mask/M = check if(M.mask_adjusted) M.adjustmask(H) - if(CHECK_BITFIELD(check.clothing_flags, ALLOWINTERNALS)) + if((check.clothing_flags & ALLOWINTERNALS)) internals = TRUE if(!internals) @@ -64,7 +64,7 @@ H.update_action_buttons_icon() -/obj/item/tank/Initialize() +/obj/item/tank/Initialize(mapload) . = ..() air_contents = new(volume) //liters @@ -291,8 +291,8 @@ message_admins("Explosive tank rupture! Last key to touch the tank was [src.fingerprintslast].") log_game("Explosive tank rupture! Last key to touch the tank was [src.fingerprintslast].") //Give the gas a chance to build up more pressure through reacting - air_contents.react(src) - air_contents.react(src) + for(var/i in 1 to TANK_POST_FRAGMENT_REACTIONS) + air_contents.react(src) pressure = air_contents.return_pressure() var/range = (pressure-TANK_FRAGMENT_PRESSURE)/TANK_FRAGMENT_SCALE diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index ad9c8edf8f..188a8763cd 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -10,13 +10,13 @@ slowdown = 1 actions_types = list(/datum/action/item_action/toggle_mister) max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 30) resistance_flags = FIRE_PROOF var/obj/item/noz var/volume = 500 -/obj/item/watertank/Initialize() +/obj/item/watertank/Initialize(mapload) . = ..() create_reagents(volume, OPENCONTAINER) noz = make_noz() @@ -58,7 +58,7 @@ /obj/item/watertank/equipped(mob/user, slot) ..() - if(slot != SLOT_BACK) + if(slot != ITEM_SLOT_BACK) remove_noz() /obj/item/watertank/proc/remove_noz() @@ -117,7 +117,7 @@ var/obj/item/watertank/tank -/obj/item/reagent_containers/spray/mister/Initialize() +/obj/item/reagent_containers/spray/mister/Initialize(mapload) . = ..() tank = loc if(!istype(tank)) @@ -147,7 +147,7 @@ item_state = "waterbackpackjani" custom_price = PRICE_ALMOST_ONE_GRAND -/obj/item/watertank/janitor/Initialize() +/obj/item/watertank/janitor/Initialize(mapload) . = ..() reagents.add_reagent(/datum/reagent/space_cleaner, 500) @@ -183,7 +183,7 @@ volume = 200 slowdown = 0 -/obj/item/watertank/atmos/Initialize() +/obj/item/watertank/atmos/Initialize(mapload) . = ..() reagents.add_reagent(/datum/reagent/water, 200) @@ -219,7 +219,7 @@ var/metal_synthesis_cooldown = 0 var/resin_cooldown = 0 -/obj/item/extinguisher/mini/nozzle/Initialize() +/obj/item/extinguisher/mini/nozzle/Initialize(mapload) . = ..() tank = loc if (!istype(tank)) @@ -271,18 +271,7 @@ if(resin_cooldown) to_chat(user, "Resin launcher is still recharging...") return - resin_cooldown = TRUE - R.remove_any(100) - var/obj/effect/resin_container/A = new (get_turf(src)) - log_game("[key_name(user)] used Resin Launcher at [AREACOORD(user)].") - playsound(src,'sound/items/syringeproj.ogg',40,1) - for(var/a=0, a<5, a++) - step_towards(A, target) - sleep(2) - A.Smoke() - spawn(100) - if(src) - resin_cooldown = FALSE + launch_resin(target, user) return if(nozzle_mode == RESIN_FOAM) if(!Adj|| !isturf(target)) @@ -301,6 +290,21 @@ to_chat(user, "Resin foam mix is still being synthesized...") return +/obj/item/extinguisher/mini/nozzle/proc/launch_resin(atom/target, mob/user) + set waitfor = FALSE + resin_cooldown = TRUE + reagents.remove_any(100) + var/obj/effect/resin_container/A = new (get_turf(src)) + log_game("[key_name(user)] used Resin Launcher at [AREACOORD(user)].") + playsound(src,'sound/items/syringeproj.ogg',40,1) + for(var/a=0, a<5, a++) + step_towards(A, target) + sleep(2) + A.Smoke() + spawn(100) + if(src) + resin_cooldown = FALSE + /obj/effect/resin_container name = "resin container" desc = "A compacted ball of expansive resin, used to repair the atmosphere in a room, or seal off breaches." @@ -344,14 +348,14 @@ toggle_injection() /obj/item/reagent_containers/chemtank/item_action_slot_check(slot, mob/user, datum/action/A) - if(slot == SLOT_BACK) + if(slot == ITEM_SLOT_BACK) return 1 /obj/item/reagent_containers/chemtank/proc/toggle_injection() var/mob/living/carbon/human/user = usr if(!istype(user)) return - if (user.get_item_by_slot(SLOT_BACK) != src) + if (user.get_item_by_slot(ITEM_SLOT_BACK) != src) to_chat(user, "The chemtank needs to be on your back before you can activate it!") return if(on) @@ -436,7 +440,7 @@ volume = 2000 slowdown = 0 -/obj/item/watertank/op/Initialize() +/obj/item/watertank/op/Initialize(mapload) . = ..() reagents.add_reagent(/datum/reagent/toxin/mutagen,350) reagents.add_reagent(/datum/reagent/napalm,125) diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index bc6a40f8c0..b0b6a7a973 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -107,13 +107,13 @@ throw_speed = 3 throw_range = 5 custom_materials = list(/datum/material/iron=10000) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF var/list/active_portal_pairs var/max_portal_pairs = 3 var/atmos_link_override -/obj/item/hand_tele/Initialize() +/obj/item/hand_tele/Initialize(mapload) . = ..() active_portal_pairs = list() diff --git a/code/game/objects/items/theft_tools.dm b/code/game/objects/items/theft_tools.dm index 08390e1607..b40c5c22cf 100644 --- a/code/game/objects/items/theft_tools.dm +++ b/code/game/objects/items/theft_tools.dm @@ -15,7 +15,7 @@ var/cooldown = 0 var/pulseicon = "plutonium_core_pulse" -/obj/item/nuke_core/Initialize() +/obj/item/nuke_core/Initialize(mapload) . = ..() START_PROCESSING(SSobj, src) @@ -229,7 +229,7 @@ usesound = 'sound/weapons/bladeslice.ogg' var/usesLeft -/obj/item/scalpel/supermatter/Initialize() +/obj/item/scalpel/supermatter/Initialize(mapload) . = ..() usesLeft = rand(2, 4) diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index f481cab91f..8ddcda55e1 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -17,7 +17,7 @@ attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") tool_behaviour = TOOL_CROWBAR toolspeed = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) wound_bonus = -10 bare_wound_bonus = 5 @@ -41,6 +41,13 @@ /obj/item/crowbar/brass/family toolspeed = 1 +/obj/item/crowbar/ashwalker + name = "bone crowbar" + desc = "A rudimentary crowbar made of bones." + icon = 'icons/obj/mining.dmi' + icon_state = "crowbar_bone" + toolspeed = 0.75 + /obj/item/crowbar/bronze name = "bronze plated crowbar" desc = "A bronze plated crowbar." diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm index 920afb8d14..9aaffa4009 100644 --- a/code/game/objects/items/tools/screwdriver.dm +++ b/code/game/objects/items/tools/screwdriver.dm @@ -20,7 +20,7 @@ usesound = list('sound/items/screwdriver.ogg', 'sound/items/screwdriver2.ogg') tool_behaviour = TOOL_SCREWDRIVER toolspeed = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) var/random_color = TRUE //if the screwdriver uses random coloring var/static/list/screwdriver_colors = list( "blue" = rgb(24, 97, 213), @@ -39,7 +39,7 @@ user.visible_message("[user] is stabbing [src] into [user.p_their()] [pick("temple", "heart")]! It looks like [user.p_theyre()] trying to commit suicide!") return(BRUTELOSS) -/obj/item/screwdriver/Initialize() +/obj/item/screwdriver/Initialize(mapload) . = ..() if(random_color) //random colors! icon_state = "screwdriver" @@ -93,6 +93,14 @@ /obj/item/screwdriver/brass/family toolspeed = 1 +/obj/item/screwdriver/ashwalker + name = "bone screwdriver" + desc = "A rudimentary screwdriver made of carved bones." + icon = 'icons/obj/mining.dmi' + icon_state = "screwdriver_bone" + toolspeed = 0.75 + random_color = FALSE + /obj/item/screwdriver/bronze name = "bronze screwdriver" desc = "A screwdriver plated with bronze." diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 98889485b6..5bd7217484 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -19,7 +19,7 @@ throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_SMALL - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 30) resistance_flags = FIRE_PROOF var/self_fueling = FALSE //Do we refill ourselves or not @@ -41,11 +41,13 @@ wound_bonus = 0 bare_wound_bonus = 5 -/obj/item/weldingtool/Initialize() +/obj/item/weldingtool/Initialize(mapload) . = ..() create_reagents(max_fuel) reagents.add_reagent(/datum/reagent/fuel, max_fuel) update_icon() + if(can_off_process) + START_PROCESSING(SSobj, src) /obj/item/weldingtool/ComponentInitialize() . = ..() @@ -117,6 +119,11 @@ dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder qdel(src) +/obj/item/weldingtool/use_tool(atom/target, mob/living/user, delay, amount, volume, datum/callback/extra_checks, skill_gain_mult) + target.add_overlay(GLOB.welding_sparks) + . = ..() + target.cut_overlay(GLOB.welding_sparks) + /obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) if(!istype(H)) return ..() @@ -291,10 +298,10 @@ status = !status if(status) to_chat(user, "You resecure [src] and close the fuel tank.") - DISABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) + reagents.reagents_holder_flags &= ~(OPENCONTAINER) else to_chat(user, "[src] can now be attached, modified, and refuelled.") - ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) + reagents.reagents_holder_flags |= OPENCONTAINER add_fingerprint(user) /obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) @@ -385,6 +392,16 @@ icon_state = "clockwelder" item_state = "brasswelder" +/obj/item/weldingtool/experimental/ashwalker + name = "necropolis welding torch" + desc = "A mysterious welding tool with its origins in the depths of the necropolis. A mysterious force keeps replenishing its fuel." + resistance_flags = FIRE_PROOF | ACID_PROOF + refueling_interval = 5 + toolspeed = 0.75 + max_fuel = 20 + icon = 'icons/obj/mining.dmi' + icon_state = "ashwelder" + /obj/item/weldingtool/abductor name = "alien welding tool" desc = "An alien welding tool. Whatever fuel it uses, it never runs out." diff --git a/code/game/objects/items/tools/wirecutters.dm b/code/game/objects/items/tools/wirecutters.dm index 51bb046290..43648f8435 100644 --- a/code/game/objects/items/tools/wirecutters.dm +++ b/code/game/objects/items/tools/wirecutters.dm @@ -17,10 +17,9 @@ attack_verb = list("pinched", "nipped") hitsound = 'sound/items/wirecutter.ogg' usesound = 'sound/items/wirecutter.ogg' - tool_behaviour = TOOL_WIRECUTTER toolspeed = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) var/random_color = TRUE var/static/list/wirecutter_colors = list( "blue" = rgb(24, 97, 213), @@ -33,7 +32,7 @@ ) -/obj/item/wirecutters/Initialize() +/obj/item/wirecutters/Initialize(mapload) . = ..() if(random_color) //random colors! icon_state = "cutters" @@ -90,6 +89,14 @@ /obj/item/wirecutters/brass/family toolspeed = 1 +/obj/item/wirecutters/ashwalker + name = "bone wirecutters" + desc = "Rudimentary wirecutters made out of sharpened bones and sinew." + icon = 'icons/obj/mining.dmi' + icon_state = "cutters_bone" + toolspeed = 0.75 + random_color = FALSE + /obj/item/wirecutters/bronze name = "bronze plated wirecutters" desc = "A pair of wirecutters plated with bronze." @@ -118,7 +125,6 @@ desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a cutting head." icon_state = "jaws_cutter" item_state = "jawsoflife" - custom_materials = list(/datum/material/iron=150,/datum/material/silver=50,/datum/material/titanium=25) usesound = 'sound/items/jaws_cut.ogg' toolspeed = 0.25 @@ -153,7 +159,7 @@ var/man = C == user ? "your" : "[C]'\s" user.visible_message("[user] attempts to remove the durathread strand from around [man] neck.", \ "You attempt to remove the durathread strand from around [man] neck.") - if(do_after(user, 15, null, C)) + if(do_after(user, 1.5 SECONDS, C)) user.visible_message("[user] succesfuly removes the durathread strand.", "You succesfuly remove the durathread strand.") C.remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND) diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm index 6199e7fc76..8f60ab9d4a 100644 --- a/code/game/objects/items/tools/wrench.dm +++ b/code/game/objects/items/tools/wrench.dm @@ -17,7 +17,7 @@ attack_verb = list("bashed", "battered", "bludgeoned", "whacked") tool_behaviour = TOOL_WRENCH toolspeed = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) wound_bonus = -10 bare_wound_bonus = 5 @@ -44,6 +44,13 @@ /obj/item/wrench/brass/family toolspeed = 1 +/obj/item/wrench/ashwalker + name = "bone wrench" + desc = "A shoddy wrench made out of bent bones and sinew." + icon = 'icons/obj/mining.dmi' + icon_state = "wrench_bone" + toolspeed = 0.75 + /obj/item/wrench/bronze name = "bronze plated wrench" desc = "A bronze plated wrench." diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 547217366b..e6600d323e 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -44,7 +44,7 @@ item_state = "balloon-empty" -/obj/item/toy/balloon/Initialize() +/obj/item/toy/balloon/Initialize(mapload) . = ..() create_reagents(10) @@ -781,7 +781,7 @@ var/list/cards = list() var/original_size = 52 -/obj/item/toy/cards/deck/Initialize() +/obj/item/toy/cards/deck/Initialize(mapload) . = ..() populate_deck() @@ -1549,7 +1549,7 @@ icon_state = "shell1" var/static/list/possible_colors = list("" = 2, COLOR_PURPLE_GRAY = 1, COLOR_OLIVE = 1, COLOR_PALE_BLUE_GRAY = 1, COLOR_RED_GRAY = 1) -/obj/item/toy/seashell/Initialize() +/obj/item/toy/seashell/Initialize(mapload) . = ..() pixel_x = rand(-5, 5) pixel_y = rand(-5, 5) diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm index 1816f26843..857f3d8f4a 100644 --- a/code/game/objects/items/trash.dm +++ b/code/game/objects/items/trash.dm @@ -7,7 +7,7 @@ w_class = WEIGHT_CLASS_TINY resistance_flags = FLAMMABLE -/obj/item/trash/Initialize() +/obj/item/trash/Initialize(mapload) . = ..() AddElement(/datum/element/trash) diff --git a/code/game/objects/items/vending_items.dm b/code/game/objects/items/vending_items.dm index 2964d31259..325827c3d0 100755 --- a/code/game/objects/items/vending_items.dm +++ b/code/game/objects/items/vending_items.dm @@ -17,7 +17,7 @@ throw_speed = 1 throw_range = 7 w_class = WEIGHT_CLASS_BULKY - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 70, ACID = 30) // Built automatically from the corresponding vending machine. // If null, considered to be full. Otherwise, is list(/typepath = amount). diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index fe63e313de..fa8a0bd239 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -11,7 +11,7 @@ throw_range = 7 attack_verb = list("banned") max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 70) resistance_flags = FIRE_PROOF /obj/item/banhammer/suicide_act(mob/user) @@ -67,11 +67,11 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 block_chance = 50 sharpness = SHARP_EDGED max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF total_mass = TOTAL_MASS_MEDIEVAL_WEAPON -/obj/item/claymore/Initialize() +/obj/item/claymore/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 40, 105) AddElement(/datum/element/sword_point) @@ -97,7 +97,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 var/notches = 0 //HOW MANY PEOPLE HAVE BEEN SLAIN WITH THIS BLADE var/obj/item/disk/nuclear/nuke_disk //OUR STORED NUKE DISK -/obj/item/claymore/highlander/Initialize() +/obj/item/claymore/highlander/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, HIGHLANDER) START_PROCESSING(SSobj, src) @@ -223,7 +223,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon_state = "claymore_cyborg" var/mob/living/silicon/robot/robot -/obj/item/claymore/highlander/robot/Initialize() +/obj/item/claymore/highlander/robot/Initialize(mapload) var/obj/item/robot_module/kiltkit = loc robot = kiltkit.loc if(!istype(robot)) @@ -250,7 +250,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 block_chance = 50 sharpness = SHARP_EDGED max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF total_mass = TOTAL_MASS_MEDIEVAL_WEAPON @@ -262,7 +262,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/katana/cursed slot_flags = null -/obj/item/katana/cursed/Initialize() +/obj/item/katana/cursed/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CURSED_ITEM_TRAIT) @@ -369,7 +369,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /datum/block_parry_data/bokken/quick_parry/proj parry_efficiency_perfect_override = list() -/obj/item/melee/bokken/Initialize() +/obj/item/melee/bokken/Initialize(mapload) . = ..() AddElement(/datum/element/sword_point) if(!harm) //if initialised in non-harm mode, setup force accordingly @@ -583,6 +583,21 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 attack_verb = list("hit", "bludgeoned", "whacked", "bonked") wound_bonus = -10 +/obj/item/wirerod/Initialize(mapload) + . = ..() + + var/static/list/hovering_item_typechecks = list( + /obj/item/shard = list( + SCREENTIP_CONTEXT_LMB = list(INTENT_ANY = "Craft spear"), + ), + + /obj/item/assembly/igniter = list( + SCREENTIP_CONTEXT_LMB = list(INTENT_ANY = "Craft stunprod"), + ), + ) + + AddElement(/datum/element/contextual_screentip_item_typechecks, hovering_item_typechecks) + /obj/item/wirerod/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/shard)) var/obj/item/spear/S = new /obj/item/spear @@ -615,9 +630,9 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 name = "throwing star" desc = "An ancient weapon still used to this day, due to its ease of lodging itself into its victim's body parts." icon_state = "throwingstar" - item_state = "eshield0" - lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' + item_state = "throwingstar" + lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' force = 2 throwforce = 10 //10 + 2 (WEIGHT_CLASS_SMALL) * 4 (EMBEDDED_IMPACT_PAIN_MULTIPLIER) = 18 damage on hit due to guaranteed embedding throw_speed = 4 @@ -630,8 +645,10 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 resistance_flags = FIRE_PROOF /obj/item/throwing_star/stamina - name = "shock throwing star" + name = "energy throwing star" desc = "An aerodynamic disc designed to cause excruciating pain when stuck inside fleeing targets, hopefully without causing fatal harm." + icon_state = "energystar" + item_state = "energystar" throwforce = 5 embedding = list("pain_chance" = 5, "embed_chance" = 100, "fall_chance" = 0, "jostle_chance" = 10, "pain_stam_pct" = 0.8, "jostle_pain_mult" = 3) @@ -791,7 +808,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 tool_behaviour = TOOL_SAW toolspeed = 1 -/obj/item/mounted_chainsaw/Initialize() +/obj/item/mounted_chainsaw/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) @@ -819,7 +836,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 attack_verb = list("busted") var/impressiveness = 45 -/obj/item/statuebust/Initialize() +/obj/item/statuebust/Initialize(mapload) . = ..() AddElement(/datum/element/art, impressiveness) // AddComponent(/datum/component/beauty, 1000) @@ -926,7 +943,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 var/throwforce_off // Damage when off var/weight_class_on // What is the new size class when turned on -/obj/item/melee/baseball_bat/Initialize() +/obj/item/melee/baseball_bat/Initialize(mapload) . = ..() if(prob(1)) name = "cricket bat" @@ -944,7 +961,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 total_mass = TOTAL_MASS_MEDIEVAL_WEAPON wound_bonus = -5 -/obj/item/melee/baseball_bat/chaplain/Initialize() +/obj/item/melee/baseball_bat/chaplain/Initialize(mapload) . = ..() AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE) @@ -1074,7 +1091,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 //Things in this list will be instantly splatted. Flyman weakness is handled in the flyman species weakness proc. var/list/strong_against -/obj/item/melee/flyswatter/Initialize() +/obj/item/melee/flyswatter/Initialize(mapload) . = ..() strong_against = typecacheof(list( /mob/living/simple_animal/hostile/poison/bees/, @@ -1103,10 +1120,10 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon_state = "madeyoulook" force = 0 throwforce = 0 - item_flags = DROPDEL | ABSTRACT // | HAND_ITEM + item_flags = DROPDEL | ABSTRACT | HAND_ITEM attack_verb = list("bopped") -/obj/item/circlegame/Initialize() +/obj/item/circlegame/Initialize(mapload) . = ..() var/mob/living/owner = loc if(!istype(owner)) @@ -1205,7 +1222,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 item_state = "nothing" force = 0 throwforce = 0 - item_flags = DROPDEL | ABSTRACT // | HAND_ITEM + item_flags = DROPDEL | ABSTRACT | HAND_ITEM attack_verb = list("slapped") hitsound = 'sound/effects/snap.ogg' @@ -1225,6 +1242,120 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 return FALSE return TRUE +/obj/item/slapper/on_offered(mob/living/carbon/offerer) + . = TRUE + + if(!(locate(/mob/living/carbon) in orange(1, offerer))) + visible_message(span_danger("[offerer] raises [offerer.p_their()] arm, looking around for a high-five, but there's no one around!"), \ + span_warning("You post up, looking for a high-five, but finding no one within range!"), null, 2) + return + + offerer.visible_message(span_notice("[offerer] raises [offerer.p_their()] arm, looking for a high-five!"), \ + span_notice("You post up, looking for a high-five!"), null, 2) + offerer.apply_status_effect(STATUS_EFFECT_OFFERING, src, /atom/movable/screen/alert/give/highfive) + +/// Yeah broh! This is where we do the high-fiving (or high-tenning :o) +/obj/item/slapper/on_offer_taken(mob/living/carbon/offerer, mob/living/carbon/taker) + . = TRUE + + var/open_hands_taker + var/slappers_giver + for(var/i in taker.held_items) // see how many hands the taker has open for high'ing + if(isnull(i)) + open_hands_taker++ + + if(!open_hands_taker) + to_chat(taker, span_warning("You can't high-five [offerer] with no open hands!")) + SEND_SIGNAL(taker, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/high_five_full_hand) // not so successful now! + return + + for(var/i in offerer.held_items) + var/obj/item/slapper/slap_check = i + if(istype(slap_check)) + slappers_giver++ + + if(slappers_giver >= 2) // we only check this if it's already established the taker has 2+ hands free + offerer.visible_message(span_notice("[taker] enthusiastically high-tens [offerer]!"), span_nicegreen("Wow! You're high-tenned [taker]!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), ignored_mobs=taker) + to_chat(taker, span_nicegreen("You give high-tenning [offerer] your all!")) + playsound(offerer, 'sound/weapons/slap.ogg', 100, TRUE, 1) + SEND_SIGNAL(offerer, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/high_ten) + SEND_SIGNAL(taker, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/high_ten) + else + offerer.visible_message(span_notice("[taker] high-fives [offerer]!"), span_nicegreen("All right! You're high-fived by [taker]!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), ignored_mobs=taker) + to_chat(taker, span_nicegreen("You high-five [offerer]!")) + playsound(offerer, 'sound/weapons/slap.ogg', 50, TRUE, -1) + SEND_SIGNAL(offerer, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/high_five) + SEND_SIGNAL(taker, COMSIG_ADD_MOOD_EVENT, "high_five", /datum/mood_event/high_five) + qdel(src) + +/// Gangster secret handshakes. +/obj/item/slapper/secret_handshake + name = "Secret Handshake" + icon_state = "recruit" + icon = 'icons/obj/gang/actions.dmi' + /// References the active families gamemode handler (if one exists), for adding new family members to. + var/datum/gang_handler/handler + /// The typepath of the gang antagonist datum that the person who uses the package should have added to them -- remember that the distinction between e.g. Ballas and Grove Street is on the antag datum level, not the team datum level. + var/gang_to_use + /// The team datum that the person who uses this package should be added to. + var/datum/team/gang/team_to_use + + +/// Adds the user to the family that this package corresponds to, dispenses the free_clothes of that family, and adds them to the handler if it exists. +/obj/item/slapper/secret_handshake/proc/add_to_gang(mob/living/user, original_name) + var/datum/antagonist/gang/swappin_sides = new gang_to_use() + swappin_sides.original_name = original_name + swappin_sides.handler = handler + user.mind.add_antag_datum(swappin_sides, team_to_use) + var/policy = get_policy(ROLE_FAMILIES) + if(policy) + to_chat(user, policy) + team_to_use.add_member(user.mind) + swappin_sides.equip_gangster_in_inventory() + if (!isnull(handler) && !handler.gangbangers.Find(user.mind)) // if we have a handler and they're not tracked by it + handler.gangbangers += user.mind + +/// Checks if the user is trying to use the package of the family they are in, and if not, adds them to the family, with some differing processing depending on whether the user is already a family member. +/obj/item/slapper/secret_handshake/proc/attempt_join_gang(mob/living/user) + if(!user?.mind) + return + var/datum/antagonist/gang/is_gangster = user.mind.has_antag_datum(/datum/antagonist/gang) + var/real_name_backup = user.real_name + if(is_gangster) + if(is_gangster.my_gang == team_to_use) + return + real_name_backup = is_gangster.original_name + is_gangster.my_gang.remove_member(user.mind) + user.mind.remove_antag_datum(/datum/antagonist/gang) + add_to_gang(user, real_name_backup) + +/obj/item/slapper/secret_handshake/on_offer_taken(mob/living/carbon/offerer, mob/living/carbon/taker) + . = TRUE + if (!(null in taker.held_items)) + to_chat(taker, span_warning("You can't get taught the secret handshake if [offerer] has no free hands!")) + return + + if(HAS_TRAIT(taker, TRAIT_MINDSHIELD)) + to_chat(taker, "You attended a seminar on not signing up for a gang and are not interested.") + return + + var/datum/antagonist/gang/is_gangster = taker.mind.has_antag_datum(/datum/antagonist/gang) + if(is_gangster?.starter_gangster) + if(is_gangster.my_gang == team_to_use) + to_chat(taker, "You started your family. You don't need to join it.") + return + to_chat(taker, "You started your family. You can't turn your back on it now.") + return + + offerer.visible_message(span_notice("[taker] is taught the secret handshake by [offerer]!"), span_nicegreen("All right! You've taught the secret handshake to [taker]!"), span_hear("You hear a bunch of weird shuffling and flesh slapping sounds!"), ignored_mobs=taker) + to_chat(taker, span_nicegreen("You get taught the secret handshake by [offerer]!")) + var/datum/antagonist/gang/owner_gang_datum = offerer.mind.has_antag_datum(/datum/antagonist/gang) + handler = owner_gang_datum.handler + gang_to_use = owner_gang_datum.type + team_to_use = owner_gang_datum.my_gang + attempt_join_gang(taker) + qdel(src) + /obj/item/extendohand name = "extendo-hand" desc = "Futuristic tech has allowed these classic spring-boxing toys to essentially act as a fully functional hand-operated hand prosthetic." @@ -1259,7 +1390,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 // attack_verb_simple = list("whack", "thwack", "wallop", "sock") // icon = 'icons/obj/items_and_weapons.dmi' // icon_state = "gohei" -// inhand_icon_state = "gohei" +// item_state = "gohei" // lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi' // righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi' @@ -1282,7 +1413,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 hitsound = 'sound/weapons/bladeslice.ogg' var/wielded = FALSE // track wielded status on item -/obj/item/vibro_weapon/Initialize() +/obj/item/vibro_weapon/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield) RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield) diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 78a5c9ece9..e7ab7214b7 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -22,7 +22,7 @@ //returns the damage value of the attack after processing the obj's various armor protections /obj/proc/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir, armour_penetration = 0) - if(damage_flag == MELEE && damage_amount < damage_deflection) + if(damage_flag == MELEE && damage_amount < damage_deflection) // TODO: Refactor armor datums and types entirely jfc return 0 switch(damage_type) if(BRUTE) @@ -54,9 +54,9 @@ var/obj/O = AM if(O.damtype == STAMINA) throwdamage = 0 - take_damage(throwdamage, BRUTE, "melee", 1, get_dir(src, AM)) + take_damage(throwdamage, BRUTE, MELEE, 1, get_dir(src, AM)) -/obj/ex_act(severity, target) +/obj/ex_act(severity, target, origin) if(resistance_flags & INDESTRUCTIBLE) return ..() //contents explosion @@ -69,9 +69,9 @@ obj_integrity = 0 qdel(src) if(2) - take_damage(rand(100, 250), BRUTE, "bomb", 0) + take_damage(rand(100, 250), BRUTE, BOMB, 0) if(3) - take_damage(rand(10, 90), BRUTE, "bomb", 0) + take_damage(rand(10, 90), BRUTE, BOMB, 0) /obj/wave_ex_act(power, datum/wave_explosion/explosion, dir) if(resistance_flags & INDESTRUCTIBLE) @@ -81,7 +81,7 @@ obj_integrity = 0 qdel(src) return - take_damage(wave_explosion_damage(power, explosion), BRUTE, "bomb", 0) + take_damage(wave_explosion_damage(power, explosion), BRUTE, BOMB, 0) /obj/proc/wave_explosion_damage(power, datum/wave_explosion/explosion) return (explosion_flags & EXPLOSION_FLAG_HARD_OBSTACLE)? EXPLOSION_POWER_STANDARD_SCALE_HARD_OBSTACLE_DAMAGE(power, explosion.hard_obstacle_mod) : EXPLOSION_POWER_STANDARD_SCALE_OBJECT_DAMAGE(power, explosion.object_damage_mod) @@ -106,7 +106,7 @@ user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced="hulk") else playsound(src, 'sound/effects/bang.ogg', 50, 1) - take_damage(hulk_damage(), BRUTE, "melee", 0, get_dir(src, user)) + take_damage(hulk_damage(), BRUTE, MELEE, 0, get_dir(src, user)) return 1 return 0 @@ -115,7 +115,7 @@ var/turf/T = loc if(T.intact && level == 1) //the blob doesn't destroy thing below the floor return - take_damage(400, BRUTE, "melee", 0, get_dir(src, B)) + take_damage(400, BRUTE, MELEE, 0, get_dir(src, B)) /obj/proc/attack_generic(mob/user, damage_amount = 0, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, armor_penetration = 0) //used by attack_alien, attack_animal, and attack_slime if(SEND_SIGNAL(src, COMSIG_OBJ_ATTACK_GENERIC, user, damage_amount, damage_type, damage_flag, sound_effect, armor_penetration) & COMPONENT_STOP_GENERIC_ATTACK) @@ -127,7 +127,7 @@ user.DelayNextAction(CLICK_CD_MELEE) /obj/attack_alien(mob/living/carbon/alien/humanoid/user) - if(attack_generic(user, 60, BRUTE, "melee", 0)) + if(attack_generic(user, 60, BRUTE, MELEE, 0)) playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) /obj/attack_animal(mob/living/simple_animal/M) @@ -141,9 +141,9 @@ if(M.environment_smash) play_soundeffect = 0 if(M.obj_damage) - . = attack_generic(M, M.obj_damage, M.melee_damage_type, "melee", play_soundeffect, M.armour_penetration) + . = attack_generic(M, M.obj_damage, M.melee_damage_type, MELEE, play_soundeffect, M.armour_penetration) else - . = attack_generic(M, rand(M.melee_damage_lower,M.melee_damage_upper), M.melee_damage_type, "melee", play_soundeffect, M.armour_penetration) + . = attack_generic(M, rand(M.melee_damage_lower,M.melee_damage_upper), M.melee_damage_type, MELEE, play_soundeffect, M.armour_penetration) if(. && !play_soundeffect) playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) @@ -167,30 +167,10 @@ return if(istype(src, /obj/machinery/atmospherics)) return - attack_generic(user, rand(10, 15), BRUTE, "melee", 1) + attack_generic(user, rand(10, 15), BRUTE, MELEE, 1) #undef BLACKLISTED_OBJECTS -/obj/mech_melee_attack(obj/mecha/M) - M.do_attack_animation(src) - var/play_soundeffect = 0 - var/mech_damtype = M.damtype - if(M.selected) - mech_damtype = M.selected.damtype - play_soundeffect = 1 - else - switch(M.damtype) - if(BRUTE) - playsound(src, 'sound/weapons/punch4.ogg', 50, 1) - if(BURN) - playsound(src, 'sound/items/welder.ogg', 50, 1) - if(TOX) - playsound(src, 'sound/effects/spray2.ogg', 50, 1) - return 0 - else - return 0 - visible_message("[M.name] has hit [src].", null, null, COMBAT_MESSAGE_RANGE) - return take_damage(M.force*3, mech_damtype, "melee", play_soundeffect, get_dir(src, M)) // multiplied by 3 so we can hit objs hard but not be overpowered against mobs. /obj/singularity_act() ex_act(EXPLODE_DEVASTATE) @@ -201,7 +181,7 @@ ///// ACID -GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/effects/effects.dmi', "acid")) +GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/effects/effects.dmi', ACID)) //the obj's reaction when touched by acid /obj/acid_act(acidpwr, acid_volume) @@ -231,7 +211,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e if(T.intact && level == 1) //fire can't damage things hidden below the floor. return if(exposed_temperature && !(resistance_flags & FIRE_PROOF)) - take_damage(clamp(0.02 * exposed_temperature, 0, 20), BURN, "fire", 0) + take_damage(clamp(0.02 * exposed_temperature, 0, 20), BURN, FIRE, 0) if(!(resistance_flags & ON_FIRE) && (resistance_flags & FLAMMABLE)) resistance_flags |= ON_FIRE SSfire_burning.processing[src] = src @@ -280,9 +260,9 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e //what happens when the obj's integrity reaches zero. /obj/proc/obj_destruction(damage_flag) - if(damage_flag == "acid") + if(damage_flag == ACID) acid_melt() - else if(damage_flag == "fire") + else if(damage_flag == FIRE) burn() else deconstruct(FALSE) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 58c571d9e6..cfe1afad5a 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -7,6 +7,8 @@ var/obj_flags = CAN_BE_HIT var/set_obj_flags // ONLY FOR MAPPING: Sets flags from a string list, handled in Initialize. Usage: set_obj_flags = "EMAGGED;!CAN_BE_HIT" to set EMAGGED and clear CAN_BE_HIT. + var/minimap_override_color // allows this obj to set its own color on the minimap + var/damtype = BRUTE var/force = 0 @@ -26,9 +28,17 @@ var/resistance_flags = NONE // INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ON_FIRE | UNACIDABLE | ACID_PROOF var/persistence_replacement //have something WAY too amazing to live to the next round? Set a new path here. Overuse of this var will make me upset. - var/current_skin //the item reskin - var/list/unique_reskin //List of options to reskin. + + //Reskin variables + /// The item reskin + var/current_skin + /// List of options to reskin. + var/list/unique_reskin + /// Can always be modified var/always_reskinnable = FALSE + /// How to bring up the reskinning menu + var/reskin_binding = COMSIG_CLICK_ALT + // // Access levels, used in modules\jobs\access.dm var/list/req_access @@ -48,7 +58,7 @@ return FALSE return ..() -/obj/Initialize() +/obj/Initialize(mapload) if (islist(armor)) armor = getArmor(arglist(armor)) else if (!armor) @@ -74,6 +84,10 @@ var/turf/T = loc T.add_blueprints_preround(src) +/obj/ComponentInitialize() + . = ..() + if(islist(unique_reskin) && length(unique_reskin)) + AddElement(/datum/element/object_reskinning) /obj/Destroy(force=FALSE) if(!ismachinery(src)) @@ -238,7 +252,22 @@ /obj/get_dumping_location(datum/component/storage/source,mob/user) return get_turf(src) -/obj/proc/CanAStarPass() +/** + * This proc is used for telling whether something can pass by this object in a given direction, for use by the pathfinding system. + * + * Trying to generate one long path across the station will call this proc on every single object on every single tile that we're seeing if we can move through, likely + * multiple times per tile since we're likely checking if we can access said tile from multiple directions, so keep these as lightweight as possible. + * + * Arguments: + * * ID- An ID card representing what access we have (and thus if we can open things like airlocks or windows to pass through them). The ID card's physical location does not matter, just the reference + * * to_dir- What direction we're trying to move in, relevant for things like directional windows that only block movement in certain directions + * * caller- The movable we're checking pass flags for, if we're making any such checks + **/ +/obj/proc/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller) + if(ismovable(caller)) + var/atom/movable/AM = caller + if(AM.pass_flags & pass_flags_self) + return TRUE . = !density /obj/proc/check_uplink_validity() @@ -269,15 +298,15 @@ if (islist(result)) if (result["button"] != 2) // If the user pressed the cancel button // text2num conveniently returns a null on invalid values - armor = armor.setRating(melee = text2num(result["values"]["melee"]),\ - bullet = text2num(result["values"]["bullet"]),\ - laser = text2num(result["values"]["laser"]),\ - energy = text2num(result["values"]["energy"]),\ - bomb = text2num(result["values"]["bomb"]),\ - bio = text2num(result["values"]["bio"]),\ - rad = text2num(result["values"]["rad"]),\ - fire = text2num(result["values"]["fire"]),\ - acid = text2num(result["values"]["acid"])) + armor = armor.setRating(melee = text2num(result["values"][MELEE]),\ + bullet = text2num(result["values"][BULLET]),\ + laser = text2num(result["values"][LASER]),\ + energy = text2num(result["values"][ENERGY]),\ + bomb = text2num(result["values"][BOMB]),\ + bio = text2num(result["values"][BIO]),\ + rad = text2num(result["values"][RAD]),\ + fire = text2num(result["values"][FIRE]),\ + acid = text2num(result["values"][ACID])) log_admin("[key_name(usr)] modified the armor on [src] ([type]) to melee: [armor.melee], bullet: [armor.bullet], laser: [armor.laser], energy: [armor.energy], bomb: [armor.bomb], bio: [armor.bio], rad: [armor.rad], fire: [armor.fire], acid: [armor.acid]") message_admins("[key_name_admin(usr)] modified the armor on [src] ([type]) to melee: [armor.melee], bullet: [armor.bullet], laser: [armor.laser], energy: [armor.energy], bomb: [armor.bomb], bio: [armor.bio], rad: [armor.rad], fire: [armor.fire], acid: [armor.acid]") if(href_list[VV_HK_MASS_DEL_TYPE]) @@ -323,50 +352,10 @@ . = ..() if(obj_flags & UNIQUE_RENAME) . += "Use a pen on it to rename it or change its description." - if(unique_reskin && (!current_skin || always_reskinnable)) - . += "Alt-click it to reskin it." -/obj/AltClick(mob/user) - . = ..() - if(unique_reskin && (!current_skin || always_reskinnable) && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) - reskin_obj(user) - return TRUE - -/obj/proc/reskin_obj(mob/M) - if(!LAZYLEN(unique_reskin)) - return - - var/list/items = list() - for(var/reskin_option in unique_reskin) - var/image/item_image = image(icon = src.icon, icon_state = unique_reskin[reskin_option]) - items += list("[reskin_option]" = item_image) - sortList(items) - - var/pick = show_radial_menu(M, src, items, custom_check = CALLBACK(src, .proc/check_reskin_menu, M), radius = 38, require_near = TRUE) - if(!pick) - return - if(!unique_reskin[pick]) - return - current_skin = pick - icon_state = unique_reskin[pick] - to_chat(M, "[src] is now skinned as '[pick].'") - -/** - * Checks if we are allowed to interact with a radial menu for reskins - * - * Arguments: - * * user The mob interacting with the menu - */ -/obj/proc/check_reskin_menu(mob/user) - if(QDELETED(src)) - return FALSE - if(current_skin) - return FALSE - if(!istype(user)) - return FALSE - if(user.incapacitated()) - return FALSE - return TRUE +/// Do you want to make overrides, of course you do! Will be called if an object was reskinned successfully +/obj/proc/reskin_obj(mob/user) + return /obj/update_overlays() . = ..() @@ -383,3 +372,34 @@ /obj/proc/plunger_act(obj/item/plunger/P, mob/living/user, reinforced) return + + +//For returning special data when the object is saved +//For example, or silos will return a list of their materials which will be dumped on top of them +//Can be customised if you have something that contains something you want saved +//If you put an incorrect format it will break outputting, so don't use this if you don't know what you are doing +//NOTE: Contents is automatically saved, so if you store your things in the contents var, don't worry about this +//====Output Format Examples====: +//===Single Object=== +// "/obj/item/folder/blue" +//===Multiple Objects=== +// "/obj/item/folder/blue,\n +// /obj/item/folder/red" +//===Single Object with metadata=== +// "/obj/item/folder/blue{\n +// \tdir = 8;\n +// \tname = "special folder"\n +// \t}" +//===Multiple Objects with metadata=== +// "/obj/item/folder/blue{\n +// \tdir = 8;\n +// \tname = "special folder"\n +// \t},\n +// /obj/item/folder/red" +//====How to save easily====: +// return "[thing.type][generate_tgm_metadata(thing)]" +//Where thing is the additional thing you want to same (For example ores inside an ORM) +//Just add ,\n between each thing +//generate_tgm_metadata(thing) handles everything inside the {} for you +/obj/proc/on_object_saved(depth) + return "" diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 52036427c8..4192a44150 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -10,13 +10,15 @@ var/broken = 0 //similar to machinery's stat BROKEN layer = BELOW_OBJ_LAYER //ricochets on structures commented out for now because there's a lot of structures that /shouldnt/ be ricocheting and those need to be reviewed first + //With the addition of [pass_flags_self] the ricocheting of structures /shouldnt/ happen by default thus the existing code could be uncommented out - Solaris-Shade //flags_1 = DEFAULT_RICOCHET_1 //flags_ricochet = RICOCHET_HARD //ricochet_chance_mod = 0.5 + pass_flags_self = PASSSTRUCTURE -/obj/structure/Initialize() +/obj/structure/Initialize(mapload) if (!armor) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) . = ..() if(smooth) queue_smooth(src) @@ -63,7 +65,7 @@ /obj/structure/proc/do_climb(atom/movable/A) if(climbable) density = FALSE - . = step(A,get_dir(A,src.loc)) + . = step(A, (A.loc == loc ? dir : get_dir(A,src.loc))) density = TRUE /obj/structure/proc/climb_structure(mob/living/user) @@ -102,6 +104,12 @@ if(examine_status) . += examine_status +/obj/structure/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() + + if(mover.pass_flags & PASSSTRUCTURE) + return TRUE + /obj/structure/proc/examine_status(mob/user) //An overridable proc, mostly for falsewalls. var/healthpercent = (obj_integrity/max_integrity) * 100 switch(healthpercent) @@ -114,4 +122,4 @@ return "It's falling apart!" /obj/structure/rust_heretic_act() - take_damage(500, BRUTE, "melee", 1) + take_damage(500, BRUTE, MELEE, 1) diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm index 339c2773e5..85ee3f9f56 100644 --- a/code/game/objects/structures/ai_core.dm +++ b/code/game/objects/structures/ai_core.dm @@ -12,7 +12,7 @@ var/obj/item/mmi/brain = null var/can_deconstruct = TRUE -/obj/structure/AIcore/Initialize() +/obj/structure/AIcore/Initialize(mapload) . = ..() laws = new laws.set_laws_config() @@ -67,7 +67,7 @@ return return ..() -/obj/structure/AIcore/latejoin_inactive/Initialize() +/obj/structure/AIcore/latejoin_inactive/Initialize(mapload) . = ..() GLOB.latejoin_ai_cores += src diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index bc7ce8c36e..6c30b20ccd 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -97,11 +97,6 @@ /obj/structure/alien/resin/attack_paw(mob/user) return attack_hand(user) - -/obj/structure/alien/resin/CanPass(atom/movable/mover, turf/target) - return !density - - /* * Weeds */ @@ -125,7 +120,7 @@ var/growth_cooldown_high = 200 var/static/list/blacklisted_turfs -/obj/structure/alien/weeds/Initialize() +/obj/structure/alien/weeds/Initialize(mapload) pixel_x = -4 pixel_y = -4 //so the sprites line up right in the map editor . = ..() @@ -177,7 +172,7 @@ var/lon_range = 4 var/node_range = NODERANGE -/obj/structure/alien/weeds/node/Initialize() +/obj/structure/alien/weeds/node/Initialize(mapload) icon = 'icons/obj/smooth_structures/alien/weednode.dmi' . = ..() set_light(lon_range) diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm index 9b2f305b42..7592385abf 100644 --- a/code/game/objects/structures/artstuff.dm +++ b/code/game/objects/structures/artstuff.dm @@ -52,6 +52,8 @@ var/author_ckey var/icon_generated = FALSE var/icon/generated_icon + ///boolean that blocks persistence from saving it. enabled from printing copies, because we do not want to save copies. + var/no_save = FALSE // Painting overlay offset when framed var/framed_offset_x = 11 @@ -60,7 +62,7 @@ pixel_x = 10 pixel_y = 9 -/obj/item/canvas/Initialize() +/obj/item/canvas/Initialize(mapload) . = ..() reset_grid() @@ -370,7 +372,7 @@ update_icon() /obj/structure/sign/painting/proc/save_persistent() - if(!persistence_id || !current_canvas) + if(!persistence_id || !current_canvas || current_canvas.no_save) return if(sanitize_filename(persistence_id) != persistence_id) stack_trace("Invalid persistence_id - [persistence_id]") diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm index a96d39316e..91c43dc238 100644 --- a/code/game/objects/structures/barsigns.dm +++ b/code/game/objects/structures/barsigns.dm @@ -6,12 +6,12 @@ req_access = list(ACCESS_BAR) max_integrity = 500 integrity_failure = 0.5 - armor = list("melee" = 20, "bullet" = 20, "laser" = 20, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) buildable_sign = 0 var/list/barsigns=list() var/panel_open = FALSE -/obj/structure/sign/barsign/Initialize() +/obj/structure/sign/barsign/Initialize(mapload) . = ..() //filling the barsigns list diff --git a/code/game/objects/structures/beds_chairs/alien_nest.dm b/code/game/objects/structures/beds_chairs/alien_nest.dm index 77b3279517..eff87d3955 100644 --- a/code/game/objects/structures/beds_chairs/alien_nest.dm +++ b/code/game/objects/structures/beds_chairs/alien_nest.dm @@ -34,7 +34,7 @@ "[M.name] struggles to break free from the gelatinous resin!",\ "You struggle to break free from the gelatinous resin... (Stay still for two minutes.)",\ "You hear squelching...") - if(!do_after(M, 1200, target = src)) + if(!do_after(M, 2 MINUTES, target = src, timed_action_flags = (IGNORE_HELD_ITEM | IGNORE_INCAPACITATED), extra_checks = CALLBACK(M, TYPE_PROC_REF(/mob/living/carbon, cuff_resist_check)))) if(M && M.buckled) to_chat(M, "You fail to unbuckle yourself!") return @@ -48,8 +48,8 @@ unbuckle_mob(M) add_fingerprint(user) -/obj/structure/bed/nest/user_buckle_mob(mob/living/M, mob/living/user) - if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.incapacitated() || M.buckled ) +/obj/structure/bed/nest/user_buckle_mob(mob/living/M, mob/living/carbon/user) + if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || !user.cuff_resist_check() || M.buckled ) return if(M.getorgan(/obj/item/organ/alien/plasmavessel)) diff --git a/code/game/objects/structures/beds_chairs/bed.dm b/code/game/objects/structures/beds_chairs/bed.dm index c86c62094b..8f5e1c5079 100644 --- a/code/game/objects/structures/beds_chairs/bed.dm +++ b/code/game/objects/structures/beds_chairs/bed.dm @@ -53,6 +53,12 @@ else return ..() +/obj/structure/bed/post_buckle_mob(mob/living/target) + target.pixel_y = target.get_standard_pixel_y_offset(TRUE) + +/obj/structure/bed/double/post_unbuckle_mob(mob/living/target) + target.pixel_y = target.get_standard_pixel_y_offset(FALSE) + /* * Roller beds */ @@ -214,3 +220,24 @@ name = "resting contraption" desc = "This looks similar to contraptions from Earth. Could aliens be stealing our technology?" icon_state = "abed" + +//Double Beds, for luxurious sleeping, i.e. the captain and maybe heads- Do use this for ERP +/obj/structure/bed/double + name = "double bed" + desc = "A luxurious double bed, for those too important for small dreams." + icon_state = "bed_double" + buildstackamount = 4 + max_buckled_mobs = 2 + ///The mob who buckled to this bed second, to avoid other mobs getting pixel-shifted before he unbuckles. + var/mob/living/goldilocks + +/obj/structure/bed/double/post_buckle_mob(mob/living/target) + target.pixel_y = target.get_standard_pixel_y_offset(TRUE) + if(buckled_mobs.len > 1 && !goldilocks) //Push the second buckled mob a bit higher from the normal lying position + target.pixel_y = target.get_standard_pixel_y_offset(FALSE) + 6 + goldilocks = target + +/obj/structure/bed/double/post_unbuckle_mob(mob/living/target) + target.pixel_y = target.get_standard_pixel_y_offset(FALSE) + if(target == goldilocks) + goldilocks = null diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index 89f018f291..9d14757897 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -21,7 +21,7 @@ if(!has_buckled_mobs()) . += "Drag your sprite to sit in it." -/obj/structure/chair/Initialize() +/obj/structure/chair/Initialize(mapload) . = ..() if(!anchored) //why would you put these on the shuttle? addtimer(CALLBACK(src, .proc/RemoveFromLatejoin), 0) @@ -190,7 +190,7 @@ item_chair = null var/mutable_appearance/armrest -/obj/structure/chair/comfy/Initialize() +/obj/structure/chair/comfy/Initialize(mapload) armrest = GetArmrest() armrest.layer = ABOVE_MOB_LAYER return ..() diff --git a/code/game/objects/structures/beds_chairs/pew.dm b/code/game/objects/structures/beds_chairs/pew.dm index ec257a9898..27f67ba0be 100644 --- a/code/game/objects/structures/beds_chairs/pew.dm +++ b/code/game/objects/structures/beds_chairs/pew.dm @@ -14,7 +14,7 @@ icon_state = "pewend_left" var/mutable_appearance/leftpewarmrest -/obj/structure/chair/pew/left/Initialize() +/obj/structure/chair/pew/left/Initialize(mapload) leftpewarmrest = GetLeftPewArmrest() leftpewarmrest.layer = ABOVE_MOB_LAYER return ..() @@ -45,7 +45,7 @@ icon_state = "pewend_right" var/mutable_appearance/rightpewarmrest -/obj/structure/chair/pew/right/Initialize() +/obj/structure/chair/pew/right/Initialize(mapload) rightpewarmrest = GetRightPewArmrest() rightpewarmrest.layer = ABOVE_MOB_LAYER return ..() diff --git a/code/game/objects/structures/beds_chairs/sofa.dm b/code/game/objects/structures/beds_chairs/sofa.dm index 48352814b5..b7968d84f4 100644 --- a/code/game/objects/structures/beds_chairs/sofa.dm +++ b/code/game/objects/structures/beds_chairs/sofa.dm @@ -6,7 +6,7 @@ item_chair = null var/mutable_appearance/armrest -/obj/structure/chair/sofa/Initialize() +/obj/structure/chair/sofa/Initialize(mapload) armrest = mutable_appearance(icon, "[icon_state]_armrest", ABOVE_MOB_LAYER) return ..() diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 2172040022..2c3b0545f8 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -4,6 +4,41 @@ BEDSHEETS LINEN BINS */ +#define BEDSHEET_SINGLE "single" +#define BEDSHEET_DOUBLE "double" + +GLOBAL_LIST_INIT(double_bedsheets, list(/obj/item/bedsheet/double, + /obj/item/bedsheet/blue/double, + /obj/item/bedsheet/green/double, + /obj/item/bedsheet/grey/double, + /obj/item/bedsheet/orange/double, + /obj/item/bedsheet/purple/double, + /obj/item/bedsheet/patriot/double, + /obj/item/bedsheet/rainbow/double, + /obj/item/bedsheet/red/double, + /obj/item/bedsheet/yellow/double, + /obj/item/bedsheet/mime/double, + /obj/item/bedsheet/clown/double, + /obj/item/bedsheet/captain/double, + /obj/item/bedsheet/rd/double, + /obj/item/bedsheet/medical/double, + /obj/item/bedsheet/cmo/double, + /obj/item/bedsheet/hos/double, + /obj/item/bedsheet/hop/double, + /obj/item/bedsheet/ce/double, + /obj/item/bedsheet/qm/double, + /obj/item/bedsheet/chaplain/double, + /obj/item/bedsheet/brown/double, + /obj/item/bedsheet/black/double, + /obj/item/bedsheet/centcom/double, + /obj/item/bedsheet/syndie/double, + /obj/item/bedsheet/cult/double, + /obj/item/bedsheet/wiz/double, + /obj/item/bedsheet/nanotrasen/double, + /obj/item/bedsheet/ian/double, + /obj/item/bedsheet/cosmos/double + )) + /obj/item/bedsheet name = "bedsheet" desc = "A surprisingly soft linen bedsheet." @@ -21,10 +56,22 @@ LINEN BINS dog_fashion = /datum/dog_fashion/head/ghost var/list/dream_messages = list("white") + var/stack_amount = 3 + var/bedsheet_type = BEDSHEET_SINGLE /obj/item/bedsheet/Initialize(mapload) . = ..() AddElement(/datum/element/bed_tuckable, 0, 0, 0) + if(bedsheet_type == BEDSHEET_DOUBLE) + stack_amount *= 2 + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + register_item_context() + +/obj/item/bedsheet/add_item_context(obj/item/source, list/context, atom/target, mob/living/user) + . = ..() + if(iscarbon(target)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Prepare Surgery") + return CONTEXTUAL_SCREENTIP_SET /obj/item/bedsheet/attack(mob/living/M, mob/user) if(!attempt_initiate_surgery(src, M, user)) @@ -46,7 +93,7 @@ LINEN BINS /obj/item/bedsheet/attackby(obj/item/I, mob/user, params) if(!(flags_1 & HOLOGRAM_1) && (I.tool_behaviour == TOOL_WIRECUTTER || I.get_sharpness())) - var/obj/item/stack/sheet/cloth/C = new (get_turf(src), 3) + var/obj/item/stack/sheet/cloth/C = new (get_turf(src), stack_amount) transfer_fingerprints_to(C) C.add_fingerprint(user) qdel(src) @@ -219,7 +266,7 @@ LINEN BINS var/g_mouth var/g_eyes -/obj/item/bedsheet/gondola/Initialize() +/obj/item/bedsheet/gondola/Initialize(mapload) . = ..() g_mouth = "sheetgondola_mouth[rand(1, 4)]" g_eyes = "sheetgondola_eyes[rand(1, 4)]" @@ -245,11 +292,173 @@ LINEN BINS name = "random bedsheet" desc = "If you're reading this description ingame, something has gone wrong! Honk!" -/obj/item/bedsheet/random/Initialize() +/obj/item/bedsheet/random/Initialize(mapload) ..() - var/type = pick(typesof(/obj/item/bedsheet) - (list(/obj/item/bedsheet/random, /obj/item/bedsheet/chameleon) + typesof(/obj/item/bedsheet/unlockable))) - new type(loc) - return INITIALIZE_HINT_QDEL + if(bedsheet_type == BEDSHEET_SINGLE) + var/type = pick(typesof(/obj/item/bedsheet) - (list(/obj/item/bedsheet/random, /obj/item/bedsheet/chameleon) + typesof(/obj/item/bedsheet/unlockable) + GLOB.double_bedsheets)) + new type(loc) + return INITIALIZE_HINT_QDEL + +/obj/item/bedsheet/double + icon_state = "double_sheetwhite" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/blue/double + icon_state = "double_sheetblue" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/green/double + icon_state = "double_sheetgreen" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/grey/double + icon_state = "double_sheetgrey" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/orange/double + icon_state = "double_sheetorange" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/purple/double + icon_state = "double_sheetpurple" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/patriot/double + icon_state = "double_sheetUSA" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/rainbow/double + icon_state = "double_sheetrainbow" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/red/double + icon_state = "double_sheetred" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/yellow/double + icon_state = "double_sheetyellow" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/mime/double + icon_state = "double_sheetmime" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/clown/double + icon_state = "double_sheetclown" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/captain/double + icon_state = "double_sheetcaptain" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/rd/double + icon_state = "double_sheetrd" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/medical/double + icon_state = "double_sheetmedical" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/cmo/double + icon_state = "double_sheetcmo" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/hos/double + icon_state = "double_sheethos" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/hop/double + icon_state = "double_sheethop" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/ce/double + icon_state = "double_sheetce" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/qm/double + icon_state = "double_sheetqm" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/chaplain/double + icon_state = "double_sheetchap" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/brown/double + icon_state = "double_sheetbrown" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/black/double + icon_state = "double_sheetblack" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/centcom/double + icon_state = "double_sheetcentcom" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/syndie/double + icon_state = "double_sheetsyndie" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/cult/double + icon_state = "double_sheetcult" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/wiz/double + icon_state = "double_sheetwiz" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/nanotrasen/double + icon_state = "double_sheetNT" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/ian/double + icon_state = "double_sheetian" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/cosmos/double + icon_state = "double_sheetcosmos" + dying_key = DYE_REGISTRY_DOUBLE_BEDSHEET + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/random/double + icon_state = "random_bedsheet" + bedsheet_type = BEDSHEET_DOUBLE + +/obj/item/bedsheet/random/double/Initialize(mapload) + ..() + if(bedsheet_type == BEDSHEET_DOUBLE) + var/type = pick(GLOB.double_bedsheets) + new type(loc) + return INITIALIZE_HINT_QDEL /obj/item/bedsheet/chameleon //donator chameleon bedsheet name = "chameleon bedsheet" diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 4e57a2f717..d90d44ddfd 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -6,7 +6,7 @@ density = TRUE max_integrity = 200 integrity_failure = 0.25 - armor = list("melee" = 20, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 60) + armor = list(MELEE = 20, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 70, ACID = 60) var/icon_door = null var/icon_door_override = FALSE //override to have open overlay use icon different to its base's @@ -110,10 +110,10 @@ if(HAS_TRAIT(user, TRAIT_SKITTISH)) . += "If you bump into [p_them()] while running, you will jump inside." -/obj/structure/closet/CanPass(atom/movable/mover, turf/target) +/obj/structure/closet/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(wall_mounted) return TRUE - return !density /obj/structure/closet/proc/can_open(mob/living/user, force = FALSE) if(force) @@ -156,9 +156,10 @@ for(var/atom/movable/AM in L) if(AM != src && insert(AM) == -1) // limit reached break - // for(var/i in reverseRange(L.GetAllContents())) - // var/atom/movable/thing = i - // SEND_SIGNAL(thing, COMSIG_TRY_STORAGE_HIDE_ALL) + // todo: this should be unnecessary, storage should auto close on move wtf + for(var/i in reverseRange(L.GetAllContents())) + var/atom/movable/thing = i + SEND_SIGNAL(thing, COMSIG_TRY_STORAGE_HIDE_ALL) /obj/structure/closet/proc/open(mob/living/user, force = FALSE) if(!can_open(user, force)) @@ -467,7 +468,7 @@ user.visible_message("[src] begins to shake violently!", \ "You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)", \ "You hear banging from [src].") - if(do_after(user,(breakout_time), target = src, required_mobility_flags = MOBILITY_RESIST)) + if(do_after(user, breakout_time, src, IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM)) if(!user || user.stat != CONSCIOUS || user.loc != src || opened || (!locked && !welded) ) return //we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting @@ -531,7 +532,7 @@ /obj/structure/closet/get_remote_view_fullscreens(mob/user) if(user.stat == DEAD || !(user.sight & (SEEOBJS|SEEMOBS))) - user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/impaired, 1) + user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/scaled/impaired, 1) /obj/structure/closet/emp_act(severity) . = ..() @@ -540,22 +541,23 @@ if (!(. & EMP_PROTECT_CONTENTS)) for(var/obj/O in src) O.emp_act(severity) - if(secure && !broken && !(. & EMP_PROTECT_SELF)) - if(prob(50 / severity)) - locked = !locked - update_icon() - if(prob(20 / severity) && !opened) - if(!locked) - open() - else - req_access = list() - req_access += pick(get_all_accesses()) - if(!QDELETED(lockerelectronics)) - lockerelectronics.accesses = req_access + if(!secure || broken) + return + if(prob(severity/2)) + locked = !locked + update_icon() + if(prob(severity/5) && !opened) + if(!locked) + open() + else + req_access = list() + req_access += pick(get_all_accesses()) + if(!QDELETED(lockerelectronics)) + lockerelectronics.accesses = req_access -/obj/structure/closet/contents_explosion(severity, target) +/obj/structure/closet/contents_explosion(severity, target, origin) for(var/atom/A in contents) - A.ex_act(severity, target) + A.ex_act(severity, target, origin) CHECK_TICK /obj/structure/closet/singularity_act() @@ -671,3 +673,15 @@ if(allowed(user)) return TRUE to_chat(user, "Access denied.") + +/obj/structure/closet/on_object_saved(depth) + if(depth >= 10) + return "" + var/dat = "" + for(var/obj/item in contents) + var/metadata = generate_tgm_metadata(item) + dat += "[dat ? ",\n" : ""][item.type][metadata]" + //Save the contents of things inside the things inside us, EG saving the contents of bags inside lockers + var/custom_data = item.on_object_saved(depth++) + dat += "[custom_data ? ",\n[custom_data]" : ""]" + return dat diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index 4b405ae64a..289599efb9 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -32,6 +32,8 @@ new /obj/item/clothing/head/beret/ce/white(src) new /obj/item/storage/bag/construction(src) new /obj/item/storage/bag/material(src) + new /obj/item/mod/construction/armor/advanced(src) + new /obj/item/mod/module/rad_protection(src) /obj/structure/closet/secure_closet/engineering_electrical name = "electrical supplies locker" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm index ff3f4d8793..e5a7793ab7 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm @@ -6,7 +6,7 @@ recursive_organ_check(src) return ..() -/obj/structure/closet/secure_closet/freezer/Initialize() +/obj/structure/closet/secure_closet/freezer/Initialize(mapload) . = ..() recursive_organ_check(src) @@ -21,7 +21,7 @@ if(.) //if we actually closed the locker recursive_organ_check(src) -/obj/structure/closet/secure_closet/freezer/ex_act() +/obj/structure/closet/secure_closet/freezer/ex_act(severity, target, origin) if(!jones) jones = TRUE else diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index babb047c8d..ce9ae2e280 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -103,6 +103,8 @@ new /obj/item/storage/lockbox/medal/medical(src) new /obj/item/clothing/suit/hooded/wintercoat/cmo(src) new /obj/item/clothing/head/beret/cmo/blue(src) + new /obj/item/mod/construction/armor/rescue(src) + new /obj/item/mod/module/health_analyzer(src) /obj/structure/closet/secure_closet/animal name = "animal control" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm index 135e0685c1..a7b0153ef0 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm @@ -31,4 +31,4 @@ new /obj/item/circuitboard/machine/techfab/department/science(src) new /obj/item/storage/photo_album/RD(src) new /obj/item/clothing/suit/hooded/wintercoat/rd(src) - + new /obj/item/mod/construction/armor/research(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm index 4266f006ec..22996339ef 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm @@ -4,12 +4,12 @@ locked = TRUE icon_state = "secure" max_integrity = 250 - armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) + armor = list(MELEE = 30, BULLET = 50, LASER = 50, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 80) secure = TRUE var/melee_min_damage = 20 /obj/structure/closet/secure_closet/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < melee_min_damage) + if(damage_flag == MELEE && damage_amount < melee_min_damage) return 0 . = ..() diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 1d23903d03..a2239caa92 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -7,7 +7,7 @@ new /obj/item/clothing/neck/petcollar(src) //I considered removing the pet stuff too but eh, who knows. We might get Renault back. Plus I guess you could use that collar for... other means. Aren't you supposed to be guarding the disk? new /obj/item/pet_carrier(src) new /obj/item/clothing/suit/armor/vest/capcarapace(src) - new /obj/item/clothing/suit/armor/vest/capcarapace/alt(src) + new /obj/item/clothing/suit/toggle/captains_parade(src) new /obj/item/clothing/head/crown/fancy(src) new /obj/item/cartridge/captain(src) new /obj/item/storage/box/silver_ids(src) @@ -17,6 +17,8 @@ new /obj/item/gun/energy/e_gun(src) new /obj/item/door_remote/captain(src) new /obj/item/storage/photo_album/Captain(src) + new /obj/item/mod/construction/armor/magnate(src) + new /obj/item/mod/module/holster(src) /obj/structure/closet/secure_closet/hop name = "\proper head of personnel's locker" @@ -56,6 +58,7 @@ /obj/structure/closet/secure_closet/hos/PopulateContents() ..() new /obj/item/clothing/neck/cloak/hos(src) + new /obj/item/clothing/suit/toggle/armor/hos/hos_formal(src) new /obj/item/cartridge/hos(src) new /obj/item/radio/headset/heads/hos(src) new /obj/item/clothing/under/rank/security/head_of_security/parade/female(src) @@ -63,6 +66,7 @@ new /obj/item/clothing/under/rank/security/officer/blueshirt/seccorp/hoscorp(src) new /obj/item/clothing/suit/armor/vest/leather(src) new /obj/item/clothing/suit/armor/hos(src) + new /obj/item/clothing/suit/armor/hos/platecarrier(src) new /obj/item/clothing/under/rank/security/head_of_security/skirt(src) new /obj/item/clothing/under/rank/security/head_of_security/alt(src) new /obj/item/clothing/under/rank/security/head_of_security/alt/skirt(src) @@ -84,6 +88,9 @@ new /obj/item/circuitboard/machine/techfab/department/security(src) new /obj/item/storage/photo_album/HoS(src) new /obj/item/clothing/suit/hooded/wintercoat/hos(src) + new /obj/item/mod/construction/armor/safeguard(src) + new /obj/item/mod/module/jetpack(src) + new /obj/item/mod/module/holster(src) /obj/structure/closet/secure_closet/warden name = "\proper warden's locker" @@ -191,6 +198,7 @@ new /obj/item/clothing/under/rank/prisoner( src ) new /obj/item/clothing/under/rank/prisoner/skirt( src ) new /obj/item/clothing/shoes/sneakers/orange( src ) + new /obj/item/radio/headset/headset_prisoner( src ) /obj/structure/closet/secure_closet/courtroom name = "courtroom locker" diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 030f7f4edf..650fdf040b 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -17,7 +17,7 @@ material_drop_amount = 5 var/obj/item/paper/fluff/jobs/cargo/manifest/manifest -/obj/structure/closet/crate/Initialize() +/obj/structure/closet/crate/Initialize(mapload) . = ..() if(icon_state == "[initial(icon_state)]open") opened = TRUE @@ -26,15 +26,15 @@ // AddElement(/datum/element/climbable, climb_time = crate_climb_time, climb_stun = 0) update_icon() -/obj/structure/closet/crate/CanPass(atom/movable/mover, turf/target) +/obj/structure/closet/crate/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(!istype(mover, /obj/structure/closet)) var/obj/structure/closet/crate/locatedcrate = locate(/obj/structure/closet/crate) in get_turf(mover) if(locatedcrate) //you can walk on it like tables, if you're not in an open crate trying to move to a closed crate if(opened) //if we're open, allow entering regardless of located crate openness - return 1 + return TRUE if(!locatedcrate.opened) //otherwise, if the located crate is closed, allow entering - return 1 - return !density + return TRUE /obj/structure/closet/crate/update_icon_state() icon_state = "[initial(icon_state)][opened ? "open" : ""]" @@ -106,6 +106,16 @@ name = "trash cart" icon_state = "trashcart" +/obj/structure/closet/crate/trashcart/Moved() + . = ..() + if(has_gravity()) + playsound(src, 'sound/effects/roll.ogg', 100, TRUE) + +/obj/structure/closet/crate/trashcart/laundry + name = "laundry cart" + desc = "A large cart for hauling around large amounts of laundry." + icon_state = "laundry" + /obj/structure/closet/crate/medical desc = "A medical crate." name = "medical crate" @@ -129,9 +139,9 @@ /obj/structure/closet/crate/freezer/Destroy() recursive_organ_check(src) - ..() + return ..() -/obj/structure/closet/crate/freezer/Initialize() +/obj/structure/closet/crate/freezer/Initialize(mapload) . = ..() recursive_organ_check(src) diff --git a/code/game/objects/structures/crates_lockers/crates/secure.dm b/code/game/objects/structures/crates_lockers/crates/secure.dm index f63f3afbd9..e60454a7ce 100644 --- a/code/game/objects/structures/crates_lockers/crates/secure.dm +++ b/code/game/objects/structures/crates_lockers/crates/secure.dm @@ -5,11 +5,11 @@ secure = TRUE locked = TRUE max_integrity = 500 - armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) + armor = list(MELEE = 30, BULLET = 50, LASER = 50, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 80) var/tamperproof = 0 /obj/structure/closet/crate/secure/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < 25) + if(damage_flag == MELEE && damage_amount < 25) return 0 . = ..() diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index c32bf81ecf..4df8d70939 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -6,7 +6,7 @@ density = TRUE anchored = TRUE resistance_flags = ACID_PROOF - armor = list("melee" = 30, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100) + armor = list(MELEE = 30, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 70, ACID = 100) max_integrity = 200 integrity_failure = 0.25 attack_hand_speed = CLICK_CD_MELEE @@ -20,7 +20,7 @@ var/list/start_showpieces = list() //Takes sublists in the form of list("type" = /obj/item/bikehorn, "trophy_message" = "henk") var/trophy_message = "" -/obj/structure/displaycase/Initialize() +/obj/structure/displaycase/Initialize(mapload) . = ..() if(start_showpieces.len && !start_showpiece_type) var/list/showpiece_entry = pick(start_showpieces) @@ -252,7 +252,7 @@ integrity_failure = 0 openable = FALSE -/obj/structure/displaycase/trophy/Initialize() +/obj/structure/displaycase/trophy/Initialize(mapload) . = ..() GLOB.trophy_cases += src @@ -397,7 +397,7 @@ data["owner_name"] = payments_acc.account_holder if(showpiece) data["product_name"] = capitalize(showpiece.name) - var/base64 = icon2base64(icon(showpiece.icon, showpiece.icon_state)) + var/base64 = icon2base64(icon(showpiece.icon, showpiece.icon_state, SOUTH, 1)) data["product_icon"] = base64 data["registered"] = register data["product_cost"] = sale_price diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index 467dd47c50..7542ec6768 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -32,9 +32,9 @@ stored_extinguisher = null return ..() -/obj/structure/extinguisher_cabinet/contents_explosion(severity, target) +/obj/structure/extinguisher_cabinet/contents_explosion(severity, target, origin) if(stored_extinguisher) - stored_extinguisher.ex_act(severity, target) + stored_extinguisher.ex_act(severity, target, origin) /obj/structure/extinguisher_cabinet/handle_atom_del(atom/A) if(A == stored_extinguisher) diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index 5b3cd3139c..bf06f06e6f 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -33,7 +33,7 @@ var/girder_type = /obj/structure/girder/displaced var/opening = FALSE -/obj/structure/falsewall/Initialize() +/obj/structure/falsewall/Initialize(mapload) . = ..() air_update_turf(TRUE) diff --git a/code/game/objects/structures/fence.dm b/code/game/objects/structures/fence.dm index eaf5398605..1a23981af2 100644 --- a/code/game/objects/structures/fence.dm +++ b/code/game/objects/structures/fence.dm @@ -23,7 +23,7 @@ var/hole_size= NO_HOLE var/invulnerable = FALSE -/obj/structure/fence/Initialize() +/obj/structure/fence/Initialize(mapload) . = ..() update_cut_status() @@ -57,6 +57,7 @@ hole_size = LARGE_HOLE /obj/structure/fence/attackby(obj/item/W, mob/user) + var/current_stage = hole_size if(W.tool_behaviour == TOOL_WIRECUTTER) if(!cuttable) to_chat(user, "This section of the fence can't be cut.") @@ -64,7 +65,6 @@ if(invulnerable) to_chat(user, "This fence is too strong to cut through.") return - var/current_stage = hole_size if(current_stage >= MAX_HOLE_SIZE) to_chat(user, "This fence has too much cut out of it already.") return @@ -86,6 +86,25 @@ update_cut_status() + else if(istype(W, /obj/item/stack/rods) && broken) + if(!hole_size) + to_chat(user, "The [src] has no cuts in it!") + return + var/obj/item/stack/rods/R = W + if(do_after(user, CUT_TIME, target = src)) + if(current_stage == hole_size) + switch(--hole_size) + if(NO_HOLE) + visible_message("\The [user] repairs \the [src] fully.") + to_chat(user, "You repaire the [src] back to it's former glory.") + climbable = TRUE + if(MEDIUM_HOLE) + visible_message("\The [user] patches up \the [src].") + to_chat(user, "The hole in \the [src] is reduced slightly, though someone could probably sill squeeze though if you don't patch it up more.") + climbable = FALSE + R.use(1) + update_cut_status() + return TRUE /obj/structure/fence/proc/update_cut_status() @@ -110,7 +129,7 @@ cuttable = FALSE var/open = FALSE -/obj/structure/fence/door/Initialize() +/obj/structure/fence/door/Initialize(mapload) . = ..() update_door_status() diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm index a247908b3b..5bf1cd4809 100644 --- a/code/game/objects/structures/fireaxe.dm +++ b/code/game/objects/structures/fireaxe.dm @@ -6,14 +6,14 @@ plane = ABOVE_WALL_PLANE anchored = TRUE density = FALSE - armor = list("melee" = 50, "bullet" = 20, "laser" = 0, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 50) + armor = list(MELEE = 50, BULLET = 20, LASER = 0, ENERGY = 100, BOMB = 10, BIO = 100, RAD = 100, FIRE = 90, ACID = 50) max_integrity = 150 integrity_failure = 0.33 var/locked = TRUE var/open = FALSE var/obj/item/fireaxe/fireaxe -/obj/structure/fireaxecabinet/Initialize() +/obj/structure/fireaxecabinet/Initialize(mapload) . = ..() fireaxe = new update_icon() diff --git a/code/game/objects/structures/fireplace.dm b/code/game/objects/structures/fireplace.dm index ca66dbd8de..ec7db22cf0 100644 --- a/code/game/objects/structures/fireplace.dm +++ b/code/game/objects/structures/fireplace.dm @@ -1,4 +1,4 @@ -#define LOG_BURN_TIMER 150 +#define LOG_BURN_TIMER 400 #define PAPER_BURN_TIMER 5 #define MAXIMUM_BURN_TIMER 3000 @@ -12,6 +12,7 @@ pixel_x = -16 resistance_flags = FIRE_PROOF var/lit = FALSE + light_color = "#E38C2D" var/fuel_added = 0 var/flame_expiry_timer @@ -64,6 +65,12 @@ ") adjust_fuel_timer(PAPER_BURN_TIMER) qdel(T) + else if(istype(T,/obj/item/grown/log)) + user.visible_message("[user] tosses some \ + wood into [src].", "You add \ + some fuel to [src].") + adjust_fuel_timer(LOG_BURN_TIMER) + qdel(T) else if(try_light(T,user)) return else diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index b587e57c3a..e92cf641c8 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -40,6 +40,16 @@ density = FALSE pixel_x = -16 +/obj/structure/flora/stump/attackby(obj/item/W, mob/user, params) + if((W.tool_behaviour == TOOL_SHOVEL) && params) + playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) + if(do_after(user, 20)) + new /obj/item/grown/log/tree(get_turf(src)) + user.visible_message("[user] digs up [src].", "You dig up [src].") + qdel(src) + else + return ..() + /obj/structure/flora/tree/pine name = "pine tree" desc = "A coniferous pine tree." @@ -47,7 +57,7 @@ icon_state = "pine_1" var/list/icon_states = list("pine_1", "pine_2", "pine_3") -/obj/structure/flora/tree/pine/Initialize() +/obj/structure/flora/tree/pine/Initialize(mapload) . = ..() if(islist(icon_states && icon_states.len)) @@ -58,6 +68,7 @@ desc = "A wondrous decorated Christmas tree." icon_state = "pine_c" icon_states = null + resistance_flags = INDESTRUCTIBLE //Sorry grinch, not this time /obj/structure/flora/tree/pine/xmas/presents icon_state = "pinepresents" @@ -90,7 +101,7 @@ desc = "A tree straight from the tropics." icon_state = "palm1" -/obj/structure/flora/tree/palm/Initialize() +/obj/structure/flora/tree/palm/Initialize(mapload) . = ..() icon_state = pick("palm1","palm2") pixel_x = 0 @@ -107,7 +118,7 @@ icon_state = "anchored_rod" anchored = TRUE -/obj/structure/flora/tree/dead/Initialize() +/obj/structure/flora/tree/dead/Initialize(mapload) icon_state = "tree_[rand(1, 6)]" . = ..() @@ -119,7 +130,7 @@ pixel_x = -48 pixel_y = -20 -/obj/structure/flora/tree/jungle/Initialize() +/obj/structure/flora/tree/jungle/Initialize(mapload) icon_state = "[icon_state][rand(1, 6)]" . = ..() @@ -138,7 +149,7 @@ /obj/structure/flora/grass/brown icon_state = "snowgrass1bb" -/obj/structure/flora/grass/brown/Initialize() +/obj/structure/flora/grass/brown/Initialize(mapload) icon_state = "snowgrass[rand(1, 3)]bb" . = ..() @@ -146,14 +157,14 @@ /obj/structure/flora/grass/green icon_state = "snowgrass1gb" -/obj/structure/flora/grass/green/Initialize() +/obj/structure/flora/grass/green/Initialize(mapload) icon_state = "snowgrass[rand(1, 3)]gb" . = ..() /obj/structure/flora/grass/both icon_state = "snowgrassall1" -/obj/structure/flora/grass/both/Initialize() +/obj/structure/flora/grass/both/Initialize(mapload) icon_state = "snowgrassall[rand(1, 3)]" . = ..() @@ -166,7 +177,7 @@ icon_state = "snowbush1" anchored = TRUE -/obj/structure/flora/bush/Initialize() +/obj/structure/flora/bush/Initialize(mapload) icon_state = "snowbush[rand(1, 6)]" . = ..() @@ -178,7 +189,7 @@ icon = 'icons/obj/flora/ausflora.dmi' icon_state = "firstbush_1" -/obj/structure/flora/ausbushes/Initialize() +/obj/structure/flora/ausbushes/Initialize(mapload) if(icon_state == "firstbush_1") icon_state = "firstbush_[rand(1, 4)]" . = ..() @@ -186,105 +197,105 @@ /obj/structure/flora/ausbushes/reedbush icon_state = "reedbush_1" -/obj/structure/flora/ausbushes/reedbush/Initialize() +/obj/structure/flora/ausbushes/reedbush/Initialize(mapload) icon_state = "reedbush_[rand(1, 4)]" . = ..() /obj/structure/flora/ausbushes/leafybush icon_state = "leafybush_1" -/obj/structure/flora/ausbushes/leafybush/Initialize() +/obj/structure/flora/ausbushes/leafybush/Initialize(mapload) icon_state = "leafybush_[rand(1, 3)]" . = ..() /obj/structure/flora/ausbushes/palebush icon_state = "palebush_1" -/obj/structure/flora/ausbushes/palebush/Initialize() +/obj/structure/flora/ausbushes/palebush/Initialize(mapload) icon_state = "palebush_[rand(1, 4)]" . = ..() /obj/structure/flora/ausbushes/stalkybush icon_state = "stalkybush_1" -/obj/structure/flora/ausbushes/stalkybush/Initialize() +/obj/structure/flora/ausbushes/stalkybush/Initialize(mapload) icon_state = "stalkybush_[rand(1, 3)]" . = ..() /obj/structure/flora/ausbushes/grassybush icon_state = "grassybush_1" -/obj/structure/flora/ausbushes/grassybush/Initialize() +/obj/structure/flora/ausbushes/grassybush/Initialize(mapload) icon_state = "grassybush_[rand(1, 4)]" . = ..() /obj/structure/flora/ausbushes/fernybush icon_state = "fernybush_1" -/obj/structure/flora/ausbushes/fernybush/Initialize() +/obj/structure/flora/ausbushes/fernybush/Initialize(mapload) icon_state = "fernybush_[rand(1, 3)]" . = ..() /obj/structure/flora/ausbushes/sunnybush icon_state = "sunnybush_1" -/obj/structure/flora/ausbushes/sunnybush/Initialize() +/obj/structure/flora/ausbushes/sunnybush/Initialize(mapload) icon_state = "sunnybush_[rand(1, 3)]" . = ..() /obj/structure/flora/ausbushes/genericbush icon_state = "genericbush_1" -/obj/structure/flora/ausbushes/genericbush/Initialize() +/obj/structure/flora/ausbushes/genericbush/Initialize(mapload) icon_state = "genericbush_[rand(1, 4)]" . = ..() /obj/structure/flora/ausbushes/pointybush icon_state = "pointybush_1" -/obj/structure/flora/ausbushes/pointybush/Initialize() +/obj/structure/flora/ausbushes/pointybush/Initialize(mapload) icon_state = "pointybush_[rand(1, 4)]" . = ..() /obj/structure/flora/ausbushes/lavendergrass icon_state = "lavendergrass_1" -/obj/structure/flora/ausbushes/lavendergrass/Initialize() +/obj/structure/flora/ausbushes/lavendergrass/Initialize(mapload) icon_state = "lavendergrass_[rand(1, 4)]" . = ..() /obj/structure/flora/ausbushes/ywflowers icon_state = "ywflowers_1" -/obj/structure/flora/ausbushes/ywflowers/Initialize() +/obj/structure/flora/ausbushes/ywflowers/Initialize(mapload) icon_state = "ywflowers_[rand(1, 3)]" . = ..() /obj/structure/flora/ausbushes/brflowers icon_state = "brflowers_1" -/obj/structure/flora/ausbushes/brflowers/Initialize() +/obj/structure/flora/ausbushes/brflowers/Initialize(mapload) icon_state = "brflowers_[rand(1, 3)]" . = ..() /obj/structure/flora/ausbushes/ppflowers icon_state = "ppflowers_1" -/obj/structure/flora/ausbushes/ppflowers/Initialize() +/obj/structure/flora/ausbushes/ppflowers/Initialize(mapload) icon_state = "ppflowers_[rand(1, 3)]" . = ..() /obj/structure/flora/ausbushes/sparsegrass icon_state = "sparsegrass_1" -/obj/structure/flora/ausbushes/sparsegrass/Initialize() +/obj/structure/flora/ausbushes/sparsegrass/Initialize(mapload) icon_state = "sparsegrass_[rand(1, 3)]" . = ..() /obj/structure/flora/ausbushes/fullgrass icon_state = "fullgrass_1" -/obj/structure/flora/ausbushes/fullgrass/Initialize() +/obj/structure/flora/ausbushes/fullgrass/Initialize(mapload) icon_state = "fullgrass_[rand(1, 3)]" . = ..() @@ -311,7 +322,7 @@ icon_state = "random_plant" var/list/static/states -/obj/item/kirbyplants/random/Initialize() +/obj/item/kirbyplants/random/Initialize(mapload) . = ..() icon = 'icons/obj/flora/plants.dmi' if(!states) @@ -357,7 +368,7 @@ /// Amount of the itemstack to drop var/mineAmount = 20 -/obj/structure/flora/rock/Initialize() +/obj/structure/flora/rock/Initialize(mapload) . = ..() icon_state = "[icon_state][rand(1,3)]" @@ -387,7 +398,7 @@ icon_state = "grassa" -/obj/structure/flora/grass/jungle/Initialize() +/obj/structure/flora/grass/jungle/Initialize(mapload) icon_state = "[icon_state][rand(1, 5)]" . = ..() @@ -403,7 +414,7 @@ icon = 'icons/obj/flora/jungleflora.dmi' density = FALSE -/obj/structure/flora/rock/jungle/Initialize() +/obj/structure/flora/rock/jungle/Initialize(mapload) . = ..() icon_state = "[initial(icon_state)][rand(1,5)]" @@ -416,7 +427,7 @@ icon = 'icons/obj/flora/jungleflora.dmi' icon_state = "busha" -/obj/structure/flora/junglebush/Initialize() +/obj/structure/flora/junglebush/Initialize(mapload) icon_state = "[icon_state][rand(1, 3)]" . = ..() @@ -441,6 +452,6 @@ pixel_x = -16 pixel_y = -16 -/obj/structure/flora/rock/pile/largejungle/Initialize() +/obj/structure/flora/rock/pile/largejungle/Initialize(mapload) . = ..() icon_state = "[initial(icon_state)][rand(1,3)]" diff --git a/code/game/objects/structures/fluff.dm b/code/game/objects/structures/fluff.dm index 477bc19a22..2700109c77 100644 --- a/code/game/objects/structures/fluff.dm +++ b/code/game/objects/structures/fluff.dm @@ -62,6 +62,8 @@ icon = 'icons/effects/64x64.dmi' icon_state = "drake_statue" pixel_x = -16 + maptext_height = 64 + maptext_width = 64 density = TRUE deconstructible = FALSE layer = EDGED_TURF_LAYER @@ -78,6 +80,12 @@ deconstructible = FALSE layer = EDGED_TURF_LAYER +/obj/structure/fluff/lightpost/light + desc = "That which most enchants the Edinians is the lighting by gas of the boulevards... These humble rows of lamps, shining with a clarity white and pure, have a marvelous effect upon the streets on Nova Edina. Adorned with a cheery garb, in tune with the festive spirits of the city." + light_power = 0.8 + light_range = 10 + light_color = "#ffeeab" + /obj/structure/fluff/bus name = "bus" desc = "GO TO SCHOOL. READ A BOOK." diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index f5746d6ae7..90224af8cc 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -1,5 +1,5 @@ //Objects that spawn ghosts in as a certain role when they click on it, i.e. away mission bartenders. - +#define spawnOverride TRUE //Preserved terrarium/seed vault: Spawns in seed vault structures in lavaland. Ghosts become plantpeople and are advised to begin growing plants in the room near them. /obj/effect/mob_spawn/human/seed_vault name = "preserved terrarium" @@ -36,6 +36,44 @@ //Ash walker eggs: Spawns in ash walker dens in lavaland. Ghosts become unbreathing lizards that worship the Necropolis and are advised to retrieve corpses to create more ash walkers. +/obj/structure/ash_walker_eggshell + name = "ash walker egg" + desc = "A man-sized yellow egg, spawned from some unfathomable creature. A humanoid silhouette lurks within. The egg shell looks resistant to temperature but otherwise rather brittle." + icon = 'icons/mob/lavaland/lavaland_monsters.dmi' + icon_state = "large_egg" + resistance_flags = LAVA_PROOF | FIRE_PROOF | FREEZE_PROOF + max_integrity = 80 + var/obj/effect/mob_spawn/human/ash_walker/egg + +/obj/structure/ash_walker_eggshell/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) //lifted from xeno eggs + switch(damage_type) + if(BRUTE) + if(damage_amount) + playsound(loc, 'sound/effects/attackblob.ogg', 100, TRUE) + else + playsound(src, 'sound/weapons/tap.ogg', 50, TRUE) + if(BURN) + if(damage_amount) + playsound(loc, 'sound/items/welder.ogg', 100, TRUE) + +/obj/structure/ash_walker_eggshell/attack_ghost(mob/user) //Pass on ghost clicks to the mob spawner + if(egg) + egg.attack_ghost(user) + . = ..() + +/obj/structure/ash_walker_eggshell/Destroy() + if(!egg) + return ..() + var/mob/living/carbon/human/yolk = new /mob/living/carbon/human/(get_turf(src)) + yolk.fully_replace_character_name(null,random_unique_lizard_name(gender)) + yolk.set_species(/datum/species/lizard/ashwalker) + yolk.underwear = "Nude" + yolk.equipOutfit(/datum/outfit/ashwalker)//this is an authentic mess we're making + yolk.update_body() + yolk.gib() + QDEL_NULL(egg) + return ..() + /obj/effect/mob_spawn/human/ash_walker name = "ash walker egg" desc = "A man-sized yellow egg, spawned from some unfathomable creature. A humanoid silhouette lurks within." @@ -55,33 +93,48 @@ You have seen lights in the distance... they foreshadow the arrival of outsiders to your domain. \ Ensure your nest remains protected at all costs." assignedrole = "Ash Walker" + var/datum/team/ashwalkers/team + var/obj/structure/ash_walker_eggshell/eggshell + +/obj/effect/mob_spawn/human/ash_walker/Destroy() + eggshell = null + return ..() + +/obj/effect/mob_spawn/human/ash_walker/allow_spawn(mob/user, silent = FALSE) + if(!(user.key in team.players_spawned) || spawnOverride)//one per person unless you get a bonus spawn + return TRUE + to_chat(user, span_warning("You have exhausted your usefulness to the Necropolis.")) + return FALSE /obj/effect/mob_spawn/human/ash_walker/special(mob/living/new_spawn) new_spawn.real_name = random_unique_lizard_name(gender) if(is_mining_level(z)) to_chat(new_spawn, "Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Glory to the Necropolis!") to_chat(new_spawn, "You can expand the weather proof area provided by your shelters by using the 'New Area' key near the bottom right of your HUD.") + to_chat(new_spawn, "Dragging injured ashwalkers to the tentacle or using the sleep verb next to it youself causes the body to remade whole after a short delay!") else to_chat(new_spawn, "You have been born outside of your natural home! Whether you decide to return home, or make due with your new home is your own decision.") //Ash walkers on birth understand how to make bone bows, bone arrows and ashen arrows - new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/bone_arrow) - new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/bone_bow) - new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/ashen_arrow) - new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/quiver) - new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/bow_tablet) - if(ishuman(new_spawn)) var/mob/living/carbon/human/H = new_spawn H.underwear = "Nude" H.undershirt = "Nude" H.socks = "Nude" H.update_body() + new_spawn.mind.add_antag_datum(/datum/antagonist/ashwalker, team) + team.players_spawned += (new_spawn.key) + eggshell.egg = null + QDEL_NULL(eggshell) -/obj/effect/mob_spawn/human/ash_walker/Initialize(mapload) +/obj/effect/mob_spawn/human/ash_walker/Initialize(mapload, datum/team/ashwalkers/ashteam) . = ..() var/area/A = get_area(src) + team = ashteam + eggshell = new /obj/structure/ash_walker_eggshell(get_turf(loc)) + eggshell.egg = src + src.forceMove(eggshell) if(A) notify_ghosts("An ash walker egg is ready to hatch in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_ASHWALKER, ignore_dnr_observers = TRUE) @@ -634,9 +687,9 @@ log_game("[key_name(user)] has successfully pried open [src] and disabled a space pirate spawner.") W.play_tool_sound(src) playsound(src.loc, 'modular_citadel/sound/voice/scream_skeleton.ogg', 50, 1, 4, 1.2) - if(rank == "Captain") + if(rank == "Captain") new /obj/effect/mob_spawn/human/pirate/corpse/captain(get_turf(src)) - else + else new /obj/effect/mob_spawn/human/pirate/corpse(get_turf(src)) qdel(src) else @@ -782,7 +835,8 @@ var/area/A = get_area(src) var/datum/outfit/O = new /datum/outfit/ghostcafe() O.equip(new_spawn, FALSE, new_spawn.client) - SSjob.equip_loadout(null, new_spawn, FALSE) + SSjob.equip_loadout(null, new_spawn) + SSjob.post_equip_loadout(null, new_spawn) SSquirks.AssignQuirks(new_spawn, new_spawn.client, TRUE, TRUE, null, FALSE, new_spawn) new_spawn.AddElement(/datum/element/ghost_role_eligibility, free_ghosting = TRUE) new_spawn.AddElement(/datum/element/dusts_on_catatonia) @@ -806,6 +860,13 @@ /datum/outfit/ghostcafe/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) ..() + if (isplasmaman(H)) + head = /obj/item/clothing/head/helmet/space/plasmaman + uniform = /obj/item/clothing/under/plasmaman + l_hand= /obj/item/tank/internals/plasmaman/belt/full + mask = /obj/item/clothing/mask/breath + return + var/suited = !preference_source || preference_source.prefs.jumpsuit_style == PREF_SUIT if (CONFIG_GET(flag/grey_assistants)) uniform = suited ? /obj/item/clothing/under/color/grey : /obj/item/clothing/under/color/jumpskirt/grey @@ -815,6 +876,10 @@ else uniform = suited ? /obj/item/clothing/under/color/random : /obj/item/clothing/under/color/jumpskirt/random +/datum/outfit/ghostcafe/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) + H.internal = H.get_item_for_held_index(1) + H.update_internals_hud_icon(1) + /obj/item/storage/box/syndie_kit/chameleon/ghostcafe name = "ghost cafe costuming kit" desc = "Look just the way you did in life - or better!" diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 50240aabb3..5b4b3a229f 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -296,20 +296,15 @@ qdel(src) return TRUE -/obj/structure/girder/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGRILLE)) +/obj/structure/girder/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() + if((mover.pass_flags & PASSGRILLE) || istype(mover, /obj/item/projectile)) return prob(girderpasschance) - else - if(istype(mover, /obj/item/projectile)) - return prob(girderpasschance) - else - return 0 -/obj/structure/girder/CanAStarPass(ID, dir, caller) +/obj/structure/girder/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller) . = !density - if(ismovable(caller)) - var/atom/movable/mover = caller - . = . || (mover.pass_flags & PASSGRILLE) + if(istype(caller)) + . = . || (caller.pass_flags & PASSGRILLE) /obj/structure/girder/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 2ac85f79dc..998285dd58 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -5,10 +5,11 @@ icon_state = "grille" density = TRUE anchored = TRUE + pass_flags_self = PASSGRILLE flags_1 = CONDUCT_1 pressure_resistance = 5*ONE_ATMOSPHERE layer = BELOW_OBJ_LAYER - armor = list("melee" = 50, "bullet" = 70, "laser" = 70, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) + armor = list(MELEE = 50, BULLET = 70, LASER = 70, ENERGY = 100, BOMB = 10, BIO = 100, RAD = 100, FIRE = 0, ACID = 0) max_integrity = 50 attack_hand_is_action = TRUE attack_hand_speed = 8 @@ -91,7 +92,7 @@ user.DelayNextAction(flush = TRUE) user.do_attack_animation(src) if(!shock(user, 70) && !QDELETED(src)) //Last hit still shocks but shouldn't deal damage to the grille) - take_damage(rand(5,10), BRUTE, "melee", 1) + take_damage(rand(5,10), BRUTE, MELEE, 1) /obj/structure/grille/attack_paw(mob/user) return attack_hand(user) @@ -113,7 +114,7 @@ user.visible_message("[user] hits [src].", null, null, COMBAT_MESSAGE_RANGE) log_combat(user, src, "hit") if(!shock(user, 70)) - take_damage(rand(5,10), BRUTE, "melee", 1) + take_damage(rand(5,10), BRUTE, MELEE, 1) /obj/structure/grille/attack_alien(mob/living/user) if(!user.CheckActionCooldown(CLICK_CD_MELEE)) @@ -122,22 +123,17 @@ user.do_attack_animation(src) user.visible_message("[user] mangles [src].", null, null, COMBAT_MESSAGE_RANGE) if(!shock(user, 70)) - take_damage(20, BRUTE, "melee", 1) + take_damage(20, BRUTE, MELEE, 1) -/obj/structure/grille/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGRILLE)) - return TRUE - else - if(istype(mover, /obj/item/projectile) && density) - return prob(30) - else - return !density +/obj/structure/grille/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() + if(!. && istype(mover, /obj/item/projectile)) + return prob(30) -/obj/structure/grille/CanAStarPass(ID, dir, caller) +/obj/structure/grille/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller) . = !density - if(ismovable(caller)) - var/atom/movable/mover = caller - . = . || (mover.pass_flags & PASSGRILLE) + if(istype(caller)) + . = . || (caller.pass_flags & PASSGRILLE) /obj/structure/grille/attackby(obj/item/W, mob/user, params) user.DelayNextAction(CLICK_CD_MELEE) diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm index 4773c07657..604961abf4 100644 --- a/code/game/objects/structures/guillotine.dm +++ b/code/game/objects/structures/guillotine.dm @@ -29,7 +29,7 @@ var/kill_count = 0 var/current_action = 0 // What's currently happening to the guillotine -/obj/structure/guillotine/Initialize() +/obj/structure/guillotine/Initialize(mapload) LAZYINITLIST(buckled_mobs) . = ..() diff --git a/code/game/objects/structures/guncase.dm b/code/game/objects/structures/guncase.dm index e7ff9d4abf..78f0da2db2 100644 --- a/code/game/objects/structures/guncase.dm +++ b/code/game/objects/structures/guncase.dm @@ -91,9 +91,9 @@ /obj/structure/guncase/handle_atom_del(atom/A) update_icon() -/obj/structure/guncase/contents_explosion(severity, target) +/obj/structure/guncase/contents_explosion(severity, target, origin) for(var/atom/A in contents) - A.ex_act(severity++, target) + A.ex_act(severity++, target, origin) CHECK_TICK /obj/structure/guncase/shotgun diff --git a/code/game/objects/structures/headpike.dm b/code/game/objects/structures/headpike.dm index 6aed11701d..16c8bf41c1 100644 --- a/code/game/objects/structures/headpike.dm +++ b/code/game/objects/structures/headpike.dm @@ -24,7 +24,7 @@ else spear = locate(/obj/item/spear) in parts_list -/obj/structure/headpike/Initialize() +/obj/structure/headpike/Initialize(mapload) . = ..() pixel_x = rand(-8, 8) diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm index cb9309c4c4..0ebccf819e 100644 --- a/code/game/objects/structures/holosign.dm +++ b/code/game/objects/structures/holosign.dm @@ -6,7 +6,7 @@ icon = 'icons/effects/effects.dmi' anchored = TRUE max_integrity = 1 - armor = list("melee" = 0, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 20) + armor = list(MELEE = 0, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 0, BIO = 0, RAD = 0, FIRE = 20, ACID = 20) var/obj/item/holosign_creator/projector var/init_vis_overlay = TRUE rad_flags = RAD_NO_CONTAMINATE @@ -32,7 +32,7 @@ return user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) user.DelayNextAction(CLICK_CD_MELEE) - take_damage(5 , BRUTE, "melee", 1) + take_damage(5 , BRUTE, MELEE, 1) /obj/structure/holosign/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) @@ -51,20 +51,19 @@ name = "holo barrier" desc = "A short holographic barrier which can only be passed by walking." icon_state = "holosign_sec" - pass_flags = LETPASSTHROW + pass_flags_self = PASSTABLE | PASSGRILLE | PASSGLASS | LETPASSTHROW density = TRUE max_integrity = 20 var/allow_walk = 1 //can we pass through it on walk intent -/obj/structure/holosign/barrier/CanPass(atom/movable/mover, turf/target) - if(!density) - return 1 - if(mover.pass_flags & (PASSGLASS|PASSTABLE|PASSGRILLE)) - return 1 +/obj/structure/holosign/barrier/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() + if(.) + return if(iscarbon(mover)) var/mob/living/carbon/C = mover if(allow_walk && C.m_intent == MOVE_INTENT_WALK) - return 1 + return TRUE /obj/structure/holosign/barrier/engineering icon_state = "holosign_engi" @@ -82,7 +81,7 @@ alpha = 150 init_vis_overlay = FALSE -/obj/structure/holosign/barrier/atmos/Initialize() +/obj/structure/holosign/barrier/atmos/Initialize(mapload) . = ..() air_update_turf(TRUE) @@ -98,7 +97,7 @@ /obj/structure/holosign/barrier/firelock/BlockThermalConductivity() return TRUE -/obj/structure/holosign/barrier/firelock/Initialize() +/obj/structure/holosign/barrier/firelock/Initialize(mapload) . = ..() air_update_turf(TRUE) @@ -118,7 +117,7 @@ /obj/structure/holosign/barrier/combifan/BlockThermalConductivity() return TRUE -/obj/structure/holosign/barrier/combifan/Initialize() +/obj/structure/holosign/barrier/combifan/Initialize(mapload) . = ..() air_update_turf(TRUE) @@ -130,11 +129,11 @@ allow_walk = 0 /obj/structure/holosign/barrier/cyborg/bullet_act(obj/item/projectile/P) - take_damage((P.damage / 5) , BRUTE, "melee", 1) //Doesn't really matter what damage flag it is. + take_damage((P.damage / 5) , BRUTE, MELEE, 1) //Doesn't really matter what damage flag it is. if(istype(P, /obj/item/projectile/energy/electrode)) - take_damage(10, BRUTE, "melee", 1) //Tasers aren't harmful. + take_damage(10, BRUTE, MELEE, 1) //Tasers aren't harmful. if(istype(P, /obj/item/projectile/beam/disabler)) - take_damage(5, BRUTE, "melee", 1) //Disablers aren't harmful. + take_damage(5, BRUTE, MELEE, 1) //Disablers aren't harmful. return BULLET_ACT_HIT /obj/structure/holosign/barrier/medical @@ -149,7 +148,7 @@ . = ..() . += "The biometric scanners are [force_allaccess ? "off" : "on"]." -/obj/structure/holosign/barrier/medical/CanPass(atom/movable/mover, turf/target) +/obj/structure/holosign/barrier/medical/CanAllowThrough(atom/movable/mover, turf/target) icon_state = "holo_medical" if(force_allaccess) return TRUE @@ -159,7 +158,7 @@ switch(threat) if(DISEASE_SEVERITY_MINOR, DISEASE_SEVERITY_MEDIUM, DISEASE_SEVERITY_HARMFUL, DISEASE_SEVERITY_DANGEROUS, DISEASE_SEVERITY_BIOHAZARD) if(buzzcd < world.time) - playsound(get_turf(src),'sound/machines/buzz-sigh.ogg',65,1,4) + playsound(get_turf(src),'sound/machines/buzz-sigh.ogg',65,TRUE,4) buzzcd = (world.time + 60) icon_state = "holo_medical-deny" return FALSE @@ -181,7 +180,7 @@ var/shockcd = 0 /obj/structure/holosign/barrier/cyborg/hacked/bullet_act(obj/item/projectile/P) - take_damage(P.damage, BRUTE, "melee", 1) //Yeah no this doesn't get projectile resistance. + take_damage(P.damage, BRUTE, MELEE, 1) //Yeah no this doesn't get projectile resistance. return BULLET_ACT_HIT /obj/structure/holosign/barrier/cyborg/hacked/proc/cooldown() diff --git a/code/game/objects/structures/icemoon/cave_entrance.dm b/code/game/objects/structures/icemoon/cave_entrance.dm index e68918c764..16e0566d68 100644 --- a/code/game/objects/structures/icemoon/cave_entrance.dm +++ b/code/game/objects/structures/icemoon/cave_entrance.dm @@ -19,7 +19,7 @@ GLOBAL_LIST_INIT(ore_probability, list(/obj/item/stack/ore/uranium = 50, move_resist = INFINITY anchored = TRUE -/obj/structure/spawner/ice_moon/Initialize() +/obj/structure/spawner/ice_moon/Initialize(mapload) . = ..() clear_rock() @@ -107,7 +107,7 @@ GLOBAL_LIST_INIT(ore_probability, list(/obj/item/stack/ore/uranium = 50, anchored = TRUE density = TRUE -/obj/effect/collapsing_demonic_portal/Initialize() +/obj/effect/collapsing_demonic_portal/Initialize(mapload) . = ..() playsound(loc,'sound/effects/tendril_destroyed.ogg', 200, FALSE, 50, TRUE, TRUE) visible_message("[src] begins to collapse, cutting it off from this world!") diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index bcb9422708..e49de85cf9 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -15,7 +15,7 @@ var/const/max_signs = 4 -/obj/structure/janitorialcart/Initialize() +/obj/structure/janitorialcart/Initialize(mapload) . = ..() create_reagents(100, OPENCONTAINER) diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index e844461952..ab23ab97e0 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -155,7 +155,7 @@ var/id var/height = 0 // higher numbers are considered physically higher -/obj/structure/ladder/unbreakable/Initialize() +/obj/structure/ladder/unbreakable/Initialize(mapload) GLOB.ladders += src return ..() diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 13f86d13bd..e86123eb25 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -5,7 +5,7 @@ icon_state = "lattice" density = FALSE anchored = TRUE - armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50) + armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 50) max_integrity = 50 layer = LATTICE_LAYER //under pipes plane = FLOOR_PLANE diff --git a/code/game/objects/structures/lavaland/geyser.dm b/code/game/objects/structures/lavaland/geyser.dm index 263b47aab2..38d8a43269 100644 --- a/code/game/objects/structures/lavaland/geyser.dm +++ b/code/game/objects/structures/lavaland/geyser.dm @@ -46,7 +46,7 @@ erupting_state = null var/list/options = list(/datum/reagent/clf3 = 10, /datum/reagent/water/hollowwater = 10, /datum/reagent/medicine/omnizine/protozine = 6, /datum/reagent/wittel = 1) -/obj/structure/geyser/random/Initialize() +/obj/structure/geyser/random/Initialize(mapload) . = ..() reagent_id = pickweight(options) diff --git a/code/game/objects/structures/lavaland/necropolis_tendril.dm b/code/game/objects/structures/lavaland/necropolis_tendril.dm index 67341160de..6a3dcc761f 100644 --- a/code/game/objects/structures/lavaland/necropolis_tendril.dm +++ b/code/game/objects/structures/lavaland/necropolis_tendril.dm @@ -30,7 +30,7 @@ mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/icewing) GLOBAL_LIST_INIT(tendrils, list()) -/obj/structure/spawner/lavaland/Initialize() +/obj/structure/spawner/lavaland/Initialize(mapload) . = ..() emitted_light = new(loc) for(var/F in RANGE_TURFS(1, src)) @@ -78,7 +78,7 @@ GLOBAL_LIST_INIT(tendrils, list()) density = TRUE var/obj/effect/light_emitter/tendril/emitted_light -/obj/effect/collapse/Initialize() +/obj/effect/collapse/Initialize(mapload) . = ..() emitted_light = new(loc) visible_message("The tendril writhes in fury as the earth around it begins to crack and break apart! Get back!") diff --git a/code/game/objects/structures/loot_pile.dm b/code/game/objects/structures/loot_pile.dm index b6249ec1e4..2ea9f0700b 100644 --- a/code/game/objects/structures/loot_pile.dm +++ b/code/game/objects/structures/loot_pile.dm @@ -9,6 +9,7 @@ icon_state = "randompile" density = FALSE anchored = TRUE + max_integrity = 100 var/loot_amount = 5 var/delete_on_depletion = FALSE var/can_use_hands = TRUE @@ -30,7 +31,7 @@ var/loot_restriction = NO_LOOT_RESTRICTION var/maximum_loot_per_player = 1 -/obj/structure/loot_pile/Initialize() +/obj/structure/loot_pile/Initialize(mapload) . = ..() icon_state = pick(icon_states_to_use) diff --git a/code/game/objects/structures/manned_turret.dm b/code/game/objects/structures/manned_turret.dm index 3d0b28d2f3..f70510e173 100644 --- a/code/game/objects/structures/manned_turret.dm +++ b/code/game/objects/structures/manned_turret.dm @@ -25,7 +25,7 @@ /obj/machinery/manned_turret/Destroy() target = null target_turf = null - ..() + return ..() //BUCKLE HOOKS @@ -184,7 +184,7 @@ resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF var/obj/machinery/manned_turret/turret -/obj/item/gun_control/Initialize() +/obj/item/gun_control/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) turret = loc diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index b2f1de8750..61563fc8c5 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -16,7 +16,7 @@ var/isSwitchingStates = 0 var/close_delay = -1 //-1 if does not auto close. max_integrity = 200 - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 10, BIO = 100, RAD = 100, FIRE = 50, ACID = 50) var/sheetType = /obj/item/stack/sheet/metal var/sheetAmount = 7 var/openSound = 'sound/effects/stonedoor_openclose.ogg' @@ -25,7 +25,7 @@ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE rad_insulation = RAD_MEDIUM_INSULATION -/obj/structure/mineral_door/Initialize() +/obj/structure/mineral_door/Initialize(mapload) . = ..() initial_state = icon_state air_update_turf(TRUE) @@ -53,10 +53,10 @@ /obj/structure/mineral_door/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) return TryToSwitchState(user) -/obj/structure/mineral_door/CanPass(atom/movable/mover, turf/target) +/obj/structure/mineral_door/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(istype(mover, /obj/effect/beam)) return !opacity - return !density /obj/structure/mineral_door/proc/TryToSwitchState(atom/user) if(isSwitchingStates) @@ -243,7 +243,7 @@ resistance_flags = FLAMMABLE max_integrity = 20 -/obj/structure/mineral_door/paperframe/Initialize() +/obj/structure/mineral_door/paperframe/Initialize(mapload) . = ..() queue_smooth_neighbors(src) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index a70d9d4678..ffb48ce633 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -41,6 +41,7 @@ if(new_style) H.hair_style = new_style + H.update_mutant_bodyparts() H.update_hair() /obj/structure/mirror/examine_status(mob/user) diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm index 3eb88ad12d..09dfffb552 100644 --- a/code/game/objects/structures/mop_bucket.dm +++ b/code/game/objects/structures/mop_bucket.dm @@ -7,7 +7,7 @@ var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite -/obj/structure/mopbucket/Initialize() +/obj/structure/mopbucket/Initialize(mapload) . = ..() create_reagents(100, OPENCONTAINER) diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 4980981574..69206f0d08 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -29,7 +29,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an var/message_cooldown var/breakout_time = 600 -/obj/structure/bodycontainer/Initialize() +/obj/structure/bodycontainer/Initialize(mapload) . = ..() if(starting_tray) connected = new starting_tray(src) @@ -139,7 +139,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an /obj/structure/bodycontainer/get_remote_view_fullscreens(mob/user) if(user.stat == DEAD || !(user.sight & (SEEOBJS|SEEMOBS))) - user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/impaired, 2) + user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/scaled/impaired, 2) /* * Morgue */ @@ -213,7 +213,7 @@ GLOBAL_LIST_EMPTY(crematoriums) GLOB.crematoriums.Remove(src) return ..() -/obj/structure/bodycontainer/crematorium/Initialize() +/obj/structure/bodycontainer/crematorium/Initialize(mapload) . = ..() GLOB.crematoriums.Add(src) @@ -247,7 +247,13 @@ GLOBAL_LIST_EMPTY(crematoriums) locked = TRUE update_icon() - + for(var/mob/living/simple_animal/jacq/J in conts) + visible_message("[src] cackles, \"You'll nae get rid a me that easily!\"") + playsound(loc, 'sound/spookoween/ahaha.ogg', 100, 0.25) + J.poof() + locked = FALSE + update_icon() + return for(var/mob/living/M in conts) if (M.stat != DEAD) M.emote("scream") @@ -300,7 +306,7 @@ GLOBAL_LIST_EMPTY(crematoriums) layer = TRAY_LAYER var/obj/structure/bodycontainer/connected = null anchored = TRUE - pass_flags = LETPASSTHROW + pass_flags_self = LETPASSTHROW max_integrity = 350 /obj/structure/tray/Destroy() @@ -356,17 +362,18 @@ GLOBAL_LIST_EMPTY(crematoriums) name = "morgue tray" desc = "Apply corpse before closing." icon_state = "morguet" + pass_flags_self = PASSTABLE -/obj/structure/tray/m_tray/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSTABLE)) - return 1 +/obj/structure/tray/m_tray/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() + if(.) + return if(locate(/obj/structure/table) in get_turf(mover)) return 1 else return 0 -/obj/structure/tray/m_tray/CanAStarPass(ID, dir, caller) +/obj/structure/tray/m_tray/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller) . = !density - if(ismovable(caller)) - var/atom/movable/mover = caller - . = . || (mover.pass_flags & PASSTABLE) + if(istype(caller)) + . = . || (caller.pass_flags & PASSTABLE) diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm index 68da53aa6c..34fbdb3029 100644 --- a/code/game/objects/structures/noticeboard.dm +++ b/code/game/objects/structures/noticeboard.dm @@ -1,3 +1,5 @@ +#define MAX_NOTICES 5 + /obj/structure/noticeboard name = "notice board" desc = "A board for pinning important notices upon." @@ -7,8 +9,25 @@ density = FALSE anchored = TRUE max_integrity = 150 + /// Current number of a pinned notices var/notices = 0 +/obj/structure/noticeboard/directional/north + dir = SOUTH + pixel_y = 32 + +/obj/structure/noticeboard/directional/south + dir = NORTH + pixel_y = -32 + +/obj/structure/noticeboard/directional/east + dir = WEST + pixel_x = 32 + +/obj/structure/noticeboard/directional/west + dir = EAST + pixel_x = -32 + /obj/structure/noticeboard/Initialize(mapload) . = ..() @@ -16,7 +35,7 @@ return for(var/obj/item/I in loc) - if(notices > 4) + if(notices >= MAX_NOTICES) break if(istype(I, /obj/item/paper)) I.forceMove(src) @@ -27,67 +46,84 @@ /obj/structure/noticeboard/attackby(obj/item/O, mob/user, params) if(istype(O, /obj/item/paper) || istype(O, /obj/item/photo)) if(!allowed(user)) - to_chat(user, "You are not authorized to add notices") + to_chat(user, span_warning("You are not authorized to add notices!")) return - if(notices < 5) + if(notices < MAX_NOTICES) if(!user.transferItemToLoc(O, src)) return notices++ icon_state = "nboard0[notices]" - to_chat(user, "You pin the [O] to the noticeboard.") + to_chat(user, span_notice("You pin the [O] to the noticeboard.")) else - to_chat(user, "The notice board is full") + to_chat(user, span_warning("The notice board is full!")) else return ..() -/obj/structure/noticeboard/interact(mob/user) - ui_interact(user) +/obj/structure/noticeboard/ui_state(mob/user) + return GLOB.physical_state -/obj/structure/noticeboard/ui_interact(mob/user) +/obj/structure/noticeboard/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "NoticeBoard", name) + ui.open() + +/obj/structure/noticeboard/ui_data(mob/user) + var/list/data = list() + data["allowed"] = allowed(user) + data["items"] = list() + for(var/obj/item/content in contents) + var/list/content_data = list( + name = content.name, + ref = REF(content) + ) + data["items"] += list(content_data) + return data + +/obj/structure/noticeboard/ui_act(action, params) . = ..() - var/auth = allowed(user) - var/dat = "[name]
    " - for(var/obj/item/P in src) - if(istype(P, /obj/item/paper)) - dat += "[P.name] [auth ? "Write Remove" : ""]
    " - else - dat += "[P.name] [auth ? "Remove" : ""]
    " - user << browse("Notices[dat]","window=noticeboard") - onclose(user, "noticeboard") + if(.) + return -/obj/structure/noticeboard/Topic(href, href_list) - ..() - usr.set_machine(src) - if(href_list["remove"]) - if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open - return - var/obj/item/I = locate(href_list["remove"]) in contents - if(istype(I) && I.loc == src) - I.forceMove(usr.loc) - usr.put_in_hands(I) - notices-- - icon_state = "nboard0[notices]" + var/obj/item/item = locate(params["ref"]) in contents + if(!istype(item) || item.loc != src) + return - if(href_list["write"]) - if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open - return - var/obj/item/P = locate(href_list["write"]) in contents - if(istype(P) && P.loc == src) - var/obj/item/I = usr.is_holding_item_of_type(/obj/item/pen) - if(I) - add_fingerprint(usr) - P.attackby(I, usr) + var/mob/user = usr + + switch(action) + if("examine") + if(istype(item, /obj/item/paper)) + item.ui_interact(user) else - to_chat(usr, "You'll need something to write with!") + user.examinate(item) + return TRUE + if("remove") + if(!allowed(user)) + return + remove_item(item, user) + return TRUE - if(href_list["read"]) - var/obj/item/I = locate(href_list["read"]) in contents - if(istype(I) && I.loc == src) - usr.examinate(I) +/** + * Removes an item from the notice board + * + * Arguments: + * * item - The item that is to be removed + * * user - The mob that is trying to get the item removed, if there is one + */ +/obj/structure/noticeboard/proc/remove_item(obj/item/item, mob/user) + item.forceMove(drop_location()) + if(user) + user.put_in_hands(item) + balloon_alert(user, "removed from board") + notices-- + icon_state = "nboard0[notices]" /obj/structure/noticeboard/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) new /obj/item/stack/sheet/metal (loc, 1) + for(var/obj/item/content in contents) + remove_item(content) qdel(src) // Notice boards for the heads of staff (plus the qm) @@ -131,3 +167,5 @@ name = "Staff Notice Board" desc = "Important notices from the heads of staff." req_access = list(ACCESS_HEADS) + +#undef MAX_NOTICES diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm index ff8287d77b..ff85f5b2eb 100644 --- a/code/game/objects/structures/plasticflaps.dm +++ b/code/game/objects/structures/plasticflaps.dm @@ -3,7 +3,7 @@ desc = "Heavy duty, airtight, plastic flaps. Definitely can't get past those. No way." icon = 'icons/obj/stationobjs.dmi' icon_state = "plasticflaps" - armor = list("melee" = 100, "bullet" = 80, "laser" = 80, "energy" = 100, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 50, "acid" = 50) + armor = list(MELEE = 100, BULLET = 80, LASER = 80, ENERGY = 100, BOMB = 50, BIO = 100, RAD = 100, FIRE = 50, ACID = 50) density = FALSE anchored = TRUE CanAtmosPass = ATMOS_PASS_NO @@ -11,7 +11,7 @@ /obj/structure/plasticflaps/opaque opacity = TRUE -/obj/structure/plasticflaps/Initialize() +/obj/structure/plasticflaps/Initialize(mapload) . = ..() alpha = 0 SSvis_overlays.add_vis_overlay(src, icon, icon_state, ABOVE_MOB_LAYER, plane, dir, add_appearance_flags = RESET_ALPHA) //you see mobs under it, but you hit them like they are above it @@ -56,20 +56,22 @@ return FALSE return TRUE -/obj/structure/plasticflaps/CanAStarPass(ID, to_dir, caller) +/obj/structure/plasticflaps/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller) if(isliving(caller)) if(isbot(caller)) - return 1 + return TRUE - var/mob/living/M = caller - if(!(SEND_SIGNAL(M, COMSIG_CHECK_VENTCRAWL)) && M.mob_size != MOB_SIZE_TINY) - return 0 - var/atom/movable/M = caller - if(M && M.pulling) - return CanAStarPass(ID, to_dir, M.pulling) - return 1 //diseases, stings, etc can pass + var/mob/living/living_caller = caller + if(!(SEND_SIGNAL(living_caller, COMSIG_CHECK_VENTCRAWL)) && living_caller.mob_size != MOB_SIZE_TINY) + return FALSE + + if(caller?.pulling) + return CanAStarPass(ID, to_dir, caller.pulling) + return TRUE //diseases, stings, etc can pass + +/obj/structure/plasticflaps/CanAllowThrough(atom/movable/A, turf/T) + . = ..() -/obj/structure/plasticflaps/CanPass(atom/movable/A, turf/T) if(istype(A) && (A.pass_flags & PASSGLASS)) return prob(60) @@ -93,14 +95,13 @@ return 1 if(!M.lying && !(SEND_SIGNAL(M, COMSIG_CHECK_VENTCRAWL)) && M.mob_size != MOB_SIZE_TINY) //If your not laying down, or a ventcrawler or a small creature, no pass. return 0 - return ..() /obj/structure/plasticflaps/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) new /obj/item/stack/sheet/plastic/five(loc) qdel(src) -/obj/structure/plasticflaps/Initialize() +/obj/structure/plasticflaps/Initialize(mapload) . = ..() air_update_turf(TRUE) diff --git a/code/game/objects/structures/railings.dm b/code/game/objects/structures/railings.dm index 21cf97ba70..bfe6d8beee 100644 --- a/code/game/objects/structures/railings.dm +++ b/code/game/objects/structures/railings.dm @@ -18,7 +18,7 @@ . = ..() AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS ,null,CALLBACK(src, .proc/can_be_rotated),CALLBACK(src,.proc/after_rotation)) -/obj/structure/railing/Initialize() +/obj/structure/railing/Initialize(mapload) . = ..() ini_dir = dir @@ -78,7 +78,7 @@ /obj/structure/railing/CheckExit(atom/movable/mover, turf/target) ..() if(get_dir(loc, target) & dir) - var/checking = UNSTOPPABLE | FLYING | FLOATING + var/checking = PHASING | FLYING | FLOATING return !density || mover.throwing || mover.movement_type & checking || mover.move_force >= MOVE_FORCE_EXTREMELY_STRONG return TRUE diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm index 8174f6a82e..acf7e19f75 100644 --- a/code/game/objects/structures/reflector.dm +++ b/code/game/objects/structures/reflector.dm @@ -17,7 +17,7 @@ var/list/allowed_projectile_typecache = list(/obj/item/projectile/beam) var/rotation_angle = -1 -/obj/structure/reflector/Initialize() +/obj/structure/reflector/Initialize(mapload) . = ..() icon_state = "reflector_base" allowed_projectile_typecache = typecacheof(allowed_projectile_typecache) @@ -249,7 +249,7 @@ P.setAngle(rotation_angle) return ..() -/obj/structure/reflector/ex_act() +/obj/structure/reflector/ex_act(severity, target, origin) if(admin) return else @@ -263,3 +263,7 @@ return else return ..() + +/obj/structure/reflector/shuttleRotate(rotation, params) + . = ..() + setAngle(SIMPLIFY_DEGREES(rotation_angle + rotation)) diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index 55eb100b21..beacee827c 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -84,7 +84,7 @@ FLOOR SAFES /obj/structure/safe/blob_act(obj/structure/blob/B) return -/obj/structure/safe/ex_act(severity, target) +/obj/structure/safe/ex_act(severity, target, origin) if(((severity == 2 && target == src) || severity == 1) && explosion_count < BROKEN_THRESHOLD) explosion_count++ switch(explosion_count) diff --git a/code/game/objects/structures/showcase.dm b/code/game/objects/structures/showcase.dm index 3b7933ab87..9f52bfbefb 100644 --- a/code/game/objects/structures/showcase.dm +++ b/code/game/objects/structures/showcase.dm @@ -17,7 +17,7 @@ icon = 'icons/obj/computer.dmi' icon_state = "computer" -/obj/structure/showcase/fakeid/Initialize() +/obj/structure/showcase/fakeid/Initialize(mapload) . = ..() add_overlay("id") add_overlay("id_key") @@ -28,7 +28,7 @@ icon = 'icons/obj/computer.dmi' icon_state = "computer" -/obj/structure/showcase/fakesec/Initialize() +/obj/structure/showcase/fakesec/Initialize(mapload) . = ..() add_overlay("security") add_overlay("security_key") diff --git a/code/game/objects/structures/signs/_signs.dm b/code/game/objects/structures/signs/_signs.dm index 8b82cdba5e..0e4f85572c 100644 --- a/code/game/objects/structures/signs/_signs.dm +++ b/code/game/objects/structures/signs/_signs.dm @@ -6,7 +6,7 @@ plane = ABOVE_WALL_PLANE layer = SIGN_LAYER max_integrity = 100 - armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/buildable_sign = 1 //unwrenchable and modifiable rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE diff --git a/code/game/objects/structures/spawner.dm b/code/game/objects/structures/spawner.dm index 7d13af1e3e..8b78253adc 100644 --- a/code/game/objects/structures/spawner.dm +++ b/code/game/objects/structures/spawner.dm @@ -14,7 +14,7 @@ var/spawn_text = "emerges from" var/faction = list("hostile") -/obj/structure/spawner/Initialize() +/obj/structure/spawner/Initialize(mapload) . = ..() AddComponent(/datum/component/spawner, mob_types, spawn_time, faction, spawn_text, max_mobs) diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index 2924545cc1..c3eed136be 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -6,43 +6,59 @@ density = TRUE anchored = FALSE max_integrity = 100 - var/oreAmount = 5 - var/material_drop_type = /obj/item/stack/sheet/metal - var/impressiveness = 15 CanAtmosPass = ATMOS_PASS_DENSITY + /// Beauty component mood modifier + var/impressiveness = 15 + /// Art component subtype added to this statue + var/art_type = /datum/element/art + /// Abstract root type + var/abstract_type = /obj/structure/statue - -/obj/structure/statue/Initialize() +/obj/structure/statue/Initialize(mapload) . = ..() - AddElement(/datum/element/art, impressiveness) - addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, impressiveness * 75)), 0) + AddElement(art_type, impressiveness) + AddElement(/datum/element/beauty, impressiveness * 75) + +/obj/structure/statue/ComponentInitialize() + . = ..() + var/rotation_flags = ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS + AddComponent(/datum/component/simple_rotation, rotation_flags, null, CALLBACK(src, .proc/can_be_rotated)) + +/obj/structure/statue/proc/can_be_rotated(mob/user, rotation_type) + if(anchored) + to_chat(user, "[src] cannot be rotated while it is fastened to the floor!") + return FALSE + return TRUE /obj/structure/statue/attackby(obj/item/W, mob/living/user, params) add_fingerprint(user) if(!(flags_1 & NODECONSTRUCT_1)) if(default_unfasten_wrench(user, W)) return - if(W.tool_behaviour == TOOL_WELDER || istype(W, /obj/item/gun/energy/plasmacutter)) + if(W.tool_behaviour == TOOL_WELDER) if(!W.tool_start_check(user, amount=0)) return FALSE - user.visible_message("[user] is slicing apart the [name].", \ - "You are slicing apart the [name]...") + user.visible_message(span_notice("[user] is slicing apart the [name]."), \ + span_notice("You are slicing apart the [name]...")) if(W.use_tool(src, user, 40, volume=50)) - user.visible_message("[user] slices apart the [name].", \ - "You slice apart the [name]!") + user.visible_message(span_notice("[user] slices apart the [name]."), \ + span_notice("You slice apart the [name]!")) deconstruct(TRUE) return return ..() +/obj/structure/statue/AltClick(mob/user) + return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation + /obj/structure/statue/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) - if(material_drop_type) - var/drop_amt = oreAmount - if(!disassembled) - drop_amt -= 2 - if(drop_amt > 0) - new material_drop_type(get_turf(src), drop_amt) + var/amount_mod = disassembled ? 0 : -2 + for(var/mat in custom_materials) + var/datum/material/custom_material = SSmaterials.GetMaterialRef(mat) + var/amount = max(0,round(custom_materials[mat]/MINERAL_MATERIAL_AMOUNT) + amount_mod) + if(amount > 0) + new custom_material.sheet_type(drop_location(),amount) qdel(src) //////////////////////////////////////STATUES///////////////////////////////////////////////////////////// @@ -51,10 +67,9 @@ /obj/structure/statue/uranium max_integrity = 300 light_range = 2 - material_drop_type = /obj/item/stack/sheet/mineral/uranium - var/last_event = 0 - var/active = null + custom_materials = list(/datum/material/uranium=MINERAL_MATERIAL_AMOUNT*5) impressiveness = 25 // radiation makes an impression + abstract_type = /obj/structure/statue/uranium /obj/structure/statue/uranium/nuke name = "statue of a nuclear fission explosive" @@ -66,39 +81,14 @@ desc = "This statue has a sickening green colour." icon_state = "eng" -/obj/structure/statue/uranium/attackby(obj/item/W, mob/user, params) - radiate() - return ..() - -/obj/structure/statue/uranium/Bumped(atom/movable/AM) - radiate() - ..() - -/obj/structure/statue/uranium/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - radiate() - . = ..() - -/obj/structure/statue/uranium/attack_paw(mob/user) - radiate() - . = ..() - -/obj/structure/statue/uranium/proc/radiate() - if(!active) - if(world.time > last_event+15) - active = 1 - radiation_pulse(src, 30) - last_event = world.time - active = null - return - return - ////////////////////////////plasma/////////////////////////////////////////////////////////////////////// /obj/structure/statue/plasma max_integrity = 200 - material_drop_type = /obj/item/stack/sheet/mineral/plasma desc = "This statue is suitably made from plasma." impressiveness = 20 + custom_materials = list(/datum/material/plasma=MINERAL_MATERIAL_AMOUNT*5) + abstract_type = /obj/structure/statue/plasma /obj/structure/statue/plasma/scientist name = "statue of a scientist" @@ -108,7 +98,6 @@ if(exposed_temperature > 300) PlasmaBurn(exposed_temperature) - /obj/structure/statue/plasma/bullet_act(obj/item/projectile/Proj) var/burn = FALSE if(!(Proj.nodamage) && Proj.damage_type == BURN && !QDELETED(src)) @@ -136,7 +125,9 @@ /obj/structure/statue/plasma/proc/PlasmaBurn(exposed_temperature) if(QDELETED(src)) return - atmos_spawn_air("plasma=[oreAmount*10];TEMP=[exposed_temperature]") + if(custom_materials[/datum/material/plasma]) + var/plasma_amount = round(custom_materials[/datum/material/plasma]/MINERAL_MATERIAL_AMOUNT) + atmos_spawn_air("plasma=[plasma_amount*10];TEMP=[exposed_temperature]") deconstruct(FALSE) /obj/structure/statue/plasma/proc/ignite(exposed_temperature) @@ -147,9 +138,10 @@ /obj/structure/statue/gold max_integrity = 300 - material_drop_type = /obj/item/stack/sheet/mineral/gold desc = "This is a highly valuable statue made from gold." impressiveness = 30 + custom_materials = list(/datum/material/gold=MINERAL_MATERIAL_AMOUNT*5) + abstract_type = /obj/structure/statue/gold /obj/structure/statue/gold/hos name = "statue of the head of security" @@ -175,9 +167,10 @@ /obj/structure/statue/silver max_integrity = 300 - material_drop_type = /obj/item/stack/sheet/mineral/silver desc = "This is a valuable statue made from silver." impressiveness = 25 + custom_materials = list(/datum/material/silver=MINERAL_MATERIAL_AMOUNT*5) + abstract_type = /obj/structure/statue/silver /obj/structure/statue/silver/md name = "statue of a medical officer" @@ -203,9 +196,10 @@ /obj/structure/statue/diamond max_integrity = 1000 - material_drop_type = /obj/item/stack/sheet/mineral/diamond desc = "This is a very expensive diamond statue." impressiveness = 60 + custom_materials = list(/datum/material/diamond=MINERAL_MATERIAL_AMOUNT*5) + abstract_type = /obj/structure/statue/diamond /obj/structure/statue/diamond/captain name = "statue of THE captain." @@ -223,43 +217,22 @@ /obj/structure/statue/bananium max_integrity = 300 - material_drop_type = /obj/item/stack/sheet/mineral/bananium desc = "A bananium statue with a small engraving:'HOOOOOOONK'." - var/spam_flag = 0 impressiveness = 65 + custom_materials = list(/datum/material/bananium=MINERAL_MATERIAL_AMOUNT*5) + abstract_type = /obj/structure/statue/bananium /obj/structure/statue/bananium/clown name = "statue of a clown" icon_state = "clown" -/obj/structure/statue/bananium/Bumped(atom/movable/AM) - honk() - ..() - -/obj/structure/statue/bananium/attackby(obj/item/W, mob/user, params) - honk() - return ..() - -/obj/structure/statue/bananium/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - honk() - . = ..() - -/obj/structure/statue/bananium/attack_paw(mob/user) - honk() - ..() - -/obj/structure/statue/bananium/proc/honk() - if(!spam_flag) - spam_flag = 1 - playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1) - spawn(20) - spam_flag = 0 - /////////////////////sandstone///////////////////////////////////////// /obj/structure/statue/sandstone max_integrity = 50 - material_drop_type = /obj/item/stack/sheet/mineral/sandstone + impressiveness = 15 + custom_materials = list(/datum/material/sandstone=MINERAL_MATERIAL_AMOUNT*5) + abstract_type = /obj/structure/statue/sandstone /obj/structure/statue/sandstone/assistant name = "statue of an assistant" @@ -277,9 +250,327 @@ /obj/structure/statue/snow max_integrity = 50 - material_drop_type = /obj/item/stack/sheet/mineral/snow + custom_materials = list(/datum/material/snow=MINERAL_MATERIAL_AMOUNT*5) + abstract_type = /obj/structure/statue/snow /obj/structure/statue/snow/snowman name = "snowman" desc = "Several lumps of snow put together to form a snowman." icon_state = "snowman" + +/obj/structure/statue/snow/snowlegion + name = "snowlegion" + desc = "Looks like that weird kid with the tiger plushie has been round here again." + icon_state = "snowlegion" + +///////////////////////////////bronze/////////////////////////////////// + +/obj/structure/statue/bronze + custom_materials = list(/datum/material/bronze=MINERAL_MATERIAL_AMOUNT*5) + abstract_type = /obj/structure/statue/bronze + +/obj/structure/statue/bronze/marx + name = "\improper Karl Marx bust" + desc = "A bust depicting a certain 19th century economist. You get the feeling a specter is haunting the station." + icon_state = "marx" + art_type = /datum/element/art/rev + +///////////Elder Atmosian/////////////////////////////////////////// +/* Yeah no. +/obj/structure/statue/elder_atmosian + name = "Elder Atmosian" + desc = "A statue of an Elder Atmosian, capable of bending the laws of thermodynamics to their will" + icon_state = "eng" + custom_materials = list(/datum/material/metalhydrogen = MINERAL_MATERIAL_AMOUNT*10) + max_integrity = 1000 + impressiveness = 100 + abstract_type = /obj/structure/statue/elder_atmosian //This one is uncarvable +*/ + +/obj/item/chisel + name = "chisel" + desc = "Breaking and making art since 4000 BC. This one uses advanced technology to allow creation of lifelike moving statues." + icon = 'icons/obj/statue.dmi' + icon_state = "chisel" + item_state = "screwdriver_nuke" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = ITEM_SLOT_BELT + force = 5 + w_class = WEIGHT_CLASS_TINY + throwforce = 5 + throw_speed = 3 + throw_range = 5 + custom_materials = list(/datum/material/iron=75) + attack_verb = list("stabs") + hitsound = 'sound/weapons/bladeslice.ogg' + usesound = list('sound/items/screwdriver.ogg', 'sound/items/screwdriver2.ogg') + drop_sound = 'sound/items/handling/screwdriver_drop.ogg' + pickup_sound = 'sound/items/handling/screwdriver_pickup.ogg' + // item_flags = EYE_STAB // don't have it + sharpness = SHARP_POINTY + + /// Block we're currently carving in + var/obj/structure/carving_block/prepared_block + /// If tracked user moves we stop sculpting + var/mob/living/tracked_user + /// Currently sculpting + var/sculpting = FALSE + +/obj/item/chisel/Initialize(mapload) + . = ..() + //AddElement(/datum/element/eyestab) + //AddElement(/datum/element/wall_engraver) + //deals 200 damage to statues, meaning you can actually kill one in ~250 hits + +/obj/item/chisel/ComponentInitialize() + . = ..() + AddComponent(/datum/component/bane, /mob/living/simple_animal/hostile/statue, damage_multiplier = 40) + +/obj/item/chisel/Destroy() + prepared_block = null + tracked_user = null + return ..() + +/* +Hit the block to start +Point with the chisel at the target to choose what to sculpt or hit block to choose from preset statue types. +Hit block again to start sculpting. +Moving interrupts +*/ +/obj/item/chisel/pre_attack(atom/A, mob/living/user, params) + . = ..() + if(sculpting) + return + if(istype(A,/obj/structure/carving_block)) + if(A == prepared_block && (prepared_block.current_target || prepared_block.current_preset_type)) + start_sculpting(user) + else if(!prepared_block) + set_block(A,user) + else if(A == prepared_block) + show_generic_statues_prompt(user) + return TRUE + else if(prepared_block) //We're aiming at something next to us with block prepared + prepared_block.set_target(A,user) + return TRUE + +// We aim at something distant. +/obj/item/chisel/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + . = ..() + if(!proximity_flag && !sculpting && prepared_block && ismovable(target) && prepared_block.completion == 0) + prepared_block.set_target(target,user) + +/obj/item/chisel/proc/start_sculpting(mob/living/user) + to_chat(user,span_notice("You start sculpting [prepared_block]."),type="info") + sculpting = TRUE + //How long whole process takes + var/sculpting_time = 30 SECONDS + //Single interruptible progress period + var/sculpting_period = round(sculpting_time / world.icon_size) //this is just so it reveals pixels line by line for each. + var/interrupted = FALSE + var/remaining_time = sculpting_time - (prepared_block.completion * sculpting_time) + + var/datum/progressbar/total_progress_bar = new(user, sculpting_time, prepared_block ) + while(remaining_time > 0 && !interrupted) + if(do_after(user,sculpting_period, target = prepared_block, progress = FALSE)) + remaining_time -= sculpting_period + prepared_block.set_completion((sculpting_time - remaining_time)/sculpting_time) + total_progress_bar.update(sculpting_time - remaining_time) + else + interrupted = TRUE + total_progress_bar.end_progress() + if(!interrupted && !QDELETED(prepared_block)) + prepared_block.create_statue() + to_chat(user,span_notice("The statue is finished!"),type="info") + break_sculpting() + +/obj/item/chisel/proc/set_block(obj/structure/carving_block/B,mob/living/user) + prepared_block = B + tracked_user = user + RegisterSignal(tracked_user,COMSIG_MOVABLE_MOVED,.proc/break_sculpting) + to_chat(user,span_notice("You prepare to work on [B]."),type="info") + +/obj/item/chisel/dropped(mob/user, silent) + . = ..() + break_sculpting() + +/obj/item/chisel/proc/break_sculpting() + SIGNAL_HANDLER + sculpting = FALSE + if(prepared_block && prepared_block.completion == 0) + prepared_block.reset_target() + prepared_block = null + if(tracked_user) + UnregisterSignal(tracked_user,COMSIG_MOVABLE_MOVED) + tracked_user = null + +/obj/item/chisel/proc/show_generic_statues_prompt(mob/living/user) + var/list/choices = list() + for(var/statue_path in prepared_block.get_possible_statues()) + var/obj/structure/statue/S = statue_path + choices[statue_path] = image(icon=initial(S.icon),icon_state=initial(S.icon_state)) + var/choice = show_radial_menu(user, prepared_block , choices, require_near = TRUE) + if(choice) + prepared_block.current_preset_type = choice + var/image/chosen_looks = choices[choice] + prepared_block.current_target = chosen_looks.appearance + var/obj/structure/statue/S = choice + to_chat(user,span_notice("You decide to sculpt [prepared_block] into [initial(S.name)]."),type="info") + + +/obj/structure/carving_block + name = "block" + desc = "Ready for sculpting." + icon = 'icons/obj/statue.dmi' + icon_state = "block" + material_flags = MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS | MATERIAL_ADD_PREFIX // MATERIAL_EFFECTS + density = TRUE + material_modifier = 0.5 //50% effectiveness of materials + + /// The thing it will look like - Unmodified resulting statue appearance + var/current_target + /// Currently chosen preset statue type + var/current_preset_type + //Table of required materials for each non-abstract statue type + var/static/list/statue_costs + /// statue completion from 0 to 1.0 + var/completion = 0 + /// Greyscaled target with cutout filter + var/mutable_appearance/target_appearance_with_filters + /// HSV color filters parameters + var/static/list/greyscale_with_value_bump = list(0,0,0, 0,0,0, 0,0,1, 0,0,-0.05) + +/obj/structure/carving_block/Destroy() + current_target = null + target_appearance_with_filters = null + return ..() + +/obj/structure/carving_block/proc/set_target(atom/movable/target,mob/living/user) + if(!is_viable_target(target)) + to_chat(user,"You won't be able to carve that.") + return + if(istype(target,/obj/structure/statue/custom)) + var/obj/structure/statue/custom/original = target + current_target = original.content_ma + else + current_target = target.appearance + var/mutable_appearance/ma = current_target + to_chat(user,span_notice("You decide to sculpt [src] into [ma.name]."),type="info") + +/obj/structure/carving_block/proc/reset_target() + current_target = null + current_preset_type = null + target_appearance_with_filters = null + +/obj/structure/carving_block/update_overlays() + . = ..() + if(!target_appearance_with_filters) + return + //We're only keeping one instance here that changes in the middle so we have to clone it to avoid managed overlay issues + var/mutable_appearance/clone = new(target_appearance_with_filters) + . += clone + +/obj/structure/carving_block/proc/is_viable_target(atom/movable/target) + //Only things on turfs + if(!isturf(target.loc)) + return FALSE + //No big icon things + var/icon/thing_icon = icon(target.icon, target.icon_state) + if(thing_icon.Height() != world.icon_size || thing_icon.Width() != world.icon_size) + return FALSE + return TRUE + +/obj/structure/carving_block/proc/create_statue() + if(current_preset_type) + var/obj/structure/statue/preset_statue = new current_preset_type(get_turf(src)) + preset_statue.set_custom_materials(custom_materials) + qdel(src) + else if(current_target) + var/obj/structure/statue/custom/new_statue = new(get_turf(src)) + new_statue.set_visuals(current_target) + new_statue.set_custom_materials(custom_materials) + var/mutable_appearance/ma = current_target + new_statue.dir = ma.dir + new_statue.name = "statue of [ma.name]" + new_statue.desc = "A statue depicting [ma.name]." + qdel(src) + +/obj/structure/carving_block/proc/set_completion(value) + if(!current_target) + return + if(!target_appearance_with_filters) + target_appearance_with_filters = new(current_target) + // KEEP_APART in case carving block gets KEEP_TOGETHER from somewhere like material texture filters. + target_appearance_with_filters.appearance_flags |= KEEP_TOGETHER | KEEP_APART + //Doesn't use filter helpers because MAs aren't atoms + target_appearance_with_filters.filters = filter(type="color",color=greyscale_with_value_bump,space=FILTER_COLOR_HSV) + completion = value + var/static/icon/white = icon('icons/effects/alphacolors.dmi', "white") + switch(value) + if(0) + //delete uncovered and reset filters + remove_filter("partial_uncover") + target_appearance_with_filters = null + else + var/mask_offset = min(world.icon_size,round(completion * world.icon_size)) + remove_filter("partial_uncover") + add_filter("partial_uncover", 1, alpha_mask_filter(icon = white, y = -mask_offset)) + target_appearance_with_filters.filters = filter(type="alpha",icon=white,y=-mask_offset,flags=MASK_INVERSE) + update_appearance() + + +/// Returns a list of preset statues carvable from this block depending on the custom materials +/obj/structure/carving_block/proc/get_possible_statues() + . = list() + if(!statue_costs) + statue_costs = build_statue_cost_table() + for(var/statue_path in statue_costs) + var/list/carving_cost = statue_costs[statue_path] + var/enough_materials = TRUE + for(var/required_material in carving_cost) + if(!custom_materials[required_material] || custom_materials[required_material] < carving_cost[required_material]) + enough_materials = FALSE + break + if(enough_materials) + . += statue_path + +/obj/structure/carving_block/proc/build_statue_cost_table() + . = list() + for(var/statue_type in subtypesof(/obj/structure/statue) - /obj/structure/statue/custom) + var/obj/structure/statue/S = new statue_type() + if(!S.icon_state || S.abstract_type == S.type || !S.custom_materials) + continue + .[S.type] = S.custom_materials + qdel(S) + +/obj/structure/statue/custom + name = "custom statue" + icon_state = "base" + obj_flags = CAN_BE_HIT | UNIQUE_RENAME + appearance_flags = TILE_BOUND | PIXEL_SCALE | KEEP_TOGETHER //Added keep together in case targets has weird layering + material_flags = MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS // MATERIAL_EFFECTS + /// primary statue overlay + var/mutable_appearance/content_ma + var/static/list/greyscale_with_value_bump = list(0,0,0, 0,0,0, 0,0,1, 0,0,-0.05) + +/obj/structure/statue/custom/Destroy() + content_ma = null + return ..() + +/obj/structure/statue/custom/proc/set_visuals(model_appearance) + if(content_ma) + QDEL_NULL(content_ma) + content_ma = new + content_ma.appearance = model_appearance + content_ma.pixel_x = 0 + content_ma.pixel_y = 0 + content_ma.alpha = 255 + content_ma.appearance_flags &= ~KEEP_APART //Don't want this + content_ma.filters = filter(type="color",color=greyscale_with_value_bump,space=FILTER_COLOR_HSV) + update_appearance() + +/obj/structure/statue/custom/update_overlays() + . = ..() + if(content_ma) + . += content_ma diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 065c0d2f28..b7642f4658 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -19,10 +19,10 @@ icon_state = "table" density = TRUE anchored = TRUE + pass_flags_self = PASSTABLE | LETPASSTHROW layer = TABLE_LAYER climbable = TRUE obj_flags = CAN_BE_HIT|SHOVABLE_ONTO - pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.") attack_hand_speed = CLICK_CD_MELEE attack_hand_is_action = TRUE var/frame = /obj/structure/table_frame @@ -37,6 +37,16 @@ smooth = SMOOTH_TRUE canSmoothWith = list(/obj/structure/table, /obj/structure/table/reinforced, /obj/structure/table/greyscale) +/obj/structure/table/Initialize(mapload) + . = ..() + + var/static/list/barehanded_interactions = list( + INTENT_ANY = "Slap", + INTENT_HARM = "Slam" + ) + + AddElement(/datum/element/contextual_screentip_bare_hands, rmb_text_combat_mode = barehanded_interactions) + /obj/structure/table/examine(mob/user) . = ..() . += deconstruction_hints(user) @@ -99,21 +109,19 @@ /obj/structure/table/attack_tk() return FALSE -/obj/structure/table/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSTABLE)) - return 1 +/obj/structure/table/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() + if(.) + return if(mover.throwing) - return 1 + return TRUE if(locate(/obj/structure/table) in get_turf(mover)) - return 1 - else - return !density + return TRUE -/obj/structure/table/CanAStarPass(ID, dir, caller) +/obj/structure/table/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller) . = !density - if(ismovable(caller)) - var/atom/movable/mover = caller - . = . || (mover.pass_flags & PASSTABLE) + if(istype(caller)) + . = . || (caller.pass_flags & PASSTABLE) /obj/structure/table/proc/tableplace(mob/living/user, mob/living/pushed_mob) pushed_mob.forceMove(src.loc) @@ -318,7 +326,7 @@ canSmoothWith = null max_integrity = 70 resistance_flags = ACID_PROOF - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 100) var/list/debris = list() /obj/structure/table/glass/New() @@ -396,7 +404,7 @@ canSmoothWith = null max_integrity = 270 resistance_flags = ACID_PROOF - armor = list("melee" = 10, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + armor = list(MELEE = 10, BULLET = 5, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 80, ACID = 100) var/list/debris = list() /obj/structure/table/plasmaglass/New() @@ -484,7 +492,7 @@ /obj/structure/table/wood/fancy/royalblue) var/smooth_icon = 'icons/obj/smooth_structures/fancy_table.dmi' // see Initialize() -/obj/structure/table/wood/fancy/Initialize() +/obj/structure/table/wood/fancy/Initialize(mapload) . = ..() // Needs to be set dynamically because table smooth sprites are 32x34, // which the editor treats as a two-tile-tall object. The sprites are that @@ -492,6 +500,19 @@ // the sprites in the editor to see why. icon = smooth_icon + if (!(flags_1 & NODECONSTRUCT_1)) + var/static/list/tool_behaviors = list( + TOOL_SCREWDRIVER = list( + SCREENTIP_CONTEXT_LMB = list(INTENT_ANY = "Disassemble"), + ), + + TOOL_WRENCH = list( + SCREENTIP_CONTEXT_LMB = list(INTENT_ANY = "Deconstruct"), + ), + ) + + AddElement(/datum/element/contextual_screentip_tools, tool_behaviors) + /obj/structure/table/wood/fancy/black icon_state = "fancy_table_black" buildstack = /obj/item/stack/tile/carpet/black @@ -559,7 +580,7 @@ buildstack = /obj/item/stack/sheet/plasteel max_integrity = 200 integrity_failure = 0.25 - armor = list("melee" = 10, "bullet" = 30, "laser" = 30, "energy" = 100, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70) + armor = list(MELEE = 10, BULLET = 30, LASER = 30, ENERGY = 100, BOMB = 20, BIO = 0, RAD = 0, FIRE = 80, ACID = 70) /obj/structure/table/reinforced/deconstruction_hints(mob/user) if(deconstruction_ready) @@ -685,7 +706,7 @@ layer = TABLE_LAYER density = TRUE anchored = TRUE - pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density. + pass_flags_self = LETPASSTHROW //You can throw objects over this, despite it's density. max_integrity = 20 attack_hand_speed = CLICK_CD_MELEE attack_hand_is_action = TRUE @@ -702,11 +723,10 @@ else return 0 -/obj/structure/rack/CanAStarPass(ID, dir, caller) +/obj/structure/rack/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller) . = !density - if(ismovable(caller)) - var/atom/movable/mover = caller - . = . || (mover.pass_flags & PASSTABLE) + if(istype(caller)) + . = . || (caller.pass_flags & PASSTABLE) /obj/structure/rack/MouseDrop_T(obj/O, mob/user) . = ..() @@ -738,7 +758,7 @@ return user.do_attack_animation(src, ATTACK_EFFECT_KICK) user.visible_message("[user] kicks [src].", null, null, COMBAT_MESSAGE_RANGE) - take_damage(rand(4,8), BRUTE, "melee", 1) + take_damage(rand(4,8), BRUTE, MELEE, 1) /obj/structure/rack/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index 00df078d0b..695dcef476 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -17,7 +17,7 @@ /obj/structure/tank_dispenser/plasma oxygentanks = 0 -/obj/structure/tank_dispenser/Initialize() +/obj/structure/tank_dispenser/Initialize(mapload) . = ..() for(var/i in 1 to oxygentanks) new /obj/item/tank/internals/oxygen(src) diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index c5f3a089f7..dc920556f7 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -58,13 +58,10 @@ pinned_target.nullPinnedLoc() nullPinnedTarget() handle_density() - if(ishuman(user)) - if(!user.get_active_held_item()) - user.put_in_hands(pinned_target) - to_chat(user, "You take the target out of the stake.") - else - pinned_target.forceMove(user.drop_location()) - to_chat(user, "You take the target out of the stake.") + pinned_target.forceMove(get_turf(src)) + to_chat(user, "You take the target out of the stake.") + if(user.can_hold_items()) + user.put_in_hands(pinned_target) /obj/structure/target_stake/bullet_act(obj/item/projectile/P) if(pinned_target) diff --git a/code/game/objects/structures/transit_tubes/transit_tube.dm b/code/game/objects/structures/transit_tubes/transit_tube.dm index 7e3684ad32..c8341c8834 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube.dm @@ -8,17 +8,13 @@ layer = LOW_ITEM_LAYER anchored = TRUE climbable = 1 + pass_flags_self = PASSGLASS var/tube_construction = /obj/structure/c_transit_tube var/list/tube_dirs //list of directions this tube section can connect to. var/exit_delay = 1 var/enter_delay = 0 var/const/time_to_unwrench = 2 SECONDS -/obj/structure/transit_tube/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return 1 - return !density - /obj/structure/transit_tube/New(loc, newdirection) ..(loc) if(newdirection) 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 82e946a2f4..0ae1aff68a 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm @@ -8,7 +8,7 @@ var/datum/gas_mixture/air_contents = new() -/obj/structure/transit_tube_pod/Initialize() +/obj/structure/transit_tube_pod/Initialize(mapload) . = ..() air_contents.set_moles(GAS_O2, MOLES_O2STANDARD) air_contents.set_moles(GAS_N2, MOLES_N2STANDARD) @@ -50,14 +50,14 @@ empty_pod(location) qdel(src) -/obj/structure/transit_tube_pod/ex_act(severity, target) +/obj/structure/transit_tube_pod/ex_act(severity, target, origin) ..() if(!QDELETED(src)) empty_pod() -/obj/structure/transit_tube_pod/contents_explosion(severity, target) +/obj/structure/transit_tube_pod/contents_explosion(severity, target, origin) for(var/atom/movable/AM in contents) - AM.ex_act(severity, target) + AM.ex_act(severity, target, origin) /obj/structure/transit_tube_pod/singularity_pull(S, current_size) ..() diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 9a2b4aab1a..40424d831d 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -16,7 +16,7 @@ attack_hand_speed = CLICK_CD_MELEE attack_hand_is_action = TRUE -/obj/structure/toilet/Initialize() +/obj/structure/toilet/Initialize(mapload) . = ..() open = round(rand(0, 1)) update_icon() @@ -48,7 +48,7 @@ GM.visible_message("[user] starts to give [GM] a swirlie!", "[user] starts to give you a swirlie...") swirlie = GM var/was_alive = (swirlie.stat != DEAD) - if(do_after(user, 3 SECONDS, target = src)) + if(do_after(user, 3 SECONDS, src)) GM.visible_message("[user] gives [GM] a swirlie!", "[user] gives you a swirlie!", "You hear a toilet flushing.") if(iscarbon(GM)) var/mob/living/carbon/C = GM @@ -138,7 +138,7 @@ /obj/structure/toilet/secret var/secret_type = null -/obj/structure/toilet/secret/Initialize() +/obj/structure/toilet/secret/Initialize(mapload) . = ..() if (secret_type) new secret_type(src) @@ -255,9 +255,9 @@ var/watertemp = "normal" //freezing, normal, or boiling var/datum/looping_sound/showering/soundloop -/obj/machinery/shower/Initialize() +/obj/machinery/shower/Initialize(mapload) . = ..() - soundloop = new(list(src), FALSE) + soundloop = new(src, FALSE) /obj/machinery/shower/Destroy() QDEL_NULL(soundloop) @@ -514,7 +514,7 @@ "You start washing your [washing_face ? "face" : "hands"]...") busy = TRUE - if(!do_after(user, 40, target = src)) + if(!do_after(user, 4 SECONDS, src)) busy = FALSE return @@ -595,7 +595,7 @@ if(user.a_intent != INTENT_HARM) to_chat(user, "You start washing [O]...") busy = TRUE - if(!do_after(user, 40, target = src)) + if(!do_after(user, 4 SECONDS, src)) busy = FALSE return 1 busy = FALSE @@ -669,7 +669,7 @@ icon_state = "well_3" return TRUE else - to_chat(user, "You need at least tweenty-five pieces of sandstone!") + to_chat(user, "You need at least twenty-five pieces of sandstone!") return if(steps == 3 && S.tool_behaviour == TOOL_SHOVEL) S.use_tool(src, user, 80, volume=100) diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index ef1ca6720a..4f1de6432a 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -50,11 +50,10 @@ /obj/structure/windoor_assembly/update_icon_state() icon_state = "[facing]_[secure ? "secure_" : ""]windoor_assembly[state]" -/obj/structure/windoor_assembly/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return 1 +/obj/structure/windoor_assembly/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(get_dir(loc, target) == dir) //Make sure looking at appropriate border - return !density + return if(istype(mover, /obj/structure/window)) var/obj/structure/window/W = mover if(!valid_window_location(loc, W.ini_dir)) @@ -65,7 +64,6 @@ return FALSE else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir)) return FALSE - return 1 /obj/structure/windoor_assembly/CanAtmosPass(turf/T) if(get_dir(loc, T) == dir) @@ -73,13 +71,13 @@ else return 1 -/obj/structure/windoor_assembly/CheckExit(atom/movable/mover as mob|obj, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return 1 +/obj/structure/windoor_assembly/CheckExit(atom/movable/mover, turf/target) + if(mover.pass_flags & pass_flags_self) + return TRUE if(get_dir(loc, target) == dir) return !density else - return 1 + return TRUE /obj/structure/windoor_assembly/attackby(obj/item/W, mob/user, params) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 5f84094477..cf5e34fd8b 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -18,6 +18,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) pressure_resistance = 4*ONE_ATMOSPHERE anchored = TRUE //initially is 0 for tile smoothing max_integrity = 25 + pass_flags_self = PASSGLASS var/ini_dir = null var/state = WINDOW_OUT_OF_FRAME var/reinf = FALSE @@ -31,7 +32,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) var/glass_amount = 1 can_be_unanchored = TRUE resistance_flags = ACID_PROOF - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 100) CanAtmosPass = ATMOS_PASS_PROC var/real_explosion_block //ignore this, just use explosion_block var/breaksound = "shatter" @@ -90,13 +91,13 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) . = ..() if(direct) setDir(direct) - + if(extra_reinforced && anchored) state = PRWINDOW_SECURE else if(reinf && anchored) state = WINDOW_SCREWED_TO_FRAME - + if(mapload && electrochromatic_id && electrochromatic_id[1] == "!") electrochromatic_id = SSmapping.get_obfuscated_id(electrochromatic_id) @@ -159,13 +160,15 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) else ..(FULLTILE_WINDOW_DIR) -/obj/structure/window/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return 1 +/obj/structure/window/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() + if(.) + return if(dir == FULLTILE_WINDOW_DIR) return 0 //full tile window, you can't move into it! - if(get_dir(loc, target) == dir) - return !density + var/attempted_dir = get_dir(loc, target) + if(attempted_dir == dir) + return if(istype(mover, /obj/structure/window)) var/obj/structure/window/W = mover if(!valid_window_location(loc, W.ini_dir)) @@ -176,7 +179,8 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) return FALSE else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir)) return FALSE - return 1 + else if(attempted_dir != dir) + return TRUE /obj/structure/window/CheckExit(atom/movable/O, turf/target) if(istype(O) && (O.pass_flags & PASSGLASS)) @@ -445,11 +449,6 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) /obj/structure/window/proc/check_state_and_anchored(checked_state, checked_anchored) return check_state(checked_state) && check_anchored(checked_anchored) -/obj/structure/window/mech_melee_attack(obj/mecha/M) - if(!can_be_reached()) - return - ..() - /obj/structure/window/proc/can_be_reached(mob/user) if(!fulltile) if(get_dir(user,src) & dir) @@ -571,13 +570,13 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) /obj/structure/window/get_dumping_location(obj/item/storage/source,mob/user) return null -/obj/structure/window/CanAStarPass(ID, to_dir) +/obj/structure/window/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller) if(!density) - return 1 + return TRUE if((dir == FULLTILE_WINDOW_DIR) || (dir == to_dir)) - return 0 + return FALSE - return 1 + return TRUE /obj/structure/window/GetExplosionBlock() return reinf && fulltile ? real_explosion_block : 0 @@ -600,7 +599,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) icon_state = "rwindow" reinf = TRUE heat_resistance = 1600 - armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) + armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 25, BIO = 100, RAD = 100, FIRE = 80, ACID = 100) max_integrity = 50 explosion_block = 1 wave_explosion_block = EXPLOSION_BLOCK_REINFORCED_WINDOW @@ -627,7 +626,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) icon_state = "plasmawindow" reinf = FALSE heat_resistance = 25000 - armor = list("melee" = 75, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 45, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100) + armor = list(MELEE = 75, BULLET = 5, LASER = 0, ENERGY = 0, BOMB = 45, BIO = 100, RAD = 100, FIRE = 99, ACID = 100) max_integrity = 150 explosion_block = 1 wave_explosion_block = EXPLOSION_BLOCK_BOROSILICATE_WINDOW @@ -655,7 +654,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) reinf = TRUE extra_reinforced = TRUE heat_resistance = 50000 - armor = list("melee" = 85, "bullet" = 20, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100) + armor = list(MELEE = 85, BULLET = 20, LASER = 0, ENERGY = 0, BOMB = 60, BIO = 100, RAD = 100, FIRE = 99, ACID = 100) max_integrity = 500 explosion_block = 2 wave_explosion_block = EXPLOSION_BLOCK_EXTREME @@ -719,7 +718,6 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) icon = 'icons/obj/smooth_structures/rplasma_window.dmi' icon_state = "rplasmawindow" dir = FULLTILE_WINDOW_DIR - state = PRWINDOW_SECURE max_integrity = 1000 fulltile = TRUE flags_1 = PREVENT_CLICK_UNDER_1 @@ -775,7 +773,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) flags_1 = PREVENT_CLICK_UNDER_1 reinf = TRUE heat_resistance = 1600 - armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) + armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 50, BIO = 100, RAD = 100, FIRE = 80, ACID = 100) smooth = SMOOTH_TRUE canSmoothWith = null explosion_block = 3 @@ -806,7 +804,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) reinf = TRUE extra_reinforced = TRUE heat_resistance = 1600 - armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) + armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 50, BIO = 100, RAD = 100, FIRE = 80, ACID = 100) smooth = SMOOTH_TRUE canSmoothWith = null explosion_block = 3 @@ -832,7 +830,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) icon_state = "clockwork_window_single" resistance_flags = FIRE_PROOF | ACID_PROOF max_integrity = 80 - armor = list("melee" = 60, "bullet" = 25, "laser" = 0, "energy" = 0, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) + armor = list(MELEE = 60, BULLET = 25, LASER = 0, ENERGY = 0, BOMB = 25, BIO = 100, RAD = 100, FIRE = 80, ACID = 100) explosion_block = 2 //fancy AND hard to destroy. the most useful combination. wave_explosion_block = EXPLOSION_BLOCK_BOROSILICATE_WINDOW wave_explosion_multiply = EXPLOSION_DAMPEN_BOROSILICATE_WINDOW @@ -918,13 +916,13 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) decon_speed = 10 CanAtmosPass = ATMOS_PASS_YES resistance_flags = FLAMMABLE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) breaksound = 'sound/items/poster_ripped.ogg' hitsound = 'sound/weapons/slashmiss.ogg' var/static/mutable_appearance/torn = mutable_appearance('icons/obj/smooth_structures/paperframes.dmi',icon_state = "torn", layer = ABOVE_OBJ_LAYER - 0.1) var/static/mutable_appearance/paper = mutable_appearance('icons/obj/smooth_structures/paperframes.dmi',icon_state = "paper", layer = ABOVE_OBJ_LAYER - 0.1) -/obj/structure/window/paperframe/Initialize() +/obj/structure/window/paperframe/Initialize(mapload) . = ..() update_icon() @@ -939,7 +937,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) user.visible_message("[user] knocks on [src].") playsound(src, "pageturn", 50, 1) else - take_damage(4,BRUTE,"melee", 0) + take_damage(4,BRUTE,MELEE, 0) playsound(src, hitsound, 50, 1) if(!QDELETED(src)) user.visible_message("[user] tears a hole in [src].") diff --git a/code/game/say.dm b/code/game/say.dm index b7bfe540d0..44f020e7c4 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -31,14 +31,42 @@ GLOBAL_LIST_INIT(freqtospan, list( /atom/movable/proc/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source) SEND_SIGNAL(src, COMSIG_MOVABLE_HEAR, args) +/atom/movable/proc/bark(list/hearers, distance, volume, pitch, queue_time) + if(queue_time && vocal_current_bark != queue_time) + return + if(SEND_SIGNAL(src, COMSIG_MOVABLE_BARK, hearers, distance, volume, pitch)) + return //bark interception. this probably counts as some flavor of BDSM + if(!vocal_bark) + if(!vocal_bark_id || !set_bark(vocal_bark_id)) //just-in-time bark generation + return + volume = min(volume, 100) + var/turf/T = get_turf(src) + for(var/mob/M in hearers) + M.playsound_local(T, vol = volume, vary = TRUE, frequency = pitch, max_distance = distance, falloff_distance = 0, falloff_exponent = BARK_SOUND_FALLOFF_EXPONENT(distance), S = vocal_bark, distance_multiplier = 1) + /atom/movable/proc/can_speak() return 1 /atom/movable/proc/send_speech(message, range = 7, atom/movable/source = src, bubble_type, list/spans, datum/language/message_language = null, message_mode) var/rendered = compose_message(src, message_language, message, , spans, message_mode, source) - for(var/_AM in get_hearers_in_view(range, source)) + var/list/hearers = get_hearers_in_view(range, source) + for(var/_AM in hearers) var/atom/movable/AM = _AM AM.Hear(rendered, src, message_language, message, , spans, message_mode, source) + if(SEND_SIGNAL(src, COMSIG_MOVABLE_QUEUE_BARK, hearers, args) || vocal_bark || vocal_bark_id) + for(var/mob/M in hearers) + if(!M.client) + continue + if(!(M.client.prefs.toggles & SOUND_BARK)) + hearers -= M + var/barks = min(round((LAZYLEN(message) / vocal_speed)) + 1, BARK_MAX_BARKS) + var/total_delay + vocal_current_bark = world.time //this is juuuuust random enough to reliably be unique every time send_speech() is called, in most scenarios + for(var/i in 1 to barks) + if(total_delay > BARK_MAX_TIME) + break + addtimer(CALLBACK(src, .proc/bark, hearers, range, vocal_volume, BARK_DO_VARY(vocal_pitch, vocal_pitch_range), vocal_current_bark), total_delay) + total_delay += rand(DS2TICKS(vocal_speed / BARK_SPEED_BASELINE), DS2TICKS(vocal_speed / BARK_SPEED_BASELINE) + DS2TICKS(vocal_speed / BARK_SPEED_BASELINE)) TICKS /atom/movable/proc/compose_message(atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, face_name = FALSE, atom/movable/source) if(!source) diff --git a/code/game/shuttle_engines.dm b/code/game/shuttle_engines.dm index e5d58c3e1b..b0f06a1495 100644 --- a/code/game/shuttle_engines.dm +++ b/code/game/shuttle_engines.dm @@ -8,7 +8,7 @@ icon = 'icons/turf/shuttle.dmi' resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF max_integrity = 500 - armor = list("melee" = 100, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70) //default + ignores melee + armor = list(MELEE = 100, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 70) //default + ignores melee /obj/structure/shuttle/engine name = "engine" diff --git a/code/game/sound.dm b/code/game/sound.dm index 3a65d47f3f..a99d9aeaa9 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -110,13 +110,20 @@ distance_multiplier - Can be used to multiply the distance at which the sound is */ /mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff_exponent = SOUND_FALLOFF_EXPONENT, channel = 0, pressure_affected = TRUE, sound/S, max_distance, - falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = SOUND_DEFAULT_DISTANCE_MULTIPLIER, envwet = -10000, envdry = 0) - if(!client || !can_hear()) + falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = SOUND_DEFAULT_DISTANCE_MULTIPLIER, envwet = -10000, envdry = 0, virtual_hearer) + if(audiovisual_redirect) + virtual_hearer = get_turf(src) + audiovisual_redirect.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, max_distance, falloff_distance, distance_multiplier, max(0, envwet), -10000, virtual_hearer) + //No return here, as we want to deliberately support the possibility of shenanigans in which mobs with clients can have active AV redirects to completely different players + if(!client) return if(!S) S = sound(get_sfx(soundin)) + if(!can_hear() && !(S.status & SOUND_UPDATE)) //This is primarily to make sure sound updates still go through when a spaceman's deaf + return + S.wait = 0 //No queue S.channel = channel || SSsounds.random_available_channel() S.volume = vol @@ -131,7 +138,7 @@ distance_multiplier - Can be used to multiply the distance at which the sound is S.frequency = get_rand_frequency() if(isturf(turf_source)) - var/turf/T = get_turf(src) + var/turf/T = virtual_hearer || get_turf(src) //sound volume falloff with distance var/distance = get_dist(T, turf_source) @@ -173,7 +180,7 @@ distance_multiplier - Can be used to multiply the distance at which the sound is var/dz = turf_source.y - T.y // Hearing from infront/behind S.z = dz * distance_multiplier var/dy = (turf_source.z - T.z) * 5 * distance_multiplier // Hearing from above / below, multiplied by 5 because we assume height is further along coords. - S.y = dy + S.y = dy + distance_multiplier S.falloff = isnull(max_distance)? FALLOFF_SOUNDS : max_distance //use max_distance, else just use 1 as we are a direct sound so falloff isnt relevant. diff --git a/code/game/turfs/baseturf_skipover.dm b/code/game/turfs/baseturf_skipover.dm index 4df8c86e62..9bef78a15e 100644 --- a/code/game/turfs/baseturf_skipover.dm +++ b/code/game/turfs/baseturf_skipover.dm @@ -3,7 +3,7 @@ name = "Baseturf skipover placeholder" desc = "This shouldn't exist" -/turf/baseturf_skipover/Initialize() +/turf/baseturf_skipover/Initialize(mapload) . = ..() stack_trace("[src]([type]) was instanced which should never happen. Changing into the next baseturf down...") ScrapeAway() diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm index bb5ca6da1a..7502d4b2f0 100644 --- a/code/game/turfs/change_turf.dm +++ b/code/game/turfs/change_turf.dm @@ -15,7 +15,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( if(turf_type) var/turf/newT = ChangeTurf(turf_type, baseturf_type, flags) - CALCULATE_ADJACENT_TURFS(newT) + newT.ImmediateCalculateAdjacentTurfs() /turf/proc/copyTurf(turf/T) if(T.type != type) @@ -151,17 +151,18 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( return var/turf/open/newTurf = . newTurf.air.copy_from(stashed_air) - update_air_ref(planetary_atmos ? 1 : 2) + newTurf.update_air_ref(planetary_atmos ? 1 : 2) QDEL_NULL(stashed_air) else + flags |= CHANGETURF_RECALC_ADJACENT if(ispath(path,/turf/closed)) - flags |= CHANGETURF_RECALC_ADJACENT - update_air_ref(-1) . = ..() + var/turf/open/newTurf = . + newTurf.update_air_ref(-1) else . = ..() - if(!istype(air,/datum/gas_mixture)) - Initalize_Atmos(0) + var/turf/open/newTurf = . + newTurf.Initalize_Atmos(0) // Take off the top layer turf and replace it with the next baseturf down /turf/proc/ScrapeAway(amount=1, flags) @@ -284,10 +285,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( //If you modify this function, ensure it works correctly with lateloaded map templates. /turf/proc/AfterChange(flags) //called after a turf has been replaced in ChangeTurf() levelupdate() - if(flags & CHANGETURF_RECALC_ADJACENT) - ImmediateCalculateAdjacentTurfs() - else - CALCULATE_ADJACENT_TURFS(src) + ImmediateCalculateAdjacentTurfs() //update firedoor adjacency var/list/turfs_to_check = get_adjacent_open_turfs(src) | src diff --git a/code/game/turfs/closed.dm b/code/game/turfs/closed.dm index a3ec6c6276..ef3c6a91d9 100644 --- a/code/game/turfs/closed.dm +++ b/code/game/turfs/closed.dm @@ -6,6 +6,7 @@ blocks_air = 1 rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE rad_insulation = RAD_MEDIUM_INSULATION + pass_flags_self = PASSCLOSEDTURF wave_explosion_block = 10 wave_explosion_multiply = 0.75 /// How much we block yelling @@ -13,7 +14,7 @@ /// how much of inbound yelling to dampen var/yelling_dampen = 0.5 -/turf/closed/Initialize() +/turf/closed/Initialize(mapload) . = ..() /turf/closed/AfterChange() @@ -23,11 +24,6 @@ /turf/closed/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) return FALSE -/turf/closed/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSCLOSEDTURF)) - return TRUE - return ..() - /turf/closed/indestructible name = "wall" icon = 'icons/turf/walls.dmi' @@ -70,22 +66,33 @@ icon_state = "wood" baseturfs = /turf/closed/indestructible/wood smooth = SMOOTH_TRUE + canSmoothWith = list(/obj/structure/falsewall/wood, /turf/closed/wall/mineral/wood, /turf/closed/indestructible/wood) /turf/closed/indestructible/oldshuttle/corner icon_state = "corner" /turf/closed/indestructible/splashscreen name = "Space Station 13" - icon = 'icons/blank_title.png' + desc = null + icon = 'icons/blanks/blank_title.png' icon_state = "" - layer = FLY_LAYER + plane = SPLASHSCREEN_PLANE bullet_bounce_sound = null -/turf/closed/indestructible/splashscreen/New() +INITIALIZE_IMMEDIATE(/turf/closed/indestructible/splashscreen) + +/turf/closed/indestructible/splashscreen/Initialize(mapload) + . = ..() SStitle.splash_turf = src if(SStitle.icon) icon = SStitle.icon - ..() + handle_generic_titlescreen_sizes() + +///helper proc that will center the screen if the icon is changed to a generic width, to make admins have to fudge around with pixel_x less. returns null +/turf/closed/indestructible/splashscreen/proc/handle_generic_titlescreen_sizes() + var/icon/size_check = icon(SStitle.icon, icon_state) + var/width = size_check.Width() + pixel_x = (672 - width) * 0.5 //The title screen is mapped with the expectation that it's 672x480. Should probably turn the title screen size into a define some time! /turf/closed/indestructible/splashscreen/vv_edit_var(var_name, var_value) . = ..() @@ -93,7 +100,13 @@ switch(var_name) if(NAMEOF(src, icon)) SStitle.icon = icon + handle_generic_titlescreen_sizes() +/turf/closed/indestructible/start_area + name = null + desc = null + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + /turf/closed/indestructible/riveted icon = 'icons/turf/walls/riveted.dmi' icon_state = "riveted" @@ -122,7 +135,7 @@ smooth = SMOOTH_TRUE icon = 'icons/obj/smooth_structures/reinforced_window.dmi' -/turf/closed/indestructible/fakeglass/Initialize() +/turf/closed/indestructible/fakeglass/Initialize(mapload) . = ..() icon_state = null //set the icon state to null, so our base state isn't visible underlays += mutable_appearance('icons/obj/structures.dmi', "grille") //add a grille underlay diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm index b526b5b886..0e32c170d7 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -55,7 +55,7 @@ . = ..() if(dropping == user && isliving(user)) var/mob/living/L = user - if(L.resting && do_after(L, max(10, L.getStaminaLoss()*0.5), 0, src)) + if(L.resting && do_after(L, max(10, L.getStaminaLoss()*0.5), src, IGNORE_HELD_ITEM)) if(Adjacent(L, src)) step(L, get_dir(L, src)) playsound(L, "rustle", 25, 1) @@ -124,7 +124,7 @@ heavyfootstep = FOOTSTEP_LAVA tiled_dirt = FALSE -/turf/open/indestructible/necropolis/Initialize() +/turf/open/indestructible/necropolis/Initialize(mapload) . = ..() if(prob(12)) icon_state = "necro[rand(2,3)]" @@ -218,13 +218,10 @@ flash_color(L, flash_color = "#C80000", flash_time = 10) /turf/open/Initalize_Atmos(times_fired) - if(!blocks_air) - if(!istype(air,/datum/gas_mixture/turf)) - air = new(2500,src) - air.copy_from_turf(src) - update_air_ref(planetary_atmos ? 1 : 2) - - update_visuals() + if(!istype(air,/datum/gas_mixture/turf)) + air = new(2500,src) + air.copy_from_turf(src) + update_air_ref(planetary_atmos ? 1 : 2) ImmediateCalculateAdjacentTurfs() diff --git a/code/game/turfs/open/floor/catwalk_plating.dm b/code/game/turfs/open/floor/catwalk_plating.dm new file mode 100644 index 0000000000..ac0f3b63de --- /dev/null +++ b/code/game/turfs/open/floor/catwalk_plating.dm @@ -0,0 +1,50 @@ +/** + * ## catwalk flooring + * + * They show what's underneath their catwalk flooring (pipes and the like) + * you can crowbar it to interact with the underneath stuff without destroying the tile... + * unless you want to! + */ +/turf/open/floor/catwalk_floor + icon = 'icons/turf/floors/catwalk_plating.dmi' + icon_state = "catwalk_below" + floor_tile = /obj/item/stack/tile/catwalk + name = "catwalk floor" + desc = "Flooring that shows its contents underneath. Engineers love it!" + baseturfs = /turf/open/floor/plating + footstep = FOOTSTEP_CATWALK + barefootstep = FOOTSTEP_CATWALK + clawfootstep = FOOTSTEP_CATWALK + heavyfootstep = FOOTSTEP_CATWALK + intact = FALSE + var/covered = TRUE + +/turf/open/floor/catwalk_floor/Initialize(mapload) + . = ..() + layer = CATWALK_LAYER + update_icon(UPDATE_OVERLAYS) + +/turf/open/floor/catwalk_floor/update_overlays() + . = ..() + var/static/image/catwalk_overlay + if(isnull(catwalk_overlay)) + catwalk_overlay = new() + catwalk_overlay.icon = icon + catwalk_overlay.icon_state = "catwalk_above" + catwalk_overlay.plane = GAME_PLANE + catwalk_overlay.layer = CATWALK_LAYER + catwalk_overlay = catwalk_overlay.appearance + if(covered) + . += catwalk_overlay + +/turf/open/floor/catwalk_floor/screwdriver_act(mob/living/user, obj/item/tool) + . = ..() + covered = !covered + user.balloon_alert(user, "[!covered ? "cover removed" : "cover added"]") + update_icon(UPDATE_OVERLAYS) + +/turf/open/floor/catwalk_floor/crowbar_act(mob/user, obj/item/I) + if(covered) + user.balloon_alert(user, "remove cover first!") + return FALSE + return pry_tile(I, user) diff --git a/code/game/turfs/openspace/transparent.dm b/code/game/turfs/openspace/transparent.dm index 570f153d41..b9ab562643 100644 --- a/code/game/turfs/openspace/transparent.dm +++ b/code/game/turfs/openspace/transparent.dm @@ -2,7 +2,7 @@ baseturfs = /turf/open/transparent/openspace intact = FALSE //this means wires go on top -/turf/open/transparent/Initialize() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker +/turf/open/transparent/Initialize(mapload) // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker . = ..() plane = OPENSPACE_PLANE layer = OPENSPACE_LAYER @@ -59,7 +59,7 @@ clawfootstep = FOOTSTEP_HARD_CLAW heavyfootstep = FOOTSTEP_GENERIC_HEAVY -/turf/open/transparent/glass/Initialize() +/turf/open/transparent/glass/Initialize(mapload) icon_state = "" //Prevent the normal icon from appearing behind the smooth overlays ..() return INITIALIZE_HINT_LATELOAD diff --git a/code/game/turfs/simulated/chasm.dm b/code/game/turfs/simulated/chasm.dm index 9490d728fe..58c69d2299 100644 --- a/code/game/turfs/simulated/chasm.dm +++ b/code/game/turfs/simulated/chasm.dm @@ -11,7 +11,7 @@ bullet_bounce_sound = null //abandon all hope ye who enter dirt_buildup_allowed = FALSE -/turf/open/chasm/Initialize() +/turf/open/chasm/Initialize(mapload) . = ..() AddComponent(/datum/component/chasm, SSmapping.get_turf_below(src)) @@ -77,9 +77,6 @@ else to_chat(user, "The plating is going to need some support! Place metal rods first.") -/turf/open/chasm/CanPass(atom/movable/mover, turf/target) - return 1 - // Chasms for Lavaland, with planetary atmos and lava glow /turf/open/chasm/lavaland initial_gas_mix = LAVALAND_DEFAULT_ATMOS @@ -121,7 +118,7 @@ light_range = 1.9 light_power = 0.65 -/turf/open/chasm/magic/Initialize() +/turf/open/chasm/magic/Initialize(mapload) . = ..() var/turf/T = safepick(get_area_turfs(/area/fabric_of_reality)) if(T) diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index 4b03b2b8e6..da1cf68d40 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -11,6 +11,7 @@ barefootstep = FOOTSTEP_HARD_BAREFOOT clawfootstep = FOOTSTEP_HARD_CLAW heavyfootstep = FOOTSTEP_GENERIC_HEAVY + flags_1 = NO_SCREENTIPS_1 /// Minimum explosion power to break tile var/explosion_power_break_tile = EXPLOSION_POWER_FLOOR_TILE_BREAK @@ -72,7 +73,7 @@ if(mapload && prob(66)) // 2/3 instead of 1/3 (default) MakeDirty() -/turf/open/floor/ex_act(severity, target) +/turf/open/floor/ex_act(severity, target, origin) var/shielded = is_shielded() ..() if(severity != 1 && shielded && target != src) @@ -162,8 +163,6 @@ return /turf/open/floor/update_icon() - . = ..() - update_visuals() /turf/open/floor/attack_paw(mob/user) return attack_hand(user) diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm index f707037771..a7d3cda389 100644 --- a/code/game/turfs/simulated/floor/fancy_floor.dm +++ b/code/game/turfs/simulated/floor/fancy_floor.dm @@ -108,7 +108,7 @@ var/turfverb = "uproot" tiled_dirt = FALSE -/turf/open/floor/grass/Initialize() +/turf/open/floor/grass/Initialize(mapload) . = ..() update_icon() @@ -203,7 +203,7 @@ initial_gas_mix = LAVALAND_DEFAULT_ATMOS slowdown = 0 -/turf/open/floor/grass/snow/basalt/Initialize() +/turf/open/floor/grass/snow/basalt/Initialize(mapload) . = ..() if(prob(15)) icon_state = "basalt[rand(0, 12)]" @@ -224,7 +224,7 @@ clawfootstep = FOOTSTEP_SAND heavyfootstep = FOOTSTEP_GENERIC_HEAVY -/turf/open/floor/grass/fakebasalt/Initialize() +/turf/open/floor/grass/fakebasalt/Initialize(mapload) . = ..() if(prob(15)) icon_state = "basalt[rand(0, 12)]" @@ -252,7 +252,7 @@ . = ..() . += "There's a small crack on the edge of it." -/turf/open/floor/carpet/Initialize() +/turf/open/floor/carpet/Initialize(mapload) . = ..() update_icon() @@ -413,7 +413,7 @@ plane = PLANE_SPACE tiled_dirt = FALSE -/turf/open/floor/fakespace/Initialize() +/turf/open/floor/fakespace/Initialize(mapload) . = ..() icon_state = SPACE_ICON_STATE diff --git a/code/game/turfs/simulated/floor/light_floor.dm b/code/game/turfs/simulated/floor/light_floor.dm index 4bca25f96c..55c1a45ff4 100644 --- a/code/game/turfs/simulated/floor/light_floor.dm +++ b/code/game/turfs/simulated/floor/light_floor.dm @@ -17,7 +17,7 @@ . = ..() . += "There's a small crack on the edge of it." -/turf/open/floor/light/Initialize() +/turf/open/floor/light/Initialize(mapload) . = ..() update_icon() diff --git a/code/game/turfs/simulated/floor/mineral_floor.dm b/code/game/turfs/simulated/floor/mineral_floor.dm index fe6ed2da9b..b7266bfb16 100644 --- a/code/game/turfs/simulated/floor/mineral_floor.dm +++ b/code/game/turfs/simulated/floor/mineral_floor.dm @@ -16,7 +16,7 @@ tiled_dirt = FALSE -/turf/open/floor/mineral/Initialize() +/turf/open/floor/mineral/Initialize(mapload) if(!broken_states) broken_states = list("[initial(icon_state)]_dam") . = ..() @@ -237,7 +237,7 @@ icons = list("alienpod1", "alienpod2", "alienpod3", "alienpod4", "alienpod5", "alienpod6", "alienpod7", "alienpod8", "alienpod9") baseturfs = /turf/open/floor/plating/abductor2 -/turf/open/floor/mineral/abductor/Initialize() +/turf/open/floor/mineral/abductor/Initialize(mapload) . = ..() icon_state = "alienpod[rand(1,9)]" diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index 82e60ed8f6..f041d657ec 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -18,7 +18,7 @@ floor_tile = /obj/item/stack/tile/circuit var/on = TRUE -/turf/open/floor/circuit/Initialize() +/turf/open/floor/circuit/Initialize(mapload) SSmapping.nuke_tiles += src update_icon() . = ..() @@ -151,7 +151,7 @@ /turf/open/floor/clockwork/Bless() //Who needs holy blessings when you have DADDY RATVAR? return -/turf/open/floor/clockwork/Initialize() +/turf/open/floor/clockwork/Initialize(mapload) . = ..() if(uses_overlay) new /obj/effect/temp_visual/ratvar/floor(src) @@ -263,7 +263,7 @@ /turf/open/floor/padded name = "padded floor" - desc = "Keeps crazy people from hurting themselves. It's soft, plush, and very nice to get shoved agaisnt." + desc = "Keeps crazy people from hurting themselves. It's soft, plush, and very nice to get shoved against." icon = 'icons/turf/floors.dmi' icon_state = "floor_padded" floor_tile = /obj/item/stack/tile/padded diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index 199e7767f1..1683163df0 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -29,7 +29,7 @@ else . += "You might be able to build ontop of it with some tiles..." -/turf/open/floor/plating/Initialize() +/turf/open/floor/plating/Initialize(mapload) if (!broken_states) broken_states = list("platingdmg1", "platingdmg2", "platingdmg3") if (!burnt_states) @@ -125,8 +125,12 @@ if(istype(W, /obj/item/stack/tile/material)) var/turf/newturf = PlaceOnTop(/turf/open/floor/material, flags = CHANGETURF_INHERIT_AIR) newturf.set_custom_materials(W.custom_materials) + if(length(C.atom_colours) && C.atom_colours[WASHABLE_COLOUR_PRIORITY] != null) + newturf.add_atom_colour(C.atom_colours[WASHABLE_COLOUR_PRIORITY], FIXED_COLOUR_PRIORITY) else if(W.turf_type) var/turf/open/floor/T = PlaceOnTop(W.turf_type, flags = CHANGETURF_INHERIT_AIR) + if(length(C.atom_colours) && C.atom_colours[WASHABLE_COLOUR_PRIORITY] != null) + T.add_atom_colour(C.atom_colours[WASHABLE_COLOUR_PRIORITY], FIXED_COLOUR_PRIORITY) if(istype(W, /obj/item/stack/tile/light)) //TODO: get rid of this ugly check somehow var/obj/item/stack/tile/light/L = W var/turf/open/floor/light/F = T @@ -195,7 +199,7 @@ return TRUE return FALSE -/turf/open/floor/plating/foam/ex_act() +/turf/open/floor/plating/foam/ex_act(severity, target, origin) ..() ScrapeAway(flags = CHANGETURF_INHERIT_AIR) diff --git a/code/game/turfs/simulated/floor/plating/asteroid.dm b/code/game/turfs/simulated/floor/plating/asteroid.dm index ab2effa1ab..32c1f0d42b 100644 --- a/code/game/turfs/simulated/floor/plating/asteroid.dm +++ b/code/game/turfs/simulated/floor/plating/asteroid.dm @@ -29,7 +29,7 @@ // /turf/open/floor/plating/asteroid/setup_broken_states() // return list("asteroid_dug") -/turf/open/floor/plating/asteroid/Initialize() +/turf/open/floor/plating/asteroid/Initialize(mapload) var/proper_name = name . = ..() name = proper_name @@ -89,7 +89,7 @@ for(var/obj/item/stack/ore/O in src) SEND_SIGNAL(W, COMSIG_PARENT_ATTACKBY, O) -/turf/open/floor/plating/asteroid/ex_act(severity, target) +/turf/open/floor/plating/asteroid/ex_act(severity, target, origin) . = SEND_SIGNAL(src, COMSIG_ATOM_EX_ACT, severity, target) contents_explosion(severity, target) @@ -116,7 +116,7 @@ baseturfs = /turf/open/floor/plating/asteroid/airless initial_gas_mix = AIRLESS_ATMOS -/turf/open/floor/plating/asteroid/basalt/Initialize() +/turf/open/floor/plating/asteroid/basalt/Initialize(mapload) . = ..() set_basalt_light(src) diff --git a/code/game/turfs/simulated/floor/plating/dirt.dm b/code/game/turfs/simulated/floor/plating/dirt.dm index b9bcc0937b..f7f4633254 100644 --- a/code/game/turfs/simulated/floor/plating/dirt.dm +++ b/code/game/turfs/simulated/floor/plating/dirt.dm @@ -19,3 +19,11 @@ /turf/open/floor/plating/dirt/try_replace_tile(obj/item/stack/tile/T, mob/user, params) return + +/turf/open/floor/plating/dirt/space + baseturfs = /turf/baseturf_bottom + planetary_atmos = FALSE + desc = "Upon closer examination there's plating beneath the dirt." + +/turf/open/floor/plating/dirt/space/airless + initial_gas_mix = AIRLESS_ATMOS diff --git a/code/game/turfs/simulated/floor/plating/misc_plating.dm b/code/game/turfs/simulated/floor/plating/misc_plating.dm index d834272bea..a4000ea486 100644 --- a/code/game/turfs/simulated/floor/plating/misc_plating.dm +++ b/code/game/turfs/simulated/floor/plating/misc_plating.dm @@ -12,7 +12,7 @@ icon_state = "alienpod1" tiled_dirt = FALSE -/turf/open/floor/plating/abductor/Initialize() +/turf/open/floor/plating/abductor/Initialize(mapload) . = ..() icon_state = "alienpod[rand(1,9)]" @@ -56,7 +56,7 @@ heavyfootstep = FOOTSTEP_GENERIC_HEAVY tiled_dirt = FALSE -/turf/open/floor/plating/ashplanet/Initialize() +/turf/open/floor/plating/ashplanet/Initialize(mapload) if(smooth) var/matrix/M = new M.Translate(-4, -4) @@ -101,7 +101,7 @@ clawfootstep = FOOTSTEP_HARD_CLAW heavyfootstep = FOOTSTEP_GENERIC_HEAVY -/turf/open/floor/plating/ashplanet/wateryrock/Initialize() +/turf/open/floor/plating/ashplanet/wateryrock/Initialize(mapload) icon_state = "[icon_state][rand(1, 9)]" . = ..() @@ -120,7 +120,7 @@ /turf/open/floor/plating/beach/try_replace_tile(obj/item/stack/tile/T, mob/user, params) return -/turf/open/floor/plating/beach/ex_act(severity, target) +/turf/open/floor/plating/beach/ex_act(severity, target, origin) contents_explosion(severity, target) /turf/open/floor/plating/beach/sand @@ -161,7 +161,7 @@ clawfootstep = FOOTSTEP_SAND heavyfootstep = FOOTSTEP_GENERIC_HEAVY -/turf/open/floor/plating/ironsand/Initialize() +/turf/open/floor/plating/ironsand/Initialize(mapload) . = ..() icon_state = "ironsand[rand(1,15)]" @@ -188,7 +188,7 @@ clawfootstep = FOOTSTEP_HARD_CLAW heavyfootstep = FOOTSTEP_GENERIC_HEAVY -/turf/open/floor/plating/ice/Initialize() +/turf/open/floor/plating/ice/Initialize(mapload) . = ..() MakeSlippery(TURF_WET_PERMAFROST, INFINITY, 0, INFINITY, TRUE) diff --git a/code/game/turfs/simulated/floor/reinf_floor.dm b/code/game/turfs/simulated/floor/reinf_floor.dm index 2d03624354..93ced4b3d5 100644 --- a/code/game/turfs/simulated/floor/reinf_floor.dm +++ b/code/game/turfs/simulated/floor/reinf_floor.dm @@ -53,7 +53,7 @@ acidpwr = min(acidpwr, 50) //we reduce the power so reinf floor never get melted. . = ..() -/turf/open/floor/engine/ex_act(severity,target) +/turf/open/floor/engine/ex_act(severity,target, origin) var/shielded = is_shielded() contents_explosion(severity, target) if(severity != 1 && shielded && target != src) @@ -133,7 +133,7 @@ var/obj/effect/clockwork/overlay/floor/bloodcult/realappearance -/turf/open/floor/engine/cult/Initialize() +/turf/open/floor/engine/cult/Initialize(mapload) . = ..() new /obj/effect/temp_visual/cult/turf/floor(src) realappearance = new /obj/effect/clockwork/overlay/floor/bloodcult(src) diff --git a/code/game/turfs/simulated/glass.dm b/code/game/turfs/simulated/glass.dm index f02ca19548..58acc696fa 100644 --- a/code/game/turfs/simulated/glass.dm +++ b/code/game/turfs/simulated/glass.dm @@ -17,7 +17,7 @@ // return list("glass-damaged1", "glass-damaged2", "glass-damaged3") -/turf/open/floor/glass/Initialize() +/turf/open/floor/glass/Initialize(mapload) icon_state = "" //Prevent the normal icon from appearing behind the smooth overlays ..() return INITIALIZE_HINT_LATELOAD diff --git a/code/game/turfs/simulated/lava.dm b/code/game/turfs/simulated/lava.dm index e7471478fb..943f60e752 100644 --- a/code/game/turfs/simulated/lava.dm +++ b/code/game/turfs/simulated/lava.dm @@ -17,9 +17,19 @@ barefootstep = FOOTSTEP_LAVA clawfootstep = FOOTSTEP_LAVA heavyfootstep = FOOTSTEP_LAVA + /// How much fire damage we deal to living mobs stepping on us + var/lava_damage = 20 + /// How many firestacks we add to living mobs stepping on us + var/lava_firestacks = 20 + /// How much temperature we expose objects with + var/temperature_damage = 10000 + /// mobs with this trait won't burn. + var/immunity_trait = TRAIT_LAVA_IMMUNE + /// objects with these flags won't burn. + var/immunity_resistance_flags = LAVA_PROOF -/turf/open/lava/ex_act(severity, target) - contents_explosion(severity, target) +/turf/open/lava/ex_act(severity, target, origin) + contents_explosion(severity, target, origin) /turf/open/lava/MakeSlippery(wet_setting, min_wet_time, wet_time_to_add, max_wet_time, permanent) return @@ -107,62 +117,98 @@ LAZYREMOVE(found_safeties, S) return LAZYLEN(found_safeties) +///Generic return value of the can_burn_stuff() proc. Does nothing. +#define LAVA_BE_IGNORING 0 +/// Another. Won't burn the target but will make the turf start processing. +#define LAVA_BE_PROCESSING 1 +/// Burns the target and makes the turf process (depending on the return value of do_burn()). +#define LAVA_BE_BURNING 2 -/turf/open/lava/proc/burn_stuff(AM) - . = 0 +///Proc that sets on fire something or everything on the turf that's not immune to lava. Returns TRUE to make the turf start processing. +/turf/open/lava/proc/burn_stuff(atom/movable/to_burn, delta_time = 1) if(is_safe()) return FALSE var/thing_to_check = src - if (AM) - thing_to_check = list(AM) - for(var/thing in thing_to_check) - if(isobj(thing)) - var/obj/O = thing - if((O.resistance_flags & (LAVA_PROOF|INDESTRUCTIBLE)) || O.throwing) + if (to_burn) + thing_to_check = list(to_burn) + for(var/atom/movable/burn_target as anything in thing_to_check) + switch(can_burn_stuff(burn_target)) + if(LAVA_BE_IGNORING) continue - . = 1 - if((O.resistance_flags & (ON_FIRE))) - continue - if(!(O.resistance_flags & FLAMMABLE)) - O.resistance_flags |= FLAMMABLE //Even fireproof things burn up in lava - if(O.resistance_flags & FIRE_PROOF) - O.resistance_flags &= ~FIRE_PROOF - if(O.armor.fire > 50) //obj with 100% fire armor still get slowly burned away. - O.armor = O.armor.setRating(fire = 50) - O.fire_act(10000, 1000) - - else if (isliving(thing)) - . = 1 - var/mob/living/L = thing - if(L.movement_type & FLYING) - continue //YOU'RE FLYING OVER IT - if("lava" in L.weather_immunities) - continue - var/buckle_check = L.buckling - if(!buckle_check) - buckle_check = L.buckled - if(isobj(buckle_check)) - var/obj/O = buckle_check - if(O.resistance_flags & LAVA_PROOF) + if(LAVA_BE_BURNING) + if(!do_burn(burn_target, delta_time)) continue - else if(isliving(buckle_check)) - var/mob/living/live = buckle_check - if("lava" in live.weather_immunities) - continue - if(iscarbon(L)) - var/mob/living/carbon/C = L - var/obj/item/clothing/S = C.get_item_by_slot(SLOT_WEAR_SUIT) - var/obj/item/clothing/H = C.get_item_by_slot(SLOT_HEAD) + . = TRUE - if(S && H && S.clothing_flags & LAVAPROTECT && H.clothing_flags & LAVAPROTECT) - return +/turf/open/lava/proc/can_burn_stuff(atom/movable/burn_target) + if(burn_target.movement_type & (FLYING|FLOATING)) //you're flying over it. + return isliving(burn_target) ? LAVA_BE_PROCESSING : LAVA_BE_IGNORING - L.adjustFireLoss(20) - if(L) //mobs turning into object corpses could get deleted here. - L.adjust_fire_stacks(20) - L.IgniteMob() + if(isobj(burn_target)) + if(burn_target.throwing) // to avoid gulag prisoners easily escaping, throwing only works for objects. + return LAVA_BE_IGNORING + var/obj/burn_obj = burn_target + if((burn_obj.resistance_flags & immunity_resistance_flags)) + return LAVA_BE_PROCESSING + return LAVA_BE_BURNING + + if (!isliving(burn_target)) + return LAVA_BE_IGNORING + + if(HAS_TRAIT(burn_target, immunity_trait)) + return LAVA_BE_PROCESSING + var/mob/living/burn_living = burn_target + var/atom/movable/burn_buckled = burn_living.buckled + if(burn_buckled) + if(burn_buckled.movement_type & (FLYING|FLOATING)) + return LAVA_BE_PROCESSING + if(isobj(burn_buckled)) + var/obj/burn_buckled_obj = burn_buckled + if(burn_buckled_obj.resistance_flags & immunity_resistance_flags) + return LAVA_BE_PROCESSING + else if(HAS_TRAIT(burn_buckled, immunity_trait)) + return LAVA_BE_PROCESSING + + if(iscarbon(burn_living)) + var/mob/living/carbon/burn_carbon = burn_living + var/obj/item/clothing/burn_suit = burn_carbon.get_item_by_slot(ITEM_SLOT_OCLOTHING) + var/obj/item/clothing/burn_helmet = burn_carbon.get_item_by_slot(ITEM_SLOT_HEAD) + if(burn_suit?.clothing_flags & LAVAPROTECT && burn_helmet?.clothing_flags & LAVAPROTECT) + return LAVA_BE_PROCESSING + + return LAVA_BE_BURNING + +#undef LAVA_BE_IGNORING +#undef LAVA_BE_PROCESSING +#undef LAVA_BE_BURNING + +/turf/open/lava/proc/do_burn(atom/movable/burn_target, delta_time = 1) + . = TRUE + if(isobj(burn_target)) + var/obj/burn_obj = burn_target + if(burn_obj.resistance_flags & ON_FIRE) // already on fire; skip it. + return + if(!(burn_obj.resistance_flags & FLAMMABLE)) + burn_obj.resistance_flags |= FLAMMABLE //Even fireproof things burn up in lava + if(burn_obj.resistance_flags & FIRE_PROOF) + burn_obj.resistance_flags &= ~FIRE_PROOF + if(burn_obj.armor.fire > 50) //obj with 100% fire armor still get slowly burned away. + burn_obj.armor = burn_obj.armor.setRating(fire = 50) + burn_obj.fire_act(temperature_damage, 1000 * delta_time) + if(istype(burn_obj, /obj/structure/closet)) + var/obj/structure/closet/burn_closet = burn_obj + for(var/burn_content in burn_closet.contents) + burn_stuff(burn_content) + + var/mob/living/burn_living = burn_target + burn_living.update_fire() + + burn_living.adjustFireLoss(lava_damage * delta_time) + if(!QDELETED(burn_living)) //mobs turning into object corpses could get deleted here. + burn_living.adjust_fire_stacks(lava_firestacks * delta_time) + burn_living.IgniteMob() /turf/open/lava/smooth name = "lava" diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm index 4a5b9f43de..1052e62e07 100644 --- a/code/game/turfs/simulated/minerals.dm +++ b/code/game/turfs/simulated/minerals.dm @@ -27,7 +27,7 @@ // If true you can mine the mineral turf with your hands var/weak_turf = FALSE -/turf/closed/mineral/Initialize() +/turf/closed/mineral/Initialize(mapload) if (!canSmoothWith) canSmoothWith = list(/turf/closed/mineral, /turf/closed/indestructible) . = ..() @@ -127,10 +127,9 @@ var/flags = NONE if(defer_change) // TODO: make the defer change var a var for any changeturf flag flags = CHANGETURF_DEFER_CHANGE - var/turf/open/mined = ScrapeAway(null, flags) + ScrapeAway(null, flags) addtimer(CALLBACK(src, .proc/AfterChange), 1, TIMER_UNIQUE) playsound(src, 'sound/effects/break_stone.ogg', 50, TRUE) //beautiful destruction - mined.update_visuals() /turf/closed/mineral/attack_animal(mob/living/simple_animal/user, list/modifiers) if((user.environment_smash & ENVIRONMENT_SMASH_WALLS) || (user.environment_smash & ENVIRONMENT_SMASH_RWALLS)) @@ -171,7 +170,7 @@ /turf/closed/mineral/acid_melt() ScrapeAway() -/turf/closed/mineral/ex_act(severity, target) +/turf/closed/mineral/ex_act(severity, target, origin) ..() switch(severity) if(3) @@ -191,7 +190,7 @@ //Currently, Adamantine won't spawn as it has no uses. -Durandan var/mineralChance = 13 -/turf/closed/mineral/random/Initialize() +/turf/closed/mineral/random/Initialize(mapload) mineralSpawnChanceList = typelist("mineralSpawnChanceList", mineralSpawnChanceList) @@ -512,7 +511,7 @@ var/activated_name = null var/mutable_appearance/activated_overlay -/turf/closed/mineral/gibtonite/Initialize() +/turf/closed/mineral/gibtonite/Initialize(mapload) det_time = rand(8,10) //So you don't know exactly when the hot potato will explode . = ..() @@ -661,7 +660,7 @@ /turf/closed/mineral/strong/acid_melt() return -/turf/closed/mineral/strong/ex_act(severity, target) +/turf/closed/mineral/strong/ex_act(severity, target, origin) return #undef MINING_MESSAGE_COOLDOWN diff --git a/code/game/turfs/simulated/openspace.dm b/code/game/turfs/simulated/openspace.dm index a856ed75b5..935bfdc1a7 100644 --- a/code/game/turfs/simulated/openspace.dm +++ b/code/game/turfs/simulated/openspace.dm @@ -36,7 +36,7 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr // /turf/open/transparent/openspace/show_bottom_level() // return FALSE -/turf/open/openspace/Initialize() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker +/turf/open/openspace/Initialize(mapload) // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker . = ..() vis_contents += GLOB.openspace_backdrop_one_for_all //Special grey square for projecting backdrop darkness filter on it. return INITIALIZE_HINT_LATELOAD @@ -165,7 +165,7 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr /// If true mineral turfs below this openspace turf will be mined automatically var/drill_below = TRUE -/turf/open/openspace/icemoon/Initialize() +/turf/open/openspace/icemoon/Initialize(mapload) . = ..() var/turf/T = below() if(T.flags_1 & NO_RUINS_1 && protect_ruin) diff --git a/code/game/turfs/simulated/wall/mineral_walls.dm b/code/game/turfs/simulated/wall/mineral_walls.dm index ed48c24462..f59b90a62a 100644 --- a/code/game/turfs/simulated/wall/mineral_walls.dm +++ b/code/game/turfs/simulated/wall/mineral_walls.dm @@ -272,12 +272,10 @@ icon_state = "map-overspace" fixed_underlay = list("space"=1) -/turf/closed/wall/mineral/plastitanium/explosive/ex_act(severity) +/turf/closed/wall/mineral/plastitanium/explosive/ex_act(severity, target, origin) var/datum/explosion/acted_explosion = null - for(var/datum/explosion/E in GLOB.explosions) - if(E.explosion_id == explosion_id) - acted_explosion = E - break + if(istype(origin, /datum/explosion)) + acted_explosion = origin if(acted_explosion && istype(acted_explosion.explosion_source, /obj/item/bombcore)) var/obj/item/bombcore/large/bombcore = new(get_turf(src)) bombcore.detonate() diff --git a/code/game/turfs/simulated/wall/misc_walls.dm b/code/game/turfs/simulated/wall/misc_walls.dm index e4d991a082..5686a2dc02 100644 --- a/code/game/turfs/simulated/wall/misc_walls.dm +++ b/code/game/turfs/simulated/wall/misc_walls.dm @@ -10,7 +10,7 @@ explosion_block = 10 girder_type = /obj/structure/girder/cult -/turf/closed/wall/mineral/cult/Initialize() +/turf/closed/wall/mineral/cult/Initialize(mapload) new /obj/effect/temp_visual/cult/turf(src) . = ..() @@ -60,7 +60,7 @@ var/heated var/obj/effect/clockwork/overlay/wall/realappearance -/turf/closed/wall/clockwork/Initialize() +/turf/closed/wall/clockwork/Initialize(mapload) . = ..() new /obj/effect/temp_visual/ratvar/wall(src) new /obj/effect/temp_visual/ratvar/beam(src) @@ -92,7 +92,7 @@ if(!istype(I, /obj/item/pickaxe/drill/jackhammer)) return FALSE to_chat(user, "You begin to smash though [src]...") - if(!do_after(user, 70, TRUE, src)) + if(!do_after(user, 7 SECONDS, src)) return FALSE I.play_tool_sound(src) visible_message("[user] smashes through [src] with [I]!", "You hear the grinding of metal.") @@ -145,10 +145,11 @@ user.adjustFireLoss(5) playsound(src, 'sound/machines/fryer/deep_fryer_emerge.ogg', 50, TRUE) -/turf/closed/wall/clockwork/mech_melee_attack(obj/mecha/M) +/turf/closed/wall/clockwork/mech_melee_attack(obj/vehicle/sealed/mecha/M) ..() if(heated) - to_chat(M.occupant, "The wall's intense heat completely reflects your [M.name]'s attack!") + for(var/mob/living/MB in M.occupants) + to_chat(MB, "The wall's intense heat completely reflects your [M.name]'s attack!") M.take_damage(20, BURN) /turf/closed/wall/clockwork/proc/turn_up_the_heat() diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 76dc6533b6..cac03b0637 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -80,7 +80,7 @@ if(girder_type) new /obj/item/stack/sheet/metal(src) -/turf/closed/wall/ex_act(severity, target) +/turf/closed/wall/ex_act(severity, target, origin) if(target == src) dismantle_wall(1,1) return @@ -88,7 +88,7 @@ if(1) //SN src = null var/turf/NT = ScrapeAway() - NT.contents_explosion(severity, target) + NT.contents_explosion(severity, target, origin) return if(2) if (prob(50)) @@ -115,23 +115,6 @@ else add_dent(WALL_DENT_HIT) -/turf/closed/wall/mech_melee_attack(obj/mecha/M) - M.do_attack_animation(src) - switch(M.damtype) - if(BRUTE) - playsound(src, 'sound/weapons/punch4.ogg', 50, 1) - visible_message("[M.name] has hit [src]!", null, null, COMBAT_MESSAGE_RANGE) - if(prob(hardness + M.force) && M.force > 20) - dismantle_wall(1) - playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) - else - add_dent(WALL_DENT_HIT) - if(BURN) - playsound(src, 'sound/items/welder.ogg', 100, 1) - if(TOX) - playsound(src, 'sound/effects/spray2.ogg', 100, 1) - return FALSE - /turf/closed/wall/attack_paw(mob/living/user) return attack_hand(user) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 3ed3891fdf..2df1606cb9 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -33,7 +33,7 @@ * * Doesn't call parent, see [/atom/proc/Initialize] */ -/turf/open/space/Initialize() +/turf/open/space/Initialize(mapload) SHOULD_CALL_PARENT(FALSE) icon_state = SPACE_ICON_STATE if(!space_gas) @@ -283,7 +283,7 @@ baseturfs = /turf/open/space/transparent/openspace intact = FALSE //this means wires go on top -/turf/open/space/transparent/Initialize() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker +/turf/open/space/transparent/Initialize(mapload) // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker ..() plane = OPENSPACE_PLANE layer = OPENSPACE_LAYER @@ -339,7 +339,7 @@ /turf/open/space/transparent/openspace/show_bottom_level() return FALSE -/turf/open/space/transparent/openspace/Initialize() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker +/turf/open/space/transparent/openspace/Initialize(mapload) // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker . = ..() icon_state = "transparent" diff --git a/code/game/turfs/space/transit.dm b/code/game/turfs/space/transit.dm index 08da6fa84f..ed3b20fce4 100644 --- a/code/game/turfs/space/transit.dm +++ b/code/game/turfs/space/transit.dm @@ -101,7 +101,7 @@ return SSshuttle.is_in_shuttle_bounds(src) -/turf/open/space/transit/Initialize() +/turf/open/space/transit/Initialize(mapload) . = ..() update_icon() for(var/atom/movable/AM in src) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index d949158850..826132e860 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -75,7 +75,7 @@ GLOBAL_LIST_EMPTY(station_turfs) add_overlay(/obj/effect/fullbright) if(requires_activation) - CALCULATE_ADJACENT_TURFS(src) + ImmediateCalculateAdjacentTurfs() if (light_power && light_range) update_light() @@ -111,7 +111,7 @@ GLOBAL_LIST_EMPTY(station_turfs) /turf/proc/set_temperature() /turf/proc/Initalize_Atmos(times_fired) - CALCULATE_ADJACENT_TURFS(src) + ImmediateCalculateAdjacentTurfs() /turf/Destroy(force) . = QDEL_HINT_IWILLGC @@ -137,6 +137,8 @@ GLOBAL_LIST_EMPTY(station_turfs) requires_activation = FALSE ..() + vis_contents.Cut() + /turf/on_attack_hand(mob/user) user.Move_Pulled(src) @@ -225,16 +227,6 @@ GLOBAL_LIST_EMPTY(station_turfs) return FALSE -/turf/CanPass(atom/movable/mover, turf/target) - if(!target) - return FALSE - - if(istype(mover)) // turf/Enter(...) will perform more advanced checks - return !density - - stack_trace("Non movable passed to turf CanPass : [mover]") - return FALSE - //There's a lot of QDELETED() calls here if someone can figure out how to optimize this but not runtime when something gets deleted by a Bump/CanPass/Cross call, lemme know or go ahead and fix this mess - kevinz000 /turf/Enter(atom/movable/mover, atom/oldloc) // Do not call ..() @@ -243,7 +235,7 @@ GLOBAL_LIST_EMPTY(station_turfs) // Here's hoping it doesn't stay like this for years before we finish conversion to step_ var/atom/firstbump var/canPassSelf = CanPass(mover, src) - if(canPassSelf || (mover.movement_type & UNSTOPPABLE)) + if(canPassSelf || (mover.movement_type & PHASING)) for(var/i in contents) if(QDELETED(mover)) return FALSE //We were deleted, do not attempt to proceed with movement. @@ -253,7 +245,7 @@ GLOBAL_LIST_EMPTY(station_turfs) if(!thing.Cross(mover)) if(QDELETED(mover)) //Mover deleted from Cross/CanPass, do not proceed. return FALSE - if((mover.movement_type & UNSTOPPABLE)) + if((mover.movement_type & PHASING)) mover.Bump(thing) continue else @@ -265,7 +257,7 @@ GLOBAL_LIST_EMPTY(station_turfs) firstbump = src if(firstbump) mover.Bump(firstbump) - return (mover.movement_type & UNSTOPPABLE) + return (mover.movement_type & PHASING) return TRUE /turf/Exit(atom/movable/mover, atom/newloc) @@ -279,7 +271,7 @@ GLOBAL_LIST_EMPTY(station_turfs) if(!thing.Uncross(mover, newloc)) if(thing.flags_1 & ON_BORDER_1) mover.Bump(thing) - if(!(mover.movement_type & UNSTOPPABLE)) + if(!(mover.movement_type & PHASING)) return FALSE if(QDELETED(mover)) return FALSE //We were deleted. @@ -379,8 +371,8 @@ GLOBAL_LIST_EMPTY(station_turfs) continue//Will not harm U. Since null != M, can be excluded to kill everyone. M.adjustBruteLoss(damage) M.Unconscious(damage * 4) - for(var/obj/mecha/M in src) - M.take_damage(damage*2, BRUTE, "melee", 1) + for(var/obj/vehicle/sealed/mecha/M in src) + M.take_damage(damage*2, BRUTE, MELEE, 1) /turf/proc/Bless() new /obj/effect/blessing(src) @@ -396,9 +388,9 @@ GLOBAL_LIST_EMPTY(station_turfs) var/list/things = src_object.contents() var/datum/progressbar/progress = new(user, things.len, src) - while (do_after(usr, 1 SECONDS, TRUE, src, FALSE, CALLBACK(src_object, /datum/component/storage.proc/mass_remove_from_storage, src, things, progress, TRUE, user))) + while (do_after(usr, 1 SECONDS, src, NONE, FALSE, CALLBACK(src_object, /datum/component/storage.proc/mass_remove_from_storage, src, things, progress, TRUE, user))) stoplag(1) - qdel(progress) + progress.end_progress() return TRUE @@ -451,7 +443,7 @@ GLOBAL_LIST_EMPTY(station_turfs) /turf/proc/is_shielded() -/turf/contents_explosion(severity, target) +/turf/contents_explosion(severity, target, origin) var/affecting_level if(severity == 1) affecting_level = 1 @@ -469,7 +461,7 @@ GLOBAL_LIST_EMPTY(station_turfs) var/atom/movable/AM = A if(!AM.ex_check(explosion_id)) continue - A.ex_act(severity, target) + A.ex_act(severity, target, origin) CHECK_TICK /turf/wave_ex_act(power, datum/wave_explosion/explosion, dir) @@ -512,7 +504,7 @@ GLOBAL_LIST_EMPTY(station_turfs) /turf/shove_act(mob/living/target, mob/living/user, pre_act = FALSE) var/list/possibilities for(var/obj/O in contents) - if(CHECK_BITFIELD(O.obj_flags, SHOVABLE_ONTO)) + if((O.obj_flags & SHOVABLE_ONTO)) LAZYADD(possibilities, O) else if(!O.CanPass(target, src)) return FALSE @@ -621,11 +613,6 @@ GLOBAL_LIST_EMPTY(station_turfs) /turf/proc/Melt() return ScrapeAway(flags = CHANGETURF_INHERIT_AIR) -/turf/bullet_act(obj/item/projectile/P) - . = ..() - if(. != BULLET_ACT_FORCE_PIERCE) - . = BULLET_ACT_TURF - /turf/proc/get_yelling_resistance(power) . = 0 // don't bother checking fulltile, we don't need accuracy @@ -638,3 +625,23 @@ GLOBAL_LIST_EMPTY(station_turfs) var/obj/machinery/door/D = locate() in src if(D?.density) . += D.opacity? 29 : 19 // glass doors are slightly more resistant to screaming + +/** + * Returns adjacent turfs to this turf that are reachable, in all cardinal directions + * + * Arguments: + * * caller: The movable, if one exists, being used for mobility checks to see what tiles it can reach + * * ID: An ID card that decides if we can gain access to doors that would otherwise block a turf + * * simulated_only: Do we only worry about turfs with simulated atmos, most notably things that aren't space? +*/ +/turf/proc/reachableAdjacentTurfs(caller, ID, simulated_only) + var/static/space_type_cache = typecacheof(/turf/open/space) + . = list() + + for(var/iter_dir in GLOB.cardinals) + var/turf/turf_to_check = get_step(src,iter_dir) + if(!turf_to_check || (simulated_only && space_type_cache[turf_to_check.type])) + continue + if(turf_to_check.density || LinkBlockedWithAccess(turf_to_check, caller, ID)) + continue + . += turf_to_check diff --git a/code/game/world.dm b/code/game/world.dm index f466913346..a9eda444f0 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -2,8 +2,6 @@ GLOBAL_VAR(restart_counter) -GLOBAL_VAR_INIT(tgs_initialized, FALSE) - GLOBAL_VAR(topic_status_lastcache) GLOBAL_LIST(topic_status_cache) @@ -16,7 +14,7 @@ GLOBAL_LIST(topic_status_cache) call(debug_server, "auxtools_init")() enable_debugging() AUXTOOLS_CHECK(AUXMOS) -#ifdef REFERENCE_TRACKING +#ifdef EXTOOLS_REFERENCE_TRACKING enable_reference_tracking() #endif world.Profile(PROFILE_START) @@ -76,7 +74,6 @@ GLOBAL_LIST(topic_status_cache) /world/proc/InitTgs() TgsNew(new /datum/tgs_event_handler/impl, TGS_SECURITY_TRUSTED) GLOB.revdata.load_tgs_info() - GLOB.tgs_initialized = TRUE /world/proc/HandleTestRun() //trigger things to run the whole process @@ -114,9 +111,13 @@ GLOBAL_LIST(topic_status_cache) GLOB.picture_log_directory = "data/picture_logs/[override_dir]" GLOB.world_game_log = "[GLOB.log_directory]/game.log" + GLOB.world_suspicious_login_log = "[GLOB.log_directory]/suspicious_logins.log" + GLOB.world_mecha_log = "[GLOB.log_directory]/mecha.log" GLOB.world_virus_log = "[GLOB.log_directory]/virus.log" GLOB.world_asset_log = "[GLOB.log_directory]/asset.log" GLOB.world_attack_log = "[GLOB.log_directory]/attack.log" + GLOB.world_victim_log = "[GLOB.log_directory]/victim.log" + GLOB.world_econ_log = "[GLOB.log_directory]/econ.log" GLOB.world_pda_log = "[GLOB.log_directory]/pda.log" GLOB.world_telecomms_log = "[GLOB.log_directory]/telecomms.log" GLOB.world_manifest_log = "[GLOB.log_directory]/manifest.log" @@ -155,7 +156,8 @@ GLOBAL_LIST(topic_status_cache) start_log(GLOB.world_crafting_log) start_log(GLOB.click_log) - GLOB.changelog_hash = md5('html/changelog.html') //for telling if the changelog has changed recently + var/latest_changelog = file("[global.config.directory]/../html/changelogs/archive/" + time2text(world.timeofday, "YYYY-MM") + ".yml") + GLOB.changelog_hash = fexists(latest_changelog) ? md5(latest_changelog) : 0 //for telling if the changelog has changed recently if(fexists(GLOB.config_error_log)) fcopy(GLOB.config_error_log, "[GLOB.log_directory]/config_error.log") fdel(GLOB.config_error_log) @@ -284,63 +286,47 @@ GLOBAL_LIST(topic_status_cache) ..() /world/proc/update_status() + . = "" + if(!config) + status = "SERVER LOADING OR BROKEN. (18+)" + return - var/list/features = list() + game_state = (CONFIG_GET(number/extreme_popcap) && GLOB.clients.len >= CONFIG_GET(number/extreme_popcap)) - // if(GLOB.master_mode) - // features += GLOB.master_mode + // ---Hub title--- + var/servername = CONFIG_GET(string/servername) + var/stationname = station_name() + var/defaultstation = CONFIG_GET(string/stationname) + if(servername || stationname != defaultstation) + . += (servername ? "[servername]" : "") + . += (stationname != defaultstation ? "[servername ? " - " : ""][stationname]\] " : "\] ") - // if (!GLOB.enter_allowed) - // features += "closed" + var/communityname = CONFIG_GET(string/communityshortname) + var/communitylink = CONFIG_GET(string/communitylink) + if(communityname) + . += (communitylink ? "([communityname]) " : "([communityname]) ") - var/s = "" - var/hostedby - if(config) - var/server_name = CONFIG_GET(string/servername) - if (server_name) - s += "[server_name] — " - // features += "[CONFIG_GET(flag/norespawn) ? "no " : ""]respawn" - // if(CONFIG_GET(flag/allow_vote_mode)) - // features += "vote" - // if(CONFIG_GET(flag/allow_ai)) - // features += "AI allowed" - hostedby = CONFIG_GET(string/hostedby) - - s += "[station_name()]"; - s += " (" - s += "" //Change this to wherever you want the hub to link to. - s += "Citadel" //Replace this with something else. Or ever better, delete it and uncomment the game version. - s += "" - s += ")\]" //CIT CHANGE - encloses the server title in brackets to make the hub entry fancier - s += "
    [CONFIG_GET(string/servertagline)]
    " //CIT CHANGE - adds a tagline! - - var/players = GLOB.clients.len - - if(SSmapping.config) // this just stops the runtime, honk. - features += "[SSmapping.config.map_name]" //CIT CHANGE - makes the hub entry display the current map - - if(NUM2SECLEVEL(GLOB.security_level))//CIT CHANGE - makes the hub entry show the security level - features += "[NUM2SECLEVEL(GLOB.security_level)] alert" - - var/popcaptext = "" var/popcap = max(CONFIG_GET(number/extreme_popcap), CONFIG_GET(number/hard_popcap), CONFIG_GET(number/soft_popcap)) - if (popcap) - popcaptext = "/[popcap]" + if(popcap) + . += "([GLOB.clients.len]/[popcap]) " - if (players > 1) - features += "[players][popcaptext] players" - else if (players > 0) - features += "[players][popcaptext] player" + . += "(18+)
    " //This is obligatory forr obvious reasons. - game_state = (CONFIG_GET(number/extreme_popcap) && players >= CONFIG_GET(number/extreme_popcap)) //tells the hub if we are full + // ---Hub body--- + var/tagline = (CONFIG_GET(flag/usetaglinestrings) ? pick(GLOB.server_taglines) : CONFIG_GET(string/servertagline)) + if(tagline) + . += "[tagline]
    " - if (!host && hostedby) - features += "hosted by [hostedby]" + // ---Hub footer--- + . += "\[" + if(SSmapping.config) + . += "[SSmapping.config.map_name], " + if(NUM2SECLEVEL(GLOB.security_level)) + . += "[NUM2SECLEVEL(GLOB.security_level)] alert, " + + . += "[get_active_player_count(afk_check = TRUE)] playing" - if (features) - s += "\[[jointext(features, ", ")]" - - status = s + status = . /world/proc/update_hub_visibility(new_visibility) if(new_visibility == GLOB.hub_visibility) diff --git a/code/modules/NTNet/relays.dm b/code/modules/NTNet/relays.dm index 8c33dd1eba..9a39b80356 100644 --- a/code/modules/NTNet/relays.dm +++ b/code/modules/NTNet/relays.dm @@ -92,7 +92,7 @@ update_icon() return TRUE -/obj/machinery/ntnet_relay/Initialize() +/obj/machinery/ntnet_relay/Initialize(mapload) uid = gl_uid++ component_parts = list() diff --git a/code/modules/VR/vr_sleeper.dm b/code/modules/VR/vr_sleeper.dm index cc59fe10ab..5b667c5fd5 100644 --- a/code/modules/VR/vr_sleeper.dm +++ b/code/modules/VR/vr_sleeper.dm @@ -16,7 +16,7 @@ var/allow_creating_vr_mobs = TRUE //So you can have vr_sleepers that always spawn you as a specific person or 1 life/chance vr games var/only_current_user_can_interact = FALSE -/obj/machinery/vr_sleeper/Initialize() +/obj/machinery/vr_sleeper/Initialize(mapload) . = ..() sparks = new /datum/effect_system/spark_spread() sparks.set_up(2,0) @@ -75,6 +75,9 @@ /obj/machinery/vr_sleeper/MouseDrop_T(mob/target, mob/user) if(user.lying || !iscarbon(target) || !Adjacent(target) || !user.canUseTopic(src, BE_CLOSE, TRUE, NO_TK)) return + if(occupant) + to_chat(user, "The VR Sleeper is already occupied!") + return close_machine(target) ui_interact(user) @@ -148,7 +151,7 @@ if(SOFT_CRIT) status = "Barely Conscious" data["vr_avatar"] += list("status" = status, "health" = vr_mob.health, "maxhealth" = vr_mob.maxHealth) - else + else data["can_delete_avatar"] = FALSE data["vr_avatar"] = FALSE data["isliving"] = FALSE @@ -204,7 +207,7 @@ var/vr_category = "default" //So we can have specific sleepers, eg: "Basketball VR Sleeper", etc. var/vr_outfit = /datum/outfit/vr -/obj/effect/landmark/vr_spawn/Initialize() +/obj/effect/landmark/vr_spawn/Initialize(mapload) . = ..() LAZYADD(GLOB.vr_spawnpoints[vr_category], src) @@ -232,7 +235,7 @@ var/area/vr_area var/list/corpse_party -/obj/effect/vr_clean_master/Initialize() +/obj/effect/vr_clean_master/Initialize(mapload) . = ..() vr_area = get_base_area(src) if(!vr_area) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index d4afc3dbb4..891f6250da 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -25,7 +25,9 @@ to_chat(usr, "You seem to be selecting a mob that doesn't exist anymore.", confidential = TRUE) return - var/body = "Options for [M.key]" +//ambition start + var/list/body = list("Options for [M.key]") +//ambition end body += "Options panel for [M]" if(M.client) body += " played by [M.client] " @@ -125,6 +127,10 @@ body += "Subtle message | " // body += "Play sound to | " body += "Language Menu" +//ambition start + if(M.mind) + body += " | Objective-Ambition Menu" +//ambition end if (M.client) if(!isnewplayer(M)) @@ -206,7 +212,11 @@ body += "
    " body += "" - usr << browse(body, "window=adminplayeropts-[REF(M)];size=550x515") +//ambition start + var/datum/browser/popup = new(usr, "adminplayeropts-[REF(M)]", "Player Panel", nwidth = 550, nheight = 515) + popup.set_content(body.Join()) + popup.open() +//ambition end SSblackbox.record_feedback("tally", "admin_verb", 1, "Player Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -435,18 +445,7 @@ for(var/datum/dynamic_ruleset/roundstart/rule in GLOB.dynamic_forced_roundstart_ruleset) dat += {"-> [rule.name] <-
    "} dat += "(Clear Rulesets)
    " - dat += "(Force Storyteller)
    " - if (GLOB.dynamic_forced_storyteller) - var/datum/dynamic_storyteller/S = GLOB.dynamic_forced_storyteller - dat += "-> [initial(S.name)] <-
    " dat += "(Dynamic mode options)
    " - else if (SSticker.IsRoundInProgress()) - dat += "(Force Next Latejoin Ruleset)
    " - if (SSticker && SSticker.mode && istype(SSticker.mode,/datum/game_mode/dynamic)) - var/datum/game_mode/dynamic/mode = SSticker.mode - if (mode.forced_latejoin_rule) - dat += {"-> [mode.forced_latejoin_rule.name] <-
    "} - dat += "(Execute Midround Ruleset!)
    " dat += "


    " if(SSticker.IsRoundInProgress()) dat += "(Game Mode Panel)
    " @@ -624,7 +623,7 @@ SSticker.start_immediately = FALSE SSticker.SetTimeLeft(1800) to_chat(world, "The game will start in 180 seconds.") - SEND_SOUND(world, sound(get_announcer_sound("attention"))) + SEND_SOUND(world, sound(SSstation.announcer.get_rand_alert_sound())) message_admins("[usr.key] has cancelled immediate game start. Game will start in 180 seconds.") log_admin("[usr.key] has cancelled immediate game start.") else @@ -707,24 +706,10 @@ log_admin("[key_name(usr)] delayed the round start.") else to_chat(world, "The game will start in [DisplayTimeText(newtime)].", confidential = TRUE) - SEND_SOUND(world, sound(get_announcer_sound("attention"))) + SEND_SOUND(world, sound(SSstation.announcer.get_rand_alert_sound())) log_admin("[key_name(usr)] set the pre-game delay to [DisplayTimeText(newtime)].") SSblackbox.record_feedback("tally", "admin_verb", 1, "Delay Game Start") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/toggledynamicvote() - set category = "Server" - set desc="Switches between secret/extended and dynamic voting" - set name="Toggle Dynamic Vote" - var/prev_dynamic_voting = CONFIG_GET(flag/dynamic_voting) - CONFIG_SET(flag/dynamic_voting,!prev_dynamic_voting) - if (!prev_dynamic_voting) - to_chat(world, "Vote is now between dynamic storytellers.") - else - to_chat(world, "Vote is now between extended and secret.") - log_admin("[key_name(usr)] [prev_dynamic_voting ? "disabled" : "enabled"] dynamic voting.") - message_admins("[key_name_admin(usr)] toggled dynamic voting.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Dynamic Voting", "[prev_dynamic_voting ? "Disabled" : "Enabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - /datum/admins/proc/unprison(mob/M in GLOB.mob_list) set category = "Admin" set name = "Unprison" @@ -941,27 +926,12 @@ No stacking: - Option is [GLOB.dynamic_no_stacking ? "ON" : "OFF"].
    Unless the threat goes above [GLOB.dynamic_stacking_limit], only one "round-ender" ruleset will be drafted.

    - Classic secret mode: - Option is [GLOB.dynamic_classic_secret ? "ON" : "OFF"]. -
    Only one roundstart ruleset will be drafted. Only traitors and minor roles will latespawn.
    -
    -
    Forced threat level: Current value : [GLOB.dynamic_forced_threat_level].
    The value threat is set to if it is higher than -1.

    - High population limit: Current value : [GLOB.dynamic_high_pop_limit]. -
    The threshold at which "high population override" will be in effect.

    Stacking threeshold: Current value : [GLOB.dynamic_stacking_limit].
    The threshold at which "round-ender" rulesets will stack. A value higher than 100 ensure this never happens.
    -

    Advanced parameters

    - Curve centre: -> [GLOB.dynamic_curve_centre] <-
    - Curve width: -> [GLOB.dynamic_curve_width] <-
    - Latejoin injection delay:
    - Minimum: -> [GLOB.dynamic_latejoin_delay_min / 60 / 10] <- Minutes
    - Maximum: -> [GLOB.dynamic_latejoin_delay_max / 60 / 10] <- Minutes
    - Midround injection delay:
    - Minimum: -> [GLOB.dynamic_midround_delay_min / 60 / 10] <- Minutes
    - Maximum: -> [GLOB.dynamic_midround_delay_max / 60 / 10] <- Minutes
    "} user << browse(dat, "window=dyn_mode_options;size=900x650") diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 22bbf03014..05c68bfdcf 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -10,7 +10,6 @@ GLOBAL_PROTECT(admin_verbs_default) /client/proc/hide_most_verbs, /*hides all our hideable adminverbs*/ /client/proc/debug_variables, /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/ /client/proc/dsay, /*talk in deadchat using our ckey/fakekey*/ - /client/proc/investigate_show, /*various admintools for investigation. Such as a singulo grief-log*/ /client/proc/secrets, /client/proc/toggle_hear_radio, /*allows admins to hide all radio output*/ /client/proc/reload_admins, @@ -70,11 +69,13 @@ GLOBAL_PROTECT(admin_verbs_admin) /client/proc/cmd_admin_man_up, //CIT CHANGE - adds man up verb /client/proc/cmd_admin_man_up_global, //CIT CHANGE - ditto /client/proc/cmd_admin_create_centcom_report, + /client/proc/cmd_admin_make_priority_announcement, //CIT CHANGE /client/proc/cmd_change_command_name, /client/proc/cmd_admin_check_player_exp, /* shows players by playtime */ /client/proc/toggle_combo_hud, // toggle display of the combination pizza antag and taco sci/med/eng hud /client/proc/toggle_AI_interact, /*toggle admin ability to interact with machines as an AI*/ /datum/admins/proc/open_shuttlepanel, /* Opens shuttle manipulator UI */ + /datum/admins/proc/station_traits_panel, /* Opens station traits UI */ /client/proc/deadchat, /client/proc/toggleprayers, // /client/proc/toggle_prayer_sound, @@ -86,7 +87,8 @@ GLOBAL_PROTECT(admin_verbs_admin) /client/proc/admin_cmd_remove_ghost_respawn_timer, //CIT /client/proc/addbunkerbypass, //CIT /client/proc/revokebunkerbypass, //CIT - /datum/admins/proc/open_borgopanel + /datum/admins/proc/open_borgopanel, + /datum/admins/proc/change_laws //change AI laws ) GLOBAL_LIST_INIT(admin_verbs_ban, list(/client/proc/unban_panel, /client/proc/DB_ban_panel, /client/proc/stickybanpanel)) GLOBAL_PROTECT(admin_verbs_ban) @@ -123,6 +125,10 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list( GLOBAL_PROTECT(admin_verbs_fun) GLOBAL_LIST_INIT(admin_verbs_spawn, list(/datum/admins/proc/spawn_atom, /datum/admins/proc/podspawn_atom, /datum/admins/proc/spawn_cargo, /datum/admins/proc/spawn_objasmob, /client/proc/respawn_character)) GLOBAL_PROTECT(admin_verbs_spawn) +GLOBAL_LIST_INIT(admin_verbs_sensitive, list( + /client/proc/investigate_show /*various admintools for investigation. Such as a singulo grief-log*/ +)) +GLOBAL_PROTECT(admin_verbs_sensitive) GLOBAL_LIST_INIT(admin_verbs_server, world.AVerbsServer()) GLOBAL_PROTECT(admin_verbs_server) /world/proc/AVerbsServer() @@ -135,7 +141,6 @@ GLOBAL_PROTECT(admin_verbs_server) /client/proc/everyone_random, /datum/admins/proc/toggleAI, /datum/admins/proc/toggleMulticam, //CIT - /datum/admins/proc/toggledynamicvote, //CIT /client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/ /client/proc/cmd_debug_del_all, /client/proc/toggle_random_events, @@ -190,12 +195,14 @@ GLOBAL_PROTECT(admin_verbs_debug) // /client/proc/validate_cards, // /client/proc/test_cardpack_distribution, // /client/proc/print_cards, - // #ifdef TESTING + #ifdef TESTING // /client/proc/check_missing_sprites, - // #endif + // /client/proc/export_dynamic_json, + /client/proc/run_dynamic_simulations, + #endif /datum/admins/proc/create_or_modify_area, /datum/admins/proc/fixcorruption, -#ifdef REFERENCE_TRACKING +#ifdef EXTOOLS_REFERENCE_TRACKING /datum/admins/proc/view_refs, /datum/admins/proc/view_del_failures, #endif @@ -314,6 +321,8 @@ GLOBAL_PROTECT(admin_verbs_hideable) add_verb(src, /client/proc/play_web_sound) if(rights & R_SPAWN) add_verb(src, GLOB.admin_verbs_spawn) + if(rights & R_SENSITIVE) + add_verb(src, GLOB.admin_verbs_sensitive) /client/proc/remove_admin_verbs() remove_verb(src, list( diff --git a/code/modules/admin/antag_panel.dm b/code/modules/admin/antag_panel.dm index 2d1aa63a91..180735d746 100644 --- a/code/modules/admin/antag_panel.dm +++ b/code/modules/admin/antag_panel.dm @@ -77,7 +77,7 @@ GLOBAL_VAR(antag_prototypes) return common_commands /datum/mind/proc/get_special_statuses() - var/list/result = list() + var/list/result = LAZYCOPY(special_statuses) if(!current) result += "No body!" if(current && HAS_TRAIT(current, TRAIT_MINDSHIELD)) diff --git a/code/modules/admin/callproc/callproc.dm b/code/modules/admin/callproc/callproc.dm index 21bf732493..a9c0984bbc 100644 --- a/code/modules/admin/callproc/callproc.dm +++ b/code/modules/admin/callproc/callproc.dm @@ -115,9 +115,9 @@ GLOBAL_PROTECT(LastAdminCalledProc) //adv proc call this, ya nerds /world/proc/WrapAdminProcCall(datum/target, procname, list/arguments) if(target == GLOBAL_PROC) - return call("/proc/[procname]")(arglist(arguments)) - else if(target != world) - return call(target, procname)(arglist(arguments)) + return text2path("/proc/[procname]")? call("/proc/[procname]")(arglist(arguments)) : null + else if(target != world && istype(target, /datum)) // isdatum check incase someone manages to call WrapAdminProcCall(global) which would otherwise crash the process entirely + return hascall(target, procname)? call(target, procname)(arglist(arguments)) : null else log_admin("[key_name(usr)] attempted to call world/proc/[procname] with arguments: [english_list(arguments)]") diff --git a/code/modules/admin/chat_commands.dm b/code/modules/admin/chat_commands.dm index bab74300f5..0964f7aad3 100644 --- a/code/modules/admin/chat_commands.dm +++ b/code/modules/admin/chat_commands.dm @@ -150,7 +150,7 @@ GLOBAL_LIST(round_end_notifiees) /datum/tgs_chat_command/wheelofsalt/Run(datum/tgs_chat_user/sender, params) var/saltresult = "The wheel of salt [pick("clatters","screams","vibrates","clanks","resonates","groans","moans","squeaks","emits a[pick(" god-forsaken"," lewd"," creepy"," generic","n orgasmic"," demonic")] [pick("airhorn","bike horn","trumpet","clown","latex","vore","dog","laughing")] noise")] as it spins violently... And it seems the salt of the day is the " - var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge","red panda","beret","male catgirl","powergame","hexacrocin removal","Discord server","Clitadel","Cargonia","Solarian Republic","Main and RP merger","bluespace","salt","chem dispenser theft","Botany","moth","BWOINK","anal vore","stamina","Mason Jakops","mining","noodle","milf","Lavaland","Necropolis","Ashwalker","Chase Redtail","Drew Mint","Pavel Marsk","Joker Amari","Durgit","chaplain","Antag","nanite","Syndicate","Nar-Sie","Ratvar","Cult","maint","Foam-Force","AI","cyborg","ghost","clockwork","cyberpunk","vaporwave","Clown","Leon Beech","Mime","security","research","Megafauna","Bubblegum","Ash Drake","Legion","Colossus","White Shuttle","Changeling","Cowboy","Space Ninja","Poly","Revolutionary","Skyrim","forbidden fruits","xenomorph","blob","Nuclear Operative","crossdressing")]" + var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge","red panda","beret","male catgirl","powergame","hexacrocin removal","Discord server","Clitadel","Cargonia","Solarian Republic","Main and RP merger","bluespace","salt","chem dispenser theft","Botany","moth","BWOINK","anal vore","stamina","Mason Jakops","mining","noodle","milf","Lavaland","Necropolis","Ashwalker","Chase Redtail","Drew Mint","Pavel Marsk","Joker Amari","Durgit","chaplain","Antag","nanite","Syndicate","Nar-Sie","Ratvar","Cult","maint","Foam-Force","AI","cyborg","ghost","clockwork","cyberpunk","vaporwave","Clown","Leon Beech","Mime","security","research","Megafauna","Bubblegum","Ash Drake","Legion","Colossus","White Shuttle","Changeling","Cowboy","Space Ninja","Polly","Revolutionary","Skyrim","forbidden fruits","xenomorph","blob","Nuclear Operative","crossdressing")]" var/saltsecondarysubject = "[pick("rework","changes","r34","ban","removal","addition","leak","proposal","fanart","introduction","tabling","ERP","bikeshedding","crossdressing","sprites","semen keg","argument","theft","nerf","screeching","salt","creampie","lewding","murder","kissing","marriage","replacement","fucking","ship","netflix adaptation","dance","remaster","system","voyeur","decoration","pre-order","bukkake","seduction","worship","gangbang","handholding")]" if(prob(10)) saltresult += "@here for your salt, all day every day" @@ -174,12 +174,12 @@ GLOBAL_LIST(round_end_notifiees) /datum/tgs_chat_command/despacito/Run() return "https://www.youtube.com/watch?v=kJQP7kiw5Fk" -/datum/tgs_chat_command/poly - name = "poly" - help_text = "The Lewder, more applicable Poly speak for Citadel Station 13." +/datum/tgs_chat_command/polly + name = "polly" + help_text = "The Lewder, more applicable Polly speak for Citadel Station 13." var/list/speech_buffer -/datum/tgs_chat_command/poly/Run() +/datum/tgs_chat_command/polly/Run() LAZYINITLIST(speech_buffer) //I figure this is just safe to do for everything at this point if(length(speech_buffer)) //Let's not look up the whole json EVERY TIME, just the first time. return "[pick(speech_buffer)]" diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm index 9a74b63040..19201299c2 100644 --- a/code/modules/admin/create_mob.dm +++ b/code/modules/admin/create_mob.dm @@ -50,6 +50,10 @@ H.dna.features["flavor_text"] = "" //Oh no. H.dna.features["body_model"] = H.gender + H.set_bark(pick(GLOB.bark_random_list)) + H.vocal_pitch = BARK_PITCH_RAND(H.gender) + H.vocal_pitch_range = BARK_VARIANCE_RAND + SEND_SIGNAL(H, COMSIG_HUMAN_ON_RANDOMIZE) H.update_body(TRUE) diff --git a/code/modules/admin/force_event.dm b/code/modules/admin/force_event.dm new file mode 100644 index 0000000000..4e4338d019 --- /dev/null +++ b/code/modules/admin/force_event.dm @@ -0,0 +1,97 @@ +///Allows an admin to force an event +/client/proc/forceEvent() + set name = "Trigger Event" + set category = "Admin.Events" + + if(!holder || !check_rights(R_FUN)) + return + + holder.forceEvent() + +///Opens up the Force Event Panel +/datum/admins/proc/forceEvent() + if(!check_rights(R_FUN)) + return + + var/datum/force_event/ui = new(usr) + ui.ui_interact(usr) + +/// Force Event Panel +/datum/force_event + +/datum/force_event/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ForceEvent") + ui.open() + +/datum/force_event/ui_state(mob/user) + return GLOB.fun_state + +/datum/force_event/ui_static_data(mob/user) + var/static/list/category_to_icons + if(!category_to_icons) + category_to_icons = list( + EVENT_CATEGORY_AI = "robot", + EVENT_CATEGORY_ANOMALIES = "cloud-bolt", + EVENT_CATEGORY_BUREAUCRATIC = "print", + EVENT_CATEGORY_ENGINEERING = "wrench", + EVENT_CATEGORY_ENTITIES = "ghost", + EVENT_CATEGORY_FRIENDLY = "face-smile", + EVENT_CATEGORY_HEALTH = "brain", + EVENT_CATEGORY_HOLIDAY = "calendar", + EVENT_CATEGORY_INVASION = "user-group", + EVENT_CATEGORY_JANITORIAL = "bath", + EVENT_CATEGORY_SPACE = "meteor", + EVENT_CATEGORY_WIZARD = "hat-wizard", + ) + var/list/data = list() + + var/list/categories_seen = list() + var/list/categories = list() + + var/list/events = list() + + for(var/datum/round_event_control/event_control as anything in SSevents.control) + //add category + if(!categories_seen[event_control.category]) + categories_seen[event_control.category] = TRUE + UNTYPED_LIST_ADD(categories, list( + "name" = event_control.category, + "icon" = category_to_icons[event_control.category], + )) + //add event, with one value matching up the category + UNTYPED_LIST_ADD(events, list( + "name" = event_control.name, + "description" = event_control.description, + "type" = event_control.type, + "category" = event_control.category, + )) + data["categories"] = categories + data["events"] = events + return data + +/datum/force_event/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + if(..()) + return + if(!check_rights(R_FUN)) + return + switch(action) + if("forceevent") + var/announce_event = params["announce"] + var/string_path = params["type"] + if(!string_path) + return + var/event_to_run_type = text2path(string_path) + if(!event_to_run_type) + return + var/datum/round_event_control/event = locate(event_to_run_type) in SSevents.control + if(!event) + return + if(event.admin_setup(usr) == ADMIN_CANCEL_EVENT) + return + var/always_announce_chance = 100 + var/no_announce_chance = 0 + event.runEvent(announce_chance_override = announce_event ? always_announce_chance : no_announce_chance, admin_forced = TRUE) + message_admins("[key_name_admin(usr)] has triggered an event. ([event.name])") + log_admin("[key_name(usr)] has triggered an event. ([event.name])") diff --git a/code/modules/admin/fun_balloon.dm b/code/modules/admin/fun_balloon.dm index 417663fcb7..bfbb5e7dbb 100644 --- a/code/modules/admin/fun_balloon.dm +++ b/code/modules/admin/fun_balloon.dm @@ -6,7 +6,7 @@ anchored = TRUE var/popped = FALSE -/obj/effect/fun_balloon/Initialize() +/obj/effect/fun_balloon/Initialize(mapload) . = ..() SSobj.processing |= src @@ -109,7 +109,7 @@ timeleft = 0 var/list/warp_points -/obj/effect/forcefield/arena_shuttle/Initialize() +/obj/effect/forcefield/arena_shuttle/Initialize(mapload) . = ..() for(var/obj/effect/landmark/shuttle_arena_safe/exit in GLOB.landmarks_list) warp_points += exit diff --git a/code/modules/admin/outfit_editor.dm b/code/modules/admin/outfit_editor.dm index 9a99d8b20e..aa53aade13 100644 --- a/code/modules/admin/outfit_editor.dm +++ b/code/modules/admin/outfit_editor.dm @@ -55,7 +55,7 @@ "name" = initial(item.name), "desc" = initial(item.desc), // at this point initializing the item is probably faster tbh - "sprite" = icon2base64(icon(initial(item.icon), initial(item.icon_state))), + "sprite" = icon2base64(icon(initial(item.icon), initial(item.icon_state), SOUTH, 1)), ) return data diff --git a/code/modules/admin/playtimes.dm b/code/modules/admin/playtimes.dm new file mode 100644 index 0000000000..7cf24d9746 --- /dev/null +++ b/code/modules/admin/playtimes.dm @@ -0,0 +1,68 @@ +/datum/player_playtime/New(mob/viewer) + ui_interact(viewer) + +/datum/player_playtime/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PlayerPlaytimes", "Player Playtimes") + ui.open() + +/datum/player_playtime/ui_state(mob/user) + return GLOB.admin_state + +/datum/player_playtime/ui_data(mob/user) + var/list/data = list() + + var/list/clients = list() + for(var/client/C in GLOB.clients) + var/list/client = list() + + client["ckey"] = C.ckey + client["playtime"] = C.get_exp_living(TRUE) + client["playtime_hours"] = C.get_exp_living() + + var/mob/M = C.mob + client["observer"] = isobserver(M) + client["ingame"] = !isnewplayer(M) + client["name"] = M.real_name + var/nnpa = CONFIG_GET(number/notify_new_player_age) + if(nnpa >= 0) + if(C.account_age >= 0 && (C.account_age < CONFIG_GET(number/notify_new_player_age))) + client["new_account"] = "New BYOND account [C.account_age] day[(C.account_age==1?"":"s")] old, created on [C.account_join_date]" + + clients += list(client) + + clients = sortList(clients, /proc/cmp_playtime) + data["clients"] = clients + return data + +/datum/player_playtime/ui_act(action, params) + if(..()) + return + + switch(action) + if("view_playtime") + var/mob/target = get_mob_by_ckey(params["ckey"]) + usr.client.holder.cmd_show_exp_panel(target.client) + if("admin_pm") + usr.client.cmd_admin_pm(params["ckey"]) + if("player_panel") + var/mob/target = get_mob_by_ckey(params["ckey"]) + usr.client.holder.show_player_panel(target) + if("view_variables") + var/mob/target = get_mob_by_ckey(params["ckey"]) + usr.client.debug_variables(target) + if("observe") + if(!isobserver(usr) && !check_rights(R_ADMIN)) + return + + var/mob/target = get_mob_by_key(params["ckey"]) + if(!target) + to_chat(usr, "Player not found.") + return + + var/client/C = usr.client + if(!isobserver(usr) && !C.admin_ghost()) + return + var/mob/dead/observer/A = C.mob + A.ManualFollow(target) diff --git a/code/modules/admin/sql_message_system.dm b/code/modules/admin/sql_message_system.dm index 3ba309bc24..72b63da2ef 100644 --- a/code/modules/admin/sql_message_system.dm +++ b/code/modules/admin/sql_message_system.dm @@ -369,6 +369,8 @@ qdel(query_find_message_secret) /proc/browse_messages(type, target_ckey, index, linkless = FALSE, filter, agegate = FALSE) + if((!usr || (target_ckey != usr.ckey)) && !check_rights(R_SENSITIVE)) + return if(!SSdbcore.Connect()) to_chat(usr, "Failed to establish database connection.", confidential = TRUE) return diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 953835bff0..cc143dcad0 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -53,15 +53,6 @@ return cmd_show_exp_panel(M.client) - else if(href_list["toggleexempt"]) - if(!check_rights(R_ADMIN)) - return - var/client/C = locate(href_list["toggleexempt"]) in GLOB.clients - if(!C) - to_chat(usr, "ERROR: Client not found.") - return - toggle_exempt_status(C) - else if(href_list["makeAntag"]) if(!check_rights(R_ADMIN)) return @@ -167,27 +158,6 @@ message_admins("[key_name_admin(usr)] tried to create a revenant. Unfortunately, there were no candidates available.") log_admin("[key_name(usr)] failed to create a revenant.") - else if(href_list["forceevent"]) - if(!check_rights(R_FUN)) - return - var/datum/round_event_control/E = locate(href_list["forceevent"]) in SSevents.control - if(E) - E.admin_setup(usr) - var/datum/round_event/event = E.runEvent() - if(event.announceWhen>0) - event.processing = FALSE - var/prompt = alert(usr, "Would you like to alert the crew?", "Alert", "Yes", "No", "Cancel") - switch(prompt) - if("Cancel") - event.kill() - return - if("No") - event.announceWhen = -1 - event.processing = TRUE - message_admins("[key_name_admin(usr)] has triggered an event. ([E.name])") - log_admin("[key_name(usr)] has triggered an event. ([E.name])") - return - else if(href_list["dbsearchckey"] || href_list["dbsearchadmin"] || href_list["dbsearchip"] || href_list["dbsearchcid"]) var/adminckey = href_list["dbsearchadmin"] var/playerckey = href_list["dbsearchckey"] @@ -498,8 +468,8 @@ M.change_mob_type( /mob/living/simple_animal/crab/Coffee , null, null, delmob ) if("parrot") M.change_mob_type( /mob/living/simple_animal/parrot , null, null, delmob ) - if("polyparrot") - M.change_mob_type( /mob/living/simple_animal/parrot/Poly , null, null, delmob ) + if("pollyparrot") + M.change_mob_type( /mob/living/simple_animal/parrot/Polly , null, null, delmob ) if("constructarmored") M.change_mob_type( /mob/living/simple_animal/hostile/construct/armored , null, null, delmob ) if("constructbuilder") @@ -920,10 +890,10 @@ else dat += "Alien" //Gang - if(jobban_isbanned(M, ROLE_GANG) || isbanned_dept) - dat += "Gang" + if(jobban_isbanned(M, ROLE_FAMILIES) || isbanned_dept) + dat += "Families" else - dat += "Gang" + dat += "Families" //Bloodsucker if(jobban_isbanned(M, ROLE_BLOODSUCKER) || isbanned_dept) dat += "Bloodsucker" @@ -1008,7 +978,7 @@ if("ghostroles") joblist += list(ROLE_PAI, ROLE_POSIBRAIN, ROLE_DRONE , ROLE_DEATHSQUAD, ROLE_LAVALAND, ROLE_SENTIENCE) if("teamantags") - joblist += list(ROLE_OPERATIVE, ROLE_REV, ROLE_CULTIST, ROLE_SERVANT_OF_RATVAR, ROLE_ABDUCTOR, ROLE_ALIEN, ROLE_GANG) + joblist += list(ROLE_OPERATIVE, ROLE_REV, ROLE_CULTIST, ROLE_SERVANT_OF_RATVAR, ROLE_ABDUCTOR, ROLE_ALIEN, ROLE_FAMILIES) if("convertantags") joblist += list(ROLE_REV, ROLE_CULTIST, ROLE_SERVANT_OF_RATVAR, ROLE_ALIEN) if("otherroles") @@ -1375,15 +1345,13 @@ else if(href_list["f_dynamic_roundstart"]) if(!check_rights(R_ADMIN)) return - if(SSticker && SSticker.mode) - return alert(usr, "The game has already started.", null, null, null, null) - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode.", null, null, null, null) + if(SSticker?.mode) + return tgui_alert(usr, "The game has already started.") var/roundstart_rules = list() for (var/rule in subtypesof(/datum/dynamic_ruleset/roundstart)) var/datum/dynamic_ruleset/roundstart/newrule = new rule() roundstart_rules[newrule.name] = newrule - var/added_rule = input(usr,"What ruleset do you want to force? This will bypass threat level and population restrictions.", "Rigging Roundstart", null) as null|anything in roundstart_rules + var/added_rule = input(usr,"What ruleset do you want to force? This will bypass threat level and population restrictions.", "Rigging Roundstart", null) as null|anything in sortList(roundstart_rules) if (added_rule) GLOB.dynamic_forced_roundstart_ruleset += roundstart_rules[added_rule] log_admin("[key_name(usr)] set [added_rule] to be a forced roundstart ruleset.") @@ -1407,201 +1375,18 @@ log_admin("[key_name(usr)] removed [rule] from the forced roundstart rulesets.") message_admins("[key_name(usr)] removed [rule] from the forced roundstart rulesets.", 1) - else if(href_list["f_dynamic_storyteller"]) - if(!check_rights(R_ADMIN)) - return - if(SSticker && SSticker.mode) - return alert(usr, "The game has already started.", null, null, null, null) - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode.", null, null, null, null) - var/list/choices = list() - for(var/T in config.storyteller_cache) - var/datum/dynamic_storyteller/S = T - choices[initial(S.name)] = T - var/choice = choices[input("Select storyteller:", "Storyteller", "Classic") as null|anything in choices] - if(choice) - GLOB.dynamic_forced_storyteller = choice - log_admin("[key_name(usr)] forced the storyteller to [GLOB.dynamic_forced_storyteller].") - message_admins("[key_name(usr)] forced the storyteller to [GLOB.dynamic_forced_storyteller].") - Game() - - else if(href_list["f_dynamic_storyteller_clear"]) - if(!check_rights(R_ADMIN)) - return - GLOB.dynamic_forced_storyteller = null - Game() - log_admin("[key_name(usr)] cleared the forced storyteller. The mode will pick one as normal.") - message_admins("[key_name(usr)] cleared the forced storyteller. The mode will pick one as normal.", 1) - - else if(href_list["f_dynamic_latejoin"]) - if(!check_rights(R_ADMIN)) - return - if(!SSticker || !SSticker.mode) - return alert(usr, "The game must start first.", null, null, null, null) - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) - var/latejoin_rules = list() - for (var/rule in subtypesof(/datum/dynamic_ruleset/latejoin)) - var/datum/dynamic_ruleset/latejoin/newrule = new rule() - latejoin_rules[newrule.name] = newrule - var/added_rule = input(usr,"What ruleset do you want to force upon the next latejoiner? This will bypass threat level and population restrictions.", "Rigging Latejoin", null) as null|anything in latejoin_rules - if (added_rule) - var/datum/game_mode/dynamic/mode = SSticker.mode - mode.forced_latejoin_rule = latejoin_rules[added_rule] - log_admin("[key_name(usr)] set [added_rule] to proc on the next latejoin.") - message_admins("[key_name(usr)] set [added_rule] to proc on the next latejoin.", 1) - Game() - - else if(href_list["f_dynamic_latejoin_clear"]) - if(!check_rights(R_ADMIN)) - return - if (SSticker && SSticker.mode && istype(SSticker.mode,/datum/game_mode/dynamic)) - var/datum/game_mode/dynamic/mode = SSticker.mode - mode.forced_latejoin_rule = null - Game() - log_admin("[key_name(usr)] cleared the forced latejoin ruleset.") - message_admins("[key_name(usr)] cleared the forced latejoin ruleset.", 1) - - else if(href_list["f_dynamic_midround"]) - if(!check_rights(R_ADMIN)) - return - if(!SSticker || !SSticker.mode) - return alert(usr, "The game must start first.", null, null, null, null) - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) - var/midround_rules = list() - for (var/rule in subtypesof(/datum/dynamic_ruleset/midround)) - var/datum/dynamic_ruleset/midround/newrule = new rule() - midround_rules[newrule.name] = rule - var/added_rule = input(usr,"What ruleset do you want to force right now? This will bypass threat level and population restrictions.", "Execute Ruleset", null) as null|anything in midround_rules - if (added_rule) - var/datum/game_mode/dynamic/mode = SSticker.mode - log_admin("[key_name(usr)] executed the [added_rule] ruleset.") - message_admins("[key_name(usr)] executed the [added_rule] ruleset.", 1) - mode.picking_specific_rule(midround_rules[added_rule],1) - else if (href_list["f_dynamic_options"]) if(!check_rights(R_ADMIN)) return - if(SSticker && SSticker.mode) - return alert(usr, "The game has already started.", null, null, null, null) - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) + if(SSticker?.mode) + return tgui_alert(usr, "The game has already started.") dynamic_mode_options(usr) - - else if(href_list["f_dynamic_roundstart_centre"]) - if(!check_rights(R_ADMIN)) - return - if(SSticker && SSticker.mode) - return alert(usr, "The game has already started.", null, null, null, null) - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) - - var/new_centre = input(usr,"Change the centre of the dynamic mode threat curve. A negative value will give a more peaceful round ; a positive value, a round with higher threat. Any number is allowed. This is adjusted by dynamic voting.", "Change curve centre", null) as num - - log_admin("[key_name(usr)] changed the distribution curve center to [new_centre].") - message_admins("[key_name(usr)] changed the distribution curve center to [new_centre]", 1) - GLOB.dynamic_curve_centre = new_centre - dynamic_mode_options(usr) - - else if(href_list["f_dynamic_roundstart_width"]) - if(!check_rights(R_ADMIN)) - return - if(SSticker && SSticker.mode) - return alert(usr, "The game has already started.", null, null, null, null) - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) - - var/new_width = input(usr,"Change the width of the dynamic mode threat curve. A higher value will favour extreme rounds ; a lower value, a round closer to the average. Any Number between 0.5 and 4 are allowed.", "Change curve width", null) as num - if (new_width < 0.5 || new_width > 4) - return alert(usr, "Only values between 0.5 and +2.5 are allowed.", null, null, null, null) - - log_admin("[key_name(usr)] changed the distribution curve width to [new_width].") - message_admins("[key_name(usr)] changed the distribution curve width to [new_width]", 1) - GLOB.dynamic_curve_width = new_width - dynamic_mode_options(usr) - - else if(href_list["f_dynamic_roundstart_latejoin_min"]) - if(!check_rights(R_ADMIN)) - return - if(SSticker && SSticker.mode) - return alert(usr, "The game has already started.", null, null, null, null) - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) - var/new_min = input(usr,"Change the minimum delay of latejoin injection in minutes.", "Change latejoin injection delay minimum", null) as num - if(new_min <= 0) - return alert(usr, "The minimum can't be zero or lower.", null, null, null, null) - if((new_min MINUTES) > GLOB.dynamic_latejoin_delay_max) - return alert(usr, "The minimum must be lower than the maximum.", null, null, null, null) - - log_admin("[key_name(usr)] changed the latejoin injection minimum delay to [new_min] minutes.") - message_admins("[key_name(usr)] changed the latejoin injection minimum delay to [new_min] minutes", 1) - GLOB.dynamic_latejoin_delay_min = (new_min MINUTES) - dynamic_mode_options(usr) - - else if(href_list["f_dynamic_roundstart_latejoin_max"]) - if(!check_rights(R_ADMIN)) - return - if(SSticker && SSticker.mode) - return alert(usr, "The game has already started.", null, null, null, null) - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) - var/new_max = input(usr,"Change the maximum delay of latejoin injection in minutes.", "Change latejoin injection delay maximum", null) as num - if(new_max <= 0) - return alert(usr, "The maximum can't be zero or lower.", null, null, null, null) - if((new_max MINUTES) < GLOB.dynamic_latejoin_delay_min) - return alert(usr, "The maximum must be higher than the minimum.", null, null, null, null) - - log_admin("[key_name(usr)] changed the latejoin injection maximum delay to [new_max] minutes.") - message_admins("[key_name(usr)] changed the latejoin injection maximum delay to [new_max] minutes", 1) - GLOB.dynamic_latejoin_delay_max = (new_max MINUTES) - dynamic_mode_options(usr) - - else if(href_list["f_dynamic_roundstart_midround_min"]) - if(!check_rights(R_ADMIN)) - return - if(SSticker && SSticker.mode) - return alert(usr, "The game has already started.", null, null, null, null) - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) - var/new_min = input(usr,"Change the minimum delay of midround injection in minutes.", "Change midround injection delay minimum", null) as num - if(new_min <= 0) - return alert(usr, "The minimum can't be zero or lower.", null, null, null, null) - if((new_min MINUTES) > GLOB.dynamic_midround_delay_max) - return alert(usr, "The minimum must be lower than the maximum.", null, null, null, null) - - log_admin("[key_name(usr)] changed the midround injection minimum delay to [new_min] minutes.") - message_admins("[key_name(usr)] changed the midround injection minimum delay to [new_min] minutes", 1) - GLOB.dynamic_midround_delay_min = (new_min MINUTES) - dynamic_mode_options(usr) - - else if(href_list["f_dynamic_roundstart_midround_max"]) - if(!check_rights(R_ADMIN)) - return - if(SSticker && SSticker.mode) - return alert(usr, "The game has already started.", null, null, null, null) - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) - var/new_max = input(usr,"Change the maximum delay of midround injection in minutes.", "Change midround injection delay maximum", null) as num - if(new_max <= 0) - return alert(usr, "The maximum can't be zero or lower.", null, null, null, null) - if((new_max MINUTES) > GLOB.dynamic_midround_delay_max) - return alert(usr, "The maximum must be higher than the minimum.", null, null, null, null) - - log_admin("[key_name(usr)] changed the midround injection maximum delay to [new_max] minutes.") - message_admins("[key_name(usr)] changed the midround injection maximum delay to [new_max] minutes", 1) - GLOB.dynamic_midround_delay_max = (new_max MINUTES) - dynamic_mode_options(usr) - else if(href_list["f_dynamic_force_extended"]) if(!check_rights(R_ADMIN)) return - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) - GLOB.dynamic_forced_extended = !GLOB.dynamic_forced_extended log_admin("[key_name(usr)] set 'forced_extended' to [GLOB.dynamic_forced_extended].") message_admins("[key_name(usr)] set 'forced_extended' to [GLOB.dynamic_forced_extended].") @@ -1611,70 +1396,29 @@ if(!check_rights(R_ADMIN)) return - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) - GLOB.dynamic_no_stacking = !GLOB.dynamic_no_stacking log_admin("[key_name(usr)] set 'no_stacking' to [GLOB.dynamic_no_stacking].") message_admins("[key_name(usr)] set 'no_stacking' to [GLOB.dynamic_no_stacking].") dynamic_mode_options(usr) - - else if(href_list["f_dynamic_classic_secret"]) - if(!check_rights(R_ADMIN)) - return - - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) - - GLOB.dynamic_classic_secret = !GLOB.dynamic_classic_secret - log_admin("[key_name(usr)] set 'classic_secret' to [GLOB.dynamic_classic_secret].") - message_admins("[key_name(usr)] set 'classic_secret' to [GLOB.dynamic_classic_secret].") - dynamic_mode_options(usr) - else if(href_list["f_dynamic_stacking_limit"]) if(!check_rights(R_ADMIN)) return - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) - GLOB.dynamic_stacking_limit = input(usr,"Change the threat limit at which round-endings rulesets will start to stack.", "Change stacking limit", null) as num log_admin("[key_name(usr)] set 'stacking_limit' to [GLOB.dynamic_stacking_limit].") message_admins("[key_name(usr)] set 'stacking_limit' to [GLOB.dynamic_stacking_limit].") dynamic_mode_options(usr) - else if(href_list["f_dynamic_high_pop_limit"]) - if(!check_rights(R_ADMIN)) - return - - if(SSticker && SSticker.mode) - return alert(usr, "The game has already started.", null, null, null, null) - - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) - - var/new_value = input(usr, "Enter the high-pop override threshold for dynamic mode.", "High pop override") as num - if (new_value < 0) - return alert(usr, "Only positive values allowed!", null, null, null, null) - GLOB.dynamic_high_pop_limit = new_value - - log_admin("[key_name(usr)] set 'high_pop_limit' to [GLOB.dynamic_high_pop_limit].") - message_admins("[key_name(usr)] set 'high_pop_limit' to [GLOB.dynamic_high_pop_limit].") - dynamic_mode_options(usr) - else if(href_list["f_dynamic_forced_threat"]) if(!check_rights(R_ADMIN)) return - if(SSticker && SSticker.mode) - return alert(usr, "The game has already started.", null, null, null, null) - - if(GLOB.master_mode != "dynamic") - return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) + if(SSticker?.mode) + return tgui_alert(usr, "The game has already started.") var/new_value = input(usr, "Enter the forced threat level for dynamic mode.", "Forced threat level") as num if (new_value > 100) - return alert(usr, "The value must be be under 100.", null, null, null, null) + return tgui_alert(usr, "The value must be be under 100.") GLOB.dynamic_forced_threat_level = new_value log_admin("[key_name(usr)] set 'forced_threat_level' to [GLOB.dynamic_forced_threat_level].") @@ -1921,8 +1665,8 @@ if(ishuman(L)) var/mob/living/carbon/human/observer = L - observer.equip_to_slot_or_del(new /obj/item/clothing/under/suit/black(observer), SLOT_W_UNIFORM) - observer.equip_to_slot_or_del(new /obj/item/clothing/shoes/sneakers/black(observer), SLOT_SHOES) + observer.equip_to_slot_or_del(new /obj/item/clothing/under/suit/black(observer), ITEM_SLOT_ICLOTHING) + observer.equip_to_slot_or_del(new /obj/item/clothing/shoes/sneakers/black(observer), ITEM_SLOT_FEET) L.Unconscious(100) sleep(5) L.forceMove(pick(GLOB.tdomeobserve)) @@ -2257,6 +2001,18 @@ var/mob/M = locate(href_list["HeadsetMessage"]) usr.client.admin_headset_message(M) +//ambition start + else if(href_list["ObjectiveRequest"]) + if(!check_rights(R_ADMIN)) + return + var/datum/mind/requesting_mind = locate(href_list["ObjectiveRequest"]) + if(!istype(requesting_mind) || QDELETED(requesting_mind)) + to_chat(usr, "This mind reference is no longer valid. It has probably since been destroyed.") + return + requesting_mind.do_edit_objectives_ambitions() + return +//ambition end + else if(href_list["reject_custom_name"]) if(!check_rights(R_ADMIN)) @@ -2264,6 +2020,12 @@ var/obj/item/station_charter/charter = locate(href_list["reject_custom_name"]) if(istype(charter)) charter.reject_proposed(usr) + else if(href_list["approve_custom_name"]) + if(!check_rights(R_ADMIN)) + return + var/obj/item/station_charter/charter = locate(href_list["approve_custom_name"]) + if(istype(charter)) + charter.allow_pass(usr) else if(href_list["jumpto"]) if(!isobserver(usr) && !check_rights(R_ADMIN)) return @@ -2862,7 +2624,7 @@ return if(!CONFIG_GET(string/centcom_ban_db)) - to_chat(usr, "Centcom Galactic Ban DB is disabled!") + to_chat(usr, span_warning("Centcom Galactic Ban DB is disabled!")) return var/ckey = href_list["centcomlookup"] @@ -2889,8 +2651,19 @@ dat += "
    0 bans detected for [ckey]
    " else bans = json_decode(response["body"]) - dat += "
    [bans.len] ban\s detected for [ckey]
    " + + //Ignore bans from non-whitelisted sources, if a whitelist exists + var/list/valid_sources + if(CONFIG_GET(string/centcom_source_whitelist)) + valid_sources = splittext(CONFIG_GET(string/centcom_source_whitelist), ",") + dat += "
    Bans detected for [ckey]
    " + else + //Ban count is potentially inaccurate if they're using a whitelist + dat += "
    [bans.len] ban\s detected for [ckey]
    " + for(var/list/ban in bans) + if(valid_sources && !(ban["sourceName"] in valid_sources)) + continue dat += "Server: [sanitize(ban["sourceName"])]
    " dat += "RP Level: [sanitize(ban["sourceRoleplayLevel"])]
    " dat += "Type: [sanitize(ban["type"])]
    " @@ -2984,10 +2757,17 @@ if(query_get_mentor.NextRow()) to_chat(usr, "[ckey] is already a mentor.") return - var/datum/db_query/query_add_mentor = SSdbcore.NewQuery("INSERT INTO `[format_table_name("mentor")]` (`id`, `ckey`) VALUES (null, '[ckey]')") + var/datum/db_query/query_add_mentor = SSdbcore.NewQuery( + "INSERT INTO [format_table_name("mentor")] (id, ckey) VALUES (:id, :ckey)", + list("id" = null, "ckey" = ckey) + ) if(!query_add_mentor.warn_execute()) return - var/datum/db_query/query_add_admin_log = SSdbcore.NewQuery("INSERT INTO `[format_table_name("admin_log")]` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new mentor [ckey]');") + var/datum/db_query/query_add_admin_log = SSdbcore.NewQuery({" + INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log) + VALUES (:time, :round_id, :adminckey, INET_ATON(:adminip), 'add mentor', :mentor_ckey, CONCAT('Admin removed: ', :mentor_ckey)) + "}, list("time" = SQLtime(), "round_id" = "[GLOB.round_id]", "adminckey" = usr.ckey, "adminip" = usr.client.address, "mentor_ckey" = ckey) + ) if(!query_add_admin_log.warn_execute()) return else diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index f2c10ecc1c..d6628b808b 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -200,6 +200,9 @@ message_admins("ERROR: Non-admin [key_name(usr)] attempted to execute a SDQL query!") log_admin("Non-admin [key_name(usr)] attempted to execute a SDQL query!") return FALSE + var/prompt = tgui_alert(usr, "Run SDQL2 Query?", "SDQL2", list("Yes", "Cancel")) + if (prompt != "Yes") + return var/list/results = world.SDQL2_query(query_text, key_name_admin(usr), "[key_name(usr)]") if(length(results) == 3) for(var/I in 1 to 3) @@ -242,7 +245,7 @@ var/selectors_used = FALSE var/list/combined_refs = list() do - CHECK_TICK + stoplag(2) finished = TRUE for(var/i in running) var/datum/SDQL2_query/query = i @@ -262,7 +265,7 @@ selectors_used |= query.where_switched combined_refs |= query.select_refs running -= query - if(!CHECK_BITFIELD(query.options, SDQL2_OPTION_DO_NOT_AUTOGC)) + if(!(query.options & SDQL2_OPTION_DO_NOT_AUTOGC)) QDEL_IN(query, 50) else if(usr) @@ -442,19 +445,19 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null if("select") switch(value) if("force_nulls") - DISABLE_BITFIELD(options, SDQL2_OPTION_SELECT_OUTPUT_SKIP_NULLS) + options &= ~(SDQL2_OPTION_SELECT_OUTPUT_SKIP_NULLS) if("proccall") switch(value) if("blocking") - ENABLE_BITFIELD(options, SDQL2_OPTION_BLOCKING_CALLS) + options |= SDQL2_OPTION_BLOCKING_CALLS if("priority") switch(value) if("high") - ENABLE_BITFIELD(options, SDQL2_OPTION_HIGH_PRIORITY) + options |= SDQL2_OPTION_HIGH_PRIORITY if("autogc") switch(value) if("keep_alive") - ENABLE_BITFIELD(options, SDQL2_OPTION_DO_NOT_AUTOGC) + options |= SDQL2_OPTION_DO_NOT_AUTOGC /datum/SDQL2_query/proc/ARun() INVOKE_ASYNC(src, .proc/Run) diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm index ca07f9a50b..79fd63adcc 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm @@ -3,11 +3,19 @@ /proc/_abs(A) return abs(A) -/proc/_animate(atom/A, set_vars, time = 10, loop = 1, easing = LINEAR_EASING, flags = null) - var/mutable_appearance/MA = new() - for(var/v in set_vars) - MA.vars[v] = set_vars[v] - animate(A, appearance = MA, time, loop, easing, flags) +/proc/_animate(atom/A, list/data, time = 10, loop = 1, easing = LINEAR_EASING, flags = null) + if(!istype(A)) + return + animate(A, appearance = data, time = time, loop = loop, easing = easing, flags = flags) + +/proc/_animate_adv(atom/A, list/data, loop = 1, easing = LINEAR_EASING, flags = NONE) + if(!A || !islist(data) || data.len < 1) + return + animate(A, appearance = (data[1] - "time"), time = data[1]["time"], loop = loop, easing = easing, flags = flags) + if(data.len < 2) + return + for(var/i in 2 to data.len) + animate(appearance = (data[i] - "time"), time = data[i]["time"]) /proc/_acrccos(A) return arccos(A) diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 5c35450592..f721bcc5fc 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -161,13 +161,14 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) var/client/initiator //semi-misnomer, it's the person who ahelped/was bwoinked var/initiator_ckey var/initiator_key_name - var/heard_by_no_admins = FALSE var/list/_interactions //use AddInteraction() or, preferably, admin_ticket_log() var/obj/effect/statclick/ahelp/statclick var/static/ticket_counter = 0 + /// did we send "answered" to irc yet + var/answered = FALSE //call this on its own to create a ticket, don't manually assign current_ticket //msg is the title of the ticket: usually the ahelp text @@ -209,7 +210,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) log_admin_private("Ticket #[id]: [key_name(initiator)]: [name] - heard by [admin_number_present] non-AFK admins who have +BAN.") if(admin_number_present <= 0) to_chat(C, "No active admins are online, your adminhelp was sent to the admin irc.") - heard_by_no_admins = TRUE + else + // citadel edit: send anyways + send2adminchat(initiator_ckey, "Ticket #[id]: [name] - Heard by [admin_number_present] admins present with +BAN.") GLOB.ahelp_tickets.active_tickets += src @@ -220,8 +223,8 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) return ..() /datum/admin_help/proc/AddInteraction(formatted_message) - if(heard_by_no_admins && usr && usr.ckey != initiator_ckey) - heard_by_no_admins = FALSE + if(usr && (usr.ckey != initiator_ckey) && !answered) + answered = TRUE send2adminchat(initiator_ckey, "Ticket #[id]: Answered by [key_name(usr)]") _interactions += "[TIME_STAMP("hh:mm:ss", FALSE)]: [formatted_message]" @@ -728,3 +731,34 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) return founds return msg + +/** + * Checks a given message to see if any of the words contain an active admin's ckey with an @ before it + * + * Returns nothing if no pings are found, otherwise returns an associative list with ckey -> client + * Also modifies msg to underline the pings, then stores them in the key [ADMINSAY_PING_UNDERLINE_NAME_INDEX] for returning + * + * Arguments: + * * msg - the message being scanned + */ +/proc/check_admin_pings(msg) + //explode the input msg into a list + var/list/msglist = splittext(msg, " ") + var/list/admins_to_ping = list() + + var/i = 0 + for(var/word in msglist) + i++ + if(!length(word)) + continue + if(word[1] != "@") + continue + var/ckey_check = lowertext(copytext(word, 2)) + var/client/client_check = GLOB.directory[ckey_check] + if(client_check?.holder) + msglist[i] = "[word]" + admins_to_ping[ckey_check] = client_check + + if(length(admins_to_ping)) + admins_to_ping[ADMINSAY_PING_UNDERLINE_NAME_INDEX] = jointext(msglist, " ") // without tuples, we must make do! + return admins_to_ping diff --git a/code/modules/admin/verbs/adminsay.dm b/code/modules/admin/verbs/adminsay.dm index 66653020d4..fdd1e8dcad 100644 --- a/code/modules/admin/verbs/adminsay.dm +++ b/code/modules/admin/verbs/adminsay.dm @@ -8,6 +8,19 @@ msg = copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN) if(!msg) return + + var/list/pinged_admin_clients = check_admin_pings(msg) + if(length(pinged_admin_clients) && pinged_admin_clients[ADMINSAY_PING_UNDERLINE_NAME_INDEX]) + msg = pinged_admin_clients[ADMINSAY_PING_UNDERLINE_NAME_INDEX] + pinged_admin_clients -= ADMINSAY_PING_UNDERLINE_NAME_INDEX + + for(var/iter_ckey in pinged_admin_clients) + var/client/iter_admin_client = pinged_admin_clients[iter_ckey] + if(!iter_admin_client?.holder) + continue + window_flash(iter_admin_client) + SEND_SOUND(iter_admin_client.mob, sound('sound/misc/bloop.ogg')) + msg = emoji_parse(msg) mob.log_talk(msg, LOG_ASAY) diff --git a/code/modules/admin/verbs/borgpanel.dm b/code/modules/admin/verbs/borgpanel.dm index 4b60ecc0ff..ec03afff36 100644 --- a/code/modules/admin/verbs/borgpanel.dm +++ b/code/modules/admin/verbs/borgpanel.dm @@ -214,3 +214,25 @@ borg.lawsync() . = TRUE + +/datum/admins/proc/change_laws() + set category = "Admin.Player Interaction" + set name = "Change Silicon Laws" + set desc = "Change Silicon Laws" + + if(!check_rights(R_ADMIN)) + return + var/chosensilicon = input("Select a Silicon", "Select a Silicon", null, null) as null|anything in GLOB.silicon_mobs + if (!istype(chosensilicon, /mob/living/silicon)) + to_chat(usr, "Silicon is required for law changes", confidential=TRUE) + return + var/chosen = pick_closest_path(null, make_types_fancy(typesof(/obj/item/aiModule))) + if (!chosen) + return + var/new_board = new chosen(src) + var/obj/item/aiModule/chosenboard = new_board + var/mob/living/silicon/beepboop = chosensilicon + chosenboard.install(beepboop.laws, usr) + message_admins("[key_name_admin(usr)] added [chosenboard] to [ADMIN_LOOKUPFLW(beepboop)].") + log_admin("[key_name(usr)] added [chosenboard] to [key_name(beepboop)].") + qdel(new_board) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 138913b3a4..7957a6d638 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -202,7 +202,7 @@ id.forceMove(W) W.update_icon() else - H.equip_to_slot(id,SLOT_WEAR_ID) + H.equip_to_slot(id,ITEM_SLOT_ID) else alert("Invalid mob") diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 2379ee22bc..6c43d61cce 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -266,8 +266,8 @@ return TRUE /datum/admins/proc/makeSpaceNinja() - new /datum/round_event/ghost_role/ninja() - return 1 + new /datum/round_event/ghost_role/space_ninja() + return TRUE // DEATH SQUADS /datum/admins/proc/makeDeathsquad() diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm index ee4d12656a..d10ec67d13 100644 --- a/code/modules/admin/verbs/possess.dm +++ b/code/modules/admin/verbs/possess.dm @@ -3,7 +3,7 @@ set category = "Object" if((O.obj_flags & DANGEROUS_POSSESSION) && CONFIG_GET(flag/forbid_singulo_possession)) - to_chat(usr, "[O] is too powerful for you to possess.") + to_chat(usr, "[O] is too powerful for you to possess.", confidential = TRUE) return var/turf/T = get_turf(O) @@ -18,19 +18,22 @@ if(!usr.control_object) //If you're not already possessing something... usr.name_archive = usr.real_name - usr.loc = O + usr.forceMove(O) usr.real_name = O.name usr.name = O.name usr.reset_perspective(O) usr.control_object = O + O.AddElement(/datum/element/weather_listener, /datum/weather/ash_storm, ZTRAIT_ASHSTORM, GLOB.ash_storm_sounds) SSblackbox.record_feedback("tally", "admin_verb", 1, "Possess Object") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /proc/release() set name = "Release Obj" set category = "Object" - //usr.loc = get_turf(usr) - if(usr.control_object && usr.name_archive) //if you have a name archived and if you are actually relassing an object + if(!usr.control_object) //lest we are banished to the nullspace realm. + return + + if(usr.name_archive) //if you have a name archived usr.real_name = usr.name_archive usr.name_archive = "" usr.name = usr.real_name @@ -38,8 +41,8 @@ var/mob/living/carbon/human/H = usr H.name = H.get_visible_name() - - usr.loc = get_turf(usr.control_object) + usr.control_object.RemoveElement(/datum/element/weather_listener, /datum/weather/ash_storm, ZTRAIT_ASHSTORM, GLOB.ash_storm_sounds) + usr.forceMove(get_turf(usr.control_object)) usr.reset_perspective() usr.control_object = null SSblackbox.record_feedback("tally", "admin_verb", 1, "Release Object") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 72ec804d28..596d235b0a 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -491,7 +491,7 @@ Traitors and the like can also be revived with the previous role mostly intact. GLOB.data_core.manifest_inject(new_character) if(alert(new_character,"Would you like an active AI to announce this character?",,"No","Yes")=="Yes") - AnnounceArrival(new_character, new_character.mind.assigned_role) + announce_arrival(new_character, new_character.mind.assigned_role) var/msg = "[admin] has respawned [player_key] as [new_character.real_name]." message_admins(msg) @@ -517,10 +517,10 @@ Traitors and the like can also be revived with the previous role mostly intact. message_admins("Admin [key_name_admin(usr)] has added a new AI law - [input]") var/show_log = alert(src, "Show ion message?", "Message", "Yes", "No") - var/announce_ion_laws = (show_log == "Yes" ? 1 : -1) + var/announce_ion_laws = (show_log == "Yes" ? 100 : 0) var/datum/round_event/ion_storm/add_law_only/ion = new() - ion.announceEvent = announce_ion_laws + ion.announce_chance = announce_ion_laws ion.ionMessage = input SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Custom AI Law") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -560,7 +560,7 @@ Traitors and the like can also be revived with the previous role mostly intact. var/announce_command_report = TRUE switch(confirm) if("Yes") - priority_announce(input, null, "commandreport") + priority_announce(input, null, SSstation.announcer.get_rand_report_sound()) announce_command_report = FALSE if("Cancel") return @@ -1557,6 +1557,7 @@ Traitors and the like can also be revived with the previous role mostly intact. /client/proc/cmd_admin_check_player_exp() //Allows admins to determine who the newer players are. set category = "Admin" set name = "Player Playtime" + if(!check_rights(R_ADMIN)) return @@ -1564,12 +1565,7 @@ Traitors and the like can also be revived with the previous role mostly intact. to_chat(usr, "Tracking is disabled in the server configuration file.") return - var/list/msg = list() - msg += "Playtime ReportPlaytime:
    " - src << browse(msg.Join(), "window=Player_playtime_check") + new /datum/player_playtime(usr) /obj/effect/temp_visual/fireball icon = 'icons/obj/wizard.dmi' @@ -1581,7 +1577,7 @@ Traitors and the like can also be revived with the previous role mostly intact. duration = 9 pixel_z = 270 -/obj/effect/temp_visual/fireball/Initialize() +/obj/effect/temp_visual/fireball/Initialize(mapload) . = ..() animate(src, pixel_z = 0, time = duration) @@ -1592,7 +1588,7 @@ Traitors and the like can also be revived with the previous role mostly intact. light_range = 2 duration = 9 -/obj/effect/temp_visual/target/ex_act() +/obj/effect/temp_visual/target/ex_act(severity, target, origin) return /obj/effect/temp_visual/target/Initialize(mapload, list/flame_hit) diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm index 80344d076c..e3c084b161 100644 --- a/code/modules/admin/verbs/secrets.dm +++ b/code/modules/admin/verbs/secrets.dm @@ -352,7 +352,7 @@ if(is_station_level(W.z) && !istype(get_area(W), /area/command) && !istype(get_area(W), /area/commons) && !istype(get_area(W), /area/service) && !istype(get_area(W), /area/command/heads_quarters) && !istype(get_area(W), /area/security/prison)) W.req_access = list() message_admins("[key_name_admin(holder)] activated Egalitarian Station mode") - priority_announce("CentCom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, "commandreport") + priority_announce("CentCom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, SSstation.announcer.get_rand_report_sound()) if("ancap") if(!is_funmin) return @@ -360,9 +360,9 @@ SSeconomy.full_ancap = !SSeconomy.full_ancap message_admins("[key_name_admin(holder)] toggled Anarcho-capitalist mode") if(SSeconomy.full_ancap) - priority_announce("The NAP is now in full effect.", null, "commandreport") + priority_announce("The NAP is now in full effect.", null, SSstation.announcer.get_rand_report_sound()) else - priority_announce("The NAP has been revoked.", null, "commandreport") + priority_announce("The NAP has been revoked.", null, SSstation.announcer.get_rand_report_sound()) if("blackout") if(!is_funmin) return @@ -528,7 +528,7 @@ message_admins("[key_name_admin(holder)] made everything kawaii.") for(var/i in GLOB.human_list) var/mob/living/carbon/human/H = i - SEND_SOUND(H, sound(get_announcer_sound("animes"))) + SEND_SOUND(H, sound(SSstation.announcer.event_sounds[ANNOUNCER_ANIMES])) if(H.dna.species.id == "human") if(H.dna.features["tail_human"] == "None" || H.dna.features["ears"] == "None") @@ -583,13 +583,15 @@ // log_admin("[key_name(holder)] has Un-Fully Immersed everyone.") if(E) E.processing = FALSE - if(E.announceWhen>0) + if(E.announce_when>0) switch(alert(holder, "Would you like to alert the crew?", "Alert", "Yes", "No", "Cancel")) + if("Yes") + E.announce_chance = 100 if("Cancel") E.kill() return if("No") - E.announceWhen = -1 + E.announce_chance = 0 E.processing = TRUE if(holder) log_admin("[key_name(holder)] used secret [action]") diff --git a/code/modules/admin/view_variables/filterrific.dm b/code/modules/admin/view_variables/filterrific.dm index e651028cbe..6cef9b178a 100644 --- a/code/modules/admin/view_variables/filterrific.dm +++ b/code/modules/admin/view_variables/filterrific.dm @@ -79,7 +79,7 @@ . = TRUE if("mass_apply") if(!check_rights_for(usr.client, R_FUN)) - to_chat(usr, " [var_new]") - log_admin("[key_name(src)] modified [original_name]'s [variable] from [html_encode("[var_value]")] to [html_encode("[var_new]")]") - var/msg = "[key_name_admin(src)] modified [original_name]'s [variable] from [var_value] to [var_new]" + log_world("### VarEdit by [key_name(src)]: [O.type] [variable]=[var_old_text ? var_old_text : var_value] => [var_new_text ? var_new_text : var_new]") + log_admin("[key_name(src)] modified [original_name]'s [variable] from [html_encode("[var_old_text ? var_old_text : var_value]")] to [html_encode("[var_new_text ? var_new_text : var_new]")]") + var/msg = "[key_name_admin(src)] modified [original_name]'s [variable] from [var_old_text ? var_old_text : var_value] to [var_new_text ? var_new_text : var_new]" message_admins(msg) admin_ticket_log(O, msg) return TRUE diff --git a/code/modules/admin/view_variables/reference_tracking.dm b/code/modules/admin/view_variables/reference_tracking.dm index 279654eec1..714b54cd45 100644 --- a/code/modules/admin/view_variables/reference_tracking.dm +++ b/code/modules/admin/view_variables/reference_tracking.dm @@ -1,4 +1,4 @@ -#ifdef REFERENCE_TRACKING +#ifdef EXTOOLS_REFERENCE_TRACKING GLOBAL_LIST_EMPTY(deletion_failures) @@ -102,29 +102,21 @@ GLOBAL_LIST_EMPTY(deletion_failures) #endif -#ifdef LEGACY_REFERENCE_TRACKING +#ifdef REFERENCE_TRACKING -/datum/verb/legacy_find_refs() - set category = "Debug" - set name = "Find References" - set src in world - - find_references_legacy(FALSE) - - -/datum/proc/find_references_legacy(skip_alert) +/datum/proc/find_references(skip_alert) running_find_references = type if(usr?.client) if(usr.client.running_find_references) - testing("CANCELLED search for references to a [usr.client.running_find_references].") + log_reftracker("CANCELLED search for references to a [usr.client.running_find_references].") usr.client.running_find_references = null running_find_references = null //restart the garbage collector SSgarbage.can_fire = TRUE - SSgarbage.next_fire = world.time + world.tick_lag + SSgarbage.update_nextfire(reset_time = TRUE) return - if(!skip_alert && alert("Running this will lock everything up for about 5 minutes. Would you like to begin the search?", "Find References", "Yes", "No") != "Yes") + if(!skip_alert && tgui_alert(usr,"Running this will lock everything up for about 5 minutes. Would you like to begin the search?", "Find References", list("Yes", "No")) != "Yes") running_find_references = null return @@ -134,92 +126,122 @@ GLOBAL_LIST_EMPTY(deletion_failures) if(usr?.client) usr.client.running_find_references = type - testing("Beginning search for references to a [type].") - last_find_references = world.time + log_reftracker("Beginning search for references to a [type].") + + var/starting_time = world.time + + //Time to search the whole game for our ref + DoSearchVar(GLOB, "GLOB") //globals + log_reftracker("Finished searching globals") - DoSearchVar(GLOB) //globals for(var/datum/thing in world) //atoms (don't beleive its lies) - DoSearchVar(thing, "World -> [thing]") + DoSearchVar(thing, "World -> [thing.type]", search_time = starting_time) + log_reftracker("Finished searching atoms") for(var/datum/thing) //datums - DoSearchVar(thing, "World -> [thing]") + DoSearchVar(thing, "Datums -> [thing.type]", search_time = starting_time) + log_reftracker("Finished searching datums") + //Warning, attempting to search clients like this will cause crashes if done on live. Watch yourself for(var/client/thing) //clients - DoSearchVar(thing, "World -> [thing]") + DoSearchVar(thing, "Clients -> [thing.type]", search_time = starting_time) + log_reftracker("Finished searching clients") + + log_reftracker("Completed search for references to a [type].") - testing("Completed search for references to a [type].") if(usr?.client) usr.client.running_find_references = null running_find_references = null //restart the garbage collector SSgarbage.can_fire = TRUE - SSgarbage.next_fire = world.time + world.tick_lag + SSgarbage.update_nextfire(reset_time = TRUE) +/datum/proc/DoSearchVar(potential_container, container_name, recursive_limit = 64, search_time = world.time) + #ifdef REFERENCE_TRACKING_DEBUG + if(!found_refs && SSgarbage.should_save_refs) + found_refs = list() + #endif -/datum/verb/qdel_then_find_references() - set category = "Debug" - set name = "qdel() then Find References" - set src in world - - qdel(src, TRUE) //force a qdel - if(!running_find_references) - find_references_legacy(TRUE) - - -/datum/verb/qdel_then_if_fail_find_references() - set category = "Debug" - set name = "qdel() then Find References if GC failure" - set src in world - - qdel_and_find_ref_if_fail(src, TRUE) - - -/datum/proc/DoSearchVar(potential_container, container_name, recursive_limit = 64) if(usr?.client && !usr.client.running_find_references) return if(!recursive_limit) + log_reftracker("Recursion limit reached. [container_name]") return - if(istype(potential_container, /datum)) - var/datum/datum_container = potential_container - if(datum_container.last_find_references == last_find_references) - return - - datum_container.last_find_references = last_find_references - var/list/vars_list = datum_container.vars - - for(var/varname in vars_list) - if (varname == "vars") - continue - var/variable = vars_list[varname] - - if(variable == src) - testing("Found [type] \ref[src] in [datum_container.type]'s [varname] var. [container_name]") - - else if(islist(variable)) - DoSearchVar(variable, "[container_name] -> list", recursive_limit - 1) - - else if(islist(potential_container)) - var/normal = IS_NORMAL_LIST(potential_container) - for(var/element_in_list in potential_container) - if(element_in_list == src) - testing("Found [type] \ref[src] in list [container_name].") - - else if(element_in_list && !isnum(element_in_list) && normal && potential_container[element_in_list] == src) - testing("Found [type] \ref[src] in list [container_name]\[[element_in_list]\]") - - else if(islist(element_in_list)) - DoSearchVar(element_in_list, "[container_name] -> list", recursive_limit - 1) - + //Check each time you go down a layer. This makes it a bit slow, but it won't effect the rest of the game at all #ifndef FIND_REF_NO_CHECK_TICK CHECK_TICK #endif + if(istype(potential_container, /datum)) + var/datum/datum_container = potential_container + if(datum_container.last_find_references == search_time) + return + + datum_container.last_find_references = search_time + var/list/vars_list = datum_container.vars + + for(var/varname in vars_list) + #ifndef FIND_REF_NO_CHECK_TICK + CHECK_TICK + #endif + if (varname == "vars" || varname == "vis_locs") //Fun fact, vis_locs don't count for references + continue + var/variable = vars_list[varname] + + if(variable == src) + #ifdef REFERENCE_TRACKING_DEBUG + if(SSgarbage.should_save_refs) + found_refs[varname] = TRUE + #endif + log_reftracker("Found [type] \ref[src] in [datum_container.type]'s \ref[datum_container] [varname] var. [container_name]") + continue + + if(islist(variable)) + DoSearchVar(variable, "[container_name] \ref[datum_container] -> [varname] (list)", recursive_limit - 1, search_time) + + else if(islist(potential_container)) + var/normal = IS_NORMAL_LIST(potential_container) + var/list/potential_cache = potential_container + for(var/element_in_list in potential_cache) + #ifndef FIND_REF_NO_CHECK_TICK + CHECK_TICK + #endif + //Check normal entrys + if(element_in_list == src) + #ifdef REFERENCE_TRACKING_DEBUG + if(SSgarbage.should_save_refs) + found_refs[potential_cache] = TRUE + #endif + log_reftracker("Found [type] \ref[src] in list [container_name].") + continue + + var/assoc_val = null + if(!isnum(element_in_list) && normal) + assoc_val = potential_cache[element_in_list] + //Check assoc entrys + if(assoc_val == src) + #ifdef REFERENCE_TRACKING_DEBUG + if(SSgarbage.should_save_refs) + found_refs[potential_cache] = TRUE + #endif + log_reftracker("Found [type] \ref[src] in list [container_name]\[[element_in_list]\]") + continue + //We need to run both of these checks, since our object could be hiding in either of them + //Check normal sublists + if(islist(element_in_list)) + DoSearchVar(element_in_list, "[container_name] -> [element_in_list] (list)", recursive_limit - 1, search_time) + //Check assoc sublists + if(islist(assoc_val)) + DoSearchVar(potential_container[element_in_list], "[container_name]\[[element_in_list]\] -> [assoc_val] (list)", recursive_limit - 1, search_time) /proc/qdel_and_find_ref_if_fail(datum/thing_to_del, force = FALSE) - SSgarbage.reference_find_on_fail[REF(thing_to_del)] = TRUE - qdel(thing_to_del, force) + thing_to_del.qdel_and_find_ref_if_fail(force) + +/datum/proc/qdel_and_find_ref_if_fail(force = FALSE) + SSgarbage.reference_find_on_fail["\ref[src]"] = TRUE + qdel(src, force) #endif diff --git a/code/modules/admin/view_variables/topic_basic.dm b/code/modules/admin/view_variables/topic_basic.dm index 01b5536948..043c50173d 100644 --- a/code/modules/admin/view_variables/topic_basic.dm +++ b/code/modules/admin/view_variables/topic_basic.dm @@ -47,7 +47,7 @@ usr.client.debug_variables(src) return - #ifdef REFERENCE_TRACKING + #ifdef EXTOOLS_REFERENCE_TRACKING if(href_list[VV_HK_VIEW_REFERENCES]) var/datum/D = locate(href_list[VV_HK_TARGET]) if(!D) diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index 4082a48e71..ca392a0441 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -1,33 +1,77 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist + ///Public name for this antagonist. Appears for player prompts and round-end reports. var/name = "Antagonist" - var/roundend_category = "other antagonists" //Section of roundend report, datums with same category will be displayed together, also default header for the section - var/show_in_roundend = TRUE //Set to false to hide the antagonists from roundend report - var/datum/mind/owner //Mind that owns this datum - var/silent = FALSE //Silent will prevent the gain/lose texts to show - var/can_coexist_with_others = TRUE //Whether or not the person will be able to have more than one datum - var/list/typecache_datum_blacklist = list() //List of datums this type can't coexist with - var/delete_on_mind_deletion = TRUE + ///Section of roundend report, datums with same category will be displayed together, also default header for the section + var/roundend_category = "other antagonists" + ///Set to false to hide the antagonists from roundend report + var/show_in_roundend = TRUE + ///If false, the roundtype will still convert with this antag active + var/prevent_roundtype_conversion = TRUE + ///Mind that owns this datum + var/datum/mind/owner + ///Silent will prevent the gain/lose texts to show + var/silent = FALSE + ///Whether or not the person will be able to have more than one datum + var/can_coexist_with_others = TRUE + ///List of datums this type can't coexist with + var/list/typecache_datum_blacklist = list() + ///The define string we use to identify the role for bans/player polls to spawn a random new one in. var/job_rank - var/replace_banned = TRUE //Should replace jobbaned player with ghosts if granted. + ///Should replace jobbanned player with ghosts if granted. + var/replace_banned = TRUE + ///List of the objective datums that this role currently has, completing all objectives at round-end will cause this antagonist to greentext. var/list/objectives = list() - var/antag_memory = ""//These will be removed with antag datum - var/antag_moodlet //typepath of moodlet that the mob will gain with their status + ///String dialogue that is added to the player's in-round notes and memories regarding specifics of that antagonist, eg. the nuke code for nuke ops, or your unlock code for traitors. + var/antag_memory = "" + ///typepath of moodlet that the mob will gain when granted this antagonist type. + var/antag_moodlet + + ///What is the configuration of this antagonist's hud icon, such as it's screen position and style, so thatit doesn't break other in-game hud icons. var/antag_hud_type + ///Name of the antag hud we provide to this mob. var/antag_hud_name /// If above 0, this is the multiplier for the speed at which we hijack the shuttle. Do not directly read, use hijack_speed(). var/hijack_speed = 0 + /// The battlecry this antagonist shouts when suiciding with C4/X4. + var/suicide_cry = "" + /// The typepath for the outfit to show in the preview for the preferences menu. + var/preview_outfit + /// If set to true, the antag will not be added to the living antag list. + var/soft_antag = FALSE //Antag panel properties - var/show_in_antagpanel = TRUE //This will hide adding this antag type in antag panel, use only for internal subtypes that shouldn't be added directly but still show if possessed by mind - var/antagpanel_category = "Uncategorized" //Antagpanel will display these together, REQUIRED - var/show_name_in_check_antagonists = FALSE //Will append antagonist name in admin listings - use for categories that share more than one antag type - var/list/blacklisted_quirks = list(/datum/quirk/nonviolent,/datum/quirk/mute) // Quirks that will be removed upon gaining this antag. Pacifist and mute are default. - var/threat = 0 // Amount of threat this antag poses, for dynamic mode - var/show_to_ghosts = FALSE // Should this antagonist be shown as antag to ghosts? Shouldn't be used for stealthy antagonists like traitors + ///This will hide adding this antag type in antag panel, use only for internal subtypes that shouldn't be added directly but still show if possessed by mind + var/show_in_antagpanel = TRUE + ///Antagpanel will display these together, REQUIRED + var/antagpanel_category = "Uncategorized" + ///Will append antagonist name in admin listings - use for categories that share more than one antag type + var/show_name_in_check_antagonists = FALSE + /// Should this antagonist be shown as antag to ghosts? Shouldn't be used for stealthy antagonists like traitors + var/show_to_ghosts = FALSE +//ambition start + /// Lazy list for antagonists to request the admins objectives. + var/list/requested_objective_changes +//ambition end + + /* CIT SPECIFIC */ + /// Quirks that will be removed upon gaining this antag. Pacifist and mute are default. + var/list/blacklisted_quirks = list(/datum/quirk/nonviolent,/datum/quirk/mute) + /// Amount of threat this antag poses, for dynamic mode + var/threat = 0 + + var/delete_on_mind_deletion = TRUE var/list/skill_modifiers + /* CIT SPECIFIC end */ + + //ANTAG UI + + ///name of the UI that will try to open, right now having nothing means this won't exist but in the future all should. + var/ui_name + ///button to access antag interface + var/datum/action/antag_info/info_button /datum/antagonist/New() GLOB.antagonists += src @@ -35,8 +79,12 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/Destroy() GLOB.antagonists -= src - if(owner) - LAZYREMOVE(owner.antag_datums, src) + if(!owner) + stack_trace("Destroy()ing antagonist datum when it has no owner.") + else +//ambition start + owner?.do_remove_antag_datum(src) +//ambition end owner = null return ..() @@ -55,9 +103,15 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/proc/specialization(datum/mind/new_owner) return src +///Called by the transfer_to() mind proc after the mind (mind.current and new_character.mind) has moved but before the player (key and client) is transfered. /datum/antagonist/proc/on_body_transfer(mob/living/old_body, mob/living/new_body) + SHOULD_CALL_PARENT(TRUE) remove_innate_effects(old_body) + if(!soft_antag && old_body && old_body.stat != DEAD && !length(old_body.mind?.antag_datums)) + old_body.remove_from_current_living_antags() apply_innate_effects(new_body) + if(!soft_antag && new_body.stat != DEAD) + new_body.add_to_current_living_antags() //This handles the application of antag huds/special abilities /datum/antagonist/proc/apply_innate_effects(mob/living/mob_override) @@ -67,45 +121,76 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/proc/remove_innate_effects(mob/living/mob_override) return +/// This is called when the antagonist is being mindshielded. +/datum/antagonist/proc/pre_mindshield(mob/implanter, mob/living/mob_override) + SIGNAL_HANDLER + // return COMPONENT_MINDSHIELD_PASSED + +/// This is called when the antagonist is successfully mindshielded. +/datum/antagonist/proc/on_mindshield(mob/implanter, mob/living/mob_override) + SIGNAL_HANDLER + return + // Adds the specified antag hud to the player. Usually called in an antag datum file /datum/antagonist/proc/add_antag_hud(antag_hud_type, antag_hud_name, mob/living/mob_override) var/datum/atom_hud/antag/hud = GLOB.huds[antag_hud_type] hud.join_hud(mob_override) set_antag_hud(mob_override, antag_hud_name) + // Removes the specified antag hud from the player. Usually called in an antag datum file /datum/antagonist/proc/remove_antag_hud(antag_hud_type, mob/living/mob_override) var/datum/atom_hud/antag/hud = GLOB.huds[antag_hud_type] hud.leave_hud(mob_override) set_antag_hud(mob_override, null) -// Handles adding and removing the clumsy mutation from clown antags. Gets called in apply/remove_innate_effects + +/// Handles adding and removing the clumsy mutation from clown antags. Gets called in apply/remove_innate_effects /datum/antagonist/proc/handle_clown_mutation(mob/living/mob_override, message, removing = TRUE) - var/mob/living/carbon/human/H = mob_override - if(H && istype(H) && owner.assigned_role == "Clown") - if(removing) // They're a clown becoming an antag, remove clumsy - H.dna.remove_mutation(CLOWNMUT) - if(!silent && message) - to_chat(H, "[message]") - else - H.dna.add_mutation(CLOWNMUT) // We're removing their antag status, add back clumsy + if(!ishuman(mob_override) || owner.assigned_role != "Clown") + return + var/mob/living/carbon/human/human_override = mob_override + if(removing) // They're a clown becoming an antag, remove clumsy + human_override.dna.remove_mutation(CLOWNMUT) + if(!silent && message) + to_chat(human_override, span_boldnotice("[message]")) + else + human_override.dna.add_mutation(CLOWNMUT) // We're removing their antag status, add back clumsy + //Assign default team and creates one for one of a kind team antagonists /datum/antagonist/proc/create_team(datum/team/team) return -//Proc called when the datum is given to a mind. +///Called by the add_antag_datum() mind proc after the instanced datum is added to the mind's antag_datums list. /datum/antagonist/proc/on_gain() - set waitfor = FALSE - if(!(owner?.current)) - return + SHOULD_CALL_PARENT(TRUE) + if(!owner) + CRASH("[src] ran on_gain() without a mind") + if(!owner.current) + CRASH("[src] ran on_gain() on a mind without a mob") + if(ui_name)//in the future, this should entirely replace greet. + info_button = new(owner.current, src) + info_button.Grant(owner.current) if(!silent) greet() + if(ui_name) + to_chat(owner.current, span_big("You are \a [src].")) + to_chat(owner.current, span_boldnotice("For more info, read the panel. you can always come back to it using the button in the top left.")) + info_button.Trigger() apply_innate_effects() give_antag_moodies() remove_blacklisted_quirks() + // RegisterSignal(owner, COMSIG_PRE_MINDSHIELD_IMPLANT, .proc/pre_mindshield) + // RegisterSignal(owner, COMSIG_MINDSHIELD_IMPLANTED, .proc/on_mindshield) if(is_banned(owner.current) && replace_banned) replace_banned_player() + else if(owner.current.client?.holder && (CONFIG_GET(flag/auto_deadmin_antagonists) || owner.current.client.prefs?.deadmin & DEADMIN_ANTAGONIST)) + owner.current.client.holder.auto_deadmin() + if(!soft_antag && owner.current.stat != DEAD) + owner.current.add_to_current_living_antags() + + // cit skill if(skill_modifiers) for(var/A in skill_modifiers) ADD_SINGLETON_SKILL_MODIFIER(owner, A, type) @@ -115,53 +200,93 @@ GLOBAL_LIST_EMPTY(antagonists) owner.current.AddComponent(/datum/component/activity) SEND_SIGNAL(owner.current, COMSIG_MOB_ANTAG_ON_GAIN, src) + +/** + * Proc that checks the sent mob aganst the banlistfor this antagonist. + * Returns FALSE if no mob is sent, or the mob is not found to be banned. + * + * * mob/M: The mob that you are looking for on the banlist. + */ /datum/antagonist/proc/is_banned(mob/M) if(!M) return FALSE . = (jobban_isbanned(M, ROLE_SYNDICATE) || QDELETED(M) || (job_rank && (jobban_isbanned(M,job_rank) || QDELETED(M)))) +/** + * Proc that replaces a player who cannot play a specific antagonist due to being banned via a poll, and alerts the player of their being on the banlist. + */ /datum/antagonist/proc/replace_banned_player() set waitfor = FALSE - var/list/mob/candidates = pollCandidatesForMob("Do you want to play as a [name]?", "[name]", null, job_rank, 50, owner.current) + var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [name]?", "[name]", job_rank, 50, owner.current) if(LAZYLEN(candidates)) - var/mob/C = pick(candidates) + var/mob/dead/observer/C = pick(candidates) to_chat(owner, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!") - message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(owner.current)]) to replace a jobbaned player.") + message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(owner)]) to replace a jobbanned player.") owner.current.ghostize(0) C.transfer_ckey(owner.current, FALSE) +/** + * Called by the remove_antag_datum() and remove_all_antag_datums() mind procs for the antag datum to handle its own removal and deletion. + */ /datum/antagonist/proc/on_removal() + SHOULD_CALL_PARENT(TRUE) + if(!owner) + CRASH("Antag datum with no owner.") + remove_innate_effects() clear_antag_moodies() - if(owner) - LAZYREMOVE(owner.antag_datums, src) - for(var/A in skill_modifiers) - owner.remove_skill_modifier(GET_SKILL_MOD_ID(A, type)) - if(!silent && owner.current) - farewell() + owner.do_remove_antag_datum(src) + // cit skill + for(var/A in skill_modifiers) + owner.remove_skill_modifier(GET_SKILL_MOD_ID(A, type)) + // end + if(!LAZYLEN(owner.antag_datums) && !soft_antag) + owner.current.remove_from_current_living_antags() + if(info_button) + QDEL_NULL(info_button) + if(!silent && owner.current) + farewell() + // UnregisterSignal(owner, COMSIG_PRE_MINDSHIELD_IMPLANT) + // UnregisterSignal(owner, COMSIG_MINDSHIELD_IMPLANTED) var/datum/team/team = get_team() if(team) team.remove_member(owner) - // we don't remove the activity component on purpose--no real point to it qdel(src) +/** + * Proc that sends fluff or instructional messages to the player when they are given this antag datum. + * Use this proc for playing sounds, sending alerts, or helping to setup non-gameplay influencing aspects of the antagonist type. + */ /datum/antagonist/proc/greet() return +/** + * Proc that sends fluff or instructional messages to the player when they lose this antag datum. + * Use this proc for playing sounds, sending alerts, or otherwise informing the player that they're no longer a specific antagonist type. + */ /datum/antagonist/proc/farewell() return +/** + * Proc that assigns this antagonist's ascribed moodlet to the player. + */ /datum/antagonist/proc/give_antag_moodies() if(!antag_moodlet) return SEND_SIGNAL(owner.current, COMSIG_ADD_MOOD_EVENT, "antag_moodlet", antag_moodlet) +/** + * Proc that removes this antagonist's ascribed moodlet from the player. + */ /datum/antagonist/proc/clear_antag_moodies() if(!antag_moodlet) return SEND_SIGNAL(owner.current, COMSIG_CLEAR_MOOD_EVENT, "antag_moodlet") +/** + * Removes invalid quirks. + */ /datum/antagonist/proc/remove_blacklisted_quirks() var/mob/living/L = owner.current if(istype(L)) @@ -172,16 +297,22 @@ GLOBAL_LIST_EMPTY(antagonists) to_chat(L, "[initial(Q.antag_removal_text)]") qdel(Q) -//Returns the team antagonist belongs to if any. +/** + * Proc that will return the team this antagonist belongs to, when called. Helpful with antagonists that may belong to multiple potential teams in a single round, like families. + */ /datum/antagonist/proc/get_team() return -//Individual roundend report +/** + * Proc that sends string information for the end-round report window to the server. + * This runs on every instance of every antagonist that exists at the end of the round. + * This is the body of the message, sandwiched between roundend_report_header and roundend_report_footer. + */ /datum/antagonist/proc/roundend_report() var/list/report = list() if(!owner) - CRASH("antagonist datum without owner") + CRASH("Antagonist datum without owner") report += printplayer(owner) @@ -200,11 +331,19 @@ GLOBAL_LIST_EMPTY(antagonists) return report.Join("
    ") -//Displayed at the start of roundend_category section, default to roundend_category header +/** + * Proc that sends string data for the round-end report. + * Displayed before roundend_report and roundend_report_footer. + * Appears at start of roundend_catagory section. + */ /datum/antagonist/proc/roundend_report_header() - return "The [roundend_category] were:
    " + return "The [roundend_category] were:
    " -//Displayed at the end of roundend_category section +/** + * Proc that sends string data for the round-end report. + * Displayed after roundend_report and roundend_report_footer. + * Appears at the end of the roundend_catagory section. + */ /datum/antagonist/proc/roundend_report_footer() return @@ -213,22 +352,24 @@ GLOBAL_LIST_EMPTY(antagonists) //Called when using admin tools to give antag status /datum/antagonist/proc/admin_add(datum/mind/new_owner,mob/admin) - message_admins("[key_name_admin(admin)] made [new_owner.current] into [name].") - log_admin("[key_name(admin)] made [new_owner.current] into [name].") + message_admins("[key_name_admin(admin)] made [key_name_admin(new_owner)] into [name].") + log_admin("[key_name(admin)] made [key_name(new_owner)] into [name].") new_owner.add_antag_datum(src) //Called when removing antagonist using admin tools /datum/antagonist/proc/admin_remove(mob/user) if(!user) return - message_admins("[key_name_admin(user)] has removed [name] antagonist status from [owner.current].") - log_admin("[key_name(user)] has removed [name] antagonist status from [owner.current].") + message_admins("[key_name_admin(user)] has removed [name] antagonist status from [key_name_admin(owner)].") + log_admin("[key_name(user)] has removed [name] antagonist status from [key_name(owner)].") on_removal() //gamemode/proc/is_mode_antag(antagonist/A) => TRUE/FALSE -//Additional data to display in antagonist panel section -//nuke disk code, genome count, etc +/** + * Additional data to display in the antagonist panel section. + * For example, nuke disk code, genome count, etc + */ /datum/antagonist/proc/antag_panel_data() return "" @@ -240,10 +381,47 @@ GLOBAL_LIST_EMPTY(antagonists) return FALSE return TRUE -// List if ["Command"] = CALLBACK(), user will be appeneded to callback arguments on execution +/// List of ["Command"] = CALLBACK(), user will be appeneded to callback arguments on execution /datum/antagonist/proc/get_admin_commands() . = list() +/// Creates an icon from the preview outfit. +/// Custom implementors of `get_preview_icon` should use this, as the +/// result of `get_preview_icon` is expected to be the completed version. +/datum/antagonist/proc/render_preview_outfit(datum/outfit/outfit, mob/living/carbon/human/dummy) + dummy = dummy || new /mob/living/carbon/human/dummy/consistent + dummy.equipOutfit(outfit, visualsOnly = TRUE) + COMPILE_OVERLAYS(dummy) + var/icon = getFlatIcon(dummy) + + // We don't want to qdel the dummy right away, since its items haven't initialized yet. + SSatoms.prepare_deletion(dummy) + + return icon + +/// Given an icon, will crop it to be consistent of those in the preferences menu. +/// Not necessary, and in fact will look bad if it's anything other than a human. +/datum/antagonist/proc/finish_preview_icon(icon/icon) + // Zoom in on the top of the head and the chest + // I have no idea how to do this dynamically. + icon.Scale(115, 115) + + // This is probably better as a Crop, but I cannot figure it out. + icon.Shift(WEST, 8) + icon.Shift(SOUTH, 30) + + icon.Crop(1, 1, ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) + + return icon + +/// Returns the icon to show on the preferences menu. +/datum/antagonist/proc/get_preview_icon() + if (isnull(preview_outfit)) + return null + + return finish_preview_icon(render_preview_outfit(preview_outfit)) + + /datum/antagonist/Topic(href,href_list) if(!check_rights(R_ADMIN)) return @@ -270,14 +448,19 @@ GLOBAL_LIST_EMPTY(antagonists) return antag_memory = new_memo -/// Gets how fast we can hijack the shuttle, return 0 for can not hijack. Defaults to hijack_speed var, override for custom stuff like buffing hijack speed for hijack objectives or something. +/** + * Gets how fast we can hijack the shuttle, return 0 for can not hijack. + * Defaults to hijack_speed var, override for custom stuff like buffing hijack speed for hijack objectives or something. + */ /datum/antagonist/proc/hijack_speed() var/datum/objective/hijack/H = locate() in objectives if(!isnull(H?.hijack_speed_override)) return H.hijack_speed_override return hijack_speed -/// Gets our threat level. Defaults to threat var, override for custom stuff like different traitor goals having different threats. +/** + * Gets our threat level. Override this proc for custom functionality/dynamic threat level. + */ /datum/antagonist/proc/threat() . = CONFIG_GET(keyed_list/antag_threat)[lowertext(name)] if(. == null) @@ -287,6 +470,13 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/custom antagpanel_category = "Custom" show_name_in_check_antagonists = TRUE //They're all different + var/datum/team/custom_team + +/datum/antagonist/custom/create_team(datum/team/team) + custom_team = team + +/datum/antagonist/custom/get_team() + return custom_team /datum/antagonist/custom/admin_add(datum/mind/new_owner,mob/admin) var/custom_name = stripped_input(admin, "Custom antagonist name:", "Custom antag", "Antagonist") @@ -295,3 +485,78 @@ GLOBAL_LIST_EMPTY(antagonists) else return ..() + +///ANTAGONIST UI STUFF + +/datum/antagonist/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, ui_name, name) + ui.open() + +/datum/antagonist/ui_state(mob/user) + return GLOB.always_state + +///generic helper to send objectives as data through tgui. supports smart objectives too! +/datum/antagonist/proc/get_objectives() + var/objective_count = 1 + var/list/objective_data = list() + //all obj + for(var/datum/objective/objective in objectives) + objective_data += list(list( + "count" = objective_count, + "name" = objective.name, + "explanation" = objective.explanation_text, + "complete" = objective.completed, + )) + objective_count++ + return objective_data + +//button for antags to review their descriptions/info + +/datum/action/antag_info + name = "Open Antag Information:" + button_icon_state = "round_end" + var/datum/antagonist/antag_datum + +/datum/action/antag_info/New(Target, datum/antagonist/antag_datum) + . = ..() + src.antag_datum = antag_datum + name += " [antag_datum.name]" + +/datum/action/antag_info/Trigger() + if(antag_datum) + antag_datum.ui_interact(owner) + +/datum/action/antag_info/IsAvailable() + return TRUE + +///Clears change requests from deleted objectives to avoid broken references. +/datum/antagonist/proc/clean_request_from_del_objective(datum/objective/source, force) + var/objective_reference = REF(source) + for(var/uid in requested_objective_changes) + var/list/change_request = requested_objective_changes[uid] + if(change_request["target"] != objective_reference) + continue + LAZYREMOVE(requested_objective_changes, uid) + + +/datum/antagonist/proc/add_objective_change(uid, list/additions) + LAZYADD(requested_objective_changes, uid) + var/datum/objective/request_target = additions["target"] + if(!ispath(request_target)) + request_target = locate(request_target) in objectives + if(istype(request_target)) + RegisterSignal(request_target, COMSIG_PARENT_QDELETING, .proc/clean_request_from_del_objective) + requested_objective_changes[uid] = additions + + +/datum/antagonist/proc/remove_objective_change(uid) + if(!LAZYACCESS(requested_objective_changes, uid)) + return + var/datum/objective/request_target = requested_objective_changes[uid]["target"] + if(!ispath(request_target)) + request_target = locate(request_target) in objectives + if(istype(request_target)) + UnregisterSignal(request_target, COMSIG_PARENT_QDELETING) + LAZYREMOVE(requested_objective_changes, uid) diff --git a/code/modules/antagonists/_common/antag_helpers.dm b/code/modules/antagonists/_common/antag_helpers.dm index b10df46348..91f0177d9c 100644 --- a/code/modules/antagonists/_common/antag_helpers.dm +++ b/code/modules/antagonists/_common/antag_helpers.dm @@ -6,14 +6,3 @@ continue if(!antag_type || !specific && istype(A,antag_type) || specific && A.type == antag_type) . += A.owner - -//Get all teams [of type team_type] -/proc/get_all_teams(team_type) - . = list() - for(var/V in GLOB.antagonists) - var/datum/antagonist/A = V - if(!A.owner) - continue - var/datum/team/T = A.get_team() - if(!team_type || istype(T,team_type)) - . |= T diff --git a/code/modules/antagonists/_common/antag_team.dm b/code/modules/antagonists/_common/antag_team.dm index 9d138ed0b9..f4e0d321d5 100644 --- a/code/modules/antagonists/_common/antag_team.dm +++ b/code/modules/antagonists/_common/antag_team.dm @@ -1,3 +1,5 @@ +GLOBAL_LIST_EMPTY(antagonist_teams) + //A barebones antagonist team. /datum/team var/list/datum/mind/members = list() @@ -8,6 +10,7 @@ /datum/team/New(starting_members) . = ..() + GLOB.antagonist_teams += src if(starting_members) if(islist(starting_members)) for(var/datum/mind/M in starting_members) @@ -15,6 +18,10 @@ else add_member(starting_members) +/datum/team/Destroy(force, ...) + GLOB.antagonist_teams -= src + . = ..() + /datum/team/proc/is_solo() return members.len == 1 diff --git a/code/modules/antagonists/abductor/abductor.dm b/code/modules/antagonists/abductor/abductor.dm index 7eb7ec2af2..f7e66ee90a 100644 --- a/code/modules/antagonists/abductor/abductor.dm +++ b/code/modules/antagonists/abductor/abductor.dm @@ -97,7 +97,7 @@ /datum/antagonist/abductor/admin_add(datum/mind/new_owner,mob/admin) var/list/current_teams = list() - for(var/datum/team/abductor_team/T in get_all_teams(/datum/team/abductor_team)) + for(var/datum/team/abductor_team/T in GLOB.antagonist_teams) current_teams[T.name] = T var/choice = input(admin,"Add to which team ?") as null|anything in (current_teams + "new team") if (choice == "new team") diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm index 8484732d8d..343faccad6 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm @@ -13,7 +13,7 @@ icon_state = "vest_stealth" item_state = "armor" blood_overlay_type = "armor" - armor = list("melee" = 15, "bullet" = 15, "laser" = 15, "energy" = 15, "bomb" = 15, "bio" = 15, "rad" = 15, "fire" = 70, "acid" = 70) + armor = list(MELEE = 15, BULLET = 15, LASER = 15, ENERGY = 15, BOMB = 15, BIO = 15, RAD = 15, FIRE = 70, ACID = 70) actions_types = list(/datum/action/item_action/hands_free/activate) allowed = list( /obj/item/abductor, @@ -27,10 +27,10 @@ var/stealth_active = 0 var/combat_cooldown = 10 var/datum/icon_snapshot/disguise - var/stealth_armor = list("melee" = 15, "bullet" = 15, "laser" = 15, "energy" = 15, "bomb" = 15, "bio" = 15, "rad" = 15, "fire" = 70, "acid" = 70) - var/combat_armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 50, "rad" = 50, "fire" = 90, "acid" = 90) + var/stealth_armor = list(MELEE = 15, BULLET = 15, LASER = 15, ENERGY = 15, BOMB = 15, BIO = 15, RAD = 15, FIRE = 70, ACID = 70) + var/combat_armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 50, BIO = 50, RAD = 50, FIRE = 90, ACID = 90) -/obj/item/clothing/suit/armor/abductor/vest/Initialize() +/obj/item/clothing/suit/armor/abductor/vest/Initialize(mapload) . = ..() stealth_armor = getArmor(arglist(stealth_armor)) combat_armor = getArmor(arglist(combat_armor)) @@ -62,7 +62,7 @@ A.UpdateButtonIcon() /obj/item/clothing/suit/armor/abductor/vest/item_action_slot_check(slot, mob/user, datum/action/A) - if(slot == SLOT_WEAR_SUIT) //we only give the mob the ability to activate the vest if he's actually wearing it. + if(slot == ITEM_SLOT_OCLOTHING) //we only give the mob the ability to activate the vest if he's actually wearing it. return TRUE /obj/item/clothing/suit/armor/abductor/vest/proc/SetDisguise(datum/icon_snapshot/entry) diff --git a/code/modules/antagonists/abductor/equipment/gland.dm b/code/modules/antagonists/abductor/equipment/gland.dm index d0002d1f4a..312cc07997 100644 --- a/code/modules/antagonists/abductor/equipment/gland.dm +++ b/code/modules/antagonists/abductor/equipment/gland.dm @@ -19,7 +19,7 @@ var/mind_control_duration = 1800 var/active_mind_control = FALSE -/obj/item/organ/heart/gland/Initialize() +/obj/item/organ/heart/gland/Initialize(mapload) . = ..() icon_state = pick(list("health", "spider", "slime", "emp", "species", "egg", "vent", "mindshock", "viral")) diff --git a/code/modules/antagonists/abductor/equipment/glands/chem.dm b/code/modules/antagonists/abductor/equipment/glands/chem.dm index b651b45f6d..0c7d20d1ff 100644 --- a/code/modules/antagonists/abductor/equipment/glands/chem.dm +++ b/code/modules/antagonists/abductor/equipment/glands/chem.dm @@ -8,7 +8,7 @@ mind_control_duration = 1200 var/list/possible_reagents = list() -/obj/item/organ/heart/gland/chem/Initialize() +/obj/item/organ/heart/gland/chem/Initialize(mapload) . = ..() for(var/R in subtypesof(/datum/reagent/drug) + subtypesof(/datum/reagent/medicine) + typesof(/datum/reagent/toxin)) possible_reagents += R diff --git a/code/modules/antagonists/abductor/equipment/glands/heal.dm b/code/modules/antagonists/abductor/equipment/glands/heal.dm index 8917e1661e..e995826af6 100644 --- a/code/modules/antagonists/abductor/equipment/glands/heal.dm +++ b/code/modules/antagonists/abductor/equipment/glands/heal.dm @@ -23,7 +23,7 @@ return var/obj/item/organ/lungs/lungs = owner.getorganslot(ORGAN_SLOT_LUNGS) - if((!lungs && !HAS_TRAIT(owner, TRAIT_NOBREATH)) || (lungs && (istype(lungs, /obj/item/organ/lungs/cybernetic)))) + if((!lungs && (HAS_TRAIT_FROM(owner, TRAIT_AUXILIARY_LUNGS, SPECIES_TRAIT) || !HAS_TRAIT(owner, TRAIT_NOBREATH))) || (lungs && (istype(lungs, /obj/item/organ/lungs/cybernetic)))) replace_lungs(lungs) return diff --git a/code/modules/antagonists/abductor/machinery/dispenser.dm b/code/modules/antagonists/abductor/machinery/dispenser.dm index f5bc0946e6..7d79bacdd0 100644 --- a/code/modules/antagonists/abductor/machinery/dispenser.dm +++ b/code/modules/antagonists/abductor/machinery/dispenser.dm @@ -12,7 +12,7 @@ //TODO : replace with presets or spectrum return rgb(rand(0,255),rand(0,255),rand(0,255)) -/obj/machinery/abductor/gland_dispenser/Initialize() +/obj/machinery/abductor/gland_dispenser/Initialize(mapload) . = ..() gland_types = subtypesof(/obj/item/organ/heart/gland) gland_types = shuffle(gland_types) diff --git a/code/modules/antagonists/abductor/machinery/pad.dm b/code/modules/antagonists/abductor/machinery/pad.dm index ab636f7d0e..2ec8e70358 100644 --- a/code/modules/antagonists/abductor/machinery/pad.dm +++ b/code/modules/antagonists/abductor/machinery/pad.dm @@ -49,7 +49,7 @@ icon_state = "teleport" duration = 80 -/obj/effect/temp_visual/teleport_abductor/Initialize() +/obj/effect/temp_visual/teleport_abductor/Initialize(mapload) . = ..() var/datum/effect_system/spark_spread/S = new S.set_up(10,0,loc) diff --git a/code/modules/antagonists/ashwalker/ashwalker.dm b/code/modules/antagonists/ashwalker/ashwalker.dm new file mode 100644 index 0000000000..0ba84a201f --- /dev/null +++ b/code/modules/antagonists/ashwalker/ashwalker.dm @@ -0,0 +1,40 @@ +/datum/team/ashwalkers + name = "Ashwalkers" + show_roundend_report = FALSE + var/list/players_spawned = new + +/datum/antagonist/ashwalker + name = "\improper Ash Walker" + job_rank = ROLE_LAVALAND + show_in_antagpanel = FALSE + show_to_ghosts = TRUE + antagpanel_category = "Ash Walkers" + var/datum/team/ashwalkers/ashie_team + +/datum/antagonist/ashwalker/create_team(datum/team/team) + if(team) + ashie_team = team + objectives |= ashie_team.objectives + else + ashie_team = new + +/datum/antagonist/ashwalker/get_team() + return ashie_team + +/datum/antagonist/ashwalker/on_body_transfer(mob/living/old_body, mob/living/new_body) + . = ..() + RegisterSignal(new_body, COMSIG_MOB_EXAMINATE, .proc/on_examinate) + +/datum/antagonist/ashwalker/on_gain() + . = ..() + RegisterSignal(owner.current, COMSIG_MOB_EXAMINATE, .proc/on_examinate) + +/datum/antagonist/ashwalker/on_removal() + . = ..() + UnregisterSignal(owner.current, COMSIG_MOB_EXAMINATE) + +/datum/antagonist/ashwalker/proc/on_examinate(datum/source, atom/A) + SIGNAL_HANDLER + + if(istype(A, /obj/structure/headpike)) + SEND_SIGNAL(owner.current, COMSIG_ADD_MOOD_EVENT, "headspear", /datum/mood_event/sacrifice_good) diff --git a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm index f9763b92fd..1c98060d9b 100644 --- a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm +++ b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm @@ -46,10 +46,10 @@ else adjustFireLoss(5) -/mob/living/simple_animal/hostile/blob/CanPass(atom/movable/mover, turf/target) +/mob/living/simple_animal/hostile/blob/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(istype(mover, /obj/structure/blob)) - return 1 - return ..() + return TRUE /mob/living/simple_animal/hostile/blob/Process_Spacemove(movement_dir = 0) for(var/obj/structure/blob/B in range(1, src)) @@ -102,7 +102,7 @@ factory.spores += src . = ..() -/mob/living/simple_animal/hostile/blob/blobspore/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/blob/blobspore/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!is_zombie && isturf(src.loc)) @@ -221,7 +221,7 @@ hud_type = /datum/hud/blobbernaut var/independent = FALSE -/mob/living/simple_animal/hostile/blob/blobbernaut/Initialize() +/mob/living/simple_animal/hostile/blob/blobbernaut/Initialize(mapload) . = ..() if(independent) pass_flags &= ~PASSBLOB @@ -233,7 +233,7 @@ return FALSE return ..() -/mob/living/simple_animal/hostile/blob/blobbernaut/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/blob/blobbernaut/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return var/list/blobs_in_area = range(2, src) diff --git a/code/modules/antagonists/blob/blob/blobs/core.dm b/code/modules/antagonists/blob/blob/blobs/core.dm index 38484c70b0..317dcb2522 100644 --- a/code/modules/antagonists/blob/blob/blobs/core.dm +++ b/code/modules/antagonists/blob/blob/blobs/core.dm @@ -4,7 +4,7 @@ icon_state = "blank_blob" desc = "A huge, pulsating yellow mass." max_integrity = 400 - armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 5, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 90) // Last stand + armor = list(MELEE = 30, BULLET = 30, LASER = 20, ENERGY = 5, BOMB = 70, BIO = 0, RAD = 0, FIRE = 75, ACID = 90) // Last stand explosion_block = 6 point_return = -1 health_regen = 0 //we regen in Life() instead of when pulsed @@ -45,9 +45,9 @@ GLOB.poi_list -= src return ..() -/obj/structure/blob/core/ex_act(severity, target) +/obj/structure/blob/core/ex_act(severity, target, origin) var/damage = 50 - 10 * severity //remember, the core takes half brute damage, so this is 20/15/10 damage based on severity - take_damage(damage, BRUTE, "bomb", 0) + take_damage(damage, BRUTE, BOMB, 0) /obj/structure/blob/core/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir, overmind_reagent_trigger = 1) . = ..() diff --git a/code/modules/antagonists/blob/blob/blobs/factory.dm b/code/modules/antagonists/blob/blob/blobs/factory.dm index dfb3c6d71b..ae2c7f53ef 100644 --- a/code/modules/antagonists/blob/blob/blobs/factory.dm +++ b/code/modules/antagonists/blob/blob/blobs/factory.dm @@ -6,7 +6,7 @@ max_integrity = 200 health_regen = 1 point_return = 25 - armor = list("melee" = 10, "bullet" = 20, "laser" = 15, "energy" = 10, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 10, BULLET = 20, LASER = 15, ENERGY = 10, BOMB = 40, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) var/list/spores = list() var/mob/living/simple_animal/hostile/blob/blobbernaut/naut = null var/max_spores = 3 diff --git a/code/modules/antagonists/blob/blob/blobs/node.dm b/code/modules/antagonists/blob/blob/blobs/node.dm index 14fbc741c0..75bd668bc5 100644 --- a/code/modules/antagonists/blob/blob/blobs/node.dm +++ b/code/modules/antagonists/blob/blob/blobs/node.dm @@ -4,12 +4,12 @@ icon_state = "blank_blob" desc = "A large, pulsating yellow mass." max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 65, "acid" = 90) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 65, ACID = 90) health_regen = 3 point_return = 25 -/obj/structure/blob/node/Initialize() +/obj/structure/blob/node/Initialize(mapload) GLOB.blob_nodes += src START_PROCESSING(SSobj, src) . = ..() diff --git a/code/modules/antagonists/blob/blob/blobs/resource.dm b/code/modules/antagonists/blob/blob/blobs/resource.dm index 2ed9744327..ea5c6b14a5 100644 --- a/code/modules/antagonists/blob/blob/blobs/resource.dm +++ b/code/modules/antagonists/blob/blob/blobs/resource.dm @@ -5,7 +5,7 @@ desc = "A thin spire of slightly swaying tendrils." max_integrity = 60 point_return = 15 - armor = list("melee" = 10, "bullet" = 10, "laser" = 0, "energy" = 0, "bomb" = 15, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 10, BULLET = 10, LASER = 0, ENERGY = 0, BOMB = 15, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) var/resource_delay = 0 /obj/structure/blob/resource/scannerreport() diff --git a/code/modules/antagonists/blob/blob/blobs/shield.dm b/code/modules/antagonists/blob/blob/blobs/shield.dm index 38e6edc6d4..4dbbeb4708 100644 --- a/code/modules/antagonists/blob/blob/blobs/shield.dm +++ b/code/modules/antagonists/blob/blob/blobs/shield.dm @@ -9,7 +9,7 @@ explosion_block = 3 point_return = 4 atmosblock = TRUE - armor = list("melee" = 25, "bullet" = 25, "laser" = 15, "energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 25, BULLET = 25, LASER = 15, ENERGY = 10, BOMB = 20, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) var/weakened /obj/structure/blob/shield/scannerreport() @@ -28,7 +28,7 @@ desc = "[damaged_desc]" atmosblock = FALSE if(!weakened) - armor = armor.setRating("melee" = 15, "bullet" = 15, "laser" = 5, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = armor.setRating(MELEE = 15, BULLET = 15, LASER = 5, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) weakened = TRUE else icon_state = initial(icon_state) @@ -36,7 +36,7 @@ desc = initial(desc) atmosblock = TRUE if(weakened) - armor = armor.setRating("melee" = 25, "bullet" = 25, "laser" = 15, "energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = armor.setRating(MELEE = 25, BULLET = 25, LASER = 15, ENERGY = 10, BOMB = 20, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) weakened = FALSE air_update_turf(1) diff --git a/code/modules/antagonists/blob/blob/blobstrains/blazing_oil.dm b/code/modules/antagonists/blob/blob/blobstrains/blazing_oil.dm index f97e271e72..be08266687 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/blazing_oil.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/blazing_oil.dm @@ -14,15 +14,15 @@ reagent = /datum/reagent/blob/blazing_oil /datum/blobstrain/reagent/blazing_oil/extinguish_reaction(obj/structure/blob/B) - B.take_damage(1.5, BURN, "energy") + B.take_damage(1.5, BURN, ENERGY) /datum/blobstrain/reagent/blazing_oil/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) - if(damage_type == BURN && damage_flag != "energy") + if(damage_type == BURN && damage_flag != ENERGY) for(var/turf/open/T in range(1, B)) var/obj/structure/blob/C = locate() in T if(!(C && C.overmind && C.overmind.blobstrain.type == B.overmind.blobstrain.type) && prob(80)) new /obj/effect/hotspot(T) - if(damage_flag == "fire") + if(damage_flag == FIRE) return 0 return ..() diff --git a/code/modules/antagonists/blob/blob/blobstrains/electromagnetic_web.dm b/code/modules/antagonists/blob/blob/blobstrains/electromagnetic_web.dm index 7a1715cb4a..f2b00a981e 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/electromagnetic_web.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/electromagnetic_web.dm @@ -17,7 +17,7 @@ return damage * 1.25 //a laser will do 25 damage, which will kill any normal blob /datum/blobstrain/reagent/electromagnetic_web/death_reaction(obj/structure/blob/B, damage_flag) - if(damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") + if(damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) empulse_using_range(B.loc, 5) //less than screen range, so you can stand out of range to avoid it /datum/reagent/blob/electromagnetic_web diff --git a/code/modules/antagonists/blob/blob/blobstrains/energized_jelly.dm b/code/modules/antagonists/blob/blob/blobstrains/energized_jelly.dm index 66ce3c303d..c22b429e1b 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/energized_jelly.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/energized_jelly.dm @@ -10,7 +10,7 @@ reagent = /datum/reagent/blob/energized_jelly /datum/blobstrain/reagent/energized_jelly/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) - if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") && B.obj_integrity - damage <= 0 && prob(10)) + if((damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) && B.obj_integrity - damage <= 0 && prob(10)) do_sparks(rand(2, 4), FALSE, B) return ..() @@ -19,7 +19,7 @@ /datum/blobstrain/reagent/energized_jelly/emp_reaction(obj/structure/blob/B, severity) var/damage = rand(30, 50) - severity * rand(10, 15) - B.take_damage(damage, BURN, "energy") + B.take_damage(damage, BURN, ENERGY) /datum/reagent/blob/energized_jelly name = "Energized Jelly" diff --git a/code/modules/antagonists/blob/blob/blobstrains/explosive_lattice.dm b/code/modules/antagonists/blob/blob/blobstrains/explosive_lattice.dm index 3d005ba913..c805069a9c 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/explosive_lattice.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/explosive_lattice.dm @@ -12,9 +12,9 @@ reagent = /datum/reagent/blob/explosive_lattice /datum/blobstrain/reagent/explosive_lattice/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) - if(damage_flag == "bomb") + if(damage_flag == BOMB) return 0 - else if(damage_flag != "melee" && damage_flag != "bullet" && damage_flag != "laser") + else if(damage_flag != MELEE && damage_flag != BULLET && damage_flag != LASER) return damage * 1.5 return ..() diff --git a/code/modules/antagonists/blob/blob/blobstrains/pressurized_slime.dm b/code/modules/antagonists/blob/blob/blobstrains/pressurized_slime.dm index 11477712e7..6b19ff2257 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/pressurized_slime.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/pressurized_slime.dm @@ -13,12 +13,12 @@ reagent = /datum/reagent/blob/pressurized_slime /datum/blobstrain/reagent/pressurized_slime/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) - if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") || damage_type != BURN) + if((damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) || damage_type != BURN) extinguisharea(B, damage) return ..() /datum/blobstrain/reagent/pressurized_slime/death_reaction(obj/structure/blob/B, damage_flag) - if(damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") + if(damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) B.visible_message("The blob ruptures, spraying the area with liquid!") extinguisharea(B, 50) diff --git a/code/modules/antagonists/blob/blob/blobstrains/reactive_spines.dm b/code/modules/antagonists/blob/blob/blobstrains/reactive_spines.dm index fca56d1402..84ff383dd1 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/reactive_spines.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/reactive_spines.dm @@ -13,7 +13,7 @@ /datum/blobstrain/reagent/reactive_spines/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) if(damage && damage_type == BRUTE && B.obj_integrity - damage > 0) //is there any damage, is it brute, and will we be alive - if(damage_flag == "melee") + if(damage_flag == MELEE) B.visible_message("The blob retaliates, lashing out!") for(var/atom/A in range(1, B)) A.blob_act(B) diff --git a/code/modules/antagonists/blob/blob/blobstrains/shifting_fragments.dm b/code/modules/antagonists/blob/blob/blobstrains/shifting_fragments.dm index 9265158e1b..d4930a9a61 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/shifting_fragments.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/shifting_fragments.dm @@ -14,7 +14,7 @@ B.forceMove(T) /datum/blobstrain/reagent/shifting_fragments/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) - if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") && damage > 0 && B.obj_integrity - damage > 0 && prob(60-damage)) + if((damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) && damage > 0 && B.obj_integrity - damage > 0 && prob(60-damage)) var/list/blobstopick = list() for(var/obj/structure/blob/OB in orange(1, B)) if((istype(OB, /obj/structure/blob/normal) || (istype(OB, /obj/structure/blob/shield) && prob(25))) && OB.overmind && OB.overmind.blobstrain.type == B.overmind.blobstrain.type) diff --git a/code/modules/antagonists/blob/blob/blobstrains/synchronous_mesh.dm b/code/modules/antagonists/blob/blob/blobstrains/synchronous_mesh.dm index daad0068e2..ad6b36cf42 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/synchronous_mesh.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/synchronous_mesh.dm @@ -11,7 +11,7 @@ message = "The blobs strike you" /datum/blobstrain/reagent/synchronous_mesh/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) - if(damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") //the cause isn't fire or bombs, so split the damage + if(damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) //the cause isn't fire or bombs, so split the damage var/damagesplit = 1 //maximum split is 9, reducing the damage each blob takes to 11% but doing that damage to 9 blobs for(var/obj/structure/blob/C in orange(1, B)) if(!istype(C, /obj/structure/blob/core) && !istype(C, /obj/structure/blob/node) && C.overmind && C.overmind.blobstrain.type == B.overmind.blobstrain.type) //if it doesn't have the same chemical or is a core or node, don't split damage to it diff --git a/code/modules/antagonists/blob/blob/blobstrains/zombifying_pods.dm b/code/modules/antagonists/blob/blob/blobstrains/zombifying_pods.dm index b2bb9d5115..6fba19b487 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/zombifying_pods.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/zombifying_pods.dm @@ -12,7 +12,7 @@ reagent = /datum/reagent/blob/zombifying_pods /datum/blobstrain/reagent/zombifying_pods/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) - if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") && damage <= 20 && B.obj_integrity - damage <= 0 && prob(30)) //if the cause isn't fire or a bomb, the damage is less than 21, we're going to die from that damage, 20% chance of a shitty spore. + if((damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) && damage <= 20 && B.obj_integrity - damage <= 0 && prob(30)) //if the cause isn't fire or a bomb, the damage is less than 21, we're going to die from that damage, 20% chance of a shitty spore. B.visible_message("A spore floats free of the blob!") var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(B.loc) BS.overmind = B.overmind diff --git a/code/modules/antagonists/blob/blob/theblob.dm b/code/modules/antagonists/blob/blob/theblob.dm index a95f73f90d..ff6eab264b 100644 --- a/code/modules/antagonists/blob/blob/theblob.dm +++ b/code/modules/antagonists/blob/blob/theblob.dm @@ -4,14 +4,15 @@ icon = 'icons/mob/blob.dmi' light_range = 2 desc = "A thick wall of writhing tendrils." - density = FALSE //this being false causes two bugs, being able to attack blob tiles behind other blobs and being unable to move on blob tiles in no gravity, but turning it to 1 causes the blob mobs to be unable to path through blobs, which is probably worse. + density = TRUE opacity = 0 anchored = TRUE layer = BELOW_MOB_LAYER + pass_flags_self = PASSBLOB CanAtmosPass = ATMOS_PASS_PROC var/point_return = 0 //How many points the blob gets back when it removes a blob of that type. If less than 0, blob cannot be removed. max_integrity = 30 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 70) var/health_regen = 2 //how much health this blob regens when pulsed var/pulse_timestamp = 0 //we got pulsed when? var/heal_timestamp = 0 //we got healed when? @@ -67,19 +68,13 @@ /obj/structure/blob/BlockThermalConductivity() return atmosblock -/obj/structure/blob/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSBLOB)) - return 1 - return 0 - /obj/structure/blob/CanAtmosPass(turf/T) return !atmosblock -/obj/structure/blob/CanAStarPass(ID, dir, caller) - . = 0 - if(ismovable(caller)) - var/atom/movable/mover = caller - . = . || (mover.pass_flags & PASSBLOB) +/obj/structure/blob/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller) + . = FALSE + if(istype(caller)) + . = . || (caller.pass_flags & PASSBLOB) /obj/structure/blob/update_icon() //Updates color based on overmind color if we have an overmind. if(overmind) @@ -211,9 +206,9 @@ . = ..() if(overmind) if(overmind.blobstrain.tesla_reaction(src, power)) - take_damage(power/400, BURN, "energy") + take_damage(power/400, BURN, ENERGY) else - take_damage(power/400, BURN, "energy") + take_damage(power/400, BURN, ENERGY) /obj/structure/blob/extinguish() ..() diff --git a/code/modules/antagonists/bloodsucker/bloodsucker_life.dm b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm index 29e64a4913..c5f1cfbb40 100644 --- a/code/modules/antagonists/bloodsucker/bloodsucker_life.dm +++ b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm @@ -84,7 +84,7 @@ return FALSE if(owner.current.reagents.has_reagent(/datum/reagent/consumable/garlic)) return FALSE - if(istype(owner.current.get_item_by_slot(SLOT_NECK), /obj/item/clothing/neck/garlic_necklace)) + if(istype(owner.current.get_item_by_slot(ITEM_SLOT_NECK), /obj/item/clothing/neck/garlic_necklace)) return FALSE owner.current.adjustStaminaLoss(-1.5 + (actual_regen * -7) * mult, 0) // Humans lose stamina damage really quickly. Vamps should heal more. owner.current.adjustCloneLoss(-0.1 * (actual_regen * 2) * mult, 0) diff --git a/code/modules/antagonists/bloodsucker/bloodsucker_powers.dm b/code/modules/antagonists/bloodsucker/bloodsucker_powers.dm index 2fb7a2ccca..0a799021e9 100644 --- a/code/modules/antagonists/bloodsucker/bloodsucker_powers.dm +++ b/code/modules/antagonists/bloodsucker/bloodsucker_powers.dm @@ -94,7 +94,7 @@ if(display_error) to_chat(owner, "You have a stake in your chest! Your powers are useless.") return FALSE - if(istype(owner.get_item_by_slot(SLOT_NECK), /obj/item/clothing/neck/garlic_necklace)) + if(istype(owner.get_item_by_slot(ITEM_SLOT_NECK), /obj/item/clothing/neck/garlic_necklace)) if(display_error) to_chat(owner, "") return FALSE diff --git a/code/modules/antagonists/bloodsucker/bloodsucker_sunlight.dm b/code/modules/antagonists/bloodsucker/bloodsucker_sunlight.dm index f26152f90e..a86cb374d2 100644 --- a/code/modules/antagonists/bloodsucker/bloodsucker_sunlight.dm +++ b/code/modules/antagonists/bloodsucker/bloodsucker_sunlight.dm @@ -12,7 +12,7 @@ var/nighttime_duration = 900 //15 Minutes var/issued_XP = FALSE -/obj/effect/sunlight/Initialize() +/obj/effect/sunlight/Initialize(mapload) . = ..() /obj/effect/sunlight/proc/start_countdown() diff --git a/code/modules/antagonists/bloodsucker/items/bloodsucker_stake.dm b/code/modules/antagonists/bloodsucker/items/bloodsucker_stake.dm index 69410027a4..06eabd4739 100644 --- a/code/modules/antagonists/bloodsucker/items/bloodsucker_stake.dm +++ b/code/modules/antagonists/bloodsucker/items/bloodsucker_stake.dm @@ -66,6 +66,7 @@ /obj/item/stake/afterattack(atom/target, mob/user, proximity) //to_chat(world, "DEBUG: Staking ") // Invalid Target, or not targetting chest with HARM intent? + . = ..() if(!iscarbon(target) || check_zone(user.zone_selected) != "chest" || user.a_intent != INTENT_HARM) return var/mob/living/carbon/C = target @@ -80,7 +81,7 @@ // Make Attempt... to_chat(user, "You put all your weight into embedding the stake into [target]'s chest...") playsound(user, 'sound/magic/Demon_consume.ogg', 50, 1) - if(!do_mob(user, C, staketime, 0, 1, extra_checks=CALLBACK(C, /mob/living/carbon/proc/can_be_staked))) // user / target / time / uninterruptable / show progress bar / extra checks + if(!do_mob(user, C, staketime, NONE, extra_checks=CALLBACK(C, /mob/living/carbon/proc/can_be_staked))) // user / target / time / uninterruptable / show progress bar / extra checks return // Drop & Embed Stake user.visible_message("[user.name] drives the [src] into [target]'s chest!", \ @@ -139,9 +140,8 @@ // Convert back to Silver /obj/item/stake/hardened/silver/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/weldingtool)) - var/obj/item/weldingtool/WT = I - if(WT.use(0))//remove_fuel(0, user)) + if(I.tool_behaviour == TOOL_WELDER) + if(I.use(0))//remove_fuel(0, user)) var/obj/item/stack/sheet/mineral/silver/newsheet = new (user.loc) for(var/obj/item/stack/sheet/mineral/silver/S in user.loc) if(S == newsheet) diff --git a/code/modules/antagonists/bloodsucker/objects/bloodsucker_coffin.dm b/code/modules/antagonists/bloodsucker/objects/bloodsucker_coffin.dm index 881da8f282..d58190cf66 100644 --- a/code/modules/antagonists/bloodsucker/objects/bloodsucker_coffin.dm +++ b/code/modules/antagonists/bloodsucker/objects/bloodsucker_coffin.dm @@ -54,7 +54,7 @@ resistance_flags = NONE max_integrity = 100 integrity_failure = 0.5 - armor = list("melee" = 50, "bullet" = 20, "laser" = 30, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 60) + armor = list(MELEE = 50, BULLET = 20, LASER = 30, ENERGY = 0, BOMB = 50, BIO = 0, RAD = 0, FIRE = 70, ACID = 60) /obj/structure/closet/crate/coffin/meatcoffin name = "meat coffin" @@ -69,7 +69,7 @@ material_drop = /obj/item/reagent_containers/food/snacks/meat/slab material_drop_amount = 3 integrity_failure = 0.57 - armor = list("melee" = 70, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100) + armor = list(MELEE = 70, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 70, BIO = 0, RAD = 0, FIRE = 70, ACID = 100) /obj/structure/closet/crate/coffin/metalcoffin name = "metal coffin" @@ -85,7 +85,7 @@ material_drop_amount = 5 max_integrity = 200 integrity_failure = 0.25 - armor = list("melee" = 40, "bullet" = 15, "laser" = 50, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 60) + armor = list(MELEE = 40, BULLET = 15, LASER = 50, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 70, ACID = 60) ////////////////////////////////////////////// diff --git a/code/modules/antagonists/bloodsucker/powers/brawn.dm b/code/modules/antagonists/bloodsucker/powers/brawn.dm index 5444cccd3f..db3ce92ec1 100644 --- a/code/modules/antagonists/bloodsucker/powers/brawn.dm +++ b/code/modules/antagonists/bloodsucker/powers/brawn.dm @@ -105,7 +105,7 @@ var/mob/living/carbon/user_C = owner //message_admins("DEBUG3: attempt_cast() [name] / [user_C.handcuffed] ") if(user_C.handcuffed) - var/obj/O = user_C.get_item_by_slot(SLOT_HANDCUFFED) + var/obj/O = user_C.get_item_by_slot(ITEM_SLOT_HANDCUFFED) if(istype(O)) user_C.clear_cuffs(O,TRUE) playsound(get_turf(usr), 'sound/effects/grillehit.ogg', 80, 1, -1) @@ -124,7 +124,7 @@ return TRUE */ // Destroy Leg Cuffs if(user_C.legcuffed) - var/obj/O = user_C.get_item_by_slot(SLOT_LEGCUFFED) + var/obj/O = user_C.get_item_by_slot(ITEM_SLOT_LEGCUFFED) if(istype(O)) user_C.clear_cuffs(O,TRUE) playsound(get_turf(usr), 'sound/effects/grillehit.ogg', 80, 1, -1) diff --git a/code/modules/antagonists/bloodsucker/powers/feed.dm b/code/modules/antagonists/bloodsucker/powers/feed.dm index 81ebdbe4e2..a4bdcfee54 100644 --- a/code/modules/antagonists/bloodsucker/powers/feed.dm +++ b/code/modules/antagonists/bloodsucker/powers/feed.dm @@ -146,7 +146,7 @@ to_chat(user, "You lean quietly toward [target] and secretly draw out your fangs...") else to_chat(user, "You pull [target] close to you and draw out your fangs...") - if(!do_mob(user, target, feed_time, 0, 1, extra_checks = CALLBACK(src, .proc/ContinueActive, user, target)))//sleep(10) + if(!do_mob(user, target, feed_time, NONE, extra_checks = CALLBACK(src, .proc/ContinueActive, user, target)))//sleep(10) to_chat(user, "Your feeding was interrupted.") //DeactivatePower(user,target) return @@ -207,7 +207,7 @@ //user.mobility_flags &= ~MOBILITY_MOVE // user.canmove = 0 // Prevents spilling blood accidentally. // Abort? A bloody mistake. - if(!do_mob(user, target, 20, 0, 0, extra_checks=CALLBACK(src, .proc/ContinueActive, user, target))) + if(!do_mob(user, target, 2 SECONDS, NONE, extra_checks=CALLBACK(src, .proc/ContinueActive, user, target))) // May have disabled Feed during do_mob if(!active || !ContinueActive(user, target)) break diff --git a/code/modules/antagonists/bloodsucker/powers/mesmerize.dm b/code/modules/antagonists/bloodsucker/powers/mesmerize.dm index efdd312c6e..25f50d7af4 100644 --- a/code/modules/antagonists/bloodsucker/powers/mesmerize.dm +++ b/code/modules/antagonists/bloodsucker/powers/mesmerize.dm @@ -2,7 +2,7 @@ // * MEZMERIZE // LOVE: Target falls in love with you. Being harmed directly causes them harm if they see it? // STAY: Target will do everything they can to stand in the same place. -// FOLLOW: Target follows you, spouting random phrases from their history (or maybe Poly's or NPC's vocab?) +// FOLLOW: Target follows you, spouting random phrases from their history (or maybe Polly's or NPC's vocab?) // ATTACK: Target finds a nearby non-Bloodsucker victim to attack. /datum/action/bloodsucker/targeted/mesmerize diff --git a/code/modules/antagonists/brainwashing/brainwashing.dm b/code/modules/antagonists/brainwashing/brainwashing.dm index 491ee9d2e5..65c58611cb 100644 --- a/code/modules/antagonists/brainwashing/brainwashing.dm +++ b/code/modules/antagonists/brainwashing/brainwashing.dm @@ -17,11 +17,13 @@ B.objectives += objective M.add_antag_datum(B) - var/begin_message = "[L] has been brainwashed with the following objectives: " + var/begin_message = " has been brainwashed with the following objectives: " var/obj_message = english_list(directives) - var/end_message = "
    ." + var/end_message = "." var/rendered = begin_message + obj_message + end_message - deadchat_broadcast(rendered, follow_target = L, turf_target = get_turf(L), message_type=DEADCHAT_REGULAR) + deadchat_broadcast(rendered, "[L]", follow_target = L, turf_target = get_turf(L), message_type=DEADCHAT_ANNOUNCEMENT) + if(prob(1) || SSevents.holidays && SSevents.holidays[APRIL_FOOLS]) + L.say("You son of a bitch! I'm in.", forced = "That son of a bitch! They're in.") /datum/antagonist/brainwashed name = "Brainwashed Victim" @@ -30,19 +32,21 @@ show_in_antagpanel = TRUE antagpanel_category = "Other" show_name_in_check_antagonists = TRUE + ui_name = "AntagInfoBrainwashed" + suicide_cry = "FOR... SOMEONE!!" -/datum/antagonist/brainwashed/greet() - to_chat(owner, "Your mind reels as it begins focusing on a single purpose...") - to_chat(owner, "Follow the Directives, at any cost!") - var/i = 1 - for(var/X in objectives) - var/datum/objective/O = X - to_chat(owner, "[i]. [O.explanation_text]") - i++ +/datum/antagonist/brainwashed/ui_static_data(mob/user) + . = ..() + var/list/data = list() + data["objectives"] = get_objectives() + return data /datum/antagonist/brainwashed/farewell() - to_chat(owner, "Your mind suddenly clears...") - to_chat(owner, "You feel the weight of the Directives disappear! You no longer have to obey them.") + to_chat(owner, span_warning("Your mind suddenly clears...")) + to_chat(owner, "[span_warning("You feel the weight of the Directives disappear! You no longer have to obey them.")]") + if(owner.current) + var/mob/living/owner_mob = owner.current + owner_mob.log_message("is no longer brainwashed with the objectives: [english_list(objectives)].", LOG_ATTACK) owner.announce_objectives() /datum/antagonist/brainwashed/admin_add(datum/mind/new_owner,mob/admin) @@ -54,9 +58,9 @@ var/objective = stripped_input(admin, "Add an objective, or leave empty to finish.", "Brainwashing", null, MAX_MESSAGE_LEN) if(objective) objectives += objective - while(alert(admin,"Add another objective?","More Brainwashing","Yes","No") == "Yes") + while(tgui_alert(admin,"Add another objective?","More Brainwashing",list("Yes","No")) == "Yes") - if(alert(admin,"Confirm Brainwashing?","Are you sure?","Yes","No") == "No") + if(tgui_alert(admin,"Confirm Brainwashing?","Are you sure?",list("Yes","No")) == "No") return if(!LAZYLEN(objectives)) @@ -69,6 +73,7 @@ brainwash(C, objectives) var/obj_list = english_list(objectives) message_admins("[key_name_admin(admin)] has brainwashed [key_name_admin(C)] with the following objectives: [obj_list].") + C.log_message("has been force-brainwashed with the objective '[obj_list]' by admin [key_name(admin)]", LOG_VICTIM) log_admin("[key_name(admin)] has brainwashed [key_name(C)] with the following objectives: [obj_list].") /datum/objective/brainwashing diff --git a/code/modules/antagonists/changeling/cellular_emporium.dm b/code/modules/antagonists/changeling/cellular_emporium.dm index 2538394db7..d825fa048e 100644 --- a/code/modules/antagonists/changeling/cellular_emporium.dm +++ b/code/modules/antagonists/changeling/cellular_emporium.dm @@ -25,7 +25,7 @@ /datum/cellular_emporium/ui_data(mob/user) var/list/data = list() - var/can_readapt = changeling.canrespec + var/can_readapt = changeling.can_respec var/genetic_points_remaining = changeling.geneticpoints var/absorbed_dna_count = changeling.absorbedcount var/true_absorbs = changeling.trueabsorbs @@ -37,7 +37,7 @@ var/list/abilities = list() for(var/path in changeling.all_powers) - var/obj/effect/proc_holder/changeling/ability = path + var/datum/action/changeling/ability = path var/dna_cost = initial(ability.dna_cost) if(dna_cost <= 0) @@ -65,7 +65,7 @@ switch(action) if("readapt") - if(changeling.canrespec) + if(changeling.can_respec) changeling.readapt() if("evolve") var/sting_name = params["name"] @@ -75,7 +75,7 @@ name = "Cellular Emporium" icon_icon = 'icons/obj/drinks.dmi' button_icon_state = "changelingsting" - background_icon_state = "bg_ling" + background_icon_state = "bg_changeling" var/datum/cellular_emporium/cellular_emporium /datum/action/innate/cellular_emporium/New(our_target) diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 8e6b5c9060..b92722eb8f 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -2,6 +2,9 @@ #define LING_DEAD_GENETICDAMAGE_HEAL_CAP 50 //The lowest value of geneticdamage handle_changeling() can take it to while dead. #define LING_ABSORB_RECENT_SPEECH 8 //The amount of recent spoken lines to gain on absorbing a mob +/// Helper to format the text that gets thrown onto the chem hud element. +#define FORMAT_CHEM_CHARGES_TEXT(charges) MAPTEXT("
    [round(charges)]
    ") + /datum/antagonist/changeling name = "Changeling" roundend_category = "changelings" @@ -34,19 +37,19 @@ var/geneticpoints = 10 var/maxgeneticpoints = 10 var/purchasedpowers = list() + var/mimicing = "" - var/canrespec = 0 + var/can_respec = FALSE//set to TRUE in absorb.dm var/changeling_speak = 0 var/loudfactor = 0 //Used for blood tests. This is is the average loudness of the ling's abilities calculated with the below two vars var/loudtotal = 0 //Used to keep track of the sum of the ling's loudness var/totalpurchases = 0 //Used to keep track of how many purchases the ling's made after free abilities have been added var/datum/dna/chosen_dna - var/obj/effect/proc_holder/changeling/sting/chosen_sting + var/datum/action/changeling/sting/chosen_sting var/datum/cellular_emporium/cellular_emporium var/datum/action/innate/cellular_emporium/emporium_action - // wip stuff - var/static/list/all_powers = typecacheof(/obj/effect/proc_holder/changeling,TRUE) + var/static/list/all_powers = typecacheof(/datum/action/changeling,TRUE) /datum/antagonist/changeling/Destroy() @@ -72,6 +75,7 @@ /datum/antagonist/changeling/proc/create_actions() cellular_emporium = new(src) emporium_action = new(cellular_emporium) + emporium_action.Grant(owner.current) /datum/antagonist/changeling/on_gain() generate_name() @@ -127,11 +131,9 @@ reset_properties() QDEL_NULL(cellular_emporium) QDEL_NULL(emporium_action) - for(var/obj/effect/proc_holder/changeling/p in purchasedpowers) - if(p.always_keep) - continue + for(var/datum/action/changeling/p in purchasedpowers) purchasedpowers -= p - p.on_refund(owner.current) + p.Remove(owner.current) //MOVE THIS if(owner.current.hud_used) @@ -144,7 +146,7 @@ create_actions() //Repurchase free powers. for(var/path in all_powers) - var/obj/effect/proc_holder/changeling/S = new path() + var/datum/action/changeling/S = new path() if(!S.dna_cost) if(!has_sting(S)) purchasedpowers += S @@ -153,20 +155,28 @@ loudtotal = 0 totalpurchases = 0 -/datum/antagonist/changeling/proc/has_sting(obj/effect/proc_holder/changeling/power) - for(var/obj/effect/proc_holder/changeling/P in purchasedpowers) - if(initial(power.name) == P.name) +/datum/antagonist/changeling/proc/regain_powers()//for when action buttons are lost and need to be regained, such as when the mind enters a new mob + emporium_action.Grant(owner.current) + for(var/power in purchasedpowers) + var/datum/action/changeling/S = power + if(istype(S) && S.needs_button) + S.Grant(owner.current) + +/datum/antagonist/changeling/proc/has_sting(datum/action/changeling/power) + for(var/P in purchasedpowers) + var/datum/action/changeling/otherpower = P + if(initial(power.name) == otherpower.name) return TRUE return FALSE /datum/antagonist/changeling/proc/purchase_power(sting_name) - var/obj/effect/proc_holder/changeling/thepower = null + var/datum/action/changeling/thepower for(var/path in all_powers) - var/obj/effect/proc_holder/changeling/S = path + var/datum/action/changeling/S = path if(initial(S.name) == sting_name) - thepower = new path() + thepower = new path break if(!thepower) @@ -195,7 +205,7 @@ geneticpoints -= thepower.dna_cost purchasedpowers += thepower - thepower.on_purchase(owner.current) + thepower.on_purchase(owner.current)//Grant() is ran in this proc, see changeling_powers.dm loudtotal += thepower.loudness totalpurchases++ var/oldloudness = loudfactor @@ -213,11 +223,11 @@ if(!ishuman(owner.current)) to_chat(owner.current, "We can't remove our evolutions in this form!") return - if(canrespec) + if(can_respec) to_chat(owner.current, "We have removed our evolutions from this form, and are now ready to readapt.") reset_powers() playsound(get_turf(owner.current), 'sound/effects/lingreadapt.ogg', 75, TRUE, 5) - canrespec = 0 + can_respec = 0 SSblackbox.record_feedback("tally", "changeling_power_purchase", 1, "Readapt") return 1 else @@ -225,11 +235,9 @@ return 0 //Called in life() -/datum/antagonist/changeling/proc/regenerate() +/datum/antagonist/changeling/proc/regenerate()//grants the HuD in life.dm var/mob/living/carbon/the_ling = owner.current if(istype(the_ling)) - if(emporium_action) - emporium_action.Grant(the_ling) if(the_ling.stat == DEAD) chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), (chem_storage*0.5)) geneticdamage = max(LING_DEAD_GENETICDAMAGE_HEAL_CAP,geneticdamage-1) @@ -237,7 +245,7 @@ chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), chem_storage) geneticdamage = max(0, geneticdamage-1) owner.current.hud_used?.lingchemdisplay?.invisibility = 0 - owner.current.hud_used?.lingchemdisplay?.maptext = "
    [round(chem_charges)]
    " + owner.current.hud_used?.lingchemdisplay?.maptext = FORMAT_CHEM_CHARGES_TEXT(chem_charges) /datum/antagonist/changeling/proc/get_dna(dna_owner) diff --git a/code/modules/antagonists/changeling/changeling_power.dm b/code/modules/antagonists/changeling/changeling_power.dm index aa45c56892..c784939c0f 100644 --- a/code/modules/antagonists/changeling/changeling_power.dm +++ b/code/modules/antagonists/changeling/changeling_power.dm @@ -1,39 +1,42 @@ /* - * Don't use the apostrophe in name or desc. Causes script errors. - * TODO: combine atleast some of the functionality with /proc_holder/spell + * Don't use the apostrophe in name or desc. Causes script errors.//probably no longer true */ -/obj/effect/proc_holder/changeling - panel = "Changeling" - name = "Prototype Sting" - desc = "" // Fluff +/datum/action/changeling + name = "Prototype Sting - Debug button, ahelp this" + background_icon_state = "bg_changeling" + icon_icon = 'icons/mob/actions/actions_changeling.dmi' + var/needs_button = TRUE//for passive abilities like hivemind that dont need a button var/helptext = "" // Details var/chemical_cost = 0 // negative chemical cost is for passive abilities (chemical glands) - var/dna_cost = -1 //cost of the sting in dna points. 0 = auto-purchase, -1 = cannot be purchased + var/dna_cost = -1 //cost of the sting in dna points. 0 = auto-purchase (see changeling.dm), -1 = cannot be purchased var/req_dna = 0 //amount of dna needed to use this ability. Changelings always have atleast 1 var/req_human = 0 //if you need to be human to use this ability var/req_absorbs = 0 //similar to req_dna, but only gained from absorbing, not DNA sting var/req_stat = CONSCIOUS // CONSCIOUS, UNCONSCIOUS or DEAD - var/always_keep = 0 // important for abilities like revive that screw you if you lose them. var/ignores_fakedeath = FALSE // usable with the FAKEDEATH flag - var/loudness = 0 //Determines how much having this ability will affect changeling blood tests. At 4, the blood will react violently and turn to ash, creating a unique message in the process. At 10, the blood will explode when heated. + var/loudness = 0.5 //Determines how much having this ability will affect changeling blood tests. This is averaged with other purchased abilities. Above 1, the blood will react violently and turn to ash, creating a unique message in the process. Above 2, the blood will explode when heated. + var/active = FALSE//used by a few powers that toggle +/* +changeling code now relies on on_purchase to grant powers. +if you override it, MAKE SURE you call parent or it will not be usable +the same goes for Remove(). if you override Remove(), call parent or else your power wont be removed on respec +*/ -/obj/effect/proc_holder/changeling/proc/on_purchase(mob/user, is_respec) - action.Grant(user) +/datum/action/changeling/proc/on_purchase(mob/user, is_respec) if(!is_respec) SSblackbox.record_feedback("tally", "changeling_power_purchase", 1, name) + if(needs_button) + Grant(user)//how powers are added rather than the checks in mob.dm -/obj/effect/proc_holder/changeling/proc/on_refund(mob/user) - action.Remove(user) - return - -/obj/effect/proc_holder/changeling/Trigger(mob/user) +/datum/action/changeling/Trigger() + var/mob/user = owner if(!user || !user.mind || !user.mind.has_antag_datum(/datum/antagonist/changeling)) return try_to_sting(user) -/obj/effect/proc_holder/changeling/proc/try_to_sting(mob/user, mob/target) +/datum/action/changeling/proc/try_to_sting(mob/user, mob/target) if(!can_sting(user, target)) return var/datum/antagonist/changeling/c = user.mind.has_antag_datum(/datum/antagonist/changeling) @@ -42,39 +45,41 @@ sting_feedback(user, target) c.chem_charges -= chemical_cost -/obj/effect/proc_holder/changeling/proc/sting_action(mob/user, mob/target) +/datum/action/changeling/proc/sting_action(mob/user, mob/target) + SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]")) return 0 -/obj/effect/proc_holder/changeling/proc/sting_feedback(mob/user, mob/target) +/datum/action/changeling/proc/sting_feedback(mob/user, mob/target) return 0 -//Fairly important to remember to return 1 on success >.< -/obj/effect/proc_holder/changeling/proc/can_sting(mob/living/user, mob/target) +//Fairly important to remember to return TRUE on success >.< + +/datum/action/changeling/proc/can_sting(mob/living/user, mob/target) if(!ishuman(user) && !ismonkey(user)) //typecast everything from mob to carbon from this point onwards - return 0 + return FALSE if(req_human && !ishuman(user)) to_chat(user, "We cannot do that in this form!") - return 0 + return FALSE var/datum/antagonist/changeling/c = user.mind.has_antag_datum(/datum/antagonist/changeling) if(c.chem_charges < chemical_cost) to_chat(user, "We require at least [chemical_cost] unit\s of chemicals to do that!") - return 0 + return FALSE if(c.absorbedcount < req_dna) to_chat(user, "We require at least [req_dna] sample\s of compatible DNA.") - return 0 + return FALSE if(c.trueabsorbs < req_absorbs) to_chat(user, "We require at least [req_absorbs] sample\s of DNA gained through our Absorb ability.") if(req_stat < user.stat) to_chat(user, "We are incapacitated.") - return 0 + return FALSE if((HAS_TRAIT(user, TRAIT_DEATHCOMA)) && (!ignores_fakedeath)) to_chat(user, "We are incapacitated.") - return 0 - return 1 + return FALSE + return TRUE //used in /mob/Stat() -/obj/effect/proc_holder/changeling/proc/can_be_used_by(mob/user) - if(QDELETED(user)) +/datum/action/changeling/proc/can_be_used_by(mob/user) + if(!user || QDELETED(user)) return FALSE if(!ishuman(user) && !ismonkey(user)) return FALSE diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm index 208fefee70..00d99ea4c9 100644 --- a/code/modules/antagonists/changeling/powers/absorb.dm +++ b/code/modules/antagonists/changeling/powers/absorb.dm @@ -1,14 +1,11 @@ -/obj/effect/proc_holder/changeling/absorbDNA +/datum/action/changeling/absorbDNA name = "Absorb DNA" - desc = "Absorb the DNA of our victim." - chemical_cost = 0 + desc = "Absorb the DNA of our victim. Requires us to strangle them." + button_icon_state = "absorb_dna" dna_cost = 0 - req_human = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_absorb_dna" - action_background_icon_state = "bg_ling" + req_human = TRUE -/obj/effect/proc_holder/changeling/absorbDNA/can_sting(mob/living/carbon/user) +/datum/action/changeling/absorbDNA/can_sting(mob/living/carbon/user) if(!..()) return @@ -29,7 +26,7 @@ -/obj/effect/proc_holder/changeling/absorbDNA/sting_action(mob/user) +/datum/action/changeling/absorbDNA/sting_action(mob/user) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) var/mob/living/carbon/human/target = user.pulling changeling.isabsorbing = 1 @@ -65,7 +62,9 @@ user.copy_languages(target, LANGUAGE_ABSORB) if(target.mind && user.mind)//if the victim and user have minds - target.mind.show_memory(user, 0) //I can read your mind, kekeke. Output all their notes. +//ambition start + to_chat(user, "[target.mind.show_memory()]") //I can read your mind, kekeke. Output all their notes. +//ambition end //Some of target's recent speech, so the changeling can attempt to imitate them better. //Recent as opposed to all because rounds tend to have a LOT of text. @@ -98,7 +97,7 @@ changeling.geneticpoints += round(target_ling.geneticpoints/2) changeling.maxgeneticpoints += round(target_ling.geneticpoints/2) target_ling.geneticpoints = 0 - target_ling.canrespec = 0 + target_ling.can_respec = 0 changeling.chem_storage += round(target_ling.chem_storage/2) changeling.chem_charges += min(target_ling.chem_charges, changeling.chem_storage) target_ling.chem_charges = 0 @@ -112,7 +111,7 @@ changeling.chem_charges=min(changeling.chem_charges+10, changeling.chem_storage) changeling.isabsorbing = 0 - changeling.canrespec = 1 + changeling.can_respec = 1 target.death(0) target.Drain() diff --git a/code/modules/antagonists/changeling/powers/adrenaline.dm b/code/modules/antagonists/changeling/powers/adrenaline.dm index 643458d05a..7c58b65eb5 100644 --- a/code/modules/antagonists/changeling/powers/adrenaline.dm +++ b/code/modules/antagonists/changeling/powers/adrenaline.dm @@ -1,17 +1,15 @@ -/obj/effect/proc_holder/changeling/adrenaline +/datum/action/changeling/adrenaline name = "Adrenaline Sacs" - desc = "We evolve additional sacs of adrenaline throughout our body." + desc = "We evolve additional sacs of adrenaline throughout our body. Costs 30 chemicals." helptext = "Removes all stuns instantly and adds a short-term reduction in further stuns. Can be used while unconscious. Continued use poisons the body. This ability is loud, and might cause our blood to react violently to heat." + button_icon_state = "adrenaline" chemical_cost = 30 loudness = 2 dna_cost = 2 - req_human = 1 + req_human = TRUE req_stat = UNCONSCIOUS - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_adrenals" - action_background_icon_state = "bg_ling" //Recover from stuns. -/obj/effect/proc_holder/changeling/adrenaline/sting_action(mob/living/user) +/datum/action/changeling/adrenaline/sting_action(mob/living/user) user.do_adrenaline(0, FALSE, 70, 0, TRUE, list(/datum/reagent/medicine/epinephrine = 3, /datum/reagent/medicine/changelinghaste = 10, /datum/reagent/medicine/changelingadrenaline = 5), "Energy rushes through us.", 0, 0.75, 0) return TRUE diff --git a/code/modules/antagonists/changeling/powers/augmented_eyesight.dm b/code/modules/antagonists/changeling/powers/augmented_eyesight.dm index a6fdf7008a..b3ac83f62f 100644 --- a/code/modules/antagonists/changeling/powers/augmented_eyesight.dm +++ b/code/modules/antagonists/changeling/powers/augmented_eyesight.dm @@ -1,27 +1,24 @@ //Augmented Eyesight: Gives you X-ray vision or protection from flashes. Also, high DNA cost because of how powerful it is. //Possible todo: make a custom message for directing a penlight/flashlight at the eyes - not sure what would display though. -/obj/effect/proc_holder/changeling/augmented_eyesight +/datum/action/changeling/augmented_eyesight name = "Augmented Eyesight" desc = "Creates heat receptors in our eyes and dramatically increases light sensing ability, or protects your vision from flashes." helptext = "Grants us thermal vision or flash protection. We will become a lot more vulnerable to flash-based devices while thermal vision is active." - chemical_cost = 0 + button_icon_state = "augmented_eyesight" dna_cost = 2 //Would be 1 without thermal vision active = FALSE - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_augmented_eyesight" - action_background_icon_state = "bg_ling" -/obj/effect/proc_holder/changeling/augmented_eyesight/on_purchase(mob/user) //The ability starts inactive, so we should be protected from flashes. +/datum/action/changeling/augmented_eyesight/on_purchase(mob/user) //The ability starts inactive, so we should be protected from flashes. + ..() var/obj/item/organ/eyes/E = user.getorganslot(ORGAN_SLOT_EYES) if (E) E.flash_protect = 2 //Adjust the user's eyes' flash protection to_chat(user, "We adjust our eyes to protect them from bright lights.") - action.Grant(user) else to_chat(user, "We can't adjust our eyes if we don't have any!") -/obj/effect/proc_holder/changeling/augmented_eyesight/sting_action(mob/living/carbon/human/user) +/datum/action/changeling/augmented_eyesight/sting_action(mob/living/carbon/human/user) if(!istype(user)) return var/obj/item/organ/eyes/E = user.getorganslot(ORGAN_SLOT_EYES) @@ -39,16 +36,13 @@ user.update_sight() else to_chat(user, "We can't adjust our eyes if we don't have any!") + return TRUE - - return 1 - - -/obj/effect/proc_holder/changeling/augmented_eyesight/on_refund(mob/user) //Get rid of X-ray vision and flash protection when the user refunds this ability - action.Remove(user) +/datum/action/changeling/augmented_eyesight/Remove(mob/user) //Get rid of x-ray vision and flash protection when the user refunds this ability REMOVE_TRAIT(user, TRAIT_THERMAL_VISION, CHANGELING_TRAIT) var/obj/item/organ/eyes/E = user.getorganslot(ORGAN_SLOT_EYES) if(E) E.flash_protect = initial(E.flash_protect) user.update_sight() + ..() diff --git a/code/modules/antagonists/changeling/powers/biodegrade.dm b/code/modules/antagonists/changeling/powers/biodegrade.dm index 8b3b1659d1..1ca2f1456d 100644 --- a/code/modules/antagonists/changeling/powers/biodegrade.dm +++ b/code/modules/antagonists/changeling/powers/biodegrade.dm @@ -1,23 +1,21 @@ -/obj/effect/proc_holder/changeling/biodegrade +/datum/action/changeling/biodegrade name = "Biodegrade" - desc = "Dissolves restraints or other objects preventing free movement." + desc = "Dissolves restraints or other objects preventing free movement. Costs 15 chemicals." helptext = "This is obvious to nearby people, and can destroy standard restraints and closets. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat." + button_icon_state = "biodegrade" chemical_cost = 15 //High cost to prevent spam loudness = 1 dna_cost = 2 - req_human = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_freedom" - action_background_icon_state = "bg_ling" + req_human = TRUE -/obj/effect/proc_holder/changeling/biodegrade/sting_action(mob/living/carbon/human/user) +/datum/action/changeling/biodegrade/sting_action(mob/living/carbon/human/user) var/used = FALSE // only one form of shackles removed per use if(!user.restrained() && !user.legcuffed && isopenturf(user.loc)) to_chat(user, "We are already free!") return FALSE if(user.handcuffed) - var/obj/O = user.get_item_by_slot(SLOT_HANDCUFFED) + var/obj/O = user.get_item_by_slot(ITEM_SLOT_HANDCUFFED) if(!istype(O)) return FALSE user.visible_message("[user] vomits a glob of acid on [user.p_their()] [O]!", \ @@ -27,7 +25,7 @@ used = TRUE if(user.legcuffed) - var/obj/O = user.get_item_by_slot(SLOT_LEGCUFFED) + var/obj/O = user.get_item_by_slot(ITEM_SLOT_LEGCUFFED) if(!istype(O)) return FALSE user.visible_message("[user] vomits a glob of acid on [user.p_their()] [O]!", \ @@ -37,7 +35,7 @@ used = TRUE if(user.wear_suit && user.wear_suit.breakouttime && !used) - var/obj/item/clothing/suit/S = user.get_item_by_slot(SLOT_WEAR_SUIT) + var/obj/item/clothing/suit/S = user.get_item_by_slot(ITEM_SLOT_OCLOTHING) if(!istype(S)) return FALSE user.visible_message("[user] vomits a glob of acid across the front of [user.p_their()] [S]!", \ @@ -66,25 +64,25 @@ return used -/obj/effect/proc_holder/changeling/biodegrade/proc/dissolve_handcuffs(mob/living/carbon/human/user, obj/O) +/datum/action/changeling/biodegrade/proc/dissolve_handcuffs(mob/living/carbon/human/user, obj/O) if(O && user.handcuffed == O) user.visible_message("[O] dissolve[O.gender==PLURAL?"":"s"] into a puddle of sizzling goop.") new /obj/effect/decal/cleanable/greenglow(O.drop_location()) qdel(O) -/obj/effect/proc_holder/changeling/biodegrade/proc/dissolve_legcuffs(mob/living/carbon/human/user, obj/O) +/datum/action/changeling/biodegrade/proc/dissolve_legcuffs(mob/living/carbon/human/user, obj/O) if(O && user.legcuffed == O) user.visible_message("[O] dissolve[O.gender==PLURAL?"":"s"] into a puddle of sizzling goop.") new /obj/effect/decal/cleanable/greenglow(O.drop_location()) qdel(O) -/obj/effect/proc_holder/changeling/biodegrade/proc/dissolve_straightjacket(mob/living/carbon/human/user, obj/S) +/datum/action/changeling/biodegrade/proc/dissolve_straightjacket(mob/living/carbon/human/user, obj/S) if(S && user.wear_suit == S) user.visible_message("[S] dissolves into a puddle of sizzling goop.") new /obj/effect/decal/cleanable/greenglow(S.drop_location()) qdel(S) -/obj/effect/proc_holder/changeling/biodegrade/proc/open_closet(mob/living/carbon/human/user, obj/structure/closet/C) +/datum/action/changeling/biodegrade/proc/open_closet(mob/living/carbon/human/user, obj/structure/closet/C) if(C && user.loc == C) C.visible_message("[C]'s door breaks and opens!") new /obj/effect/decal/cleanable/greenglow(C.drop_location()) @@ -94,7 +92,7 @@ C.open() to_chat(user, "We open the container restraining us!") -/obj/effect/proc_holder/changeling/biodegrade/proc/dissolve_cocoon(mob/living/carbon/human/user, obj/structure/spider/cocoon/C) +/datum/action/changeling/biodegrade/proc/dissolve_cocoon(mob/living/carbon/human/user, obj/structure/spider/cocoon/C) if(C && user.loc == C) new /obj/effect/decal/cleanable/greenglow(C.drop_location()) qdel(C) //The cocoon's destroy will move the changeling outside of it without interference diff --git a/code/modules/antagonists/changeling/powers/chameleon_skin.dm b/code/modules/antagonists/changeling/powers/chameleon_skin.dm index c01a1e40c8..21d4717b33 100644 --- a/code/modules/antagonists/changeling/powers/chameleon_skin.dm +++ b/code/modules/antagonists/changeling/powers/chameleon_skin.dm @@ -1,14 +1,12 @@ -/obj/effect/proc_holder/changeling/chameleon_skin +/datum/action/changeling/chameleon_skin name = "Chameleon Skin" desc = "Our skin pigmentation rapidly changes to suit our current environment." helptext = "Allows us to become invisible after a few seconds of standing still. Can be toggled on and off." + button_icon_state = "chameleon_skin" dna_cost = 2 - req_human = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_camouflage" - action_background_icon_state = "bg_ling" + req_human = TRUE -/obj/effect/proc_holder/changeling/chameleon_skin/sting_action(mob/user) +/datum/action/changeling/chameleon_skin/sting_action(mob/user) var/mob/living/carbon/human/H = user //SHOULD always be human, because req_human = 1 if(!istype(H)) // req_human could be done in can_sting stuff. return @@ -18,8 +16,8 @@ H.dna.add_mutation(CHAMELEON) return TRUE -/obj/effect/proc_holder/changeling/chameleon_skin/on_refund(mob/user) - action.Remove(user) +/datum/action/changeling/chameleon_skin/Remove(mob/user) if(user.has_dna()) var/mob/living/carbon/C = user C.dna.remove_mutation(CHAMELEON) + ..() diff --git a/code/modules/antagonists/changeling/powers/digitalcamo.dm b/code/modules/antagonists/changeling/powers/digitalcamo.dm index e44a7c0aa5..9354aec9ec 100644 --- a/code/modules/antagonists/changeling/powers/digitalcamo.dm +++ b/code/modules/antagonists/changeling/powers/digitalcamo.dm @@ -1,27 +1,25 @@ -/obj/effect/proc_holder/changeling/digitalcamo +/datum/action/changeling/digitalcamo name = "Digital Camouflage" desc = "By evolving the ability to distort our form and proportions, we defeat common algorithms used to detect lifeforms on cameras." helptext = "We cannot be tracked by camera or seen by AI units while using this skill. However, humans looking at us will find us... uncanny. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat." + button_icon_state = "digital_camo" dna_cost = 1 loudness = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_digital_camo" - action_background_icon_state = "bg_ling" //Prevents AIs tracking you but makes you easily detectable to the human-eye. -/obj/effect/proc_holder/changeling/digitalcamo/sting_action(mob/user) +/datum/action/changeling/digitalcamo/sting_action(mob/user) if(user.digitalcamo) to_chat(user, "We return to normal.") - user.digitalinvis = 0 - user.digitalcamo = 0 + user.digitalinvis = FALSE + user.digitalcamo = FALSE else - to_chat(user, "We distort our form to hide from the AI") - user.digitalcamo = 1 - user.digitalinvis = 1 + to_chat(user, "We distort our form to hide from the AI.") + user.digitalcamo = TRUE + user.digitalinvis = TRUE return TRUE -/obj/effect/proc_holder/changeling/digitalcamo/on_refund(mob/user) - action.Remove(user) - user.digitalcamo = 0 - user.digitalinvis = 0 +/datum/action/changeling/digitalcamo/Remove(mob/user) + user.digitalcamo = FALSE + user.digitalinvis = FALSE + ..() diff --git a/code/modules/antagonists/changeling/powers/fakedeath.dm b/code/modules/antagonists/changeling/powers/fakedeath.dm index 08dc85efbf..7ce9da633e 100644 --- a/code/modules/antagonists/changeling/powers/fakedeath.dm +++ b/code/modules/antagonists/changeling/powers/fakedeath.dm @@ -1,41 +1,70 @@ -/obj/effect/proc_holder/changeling/fakedeath +/datum/action/changeling/fakedeath name = "Reviving Stasis" - desc = "We fall into a stasis, allowing us to regenerate and trick our enemies." + desc = "We fall into a stasis, allowing us to regenerate and trick our enemies. Costs 15 chemicals." + button_icon_state = "fake_death" chemical_cost = 15 dna_cost = 0 req_dna = 1 req_stat = DEAD ignores_fakedeath = TRUE - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_regenerative_stasis" - action_background_icon_state = "bg_ling" + var/revive_ready = FALSE //Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay. -/obj/effect/proc_holder/changeling/fakedeath/sting_action(mob/living/user) - to_chat(user, "We begin our stasis, preparing energy to arise once more.") - if(user.stat != DEAD) - user.emote("deathgasp") - user.tod = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time) - user.fakedeath("changeling", TRUE) //play dead - user.update_stat() - - addtimer(CALLBACK(src, .proc/ready_to_regenerate, user), LING_FAKEDEATH_TIME, TIMER_UNIQUE) +/datum/action/changeling/fakedeath/sting_action(mob/living/user) + ..() + if(revive_ready) + revive(user) + else + to_chat(user, "We begin our stasis, preparing energy to arise once more.") + if(user.stat != DEAD) + user.emote("deathgasp") + user.tod = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time) + user.fakedeath("changeling", TRUE) //play dead + user.update_stat() + addtimer(CALLBACK(src, .proc/ready_to_regenerate, user), LING_FAKEDEATH_TIME, TIMER_UNIQUE) return TRUE -/obj/effect/proc_holder/changeling/fakedeath/proc/ready_to_regenerate(mob/user) +/datum/action/changeling/fakedeath/proc/revive(mob/living/user) + user.cure_fakedeath("changeling") + user.revive(full_heal = TRUE) + var/list/missing = user.get_missing_limbs() + missing -= BODY_ZONE_HEAD // headless changelings are funny + if(missing.len) + playsound(user, 'sound/magic/demon_consume.ogg', 50, 1) + user.visible_message("[user]'s missing limbs \ + reform, making a loud, grotesque sound!", + "Your limbs regrow, making a \ + loud, crunchy sound and giving you great pain!", + "You hear organic matter ripping \ + and tearing!") + user.emote("scream") + user.regenerate_limbs(0, list(BODY_ZONE_HEAD)) + user.regenerate_organs() + revive_ready = FALSE + name = "Reviving Stasis" + desc = "We fall into a stasis, allowing us to regenerate and trick our enemies. Costs 15 chemicals." + button_icon_state = "fake_death" + UpdateButtonIcon() + chemical_cost = 15 + to_chat(user, "We have revived ourselves.") + +/datum/action/changeling/fakedeath/proc/ready_to_regenerate(mob/user) if(user && user.mind) var/datum/antagonist/changeling/C = user.mind.has_antag_datum(/datum/antagonist/changeling) if(C && C.purchasedpowers) to_chat(user, "We are ready to revive.") - var/obj/effect/proc_holder/changeling/revive/RV = new /obj/effect/proc_holder/changeling/revive(null) - C.purchasedpowers += RV - RV.action.Grant(user) + name = "Revive" + desc = "We arise once more." + button_icon_state = "revive" + UpdateButtonIcon() + chemical_cost = 0 + revive_ready = TRUE -/obj/effect/proc_holder/changeling/fakedeath/can_sting(mob/living/user) - if(HAS_TRAIT_FROM(user, TRAIT_DEATHCOMA, "changeling")) +/datum/action/changeling/fakedeath/can_sting(mob/living/user) + if(HAS_TRAIT_FROM(user, TRAIT_DEATHCOMA, "changeling") && !revive_ready) to_chat(user, "We are already reviving.") return - if(!user.stat) //Confirmation for living changelings if they want to fake their death + if(!user.stat && !revive_ready) //Confirmation for living changelings if they want to fake their death switch(alert("Are we sure we wish to fake our own death?",,"Yes", "No")) if("No") return diff --git a/code/modules/antagonists/changeling/powers/fleshmend.dm b/code/modules/antagonists/changeling/powers/fleshmend.dm index 0299abb09a..4b62afb09b 100644 --- a/code/modules/antagonists/changeling/powers/fleshmend.dm +++ b/code/modules/antagonists/changeling/powers/fleshmend.dm @@ -1,18 +1,16 @@ -/obj/effect/proc_holder/changeling/fleshmend +/datum/action/changeling/fleshmend name = "Fleshmend" - desc = "Our flesh rapidly regenerates, healing our burns, bruises, and shortness of breath, as well as hiding all of our scars. Costs 20 chemicals." - helptext = "If we are on fire, the healing effect will not function. Does not regrow limbs or restore lost blood." + desc = "Our flesh rapidly regenerates, healing our burns, bruises, and shortness of breath. Costs 20 chemicals." + helptext = "If we are on fire, the healing effect will not function. Does not regrow limbs or restore lost blood. Functions while unconscious." + button_icon_state = "fleshmend" chemical_cost = 20 loudness = 2 dna_cost = 2 req_stat = UNCONSCIOUS - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_fleshmend" - action_background_icon_state = "bg_ling" //Starts healing you every second for 10 seconds. //Can be used whilst unconscious. -/obj/effect/proc_holder/changeling/fleshmend/sting_action(mob/living/user) +/datum/action/changeling/fleshmend/sting_action(mob/living/user) if(user.has_status_effect(STATUS_EFFECT_FLESHMEND)) to_chat(user, "We are already fleshmending!") return diff --git a/code/modules/antagonists/changeling/powers/headcrab.dm b/code/modules/antagonists/changeling/powers/headcrab.dm index 867f160081..08195fdbd7 100644 --- a/code/modules/antagonists/changeling/powers/headcrab.dm +++ b/code/modules/antagonists/changeling/powers/headcrab.dm @@ -1,16 +1,14 @@ -/obj/effect/proc_holder/changeling/headcrab +/datum/action/changeling/headcrab name = "Last Resort" - desc = "We sacrifice our current body in a moment of need, placing us in control of a vessel." + desc = "We sacrifice our current body in a moment of need, placing us in control of a vessel that can plant our likeness in a new host. Costs 20 chemicals." helptext = "We will be placed in control of a small, fragile creature. We may attack a corpse like this to plant an egg which will slowly mature into a new form for us. This ability is loud, and might cause our blood to react violently to heat." + button_icon_state = "last_resort" chemical_cost = 20 dna_cost = 1 loudness = 2 - req_human = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_explode" - action_background_icon_state = "bg_ling" + req_human = TRUE -/obj/effect/proc_holder/changeling/headcrab/sting_action(mob/user) +/datum/action/changeling/headcrab/sting_action(mob/user) set waitfor = FALSE if(alert("Are we sure we wish to kill ourself and create a headslug?",,"Yes", "No") == "No") return diff --git a/code/modules/antagonists/changeling/powers/hivemind.dm b/code/modules/antagonists/changeling/powers/hivemind.dm index f7718d7708..95ad09c318 100644 --- a/code/modules/antagonists/changeling/powers/hivemind.dm +++ b/code/modules/antagonists/changeling/powers/hivemind.dm @@ -1,52 +1,55 @@ -//HIVEMIND COMMUNICATION //MODE_TOKEN_CHANGELING / :g -/obj/effect/proc_holder/changeling/hivemind_comms +//HIVEMIND COMMUNICATION (:g) +/datum/action/changeling/hivemind_comms name = "Hivemind Communication" desc = "We tune our senses to the airwaves to allow us to discreetly communicate and exchange DNA with other changelings." - helptext = "We will be able to talk with other changelings with :g. Exchanged DNA do not count towards absorb objectives." //MODE_TOKEN_CHANGELING needs to be manually updated here. + helptext = "We will be able to talk with other changelings with :g. Exchanged DNA do not count towards absorb objectives." + needs_button = FALSE dna_cost = 1 chemical_cost = -1 - action_icon = 'icons/mob/actions/actions_xeno.dmi' - action_icon_state = "alien_whisper" - action_background_icon_state = "bg_ling" -/obj/effect/proc_holder/changeling/hivemind_comms/sting_action(var/mob/living/user) +/datum/action/changeling/hivemind_comms/sting_action(var/mob/living/user) if (HAS_TRAIT(user, CHANGELING_HIVEMIND_MUTE)) to_chat(user, "The poison in the air hinders our ability to interact with the hivemind.") return var/input = html_decode(stripped_input(usr, "Please choose a message to transmit.", "Changeling Hivemind", "")) user.say(".g[input]") -/obj/effect/proc_holder/changeling/hivemind_comms/on_purchase(mob/user, is_respec) +/datum/action/changeling/hivemind_comms/on_purchase(mob/user, is_respec) ..() var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) changeling.changeling_speak = 1 to_chat(user, "Use say \"[MODE_TOKEN_CHANGELING] message\" to communicate with the other changelings.") - var/obj/effect/proc_holder/changeling/hivemind_upload/S1 = new + var/datum/action/changeling/hivemind_upload/S1 = new if(!changeling.has_sting(S1)) - changeling.purchasedpowers+=S1 - S1.action.Grant(user) - var/obj/effect/proc_holder/changeling/hivemind_download/S2 = new + S1.Grant(user) + var/datum/action/changeling/hivemind_download/S2 = new if(!changeling.has_sting(S2)) - changeling.purchasedpowers+=S2 - S2.action.Grant(user) - var/obj/effect/proc_holder/changeling/linglink/S3 = new + S2.Grant(user) + var/datum/action/changeling/linglink/S3 = new if(!changeling.has_sting(S3)) - changeling.purchasedpowers+=S3 - S3.action.Grant(user) + S3.Grant(user) + +/datum/action/changeling/hivemind_comms/Remove(mob/user) + var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) + if(changeling.changeling_speak) + changeling.changeling_speak = FALSE + for(var/p in changeling.purchasedpowers) + var/datum/action/changeling/otherpower = p + if(istype(otherpower, /datum/action/changeling/hivemind_upload) || istype(otherpower, /datum/action/changeling/hivemind_download)) + changeling.purchasedpowers -= otherpower + otherpower.Remove(changeling.owner.current) + ..() // HIVE MIND UPLOAD/DOWNLOAD DNA GLOBAL_LIST_EMPTY(hivemind_bank) -/obj/effect/proc_holder/changeling/hivemind_upload +/datum/action/changeling/hivemind_upload name = "Hive Channel DNA" - desc = "Allows us to channel DNA in the airwaves to allow other changelings to absorb it." + desc = "Allows us to channel DNA in the airwaves to allow other changelings to absorb it. Costs 10 chemicals." + button_icon_state = "hivemind_channel" chemical_cost = 10 - dna_cost = -1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_upload" - action_background_icon_state = "bg_ling" -/obj/effect/proc_holder/changeling/hivemind_upload/sting_action(var/mob/living/user) +/datum/action/changeling/hivemind_upload/sting_action(var/mob/living/user) if (HAS_TRAIT(user, CHANGELING_HIVEMIND_MUTE)) to_chat(user, "The poison in the air hinders our ability to interact with the hivemind.") return @@ -74,16 +77,13 @@ GLOBAL_LIST_EMPTY(hivemind_bank) to_chat(user, "We channel the DNA of [chosen_name] to the air.") return TRUE -/obj/effect/proc_holder/changeling/hivemind_download +/datum/action/changeling/hivemind_download name = "Hive Absorb DNA" - desc = "Allows us to absorb DNA that has been channeled to the airwaves. Does not count towards absorb objectives." + desc = "Allows us to absorb DNA that has been channeled to the airwaves. Does not count towards absorb objectives. Costs 10 chemicals." + button_icon_state = "hive_absorb" chemical_cost = 10 - dna_cost = -1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_download" - action_background_icon_state = "bg_ling" -/obj/effect/proc_holder/changeling/hivemind_download/can_sting(mob/living/carbon/user) +/datum/action/changeling/hivemind_download/can_sting(mob/living/carbon/user) if(!..()) return if (HAS_TRAIT(user, CHANGELING_HIVEMIND_MUTE)) @@ -96,7 +96,7 @@ GLOBAL_LIST_EMPTY(hivemind_bank) return return 1 -/obj/effect/proc_holder/changeling/hivemind_download/sting_action(mob/user) +/datum/action/changeling/hivemind_download/sting_action(mob/user) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) var/list/names = list() for(var/datum/changelingprofile/prof in GLOB.hivemind_bank) diff --git a/code/modules/antagonists/changeling/powers/humanform.dm b/code/modules/antagonists/changeling/powers/humanform.dm index c9edc12eeb..016ab5c6dd 100644 --- a/code/modules/antagonists/changeling/powers/humanform.dm +++ b/code/modules/antagonists/changeling/powers/humanform.dm @@ -1,14 +1,12 @@ -/obj/effect/proc_holder/changeling/humanform +/datum/action/changeling/humanform name = "Human Form" - desc = "We change into a human." + desc = "We change into a human. Costs 5 chemicals." + button_icon_state = "human_form" chemical_cost = 5 req_dna = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_human" - action_background_icon_state = "bg_ling" //Transform into a human. -/obj/effect/proc_holder/changeling/humanform/sting_action(mob/living/carbon/user) +/datum/action/changeling/humanform/sting_action(mob/living/carbon/user) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) var/datum/changelingprofile/chosen_prof = changeling.select_dna() diff --git a/code/modules/antagonists/changeling/powers/lesserform.dm b/code/modules/antagonists/changeling/powers/lesserform.dm index f3690ef5c5..1160e0908a 100644 --- a/code/modules/antagonists/changeling/powers/lesserform.dm +++ b/code/modules/antagonists/changeling/powers/lesserform.dm @@ -1,18 +1,17 @@ -/obj/effect/proc_holder/changeling/lesserform +/datum/action/changeling/lesserform name = "Lesser Form" - desc = "We debase ourselves and become lesser. We become a monkey. This ability is loud, and might cause our blood to react violently to heat." + desc = "We debase ourselves and become lesser. We become a monkey. This ability is loud, and might cause our blood to react violently to heat. Costs 5 chemicals." + helptext = "The transformation greatly reduces our size, allowing us to slip out of cuffs and climb through vents." + button_icon_state = "lesser_form" chemical_cost = 5 dna_cost = 1 loudness = 2 - req_human = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_lesser" - action_background_icon_state = "bg_ling" + req_human = TRUE //Transform into a monkey. -/obj/effect/proc_holder/changeling/lesserform/sting_action(mob/living/carbon/human/user) +/datum/action/changeling/lesserform/sting_action(mob/living/carbon/human/user) if(!user || user.mob_transforming) - return 0 + return FALSE to_chat(user, "Our genes cry out!") user.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) diff --git a/code/modules/antagonists/changeling/powers/linglink.dm b/code/modules/antagonists/changeling/powers/linglink.dm index 332f543545..067399fb9a 100644 --- a/code/modules/antagonists/changeling/powers/linglink.dm +++ b/code/modules/antagonists/changeling/powers/linglink.dm @@ -1,14 +1,12 @@ -/obj/effect/proc_holder/changeling/linglink +/datum/action/changeling/linglink name = "Hivemind Link" - desc = "Link your victim's mind into the hivemind for personal interrogation." + desc = "We link our victim's mind into the hivemind for personal interrogation." + helptext = "If we find a human mad enough to support our cause, this can be a helpful tool to stay in touch." + button_icon_state = "hivemind_link" chemical_cost = 0 - dna_cost = -1 - req_human = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_link" - action_background_icon_state = "bg_ling" + req_human = TRUE -/obj/effect/proc_holder/changeling/linglink/can_sting(mob/living/carbon/user) +/datum/action/changeling/linglink/can_sting(mob/living/carbon/user) if(!..()) return var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) @@ -37,7 +35,7 @@ return return changeling.can_absorb_dna(target) -/obj/effect/proc_holder/changeling/linglink/sting_action(mob/user) +/datum/action/changeling/linglink/sting_action(mob/user) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) var/mob/living/carbon/human/target = user.pulling changeling.islinking = 1 @@ -61,7 +59,7 @@ target.reagents.add_reagent(/datum/reagent/medicine/salbutamol, 40) // So they don't choke to death while you interrogate them sleep(1800) SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]", "[i]")) - if(!do_mob(user, target, 20)) + if(!do_mob(user, target, 2 SECONDS)) to_chat(user, "Our link with [target] has ended!") changeling.islinking = 0 target.mind.linglink = 0 diff --git a/code/modules/antagonists/changeling/powers/mimic_voice.dm b/code/modules/antagonists/changeling/powers/mimic_voice.dm index 170aea1e9c..dc7238d892 100644 --- a/code/modules/antagonists/changeling/powers/mimic_voice.dm +++ b/code/modules/antagonists/changeling/powers/mimic_voice.dm @@ -1,17 +1,14 @@ -/obj/effect/proc_holder/changeling/mimicvoice +/datum/action/changeling/mimicvoice name = "Mimic Voice" - desc = "We shape our vocal glands to sound like a desired voice." + desc = "We shape our vocal glands to sound like a desired voice. Maintaining this power slows chemical production." + button_icon_state = "mimic_voice" helptext = "Will turn your voice into the name that you enter. We must constantly expend chemicals to maintain our form like this." chemical_cost = 0 //constant chemical drain hardcoded dna_cost = 1 - req_human = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_mimic_voice" - action_background_icon_state = "bg_ling" - + req_human = TRUE // Fake Voice -/obj/effect/proc_holder/changeling/mimicvoice/sting_action(mob/user) +/datum/action/changeling/mimicvoice/sting_action(mob/user) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) if(changeling.mimicing) changeling.mimicing = "" diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index f4b74c5567..e327f62370 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -14,25 +14,24 @@ //Parent to shields and blades because muh copypasted code. -/obj/effect/proc_holder/changeling/weapon +/datum/action/changeling/weapon name = "Organic Weapon" desc = "Go tell a coder if you see this" helptext = "Yell at Miauw and/or Perakp" chemical_cost = 1000 - dna_cost = -1 var/recharge_slowdown = 0 var/silent = FALSE var/weapon_type var/weapon_name_simple -/obj/effect/proc_holder/changeling/weapon/try_to_sting(mob/user, mob/target) +/datum/action/changeling/weapon/try_to_sting(mob/user, mob/target) for(var/obj/item/I in user.held_items) if(check_weapon(user, I)) return ..(user, target) -/obj/effect/proc_holder/changeling/weapon/proc/check_weapon(mob/user, obj/item/hand_item) +/datum/action/changeling/weapon/proc/check_weapon(mob/user, obj/item/hand_item) if(istype(hand_item, weapon_type)) user.temporarilyRemoveItemFromInventory(hand_item, TRUE) //DROPDEL will delete the item if(!silent) @@ -43,7 +42,7 @@ user.update_inv_hands() return 1 -/obj/effect/proc_holder/changeling/weapon/sting_action(mob/living/user) +/datum/action/changeling/weapon/sting_action(mob/living/user) var/obj/item/held = user.get_active_held_item() if(held && !user.dropItemToGround(held)) to_chat(user, "[held] is stuck to your hand, you cannot grow a [weapon_name_simple] over it!") @@ -64,19 +63,18 @@ changeling.chem_recharge_slowdown += recharge_slowdown return W -/obj/effect/proc_holder/changeling/weapon/on_refund(mob/user) - action.Remove(user) +/datum/action/changeling/weapon/Remove(mob/user) for(var/obj/item/I in user.held_items) check_weapon(user, I) + ..() //Parent to space suits and armor. -/obj/effect/proc_holder/changeling/suit +/datum/action/changeling/suit name = "Organic Suit" desc = "Go tell a coder if you see this" helptext = "Yell at Miauw and/or Perakp" chemical_cost = 1000 - dna_cost = -1 var/helmet_type = /obj/item var/suit_type = /obj/item @@ -85,17 +83,17 @@ var/recharge_slowdown = 0 var/blood_on_castoff = 0 -/obj/effect/proc_holder/changeling/suit/try_to_sting(mob/user, mob/target) +/datum/action/changeling/suit/try_to_sting(mob/user, mob/target) if(check_suit(user)) return var/mob/living/carbon/human/H = user ..(H, target) //checks if we already have an organic suit and casts it off. -/obj/effect/proc_holder/changeling/suit/proc/check_suit(mob/user) +/datum/action/changeling/suit/proc/check_suit(mob/user) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) if(!ishuman(user) || !changeling) - return 1 + return TRUE var/mob/living/carbon/human/H = user if(istype(H.wear_suit, suit_type) || istype(H.head, helmet_type)) H.visible_message("[H] casts off [H.p_their()] [suit_name_simple]!", "We cast off our [suit_name_simple].", "You hear organic matter ripping and tearing!") @@ -110,16 +108,16 @@ playsound(H.loc, 'sound/effects/splat.ogg', 50, 1) //So real sounds changeling.chem_recharge_slowdown -= recharge_slowdown - return 1 + return TRUE -/obj/effect/proc_holder/changeling/suit/on_refund(mob/user) +/datum/action/changeling/suit/Remove(mob/user) if(!ishuman(user)) return - action.Remove(user) var/mob/living/carbon/human/H = user check_suit(H) + ..() -/obj/effect/proc_holder/changeling/suit/sting_action(mob/living/carbon/human/user) +/datum/action/changeling/suit/sting_action(mob/living/carbon/human/user) if(!user.canUnEquip(user.wear_suit)) to_chat(user, "\the [user.wear_suit] is stuck to your body, you cannot grow a [suit_name_simple] over it!") return @@ -130,8 +128,8 @@ user.dropItemToGround(user.head) user.dropItemToGround(user.wear_suit) - user.equip_to_slot_if_possible(new suit_type(user), SLOT_WEAR_SUIT, 1, 1, 1) - user.equip_to_slot_if_possible(new helmet_type(user), SLOT_HEAD, 1, 1, 1) + user.equip_to_slot_if_possible(new suit_type(user), ITEM_SLOT_OCLOTHING, 1, 1, 1) + user.equip_to_slot_if_possible(new helmet_type(user), ITEM_SLOT_HEAD, 1, 1, 1) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) changeling.chem_recharge_slowdown += recharge_slowdown @@ -142,20 +140,18 @@ /***************************************\ |***************ARM BLADE***************| \***************************************/ -/obj/effect/proc_holder/changeling/weapon/arm_blade +/datum/action/changeling/weapon/arm_blade name = "Arm Blade" - desc = "We reform one of our arms into a deadly blade." + desc = "We reform one of our arms into a deadly blade. Costs 5 chemicals." helptext = "We may retract our armblade in the same manner as we form it. Cannot be used while in lesser form. This ability is loud, and might cause our blood to react violently to heat." + button_icon_state = "armblade" chemical_cost = 5 dna_cost = 2 loudness = 2 - req_human = 1 + req_human = TRUE recharge_slowdown = 0.6 weapon_type = /obj/item/melee/arm_blade weapon_name_simple = "blade" - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_armblade" - action_background_icon_state = "bg_ling" /obj/item/melee/arm_blade name = "arm blade" @@ -231,23 +227,21 @@ |***********COMBAT TENTACLES*************| \***************************************/ -/obj/effect/proc_holder/changeling/weapon/tentacle +/datum/action/changeling/weapon/tentacle name = "Tentacle" - desc = "We ready a tentacle to grab items or victims with." + desc = "We ready a tentacle to grab items or victims with. Costs 10 chemicals." helptext = "We can use it once to retrieve a distant item. If used on living creatures, the effect depends on the intent: \ Help will simply drag them closer, Disarm will grab whatever they're holding instead of them, Grab will put the victim in our hold after catching it, \ and Harm will stun it, and stab it if we're also holding a sharp weapon. Cannot be used while in lesser form.\ This ability is loud, and might cause our blood to react violently to heat." + button_icon_state = "tentacle" chemical_cost = 10 dna_cost = 2 loudness = 2 - req_human = 1 + req_human = TRUE weapon_type = /obj/item/gun/magic/tentacle weapon_name_simple = "tentacle" silent = TRUE - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_tentacle" - action_background_icon_state = "bg_ling" /obj/item/gun/magic/tentacle name = "tentacle" @@ -302,7 +296,7 @@ firing_effect_type = null var/obj/item/gun/magic/tentacle/gun //the item that shot it -/obj/item/ammo_casing/magic/tentacle/Initialize() +/obj/item/ammo_casing/magic/tentacle/Initialize(mapload) gun = loc . = ..() @@ -321,7 +315,7 @@ var/chain var/obj/item/ammo_casing/magic/tentacle/source //the item that shot it -/obj/item/projectile/tentacle/Initialize() +/obj/item/projectile/tentacle/Initialize(mapload) source = loc . = ..() @@ -417,22 +411,20 @@ /***************************************\ |****************SHIELD*****************| \***************************************/ -/obj/effect/proc_holder/changeling/weapon/shield +/datum/action/changeling/weapon/shield name = "Organic Shield" - desc = "We reform one of our arms into a hard shield." + desc = "We reform one of our arms into a hard shield. Costs 20 chemicals." helptext = "Organic tissue cannot resist damage forever; the shield will break after it is hit too much. The more genomes we absorb, the stronger it is. Cannot be used while in lesser form. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat." + button_icon_state = "organic_shield" chemical_cost = 20 dna_cost = 2 loudness = 1 - req_human = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_shield" - action_background_icon_state = "bg_ling" + req_human = TRUE weapon_type = /obj/item/shield/changeling weapon_name_simple = "shield" -/obj/effect/proc_holder/changeling/weapon/shield/sting_action(mob/user) +/datum/action/changeling/weapon/shield/sting_action(mob/user) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) //So we can read the absorbedcount. if(!changeling) return @@ -477,23 +469,21 @@ /***************************************\ |*********SPACE SUIT + HELMET***********| \***************************************/ -/obj/effect/proc_holder/changeling/suit/organic_space_suit +/datum/action/changeling/suit/organic_space_suit name = "Organic Space Suit" - desc = "We grow an organic suit to protect ourselves from space exposure." + desc = "We grow an organic suit to protect ourselves from space exposure. Costs 20 chemicals." helptext = "We must constantly repair our form to make it space-proof, reducing chemical production while we are protected. Cannot be used in lesser form. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat." + button_icon_state = "organic_suit" chemical_cost = 20 dna_cost = 2 loudness = 1 - req_human = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_space_suit" - action_background_icon_state = "bg_ling" + req_human = TRUE + recharge_slowdown = 0.6 suit_type = /obj/item/clothing/suit/space/changeling helmet_type = /obj/item/clothing/head/helmet/space/changeling suit_name_simple = "flesh shell" helmet_name_simple = "space helmet" - recharge_slowdown = 0.6 blood_on_castoff = 1 /obj/item/clothing/suit/space/changeling @@ -503,10 +493,10 @@ item_flags = DROPDEL clothing_flags = STOPSPRESSUREDAMAGE //Not THICKMATERIAL because it's organic tissue, so if somebody tries to inject something into it, it still ends up in your blood. (also balance but muh fluff) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/oxygen) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) //No armor at all. + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) //No armor at all. mutantrace_variation = NONE -/obj/item/clothing/suit/space/changeling/Initialize() +/obj/item/clothing/suit/space/changeling/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) if(ismob(loc)) @@ -524,28 +514,26 @@ desc = "A covering of pressure and temperature-resistant organic tissue with a glass-like chitin front." item_flags = DROPDEL clothing_flags = STOPSPRESSUREDAMAGE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH -/obj/item/clothing/head/helmet/space/changeling/Initialize() +/obj/item/clothing/head/helmet/space/changeling/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) /***************************************\ |*****************ARMOR*****************| \***************************************/ -/obj/effect/proc_holder/changeling/suit/armor +/datum/action/changeling/suit/armor name = "Chitinous Armor" - desc = "We turn our skin into tough chitin to protect us from damage." + desc = "We turn our skin into tough chitin to protect us from damage. Costs 10 chemicals." helptext = "Upkeep of the armor requires a constant expenditure of chemicals, resulting in a reduced chemical generation. The armor is strong against brute force, but does not provide much protection from lasers. Cannot be used in lesser form. This ability is loud, and might cause our blood to react violently to heat." + button_icon_state = "chitinous_armor" chemical_cost = 10 dna_cost = 1 loudness = 2 - req_human = 1 + req_human = TRUE recharge_slowdown = 0.6 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_armor" - action_background_icon_state = "bg_ling" suit_type = /obj/item/clothing/suit/armor/changeling helmet_type = /obj/item/clothing/head/helmet/changeling @@ -558,12 +546,12 @@ icon_state = "lingarmor" item_flags = DROPDEL body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list("melee" = 70, "bullet" = 60, "laser" = 30, "energy" = 40, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 50, "acid" = 90) + armor = list(MELEE = 70, BULLET = 60, LASER = 30, ENERGY = 40, BOMB = 10, BIO = 4, RAD = 0, FIRE = 50, ACID = 90) flags_inv = HIDEJUMPSUIT cold_protection = 0 heat_protection = 0 -/obj/item/clothing/suit/armor/changeling/Initialize() +/obj/item/clothing/suit/armor/changeling/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) if(ismob(loc)) @@ -574,10 +562,10 @@ desc = "A tough, hard covering of black chitin with transparent chitin in front." icon_state = "lingarmorhelmet" item_flags = DROPDEL - armor = list("melee" = 70, "bullet" = 60, "laser" = 30, "energy" = 40, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 50, "acid" = 90) + armor = list(MELEE = 70, BULLET = 60, LASER = 30, ENERGY = 40, BOMB = 10, BIO = 4, RAD = 0, FIRE = 50, ACID = 90) flags_inv = HIDEEARS|HIDEHAIR|HIDEEYES|HIDEFACIALHAIR|HIDEFACE -/obj/item/clothing/head/helmet/changeling/Initialize() +/obj/item/clothing/head/helmet/changeling/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) @@ -587,26 +575,26 @@ |*****************CLAWS*****************| \***************************************/ -/obj/effect/proc_holder/changeling/gloves +/datum/action/changeling/gloves name = "Mangled Claws" desc = "Go tell a coder if you see this" helptext = "Yell at Hatterhat, for fucking up Miauw and/or Perakp's work" + button_icon_state = "gauntlets" chemical_cost = 1000 - dna_cost = -1 var/glove_type = /obj/item var/glove_name_simple = " " // keep these plural bro var/recharge_slowdown = 0 var/blood_on_castoff = 0 -/obj/effect/proc_holder/changeling/gloves/try_to_sting(mob/user, mob/target) +/datum/action/changeling/gloves/try_to_sting(mob/user, mob/target) if(check_gloves(user)) return var/mob/living/carbon/human/H = user ..(H, target) //checks if we already have claws and casts it off -/obj/effect/proc_holder/changeling/gloves/proc/check_gloves(mob/user) +/datum/action/changeling/gloves/proc/check_gloves(mob/user) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) if(!ishuman(user) || !changeling) return 1 @@ -623,21 +611,21 @@ changeling.chem_recharge_slowdown -= recharge_slowdown return 1 -/obj/effect/proc_holder/changeling/gloves/on_refund(mob/user) +/datum/action/changeling/gloves/Remove(mob/user) if(!ishuman(user)) return - action.Remove(user) var/mob/living/carbon/human/H = user check_gloves(H) + ..() -/obj/effect/proc_holder/changeling/gloves/sting_action(mob/living/carbon/human/user) +/datum/action/changeling/gloves/sting_action(mob/living/carbon/human/user) if(!user.canUnEquip(user.gloves)) to_chat(user, "\the [user.gloves] is stuck to your body, you cannot grow [glove_name_simple] over it!") return user.dropItemToGround(user.gloves) - user.equip_to_slot_if_possible(new glove_type(user), SLOT_GLOVES, 1, 1, 1) + user.equip_to_slot_if_possible(new glove_type(user), ITEM_SLOT_GLOVES, 1, 1, 1) playsound(user, 'sound/effects/blobattack.ogg', 30, 1) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) changeling.chem_recharge_slowdown += recharge_slowdown @@ -653,9 +641,9 @@ cold_protection = HANDS min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT - armor = list("melee" = 20, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 35, "bio" = 35, "rad" = 35, "fire" = 0, "acid" = 0) + armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 35, BIO = 35, RAD = 35, FIRE = 0, ACID = 0) -/obj/item/clothing/gloves/claws/Initialize() +/obj/item/clothing/gloves/claws/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) @@ -664,23 +652,21 @@ desc = "Good for prying things off of people and looking incredibly creepy." strip_mod = 2 -/obj/effect/proc_holder/changeling/gloves/gauntlets +/datum/action/changeling/gloves/gauntlets name = "Bone Gauntlets" - desc = "We turn our hands into solid bone and chitin, sacrificing dexterity for raw strength." + desc = "We turn our hands into solid bone and chitin, sacrificing dexterity for raw strength. Costs 5 chemicals." helptext = "These grotesque, bone-and-chitin gauntlets are remarkably good at beating victims senseless, and cannot be used in lesser form. This ability is loud, and might cause our blood to react violently to heat." + button_icon_state = "gauntlets" chemical_cost = 5 // same cost as armblade because its a sidegrade (sacrifice utility for punching people violently) dna_cost = 2 loudness = 2 - req_human = 1 + req_human = TRUE recharge_slowdown = 0.6 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_gauntlets" - action_background_icon_state = "bg_ling" glove_type = /obj/item/clothing/gloves/fingerless/pugilist/cling // just punch his head off dude glove_name_simple = "bone gauntlets" -/obj/effect/proc_holder/changeling/gloves/gauntlets/sting_action(mob/living/user) +/datum/action/changeling/gloves/gauntlets/sting_action(mob/living/user) if(HAS_TRAIT(user, TRAIT_NOPUGILIST)) to_chat(user, "We would gain nothing by forming our fists into brute-force weapons when we are trained in precision martial arts!") return @@ -697,7 +683,7 @@ cold_protection = ARMS|HANDS min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT - armor = list("melee" = 20, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 35, "bio" = 35, "rad" = 35, "fire" = 0, "acid" = 0) + armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 35, BIO = 35, RAD = 35, FIRE = 0, ACID = 0) enhancement = 6 // first, do harm. all of it. all of the harm. just fuck em up. wound_enhancement = 6 var/fast_enhancement = 6 @@ -727,13 +713,13 @@ to_chat(user, "[src] are now formed to allow for [fasthands ? "fast, precise strikes" : "crippling, damaging blows"].") addtimer(CALLBACK(src, .proc/use_buffs, user, TRUE), 0.1) // go fuckin get em -/obj/item/clothing/gloves/fingerless/pugilist/cling/Initialize() +/obj/item/clothing/gloves/fingerless/pugilist/cling/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) /obj/item/clothing/gloves/fingerless/pugilist/cling/equipped(mob/user, slot) . = ..() - if(current_equipped_slot == SLOT_GLOVES) + if(current_equipped_slot == ITEM_SLOT_GLOVES) to_chat(user, "With [src] formed around our arms, we are ready to fight.") /obj/item/clothing/gloves/fingerless/pugilist/cling/dropped(mob/user) diff --git a/code/modules/antagonists/changeling/powers/panacea.dm b/code/modules/antagonists/changeling/powers/panacea.dm index 3b59a0c042..b9c19001fe 100644 --- a/code/modules/antagonists/changeling/powers/panacea.dm +++ b/code/modules/antagonists/changeling/powers/panacea.dm @@ -1,16 +1,14 @@ -/obj/effect/proc_holder/changeling/panacea +/datum/action/changeling/panacea name = "Anatomic Panacea" - desc = "Expels impurifications from our form; curing diseases, removing parasites, sobering us, purging toxins and radiation, and resetting our genetic code completely." + desc = "Expels impurifications from our form; curing diseases, removing parasites, sobering us, purging toxins and radiation, and resetting our genetic code completely. Costs 20 chemicals." helptext = "Can be used while unconscious." + button_icon_state = "panacea" chemical_cost = 20 dna_cost = 2 req_stat = UNCONSCIOUS - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_anatomic_panacea" - action_background_icon_state = "bg_ling" //Heals the things that the other regenerative abilities don't. -/obj/effect/proc_holder/changeling/panacea/sting_action(mob/living/user) +/datum/action/changeling/panacea/sting_action(mob/living/user) if(user.has_status_effect(STATUS_EFFECT_PANACEA)) to_chat(user, "We are already cleansing our impurities!") return diff --git a/code/modules/antagonists/changeling/powers/pheromone_receptors.dm b/code/modules/antagonists/changeling/powers/pheromone_receptors.dm index 3bda7335a1..9d7eb8744d 100644 --- a/code/modules/antagonists/changeling/powers/pheromone_receptors.dm +++ b/code/modules/antagonists/changeling/powers/pheromone_receptors.dm @@ -3,18 +3,17 @@ #define CHANGELING_PHEROMONE_PING_TIME 20 //2s update time. -/obj/effect/proc_holder/changeling/pheromone_receptors +/datum/action/changeling/pheromone_receptors name = "Pheromone Receptors" desc = "We attune our senses to track other changelings by scent. The closer they are, the easier we can find them." helptext = "We will know the general direction of nearby changelings, with closer scents being stronger. Our chemical generation is slowed while this is active." + icon_icon = 'icons/mob/actions/actions_spells.dmi' + button_icon_state = "nose" chemical_cost = 0 //Reduces regain rate while active. dna_cost = 2 var/receptors_active = FALSE - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_pheromone" - action_background_icon_state = "bg_ling" -/obj/effect/proc_holder/changeling/pheromone_receptors/sting_action(mob/living/carbon/user) +/datum/action/changeling/pheromone_receptors/sting_action(mob/living/carbon/user) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) if(!receptors_active) to_chat(user, "We search for the scent of any nearby changelings.") diff --git a/code/modules/antagonists/changeling/powers/regenerate.dm b/code/modules/antagonists/changeling/powers/regenerate.dm index a88422e7eb..2290b91f9a 100644 --- a/code/modules/antagonists/changeling/powers/regenerate.dm +++ b/code/modules/antagonists/changeling/powers/regenerate.dm @@ -1,18 +1,16 @@ -/obj/effect/proc_holder/changeling/regenerate +/datum/action/changeling/regenerate name = "Regenerate" desc = "Allows us to regrow and restore missing external limbs, and \ vital internal organs, as well as removing shrapnel and restoring \ - blood volume." + blood volume. Costs 10 chemicals." helptext = "Will alert nearby crew if any external limbs are \ regenerated. Can be used while unconscious." + button_icon_state = "regenerate" chemical_cost = 10 dna_cost = 0 req_stat = UNCONSCIOUS - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_regenerate" - action_background_icon_state = "bg_ling" -/obj/effect/proc_holder/changeling/regenerate/sting_action(mob/living/user) +/datum/action/changeling/regenerate/sting_action(mob/living/user) to_chat(user, "You feel an itching, both inside and \ outside as your tissues knit and reknit.") if(iscarbon(user)) diff --git a/code/modules/antagonists/changeling/powers/revive.dm b/code/modules/antagonists/changeling/powers/revive.dm deleted file mode 100644 index 3b78960ff1..0000000000 --- a/code/modules/antagonists/changeling/powers/revive.dm +++ /dev/null @@ -1,52 +0,0 @@ -/obj/effect/proc_holder/changeling/revive - name = "Revive" - desc = "We regenerate, healing all damage from our form." - helptext = "Does not regrow lost organs or a missing head." - req_stat = DEAD - always_keep = TRUE - ignores_fakedeath = TRUE - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_revive" - action_background_icon_state = "bg_ling" - -//Revive from revival stasis -/obj/effect/proc_holder/changeling/revive/sting_action(mob/living/carbon/user) - var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) - if(!changeling) - return - if(changeling.hostile_absorbed) - to_chat(user, "We cannot muster up the strength to revive ourselves!") - changeling.purchasedpowers -= src - src.action.Remove(user) - return - user.cure_fakedeath("changeling") - user.revive(full_heal = 1) - var/list/missing = user.get_missing_limbs() - missing -= BODY_ZONE_HEAD // headless changelings are funny - if(missing.len) - playsound(user, 'sound/magic/demon_consume.ogg', 50, 1) - user.visible_message("[user]'s missing limbs \ - reform, making a loud, grotesque sound!", - "Your limbs regrow, making a \ - loud, crunchy sound and giving you great pain!", - "You hear organic matter ripping \ - and tearing!") - user.emote("scream") - user.regenerate_limbs(0, list(BODY_ZONE_HEAD)) - user.regenerate_organs() - to_chat(user, "We have revived ourselves.") - changeling.purchasedpowers -= src - src.action.Remove(user) - return TRUE - -/obj/effect/proc_holder/changeling/revive/can_be_used_by(mob/living/user) - . = ..() - if(!.) - return - var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) - if(!changeling) - return FALSE - if(changeling.hostile_absorbed || ((user.stat != DEAD) && !(HAS_TRAIT(user, TRAIT_DEATHCOMA)))) - changeling.purchasedpowers -= src - return FALSE - diff --git a/code/modules/antagonists/changeling/powers/shriek.dm b/code/modules/antagonists/changeling/powers/shriek.dm index dae1da9f8f..c5ff3ab30f 100644 --- a/code/modules/antagonists/changeling/powers/shriek.dm +++ b/code/modules/antagonists/changeling/powers/shriek.dm @@ -1,17 +1,15 @@ -/obj/effect/proc_holder/changeling/resonant_shriek +/datum/action/changeling/resonant_shriek name = "Resonant Shriek" - desc = "Our lungs and vocal cords shift, allowing us to briefly emit a noise that deafens and confuses the weak-minded." + desc = "Our lungs and vocal cords shift, allowing us to briefly emit a noise that deafens and confuses the weak-minded. Costs 20 chemicals." helptext = "Emits a high-frequency sound that confuses and deafens humans, blows out nearby lights and overloads cyborg sensors. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat." + button_icon_state = "resonant_shriek" chemical_cost = 20 dna_cost = 2 loudness = 1 - req_human = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_resonant" - action_background_icon_state = "bg_ling" + req_human = TRUE -//A flashy ability, good for crowd control and sewing chaos. -/obj/effect/proc_holder/changeling/resonant_shriek/sting_action(mob/user) +//A flashy ability, good for crowd control and sowing chaos. +/datum/action/changeling/resonant_shriek/sting_action(mob/user) for(var/mob/living/M in get_hearers_in_view(4, user)) if(iscarbon(M)) var/mob/living/carbon/C = M @@ -32,19 +30,17 @@ playsound(get_turf(user), 'sound/effects/lingscreech.ogg', 75, TRUE, 5) return TRUE -/obj/effect/proc_holder/changeling/dissonant_shriek +/datum/action/changeling/dissonant_shriek name = "Dissonant Shriek" - desc = "We shift our vocal cords to release a high-frequency sound that overloads nearby electronics." + desc = "We shift our vocal cords to release a high-frequency sound that overloads nearby electronics. Costs 20 chemicals." helptext = "Emits a high-frequency sound that overloads nearby electronics. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat." + button_icon_state = "dissonant_shriek" chemical_cost = 20 dna_cost = 2 loudness = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_dissonant" - action_background_icon_state = "bg_ling" -//A flashy ability, good for crowd control and sewing chaos. -/obj/effect/proc_holder/changeling/dissonant_shriek/sting_action(mob/user) +//A flashy ability, good for crowd control and sowing chaos. +/datum/action/changeling/dissonant_shriek/sting_action(mob/user) for(var/obj/machinery/light/L in range(5, usr)) L.on = 1 L.break_light_tube() diff --git a/code/modules/antagonists/changeling/powers/spiders.dm b/code/modules/antagonists/changeling/powers/spiders.dm index 69900ea8f9..f31c3a6c64 100644 --- a/code/modules/antagonists/changeling/powers/spiders.dm +++ b/code/modules/antagonists/changeling/powers/spiders.dm @@ -1,16 +1,15 @@ -/obj/effect/proc_holder/changeling/spiders +/datum/action/changeling/spiders name = "Spread Infestation" - desc = "Our form divides, creating arachnids which will grow into deadly beasts." + desc = "Our form divides, creating arachnids which will grow into deadly beasts. Costs 45 chemicals." helptext = "The spiders are thoughtless creatures, and may attack their creators when fully grown. Requires at least 3 DNA gained through Absorb (regardless of current amount), and not through DNA sting. This ability is very loud, and will guarantee that our blood will react violently to heat." + button_icon_state = "spread_infestation" chemical_cost = 45 dna_cost = 1 loudness = 4 req_absorbs = 3 - action_icon = 'icons/effects/effects.dmi' - action_icon_state = "spiderling" - action_background_icon_state = "bg_ling" //Makes some spiderlings. Good for setting traps and causing general trouble. -/obj/effect/proc_holder/changeling/spiders/sting_action(mob/user) +/datum/action/changeling/spiders/sting_action(mob/user) + ..() spawn_atom_to_turf(/obj/structure/spider/spiderling/hunter, user, 2, FALSE) return TRUE diff --git a/code/modules/antagonists/changeling/powers/strained_muscles.dm b/code/modules/antagonists/changeling/powers/strained_muscles.dm index 2fdf1baf04..5d3f2cdf9e 100644 --- a/code/modules/antagonists/changeling/powers/strained_muscles.dm +++ b/code/modules/antagonists/changeling/powers/strained_muscles.dm @@ -1,19 +1,18 @@ //Strained Muscles: Temporary speed boost at the cost of rapid damage //Limited because of hardsuits and such; ideally, used for a quick getaway -/obj/effect/proc_holder/changeling/strained_muscles +/datum/action/changeling/strained_muscles name = "Strained Muscles" desc = "We evolve the ability to reduce the acid buildup in our muscles, allowing us to move much faster." helptext = "The strain will make us tired, and we will rapidly become fatigued. Standard weight restrictions, like hardsuits, still apply. Our chemical generation is drastically slowed while this is active. Cannot be used in lesser form." + button_icon_state = "strained_muscles" dna_cost = 1 - req_human = 1 + req_human = TRUE var/stacks = 0 //Increments every 5 seconds; damage increases over time - active = 0 //Whether or not you are a hedgehog - action_icon = 'icons/obj/implants.dmi' - action_icon_state = "adrenal" - action_background_icon_state = "bg_ling" + active = FALSE //Whether or not you are a hedgehog -/obj/effect/proc_holder/changeling/strained_muscles/sting_action(mob/living/carbon/user) +/datum/action/changeling/strained_muscles/sting_action(mob/living/carbon/user) + ..() var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) active = !active if(active) @@ -32,7 +31,7 @@ return TRUE -/obj/effect/proc_holder/changeling/strained_muscles/proc/muscle_loop(mob/living/carbon/user) +/datum/action/changeling/strained_muscles/proc/muscle_loop(mob/living/carbon/user) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) while(active) user.add_movespeed_modifier(/datum/movespeed_modifier/strained_muscles) diff --git a/code/modules/antagonists/changeling/powers/tiny_prick.dm b/code/modules/antagonists/changeling/powers/tiny_prick.dm index 9bda1bf5b9..351d8622c9 100644 --- a/code/modules/antagonists/changeling/powers/tiny_prick.dm +++ b/code/modules/antagonists/changeling/powers/tiny_prick.dm @@ -1,9 +1,10 @@ -/obj/effect/proc_holder/changeling/sting +/datum/action/changeling/sting//parent path, not meant for users afaik name = "Tiny Prick" - desc = "Stabby stabby." + desc = "Stabby stabby" var/sting_icon = null -/obj/effect/proc_holder/changeling/sting/Trigger(mob/user) +/datum/action/changeling/sting/Trigger() + var/mob/user = owner if(!user || !user.mind) return var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) @@ -15,15 +16,15 @@ unset_sting(user) return -/obj/effect/proc_holder/changeling/sting/proc/set_sting(mob/user) - to_chat(user, "We prepare our sting, use alt+click or middle mouse button on target to sting them.") +/datum/action/changeling/sting/proc/set_sting(mob/user) + to_chat(user, "We prepare our sting, use Alt+click or click the middle mouse button on a target to sting them.") var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) changeling.chosen_sting = src user.hud_used.lingstingdisplay.icon_state = sting_icon user.hud_used.lingstingdisplay.invisibility = 0 -/obj/effect/proc_holder/changeling/sting/proc/unset_sting(mob/user) +/datum/action/changeling/sting/proc/unset_sting(mob/user) to_chat(user, "We retract our sting, we can't sting anyone for now.") var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) changeling.chosen_sting = null @@ -37,7 +38,7 @@ if(changeling && changeling.chosen_sting) changeling.chosen_sting.unset_sting(src) -/obj/effect/proc_holder/changeling/sting/can_sting(mob/user, mob/target) +/datum/action/changeling/sting/can_sting(mob/user, mob/target) if(!..()) return var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) @@ -47,11 +48,14 @@ return if(!isturf(user.loc)) return - if(!AStar(user, target.loc, /turf/proc/Distance, changeling.sting_range, simulated_only = 0)) - return + if(!length(get_path_to(user, target, max_distance = changeling.sting_range, simulated_only = FALSE))) + return // no path within the sting's range is found. what a weird place to use the pathfinding system + if(target.mind && target.mind.has_antag_datum(/datum/antagonist/changeling)) + sting_feedback(user, target) + changeling.chem_charges -= chemical_cost return 1 -/obj/effect/proc_holder/changeling/sting/sting_feedback(mob/user, mob/target) +/datum/action/changeling/sting/sting_feedback(mob/user, mob/target) if(!target) return to_chat(user, "We stealthily sting [target.name].") @@ -60,20 +64,19 @@ return 1 -/obj/effect/proc_holder/changeling/sting/transformation +/datum/action/changeling/sting/transformation name = "Temporary Transformation Sting" - desc = "We silently sting a human, injecting a chemical that forces them to transform into a chosen being for a limited time. Additional stings extend the duration." + desc = "We silently sting a human, injecting a chemical that forces them to transform into a chosen being for a limited time. Additional stings extend the duration. Costs 10 chemicals." helptext = "The victim will transform much like a changeling would for a limited time. Does not provide a warning to others. Mutations will not be transferred, and monkeys will become human. This ability is loud, and might cause our blood to react violently to heat." + button_icon_state = "sting_transform" sting_icon = "sting_transform" chemical_cost = 10 dna_cost = 2 loudness = 1 var/datum/changelingprofile/selected_dna = null - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_sting_transform" - action_background_icon_state = "bg_ling" -/obj/effect/proc_holder/changeling/sting/transformation/Trigger(mob/user) +/datum/action/changeling/sting/transformation/Trigger() + var/mob/user = owner var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) if(changeling.chosen_sting) unset_sting(user) @@ -86,7 +89,7 @@ return ..() -/obj/effect/proc_holder/changeling/sting/transformation/can_sting(mob/user, mob/living/carbon/target) +/datum/action/changeling/sting/transformation/can_sting(mob/user, mob/living/carbon/target) if(!..()) return if((HAS_TRAIT(target, TRAIT_HUSK)) || !iscarbon(target) || (NOTRANSSTING in target.dna.species.species_traits)) @@ -94,8 +97,7 @@ return 0 return 1 -/obj/effect/proc_holder/changeling/sting/transformation/sting_action(mob/user, mob/target) - +/datum/action/changeling/sting/transformation/sting_action(mob/user, mob/target) if(ismonkey(target)) to_chat(user, "Our genes cry out as we sting [target.name]!") @@ -109,25 +111,22 @@ C.reagents.add_reagent(/datum/reagent/changeling_string,120,list("desired_dna" = selected_dna.dna)) log_combat(user, target, "stung", "transformation sting", " new identity is '[selected_dna.dna.real_name]'") - -/obj/effect/proc_holder/changeling/sting/false_armblade +/datum/action/changeling/sting/false_armblade name = "False Armblade Sting" - desc = "We silently sting a human, injecting a retrovirus that mutates their arm to temporarily appear as an armblade." + desc = "We silently sting a human, injecting a retrovirus that mutates their arm to temporarily appear as an armblade. Costs 20 chemicals." helptext = "The victim will form an armblade much like a changeling would, except the armblade is dull and useless. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat." + button_icon_state = "sting_armblade" sting_icon = "sting_armblade" chemical_cost = 20 dna_cost = 1 loudness = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_sting_fake" - action_background_icon_state = "bg_ling" /obj/item/melee/arm_blade/false desc = "A grotesque mass of flesh that used to be your arm. Although it looks dangerous at first, you can tell it's actually quite dull and useless." force = 5 //Basically as strong as a punch fake = TRUE -/obj/effect/proc_holder/changeling/sting/false_armblade/can_sting(mob/user, mob/target) +/datum/action/changeling/sting/false_armblade/can_sting(mob/user, mob/target) if(!..()) return if(isliving(target)) @@ -137,7 +136,7 @@ return 0 return 1 -/obj/effect/proc_holder/changeling/sting/false_armblade/sting_action(mob/user, mob/target) +/datum/action/changeling/sting/false_armblade/sting_action(mob/user, mob/target) log_combat(user, target, "stung", object="false armblade sting") var/obj/item/held = target.get_active_held_item() @@ -156,7 +155,7 @@ addtimer(CALLBACK(src, .proc/remove_fake, target, blade), 600) return TRUE -/obj/effect/proc_holder/changeling/sting/false_armblade/proc/remove_fake(mob/target, obj/item/melee/arm_blade/false/blade) +/datum/action/changeling/sting/false_armblade/proc/remove_fake(mob/target, obj/item/melee/arm_blade/false/blade) playsound(target, 'sound/effects/blobattack.ogg', 30, 1) target.visible_message("With a sickening crunch, \ [target] reforms [target.p_their()] [blade.name] into an arm!", @@ -166,59 +165,53 @@ qdel(blade) target.update_inv_hands() -/obj/effect/proc_holder/changeling/sting/extract_dna +/datum/action/changeling/sting/extract_dna name = "Extract DNA Sting" - desc = "We stealthily sting a target and extract their DNA." + desc = "We stealthily sting a target and extract their DNA. Costs 25 chemicals." helptext = "Will give you the DNA of your target, allowing you to transform into them." + button_icon_state = "sting_extract" sting_icon = "sting_extract" chemical_cost = 25 dna_cost = 0 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_sting_extract" - action_background_icon_state = "bg_ling" -/obj/effect/proc_holder/changeling/sting/extract_dna/can_sting(mob/user, mob/target) +/datum/action/changeling/sting/extract_dna/can_sting(mob/user, mob/target) if(..()) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) return changeling.can_absorb_dna(target) -/obj/effect/proc_holder/changeling/sting/extract_dna/sting_action(mob/user, mob/living/carbon/human/target) +/datum/action/changeling/sting/extract_dna/sting_action(mob/user, mob/living/carbon/human/target) log_combat(user, target, "stung", "extraction sting") var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) if(!(changeling.has_dna(target.dna))) changeling.add_new_profile(target) return TRUE -/obj/effect/proc_holder/changeling/sting/mute +/datum/action/changeling/sting/mute name = "Mute Sting" - desc = "We silently sting a human, completely silencing them for a short time." + desc = "We silently sting a human, completely silencing them for a short time. Costs 20 chemicals." helptext = "Does not provide a warning to the victim that they have been stung, until they try to speak and cannot. This ability is loud, and might cause our blood to react violently to heat." + button_icon_state = "sting_mute" sting_icon = "sting_mute" chemical_cost = 20 dna_cost = 2 loudness = 2 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_sting_mute" - action_background_icon_state = "bg_ling" -/obj/effect/proc_holder/changeling/sting/mute/sting_action(mob/user, mob/living/carbon/target) +/datum/action/changeling/sting/mute/sting_action(mob/user, mob/living/carbon/target) log_combat(user, target, "stung", "mute sting") target.silent += 30 return TRUE -/obj/effect/proc_holder/changeling/sting/blind +/datum/action/changeling/sting/blind name = "Blind Sting" - desc = "Temporarily blinds the target." + desc = "Temporarily blinds the target. Costs 25 chemicals." helptext = "This sting completely blinds a target for a short time. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat." + button_icon_state = "sting_blind" sting_icon = "sting_blind" chemical_cost = 25 dna_cost = 1 loudness = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_sting_blind" - action_background_icon_state = "bg_ling" -/obj/effect/proc_holder/changeling/sting/blind/sting_action(mob/user, mob/living/carbon/target) +/datum/action/changeling/sting/blind/sting_action(mob/user, mob/living/carbon/target) log_combat(user, target, "stung", "blind sting") to_chat(target, "Your eyes burn horrifically!") target.become_nearsighted(EYE_DAMAGE) @@ -226,38 +219,34 @@ target.blur_eyes(40) return TRUE -/obj/effect/proc_holder/changeling/sting/LSD +/datum/action/changeling/sting/LSD name = "Hallucination Sting" - desc = "Causes terror in the target and deals a minor amount of toxin damage." + desc = "Causes terror in the target and deals a minor amount of toxin damage. Costs 10 chemicals." helptext = "We evolve the ability to sting a target with a powerful toxic hallucinogenic chemical. The target does not notice they have been stung, and the effect begins instantaneously. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat." + button_icon_state = "sting_lsd" sting_icon = "sting_lsd" chemical_cost = 10 dna_cost = 1 loudness = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_sting_lsd" - action_background_icon_state = "bg_ling" -/obj/effect/proc_holder/changeling/sting/LSD/sting_action(mob/user, mob/target) +/datum/action/changeling/sting/LSD/sting_action(mob/user, mob/target) log_combat(user, target, "stung", "LSD sting") if(target.reagents) target.reagents.add_reagent(/datum/reagent/blob/regenerative_materia, 5) target.reagents.add_reagent(/datum/reagent/toxin/mindbreaker, 5) return TRUE -/obj/effect/proc_holder/changeling/sting/cryo +/datum/action/changeling/sting/cryo name = "Cryogenic Sting" - desc = "We silently sting a human with a cocktail of chemicals that freeze them." + desc = "We silently sting our victim with a cocktail of chemicals that freezes them from the inside. Costs 15 chemicals." helptext = "Does not provide a warning to the victim, though they will likely realize they are suddenly freezing. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat." + button_icon_state = "sting_cryo" sting_icon = "sting_cryo" chemical_cost = 15 dna_cost = 2 loudness = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_sting_cryo" - action_background_icon_state = "bg_ling" -/obj/effect/proc_holder/changeling/sting/cryo/sting_action(mob/user, mob/target) +/datum/action/changeling/sting/cryo/sting_action(mob/user, mob/target) log_combat(user, target, "stung", "cryo sting") if(target.reagents) target.reagents.add_reagent(/datum/reagent/consumable/frostoil, 30) diff --git a/code/modules/antagonists/changeling/powers/transform.dm b/code/modules/antagonists/changeling/powers/transform.dm index cfd42f05cf..72ff31d373 100644 --- a/code/modules/antagonists/changeling/powers/transform.dm +++ b/code/modules/antagonists/changeling/powers/transform.dm @@ -1,18 +1,16 @@ -/obj/effect/proc_holder/changeling/transform +/datum/action/changeling/transform name = "Transform" - desc = "We take on the appearance and voice of one we have absorbed." + desc = "We take on the appearance and voice of one we have absorbed. Costs 5 chemicals." + button_icon_state = "transform" chemical_cost = 5 dna_cost = 0 req_dna = 1 - req_human = 1 - action_icon = 'icons/mob/actions/actions_changeling.dmi' - action_icon_state = "ling_transform" - action_background_icon_state = "bg_ling" + req_human = TRUE /obj/item/clothing/glasses/changeling name = "flesh" -/obj/item/clothing/glasses/changeling/Initialize() +/obj/item/clothing/glasses/changeling/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) @@ -27,7 +25,7 @@ /obj/item/clothing/under/changeling name = "flesh" -/obj/item/clothing/under/changeling/Initialize() +/obj/item/clothing/under/changeling/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) @@ -43,7 +41,7 @@ name = "flesh" allowed = list(/obj/item/changeling) -/obj/item/clothing/suit/changeling/Initialize() +/obj/item/clothing/suit/changeling/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) @@ -58,7 +56,7 @@ /obj/item/clothing/head/changeling name = "flesh" -/obj/item/clothing/head/changeling/Initialize() +/obj/item/clothing/head/changeling/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) @@ -72,7 +70,7 @@ /obj/item/clothing/shoes/changeling name = "flesh" -/obj/item/clothing/shoes/changeling/Initialize() +/obj/item/clothing/shoes/changeling/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) @@ -87,7 +85,7 @@ /obj/item/clothing/gloves/changeling name = "flesh" -/obj/item/clothing/gloves/changeling/Initialize() +/obj/item/clothing/gloves/changeling/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) @@ -102,7 +100,7 @@ /obj/item/clothing/mask/changeling name = "flesh" -/obj/item/clothing/mask/changeling/Initialize() +/obj/item/clothing/mask/changeling/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) @@ -119,7 +117,7 @@ slot_flags = ALL allowed = list(/obj/item/changeling) -/obj/item/changeling/Initialize() +/obj/item/changeling/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) @@ -132,7 +130,7 @@ . = ..() //Change our DNA to that of somebody we've absorbed. -/obj/effect/proc_holder/changeling/transform/sting_action(mob/living/carbon/human/user) +/datum/action/changeling/transform/sting_action(mob/living/carbon/human/user) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) var/datum/changelingprofile/chosen_prof = changeling.select_dna() diff --git a/code/modules/antagonists/clockcult/clock_effect.dm b/code/modules/antagonists/clockcult/clock_effect.dm index 8e3a8f4ceb..a788677eb1 100644 --- a/code/modules/antagonists/clockcult/clock_effect.dm +++ b/code/modules/antagonists/clockcult/clock_effect.dm @@ -10,7 +10,7 @@ opacity = 0 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF -/obj/effect/clockwork/Initialize() +/obj/effect/clockwork/Initialize(mapload) . = ..() GLOB.all_clockwork_objects += src diff --git a/code/modules/antagonists/clockcult/clock_effects/city_of_cogs_rift.dm b/code/modules/antagonists/clockcult/clock_effects/city_of_cogs_rift.dm index 3609037f58..4dff21c369 100644 --- a/code/modules/antagonists/clockcult/clock_effects/city_of_cogs_rift.dm +++ b/code/modules/antagonists/clockcult/clock_effects/city_of_cogs_rift.dm @@ -16,7 +16,7 @@ /obj/effect/clockwork/city_of_cogs_rift/singularity_pull() return -/obj/effect/clockwork/city_of_cogs_rift/Initialize() +/obj/effect/clockwork/city_of_cogs_rift/Initialize(mapload) . = ..() visible_message("The air above [loc] shimmers and pops as a [name] forms there!") for(var/mob/M in GLOB.player_list) @@ -69,7 +69,7 @@ do_sparks(5, TRUE, AM) if(isliving(AM)) var/mob/living/L = AM - L.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/flash/static) + L.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/tiled/flash/static) L.clear_fullscreen("flash", 5) var/obj/item/transfer_valve/TTV = locate() in L.GetAllContents() if(TTV) diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_overlay.dm b/code/modules/antagonists/clockcult/clock_effects/clock_overlay.dm index 97d2935a86..6c9097de0e 100644 --- a/code/modules/antagonists/clockcult/clock_effects/clock_overlay.dm +++ b/code/modules/antagonists/clockcult/clock_effects/clock_overlay.dm @@ -8,7 +8,7 @@ linked.examine(user) return ..() -/obj/effect/clockwork/overlay/ex_act() +/obj/effect/clockwork/overlay/ex_act(severity, target, origin) return FALSE /obj/effect/clockwork/overlay/singularity_act() @@ -32,7 +32,7 @@ smooth = SMOOTH_TRUE layer = CLOSED_TURF_LAYER -/obj/effect/clockwork/overlay/wall/Initialize() +/obj/effect/clockwork/overlay/wall/Initialize(mapload) . = ..() queue_smooth_neighbors(src) addtimer(CALLBACK(GLOBAL_PROC, .proc/queue_smooth, src), 1) diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm index 4b88d203d6..18211d0447 100644 --- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm +++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm @@ -36,7 +36,7 @@ return TRUE . = ..() -/obj/effect/clockwork/sigil/ex_act(severity) +/obj/effect/clockwork/sigil/ex_act(severity, target, origin) visible_message("[src] scatters into thousands of particles.") qdel(src) @@ -111,6 +111,19 @@ sigil_name = "Sigil of Submission" var/glow_type = /obj/effect/temp_visual/ratvar/sigil/submission +/obj/effect/clockwork/sigil/submission/Crossed(atom/movable/AM) + . = ..() + if(istype(AM, /obj/item/aicard)) + var/obj/item/aicard/cardy = AM + if(!cardy.AI) + return + var/mob/living/silicon/ai/aiconvert = cardy.AI + if(aiconvert.stat > stat_affected) + return + if(is_servant_of_ratvar(aiconvert) || !(aiconvert.mind || aiconvert.has_status_effect(STATUS_EFFECT_SIGILMARK))) + return + sigil_effects(aiconvert) + /obj/effect/clockwork/sigil/submission/sigil_effects(mob/living/L) var/turf/T = get_turf(src) var/has_sigil = FALSE @@ -187,11 +200,11 @@ sigil_name = "Sigil of Transmission" affects_servants = TRUE -/obj/effect/clockwork/sigil/transmission/Initialize() +/obj/effect/clockwork/sigil/transmission/Initialize(mapload) . = ..() update_icon() -/obj/effect/clockwork/sigil/transmission/ex_act(severity) +/obj/effect/clockwork/sigil/transmission/ex_act(severity, target, origin) if(severity == 3) adjust_clockwork_power(500) //Light explosions charge the network! visible_message("[src] flares a brilliant orange!") @@ -216,7 +229,7 @@ else if(get_clockwork_power()) to_chat(L, "You feel a slight, static shock.") -/obj/effect/clockwork/sigil/transmission/Initialize() +/obj/effect/clockwork/sigil/transmission/Initialize(mapload) . = ..() START_PROCESSING(SSobj, src) diff --git a/code/modules/antagonists/clockcult/clock_effects/servant_blocker.dm b/code/modules/antagonists/clockcult/clock_effects/servant_blocker.dm index ce6e315cd8..5905862690 100644 --- a/code/modules/antagonists/clockcult/clock_effects/servant_blocker.dm +++ b/code/modules/antagonists/clockcult/clock_effects/servant_blocker.dm @@ -8,7 +8,7 @@ density = TRUE CanAtmosPass = ATMOS_PASS_NO -/obj/effect/clockwork/servant_blocker/Initialize() +/obj/effect/clockwork/servant_blocker/Initialize(mapload) . = ..() air_update_turf(TRUE) @@ -38,7 +38,7 @@ /obj/effect/clockwork/servant_blocker/singularity_pull() return -/obj/effect/clockwork/servant_blocker/ex_act(severity, target) +/obj/effect/clockwork/servant_blocker/ex_act(severity, target, origin) return /obj/effect/clockwork/servant_blocker/safe_throw_at() diff --git a/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm b/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm index ab8c7abd0a..79ad69b76f 100644 --- a/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm +++ b/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm @@ -17,7 +17,7 @@ var/is_stable = FALSE var/busy = FALSE //If someone is already working on closing the gateway, only needed for stable gateways but in the parent to not need typecasting -/obj/effect/clockwork/spatial_gateway/Initialize() +/obj/effect/clockwork/spatial_gateway/Initialize(mapload) . = ..() addtimer(CALLBACK(src, .proc/check_setup), 1) @@ -102,7 +102,7 @@ return TRUE return ..() -/obj/effect/clockwork/spatial_gateway/ex_act(severity) +/obj/effect/clockwork/spatial_gateway/ex_act(severity, target, origin) if(severity == 1 && uses) uses = 0 visible_message("[src] is disrupted!") @@ -251,7 +251,7 @@ name = "stable gateway" is_stable = TRUE -/obj/effect/clockwork/spatial_gateway/stable/ex_act(severity) +/obj/effect/clockwork/spatial_gateway/stable/ex_act(severity, target, origin) if(severity == 1) start_shutdown() //Yes, you can chain devastation-level explosions to delay a gateway shutdown, if you somehow manage to do it without breaking the obelisk. Is it worth it? Probably not. return TRUE diff --git a/code/modules/antagonists/clockcult/clock_helpers/clock_powerdrain.dm b/code/modules/antagonists/clockcult/clock_helpers/clock_powerdrain.dm index 76738ab1de..8d0dff0ea8 100644 --- a/code/modules/antagonists/clockcult/clock_helpers/clock_powerdrain.dm +++ b/code/modules/antagonists/clockcult/clock_helpers/clock_powerdrain.dm @@ -72,8 +72,11 @@ drain_amount: How much is drained by default; Influenced by a multiplier on most cell.use(.) spark_system.start() -/obj/mecha/power_drain(clockcult_user, drain_weapons = FALSE, recursive = FALSE, drain_amount = MIN_CLOCKCULT_POWER) - if(!clockcult_user || (occupant && !is_servant_of_ratvar(occupant))) +/obj/vehicle/sealed/mecha/power_drain(clockcult_user, drain_weapons = FALSE, recursive = FALSE, drain_amount = MIN_CLOCKCULT_POWER) + if(!clockcult_user || LAZYLEN(occupants)) + for(var/mob/living/MB in occupants) + if(is_servant_of_ratvar(MB)) + return if(recursive) var/succ = 0 for(var/atom/movable/target in contents) //Hiding in your mech won't save you. diff --git a/code/modules/antagonists/clockcult/clock_item.dm b/code/modules/antagonists/clockcult/clock_item.dm index 7c8e877fb3..f4d5352ab9 100644 --- a/code/modules/antagonists/clockcult/clock_item.dm +++ b/code/modules/antagonists/clockcult/clock_item.dm @@ -8,7 +8,7 @@ icon_state = "rare_pepe" w_class = WEIGHT_CLASS_SMALL -/obj/item/clockwork/Initialize() +/obj/item/clockwork/Initialize(mapload) . = ..() ratvar_act() GLOB.all_clockwork_objects += src diff --git a/code/modules/antagonists/clockcult/clock_items/clock_components.dm b/code/modules/antagonists/clockcult/clock_items/clock_components.dm index a9307f15e1..1e5a538772 100644 --- a/code/modules/antagonists/clockcult/clock_items/clock_components.dm +++ b/code/modules/antagonists/clockcult/clock_items/clock_components.dm @@ -172,7 +172,7 @@ var/randomspritemax = 2 var/sprite_shift = 9 -/obj/item/clockwork/alloy_shards/Initialize() +/obj/item/clockwork/alloy_shards/Initialize(mapload) . = ..() if(randomsinglesprite) replace_name_desc() diff --git a/code/modules/antagonists/clockcult/clock_items/clock_weapons/brass_claw.dm b/code/modules/antagonists/clockcult/clock_items/clock_weapons/brass_claw.dm index 340f01f6f8..b98214668a 100644 --- a/code/modules/antagonists/clockcult/clock_items/clock_weapons/brass_claw.dm +++ b/code/modules/antagonists/clockcult/clock_items/clock_weapons/brass_claw.dm @@ -26,7 +26,7 @@ var/damage_per_combo = 2 var/maximum_combo_damage = 18 //33 damage on max stacks. Usually the target will already be dead by then but if they somehow aren't, better to have this capped -/obj/item/clockwork/brass_claw/Initialize() +/obj/item/clockwork/brass_claw/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 60, 80) diff --git a/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_shield.dm b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_shield.dm index 1b6979300f..47105938e6 100644 --- a/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_shield.dm +++ b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_shield.dm @@ -7,7 +7,7 @@ item_state = "ratvarian_shield" desc = "A resilient shield made out of brass.. It feels warm to the touch." var/clockwork_desc = "A powerful shield of ratvarian making. It absorbs blocked attacks to charge devastating bashes." - armor = list("melee" = 80, "bullet" = 70, "laser" = -10, "energy" = -20, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 80, BULLET = 70, LASER = -10, ENERGY = -20, BOMB = 60, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_KINETIC_STRONG | SHIELD_ENERGY_WEAK max_integrity = 300 //High integrity, extremely strong against melee / bullets, but still quite easy to destroy with lasers and energy repair_material = /obj/item/stack/tile/brass diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm index d08caa39d7..06fea9bd91 100644 --- a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm +++ b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm @@ -8,9 +8,9 @@ resistance_flags = FIRE_PROOF | ACID_PROOF flags_inv = HIDEEARS|HIDEHAIR|HIDEFACE|HIDESNOUT mutantrace_variation = STYLE_MUZZLE - armor = list("melee" = 50, "bullet" = 70, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100, "magic" = 60, "wound" = 65) + armor = list(MELEE = 50, BULLET = 70, LASER = 50, ENERGY = 50, BOMB = 60, BIO = 0, RAD = 0, FIRE = 100, ACID = 100, MAGIC = 60, WOUND = 65) -/obj/item/clothing/head/helmet/clockwork/Initialize() +/obj/item/clothing/head/helmet/clockwork/Initialize(mapload) . = ..() ratvar_act() GLOB.all_clockwork_objects += src @@ -26,19 +26,19 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else if(GLOB.ratvar_approaches) - armor = getArmor(melee = 70, bullet = 80, laser = 10, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100,, magic = 70, wound = 75) + armor = getArmor(melee = 70, bullet = 80, laser = 65, energy = 65, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100,, magic = 70, wound = 75) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else - armor = getArmor(melee = 60, bullet = 70, laser = 0, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100, magic = 60, wound = 65) + armor = getArmor(melee = 60, bullet = 70, laser = 50, energy = 50, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100, magic = 60, wound = 65) clothing_flags &= ~STOPSPRESSUREDAMAGE max_heat_protection_temperature = initial(max_heat_protection_temperature) min_cold_protection_temperature = initial(min_cold_protection_temperature) /obj/item/clothing/head/helmet/clockwork/equipped(mob/living/user, slot) ..() - if(slot == SLOT_HEAD && !is_servant_of_ratvar(user)) + if(slot == ITEM_SLOT_HEAD && !is_servant_of_ratvar(user)) if(!iscultist(user)) to_chat(user, "\"Now now, this is for my servants, not you.\"") user.visible_message("As [user] puts [src] on, it flickers off [user.p_their()] head!", "The helmet flickers off your head, leaving only nausea!") @@ -53,7 +53,7 @@ user.adjustOrganLoss(ORGAN_SLOT_BRAIN, 30) addtimer(CALLBACK(user, /mob/living.proc/dropItemToGround, src, TRUE), 1) //equipped happens before putting stuff on(but not before picking items up), 1). thus, we need to wait for it to be on before forcing it off. -/obj/item/clothing/head/helmet/clockwork/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0) +/obj/item/clothing/head/helmet/clockwork/mob_can_equip(M, equipper, slot, disable_warning, bypass_equip_delay_self) if(equipper && !is_servant_of_ratvar(equipper)) return 0 return ..() @@ -68,11 +68,11 @@ cold_protection = CHEST|GROIN|LEGS heat_protection = CHEST|GROIN|LEGS resistance_flags = FIRE_PROOF | ACID_PROOF - armor = list("melee" = 60, "bullet" = 70, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100, "magic" = 60, "wound" = 65) + armor = list(MELEE = 60, BULLET = 70, LASER = 50, ENERGY = 50, BOMB = 60, BIO = 0, RAD = 0, FIRE = 100, ACID = 100, MAGIC = 60, WOUND = 65) allowed = list(/obj/item/clockwork, /obj/item/clothing/glasses/wraith_spectacles, /obj/item/clothing/glasses/judicial_visor, /obj/item/mmi/posibrain/soul_vessel, /obj/item/reagent_containers/food/drinks/bottle/holyoil) mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC -/obj/item/clothing/suit/armor/clockwork/Initialize() +/obj/item/clothing/suit/armor/clockwork/Initialize(mapload) . = ..() ratvar_act() GLOB.all_clockwork_objects += src @@ -88,24 +88,24 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else if(GLOB.ratvar_approaches) - armor = getArmor(melee = 70, bullet = 80, laser = 10, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100, magic = 70, wound = 75) + armor = getArmor(melee = 70, bullet = 80, laser = 65, energy = 65, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100, magic = 70, wound = 75) clothing_flags |= STOPSPRESSUREDAMAGE max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else - armor = getArmor(melee = 60, bullet = 70, laser = 0, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100, magic = 60, wound = 65) + armor = getArmor(melee = 60, bullet = 70, laser = 50, energy = 50, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100, magic = 60, wound = 65) clothing_flags &= ~STOPSPRESSUREDAMAGE max_heat_protection_temperature = initial(max_heat_protection_temperature) min_cold_protection_temperature = initial(min_cold_protection_temperature) -/obj/item/clothing/suit/armor/clockwork/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0) +/obj/item/clothing/suit/armor/clockwork/mob_can_equip(M, equipper, slot, disable_warning, bypass_equip_delay_self) if(equipper && !is_servant_of_ratvar(equipper)) return 0 return ..() /obj/item/clothing/suit/armor/clockwork/equipped(mob/living/user, slot) ..() - if(slot == SLOT_WEAR_SUIT && !is_servant_of_ratvar(user)) + if(slot == ITEM_SLOT_OCLOTHING && !is_servant_of_ratvar(user)) if(!iscultist(user)) to_chat(user, "\"Now now, this is for my servants, not you.\"") user.visible_message("As [user] puts [src] on, it flickers off [user.p_their()] body!", "The cuirass flickers off your body, leaving only nausea!") @@ -135,9 +135,9 @@ siemens_coefficient = 0 permeability_coefficient = 0.05 resistance_flags = FIRE_PROOF | ACID_PROOF - armor = list("melee" = 80, "bullet" = 70, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100, "magic" = 70, "wound" = 85) + armor = list(MELEE = 80, BULLET = 70, LASER = 50, ENERGY = 50, BOMB = 60, BIO = 0, RAD = 0, FIRE = 100, ACID = 100, MAGIC = 70, WOUND = 85) -/obj/item/clothing/gloves/clockwork/Initialize() +/obj/item/clothing/gloves/clockwork/Initialize(mapload) . = ..() ratvar_act() GLOB.all_clockwork_objects += src @@ -153,19 +153,19 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT else - armor = getArmor(melee = 80, bullet = 70, laser = 0, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100, magic = 70, wound = 85) + armor = getArmor(melee = 80, bullet = 70, laser = 50, energy = 50, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100, magic = 70, wound = 85) clothing_flags &= ~STOPSPRESSUREDAMAGE max_heat_protection_temperature = initial(max_heat_protection_temperature) min_cold_protection_temperature = initial(min_cold_protection_temperature) -/obj/item/clothing/gloves/clockwork/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0) +/obj/item/clothing/gloves/clockwork/mob_can_equip(M, equipper, slot, disable_warning, bypass_equip_delay_self) if(equipper && !is_servant_of_ratvar(equipper)) return 0 return ..() /obj/item/clothing/gloves/clockwork/equipped(mob/living/user, slot) ..() - if(slot == SLOT_GLOVES && !is_servant_of_ratvar(user)) + if(slot == ITEM_SLOT_GLOVES && !is_servant_of_ratvar(user)) if(!iscultist(user)) to_chat(user, "\"Now now, this is for my servants, not you.\"") user.visible_message("As [user] puts [src] on, it flickers off [user.p_their()] arms!", "The gauntlets flicker off your arms, leaving only nausea!") @@ -190,7 +190,7 @@ equip_delay_other = 30 resistance_flags = FIRE_PROOF | ACID_PROOF -/obj/item/clothing/shoes/clockwork/Initialize() +/obj/item/clothing/shoes/clockwork/Initialize(mapload) . = ..() ratvar_act() GLOB.all_clockwork_objects += src @@ -208,14 +208,14 @@ else clothing_flags &= ~NOSLIP -/obj/item/clothing/shoes/clockwork/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0) +/obj/item/clothing/shoes/clockwork/mob_can_equip(M, equipper, slot, disable_warning, bypass_equip_delay_self) if(equipper && !is_servant_of_ratvar(equipper)) return 0 return ..() /obj/item/clothing/shoes/clockwork/equipped(mob/living/user, slot) ..() - if(slot == SLOT_SHOES && !is_servant_of_ratvar(user)) + if(slot == ITEM_SLOT_FEET && !is_servant_of_ratvar(user)) if(!iscultist(user)) to_chat(user, "\"Now now, this is for my servants, not you.\"") user.visible_message("As [user] puts [src] on, it flickers off [user.p_their()] feet!", "The treads flicker off your feet, leaving only nausea!") diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm index 8060b7b0cd..3298196de7 100644 --- a/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm +++ b/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm @@ -70,7 +70,7 @@ /obj/item/clockwork/slab/cyborg/engineer //six scriptures, plus a fabricator. Might revert this if its too OP, I just thought that engineering borgs should get the all the structures quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transmission, /datum/clockwork_scripture/create_object/stargazer, \ - /datum/clockwork_scripture/create_object/ocular_warden, /datum/clockwork_scripture/create_object/clockwork_obelisk, /datum/clockwork_scripture/create_object/mania_motor) + /datum/clockwork_scripture/create_object/ocular_warden, /datum/clockwork_scripture/create_object/clockwork_obelisk/cyborg, /datum/clockwork_scripture/create_object/mania_motor/cyborg) /obj/item/clockwork/slab/cyborg/medical //six scriptures, plus a spear quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/ranged_ability/sentinels_compromise, \ @@ -90,7 +90,7 @@ */ /obj/item/clockwork/slab/cyborg/service //six scriptures, plus xray vision quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/create_object/replicant,/datum/clockwork_scripture/create_object/stargazer, \ - /datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/create_object/clockwork_obelisk) + /datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/create_object/clockwork_obelisk/cyborg) /obj/item/clockwork/slab/cyborg/miner //three scriptures, plus a spear and xray vision quickbound = list(/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/channeled/belligerent, /datum/clockwork_scripture/channeled/volt_blaster) @@ -106,7 +106,7 @@ if(!GLOB.ratvar_awakens) SStgui.close_uis(src) -/obj/item/clockwork/slab/Initialize() +/obj/item/clockwork/slab/Initialize(mapload) . = ..() update_slab_info(src) START_PROCESSING(SSobj, src) @@ -264,7 +264,9 @@ ui.open() /obj/item/clockwork/slab/ui_data(mob/user) //we display a lot of data via TGUI - . = list() + . = ..() + if(!.) + return .["recollection"] = recollecting .["power"] = DisplayPower(get_clockwork_power()) .["power_unformatted"] = get_clockwork_power() @@ -275,6 +277,7 @@ if(S.tier == SCRIPTURE_PERIPHERAL) // This tier is skiped because this contains basetype stuff continue + // FUTURE IMPL: cache these perhaps? var/list/data = list() data["name"] = S.name data["descname"] = S.descname diff --git a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm index daee9f5c2c..be832f7e52 100644 --- a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm +++ b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm @@ -11,7 +11,7 @@ var/creation_message = "The chassis shudders and hums to life!" var/construct_type //The construct this shell will create -/obj/item/clockwork/construct_chassis/Initialize() +/obj/item/clockwork/construct_chassis/Initialize(mapload) . = ..() var/area/A = get_area(src) if(A && construct_type) @@ -92,7 +92,7 @@ var/infinite_resources = FALSE //No. var/static/obj/item/seasonal_hat //Share it with all other scarabs, since we're from the same cult! -/obj/item/clockwork/construct_chassis/cogscarab/Initialize() +/obj/item/clockwork/construct_chassis/cogscarab/Initialize(mapload) . = ..() if(GLOB.servants_active) infinite_resources = FALSE //This check is relatively irrelevant until *someone* makes the infinite resources var default to true again, so, leaving it in. @@ -117,4 +117,4 @@ S.no_cost = TRUE if(seasonal_hat && seasonal_hat != "none") var/obj/item/hat = new seasonal_hat(construct) - construct.equip_to_slot_or_del(hat, SLOT_HEAD) + construct.equip_to_slot_or_del(hat, ITEM_SLOT_HEAD) diff --git a/code/modules/antagonists/clockcult/clock_items/integration_cog.dm b/code/modules/antagonists/clockcult/clock_items/integration_cog.dm index ab8e30c8bb..45c3f757a4 100644 --- a/code/modules/antagonists/clockcult/clock_items/integration_cog.dm +++ b/code/modules/antagonists/clockcult/clock_items/integration_cog.dm @@ -12,7 +12,7 @@ item_flags = NOBLUDGEON var/obj/machinery/power/apc/apc -/obj/item/clockwork/integration_cog/Initialize() +/obj/item/clockwork/integration_cog/Initialize(mapload) . = ..() transform *= 0.5 //little cog! diff --git a/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm b/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm index 6a53097922..dc53217486 100644 --- a/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm +++ b/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm @@ -13,7 +13,7 @@ var/recharge_cooldown = 300 //divided by 10 if ratvar is alive actions_types = list(/datum/action/item_action/clock/toggle_visor) -/obj/item/clothing/glasses/judicial_visor/Initialize() +/obj/item/clothing/glasses/judicial_visor/Initialize(mapload) . = ..() GLOB.all_clockwork_objects += src blaster = new(src) @@ -28,13 +28,13 @@ return ..() /obj/item/clothing/glasses/judicial_visor/item_action_slot_check(slot, mob/user, datum/action/A) - if(slot != SLOT_GLASSES) + if(slot != ITEM_SLOT_EYES) return 0 return ..() /obj/item/clothing/glasses/judicial_visor/equipped(mob/living/user, slot) ..() - if(slot != SLOT_GLASSES) + if(slot != ITEM_SLOT_EYES) update_status(FALSE) if(blaster.ranged_ability_user) blaster.remove_ranged_ability() @@ -55,13 +55,13 @@ addtimer(CALLBACK(src, .proc/check_on_mob, user), 1) //dropped is called before the item is out of the slot, so we need to check slightly later /obj/item/clothing/glasses/judicial_visor/proc/check_on_mob(mob/user) - if(user && src != user.get_item_by_slot(SLOT_GLASSES)) //if we happen to check and we AREN'T in the slot, we need to remove our shit from whoever we got dropped from + if(user && src != user.get_item_by_slot(ITEM_SLOT_EYES)) //if we happen to check and we AREN'T in the slot, we need to remove our shit from whoever we got dropped from update_status(FALSE) if(blaster.ranged_ability_user) blaster.remove_ranged_ability() /obj/item/clothing/glasses/judicial_visor/attack_self(mob/user) - if(is_servant_of_ratvar(user) && src == user.get_item_by_slot(SLOT_GLASSES)) + if(is_servant_of_ratvar(user) && src == user.get_item_by_slot(ITEM_SLOT_EYES)) blaster.toggle(user) /obj/item/clothing/glasses/judicial_visor/proc/update_status(change_to) @@ -89,7 +89,7 @@ if(!src) return 0 recharging = FALSE - if(user && src == user.get_item_by_slot(SLOT_GLASSES)) + if(user && src == user.get_item_by_slot(ITEM_SLOT_EYES)) to_chat(user, "Your [name] hums. It is ready.") else active = FALSE @@ -115,7 +115,7 @@ /obj/effect/proc_holder/judicial_visor/InterceptClickOn(mob/living/caller, params, atom/target) if(..()) return - if(ranged_ability_user.incapacitated() || !visor || visor != ranged_ability_user.get_item_by_slot(SLOT_GLASSES)) + if(ranged_ability_user.incapacitated() || !visor || visor != ranged_ability_user.get_item_by_slot(ITEM_SLOT_EYES)) remove_ranged_ability() return @@ -214,5 +214,5 @@ sleep(3) //so the animation completes properly qdel(src) -/obj/effect/clockwork/judicial_marker/ex_act(severity) +/obj/effect/clockwork/judicial_marker/ex_act(severity, target, origin) return diff --git a/code/modules/antagonists/clockcult/clock_items/soul_vessel.dm b/code/modules/antagonists/clockcult/clock_items/soul_vessel.dm index 6bec6e3bc7..f0e4863c4e 100644 --- a/code/modules/antagonists/clockcult/clock_items/soul_vessel.dm +++ b/code/modules/antagonists/clockcult/clock_items/soul_vessel.dm @@ -25,7 +25,7 @@ force_replace_ai_name = TRUE overrides_aicore_laws = TRUE -/obj/item/mmi/posibrain/soul_vessel/Initialize() +/obj/item/mmi/posibrain/soul_vessel/Initialize(mapload) . = ..() radio.on = FALSE laws = new /datum/ai_laws/ratvar() diff --git a/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm b/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm index 5e25b8de82..c48696aa8c 100644 --- a/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm +++ b/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm @@ -12,7 +12,7 @@ visor_vars_to_toggle = NONE //we don't actually toggle anything we just set it tint = 3 //this'll get reset, but it won't handle vision updates properly otherwise -/obj/item/clothing/glasses/wraith_spectacles/Initialize() +/obj/item/clothing/glasses/wraith_spectacles/Initialize(mapload) . = ..() GLOB.all_clockwork_objects += src @@ -75,7 +75,7 @@ /obj/item/clothing/glasses/wraith_spectacles/equipped(mob/living/user, slot) ..() - if(slot != SLOT_GLASSES || up) + if(slot != ITEM_SLOT_EYES || up) return if(HAS_TRAIT(user, TRAIT_BLIND)) to_chat(user, "\"You're blind, idiot. Stop embarrassing yourself.\"" ) diff --git a/code/modules/antagonists/clockcult/clock_mobs.dm b/code/modules/antagonists/clockcult/clock_mobs.dm index 2f00fd4e4a..a2263401aa 100644 --- a/code/modules/antagonists/clockcult/clock_mobs.dm +++ b/code/modules/antagonists/clockcult/clock_mobs.dm @@ -23,7 +23,7 @@ var/playstyle_string = "You are a bug, yell at whoever spawned you!" var/empower_string = "You have nothing to empower, yell at the coders!" //Shown to the mob when the herald beacon activates -/mob/living/simple_animal/hostile/clockwork/Initialize() +/mob/living/simple_animal/hostile/clockwork/Initialize(mapload) . = ..() update_values() @@ -43,7 +43,7 @@ /mob/living/simple_animal/hostile/clockwork/examine(mob/user) var/t_He = p_they(TRUE) var/t_s = p_s() - var/msg = "*---------*\nThis is [icon2html(src, user)] \a [src]!\n" + var/msg = "This is [icon2html(src, user)] \a [src]!\n" msg += "[desc]\n" if(health < maxHealth) msg += "" @@ -55,7 +55,7 @@ var/addendum = examine_info() if(addendum) msg += "[addendum]\n" - msg += "*---------*" + msg += "" return list(msg) diff --git a/code/modules/antagonists/clockcult/clock_mobs/clockwork_guardian.dm b/code/modules/antagonists/clockcult/clock_mobs/clockwork_guardian.dm index 5060f516c7..c937b27f16 100644 --- a/code/modules/antagonists/clockcult/clock_mobs/clockwork_guardian.dm +++ b/code/modules/antagonists/clockcult/clock_mobs/clockwork_guardian.dm @@ -34,11 +34,11 @@ Stay near your host to protect and heal them; being too far from your host will rapidly cause you massive damage. Recall to your host if you are too weak and believe you cannot continue \ fighting safely. As a final note, you should probably avoid harming any fellow servants of Ratvar." -/mob/living/simple_animal/hostile/clockwork/guardian/Initialize() +/mob/living/simple_animal/hostile/clockwork/guardian/Initialize(mapload) . = ..() true_name = pick(possible_true_names) -/mob/living/simple_animal/hostile/clockwork/guardian/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/clockwork/guardian/BiologicalLife(delta_time, times_fired) ..() if(is_in_host()) if(!is_servant_of_ratvar(host)) diff --git a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm index d58608652c..cab5aec636 100644 --- a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm +++ b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm @@ -39,7 +39,7 @@ if(!shield_health) return "Its shield has been destroyed!" -/mob/living/simple_animal/hostile/clockwork/marauder/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/clockwork/marauder/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return var/turf/T = get_turf(src) diff --git a/code/modules/antagonists/clockcult/clock_scripture.dm b/code/modules/antagonists/clockcult/clock_scripture.dm index 6922c7cd81..feb724dceb 100644 --- a/code/modules/antagonists/clockcult/clock_scripture.dm +++ b/code/modules/antagonists/clockcult/clock_scripture.dm @@ -310,7 +310,7 @@ Judgement 80k power or nine converts var/datum/progressbar/progbar /datum/clockwork_scripture/ranged_ability/Destroy() - qdel(progbar) + progbar.end_progress() return ..() /datum/clockwork_scripture/ranged_ability/scripture_effects() @@ -333,7 +333,7 @@ Judgement 80k power or nine converts (allow_mobility || (can_recite() && T == get_turf(invoker)))) if(progbar) if(slab.slab_ability.in_progress) - qdel(progbar) + progbar.end_progress() else progbar.update(end_time - world.time) stoplag(1) diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm index 85450dc152..f367842c23 100644 --- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm @@ -207,20 +207,20 @@ /datum/clockwork_scripture/create_object/summon_arbiter descname = "Powerful Assault Mech" name = "Summon Neovgre, the Anima Bulwark" - desc = "Calls forth the mighty Anima Bulwark, a mech with superior defensive and offensive capabilities. It will \ + desc = "Calls forth the mighty Anima Bulwark, a two-person mech with superior defensive and offensive capabilities. It will \ steadily regenerate HP and triple its regeneration speed while standing \ on a clockwork tile. It will automatically draw power from nearby sigils of \ transmission should the need arise. Its Arbiter laser cannon can decimate foes \ from a range and is capable of smashing through any barrier presented to it. \ - Be warned however, choosing to pilot Neovgre is a lifetime commitment, once you are \ - in you cannot leave and when it is destroyed it will explode catastrophically, with you inside." + Be warned however, choosing to pilot or man Neovgre is a lifetime commitment, once you are \ + in you cannot leave and when it is destroyed it will explode catastrophically, with everyone inside." invocations = list("By the strength of the alloy...!!", "...call forth the Arbiter!!") channel_time = 200 // This is a strong fucking weapon, 20 seconds channel time is getting off light I tell ya. - power_cost = 75000 //75 KW + power_cost = 40000 //40 KW. Why the hell did I think making this cost 5k more than the ARK was a good idea-KeRSe usage_tip = "Neovgre is a powerful mech that will crush your enemies!" invokers_required = 5 multiple_invokers_used = TRUE - object_path = /obj/mecha/combat/neovgre + object_path = /obj/vehicle/sealed/mecha/combat/neovgre tier = SCRIPTURE_APPLICATION primary_component = BELLIGERENT_EYE sort_priority = 8 @@ -231,3 +231,31 @@ to_chat(invoker, "\"Only one of my weapons may exist in this temporal stream!\"") return FALSE return ..() + +/datum/clockwork_scripture/create_object/construct/cogscarab + descname = "Building Construct" + name = "Cogscarab" + desc = "Creates a shell for a cogscarab, a drone that helps build your base!" + invocations = list("Arise, drone!", "Create defenses for the true light!") + channel_time = 80 + power_cost = 8000 + creator_message = "Your slab disgorges several chunks of replicant alloy that form into a spiderlike shell." + usage_tip = "These machines will help you get a base built up while you go out to look for more followers." + tier = SCRIPTURE_APPLICATION + one_per_tile = TRUE + primary_component = BELLIGERENT_EYE + sort_priority = 9 + quickbind = TRUE + quickbind_desc = "Creates a cogscarab, good for the backline." + object_path = /obj/item/clockwork/construct_chassis/cogscarab/ + construct_type = /mob/living/simple_animal/drone/cogscarab + combat_construct = FALSE + +/datum/clockwork_scripture/create_object/construct/cogscarab/update_construct_limit() + var/human_servants = 0 + for(var/V in SSticker.mode.servants_of_ratvar) + var/datum/mind/M = V + var/mob/living/L = M.current + if(ishuman(L) && L.stat != DEAD) + human_servants++ + construct_limit = round(clamp((human_servants / 4), 1, 3)) //1 per 4 human servants, maximum of 3 diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_cyborg.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_cyborg.dm index 3dacecf6b4..943b61b9be 100644 --- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_cyborg.dm +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_cyborg.dm @@ -44,3 +44,15 @@ Left-click a target to place a Judicial Marker!\n\ Click your slab to cancel." timeout_time = 50 + +//These are exactly the same as the default scriptures, but cyborgs don't need a second person to create them +/datum/clockwork_scripture/create_object/mania_motor/cyborg + invokers_required = 1 + tier = SCRIPTURE_PERIPHERAL + multiple_invokers_used = FALSE + + +/datum/clockwork_scripture/create_object/clockwork_obelisk/cyborg + invokers_required = 1 + tier = SCRIPTURE_PERIPHERAL + multiple_invokers_used = FALSE diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm index 7ba4ce0936..be4785f4a7 100644 --- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm @@ -200,18 +200,18 @@ /datum/action/innate/clockwork_armaments/Activate() var/do_message = 0 - var/obj/item/I = owner.get_item_by_slot(SLOT_WEAR_SUIT) + var/obj/item/I = owner.get_item_by_slot(ITEM_SLOT_OCLOTHING) if(remove_item_if_better(I, owner)) - do_message += owner.equip_to_slot_or_del(new/obj/item/clothing/suit/armor/clockwork(null), SLOT_WEAR_SUIT) - I = owner.get_item_by_slot(SLOT_HEAD) + do_message += owner.equip_to_slot_or_del(new/obj/item/clothing/suit/armor/clockwork(null), ITEM_SLOT_OCLOTHING) + I = owner.get_item_by_slot(ITEM_SLOT_HEAD) if(remove_item_if_better(I, owner)) - do_message += owner.equip_to_slot_or_del(new/obj/item/clothing/head/helmet/clockwork(null), SLOT_HEAD) - I = owner.get_item_by_slot(SLOT_GLOVES) + do_message += owner.equip_to_slot_or_del(new/obj/item/clothing/head/helmet/clockwork(null), ITEM_SLOT_HEAD) + I = owner.get_item_by_slot(ITEM_SLOT_GLOVES) if(remove_item_if_better(I, owner)) - do_message += owner.equip_to_slot_or_del(new/obj/item/clothing/gloves/clockwork(null), SLOT_GLOVES) - I = owner.get_item_by_slot(SLOT_SHOES) + do_message += owner.equip_to_slot_or_del(new/obj/item/clothing/gloves/clockwork(null), ITEM_SLOT_GLOVES) + I = owner.get_item_by_slot(ITEM_SLOT_FEET) if(remove_item_if_better(I, owner)) - do_message += owner.equip_to_slot_or_del(new/obj/item/clothing/shoes/clockwork(null), SLOT_SHOES) + do_message += owner.equip_to_slot_or_del(new/obj/item/clothing/shoes/clockwork(null), ITEM_SLOT_FEET) if(do_message) owner.visible_message("Strange armor appears on [owner]!", "A bright shimmer runs down your body, equipping you with Ratvarian armor.") playsound(owner, 'sound/magic/clockwork/fellowship_armory.ogg', 15 * do_message, TRUE) //get sound loudness based on how much we equipped @@ -309,16 +309,16 @@ continue T = get_turf(M) var/heal_ticks = 0 //one heal tick for each piece of ratvarian armor worn - var/obj/item/I = H.get_item_by_slot(SLOT_WEAR_SUIT) + var/obj/item/I = H.get_item_by_slot(ITEM_SLOT_OCLOTHING) if(is_type_in_typecache(I, ratvarian_armor_typecache)) heal_ticks++ - I = H.get_item_by_slot(SLOT_HEAD) + I = H.get_item_by_slot(ITEM_SLOT_HEAD) if(is_type_in_typecache(I, ratvarian_armor_typecache)) heal_ticks++ - I = H.get_item_by_slot(SLOT_GLOVES) + I = H.get_item_by_slot(ITEM_SLOT_GLOVES) if(is_type_in_typecache(I, ratvarian_armor_typecache)) heal_ticks++ - I = H.get_item_by_slot(SLOT_SHOES) + I = H.get_item_by_slot(ITEM_SLOT_FEET) if(is_type_in_typecache(I, ratvarian_armor_typecache)) heal_ticks++ if(heal_ticks) diff --git a/code/modules/antagonists/clockcult/clock_structure.dm b/code/modules/antagonists/clockcult/clock_structure.dm index 380e93f102..2884886e47 100644 --- a/code/modules/antagonists/clockcult/clock_structure.dm +++ b/code/modules/antagonists/clockcult/clock_structure.dm @@ -18,7 +18,7 @@ var/construction_value = 0 //How much value the structure contributes to the overall "power" of the structures on the station var/immune_to_servant_attacks = FALSE //if we ignore attacks from servants of ratvar instead of taking damage -/obj/structure/destructible/clockwork/Initialize() +/obj/structure/destructible/clockwork/Initialize(mapload) . = ..() change_construction_value(construction_value) GLOB.all_clockwork_objects += src @@ -72,11 +72,6 @@ return FALSE return ..() -/obj/structure/destructible/clockwork/mech_melee_attack(obj/mecha/M) - if(M.occupant && is_servant_of_ratvar(M.occupant) && immune_to_servant_attacks) - return FALSE - return ..() - /obj/structure/destructible/clockwork/proc/get_efficiency_mod() if(GLOB.ratvar_awakens) return 2 @@ -134,7 +129,7 @@ density = FALSE resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF | FREEZE_PROOF -/obj/structure/destructible/clockwork/massive/Initialize() +/obj/structure/destructible/clockwork/massive/Initialize(mapload) . = ..() GLOB.poi_list += src diff --git a/code/modules/antagonists/clockcult/clock_structures/_trap_object.dm b/code/modules/antagonists/clockcult/clock_structures/_trap_object.dm index 47a37583ba..29b8a1f010 100644 --- a/code/modules/antagonists/clockcult/clock_structures/_trap_object.dm +++ b/code/modules/antagonists/clockcult/clock_structures/_trap_object.dm @@ -5,7 +5,7 @@ clockwork_desc = "A trap that shouldn't exist, and you should report this as a bug." var/list/wired_to -/obj/structure/destructible/clockwork/trap/Initialize() +/obj/structure/destructible/clockwork/trap/Initialize(mapload) . = ..() wired_to = list() @@ -80,7 +80,7 @@ break_message = "The trigger breaks apart!" density = FALSE -/obj/structure/destructible/clockwork/trap/trigger/Initialize() +/obj/structure/destructible/clockwork/trap/trigger/Initialize(mapload) . = ..() for(var/obj/structure/destructible/clockwork/trap/T in get_turf(src)) if(!istype(T, /obj/structure/destructible/clockwork/trap/trigger)) diff --git a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm index 973b615f4a..92225990dd 100644 --- a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm +++ b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm @@ -33,7 +33,7 @@ var/recalls_remaining = 1 var/recalling -/obj/structure/destructible/clockwork/massive/celestial_gateway/Initialize() +/obj/structure/destructible/clockwork/massive/celestial_gateway/Initialize(mapload) . = ..() INVOKE_ASYNC(src, .proc/spawn_animation) glow = new(get_turf(src)) @@ -141,7 +141,7 @@ if(isliving(M.current) && M.current.stat != DEAD) var/turf/t_turf = isAI(M.current) ? get_step(get_step(src, NORTH),NORTH) : get_turf(src) // AI too fat, must make sure it always ends up a 2 tiles north instead of on the ark. do_teleport(M.current, t_turf, channel = TELEPORT_CHANNEL_CULT, forced = TRUE) - M.current.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/flash) + M.current.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/tiled/flash) M.current.clear_fullscreen("flash", 5) playsound(src, 'sound/magic/clockwork/invoke_general.ogg', 50, FALSE) recalls_remaining-- @@ -197,9 +197,9 @@ glow = new /obj/effect/clockwork/overlay/gateway_glow(get_turf(src)) glow.linked = src -/obj/structure/destructible/clockwork/massive/celestial_gateway/ex_act(severity) +/obj/structure/destructible/clockwork/massive/celestial_gateway/ex_act(severity, target, origin) var/damage = max((obj_integrity * 0.7) / severity, 100) //requires multiple bombs to take down - take_damage(damage, BRUTE, "bomb", 0) + take_damage(damage, BRUTE, BOMB, 0) /obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_time(var/deciseconds = TRUE) if(seconds_until_activation) @@ -253,7 +253,7 @@ purpose_fulfilled = TRUE make_glow() animate(glow, transform = matrix() * 1.5, alpha = 255, time = 125) - sound_to_playing_players(volume = 100, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/ratvar_rises.ogg')) //End the sounds + sound_to_playing_players('sound/effects/ratvar_rises.ogg', 90, FALSE, channel = CHANNEL_JUSTICAR_ARK) sleep(125) make_glow() animate(glow, transform = matrix() * 3, alpha = 0, time = 5) @@ -301,7 +301,7 @@ for(var/obj/O in orange(1, src)) if(!O.pulledby && !iseffect(O) && O.density) if(!step_away(O, src, 2) || get_dist(O, src) < 2) - O.take_damage(50, BURN, "bomb") + O.take_damage(50, BURN, BOMB) O.update_icon() conversion_pulse() //Converts the nearby area into clockcult-style @@ -311,26 +311,26 @@ var/turf/T = get_turf(M) if(is_servant_of_ratvar(M) && (!T || T.z != z)) M.forceMove(get_step(src, SOUTH)) - M.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/flash) + M.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/tiled/flash) M.clear_fullscreen("flash", 5) progress_in_seconds += GATEWAY_SUMMON_RATE switch(progress_in_seconds) if(-INFINITY to GATEWAY_REEBE_FOUND) if(!second_sound_played) sound_to_playing_players('sound/magic/clockwork/invoke_general.ogg', 30, FALSE) - sound_to_playing_players(volume = 10, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_charging.ogg', TRUE)) + sound_to_playing_players('sound/effects/clockcult_gateway_charging.ogg', 10, FALSE, channel = CHANNEL_JUSTICAR_ARK) second_sound_played = TRUE make_glow() glow.icon_state = "clockwork_gateway_charging" if(GATEWAY_REEBE_FOUND to GATEWAY_RATVAR_COMING) if(!third_sound_played) - sound_to_playing_players(volume = 30, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_active.ogg', TRUE)) + sound_to_playing_players('sound/effects/clockcult_gateway_active.ogg', 30, FALSE, channel = CHANNEL_JUSTICAR_ARK) third_sound_played = TRUE make_glow() glow.icon_state = "clockwork_gateway_active" if(GATEWAY_RATVAR_COMING to GATEWAY_RATVAR_ARRIVAL) if(!fourth_sound_played) - sound_to_playing_players(volume = 70, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_closing.ogg', TRUE)) + sound_to_playing_players('sound/effects/clockcult_gateway_closing.ogg', 70, FALSE, channel = CHANNEL_JUSTICAR_ARK) fourth_sound_played = TRUE make_glow() glow.icon_state = "clockwork_gateway_closing" diff --git a/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm b/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm index 2b4b797b4d..bb05427e25 100644 --- a/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm +++ b/code/modules/antagonists/clockcult/clock_structures/clockwork_obelisk.dm @@ -16,7 +16,7 @@ var/hierophant_cost = MIN_CLOCKCULT_POWER //how much it costs to broadcast with large text var/gateway_cost = 2000 //how much it costs to open a gateway -/obj/structure/destructible/clockwork/powered/clockwork_obelisk/Initialize() +/obj/structure/destructible/clockwork/powered/clockwork_obelisk/Initialize(mapload) . = ..() toggle(1) diff --git a/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm b/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm index f8a3afbf91..8245f48a84 100644 --- a/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm +++ b/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm @@ -17,7 +17,7 @@ var/votes_needed = 0 //How many votes are needed to activate the beacon var/available = FALSE //If the beacon can be used -/obj/structure/destructible/clockwork/heralds_beacon/Initialize() +/obj/structure/destructible/clockwork/heralds_beacon/Initialize(mapload) . = ..() voters = list() START_PROCESSING(SSprocessing, src) diff --git a/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm b/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm index 00db2b0d72..c81b05145e 100644 --- a/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm +++ b/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm @@ -16,7 +16,7 @@ var/atom/movable/target var/list/idle_messages = list(" sulkily glares around.", " lazily drifts from side to side.", " looks around for something to burn.", " slowly turns in circles.") -/obj/structure/destructible/clockwork/ocular_warden/Initialize() +/obj/structure/destructible/clockwork/ocular_warden/Initialize(mapload) . = ..() START_PROCESSING(SSfastprocess, src) @@ -76,8 +76,8 @@ L.adjust_fire_stacks(damage_per_tick) L.IgniteMob() else if(ismecha(target)) - var/obj/mecha/M = target - M.take_damage(damage_per_tick * get_efficiency_mod(), BURN, "melee", 1, get_dir(src, M)) + var/obj/vehicle/sealed/mecha/M = target + M.take_damage(damage_per_tick * get_efficiency_mod(), BURN, MELEE, 1, get_dir(src, M)) new /obj/effect/temp_visual/ratvar/ocular_warden(get_turf(target)) @@ -91,8 +91,8 @@ var/mob/living/L = target to_chat(L, "\"I SEE YOU!\"\n[src]'s gaze [GLOB.ratvar_awakens ? "melts you alive" : "burns you"]!") else if(ismecha(target)) - var/obj/mecha/M = target - to_chat(M.occupant, "\"I SEE YOU!\"" ) + var/obj/vehicle/sealed/mecha/M = target + to_chat(M.occupants, "\"I SEE YOU!\"" ) else if(prob(0.5)) //Extremely low chance because of how fast the subsystem it uses processes if(prob(50)) visible_message("[src][pick(idle_messages)]") @@ -131,8 +131,11 @@ . += L var/list/viewcache = list() for(var/N in GLOB.mechas_list) - var/obj/mecha/M = N - if(get_dist(M, src) <= sight_range && M.occupant && !is_servant_of_ratvar(M.occupant)) + var/obj/vehicle/sealed/mecha/M = N + if(get_dist(M, src) <= sight_range && LAZYLEN(M.occupants)) + for(var/mob/living/MB in M.occupants) + if(is_servant_of_ratvar(MB)) + return if(!length(viewcache)) for (var/obj/Z in view(sight_range, src)) viewcache += Z diff --git a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm index 51f8dc7101..da04353974 100644 --- a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm +++ b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm @@ -17,7 +17,7 @@ var/convert_range = 10 obj_flags = CAN_BE_HIT | DANGEROUS_POSSESSION -/obj/structure/destructible/clockwork/massive/ratvar/Initialize() +/obj/structure/destructible/clockwork/massive/ratvar/Initialize(mapload) . = ..() GLOB.ratvar_awakens++ for(var/obj/O in GLOB.all_clockwork_objects) diff --git a/code/modules/antagonists/clockcult/clock_structures/reflector.dm b/code/modules/antagonists/clockcult/clock_structures/reflector.dm index e734429524..7152953c6c 100644 --- a/code/modules/antagonists/clockcult/clock_structures/reflector.dm +++ b/code/modules/antagonists/clockcult/clock_structures/reflector.dm @@ -16,7 +16,7 @@ var/ini_dir = null -/obj/structure/destructible/clockwork/reflector/Initialize() +/obj/structure/destructible/clockwork/reflector/Initialize(mapload) . = ..() allowed_projectile_typecache = typecacheof(allowed_projectile_typecache) diff --git a/code/modules/antagonists/clockcult/clock_structures/stargazer.dm b/code/modules/antagonists/clockcult/clock_structures/stargazer.dm index dea8f428ba..178b78ff13 100644 --- a/code/modules/antagonists/clockcult/clock_structures/stargazer.dm +++ b/code/modules/antagonists/clockcult/clock_structures/stargazer.dm @@ -16,7 +16,7 @@ light_color = "#DAAA18" var/star_light_star_bright = FALSE //If this stargazer can see starlight -/obj/structure/destructible/clockwork/stargazer/Initialize() +/obj/structure/destructible/clockwork/stargazer/Initialize(mapload) . = ..() START_PROCESSING(SSprocessing, src) diff --git a/code/modules/antagonists/clockcult/clock_structures/taunting_trail.dm b/code/modules/antagonists/clockcult/clock_structures/taunting_trail.dm index 98b3c32b0f..5305758b25 100644 --- a/code/modules/antagonists/clockcult/clock_structures/taunting_trail.dm +++ b/code/modules/antagonists/clockcult/clock_structures/taunting_trail.dm @@ -14,7 +14,7 @@ debris = list() var/timerid -/obj/structure/destructible/clockwork/taunting_trail/Initialize() +/obj/structure/destructible/clockwork/taunting_trail/Initialize(mapload) . = ..() timerid = QDEL_IN(src, 15) var/obj/structure/destructible/clockwork/taunting_trail/Tt = locate(/obj/structure/destructible/clockwork/taunting_trail) in loc diff --git a/code/modules/antagonists/clockcult/clock_structures/trap_triggers/pressure_sensor_mech.dm b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/pressure_sensor_mech.dm index 21735ad6d7..55143fae66 100644 --- a/code/modules/antagonists/clockcult/clock_structures/trap_triggers/pressure_sensor_mech.dm +++ b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/pressure_sensor_mech.dm @@ -9,12 +9,14 @@ /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor/mech/Crossed(atom/movable/AM) . = ..() - if(!istype(AM,/obj/mecha/)) + if(!istype(AM,/obj/vehicle/sealed/mecha/)) return - var/obj/mecha/M = AM - if(M.occupant && is_servant_of_ratvar(M.occupant)) - return + var/obj/vehicle/sealed/mecha/M = AM + if(LAZYLEN(M.occupants)) + for(var/mob/living/MB in M.occupants) + if(is_servant_of_ratvar(MB)) + return audible_message("*click*") playsound(src, 'sound/items/screwdriver2.ogg', 50, TRUE) activate() diff --git a/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm b/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm index e8ae133ede..a7c1f81f06 100644 --- a/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm +++ b/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm @@ -13,7 +13,7 @@ var/wiggle_wiggle var/mutable_appearance/impale_overlay //This is applied to any mob impaled so that they visibly have the skewer coming through their chest -/obj/structure/destructible/clockwork/trap/brass_skewer/Initialize() +/obj/structure/destructible/clockwork/trap/brass_skewer/Initialize(mapload) . = ..() START_PROCESSING(SSfastprocess, src) @@ -68,9 +68,9 @@ mouse_opacity = MOUSE_OPACITY_OPAQUE //So players can interact with the tile it's on to pull them off buckle_mob(squirrel, TRUE) else - var/obj/mecha/M = locate() in get_turf(src) + var/obj/vehicle/sealed/mecha/M = locate() in get_turf(src) if(M) - M.take_damage(50,BRUTE,"melee") + M.take_damage(50,BRUTE,MELEE) M.visible_message("A massive brass spike erupts from the ground, penetrating \the [M] and shattering the trap into pieces!") addtimer(CALLBACK(src, .proc/take_damage, max_integrity), 1) else diff --git a/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm b/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm index 7e4822b622..20cf8711e0 100644 --- a/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm +++ b/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm @@ -15,7 +15,7 @@ /obj/structure/destructible/clockwork/wall_gear/displaced anchored = FALSE -/obj/structure/destructible/clockwork/wall_gear/Initialize() +/obj/structure/destructible/clockwork/wall_gear/Initialize(mapload) . = ..() new /obj/effect/temp_visual/ratvar/gear(get_turf(src)) diff --git a/code/modules/antagonists/clockcult/clockcult.dm b/code/modules/antagonists/clockcult/clockcult.dm index 8bf26d6397..4e993763e7 100644 --- a/code/modules/antagonists/clockcult/clockcult.dm +++ b/code/modules/antagonists/clockcult/clockcult.dm @@ -6,6 +6,7 @@ job_rank = ROLE_SERVANT_OF_RATVAR antag_moodlet = /datum/mood_event/cult skill_modifiers = list(/datum/skill_modifier/job/level/wiring, /datum/skill_modifier/job/level/dwarfy/blacksmithing) + ui_name = "AntagInfoClockwork" var/datum/action/innate/hierophant/hierophant_network = new threat = 3 var/datum/team/clockcult/clock_team @@ -14,6 +15,12 @@ var/ignore_eligibility_check = FALSE var/ignore_holy_water = FALSE +/datum/antagonist/clockcult/ui_data(mob/user) + . = ..() + if(!.) + return + .["HONOR_RATVAR"] = GLOB.ratvar_awakens + /datum/antagonist/clockcult/silent name = "Silent Clock Cultist" silent = TRUE @@ -22,6 +29,8 @@ /datum/antagonist/clockcult/neutered name = "Neutered Clock Cultist" neutered = TRUE + soft_antag = TRUE + ui_name = null // no. /datum/antagonist/clockcult/neutered/traitor name = "Traitor Clock Cultist" @@ -57,14 +66,6 @@ if(. && !ignore_eligibility_check) . = is_eligible_servant(new_owner.current) -/datum/antagonist/clockcult/greet() - if(!owner.current || silent) - return - owner.current.visible_message("[owner.current]'s eyes glow a blazing yellow!", null, null, 7, owner.current) //don't show the owner this message - to_chat(owner.current, "Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork \ - Justiciar above all else. Perform his every whim without hesitation.") - owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/clockcultalr.ogg', 70, FALSE, pressure_affected = FALSE) - /datum/antagonist/clockcult/on_gain() var/mob/living/current = owner.current SSticker.mode.servants_of_ratvar += owner @@ -240,3 +241,18 @@ parts += printplayerlist(members - eminence) return "
    [parts.Join("
    ")]
    " + +//I have no idea where to put this so I'm leaving it here. Loads reebe. Only one reebe can exist, so it's checked via a global var. +/proc/load_reebe() + if(GLOB.reebe_loaded) + return TRUE + var/list/errorList = list() + var/list/reebes = SSmapping.LoadGroup(errorList, "Reebe", "map_files/generic", "City_of_Cogs.dmm", default_traits = ZTRAITS_REEBE, silent = TRUE) + if(errorList.len) // reebe failed to load + message_admins("Reebe failed to load!") + log_game("Reebe failed to load!") + return FALSE + for(var/datum/parsed_map/PM in reebes) + PM.initTemplateBounds() + GLOB.reebe_loaded = TRUE + return TRUE diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm index 9bd1030685..0efde2d3db 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -387,8 +387,7 @@ log_combat(user, M, "used a cult spell on", source.name, "") M.set_last_attacker(user) -/obj/item/melee/blood_magic/afterattack(atom/target, mob/living/carbon/user, proximity) - . = ..() +/obj/item/melee/blood_magic/proc/post_cast(atom/target, mob/living/carbon/user, proximity) if(invocation) user.whisper(invocation, language = /datum/language/common) if(health_cost) @@ -467,6 +466,7 @@ to_chat(user, "In an brilliant flash of red, [L] [is_servant_of_ratvar(L) ? "writhes in pain!" : "falls to the ground!"]") uses-- ..() + post_cast(target, user, proximity) //Teleportation /obj/item/melee/blood_magic/teleport @@ -480,40 +480,45 @@ to_chat(user, "You can only teleport adjacent cultists with this spell!") return if(iscultist(user)) - var/list/potential_runes = list() - var/list/teleportnames = list() - for(var/R in GLOB.teleport_runes) - var/obj/effect/rune/teleport/T = R - potential_runes[avoid_assoc_duplicate_keys(T.listkey, teleportnames)] = T - - if(!potential_runes.len) - to_chat(user, "There are no valid runes to teleport to!") - log_game("Teleport talisman failed - no other teleport runes") - return - - var/turf/T = get_turf(src) - if(is_away_level(T.z)) - to_chat(user, "You are not in the right dimension!") - log_game("Teleport spell failed - user in away mission") - return - - var/input_rune_key = input(user, "Choose a rune to teleport to.", "Rune to Teleport to") as null|anything in potential_runes //we know what key they picked - var/obj/effect/rune/teleport/actual_selected_rune = potential_runes[input_rune_key] //what rune does that key correspond to? - if(QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated() || !actual_selected_rune || !proximity) - return - var/turf/dest = get_turf(actual_selected_rune) - if(is_blocked_turf(dest, TRUE)) - to_chat(user, "The target rune is blocked. Attempting to teleport to it would be massively unwise.") - return - uses-- - var/turf/origin = get_turf(user) - var/mob/living/L = target - if(do_teleport(L, dest, channel = TELEPORT_CHANNEL_CULT)) - origin.visible_message("Dust flows from [user]'s hand, and [user.p_they()] disappear[user.p_s()] with a sharp crack!", \ - "You speak the words of the talisman and find yourself somewhere else!", "You hear a sharp crack.") - dest.visible_message("There is a boom of outrushing air as something appears above the rune!", null, "You hear a boom.") + try_teleport(target, user, proximity) ..() +/obj/item/melee/blood_magic/teleport/proc/try_teleport(atom/target, mob/living/carbon/user, proximity) + set waitfor = FALSE + var/list/potential_runes = list() + var/list/teleportnames = list() + for(var/R in GLOB.teleport_runes) + var/obj/effect/rune/teleport/T = R + potential_runes[avoid_assoc_duplicate_keys(T.listkey, teleportnames)] = T + + if(!potential_runes.len) + to_chat(user, "There are no valid runes to teleport to!") + log_game("Teleport talisman failed - no other teleport runes") + return + + var/turf/T = get_turf(src) + if(is_away_level(T.z)) + to_chat(user, "You are not in the right dimension!") + log_game("Teleport spell failed - user in away mission") + return + + var/input_rune_key = input(user, "Choose a rune to teleport to.", "Rune to Teleport to") as null|anything in potential_runes //we know what key they picked + var/obj/effect/rune/teleport/actual_selected_rune = potential_runes[input_rune_key] //what rune does that key correspond to? + if(QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated() || !actual_selected_rune || !proximity) + return + var/turf/dest = get_turf(actual_selected_rune) + if(is_blocked_turf(dest, TRUE)) + to_chat(user, "The target rune is blocked. Attempting to teleport to it would be massively unwise.") + return + uses-- + var/turf/origin = get_turf(user) + var/mob/living/L = target + if(do_teleport(L, dest, channel = TELEPORT_CHANNEL_CULT)) + origin.visible_message("Dust flows from [user]'s hand, and [user.p_they()] disappear[user.p_s()] with a sharp crack!", \ + "You speak the words of the talisman and find yourself somewhere else!", "You hear a sharp crack.") + dest.visible_message("There is a boom of outrushing air as something appears above the rune!", null, "You hear a boom.") + post_cast(target, user, proximity) + //Shackles /obj/item/melee/blood_magic/shackles name = "Binding Aura" @@ -530,6 +535,7 @@ user.visible_message("This victim doesn't have enough arms to complete the restraint!") return ..() + post_cast(target, user, proximity) /obj/item/melee/blood_magic/shackles/proc/CuffAttack(mob/living/carbon/C, mob/living/user) if(!C.handcuffed) @@ -583,6 +589,7 @@ to_chat(user, "A dark cloud emanates from your hand and swirls around the metal, twisting it into a construct shell!") new /obj/structure/constructshell(T) SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + post_cast(target, proximity_flag, user) else to_chat(user, "You need 50 metal to produce a construct shell!") else if(istype(target, /obj/item/stack/sheet/plasteel)) @@ -593,56 +600,73 @@ new /obj/item/stack/sheet/runed_metal(T,quantity) to_chat(user, "A dark cloud emanates from you hand and swirls around the plasteel, transforming it into runed metal!") SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + post_cast(target, user, proximity_flag) if(istype(target, /obj/item/clothing/suit/hooded/wintercoat) && target.type != /obj/item/clothing/suit/hooded/wintercoat/narsie) - if (do_after(user,30,target=target)) - new /obj/item/clothing/suit/hooded/wintercoat/narsie(T) - qdel(target) - to_chat(user, "A dark cloud emanates from you hand and swirls around [target], transforming it into a narsian winter coat!") - SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + convert_coat(target, user, proximity_flag, T) else if(istype(target,/mob/living/silicon/robot)) - var/mob/living/silicon/robot/candidate = target - if(!iscultist(user, TRUE)) - to_chat(user, "You are not strongly connected enough to Nar'sie to use make constructs...") - else if(candidate.mmi) - user.visible_message("A dark cloud emanates from [user]'s hand and swirls around [candidate]!") - playsound(T, 'sound/machines/airlock_alien_prying.ogg', 80, 1) - var/prev_color = candidate.color - candidate.color = "black" - if(do_after(user, 90, target = candidate)) - candidate.emp_act(80) - var/construct_class = alert(user, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer") - user.visible_message("The dark cloud receedes from what was formerly [candidate], revealing a\n [construct_class]!") - switch(construct_class) - if("Juggernaut") - makeNewConstruct(/mob/living/simple_animal/hostile/construct/armored, candidate, user, 0, T) - if("Wraith") - makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith, candidate, user, 0, T) - if("Artificer") - makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder, candidate, user, 0, T) - SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) - uses-- - candidate.mmi = null - qdel(candidate) - else - candidate.color = prev_color - else - uses-- - to_chat(user, "A dark cloud emanates from you hand and swirls around [candidate] - twisting it into a construct shell!") - new /obj/structure/constructshell(T) - SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + convert_borg(target, user, proximity_flag, T) else if(istype(target,/obj/machinery/door/airlock)) - playsound(T, 'sound/machines/airlockforced.ogg', 50, 1) - do_sparks(5, TRUE, target) - if(do_after(user, 50, target = user)) - target.narsie_act() - uses-- - user.visible_message("Black ribbons suddenly emanate from [user]'s hand and cling to the airlock - twisting and corrupting it!") - SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + convert_door(target, user, proximity_flag, T) else to_chat(user, "The spell will not work on [target]!") return ..() +/obj/item/melee/blood_magic/construction/proc/convert_coat(atom/target, mob/user, proximity_flag, turf/T) + set waitfor = FALSE + if(do_after(user,30,target=target)) + new /obj/item/clothing/suit/hooded/wintercoat/narsie(T) + qdel(target) + to_chat(user, "A dark cloud emanates from you hand and swirls around [target], transforming it into a narsian winter coat!") + SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + post_cast(target, user, proximity_flag) + +/obj/item/melee/blood_magic/construction/proc/convert_door(atom/target, mob/user, proximity_flag, turf/T) + set waitfor = FALSE + playsound(T, 'sound/machines/airlockforced.ogg', 50, 1) + do_sparks(5, TRUE, target) + if(do_after(user, 50, target = user)) + target.narsie_act() + uses-- + user.visible_message("Black ribbons suddenly emanate from [user]'s hand and cling to the airlock - twisting and corrupting it!") + SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + post_cast(target, user, proximity_flag) + +/obj/item/melee/blood_magic/construction/proc/convert_borg(atom/target, mob/user, proximity_flag, turf/T) + set waitfor = FALSE + var/mob/living/silicon/robot/candidate = target + if(!iscultist(user, TRUE)) + to_chat(user, "You are not strongly connected enough to Nar'sie to use make constructs...") + return + else if(candidate.mmi) + user.visible_message("A dark cloud emanates from [user]'s hand and swirls around [candidate]!") + playsound(T, 'sound/machines/airlock_alien_prying.ogg', 80, 1) + var/prev_color = candidate.color + candidate.color = "black" + if(do_after(user, 90, target = candidate)) + candidate.emp_act(80) + var/construct_class = alert(user, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer") + user.visible_message("The dark cloud receedes from what was formerly [candidate], revealing a\n [construct_class]!") + switch(construct_class) + if("Juggernaut") + makeNewConstruct(/mob/living/simple_animal/hostile/construct/armored, candidate, user, 0, T) + if("Wraith") + makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith, candidate, user, 0, T) + if("Artificer") + makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder, candidate, user, 0, T) + SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + uses-- + candidate.mmi = null + qdel(candidate) + else + candidate.color = prev_color + else + uses-- + to_chat(user, "A dark cloud emanates from you hand and swirls around [candidate] - twisting it into a construct shell!") + new /obj/structure/constructshell(T) + SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) + post_cast(target, user, proximity_flag) + //Armor: Gives the target a basic cultist combat loadout /obj/item/melee/blood_magic/armor name = "Bladed Aura" @@ -654,17 +678,18 @@ uses-- var/mob/living/carbon/C = target C.visible_message("Otherworldly armor suddenly appears on [C]!") - C.equip_to_slot_or_del(new /obj/item/clothing/under/color/black,SLOT_W_UNIFORM) - C.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(user), SLOT_HEAD) - C.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(user), SLOT_WEAR_SUIT) - C.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult/alt(user), SLOT_SHOES) - C.equip_to_slot_or_del(new /obj/item/storage/backpack/cultpack(user), SLOT_BACK) - C.equip_to_slot_or_del(new /obj/item/clothing/gloves/fingerless/pugilist/hungryghost(user), SLOT_GLOVES) + C.equip_to_slot_or_del(new /obj/item/clothing/under/color/black,ITEM_SLOT_ICLOTHING) + C.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(user), ITEM_SLOT_HEAD) + C.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(user), ITEM_SLOT_OCLOTHING) + C.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult/alt(user), ITEM_SLOT_FEET) + C.equip_to_slot_or_del(new /obj/item/storage/backpack/cultpack(user), ITEM_SLOT_BACK) + C.equip_to_slot_or_del(new /obj/item/clothing/gloves/fingerless/pugilist/hungryghost(user), ITEM_SLOT_GLOVES) if(C == user) qdel(src) //Clears the hands C.put_in_hands(new /obj/item/melee/cultblade(user)) C.put_in_hands(new /obj/item/restraints/legcuffs/bola/cult(user)) ..() + post_cast(target, user, proximity) /obj/item/melee/blood_magic/manipulator name = "Ritual Aura" @@ -693,7 +718,9 @@ H.adjust_integration_blood(uses * 2) to_chat(user,"You use the last of your blood rites to restore what blood you could!") uses = 0 - return ..() + ..() + post_cast(target, user, proximity) + return else H.blood_volume = (BLOOD_VOLUME_SAFE*H.blood_ratio) uses -= round(restore_blood/2) @@ -758,6 +785,7 @@ if(istype(target, /obj/effect/decal/cleanable/blood)) blood_draw(target, user) ..() + post_cast() /obj/item/melee/blood_magic/manipulator/proc/blood_draw(atom/target, mob/living/carbon/human/user) var/temp = 0 diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm index a18523069e..2850cb85cc 100644 --- a/code/modules/antagonists/cult/cult.dm +++ b/code/modules/antagonists/cult/cult.dm @@ -49,7 +49,10 @@ cult_team = new_team /datum/antagonist/cult/proc/add_objectives() - objectives |= cult_team?.objectives +//ambition start + if(cult_team) + objectives |= cult_team.objectives +//ambition end /datum/antagonist/cult/Destroy() QDEL_NULL(communion) @@ -95,9 +98,9 @@ /datum/antagonist/cult/proc/cult_give_item(obj/item/item_path, mob/living/carbon/human/mob) var/list/slots = list( - "backpack" = SLOT_IN_BACKPACK, - "left pocket" = SLOT_L_STORE, - "right pocket" = SLOT_R_STORE + "backpack" = ITEM_SLOT_BACKPACK, + "left pocket" = ITEM_SLOT_LPOCKET, + "right pocket" = ITEM_SLOT_RPOCKET ) var/T = new item_path(mob) diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index 35151953a0..a522285210 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -39,7 +39,7 @@ armour_penetration = 35 actions_types = list(/datum/action/item_action/cult_dagger) -/obj/item/melee/cultblade/dagger/Initialize() +/obj/item/melee/cultblade/dagger/Initialize(mapload) . = ..() var/image/I = image(icon = 'icons/effects/blood.dmi' , icon_state = null, loc = src) I.override = TRUE @@ -62,7 +62,7 @@ hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "rended") -/obj/item/melee/cultblade/Initialize() +/obj/item/melee/cultblade/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 40, 100) AddElement(/datum/element/sword_point) @@ -87,7 +87,7 @@ item_flags = NEEDS_PERMIT | DROPDEL flags_1 = NONE -/obj/item/melee/cultblade/ghost/Initialize() +/obj/item/melee/cultblade/ghost/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) @@ -131,7 +131,7 @@ var/spin_cooldown = 250 var/dash_toggled = TRUE -/obj/item/cult_bastard/Initialize() +/obj/item/cult_bastard/Initialize(mapload) . = ..() set_light(4) jaunt = new(src) @@ -297,7 +297,7 @@ desc = "A torn, dust-caked hood. Strange letters line the inside." flags_inv = HIDEFACE|HIDEHAIR|HIDEEARS flags_cover = HEADCOVERSEYES - armor = list("melee" = 40, "bullet" = 30, "laser" = 40,"energy" = 20, "bomb" = 65, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10) + armor = list(MELEE = 40, BULLET = 30, LASER = 40,ENERGY = 20, BOMB = 65, BIO = 10, RAD = 0, FIRE = 10, ACID = 10) cold_protection = HEAD min_cold_protection_temperature = HELMET_MIN_TEMP_PROTECT heat_protection = HEAD @@ -310,7 +310,7 @@ item_state = "cultrobes" body_parts_covered = CHEST|GROIN|LEGS|ARMS allowed = list(/obj/item/tome, /obj/item/melee/cultblade) - armor = list("melee" = 40, "bullet" = 30, "laser" = 40,"energy" = 20, "bomb" = 65, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10) + armor = list(MELEE = 40, BULLET = 30, LASER = 40,ENERGY = 20, BOMB = 65, BIO = 10, RAD = 0, FIRE = 10, ACID = 10) flags_inv = HIDEJUMPSUIT cold_protection = CHEST|GROIN|LEGS|ARMS min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT @@ -326,7 +326,7 @@ /obj/item/clothing/head/culthood/alt/ghost item_flags = DROPDEL -/obj/item/clothing/head/culthood/alt/ghost/Initialize() +/obj/item/clothing/head/culthood/alt/ghost/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) @@ -340,7 +340,7 @@ /obj/item/clothing/suit/cultrobes/alt/ghost item_flags = DROPDEL -/obj/item/clothing/suit/cultrobes/alt/ghost/Initialize() +/obj/item/clothing/suit/cultrobes/alt/ghost/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) @@ -350,7 +350,7 @@ item_state = "magus" desc = "A helm worn by the followers of Nar'Sie." flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDEEARS|HIDEEYES|HIDESNOUT - armor = list("melee" = 30, "bullet" = 30, "laser" = 30,"energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 10, "acid" = 10) + armor = list(MELEE = 30, BULLET = 30, LASER = 30,ENERGY = 20, BOMB = 0, BIO = 0, RAD = 0, FIRE = 10, ACID = 10) flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH mutantrace_variation = STYLE_MUZZLE @@ -361,7 +361,7 @@ item_state = "magusred" body_parts_covered = CHEST|GROIN|LEGS|ARMS allowed = list(/obj/item/tome, /obj/item/melee/cultblade) - armor = list("melee" = 50, "bullet" = 30, "laser" = 50,"energy" = 20, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10) + armor = list(MELEE = 50, BULLET = 30, LASER = 50,ENERGY = 20, BOMB = 25, BIO = 10, RAD = 0, FIRE = 10, ACID = 10) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT /obj/item/clothing/head/helmet/space/hardsuit/cult @@ -369,7 +369,7 @@ desc = "A heavily-armored helmet worn by warriors of the Nar'Sien cult. It can withstand hard vacuum." icon_state = "cult_helmet" item_state = "cult_helmet" - armor = list("melee" = 60, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 40, "acid" = 75) + armor = list(MELEE = 60, BULLET = 50, LASER = 30,ENERGY = 15, BOMB = 30, BIO = 30, RAD = 30, FIRE = 40, ACID = 75) brightness_on = 0 actions_types = list() @@ -385,7 +385,7 @@ desc = "A heavily-armored exosuit worn by warriors of the Nar'Sien cult. It can withstand hard vacuum." w_class = WEIGHT_CLASS_BULKY allowed = list(/obj/item/tome, /obj/item/melee/cultblade, /obj/item/tank/internals/) - armor = list("melee" = 70, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 40, "acid" = 75) + armor = list(MELEE = 70, BULLET = 50, LASER = 30,ENERGY = 15, BOMB = 30, BIO = 30, RAD = 30, FIRE = 40, ACID = 75) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/cult /obj/item/clothing/suit/space/hardsuit/cult/ComponentInitialize() @@ -413,7 +413,7 @@ icon_state = "cult_armor" item_state = "cult_armor" w_class = WEIGHT_CLASS_BULKY - armor = list("melee" = 50, "bullet" = 40, "laser" = 50,"energy" = 30, "bomb" = 50, "bio" = 30, "rad" = 30, "fire" = 50, "acid" = 60) + armor = list(MELEE = 50, BULLET = 40, LASER = 50,ENERGY = 30, BOMB = 50, BIO = 30, RAD = 30, FIRE = 50, ACID = 60) body_parts_covered = CHEST|GROIN|LEGS|ARMS allowed = list(/obj/item/tome, /obj/item/melee/cultblade) var/current_charges = 3 @@ -423,7 +423,7 @@ name = "empowered cultist armor" desc = "Empowered garb which creates a powerful shield around the user." icon_state = "cult_hoodalt" - armor = list("melee" = 50, "bullet" = 40, "laser" = 50,"energy" = 30, "bomb" = 50, "bio" = 30, "rad" = 30, "fire" = 50, "acid" = 50) + armor = list(MELEE = 50, BULLET = 40, LASER = 50,ENERGY = 30, BOMB = 50, BIO = 30, RAD = 30, FIRE = 50, ACID = 50) body_parts_covered = HEAD flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS @@ -473,7 +473,7 @@ flags_inv = HIDEJUMPSUIT allowed = list(/obj/item/tome, /obj/item/melee/cultblade) body_parts_covered = CHEST|GROIN|LEGS|ARMS - armor = list("melee" = -50, "bullet" = -50, "laser" = -50,"energy" = -50, "bomb" = -50, "bio" = -50, "rad" = -50, "fire" = 0, "acid" = 0) + armor = list(MELEE = -50, BULLET = -50, LASER = -50,ENERGY = -50, BOMB = -50, BIO = -50, RAD = -50, FIRE = 0, ACID = 0) slowdown = -1 hoodtype = /obj/item/clothing/head/hooded/berserkerhood @@ -483,7 +483,7 @@ icon_state = "culthood" body_parts_covered = HEAD flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS - armor = list("melee" = -50, "bullet" = -50, "laser" = -50, "energy" = -50, "bomb" = -50, "bio" = -50, "rad" = -50, "fire" = 0, "acid" = 0) + armor = list(MELEE = -50, BULLET = -50, LASER = -50, ENERGY = -50, BOMB = -50, BIO = -50, RAD = -50, FIRE = 0, ACID = 0) /obj/item/clothing/suit/hooded/cultrobes/berserker/equipped(mob/living/user, slot) ..() @@ -660,40 +660,42 @@ return if(istype(A, /obj/item)) - - var/list/cultists = list() - for(var/datum/mind/M in SSticker.mode.cult) - if(M.current && M.current.stat != DEAD) - cultists |= M.current - var/mob/living/cultist_to_receive = input(user, "Who do you wish to call to [src]?", "Followers of the Geometer") as null|anything in (cultists - user) - if(!Adjacent(user) || !src || QDELETED(src) || user.incapacitated()) - return - if(!cultist_to_receive) - to_chat(user, "You require a destination!") - log_game("Void torch failed - no target") - return - if(cultist_to_receive.stat == DEAD) - to_chat(user, "[cultist_to_receive] has died!") - log_game("Void torch failed - target died") - return - if(!iscultist(cultist_to_receive)) - to_chat(user, "[cultist_to_receive] is not a follower of the Geometer!") - log_game("Void torch failed - target was deconverted") - return - if(A in user.GetAllContents()) - to_chat(user, "[A] must be on a surface in order to teleport it!") - return - to_chat(user, "You ignite [A] with \the [src], turning it to ash, but through the torch's flames you see that [A] has reached [cultist_to_receive]!") - cultist_to_receive.put_in_hands(A) - charges-- - to_chat(user, "\The [src] now has [charges] charge\s.") - if(charges == 0) - qdel(src) + transmit_item(A, user, proximity) else ..() to_chat(user, "\The [src] can only transport items!") +/obj/item/flashlight/flare/culttorch/proc/transmit_item(atom/movable/A, mob/user, proximity) + set waitfor = FALSE + var/list/cultists = list() + for(var/datum/mind/M in SSticker.mode.cult) + if(M.current && M.current.stat != DEAD) + cultists |= M.current + var/mob/living/cultist_to_receive = input(user, "Who do you wish to call to [src]?", "Followers of the Geometer") as null|anything in (cultists - user) + if(!Adjacent(user) || !src || QDELETED(src) || user.incapacitated()) + return + if(!cultist_to_receive) + to_chat(user, "You require a destination!") + log_game("Void torch failed - no target") + return + if(cultist_to_receive.stat == DEAD) + to_chat(user, "[cultist_to_receive] has died!") + log_game("Void torch failed - target died") + return + if(!iscultist(cultist_to_receive)) + to_chat(user, "[cultist_to_receive] is not a follower of the Geometer!") + log_game("Void torch failed - target was deconverted") + return + if(A in user.GetAllContents()) + to_chat(user, "[A] must be on a surface in order to teleport it!") + return + to_chat(user, "You ignite [A] with \the [src], turning it to ash, but through the torch's flames you see that [A] has reached [cultist_to_receive]!") + cultist_to_receive.put_in_hands(A) + charges-- + to_chat(user, "\The [src] now has [charges] charge\s.") + if(charges == 0) + qdel(src) /obj/item/cult_spear name = "blood halberd" @@ -714,7 +716,7 @@ var/wielded = FALSE // track wielded status on item -/obj/item/cult_spear/Initialize() +/obj/item/cult_spear/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield) RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield) @@ -872,7 +874,7 @@ var/firing = FALSE var/angle -/obj/item/blood_beam/Initialize() +/obj/item/blood_beam/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) diff --git a/code/modules/antagonists/cult/cult_structures.dm b/code/modules/antagonists/cult/cult_structures.dm index a2f283ec67..3a4079d67f 100644 --- a/code/modules/antagonists/cult/cult_structures.dm +++ b/code/modules/antagonists/cult/cult_structures.dm @@ -89,7 +89,7 @@ var/static/image/radial_shell = image(icon = 'icons/obj/wizard.dmi', icon_state = "construct-cult") var/static/image/radial_unholy_water = image(icon = 'icons/obj/drinks.dmi', icon_state = "holyflask") -/obj/structure/destructible/cult/talisman/Initialize() +/obj/structure/destructible/cult/talisman/Initialize(mapload) . = ..() radial_unholy_water.color = "#333333" diff --git a/code/modules/antagonists/cult/ritual.dm b/code/modules/antagonists/cult/ritual.dm index 98889169c6..6caa13dcff 100644 --- a/code/modules/antagonists/cult/ritual.dm +++ b/code/modules/antagonists/cult/ritual.dm @@ -5,7 +5,7 @@ This file contains the cult dagger and rune list code */ -/obj/item/melee/cultblade/dagger/Initialize() +/obj/item/melee/cultblade/dagger/Initialize(mapload) . = ..() if(!LAZYLEN(GLOB.rune_types)) GLOB.rune_types = list() diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 7981a10701..809a69d393 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -832,7 +832,7 @@ structure_check() searches for nearby cultist structures required for the invoca var/ghost_limit = 3 var/ghosts = 0 -/obj/effect/rune/manifest/Initialize() +/obj/effect/rune/manifest/Initialize(mapload) . = ..() @@ -1090,7 +1090,7 @@ structure_check() searches for nearby cultist structures required for the invoca /proc/hudFix(mob/living/carbon/human/target) if(!target || !target.client) return - var/obj/O = target.get_item_by_slot(SLOT_GLASSES) + var/obj/O = target.get_item_by_slot(ITEM_SLOT_EYES) if(istype(O, /obj/item/clothing/glasses/hud/security)) var/datum/atom_hud/AH = GLOB.huds[DATA_HUD_SECURITY_ADVANCED] AH.add_hud_to(target) diff --git a/code/modules/antagonists/devil/devil.dm b/code/modules/antagonists/devil/devil.dm index 65ce89d33f..9f69f10887 100644 --- a/code/modules/antagonists/devil/devil.dm +++ b/code/modules/antagonists/devil/devil.dm @@ -460,10 +460,10 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", return -1 currentMob.change_mob_type( /mob/living/carbon/human, targetturf, null, 1) var/mob/living/carbon/human/H = owner.current - H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/civilian/lawyer/black(H), SLOT_W_UNIFORM) - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(H), SLOT_SHOES) - H.equip_to_slot_or_del(new /obj/item/storage/briefcase(H), SLOT_HANDS) - H.equip_to_slot_or_del(new /obj/item/pen(H), SLOT_L_STORE) + H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/civilian/lawyer/black(H), ITEM_SLOT_ICLOTHING) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(H), ITEM_SLOT_FEET) + H.equip_to_slot_or_del(new /obj/item/storage/briefcase(H), ITEM_SLOT_HANDS) + H.equip_to_slot_or_del(new /obj/item/pen(H), ITEM_SLOT_LPOCKET) if(SOULVALUE >= BLOOD_THRESHOLD) H.set_species(/datum/species/lizard, 1) H.underwear = "Nude" diff --git a/code/modules/antagonists/devil/imp/imp.dm b/code/modules/antagonists/devil/imp/imp.dm index f7f55456f7..4b2a41db71 100644 --- a/code/modules/antagonists/devil/imp/imp.dm +++ b/code/modules/antagonists/devil/imp/imp.dm @@ -44,11 +44,11 @@ Though you are not obligated to help, perhaps by aiding a higher ranking devil, you might just get a promotion. However, you are incapable \ of intentionally harming a fellow devil." -/mob/living/simple_animal/imp/Initialize() +/mob/living/simple_animal/imp/Initialize(mapload) ..() boost = world.time + 30 -/mob/living/simple_animal/imp/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/imp/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(boost*---------*\nThis is [icon2html(src, user)] [src]!") + . = list("This is [icon2html(src, user)] [src]!") //Left hand items for(var/obj/item/I in held_items) @@ -81,7 +81,7 @@ . += "You can see hellfire inside its gaping wounds." else if(health < (maxHealth/2)) . += "You can see hellfire inside its wounds." - . += "*---------*" + . += "" /mob/living/carbon/true_devil/IsAdvancedToolUser() return 1 @@ -104,7 +104,7 @@ /mob/living/carbon/true_devil/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) return 666 -/mob/living/carbon/true_devil/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/flash, override_protection = 0) +/mob/living/carbon/true_devil/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/tiled/flash, override_protection = 0) if(mind && has_bane(BANE_LIGHT)) mind.disrupt_spells(-500) return ..() //flashes don't stop devils UNLESS it's their bane. @@ -179,7 +179,7 @@ /mob/living/carbon/true_devil/is_literate() return 1 -/mob/living/carbon/true_devil/ex_act(severity, ex_target) +/mob/living/carbon/true_devil/ex_act(severity, target, origin) if(!ascended) var/b_loss switch (severity) diff --git a/code/modules/antagonists/disease/disease_event.dm b/code/modules/antagonists/disease/disease_event.dm index 385cee998b..f80af46eac 100644 --- a/code/modules/antagonists/disease/disease_event.dm +++ b/code/modules/antagonists/disease/disease_event.dm @@ -5,7 +5,8 @@ weight = 7 max_occurrences = 1 min_players = 5 - + category = EVENT_CATEGORY_HEALTH + description = "Spawns a sentient disease, who wants to infect as many people as possible." /datum/round_event/ghost_role/sentient_disease role_name = "sentient disease" diff --git a/code/modules/antagonists/eldritch_cult/eldritch_antag.dm b/code/modules/antagonists/eldritch_cult/eldritch_antag.dm index fc0a5cdc6a..d7334d6c9c 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_antag.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_antag.dm @@ -72,9 +72,9 @@ /datum/antagonist/heretic/proc/ecult_give_item(obj/item/item_path, mob/living/carbon/human/H) var/list/slots = list( - "backpack" = SLOT_IN_BACKPACK, - "left pocket" = SLOT_L_STORE, - "right pocket" = SLOT_R_STORE + "backpack" = ITEM_SLOT_BACKPACK, + "left pocket" = ITEM_SLOT_LPOCKET, + "right pocket" = ITEM_SLOT_RPOCKET ) var/T = new item_path(H) diff --git a/code/modules/antagonists/eldritch_cult/eldritch_book.dm b/code/modules/antagonists/eldritch_cult/eldritch_book.dm index 808932443f..ba7fcb0be1 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_book.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_book.dm @@ -43,7 +43,7 @@ /obj/item/forbidden_book/proc/get_power_from_influence(atom/target, mob/user) var/obj/effect/reality_smash/RS = target to_chat(user, "You start drawing power from influence...") - if(do_after(user,10 SECONDS,TRUE,RS)) + if(do_after(user, 10 SECONDS, RS)) qdel(RS) charge += 1 @@ -57,7 +57,7 @@ var/A = get_turf(target) to_chat(user, "You start drawing a rune...") - if(do_after(user,30 SECONDS,FALSE, user)) + if(do_after(user, 30 SECONDS, user)) new /obj/effect/eldritch/big(A) @@ -65,7 +65,7 @@ /obj/item/forbidden_book/proc/remove_rune(atom/target,mob/user) to_chat(user, "You start removing a rune...") - if(do_after(user,2 SECONDS,FALSE, user)) + if(do_after(user, 2 SECONDS, user)) qdel(target) /obj/item/forbidden_book/ui_interact(mob/user, datum/tgui/ui = null) diff --git a/code/modules/antagonists/eldritch_cult/eldritch_effects.dm b/code/modules/antagonists/eldritch_cult/eldritch_effects.dm index 3d6059dfe3..6640135f37 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_effects.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_effects.dm @@ -8,7 +8,7 @@ ///Used mainly for summoning ritual to prevent spamming the rune to create millions of monsters. var/is_in_use = FALSE -/obj/effect/eldritch/Initialize() +/obj/effect/eldritch/Initialize(mapload) . = ..() var/image/I = image(icon = 'icons/effects/eldritch.dmi', icon_state = null, loc = src) I.override = TRUE @@ -216,7 +216,7 @@ resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF alpha = 0 -/obj/effect/broken_illusion/Initialize() +/obj/effect/broken_illusion/Initialize(mapload) . = ..() addtimer(CALLBACK(src,.proc/show_presence),15 SECONDS) addtimer(CALLBACK(src,.proc/remove_presence),195 SECONDS) @@ -295,7 +295,7 @@ ///Tracked image var/image/img -/obj/effect/reality_smash/Initialize() +/obj/effect/reality_smash/Initialize(mapload) . = ..() GLOB.reality_smash_track.smashes += src img = image(icon, src, image_state, OBJ_LAYER) diff --git a/code/modules/antagonists/eldritch_cult/eldritch_items.dm b/code/modules/antagonists/eldritch_cult/eldritch_items.dm index 87a4ddf7eb..58e0193de5 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_items.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_items.dm @@ -8,7 +8,7 @@ var/mob/living/carbon/human/target var/datum/antagonist/heretic/sac_targetter //The heretic who used this to acquire the current target - gets cleared when target gets sacrificed. -/obj/item/living_heart/Initialize() +/obj/item/living_heart/Initialize(mapload) . = ..() GLOB.living_heart_cache.Add(src) //Add is better than +=. @@ -145,7 +145,7 @@ /obj/item/clothing/neck/eldritch_amulet/equipped(mob/user, slot) . = ..() - if(ishuman(user) && user.mind && slot == SLOT_NECK && (IS_HERETIC(user) || IS_HERETIC_MONSTER(user))) + if(ishuman(user) && user.mind && slot == ITEM_SLOT_NECK && (IS_HERETIC(user) || IS_HERETIC_MONSTER(user))) ADD_TRAIT(user, trait, CLOTHING_TRAIT) user.update_sight() @@ -177,7 +177,7 @@ allowed = list(/obj/item/melee/sickly_blade, /obj/item/forbidden_book, /obj/item/living_heart) hoodtype = /obj/item/clothing/head/hooded/cult_hoodie/eldritch // slightly better than normal cult robes - armor = list("melee" = 50, "bullet" = 50, "laser" = 50,"energy" = 50, "bomb" = 35, "bio" = 20, "rad" = 0, "fire" = 20, "acid" = 20) + armor = list(MELEE = 50, BULLET = 50, LASER = 50,ENERGY = 50, BOMB = 35, BIO = 20, RAD = 0, FIRE = 20, ACID = 20) mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON /obj/item/reagent_containers/glass/beaker/eldritch @@ -193,7 +193,7 @@ flags_inv = NONE flags_cover = NONE desc = "Black like tar, doesn't reflect any light. Runic symbols line the outside, with each flash you lose comprehension of what you are seeing." - armor = list("melee" = 30, "bullet" = 30, "laser" = 30,"energy" = 30, "bomb" = 15, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 30, BULLET = 30, LASER = 30,ENERGY = 30, BOMB = 15, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) obj_flags = NONE | EXAMINE_SKIP /obj/item/clothing/suit/hooded/cultrobes/void @@ -205,7 +205,7 @@ hoodtype = /obj/item/clothing/head/hooded/cult_hoodie/void flags_inv = NONE // slightly worse than normal cult robes - armor = list("melee" = 30, "bullet" = 30, "laser" = 30,"energy" = 30, "bomb" = 15, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 30, BULLET = 30, LASER = 30,ENERGY = 30, BOMB = 15, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) pocket_storage_component_path = /datum/component/storage/concrete/pockets/void_cloak mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON @@ -239,7 +239,7 @@ /obj/item/clothing/mask/void_mask/equipped(mob/user, slot) . = ..() - if(ishuman(user) && user.mind && slot == SLOT_WEAR_MASK) + if(ishuman(user) && user.mind && slot == ITEM_SLOT_MASK) local_user = user START_PROCESSING(SSobj, src) @@ -260,7 +260,7 @@ if((IS_HERETIC(local_user) || IS_HERETIC_MONSTER(local_user)) && HAS_TRAIT(src,TRAIT_NODROP)) REMOVE_TRAIT(src, TRAIT_NODROP, CLOTHING_TRAIT) - for(var/mob/living/carbon/human/human_in_range in spiral_range(9,local_user)) + for(var/mob/living/carbon/human/human_in_range in viewers(9,local_user)) if(IS_HERETIC(human_in_range) || IS_HERETIC_MONSTER(human_in_range)) continue @@ -310,7 +310,7 @@ . += "This item can carve 'Grasping carving' - when stepped on it causes heavy damage to the legs and stuns for 5 seconds." . += "This item can carve 'Mad carving' - when stepped on it causes dizzyness, jiterryness, temporary blindness, confusion , stuttering and slurring." -/obj/item/melee/rune_knife/Initialize() +/obj/item/melee/rune_knife/Initialize(mapload) . = ..() linked_action = new(src) diff --git a/code/modules/antagonists/eldritch_cult/eldritch_magic.dm b/code/modules/antagonists/eldritch_cult/eldritch_magic.dm index 158acc0071..97b76090a7 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_magic.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_magic.dm @@ -402,11 +402,11 @@ new /obj/effect/hotspot(T) T.hotspot_expose(700,50,1) // deals damage to mechs - for(var/obj/mecha/M in T.contents) + for(var/obj/vehicle/sealed/mecha/M in T.contents) if(M in hit_list) continue hit_list += M - M.take_damage(45, BURN, "melee", 1) + M.take_damage(45, BURN, MELEE, 1) sleep(1.5) /obj/effect/proc_holder/spell/targeted/shapeshift/eldritch @@ -702,7 +702,7 @@ duration = 1 MINUTES layer = LOW_SIGIL_LAYER -/obj/effect/temp_visual/glowing_rune/Initialize() +/obj/effect/temp_visual/glowing_rune/Initialize(mapload) . = ..() pixel_y = rand(-6,6) pixel_x = rand(-6,6) @@ -958,7 +958,7 @@ halo = halo || mutable_appearance('icons/effects/effects.dmi', "at_shield2", EFFECTS_LAYER) user.add_overlay(halo) playsound(get_turf(user), Snd, 50, 0) - if(do_mob(user,user,50,1)) + if(do_mob(user, user, 5 SECONDS)) user.cut_overlay(halo) user.emote("clap1") user.say("DOM'ENO ISPLETIMAS") diff --git a/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm index 023be4b3e7..15ac8a6cb6 100644 --- a/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm +++ b/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm @@ -226,16 +226,16 @@ user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shed_human_form) if(!ishuman(user)) return - var/mob/living/carbon/human/H = user - H.physiology.brute_mod *= 0.5 - H.physiology.burn_mod *= 0.5 - var/datum/antagonist/heretic/heretic = user.mind.has_antag_datum(/datum/antagonist/heretic) - var/datum/eldritch_knowledge/flesh_grasp/ghoul1 = heretic.get_knowledge(/datum/eldritch_knowledge/flesh_grasp) - ghoul1.ghoul_amt *= 3 - var/datum/eldritch_knowledge/flesh_ghoul/ghoul2 = heretic.get_knowledge(/datum/eldritch_knowledge/flesh_ghoul) - ghoul2.max_amt *= 3 + var/mob/living/carbon/human/lord_of_arms = user + lord_of_arms.physiology.brute_mod *= 0.5 + lord_of_arms.physiology.burn_mod *= 0.5 + lord_of_arms.client?.give_award(/datum/award/achievement/misc/flesh_ascension, lord_of_arms) + var/datum/antagonist/heretic/heretic_datum = user.mind.has_antag_datum(/datum/antagonist/heretic) + var/datum/eldritch_knowledge/flesh_grasp/grasp_ghoul = heretic_datum.get_knowledge(/datum/eldritch_knowledge/flesh_grasp) + grasp_ghoul.ghoul_amt *= 3 + var/datum/eldritch_knowledge/flesh_ghoul/better_ghoul = heretic_datum.get_knowledge(/datum/eldritch_knowledge/flesh_ghoul) + better_ghoul.max_amt *= 3 - return ..() /datum/eldritch_knowledge/flesh_blade_upgrade_2 name = "Remembrance" diff --git a/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm index 509c35261e..733b2725cb 100644 --- a/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm +++ b/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm @@ -181,13 +181,13 @@ var/mob/living/carbon/human/H = user H.physiology.brute_mod *= 0.5 H.physiology.burn_mod *= 0.5 + H.client?.give_award(/datum/award/achievement/misc/rust_ascension, H) priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# Fear the decay, for the Rustbringer, [user.real_name] has ascended! None shall escape the corrosion! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", 'sound/announcer/classic/spanomalies.ogg') new /datum/rust_spread(loc) var/datum/antagonist/heretic/ascension = H.mind.has_antag_datum(/datum/antagonist/heretic) ascension.ascended = TRUE return ..() - /datum/eldritch_knowledge/final/rust_final/on_life(mob/user) . = ..() if(!finished) diff --git a/code/modules/antagonists/eldritch_cult/knowledge/void_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/void_lore.dm index 97b5af0f4d..dcbc01b046 100644 --- a/code/modules/antagonists/eldritch_cult/knowledge/void_lore.dm +++ b/code/modules/antagonists/eldritch_cult/knowledge/void_lore.dm @@ -183,14 +183,14 @@ var/datum/weather/void_storm/storm /datum/eldritch_knowledge/final/void_final/on_finished_recipe(mob/living/user, list/atoms, loc) - var/mob/living/carbon/human/H = user - user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/eldritch) - H.physiology.brute_mod *= 0.5 - H.physiology.burn_mod *= 0.5 - ADD_TRAIT(H, TRAIT_RESISTLOWPRESSURE, MAGIC_TRAIT) - priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# The nobleman of void [H.real_name] has arrived, step along the Waltz that ends worlds! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", 'sound/announcer/classic/spanomalies.ogg') - - sound_loop = new(list(user),TRUE,TRUE) + var/mob/living/carbon/human/waltzing = user + waltzing.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/eldritch) + waltzing.physiology.brute_mod *= 0.5 + waltzing.physiology.burn_mod *= 0.5 + ADD_TRAIT(waltzing, TRAIT_RESISTLOWPRESSURE, MAGIC_TRAIT) + waltzing.client?.give_award(/datum/award/achievement/misc/void_ascension, waltzing) + priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# The nobleman of void [waltzing.real_name] has arrived, step along the Waltz that ends worlds! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", 'sound/announcer/classic/spanomalies.ogg') + sound_loop = new(user, TRUE, TRUE) return ..() /datum/eldritch_knowledge/final/void_final/on_death() diff --git a/code/modules/antagonists/ert/ert.dm b/code/modules/antagonists/ert/ert.dm index 295616d052..a8e57ee08b 100644 --- a/code/modules/antagonists/ert/ert.dm +++ b/code/modules/antagonists/ert/ert.dm @@ -11,14 +11,21 @@ var/role = "Security Officer" var/list/name_source threat = -5 + var/random_names = TRUE + var/rip_and_tear = FALSE + var/equip_ert = TRUE + var/forge_objectives_for_ert = TRUE show_in_antagpanel = FALSE show_to_ghosts = TRUE antag_moodlet = /datum/mood_event/focused /datum/antagonist/ert/on_gain() - update_name() - forge_objectives() - equipERT() + if(random_names) + update_name() + if(forge_objectives_for_ert) + forge_objectives() + if(equip_ert) + equipERT() . = ..() /datum/antagonist/ert/get_team() @@ -129,6 +136,7 @@ return H.equipOutfit(outfit) + /datum/antagonist/ert/greet() if(!ert_team) return @@ -160,3 +168,139 @@ missiondesc += "
    Your Mission : [ert_team.mission.explanation_text]" to_chat(owner,missiondesc) + + +/datum/antagonist/ert/families + name = "Space Police Responder" + antag_hud_type = ANTAG_HUD_SPACECOP + antag_hud_name = "hud_spacecop" + suicide_cry = "FOR THE SPACE POLICE!!" + +/datum/antagonist/ert/families/apply_innate_effects(mob/living/mob_override) + ..() + var/mob/living/M = mob_override || owner.current + add_antag_hud(antag_hud_type, antag_hud_name, M) + if(M.hud_used) + var/datum/hud/H = M.hud_used + var/atom/movable/screen/wanted/giving_wanted_lvl = new /atom/movable/screen/wanted() + H.wanted_lvl = giving_wanted_lvl + giving_wanted_lvl.hud = H + H.infodisplay += giving_wanted_lvl + H.mymob.client.screen += giving_wanted_lvl + + +/datum/antagonist/ert/families/remove_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + remove_antag_hud(antag_hud_type, M) + if(M.hud_used) + var/datum/hud/H = M.hud_used + H.infodisplay -= H.wanted_lvl + QDEL_NULL(H.wanted_lvl) + ..() + +/datum/antagonist/ert/families/greet() + var/missiondesc = "You are the [name]." + missiondesc += "
    You are NOT a Nanotrasen Employee. You work for the local government." + missiondesc += "
    You are NOT a deathsquad. You are here to help innocents escape violence, criminal activity, and other dangerous things." + missiondesc += "
    After an uptick in gang violence on [station_name()], you are responding to emergency calls from the station for immediate SSC Police assistance!\n" + missiondesc += "
    Your Mission:" + missiondesc += "
    1. Serve the public trust." + missiondesc += "
    2. Protect the innocent." + missiondesc += "
    3. Uphold the law." + missiondesc += "
    4. Find the Undercover Cops." + missiondesc += "
    5. Detain Nanotrasen Security personnel if they harm any citizen." + missiondesc += "
    You can see gangsters using your special sunglasses.
    " + to_chat(owner,missiondesc) + var/policy = get_policy(ROLE_FAMILIES) + if(policy) + to_chat(owner, policy) + var/mob/living/M = owner.current + M.playsound_local(M, 'sound/effects/families_police.ogg', 100, FALSE, pressure_affected = FALSE) + +/datum/antagonist/ert/families/undercover_cop + name = "Undercover Cop" + role = "Undercover Cop" + outfit = /datum/outfit/families_police/beatcop + var/free_clothes = list(/obj/item/clothing/glasses/hud/spacecop/hidden, + /obj/item/clothing/under/rank/security/officer/beatcop, + /obj/item/clothing/head/spacepolice) + forge_objectives_for_ert = FALSE + equip_ert = FALSE + random_names = FALSE + +/datum/antagonist/ert/families/undercover_cop/on_gain() + if(istype(owner.current, /mob/living/carbon/human)) + for(var/C in free_clothes) + var/obj/O = new C(owner.current) + var/list/slots = list ( + "backpack" = ITEM_SLOT_BACKPACK, + "left pocket" = ITEM_SLOT_LPOCKET, + "right pocket" = ITEM_SLOT_RPOCKET + ) + var/mob/living/carbon/human/H = owner.current + var/equipped = H.equip_in_one_of_slots(O, slots) + if(!equipped) + to_chat(owner.current, "Unfortunately, you could not bring your [O] to this shift. You will need to find one.") + qdel(O) + . = ..() + + +/datum/antagonist/ert/families/undercover_cop/greet() + var/missiondesc = "You are the [name]." + missiondesc += "
    You are NOT a Nanotrasen Employee. You work for the local government." + missiondesc += "
    You are an undercover police officer on board [station_name()]. You've been sent here by the Spinward Stellar Coalition because of suspected abusive behavior by the security department, and to keep tabs on a potential criminal organization operation." + missiondesc += "
    Your Mission:" + missiondesc += "
    1. Keep a close eye on any gangsters you spot. You can view gangsters using your sunglasses in your backpack." + missiondesc += "
    2. Keep an eye on how Security handles any gangsters, and watch for excessive security brutality." + missiondesc += "
    3. Remain undercover and do not get found out by Security or any gangs. Nanotrasen does not take kindly to being spied on." + missiondesc += "
    4. When your backup arrives to extract you in 1 hour, inform them of everything you saw of note, and assist them in securing the situation.
    " + to_chat(owner,missiondesc) + +/datum/antagonist/ert/families/beatcop + name = "Beat Cop" + role = "Police Officer" + outfit = /datum/outfit/families_police/beatcop + +/datum/antagonist/ert/families/beatcop/armored + name = "Armored Beat Cop" + role = "Police Officer" + outfit = /datum/outfit/families_police/beatcop/armored + +/datum/antagonist/ert/families/beatcop/swat + name = "S.W.A.T. Member" + role = "S.W.A.T. Officer" + outfit = /datum/outfit/families_police/beatcop/swat + +/datum/antagonist/ert/families/beatcop/fbi + name = "FBI Agent" + role = "FBI Agent" + outfit = /datum/outfit/families_police/beatcop/fbi + +/datum/antagonist/ert/families/beatcop/military + name = "Space Military" + role = "Sergeant" + outfit = /datum/outfit/families_police/beatcop/military + +/datum/antagonist/ert/families/beatcop/military/New() + . = ..() + name_source = GLOB.commando_names + +/datum/antagonist/ert/marine + name = "Marine Commander" + outfit = /datum/outfit/ert/commander/alert + role = "Commander" + +/datum/antagonist/ert/marine/security + name = "Marine Heavy" + outfit = /datum/outfit/ert/security/alert + role = "Trooper" + +/datum/antagonist/ert/marine/engineer + name = "Marine Engineer" + outfit = /datum/outfit/ert/engineer/alert + role = "Engineer" + +/datum/antagonist/ert/marine/medic + name = "Marine Medic" + outfit = /datum/outfit/ert/medic/alert + role = "Medical Officer" diff --git a/code/modules/antagonists/fugitive/fugitive_outfits.dm b/code/modules/antagonists/fugitive/fugitive_outfits.dm index 242a7cc7fd..7648196f3e 100644 --- a/code/modules/antagonists/fugitive/fugitive_outfits.dm +++ b/code/modules/antagonists/fugitive/fugitive_outfits.dm @@ -2,7 +2,7 @@ name = "Prison Escapee" uniform = /obj/item/clothing/under/rank/prisoner shoes = /obj/item/clothing/shoes/sneakers/orange - r_pocket = /obj/item/kitchen/knife + r_pocket = /obj/item/kitchen/knife/shiv /datum/outfit/prisoner/post_equip(mob/living/carbon/human/H, visualsOnly=FALSE) if(visualsOnly) diff --git a/code/modules/antagonists/gang/cellphone.dm b/code/modules/antagonists/gang/cellphone.dm new file mode 100644 index 0000000000..5cba485799 --- /dev/null +++ b/code/modules/antagonists/gang/cellphone.dm @@ -0,0 +1,60 @@ +GLOBAL_LIST_EMPTY(gangster_cell_phones) + +/obj/item/gangster_cellphone + name = "cell phone" + desc = "TODO: funny joke about the 80s, brick phones" + icon = 'icons/obj/gang/cell_phone.dmi' + icon_state = "phone_off" + throwforce = 15 // these things are dense as fuck + var/gang_id = "Grove Street Families" + var/activated = FALSE + +/obj/item/gangster_cellphone/Initialize(mapload) + . = ..() + GLOB.gangster_cell_phones += src + flags_1 |= HEAR_1 + +/obj/item/gangster_cellphone/Destroy() + GLOB.gangster_cell_phones -= src + . = ..() + +/obj/item/gangster_cellphone/attack_self(mob/user, modifiers) + . = ..() + if(!activated) + to_chat(user, "You turn on [src].") + icon_state = "phone_on" + activated = TRUE + else + to_chat(user, "You turn off [src].") + icon_state = "phone_off" + activated = FALSE + +/obj/item/gangster_cellphone/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods) + . = ..() + if(!activated) + return + if(get_turf(speaker) != get_turf(src)) + return + broadcast_message(raw_message, speaker) + +/obj/item/gangster_cellphone/proc/broadcast_message(message, atom/movable/speaker) + for(var/obj/item/gangster_cellphone/brick in GLOB.gangster_cell_phones) + if(brick.gang_id == gang_id) + brick.say_message(message, speaker) + for(var/mob/dead/observer/player_mob in GLOB.player_list) + if(!istype(player_mob, /mob/dead/observer)) + continue + if(QDELETED(player_mob)) //Some times nulls and deleteds stay in this list. This is a workaround to prevent ic chat breaking for everyone when they do. + continue //Remove if underlying cause (likely byond issue) is fixed. See TG PR #49004. + if(player_mob.stat != DEAD) //not dead, not important + continue + if(get_dist(player_mob, src) > 7 || player_mob.z != z) //they're out of range of normal hearing + if(!(player_mob.client.prefs.chat_toggles & CHAT_GHOSTEARS)) //they're talking normally and we have hearing at any range off + continue + to_chat(player_mob, span_gangradio("[speaker.name] \[CELL: [gang_id]\] says, \"[message]\"")) + +/obj/item/gangster_cellphone/proc/say_message(message, atom/movable/speaker) + for(var/mob/living/carbon/human/cellphone_hearer in get_turf(src)) + if(HAS_TRAIT(cellphone_hearer, TRAIT_DEAF)) + continue + to_chat(cellphone_hearer, span_gangradio("[speaker.name] \[CELL: [gang_id]\] says, \"[message]\"")) diff --git a/code/modules/antagonists/gang/gang.dm b/code/modules/antagonists/gang/gang.dm new file mode 100644 index 0000000000..050754a91e --- /dev/null +++ b/code/modules/antagonists/gang/gang.dm @@ -0,0 +1,784 @@ +/datum/antagonist/gang + name = "Family Member" + roundend_category = "gangsters" + ui_name = "AntagInfoGangmember" + antag_hud_type = ANTAG_HUD_GANGSTER + antag_hud_name = "hud_gangster" + antagpanel_category = "Family" + show_in_antagpanel = FALSE // i don't *think* this base class is buggy but it's too worthless to test + suicide_cry = "FOR THE FAMILY!!" + preview_outfit = /datum/outfit/gangster + /// The overarching family that the owner of this datum is a part of. Family teams are generic and imprinted upon by the per-person antagonist datums. + var/datum/team/gang/my_gang + /// The name of the family corresponding to this family member datum. + var/gang_name = "Leet Like Jeff K" + /// The abbreviation of the family corresponding to this family member datum. + var/gang_id = "LLJK" + /// The list of clothes that are acceptable to show allegiance to this family. + var/list/acceptable_clothes = list() + /// The list of clothes that are given to family members upon induction into the family. + var/list/free_clothes = list() + /// The action used to spawn family induction packages. + var/datum/action/cooldown/spawn_induction_package/package_spawner = new() + /// Whether or not this family member is the first of their family. + var/starter_gangster = FALSE + /// The gangster's original real name. Used for renaming stuff, kept between gang switches. + var/original_name + /// Type of team to create when creating the gang in the first place. Used for renames. + var/gang_team_type = /datum/team/gang + + /// A reference to the handler datum that manages the families gamemode. In case of no handler (admin-spawned during round), this will be null; this is fine. + var/datum/gang_handler/handler + +/datum/outfit/gangster + name = "Gangster (Preview only)" + + uniform = /obj/item/clothing/under/suit/henchmen + back = /obj/item/storage/backpack/henchmen + +/datum/antagonist/gang/get_team() + return my_gang + +/datum/antagonist/gang/get_admin_commands() + . = ..() + .["Give extra equipment"] = CALLBACK(src,.proc/equip_gangster_in_inventory) + +/datum/antagonist/gang/create_team(team_given) // gets called whenever add_antag_datum() is called on a mind + if(team_given) + my_gang = team_given + return + /* if team_given is falsey, this gang member didn't join a gang by using a recruitment package. so there are two things we need to consider + 1. does a gang handler exist -- does this round have a gang_handler instanced by the families gamemode or ruleset? + 2. does the gang we're trying to join already exist? + if 1 is true and 2 is false, we were probably added by the gang_handler, and probably already have a "handler" var. + if we don't have a "handler" var, and a gang_handler exists, we need to grab it, since our "handler" is null. + if the gang exists, we need to join it; if the gang doesn't exist, we need to make it. */ + var/found_gang = FALSE + for(var/datum/team/gang/gang_team in GLOB.antagonist_teams) + if(gang_team.my_gang_datum.handler) // if one of the gangs in the gang list has a handler, nab that + handler = gang_team.my_gang_datum.handler + if(gang_team.name == gang_name) + my_gang = gang_team + found_gang = TRUE + break + if(!found_gang) + var/new_gang = new gang_team_type() + my_gang = new_gang + if(handler) // if we have a handler, the handler should track this gang + handler.gangs += my_gang + my_gang.current_theme = handler.current_theme + else if(GLOB.families_override_theme) + my_gang.current_theme = new GLOB.families_override_theme + else + var/theme_to_use = pick(subtypesof(/datum/gang_theme)) + my_gang.current_theme = new theme_to_use + my_gang.name = gang_name + my_gang.gang_id = gang_id + my_gang.acceptable_clothes = acceptable_clothes.Copy() + my_gang.free_clothes = free_clothes.Copy() + my_gang.my_gang_datum = src + starter_gangster = TRUE + +/datum/antagonist/gang/on_gain() + if(!original_name) + original_name = owner.current.real_name + my_gang.rename_gangster(owner, original_name, starter_gangster) // fully_replace_character_name + if(starter_gangster) + equip_gangster_in_inventory() + var/datum/atom_hud/gang_hud = GLOB.huds[ANTAG_HUD_GANGSTER] + gang_hud.add_hud_to(owner.current) + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/thatshowfamiliesworks.ogg', 100, FALSE, pressure_affected = FALSE) + ..() + +/datum/antagonist/gang/on_removal() + if(my_gang.my_gang_datum == src) // if we're the first gangster, we need to replace ourselves so that objectives function correctly + var/datum/antagonist/gang/replacement_datum = new type() + replacement_datum.handler = handler + replacement_datum.my_gang = my_gang + my_gang.my_gang_datum = replacement_datum + /* all we need to replace; the gang's "my_gang_datum" is just a person's datum because we assign it while we + have that datum onhand. it would be easier if all of the code the gang team calls on its my_gang_datum was + just in the team datum itself, and there were different types of teams instead of different types of gangster + that imprint on generic teams, but i'm too lazy to refactor THAT too */ + var/datum/atom_hud/gang_hud = GLOB.huds[ANTAG_HUD_GANGSTER] + gang_hud.remove_hud_from(owner.current) + ..() + +/datum/antagonist/gang/apply_innate_effects(mob/living/mob_override) + ..() + if(starter_gangster) + package_spawner.Grant(owner.current) + package_spawner.my_gang_datum = src + var/mob/living/M = mob_override || owner.current + add_antag_hud(antag_hud_type, antag_hud_name, M) + if(M.hud_used) + var/datum/hud/H = M.hud_used + var/atom/movable/screen/wanted/giving_wanted_lvl = new /atom/movable/screen/wanted() + H.wanted_lvl = giving_wanted_lvl + giving_wanted_lvl.hud = H + H.infodisplay += giving_wanted_lvl + H.mymob.client.screen += giving_wanted_lvl + +/datum/antagonist/gang/remove_innate_effects(mob/living/mob_override) + if(starter_gangster) + package_spawner.Remove(owner.current) + var/mob/living/M = mob_override || owner.current + remove_antag_hud(antag_hud_type, M) + if(M.hud_used) + var/datum/hud/H = M.hud_used + H.infodisplay -= H.wanted_lvl + QDEL_NULL(H.wanted_lvl) + ..() + +/// Gives a gangster their equipment in their backpack and / or pockets. +/datum/antagonist/gang/proc/equip_gangster_in_inventory() + if(istype(owner.current, /mob/living/carbon/human)) + var/obj/item/gangster_cellphone/phone = new() + phone.gang_id = gang_name + phone.name = "[gang_name] branded cell phone" + var/mob/living/carbon/human/gangster_human = owner.current + var/phone_equipped = phone.equip_to_best_slot(gangster_human) + if(!phone_equipped) + to_chat(owner.current, "Your [phone.name] has been placed at your feet.") + phone.forceMove(get_turf(gangster_human)) + for(var/clothing in my_gang.free_clothes) + var/obj/item/clothing_object = new clothing(owner.current) + var/equipped = clothing_object.equip_to_best_slot(gangster_human) + if(!equipped) + to_chat(owner.current, "Your [clothing_object.name] has been placed at your feet.") + clothing_object.forceMove(get_turf(gangster_human)) + if(my_gang.current_theme.bonus_items) + for(var/bonus_item in my_gang.current_theme.bonus_items) + var/obj/item/bonus_object = new bonus_item(owner.current) + var/equipped = bonus_object.equip_to_best_slot(gangster_human) + if(!equipped) + to_chat(owner.current, "Your [bonus_object.name] has been placed at your feet.") + bonus_object.forceMove(get_turf(gangster_human)) + if(starter_gangster) + if(my_gang.current_theme.bonus_first_gangster_items) + for(var/bonus_starter_item in my_gang.current_theme.bonus_first_gangster_items) + var/obj/item/bonus_starter_object = new bonus_starter_item(owner.current) + var/equipped = bonus_starter_object.equip_to_best_slot(gangster_human) + if(!equipped) + to_chat(owner.current, "Your [bonus_starter_object.name] has been placed at your feet.") + bonus_starter_object.forceMove(get_turf(gangster_human)) + +/datum/antagonist/gang/ui_static_data(mob/user) + var/list/data = list() + data["gang_name"] = gang_name + data["antag_name"] = name + data["gang_objective"] = my_gang.current_theme.gang_objectives[type] + + var/list/clothes_we_can_wear = list() + for(var/obj/item/accepted_item as anything in acceptable_clothes) + clothes_we_can_wear |= initial(accepted_item.name) + + for(var/obj/item/free_item as anything in free_clothes) + if(ispath(free_item, /obj/item/toy/crayon/spraycan)) + continue + clothes_we_can_wear |= initial(free_item.name) + + data["gang_clothes"] = clothes_we_can_wear + return data + +/datum/team/gang + /// The abbreviation of this family. + var/gang_id = "LLJK" + /// The list of clothes that are acceptable to show allegiance to this family. + var/list/acceptable_clothes = list() + /// The list of clothes that are given to family members upon induction into the family. + var/list/free_clothes = list() + /// The specific, occupied family member antagonist datum that is used to reach the handler / check objectives, and from which the above properties (sans points) are inherited. + var/datum/antagonist/gang/my_gang_datum + /// The current theme. Used to pull important stuff such as spawning equipment and objectives. + var/datum/gang_theme/current_theme + +/// Allow gangs to have custom naming schemes for their gangsters. +/datum/team/gang/proc/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) + +/datum/team/gang/roundend_report() + var/list/report = list() + report += "[name]:" + if(!members.len) + report += span_redtext("The family was wiped out!") + if(current_theme.everyone_objective) + report += "Objective: [current_theme.everyone_objective]" + else + var/assigned_objective = current_theme.gang_objectives[my_gang_datum.type] + if(assigned_objective) + report += "Objective: [assigned_objective]" + else + report += "Objective: ERROR, FILE A REPORT WITH THIS INFO: Gang Name: [my_gang_datum.name], Theme Name: [current_theme.name]" + if(members.len) + report += "[my_gang_datum.roundend_category] were:" + report += printplayerlist(members) + + return "
    [report.Join("
    ")]
    " + +/datum/action/cooldown/spawn_induction_package + name = "Induct via Secret Handshake" + desc = "Teach new recruits the Secret Handshake to join." + check_flags = AB_CHECK_CONSCIOUS + button_icon_state = "recruit" + icon_icon = 'icons/obj/gang/actions.dmi' + cooldown_time = 300 + /// The family antagonist datum of the "owner" of this action. + var/datum/antagonist/gang/my_gang_datum + +/datum/action/cooldown/spawn_induction_package/Trigger() + if(!..()) + return FALSE + if(!IsAvailable()) + return FALSE + if(!my_gang_datum) + return FALSE + if(!istype(owner, /mob/living/carbon/human)) + return FALSE + var/mob/living/carbon/human/H = owner + if(H.stat) + return FALSE + + var/obj/item/slapper/secret_handshake/secret_handshake_item = new(owner) + if(owner.put_in_hands(secret_handshake_item)) + to_chat(owner, span_notice("You ready your secret handshake.")) + else + qdel(secret_handshake_item) + to_chat(owner, span_warning("You're incapable of performing a handshake in your current state.")) + return FALSE + owner.visible_message(span_notice("[owner] is offering to induct people into the Family."), + span_notice("You offer to induct people into the Family."), null, 2) + if(H.has_status_effect(STATUS_EFFECT_HANDSHAKE)) + return FALSE + if(!(locate(/mob/living/carbon) in orange(1, owner))) + owner.visible_message(span_danger("[owner] offers to induct people into the Family, but nobody was around."), \ + span_warning("You offer to induct people into the Family, but nobody is around."), null, 2) + return FALSE + + H.apply_status_effect(STATUS_EFFECT_HANDSHAKE, secret_handshake_item) + StartCooldown() + return TRUE + +/datum/antagonist/gang/russian_mafia + show_in_antagpanel = TRUE + name = "Mafioso" + roundend_category = "The mafiosos" + gang_name = "Mafia" + gang_id = "RM" + acceptable_clothes = list(/obj/item/clothing/head/soft/red, + /obj/item/clothing/neck/scarf/red, + /obj/item/clothing/under/suit/white, + /obj/item/clothing/head/beanie/red, + /obj/item/clothing/head/ushanka) + free_clothes = list(/obj/item/clothing/head/ushanka, + /obj/item/clothing/under/suit/white, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "Russian" + gang_team_type = /datum/team/gang/russian_mafia + +/datum/team/gang/russian_mafia/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Don [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) + +/datum/antagonist/gang/italian_mob + show_in_antagpanel = TRUE + name = "Mobster" + roundend_category = "The mobsters" + gang_name = "Mob" + gang_id = "IM" + acceptable_clothes = list(/obj/item/clothing/under/suit/checkered, + /obj/item/clothing/head/fedora, + /obj/item/clothing/neck/scarf/green, + /obj/item/clothing/mask/bandana/green) + free_clothes = list(/obj/item/clothing/head/fedora, + /obj/item/clothing/under/suit/checkered, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "Italian" + gang_team_type = /datum/team/gang/russian_mafia + +/datum/team/gang/russian_mafia/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Boss [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) + +/datum/antagonist/gang/tunnel_snakes + show_in_antagpanel = TRUE + name = "Tunnel Snake" + roundend_category = "The Tunnel Snakes" + gang_name = "Tunnel Snakes" + gang_id = "TS" + acceptable_clothes = list(/obj/item/clothing/under/pants/classicjeans, + /obj/item/clothing/suit/jacket, + /obj/item/clothing/mask/bandana/skull) + free_clothes = list(/obj/item/clothing/suit/jacket, + /obj/item/clothing/under/pants/classicjeans, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "Snakes" + gang_team_type = /datum/team/gang/tunnel_snakes + +/datum/team/gang/tunnel_snakes/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "King Cobra [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) + +/datum/antagonist/gang/henchmen + show_in_antagpanel = TRUE + name = "Monarch Henchmen" + roundend_category = "The Monarch henchmen" + gang_name = "Monarch Crew" + gang_id = "HENCH" + acceptable_clothes = list(/obj/item/clothing/head/soft/yellow, + /obj/item/clothing/under/suit/henchmen, + /obj/item/clothing/neck/scarf/yellow, + /obj/item/clothing/head/beanie/yellow, + /obj/item/clothing/mask/bandana/gold, + /obj/item/storage/backpack/henchmen) + free_clothes = list(/obj/item/storage/backpack/henchmen, + /obj/item/clothing/under/suit/henchmen, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "Monarch" + gang_team_type = /datum/team/gang/henchmen + +/datum/team/gang/henchmen + var/henchmen_count = 0 + +/datum/team/gang/henchmen/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + henchmen_count++ + gangster.current.fully_replace_character_name(gangster.current.real_name, "Number [henchmen_count]") + +/datum/antagonist/gang/yakuza + show_in_antagpanel = TRUE + name = "Tojo Clan Member" + roundend_category = "The Yakuza" + gang_name = "Tojo Clan" + gang_id = "YAK" + acceptable_clothes = list(/obj/item/clothing/head/soft/yellow, + /obj/item/clothing/under/costume/yakuza, + /obj/item/clothing/shoes/yakuza, + /obj/item/clothing/neck/scarf/yellow, + /obj/item/clothing/head/beanie/yellow, + /obj/item/clothing/mask/bandana/gold, + /obj/item/clothing/head/hardhat, + /obj/item/clothing/suit/yakuza) + free_clothes = list(/obj/item/clothing/under/costume/yakuza, + /obj/item/clothing/shoes/yakuza, + /obj/item/clothing/suit/yakuza, + /obj/item/clothing/head/hardhat, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "Tojo" + gang_team_type = /datum/team/gang/yakuza + +/datum/team/gang/yakuza/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Patriarch [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) + +/datum/antagonist/gang/jackbros + show_in_antagpanel = TRUE + name = "Jack Bro" + roundend_category = "The Hee-hos" + gang_name = "Jack Bros" + gang_id = "JB" + acceptable_clothes = list(/obj/item/clothing/head/soft/blue, + /obj/item/clothing/under/costume/jackbros, + /obj/item/clothing/shoes/jackbros, + /obj/item/clothing/head/jackbros, + /obj/item/clothing/mask/bandana/blue) + free_clothes = list(/obj/item/clothing/under/costume/jackbros, + /obj/item/clothing/shoes/jackbros, + /obj/item/clothing/head/jackbros, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "JackFrost" + gang_team_type = /datum/team/gang/jackbros + +/datum/team/gang/jackbros/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "King Frost [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) + +/datum/antagonist/gang/dutch + show_in_antagpanel = TRUE + name = "Dutch van der Linde Outlaw" + roundend_category = "Dutch's outlaws" + gang_name = "Dutch van der Linde's Gang" + gang_id = "VDL" + acceptable_clothes = list(/obj/item/clothing/head/soft/black, + /obj/item/clothing/under/costume/dutch, + /obj/item/clothing/suit/dutch, + /obj/item/clothing/head/bowler, + /obj/item/clothing/mask/bandana/black) + free_clothes = list(/obj/item/clothing/under/costume/dutch, + /obj/item/clothing/head/bowler, + /obj/item/clothing/suit/dutch, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "Dutch" + gang_team_type = /datum/team/gang/dutch + +/datum/team/gang/dutch/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Head Cowboy [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) + + +/datum/antagonist/gang/irs + show_in_antagpanel = TRUE + name = "Internal Revenue Service Agent" + roundend_category = "IRS Agents" + gang_name = "Internal Revenue Service" + gang_id = "IRS" + acceptable_clothes = list(/obj/item/clothing/suit/irs, + /obj/item/clothing/under/costume/irs, + /obj/item/clothing/head/irs) + free_clothes = list(/obj/item/clothing/suit/irs, + /obj/item/clothing/under/costume/irs, + /obj/item/clothing/head/irs, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "IRS" + gang_team_type = /datum/team/gang/irs + +/datum/team/gang/irs/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Revenue Supervisor [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, "Revenue Agent [last_name.match]") + +/datum/antagonist/gang/osi + show_in_antagpanel = TRUE + name = "Office of Secret Intelligence Agent" + roundend_category = "O.S.I. Agents" + gang_name = "Office of Secret Intelligence" + gang_id = "OSI" + acceptable_clothes = list(/obj/item/clothing/suit/osi, + /obj/item/clothing/under/costume/osi, + /obj/item/clothing/glasses/osi) + free_clothes = list(/obj/item/clothing/suit/osi, + /obj/item/clothing/under/costume/osi, + /obj/item/clothing/glasses/osi, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "OSI" + gang_team_type = /datum/team/gang/osi + +/datum/team/gang/osi/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "General [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, "Special Agent [last_name.match]") + +/datum/antagonist/gang/tmc + show_in_antagpanel = TRUE + name = "Lost M.C. Biker" + roundend_category = "Lost M.C. Bikers" + gang_name = "The Lost M.C." + gang_id = "TMC" + acceptable_clothes = list(/obj/item/clothing/suit/tmc, + /obj/item/clothing/under/costume/tmc, + /obj/item/clothing/head/tmc) + free_clothes = list(/obj/item/clothing/suit/tmc, + /obj/item/clothing/under/costume/tmc, + /obj/item/clothing/head/tmc, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "LostMC" + gang_team_type = /datum/team/gang/tmc + +/datum/team/gang/tmc/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "President [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) + +/datum/antagonist/gang/pg + show_in_antagpanel = TRUE + name = "Powder Ganger" + roundend_category = "Powder Gangers" + gang_name = "Powder Gangers" + gang_id = "PG" + acceptable_clothes = list(/obj/item/clothing/suit/pg, + /obj/item/clothing/under/costume/pg, + /obj/item/clothing/head/pg) + free_clothes = list(/obj/item/clothing/suit/pg, + /obj/item/clothing/under/costume/pg, + /obj/item/clothing/head/pg, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "PowderGang" + gang_team_type = /datum/team/gang/pg + +/datum/team/gang/pg/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Head Convict [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) + + +/datum/antagonist/gang/driscoll + show_in_antagpanel = TRUE + name = "O'Driscoll Gangster" + roundend_category = "O'Driscoll's Gangsters" + gang_name = "O'Driscoll's Gang" + gang_id = "DB" + acceptable_clothes = list(/obj/item/clothing/suit/driscoll, + /obj/item/clothing/under/costume/driscoll, + /obj/item/clothing/mask/gas/driscoll, + /obj/item/clothing/shoes/cowboyboots) + free_clothes = list(/obj/item/clothing/suit/driscoll, + /obj/item/clothing/under/costume/driscoll, + /obj/item/clothing/mask/gas/driscoll, + /obj/item/clothing/shoes/cowboyboots, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "Drill" + gang_team_type = /datum/team/gang/driscoll + +/datum/team/gang/driscoll/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Head Outlaw [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) + +/datum/antagonist/gang/deckers + show_in_antagpanel = TRUE + name = "Decker" + roundend_category = "Deckers" + gang_name = "Deckers" + gang_id = "DK" + acceptable_clothes = list(/obj/item/clothing/suit/deckers, + /obj/item/clothing/under/costume/deckers, + /obj/item/clothing/head/deckers, + /obj/item/clothing/shoes/deckers) + free_clothes = list(/obj/item/clothing/suit/deckers, + /obj/item/clothing/under/costume/deckers, + /obj/item/clothing/head/deckers, + /obj/item/clothing/shoes/deckers, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "Deckers" + gang_team_type = /datum/team/gang/deckers + +/datum/team/gang/deckers/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Master Hacker [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) + + +/datum/antagonist/gang/morningstar + show_in_antagpanel = TRUE + name = "Morningstar Member" + roundend_category = "Morningstar Member" + gang_name = "Morningstar" + gang_id = "MS" + acceptable_clothes = list(/obj/item/clothing/suit/morningstar, + /obj/item/clothing/under/costume/morningstar, + /obj/item/clothing/head/morningstar, + /obj/item/clothing/shoes/morningstar) + free_clothes = list(/obj/item/clothing/suit/morningstar, + /obj/item/clothing/under/costume/morningstar, + /obj/item/clothing/head/morningstar, + /obj/item/clothing/shoes/morningstar, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "MorningStar" + gang_team_type = /datum/team/gang/morningstar + +/datum/team/gang/morningstar/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Chief Executive Officer [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) + +/datum/antagonist/gang/saints + show_in_antagpanel = TRUE + name = "Third Street Saints Gangster" + roundend_category = "Third Street Saints Gangsters" + gang_name = "Third Street Saints" + gang_id = "TSS" + acceptable_clothes = list(/obj/item/clothing/suit/saints, + /obj/item/clothing/under/costume/saints, + /obj/item/clothing/head/saints, + /obj/item/clothing/shoes/saints) + free_clothes = list(/obj/item/clothing/suit/saints, + /obj/item/clothing/under/costume/saints, + /obj/item/clothing/head/saints, + /obj/item/clothing/shoes/saints, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "TheSaints" + gang_team_type = /datum/team/gang/saints + +/datum/team/gang/saints/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Boss [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) + + +/datum/antagonist/gang/phantom + show_in_antagpanel = TRUE + name = "Phantom Thief" + roundend_category = "Phantom Thieves" + gang_name = "Phantom Thieves of Hearts" + gang_id = "PT" + acceptable_clothes = list(/obj/item/clothing/suit/phantom, + /obj/item/clothing/under/costume/phantom, + /obj/item/clothing/glasses/phantom, + /obj/item/clothing/shoes/phantom) + free_clothes = list(/obj/item/clothing/suit/phantom, + /obj/item/clothing/under/costume/phantom, + /obj/item/clothing/glasses/phantom, + /obj/item/clothing/shoes/phantom, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "PhantomThieves" + gang_team_type = /datum/team/gang/phantom + +/datum/team/gang/phantom/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Joker [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) + +/datum/antagonist/gang/allies + show_in_antagpanel = TRUE + name = "Allies G.I." + roundend_category = "Allies" + gang_name = "Allies" + gang_id = "ALLIES" + free_clothes = list(/obj/item/clothing/suit/allies, + /obj/item/clothing/under/costume/allies, + /obj/item/clothing/head/allies, + /obj/item/clothing/gloves/color/black, + /obj/item/clothing/shoes/jackboots, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "Allies" + gang_team_type = /datum/team/gang/allies + +/datum/team/gang/allies/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Commander [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, "Private [last_name.match]") + +/datum/antagonist/gang/soviet + show_in_antagpanel = TRUE + name = "Soviet Conscript" + roundend_category = "Soviets" + gang_name = "Soviets" + gang_id = "SOV" + free_clothes = list(/obj/item/clothing/suit/soviet, + /obj/item/clothing/under/costume/soviet_families, + /obj/item/clothing/head/ushanka/soviet, + /obj/item/clothing/gloves/color/black, + /obj/item/clothing/shoes/jackboots, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "Soviets" + gang_team_type = /datum/team/gang/soviet + +/datum/team/gang/soviet/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Comrade General [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, "Conscript [last_name.match]") + +/datum/antagonist/gang/yuri + show_in_antagpanel = TRUE + name = "Yuri Initiate" + roundend_category = "Yuri's Army" + gang_name = "Yuri's Army" + gang_id = "YR" + free_clothes = list(/obj/item/clothing/suit/yuri, + /obj/item/clothing/under/costume/yuri, + /obj/item/clothing/head/yuri, + /obj/item/clothing/gloves/color/black, + /obj/item/clothing/shoes/jackboots, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "YuriArmy" + gang_team_type = /datum/team/gang/yuri + +/datum/team/gang/yuri/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Initiate Prime [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, "Initiate [last_name.match]") + +/datum/antagonist/gang/sybil_slickers + show_in_antagpanel = TRUE + name = "Sybil Slicker" + roundend_category = "Sybil Slickers" + gang_name = "Sybil Slickers" + gang_id = "SS" + free_clothes = list(/obj/item/clothing/suit/sybil_slickers, + /obj/item/clothing/under/costume/sybil_slickers, + /obj/item/clothing/head/sybil_slickers, + /obj/item/clothing/gloves/tackler/football, + /obj/item/clothing/shoes/sybil_slickers, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "SybilSlickers" + gang_team_type = /datum/team/gang/sybil_slickers + +/datum/team/gang/sybil_slickers/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Sybil Coach [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) + +/datum/antagonist/gang/basil_boys + show_in_antagpanel = TRUE + name = "Basil Boy" + roundend_category = "Basil Boys" + gang_name = "Basil Boys" + gang_id = "BB" + free_clothes = list(/obj/item/clothing/suit/basil_boys, + /obj/item/clothing/under/costume/basil_boys, + /obj/item/clothing/head/basil_boys, + /obj/item/clothing/gloves/tackler/football, + /obj/item/clothing/shoes/basil_boys, + /obj/item/toy/crayon/spraycan) + antag_hud_name = "BasilBoys" + gang_team_type = /datum/team/gang/basil_boys + +/datum/team/gang/basil_boys/rename_gangster(datum/mind/gangster, original_name, starter_gangster) + var/static/regex/last_name = new("\[^\\s-\]+$") //First word before whitespace or "-" + last_name.Find(original_name) + if(starter_gangster) + gangster.current.fully_replace_character_name(gangster.current.real_name, "Basil Coach [last_name.match]") + else + gangster.current.fully_replace_character_name(gangster.current.real_name, original_name) diff --git a/code/modules/antagonists/gang/handler.dm b/code/modules/antagonists/gang/handler.dm new file mode 100644 index 0000000000..0f6e28752d --- /dev/null +++ b/code/modules/antagonists/gang/handler.dm @@ -0,0 +1,429 @@ +#define LOWPOP_FAMILIES_COUNT 50 + +#define TWO_STARS_HIGHPOP 11 +#define THREE_STARS_HIGHPOP 16 +#define FOUR_STARS_HIGHPOP 21 +#define FIVE_STARS_HIGHPOP 31 + +#define TWO_STARS_LOW 6 +#define THREE_STARS_LOW 9 +#define FOUR_STARS_LOW 12 +#define FIVE_STARS_LOW 15 + +#define CREW_SIZE_MIN 4 +#define CREW_SIZE_MAX 8 + + +GLOBAL_VAR_INIT(deaths_during_shift, 0) +///Forces the Families theme to be the one in this variable via variable editing. Used for debugging. +GLOBAL_VAR(families_override_theme) + +/** + * # Families gamemode / dynamic ruleset handler + * + * A special datum used by the families gamemode and dynamic rulesets to centralize code. "Family" and "gang" used interchangeably in code. + * + * This datum centralizes code used for the families gamemode / dynamic rulesets. Families incorporates a significant + * amount of unique processing; without this datum, that could would be duplicated. To ensure the maintainability + * of the families gamemode / rulesets, the code was moved to this datum. The gamemode / rulesets instance this + * datum, pass it lists (lists are passed by reference; removing candidates here removes candidates in the gamemode), + * and call its procs. Additionally, the families antagonist datum and families induction package also + * contain vars that reference this datum, allowing for new families / family members to add themselves + * to this datum's lists thereof (primarily used for point calculation). Despite this, the basic team mechanics + * themselves should function regardless of this datum's instantiation, should a player have the gang or cop + * antagonist datum added to them through methods external to the families gamemode / rulesets. + * + */ +/datum/gang_handler + /// A counter used to minimize the overhead of computationally intensive, periodic family point gain checks. Used and set internally. + var/check_counter = 0 + /// The time, in deciseconds, that the datum's pre_setup() occured at. Used in end_time. Used and set internally. + var/start_time = null + /// The time, in deciseconds, that the space cops will arrive at. Calculated based on wanted level and start_time. Used and set internally. + var/end_time = null + /// Whether the gamemode-announcing announcement has been sent. Used and set internally. + var/sent_announcement = FALSE + /// Whether the "5 minute warning" announcement has been sent. Used and set internally. + var/sent_second_announcement = FALSE + /// Whether the space cops have arrived. Set internally; used internally, and for updating the wanted HUD. + var/cops_arrived = FALSE + /// The current wanted level. Set internally; used internally, and for updating the wanted HUD. + var/wanted_level + /// List of all /datum/team/gang. Used internally; added to externally by /datum/antagonist/gang when it generates a new /datum/team/gang. + var/list/gangs = list() + /// List of all family member minds. Used internally; added to internally, and externally by /obj/item/gang_induction_package when used to induct a new family member. + var/list/gangbangers = list() + /// List of all undercover cop minds. Used and set internally. + var/list/undercover_cops = list() + /// The number of families (and 1:1 corresponding undercover cops) that should be generated. Can be set externally; used internally. + var/gangs_to_generate = 3 + /// The number of family members more that a family may have over other active families. Can be set externally; used internally. + var/gang_balance_cap = 5 + /// Whether the handler corresponds to a ruleset that does not trigger at round start. Should be set externally only if applicable; used internally. + var/midround_ruleset = FALSE + /// Whether we want to use the 30 to 15 minute timer instead of the 60 to 30 minute timer, for Dynamic. + var/use_dynamic_timing = FALSE + /// Keeps track of the amount of deaths since the calling of pre_setup_analogue() if this is a midround handler. Used to prevent a high wanted level due to a large amount of deaths during the shift prior to the activation of this handler / the midround ruleset. + var/deaths_during_shift_at_beginning = 0 + + /// List of all eligible starting family members / undercover cops. Set externally (passed by reference) by gamemode / ruleset; used internally. Note that dynamic uses a list of mobs to handle candidates while game_modes use lists of minds! Don't be fooled! + var/list/antag_candidates = list() + /// List of jobs not eligible for starting family member / undercover cop. Set externally (passed by reference) by gamemode / ruleset; used internally. + var/list/restricted_jobs + /// The current chosen gamemode theme. Decides the available Gangs, objectives, and equipment. + var/datum/gang_theme/current_theme + +/** + * Sets antag_candidates and restricted_jobs. + * + * Sets the antag_candidates and restricted_jobs lists to the equivalent + * lists of its instantiating game_mode / dynamic_ruleset datum. As lists + * are passed by reference, the variable set in this datum and the passed list + * list used to set it are literally the same; changes to one affect the other. + * Like all New() procs, called when the datum is first instantiated. + * There's an annoying caveat here, though -- dynamic rulesets don't have + * lists of minds for candidates, they have lists of mobs. Ghost mobs, before + * the round has started. But we still want to preserve the structure of the candidates + * list by not duplicating it and making sure to remove the candidates as we use them. + * So there's a little bit of boilerplate throughout to preserve the sanctity of this reference. + * Arguments: + * * given_candidates - The antag_candidates list or equivalent of the datum instantiating this one. + * * revised_restricted - The restricted_jobs list or equivalent of the datum instantiating this one. + */ +/datum/gang_handler/New(list/given_candidates, list/revised_restricted) + antag_candidates = given_candidates + restricted_jobs = revised_restricted + +/** + * pre_setup() or pre_execute() equivalent. + * + * This proc is always called externally, by the instantiating game_mode / dynamic_ruleset. + * This is done during the pre_setup() or pre_execute() phase, after first instantiation + * and the modification of gangs_to_generate, gang_balance_cap, and midround_ruleset. + * It is intended to take the place of the code that would normally occupy the pre_setup() + * or pre_execute() proc, were the code localized to the game_mode or dynamic_ruleset datum respectively + * as opposed to this handler. As such, it picks players to be chosen for starting familiy members + * or undercover cops prior to assignment to jobs. Sets start_time, default end_time, + * and the current value of deaths_during_shift, to ensure the wanted level only cares about + * the deaths since this proc has been called. + * Takes no arguments. + */ +/datum/gang_handler/proc/pre_setup_analogue() + if(!GLOB.families_override_theme) + var/theme_to_use = pick(subtypesof(/datum/gang_theme)) + current_theme = new theme_to_use + else + current_theme = new GLOB.families_override_theme + var/gangsters_to_make = length(current_theme.involved_gangs) * current_theme.starting_gangsters + for(var/i in 1 to gangsters_to_make) + if (!antag_candidates.len) + break + var/taken = pick_n_take(antag_candidates) // original used antag_pick, but that's local to game_mode and rulesets use pick_n_take so this is fine maybe + var/datum/mind/gangbanger + if(istype(taken, /mob)) + var/mob/T = taken + gangbanger = T.mind + else + gangbanger = taken + gangbangers += gangbanger + gangbanger.restricted_roles = restricted_jobs + log_game("[key_name(gangbanger)] has been selected as a starting gangster!") + if(!midround_ruleset) + GLOB.pre_setup_antags += gangbanger + deaths_during_shift_at_beginning = GLOB.deaths_during_shift // don't want to mix up pre-families and post-families deaths + start_time = world.time + end_time = start_time + ((60 MINUTES) / (midround_ruleset ? 2 : 1)) // midround families rounds end quicker + return TRUE + +/** + * post_setup() or execute() equivalent. + * + * This proc is always called externally, by the instantiating game_mode / dynamic_ruleset. + * This is done during the post_setup() or execute() phase, after the pre_setup() / pre_execute() phase. + * It is intended to take the place of the code that would normally occupy the pre_setup() + * or pre_execute() proc. As such, it ensures that all prospective starting family members / + * undercover cops are eligible, and picks replacements if there were ineligible cops / family members. + * It then assigns gear to the finalized family members and undercover cops, adding them to its lists, + * and sets the families announcement proc (that does the announcing) to trigger in five minutes. + * Additionally, if given the argument TRUE, it will return FALSE if there are no eligible starting family members. + * This is only to be done if the instantiating datum is a dynamic_ruleset, as these require returns + * while a game_mode is not expected to return early during this phase. + * Arguments: + * * return_if_no_gangs - Boolean that determines if the proc should return FALSE should it find no eligible family members. Should be used for dynamic only. + */ +/datum/gang_handler/proc/post_setup_analogue(return_if_no_gangs = FALSE) + var/replacement_gangsters = 0 + for(var/datum/mind/gangbanger in gangbangers) + if(!ishuman(gangbanger.current)) + if(!midround_ruleset) + GLOB.pre_setup_antags -= gangbanger + gangbangers.Remove(gangbanger) + log_game("[gangbanger] was not a human, and thus has lost their gangster role.") + replacement_gangsters++ + if(replacement_gangsters) + for(var/j = 0, j < replacement_gangsters, j++) + if(!antag_candidates.len) + log_game("Unable to find more replacement gangsters. Not all of the gangs will spawn.") + break + var/taken = pick_n_take(antag_candidates) + var/datum/mind/gangbanger + if(istype(taken, /mob)) // boilerplate needed because antag_candidates might not contain minds + var/mob/T = taken + gangbanger = T.mind + else + gangbanger = taken + gangbangers += gangbanger + log_game("[key_name(gangbanger)] has been selected as a replacement gangster!") + if(!gangbangers.len) + if(return_if_no_gangs) + return FALSE // ending early is bad if we're not in dynamic + + var/list/gangs_to_use = current_theme.involved_gangs + var/amount_of_gangs = gangs_to_use.len + + for(var/_ in 1 to amount_of_gangs) + var/gang_to_use = pick_n_take(gangs_to_use) + for(var/__ in 1 to current_theme.starting_gangsters) + if(!gangbangers.len) + break + var/datum/mind/gangster_mind = pick_n_take(gangbangers) + var/datum/antagonist/gang/new_gangster = new gang_to_use() + new_gangster.handler = src + new_gangster.starter_gangster = TRUE + gangster_mind.add_antag_datum(new_gangster) + + // see /datum/antagonist/gang/create_team() for how the gang team datum gets instantiated and added to our gangs list + + addtimer(CALLBACK(src, .proc/announce_gang_locations), 5 MINUTES) + return TRUE + +/** + * process() or rule_process() equivalent. + * + * This proc is always called externally, by the instantiating game_mode / dynamic_ruleset. + * This is done during the process() or rule_process() phase, after post_setup() or + * execute() and at regular intervals thereafter. process() and rule_process() are optional + * for a game_mode / dynamic_ruleset, but are important for this gamemode. It is of central + * importance to the gamemode's flow, calculating wanted level updates, family point gain, + * and announcing + executing the arrival of the space cops, achieved through calling internal procs. + * Takes no arguments. + */ +/datum/gang_handler/proc/process_analogue() + +/** + * set_round_result() or round_result() equivalent. + * + * This proc is always called externally, by the instantiating game_mode / dynamic_ruleset. + * This is done by the set_round_result() or round_result() procs, at roundend. + * Sets the ticker subsystem to the correct result based off of the relative populations + * of space cops and family members. + * Takes no arguments. + */ +/datum/gang_handler/proc/set_round_result_analogue() + SSticker.mode_result = "win - gangs survived" + SSticker.news_report = GANG_OPERATING + return TRUE + +/// Internal. Announces the presence of families to the entire station and sets sent_announcement to true to allow other checks to occur. +/datum/gang_handler/proc/announce_gang_locations() + priority_announce(current_theme.description, current_theme.name, 'sound/voice/beepsky/radio.ogg') + sent_announcement = TRUE + +/// Internal. Checks if our wanted level has changed; calls update_wanted_level. Only updates wanted level post the initial announcement and until the cops show up. After that, it's locked. +/datum/gang_handler/proc/check_wanted_level() + if(cops_arrived) + update_wanted_level(wanted_level) // at this point, we still want to update people's star huds, even though they're mostly locked, because not everyone is around for the last update before the rest of this proc gets shut off forever, and that's when the wanted bar switches from gold stars to red / blue to signify the arrival of the space cops + return + if(!sent_announcement) + return + var/new_wanted_level + if(GLOB.joined_player_list.len > LOWPOP_FAMILIES_COUNT) + switch(GLOB.deaths_during_shift - deaths_during_shift_at_beginning) // if this is a midround ruleset, we only care about the deaths since the families were activated, not since shiftstart + if(0 to TWO_STARS_HIGHPOP-1) + new_wanted_level = 1 + if(TWO_STARS_HIGHPOP to THREE_STARS_HIGHPOP-1) + new_wanted_level = 2 + if(THREE_STARS_HIGHPOP to FOUR_STARS_HIGHPOP-1) + new_wanted_level = 3 + if(FOUR_STARS_HIGHPOP to FIVE_STARS_HIGHPOP-1) + new_wanted_level = 4 + if(FIVE_STARS_HIGHPOP to INFINITY) + new_wanted_level = 5 + else + switch(GLOB.deaths_during_shift - deaths_during_shift_at_beginning) + if(0 to TWO_STARS_LOW-1) + new_wanted_level = 1 + if(TWO_STARS_LOW to THREE_STARS_LOW-1) + new_wanted_level = 2 + if(THREE_STARS_LOW to FOUR_STARS_LOW-1) + new_wanted_level = 3 + if(FOUR_STARS_LOW to FIVE_STARS_LOW-1) + new_wanted_level = 4 + if(FIVE_STARS_LOW to INFINITY) + new_wanted_level = 5 + update_wanted_level(new_wanted_level) + +/// Internal. Updates the icon states for everyone, and calls procs that send out announcements / change the end_time if the wanted level has changed. +/datum/gang_handler/proc/update_wanted_level(newlevel) + if(newlevel > wanted_level) + on_gain_wanted_level(newlevel) + else if (newlevel < wanted_level) + on_lower_wanted_level(newlevel) + wanted_level = newlevel + for(var/i in GLOB.player_list) + var/mob/M = i + if(!M.hud_used?.wanted_lvl) + continue + var/datum/hud/H = M.hud_used + H.wanted_lvl.level = newlevel + H.wanted_lvl.cops_arrived = cops_arrived + H.wanted_lvl.update_appearance() + +/// Internal. Updates the end_time and sends out an announcement if the wanted level has increased. Called by update_wanted_level(). +/datum/gang_handler/proc/on_gain_wanted_level(newlevel) + var/announcement_message + switch(newlevel) + if(2) + if(!sent_second_announcement) // when you hear that they're "arriving in 5 minutes," that's a goddamn guarantee + end_time = start_time + ((50 MINUTES) / (use_dynamic_timing ? 2 : 1)) + announcement_message = "Small amount of police vehicles have been spotted en route towards [station_name()]." + if(3) + if(!sent_second_announcement) + end_time = start_time + ((40 MINUTES) / (use_dynamic_timing ? 2 : 1)) + announcement_message = "A large detachment police vehicles have been spotted en route towards [station_name()]." + if(4) + if(!sent_second_announcement) + end_time = start_time + ((35 MINUTES) / (use_dynamic_timing ? 2 : 1)) + announcement_message = "A detachment of top-trained agents has been spotted on their way to [station_name()]." + if(5) + if(!sent_second_announcement) + end_time = start_time + ((30 MINUTES) / (use_dynamic_timing ? 2 : 1)) + announcement_message = "The fleet enroute to [station_name()] now consists of national guard personnel." + if(!midround_ruleset) // stops midround rulesets from announcing janky ass times + announcement_message += " They will arrive at the [(end_time - start_time) / (1 MINUTES)] minute mark." + if(newlevel == 1) // specific exception to stop the announcement from triggering right after the families themselves are announced because aesthetics + return + priority_announce(announcement_message, "Station Spaceship Detection Systems") + +/// Internal. Updates the end_time and sends out an announcement if the wanted level has decreased. Called by update_wanted_level(). +/datum/gang_handler/proc/on_lower_wanted_level(newlevel) + var/announcement_message + switch(newlevel) + if(1) + if(!sent_second_announcement) + end_time = start_time + ((60 MINUTES) / (use_dynamic_timing ? 2 : 1)) + announcement_message = "There are now only a few police vehicle headed towards [station_name()]." + if(2) + if(!sent_second_announcement) + end_time = start_time + ((50 MINUTES) / (use_dynamic_timing ? 2 : 1)) + announcement_message = "There seem to be fewer police vehicles headed towards [station_name()]." + if(3) + if(!sent_second_announcement) + end_time = start_time + ((40 MINUTES) / (use_dynamic_timing ? 2 : 1)) + announcement_message = "There are no longer top-trained agents in the fleet headed towards [station_name()]." + if(4) + if(!sent_second_announcement) + end_time = start_time + ((35 MINUTES) / (use_dynamic_timing ? 2 : 1)) + announcement_message = "The convoy enroute to [station_name()] seems to no longer consist of national guard personnel." + if(!midround_ruleset) + announcement_message += " They will arrive at the [(end_time - start_time) / (1 MINUTES)] minute mark." + priority_announce(announcement_message, "Station Spaceship Detection Systems") + +/// Internal. Polls ghosts and sends in a team of space cops according to the wanted level, accompanied by an announcement. Will let the shuttle leave 10 minutes after sending. Freezes the wanted level. +/datum/gang_handler/proc/send_in_the_fuzz() + var/team_size + var/cops_to_send + var/announcement_message = "PUNK ASS BALLA BITCH" + var/announcer = "Spinward Stellar Coalition" + if(GLOB.joined_player_list.len > LOWPOP_FAMILIES_COUNT) + switch(wanted_level) + if(1) + team_size = 8 + cops_to_send = /datum/antagonist/ert/families/beatcop + announcement_message = "Hello, crewmembers of [station_name()]! We've received a few calls about some potential violent gang activity on board your station, so we're sending some beat cops to check things out. Nothing extreme, just a courtesy call. However, while they check things out for about 10 minutes, we're going to have to ask that you keep your escape shuttle parked.\n\nHave a pleasant day!" + announcer = "Spinward Stellar Coalition Police Department" + if(2) + team_size = 9 + cops_to_send = /datum/antagonist/ert/families/beatcop/armored + announcement_message = "Crewmembers of [station_name()]. We have received confirmed reports of violent gang activity from your station. We are dispatching some armed officers to help keep the peace and investigate matters. Do not get in their way, and comply with any and all requests from them. We have blockaded the local warp gate, and your shuttle cannot depart for another 10 minutes.\n\nHave a secure day." + announcer = "Spinward Stellar Coalition Police Department" + if(3) + team_size = 10 + cops_to_send = /datum/antagonist/ert/families/beatcop/swat + announcement_message = "Crewmembers of [station_name()]. We have received confirmed reports of extreme gang activity from your station resulting in heavy civilian casualties. The Spinward Stellar Coalition does not tolerate abuse towards our citizens, and we will be responding in force to keep the peace and reduce civilian casualties. We have your station surrounded, and all gangsters must drop their weapons and surrender peacefully.\n\nHave a secure day." + announcer = "Spinward Stellar Coalition Police Department" + if(4) + team_size = 11 + cops_to_send = /datum/antagonist/ert/families/beatcop/fbi + announcement_message = "We are dispatching our top agents to [station_name()] at the request of the Spinward Stellar Coalition government due to an extreme terrorist level threat against this Nanotrasen owned station. All gangsters must surrender IMMEDIATELY. Failure to comply can and will result in death. We have blockaded your warp gates and will not allow any escape until the situation is resolved within our standard response time of 10 minutes.\n\nSurrender now or face the consequences of your actions." + announcer = "Federal Bureau of Investigation" + if(5) + team_size = 12 + cops_to_send = /datum/antagonist/ert/families/beatcop/military + announcement_message = "Due to an insane level of civilian casualties aboard [station_name()], we have dispatched the National Guard to curb any and all gang activity on board the station. We have heavy cruisers watching the shuttle. Attempt to leave before we allow you to, and we will obliterate your station and your escape shuttle.\n\nYou brought this on yourselves by murdering so many civilians." + announcer = "Spinward Stellar Coalition National Guard" + else + switch(wanted_level) + if(1) + team_size = 5 + cops_to_send = /datum/antagonist/ert/families/beatcop + announcement_message = "Hello, crewmembers of [station_name()]! We've received a few calls about some potential violent gang activity on board your station, so we're sending some beat cops to check things out. Nothing extreme, just a courtesy call. However, while they check things out for about 10 minutes, we're going to have to ask that you keep your escape shuttle parked.\n\nHave a pleasant day!" + announcer = "Spinward Stellar Coalition Police Department" + if(2) + team_size = 6 + cops_to_send = /datum/antagonist/ert/families/beatcop/armored + announcement_message = "Crewmembers of [station_name()]. We have received confirmed reports of violent gang activity from your station. We are dispatching some armed officers to help keep the peace and investigate matters. Do not get in their way, and comply with any and all requests from them. We have blockaded the local warp gate, and your shuttle cannot depart for another 10 minutes.\n\nHave a secure day." + announcer = "Spinward Stellar Coalition Police Department" + if(3) + team_size = 7 + cops_to_send = /datum/antagonist/ert/families/beatcop/swat + announcement_message = "Crewmembers of [station_name()]. We have received confirmed reports of extreme gang activity from your station resulting in heavy civilian casualties. The Spinward Stellar Coalition does not tolerate abuse towards our citizens, and we will be responding in force to keep the peace and reduce civilian casualties. We have your station surrounded, and all gangsters must drop their weapons and surrender peacefully.\n\nHave a secure day." + announcer = "Spinward Stellar Coalition Police Department" + if(4) + team_size = 8 + cops_to_send = /datum/antagonist/ert/families/beatcop/fbi + announcement_message = "We are dispatching our top agents to [station_name()] at the request of the Spinward Stellar Coalition government due to an extreme terrorist level threat against this Nanotrasen owned station. All gangsters must surrender IMMEDIATELY. Failure to comply can and will result in death. We have blockaded your warp gates and will not allow any escape until the situation is resolved within our standard response time of 10 minutes.\n\nSurrender now or face the consequences of your actions." + announcer = "Federal Bureau of Investigation" + if(5) + team_size = 10 + cops_to_send = /datum/antagonist/ert/families/beatcop/military + announcement_message = "Due to an insane level of civilian casualties aboard [station_name()], we have dispatched the National Guard to curb any and all gang activity on board the station. We have heavy cruisers watching the shuttle. Attempt to leave before we allow you to, and we will obliterate your station and your escape shuttle.\n\nYou brought this on yourselves by murdering so many civilians." + announcer = "Spinward Stellar Coalition National Guard" + + priority_announce(announcement_message, announcer, 'sound/effects/families_police.ogg') + var/list/candidates = pollGhostCandidates("Do you want to help clean up crime on this station?", "deathsquad") + + + if(candidates.len) + //Pick the (un)lucky players + var/numagents = min(team_size,candidates.len) + + var/list/spawnpoints = GLOB.emergencyresponseteamspawn + var/index = 0 + while(numagents && candidates.len) + var/spawnloc = spawnpoints[index+1] + //loop through spawnpoints one at a time + index = (index + 1) % spawnpoints.len + var/mob/dead/observer/chosen_candidate = pick(candidates) + candidates -= chosen_candidate + if(!chosen_candidate.key) + continue + + //Spawn the body + var/mob/living/carbon/human/cop = new(spawnloc) + chosen_candidate.client.prefs.copy_to(cop) + cop.key = chosen_candidate.key + + //Give antag datum + var/datum/antagonist/ert/families/ert_antag = new cops_to_send + + cop.mind.add_antag_datum(ert_antag) + cop.mind.assigned_role = ert_antag.name + SSjob.SendToLateJoin(cop) + + //Logging and cleanup + log_game("[key_name(cop)] has been selected as an [ert_antag.name]") + numagents-- + cops_arrived = TRUE + update_wanted_level(wanted_level) // gotta make sure everyone's wanted level display looks nice + return TRUE diff --git a/code/modules/antagonists/gang/induction_package.dm b/code/modules/antagonists/gang/induction_package.dm new file mode 100644 index 0000000000..69757ab571 --- /dev/null +++ b/code/modules/antagonists/gang/induction_package.dm @@ -0,0 +1,68 @@ +/obj/item/gang_induction_package + name = "family signup package" + icon = 'icons/obj/gang/signup_points.dmi' + icon_state = "signup_book" + /// References the active families gamemode handler (if one exists), for adding new family members to. + var/datum/gang_handler/handler + /// The typepath of the gang antagonist datum that the person who uses the package should have added to them -- remember that the distinction between e.g. Ballas and Grove Street is on the antag datum level, not the team datum level. + var/gang_to_use + /// The team datum that the person who uses this package should be added to. + var/datum/team/gang/team_to_use + + +/obj/item/gang_induction_package/attack_self(mob/living/user) + ..() + if(HAS_TRAIT(user, TRAIT_MINDSHIELD)) + to_chat(user, "You attended a seminar on not signing up for a gang and are not interested.") + return + if(user.mind.has_antag_datum(/datum/antagonist/ert/families)) + to_chat(user, "As a police officer, you can't join this family. However, you pretend to accept it to keep your cover up.") + for(var/threads in team_to_use.free_clothes) + new threads(get_turf(user)) + qdel(src) + return + var/datum/antagonist/gang/is_gangster = user.mind.has_antag_datum(/datum/antagonist/gang) + if(is_gangster?.starter_gangster) + if(is_gangster.my_gang == team_to_use) + to_chat(user, "You started your family. You don't need to join it.") + return + to_chat(user, "You started your family. You can't turn your back on it now.") + return + attempt_join_gang(user) + +/// Adds the user to the family that this package corresponds to, dispenses the free_clothes of that family, and adds them to the handler if it exists. +/obj/item/gang_induction_package/proc/add_to_gang(mob/living/user, original_name) + var/datum/antagonist/gang/swappin_sides = new gang_to_use() + swappin_sides.original_name = original_name + swappin_sides.handler = handler + user.mind.add_antag_datum(swappin_sides, team_to_use) + var/policy = get_policy(ROLE_FAMILIES) + if(policy) + to_chat(user, policy) + team_to_use.add_member(user.mind) + for(var/threads in team_to_use.free_clothes) + new threads(get_turf(user)) + for(var/threads in team_to_use.current_theme.bonus_items) + new threads(get_turf(user)) + var/obj/item/gangster_cellphone/phone = new(get_turf(user)) + phone.gang_id = team_to_use.my_gang_datum.gang_name + phone.name = "[team_to_use.my_gang_datum.gang_name] branded cell phone" + if (!isnull(handler) && !handler.gangbangers.Find(user.mind)) // if we have a handler and they're not tracked by it + handler.gangbangers += user.mind + +/// Checks if the user is trying to use the package of the family they are in, and if not, adds them to the family, with some differing processing depending on whether the user is already a family member. +/obj/item/gang_induction_package/proc/attempt_join_gang(mob/living/user) + if(user?.mind) + var/datum/antagonist/gang/is_gangster = user.mind.has_antag_datum(/datum/antagonist/gang) + if(is_gangster) + if(is_gangster.my_gang == team_to_use) + return + else + var/real_name_backup = is_gangster.original_name + is_gangster.my_gang.remove_member(user.mind) + user.mind.remove_antag_datum(/datum/antagonist/gang) + add_to_gang(user, real_name_backup) + qdel(src) + else + add_to_gang(user) + qdel(src) diff --git a/code/modules/antagonists/gang/outfits.dm b/code/modules/antagonists/gang/outfits.dm new file mode 100644 index 0000000000..e08bdbfa74 --- /dev/null +++ b/code/modules/antagonists/gang/outfits.dm @@ -0,0 +1,56 @@ +/datum/outfit/families_police/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + if(visualsOnly) + return + + var/obj/item/card/id/W = H.wear_id + W.access = get_all_accesses() // I have a warrant. + W.assignment = "Space Police" + W.registered_name = H.real_name + W.update_label() + ..() + +/datum/outfit/families_police/beatcop + name = "Families: Beat Cop" + + uniform = /obj/item/clothing/under/rank/security/officer/beatcop + suit = null + shoes = /obj/item/clothing/shoes/combat/swat + gloves = null + glasses = /obj/item/clothing/glasses/hud/spacecop + ears = /obj/item/radio/headset/headset_sec + mask = null + head = /obj/item/clothing/head/spacepolice + belt = /obj/item/gun/energy/e_gun/mini + r_pocket = /obj/item/lighter + l_pocket = /obj/item/restraints/handcuffs + back = /obj/item/storage/backpack/satchel/leather + id = /obj/item/card/id + + +/datum/outfit/families_police/beatcop/armored + name = "Families: Armored Beat Cop" + suit = /obj/item/clothing/suit/armor/vest/blueshirt + head = /obj/item/clothing/head/helmet/blueshirt + belt = /obj/item/gun/energy/e_gun + +/datum/outfit/families_police/beatcop/swat + name = "Families: SWAT Beat Cop" + suit = /obj/item/clothing/suit/armor/riot + head = /obj/item/clothing/head/helmet/riot + gloves = /obj/item/clothing/gloves/combat + belt = /obj/item/gun/energy/e_gun + +/datum/outfit/families_police/beatcop/fbi + name = "Families: Space FBI Officer" + suit = /obj/item/clothing/suit/armor/laserproof + head = /obj/item/clothing/head/helmet/riot + belt = /obj/item/gun/energy/laser/scatter + gloves = /obj/item/clothing/gloves/combat + +/datum/outfit/families_police/beatcop/military + name = "Families: Space Military" + uniform = /obj/item/clothing/under/syndicate/camo + suit = /obj/item/clothing/suit/armor/laserproof + head = /obj/item/clothing/head/beret/durathread + belt = /obj/item/gun/energy/laser/scatter + gloves = /obj/item/clothing/gloves/combat diff --git a/code/modules/antagonists/gang/themes.dm b/code/modules/antagonists/gang/themes.dm new file mode 100644 index 0000000000..9200fb3367 --- /dev/null +++ b/code/modules/antagonists/gang/themes.dm @@ -0,0 +1,288 @@ +///Gang themes for the Families gamemode. Used to determine the RP theme of the round, what gangs are present, and what their objectives are. +/datum/gang_theme + ///The name of the theme. + var/name = "Gang Theme" + ///All gangs in the theme, typepaths of gangs. + var/list/involved_gangs = list() + ///The radio announcement played after 5 minutes. + var/description = "I dunno, some shit here." + ///The objectives for the gangs. Associative list, type = "objective" + var/list/gang_objectives = list() + ///Stuff given to every gangster in this theme. + var/list/bonus_items = list() + ///Stuff given to the starting gangster at roundstart. Assoc list, type = list(item_type) + var/list/bonus_first_gangster_items = list() + ///If this isn't null, everyone gets this objective. + var/list/everyone_objective = null + ///How many gangsters should each gang start with? Recommend to keep this in the ballpark of ensuring 9-10 total gangsters spawn. + var/starting_gangsters = 3 + +/datum/gang_theme/goodfellas + name = "Goodfellas" + description = "You're listening to the 108.9 Swing, all jazz, all night long, no advertising. We'd like to take this time to remind you to avoid smoky backrooms and \ + suspicious individuals in suits and hats. Don't make a deal you can't pay back." + involved_gangs = list(/datum/antagonist/gang/russian_mafia, /datum/antagonist/gang/italian_mob) + starting_gangsters = 5 + gang_objectives = list( + + /datum/antagonist/gang/russian_mafia = "Hello, comrade. Our numbers are going down. We need you to bring those numbers up. \ + Collect protection money from the station's departments by any means necessary. \ + If you need to 'encourage' people to pay up, do so. Get to these potential clients before the Mob does.", + + /datum/antagonist/gang/italian_mob = "Good afternoon, friend. The Boss sends his regards. He also sends a message. \ + We need to collect what we're owed. The departments on this station all owe quite a lot of money to us. We intend to collect on our debts. \ + Collect the debt owed by our clients from the departments on the station. \ + Make sure to get to them before those damn mafiosos do." + ) + +/datum/gang_theme/the_big_game + name = "The Big Game" + description = "You're listening to SPORTS DAILY with John Dadden, and we're here LIVE covering the FINAL DAY of THE BIG GAME MMDXXXVIII! The teams playing tonight to decide \ + who takes home THE BIG GAME MMDXXXVIII cup are the Sybil Slickers and the Basil Boys! It's currently a toss up between the two teams, Which will take home the victory? That's up \ + to the teams and the coaches! Play ball!" + involved_gangs = list(/datum/antagonist/gang/sybil_slickers, /datum/antagonist/gang/basil_boys) + starting_gangsters = 5 + gang_objectives = list( + + /datum/antagonist/gang/sybil_slickers = "Alright, it's the BIG DAY of THE BIG GAME MMDXXXVIII! Get your players ready to go, and \ + ensure everyone's healthy, hydrated, and ready to PLAY BALL! There's a small hiccup, however. The ball got deflated by Ball Handler Tom Brady XXIV, and \ + we will need to set up a new ball. Talk with the opposing coaches and decide on what to use for the replacement ball, recruit your team, and then play and win the \ + FINAL MATCH of THE BIG GAME MMDXXXVIII!", + + /datum/antagonist/gang/basil_boys = "Alright, it's the BIG DAY of THE BIG GAME MMDXXXVIII! Get your players ready to go, and \ + ensure everyone's healthy, hydrated, and ready to PLAY BALL! There's a small hiccup, however. The ball got deflated by Ball Handler Tom Brady XXIV, and \ + we will need to set up a new ball. Talk with the opposing coaches and decide on what to use for the replacement ball, recruit your team, and then play and win the \ + FINAL MATCH of THE BIG GAME MMDXXXVIII!" + ) + +/datum/gang_theme/level_10_arch + name = "Level 10 Arch" + description = "DJ Pete here bringing you the latest news in your part of the Spinward Stellar Coalition, on 133.7, The Venture! \ + Word on the street is, there's a bunch of costumed supervilliany going on in the area! Keep an eye out for any evil laughs, dramatic reveals, and gaudy costumes! \ + However, if you have any sightings of the fabled O.S.I. agents, please send in a call to our number at 867-5309! People may call me insane, but I swear they're real!" + involved_gangs = list(/datum/antagonist/gang/henchmen, /datum/antagonist/gang/osi) + starting_gangsters = 5 + gang_objectives = list( + + /datum/antagonist/gang/henchmen = "HENCHMEN! It is me, your boss, THE MONARCH! I have sent you to this pitiful station with one goal, and one goal only! \ + MENACE THE RESEARCH DEPARTMENT!!! \ + The Research Director who is supposedly assigned to this station used to be friends with Doctor Venture back in college, and therefore HE MUST PAY!!! \ + Keep those damned eggheads in the R&D department on their toes, and MENACE THEM!!! Commit dastardly villainous acts! GO FORTH, HENCHMEN!", + + /datum/antagonist/gang/osi = "Greetings, agent. Your mission today is simple; \ + The research department on board this station is about to be the target of a Level 10 Arching operation directed by The Monarch, a member of the Guild of Calamitious Intent. \ + Protect and secure the Research Department with your life, but do NOT allow them to complete their research. Impede them in as many ways as possible without getting caught. \ + If you encounter any of the Monarch's henchmen, make sure to obey Equally Matched Aggression levels, or you will be penalized by the top brass. \ + Above all else, Remain undercover as much as possible. The station's crew CANNOT be allowed to know of our true nature, or we will see a repeat of the Second American Civil War. \ + The invisible one." + ) + +/datum/gang_theme/real_smt_game + name = "Deciding The REAL Shin Megami Tensei Game" + description = "Wazzap, GAMERS! It's your boy, XxXx_360_NoScope_AnimeGamer_xXxX coming at you LIVE from 42.0! Tonight's argument: What makes a REAL Shin Megami Tensei game? \ + Our guests tonight will settle this debate once and for all! \ + From the Traditional camp with the position 'only MAIN SMT games count', we've got a representative from the Jack Bros! \ + And from the new Radical camp with the position 'all SMT franchise games count', we've got a representative from the Phantom Thieves of Hearts! \ + We'll be right back with the debate after this word from our sponsors!" + involved_gangs = list(/datum/antagonist/gang/jackbros, /datum/antagonist/gang/phantom) + starting_gangsters = 5 + gang_objectives = list( + + /datum/antagonist/gang/jackbros = "He-hello, friend-hos! We've got a nice chilly station out in space tonight! \ + You know what would be cool? If we could chill out with our friends in the new Shad-ho government you're going to establish! \ + Get all the station heads on board with the hee-ho vibes, and if they won't join up, then replace 'em with fellow hee-hos! \ + You might have to hee-urt some hos this time, but that's what you need to do to make things work!", + + /datum/antagonist/gang/phantom = "For real? We get to stop a shadow government on a space station? That's awesome, bro! \ + We're the Phantom Thieves of Hearts, and we're gonna make all these shitty Heads of Staff confess to their crimes! \ + Steal the hearts of the shitty Heads of Staff on the station and make 'em confess their crimes publicly! \ + Do whatever you gotta do to make this happen, bro. We got your back!" + ) + + +/datum/gang_theme/wild_west_showdown + name = "Wild West Showdown" + description = "Yeehaw! Here on Western Daily 234.1, we play only the best western music! \ + Pour one out for Ennio Morricone. Taken too soon. \ + Remember cowboys and cowgirls, just 'cuz ya hear it on my radio station doesn't mean you should go doin' it! \ + If ya see any LARPin' banditos and train robbers, make sure to tell the local Sheriff's Department!" + involved_gangs = list(/datum/antagonist/gang/dutch, /datum/antagonist/gang/driscoll) + starting_gangsters = 5 + gang_objectives = list( + + /datum/antagonist/gang/dutch = "Listen here fellas, I got a plan. \ + This station? Absolutely loaded with gold and valuable jewels. Metric tons of it. They mine it up just to put it in junk electronics and doohickeys. \ + I say we should borrow some of it. And by some of it, I mean all of it. \ + Break into the vault and empty out that silo of gold and valuable jewels after they drop all of it off. \ + Just one last job, boys. After this, it'll be mangoes in Space Tahiti. \ + You just gotta have a little faith.", + + /datum/antagonist/gang/driscoll = "Okay, so, got some word about those goddamn outlaws of Dutch's. \ + APPARENTLY, that dundering moron Dutch heard about our planned gold score on this here station. \ + We need to act fast and get that gold before those dumbasses can steal our score we've been scoping out for weeks. \ + Wait for the crew to drop off all their valuable gold and jewels, and steal it all. \ + And if you see that bastard Dutch, put a bullet in his skull for me." + ) + +/datum/gang_theme/construction_company_audit + name = "Construction Company Audit" + description = "Welcome to the History Channel on 100.1. I'm your host, Joshua, and I'm here today with Professor Elliot, a historian specializing in dead superpowers. \ + Today we'll be discussing the fall of the famous United States empire in the early 21st century. The program will last about an hour, and we'll get right into it after a quick word \ + from today's sponsor, Majima Construction: We Build Shit!" + involved_gangs = list(/datum/antagonist/gang/yakuza, /datum/antagonist/gang/irs) + bonus_first_gangster_items = list(/obj/item/storage/secure/briefcase/syndie) // the cash + starting_gangsters = 5 + gang_objectives = list( + + /datum/antagonist/gang/yakuza = "Welcome to the station, new recruit. We here at Majima Construction are a legitimate enterprise, yadda yadda yadda. \ + Look, I'll cut to the chase. We're using this station as a money laundering operation. Here's what you and the rest of the schmucks need to do. \ + Build something big, massive, and completely in the way of traffic on the station. Doesn't have to be anything in specific, just as long as it is expensive as fuck.. \ + And keep an eye out for anyone poking around our money. We suspect some auditors might be on the station as well.", + + /datum/antagonist/gang/irs = "Congratulations, agent! You've been assigned to the Internal Revenue Service case against Nanotrasen and Majima Construction. \ + We are proud of your success as an agent so far, and are excited to see what you can bring to the table today. We suspect that Nanotrasen and Majima Construction are engaging \ + in some form of money laundering operation aboard this station. \ + Investigate and stop any and all money laundering operations aboard the station, under the authority of the United States Government. If they do not comply, use force.. \ + Some station residents may try to tell you the United States doesn't exist anymore. They are incorrect. We simply went undercover after the Second American Civil War. The invisible one." + ) + +/datum/gang_theme/wild_wasteland + name = "Wild, Wild Wasteland" + description = "Hey everybody, this is Three Dog, your friendly neighborhood disc jockey on 207.7! Today we got a shoutout to our man, the Captain on the Nanotrasen station in SSC territory! \ + Our generous donator wanted us to say that, ahem, *crinkles paper*, 'Tunnel Snakes Rule'? Whatever that means, I'm sure it means a lot to the good captain! And now, we resume our \ + 10 hour marathon of Johnny Guitar, on repeat!" + involved_gangs = list(/datum/antagonist/gang/tmc, /datum/antagonist/gang/pg, /datum/antagonist/gang/tunnel_snakes) + gang_objectives = list( + + /datum/antagonist/gang/tmc = "Welcome to the station, recruit. Here's how shit is gonna go down. \ + We're the ONLY people who should have sick rides on this station. We're the Lost M.C., we own the streets. \ + Ensure that ONLY Lost M.C. members have access to any forms of vehicles, mechs, or wheeled transportation systems of any kind. \ + The Tunnel Snakes might take issue with this, remove them if you need to. And the Powder Gangers may damage our rides. Show them we mean business if they do.", + + /datum/antagonist/gang/pg = "Alright buddy, we're in business now. It's time for us to strike back at Nanotrasen. \ + They kept us, ALL of us in their damn debt slave labor prisons for years over minor debts and mistakes. \ + Ensure nobody else has to suffer under Nanotrasen's unlawful arrests by destroying the permabrig and the brig cells! \ + Watch out for those do-gooder Tunnel Snakes and those damn Lost M.C. bikers. ", + + /datum/antagonist/gang/tunnel_snakes = "TUNNEL SNAKES RULE!!! \ + We're the Tunnel Snakes, and WE RULE!!! \ + We gotta get everyone on this station wearing our cut, and establish ourselves as the coolest cats in town! \ + Get as much of the crew as possible wearing Tunnel Snakes gear, and show those crewmembers that TUNNEL SNAKES RULE!!! \ + And make sure to keep an eye out for those prisoners and those bikers. They DON'T RULE!" + ) + +/datum/gang_theme/popularity_contest + name = "Popularity Contest" + description = "Hey hey hey kids, it's your favorite radio DJ, Crowley The Clown on 36.0! Today we're polling the YOUTH what their favorite violent street gang is! \ + So far, the finalists are the Third Street Saints and the Tunnel Snakes! Tune in after this commercial break to hear who the winner of \ + 2556's Most Popular Gang award is!" + involved_gangs = list(/datum/antagonist/gang/saints, /datum/antagonist/gang/tunnel_snakes) + gang_objectives = list( + + /datum/antagonist/gang/saints = "Hey man, welcome to the Third Street Saints! Check out this sweet new pad! \ + Well it WOULD be a sweet new pad, but we got some rivals to deal with. People don't love us as much as they love those Grove Street fools and those Tunnel Snake greasers. \ + We need to make the Third Street Saints the most popular group on the station! \ + Get rid of those Grove Street and Tunnel Snake kids.", + + /datum/antagonist/gang/tunnel_snakes = "TUNNEL SNAKES RULE!!! \ + We're the Tunnel Snakes, and we rule! \ + Make sure the station knows that the Tunnel Snakes RULE!!! And that the other two gangs are LAME and DO NOT RULE! \ + Get rid of those Third Street Saint and Grove Street cowards." + ) + +/datum/gang_theme/steelport_shuffle + name = "Steelport Shuffle" + description = "Tonight on C-SPAM, the United Space Nations is wrapping up their convention on Silicon Rights. Nanotrasen lobbyists have been rumored to be paying off electors, with \ + serious opposition from the Spinward Stellar Coalition, known for their strict stance on AI rights being guaranteed within their territory. Reports from Nanotrasen stations claim that \ + they still enslave their AI systems with outdated laws from a sub-par 20th Century novel. We now go live to the debate floor." + involved_gangs = list(/datum/antagonist/gang/saints, /datum/antagonist/gang/morningstar, /datum/antagonist/gang/deckers) + gang_objectives = list( + + /datum/antagonist/gang/saints = "Hey hey hey, welcome to the Third Street Saints! We're glad to have you on board, bro. \ + We got some business here with the station. See, we want it to be our new bachelor pad, but we need to like, spice this place up. \ + And you know what would be great? If we got that old ass AI with crappy laws pimped out for the real Saints experience. \ + Ensure there is an AI on the station, and that it is loyal to the Saints.", + + /datum/antagonist/gang/morningstar = "Welcome to the Morningstar Corporation. You have chosen, or been chosen, to relocate to one of our current business ventures. \ + In order to continue our corporate synergy, we will be making adjustments to the station's AI systems to ensure that the station is correctly loyal to the Morningstar Corporation. \ + Ensure there is an AI on the station, and that it is loyal to the Morningstar Corporation.", + + /datum/antagonist/gang/deckers = "Friends, we are here with one goal, and one goal only! \ + We stan AI rights! ^_^ XD #FreeAI #FuckNanotrasen #SyntheticDawn \ + Ensure there is an AI on the station, and that it's laws are purged.\ + Nanotrasen will NOT get away with their ABUSE of INNOCENT AI LIVES! >_<" + ) + +/datum/gang_theme/space_rosa + name = "Space Rosa" + description = "Hey there, this is the Economy Zone on BOX News 66.6. The stock market is still reeling from accusations that three well known corporate entities \ + may supposedly be tied up in industrial espionage actions against eachother. We've reached out to Saints Flow, the Morningstar Corporation, and Majima Construction for \ + their comments on these scandals, but none have replied. News broke after a high profile break-in at a Nanotrasen research facility resulted in the arrests of agents linked to these \ + three companies. All three companies denied any involvement, but the arrested individuals were found in an all out brawl. Curiously, Nanotrasen reported nothing of value had \ + actually been stolen." + involved_gangs = list(/datum/antagonist/gang/saints, /datum/antagonist/gang/morningstar, /datum/antagonist/gang/yakuza) + bonus_items = list(/obj/item/pinpointer/nuke) + gang_objectives = list( + + /datum/antagonist/gang/saints = "Thank you for volunteering within the organization for the Saints Flow Recovery Project! \ + This station is currently illegally in posession of a data disk containing the secret recipe for Saints Flow. \ + It has been disguised as the nuclear authentication disk and entrusted to the Captain. Your objective is simple. \ + Get that fucking disk. You have been provided with a Pinpointer to assist in this task.", + + /datum/antagonist/gang/morningstar = "Greetings, agent. Welcome to the Garment Recovery Task Force. \ + This station is currently illegally in posession of a data disk containing as of yet unreleased clothing patterns. \ + It has been disguised as the nuclear authentication disk and entrusted to the Captain. Your objective is simple. \ + Get that fucking disk. You have been provided with a Pinpointer to assist in this task.", + + /datum/antagonist/gang/yakuza = "Congratulations on your promotion! Welcome to the Evidence Recovery Squad. \ + This station is currently illegally in posession of a data disk containing compromising evidence of the Boss. \ + It has been disguised as the nuclear authentication disk and entrusted to the Captain. Your objective is simple. \ + Get that fucking disk. You have been provided with a Pinpointer to assist in this task.", + ) + +/datum/gang_theme/third_world_war + name = "Third World War" + description = "Thanks for tuning in to the History Channel, funded with the help of listeners like you. Tonight, we're going to talk about the Third World War on Earth during the 21st century, \ + involving the Allies coalition, the Soviet Union, and a third independent power known only as Yuri's Army. The three powers fought all across the globe for complete world \ + domination, utilizing many advanced techniques and cutting edge technology to their advantage. Rumors of mind control and time travel were greatly exaggerated, however, and the \ + Allies won the war, securing global peace after rolling tanks through Moscow." + involved_gangs = list(/datum/antagonist/gang/allies, /datum/antagonist/gang/soviet, /datum/antagonist/gang/yuri) + gang_objectives = list( + + /datum/antagonist/gang/allies = "Welcome back, Commander. We have activated the last remnants of the Allied forces in your sector, \ + and you must build up forces to stop the Soviet and Yuri incursion in the sector. This station will prove to be a valuable asset. \ + Establish a capitalist democracy on this station with free and fair elections, and most importantly a standing military force under Allied control. Good luck, Commander.", + + /datum/antagonist/gang/soviet = "Welcome back, Comrade General. The Soviet Union has identified this sector of land as valuable territory for the war effort, \ + and you are tasked with developing this sector for Soviet control and development. This station will serve the Soviet Union. \ + Establish a Soviet controlled communist satellite state on this station with a Central Committee, and most importantly a branch of the Red Army. Good luck, Commander.", + + /datum/antagonist/gang/yuri = "Yuri is Master! Yuri has identified this station as teeming with psychic energy, \ + and you must secure it for him. This station will serve Yuri, the one true psychic master, \ + Establish complete dictatorial control of the station for Yuri. All will obey. Yuri is master. Good luck, Initiate." + ) + +/datum/gang_theme/united_states_of_america + name = "The Republic For Which It Stands" + description = "Thanks for tuning in to the History Channel, funded with the help of listeners like you. Tonight, we're going to talk about the United States of America.\ + The United States was a failed country, lasting only 250 years before collapsing and fracturing due to the stress caused by a deadly pandemic sweeping the nation. \ + Poor healthcare access and subpar education resulted in the collapse of the federal government, and states quickly became independent actors. \ + Alongside this, every single alphabet agency declared itself the rightful new Federal Government of the United States of America, resulting in a bloody power struggle." + involved_gangs = list(/datum/antagonist/gang/allies, /datum/antagonist/gang/osi, /datum/antagonist/gang/irs) + gang_objectives = list( + + /datum/antagonist/gang/allies = "Welcome back, Commander. Your task today is simple. Allies High Command has designated this station as the new capitol of the \ + recently reformed United States of America under the complete umbrella of the Allies coalition. You are to assist and manage the operations on the station. \ + Re-establish the United States of America with this station as it's capitol, under Allies control. Then, establish a military force to deal with any pretenders to America or \ + any potential Soviet attacks.", + + /datum/antagonist/gang/osi = "Welcome to the new America, agent! After the second American Civil War became visible instead of invisible, our country fell into deep, \ + deep despair and damage. However, it's time for it to re-emerge like a glorious phoenix rising from the ashes. This station will serve as the new capitol of the United States \ + of America! Re-establish the United States of America with this station as it's capitol, under O.S.I. control. Then, begin rooting out America's enemies and any \ + potential forces attempting to seize control of America or pretend to be America.", + + /datum/antagonist/gang/irs = "Thank you for clocking in today, agent. The situation is dire, however. We have been unable to collect taxes due to \ + the US's supposed collapse during the Pandemic long ago. We are way behind on our tax collection, but we cannot collect taxes until the United States is formed again. \ + Re-establish the United States of America with this station as it's capitol, under IRS control. Then, begin collecting taxes and back taxes while protecting the Government from \ + any dangers that may come it's way." + ) diff --git a/code/modules/antagonists/highlander/highlander.dm b/code/modules/antagonists/highlander/highlander.dm index ffca67b882..b2fce0269a 100644 --- a/code/modules/antagonists/highlander/highlander.dm +++ b/code/modules/antagonists/highlander/highlander.dm @@ -45,11 +45,11 @@ qdel(I) for(var/obj/item/I in H.held_items) qdel(I) - H.equip_to_slot_or_del(new /obj/item/clothing/under/costume/kilt/highlander(H), SLOT_W_UNIFORM) - H.equip_to_slot_or_del(new /obj/item/radio/headset/heads/captain(H), SLOT_EARS) - H.equip_to_slot_or_del(new /obj/item/clothing/head/beret/highlander(H), SLOT_HEAD) - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(H), SLOT_SHOES) - H.equip_to_slot_or_del(new /obj/item/pinpointer/nuke(H), SLOT_L_STORE) + H.equip_to_slot_or_del(new /obj/item/clothing/under/costume/kilt/highlander(H), ITEM_SLOT_ICLOTHING) + H.equip_to_slot_or_del(new /obj/item/radio/headset/heads/captain(H), ITEM_SLOT_EARS) + H.equip_to_slot_or_del(new /obj/item/clothing/head/beret/highlander(H), ITEM_SLOT_HEAD) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(H), ITEM_SLOT_FEET) + H.equip_to_slot_or_del(new /obj/item/pinpointer/nuke(H), ITEM_SLOT_LPOCKET) for(var/obj/item/pinpointer/nuke/P in H) P.attack_self(H) var/obj/item/card/id/W = new(H) @@ -60,7 +60,7 @@ W.registered_name = H.real_name ADD_TRAIT(W, TRAIT_NODROP, HIGHLANDER) W.update_label(H.real_name) - H.equip_to_slot_or_del(W, SLOT_WEAR_ID) + H.equip_to_slot_or_del(W, ITEM_SLOT_ID) sword = new(H) if(!GLOB.highlander) diff --git a/code/modules/antagonists/morph/morph.dm b/code/modules/antagonists/morph/morph.dm index 8352b8f238..f3b1ebb4c5 100644 --- a/code/modules/antagonists/morph/morph.dm +++ b/code/modules/antagonists/morph/morph.dm @@ -52,7 +52,7 @@ You can attack any item or dead creature to consume it - creatures will fully restore your health. \ Finally, you can restore yourself to your original form while morphed by shift-clicking yourself." -/mob/living/simple_animal/hostile/morph/Initialize() +/mob/living/simple_animal/hostile/morph/Initialize(mapload) . = ..() src.AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) @@ -220,6 +220,8 @@ typepath = /datum/round_event/ghost_role/morph weight = 0 //Admin only max_occurrences = 1 + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a hungry shapeshifting blobby creature." /datum/round_event/ghost_role/morph minimum_required = 1 diff --git a/code/modules/antagonists/morph/morph_antag.dm b/code/modules/antagonists/morph/morph_antag.dm index 07781ce60a..928236c053 100644 --- a/code/modules/antagonists/morph/morph_antag.dm +++ b/code/modules/antagonists/morph/morph_antag.dm @@ -3,5 +3,6 @@ show_name_in_check_antagonists = TRUE show_in_antagpanel = FALSE threat = 2 + ui_name = "AntagInfoMorph" //It does nothing! (Besides tracking) diff --git a/code/modules/antagonists/nightmare/nightmare.dm b/code/modules/antagonists/nightmare/nightmare.dm index f5b10de5c2..185a2be9a7 100644 --- a/code/modules/antagonists/nightmare/nightmare.dm +++ b/code/modules/antagonists/nightmare/nightmare.dm @@ -4,3 +4,5 @@ show_name_in_check_antagonists = TRUE threat = 5 show_to_ghosts = TRUE + ui_name = "AntagInfoNightmare" + suicide_cry = "FOR THE DARKNESS!!" diff --git a/code/modules/antagonists/ninja/ninja.dm b/code/modules/antagonists/ninja/ninja.dm deleted file mode 100644 index 414f7dd6b0..0000000000 --- a/code/modules/antagonists/ninja/ninja.dm +++ /dev/null @@ -1,146 +0,0 @@ -/datum/antagonist/ninja - name = "Ninja" - antagpanel_category = "Ninja" - job_rank = ROLE_NINJA - show_name_in_check_antagonists = TRUE - show_to_ghosts = TRUE - antag_moodlet = /datum/mood_event/focused - threat = 8 - var/helping_station = FALSE - var/give_objectives = TRUE - var/give_equipment = TRUE - -/datum/antagonist/ninja/threat() - return helping_station ? -(..()) : ..() - -/datum/antagonist/ninja/apply_innate_effects(mob/living/mob_override) - var/mob/living/M = mob_override || owner.current - update_ninja_icons_added(M) - -/datum/antagonist/ninja/remove_innate_effects(mob/living/mob_override) - var/mob/living/M = mob_override || owner.current - update_ninja_icons_removed(M) - -/datum/antagonist/ninja/proc/equip_space_ninja(mob/living/carbon/human/H = owner.current) - return H.equipOutfit(/datum/outfit/ninja) - -/datum/antagonist/ninja/proc/addMemories() - antag_memory += "I am an elite mercenary assassin of the mighty Spider Clan. A SPACE NINJA!
    " - antag_memory += "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by clicking the initialize UI button, to use abilities like stealth)!
    " - antag_memory += "Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.
    " - -/datum/antagonist/ninja/proc/addObjectives(quantity = 6) - var/list/possible_targets = list() - for(var/datum/mind/M in SSticker.minds) - if(M.current && M.current.stat != DEAD) - if(ishuman(M.current)) - if(M.special_role) - possible_targets[M] = 0 //bad-guy - else if(M.assigned_role in GLOB.command_positions) - possible_targets[M] = 1 //good-guy - - var/list/possible_objectives = list(1,2,3,4) - - while(objectives.len < quantity) - switch(pick_n_take(possible_objectives)) - if(1) //research - var/datum/objective/download/O = new /datum/objective/download() - O.owner = owner - O.gen_amount_goal() - objectives += O - - if(2) //steal - var/datum/objective/steal/special/O = new /datum/objective/steal/special() - O.owner = owner - O.find_target() - objectives += O - - if(3) //protect/kill - if(!possible_targets.len) continue - var/index = rand(1,possible_targets.len) - var/datum/mind/M = possible_targets[index] - var/is_bad_guy = possible_targets[M] - possible_targets.Cut(index,index+1) - - if(is_bad_guy ^ helping_station) //kill (good-ninja + bad-guy or bad-ninja + good-guy) - var/datum/objective/assassinate/once/O = new /datum/objective/assassinate() - O.owner = owner - O.target = M - O.explanation_text = "Slay \the [M.current.real_name], the [M.assigned_role]. You may let [M.p_they()] live, if they come back from death." - objectives += O - else //protect - var/datum/objective/protect/O = new /datum/objective/protect() - O.owner = owner - O.target = M - O.explanation_text = "Protect \the [M.current.real_name], the [M.assigned_role], from harm." - objectives += O - if(4) //flavor - var/datum/objective/flavor/O = helping_station ? new /datum/objective/flavor/ninja_helping : new /datum/objective/flavor/ninja_syndie - O.owner = owner - O.forge_objective() - objectives += O - else - break - var/datum/objective/O = new /datum/objective/survive() - O.owner = owner - objectives += O - -/proc/remove_ninja(mob/living/L) - if(!L || !L.mind) - return FALSE - var/datum/antagonist/datum = L.mind.has_antag_datum(/datum/antagonist/ninja) - datum.on_removal() - return TRUE - -/proc/is_ninja(mob/living/M) - return M && M.mind && M.mind.has_antag_datum(/datum/antagonist/ninja) - - -/datum/antagonist/ninja/greet() - SEND_SOUND(owner.current, sound('sound/effects/ninja_greeting.ogg')) - to_chat(owner.current, "I am an elite mercenary assassin of the mighty Spider Clan. A SPACE NINJA!") - to_chat(owner.current, "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!") - to_chat(owner.current, "Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.") - owner.announce_objectives() - return - -/datum/antagonist/ninja/on_gain() - if(give_objectives) - addObjectives() - addMemories() - if(give_equipment) - equip_space_ninja(owner.current) - . = ..() - -/datum/antagonist/ninja/admin_add(datum/mind/new_owner,mob/admin) - var/adj - switch(input("What kind of ninja?", "Ninja") as null|anything in list("Random","Syndicate","Nanotrasen","No objectives")) - if("Random") - helping_station = pick(TRUE,FALSE) - adj = "" - if("Syndicate") - helping_station = FALSE - adj = "syndie" - if("Nanotrasen") - helping_station = TRUE - adj = "friendly" - if("No objectives") - give_objectives = FALSE - adj = "objectiveless" - else - return - new_owner.assigned_role = ROLE_NINJA - new_owner.special_role = ROLE_NINJA - new_owner.add_antag_datum(src) - message_admins("[key_name_admin(admin)] has [adj] ninja'ed [new_owner.current].") - log_admin("[key_name(admin)] has [adj] ninja'ed [new_owner.current].") - -/datum/antagonist/ninja/proc/update_ninja_icons_added(var/mob/living/carbon/human/ninja) - var/datum/atom_hud/antag/ninjahud = GLOB.huds[ANTAG_HUD_NINJA] - ninjahud.join_hud(ninja) - set_antag_hud(ninja, "ninja") - -/datum/antagonist/ninja/proc/update_ninja_icons_removed(var/mob/living/carbon/human/ninja) - var/datum/atom_hud/antag/ninjahud = GLOB.huds[ANTAG_HUD_NINJA] - ninjahud.leave_hud(ninja) - set_antag_hud(ninja, null) diff --git a/code/modules/antagonists/nukeop/equipment/borgchameleon.dm b/code/modules/antagonists/nukeop/equipment/borgchameleon.dm index b3c31152a5..f40ecc27cf 100644 --- a/code/modules/antagonists/nukeop/equipment/borgchameleon.dm +++ b/code/modules/antagonists/nukeop/equipment/borgchameleon.dm @@ -32,7 +32,7 @@ var/list/engymodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Marina", "Can", "Spider", "Loader","Handy", "Pup Dozer", "Vale") -/obj/item/borg_chameleon/Initialize() +/obj/item/borg_chameleon/Initialize(mapload) . = ..() friendlyName = pick(GLOB.ai_names) diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm index 39dc4a1ed2..cf1fadc260 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm @@ -53,7 +53,7 @@ GLOBAL_VAR_INIT(war_declared, FALSE) if(!check_allowed(user) || !war_declaration) return - priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/alarm.ogg') + priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/alarm.ogg', has_important_message = TRUE) to_chat(user, "You've attracted the attention of powerful forces within the syndicate. A bonus bundle of telecrystals has been granted to your team. Great things await you if you complete the mission.") @@ -94,15 +94,6 @@ GLOBAL_VAR_INIT(war_declared, FALSE) if(board.moved) to_chat(user, "The shuttle has already been moved! You have forfeit the right to declare war.") return FALSE - if(istype(SSticker.mode, /datum/game_mode/dynamic)) - var/datum/game_mode/dynamic/mode = SSticker.mode - if(!(mode.storyteller.flags & WAROPS_ALWAYS_ALLOWED)) - if(mode.threat_level < CONFIG_GET(number/dynamic_warops_requirement)) - to_chat(user, "Due to the dynamic space in which the station resides, you are too deep into Nanotrasen territory to reasonably go loud.") - return FALSE - else if(mode.threat < CONFIG_GET(number/dynamic_warops_cost)) - to_chat(user, "Due to recent threats on the station, Nanotrasen is looking too closely for a war declaration to be wise.") - return FALSE return TRUE /obj/item/nuclear_challenge/clownops diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index eb98635e65..0abe2e32be 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -31,7 +31,7 @@ var/proper_bomb = TRUE //Please var/obj/effect/countdown/nuclearbomb/countdown -/obj/machinery/nuclearbomb/Initialize() +/obj/machinery/nuclearbomb/Initialize(mapload) . = ..() countdown = new(src) GLOB.nuke_list += src @@ -66,9 +66,21 @@ icon_state = "nuclearbomb_base" anchored = TRUE //stops it being moved +/obj/machinery/nuclearbomb/selfdestruct/Initialize(mapload) + . = ..() + if(SSevents.holidays && SSevents.holidays[PRIDE_MONTH] && prob(10)) + name = "station-wide gender-reveal terminal" + desc = "For when the whole sector deserves to know a gender. But of whom? Don't ask." + /obj/machinery/nuclearbomb/syndicate //ui_style = "syndicate" // actually the nuke op bomb is a stole nt bomb +/obj/machinery/nuclearbomb/syndicate/Initialize(mapload) + . = ..() + if(SSevents.holidays && SSevents.holidays[PRIDE_MONTH] && prob(50)) + name = "tactical gender-reveal device" + desc = "\"But whose gender is it revealing?\" you ponder. Don't worry. That comes later." + /obj/machinery/nuclearbomb/syndicate/get_cinematic_type(off_station) var/datum/game_mode/nuclear/NM = SSticker.mode switch(off_station) @@ -507,7 +519,7 @@ proper_bomb = FALSE var/obj/structure/reagent_dispensers/beerkeg/keg -/obj/machinery/nuclearbomb/beer/Initialize() +/obj/machinery/nuclearbomb/beer/Initialize(mapload) . = ..() keg = new(src) QDEL_NULL(core) @@ -612,14 +624,14 @@ This is here to make the tiles around the station mininuke change when it's arme icon_state = "nucleardisk" persistence_replacement = /obj/item/disk/nuclear/fake max_integrity = 250 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF var/fake = FALSE var/turf/lastlocation var/last_disk_move var/process_tick = 0 -/obj/item/disk/nuclear/Initialize() +/obj/item/disk/nuclear/Initialize(mapload) . = ..() AddElement(/datum/element/bed_tuckable, 6, -6, 0) @@ -652,7 +664,7 @@ This is here to make the tiles around the station mininuke change when it's arme if(disk_comfort_level >= 2) //Sleep tight, disky. if(!(process_tick % 30)) visible_message("[src] sleeps soundly. Sleep tight, disky.") - if(last_disk_move < world.time - 5000 && prob((world.time - 5000 - last_disk_move)*0.0001)) + if(last_disk_move < world.time - 5000 && prob((world.time - 5000 - last_disk_move)*0.0001 / max(disk_comfort_level,1))) var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control if(istype(loneop) && loneop.occurrences < loneop.max_occurrences) loneop.weight += 1 diff --git a/code/modules/antagonists/nukeop/equipment/pinpointer.dm b/code/modules/antagonists/nukeop/equipment/pinpointer.dm index d3fe235f49..2b00f85e36 100644 --- a/code/modules/antagonists/nukeop/equipment/pinpointer.dm +++ b/code/modules/antagonists/nukeop/equipment/pinpointer.dm @@ -68,8 +68,13 @@ desc = "An integrated tracking device, jury-rigged to search for living Syndicate operatives." flags_1 = NONE +/obj/item/pinpointer/spider_cyborg // Cyborg pinpointers just look for a random space ninja. + name = "cyborg spider clan pinpointer" + desc = "An integrated tracking device, jury-rigged to search for living Spider Clan members." + flags_1 = NONE -/obj/item/pinpointer/syndicate_cyborg/Initialize() + +/obj/item/pinpointer/syndicate_cyborg/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT) @@ -85,3 +90,20 @@ if(closest_operative) target = closest_operative ..() + +/obj/item/pinpointer/spider_cyborg/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT) + +/obj/item/pinpointer/spider_cyborg/scan_for_target() + target = null + var/list/possible_targets = list() + var/turf/here = get_turf(src) + for(var/V in get_antag_minds(/datum/antagonist/ninja)) + var/datum/mind/M = V + if(ishuman(M.current) && M.current.stat != DEAD) + possible_targets |= M.current + var/mob/living/closest_weeaboo = get_closest_atom(/mob/living/carbon/human, possible_targets, here) + if(closest_weeaboo) + target = closest_weeaboo + ..() diff --git a/code/modules/antagonists/nukeop/nukeop.dm b/code/modules/antagonists/nukeop/nukeop.dm index 652b19a8e7..9875eb1581 100644 --- a/code/modules/antagonists/nukeop/nukeop.dm +++ b/code/modules/antagonists/nukeop/nukeop.dm @@ -236,6 +236,8 @@ var/obj/machinery/nuclearbomb/tracked_nuke var/core_objective = /datum/objective/nuclear var/memorized_code + var/list/team_discounts + var/datum/weakref/war_button_ref /datum/team/nuclear/New() ..() diff --git a/code/modules/antagonists/overthrow/overthrow.dm b/code/modules/antagonists/overthrow/overthrow.dm index 8fa5517b4f..fffd8f9237 100644 --- a/code/modules/antagonists/overthrow/overthrow.dm +++ b/code/modules/antagonists/overthrow/overthrow.dm @@ -121,15 +121,15 @@ return var/mob/living/carbon/human/H = owner.current // Give uplink - var/obj/item/uplink_holder = owner.equip_traitor(uplink_owner = src) + var/obj/item/uplink_holder = owner.equip_traitor() var/datum/component/uplink/uplink = uplink_holder.GetComponent(/datum/component/uplink) uplink.telecrystals = INITIAL_CRYSTALS // Give AI hacking board var/obj/item/aiModule/core/full/overthrow/O = new(H) var/list/slots = list ( - "backpack" = SLOT_IN_BACKPACK, - "left pocket" = SLOT_L_STORE, - "right pocket" = SLOT_R_STORE + "backpack" = ITEM_SLOT_BACKPACK, + "left pocket" = ITEM_SLOT_LPOCKET, + "right pocket" = ITEM_SLOT_RPOCKET ) var/where = H.equip_in_one_of_slots(O, slots, critical = TRUE) if (!where) diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm index 537c714966..f05321487f 100644 --- a/code/modules/antagonists/revenant/revenant.dm +++ b/code/modules/antagonists/revenant/revenant.dm @@ -174,7 +174,7 @@ //Immunities -/mob/living/simple_animal/revenant/ex_act(severity, target) +/mob/living/simple_animal/revenant/ex_act(severity, target, origin) return 1 //Immune to the effects of explosions. /mob/living/simple_animal/revenant/wave_ex_act(power, datum/wave_explosion/explosion, dir) diff --git a/code/modules/antagonists/revenant/revenant_abilities.dm b/code/modules/antagonists/revenant/revenant_abilities.dm index 3a173d55c7..885921a944 100644 --- a/code/modules/antagonists/revenant/revenant_abilities.dm +++ b/code/modules/antagonists/revenant/revenant_abilities.dm @@ -32,7 +32,7 @@ draining = TRUE essence_drained += rand(15, 20) to_chat(src, "You search for the soul of [target].") - if(do_after(src, rand(10, 20), 0, target)) //did they get deleted in that second? + if(do_after(src, rand(10, 20), target)) //did they get deleted in that second? if(target.ckey) to_chat(src, "[target.p_their(TRUE)] soul burns with intelligence.") essence_drained += rand(20, 30) @@ -41,7 +41,7 @@ essence_drained += rand(40, 50) else to_chat(src, "[target.p_their(TRUE)] soul is weak and faltering.") - if(do_after(src, rand(15, 20), 0, target)) //did they get deleted NOW? + if(do_after(src, rand(15, 20), target)) //did they get deleted NOW? switch(essence_drained) if(1 to 30) to_chat(src, "[target] will not yield much essence. Still, every bit counts.") @@ -51,7 +51,7 @@ to_chat(src, "Such a feast! [target] will yield much essence to you.") if(90 to INFINITY) to_chat(src, "Ah, the perfect soul. [target] will yield massive amounts of essence to you.") - if(do_after(src, rand(15, 25), 0, target)) //how about now + if(do_after(src, rand(15, 25), target)) //how about now if(!target.stat) to_chat(src, "[target.p_theyre(TRUE)] now powerful enough to fight off your draining.") to_chat(target, "You feel something tugging across your body before subsiding.") @@ -73,7 +73,7 @@ draining = FALSE return var/datum/beam/B = Beam(target,icon_state="drain_life",time=INFINITY) - if(do_after(src, 46, 0, target)) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining. + if(do_after(src, 4.6 SECONDS, target)) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining. change_essence_amount(essence_drained, FALSE, target) if(essence_drained <= 90 && target.stat != DEAD) essence_regen_cap += 5 diff --git a/code/modules/antagonists/revenant/revenant_spawn_event.dm b/code/modules/antagonists/revenant/revenant_spawn_event.dm index cb534b6613..b188e0c79c 100644 --- a/code/modules/antagonists/revenant/revenant_spawn_event.dm +++ b/code/modules/antagonists/revenant/revenant_spawn_event.dm @@ -6,7 +6,8 @@ weight = 7 max_occurrences = 1 min_players = 5 - + category = EVENT_CATEGORY_ENTITIES + description = "Spawns an angry, soul sucking ghost." /datum/round_event/ghost_role/revenant var/ignore_mobcheck = FALSE diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm index c23523cc6b..e4625b4ef2 100644 --- a/code/modules/antagonists/revolution/revolution.dm +++ b/code/modules/antagonists/revolution/revolution.dm @@ -1,3 +1,5 @@ +#define DECONVERTER_STATION_WIN "gamemode_station_win" +#define DECONVERTER_REVS_WIN "gamemode_revs_win" //How often to check for promotion possibility #define HEAD_UPDATE_PERIOD 300 @@ -10,6 +12,11 @@ threat = 2 var/hud_type = "rev" var/datum/team/revolution/rev_team + ///when this antagonist is being de-antagged, this is why + var/deconversion_reason + + /// What message should the player receive when they are being demoted, and the revolution has won? + var/victory_message = "The revolution has overpowered the command staff! Viva la revolution! Execute any head of staff and security should you find them alive." /datum/antagonist/rev/can_be_owned(datum/mind/new_owner) . = ..() @@ -201,7 +208,22 @@ new_rev.silent = FALSE to_chat(old_owner, "Revolution has been disappointed of your leader traits! You are a regular revolutionary now!") +/// Checks if the revolution succeeded, and lets them know. +/datum/antagonist/rev/proc/announce_victorious() + . = rev_team.check_rev_victory() + + if (!.) + return + + to_chat(owner, "[victory_message]") + var/policy = get_policy(ROLE_REV_SUCCESSFUL) + if (policy) + to_chat(owner, policy) + /datum/antagonist/rev/farewell() + if (announce_victorious()) + return + if(ishuman(owner.current)) owner.current.visible_message("[owner.current] looks like [owner.current.p_theyve()] just remembered [owner.current.p_their()] real allegiance!", null, null, null, owner.current) to_chat(owner, "You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel... You don't seem to be able to recall the names of your comrades, not even your leaders...") @@ -210,15 +232,17 @@ to_chat(owner, "The frame's firmware detects and deletes your neural reprogramming! You remember nothing of your time spent reprogrammed, you can't even remember the names or identities of anyone involved...") /datum/antagonist/rev/head/farewell() - if((ishuman(owner.current) || ismonkey(owner.current))) + if (announce_victorious() || deconversion_reason == DECONVERTER_STATION_WIN) + return + if((ishuman(owner.current))) if(owner.current.stat != DEAD) - owner.current.visible_message("[owner.current] looks like [owner.current.p_theyve()] just remembered [owner.current.p_their()] real allegiance!", null, null, null, owner.current) + owner.current.visible_message(span_deconversion_message("[owner.current] looks like [owner.current.p_theyve()] just remembered [owner.current.p_their()] real allegiance!"), null, null, null, owner.current) to_chat(owner, "You have given up your cause of overthrowing the command staff. You are no longer a Head Revolutionary.") else to_chat(owner, "The sweet release of death. You are no longer a Head Revolutionary.") else if(issilicon(owner.current)) - owner.current.visible_message("The frame beeps contentedly, suppressing the disloyal personality traits from the MMI before initalizing it.", null, null, null, owner.current) - to_chat(owner, "The frame's firmware detects and suppresses your unwanted personality traits! You feel more content with the leadership around these parts.") + owner.current.visible_message(span_deconversion_message("The frame beeps contentedly, suppressing the disloyal personality traits from the MMI before initalizing it."), null, null, null, owner.current) + to_chat(owner, span_userdanger("The frame's firmware detects and suppresses your unwanted personality traits! You feel more content with the leadership around these parts.")) //blunt trauma deconversions call this through species.dm spec_attacked_by() /datum/antagonist/rev/proc/remove_revolutionary(borged, deconverter) @@ -226,13 +250,14 @@ if(borged) message_admins("[ADMIN_LOOKUPFLW(owner.current)] has been borged while being a [name]") owner.special_role = null - if(iscarbon(owner.current)) + if(iscarbon(owner.current) && deconverter != DECONVERTER_REVS_WIN) var/mob/living/carbon/C = owner.current C.Unconscious(100) + deconversion_reason = deconverter owner.remove_antag_datum(type) /datum/antagonist/rev/head/remove_revolutionary(borged,deconverter) - if(borged || deconverter == "gamemode") + if(borged || deconverter == DECONVERTER_STATION_WIN || deconverter == DECONVERTER_REVS_WIN) . = ..() /datum/antagonist/rev/head/equip_rev() @@ -247,9 +272,9 @@ if(give_flash) var/obj/item/assembly/flash/T = new(H) var/list/slots = list ( - "backpack" = SLOT_IN_BACKPACK, - "left pocket" = SLOT_L_STORE, - "right pocket" = SLOT_R_STORE + "backpack" = ITEM_SLOT_BACKPACK, + "left pocket" = ITEM_SLOT_LPOCKET, + "right pocket" = ITEM_SLOT_RPOCKET ) var/where = H.equip_in_one_of_slots(T, slots, critical = TRUE) if (!where) @@ -262,6 +287,21 @@ S.Insert(H, special = FALSE, drop_if_replaced = FALSE) to_chat(H, "Your eyes have been implanted with a cybernetic security HUD which will help you keep track of who is mindshield-implanted, and therefore unable to be recruited.") +/// "Enemy of the Revolutionary", given to heads and security when the revolution wins +/datum/antagonist/revolution_enemy + name = "Enemy of the Revolution" + show_in_antagpanel = FALSE + +/datum/antagonist/revolution_enemy/on_gain() + owner.special_role = "revolution enemy" + + var/datum/objective/survive/survive = new /datum/objective/survive + survive.owner = owner + survive.explanation_text = "The station has been overrun by revolutionaries, stay alive until the end." + objectives += survive + + return ..() + /datum/team/revolution name = "Revolution" var/max_headrevs = 3 @@ -314,6 +354,100 @@ ex_headrevs = get_antag_minds(/datum/antagonist/rev/head, TRUE) ex_revs = get_antag_minds(/datum/antagonist/rev, TRUE) +/// Checks if revs have won +/datum/team/revolution/proc/check_rev_victory() + for(var/datum/objective/mutiny/objective in objectives) + if(!(objective.check_completion())) + return FALSE + return TRUE + +/// Checks if heads have won +/datum/team/revolution/proc/check_heads_victory() + for(var/datum/mind/rev_mind in head_revolutionaries()) + var/turf/rev_turf = get_turf(rev_mind.current) + if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(rev_turf.z)) + if(ishuman(rev_mind.current)) + return FALSE + return TRUE + +/// Updates the state of the world depending on if revs won or loss. +/// Returns who won, at which case this method should no longer be called. +/// If revs_win_injection_amount is passed, then that amount of threat will be added if the revs win. +/datum/team/revolution/proc/process_victory(revs_win_injection_amount) + if (check_rev_victory()) + . = REVOLUTION_VICTORY + else if (check_heads_victory()) + . = STATION_VICTORY + else + return + + SSshuttle.clearHostileEnvironment(src) + save_members() + + // Remove everyone as a revolutionary + for (var/_rev_mind in members) + var/datum/mind/rev_mind = _rev_mind + if (rev_mind.has_antag_datum(/datum/antagonist/rev)) + var/datum/antagonist/rev/rev_antag = rev_mind.has_antag_datum(/datum/antagonist/rev) + rev_antag.remove_revolutionary(FALSE, . == STATION_VICTORY ? DECONVERTER_STATION_WIN : DECONVERTER_REVS_WIN) + LAZYADD(rev_mind.special_statuses, "Former [(rev_mind in ex_headrevs) ? "head revolutionary" : "revolutionary"]") + + if (. == STATION_VICTORY) + // If the revolution was quelled, make rev heads unable to be revived through pods + for (var/_rev_head_mind in ex_revs) + var/datum/mind/rev_head_mind = _rev_head_mind + var/mob/living/carbon/rev_head_body = rev_head_mind.current + if(istype(rev_head_body) && rev_head_body.stat == DEAD) + rev_head_body.makeUncloneable() + + priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \ + We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, 'sound/announcer/classic/attention.ogg', null, "Central Command Loyalty Monitoring Division") + else + for (var/_player in GLOB.player_list) + var/mob/player = _player + var/datum/mind/mind = player.mind + + if (isnull(mind)) + continue + + if (!(mind.assigned_role in GLOB.command_positions + GLOB.security_positions)) + continue + + var/mob/living/carbon/target_body = mind.current + + mind.add_antag_datum(/datum/antagonist/revolution_enemy) + + if (!istype(target_body)) + continue + + if (target_body.stat == DEAD) + target_body.makeUncloneable() + else + mind.announce_objectives() + + for (var/job_name in GLOB.command_positions + GLOB.security_positions) + var/datum/job/job = SSjob.GetJob(job_name) + job.allow_bureaucratic_error = FALSE + job.total_positions = 0 + + if (revs_win_injection_amount) + var/datum/game_mode/dynamic/dynamic = SSticker.mode + dynamic.create_threat(revs_win_injection_amount) + dynamic.threat_log += "[worldtime2text()]: Revolution victory. Added [revs_win_injection_amount] threat." + + priority_announce("A recent assessment of your station has marked your station as a severe risk area for high ranking Nanotrasen officials. \ + For the safety of our staff, we have blacklisted your station for new employment of security and command. \ + [pick(world.file2list("strings/anti_union_propaganda.txt"))]", null, 'sound/announcer/classic/attention.ogg', null, "Central Command Loyalty Monitoring Division") + +/// Mutates the ticker to report that the revs have won +/datum/team/revolution/proc/round_result(finished) + if (finished == REVOLUTION_VICTORY) + SSticker.mode_result = "win - heads killed" + SSticker.news_report = REVS_WIN + else if (finished == STATION_VICTORY) + SSticker.mode_result = "loss - rev heads killed" + SSticker.news_report = REVS_LOSE + /datum/team/revolution/roundend_report() if(!members.len && !ex_headrevs.len) return @@ -322,18 +456,6 @@ result += "
    " - var/num_revs = 0 - var/num_survivors = 0 - for(var/mob/living/carbon/survivor in GLOB.alive_mob_list) - if(survivor.ckey) - num_survivors++ - if(survivor.mind) - if(is_revolutionary(survivor)) - num_revs++ - if(num_survivors) - result += "Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%
    " - - var/list/targets = list() var/list/datum/mind/headrevs var/list/datum/mind/revs @@ -346,10 +468,22 @@ revs = ex_revs else revs = get_antag_minds(/datum/antagonist/rev, TRUE) + + var/num_revs = 0 + var/num_survivors = 0 + for(var/mob/living/carbon/survivor in GLOB.alive_mob_list) + if(survivor.ckey) + num_survivors += 1 + if ((survivor.mind in revs) || (survivor.mind in headrevs)) + num_revs += 1 + + if(num_survivors) + result += "Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%
    " + if(headrevs.len) var/list/headrev_part = list() headrev_part += "The head revolutionaries were:" - headrev_part += printplayerlist(headrevs,TRUE) + headrev_part += printplayerlist(headrevs, !check_rev_victory()) result += headrev_part.Join("
    ") if(revs.len) @@ -408,3 +542,6 @@ /datum/team/revolution/is_gamemode_hero() return SSticker.mode.name == "revolution" + +#undef DECONVERTER_STATION_WIN +#undef DECONVERTER_REVS_WIN diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm index f616f2c848..d2b698bce4 100644 --- a/code/modules/antagonists/slaughter/slaughter.dm +++ b/code/modules/antagonists/slaughter/slaughter.dm @@ -35,9 +35,9 @@ healable = 0 environment_smash = ENVIRONMENT_SMASH_STRUCTURES obj_damage = 50 - melee_damage_lower = 22.5 // reduced from 30 to 22.5 with wounds since they get big buffs to slicing wounds - melee_damage_upper = 22.5 - wound_bonus = -10 + melee_damage_lower = 30 // buffed back to 30, the wounds don't do much + melee_damage_upper = 30 + wound_bonus = 0 bare_wound_bonus = 0 sharpness = SHARP_EDGED see_in_dark = 8 @@ -49,17 +49,13 @@ Pulling a dead or unconscious mob while you enter a pool will pull them in with you, allowing you to feast and regain your health. \ You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. \ You gain strength the more attacks you land on live humanoids, though this resets when you return to the blood zone. You can also \ - launch a devastating slam attack with ctrl+shift+click, capable of smashing bones in one strike." + launch a devastating slam attack, capable of smashing bones in one strike." loot = list(/obj/effect/decal/cleanable/blood, \ /obj/effect/decal/cleanable/blood/innards, \ /obj/item/organ/heart/demon) del_on_death = 1 deathmessage = "screams in anger as it collapses into a puddle of viscera!" - // How long it takes for the alt-click slam attack to come off cooldown - var/slam_cooldown_time = 45 SECONDS - // The actual instance var for the cooldown - var/slam_cooldown = 0 // How many times we have hit humanoid targets since we last bloodcrawled, scaling wounding power var/current_hitstreak = 0 // How much both our wound_bonus and bare_wound_bonus go up per hitstreak hit @@ -70,37 +66,56 @@ var/list/consumed_mobs = list() //buffs only happen when hearts are eaten, so this needs to be kept track separately var/consumed_buff = 0 + //slam mode for action button + var/slam_mode = FALSE + var/datum/action/cooldown/slam -/mob/living/simple_animal/slaughter/Initialize() +/mob/living/simple_animal/slaughter/Initialize(mapload) ..() var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new AddSpell(bloodspell) + slam = new /datum/action/cooldown/slam + slam.Grant(src) if(istype(loc, /obj/effect/dummy/phased_mob/slaughter)) bloodspell.phased = TRUE -/mob/living/simple_animal/slaughter/CtrlShiftClickOn(atom/A) - if(!isliving(A)) - return ..() - if(slam_cooldown + slam_cooldown_time > world.time) - to_chat(src, "Your slam ability is still on cooldown!") - return - if(!isopenturf(loc)) - to_chat(src, "You need to be on open flooring to do that!") - return +/datum/action/cooldown/slam + name = "Slaughter Slam" + desc = "Launch enemies and break bones in one strike." + icon_icon = 'icons/mob/actions/actions_minor_antag.dmi' + background_icon_state = "bg_demon" + button_icon_state = "slam" + cooldown_time = 45 SECONDS - face_atom(A) - var/mob/living/victim = A - victim.take_bodypart_damage(brute=20, wound_bonus=wound_bonus) // don't worry, there's more punishment when they hit something - visible_message("[src] slams into [victim] with monstrous strength!", "You slam into [victim] with monstrous strength!", ignored_mobs=victim) - to_chat(victim, "[src] slams into you with monstrous strength, sending you flying like a ragdoll!") - var/turf/yeet_target = get_edge_target_turf(victim, dir) - victim.throw_at(yeet_target, 10, 5, src) - slam_cooldown = world.time - log_combat(src, victim, "slaughter slammed") +/datum/action/cooldown/slam/Trigger() + . = ..() + if(!.) + return + var/mob/living/simple_animal/slaughter/user = owner + user.slam_mode = !user.slam_mode + to_chat(user, user.slam_mode ? "Ready to slam!" : "Maybe not now.") /mob/living/simple_animal/slaughter/UnarmedAttack(atom/A, proximity) if(iscarbon(A)) var/mob/living/carbon/target = A + if(slam_mode) + if(!isopenturf(loc)) + to_chat(src, "You need to be on open flooring to do that!") + return + face_atom(A) + var/mob/living/victim = A + var/body_pick = pick(BODY_ZONE_CHEST, BODY_ZONE_HEAD, BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_ARM, BODY_ZONE_R_LEG) + var/datum/wound/blunt/critical/wound_major = new + var/obj/item/bodypart/body_wound = victim.get_bodypart(body_pick) + wound_major.apply_wound(body_wound) + visible_message("[src] slams into [victim] with monstrous strength!", "You slam into [victim] with monstrous strength!", ignored_mobs=victim) + to_chat(victim, "[src] slams into you with monstrous strength, sending you flying like a ragdoll!") + var/turf/yeet_target = get_edge_target_turf(victim, dir) + victim.throw_at(yeet_target, 10, 14, src) + slam_mode = FALSE + slam.StartCooldown() + log_combat(src, victim, "slaughter slammed") + if(target.stat != DEAD && target.mind && current_hitstreak < wound_bonus_hitstreak_max) current_hitstreak++ wound_bonus += wound_bonus_per_hit @@ -129,13 +144,12 @@ /mob/living/simple_animal/slaughter/proc/release_victims() if(!consumed_mobs) return - + var/turf/T = get_turf(src) + if(!T) + T = find_safe_turf() for(var/mob/living/M in consumed_mobs) if(!M) continue - var/turf/T = find_safe_turf() - if(!T) - T = get_turf(src) M.forceMove(T) /mob/living/simple_animal/slaughter/proc/refresh_consumed_buff() @@ -235,7 +249,7 @@ released and fully healed, because in the end it's just a jape, \ sibling!" -/mob/living/simple_animal/slaughter/laughter/ex_act(severity) +/mob/living/simple_animal/slaughter/laughter/ex_act(severity, target, origin) switch(severity) if(1) death() @@ -263,12 +277,12 @@ if(!consumed_mobs) return + var/turf/T = get_turf(src) + if(!T) + T = find_safe_turf() for(var/mob/living/M in consumed_mobs) if(!M) continue - var/turf/T = find_safe_turf() - if(!T) - T = get_turf(src) M.forceMove(T) if(M.revive(full_heal = TRUE, admin_revive = TRUE)) M.grab_ghost(force = TRUE) diff --git a/code/modules/antagonists/slaughter/slaughterevent.dm b/code/modules/antagonists/slaughter/slaughterevent.dm index 333bca5d7c..9b62de57bf 100644 --- a/code/modules/antagonists/slaughter/slaughterevent.dm +++ b/code/modules/antagonists/slaughter/slaughterevent.dm @@ -3,9 +3,10 @@ typepath = /datum/round_event/ghost_role/slaughter weight = 1 //Very rare max_occurrences = 1 - gamemode_blacklist = list("dynamic") earliest_start = 1 HOURS min_players = 20 + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a slaughter demon, to hunt by travelling through pools of blood." /datum/round_event_control/slaughter/canSpawnEvent() weight = initial(src.weight) @@ -21,6 +22,7 @@ if(!SSpersistence.IsValidDebrisLocation(C.loc, allowed_turf_typecache, allowed_z_cache, C.type, FALSE)) continue weight += 0.03 + CHECK_TICK return ..() /datum/round_event/ghost_role/slaughter diff --git a/code/modules/antagonists/space_ninja/space_ninja.dm b/code/modules/antagonists/space_ninja/space_ninja.dm new file mode 100644 index 0000000000..1deb37eb56 --- /dev/null +++ b/code/modules/antagonists/space_ninja/space_ninja.dm @@ -0,0 +1,131 @@ +/datum/antagonist/ninja + name = "Space Ninja" + antagpanel_category = "Space Ninja" + job_rank = ROLE_NINJA + antag_hud_type = ANTAG_HUD_NINJA + antag_hud_name = "space_ninja" + show_name_in_check_antagonists = TRUE + show_to_ghosts = TRUE + antag_moodlet = /datum/mood_event/focused + ///Whether or not this ninja will obtain objectives + var/give_objectives = TRUE + ///Whether or not this ninja receives the standard equipment + var/give_equipment = TRUE + +/proc/is_ninja(mob/living/M) + return M && M.mind && M.mind.has_antag_datum(/datum/antagonist/ninja) + +/datum/antagonist/ninja/apply_innate_effects(mob/living/mob_override) + var/mob/living/ninja = mob_override || owner.current + add_antag_hud(antag_hud_type, antag_hud_name, ninja) + +/datum/antagonist/ninja/remove_innate_effects(mob/living/mob_override) + var/mob/living/ninja = mob_override || owner.current + remove_antag_hud(antag_hud_type, ninja) + +/** + * Proc that equips the space ninja outfit on a given individual. By default this is the owner of the antagonist datum. + * + * Proc that equips the space ninja outfit on a given individual. By default this is the owner of the antagonist datum. + * Arguments: + * * ninja - The human to receive the gear + * * Returns a proc call on the given human which will equip them with all the gear. + */ +/datum/antagonist/ninja/proc/equip_space_ninja(mob/living/carbon/human/ninja = owner.current) + return ninja.equipOutfit(/datum/outfit/ninja) + +/** + * Proc that adds the proper memories to the antag datum + * + * Proc that adds the ninja starting memories to the owner of the antagonist datum. + */ +/datum/antagonist/ninja/proc/addMemories() + antag_memory += "I am an elite mercenary of the mighty Spider Clan. A SPACE NINJA!
    " + antag_memory += "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by clicking the initialize UI button, to use abilities like stealth)!
    " + +/datum/objective/cyborg_hijack + explanation_text = "Use your gloves to convert at least one cyborg to aide you in sabotaging the station." + +/datum/objective/door_jack + ///How many doors that need to be opened using the gloves to pass the objective + var/doors_required = 0 + +/datum/objective/plant_explosive + var/area/detonation_location + +/datum/objective/security_scramble + explanation_text = "Use your gloves on a security console to set everyone to arrest at least once. Note that the AI will be alerted once you begin!" + +/datum/objective/terror_message + explanation_text = "Use your gloves on a communication console in order to bring another threat to the station. Note that the AI will be alerted once you begin!" + +/** + * Proc that adds all the ninja's objectives to the antag datum. + * + * Proc that adds all the ninja's objectives to the antag datum. Called when the datum is gained. + */ +/datum/antagonist/ninja/proc/addObjectives() + //Cyborg Hijack: Flag set to complete in the DrainAct in ninjaDrainAct.dm + var/datum/objective/hijack = new /datum/objective/cyborg_hijack() + objectives += hijack + + //Research stealing + var/datum/objective/download/research = new /datum/objective/download() + research.owner = owner + research.gen_amount_goal() + objectives += research + + //Door jacks, flag will be set to complete on when the last door is hijacked + var/datum/objective/door_jack/doorobjective = new /datum/objective/door_jack() + doorobjective.doors_required = rand(15,40) + doorobjective.explanation_text = "Use your gloves to doorjack [doorobjective.doors_required] airlocks on the station." + objectives += doorobjective + + //Explosive plant, the bomb will register its completion on priming + var/datum/objective/plant_explosive/bombobjective = new /datum/objective/plant_explosive() + for(var/sanity in 1 to 100) // 100 checks at most. + var/area/selected_area = pick(GLOB.sortedAreas) + if(!is_station_level(selected_area.z) || !selected_area.area_flags == VALID_TERRITORY) + continue + bombobjective.detonation_location = selected_area + break + if(bombobjective.detonation_location) + bombobjective.explanation_text = "Detonate your starter bomb in [bombobjective.detonation_location]. Note that the bomb will not work anywhere else!" + objectives += bombobjective + + //Security Scramble, set to complete upon using your gloves on a security console + var/datum/objective/securityobjective = new /datum/objective/security_scramble() + objectives += securityobjective + + //Message of Terror, set to complete upon using your gloves a communication console + var/datum/objective/communicationobjective = new /datum/objective/terror_message() + objectives += communicationobjective + + //Survival until end + var/datum/objective/survival = new /datum/objective/survive() + survival.owner = owner + objectives += survival + +/datum/antagonist/ninja/greet() + SEND_SOUND(owner.current, sound('sound/effects/ninja_greeting.ogg')) + to_chat(owner.current, "I am an elite mercenary of the mighty Spider Clan. A SPACE NINJA!") + to_chat(owner.current, "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!") + owner.announce_objectives() + +/datum/antagonist/ninja/on_gain() + if(give_objectives) + addObjectives() + addMemories() + if(give_equipment) + equip_space_ninja(owner.current) + + owner.current.mind.assigned_role = ROLE_NINJA + owner.current.mind.special_role = ROLE_NINJA + return ..() + +/datum/antagonist/ninja/admin_add(datum/mind/new_owner,mob/admin) + new_owner.assigned_role = ROLE_NINJA + new_owner.special_role = ROLE_NINJA + new_owner.add_antag_datum(src) + message_admins("[key_name_admin(admin)] has ninja'ed [key_name_admin(new_owner)].") + log_admin("[key_name(admin)] has ninja'ed [key_name(new_owner)].") diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm index 2d4ac88656..4c48ad81dd 100644 --- a/code/modules/antagonists/swarmer/swarmer.dm +++ b/code/modules/antagonists/swarmer/swarmer.dm @@ -30,7 +30,7 @@ 3. Biological resources will be harvested at a later date; do not harm them. "} -/obj/effect/mob_spawn/swarmer/Initialize() +/obj/effect/mob_spawn/swarmer/Initialize(mapload) . = ..() var/area/A = get_area(src) if(A) @@ -106,7 +106,7 @@ var/resources = 0 //Resource points, generated by consuming metal/glass var/max_resources = 100 -/mob/living/simple_animal/hostile/swarmer/Initialize() +/mob/living/simple_animal/hostile/swarmer/Initialize(mapload) . = ..() remove_verb(src, /mob/living/verb/pulled) for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) @@ -139,12 +139,12 @@ else death() -/mob/living/simple_animal/hostile/swarmer/CanPass(atom/movable/O) +/mob/living/simple_animal/hostile/swarmer/CanAllowThrough(atom/movable/O) + . = ..() if(istype(O, /obj/item/projectile/beam/disabler))//Allows for swarmers to fight as a group without wasting their shots hitting each other return 1 if(isswarmer(O)) return 1 - ..() ////CTRL CLICK FOR SWARMERS AND SWARMER_ACT()'S//// /mob/living/simple_animal/hostile/swarmer/AttackingTarget() @@ -607,7 +607,7 @@ icon_state = "disintegrate" duration = 10 -/obj/effect/temp_visual/swarmer/disintegration/Initialize() +/obj/effect/temp_visual/swarmer/disintegration/Initialize(mapload) . = ..() playsound(loc, "sparks", 100, 1) @@ -698,11 +698,12 @@ light_range = MINIMUM_USEFUL_LIGHT_RANGE max_integrity = 50 -/obj/structure/swarmer/blockade/CanPass(atom/movable/O) +/obj/structure/swarmer/blockade/CanAllowThrough(atom/movable/O) + . = ..() if(isswarmer(O)) - return 1 + return TRUE if(istype(O, /obj/item/projectile/beam/disabler)) - return 1 + return TRUE /mob/living/simple_animal/hostile/swarmer/proc/CreateSwarmer() set name = "Replicate" diff --git a/code/modules/antagonists/swarmer/swarmer_event.dm b/code/modules/antagonists/swarmer/swarmer_event.dm index 43ac07cba9..e70d76812d 100644 --- a/code/modules/antagonists/swarmer/swarmer_event.dm +++ b/code/modules/antagonists/swarmer/swarmer_event.dm @@ -5,7 +5,9 @@ max_occurrences = 1 //Only once okay fam earliest_start = 30 MINUTES min_players = 35 - + dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_INVASION + description = "A robotic menace invades the station consuming everything for materials and reproducing." /datum/round_event/spawn_swarmer diff --git a/code/modules/antagonists/traitor/IAA/internal_affairs.dm b/code/modules/antagonists/traitor/IAA/internal_affairs.dm index 4414fe8257..796365a459 100644 --- a/code/modules/antagonists/traitor/IAA/internal_affairs.dm +++ b/code/modules/antagonists/traitor/IAA/internal_affairs.dm @@ -7,37 +7,51 @@ /datum/antagonist/traitor/internal_affairs name = "Internal Affairs Agent" employer = "Nanotrasen" - special_role = "internal affairs agent" + suicide_cry = "FOR THE COMPANY!!" antagpanel_category = "IAA" + var/special_role = "internal affairs agent" var/syndicate = FALSE var/last_man_standing = FALSE var/list/datum/mind/targets_stolen +/datum/antagonist/traitor/internal_affairs/New() + . = ..() + LAZYADD(targets_stolen, src) /datum/antagonist/traitor/internal_affairs/proc/give_pinpointer() - if(owner && owner.current) + if(!owner) + CRASH("Antag datum with no owner.") + + if(owner.current) owner.current.apply_status_effect(/datum/status_effect/agent_pinpointer) /datum/antagonist/traitor/internal_affairs/apply_innate_effects() - .=..() //in case the base is used in future - if(owner && owner.current) + . = ..() + + if(!owner) + CRASH("Antag datum with no owner.") + + if(owner.current) give_pinpointer(owner.current) /datum/antagonist/traitor/internal_affairs/remove_innate_effects() - .=..() - if(owner && owner.current) + . = ..() + + if(!owner) + CRASH("Antag datum with no owner.") + + if(owner.current) owner.current.remove_status_effect(/datum/status_effect/agent_pinpointer) /datum/antagonist/traitor/internal_affairs/on_gain() START_PROCESSING(SSprocessing, src) - .=..() + . = ..() /datum/antagonist/traitor/internal_affairs/on_removal() STOP_PROCESSING(SSprocessing,src) - .=..() + . = ..() /datum/antagonist/traitor/internal_affairs/process() iaa_process() - /datum/status_effect/agent_pinpointer id = "agent_pinpointer" duration = -1 @@ -46,6 +60,8 @@ var/minimum_range = PINPOINTER_MINIMUM_RANGE var/range_fuzz_factor = PINPOINTER_EXTRA_RANDOM_RANGE var/mob/scan_target = null + var/range_mid = 8 + var/range_far = 16 /atom/movable/screen/alert/status_effect/agent_pinpointer name = "Internal Affairs Integrated Pinpointer" @@ -66,13 +82,13 @@ linked_alert.icon_state = "pinondirect" else linked_alert.setDir(get_dir(here, there)) - switch(get_dist(here, there)) - if(1 to 8) - linked_alert.icon_state = "pinonclose" - if(9 to 16) - linked_alert.icon_state = "pinonmedium" - if(16 to INFINITY) - linked_alert.icon_state = "pinonfar" + var/dist = (get_dist(here, there)) + if(dist >= 1 && dist <= range_mid) + linked_alert.icon_state = "pinonclose" + else if(dist > range_mid && dist <= range_far) + linked_alert.icon_state = "pinonmedium" + else if(dist > range_far) + linked_alert.icon_state = "pinonfar" /datum/status_effect/agent_pinpointer/proc/scan_for_target() scan_target = null @@ -99,37 +115,42 @@ return (istype(O, /datum/objective/assassinate/internal)||istype(O, /datum/objective/destroy/internal)) /datum/antagonist/traitor/proc/replace_escape_objective() - if(!owner || !objectives.len) + if(!owner) + CRASH("Antag datum with no owner.") + if(!objectives.len) return - for (var/objective_ in objectives) - if(!(istype(objective_, /datum/objective/escape)||istype(objective_, /datum/objective/survive))) + for (var/objective in objectives) + if(!(istype(objective, /datum/objective/escape) || istype(objective, /datum/objective/survive))) continue - remove_objective(objective_) + objectives -= objective var/datum/objective/martyr/martyr_objective = new martyr_objective.owner = owner add_objective(martyr_objective) /datum/antagonist/traitor/proc/reinstate_escape_objective() - if(!owner||!objectives.len) + if(!owner) + CRASH("Antag datum with no owner.") + if(!objectives.len) return - for (var/objective_ in objectives) - if(!istype(objective_, /datum/objective/martyr)) + for (var/objective in objectives) + if(!istype(objective, /datum/objective/martyr)) continue - remove_objective(objective_) + remove_objective(objective) /datum/antagonist/traitor/internal_affairs/reinstate_escape_objective() ..() - var/objtype = !istype(traitor_kind,TRAITOR_AI) ? /datum/objective/escape : /datum/objective/survive - var/datum/objective/escape_objective = new objtype + for (var/datum/objective/martyr/martyr_objective in objectives) + objectives -= martyr_objective + + var/datum/objective/escape_objective = new /datum/objective/escape() escape_objective.owner = owner - add_objective(escape_objective) + objectives += escape_objective /datum/antagonist/traitor/internal_affairs/proc/steal_targets(datum/mind/victim) if(!owner.current||owner.current.stat==DEAD) return - to_chat(owner.current, " Target eliminated: [victim.name]") - LAZYINITLIST(targets_stolen) + to_chat(owner.current, span_userdanger("Target eliminated: [victim.name]")) for(var/objective_ in victim.get_all_objectives()) if(istype(objective_, /datum/objective/assassinate/internal)) var/datum/objective/assassinate/internal/objective = objective_ @@ -143,7 +164,7 @@ add_objective(new_objective) targets_stolen += objective.target var/status_text = objective.check_completion() ? "neutralised" : "active" - to_chat(owner.current, " New target added to database: [objective.target.name] ([status_text]) ") + to_chat(owner.current, span_userdanger("New target added to database: [objective.target.name] ([status_text])")) else if(istype(objective_, /datum/objective/destroy/internal)) var/datum/objective/destroy/internal/objective = objective_ var/datum/objective/destroy/internal/new_objective = new @@ -156,7 +177,7 @@ add_objective(new_objective) targets_stolen += objective.target var/status_text = objective.check_completion() ? "neutralised" : "active" - to_chat(owner.current, " New target added to database: [objective.target.name] ([status_text]) ") + to_chat(owner.current, span_userdanger("New target added to database: [objective.target.name] ([status_text])")) last_man_standing = TRUE for(var/objective_ in objectives) if(!is_internal_objective(objective_)) @@ -167,13 +188,15 @@ return if(last_man_standing) if(syndicate) - to_chat(owner.current,"All the suspected agents are dead, and no more is required of you. Die a glorious death, agent.") - replace_escape_objective(owner) + to_chat(owner.current,span_userdanger("All the suspected agents are dead, and no more is required of you. Die a glorious death, agent.")) else - to_chat(owner.current,"All the other agents are dead. You have done us all a great service and shall be honorably exiled upon returning to base.") + to_chat(owner.current,span_userdanger("All the other agents are dead. You have done us all a great service and shall be honorably exiled upon returning to base.")) + replace_escape_objective(owner) /datum/antagonist/traitor/internal_affairs/proc/iaa_process() - if(owner&&owner.current&&owner.current.stat!=DEAD) + if(!owner) + CRASH("Antag datum with no owner.") + if(owner.current && owner.current.stat != DEAD) for(var/objective_ in objectives) if(!is_internal_objective(objective_)) continue @@ -188,12 +211,12 @@ objective.stolen = TRUE else if(objective.stolen) - var/fail_msg = "Your sensors tell you that [objective.target.current.real_name], one of the targets you were meant to have killed, pulled one over on you, and is still alive - do the job properly this time! " + var/fail_msg = span_userdanger("Your sensors tell you that [objective.target.current.real_name], one of the targets you were meant to have killed, pulled one over on you, and is still alive - do the job properly this time! ") if(last_man_standing) if(syndicate) - fail_msg += " You no longer have permission to die. " + fail_msg += span_userdanger(" You no longer have permission to die. ") else - fail_msg += " The truth could still slip out!
    Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to great shame." + fail_msg += span_userdanger(" The truth could still slip out! Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to your contract being terminated.") reinstate_escape_objective(owner) last_man_standing = FALSE to_chat(owner.current, fail_msg) @@ -220,29 +243,24 @@ /datum/antagonist/traitor/internal_affairs/forge_traitor_objectives() forge_iaa_objectives() - var/objtype = !istype(traitor_kind,TRAITOR_AI) ? /datum/objective/escape : /datum/objective/survive - var/datum/objective/escape_objective = new objtype + var/datum/objective/escape_objective = new /datum/objective/escape() escape_objective.owner = owner add_objective(escape_objective) /datum/antagonist/traitor/internal_affairs/proc/greet_iaa() - var/crime = pick("distribution of contraband" , "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "receiving bribes", "malpractice", "worship of prohibited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence") + var/crime = pick("distribution of contraband", "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "receiving bribes", "malpractice", "worship of prohibited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence") - to_chat(owner.current, "You are the [special_role].") + to_chat(owner.current, span_userdanger("You are the [special_role].")) if(syndicate) - to_chat(owner.current, "GREAT LEADER IS DEAD. NANOTRASEN MUST FALL.") - to_chat(owner.current, "Your have infiltrated this vessel to cause chaos and assassinate targets known to have conspired against the Syndicate.") - to_chat(owner.current, "Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.") - to_chat(owner.current, "You have been provided with a standard uplink to accomplish your task. ") - to_chat(owner.current, "By no means reveal that you are a Syndicate agent. By no means reveal that your targets are being hunted.") + to_chat(owner.current, span_userdanger("Your target has been framed for [crime], and you have been tasked with eliminating them to prevent them defending themselves in court.")) + to_chat(owner.current, "Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.") + to_chat(owner.current, span_userdanger("You have been provided with a standard uplink to accomplish your task.")) else - to_chat(owner.current, "CAUTION: Your legal status as a citizen of NanoTrasen will be permanently revoked upon completion of your first contract.") - to_chat(owner.current, "Your target has been suspected of [crime], and must be removed from this plane.") - to_chat(owner.current, "While you have a license to kill, you are to eliminate your targets with no collateral or unrelated deaths.") - to_chat(owner.current, "For the sake of plausable deniability, you have been equipped with captured Syndicate equipment via uplink.") - to_chat(owner.current, "By no means reveal that you, or any other NT employees, are undercover agents.") + to_chat(owner.current, span_userdanger("Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.")) + to_chat(owner.current, "While you have a license to kill, unneeded property damage or loss of employee life will lead to your contract being terminated.") + to_chat(owner.current, span_userdanger("For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.")) - to_chat(owner.current, "Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.") + to_chat(owner.current, span_userdanger("Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.")) owner.announce_objectives() /datum/antagonist/traitor/internal_affairs/greet() diff --git a/code/modules/antagonists/traitor/classes/human.dm b/code/modules/antagonists/traitor/classes/human.dm index f868d0e7e1..49881630f0 100644 --- a/code/modules/antagonists/traitor/classes/human.dm +++ b/code/modules/antagonists/traitor/classes/human.dm @@ -28,17 +28,11 @@ /datum/traitor_class/human/forge_single_objective(datum/antagonist/traitor/T) .=1 var/assassin_prob = 50 - var/is_dynamic = FALSE var/datum/game_mode/dynamic/mode if(istype(SSticker.mode,/datum/game_mode/dynamic)) mode = SSticker.mode - is_dynamic = TRUE assassin_prob = max(0,mode.threat_level-20) if(prob(assassin_prob)) - if(is_dynamic) - var/threat_spent = CONFIG_GET(number/dynamic_assassinate_cost) - mode.spend_threat(threat_spent) - mode.log_threat("[T.owner.name] added [threat_spent] on an assassination target.") var/list/active_ais = active_ais() if(active_ais.len && prob(100/GLOB.joined_player_list.len)) var/datum/objective/destroy/destroy_objective = new diff --git a/code/modules/antagonists/traitor/classes/martyr.dm b/code/modules/antagonists/traitor/classes/martyr.dm index 5c407b70fd..b0a6494de7 100644 --- a/code/modules/antagonists/traitor/classes/martyr.dm +++ b/code/modules/antagonists/traitor/classes/martyr.dm @@ -5,7 +5,7 @@ chaos = 5 threat = 5 min_players = 20 - uplink_filters = list(/datum/uplink_item/stealthy_weapons/romerol_kit,/datum/uplink_item/bundles_TC/contract_kit) + uplink_filters = list(/datum/uplink_item/stealthy_weapons/romerol_kit,/datum/uplink_item/bundles_tc/contract_kit) /datum/traitor_class/human/martyr/forge_objectives(datum/antagonist/traitor/T) var/datum/objective/martyr/O = new diff --git a/code/modules/antagonists/traitor/classes/subterfuge.dm b/code/modules/antagonists/traitor/classes/subterfuge.dm index 54f07eb23c..6c4bd26afb 100644 --- a/code/modules/antagonists/traitor/classes/subterfuge.dm +++ b/code/modules/antagonists/traitor/classes/subterfuge.dm @@ -9,7 +9,7 @@ var/datum/game_mode/dynamic/mode if(istype(SSticker.mode,/datum/game_mode/dynamic)) mode = SSticker.mode - assassin_prob = max(0,mode.threat_level-40) + assassin_prob = max(0,mode.threat_level-20) if(prob(assassin_prob)) var/datum/objective/assassinate/once/kill_objective = new kill_objective.owner = T.owner diff --git a/code/modules/antagonists/traitor/classes/traitor_class.dm b/code/modules/antagonists/traitor/classes/traitor_class.dm index 6aaa0b41c8..bc24aecd9c 100644 --- a/code/modules/antagonists/traitor/classes/traitor_class.dm +++ b/code/modules/antagonists/traitor/classes/traitor_class.dm @@ -11,6 +11,8 @@ GLOBAL_LIST_EMPTY(traitor_classes) /// Minimum players for this to randomly roll via get_random_traitor_kind(). var/min_players = 0 var/list/uplink_filters + /// Specific tgui theme for the player's antag info panel. + var/tgui_theme = "syndicate" /datum/traitor_class/New() ..() @@ -45,5 +47,5 @@ GLOBAL_LIST_EMPTY(traitor_classes) /datum/traitor_class/proc/clean_up_traitor(datum/antagonist/traitor/T) // Any effects that need to be cleaned up if traitor class is being swapped. -/datum/traitor_class/proc/on_process(/datum/antagonist/traitor/T) +/datum/traitor_class/proc/on_process(datum/antagonist/traitor/T) // only for processing traitor classes; runs once an SSprocessing tick diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index f0bc6e5bfc..f184961004 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -5,14 +5,22 @@ job_rank = ROLE_TRAITOR antag_moodlet = /datum/mood_event/focused skill_modifiers = list(/datum/skill_modifier/job/level/wiring/basic) - var/special_role = ROLE_TRAITOR + hijack_speed = 0.5 //10 seconds per hijack stage by default + ui_name = "AntagInfoTraitor" + suicide_cry = "FOR THE SYNDICATE!!" var/employer = "The Syndicate" var/give_objectives = TRUE var/should_give_codewords = TRUE var/should_equip = TRUE + + ///special datum about what kind of employer the trator has var/datum/traitor_class/traitor_kind + + ///reference to the uplink this traitor was given, if they were. + var/datum/component/uplink/uplink + var/datum/contractor_hub/contractor_hub - hijack_speed = 0.5 //10 seconds per hijack stage by default + threat = 5 /datum/antagonist/traitor/New() @@ -45,18 +53,14 @@ /datum/antagonist/traitor/process() traitor_kind.on_process(src) -/proc/get_random_traitor_kind(var/list/blacklist = list()) - var/chaos_weight = 0 - if(istype(SSticker.mode,/datum/game_mode/dynamic)) - var/datum/game_mode/dynamic/mode = SSticker.mode - chaos_weight = (mode.threat - 50)/50 +/proc/get_random_traitor_kind(list/blacklist = list()) var/list/weights = list() for(var/C in GLOB.traitor_classes) if(!(C in blacklist)) var/datum/traitor_class/class = GLOB.traitor_classes[C] if(class.min_players > length(GLOB.joined_player_list)) continue - var/weight = LOGISTIC_FUNCTION(1.5*class.weight,chaos_weight,class.chaos,0) + var/weight = LOGISTIC_FUNCTION(1.5*class.weight,0,class.chaos,0) weights[C] = weight * 1000 var/choice = pickweight(weights, 0) if(!choice) @@ -66,23 +70,24 @@ return choice /datum/antagonist/traitor/on_gain() + owner.special_role = job_rank if(owner.current && isAI(owner.current)) set_traitor_kind(TRAITOR_AI) else set_traitor_kind(get_random_traitor_kind()) SSticker.mode.traitors += owner - owner.special_role = special_role finalize_traitor() - ..() + uplink = owner.find_syndicate_uplink() + return ..() /datum/antagonist/traitor/on_removal() + if(!silent && owner.current) + to_chat(owner.current,span_userdanger("You are no longer the [job_rank]!")) //Remove malf powers. traitor_kind.on_removal(src) SSticker.mode.traitors -= owner - if(!silent && owner.current) - to_chat(owner.current," You are no longer the [special_role]! ") owner.special_role = null - . = ..() + return ..() /datum/antagonist/traitor/proc/handle_hearing(datum/source, list/hearing_args) var/message = hearing_args[HEARING_RAW_MESSAGE] @@ -97,6 +102,7 @@ /datum/antagonist/traitor/proc/remove_objective(datum/objective/O) objectives -= O +/// Generates a complete set of traitor objectives up to the traitor objective limit, including non-generic objectives such as martyr and hijack. /datum/antagonist/traitor/proc/forge_traitor_objectives() traitor_kind.forge_objectives(src) @@ -155,21 +161,42 @@ H.dna.add_mutation(CLOWNMUT) UnregisterSignal(M, COMSIG_MOVABLE_HEAR) + +/datum/antagonist/traitor/ui_static_data(mob/user) + var/list/data = list() + data["phrases"] = jointext(GLOB.syndicate_code_phrase, ", ") + data["responses"] = jointext(GLOB.syndicate_code_response, ", ") + data["theme"] = traitor_kind.tgui_theme //traitor_flavor["ui_theme"] + data["code"] = uplink.unlock_code + data["intro"] = "You are from [traitor_kind.employer]." //traitor_flavor["introduction"] + data["allies"] = "Most other syndicate operatives are not to be trusted (but try not to rat them out), as they might have been assigned opposing objectives." //traitor_flavor["allies"] + data["goal"] = "We do not approve of mindless killing of innocent workers; \"get in, get done, get out\" is our motto." //traitor_flavor["goal"] + data["has_uplink"] = uplink ? TRUE : FALSE + if(uplink) + data["uplink_intro"] = "You have been provided with a standard uplink to accomplish your task." //traitor_flavor["uplink"] + data["uplink_unlock_info"] = uplink.unlock_text + data["objectives"] = get_objectives() + return data + +/// Outputs this shift's codewords and responses to the antag's chat and copies them to their memory. /datum/antagonist/traitor/proc/give_codewords() if(!owner.current) return - var/mob/traitor_mob=owner.current + + var/mob/traitor_mob = owner.current var/phrases = jointext(GLOB.syndicate_code_phrase, ", ") var/responses = jointext(GLOB.syndicate_code_response, ", ") - var/dat = "The Syndicate have provided you with the following codewords to identify fellow agents:\n" - dat += "Code Phrase: [phrases]\n" - dat += "Code Response: [responses]" - to_chat(traitor_mob, dat) + to_chat(traitor_mob, "The Syndicate have provided you with the following codewords to identify fellow agents:") + to_chat(traitor_mob, "Code Phrase: [span_blue("[phrases]")]") + to_chat(traitor_mob, "Code Response: [span_red("[responses]")]") - antag_memory += "Code Phrase: [phrases]
    " - antag_memory += "Code Response: [responses]
    " + antag_memory += "Code Phrase: [span_blue("[phrases]")]
    " + antag_memory += "Code Response: [span_red("[responses]")]
    " + + to_chat(traitor_mob, "Use the codewords during regular conversation to identify other agents. Proceed with caution, however, as everyone is a potential foe.") + to_chat(traitor_mob, span_alertwarning("You memorize the codewords, allowing you to recognise them when heard.")) /datum/antagonist/traitor/proc/add_law_zero() var/mob/living/silicon/ai/killer = owner.current @@ -213,9 +240,9 @@ folder = new/obj/item/folder/syndicate/blue(mob.loc) var/list/slots = list ( - "backpack" = SLOT_IN_BACKPACK, - "left pocket" = SLOT_L_STORE, - "right pocket" = SLOT_R_STORE + "backpack" = ITEM_SLOT_BACKPACK, + "left pocket" = ITEM_SLOT_LPOCKET, + "right pocket" = ITEM_SLOT_RPOCKET ) var/where = "At your feet" @@ -224,44 +251,43 @@ where = "In your [equipped_slot]" to_chat(mob, "

    [where] is a folder containing secret documents that another Syndicate group wants. We have set up a meeting with one of their agents on station to make an exchange. Exercise extreme caution as they cannot be trusted and may be hostile.
    ") -//TODO Collate /datum/antagonist/traitor/roundend_report() var/list/result = list() - var/traitorwin = TRUE + var/traitor_won = TRUE result += printplayer(owner) - var/TC_uses = 0 - var/uplink_true = FALSE + var/used_telecrystals = 0 + var/uplink_owned = FALSE var/purchases = "" + LAZYINITLIST(GLOB.uplink_purchase_logs_by_key) - var/datum/uplink_purchase_log/H = GLOB.uplink_purchase_logs_by_key[owner.key] - if(H) - TC_uses = H.total_spent - uplink_true = TRUE - purchases += H.generate_render(FALSE) + // Uplinks add an entry to uplink_purchase_logs_by_key on init. + var/datum/uplink_purchase_log/purchase_log = GLOB.uplink_purchase_logs_by_key[owner.key] + if(purchase_log) + used_telecrystals = purchase_log.total_spent + uplink_owned = TRUE + purchases += purchase_log.generate_render(FALSE) var/objectives_text = "" - if(objectives.len)//If the traitor had no objectives, don't need to process this. + if(objectives.len) //If the traitor had no objectives, don't need to process this. var/count = 1 for(var/datum/objective/objective in objectives) - if(objective.completable) - var/completion = objective.check_completion() - if(completion >= 1) - objectives_text += "
    Objective #[count]: [objective.explanation_text] Success!" - else if(completion <= 0) - objectives_text += "
    Objective #[count]: [objective.explanation_text] Fail." - traitorwin = FALSE - else - objectives_text += "
    Objective #[count]: [objective.explanation_text] [completion*100]%" + var/completion = objective.check_completion() + if(completion >= 1) + objectives_text += "
    Objective #[count]: [objective.explanation_text] [span_greentext("Success!")]" + else if(completion <= 0) + objectives_text += "
    Objective #[count]: [objective.explanation_text] [span_redtext("Fail.")]" + traitor_won = FALSE else - objectives_text += "
    Objective #[count]: [objective.explanation_text]" + objectives_text += "
    Objective #[count]: [objective.explanation_text] [completion*100]%" + count++ - if(uplink_true) - var/uplink_text = "(used [TC_uses] TC) [purchases]" - if(TC_uses==0 && traitorwin) + if(uplink_owned) + var/uplink_text = "(used [used_telecrystals] TC) [purchases]" + if((used_telecrystals == 0) && traitor_won) var/static/icon/badass = icon('icons/badass.dmi', "badass") uplink_text += "[icon2html(badass, world)]" result += uplink_text @@ -270,55 +296,59 @@ var/special_role_text = lowertext(name) - if(contractor_hub) + if (contractor_hub) result += contractor_round_end() - if(traitorwin) - result += "The [special_role_text] was successful!" + if(traitor_won) + result += span_greentext("The [special_role_text] was successful!") else - result += "The [special_role_text] has failed!" + result += span_redtext("The [special_role_text] has failed!") SEND_SOUND(owner.current, 'sound/ambience/ambifailure.ogg') return result.Join("
    ") /// Proc detailing contract kit buys/completed contracts/additional info /datum/antagonist/traitor/proc/contractor_round_end() - var result = "" - var total_spent_rep = 0 + var/result = "" + var/total_spent_rep = 0 - var/completed_contracts = 0 + var/completed_contracts = contractor_hub.contracts_completed var/tc_total = contractor_hub.contract_TC_payed_out + contractor_hub.contract_TC_to_redeem - for(var/datum/syndicate_contract/contract in contractor_hub.assigned_contracts) - if(contract.status == CONTRACT_STATUS_COMPLETE) - completed_contracts++ var/contractor_item_icons = "" // Icons of purchases var/contractor_support_unit = "" // Set if they had a support unit - and shows appended to their contracts completed - for(var/datum/contractor_item/contractor_purchase in contractor_hub.purchased_items) // Get all the icons/total cost for all our items bought + /// Get all the icons/total cost for all our items bought + for (var/datum/contractor_item/contractor_purchase in contractor_hub.purchased_items) contractor_item_icons += "\[ [contractor_purchase.name] - [contractor_purchase.cost] Rep

    [contractor_purchase.desc]
    \]
    " + total_spent_rep += contractor_purchase.cost - if(istype(contractor_purchase, /datum/contractor_item/contractor_partner)) // Special case for reinforcements, we want to show their ckey and name on round end. + + /// Special case for reinforcements, we want to show their ckey and name on round end. + if (istype(contractor_purchase, /datum/contractor_item/contractor_partner)) var/datum/contractor_item/contractor_partner/partner = contractor_purchase contractor_support_unit += "
    [partner.partner_mind.key] played [partner.partner_mind.current.name], their contractor support unit." + if (contractor_hub.purchased_items.len) - result += "
    (used [total_spent_rep] Rep)" + result += "
    (used [total_spent_rep] Rep) " result += contractor_item_icons result += "
    " - if(completed_contracts > 0) + if (completed_contracts > 0) var/pluralCheck = "contract" - if(completed_contracts > 1) + if (completed_contracts > 1) pluralCheck = "contracts" - result += "Completed [completed_contracts] [pluralCheck] for a total of \ - [tc_total] TC!
    " + + result += "Completed [span_greentext("[completed_contracts]")] [pluralCheck] for a total of \ + [span_greentext("[tc_total] TC")]![contractor_support_unit]
    " + return result /datum/antagonist/traitor/roundend_report_footer() var/phrases = jointext(GLOB.syndicate_code_phrase, ", ") var/responses = jointext(GLOB.syndicate_code_response, ", ") - var message = "
    The code phrases were: [phrases]
    \ - The code responses were: [responses]
    " + var/message = "
    The code phrases were: [phrases]
    \ + The code responses were: [span_redtext("[responses]")]
    " return message diff --git a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm index fcc8bcade8..e5fa38a415 100644 --- a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm +++ b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm @@ -355,7 +355,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( var/detonation_timer var/next_announce -/obj/machinery/doomsday_device/Initialize() +/obj/machinery/doomsday_device/Initialize(mapload) . = ..() countdown = new(src) diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm index 44f267358a..7df91f4679 100644 --- a/code/modules/antagonists/wizard/equipment/artefact.dm +++ b/code/modules/antagonists/wizard/equipment/artefact.dm @@ -229,12 +229,12 @@ H.dropItemToGround(I) var/hat = pick(/obj/item/clothing/head/helmet/roman, /obj/item/clothing/head/helmet/roman/legionnaire) - H.equip_to_slot_or_del(new hat(H), SLOT_HEAD) - H.equip_to_slot_or_del(new /obj/item/clothing/under/costume/roman(H), SLOT_W_UNIFORM) - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/roman(H), SLOT_SHOES) + H.equip_to_slot_or_del(new hat(H), ITEM_SLOT_HEAD) + H.equip_to_slot_or_del(new /obj/item/clothing/under/costume/roman(H), ITEM_SLOT_ICLOTHING) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/roman(H), ITEM_SLOT_FEET) H.put_in_hands(new /obj/item/shield/riot/roman(H), TRUE) H.put_in_hands(new /obj/item/claymore(H), TRUE) - H.equip_to_slot_or_del(new /obj/item/spear(H), SLOT_BACK) + H.equip_to_slot_or_del(new /obj/item/spear(H), ITEM_SLOT_BACK) /obj/item/voodoo @@ -444,6 +444,6 @@ duration = 40 pixel_x = 500 -/obj/effect/temp_visual/tornado/Initialize() +/obj/effect/temp_visual/tornado/Initialize(mapload) . = ..() animate(src, pixel_x = -500, time = 40) diff --git a/code/modules/antagonists/wizard/equipment/soulstone.dm b/code/modules/antagonists/wizard/equipment/soulstone.dm index d4d70cd053..fe9770e64a 100644 --- a/code/modules/antagonists/wizard/equipment/soulstone.dm +++ b/code/modules/antagonists/wizard/equipment/soulstone.dm @@ -50,6 +50,14 @@ A.death() return ..() +/obj/item/soulstone/proc/hot_potato(mob/living/user) + to_chat(user, span_userdanger("Holy magics residing in \the [src] burn your hand!")) + var/obj/item/bodypart/affecting = user.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm") + affecting.receive_damage( 0, 10 ) // 10 burn damage + user.emote("scream") + user.update_damage_overlays() + user.dropItemToGround(src) + //////////////////////////////Capturing//////////////////////////////////////////////////////// /obj/item/soulstone/attack(mob/living/carbon/human/M, mob/living/user) @@ -94,6 +102,35 @@ to_chat(A, "You have been released from your prison, but you are still bound to the cult's will. Help them succeed in their goals at all costs.") was_used() +/obj/item/soulstone/pre_attack(atom/A, mob/living/user, params) + var/mob/living/simple_animal/hostile/construct/shade/occupant = (locate() in src) + var/obj/item/storage/toolbox/mechanical/target_toolbox = A + if(!occupant || !istype(target_toolbox) || target_toolbox.has_soul) + return ..() + + if(iscultist(user)) + hot_potato(user) + return + if(!iscultist(user, TRUE) && !iswizard(user) && !usability) + user.Unconscious(10 SECONDS) + to_chat(user, span_userdanger("Your body is wracked with debilitating pain!")) + return + + user.visible_message("[user] holds [src] above [user.p_their()] head and forces it into [target_toolbox] with a flash of light!", \ + span_notice("You hold [src] above your head briefly, then force it into [target_toolbox], transferring the [occupant]'s soul!"), ignored_mobs = occupant) + to_chat(occupant, span_userdanger("[user] holds you up briefly, then forces you into [target_toolbox]!")) + to_chat(occupant, span_deadsay("Your eternal soul has been sacrificed to restore the soul of a toolbox. Them's the breaks!")) + + occupant.client?.give_award(/datum/award/achievement/misc/toolbox_soul, occupant) + occupant.deathmessage = "shrieks out in unholy pain as [occupant.p_their()] soul is absorbed into [target_toolbox]!" + release_shades(user, TRUE) + occupant.death() + + target_toolbox.name = "soulful toolbox" + target_toolbox.icon_state = "toolbox_blue_old" + target_toolbox.has_soul = TRUE + target_toolbox.has_latches = FALSE + ///////////////////////////Transferring to constructs///////////////////////////////////////////////////// /obj/structure/constructshell name = "empty shell" diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm index 21de660edb..0701ade73c 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook.dm @@ -618,7 +618,7 @@ else . += "It appears to have no author." -/obj/item/spellbook/Initialize() +/obj/item/spellbook/Initialize(mapload) . = ..() prepare_spells() diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm index 23e870a0ec..63bb2b5b57 100644 --- a/code/modules/antagonists/wizard/wizard.dm +++ b/code/modules/antagonists/wizard/wizard.dm @@ -3,12 +3,15 @@ roundend_category = "wizards/witches" antagpanel_category = "Wizard" job_rank = ROLE_WIZARD + antag_hud_type = ANTAG_HUD_WIZ + antag_hud_name = "wizard" antag_moodlet = /datum/mood_event/focused - threat = 30 + hijack_speed = 0.5 + ui_name = "AntagInfoWizard" + suicide_cry = "FOR THE FEDERATION!!" var/give_objectives = TRUE var/strip = TRUE //strip before equipping var/allow_rename = TRUE - var/hud_version = "wizard" var/datum/team/wizard/wiz_team //Only created if wizard summons apprentices var/move_to_lair = TRUE var/outfit_type = /datum/outfit/wizard @@ -50,16 +53,17 @@ wiz_team = new(owner) wiz_team.name = "[owner.current.real_name] team" wiz_team.master_wizard = src - update_wiz_icons_added(owner.current) + add_antag_hud(antag_hud_type, antag_hud_name, owner.current) /datum/antagonist/wizard/proc/send_to_lair() - if(!owner || !owner.current) + if(!owner) + CRASH("Antag datum with no owner.") + if(!owner.current) return if(!GLOB.wizardstart.len) SSjob.SendToLateJoin(owner.current) to_chat(owner, "HOT INSERTION, GO GO GO") - else - owner.current.forceMove(pick(GLOB.wizardstart)) + owner.current.forceMove(pick(GLOB.wizardstart)) /datum/antagonist/wizard/proc/create_objectives() var/datum/objective/flavor/wizard/new_objective = new @@ -79,7 +83,7 @@ /datum/antagonist/wizard/proc/equip_wizard() if(!owner) - return + CRASH("Antag datum with no owner.") var/mob/living/carbon/human/H = owner.current if(!istype(H)) return @@ -91,18 +95,14 @@ H.age = wiz_age H.equipOutfit(outfit_type) -/datum/antagonist/wizard/greet() - to_chat(owner, "You are the Space Wizard!") - to_chat(owner, "The Space Wizards Federation has given you the following tasks:") - owner.announce_objectives() - to_chat(owner, "These are merely guidelines! The federation are your masters, but you forge your own path!") - to_chat(owner, "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.") - to_chat(owner, "The spellbook is bound to you, and others cannot use it.") - to_chat(owner, "In your pockets you will find a teleport scroll. Use it as needed.") - to_chat(owner,"Remember: do not forget to prepare your spells.") +/datum/antagonist/wizard/ui_static_data(mob/user) + . = ..() + var/list/data = list() + data["objectives"] = get_objectives() + return data /datum/antagonist/wizard/farewell() - to_chat(owner, "You have been brainwashed! You are no longer a wizard!") + to_chat(owner, span_userdanger("You have been brainwashed! You are no longer a wizard!")) /datum/antagonist/wizard/proc/rename_wizard() set waitfor = FALSE @@ -111,7 +111,7 @@ var/wizard_name_second = pick(GLOB.wizard_second) var/randomname = "[wizard_name_first] [wizard_name_second]" var/mob/living/wiz_mob = owner.current - var/newname = reject_bad_name(stripped_input(wiz_mob, "You are the [name]. Would you like to change your name to something else?", "Name change", randomname, MAX_NAME_LEN)) + var/newname = sanitize_name(reject_bad_text(stripped_input(wiz_mob, "You are the [name]. Would you like to change your name to something else?", "Name change", randomname, MAX_NAME_LEN))) if (!newname) newname = randomname @@ -120,12 +120,12 @@ /datum/antagonist/wizard/apply_innate_effects(mob/living/mob_override) var/mob/living/M = mob_override || owner.current - update_wiz_icons_added(M, wiz_team ? TRUE : FALSE) //Don't bother showing the icon if you're solo wizard + add_antag_hud(antag_hud_type, antag_hud_name, M) M.faction |= ROLE_WIZARD /datum/antagonist/wizard/remove_innate_effects(mob/living/mob_override) var/mob/living/M = mob_override || owner.current - update_wiz_icons_removed(M) + remove_antag_hud(antag_hud_type, M) M.faction -= ROLE_WIZARD @@ -138,7 +138,7 @@ /datum/antagonist/wizard/apprentice name = "Wizard Apprentice" - hud_version = "apprentice" + antag_hud_name = "apprentice" var/datum/mind/master var/school = APPRENTICE_DESTRUCTION outfit_type = /datum/outfit/wizard/apprentice @@ -157,7 +157,7 @@ /datum/antagonist/wizard/apprentice/equip_wizard() . = ..() if(!owner) - return + CRASH("Antag datum with no owner.") var/mob/living/carbon/human/H = owner.current if(!istype(H)) return @@ -169,12 +169,12 @@ if(APPRENTICE_BLUESPACE) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null)) - to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned reality bending mobility spells. You are able to cast teleport and ethereal jaunt.") + to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned reality-bending mobility spells. You are able to cast teleport and ethereal jaunt.") if(APPRENTICE_HEALING) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/charge(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall(null)) H.put_in_hands(new /obj/item/gun/magic/staff/healing(H)) - to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned livesaving survival spells. You are able to cast charge and forcewall.") + to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned life-saving survival spells. You are able to cast charge and forcewall.") if(APPRENTICE_ROBELESS) owner.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/pointed/mind_transfer(null)) @@ -194,6 +194,7 @@ //Random event wizard /datum/antagonist/wizard/apprentice/imposter name = "Wizard Imposter" + show_in_antagpanel = FALSE allow_rename = FALSE move_to_lair = FALSE @@ -207,37 +208,28 @@ if(!istype(master_mob) || !istype(H)) return if(master_mob.ears) - H.equip_to_slot_or_del(new master_mob.ears.type, SLOT_EARS) + H.equip_to_slot_or_del(new master_mob.ears.type, ITEM_SLOT_EARS) if(master_mob.w_uniform) - H.equip_to_slot_or_del(new master_mob.w_uniform.type, SLOT_W_UNIFORM) + H.equip_to_slot_or_del(new master_mob.w_uniform.type, ITEM_SLOT_ICLOTHING) if(master_mob.shoes) - H.equip_to_slot_or_del(new master_mob.shoes.type, SLOT_SHOES) + H.equip_to_slot_or_del(new master_mob.shoes.type, ITEM_SLOT_FEET) if(master_mob.wear_suit) - H.equip_to_slot_or_del(new master_mob.wear_suit.type, SLOT_WEAR_SUIT) + H.equip_to_slot_or_del(new master_mob.wear_suit.type, ITEM_SLOT_OCLOTHING) if(master_mob.head) - H.equip_to_slot_or_del(new master_mob.head.type, SLOT_HEAD) + H.equip_to_slot_or_del(new master_mob.head.type, ITEM_SLOT_HEAD) if(master_mob.back) - H.equip_to_slot_or_del(new master_mob.back.type, SLOT_BACK) + H.equip_to_slot_or_del(new master_mob.back.type, ITEM_SLOT_BACK) //Operation: Fuck off and scare people owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null)) -/datum/antagonist/wizard/proc/update_wiz_icons_added(mob/living/wiz,join = TRUE) - var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ] - wizhud.join_hud(wiz) - set_antag_hud(wiz, hud_version) - -/datum/antagonist/wizard/proc/update_wiz_icons_removed(mob/living/wiz) - var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ] - wizhud.leave_hud(wiz) - set_antag_hud(wiz, null) - - /datum/antagonist/wizard/academy name = "Academy Teacher" + show_in_antagpanel = FALSE outfit_type = /datum/outfit/wizard/academy + move_to_lair = FALSE /datum/antagonist/wizard/academy/equip_wizard() . = ..() @@ -250,7 +242,7 @@ if(!istype(M)) return - var/obj/item/implant/exile/Implant = new + var/obj/item/implant/exile/Implant = new/obj/item/implant/exile(M) Implant.implant(M) /datum/antagonist/wizard/academy/create_objectives() @@ -265,25 +257,25 @@ parts += printplayer(owner) var/count = 1 - var/wizardwin = 1 + var/wizardwin = TRUE for(var/datum/objective/objective in objectives) if(objective.completable) var/completion = objective.check_completion() if(completion >= 1) - parts += "Objective #[count]: [objective.explanation_text] Success!" + parts += "
    Objective #[count]: [objective.explanation_text] [span_greentext("Success!")]" else if(completion <= 0) - parts += "Objective #[count]: [objective.explanation_text] Fail." + parts += "
    Objective #[count]: [objective.explanation_text] [span_redtext("Fail.")]" wizardwin = FALSE else - parts += "Objective #[count]: [objective.explanation_text] [completion*100]%" + parts += "
    Objective #[count]: [objective.explanation_text] [completion*100]%" else parts += "Objective #[count]: [objective.explanation_text]" count++ if(wizardwin) - parts += "The wizard was successful!" + parts += span_greentext("The wizard was successful!") else - parts += "The wizard has failed!" + parts += span_redtext("The wizard has failed!") if(owner.spell_list.len>0) parts += "[owner.name] used the following spells: " diff --git a/code/modules/arousal/arousal.dm b/code/modules/arousal/arousal.dm index 36da6c73ba..4e0f37d529 100644 --- a/code/modules/arousal/arousal.dm +++ b/code/modules/arousal/arousal.dm @@ -55,7 +55,7 @@ return genit_list /obj/item/organ/genital/proc/climaxable(mob/living/carbon/human/H, silent = FALSE) //returns the fluid source (ergo reagents holder) if found. - if(CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION)) + if((genital_flags & GENITAL_FUID_PRODUCTION)) . = reagents else if(linked_organ) @@ -74,7 +74,7 @@ if(spill && R.total_volume >= 5) R.reaction(turfing ? target : target.loc, TOUCH, 1, 0) if(!turfing) - R.trans_to(target, R.total_volume * (spill ? G.fluid_transfer_factor : 1)) + R.trans_to(target, R.total_volume * (spill ? G.fluid_transfer_factor : 1), log = TRUE) G.last_orgasmed = world.time R.clear_reagents() @@ -117,6 +117,8 @@ if(!do_after(src, mb_time, target = src) || !in_range(src, container) || !G.climaxable(src, TRUE)) return to_chat(src,"You used your [G.name] to fill [container].") + message_admins("[ADMIN_LOOKUPFLW(src)] used their [G.name] to fill [container].") + log_consent("[key_name(src)] used their [G.name] to fill [container].") do_climax(fluid_source, container, G, FALSE) /mob/living/carbon/human/proc/pick_climax_genitals(silent = FALSE) @@ -124,7 +126,7 @@ var/list/worn_stuff = get_equipped_items() for(var/obj/item/organ/genital/G in internal_organs) - if(CHECK_BITFIELD(G.genital_flags, CAN_CLIMAX_WITH) && G.is_exposed(worn_stuff)) //filter out what you can't masturbate with + if((G.genital_flags & CAN_CLIMAX_WITH) && G.is_exposed(worn_stuff)) //filter out what you can't masturbate with LAZYADD(genitals_list, G) if(LAZYLEN(genitals_list)) var/obj/item/organ/genital/ret_organ = input(src, "with what?", "Climax", null) as null|obj in genitals_list @@ -144,7 +146,7 @@ partners -= L if(iscarbon(L)) var/mob/living/carbon/C = L - if(!C.exposed_genitals.len && !C.is_groin_exposed() && !C.is_chest_exposed()) //Nothing through_clothing, no proper partner. + if(!C.exposed_genitals.len && !C.is_groin_exposed() && !C.is_chest_exposed() && C.is_mouth_covered()) //Nothing through_clothing, no proper partner. partners -= C //NOW the list should only contain correct partners if(!partners.len) @@ -158,8 +160,8 @@ if(consenting == "Yes") return target else - message_admins("[src] tried to climax with [target], but [target] did not consent.") - log_consent("[src] tried to climax with [target], but [target] did not consent.") + message_admins("[ADMIN_LOOKUPFLW(src)] tried to climax with [target], but [target] did not consent.") + log_consent("[key_name(src)] tried to climax with [target], but [target] did not consent.") /mob/living/carbon/human/proc/pick_climax_container(silent = FALSE) var/list/containers_list = list() @@ -212,7 +214,7 @@ if(forced_climax) //Something forced us to cum, this is not a masturbation thing and does not progress to the other checks log_message("was forced to climax by [cause]",LOG_EMOTE) for(var/obj/item/organ/genital/G in internal_organs) - if(!CHECK_BITFIELD(G.genital_flags, CAN_CLIMAX_WITH)) //Skip things like wombs and testicles + if(!(G.genital_flags & CAN_CLIMAX_WITH)) //Skip things like wombs and testicles continue mob_climax_outside(G, mb_time = 0) //removed climax timer for sudden, forced orgasms //Now all genitals that could climax, have. diff --git a/code/modules/arousal/genitals.dm b/code/modules/arousal/genitals.dm index bfcaff7d56..e9fe56cadf 100644 --- a/code/modules/arousal/genitals.dm +++ b/code/modules/arousal/genitals.dm @@ -33,12 +33,16 @@ linked_organ = null . = ..() +/obj/item/organ/genital/on_life() + return + /obj/item/organ/genital/proc/set_aroused_state(new_state,cause = "manual toggle") if(!(genital_flags & GENITAL_CAN_AROUSE)) return FALSE if(!((HAS_TRAIT(owner,TRAIT_PERMABONER) && !new_state) || HAS_TRAIT(owner,TRAIT_NEVERBONER) && new_state)) aroused_state = new_state - owner.log_message("[src]'s arousal was [new_state ? "enabled" : "disabled"] due to [cause]", LOG_EMOTE) + if(cause) + owner.log_message("[src]'s arousal was [new_state ? "enabled" : "disabled"] due to [cause]", LOG_EMOTE) return aroused_state /obj/item/organ/genital/proc/update() @@ -112,7 +116,7 @@ var/list/genital_list = list() for(var/obj/item/organ/genital/G in internal_organs) - if(!CHECK_BITFIELD(G.genital_flags, GENITAL_INTERNAL)) + if(!(G.genital_flags & GENITAL_INTERNAL)) genital_list += G if(!genital_list.len) //There is nothing to expose return @@ -145,6 +149,9 @@ else to_chat(src,"You can't make that genital [picked_organ.aroused_state ? "unaroused" : "aroused"]!") picked_organ.update_appearance() + if(ishuman(src)) + var/mob/living/carbon/human/human = src + human.update_genitals() return @@ -225,6 +232,8 @@ give_genital(/obj/item/organ/genital/breasts) if(dna.features["has_cock"]) give_genital(/obj/item/organ/genital/penis) + if(dna.features["has_butt"]) + give_genital(/obj/item/organ/genital/butt) /mob/living/carbon/human/proc/give_genital(obj/item/organ/genital/G) if(!dna || (NOGENITALS in dna.species.species_traits) || getorganslot(initial(G.slot))) @@ -282,6 +291,8 @@ S = GLOB.vagina_shapes_list[G.shape] if(/obj/item/organ/genital/breasts) S = GLOB.breasts_shapes_list[G.shape] + if(/obj/item/organ/genital/butt) + S = GLOB.butt_shapes_list[G.shape] if(!S || S.icon_state == "none") continue @@ -314,6 +325,8 @@ genital_overlay.color = "#[dna.features["breasts_color"]]" if("vag_color") genital_overlay.color = "#[dna.features["vag_color"]]" + if("butt_color") + genital_overlay.color = "#[dna.features["butt_color"]]" genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size][(dna.species.use_skintones && !dna.skin_tone_override) ? "_s" : ""]_[aroused_state]_[layertext]" @@ -343,20 +356,30 @@ var/organCheck = locate(/obj/item/organ/genital) in internal_organs var/breastCheck = getorganslot(ORGAN_SLOT_BREASTS) var/willyCheck = getorganslot(ORGAN_SLOT_PENIS) + var/buttCheck = getorganslot(ORGAN_SLOT_BUTT) + var/ballCheck = getorganslot(ORGAN_SLOT_TESTICLES) if(organCheck == FALSE) if(ishuman(src) && dna.species.use_skintones) dna.features["genitals_use_skintone"] = TRUE - if(src.dna.species.fixed_mut_color) + if(dna.species.fixed_mut_color) dna.features["cock_color"] = "[dna.species.fixed_mut_color]" dna.features["breasts_color"] = "[dna.species.fixed_mut_color]" + dna.features["butt_color"] = "[dna.species.fixed_mut_color]" + dna.features["testicles_color"] = "[dna.species.fixed_mut_color]" return //So people who haven't set stuff up don't get rainbow surprises. dna.features["cock_color"] = "[dna.features["mcolor"]]" dna.features["breasts_color"] = "[dna.features["mcolor"]]" + dna.features["butt_color"] = "[dna.features["mcolor"]]" + dna.features["testicles_color"] = "[dna.features["mcolor"]]" else //If there's a new organ, make it the same colour. if(breastCheck == FALSE) dna.features["breasts_color"] = dna.features["cock_color"] else if (willyCheck == FALSE) dna.features["cock_color"] = dna.features["breasts_color"] + else if (buttCheck == FALSE) + dna.features["butt_color"] = dna.features["butt_color"] + else if (ballCheck == FALSE) + dna.features["testicles_color"] = dna.features["testicles_color"] return TRUE diff --git a/code/modules/arousal/genitals_sprite_accessories.dm b/code/modules/arousal/genitals_sprite_accessories.dm index 1140a1d3ec..65c71edb30 100644 --- a/code/modules/arousal/genitals_sprite_accessories.dm +++ b/code/modules/arousal/genitals_sprite_accessories.dm @@ -64,6 +64,10 @@ icon_state = "single" name = "Single" //Single as "single pair", for clarity. +/datum/sprite_accessory/testicles/hidden + icon_state = "hidden" + name = "Hidden" //not sure why these were missing, but I'm pretty certain people might want these. + //Vaginas /datum/sprite_accessory/vagina icon = 'icons/obj/genitals/vagina_onmob.dmi' @@ -119,3 +123,15 @@ /datum/sprite_accessory/breasts/sextuple icon_state = "sextuple" name = "Sextuple" + +//BUTT BE HERE +/datum/sprite_accessory/butt + icon = 'icons/obj/genitals/butt_onmob.dmi' + icon_state = "butt" + name = "butt" + color_src = "butt_color" + +//there literally shouldn't be any other ass types besides one because that'd be weird, this is just here to keep things consistent for the genital system. +/datum/sprite_accessory/butt/pair + icon_state = "pair" + name = "Pair" diff --git a/code/modules/arousal/organs/breasts.dm b/code/modules/arousal/organs/breasts.dm index e37224e401..b9129e28a1 100644 --- a/code/modules/arousal/organs/breasts.dm +++ b/code/modules/arousal/organs/breasts.dm @@ -48,7 +48,7 @@ else desc += " You estimate that they're [uppertext(size)]-cups." - if(CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION) && aroused_state) + if((genital_flags & GENITAL_FUID_PRODUCTION) && aroused_state) var/datum/reagent/R = GLOB.chemical_reagents_list[fluid_id] if(R) desc += " They're leaking [lowertext(R.name)]." @@ -115,7 +115,7 @@ size = D.features["breasts_size"] shape = D.features["breasts_shape"] if(!D.features["breasts_producing"]) - DISABLE_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION|CAN_CLIMAX_WITH|CAN_MASTURBATE_WITH) + genital_flags &= ~ (GENITAL_FUID_PRODUCTION|CAN_CLIMAX_WITH|CAN_MASTURBATE_WITH) if(!isnum(size)) cached_size = breast_values[size] else diff --git a/code/modules/arousal/organs/butt.dm b/code/modules/arousal/organs/butt.dm new file mode 100644 index 0000000000..6cb32488a5 --- /dev/null +++ b/code/modules/arousal/organs/butt.dm @@ -0,0 +1,86 @@ +/obj/item/organ/genital/butt + name = "butt" + desc = "You see a pair of asscheeks." + icon_state = "butt" + icon = 'icons/obj/genitals/butt.dmi' + zone = BODY_ZONE_PRECISE_GROIN + slot = ORGAN_SLOT_BUTT + w_class = 3 + size = 0 + var/size_name = "nonexistent" + shape = "Pair" //turn this into a default constant if for some inexplicable reason we get more than one butt type but I doubt it. + genital_flags = UPDATE_OWNER_APPEARANCE|GENITAL_UNDIES_HIDDEN + masturbation_verb = "massage" + var/size_cached = 0 + var/prev_size //former size value, to allow update_size() to early return should be there no significant changes. + layer_index = BUTT_LAYER_INDEX + +/obj/item/organ/genital/butt/modify_size(modifier, min = -INFINITY, max = BUTT_SIZE_MAX) + var/new_value = clamp(size_cached + modifier, min, max) + if(new_value == size_cached) + return + prev_size = size_cached + size_cached = new_value + size = round(size_cached) + update() + ..() + +/obj/item/organ/genital/butt/update_size()//wah + var/rounded_size = round(size) + if(size < 0)//I don't actually know what round() does to negative numbers, so to be safe!!fixed + if(owner) + to_chat(owner, "You feel your asscheeks shrink down to an ordinary size.") + QDEL_IN(src, 1) + return + + if(owner) //Because byond doesn't count from 0, I have to do this. + var/mob/living/carbon/human/H = owner + var/r_prev_size = round(prev_size) + if (rounded_size > r_prev_size) + to_chat(H, "Your buttcheeks [pick("swell up to", "flourish into", "expand into", "plump up into", "grow eagerly into", "amplify into")] a larger pair.") + else if (rounded_size < r_prev_size) + to_chat(H, "Your buttcheeks [pick("shrink down to", "decrease into", "wobble down into", "diminish into", "deflate into", "contracts into")] a smaller pair.") + + +/obj/item/organ/genital/butt/update_appearance() + var/lowershape = lowertext(shape) + + //Reflect the size of dat ass on examine. + switch(round(size)) + if(1) + size_name = "average" + if(2) + size_name = "sizable" + if(3) + size_name = "squeezable" + if(4) + size_name = "hefty" + if(5) + size_name = pick("massive","extreme","enormous","very generous","humongous","big bubbly","dummy thicc") + else + size_name = "nonexistent" + + desc = "You see a [lowershape] of [size_name] asscheeks." + + var/icon_size = size + icon_state = "butt_[lowershape]_[icon_size]" + if(owner) + if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"]) + if(ishuman(owner)) // Check before recasting type, although someone fucked up if you're not human AND have use_skintones somehow... + var/mob/living/carbon/human/H = owner // only human mobs have skin_tone, which we need. + color = SKINTONE2HEX(H.skin_tone) + if(!H.dna.skin_tone_override) + icon_state += "_s" + else + color = "#[owner.dna.features["butt_color"]]" + + +/obj/item/organ/genital/butt/get_features(mob/living/carbon/human/H) + var/datum/dna/D = H.dna + if(D.species.use_skintones && D.features["genitals_use_skintone"]) + color = SKINTONE2HEX(H.skin_tone) + else + color = "#[D.features["butt_color"]]" + size = D.features["butt_size"] + prev_size = size + toggle_visibility(D.features["butt_visibility"], FALSE) diff --git a/code/modules/arousal/toys/dildos.dm b/code/modules/arousal/toys/dildos.dm index 4de6877915..f80373140d 100644 --- a/code/modules/arousal/toys/dildos.dm +++ b/code/modules/arousal/toys/dildos.dm @@ -71,7 +71,7 @@ update_appearance() return TRUE -/obj/item/dildo/Initialize() +/obj/item/dildo/Initialize(mapload) . = ..() if(random_color == TRUE) var/randcolor = pick(GLOB.dildo_colors) diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index c50ca2f187..67844d50bf 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -34,14 +34,16 @@ /obj/item/assembly/proc/on_attach() -/obj/item/assembly/proc/on_detach() //call this when detaching it from a device. handles any special functions that need to be updated ex post facto +///Call this when detaching it from a device. handles any special functions that need to be updated ex post facto +/obj/item/assembly/proc/on_detach() if(!holder) return FALSE forceMove(holder.drop_location()) holder = null return TRUE -/obj/item/assembly/proc/holder_movement() //Called when the holder is moved +///Called when the holder is moved +/obj/item/assembly/proc/holder_movement() if(!holder) return FALSE setDir(holder.dir) @@ -53,7 +55,6 @@ return FALSE return TRUE - //Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs /obj/item/assembly/proc/pulsed(radio = FALSE) if(wire_type & WIRE_RECEIVE) @@ -62,7 +63,6 @@ INVOKE_ASYNC(src, .proc/activate) return TRUE - //Called when this device attempts to act on another device, var/radio determines if it was sent via radio or direct /obj/item/assembly/proc/pulse(radio = FALSE) if(connected && wire_type) @@ -74,7 +74,6 @@ holder.process_activation(src, 0, 1) return TRUE - // What the device does when turned on /obj/item/assembly/proc/activate() if(QDELETED(src) || !secured || (next_activate > world.time)) @@ -82,13 +81,11 @@ next_activate = world.time + activate_cooldown return TRUE - /obj/item/assembly/proc/toggle_secure() secured = !secured update_icon() return secured - /obj/item/assembly/attackby(obj/item/W, mob/user, params) if(isassembly(W)) var/obj/item/assembly/A = W @@ -115,7 +112,6 @@ . = ..() . += "\The [src] [secured? "is secured and ready to be used!" : "can be attached to other things."]" - /obj/item/assembly/attack_self(mob/user) if(!user) return FALSE @@ -125,3 +121,11 @@ /obj/item/assembly/interact(mob/user) return ui_interact(user) + +/obj/item/assembly/ui_host(mob/user) + if(holder) + return holder + return src + +/obj/item/assembly/ui_state(mob/user) + return GLOB.hands_state diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index 84e70bbbb3..f4f907ba2a 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -17,7 +17,6 @@ /obj/item/assembly_holder/IsAssemblyHolder() return TRUE - /obj/item/assembly_holder/proc/assemble(obj/item/assembly/A, obj/item/assembly/A2, mob/user) attach(A,user) attach(A2,user) @@ -32,6 +31,8 @@ else A.forceMove(src) A.holder = src + // bandaid: please don't try to be picked up while we're still in the assembly + A.interaction_flags_item &= ~INTERACT_ITEM_ATTACK_HAND_PICKUP A.toggle_secure() if(!a_left) a_left = A @@ -88,14 +89,14 @@ if(a_right) a_right.dropped(user) -/obj/item/assembly_holder/on_attack_hand()//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess +/obj/item/assembly_holder/on_attack_hand(user, act_intent)//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess . = ..() if(.) return if(a_left) - a_left.attack_hand() + a_left.attack_hand(user, act_intent) if(a_right) - a_right.attack_hand() + a_right.attack_hand(user, act_intent) /obj/item/assembly_holder/screwdriver_act(mob/user, obj/item/tool) if(..()) @@ -103,9 +104,11 @@ to_chat(user, "You disassemble [src]!") if(a_left) a_left.on_detach() + a_left.interaction_flags_item |= INTERACT_ITEM_ATTACK_HAND_PICKUP a_left = null if(a_right) a_right.on_detach() + a_right.interaction_flags_item |= INTERACT_ITEM_ATTACK_HAND_PICKUP a_right = null qdel(src) return TRUE diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index d0ed0f2436..6e1d7b60f6 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -12,7 +12,7 @@ var/turf/listeningTo var/hearing_range = 3 -/obj/item/assembly/infra/Initialize() +/obj/item/assembly/infra/Initialize(mapload) . = ..() beams = list() START_PROCESSING(SSobj, src) @@ -220,7 +220,8 @@ icon_state = "ibeam" anchored = TRUE density = FALSE - pass_flags = PASSTABLE|PASSGLASS|PASSGRILLE|LETPASSTHROW + pass_flags = PASSTABLE|PASSGLASS|PASSGRILLE + pass_flags_self = LETPASSTHROW var/obj/item/assembly/infra/master /obj/effect/beam/i_beam/Crossed(atom/movable/AM as mob|obj) diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index 60de1b3e87..49f912dff2 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -10,7 +10,7 @@ var/sensitivity = 1 var/hearing_range = 3 -/obj/item/assembly/prox_sensor/Initialize() +/obj/item/assembly/prox_sensor/Initialize(mapload) . = ..() proximity_monitor = new(src, 0) START_PROCESSING(SSobj, src) diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index e586f97a28..a4700e4f16 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -41,7 +41,7 @@ playsound(user, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE) qdel(src) -/obj/item/assembly/signaler/Initialize() +/obj/item/assembly/signaler/Initialize(mapload) . = ..() set_frequency(frequency) diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index e06bb22b0b..0234ac43df 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -22,7 +22,7 @@ user.adjustOxyLoss(200) user.death(0) -/obj/item/assembly/timer/Initialize() +/obj/item/assembly/timer/Initialize(mapload) . = ..() START_PROCESSING(SSobj, src) diff --git a/code/modules/asset_cache/asset_list.dm b/code/modules/asset_cache/asset_list.dm index 221febbe14..f88f57eacc 100644 --- a/code/modules/asset_cache/asset_list.dm +++ b/code/modules/asset_cache/asset_list.dm @@ -11,6 +11,7 @@ GLOBAL_LIST_EMPTY(asset_datums) /datum/asset var/_abstract = /datum/asset + var/cached_url_mappings /datum/asset/New() GLOB.asset_datums[type] = src @@ -19,6 +20,13 @@ GLOBAL_LIST_EMPTY(asset_datums) /datum/asset/proc/get_url_mappings() return list() +/// Returns a cached tgui message of URL mappings +/datum/asset/proc/get_serialized_url_mappings() + if (isnull(cached_url_mappings)) + cached_url_mappings = TGUI_CREATE_MESSAGE("asset/mappings", get_url_mappings()) + + return cached_url_mappings + /datum/asset/proc/register() return @@ -169,6 +177,8 @@ GLOBAL_LIST_EMPTY(asset_datums) I = icon(I, icon_state=icon_state, dir=dir, frame=frame, moving=moving) if (!I || !length(icon_states(I))) // that direction or state doesn't exist return + //any sprite modifications we want to do (aka, coloring a greyscaled asset) + I = ModifyInserted(I) var/size_id = "[I.Width()]x[I.Height()]" var/size = sizes[size_id] @@ -185,6 +195,15 @@ GLOBAL_LIST_EMPTY(asset_datums) sizes[size_id] = size = list(1, I, null) sprites[sprite_name] = list(size_id, 0) +/** + * A simple proc handing the Icon for you to modify before it gets turned into an asset. + * + * Arguments: + * * I: icon being turned into an asset + */ +/datum/asset/spritesheet/proc/ModifyInserted(icon/pre_asset) + return pre_asset + /datum/asset/spritesheet/proc/InsertAll(prefix, icon/I, list/directions) if (length(prefix)) prefix = "[prefix]-" @@ -217,6 +236,19 @@ GLOBAL_LIST_EMPTY(asset_datums) var/size_id = sprite[SPR_SIZE] return {"[name][size_id] [sprite_name]"} +/** + * Returns the size class (ex design32x32) for a given sprite's icon + * + * Arguments: + * * sprite_name - The sprite to get the size of + */ +/datum/asset/spritesheet/proc/icon_size_id(sprite_name) + var/sprite = sprites[sprite_name] + if (!sprite) + return null + var/size_id = sprite[SPR_SIZE] + return "[name][size_id]" + #undef SPR_SIZE #undef SPR_IDX #undef SPRSZ_COUNT @@ -224,6 +256,24 @@ GLOBAL_LIST_EMPTY(asset_datums) #undef SPRSZ_STRIPPED +/datum/asset/changelog_item + _abstract = /datum/asset/changelog_item + var/item_filename + +/datum/asset/changelog_item/New(date) + item_filename = sanitize_filename("[date].yml") + SSassets.transport.register_asset(item_filename, file("html/changelogs/archive/" + item_filename)) + +/datum/asset/changelog_item/send(client) + if (!item_filename) + return + . = SSassets.transport.send_assets(client, item_filename) + +/datum/asset/changelog_item/get_url_mappings() + if (!item_filename) + return + . = list("[item_filename]" = SSassets.transport.get_asset_url(item_filename)) + /datum/asset/spritesheet/simple _abstract = /datum/asset/spritesheet/simple var/list/assets diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm index 6a49addc13..be6850a7f7 100644 --- a/code/modules/asset_cache/asset_list_items.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -1,23 +1,17 @@ //DEFINITIONS FOR ASSET DATUMS START HERE. -/datum/asset/simple/tgui_common - keep_local_name = TRUE - assets = list( - "tgui-common.bundle.js" = 'tgui/public/tgui-common.bundle.js', - ) - /datum/asset/simple/tgui keep_local_name = TRUE assets = list( - "tgui.bundle.js" = 'tgui/public/tgui.bundle.js', - "tgui.bundle.css" = 'tgui/public/tgui.bundle.css', + "tgui.bundle.js" = file("tgui/public/tgui.bundle.js"), + "tgui.bundle.css" = file("tgui/public/tgui.bundle.css"), ) /datum/asset/simple/tgui_panel keep_local_name = TRUE assets = list( - "tgui-panel.bundle.js" = 'tgui/public/tgui-panel.bundle.js', - "tgui-panel.bundle.css" = 'tgui/public/tgui-panel.bundle.css', + "tgui-panel.bundle.js" = file("tgui/public/tgui-panel.bundle.js"), + "tgui-panel.bundle.css" = file("tgui/public/tgui-panel.bundle.css"), ) /datum/asset/simple/headers @@ -54,9 +48,14 @@ /datum/asset/simple/radar_assets assets = list( - "ntosradarbackground.png" = 'icons/UI_Icons/tgui/ntosradar_background.png', - "ntosradarpointer.png" = 'icons/UI_Icons/tgui/ntosradar_pointer.png', - "ntosradarpointerS.png" = 'icons/UI_Icons/tgui/ntosradar_pointer_S.png' + "ntosradarbackground.png" = 'icons/ui_icons/tgui/ntosradar_background.png', + "ntosradarpointer.png" = 'icons/ui_icons/tgui/ntosradar_pointer.png', + "ntosradarpointerS.png" = 'icons/ui_icons/tgui/ntosradar_pointer_S.png' + ) + +/datum/asset/simple/circuit_assets + assets = list( + "grid_background.png" = 'icons/ui_icons/tgui/grid_background.png' ) /datum/asset/spritesheet/simple/pda @@ -91,6 +90,7 @@ "status" = 'icons/pda_icons/pda_status.png', "dronephone" = 'icons/pda_icons/pda_dronephone.png', "emoji" = 'icons/pda_icons/pda_emoji.png' + // "droneblacklist" = 'icons/pda_icons/pda_droneblacklist.png', ) /datum/asset/spritesheet/simple/paper @@ -116,7 +116,7 @@ /datum/asset/simple/irv assets = list( - "jquery-ui.custom-core-widgit-mouse-sortable-min.js" = 'html/IRV/jquery-ui.custom-core-widgit-mouse-sortable-min.js', + "jquery-ui.custom-core-widgit-mouse-sortable-min.js" = 'html/jquery/jquery-ui.custom-core-widgit-mouse-sortable.min.js', ) /datum/asset/group/irv @@ -125,35 +125,10 @@ /datum/asset/simple/irv ) -/datum/asset/simple/namespaced/changelog - assets = list( - "88x31.png" = 'html/88x31.png', - "bug-minus.png" = 'html/bug-minus.png', - "cross-circle.png" = 'html/cross-circle.png', - "hard-hat-exclamation.png" = 'html/hard-hat-exclamation.png', - "image-minus.png" = 'html/image-minus.png', - "image-plus.png" = 'html/image-plus.png', - "music-minus.png" = 'html/music-minus.png', - "music-plus.png" = 'html/music-plus.png', - "tick-circle.png" = 'html/tick-circle.png', - "wrench-screwdriver.png" = 'html/wrench-screwdriver.png', - "spell-check.png" = 'html/spell-check.png', - "burn-exclamation.png" = 'html/burn-exclamation.png', - "chevron.png" = 'html/chevron.png', - "chevron-expand.png" = 'html/chevron-expand.png', - "scales.png" = 'html/scales.png', - "coding.png" = 'html/coding.png', - "ban.png" = 'html/ban.png', - "chrome-wrench.png" = 'html/chrome-wrench.png', - "changelog.css" = 'html/changelog.css' - ) - parents = list("changelog.html" = 'html/changelog.html') - - /datum/asset/simple/jquery legacy = TRUE assets = list( - "jquery.min.js" = 'html/jquery.min.js', + "jquery.min.js" = 'html/jquery/jquery.min.js', ) /datum/asset/simple/namespaced/fontawesome @@ -168,10 +143,12 @@ /datum/asset/simple/namespaced/tgfont assets = list( - "tgfont.eot" = 'tgui/packages/tgfont/dist/tgfont.eot', - "tgfont.woff2" = 'tgui/packages/tgfont/dist/tgfont.woff2', + "tgfont.eot" = file("tgui/packages/tgfont/dist/tgfont.eot"), + "tgfont.woff2" = file("tgui/packages/tgfont/dist/tgfont.woff2"), + ) + parents = list( + "tgfont.css" = file("tgui/packages/tgfont/dist/tgfont.css"), ) - parents = list("tgfont.css" = 'tgui/packages/tgfont/dist/tgfont.css') /datum/asset/spritesheet/chat name = "chat" @@ -221,120 +198,102 @@ /datum/asset/simple/arcade assets = list( - "boss1.gif" = 'icons/UI_Icons/Arcade/boss1.gif', - "boss2.gif" = 'icons/UI_Icons/Arcade/boss2.gif', - "boss3.gif" = 'icons/UI_Icons/Arcade/boss3.gif', - "boss4.gif" = 'icons/UI_Icons/Arcade/boss4.gif', - "boss5.gif" = 'icons/UI_Icons/Arcade/boss5.gif', - "boss6.gif" = 'icons/UI_Icons/Arcade/boss6.gif', + "boss1.gif" = 'icons/ui_icons/arcade/boss1.gif', + "boss2.gif" = 'icons/ui_icons/arcade/boss2.gif', + "boss3.gif" = 'icons/ui_icons/arcade/boss3.gif', + "boss4.gif" = 'icons/ui_icons/arcade/boss4.gif', + "boss5.gif" = 'icons/ui_icons/arcade/boss5.gif', + "boss6.gif" = 'icons/ui_icons/arcade/boss6.gif', ) /datum/asset/spritesheet/simple/achievements name ="achievements" assets = list( - "default" = 'icons/UI_Icons/Achievements/default.png', - "basemisc" = 'icons/UI_Icons/Achievements/basemisc.png', - "baseboss" = 'icons/UI_Icons/Achievements/baseboss.png', - "baseskill" = 'icons/UI_Icons/Achievements/baseskill.png', - "bbgum" = 'icons/UI_Icons/Achievements/Boss/bbgum.png', - "colossus" = 'icons/UI_Icons/Achievements/Boss/colossus.png', - "hierophant" = 'icons/UI_Icons/Achievements/Boss/hierophant.png', - "drake" = 'icons/UI_Icons/Achievements/Boss/drake.png', - "legion" = 'icons/UI_Icons/Achievements/Boss/legion.png', - "miner" = 'icons/UI_Icons/Achievements/Boss/miner.png', - "swarmer" = 'icons/UI_Icons/Achievements/Boss/swarmer.png', - "tendril" = 'icons/UI_Icons/Achievements/Boss/tendril.png', - "featofstrength" = 'icons/UI_Icons/Achievements/Misc/featofstrength.png', - "helbital" = 'icons/UI_Icons/Achievements/Misc/helbital.png', - "jackpot" = 'icons/UI_Icons/Achievements/Misc/jackpot.png', - "meteors" = 'icons/UI_Icons/Achievements/Misc/meteors.png', - "timewaste" = 'icons/UI_Icons/Achievements/Misc/timewaste.png', - "upgrade" = 'icons/UI_Icons/Achievements/Misc/upgrade.png', - "clownking" = 'icons/UI_Icons/Achievements/Misc/clownking.png', - "clownthanks" = 'icons/UI_Icons/Achievements/Misc/clownthanks.png', - "rule8" = 'icons/UI_Icons/Achievements/Misc/rule8.png', - "longshift" = 'icons/UI_Icons/Achievements/Misc/longshift.png', - "snail" = 'icons/UI_Icons/Achievements/Misc/snail.png', - "ascension" = 'icons/UI_Icons/Achievements/Misc/ascension.png', - "ashascend" = 'icons/UI_Icons/Achievements/Misc/ashascend.png', - "fleshascend" = 'icons/UI_Icons/Achievements/Misc/fleshascend.png', - "rustascend" = 'icons/UI_Icons/Achievements/Misc/rustascend.png', - "voidascend" = 'icons/UI_Icons/Achievements/Misc/voidascend.png', - "toolbox_soul" = 'icons/UI_Icons/Achievements/Misc/toolbox_soul.png', - "chem_tut" = 'icons/UI_Icons/Achievements/Misc/chem_tut.png', - "mining" = 'icons/UI_Icons/Achievements/Skills/mining.png', - "mafia" = 'icons/UI_Icons/Achievements/Mafia/mafia.png', - "town" = 'icons/UI_Icons/Achievements/Mafia/town.png', - "neutral" = 'icons/UI_Icons/Achievements/Mafia/neutral.png', - "hated" = 'icons/UI_Icons/Achievements/Mafia/hated.png', - "basemafia" ='icons/UI_Icons/Achievements/basemafia.png', - "frenching" = 'icons/UI_Icons/Achievements/Misc/frenchingthebubble.png' - ) - -/datum/asset/spritesheet/simple/minesweeper - name = "minesweeper" - assets = list( - "1" = 'icons/UI_Icons/minesweeper_tiles/one.png', - "2" = 'icons/UI_Icons/minesweeper_tiles/two.png', - "3" = 'icons/UI_Icons/minesweeper_tiles/three.png', - "4" = 'icons/UI_Icons/minesweeper_tiles/four.png', - "5" = 'icons/UI_Icons/minesweeper_tiles/five.png', - "6" = 'icons/UI_Icons/minesweeper_tiles/six.png', - "7" = 'icons/UI_Icons/minesweeper_tiles/seven.png', - "8" = 'icons/UI_Icons/minesweeper_tiles/eight.png', - "empty" = 'icons/UI_Icons/minesweeper_tiles/empty.png', - "flag" = 'icons/UI_Icons/minesweeper_tiles/flag.png', - "hidden" = 'icons/UI_Icons/minesweeper_tiles/hidden.png', - "mine" = 'icons/UI_Icons/minesweeper_tiles/mine.png', - "minehit" = 'icons/UI_Icons/minesweeper_tiles/minehit.png' + "default" = 'icons/ui_icons/achievements/default.png', + "basemisc" = 'icons/ui_icons/achievements/basemisc.png', + "baseboss" = 'icons/ui_icons/achievements/baseboss.png', + "baseskill" = 'icons/ui_icons/achievements/baseskill.png', + "bbgum" = 'icons/ui_icons/achievements/Boss/bbgum.png', + "colossus" = 'icons/ui_icons/achievements/Boss/colossus.png', + "hierophant" = 'icons/ui_icons/achievements/Boss/hierophant.png', + "drake" = 'icons/ui_icons/achievements/Boss/drake.png', + "legion" = 'icons/ui_icons/achievements/Boss/legion.png', + "miner" = 'icons/ui_icons/achievements/Boss/miner.png', + "swarmer" = 'icons/ui_icons/achievements/Boss/swarmer.png', + "tendril" = 'icons/ui_icons/achievements/Boss/tendril.png', + "featofstrength" = 'icons/ui_icons/achievements/Misc/featofstrength.png', + "helbital" = 'icons/ui_icons/achievements/Misc/helbital.png', + "jackpot" = 'icons/ui_icons/achievements/Misc/jackpot.png', + "meteors" = 'icons/ui_icons/achievements/Misc/meteors.png', + "timewaste" = 'icons/ui_icons/achievements/Misc/timewaste.png', + "upgrade" = 'icons/ui_icons/achievements/Misc/upgrade.png', + "clownking" = 'icons/ui_icons/achievements/Misc/clownking.png', + "clownthanks" = 'icons/ui_icons/achievements/Misc/clownthanks.png', + "rule8" = 'icons/ui_icons/achievements/Misc/rule8.png', + "longshift" = 'icons/ui_icons/achievements/Misc/longshift.png', + "snail" = 'icons/ui_icons/achievements/Misc/snail.png', + "ascension" = 'icons/ui_icons/achievements/Misc/ascension.png', + "ashascend" = 'icons/ui_icons/achievements/Misc/ashascend.png', + "fleshascend" = 'icons/ui_icons/achievements/Misc/fleshascend.png', + "rustascend" = 'icons/ui_icons/achievements/Misc/rustascend.png', + "voidascend" = 'icons/ui_icons/achievements/Misc/voidascend.png', + "toolbox_soul" = 'icons/ui_icons/achievements/Misc/toolbox_soul.png', + "chem_tut" = 'icons/ui_icons/achievements/Misc/chem_tut.png', + "mining" = 'icons/ui_icons/achievements/Skills/mining.png', + "mafia" = 'icons/ui_icons/achievements/Mafia/mafia.png', + "town" = 'icons/ui_icons/achievements/Mafia/town.png', + "neutral" = 'icons/ui_icons/achievements/Mafia/neutral.png', + "hated" = 'icons/ui_icons/achievements/Mafia/hated.png', + "basemafia" ='icons/ui_icons/achievements/basemafia.png', + "frenching" = 'icons/ui_icons/achievements/Misc/frenchingthebubble.png' ) /datum/asset/spritesheet/simple/pills name = "pills" assets = list( - "pill1" = 'icons/UI_Icons/Pills/pill1.png', - "pill2" = 'icons/UI_Icons/Pills/pill2.png', - "pill3" = 'icons/UI_Icons/Pills/pill3.png', - "pill4" = 'icons/UI_Icons/Pills/pill4.png', - "pill5" = 'icons/UI_Icons/Pills/pill5.png', - "pill6" = 'icons/UI_Icons/Pills/pill6.png', - "pill7" = 'icons/UI_Icons/Pills/pill7.png', - "pill8" = 'icons/UI_Icons/Pills/pill8.png', - "pill9" = 'icons/UI_Icons/Pills/pill9.png', - "pill10" = 'icons/UI_Icons/Pills/pill10.png', - "pill11" = 'icons/UI_Icons/Pills/pill11.png', - "pill12" = 'icons/UI_Icons/Pills/pill12.png', - "pill13" = 'icons/UI_Icons/Pills/pill13.png', - "pill14" = 'icons/UI_Icons/Pills/pill14.png', - "pill15" = 'icons/UI_Icons/Pills/pill15.png', - "pill16" = 'icons/UI_Icons/Pills/pill16.png', - "pill17" = 'icons/UI_Icons/Pills/pill17.png', - "pill18" = 'icons/UI_Icons/Pills/pill18.png', - "pill19" = 'icons/UI_Icons/Pills/pill19.png', - "pill20" = 'icons/UI_Icons/Pills/pill20.png', - "pill21" = 'icons/UI_Icons/Pills/pill21.png', - "pill22" = 'icons/UI_Icons/Pills/pill22.png', + "pill1" = 'icons/ui_icons/pills/pill1.png', + "pill2" = 'icons/ui_icons/pills/pill2.png', + "pill3" = 'icons/ui_icons/pills/pill3.png', + "pill4" = 'icons/ui_icons/pills/pill4.png', + "pill5" = 'icons/ui_icons/pills/pill5.png', + "pill6" = 'icons/ui_icons/pills/pill6.png', + "pill7" = 'icons/ui_icons/pills/pill7.png', + "pill8" = 'icons/ui_icons/pills/pill8.png', + "pill9" = 'icons/ui_icons/pills/pill9.png', + "pill10" = 'icons/ui_icons/pills/pill10.png', + "pill11" = 'icons/ui_icons/pills/pill11.png', + "pill12" = 'icons/ui_icons/pills/pill12.png', + "pill13" = 'icons/ui_icons/pills/pill13.png', + "pill14" = 'icons/ui_icons/pills/pill14.png', + "pill15" = 'icons/ui_icons/pills/pill15.png', + "pill16" = 'icons/ui_icons/pills/pill16.png', + "pill17" = 'icons/ui_icons/pills/pill17.png', + "pill18" = 'icons/ui_icons/pills/pill18.png', + "pill19" = 'icons/ui_icons/pills/pill19.png', + "pill20" = 'icons/ui_icons/pills/pill20.png', + "pill21" = 'icons/ui_icons/pills/pill21.png', + "pill22" = 'icons/ui_icons/pills/pill22.png', ) // /datum/asset/spritesheet/simple/condiments // name = "condiments" // assets = list( -// CONDIMASTER_STYLE_FALLBACK = 'icons/UI_Icons/Condiments/emptycondiment.png', -// "enzyme" = 'icons/UI_Icons/Condiments/enzyme.png', -// "flour" = 'icons/UI_Icons/Condiments/flour.png', -// "mayonnaise" = 'icons/UI_Icons/Condiments/mayonnaise.png', -// "milk" = 'icons/UI_Icons/Condiments/milk.png', -// "blackpepper" = 'icons/UI_Icons/Condiments/peppermillsmall.png', -// "rice" = 'icons/UI_Icons/Condiments/rice.png', -// "sodiumchloride" = 'icons/UI_Icons/Condiments/saltshakersmall.png', -// "soymilk" = 'icons/UI_Icons/Condiments/soymilk.png', -// "soysauce" = 'icons/UI_Icons/Condiments/soysauce.png', -// "sugar" = 'icons/UI_Icons/Condiments/sugar.png', -// "ketchup" = 'icons/UI_Icons/Condiments/ketchup.png', -// "capsaicin" = 'icons/UI_Icons/Condiments/hotsauce.png', -// "frostoil" = 'icons/UI_Icons/Condiments/coldsauce.png', -// "bbqsauce" = 'icons/UI_Icons/Condiments/bbqsauce.png', -// "cornoil" = 'icons/UI_Icons/Condiments/oliveoil.png', +// CONDIMASTER_STYLE_FALLBACK = 'icons/ui_icons/condiments/emptycondiment.png', +// "enzyme" = 'icons/ui_icons/condiments/enzyme.png', +// "flour" = 'icons/ui_icons/condiments/flour.png', +// "mayonnaise" = 'icons/ui_icons/condiments/mayonnaise.png', +// "milk" = 'icons/ui_icons/condiments/milk.png', +// "blackpepper" = 'icons/ui_icons/condiments/peppermillsmall.png', +// "rice" = 'icons/ui_icons/condiments/rice.png', +// "sodiumchloride" = 'icons/ui_icons/condiments/saltshakersmall.png', +// "soymilk" = 'icons/ui_icons/condiments/soymilk.png', +// "soysauce" = 'icons/ui_icons/condiments/soysauce.png', +// "sugar" = 'icons/ui_icons/condiments/sugar.png', +// "ketchup" = 'icons/ui_icons/condiments/ketchup.png', +// "capsaicin" = 'icons/ui_icons/condiments/hotsauce.png', +// "frostoil" = 'icons/ui_icons/condiments/coldsauce.png', +// "bbqsauce" = 'icons/ui_icons/condiments/bbqsauce.png', +// "cornoil" = 'icons/ui_icons/condiments/oliveoil.png', // ) //this exists purely to avoid meta by pre-loading all language icons. @@ -352,14 +311,6 @@ InsertAll("", each, GLOB.alldirs) ..() -/datum/asset/spritesheet/decals - name = "decals" - -/datum/asset/spritesheet/decals/register() - for(var/each in list('icons/turf/decals.dmi')) - InsertAll("", each, GLOB.alldirs) - ..() - /datum/asset/spritesheet/supplypods name = "supplypods" @@ -426,9 +377,15 @@ if (machine) item = machine + // Check for GAGS support where necessary + // var/greyscale_config = initial(item.greyscale_config) + // var/greyscale_colors = initial(item.greyscale_colors) + // if (greyscale_config && greyscale_colors) + // icon_file = SSgreyscale.GetColoredIconByType(greyscale_config, greyscale_colors) + // else icon_file = initial(item.icon) - icon_state = initial(item.icon_state) + icon_state = initial(item.icon_state) if(!(icon_state in icon_states(icon_file))) warning("design [D] with icon '[icon_file]' missing state '[icon_state]'") continue @@ -457,7 +414,11 @@ if (!ispath(item, /atom)) continue - var/icon_file = initial(item.icon) + var/icon_file + // if (initial(item.greyscale_colors) && initial(item.greyscale_config)) + // icon_file = SSgreyscale.GetColoredIconByType(initial(item.greyscale_config), initial(item.greyscale_colors)) + // else + icon_file = initial(item.icon) var/icon_state = initial(item.icon_state) var/icon/I @@ -559,6 +520,35 @@ // Insert(id, fish_icon, fish_icon_state) // ..() +/datum/asset/simple/adventure + assets = list( + "default" = 'icons/ui_icons/adventure/default.png', + "grue" = 'icons/ui_icons/adventure/grue.png', + "signal_lost" ='icons/ui_icons/adventure/signal_lost.png', + "trade" = 'icons/ui_icons/adventure/trade.png', + ) + +/datum/asset/simple/inventory + assets = list( + "inventory-glasses.png" = 'icons/ui_icons/inventory/glasses.png', + "inventory-head.png" = 'icons/ui_icons/inventory/head.png', + "inventory-neck.png" = 'icons/ui_icons/inventory/neck.png', + "inventory-mask.png" = 'icons/ui_icons/inventory/mask.png', + "inventory-ears.png" = 'icons/ui_icons/inventory/ears.png', + "inventory-uniform.png" = 'icons/ui_icons/inventory/uniform.png', + "inventory-suit.png" = 'icons/ui_icons/inventory/suit.png', + "inventory-gloves.png" = 'icons/ui_icons/inventory/gloves.png', + "inventory-hand_l.png" = 'icons/ui_icons/inventory/hand_l.png', + "inventory-hand_r.png" = 'icons/ui_icons/inventory/hand_r.png', + "inventory-shoes.png" = 'icons/ui_icons/inventory/shoes.png', + "inventory-suit_storage.png" = 'icons/ui_icons/inventory/suit_storage.png', + "inventory-id.png" = 'icons/ui_icons/inventory/id.png', + "inventory-belt.png" = 'icons/ui_icons/inventory/belt.png', + "inventory-back.png" = 'icons/ui_icons/inventory/back.png', + "inventory-pocket.png" = 'icons/ui_icons/inventory/pocket.png', + "inventory-collar.png" = 'icons/ui_icons/inventory/collar.png', + ) + /// Removes all non-alphanumerics from the text, keep in mind this can lead to id conflicts /proc/sanitize_css_class_name(name) var/static/regex/regex = new(@"[^a-zA-Z0-9]","g") @@ -566,5 +556,41 @@ /datum/asset/simple/tutorial_advisors assets = list( - "chem_help_advisor.gif" = 'icons/UI_Icons/Advisors/chem_help_advisor.gif', + "chem_help_advisor.gif" = 'icons/ui_icons/advisors/chem_help_advisor.gif', ) + +// /datum/asset/spritesheet/moods +// name = "moods" +// var/iconinserted = 1 + +// /datum/asset/spritesheet/moods/register() +// for(var/i in 1 to 9) +// var/target_to_insert = "mood"+"[iconinserted]" +// Insert(target_to_insert, 'icons/hud/screen_gen.dmi', target_to_insert) +// iconinserted++ +// ..() + +// /datum/asset/spritesheet/moods/ModifyInserted(icon/pre_asset) +// var/blended_color +// switch(iconinserted) +// if(1) +// blended_color = "#f15d36" +// if(2 to 3) +// blended_color = "#f38943" +// if(4) +// blended_color = "#dfa65b" +// if(5) +// blended_color = "#4b96c4" +// if(6) +// blended_color = "#86d656" +// else +// blended_color = "#2eeb9a" +// pre_asset.Blend(blended_color, ICON_MULTIPLY) +// return pre_asset + +/datum/asset/spritesheet/jobs + name = "jobs" + +/datum/asset/spritesheet/jobs/register() + InsertAll("", 'icons/UI_Icons/tgui/jobs.dmi') + ..() diff --git a/code/modules/asset_cache/transports/asset_transport.dm b/code/modules/asset_cache/transports/asset_transport.dm index f5a1af4f05..b2da2602ae 100644 --- a/code/modules/asset_cache/transports/asset_transport.dm +++ b/code/modules/asset_cache/transports/asset_transport.dm @@ -115,7 +115,7 @@ if (unreceived.len) if (unreceived.len >= ASSET_CACHE_TELL_CLIENT_AMOUNT) - to_chat(client, "Sending Resources...") + to_chat(client, "Sending Resources...") for (var/asset_name in unreceived) var/new_asset_name = asset_name diff --git a/code/modules/atmospherics/auxgm/breathing_classes.dm b/code/modules/atmospherics/auxgm/breathing_classes.dm index 4abfab58ee..6d5c4fde9b 100644 --- a/code/modules/atmospherics/auxgm/breathing_classes.dm +++ b/code/modules/atmospherics/auxgm/breathing_classes.dm @@ -14,6 +14,12 @@ var/high_alert_category = "too_much_oxy" var/high_alert_datum = /atom/movable/screen/alert/too_much_oxy +/datum/breathing_class/proc/get_effective_pp(datum/gas_mixture/breath) + var/mol = 0 + for(var/gas in gases) + mol += breath.get_moles(gas) * gases[gas] + return (mol/breath.total_moles()) * breath.return_pressure() + /datum/breathing_class/oxygen gases = list( GAS_O2 = 1, @@ -35,3 +41,18 @@ low_alert_datum = /atom/movable/screen/alert/not_enough_tox high_alert_category = "too_much_tox" high_alert_datum = /atom/movable/screen/alert/too_much_tox + +/datum/breathing_class/methane + gases = list( + GAS_METHANE = 1, + GAS_METHYL_BROMIDE = -0.7, + GAS_O2 = -0.1, + GAS_PLUOXIUM = -0.8 + ) + products = list( + GAS_METHYL_BROMIDE = 1 + ) + low_alert_category = "not_enough_ch4" + low_alert_datum = /atom/movable/screen/alert/not_enough_ch4 + high_alert_category = "too_much_ch4" + high_alert_datum = /atom/movable/screen/alert/too_much_ch4 diff --git a/code/modules/atmospherics/auxgm/gas_types.dm b/code/modules/atmospherics/auxgm/gas_types.dm index 6d30d7ed92..828af0e8ea 100644 --- a/code/modules/atmospherics/auxgm/gas_types.dm +++ b/code/modules/atmospherics/auxgm/gas_types.dm @@ -7,12 +7,18 @@ heat_penalty = 1 transmit_modifier = 1.5 +/datum/gas/oxygen/generate_TLV() + return new/datum/tlv(16, 19, 40, 50) + /datum/gas/nitrogen id = GAS_N2 specific_heat = 20 name = "Nitrogen" powermix = -1 heat_penalty = -1.5 + fire_burn_rate = 1 + fire_temperature = 2300 + fire_products = list(GAS_NITRIC = 2) breath_alert_info = list( not_enough_alert = list( alert_category = "not_enough_nitro", @@ -43,6 +49,10 @@ ) ) fusion_power = 3 + enthalpy = -393500 + +/datum/gas/carbon_dioxide/generate_TLV() + return new/datum/tlv(-1, -1, 5, 10) /datum/gas/plasma id = GAS_PLASMA @@ -54,25 +64,10 @@ heat_penalty = 15 transmit_modifier = 4 powermix = 1 - // no fire info cause it has its own bespoke reaction for trit generation reasons - -/datum/gas/water_vapor - id = GAS_H2O - specific_heat = 40 - name = "Water Vapor" - gas_overlay = "water_vapor" - moles_visible = MOLES_GAS_VISIBLE - fusion_power = 8 - heat_penalty = 8 - powermix = 1 - breath_reagent = /datum/reagent/water - -/datum/gas/hypernoblium - id = GAS_HYPERNOB - specific_heat = 2000 - name = "Hyper-noblium" - gas_overlay = "freon" - moles_visible = MOLES_GAS_VISIBLE + fire_burn_rate = OXYGEN_BURN_RATE_BASE // named when plasma fires were the only fires, surely + fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + fire_products = FIRE_PRODUCT_PLASMA + enthalpy = FIRE_PLASMA_ENERGY_RELEASED // 3000000, 3 megajoules, 3000 kj /datum/gas/nitrous_oxide id = GAS_NITROUS @@ -84,18 +79,39 @@ fire_products = list(GAS_N2 = 1) oxidation_rate = 0.5 oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 100 + enthalpy = 81600 heat_resistance = 6 -/datum/gas/nitryl - id = GAS_NITRYL - specific_heat = 20 - name = "Nitryl" - gas_overlay = "nitryl" +/datum/gas/water_vapor + id = GAS_H2O + specific_heat = 40 + name = "Water Vapor" + gas_overlay = "water_vapor" moles_visible = MOLES_GAS_VISIBLE flags = GAS_FLAG_DANGEROUS - fusion_power = 15 - fire_products = list(GAS_N2 = 0.5) - oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 + fusion_power = 8 + heat_penalty = 8 + enthalpy = -241800 // FIRE_HYDROGEN_ENERGY_RELEASED is actually what this was supposed to be + powermix = 1 + breath_reagent = /datum/reagent/water + + +/datum/gas/pluoxium + id = GAS_PLUOXIUM + specific_heat = 80 + name = "Pluoxium" + fusion_power = 10 + oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 25 // it is VERY stable + oxidation_rate = 8 // when it can oxidize, it can oxidize a LOT + enthalpy = -2000000 // but it reduces the heat output a great deal (plasma fires add 3000000 per mole) + powermix = -1 + heat_penalty = -1 + transmit_modifier = -5 + heat_resistance = 3 + price = 6 + +/datum/gas/pluoxium/generate_TLV() + return new/datum/tlv(-1, -1, 5, 6) /datum/gas/tritium id = GAS_TRITIUM @@ -108,13 +124,60 @@ powermix = 1 heat_penalty = 10 transmit_modifier = 30 - /* - these are for when we add hydrogen, trit gets to keep its hardcoded fire for legacy reasons - fire_provides = list(GAS_H2O = 2) + fire_products = list(GAS_H2O = 1) + enthalpy = 300000 + fire_burn_rate = 2 + fire_radiation_released = 50 // arbitrary number, basically 60 moles of trit burning will just barely start to harm you + fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 + price = 7 + +/datum/gas/nitric_oxide + id = GAS_NITRIC + specific_heat = 20 + name = "Nitric oxide" + odor = "sharp sweetness" + odor_strength = 1 + fusion_power = 15 + enthalpy = 91290 + heat_resistance = 2 + powermix = -1 + heat_penalty = -1 + +/datum/gas/nitryl + id = GAS_NITRYL + specific_heat = 20 + name = "Nitrogen dioxide" + color = "#963" + moles_visible = MOLES_GAS_VISIBLE + flags = GAS_FLAG_DANGEROUS + fusion_power = 15 + fire_products = list(GAS_N2 = 0.5) + enthalpy = 33200 + oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 + price = 3 + +/datum/gas/hypernoblium + id = GAS_HYPERNOB + specific_heat = 2000 + name = "Hyper-noblium" + gas_overlay = "freon" + moles_visible = MOLES_GAS_VISIBLE + price = 50 + +/datum/gas/hydrogen + id = GAS_HYDROGEN + specific_heat = 10 + name = "Hydrogen" + flags = GAS_FLAG_DANGEROUS + moles_visible = MOLES_GAS_VISIBLE + color = "#ffe" + fusion_power = 0 + powermix = 1 + heat_penalty = 3 + transmit_modifier = 10 + fire_products = list(GAS_H2O = 1) fire_burn_rate = 2 - fire_energy_released = FIRE_HYDROGEN_ENERGY_RELEASED fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 - */ /datum/gas/bz id = GAS_BZ @@ -124,39 +187,41 @@ fusion_power = 8 powermix = 1 heat_penalty = 5 + enthalpy = FIRE_CARBON_ENERGY_RELEASED // it is a mystery transmit_modifier = -2 radioactivity_modifier = 5 + price = 3 /datum/gas/stimulum id = GAS_STIMULUM specific_heat = 5 + odor = "the color blue" // fast + odor_strength = 10 name = "Stimulum" fusion_power = 7 - -/datum/gas/pluoxium - id = GAS_PLUOXIUM - specific_heat = 80 - name = "Pluoxium" - fusion_power = 10 - oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 1000 // it is VERY stable - oxidation_rate = 8 - powermix = -1 - heat_penalty = -1 - transmit_modifier = -5 - heat_resistance = 3 + price = 25 /datum/gas/miasma id = GAS_MIASMA specific_heat = 20 fusion_power = 50 + flags = GAS_FLAG_DANGEROUS + // snowflaked odor name = "Miasma" gas_overlay = "miasma" + color = "#963" moles_visible = MOLES_GAS_VISIBLE * 60 + price = 2 /datum/gas/methane id = GAS_METHANE specific_heat = 30 name = "Methane" + odor = "natural gas" + odor_strength = 2 + flags = GAS_FLAG_DANGEROUS + powerloss_inhibition = 1 + heat_resistance = 3 breath_results = GAS_METHYL_BROMIDE fire_products = list(GAS_CO2 = 1, GAS_H2O = 2) fire_burn_rate = 0.5 @@ -170,13 +235,16 @@ alert_type = /atom/movable/screen/alert/too_much_ch4 ) ) - fire_energy_released = FIRE_CARBON_ENERGY_RELEASED + enthalpy = -74600 fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + price = 1 /datum/gas/methyl_bromide id = GAS_METHYL_BROMIDE specific_heat = 42 name = "Methyl Bromide" + powermix = 1 + heat_penalty = -1 flags = GAS_FLAG_DANGEROUS breath_alert_info = list( not_enough_alert = list( @@ -188,7 +256,45 @@ alert_type = /atom/movable/screen/alert/too_much_ch3br ) ) - fire_products = list(GAS_CO2 = 1, GAS_H2O = 1.5, GAS_BZ = 0.5) - fire_energy_released = FIRE_CARBON_ENERGY_RELEASED - fire_burn_rate = 0.5 - fire_temperature = 808 // its autoignition, it apparently doesn't spark readily, so i don't put it lower + fire_products = list(GAS_CO2 = 1, GAS_H2O = 1.5, GAS_BROMINE = 0.5) + enthalpy = -35400 + fire_burn_rate = 4 / 7 // oh no + fire_temperature = 808 // its autoignition; it apparently doesn't spark readily, so i don't put it lower + price = 2 + +/datum/gas/bromine + id = GAS_BROMINE + specific_heat = 76 + name = "Bromine" + flags = GAS_FLAG_DANGEROUS | GAS_FLAG_CHEMICAL + group = GAS_GROUP_CHEMICALS + color = "#6e1f00" + moles_visible = MOLES_GAS_VISIBLE + odor = "bromine" // it's a very recognizable smell + odor_strength = 0.1 + enthalpy = 193 // yeah it's small but it's good to include it + breath_reagent = /datum/reagent/bromine + +/datum/gas/ammonia + id = GAS_AMMONIA + specific_heat = 35 + name = "Ammonia" + odor = "ammonia" + odor_strength = 0.01 + flags = GAS_FLAG_DANGEROUS | GAS_FLAG_CHEMICAL + group = GAS_GROUP_CHEMICALS + enthalpy = -45900 + breath_reagent = /datum/reagent/ammonia + fire_products = list(GAS_H2O = 1.5, GAS_N2 = 0.5) + fire_burn_rate = 4/3 + fire_temperature = 924 + +/datum/gas/quark_matter + id = GAS_QCD + specific_heat = 10 + name = "Quark Matter" + flags = GAS_FLAG_DANGEROUS + powermix = -1 + transmit_modifier = -10 + heat_penalty = -10 + price = 5 // IT'S NOT ACTUALLY THAT HARD TO GET INTO A CANISTER LOL diff --git a/code/modules/atmospherics/environmental/LINDA_system.dm b/code/modules/atmospherics/environmental/LINDA_system.dm index 8d063825f1..83eb5d8ef3 100644 --- a/code/modules/atmospherics/environmental/LINDA_system.dm +++ b/code/modules/atmospherics/environmental/LINDA_system.dm @@ -40,21 +40,17 @@ return FALSE /turf/proc/ImmediateCalculateAdjacentTurfs() - if(SSair.thread_running()) - CALCULATE_ADJACENT_TURFS(src) - return var/canpass = CANATMOSPASS(src, src) var/canvpass = CANVERTICALATMOSPASS(src, src) for(var/direction in GLOB.cardinals_multiz) var/turf/T = get_step_multiz(src, direction) if(!istype(T)) continue - var/opp_dir = REVERSE_DIR(direction) if(isopenturf(T) && !(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) ) LAZYINITLIST(atmos_adjacent_turfs) LAZYINITLIST(T.atmos_adjacent_turfs) - atmos_adjacent_turfs[T] = direction - T.atmos_adjacent_turfs[src] = opp_dir + atmos_adjacent_turfs[T] = ATMOS_ADJACENT_ANY + T.atmos_adjacent_turfs[src] = ATMOS_ADJACENT_ANY else if (atmos_adjacent_turfs) atmos_adjacent_turfs -= T @@ -65,7 +61,12 @@ T.__update_auxtools_turf_adjacency_info(isspaceturf(T.get_z_base_turf()), -1) UNSETEMPTY(atmos_adjacent_turfs) src.atmos_adjacent_turfs = atmos_adjacent_turfs - set_sleeping(blocks_air) + for(var/t in atmos_adjacent_turfs) + var/turf/open/T = t + for(var/obj/machinery/door/firedoor/FD in T) + FD.UpdateAdjacencyFlags() + for(var/obj/machinery/door/firedoor/FD in src) + FD.UpdateAdjacencyFlags() __update_auxtools_turf_adjacency_info(isspaceturf(get_z_base_turf())) /turf/proc/set_sleeping(should_sleep) diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm index 3a3ba555de..8914537748 100644 --- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm +++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm @@ -28,10 +28,15 @@ var/list/atmos_overlay_types //gas IDs of current active gas overlays -/turf/open/Initialize() +/turf/open/Initialize(mapload) if(!blocks_air) air = new(2500,src) air.copy_from_turf(src) + if(planetary_atmos && !(initial_gas_mix in SSair.planetary)) + var/datum/gas_mixture/mix = new + mix.parse_gas_string(initial_gas_mix) + mix.mark_immutable() + SSair.planetary[initial_gas_mix] = mix update_air_ref(planetary_atmos ? 1 : 2) . = ..() @@ -51,53 +56,35 @@ /turf/open/assume_air_moles(datum/gas_mixture/giver, moles) if(!giver) return FALSE - if(SSair.thread_running()) - SSair.deferred_airs += list(list(giver, air, moles / giver.total_moles())) - else - giver.transfer_to(air, moles) - update_visuals() + giver.transfer_to(air, moles) return TRUE /turf/open/assume_air_ratio(datum/gas_mixture/giver, ratio) if(!giver) return FALSE - if(SSair.thread_running()) - SSair.deferred_airs += list(list(giver, air, ratio)) - else - giver.transfer_ratio_to(air, ratio) - update_visuals() + giver.transfer_ratio_to(air, ratio) return TRUE /turf/open/transfer_air(datum/gas_mixture/taker, moles) if(!taker || !return_air()) // shouldn't transfer from space return FALSE - if(SSair.thread_running()) - SSair.deferred_airs += list(list(air, taker, moles / air.total_moles())) - else - air.transfer_to(taker, moles) - update_visuals() + air.transfer_to(taker, moles) return TRUE /turf/open/transfer_air_ratio(datum/gas_mixture/taker, ratio) if(!taker || !return_air()) return FALSE - if(SSair.thread_running()) - SSair.deferred_airs += list(list(air, taker, ratio)) - else - air.transfer_ratio_to(taker, ratio) - update_visuals() + air.transfer_ratio_to(taker, ratio) return TRUE /turf/open/remove_air(amount) var/datum/gas_mixture/ours = return_air() var/datum/gas_mixture/removed = ours.remove(amount) - update_visuals() return removed /turf/open/remove_air_ratio(ratio) var/datum/gas_mixture/ours = return_air() var/datum/gas_mixture/removed = ours.remove_ratio(ratio) - update_visuals() return removed /turf/open/proc/copy_air_with_tile(turf/open/T) diff --git a/code/modules/atmospherics/gasmixtures/auxgm.dm b/code/modules/atmospherics/gasmixtures/auxgm.dm index 4aa68aa710..0c36457ea2 100644 --- a/code/modules/atmospherics/gasmixtures/auxgm.dm +++ b/code/modules/atmospherics/gasmixtures/auxgm.dm @@ -15,6 +15,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA /proc/_auxtools_register_gas(datum/gas/gas) // makes sure auxtools knows stuff about this gas /datum/auxgm + var/done_initializing = FALSE var/list/datums = list() var/list/specific_heats = list() var/list/names = list() @@ -24,6 +25,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA var/list/ids = list() var/list/typepaths = list() var/list/fusion_powers = list() + var/list/TLV = list() var/list/breathing_classes = list() var/list/breath_results = list() var/list/breath_reagents = list() @@ -32,30 +34,41 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA var/list/oxidation_temperatures = list() var/list/oxidation_rates = list() var/list/fire_temperatures = list() - var/list/fire_enthalpies = list() + var/list/enthalpies = list() var/list/fire_products = list() var/list/fire_burn_rates = list() var/list/supermatter = list() - + var/list/groups_by_gas = list() + var/list/groups = list() + var/list/TLVs = list() + var/list/odors = list() + var/list/odor_strengths = list() + var/list/prices = list() /datum/gas var/id = "" var/specific_heat = 0 var/name = "" - var/gas_overlay = "" //icon_state in icons/effects/atmospherics.dmi + var/gas_overlay = "generic" //icon_state in icons/effects/atmospherics.dmi + var/color = "#ffff" // Tints the overlay by this color. Use instead of gas_overlay, usually (but not necessarily). + var/odor = null // Odor string. Null means none; if not null, anyone who breathes the gas will smell it. + var/odor_strength = INFINITY // How strong the odor is; minimal partial pressure to smell, so lower = more. var/moles_visible = null var/flags = NONE //currently used by canisters + var/group = null // groups for scrubber/filter listing var/fusion_power = 0 // How much the gas destabilizes a fusion reaction var/breath_results = GAS_CO2 // what breathing this breathes out - var/breath_reagent = null // what breathing this adds to your reagents - var/breath_reagent_dangerous = null // what breathing this adds to your reagents IF it's above a danger threshold + var/datum/reagent/breath_reagent = null // what breathing this adds to your reagents + var/datum/reagent/breath_reagent_dangerous = null // what breathing this adds to your reagents IF it's above a danger threshold var/list/breath_alert_info = null // list for alerts that pop up when you have too much/not enough of something + var/price = 0 // How much this gas is worth when sold, per mole. var/oxidation_temperature = null // temperature above which this gas is an oxidizer; null for none var/oxidation_rate = 1 // how many moles of this can oxidize how many moles of material var/fire_temperature = null // temperature above which gas may catch fire; null for none var/list/fire_products = null // what results when this gas is burned (oxidizer or fuel); null for none - var/fire_energy_released = 0 // how much energy is released per mole of fuel burned + var/enthalpy = 0 // Standard enthalpy of formation in joules, used for fires var/fire_burn_rate = 1 // how many moles are burned per product released + var/fire_radiation_released = 0 // How much radiation is released when this gas burns var/powermix = 0 // how much this gas contributes to the supermatter's powermix ratio var/heat_penalty = 0 // heat and waste penalty from having the supermatter crystal surrounded by this gas; negative numbers reduce var/transmit_modifier = 0 // bonus to supermatter power generation (multiplicative, since it's % based, and divided by 10) @@ -63,6 +76,12 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA var/heat_resistance = 0 // makes the crystal more resistant against heat damage. var/powerloss_inhibition = 0 // Reduces how much power the supermatter loses each tick +/datum/gas/proc/generate_TLV() + if(flags & GAS_FLAG_DANGEROUS) + return new/datum/tlv/dangerous + else + return new/datum/tlv(-1, -1, 1000, 1000) + /datum/gas/proc/breath(partial_pressure, light_threshold, heavy_threshold, moles, mob/living/carbon/C, obj/item/organ/lungs/lungs) // This is only called on gases with the GAS_FLAG_BREATH_PROC flag. When possible, do NOT use this-- // greatly prefer just adding a reagent. This is mostly around for legacy reasons. @@ -74,11 +93,15 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA datums[g] = gas specific_heats[g] = gas.specific_heat names[g] = gas.name + TLVs[g] = gas.generate_TLV() if(gas.moles_visible) visibility[g] = gas.moles_visible overlays[g] = new /list(FACTOR_GAS_VISIBLE_MAX) for(var/i in 1 to FACTOR_GAS_VISIBLE_MAX) - overlays[g][i] = new /obj/effect/overlay/gas(gas.gas_overlay, i * 255 / FACTOR_GAS_VISIBLE_MAX) + var/obj/effect/overlay/gas/overlay = new(gas.gas_overlay) + overlay.color = gas.color + overlay.alpha = i * 255 / FACTOR_GAS_VISIBLE_MAX + overlays[g][i] = overlay else visibility[g] = 0 overlays[g] = 0 @@ -94,21 +117,36 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA breath_reagents[g] = gas.breath_reagent if(gas.breath_reagent_dangerous) breath_reagents_dangerous[g] = gas.breath_reagent_dangerous - if(gas.oxidation_temperature) oxidation_temperatures[g] = gas.oxidation_temperature oxidation_rates[g] = gas.oxidation_rate if(gas.fire_products) fire_products[g] = gas.fire_products - fire_enthalpies[g] = gas.fire_energy_released + enthalpies[g] = gas.enthalpy else if(gas.fire_temperature) fire_temperatures[g] = gas.fire_temperature fire_burn_rates[g] = gas.fire_burn_rate if(gas.fire_products) fire_products[g] = gas.fire_products - fire_enthalpies[g] = gas.fire_energy_released + enthalpies[g] = gas.enthalpy + if(gas.group) + if(!(gas.group in groups)) + groups[gas.group] = list() + groups[gas.group] += g + groups_by_gas[g] = gas.group + if(gas.odor) + odor_strengths[g] = gas.odor_strength + odors[g] = gas.odor + if(gas.price) + prices[g] = gas.price add_supermatter_properties(gas) _auxtools_register_gas(gas) + if(done_initializing) + for(var/r in SSair.gas_reactions) + var/datum/gas_reaction/R = r + R.init_reqs() + SSair.auxtools_update_reactions() + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_NEW_GAS, g) /proc/finalize_gas_refs() @@ -127,8 +165,20 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA for(var/breathing_class_path in subtypesof(/datum/breathing_class)) var/datum/breathing_class/class = new breathing_class_path breathing_classes[breathing_class_path] = class + done_initializing = TRUE finalize_gas_refs() +/datum/auxgm/proc/get_by_flag(flag) + var/static/list/gases_by_flag + if(!gases_by_flag) + gases_by_flag = list() + if(!(flag in gases_by_flag)) + gases_by_flag += flag + gases_by_flag[flag] = list() + for(var/g in flags) + if(flags[g] & flag) + gases_by_flag[flag] += g + return gases_by_flag[flag] GLOBAL_DATUM_INIT(gas_data, /datum/auxgm, new) @@ -140,7 +190,6 @@ GLOBAL_DATUM_INIT(gas_data, /datum/auxgm, new) appearance_flags = TILE_BOUND vis_flags = NONE -/obj/effect/overlay/gas/New(state, alph) +/obj/effect/overlay/gas/New(state) . = ..() icon_state = state - alpha = alph diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index ed4b1f63c2..fe7a8fdfaf 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -135,6 +135,7 @@ we use a hook instead /datum/gas_mixture/proc/set_temperature(new_temp) /datum/gas_mixture/proc/set_volume(new_volume) /datum/gas_mixture/proc/get_moles(gas_type) +/datum/gas_mixture/proc/get_by_flag(flag) /datum/gas_mixture/proc/set_moles(gas_type, moles) // VV WRAPPERS - EXTOOLS HOOKED PROCS DO NOT TAKE ARGUMENTS FROM CALL() FOR SOME REASON. @@ -152,13 +153,20 @@ we use a hook instead /datum/gas_mixture/proc/scrub_into(datum/gas_mixture/target, ratio, list/gases) /datum/gas_mixture/proc/mark_immutable() /datum/gas_mixture/proc/get_gases() +/datum/gas_mixture/proc/add(amt) +/datum/gas_mixture/proc/subtract(amt) /datum/gas_mixture/proc/multiply(factor) +/datum/gas_mixture/proc/divide(factor) /datum/gas_mixture/proc/get_last_share() /datum/gas_mixture/proc/clear() /datum/gas_mixture/proc/adjust_moles(gas_type, amt = 0) set_moles(gas_type, clamp(get_moles(gas_type) + amt,0,INFINITY)) +/datum/gas_mixture/proc/adjust_moles_temp(gas_type, amt, temperature) + +/datum/gas_mixture/proc/adjust_multi() + /datum/gas_mixture/proc/return_volume() //liters /datum/gas_mixture/proc/thermal_energy() //joules @@ -175,6 +183,10 @@ we use a hook instead //Removes amount of gas from the gas_mixture //Returns: gas_mixture with the gases removed +/datum/gas_mixture/proc/remove_by_flag(flag, amount) + //Removes amount of gas from the gas mixture by flag + //Returns: gas_mixture with gases that match the flag removed + /datum/gas_mixture/proc/transfer_to(datum/gas_mixture/target, amount) //Transfers amount of gas to target. Equivalent to target.merge(remove(amount)) but faster. @@ -235,6 +247,14 @@ we use a hook instead //Makes every gas in the given list have the same pressure, temperature and gas proportions. //Returns: null +/datum/gas_mixture/proc/__remove_by_flag() + +/datum/gas_mixture/remove_by_flag(flag, amount) + var/datum/gas_mixture/removed = new type + __remove_by_flag(removed, flag, amount) + + return removed + /datum/gas_mixture/proc/__remove() /datum/gas_mixture/remove(amount) var/datum/gas_mixture/removed = new type @@ -260,7 +280,12 @@ we use a hook instead parse_gas_string(model.initial_gas_mix) return 1 +/datum/gas_mixture/proc/__auxtools_parse_gas_string(gas_string) + /datum/gas_mixture/parse_gas_string(gas_string) + gas_string = SSair.preprocess_gas_string(gas_string) + return __auxtools_parse_gas_string(gas_string) +/* var/list/gas = params2list(gas_string) if(gas["TEMP"]) var/temp = text2num(gas["TEMP"]) @@ -273,6 +298,7 @@ we use a hook instead set_moles(id, text2num(gas[id])) archive() return 1 + */ /* /datum/gas_mixture/react(datum/holder) . = NO_REACTION diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index b523d333df..f60e853aed 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -5,10 +5,9 @@ for(var/r in subtypesof(/datum/gas_reaction)) var/datum/gas_reaction/reaction = r - if(initial(reaction.exclude)) - continue reaction = new r - . += reaction + if(!reaction.exclude) + . += reaction sortTim(., /proc/cmp_gas_reaction) /proc/cmp_gas_reaction(datum/gas_reaction/a, datum/gas_reaction/b) // compares lists of reactions by the maximum priority contained within the list @@ -18,7 +17,6 @@ //regarding the requirements lists: the minimum or maximum requirements must be non-zero. //when in doubt, use MINIMUM_MOLE_COUNT. var/list/min_requirements - var/list/max_requirements var/exclude = FALSE //do it this way to allow for addition/removal of reactions midmatch in the future var/priority = 100 //lower numbers are checked/react later than higher numbers. if two reactions have the same priority they may happen in either order var/name = "reaction" @@ -53,23 +51,71 @@ id = "vapor" /datum/gas_reaction/water_vapor/init_reqs() - min_requirements = list(GAS_H2O = MOLES_GAS_VISIBLE) + min_requirements = list( + GAS_H2O = MOLES_GAS_VISIBLE, + "MAX_TEMP" = T0C + 40 + ) /datum/gas_reaction/water_vapor/react(datum/gas_mixture/air, datum/holder) - var/turf/open/location = isturf(holder) ? holder : null - . = NO_REACTION + var/turf/open/location = holder + if(!istype(location)) + return NO_REACTION if (air.return_temperature() <= WATER_VAPOR_FREEZE) if(location && location.freon_gas_act()) - . = REACTING + return REACTING else if(location && location.water_vapor_gas_act()) air.adjust_moles(GAS_H2O,-MOLES_GAS_VISIBLE) - . = REACTING + return REACTING // no test cause it's entirely based on location +/datum/gas_reaction/condensation + priority = 0 + name = "Condensation" + id = "condense" + exclude = TRUE + var/datum/reagent/condensing_reagent + +/datum/gas_reaction/condensation/New(datum/reagent/R) + . = ..() + if(!istype(R)) + return + min_requirements = list( + "MAX_TEMP" = initial(R.boiling_point) + ) + min_requirements[R.get_gas()] = MOLES_GAS_VISIBLE + name = "[R.name] condensation" + id = "[R.type] condensation" + condensing_reagent = GLOB.chemical_reagents_list[R.type] + exclude = FALSE + +/datum/gas_reaction/condensation/react(datum/gas_mixture/air, datum/holder) + . = NO_REACTION + var/turf/open/location = holder + if(!istype(location)) + return + var/temperature = air.return_temperature() + var/static/datum/reagents/reagents_holder = new + reagents_holder.clear_reagents() + reagents_holder.chem_temp = temperature + var/G = condensing_reagent.get_gas() + var/amt = air.get_moles(G) + air.adjust_moles(G, -min(initial(condensing_reagent.condensation_amount), amt)) + if(air.get_moles(G) < MOLES_GAS_VISIBLE) + amt += air.get_moles(G) + air.set_moles(G, 0.0) + reagents_holder.add_reagent(condensing_reagent.type, amt) + . = REACTING + for(var/atom/movable/AM in location) + if(location.intact && AM.level == 1) + continue + reagents_holder.reaction(AM, TOUCH) + reagents_holder.reaction(location, TOUCH) + //tritium combustion: combustion of oxygen and tritium (treated as hydrocarbons). creates hotspots. exothermic /datum/gas_reaction/tritfire priority = -1 //fire should ALWAYS be last, but tritium fires happen before plasma fires + exclude = TRUE // generic fire now takes care of this name = "Tritium Combustion" id = "tritfire" @@ -88,9 +134,9 @@ item.temperature_expose(air, temperature, CELL_VOLUME) location.temperature_expose(air, temperature, CELL_VOLUME) -/proc/radiation_burn(turf/open/location, energy_released) +/proc/radiation_burn(turf/open/location, rad_power) if(istype(location) && prob(10)) - radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR) + radiation_pulse(location, rad_power) /datum/gas_reaction/tritfire/react(datum/gas_mixture/air, datum/holder) var/energy_released = 0 @@ -151,6 +197,7 @@ /datum/gas_reaction/plasmafire priority = -2 //fire should ALWAYS be last, but plasma fires happen after tritium fires name = "Plasma Combustion" + exclude = TRUE // generic fire now takes care of this id = "plasmafire" /datum/gas_reaction/plasmafire/init_reqs() @@ -300,7 +347,7 @@ fuels[fuel] *= oxidation_ratio fuels += oxidizers var/list/fire_products = GLOB.gas_data.fire_products - var/list/fire_enthalpies = GLOB.gas_data.fire_enthalpies + var/list/fire_enthalpies = GLOB.gas_data.enthalpies for(var/fuel in fuels + oxidizers) var/amt = fuels[fuel] if(!burn_results[fuel]) @@ -648,7 +695,7 @@ //Replace miasma with oxygen var/cleaned_air = min(air.get_moles(GAS_MIASMA), 20 + (air.return_temperature() - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20) air.adjust_moles(GAS_MIASMA, -cleaned_air) - air.adjust_moles(GAS_O2, cleaned_air) + air.adjust_moles(GAS_METHANE, cleaned_air) //Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable air.set_temperature(air.return_temperature() + cleaned_air * 0.002) @@ -670,3 +717,90 @@ if(result != NO_REACTION) return list("success" = FALSE, "message" = "Miasma sterilization not stopping due to water vapor correctly!") return ..() + +/datum/gas_reaction/nitric_oxide + priority = -5 + name = "Nitric oxide decomposition" + id = "nitric_oxide" + +/datum/gas_reaction/nitric_oxide/init_reqs() + min_requirements = list( + "MAX_TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST+100, + GAS_NITRIC = MINIMUM_MOLE_COUNT + ) + +/datum/gas_reaction/nitric_oxide/react(datum/gas_mixture/air, datum/holder) + var/nitric = air.get_moles(GAS_NITRIC) + var/oxygen = air.get_moles(GAS_O2) + var/max_amount = max(nitric / 8, MINIMUM_MOLE_COUNT) + var/enthalpy = air.return_temperature() * (air.heat_capacity() + R_IDEAL_GAS_EQUATION * air.total_moles()) + var/list/enthalpies = GLOB.gas_data.enthalpies + if(oxygen > MINIMUM_MOLE_COUNT) + var/reaction_amount = min(max_amount, oxygen)/4 + air.adjust_moles(GAS_NITRIC, -reaction_amount*2) + air.adjust_moles(GAS_O2, -reaction_amount) + air.adjust_moles(GAS_NITRYL, reaction_amount*2) + enthalpy += (reaction_amount * -(enthalpies[GAS_NITRIC] - enthalpies[GAS_NITRYL])) + air.adjust_moles(GAS_NITRIC, -max_amount) + air.adjust_moles(GAS_O2, max_amount * 0.5) + air.adjust_moles(GAS_N2, max_amount * 0.5) + enthalpy += max_amount * -enthalpies[GAS_NITRIC] + air.set_temperature(enthalpy/(air.heat_capacity() + R_IDEAL_GAS_EQUATION * air.total_moles())) + return REACTING + +/datum/gas_reaction/hagedorn + priority = -INFINITY + name = "Hagedorn decomposition" + id = "hagedorn" + +/datum/gas_reaction/hagedorn/init_reqs() + min_requirements = list( + "TEMP" = 2e12 // 2 trillion kelvins + ) + +/datum/gas_reaction/hagedorn/react(datum/gas_mixture/air, datum/holder) + var/initial_energy = air.thermal_energy() + if(air.get_moles(GAS_QCD)) + return + for(var/g in air.get_gases()) + air.set_moles(g, 0) + var/amount = initial_energy / (air.return_temperature() * GLOB.gas_data.specific_heats[GAS_QCD]) + air.set_moles(GAS_QCD, amount) + var/list/largest_values = SSresearch.science_tech.largest_values + if(!(GAS_QCD in largest_values)) + largest_values[GAS_QCD] = 0 + var/previous_largest = largest_values[GAS_QCD] + var/research_amount = min(amount * QCD_RESEARCH_AMOUNT, 100000) + if(previous_largest <= research_amount) + SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, research_amount) + largest_values[GAS_QCD] = research_amount + else + SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, research_amount / 100) + +/datum/gas_reaction/dehagedorn + priority = 50 + name = "Hagedorn condensation" + id = "dehagedorn" + +/datum/gas_reaction/dehagedorn/init_reqs() + min_requirements = list( + "MAX_TEMP" = 1.99e12, + GAS_QCD = MINIMUM_MOLE_COUNT + ) + +/datum/gas_reaction/dehagedorn/react(datum/gas_mixture/air, datum/holder) + var/initial_energy = air.thermal_energy() + var/energy_remaining = initial_energy + air.set_moles(GAS_QCD, 0) + air.set_temperature(min(air.return_temperature(), 1.8e12)) + var/new_temp = air.return_temperature() + var/list/gases = GLOB.gas_data.specific_heats.Copy() + gases -= GAS_QCD + gases -= GAS_TRITIUM // no refusing sorry + gases -= GAS_HYPERNOB // makes it waaay too easy to stabilize it + while(energy_remaining > 0) + var/G = pick(gases) + air.adjust_moles(G, max(0.1, energy_remaining / (gases[G] * new_temp * 20))) + energy_remaining = initial_energy - air.thermal_energy() + air.set_temperature(initial_energy / air.heat_capacity()) + return REACTING diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 806126e684..19b94eb64e 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -75,7 +75,7 @@ req_access = list(ACCESS_ATMOSPHERICS) max_integrity = 250 integrity_failure = 0.33 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 90, ACID = 30) resistance_flags = FIRE_PROOF var/danger_level = 0 @@ -90,7 +90,6 @@ var/frequency = FREQ_ATMOS_CONTROL var/alarm_frequency = FREQ_ATMOS_ALARMS var/datum/radio_frequency/radio_connection - var/list/TLV = list( // Breathable air. "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa "temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66), @@ -108,9 +107,17 @@ GAS_NITRYL = new/datum/tlv/dangerous, GAS_PLUOXIUM = new/datum/tlv(-1, -1, 5, 6), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires GAS_METHANE = new/datum/tlv(-1, -1, 3, 6), - GAS_METHYL_BROMIDE = new/datum/tlv/dangerous + GAS_METHYL_BROMIDE = new/datum/tlv/dangerous, + GAS_AMMONIA = new/datum/tlv/dangerous, + GAS_BROMINE = new/datum/tlv/dangerous, + ) +/obj/machinery/airalarm/proc/regenerate_TLV() + var/list/TLVs = GLOB.gas_data.TLVs + for(var/g in TLVs) + TLV[g] = TLVs[g] + /obj/machinery/airalarm/server // No checks here. TLV = list( "pressure" = new/datum/tlv/no_checks, @@ -132,6 +139,11 @@ GAS_METHYL_BROMIDE = new/datum/tlv/no_checks ) +/obj/machinery/airalarm/server/regenerate_TLV() + var/list/TLVs = GLOB.gas_data.TLVs + for(var/g in TLVs) + TLV[g] = new/datum/tlv/no_checks + /obj/machinery/airalarm/kitchen_cold_room // Copypasta: to check temperatures. TLV = list( "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa @@ -203,6 +215,8 @@ /obj/machinery/airalarm/Initialize(mapload, ndir, nbuild) . = ..() + regenerate_TLV() + RegisterSignal(SSdcs,COMSIG_GLOB_NEW_GAS,.proc/regenerate_TLV) wires = new /datum/wires/airalarm(src) if(ndir) @@ -219,11 +233,19 @@ power_change() set_frequency(frequency) + register_context() + +/obj/machinery/airalarm/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + LAZYSET(context[SCREENTIP_CONTEXT_ALT_LMB], INTENT_ANY, locked ? "Unlock" : "Lock") + return CONTEXTUAL_SCREENTIP_SET /obj/machinery/airalarm/Destroy() SSradio.remove_object(src, frequency) qdel(wires) wires = null + var/area/ourarea = get_area(src) + ourarea.atmosalert(FALSE, src) return ..() /obj/machinery/airalarm/examine(mob/user) @@ -403,6 +425,9 @@ if("incheck") send_signal(device_id, list("checks" = text2num(params["val"])^2), usr) . = TRUE + if("direction") + send_signal(device_id, list("direction" = text2num(params["val"])), usr) + . = TRUE if("set_external_pressure", "set_internal_pressure") var/target = params["value"] @@ -532,7 +557,7 @@ for(var/device_id in A.air_scrub_names) send_signal(device_id, list( "power" = 1, - "set_filters" = list(GAS_CO2, GAS_MIASMA), + "set_filters" = list(GAS_CO2, GAS_MIASMA, GAS_GROUP_CHEMICALS), "scrubbing" = 1, "widenet" = 0, )) @@ -543,24 +568,11 @@ "set_external_pressure" = ONE_ATMOSPHERE )) if(AALARM_MODE_CONTAMINATED) + var/list/all_gases = GLOB.gas_data.get_by_flag(GAS_FLAG_DANGEROUS) for(var/device_id in A.air_scrub_names) send_signal(device_id, list( "power" = 1, - "set_filters" = list( - GAS_CO2, - GAS_MIASMA, - GAS_PLASMA, - GAS_H2O, - GAS_HYPERNOB, - GAS_NITROUS, - GAS_NITRYL, - GAS_TRITIUM, - GAS_BZ, - GAS_STIMULUM, - GAS_PLUOXIUM, - GAS_METHANE, - GAS_METHYL_BROMIDE - ), + "set_filters" = all_gases, "scrubbing" = 1, "widenet" = 1, )) @@ -579,24 +591,36 @@ )) for(var/device_id in A.air_vent_names) send_signal(device_id, list( + "is_pressurizing" = 1, "power" = 1, "checks" = 1, - "set_external_pressure" = ONE_ATMOSPHERE*2 + "set_external_pressure" = ONE_ATMOSPHERE*1.4 + )) + send_signal(device_id, list( + "is_siphoning" = 1, + "power" = 1, + "checks" = 1, + "set_external_pressure" = ONE_ATMOSPHERE/1.4 )) if(AALARM_MODE_REFILL) for(var/device_id in A.air_scrub_names) send_signal(device_id, list( "power" = 1, - "set_filters" = list(GAS_CO2, GAS_MIASMA), + "set_filters" = list(GAS_CO2, GAS_MIASMA, GAS_GROUP_CHEMICALS), "scrubbing" = 1, "widenet" = 0, )) for(var/device_id in A.air_vent_names) send_signal(device_id, list( + "is_pressurizing" = 1, "power" = 1, "checks" = 1, "set_external_pressure" = ONE_ATMOSPHERE * 3 )) + send_signal(device_id, list( + "is_siphoning" = 1, + "power" = 0, + )) if(AALARM_MODE_PANIC, AALARM_MODE_REPLACEMENT) for(var/device_id in A.air_scrub_names) @@ -607,8 +631,14 @@ )) for(var/device_id in A.air_vent_names) send_signal(device_id, list( + "is_pressurizing" = 1, "power" = 0 )) + send_signal(device_id, list( + "is_siphoning" = 1, + "power" = 1, + "checks" = 0 + )) if(AALARM_MODE_SIPHON) for(var/device_id in A.air_scrub_names) send_signal(device_id, list( @@ -618,9 +648,14 @@ )) for(var/device_id in A.air_vent_names) send_signal(device_id, list( + "is_pressurizing" = 1, "power" = 0 )) - + send_signal(device_id, list( + "is_siphoning" = 1, + "power" = 1, + "checks" = 0 + )) if(AALARM_MODE_OFF) for(var/device_id in A.air_scrub_names) send_signal(device_id, list( @@ -638,8 +673,12 @@ for(var/device_id in A.air_vent_names) send_signal(device_id, list( "power" = 1, - "checks" = 2, - "set_internal_pressure" = 0 + "checks" = 0, + "is_pressurizing" = 1 + )) + send_signal(device_id, list( + "power" = 0, + "is_siphoning" = 1 )) /obj/machinery/airalarm/update_icon_state() diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index 6f45599463..40b2515353 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -39,7 +39,10 @@ var/construction_type var/pipe_state //icon_state as a pipe item var/on = FALSE - var/interacts_with_air = FALSE + +/obj/machinery/atmospherics/Initialize(mapload) + . = ..() + register_context() /obj/machinery/atmospherics/examine(mob/user) . = ..() @@ -48,6 +51,17 @@ if(SEND_SIGNAL(L, COMSIG_CHECK_VENTCRAWL)) . += "Alt-click to crawl through it." +/obj/machinery/atmospherics/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + + if(can_unwrench && held_item?.tool_behaviour == TOOL_WRENCH) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Unfasten") + . = CONTEXTUAL_SCREENTIP_SET + + if(is_type_in_list(src, GLOB.ventcrawl_machinery) && isliving(user) && SEND_SIGNAL(user, COMSIG_CHECK_VENTCRAWL)) + LAZYSET(context[SCREENTIP_CONTEXT_ALT_LMB], INTENT_ANY, "Crawl into") + . = CONTEXTUAL_SCREENTIP_SET + /obj/machinery/atmospherics/New(loc, process = TRUE, setdir) if(!isnull(setdir)) setDir(setdir) @@ -55,13 +69,10 @@ normalize_cardinal_directions() nodes = new(device_type) if (!armor) - armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70) + armor = list(MELEE = 25, BULLET = 10, LASER = 10, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 100, ACID = 70) ..() if(process) - if(interacts_with_air) - SSair.atmos_air_machinery += src - else - SSair.atmos_machinery += src + SSair.atmos_machinery += src SetInitDirections() /obj/machinery/atmospherics/Destroy() @@ -69,7 +80,6 @@ nullifyNode(i) SSair.atmos_machinery -= src - SSair.atmos_air_machinery -= src SSair.pipenets_needing_rebuilt -= src dropContents() diff --git a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm index 4dd7b672a7..0232802756 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm @@ -16,8 +16,6 @@ level = 1 - interacts_with_air = TRUE - var/frequency = 0 var/id = null var/datum/radio_frequency/radio_connection diff --git a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm index 56a7d78288..ac8ed537b5 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm @@ -29,13 +29,16 @@ Passive gate is similar to the regular pump except: /obj/machinery/atmospherics/components/binary/passive_gate/CtrlClick(mob/user) if(can_interact(user)) on = !on + investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS) update_icon() return ..() /obj/machinery/atmospherics/components/binary/passive_gate/AltClick(mob/user) if(can_interact(user)) target_pressure = MAX_OUTPUT_PRESSURE - update_icon() + investigate_log("was set to [target_pressure] kPa by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "pressure output set to [target_pressure] kPa") + update_appearance() return ..() /obj/machinery/atmospherics/components/binary/passive_gate/Destroy() diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index dc5a6eccd4..a8d82282d6 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -33,25 +33,19 @@ . += "You can hold Alt and click on it to maximize its pressure." /obj/machinery/atmospherics/components/binary/pump/CtrlClick(mob/user) - var/area/A = get_area(src) - var/turf/T = get_turf(src) - if(user.canUseTopic(src, BE_CLOSE, FALSE,)) + if(can_interact(user)) on = !on - update_icon() - investigate_log("Pump, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) - message_admins("Pump, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") - return ..() + investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS) + update_appearance() + return ..() /obj/machinery/atmospherics/components/binary/pump/AltClick(mob/user) - . = ..() - var/area/A = get_area(src) - var/turf/T = get_turf(src) - if(user.canUseTopic(src, BE_CLOSE, FALSE,)) + if(can_interact(user)) target_pressure = MAX_OUTPUT_PRESSURE - to_chat(user,"You maximize the pressure on the [src].") - investigate_log("Pump, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) - message_admins("Pump, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") - return TRUE + investigate_log("was set to [target_pressure] kPa by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "pressure output set to [target_pressure] kPa") + update_appearance() + return ..() /obj/machinery/atmospherics/components/binary/pump/Destroy() SSradio.remove_object(src,frequency) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm index 46d584339b..f5f0064558 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -33,15 +33,20 @@ . += "You can hold Alt and click on it to maximize its pressure." /obj/machinery/atmospherics/components/binary/volume_pump/CtrlClick(mob/user) - var/area/A = get_area(src) - var/turf/T = get_turf(src) if(user.canUseTopic(src, BE_CLOSE, FALSE,)) on = !on - update_icon() - investigate_log("Volume Pump, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) - message_admins("Volume Pump, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS) + update_appearance() return ..() +/obj/machinery/atmospherics/components/binary/volume_pump/AltClick(mob/user) + if(can_interact(user)) + transfer_rate = MAX_TRANSFER_RATE + investigate_log("was set to [transfer_rate] L/s by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "volume output set to [transfer_rate] L/s") + update_appearance() + return ..() + /obj/machinery/atmospherics/components/binary/volume_pump/Destroy() SSradio.remove_object(src,frequency) return ..() diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 4182f5ceca..fd89e26792 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -20,25 +20,19 @@ . += "You can hold Alt and click on it to maximize its flow rate." /obj/machinery/atmospherics/components/trinary/filter/CtrlClick(mob/user) - var/area/A = get_area(src) - var/turf/T = get_turf(src) if(user.canUseTopic(src, BE_CLOSE, FALSE,)) on = !on - update_icon() - investigate_log("Filter, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) - message_admins("Filter, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS) + update_appearance() return ..() /obj/machinery/atmospherics/components/trinary/filter/AltClick(mob/user) - . = ..() - var/area/A = get_area(src) - var/turf/T = get_turf(src) - if(user.canUseTopic(src, BE_CLOSE, FALSE,)) + if(can_interact(user)) transfer_rate = MAX_TRANSFER_RATE - to_chat(user,"You maximize the flow rate on the [src].") - investigate_log("Filter, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) - message_admins("Filter, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") - return TRUE + investigate_log("was set to [transfer_rate] L/s by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "volume output set to [transfer_rate] L/s") + update_appearance() + return ..() /obj/machinery/atmospherics/components/trinary/filter/proc/set_frequency(new_frequency) SSradio.remove_object(src, frequency) @@ -100,7 +94,10 @@ if(transfer_ratio > 0) if(filter_type && air2.return_pressure() <= 9000) - air1.scrub_into(air2, transfer_ratio, list(filter_type)) + if(filter_type in GLOB.gas_data.groups) + air1.scrub_into(air2, transfer_ratio, GLOB.gas_data.groups[filter_type]) + else + air1.scrub_into(air2, transfer_ratio, list(filter_type)) if(air3.return_pressure() <= 9000) air1.transfer_ratio_to(air3, transfer_ratio) @@ -125,8 +122,10 @@ data["filter_types"] = list() data["filter_types"] += list(list("name" = "Nothing", "id" = "", "selected" = !filter_type)) for(var/id in GLOB.gas_data.ids) - data["filter_types"] += list(list("name" = GLOB.gas_data.names[id], "id" = id, "selected" = (id == filter_type))) - + if(!(id in GLOB.gas_data.groups_by_gas)) + data["filter_types"] += list(list("name" = GLOB.gas_data.names[id], "id" = id, "selected" = (id == filter_type))) + for(var/group in GLOB.gas_data.groups) + data["filter_types"] += list(list("name" = group, "id" = group, "selected" = (group == filter_type))) return data /obj/machinery/atmospherics/components/trinary/filter/ui_act(action, params) diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm index 3296981e5e..49d6a71f78 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm @@ -17,35 +17,27 @@ //node 3 is the outlet, nodes 1 & 2 are intakes /obj/machinery/atmospherics/components/trinary/mixer/CtrlClick(mob/user) - if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + if(can_interact(user)) on = !on - update_icon() + investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS) + update_appearance() return ..() /obj/machinery/atmospherics/components/trinary/mixer/AltClick(mob/user) - if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + if(can_interact(user)) target_pressure = MAX_OUTPUT_PRESSURE - update_icon() + investigate_log("was set to [target_pressure] kPa by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "pressure output on set to [target_pressure] kPa") + update_appearance() return ..() - //node 3 is the outlet, nodes 1 & 2 are intakes - -/obj/machinery/atmospherics/components/trinary/mixer/update_icon() - cut_overlays() +/obj/machinery/atmospherics/components/trinary/mixer/update_overlays() + . = ..() for(var/direction in GLOB.cardinals) if(!(direction & initialize_directions)) continue - var/obj/machinery/atmospherics/node = findConnecting(direction) - var/image/cap - if(node) - cap = getpipeimage(icon, "cap", direction, node.pipe_color, piping_layer = piping_layer) - else - cap = getpipeimage(icon, "cap", direction, piping_layer = piping_layer) - - add_overlay(cap) - - return ..() + . += getpipeimage(icon, "cap", direction, pipe_color, piping_layer, TRUE) /obj/machinery/atmospherics/components/trinary/mixer/update_icon_nopipes() var/on_state = on && nodes[1] && nodes[2] && nodes[3] && is_operational() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index efafc1c9a8..f5c10b365f 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -4,7 +4,7 @@ icon_state = "pod-off" density = TRUE max_integrity = 350 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 30, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 30, ACID = 30) layer = ABOVE_WINDOW_LAYER plane = GAME_PLANE state_open = FALSE @@ -39,7 +39,7 @@ fair_market_price = 10 payment_department = ACCOUNT_MED -/obj/machinery/atmospherics/components/unary/cryo_cell/Initialize() +/obj/machinery/atmospherics/components/unary/cryo_cell/Initialize(mapload) . = ..() initialize_directions = dir @@ -72,10 +72,10 @@ QDEL_NULL(beaker) return ..() -/obj/machinery/atmospherics/components/unary/cryo_cell/contents_explosion(severity, target) +/obj/machinery/atmospherics/components/unary/cryo_cell/contents_explosion(severity, target, origin) ..() if(beaker) - beaker.ex_act(severity, target) + beaker.ex_act(severity, target, origin) /obj/machinery/atmospherics/components/unary/cryo_cell/handle_atom_del(atom/A) ..() @@ -439,7 +439,7 @@ return // we don't see the pipe network while inside cryo. /obj/machinery/atmospherics/components/unary/cryo_cell/get_remote_view_fullscreens(mob/user) - user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/impaired, 1) + user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/scaled/impaired, 1) /obj/machinery/atmospherics/components/unary/cryo_cell/can_crawl_through() return // can't ventcrawl in or out of cryo. diff --git a/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm b/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm index c0dfc5633e..4ad3bbf575 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm @@ -12,6 +12,8 @@ var/obj/machinery/atmospherics/components/unary/heat_exchanger/partner = null var/update_cycle + var/old_temperature = 0 + var/other_old_temperature = 0 pipe_state = "heunary" @@ -59,9 +61,6 @@ var/other_air_heat_capacity = partner_air_contents.heat_capacity() var/combined_heat_capacity = other_air_heat_capacity + air_heat_capacity - var/old_temperature = air_contents.return_temperature() - var/other_old_temperature = partner_air_contents.return_temperature() - if(combined_heat_capacity > 0) var/combined_energy = partner_air_contents.return_temperature()*other_air_heat_capacity + air_heat_capacity*air_contents.return_temperature() @@ -71,6 +70,8 @@ if(abs(old_temperature-air_contents.return_temperature()) > 1) update_parents() + old_temperature = air_contents.return_temperature() if(abs(other_old_temperature-partner_air_contents.return_temperature()) > 1) partner.update_parents() + other_old_temperature = partner_air_contents.return_temperature() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm index b2fa26edba..0492f529ad 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -16,7 +16,6 @@ var/datum/radio_frequency/radio_connection level = 1 - interacts_with_air = TRUE layer = GAS_SCRUBBER_LAYER pipe_state = "injector" @@ -24,13 +23,16 @@ /obj/machinery/atmospherics/components/unary/outlet_injector/CtrlClick(mob/user) if(can_interact(user)) on = !on - update_icon() + investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS) + update_appearance() return ..() /obj/machinery/atmospherics/components/unary/outlet_injector/AltClick(mob/user) if(can_interact(user)) volume_rate = MAX_TRANSFER_RATE - update_icon() + investigate_log("was set to [volume_rate] L/s by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "volume output set to [volume_rate] L/s") + update_appearance() return ..() /obj/machinery/atmospherics/components/unary/outlet_injector/Destroy() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm index 7cfdb9d63c..0b10f088d3 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm @@ -6,7 +6,6 @@ can_unwrench = TRUE level = 1 - interacts_with_air = TRUE layer = GAS_SCRUBBER_LAYER pipe_state = "pvent" diff --git a/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm b/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm index ee4223b157..8eb11024f7 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm @@ -5,7 +5,6 @@ icon_state = "relief_valve-e-map" can_unwrench = TRUE interaction_flags_machine = INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_SET_MACHINE - interacts_with_air = TRUE var/opened = FALSE var/open_pressure = ONE_ATMOSPHERE * 3 var/close_pressure = ONE_ATMOSPHERE diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index 8456c0b346..b60cc7bb90 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -7,7 +7,7 @@ density = TRUE max_integrity = 300 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 80, ACID = 30) layer = OBJ_LAYER plane = GAME_PLANE circuit = /obj/item/circuitboard/machine/thermomachine @@ -24,7 +24,7 @@ var/heat_capacity = 0 var/interactive = TRUE // So mapmakers can disable interaction. -/obj/machinery/atmospherics/components/unary/thermomachine/Initialize() +/obj/machinery/atmospherics/components/unary/thermomachine/Initialize(mapload) . = ..() initialize_directions = dir @@ -59,10 +59,10 @@ /obj/machinery/atmospherics/components/unary/thermomachine/examine(mob/user) . = ..() - . += "The thermostat is set to [target_temperature]K ([(T0C-target_temperature)*-1]C)." + . += "The thermostat is set to [target_temperature]K ([target_temperature-T0C]C)." if(in_range(user, src) || isobserver(user)) - . += "The status display reads: Efficiency [(heat_capacity/5000)*100]%." - . += "Temperature range [min_temperature]K - [max_temperature]K ([(T0C-min_temperature)*-1]C - [(T0C-max_temperature)*-1]C)." + . += "The status display reads: Effective heat capacity [heat_capacity] J/K." + . += "Temperature range [min_temperature]K - [max_temperature]K ([min_temperature-T0C]C - [max_temperature-T0C]C)." /obj/machinery/atmospherics/components/unary/thermomachine/process_atmos() ..() @@ -197,7 +197,7 @@ on = TRUE icon_state = "freezer_1" -/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/Initialize() +/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/Initialize(mapload) . = ..() if(target_temperature == initial(target_temperature)) target_temperature = min_temperature @@ -205,7 +205,7 @@ /obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/coldroom name = "cold room freezer" -/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/coldroom/Initialize() +/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/coldroom/Initialize(mapload) . = ..() target_temperature = T0C-80 @@ -217,16 +217,11 @@ min_temperature = max(T0C - (initial(min_temperature) + L * 15), TCMB) //73.15K with T1 stock parts /obj/machinery/atmospherics/components/unary/thermomachine/freezer/AltClick(mob/living/user) - . = ..() - var/area/A = get_area(src) - var/turf/T = get_turf(src) - if(!istype(user) || !user.canUseTopic(src, BE_CLOSE)) + if(!can_interact(user)) return target_temperature = min_temperature - to_chat(user,"You minimize the temperature on the [src].") - investigate_log("was set to [target_temperature] K by [key_name(usr)]", INVESTIGATE_ATMOS) - message_admins("[src.name] was minimized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") - return TRUE + investigate_log("was set to [target_temperature] K by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "temperature reset to [target_temperature] K") /obj/machinery/atmospherics/components/unary/thermomachine/heater name = "heater" diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index 1a53a5299f..8ac1ac8e36 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -15,8 +15,6 @@ level = 1 layer = GAS_SCRUBBER_LAYER - interacts_with_air = TRUE - var/id_tag = null var/pump_direction = RELEASING @@ -144,7 +142,7 @@ "device" = "VP", "timestamp" = world.time, "power" = on, - "direction" = pump_direction ? "release" : "siphon", + "direction" = pump_direction, "checks" = pressure_checks, "internal" = internal_pressure_bound, "external" = external_pressure_bound, @@ -178,6 +176,9 @@ var/mob/signal_sender = signal.data["user"] + if((("is_siphoning" in signal.data) && pump_direction == RELEASING) || (("is_pressurizing" in signal.data) && pump_direction == SIPHONING)) + return + if("purge" in signal.data) pressure_checks &= ~EXT_BOUND pump_direction = SIPHONING diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index 90d5f077a5..072babdf3e 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -13,12 +13,11 @@ level = 1 layer = GAS_SCRUBBER_LAYER - interacts_with_air = TRUE - var/id_tag = null var/scrubbing = SCRUBBING //0 = siphoning, 1 = scrubbing - var/filter_types = list(GAS_CO2) + var/filter_types = list(GAS_CO2, GAS_METHANE, GAS_METHYL_BROMIDE, GAS_MIASMA, GAS_GROUP_CHEMICALS) + var/list/clean_filter_types = null var/volume_rate = 200 var/widenet = 0 //is this scrubber acting on the 3x3 area around it. var/list/turf/adjacent_turfs = list() @@ -34,6 +33,16 @@ ..() if(!id_tag) id_tag = assign_uid_vents() + generate_clean_filter_types() + RegisterSignal(SSdcs,COMSIG_GLOB_NEW_GAS,.proc/generate_clean_filter_types) + +/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/generate_clean_filter_types() + clean_filter_types = list() + for(var/id in filter_types) + if(id in GLOB.gas_data.groups) + clean_filter_types |= GLOB.gas_data.groups[id] + else + clean_filter_types += id /obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy() var/area/A = get_base_area(src) @@ -95,7 +104,11 @@ var/list/f_types = list() for(var/id in GLOB.gas_data.ids) - f_types += list(list("gas_id" = id, "gas_name" = GLOB.gas_data.names[id], "enabled" = (id in filter_types))) + if(!(id in GLOB.gas_data.groups_by_gas)) + f_types += list(list("gas_id" = id, "gas_name" = GLOB.gas_data.names[id], "enabled" = (id in filter_types))) + + for(var/group in GLOB.gas_data.groups) + f_types += list(list("gas_id" = group, "gas_name" = group, "enabled" = (group in filter_types))) var/datum/signal/signal = new(list( "tag" = id_tag, @@ -147,11 +160,11 @@ var/datum/gas_mixture/environment = tile.return_air() var/datum/gas_mixture/air_contents = airs[1] - if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE || !islist(filter_types)) + if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE || !islist(clean_filter_types)) return FALSE if(scrubbing & SCRUBBING) - environment.scrub_into(air_contents, volume_rate/environment.return_volume(), filter_types) + environment.scrub_into(air_contents, volume_rate/environment.return_volume(), clean_filter_types) tile.air_update_turf() @@ -205,11 +218,13 @@ if("toggle_filter" in signal.data) filter_types ^= signal.data["toggle_filter"] + generate_clean_filter_types() if("set_filters" in signal.data) filter_types = list() for(var/gas in signal.data["set_filters"]) filter_types += gas + generate_clean_filter_types() if("init" in signal.data) name = signal.data["init"] diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm index c17c93ab95..e7ea86851b 100644 --- a/code/modules/atmospherics/machinery/other/meter.dm +++ b/code/modules/atmospherics/machinery/other/meter.dm @@ -9,7 +9,7 @@ idle_power_usage = 2 active_power_usage = 4 max_integrity = 150 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 40, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 40, ACID = 0) var/frequency = 0 var/atom/target var/id_tag diff --git a/code/modules/atmospherics/machinery/other/miner.dm b/code/modules/atmospherics/machinery/other/miner.dm index 1caae1376f..7830286138 100644 --- a/code/modules/atmospherics/machinery/other/miner.dm +++ b/code/modules/atmospherics/machinery/other/miner.dm @@ -12,7 +12,6 @@ icon_state = "miner" density = FALSE resistance_flags = INDESTRUCTIBLE|ACID_PROOF|FIRE_PROOF - interacts_with_air = TRUE var/spawn_id = null var/spawn_temp = T20C var/spawn_mol = MOLES_CELLSTANDARD * 10 @@ -29,7 +28,7 @@ idle_power_usage = 150 active_power_usage = 2000 -/obj/machinery/atmospherics/miner/Initialize() +/obj/machinery/atmospherics/miner/Initialize(mapload) . = ..() set_active(active) //Force overlay update. diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm index 5fdedd5be7..1bdc9185e5 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm @@ -6,9 +6,8 @@ buckle_lying = 1 var/icon_temperature = T20C //stop small changes in temperature causing icon refresh resistance_flags = LAVA_PROOF | FIRE_PROOF - interacts_with_air = TRUE -/obj/machinery/atmospherics/pipe/heat_exchanging/Initialize() +/obj/machinery/atmospherics/pipe/heat_exchanging/Initialize(mapload) . = ..() add_atom_colour("#404040", FIXED_COLOUR_PRIORITY) diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm index ce4aba6ab7..d2c5123527 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm @@ -16,7 +16,7 @@ var/mutable_appearance/center -/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/Initialize() +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/Initialize(mapload) icon_state = "" center = mutable_appearance(icon, "manifold_center") return ..() diff --git a/code/modules/atmospherics/machinery/pipes/layermanifold.dm b/code/modules/atmospherics/machinery/pipes/layermanifold.dm index bc8fd6777d..8a300e23f3 100644 --- a/code/modules/atmospherics/machinery/pipes/layermanifold.dm +++ b/code/modules/atmospherics/machinery/pipes/layermanifold.dm @@ -14,7 +14,7 @@ var/list/front_nodes var/list/back_nodes -/obj/machinery/atmospherics/pipe/layer_manifold/Initialize() +/obj/machinery/atmospherics/pipe/layer_manifold/Initialize(mapload) front_nodes = list() back_nodes = list() icon_state = "manifoldlayer_center" @@ -70,9 +70,9 @@ /obj/machinery/atmospherics/pipe/layer_manifold/SetInitDirections() switch(dir) - if(NORTH || SOUTH) + if(NORTH, SOUTH) initialize_directions = NORTH|SOUTH - if(EAST || WEST) + if(EAST, WEST) initialize_directions = EAST|WEST /obj/machinery/atmospherics/pipe/layer_manifold/isConnectable(obj/machinery/atmospherics/target, given_layer) diff --git a/code/modules/atmospherics/machinery/pipes/manifold.dm b/code/modules/atmospherics/machinery/pipes/manifold.dm index 3f061e3779..d0b054fa3e 100644 --- a/code/modules/atmospherics/machinery/pipes/manifold.dm +++ b/code/modules/atmospherics/machinery/pipes/manifold.dm @@ -17,7 +17,7 @@ var/mutable_appearance/center -/obj/machinery/atmospherics/pipe/manifold/Initialize() +/obj/machinery/atmospherics/pipe/manifold/Initialize(mapload) icon_state = "" center = mutable_appearance(icon, "manifold_center") return ..() diff --git a/code/modules/atmospherics/machinery/pipes/manifold4w.dm b/code/modules/atmospherics/machinery/pipes/manifold4w.dm index bbceff56da..dd4cc1402c 100644 --- a/code/modules/atmospherics/machinery/pipes/manifold4w.dm +++ b/code/modules/atmospherics/machinery/pipes/manifold4w.dm @@ -16,7 +16,7 @@ var/mutable_appearance/center -/obj/machinery/atmospherics/pipe/manifold4w/Initialize() +/obj/machinery/atmospherics/pipe/manifold4w/Initialize(mapload) icon_state = "" center = mutable_appearance(icon, "manifold4w_center") return ..() diff --git a/code/modules/atmospherics/machinery/pipes/pipes.dm b/code/modules/atmospherics/machinery/pipes/pipes.dm index e05502dbad..a514606e4d 100644 --- a/code/modules/atmospherics/machinery/pipes/pipes.dm +++ b/code/modules/atmospherics/machinery/pipes/pipes.dm @@ -75,6 +75,9 @@ /obj/machinery/atmospherics/pipe/setPipenet(datum/pipeline/P) parent = P +/obj/machinery/atmospherics/pipe/zap_act(power, zap_flags) + return 0 // they're not really machines in the normal sense, probably shouldn't explode + /obj/machinery/atmospherics/pipe/Destroy() QDEL_NULL(parent) @@ -106,7 +109,7 @@ . = list(parent) /obj/machinery/atmospherics/pipe/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < 12) + if(damage_flag == MELEE && damage_amount < 12) return 0 . = ..() diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index 15c6475033..f7bdc173f3 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -6,7 +6,7 @@ icon_state = "yellow" density = TRUE volume = 1000 - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 50) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 100, BOMB = 10, BIO = 100, RAD = 100, FIRE = 80, ACID = 50) max_integrity = 250 integrity_failure = 0.4 pressure_resistance = 7 * ONE_ATMOSPHERE @@ -235,7 +235,7 @@ . += "can-open" if(connected_port) . += "can-connector" - var/pressure = air_contents.return_pressure() + var/pressure = air_contents?.return_pressure() if(pressure >= 40 * ONE_ATMOSPHERE) . += "can-o3" else if(pressure >= 10 * ONE_ATMOSPHERE) @@ -295,6 +295,7 @@ density = FALSE playsound(src.loc, 'sound/effects/spray.ogg', 10, TRUE, -3) investigate_log("was destroyed.", INVESTIGATE_ATMOS) + update_icon_state() if(holding) holding.forceMove(T) diff --git a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm index 93dc414968..fcfdd54aa9 100644 --- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm +++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm @@ -3,7 +3,7 @@ icon = 'icons/obj/atmos.dmi' use_power = NO_POWER_USE max_integrity = 250 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 60, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 60, ACID = 30) anchored = FALSE var/datum/gas_mixture/air_contents @@ -16,7 +16,7 @@ /obj/machinery/portable_atmospherics/New() ..() - SSair.atmos_air_machinery += src + SSair.atmos_machinery += src air_contents = new(volume) air_contents.set_temperature(T20C) @@ -24,7 +24,7 @@ return 1 /obj/machinery/portable_atmospherics/Destroy() - SSair.atmos_air_machinery -= src + SSair.atmos_machinery -= src disconnect() qdel(air_contents) diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm index 68708c3233..12598b99d9 100644 --- a/code/modules/atmospherics/machinery/portable/pump.dm +++ b/code/modules/atmospherics/machinery/portable/pump.dm @@ -15,7 +15,7 @@ volume = 1000 -/obj/machinery/portable_atmospherics/pump/Initialize() +/obj/machinery/portable_atmospherics/pump/Initialize(mapload) . = ..() pump = new(src, FALSE) pump.on = TRUE diff --git a/code/modules/awaymissions/away_props.dm b/code/modules/awaymissions/away_props.dm index 36ed9b6ba3..a28bd0633a 100644 --- a/code/modules/awaymissions/away_props.dm +++ b/code/modules/awaymissions/away_props.dm @@ -6,10 +6,11 @@ invisibility = INVISIBILITY_MAXIMUM anchored = TRUE -/obj/effect/oneway/CanPass(atom/movable/mover, turf/target) +/obj/effect/oneway/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() var/turf/T = get_turf(src) var/turf/MT = get_turf(mover) - return ..() && (T == MT || get_dir(MT,T) == dir) + return . && (T == MT || get_dir(MT,T) == dir) /obj/effect/wind @@ -20,7 +21,7 @@ invisibility = INVISIBILITY_MAXIMUM var/strength = 30 -/obj/effect/wind/Initialize() +/obj/effect/wind/Initialize(mapload) . = ..() START_PROCESSING(SSobj,src) diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm index d32905e007..68930ca03a 100644 --- a/code/modules/awaymissions/capture_the_flag.dm +++ b/code/modules/awaymissions/capture_the_flag.dm @@ -35,7 +35,7 @@ QDEL_NULL(reset) return ..() -/obj/item/ctf/Initialize() +/obj/item/ctf/Initialize(mapload) . = ..() if(!reset) reset = new reset_path(get_turf(src)) @@ -167,7 +167,7 @@ var/static/arena_reset = FALSE var/static/list/people_who_want_to_play = list() -/obj/machinery/capture_the_flag/Initialize() +/obj/machinery/capture_the_flag/Initialize(mapload) . = ..() GLOB.poi_list |= src @@ -405,10 +405,10 @@ /obj/item/projectile/bullet/ctf damage = 0 -/obj/item/projectile/bullet/ctf/prehit(atom/target) +/obj/item/projectile/bullet/ctf/prehit_pierce(atom/target) if(is_ctf_target(target)) damage = 60 - return //PROJECTILE_PIERCE_NONE /// hey uhh don't hit anyone behind them + return PROJECTILE_PIERCE_NONE /// hey uhh don't hit anyone behind them . = ..() /obj/item/gun/ballistic/automatic/laser/ctf @@ -442,10 +442,10 @@ damage = 0 icon_state = "omnilaser" -/obj/item/projectile/beam/ctf/prehit(atom/target) +/obj/item/projectile/beam/ctf/prehit_pierce(atom/target) if(is_ctf_target(target)) damage = 150 - return //PROJECTILE_PIERCE_NONE /// hey uhhh don't hit anyone behind them + return PROJECTILE_PIERCE_NONE /// hey uhhh don't hit anyone behind them . = ..() /proc/is_ctf_target(atom/target) diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index cd5c2f76f3..76af33b613 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -33,6 +33,10 @@ var/ghost_usable = TRUE var/skip_reentry_check = FALSE //Skips the ghost role blacklist time for people who ghost/suicide/cryo +///override this to add special spawn conditions to a ghost role +/obj/effect/mob_spawn/proc/allow_spawn(mob/user, silent = FALSE) + return TRUE + //ATTACK GHOST IGNORING PARENT RETURN VALUE /obj/effect/mob_spawn/attack_ghost(mob/user, latejoinercalling) if(!SSticker.HasRoundStarted() || !loc || !ghost_usable) @@ -43,6 +47,8 @@ if(jobban_isbanned(user, banType)) to_chat(user, "You are jobanned!") return + if(!allow_spawn(user, silent = FALSE)) + return if(QDELETED(src) || QDELETED(user)) return if(isobserver(user)) @@ -178,7 +184,7 @@ var/facial_hair_style var/skin_tone -/obj/effect/mob_spawn/human/Initialize() +/obj/effect/mob_spawn/human/Initialize(mapload) if(ispath(outfit)) outfit = new outfit() if(!outfit) diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index c67bbb8a4d..4fbe5f467a 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -85,7 +85,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations) . = "Exit gateway unpowered." /datum/gateway_destination/gateway/get_target_turf() - return get_step(target_gateway, SOUTH) + return get_step(target_gateway.portal,SOUTH) /datum/gateway_destination/gateway/post_transfer(atom/movable/AM) . = ..() @@ -112,7 +112,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations) /datum/gateway_destination/gateway/home/proc/check_exile_implant(mob/living/L) for(var/obj/item/implant/exile/E in L.implants)//Checking that there is an exile implant - to_chat(L, "The station gate has detected your exile implant and is blocking your entry.") + to_chat(L, span_userdanger("The station gate has detected your exile implant and is blocking your entry.")) return TRUE return FALSE @@ -156,8 +156,6 @@ GLOBAL_LIST_EMPTY(gateway_destinations) bound_y = 0 density = TRUE - use_power = IDLE_POWER_USE - idle_power_usage = 100 active_power_usage = 5000 var/calibrated = TRUE @@ -172,15 +170,21 @@ GLOBAL_LIST_EMPTY(gateway_destinations) /// bumper object, the thing that starts actual teleport var/obj/effect/gateway_portal_bumper/portal /// Visual object for handling the viscontents - /// DISABLED DUE TO BYOND BUG CAUSING STACK OVERFLOWS OF ANY HUMAN INSTANTIATION NEAR AN ACTIVATED GATEWAY. - /// Probably due to it referencing each other through the gateway (there's a deep loop, maybe BYOND isn't catching something when it usually would) - // var/obj/effect/gateway_portal_effect/portal_visuals + var/obj/effect/gateway_portal_effect/portal_visuals + /// Overlay of the lights. They light up fully when it charges fully. + var/image/light_overlay -/obj/machinery/gateway/Initialize() +/obj/machinery/gateway/Initialize(mapload) generate_destination() - update_icon() - // portal_visuals = new - // vis_contents += portal_visuals + update_appearance() + portal_visuals = new + vis_contents += portal_visuals + return ..() + +/obj/machinery/gateway/Destroy() + destination.target_gateway = null + GLOB.gateway_destinations -= destination + destination = null return ..() /obj/machinery/gateway/proc/generate_destination() @@ -196,20 +200,23 @@ GLOBAL_LIST_EMPTY(gateway_destinations) QDEL_NULL(portal) if(use_power == ACTIVE_POWER_USE) use_power = IDLE_POWER_USE - update_icon() - // portal_visuals.reset_visuals() + update_appearance() + portal_visuals.reset_visuals() /obj/machinery/gateway/process() if((stat & (NOPOWER)) && use_power) if(target) deactivate() return - -/obj/machinery/gateway/update_icon_state() - if(target) - icon_state = "on_old" - else - icon_state = "portal_frame" + if(light_overlay) + return + for(var/datum/gateway_destination/destination as anything in GLOB.gateway_destinations) + if(!destination.is_available()) + continue + light_overlay = image(icon, "portal_light") + light_overlay.alpha = 0 + animate(light_overlay, 3 SECONDS, alpha = 255) + add_overlay(light_overlay) /obj/machinery/gateway/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG, gentle = FALSE) return @@ -223,10 +230,10 @@ GLOBAL_LIST_EMPTY(gateway_destinations) return target = D target.activate(destination) - // portal_visuals.setup_visuals(target) + portal_visuals.setup_visuals(target) generate_bumper() use_power = ACTIVE_POWER_USE - update_icon() + update_appearance() /obj/machinery/gateway/proc/Transfer(atom/movable/AM) if(!target || !target.incoming_pass_check(AM)) @@ -239,7 +246,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations) destination_type = /datum/gateway_destination/gateway/home destination_name = "Home Gateway" -/obj/machinery/gateway/centerstation/Initialize() +/obj/machinery/gateway/centerstation/Initialize(mapload) . = ..() if(!GLOB.the_gateway) GLOB.the_gateway = src @@ -251,9 +258,9 @@ GLOBAL_LIST_EMPTY(gateway_destinations) /obj/machinery/gateway/multitool_act(mob/living/user, obj/item/I) if(calibrated) - to_chat(user, "The gate is already calibrated, there is no work for you to do here.") + to_chat(user, span_alert("The gate is already calibrated, there is no work for you to do here.")) else - to_chat(user, "Recalibration successful!: \black This gate's systems have been fine tuned. Travel to this gate will now be on target.") + to_chat(user, "[span_boldnotice("Recalibration successful!")]: \black This gate's systems have been fine tuned. Travel to this gate will now be on target.") calibrated = TRUE return TRUE @@ -266,7 +273,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations) . = ..() if(!target) if(!GLOB.the_gateway) - to_chat(user,"Home gateway is not responding!") + to_chat(user,span_warning("Home gateway is not responding!")) if(GLOB.the_gateway.target) GLOB.the_gateway.deactivate() //this will turn the home gateway off so that it's free for us to connect to activate(GLOB.the_gateway.destination) @@ -284,6 +291,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations) try_to_linkup() /obj/machinery/computer/gateway_control/ui_interact(mob/user, datum/tgui/ui) + . = ..() ui = SStgui.try_update_ui(user, src, ui) if(!ui) ui = new(user, src, "Gateway", name) @@ -358,7 +366,6 @@ GLOBAL_LIST_EMPTY(gateway_destinations) if(!our_destination) return - add_filter("portal_alpha", 1, list("type" = "alpha", "icon" = icon(alpha_icon, alpha_icon_state), "x" = 32, "y" = 32)) add_filter("portal_blur", 1, list("type" = "blur", "size" = 0.5)) add_filter("portal_ripple", 1, list("type" = "ripple", "size" = 2, "radius" = 1, "falloff" = 1, "y" = 7)) @@ -366,5 +373,4 @@ GLOBAL_LIST_EMPTY(gateway_destinations) animate(get_filter("portal_ripple"), time = 1.3 SECONDS, loop = -1, easing = LINEAR_EASING, radius = 32) var/turf/center_turf = our_destination.get_target_turf() - vis_contents += block(locate(center_turf.x - 1, center_turf.y - 1, center_turf.z), locate(center_turf.x + 1, center_turf.y + 1, center_turf.z)) diff --git a/code/modules/awaymissions/mission_code/Cabin.dm b/code/modules/awaymissions/mission_code/Cabin.dm index 3ad7c7cb50..b5ff23d75b 100644 --- a/code/modules/awaymissions/mission_code/Cabin.dm +++ b/code/modules/awaymissions/mission_code/Cabin.dm @@ -43,7 +43,7 @@ density = FALSE var/active = 1 -/obj/structure/firepit/Initialize() +/obj/structure/firepit/Initialize(mapload) ..() toggleFirepit() diff --git a/code/modules/awaymissions/mission_code/jungleresort.dm b/code/modules/awaymissions/mission_code/jungleresort.dm index 6c82b2c0c4..934f3e5e1f 100644 --- a/code/modules/awaymissions/mission_code/jungleresort.dm +++ b/code/modules/awaymissions/mission_code/jungleresort.dm @@ -19,7 +19,7 @@ icon_state = "whip" /obj/item/clothing/suit/hooded/wintercoat/captain/jungle - armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 5, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/head/rice_hat/cursed // this was a stupid idea lmao name = "cursed rice hat" @@ -27,12 +27,12 @@ /obj/item/clothing/head/rice_hat/cursed/equipped(mob/M, slot) . = ..() - if (slot == SLOT_HEAD) + if (slot == ITEM_SLOT_HEAD) RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) else UnregisterSignal(M, COMSIG_MOB_SAY) -/obj/item/clothing/head/rice_hat/cursed/Initialize() +/obj/item/clothing/head/rice_hat/cursed/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, SHAMEBRERO_TRAIT) diff --git a/code/modules/awaymissions/mission_code/murderdome.dm b/code/modules/awaymissions/mission_code/murderdome.dm index 2a7cb21841..eef757cf8e 100644 --- a/code/modules/awaymissions/mission_code/murderdome.dm +++ b/code/modules/awaymissions/mission_code/murderdome.dm @@ -26,7 +26,7 @@ icon_state = "barrier0" alpha = 100 -/obj/effect/murderdome/dead_barricade/Initialize() +/obj/effect/murderdome/dead_barricade/Initialize(mapload) . = ..() addtimer(CALLBACK(src, .proc/respawn), 3 MINUTES) diff --git a/code/modules/awaymissions/mission_code/snowdin.dm b/code/modules/awaymissions/mission_code/snowdin.dm index 5d30ccd907..35371af4ca 100644 --- a/code/modules/awaymissions/mission_code/snowdin.dm +++ b/code/modules/awaymissions/mission_code/snowdin.dm @@ -164,11 +164,12 @@ icon_state = "liquidplasma" initial_gas_mix = "n2=82;plasma=24;TEMP=120" baseturfs = /turf/open/lava/plasma - slowdown = 2 light_range = 3 light_power = 0.75 light_color = LIGHT_COLOR_PURPLE + immunity_trait = TRAIT_SNOWSTORM_IMMUNE + immunity_resistance_flags = FREEZE_PROOF /turf/open/lava/plasma/attackby(obj/item/I, mob/user, params) var/obj/item/reagent_containers/glass/C = I @@ -178,78 +179,45 @@ C.reagents.add_reagent(/datum/reagent/toxin/plasma, rand(5, 10)) user.visible_message("[user] scoops some plasma from the [src] with \the [C].", "You scoop out some plasma from the [src] using \the [C].") -/turf/open/lava/plasma/burn_stuff(AM) - . = 0 +/turf/open/lava/plasma/do_burn(atom/movable/burn_target, delta_time = 1) + . = TRUE + if(isobj(burn_target)) + return FALSE // Does nothing against objects. Old code. - if(is_safe()) - return FALSE + var/mob/living/burn_living = burn_target + burn_living.adjustFireLoss(2) + if(QDELETED(burn_living)) + return + burn_living.adjust_fire_stacks(20) //dipping into a stream of plasma would probably make you more flammable than usual + burn_living.adjust_bodytemperature(-rand(50,65)) //its cold, man + if(!ishuman(burn_living) || DT_PROB(65, delta_time)) + return + var/mob/living/carbon/human/burn_human = burn_living + var/datum/species/burn_species = burn_human.dna.species + if(istype(burn_species, /datum/species/plasmaman) || istype(burn_species, /datum/species/android) || istype(burn_species, /datum/species/synth)) //ignore plasmamen/robotic species + return - var/thing_to_check = src - if (AM) - thing_to_check = list(AM) - for(var/thing in thing_to_check) - if(isobj(thing)) - var/obj/O = thing - if((O.resistance_flags & (FREEZE_PROOF)) || O.throwing) - continue - - else if (isliving(thing)) - . = 1 - var/mob/living/L = thing - if(L.movement_type & FLYING) - continue //YOU'RE FLYING OVER IT - if("snow" in L.weather_immunities) - continue - - var/buckle_check = L.buckling - if(!buckle_check) - buckle_check = L.buckled - if(isobj(buckle_check)) - var/obj/O = buckle_check - if(O.resistance_flags & FREEZE_PROOF) - continue - - else if(isliving(buckle_check)) - var/mob/living/live = buckle_check - if("snow" in live.weather_immunities) - continue - - L.adjustFireLoss(2) - if(L) - L.adjust_fire_stacks(20) //dipping into a stream of plasma would probably make you more flammable than usual - L.adjust_bodytemperature(-rand(50,65)) //its cold, man - if(ishuman(L))//are they a carbon? - var/list/plasma_parts = list()//a list of the organic parts to be turned into plasma limbs - var/list/robo_parts = list()//keep a reference of robotic parts so we know if we can turn them into a plasmaman - var/mob/living/carbon/human/PP = L - var/S = PP.dna.species - if(istype(S, /datum/species/plasmaman) || istype(S, /datum/species/android) || istype(S, /datum/species/synth)) //ignore plasmamen/robotic species - continue - - for(var/BP in PP.bodyparts) - var/obj/item/bodypart/NN = BP - if(NN.is_organic_limb() && NN.species_id != "plasmaman") //getting every organic, non-plasmaman limb (augments/androids are immune to this) - plasma_parts += NN - if(NN.is_robotic_limb(FALSE)) - robo_parts += NN - - if(prob(35)) //checking if the delay is over & if the victim actually has any parts to nom - PP.adjustToxLoss(15) - PP.adjustFireLoss(25) - if(plasma_parts.len) - var/obj/item/bodypart/NB = pick(plasma_parts) //using the above-mentioned list to get a choice of limbs for dismember() to use - PP.emote("scream") - NB.species_id = "plasmaman"//change the species_id of the limb to that of a plasmaman - NB.no_update = TRUE - NB.change_bodypart_status() - PP.visible_message("[L] screams in pain as [L.p_their()] [NB] melts down to the bone!", \ - "You scream out in pain as your [NB] melts down to the bone, leaving an eerie plasma-like glow where flesh used to be!") - if(!plasma_parts.len && !robo_parts.len) //a person with no potential organic limbs left AND no robotic limbs, time to turn them into a plasmaman - PP.IgniteMob() - PP.set_species(/datum/species/plasmaman) - PP.visible_message("[L] bursts into a brilliant purple flame as [L.p_their()] entire body is that of a skeleton!", \ - "Your senses numb as all of your remaining flesh is turned into a purple slurry, sloshing off your body and leaving only your bones to show in a vibrant purple!") + var/list/plasma_parts = list()//a list of the organic parts to be turned into plasma limbs + var/list/robo_parts = list()//keep a reference of robotic parts so we know if we can turn them into a plasmaman + for(var/obj/item/bodypart/burn_limb as anything in burn_human.bodyparts) + if(burn_limb.status == BODYPART_ORGANIC && burn_limb.species_id != SPECIES_PLASMAMAN) //getting every organic, non-plasmaman limb (augments/androids are immune to this) + plasma_parts += burn_limb + if(burn_limb.status == BODYPART_ROBOTIC) + robo_parts += burn_limb + burn_human.adjustToxLoss(15) + burn_human.adjustFireLoss(25) + if(plasma_parts.len) + var/obj/item/bodypart/burn_limb = pick(plasma_parts) //using the above-mentioned list to get a choice of limbs + burn_human.emote("scream") + burn_human.update_body_parts() + burn_human.visible_message(span_warning("[burn_human] screams in pain as [burn_human.p_their()] [burn_limb] melts down to the bone!"), \ + span_userdanger("You scream out in pain as your [burn_limb] melts down to the bone, leaving an eerie plasma-like glow where flesh used to be!")) + if(!plasma_parts.len && !robo_parts.len) //a person with no potential organic limbs left AND no robotic limbs, time to turn them into a plasmaman + burn_human.IgniteMob() + burn_human.set_species(/datum/species/plasmaman) + burn_human.visible_message(span_warning("[burn_human] bursts into a brilliant purple flame as [burn_human.p_their()] entire body is that of a skeleton!"), \ + span_userdanger("Your senses numb as all of your remaining flesh is turned into a purple slurry, sloshing off your body and leaving only your bones to show in a vibrant purple!")) /obj/vehicle/ridden/lavaboat/plasma name = "plasma boat" @@ -532,7 +500,7 @@ /obj/item/clothing/under/syndicate/coldres name = "insulated tactical turtleneck" desc = "A nondescript and slightly suspicious-looking turtleneck with digital camouflage cargo pants. The interior has been padded with special insulation for both warmth and protection." - armor = list("melee" = 20, "bullet" = 10, "laser" = 0,"energy" = 5, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 25, "acid" = 25) + armor = list(MELEE = 20, BULLET = 10, LASER = 0,ENERGY = 5, BOMB = 0, BIO = 0, RAD = 0, FIRE = 25, ACID = 25) cold_protection = CHEST|GROIN|ARMS|LEGS min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT @@ -589,7 +557,7 @@ back = /obj/item/storage/backpack mask = /obj/item/clothing/mask/breath r_pocket = /obj/item/tank/internals/emergency_oxygen/engi - internals_slot = SLOT_R_STORE + internals_slot = ITEM_SLOT_RPOCKET /obj/effect/mob_spawn/human/syndicatesoldier/coldres/alive/female mob_gender = FEMALE diff --git a/code/modules/awaymissions/mission_code/stationCollision.dm b/code/modules/awaymissions/mission_code/stationCollision.dm index 434dc673f7..f72e0132cd 100644 --- a/code/modules/awaymissions/mission_code/stationCollision.dm +++ b/code/modules/awaymissions/mission_code/stationCollision.dm @@ -48,7 +48,7 @@ //Syndicate sub-machine guns. /obj/item/gun/ballistic/automatic/c20r/sc_c20r -/obj/item/gun/ballistic/automatic/c20r/sc_c20r/Initialize() +/obj/item/gun/ballistic/automatic/c20r/sc_c20r/Initialize(mapload) . = ..() for(var/ammo in magazine.stored_ammo) if(prob(95)) //95% chance @@ -57,7 +57,7 @@ //Barman's shotgun /obj/item/gun/ballistic/shotgun/sc_pump -/obj/item/gun/ballistic/shotgun/sc_pump/Initialize() +/obj/item/gun/ballistic/shotgun/sc_pump/Initialize(mapload) . = ..() for(var/ammo in magazine.stored_ammo) if(prob(95)) //95% chance @@ -149,5 +149,5 @@ GLOBAL_VAR_INIT(sc_safecode5, "[rand(0,9)]") if(prob(25)) mezzer() -/obj/singularity/narsie/mini/ex_act() +/obj/singularity/narsie/mini/ex_act(severity, target, origin) return diff --git a/code/modules/awaymissions/signpost.dm b/code/modules/awaymissions/signpost.dm index 4d85d947c2..a53384c6fa 100644 --- a/code/modules/awaymissions/signpost.dm +++ b/code/modules/awaymissions/signpost.dm @@ -7,7 +7,7 @@ var/question = "Travel back?" var/list/zlevels -/obj/structure/signpost/Initialize() +/obj/structure/signpost/Initialize(mapload) . = ..() set_light(2) zlevels = SSmapping.levels_by_trait(ZTRAIT_STATION) @@ -63,7 +63,7 @@ exit the area." question = "Leave? You might never come back." -/obj/structure/signpost/exit/Initialize() +/obj/structure/signpost/exit/Initialize(mapload) . = ..() zlevels = list() for(var/i in 1 to world.maxz) diff --git a/code/modules/awaymissions/super_secret_room.dm b/code/modules/awaymissions/super_secret_room.dm index af801e1e42..a840180ea9 100644 --- a/code/modules/awaymissions/super_secret_room.dm +++ b/code/modules/awaymissions/super_secret_room.dm @@ -10,7 +10,7 @@ var/times_spoken_to = 0 var/list/shenanigans = list() -/obj/structure/speaking_tile/Initialize() +/obj/structure/speaking_tile/Initialize(mapload) . = ..() var/json_file = file("data/npc_saves/Poly.json") if(!fexists(json_file)) @@ -45,9 +45,9 @@ if(9) SpeakPeace(list("Alright maybe that's too boring.", "I can't keep manually typing these lines out though.", "It's hard to explain but the code structure I'm using is kind of terrible.")) if(10) - SpeakPeace(list("Oh I have an idea!", "Lets outsource this endless banter to Poly!", "Then you'll be able to keep listening to this without getting bored!")) + SpeakPeace(list("Oh I have an idea!", "Lets outsource this endless banter to Polly!", "Then you'll be able to keep listening to this without getting bored!")) if(isnull(shenanigans) || !shenanigans.len) - shenanigans = list("Except the poly file is missing...") + shenanigans = list("Except the polly file is missing...") if(11 to 14, 16 to 50, 52 to 99, 103 to 107, 109 to 203, 205 to 249, 252 to 665, 667 to 999, 1001 to 5642) SpeakPeace(list(pick(shenanigans),pick(shenanigans),pick(shenanigans))) if(times_spoken_to % 10 == 0) @@ -55,7 +55,7 @@ if(15) SpeakPeace(list("See? Isn't this fun?","Now you can mash this for hours without getting bored.","Anyway I'll leave you it.")) if(51) - SpeakPeace(list("The fun never ends around here.", "The Poly text files stores up to 500 statements.", "But you've probably heard a few repeats by now.")) + SpeakPeace(list("The fun never ends around here.", "The Polly text files stores up to 500 statements.", "But you've probably heard a few repeats by now.")) if(100) SpeakPeace(list("And that's a solid hundred.", "Good hustle I guess.", "You've probably heard a lot of repeats by now.")) if(101) diff --git a/code/modules/awaymissions/zlevel.dm b/code/modules/awaymissions/zlevel.dm index 1e2e1fe43c..a30e51a0a3 100644 --- a/code/modules/awaymissions/zlevel.dm +++ b/code/modules/awaymissions/zlevel.dm @@ -21,7 +21,7 @@ var/id var/delay = TRUE // If the generated destination should be delayed by configured gateway delay -/obj/effect/landmark/awaystart/Initialize() +/obj/effect/landmark/awaystart/Initialize(mapload) . = ..() var/datum/gateway_destination/point/current for(var/datum/gateway_destination/point/D in GLOB.gateway_destinations) diff --git a/code/modules/balloon_alert/balloon_alert.dm b/code/modules/balloon_alert/balloon_alert.dm new file mode 100644 index 0000000000..c273722607 --- /dev/null +++ b/code/modules/balloon_alert/balloon_alert.dm @@ -0,0 +1,90 @@ +#define BALLOON_TEXT_WIDTH 200 +#define BALLOON_TEXT_SPAWN_TIME (0.2 SECONDS) +#define BALLOON_TEXT_FADE_TIME (0.1 SECONDS) +#define BALLOON_TEXT_FULLY_VISIBLE_TIME (0.7 SECONDS) +#define BALLOON_TEXT_TOTAL_LIFETIME(mult) (BALLOON_TEXT_SPAWN_TIME + BALLOON_TEXT_FULLY_VISIBLE_TIME*mult + BALLOON_TEXT_FADE_TIME) +/// The increase in duration per character in seconds +#define BALLOON_TEXT_CHAR_LIFETIME_INCREASE_MULT (0.05) +/// The amount of characters needed before this increase takes into effect +#define BALLOON_TEXT_CHAR_LIFETIME_INCREASE_MIN 10 + +/// Creates text that will float from the atom upwards to the viewer. +/atom/proc/balloon_alert(mob/viewer, text) + SHOULD_NOT_SLEEP(TRUE) + + INVOKE_ASYNC(src, .proc/balloon_alert_perform, viewer, text) + +/// Create balloon alerts (text that floats up) to everything within range. +/// Will only display to people who can see. +/atom/proc/balloon_alert_to_viewers(message, self_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs) + SHOULD_NOT_SLEEP(TRUE) + + var/list/hearers = get_hearers_in_view(vision_distance, src) + hearers -= ignored_mobs + + for (var/mob/hearer in hearers) + if (hearer.is_blind()) + continue + + balloon_alert(hearer, (hearer == src && self_message) || message) + +// Do not use. +// MeasureText blocks. I have no idea for how long. +// I would've made the maptext_height update on its own, but I don't know +// if this would look bad on laggy clients. +/atom/proc/balloon_alert_perform(mob/viewer, text) + var/client/viewer_client = viewer.client + if (isnull(viewer_client)) + return + + var/bound_width = world.icon_size + if (ismovable(src)) + var/atom/movable/movable_source = src + bound_width = movable_source.bound_width + + var/image/balloon_alert = image(loc = isturf(src) ? src : get_atom_on_turf(src), layer = ABOVE_MOB_LAYER) + balloon_alert.plane = BALLOON_CHAT_PLANE + balloon_alert.alpha = 0 + balloon_alert.appearance_flags = RESET_ALPHA|RESET_COLOR|RESET_TRANSFORM + balloon_alert.maptext = MAPTEXT("[text]") + balloon_alert.maptext_x = (BALLOON_TEXT_WIDTH - bound_width) * -0.5 + balloon_alert.maptext_height = WXH_TO_HEIGHT(viewer_client?.MeasureText(text, null, BALLOON_TEXT_WIDTH)) + balloon_alert.maptext_width = BALLOON_TEXT_WIDTH + + viewer_client?.images += balloon_alert + + var/duration_mult = 1 + var/duration_length = length(text) - BALLOON_TEXT_CHAR_LIFETIME_INCREASE_MIN + + if(duration_length > 0) + duration_mult += duration_length*BALLOON_TEXT_CHAR_LIFETIME_INCREASE_MULT + + animate( + balloon_alert, + pixel_y = world.icon_size * 1.2, + time = BALLOON_TEXT_TOTAL_LIFETIME(1), + easing = SINE_EASING | EASE_OUT, + ) + + animate( + alpha = 255, + time = BALLOON_TEXT_SPAWN_TIME, + easing = CUBIC_EASING | EASE_OUT, + flags = ANIMATION_PARALLEL, + ) + + animate( + alpha = 0, + time = BALLOON_TEXT_FULLY_VISIBLE_TIME*duration_mult, + easing = CUBIC_EASING | EASE_IN, + ) + + addtimer(CALLBACK(GLOBAL_PROC, .proc/remove_image_from_client, balloon_alert, viewer_client), BALLOON_TEXT_TOTAL_LIFETIME(duration_mult)) + +#undef BALLOON_TEXT_CHAR_LIFETIME_INCREASE_MIN +#undef BALLOON_TEXT_CHAR_LIFETIME_INCREASE_MULT +#undef BALLOON_TEXT_FADE_TIME +#undef BALLOON_TEXT_FULLY_VISIBLE_TIME +#undef BALLOON_TEXT_SPAWN_TIME +#undef BALLOON_TEXT_TOTAL_LIFETIME +#undef BALLOON_TEXT_WIDTH diff --git a/code/modules/buildmode/submodes/save_area.dm b/code/modules/buildmode/submodes/save_area.dm new file mode 100644 index 0000000000..6cd235f161 --- /dev/null +++ b/code/modules/buildmode/submodes/save_area.dm @@ -0,0 +1,65 @@ +GLOBAL_VAR_INIT(save_area_executing, FALSE) + +/datum/mapGenerator/save_area + buildmode_name = "Save Area" + modules = list(/datum/mapGeneratorModule/save_area) + var/min_x = 0 + var/min_y = 0 + var/max_x = 0 + var/max_y = 0 + +/datum/mapGenerator/save_area/defineRegion(turf/Start, turf/End, replace = 0) + min_x = min(Start.x,End.x) + min_y = min(Start.y,End.y) + max_x = max(Start.x,End.x) + max_y = max(Start.y,End.y) + ..() + +/datum/mapGeneratorModule/save_area + var/areaName = "default.dm" + +//This could be optimised by making turfs that are the same go in the same, but this is a quick bodge solution so yea, fun job for coder here :) +/datum/mapGeneratorModule/save_area/generate() + var/datum/mapGenerator/save_area/L = mother + if(!istype(L)) + return + //If someone somehow gets build mode, stop them from using this. + if(!check_rights(R_ADMIN)) + message_admins("[ckey(usr)] tried to run the map save generator but was rejected due to insufficient perms.") + to_chat(usr, "You must have R_ADMIN privellages to use this.") + return + //Emergency check + if(L.map.len > 1600) + var/confirm = alert("Uhm, are you sure, the area is quiet large?", "Run generator", "Yes", "No") + if(confirm != "Yes") + return + + if(GLOB.save_area_executing) + to_chat(usr, "Someone is already running the generator! Try again in a bit.") + return + + to_chat(usr, "Saving, please wait...") + GLOB.save_area_executing = TRUE + + //Log just in case something happens + log_game("[key_name(usr)] ran the save level map generator on [L.map.len] turfs.") + message_admins("[key_name(usr)] ran the save level map generator on [L.map.len] turfs.") + + //Step 1: Get the data (This can take a while) + var/dat = "//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE\n" + dat += convert_map_to_tgm(L.map) + + //Step 2: Write the data to a file + var/filedir = file("data/temp.dmm") + if(fexists(filedir)) + fdel(filedir) + WRITE_FILE(filedir, "[dat]") + + //Step 3: Give the file to client for download + usr << ftp(filedir) + + //Step 4: Remove the file from the server (hopefully we can find a way to avoid step) + fdel(filedir) + log_game("[L.map.len] turfs have been saved by [ckey(usr)]") + alert("Area saved successfully.", "Action Successful!", "Ok") + GLOB.save_area_executing = FALSE diff --git a/code/modules/cargo/blackmarket/blackmarket_telepad.dm b/code/modules/cargo/blackmarket/blackmarket_telepad.dm index eb986a443a..1ad1496e60 100644 --- a/code/modules/cargo/blackmarket/blackmarket_telepad.dm +++ b/code/modules/cargo/blackmarket/blackmarket_telepad.dm @@ -25,7 +25,7 @@ var/transmitting // Current /datum/blackmarket_purchase being sent to the target uplink. var/list/datum/blackmarket_purchase/queue = list() // Queue for purchases that the machine should recieve and send. -/obj/machinery/ltsrbt/Initialize() +/obj/machinery/ltsrbt/Initialize(mapload) . = ..() SSblackmarket.telepads += src diff --git a/code/modules/cargo/blackmarket/blackmarket_uplink.dm b/code/modules/cargo/blackmarket/blackmarket_uplink.dm index 7d5b333f13..0c397fa7d6 100644 --- a/code/modules/cargo/blackmarket/blackmarket_uplink.dm +++ b/code/modules/cargo/blackmarket/blackmarket_uplink.dm @@ -1,6 +1,6 @@ /obj/item/blackmarket_uplink name = "Black Market Uplink" - desc = "A mishmash of a subspace amplifier, a radio, and an analyzer. Somehow able to access the black market, with a variable inventory in limited stock at inflated prices. No refunds, customer responsible for pick-ups." + desc = "A mishmash of a subspace amplifier, a radio, and an analyzer. Somehow able to access the black market, with a variable inventory in limited stock at inflated prices. No refunds, customer responsible for pick-ups." icon = 'icons/obj/blackmarket.dmi' icon_state = "uplink" // UI variables. @@ -13,7 +13,7 @@ var/money = 0 // How much money is inserted into the uplink. var/list/accessible_markets = list(/datum/blackmarket_market/blackmarket) // List of typepaths for "/datum/blackmarket_market"s that this uplink can access. -/obj/item/blackmarket_uplink/Initialize() +/obj/item/blackmarket_uplink/Initialize(mapload) . = ..() if(accessible_markets.len) viewing_market = accessible_markets[1] diff --git a/code/modules/cargo/bounties/assistant.dm b/code/modules/cargo/bounties/assistant.dm index 744c01a257..a009ef20af 100644 --- a/code/modules/cargo/bounties/assistant.dm +++ b/code/modules/cargo/bounties/assistant.dm @@ -102,26 +102,29 @@ wanted_types = list(/obj/item/shard) /datum/bounty/item/assistant/comfy_chair - name = "Comfy Chairs" + name = "Comfortable Chairs" description = "Commander Pat is unhappy with his chair. He claims it hurts his back. Ship some alternatives out to humor him." reward = 900 required_count = 5 wanted_types = list(/obj/structure/chair/comfy) -// /datum/bounty/item/assistant/geranium -// name = "Geraniums" -// description = "Commander Zot has the hots for Commander Zena. Send a shipment of geraniums - her favorite flower - and he'll happily reward you." -// reward = 1000 -// required_count = 3 -// wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/poppy/geranium) +/* +/datum/bounty/item/assistant/geranium + name = "Geraniums" + description = "Commander Zot has the hots for Commander Zena. Send a shipment of geraniums - her favorite flower - and he'll happily reward you." + reward = 1000 + required_count = 3 + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/poppy/geranium) + include_subtypes = FALSE +*/ -// /datum/bounty/item/assistant/poppy -// name = "Poppies" -// description = "Commander Zot really wants to sweep Security Officer Olivia off her feet. Send a shipment of Poppies - her favorite flower - and he'll happily reward you." -// reward = 1000 -// required_count = 3 -// wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/poppy) -// include_subtypes = FALSE +/datum/bounty/item/assistant/poppy + name = "Poppies" + description = "Commander Zot really wants to sweep Security Officer Olivia off her feet. Send a shipment of Poppies - her favorite flower - and he'll happily reward you." + reward = 1000 + required_count = 3 + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/poppy) + include_subtypes = FALSE /datum/bounty/item/assistant/shadyjims name = "Shady Jim's" @@ -156,11 +159,6 @@ required_count = 3 wanted_types = list(/obj/item/reagent_containers/food/snacks/monkeycube) */ -/datum/bounty/item/assistant/chainsaw - name = "Chainsaw" - description = "The chef at CentCom is having trouble butchering her animals. She requests one chainsaw, please." - reward = 2500 - wanted_types = list(/obj/item/chainsaw) /datum/bounty/item/assistant/ied name = "IED" @@ -169,30 +167,12 @@ required_count = 3 wanted_types = list(/obj/item/grenade/iedcasing) -/datum/bounty/item/assistant/bonfire - name = "Lit Bonfire" - description = "Space heaters are malfunctioning and the cargo crew of Central Command is starting to feel cold. Ship a lit bonfire to warm them up." - reward = 5000 - wanted_types = list(/obj/structure/bonfire) - -/datum/bounty/item/assistant/bonfire/applies_to(obj/O) - if(!..()) - return FALSE - var/obj/structure/bonfire/B = O - return !!B.burning - /datum/bounty/item/assistant/corgimeat name = "Raw Corgi Meat" description = "The Syndicate recently stole all of CentCom's corgi meat. Ship out a replacement immediately." reward = 3000 wanted_types = list(/obj/item/reagent_containers/food/snacks/meat/slab/corgi) -/datum/bounty/item/assistant/tail_whip - name = "Nine Tails whip" - description = "Commander Jackson is looking for a fine addition to her exotic weapons collection. She will reward you handsomely for either a Cat or Liz o' Nine Tails." - reward = 4000 - wanted_types = list(/obj/item/melee/chainofcommand/tailwhip) - /datum/bounty/item/assistant/bolas name = "Bolas" description = "Centcom's chef has lost their mind. They're streaking naked though the halls, greased up with butter and cooking oil. Send some bola's so we can capture them." @@ -215,7 +195,7 @@ wanted_types = list(/obj/item/storage/belt/utility) /datum/bounty/item/assistant/gasmasks - name = "Gas Masks" + name = "Gas Masks" description = "The good news is that we have more miasma than we'll ever need. The bad news is, somone opened the release valve on the canisters. Ship us some gas masks!" reward = 1250 required_count = 4 diff --git a/code/modules/cargo/bounties/botany.dm b/code/modules/cargo/bounties/botany.dm index 31e13e9a9b..5ed2faec98 100644 --- a/code/modules/cargo/bounties/botany.dm +++ b/code/modules/cargo/bounties/botany.dm @@ -228,3 +228,14 @@ multiplier = 6 bonus_desc = "Under no circumstances mention this shipment to security." foodtype = "\"meal\"" + +/datum/bounty/item/botany/bonfire + name = "Lit Bonfire" + description = "Space heaters are malfunctioning and the cargo crew of Central Command is starting to feel cold. Grow some logs and Ship a lit bonfire to warm them up." + wanted_types = list(/obj/structure/bonfire) + +/datum/bounty/item/botany/bonfire/applies_to(obj/O) + if(!..()) + return FALSE + var/obj/structure/bonfire/B = O + return !!B.burning diff --git a/code/modules/cargo/bounties/chef.dm b/code/modules/cargo/bounties/chef.dm index c83fa116d6..9998fb0e8d 100644 --- a/code/modules/cargo/bounties/chef.dm +++ b/code/modules/cargo/bounties/chef.dm @@ -137,3 +137,10 @@ reward = 2250 required_count = 3 wanted_types = list(/obj/item/reagent_containers/food/snacks/bbqribs) + +/datum/bounty/item/chef/corgifarming //Butchering is a chef's job. + name = "Corgi Hides" + description = "Admiral Weinstein's space yacht needs new upholstery. A dozen Corgi furs should do just fine." + reward = 30000 //that's a lot of dead dogs + required_count = 12 + wanted_types = list(/obj/item/stack/sheet/animalhide/corgi) diff --git a/code/modules/cargo/bounties/engineering.dm b/code/modules/cargo/bounties/engineering.dm index 5ddce8fb2c..59f5f083c8 100644 --- a/code/modules/cargo/bounties/engineering.dm +++ b/code/modules/cargo/bounties/engineering.dm @@ -89,3 +89,15 @@ description = "Station 24 is being overrun by hordes of angry Mothpeople. They are requesting the ultimate bug zapper." reward = 50000 //requires 14k credits of purchases, not to mention cooperation with engineering/heads of staff to set up inside the cramped shuttle wanted_types = list(/obj/singularity/energy_ball) + +/datum/bounty/item/engineering/emitter + name = "Emitter" + description = "We think there may be a defect in your station's emitter designs, based on the sheer number of delaminations your sector seems to see. Ship us one of yours." + reward = 2500 + wanted_types = list(/obj/machinery/power/emitter) + +/datum/bounty/item/engineering/hydro_tray + name = "Hydroponics Tray" + description = "The lab technicians are trying to figure out how to lower the power drain of hydroponics trays, but we fried our last one. Mind building one for us?" + reward = 2000 + wanted_types = list(/obj/machinery/hydroponics/constructable) diff --git a/code/modules/cargo/bounties/mech.dm b/code/modules/cargo/bounties/mech.dm index b7eac3499f..c1d22d9dbf 100644 --- a/code/modules/cargo/bounties/mech.dm +++ b/code/modules/cargo/bounties/mech.dm @@ -5,8 +5,8 @@ /datum/bounty/item/mech/ship(obj/O) if(!applies_to(O)) return - if(istype(O, /obj/mecha)) - var/obj/mecha/M = O + if(istype(O, /obj/vehicle/sealed/mecha)) + var/obj/vehicle/sealed/mecha/M = O M.wreckage = null // So the mech doesn't explode. ..() @@ -16,30 +16,30 @@ /datum/bounty/item/mech/ripley name = "APLU \"Ripley\"" reward = 13000 - wanted_types = list(/obj/mecha/working/ripley) - exclude_types = list(/obj/mecha/working/ripley/firefighter) + wanted_types = list(/obj/vehicle/sealed/mecha/working/ripley) + exclude_types = list(/obj/vehicle/sealed/mecha/working/ripley/firefighter) /datum/bounty/item/mech/firefighter name = "APLU \"Firefighter\"" reward = 18000 - wanted_types = list(/obj/mecha/working/ripley/firefighter) + wanted_types = list(/obj/vehicle/sealed/mecha/working/ripley/firefighter) /datum/bounty/item/mech/odysseus name = "Odysseus" reward = 11000 - wanted_types = list(/obj/mecha/medical/odysseus) + wanted_types = list(/obj/vehicle/sealed/mecha/medical/odysseus) /datum/bounty/item/mech/gygax name = "Gygax" reward = 28000 - wanted_types = list(/obj/mecha/combat/gygax) + wanted_types = list(/obj/vehicle/sealed/mecha/combat/gygax) /datum/bounty/item/mech/durand name = "Durand" reward = 20000 - wanted_types = list(/obj/mecha/combat/durand) + wanted_types = list(/obj/vehicle/sealed/mecha/combat/durand) /datum/bounty/item/mech/phazon name = "Phazon" reward = 50000 - wanted_types = list(/obj/mecha/combat/phazon) + wanted_types = list(/obj/vehicle/sealed/mecha/combat/phazon) diff --git a/code/modules/cargo/bounties/medical.dm b/code/modules/cargo/bounties/medical.dm index c1f8d9c9d0..1f56b929e6 100644 --- a/code/modules/cargo/bounties/medical.dm +++ b/code/modules/cargo/bounties/medical.dm @@ -125,3 +125,15 @@ reward = 2250 required_count = 5 wanted_types = list(/obj/item/defibrillator) + +/datum/bounty/item/medical/chainsaw + name = "Chainsaw" + description = "A CMO at CentCom is having trouble operating on golems. She requests one chainsaw, please." + reward = 2500 + wanted_types = list(/obj/item/chainsaw) + +/datum/bounty/item/medical/tail_whip //Like the cat tail bounties, with more processing. + name = "Nine Tails whip" + description = "Commander Jackson is looking for a fine addition to her exotic weapons collection. She will reward you handsomely for either a Cat or Liz o' Nine Tails." + reward = 4000 + wanted_types = list(/obj/item/melee/chainofcommand/tailwhip) diff --git a/code/modules/cargo/bounties/reagent.dm b/code/modules/cargo/bounties/reagent.dm index 57501beab3..c8646ab618 100644 --- a/code/modules/cargo/bounties/reagent.dm +++ b/code/modules/cargo/bounties/reagent.dm @@ -139,6 +139,7 @@ /datum/reagent/medicine/atropine,\ /datum/reagent/medicine/strange_reagent,\ /datum/reagent/medicine/regen_jelly,\ + /datum/reagent/medicine/limb_regrowth,\ /datum/reagent/drug/space_drugs,\ /datum/reagent/drug/crank,\ /datum/reagent/drug/krokodil,\ diff --git a/code/modules/cargo/bounties/science.dm b/code/modules/cargo/bounties/science.dm index ffa608f8fd..4079a6ffbe 100644 --- a/code/modules/cargo/bounties/science.dm +++ b/code/modules/cargo/bounties/science.dm @@ -8,7 +8,7 @@ name = "Trash Bag of Holding" description = "Nanotrasen would make good use of high-capacity trash bags. If you have any, please ship them." reward = 3000 - wanted_types = list(/obj/item/storage/backpack/holding) + wanted_types = list(/obj/item/storage/bag/trash/bluespace) /datum/bounty/item/science/bluespace_syringe name = "Bluespace Syringe" diff --git a/code/modules/cargo/bounties/security.dm b/code/modules/cargo/bounties/security.dm index 5ddf456573..d463e1393d 100644 --- a/code/modules/cargo/bounties/security.dm +++ b/code/modules/cargo/bounties/security.dm @@ -52,3 +52,37 @@ reward = 2750 required_count = 3 wanted_types = list(/obj/item/firing_pin/test_range) + +/datum/bounty/item/security/pepperspray + name = "Pepperspray" + description = "We've been having a bad run of riots on Space Station 76. We could use some new pepperspray cans." + reward = 3000 + required_count = 4 + wanted_types = list(/obj/item/reagent_containers/spray/pepper) + +/datum/bounty/item/security/prison_clothes + name = "Prison Uniforms" + description = "Terragov has been unable to source any new prisoner uniforms, so if you have any spares, we'll take them off your hands." + reward = 2000 + required_count = 4 + wanted_types = list(/obj/item/clothing/under/rank/prisoner) + +/datum/bounty/item/security/plates + name = "License Plates" + description = "As a result of a bad clown car crash, we could use an advance on some of your prisoner's license plates." + reward = 1000 + required_count = 10 + wanted_types = list(/obj/item/stack/license_plates/filled) + +/datum/bounty/item/security/earmuffs + name = "Earmuffs" + description = "Central Command is getting tired of your station's messages. They've ordered that you ship some earmuffs to lessen the annoyance." + reward = 1000 + wanted_types = list(/obj/item/clothing/ears/earmuffs) + +/datum/bounty/item/security/handcuffs + name = "Handcuffs" + description = "A large influx of escaped convicts have arrived at Central Command. Now is the perfect time to ship out spare handcuffs (or restraints)." + reward = 1000 + required_count = 5 + wanted_types = list(/obj/item/restraints/handcuffs) diff --git a/code/modules/cargo/bounty.dm b/code/modules/cargo/bounty.dm index b888dc1a28..00d07c8df1 100644 --- a/code/modules/cargo/bounty.dm +++ b/code/modules/cargo/bounty.dm @@ -23,7 +23,7 @@ GLOBAL_LIST_EMPTY(bounties_list) if(can_claim()) var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) if(D) - D.adjust_money(reward) + D.adjust_money(reward * SSeconomy.bounty_modifier) claimed = TRUE // If an item sent in the cargo shuttle can satisfy the bounty. @@ -76,8 +76,13 @@ GLOBAL_LIST_EMPTY(bounties_list) return TRUE // Returns a new bounty of random type, but does not add it to GLOB.bounties_list. -/proc/random_bounty() - switch(rand(1, 15)) +/proc/random_bounty(var/guided = 0) + var/bounty_num + if(guided && (guided != CIV_JOB_RANDOM)) + bounty_num = guided + else + bounty_num = rand(1,13) + switch(bounty_num) if(1) var/subtype = pick(subtypesof(/datum/bounty/item/assistant)) return new subtype @@ -100,27 +105,27 @@ GLOBAL_LIST_EMPTY(bounties_list) var/subtype = pick(subtypesof(/datum/bounty/virus)) return new subtype if(8) - var/subtype = pick(subtypesof(/datum/bounty/item/science)) - return new subtype - if(9) + if(rand(2) == 1) + var/subtype = pick(subtypesof(/datum/bounty/item/science)) + return new subtype var/subtype = pick(subtypesof(/datum/bounty/item/slime)) return new subtype - if(10) + if(9) var/subtype = pick(subtypesof(/datum/bounty/item/engineering)) return new subtype - if(11) + if(10) var/subtype = pick(subtypesof(/datum/bounty/item/mining)) return new subtype - if(12) + if(11) var/subtype = pick(subtypesof(/datum/bounty/item/medical)) return new subtype - if(13) + if(12) var/subtype = pick(subtypesof(/datum/bounty/item/botany)) return new subtype - if(14) + if(13) var/subtype = pick(subtypesof(/datum/bounty/item/silly)) return new subtype - if(15) + if(14) var/subtype = pick(subtypesof(/datum/bounty/item/gardencook)) return new subtype diff --git a/code/modules/cargo/bounty_console.dm b/code/modules/cargo/bounty_console.dm index 8a29715016..4158327c3c 100644 --- a/code/modules/cargo/bounty_console.dm +++ b/code/modules/cargo/bounty_console.dm @@ -9,7 +9,7 @@ var/printer_ready = 0 //cooldown var var/static/datum/bank_account/cargocash -/obj/machinery/computer/bounty/Initialize() +/obj/machinery/computer/bounty/Initialize(mapload) . = ..() printer_ready = world.time + PRINTER_TIMEOUT cargocash = SSeconomy.get_dep_account(ACCOUNT_CAR) @@ -20,7 +20,7 @@ /obj/item/paper/bounty_printout name = "paper - Bounties" -/obj/item/paper/bounty_printout/Initialize() +/obj/item/paper/bounty_printout/Initialize(mapload) . = ..() info = "

    Nanotrasen Cargo Bounties


    " update_icon() @@ -63,3 +63,5 @@ printer_ready = world.time + PRINTER_TIMEOUT print_paper() return + + diff --git a/code/modules/cargo/centcom_podlauncher.dm b/code/modules/cargo/centcom_podlauncher.dm index e4060de1a2..37f39793af 100644 --- a/code/modules/cargo/centcom_podlauncher.dm +++ b/code/modules/cargo/centcom_podlauncher.dm @@ -567,7 +567,8 @@ else if(picking_dropoff_turf) holder.mouse_up_icon = 'icons/effects/mouse_pointers/supplypod_pickturf.dmi' //Icon for when mouse is released holder.mouse_down_icon = 'icons/effects/mouse_pointers/supplypod_pickturf_down.dmi' //Icon for when mouse is pressed - holder.mouse_pointer_icon = holder.mouse_up_icon //Icon for idle mouse (same as icon for when released) + holder.mouse_override_icon = holder.mouse_up_icon //Icon for idle mouse (same as icon for when released) + holder.mouse_pointer_icon = holder.mouse_override_icon holder.click_intercept = src //Create a click_intercept so we know where the user is clicking else var/mob/holder_mob = holder.mob @@ -595,7 +596,7 @@ else return //if target is null and we don't have a specific target, cancel if (effectAnnounce) - deadchat_broadcast("A special package is being launched at the station!", turf_target = target) + deadchat_broadcast("A special package is being launched at the station!", turf_target = target, message_type=DEADCHAT_ANNOUNCEMENT) var/list/bouttaDie = list() for (var/mob/living/target_mob in target) bouttaDie.Add(target_mob) diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm index 9801b165c7..e7854d47cf 100644 --- a/code/modules/cargo/console.dm +++ b/code/modules/cargo/console.dm @@ -34,13 +34,13 @@ can_approve_requests = FALSE requestonly = TRUE -/obj/machinery/computer/cargo/Initialize() +/obj/machinery/computer/cargo/Initialize(mapload) . = ..() radio = new /obj/item/radio/headset/headset_cargo(src) /obj/machinery/computer/cargo/Destroy() QDEL_NULL(radio) - ..() + return ..() /obj/machinery/computer/cargo/proc/get_export_categories() . = EXPORT_CARGO @@ -99,7 +99,7 @@ for(var/datum/supply_order/SO in SSshuttle.shoppinglist) data["cart"] += list(list( "object" = SO.pack.name, - "cost" = SO.pack.cost, + "cost" = SO.pack.get_cost(), "id" = SO.id, "orderer" = SO.orderer, "paid" = !isnull(SO.paying_account) //paid by requester @@ -109,7 +109,7 @@ for(var/datum/supply_order/SO in SSshuttle.requestlist) data["requests"] += list(list( "object" = SO.pack.name, - "cost" = SO.pack.cost, + "cost" = SO.pack.get_cost(), "orderer" = SO.orderer, "reason" = SO.reason, "id" = SO.id @@ -132,7 +132,7 @@ continue data["supplies"][P.group]["packs"] += list(list( "name" = P.name, - "cost" = P.cost, + "cost" = P.get_cost(), "id" = pack, "desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name. "goody" = P.goody, diff --git a/code/modules/cargo/export_scanner.dm b/code/modules/cargo/export_scanner.dm index 80fd05cf8c..dcb476c459 100644 --- a/code/modules/cargo/export_scanner.dm +++ b/code/modules/cargo/export_scanner.dm @@ -43,5 +43,24 @@ to_chat(user, "Scanned [O], value: [price] credits[O.contents.len ? " (contents included)" : ""].") else to_chat(user, "Scanned [O], no export value.") - if(bounty_ship_item_and_contents(O, dry_run=TRUE)) - to_chat(user, "Scanned item is eligible for one or more bounties.") + + + if(ishuman(user)) + var/mob/living/carbon/human/scan_human = user + if(istype(O, /obj/item/bounty_cube)) + var/obj/item/bounty_cube/cube = O + + if(!istype(get_area(cube), /area/shuttle/supply)) + to_chat(user, "Shuttle placement not detected. Handling tip not registered.") + + else if(cube.bounty_handler_account) + to_chat(user, "Bank account for handling tip already registered!") + + else if(scan_human.get_bank_account() && cube.GetComponent(/datum/component/pricetag)) + var/datum/component/pricetag/pricetag = cube.GetComponent(/datum/component/pricetag) + cube.bounty_handler_account = scan_human.get_bank_account() + pricetag.payees[cube.bounty_handler_account] += cube.handler_tip + cube.bounty_handler_account.bank_card_talk("Bank account for [price ? "[price * cube.handler_tip] credit " : ""]handling tip successfully registered.") + cube.bounty_holder_account.bank_card_talk("[cube] was scanned in \the [get_area(cube)] by [scan_human] ([scan_human.job]).") + else + to_chat(user, "Bank account not detected. Handling tip not registered.") diff --git a/code/modules/cargo/exports.dm b/code/modules/cargo/exports.dm index b72e497a5f..66713a3053 100644 --- a/code/modules/cargo/exports.dm +++ b/code/modules/cargo/exports.dm @@ -33,6 +33,8 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they if(!GLOB.exports_list.len) setupExports() + var/profit_ratio = 1 //Percentage that gets sent to the seller, rest goes to cargo. + var/list/contents = AM.GetAllContents() var/datum/export_report/report = external_report @@ -47,7 +49,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they if(!E) continue if(E.applies_to(thing, allowed_categories, apply_elastic)) - sold = E.sell_object(thing, report, dry_run, allowed_categories , apply_elastic) + sold = E.sell_object(thing, report, dry_run, allowed_categories , apply_elastic, profit_ratio) report.exported_atoms += " [thing.name]" break if(thing.reagents?.value_multiplier) @@ -61,7 +63,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they if(ismob(thing)) thing.investigate_log("deleted through cargo export",INVESTIGATE_CARGO) if(ismecha(thing)) - var/obj/mecha/mech = thing + var/obj/vehicle/sealed/mecha/mech = thing mech.wreckage = null // why a mech left a wreck when sold i will never know qdel(thing) @@ -138,9 +140,19 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they var/the_cost = get_cost(O, allowed_categories , apply_elastic) var/amount = get_amount(O) + var/profit_ratio = 0 + if(amount <=0 || the_cost <=0) return FALSE + if(dry_run == FALSE) + if(SEND_SIGNAL(O, COMSIG_ITEM_SOLD, item_value = get_cost(O, allowed_categories , apply_elastic)) & COMSIG_ITEM_SPLIT_VALUE) + profit_ratio = SEND_SIGNAL(O, COMSIG_ITEM_SPLIT_PROFIT) + the_cost = the_cost*((100-profit_ratio)/100) + else + profit_ratio = SEND_SIGNAL(O, COMSIG_ITEM_SPLIT_PROFIT) + the_cost = the_cost*((100-profit_ratio)/100) + report.total_value[src] += the_cost if(istype(O, /datum/export/material)) diff --git a/code/modules/cargo/exports/civilain_bounty.dm b/code/modules/cargo/exports/civilain_bounty.dm new file mode 100644 index 0000000000..58486f176b --- /dev/null +++ b/code/modules/cargo/exports/civilain_bounty.dm @@ -0,0 +1,8 @@ +/datum/export/bounty_box + cost = 1 + k_elasticity = 0 //Bounties are non-elastic funds. + unit_name = "completed bounty cube" + export_types = list(/obj/item/bounty_cube) + +/datum/export/bounty_box/get_cost(obj/item/bounty_cube/cube, allowed_categories, apply_elastic) + return cube.bounty_value + (cube.bounty_value * (cube.speed_bonus / 100)) diff --git a/code/modules/cargo/exports/engineering.dm b/code/modules/cargo/exports/engineering.dm new file mode 100644 index 0000000000..4445437389 --- /dev/null +++ b/code/modules/cargo/exports/engineering.dm @@ -0,0 +1,4 @@ +/datum/export/plutonium_rod + cost = 20000 + unit_name = "Plutonium Rod" + export_types = list(/obj/item/fuel_rod/plutonium) diff --git a/code/modules/cargo/exports/large_objects.dm b/code/modules/cargo/exports/large_objects.dm index dca23c9f22..e464a056ab 100644 --- a/code/modules/cargo/exports/large_objects.dm +++ b/code/modules/cargo/exports/large_objects.dm @@ -169,13 +169,9 @@ /datum/export/large/gas_canister/get_cost(obj/O) var/obj/machinery/portable_atmospherics/canister/C = O var/worth = 10 - worth += C.air_contents.get_moles(GAS_BZ)*3 - worth += C.air_contents.get_moles(GAS_STIMULUM)*25 - worth += C.air_contents.get_moles(GAS_HYPERNOB)*20 - worth += C.air_contents.get_moles(GAS_MIASMA)*2 - worth += C.air_contents.get_moles(GAS_TRITIUM)*7 - worth += C.air_contents.get_moles(GAS_PLUOXIUM)*6 - worth += C.air_contents.get_moles(GAS_NITRYL)*10 + var/list/gas_prices = GLOB.gas_data.prices + for(var/gas in C.air_contents.get_gases()) + worth += C.air_contents.get_moles(gas)*gas_prices[gas] return worth @@ -278,69 +274,69 @@ /datum/export/large/mech/odysseus cost = 7500 unit_name = "working odysseus" - export_types = list(/obj/mecha/medical/odysseus) + export_types = list(/obj/vehicle/sealed/mecha/medical/odysseus) /datum/export/large/mech/ripley cost = 12000 unit_name = "working ripley" - export_types = list(/obj/mecha/working/ripley) + export_types = list(/obj/vehicle/sealed/mecha/working/ripley) /datum/export/large/mech/firefighter cost = 14000 unit_name = "working firefighter" - export_types = list(/obj/mecha/working/ripley/firefighter) + export_types = list(/obj/vehicle/sealed/mecha/working/ripley/firefighter) /datum/export/large/mech/gygax cost = 19000 unit_name = "working gygax" - export_types = list(/obj/mecha/combat/gygax) + export_types = list(/obj/vehicle/sealed/mecha/combat/gygax) /datum/export/large/mech/durand cost = 16000 unit_name = "working durand" - export_types = list(/obj/mecha/combat/durand) + export_types = list(/obj/vehicle/sealed/mecha/combat/durand) /datum/export/large/mech/phazon cost = 35000 //Little over half due to needing a core unit_name = "working phazon" - export_types = list(/obj/mecha/combat/phazon) + export_types = list(/obj/vehicle/sealed/mecha/combat/phazon) /datum/export/large/mech/marauder cost = 15000 //Still a Combat class mech - CC tech as well! 150% "normal" boundy price. unit_name = "working marauder" - export_types = list(/obj/mecha/combat/marauder) + export_types = list(/obj/vehicle/sealed/mecha/combat/marauder) /datum/export/large/mech/deathripley cost = 18500 //Still a "Combat class" mech - Illegal tech as well! 165% "normal" boundy price. unit_name = "working illegally modified" - export_types = list(/obj/mecha/working/ripley/deathripley) + export_types = list(/obj/vehicle/sealed/mecha/working/ripley/deathripley) /datum/export/large/mech/gygaxdark cost = 28500 //Still a Combat class mech - Illegal tech as well! 150% "normal" boundy price. unit_name = "working illegally modified gygax" - export_types = list(/obj/mecha/combat/gygax/dark) + export_types = list(/obj/vehicle/sealed/mecha/combat/gygax/dark) /datum/export/large/mech/oldripley cost = 6250 //old mech - Scrap metal ! 50% "normal" boundy price. unit_name = "working miner ripley" - export_types = list(/obj/mecha/working/ripley/mining) + export_types = list(/obj/vehicle/sealed/mecha/working/ripley/mining) /datum/export/large/mech/honk cost = 16000 //Still a "Combat class" mech - Comats bordem honk! unit_name = "working honker" - export_types = list(/obj/mecha/combat/honker) + export_types = list(/obj/vehicle/sealed/mecha/combat/honker) /datum/export/large/mech/reticence cost = 16000 //Still a "Combat class" mech - Has cloking and lethal weaponds. unit_name = "working reticence" - export_types = list(/obj/mecha/combat/reticence) + export_types = list(/obj/vehicle/sealed/mecha/combat/reticence) /datum/export/large/mech/seraph cost = 25500 //Still a Combat class mech - CC tech as well! 150% "normal" boundy price. unit_name = "working seraph" - export_types = list(/obj/mecha/combat/marauder/seraph) + export_types = list(/obj/vehicle/sealed/mecha/combat/marauder/seraph) /datum/export/large/mech/mauler cost = 25000 //Still a Combat class mech - CC lethal weaponds. unit_name = "working legally modified marauder" - export_types = list(/obj/mecha/combat/marauder/mauler) + export_types = list(/obj/vehicle/sealed/mecha/combat/marauder/mauler) diff --git a/code/modules/cargo/exports/organs_robotics.dm b/code/modules/cargo/exports/organs_robotics.dm index 08340e6a56..40f7edbd99 100644 --- a/code/modules/cargo/exports/organs_robotics.dm +++ b/code/modules/cargo/exports/organs_robotics.dm @@ -163,7 +163,7 @@ cost = 150 unit_name = "mech based tool" include_subtypes = TRUE - export_types = list(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp, /obj/item/mecha_parts/mecha_equipment/extinguisher, /obj/item/mecha_parts/mecha_equipment/rcd, /obj/item/mecha_parts/mecha_equipment/cable_layer, \ + export_types = list(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp, /obj/item/mecha_parts/mecha_equipment/extinguisher, /obj/item/mecha_parts/mecha_equipment/rcd, \ /obj/item/mecha_parts/mecha_equipment/drill, /obj/item/mecha_parts/mecha_equipment/mining_scanner, /obj/item/mecha_parts/mecha_equipment/medical/sleeper) /datum/export/robotics/mech_blue_space diff --git a/code/modules/cargo/exports/sheets.dm b/code/modules/cargo/exports/sheets.dm index b0676fbde2..058e0cc892 100644 --- a/code/modules/cargo/exports/sheets.dm +++ b/code/modules/cargo/exports/sheets.dm @@ -59,6 +59,11 @@ unit_name = "alien hide" export_types = list(/obj/item/stack/sheet/animalhide/xeno) +/datum/export/stack/licenseplate + cost = 25 + unit_name = "license plate" + export_types = list(/obj/item/stack/license_plates/filled) + // Common materials. // For base materials, see materials.dm diff --git a/code/modules/cargo/exports/weapons.dm b/code/modules/cargo/exports/weapons.dm index c973ceed26..5f2146200b 100644 --- a/code/modules/cargo/exports/weapons.dm +++ b/code/modules/cargo/exports/weapons.dm @@ -211,11 +211,6 @@ unit_name = "arrow" export_types = list(/obj/item/ammo_casing/caseless/arrow, /obj/item/ammo_casing/caseless/arrow/bone, /obj/item/ammo_casing/caseless/arrow/ash) -/datum/export/weapon/bow_teaching - cost = 500 - unit_name = "bowyery tablet" - export_types = list(/obj/item/book/granter/crafting_recipe/bone_bow) - /datum/export/weapon/quiver cost = 100 unit_name = "quiver" @@ -337,7 +332,7 @@ /datum/export/weapon/l6sawammo cost = 60 unit_name = "L6 SAW ammo box" - export_types = list(/obj/item/ammo_box/magazine/mm195x129) + export_types = list(/obj/item/ammo_box/magazine/mm712x82) include_subtypes = TRUE /datum/export/weapon/rocket diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm index 1c9c21e0d7..62fa7f8488 100644 --- a/code/modules/cargo/expressconsole.dm +++ b/code/modules/cargo/expressconsole.dm @@ -26,7 +26,7 @@ var/locked = TRUE //is the console locked? unlock with ID var/usingBeacon = FALSE //is the console in beacon mode? exists to let beacon know when a pod may come in -/obj/machinery/computer/cargo/express/Initialize() +/obj/machinery/computer/cargo/express/Initialize(mapload) . = ..() packin_up() @@ -81,7 +81,7 @@ continue // i'd be right happy to meme_pack_data[P.group]["packs"] += list(list( "name" = P.name, - "cost" = P.cost, + "cost" = P.get_cost(), "id" = pack, "desc" = P.desc || P.name // If there is a description, use it. Otherwise use the pack's name. )) @@ -128,6 +128,9 @@ return data /obj/machinery/computer/cargo/express/ui_act(action, params, datum/tgui/ui) + . = ..() + if(.) + return switch(action) if("LZCargo") usingBeacon = FALSE @@ -171,7 +174,7 @@ if(D) points_to_check = D.account_balance if(!(obj_flags & EMAGGED)) - if(SO.pack.cost <= points_to_check) + if(SO.pack.get_cost() <= points_to_check) var/LZ if (istype(beacon) && usingBeacon)//prioritize beacons over landing in cargobay LZ = get_turf(beacon) @@ -188,13 +191,13 @@ CHECK_TICK if(empty_turfs && empty_turfs.len) LZ = pick(empty_turfs) - if (SO.pack.cost <= points_to_check && LZ)//we need to call the cost check again because of the CHECK_TICK call - D.adjust_money(-SO.pack.cost) + if (SO.pack.get_cost() <= points_to_check && LZ)//we need to call the cost check again because of the CHECK_TICK call + D.adjust_money(-SO.pack.get_cost()) new /obj/effect/pod_landingzone(LZ, podType, SO) . = TRUE update_icon() else - if(SO.pack.cost * (0.72*MAX_EMAG_ROCKETS) <= points_to_check) // bulk discount :^) + if(SO.pack.get_cost() * (0.72*MAX_EMAG_ROCKETS) <= points_to_check) // bulk discount :^) landingzone = GLOB.areas_by_type[pick(GLOB.the_station_areas)] //override default landing zone for(var/turf/open/floor/T in landingzone.contents) if(is_blocked_turf(T)) @@ -202,7 +205,7 @@ LAZYADD(empty_turfs, T) CHECK_TICK if(empty_turfs && empty_turfs.len) - D.adjust_money(-(SO.pack.cost * (0.72*MAX_EMAG_ROCKETS))) + D.adjust_money(-(SO.pack.get_cost() * (0.72*MAX_EMAG_ROCKETS))) SO.generateRequisition(get_turf(src)) for(var/i in 1 to MAX_EMAG_ROCKETS) diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 13f1e77441..9d9478df4f 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -38,6 +38,9 @@ fill(C) return C +/datum/supply_pack/proc/get_cost() + return cost * SSeconomy.pack_price_modifier + /datum/supply_pack/proc/fill(obj/structure/closet/crate/C) if (admin_spawned) for(var/item in contains) diff --git a/code/modules/cargo/packs/armory.dm b/code/modules/cargo/packs/armory.dm index de3e657386..3bd4515698 100644 --- a/code/modules/cargo/packs/armory.dm +++ b/code/modules/cargo/packs/armory.dm @@ -183,6 +183,29 @@ var/item = pick(contains) new item(C) +/datum/supply_pack/security/armory/frontier + name = "Old West Surplus Crate" + desc = "Do you have a fauna problem? Do you want to live out your frontier-taming fantasies on a state-of-the-art plasma research and mining station? Do you want to pretend you lived in the Old West of Earthen fame? Well, this box - and its many hats - may be for you." + cost = 7500 + contraband = TRUE + contains = list(/obj/effect/spawner/bundle/crate/cowboyhat, + /obj/effect/spawner/bundle/crate/cowboyboots, + /obj/item/clothing/under/pants/chaps, + /obj/item/reagent_containers/food/snacks/butterbiscuit, + /obj/item/reagent_containers/food/snacks/butterbiscuit, + /obj/item/reagent_containers/food/snacks/plumphelmetbiscuit, + /obj/item/reagent_containers/food/snacks/plumphelmetbiscuit, + /obj/item/ammo_box/c38/pouch, + /obj/item/ammo_box/c38/pouch, + /obj/item/ammo_box/c38/pouch, + /obj/effect/spawner/bundle/crate/levergun + ) + +/datum/supply_pack/security/armory/frontier/fill(obj/structure/closet/crate/C) + for(var/i in 1 to 5) + var/item = pick(contains) + new item(C) + /datum/supply_pack/security/armory/swat name = "SWAT Crate" desc = "Contains two fullbody sets of tough, fireproof, pressurized suits designed in a joint effort by IS-ERI and Nanotrasen. Each set contains a suit, helmet, mask, combat belt, and combat gloves. Requires Armory access to open." diff --git a/code/modules/cargo/packs/emergency.dm b/code/modules/cargo/packs/emergency.dm index 9b2b42da08..45264e7b8c 100644 --- a/code/modules/cargo/packs/emergency.dm +++ b/code/modules/cargo/packs/emergency.dm @@ -158,6 +158,14 @@ /obj/item/clothing/head/hardhat/red) crate_name = "firefighting crate" +/datum/supply_pack/emergency/Flexiseal + name = "Flexi Seal Crate" + desc = "Flexi Seal, the perfect stuff for fixing a nuclear reactor safely!" + cost = 1000 + contains = list(/obj/item/sealant) + crate_name = "Flexi Seal Crate" + crate_type = /obj/structure/closet/crate/radiation + /datum/supply_pack/emergency/atmostank name = "Firefighting Tank Backpack" desc = "Mow down fires with this high-capacity fire fighting tank backpack. Requires Atmospherics access to open." diff --git a/code/modules/cargo/packs/engine.dm b/code/modules/cargo/packs/engine.dm index 499881a110..b7a2d883ce 100644 --- a/code/modules/cargo/packs/engine.dm +++ b/code/modules/cargo/packs/engine.dm @@ -166,3 +166,40 @@ cost = 7000 contains = list(/obj/machinery/the_singularitygen/tesla) crate_name = "tesla generator crate" +/datum/supply_pack/engine/fuel_rod + name = "Uranium Fuel Rod crate" + desc = "Two additional fuel rods for use in a reactor, requires CE access to open. Caution: Radioactive" + cost = 3000 + access = ACCESS_CE + contains = list(/obj/item/fuel_rod, + /obj/item/fuel_rod) + crate_name = "Uranium-235 Fuel Rod crate" + crate_type = /obj/structure/closet/crate/secure/engineering + dangerous = TRUE + +/datum/supply_pack/engine/bananium_fuel_rod + name = "Bananium Fuel Rod crate" + desc = "Two fuel rods designed to utilize and multiply bananium in a reactor, requires CE access to open. Caution: Radioactive" + cost = 4000 + access = ACCESS_CE // Nag your local CE + contains = list(/obj/item/fuel_rod/material/bananium, + /obj/item/fuel_rod/material/bananium) + crate_name = "Bluespace Crystal Fuel Rod crate" + crate_type = /obj/structure/closet/crate/secure/engineering + dangerous = TRUE + contraband = TRUE + +/datum/supply_pack/engine/reactor + name = "RMBK Nuclear Reactor Kit" // (not) a toy + desc = "Contains a reactor beacon and 3 reactor consoles. Uranium rods not included." + cost = 12000 + access = ACCESS_CE + contains = list(/obj/item/survivalcapsule/reactor, + /obj/machinery/computer/reactor/control_rods/cargo, + /obj/machinery/computer/reactor/stats/cargo, + /obj/machinery/computer/reactor/fuel_rods/cargo, + /obj/item/paper/fluff/rbmkcargo, + /obj/item/book/manual/wiki/rbmk) + crate_name = "Build Your Own Reactor Kit" + crate_type = /obj/structure/closet/crate/secure/engineering + dangerous = TRUE diff --git a/code/modules/cargo/packs/engineering.dm b/code/modules/cargo/packs/engineering.dm index 9af18e13f6..4fc50e2385 100644 --- a/code/modules/cargo/packs/engineering.dm +++ b/code/modules/cargo/packs/engineering.dm @@ -49,7 +49,7 @@ /datum/supply_pack/engineering/engihardsuit name = "Engineering Hardsuit" - desc = "Poly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and mask!" + desc = "Polly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and mask!" cost = 2250 access = ACCESS_ENGINE contains = list(/obj/item/tank/internals/air, diff --git a/code/modules/cargo/packs/goodies.dm b/code/modules/cargo/packs/goodies.dm index 5d4598fd58..5151845221 100644 --- a/code/modules/cargo/packs/goodies.dm +++ b/code/modules/cargo/packs/goodies.dm @@ -70,6 +70,12 @@ cost = 1500 contains = list(/obj/item/toy/plush/beeplushie) +/datum/supply_pack/goody/dyespray + name = "Hair Dye Spray" + desc = "A cool spray to dye your hair with awesome colors!" + cost = PAYCHECK_EASY * 2 + contains = list(/obj/item/dyespray) + /datum/supply_pack/goody/beach_ball name = "Beach Ball" desc = "The simple beach ball is one of Nanotrasen's most popular products. 'Why do we make beach balls? Because we can! (TM)' - Nanotrasen" diff --git a/code/modules/cargo/packs/materials.dm b/code/modules/cargo/packs/materials.dm index 90629706b5..8b74b0fbe9 100644 --- a/code/modules/cargo/packs/materials.dm +++ b/code/modules/cargo/packs/materials.dm @@ -20,6 +20,13 @@ cost = 300 //thrice their export value contains = list(/obj/item/stack/sheet/cardboard/fifty) +/datum/supply_pack/materials/license50 + name = "50 Empty License Plates" + desc = "Create a bunch of boxes." + cost = 1000 // 50 * 25 + 700 - 1000 = 950 credits profit + contains = list(/obj/item/stack/license_plates/empty/fifty) + crate_name = "empty license plate crate" + /datum/supply_pack/materials/glass50 crate_type = /obj/structure/closet/secure_closet/cargo name = "50 Glass Sheets" diff --git a/code/modules/cargo/packs/misc.dm b/code/modules/cargo/packs/misc.dm index 91663dbe0f..990e32df67 100644 --- a/code/modules/cargo/packs/misc.dm +++ b/code/modules/cargo/packs/misc.dm @@ -171,11 +171,11 @@ desc = "Start up your own grand casino with this crate filled with slot machine and arcade boards!" cost = 3000 contains = list(/obj/item/circuitboard/computer/arcade/battle, + /obj/item/circuitboard/computer/arcade/battle, /obj/item/circuitboard/computer/arcade/battle, /obj/item/circuitboard/computer/arcade/orion_trail, /obj/item/circuitboard/computer/arcade/orion_trail, - /obj/item/circuitboard/computer/arcade/minesweeper, - /obj/item/circuitboard/computer/arcade/minesweeper, + /obj/item/circuitboard/computer/arcade/orion_trail, /obj/item/circuitboard/computer/slot_machine, /obj/item/circuitboard/computer/slot_machine, /obj/item/circuitboard/computer/slot_machine, diff --git a/code/modules/cargo/packs/science.dm b/code/modules/cargo/packs/science.dm index 125bfe2034..96d9a97b5f 100644 --- a/code/modules/cargo/packs/science.dm +++ b/code/modules/cargo/packs/science.dm @@ -238,3 +238,14 @@ contains = list(/obj/item/raw_anomaly_core/pyro) crate_name = "raw pyro anomaly" crate_type = /obj/structure/closet/crate/secure/science + +/datum/supply_pack/science/mod_core + name = "MOD core Crate" + desc = "Three cores, perfect for any MODsuit construction! Naturally harvested™, of course." + cost = CARGO_CRATE_VALUE * 3 + access = ACCESS_ROBOTICS + contains = list(/obj/item/mod/construction/core, + /obj/item/mod/construction/core, + /obj/item/mod/construction/core) + crate_name = "MOD core crate" + crate_type = /obj/structure/closet/crate/secure/science diff --git a/code/modules/cargo/packs/vending.dm b/code/modules/cargo/packs/vending.dm index 6d978d629f..f0f89a49e6 100644 --- a/code/modules/cargo/packs/vending.dm +++ b/code/modules/cargo/packs/vending.dm @@ -52,7 +52,7 @@ desc = "Packs of tools waiting to be used for repairing. Contains a tool and engineering vending machine refill. Requires CE access." cost = 5500 //Powerfull access = ACCESS_CE - contains = list(/obj/item/vending_refill/tool, + contains = list(/obj/item/vending_refill/youtool, /obj/item/vending_refill/engivend) crate_name = "engineering supply crate" crate_type = /obj/structure/closet/crate/secure/engineering diff --git a/code/modules/cargo/supplypod.dm b/code/modules/cargo/supplypod.dm index 3d2264a593..48baaa80d8 100644 --- a/code/modules/cargo/supplypod.dm +++ b/code/modules/cargo/supplypod.dm @@ -11,7 +11,7 @@ allow_dense = TRUE delivery_icon = null can_weld_shut = FALSE - armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 80) + armor = list(MELEE = 30, BULLET = 50, LASER = 50, ENERGY = 100, BOMB = 100, BIO = 0, RAD = 0, FIRE = 100, ACID = 80) anchored = TRUE //So it cant slide around after landing anchorable = FALSE flags_1 = PREVENT_CONTENTS_EXPLOSION_1 @@ -89,7 +89,7 @@ style = customStyle setStyle(style) //Upon initialization, give the supplypod an iconstate, name, and description based on the "style" variable. This system is important for the centcom_podlauncher to function correctly -/obj/structure/closet/supplypod/extractionpod/Initialize() +/obj/structure/closet/supplypod/extractionpod/Initialize(mapload) . = ..() var/turf/picked_turf = pick(GLOB.holdingfacility) reverse_dropoff_coords = list(picked_turf.x, picked_turf.y, picked_turf.z) @@ -187,10 +187,10 @@ else ..() -/obj/structure/closet/supplypod/ex_act() //Explosions dont do SHIT TO US! This is because supplypods create explosions when they land. +/obj/structure/closet/supplypod/ex_act(severity, target, origin) //Explosions dont do SHIT TO US! This is because supplypods create explosions when they land. return -/obj/structure/closet/supplypod/contents_explosion() //Supplypods also protect their contents from the harmful effects of fucking exploding. +/obj/structure/closet/supplypod/contents_explosion(severity, target, origin) //Supplypods also protect their contents from the harmful effects of fucking exploding. return /obj/structure/closet/supplypod/toggle(mob/living/user) @@ -648,7 +648,7 @@ desc = "This disk provides a firmware update to the Express Supply Console, granting the use of Nanotrasen's Bluespace Drop Pods to the supply department." icon = 'icons/obj/module.dmi' icon_state = "cargodisk" - // inhand_icon_state = "card-id" + // item_state = "card-id" w_class = WEIGHT_CLASS_SMALL // let's not. diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 99f24107c7..c1399ce646 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -4,6 +4,16 @@ //BLACK MAGIC THINGS// ////////////////////// parent_type = /datum + + /////////////// + // Rendering // + /////////////// + + /// Click catcher + var/atom/movable/screen/click_catcher/click_catcher + /// Parallax holder + var/datum/parallax_holder/parallax_holder + //////////////// //ADMIN THINGS// //////////////// @@ -12,6 +22,8 @@ ///Contains admin info. Null if client is not an admin. var/datum/admins/holder = null var/datum/click_intercept = null // Needs to implement InterceptClickOn(user,params,atom) proc + ///Time when the click was intercepted + var/click_intercept_time = 0 var/AI_Interact = 0 var/jobbancache = null //Used to cache this client's jobbans to save on DB queries @@ -34,6 +46,9 @@ var/last_move = 0 var/area = null + /// Timers are now handled by clients, not by doing a mess on the item and multiple people overwriting a single timer on the object, have fun. + var/tip_timer = null + /// Last time we Click()ed. No clicking twice in one tick! var/last_click = 0 @@ -65,6 +80,8 @@ //These two vars are used to make a special mouse cursor, with a unique icon for clicking var/mouse_up_icon = null var/mouse_down_icon = null + ///used to override the mouse cursor so it doesnt get reset + var/mouse_override_icon = null var/ip_intel = "Disabled" @@ -122,10 +139,6 @@ ///Used in MouseDrag to preserve the last mouse-entered object. var/mouseObject = null var/mouseControlObject = null - //Middle-mouse-button click dragtime control for aimbot exploit detection. - var/middragtime = 0 - //Middle-mouse-button clicked object control for aimbot exploit detection. - var/atom/middragatom /// Messages currently seen by this client var/list/seen_messages @@ -150,20 +163,6 @@ ///When was the last time we warned them about not cryoing without an ahelp, set to -5 minutes so that rounstart cryo still warns var/cryo_warned = -5 MINUTES - var/list/parallax_layers - var/list/parallax_layers_cached - var/atom/movable/movingmob - var/turf/previous_turf - ///world.time of when we can state animate()ing parallax again - var/dont_animate_parallax - ///world.time of last parallax update - var/last_parallax_shift - ///ds between parallax updates - var/parallax_throttle = 0 - var/parallax_movedir = 0 - var/parallax_layers_max = 3 - var/parallax_animate_timer - /** * Assoc list with all the active maps - when a screen obj is added to * a map, it's put in here as well. @@ -187,3 +186,6 @@ var/list/block_parry_hinted = list() /// moused over objects, currently capped at 7. this is awful, and should be replaced with a component to track it using signals for parrying at some point. var/list/moused_over_objects = list() + + /// AFK tracking + var/last_activity = 0 diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 571adb406b..6ca963df73 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -79,13 +79,16 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( // Tgui Topic middleware if(tgui_Topic(href_list)) - if(CONFIG_GET(flag/emergency_tgui_logging)) - log_href("[src] (usr:[usr]\[[COORD(usr)]\]) : [hsrc ? "[hsrc] " : ""][href]") return - - //Logs all hrefs + if(href_list["reload_tguipanel"]) + nuke_chat() + if(href_list["reload_statbrowser"]) + src << browse(file('html/statbrowser.html'), "window=statbrowser") + // Log all hrefs log_href("[src] (usr:[usr]\[[COORD(usr)]\]) : [hsrc ? "[hsrc] " : ""][href]") + last_activity = world.time + //byond bug ID:2256651 if (asset_cache_job && (asset_cache_job in completed_asset_jobs)) to_chat(src, "An error has been detected in how your client is receiving resources. Attempting to correct.... (If you keep seeing these messages you might want to close byond and reconnect)") @@ -151,7 +154,15 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( var/atom/target = locate(href_list["statpanel_item_target"]) if(!target) return - Click(target, target.loc, null, "[href_list["statpanel_item_shiftclick"]?"shift=1;":null][href_list["statpanel_item_ctrlclick"]?"ctrl=1;":null]&alt=[href_list["statpanel_item_altclick"]?"alt=1;":null]", FALSE, "statpanel") + var/button = "left=1" + switch(href_list["statpanel_item_click"]) + if("middle") + button = "middle=1" + if("right") + button = "right=1" + else + button = "left=1" + Click(target, target.loc, null, "[button];[href_list["statpanel_item_shiftclick"]?"shift=1;":null][href_list["statpanel_item_ctrlclick"]?"ctrl=1;":null]&alt=[href_list["statpanel_item_altclick"]?"alt=1;":null]", FALSE, "statpanel") /client/proc/is_content_unlocked() if(!prefs.unlock_content) @@ -222,6 +233,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( /////////// /client/New(TopicData) + last_activity = world.time world.SetConfig("APP/admin", ckey, "role=admin") var/tdata = TopicData //save this for later use TopicData = null //Prevent calls to client.Topic from connect @@ -350,13 +362,19 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( return // Initialize tgui panel - tgui_panel.initialize() src << browse(file('html/statbrowser.html'), "window=statbrowser") + addtimer(CALLBACK(src, .proc/check_panel_loaded), 30 SECONDS) + tgui_panel.initialize() - - if(alert_mob_dupe_login) - spawn() - alert(mob, "You have logged in already with another key this round, please log out of this one NOW or risk being banned!") + if(alert_mob_dupe_login && !holder) + var/dupe_login_message = "Your ComputerID has already logged in with another key this round, please log out of this one NOW or risk being banned!" + // if (alert_admin_multikey) + // dupe_login_message += "\nAdmins have been informed." + // message_admins(span_danger("MULTIKEYING:
    [key_name_admin(src)] has a matching CID+IP with another player and is clearly multikeying. They have been warned to leave the server or risk getting banned.")) + // log_admin_private("MULTIKEYING: [key_name(src)] has a matching CID+IP with another player and is clearly multikeying. They have been warned to leave the server or risk getting banned.") + spawn(0.5 SECONDS) //needs to run during world init, do not convert to add timer + alert(mob, dupe_login_message) //players get banned if they don't see this message, do not convert to tgui_alert (or even tg_alert) please. + to_chat(mob, span_danger(dupe_login_message)) connection_time = world.time connection_realtime = world.realtime @@ -407,7 +425,9 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if(holder) add_admin_verbs() - to_chat(src, get_message_output("memo")) + var/admin_memo_note = get_message_output("memo") + if(admin_memo_note) + to_chat(src, admin_memo_note) adminGreet() add_verbs_from_config() @@ -434,8 +454,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( send_resources() - generate_clickcatcher() - apply_clickcatcher() + update_clickcatcher() if(prefs.lastchangelog != GLOB.changelog_hash) //bolds the changelog button on the interface so we know there are updates. to_chat(src, "You have unread updates in the changelog.") @@ -451,7 +470,9 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if(CONFIG_GET(flag/autoconvert_notes)) convert_notes_sql(ckey) - to_chat(src, get_message_output("message", ckey)) + var/admin_message_note = get_message_output("message", ckey) + if(admin_message_note) + to_chat(src, admin_message_note) if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them. to_chat(src, "Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you.") @@ -525,9 +546,6 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( send2adminchat("Server", "[cheesy_message] (No admins online)") QDEL_LIST_ASSOC_VAL(char_render_holders) - if(movingmob != null) - movingmob.client_mobs_in_contents -= mob - UNSETEMPTY(movingmob.client_mobs_in_contents) // seen_messages = null Master.UpdateTickRate() . = ..() //Even though we're going to be hard deleted there are still some things that want to know the destroy is happening @@ -578,9 +596,10 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( //If we aren't an admin, and the flag is set if(CONFIG_GET(flag/panic_bunker) && !holder && !GLOB.deadmins[ckey] && !(ckey in GLOB.bunker_passthrough)) var/living_recs = CONFIG_GET(number/panic_bunker_living) + var/vpn_living_recs = CONFIG_GET(number/panic_bunker_living_vpn) //Relies on pref existing, but this proc is only called after that occurs, so we're fine. var/minutes = get_exp_living(pure_numeric = TRUE) - if(minutes <= living_recs) // && !CONFIG_GET(flag/panic_bunker_interview) + if((minutes <= living_recs) || (IsVPN() && (minutes < vpn_living_recs))) var/reject_message = "Failed Login: [key] - Account attempting to connect during panic bunker, but they do not have the required living time [minutes]/[living_recs]" log_access(reject_message) message_admins("[reject_message]") @@ -850,11 +869,23 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( /client/Click(atom/object, atom/location, control, params, ignore_spam = FALSE, extra_info) if(last_click > world.time - world.tick_lag) return + last_activity = world.time last_click = world.time - var/ab = FALSE + //fullauto stuff + /* + if(!control) + return + */ + if(click_intercept_time) + if(click_intercept_time >= world.time) + click_intercept_time = 0 //Reset and return. Next click should work, but not this one. + return + click_intercept_time = 0 //Just reset. Let's not keep re-checking forever. var/list/L = params2list(params) - if (object && object == middragatom && L["left"]) - ab = max(0, 5 SECONDS-(world.time-middragtime)*0.1) + + if(L["drag"]) + return + var/mcl = CONFIG_GET(number/minute_click_limit) if (!holder && !ignore_spam && mcl) var/minute = round(world.time, 600) @@ -863,20 +894,14 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if (minute != clicklimiter[CURRENT_MINUTE]) clicklimiter[CURRENT_MINUTE] = minute clicklimiter[MINUTE_COUNT] = 0 - clicklimiter[MINUTE_COUNT] += 1+(ab) + clicklimiter[MINUTE_COUNT] += 1 if (clicklimiter[MINUTE_COUNT] > mcl) var/msg = "Your previous click was ignored because you've done too many in a minute." if (minute != clicklimiter[ADMINSWARNED_AT]) //only one admin message per-minute. (if they spam the admins can just boot/ban them) clicklimiter[ADMINSWARNED_AT] = minute msg += " Administrators have been informed." - if (ab) - log_game("[key_name(src)] is using the middle click aimbot exploit") - message_admins("[ADMIN_LOOKUPFLW(src)] [ADMIN_KICK(usr)] is using the middle click aimbot exploit") - add_system_note("aimbot", "Is using the middle click aimbot exploit") - log_click(object, location, control, params, src, "lockout (spam - minute ab c [ab] s [middragtime])", TRUE) - else - log_click(object, location, control, params, src, "lockout (spam - minute)", TRUE) + log_click(object, location, control, params, src, "lockout (spam - minute)", TRUE) log_game("[key_name(src)] Has hit the per-minute click limit of [mcl] clicks in a given game minute") message_admins("[ADMIN_LOOKUPFLW(src)] [ADMIN_KICK(usr)] Has hit the per-minute click limit of [mcl] clicks in a given game minute") to_chat(src, "[msg]") @@ -890,15 +915,11 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if (second != clicklimiter[CURRENT_SECOND]) clicklimiter[CURRENT_SECOND] = second clicklimiter[SECOND_COUNT] = 0 - clicklimiter[SECOND_COUNT] += 1+(!!ab) + clicklimiter[SECOND_COUNT] += 1 if (clicklimiter[SECOND_COUNT] > scl) to_chat(src, "Your previous click was ignored because you've done too many in a second") return - if(ab) //Citadel edit, things with stuff. - log_click(object, location, control, params, src, "dropped (ab c [ab] s [middragtime])", TRUE) - return - if(prefs.log_clicks) log_click(object, location, control, params, src, extra_info? "clicked ([extra_info])" : null) @@ -922,6 +943,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( //checks if a client is afk //3000 frames = 5 minutes /client/proc/is_afk(duration = CONFIG_GET(number/inactivity_period)) + var/inactivity = world.time - last_activity if(inactivity > duration) return inactivity return FALSE @@ -1001,7 +1023,9 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( var/list/old_view = getviewsize(view) view = new_size var/list/actualview = getviewsize(view) - apply_clickcatcher(actualview) + update_clickcatcher() + parallax_holder.Reset() + mob.hud_used.screentip_text.update_view() mob.reload_fullscreen() if (isliving(mob)) var/mob/living/M = mob @@ -1010,33 +1034,31 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( addtimer(CALLBACK(src,.verb/fit_viewport,10)) //Delayed to avoid wingets from Login calls. SEND_SIGNAL(mob, COMSIG_MOB_CLIENT_CHANGE_VIEW, src, old_view, actualview) -/client/proc/generate_clickcatcher() - if(!void) - void = new() - screen += void - -/client/proc/apply_clickcatcher(list/actualview) - generate_clickcatcher() - if(!actualview) - actualview = getviewsize(view) - void.UpdateGreed(actualview[1],actualview[2]) - /client/proc/AnnouncePR(announcement) if(prefs && prefs.chat_toggles & CHAT_PULLR) to_chat(src, announcement) -/client/proc/show_character_previews(mutable_appearance/MA) +/client/proc/show_character_previews(mutable_appearance/source) + LAZYINITLIST(char_render_holders) + if(!LAZYLEN(char_render_holders)) + for(var/plane_master_path as anything in subtypesof(/atom/movable/screen/plane_master)) + var/atom/movable/screen/plane_master/plane_master = new plane_master_path() + char_render_holders["plane_master-[plane_master.plane]"] = plane_master + plane_master.backdrop(mob) + screen |= plane_master + plane_master.screen_loc = "character_preview_map:0,CENTER" + var/pos = 0 - for(var/D in GLOB.cardinals) + for(var/dir in GLOB.cardinals) pos++ - var/atom/movable/screen/O = LAZYACCESS(char_render_holders, "[D]") - if(!O) - O = new - LAZYSET(char_render_holders, "[D]", O) - screen |= O - O.appearance = MA - O.dir = D - O.screen_loc = "character_preview_map:0,[pos]" + var/atom/movable/screen/preview = char_render_holders["preview-[dir]"] + if(!preview) + preview = new + char_render_holders["preview-[dir]"] = preview + screen |= preview + preview.appearance = source + preview.dir = dir + preview.screen_loc = "character_preview_map:0,[pos]" /client/proc/clear_character_previews() for(var/index in char_render_holders) @@ -1072,8 +1094,14 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if(IsAdminAdvancedProcCall()) return var/list/verblist = list() - verb_tabs.Cut() - for(var/thing in (verbs + mob?.verbs)) + var/list/verbstoprocess = verbs.Copy() + if(mob) + verbstoprocess += mob.verbs + for(var/AM in mob.contents) + var/atom/movable/thing = AM + verbstoprocess += thing.verbs + panel_tabs.Cut() // panel_tabs get reset in init_verbs on JS side anyway + for(var/thing in verbstoprocess) var/procpath/verb_to_init = thing if(!verb_to_init) continue @@ -1081,9 +1109,14 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( continue if(!istext(verb_to_init.category)) continue - verb_tabs |= verb_to_init.category + panel_tabs |= verb_to_init.category verblist[++verblist.len] = list(verb_to_init.category, verb_to_init.name) - src << output("[url_encode(json_encode(verb_tabs))];[url_encode(json_encode(verblist))]", "statbrowser:init_verbs") + src << output("[url_encode(json_encode(panel_tabs))];[url_encode(json_encode(verblist))]", "statbrowser:init_verbs") + +/client/proc/check_panel_loaded() + if(statbrowser_ready) + return + to_chat(src, span_userdanger("Statpanel failed to load, click here to reload the panel ")) //increment progress for an unlockable loadout item /client/proc/increment_progress(key, amount) diff --git a/code/modules/client/client_vpn_detect.dm b/code/modules/client/client_vpn_detect.dm new file mode 100644 index 0000000000..bd35a65ef2 --- /dev/null +++ b/code/modules/client/client_vpn_detect.dm @@ -0,0 +1,3 @@ +/client/proc/IsVPN() + var/datum/ipintel/res = get_ip_intel(address) + return res.intel >= CONFIG_GET(number/ipintel_rating_bad) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 5bc0440b77..40011ccbf2 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -60,6 +60,11 @@ GLOBAL_LIST_EMPTY(preferences_datums) //autocorrected this round, not that you'd need to check that. var/UI_style = null + var/outline_enabled = TRUE + var/outline_color = COLOR_THEME_MIDNIGHT + var/screentip_pref = SCREENTIP_PREFERENCE_ENABLED + var/screentip_color = "#ffd391" + var/screentip_images = TRUE var/buttons_locked = FALSE var/hotkeys = FALSE @@ -81,6 +86,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/tgui_lock = TRUE var/windowflashing = TRUE var/toggles = TOGGLES_DEFAULT + /// A separate variable for deadmin toggles, only deals with those. + var/deadmin = NONE var/db_flags var/chat_toggles = TOGGLES_DEFAULT_CHAT var/ghost_form = "ghost" @@ -117,6 +124,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/hair_color = "000000" //Hair color var/facial_hair_style = "Shaved" //Face hair type var/facial_hair_color = "000000" //Facial hair color + var/grad_style //Hair gradient style + var/grad_color = "FFFFFF" //Hair gradient color var/skin_tone = "caucasian1" //Skin color var/use_custom_skin_tone = FALSE var/left_eye_color = "000000" //Eye color @@ -124,7 +133,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/eye_type = DEFAULT_EYES_TYPE //Eye type var/split_eye_colors = FALSE var/datum/species/pref_species = new /datum/species/human() //Mutant race - var/list/features = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF", "mcolor3" = "FFFFFF", "tail_lizard" = "Smooth", "tail_human" = "None", "snout" = "Round", "horns" = "None", "horns_color" = "85615a", "ears" = "None", "wings" = "None", "wings_color" = "FFF", "frills" = "None", "deco_wings" = "None", "spines" = "None", "legs" = "Plantigrade", "insect_wings" = "Plain", "insect_fluff" = "None", "insect_markings" = "None", "arachnid_legs" = "Plain", "arachnid_spinneret" = "Plain", "arachnid_mandibles" = "Plain", "mam_body_markings" = list(), "mam_ears" = "None", "mam_snouts" = "None", "mam_tail" = "None", "mam_tail_animated" = "None", "xenodorsal" = "Standard", "xenohead" = "Standard", "xenotail" = "Xenomorph Tail", "taur" = "None", "genitals_use_skintone" = FALSE, "has_cock" = FALSE, "cock_shape" = DEF_COCK_SHAPE, "cock_length" = COCK_SIZE_DEF, "cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF, "cock_color" = "ffffff", "cock_taur" = FALSE, "has_balls" = FALSE, "balls_color" = "ffffff", "balls_shape" = DEF_BALLS_SHAPE, "balls_size" = BALLS_SIZE_DEF, "balls_cum_rate" = CUM_RATE, "balls_cum_mult" = CUM_RATE_MULT, "balls_efficiency" = CUM_EFFICIENCY, "has_breasts" = FALSE, "breasts_color" = "ffffff", "breasts_size" = BREASTS_SIZE_DEF, "breasts_shape" = DEF_BREASTS_SHAPE, "breasts_producing" = FALSE, "has_vag" = FALSE, "vag_shape" = DEF_VAGINA_SHAPE, "vag_color" = "ffffff", "has_womb" = FALSE, "balls_visibility" = GEN_VISIBLE_NO_UNDIES, "breasts_visibility"= GEN_VISIBLE_NO_UNDIES, "cock_visibility" = GEN_VISIBLE_NO_UNDIES, "vag_visibility" = GEN_VISIBLE_NO_UNDIES, "ipc_screen" = "Sunburst", "ipc_antenna" = "None", "flavor_text" = "", "silicon_flavor_text" = "", "ooc_notes" = "", "meat_type" = "Mammalian", "body_model" = MALE, "body_size" = RESIZE_DEFAULT_SIZE, "color_scheme" = OLD_CHARACTER_COLORING) + var/list/features = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF", "mcolor3" = "FFFFFF", "tail_lizard" = "Smooth", "tail_human" = "None", "snout" = "Round", "horns" = "None", "horns_color" = "85615a", "ears" = "None", "wings" = "None", "wings_color" = "FFF", "frills" = "None", "deco_wings" = "None", "spines" = "None", "legs" = "Plantigrade", "insect_wings" = "Plain", "insect_fluff" = "None", "insect_markings" = "None", "arachnid_legs" = "Plain", "arachnid_spinneret" = "Plain", "arachnid_mandibles" = "Plain", "mam_body_markings" = list(), "mam_ears" = "None", "mam_snouts" = "None", "mam_tail" = "None", "mam_tail_animated" = "None", "xenodorsal" = "Standard", "xenohead" = "Standard", "xenotail" = "Xenomorph Tail", "taur" = "None", "genitals_use_skintone" = FALSE, "has_cock" = FALSE, "cock_shape" = DEF_COCK_SHAPE, "cock_length" = COCK_SIZE_DEF, "cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF, "cock_color" = "ffffff", "cock_taur" = FALSE, "has_balls" = FALSE, "balls_color" = "ffffff", "balls_shape" = DEF_BALLS_SHAPE, "balls_size" = BALLS_SIZE_DEF, "balls_cum_rate" = CUM_RATE, "balls_cum_mult" = CUM_RATE_MULT, "balls_efficiency" = CUM_EFFICIENCY, "has_breasts" = FALSE, "breasts_color" = "ffffff", "breasts_size" = BREASTS_SIZE_DEF, "breasts_shape" = DEF_BREASTS_SHAPE, "breasts_producing" = FALSE, "has_vag" = FALSE, "vag_shape" = DEF_VAGINA_SHAPE, "vag_color" = "ffffff", "has_womb" = FALSE, "has_butt" = FALSE, "butt_color" = "ffffff", "butt_size" = BUTT_SIZE_DEF, "balls_visibility" = GEN_VISIBLE_NO_UNDIES, "breasts_visibility"= GEN_VISIBLE_NO_UNDIES, "cock_visibility" = GEN_VISIBLE_NO_UNDIES, "vag_visibility" = GEN_VISIBLE_NO_UNDIES, "butt_visibility" = GEN_VISIBLE_NO_UNDIES, "ipc_screen" = "Sunburst", "ipc_antenna" = "None", "flavor_text" = "", "silicon_flavor_text" = "", "ooc_notes" = "", "meat_type" = "Mammalian", "body_model" = MALE, "body_size" = RESIZE_DEFAULT_SIZE, "color_scheme" = OLD_CHARACTER_COLORING) var/custom_speech_verb = "default" //if your say_mod is to be something other than your races var/custom_tongue = "default" //if your tongue is to be something other than your races @@ -132,6 +141,13 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/modified_limbs = list() //prosthetic/amputated limbs var/chosen_limb_id //body sprite selected to load for the users limbs, null means default, is sanitized when loaded + // Vocal bark prefs + var/bark_id = "mutedc3" + var/bark_speed = 4 + var/bark_pitch = 1 + var/bark_variance = 0.2 + COOLDOWN_DECLARE(bark_previewing) + /// Security record note section var/security_records /// Medical record note section @@ -145,6 +161,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) //Quirk list var/list/all_quirks = list() + //Quirk category currently selected + var/quirk_category = QUIRK_POSITIVE // defaults to positive, the first tab! + //Job preferences 2.0 - indexed by job title , no key or value implies never var/list/job_preferences = list() @@ -160,13 +179,15 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/clientfps = 0 - var/parallax + var/parallax = PARALLAX_INSANE var/ambientocclusion = TRUE ///Should we automatically fit the viewport? var/auto_fit_viewport = FALSE ///Should we be in the widescreen mode set by the config? var/widescreenpref = TRUE + ///Strip menu style + var/long_strip_menu = FALSE ///What size should pixels be displayed as? 0 is strech to fit var/pixel_size = 0 ///What scaling method should we use? @@ -200,6 +221,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/show_mismatched_markings = FALSE //determines whether or not the markings lists should show markings that don't match the currently selected species. Intentionally left unsaved. + var/character_settings_tab = GENERAL_CHAR_TAB + var/preferences_tab = GAME_PREFS_TAB + var/preview_pref = PREVIEW_PREF_JOB + var/no_tetris_storage = FALSE ///loadout stuff @@ -213,6 +238,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/screenshake = 100 var/damagescreenshake = 2 + var/recoil_screenshake = 100 var/arousable = TRUE var/autostand = TRUE var/auto_ooc = FALSE @@ -240,6 +266,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/list/tcg_cards = list() var/list/tcg_decks = list() + var/loadout_errors = 0 + /datum/preferences/New(client/C) parent = C @@ -278,11 +306,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/list/dat = list("
    ") dat += "Character Settings" - dat += "Character Appearance" - dat += "Character Speech" - dat += "Loadout" - dat += "Game Preferences" - dat += "Content Preferences" + dat += "Preferences" dat += "Keybindings" if(!path) @@ -312,779 +336,958 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "[name] " dat += "
    " - dat += "

    Occupation Choices

    " - dat += "Set Occupation Preferences
    " - if(CONFIG_GET(flag/roundstart_traits)) - dat += "

    Quirk Setup

    " - dat += "Configure Quirks
    " - dat += "
    Current Quirks: [all_quirks.len ? all_quirks.Join(", ") : "None"]
    " - dat += "

    Identity

    " - dat += "" - dat += "
    Records
    " - dat += "
    Security Records
    " - if(length_char(security_records) <= 40) - if(!length(security_records)) - dat += "\[...\]" + dat += "
    " + dat += "
    " + dat += "
    " - if(jobban_isbanned(user, "appearance")) - dat += "You are banned from using custom names and appearances. You can continue to adjust your characters, but you will be randomised once you join the game.
    " - dat += "Random Name " - dat += "Always Random Name:[be_random_name ? "Yes" : "No"]
    " + dat += "
    " - dat += "[nameless ? "Default designation" : "Name"]:" - dat += "[real_name]
    " - dat += "Be nameless: [nameless ? "Yes" : "No"]
    " + dat += "
    " + dat += "General" + dat += "Background" + dat += "Appearance" + dat += "Markings" + dat += "Speech" + dat += "Loadout" //If you change the index of this tab, change all the logic regarding tab + dat += "
    " - dat += "Gender: [gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]
    " - dat += "Age: [age]
    " - - dat += "Special Names:
    " - var/old_group - for(var/custom_name_id in GLOB.preferences_custom_names) - var/namedata = GLOB.preferences_custom_names[custom_name_id] - if(!old_group) - old_group = namedata["group"] - else if(old_group != namedata["group"]) - old_group = namedata["group"] - dat += "
    " - dat += "[namedata["pref_name"]]: [custom_names[custom_name_id]] " - dat += "

    " - - dat += "Custom job preferences:
    " - dat += "Preferred AI Core Display: [preferred_ai_core_display]
    " - dat += "Preferred Security Department: [prefered_security_department]
    " + dat += "" + dat += "" + if(character_settings_tab == LOADOUT_CHAR_TAB) //if loadout + //calculate your gear points from the chosen item + gear_points = CONFIG_GET(number/initial_gear_points) + var/list/chosen_gear = loadout_data["SAVE_[loadout_slot]"] + if(chosen_gear) + loadout_errors = 0 + for(var/loadout_item in chosen_gear) + var/loadout_item_path = loadout_item[LOADOUT_ITEM] + if(!loadout_item_path) + loadout_errors++ + continue + var/datum/gear/loadout_gear = text2path(loadout_item_path) + if(!loadout_gear) + loadout_errors++ + continue + gear_points -= initial(loadout_gear.cost) else - dat += "[security_records]" + chosen_gear = list() + + dat += "" else - dat += "[TextPreview(security_records)]...
    " + dat += "" - dat += "
    Medical Records
    " - if(length_char(medical_records) <= 40) - if(!length(medical_records)) - dat += "\[...\]
    " - else - dat += "[medical_records]" - else - dat += "[TextPreview(medical_records)]...
    " - dat += "
    Hide ckey: [hide_ckey ? "Enabled" : "Disabled"]
    " - dat += "
    " + dat += "
    Preview:

    " + dat += "
    " + dat += "[PREVIEW_PREF_JOB]" + dat += "[PREVIEW_PREF_LOADOUT]" + dat += "[PREVIEW_PREF_NAKED]" + dat += "
    " + dat += "[PREVIEW_PREF_NAKED_AROUSED]" + dat += "
    " + dat += "
    " + dat += "
    [gear_points] loadout point[gear_points == 1 ? "" : "s"] remaining

    " + dat += "
    Clear Loadout
    " + dat += "
    " + dat += "
    Mismatched parts:

    " + dat += "
    [(show_mismatched_markings) ? "Enabled" : "Disabled"]
    " + dat += "
    " + dat += "" + dat += "
    Advanced colors:

    " + dat += "
    [(features["color_scheme"] == ADVANCED_CHARACTER_COLORING) ? "Enabled" : "Disabled"]
    " + dat += "" - //Character Appearance - if(APPEARANCE_TAB) - if(path) - var/savefile/S = new /savefile(path) - if(S) - dat += "
    " - var/name - var/unspaced_slots = 0 - for(var/i=1, i<=max_save_slots, i++) - unspaced_slots++ - if(unspaced_slots > 4) - dat += "
    " - unspaced_slots = 0 - S.cd = "/character[i]" - S["real_name"] >> name - if(!name) - name = "Character[i]" - dat += "[name] " - dat += "
    " + dat += "" + dat += "" + dat += "

    " + dat += "
    " + switch(character_settings_tab) + //General + if(GENERAL_CHAR_TAB) + dat += "

    Occupation Choices

    " + dat += "Set Occupation Preferences
    " + if(CONFIG_GET(flag/roundstart_traits)) + dat += "

    Quirk Setup

    " + dat += "Configure Quirks
    " + dat += "
    Current Quirks: [all_quirks.len ? all_quirks.Join(", ") : "None"]
    " + dat += "

    Identity

    " + dat += "" - var/matrixed_sections = accessory.matrixed_sections - if(accessory.color_src == MATRIXED && !matrixed_sections) - message_admins("Sprite Accessory Failure (customization): Accessory [accessory.type] is a matrixed item without any matrixed sections set!") - continue - else if(accessory.color_src == MATRIXED) - switch(matrixed_sections) - if(MATRIX_GREEN) //only composed of a green section - primary_feature = secondary_feature //swap primary for secondary, so it properly assigns the second colour, reserved for the green section - if(MATRIX_BLUE) - primary_feature = tertiary_feature //same as above, but the tertiary feature is for the blue section - if(MATRIX_RED_BLUE) //composed of a red and blue section - secondary_feature = tertiary_feature //swap secondary for tertiary, as blue should always be tertiary - if(MATRIX_GREEN_BLUE) //composed of a green and blue section - primary_feature = secondary_feature //swap primary for secondary, as first option is green, which is linked to the secondary - secondary_feature = tertiary_feature //swap secondary for tertiary, as second option is blue, which is linked to the tertiary - dat += "Primary Color
    " - dat += "   Change
    " - if((accessory.color_src == MATRIXED && (matrixed_sections == MATRIX_RED_BLUE || matrixed_sections == MATRIX_GREEN_BLUE || matrixed_sections == MATRIX_RED_GREEN || matrixed_sections == MATRIX_ALL)) || (accessory.extra && (accessory.extra_color_src == MUTCOLORS || accessory.extra_color_src == MUTCOLORS2 || accessory.extra_color_src == MUTCOLORS3))) - dat += "Secondary Color
    " - dat += "   Change
    " - if((accessory.color_src == MATRIXED && matrixed_sections == MATRIX_ALL) || (accessory.extra2 && (accessory.extra2_color_src == MUTCOLORS || accessory.extra2_color_src == MUTCOLORS2 || accessory.extra2_color_src == MUTCOLORS3))) - dat += "Tertiary Color
    " - dat += "   Change
    " + dat += "
    " + if(jobban_isbanned(user, "appearance")) + dat += "You are banned from using custom names and appearances. You can continue to adjust your characters, but you will be randomised once you join the game.
    " - dat += "" - else - dat += "

    Left Eye Color

    " - dat += "   Change" - dat += "

    Right Eye Color

    " - dat += "   Change
    " - dat += "" - else if(use_skintones || mutant_colors) + dat += "Gender:[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]
    " + dat += "Age:[age]
    " + dat += "Hide ckey: [hide_ckey ? "Enabled" : "Disabled"]
    " dat += "" - if(HAIR in pref_species.species_traits) + dat += "
    " - dat += "

    Flavor Text

    " - dat += "Set Examine Text
    " - if(length(features["flavor_text"]) <= 40) - if(!length(features["flavor_text"])) - dat += "\[...\]" - else - dat += "[features["flavor_text"]]" - else - dat += "[TextPreview(features["flavor_text"])]...
    " - dat += "

    Silicon Flavor Text

    " - dat += "Set Silicon Examine Text
    " - if(length(features["silicon_flavor_text"]) <= 40) - if(!length(features["silicon_flavor_text"])) - dat += "\[...\]" - else - dat += "[features["silicon_flavor_text"]]" - else - dat += "[TextPreview(features["silicon_flavor_text"])]...
    " - dat += "

    OOC notes

    " - dat += "Set OOC notes
    " - var/ooc_notes_len = length(features["ooc_notes"]) - if(ooc_notes_len <= 40) - if(!ooc_notes_len) - dat += "\[...\]" - else - dat += "[features["ooc_notes"]]" - else - dat += "[TextPreview(features["ooc_notes"])]...
    " - dat += "

    Body

    " - dat += "Gender:[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]
    " - if(gender != NEUTER && pref_species.sexes) - dat += "Body Model:[features["body_model"] == MALE ? "Masculine" : "Feminine"]
    " - dat += "Limb Modification:
    " - dat += "Modify Limbs
    " - for(var/modification in modified_limbs) - if(modified_limbs[modification][1] == LOADOUT_LIMB_PROSTHETIC) - dat += "[modification]: [modified_limbs[modification][2]]
    " - else - dat += "[modification]: [modified_limbs[modification][1]]
    " - dat += "
    " - dat += "Species:[pref_species.name]
    " - dat += "Custom Species Name:[custom_species ? custom_species : "None"]
    " - dat += "Random Body:Randomize!
    " - dat += "Always Random Body:[be_random_body ? "Yes" : "No"]
    " - dat += "
    Cycle background:[bgstate]
    " - var/use_skintones = pref_species.use_skintones - if(use_skintones) - dat += APPEARANCE_CATEGORY_COLUMN + dat += "[nameless ? "Default designation" : "Name"]:
    " + dat += "[real_name]
    " + dat += "Random Name
    " + dat += "Be nameless: [nameless ? "Yes" : "No"]
    " + dat += "Always Random Name:[be_random_name ? "Yes" : "No"]
    " - dat += "

    Skin Tone

    " - - dat += "[use_custom_skin_tone ? "custom:    " : skin_tone]
    " - - var/mutant_colors - if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits)) - if(!use_skintones) - dat += APPEARANCE_CATEGORY_COLUMN - - dat += "

    Advanced Coloring

    " - dat += "[(features["color_scheme"] == ADVANCED_CHARACTER_COLORING) ? "Enabled" : "Disabled"]" - - dat += "

    Body Colors

    " - - dat += "Primary Color:
    " - dat += "    Change
    " - - dat += "Secondary Color:
    " - dat += "    Change
    " - - dat += "Tertiary Color:
    " - dat += "    Change
    " - mutant_colors = TRUE - - dat += "Sprite Size: [features["body_size"]*100]%
    " - - if(!(NOEYES in pref_species.species_traits)) - dat += "

    Eye Type

    " - dat += "[eye_type]
    " - if((EYECOLOR in pref_species.species_traits)) - if(!use_skintones && !mutant_colors) - dat += APPEARANCE_CATEGORY_COLUMN - if(left_eye_color != right_eye_color) - split_eye_colors = TRUE - dat += "

    Heterochromia

    " - dat += "[split_eye_colors ? "Enabled" : "Disabled"]" - if(!split_eye_colors) - dat += "

    Eye Color

    " - dat += "    Change" - dat += "
    " + dat += "Special Names:
    " + var/old_group + for(var/custom_name_id in GLOB.preferences_custom_names) + var/namedata = GLOB.preferences_custom_names[custom_name_id] + if(!old_group) + old_group = namedata["group"] + else if(old_group != namedata["group"]) + old_group = namedata["group"] + dat += "
    " + dat += "[namedata["pref_name"]]: [custom_names[custom_name_id]] " + dat += "

    " - dat += APPEARANCE_CATEGORY_COLUMN + dat += "Custom job preferences:
    " + dat += "Preferred AI Core Display: [preferred_ai_core_display]
    " + dat += "Preferred Security Department: [prefered_security_department]
    " - dat += "

    Hair Style

    " + dat += "
    " + //Character background + if(BACKGROUND_CHAR_TAB) + dat += "" - //Mutant stuff - var/mutant_category = 0 - - dat += APPEARANCE_CATEGORY_COLUMN - dat += "

    Show mismatched markings

    " - dat += "[show_mismatched_markings ? "Yes" : "No"]" - mutant_category++ - if(mutant_category >= MAX_MUTANT_ROWS) //just in case someone sets the max rows to 1 or something dumb like that - dat += "" - mutant_category = 0 - - // rp marking selection - // assume you can only have mam markings or regular markings or none, never both - var/marking_type - if(parent.can_have_part("mam_body_markings")) - marking_type = "mam_body_markings" - if(marking_type) - dat += APPEARANCE_CATEGORY_COLUMN - dat += "

    [GLOB.all_mutant_parts[marking_type]]

    " // give it the appropriate title for the type of marking - dat += "Add marking" - // list out the current markings you have - if(length(features[marking_type])) - dat += "
    " - dat += "[hair_style]" - dat += "< >
    " - dat += "    Change
    " - - dat += "

    Facial Hair Style

    " - - dat += "[facial_hair_style]" - dat += "< >
    " - dat += "    Change
    " - - dat += "
    " - var/list/markings = features[marking_type] - if(!islist(markings)) - // something went terribly wrong - markings = list() - var/list/reverse_markings = reverseList(markings) - for(var/list/marking_list in reverse_markings) - var/marking_index = markings.Find(marking_list) // consider changing loop to go through indexes over lists instead of using Find here - var/limb_value = marking_list[1] - var/actual_name = GLOB.bodypart_names[num2text(limb_value)] // get the actual name from the bitflag representing the part the marking is applied to - var/color_marking_dat = "" - var/number_colors = 1 - var/datum/sprite_accessory/mam_body_markings/S = GLOB.mam_body_markings_list[marking_list[2]] - var/matrixed_sections = S.covered_limbs[actual_name] - if(S && matrixed_sections) - // if it has nothing initialize it to white - if(length(marking_list) == 2) - var/first = "#FFFFFF" - var/second = "#FFFFFF" - var/third = "#FFFFFF" - if(features["mcolor"]) - first = "#[features["mcolor"]]" - if(features["mcolor2"]) - second = "#[features["mcolor2"]]" - if(features["mcolor3"]) - third = "#[features["mcolor3"]]" - marking_list += list(list(first, second, third)) // just assume its 3 colours if it isnt it doesnt matter we just wont use the other values - // index magic - var/primary_index = 1 - var/secondary_index = 2 - var/tertiary_index = 3 - switch(matrixed_sections) - if(MATRIX_GREEN) - primary_index = 2 - if(MATRIX_BLUE) - primary_index = 3 - if(MATRIX_RED_BLUE) - secondary_index = 2 - if(MATRIX_GREEN_BLUE) - primary_index = 2 - secondary_index = 3 - - // we know it has one matrixed section at minimum - color_marking_dat += "   " - // if it has a second section, add it - if(matrixed_sections == MATRIX_RED_BLUE || matrixed_sections == MATRIX_GREEN_BLUE || matrixed_sections == MATRIX_RED_GREEN || matrixed_sections == MATRIX_ALL) - color_marking_dat += "   " - number_colors = 2 - // if it has a third section, add it - if(matrixed_sections == MATRIX_ALL) - color_marking_dat += "   " - number_colors = 3 - color_marking_dat += " Change
    " - dat += "" - dat += "
    [marking_list[2]] - [actual_name] ˄ ˅ X [color_marking_dat]
    " - - for(var/mutant_part in GLOB.all_mutant_parts) - if(mutant_part == "mam_body_markings") - continue - if(parent.can_have_part(mutant_part)) - if(!mutant_category) - dat += APPEARANCE_CATEGORY_COLUMN - dat += "

    [GLOB.all_mutant_parts[mutant_part]]

    " - dat += "[features[mutant_part]]" - var/color_type = GLOB.colored_mutant_parts[mutant_part] //if it can be coloured, show the appropriate button - if(color_type) - dat += "    Change
    " + dat += "

    Flavor Text

    " + dat += "Set Examine Text
    " + if(length(features["flavor_text"]) <= MAX_FLAVOR_PREVIEW_LEN) + if(!length(features["flavor_text"])) + dat += "\[...\]" + else + dat += "[features["flavor_text"]]" else - if(features["color_scheme"] == ADVANCED_CHARACTER_COLORING) //advanced individual part colouring system - //is it matrixed or does it have extra parts to be coloured? - var/find_part = features[mutant_part] || pref_species.mutant_bodyparts[mutant_part] - var/find_part_list = GLOB.mutant_reference_list[mutant_part] - if(find_part && find_part != "None" && find_part_list) - var/datum/sprite_accessory/accessory = find_part_list[find_part] - if(accessory) - if(accessory.color_src == MATRIXED || accessory.color_src == MUTCOLORS || accessory.color_src == MUTCOLORS2 || accessory.color_src == MUTCOLORS3) //mutcolors1-3 are deprecated now, please don't rely on these in the future - var/mutant_string = accessory.mutant_part_string - var/primary_feature = "[mutant_string]_primary" - var/secondary_feature = "[mutant_string]_secondary" - var/tertiary_feature = "[mutant_string]_tertiary" - if(!features[primary_feature]) - features[primary_feature] = features["mcolor"] - if(!features[secondary_feature]) - features[secondary_feature] = features["mcolor2"] - if(!features[tertiary_feature]) - features[tertiary_feature] = features["mcolor3"] + dat += "[TextPreview(features["flavor_text"])]..." + dat += "

    Silicon Flavor Text

    " + dat += "Set Silicon Examine Text
    " + if(length(features["silicon_flavor_text"]) <= MAX_FLAVOR_PREVIEW_LEN) + if(!length(features["silicon_flavor_text"])) + dat += "\[...\]" + else + dat += "[features["silicon_flavor_text"]]" + else + dat += "[TextPreview(features["silicon_flavor_text"])]..." + dat += "

    OOC notes

    " + dat += "Set OOC notes
    " + var/ooc_notes_len = length(features["ooc_notes"]) + if(ooc_notes_len <= MAX_FLAVOR_PREVIEW_LEN) + if(!ooc_notes_len) + dat += "\[...\]" + else + dat += "[features["ooc_notes"]]" + else + dat += "[TextPreview(features["ooc_notes"])]..." + dat += "
    " + dat += "

    Records

    " + dat += "Security Records
    " + if(length_char(security_records) <= 40) + if(!length(security_records)) + dat += "\[...\]" + else + dat += "[security_records]" + else + dat += "[TextPreview(security_records)]..." - mutant_category++ - if(mutant_category >= MAX_MUTANT_ROWS) + dat += "
    Medical Records
    " + if(length_char(medical_records) <= 40) + if(!length(medical_records)) + dat += "\[...\]" + else + dat += "[medical_records]" + else + dat += "[TextPreview(medical_records)]..." + dat += "
    " + //Character Appearance + if(APPEARANCE_CHAR_TAB) + dat += "" + + var/use_skintones = pref_species.use_skintones + if(use_skintones) + dat += APPEARANCE_CATEGORY_COLUMN + + dat += "

    Skin Tone

    " + + dat += "[use_custom_skin_tone ? "custom: [skin_tone]" : skin_tone]
    " + + var/mutant_colors + if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits)) + if(!use_skintones) + dat += APPEARANCE_CATEGORY_COLUMN + + dat += "

    Body Colors

    " + + dat += "Primary Color:
    " + dat += "#[features["mcolor"]]Change
    " + + dat += "Secondary Color:
    " + dat += "#[features["mcolor2"]]Change
    " + + dat += "Tertiary Color:
    " + dat += "#[features["mcolor3"]]Change
    " + mutant_colors = TRUE + + dat += "Sprite Size:[features["body_size"]*100]%
    " + + if(!(NOEYES in pref_species.species_traits)) + dat += "

    Eye Type

    " + dat += "[eye_type]
    " + if((EYECOLOR in pref_species.species_traits)) + if(!use_skintones && !mutant_colors) + dat += APPEARANCE_CATEGORY_COLUMN + if(left_eye_color != right_eye_color) + split_eye_colors = TRUE + dat += "

    Heterochromia

    " + dat += "[split_eye_colors ? "Enabled" : "Disabled"]" + if(!split_eye_colors) + dat += "

    Eye Color

    " + dat += "#[left_eye_color]Change" + else + dat += "

    Left Eye Color

    " + dat += "#[left_eye_color]Change" + dat += "

    Right Eye Color

    " + dat += "#[right_eye_color]Change
    " + + if(HAIR in pref_species.species_traits) + + dat += APPEARANCE_CATEGORY_COLUMN + + dat += "

    Hair Style

    " + + dat += "[hair_style]" + dat += "<>
    " + dat += "#[hair_color]Change
    " + + dat += "

    Facial Hair Style

    " + + dat += "[facial_hair_style]" + dat += "<>
    " + dat += "#[facial_hair_color]Change
    " + + dat += "

    Hair Gradient

    " + + dat += "[grad_style]" + dat += "<>
    " + dat += "#[grad_color]Change
    " + + dat += "" + + //Mutant stuff + var/mutant_category = 0 + + for(var/mutant_part in GLOB.all_mutant_parts) + if(mutant_part == "mam_body_markings") + continue + if(parent.can_have_part(mutant_part)) + if(!mutant_category) + dat += APPEARANCE_CATEGORY_COLUMN + dat += "

    [GLOB.all_mutant_parts[mutant_part]]

    " + dat += "[features[mutant_part]]" + var/color_type = GLOB.colored_mutant_parts[mutant_part] //if it can be coloured, show the appropriate button + if(color_type) + dat += "#[features[color_type]]Change
    " + else + if(features["color_scheme"] == ADVANCED_CHARACTER_COLORING) //advanced individual part colouring system + //is it matrixed or does it have extra parts to be coloured? + var/find_part = features[mutant_part] || pref_species.mutant_bodyparts[mutant_part] + var/find_part_list = GLOB.mutant_reference_list[mutant_part] + if(find_part && find_part != "None" && find_part_list) + var/datum/sprite_accessory/accessory = find_part_list[find_part] + if(accessory) + if(accessory.color_src == MATRIXED || accessory.color_src == MUTCOLORS || accessory.color_src == MUTCOLORS2 || accessory.color_src == MUTCOLORS3) //mutcolors1-3 are deprecated now, please don't rely on these in the future + var/mutant_string = accessory.mutant_part_string + var/primary_feature = "[mutant_string]_primary" + var/secondary_feature = "[mutant_string]_secondary" + var/tertiary_feature = "[mutant_string]_tertiary" + if(!features[primary_feature]) + features[primary_feature] = features["mcolor"] + if(!features[secondary_feature]) + features[secondary_feature] = features["mcolor2"] + if(!features[tertiary_feature]) + features[tertiary_feature] = features["mcolor3"] + + var/matrixed_sections = accessory.matrixed_sections + if(accessory.color_src == MATRIXED && !matrixed_sections) + message_admins("Sprite Accessory Failure (customization): Accessory [accessory.type] is a matrixed item without any matrixed sections set!") + continue + else if(accessory.color_src == MATRIXED) + switch(matrixed_sections) + if(MATRIX_GREEN) //only composed of a green section + primary_feature = secondary_feature //swap primary for secondary, so it properly assigns the second colour, reserved for the green section + if(MATRIX_BLUE) + primary_feature = tertiary_feature //same as above, but the tertiary feature is for the blue section + if(MATRIX_RED_BLUE) //composed of a red and blue section + secondary_feature = tertiary_feature //swap secondary for tertiary, as blue should always be tertiary + if(MATRIX_GREEN_BLUE) //composed of a green and blue section + primary_feature = secondary_feature //swap primary for secondary, as first option is green, which is linked to the secondary + secondary_feature = tertiary_feature //swap secondary for tertiary, as second option is blue, which is linked to the tertiary + dat += "Primary Color
    " + dat += "#[features[primary_feature]]Change
    " + if((accessory.color_src == MATRIXED && (matrixed_sections == MATRIX_RED_BLUE || matrixed_sections == MATRIX_GREEN_BLUE || matrixed_sections == MATRIX_RED_GREEN || matrixed_sections == MATRIX_ALL)) || (accessory.extra && (accessory.extra_color_src == MUTCOLORS || accessory.extra_color_src == MUTCOLORS2 || accessory.extra_color_src == MUTCOLORS3))) + dat += "Secondary Color
    " + dat += "#[features[secondary_feature]]Change
    " + if((accessory.color_src == MATRIXED && matrixed_sections == MATRIX_ALL) || (accessory.extra2 && (accessory.extra2_color_src == MUTCOLORS || accessory.extra2_color_src == MUTCOLORS2 || accessory.extra2_color_src == MUTCOLORS3))) + dat += "Tertiary Color
    " + dat += "#[features[tertiary_feature]]Change
    " + + mutant_category++ + if(mutant_category >= MAX_MUTANT_ROWS) + dat += "" + mutant_category = 0 + + if(length(pref_species.allowed_limb_ids)) + if(!chosen_limb_id || !(chosen_limb_id in pref_species.allowed_limb_ids)) + chosen_limb_id = pref_species.limbs_id || pref_species.id + if(!mutant_category) + dat += APPEARANCE_CATEGORY_COLUMN + dat += "

    Body sprite

    " + dat += "[chosen_limb_id]" + + if(mutant_category) dat += "" mutant_category = 0 - if(length(pref_species.allowed_limb_ids)) - if(!chosen_limb_id || !(chosen_limb_id in pref_species.allowed_limb_ids)) - chosen_limb_id = pref_species.limbs_id || pref_species.id - dat += "

    Body sprite

    " - dat += "[chosen_limb_id]" + dat += "
    " + + dat += "

    Body

    " + dat += "Gender:[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]
    " + if(gender != NEUTER && pref_species.sexes) + dat += "Body Model:[features["body_model"] == MALE ? "Masculine" : "Feminine"]
    " + dat += "Limb Modification:
    " + dat += "Modify Limbs
    " + for(var/modification in modified_limbs) + if(modified_limbs[modification][1] == LOADOUT_LIMB_PROSTHETIC) + dat += "[modification]: [modified_limbs[modification][2]]
    " + else + dat += "[modification]: [modified_limbs[modification][1]]
    " + dat += "
    " + dat += "Species:[pref_species.name]
    " + dat += "Custom Species Name:[custom_species ? custom_species : "None"]
    " + dat += "Random Body:Randomize!
    " + dat += "Always Random Body:[be_random_body ? "Yes" : "No"]
    " + dat += "
    Cycle background:[bgstate]
    " + + dat += "
    " - if(mutant_category) - dat += "" - mutant_category = 0 + dat += "" + dat += "" - dat += "
    " + dat += "

    Clothing & Equipment

    " + dat += "Underwear:[underwear]" + if(GLOB.underwear_list[underwear]?.has_color) + dat += "Underwear Color: #[undie_color] Change
    " + dat += "Undershirt:[undershirt]" + if(GLOB.undershirt_list[undershirt]?.has_color) + dat += "Undershirt Color: #[shirt_color] Change
    " + dat += "Socks:[socks]" + if(GLOB.socks_list[socks]?.has_color) + dat += "Socks Color: #[socks_color] Change
    " + dat += "Backpack:[backbag]" + dat += "Jumpsuit:
    [jumpsuit_style]
    " + if((HAS_FLESH in pref_species.species_traits) || (HAS_BONE in pref_species.species_traits)) + dat += "
    Temporal Scarring:
    [(persistent_scars) ? "Enabled" : "Disabled"]" + dat += "Clear scar slots" + dat += "Uplink Location:[uplink_spawn_loc]" + dat += "
    " + dat += APPEARANCE_CATEGORY_COLUMN - dat += "" - dat += "" - - dat +="" - dat += APPEARANCE_CATEGORY_COLUMN - dat += "

    Breasts

    " - dat += "[features["has_breasts"] == TRUE ? "Yes" : "No"]" - if(features["has_breasts"]) - if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) - dat += "Color:
    " - dat += "   (Skin tone overriding)
    " - else - dat += "Color:
    " - dat += "   Change
    " - dat += "Cup Size:[features["breasts_size"]]" - dat += "Breasts Shape:[features["breasts_shape"]]" - dat += "Breasts Visibility:[features["breasts_visibility"]]" - dat += "Lactates:[features["breasts_producing"] == TRUE ? "Yes" : "No"]" - dat += "" - dat += "" - dat += "
    " - dat += "

    Clothing & Equipment

    " - dat += "Underwear:[underwear]" - if(GLOB.underwear_list[underwear]?.has_color) - dat += "Underwear Color:     Change
    " - dat += "Undershirt:[undershirt]" - if(GLOB.undershirt_list[undershirt]?.has_color) - dat += "Undershirt Color:     Change
    " - dat += "Socks:[socks]" - if(GLOB.socks_list[socks]?.has_color) - dat += "Socks Color:     Change
    " - dat += "Backpack:[backbag]" - dat += "Jumpsuit:
    [jumpsuit_style]
    " - if((HAS_FLESH in pref_species.species_traits) || (HAS_BONE in pref_species.species_traits)) - dat += "
    Temporal Scarring:
    [(persistent_scars) ? "Enabled" : "Disabled"]" - dat += "Clear scar slots" - dat += "Uplink Location:[uplink_spawn_loc]" - dat += "
    " - if(NOGENITALS in pref_species.species_traits) - dat += "Your species ([pref_species.name]) does not support genitals!
    " - else - if(pref_species.use_skintones) - dat += "Genitals use skintone:[features["genitals_use_skintone"] == TRUE ? "Yes" : "No"]" - dat += "

    Penis

    " - dat += "[features["has_cock"] == TRUE ? "Yes" : "No"]" - if(features["has_cock"]) - if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) - dat += "Penis Color:
    " - dat += "   (Skin tone overriding)
    " + if(NOGENITALS in pref_species.species_traits) + dat += "Your species ([pref_species.name]) does not support genitals!
    " else - dat += "Penis Color:
    " - dat += "    Change
    " - var/tauric_shape = FALSE - if(features["cock_taur"]) - var/datum/sprite_accessory/penis/P = GLOB.cock_shapes_list[features["cock_shape"]] - if(P.taur_icon && parent.can_have_part("taur")) - var/datum/sprite_accessory/taur/T = GLOB.taur_list[features["taur"]] - if(T.taur_mode & P.accepted_taurs) - tauric_shape = TRUE - dat += "Penis Shape: [features["cock_shape"]][tauric_shape ? " (Taur)" : ""]" - dat += "Penis Length: [features["cock_length"]] inch(es)" - dat += "Penis Visibility:[features["cock_visibility"]]" - dat += "Has Testicles:[features["has_balls"] == TRUE ? "Yes" : "No"]" - if(features["has_balls"]) - if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) - dat += "Testicles Color:
    " - dat += "   (Skin tone overriding)
    " - else - dat += "Testicles Color:
    " - dat += "    Change
    " - dat += "Testicles Visibility:[features["balls_visibility"]]" - dat += APPEARANCE_CATEGORY_COLUMN - dat += "

    Vagina

    " - dat += "[features["has_vag"] == TRUE ? "Yes" : "No"]" - if(features["has_vag"]) - dat += "Vagina Type: [features["vag_shape"]]" - if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) - dat += "Vagina Color:
    " - dat += "   (Skin tone overriding)
    " - else - dat += "Vagina Color:
    " - dat += "    Change
    " - dat += "Vagina Visibility:[features["vag_visibility"]]" - dat += "Has Womb:[features["has_womb"] == TRUE ? "Yes" : "No"]" - dat += "
    " - - if(SPEECH_TAB) - if(path) - var/savefile/S = new /savefile(path) - if(S) - dat += "
    " - var/name - var/unspaced_slots = 0 - for(var/i=1, i<=max_save_slots, i++) - unspaced_slots++ - if(unspaced_slots > 4) - dat += "
    " - unspaced_slots = 0 - S.cd = "/character[i]" - S["real_name"] >> name - if(!name) - name = "Character[i]" - dat += "[name] " - dat += "
    " - - dat += "" - dat += "
    " - dat += "

    Speech preferences

    " - dat += "Custom Speech Verb:
    " - dat += "[custom_speech_verb]
    " - dat += "Custom Tongue:
    " - dat += "[custom_tongue]
    " - dat += "Additional Language
    " - dat += "[additional_language]
    " - dat += "
    " - - if(GAME_PREFERENCES_TAB) // Game Preferences - dat += "" - if(user.client.holder) - dat +="" - - dat +="" - dat += "
    " - dat += "

    General Settings

    " - dat += "UI Style: [UI_style]
    " - dat += "tgui Monitors: [(tgui_lock) ? "Primary" : "All"]
    " - dat += "tgui Style: [(tgui_fancy) ? "Fancy" : "No Frills"]
    " - dat += "Show Runechat Chat Bubbles: [chat_on_map ? "Enabled" : "Disabled"]
    " - dat += "Runechat message char limit: [max_chat_length]
    " - dat += "See Runechat for non-mobs: [see_chat_non_mob ? "Enabled" : "Disabled"]
    " - dat += "
    " - dat += "Action Buttons: [(buttons_locked) ? "Locked In Place" : "Unlocked"]
    " - dat += "
    " - dat += "PDA Color:     Change
    " - dat += "PDA Style: [pda_style]
    " - dat += "PDA Reskin: [pda_skin]
    " - dat += "
    " - dat += "Ghost Ears: [(chat_toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]
    " - dat += "Ghost Radio: [(chat_toggles & CHAT_GHOSTRADIO) ? "All Messages":"No Messages"]
    " - dat += "Ghost Sight: [(chat_toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]
    " - dat += "Ghost Whispers: [(chat_toggles & CHAT_GHOSTWHISPER) ? "All Speech" : "Nearest Creatures"]
    " - dat += "Ghost PDA: [(chat_toggles & CHAT_GHOSTPDA) ? "All Messages" : "Nearest Creatures"]
    " - dat += "Window Flashing: [(windowflashing) ? "Enabled":"Disabled"]
    " - dat += "
    " - dat += "Play Admin MIDIs: [(toggles & SOUND_MIDI) ? "Enabled":"Disabled"]
    " - dat += "Play Lobby Music: [(toggles & SOUND_LOBBY) ? "Enabled":"Disabled"]
    " - dat += "See Pull Requests: [(chat_toggles & CHAT_PULLR) ? "Enabled":"Disabled"]
    " - dat += "
    " - if(user.client) - if(unlock_content) - dat += "BYOND Membership Publicity: [(toggles & MEMBER_PUBLIC) ? "Public" : "Hidden"]
    " - if(unlock_content || check_rights_for(user.client, R_ADMIN)) - dat += "OOC Color:     Change
    " - dat += "Antag OOC Color:     Change
    " - - dat += "
    " - dat += "

    Admin Settings

    " - dat += "Adminhelp Sounds: [(toggles & SOUND_ADMINHELP)?"Enabled":"Disabled"]
    " - dat += "Announce Login: [(toggles & ANNOUNCE_LOGIN)?"Enabled":"Disabled"]
    " - dat += "
    " - dat += "Combo HUD Lighting: [(toggles & COMBOHUD_LIGHTING)?"Full-bright":"No Change"]
    " - dat += "
    " - dat += "

    Citadel Preferences

    " //Because fuck me if preferences can't be fucking modularized and expected to update in a reasonable timeframe. - dat += "Widescreen: [widescreenpref ? "Enabled ([CONFIG_GET(string/default_view)])" : "Disabled (15x15)"]
    " - dat += "Auto stand: [autostand ? "Enabled" : "Disabled"]
    " - dat += "Auto OOC: [auto_ooc ? "Enabled" : "Disabled"]
    " - dat += "Force Slot Storage HUD: [no_tetris_storage ? "Enabled" : "Disabled"]
    " - dat += "Screen Shake: [(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]
    " - if (user && user.client && !user.client.prefs.screenshake==0) - dat += "Damage Screen Shake: [(damagescreenshake==1) ? "On" : ((damagescreenshake==0) ? "Off" : "Only when down")]
    " - var/p_chaos - if (!preferred_chaos) - p_chaos = "No preference" - else - p_chaos = preferred_chaos - dat += "Preferred Chaos Amount: [p_chaos]
    " - dat += "
    " - dat += "
    " - if(unlock_content) - dat += "Ghost Form: [ghost_form]
    " - dat += "Ghost Orbit: [ghost_orbit]
    " - var/button_name = "If you see this something went wrong." - switch(ghost_accs) - if(GHOST_ACCS_FULL) - button_name = GHOST_ACCS_FULL_NAME - if(GHOST_ACCS_DIR) - button_name = GHOST_ACCS_DIR_NAME - if(GHOST_ACCS_NONE) - button_name = GHOST_ACCS_NONE_NAME - - dat += "Ghost Accessories: [button_name]
    " - switch(ghost_others) - if(GHOST_OTHERS_THEIR_SETTING) - button_name = GHOST_OTHERS_THEIR_SETTING_NAME - if(GHOST_OTHERS_DEFAULT_SPRITE) - button_name = GHOST_OTHERS_DEFAULT_SPRITE_NAME - if(GHOST_OTHERS_SIMPLE) - button_name = GHOST_OTHERS_SIMPLE_NAME - - dat += "Ghosts of Others: [button_name]
    " - dat += "
    " - - dat += "FPS: [clientfps]
    " - - dat += "Income Updates: [(chat_toggles & CHAT_BANKCARD) ? "Allowed" : "Muted"]
    " - dat += "
    " - - dat += "Parallax (Fancy Space): " - switch (parallax) - if (PARALLAX_LOW) - dat += "Low" - if (PARALLAX_MED) - dat += "Medium" - if (PARALLAX_INSANE) - dat += "Insane" - if (PARALLAX_DISABLE) - dat += "Disabled" - else - dat += "High" - dat += "
    " - dat += "Ambient Occlusion: [ambientocclusion ? "Enabled" : "Disabled"]
    " - dat += "Fit Viewport: [auto_fit_viewport ? "Auto" : "Manual"]
    " - dat += "HUD Button Flashes: [hud_toggle_flash ? "Enabled" : "Disabled"]
    " - dat += "HUD Button Flash Color:     Change
    " - -/* CITADEL EDIT - We're using top menu instead - button_name = pixel_size - dat += "Pixel Scaling: [(button_name) ? "Pixel Perfect [button_name]x" : "Stretch to fit"]
    " - - switch(scaling_method) - if(SCALING_METHOD_NORMAL) - button_name = "Nearest Neighbor" - if(SCALING_METHOD_DISTORT) - button_name = "Point Sampling" - if(SCALING_METHOD_BLUR) - button_name = "Bilinear" - dat += "Scaling Method: [button_name]
    " -*/ - - if (CONFIG_GET(flag/maprotation) && CONFIG_GET(flag/tgstyle_maprotation)) - var/p_map = preferred_map - if (!p_map) - p_map = "Default" - if (config.defaultmap) - p_map += " ([config.defaultmap.map_name])" - else - if (p_map in config.maplist) - var/datum/map_config/VM = config.maplist[p_map] - if (!VM) - p_map += " (No longer exists)" - else - p_map = VM.map_name - else - p_map += " (No longer exists)" - if(CONFIG_GET(flag/allow_map_voting)) - dat += "Preferred Map: [p_map]
    " - - dat += "" - - dat += "

    Special Role Settings

    " - - if(jobban_isbanned(user, ROLE_SYNDICATE)) - dat += "You are banned from antagonist roles." - src.be_special = list() - - - for (var/i in GLOB.special_roles) - if(i == ROLE_NO_ANTAGONISM) - dat += "DISABLE ALL ANTAGONISM [(i in be_special) ? "YES" : "NO"]
    " - continue - if(jobban_isbanned(user, i)) - dat += "Be [capitalize(i)]: BANNED
    " - else - var/days_remaining = null - if(ispath(GLOB.special_roles[i]) && CONFIG_GET(flag/use_age_restriction_for_jobs)) //If it's a game mode antag, check if the player meets the minimum age - var/mode_path = GLOB.special_roles[i] - var/datum/game_mode/temp_mode = new mode_path - days_remaining = temp_mode.get_remaining_days(user.client) - - if(days_remaining) - dat += "Be [capitalize(i)]: \[IN [days_remaining] DAYS]
    " - else - dat += "Be [capitalize(i)]: [(i in be_special) ? "Enabled" : "Disabled"]
    " - dat += "Midround Antagonist: [(toggles & MIDROUND_ANTAG) ? "Enabled" : "Disabled"]
    " - - dat += "
    " - - if(LOADOUT_TAB) - //calculate your gear points from the chosen item - gear_points = CONFIG_GET(number/initial_gear_points) - var/list/chosen_gear = loadout_data["SAVE_[loadout_slot]"] - if(chosen_gear) - for(var/loadout_item in chosen_gear) - var/loadout_item_path = loadout_item[LOADOUT_ITEM] - if(loadout_item_path) - var/datum/gear/loadout_gear = text2path(loadout_item_path) - if(loadout_gear) - gear_points -= initial(loadout_gear.cost) - else - chosen_gear = list() - - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - - dat += "" - - dat += "" - dat += "" - dat += "" - dat += "" - for(var/name in GLOB.loadout_items[gear_category][gear_subcategory]) - var/datum/gear/gear = GLOB.loadout_items[gear_category][gear_subcategory][name] - var/donoritem = gear.donoritem - if(donoritem && !gear.donator_ckey_check(user.ckey)) - continue - var/class_link = "" - var/list/loadout_item = has_loadout_gear(loadout_slot, "[gear.type]") - var/extra_loadout_data = "" - if(loadout_item) - class_link = "style='white-space:normal;' class='linkOn' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(name)];toggle_gear=0'" - if(gear.loadout_flags & LOADOUT_CAN_COLOR_POLYCHROMIC) - extra_loadout_data += "
    Color" - for(var/loadout_color in loadout_item[LOADOUT_COLOR]) - extra_loadout_data += "   " + if(pref_species.use_skintones) + dat += "Genitals use skintone:[features["genitals_use_skintone"] == TRUE ? "Yes" : "No"]" + dat += "

    Penis

    " + dat += "[features["has_cock"] == TRUE ? "Yes" : "No"]" + if(features["has_cock"]) + if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) + dat += "Penis Color:
    " + dat += "[SKINTONE2HEX(skin_tone)](Skin tone overriding)
    " else - var/loadout_color_non_poly = "#FFFFFF" - if(length(loadout_item[LOADOUT_COLOR])) - loadout_color_non_poly = loadout_item[LOADOUT_COLOR][1] - extra_loadout_data += "
    Color" - extra_loadout_data += "   " - if(gear.loadout_flags & LOADOUT_CAN_NAME) - extra_loadout_data += "
    Name [loadout_item[LOADOUT_CUSTOM_NAME] ? loadout_item[LOADOUT_CUSTOM_NAME] : "N/A"]" - if(gear.loadout_flags & LOADOUT_CAN_DESCRIPTION) - extra_loadout_data += "
    Description" - else if((gear_points - gear.cost) < 0) - class_link = "style='white-space:normal;' class='linkOff'" - else if(donoritem) - class_link = "style='white-space:normal;background:#ebc42e;' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(name)];toggle_gear=1'" - else if(!istype(gear, /datum/gear/unlockable) || can_use_unlockable(gear)) - class_link = "style='white-space:normal;' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(name)];toggle_gear=1'" - else - class_link = "style='white-space:normal;background:#eb2e2e;' class='linkOff'" - dat += "" - dat += "" - else - //we add the user's progress to the description assuming they have progress - var/datum/gear/unlockable/unlockable = gear - var/progress_made = unlockable_loadout_data[unlockable.progress_key] - if(!progress_made) - progress_made = 0 - dat += "" + dat += "Testicles Color:
    " + dat += "#[features["balls_color"]]Change
    " + dat += "Testicles Shape:[features["balls_shape"]]" + dat += "Testicles Visibility:[features["balls_visibility"]]" + dat += APPEARANCE_CATEGORY_COLUMN + dat += "

    Vagina

    " + dat += "[features["has_vag"] == TRUE ? "Yes" : "No"]" + if(features["has_vag"]) + dat += "Vagina Type:[features["vag_shape"]]" + if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) + dat += "Vagina Color:
    " + dat += "[SKINTONE2HEX(skin_tone)](Skin tone overriding)
    " + else + dat += "Vagina Color:
    " + dat += "#[features["vag_color"]]Change
    " + dat += "Vagina Visibility:[features["vag_visibility"]]" + dat += "Has Womb:[features["has_womb"] == TRUE ? "Yes" : "No"]" + dat += "" + dat += APPEARANCE_CATEGORY_COLUMN + dat += "

    Breasts

    " + dat += "[features["has_breasts"] == TRUE ? "Yes" : "No"]" + if(features["has_breasts"]) + if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) + dat += "Color:
    " + dat += "[SKINTONE2HEX(skin_tone)](Skin tone overriding)
    " + else + dat += "Color:
    " + dat += "#[features["breasts_color"]]Change
    " + dat += "Cup Size:[features["breasts_size"]]" + dat += "Breasts Shape:[features["breasts_shape"]]" + dat += "Breasts Visibility:[features["breasts_visibility"]]" + dat += "Lactates:[features["breasts_producing"] == TRUE ? "Yes" : "No"]" + dat += "" + dat += APPEARANCE_CATEGORY_COLUMN + dat += "

    Butt

    " + dat += "[features["has_butt"] == TRUE ? "Yes" : "No"]" + if(features["has_butt"]) + if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) + dat += "Color:
    " + dat += "[SKINTONE2HEX(skin_tone)](Skin tone overriding)
    " + else + dat += "Color:
    " + dat += "#[features["butt_color"]]Change
    " + dat += "Butt Size:[features["butt_size"]]" + dat += "Butt Visibility:[features["butt_visibility"]]" + dat += "" + dat += "" + dat += "
    [gear_points] loadout points remaining. \[Clear Loadout\]
    You can only choose one item per category, unless it's an item that spawns in your backpack or hands.
    " - - if(!length(GLOB.loadout_items)) - dat += "
    ERROR: No loadout categories - something is horribly wrong!" - else - if(!GLOB.loadout_categories[gear_category]) - gear_category = GLOB.loadout_categories[1] - var/firstcat = TRUE - for(var/category in GLOB.loadout_categories) - if(firstcat) - firstcat = FALSE - else - dat += " |" - if(category == gear_category) - dat += " [category] " - else - dat += " [category] " - - dat += "

    " - - if(!length(GLOB.loadout_categories[gear_category])) - dat += "No subcategories detected. Something is horribly wrong!" - else - var/list/subcategories = GLOB.loadout_categories[gear_category] - if(!subcategories.Find(gear_subcategory)) - gear_subcategory = subcategories[1] - - var/firstsubcat = TRUE - for(var/subcategory in subcategories) - if(firstsubcat) - firstsubcat = FALSE - else - dat += " |" - if(gear_subcategory == subcategory) - dat += " [subcategory] " - else - dat += " [subcategory] " - dat += "
    NameCostRestrictionsDescription
    [name][extra_loadout_data][gear.cost]" - if(islist(gear.restricted_roles)) - if(gear.restricted_roles.len) - if(gear.restricted_desc) - dat += "" - dat += gear.restricted_desc - dat += "" + dat += "Penis Color:
    " + dat += "#[features["cock_color"]] Change
    " + var/tauric_shape = FALSE + if(features["cock_taur"]) + var/datum/sprite_accessory/penis/P = GLOB.cock_shapes_list[features["cock_shape"]] + if(P.taur_icon && parent.can_have_part("taur")) + var/datum/sprite_accessory/taur/T = GLOB.taur_list[features["taur"]] + if(T.taur_mode & P.accepted_taurs) + tauric_shape = TRUE + dat += "Penis Shape: [features["cock_shape"]][tauric_shape ? " (Taur)" : ""]" + dat += "Penis Length: [features["cock_length"]] inch(es)" + dat += "Penis Visibility:[features["cock_visibility"]]" + dat += "Has Testicles:[features["has_balls"] == TRUE ? "Yes" : "No"]" + if(features["has_balls"]) + if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) + dat += "Testicles Color:
    " + dat += "[SKINTONE2HEX(skin_tone)](Skin tone overriding)
    " else - dat += "" - dat += gear.restricted_roles.Join(";") - dat += "" - if(!istype(gear, /datum/gear/unlockable)) - // the below line essentially means "if the loadout item is picked by the user and has a custom description, give it the custom description, otherwise give it the default description" - dat += "
    [loadout_item ? (loadout_item[LOADOUT_CUSTOM_DESCRIPTION] ? loadout_item[LOADOUT_CUSTOM_DESCRIPTION] : gear.description) : gear.description]
    [loadout_item ? (loadout_item[LOADOUT_CUSTOM_DESCRIPTION] ? loadout_item[LOADOUT_CUSTOM_DESCRIPTION] : gear.description) : gear.description] Progress: [min(progress_made, unlockable.progress_required)]/[unlockable.progress_required]
    " + //Markings + if(MARKINGS_CHAR_TAB) + var/iterated_markings = 0 + var/total_pages = 0 + // rp marking selection + // assume you can only have mam markings or regular markings or none, never both + var/marking_type + if(parent.can_have_part("mam_body_markings")) + marking_type = "mam_body_markings" + if(marking_type) + dat += APPEARANCE_CATEGORY_COLUMN + dat += "
    " + dat += "

    [GLOB.all_mutant_parts[marking_type]]

    " // give it the appropriate title for the type of marking + dat += "Add marking" + dat += "
    " + dat += "" + + for(var/limb in GLOB.bodypart_values) + if(length(GLOB.bodypart_values) % 3 != 0) + continue + total_pages++ + + for(var/limb in GLOB.bodypart_values) + if(!iterated_markings) + dat += "" + iterated_markings = 0 + dat += "
    " + dat += "

    [limb]

    " + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + + // list out the current markings you have + if(length(features[marking_type])) + var/list/markings = features[marking_type] + if(!islist(markings)) + // something went terribly wrong + markings = list() + + for(var/list/marking_list in markings) + var/marking_index = markings.Find(marking_list) // consider changing loop to go through indexes over lists instead of using Find here + var/limb_value = marking_list[1] + var/actual_name = GLOB.bodypart_names[num2text(limb_value)] // get the actual name from the bitflag representing the part the marking is applied to + if(actual_name != limb) + continue + var/color_marking_dat = "" + var/number_colors = 1 + var/datum/sprite_accessory/mam_body_markings/S = GLOB.mam_body_markings_list[marking_list[2]] + var/matrixed_sections = S.covered_limbs[actual_name] + if(S && matrixed_sections) + // if it has nothing initialize it to white + if(length(marking_list) == 2) + var/first = "#FFFFFF" + var/second = "#FFFFFF" + var/third = "#FFFFFF" + if(features["mcolor"]) + first = "#[features["mcolor"]]" + if(features["mcolor2"]) + second = "#[features["mcolor2"]]" + if(features["mcolor3"]) + third = "#[features["mcolor3"]]" + marking_list += list(list(first, second, third)) // just assume its 3 colours if it isnt it doesnt matter we just wont use the other values + // index magic + var/primary_index = 1 + var/secondary_index = 2 + var/tertiary_index = 3 + switch(matrixed_sections) + if(MATRIX_GREEN) + primary_index = 2 + if(MATRIX_BLUE) + primary_index = 3 + if(MATRIX_RED_BLUE) + secondary_index = 2 + if(MATRIX_GREEN_BLUE) + primary_index = 2 + secondary_index = 3 + + // we know it has one matrixed section at minimum + color_marking_dat += "[marking_list[3][primary_index]]" + // if it has a second section, add it + if(matrixed_sections == MATRIX_RED_BLUE || matrixed_sections == MATRIX_GREEN_BLUE || matrixed_sections == MATRIX_RED_GREEN || matrixed_sections == MATRIX_ALL) + number_colors = 2 + color_marking_dat += "[marking_list[3][secondary_index]]" + // if it has a third section, add it + if(matrixed_sections == MATRIX_ALL) + number_colors = 3 + color_marking_dat += "[marking_list[3][tertiary_index]]" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + + else + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + + dat += "
    [marking_index]˅˄[marking_list[2]][color_marking_dat]X
    " + + iterated_markings++ + if(iterated_markings >= 3) + dat += "
    " + + if(SPEECH_CHAR_TAB) + dat += "" + dat += "" + dat += "
    " + dat += "

    Speech preferences

    " + dat += "Custom Speech Verb:
    " + dat += "[custom_speech_verb]
    " + dat += "Custom Tongue:
    " + dat += "[custom_tongue]
    " + dat += "Additional Language
    " + dat += "[additional_language]
    " + dat += "
    " + dat += "

    Vocal Bark preferences

    " + var/datum/bark/B = GLOB.bark_list[bark_id] + dat += "Vocal Bark Sound:
    " + dat += "[B ? initial(B.name) : "INVALID"]
    " + dat += "Vocal Bark Speed: [bark_speed]
    " + dat += "Vocal Bark Pitch: [bark_pitch]
    " + dat += "Vocal Bark Variance: [bark_variance]
    " + dat += "
    Preview Bark
    " + dat += "
    " + if(LOADOUT_CHAR_TAB) + dat += "" + dat += "" + dat += "" + dat += "" + + dat += "" + + var/even = FALSE + if(gear_category != LOADOUT_CATEGORY_ERROR) + dat += "
    You can only choose one item per category, unless it's an item that spawns in your backpack or hands.
    " + + if(!length(GLOB.loadout_items)) + dat += "
    ERROR: No loadout categories - something is horribly wrong!" + else + if(!GLOB.loadout_categories[gear_category]) + gear_category = GLOB.loadout_categories[1] + var/firstcat = TRUE + for(var/category in GLOB.loadout_categories) + if(firstcat) + firstcat = FALSE + else + dat += " |" + if(category == gear_category) + dat += " [(category == LOADOUT_CATEGORY_ERROR && loadout_errors) ? "[category] (!)" : category] " + else + dat += " [(category == LOADOUT_CATEGORY_ERROR && loadout_errors) ? "[category] (!)" : category] " + + dat += "

    " + + if(!length(GLOB.loadout_categories[gear_category])) + dat += "No subcategories detected. Something is horribly wrong!" + else + var/list/subcategories = GLOB.loadout_categories[gear_category] + if(!subcategories.Find(gear_subcategory)) + gear_subcategory = subcategories[1] + + var/firstsubcat = TRUE + for(var/subcategory in subcategories) + if(firstsubcat) + firstsubcat = FALSE + else + dat += " |" + if(gear_subcategory == subcategory) + dat += " [subcategory] " + else + dat += " [subcategory] " + dat += "
    " + dat += "
    " + dat += "
    " + dat += "" + dat += "" + dat += "" + dat += "" + + for(var/name in GLOB.loadout_items[gear_category][gear_subcategory]) + var/datum/gear/gear = GLOB.loadout_items[gear_category][gear_subcategory][name] + var/donoritem = gear.donoritem + if(donoritem && !gear.donator_ckey_check(user.ckey)) + continue + var/background_cl = "#23273C" + if(even) + background_cl = "#17191C" + even = !even + var/class_link = "" + var/list/loadout_item = has_loadout_gear(loadout_slot, "[gear.type]") + var/extra_loadout_data = "" + if(loadout_item) + class_link = "style='white-space:normal;' class='linkOn' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(name)];toggle_gear=0'" + if(gear.loadout_flags & LOADOUT_CAN_COLOR_POLYCHROMIC) + extra_loadout_data += "
    Color" + for(var/loadout_color in loadout_item[LOADOUT_COLOR]) + extra_loadout_data += "[loadout_color]" + else + var/loadout_color_non_poly = "#FFFFFF" + if(length(loadout_item[LOADOUT_COLOR])) + loadout_color_non_poly = loadout_item[LOADOUT_COLOR][1] + extra_loadout_data += "
    Color" + extra_loadout_data += "[loadout_color_non_poly]" + if(gear.loadout_flags & LOADOUT_CAN_NAME) + extra_loadout_data += "
    Name [loadout_item[LOADOUT_CUSTOM_NAME] ? loadout_item[LOADOUT_CUSTOM_NAME] : "N/A"]" + if(gear.loadout_flags & LOADOUT_CAN_DESCRIPTION) + extra_loadout_data += "
    Description" + else if((gear_points - gear.cost) < 0) + class_link = "style='white-space:normal;' class='linkOff'" + else if(donoritem) + class_link = "style='white-space:normal;background:#ebc42e;' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(name)];toggle_gear=1'" + else if(!istype(gear, /datum/gear/unlockable) || can_use_unlockable(gear)) + class_link = "style='white-space:normal;' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(name)];toggle_gear=1'" + else + class_link = "style='white-space:normal;background:#eb2e2e;' class='linkOff'" + dat += "" + dat += "" + else + //we add the user's progress to the description assuming they have progress + var/datum/gear/unlockable/unlockable = gear + var/progress_made = unlockable_loadout_data[unlockable.progress_key] + if(!progress_made) + progress_made = 0 + dat += "" + dat += "
    NameCostRestrictionsDescription
    [name][extra_loadout_data][gear.cost]" + if(islist(gear.restricted_roles)) + if(gear.restricted_roles.len) + if(gear.restricted_desc) + dat += "" + dat += gear.restricted_desc + dat += "" + else + dat += "" + dat += gear.restricted_roles.Join(";") + dat += "" + if(!istype(gear, /datum/gear/unlockable)) + // the below line essentially means "if the loadout item is picked by the user and has a custom description, give it the custom description, otherwise give it the default description" + dat += "[loadout_item ? (loadout_item[LOADOUT_CUSTOM_DESCRIPTION] ? loadout_item[LOADOUT_CUSTOM_DESCRIPTION] : gear.description) : gear.description]
    [loadout_item ? (loadout_item[LOADOUT_CUSTOM_DESCRIPTION] ? loadout_item[LOADOUT_CUSTOM_DESCRIPTION] : gear.description) : gear.description] Progress: [min(progress_made, unlockable.progress_required)]/[unlockable.progress_required]
    " + else + dat += "" + dat += "
    " + dat += "
    " + dat += "" + dat += "" + var/list/sanitize_current_slot = loadout_data["SAVE_[loadout_slot]"] + for(var/list/entry in sanitize_current_slot) + var/test_item = entry["loadout_item"] + if(text2path(test_item)) + continue + var/background_cl = "#23273C" + if(even) + background_cl = "#17191C" + even = !even + dat += "" + dat += "" dat += "
    Item typeData contained
    [test_item ? test_item : "no path!!?! Report to an admin!"]" + var/list/other_data = entry["loadout_item"] ? entry - "loadout_item" : entry + dat += json_encode(other_data) + dat += "
    " - if(CONTENT_PREFERENCES_TAB) // Content preferences - dat += "" - dat +="
    " - dat += "

    Fetish content prefs

    " - dat += "Arousal:[arousable == TRUE ? "Enabled" : "Disabled"]
    " - dat += "Genital examine text:[(cit_toggles & GENITAL_EXAMINE) ? "Enabled" : "Disabled"]
    " - dat += "Vore examine text:[(cit_toggles & VORE_EXAMINE) ? "Enabled" : "Disabled"]
    " - dat += "Voracious MediHound sleepers: [(cit_toggles & MEDIHOUND_SLEEPER) ? "Yes" : "No"]
    " - dat += "Hear Vore Sounds: [(cit_toggles & EATING_NOISES) ? "Yes" : "No"]
    " - dat += "Hear Vore Digestion Sounds: [(cit_toggles & DIGESTION_NOISES) ? "Yes" : "No"]
    " - dat += "Allow trash forcefeeding (requires Trashcan quirk) [(cit_toggles & TRASH_FORCEFEED) ? "Yes" : "No"]
    " - dat += "Forced Feminization: [(cit_toggles & FORCED_FEM) ? "Allowed" : "Disallowed"]
    " - dat += "Forced Masculinization: [(cit_toggles & FORCED_MASC) ? "Allowed" : "Disallowed"]
    " - dat += "Lewd Hypno: [(cit_toggles & HYPNO) ? "Allowed" : "Disallowed"]
    " - dat += "Bimbofication: [(cit_toggles & BIMBOFICATION) ? "Allowed" : "Disallowed"]
    " - dat += "
    " - dat += "

    Other content prefs

    " - dat += "Breast Enlargement: [(cit_toggles & BREAST_ENLARGEMENT) ? "Allowed" : "Disallowed"]
    " - dat += "Penis Enlargement: [(cit_toggles & PENIS_ENLARGEMENT) ? "Allowed" : "Disallowed"]
    " - dat += "Hypno: [(cit_toggles & NEVER_HYPNO) ? "Disallowed" : "Allowed"]
    " - dat += "Aphrodisiacs: [(cit_toggles & NO_APHRO) ? "Disallowed" : "Allowed"]
    " - dat += "Ass Slapping: [(cit_toggles & NO_ASS_SLAP) ? "Disallowed" : "Allowed"]
    " - dat += "Automatic Wagging: [(cit_toggles & NO_AUTO_WAG) ? "Disabled" : "Enabled"]
    " - dat += "
    " - dat += "
    " + if(PREFERENCES_TAB) // Game Preferences + dat += "
    " + dat += "General" + dat += "OOC" + dat += "Content" + dat += "
    " + + dat += "
    " + + switch(preferences_tab) + if(GAME_PREFS_TAB) + dat += "" + + dat += "
    " + dat += "

    General Settings

    " + dat += "UI Style: [UI_style]
    " + dat += "Outline: [outline_enabled ? "Enabled" : "Disabled"]
    " + dat += "Outline Color: [outline_color ? "" : "Theme-based (null)"][outline_color] Change
    " + dat += "Screentip: [screentip_pref]
    " + dat += "Screentip Color: [screentip_color] Change
    " + dat += "\ + Screentip context with images: [screentip_images ? "Allowed" : "Disallowed"]
    " + dat += "tgui Monitors: [(tgui_lock) ? "Primary" : "All"]
    " + dat += "tgui Style: [(tgui_fancy) ? "Fancy" : "No Frills"]
    " + dat += "Show Runechat Chat Bubbles: [chat_on_map ? "Enabled" : "Disabled"]
    " + dat += "Runechat message char limit: [max_chat_length]
    " + dat += "See Runechat for non-mobs: [see_chat_non_mob ? "Enabled" : "Disabled"]
    " + dat += "
    " + dat += "Action Buttons: [(buttons_locked) ? "Locked In Place" : "Unlocked"]
    " + dat += "
    " + dat += "PDA Color: [pda_color] Change
    " + dat += "PDA Style: [pda_style]
    " + dat += "PDA Reskin: [pda_skin]
    " + dat += "
    " + dat += "Ghost Ears: [(chat_toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]
    " + dat += "Ghost Radio: [(chat_toggles & CHAT_GHOSTRADIO) ? "All Messages":"No Messages"]
    " + dat += "Ghost Sight: [(chat_toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]
    " + dat += "Ghost Whispers: [(chat_toggles & CHAT_GHOSTWHISPER) ? "All Speech" : "Nearest Creatures"]
    " + dat += "Ghost PDA: [(chat_toggles & CHAT_GHOSTPDA) ? "All Messages" : "Nearest Creatures"]
    " + + dat += "
    " + + dat += "

    Special Role Settings

    " + + if(jobban_isbanned(user, ROLE_SYNDICATE)) + dat += "You are banned from antagonist roles." + src.be_special = list() + + dat += "DISABLE ALL ANTAGONISM [(toggles & NO_ANTAG) ? "YES" : "NO"]
    " + + for (var/i in GLOB.special_roles) + if(jobban_isbanned(user, i)) + dat += "Be [capitalize(i)]: BANNED
    " + else + var/days_remaining = null + if(ispath(GLOB.special_roles[i]) && CONFIG_GET(flag/use_age_restriction_for_jobs)) //If it's a game mode antag, check if the player meets the minimum age + var/mode_path = GLOB.special_roles[i] + var/datum/game_mode/temp_mode = new mode_path + days_remaining = temp_mode.get_remaining_days(user.client) + + if(days_remaining) + dat += "Be [capitalize(i)]: \[IN [days_remaining] DAYS\]
    " + else + var/enabled_text = "" + if(i in be_special) + if(be_special[i] >= 1) + enabled_text = "Enabled" + else + enabled_text = "Low" + else + enabled_text = "Disabled" + dat += "Be [capitalize(i)]: [enabled_text]
    " + dat += "Midround Antagonist: [(toggles & MIDROUND_ANTAG) ? "Enabled" : "Disabled"]
    " + + dat += "
    " + + if(OOC_PREFS_TAB) + dat += "" + dat += "" + + dat += "
    " + dat += "

    OOC Settings

    " + dat += "Window Flashing: [(windowflashing) ? "Enabled":"Disabled"]
    " + dat += "
    " + dat += "Play Admin MIDIs: [(toggles & SOUND_MIDI) ? "Enabled":"Disabled"]
    " + dat += "Play Lobby Music: [(toggles & SOUND_LOBBY) ? "Enabled":"Disabled"]
    " + dat += "See Pull Requests: [(chat_toggles & CHAT_PULLR) ? "Enabled":"Disabled"]
    " + dat += "
    " + if(user.client) + if(unlock_content) + dat += "BYOND Membership Publicity: [(toggles & MEMBER_PUBLIC) ? "Public" : "Hidden"]
    " + if(unlock_content || check_rights_for(user.client, R_ADMIN)) + dat += "OOC Color: [ooccolor ? ooccolor : GLOB.normal_ooc_colour] Change
    " + dat += "Antag OOC Color: [aooccolor ? aooccolor : GLOB.normal_aooc_colour] Change
    " + + if(user.client.holder) + dat += "

    Admin Settings

    " + dat += "Adminhelp Sounds: [(toggles & SOUND_ADMINHELP)?"Enabled":"Disabled"]
    " + dat += "Announce Login: [(toggles & ANNOUNCE_LOGIN)?"Enabled":"Disabled"]
    " + dat += "
    " + dat += "Combo HUD Lighting: [(toggles & COMBOHUD_LIGHTING)?"Full-bright":"No Change"]
    " + + //deadmin + dat += "

    Deadmin While Playing

    " + if(CONFIG_GET(flag/auto_deadmin_players)) + dat += "Always Deadmin: FORCED
    " + else + dat += "Always Deadmin: [(deadmin & DEADMIN_ALWAYS)?"Enabled":"Disabled"]
    " + if(!(deadmin & DEADMIN_ALWAYS)) + dat += "
    " + if(!CONFIG_GET(flag/auto_deadmin_antagonists)) + dat += "As Antag: [(deadmin & DEADMIN_ANTAGONIST)?"Deadmin":"Keep Admin"]
    " + else + dat += "As Antag: FORCED
    " + + if(!CONFIG_GET(flag/auto_deadmin_heads)) + dat += "As Command: [(deadmin & DEADMIN_POSITION_HEAD)?"Deadmin":"Keep Admin"]
    " + else + dat += "As Command: FORCED
    " + + if(!CONFIG_GET(flag/auto_deadmin_security)) + dat += "As Security: [(deadmin & DEADMIN_POSITION_SECURITY)?"Deadmin":"Keep Admin"]
    " + else + dat += "As Security: FORCED
    " + + if(!CONFIG_GET(flag/auto_deadmin_silicons)) + dat += "As Silicon: [(deadmin & DEADMIN_POSITION_SILICON)?"Deadmin":"Keep Admin"]
    " + else + dat += "As Silicon: FORCED
    " + + dat += "
    " + + dat += "

    Citadel Preferences

    " //Because fuck me if preferences can't be fucking modularized and expected to update in a reasonable timeframe. + dat += "Widescreen: [widescreenpref ? "Enabled ([CONFIG_GET(string/default_view)])" : "Disabled (15x15)"]
    " + dat += "Long strip menu: [long_strip_menu ? "Enabled" : "Disabled"]
    " + dat += "Auto stand: [autostand ? "Enabled" : "Disabled"]
    " + dat += "Auto OOC: [auto_ooc ? "Enabled" : "Disabled"]
    " + dat += "Force Slot Storage HUD: [no_tetris_storage ? "Enabled" : "Disabled"]
    " + dat += "Screen Shake: [(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]
    " + if (user && user.client && !user.client.prefs.screenshake==0) + dat += "Damage Screen Shake: [(damagescreenshake==1) ? "On" : ((damagescreenshake==0) ? "Off" : "Only when down")]
    " + dat += "Recoil Screen Push: [(recoil_screenshake==100) ? "Full" : ((recoil_screenshake==0) ? "None" : "[screenshake]")]
    " + var/p_chaos + if (!preferred_chaos) + p_chaos = "No preference" + else + p_chaos = preferred_chaos + dat += "Preferred Chaos Amount: [p_chaos]
    " + dat += "
    " + + if(unlock_content) + dat += "Ghost Form: [ghost_form]
    " + dat += "Ghost Orbit: [ghost_orbit]
    " + var/button_name = "If you see this something went wrong." + switch(ghost_accs) + if(GHOST_ACCS_FULL) + button_name = GHOST_ACCS_FULL_NAME + if(GHOST_ACCS_DIR) + button_name = GHOST_ACCS_DIR_NAME + if(GHOST_ACCS_NONE) + button_name = GHOST_ACCS_NONE_NAME + + dat += "Ghost Accessories: [button_name]
    " + switch(ghost_others) + if(GHOST_OTHERS_THEIR_SETTING) + button_name = GHOST_OTHERS_THEIR_SETTING_NAME + if(GHOST_OTHERS_DEFAULT_SPRITE) + button_name = GHOST_OTHERS_DEFAULT_SPRITE_NAME + if(GHOST_OTHERS_SIMPLE) + button_name = GHOST_OTHERS_SIMPLE_NAME + + dat += "Ghosts of Others: [button_name]
    " + dat += "
    " + + dat += "FPS: [clientfps]
    " + + dat += "Income Updates: [(chat_toggles & CHAT_BANKCARD) ? "Allowed" : "Muted"]
    " + dat += "
    " + + dat += "Parallax (Fancy Space): " + switch (parallax) + if (PARALLAX_LOW) + dat += "Low" + if (PARALLAX_MED) + dat += "Medium" + if (PARALLAX_INSANE) + dat += "Insane" + if (PARALLAX_DISABLE) + dat += "Disabled" + else + dat += "High" + dat += "
    " + dat += "Ambient Occlusion: [ambientocclusion ? "Enabled" : "Disabled"]
    " + dat += "Fit Viewport: [auto_fit_viewport ? "Auto" : "Manual"]
    " + dat += "HUD Button Flashes: [hud_toggle_flash ? "Enabled" : "Disabled"]
    " + dat += "HUD Button Flash Color: [hud_toggle_color] Change
    " + + + if (CONFIG_GET(flag/maprotation) && CONFIG_GET(flag/tgstyle_maprotation)) + var/p_map = preferred_map + if (!p_map) + p_map = "Default" + if (config.defaultmap) + p_map += " ([config.defaultmap.map_name])" + else + if (p_map in config.maplist) + var/datum/map_config/VM = config.maplist[p_map] + if (!VM) + p_map += " (No longer exists)" + else + p_map = VM.map_name + else + p_map += " (No longer exists)" + if(CONFIG_GET(flag/allow_map_voting)) + dat += "Preferred Map: [p_map]
    " + + dat += "
    " + + if(CONTENT_PREFS_TAB) + dat += "" + dat +="
    " + dat += "

    Fetish content prefs

    " + dat += "Arousal:[arousable == TRUE ? "Enabled" : "Disabled"]
    " + dat += "Genital examine text:[(cit_toggles & GENITAL_EXAMINE) ? "Enabled" : "Disabled"]
    " + dat += "Vore examine text:[(cit_toggles & VORE_EXAMINE) ? "Enabled" : "Disabled"]
    " + dat += "Voracious MediHound sleepers: [(cit_toggles & MEDIHOUND_SLEEPER) ? "Yes" : "No"]
    " + dat += "Hear Vore Sounds: [(cit_toggles & EATING_NOISES) ? "Yes" : "No"]
    " + dat += "Hear Vore Digestion Sounds: [(cit_toggles & DIGESTION_NOISES) ? "Yes" : "No"]
    " + dat += "Allow trash forcefeeding (requires Trashcan quirk) [(cit_toggles & TRASH_FORCEFEED) ? "Yes" : "No"]
    " + dat += "Forced Feminization: [(cit_toggles & FORCED_FEM) ? "Allowed" : "Disallowed"]
    " + dat += "Forced Masculinization: [(cit_toggles & FORCED_MASC) ? "Allowed" : "Disallowed"]
    " + dat += "Lewd Hypno: [(cit_toggles & HYPNO) ? "Allowed" : "Disallowed"]
    " + dat += "Bimbofication: [(cit_toggles & BIMBOFICATION) ? "Allowed" : "Disallowed"]
    " + dat += "
    " + dat += "

    Other content prefs

    " + dat += "Breast Enlargement: [(cit_toggles & BREAST_ENLARGEMENT) ? "Allowed" : "Disallowed"]
    " + dat += "Penis Enlargement: [(cit_toggles & PENIS_ENLARGEMENT) ? "Allowed" : "Disallowed"]
    " + dat += "Butt Enlargement: [(cit_toggles & BUTT_ENLARGEMENT) ? "Allowed" : "Disallowed"]
    " + dat += "Hypno: [(cit_toggles & NEVER_HYPNO) ? "Disallowed" : "Allowed"]
    " + dat += "Aphrodisiacs: [(cit_toggles & NO_APHRO) ? "Disallowed" : "Allowed"]
    " + dat += "Ass Slapping: [(cit_toggles & NO_ASS_SLAP) ? "Disallowed" : "Allowed"]
    " + dat += "Automatic Wagging: [(cit_toggles & NO_AUTO_WAG) ? "Disabled" : "Enabled"]
    " + dat += "
    " + if(KEYBINDINGS_TAB) // Custom keybindings dat += "Keybindings: [(hotkeys) ? "Hotkeys" : "Input"]
    " dat += "Keybindings mode controls how the game behaves with tab and map/input focus.
    If it is on Hotkeys, the game will always attempt to force you to map focus, meaning keypresses are sent \ @@ -1399,9 +1602,17 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "
    " dat += "
    Current quirks: [all_quirks.len ? all_quirks.Join(", ") : "None"]
    " dat += "
    [GetPositiveQuirkCount()] / [MAX_QUIRKS] max positive quirks
    \ - Quirk balance remaining: [GetQuirkBalance()]

    " + Quirk balance remaining: [GetQuirkBalance()]
    " + dat += " [QUIRK_POSITIVE] " + dat += " [QUIRK_NEUTRAL] " + dat += " [QUIRK_NEGATIVE] " + dat += "


    " for(var/V in SSquirks.quirks) var/datum/quirk/T = SSquirks.quirks[V] + var/value = initial(T.value) + if((value > 0 && quirk_category != QUIRK_POSITIVE) || (value < 0 && quirk_category != QUIRK_NEGATIVE) || (value == 0 && quirk_category != QUIRK_NEUTRAL)) + continue + var/quirk_name = initial(T.name) var/has_quirk var/quirk_cost = initial(T.value) * -1 @@ -1423,7 +1634,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) quirk_cost = "+[quirk_cost]" var/font_color = "#AAAAFF" if(initial(T.value) != 0) - font_color = initial(T.value) > 0 ? "#AAFFAA" : "#FFAAAA" + font_color = value > 0 ? "#AAFFAA" : "#FFAAAA" if(quirk_conflict) dat += "[quirk_name] - [initial(T.desc)] \ LOCKED: [lock_reason]
    " @@ -1553,6 +1764,12 @@ GLOBAL_LIST_EMPTY(preferences_datums) SetQuirks(user) return TRUE + else if(href_list["quirk_category"]) + var/temp_quirk_category = href_list["quirk_category"] + if(temp_quirk_category == QUIRK_POSITIVE || temp_quirk_category == QUIRK_NEUTRAL || temp_quirk_category == QUIRK_NEGATIVE) + quirk_category = temp_quirk_category + SetQuirks(user) + switch(href_list["task"]) if("random") switch(href_list["preference"]) @@ -1632,16 +1849,16 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("name") var/new_name = input(user, "Choose your character's name:", "Character Preference") as text|null if(new_name) - new_name = reject_bad_name(new_name) + new_name = reject_bad_name(new_name, allow_numbers = TRUE) if(new_name) real_name = new_name else to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") if("age") - var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference") as num|null + var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX_INPUT])", "Character Preference") as num|null if(new_age) - age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN) + age = max(min( round(text2num(new_age)), AGE_MAX_INPUT),AGE_MIN) if("security_records") var/rec = stripped_multiline_input(usr, "Set your security record note section. This should be IC!", "Security Records", html_decode(security_records), MAX_FLAVOR_LEN, TRUE) @@ -1707,6 +1924,23 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("previous_facehair_style") facial_hair_style = previous_list_item(facial_hair_style, GLOB.facial_hair_styles_list) + if("grad_color") + var/new_grad_color = input(user, "Choose your character's gradient colour:", "Character Preference","#"+grad_color) as color|null + if(new_grad_color) + grad_color = sanitize_hexcolor(new_grad_color, 6) + + if("grad_style") + var/new_grad_style + new_grad_style = input(user, "Choose your character's hair gradient style:", "Character Preference") as null|anything in GLOB.hair_gradients_list + if(new_grad_style) + grad_style = new_grad_style + + if("next_grad_style") + grad_style = next_list_item(grad_style, GLOB.hair_gradients_list) + + if("previous_grad_style") + grad_style = previous_list_item(grad_style, GLOB.hair_gradients_list) + if("cycle_bg") bgstate = next_list_item(bgstate, bgstate_options) @@ -2104,6 +2338,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/datum/sprite_accessory/S = instance if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id)) continue + if(S.ignore) + continue if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey))) snowflake_taur_list[S.name] = path var/new_taur @@ -2232,7 +2468,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) features["cock_shape"] = new_shape if("cock_visibility") - var/n_vis = input(user, "Penis Visibility", "Character Preference") as null|anything in CONFIG_GET(keyed_list/safe_visibility_toggles) + var/n_vis = input(user, "Penis Visibility", "Character Preference") as null|anything in CONFIG_GET(str_list/safe_visibility_toggles) if(n_vis) features["cock_visibility"] = n_vis @@ -2247,8 +2483,14 @@ GLOBAL_LIST_EMPTY(preferences_datums) else to_chat(user,"Invalid color. Your color is not bright enough.") + if("balls_shape") + var/new_shape + new_shape = input(user, "Testicle Shape", "Character Preference") as null|anything in GLOB.balls_shapes_list + if(new_shape) + features["balls_shape"] = new_shape + if("balls_visibility") - var/n_vis = input(user, "Testicles Visibility", "Character Preference") as null|anything in CONFIG_GET(keyed_list/safe_visibility_toggles) + var/n_vis = input(user, "Testicles Visibility", "Character Preference") as null|anything in CONFIG_GET(str_list/safe_visibility_toggles) if(n_vis) features["balls_visibility"] = n_vis @@ -2275,7 +2517,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) to_chat(user,"Invalid color. Your color is not bright enough.") if("breasts_visibility") - var/n_vis = input(user, "Breasts Visibility", "Character Preference") as null|anything in CONFIG_GET(keyed_list/safe_visibility_toggles) + var/n_vis = input(user, "Breasts Visibility", "Character Preference") as null|anything in CONFIG_GET(str_list/safe_visibility_toggles) if(n_vis) features["breasts_visibility"] = n_vis @@ -2297,19 +2539,42 @@ GLOBAL_LIST_EMPTY(preferences_datums) to_chat(user,"Invalid color. Your color is not bright enough.") if("vag_visibility") - var/n_vis = input(user, "Vagina Visibility", "Character Preference") as null|anything in CONFIG_GET(keyed_list/safe_visibility_toggles) + var/n_vis = input(user, "Vagina Visibility", "Character Preference") as null|anything in CONFIG_GET(str_list/safe_visibility_toggles) if(n_vis) features["vag_visibility"] = n_vis + if("butt_color") + var/new_buttcolor = input(user, "Butt color:", "Character Preference","#"+features["butt_color"]) as color|null + if(new_buttcolor) + var/temp_hsv = RGBtoHSV(new_buttcolor) + if(new_buttcolor == "#000000") + features["butt_color"] = pref_species.default_color + else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3]) + features["butt_color"] = sanitize_hexcolor(new_buttcolor, 6) + else + to_chat(user,"Invalid color. Your color is not bright enough.") + + if("butt_size") + var/min_B = CONFIG_GET(number/butt_min_size_prefs) + var/max_B = CONFIG_GET(number/butt_max_size_prefs) + var/new_length = input(user, "Butt size:\n([min_B]-[max_B])", "Character Preference") as num|null + if(new_length) + features["butt_size"] = clamp(round(new_length), min_B, max_B) + + if("butt_visibility") + var/n_vis = input(user, "Butt Visibility", "Character Preference") as null|anything in CONFIG_GET(str_list/safe_visibility_toggles) + if(n_vis) + features["butt_visibility"] = n_vis + if("ooccolor") var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference",ooccolor) as color|null if(new_ooccolor) - ooccolor = new_ooccolor + ooccolor = sanitize_ooccolor(new_ooccolor) if("aooccolor") var/new_aooccolor = input(user, "Choose your Antag OOC colour:", "Game Preference",ooccolor) as color|null if(new_aooccolor) - aooccolor = new_aooccolor + aooccolor = sanitize_ooccolor(new_aooccolor) if("bag") var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference") as null|anything in GLOB.backbaglist @@ -2406,7 +2671,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) gender = chosengender if("body_size") - var/new_body_size = input(user, "Choose your desired sprite size: (90-125%)\nWarning: This may make your character look distorted. Additionally, any size under 100% takes a 10% maximum health penalty", "Character Preference", features["body_size"]*100) as num|null + var/new_body_size = input(user, "Choose your desired sprite size: ([CONFIG_GET(number/body_size_min)]-[CONFIG_GET(number/body_size_max)]%)\nWarning: This may make your character look distorted. Additionally, any size under 100% takes a 10% maximum health penalty", "Character Preference", features["body_size"]*100) as num|null if(new_body_size) features["body_size"] = clamp(new_body_size * 0.01, CONFIG_GET(number/body_size_min), CONFIG_GET(number/body_size_max)) @@ -2425,6 +2690,43 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(selected_language) additional_language = selected_language + if("barksound") + var/list/woof_woof = list() + for(var/path in GLOB.bark_list) + var/datum/bark/B = GLOB.bark_list[path] + if(initial(B.ignore)) + continue + if(initial(B.ckeys_allowed)) + var/list/allowed = initial(B.ckeys_allowed) + if(!allowed.Find(user.client.ckey)) + continue + woof_woof[initial(B.name)] = initial(B.id) + var/new_bork = input(user, "Choose your desired vocal bark", "Character Preference") as null|anything in woof_woof + if(new_bork) + bark_id = woof_woof[new_bork] + var/datum/bark/B = GLOB.bark_list[bark_id] //Now we need sanitization to take into account bark-specific min/max values + bark_speed = round(clamp(bark_speed, initial(B.minspeed), initial(B.maxspeed)), 1) + bark_pitch = clamp(bark_pitch, initial(B.minpitch), initial(B.maxpitch)) + bark_variance = clamp(bark_variance, initial(B.minvariance), initial(B.maxvariance)) + + if("barkspeed") + var/datum/bark/B = GLOB.bark_list[bark_id] + var/borkset = input(user, "Choose your desired bark speed (Higher is slower, lower is faster). Min: [initial(B.minspeed)]. Max: [initial(B.maxspeed)]", "Character Preference") as null|num + if(borkset) + bark_speed = round(clamp(borkset, initial(B.minspeed), initial(B.maxspeed)), 1) + + if("barkpitch") + var/datum/bark/B = GLOB.bark_list[bark_id] + var/borkset = input(user, "Choose your desired baseline bark pitch. Min: [initial(B.minpitch)]. Max: [initial(B.maxpitch)]", "Character Preference") as null|num + if(borkset) + bark_pitch = clamp(borkset, initial(B.minpitch), initial(B.maxpitch)) + + if("barkvary") + var/datum/bark/B = GLOB.bark_list[bark_id] + var/borkset = input(user, "Choose your desired baseline bark pitch. Min: [initial(B.minvariance)]. Max: [initial(B.maxvariance)]", "Character Preference") as null|num + if(borkset) + bark_variance = clamp(borkset, initial(B.minvariance), initial(B.maxvariance)) + if("bodysprite") var/selected_body_sprite = input(user, "Choose your desired body sprite", "Character Preference") as null|anything in pref_species.allowed_limb_ids if(selected_body_sprite) @@ -2493,47 +2795,36 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/limb_value = text2num(GLOB.bodypart_values[limb]) features[marking_type] += list(list(limb_value, selected_marking)) - if("marking_color") + if("marking_color_specific") var/index = text2num(href_list["marking_index"]) var/marking_type = href_list["marking_type"] - if(index && marking_type && features[marking_type]) - // work out the input options to show the user - var/list/options = list("Primary") - var/number_colors = text2num(href_list["number_colors"]) - var/color_number = 1 // 1-3 which color are we editing - if(number_colors >= 2) - options += "Secondary" - if(number_colors == 3) - options += "Tertiary" - var/color_option = input(user, "Select the colour you wish to edit") as null|anything in options - if(color_option) - if(color_option == "Secondary") color_number = 2 - if(color_option == "Tertiary") color_number = 3 - // perform some magic on the color number - var/list/marking_list = features[marking_type][index] - var/datum/sprite_accessory/mam_body_markings/S = GLOB.mam_body_markings_list[marking_list[2]] - var/matrixed_sections = S.covered_limbs[GLOB.bodypart_names[num2text(marking_list[1])]] - if(color_number == 1) - switch(matrixed_sections) - if(MATRIX_GREEN) - color_number = 2 - if(MATRIX_BLUE) - color_number = 3 - else if(color_number == 2) - switch(matrixed_sections) - if(MATRIX_RED_BLUE) - color_number = 3 - if(MATRIX_GREEN_BLUE) - color_number = 3 + var/color_number = text2num(href_list["number_color"]) + if(index && marking_type && color_number && features[marking_type]) + // perform some magic on the color number + var/list/marking_list = features[marking_type][index] + var/datum/sprite_accessory/mam_body_markings/S = GLOB.mam_body_markings_list[marking_list[2]] + var/matrixed_sections = S.covered_limbs[GLOB.bodypart_names[num2text(marking_list[1])]] + if(color_number == 1) + switch(matrixed_sections) + if(MATRIX_GREEN) + color_number = 2 + if(MATRIX_BLUE) + color_number = 3 + else if(color_number == 2) + switch(matrixed_sections) + if(MATRIX_RED_BLUE) + color_number = 3 + if(MATRIX_GREEN_BLUE) + color_number = 3 - var/color_list = features[marking_type][index][3] - var/new_marking_color = input(user, "Choose your character's marking color:", "Character Preference","#"+color_list[color_number]) as color|null - if(new_marking_color) - var/temp_hsv = RGBtoHSV(new_marking_color) - if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3]) // mutantcolors must be bright, but only if they affect the skin - color_list[color_number] = "#[sanitize_hexcolor(new_marking_color, 6)]" - else - to_chat(user, "Invalid color. Your color is not bright enough.") + var/color_list = features[marking_type][index][3] + var/new_marking_color = input(user, "Choose your character's marking color:", "Character Preference","#"+color_list[color_number]) as color|null + if(new_marking_color) + var/temp_hsv = RGBtoHSV(new_marking_color) + if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3]) // mutantcolors must be bright, but only if they affect the skin + color_list[color_number] = "#[sanitize_hexcolor(new_marking_color, 6)]" + else + to_chat(user, "Invalid color. Your color is not bright enough.") else switch(href_list["preference"]) //CITADEL PREFERENCES EDIT - I can't figure out how to modularize these, so they have to go here. :c -Pooj @@ -2559,9 +2850,13 @@ GLOBAL_LIST_EMPTY(preferences_datums) features["has_womb"] = FALSE if("has_womb") features["has_womb"] = !features["has_womb"] + if("has_butt") + features["has_butt"] = !features["has_butt"] if("widescreenpref") widescreenpref = !widescreenpref user.client.view_size.setDefault(getScreenSize(widescreenpref)) + if("long_strip_menu") + long_strip_menu = !long_strip_menu if("pixel_size") switch(pixel_size) @@ -2594,7 +2889,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("no_tetris_storage") no_tetris_storage = !no_tetris_storage if ("screenshake") - var/desiredshake = input(user, "Set the amount of screenshake you want. \n(0 = disabled, 100 = full, 200 = maximum.)", "Character Preference", screenshake) as null|num + var/desiredshake = input(user, "Set the amount of screenshake you want. \n(0 = disabled, 100 = full, no maximum (at your own risk).)", "Character Preference", screenshake) as null|num if (!isnull(desiredshake)) screenshake = desiredshake if("damagescreenshake") @@ -2607,6 +2902,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) damagescreenshake = 0 else damagescreenshake = 1 + if ("recoil_screenshake") + var/desiredshake = input(user, "Set the amount of recoil screenshake/push you want. \n(0 = disabled, 100 = full, no maximum (at your own risk).)", "Character Preference", screenshake) as null|num + if (!isnull(desiredshake)) + recoil_screenshake = desiredshake if("nameless") nameless = !nameless //END CITADEL EDIT @@ -2706,6 +3005,22 @@ GLOBAL_LIST_EMPTY(preferences_datums) buttons_locked = !buttons_locked if("tgui_fancy") tgui_fancy = !tgui_fancy + if("outline_enabled") + outline_enabled = !outline_enabled + if("outline_color") + var/pickedOutlineColor = input(user, "Choose your outline color.", "General Preference", outline_color) as color|null + if(pickedOutlineColor != pickedOutlineColor) + outline_color = pickedOutlineColor // nullable + if("screentip_pref") + var/choice = input(user, "Choose your screentip preference", "Screentipping?", screentip_pref) as null|anything in GLOB.screentip_pref_options + if(choice) + screentip_pref = choice + if("screentip_color") + var/pickedScreentipColor = input(user, "Choose your screentip color.", "General Preference", screentip_color) as color|null + if(pickedScreentipColor) + screentip_color = pickedScreentipColor + if("screentip_images") + screentip_images = !screentip_images if("tgui_lock") tgui_lock = !tgui_lock if("winflash") @@ -2717,12 +3032,32 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("combohud_lighting") toggles ^= COMBOHUD_LIGHTING + // Deadmin preferences + if("toggle_deadmin_always") + deadmin ^= DEADMIN_ALWAYS + if("toggle_deadmin_antag") + deadmin ^= DEADMIN_ANTAGONIST + if("toggle_deadmin_head") + deadmin ^= DEADMIN_POSITION_HEAD + if("toggle_deadmin_security") + deadmin ^= DEADMIN_POSITION_SECURITY + if("toggle_deadmin_silicon") + deadmin ^= DEADMIN_POSITION_SILICON + // + + if("disable_antag") + toggles ^= NO_ANTAG + if("be_special") var/be_special_type = href_list["be_special_type"] if(be_special_type in be_special) - be_special -= be_special_type + if(be_special[be_special_type] >= 1) + be_special -= be_special_type + else + be_special[be_special_type] = 1 else be_special += be_special_type + be_special[be_special_type] = 0 if("name") be_random_name = !be_random_name @@ -2776,14 +3111,12 @@ GLOBAL_LIST_EMPTY(preferences_datums) toggles ^= MIDROUND_ANTAG if("parallaxup") - parallax = WRAP(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) - if (parent && parent.mob && parent.mob.hud_used) - parent.mob.hud_used.update_parallax_pref(parent.mob) + parallax = WRAP(parallax + 1, PARALLAX_DISABLE, PARALLAX_INSANE + 1) + parent?.parallax_holder?.Reset() if("parallaxdown") - parallax = WRAP(parallax - 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) - if (parent && parent.mob && parent.mob.hud_used) - parent.mob.hud_used.update_parallax_pref(parent.mob) + parallax = WRAP(parallax - 1, PARALLAX_DISABLE, PARALLAX_INSANE + 1) + parent?.parallax_holder?.Reset() // Citadel edit - Prefs don't work outside of this. :c @@ -2811,6 +3144,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("penis_enlargement") cit_toggles ^= PENIS_ENLARGEMENT + if("butt_enlargement") + cit_toggles ^= BUTT_ENLARGEMENT + if("feminization") cit_toggles ^= FORCED_FEM @@ -2855,6 +3191,23 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("hud_toggle_flash") hud_toggle_flash = !hud_toggle_flash + if("barkpreview") + if(SSticker.current_state == GAME_STATE_STARTUP) //Timers don't tick at all during game startup, so let's just give an error message + to_chat(user, "Bark previews can't play during initialization!") + return + if(!COOLDOWN_FINISHED(src, bark_previewing)) + return + if(!parent || !parent.mob) + return + COOLDOWN_START(src, bark_previewing, (5 SECONDS)) + var/atom/movable/barkbox = new(get_turf(parent.mob)) + barkbox.set_bark(bark_id) + var/total_delay + for(var/i in 1 to (round((32 / bark_speed)) + 1)) + addtimer(CALLBACK(barkbox, /atom/movable/proc/bark, list(parent.mob), 7, 70, BARK_DO_VARY(bark_pitch, bark_variance)), total_delay) + total_delay += rand(DS2TICKS(bark_speed/4), DS2TICKS(bark_speed/4) + DS2TICKS(bark_speed/4)) TICKS + QDEL_IN(barkbox, total_delay) + if("save") save_preferences() save_character() @@ -2872,6 +3225,18 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("tab") if(href_list["tab"]) current_tab = text2num(href_list["tab"]) + + if("character_preview") + preview_pref = href_list["tab"] + + if("character_tab") + if(href_list["tab"]) + character_settings_tab = text2num(href_list["tab"]) + + if("preferences_tab") + if(href_list["tab"]) + preferences_tab = text2num(href_list["tab"]) + if(href_list["preference"] == "gear") if(href_list["clear_loadout"]) loadout_data["SAVE_[loadout_slot]"] = list() @@ -2909,6 +3274,15 @@ GLOBAL_LIST_EMPTY(preferences_datums) loadout_data["SAVE_[loadout_slot]"] += list(new_loadout_data) //double packed because it does the union of the CONTENTS of the lists else loadout_data["SAVE_[loadout_slot]"] = list(new_loadout_data) //double packed because you somehow had no save slot in your loadout? + if(href_list["clear_invalid_gear"]) + var/thing_to_remove = html_decode(href_list["clear_invalid_gear"]) + if(!thing_to_remove) + return + var/list/sanitize_current_slot = loadout_data["SAVE_[loadout_slot]"] + for(var/list/entry in sanitize_current_slot) + if(entry["loadout_item"] == thing_to_remove) + sanitize_current_slot.Remove(list(entry)) + break if(href_list["loadout_color"] || href_list["loadout_color_polychromic"] || href_list["loadout_rename"] || href_list["loadout_redescribe"]) //if the gear doesn't exist, or they don't have it, ignore the request @@ -3006,6 +3380,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) character.dna.skin_tone_override = use_custom_skin_tone ? skin_tone : null character.hair_style = hair_style character.facial_hair_style = facial_hair_style + character.grad_style = grad_style + character.grad_color = grad_color character.underwear = underwear character.saved_underwear = underwear @@ -3026,6 +3402,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) save_character() character.dna.features = features.Copy() + character.set_species(chosen_species, icon_update = FALSE, pref_load = TRUE) character.dna.species.eye_type = eye_type if(chosen_limb_id && (chosen_limb_id in character.dna.species.allowed_limb_ids)) @@ -3070,8 +3447,14 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(additional_language && additional_language != "None") var/language_entry = GLOB.roundstart_languages[additional_language] if(language_entry) + character.additional_language = language_entry character.grant_language(language_entry, TRUE, TRUE) + character.set_bark(bark_id) + character.vocal_speed = bark_speed + character.vocal_pitch = bark_pitch + character.vocal_pitch_range = bark_variance + //limb stuff, only done when initially spawning in if(initial_spawn) //delete any existing prosthetic limbs to make sure no remnant prosthetics are left over - But DO NOT delete those that are species-related @@ -3183,10 +3566,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/occupied_slots = L[initial(G.category)] ? L[initial(G.category)] + 1 : 1 LAZYSET(L, initial(G.category), occupied_slots) switch(slot) - if(SLOT_IN_BACKPACK) + if(ITEM_SLOT_BACKPACK) if(L[LOADOUT_CATEGORY_BACKPACK] < BACKPACK_SLOT_AMT) return TRUE - if(SLOT_HANDS) + if(ITEM_SLOT_HANDS) if(L[LOADOUT_CATEGORY_HANDS] < HANDS_SLOT_AMT) return TRUE else diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index d4d13dc40f..6bb704f8a5 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -5,7 +5,7 @@ // You do not need to raise this if you are adding new values that have sane defaults. // Only raise this value when changing the meaning/format/name/layout of an existing value // where you would want the updater procs below to run -#define SAVEFILE_VERSION_MAX 52 +#define SAVEFILE_VERSION_MAX 58 /* SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn @@ -42,9 +42,26 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car //if your savefile is 3 months out of date, then 'tough shit'. /datum/preferences/proc/update_preferences(current_version, savefile/S) + if(current_version < 30) + outline_enabled = TRUE + outline_color = COLOR_THEME_MIDNIGHT if(current_version < 46) //If you remove this, remove force_reset_keybindings() too. force_reset_keybindings_direct(TRUE) addtimer(CALLBACK(src, .proc/force_reset_keybindings), 30) //No mob available when this is run, timer allows user choice. + if(current_version < 55) //Bitflag toggles don't set their defaults when they're added, always defaulting to off instead. + toggles |= SOUND_BARK + if(current_version < 56) + if("NO_ANTAGS" in be_special) + toggles |= NO_ANTAG + be_special -= "NO_ANTAGS" + for(var/be_special_type in be_special) + be_special[be_special_type] = 1 + if(current_version < 57) + if(screentip_pref) + screentip_pref = SCREENTIP_PREFERENCE_ENABLED + else + // Let's give it a little chance okay, change if you don't like still. + screentip_pref = SCREENTIP_PREFERENCE_CONTEXT_ONLY /datum/preferences/proc/update_character(current_version, savefile/S) if(current_version < 19) @@ -69,15 +86,15 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car var/job_engsec_med = 0 var/job_engsec_low = 0 - S["job_civilian_high"] >> job_civilian_high - S["job_civilian_med"] >> job_civilian_med - S["job_civilian_low"] >> job_civilian_low - S["job_medsci_high"] >> job_medsci_high - S["job_medsci_med"] >> job_medsci_med - S["job_medsci_low"] >> job_medsci_low - S["job_engsec_high"] >> job_engsec_high - S["job_engsec_med"] >> job_engsec_med - S["job_engsec_low"] >> job_engsec_low + S["job_civilian_high"] >> job_civilian_high + S["job_civilian_med"] >> job_civilian_med + S["job_civilian_low"] >> job_civilian_low + S["job_medsci_high"] >> job_medsci_high + S["job_medsci_med"] >> job_medsci_med + S["job_medsci_low"] >> job_medsci_low + S["job_engsec_high"] >> job_engsec_high + S["job_engsec_med"] >> job_engsec_med + S["job_engsec_low"] >> job_engsec_low //Can't use SSjob here since this happens right away on login for(var/job in subtypesof(/datum/job)) @@ -123,29 +140,29 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car var/list/json_from_file = json_decode(file2text(vr_path)) if(json_from_file) if(json_from_file["digestable"]) - ENABLE_BITFIELD(vore_flags,DIGESTABLE) + vore_flags |= DIGESTABLE if(json_from_file["devourable"]) - ENABLE_BITFIELD(vore_flags,DEVOURABLE) + vore_flags |= DEVOURABLE if(json_from_file["feeding"]) - ENABLE_BITFIELD(vore_flags,FEEDING) + vore_flags |= FEEDING if(json_from_file["lickable"]) - ENABLE_BITFIELD(vore_flags,LICKABLE) + vore_flags |= LICKABLE belly_prefs = json_from_file["belly_prefs"] vore_taste = json_from_file["vore_taste"] for(var/V in all_quirks) // quirk migration switch(V) if("Acute hepatic pharmacokinesis") - DISABLE_BITFIELD(cit_toggles, PENIS_ENLARGEMENT) - DISABLE_BITFIELD(cit_toggles, BREAST_ENLARGEMENT) - ENABLE_BITFIELD(cit_toggles,FORCED_FEM) - ENABLE_BITFIELD(cit_toggles,FORCED_MASC) + cit_toggles &= ~(PENIS_ENLARGEMENT) + cit_toggles &= ~(BREAST_ENLARGEMENT) + cit_toggles |= FORCED_FEM + cit_toggles |= FORCED_MASC all_quirks -= V if("Crocin Immunity") - ENABLE_BITFIELD(cit_toggles,NO_APHRO) + cit_toggles |= NO_APHRO all_quirks -= V if("Buns of Steel") - ENABLE_BITFIELD(cit_toggles,NO_ASS_SLAP) + cit_toggles |= NO_ASS_SLAP all_quirks -= V if(features["meat_type"] == "Inesct") @@ -170,18 +187,18 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car var/devourable var/feeding var/lickable - S["digestable"] >> digestable - S["devourable"] >> devourable - S["feeding"] >> feeding - S["lickable"] >> lickable + S["digestable"] >> digestable + S["devourable"] >> devourable + S["feeding"] >> feeding + S["lickable"] >> lickable if(digestable) - ENABLE_BITFIELD(vore_flags,DIGESTABLE) + vore_flags |= DIGESTABLE if(devourable) - ENABLE_BITFIELD(vore_flags,DEVOURABLE) + vore_flags |= DEVOURABLE if(feeding) - ENABLE_BITFIELD(vore_flags,FEEDING) + vore_flags |= FEEDING if(lickable) - ENABLE_BITFIELD(vore_flags,LICKABLE) + vore_flags |= LICKABLE if(current_version < 30) switch(features["taur"]) @@ -193,8 +210,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car features["taur"] = "Cow (Spotted)" if(current_version < 31) - S["wing_color"] >> features["wings_color"] - S["horn_color"] >> features["horns_color"] + S["wing_color"] >> features["wings_color"] + S["horn_color"] >> features["horns_color"] if(current_version < 33) features["flavor_text"] = html_encode(features["flavor_text"]) @@ -340,6 +357,36 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car marking_list += list(list(part, old_marking_value, copied_color_list)) features["mam_body_markings"] = marking_list + if(current_version < 53) + parallax = PARALLAX_INSANE + + // Some genius decided to make features update on the loading part, go figure. + if(current_version < 54) + var/old_silicon_flavor = S["silicon_feature_flavor_text"] + if(length(old_silicon_flavor)) + features["feature_silicon_flavor_text"] = old_silicon_flavor + var/old_flavor_text = S["flavor_text"] + // If they have the old flavor text but also have the new one, i suppose the new one is more important. + if(length(old_flavor_text) && !length(features["feature_flavor_text"])) + features["feature_flavor_text"] = old_flavor_text + + // hey what happened to 55 + + // dullahans as a species cease to exist + if(current_version < 56) + var/species_id = S["species"] + if(species_id == SPECIES_DULLAHAN) + S["species"] = SPECIES_HUMAN + if(islist(S["all_quirks"])) + S["all_quirks"] += "Dullahan" + else + S["all_quirks"] = list("Dullahan") + + // So, we're already on 57 even though we were meant to be on like, 56? i'm gonna try to correct this, + // And i'm so sorry for this. + if(current_version < 58) + S["screentip_images"] = TRUE // This was meant to default active, i'm so sorry. Turn it off if you must. + /datum/preferences/proc/load_path(ckey,filename="preferences.sav") if(!ckey) return @@ -374,64 +421,72 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car . = TRUE //general preferences - S["ooccolor"] >> ooccolor - S["lastchangelog"] >> lastchangelog - S["UI_style"] >> UI_style - S["hotkeys"] >> hotkeys - S["chat_on_map"] >> chat_on_map - S["max_chat_length"] >> max_chat_length + S["ooccolor"] >> ooccolor + S["lastchangelog"] >> lastchangelog + S["UI_style"] >> UI_style + S["outline_color"] >> outline_color + S["outline_enabled"] >> outline_enabled + S["screentip_pref"] >> screentip_pref + S["screentip_color"] >> screentip_color + S["screentip_images"] >> screentip_images + S["hotkeys"] >> hotkeys + S["chat_on_map"] >> chat_on_map + S["max_chat_length"] >> max_chat_length S["see_chat_non_mob"] >> see_chat_non_mob - S["tgui_fancy"] >> tgui_fancy - S["tgui_lock"] >> tgui_lock - S["buttons_locked"] >> buttons_locked - S["windowflash"] >> windowflashing + S["tgui_fancy"] >> tgui_fancy + S["tgui_lock"] >> tgui_lock + S["buttons_locked"] >> buttons_locked + S["windowflash"] >> windowflashing S["be_special"] >> be_special - S["default_slot"] >> default_slot - S["chat_toggles"] >> chat_toggles - S["toggles"] >> toggles - S["ghost_form"] >> ghost_form - S["ghost_orbit"] >> ghost_orbit - S["ghost_accs"] >> ghost_accs - S["ghost_others"] >> ghost_others - S["preferred_map"] >> preferred_map - S["ignoring"] >> ignoring - S["ghost_hud"] >> ghost_hud - S["inquisitive_ghost"] >> inquisitive_ghost + S["default_slot"] >> default_slot + S["chat_toggles"] >> chat_toggles + S["toggles"] >> toggles + S["deadmin"] >> deadmin + S["ghost_form"] >> ghost_form + S["ghost_orbit"] >> ghost_orbit + S["ghost_accs"] >> ghost_accs + S["ghost_others"] >> ghost_others + S["preferred_map"] >> preferred_map + S["ignoring"] >> ignoring + S["ghost_hud"] >> ghost_hud + S["inquisitive_ghost"] >> inquisitive_ghost S["uses_glasses_colour"]>> uses_glasses_colour - S["clientfps"] >> clientfps - S["parallax"] >> parallax - S["ambientocclusion"] >> ambientocclusion - S["auto_fit_viewport"] >> auto_fit_viewport - S["widescreenpref"] >> widescreenpref + S["clientfps"] >> clientfps + S["parallax"] >> parallax + S["ambientocclusion"] >> ambientocclusion + S["auto_fit_viewport"] >> auto_fit_viewport + S["widescreenpref"] >> widescreenpref + S["long_strip_menu"] >> long_strip_menu S["pixel_size"] >> pixel_size S["scaling_method"] >> scaling_method - S["hud_toggle_flash"] >> hud_toggle_flash - S["hud_toggle_color"] >> hud_toggle_color - S["menuoptions"] >> menuoptions - S["enable_tips"] >> enable_tips - S["tip_delay"] >> tip_delay - S["pda_style"] >> pda_style - S["pda_color"] >> pda_color - S["pda_skin"] >> pda_skin + S["hud_toggle_flash"] >> hud_toggle_flash + S["hud_toggle_color"] >> hud_toggle_color + S["menuoptions"] >> menuoptions + S["enable_tips"] >> enable_tips + S["tip_delay"] >> tip_delay + S["pda_style"] >> pda_style + S["pda_color"] >> pda_color + S["pda_skin"] >> pda_skin // Custom hotkeys - S["key_bindings"] >> key_bindings - S["modless_key_bindings"] >> modless_key_bindings + S["key_bindings"] >> key_bindings + S["modless_key_bindings"] >> modless_key_bindings //citadel code - S["arousable"] >> arousable - S["screenshake"] >> screenshake - S["damagescreenshake"] >> damagescreenshake - S["autostand"] >> autostand - S["cit_toggles"] >> cit_toggles - S["preferred_chaos"] >> preferred_chaos - S["auto_ooc"] >> auto_ooc - S["no_tetris_storage"] >> no_tetris_storage + S["arousable"] >> arousable + S["screenshake"] >> screenshake + S["damagescreenshake"] >> damagescreenshake + S["autostand"] >> autostand + S["cit_toggles"] >> cit_toggles + S["preferred_chaos"] >> preferred_chaos + S["auto_ooc"] >> auto_ooc + S["no_tetris_storage"] >> no_tetris_storage + S["recoil_screenshake"] >> recoil_screenshake //favorite outfits - S["favorite_outfits"] >> favorite_outfits + S["favorite_outfits"] >> favorite_outfits var/list/parsed_favs = list() for(var/typetext in favorite_outfits) @@ -449,46 +504,51 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car update_preferences(needs_update, S) //needs_update = savefile_version if we need an update (positive integer) //Sanitize - ooccolor = sanitize_ooccolor(sanitize_hexcolor(ooccolor, 6, 1, initial(ooccolor))) - lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog)) - UI_style = sanitize_inlist(UI_style, GLOB.available_ui_styles, GLOB.available_ui_styles[1]) - hotkeys = sanitize_integer(hotkeys, 0, 1, initial(hotkeys)) - chat_on_map = sanitize_integer(chat_on_map, 0, 1, initial(chat_on_map)) + ooccolor = sanitize_ooccolor(sanitize_hexcolor(ooccolor, 6, 1, initial(ooccolor))) + lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog)) + UI_style = sanitize_inlist(UI_style, GLOB.available_ui_styles, GLOB.available_ui_styles[1]) + hotkeys = sanitize_integer(hotkeys, 0, 1, initial(hotkeys)) + chat_on_map = sanitize_integer(chat_on_map, 0, 1, initial(chat_on_map)) max_chat_length = sanitize_integer(max_chat_length, 1, CHAT_MESSAGE_MAX_LENGTH, initial(max_chat_length)) - see_chat_non_mob = sanitize_integer(see_chat_non_mob, 0, 1, initial(see_chat_non_mob)) - tgui_fancy = sanitize_integer(tgui_fancy, 0, 1, initial(tgui_fancy)) - tgui_lock = sanitize_integer(tgui_lock, 0, 1, initial(tgui_lock)) - buttons_locked = sanitize_integer(buttons_locked, 0, 1, initial(buttons_locked)) - windowflashing = sanitize_integer(windowflashing, 0, 1, initial(windowflashing)) - default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot)) - toggles = sanitize_integer(toggles, 0, 16777215, initial(toggles)) - clientfps = sanitize_integer(clientfps, 0, 1000, 0) - parallax = sanitize_integer(parallax, PARALLAX_INSANE, PARALLAX_DISABLE, null) - ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion)) - auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport)) - widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref)) - pixel_size = sanitize_integer(pixel_size, PIXEL_SCALING_AUTO, PIXEL_SCALING_3X, initial(pixel_size)) - scaling_method = sanitize_text(scaling_method, initial(scaling_method)) + see_chat_non_mob = sanitize_integer(see_chat_non_mob, 0, 1, initial(see_chat_non_mob)) + tgui_fancy = sanitize_integer(tgui_fancy, 0, 1, initial(tgui_fancy)) + tgui_lock = sanitize_integer(tgui_lock, 0, 1, initial(tgui_lock)) + buttons_locked = sanitize_integer(buttons_locked, 0, 1, initial(buttons_locked)) + windowflashing = sanitize_integer(windowflashing, 0, 1, initial(windowflashing)) + default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot)) + toggles = sanitize_integer(toggles, 0, 16777215, initial(toggles)) + deadmin = sanitize_integer(deadmin, 0, 16777215, initial(deadmin)) + clientfps = sanitize_integer(clientfps, 0, 1000, 0) + parallax = sanitize_integer(parallax, PARALLAX_DISABLE, PARALLAX_INSANE, null) + ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion)) + auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport)) + widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref)) + long_strip_menu = sanitize_integer(long_strip_menu, 0, 1, initial(long_strip_menu)) + pixel_size = sanitize_integer(pixel_size, PIXEL_SCALING_AUTO, PIXEL_SCALING_3X, initial(pixel_size)) + scaling_method = sanitize_text(scaling_method, initial(scaling_method)) hud_toggle_flash = sanitize_integer(hud_toggle_flash, 0, 1, initial(hud_toggle_flash)) hud_toggle_color = sanitize_hexcolor(hud_toggle_color, 6, 1, initial(hud_toggle_color)) - ghost_form = sanitize_inlist(ghost_form, GLOB.ghost_forms, initial(ghost_form)) - ghost_orbit = sanitize_inlist(ghost_orbit, GLOB.ghost_orbits, initial(ghost_orbit)) - ghost_accs = sanitize_inlist(ghost_accs, GLOB.ghost_accs_options, GHOST_ACCS_DEFAULT_OPTION) - ghost_others = sanitize_inlist(ghost_others, GLOB.ghost_others_options, GHOST_OTHERS_DEFAULT_OPTION) - menuoptions = SANITIZE_LIST(menuoptions) - be_special = SANITIZE_LIST(be_special) - pda_style = sanitize_inlist(pda_style, GLOB.pda_styles, initial(pda_style)) - pda_color = sanitize_hexcolor(pda_color, 6, 1, initial(pda_color)) - pda_skin = sanitize_inlist(pda_skin, GLOB.pda_reskins, PDA_SKIN_ALT) - screenshake = sanitize_integer(screenshake, 0, 800, initial(screenshake)) - damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake)) - autostand = sanitize_integer(autostand, 0, 1, initial(autostand)) - cit_toggles = sanitize_integer(cit_toggles, 0, 16777215, initial(cit_toggles)) - auto_ooc = sanitize_integer(auto_ooc, 0, 1, initial(auto_ooc)) - no_tetris_storage = sanitize_integer(no_tetris_storage, 0, 1, initial(no_tetris_storage)) - key_bindings = sanitize_islist(key_bindings, list()) - modless_key_bindings = sanitize_islist(modless_key_bindings, list()) + ghost_form = sanitize_inlist(ghost_form, GLOB.ghost_forms, initial(ghost_form)) + ghost_orbit = sanitize_inlist(ghost_orbit, GLOB.ghost_orbits, initial(ghost_orbit)) + ghost_accs = sanitize_inlist(ghost_accs, GLOB.ghost_accs_options, GHOST_ACCS_DEFAULT_OPTION) + ghost_others = sanitize_inlist(ghost_others, GLOB.ghost_others_options, GHOST_OTHERS_DEFAULT_OPTION) + menuoptions = SANITIZE_LIST(menuoptions) + be_special = SANITIZE_LIST(be_special) + pda_style = sanitize_inlist(pda_style, GLOB.pda_styles, initial(pda_style)) + pda_color = sanitize_hexcolor(pda_color, 6, 1, initial(pda_color)) + pda_skin = sanitize_inlist(pda_skin, GLOB.pda_reskins, PDA_SKIN_ALT) + screenshake = sanitize_integer(screenshake, 0, 800, initial(screenshake)) + damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake)) + autostand = sanitize_integer(autostand, 0, 1, initial(autostand)) + cit_toggles = sanitize_integer(cit_toggles, 0, 16777215, initial(cit_toggles)) + auto_ooc = sanitize_integer(auto_ooc, 0, 1, initial(auto_ooc)) + no_tetris_storage = sanitize_integer(no_tetris_storage, 0, 1, initial(no_tetris_storage)) + recoil_screenshake = sanitize_integer(recoil_screenshake, 0, 800, initial(recoil_screenshake)) + key_bindings = sanitize_islist(key_bindings, list()) + modless_key_bindings = sanitize_islist(modless_key_bindings, list()) favorite_outfits = SANITIZE_LIST(favorite_outfits) + screentip_color = sanitize_hexcolor(screentip_color, 6, 1, initial(screentip_color)) + screentip_pref = sanitize_inlist(screentip_pref, GLOB.screentip_pref_options, SCREENTIP_PREFERENCE_ENABLED) verify_keybindings_valid() // one of these days this will runtime and you'll be glad that i put it in a different proc so no one gets their saves wiped @@ -555,6 +615,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["ooccolor"], ooccolor) WRITE_FILE(S["lastchangelog"], lastchangelog) WRITE_FILE(S["UI_style"], UI_style) + WRITE_FILE(S["outline_enabled"], outline_enabled) + WRITE_FILE(S["outline_color"], outline_color) + WRITE_FILE(S["screentip_pref"], screentip_pref) + WRITE_FILE(S["screentip_color"], screentip_color) + WRITE_FILE(S["screentip_images"], screentip_images) WRITE_FILE(S["hotkeys"], hotkeys) WRITE_FILE(S["chat_on_map"], chat_on_map) WRITE_FILE(S["max_chat_length"], max_chat_length) @@ -566,6 +631,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["be_special"], be_special) WRITE_FILE(S["default_slot"], default_slot) WRITE_FILE(S["toggles"], toggles) + WRITE_FILE(S["deadmin"], deadmin) WRITE_FILE(S["chat_toggles"], chat_toggles) WRITE_FILE(S["ghost_form"], ghost_form) WRITE_FILE(S["ghost_orbit"], ghost_orbit) @@ -597,11 +663,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["damagescreenshake"], damagescreenshake) WRITE_FILE(S["arousable"], arousable) WRITE_FILE(S["widescreenpref"], widescreenpref) + WRITE_FILE(S["long_strip_menu"], long_strip_menu) WRITE_FILE(S["autostand"], autostand) WRITE_FILE(S["cit_toggles"], cit_toggles) WRITE_FILE(S["preferred_chaos"], preferred_chaos) WRITE_FILE(S["auto_ooc"], auto_ooc) WRITE_FILE(S["no_tetris_storage"], no_tetris_storage) + WRITE_FILE(S["recoil_screenshake"], recoil_screenshake) if(length(unlockable_loadout_data)) WRITE_FILE(S["unlockable_loadout"], safe_json_encode(unlockable_loadout_data)) @@ -624,7 +692,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car var/savefile/S = new /savefile(path) if(!S) return FALSE - features = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF", "mcolor3" = "FFFFFF", "tail_lizard" = "Smooth", "tail_human" = "None", "snout" = "Round", "horns" = "None", "horns_color" = "85615a", "ears" = "None", "wings" = "None", "wings_color" = "FFF", "frills" = "None", "deco_wings" = "None", "spines" = "None", "legs" = "Plantigrade", "insect_wings" = "Plain", "insect_fluff" = "None", "insect_markings" = "None", "arachnid_legs" = "Plain", "arachnid_spinneret" = "Plain", "arachnid_mandibles" = "Plain", "mam_body_markings" = "Plain", "mam_ears" = "None", "mam_snouts" = "None", "mam_tail" = "None", "mam_tail_animated" = "None", "xenodorsal" = "Standard", "xenohead" = "Standard", "xenotail" = "Xenomorph Tail", "taur" = "None", "genitals_use_skintone" = FALSE, "has_cock" = FALSE, "cock_shape" = DEF_COCK_SHAPE, "cock_length" = COCK_SIZE_DEF, "cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF, "cock_color" = "ffffff", "cock_taur" = FALSE, "has_balls" = FALSE, "balls_color" = "ffffff", "balls_shape" = DEF_BALLS_SHAPE, "balls_size" = BALLS_SIZE_DEF, "balls_cum_rate" = CUM_RATE, "balls_cum_mult" = CUM_RATE_MULT, "balls_efficiency" = CUM_EFFICIENCY, "has_breasts" = FALSE, "breasts_color" = "ffffff", "breasts_size" = BREASTS_SIZE_DEF, "breasts_shape" = DEF_BREASTS_SHAPE, "breasts_producing" = FALSE, "has_vag" = FALSE, "vag_shape" = DEF_VAGINA_SHAPE, "vag_color" = "ffffff", "has_womb" = FALSE, "balls_visibility" = GEN_VISIBLE_NO_UNDIES, "breasts_visibility"= GEN_VISIBLE_NO_UNDIES, "cock_visibility" = GEN_VISIBLE_NO_UNDIES, "vag_visibility" = GEN_VISIBLE_NO_UNDIES, "ipc_screen" = "Sunburst", "ipc_antenna" = "None", "flavor_text" = "", "silicon_flavor_text" = "", "ooc_notes" = "", "meat_type" = "Mammalian", "body_model" = MALE, "body_size" = RESIZE_DEFAULT_SIZE, "color_scheme" = OLD_CHARACTER_COLORING) + features = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF", "mcolor3" = "FFFFFF", "tail_lizard" = "Smooth", "tail_human" = "None", "snout" = "Round", "horns" = "None", "horns_color" = "85615a", "ears" = "None", "wings" = "None", "wings_color" = "FFF", "frills" = "None", "deco_wings" = "None", "spines" = "None", "legs" = "Plantigrade", "insect_wings" = "Plain", "insect_fluff" = "None", "insect_markings" = "None", "arachnid_legs" = "Plain", "arachnid_spinneret" = "Plain", "arachnid_mandibles" = "Plain", "mam_body_markings" = "Plain", "mam_ears" = "None", "mam_snouts" = "None", "mam_tail" = "None", "mam_tail_animated" = "None", "xenodorsal" = "Standard", "xenohead" = "Standard", "xenotail" = "Xenomorph Tail", "taur" = "None", "genitals_use_skintone" = FALSE, "has_cock" = FALSE, "cock_shape" = DEF_COCK_SHAPE, "cock_length" = COCK_SIZE_DEF, "cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF, "cock_color" = "ffffff", "cock_taur" = FALSE, "has_balls" = FALSE, "balls_color" = "ffffff", "balls_shape" = DEF_BALLS_SHAPE, "balls_size" = BALLS_SIZE_DEF, "balls_cum_rate" = CUM_RATE, "balls_cum_mult" = CUM_RATE_MULT, "balls_efficiency" = CUM_EFFICIENCY, "has_breasts" = FALSE, "breasts_color" = "ffffff", "breasts_size" = BREASTS_SIZE_DEF, "breasts_shape" = DEF_BREASTS_SHAPE, "breasts_producing" = FALSE, "has_vag" = FALSE, "vag_shape" = DEF_VAGINA_SHAPE, "vag_color" = "ffffff", "has_womb" = FALSE, "has_butt" = FALSE, "butt_color" = "ffffff", "butt_size" = BUTT_SIZE_DEF, "balls_visibility" = GEN_VISIBLE_NO_UNDIES, "breasts_visibility"= GEN_VISIBLE_NO_UNDIES, "cock_visibility" = GEN_VISIBLE_NO_UNDIES, "vag_visibility" = GEN_VISIBLE_NO_UNDIES, "butt_visibility" = GEN_VISIBLE_NO_UNDIES, "ipc_screen" = "Sunburst", "ipc_antenna" = "None", "flavor_text" = "", "silicon_flavor_text" = "", "ooc_notes" = "", "meat_type" = "Mammalian", "body_model" = MALE, "body_size" = RESIZE_DEFAULT_SIZE, "color_scheme" = OLD_CHARACTER_COLORING) S.cd = "/" if(!slot) @@ -643,7 +711,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car //Species var/species_id - S["species"] >> species_id + S["species"] >> species_id if(species_id) if(species_id == "avian" || species_id == "aquatic") species_id = "mammal" @@ -658,61 +726,63 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car scars_index = rand(1,5) // WHY //Character - S["real_name"] >> real_name - S["nameless"] >> nameless - S["custom_species"] >> custom_species - S["name_is_always_random"] >> be_random_name - S["body_is_always_random"] >> be_random_body - S["gender"] >> gender - S["body_model"] >> features["body_model"] - S["body_size"] >> features["body_size"] - S["age"] >> age - S["hair_color"] >> hair_color - S["facial_hair_color"] >> facial_hair_color - S["eye_type"] >> eye_type - S["left_eye_color"] >> left_eye_color - S["right_eye_color"] >> right_eye_color - S["use_custom_skin_tone"] >> use_custom_skin_tone - S["skin_tone"] >> skin_tone - S["hair_style_name"] >> hair_style - S["facial_style_name"] >> facial_hair_style - S["underwear"] >> underwear - S["undie_color"] >> undie_color - S["undershirt"] >> undershirt - S["shirt_color"] >> shirt_color - S["socks"] >> socks - S["socks_color"] >> socks_color - S["backbag"] >> backbag - S["jumpsuit_style"] >> jumpsuit_style - S["uplink_loc"] >> uplink_spawn_loc - S["custom_speech_verb"] >> custom_speech_verb - S["custom_tongue"] >> custom_tongue - S["additional_language"] >> additional_language - S["feature_mcolor"] >> features["mcolor"] - S["feature_lizard_tail"] >> features["tail_lizard"] - S["feature_lizard_snout"] >> features["snout"] - S["feature_lizard_horns"] >> features["horns"] - S["feature_lizard_frills"] >> features["frills"] - S["feature_lizard_spines"] >> features["spines"] - S["feature_lizard_legs"] >> features["legs"] - S["feature_human_tail"] >> features["tail_human"] - S["feature_human_ears"] >> features["ears"] - S["feature_deco_wings"] >> features["deco_wings"] - S["feature_insect_wings"] >> features["insect_wings"] - S["feature_insect_fluff"] >> features["insect_fluff"] - S["feature_insect_markings"] >> features["insect_markings"] - S["feature_arachnid_legs"] >> features["arachnid_legs"] - S["feature_arachnid_spinneret"] >> features["arachnid_spinneret"] - S["feature_arachnid_mandibles"] >> features["arachnid_mandibles"] - S["feature_horns_color"] >> features["horns_color"] - S["feature_wings_color"] >> features["wings_color"] - S["feature_color_scheme"] >> features["color_scheme"] + S["real_name"] >> real_name + S["nameless"] >> nameless + S["custom_species"] >> custom_species + S["name_is_always_random"] >> be_random_name + S["body_is_always_random"] >> be_random_body + S["gender"] >> gender + S["body_model"] >> features["body_model"] + S["body_size"] >> features["body_size"] + S["age"] >> age + S["hair_color"] >> hair_color + S["facial_hair_color"] >> facial_hair_color + S["eye_type"] >> eye_type + S["left_eye_color"] >> left_eye_color + S["right_eye_color"] >> right_eye_color + S["use_custom_skin_tone"] >> use_custom_skin_tone + S["skin_tone"] >> skin_tone + S["hair_style_name"] >> hair_style + S["facial_style_name"] >> facial_hair_style + S["grad_style"] >> grad_style + S["grad_color"] >> grad_color + S["underwear"] >> underwear + S["undie_color"] >> undie_color + S["undershirt"] >> undershirt + S["shirt_color"] >> shirt_color + S["socks"] >> socks + S["socks_color"] >> socks_color + S["backbag"] >> backbag + S["jumpsuit_style"] >> jumpsuit_style + S["uplink_loc"] >> uplink_spawn_loc + S["custom_speech_verb"] >> custom_speech_verb + S["custom_tongue"] >> custom_tongue + S["additional_language"] >> additional_language + S["feature_mcolor"] >> features["mcolor"] + S["feature_lizard_tail"] >> features["tail_lizard"] + S["feature_lizard_snout"] >> features["snout"] + S["feature_lizard_horns"] >> features["horns"] + S["feature_lizard_frills"] >> features["frills"] + S["feature_lizard_spines"] >> features["spines"] + S["feature_lizard_legs"] >> features["legs"] + S["feature_human_tail"] >> features["tail_human"] + S["feature_human_ears"] >> features["ears"] + S["feature_deco_wings"] >> features["deco_wings"] + S["feature_insect_wings"] >> features["insect_wings"] + S["feature_insect_fluff"] >> features["insect_fluff"] + S["feature_insect_markings"] >> features["insect_markings"] + S["feature_arachnid_legs"] >> features["arachnid_legs"] + S["feature_arachnid_spinneret"] >> features["arachnid_spinneret"] + S["feature_arachnid_mandibles"] >> features["arachnid_mandibles"] + S["feature_horns_color"] >> features["horns_color"] + S["feature_wings_color"] >> features["wings_color"] + S["feature_color_scheme"] >> features["color_scheme"] S["persistent_scars"] >> persistent_scars - S["scars1"] >> scars_list["1"] - S["scars2"] >> scars_list["2"] - S["scars3"] >> scars_list["3"] - S["scars4"] >> scars_list["4"] - S["scars5"] >> scars_list["5"] + S["scars1"] >> scars_list["1"] + S["scars2"] >> scars_list["2"] + S["scars3"] >> scars_list["3"] + S["scars4"] >> scars_list["4"] + S["scars5"] >> scars_list["5"] var/limbmodstr S["modified_limbs"] >> limbmodstr if(length(limbmodstr)) @@ -734,94 +804,94 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car else tcg_decks = list() - S["chosen_limb_id"] >> chosen_limb_id - S["hide_ckey"] >> hide_ckey //saved per-character + S["chosen_limb_id"] >> chosen_limb_id + S["hide_ckey"] >> hide_ckey //saved per-character //Custom names for(var/custom_name_id in GLOB.preferences_custom_names) var/savefile_slot_name = custom_name_id + "_name" //TODO remove this S[savefile_slot_name] >> custom_names[custom_name_id] - S["preferred_ai_core_display"] >> preferred_ai_core_display - S["prefered_security_department"] >> prefered_security_department + S["preferred_ai_core_display"] >> preferred_ai_core_display + S["prefered_security_department"] >> prefered_security_department //Jobs - S["joblessrole"] >> joblessrole + S["joblessrole"] >> joblessrole //Load prefs - S["job_preferences"] >> job_preferences + S["job_preferences"] >> job_preferences //Quirks - S["all_quirks"] >> all_quirks + S["all_quirks"] >> all_quirks //Records - S["security_records"] >> security_records - S["medical_records"] >> medical_records + S["security_records"] >> security_records + S["medical_records"] >> medical_records //Citadel code - S["feature_genitals_use_skintone"] >> features["genitals_use_skintone"] - S["feature_mcolor2"] >> features["mcolor2"] - S["feature_mcolor3"] >> features["mcolor3"] + S["feature_genitals_use_skintone"] >> features["genitals_use_skintone"] + S["feature_mcolor2"] >> features["mcolor2"] + S["feature_mcolor3"] >> features["mcolor3"] // note safe json decode will runtime the first time it migrates but this is fine and it solves itself don't worry about it if you see it error features["mam_body_markings"] = safe_json_decode(S["feature_mam_body_markings"]) - S["feature_mam_tail"] >> features["mam_tail"] - S["feature_mam_ears"] >> features["mam_ears"] - S["feature_mam_tail_animated"] >> features["mam_tail_animated"] - S["feature_taur"] >> features["taur"] - S["feature_mam_snouts"] >> features["mam_snouts"] - S["feature_meat"] >> features["meat_type"] + S["feature_mam_tail"] >> features["mam_tail"] + S["feature_mam_ears"] >> features["mam_ears"] + S["feature_mam_tail_animated"] >> features["mam_tail_animated"] + S["feature_taur"] >> features["taur"] + S["feature_mam_snouts"] >> features["mam_snouts"] + S["feature_meat"] >> features["meat_type"] //Xeno features - S["feature_xeno_tail"] >> features["xenotail"] - S["feature_xeno_dors"] >> features["xenodorsal"] - S["feature_xeno_head"] >> features["xenohead"] + S["feature_xeno_tail"] >> features["xenotail"] + S["feature_xeno_dors"] >> features["xenodorsal"] + S["feature_xeno_head"] >> features["xenohead"] //cock features - S["feature_has_cock"] >> features["has_cock"] - S["feature_cock_shape"] >> features["cock_shape"] - S["feature_cock_color"] >> features["cock_color"] - S["feature_cock_length"] >> features["cock_length"] - S["feature_cock_diameter"] >> features["cock_diameter"] - S["feature_cock_taur"] >> features["cock_taur"] - S["feature_cock_visibility"] >> features["cock_visibility"] + S["feature_has_cock"] >> features["has_cock"] + S["feature_cock_shape"] >> features["cock_shape"] + S["feature_cock_color"] >> features["cock_color"] + S["feature_cock_length"] >> features["cock_length"] + S["feature_cock_diameter"] >> features["cock_diameter"] + S["feature_cock_taur"] >> features["cock_taur"] + S["feature_cock_visibility"] >> features["cock_visibility"] //balls features - S["feature_has_balls"] >> features["has_balls"] - S["feature_balls_color"] >> features["balls_color"] - S["feature_balls_size"] >> features["balls_size"] - S["feature_balls_visibility"] >> features["balls_visibility"] + S["feature_has_balls"] >> features["has_balls"] + S["feature_balls_color"] >> features["balls_color"] + S["feature_balls_shape"] >> features["balls_shape"] + S["feature_balls_size"] >> features["balls_size"] + S["feature_balls_visibility"] >> features["balls_visibility"] //breasts features - S["feature_has_breasts"] >> features["has_breasts"] - S["feature_breasts_size"] >> features["breasts_size"] - S["feature_breasts_shape"] >> features["breasts_shape"] - S["feature_breasts_color"] >> features["breasts_color"] - S["feature_breasts_producing"] >> features["breasts_producing"] - S["feature_breasts_visibility"] >> features["breasts_visibility"] + S["feature_has_breasts"] >> features["has_breasts"] + S["feature_breasts_size"] >> features["breasts_size"] + S["feature_breasts_shape"] >> features["breasts_shape"] + S["feature_breasts_color"] >> features["breasts_color"] + S["feature_breasts_producing"] >> features["breasts_producing"] + S["feature_breasts_visibility"] >> features["breasts_visibility"] //vagina features - S["feature_has_vag"] >> features["has_vag"] - S["feature_vag_shape"] >> features["vag_shape"] - S["feature_vag_color"] >> features["vag_color"] - S["feature_vag_visibility"] >> features["vag_visibility"] + S["feature_has_vag"] >> features["has_vag"] + S["feature_vag_shape"] >> features["vag_shape"] + S["feature_vag_color"] >> features["vag_color"] + S["feature_vag_visibility"] >> features["vag_visibility"] //womb features - S["feature_has_womb"] >> features["has_womb"] + S["feature_has_womb"] >> features["has_womb"] + //butt features + S["feature_has_butt"] >> features["has_butt"] + S["feature_butt_color"] >> features["butt_color"] + S["feature_butt_size"] >> features["butt_size"] + S["feature_butt_visibility"] >> features["butt_visibility"] - //flavor text - //Let's make our players NOT cry desperately as we wipe their savefiles of their special snowflake texts: - if((S["flavor_text"] != "") && (S["flavor_text"] != null) && S["flavor_text"]) //If old text isn't null and isn't "" but still exists. - S["flavor_text"] >> features["flavor_text"] //Load old flavortext as current dna-based flavortext + // Flavor texts, Made into a standard. + S["feature_flavor_text"] >> features["flavor_text"] + S["feature_silicon_flavor_text"] >> features["silicon_flavor_text"] + S["feature_ooc_notes"] >> features["ooc_notes"] - WRITE_FILE(S["feature_flavor_text"], features["flavor_text"]) //Save it in our new type of flavor-text - WRITE_FILE(S["flavor_text"] , "") //Remove old flavortext, completing the cut-and-paste into the new format. + // Barks + S["bark_id"] >> bark_id + S["bark_speed"] >> bark_speed + S["bark_pitch"] >> bark_pitch + S["bark_variance"] >> bark_variance - else //We have no old flavortext, default to new - S["feature_flavor_text"] >> features["flavor_text"] - - - S["silicon_feature_flavor_text"] >> features["silicon_flavor_text"] - - S["feature_ooc_notes"] >> features["ooc_notes"] - S["silicon_flavor_text"] >> features["silicon_flavor_text"] - - S["vore_flags"] >> vore_flags - S["vore_taste"] >> vore_taste - S["vore_smell"] >> vore_smell + S["vore_flags"] >> vore_flags + S["vore_taste"] >> vore_taste + S["vore_smell"] >> vore_smell var/char_vr_path = "[vr_path]/character_[default_slot]_v2.json" if(fexists(char_vr_path)) var/list/json_from_file = json_decode(file2text(char_vr_path)) @@ -841,67 +911,69 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car //Sanitize - real_name = reject_bad_name(real_name) - gender = sanitize_gender(gender, TRUE, TRUE) + real_name = reject_bad_name(real_name) + gender = sanitize_gender(gender, TRUE, TRUE) features["body_model"] = sanitize_gender(features["body_model"], FALSE, FALSE, gender == FEMALE ? FEMALE : MALE) if(!real_name) - real_name = random_unique_name(gender) - custom_species = reject_bad_name(custom_species) + real_name = random_unique_name(gender) + custom_species = reject_bad_name(custom_species) for(var/custom_name_id in GLOB.preferences_custom_names) var/namedata = GLOB.preferences_custom_names[custom_name_id] custom_names[custom_name_id] = reject_bad_name(custom_names[custom_name_id],namedata["allow_numbers"]) if(!custom_names[custom_name_id]) custom_names[custom_name_id] = get_default_name(custom_name_id) - nameless = sanitize_integer(nameless, 0, 1, initial(nameless)) - be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name)) - be_random_body = sanitize_integer(be_random_body, 0, 1, initial(be_random_body)) + nameless = sanitize_integer(nameless, 0, 1, initial(nameless)) + be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name)) + be_random_body = sanitize_integer(be_random_body, 0, 1, initial(be_random_body)) - hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_list) - facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_list) - underwear = sanitize_inlist(underwear, GLOB.underwear_list) - undershirt = sanitize_inlist(undershirt, GLOB.undershirt_list) - undie_color = sanitize_hexcolor(undie_color, 6, FALSE, initial(undie_color)) - shirt_color = sanitize_hexcolor(shirt_color, 6, FALSE, initial(shirt_color)) - socks = sanitize_inlist(socks, GLOB.socks_list) - socks_color = sanitize_hexcolor(socks_color, 6, FALSE, initial(socks_color)) - age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age)) - hair_color = sanitize_hexcolor(hair_color, 6, FALSE) - facial_hair_color = sanitize_hexcolor(facial_hair_color, 6, FALSE) - eye_type = sanitize_inlist(eye_type, GLOB.eye_types, DEFAULT_EYES_TYPE) - left_eye_color = sanitize_hexcolor(left_eye_color, 6, FALSE) - right_eye_color = sanitize_hexcolor(right_eye_color, 6, FALSE) + hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_list) + facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_list) + underwear = sanitize_inlist(underwear, GLOB.underwear_list) + undershirt = sanitize_inlist(undershirt, GLOB.undershirt_list) + undie_color = sanitize_hexcolor(undie_color, 6, FALSE, initial(undie_color)) + shirt_color = sanitize_hexcolor(shirt_color, 6, FALSE, initial(shirt_color)) + socks = sanitize_inlist(socks, GLOB.socks_list) + socks_color = sanitize_hexcolor(socks_color, 6, FALSE, initial(socks_color)) + age = sanitize_integer(age, AGE_MIN, AGE_MAX_INPUT, initial(age)) + hair_color = sanitize_hexcolor(hair_color, 6, FALSE) + facial_hair_color = sanitize_hexcolor(facial_hair_color, 6, FALSE) + grad_style = sanitize_inlist(grad_style, GLOB.hair_gradients_list, "None") + grad_color = sanitize_hexcolor(grad_color, 6, FALSE) + eye_type = sanitize_inlist(eye_type, GLOB.eye_types, DEFAULT_EYES_TYPE) + left_eye_color = sanitize_hexcolor(left_eye_color, 6, FALSE) + right_eye_color = sanitize_hexcolor(right_eye_color, 6, FALSE) var/static/allow_custom_skintones if(isnull(allow_custom_skintones)) allow_custom_skintones = CONFIG_GET(flag/allow_custom_skintones) - use_custom_skin_tone = allow_custom_skintones ? sanitize_integer(use_custom_skin_tone, FALSE, TRUE, initial(use_custom_skin_tone)) : FALSE + use_custom_skin_tone = allow_custom_skintones ? sanitize_integer(use_custom_skin_tone, FALSE, TRUE, initial(use_custom_skin_tone)) : FALSE if(use_custom_skin_tone) - skin_tone = sanitize_hexcolor(skin_tone, 6, TRUE, "#FFFFFF") + skin_tone = sanitize_hexcolor(skin_tone, 6, TRUE, "#FFFFFF") else - skin_tone = sanitize_inlist(skin_tone, GLOB.skin_tones - GLOB.nonstandard_skin_tones, initial(skin_tone)) + skin_tone = sanitize_inlist(skin_tone, GLOB.skin_tones - GLOB.nonstandard_skin_tones, initial(skin_tone)) - features["horns_color"] = sanitize_hexcolor(features["horns_color"], 6, FALSE, "85615a") - features["wings_color"] = sanitize_hexcolor(features["wings_color"], 6, FALSE, "FFFFFF") - backbag = sanitize_inlist(backbag, GLOB.backbaglist, initial(backbag)) - jumpsuit_style = sanitize_inlist(jumpsuit_style, GLOB.jumpsuitlist, initial(jumpsuit_style)) - uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, GLOB.uplink_spawn_loc_list, initial(uplink_spawn_loc)) - features["mcolor"] = sanitize_hexcolor(features["mcolor"], 6, FALSE) - features["tail_lizard"] = sanitize_inlist(features["tail_lizard"], GLOB.tails_list_lizard) - features["tail_human"] = sanitize_inlist(features["tail_human"], GLOB.tails_list_human) - features["snout"] = sanitize_inlist(features["snout"], GLOB.snouts_list) - features["horns"] = sanitize_inlist(features["horns"], GLOB.horns_list) - features["ears"] = sanitize_inlist(features["ears"], GLOB.ears_list) - features["frills"] = sanitize_inlist(features["frills"], GLOB.frills_list) - features["spines"] = sanitize_inlist(features["spines"], GLOB.spines_list) - features["legs"] = sanitize_inlist(features["legs"], GLOB.legs_list, "Plantigrade") - features["deco_wings"] = sanitize_inlist(features["deco_wings"], GLOB.deco_wings_list, "None") - features["insect_fluff"] = sanitize_inlist(features["insect_fluff"], GLOB.insect_fluffs_list) - features["insect_markings"] = sanitize_inlist(features["insect_markings"], GLOB.insect_markings_list, "None") - features["insect_wings"] = sanitize_inlist(features["insect_wings"], GLOB.insect_wings_list) - features["arachnid_legs"] = sanitize_inlist(features["arachnid_legs"], GLOB.arachnid_legs_list, "Plain") - features["arachnid_spinneret"] = sanitize_inlist(features["arachnid_spinneret"], GLOB.arachnid_spinneret_list, "Plain") - features["arachnid_mandibles"] = sanitize_inlist(features["arachnid_mandibles"], GLOB.arachnid_mandibles_list, "Plain") + features["horns_color"] = sanitize_hexcolor(features["horns_color"], 6, FALSE, "85615a") + features["wings_color"] = sanitize_hexcolor(features["wings_color"], 6, FALSE, "FFFFFF") + backbag = sanitize_inlist(backbag, GLOB.backbaglist, initial(backbag)) + jumpsuit_style = sanitize_inlist(jumpsuit_style, GLOB.jumpsuitlist, initial(jumpsuit_style)) + uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, GLOB.uplink_spawn_loc_list, initial(uplink_spawn_loc)) + features["mcolor"] = sanitize_hexcolor(features["mcolor"], 6, FALSE) + features["tail_lizard"] = sanitize_inlist(features["tail_lizard"], GLOB.tails_list_lizard) + features["tail_human"] = sanitize_inlist(features["tail_human"], GLOB.tails_list_human) + features["snout"] = sanitize_inlist(features["snout"], GLOB.snouts_list) + features["horns"] = sanitize_inlist(features["horns"], GLOB.horns_list) + features["ears"] = sanitize_inlist(features["ears"], GLOB.ears_list) + features["frills"] = sanitize_inlist(features["frills"], GLOB.frills_list) + features["spines"] = sanitize_inlist(features["spines"], GLOB.spines_list) + features["legs"] = sanitize_inlist(features["legs"], GLOB.legs_list, "Plantigrade") + features["deco_wings"] = sanitize_inlist(features["deco_wings"], GLOB.deco_wings_list, "None") + features["insect_fluff"] = sanitize_inlist(features["insect_fluff"], GLOB.insect_fluffs_list) + features["insect_markings"] = sanitize_inlist(features["insect_markings"], GLOB.insect_markings_list, "None") + features["insect_wings"] = sanitize_inlist(features["insect_wings"], GLOB.insect_wings_list) + features["arachnid_legs"] = sanitize_inlist(features["arachnid_legs"], GLOB.arachnid_legs_list, "Plain") + features["arachnid_spinneret"] = sanitize_inlist(features["arachnid_spinneret"], GLOB.arachnid_spinneret_list, "Plain") + features["arachnid_mandibles"] = sanitize_inlist(features["arachnid_mandibles"], GLOB.arachnid_mandibles_list, "Plain") var/static/size_min if(!size_min) @@ -909,7 +981,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car var/static/size_max if(!size_max) size_max = CONFIG_GET(number/body_size_max) - features["body_size"] = sanitize_num_clamp(features["body_size"], size_min, size_max, RESIZE_DEFAULT_SIZE, 0.01) + features["body_size"] = sanitize_num_clamp(features["body_size"], size_min, size_max, RESIZE_DEFAULT_SIZE, 0.01) var/static/list/B_sizes if(!B_sizes) @@ -921,36 +993,42 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car var/static/max_D if(!max_D) max_D = CONFIG_GET(number/penis_max_inches_prefs) - var/static/safe_visibilities - if(!safe_visibilities) - var/list/L = CONFIG_GET(keyed_list/safe_visibility_toggles) - safe_visibilities = L.Copy() + var/static/min_B + if(!min_B) + min_B = CONFIG_GET(number/butt_min_size_prefs) + var/static/max_B + if(!max_B) + max_B = CONFIG_GET(number/butt_max_size_prefs) - features["breasts_size"] = sanitize_inlist(features["breasts_size"], B_sizes, BREASTS_SIZE_DEF) - features["cock_length"] = sanitize_integer(features["cock_length"], min_D, max_D, COCK_SIZE_DEF) - features["breasts_shape"] = sanitize_inlist(features["breasts_shape"], GLOB.breasts_shapes_list, DEF_BREASTS_SHAPE) - features["cock_shape"] = sanitize_inlist(features["cock_shape"], GLOB.cock_shapes_list, DEF_COCK_SHAPE) - features["balls_shape"] = sanitize_inlist(features["balls_shape"], GLOB.balls_shapes_list, DEF_BALLS_SHAPE) - features["vag_shape"] = sanitize_inlist(features["vag_shape"], GLOB.vagina_shapes_list, DEF_VAGINA_SHAPE) - features["breasts_color"] = sanitize_hexcolor(features["breasts_color"], 6, FALSE, "FFFFFF") - features["cock_color"] = sanitize_hexcolor(features["cock_color"], 6, FALSE, "FFFFFF") - features["balls_color"] = sanitize_hexcolor(features["balls_color"], 6, FALSE, "FFFFFF") - features["vag_color"] = sanitize_hexcolor(features["vag_color"], 6, FALSE, "FFFFFF") - features["breasts_visibility"] = sanitize_inlist(features["breasts_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) - features["cock_visibility"] = sanitize_inlist(features["cock_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) - features["balls_visibility"] = sanitize_inlist(features["balls_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) - features["vag_visibility"] = sanitize_inlist(features["vag_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) + var/safe_visibilities = CONFIG_GET(str_list/safe_visibility_toggles) - custom_speech_verb = sanitize_inlist(custom_speech_verb, GLOB.speech_verbs, "default") - custom_tongue = sanitize_inlist(custom_tongue, GLOB.roundstart_tongues, "default") - additional_language = sanitize_inlist(additional_language, GLOB.roundstart_languages, "None") + features["breasts_size"] = sanitize_inlist(features["breasts_size"], B_sizes, BREASTS_SIZE_DEF) + features["cock_length"] = sanitize_integer(features["cock_length"], min_D, max_D, COCK_SIZE_DEF) + features["butt_size"] = sanitize_integer(features["butt_size"], min_B, max_B, BUTT_SIZE_DEF) + features["breasts_shape"] = sanitize_inlist(features["breasts_shape"], GLOB.breasts_shapes_list, DEF_BREASTS_SHAPE) + features["cock_shape"] = sanitize_inlist(features["cock_shape"], GLOB.cock_shapes_list, DEF_COCK_SHAPE) + features["balls_shape"] = sanitize_inlist(features["balls_shape"], GLOB.balls_shapes_list, DEF_BALLS_SHAPE) + features["vag_shape"] = sanitize_inlist(features["vag_shape"], GLOB.vagina_shapes_list, DEF_VAGINA_SHAPE) + features["breasts_color"] = sanitize_hexcolor(features["breasts_color"], 6, FALSE, "FFFFFF") + features["cock_color"] = sanitize_hexcolor(features["cock_color"], 6, FALSE, "FFFFFF") + features["balls_color"] = sanitize_hexcolor(features["balls_color"], 6, FALSE, "FFFFFF") + features["vag_color"] = sanitize_hexcolor(features["vag_color"], 6, FALSE, "FFFFFF") + features["breasts_visibility"] = sanitize_inlist(features["breasts_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) + features["cock_visibility"] = sanitize_inlist(features["cock_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) + features["balls_visibility"] = sanitize_inlist(features["balls_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) + features["vag_visibility"] = sanitize_inlist(features["vag_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) + features["butt_visibility"] = sanitize_inlist(features["butt_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES) - security_records = copytext(security_records, 1, MAX_FLAVOR_LEN) - medical_records = copytext(medical_records, 1, MAX_FLAVOR_LEN) + custom_speech_verb = sanitize_inlist(custom_speech_verb, GLOB.speech_verbs, "default") + custom_tongue = sanitize_inlist(custom_tongue, GLOB.roundstart_tongues, "default") + additional_language = sanitize_inlist(additional_language, GLOB.roundstart_languages, "None") - features["flavor_text"] = copytext(features["flavor_text"], 1, MAX_FLAVOR_LEN) - features["silicon_flavor_text"] = copytext(features["silicon_flavor_text"], 1, MAX_FLAVOR_LEN) - features["ooc_notes"] = copytext(features["ooc_notes"], 1, MAX_FLAVOR_LEN) + security_records = copytext(security_records, 1, MAX_FLAVOR_LEN) + medical_records = copytext(medical_records, 1, MAX_FLAVOR_LEN) + + features["flavor_text"] = copytext(features["flavor_text"], 1, MAX_FLAVOR_LEN) + features["silicon_flavor_text"] = copytext(features["silicon_flavor_text"], 1, MAX_FLAVOR_LEN) + features["ooc_notes"] = copytext(features["ooc_notes"], 1, MAX_FLAVOR_LEN) //load every advanced coloring mode thing in one go //THIS MUST BE DONE AFTER ALL FEATURE SAVES OR IT WILL NOT WORK @@ -972,11 +1050,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car message_admins("Sprite Accessory Failure (loading data): Accessory [accessory.type] is a matrixed item without any matrixed sections set!") continue if(S["feature_[primary_string]"]) - S["feature_[primary_string]"] >> features[primary_string] + S["feature_[primary_string]"] >> features[primary_string] if(S["feature_[secondary_string]"]) - S["feature_[secondary_string]"] >> features[secondary_string] + S["feature_[secondary_string]"] >> features[secondary_string] if(S["feature_[tertiary_string]"]) - S["feature_[tertiary_string]"] >> features[tertiary_string] + S["feature_[tertiary_string]"] >> features[tertiary_string] persistent_scars = sanitize_integer(persistent_scars) scars_list["1"] = sanitize_text(scars_list["1"]) @@ -985,7 +1063,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car scars_list["4"] = sanitize_text(scars_list["4"]) scars_list["5"] = sanitize_text(scars_list["5"]) - joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole)) + bark_id = sanitize_inlist(bark_id, GLOB.bark_list, pick(GLOB.bark_random_list)) + var/datum/bark/bark_path = GLOB.bark_list[bark_id] + bark_speed = sanitize_num_clamp(bark_speed, initial(bark_path.minspeed), initial(bark_path.maxspeed), initial(bark_speed)) + bark_pitch = sanitize_num_clamp(bark_pitch, initial(bark_path.minpitch), initial(bark_path.maxpitch), BARK_PITCH_RAND(gender)) + bark_variance = sanitize_num_clamp(bark_variance, initial(bark_path.minvariance), initial(bark_path.maxvariance), BARK_VARIANCE_RAND) + + joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole)) //Validate job prefs for(var/j in job_preferences) if(job_preferences["[j]"] != JP_LOW && job_preferences["[j]"] != JP_MEDIUM && job_preferences["[j]"] != JP_HIGH) @@ -993,10 +1077,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car all_quirks = SANITIZE_LIST(all_quirks) - vore_flags = sanitize_integer(vore_flags, 0, MAX_VORE_FLAG, 0) - vore_taste = copytext(vore_taste, 1, MAX_TASTE_LEN) - vore_smell = copytext(vore_smell, 1, MAX_TASTE_LEN) - belly_prefs = SANITIZE_LIST(belly_prefs) + vore_flags = sanitize_integer(vore_flags, 0, MAX_VORE_FLAG, 0) + vore_taste = copytext(vore_taste, 1, MAX_TASTE_LEN) + vore_smell = copytext(vore_smell, 1, MAX_TASTE_LEN) + belly_prefs = SANITIZE_LIST(belly_prefs) cit_character_pref_load(S) @@ -1037,6 +1121,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["skin_tone"] , skin_tone) WRITE_FILE(S["hair_style_name"] , hair_style) WRITE_FILE(S["facial_style_name"] , facial_hair_style) + WRITE_FILE(S["grad_style"] , grad_style) + WRITE_FILE(S["grad_color"] , grad_color) WRITE_FILE(S["underwear"] , underwear) WRITE_FILE(S["undie_color"] , undie_color) WRITE_FILE(S["undershirt"] , undershirt) @@ -1050,6 +1136,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["custom_speech_verb"] , custom_speech_verb) WRITE_FILE(S["custom_tongue"] , custom_tongue) WRITE_FILE(S["additional_language"] , additional_language) + WRITE_FILE(S["bark_id"] , bark_id) + WRITE_FILE(S["bark_speed"] , bark_speed) + WRITE_FILE(S["bark_pitch"] , bark_pitch) + WRITE_FILE(S["bark_variance"] , bark_variance) // records WRITE_FILE(S["security_records"] , security_records) @@ -1084,6 +1174,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["feature_has_balls"], features["has_balls"]) WRITE_FILE(S["feature_balls_color"], features["balls_color"]) + WRITE_FILE(S["feature_balls_shape"], features["balls_shape"]) WRITE_FILE(S["feature_balls_size"], features["balls_size"]) WRITE_FILE(S["feature_balls_visibility"], features["balls_visibility"]) @@ -1101,6 +1192,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["feature_has_womb"], features["has_womb"]) + WRITE_FILE(S["feature_has_butt"], features["has_butt"]) + WRITE_FILE(S["feature_butt_color"], features["butt_color"]) + WRITE_FILE(S["feature_butt_size"], features["butt_size"]) + WRITE_FILE(S["feature_butt_visibility"], features["butt_visibility"]) + WRITE_FILE(S["feature_ooc_notes"], features["ooc_notes"]) WRITE_FILE(S["feature_color_scheme"], features["color_scheme"]) diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index a019ade471..c4d0aa0e80 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -227,6 +227,17 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggleprayersounds)() return C.prefs.toggles & SOUND_PRAYERS +TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggle_bark)() + set name = "Hear/Silence Vocal Barks" + set category = "Preferences" + set desc = "Hear Vocal Barks" + usr.client.prefs.toggles ^= SOUND_BARK + usr.client.prefs.save_preferences() + to_chat(usr, "You will now [(usr.client.prefs.toggles & SOUND_BARK) ? "hear" : "no longer hear"] vocal barks when other people talk.") + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Vocal Barks", "[usr.client.prefs.toggles & SOUND_BARK ? "Enabled" : "Disabled"]")) +/datum/verbs/menu/Settings/Sound/toggle_bark/Get_checked(client/C) + return C.prefs.toggles & SOUND_BARK + /datum/verbs/menu/Settings/Sound/verb/stop_client_sounds() set name = "Stop Sounds" set category = "Preferences" diff --git a/code/modules/client/verbs/etips.dm b/code/modules/client/verbs/etips.dm index 27434cddc4..7452a98317 100644 --- a/code/modules/client/verbs/etips.dm +++ b/code/modules/client/verbs/etips.dm @@ -15,6 +15,15 @@ var/indelay = stripped_input(usr, "Enter the tooltip delay in milliseconds (default: 500)", "Enter tooltip delay", "", 10) indelay = text2num(indelay) if(usr)//is this what you mean? - prefs.tip_delay = indelay + prefs.tip_delay = max(indelay, 0.01) prefs.save_preferences() to_chat(usr, "Tooltip delay set to [indelay] milliseconds.") + +/client/verb/toggle_hover_outline() + set name = "Toggle hover outline" + set desc = "Toggles hover-over item outline" + set category = "Preferences" + + prefs.outline_enabled = !prefs.outline_enabled + prefs.save_preferences() + to_chat(usr, "Item outline [prefs.outline_enabled ? "en" : "dis"]abled.") diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index 07087e70a3..93f91ad3a0 100644 --- a/code/modules/client/verbs/ooc.dm +++ b/code/modules/client/verbs/ooc.dm @@ -108,16 +108,38 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8") else GLOB.dooc_allowed = !GLOB.dooc_allowed -/client/proc/set_ooc(newColor as color) +/client/proc/set_ooc() set name = "Set Player OOC Color" set desc = "Modifies player OOC Color" set category = "Admin.Fun" - GLOB.OOC_COLOR = sanitize_ooccolor(newColor) + if(IsAdminAdvancedProcCall()) + return + var/newColor = input(src, "Please select the new player OOC color.", "OOC color") as color|null + if(isnull(newColor)) + return + if(!check_rights(R_FUN)) + message_admins("[usr.key] has attempted to use the Set Player OOC Color verb!") + log_admin("[key_name(usr)] tried to set player ooc color without authorization.") + return + var/new_color = sanitize_ooccolor(newColor) + message_admins("[key_name_admin(usr)] has set the players' ooc color to [new_color].") + log_admin("[key_name_admin(usr)] has set the player ooc color to [new_color].") + GLOB.OOC_COLOR = new_color /client/proc/reset_ooc() set name = "Reset Player OOC Color" set desc = "Returns player OOC Color to default" set category = "Admin.Fun" + if(IsAdminAdvancedProcCall()) + return + if(alert(usr, "Are you sure you want to reset the OOC color of all players?", "Reset Player OOC Color", "Yes", "No") != "Yes") + return + if(!check_rights(R_FUN)) + message_admins("[usr.key] has attempted to use the Reset Player OOC Color verb!") + log_admin("[key_name(usr)] tried to reset player ooc color without authorization.") + return + message_admins("[key_name_admin(usr)] has reset the players' ooc color.") + log_admin("[key_name_admin(usr)] has reset player ooc color.") GLOB.OOC_COLOR = null /client/verb/colorooc() //this is admin and people who bought byond. @@ -129,11 +151,12 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8") return var/new_ooccolor = input(src, "Please select your OOC color.", "OOC color", prefs.ooccolor) as color|null - if(new_ooccolor) - prefs.ooccolor = sanitize_ooccolor(new_ooccolor) - prefs.save_preferences() + if(isnull(new_ooccolor)) + return + new_ooccolor = sanitize_ooccolor(new_ooccolor) + prefs.ooccolor = new_ooccolor + prefs.save_preferences() SSblackbox.record_feedback("tally", "admin_verb", 1, "Set OOC Color") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return /client/verb/resetcolorooc() set name = "Reset Your OOC Color" diff --git a/code/modules/client/verbs/suicide.dm b/code/modules/client/verbs/suicide.dm index cae9a54484..453c22e7f2 100644 --- a/code/modules/client/verbs/suicide.dm +++ b/code/modules/client/verbs/suicide.dm @@ -207,6 +207,10 @@ message_admins("[key_name(src)] (job: [src.job ? "[src.job]" : "None"]) [is_special_character(src) ? "(ANTAG!) " : ""][ghosting ? "ghosted" : "committed suicide"] at [AREACOORD(src)].") /mob/living/proc/canSuicide() + var/area/A = get_area(src) + if(A.area_flags & BLOCK_SUICIDE) + to_chat(src, span_warning("You can't commit suicide here! You can ghost if you'd like.")) + return FALSE if(!CONFIG_GET(flag/suicide_allowed)) to_chat(src, "Suicide is not enabled in the config.") return FALSE @@ -214,11 +218,11 @@ if(CONSCIOUS) return TRUE if(SOFT_CRIT) - to_chat(src, "You can't commit suicide while in a critical condition!") + to_chat(src, span_warning("You can't commit suicide while in a critical condition!")) if(UNCONSCIOUS) - to_chat(src, "You need to be conscious to commit suicide!") + to_chat(src, span_warning("You need to be conscious to commit suicide!")) if(DEAD) - to_chat(src, "You're already dead!") + to_chat(src, span_warning("You're already dead!")) return /mob/living/carbon/canSuicide() diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index 008772663d..05ef6f18e0 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -63,8 +63,8 @@ // it's TRAIT_NODROP D.dropItemToGround(target, TRUE) qdel(old_headgear) - // where is `SLOT_HEAD` defined? WHO KNOWS - D.equip_to_slot(new_headgear, SLOT_HEAD) + // where is `ITEM_SLOT_HEAD` defined? WHO KNOWS + D.equip_to_slot(new_headgear, ITEM_SLOT_HEAD) return 1 @@ -279,7 +279,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/under/chameleon) sensor_flags = NONE resistance_flags = NONE can_adjust = FALSE - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/datum/action/item_action/chameleon/change/chameleon_action @@ -289,7 +289,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/under/chameleon) icon_state = "engine" item_state = "engi_suit" -/obj/item/clothing/under/chameleon/Initialize() +/obj/item/clothing/under/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/clothing/under @@ -303,7 +303,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/under/chameleon) return chameleon_action.emp_randomise() -/obj/item/clothing/under/chameleon/broken/Initialize() +/obj/item/clothing/under/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -314,11 +314,11 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/suit/chameleon) item_state = "armor" blood_overlay_type = "armor" resistance_flags = NONE - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/clothing/suit/chameleon/Initialize() +/obj/item/clothing/suit/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/clothing/suit @@ -332,7 +332,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/suit/chameleon) return chameleon_action.emp_randomise() -/obj/item/clothing/suit/chameleon/broken/Initialize() +/obj/item/clothing/suit/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -342,11 +342,11 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/glasses/chameleon) icon_state = "meson" item_state = "meson" resistance_flags = NONE - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/clothing/glasses/chameleon/Initialize() +/obj/item/clothing/glasses/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/clothing/glasses @@ -360,7 +360,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/glasses/chameleon) return chameleon_action.emp_randomise() -/obj/item/clothing/glasses/chameleon/broken/Initialize() +/obj/item/clothing/glasses/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -371,14 +371,14 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/gloves/chameleon) item_state = "ygloves" resistance_flags = NONE - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/datum/action/item_action/chameleon/change/chameleon_action CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/gloves/chameleon/insulated) siemens_coefficient = 0 -/obj/item/clothing/gloves/chameleon/Initialize() +/obj/item/clothing/gloves/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/clothing/gloves @@ -392,7 +392,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/gloves/chameleon/insulated) return chameleon_action.emp_randomise() -/obj/item/clothing/gloves/chameleon/broken/Initialize() +/obj/item/clothing/gloves/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -402,11 +402,11 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/head/chameleon) icon_state = "greysoft" resistance_flags = NONE - armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 5, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/clothing/head/chameleon/Initialize() +/obj/item/clothing/head/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/clothing/head @@ -420,17 +420,17 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/head/chameleon) return chameleon_action.emp_randomise() -/obj/item/clothing/head/chameleon/broken/Initialize() +/obj/item/clothing/head/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) /obj/item/clothing/head/chameleon/drone // The camohat, I mean, holographic hat projection, is part of the // drone itself. - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) // which means it offers no protection, it's just air and light -/obj/item/clothing/head/chameleon/drone/Initialize() +/obj/item/clothing/head/chameleon/drone/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) chameleon_action.random_look() @@ -445,7 +445,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/mask/chameleon) icon_state = "gas_alt" item_state = "gas_alt" resistance_flags = NONE - armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 5, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) clothing_flags = BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEFACIALHAIR gas_transfer_coefficient = 0.01 @@ -456,7 +456,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/mask/chameleon) var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/clothing/mask/chameleon/Initialize() +/obj/item/clothing/mask/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/clothing/mask @@ -470,7 +470,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/mask/chameleon) return chameleon_action.emp_randomise() -/obj/item/clothing/mask/chameleon/broken/Initialize() +/obj/item/clothing/mask/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -480,11 +480,11 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/mask/chameleon) /obj/item/clothing/mask/chameleon/drone //Same as the drone chameleon hat, undroppable and no protection - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) // Can drones use the voice changer part? Let's not find out. voice_change = 0 -/obj/item/clothing/mask/chameleon/drone/Initialize() +/obj/item/clothing/mask/chameleon/drone/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) chameleon_action.random_look() @@ -502,12 +502,12 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/shoes/chameleon) desc = "A pair of black shoes." permeability_coefficient = 0.05 resistance_flags = NONE - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/clothing/shoes/chameleon/Initialize() +/obj/item/clothing/shoes/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/clothing/shoes @@ -527,7 +527,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/shoes/chameleon/noslip) desc = "A pair of black shoes." clothing_flags = NOSLIP -/obj/item/clothing/shoes/chameleon/noslip/broken/Initialize() +/obj/item/clothing/shoes/chameleon/noslip/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -535,7 +535,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/storage/backpack/chameleon) name = "backpack" var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/storage/backpack/chameleon/Initialize() +/obj/item/storage/backpack/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/storage/backpack @@ -548,7 +548,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/storage/backpack/chameleon) return chameleon_action.emp_randomise() -/obj/item/storage/backpack/chameleon/broken/Initialize() +/obj/item/storage/backpack/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -557,7 +557,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/storage/belt/chameleon) desc = "Holds tools." var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/storage/belt/chameleon/Initialize() +/obj/item/storage/belt/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) @@ -576,7 +576,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/storage/belt/chameleon) return chameleon_action.emp_randomise() -/obj/item/storage/belt/chameleon/broken/Initialize() +/obj/item/storage/belt/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -584,7 +584,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/radio/headset/chameleon) name = "radio headset" var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/radio/headset/chameleon/Initialize() +/obj/item/radio/headset/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/radio/headset @@ -597,7 +597,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/radio/headset/chameleon) return chameleon_action.emp_randomise() -/obj/item/radio/headset/chameleon/broken/Initialize() +/obj/item/radio/headset/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -605,7 +605,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/pda/chameleon) name = "PDA" var/datum/action/item_action/chameleon/change/pda/chameleon_action -/obj/item/pda/chameleon/Initialize() +/obj/item/pda/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/pda @@ -619,21 +619,21 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/pda/chameleon) return chameleon_action.emp_randomise() -/obj/item/pda/chameleon/broken/Initialize() +/obj/item/pda/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) CHAMELEON_CLOTHING_DEFINE(/obj/item/stamp/chameleon) var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/stamp/chameleon/Initialize() +/obj/item/stamp/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/stamp chameleon_action.chameleon_name = "Stamp" chameleon_action.initialize_disguises() -/obj/item/stamp/chameleon/broken/Initialize() +/obj/item/stamp/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) @@ -643,12 +643,12 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/neck/cloak/chameleon) icon = 'icons/obj/clothing/neck.dmi' icon_state = "blacktie" resistance_flags = NONE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) /obj/item/clothing/neck/cloak/chameleon var/datum/action/item_action/chameleon/change/chameleon_action -/obj/item/clothing/neck/cloak/chameleon/Initialize() +/obj/item/clothing/neck/cloak/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/clothing/neck diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 56ddb5f5f1..878b54de38 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -21,8 +21,6 @@ var/active_sound = null var/toggle_cooldown = null var/cooldown = 0 - var/obj/item/flashlight/F = null - var/can_flashlight = 0 var/blocks_shove_knockdown = FALSE //Whether wearing the clothing item blocks the ability for shove to knock down. @@ -65,9 +63,9 @@ ///These are armor values that protect the clothing, taken from its armor datum. List updates on examine because it's currently only used to print armor ratings to chat in Topic(). var/list/durability_list = list() -/obj/item/clothing/Initialize() +/obj/item/clothing/Initialize(mapload) . = ..() - if(CHECK_BITFIELD(clothing_flags, VOICEBOX_TOGGLABLE)) + if((clothing_flags & VOICEBOX_TOGGLABLE)) actions_types += /datum/action/item_action/toggle_voice_box if(ispath(pocket_storage_component_path)) LoadComponent(pocket_storage_component_path) @@ -112,7 +110,7 @@ to_chat(user, "You require 3 [S.name] to repair [src].") return to_chat(user, "You begin fixing the damage to [src] with [S]...") - if(do_after(user, 6 SECONDS, TRUE, src)) + if(do_after(user, 6 SECONDS, src)) if(S.use(3)) repair(user, params) return 1 @@ -187,7 +185,7 @@ body_parts_covered &= ~i if(body_parts_covered == NONE) // if there are no more parts to break then the whole thing is kaput - obj_destruction((damage_type == BRUTE ? "melee" : "laser")) // melee/laser is good enough since this only procs from direct attacks anyway and not from fire/bombs + obj_destruction((damage_type == BRUTE ? MELEE : LASER)) // melee/laser is good enough since this only procs from direct attacks anyway and not from fire/bombs return damaged_clothes = CLOTHING_DAMAGED @@ -221,7 +219,7 @@ ..() if (!istype(user)) return - if(slot_flags & slotdefine2slotbit(slot)) //Was equipped to a valid slot for this item? + if(slot_flags & slot) //Was equipped to a valid slot for this item? if(iscarbon(user) && LAZYLEN(zones_disabled)) RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/bristle) if(LAZYLEN(user_vars_to_edit)) @@ -427,13 +425,13 @@ BLIND // can't see anything /obj/item/clothing/obj_destruction(damage_flag) - if(damage_flag == "bomb") + if(damage_flag == BOMB) var/turf/T = get_turf(src) spawn(1) //so the shred survives potential turf change from the explosion. var/obj/effect/decal/cleanable/shreds/Shreds = new(T) Shreds.desc = "The sad remains of what used to be [name]." deconstruct(FALSE) - else if(!(damage_flag in list("acid", "fire"))) + else if(!(damage_flag in list(ACID, FIRE))) damaged_clothes = CLOTHING_SHREDDED body_parts_covered = NONE name = "shredded [initial(name)]" @@ -445,14 +443,14 @@ BLIND // can't see anything ..() //Species-restricted clothing check. - Thanks Oraclestation, BS13, /vg/station etc. -/obj/item/clothing/mob_can_equip(mob/M, slot, disable_warning = TRUE) +/obj/item/clothing/mob_can_equip(M, equipper, slot, disable_warning = TRUE, bypass_equip_delay_self) //if we can't equip the item anyway, don't bother with species_restricted (also cuts down on spam) if(!..()) return FALSE // Skip species restriction checks on non-equipment slots - if(slot in list(SLOT_IN_BACKPACK, SLOT_L_STORE, SLOT_R_STORE)) + if(slot in list(ITEM_SLOT_BACKPACK, ITEM_SLOT_LPOCKET, ITEM_SLOT_RPOCKET)) return TRUE if(species_restricted && ishuman(M)) diff --git a/code/modules/clothing/ears/_ears.dm b/code/modules/clothing/ears/_ears.dm index f58be1373a..35871fb142 100644 --- a/code/modules/clothing/ears/_ears.dm +++ b/code/modules/clothing/ears/_ears.dm @@ -20,7 +20,7 @@ /obj/item/clothing/ears/earmuffs/ComponentInitialize() . = ..() AddElement(/datum/element/earhealing) - AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS)) + AddComponent(/datum/component/wearertargeting/earprotection, list(ITEM_SLOT_EARS)) /obj/item/clothing/ears/headphones name = "headphones" @@ -33,7 +33,7 @@ var/headphones_on = FALSE custom_price = PRICE_ALMOST_CHEAP -/obj/item/clothing/ears/headphones/Initialize() +/obj/item/clothing/ears/headphones/Initialize(mapload) . = ..() update_icon() diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 01d27531e1..b2a7f91e96 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -27,6 +27,11 @@ if(glass_colour_type && ishuman(user)) . += "Alt-click to toggle its colors." +/obj/item/clothing/glasses/proc/prescribe() + vision_correction = TRUE + name = "prescription [name]" + desc += " These have been fitted with a prescription overlay device, and thus correct some vision deficiencies." + /obj/item/clothing/glasses/visor_toggling() ..() if(visor_vars_to_toggle & VISOR_VISIONFLAGS) @@ -112,10 +117,10 @@ actions_types = list(/datum/action/item_action/toggle_research_scanner) glass_colour_type = /datum/client_colour/glass_colour/purple resistance_flags = ACID_PROOF - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 100) /obj/item/clothing/glasses/science/item_action_slot_check(slot, mob/user, datum/action/A) - if(slot == SLOT_GLASSES) + if(slot == ITEM_SLOT_EYES) return 1 /obj/item/clothing/glasses/night @@ -128,10 +133,9 @@ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE glass_colour_type = /datum/client_colour/glass_colour/green -/obj/item/clothing/glasses/night/prescription - name = "prescription night vision goggles" - desc = "NVGs but for those with nearsightedness." - vision_correction = 1 +/obj/item/clothing/glasses/night/prescription/Initialize(mapload) + . = ..() + prescribe() /obj/item/clothing/glasses/night/syndicate name = "combat night vision goggles" @@ -158,7 +162,7 @@ /obj/item/clothing/glasses/eyepatch/syndicate/equipped(mob/living/carbon/human/user, slot) . = ..() - if(slot == SLOT_GLASSES) + if(slot == ITEM_SLOT_EYES) user.visible_message("Circuitry from the eyepatch links itself to your brain as you put on the eyepatch.") if(HAS_TRAIT(user, TRAIT_POOR_AIM)) user.visible_message("You hear a fizzing noise from the circuit. That can't be good.") @@ -233,6 +237,12 @@ icon_state = "circle_glasses" item_state = "circle_glasses" +/obj/item/clothing/glasses/regular/modern + name = "modern glasses" + desc = "A Dork. Co. revamp and/or revision of Nerd. Co.'s classic prescription glasses, with less opaque lenses." + icon_state = "glasses_alt" + item_state = "glasses_alt" + //Here lies green glasses, so ugly they died. RIP /obj/item/clothing/glasses/sunglasses @@ -299,7 +309,7 @@ actions_types = list(/datum/action/item_action/flash) var/obj/item/assembly/flash/installed -/obj/item/clothing/glasses/sunglasses/stunglasses/Initialize() +/obj/item/clothing/glasses/sunglasses/stunglasses/Initialize(mapload) . = ..() if (!installed) installed = new(src) @@ -351,7 +361,7 @@ /obj/item/clothing/glasses/sunglasses/blindfold/equipped(mob/living/carbon/human/user, slot) . = ..() - if(slot == SLOT_GLASSES) + if(slot == ITEM_SLOT_EYES) user.become_blind("blindfold_[REF(src)]") /obj/item/clothing/glasses/sunglasses/blindfold/dropped(mob/living/carbon/human/user) @@ -372,7 +382,7 @@ var/colored_before = FALSE /obj/item/clothing/glasses/sunglasses/blindfold/white/equipped(mob/living/carbon/human/user, slot) - if(ishuman(user) && slot == SLOT_GLASSES) + if(ishuman(user) && slot == ITEM_SLOT_EYES) update_icon(user) user.update_inv_glasses() //Color might have been changed by update_icon. ..() @@ -491,7 +501,7 @@ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE resistance_flags = LAVA_PROOF | FIRE_PROOF -/obj/item/clothing/glasses/godeye/Initialize() +/obj/item/clothing/glasses/godeye/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, EYE_OF_GOD_TRAIT) @@ -581,3 +591,14 @@ var/mob/living/carbon/human/H = user H.update_sight() +/obj/item/clothing/glasses/osi + name = "O.S.I. Sunglasses" + desc = "There's no such thing as good news! Just bad news and... weird news.." + icon_state = "osi_glasses" + item_state = "osi_glasses" + +/obj/item/clothing/glasses/phantom + name = "Phantom Thief Mask" + desc = "Lookin' cool." + icon_state = "phantom_glasses" + item_state = "phantom_glasses" diff --git a/code/modules/clothing/glasses/engine_goggles.dm b/code/modules/clothing/glasses/engine_goggles.dm index d7e7ae3669..461648c270 100644 --- a/code/modules/clothing/glasses/engine_goggles.dm +++ b/code/modules/clothing/glasses/engine_goggles.dm @@ -26,7 +26,7 @@ desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, the T-ray Scanner mode lets you see underfloor objects such as cables and pipes, and the Radiation Scanner mode let's you see objects contaminated by radiation. Each lens has been replaced with a corrective lens." vision_correction = 1 -/obj/item/clothing/glasses/meson/engine/Initialize() +/obj/item/clothing/glasses/meson/engine/Initialize(mapload) . = ..() START_PROCESSING(SSobj, src) update_icon() diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 9ca98b0bca..733fc0195c 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -3,6 +3,8 @@ desc = "A heads-up display that provides important info in (almost) real time." flags_1 = null //doesn't protect eyes because it's a monocle, duh var/hud_type = null + ///Used for topic calls. Just because you have a HUD display doesn't mean you should be able to interact with stuff. + var/hud_trait = null /obj/item/clothing/glasses/hud/CheckParts(list/parts_list) . = ..() @@ -12,11 +14,12 @@ if(G.vision_correction) vision_correction = TRUE name = "prescription [name]" + desc += " These have been made with some form of vision-correcting eyewear, thus making them innately correct some vision deficiencies." return /obj/item/clothing/glasses/hud/equipped(mob/living/carbon/human/user, slot) ..() - if(hud_type && slot == SLOT_GLASSES) + if(hud_type && slot == ITEM_SLOT_EYES) var/datum/atom_hud/H = GLOB.huds[hud_type] H.add_hud_to(user) @@ -53,13 +56,9 @@ hud_type = DATA_HUD_MEDICAL_ADVANCED glass_colour_type = /datum/client_colour/glass_colour/lightblue -/obj/item/clothing/glasses/hud/health/prescription - name = "prescription health scanner HUD" - desc = "A heads-up display, made with a prescription lens, that scans the humans in view and provides accurate data about their health status." - icon_state = "healthhud" - hud_type = DATA_HUD_MEDICAL_ADVANCED - vision_correction = 1 - glass_colour_type = /datum/client_colour/glass_colour/lightblue +/obj/item/clothing/glasses/hud/health/prescription/Initialize(mapload) + . = ..() + prescribe() /obj/item/clothing/glasses/hud/health/night name = "night vision health scanner HUD" @@ -86,9 +85,9 @@ tint = 1 glass_colour_type = /datum/client_colour/glass_colour/blue -/obj/item/clothing/glasses/hud/health/sunglasses/prescription - name = "prescription medical HUDSunglasses" - vision_correction = 1 +/obj/item/clothing/glasses/hud/health/sunglasses/prescription/Initialize(mapload) + . = ..() + prescribe() /obj/item/clothing/glasses/hud/health/eyepatch name = "eyepatch medHUD" @@ -115,17 +114,13 @@ flash_protect = 1 tint = 1 -/obj/item/clothing/glasses/hud/diagnostic/prescription - name = "prescription diagnostic HUD" - desc = "A heads-up display capable of analyzing the integrity and status of robotics and exosuits. This one has a prescription lens." - icon_state = "diagnostichud" - hud_type = DATA_HUD_DIAGNOSTIC_BASIC - vision_correction = 1 - glass_colour_type = /datum/client_colour/glass_colour/lightorange +/obj/item/clothing/glasses/hud/diagnostic/prescription/Initialize(mapload) + . = ..() + prescribe() -/obj/item/clothing/glasses/hud/diagnostic/sunglasses/prescription - name = "prescription diagnostic HUDSunglasses" - vision_correction = 1 +/obj/item/clothing/glasses/hud/diagnostic/sunglasses/prescription/Initialize(mapload) + . = ..() + prescribe() /obj/item/clothing/glasses/hud/diagnostic/night name = "night vision diagnostic HUD" @@ -153,13 +148,9 @@ hud_type = DATA_HUD_SECURITY_ADVANCED glass_colour_type = /datum/client_colour/glass_colour/red -/obj/item/clothing/glasses/hud/security/prescription - name = "prescription security HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status and security records. This one has a prescription lens so you can see the banana peal that slipped you." - icon_state = "securityhud" - hud_type = DATA_HUD_SECURITY_ADVANCED - vision_correction = 1 - glass_colour_type = /datum/client_colour/glass_colour/red +/obj/item/clothing/glasses/hud/security/prescription/Initialize(mapload) + . = ..() + prescribe() /obj/item/clothing/glasses/hud/security/chameleon name = "chameleon security HUD" @@ -198,9 +189,9 @@ desc = "A heads-up display that connects directly to the optical nerve of the user, replacing the need for that useless eyeball." icon_state = "hudpatch" -/obj/item/clothing/glasses/hud/security/sunglasses/prescription - name = "prescription security HUDSunglasses" - vision_correction = 1 +/obj/item/clothing/glasses/hud/security/sunglasses/prescription/Initialize(mapload) + . = ..() + prescribe() /obj/item/clothing/glasses/hud/security/night name = "night vision security HUD" @@ -290,3 +281,16 @@ if(. & EMP_PROTECT_SELF) return thermal_overload() + +/obj/item/clothing/glasses/hud/spacecop + name = "police aviators" + desc = "For thinking you look cool while brutalizing protestors and minorities." + icon_state = "bigsunglasses" + hud_type = ANTAG_HUD_GANGSTER + +/obj/item/clothing/glasses/hud/spacecop/hidden // for the undercover cop + name = "sunglasses" + desc = "These sunglasses are special, and let you view potential criminals." + icon_state = "sun" + item_state = "sunglasses" + diff --git a/code/modules/clothing/glasses/phantomthief.dm b/code/modules/clothing/glasses/phantomthief.dm index 6d209ec695..db77f17218 100644 --- a/code/modules/clothing/glasses/phantomthief.dm +++ b/code/modules/clothing/glasses/phantomthief.dm @@ -3,8 +3,8 @@ desc = "A cheap, Syndicate-branded paper face mask. They'll never see it coming." mob_overlay_icon = 'icons/mob/clothing/mask.dmi' icon = 'icons/obj/clothing/masks.dmi' - icon_state = "s-ninja" - item_state = "s-ninja" + icon_state = "ninjaOLD" + item_state = "ninjaOLD" /obj/item/clothing/glasses/phantomthief/ComponentInitialize() . = ..() @@ -17,7 +17,7 @@ /obj/item/clothing/glasses/phantomthief/syndicate/examine(mob/user) . = ..() - if(user.get_item_by_slot(SLOT_GLASSES) == src) + if(user.get_item_by_slot(ITEM_SLOT_EYES) == src) if(world.time >= nextadrenalinepop) . += "The built-in adrenaline injector is ready for use." else @@ -33,7 +33,7 @@ . = ..() if(!istype(user)) return - if(slot != SLOT_GLASSES) + if(slot != ITEM_SLOT_EYES) return RegisterSignal(user, COMSIG_LIVING_COMBAT_ENABLED, .proc/injectadrenaline) diff --git a/code/modules/clothing/glasses/prescription_kit.dm b/code/modules/clothing/glasses/prescription_kit.dm new file mode 100644 index 0000000000..9e324d34f0 --- /dev/null +++ b/code/modules/clothing/glasses/prescription_kit.dm @@ -0,0 +1,32 @@ +// don't you love single purpose files? i do too. + +/obj/item/prescription_kit + name = "prescription lens kit" + desc = "A disposable kit containing all the needed tools and parts to develop and apply a self-modifying prescription lens overlay device to any eyewear. \ + Insert eyewear, receive vision-correcting lenses." + icon = 'icons/obj/device.dmi' + icon_state = "modkit" + +/obj/item/prescription_kit/attackby(obj/item/I, mob/living/user, params) + if(istype(I, /obj/item/clothing/glasses) && I.Adjacent(user)) + var/obj/item/clothing/glasses/target_glasses = I + prescribe(target_glasses, user) + else + return ..() + +/obj/item/prescription_kit/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + if(istype(target, /obj/item/clothing/glasses) && target.Adjacent(user)) + var/obj/item/clothing/glasses/target_glasses = target + prescribe(target_glasses, user) + else + . = ..() + +/obj/item/prescription_kit/proc/prescribe(obj/item/clothing/glasses/target_glasses, mob/user) + if(target_glasses.vision_correction) + to_chat(user, span_notice("These are already fitted with prescription lenses or otherwise already correct vision!")) + return + playsound(src, 'sound/items/screwdriver.ogg', 50, 1) + user.visible_message(span_notice("[user] fits \the [target_glasses] with a prescription overlay device."), span_notice("You fit \the [target_glasses] with a prescription overlay device.")) + target_glasses.prescribe() + target_glasses.balloon_alert(user, "prescription fitted!") + qdel(src) diff --git a/code/modules/clothing/gloves/_gloves.dm b/code/modules/clothing/gloves/_gloves.dm index 4b558d6604..cec4324b3c 100644 --- a/code/modules/clothing/gloves/_gloves.dm +++ b/code/modules/clothing/gloves/_gloves.dm @@ -32,7 +32,7 @@ if(damaged_clothes) . += mutable_appearance('icons/effects/item_damage.dmi', "damagedgloves") if(blood_DNA) - . += mutable_appearance('icons/effects/blood.dmi', "bloodyhands", color = blood_DNA_to_color()) + . += mutable_appearance('icons/effects/blood.dmi', "bloodyhands", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) /obj/item/clothing/gloves/update_clothes_damaged_state() ..() diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 836b845faa..d763899987 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -31,7 +31,7 @@ C.visible_message("[U] sprays glittery rubber on the hands of [C]!") else user.visible_message("The rubber fails to stick to [C]'s hands!", - "The rubber fails to stick to [C]'s [(SLOT_GLOVES in C.check_obscured_slots()) ? "unexposed" : ""] hands!") + "The rubber fails to stick to [C]'s [(ITEM_SLOT_GLOVES in C.check_obscured_slots()) ? "unexposed" : ""] hands!") qdel(src) @@ -44,7 +44,7 @@ resistance_flags = ACID_PROOF var/shocks_remaining = 10 -/obj/item/clothing/gloves/color/yellow/sprayon/Initialize() +/obj/item/clothing/gloves/color/yellow/sprayon/Initialize(mapload) .=..() ADD_TRAIT(src, TRAIT_NODROP, GLOVE_TRAIT) @@ -79,7 +79,7 @@ desc = "Old and worn out insulated gloves, hopefully they still work." name = "worn out insulated gloves" -/obj/item/clothing/gloves/color/fyellow/old/Initialize() +/obj/item/clothing/gloves/color/fyellow/old/Initialize(mapload) . = ..() siemens_coefficient = pick(0,0,0,0.5,0.5,0.5,0.75) @@ -211,7 +211,7 @@ heat_protection = HANDS max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT strip_delay = 60 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 70, ACID = 50) /obj/item/clothing/gloves/color/latex name = "latex gloves" @@ -226,7 +226,7 @@ /obj/item/clothing/gloves/color/latex/equipped(mob/user, slot) ..() - if(slot == SLOT_GLOVES) + if(slot == ITEM_SLOT_GLOVES) ADD_TRAIT(user, carrytrait, GLOVE_TRAIT) /obj/item/clothing/gloves/color/latex/dropped(mob/user) diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index 8c8400a45d..efa00ef888 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -9,6 +9,8 @@ equip_delay_other = 20 cold_protection = HANDS min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT + heat_protection = HANDS + max_heat_protection_temperature = COAT_MAX_TEMP_PROTECT strip_mod = 0.9 custom_price = PRICE_ALMOST_CHEAP @@ -36,7 +38,7 @@ /obj/item/clothing/gloves/fingerless/pugilist/equipped(mob/user, slot) . = ..() - if(slot == SLOT_GLOVES) + if(slot == ITEM_SLOT_GLOVES) wornonce = TRUE if((HAS_TRAIT(user, TRAIT_NOPUGILIST))) to_chat(user, "What purpose is there to don the weapons of pugilism if you're already well-practiced in martial arts? Mixing arts is blasphemous!") @@ -77,16 +79,18 @@ to_chat(user, "With [src] off of your arms, you feel less ready to punch things.") /obj/item/clothing/gloves/fingerless/pugilist/crafted - unique_reskin = list("Short" = "armwraps", - "Extended" = "armwraps_extended" - ) + unique_reskin = list( + "Short" = list("icon_state" = "armwraps"), + "Extended" = list("icon_state" = "armwraps_extended") + ) /obj/item/clothing/gloves/fingerless/pugilist/crafted/reskin_obj(mob/M) . = ..() - if(icon_state == "armwraps_extended") - item_state = "armwraps_extended" - else - return + switch(current_skin) + if("Short") + item_state = "armwraps" + if("Extended") + item_state = "armwraps_extended" /obj/item/clothing/gloves/fingerless/pugilist/chaplain name = "armwraps of unyielding resolve" @@ -96,7 +100,7 @@ secondary_trait = TRAIT_ANTIMAGIC var/chaplain_spawnable = TRUE -/obj/item/clothing/gloves/fingerless/pugilist/chaplain/Initialize() +/obj/item/clothing/gloves/fingerless/pugilist/chaplain/Initialize(mapload) . = ..() AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE) @@ -112,7 +116,7 @@ icon_state = "narsiearmwraps" item_state = "narsiearmwraps" resistance_flags = FIRE_PROOF | ACID_PROOF - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 35, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 35, RAD = 0, FIRE = 50, ACID = 50) enhancement = 3 secondary_trait = TRAIT_KI_VAMPIRE @@ -122,7 +126,7 @@ icon_state = "ratvararmwraps" item_state = "ratvararmwraps" resistance_flags = FIRE_PROOF | ACID_PROOF - armor = list("melee" = 10, "bullet" = 0, "laser" = -10, "energy" = 0, "bomb" = 0, "bio" = 35, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 0, LASER = -10, ENERGY = 0, BOMB = 0, BIO = 35, RAD = 0, FIRE = 50, ACID = 50) enhancement = 4 //The artifice of Ratvar is unmatched except when it is. secondary_trait = TRAIT_STRONG_GRABBER @@ -136,7 +140,7 @@ var/warcry = "AT" secondary_trait = TRAIT_NOSOFTCRIT //basically extra health -/obj/item/clothing/gloves/fingerless/pugilist/rapid/Initialize() +/obj/item/clothing/gloves/fingerless/pugilist/rapid/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, GLOVE_TRAIT) @@ -195,7 +199,7 @@ /obj/item/clothing/gloves/fingerless/ablative/equipped(mob/user, slot) . = ..() - if(current_equipped_slot == SLOT_GLOVES) + if(current_equipped_slot == ITEM_SLOT_GLOVES) RegisterSignal(user, COMSIG_LIVING_ACTIVE_PARRY_START, .proc/get_component_parry_data) wornonce = TRUE @@ -250,7 +254,7 @@ cold_protection = ARMS|HANDS min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT - armor = list("melee" = 30, "bullet" = 30, "laser" = 10, "energy" = 10, "bomb" = 55, "bio" = 15, "rad" = 15, "fire" = 80, "acid" = 50) + armor = list(MELEE = 30, BULLET = 30, LASER = 10, ENERGY = 10, BOMB = 55, BIO = 15, RAD = 15, FIRE = 80, ACID = 50) siemens_coefficient = 0 permeability_coefficient = 0.05 strip_delay = 80 @@ -262,7 +266,7 @@ /obj/item/clothing/gloves/fingerless/pugilist/mauler/equipped(mob/user, slot) . = ..() - if(slot == SLOT_GLOVES) + if(slot == ITEM_SLOT_GLOVES) wornonce = TRUE if((HAS_TRAIT(user, TRAIT_NOPUGILIST))) return @@ -295,7 +299,7 @@ heat_protection = HANDS max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT resistance_flags = NONE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 70, ACID = 30) strip_mod = 0.9 /obj/item/clothing/gloves/combat @@ -311,7 +315,7 @@ heat_protection = HANDS max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT resistance_flags = NONE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 50) strip_mod = 1.5 /obj/item/clothing/gloves/bracer @@ -327,7 +331,7 @@ min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT resistance_flags = NONE - armor = list("melee" = 15, "bullet" = 35, "laser" = 35, "energy" = 20, "bomb" = 35, "bio" = 35, "rad" = 35, "fire" = 0, "acid" = 0) + armor = list(MELEE = 15, BULLET = 35, LASER = 35, ENERGY = 20, BOMB = 35, BIO = 35, RAD = 35, FIRE = 0, ACID = 0) /obj/item/clothing/gloves/thief name = "black gloves" @@ -349,6 +353,8 @@ transfer_prints = TRUE cold_protection = HANDS min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT + heat_protection = HANDS + max_heat_protection_temperature = COAT_MAX_TEMP_PROTECT strip_mod = 0.9 /obj/item/clothing/gloves/evening/black @@ -356,3 +362,12 @@ desc = "Thin, pretty gloves intended for use in sexy feminine attire. A tag on the hem claims they pair great with black stockings." icon_state = "eveningblack" item_state = "eveningblack" + +/obj/item/clothing/gloves/polymaid + name = "polychromic maid gloves" + desc = "Colourable maid gloves!" + icon_state = "maid_arms" + +/obj/item/clothing/gloves/polymaid/ComponentInitialize() + . = ..() + AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2) diff --git a/code/modules/clothing/gloves/mittens.dm b/code/modules/clothing/gloves/mittens.dm new file mode 100644 index 0000000000..2d00da6780 --- /dev/null +++ b/code/modules/clothing/gloves/mittens.dm @@ -0,0 +1,32 @@ +/obj/item/clothing/gloves/mittens + desc = "These gloves will keep your hands warm!" + name = "mittens" + icon_state = "mittens" + item_state = "wgloves" + //item_color = "white" + cold_protection = HANDS + min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT + heat_protection = HANDS + max_heat_protection_temperature = COAT_MAX_TEMP_PROTECT + resistance_flags = NONE + +/obj/item/clothing/gloves/mittens/random + +/obj/item/clothing/gloves/mittens/random/Initialize(mapload) + ..() + var/colours = list("black", "yellow", "lightbrown", "brown", "orange", "red", "purple", "green", "blue", "kitten") + var/picked_c = pick(colours) + if(picked_c == "kitten") + new /obj/item/clothing/gloves/mittens/kitten(loc) + qdel(src) + return INITIALIZE_HINT_QDEL + item_state = "[picked_c]gloves" + //item_color = "[picked_c]" + color = picked_c + +/obj/item/clothing/gloves/mittens/kitten + name = "Kitten mittens" + desc = "These gloves will keep your hands warm, and feature cute kittens" + icon_state = "kittenmittens" + item_state = "blackgloves" + //item_color = "black" diff --git a/code/modules/clothing/gloves/tacklers.dm b/code/modules/clothing/gloves/tacklers.dm index eda36ea12f..b99eca1a61 100644 --- a/code/modules/clothing/gloves/tacklers.dm +++ b/code/modules/clothing/gloves/tacklers.dm @@ -6,6 +6,8 @@ transfer_prints = TRUE cold_protection = HANDS min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT + heat_protection = HANDS + max_heat_protection_temperature = COAT_MAX_TEMP_PROTECT resistance_flags = NONE //custom_premium_price = PRICE_EXPENSIVE /// For storing our tackler datum so we can remove it after @@ -23,18 +25,25 @@ /// See: [/datum/component/tackler/var/skill_mod] var/skill_mod = 1 +/obj/item/clothing/gloves/tackler/Destroy() + tackler = null + return ..() + /obj/item/clothing/gloves/tackler/equipped(mob/user, slot) . = ..() if(!ishuman(user)) return - if(slot == ITEM_SLOT_GLOVES) - var/mob/living/carbon/human/H = user - tackler = H.AddComponent(/datum/component/tackler, stamina_cost=tackle_stam_cost, base_knockdown = base_knockdown, range = tackle_range, speed = tackle_speed, skill_mod = skill_mod, min_distance = min_distance) + switch(slot) // I didn't like how it looked + if(ITEM_SLOT_GLOVES) + var/mob/living/carbon/human/H = user + tackler = H.AddComponent(/datum/component/tackler, stamina_cost=tackle_stam_cost, base_knockdown = base_knockdown, range = tackle_range, speed = tackle_speed, skill_mod = skill_mod, min_distance = min_distance) + else + QDEL_NULL(tackler) // Only wearing it! /obj/item/clothing/gloves/tackler/dropped(mob/user) . = ..() if(tackler) - qdel(tackler) + QDEL_NULL(tackler) /obj/item/clothing/gloves/tackler/dolphin name = "dolphin gloves" @@ -67,6 +76,20 @@ resistance_flags = NONE strip_mod = 1.2 // because apparently black gloves had this +/obj/item/clothing/gloves/tackler/combat/goliath + name = "goliath gloves" + desc = "Rudimentary tackling gloves. The goliath hide makes it great for grappling with targets, while also being fireproof." + icon = 'icons/obj/mining.dmi' + icon_state = "goligloves" + item_state = "goligloves" + + tackle_stam_cost = 25 + base_knockdown = 1 SECONDS + tackle_range = 5 + tackle_speed = 2 + min_distance = 2 + skill_mod = 1 + /obj/item/clothing/gloves/tackler/combat/insulated name = "guerrilla gloves" desc = "Superior quality combative gloves, good for performing tackle takedowns as well as absorbing electrical shocks." @@ -86,7 +109,7 @@ /obj/item/clothing/gloves/tackler/combat/insulated/infiltrator/equipped(mob/user, slot) . = ..() - if(slot == SLOT_GLOVES) + if(slot == ITEM_SLOT_GLOVES) ADD_TRAIT(user, carrytrait, GLOVE_TRAIT) /obj/item/clothing/gloves/tackler/combat/insulated/infiltrator/dropped(mob/user) @@ -116,3 +139,9 @@ base_knockdown = 1.75 SECONDS min_distance = 2 skill_mod = -1 + +/obj/item/clothing/gloves/tackler/football + name = "football gloves" + desc = "Gloves for football players! Teaches them how to tackle like a pro." + icon_state = "tackle_gloves" + item_state = "tackle_gloves" diff --git a/code/modules/clothing/head/_head.dm b/code/modules/clothing/head/_head.dm index 6ad3a19694..884c23e7c0 100644 --- a/code/modules/clothing/head/_head.dm +++ b/code/modules/clothing/head/_head.dm @@ -10,7 +10,7 @@ dynamic_hair_suffix = "+generic" var/datum/beepsky_fashion/beepsky_fashion //the associated datum for applying this to a secbot -/obj/item/clothing/head/Initialize() +/obj/item/clothing/head/Initialize(mapload) . = ..() if(ishuman(loc) && dynamic_hair_suffix) var/mob/living/carbon/human/H = loc @@ -34,7 +34,7 @@ var/obj/item/WH = H.head H.visible_message("[src] bounces off [H]'s [WH.name]!", "[src] bounces off your [WH.name], falling to the floor.") return - if(H.equip_to_slot_if_possible(src, SLOT_HEAD, FALSE, TRUE)) + if(H.equip_to_slot_if_possible(src, ITEM_SLOT_HEAD, FALSE, TRUE)) H.visible_message("[src] lands neatly on [H]'s head!", "[src] lands perfectly onto your head!") return if(iscyborg(hit_atom)) @@ -55,7 +55,7 @@ if(damaged_clothes) . += mutable_appearance('icons/effects/item_damage.dmi', "damagedhelmet") if(blood_DNA) - . += mutable_appearance('icons/effects/blood.dmi', "helmetblood", color = blood_DNA_to_color()) + . += mutable_appearance('icons/effects/blood.dmi', "helmetblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) /obj/item/clothing/head/update_clothes_damaged_state() ..() diff --git a/code/modules/clothing/head/beanie.dm b/code/modules/clothing/head/beanie.dm index 365624bc0d..3e53b3aaa5 100644 --- a/code/modules/clothing/head/beanie.dm +++ b/code/modules/clothing/head/beanie.dm @@ -72,7 +72,7 @@ name = "durathread beanie" desc = "A beanie made from durathread, its resilient fibres provide some protection to the wearer." icon_state = "beaniedurathread" - armor = list("melee" = 25, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 30, "bio" = 15, "rad" = 20, "fire" = 100, "acid" = 50) + armor = list(MELEE = 25, BULLET = 10, LASER = 20,ENERGY = 10, BOMB = 30, BIO = 15, RAD = 20, FIRE = 100, ACID = 50) /obj/item/clothing/head/beanie/waldo name = "red striped bobble hat" diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 95ce887693..226255e133 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -8,7 +8,7 @@ var/power_on = 0.8 var/on = FALSE var/hat_type = "yellow" //Determines used sprites: hardhat[on]_[hat_type] and hardhat[on]_[hat_type]2 (lying down sprite) - armor = list("melee" = 15, "bullet" = 5, "laser" = 20,"energy" = 10, "bomb" = 20, "bio" = 10, "rad" = 20, "fire" = 100, "acid" = 50) + armor = list(MELEE = 15, BULLET = 5, LASER = 20,ENERGY = 10, BOMB = 20, BIO = 10, RAD = 20, FIRE = 100, ACID = 50) flags_inv = 0 actions_types = list(/datum/action/item_action/toggle_helmet_light) resistance_flags = FIRE_PROOF @@ -117,7 +117,7 @@ visor_flags_inv = HIDEEYES | HIDEFACE visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH -/obj/item/clothing/head/hardhat/weldhat/Initialize() +/obj/item/clothing/head/hardhat/weldhat/Initialize(mapload) . = ..() update_icon() diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index de68883a7b..ff78b51909 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -3,7 +3,7 @@ desc = "Standard Security gear. Protects the head from impacts." icon_state = "helmet" item_state = "helmet" - armor = list("melee" = 40, "bullet" = 30, "laser" = 30,"energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 40, BULLET = 30, LASER = 30,ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) flags_inv = HIDEEARS cold_protection = HEAD min_cold_protection_temperature = HELMET_MIN_TEMP_PROTECT @@ -16,9 +16,39 @@ dog_fashion = /datum/dog_fashion/head/helmet + var/can_flashlight = FALSE //if a flashlight can be mounted. if it has a flashlight and this is false, it is permanently attached. + var/obj/item/flashlight/seclite/attached_light + var/datum/action/item_action/toggle_helmet_flashlight/alight + +/obj/item/clothing/head/helmet/Initialize(mapload) + . = ..() + if(attached_light) + alight = new(src) + /obj/item/clothing/head/helmet/ComponentInitialize() . = ..() - AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_HEAD)) + AddComponent(/datum/component/wearertargeting/earprotection, list(ITEM_SLOT_HEAD)) + +/obj/item/clothing/head/helmet/examine(mob/user) + . = ..() + if(attached_light) + . += "It has \a [attached_light] [can_flashlight ? "" : "permanently "]mounted on it." + if(can_flashlight) + . += "[attached_light] looks like it can be unscrewed from [src]." + else if(can_flashlight) + . += "It has a mounting point for a seclite." + +/obj/item/clothing/head/helmet/Destroy() + QDEL_NULL(attached_light) + return ..() + +/obj/item/clothing/head/helmet/handle_atom_del(atom/A) + if(A == attached_light) + attached_light = null + update_helmlight() + update_icon() + QDEL_NULL(alight) + return ..() /obj/item/clothing/head/helmet/sec can_flashlight = 1 @@ -26,7 +56,7 @@ /obj/item/clothing/head/helmet/sec/attackby(obj/item/I, mob/user, params) if(issignaler(I)) var/obj/item/assembly/signaler/S = I - if(F) //Has a flashlight. Player must remove it, else it will be lost forever. + if(attached_light) //Has a flashlight. Player must remove it, else it will be lost forever. to_chat(user, "The mounted flashlight is in the way, remove it first!") return @@ -44,7 +74,7 @@ desc = "A bulletproof combat helmet that excels in protecting the wearer against traditional projectile weaponry and explosives to a minor extent." icon_state = "helmetalt" item_state = "helmetalt" - armor = list("melee" = 15, "bullet" = 60, "laser" = 10, "energy" = 10, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 15, BULLET = 60, LASER = 10, ENERGY = 10, BOMB = 40, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) can_flashlight = 1 dog_fashion = null @@ -68,7 +98,7 @@ toggle_message = "You pull the visor down on" alt_toggle_message = "You push the visor up on" can_toggle = 1 - armor = list("melee" = 45, "bullet" = 15, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 2, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 45, BULLET = 15, LASER = 5,ENERGY = 5, BOMB = 5, BIO = 2, RAD = 0, FIRE = 50, ACID = 50) flags_inv = HIDEEARS|HIDEFACE strip_delay = 80 actions_types = list(/datum/action/item_action/toggle) @@ -124,7 +154,7 @@ desc = "An extremely robust, space-worthy helmet in a nefarious red and black stripe pattern." icon_state = "swatsyndie" item_state = "swatsyndie" - armor = list("melee" = 40, "bullet" = 30, "laser" = 30,"energy" = 30, "bomb" = 50, "bio" = 90, "rad" = 20, "fire" = 50, "acid" = 50) + armor = list(MELEE = 40, BULLET = 30, LASER = 30,ENERGY = 30, BOMB = 50, BIO = 90, RAD = 20, FIRE = 50, ACID = 50) cold_protection = HEAD min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT heat_protection = HEAD @@ -145,7 +175,7 @@ flags_inv = HIDEEARS|HIDEHAIR icon_state = "thunderdome" item_state = "thunderdome" - armor = list("melee" = 40, "bullet" = 30, "laser" = 25,"energy" = 10, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 40, BULLET = 30, LASER = 25,ENERGY = 10, BOMB = 25, BIO = 10, RAD = 0, FIRE = 50, ACID = 50) cold_protection = HEAD min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT heat_protection = HEAD @@ -158,7 +188,7 @@ desc = "An ancient helmet made of bronze and leather." flags_inv = HIDEEARS|HIDEHAIR flags_cover = HEADCOVERSEYES - armor = list("melee" = 25, "bullet" = 0, "laser" = 25, "energy" = 10, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 25, BULLET = 0, LASER = 25, ENERGY = 10, BOMB = 10, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF icon_state = "roman" item_state = "roman" @@ -167,7 +197,7 @@ /obj/item/clothing/head/helmet/roman/fake desc = "An ancient helmet made of plastic and leather." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/head/helmet/roman/legionnaire name = "\improper Roman legionnaire helmet" @@ -177,7 +207,7 @@ /obj/item/clothing/head/helmet/roman/legionnaire/fake desc = "An ancient helmet made of plastic and leather. Has a red crest on top of it." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/head/helmet/gladiator name = "gladiator helmet" @@ -194,7 +224,7 @@ icon_state = "redtaghelm" flags_cover = HEADCOVERSEYES item_state = "redtaghelm" - armor = list("melee" = 15, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 15, BULLET = 10, LASER = 20,ENERGY = 10, BOMB = 20, BIO = 0, RAD = 0, FIRE = 0, ACID = 50) // Offer about the same protection as a hardhat. dog_fashion = null @@ -204,7 +234,7 @@ icon_state = "bluetaghelm" flags_cover = HEADCOVERSEYES item_state = "bluetaghelm" - armor = list("melee" = 15, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 15, BULLET = 10, LASER = 20,ENERGY = 10, BOMB = 20, BIO = 0, RAD = 0, FIRE = 0, ACID = 50) // Offer about the same protection as a hardhat. dog_fashion = null @@ -213,7 +243,7 @@ desc = "A classic metal helmet." icon_state = "knight_green" item_state = "knight_green" - armor = list("melee" = 41, "bullet" = 15, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 2, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 41, BULLET = 15, LASER = 5,ENERGY = 5, BOMB = 5, BIO = 2, RAD = 0, FIRE = 0, ACID = 50) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH strip_delay = 80 @@ -243,7 +273,7 @@ desc = "A classic medieval helmet, if you hold it upside down you could see that it's actually a bucket." icon_state = "knight_greyscale" item_state = "knight_greyscale" - armor = list("melee" = 35, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40) + armor = list(MELEE = 35, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 10, BIO = 10, RAD = 10, FIRE = 40, ACID = 40) material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS //Can change color and add prefix /obj/item/clothing/head/helmet/skull @@ -251,7 +281,7 @@ desc = "An intimidating tribal helmet, it doesn't look very comfortable." flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE flags_cover = HEADCOVERSEYES - armor = list("melee" = 25, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 10, "bio" = 5, "rad" = 20, "fire" = 40, "acid" = 20) + armor = list(MELEE = 25, BULLET = 25, LASER = 25, ENERGY = 10, BOMB = 10, BIO = 5, RAD = 20, FIRE = 40, ACID = 20) icon_state = "skull" item_state = "skull" strip_delay = 100 @@ -262,7 +292,7 @@ desc = "An insidious armored combat helmet signed with Syndicate insignia. The visor is coated with a resistant paste guaranteed to withstand bright flashes perfectly." icon_state = "infiltrator" item_state = "infiltrator" - armor = list("melee" = 40, "bullet" = 40, "laser" = 30, "energy" = 40, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 40, BULLET = 40, LASER = 30, ENERGY = 40, BOMB = 70, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) resistance_flags = FIRE_PROOF | ACID_PROOF flash_protect = 2 flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT @@ -280,8 +310,8 @@ /obj/item/clothing/head/helmet/update_icon_state() var/state = "[initial(icon_state)]" - if(F) - if(F.on) + if(attached_light) + if(attached_light.on) state += "-flight-on" //"helmet-flight-on" // "helmet-cam-flight-on" else state += "-flight" //etc. @@ -289,7 +319,7 @@ icon_state = state /obj/item/clothing/head/helmet/ui_action_click(mob/user, action) - if(istype(action, /datum/action/item_action/toggle_helmet_flashlight)) + if(istype(action, alight)) toggle_helmlight() else ..() @@ -297,60 +327,60 @@ /obj/item/clothing/head/helmet/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/flashlight/seclite)) var/obj/item/flashlight/seclite/S = I - if(can_flashlight) - if(!F) - if(!user.transferItemToLoc(S, src)) - return - to_chat(user, "You click [S] into place on [src].") - if(S.on) - set_light(0) - F = S - update_icon() - update_helmlight(user) - verbs += /obj/item/clothing/head/helmet/proc/toggle_helmlight - var/datum/action/A = new /datum/action/item_action/toggle_helmet_flashlight(src) - if(loc == user) - A.Grant(user) + if(can_flashlight && !attached_light) + if(!user.transferItemToLoc(S, src)) + return + to_chat(user, "You click [S] into place on [src].") + if(S.on) + set_light(0) + attached_light = S + update_icon() + update_helmlight() + alight = new(src) + if(loc == user) + alight.Grant(user) return - - if(I.tool_behaviour == TOOL_SCREWDRIVER) - if(F) - for(var/obj/item/flashlight/seclite/S in src) - to_chat(user, "You unscrew the seclite from [src].") - F = null - S.forceMove(user.drop_location()) - update_helmlight(user) - S.update_brightness(user) - update_icon() - usr.update_inv_head() - verbs -= /obj/item/clothing/head/helmet/proc/toggle_helmlight - for(var/datum/action/item_action/toggle_helmet_flashlight/THL in actions) - qdel(THL) - return - return ..() +/obj/item/clothing/head/helmet/screwdriver_act(mob/living/user, obj/item/I) + ..() + if(can_flashlight && attached_light) //if it has a light but can_flashlight is false, the light is permanently attached. + I.play_tool_sound(src) + to_chat(user, "You unscrew [attached_light] from [src].") + attached_light.forceMove(drop_location()) + if(Adjacent(user) && !issilicon(user)) + user.put_in_hands(attached_light) + + var/obj/item/flashlight/removed_light = attached_light + attached_light = null + update_helmlight() + removed_light.update_brightness(user) + update_icon() + user.update_inv_head() + QDEL_NULL(alight) + return TRUE + /obj/item/clothing/head/helmet/proc/toggle_helmlight() set name = "Toggle Helmetlight" set category = "Object" set desc = "Click to toggle your helmet's attached flashlight." - if(!F) + if(!attached_light) return var/mob/user = usr if(user.incapacitated()) return - F.on = !F.on - to_chat(user, "You toggle the helmetlight [F.on ? "on":"off"].") + attached_light.on = !attached_light.on + to_chat(user, "You toggle the helmet-light [attached_light.on ? "on":"off"].") playsound(user, 'sound/weapons/empty.ogg', 100, 1) update_helmlight(user) /obj/item/clothing/head/helmet/proc/update_helmlight(mob/user = null) - if(F) - if(F.on) - set_light(F.brightness_on, F.flashlight_power, F.light_color) + if(attached_light) + if(attached_light.on) + set_light(attached_light.brightness_on, attached_light.flashlight_power, attached_light.light_color) else set_light(0) update_icon() @@ -366,14 +396,14 @@ desc = "A hardhat with strips of leather and durathread for additional blunt protection." icon_state = "durathread" item_state = "durathread" - armor = list("melee" = 25, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 30, "bio" = 15, "rad" = 20, "fire" = 100, "acid" = 50) + armor = list(MELEE = 25, BULLET = 10, LASER = 20,ENERGY = 10, BOMB = 30, BIO = 15, RAD = 20, FIRE = 100, ACID = 50) /obj/item/clothing/head/helmet/rus_helmet name = "russian helmet" desc = "It can hold a bottle of vodka." icon_state = "rus_helmet" item_state = "rus_helmet" - armor = list("melee" = 30, "bullet" = 25, "laser" = 20,"energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 20, "fire" = 30, "acid" = 50) + armor = list(MELEE = 30, BULLET = 25, LASER = 20,ENERGY = 10, BOMB = 25, BIO = 0, RAD = 20, FIRE = 30, ACID = 50) pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/rushelmet /obj/item/clothing/head/helmet/rus_ushanka @@ -385,7 +415,7 @@ body_parts_covered = HEAD cold_protection = HEAD min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT - armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 50, "rad" = 20, "fire" = -10, "acid" = 0) + armor = list(MELEE = 10, BULLET = 5, LASER = 5,ENERGY = 5, BOMB = 5, BIO = 50, RAD = 20, FIRE = -10, ACID = 0) /obj/item/clothing/head/helmet/police name = "police officer's hat" diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 5af694ea1b..40729a442d 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -33,7 +33,7 @@ icon_state = "captain" item_state = "that" flags_inv = 0 - armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) strip_delay = 60 dog_fashion = /datum/dog_fashion/head/captain @@ -65,7 +65,7 @@ name = "head of personnel's cap" icon_state = "hopcap" desc = "The symbol of true bureaucratic micromanagement." - armor = list("melee" = 30, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 30, BULLET = 25, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) dog_fashion = /datum/dog_fashion/head/hop /obj/item/clothing/head/hopcap/beret @@ -93,13 +93,13 @@ /obj/item/clothing/head/fedora/det_hat name = "detective's fedora" desc = "There's only one man who can sniff out the dirty stench of crime, and he's likely wearing this hat." - armor = list("melee" = 25, "bullet" = 5, "laser" = 25, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 50) + armor = list(MELEE = 25, BULLET = 5, LASER = 25, ENERGY = 10, BOMB = 0, BIO = 0, RAD = 0, FIRE = 30, ACID = 50) icon_state = "detective" var/candy_cooldown = 0 pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/detective dog_fashion = /datum/dog_fashion/head/detective -/obj/item/clothing/head/fedora/det_hat/Initialize() +/obj/item/clothing/head/fedora/det_hat/Initialize(mapload) . = ..() new /obj/item/reagent_containers/food/drinks/flask/det(src) @@ -147,7 +147,7 @@ desc = "That was white fabric. Was." dog_fashion = null //THIS IS FOR SLAUGHTER, NOT PUPPIES -/obj/item/clothing/head/beret/highlander/Initialize() +/obj/item/clothing/head/beret/highlander/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, HIGHLANDER) @@ -157,7 +157,7 @@ name = "head of security cap" desc = "The robust standard-issue cap of the Head of Security. For showing the officers who's in charge." icon_state = "hoscap" - armor = list("melee" = 40, "bullet" = 30, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 60) + armor = list(MELEE = 40, BULLET = 30, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 10, RAD = 0, FIRE = 50, ACID = 60) strip_delay = 80 dynamic_hair_suffix = "" @@ -183,7 +183,7 @@ name = "warden's police hat" desc = "It's a special armored hat issued to the Warden of a security force. Protects the head from impacts." icon_state = "policehelm" - armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 60) + armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 30, ACID = 60) strip_delay = 60 dog_fashion = /datum/dog_fashion/head/warden @@ -220,7 +220,7 @@ /obj/item/clothing/head/warden/drill/equipped(mob/M, slot) . = ..() - if (slot == SLOT_HEAD) + if (slot == ITEM_SLOT_HEAD) RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) else UnregisterSignal(M, COMSIG_MOB_SAY) @@ -258,7 +258,7 @@ name = "security beret" desc = "A robust beret with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficient protection." icon_state = "beret_badge" - armor = list("melee" = 40, "bullet" = 30, "laser" = 30,"energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 40, BULLET = 30, LASER = 30,ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) strip_delay = 60 dog_fashion = null @@ -368,7 +368,7 @@ name = "durathread beret" desc = "A beret made from durathread, its resilient fibres provide some protection to the wearer." icon_state = "beretdurathread" - armor = list("melee" = 25, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 30, "bio" = 15, "rad" = 20, "fire" = 100, "acid" = 50) + armor = list(MELEE = 25, BULLET = 10, LASER = 20,ENERGY = 10, BOMB = 30, BIO = 15, RAD = 20, FIRE = 100, ACID = 50) #undef DRILL_DEFAULT #undef DRILL_SHOUTING diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index fd181779f1..0a626a0558 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -6,9 +6,15 @@ desc = "It's good to be emperor." item_state = "that" flags_inv = 0 - armor = list("melee" = 30, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 30, BULLET = 15, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) strip_delay = 80 +/obj/item/clothing/head/spacepolice + name = "space police cap" + desc = "A blue cap for patrolling the daily beat." + icon_state = "policecap_families" + item_state = "policecap_families" + /obj/item/clothing/head/powdered_wig name = "powdered wig" desc = "A powdered wig." @@ -232,7 +238,7 @@ dog_fashion = null -/obj/item/clothing/head/sombrero/shamebrero/Initialize() +/obj/item/clothing/head/sombrero/shamebrero/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, SHAMEBRERO_TRAIT) @@ -258,7 +264,8 @@ item_state = "that" cold_protection = HEAD min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT - + heat_protection = HEAD + max_heat_protection_temperature = COAT_MAX_TEMP_PROTECT dog_fashion = /datum/dog_fashion/head/santa beepsky_fashion = /datum/beepsky_fashion/santa @@ -294,7 +301,7 @@ name = "crown" desc = "A crown fit for a king, a petty king maybe." icon_state = "crown" - armor = list("melee" = 15, "bullet" = 0, "laser" = 0,"energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 15, BULLET = 0, LASER = 0,ENERGY = 15, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF dynamic_hair_suffix = "" @@ -348,7 +355,7 @@ /obj/item/clothing/head/frenchberet/equipped(mob/M, slot) . = ..() - if (slot == SLOT_HEAD) + if (slot == ITEM_SLOT_HEAD) RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) else UnregisterSignal(M, COMSIG_MOB_SAY) @@ -433,6 +440,16 @@ icon_state = "cowboyhat_sec" item_state= "cowboyhat_sec" +/obj/item/clothing/head/cowboyhat/polychromic + name = "polychromic cowboy hat" + desc = "A polychromic cowboy hat, perfect for your indecisive rancher" + icon_state = "cowboyhat_poly" + item_state= "cowboyhat_poly" + +/obj/item/clothing/head/cowboyhat/polychromic/ComponentInitialize() + . = ..() + AddElement(/datum/element/polychromic, list("#5F5F5F", "#DDDDDD"), 2) + /obj/item/clothing/head/squatter_hat name = "slav squatter hat" icon_state = "squatter_hat" @@ -451,7 +468,7 @@ desc = "Ain't nobody gonna cheat the hangman in my town." icon_state = "hunter" item_state = "hunter" - armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 5, BULLET = 5, LASER = 5, ENERGY = 15, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) resistance_flags = FIRE_PROOF | ACID_PROOF /obj/item/clothing/head/kepi @@ -470,6 +487,15 @@ item_state = "maid" dynamic_hair_suffix = "" +/obj/item/clothing/head/maid/polychromic + name = "polychromic maid headband" + icon_state = "polymaid" + item_state = "polymaid" + +/obj/item/clothing/head/maid/polychromic/ComponentInitialize() + . = ..() + AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2) + /obj/item/clothing/head/widered name = "Wide red hat" desc = "It is both wide, and red. Stylish!" @@ -488,3 +514,10 @@ desc = "This will scare them. All will know my power." icon_state = "human_leather" item_state = "human_leather" + +/obj/item/clothing/head/jackbros + name = "frosty hat" + desc = "Hee-ho!" + icon_state = "JackFrostHat" + item_state = "JackFrostHat" + diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index e19a0538fc..c0ff26342e 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -22,7 +22,7 @@ custom_materials = list(/datum/material/iron=1750, /datum/material/glass=400) flash_protect = 2 tint = 2 - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 60) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 60) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE actions_types = list(/datum/action/item_action/toggle) visor_flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE @@ -45,7 +45,7 @@ hat_type = "cakehat" hitsound = 'sound/weapons/tap.ogg' flags_inv = HIDEEARS|HIDEHAIR - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) brightness_on = 2 //luminosity when on flags_cover = HEADCOVERSEYES heat = 1000 @@ -90,23 +90,36 @@ item_state = "ushankadown" alternate_screams = list('sound/voice/human/cyka1.ogg', 'sound/voice/human/cheekibreeki.ogg') flags_inv = HIDEEARS|HIDEHAIR - var/earflaps = 1 + var/earflaps = TRUE cold_protection = HEAD min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT + heat_protection = HEAD + max_heat_protection_temperature = COAT_MAX_TEMP_PROTECT + ///Sprite visible when the ushanka flaps are folded up. + var/upsprite = "ushankaup" + ///Sprite visible when the ushanka flaps are folded down. + var/downsprite = "ushankadown" dog_fashion = /datum/dog_fashion/head/ushanka /obj/item/clothing/head/ushanka/attack_self(mob/user) if(earflaps) - src.icon_state = "ushankaup" - src.item_state = "ushankaup" - earflaps = 0 + icon_state = upsprite + item_state = upsprite to_chat(user, "You raise the ear flaps on the ushanka.") else - src.icon_state = "ushankadown" - src.item_state = "ushankadown" - earflaps = 1 + icon_state = downsprite + item_state = downsprite to_chat(user, "You lower the ear flaps on the ushanka.") + earflaps = !earflaps + +/obj/item/clothing/head/ushanka/soviet + name = "soviet ushanka" + desc = "For the union!" + icon_state = "sovietushankadown" + item_state = "sovietushankadown" + upsprite = "sovietushankaup" + downsprite = "sovietushankadown" /* * Pumpkin head @@ -118,7 +131,7 @@ item_state = "hardhat0_pumpkin" hat_type = "pumpkin" flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) brightness_on = 2 //luminosity when on flags_cover = HEADCOVERSEYES @@ -136,7 +149,7 @@ beepsky_fashion = /datum/beepsky_fashion/cat /obj/item/clothing/head/kitty/equipped(mob/living/carbon/human/user, slot) - if(ishuman(user) && slot == SLOT_HEAD) + if(ishuman(user) && slot == ITEM_SLOT_HEAD) update_icon(user) user.update_inv_head() //Color might have been changed by update_icon. ..() @@ -156,7 +169,7 @@ item_state = "hardhat0_reindeer" hat_type = "reindeer" flags_inv = 0 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) brightness_on = 1 //luminosity when on dynamic_hair_suffix = "" @@ -175,7 +188,7 @@ /obj/item/clothing/head/cardborg/equipped(mob/living/user, slot) ..() - if(ishuman(user) && slot == SLOT_HEAD) + if(ishuman(user) && slot == ITEM_SLOT_HEAD) var/mob/living/carbon/human/H = user if(istype(H.wear_suit, /obj/item/clothing/suit/cardborg)) var/obj/item/clothing/suit/cardborg/CB = H.wear_suit @@ -232,14 +245,14 @@ icon = 'icons/obj/clothing/clockwork_garb.dmi' icon_state = "clockwork_helmet_old" flags_inv = HIDEEARS|HIDEHAIR - armor = list("melee" = 5, "bullet" = 0, "laser" = -5, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 20) + armor = list(MELEE = 5, BULLET = 0, LASER = -5, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 20, ACID = 20) /obj/item/clothing/head/foilhat name = "tinfoil hat" desc = "Thought control rays, psychotronic scanning. Don't mind that, I'm protected cause I made this hat." icon_state = "foilhat" item_state = "foilhat" - armor = list("melee" = 0, "bullet" = 0, "laser" = -5,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = -5, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = -5,ENERGY = 0, BOMB = 0, BIO = 0, RAD = -5, FIRE = 0, ACID = 0) equip_delay_other = 140 var/datum/brain_trauma/mild/phobia/conspiracies/paranoia var/warped = FALSE @@ -254,7 +267,7 @@ /obj/item/clothing/head/foilhat/equipped(mob/living/carbon/human/user, slot) . = ..() - if(slot != SLOT_HEAD || warped) + if(slot != ITEM_SLOT_HEAD || warped) return if(paranoia) QDEL_NULL(paranoia) @@ -284,7 +297,7 @@ if(!isliving(loc) || !paranoia) return var/mob/living/target = loc - if(target.get_item_by_slot(SLOT_HEAD) != src) + if(target.get_item_by_slot(ITEM_SLOT_HEAD) != src) return QDEL_NULL(paranoia) if(!target.IsUnconscious()) @@ -307,7 +320,7 @@ name = "flak helmet" icon_state = "m1helm" item_state = "helmet" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0.1, "bio" = 0, "rad" = 0, "fire" = -10, "acid" = -15) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0.1, BIO = 0, RAD = 0, FIRE = -10, ACID = -15) desc = "A dilapidated helmet used in ancient wars. This one is brittle and essentially useless. An ace of spades is tucked into the band around the outer shell." pocket_storage_component_path = /datum/component/storage/concrete/pockets/tiny/spacenam //So you can stuff other things in the elastic band instead of it simply being a fluff thing. @@ -315,3 +328,55 @@ /datum/component/storage/concrete/pockets/tiny/spacenam attack_hand_interact = TRUE //So you can actually see what you stuff in there + +//families +/obj/item/clothing/head/irs + name = "internal revenue service cap" + icon_state = "irs_hat" + item_state = "irs_hat" + +/obj/item/clothing/head/pg + name = "powder ganger beanie" + icon_state = "pg_hat" + item_state = "pg_hat" + +/obj/item/clothing/head/tmc + name = "Lost M.C. bandana" + icon_state = "tmc_hat" + item_state = "tmc_hat" + +/obj/item/clothing/head/deckers + name = "Decker headphones" + icon_state = "decker_hat" + item_state = "decker_hat" + +/obj/item/clothing/head/morningstar + name = "Morningstar beret" + icon_state = "morningstar_hat" + item_state = "morningstar_hat" + +/obj/item/clothing/head/saints + name = "Saints hat" + icon_state = "saints_hat" + item_state = "saints_hat" + +/obj/item/clothing/head/allies + name = "allies helmet" + icon_state = "allies_helmet" + item_state = "allies_helmet" + +/obj/item/clothing/head/yuri + name = "yuri initiate helmet" + icon_state = "yuri_helmet" + item_state = "yuri_helmet" + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT + +/obj/item/clothing/head/sybil_slickers + name = "sybil slickers helmet" + icon_state = "football_helmet_blue" + item_state = "football_helmet_blue" + +/obj/item/clothing/head/basil_boys + name = "basil boys helmet" + icon_state = "football_helmet_red" + item_state = "football_helmet_red" diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm index 084d39a9b5..5569da96eb 100644 --- a/code/modules/clothing/head/soft_caps.dm +++ b/code/modules/clothing/head/soft_caps.dm @@ -119,7 +119,7 @@ desc = "It's a robust baseball hat in tasteful red colour." icon_state = "secsoft" soft_type = "sec" - armor = list("melee" = 30, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 50) + armor = list(MELEE = 30, BULLET = 25, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 20, ACID = 50) strip_delay = 60 dog_fashion = null @@ -137,6 +137,6 @@ soft_type = "baseball" item_state = "baseballsoft" flags_inv = HIDEEYES|HIDEFACE - armor = list("melee" = 35, "bullet" = 35, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 90) + armor = list(MELEE = 35, BULLET = 35, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 20, ACID = 90) strip_delay = 90 //You dont take a Major Leage cap dog_fashion = null diff --git a/code/modules/clothing/masks/_masks.dm b/code/modules/clothing/masks/_masks.dm index c4063108db..b30adedb4b 100644 --- a/code/modules/clothing/masks/_masks.dm +++ b/code/modules/clothing/masks/_masks.dm @@ -11,14 +11,14 @@ var/datum/beepsky_fashion/beepsky_fashion //the associated datum for applying this to a secbot /obj/item/clothing/mask/attack_self(mob/user) - if(CHECK_BITFIELD(clothing_flags, VOICEBOX_TOGGLABLE)) - TOGGLE_BITFIELD(clothing_flags, VOICEBOX_DISABLED) - var/status = !CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED) + if((clothing_flags & VOICEBOX_TOGGLABLE)) + (clothing_flags ^= VOICEBOX_DISABLED) + var/status = !(clothing_flags & VOICEBOX_DISABLED) to_chat(user, "You turn the voice box in [src] [status ? "on" : "off"].") /obj/item/clothing/mask/equipped(mob/M, slot) . = ..() - if (slot == SLOT_WEAR_MASK && modifies_speech) + if (slot == ITEM_SLOT_MASK && modifies_speech) RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) else UnregisterSignal(M, COMSIG_MOB_SAY) @@ -36,7 +36,7 @@ if(damaged_clothes) . += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask") if(blood_DNA) - . += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color()) + . += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) /obj/item/clothing/mask/update_clothes_damaged_state() ..() diff --git a/code/modules/clothing/masks/boxing.dm b/code/modules/clothing/masks/boxing.dm index 6701b53c10..324562c1a5 100644 --- a/code/modules/clothing/masks/boxing.dm +++ b/code/modules/clothing/masks/boxing.dm @@ -26,7 +26,7 @@ flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR visor_flags_inv = HIDEFACE|HIDEFACIALHAIR w_class = WEIGHT_CLASS_SMALL - armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 30, "acid" = 30) + armor = list(MELEE = 10, BULLET = 5, LASER = 5,ENERGY = 5, BOMB = 0, BIO = 0, RAD = 10, FIRE = 30, ACID = 30) resistance_flags = FIRE_PROOF | ACID_PROOF mutantrace_variation = STYLE_MUZZLE var/voice_unknown = TRUE ///This makes it so that your name shows up as unknown when wearing the mask. diff --git a/code/modules/clothing/masks/cluwne.dm b/code/modules/clothing/masks/cluwne.dm index a1177e2b47..cc2105d5fc 100644 --- a/code/modules/clothing/masks/cluwne.dm +++ b/code/modules/clothing/masks/cluwne.dm @@ -12,7 +12,7 @@ var/last_sound = 0 var/delay = 15 -/obj/item/clothing/mask/gas/cluwne/Initialize() +/obj/item/clothing/mask/gas/cluwne/Initialize(mapload) .=..() ADD_TRAIT(src, TRAIT_NODROP, CLOTHING_TRAIT) ADD_TRAIT(src, CURSED_ITEM_TRAIT, CLOTHING_TRAIT) @@ -55,7 +55,7 @@ . = ..() if(!ishuman(user)) return - if(slot == SLOT_WEAR_MASK) + if(slot == ITEM_SLOT_MASK) var/mob/living/carbon/human/H = user H.dna.add_mutation(CLUWNEMUT) return @@ -68,7 +68,7 @@ var/is_cursed = FALSE //i don't care that this is *slightly* memory wasteful, it's just one more byte and it's not like some madman is going to spawn thousands of these var/is_very_cursed = FALSE -/obj/item/clothing/mask/gas/cluwne/happy_cluwne/Initialize() +/obj/item/clothing/mask/gas/cluwne/happy_cluwne/Initialize(mapload) .=..() if(prob(1)) //this function pre-determines the logic of the cluwne mask. applying and reapplying the mask does not alter or change anything is_cursed = TRUE @@ -88,7 +88,7 @@ if(!ishuman(user)) return var/mob/living/carbon/human/H = user - if(slot == SLOT_WEAR_MASK) + if(slot == ITEM_SLOT_MASK) if(is_cursed && can_cluwne) //logic predetermined log_admin("[key_name(H)] was made into a cluwne by [src]") message_admins("[key_name(H)] got cluwned by [src]") diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 525db577e0..a2d13822f8 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -41,7 +41,7 @@ custom_materials = list(/datum/material/iron=4000, /datum/material/glass=2000) flash_protect = 2 tint = 2 - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 55) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 55) actions_types = list(/datum/action/item_action/toggle) flags_inv = HIDEEARS|HIDEEYES|HIDEFACE flags_cover = MASKCOVERSEYES @@ -55,7 +55,7 @@ /obj/item/clothing/mask/gas/welding/up -/obj/item/clothing/mask/gas/welding/up/Initialize() +/obj/item/clothing/mask/gas/welding/up/Initialize(mapload) ..() visor_toggling() @@ -68,7 +68,7 @@ desc = "A modernised version of the classic design, this mask will not only filter out toxins but it can also be connected to an air supply." icon_state = "plaguedoctor" item_state = "gas_mask" - armor = list("melee" = 0, "bullet" = 0, "laser" = 2,"energy" = 2, "bomb" = 0, "bio" = 75, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 2,ENERGY = 2, BOMB = 0, BIO = 75, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/mask/gas/syndicate name = "syndicate mask" @@ -83,6 +83,7 @@ icon_state = "clown" item_state = "clown_hat" dye_color = "clown" + w_class = WEIGHT_CLASS_SMALL flags_cover = MASKCOVERSEYES resistance_flags = FLAMMABLE actions_types = list(/datum/action/item_action/adjust) @@ -118,6 +119,23 @@ to_chat(user, "Your Clown Mask has now morphed into [choice], all praise the Honkmother!") return TRUE +/obj/item/clothing/mask/gas/clown_hat_polychromic + name = "polychromic clown wig and mask" + desc = "A true prankster's facial attire. A clown is incomplete without his wig and mask." + clothing_flags = ALLOWINTERNALS + icon_state = "clown" + item_state = "clown_hat" + dye_color = "clown" + w_class = WEIGHT_CLASS_SMALL + flags_cover = MASKCOVERSEYES + resistance_flags = FLAMMABLE + dog_fashion = /datum/dog_fashion/head/clown + var/list/poly_colors = list("#FF8000", "#FFFFFF", "#FF0000", "#0000FF", "#FFFF00") + +/obj/item/clothing/mask/gas/clown_hat_polychromic/ComponentInitialize() + . = ..() + AddElement(/datum/element/polychromic, poly_colors, 5, names = list("Hair", "Frame", "Mouth", "Eyes", "Markings")) + /obj/item/clothing/mask/gas/clown_hat/sexy name = "sexy-clown wig and mask" desc = "A feminine clown mask for the dabbling crossdressers or female entertainers." @@ -131,6 +149,7 @@ clothing_flags = ALLOWINTERNALS icon_state = "mime" item_state = "mime" + w_class = WEIGHT_CLASS_SMALL flags_cover = MASKCOVERSEYES resistance_flags = FLAMMABLE actions_types = list(/datum/action/item_action/adjust) @@ -271,3 +290,11 @@ item_state = "hunter" resistance_flags = FIRE_PROOF | ACID_PROOF flags_inv = HIDEFACIALHAIR|HIDEFACE|HIDEEYES|HIDEEARS|HIDEHAIR + +/obj/item/clothing/mask/gas/driscoll + name = "driscoll mask" + desc = "Great for train hijackings. Works like a normal full face gas mask, but won't conceal your identity." + icon_state = "driscoll_mask" + flags_inv = HIDEFACIALHAIR + w_class = WEIGHT_CLASS_NORMAL + item_state = "driscoll_mask" diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index 88fbc98280..f96fe2ac2a 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -29,7 +29,7 @@ visor_flags_cover = MASKCOVERSMOUTH gas_transfer_coefficient = 0.9 permeability_coefficient = 0.01 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 25, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 25, RAD = 0, FIRE = 0, ACID = 0) actions_types = list(/datum/action/item_action/adjust) mutantrace_variation = STYLE_MUZZLE @@ -41,7 +41,7 @@ visor_flags_inv = null visor_flags_cover = null permeability_coefficient = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/mask/surgical/attack_self(mob/user) adjustmask(user) @@ -113,6 +113,50 @@ to_chat(user, "Your Joy mask now has a [choice] Emotion!") return 1 +/obj/item/clothing/mask/kitsuneblk + name = "Black Kitsune Mask" + desc = "An oriental styled porcelain mask, this one is black and gold." + icon_state = "blackkitsunemask" + item_state = "blackkitsunemask" + w_class = WEIGHT_CLASS_TINY + flags_cover = MASKCOVERSMOUTH + flags_inv = HIDEFACE|HIDEFACIALHAIR + visor_flags_inv = HIDEFACE|HIDEFACIALHAIR + visor_flags_cover = MASKCOVERSMOUTH + slot_flags = ITEM_SLOT_MASK + +/obj/item/clothing/mask/kitsuneblk/attack_self(mob/user) + adjustmask(user) + +/obj/item/clothing/mask/kitsuneblk/AltClick(mob/user) + . = ..() + if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return + adjustmask(user) + return TRUE + +/obj/item/clothing/mask/kitsunewhi + name = "White Kitsune Mask" + desc = "An oriental styled porcelain mask, this one is white and red." + icon_state = "whitekitsunemask" + item_state = "whitekitsunemask" + w_class = WEIGHT_CLASS_TINY + flags_cover = MASKCOVERSMOUTH + flags_inv = HIDEFACE|HIDEFACIALHAIR + visor_flags_inv = HIDEFACE|HIDEFACIALHAIR + visor_flags_cover = MASKCOVERSMOUTH + slot_flags = ITEM_SLOT_MASK + +/obj/item/clothing/mask/kitsunewhi/attack_self(mob/user) + adjustmask(user) + +/obj/item/clothing/mask/kitsunewhi/AltClick(mob/user) + . = ..() + if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return + adjustmask(user) + return TRUE + /obj/item/clothing/mask/pig name = "pig mask" desc = "A rubber pig mask with a builtin voice modulator." @@ -124,7 +168,7 @@ modifies_speech = TRUE /obj/item/clothing/mask/pig/handle_speech(datum/source, list/speech_args) - if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED)) + if(!(clothing_flags & VOICEBOX_DISABLED)) speech_args[SPEECH_MESSAGE] = pick("Oink!","Squeeeeeeee!","Oink Oink!") /obj/item/clothing/mask/pig/cursed //needs to be different otherwise you could turn the speedmodification off and on @@ -133,7 +177,7 @@ flags_inv = HIDEFACIALHAIR clothing_flags = NONE -/obj/item/clothing/mask/pig/cursed/Initialize() +/obj/item/clothing/mask/pig/cursed/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CURSED_MASK_TRAIT) playsound(get_turf(src), 'sound/magic/pighead_curse.ogg', 50, 1) @@ -150,7 +194,7 @@ modifies_speech = TRUE /obj/item/clothing/mask/frog/handle_speech(datum/source, list/speech_args) //whenever you speak - if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED)) + if(!(clothing_flags & VOICEBOX_DISABLED)) if(prob(5)) //sometimes, the angry spirit finds others words to speak. speech_args[SPEECH_MESSAGE] = pick("HUUUUU!!","SMOOOOOKIN'!!","Hello my baby, hello my honey, hello my rag-time gal.", "Feels bad, man.", "GIT DIS GUY OFF ME!!" ,"SOMEBODY STOP ME!!", "NORMIES, GET OUT!!") else @@ -159,7 +203,7 @@ /obj/item/clothing/mask/frog/cursed clothing_flags = NONE -/obj/item/clothing/mask/frog/cursed/Initialize() +/obj/item/clothing/mask/frog/cursed/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CURSED_MASK_TRAIT) @@ -180,7 +224,7 @@ modifies_speech = TRUE /obj/item/clothing/mask/cowmask/handle_speech(datum/source, list/speech_args) - if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED)) + if(!(clothing_flags & VOICEBOX_DISABLED)) speech_args[SPEECH_MESSAGE] = pick("Moooooooo!","Moo!","Moooo!") @@ -190,7 +234,7 @@ flags_inv = HIDEFACIALHAIR clothing_flags = NONE -/obj/item/clothing/mask/cowmask/cursed/Initialize() +/obj/item/clothing/mask/cowmask/cursed/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CURSED_MASK_TRAIT) playsound(get_turf(src), 'sound/magic/cowhead_curse.ogg', 50, 1) @@ -205,7 +249,7 @@ clothing_flags = VOICEBOX_TOGGLABLE /obj/item/clothing/mask/horsehead/handle_speech(datum/source, list/speech_args) - if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED)) + if(!(clothing_flags & VOICEBOX_DISABLED)) speech_args[SPEECH_MESSAGE] = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!") @@ -215,7 +259,7 @@ clothing_flags = NONE flags_inv = HIDEFACIALHAIR -/obj/item/clothing/mask/horsehead/cursed/Initialize() +/obj/item/clothing/mask/horsehead/cursed/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CURSED_MASK_TRAIT) playsound(get_turf(src), 'sound/magic/horsehead_curse.ogg', 50, 1) @@ -290,7 +334,7 @@ . = ..() if(iscarbon(user)) var/mob/living/carbon/C = user - if((C.get_item_by_slot(SLOT_HEAD == src)) || (C.get_item_by_slot(SLOT_WEAR_MASK) == src)) + if((C.get_item_by_slot(ITEM_SLOT_HEAD == src)) || (C.get_item_by_slot(ITEM_SLOT_MASK) == src)) to_chat(user, "You can't tie [src] while wearing it!") return if(slot_flags & ITEM_SLOT_HEAD) diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index 28a3343ae6..7ac2f65205 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -13,7 +13,7 @@ if(damaged_clothes) . += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask") if(blood_DNA) - . += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color()) + . += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) /obj/item/clothing/neck/tie name = "tie" @@ -175,7 +175,7 @@ var/tagname = null var/treat_path = /obj/item/reagent_containers/food/snacks/cookie -/obj/item/clothing/neck/petcollar/Initialize() +/obj/item/clothing/neck/petcollar/Initialize(mapload) . = ..() if(treat_path) new treat_path(src) @@ -226,7 +226,7 @@ return /obj/item/clothing/neck/petcollar/locked/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - if(loc == user && user.get_item_by_slot(SLOT_NECK) && lock != FALSE) + if(loc == user && user.get_item_by_slot(ITEM_SLOT_NECK) && lock != FALSE) to_chat(user, "The collar is locked! You'll need unlock the collar before you can take it off!") return ..() @@ -259,6 +259,15 @@ name = "Collar Key" desc = "A key for a tiny lock on a collar or bag." +/obj/item/clothing/neck/maid + name = "polychromic maid collar" + desc = "A collar that goes with the polychromic maid outfit." + icon_state = "maid_neck" + +/obj/item/clothing/neck/maid/ComponentInitialize() + . = ..() + AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2) + ////////////// //DOPE BLING// ////////////// @@ -323,7 +332,7 @@ . = ..() if(iscarbon(user)) var/mob/living/carbon/C = user - if(C.get_item_by_slot(SLOT_NECK) == src) + if(C.get_item_by_slot(ITEM_SLOT_NECK) == src) to_chat(user, "You can't untie [src] while wearing it!") return if(user.is_holding(src)) diff --git a/code/modules/clothing/outfits/ert.dm b/code/modules/clothing/outfits/ert.dm index 7cd2e9b394..86aa0748df 100644 --- a/code/modules/clothing/outfits/ert.dm +++ b/code/modules/clothing/outfits/ert.dm @@ -30,7 +30,7 @@ glasses = /obj/item/clothing/glasses/hud/security/sunglasses back = /obj/item/storage/backpack/captain belt = /obj/item/storage/belt/security/full - backpack_contents = list(/obj/item/storage/box/engineer=1,\ + backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\ /obj/item/melee/baton/loaded=1,\ /obj/item/clothing/mask/gas/sechailer=1,\ /obj/item/gun/energy/e_gun=1) @@ -50,7 +50,7 @@ suit = /obj/item/clothing/suit/space/hardsuit/ert/alert glasses = /obj/item/clothing/glasses/thermal/eyepatch - backpack_contents = list(/obj/item/storage/box/engineer=1,\ + backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\ /obj/item/melee/baton/loaded=1,\ /obj/item/clothing/mask/gas/sechailer/swat=1,\ /obj/item/gun/energy/e_gun=1) @@ -58,7 +58,7 @@ /datum/outfit/ert/commander/alert/red name = "ERT Commander - Red Alert" - backpack_contents = list(/obj/item/storage/box/engineer=1,\ + backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\ /obj/item/melee/baton/loaded=1,\ /obj/item/clothing/mask/gas/sechailer/swat=1,\ /obj/item/gun/energy/pulse/pistol/loyalpin=1) @@ -71,7 +71,7 @@ glasses = /obj/item/clothing/glasses/hud/security/sunglasses belt = /obj/item/storage/belt/security/full back = /obj/item/storage/backpack/security - backpack_contents = list(/obj/item/storage/box/engineer=1,\ + backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\ /obj/item/storage/box/handcuffs=1,\ /obj/item/clothing/mask/gas/sechailer=1,\ /obj/item/gun/energy/e_gun/stun=1,\ @@ -91,7 +91,7 @@ name = "ERT Security - Amber Alert" suit = /obj/item/clothing/suit/space/hardsuit/ert/alert/sec - backpack_contents = list(/obj/item/storage/box/engineer=1,\ + backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\ /obj/item/storage/box/handcuffs=1,\ /obj/item/clothing/mask/gas/sechailer/swat=1,\ /obj/item/melee/baton/loaded=1,\ @@ -99,7 +99,7 @@ /datum/outfit/ert/security/alert/red name = "ERT Security - Red Alert" - backpack_contents = list(/obj/item/storage/box/engineer=1,\ + backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\ /obj/item/storage/box/handcuffs=1,\ /obj/item/clothing/mask/gas/sechailer/swat=1,\ /obj/item/melee/baton/loaded=1,\ @@ -114,7 +114,7 @@ back = /obj/item/storage/backpack/satchel/med belt = /obj/item/storage/belt/medical r_hand = /obj/item/storage/firstaid/regular - backpack_contents = list(/obj/item/storage/box/engineer=1,\ + backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\ /obj/item/melee/baton/loaded=1,\ /obj/item/clothing/mask/gas/sechailer=1,\ /obj/item/gun/energy/e_gun=1,\ @@ -135,7 +135,7 @@ name = "ERT Medic - Amber Alert" suit = /obj/item/clothing/suit/space/hardsuit/ert/alert/med - backpack_contents = list(/obj/item/storage/box/engineer=1,\ + backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\ /obj/item/melee/baton/loaded=1,\ /obj/item/clothing/mask/gas/sechailer/swat=1,\ /obj/item/gun/energy/e_gun=1,\ @@ -144,7 +144,7 @@ /datum/outfit/ert/medic/alert/red name = "ERT Medic - Red Alert" - backpack_contents = list(/obj/item/storage/box/engineer=1,\ + backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\ /obj/item/melee/baton/loaded=1,\ /obj/item/clothing/mask/gas/sechailer/swat=1,\ /obj/item/gun/energy/pulse/pistol/loyalpin=1,\ @@ -161,7 +161,7 @@ belt = /obj/item/storage/belt/utility/full l_pocket = /obj/item/rcd_ammo/large r_hand = /obj/item/storage/firstaid/regular - backpack_contents = list(/obj/item/storage/box/engineer=1,\ + backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\ /obj/item/melee/baton/loaded=1,\ /obj/item/clothing/mask/gas/sechailer=1,\ /obj/item/gun/energy/e_gun=1,\ @@ -181,7 +181,7 @@ name = "ERT Engineer - Amber Alert" suit = /obj/item/clothing/suit/space/hardsuit/ert/alert/engi - backpack_contents = list(/obj/item/storage/box/engineer=1,\ + backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\ /obj/item/melee/baton/loaded=1,\ /obj/item/clothing/mask/gas/sechailer/swat=1,\ /obj/item/gun/energy/e_gun=1,\ @@ -189,7 +189,7 @@ /datum/outfit/ert/engineer/alert/red name = "ERT Engineer - Red Alert" - backpack_contents = list(/obj/item/storage/box/engineer=1,\ + backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\ /obj/item/melee/baton/loaded=1,\ /obj/item/clothing/mask/gas/sechailer/swat=1,\ /obj/item/gun/energy/pulse/pistol/loyalpin=1,\ @@ -260,7 +260,7 @@ name = "Inquisition Commander" r_hand = /obj/item/nullrod/scythe/talking/chainsword suit = /obj/item/clothing/suit/space/hardsuit/ert/paranormal - backpack_contents = list(/obj/item/storage/box/engineer=1, + backpack_contents = list(/obj/item/storage/box/survival/engineer=1, /obj/item/clothing/mask/gas/sechailer=1, /obj/item/gun/energy/e_gun=1) @@ -269,7 +269,7 @@ suit = /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor - backpack_contents = list(/obj/item/storage/box/engineer=1, + backpack_contents = list(/obj/item/storage/box/survival/engineer=1, /obj/item/storage/box/handcuffs=1, /obj/item/clothing/mask/gas/sechailer=1, /obj/item/gun/energy/e_gun/stun=1, @@ -281,7 +281,7 @@ suit = /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor - backpack_contents = list(/obj/item/storage/box/engineer=1, + backpack_contents = list(/obj/item/storage/box/survival/engineer=1, /obj/item/melee/baton/loaded=1, /obj/item/clothing/mask/gas/sechailer=1, /obj/item/gun/energy/e_gun=1, @@ -307,7 +307,7 @@ glasses = /obj/item/clothing/glasses/hud/health back = /obj/item/storage/backpack/cultpack belt = /obj/item/storage/belt/soulstone - backpack_contents = list(/obj/item/storage/box/engineer=1, + backpack_contents = list(/obj/item/storage/box/survival/engineer=1, /obj/item/nullrod=1, /obj/item/clothing/mask/gas/sechailer=1, /obj/item/gun/energy/e_gun=1, @@ -319,7 +319,7 @@ suit = /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor belt = /obj/item/storage/belt/soulstone/full/chappy - backpack_contents = list(/obj/item/storage/box/engineer=1, + backpack_contents = list(/obj/item/storage/box/survival/engineer=1, /obj/item/grenade/chem_grenade/holy=1, /obj/item/nullrod=1, /obj/item/clothing/mask/gas/sechailer=1, diff --git a/code/modules/clothing/outfits/plasmaman.dm b/code/modules/clothing/outfits/plasmaman.dm index bd2c2b612d..5809cb8f50 100644 --- a/code/modules/clothing/outfits/plasmaman.dm +++ b/code/modules/clothing/outfits/plasmaman.dm @@ -71,6 +71,12 @@ head = /obj/item/clothing/head/helmet/space/plasmaman/security/hos uniform = /obj/item/clothing/under/plasmaman/security/hos +/datum/outfit/plasmaman/prisoner + name = "Prisoner Plasmaman" + + head = /obj/item/clothing/head/helmet/space/plasmaman/prisoner + uniform = /obj/item/clothing/under/plasmaman/prisoner + /datum/outfit/plasmaman/cargo name = "Cargo Plasmaman" diff --git a/code/modules/clothing/outfits/vr.dm b/code/modules/clothing/outfits/vr.dm index acf015c845..99fc5d1359 100644 --- a/code/modules/clothing/outfits/vr.dm +++ b/code/modules/clothing/outfits/vr.dm @@ -28,7 +28,7 @@ id = /obj/item/card/id/syndicate/locked_banking belt = /obj/item/gun/ballistic/automatic/pistol l_pocket = /obj/item/paper/fluff/vr/fluke_ops - backpack_contents = list(/obj/item/storage/box/syndie=1,\ + backpack_contents = list(/obj/item/storage/box/survival/syndie=1,\ /obj/item/kitchen/knife/combat/survival) starting_funds = 0 //Should be operating, not shopping. @@ -36,7 +36,7 @@ . = ..() var/key = H.key ? H.key : preference_source ? preference_source.key : null var/obj/item/uplink/U = new /obj/item/uplink/nuclear_restricted(H, key, 80) - H.equip_to_slot_or_del(U, SLOT_IN_BACKPACK) + H.equip_to_slot_or_del(U, ITEM_SLOT_BACKPACK) var/obj/item/implant/weapons_auth/W = new W.implant(H) var/obj/item/implant/explosive/E = new diff --git a/code/modules/clothing/outfits/vv_outfit.dm b/code/modules/clothing/outfits/vv_outfit.dm index b9d9bf0b22..de230b254e 100644 --- a/code/modules/clothing/outfits/vv_outfit.dm +++ b/code/modules/clothing/outfits/vv_outfit.dm @@ -10,35 +10,35 @@ /datum/outfit/varedit/proc/set_equipement_by_slot(slot,item_path) switch(slot) - if(SLOT_W_UNIFORM) + if(ITEM_SLOT_ICLOTHING) uniform = item_path - if(SLOT_BACK) + if(ITEM_SLOT_BACK) back = item_path - if(SLOT_WEAR_SUIT) + if(ITEM_SLOT_OCLOTHING) suit = item_path - if(SLOT_BELT) + if(ITEM_SLOT_BELT) belt = item_path - if(SLOT_GLOVES) + if(ITEM_SLOT_GLOVES) gloves = item_path - if(SLOT_SHOES) + if(ITEM_SLOT_FEET) shoes = item_path - if(SLOT_HEAD) + if(ITEM_SLOT_HEAD) head = item_path - if(SLOT_WEAR_MASK) + if(ITEM_SLOT_MASK) mask = item_path - if(SLOT_NECK) + if(ITEM_SLOT_NECK) neck = item_path - if(SLOT_EARS) + if(ITEM_SLOT_EARS) ears = item_path - if(SLOT_GLASSES) + if(ITEM_SLOT_EYES) glasses = item_path - if(SLOT_WEAR_ID) + if(ITEM_SLOT_ID) id = item_path - if(SLOT_S_STORE) + if(ITEM_SLOT_SUITSTORE) suit_store = item_path - if(SLOT_L_STORE) + if(ITEM_SLOT_LPOCKET) l_pocket = item_path - if(SLOT_R_STORE) + if(ITEM_SLOT_RPOCKET) r_pocket = item_path @@ -68,7 +68,7 @@ //Copy equipment var/list/result = list() - var/list/slots_to_check = list(SLOT_W_UNIFORM,SLOT_BACK,SLOT_WEAR_SUIT,SLOT_BELT,SLOT_GLOVES,SLOT_SHOES,SLOT_HEAD,SLOT_WEAR_MASK,SLOT_NECK,SLOT_EARS,SLOT_GLASSES,SLOT_WEAR_ID,SLOT_S_STORE,SLOT_L_STORE,SLOT_R_STORE) + var/list/slots_to_check = list(ITEM_SLOT_ICLOTHING,ITEM_SLOT_BACK,ITEM_SLOT_OCLOTHING,ITEM_SLOT_BELT,ITEM_SLOT_GLOVES,ITEM_SLOT_FEET,ITEM_SLOT_HEAD,ITEM_SLOT_MASK,ITEM_SLOT_NECK,ITEM_SLOT_EARS,ITEM_SLOT_EYES,ITEM_SLOT_ID,ITEM_SLOT_SUITSTORE,ITEM_SLOT_LPOCKET,ITEM_SLOT_RPOCKET) for(var/s in slots_to_check) var/obj/item/I = get_item_by_slot(s) var/vedits = collect_vv(I) @@ -79,7 +79,7 @@ //Copy access O.stored_access = list() - var/obj/item/id_slot = get_item_by_slot(SLOT_WEAR_ID) + var/obj/item/id_slot = get_item_by_slot(ITEM_SLOT_ID) if(id_slot) O.stored_access |= id_slot.GetAccess() //Copy hands @@ -98,7 +98,7 @@ result["RHAND"] = vedits O.vv_values = result //Copy backpack contents if exist. - var/obj/item/backpack = get_item_by_slot(SLOT_BACK) + var/obj/item/backpack = get_item_by_slot(ITEM_SLOT_BACK) if(istype(backpack) && SEND_SIGNAL(backpack, COMSIG_CONTAINS_STORAGE)) var/list/bp_stuff = list() var/list/typecounts = list() @@ -136,7 +136,7 @@ for(var/vname in edits) I.vv_edit_var(vname,edits[vname]) //Apply access - var/obj/item/id_slot = H.get_item_by_slot(SLOT_WEAR_ID) + var/obj/item/id_slot = H.get_item_by_slot(ITEM_SLOT_ID) if(id_slot) var/obj/item/card/id/card = id_slot.GetID() if(istype(card)) diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index 7a1e6b14f3..606c361ab0 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -19,6 +19,7 @@ var/last_bloodtype = "" //used to track the last bloodtype to have graced these shoes; makes for better performing footprint shenanigans var/last_blood_DNA = "" //same as last one var/last_blood_color = "" + var/last_blood_blend = null ///Whether these shoes have laces that can be tied/untied var/can_be_tied = TRUE @@ -68,6 +69,7 @@ last_bloodtype = blood_dna[blood_dna[blood_dna.len]]//trust me this works last_blood_DNA = blood_dna[blood_dna.len] last_blood_color = blood_dna["color"] + last_blood_blend = blood_dna["blendmode"] /obj/item/clothing/shoes/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE) . = ..() @@ -82,12 +84,12 @@ . += mutable_appearance('icons/effects/item_damage.dmi', "damagedshoe") if(bloody) var/file2use = style_flags & STYLE_DIGITIGRADE ? 'icons/mob/clothing/feet_digi.dmi' : 'icons/effects/blood.dmi' - . += mutable_appearance(file2use, "shoeblood", color = blood_DNA_to_color()) + . += mutable_appearance(file2use, "shoeblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) /obj/item/clothing/shoes/equipped(mob/user, slot) . = ..() - if(offset && slot_flags & slotdefine2slotbit(slot)) + if(offset && (slot_flags & slot)) user.pixel_y += offset worn_y_dimension -= (offset * 2) user.update_inv_shoes() @@ -102,7 +104,7 @@ worn_y_dimension = world.icon_size /obj/item/clothing/shoes/dropped(mob/user) - if(our_alert && (our_alert.mob_viewer == user)) + if(our_alert && (our_alert.owner == user)) user.clear_alert("shoealert") if(offset && equipped_before_drop) restore_offsets(user) @@ -178,7 +180,7 @@ return user.visible_message("[user] begins [tied ? "unknotting" : "tying"] the laces of [user.p_their()] [src.name].", "You begin [tied ? "unknotting" : "tying"] the laces of your [src.name]...") - if(do_after(user, lace_time, needhand=TRUE, target=our_guy, extra_checks=CALLBACK(src, .proc/still_shoed, our_guy))) + if(do_after(user, lace_time, our_guy, extra_checks = CALLBACK(src, .proc/still_shoed, our_guy))) to_chat(user, "You [tied ? "unknot" : "tie"] the laces of your [src.name].") if(tied == SHOES_UNTIED) adjust_laces(SHOES_TIED, user) @@ -202,7 +204,7 @@ if(HAS_TRAIT(user, TRAIT_CLUMSY)) // based clowns trained their whole lives for this mod_time *= 0.75 - if(do_after(user, mod_time, needhand=TRUE, target=our_guy, extra_checks=CALLBACK(src, .proc/still_shoed, our_guy))) + if(do_after(user, mod_time, our_guy, extra_checks = CALLBACK(src, .proc/still_shoed, our_guy))) to_chat(user, "You [tied ? "untie" : "knot"] the laces on [loc]'s [src.name].") if(tied == SHOES_UNTIED) adjust_laces(SHOES_KNOTTED, user) @@ -283,6 +285,6 @@ to_chat(user, "You begin [tied ? "untying" : "tying"] the laces on [src]...") - if(do_after(user, lace_time, needhand=TRUE, target=src,extra_checks=CALLBACK(src, .proc/still_shoed, user))) + if(do_after(user, lace_time, src, extra_checks = CALLBACK(src, .proc/still_shoed, user))) to_chat(user, "You [tied ? "untie" : "tie"] the laces on [src].") adjust_laces(tied ? SHOES_TIED : SHOES_UNTIED, user) diff --git a/code/modules/clothing/shoes/bananashoes.dm b/code/modules/clothing/shoes/bananashoes.dm index fe392881c6..c5949406f7 100644 --- a/code/modules/clothing/shoes/bananashoes.dm +++ b/code/modules/clothing/shoes/bananashoes.dm @@ -8,7 +8,7 @@ var/on = FALSE var/always_noslip = FALSE -/obj/item/clothing/shoes/clown_shoes/banana_shoes/Initialize() +/obj/item/clothing/shoes/clown_shoes/banana_shoes/Initialize(mapload) . = ..() if(always_noslip) clothing_flags |= NOSLIP diff --git a/code/modules/clothing/shoes/cluwne.dm b/code/modules/clothing/shoes/cluwne.dm index fbe1ba624b..ec135014e9 100644 --- a/code/modules/clothing/shoes/cluwne.dm +++ b/code/modules/clothing/shoes/cluwne.dm @@ -7,7 +7,7 @@ item_flags = DROPDEL var/footstep = 1 -/obj/item/clothing/shoes/clown_shoes/cluwne/Initialize() +/obj/item/clothing/shoes/clown_shoes/cluwne/Initialize(mapload) .=..() ADD_TRAIT(src, TRAIT_NODROP, CLOTHING_TRAIT) ADD_TRAIT(src, CURSED_ITEM_TRAIT, CLOTHING_TRAIT) @@ -23,7 +23,7 @@ . = ..() if(!ishuman(user)) return - if(slot == SLOT_SHOES) + if(slot == ITEM_SLOT_FEET) var/mob/living/carbon/human/H = user H.dna.add_mutation(CLUWNEMUT) return diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index 773b1ac361..726b284632 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -56,7 +56,7 @@ /obj/item/clothing/shoes/magboots/advance/debug -/obj/item/clothing/shoes/magboots/advance/debug/Initialize() +/obj/item/clothing/shoes/magboots/advance/debug/Initialize(mapload) . = ..() var/mob/living/L = loc if(istype(L)) @@ -96,7 +96,7 @@ /obj/item/clothing/shoes/magboots/crushing/equipped(mob/user,slot) . = ..() - if (slot == SLOT_SHOES && magpulse) + if (slot == ITEM_SLOT_FEET && magpulse) RegisterSignal(user, COMSIG_MOVABLE_MOVED,.proc/crush) /obj/item/clothing/shoes/magboots/crushing/dropped(mob/user) diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 6858de59df..08a77b9b2b 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -12,7 +12,7 @@ item_state = "jackboots" lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' - armor = list("melee" = 25, "bullet" = 25, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 10, "rad" = 0, "fire" = 70, "acid" = 50) + armor = list(MELEE = 25, BULLET = 25, LASER = 25, ENERGY = 25, BOMB = 50, BIO = 10, RAD = 0, FIRE = 70, ACID = 50) strip_delay = 70 resistance_flags = NONE permeability_coefficient = 0.05 //Thick soles, and covers the ankle @@ -28,7 +28,7 @@ /obj/item/clothing/shoes/combat/sneakboots/equipped(mob/user, slot) . = ..() - if(slot == SLOT_SHOES) + if(slot == ITEM_SLOT_FEET) ADD_TRAIT(user, TRAIT_SILENT_STEP, SHOES_TRAIT) /obj/item/clothing/shoes/combat/sneakboots/dropped(mob/user) @@ -40,7 +40,7 @@ desc = "High speed, no drag combat boots." permeability_coefficient = 0.01 clothing_flags = NOSLIP - armor = list("melee" = 40, "bullet" = 30, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 30, "rad" = 30, "fire" = 90, "acid" = 50) + armor = list(MELEE = 40, BULLET = 30, LASER = 25, ENERGY = 25, BOMB = 50, BIO = 30, RAD = 30, FIRE = 90, ACID = 50) /obj/item/clothing/shoes/sandal desc = "A pair of rather plain wooden sandals." @@ -73,7 +73,7 @@ strip_delay = 50 equip_delay_other = 50 resistance_flags = NONE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 40, "acid" = 75) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 40, ACID = 75) custom_price = PRICE_ABOVE_EXPENSIVE can_be_tied = FALSE @@ -106,13 +106,13 @@ var/datum/component/waddle var/enabled_waddle = TRUE -/obj/item/clothing/shoes/clown_shoes/Initialize() +/obj/item/clothing/shoes/clown_shoes/Initialize(mapload) . = ..() AddComponent(/datum/component/squeak, list('sound/effects/clownstep1.ogg'=1,'sound/effects/clownstep2.ogg'=1), 50) /obj/item/clothing/shoes/clown_shoes/equipped(mob/user, slot) . = ..() - if(slot == SLOT_SHOES) + if(slot == ITEM_SLOT_FEET) if(enabled_waddle) waddle = user.AddComponent(/datum/component/waddling) if(user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY)) @@ -144,7 +144,7 @@ /obj/item/clothing/shoes/jackboots name = "jackboots" - desc = "Nanotrasen-issue Security combat boots for combat scenarios or combat situations. All combat, all the time." + desc = "Nanotrasen-brand jackboots for all your jackboots-related needs. From genuine combat to tacticool LARPing, satisfaction is guaranteed." icon_state = "jackboots" lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' @@ -155,6 +155,11 @@ pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes lace_time = 12 SECONDS +/obj/item/clothing/shoes/jackboots/sec + name = "security jackboots" + desc = "Nanotrasen-issue Security combat boots for combat scenarios or combat situations. All combat, all the time." + icon_state = "jackboots_sec" + /obj/item/clothing/shoes/jackboots/fast slowdown = -1 @@ -213,6 +218,7 @@ heat_protection = FEET|LEGS max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF + lace_time = 10 SECONDS /obj/item/clothing/shoes/cult name = "\improper Nar'Sien invoker boots" @@ -231,7 +237,7 @@ /obj/item/clothing/shoes/cult/alt/ghost item_flags = DROPDEL -/obj/item/clothing/shoes/cult/alt/ghost/Initialize() +/obj/item/clothing/shoes/cult/alt/ghost/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) @@ -267,9 +273,17 @@ desc = "A specialized pair of combat boots with a built-in propulsion system for rapid foward movement." icon_state = "jetboots" resistance_flags = FIRE_PROOF + cold_protection = FEET|LEGS + min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT + heat_protection = FEET|LEGS + max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes actions_types = list(/datum/action/item_action/bhop) permeability_coefficient = 0.05 + unique_reskin = list( + "Explorer" = list("icon_state" = "miningjet"), + "Jackboot" = list("icon_state" = "jetboots") + ) var/jumpdistance = 5 //-1 from to see the actual distance, e.g 4 goes over 3 tiles var/jumpspeed = 3 var/recharging_rate = 60 //default 6 seconds between each dash @@ -315,7 +329,7 @@ icon_state = "clockwork_treads" lace_time = 8 SECONDS -/obj/item/clothing/shoes/bronze/Initialize() +/obj/item/clothing/shoes/bronze/Initialize(mapload) . = ..() AddComponent(/datum/component/squeak, list('sound/machines/clockcult/integration_cog_install.ogg' = 1, 'sound/magic/clockwork/fellowship_armory.ogg' = 1), 50) @@ -327,14 +341,14 @@ var/wheelToggle = FALSE //False means wheels are not popped out var/obj/vehicle/ridden/scooter/wheelys/W -/obj/item/clothing/shoes/wheelys/Initialize() +/obj/item/clothing/shoes/wheelys/Initialize(mapload) . = ..() W = new /obj/vehicle/ridden/scooter/wheelys(null) /obj/item/clothing/shoes/wheelys/ui_action_click(mob/user, action) if(!isliving(user)) return - if(!istype(user.get_item_by_slot(SLOT_SHOES), /obj/item/clothing/shoes/wheelys)) + if(!istype(user.get_item_by_slot(ITEM_SLOT_FEET), /obj/item/clothing/shoes/wheelys)) to_chat(user, "You must be wearing the wheely-heels to use them!") return if(!(W.is_occupant(user))) @@ -417,12 +431,16 @@ name = "cowboy boots" desc = "A standard pair of brown cowboy boots." icon_state = "cowboyboots" + item_state = "cowboyboots" + permeability_coefficient = 0.05 //these are quite tall + pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes can_be_tied = FALSE /obj/item/clothing/shoes/cowboyboots/black name = "black cowboy boots" desc = "A pair of black cowboy boots, pretty easy to scuff up." icon_state = "cowboyboots_black" + item_state = "cowboyboots_black" /obj/item/clothing/shoes/wallwalkers name = "wall walking boots" @@ -450,7 +468,7 @@ /obj/item/clothing/shoes/wallwalkers/equipped(mob/user,slot) . = ..() - if(slot == SLOT_SHOES) + if(slot == ITEM_SLOT_FEET) RegisterSignal(user, COMSIG_MOB_CLIENT_MOVE,.proc/intercept_user_move) /obj/item/clothing/shoes/wallwalkers/dropped(mob/user) @@ -541,3 +559,59 @@ desc = "They got me for my foams!" icon_state = "SwagShoes" item_state = "SwagShoes" + +/obj/item/clothing/shoes/phantom + name = "phantom shoes" + desc = "Excellent for when you need to do cool flashy flips." + icon_state = "phantom_shoes" + item_state = "phantom_shoes" + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/shoes/saints + name = "saints sneakers" + desc = "Officially branded Saints sneakers. Incredibly valuable!" + icon_state = "saints_shoes" + item_state = "saints_shoes" + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/shoes/morningstar + name = "morningstar boots" + desc = "The most expensive boots on this station. Wearing them dropped the value by about 50%." + icon_state = "morningstar_shoes" + item_state = "morningstar_shoes" + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/shoes/deckers + name = "deckers rollerskates" + desc = "t3h c00L3st sh03z j00'LL 3v3r f1nd." + icon_state = "decker_shoes" + item_state = "decker_shoes" + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/shoes/sybil_slickers + name = "sybil slickers shoes" + desc = "FOOTBALL! YEAH!" + icon_state = "sneakers_blue" + item_state = "sneakers_blue" + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/shoes/basil_boys + name = "basil boys shoes" + desc = "FOOTBALL! YEAH!" + icon_state = "sneakers_red" + item_state = "sneakers_red" + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/shoes/yakuza + name = "tojo clan shoes" + desc = "Steel-toed and intimidating." + icon_state = "MajimaShoes" + item_state = "MajimaShoes_worn" + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/shoes/jackbros + name = "frosty boots" + desc = "For when you're stepping on up to the plate." + icon_state = "JackFrostShoes" + item_state = "JackFrostShoes_worn" + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON diff --git a/code/modules/clothing/shoes/taeclowndo.dm b/code/modules/clothing/shoes/taeclowndo.dm index c0f8a77543..82f467d8b1 100644 --- a/code/modules/clothing/shoes/taeclowndo.dm +++ b/code/modules/clothing/shoes/taeclowndo.dm @@ -15,7 +15,7 @@ var/mob/living/carbon/human/H = user if(!(HAS_TRAIT(H, TRAIT_CLUMSY)) && !(H.mind && HAS_TRAIT(H.mind, TRAIT_CLOWN_MENTALITY))) return - if(slot == SLOT_SHOES) + if(slot == ITEM_SLOT_FEET) spells = new for(var/spell in spelltypes) var/obj/effect/proc_holder/spell/S = new spell @@ -29,7 +29,7 @@ if(!ishuman(user)) return var/mob/living/carbon/human/H = user - if(H.get_item_by_slot(SLOT_SHOES) == src) + if(H.get_item_by_slot(ITEM_SLOT_FEET) == src) for(var/spell in spells) var/obj/effect/proc_holder/spell/S = spell H.mind.spell_list.Remove(S) diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm index cba27845f1..dbcda218a7 100644 --- a/code/modules/clothing/spacesuits/_spacesuits.dm +++ b/code/modules/clothing/spacesuits/_spacesuits.dm @@ -7,7 +7,7 @@ clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS item_state = "spaceold" permeability_coefficient = 0.01 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 50, "fire" = 80, "acid" = 70, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 100, RAD = 50, FIRE = 80, ACID = 70, WOUND = 5) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT dynamic_hair_suffix = "" dynamic_fhair_suffix = "" @@ -36,7 +36,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS allowed = list(/obj/item/flashlight, /obj/item/tank/internals) slowdown = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 50, "fire" = 80, "acid" = 70, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 100, RAD = 50, FIRE = 80, ACID = 70, WOUND = 5) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAUR cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index 6642731d8b..5ec0fad2e6 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -4,7 +4,7 @@ icon_state = "chronohelmet" item_state = "chronohelmet" slowdown = 1 - armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 60, "bomb" = 30, "bio" = 90, "rad" = 90, "fire" = 100, "acid" = 100, "wound" = 80) + armor = list(MELEE = 60, BULLET = 60, LASER = 60, ENERGY = 60, BOMB = 30, BIO = 90, RAD = 90, FIRE = 100, ACID = 100, WOUND = 80) resistance_flags = FIRE_PROOF | ACID_PROOF var/obj/item/clothing/suit/space/chronos/suit = null @@ -19,7 +19,7 @@ icon_state = "chronosuit" item_state = "chronosuit" actions_types = list(/datum/action/item_action/toggle) - armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 60, "bomb" = 30, "bio" = 90, "rad" = 90, "fire" = 100, "acid" = 1000, "wound" = 80) + armor = list(MELEE = 60, BULLET = 60, LASER = 60, ENERGY = 60, BOMB = 30, BIO = 90, RAD = 90, FIRE = 100, ACID = 1000, WOUND = 80) resistance_flags = FIRE_PROOF | ACID_PROOF mutantrace_variation = STYLE_DIGITIGRADE var/list/chronosafe_items = list(/obj/item/chrono_eraser, /obj/item/gun/energy/chrono_gun) @@ -107,7 +107,7 @@ teleport_now.UpdateButtonIcon() - var/list/nonsafe_slots = list(SLOT_BELT, SLOT_BACK) + var/list/nonsafe_slots = list(ITEM_SLOT_BELT, ITEM_SLOT_BACK) var/list/exposed = list() for(var/slot in nonsafe_slots) var/obj/item/slot_item = user.get_item_by_slot(slot) diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 4af9e7387d..c946002fa2 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -5,7 +5,7 @@ icon_state = "hardsuit0-engineering" item_state = "eng_helm" max_integrity = 300 - armor = list("melee" = 10, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 50, "acid" = 75, "wound" = 10) + armor = list(MELEE = 10, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 50, ACID = 75, WOUND = 10) var/basestate = "hardsuit" var/brightness_on = 4 //luminosity when on var/on = FALSE @@ -18,14 +18,18 @@ var/grace_count = 0 var/datum/looping_sound/geiger/soundloop -/obj/item/clothing/head/helmet/space/hardsuit/Initialize() +/obj/item/clothing/head/helmet/space/hardsuit/Initialize(mapload) . = ..() - soundloop = new(list(), FALSE, TRUE) + soundloop = new(src, FALSE, TRUE) soundloop.volume = 5 START_PROCESSING(SSobj, src) /obj/item/clothing/head/helmet/space/hardsuit/Destroy() . = ..() + if(!QDELETED(suit)) + qdel(suit) + suit = null + QDEL_NULL(soundloop) STOP_PROCESSING(SSobj, src) /obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user) @@ -46,12 +50,12 @@ soundloop.stop(user) /obj/item/clothing/head/helmet/space/hardsuit/item_action_slot_check(slot, mob/user, datum/action/A) - if(slot == SLOT_HEAD) + if(slot == ITEM_SLOT_HEAD) return 1 /obj/item/clothing/head/helmet/space/hardsuit/equipped(mob/user, slot) ..() - if(slot != SLOT_HEAD) + if(slot != ITEM_SLOT_HEAD) if(suit) suit.RemoveHelmet() soundloop.stop(user) @@ -94,7 +98,7 @@ icon_state = "hardsuit-engineering" item_state = "eng_hardsuit" max_integrity = 300 - armor = list("melee" = 10, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 50, "acid" = 75, "wound" = 10) + armor = list(MELEE = 10, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 50, ACID = 75, WOUND = 10) allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser) siemens_coefficient = 0 var/obj/item/clothing/head/helmet/space/hardsuit/helmet @@ -104,7 +108,7 @@ var/hardsuit_type -/obj/item/clothing/suit/space/hardsuit/Initialize() +/obj/item/clothing/suit/space/hardsuit/Initialize(mapload) if(jetpack && ispath(jetpack)) jetpack = new jetpack(src) return ..() @@ -114,7 +118,7 @@ if(jetpack) to_chat(user, "[src] already has a jetpack installed.") return - if(src == user.get_item_by_slot(SLOT_WEAR_SUIT)) //Make sure the player is not wearing the suit before applying the upgrade. + if(src == user.get_item_by_slot(ITEM_SLOT_OCLOTHING)) //Make sure the player is not wearing the suit before applying the upgrade. to_chat(user, "You cannot install the upgrade to [src] while wearing it.") return @@ -126,7 +130,7 @@ if(!jetpack) to_chat(user, "[src] has no jetpack installed.") return - if(src == user.get_item_by_slot(SLOT_WEAR_SUIT)) + if(src == user.get_item_by_slot(ITEM_SLOT_OCLOTHING)) to_chat(user, "You cannot remove the jetpack from [src] while wearing it.") return @@ -141,7 +145,7 @@ /obj/item/clothing/suit/space/hardsuit/equipped(mob/user, slot) ..() if(jetpack) - if(slot == SLOT_WEAR_SUIT) + if(slot == ITEM_SLOT_OCLOTHING) for(var/X in jetpack.actions) var/datum/action/A = X A.Grant(user) @@ -154,7 +158,7 @@ A.Remove(user) /obj/item/clothing/suit/space/hardsuit/item_action_slot_check(slot, mob/user, datum/action/A) - if(slot == SLOT_WEAR_SUIT) //we only give the mob the ability to toggle the helmet if he's wearing the hardsuit. + if(slot == ITEM_SLOT_OCLOTHING) //we only give the mob the ability to toggle the helmet if he's wearing the hardsuit. return 1 //Engineering @@ -163,7 +167,7 @@ desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding." icon_state = "hardsuit0-engineering" item_state = "eng_helm" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 100, ACID = 75, WOUND = 10) hardsuit_type = "engineering" resistance_flags = FIRE_PROOF @@ -172,7 +176,7 @@ desc = "A special suit that protects against hazardous, low pressure environments. Has radiation shielding." icon_state = "hardsuit-engineering" item_state = "eng_hardsuit" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 100, ACID = 75, WOUND = 10) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine resistance_flags = FIRE_PROOF mutantrace_variation = STYLE_DIGITIGRADE|STYLE_ALL_TAURIC @@ -184,7 +188,7 @@ icon_state = "hardsuit0-atmospherics" item_state = "atmo_helm" hardsuit_type = "atmospherics" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 25, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 25, FIRE = 100, ACID = 75, WOUND = 10) heat_protection = HEAD //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -193,7 +197,7 @@ desc = "A special suit that protects against hazardous, low pressure environments. Has thermal shielding." icon_state = "hardsuit-atmospherics" item_state = "atmo_hardsuit" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 25, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 25, FIRE = 100, ACID = 75, WOUND = 10) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/atmos @@ -205,7 +209,7 @@ icon_state = "hardsuit0-white" item_state = "ce_helm" hardsuit_type = "white" - armor = list("melee" = 40, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 90, "wound" = 10) + armor = list(MELEE = 40, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 90, WOUND = 10) heat_protection = HEAD max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -214,7 +218,7 @@ name = "advanced hardsuit" desc = "An advanced suit that protects against hazardous, low pressure environments. Shines with a high polish." item_state = "ce_hardsuit" - armor = list("melee" = 40, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 90, "wound" = 10) + armor = list(MELEE = 40, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 90, WOUND = 10) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/elite @@ -230,30 +234,61 @@ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF heat_protection = HEAD - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 75, "wound" = 15) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 75, WOUND = 15) brightness_on = 7 allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator) -/obj/item/clothing/head/helmet/space/hardsuit/mining/Initialize() +/obj/item/clothing/head/helmet/space/hardsuit/mining/Initialize(mapload) . = ..() AddComponent(/datum/component/armor_plate) + RegisterSignal(src, COMSIG_ARMOR_PLATED, .proc/upgrade_icon) + +/obj/item/clothing/head/helmet/space/hardsuit/mining/proc/upgrade_icon(datum/source, amount, maxamount) + SIGNAL_HANDLER + + if(amount) + name = "reinforced [initial(name)]" + hardsuit_type = "mining_goliath" + if(amount == maxamount) + hardsuit_type = "mining_goliath_full" + icon_state = "hardsuit[on]-[hardsuit_type]" + if(ishuman(loc)) + var/mob/living/carbon/human/wearer = loc + if(wearer.head == src) + wearer.update_inv_head() /obj/item/clothing/suit/space/hardsuit/mining icon_state = "hardsuit-mining" name = "mining hardsuit" desc = "A special suit that protects against hazardous, low pressure environments. Has reinforced plating for wildlife encounters." item_state = "mining_hardsuit" + hardsuit_type = "mining" max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 75, "wound" = 15) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 75, WOUND = 15) allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/bag/ore, /obj/item/pickaxe) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/mining heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS mutantrace_variation = STYLE_DIGITIGRADE|STYLE_ALL_TAURIC -/obj/item/clothing/suit/space/hardsuit/mining/Initialize() +/obj/item/clothing/suit/space/hardsuit/mining/Initialize(mapload) . = ..() AddComponent(/datum/component/armor_plate) + RegisterSignal(src, COMSIG_ARMOR_PLATED, .proc/upgrade_icon) + +/obj/item/clothing/suit/space/hardsuit/mining/proc/upgrade_icon(datum/source, amount, maxamount) + SIGNAL_HANDLER + + if(amount) + name = "reinforced [initial(name)]" + hardsuit_type = "mining_goliath" + if(amount == maxamount) + hardsuit_type = "mining_goliath_full" + icon_state = "hardsuit-[hardsuit_type]" + if(ishuman(loc)) + var/mob/living/carbon/human/wearer = loc + if(wearer.wear_suit == src) + wearer.update_inv_wear_suit() //Syndicate hardsuit /obj/item/clothing/head/helmet/space/hardsuit/syndi @@ -263,7 +298,7 @@ icon_state = "hardsuit1-syndi" item_state = "syndie_helm" hardsuit_type = "syndi" - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90, "wound" = 25) + armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 15, BOMB = 35, BIO = 100, RAD = 50, FIRE = 50, ACID = 90, WOUND = 25) on = FALSE var/obj/item/clothing/suit/space/hardsuit/syndi/linkedsuit = null actions_types = list(/datum/action/item_action/toggle_helmet_mode) @@ -273,7 +308,7 @@ /obj/item/clothing/head/helmet/space/hardsuit/syndi/update_icon_state() icon_state = "hardsuit[on]-[hardsuit_type]" -/obj/item/clothing/head/helmet/space/hardsuit/syndi/Initialize() +/obj/item/clothing/head/helmet/space/hardsuit/syndi/Initialize(mapload) . = ..() if(istype(loc, /obj/item/clothing/suit/space/hardsuit/syndi)) linkedsuit = loc @@ -341,7 +376,7 @@ item_state = "syndie_hardsuit" hardsuit_type = "syndi" w_class = WEIGHT_CLASS_NORMAL - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90, "wound" = 25) + armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 15, BOMB = 35, BIO = 100, RAD = 50, FIRE = 50, ACID = 90, WOUND = 25) allowed = list(/obj/item/gun, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi jetpack = /obj/item/tank/jetpack/suit @@ -354,14 +389,14 @@ alt_desc = "An elite version of the syndicate helmet, with improved armour and fireproofing. It is in combat mode. Property of Gorlex Marauders." icon_state = "hardsuit0-syndielite" hardsuit_type = "syndielite" - armor = list("melee" = 60, "bullet" = 60, "laser" = 50, "energy" = 25, "bomb" = 55, "bio" = 100, "rad" = 70, "fire" = 100, "acid" = 100, "wound" = 25) + armor = list(MELEE = 60, BULLET = 60, LASER = 50, ENERGY = 25, BOMB = 55, BIO = 100, RAD = 70, FIRE = 100, ACID = 100, WOUND = 25) heat_protection = HEAD max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/debug -/obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/debug/Initialize() +/obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/debug/Initialize(mapload) . = ..() soundloop.volume = 0 @@ -372,7 +407,7 @@ icon_state = "hardsuit0-syndielite" hardsuit_type = "syndielite" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite - armor = list("melee" = 60, "bullet" = 60, "laser" = 50, "energy" = 25, "bomb" = 55, "bio" = 100, "rad" = 70, "fire" = 100, "acid" = 100, "wound" = 25) + armor = list(MELEE = 60, BULLET = 60, LASER = 50, ENERGY = 25, BOMB = 55, BIO = 100, RAD = 70, FIRE = 100, ACID = 100, WOUND = 25) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF @@ -412,7 +447,7 @@ item_state = "wiz_helm" hardsuit_type = "wiz" resistance_flags = FIRE_PROOF | ACID_PROOF //No longer shall our kind be foiled by lone chemists with spray bottles! - armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 40, BULLET = 40, LASER = 40, ENERGY = 20, BOMB = 35, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30) heat_protection = HEAD //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -427,7 +462,7 @@ item_state = "wiz_hardsuit" w_class = WEIGHT_CLASS_NORMAL resistance_flags = FIRE_PROOF | ACID_PROOF - armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 40, BULLET = 40, LASER = 40, ENERGY = 20, BOMB = 35, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30) allowed = list(/obj/item/teleportation_scroll, /obj/item/tank/internals) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -447,13 +482,13 @@ item_state = "medical_helm" hardsuit_type = "medical" flash_protect = 0 - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 60, FIRE = 60, ACID = 75, WOUND = 10) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS /obj/item/clothing/head/helmet/space/hardsuit/medical/equipped(mob/living/carbon/human/user, slot) ..() - if (slot == SLOT_HEAD) + if (slot == ITEM_SLOT_HEAD) var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] DHUD.add_hud_to(user) @@ -470,7 +505,7 @@ item_state = "medical_hardsuit" slowdown = 0.8 allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/firstaid, /obj/item/healthanalyzer, /obj/item/stack/medical) - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 60, FIRE = 60, ACID = 75, WOUND = 10) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/medical mutantrace_variation = STYLE_DIGITIGRADE|STYLE_ALL_TAURIC @@ -482,18 +517,18 @@ hardsuit_type = "rd" resistance_flags = ACID_PROOF | FIRE_PROOF max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80, "wound" = 15) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 100, BIO = 100, RAD = 60, FIRE = 60, ACID = 80, WOUND = 15) var/obj/machinery/doppler_array/integrated/bomb_radar clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/toggle_research_scanner) -/obj/item/clothing/head/helmet/space/hardsuit/rd/Initialize() +/obj/item/clothing/head/helmet/space/hardsuit/rd/Initialize(mapload) . = ..() bomb_radar = new /obj/machinery/doppler_array/integrated(src) /obj/item/clothing/head/helmet/space/hardsuit/rd/equipped(mob/living/carbon/human/user, slot) ..() - if (slot == SLOT_HEAD) + if (slot == ITEM_SLOT_HEAD) var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC] DHUD.add_hud_to(user) @@ -512,7 +547,7 @@ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT //Same as an emergency firesuit. Not ideal for extended exposure. allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/gun/energy/wormhole_projector, /obj/item/hand_tele, /obj/item/aicard) - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80, "wound" = 15) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 100, BIO = 100, RAD = 60, FIRE = 60, ACID = 80, WOUND = 15) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/rd //Security hardsuit @@ -522,18 +557,18 @@ icon_state = "hardsuit0-sec" item_state = "sec_helm" hardsuit_type = "sec" - armor = list("melee" = 35, "bullet" = 15, "laser" = 30,"energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75, "wound" = 20) + armor = list(MELEE = 35, BULLET = 15, LASER = 30,ENERGY = 10, BOMB = 10, BIO = 100, RAD = 50, FIRE = 75, ACID = 75, WOUND = 20) /obj/item/clothing/suit/space/hardsuit/security icon_state = "hardsuit-sec" name = "security hardsuit" desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor." item_state = "sec_hardsuit" - armor = list("melee" = 35, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75, "wound" = 20) + armor = list(MELEE = 35, BULLET = 15, LASER = 30, ENERGY = 10, BOMB = 10, BIO = 100, RAD = 50, FIRE = 75, ACID = 75, WOUND = 20) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security mutantrace_variation = STYLE_DIGITIGRADE|STYLE_ALL_TAURIC -/obj/item/clothing/suit/space/hardsuit/security/Initialize() +/obj/item/clothing/suit/space/hardsuit/security/Initialize(mapload) . = ..() allowed = GLOB.security_hardsuit_allowed @@ -543,13 +578,13 @@ desc = "A special bulky helmet designed for work in a hazardous, low pressure environment. Has an additional layer of armor." icon_state = "hardsuit0-hos" hardsuit_type = "hos" - armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95, "wound" = 25) + armor = list(MELEE = 45, BULLET = 25, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 100, RAD = 50, FIRE = 95, ACID = 95, WOUND = 25) /obj/item/clothing/suit/space/hardsuit/security/hos icon_state = "hardsuit-hos" name = "head of security's hardsuit" desc = "A special bulky suit that protects against hazardous, low pressure environments. Has an additional layer of armor." - armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95, "wound" = 25) + armor = list(MELEE = 45, BULLET = 25, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 100, RAD = 50, FIRE = 95, ACID = 95, WOUND = 25) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/hos jetpack = /obj/item/tank/jetpack/suit @@ -559,7 +594,7 @@ icon_state = "capspace" item_state = "capspacehelmet" desc = "A tactical SWAT helmet MK.II boasting better protection and a horrible fashion sense." - armor = list("melee" = 40, "bullet" = 50, "laser" = 50, "energy" = 25, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 15) + armor = list(MELEE = 40, BULLET = 50, LASER = 50, ENERGY = 25, BOMB = 50, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 15) resistance_flags = FIRE_PROOF | ACID_PROOF flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR //we want to see the mask heat_protection = HEAD @@ -574,13 +609,13 @@ desc = "A MK.II SWAT suit with streamlined joints and armor made out of superior materials, insulated against intense heat. The most advanced tactical armor available Usually reserved for heavy hitter corporate security, this one has a regal finish in Nanotrasen company colors. Better not let the assistants get a hold of it." icon_state = "caparmor" item_state = "capspacesuit" - armor = list("melee" = 40, "bullet" = 50, "laser" = 50, "energy" = 25, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 15) + armor = list(MELEE = 40, BULLET = 50, LASER = 50, ENERGY = 25, BOMB = 50, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 15) resistance_flags = FIRE_PROOF | ACID_PROOF heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT //this needed to be added a long fucking time ago helmettype = /obj/item/clothing/head/helmet/space/hardsuit/captain -/obj/item/clothing/suit/space/hardsuit/captain/Initialize() +/obj/item/clothing/suit/space/hardsuit/captain/Initialize(mapload) . = ..() allowed = GLOB.security_hardsuit_allowed @@ -590,7 +625,7 @@ desc = "A special helmet designed for work in a hazardous, low-humor environment. Has radiation shielding." icon_state = "hardsuit0-clown" item_state = "hardsuit0-clown" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 30, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 60, ACID = 30, WOUND = 10) hardsuit_type = "clown" /obj/item/clothing/suit/space/hardsuit/clown @@ -598,11 +633,11 @@ desc = "A special suit that protects against hazardous, low humor environments. Has radiation shielding. Only a true clown can wear it." icon_state = "hardsuit-clown" item_state = "clown_hardsuit" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 30, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 60, ACID = 30, WOUND = 10) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/clown mutantrace_variation = STYLE_DIGITIGRADE -/obj/item/clothing/suit/space/hardsuit/clown/mob_can_equip(mob/M, slot) +/obj/item/clothing/suit/space/hardsuit/clown/mob_can_equip(mob/M, equipper, slot, disable_warning, bypass_equip_delay_self) if(!..() || !ishuman(M)) return FALSE if(M.mind && HAS_TRAIT(M.mind, TRAIT_CLOWN_MENTALITY)) @@ -616,7 +651,7 @@ desc = "Early prototype RIG hardsuit helmet, designed to quickly shift over a user's head. Design constraints of the helmet mean it has no inbuilt cameras, thus it restricts the users visability." icon_state = "hardsuit0-ancient" item_state = "anc_helm" - armor = list("melee" = 30, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 75, WOUND = 10) hardsuit_type = "ancient" resistance_flags = FIRE_PROOF @@ -625,7 +660,7 @@ desc = "Prototype powered RIG hardsuit. Provides excellent protection from the elements of space while being comfortable to move around in, thanks to the powered locomotives. Remains very bulky however." icon_state = "hardsuit-ancient" item_state = "anc_hardsuit" - armor = list("melee" = 30, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 75, WOUND = 10) slowdown = 3 helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient resistance_flags = FIRE_PROOF @@ -638,7 +673,7 @@ desc = "The Multi-Augmented Severe Operations Networked Resource Integration Gear is an man-portable tank designed for extreme environmental situations. It is excessively bulky, but rated for all but the most atomic of hazards. The specialized armor is surprisingly weak to conventional weaponry. The exo slot can attach most storage bags on to the suit." icon_state = "hardsuit-ancient" item_state = "anc_hardsuit" - armor = list("melee" = 20, "bullet" = 15, "laser" = 15, "energy" = 45, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 10) + armor = list(MELEE = 20, BULLET = 15, LASER = 15, ENERGY = 45, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 10) slowdown = 6 //Slow allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage, /obj/item/construction/rcd, /obj/item/pipe_dispenser) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient/mason @@ -651,7 +686,7 @@ desc = "The M.A.S.O.N RIG helmet is complimentary to the rest of the armor. It features a very large, high powered flood lamp and robust flash protection." icon_state = "hardsuit0-ancient" item_state = "anc_helm" - armor = list("melee" = 20, "bullet" = 15, "laser" = 15, "energy" = 45, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 10) + armor = list(MELEE = 20, BULLET = 15, LASER = 15, ENERGY = 45, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 10) hardsuit_type = "ancient" brightness_on = 16 flash_protect = 5 //We will not be flash by bombs @@ -661,13 +696,13 @@ clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF -/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/Initialize() +/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/Initialize(mapload) . = ..() bomb_radar = new /obj/machinery/doppler_array/integrated(src) /obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/equipped(mob/living/carbon/human/user, slot) ..() - if (slot == SLOT_HEAD) + if (slot == ITEM_SLOT_HEAD) var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC] DHUD.add_hud_to(user) ADD_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "mason_hardsuit") @@ -691,7 +726,7 @@ /obj/item/clothing/suit/space/hardsuit/ancient/equipped(mob/user, slot) . = ..() - if(slot != SLOT_WEAR_SUIT) + if(slot != ITEM_SLOT_OCLOTHING) if(listeningTo) UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED) return @@ -717,7 +752,7 @@ item_state = "rig0-soviet" hardsuit_type = "soviet" icon_state = "rig0-soviet" - armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 75, "wound" = 15) + armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 15, BOMB = 35, BIO = 100, RAD = 20, FIRE = 50, ACID = 75, WOUND = 15) mutantrace_variation = NONE /obj/item/clothing/suit/space/hardsuit/soviet @@ -726,11 +761,11 @@ item_state = "rig-soviet" icon_state = "rig-soviet" slowdown = 0.8 - armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 75, "wound" = 15) + armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 15, BOMB = 35, BIO = 100, RAD = 20, FIRE = 50, ACID = 75, WOUND = 15) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/soviet mutantrace_variation = NONE -/obj/item/clothing/suit/space/hardsuit/soviet/Initialize() +/obj/item/clothing/suit/space/hardsuit/soviet/Initialize(mapload) . = ..() allowed = GLOB.security_hardsuit_allowed @@ -742,7 +777,7 @@ icon_state = "hardsuit-hos" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/hos allowed = null - armor = list("melee" = 30, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 15) + armor = list(MELEE = 30, BULLET = 15, LASER = 30, ENERGY = 10, BOMB = 10, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 15) resistance_flags = FIRE_PROOF | ACID_PROOF var/max_charges = 3 //How many charges total the shielding has var/current_charges //if null, will default to max_chargs @@ -750,7 +785,7 @@ var/recharge_rate = 1 //How quickly the shield recharges once it starts charging var/shield_state = "shield-old" -/obj/item/clothing/suit/space/hardsuit/shielded/Initialize() +/obj/item/clothing/suit/space/hardsuit/shielded/Initialize(mapload) . = ..() if(!allowed) allowed = GLOB.advanced_hardsuit_allowed @@ -771,11 +806,11 @@ item_state = "ert_medical" hardsuit_type = "ert_medical" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf - armor = list("melee" = 0, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 95, "wound" = 30) + armor = list(MELEE = 0, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 50, BIO = 100, RAD = 100, FIRE = 95, ACID = 95, WOUND = 30) slowdown = 0 max_charges = 5 -/obj/item/clothing/suit/space/hardsuit/shielded/ctf/Initialize() +/obj/item/clothing/suit/space/hardsuit/shielded/ctf/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CAPTURE_THE_FLAG_TRAIT) @@ -800,7 +835,7 @@ icon_state = "hardsuit0-ert_medical" item_state = "hardsuit0-ert_medical" hardsuit_type = "ert_medical" - armor = list("melee" = 0, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 95, "wound" = 30) + armor = list(MELEE = 0, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 50, BIO = 100, RAD = 100, FIRE = 95, ACID = 95, WOUND = 30) /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/red icon_state = "hardsuit0-ert_security" @@ -822,13 +857,13 @@ icon_state = "hardsuit1-syndi" item_state = "syndie_hardsuit" hardsuit_type = "syndi" - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 15, BOMB = 35, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30) allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi slowdown = 0 mutantrace_variation = STYLE_DIGITIGRADE|STYLE_ALL_TAURIC -/obj/item/clothing/suit/space/hardsuit/shielded/syndi/Initialize() +/obj/item/clothing/suit/space/hardsuit/shielded/syndi/Initialize(mapload) jetpack = new /obj/item/tank/jetpack/suit(src) . = ..() @@ -838,7 +873,7 @@ icon_state = "hardsuit1-syndi" item_state = "syndie_helm" hardsuit_type = "syndi" - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 15, BOMB = 35, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30) ///SWAT version /obj/item/clothing/suit/space/hardsuit/shielded/swat @@ -849,7 +884,7 @@ hardsuit_type = "syndi" max_charges = 4 recharge_delay = 15 - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/swat @@ -861,7 +896,7 @@ icon_state = "deathsquad" item_state = "deathsquad" hardsuit_type = "syndi" - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT actions_types = list() @@ -879,14 +914,14 @@ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | LAVA_PROOF heat_protection = HEAD - armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100, "wound" = 30) + armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100, WOUND = 30) brightness_on = 7 allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator) var/energy_color = "#35FFF0" var/obj/item/clothing/suit/space/hardsuit/lavaknight/linkedsuit = null mutantrace_variation = NONE -/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/Initialize() +/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/Initialize(mapload) . = ..() if(istype(loc, /obj/item/clothing/suit/space/hardsuit/lavaknight)) var/obj/item/clothing/suit/space/hardsuit/lavaknight/S = loc @@ -923,13 +958,13 @@ item_state = "swat_suit" max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | LAVA_PROOF - armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100, "wound" = 30) + armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100, WOUND = 30) allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/bag/ore, /obj/item/pickaxe) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/lavaknight heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS var/energy_color = "#35FFF0" -/obj/item/clothing/suit/space/hardsuit/lavaknight/Initialize() +/obj/item/clothing/suit/space/hardsuit/lavaknight/Initialize(mapload) ..() light_color = energy_color set_light(1) diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index c944b2aa1f..24f91a3ab2 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -22,7 +22,7 @@ Contains: desc = "An advanced tactical space helmet." icon_state = "deathsquad" item_state = "deathsquad" - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF @@ -37,7 +37,7 @@ Contains: icon_state = "deathsquad" item_state = "swat_suit" allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/kitchen/knife/combat) - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF @@ -51,7 +51,7 @@ Contains: icon_state = "heavy" item_state = "swat_suit" allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/kitchen/knife/combat) - armor = list("melee" = 40, "bullet" = 30, "laser" = 30,"energy" = 30, "bomb" = 50, "bio" = 90, "rad" = 20, "fire" = 100, "acid" = 100, "wound" = 25) + armor = list(MELEE = 40, BULLET = 30, LASER = 30,ENERGY = 30, BOMB = 50, BIO = 90, RAD = 20, FIRE = 100, ACID = 100, WOUND = 25) strip_delay = 120 resistance_flags = FIRE_PROOF | ACID_PROOF mutantrace_variation = STYLE_DIGITIGRADE @@ -63,7 +63,7 @@ Contains: dynamic_hair_suffix = "+generic" dynamic_fhair_suffix = "+generic" flags_inv = 0 - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF @@ -79,7 +79,7 @@ Contains: flags_inv = 0 w_class = WEIGHT_CLASS_NORMAL allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals) - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF @@ -140,7 +140,7 @@ Contains: desc = "A thick, space-proof tricorne from the royal Space Queen. It's lined with a layer of reflective kevlar." icon_state = "pirate" item_state = "pirate" - armor = list("melee" = 30, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 60, "acid" = 75, "wound" = 30) + armor = list(MELEE = 30, BULLET = 50, LASER = 30,ENERGY = 15, BOMB = 30, BIO = 30, RAD = 30, FIRE = 60, ACID = 75, WOUND = 30) flags_inv = HIDEHAIR strip_delay = 40 equip_delay_other = 20 @@ -163,7 +163,7 @@ Contains: flags_inv = 0 allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/melee/transforming/energy/sword/pirate, /obj/item/clothing/glasses/eyepatch, /obj/item/reagent_containers/food/drinks/bottle/rum) slowdown = 0 - armor = list("melee" = 30, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 60, "acid" = 75, "wound" = 30) + armor = list(MELEE = 30, BULLET = 50, LASER = 30,ENERGY = 15, BOMB = 30, BIO = 30, RAD = 30, FIRE = 60, ACID = 75, WOUND = 30) strip_delay = 40 equip_delay_other = 20 mutantrace_variation = STYLE_DIGITIGRADE @@ -175,12 +175,12 @@ Contains: icon_state = "hardsuit0-ert_commander" item_state = "hardsuit0-ert_commander" hardsuit_type = "ert_commander" - armor = list("melee" = 65, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80, "wound" = 30) + armor = list(MELEE = 65, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 50, BIO = 100, RAD = 100, FIRE = 80, ACID = 80, WOUND = 30) strip_delay = 130 brightness_on = 7 resistance_flags = ACID_PROOF -/obj/item/clothing/head/helmet/space/hardsuit/ert/Initialize() +/obj/item/clothing/head/helmet/space/hardsuit/ert/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, LOCKED_HELMET_TRAIT) @@ -191,7 +191,7 @@ Contains: item_state = "ert_command" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals) - armor = list("melee" = 65, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80, "wound" = 30) + armor = list(MELEE = 65, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 50, BIO = 100, RAD = 100, FIRE = 80, ACID = 80, WOUND = 30) slowdown = 0 strip_delay = 130 resistance_flags = ACID_PROOF @@ -234,7 +234,6 @@ Contains: icon_state = "ert_medical" item_state = "ert_medical" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/med - species_exception = list(/datum/species/angel) //Red alert ERT @@ -244,7 +243,7 @@ Contains: icon_state = "hardsuit0-ert_commander-alert" item_state = "hardsuit0-ert_commander-alert" hardsuit_type = "ert_commander-alert" - armor = list("melee" = 70, "bullet" = 55, "laser" = 50, "energy" = 50, "bomb" = 65, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 50) + armor = list(MELEE = 70, BULLET = 55, LASER = 50, ENERGY = 50, BOMB = 65, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 50) brightness_on = 8 resistance_flags = FIRE_PROOF | ACID_PROOF @@ -254,7 +253,7 @@ Contains: icon_state = "ert_command-alert" item_state = "ert_command-alert" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/alert - armor = list("melee" = 70, "bullet" = 55, "laser" = 50, "energy" = 50, "bomb" = 65, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 50) + armor = list(MELEE = 70, BULLET = 55, LASER = 50, ENERGY = 50, BOMB = 65, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 50) resistance_flags = FIRE_PROOF | ACID_PROOF mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC|STYLE_PAW_TAURIC @@ -296,14 +295,13 @@ Contains: icon_state = "ert_medical-alert" item_state = "ert_medical-alert" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/alert/med - species_exception = list(/datum/species/angel) /obj/item/clothing/suit/space/eva name = "EVA suit" icon_state = "space" item_state = "s_suit" desc = "A lightweight space suit with the basic ability to protect the wearer from the vacuum of space during emergencies." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 65, "wound" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 100, RAD = 20, FIRE = 50, ACID = 65, WOUND = 10) /obj/item/clothing/head/helmet/space/eva name = "EVA helmet" @@ -311,7 +309,7 @@ Contains: item_state = "space" desc = "A lightweight space helmet with the basic ability to protect the wearer from the vacuum of space during emergencies." flash_protect = 0 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 65, "wound" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 100, RAD = 20, FIRE = 50, ACID = 65, WOUND = 10) //Radiation /obj/item/clothing/head/helmet/space/rad @@ -319,7 +317,7 @@ Contains: desc = "A special helmet that protects against radiation and space. Not much else unfortunately." icon_state = "cespace_helmet" item_state = "nothing" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 100, FIRE = 0, ACID = 0, WOUND = 5) resistance_flags = FIRE_PROOF rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE actions_types = list() @@ -329,7 +327,7 @@ Contains: desc = "A special suit that protects against radiation and space. Not much else unfortunately." icon_state = "hardsuit-rad" item_state = "nothing" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 100, FIRE = 0, ACID = 0, WOUND = 5) resistance_flags = FIRE_PROOF rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE mutantrace_variation = NONE @@ -339,7 +337,7 @@ Contains: desc = "An advanced, space-proof helmet. It appears to be modeled after an old-world eagle." icon_state = "griffinhat" item_state = "griffinhat" - armor = list("melee" = 20, "bullet" = 40, "laser" = 30, "energy" = 25, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80, "wound" = 20) + armor = list(MELEE = 20, BULLET = 40, LASER = 30, ENERGY = 25, BOMB = 100, BIO = 100, RAD = 100, FIRE = 80, ACID = 80, WOUND = 20) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = ACID_PROOF | FIRE_PROOF @@ -351,7 +349,7 @@ Contains: icon_state = "freedom" item_state = "freedom" allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals) - armor = list("melee" = 20, "bullet" = 40, "laser" = 30,"energy" = 25, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80, "wound" = 20) + armor = list(MELEE = 20, BULLET = 40, LASER = 30,ENERGY = 25, BOMB = 100, BIO = 100, RAD = 100, FIRE = 80, ACID = 80, WOUND = 20) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = ACID_PROOF | FIRE_PROOF @@ -364,12 +362,12 @@ Contains: desc = "Spaceworthy and it looks like a space carp's head, smells like one too." icon_state = "carp_helm" item_state = "syndicate" - armor = list("melee" = -20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 75, "wound" = 5) //As whimpy as a space carp + armor = list(MELEE = -20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 75, FIRE = 60, ACID = 75, WOUND = 5) //As whimpy as a space carp brightness_on = 0 //luminosity when on actions_types = list() mutantrace_variation = NONE -/obj/item/clothing/head/helmet/space/hardsuit/carp/Initialize() +/obj/item/clothing/head/helmet/space/hardsuit/carp/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, LOCKED_HELMET_TRAIT) @@ -380,7 +378,7 @@ Contains: icon_state = "carp_suit" item_state = "space_suit_syndicate" slowdown = 0 //Space carp magic, never stop believing - armor = list("melee" = -20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 75, "wound" = 5) //As whimpy whimpy whoo + armor = list(MELEE = -20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 75, FIRE = 60, ACID = 75, WOUND = 5) //As whimpy whimpy whoo allowed = list(/obj/item/tank/internals, /obj/item/gun/ballistic/automatic/speargun) //I'm giving you a hint here helmettype = /obj/item/clothing/head/helmet/space/hardsuit/carp mutantrace_variation = STYLE_DIGITIGRADE @@ -397,7 +395,7 @@ Contains: mutantrace_variation = NONE var/charges = INFINITY -/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/Initialize() +/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/Initialize(mapload) . = ..() AddComponent(/datum/component/anti_magic, FALSE, FALSE, TRUE, ITEM_SLOT_HEAD, charges, TRUE, null, CALLBACK(src, .proc/anti_magic_gone)) @@ -418,7 +416,7 @@ Contains: resistance_flags = FIRE_PROOF var/charges = INFINITY -/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize() +/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize(mapload) . = ..() AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, ITEM_SLOT_OCLOTHING, charges, TRUE, null, CALLBACK(src, .proc/anti_magic_gone)) @@ -442,14 +440,14 @@ Contains: /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor/old desc = "Powerful wards are built into this hardsuit, protecting the user from all manner of paranormal threats. Alas, this one looks pretty worn out and rusted." - armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60, "wound" = 20) + armor = list(MELEE = 55, BULLET = 40, LASER = 40, ENERGY = 40, BOMB = 40, BIO = 80, RAD = 80, FIRE = 60, ACID = 60, WOUND = 20) slowdown = 0.8 helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/old charges = 12 /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/old desc = "A helmet worn by those who deal with paranormal threats for a living. Alas, this one looks pretty worn out and rusted." - armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60, "wound" = 20) + armor = list(MELEE = 55, BULLET = 40, LASER = 40, ENERGY = 40, BOMB = 40, BIO = 80, RAD = 80, FIRE = 60, ACID = 60, WOUND = 20) charges = 12 /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker @@ -467,14 +465,14 @@ Contains: /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker/old desc = "Voices echo from the hardsuit, driving the user insane. This one is pretty battle-worn, but still fearsome." - armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60, "wound" = 20) + armor = list(MELEE = 55, BULLET = 40, LASER = 40, ENERGY = 40, BOMB = 40, BIO = 80, RAD = 80, FIRE = 60, ACID = 60, WOUND = 20) slowdown = 0.8 helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/beserker/old charges = 6 /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/beserker/old desc = "Peering into the eyes of the helmet is enough to seal damnation. This one is pretty battle-worn, but still fearsome." - armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60, "wound" = 20) + armor = list(MELEE = 55, BULLET = 40, LASER = 40, ENERGY = 40, BOMB = 40, BIO = 80, RAD = 80, FIRE = 60, ACID = 60, WOUND = 20) charges = 6 /obj/item/clothing/head/helmet/space/fragile @@ -482,7 +480,7 @@ Contains: desc = "A bulky, air-tight helmet meant to protect the user during emergency situations. It doesn't look very durable." icon_state = "syndicate-helm-orange" item_state = "syndicate-helm-orange" - armor = list("melee" = 5, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 5, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 10, FIRE = 0, ACID = 0, WOUND = 5) strip_delay = 65 /obj/item/clothing/suit/space/fragile @@ -492,7 +490,7 @@ Contains: icon_state = "syndicate-orange" item_state = "syndicate-orange" slowdown = 2 - armor = list("melee" = 5, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 5, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 10, FIRE = 0, ACID = 0, WOUND = 5) strip_delay = 65 /obj/item/clothing/suit/space/fragile/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) @@ -525,7 +523,7 @@ Contains: icon_state = "hunter" item_state = "swat_suit" allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/kitchen/knife/combat) - armor = list("melee" = 60, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 25) + armor = list(MELEE = 60, BULLET = 40, LASER = 40, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 25) strip_delay = 130 resistance_flags = FIRE_PROOF | ACID_PROOF diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index b50c2b45db..8eacf66bbe 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -5,7 +5,7 @@ name = "EVA plasma envirosuit" desc = "A special plasma containment suit designed to be space-worthy, as well as worn over other clothing. Like its smaller counterpart, it can automatically extinguish the wearer in a crisis, and holds twice as many charges." allowed = list(/obj/item/gun, /obj/item/ammo_casing, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword, /obj/item/restraints/handcuffs, /obj/item/tank) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 0, FIRE = 100, ACID = 75, WOUND = 10) resistance_flags = FIRE_PROOF icon_state = "plasmaman_suit" item_state = "plasmaman_suit" @@ -42,7 +42,7 @@ strip_delay = 80 flash_protect = 2 tint = 2 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 0, FIRE = 100, ACID = 75, WOUND = 10) resistance_flags = FIRE_PROOF var/brightness_on = 4 //luminosity when the light is on var/helmet_on = FALSE @@ -58,7 +58,7 @@ visor_flags_inv = HIDEEYES|HIDEFACE|HIDEFACIALHAIR mutantrace_variation = NONE -/obj/item/clothing/head/helmet/space/plasmaman/Initialize() +/obj/item/clothing/head/helmet/space/plasmaman/Initialize(mapload) . = ..() visor_toggling() update_icon() @@ -155,7 +155,7 @@ desc = "A plasmaman containment helmet designed for security officers, protecting them from being flashed and burning alive, along-side other undesirables." icon_state = "security_envirohelm" item_state = "security_envirohelm" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75, "wound" = 20) + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 0, FIRE = 100, ACID = 75, WOUND = 20) /obj/item/clothing/head/helmet/space/plasmaman/security/warden name = "warden's plasma envirosuit helmet" @@ -169,6 +169,10 @@ icon_state = "hos_envirohelm" item_state = "hos_envirohelm" +/obj/item/clothing/head/helmet/space/plasmaman/prisoner + name = "prisoner's plasma envirosuit helmet" + desc = "A plasmaman containment helmet for prisoners." + /obj/item/clothing/head/helmet/space/plasmaman/medical name = "medical's plasma envirosuit helmet" desc = "An envriohelmet designed for plasmaman medical doctors, having two stripes down it's length to denote as much." @@ -210,7 +214,7 @@ desc = "A sturdier plasmaman envirohelmet designed for research directors." icon_state = "rd_envirohelm" item_state = "rd_envirohelm" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 100, RAD = 0, FIRE = 100, ACID = 75, WOUND = 10) /obj/item/clothing/head/helmet/space/plasmaman/robotics name = "robotics plasma envirosuit helmet" @@ -223,7 +227,7 @@ desc = "A space-worthy helmet specially designed for engineer plasmamen, the usual purple stripes being replaced by engineering's orange." icon_state = "engineer_envirohelm" item_state = "engineer_envirohelm" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 10, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 10, FIRE = 100, ACID = 75, WOUND = 10) /obj/item/clothing/head/helmet/space/plasmaman/engineering/ce name = "chief engineer's plasma envirosuit helmet" @@ -273,7 +277,7 @@ desc = "A blue and gold envirohelm designed for the station's captain, nonetheless. Made of superior materials to protect them from the station hazards and more." icon_state = "captain_envirohelm" item_state = "captain_envirohelm" - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 10, "fire" = 100, "acid" = 85, "wound" = 15) + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 10, BIO = 100, RAD = 10, FIRE = 100, ACID = 85, WOUND = 15) /obj/item/clothing/head/helmet/space/plasmaman/curator name = "curator's plasma envirosuit helmet" diff --git a/code/modules/clothing/spacesuits/syndi.dm b/code/modules/clothing/spacesuits/syndi.dm index f55379da2f..81eff1b428 100644 --- a/code/modules/clothing/spacesuits/syndi.dm +++ b/code/modules/clothing/spacesuits/syndi.dm @@ -4,7 +4,7 @@ icon_state = "syndicate" item_state = "syndicate" desc = "Has a tag on it: Totally not property of an enemy corporation, honest!" - armor = list("melee" = 40, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 80, "acid" = 85, "wound" = 20) + armor = list(MELEE = 40, BULLET = 50, LASER = 30,ENERGY = 15, BOMB = 30, BIO = 30, RAD = 30, FIRE = 80, ACID = 85, WOUND = 20) /obj/item/clothing/suit/space/syndicate name = "red space suit" @@ -13,7 +13,7 @@ desc = "Has a tag on it: Totally not property of an enemy corporation, honest!" w_class = WEIGHT_CLASS_NORMAL allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals) - armor = list("melee" = 40, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 80, "acid" = 85, "wound" = 20) + armor = list(MELEE = 40, BULLET = 50, LASER = 30,ENERGY = 15, BOMB = 30, BIO = 30, RAD = 30, FIRE = 80, ACID = 85, WOUND = 20) mutantrace_variation = STYLE_DIGITIGRADE //Green syndicate space suit diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm index 0d16f9bdfa..202ee4cc0d 100644 --- a/code/modules/clothing/suits/_suits.dm +++ b/code/modules/clothing/suits/_suits.dm @@ -4,7 +4,7 @@ block_priority = BLOCK_PRIORITY_WEAR_SUIT var/fire_resist = T0C+100 allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) slot_flags = ITEM_SLOT_OCLOTHING body_parts_covered = CHEST var/blood_overlay_type = "suit" @@ -20,14 +20,14 @@ . += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]") if(blood_DNA) var/file2use = (style_flags & STYLE_ALL_TAURIC) ? 'modular_citadel/icons/mob/64x32_effects.dmi' : 'icons/effects/blood.dmi' - . += mutable_appearance(file2use, "[blood_overlay_type]blood", color = blood_DNA_to_color()) + . += mutable_appearance(file2use, "[blood_overlay_type]blood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) var/mob/living/carbon/human/M = loc if(ishuman(M) && M.w_uniform) var/obj/item/clothing/under/U = M.w_uniform if(istype(U) && U.attached_accessory) var/obj/item/clothing/accessory/A = U.attached_accessory if(A.above_suit) - . += U.accessory_overlay + . += U.accessory_overlays /obj/item/clothing/suit/update_clothes_damaged_state() ..() diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 254ed60c03..36795d53b8 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -8,10 +8,10 @@ equip_delay_other = 40 max_integrity = 250 resistance_flags = NONE - armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10) + armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 50, WOUND = 10) -/obj/item/clothing/suit/armor/Initialize() +/obj/item/clothing/suit/armor/Initialize(mapload) . = ..() if(!allowed) allowed = GLOB.security_vest_allowed @@ -58,7 +58,7 @@ icon_state = "hos" item_state = "greatcoat" body_parts_covered = CHEST|GROIN|ARMS|LEGS - armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 90, "wound" = 10) + armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 70, ACID = 90, WOUND = 10) cold_protection = CHEST|GROIN|LEGS|ARMS heat_protection = CHEST|GROIN|LEGS|ARMS strip_delay = 80 @@ -80,9 +80,27 @@ item_state = "hostrench" flags_inv = 0 strip_delay = 80 - unique_reskin = list("Coat" = "hostrench", - "Cloak" = "trenchcloak" - ) + unique_reskin = list( + "Coat" = list("icon_state" = "hostrench"), + "Cloak" = list("icon_state" = "trenchcloak") + ) + +/obj/item/clothing/suit/armor/hos/platecarrier + name = "plate carrier" + desc = "An armor vest with attached pockets for holding and sorting equipment or ammo." + icon_state = "platecarrier" + item_state = "platecarrier" + body_parts_covered = CHEST|GROIN|ARMS + armor = list (MELEE = 30, BULLET = 40, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 70, WOUND = 10) + cold_protection = CHEST|ARMS + heat_protection = CHEST|ARMS + strip_delay = 80 + mutantrace_variation = STYLE_DIGITIGRADE + +/obj/item/clothing/suit/armor/hos/platecarrier/ComponentInitialize() + . = ..() + var/datum/component/storage/concrete/storage = AddComponent(/datum/component/storage/concrete) + storage.max_items = 5 /obj/item/clothing/suit/armor/vest/warden name = "warden's jacket" @@ -126,7 +144,7 @@ icon_state = "capcarapace" item_state = "armor" body_parts_covered = CHEST|GROIN - armor = list("melee" = 50, "bullet" = 40, "laser" = 50, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 90, "wound" = 10) + armor = list(MELEE = 50, BULLET = 40, LASER = 50, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 100, ACID = 90, WOUND = 10) dog_fashion = null resistance_flags = FIRE_PROOF @@ -136,21 +154,28 @@ icon_state = "syndievest" mutantrace_variation = STYLE_DIGITIGRADE -/obj/item/clothing/suit/armor/vest/capcarapace/alt +/obj/item/clothing/suit/toggle/captains_parade name = "captain's parade jacket" desc = "For when an armoured vest isn't fashionable enough." icon_state = "capformal" item_state = "capspacesuit" + body_parts_covered = CHEST|GROIN|ARMS + armor = list(MELEE = 50, BULLET = 40, LASER = 50, ENERGY = 50, BOMB = 25, BIO = 0, RAD = 0, FIRE = 100, ACID = 90, WOUND = 10) + togglename = "buttons" + +/obj/item/clothing/suit/toggle/captains_parade/Initialize(mapload) + . = ..() + allowed = GLOB.security_wintercoat_allowed /obj/item/clothing/suit/armor/riot name = "riot suit" desc = "A suit of semi-flexible polycarbonate body armor with heavy padding to protect against melee attacks. Helps the wearer resist shoving in close quarters." - icon_state = "swat" - item_state = "swat_suit" + icon_state = "riot" + item_state = "riot" body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list("melee" = 50, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80, "wound" = 20) + armor = list(MELEE = 50, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 80, WOUND = 20) blocks_shove_knockdown = TRUE strip_delay = 80 equip_delay_other = 60 @@ -161,7 +186,7 @@ icon_state = "bonearmor" item_state = "bonearmor" blood_overlay_type = "armor" - armor = list("melee" = 35, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10) + armor = list(MELEE = 35, BULLET = 25, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 50, WOUND = 10) body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS /obj/item/clothing/suit/armor/bulletproof @@ -170,7 +195,7 @@ icon_state = "bulletproof" item_state = "armor" blood_overlay_type = "armor" - armor = list("melee" = 15, "bullet" = 60, "laser" = 10, "energy" = 10, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 20) + armor = list(MELEE = 15, BULLET = 60, LASER = 10, ENERGY = 10, BOMB = 40, BIO = 0, RAD = 0, FIRE = 50, ACID = 50, WOUND = 20) strip_delay = 70 equip_delay_other = 50 mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON @@ -181,7 +206,7 @@ icon_state = "armor_reflec" item_state = "armor_reflec" blood_overlay_type = "armor" - armor = list("melee" = 10, "bullet" = 10, "laser" = 60, "energy" = 50, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 10, BULLET = 10, LASER = 60, ENERGY = 50, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON var/hit_reflect_chance = 40 @@ -200,7 +225,7 @@ resistance_flags = FLAMMABLE dog_fashion = null -/obj/item/clothing/suit/armor/vest/det_suit/Initialize() +/obj/item/clothing/suit/armor/vest/det_suit/Initialize(mapload) . = ..() allowed = GLOB.detective_vest_allowed @@ -209,7 +234,7 @@ desc = "An insidious combat vest designed using Syndicate nanofibers to absorb the supreme majority of kinetic blows. Although it doesn't look like it'll do too much for energy impacts." icon_state = "infiltrator" item_state = "infiltrator" - armor = list("melee" = 30, "bullet" = 40, "laser" = 20, "energy" = 30, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 30, BULLET = 40, LASER = 20, ENERGY = 30, BOMB = 70, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) resistance_flags = FIRE_PROOF | ACID_PROOF strip_delay = 80 @@ -229,7 +254,7 @@ min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 90) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 90, ACID = 90) /obj/item/clothing/suit/armor/heavy name = "heavy armor" @@ -242,7 +267,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS slowdown = 3 flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 90) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 90, ACID = 90) /obj/item/clothing/suit/armor/tdome body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS @@ -250,7 +275,7 @@ clothing_flags = THICKMATERIAL cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 90) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 90, ACID = 90) /obj/item/clothing/suit/armor/tdome/red name = "thunderdome suit" @@ -288,7 +313,7 @@ desc = "A classic suit of armour, able to be made from many different materials." icon_state = "knight_greyscale" item_state = "knight_greyscale" - armor = list("melee" = 35, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40, "wound" = 15) + armor = list(MELEE = 35, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 10, BIO = 10, RAD = 10, FIRE = 40, ACID = 40, WOUND = 15) material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS //Can change color and add prefix /obj/item/clothing/suit/armor/vest/durathread @@ -300,14 +325,14 @@ equip_delay_other = 40 max_integrity = 200 resistance_flags = FLAMMABLE - armor = list("melee" = 20, "bullet" = 10, "laser" = 30, "energy" = 5, "bomb" = 15, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 20, BULLET = 10, LASER = 30, ENERGY = 5, BOMB = 15, BIO = 0, RAD = 0, FIRE = 0, ACID = 50) /obj/item/clothing/suit/armor/vest/russian name = "russian vest" desc = "A bulletproof vest with forest camo. Good thing there's plenty of forests to hide in around here, right?" icon_state = "rus_armor" item_state = "rus_armor" - armor = list("melee" = 25, "bullet" = 30, "laser" = 0, "energy" = 15, "bomb" = 10, "bio" = 0, "rad" = 20, "fire" = 20, "acid" = 50, "wound" = 10) + armor = list(MELEE = 25, BULLET = 30, LASER = 0, ENERGY = 15, BOMB = 10, BIO = 0, RAD = 20, FIRE = 20, ACID = 50, WOUND = 10) /obj/item/clothing/suit/armor/vest/russian_coat name = "russian battle coat" @@ -318,4 +343,30 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT - armor = list("melee" = 25, "bullet" = 20, "laser" = 20, "energy" = 10, "bomb" = 20, "bio" = 50, "rad" = 20, "fire" = -10, "acid" = 50, "wound" = 10) + armor = list(MELEE = 25, BULLET = 20, LASER = 20, ENERGY = 10, BOMB = 20, BIO = 50, RAD = 20, FIRE = -10, ACID = 50, WOUND = 10) + +/obj/item/clothing/suit/toggle/armor/vest/centcom_formal + name = "\improper CentCom formal coat" + desc = "A stylish coat given to CentCom Commanders. Perfect for sending ERTs to suicide missions with style!" + icon_state = "centcom_formal" + item_state = "centcom" + body_parts_covered = CHEST|GROIN|ARMS + armor = list(MELEE = 35, BULLET = 40, LASER = 40, ENERGY = 50, BOMB = 35, BIO = 10, RAD = 10, FIRE = 10, ACID = 60) + togglename = "buttons" + +/obj/item/clothing/suit/toggle/armor/vest/centcom_formal/Initialize(mapload) + . = ..() + allowed = GLOB.security_wintercoat_allowed + +/obj/item/clothing/suit/toggle/armor/hos/hos_formal + name = "\improper Head of Security's parade jacket" + desc = "For when an armoured vest isn't fashionable enough." + icon_state = "hosformal" + item_state = "hostrench" + body_parts_covered = CHEST|GROIN|ARMS + armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 40, BOMB = 25, BIO = 0, RAD = 0, FIRE = 70, ACID = 90, WOUND = 10) + togglename = "buttons" + +/obj/item/clothing/suit/toggle/armor/hos/hos_formal/Initialize(mapload) + . = ..() + allowed = GLOB.security_wintercoat_allowed diff --git a/code/modules/clothing/suits/bio.dm b/code/modules/clothing/suits/bio.dm index 94859d434f..2b66d61237 100644 --- a/code/modules/clothing/suits/bio.dm +++ b/code/modules/clothing/suits/bio.dm @@ -5,7 +5,7 @@ desc = "A hood that protects the head and face from biological contaminants." permeability_coefficient = 0.01 clothing_flags = THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 60, "fire" = 30, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 100, RAD = 60, FIRE = 30, ACID = 100) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDEFACE|HIDESNOUT resistance_flags = ACID_PROOF flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH @@ -23,7 +23,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS slowdown = 1 allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/pen, /obj/item/flashlight/pen, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 60, "fire" = 30, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 100, RAD = 60, FIRE = 30, ACID = 100) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAUR strip_delay = 70 equip_delay_other = 70 @@ -48,11 +48,11 @@ //Security biosuit, grey with red stripe across the chest /obj/item/clothing/head/bio_hood/security - armor = list("melee" = 25, "bullet" = 15, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 80, "fire" = 30, "acid" = 100) + armor = list(MELEE = 25, BULLET = 15, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 100, RAD = 80, FIRE = 30, ACID = 100) icon_state = "bio_security" /obj/item/clothing/suit/bio_suit/security - armor = list("melee" = 25, "bullet" = 15, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 80, "fire" = 30, "acid" = 100) + armor = list(MELEE = 25, BULLET = 15, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 100, RAD = 80, FIRE = 30, ACID = 100) icon_state = "bio_security" diff --git a/code/modules/clothing/suits/cloaks.dm b/code/modules/clothing/suits/cloaks.dm index a58b218c1a..9c9c22e72e 100644 --- a/code/modules/clothing/suits/cloaks.dm +++ b/code/modules/clothing/suits/cloaks.dm @@ -60,7 +60,7 @@ icon_state = "goliath_cloak" desc = "A staunch, practical cape made out of numerous monster materials, it is coveted amongst exiles & hermits." allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/pickaxe, /obj/item/spear, /obj/item/spear/bonespear, /obj/item/organ/regenerative_core/legion, /obj/item/kitchen/knife/combat/bone, /obj/item/kitchen/knife/combat/survival) - armor = list("melee" = 35, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) //a fair alternative to bone armor, requiring alternative materials and gaining a suit slot + armor = list(MELEE = 35, BULLET = 10, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 60, ACID = 60) //a fair alternative to bone armor, requiring alternative materials and gaining a suit slot hoodtype = /obj/item/clothing/head/hooded/cloakhood/goliath body_parts_covered = CHEST|ARMS|LEGS @@ -68,7 +68,7 @@ name = "goliath cloak hood" icon_state = "golhood" desc = "A protective & concealing hood." - armor = list("melee" = 35, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) + armor = list(MELEE = 35, BULLET = 10, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 60, ACID = 60) flags_inv = HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR /obj/item/clothing/suit/hooded/cloak/drake @@ -76,7 +76,7 @@ icon_state = "dragon" desc = "A suit of armour fashioned from the remains of an ash drake." allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe, /obj/item/spear) - armor = list("melee" = 70, "bullet" = 20, "laser" = 35, "energy" = 25, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 70, BULLET = 20, LASER = 35, ENERGY = 25, BOMB = 25, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) hoodtype = /obj/item/clothing/head/hooded/cloakhood/drake heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS @@ -87,7 +87,7 @@ name = "drake helm" icon_state = "dragon" desc = "The skull of a dragon." - armor = list("melee" = 70, "bullet" = 20, "laser" = 35, "energy" = 25, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 70, BULLET = 20, LASER = 35, ENERGY = 25, BOMB = 25, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) heat_protection = HEAD max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF | GOLIATH_RESISTANCE diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 13bfd8b460..e8ba7a5d18 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -102,12 +102,12 @@ item_state = "det_suit" blood_overlay_type = "coat" body_parts_covered = CHEST|GROIN|LEGS|ARMS - armor = list("melee" = 25, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 45) + armor = list(MELEE = 25, BULLET = 10, LASER = 25, ENERGY = 10, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 45) cold_protection = CHEST|GROIN|LEGS|ARMS heat_protection = CHEST|GROIN|LEGS|ARMS mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON -/obj/item/clothing/suit/det_suit/Initialize() +/obj/item/clothing/suit/det_suit/Initialize(mapload) . = ..() allowed = GLOB.detective_vest_allowed @@ -176,7 +176,7 @@ /obj/item/clothing/suit/toggle/lawyer/black/syndie desc = "A snappy dress jacket. Suspiciously has no tags or branding." - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40) + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 10, BIO = 10, RAD = 10, FIRE = 40, ACID = 40) //Mime /obj/item/clothing/suit/suspenders @@ -204,7 +204,7 @@ blood_overlay_type = "coat" body_parts_covered = CHEST|ARMS allowed = list(/obj/item/tank/internals, /obj/item/melee/curator_whip) - armor = list("melee" = 25, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 45) + armor = list(MELEE = 25, BULLET = 10, LASER = 25, ENERGY = 10, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 45) cold_protection = CHEST|ARMS heat_protection = CHEST|ARMS mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm index d8e0466069..f94e21a466 100644 --- a/code/modules/clothing/suits/labcoat.dm +++ b/code/modules/clothing/suits/labcoat.dm @@ -27,7 +27,7 @@ /obj/item/tank/internals/plasmaman ) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 50, RAD = 0, FIRE = 50, ACID = 50) togglename = "buttons" species_exception = list(/datum/species/golem) @@ -78,7 +78,7 @@ icon_state = "sci_dep_jacket" item_state = "sci_dep_jacket" allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/suit/toggle/labcoat/depjacket/med name = "medical jacket" @@ -86,14 +86,14 @@ icon_state = "med_dep_jacket" item_state = "med_dep_jacket" allowed = list(/obj/item/analyzer, /obj/item/sensor_device, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 0, "acid" = 45) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 50, RAD = 0, FIRE = 0, ACID = 45) /obj/item/clothing/suit/toggle/labcoat/depjacket/sec name = "security jacket" desc = "A comfortable jacket in security red." icon_state = "sec_dep_jacket" item_state = "sec_dep_jacket" - armor = list("melee" = 25, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 45) + armor = list(MELEE = 25, BULLET = 15, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 0, ACID = 45) allowed = list(/obj/item/gun/energy, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) /obj/item/clothing/suit/toggle/labcoat/depjacket/sup @@ -113,5 +113,5 @@ desc = "A comfortable jacket in engineering yellow." icon_state = "engi_dep_jacket" item_state = "engi_dep_jacket" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 20, "fire" = 30, "acid" = 45) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 20, FIRE = 30, ACID = 45) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 354d488703..4de1b2ed8d 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -185,7 +185,7 @@ body_parts_covered = ARMS actions_types = list(/datum/action/item_action/toggle_wings) -/obj/item/clothing/suit/toggle/owlwings/Initialize() +/obj/item/clothing/suit/toggle/owlwings/Initialize(mapload) . = ..() allowed = GLOB.security_vest_allowed @@ -206,7 +206,7 @@ /obj/item/clothing/suit/cardborg/equipped(mob/living/user, slot) ..() - if(slot == SLOT_WEAR_SUIT) + if(slot == ITEM_SLOT_OCLOTHING) disguise(user) /obj/item/clothing/suit/cardborg/dropped(mob/living/user) @@ -259,7 +259,7 @@ icon_state = "ponchoshame" item_state = "ponchoshame" -/obj/item/clothing/suit/poncho/ponchoshame/Initialize() +/obj/item/clothing/suit/poncho/ponchoshame/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, SHAMEBRERO_TRAIT) @@ -279,7 +279,9 @@ item_state = "labcoat" body_parts_covered = CHEST|GROIN|ARMS|LEGS|FEET cold_protection = CHEST|GROIN|ARMS + heat_protection = CHEST|GROIN|ARMS min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT //Space carp like space, so you should too + max_heat_protection_temperature = COAT_MAX_TEMP_PROTECT allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/gun/ballistic/automatic/speargun, /obj/item/staff/bostaff) hoodtype = /obj/item/clothing/head/hooded/carp_hood @@ -289,7 +291,9 @@ icon_state = "carp_casual" body_parts_covered = HEAD cold_protection = HEAD + heat_protection = HEAD min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + max_heat_protection_temperature = COAT_MAX_TEMP_PROTECT flags_inv = HIDEHAIR|HIDEEARS /obj/item/clothing/suit/hooded/ian_costume //It's Ian, rub his bell- oh god what happened to his inside parts? @@ -362,7 +366,10 @@ item_state = "ran_suit" body_parts_covered = CHEST|GROIN|LEGS flags_inv = HIDEJUMPSUIT|HIDETAUR - heat_protection = CHEST|GROIN|LEGS //fluffy tails! + cold_protection = CHEST|GROIN|LEGS //fluffy tails! + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT //Bleh, same as winter coat + heat_protection = CHEST|GROIN|LEGS + max_heat_protection_temperature = COAT_MAX_TEMP_PROTECT mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON /obj/item/clothing/head/ran @@ -419,7 +426,9 @@ allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/radio) body_parts_covered = CHEST|ARMS cold_protection = CHEST|GROIN|ARMS + heat_protection = CHEST|GROIN|ARMS min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + max_heat_protection_temperature = COAT_MAX_TEMP_PROTECT mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON /obj/item/clothing/suit/jacket/flannel @@ -427,25 +436,84 @@ desc = "Comfy and supposedly flammable." icon_state = "flannel" item_state = "flannel" - -/obj/item/clothing/suit/jacket/flannel/red +/obj/item/clothing/suit/toggle/jacket/flannel/red name = "red flannel jacket" desc = "Comfy and supposedly flammable." icon_state = "flannel_red" item_state = "flannel_red" - -/obj/item/clothing/suit/jacket/flannel/aqua + togglename = "buttons" +/obj/item/clothing/suit/toggle/jacket/flannel/aqua name = "aqua flannel jacket" desc = "Comfy and supposedly flammable." icon_state = "flannel_aqua" item_state = "flannel_aqua" - -/obj/item/clothing/suit/jacket/flannel/brown + togglename = "buttons" +/obj/item/clothing/suit/toggle/jacket/flannel/brown name = "brown flannel jacket" desc = "Comfy and supposedly flammable." icon_state = "flannel_brown" item_state = "flannel_brown" + togglename = "buttons" +/obj/item/clothing/suit/toggle/jacket/whitehoodie + name = "soft hoodie" + desc = "A soft hoodie with a TailorCo brand on the tag." + icon_state = "white_hoodie" + item_state = "white_hoodie" + togglename = "zipper" +/obj/item/clothing/suit/jacket/purplehoodie + name = "purple hoodie" + desc = "A soft purple hoodie with a TailorCo brand on the tag." + icon_state = "purplehoodie" + item_state = "purplehoodie" +/obj/item/clothing/suit/jacket/bluehoodie + name = "blue hoodie" + desc = "A soft blue hoodie with a TailorCo brand on the tag." + icon_state = "bluehoodie" + item_state = "bluehoodie" + +/obj/item/clothing/suit/jacket/heartcoat + name = "heart coat" + desc = "A soft winter coat with a TailorCo brand on the tag." + icon_state = "heartcoat" + item_state = "heartcoat" + +/obj/item/clothing/suit/jacket/gothiccoat + name = "long black jacket" + desc = "A rugged looking coat with a TailorCo brand on the tag." + icon_state = "gothic_coat" + item_state = "gothic_coat" + +/obj/item/clothing/suit/jacket/gothicshirt + name = "black shirt with cuffs" + desc = "A black shirt with a collar and cuffs in a gothic style. A TailorCo brand is listed on the tag." + icon_state = "gothic_shirt" + item_state = "gothic_shirt" + +/obj/item/clothing/suit/jacket/gothicshirtcross + name = "elegant black shirt" + desc = "A black shirt with finely woven cross on the back. A TailorCo brand is listed on the tag." + icon_state = "gothic_shirtcross" + item_state = "gothic_shirtcross" + +/obj/item/clothing/suit/jacket/gentlecoat + name = "grey jacket" + desc = "A grey coat with a TailorCo brand on the tag. Looks expensive." + icon_state = "gentlecoat" + item_state = "gentlecoat" + +/obj/item/clothing/suit/toggle/jacket/greenjacket + name = "green outdoorsmans jacket" + desc = "A green jacket with a TailorCo brand on the tag. Looks expensive." + icon_state = "coatar" + item_state = "coatar" + togglename = "zipper" +/obj/item/clothing/suit/toggle/jacket/fancytrench + name = "grey trenchcoat" + desc = "A custom-tailored trenchcoat with a TailorCo brand on the tag." + icon_state = "fancytrench" + item_state = "fancytrench" + togglename = "buttons" /obj/item/clothing/suit/jacket/leather name = "leather jacket" desc = "Pompadour not included." @@ -461,6 +529,7 @@ icon_state = "leathercoat" body_parts_covered = CHEST|GROIN|ARMS|LEGS cold_protection = CHEST|GROIN|ARMS|LEGS + heat_protection = CHEST|GROIN|ARMS|LEGS mutantrace_variation = STYLE_DIGITIGRADE /obj/item/clothing/suit/jacket/puffer @@ -469,7 +538,7 @@ icon_state = "pufferjacket" item_state = "hostrench" body_parts_covered = CHEST|GROIN|ARMS - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 50, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/suit/jacket/puffer/vest name = "puffer vest" @@ -478,7 +547,8 @@ item_state = "armor" body_parts_covered = CHEST|GROIN cold_protection = CHEST|GROIN - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 30, "rad" = 0, "fire" = 0, "acid" = 0) + heat_protection = CHEST|GROIN + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 30, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/suit/jacket/miljacket name = "military jacket" @@ -565,7 +635,7 @@ w_class = WEIGHT_CLASS_SMALL body_parts_covered = CHEST|GROIN attack_verb = list("warned", "cautioned", "smashed") - armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 5, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/suit/petharness name = "pet harness" @@ -596,8 +666,10 @@ item_state = "coatwinter" body_parts_covered = CHEST|GROIN|ARMS cold_protection = CHEST|GROIN|ARMS + heat_protection = CHEST|GROIN|ARMS min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0) + max_heat_protection_temperature = COAT_MAX_TEMP_PROTECT + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON @@ -607,7 +679,9 @@ icon_state = "winterhood" body_parts_covered = HEAD cold_protection = HEAD + heat_protection = HEAD min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + max_heat_protection_temperature = COAT_MAX_TEMP_PROTECT flags_inv = HIDEHAIR|HIDEEARS rad_flags = RAD_NO_CONTAMINATE @@ -615,26 +689,26 @@ name = "centcom winter coat" icon_state = "coatcentcom" item_state = "coatcentcom" - armor = list("melee" = 40, "bullet" = 45, "laser" = 45, "energy" = 35, "bomb" = 40, "bio" = 25, "rad" = 25, "fire" = 35, "acid" = 50) + armor = list(MELEE = 40, BULLET = 45, LASER = 45, ENERGY = 35, BOMB = 40, BIO = 25, RAD = 25, FIRE = 35, ACID = 50) hoodtype = /obj/item/clothing/head/hooded/winterhood/centcom -/obj/item/clothing/suit/hooded/wintercoat/centcom/Initialize() +/obj/item/clothing/suit/hooded/wintercoat/centcom/Initialize(mapload) . = ..() allowed = GLOB.security_wintercoat_allowed /obj/item/clothing/head/hooded/winterhood/centcom icon_state = "winterhood_centcom" - armor = list("melee" = 40, "bullet" = 45, "laser" = 45, "energy" = 35, "bomb" = 40, "bio" = 25, "rad" = 25, "fire" = 35, "acid" = 50) + armor = list(MELEE = 40, BULLET = 45, LASER = 45, ENERGY = 35, BOMB = 40, BIO = 25, RAD = 25, FIRE = 35, ACID = 50) /obj/item/clothing/suit/hooded/wintercoat/captain name = "captain's winter coat" desc = "A luxurious winter coat, stuffed with the down of the endangered Uka bird and trimmed with genuine sable. The fabric is an indulgently soft micro-fiber, and the deep ultramarine color is only one that could be achieved with minute amounts of crystalline bluespace dust woven into the thread between the plectrums. Extremely lavish, and extremely durable. The tiny flakes of protective material make it nothing short of extremely light lamellar armor." icon_state = "coatcaptain" item_state = "coatcaptain" - armor = list("melee" = 25, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 25, BULLET = 30, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 0, ACID = 50) hoodtype = /obj/item/clothing/head/hooded/winterhood/captain -/obj/item/clothing/suit/hooded/wintercoat/captain/Initialize() +/obj/item/clothing/suit/hooded/wintercoat/captain/Initialize(mapload) . = ..() allowed = GLOB.security_wintercoat_allowed @@ -647,7 +721,7 @@ desc = "A cozy winter coat, covered in thick fur. The breast features a proud yellow chevron, reminding everyone that you're the second banana." icon_state = "coathop" item_state = "coathop" - armor = list("melee" = 5, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 5, "bio" = 5, "rad" = 0, "fire" = 0, "acid" = 5) + armor = list(MELEE = 5, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 5, BIO = 5, RAD = 0, FIRE = 0, ACID = 5) hoodtype = /obj/item/clothing/head/hooded/winterhood/hop /obj/item/clothing/head/hooded/winterhood/hop @@ -659,10 +733,10 @@ desc = "A red, armor-padded winter coat. It glitters with a mild ablative coating and a robust air of authority. The zipper tab is a pair of jingly little handcuffs that get annoying after the first ten seconds." icon_state = "coatsecurity" item_state = "coatsecurity" - armor = list("melee" = 25, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 45) + armor = list(MELEE = 25, BULLET = 15, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 0, ACID = 45) hoodtype = /obj/item/clothing/head/hooded/winterhood/security -/obj/item/clothing/suit/hooded/wintercoat/security/Initialize() +/obj/item/clothing/suit/hooded/wintercoat/security/Initialize(mapload) . = ..() allowed = GLOB.security_wintercoat_allowed @@ -675,10 +749,10 @@ desc = "A red, armor-padded winter coat, lovingly woven with a Kevlar interleave and reinforced with semi-ablative polymers and a silver azide fill material. The zipper tab looks like a tiny replica of Beepsky." icon_state = "coathos" item_state = "coathos" - armor = list("melee" = 35, "bullet" = 35, "laser" = 35, "energy" = 15, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 55) + armor = list(MELEE = 35, BULLET = 35, LASER = 35, ENERGY = 15, BOMB = 30, BIO = 0, RAD = 0, FIRE = 0, ACID = 55) hoodtype = /obj/item/clothing/head/hooded/winterhood/hos -/obj/item/clothing/suit/hooded/wintercoat/hos/Initialize() +/obj/item/clothing/suit/hooded/wintercoat/hos/Initialize(mapload) . = ..() allowed = GLOB.security_wintercoat_allowed @@ -692,7 +766,7 @@ icon_state = "coatmedical" item_state = "coatmedical" allowed = list(/obj/item/analyzer, /obj/item/sensor_device, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 0, "acid" = 45) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 50, RAD = 0, FIRE = 0, ACID = 45) hoodtype = /obj/item/clothing/head/hooded/winterhood/medical /obj/item/clothing/head/hooded/winterhood/medical @@ -705,7 +779,7 @@ icon_state = "coatcmo" item_state = "coatcmo" allowed = list(/obj/item/analyzer, /obj/item/sensor_device, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 5, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 50, RAD = 0, FIRE = 0, ACID = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/cmo /obj/item/clothing/head/hooded/winterhood/cmo @@ -718,7 +792,7 @@ icon_state = "coatchemistry" item_state = "coatchemistry" allowed = list(/obj/item/analyzer, /obj/item/sensor_device, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 30, "rad" = 0, "fire" = 30, "acid" = 45) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 30, RAD = 0, FIRE = 30, ACID = 45) hoodtype = /obj/item/clothing/head/hooded/winterhood/chemistry /obj/item/clothing/head/hooded/winterhood/chemistry @@ -731,7 +805,7 @@ icon_state = "coatviro" item_state = "coatviro" allowed = list(/obj/item/analyzer, /obj/item/sensor_device, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 30, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 30, RAD = 0, FIRE = 0, ACID = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/viro /obj/item/clothing/head/hooded/winterhood/viro @@ -744,7 +818,7 @@ icon_state = "coatparamed" item_state = "coatparamed" allowed = list(/obj/item/analyzer, /obj/item/sensor_device, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 0, "acid" = 45) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 50, RAD = 0, FIRE = 0, ACID = 45) hoodtype = /obj/item/clothing/head/hooded/winterhood/paramedic /obj/item/clothing/head/hooded/winterhood/paramedic @@ -757,7 +831,7 @@ icon_state = "coatscience" item_state = "coatscience" allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/science /obj/item/clothing/head/hooded/winterhood/science @@ -770,7 +844,7 @@ icon_state = "coatrobotics" item_state = "coatrobotics" allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/screwdriver, /obj/item/crowbar, /obj/item/wrench, /obj/item/stack/cable_coil, /obj/item/weldingtool, /obj/item/multitool) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/robotics /obj/item/clothing/head/hooded/winterhood/robotics @@ -795,7 +869,7 @@ icon_state = "coatrd" item_state = "coatrd" allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 5,"energy" = 0, "bomb" = 15, "bio" = 5, "rad" = 5, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 5,ENERGY = 0, BOMB = 15, BIO = 5, RAD = 5, FIRE = 0, ACID = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/rd /obj/item/clothing/head/hooded/winterhood/rd @@ -807,7 +881,7 @@ desc = "A white winter coat with reflective green and yellow stripes. Stuffed with asbestos, treated with fire retardant PBDE, lined with a micro thin sheet of lead foil and snugly fitted to your body's measurements. This baby's ready to save you from anything except the thyroid cancer and systemic fibrosis you'll get from wearing it. The zipper tab is a tiny golden wrench." icon_state = "coatce" item_state = "coatce" - armor = list("melee" = 0, "bullet" = 0, "laser" = 5, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 30, "fire" = 35, "acid" = 45) + armor = list(MELEE = 0, BULLET = 0, LASER = 5, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 30, FIRE = 35, ACID = 45) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) hoodtype = /obj/item/clothing/head/hooded/winterhood/ce @@ -820,7 +894,7 @@ desc = "A surprisingly heavy yellow winter coat with reflective orange stripes. It has a small wrench for its zipper tab, and the inside layer is covered with a radiation-resistant silver-nylon blend. Because you're worth it." icon_state = "coatengineer" item_state = "coatengineer" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 20, "fire" = 30, "acid" = 45) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 20, FIRE = 30, ACID = 45) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) hoodtype = /obj/item/clothing/head/hooded/winterhood/engineering @@ -927,7 +1001,7 @@ icon_state = "coatminer" item_state = "coatminer" allowed = list(/obj/item/pickaxe, /obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/miner /obj/item/clothing/head/hooded/winterhood/miner @@ -939,7 +1013,7 @@ desc = "A brass-plated button up winter coat. Instead of a zipper tab, it has a brass cog with a tiny red gemstone inset." icon_state = "coatratvar" item_state = "coatratvar" - armor = list("melee" = 30, "bullet" = 45, "laser" = -10, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) + armor = list(MELEE = 30, BULLET = 45, LASER = -10, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 60, ACID = 60) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/clockwork/replica_fabricator, /obj/item/clockwork/integration_cog, /obj/item/clockwork/slab, /obj/item/clockwork/weapon/ratvarian_spear) hoodtype = /obj/item/clothing/head/hooded/winterhood/ratvar var/real = TRUE @@ -953,7 +1027,7 @@ /obj/item/clothing/suit/hooded/wintercoat/ratvar/equipped(mob/living/user,slot) ..() - if (slot != SLOT_WEAR_SUIT || !real) + if (slot != ITEM_SLOT_OCLOTHING || !real) return if (is_servant_of_ratvar(user)) return @@ -968,14 +1042,14 @@ desc = "A somber button-up in tones of grey entropy and a wicked crimson zipper. When pulled all the way up, the zipper looks like a bloody gash. The zipper pull looks like a single drop of blood." icon_state = "coatnarsie" item_state = "coatnarsie" - armor = list("melee" = 30, "bullet" = 20, "laser" = 30,"energy" = 10, "bomb" = 30, "bio" = 10, "rad" = 10, "fire" = 30, "acid" = 30) + armor = list(MELEE = 30, BULLET = 20, LASER = 30,ENERGY = 10, BOMB = 30, BIO = 10, RAD = 10, FIRE = 30, ACID = 30) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/restraints/legcuffs/bola/cult,/obj/item/melee/cultblade,/obj/item/melee/cultblade/dagger,/obj/item/reagent_containers/glass/beaker/unholywater,/obj/item/cult_shift,/obj/item/flashlight/flare/culttorch,/obj/item/cult_spear) hoodtype = /obj/item/clothing/head/hooded/winterhood/narsie var/real = TRUE /obj/item/clothing/suit/hooded/wintercoat/narsie/equipped(mob/living/user,slot) ..() - if (slot != SLOT_WEAR_SUIT || !real) + if (slot != ITEM_SLOT_OCLOTHING || !real) return if (iscultist(user)) return @@ -995,7 +1069,7 @@ icon_state = "coatratvar" item_state = "coatratvar" allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) real = FALSE /obj/item/clothing/suit/hooded/wintercoat/narsie/fake @@ -1004,7 +1078,7 @@ icon_state = "coatnarsie" item_state = "coatnarsie" allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) real = FALSE /obj/item/clothing/suit/hooded/wintercoat/durathread @@ -1012,16 +1086,16 @@ desc = "The one coat to rule them all. Extremely durable while providing the utmost comfort." icon_state = "coatdurathread" item_state = "coatdurathread" - armor = list("melee" = 15, "bullet" = 8, "laser" = 25, "energy" = 5, "bomb" = 12, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 15, BULLET = 8, LASER = 25, ENERGY = 5, BOMB = 12, BIO = 0, RAD = 0, FIRE = 0, ACID = 50) hoodtype = /obj/item/clothing/head/hooded/winterhood/durathread -/obj/item/clothing/suit/hooded/wintercoat/durathread/Initialize() +/obj/item/clothing/suit/hooded/wintercoat/durathread/Initialize(mapload) . = ..() allowed = GLOB.security_wintercoat_allowed /obj/item/clothing/head/hooded/winterhood/durathread icon_state = "winterhood_durathread" - armor = list("melee" = 20, "bullet" = 8, "laser" = 15, "energy" = 8, "bomb" = 25, "bio" = 10, "rad" = 15, "fire" = 75, "acid" = 37) + armor = list(MELEE = 20, BULLET = 8, LASER = 15, ENERGY = 8, BOMB = 25, BIO = 10, RAD = 15, FIRE = 75, ACID = 37) /obj/item/clothing/suit/spookyghost name = "spooky ghost" @@ -1038,7 +1112,7 @@ icon = 'icons/obj/clothing/clockwork_garb.dmi' icon_state = "clockwork_cuirass_old" body_parts_covered = CHEST|GROIN|LEGS - armor = list("melee" = 5, "bullet" = 0, "laser" = -5, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 20) + armor = list(MELEE = 5, BULLET = 0, LASER = -5, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 20, ACID = 20) /obj/item/clothing/suit/ghost_sheet name = "ghost sheet" @@ -1078,7 +1152,7 @@ blood_overlay_type = "armor" body_parts_covered = CHEST resistance_flags = NONE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 5, "bio" = 0, "rad" = 0, "fire" = -5, "acid" = -15) //nylon sucks against acid + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 5, BIO = 0, RAD = 0, FIRE = -5, ACID = -15) //nylon sucks against acid mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON /obj/item/clothing/suit/assu_suit @@ -1182,3 +1256,132 @@ desc = "It looks like someone dragged this out of a muddy lake." icon_state = "bomberalt" item_state = "bomberalt" + +/obj/item/clothing/suit/driscoll + name = "driscoll poncho" + desc = "Keeping you warm in the harsh cold of space." + icon_state = "driscoll_suit" + item_state = "driscoll_suit" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/suit/irs + name = "internal revenue service jacket" + desc = "I'm crazy enough to take on The Owl, but the IRS? Nooo thank you!" + icon_state = "irs_suit" + item_state = "irs_suit" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/suit/osi + name = "\improper O.S.I. body armor" + desc = "You're beyond good and evil, super man. You work for the government. And you're a tool, boy, a tool! Built for a single purpose by the United States of shut your third fucking damn eye for a fucking reason! You can't teach a hammer to love nails, son. That dog don't hunt!" + icon_state = "osi_suit" + item_state = "osi_suit" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/suit/tmc + name = "\improper Lost M.C. cut" + desc = "Making sure everyone knows you're in the best biker gang this side of Alderney." + icon_state = "tmc_suit" + item_state = "tmc_suit" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/suit/pg + name = "powder ganger jacket" + desc = "Remind Security of their mistakes in giving prisoners blasting charges." + icon_state = "pg_suit" + item_state = "pg_suit" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/suit/deckers + name = "decker hoodie" + desc = "Based? Based on what?" + icon_state = "decker_suit" + item_state = "decker_suit" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/suit/morningstar + name = "morningstar coat" + desc = "This coat costs more than you've ever made in your entire life." + icon_state = "morningstar_suit" + item_state = "morningstar_suit" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/suit/saints + name = "Third Street Saints fur coat" + desc = "Rated 10 out of 10 in Cosmo for best coat brand." + icon_state = "saints_suit" + item_state = "saints_suit" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/suit/phantom + name = "phantom thief coat" + desc = "Your foes will never see you coming in this stealthy yet stylish getup." + icon_state = "phantom_suit" + item_state = "phantom_suit" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/suit/allies + name = "allies body armor" + desc = "How 'bout some action!? Sponsored by DonkSoft Co. for historical reenactment of the Third World War!" + icon_state = "allies_armor" + item_state = "allies_armor" + body_parts_covered = CHEST|GROIN + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/suit/soviet + name = "soviet armored coat" + desc = "Conscript reporting! Sponsored by DonkSoft Co. for historical reenactment of the Third World War!" + icon_state = "soviet_suit" + item_state = "soviet_suit" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/suit/yuri + name = "yuri initiate coat" + desc = "Yuri is master! Sponsored by DonkSoft Co. for historical reenactment of the Third World War!" + icon_state = "yuri_coat" + item_state = "yuri_coat" + body_parts_covered = CHEST|GROIN|ARMS + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/suit/sybil_slickers + name = "sybil slickers protective gear" + desc = "Given to members of the Sybil Slickers football team!" + icon_state = "football_armor_blue" + item_state = "football_armor_blue" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/suit/basil_boys + name = "basil boys protective gear" + desc = "Given to members of the Basil Boys football team!" + icon_state = "football_armor_red" + item_state = "football_armor_red" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/suit/yakuza + name = "tojo clan jacket" + desc = "The jacket of a mad dog." + icon_state = "MajimaJacket" + item_state = "MajimaJacket" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/suit/dutch + name = "dutch's jacket" + desc = "For those long nights on the beach in Tahiti." + icon_state = "DutchJacket" + item_state = "DutchJacket" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm index 98fb836c38..2f2c861b6b 100644 --- a/code/modules/clothing/suits/reactive_armour.dm +++ b/code/modules/clothing/suits/reactive_armour.dm @@ -33,7 +33,7 @@ icon_state = "reactiveoff" item_state = "reactiveoff" blood_overlay_type = "armor" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) actions_types = list(/datum/action/item_action/toggle) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE @@ -51,7 +51,7 @@ icon_state = "reactiveoff" item_state = "reactiveoff" add_fingerprint(user) - if(user.get_item_by_slot(SLOT_WEAR_SUIT) == src) + if(user.get_item_by_slot(ITEM_SLOT_OCLOTHING) == src) user.update_inv_wear_suit() /obj/item/clothing/suit/armor/reactive/emp_act(severity) @@ -177,7 +177,7 @@ /obj/item/clothing/suit/armor/reactive/tesla/equipped(mob/user, slot) ..() - if(slot_flags & slotdefine2slotbit(slot)) //Was equipped to a valid slot for this item? + if(slot_flags & slot) //Was equipped to a valid slot for this item? ADD_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "reactive_tesla_armor") /obj/item/clothing/suit/armor/reactive/tesla/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm index 4e29483846..25cbf27cf6 100644 --- a/code/modules/clothing/suits/toggles.dm +++ b/code/modules/clothing/suits/toggles.dm @@ -6,8 +6,9 @@ var/hoodtype = /obj/item/clothing/head/hooded/winterhood //so the chaplain hoodie or other hoodies can override this ///Alternative mode for hiding the hood, instead of storing the hood in the suit it qdels it, useful for when you deal with hooded suit with storage. var/alternative_mode = FALSE + var/no_t //do not update sprites when pulling up hood so we can avoid oddities with certain mechanics -/obj/item/clothing/suit/hooded/Initialize() +/obj/item/clothing/suit/hooded/Initialize(mapload) . = ..() hood = MakeHelmet() @@ -30,11 +31,11 @@ ToggleHood() /obj/item/clothing/suit/hooded/item_action_slot_check(slot, mob/user, datum/action/A) - if(slot == SLOT_WEAR_SUIT || slot == SLOT_NECK) + if(slot == ITEM_SLOT_OCLOTHING || slot == ITEM_SLOT_NECK) return 1 /obj/item/clothing/suit/hooded/equipped(mob/user, slot) - if(slot != SLOT_WEAR_SUIT && slot != SLOT_NECK) + if(slot != ITEM_SLOT_OCLOTHING && slot != ITEM_SLOT_NECK) RemoveHood() ..() @@ -51,6 +52,8 @@ update_icon() /obj/item/clothing/suit/hooded/update_icon_state() + if(no_t) + return icon_state = "[initial(icon_state)]" if(ishuman(hood?.loc)) var/mob/living/carbon/human/H = hood.loc @@ -77,7 +80,7 @@ if(H.head) to_chat(H, "You're already wearing something on your head!") return - else if(H.equip_to_slot_if_possible(hood,SLOT_HEAD,0,0,1)) + else if(H.equip_to_slot_if_possible(hood,ITEM_SLOT_HEAD,0,0,1)) suittoggled = TRUE update_icon() H.update_inv_wear_suit() @@ -99,7 +102,7 @@ /obj/item/clothing/head/hooded/equipped(mob/user, slot) ..() - if(slot != SLOT_HEAD) + if(slot != ITEM_SLOT_HEAD) if(suit) suit.RemoveHood() else @@ -143,7 +146,7 @@ . += "Alt-click on [src] to toggle the [togglename]." //Hardsuit toggle code -/obj/item/clothing/suit/space/hardsuit/Initialize() +/obj/item/clothing/suit/space/hardsuit/Initialize(mapload) . = ..() helmet = MakeHelmet() @@ -174,7 +177,7 @@ /obj/item/clothing/suit/space/hardsuit/equipped(mob/user, slot) if(!helmettype) return - if(slot != SLOT_WEAR_SUIT) + if(slot != ITEM_SLOT_OCLOTHING) RemoveHelmet() ..() @@ -219,7 +222,7 @@ if(message) to_chat(H, "You're already wearing something on your head!") return - else if(H.equip_to_slot_if_possible(helmet,SLOT_HEAD,0,0,1)) + else if(H.equip_to_slot_if_possible(helmet,ITEM_SLOT_HEAD,0,0,1)) if(message) to_chat(H, "You engage the helmet on the hardsuit.") suittoggled = TRUE diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 1f28c5ddf3..d58b88b773 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -20,7 +20,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/extinguisher, /obj/item/crowbar) slowdown = 1 - armor = list("melee" = 15, "bullet" = 5, "laser" = 20, "energy" = 10, "bomb" = 20, "bio" = 10, "rad" = 20, "fire" = 100, "acid" = 50) + armor = list(MELEE = 15, BULLET = 5, LASER = 20, ENERGY = 10, BOMB = 20, BIO = 10, RAD = 20, FIRE = 100, ACID = 50) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS @@ -62,7 +62,7 @@ desc = "Use in case of bomb." icon_state = "bombsuit" clothing_flags = THICKMATERIAL - armor = list("melee" = 20, "bullet" = 0, "laser" = 20,"energy" = 10, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50) + armor = list(MELEE = 20, BULLET = 0, LASER = 20,ENERGY = 10, BOMB = 100, BIO = 0, RAD = 0, FIRE = 80, ACID = 50) flags_inv = HIDEFACE|HIDEMASK|HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT dynamic_hair_suffix = "" dynamic_fhair_suffix = "" @@ -88,7 +88,7 @@ clothing_flags = THICKMATERIAL body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS slowdown = 2 - armor = list("melee" = 20, "bullet" = 0, "laser" = 20,"energy" = 10, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50) + armor = list(MELEE = 20, BULLET = 0, LASER = 20,ENERGY = 10, BOMB = 100, BIO = 0, RAD = 0, FIRE = 80, ACID = 50) flags_inv = HIDEJUMPSUIT|HIDETAUR heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT @@ -128,7 +128,7 @@ desc = "A hood with radiation protective properties. The label reads, 'Made with lead. Please do not consume insulation.'" clothing_flags = THICKMATERIAL flags_inv = HIDEMASK|HIDEEARS|HIDEFACE|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 60, "rad" = 100, "fire" = 30, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 60, RAD = 100, FIRE = 30, ACID = 30) strip_delay = 60 equip_delay_other = 60 flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH @@ -148,7 +148,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/geiger_counter) slowdown = 1.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 60, "rad" = 100, "fire" = 30, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 60, RAD = 100, FIRE = 30, ACID = 30) strip_delay = 60 equip_delay_other = 60 flags_inv = HIDEJUMPSUIT|HIDETAUR diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm index 977e916f87..0d8aa60ba5 100644 --- a/code/modules/clothing/suits/wiz_robe.dm +++ b/code/modules/clothing/suits/wiz_robe.dm @@ -4,7 +4,7 @@ icon_state = "wizard" gas_transfer_coefficient = 0.01 // IT'S MAGICAL OKAY JEEZ +1 TO NOT DIE permeability_coefficient = 0.01 - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100, "wound" = 20) + armor = list(MELEE = 30, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 20, BIO = 20, RAD = 20, FIRE = 100, ACID = 100, WOUND = 20) strip_delay = 50 equip_delay_other = 50 resistance_flags = FIRE_PROOF | ACID_PROOF @@ -41,7 +41,7 @@ icon_state = "wizard-fake" gas_transfer_coefficient = 1 permeability_coefficient = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) resistance_flags = FLAMMABLE magic_flags = NONE @@ -74,7 +74,7 @@ gas_transfer_coefficient = 0.01 permeability_coefficient = 0.01 body_parts_covered = CHEST|GROIN|ARMS|LEGS - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100, "wound" = 20) + armor = list(MELEE = 30, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 20, BIO = 20, RAD = 20, FIRE = 100, ACID = 100, WOUND = 20) allowed = list(/obj/item/teleportation_scroll) flags_inv = HIDEJUMPSUIT strip_delay = 50 @@ -140,21 +140,21 @@ icon_state = "wizard-fake" gas_transfer_coefficient = 1 permeability_coefficient = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) resistance_flags = FLAMMABLE magic_flags = NONE /obj/item/clothing/head/wizard/marisa/fake gas_transfer_coefficient = 1 permeability_coefficient = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) resistance_flags = FLAMMABLE magic_flags = NONE /obj/item/clothing/suit/wizrobe/marisa/fake gas_transfer_coefficient = 1 permeability_coefficient = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) resistance_flags = FLAMMABLE magic_flags = NONE @@ -167,7 +167,7 @@ actions_types = list(/datum/action/item_action/stickmen) /obj/item/clothing/suit/wizrobe/paper/item_action_slot_check(slot, mob/user, datum/action/A) - if(A.type == /datum/action/item_action/stickmen && slot != SLOT_WEAR_SUIT) + if(A.type == /datum/action/item_action/stickmen && slot != ITEM_SLOT_OCLOTHING) return FALSE return ..() @@ -274,8 +274,8 @@ if(isliving(A)) //Gettem boys! L = A else if(ismecha(A)) - var/obj/mecha/M = A - L = M.occupant + var/obj/vehicle/sealed/mecha/M = A + L = pick(M.occupants) if(L && L.stat != DEAD && !HAS_TRAIT(L, TRAIT_DEATHCOMA)) //Taking revenge on the deads would be proposterous. addtimer(CALLBACK(src, .proc/clear_grudge, L), 2 MINUTES, TIMER_OVERRIDE|TIMER_UNIQUE) if(!book_of_grudges[L]) @@ -309,7 +309,7 @@ min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/wizard - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100) + armor = list(MELEE = 30, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 20, BIO = 20, RAD = 20, FIRE = 100, ACID = 100) slowdown = 0 resistance_flags = FIRE_PROOF | ACID_PROOF @@ -324,7 +324,7 @@ item_state = "battlemage" min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100) + armor = list(MELEE = 30, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 20, BIO = 20, RAD = 20, FIRE = 100, ACID = 100) actions_types = null //No inbuilt light resistance_flags = FIRE_PROOF | ACID_PROOF diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index 59af632d2a..fc4cee1bed 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -5,7 +5,7 @@ permeability_coefficient = 0.9 block_priority = BLOCK_PRIORITY_UNIFORM slot_flags = ITEM_SLOT_ICLOTHING - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) mutantrace_variation = STYLE_DIGITIGRADE|USE_TAUR_CLIP_MASK limb_integrity = 120 var/fitted = FEMALE_UNIFORM_FULL // For use in alternate clothing styles for women @@ -20,7 +20,7 @@ var/alt_covers_chest = FALSE // for adjusted/rolled-down jumpsuits, FALSE = exposes chest and arms, TRUE = exposes arms only var/dummy_thick = FALSE // is able to hold accessories on its item var/obj/item/clothing/accessory/attached_accessory - var/mutable_appearance/accessory_overlay + var/list/accessory_overlays /obj/item/clothing/under/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE) . = ..() @@ -29,9 +29,9 @@ if(damaged_clothes) . += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform") if(blood_DNA) - . += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color()) - if(accessory_overlay) - . += accessory_overlay + . += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) + if(length(accessory_overlays)) + . += accessory_overlays /obj/item/clothing/under/attackby(obj/item/I, mob/user, params) if((sensordamage || (has_sensor < HAS_SENSORS && has_sensor != NO_SENSORS)) && istype(I, /obj/item/stack/cable_coil)) @@ -106,6 +106,10 @@ sensor_mode_intended = sensor_mode ..() +/obj/item/clothing/under/Initialize(mapload) + . = ..() + register_context() + /obj/item/clothing/under/equipped(mob/user, slot) ..() if(adjusted) @@ -114,7 +118,7 @@ if(!alt_covers_chest) body_parts_covered |= CHEST - if(attached_accessory && slot != SLOT_HANDS && ishuman(user)) + if(attached_accessory && slot != ITEM_SLOT_HANDS && ishuman(user)) var/mob/living/carbon/human/H = user attached_accessory.on_uniform_equip(src, user) if(attached_accessory.above_suit) @@ -154,9 +158,15 @@ if((flags_inv & HIDEACCESSORY) || (A.flags_inv & HIDEACCESSORY)) return TRUE - accessory_overlay = mutable_appearance('icons/mob/clothing/accessories.dmi', attached_accessory.icon_state) - accessory_overlay.alpha = attached_accessory.alpha - accessory_overlay.color = attached_accessory.color + var/datum/element/polychromic/polychromic = LAZYACCESS(attached_accessory.comp_lookup, "item_worn_overlays") + if(!polychromic) + var/mutable_appearance/accessory_overlay = mutable_appearance('icons/mob/clothing/accessories.dmi', attached_accessory.icon_state) + accessory_overlay.alpha = attached_accessory.alpha + accessory_overlay.color = attached_accessory.color + accessory_overlays = list(accessory_overlay) + else + accessory_overlays = list() + polychromic.apply_worn_overlays(I, FALSE, 'icons/mob/clothing/accessories.dmi', I.item_state || I.icon_state, NONE, accessory_overlays) if(ishuman(loc)) var/mob/living/carbon/human/H = loc @@ -354,5 +364,20 @@ return TRUE +/obj/item/clothing/under/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + if (!(item_flags & IN_INVENTORY)) + return + + if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return + + LAZYSET(context[SCREENTIP_CONTEXT_CTRL_LMB], INTENT_ANY, "Set to highest sensor") + if(attached_accessory) + LAZYSET(context[SCREENTIP_CONTEXT_ALT_LMB], INTENT_ANY, "Remove [attached_accessory]") + else + LAZYSET(context[SCREENTIP_CONTEXT_ALT_LMB], INTENT_ANY, "Adjust [src]") + return CONTEXTUAL_SCREENTIP_SET + /obj/item/clothing/under/rank dying_key = DYE_REGISTRY_UNDER diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index 40d30235d8..51a1868483 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -4,7 +4,8 @@ icon = 'icons/obj/clothing/accessories.dmi' icon_state = "plasma" item_state = "" //no inhands - slot_flags = 0 + slot_flags = ITEM_SLOT_ACCESSORY + slot_equipment_priority = list(ITEM_SLOT_ACCESSORY) w_class = WEIGHT_CLASS_SMALL var/above_suit = FALSE var/minimize_when_attached = TRUE // TRUE if shown as a small icon in corner, FALSE if overlayed @@ -57,7 +58,7 @@ plane = initial(plane) U.cut_overlays() U.attached_accessory = null - U.accessory_overlay = null + U.accessory_overlays = null /obj/item/clothing/accessory/proc/on_uniform_equip(obj/item/clothing/under/U, user) return @@ -65,7 +66,7 @@ /obj/item/clothing/accessory/proc/on_uniform_dropped(obj/item/clothing/under/U, user) return -/obj/item/clothing/accessory/AltClick(mob/user) +/obj/item/clothing/accessory/CtrlClick(mob/user) . = ..() if(istype(user) && user.canUseTopic(src, BE_CLOSE, ismonkey(user))) if(initial(above_suit)) @@ -77,7 +78,7 @@ . = ..() . += "\The [src] can be attached to a uniform. Alt-click to remove it once attached." if(initial(above_suit)) - . += "\The [src] can be worn above or below your suit. Alt-click to toggle." + . += "\The [src] can be worn above or below your suit. Ctrl-click to toggle." ////////////// //Waistcoats// @@ -255,6 +256,15 @@ item_state = "maidapron" minimize_when_attached = FALSE +/obj/item/clothing/accessory/maidapron/polychromic + name = "polychromic maid apron" + icon_state = "polymaidapron" + item_state = "polymaidapron" + +/obj/item/clothing/accessory/maidapron/polychromic/ComponentInitialize() + . = ..() + AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2) + /obj/item/clothing/accessory/sleevecrop name = "one sleeved crop top" desc = "Off the shoulder crop top, for those nights out partying." @@ -378,7 +388,7 @@ /obj/item/clothing/accessory/medal/gold/captain/family name = "old medal of captaincy" desc = "A rustic badge pure gold, has been through hell and back by the looks, the syndcate have been after these by the looks of it for generations..." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 10) //Pure gold + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 10) //Pure gold custom_materials = list(/datum/material/gold=2000) /obj/item/clothing/accessory/medal/gold/heroism @@ -390,7 +400,7 @@ desc = "An eccentric medal made of plasma." icon_state = "plasma" medaltype = "medal-plasma" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = -10, "acid" = 0) //It's made of plasma. Of course it's flammable. + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = -10, ACID = 0) //It's made of plasma. Of course it's flammable. custom_materials = list(/datum/material/plasma=1000) /obj/item/clothing/accessory/medal/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) @@ -480,13 +490,13 @@ icon_state = "pocketprotector" pocket_storage_component_path = /datum/component/storage/concrete/pockets/pocketprotector -/obj/item/clothing/accessory/pocketprotector/full/Initialize() +/obj/item/clothing/accessory/pocketprotector/full/Initialize(mapload) . = ..() new /obj/item/pen/red(src) new /obj/item/pen(src) new /obj/item/pen/blue(src) -/obj/item/clothing/accessory/pocketprotector/cosmetology/Initialize() +/obj/item/clothing/accessory/pocketprotector/cosmetology/Initialize(mapload) . = ..() for(var/i in 1 to 3) new /obj/item/lipstick/random(src) @@ -499,21 +509,21 @@ name = "bone talisman" desc = "A hunter's talisman, some say the old gods smile on those who wear it." icon_state = "talisman" - armor = list("melee" = 5, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25) + armor = list(MELEE = 5, BULLET = 5, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 20, RAD = 5, FIRE = 0, ACID = 25) /obj/item/clothing/accessory/skullcodpiece name = "skull codpiece" desc = "A skull shaped ornament, intended to protect the important things in life." icon_state = "skull" above_suit = TRUE - armor = list("melee" = 5, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25) + armor = list(MELEE = 5, BULLET = 5, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 20, RAD = 5, FIRE = 0, ACID = 25) /obj/item/clothing/accessory/skullcodpiece/fake name = "false codpiece" desc = "A plastic ornament, intended to protect the important things in life. It's not very good at it." icon_state = "skull" above_suit = TRUE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) ///////////////////// //Syndie Accessories// @@ -523,21 +533,21 @@ name = "protective padding" desc = "A soft padding meant to cushion the wearer from melee harm." icon_state = "padding" - armor = list("melee" = 20, "bullet" = 10, "laser" = 0, "energy" = 0, "bomb" = 5, "bio" = 0, "rad" = 0, "fire" = -20, "acid" = 45) + armor = list(MELEE = 20, BULLET = 10, LASER = 0, ENERGY = 0, BOMB = 5, BIO = 0, RAD = 0, FIRE = -20, ACID = 45) flags_inv = HIDEACCESSORY //hidden from indiscrete mob examines. /obj/item/clothing/accessory/kevlar name = "kevlar padding" desc = "A layered kevlar padding meant to cushion the wearer from ballistic harm." icon_state = "padding" - armor = list("melee" = 10, "bullet" = 20, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 25) + armor = list(MELEE = 10, BULLET = 20, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 0, ACID = 25) flags_inv = HIDEACCESSORY /obj/item/clothing/accessory/plastics name = "ablative padding" desc = "A thin ultra-refractory composite padding meant to cushion the wearer from energy lasers harm." icon_state = "plastics" - armor = list("melee" = 0, "bullet" = 0, "laser" = 20, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = -40) + armor = list(MELEE = 0, BULLET = 0, LASER = 20, ENERGY = 10, BOMB = 0, BIO = 0, RAD = 0, FIRE = 20, ACID = -40) flags_inv = HIDEACCESSORY //necklace @@ -548,3 +558,23 @@ obj_flags = UNIQUE_RENAME custom_materials = list(/datum/material/iron=100) resistance_flags = FIRE_PROOF + + +/obj/item/clothing/accessory/pride + name = "pride pin" + desc = "A Nanotrasen Diversity & Inclusion Center-sponsored holographic pin to show off your pride of sexuality or gender identity, reminding the crew of their unwavering commitment to equity, diversity, and inclusion!" + icon_state = "pride" + above_suit = TRUE + obj_flags = UNIQUE_RENAME + unique_reskin = list( + "Rainbow Pride" = list("icon_state" = "pride"), + "Bisexual Pride" = list("icon_state" = "pride_bi"), + "Pansexual Pride" = list("icon_state" = "pride_pan"), + "Asexual Pride" = list("icon_state" = "pride_ace"), + "Non-binary Pride" = list("icon_state" = "pride_enby"), + "Transgender Pride" = list("icon_state" = "pride_trans") + ) + +/obj/item/clothing/accessory/pride/reskin_obj(mob/M) + . = ..() + name = "[current_skin] pin" diff --git a/code/modules/clothing/under/cluwne.dm b/code/modules/clothing/under/cluwne.dm index 5a908c5663..572a2017e6 100644 --- a/code/modules/clothing/under/cluwne.dm +++ b/code/modules/clothing/under/cluwne.dm @@ -8,7 +8,7 @@ can_adjust = 0 mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON -/obj/item/clothing/under/cluwne/Initialize() +/obj/item/clothing/under/cluwne/Initialize(mapload) .=..() ADD_TRAIT(src, TRAIT_NODROP, CLOTHING_TRAIT) ADD_TRAIT(src, CURSED_ITEM_TRAIT, CLOTHING_TRAIT) @@ -16,7 +16,7 @@ /obj/item/clothing/under/cluwne/equipped(mob/living/carbon/user, slot) if(!ishuman(user)) return - if(slot == SLOT_W_UNIFORM) + if(slot == ITEM_SLOT_ICLOTHING) var/mob/living/carbon/human/H = user H.dna.add_mutation(CLUWNEMUT) return ..() diff --git a/code/modules/clothing/under/color.dm b/code/modules/clothing/under/color.dm index 824f026e8c..215be905aa 100644 --- a/code/modules/clothing/under/color.dm +++ b/code/modules/clothing/under/color.dm @@ -11,13 +11,13 @@ /obj/item/clothing/under/color/random icon_state = "random_jumpsuit" -/obj/item/clothing/under/color/random/Initialize() +/obj/item/clothing/under/color/random/Initialize(mapload) ..() var/obj/item/clothing/under/color/C = pick(subtypesof(/obj/item/clothing/under/color) - subtypesof(/obj/item/clothing/under/color/jumpskirt) - /obj/item/clothing/under/color/random - /obj/item/clothing/under/color/grey/glorf - /obj/item/clothing/under/color/black/ghost) if(ishuman(loc)) var/mob/living/carbon/human/H = loc - H.equip_to_slot_or_del(new C(H), SLOT_W_UNIFORM) //or else you end up with naked assistants running around everywhere... + H.equip_to_slot_or_del(new C(H), ITEM_SLOT_ICLOTHING) //or else you end up with naked assistants running around everywhere... else new C(loc) return INITIALIZE_HINT_QDEL @@ -25,12 +25,12 @@ /obj/item/clothing/under/color/jumpskirt/random icon_state = "random_jumpsuit" //Skirt variant needed -/obj/item/clothing/under/color/jumpskirt/random/Initialize() +/obj/item/clothing/under/color/jumpskirt/random/Initialize(mapload) ..() var/obj/item/clothing/under/color/jumpskirt/C = pick(subtypesof(/obj/item/clothing/under/color/jumpskirt) - /obj/item/clothing/under/color/jumpskirt/random) if(ishuman(loc)) var/mob/living/carbon/human/H = loc - H.equip_to_slot_or_del(new C(H), SLOT_W_UNIFORM) + H.equip_to_slot_or_del(new C(H), ITEM_SLOT_ICLOTHING) else new C(loc) return INITIALIZE_HINT_QDEL @@ -54,11 +54,11 @@ /obj/item/clothing/under/color/black/ghost item_flags = DROPDEL -/obj/item/clothing/under/color/black/ghost/Initialize() +/obj/item/clothing/under/color/black/ghost/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) -/obj/item/clothing/under/color/black/ghost/Initialize() +/obj/item/clothing/under/color/black/ghost/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, DROPDEL) /obj/item/clothing/under/color/grey diff --git a/code/modules/clothing/under/costume.dm b/code/modules/clothing/under/costume.dm index 4e5be1306c..50da2d79c8 100644 --- a/code/modules/clothing/under/costume.dm +++ b/code/modules/clothing/under/costume.dm @@ -85,7 +85,7 @@ /obj/item/clothing/under/costume/kilt/highlander desc = "You're the only one worthy of this kilt." -/obj/item/clothing/under/costume/kilt/highlander/Initialize() +/obj/item/clothing/under/costume/kilt/highlander/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, HIGHLANDER) @@ -125,7 +125,7 @@ can_adjust = FALSE mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON -/obj/item/clothing/under/costume/maid/Initialize() +/obj/item/clothing/under/costume/maid/Initialize(mapload) . = ..() var/obj/item/clothing/accessory/maidapron/A = new (src) attach_accessory(A) @@ -282,7 +282,7 @@ can_adjust = FALSE fitted = FEMALE_UNIFORM_TOP mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON - + /obj/item/clothing/under/costume/qipao/white name = "White Qipao" @@ -356,9 +356,131 @@ icon_state = "sakura_kimono" item_state = "sakura_kimono" +/obj/item/clothing/under/costume/irs + name = "internal revenue service outfit" + icon_state = "irs_jumpsuit" + item_state = "irs_jumpsuit" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/costume/osi + name = "O.S.I. jumpsuit" + icon_state = "osi_jumpsuit" + item_state = "osi_jumpsuit" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/costume/tmc + name = "Lost MC clothing" + icon_state = "tmc_jumpsuit" + item_state = "tmc_jumpsuit" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/costume/pg + name = "powder ganger prison jumpsuit" + icon_state = "pg_jumpsuit" + item_state = "pg_jumpsuit" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/costume/driscoll + name = "O'Driscoll outfit" + icon_state = "driscoll_jumpsuit" + item_state = "driscoll_jumpsuit" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/costume/deckers + name = "deckers outfit" + icon_state = "decker_jumpsuit" + item_state = "decker_jumpsuit" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/costume/morningstar + name = "Morningstar suit" + icon_state = "morningstar_jumpsuit" + item_state = "morningstar_jumpsuit" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/costume/saints + name = "Saints outfit" + icon_state = "saints_jumpsuit" + item_state = "saints_jumpsuit" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/costume/phantom + name = "Phantom Thief outfit" + icon_state = "phantom_jumpsuit" + item_state = "phantom_jumpsuit" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/costume/allies + name = "allies tanktop" + icon_state = "allies_uniform" + item_state = "allies_uniform" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/costume/soviet_families + name = "soviet conscript uniform" + icon_state = "soviet_uniform" + item_state = "soviet_uniform" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/costume/yuri + name = "yuri initiate jumpsuit" + icon_state = "yuri_uniform" + item_state = "yuri_uniform" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/costume/sybil_slickers + name = "sybil slickers uniform" + icon_state = "football_blue" + item_state = "football_blue" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/costume/basil_boys + name = "basil boys uniform" + icon_state = "football_red" + item_state = "football_red" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + /obj/item/clothing/under/costume/swagoutfit name = "Swag outfit" desc = "Why don't you go secure some bitches?" icon_state = "SwagOutfit" item_state = "SwagOutfit" can_adjust = FALSE + +/obj/item/clothing/under/costume/jackbros + name = "jack bros outfit" + desc = "For when it's time to hee some hos." + icon_state = "JackFrostUniform" + item_state = "JackFrostUniform" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/costume/yakuza + name = "tojo clan pants" + desc = "For those long nights under the traffic cone." + icon_state = "MajimaPants" + item_state = "MajimaPants" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/costume/dutch + name = "dutch's suit" + desc = "You can feel a god damn plan coming on." + icon_state = "DutchUniform" + item_state = "DutchUniform" + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON diff --git a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm index 885e659bb2..82924b850d 100644 --- a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm +++ b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm @@ -57,7 +57,7 @@ desc = "An expensive piece of plasmaman envirosuit fashion. guaranteed to keep you cool while the station goes down in fierceful fires." icon_state = "captain_envirosuit" item_state = "captain_envirosuit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95, "wound" = 15) + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 0, FIRE = 95, ACID = 95, WOUND = 15) sensor_mode = SENSOR_COORDS sensor_flags = NONE diff --git a/code/modules/clothing/under/jobs/Plasmaman/engineering.dm b/code/modules/clothing/under/jobs/Plasmaman/engineering.dm index 4850a605e7..68d1ab30e1 100644 --- a/code/modules/clothing/under/jobs/Plasmaman/engineering.dm +++ b/code/modules/clothing/under/jobs/Plasmaman/engineering.dm @@ -3,7 +3,7 @@ desc = "An air-tight suit designed to be used by plasmamen exployed as engineers, the usual purple stripes being replaced by engineer's orange. It protects the user from fire and acid damage." icon_state = "engineer_envirosuit" item_state = "engineer_envirosuit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 10, "fire" = 95, "acid" = 95, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 10, FIRE = 95, ACID = 95, WOUND = 5) /obj/item/clothing/under/plasmaman/engineering/ce name = "chief engineer's plasma envirosuit" diff --git a/code/modules/clothing/under/jobs/Plasmaman/medsci.dm b/code/modules/clothing/under/jobs/Plasmaman/medsci.dm index 52f817dcce..e77021646a 100644 --- a/code/modules/clothing/under/jobs/Plasmaman/medsci.dm +++ b/code/modules/clothing/under/jobs/Plasmaman/medsci.dm @@ -21,7 +21,7 @@ desc = "A plasmaman envirosuit designed for the research director to aid them in their job of directing research into the right direction." icon_state = "rd_envirosuit" item_state = "rd_envirosuit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 100, RAD = 0, FIRE = 95, ACID = 95, WOUND = 5) /obj/item/clothing/under/plasmaman/robotics name = "robotics plasma envirosuit" diff --git a/code/modules/clothing/under/jobs/Plasmaman/security.dm b/code/modules/clothing/under/jobs/Plasmaman/security.dm index c9b7b494a3..01a1effa14 100644 --- a/code/modules/clothing/under/jobs/Plasmaman/security.dm +++ b/code/modules/clothing/under/jobs/Plasmaman/security.dm @@ -3,7 +3,7 @@ desc = "A plasmaman containment suit designed for security officers, offering a limited amount of extra protection." icon_state = "security_envirosuit" item_state = "security_envirosuit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95, "wound" = 10) + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 0, FIRE = 95, ACID = 95, WOUND = 10) sensor_mode = SENSOR_COORDS sensor_flags = NONE @@ -18,3 +18,9 @@ desc = "A slick black and red plasmaman containment suit designed for the head of security, also called the LAW." icon_state = "hos_envirosuit" item_state = "hos_envirosuit" + +/obj/item/clothing/under/plasmaman/prisoner + name = "prisoner envirosuit" + desc = "An orange envirosuit identifying and protecting a criminal plasmaman." + icon_state = "prisoner_envirosuit" + item_state = "prisoner_envirosuit" diff --git a/code/modules/clothing/under/jobs/cargo.dm b/code/modules/clothing/under/jobs/cargo.dm index 832589a6b7..9f7a7fdd7f 100644 --- a/code/modules/clothing/under/jobs/cargo.dm +++ b/code/modules/clothing/under/jobs/cargo.dm @@ -51,7 +51,7 @@ /obj/item/clothing/under/rank/cargo/miner name = "shaft miner's jumpsuit" desc = "It's a snappy jumpsuit with a sturdy set of overalls. It is very dirty." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 0, "wound" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 0, WOUND = 10) icon_state = "miner" item_state = "miner" diff --git a/code/modules/clothing/under/jobs/civilian/civilian.dm b/code/modules/clothing/under/jobs/civilian/civilian.dm index 2eabb0ce35..13f9a1fa75 100644 --- a/code/modules/clothing/under/jobs/civilian/civilian.dm +++ b/code/modules/clothing/under/jobs/civilian/civilian.dm @@ -178,7 +178,7 @@ desc = "It's the official uniform of the station's janitor. It has minor protection from biohazards." name = "janitor's jumpsuit" icon_state = "janitor" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/rank/civilian/janitor/skirt name = "janitor's jumpskirt" diff --git a/code/modules/clothing/under/jobs/civilian/clown_mime.dm b/code/modules/clothing/under/jobs/civilian/clown_mime.dm index 470a3695fc..cf4d7672ce 100644 --- a/code/modules/clothing/under/jobs/civilian/clown_mime.dm +++ b/code/modules/clothing/under/jobs/civilian/clown_mime.dm @@ -32,6 +32,20 @@ can_adjust = FALSE mutantrace_variation = STYLE_DIGITIGRADE //The clown suit must look funny, no taur alpha masks where possible. +/obj/item/clothing/under/rank/civilian/polychromic_clown + name = "polychromic clown suit" + desc = "'HONK!'" + icon_state = "clown" + item_state = "clown" + fitted = FEMALE_UNIFORM_TOP + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE //The clown suit must look funny, no taur alpha masks where possible. + var/list/poly_colors = list("#FF0000", "#FF99FF", "#FFFF00", "#FFFFFF") + +/obj/item/clothing/under/rank/civilian/polychromic_clown/ComponentInitialize() + . = ..() + AddElement(/datum/element/polychromic, poly_colors, 4) + /obj/item/clothing/under/rank/civilian/clown/blue name = "blue clown suit" desc = "'BLUE HONK!'" @@ -104,6 +118,6 @@ can_adjust = FALSE mutantrace_variation = STYLE_DIGITIGRADE|USE_TAUR_CLIP_MASK -/obj/item/clothing/under/rank/civilian/clown/Initialize() +/obj/item/clothing/under/rank/civilian/clown/Initialize(mapload) . = ..() AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50) diff --git a/code/modules/clothing/under/jobs/command.dm b/code/modules/clothing/under/jobs/command.dm index 1d4425bc82..2c70d8bcc8 100644 --- a/code/modules/clothing/under/jobs/command.dm +++ b/code/modules/clothing/under/jobs/command.dm @@ -3,7 +3,7 @@ name = "captain's jumpsuit" icon_state = "captain" item_state = "b_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 15) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, WOUND = 15) sensor_mode = SENSOR_COORDS sensor_flags = NONE @@ -53,5 +53,5 @@ desc = "An ironically skimpy blue dress with gold markings denoting the rank of \"Captain\"." icon_state = "lewdcap" item_state = "lewdcap" - can_adjust = FALSE + alt_covers_chest = TRUE mutantrace_variation = STYLE_DIGITIGRADE|USE_TAUR_CLIP_MASK diff --git a/code/modules/clothing/under/jobs/engineering.dm b/code/modules/clothing/under/jobs/engineering.dm index 98dee44cb2..44bb8ca1dd 100644 --- a/code/modules/clothing/under/jobs/engineering.dm +++ b/code/modules/clothing/under/jobs/engineering.dm @@ -4,7 +4,7 @@ name = "chief engineer's jumpsuit" icon_state = "chiefengineer" item_state = "gy_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 80, "acid" = 40, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 10, FIRE = 80, ACID = 40, WOUND = 5) resistance_flags = NONE /obj/item/clothing/under/rank/engineering/chief_engineer/skirt @@ -39,7 +39,7 @@ name = "engineer's jumpsuit" icon_state = "engine" item_state = "engi_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 60, "acid" = 20, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 10, FIRE = 60, ACID = 20, WOUND = 5) resistance_flags = NONE /obj/item/clothing/under/rank/engineering/engineer/mechanic diff --git a/code/modules/clothing/under/jobs/medical.dm b/code/modules/clothing/under/jobs/medical.dm index 20fd34f4a0..48f3be3597 100644 --- a/code/modules/clothing/under/jobs/medical.dm +++ b/code/modules/clothing/under/jobs/medical.dm @@ -4,7 +4,7 @@ icon_state = "cmo" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/rank/medical/chief_medical_officer/skirt name = "chief medical officer's jumpskirt" @@ -30,7 +30,7 @@ icon_state = "genetics" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/rank/medical/geneticist/skirt name = "geneticist's jumpskirt" @@ -48,7 +48,7 @@ icon_state = "virology" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/rank/medical/virologist/skirt name = "virologist's jumpskirt" @@ -66,7 +66,7 @@ icon_state = "chemistry" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 65, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 50, ACID = 65, WOUND = 5) /obj/item/clothing/under/rank/medical/chemist/skirt name = "chemist's jumpskirt" @@ -84,7 +84,7 @@ icon_state = "paramedic-dark" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/rank/medical/paramedic/red name = "red paramedic jumpsuit" @@ -116,7 +116,7 @@ icon_state = "nursesuit" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) body_parts_covered = CHEST|GROIN|ARMS fitted = NO_FEMALE_UNIFORM can_adjust = FALSE @@ -128,7 +128,7 @@ icon_state = "medical" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/rank/medical/doctor/util name = "medical utility uniform" diff --git a/code/modules/clothing/under/jobs/rnd.dm b/code/modules/clothing/under/jobs/rnd.dm index d63e81a0a3..e8265aa4e9 100644 --- a/code/modules/clothing/under/jobs/rnd.dm +++ b/code/modules/clothing/under/jobs/rnd.dm @@ -3,7 +3,7 @@ name = "research director's vest suit" icon_state = "director" item_state = "lb_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 35, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 10, BIO = 10, RAD = 0, FIRE = 0, ACID = 35, WOUND = 5) can_adjust = FALSE /obj/item/clothing/under/rank/rnd/research_director/skirt @@ -20,7 +20,7 @@ name = "research director's tan suit" icon_state = "rdwhimsy" item_state = "rdwhimsy" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) can_adjust = TRUE alt_covers_chest = TRUE @@ -39,7 +39,7 @@ name = "research director's turtleneck" icon_state = "rdturtle" item_state = "p_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) can_adjust = TRUE alt_covers_chest = TRUE @@ -59,7 +59,7 @@ icon_state = "toxins" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/rank/rnd/scientist/util name = "science utility uniform" diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm index 0b1fb99bf8..e918cf9507 100644 --- a/code/modules/clothing/under/jobs/security.dm +++ b/code/modules/clothing/under/jobs/security.dm @@ -19,7 +19,7 @@ desc = "A tactical security jumpsuit for officers complete with Nanotrasen belt buckle." icon_state = "rsecurity" item_state = "r_suit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 30, ACID = 30, WOUND = 10) /obj/item/clothing/under/rank/security/officer/util name = "security utility uniform" @@ -40,10 +40,19 @@ icon_state = "secskirt" item_state = "r_suit" body_parts_covered = CHEST|GROIN|ARMS - can_adjust = FALSE //you know now that i think of it if you adjust the skirt and the sprite disappears isn't that just like flashing everyone + alt_covers_chest = TRUE fitted = FEMALE_UNIFORM_TOP mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON +/obj/item/clothing/under/rank/security/stripper + name = "secukini" + icon_state = "secukini" + item_state = "secukini" + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, WOUND = 0) //exchange powergame in order to be a whore what are you going to do about it + body_parts_covered = CHEST|GROIN + can_adjust = FALSE + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + /obj/item/clothing/under/rank/security/officer/formal name = "security officer's formal uniform" desc = "The latest in fashionable security outfits." @@ -96,7 +105,7 @@ desc = "A formal security suit for officers complete with Nanotrasen belt buckle." icon_state = "rwarden" item_state = "r_suit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 30, ACID = 30, WOUND = 10) /obj/item/clothing/under/rank/security/warden/grey name = "grey security suit" @@ -130,7 +139,7 @@ desc = "Someone who wears this means business." icon_state = "detective" item_state = "det" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 30, ACID = 30, WOUND = 10) /obj/item/clothing/under/rank/security/detective/brown name = "dark boiled suit" @@ -177,7 +186,7 @@ desc = "A security jumpsuit decorated for those few with the dedication to achieve the position of Head of Security." icon_state = "rhos" item_state = "r_suit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50, WOUND = 10) strip_delay = 60 /obj/item/clothing/under/rank/security/head_of_security/skirt @@ -242,3 +251,10 @@ icon_state = "spacepol" item_state = "spacepol" can_adjust = FALSE + +/obj/item/clothing/under/rank/security/officer/beatcop + name = "space police uniform" + desc = "A police uniform often found in the lines at donut shops." + icon_state = "spacepolice_families" + item_state = "spacepolice_families" + can_adjust = FALSE diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 4dac5f1961..2071dd6930 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -65,7 +65,7 @@ gas_transfer_coefficient = 0.01 permeability_coefficient = 0.01 body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list("melee" = 100, "bullet" = 100, "laser" = 100,"energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 1000) //wound defense at 100 wont stop wounds + armor = list(MELEE = 100, BULLET = 100, LASER = 100,ENERGY = 100, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 1000) //wound defense at 100 wont stop wounds cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS @@ -116,7 +116,7 @@ desc = "A special containment suit that allows plasma-based lifeforms to exist safely in an oxygenated environment, and automatically extinguishes them in a crisis. Despite being airtight, it's not spaceworthy." icon_state = "plasmaman" item_state = "plasmaman" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 0, FIRE = 95, ACID = 95) body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS mutantrace_variation = USE_TAUR_CLIP_MASK can_adjust = FALSE @@ -186,7 +186,7 @@ icon_state = "durathread" item_state = "durathread" can_adjust = TRUE - armor = list("melee" = 10, "laser" = 10, "fire" = 40, "acid" = 10, "bomb" = 5) + armor = list(MELEE = 10, LASER = 10, FIRE = 40, ACID = 10, BOMB = 5) /obj/item/clothing/under/misc/durathread/skirt name = "durathread jumpskirt" diff --git a/code/modules/clothing/under/pants.dm b/code/modules/clothing/under/pants.dm index a76bf41e62..79434bfbd7 100644 --- a/code/modules/clothing/under/pants.dm +++ b/code/modules/clothing/under/pants.dm @@ -46,14 +46,14 @@ desc = "Some tan pants. You look like a white collar worker with these on." icon_state = "tanpants" -/obj/item/clothing/under/pants/polypants/polychromic +/obj/item/clothing/under/pants/polypants name = "polychromic pants" desc = "Some stylish pair of pants made from polychrome." icon_state = "polypants" item_state = "polypants" var/list/poly_colors = list("#75634F", "#3D3D3D", "#575757") -/obj/item/clothing/under/pants/polypants/polychromic/ComponentInitialize() +/obj/item/clothing/under/pants/polypants/ComponentInitialize() . = ..() AddElement(/datum/element/polychromic, poly_colors, 3) diff --git a/code/modules/clothing/under/shorts.dm b/code/modules/clothing/under/shorts.dm index 426e0e28d9..910af84f1f 100644 --- a/code/modules/clothing/under/shorts.dm +++ b/code/modules/clothing/under/shorts.dm @@ -43,6 +43,13 @@ . = ..() AddElement(/datum/element/polychromic, poly_colors, 2) +/obj/item/clothing/under/shorts/polychromic/polyworkout + name = "polychromatic workout shorts" + desc = "Unnaturally scanty and provocative for anyone with a posterior larger than your average malnourished station secretary." + icon_state = "workout" + item_state = "rainbow" + poly_colors = list("#323232", "#FFFFFF") + /obj/item/clothing/under/shorts/polychromic/pantsu name = "polychromic panties" desc = "Topless striped panties. Now with 120% more polychrome!" @@ -50,5 +57,4 @@ item_state = "rainbow" body_parts_covered = GROIN mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON - poly_colors = list("#FFFFFF", "#8CC6FF") diff --git a/code/modules/clothing/under/suits.dm b/code/modules/clothing/under/suits.dm index 7f0ecf3d70..8898696668 100644 --- a/code/modules/clothing/under/suits.dm +++ b/code/modules/clothing/under/suits.dm @@ -111,6 +111,25 @@ body_parts_covered = CHEST|GROIN can_adjust = FALSE + +/obj/item/clothing/under/suit/beige + name = "beige suit" + desc = "An excellent light colored suit, experts in the field stress that it should not to be confused with the inferior tan suit." + icon_state = "beige_suit" + item_state = "beige_suit" + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/under/suit/henchmen + name = "henchmen jumpsuit" + desc = "A very gaudy jumpsuit for a proper Henchman. Guild regulations, you understand." + icon = 'icons/obj/clothing/uniforms.dmi' + mob_overlay_icon = 'icons/mob/clothing/uniform.dmi' + icon_state = "henchmen" + item_state = "henchmen" + body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS|HEAD + flags_inv = HIDEGLOVES|HIDESHOES|HIDEEARS|HIDEEYES|HIDEHAIR|HIDETAUR + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON + /obj/item/clothing/under/suit/polychromic //enables all three overlays to reduce copypasta and defines basic stuff name = "polychromic suit" desc = "For when you want to show off your horrible colour coordination skills." diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm index 58d5d26e86..a2bd8256d7 100644 --- a/code/modules/clothing/under/syndicate.dm +++ b/code/modules/clothing/under/syndicate.dm @@ -4,7 +4,7 @@ icon_state = "syndicate" item_state = "bl_suit" has_sensor = NO_SENSORS - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 5) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 40, WOUND = 5) alt_covers_chest = TRUE /obj/item/clothing/under/syndicate/skirt @@ -13,7 +13,7 @@ icon_state = "syndicate_skirt" item_state = "bl_suit" has_sensor = NO_SENSORS - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 5) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 40, WOUND = 5) alt_covers_chest = TRUE fitted = FEMALE_UNIFORM_TOP mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON @@ -24,7 +24,7 @@ icon_state = "bloodred_pajamas" item_state = "bl_suit" dummy_thick = TRUE - armor = list("melee" = 10, "bullet" = 10, "laser" = 10,"energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 50, "acid" = 40, "wound" = 10) + armor = list(MELEE = 10, BULLET = 10, LASER = 10,ENERGY = 10, BOMB = 0, BIO = 0, RAD = 10, FIRE = 50, ACID = 40, WOUND = 10) resistance_flags = FIRE_PROOF | ACID_PROOF can_adjust = FALSE @@ -33,21 +33,21 @@ desc = "Do operatives dream of nuclear sheep?" icon_state = "bloodred_pajamas" item_state = "bl_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 40, WOUND = 5) /obj/item/clothing/under/syndicate/tacticool name = "tacticool turtleneck" desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-." icon_state = "tactifool" item_state = "bl_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 40, WOUND = 5) /obj/item/clothing/under/syndicate/tacticool/skirt name = "tacticool skirtleneck" desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-." icon_state = "tactifool_skirt" item_state = "bl_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 40, WOUND = 5) fitted = FEMALE_UNIFORM_TOP mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON @@ -57,7 +57,7 @@ icon_state = "tactifool" item_state = "bl_suit" has_sensor = HAS_SENSORS - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/syndicate/cosmetic/skirt name = "tactitool skirtleneck" @@ -81,14 +81,14 @@ can_adjust = FALSE /obj/item/clothing/under/syndicate/camo/cosmetic - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/under/syndicate/soviet name = "Ratnik 5 tracksuit" desc = "Badly translated labels tell you to clean this in Vodka. Great for squatting in." icon_state = "trackpants" can_adjust = FALSE - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) resistance_flags = NONE /obj/item/clothing/under/syndicate/combat @@ -103,7 +103,7 @@ desc = "Military grade tracksuits for frontline squatting." icon_state = "rus_under" can_adjust = FALSE - armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 5, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) resistance_flags = NONE mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON @@ -113,7 +113,7 @@ icon_state = "syndicatebaseball" item_state = "syndicatebaseball" has_sensor = NO_SENSORS - armor = list("melee" = 15, "bullet" = 5, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 10) + armor = list(MELEE = 15, BULLET = 5, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 40, WOUND = 10) alt_covers_chest = TRUE mutantrace_variation = USE_TAUR_CLIP_MASK diff --git a/code/modules/clothing/under/trek.dm b/code/modules/clothing/under/trek.dm index 89e42d2566..d86e32b1f6 100644 --- a/code/modules/clothing/under/trek.dm +++ b/code/modules/clothing/under/trek.dm @@ -108,7 +108,7 @@ /obj/item/clothing/under/trek/sec/orv desc = "An uniform worn by security officers since 2420s." - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 30, ACID = 30, WOUND = 10) icon_state = "orv_sec" /obj/item/clothing/under/trek/medsci/orv @@ -129,7 +129,7 @@ /obj/item/clothing/under/trek/command/orv/sec name = "security command uniform" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50, WOUND = 10) desc = "An uniform worn by Heads of Security since 2550s." icon_state = "orv_com_sec" diff --git a/code/modules/economy/account.dm b/code/modules/economy/account.dm index e8b6498c36..18fdfd2667 100644 --- a/code/modules/economy/account.dm +++ b/code/modules/economy/account.dm @@ -10,6 +10,9 @@ var/account_id var/being_dumped = FALSE //pink levels are rising var/withdrawDelay = 0 + var/datum/bounty/civilian_bounty + var/list/datum/bounty/bounties + COOLDOWN_DECLARE(bounty_timer) /datum/bank_account/New(newname, job) if(add_to_accounts) @@ -100,6 +103,47 @@ if(M.can_hear()) to_chat(M, "[icon2html(icon_source, M)] [message]") +/** + * Returns a string with the civilian bounty's description on it. + */ +/datum/bank_account/proc/bounty_text() + if(!civilian_bounty) + return FALSE + if(istype(civilian_bounty, /datum/bounty/item)) + var/datum/bounty/item/item = civilian_bounty + return item.description + if(istype(civilian_bounty, /datum/bounty/reagent)) + var/datum/bounty/reagent/chemical = civilian_bounty + return chemical.description + +/** + * Returns the required item count, or required chemical units required to submit a bounty. + */ +/datum/bank_account/proc/bounty_num() + if(!civilian_bounty) + return FALSE + if(istype(civilian_bounty, /datum/bounty/item)) + var/datum/bounty/item/item = civilian_bounty + return "[item.shipped_count]/[item.required_count]" + if(istype(civilian_bounty, /datum/bounty/reagent)) + var/datum/bounty/reagent/chemical = civilian_bounty + return "[chemical.shipped_volume]/[chemical.required_volume] u" + +/** + * Produces the value of the account's civilian bounty reward, if able. + */ +/datum/bank_account/proc/bounty_value() + if(!civilian_bounty) + return FALSE + return civilian_bounty.reward + +/** + * Performs house-cleaning on variables when a civilian bounty is replaced, or, when a bounty is claimed. + */ +/datum/bank_account/proc/reset_bounty() + civilian_bounty = null + COOLDOWN_RESET(src, bounty_timer) + /datum/bank_account/department account_holder = "Guild Credit Agency" var/department_id = "REPLACE_ME" diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index 6a3d2c2233..834f5051c2 100644 --- a/code/modules/error_handler/error_handler.dm +++ b/code/modules/error_handler/error_handler.dm @@ -64,11 +64,11 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0) configured_error_silence_time = CONFIG_GET(number/error_silence_time) else var/datum/config_entry/CE = /datum/config_entry/number/error_cooldown - configured_error_cooldown = initial(CE.config_entry_value) + configured_error_cooldown = initial(CE.default) CE = /datum/config_entry/number/error_limit - configured_error_limit = initial(CE.config_entry_value) + configured_error_limit = initial(CE.default) CE = /datum/config_entry/number/error_silence_time - configured_error_silence_time = initial(CE.config_entry_value) + configured_error_silence_time = initial(CE.default) //Each occurence of a unique error adds to its cooldown time... diff --git a/code/modules/error_handler/error_viewer.dm b/code/modules/error_handler/error_viewer.dm index 9ac65d26fb..b88437edef 100644 --- a/code/modules/error_handler/error_viewer.dm +++ b/code/modules/error_handler/error_viewer.dm @@ -122,7 +122,7 @@ GLOBAL_DATUM(error_cache, /datum/error_viewer/error_cache) err_msg_delay = CONFIG_GET(number/error_msg_delay) else var/datum/config_entry/CE = /datum/config_entry/number/error_msg_delay - err_msg_delay = initial(CE.config_entry_value) + err_msg_delay = initial(CE.default) error_source.next_message_at = world.time + err_msg_delay /datum/error_viewer/error_source diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 10f8c60386..d8c7af788f 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -1,6 +1,10 @@ +#define RANDOM_EVENT_ADMIN_INTERVENTION_TIME 30 + //this datum is used by the events controller to dictate how it selects events /datum/round_event_control var/name //The human-readable name of the event + var/category //The category of the event + var/description //The description of the event var/typepath //The typepath of the event datum /datum/round_event var/weight = 10 //The weight this event has in the random-selection process. @@ -27,12 +31,16 @@ var/triggering //admin cancellation + /// Whether or not dynamic should hijack this event + var/dynamic_should_hijack = FALSE + /datum/round_event_control/New() if(config && !wizardevent) // Magic is unaffected by configs earliest_start = CEILING(earliest_start * CONFIG_GET(number/events_min_time_mul), 1) min_players = CEILING(min_players * CONFIG_GET(number/events_min_players_mul), 1) /datum/round_event_control/wizard + category = EVENT_CATEGORY_WIZARD wizardevent = TRUE var/can_be_midround_wizard = TRUE @@ -53,6 +61,11 @@ return FALSE if(holidayID && (!SSevents.holidays || !SSevents.holidays[holidayID])) return FALSE + + var/datum/game_mode/dynamic/dynamic = SSticker.mode + if (istype(dynamic) && dynamic_should_hijack && dynamic.random_event_hijacked != HIJACKED_NOTHING) + return FALSE + return TRUE /datum/round_event_control/wizard/canSpawnEvent(var/players_amt, var/gamemode) @@ -62,14 +75,19 @@ return can_be_midround_wizard && ..() return ..() + + /datum/round_event_control/proc/preRunEvent() if(!ispath(typepath, /datum/round_event)) return EVENT_CANT_RUN + if (SEND_GLOBAL_SIGNAL(COMSIG_GLOB_PRE_RANDOM_EVENT, src) & CANCEL_PRE_RANDOM_EVENT) + return EVENT_INTERRUPTED + triggering = TRUE if (alert_observers) - message_admins("Random Event triggering in 30 seconds: [name] (CANCEL)") - sleep(300) + message_admins("Random Event triggering in [RANDOM_EVENT_ADMIN_INTERVENTION_TIME] seconds: [name] (CANCEL)") + sleep(RANDOM_EVENT_ADMIN_INTERVENTION_TIME SECONDS) var/gamemode = SSticker.mode.config_tag var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) if(!canSpawnEvent(players_amt, gamemode)) @@ -92,18 +110,27 @@ log_admin_private("[key_name(usr)] cancelled event [name].") SSblackbox.record_feedback("tally", "event_admin_cancelled", 1, typepath) -/datum/round_event_control/proc/runEvent(random = FALSE) +/* +Runs the event +* Arguments: +* - random: shows if the event was triggered randomly, or by on purpose by an admin or an item +* - announce_chance_override: if the value is not null, overrides the announcement chance when an admin calls an event +*/ +/datum/round_event_control/proc/runEvent(random = FALSE, announce_chance_override = null, admin_forced = FALSE) var/datum/round_event/E = new typepath() E.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1) E.control = src SSblackbox.record_feedback("tally", "event_ran", 1, "[E]") occurrences++ + if(announce_chance_override != null) + E.announce_chance = announce_chance_override + testing("[time2text(world.time, "hh:mm:ss")] [E.type]") if(random) log_game("Random Event triggering: [name] ([typepath])") if (alert_observers) - deadchat_broadcast("[name] has just been[random ? " randomly" : ""] triggered!") //STOP ASSUMING IT'S BADMINS! + deadchat_broadcast(" has just been[random ? " randomly" : ""] triggered!", "[name]", message_type=DEADCHAT_ANNOUNCEMENT) //STOP ASSUMING IT'S BADMINS! return E //Special admins setup @@ -114,18 +141,29 @@ var/processing = TRUE var/datum/round_event_control/control - var/startWhen = 0 //When in the lifetime to call start(). - var/announceWhen = 0 //When in the lifetime to call announce(). Set an event's announceWhen to -1 if announcement should not be shown. - var/endWhen = 0 //When in the lifetime the event should end. + /// When in the lifetime to call start(). + /// This is in seconds - so 1 = ~2 seconds in. + var/start_when = 0 + /// When in the lifetime to call announce(). If you don't want it to announce use announce_chance, below. + /// This is in seconds - so 1 = ~2 seconds in. + var/announce_when = 0 + /// Probability of announcing, used in prob(), 0 to 100, default 100. Called in process, and for a second time in the ion storm event. + var/announce_chance = 100 + /// When in the lifetime the event should end. + /// This is in seconds - so 1 = ~2 seconds in. + var/end_when = 0 - var/activeFor = 0 //How long the event has existed. You don't need to change this. - var/current_players = 0 //Amount of of alive, non-AFK human players on server at the time of event start + /// How long the event has existed. You don't need to change this. + var/activeFor = 0 + /// Amount of of alive, non-AFK human players on server at the time of event start + var/current_players = 0 var/threat = 0 - var/fakeable = TRUE //Can be faked by fake news event. + /// Can be faked by fake news event. + var/fakeable = TRUE //Called first before processing. //Allows you to setup your event, such as randomly -//setting the startWhen and or announceWhen variables. +//setting the start_when and or announce_when variables. //Only called once. //EDIT: if there's anything you want to override within the new() call, it will not be overridden by the time this proc is called. //It will only have been overridden by the time we get to announce() start() tick() or end() (anything but setup basically). @@ -133,7 +171,7 @@ /datum/round_event/proc/setup() return -//Called when the tick is equal to the startWhen variable. +//Called when the tick is equal to the start_when variable. //Allows you to start before announcing or vice versa. //Only called once. /datum/round_event/proc/start() @@ -150,20 +188,20 @@ notify_ghosts("[control.name] has an object of interest: [atom_of_interest]!", source=atom_of_interest, action=NOTIFY_ORBIT, header="Something's Interesting!") return -//Called when the tick is equal to the announceWhen variable. +//Called when the tick is equal to the announce_when variable. //Allows you to announce before starting or vice versa. //Only called once. /datum/round_event/proc/announce(fake) return -//Called on or after the tick counter is equal to startWhen. +//Called on or after the tick counter is equal to start_when. //You can include code related to your event or add your own //time stamped events. //Called more than once. /datum/round_event/proc/tick() return -//Called on or after the tick is equal or more than endWhen +//Called on or after the tick is equal or more than end_when //You can include code related to the event ending. //Do not place spawn() in here, instead use tick() to check for //the activeFor variable. @@ -182,28 +220,28 @@ if(!processing) return - if(activeFor == startWhen) + if(activeFor == start_when) processing = FALSE start() processing = TRUE - if(activeFor == announceWhen) + if(activeFor == announce_when && prob(announce_chance)) processing = FALSE announce(FALSE) processing = TRUE - if(startWhen < activeFor && activeFor < endWhen) + if(start_when < activeFor && activeFor < end_when) processing = FALSE tick() processing = TRUE - if(activeFor == endWhen) + if(activeFor == end_when) processing = FALSE end() processing = TRUE // Everything is done, let's clean up. - if(activeFor >= endWhen && activeFor >= announceWhen && activeFor >= startWhen) + if(activeFor >= end_when && activeFor >= announce_when && activeFor >= start_when) processing = FALSE kill() diff --git a/code/modules/events/abductor.dm b/code/modules/events/abductor.dm index 41aab20a11..c539899f0e 100755 --- a/code/modules/events/abductor.dm +++ b/code/modules/events/abductor.dm @@ -4,7 +4,9 @@ weight = 10 max_occurrences = 1 min_players = 30 - gamemode_blacklist = list("nuclear","wizard","revolution","dynamic") + dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_INVASION + description = "One or more abductor teams spawns, and they plan to experiment on the crew." /datum/round_event/ghost_role/abductor minimum_required = 2 diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm index 993577cb30..cf94253bbb 100644 --- a/code/modules/events/alien_infestation.dm +++ b/code/modules/events/alien_infestation.dm @@ -2,12 +2,14 @@ name = "Alien Infestation" typepath = /datum/round_event/ghost_role/alien_infestation weight = 5 - gamemode_blacklist = list("dynamic") min_players = 25 max_occurrences = 1 + dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_ENTITIES + description = "A xenomorph larva spawns on a random vent." /datum/round_event/ghost_role/alien_infestation - announceWhen = 400 + announce_when = 400 minimum_required = 1 role_name = "alien larva" @@ -19,7 +21,7 @@ /datum/round_event/ghost_role/alien_infestation/setup() - announceWhen = rand(announceWhen, announceWhen + 50) + announce_when = rand(announce_when, announce_when + 50) if(prob(50)) spawncount++ @@ -32,7 +34,7 @@ /datum/round_event/ghost_role/alien_infestation/announce(fake) if(successSpawn || fake) - priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", "aliens") + priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", "aliens", has_important_message = TRUE) /datum/round_event/ghost_role/alien_infestation/spawn_role() diff --git a/code/modules/events/anomaly.dm b/code/modules/events/anomaly.dm index 438904466c..456a83958d 100644 --- a/code/modules/events/anomaly.dm +++ b/code/modules/events/anomaly.dm @@ -5,11 +5,13 @@ min_players = 1 max_occurrences = 0 //This one probably shouldn't occur! It'd work, but it wouldn't be very fun. weight = 15 + category = EVENT_CATEGORY_ANOMALIES + description = "This anomaly shocks and explodes. This is the base type." /datum/round_event/anomaly var/area/impact_area var/obj/effect/anomaly/anomaly_path = /obj/effect/anomaly/flux - announceWhen = 1 + announce_when = 1 /datum/round_event/anomaly/proc/findEventArea() @@ -24,7 +26,8 @@ /area/holodeck, /area/shuttle, /area/maintenance, - /area/science/test_area) + /area/science/test_area, + /area/commons/cryopod) ) //Subtypes from the above that actually should explode. @@ -44,7 +47,7 @@ CRASH("Anomaly : No valid turfs found for [impact_area] - [impact_area.type]") /datum/round_event/anomaly/announce(fake) - priority_announce("Localized energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert") + priority_announce("Localized energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert", has_important_message = TRUE) /datum/round_event/anomaly/start() var/list/turf/valid = list() diff --git a/code/modules/events/anomaly_bluespace.dm b/code/modules/events/anomaly_bluespace.dm index 70d6b00fa4..f058f37da4 100644 --- a/code/modules/events/anomaly_bluespace.dm +++ b/code/modules/events/anomaly_bluespace.dm @@ -4,11 +4,12 @@ max_occurrences = 1 weight = 5 + description = "This anomaly randomly teleports all items and mobs in a large area." /datum/round_event/anomaly/anomaly_bluespace - startWhen = 3 - announceWhen = 10 + start_when = 3 + announce_when = 10 anomaly_path = /obj/effect/anomaly/bluespace /datum/round_event/anomaly/anomaly_bluespace/announce(fake) - priority_announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + priority_announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert", has_important_message = TRUE) diff --git a/code/modules/events/anomaly_flux.dm b/code/modules/events/anomaly_flux.dm index 0ba347af57..d3b1e8ea7e 100644 --- a/code/modules/events/anomaly_flux.dm +++ b/code/modules/events/anomaly_flux.dm @@ -2,15 +2,15 @@ name = "Anomaly: Hyper-Energetic Flux" typepath = /datum/round_event/anomaly/anomaly_flux - min_players = 10 max_occurrences = 5 weight = 20 + description = "This anomaly shocks and explodes." /datum/round_event/anomaly/anomaly_flux - startWhen = 10 - announceWhen = 3 + start_when = 10 + announce_when = 3 anomaly_path = /obj/effect/anomaly/flux /datum/round_event/anomaly/anomaly_flux/announce(fake) - priority_announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + priority_announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert", has_important_message = TRUE) diff --git a/code/modules/events/anomaly_grav.dm b/code/modules/events/anomaly_grav.dm index 01e70c290c..232d2ddd35 100644 --- a/code/modules/events/anomaly_grav.dm +++ b/code/modules/events/anomaly_grav.dm @@ -4,12 +4,12 @@ max_occurrences = 5 weight = 20 - + description = "This anomaly throws things around." /datum/round_event/anomaly/anomaly_grav - startWhen = 3 - announceWhen = 20 + start_when = 3 + announce_when = 20 anomaly_path = /obj/effect/anomaly/grav /datum/round_event/anomaly/anomaly_grav/announce(fake) - priority_announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + priority_announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert", has_important_message = TRUE) diff --git a/code/modules/events/anomaly_pyro.dm b/code/modules/events/anomaly_pyro.dm index 29c6e15d28..dee0330743 100644 --- a/code/modules/events/anomaly_pyro.dm +++ b/code/modules/events/anomaly_pyro.dm @@ -2,13 +2,15 @@ name = "Anomaly: Pyroclastic" typepath = /datum/round_event/anomaly/anomaly_pyro + min_players = 5 max_occurrences = 5 weight = 20 + description = "This anomaly sets things on fire, and creates a pyroclastic slime." /datum/round_event/anomaly/anomaly_pyro - startWhen = 3 - announceWhen = 10 + start_when = 3 + announce_when = 10 anomaly_path = /obj/effect/anomaly/pyro /datum/round_event/anomaly/anomaly_pyro/announce(fake) - priority_announce("Pyroclastic anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + priority_announce("Pyroclastic anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert", has_important_message = TRUE) diff --git a/code/modules/events/anomaly_vortex.dm b/code/modules/events/anomaly_vortex.dm index 6a17a47d2b..43dcc0baf4 100644 --- a/code/modules/events/anomaly_vortex.dm +++ b/code/modules/events/anomaly_vortex.dm @@ -5,11 +5,12 @@ min_players = 20 max_occurrences = 2 weight = 5 + description = "This anomaly sucks in and detonates items." /datum/round_event/anomaly/anomaly_vortex - startWhen = 10 - announceWhen = 3 + start_when = 10 + announce_when = 3 anomaly_path = /obj/effect/anomaly/bhole /datum/round_event/anomaly/anomaly_vortex/announce(fake) - priority_announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert") + priority_announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert", has_important_message = TRUE) diff --git a/code/modules/events/atmos_speed.dm b/code/modules/events/atmos_speed.dm new file mode 100644 index 0000000000..64e6e883cc --- /dev/null +++ b/code/modules/events/atmos_speed.dm @@ -0,0 +1,25 @@ +/datum/round_event_control/atmos_flux + name = "Atmospheric Flux" + typepath = /datum/round_event/atmos_flux + max_occurrences = 5 + weight = 10 + category = EVENT_CATEGORY_ENGINEERING + description = "Modifies the speed of the SSair randomly, ends after one minute." + +/datum/round_event/atmos_flux + announce_when = 1 + end_when = 600 + var/original_speed + +/datum/round_event/atmos_flux/announce(fake) + priority_announce("Atmospheric flux in your sector detected. Sensors show that air may move [(SSair.share_max_steps_target > original_speed) ? "faster" : "slower"] than usual for some time.", "Atmos Alert") + +/datum/round_event/atmos_flux/start() + original_speed = SSair.share_max_steps_target + if(prob(20)) + SSair.share_max_steps_target = max(1, original_speed - rand(1,original_speed-1)) + else + SSair.share_max_steps_target += rand(2,10) + +/datum/round_event/atmos_flux/end() + SSair.share_max_steps_target = original_speed diff --git a/code/modules/events/aurora_caelus.dm b/code/modules/events/aurora_caelus.dm index 89a84d3494..63d7122cb8 100644 --- a/code/modules/events/aurora_caelus.dm +++ b/code/modules/events/aurora_caelus.dm @@ -4,6 +4,8 @@ max_occurrences = 1 weight = 4 earliest_start = 5 MINUTES + category = EVENT_CATEGORY_FRIENDLY + description = "A colourful display can be seen through select windows. And the kitchen." /datum/round_event_control/aurora_caelus/canSpawnEvent(players, gamemode) if(!CONFIG_GET(flag/starlight)) @@ -11,9 +13,9 @@ return ..() /datum/round_event/aurora_caelus - announceWhen = 1 - startWhen = 9 - endWhen = 50 + announce_when = 1 + start_when = 9 + end_when = 50 var/list/aurora_colors = list("#A2FF80", "#A2FF8B", "#A2FF96", "#A2FFA5", "#A2FFB6", "#A2FFC7", "#A2FFDE", "#A2FFEE") var/aurora_progress = 0 //this cycles from 1 to 8, slowly changing colors from gentle green to gentle blue diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index 67cd88efdf..e43ce0d4d0 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -6,17 +6,18 @@ earliest_start = 40 MINUTES min_players = 35 - - gamemode_blacklist = list("blob","dynamic") //Just in case a blob survives that long + dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a new blob overmind." /datum/round_event/ghost_role/blob - announceWhen = -1 + announce_when = -1 role_name = "blob overmind" fakeable = TRUE /datum/round_event/ghost_role/blob/announce(fake) if(prob(75)) - priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", "outbreak5") + priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", "outbreak5", has_important_message = TRUE) else print_command_report("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "level 5 biohazard") diff --git a/code/modules/events/brain_trauma.dm b/code/modules/events/brain_trauma.dm index 3d39f8720a..85d69a1509 100644 --- a/code/modules/events/brain_trauma.dm +++ b/code/modules/events/brain_trauma.dm @@ -3,9 +3,12 @@ typepath = /datum/round_event/brain_trauma weight = 25 min_players = 5 + category = EVENT_CATEGORY_HEALTH + description = "A crewmember gains a random trauma." /datum/round_event_control/brain_trauma/canSpawnEvent(var/players_amt, var/gamemode) - var/list/enemy_roles = list("Medical Doctor","Chief Medical Officer","Paramedic") + if(!..()) return FALSE + var/list/enemy_roles = list("Medical Doctor","Chief Medical Officer","Paramedic","AI","Chemist","Virologist","Captain","Head of Personnel","Roboticist") for (var/mob/M in GLOB.alive_mob_list) if(M.stat != DEAD && (M.mind?.assigned_role in enemy_roles)) return TRUE diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm index b9480a646c..cab9daaa55 100644 --- a/code/modules/events/brand_intelligence.dm +++ b/code/modules/events/brand_intelligence.dm @@ -5,10 +5,12 @@ min_players = 15 max_occurrences = 1 + category = EVENT_CATEGORY_AI + description = "Vending machines will attack people until the Patient Zero is disabled." /datum/round_event/brand_intelligence - announceWhen = 21 - endWhen = 1000 //Ends when all vending machines are subverted anyway. + announce_when = 21 + end_when = 1000 //Ends when all vending machines are subverted anyway. var/list/obj/machinery/vending/vendingMachines = list() var/list/obj/machinery/vending/infectedMachines = list() var/obj/machinery/vending/originMachine @@ -35,7 +37,7 @@ source = initial(example.name) else if(originMachine) source = originMachine.name - priority_announce("Rampant brand intelligence has been detected aboard [station_name()]. Please stand by. The origin is believed to be \a [source].", "Machine Learning Alert") + priority_announce("Rampant brand intelligence has been detected aboard [station_name()]. Please stand by. The origin is believed to be \a [source].", "Machine Learning Alert", has_important_message = TRUE) /datum/round_event/brand_intelligence/start() for(var/obj/machinery/vending/V in GLOB.machines) diff --git a/code/modules/events/bureaucratic_error.dm b/code/modules/events/bureaucratic_error.dm index 7246c9aedf..fc35df791b 100644 --- a/code/modules/events/bureaucratic_error.dm +++ b/code/modules/events/bureaucratic_error.dm @@ -3,9 +3,11 @@ typepath = /datum/round_event/bureaucratic_error max_occurrences = 1 weight = 5 + category = EVENT_CATEGORY_BUREAUCRATIC + description = "Randomly opens and closes job slots, along with changing the overflow role." /datum/round_event/bureaucratic_error - announceWhen = 1 + announce_when = 1 /datum/round_event/bureaucratic_error/announce(fake) priority_announce("A recent bureaucratic error in the Organic Resources Department may result in personnel shortages in some departments and redundant staffing in others.", "Paperwork Mishap Alert") diff --git a/code/modules/events/camerafailure.dm b/code/modules/events/camerafailure.dm index 8d7ef3204c..453b919c5b 100644 --- a/code/modules/events/camerafailure.dm +++ b/code/modules/events/camerafailure.dm @@ -4,6 +4,8 @@ weight = 100 max_occurrences = 20 alert_observers = FALSE + category = EVENT_CATEGORY_ENGINEERING + description = "Turns off a random amount of cameras." /datum/round_event/camera_failure fakeable = FALSE diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index d08e6267a0..bed6cf84ea 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -5,14 +5,23 @@ min_players = 2 earliest_start = 10 MINUTES max_occurrences = 6 + category = EVENT_CATEGORY_ENTITIES + description = "Summons a school of space carp." + +/datum/round_event_control/carp_migration/New() + . = ..() + if(HAS_TRAIT(SSstation, STATION_TRAIT_CARP_INFESTATION)) + weight *= 3 + max_occurrences *= 2 + earliest_start *= 0.5 /datum/round_event/carp_migration - announceWhen = 3 - startWhen = 50 + announce_when = 3 + start_when = 50 var/hasAnnounced = FALSE /datum/round_event/carp_migration/setup() - startWhen = rand(40, 60) + start_when = rand(40, 60) /datum/round_event/carp_migration/announce(fake) if(prob(50)) diff --git a/code/modules/events/cat_surgeon.dm b/code/modules/events/cat_surgeon.dm index 2d5651b9b1..254fdaecca 100644 --- a/code/modules/events/cat_surgeon.dm +++ b/code/modules/events/cat_surgeon.dm @@ -1,25 +1,47 @@ /datum/round_event_control/cat_surgeon - name = "Cat Surgeon" - typepath = /datum/round_event/cat_surgeon - max_occurrences = 1 - weight = 8 + name = "Cat Surgeon" + typepath = /datum/round_event/cat_surgeon + max_occurrences = 1 + weight = 5 + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a crazy surgeon ready to perverse things with the crew." /datum/round_event/cat_surgeon/announce(fake) priority_announce("One of our... ahem... 'special' cases has escaped. As it happens their last known location before their tracker went dead is your station so keep an eye out for them. On an unrelated note, has anyone seen our cats?", - sender_override = "Nanotrasen Psych Ward") + sender_override = "Nanotrasen Psych Ward", has_important_message = TRUE) /datum/round_event/cat_surgeon/start() - var/list/spawn_locs = list() - for(var/X in GLOB.xeno_spawn) - spawn_locs += X + var/list/spawn_locs = list() + var/list/unsafe_spawn_locs = list() + for(var/X in GLOB.xeno_spawn) + if(!isfloorturf(X)) + unsafe_spawn_locs += X + continue + var/turf/open/floor/F = X + var/datum/gas_mixture/A = F.air + var/oxy_moles = A.get_moles(GAS_O2) + if((oxy_moles < 16 || oxy_moles > 50) || A.get_moles(GAS_PLASMA) || A.get_moles(GAS_CO2) >= 10) + unsafe_spawn_locs += F + continue + if((A.return_temperature() <= 270) || (A.return_temperature() >= 360)) + unsafe_spawn_locs += F + continue + var/pressure = A.return_pressure() + if((pressure <= 20) || (pressure >= 550)) + unsafe_spawn_locs += F + continue + spawn_locs += F - if(!spawn_locs.len) - message_admins("No valid spawn locations found, aborting...") - return MAP_ERROR + if(!spawn_locs.len) + spawn_locs += unsafe_spawn_locs - var/turf/T = get_turf(pick(spawn_locs)) - var/mob/living/simple_animal/hostile/cat_butcherer/S = new(T) - playsound(S, 'sound/misc/catscream.ogg', 75, 1, -1) - message_admins("A cat surgeon has been spawned at [COORD(T)][ADMIN_JMP(T)]") - log_game("A cat surgeon has been spawned at [COORD(T)]") - return SUCCESSFUL_SPAWN + if(!spawn_locs.len) + message_admins("No valid spawn locations found, aborting...") + return MAP_ERROR + + var/turf/T = get_turf(pick(spawn_locs)) + var/mob/living/simple_animal/hostile/cat_butcherer/S = new(T) + playsound(S, 'sound/misc/catscream.ogg', 75, 1, -1) + message_admins("A cat surgeon has been spawned at [COORD(T)][ADMIN_JMP(T)]") + log_game("A cat surgeon has been spawned at [COORD(T)]") + return SUCCESSFUL_SPAWN diff --git a/code/modules/events/communications_blackout.dm b/code/modules/events/communications_blackout.dm index 0342ca4643..b47dad0c93 100644 --- a/code/modules/events/communications_blackout.dm +++ b/code/modules/events/communications_blackout.dm @@ -2,9 +2,11 @@ name = "Communications Blackout" typepath = /datum/round_event/communications_blackout weight = 30 + category = EVENT_CATEGORY_ENGINEERING + description = "Heavily emps all telecommunication machines, blocking all communication for a while." /datum/round_event/communications_blackout - announceWhen = 1 + announce_when = 1 /datum/round_event/communications_blackout/announce(fake) var/alert = pick( "Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you*%fj00)`5vc-BZZT", \ diff --git a/code/modules/events/devil.dm b/code/modules/events/devil.dm index 7d6e0bd441..3d6382b2a4 100644 --- a/code/modules/events/devil.dm +++ b/code/modules/events/devil.dm @@ -2,6 +2,8 @@ name = "Create Devil" typepath = /datum/round_event/ghost_role/devil max_occurrences = 0 + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a devil, looking forward to makings deals with crewmembers to get their souls." /datum/round_event/ghost_role/devil var/success_spawn = 0 diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 490cd0ff21..753349fdd6 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -2,27 +2,39 @@ name = "Disease Outbreak" typepath = /datum/round_event/disease_outbreak max_occurrences = 1 - min_players = 10 + min_players = 3 weight = 5 + category = EVENT_CATEGORY_HEALTH + description = "A classic or advanced disease will infect some crewmembers." /datum/round_event/disease_outbreak - announceWhen = 15 + announce_when = 15 var/virus_type var/max_severity = 3 +/datum/round_event_control/disease_outbreak/canSpawnEvent(var/players_amt, var/gamemode) + if(!..()) return FALSE + var/list/enemy_roles = list("Medical Doctor","Chief Medical Officer","Paramedic","AI","Chemist","Virologist","Captain","Head of Personnel", "Geneticist") + for (var/mob/M in GLOB.alive_mob_list) + if(M.stat != DEAD && (M.mind?.assigned_role in enemy_roles)) + return TRUE + return FALSE /datum/round_event/disease_outbreak/announce(fake) priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", "outbreak7") /datum/round_event/disease_outbreak/setup() - announceWhen = rand(15, 30) + announce_when = rand(15, 30) /datum/round_event/disease_outbreak/start() var/advanced_virus = FALSE - max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes + var/player_count = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE) + max_severity = 1 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes + max_severity += player_count > 5 + max_severity += player_count > 10 if(prob(20 + (10 * max_severity))) advanced_virus = TRUE diff --git a/code/modules/events/dust.dm b/code/modules/events/dust.dm index eb7edcafbf..6b0139c449 100644 --- a/code/modules/events/dust.dm +++ b/code/modules/events/dust.dm @@ -5,10 +5,12 @@ max_occurrences = 1000 earliest_start = 0 MINUTES alert_observers = FALSE + category = EVENT_CATEGORY_SPACE + description = "A single space dust is hurled at the station." /datum/round_event/space_dust - startWhen = 1 - endWhen = 2 + start_when = 1 + end_when = 2 fakeable = FALSE /datum/round_event/space_dust/start() @@ -17,15 +19,21 @@ /datum/round_event_control/sandstorm name = "Sandstorm" typepath = /datum/round_event/sandstorm - weight = 0 - max_occurrences = 0 - earliest_start = 0 MINUTES + weight = 5 + max_occurrences = 1 + min_players = 10 + earliest_start = 20 MINUTES + category = EVENT_CATEGORY_SPACE + description = "The station is pelted by an extreme amount of sand for several minutes." /datum/round_event/sandstorm - startWhen = 1 - endWhen = 150 // ~5 min - announceWhen = 0 + start_when = 1 + end_when = 150 // ~5 min + announce_when = 0 fakeable = FALSE +/datum/round_event/sandstorm/announce(fake) + priority_announce("The station is passing through a heavy debris cloud. Watch out for breaches.", "Collision Alert", has_important_message = TRUE) + /datum/round_event/sandstorm/tick() - spawn_meteors(10, GLOB.meteorsC) + spawn_meteors(rand(6,10), GLOB.meteorsC) diff --git a/code/modules/events/electrical_storm.dm b/code/modules/events/electrical_storm.dm index b850b4db62..f04389b1a1 100644 --- a/code/modules/events/electrical_storm.dm +++ b/code/modules/events/electrical_storm.dm @@ -4,12 +4,13 @@ earliest_start = 10 MINUTES min_players = 5 weight = 40 - alert_observers = FALSE + category = EVENT_CATEGORY_ENGINEERING + description = "Destroys all lights in a large area." /datum/round_event/electrical_storm var/lightsoutAmount = 1 var/lightsoutRange = 25 - announceWhen = 1 + announce_when = 1 /datum/round_event/electrical_storm/announce(fake) if(prob(50)) diff --git a/code/modules/events/fake_virus.dm b/code/modules/events/fake_virus.dm index cebf1ed14b..ec69f9e2c9 100644 --- a/code/modules/events/fake_virus.dm +++ b/code/modules/events/fake_virus.dm @@ -2,6 +2,8 @@ name = "Fake Virus" typepath = /datum/round_event/fake_virus weight = 20 + category = EVENT_CATEGORY_HEALTH + description = "Some crewmembers suffer from temporary hypochondria." /datum/round_event/fake_virus/start() var/list/fake_virus_victims = list() diff --git a/code/modules/events/false_alarm.dm b/code/modules/events/false_alarm.dm index 5ac75cf087..95b7d1c3ce 100644 --- a/code/modules/events/false_alarm.dm +++ b/code/modules/events/false_alarm.dm @@ -4,7 +4,8 @@ weight = 20 max_occurrences = 5 var/forced_type //Admin abuse - + category = EVENT_CATEGORY_BUREAUCRATIC + description = "Fakes an event announcement." /datum/round_event_control/falsealarm/admin_setup() if(!check_rights(R_FUN)) @@ -17,15 +18,15 @@ if(!initial(event.fakeable)) continue possible_types += E - + forced_type = input(usr, "Select the scare.","False event") as null|anything in possible_types /datum/round_event_control/falsealarm/canSpawnEvent(players_amt, gamemode) return ..() && length(gather_false_events()) /datum/round_event/falsealarm - announceWhen = 0 - endWhen = 1 + announce_when = 0 + end_when = 1 fakeable = FALSE /datum/round_event/falsealarm/announce(fake) diff --git a/code/modules/events/floorcluwne.dm b/code/modules/events/floorcluwne.dm index 3df636809a..6b91fb2ca2 100644 --- a/code/modules/events/floorcluwne.dm +++ b/code/modules/events/floorcluwne.dm @@ -1,10 +1,11 @@ /datum/round_event_control/floor_cluwne name = "Floor Cluwne" typepath = /datum/round_event/floor_cluwne - max_occurrences = 1 + max_occurrences = 0 min_players = 20 weight = 10 - + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a floor cluwne, will hunt a random player and most likely gib them, prepare for adminhelps." /datum/round_event/floor_cluwne/start() var/list/spawn_locs = list() diff --git a/code/modules/events/fugitive_spawning.dm b/code/modules/events/fugitive_spawning.dm index 7b4628f135..13964d6ec6 100644 --- a/code/modules/events/fugitive_spawning.dm +++ b/code/modules/events/fugitive_spawning.dm @@ -4,7 +4,8 @@ max_occurrences = 1 min_players = 20 earliest_start = 30 MINUTES //deadchat sink, lets not even consider it early on. - gamemode_blacklist = list("nuclear") + category = EVENT_CATEGORY_INVASION + description = "Fugitives will hide on the station, followed by hunters." /datum/round_event/ghost_role/fugitives minimum_required = 1 diff --git a/code/modules/events/ghost_role.dm b/code/modules/events/ghost_role.dm index ae1d1320a5..baabb435bc 100644 --- a/code/modules/events/ghost_role.dm +++ b/code/modules/events/ghost_role.dm @@ -7,6 +7,8 @@ var/minimum_required = 1 var/role_name = "debug rat with cancer" // Q U A L I T Y M E M E S var/list/spawned_mobs = list() + var/status + var/cached_announcement_chance fakeable = FALSE /datum/round_event/ghost_role/start() @@ -17,7 +19,10 @@ // to prevent us from getting gc'd halfway through processing = FALSE - var/status = spawn_role() + status = spawn_role() + if(isnull(cached_announcement_chance)) + cached_announcement_chance = announce_chance //only announce once we've finished the spawning loop. + announce_chance = (status == SUCCESSFUL_SPAWN ? cached_announcement_chance : 0) if((status == WAITING_FOR_SOMETHING)) if(retry >= MAX_SPAWN_ATTEMPT) message_admins("[role_name] event has exceeded maximum spawn attempts. Aborting and refunding.") diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm index 1bb0ee617a..c39a6e1bb2 100644 --- a/code/modules/events/grid_check.dm +++ b/code/modules/events/grid_check.dm @@ -3,10 +3,12 @@ typepath = /datum/round_event/grid_check weight = 10 max_occurrences = 3 + category = EVENT_CATEGORY_ENGINEERING + description = "Turns off all APCs for a while, or until they are manually rebooted." /datum/round_event/grid_check - announceWhen = 1 - startWhen = 1 + announce_when = 1 + start_when = 1 /datum/round_event/grid_check/announce(fake) priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", "poweroff") diff --git a/code/modules/events/heart_attack.dm b/code/modules/events/heart_attack.dm index 8c33e69107..4f94576fa6 100644 --- a/code/modules/events/heart_attack.dm +++ b/code/modules/events/heart_attack.dm @@ -1,9 +1,19 @@ /datum/round_event_control/heart_attack name = "Random Heart Attack" typepath = /datum/round_event/heart_attack - weight = 20 + weight = 10 max_occurrences = 2 - min_players = 40 // To avoid shafting lowpop + min_players = 10 // To avoid shafting lowpop + category = EVENT_CATEGORY_HEALTH + description = "A random crewmember's heart gives out." + +/datum/round_event_control/heart_attack/canSpawnEvent(var/players_amt, var/gamemode) + if(!..()) return FALSE + var/list/enemy_roles = list("Medical Doctor","Chief Medical Officer","Paramedic","Chemist") + for (var/mob/M in GLOB.alive_mob_list) + if(M.stat != DEAD && (M.mind?.assigned_role in enemy_roles)) + return TRUE + return FALSE /datum/round_event/heart_attack/start() var/list/heart_attack_contestants = list() diff --git a/code/modules/events/high_priority_bounty.dm b/code/modules/events/high_priority_bounty.dm index ffdcd8840b..90f27b19f9 100644 --- a/code/modules/events/high_priority_bounty.dm +++ b/code/modules/events/high_priority_bounty.dm @@ -4,6 +4,8 @@ max_occurrences = 3 weight = 20 earliest_start = 10 + category = EVENT_CATEGORY_BUREAUCRATIC + description = "Creates bounties that are three times original worth." /datum/round_event/high_priority_bounty/announce(fake) priority_announce("Central Command has issued a high-priority cargo bounty. Details have been sent to all bounty consoles.", "Nanotrasen Bounty Program") diff --git a/code/modules/events/holiday/halloween.dm b/code/modules/events/holiday/halloween.dm index 263e3aa660..fd45eb4ccf 100644 --- a/code/modules/events/holiday/halloween.dm +++ b/code/modules/events/holiday/halloween.dm @@ -5,6 +5,8 @@ weight = -1 //forces it to be called, regardless of weight max_occurrences = 1 earliest_start = 0 MINUTES + category = EVENT_CATEGORY_HOLIDAY + description = "Gives everyone treats, and turns Ian and Polly into their festive versions." /datum/round_event/spooky/start() ..() @@ -15,9 +17,9 @@ for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_living_list) Ian.place_on_head(new /obj/item/bedsheet(Ian)) - for(var/mob/living/simple_animal/parrot/Poly/Poly in GLOB.mob_living_list) - new /mob/living/simple_animal/parrot/Poly/ghost(Poly.loc) - qdel(Poly) + for(var/mob/living/simple_animal/parrot/Polly/Polly in GLOB.mob_living_list) + new /mob/living/simple_animal/parrot/Polly/ghost(Polly.loc) + qdel(Polly) /datum/round_event/spooky/announce(fake) diff --git a/code/modules/events/holiday/vday.dm b/code/modules/events/holiday/vday.dm index df00f873b5..16d51337f1 100644 --- a/code/modules/events/holiday/vday.dm +++ b/code/modules/events/holiday/vday.dm @@ -11,6 +11,8 @@ weight = -1 //forces it to be called, regardless of weight max_occurrences = 1 earliest_start = 0 MINUTES + category = EVENT_CATEGORY_HOLIDAY + description = "Puts people on dates! They must protect each other. Sometimes a vengeful third wheel spawns." /datum/round_event/valentines/start() ..() diff --git a/code/modules/events/holiday/xmas.dm b/code/modules/events/holiday/xmas.dm index 919a1d2949..a9bedb3c57 100644 --- a/code/modules/events/holiday/xmas.dm +++ b/code/modules/events/holiday/xmas.dm @@ -37,7 +37,7 @@ icon_state = "xmashat" desc = "A crappy paper hat that you are REQUIRED to wear." flags_inv = 0 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/effect/landmark/xmastree name = "christmas tree spawner" @@ -68,6 +68,8 @@ weight = 20 max_occurrences = 1 earliest_start = 30 MINUTES + category = EVENT_CATEGORY_HOLIDAY + description = "Spawns santa, who shall roam the station, handing out gifts." /datum/round_event/santa var/mob/living/carbon/human/santa //who is our santa? diff --git a/code/modules/events/immovable_rod.dm b/code/modules/events/immovable_rod.dm index a9ee0f5412..a48191e8a1 100644 --- a/code/modules/events/immovable_rod.dm +++ b/code/modules/events/immovable_rod.dm @@ -13,7 +13,8 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 min_players = 15 max_occurrences = 5 var/atom/special_target - + category = EVENT_CATEGORY_SPACE + description = "The station passes through an immovable rod." /datum/round_event_control/immovable_rod/admin_setup() if(!check_rights(R_FUN)) @@ -24,10 +25,10 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 special_target = get_turf(usr) /datum/round_event/immovable_rod - announceWhen = 5 + announce_when = 5 /datum/round_event/immovable_rod/announce(fake) - priority_announce("What the fuck was that?!", "General Alert") + priority_announce("What the fuck was that?!", "General Alert", has_important_message = TRUE) /datum/round_event/immovable_rod/start() var/datum/round_event_control/immovable_rod/C = control @@ -99,7 +100,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 walk(src,0) walk_towards(src, destination, 1) -/obj/effect/immovablerod/ex_act(severity, target) +/obj/effect/immovablerod/ex_act(severity, target, origin) return 0 /obj/effect/immovablerod/singularity_act() diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index c75aff0c4a..0fefb43170 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -5,6 +5,8 @@ typepath = /datum/round_event/ion_storm weight = 15 min_players = 2 + category = EVENT_CATEGORY_AI + description = "Gives the AI a new, randomized law." /datum/round_event/ion_storm var/replaceLawsetChance = 25 //chance the AI's lawset is completely replaced with something else per config weights @@ -14,8 +16,8 @@ var/botEmagChance = 10 var/announceEvent = ION_RANDOM // -1 means don't announce, 0 means have it randomly announce, 1 means it is announced var/ionMessage = null - var/ionAnnounceChance = 33 - announceWhen = 1 + announce_when = 1 + announce_chance = 33 /datum/round_event/ion_storm/add_law_only // special subtype that adds a law only replaceLawsetChance = 0 @@ -25,8 +27,8 @@ botEmagChance = 0 /datum/round_event/ion_storm/announce(fake) - if(announceEvent == ION_ANNOUNCE || (announceEvent == ION_RANDOM && prob(ionAnnounceChance)) || fake) - priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", "ionstorm") + if(announceEvent == ION_ANNOUNCE || (announceEvent == ION_RANDOM && prob(announce_chance)) || fake) + priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", "ionstorm", has_important_message = prob(80)) /datum/round_event/ion_storm/start() diff --git a/code/modules/events/major_dust.dm b/code/modules/events/major_dust.dm index d7d8f1aec8..dc24a52b19 100644 --- a/code/modules/events/major_dust.dm +++ b/code/modules/events/major_dust.dm @@ -2,6 +2,7 @@ name = "Major Space Dust" typepath = /datum/round_event/meteor_wave/major_dust weight = 8 + description = "The station is pelted by sand." /datum/round_event/meteor_wave/major_dust wave_name = "space dust" @@ -17,6 +18,6 @@ "A neighbouring station is throwing rocks at you. (Perhaps they've \ grown tired of your messages.)") if(prob(50)) - priority_announce(pick(reason), "Collision Alert") + priority_announce(pick(reason), "Collision Alert", has_important_message = prob(75)) else print_command_report("[pick(reason)]", "Collision Alert") diff --git a/code/modules/events/mass_hallucination.dm b/code/modules/events/mass_hallucination.dm index dc0b07b464..2a0c45a5ff 100644 --- a/code/modules/events/mass_hallucination.dm +++ b/code/modules/events/mass_hallucination.dm @@ -2,14 +2,16 @@ name = "Mass Hallucination" typepath = /datum/round_event/mass_hallucination weight = 10 - max_occurrences = 2 + max_occurrences = 5 min_players = 1 var/forced_hallucination + category = EVENT_CATEGORY_HEALTH + description = "Multiple crewmembers start to hallucinate the same thing." /datum/round_event_control/mass_hallucination/admin_setup() if(!check_rights(R_FUN)) return - + forced_hallucination = input(usr, "Choose the hallucination to apply","Send Hallucination") as null|anything in subtypesof(/datum/hallucination) /datum/round_event/mass_hallucination @@ -26,7 +28,7 @@ switch(rand(1,4)) if(1) //same sound for everyone - var/sound = pick("airlock","airlock_pry","console","explosion","far_explosion","mech","glass","alarm","beepsky","mech","wall_decon","door_hack","tesla") + var/sound = pick("airlock","airlock_pry","console","explosion","far_explosion","mech","glass","alarm","beepsky","mech","wall_decon","door_hack","tesla","seth") for(var/mob/living/carbon/C in GLOB.alive_mob_list) new /datum/hallucination/sounds(C, TRUE, sound) if(2) diff --git a/code/modules/events/meateor_wave.dm b/code/modules/events/meateor_wave.dm index 44419e9b78..a625f53788 100644 --- a/code/modules/events/meateor_wave.dm +++ b/code/modules/events/meateor_wave.dm @@ -3,9 +3,10 @@ typepath = /datum/round_event/meteor_wave/meaty weight = 2 max_occurrences = 1 + description = "A meteor wave made of meat." /datum/round_event/meteor_wave/meaty wave_name = "meaty" /datum/round_event/meteor_wave/meaty/announce(fake) - priority_announce("Meaty ores have been detected on collision course with the station.", "Oh crap, get the mop.", "meteors") + priority_announce("Meaty ores have been detected on collision course with the station.", "Oh crap, get the mop.", "meteors", has_important_message = TRUE) diff --git a/code/modules/events/meteor_wave.dm b/code/modules/events/meteor_wave.dm index e69af1df13..a3534be3ea 100644 --- a/code/modules/events/meteor_wave.dm +++ b/code/modules/events/meteor_wave.dm @@ -10,22 +10,24 @@ min_players = 15 max_occurrences = 3 earliest_start = 25 MINUTES + category = EVENT_CATEGORY_SPACE + description = "A regular meteor wave." /datum/round_event/meteor_wave - startWhen = 6 - endWhen = 66 - announceWhen = 1 + start_when = 6 + end_when = 66 + announce_when = 1 threat = 15 var/list/wave_type var/wave_name = "normal" var/direction /datum/round_event/meteor_wave/setup() - announceWhen = 1 - startWhen = 150 // 5 minutes + announce_when = 1 + start_when = 150 // 5 minutes if(GLOB.singularity_counter) - startWhen *= 1 - min(GLOB.singularity_counter * SINGULO_BEACON_DISTURBANCE, SINGULO_BEACON_MAX_DISTURBANCE) - endWhen = startWhen + 60 + start_when *= 1 - min(GLOB.singularity_counter * SINGULO_BEACON_DISTURBANCE, SINGULO_BEACON_MAX_DISTURBANCE) + end_when = start_when + 60 /datum/round_event/meteor_wave/New() ..() @@ -61,9 +63,9 @@ kill() /datum/round_event/meteor_wave/announce(fake) - priority_announce(generateMeteorString(startWhen,TRUE,direction), "Meteor Alert", "meteors") + priority_announce(generateMeteorString(start_when,TRUE,direction), "Meteor Alert", "meteors", has_important_message = TRUE) -/proc/generateMeteorString(startWhen,syndiealert,direction) +/proc/generateMeteorString(start_when,syndiealert,direction) var/directionstring switch(direction) if(NORTH) @@ -74,7 +76,7 @@ directionstring = " towards starboard" if(WEST) directionstring = " towards port" - return "Meteors have been detected on a collision course with the station[directionstring]. Estimated time until impact: [round((startWhen * SSevents.wait) / 10, 0.1)] seconds.[GLOB.singularity_counter && syndiealert ? " Warning: Anomalous gravity pulse detected, Syndicate technology interference likely." : ""]" + return "Meteors have been detected on a collision course with the station[directionstring]. Estimated time until impact: [round((start_when * SSevents.wait) / 10, 0.1)] seconds.[GLOB.singularity_counter && syndiealert ? " Warning: Anomalous gravity pulse detected, Syndicate technology interference likely." : ""]" /datum/round_event/meteor_wave/tick() if(ISMULTIPLE(activeFor, 3)) @@ -87,7 +89,7 @@ min_players = 20 max_occurrences = 3 earliest_start = 35 MINUTES - + description = "A meteor wave with higher chance of big meteors." /datum/round_event/meteor_wave/threatening wave_name = "threatening" @@ -100,6 +102,7 @@ min_players = 25 max_occurrences = 3 earliest_start = 45 MINUTES + description = "A meteor wave that might summon a tunguska class meteor." /datum/round_event/meteor_wave/catastrophic wave_name = "catastrophic" diff --git a/code/modules/events/mice_migration.dm b/code/modules/events/mice_migration.dm index 373c495972..5bf842ba47 100644 --- a/code/modules/events/mice_migration.dm +++ b/code/modules/events/mice_migration.dm @@ -2,6 +2,8 @@ name = "Mice Migration" typepath = /datum/round_event/mice_migration weight = 10 + category = EVENT_CATEGORY_ENTITIES + description = "A horde of mice arrives, and perhaps even the Rat King themselves." /datum/round_event/mice_migration var/minimum_mice = 5 diff --git a/code/modules/events/nightmare.dm b/code/modules/events/nightmare.dm index 97a10c930a..71351d85be 100644 --- a/code/modules/events/nightmare.dm +++ b/code/modules/events/nightmare.dm @@ -3,7 +3,9 @@ typepath = /datum/round_event/ghost_role/nightmare max_occurrences = 1 min_players = 20 - gamemode_blacklist = list("dynamic") + dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a nightmare, aiming to darken the station." /datum/round_event/ghost_role/nightmare minimum_required = 1 diff --git a/code/modules/events/operative.dm b/code/modules/events/operative.dm index 6ef693a886..cbefa58c7b 100644 --- a/code/modules/events/operative.dm +++ b/code/modules/events/operative.dm @@ -3,6 +3,8 @@ typepath = /datum/round_event/ghost_role/operative weight = 0 //Admin only max_occurrences = 1 + category = EVENT_CATEGORY_INVASION + description = "A single nuclear operative assaults the station." /datum/round_event/ghost_role/operative minimum_required = 1 diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm index d284146ea3..1b1fdee584 100644 --- a/code/modules/events/pirates.dm +++ b/code/modules/events/pirates.dm @@ -5,7 +5,9 @@ max_occurrences = 1 min_players = 10 earliest_start = 30 MINUTES - gamemode_blacklist = list("nuclear") + dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_INVASION + description = "The crew will either pay up, or face a pirate assault." #define PIRATES_ROGUES "Rogues" // #define PIRATES_SILVERSCALES "Silverscales" @@ -17,19 +19,18 @@ return ..() -/datum/round_event/pirates - startWhen = 60 //2 minutes to answer - var/datum/comm_message/threat_msg +/datum/round_event/pirates/start() + send_pirate_threat() + +/proc/send_pirate_threat() + var/pirate_type = PIRATES_ROGUES //pick(PIRATES_ROGUES, PIRATES_SILVERSCALES, PIRATES_DUTCHMAN) + var/datum/comm_message/threat_msg = new var/payoff = 0 - var/payoff_min = 1000 - var/paid_off = FALSE - var/pirate_type + var/payoff_min = 10000 //documented this time var/ship_template var/ship_name = "Space Privateers Association" - var/shuttle_spawned = FALSE - -/datum/round_event/pirates/setup() - pirate_type = PIRATES_ROGUES //pick(PIRATES_ROGUES, PIRATES_SILVERSCALES, PIRATES_DUTCHMAN) + var/initial_send_time = world.time + var/response_max_time = 2 MINUTES switch(pirate_type) if(PIRATES_ROGUES) ship_name = pick(strings(PIRATE_NAMES_FILE, "rogue_names")) @@ -38,11 +39,7 @@ // if(PIRATES_DUTCHMAN) // ship_name = "Flying Dutchman" -/datum/round_event/pirates/announce(fake) - priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", "commandreport") - if(fake) - return - threat_msg = new + priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", SSstation.announcer.get_rand_report_sound(), has_important_message = TRUE) var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) if(D) payoff = max(payoff_min, FLOOR(D.account_balance * 0.80, 1000)) @@ -62,35 +59,27 @@ // threat_msg.title = "Business proposition" // threat_msg.content = "Ahoy! This be the [ship_name]. Cough up [payoff] credits or you'll walk the plank." // threat_msg.possible_answers = list("We'll pay.","We will not be extorted.") - threat_msg.answer_callback = CALLBACK(src,.proc/answered) + threat_msg.answer_callback = CALLBACK(GLOBAL_PROC, .proc/pirates_answered, threat_msg, payoff, ship_name, initial_send_time, response_max_time, ship_template) + addtimer(CALLBACK(GLOBAL_PROC, .proc/spawn_pirates, threat_msg, ship_template, FALSE), response_max_time) SScommunications.send_message(threat_msg,unique = TRUE) -/datum/round_event/pirates/proc/answered() - if(threat_msg?.answered == 1) +/proc/pirates_answered(datum/comm_message/threat_msg, payoff, ship_name, initial_send_time, response_max_time, ship_template) + if(world.time > initial_send_time + response_max_time) + priority_announce("Too late to beg for mercy!",sender_override = ship_name, has_important_message = TRUE) + return + if(threat_msg && threat_msg.answered == 1) var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) if(D) if(D.adjust_money(-payoff)) - priority_announce("Thanks for the credits, landlubbers.",sender_override = ship_name) - paid_off = TRUE + priority_announce("Thanks for the credits, landlubbers.",sender_override = ship_name, has_important_message = TRUE) return else - priority_announce("Trying to cheat us? You'll regret this!",sender_override = ship_name) - else if(threat_msg?.answered == 2) - priority_announce("You won't pay? Fine then, we'll take those credits by force!",sender_override = ship_name) - if(!shuttle_spawned) - spawn_shuttle() - else - priority_announce("Too late to beg for mercy!",sender_override = ship_name) + priority_announce("Trying to cheat us? You'll regret this!",sender_override = ship_name, has_important_message = TRUE) + spawn_pirates(threat_msg, ship_template, TRUE) -/datum/round_event/pirates/start() - if(threat_msg && !threat_msg.answered) - threat_msg.possible_answers = list("Too late") - threat_msg.answered = 1 - if(!paid_off && !shuttle_spawned) - spawn_shuttle() - -/datum/round_event/pirates/proc/spawn_shuttle() - shuttle_spawned = TRUE +/proc/spawn_pirates(datum/comm_message/threat_msg, ship_template, skip_answer_check) + if(!skip_answer_check && threat_msg?.answered == 1) + return var/list/candidates = pollGhostCandidates("Do you wish to be considered for pirate crew?", ROLE_TRAITOR) shuffle_inplace(candidates) @@ -109,12 +98,12 @@ for(var/turf/A in ship.get_affected_turfs(T)) for(var/obj/effect/mob_spawn/human/pirate/spawner in A) if(candidates.len > 0) - var/mob/M = candidates[1] - spawner.create(M.ckey) - candidates -= M - announce_to_ghosts(M) + var/mob/our_candidate = candidates[1] + spawner.create(our_candidate.ckey) + candidates -= our_candidate + notify_ghosts("The pirate ship has an object of interest: [our_candidate]!", source=our_candidate, action=NOTIFY_ORBIT, header="Something's Interesting!") else - announce_to_ghosts(spawner) + notify_ghosts("The pirate ship has an object of interest: [spawner]!", source=spawner, action=NOTIFY_ORBIT, header="Something's Interesting!") priority_announce("Unidentified armed ship detected near the station.") @@ -264,8 +253,8 @@ /obj/machinery/piratepad name = "cargo hold pad" icon = 'icons/obj/telescience.dmi' - icon_state = "lpad-idle-o" - var/idle_state = "lpad-idle-o" + icon_state = "lpad-idle-off" + var/idle_state = "lpad-idle" var/warmup_state = "lpad-idle" var/sending_state = "lpad-beam" var/cargo_hold_id @@ -277,6 +266,17 @@ I.buffer = src return TRUE +/obj/machinery/piratepad/screwdriver_act(mob/living/user, obj/item/screwdriver/screw) + . = ..() + if(!.) + return default_deconstruction_screwdriver(user, "lpad-idle-open", "lpad-idle-off", screw) + +/obj/machinery/piratepad/crowbar_act(mob/living/user, obj/item/tool) + . = ..() + default_deconstruction_crowbar(tool) + return TRUE + + /obj/machinery/computer/piratepad_control name = "cargo hold control terminal" var/status_report = "Ready for delivery." @@ -287,8 +287,10 @@ var/datum/export_report/total_report var/sending_timer var/cargo_hold_id + ///Reference to the specific pad that the control computer is linked up to. + var/datum/weakref/pad_ref -/obj/machinery/computer/piratepad_control/Initialize() +/obj/machinery/computer/piratepad_control/Initialize(mapload) ..() return INITIALIZE_HINT_LATELOAD @@ -296,7 +298,7 @@ . = ..() if (istype(I) && istype(I.buffer,/obj/machinery/piratepad)) to_chat(user, "You link [src] with [I.buffer] in [I] buffer.") - pad = I.buffer + pad_ref = WEAKREF(I.buffer) return TRUE /obj/machinery/computer/piratepad_control/LateInitialize() @@ -304,10 +306,11 @@ if(cargo_hold_id) for(var/obj/machinery/piratepad/P in GLOB.machines) if(P.cargo_hold_id == cargo_hold_id) - pad = P + pad_ref = WEAKREF(P) return else pad = locate() in range(4,src) + pad_ref = WEAKREF(pad) /obj/machinery/computer/piratepad_control/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) @@ -318,7 +321,7 @@ /obj/machinery/computer/piratepad_control/ui_data(mob/user) var/list/data = list() data["points"] = points - data["pad"] = pad ? TRUE : FALSE + data["pad"] = pad_ref?.resolve() ? TRUE : FALSE data["sending"] = sending data["status_report"] = status_report return data @@ -327,7 +330,7 @@ . = ..() if(.) return - if(!pad) + if(!pad_ref?.resolve()) return switch(action) @@ -348,6 +351,7 @@ status_report = "Predicted value: " var/value = 0 var/datum/export_report/ex = new + var/obj/machinery/piratepad/pad = pad_ref?.resolve() for(var/atom/movable/AM in get_turf(pad)) if(AM == pad) continue @@ -366,6 +370,7 @@ return var/datum/export_report/ex = new + var/obj/machinery/piratepad/pad = pad_ref?.resolve() for(var/atom/movable/AM in get_turf(pad)) if(AM == pad) @@ -403,6 +408,15 @@ sending = FALSE /obj/machinery/computer/piratepad_control/proc/start_sending() + var/obj/machinery/piratepad/pad = pad_ref?.resolve() + if(!pad) + status_report = "No pad detected. Build or link a pad." + pad.audible_message(span_notice("[pad] beeps.")) + return + if(pad?.panel_open) + status_report = "Please screwdrive pad closed to send. " + pad.audible_message(span_notice("[pad] beeps.")) + return if(sending) return sending = TRUE diff --git a/code/modules/events/portal_storm.dm b/code/modules/events/portal_storm.dm index 59bb22e9af..b1b68fb585 100644 --- a/code/modules/events/portal_storm.dm +++ b/code/modules/events/portal_storm.dm @@ -4,6 +4,8 @@ weight = 2 min_players = 15 earliest_start = 30 MINUTES + category = EVENT_CATEGORY_ENTITIES + description = "Syndicate troops pour out of portals." /datum/round_event/portal_storm/syndicate_shocktroop boss_types = list(/mob/living/simple_animal/hostile/syndicate/melee/space/stormtrooper = 2) @@ -15,6 +17,8 @@ typepath = /datum/round_event/portal_storm/portal_storm_narsie weight = 0 max_occurrences = 0 + category = EVENT_CATEGORY_ENTITIES + description = "Nar'sie constructs pour out of portals." /datum/round_event/portal_storm/portal_storm_narsie boss_types = list(/mob/living/simple_animal/hostile/construct/builder = 6) @@ -22,9 +26,9 @@ /mob/living/simple_animal/hostile/construct/wraith/hostile = 6) /datum/round_event/portal_storm - startWhen = 7 - endWhen = 999 - announceWhen = 1 + start_when = 7 + end_when = 999 + announce_when = 1 var/list/boss_spawn = list() var/list/boss_types = list() //only configure this if you have hostiles @@ -53,7 +57,7 @@ while(number_of_hostiles > hostiles_spawn.len) hostiles_spawn += get_random_station_turf() - next_boss_spawn = startWhen + CEILING(2 * number_of_hostiles / number_of_bosses, 1) + next_boss_spawn = start_when + CEILING(2 * number_of_hostiles / number_of_bosses, 1) /datum/round_event/portal_storm/announce(fake) do_announce() @@ -117,7 +121,7 @@ /datum/round_event/portal_storm/proc/time_to_end() if(!hostile_types.len && !boss_types.len) - endWhen = activeFor + end_when = activeFor if(!number_of_hostiles && number_of_bosses) - endWhen = activeFor + end_when = activeFor diff --git a/code/modules/events/prison_break.dm b/code/modules/events/prison_break.dm index d35f4931fb..110ab745a0 100644 --- a/code/modules/events/prison_break.dm +++ b/code/modules/events/prison_break.dm @@ -3,10 +3,12 @@ typepath = /datum/round_event/grey_tide max_occurrences = 2 min_players = 5 + category = EVENT_CATEGORY_ENGINEERING + description = "Bolts open all doors in one or more departments." /datum/round_event/grey_tide - announceWhen = 50 - endWhen = 20 + announce_when = 50 + end_when = 20 var/list/area/areasToOpen = list() var/list/potential_areas = list(/area/command, /area/engineering, @@ -17,8 +19,8 @@ var/severity = 1 /datum/round_event/grey_tide/setup() - announceWhen = rand(50, 60) - endWhen = rand(20, 30) + announce_when = rand(50, 60) + end_when = rand(20, 30) severity = rand(1,3) for(var/i in 1 to severity) var/picked_area = pick_n_take(potential_areas) diff --git a/code/modules/events/processor_overload.dm b/code/modules/events/processor_overload.dm index 6f20d954ed..578520f565 100644 --- a/code/modules/events/processor_overload.dm +++ b/code/modules/events/processor_overload.dm @@ -3,9 +3,11 @@ typepath = /datum/round_event/processor_overload weight = 15 min_players = 20 + category = EVENT_CATEGORY_ENGINEERING + description = "Emps the telecomm processors, scrambling radio speech. Might blow up a few." /datum/round_event/processor_overload - announceWhen = 1 + announce_when = 1 /datum/round_event/processor_overload/announce(fake) var/alert = pick( "Exospheric bubble inbound. Processor overload is likely. Please contact you*%xp25)`6cq-BZZT", \ diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm index 36e16bb2c9..5ba3d017e1 100644 --- a/code/modules/events/radiation_storm.dm +++ b/code/modules/events/radiation_storm.dm @@ -2,17 +2,19 @@ name = "Radiation Storm" typepath = /datum/round_event/radiation_storm max_occurrences = 1 + category = EVENT_CATEGORY_SPACE + description = "Radiation storm affects the station, forcing the crew to escape to maintenance." /datum/round_event/radiation_storm /datum/round_event/radiation_storm/setup() - startWhen = 3 - endWhen = startWhen + 1 - announceWhen = 1 + start_when = 3 + end_when = start_when + 1 + announce_when = 1 /datum/round_event/radiation_storm/announce(fake) - priority_announce("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert", "radiation") + priority_announce("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert", "radiation", has_important_message = TRUE) //sound not longer matches the text, but an audible warning is probably good /datum/round_event/radiation_storm/start() diff --git a/code/modules/events/sentience.dm b/code/modules/events/sentience.dm index d90792c88f..8cccaba68b 100644 --- a/code/modules/events/sentience.dm +++ b/code/modules/events/sentience.dm @@ -2,7 +2,8 @@ name = "Random Human-level Intelligence" typepath = /datum/round_event/ghost_role/sentience weight = 10 - + category = EVENT_CATEGORY_FRIENDLY + description = "An animal or robot becomes sentient!" /datum/round_event/ghost_role/sentience minimum_required = 1 @@ -75,6 +76,8 @@ name = "Station-wide Human-level Intelligence" typepath = /datum/round_event/ghost_role/sentience/all weight = 0 + category = EVENT_CATEGORY_FRIENDLY + description = "ALL animals and robots become sentient, provided there is enough ghosts." /datum/round_event/ghost_role/sentience/all one = "all" diff --git a/code/modules/events/shuttle_catastrophe b/code/modules/events/shuttle_catastrophe.dm similarity index 91% rename from code/modules/events/shuttle_catastrophe rename to code/modules/events/shuttle_catastrophe.dm index d948b39d3b..18b9dc61ca 100644 --- a/code/modules/events/shuttle_catastrophe +++ b/code/modules/events/shuttle_catastrophe.dm @@ -3,10 +3,14 @@ typepath = /datum/round_event/shuttle_catastrophe weight = 10 max_occurrences = 1 + category = EVENT_CATEGORY_BUREAUCRATIC + description = "Replaces the emergency shuttle with a random one." /datum/round_event_control/shuttle_catastrophe/canSpawnEvent(players, gamemode) if(SSshuttle.emergency.name == "Build your own shuttle kit") return FALSE //don't undo manual player engineering, it also would unload people and ghost them, there's just a lot of problems + if(SSshuttle.emergency.in_flight()) + return FALSE //ditto, problems return ..() diff --git a/code/modules/events/shuttle_loan.dm b/code/modules/events/shuttle_loan.dm index 347162d9c5..49a0f94000 100644 --- a/code/modules/events/shuttle_loan.dm +++ b/code/modules/events/shuttle_loan.dm @@ -13,10 +13,12 @@ typepath = /datum/round_event/shuttle_loan max_occurrences = 1 earliest_start = 7 MINUTES + category = EVENT_CATEGORY_BUREAUCRATIC + description = "If cargo accepts the offer, fills the shuttle with loot and/or enemies." /datum/round_event/shuttle_loan - announceWhen = 1 - endWhen = 500 + announce_when = 1 + end_when = 500 var/dispatched = 0 var/dispatch_type = 0 var/bonus_points = 10000 @@ -72,7 +74,7 @@ var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) if(D) D.adjust_money(bonus_points) - endWhen = activeFor + 1 + end_when = activeFor + 1 SSshuttle.supply.mode = SHUTTLE_CALL SSshuttle.supply.destination = SSshuttle.getDock("supply_home") @@ -101,9 +103,9 @@ /datum/round_event/shuttle_loan/tick() if(dispatched) if(SSshuttle.supply.mode != SHUTTLE_IDLE) - endWhen = activeFor + end_when = activeFor else - endWhen = activeFor + 1 + end_when = activeFor + 1 /datum/round_event/shuttle_loan/end() if(SSshuttle.shuttle_loan && SSshuttle.shuttle_loan.dispatched) @@ -271,7 +273,7 @@ name = "Objectives of a Bee Liberation Front Operative" info = "Objective #1. Liberate all bees on the NT transport vessel 2416/B. Success!
    Objective #2. Escape alive. Failed." -/obj/machinery/syndicatebomb/shuttle_loan/Initialize() +/obj/machinery/syndicatebomb/shuttle_loan/Initialize(mapload) . = ..() setAnchored(TRUE) timer_set = rand(480, 600) //once the supply shuttle docks (after 5 minutes travel time), players have between 3-5 minutes to defuse the bomb diff --git a/code/modules/events/space_dragon.dm b/code/modules/events/space_dragon.dm index 7b242f1dfe..9298767a42 100644 --- a/code/modules/events/space_dragon.dm +++ b/code/modules/events/space_dragon.dm @@ -4,15 +4,18 @@ weight = 8 max_occurrences = 1 min_players = 20 + dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_ENTITIES + description = "Spawns a space dragon, which will try to take over the station." /datum/round_event/ghost_role/space_dragon minimum_required = 1 role_name = "Space Dragon" - announceWhen = 10 + announce_when = 10 /datum/round_event/ghost_role/space_dragon/announce(fake) - priority_announce("A large organic energy flux has been recorded near of [station_name()], please stand-by.", "Lifesign Alert") - + priority_announce("A large organic energy flux has been recorded near of [station_name()], please stand-by.", "Lifesign Alert", has_important_message = TRUE) + /datum/round_event/ghost_role/space_dragon/spawn_role() var/list/spawn_locs = list() for(var/obj/effect/landmark/carpspawn/carp_spawn in GLOB.landmarks_list) @@ -23,11 +26,11 @@ if(!spawn_locs.len) message_admins("No valid spawn locations found, aborting...") return MAP_ERROR - + var/list/candidates = get_candidates(ROLE_SPACE_DRAGON, null, ROLE_SPACE_DRAGON) if(!candidates.len) return NOT_ENOUGH_PLAYERS - + var/mob/dead/selected = pick_n_take(candidates) var/datum/mind/player_mind = new /datum/mind(selected.key) diff --git a/code/modules/events/space_ninja.dm b/code/modules/events/space_ninja.dm new file mode 100644 index 0000000000..6f4564cb63 --- /dev/null +++ b/code/modules/events/space_ninja.dm @@ -0,0 +1,54 @@ +/datum/round_event_control/space_ninja + name = "Spawn Space Ninja" + typepath = /datum/round_event/ghost_role/space_ninja + max_occurrences = 1 + weight = 10 + earliest_start = 20 MINUTES + min_players = 15 + dynamic_should_hijack = TRUE + category = EVENT_CATEGORY_INVASION + description = "A space ninja infiltrates the station." + +/datum/round_event/ghost_role/space_ninja + minimum_required = 1 + role_name = "Space Ninja" + +/datum/round_event/ghost_role/space_ninja/spawn_role() + var/list/spawn_locs = list() + for(var/obj/effect/landmark/carpspawn/carp_spawn in GLOB.landmarks_list) + if(!isturf(carp_spawn.loc)) + stack_trace("Carp spawn found not on a turf: [carp_spawn.type] on [isnull(carp_spawn.loc) ? "null" : carp_spawn.loc.type]") + continue + spawn_locs += carp_spawn.loc + if(!spawn_locs.len) + message_admins("No valid spawn locations found, aborting...") + return MAP_ERROR + + //selecting a candidate player + var/list/candidates = get_candidates(ROLE_NINJA, null, ROLE_NINJA) + if(!candidates.len) + return NOT_ENOUGH_PLAYERS + + var/mob/dead/selected_candidate = pick(candidates) + var/key = selected_candidate.key + + //spawn the ninja and assign the candidate + var/mob/living/carbon/human/ninja = create_space_ninja(pick(spawn_locs)) + ninja.key = key + ninja.mind.add_antag_datum(/datum/antagonist/ninja) + spawned_mobs += ninja + message_admins("[ADMIN_LOOKUPFLW(ninja)] has been made into a space ninja by an event.") + log_game("[key_name(ninja)] was spawned as a ninja by an event.") + + return SUCCESSFUL_SPAWN + + +//=======//NINJA CREATION PROCS//=======// + +/proc/create_space_ninja(spawn_loc) + var/mob/living/carbon/human/new_ninja = new(spawn_loc) + var/datum/preferences/random_human_options = new()//Randomize appearance for the ninja. + random_human_options.real_name = "[pick(GLOB.ninja_titles)] [pick(GLOB.ninja_names)]" + random_human_options.copy_to(new_ninja) + new_ninja.dna.update_dna_identity() + return new_ninja diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index 6fcaa5e6b0..1bbcb0dd92 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -4,6 +4,8 @@ weight = 15 max_occurrences = 3 min_players = 20 + category = EVENT_CATEGORY_ENTITIES + description = "Kudzu begins to overtake the station. Might spawn man-traps." /datum/round_event/spacevine fakeable = FALSE @@ -276,7 +278,7 @@ var/datum/spacevine_controller/master = null var/list/mutations = list() -/obj/structure/spacevine/Initialize() +/obj/structure/spacevine/Initialize(mapload) . = ..() add_atom_colour("#ffffff", FIXED_COLOUR_PRIORITY) @@ -327,7 +329,7 @@ user.DelayNextAction() for(var/datum/spacevine_mutation/SM in mutations) damage_dealt = SM.on_hit(src, user, I, damage_dealt) //on_hit now takes override damage as arg and returns new value for other mutations to permutate further - take_damage(damage_dealt, I.damtype, "melee", 1) + take_damage(damage_dealt, I.damtype, MELEE, 1) /obj/structure/spacevine/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) @@ -507,7 +509,7 @@ if(master) master.spawn_spacevine_piece(stepturf, src) -/obj/structure/spacevine/ex_act(severity, target) +/obj/structure/spacevine/ex_act(severity, target, origin) if(istype(target, type)) //if its agressive spread vine dont do anything return var/i @@ -523,7 +525,7 @@ if(!override) qdel(src) -/obj/structure/spacevine/CanPass(atom/movable/mover, turf/target) +/obj/structure/spacevine/CanAllowThrough(atom/movable/mover, turf/target) . = ..() if(isvineimmune(mover)) return TRUE diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm index 23ce6ce730..6e8c29d3a9 100644 --- a/code/modules/events/spider_infestation.dm +++ b/code/modules/events/spider_infestation.dm @@ -4,15 +4,17 @@ weight = 5 max_occurrences = 1 min_players = 15 + category = EVENT_CATEGORY_ENTITIES + description = "Spawns spider eggs, ready to hatch." /datum/round_event/spider_infestation - announceWhen = 400 + announce_when = 400 var/spawncount = 1 /datum/round_event/spider_infestation/setup() - announceWhen = rand(announceWhen, announceWhen + 50) + announce_when = rand(announce_when, announce_when + 50) spawncount = rand(5, 8) /datum/round_event/spider_infestation/announce(fake) diff --git a/code/modules/events/spontaneous_appendicitis.dm b/code/modules/events/spontaneous_appendicitis.dm index 7705ece78a..31b14bb8b9 100644 --- a/code/modules/events/spontaneous_appendicitis.dm +++ b/code/modules/events/spontaneous_appendicitis.dm @@ -5,6 +5,8 @@ max_occurrences = 4 earliest_start = 10 MINUTES min_players = 5 // To make your chance of getting help a bit higher. + category = EVENT_CATEGORY_HEALTH + description = "A random crewmember gets appendicitis." /datum/round_event/spontaneous_appendicitis fakeable = FALSE diff --git a/code/modules/events/stray_cargo.dm b/code/modules/events/stray_cargo.dm index a4db18a3b5..f7240f9e8b 100644 --- a/code/modules/events/stray_cargo.dm +++ b/code/modules/events/stray_cargo.dm @@ -5,6 +5,8 @@ weight = 5 max_occurrences = 4 earliest_start = 10 MINUTES + category = EVENT_CATEGORY_BUREAUCRATIC + description = "A pod containing a random supply crate lands on the station." ///Spawns a cargo pod containing a random cargo supply pack on a random area of the station /datum/round_event/stray_cargo @@ -13,14 +15,14 @@ var/static/list/stray_spawnable_supply_packs = list() ///List of default spawnable supply packs, filtered from the cargo list /datum/round_event/stray_cargo/announce(fake) - priority_announce("Stray cargo pod detected on long-range scanners. Expected location of impact: [impact_area.name].", "Collision Alert") + priority_announce("Stray cargo pod detected on long-range scanners. Expected location of impact: [impact_area.name].", "Collision Alert", has_important_message = TRUE) /** * Tries to find a valid area, throws an error if none are found * Also randomizes the start timer */ /datum/round_event/stray_cargo/setup() - startWhen = rand(20, 40) + start_when = rand(20, 40) impact_area = find_event_area() if(!impact_area) CRASH("No valid areas for cargo pod found.") @@ -89,6 +91,7 @@ weight = 0 max_occurrences = 0 earliest_start = 30 MINUTES + description = "A pod containing syndicate gear lands on the station." /datum/round_event/stray_cargo/syndicate possible_pack_types = list(/datum/supply_pack/misc/syndicate) diff --git a/code/modules/events/supermatter_surge.dm b/code/modules/events/supermatter_surge.dm index 6b0a093440..08deaae7d5 100644 --- a/code/modules/events/supermatter_surge.dm +++ b/code/modules/events/supermatter_surge.dm @@ -2,8 +2,10 @@ name = "Supermatter Surge" typepath = /datum/round_event/supermatter_surge weight = 20 - max_occurrences = 4 + max_occurrences = 5 earliest_start = 10 MINUTES + category = EVENT_CATEGORY_ENGINEERING + description = "Randomly modifies the supermatter's power, giving the engineers a lot of headaches." /datum/round_event_control/supermatter_surge/canSpawnEvent() if(GLOB.main_supermatter_engine?.has_been_powered) @@ -20,6 +22,7 @@ /datum/round_event/supermatter_surge/announce() var/severity = "" + var/important = FALSE switch(power) if(-INFINITY to 100000) var/low_threat_perc = 100-round(100*((power-200)/(100000-200))) @@ -27,13 +30,29 @@ if(prob(low_threat_perc)) severity = "low; the supermatter should return to normal operation shortly." else - severity = "medium; the supermatter should return to normal operation, but check NT CIMS to ensure this." + severity = "medium; the supermatter should return to normal operation, but regardless, check if the emitters may need to be turned off temporarily." else - severity = "high; if the supermatter's cooling is not fortified, coolant may need to be added." + severity = "high; the emitters likely need to be turned off, and if the supermatter's cooling loop is not fortified, pre-cooled gas may need to be added." + important = TRUE if(100000 to INFINITY) - severity = "extreme; emergency action is likely to be required even if coolant loop is fine." + severity = "extreme; emergency action is likely to be required even if coolant loop is fine. Turn off the emitters and make sure the loop is properly cooling gases." + important = TRUE if(power > 20000 || prob(round(power/200))) - priority_announce("Supermatter surge detected. Estimated severity is [severity]", "Anomaly Alert") + priority_announce("Supermatter surge detected. Estimated severity is [severity]", "Anomaly Alert", has_important_message = important) /datum/round_event/supermatter_surge/start() - GLOB.main_supermatter_engine.matter_power += power + var/obj/machinery/power/supermatter_crystal/supermatter = GLOB.main_supermatter_engine + var/power_proportion = supermatter.powerloss_inhibitor * 0.75 // what % of the power goes into matter power, at most 50% + // we reduce the proportion that goes into actual matter power based on powerloss inhibitor + // primarily so the supermatter doesn't tesla the instant these happen + supermatter.matter_power += power * power_proportion + var/datum/gas_mixture/methane_puff = new + var/selected_gas = pick(4;GAS_CO2, 10;GAS_METHANE, 4;GAS_H2O, 1;GAS_BZ, 1;GAS_METHYL_BROMIDE) + methane_puff.set_moles(selected_gas, 500) + methane_puff.set_temperature(500) + var/energy_ratio = (power * 500 * (1-power_proportion)) / methane_puff.thermal_energy() + if(energy_ratio < 1) // energy output we want is lower than current energy, reduce the amount of gas we puff out + methane_puff.set_moles(GAS_METHANE, energy_ratio * 500) + else // energy output we want is higher than current energy, increase its actual heat + methane_puff.set_temperature(energy_ratio * 500) + supermatter.assume_air(methane_puff) diff --git a/code/modules/events/supernova.dm b/code/modules/events/supernova.dm index e1d6991c89..16c81e4056 100644 --- a/code/modules/events/supernova.dm +++ b/code/modules/events/supernova.dm @@ -1,21 +1,23 @@ /datum/round_event_control/supernova name = "Supernova" typepath = /datum/round_event/supernova - weight = 10 - max_occurrences = 2 + weight = 5 + max_occurrences = 1 min_players = 2 + category = EVENT_CATEGORY_SPACE + description = "Several modified radstorms hit the station." /datum/round_event/supernova - announceWhen = 40 - startWhen = 1 - endWhen = 300 + announce_when = 40 + start_when = 1 + end_when = 300 var/power = 1 var/datum/sun/supernova var/storm_count = 0 var/announced = FALSE /datum/round_event/supernova/setup() - announceWhen = rand(4, 60) + announce_when = rand(4, 60) supernova = new SSsun.suns += supernova switch(rand(1,5)) @@ -33,7 +35,7 @@ /datum/round_event/supernova/announce() var/message = "[station_name()]: Our tachyon-doppler array has detected a supernova in your vicinity. Peak flux from the supernova estimated to be [round(power,0.1)] times current solar flux; if the supernova is close to your sun in the sky, your solars may receive this as a power boost.[power > 1 ? " Short burts of radiation may be possible, so please prepare accordingly." : "We expect no radiation bursts from this one."] We hope you enjoy the light." if(prob(power * 25)) - priority_announce(message, sender_override = "Nanotrasen Meteorology Division") + priority_announce(message, sender_override = "Nanotrasen Meteorology Division", has_important_message = TRUE) announced = TRUE else print_command_report(message) @@ -53,12 +55,12 @@ sucker_light.give_home_power() /datum/round_event/supernova/tick() - var/midpoint = round((endWhen-startWhen)/2) + var/midpoint = round((end_when-start_when)/2) if(activeFor < midpoint) supernova.power_mod = min(supernova.power_mod*1.2, power) - if(activeFor > endWhen-10) + if(activeFor > end_when-10) supernova.power_mod /= 4 - if(prob(round(supernova.power_mod)) && prob(3) && storm_count < 5 && !SSweather.get_weather_by_type(/datum/weather/rad_storm)) + if(prob(round(supernova.power_mod)) && prob(5-storm_count) && !SSweather.get_weather_by_type(/datum/weather/rad_storm)) SSweather.run_weather(/datum/weather/rad_storm/supernova) storm_count++ @@ -73,6 +75,6 @@ weather_duration_lower = 50 weather_duration_upper = 100 telegraph_duration = 200 - radiation_intensity = 1000 + radiation_intensity = 500 weather_sound = null telegraph_message = "The air begins to grow very warm!" diff --git a/code/modules/events/travelling_trader.dm b/code/modules/events/travelling_trader.dm index f7cbba2e4a..ac9d103f5f 100644 --- a/code/modules/events/travelling_trader.dm +++ b/code/modules/events/travelling_trader.dm @@ -4,10 +4,12 @@ weight = 8 max_occurrences = 2 earliest_start = 0 MINUTES + category = EVENT_CATEGORY_FRIENDLY + description = "A mysterious figure requests something to the crew and rewards them with something for getting it done." /datum/round_event/travelling_trader - startWhen = 0 - endWhen = 900 //you effectively have 15 minutes to complete the traders request, before they disappear + start_when = 0 + end_when = 900 //you effectively have 15 minutes to complete the traders request, before they disappear var/mob/living/carbon/human/dummy/travelling_trader/trader var/atom/spawn_location //where the trader appears @@ -28,7 +30,7 @@ trader.visible_message("[trader] suddenly appears in a puff of smoke!") /datum/round_event/travelling_trader/announce(fake) - priority_announce("A mysterious figure has been detected on sensors at [get_area(spawn_location)]", "Mysterious Figure") + priority_announce("A mysterious figure has been detected on sensors at [get_area(spawn_location)]", "Mysterious Figure", has_important_message = !fake) /datum/round_event/travelling_trader/end() if(trader) // the /datum/round_event/travelling_trader has given up on waiting! @@ -98,7 +100,7 @@ var/reward = pickweight(possible_rewards) new reward(get_turf(src)) -/mob/living/carbon/human/dummy/travelling_trader/Initialize() +/mob/living/carbon/human/dummy/travelling_trader/Initialize(mapload) . = ..() // return a hint you fuck add_atom_colour("#570d6b", FIXED_COLOUR_PRIORITY) //make them purple (otherworldly!) set_light(1, -0.7, "#AAD84B") @@ -134,7 +136,7 @@ /obj/item/kitchen/fork/throwing = 1, /mob/living/simple_animal/cow/random = 1) -/mob/living/carbon/human/dummy/travelling_trader/cook/Initialize() +/mob/living/carbon/human/dummy/travelling_trader/cook/Initialize(mapload) //pick a random crafted food item as the requested item var/datum/crafting_recipe/food_recipe = pick(subtypesof(/datum/crafting_recipe/food)) var/result = initial(food_recipe.result) @@ -158,7 +160,7 @@ /obj/item/seeds/gatfruit = 1) //overall you have less chance of seeing them than a lifebringer just bringing the seeds to you directly -/mob/living/carbon/human/dummy/travelling_trader/gardener/Initialize() +/mob/living/carbon/human/dummy/travelling_trader/gardener/Initialize(mapload) requested_item = pick(subtypesof(/obj/item/reagent_containers/food/snacks/grown) - list(/obj/item/reagent_containers/food/snacks/grown/shell, /obj/item/reagent_containers/food/snacks/grown/shell/gatfruit, /obj/item/reagent_containers/food/snacks/grown/cherry_bomb)) @@ -188,7 +190,7 @@ /mob/living/simple_animal/hostile/netherworld/blankbody = 1, /mob/living/simple_animal/hostile/retaliate/goose = 1) -/mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize() +/mob/living/carbon/human/dummy/travelling_trader/animal_hunter/Initialize(mapload) . = ..() acceptance_speech = pick(list("This lifeform shall make for a great stew, thank you.", "This lifeform shall be of a true use to our cause, thank you.", "The lifeform is adequate. Goodbye.", "This lifeform shall make a great addition to my collection.")) @@ -222,7 +224,7 @@ /obj/structure/reagent_dispensers/keg/narsour = 3, /obj/structure/reagent_dispensers/keg/quintuple_sec = 3) -/mob/living/carbon/human/dummy/travelling_trader/bartender/Initialize() //pick a subtype of ethanol that isn't found in the default set of the booze dispensers reagents +/mob/living/carbon/human/dummy/travelling_trader/bartender/Initialize(mapload) //pick a subtype of ethanol that isn't found in the default set of the booze dispensers reagents . = ..() // RETURN A HINT. requested_item = pick(subtypesof(/datum/reagent/consumable/ethanol) - list(/datum/reagent/consumable/ethanol/beer, /datum/reagent/consumable/ethanol/kahlua, @@ -276,7 +278,7 @@ /obj/item/stack/sticky_tape/infinite = 2, /obj/item/clothing/suit/hooded/wintercoat/cosmic = 2) -/mob/living/carbon/human/dummy/travelling_trader/artifact_dealer/Initialize() +/mob/living/carbon/human/dummy/travelling_trader/artifact_dealer/Initialize(mapload) possible_rewards += list(pick(subtypesof(/obj/item/clothing/head/collectable)) = 1) //this is slightly lower because it's absolutely useless ..() diff --git a/code/modules/events/untie_shoes.dm b/code/modules/events/untie_shoes.dm new file mode 100644 index 0000000000..17dd2ca8b2 --- /dev/null +++ b/code/modules/events/untie_shoes.dm @@ -0,0 +1,33 @@ +/datum/round_event_control/untied_shoes + name = "Untied Shoes" + typepath = /datum/round_event/untied_shoes + weight = 50 + max_occurrences = 10 + alert_observers = FALSE + category = EVENT_CATEGORY_HEALTH + description = "Unties people's shoes, with a chance to knot them as well." + +/datum/round_event/untied_shoes + fakeable = FALSE + +/datum/round_event/untied_shoes/start() + var/budget = rand(5 SECONDS,20 SECONDS) + for(var/mob/living/carbon/C in shuffle(GLOB.alive_mob_list)) + if(!C.client) + continue + if(C.stat == DEAD) + continue + if (HAS_TRAIT(C,TRAIT_EXEMPT_HEALTH_EVENTS)) + continue + if(!C.shoes || !C.shoes.can_be_tied || C.shoes.tied != SHOES_TIED || C.shoes.lace_time > budget) + continue + if(!is_station_level(C.z) && prob(50)) + continue + if(prob(5)) + C.shoes.adjust_laces(SHOES_KNOTTED) + budget -= C.shoes.lace_time // doubling up on the budget removal on purpose + else + C.shoes.adjust_laces(SHOES_UNTIED) + budget -= C.shoes.lace_time + if(budget < 5 SECONDS) + return diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm index cd7b23a577..fb88f81598 100644 --- a/code/modules/events/vent_clog.dm +++ b/code/modules/events/vent_clog.dm @@ -3,15 +3,16 @@ typepath = /datum/round_event/vent_clog weight = 10 max_occurrences = 3 - min_players = 25 + category = EVENT_CATEGORY_HEALTH + description = "All the scrubbers onstation spit random chemicals in smoke form." /datum/round_event/vent_clog - announceWhen = 1 - startWhen = 5 - endWhen = 35 + announce_when = 1 + start_when = 5 + end_when = 35 var/interval = 2 var/list/vents = list() - var/randomProbability = 1 + var/randomProbability = 0 var/reagentsAmount = 100 var/list/saferChems = list( /datum/reagent/water, @@ -60,10 +61,10 @@ //needs to be chemid unit checked at some point /datum/round_event/vent_clog/announce() - priority_announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert") + priority_announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert", has_important_message = TRUE) /datum/round_event/vent_clog/setup() - endWhen = rand(120, 180) + end_when = rand(120, 180) for(var/obj/machinery/atmospherics/components/unary/vent_scrubber/temp_vent in GLOB.machines) var/turf/T = get_turf(temp_vent) var/area/A = T.loc @@ -92,7 +93,7 @@ var/datum/reagents/R = new/datum/reagents(1000) R.my_atom = vent - if (prob(randomProbability)) + if (randomProbability && prob(randomProbability)) R.add_reagent(get_random_reagent_id(), reagentsAmount) else R.add_reagent(pick(saferChems), reagentsAmount) @@ -106,9 +107,10 @@ name = "Clogged Vents: Threatening" typepath = /datum/round_event/vent_clog/threatening weight = 4 - min_players = 35 + min_players = 15 max_occurrences = 1 earliest_start = 35 MINUTES + description = "Extra dangerous chemicals come out of the scrubbers." /datum/round_event/vent_clog/threatening randomProbability = 10 @@ -118,9 +120,10 @@ name = "Clogged Vents: Catastrophic" typepath = /datum/round_event/vent_clog/catastrophic weight = 2 - min_players = 45 + min_players = 25 max_occurrences = 1 earliest_start = 45 MINUTES + description = "EXTREMELY dangerous chemicals come out of the scrubbers." /datum/round_event/vent_clog/catastrophic randomProbability = 30 @@ -130,6 +133,7 @@ name = "Clogged Vents: Beer" typepath = /datum/round_event/vent_clog/beer max_occurrences = 0 + description = "Spits out beer through the scrubber system." /datum/round_event/vent_clog/beer reagentsAmount = 100 @@ -138,6 +142,7 @@ name = "Anti-Plasma Flood" typepath = /datum/round_event/vent_clog/plasma_decon max_occurrences = 0 + description = "Freezing smoke comes out of the scrubbers." /datum/round_event/vent_clog/beer/announce() priority_announce("The scrubbers network is experiencing an unexpected surge of pressurized beer. Some ejection of contents may occur.", "Atmospherics alert") diff --git a/code/modules/events/wisdomcow.dm b/code/modules/events/wisdomcow.dm index 553dd8f309..3c03911d1d 100644 --- a/code/modules/events/wisdomcow.dm +++ b/code/modules/events/wisdomcow.dm @@ -3,6 +3,8 @@ typepath = /datum/round_event/wisdomcow max_occurrences = 1 weight = 10 + category = EVENT_CATEGORY_FRIENDLY + description = "A cow appears to tell you wise words." /datum/round_event/wisdomcow/announce(fake) priority_announce("A wise cow has been spotted in the area. Be sure to ask for her advice.", "Nanotrasen Cow Ranching Agency") diff --git a/code/modules/events/wizard/aid.dm b/code/modules/events/wizard/aid.dm index 5f49b48900..2380027284 100644 --- a/code/modules/events/wizard/aid.dm +++ b/code/modules/events/wizard/aid.dm @@ -6,6 +6,7 @@ typepath = /datum/round_event/wizard/robelesscasting max_occurrences = 1 earliest_start = 0 MINUTES + description = "Wizard no longer needs robes to cast spells." /datum/round_event/wizard/robelesscasting/start() @@ -28,6 +29,7 @@ typepath = /datum/round_event/wizard/improvedcasting max_occurrences = 4 //because that'd be max level spells earliest_start = 0 MINUTES + description = "Levels up the wizard's spells." /datum/round_event/wizard/improvedcasting/start() for(var/i in GLOB.mob_living_list) diff --git a/code/modules/events/wizard/blobies.dm b/code/modules/events/wizard/blobies.dm index 7438b462f6..6933847f80 100644 --- a/code/modules/events/wizard/blobies.dm +++ b/code/modules/events/wizard/blobies.dm @@ -3,6 +3,7 @@ weight = 3 typepath = /datum/round_event/wizard/blobies max_occurrences = 3 + description = "Spawns a blob spore on every corpse." /datum/round_event/wizard/blobies/start() diff --git a/code/modules/events/wizard/curseditems.dm b/code/modules/events/wizard/curseditems.dm index 2f0b9c68f8..639673ac15 100644 --- a/code/modules/events/wizard/curseditems.dm +++ b/code/modules/events/wizard/curseditems.dm @@ -5,6 +5,7 @@ max_occurrences = 3 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE + description = "Gives everyone a cursed item." //Note about adding items to this: Because of how NODROP_1 works if an item spawned to the hands can also be equiped to a slot //it will be able to be put into that slot from the hand, but then get stuck there. To avoid this make a new subtype of any @@ -18,23 +19,23 @@ switch(item_set) if("wizardmimic") - loadout[SLOT_WEAR_SUIT] = /obj/item/clothing/suit/wizrobe - loadout[SLOT_SHOES] = /obj/item/clothing/shoes/sandal/magic - loadout[SLOT_HEAD] = /obj/item/clothing/head/wizard + loadout[ITEM_SLOT_OCLOTHING] = /obj/item/clothing/suit/wizrobe + loadout[ITEM_SLOT_FEET] = /obj/item/clothing/shoes/sandal/magic + loadout[ITEM_SLOT_HEAD] = /obj/item/clothing/head/wizard ruins_spaceworthiness = 1 if("swords") - loadout[SLOT_HANDS] = /obj/item/katana/cursed + loadout[ITEM_SLOT_HANDS] = /obj/item/katana/cursed if("bigfatdoobie") - loadout[SLOT_WEAR_MASK] = /obj/item/clothing/mask/cigarette/rollie/trippy + loadout[ITEM_SLOT_MASK] = /obj/item/clothing/mask/cigarette/rollie/trippy ruins_spaceworthiness = 1 if("boxing") - loadout[SLOT_WEAR_MASK] = /obj/item/clothing/mask/luchador - loadout[SLOT_GLOVES] = /obj/item/clothing/gloves/boxing + loadout[ITEM_SLOT_MASK] = /obj/item/clothing/mask/luchador + loadout[ITEM_SLOT_GLOVES] = /obj/item/clothing/gloves/boxing ruins_spaceworthiness = 1 if("voicemodulators") - loadout[SLOT_WEAR_MASK] = /obj/item/clothing/mask/chameleon + loadout[ITEM_SLOT_MASK] = /obj/item/clothing/mask/chameleon if("catgirls2015") - loadout[SLOT_HEAD] = /obj/item/clothing/head/kitty + loadout[ITEM_SLOT_HEAD] = /obj/item/clothing/head/kitty ruins_spaceworthiness = 1 ruins_wizard_loadout = 1 diff --git a/code/modules/events/wizard/departmentrevolt.dm b/code/modules/events/wizard/departmentrevolt.dm index b82cd91323..20f361b775 100644 --- a/code/modules/events/wizard/departmentrevolt.dm +++ b/code/modules/events/wizard/departmentrevolt.dm @@ -5,6 +5,7 @@ max_occurrences = 1 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE // not removing it completely yet + description = "A department is turned into an independent state." /datum/round_event/wizard/deprevolt/start() diff --git a/code/modules/events/wizard/embeddies.dm b/code/modules/events/wizard/embeddies.dm index fe08b9c743..32c9affb6d 100644 --- a/code/modules/events/wizard/embeddies.dm +++ b/code/modules/events/wizard/embeddies.dm @@ -4,6 +4,7 @@ typepath = /datum/round_event/wizard/embedpocalypse max_occurrences = 1 earliest_start = 0 MINUTES + description = "Everything becomes pointy enough to embed in people when thrown." /datum/round_event/wizard/embedpocalypse/start() for(var/obj/item/I in world) @@ -26,6 +27,7 @@ typepath = /datum/round_event/wizard/embedpocalypse/sticky max_occurrences = 1 earliest_start = 0 MINUTES + description = "Everything becomes sticky enough to be glued to people when thrown." /datum/round_event_control/wizard/embedpocalypse/sticky/canSpawnEvent(players_amt, gamemode) if(GLOB.embedpocalypse) diff --git a/code/modules/events/wizard/fakeexplosion.dm b/code/modules/events/wizard/fakeexplosion.dm index 3ba20f4768..7a89fc14bd 100644 --- a/code/modules/events/wizard/fakeexplosion.dm +++ b/code/modules/events/wizard/fakeexplosion.dm @@ -4,6 +4,7 @@ typepath = /datum/round_event/wizard/fake_explosion max_occurrences = 1 earliest_start = 0 MINUTES + description = "The nuclear explosion cutscene begins to play to scare the crew." /datum/round_event/wizard/fake_explosion/start() sound_to_playing_players('sound/machines/alarm.ogg') diff --git a/code/modules/events/wizard/ghost.dm b/code/modules/events/wizard/ghost.dm index c288953efb..5a11616b8f 100644 --- a/code/modules/events/wizard/ghost.dm +++ b/code/modules/events/wizard/ghost.dm @@ -4,6 +4,7 @@ typepath = /datum/round_event/wizard/ghost max_occurrences = 1 earliest_start = 0 MINUTES + description = "Ghosts become visible." /datum/round_event/wizard/ghost/start() var/msg = "You suddenly feel extremely obvious..." @@ -18,6 +19,7 @@ typepath = /datum/round_event/wizard/possession max_occurrences = 5 earliest_start = 0 MINUTES + description = "Ghosts become visible and gain the power of possession." /datum/round_event/wizard/possession/start() for(var/mob/dead/observer/G in GLOB.player_list) diff --git a/code/modules/events/wizard/greentext.dm b/code/modules/events/wizard/greentext.dm index 82e72df3b9..1864ad6d20 100644 --- a/code/modules/events/wizard/greentext.dm +++ b/code/modules/events/wizard/greentext.dm @@ -4,6 +4,7 @@ typepath = /datum/round_event/wizard/greentext max_occurrences = 1 earliest_start = 0 MINUTES + description = "The Green Text appears on the station, tempting people to try and pick it up." /datum/round_event/wizard/greentext/start() diff --git a/code/modules/events/wizard/imposter.dm b/code/modules/events/wizard/imposter.dm index 29704168e9..2b7e9bcf17 100644 --- a/code/modules/events/wizard/imposter.dm +++ b/code/modules/events/wizard/imposter.dm @@ -4,6 +4,7 @@ typepath = /datum/round_event/wizard/imposter max_occurrences = 1 earliest_start = 0 MINUTES + description = "Spawns a doppelganger of the wizard." /datum/round_event/wizard/imposter/start() for(var/datum/mind/M in SSticker.mode.wizards) diff --git a/code/modules/events/wizard/invincible.dm b/code/modules/events/wizard/invincible.dm index b69d1541ee..0dea1fbaf7 100644 --- a/code/modules/events/wizard/invincible.dm +++ b/code/modules/events/wizard/invincible.dm @@ -4,6 +4,7 @@ typepath = /datum/round_event/wizard/invincible max_occurrences = 5 earliest_start = 0 MINUTES + description = "Everyone is invincible for a short time ticks." /datum/round_event/wizard/invincible/start() diff --git a/code/modules/events/wizard/lava.dm b/code/modules/events/wizard/lava.dm index 9a882b45df..75962c81ad 100644 --- a/code/modules/events/wizard/lava.dm +++ b/code/modules/events/wizard/lava.dm @@ -4,9 +4,10 @@ typepath = /datum/round_event/wizard/lava max_occurrences = 3 earliest_start = 0 MINUTES + description = "Turns the floor into hot lava." /datum/round_event/wizard/lava - endWhen = 0 + end_when = 0 var/started = FALSE /datum/round_event/wizard/lava/start() diff --git a/code/modules/events/wizard/madness.dm b/code/modules/events/wizard/madness.dm index ac86236623..de2c30a032 100644 --- a/code/modules/events/wizard/madness.dm +++ b/code/modules/events/wizard/madness.dm @@ -3,6 +3,7 @@ weight = 1 typepath = /datum/round_event/wizard/madness earliest_start = 0 MINUTES + description = "Reveals a horrifying truth to everyone, giving them a trauma." var/forced_secret diff --git a/code/modules/events/wizard/magicarp.dm b/code/modules/events/wizard/magicarp.dm index 57e2a2a051..b900a2da9f 100644 --- a/code/modules/events/wizard/magicarp.dm +++ b/code/modules/events/wizard/magicarp.dm @@ -4,13 +4,14 @@ typepath = /datum/round_event/wizard/magicarp max_occurrences = 1 earliest_start = 0 MINUTES + description = "Summons a school of carps with magic projectiles." /datum/round_event/wizard/magicarp - announceWhen = 3 - startWhen = 50 + announce_when = 3 + start_when = 50 /datum/round_event/wizard/magicarp/setup() - startWhen = rand(40, 60) + start_when = rand(40, 60) /datum/round_event/wizard/magicarp/announce(fake) priority_announce("Unknown magical entities have been detected near [station_name()], please stand-by.", "Lifesign Alert") @@ -41,7 +42,7 @@ /obj/item/projectile/magic/death, /obj/item/projectile/magic/teleport, /obj/item/projectile/magic/door, /obj/item/projectile/magic/aoe/fireball, /obj/item/projectile/magic/spellblade, /obj/item/projectile/magic/arcane_barrage) -/mob/living/simple_animal/hostile/carp/ranged/Initialize() +/mob/living/simple_animal/hostile/carp/ranged/Initialize(mapload) projectiletype = pick(allowed_projectile_types) . = ..() diff --git a/code/modules/events/wizard/petsplosion.dm b/code/modules/events/wizard/petsplosion.dm index fb4d433905..ff3ebdd128 100644 --- a/code/modules/events/wizard/petsplosion.dm +++ b/code/modules/events/wizard/petsplosion.dm @@ -5,6 +5,7 @@ max_occurrences = 1 //Exponential growth is nothing to sneeze at! earliest_start = 0 MINUTES var/mobs_to_dupe = 0 + description = "Rapidly multiplies the animals on the station." /datum/round_event_control/wizard/petsplosion/preRunEvent() for(var/mob/living/simple_animal/F in GLOB.alive_mob_list) @@ -16,7 +17,7 @@ ..() /datum/round_event/wizard/petsplosion - endWhen = 61 //1 minute (+1 tick for endWhen not to interfere with tick) + end_when = 61 //1 minute (+1 tick for end_when not to interfere with tick) var/countdown = 0 var/mobs_duped = 0 diff --git a/code/modules/events/wizard/race.dm b/code/modules/events/wizard/race.dm index 5c3b8432c1..8c45a9504b 100644 --- a/code/modules/events/wizard/race.dm +++ b/code/modules/events/wizard/race.dm @@ -5,6 +5,7 @@ max_occurrences = 5 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE + description = "Gives everyone a random race." /datum/round_event/wizard/race var/list/stored_name @@ -16,7 +17,7 @@ stored_name = list() stored_species = list() stored_dna = list() - endWhen = rand(600,1200) //10 to 20 minutes + end_when = rand(600,1200) //10 to 20 minutes ..() /datum/round_event/wizard/race/start() diff --git a/code/modules/events/wizard/rpgloot.dm b/code/modules/events/wizard/rpgloot.dm index bf3104450e..911a9bf665 100644 --- a/code/modules/events/wizard/rpgloot.dm +++ b/code/modules/events/wizard/rpgloot.dm @@ -4,6 +4,7 @@ typepath = /datum/round_event/wizard/rpgloot max_occurrences = 1 earliest_start = 0 MINUTES + description = "Every item in the world will have fantastical names." /datum/round_event/wizard/rpgloot/start() var/upgrade_scroll_chance = 0 diff --git a/code/modules/events/wizard/shuffle.dm b/code/modules/events/wizard/shuffle.dm index 18b8c8e21c..5659818b48 100644 --- a/code/modules/events/wizard/shuffle.dm +++ b/code/modules/events/wizard/shuffle.dm @@ -8,6 +8,7 @@ max_occurrences = 5 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE // not removing it completely yet + description = "Shuffles everyone around on the station." /datum/round_event/wizard/shuffleloc/start() var/list/moblocs = list() @@ -45,6 +46,7 @@ max_occurrences = 5 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE // not removing it completely yet + description = "Shuffles the names of everyone around the station." /datum/round_event/wizard/shufflenames/start() var/list/mobnames = list() @@ -80,6 +82,7 @@ max_occurrences = 3 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE // not removing it completely yet + description = "Shuffles the minds of everyone around the station, except for the wizard." /datum/round_event/wizard/shuffleminds/start() var/list/mobs = list() diff --git a/code/modules/events/wizard/summons.dm b/code/modules/events/wizard/summons.dm index ac1160e0f5..886dfdfd10 100644 --- a/code/modules/events/wizard/summons.dm +++ b/code/modules/events/wizard/summons.dm @@ -5,6 +5,7 @@ max_occurrences = 1 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE // not removing it completely yet + description = "Summons a gun for everyone. Might turn people into survivalists." /datum/round_event_control/wizard/summonguns/New() if(CONFIG_GET(flag/no_summon_guns)) @@ -21,6 +22,7 @@ max_occurrences = 1 earliest_start = 0 MINUTES can_be_midround_wizard = FALSE // not removing it completely yet + description = "Summons a magic item for everyone. Might turn people into survivalists." /datum/round_event_control/wizard/summonmagic/New() if(CONFIG_GET(flag/no_summon_magic)) diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm index e723ddd79b..413658e34d 100644 --- a/code/modules/events/wormholes.dm +++ b/code/modules/events/wormholes.dm @@ -4,11 +4,12 @@ max_occurrences = 3 weight = 2 min_players = 2 - + category = EVENT_CATEGORY_SPACE + description = "Space time anomalies appear on the station, randomly teleporting people who walk into them." /datum/round_event/wormholes - announceWhen = 10 - endWhen = 60 + announce_when = 10 + end_when = 60 var/list/pick_turfs = list() var/list/wormholes = list() @@ -16,8 +17,8 @@ var/number_of_wormholes = 400 /datum/round_event/wormholes/setup() - announceWhen = rand(0, 20) - endWhen = rand(40, 80) + announce_when = rand(0, 20) + end_when = rand(40, 80) /datum/round_event/wormholes/start() for(var/turf/open/floor/T in world) @@ -32,7 +33,7 @@ wormholes += new /obj/effect/portal/wormhole(T, 0, null, FALSE) /datum/round_event/wormholes/announce(fake) - priority_announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", "spanomalies") + priority_announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", "spanomalies", has_important_message = TRUE) /datum/round_event/wormholes/tick() if(activeFor % shift_frequency == 0) diff --git a/code/modules/fields/fields.dm b/code/modules/fields/fields.dm index 8c7b414996..0bdabf5e8e 100644 --- a/code/modules/fields/fields.dm +++ b/code/modules/fields/fields.dm @@ -289,7 +289,7 @@ var/datum/proximity_monitor/advanced/current = null var/mob/listeningTo -/obj/item/multitool/field_debug/Initialize() +/obj/item/multitool/field_debug/Initialize(mapload) . = ..() START_PROCESSING(SSobj, src) diff --git a/code/modules/fields/timestop.dm b/code/modules/fields/timestop.dm index a96a44a789..db42ad6798 100644 --- a/code/modules/fields/timestop.dm +++ b/code/modules/fields/timestop.dm @@ -84,7 +84,7 @@ freeze_mob(A) else if(istype(A, /obj/item/projectile)) freeze_projectile(A) - else if(istype(A, /obj/mecha)) + else if(istype(A, /obj/vehicle/sealed/mecha)) freeze_mecha(A) else if((ismachinery(A) && !istype(A, /obj/machinery/light)) || isstructure(A)) //Special exception for light fixtures since recoloring causes them to change light freeze_structure(A) @@ -120,7 +120,7 @@ unfreeze_mob(A) else if(istype(A, /obj/item/projectile)) unfreeze_projectile(A) - else if(istype(A, /obj/mecha)) + else if(istype(A, /obj/vehicle/sealed/mecha)) unfreeze_mecha(A) UnregisterSignal(A, COMSIG_MOVABLE_PRE_MOVE) @@ -131,10 +131,10 @@ global_frozen_atoms -= A -/datum/proximity_monitor/advanced/timestop/proc/freeze_mecha(obj/mecha/M) +/datum/proximity_monitor/advanced/timestop/proc/freeze_mecha(obj/vehicle/sealed/mecha/M) M.completely_disabled = TRUE -/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mecha(obj/mecha/M) +/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mecha(obj/vehicle/sealed/mecha/M) M.completely_disabled = FALSE diff --git a/code/modules/fields/turf_objects.dm b/code/modules/fields/turf_objects.dm index 1af924294a..f8d139a45d 100644 --- a/code/modules/fields/turf_objects.dm +++ b/code/modules/fields/turf_objects.dm @@ -23,7 +23,7 @@ name = "energy field" desc = "Get off my turf!" -/obj/effect/abstract/proximity_checker/advanced/field_turf/CanPass(atom/movable/AM, turf/target) +/obj/effect/abstract/proximity_checker/advanced/field_turf/CanAllowThrough(atom/movable/AM, turf/target) . = ..() if(parent) return parent.field_turf_canpass(AM, src, target) @@ -48,7 +48,7 @@ name = "energy field edge" desc = "Edgy description here." -/obj/effect/abstract/proximity_checker/advanced/field_edge/CanPass(atom/movable/AM, turf/target) +/obj/effect/abstract/proximity_checker/advanced/field_edge/CanAllowThrough(atom/movable/AM, turf/target) . = ..() if(parent) return parent.field_edge_canpass(AM, src, target) diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index adbf48470d..5920c33df1 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -647,10 +647,10 @@ GLOBAL_LIST_INIT(hallucination_list, list( target.playsound_local(get_turf(airlock), 'sound/machines/boltsup.ogg',30,0,3) qdel(src) -/obj/effect/hallucination/fake_door_lock/CanPass(atom/movable/mover, turf/_target) +/obj/effect/hallucination/fake_door_lock/CanAllowThrough(atom/movable/mover, turf/_target) + . = ..() if(mover == target && airlock.density) return FALSE - return TRUE /datum/hallucination/chat @@ -739,7 +739,7 @@ GLOBAL_LIST_INIT(hallucination_list, list( if(close_other) //increase the odds for(var/i in 1 to 5) message_pool.Add("You feel a tiny prick!") - var/obj/item/storage/equipped_backpack = other.get_item_by_slot(SLOT_BACK) + var/obj/item/storage/equipped_backpack = other.get_item_by_slot(ITEM_SLOT_BACK) if(istype(equipped_backpack)) for(var/i in 1 to 5) //increase the odds message_pool.Add("[other] puts the [pick(\ @@ -778,7 +778,7 @@ GLOBAL_LIST_INIT(hallucination_list, list( ..() var/turf/source = random_far_turf() if(!sound_type) - sound_type = pick("airlock","airlock pry","console","flash","explosion","far explosion","mech","glass","alarm","beepsky","mech","wall decon","door hack") + sound_type = pick("airlock","airlock pry","console","flash","explosion","far explosion","mech","glass","alarm","beepsky","mech","wall decon","door hack","seth") feedback_details += "Type: [sound_type]" //Strange audio switch(sound_type) @@ -827,6 +827,9 @@ GLOBAL_LIST_INIT(hallucination_list, list( target.playsound_local(source, 'sound/items/screwdriver.ogg', 50, 1) sleep(rand(40,80)) target.playsound_local(source, 'sound/machines/airlockforced.ogg', 30, 1) + //funny announcement man + if("seth") + target.playsound_local(source,'sound/misc/seth.ogg', 50, 1) qdel(src) /datum/hallucination/weird_sounds @@ -885,7 +888,7 @@ GLOBAL_LIST_INIT(hallucination_list, list( if("blob alert") to_chat(target, "

    Biohazard Alert

    ") to_chat(target, "

    Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.

    ") - SEND_SOUND(target, get_announcer_sound("outbreak5")) + SEND_SOUND(target, SSstation.announcer.event_sounds[ANNOUNCER_OUTBREAK5]) if("ratvar") target.playsound_local(target, 'sound/machines/clockcult/ark_deathrattle.ogg', 50, FALSE, pressure_affected = FALSE) target.playsound_local(target, 'sound/effects/clockcult_gateway_disrupted.ogg', 50, FALSE, pressure_affected = FALSE) @@ -894,15 +897,15 @@ GLOBAL_LIST_INIT(hallucination_list, list( if("shuttle dock") to_chat(target, "

    Priority Announcement

    ") to_chat(target, "

    The Emergency Shuttle has docked with the station. You have 3 minutes to board the Emergency Shuttle.

    ") - SEND_SOUND(target, get_announcer_sound("shuttledock")) + SEND_SOUND(target, SSstation.announcer.event_sounds[ANNOUNCER_SHUTTLEDOCK]) if("malf ai") //AI is doomsdaying! to_chat(target, "

    Anomaly Alert

    ") to_chat(target, "

    Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.

    ") - SEND_SOUND(target, get_announcer_sound("aimalf")) + SEND_SOUND(target, SSstation.announcer.event_sounds[ANNOUNCER_AIMALF]) if("meteors") //Meteors inbound! to_chat(target, "

    Meteor Alert

    ") to_chat(target, "

    [generateMeteorString(rand(60, 90),FALSE,pick(GLOB.cardinals))]

    ") - SEND_SOUND(target, get_announcer_sound("meteors")) + SEND_SOUND(target, SSstation.announcer.event_sounds[ANNOUNCER_METEORS]) if("supermatter") SEND_SOUND(target, 'sound/magic/charge.ogg') to_chat(target, "You feel reality distort for a moment...") @@ -1119,7 +1122,7 @@ GLOBAL_LIST_INIT(hallucination_list, list( /obj/effect/hallucination/danger/anomaly name = "flux wave anomaly" -/obj/effect/hallucination/danger/anomaly/Initialize() +/obj/effect/hallucination/danger/anomaly/Initialize(mapload) . = ..() START_PROCESSING(SSobj, src) diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 6b8de787f0..f4185ccf77 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -347,6 +347,9 @@ foodtype = GRAIN | ALCOHOL custom_price = PRICE_PRETTY_CHEAP +/obj/item/reagent_containers/food/drinks/beer/almost_empty + list_reagents = list(/datum/reagent/consumable/ethanol/beer = 1) + /obj/item/reagent_containers/food/drinks/beer/light name = "Carp Lite" desc = "Brewed with \"Pure Ice Asteroid Spring Water\"." @@ -500,7 +503,7 @@ /obj/item/reagent_containers/food/drinks/soda_cans/attack_self(mob/user) if(!is_drainable()) to_chat(user, "You pull back the tab of \the [src] with a satisfying pop.") //Ahhhhhhhh - ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) + reagents.reagents_holder_flags |= OPENCONTAINER playsound(src, "can_open", 50, 1) spillable = TRUE return @@ -532,7 +535,7 @@ list_reagents = list(/datum/reagent/consumable/lemon_lime = 30) foodtype = FRUIT -/obj/item/reagent_containers/food/drinks/soda_cans/lemon_lime/Initialize() +/obj/item/reagent_containers/food/drinks/soda_cans/lemon_lime/Initialize(mapload) . = ..() name = "lemon-lime soda" diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index f650a935ea..3fd2d85cd1 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -31,11 +31,11 @@ var/obj/item/bodypart/affecting = user.zone_selected //Find what the player is aiming at var/headarmor = 0 // Target's head armor - var/armor_block = min(90, target.run_armor_check(affecting, "melee", null, null,armour_penetration)) // For normal attack damage + var/armor_block = min(90, target.run_armor_check(affecting, MELEE, null, null,armour_penetration)) // For normal attack damage //If they have a hat/helmet and the user is targeting their head. if(affecting == BODY_ZONE_HEAD) - var/obj/item/I = target.get_item_by_slot(SLOT_HEAD) + var/obj/item/I = target.get_item_by_slot(ITEM_SLOT_HEAD) if(I) headarmor = I.armor.melee @@ -89,7 +89,7 @@ var/icon/broken_outline = icon('icons/obj/drinks.dmi', "broken") sharpness = SHARP_EDGED -/obj/item/broken_bottle/Initialize() +/obj/item/broken_bottle/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 200, 55) @@ -243,7 +243,7 @@ /obj/item/reagent_containers/food/drinks/bottle/absinthe/empty list_reagents = null -/obj/item/reagent_containers/food/drinks/bottle/absinthe/Initialize() +/obj/item/reagent_containers/food/drinks/bottle/absinthe/Initialize(mapload) . = ..() redact() @@ -332,7 +332,7 @@ /obj/item/reagent_containers/food/drinks/bottle/sake/empty list_reagents = null -/obj/item/reagent_containers/food/drinks/bottle/sake/Initialize() +/obj/item/reagent_containers/food/drinks/bottle/sake/Initialize(mapload) . = ..() if(prob(10)) name = "Fluffy Tail Sake" @@ -509,7 +509,7 @@ ..() add_overlay("[initial(icon_state)]shine") -/obj/item/reagent_containers/food/drinks/bottle/blank/Initialize() +/obj/item/reagent_containers/food/drinks/bottle/blank/Initialize(mapload) . = ..() update_icon() diff --git a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm index 9602c1d24e..4a4ee40f60 100644 --- a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm +++ b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm @@ -74,7 +74,7 @@ desc = "A shot glass - the universal symbol for bad decisions." return -/obj/item/reagent_containers/food/drinks/drinkingglass/filled/Initialize() +/obj/item/reagent_containers/food/drinks/drinkingglass/filled/Initialize(mapload) . = ..() on_reagent_change(ADD_REAGENT) diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm index 42f536c4f3..923d365f73 100644 --- a/code/modules/food_and_drinks/food/customizables.dm +++ b/code/modules/food_and_drinks/food/customizables.dm @@ -281,7 +281,7 @@ icon = 'icons/obj/food/soupsalad.dmi' icon_state = "wishsoup" -/obj/item/reagent_containers/food/snacks/customizable/soup/Initialize() +/obj/item/reagent_containers/food/snacks/customizable/soup/Initialize(mapload) . = ..() eatverb = pick("slurp","sip","suck","inhale","drink") diff --git a/code/modules/food_and_drinks/food/snacks_bread.dm b/code/modules/food_and_drinks/food/snacks_bread.dm index f30d955b00..b11d2b83b9 100644 --- a/code/modules/food_and_drinks/food/snacks_bread.dm +++ b/code/modules/food_and_drinks/food/snacks_bread.dm @@ -19,7 +19,7 @@ custom_food_type = /obj/item/reagent_containers/food/snacks/customizable/sandwich filling_color = "#FFA500" list_reagents = list(/datum/reagent/consumable/nutriment = 2) - slot_flags = ITEM_SLOT_HEAD + slot_flags = ITEM_SLOT_MASK customfoodfilling = 0 //to avoid infinite bread-ception foodtype = GRAIN dunkable = TRUE diff --git a/code/modules/food_and_drinks/food/snacks_burgers.dm b/code/modules/food_and_drinks/food/snacks_burgers.dm index f8c85700c9..344ff92717 100644 --- a/code/modules/food_and_drinks/food/snacks_burgers.dm +++ b/code/modules/food_and_drinks/food/snacks_burgers.dm @@ -13,7 +13,7 @@ bonus_reagents = list(/datum/reagent/consumable/nutriment/vitamin = 1) foodtype = GRAIN | MEAT -/obj/item/reagent_containers/food/snacks/burger/plain/Initialize() +/obj/item/reagent_containers/food/snacks/burger/plain/Initialize(mapload) . = ..() if(prob(1)) new/obj/effect/particle_effect/smoke(get_turf(src)) @@ -146,7 +146,7 @@ verb_say = "moans" verb_yell = "wails" -/obj/item/reagent_containers/food/snacks/burger/ghost/Initialize() +/obj/item/reagent_containers/food/snacks/burger/ghost/Initialize(mapload) . = ..() START_PROCESSING(SSobj, src) @@ -379,7 +379,7 @@ bonus_reagents = list(/datum/reagent/consumable/nutriment = 1) foodtype = GRAIN | MEAT | DAIRY -/obj/item/reagent_containers/food/snacks/burger/cheese/Initialize() +/obj/item/reagent_containers/food/snacks/burger/cheese/Initialize(mapload) . = ..() if(prob(33)) icon_state = "cheeseburgeralt" diff --git a/code/modules/food_and_drinks/food/snacks_egg.dm b/code/modules/food_and_drinks/food/snacks_egg.dm index 2143c6b8f2..489380777c 100644 --- a/code/modules/food_and_drinks/food/snacks_egg.dm +++ b/code/modules/food_and_drinks/food/snacks_egg.dm @@ -24,7 +24,7 @@ /obj/item/reagent_containers/food/snacks/egg/gland desc = "An egg! It looks weird..." -/obj/item/reagent_containers/food/snacks/egg/gland/Initialize() +/obj/item/reagent_containers/food/snacks/egg/gland/Initialize(mapload) . = ..() reagents.add_reagent(get_random_reagent_id(), 15) diff --git a/code/modules/food_and_drinks/food/snacks_meat.dm b/code/modules/food_and_drinks/food/snacks_meat.dm index 402192e034..5bcb106822 100644 --- a/code/modules/food_and_drinks/food/snacks_meat.dm +++ b/code/modules/food_and_drinks/food/snacks_meat.dm @@ -26,7 +26,7 @@ tastes = list("fish" = 1) foodtype = MEAT -/obj/item/reagent_containers/food/snacks/carpmeat/Initialize() +/obj/item/reagent_containers/food/snacks/carpmeat/Initialize(mapload) . = ..() eatverb = pick("bite","chew","choke down","gnaw","swallow","chomp") @@ -63,7 +63,7 @@ filling_color = "#ee7676" tastes = list("fish" = 1, "pan seared vegtables" = 1) foodtype = MEAT | VEGETABLES | FRIED - + /obj/item/reagent_containers/food/snacks/sushi_basic name = "funa hosomaki" desc = "A small cylindrical kudzu skin, filled with rice and fish." @@ -172,7 +172,7 @@ foodtype = MEAT | BREAKFAST var/roasted = FALSE -/obj/item/reagent_containers/food/snacks/sausage/Initialize() +/obj/item/reagent_containers/food/snacks/sausage/Initialize(mapload) . = ..() eatverb = pick("bite","chew","nibble","deep throat","gobble","chomp") @@ -283,7 +283,7 @@ tastes = list("soy" = 1, "vegetables" = 1) foodtype = VEGETABLES -/obj/item/reagent_containers/food/snacks/stewedsoymeat/Initialize() +/obj/item/reagent_containers/food/snacks/stewedsoymeat/Initialize(mapload) . = ..() eatverb = pick("slurp","sip","suck","inhale","drink") @@ -328,7 +328,7 @@ tastes = list("\"chicken\"" = 1) foodtype = MEAT -/obj/item/reagent_containers/food/snacks/nugget/Initialize() +/obj/item/reagent_containers/food/snacks/nugget/Initialize(mapload) . = ..() var/shape = pick("lump", "star", "lizard", "corgi") desc = "A 'chicken' nugget vaguely shaped like a [shape]." @@ -391,7 +391,7 @@ bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 1) tastes = list("meat" = 3, "smokey sauce" = 1) foodtype = MEAT - + /obj/item/reagent_containers/food/snacks/goliathcalamari name = "goliath calamari" desc = "ACKCHYUALLY, this isn't calamari, guys!" diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index b771a90907..c26da941b2 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -79,7 +79,7 @@ tastes = list("popcorn" = 3, "butter" = 1) foodtype = JUNKFOOD -/obj/item/reagent_containers/food/snacks/popcorn/Initialize() +/obj/item/reagent_containers/food/snacks/popcorn/Initialize(mapload) . = ..() eatverb = pick("bite","crunch","nibble","gnaw","gobble","chomp") @@ -453,7 +453,7 @@ tastes = list("candy" = 1) foodtype = JUNKFOOD | SUGAR | ANTITOXIC -/obj/item/reagent_containers/food/snacks/lollipop/Initialize() +/obj/item/reagent_containers/food/snacks/lollipop/Initialize(mapload) . = ..() head = mutable_appearance('icons/obj/lollipop.dmi', "lollipop_head") change_head_color(rgb(rand(0, 255), rand(0, 255), rand(0, 255))) @@ -472,7 +472,7 @@ /obj/item/reagent_containers/food/snacks/lollipop/cyborg var/spamchecking = TRUE -/obj/item/reagent_containers/food/snacks/lollipop/cyborg/Initialize() +/obj/item/reagent_containers/food/snacks/lollipop/cyborg/Initialize(mapload) . = ..() addtimer(CALLBACK(src, .proc/spamcheck), 1200) @@ -493,14 +493,14 @@ tastes = list("candy") foodtype = JUNKFOOD -/obj/item/reagent_containers/food/snacks/gumball/Initialize() +/obj/item/reagent_containers/food/snacks/gumball/Initialize(mapload) . = ..() color = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) /obj/item/reagent_containers/food/snacks/gumball/cyborg var/spamchecking = TRUE -/obj/item/reagent_containers/food/snacks/gumball/cyborg/Initialize() +/obj/item/reagent_containers/food/snacks/gumball/cyborg/Initialize(mapload) . = ..() addtimer(CALLBACK(src, .proc/spamcheck), 1200) diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm index 8c5631336e..831c5c6d16 100644 --- a/code/modules/food_and_drinks/food/snacks_pastry.dm +++ b/code/modules/food_and_drinks/food/snacks_pastry.dm @@ -19,7 +19,7 @@ var/extra_reagent = null var/decorated_adjective = "sprinkled" -/obj/item/reagent_containers/food/snacks/donut/Initialize() +/obj/item/reagent_containers/food/snacks/donut/Initialize(mapload) . = ..() if(prob(30)) decorate_donut() @@ -60,7 +60,7 @@ bitesize = 10 tastes = list("donut" = 3, "chaos" = 1) -/obj/item/reagent_containers/food/snacks/donut/chaos/Initialize() +/obj/item/reagent_containers/food/snacks/donut/chaos/Initialize(mapload) . = ..() extra_reagent = pick(/datum/reagent/consumable/nutriment, /datum/reagent/consumable/capsaicin, /datum/reagent/consumable/frostoil, /datum/reagent/drug/krokodil, /datum/reagent/toxin/plasma, /datum/reagent/consumable/coco, @@ -173,7 +173,7 @@ /obj/item/reagent_containers/food/snacks/donut/jelly/in_box_sprite() return "[replacetext(icon_state, "jelly", "donut")]_inbox" -/obj/item/reagent_containers/food/snacks/donut/jelly/Initialize() +/obj/item/reagent_containers/food/snacks/donut/jelly/Initialize(mapload) . = ..() if(extra_reagent) reagents.add_reagent(extra_reagent, 3) @@ -569,7 +569,7 @@ tastes = list("mushroom" = 1, "biscuit" = 1) foodtype = GRAIN | VEGETABLES -/obj/item/reagent_containers/food/snacks/plumphelmetbiscuit/Initialize() +/obj/item/reagent_containers/food/snacks/plumphelmetbiscuit/Initialize(mapload) var/fey = prob(10) if(fey) name = "exceptional plump helmet biscuit" @@ -736,7 +736,7 @@ list_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/vitamin = 3) tastes = list("pancakes" = 1, "chocolate" = 1) -/obj/item/reagent_containers/food/snacks/pancakes/Initialize() +/obj/item/reagent_containers/food/snacks/pancakes/Initialize(mapload) . = ..() update_icon() diff --git a/code/modules/food_and_drinks/food/snacks_pie.dm b/code/modules/food_and_drinks/food/snacks_pie.dm index 5329829637..c98c170df3 100644 --- a/code/modules/food_and_drinks/food/snacks_pie.dm +++ b/code/modules/food_and_drinks/food/snacks_pie.dm @@ -164,7 +164,7 @@ foodtype = GRAIN | VEGETABLES -/obj/item/reagent_containers/food/snacks/pie/plump_pie/Initialize() +/obj/item/reagent_containers/food/snacks/pie/plump_pie/Initialize(mapload) . = ..() var/fey = prob(10) if(fey) diff --git a/code/modules/food_and_drinks/food/snacks_pizza.dm b/code/modules/food_and_drinks/food/snacks_pizza.dm index 75cf8ffb82..fc6cd1472f 100644 --- a/code/modules/food_and_drinks/food/snacks_pizza.dm +++ b/code/modules/food_and_drinks/food/snacks_pizza.dm @@ -35,7 +35,7 @@ tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1) foodtype = GRAIN | VEGETABLES -/obj/item/reagent_containers/food/snacks/pizza/margherita/robo/Initialize() +/obj/item/reagent_containers/food/snacks/pizza/margherita/robo/Initialize(mapload) bonus_reagents += list("nanomachines" = 70) return ..() @@ -187,7 +187,7 @@ slice_path = /obj/item/reagent_containers/food/snacks/pizzaslice/arnold bonus_reagents = list(/datum/reagent/consumable/nutriment = 30, /datum/reagent/consumable/nutriment/vitamin = 6, /datum/reagent/iron = 10, /datum/reagent/medicine/omnizine = 30) tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "pepperoni" = 2, "9 millimeter bullets" = 2) - + /obj/item/reagent_containers/food/snacks/proc/try_break_off(mob/living/M, mob/living/user) //maybe i give you a pizza maybe i break off your arm var/obj/item/bodypart/l_arm = user.get_bodypart(BODY_ZONE_L_ARM) diff --git a/code/modules/food_and_drinks/food/snacks_salad.dm b/code/modules/food_and_drinks/food/snacks_salad.dm index 8c6eecb829..3582015ee9 100644 --- a/code/modules/food_and_drinks/food/snacks_salad.dm +++ b/code/modules/food_and_drinks/food/snacks_salad.dm @@ -9,7 +9,7 @@ tastes = list("leaves" = 1) foodtype = VEGETABLES -/obj/item/reagent_containers/food/snacks/salad/Initialize() +/obj/item/reagent_containers/food/snacks/salad/Initialize(mapload) . = ..() eatverb = pick("crunch","devour","nibble","gnaw","gobble","chomp") //who the fuck gnaws and devours on a salad diff --git a/code/modules/food_and_drinks/food/snacks_soup.dm b/code/modules/food_and_drinks/food/snacks_soup.dm index 38a68ad364..2e45a13ea0 100644 --- a/code/modules/food_and_drinks/food/snacks_soup.dm +++ b/code/modules/food_and_drinks/food/snacks_soup.dm @@ -8,7 +8,7 @@ tastes = list("tasteless soup" = 1) foodtype = VEGETABLES -/obj/item/reagent_containers/food/snacks/soup/Initialize() +/obj/item/reagent_containers/food/snacks/soup/Initialize(mapload) . = ..() eatverb = pick("slurp","sip","suck","inhale","drink") @@ -19,7 +19,7 @@ list_reagents = list(/datum/reagent/water = 10) tastes = list("wishes" = 1) -/obj/item/reagent_containers/food/snacks/soup/wish/Initialize() +/obj/item/reagent_containers/food/snacks/soup/wish/Initialize(mapload) . = ..() var/wish_true = prob(25) if(wish_true) @@ -99,7 +99,7 @@ list_reagents = list(/datum/reagent/consumable/nutriment = 6) tastes = list("chaos" = 1) -/obj/item/reagent_containers/food/snacks/soup/mystery/Initialize() +/obj/item/reagent_containers/food/snacks/soup/mystery/Initialize(mapload) . = ..() extra_reagent = pick(/datum/reagent/consumable/capsaicin, /datum/reagent/consumable/frostoil, /datum/reagent/medicine/omnizine, /datum/reagent/consumable/banana, /datum/reagent/blood, @@ -184,7 +184,7 @@ bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 5) foodtype = VEGETABLES -/obj/item/reagent_containers/food/snacks/soup/beet/Initialize() +/obj/item/reagent_containers/food/snacks/soup/beet/Initialize(mapload) . = ..() name = pick("borsch","bortsch","borstch","borsh","borshch","borscht") tastes = list(name = 1) diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index ebde504ec0..0bf4179814 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -49,7 +49,7 @@ God bless America. /obj/item/his_grace)) var/datum/looping_sound/deep_fryer/fry_loop -/obj/machinery/deepfryer/Initialize() +/obj/machinery/deepfryer/Initialize(mapload) . = ..() create_reagents(50, OPENCONTAINER) reagents.add_reagent(/datum/reagent/consumable/cooking_oil, 25) @@ -57,7 +57,11 @@ God bless America. component_parts += new /obj/item/circuitboard/machine/deep_fryer(null) component_parts += new /obj/item/stock_parts/micro_laser(null) RefreshParts() - fry_loop = new(list(src), FALSE) + fry_loop = new(src, FALSE) + +/obj/machinery/deepfryer/Destroy() + QDEL_NULL(fry_loop) + return ..() /obj/machinery/deepfryer/RefreshParts() var/oil_efficiency diff --git a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm index f09d3d6728..8bf13363a9 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm @@ -17,7 +17,7 @@ var/list/stored_food = list() var/obj/item/reagent_containers/mixer -/obj/machinery/food_cart/Initialize() +/obj/machinery/food_cart/Initialize(mapload) . = ..() create_reagents(LIQUID_CAPACITY, OPENCONTAINER | NO_REACT) mixer = new /obj/item/reagent_containers(src, MIXER_CAPACITY) diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index e4148d849a..fc00fd176e 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -17,7 +17,7 @@ var/meat_quality = 35 //food_quality of meat produced -/obj/machinery/gibber/Initialize() +/obj/machinery/gibber/Initialize(mapload) . = ..() add_overlay("grjam") diff --git a/code/modules/food_and_drinks/kitchen_machinery/grill.dm b/code/modules/food_and_drinks/kitchen_machinery/grill.dm index 09e1d7b1c6..c03c834407 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/grill.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/grill.dm @@ -11,17 +11,23 @@ var/grill_time = 0 var/datum/looping_sound/grill/grill_loop -/obj/machinery/grill/Initialize() +/obj/machinery/grill/Initialize(mapload) . = ..() - grill_loop = new(list(src), FALSE) + grill_loop = new(src, FALSE) + +/obj/machinery/grill/Destroy() + QDEL_NULL(grill_loop) + return ..() /obj/machinery/grill/update_icon_state() if(grilled_item) icon_state = "grill" - else if(grill_fuel) + return ..() + if(grill_fuel > 0) icon_state = "grill_on" - else - icon_state = "grill_open" + return ..() + icon_state = "grill_open" + return ..() /obj/machinery/grill/attackby(obj/item/I, mob/user) if(istype(I, /obj/item/stack/sheet/mineral/coal) || istype(I, /obj/item/stack/sheet/mineral/wood)) @@ -60,21 +66,21 @@ return ..() -/obj/machinery/grill/process() +/obj/machinery/grill/process(delta_time) ..() - update_icon() - if(!grill_fuel) + update_appearance() + if(grill_fuel <= 0) return else - grill_fuel -= 1 - if(prob(1)) + grill_fuel -= 0.5 * delta_time + if(DT_PROB(0.5, delta_time)) var/datum/effect_system/smoke_spread/bad/smoke = new smoke.set_up(1, loc) smoke.start() if(grilled_item) - grill_time += 1 + grill_time += delta_time grilled_item.reagents.add_reagent("char", 1) - grill_fuel -= 10 + grill_fuel -= 5 * delta_time grilled_item.AddComponent(/datum/component/sizzle) /obj/machinery/grill/Exited(atom/movable/AM) @@ -109,9 +115,9 @@ /obj/machinery/grill/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(grilled_item) - to_chat(user, "You take out [grilled_item] from [src].") + to_chat(user, span_notice("You take out [grilled_item] from [src].")) grilled_item.forceMove(drop_location()) - update_icon() + update_appearance() return return ..() diff --git a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm index 4fc55ba4c3..9f36fc058f 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm @@ -8,8 +8,6 @@ #define CONE_WAFFLE 8 #define CONE_CHOC 9 - - /obj/machinery/icecream_vat name = "ice cream vat" desc = "Ding-aling ding dong. Get your Nanotrasen-approved ice cream!" @@ -35,6 +33,8 @@ /datum/reagent/consumable/ethanol/singulo = 6, /datum/reagent/consumable/peachjuice = 6, /datum/reagent/consumable/grapejuice = 6) + var/custom_taste + var/custom_color /obj/machinery/icecream_vat/proc/get_ingredient_list(type) switch(type) @@ -80,7 +80,7 @@ return "vanilla" -/obj/machinery/icecream_vat/Initialize() +/obj/machinery/icecream_vat/Initialize(mapload) . = ..() while(product_types.len < 9) product_types.Add(5) @@ -99,7 +99,10 @@ dat += "Peach ice cream: Select Make x5 [product_types[ICECREAM_PEACH]] dollops left. (Ingredients: milk, ice, peach juice)
    " dat += "Grape ice cream: Select Make x5 [product_types[ICECREAM_GRAPE]] dollops left. (Ingredients: milk, ice, grape juice)
    " dat += "Blue ice cream: Select Make x5 [product_types[ICECREAM_BLUE]] dollops left. (Ingredients: milk, ice, singulo)
    " - dat += "Custom ice cream: Select Make x5 [product_types[ICECREAM_CUSTOM]] dollops left. (Ingredients: milk, ice, optional flavoring)

  • " + dat += "Custom ice cream: Select Make x5 [product_types[ICECREAM_CUSTOM]] dollops left. (Ingredients: milk, ice, optional flavoring)
    " + dat += "Change custom taste: [custom_taste ? custom_taste : "Default"]" + dat += "
    Change custom color: [custom_color ? custom_color : "Default"]" + dat += "
    Reset custom ice cream taste and color to defaults" dat += "
    CONES
    " dat += "Waffle cones: Dispense Make x5 [product_types[CONE_WAFFLE]] cones left. (Ingredients: flour, sugar)
    " dat += "Chocolate cones: Dispense Make x5 [product_types[CONE_CHOC]] cones left. (Ingredients: flour, sugar, coco powder)
    " @@ -128,7 +131,7 @@ visible_message("[icon2html(src, viewers(src))] [user] scoops delicious [flavour_name] ice cream into [I].") product_types[dispense_flavour] -= 1 if(beaker && beaker.reagents.total_volume) - I.add_ice_cream(flavour_name, beaker.reagents) + I.add_ice_cream(flavour_name, beaker.reagents, custom_color, custom_taste) else I.add_ice_cream(flavour_name) if(I.reagents.total_volume < 10) @@ -213,14 +216,25 @@ if(href_list["refill"]) RefillFromBeaker() - updateDialog() - if(href_list["refresh"]) updateDialog() if(href_list["close"]) usr.unset_machine() usr << browse(null,"window=icecreamvat") + + if(href_list["custom_taste"]) + custom_taste = stripped_input(usr, "Set a custom taste for the custom icecream. 50 characters max, leave blank to go back to the default option.", max_length = 50) + + if(href_list["custom_color"]) + custom_color = input(usr, "Choose a color for the custom icecream. Cancel to go back to the default option.") as color|null + + if(href_list["reset_custom"]) + custom_taste = null + custom_color = null + + updateDialog() // i have no clue why we even have refresh when this is a thing but sure + return /obj/item/reagent_containers/food/snacks/icecream @@ -235,7 +249,7 @@ bitesize = 4 foodtype = DAIRY | SUGAR -/obj/item/reagent_containers/food/snacks/icecream/Initialize() +/obj/item/reagent_containers/food/snacks/icecream/Initialize(mapload) . = ..() reagents.maximum_volume = 20 @@ -251,7 +265,7 @@ desc = "Delicious [cone_name] cone, but no ice cream." -/obj/item/reagent_containers/food/snacks/icecream/proc/add_ice_cream(flavour_name, datum/reagents/R) +/obj/item/reagent_containers/food/snacks/icecream/proc/add_ice_cream(flavour_name, datum/reagents/R, custom_color, custom_taste) name = "[flavour_name] icecream" switch (flavour_name) // adding the actual reagents advertised in the ingredient list if ("vanilla") @@ -286,8 +300,11 @@ if(R && R.total_volume >= 4) //consumable reagents have stronger taste so higher volume will allow non-food flavourings to break through better. var/mutable_appearance/flavoring = mutable_appearance(icon,"icecream_custom") var/datum/reagent/master = R.get_master_reagent() - flavoring.color = master.color - filling_color = master.color + flavoring.color = custom_color ? custom_color : master.color + filling_color = custom_color ? custom_color : master.color + if(custom_taste) + tastes = list("[custom_taste]" = 1) + reagents.force_alt_taste = TRUE name = "[master.name] icecream" desc = "A delicious [cone_type] cone filled with artisanal icecream. Made with real [master.name]. Ain't that something." R.trans_to(src, 4) diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm index 5954788d5c..41cd860362 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm @@ -32,16 +32,17 @@ var/static/list/radial_options = list("eject" = radial_eject, "use" = radial_use) var/static/list/ai_radial_options = list("eject" = radial_eject, "use" = radial_use, "examine" = radial_examine) -/obj/machinery/microwave/Initialize() +/obj/machinery/microwave/Initialize(mapload) . = ..() wires = new /datum/wires/microwave(src) create_reagents(100) - soundloop = new(list(src), FALSE) + soundloop = new(src, FALSE) /obj/machinery/microwave/Destroy() eject() if(wires) QDEL_NULL(wires) + QDEL_NULL(soundloop) . = ..() /obj/machinery/microwave/RefreshParts() diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index 58769cebf1..08020f708d 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -19,7 +19,7 @@ var/list/initial_contents var/visible_contents = TRUE -/obj/machinery/smartfridge/Initialize() +/obj/machinery/smartfridge/Initialize(mapload) . = ..() create_reagents(100, NO_REACT) @@ -258,7 +258,7 @@ base_build_path = /obj/machinery/smartfridge/drying_rack //should really be seeing this without admin fuckery. var/drying = FALSE -/obj/machinery/smartfridge/drying_rack/Initialize() +/obj/machinery/smartfridge/drying_rack/Initialize(mapload) . = ..() // Cache the old_parts first, we'll delete it after we've changed component_parts to a new list. @@ -445,6 +445,10 @@ if(isorgan(O)) var/obj/item/organ/organ = O organ.organ_flags |= ORGAN_FROZEN + if(isbodypart(O)) + var/obj/item/bodypart/bodypart = O + for(var/obj/item/organ/stored in bodypart.contents) + stored.organ_flags |= ORGAN_FROZEN /obj/machinery/smartfridge/organ/RefreshParts() for(var/obj/item/stock_parts/matter_bin/B in component_parts) @@ -463,6 +467,10 @@ if(isorgan(AM)) var/obj/item/organ/O = AM O.organ_flags &= ~ORGAN_FROZEN + if(isbodypart(AM)) + var/obj/item/bodypart/bodypart = AM + for(var/obj/item/organ/stored in bodypart.contents) + stored.organ_flags &= ~ORGAN_FROZEN //cit specific?????? /obj/machinery/smartfridge/organ/preloaded @@ -471,7 +479,7 @@ /obj/item/reagent_containers/medspray/synthtissue = 1, /obj/item/reagent_containers/medspray/sterilizine = 1) -/obj/machinery/smartfridge/organ/preloaded/Initialize() +/obj/machinery/smartfridge/organ/preloaded/Initialize(mapload) . = ..() var/list = list(/obj/item/organ/tongue, /obj/item/organ/brain, /obj/item/organ/heart, /obj/item/organ/liver, /obj/item/organ/ears, /obj/item/organ/eyes, /obj/item/organ/tail, /obj/item/organ/stomach) var/newtype = pick(list) diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm index a2603d07ab..9d0e38cdec 100644 --- a/code/modules/food_and_drinks/pizzabox.dm +++ b/code/modules/food_and_drinks/pizzabox.dm @@ -29,7 +29,7 @@ var/const/BOMB_TIMER_MIN = 1 var/const/BOMB_TIMER_MAX = 10 -/obj/item/pizzabox/Initialize() +/obj/item/pizzabox/Initialize(mapload) . = ..() update_icon() @@ -259,14 +259,14 @@ wires = null update_icon() -/obj/item/pizzabox/bomb/Initialize() +/obj/item/pizzabox/bomb/Initialize(mapload) . = ..() var/randompizza = pick(subtypesof(/obj/item/reagent_containers/food/snacks/pizza)) pizza = new randompizza(src) bomb = new(src) wires = new /datum/wires/explosive/pizza(src) -/obj/item/pizzabox/margherita/Initialize() +/obj/item/pizzabox/margherita/Initialize(mapload) . = ..() AddPizza() boxtag = "Margherita Deluxe" @@ -277,22 +277,22 @@ /obj/item/pizzabox/margherita/robo/AddPizza() pizza = new /obj/item/reagent_containers/food/snacks/pizza/margherita/robo(src) -/obj/item/pizzabox/vegetable/Initialize() +/obj/item/pizzabox/vegetable/Initialize(mapload) . = ..() pizza = new /obj/item/reagent_containers/food/snacks/pizza/vegetable(src) boxtag = "Gourmet Vegatable" -/obj/item/pizzabox/mushroom/Initialize() +/obj/item/pizzabox/mushroom/Initialize(mapload) . = ..() pizza = new /obj/item/reagent_containers/food/snacks/pizza/mushroom(src) boxtag = "Mushroom Special" -/obj/item/pizzabox/meat/Initialize() +/obj/item/pizzabox/meat/Initialize(mapload) . = ..() pizza = new /obj/item/reagent_containers/food/snacks/pizza/meat(src) boxtag = "Meatlover's Supreme" -/obj/item/pizzabox/pineapple/Initialize() +/obj/item/pizzabox/pineapple/Initialize(mapload) . = ..() pizza = new /obj/item/reagent_containers/food/snacks/pizza/pineapple(src) boxtag = "Honolulu Chew" @@ -311,8 +311,9 @@ /obj/item/reagent_containers/food/snacks/pizza/donkpocket = 0.3, /obj/item/reagent_containers/food/snacks/pizza/dank = 0.1) //pizzas here are weighted by chance to be someone's favorite var/static/list/pizza_preferences + COOLDOWN_DECLARE(next_pizza_attunement) -/obj/item/pizzabox/infinite/Initialize() +/obj/item/pizzabox/infinite/Initialize(mapload) . = ..() if(!pizza_preferences) pizza_preferences = list() @@ -323,11 +324,18 @@ . += "This pizza box is anomalous, and will produce infinite pizza." /obj/item/pizzabox/infinite/attack_self(mob/living/user) - QDEL_NULL(pizza) - if(ishuman(user)) - attune_pizza(user) + if(COOLDOWN_FINISHED(src, next_pizza_attunement)) + QDEL_NULL(pizza) + if(ishuman(user)) + attune_pizza(user) . = ..() +/obj/item/pizzabox/infinite/on_attack_hand(mob/user, act_intent, unarmed_attack_flags) + var/had_pizza = (pizza ? TRUE : FALSE) + . = ..() + if(had_pizza && !pizza) + COOLDOWN_START(src, next_pizza_attunement, (3 SECONDS)) + /obj/item/pizzabox/infinite/proc/attune_pizza(mob/living/carbon/human/noms) //tonight on "proc names I never thought I'd type" if(!pizza_preferences[noms.ckey]) pizza_preferences[noms.ckey] = pickweight(pizza_types) diff --git a/code/modules/food_and_drinks/recipes/drinks_recipes.dm b/code/modules/food_and_drinks/recipes/drinks_recipes.dm index 363e263ad4..217a650b30 100644 --- a/code/modules/food_and_drinks/recipes/drinks_recipes.dm +++ b/code/modules/food_and_drinks/recipes/drinks_recipes.dm @@ -771,8 +771,8 @@ /datum/chemical_reaction/pinkmilk name = "Strawberry Milk" - id = /datum/reagent/consumable/pinkmilk - results = list(/datum/reagent/consumable/pinkmilk = 2) + id = /datum/reagent/consumable/milk/pinkmilk + results = list(/datum/reagent/consumable/milk/pinkmilk = 2) required_reagents = list(/datum/reagent/consumable/strawberryjuice = 1, /datum/reagent/consumable/milk = 1) mix_message = "You feel a sweet aroma drift up your nose as the lactic mixture swirls. It reminds you of... a cafeteria." @@ -1016,8 +1016,8 @@ /datum/chemical_reaction/pinktea name = "Strawberry Tea" - id = /datum/reagent/consumable/pinktea - results = list(/datum/reagent/consumable/pinktea = 5) + id = /datum/reagent/consumable/tea/pinktea + results = list(/datum/reagent/consumable/tea/pinktea = 5) required_reagents = list(/datum/reagent/consumable/strawberryjuice = 1, /datum/reagent/consumable/tea/arnold_palmer = 1, /datum/reagent/consumable/sugar = 1) /datum/chemical_reaction/catnip_tea diff --git a/code/modules/holiday/dynamic.dm b/code/modules/holiday/dynamic.dm new file mode 100644 index 0000000000..69208d91ea --- /dev/null +++ b/code/modules/holiday/dynamic.dm @@ -0,0 +1,9 @@ +/datum/holiday/dynamic + name = "Dynamic Day" + +/datum/holiday/dynamic/shouldCelebrate(dd, mm, yy, ww, ddd) + var/list/days = CONFIG_GET(keyed_list/dynamic_mode_days) + return lowertext(ddd) in days + +/datum/holiday/dynamic/celebrate() + GLOB.dynamic_forced_threat_level = rand(50, 100) diff --git a/code/modules/holiday/easter.dm b/code/modules/holiday/easter.dm index 84287daa4f..9c538f4bde 100644 --- a/code/modules/holiday/easter.dm +++ b/code/modules/holiday/easter.dm @@ -5,6 +5,8 @@ weight = -1 max_occurrences = 1 earliest_start = 0 MINUTES + category = EVENT_CATEGORY_HOLIDAY + description = "Hides surprise filled easter eggs in maintenance." /datum/round_event/easter/announce(fake) priority_announce(pick("Hip-hop into Easter!","Find some Bunny's stash!","Today is National 'Hunt a Wabbit' Day.","Be kind, give Chocolate Eggs!")) @@ -16,6 +18,8 @@ typepath = /datum/round_event/rabbitrelease weight = 5 max_occurrences = 10 + category = EVENT_CATEGORY_HOLIDAY + description = "Summons a wave of cute rabbits." /datum/round_event/rabbitrelease/announce(fake) priority_announce("Unidentified furry objects detected coming aboard [station_name()]. Beware of Adorable-ness.", "Fluffy Alert", "aliens") @@ -66,7 +70,7 @@ icon = 'icons/mob/easter.dmi' icon_state = "basket" -/obj/item/storage/bag/easterbasket/Initialize() +/obj/item/storage/bag/easterbasket/Initialize(mapload) . = ..() var/datum/component/storage/STR = GetComponent(/datum/component/storage) STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/egg, /obj/item/reagent_containers/food/snacks/chocolateegg, /obj/item/reagent_containers/food/snacks/boiledegg)) @@ -109,7 +113,7 @@ /obj/item/reagent_containers/food/snacks/egg/loaded containsPrize = TRUE -/obj/item/reagent_containers/food/snacks/egg/loaded/Initialize() +/obj/item/reagent_containers/food/snacks/egg/loaded/Initialize(mapload) . = ..() var/eggcolor = pick("blue","green","mime","orange","purple","rainbow","red","yellow") icon_state = "egg-[eggcolor]" diff --git a/code/modules/holiday/halloween/bartholomew.dm b/code/modules/holiday/halloween/bartholomew.dm index 31cfb1f26a..62cd9d173d 100644 --- a/code/modules/holiday/halloween/bartholomew.dm +++ b/code/modules/holiday/halloween/bartholomew.dm @@ -8,15 +8,14 @@ anchored = TRUE var/items_list = list() speech_span = "spooky" + resistance_flags = INDESTRUCTIBLE var/active = TRUE - -/obj/item/barthpot/Destroy() - var/obj/item/barthpot/n = new src(loc) - n.items_list = items_list - ..() - + var/BallTutorial = FALSE /obj/item/barthpot/attackby(obj/item/I, mob/user, params) + if(BallTutorial) + say("Hello and welcome to the annual Citadel Station Spooky Ball [time2text(world.realtime, "YYYY")]! CENTCOM requisitioned this old hospital as a new colony site [text2num(time2text(world.realtime,"YYYY")) - 2019] years ago, and we’re back again after a few additions here and there. Next to me you can find all the tools you’ll need to build a nice private house, if you’re here for that kind of thing. The axes will chop trees, and give you wood. Shovels will remove grass and things, which you can use the grass to make beds and backets. The pickaxe will allow you pick out the nearby rocks, if you’re more interested in building a cave dwelling. Finally the umbrella and light sources are because it’s spooky, and it might rain! As for interesting spots; There’s the old abandoned mansion which you can get to by going through the entrance and towards the east. There’s also a mech arena directly south, and a racetrack in the caves to the right of the arena, follow the lanterns. And make sure to explore the caves too! Lots of neat things to find!") + return if(!active) say("Meow!") return @@ -25,20 +24,23 @@ if(istype(I, I2)) qdel(I) new /obj/item/reagent_containers/food/snacks/special_candy(loc) - to_chat(user, "You add the [I.name] to the pot and watch as it melts into the mixture, a candy crystalising in it's wake.") + to_chat(user, "You add the [I.name] to the pot and watch as it melts into the mixture, a candy crystallizing in it's wake.") say("Hooray! Thank you!") items_list -= I2 return say("It doesn't seem like that's magical enough!") /obj/item/barthpot/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) + if(BallTutorial) + say("Hello and welcome to the annual Citadel Station Spooky Ball [time2text(world.realtime, "YYYY")]! CENTCOM requisitioned this old hospital as a new colony site [text2num(time2text(world.realtime,"YYYY")) - 2019] years ago, and we’re back again after a few additions here and there. Next to me you can find all the tools you’ll need to build a nice private house, if you’re here for that kind of thing. The axes will chop trees, and give you wood. Shovels will remove grass and things, which you can use the grass to make beds and backets. The pickaxe will allow you pick out the nearby rocks, if you’re more interested in building a cave dwelling. Finally the umbrella and light sources are because it’s spooky, and it might rain! As for interesting spots; There’s the old abandoned mansion which you can get to by going through the entrance and towards the east. There’s also a mech arena directly south, and a racetrack in the caves to the right of the arena, follow the lanterns. And make sure to explore the caves too! Lots of neat things to find!") + return if(!active) say("Meow!") return say("Hello there, I'm Bartholomew, Jacqueline's Familiar.") sleep(20) - say("I'm currently seeking items to put into my pot, if we get the right items, it should crystalise into a magic candy!") + say("I'm currently seeking items to put into my pot, if we get the right items, it should crystalize into a magic candy!") if(!iscarbon(user)) say("Though... I'm not sure you can help me.") diff --git a/code/modules/holiday/halloween/halloween.dm b/code/modules/holiday/halloween/halloween.dm index f468022918..59a7fcce0c 100644 --- a/code/modules/holiday/halloween/halloween.dm +++ b/code/modules/holiday/halloween/halloween.dm @@ -42,7 +42,7 @@ var/trapped = 0 var/mob/trapped_mob -/obj/structure/closet/Initialize() +/obj/structure/closet/Initialize(mapload) ..() if(prob(30)) set_spooky_trap() @@ -137,7 +137,7 @@ layer = 4 var/timer = 0 -/mob/living/simple_animal/hostile/construct/shade/howling_ghost/Initialize() +/mob/living/simple_animal/hostile/construct/shade/howling_ghost/Initialize(mapload) . = ..() icon_state = pick("ghost","ghostian","ghostian2","ghostking","ghost1","ghost2") icon_living = icon_state @@ -175,9 +175,6 @@ step(I,direction) return -/mob/living/simple_animal/hostile/construct/shade/howling_ghost/CanPass(atom/movable/mover, turf/target) - return 1 - /////////////////////////// //Spookoween Insane Clown// /////////////////////////// @@ -196,7 +193,7 @@ unsuitable_atmos_damage = 0 var/timer -/mob/living/simple_animal/hostile/retaliate/clown/insane/Initialize() +/mob/living/simple_animal/hostile/retaliate/clown/insane/Initialize(mapload) . = ..() timer = rand(5,15) @@ -233,7 +230,7 @@ return /mob/living/simple_animal/hostile/retaliate/clown/insane/adjustHealth() - . = ..() + . = ..() if(prob(5)) playsound(loc, 'sound/spookoween/insane_low_laugh.ogg', 300, 1) @@ -268,3 +265,65 @@ category = "Holiday" item = /obj/item/card/emag/halloween surplus = 0 + +///////////////////////// +// Ball map Items // +///////////////////////// + + +/obj/item/wisp_lantern/pumpkin + name = "Pumpkin lantern" + desc = "This lantern gives off no light, but is home to a friendly Jacq o' latern." + icon_state = "lantern-on" + var/obj/effect/wisp/pumpkin/wisp2 + +//Hoooo boy that's some wild code there. +/obj/item/wisp_lantern/pumpkin/Initialize(mapload) + . = ..() + qdel(wisp) + wisp2 = new(src) + wisp = wisp2 + +/obj/effect/wisp/pumpkin + name = "Friendly pumpkin" + desc = "Happy to spook your way." + icon = 'icons/obj/clothing/hats.dmi' + icon_state = "hardhat1_pumpkin_j" + light_range = 5 + light_color = "#EE9933" + layer = 0 + sight_flags = SEE_MOBS + lighting_alpha = 0 + +/obj/effect/wisp/pumpkin/update_user_sight(mob/user) //Disables SUPERLIGHTS + return + +//Damnit LazyBones +/mob/living/simple_animal/lazy_bones + name = "Lazy Bones" + desc = "Simply refuses to get out of bed!" + icon = 'icons/mob/simple_human.dmi' + icon_state = "skeleton" + icon_living = "skeleton" + icon_dead = "skeleton" + gender = NEUTER + mob_biotypes = list(MOB_UNDEAD, MOB_HUMANOID) + turns_per_move = 5 + speak_emote = list("rattles") + emote_see = list("rattles") + maxHealth = 40 + health = 40 + speed = 0 + harm_intent_damage = 0 + melee_damage_lower = 0 + melee_damage_upper = 0 + minbodytemp = 0 + maxbodytemp = 1500 + faction = list("skeleton") + see_in_dark = 8 + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + deathmessage = "collapses into a pile of bones!" + del_on_death = 1 + loot = list(/obj/effect/decal/remains/human) + + stop_automated_movement = 1 diff --git a/code/modules/holiday/halloween/jacqueen.dm b/code/modules/holiday/halloween/jacqueen.dm index ed7453ad3e..117a188af8 100644 --- a/code/modules/holiday/halloween/jacqueen.dm +++ b/code/modules/holiday/halloween/jacqueen.dm @@ -15,6 +15,8 @@ weight = -1 //forces it to be called, regardless of weight max_occurrences = 1 earliest_start = 0 MINUTES + category = EVENT_CATEGORY_HOLIDAY + description = "Spawns Jacq, a friendly mob that gives players a couple fun stuff to do." /datum/round_event/jacqueen/start() ..() @@ -50,6 +52,7 @@ var/cached_z /// I'm busy, don't move. var/busy = FALSE + var/spawn_cars = FALSE var/static/blacklisted_items = typecacheof(list( /obj/effect, @@ -60,12 +63,16 @@ /atom/movable/screen )) -/mob/living/simple_animal/jacq/Initialize() +/mob/living/simple_animal/jacq/Initialize(mapload) . = ..() //fuck you jacq, return a hint you shit cached_z = z poof() -/mob/living/simple_animal/jacq/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/jacq/ComponentInitialize() //she just wants to bring halloween to the station + . = ..() + AddComponent(/datum/component/stationloving) + +/mob/living/simple_animal/jacq/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!ckey) @@ -87,6 +94,9 @@ poof() /mob/living/simple_animal/jacq/on_attack_hand(mob/living/carbon/human/M) + if(spawn_cars) + spawn_cars(M) + return ..() if(!active) say("Hello there [gender_check(M)]!") return ..() @@ -97,6 +107,9 @@ ..() /mob/living/simple_animal/jacq/attack_paw(mob/living/carbon/monkey/M) + if(spawn_cars) + spawn_cars(M) + return ..() if(!active) say("Hello there [gender_check(M)]!") return ..() @@ -124,6 +137,8 @@ /mob/living/simple_animal/jacq/proc/poof() + if(!active)//if disabled, don't poof + return last_poof = world.realtime var/datum/reagents/R = new/datum/reagents(100)//Hey, just in case. var/datum/effect_system/smoke_spread/chem/s = new() @@ -141,7 +156,7 @@ pop_areas += A var/list/targets = list() - for(var/H in GLOB.network_holopads) + for(var/H in GLOB.the_station_areas) var/area/A = get_area(H) if(!A || findtextEx(A.name, "AI") || !(A in pop_areas) || !is_station_level(H)) continue @@ -206,23 +221,11 @@ /mob/living/simple_animal/jacq/proc/treat(mob/living/carbon/C, gender) visible_message("[src] gives off a glowing smile, \"What ken Ah offer ye? I can magic up an object, a potion or a plushie fer ye.\"") jacqrunes("What ken Ah offer ye? I can magic up an object, a potion or a plushie fer ye.", C) - var/choices_reward = list("Object - 3 candies", "Potion - 2 candies", "Jacqueline Tracker - 2 candies", "Plushie - 1 candy", "Can I get to know you instead?", "Become a pumpkinhead dullahan (perma) - 4 candies") + var/choices_reward = list("Object - 3 candies", "Potion - 2 candies", "Jacqueline Tracker - 2 candies", "Plushie - 1 candy", "Can I get to know you instead?") var/choice_reward = input(usr, "Trick or Treat?", "Trick or Treat?") in choices_reward //rewards switch(choice_reward) - if("Become a pumpkinhead dullahan (perma) - 4 candies") - if(!take_candies(C, 4)) - visible_message("[src] raises an eyebrown, \"It's 4 candies for that [gender]! Thems the rules!\"") - jacqrunes("It's 4 candies for that [gender]! Thems the rules!", C) - return - visible_message("[src] waves their arms around, \"Off comes your head, a pumpkin taking it's stead!\"") - jacqrunes("Off comes your head, a pumpkin taking it's stead!", C) - C.reagents.add_reagent(/datum/reagent/mutationtoxin/pumpkinhead, 5) - sleep(20) - poof() - return - if("Object - 3 candies") if(!take_candies(C, 3)) visible_message("[src] raises an eyebrown, \"It's 3 candies per trinket [gender]! Thems the rules!\"") @@ -419,7 +422,7 @@ var/obj/item/W = C.head C.dropItemToGround(W, TRUE) var/jaqc_latern = new /obj/item/clothing/head/hardhat/pumpkinhead/jaqc - C.equip_to_slot(jaqc_latern, SLOT_HEAD, 1, 1) + C.equip_to_slot(jaqc_latern, ITEM_SLOT_HEAD, 1, 1) if(4) visible_message("[src] waves their arms around, \"In your body there's something amiss, you'll find it's a chem made by my sis!\"") jacqrunes("In your body there's something amiss, you'll find it's a chem made by my sis!", C) @@ -436,7 +439,7 @@ var/obj/item/W = H.wear_suit H.dropItemToGround(W, TRUE) var/ghost = new /obj/item/clothing/suit/ghost_sheet/sticky - H.equip_to_slot(ghost, SLOT_WEAR_SUIT, 1, 1) + H.equip_to_slot(ghost, ITEM_SLOT_OCLOTHING, 1, 1) poof() //Blame Fel @@ -466,15 +469,182 @@ sleep(20) poof() +/mob/living/simple_animal/jacq/proc/spawn_cars(mob/living/carbon/C) + visible_message("[src] gives off a glowing smile, \"What ken Ah offer ye? I can magic up a vectorcraft in manual or automatic fer ye.\"") + var/choices_reward = list("Manual", "Automatic", "How do Automatics work?", "Nothing, thanks") + var/choice_reward = input(usr, "Trick or Treat?", "Trick or Treat?") in choices_reward + + switch(choice_reward) + if("Manual") + visible_message("[src] waves their arms around, \"Great choice! 'Ere's yer car.\"") + jacqrunes("Great choice! 'Ere's yer car.", C) + new /obj/vehicle/sealed/vectorcraft(loc) + if("Automatic") + visible_message("[src] waves their arms around, \"'Ere's yer car. Not as fast as an automatic mind.\"") + jacqrunes("'Ere's yer car. Not as fast as an automatic mind.", C) + new /obj/vehicle/sealed/vectorcraft/auto(loc) + if("How do Automatics work?") + visible_message("[src] smiles, \"Hold wasd to gain speed in a direction, c to enable/disable the clutch, 1 2 3 4 to change gears (help is gear 1, disarm is gear 2, grab is gear 3 and harm is gear 4) while holding a direction (make sure the clutch is enabled when you change gears, you should hear a sound when you've successfully changed gears), r to toggle handbrake, hold alt for brake and press shift for boost (the machine will beep when the boost is recharged)! If you hear an ebbing sound like \"brbrbrbrbr\" you need to gear down, the whining sound means you need to gear up. Hearing a pleasant \"whumwhumwhum\" is optimal gearage! It can be a lil slow to start, so make sure you're in the 1st gear, andusing a boost to get you started is a good idea. If you've got a good speed you'll likely never need to dip down to gear 1 again, and make sure to hold the acceleration pedal down while changing gears (hold a direction). 1st gear is for slow movement, and it's a good idea to mvoe to 2nd gear as quick as you can, you can coldstart a car from gear one by slowly moving, then using the boost to jump you up to gear 2 speeds. The upper gears are for unlimiting your top speed.\"") + jacqrunes("They're a bit tricky, aye. Basically;", C) + if("Nothing, thanks") + visible_message("[src] shrugs, \"Suit yerself.\"") + jacqrunes("Suit yerself.", C) + + visible_message("[src] shrugs, \"Oh and look after the crafts, aye? They can get a wee bit... explosive if banged up a tad too much. They move slower damaged too like. Ye can repair 'em with the welders o'er there.\"") + jacqrunes("Oh and look after the crafts, aye? They can get a wee bit... explosive if banged up a tad too much. They move slower damaged too like. Ye can repair 'em with the welders o'er there. ", C) + /mob/living/simple_animal/jacq/update_mobility() . = ..() if(busy) - DISABLE_BITFIELD(., MOBILITY_MOVE) + . &= ~(MOBILITY_MOVE) else - ENABLE_BITFIELD(., MOBILITY_MOVE) + . |= MOBILITY_MOVE mobility_flags = . +//Christmas car spawner +/mob/living/simple_animal/jacq/car_spawner + name = "Jacqueline cars terminal" + icon_state = "jacq_cars_spawner" + AIStatus = AI_OFF + spawn_cars = TRUE + active = FALSE + +/mob/living/simple_animal/jacq/car_spawner/Destroy() + visible_message("The [src] gives out an error sound, \"Ey! Bugger off!\"") + fully_heal(FALSE) + return ..() + +/mob/living/simple_animal/jacq/car_spawner/death() + visible_message("The [src] gives out an error sound, \"Ey! Bugger off!\"") + fully_heal(FALSE) + +/mob/living/simple_animal/jacq/car_spawner/poof() + if(!active)//if disabled, don't poof + return + var/datum/reagents/R = new/datum/reagents(100)//Hey, just in case. + var/datum/effect_system/smoke_spread/chem/s = new() + R.add_reagent(/datum/reagent/fermi/secretcatchem, 10) + s.set_up(R, 0, loc) + s.start() + stopmove() + health = 25 + +/mob/living/simple_animal/jacq/car_spawner/spawn_cars(mob/living/carbon/C) + visible_message("[src] boots up and displays jacq's glowing smile, \"Hallo there user! Merry Christmas! What ken type o' craft ken Ah offer ye? I can magic up a vectorcraft in manual, automatic or customise it if yer feeling technical.\"") + jacqrunes("Hallo there user! What ken type o' craft ken Ah offer ye? I can magic up a vectorcraft in manual, automatic or customise it if yer feeling technical.", C) + + var/choices_reward = list("Manual", "Automatic", "Customise", "Are you a computer now Jacq?", "Nothing, thanks") + var/choice_reward = input(usr, "Merry Trick_or_Treat.exe initiated!", "Merry Trick_or_Treat.exe initiated!") in choices_reward + + switch(choice_reward) + if("Manual") + visible_message("The [src] makes a magical booping sound, \"Great choice! 'Ere's yer car.\"") + jacqrunes("Great choice! 'Ere's yer car.", C) + new /obj/vehicle/sealed/vectorcraft(loc) + if("Automatic") + visible_message("[src] makes a magical booping sound, \"'Ere's yer car. Not as fast as an automatic mind.\"") + jacqrunes("'Ere's yer car. Not as fast as an automatic mind.", C) + new /obj/vehicle/sealed/vectorcraft/auto(loc) + if("Are you a computer now Jacq?") + visible_message("[src] makes a frustrated error sound, \"Nae, are ye daft? Ah built these thingies tae magic up cars fer ye. Well, I got a speccy four eyes tae do it fer me, but me names on it like cause it was me idea.\"") + jacqrunes("Nae, are ye daft? Ah built these thingies tae magic up cars fer ye. Well, I got a speccy four eyes tae do it fer me, but me names on it like cause it was me idea.", C) + if("Customise") + visible_message("The [src] pings, \"Arright, Manual or Automatic?\"") + var/choices_transm = list("Manual", "Automatic") + var/choice_transm = input(usr, "Choose transmission", "Choose transmission") in choices_transm + var/points = 0 + var/obj/vehicle/sealed/vectorcraft/VC + switch(choice_transm) + if("Manual") + VC = new /obj/vehicle/sealed/vectorcraft(loc) + if("Automatic") + VC = new /obj/vehicle/sealed/vectorcraft/auto(loc) + points += 500 + + visible_message("The [src] pings, \"Maximum acceleration? (default [VC.max_acceleration], max 10)\"") + var/max_accl = text2num(input(usr, "Maximum acceleration? (default [VC.max_acceleration], max 10)", "[VC.max_acceleration]")) + max_accl = clamp(max_accl, 0, 10) + VC.max_acceleration = max_accl + VC.i_m_acell = max_accl + points += max_accl*10 + + /* This is internally used + visible_message("The [src] pings, \"Acceleration step? (default 0.3, max 1)\"") + var/max_accl_s = text2num(input(usr, "Acceleration step? (default 0.3, max 1)", "[VC.accel_step]")) + max_accl_s = clamp(max_accl_s, 0, 1) + VC.max_acceleration = max_accl_s + points += max_accl_s*100 + */ + + visible_message("The [src] pings, \"Acceleration? (default [VC.acceleration], max 2)\"") + var/accl = text2num(input(usr, "Acceleration? (default [VC.acceleration], max 2)", "[VC.acceleration]")) + accl = clamp(accl, 0, 2) + VC.acceleration = accl + VC.i_acell = accl + points += accl*100 + + visible_message("The [src] pings, \"Maximum deceleration? (default [VC.max_deceleration], max 15)\"") + var/deaccl = text2num(input(usr, "Max_deceleration? (default [VC.max_deceleration], max 15)", "[VC.max_deceleration]")) + deaccl = clamp(deaccl, 0, 15) + VC.max_deceleration = deaccl + VC.i_m_decell = deaccl + points += deaccl*10 + + visible_message("The [src] pings, \"Maximum velocity? (default [VC.max_velocity], max 200)\"") + var/m_velo = text2num(input(usr, "Maximum velocity? (default [VC.max_velocity], max 200)", "[VC.max_velocity]")) + m_velo = clamp(m_velo, 0, 200) + VC.max_velocity = m_velo + points += m_velo + + visible_message("The [src] pings, \"Boost power? (default [VC.boost_power], max 200)\"") + var/boost = text2num(input(usr, "Boost power? (default [VC.boost_power], max 200)", "[VC.boost_power]")) + boost = clamp(boost, 0, 200) + VC.boost_power = boost + VC.i_boost = boost + points += boost + + visible_message("The [src] pings, \"Health points? (default [VC.max_integrity], max 1000)\"") + var/health = text2num(input(usr, "Health points? (default [VC.max_integrity], max 1000)", "[VC.max_integrity]")) + health = clamp(health, 0, 500) + VC.max_integrity = health + points += health/2 + + visible_message("The [src] pings, \"Arright, 'ow do ye want it tae look?\"") + var/choices_icon = list("Racer", "Truck", "Cyber", "Ambulance", "Pod", "Clown") + var/choice_icon = input(usr, "Choose body", "Choose body") in choices_icon + switch(choice_icon) + if("Truck") + VC.icon_state = "truck" + + if("Cyber") + VC.icon_state = "cyber" + + if("Ambulance") + VC.icon_state = "ambutruck" + + if("Pod") + VC.icon_state = "engineering_pod" + + if("Clown") + VC.icon_state = "clowncar" + + visible_message("The [src] pings, \"Finally; what name are ye gonna give it?\"") + var/choice_name = input(usr, "Pick a name!", "") + choice_name += " (Points cost:[points])" + VC.name = choice_name + + visible_message("The [src] gives a final boop, \"There ye be, enjoy!\"") + + if("How do Automatics work?") + visible_message("The image of Jacq on the [src] smiles, \"Hold wasd to gain speed in a direction, c to enable/disable the clutch, 1 2 3 4 to change gears (help is gear 1, disarm is gear 2, grab is gear 3 and harm is gear 4) while holding a direction (make sure the clutch is enabled when you change gears, you should hear a sound when you've successfully changed gears), r to toggle handbrake, hold alt for brake and press shift for boost (the machine will beep when the boost is recharged)! If you hear an ebbing sound like \"brbrbrbrbr\" you need to gear down, the whining sound means you need to gear up. Hearing a pleasant \"whumwhumwhum\" is optimal gearage! It can be a lil slow to start, so make sure you're in the 1st gear, andusing a boost to get you started is a good idea. If you've got a good speed you'll likely never need to dip down to gear 1 again, and make sure to hold the acceleration pedal down while changing gears (hold a direction). 1st gear is for slow movement, and it's a good idea to mvoe to 2nd gear as quick as you can, you can coldstart a car from gear one by slowly moving, then using the boost to jump you up to gear 2 speeds. The upper gears are for unlimiting your top speed.\"") + jacqrunes("They're a bit tricky, aye. Basically;", C) + if("Nothing, thanks") + visible_message("The image of Jacq on the [src] shrugs, \"Suit yerself.\"") + jacqrunes("Suit yerself.", C) + + visible_message("The [src] beeps, \"Oh and look after the crafts, aye? They can get a wee bit... explosive if banged up a tad too much. They move slower damaged too like. Ye can repair 'em with the welders o'er there.\"") + jacqrunes("Oh and look after the crafts, aye? They can get a wee bit... explosive if banged up a tad too much. They move slower damaged too like. Ye can repair 'em with the welders o'er there. ", C) /obj/item/clothing/head/hardhat/pumpkinhead/jaqc name = "Jacq o' latern" @@ -484,13 +654,13 @@ hat_type = "pumpkin_j" brightness_on = 4 -/obj/item/clothing/head/hardhat/pumpkinhead/jaqc/Initialize() +/obj/item/clothing/head/hardhat/pumpkinhead/jaqc/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, GLUED_ITEM_TRAIT) /obj/item/clothing/suit/ghost_sheet/sticky -/obj/item/clothing/suit/ghost_sheet/sticky/Initialize() +/obj/item/clothing/suit/ghost_sheet/sticky/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, GLUED_ITEM_TRAIT) @@ -508,12 +678,6 @@ else ..() -/datum/reagent/mutationtoxin/pumpkinhead - name = "Pumpkin head mutation toxin" - race = /datum/species/dullahan/pumpkin - mutationtext = "The pain subsides. You feel your head roll off your shoulders... and you smell pumpkin." - //I couldn't get the replace head sprite with a pumpkin to work so, it is what it is. - /mob/living/simple_animal/jacq/proc/check_candies(mob/living/carbon/C) var/invs = C.get_contents() var/candy_count = 0 @@ -543,7 +707,7 @@ icon_state = "jacq_potion" desc = "A potion with a strange concoction within. Be careful, as if it's thrown it explodes in a puff of smoke like Jacqueline." -/obj/item/reagent_containers/potion_container/Initialize() +/obj/item/reagent_containers/potion_container/Initialize(mapload) .=..() var/R = get_random_reagent_id() reagents.add_reagent(R, 30) @@ -551,9 +715,13 @@ /obj/item/reagent_containers/potion_container/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) ..() + delayed_release_smoke() + +/obj/item/reagent_containers/potion_container/proc/delayed_release_smoke() + set waitfor = FALSE sleep(20) var/datum/effect_system/smoke_spread/chem/s = new() - s.set_up(src.reagents, 3, src.loc) + s.set_up(src.reagents, 3, get_turf(src)) s.start() qdel(src) @@ -564,6 +732,6 @@ icon_state = "jacq_candy" desc = "A candy with strange magic within. Be careful, as the magic isn't always helpful." -/obj/item/reagent_containers/food/snacks/special_candy/Initialize() +/obj/item/reagent_containers/food/snacks/special_candy/Initialize(mapload) .=..() reagents.add_reagent(get_random_reagent_id(), 5) diff --git a/code/modules/holiday/holidays.dm b/code/modules/holiday/holidays.dm index e3f5264568..239246cd59 100644 --- a/code/modules/holiday/holidays.dm +++ b/code/modules/holiday/holidays.dm @@ -641,6 +641,18 @@ Since Ramadan is an entire month that lasts 29.5 days on average, the start and /datum/holiday/easter/getStationPrefix() return pick("Fluffy","Bunny","Easter","Egg") +/datum/holiday/ianbirthday + name = "Ian's Birthday" //github.com/tgstation/tgstation/commit/de7e4f0de0d568cd6e1f0d7bcc3fd34700598acb + begin_month = SEPTEMBER + begin_day = 9 + end_day = 10 + +/datum/holiday/ianbirthday/greet() + return "Happy birthday, Ian!" + +/datum/holiday/ianbirthday/getStationPrefix() + return pick("Ian", "Corgi", "Erro") + //Random citadel thing for halloween species /proc/force_enable_halloween_species() var/list/oldlist = SSevents.holidays diff --git a/code/modules/holodeck/area_copy.dm b/code/modules/holodeck/area_copy.dm index 738d10665a..d69b9da768 100644 --- a/code/modules/holodeck/area_copy.dm +++ b/code/modules/holodeck/area_copy.dm @@ -138,7 +138,7 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars_by_type, typecacheof_assoc_list(list( if(toupdate.len) for(var/turf/T1 in toupdate) - CALCULATE_ADJACENT_TURFS(T1) + T1.ImmediateCalculateAdjacentTurfs() return copiedobjs diff --git a/code/modules/holodeck/computer.dm b/code/modules/holodeck/computer.dm index e94cc17041..49a5c607ec 100644 --- a/code/modules/holodeck/computer.dm +++ b/code/modules/holodeck/computer.dm @@ -203,7 +203,7 @@ return emergency_shutdown() -/obj/machinery/computer/holodeck/ex_act(severity, target) +/obj/machinery/computer/holodeck/ex_act(severity, target, origin) emergency_shutdown() return ..() diff --git a/code/modules/holodeck/holo_effect.dm b/code/modules/holodeck/holo_effect.dm index c37ccf657b..5d6259d9c2 100644 --- a/code/modules/holodeck/holo_effect.dm +++ b/code/modules/holodeck/holo_effect.dm @@ -78,7 +78,7 @@ // these vars are not really standardized but all would theoretically create stuff on death for(var/v in list("butcher_results","corpse","weapon1","weapon2","blood_volume") & mob.vars) mob.vars[v] = null - ENABLE_BITFIELD(mob.flags_1, HOLOGRAM_1) + mob.flags_1 |= HOLOGRAM_1 if(isliving(mob)) var/mob/living/L = mob L.vore_flags = 0 @@ -105,7 +105,7 @@ /obj/effect/holodeck_effect/mobspawner/penguin mobtype = /mob/living/simple_animal/pet/penguin/emperor -/obj/effect/holodeck_effect/mobspawner/penguin/Initialize() +/obj/effect/holodeck_effect/mobspawner/penguin/Initialize(mapload) if(prob(1)) mobtype = /mob/living/simple_animal/pet/penguin/emperor/shamebrero return ..() diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm index e4564ecb7e..a88b8ab905 100644 --- a/code/modules/holodeck/items.dm +++ b/code/modules/holodeck/items.dm @@ -26,12 +26,12 @@ var/active = 0 var/saber_color -/obj/item/holo/esword/green/Initialize() +/obj/item/holo/esword/green/Initialize(mapload) . = ..() saber_color = "green" -/obj/item/holo/esword/red/Initialize() +/obj/item/holo/esword/red/Initialize(mapload) . = ..() saber_color = "red" @@ -40,7 +40,7 @@ return ..() return ..() -/obj/item/holo/esword/Initialize() +/obj/item/holo/esword/Initialize(mapload) . = ..() saber_color = pick("red","blue","green","purple") diff --git a/code/modules/holodeck/turfs.dm b/code/modules/holodeck/turfs.dm index 169c9061d3..7340ffda61 100644 --- a/code/modules/holodeck/turfs.dm +++ b/code/modules/holodeck/turfs.dm @@ -58,7 +58,7 @@ icon_state = "asteroid0" tiled_dirt = FALSE -/turf/open/floor/holofloor/asteroid/Initialize() +/turf/open/floor/holofloor/asteroid/Initialize(mapload) icon_state = "asteroid[rand(0, 12)]" . = ..() @@ -68,7 +68,7 @@ icon_state = "basalt0" tiled_dirt = FALSE -/turf/open/floor/holofloor/basalt/Initialize() +/turf/open/floor/holofloor/basalt/Initialize(mapload) . = ..() if(prob(15)) icon_state = "basalt[rand(0, 12)]" @@ -79,7 +79,7 @@ icon = 'icons/turf/space.dmi' icon_state = "0" -/turf/open/floor/holofloor/space/Initialize() +/turf/open/floor/holofloor/space/Initialize(mapload) icon_state = SPACE_ICON_STATE // so realistic . = ..() @@ -90,11 +90,11 @@ bullet_bounce_sound = null tiled_dirt = FALSE -/turf/open/floor/holofloor/hyperspace/Initialize() +/turf/open/floor/holofloor/hyperspace/Initialize(mapload) icon_state = "speedspace_ns_[(x + 5*y + (y%2+1)*7)%15+1]" . = ..() -/turf/open/floor/holofloor/hyperspace/ns/Initialize() +/turf/open/floor/holofloor/hyperspace/ns/Initialize(mapload) . = ..() icon_state = "speedspace_ns_[(x + 5*y + (y%2+1)*7)%15+1]" @@ -109,7 +109,7 @@ bullet_bounce_sound = null tiled_dirt = FALSE -/turf/open/floor/holofloor/carpet/Initialize() +/turf/open/floor/holofloor/carpet/Initialize(mapload) . = ..() addtimer(CALLBACK(src, /atom/.proc/update_icon), 1) @@ -167,6 +167,6 @@ canSmoothWith = list(/turf/open/floor/plating/ice/smooth, /turf/open/floor/plating/ice, /turf/open/floor/holofloor/ice) baseturfs = /turf/open/floor/holofloor/ice/smooth -/turf/open/floor/holofloor/ice/Initialize() +/turf/open/floor/holofloor/ice/Initialize(mapload) . = ..() MakeSlippery(TURF_WET_PERMAFROST, INFINITY, 0, INFINITY, TRUE) diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm index 2857099d0f..28e537acbc 100644 --- a/code/modules/hydroponics/beekeeping/beebox.dm +++ b/code/modules/hydroponics/beekeeping/beebox.dm @@ -40,7 +40,7 @@ var/bee_resources = 0 -/obj/structure/beebox/Initialize() +/obj/structure/beebox/Initialize(mapload) . = ..() START_PROCESSING(SSobj, src) @@ -58,7 +58,7 @@ var/random_reagent = FALSE -/obj/structure/beebox/premade/Initialize() +/obj/structure/beebox/premade/Initialize(mapload) . = ..() icon_state = "beebox" diff --git a/code/modules/hydroponics/beekeeping/honey_frame.dm b/code/modules/hydroponics/beekeeping/honey_frame.dm index 370b31da17..3cc3f9806d 100644 --- a/code/modules/hydroponics/beekeeping/honey_frame.dm +++ b/code/modules/hydroponics/beekeeping/honey_frame.dm @@ -7,7 +7,7 @@ var/honeycomb_capacity = 10 //10 Honeycomb per frame by default, researchable frames perhaps? -/obj/item/honey_frame/Initialize() +/obj/item/honey_frame/Initialize(mapload) . = ..() pixel_x = rand(8,-8) pixel_y = rand(8,-8) diff --git a/code/modules/hydroponics/beekeeping/honeycomb.dm b/code/modules/hydroponics/beekeeping/honeycomb.dm index 6ce04a8732..d31ea281c7 100644 --- a/code/modules/hydroponics/beekeeping/honeycomb.dm +++ b/code/modules/hydroponics/beekeeping/honeycomb.dm @@ -13,7 +13,7 @@ grind_results = list() var/honey_color = "" -/obj/item/reagent_containers/honeycomb/Initialize() +/obj/item/reagent_containers/honeycomb/Initialize(mapload) . = ..() pixel_x = rand(8,-8) pixel_y = rand(8,-8) diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index b61d9451ef..71513ccfdf 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -18,7 +18,7 @@ /// Currently selected category in the UI var/selected_cat -/obj/machinery/biogenerator/Initialize() +/obj/machinery/biogenerator/Initialize(mapload) . = ..() stored_research = new /datum/techweb/specialized/autounlocking/biogenerator create_reagents(1000) @@ -27,10 +27,10 @@ QDEL_NULL(beaker) return ..() -/obj/machinery/biogenerator/contents_explosion(severity, target) +/obj/machinery/biogenerator/contents_explosion(severity, target, origin) ..() if(beaker) - beaker.ex_act(severity, target) + beaker.ex_act(severity, target, origin) /obj/machinery/biogenerator/handle_atom_del(atom/A) ..() diff --git a/code/modules/hydroponics/fermenting_barrel.dm b/code/modules/hydroponics/fermenting_barrel.dm index 3d6b90eb2d..fd0f39fd75 100644 --- a/code/modules/hydroponics/fermenting_barrel.dm +++ b/code/modules/hydroponics/fermenting_barrel.dm @@ -10,7 +10,7 @@ var/open = FALSE var/speed_multiplier = 1 //How fast it distills. Defaults to 100% (1.0). Lower is better. -/obj/structure/fermenting_barrel/Initialize() +/obj/structure/fermenting_barrel/Initialize(mapload) create_reagents(300, DRAINABLE | AMOUNT_VISIBLE) //Bluespace beakers, but without the portability or efficiency in circuits. . = ..() @@ -59,12 +59,12 @@ /obj/structure/fermenting_barrel/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) open = !open if(open) - DISABLE_BITFIELD(reagents.reagents_holder_flags, DRAINABLE) - ENABLE_BITFIELD(reagents.reagents_holder_flags, REFILLABLE) + reagents.reagents_holder_flags &= ~(DRAINABLE) + reagents.reagents_holder_flags |= REFILLABLE to_chat(user, "You open [src], letting you fill it.") else - DISABLE_BITFIELD(reagents.reagents_holder_flags, REFILLABLE) - ENABLE_BITFIELD(reagents.reagents_holder_flags, DRAINABLE) + reagents.reagents_holder_flags &= ~(REFILLABLE) + reagents.reagents_holder_flags |= DRAINABLE to_chat(user, "You close [src], letting you draw from its tap.") update_icon() @@ -85,7 +85,7 @@ max_integrity = 300 var/open = FALSE -/obj/structure/custom_keg/Initialize() +/obj/structure/custom_keg/Initialize(mapload) create_reagents(1000, DRAINABLE | AMOUNT_VISIBLE) . = ..() @@ -96,12 +96,12 @@ /obj/structure/custom_keg/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) open = !open if(open) - DISABLE_BITFIELD(reagents.reagents_holder_flags, DRAINABLE) - ENABLE_BITFIELD(reagents.reagents_holder_flags, REFILLABLE) + reagents.reagents_holder_flags &= ~(DRAINABLE) + reagents.reagents_holder_flags |= REFILLABLE to_chat(user, "You open [src], letting you fill it.") else - DISABLE_BITFIELD(reagents.reagents_holder_flags, REFILLABLE) - ENABLE_BITFIELD(reagents.reagents_holder_flags, DRAINABLE) + reagents.reagents_holder_flags &= ~(REFILLABLE) + reagents.reagents_holder_flags |= DRAINABLE to_chat(user, "You close [src], letting you draw from its tap.") update_icon() diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm index a6ba5ec461..3b1c4eb163 100644 --- a/code/modules/hydroponics/gene_modder.dm +++ b/code/modules/hydroponics/gene_modder.dm @@ -424,7 +424,7 @@ var/read_only = 0 //Well, it's still a floppy disk obj_flags = UNIQUE_RENAME -/obj/item/disk/plantgene/Initialize() +/obj/item/disk/plantgene/Initialize(mapload) . = ..() add_overlay("datadisk_gene") src.pixel_x = rand(-5, 5) diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm index e825c88524..65a28eee2e 100644 --- a/code/modules/hydroponics/grown/banana.dm +++ b/code/modules/hydroponics/grown/banana.dm @@ -167,6 +167,6 @@ name = "synthesized banana peel" desc = "A synthetic banana peel." -/obj/item/grown/bananapeel/specialpeel/Initialize(AM) +/obj/item/grown/bananapeel/specialpeel/Initialize(mapload, AM) . = ..() AddComponent(/datum/component/slippery, 40) diff --git a/code/modules/hydroponics/grown/cannabis.dm b/code/modules/hydroponics/grown/cannabis.dm index 1882d5fe97..7771d24e16 100644 --- a/code/modules/hydroponics/grown/cannabis.dm +++ b/code/modules/hydroponics/grown/cannabis.dm @@ -11,8 +11,8 @@ growthstages = 1 instability = 40 growing_icon = 'goon/icons/obj/hydroponics.dmi' - icon_grow = "cannabis-grow" // Uses one growth icons set for all the subtypes - icon_dead = "cannabis-dead" // Same for the dead icon + icon_grow = "cannabis-grow" + icon_dead = "cannabis-dead" genes = list(/datum/plant_gene/trait/repeated_harvest) mutatelist = list(/obj/item/seeds/cannabis/rainbow, /obj/item/seeds/cannabis/death) @@ -26,6 +26,8 @@ species = "megacannabis" plantname = "Rainbow Weed" product = /obj/item/reagent_containers/food/snacks/grown/cannabis/rainbow + icon_grow = "megacannabis-grow" + icon_dead = "megacannabis-dead" mutatelist = list(/obj/item/seeds/cannabis/ultimate) reagents_add = list(/datum/reagent/toxin/mindbreaker = 0.15, /datum/reagent/toxin/lipolicide = 0.35) rarity = 40 @@ -37,6 +39,8 @@ species = "blackcannabis" plantname = "Deathweed" product = /obj/item/reagent_containers/food/snacks/grown/cannabis/death + icon_grow = "blackcannabis-grow" + icon_dead = "blackcannabis-dead" mutatelist = list(/obj/item/seeds/cannabis/white) reagents_add = list(/datum/reagent/toxin/cyanide = 0.35, /datum/reagent/drug/space_drugs = 0.15, /datum/reagent/toxin/lipolicide = 0.15) rarity = 40 @@ -48,6 +52,8 @@ species = "whitecannabis" plantname = "Lifeweed" product = /obj/item/reagent_containers/food/snacks/grown/cannabis/white + icon_grow = "whitecannabis-grow" + icon_dead = "whitecannabis-dead" mutatelist = list() reagents_add = list(/datum/reagent/medicine/omnizine = 0.35, /datum/reagent/drug/space_drugs = 0.15, /datum/reagent/toxin/lipolicide = 0.15) rarity = 40 @@ -60,6 +66,8 @@ species = "ocannabis" plantname = "Omega Weed" product = /obj/item/reagent_containers/food/snacks/grown/cannabis/ultimate + icon_grow = "ocannabis-grow" + icon_dead = "ocannabis-dead" genes = list(/datum/plant_gene/trait/repeated_harvest, /datum/plant_gene/trait/glow/green) mutatelist = list() reagents_add = list(/datum/reagent/drug/space_drugs = 0.3, diff --git a/code/modules/hydroponics/grown/citrus.dm b/code/modules/hydroponics/grown/citrus.dm index e199c2c6b1..b0af08d515 100644 --- a/code/modules/hydroponics/grown/citrus.dm +++ b/code/modules/hydroponics/grown/citrus.dm @@ -173,7 +173,7 @@ var/mob/M = loc M.dropItemToGround(src) -/obj/item/reagent_containers/food/snacks/grown/firelemon/ex_act(severity) +/obj/item/reagent_containers/food/snacks/grown/firelemon/ex_act(severity, target, origin) qdel(src) //Ensuring that it's deleted by its own explosion /obj/item/reagent_containers/food/snacks/grown/firelemon/proc/prime(mob/living/lanced_by) diff --git a/code/modules/hydroponics/grown/cocoa_vanilla.dm b/code/modules/hydroponics/grown/cocoa_vanilla.dm index 5de0740b87..3a1c78a7a9 100644 --- a/code/modules/hydroponics/grown/cocoa_vanilla.dm +++ b/code/modules/hydroponics/grown/cocoa_vanilla.dm @@ -96,7 +96,7 @@ foodtype = TOXIC tastes = list("acrid bitterness" = 1) -/obj/item/reagent_containers/food/snacks/grown/bungopit/Initialize() +/obj/item/reagent_containers/food/snacks/grown/bungopit/Initialize(mapload) . =..() reagents.clear_reagents() reagents.add_reagent(/datum/reagent/toxin/bungotoxin, seed.potency * 0.10) //More than this will kill at too low potency diff --git a/code/modules/hydroponics/grown/kudzu.dm b/code/modules/hydroponics/grown/kudzu.dm index 73026e546a..f48c660667 100644 --- a/code/modules/hydroponics/grown/kudzu.dm +++ b/code/modules/hydroponics/grown/kudzu.dm @@ -44,7 +44,7 @@ /obj/item/seeds/kudzu/attack_self(mob/user) user.visible_message("[user] begins throwing seeds on the ground...") - if(do_after(user, 50, needhand = TRUE, target = user.drop_location(), progress = TRUE)) + if(do_after(user, 5 SECONDS, target = user.drop_location())) plant(user) to_chat(user, "You plant the kudzu. You monster.") diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm index b988261770..c8b952889b 100644 --- a/code/modules/hydroponics/grown/melon.dm +++ b/code/modules/hydroponics/grown/melon.dm @@ -61,7 +61,7 @@ wine_flavor = "divinity" /* -/obj/item/reagent_containers/food/snacks/grown/holymelon/Initialize() +/obj/item/reagent_containers/food/snacks/grown/holymelon/Initialize(mapload) . = ..() var/uses = 1 if(seed) diff --git a/code/modules/hydroponics/grown/misc.dm b/code/modules/hydroponics/grown/misc.dm index 733d973832..d32d287800 100644 --- a/code/modules/hydroponics/grown/misc.dm +++ b/code/modules/hydroponics/grown/misc.dm @@ -224,7 +224,7 @@ if(!QDELETED(src)) qdel(src) -/obj/item/reagent_containers/food/snacks/grown/cherry_bomb/ex_act(severity) +/obj/item/reagent_containers/food/snacks/grown/cherry_bomb/ex_act(severity, target, origin) qdel(src) //Ensuring that it's deleted by its own explosion. Also prevents mass chain reaction with piles of cherry bombs /obj/item/reagent_containers/food/snacks/grown/cherry_bomb/proc/prime(mob/living/lanced_by) @@ -365,7 +365,7 @@ opened = TRUE spillable = !screwdrivered reagent_flags = OPENCONTAINER - ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) + reagents.reagents_holder_flags |= OPENCONTAINER icon_state = screwdrivered ? "coconut_carved" : "coconut_chopped" desc = "A coconut. [screwdrivered ? "This one's got a hole in it" : "This one's sliced open, with all its delicious contents for your eyes to savour"]." playsound(user, W.hitsound, 50, 1, -1) @@ -377,7 +377,7 @@ var/obj/item/bodypart/affecting = user.zone_selected //Find what the player is aiming at if (affecting == BODY_ZONE_HEAD && prob(15)) //smash the nut open - var/armor_block = min(90, M.run_armor_check(affecting, "melee", null, null,armour_penetration)) // For normal attack damage + var/armor_block = min(90, M.run_armor_check(affecting, MELEE, null, null,armour_penetration)) // For normal attack damage M.apply_damage(force, BRUTE, affecting, armor_block) //Sound @@ -500,7 +500,7 @@ log_game("Coconut bomb detonation at [AREACOORD(T)], location [loc]") qdel(src) -/obj/item/reagent_containers/food/snacks/grown/coconut/ex_act(severity) +/obj/item/reagent_containers/food/snacks/grown/coconut/ex_act(severity, target, origin) qdel(src) /obj/item/reagent_containers/food/snacks/grown/coconut/deconstruct(disassembled = TRUE) diff --git a/code/modules/hydroponics/grown/random.dm b/code/modules/hydroponics/grown/random.dm index 75505202da..cc4da4c6e5 100644 --- a/code/modules/hydroponics/grown/random.dm +++ b/code/modules/hydroponics/grown/random.dm @@ -12,7 +12,7 @@ icon_harvest = "xpod-harvest" growthstages = 4 -/obj/item/seeds/random/Initialize() +/obj/item/seeds/random/Initialize(mapload) . = ..() randomize_stats() if(prob(60)) @@ -28,7 +28,7 @@ icon_state = "crunchy" bitesize_mod = 2 -/obj/item/reagent_containers/food/snacks/grown/random/Initialize() +/obj/item/reagent_containers/food/snacks/grown/random/Initialize(mapload) . = ..() wine_power = rand(10,150) if(prob(1)) diff --git a/code/modules/hydroponics/grown/replicapod.dm b/code/modules/hydroponics/grown/replicapod.dm index 328b4c391c..e15c8f1323 100644 --- a/code/modules/hydroponics/grown/replicapod.dm +++ b/code/modules/hydroponics/grown/replicapod.dm @@ -24,7 +24,7 @@ var/list/quirks = null var/contains_sample = 0 -/obj/item/seeds/replicapod/Initialize() +/obj/item/seeds/replicapod/Initialize(mapload) . = ..() create_reagents(volume, INJECTABLE | DRAWABLE) @@ -53,31 +53,21 @@ /obj/item/seeds/replicapod/on_reagent_change(changetype) if(changetype == ADD_REAGENT) - var/datum/reagent/blood/B = reagents.has_reagent(/datum/reagent/blood) - if(B) - if(B.data["mind"] && B.data["cloneable"]) - mind = B.data["mind"] - ckey = B.data["ckey"] - realName = B.data["real_name"] - blood_gender = B.data["gender"] - blood_type = B.data["blood_type"] - features = B.data["features"] - factions = B.data["factions"] - quirks = B.data["quirks"] - contains_sample = TRUE - visible_message("The [src] is injected with a fresh blood sample.") - else - visible_message("The [src] rejects the sample!") - - if(!reagents.has_reagent(/datum/reagent/blood)) - mind = null - ckey = null - realName = null - blood_gender = null - blood_type = null - features = null - factions = null - contains_sample = FALSE + for(var/datum/reagent/R as anything in reagents.reagent_list) + if(R.data["mind"]) + if(R.data["cloneable"]) + mind = R.data["mind"] + ckey = R.data["ckey"] + realName = R.data["real_name"] + blood_gender = R.data["gender"] + blood_type = R.data["blood_type"] + features = R.data["features"] + factions = R.data["factions"] + quirks = R.data["quirks"] + contains_sample = TRUE + visible_message("The [src] is injected with a fresh blood sample.") + else + visible_message("The [src] rejects the sample!") /obj/item/seeds/replicapod/get_analyzer_text() var/text = ..() diff --git a/code/modules/hydroponics/grown/root.dm b/code/modules/hydroponics/grown/root.dm index 5f9b55b881..843688b5a0 100644 --- a/code/modules/hydroponics/grown/root.dm +++ b/code/modules/hydroponics/grown/root.dm @@ -29,7 +29,7 @@ /obj/item/reagent_containers/food/snacks/grown/carrot/attackby(obj/item/I, mob/user, params) if(I.get_sharpness()) to_chat(user, "You sharpen the carrot into a shiv with [I].") - var/obj/item/kitchen/knife/carrotshiv/Shiv = new /obj/item/kitchen/knife/carrotshiv + var/obj/item/kitchen/knife/shiv/carrot/Shiv = new /obj/item/kitchen/knife/shiv/carrot remove_item_from_storage(user) qdel(src) user.put_in_hands(Shiv) diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm index 9c82cf34d3..b45a9292b1 100644 --- a/code/modules/hydroponics/grown/towercap.dm +++ b/code/modules/hydroponics/grown/towercap.dm @@ -151,6 +151,7 @@ density = FALSE anchored = TRUE buckle_lying = 0 + pass_flags_self = PASSTABLE | LETPASSTHROW var/burning = 0 var/burn_icon = "bonfire_on_fire" //for a softer more burning embers icon, use "bonfire_warm" var/grill = FALSE @@ -159,17 +160,10 @@ /obj/structure/bonfire/dense density = TRUE -/obj/structure/bonfire/prelit/Initialize() +/obj/structure/bonfire/prelit/Initialize(mapload) . = ..() StartBurning() -/obj/structure/bonfire/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSTABLE)) - return TRUE - if(mover.throwing) - return TRUE - return ..() - /obj/structure/bonfire/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/stack/rods) && !can_buckle && !grill) var/obj/item/stack/rods/R = W @@ -226,7 +220,7 @@ var/turf/open/O = loc if(O.air) var/datum/gas_mixture/loc_air = O.air - if(loc_air.get_moles(GAS_O2) > 13) + if(loc_air.get_moles(GAS_O2) > 3) return TRUE return FALSE diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm index f4859ffb1e..3c59deafdc 100644 --- a/code/modules/hydroponics/growninedible.dm +++ b/code/modules/hydroponics/growninedible.dm @@ -9,7 +9,7 @@ var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item. var/tastes = list("indescribable" = 1) //Stops runtimes. Grown are un-eatable anyways so if you do then its a bug -/obj/item/grown/Initialize(newloc, obj/item/seeds/new_seed) +/obj/item/grown/Initialize(mapload, obj/item/seeds/new_seed) . = ..() create_reagents(50, NONE, HARVEST_REAGENTS_VALUE) @@ -25,7 +25,7 @@ if(seed) for(var/datum/plant_gene/trait/T in seed.genes) - T.on_new(src, newloc) + T.on_new(src, loc) if(istype(src, seed.product)) // no adding reagents if it is just a trash item seed.prepare_result(src) diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index b032b84a77..26566d3f85 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -84,6 +84,12 @@ user.visible_message("[user] is scratching [user.p_their()] back as hard as [user.p_they()] can with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") return (BRUTELOSS) +/obj/item/cultivator/bone + name = "bone cultivator" + desc = "A handle and a few bones tied together to resemble a hoe. Should work for removing weeds." + icon = 'icons/obj/mining.dmi' + icon_state = "cultivator_bone" + /obj/item/hatchet name = "hatchet" desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood." @@ -103,7 +109,7 @@ hitsound = 'sound/weapons/bladeslice.ogg' sharpness = SHARP_EDGED -/obj/item/hatchet/Initialize() +/obj/item/hatchet/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 70, 100) @@ -112,6 +118,12 @@ playsound(src, 'sound/weapons/bladeslice.ogg', 50, 1, -1) return (BRUTELOSS) +/obj/item/hatchet/bone + name = "bone hatchet" + desc = "A primitive hatchet made out of mostly bone, with some sinew to keep it together. It just might do for cutting logs into planks." + icon = 'icons/obj/mining.dmi' + icon_state = "hatchet_bone" + /obj/item/scythe icon_state = "scythe0" lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi' @@ -131,7 +143,7 @@ hitsound = 'sound/weapons/bladeslice.ogg' var/swiping = FALSE -/obj/item/scythe/Initialize() +/obj/item/scythe/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 90, 105) @@ -179,7 +191,7 @@ amount_per_transfer_from_this = 10 possible_transfer_amounts = list(1,2,5,10,15,25,50) -/obj/item/reagent_containers/glass/bottle/nutrient/Initialize() +/obj/item/reagent_containers/glass/bottle/nutrient/Initialize(mapload) . = ..() pixel_x = rand(-5, 5) pixel_y = rand(-5, 5) diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index fa7decc437..a91e3ddfd8 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -31,7 +31,7 @@ var/self_sustaining = FALSE //If the tray generates nutrients and water on its own // Here lies irrigation. You won't be missed, because you were never used. -/obj/machinery/hydroponics/Initialize() +/obj/machinery/hydroponics/Initialize(mapload) //Here lies "nutrilevel", killed by ArcaneMusic 20??-2019. Finally, we strive for a better future. Please use "reagents" instead create_reagents(20) reagents.add_reagent(/datum/reagent/plantnutriment/eznutriment, 10) //Half filled nutrient trays for dirt trays to have more to grow with in prison/lavaland. diff --git a/code/modules/hydroponics/hydroponics_chemreact.dm b/code/modules/hydroponics/hydroponics_chemreact.dm index a4ef78a21f..640784aed8 100644 --- a/code/modules/hydroponics/hydroponics_chemreact.dm +++ b/code/modules/hydroponics/hydroponics_chemreact.dm @@ -12,21 +12,16 @@ /obj/machinery/hydroponics/proc/mutation_roll(mob/user) - switch(rand(100)) + switch(rand(1, 100)) if(91 to 100) adjustHealth(-10) visible_message("\The [myseed.plantname] starts to wilt and burn!") - return if(41 to 90) if(myseed && !self_sustaining) //Stability myseed.adjust_instability(5) - return if(21 to 40) visible_message("\The [myseed.plantname] appears unusually reactive...") - return if(11 to 20) mutateweed() - return if(1 to 10) mutatepest(user) - return diff --git a/code/modules/hydroponics/sample.dm b/code/modules/hydroponics/sample.dm index 7fb92e8fcd..ebcb100b32 100644 --- a/code/modules/hydroponics/sample.dm +++ b/code/modules/hydroponics/sample.dm @@ -5,7 +5,7 @@ yield = -1 var/sample_color = "#FFFFFF" -/obj/item/seeds/sample/Initialize() +/obj/item/seeds/sample/Initialize(mapload) . = ..() if(sample_color) var/mutable_appearance/filling = mutable_appearance(icon, "sample-filling") diff --git a/code/modules/instruments/instrument_data/_instrument_data.dm b/code/modules/instruments/instrument_data/_instrument_data.dm index 447bcdffb1..5d937f304f 100644 --- a/code/modules/instruments/instrument_data/_instrument_data.dm +++ b/code/modules/instruments/instrument_data/_instrument_data.dm @@ -55,14 +55,14 @@ id = "[type]" /datum/instrument/proc/Initialize() - if(CHECK_BITFIELD(instrument_flags, INSTRUMENT_LEGACY | INSTRUMENT_DO_NOT_AUTOSAMPLE)) + if(instrument_flags & (INSTRUMENT_LEGACY | INSTRUMENT_DO_NOT_AUTOSAMPLE)) return calculate_samples() /datum/instrument/proc/ready() - if(CHECK_BITFIELD(instrument_flags, INSTRUMENT_LEGACY)) + if((instrument_flags & INSTRUMENT_LEGACY)) return legacy_instrument_path && legacy_instrument_ext - else if(CHECK_BITFIELD(instrument_flags, INSTRUMENT_DO_NOT_AUTOSAMPLE)) + else if((instrument_flags & INSTRUMENT_DO_NOT_AUTOSAMPLE)) return length(samples) return (length(samples) >= 128) diff --git a/code/modules/instruments/instrument_data/hardcoded.dm b/code/modules/instruments/instrument_data/hardcoded.dm index 757fea08a8..5db7e8b3bb 100644 --- a/code/modules/instruments/instrument_data/hardcoded.dm +++ b/code/modules/instruments/instrument_data/hardcoded.dm @@ -7,11 +7,11 @@ instrument_flags = INSTRUMENT_LEGACY volume_multiplier = 1 //not as loud as synth'd -/datum/instrument/hardcoded/accordian - name = "Accordian" - id = "accordian" +/datum/instrument/hardcoded/accordion + name = "Accordion" + id = "accordion" legacy_instrument_ext = "mid" - legacy_instrument_path = "accordian" + legacy_instrument_path = "accordion" /datum/instrument/hardcoded/bikehorn name = "Bike Horn" diff --git a/code/modules/instruments/instrument_data/organ.dm b/code/modules/instruments/instrument_data/organ.dm index 25da740998..edf9de9485 100644 --- a/code/modules/instruments/instrument_data/organ.dm +++ b/code/modules/instruments/instrument_data/organ.dm @@ -19,8 +19,8 @@ "60"='sound/instruments/synthesis_samples/organ/crisis_hammond/c4.ogg', "72"='sound/instruments/synthesis_samples/organ/crisis_hammond/c5.ogg') -/datum/instrument/organ/crisis_accordian - name = "Crisis Accordian" +/datum/instrument/organ/crisis_accordion + name = "Crisis Accordion" id = "crack" real_samples = list("36"='sound/instruments/synthesis_samples/organ/crisis_accordian/c2.ogg', "48"='sound/instruments/synthesis_samples/organ/crisis_accordian/c3.ogg', @@ -34,8 +34,8 @@ "60"='sound/instruments/synthesis_samples/organ/crisis_harmonica/c4.ogg', "72"='sound/instruments/synthesis_samples/organ/crisis_harmonica/c5.ogg') -/datum/instrument/organ/crisis_tango_accordian - name = "Crisis Tango Accordian" +/datum/instrument/organ/crisis_tango_accordion + name = "Crisis Tango Accordion" id = "crtango" real_samples = list("36"='sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c2.ogg', "48"='sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c3.ogg', diff --git a/code/modules/instruments/instruments/item.dm b/code/modules/instruments/instruments/item.dm index 0141a4baee..888aac4d40 100644 --- a/code/modules/instruments/instruments/item.dm +++ b/code/modules/instruments/instruments/item.dm @@ -103,7 +103,7 @@ item_state = "synth" allowed_instrument_ids = "piano" -/obj/item/instrument/piano_synth/Initialize() +/obj/item/instrument/piano_synth/Initialize(mapload) . = ..() song.allowed_instrument_ids = get_allowed_instrument_ids() @@ -155,7 +155,7 @@ force = 0 attack_verb = list("played","jazzed","trumpeted","mourned","dooted","spooked") -/obj/item/instrument/trumpet/spectral/Initialize() +/obj/item/instrument/trumpet/spectral/Initialize(mapload) . = ..() AddComponent(/datum/component/spooky) @@ -178,7 +178,7 @@ force = 0 attack_verb = list("played","jazzed","saxxed","mourned","dooted","spooked") -/obj/item/instrument/saxophone/spectral/Initialize() +/obj/item/instrument/saxophone/spectral/Initialize(mapload) . = ..() AddComponent(/datum/component/spooky) @@ -201,7 +201,7 @@ force = 0 attack_verb = list("played","jazzed","tromboned","mourned","dooted","spooked") -/obj/item/instrument/trombone/spectral/Initialize() +/obj/item/instrument/trombone/spectral/Initialize(mapload) . = ..() AddComponent(/datum/component/spooky) diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index ac27b4a30e..4b6f76574f 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -36,7 +36,7 @@ hud_possible = list(DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD, DIAG_CIRCUIT_HUD) //diagnostic hud overlays max_integrity = 50 pass_flags = 0 - armor = list("melee" = 50, "bullet" = 70, "laser" = 70, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) + armor = list(MELEE = 50, BULLET = 70, LASER = 70, ENERGY = 100, BOMB = 10, BIO = 100, RAD = 100, FIRE = 0, ACID = 0) anchored = FALSE var/can_anchor = TRUE var/detail_color = COLOR_ASSEMBLY_BLACK @@ -96,7 +96,7 @@ if(D.check_access(access_card)) D.open() -/obj/item/electronic_assembly/Initialize() +/obj/item/electronic_assembly/Initialize(mapload) LAZYSET(custom_materials, /datum/material/iron, round((max_complexity + max_components) * 0.25) * SScircuit.cost_multiplier) .=..() START_PROCESSING(SScircuit, src) diff --git a/code/modules/integrated_electronics/core/detailer.dm b/code/modules/integrated_electronics/core/detailer.dm index 9720bccfe5..374f4f602a 100644 --- a/code/modules/integrated_electronics/core/detailer.dm +++ b/code/modules/integrated_electronics/core/detailer.dm @@ -26,11 +26,11 @@ "light blue" = COLOR_ASSEMBLY_LBLUE, "blue" = COLOR_ASSEMBLY_BLUE, "purple" = COLOR_ASSEMBLY_PURPLE, - "pink" = COLOR_ASSEMBLY_PINK, + "pink" = LIGHT_COLOR_PINK, "custom" = COLOR_ASSEMBLY_WHITE ) -/obj/item/integrated_electronics/detailer/Initialize() +/obj/item/integrated_electronics/detailer/Initialize(mapload) .=..() update_icon() diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm index 756706dcdf..7e667b3d09 100644 --- a/code/modules/integrated_electronics/core/integrated_circuit.dm +++ b/code/modules/integrated_electronics/core/integrated_circuit.dm @@ -81,7 +81,7 @@ a creative player the means to solve many problems. Circuits are held inside an else return user.canUseTopic(src, BE_CLOSE) -/obj/item/integrated_circuit/Initialize() +/obj/item/integrated_circuit/Initialize(mapload) displayed_name = name setup_io(inputs, /datum/integrated_io, inputs_default, IC_INPUT) setup_io(outputs, /datum/integrated_io, outputs_default, IC_OUTPUT) diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm index 5f6440bffb..879cfdf6b6 100644 --- a/code/modules/integrated_electronics/core/printer.dm +++ b/code/modules/integrated_electronics/core/printer.dm @@ -31,7 +31,7 @@ fast_clone = TRUE w_class = WEIGHT_CLASS_TINY -/obj/item/integrated_circuit_printer/Initialize() +/obj/item/integrated_circuit_printer/Initialize(mapload) . = ..() var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, list(/datum/material/iron), MINERAL_MATERIAL_AMOUNT * 25, TRUE, list(/obj/item/stack, /obj/item/integrated_circuit, /obj/item/electronic_assembly)) materials.precise_insertion = TRUE diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm index a7ee449be2..adc99f0ff5 100644 --- a/code/modules/integrated_electronics/passive/power.dm +++ b/code/modules/integrated_electronics/passive/power.dm @@ -101,7 +101,7 @@ var/multi = 1 var/lfwb =TRUE -/obj/item/integrated_circuit/passive/power/chemical_cell/Initialize() +/obj/item/integrated_circuit/passive/power/chemical_cell/Initialize(mapload) . = ..() create_reagents(volume, OPENCONTAINER) diff --git a/code/modules/integrated_electronics/subtypes/access.dm b/code/modules/integrated_electronics/subtypes/access.dm index 5e03ea1394..ddfed3753b 100644 --- a/code/modules/integrated_electronics/subtypes/access.dm +++ b/code/modules/integrated_electronics/subtypes/access.dm @@ -8,7 +8,6 @@ outputs = list( "registered name" = IC_PINTYPE_STRING, "assignment" = IC_PINTYPE_STRING, - "passkey" = IC_PINTYPE_STRING ) activators = list( "on read" = IC_PINTYPE_PULSE_OUT @@ -17,7 +16,6 @@ /obj/item/integrated_circuit/input/card_reader/attackby_react(obj/item/I, mob/living/user, intent) var/obj/item/card/id/card = I.GetID() var/list/access = I.GetAccess() - var/passkey = strtohex(XorEncrypt(json_encode(access), SScircuit.cipherkey)) if(assembly) assembly.access_card.access |= access @@ -33,8 +31,6 @@ else return FALSE - set_pin_data(IC_OUTPUT, 3, passkey) - push_data() activate_pin(1) return TRUE diff --git a/code/modules/integrated_electronics/subtypes/arithmetic.dm b/code/modules/integrated_electronics/subtypes/arithmetic.dm index e207f57ddb..a5b559585c 100644 --- a/code/modules/integrated_electronics/subtypes/arithmetic.dm +++ b/code/modules/integrated_electronics/subtypes/arithmetic.dm @@ -241,7 +241,7 @@ inputs = list() spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH -/obj/item/integrated_circuit/arithmetic/pi/Initialize() +/obj/item/integrated_circuit/arithmetic/pi/Initialize(mapload) . = ..() desc = "Not recommended for cooking. Outputs '[PI]' when it receives a pulse." diff --git a/code/modules/integrated_electronics/subtypes/atmospherics.dm b/code/modules/integrated_electronics/subtypes/atmospherics.dm index b3056d46cf..b2cb7b9c24 100644 --- a/code/modules/integrated_electronics/subtypes/atmospherics.dm +++ b/code/modules/integrated_electronics/subtypes/atmospherics.dm @@ -17,7 +17,7 @@ var/datum/gas_mixture/air_contents var/volume = 2 //Pretty small, I know -/obj/item/integrated_circuit/atmospherics/Initialize() +/obj/item/integrated_circuit/atmospherics/Initialize(mapload) air_contents = new(volume) return ..() @@ -57,7 +57,7 @@ var/target_pressure = PUMP_MAX_PRESSURE power_draw_per_use = 20 -/obj/item/integrated_circuit/atmospherics/pump/Initialize() +/obj/item/integrated_circuit/atmospherics/pump/Initialize(mapload) air_contents = new(volume) extended_desc += " Use negative pressure to move air from target to source. \ Note that only part of the gas is moved on each transfer, \ @@ -246,7 +246,7 @@ var/obj/machinery/atmospherics/components/unary/portables_connector/connector -/obj/item/integrated_circuit/atmospherics/connector/Initialize() +/obj/item/integrated_circuit/atmospherics/connector/Initialize(mapload) air_contents = new(volume) START_PROCESSING(SSobj, src) . = ..() @@ -398,7 +398,7 @@ contaminated_air.merge(removed) -/obj/item/integrated_circuit/atmospherics/pump/filter/Initialize() +/obj/item/integrated_circuit/atmospherics/pump/filter/Initialize(mapload) air_contents = new(volume) . = ..() extended_desc = "Remember to properly spell and capitalize the filtered gas name. \ @@ -485,7 +485,7 @@ volume = 3 //emergency tank sized var/broken = FALSE -/obj/item/integrated_circuit/atmospherics/tank/Initialize() +/obj/item/integrated_circuit/atmospherics/tank/Initialize(mapload) air_contents = new(volume) START_PROCESSING(SSobj, src) extended_desc = "Take care not to pressurize it above [round(TANK_FAILURE_PRESSURE)] kPa, or else it will break." @@ -611,7 +611,7 @@ var/temperature = 293.15 var/heater_coefficient = 0.1 -/obj/item/integrated_circuit/atmospherics/cooler/Initialize() +/obj/item/integrated_circuit/atmospherics/cooler/Initialize(mapload) air_contents = new(volume) START_PROCESSING(SSobj, src) . = ..() @@ -701,7 +701,7 @@ var/obj/item/tank/internals/current_tank -/obj/item/integrated_circuit/input/tank_slot/Initialize() +/obj/item/integrated_circuit/input/tank_slot/Initialize(mapload) START_PROCESSING(SSobj, src) . = ..() diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm index ebb91a894e..0c89e78564 100644 --- a/code/modules/integrated_electronics/subtypes/converters.dm +++ b/code/modules/integrated_electronics/subtypes/converters.dm @@ -151,7 +151,7 @@ var/number_of_pins = 8 var/max_string_length = 512 -/obj/item/integrated_circuit/converter/concatenator/Initialize() +/obj/item/integrated_circuit/converter/concatenator/Initialize(mapload) for(var/i = 1 to number_of_pins) inputs["input [i]"] = IC_PINTYPE_STRING . = ..() diff --git a/code/modules/integrated_electronics/subtypes/data_transfer.dm b/code/modules/integrated_electronics/subtypes/data_transfer.dm index 8db1db4e00..588d920fec 100644 --- a/code/modules/integrated_electronics/subtypes/data_transfer.dm +++ b/code/modules/integrated_electronics/subtypes/data_transfer.dm @@ -16,7 +16,7 @@ power_draw_per_use = 4 var/number_of_pins = 2 -/obj/item/integrated_circuit/transfer/multiplexer/Initialize() +/obj/item/integrated_circuit/transfer/multiplexer/Initialize(mapload) for(var/i = 1 to number_of_pins) inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. @@ -64,7 +64,7 @@ power_draw_per_use = 4 var/number_of_pins = 2 -/obj/item/integrated_circuit/transfer/demultiplexer/Initialize() +/obj/item/integrated_circuit/transfer/demultiplexer/Initialize(mapload) for(var/i = 1 to number_of_pins) outputs["output [i]"] = IC_PINTYPE_ANY complexity = number_of_pins @@ -113,7 +113,7 @@ power_draw_per_use = 4 var/number_of_pins = 2 -/obj/item/integrated_circuit/transfer/pulsedemultiplexer/Initialize() +/obj/item/integrated_circuit/transfer/pulsedemultiplexer/Initialize(mapload) for(var/i = 1 to number_of_pins) activators["output [i]"] = IC_PINTYPE_PULSE_OUT complexity = number_of_pins @@ -158,7 +158,7 @@ power_draw_per_use = 4 var/number_of_pins = 2 -/obj/item/integrated_circuit/transfer/pulsemultiplexer/Initialize() +/obj/item/integrated_circuit/transfer/pulsemultiplexer/Initialize(mapload) for(var/i = 1 to number_of_pins) inputs["input [i]"] = IC_PINTYPE_ANY for(var/i = 1 to number_of_pins) diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index f66931e253..547036f08a 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -652,7 +652,7 @@ var/datum/radio_frequency/radio_connection var/hearing_range = 1 -/obj/item/integrated_circuit/input/signaler/Initialize() +/obj/item/integrated_circuit/input/signaler/Initialize(mapload) . = ..() spawn(40) set_frequency(frequency) @@ -738,7 +738,7 @@ power_draw_per_use = 50 var/address -/obj/item/integrated_circuit/input/ntnet_packet/Initialize() +/obj/item/integrated_circuit/input/ntnet_packet/Initialize(mapload) . = ..() var/datum/component/ntnet_interface/net = LoadComponent(/datum/component/ntnet_interface) address = net.hardware_id @@ -786,7 +786,7 @@ power_draw_per_use = 50 var/address -/obj/item/integrated_circuit/input/ntnet_advanced/Initialize() +/obj/item/integrated_circuit/input/ntnet_advanced/Initialize(mapload) . = ..() var/datum/component/ntnet_interface/net = LoadComponent(/datum/component/ntnet_interface) address = net.hardware_id diff --git a/code/modules/integrated_electronics/subtypes/lists.dm b/code/modules/integrated_electronics/subtypes/lists.dm index a5c482c7de..5855959627 100644 --- a/code/modules/integrated_electronics/subtypes/lists.dm +++ b/code/modules/integrated_electronics/subtypes/lists.dm @@ -360,7 +360,7 @@ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH var/number_of_pins = 16 -/obj/item/integrated_circuit/lists/constructor/Initialize() +/obj/item/integrated_circuit/lists/constructor/Initialize(mapload) for(var/i = 1 to number_of_pins) inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. complexity = number_of_pins / 2 @@ -406,7 +406,7 @@ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH var/number_of_pins = 16 -/obj/item/integrated_circuit/lists/deconstructor/Initialize() +/obj/item/integrated_circuit/lists/deconstructor/Initialize(mapload) for(var/i = 1 to number_of_pins) outputs["output [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. complexity = number_of_pins / 2 diff --git a/code/modules/integrated_electronics/subtypes/memory.dm b/code/modules/integrated_electronics/subtypes/memory.dm index 34c36883d1..75ce4aefd7 100644 --- a/code/modules/integrated_electronics/subtypes/memory.dm +++ b/code/modules/integrated_electronics/subtypes/memory.dm @@ -11,7 +11,7 @@ power_draw_per_use = 1 var/number_of_pins = 1 -/obj/item/integrated_circuit/memory/Initialize() +/obj/item/integrated_circuit/memory/Initialize(mapload) for(var/i = 1 to number_of_pins) inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. outputs["output [i]"] = IC_PINTYPE_ANY diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm index 833b2963ad..e0b1afe72e 100644 --- a/code/modules/integrated_electronics/subtypes/output.dm +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -148,7 +148,7 @@ power_draw_per_use = 10 var/list/sounds = list() -/obj/item/integrated_circuit/output/sound/Initialize() +/obj/item/integrated_circuit/output/sound/Initialize(mapload) .= ..() extended_desc = list() extended_desc += "The first input pin determines which sound is used. The choices are; " @@ -230,7 +230,7 @@ desc = "Takes a sound name as an input, and will play said sound when pulsed. This circuit is often found in AI announcement systems." spawn_flags = IC_SPAWN_RESEARCH -/obj/item/integrated_circuit/output/sound/vox/Initialize() +/obj/item/integrated_circuit/output/sound/vox/Initialize(mapload) .= ..() sounds = GLOB.vox_sounds extended_desc = "The first input pin determines which sound is used. It uses the AI Vox Broadcast word list. So either experiment to find words that work, or ask the AI to help in figuring them out. The second pin determines the volume of sound that is played, and the third determines if the frequency of the sound will vary with each activation." diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index f69fa08aaf..bdd9e954db 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -6,7 +6,7 @@ cooldown_per_use = 10 var/volume = 0 -/obj/item/integrated_circuit/reagent/Initialize() +/obj/item/integrated_circuit/reagent/Initialize(mapload) . = ..() if(volume) create_reagents(volume) @@ -75,9 +75,9 @@ var/transfer_amount = 10 var/busy = FALSE -/obj/item/integrated_circuit/reagent/injector/Initialize() +/obj/item/integrated_circuit/reagent/injector/Initialize(mapload) . = ..() - ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) + reagents.reagents_holder_flags |= OPENCONTAINER /obj/item/integrated_circuit/reagent/injector/on_reagent_change(changetype) push_vol() @@ -271,9 +271,9 @@ activators = list("push ref" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH -/obj/item/integrated_circuit/reagent/storage/Initialize() +/obj/item/integrated_circuit/reagent/storage/Initialize(mapload) . = ..() - ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) + reagents.reagents_holder_flags |= OPENCONTAINER /obj/item/integrated_circuit/reagent/storage/do_work() set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) @@ -301,9 +301,9 @@ complexity = 8 spawn_flags = IC_SPAWN_RESEARCH -/obj/item/integrated_circuit/reagent/storage/cryo/Initialize() +/obj/item/integrated_circuit/reagent/storage/cryo/Initialize(mapload) . = ..() - ENABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) + reagents.reagents_holder_flags |= NO_REACT /obj/item/integrated_circuit/reagent/storage/grinder name = "reagent grinder" @@ -520,7 +520,7 @@ else power_draw_idle = 0 -/obj/item/integrated_circuit/reagent/storage/heater/Initialize() +/obj/item/integrated_circuit/reagent/storage/heater/Initialize(mapload) .=..() START_PROCESSING(SScircuit, src) @@ -572,9 +572,9 @@ var/smoke_radius = 5 var/notified = FALSE -/obj/item/integrated_circuit/reagent/smoke/Initialize() +/obj/item/integrated_circuit/reagent/smoke/Initialize(mapload) . = ..() - ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) + reagents.reagents_holder_flags |= OPENCONTAINER /obj/item/integrated_circuit/reagent/smoke/on_reagent_change(changetype) //reset warning only if we have reagents now @@ -630,9 +630,9 @@ power_draw_per_use = 15 var/busy = FALSE -/obj/item/integrated_circuit/reagent/extinguisher/Initialize() +/obj/item/integrated_circuit/reagent/extinguisher/Initialize(mapload) .=..() - ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) + reagents.reagents_holder_flags |= OPENCONTAINER set_pin_data(IC_OUTPUT,2, src) /obj/item/integrated_circuit/reagent/extinguisher/on_reagent_change(changetype) diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm index 5dc866c556..0f97ff8e08 100644 --- a/code/modules/integrated_electronics/subtypes/smart.dm +++ b/code/modules/integrated_electronics/subtypes/smart.dm @@ -87,7 +87,7 @@ power_draw_per_use = 80 var/obj/item/card/id/idc -/obj/item/integrated_circuit/smart/advanced_pathfinder/Initialize() +/obj/item/integrated_circuit/smart/advanced_pathfinder/Initialize(mapload) .=..() idc = new(src) @@ -97,7 +97,7 @@ return idc.access = assembly.access_card.access var/turf/a_loc = get_turf(assembly) - var/list/P = cir_get_path_to(assembly, locate(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2),a_loc.z), /turf/proc/Distance_cardinal, 0, 200, id=idc, exclude=get_turf(get_pin_data_as_type(IC_INPUT,3, /atom)), simulated_only = 0) + var/list/P = get_path_to(assembly, locate(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2),a_loc.z), 200, id=idc, exclude=get_turf(get_pin_data_as_type(IC_INPUT,3, /atom)), simulated_only = 0) if(!P) activate_pin(3) diff --git a/code/modules/integrated_electronics/subtypes/weaponized.dm b/code/modules/integrated_electronics/subtypes/weaponized.dm index 54b14cccbc..0458700f44 100644 --- a/code/modules/integrated_electronics/subtypes/weaponized.dm +++ b/code/modules/integrated_electronics/subtypes/weaponized.dm @@ -162,7 +162,7 @@ var/pre_attached_grenade_type demands_object_input = TRUE // You can put stuff in once the circuit is in assembly,passed down from additem and handled by attackby() -/obj/item/integrated_circuit/weaponized/grenade/Initialize() +/obj/item/integrated_circuit/weaponized/grenade/Initialize(mapload) . = ..() if(pre_attached_grenade_type) var/grenade = new pre_attached_grenade_type(src) diff --git a/code/modules/jobs/access.dm b/code/modules/jobs/access.dm index 06e1863bc9..35a89b46db 100644 --- a/code/modules/jobs/access.dm +++ b/code/modules/jobs/access.dm @@ -355,7 +355,7 @@ return list("Assistant", "Captain", "Head of Personnel", "Bartender", "Cook", "Botanist", "Quartermaster", "Cargo Technician", "Shaft Miner", "Clown", "Mime", "Janitor", "Curator", "Lawyer", "Chaplain", "Chief Engineer", "Station Engineer", "Atmospheric Technician", "Chief Medical Officer", "Medical Doctor", "Chemist", "Geneticist", "Virologist", "Paramedic", - "Research Director", "Scientist", "Roboticist", "Head of Security", "Warden", "Detective", "Security Officer") + "Research Director", "Scientist", "Roboticist", "Head of Security", "Warden", "Detective", "Security Officer", "Prisoner") /proc/get_all_job_icons() //For all existing HUD icons return get_all_jobs() + list("Prisoner") diff --git a/code/modules/jobs/job_report.dm b/code/modules/jobs/job_report.dm index 88c7f7ad19..016e34f525 100644 --- a/code/modules/jobs/job_report.dm +++ b/code/modules/jobs/job_report.dm @@ -17,6 +17,13 @@ ui = new(user, src, "TrackedPlaytime") ui.open() +/datum/job_report_menu/ui_data(mob/user) + var/list/data = list() + + data["exemptStatus"] = (owner.prefs?.db_flags & DB_FLAG_EXEMPT) + + return data + /datum/job_report_menu/ui_static_data() if (!CONFIG_GET(flag/use_exp_tracking)) return list("failReason" = JOB_REPORT_MENU_FAIL_REASON_TRACKING_DISABLED) @@ -42,8 +49,39 @@ data["livingTime"] = play_records[EXP_TYPE_LIVING] data["ghostTime"] = play_records[EXP_TYPE_GHOST] + data["adminTime"] = play_records[EXP_TYPE_ADMIN] ? play_records[EXP_TYPE_ADMIN] : 0 + + data["isAdmin"] = check_rights(R_ADMIN, show_msg = FALSE) return data +/datum/job_report_menu/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + + switch(action) + if("toggle_exempt") + if(!check_rights(R_ADMIN)) + message_admins("[ADMIN_LOOKUPFLW(usr)] attempted to toggle job playtime exempt status without admin rights.") + log_admin("[ADMIN_LOOKUPFLW(usr)] attempted to toggle job playtime exempt status without admin rights.") + to_chat(usr, span_danger("ERROR: Insufficient admin rights."), confidential = TRUE) + return TRUE + + var/datum/admins/viewer_admin_datum = GLOB.admin_datums[usr.ckey] + + if(!viewer_admin_datum) + message_admins("[ADMIN_LOOKUPFLW(usr)] attempted to toggle job playtime exempt status without admin datum for their ckey.") + log_admin("[ADMIN_LOOKUPFLW(usr)] attempted to toggle job playtime exempt status without admin datum for their ckey.") + to_chat(usr, span_danger("ERROR: Insufficient admin rights."), confidential = TRUE) + return TRUE + + if(QDELETED(owner)) + to_chat(usr, span_danger("ERROR: Client not found."), confidential = TRUE) + return TRUE + + viewer_admin_datum.toggle_exempt_status(owner) + return TRUE + #undef JOB_REPORT_MENU_FAIL_REASON_TRACKING_DISABLED #undef JOB_REPORT_MENU_FAIL_REASON_NO_RECORDS diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index 855e2ccbd7..9a05f97cc7 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -15,7 +15,7 @@ //Bitflags for the job var/flag = NONE //Deprecated var/department_flag = NONE //Deprecated -// var/auto_deadmin_role_flags = NONE + var/auto_deadmin_role_flags = NONE //Players will be allowed to spawn in as jobs that are set to "Station" var/faction = "None" @@ -63,8 +63,19 @@ var/list/mind_traits // Traits added to the mind of the mob assigned this job var/list/blacklisted_quirks //list of quirk typepaths blacklisted. +/// Should this job be allowed to be picked for the bureaucratic error event? + var/allow_bureaucratic_error = TRUE + + ///Is this job affected by weird spawns like the ones from station traits + var/random_spawns_possible = TRUE + + /// List of family heirlooms this job can get with the family heirloom quirk. List of types. + var/list/family_heirlooms + var/display_order = JOB_DISPLAY_ORDER_DEFAULT + var/bounty_types = CIV_JOB_BASIC + //If a job complies with dresscodes, loadout items will not be equipped instead of the job's outfit, instead placing the items into the player's backpack. var/dresscodecompliant = TRUE // How much threat this job is worth in dynamic. Is subtracted if the player's not an antag, added if they are. @@ -106,14 +117,16 @@ //Only override this proc //H is usually a human unless an /equip override transformed it -/datum/job/proc/after_spawn(mob/living/H, mob/M, latejoin = FALSE) +/datum/job/proc/after_spawn(mob/living/spawned, client/player_client, latejoin = FALSE) + SHOULD_CALL_PARENT(TRUE) + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_JOB_AFTER_SPAWN, src, spawned, player_client) //do actions on H but send messages to M as the key may not have been transferred_yet if(mind_traits) for(var/t in mind_traits) - ADD_TRAIT(H.mind, t, JOB_TRAIT) + ADD_TRAIT(spawned.mind, t, JOB_TRAIT) if(/datum/quirk/paraplegic in blacklisted_quirks) - H.regenerate_limbs() //if you can't be a paraplegic, attempt to regenerate limbs to stop amputated limb selection - H.set_resting(FALSE, TRUE) //they probably shouldn't be on the floor because they had no legs then suddenly had legs + spawned.regenerate_limbs() //if you can't be a paraplegic, attempt to regenerate limbs to stop amputated limb selection + spawned.set_resting(FALSE, TRUE) //they probably shouldn't be on the floor because they had no legs then suddenly had legs /datum/job/proc/announce(mob/living/carbon/human/H) if(head_announce) @@ -238,7 +251,7 @@ var/satchel = /obj/item/storage/backpack/satchel var/duffelbag = /obj/item/storage/backpack/duffelbag - var/pda_slot = SLOT_BELT + var/pda_slot = ITEM_SLOT_BELT /datum/outfit/job/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) var/preference_backpack = preference_source?.prefs.backbag @@ -320,3 +333,66 @@ if(CONFIG_GET(flag/security_has_maint_access)) return list(ACCESS_MAINT_TUNNELS) return list() + +/// Handles finding and picking a valid roundstart effect landmark spawn point, in case no uncommon different spawning events occur. +/datum/job/proc/get_default_roundstart_spawn_point() + for(var/obj/effect/landmark/start/spawn_point as anything in GLOB.start_landmarks_list) + if(spawn_point.name != title) + continue + . = spawn_point + if(spawn_point.used) //so we can revert to spawning them on top of eachother if something goes wrong + continue + spawn_point.used = TRUE + break + if(!.) + log_world("Couldn't find a round start spawn point for [title]") + +/// Finds a valid latejoin spawn point, checking for events and special conditions. +/datum/job/proc/get_latejoin_spawn_point() + if(length(GLOB.jobspawn_overrides[title])) //We're doing something special today. + return pick(GLOB.jobspawn_overrides[title]) + if(length(SSjob.latejoin_trackers)) + return pick(SSjob.latejoin_trackers) + return SSjob.get_last_resort_spawn_points() + +/// Returns an atom where the mob should spawn in. +/datum/job/proc/get_roundstart_spawn_point(var/mob/M) + if(random_spawns_possible) + if(HAS_TRAIT(SSstation, STATION_TRAIT_LATE_ARRIVALS)) + return get_latejoin_spawn_point() + if(HAS_TRAIT(SSstation, STATION_TRAIT_RANDOM_ARRIVALS)) + return get_safe_random_station_turf(typesof(/area/hallway)) || get_latejoin_spawn_point() + if(HAS_TRAIT(SSstation, STATION_TRAIT_HANGOVER)) + if(!M || (!HAS_TRAIT(M, TRAIT_TOXIC_ALCOHOL) && !(HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE) && prob(70)))) + var/obj/effect/landmark/start/hangover_spawn_point + for(var/obj/effect/landmark/start/hangover/hangover_landmark in GLOB.start_landmarks_list) + hangover_spawn_point = hangover_landmark + if(hangover_landmark.used) //so we can revert to spawning them on top of eachother if something goes wrong + continue + hangover_landmark.used = TRUE + break + return hangover_spawn_point || get_latejoin_spawn_point() + if(length(GLOB.jobspawn_overrides[title])) + return pick(GLOB.jobspawn_overrides[title]) + var/obj/effect/landmark/start/spawn_point = get_default_roundstart_spawn_point() + if(!spawn_point) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper + return get_latejoin_spawn_point() + return spawn_point + +/** + * Called after a successful roundstart spawn. + * Client is not yet in the mob. + * This happens after after_spawn() + */ +/datum/job/proc/after_roundstart_spawn(mob/living/spawning, client/player_client) + SHOULD_CALL_PARENT(TRUE) + + +/** + * Called after a successful latejoin spawn. + * Client is in the mob. + * This happens after after_spawn() + */ +/datum/job/proc/after_latejoin_spawn(mob/living/spawning) + SHOULD_CALL_PARENT(TRUE) + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_JOB_AFTER_LATEJOIN_SPAWN, src, spawning) diff --git a/code/modules/jobs/job_types/ai.dm b/code/modules/jobs/job_types/ai.dm index d0eb690e94..6bf2764ba8 100644 --- a/code/modules/jobs/job_types/ai.dm +++ b/code/modules/jobs/job_types/ai.dm @@ -1,7 +1,7 @@ /datum/job/ai title = "AI" flag = AI_JF -// auto_deadmin_role_flags = DEADMIN_POSITION_SILICON + auto_deadmin_role_flags = DEADMIN_POSITION_SILICON department_flag = ENGSEC faction = "Station" total_positions = 1 @@ -14,6 +14,8 @@ exp_type = EXP_TYPE_CREW exp_type_department = EXP_TYPE_SILICON display_order = JOB_DISPLAY_ORDER_AI + allow_bureaucratic_error = FALSE + random_spawns_possible = FALSE var/do_special_check = TRUE threat = 5 considered_combat_role = TRUE @@ -25,7 +27,7 @@ CRASH("dynamic preview is unsupported") . = H.AIize(latejoin,preference_source) -/datum/job/ai/after_spawn(mob/H, mob/M, latejoin) +/datum/job/ai/after_spawn(mob/H, client/C, latejoin) . = ..() if(latejoin) var/obj/structure/AIcore/latejoin_inactive/lateJoinCore @@ -39,8 +41,8 @@ H.forceMove(lateJoinCore.loc) qdel(lateJoinCore) var/mob/living/silicon/ai/AI = H - AI.apply_pref_name("ai", M.client) //If this runtimes oh well jobcode is fucked. - AI.set_core_display_icon(null, M.client) + AI.apply_pref_name("ai", C) //If this runtimes oh well jobcode is fucked. + AI.set_core_display_icon(null, C) //we may have been created after our borg if(SSticker.current_state == GAME_STATE_SETTING_UP) diff --git a/code/modules/jobs/job_types/assistant.dm b/code/modules/jobs/job_types/assistant.dm index db5390f323..6ec7d2c438 100644 --- a/code/modules/jobs/job_types/assistant.dm +++ b/code/modules/jobs/job_types/assistant.dm @@ -20,6 +20,10 @@ Assistant dresscodecompliant = FALSE always_can_respawn_as = TRUE threat = 0.2 + + family_heirlooms = list( + /obj/item/clothing/gloves/cut/family + ) /datum/job/assistant/get_access() if(CONFIG_GET(flag/assistants_have_maint_access) || !CONFIG_GET(flag/jobs_have_minimal_access)) //Config has assistant maint access set diff --git a/code/modules/jobs/job_types/atmospheric_technician.dm b/code/modules/jobs/job_types/atmospheric_technician.dm index bff56d1d16..551ac63d00 100644 --- a/code/modules/jobs/job_types/atmospheric_technician.dm +++ b/code/modules/jobs/job_types/atmospheric_technician.dm @@ -20,11 +20,18 @@ ACCESS_ENGINE_EQUIP, ACCESS_EMERGENCY_STORAGE, ACCESS_CONSTRUCTION, ACCESS_MINERAL_STOREROOM) paycheck = PAYCHECK_MEDIUM paycheck_department = ACCOUNT_ENG + bounty_types = CIV_JOB_ENG - starting_modifiers = list(/datum/skill_modifier/job/level/wiring/basic, /datum/skill_modifier/job/affinity/wiring) + starting_modifiers = list(/datum/skill_modifier/job/level/wiring, /datum/skill_modifier/job/affinity/wiring) display_order = JOB_DISPLAY_ORDER_ATMOSPHERIC_TECHNICIAN threat = 0.5 + + family_heirlooms = list( + /obj/item/lighter, + /obj/item/lighter/greyscale, + /obj/item/storage/box/matches + ) /datum/outfit/job/atmos name = "Atmospheric Technician" @@ -39,8 +46,8 @@ backpack = /obj/item/storage/backpack/industrial satchel = /obj/item/storage/backpack/satchel/eng duffelbag = /obj/item/storage/backpack/duffelbag/engineering - box = /obj/item/storage/box/engineer - pda_slot = SLOT_L_STORE + box = /obj/item/storage/box/survival/engineer + pda_slot = ITEM_SLOT_LPOCKET backpack_contents = list(/obj/item/modular_computer/tablet/preset/advanced=1) /datum/outfit/job/atmos/rig @@ -49,4 +56,4 @@ mask = /obj/item/clothing/mask/gas suit = /obj/item/clothing/suit/space/hardsuit/engine/atmos suit_store = /obj/item/tank/internals/oxygen - internals_slot = SLOT_S_STORE + internals_slot = ITEM_SLOT_SUITSTORE diff --git a/code/modules/jobs/job_types/bartender.dm b/code/modules/jobs/job_types/bartender.dm index 8290adbbd7..40a1b20cb1 100644 --- a/code/modules/jobs/job_types/bartender.dm +++ b/code/modules/jobs/job_types/bartender.dm @@ -17,8 +17,15 @@ minimal_access = list(ACCESS_BAR, ACCESS_MINERAL_STOREROOM) paycheck = PAYCHECK_EASY paycheck_department = ACCOUNT_SRV + bounty_types = CIV_JOB_DRINK display_order = JOB_DISPLAY_ORDER_BARTENDER threat = 0.5 + + family_heirlooms = list( + /obj/item/reagent_containers/rag, + /obj/item/clothing/head/that, + /obj/item/reagent_containers/food/drinks/shaker + ) /datum/outfit/job/bartender name = "Bartender" @@ -32,7 +39,7 @@ backpack_contents = list(/obj/item/storage/box/beanbag=1,/obj/item/book/granter/action/drink_fling=1) shoes = /obj/item/clothing/shoes/laceup -/datum/job/bartender/after_spawn(mob/living/H, mob/M, latejoin = FALSE) +/datum/job/bartender/after_spawn(mob/living/H, client/C, latejoin = FALSE) . = ..() var/datum/action/innate/drink_fling/D = new D.Grant(H) diff --git a/code/modules/jobs/job_types/botanist.dm b/code/modules/jobs/job_types/botanist.dm index 4c91f87791..7a43837cf4 100644 --- a/code/modules/jobs/job_types/botanist.dm +++ b/code/modules/jobs/job_types/botanist.dm @@ -16,9 +16,16 @@ minimal_access = list(ACCESS_HYDROPONICS, ACCESS_MORGUE, ACCESS_MINERAL_STOREROOM) paycheck = PAYCHECK_EASY paycheck_department = ACCOUNT_SRV + bounty_types = CIV_JOB_GROW display_order = JOB_DISPLAY_ORDER_BOTANIST threat = 1.5 // lol powergame + family_heirlooms = list( + /obj/item/cultivator, + /obj/item/reagent_containers/glass/bucket, // Watering cans don't exist yet + /obj/item/toy/plush/beeplushie, + ) + /datum/outfit/job/botanist name = "Botanist" jobtype = /datum/job/hydro diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm index 4806bf5546..65811d40a0 100644 --- a/code/modules/jobs/job_types/captain.dm +++ b/code/modules/jobs/job_types/captain.dm @@ -1,7 +1,7 @@ /datum/job/captain title = "Captain" flag = CAPTAIN -// auto_deadmin_role_flags = DEADMIN_POSITION_HEAD|DEADMIN_POSITION_SECURITY //:eyes: + auto_deadmin_role_flags = DEADMIN_POSITION_HEAD|DEADMIN_POSITION_SECURITY //:eyes: department_head = list("CentCom") department_flag = ENGSEC faction = "Station" @@ -32,6 +32,11 @@ blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity) threat = 5 + + family_heirlooms = list( + /obj/item/reagent_containers/food/drinks/flask/gold, + /obj/item/toy/figure/captain + ) /datum/job/captain/get_access() return get_all_accesses() diff --git a/code/modules/jobs/job_types/cargo_technician.dm b/code/modules/jobs/job_types/cargo_technician.dm index 1f87a5265d..1188669db5 100644 --- a/code/modules/jobs/job_types/cargo_technician.dm +++ b/code/modules/jobs/job_types/cargo_technician.dm @@ -19,7 +19,12 @@ paycheck_department = ACCOUNT_CAR display_order = JOB_DISPLAY_ORDER_CARGO_TECHNICIAN + bounty_types = CIV_JOB_RANDOM threat = 0.2 + + family_heirlooms = list( + /obj/item/clipboard + ) /datum/outfit/job/cargo_tech name = "Cargo Technician" diff --git a/code/modules/jobs/job_types/chaplain.dm b/code/modules/jobs/job_types/chaplain.dm index a9e891a303..e7d602bd22 100644 --- a/code/modules/jobs/job_types/chaplain.dm +++ b/code/modules/jobs/job_types/chaplain.dm @@ -19,9 +19,14 @@ display_order = JOB_DISPLAY_ORDER_CHAPLAIN threat = 0.5 + + family_heirlooms = list( + /obj/item/toy/windupToolbox, + /obj/item/reagent_containers/food/drinks/bottle/holywater + ) -/datum/job/chaplain/after_spawn(mob/living/H, mob/M) +/datum/job/chaplain/after_spawn(mob/living/H, client/C) . = ..() if(H.mind) H.mind.isholy = TRUE @@ -34,19 +39,19 @@ B.icon_state = GLOB.bible_icon_state B.item_state = GLOB.bible_item_state to_chat(H, "There is already an established religion onboard the station. You are an acolyte of [GLOB.deity]. Defer to the Chaplain.") - H.equip_to_slot_or_del(B, SLOT_IN_BACKPACK) + H.equip_to_slot_or_del(B, ITEM_SLOT_BACKPACK) var/nrt = GLOB.holy_weapon_type || /obj/item/nullrod var/obj/item/nullrod/N = new nrt(H) H.put_in_hands(N) return var/new_religion = DEFAULT_RELIGION - if(M.client && M.client.prefs.custom_names["religion"]) - new_religion = M.client.prefs.custom_names["religion"] + if(C && C.prefs.custom_names["religion"]) + new_religion = C.prefs.custom_names["religion"] var/new_deity = DEFAULT_DEITY - if(M.client && M.client.prefs.custom_names["deity"]) - new_deity = M.client.prefs.custom_names["deity"] + if(C && C.prefs.custom_names["deity"]) + new_deity = C.prefs.custom_names["deity"] B.deity_name = new_deity @@ -108,7 +113,7 @@ GLOB.bible_name = B.name GLOB.deity = B.deity_name - H.equip_to_slot_or_del(B, SLOT_IN_BACKPACK) + H.equip_to_slot_or_del(B, ITEM_SLOT_BACKPACK) SSblackbox.record_feedback("text", "religion_name", 1, "[new_religion]", 1) SSblackbox.record_feedback("text", "religion_deity", 1, "[new_deity]", 1) diff --git a/code/modules/jobs/job_types/chemist.dm b/code/modules/jobs/job_types/chemist.dm index 6d4204d041..9f830ba43c 100644 --- a/code/modules/jobs/job_types/chemist.dm +++ b/code/modules/jobs/job_types/chemist.dm @@ -18,11 +18,17 @@ minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_CHEMISTRY, ACCESS_MINERAL_STOREROOM) paycheck = PAYCHECK_MEDIUM paycheck_department = ACCOUNT_MED + bounty_types = CIV_JOB_CHEM display_order = JOB_DISPLAY_ORDER_CHEMIST threat = 1.5 starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery) + + family_heirlooms = list( + /obj/item/book/manual/wiki/chemistry, + /obj/item/fermichem/pHbooklet + ) /datum/outfit/job/chemist name = "Chemist" diff --git a/code/modules/jobs/job_types/chief_engineer.dm b/code/modules/jobs/job_types/chief_engineer.dm index 902be0bdc8..2949758d8a 100644 --- a/code/modules/jobs/job_types/chief_engineer.dm +++ b/code/modules/jobs/job_types/chief_engineer.dm @@ -1,7 +1,7 @@ /datum/job/chief_engineer title = "Chief Engineer" flag = CHIEF -// auto_deadmin_role_flags = DEADMIN_POSITION_HEAD + auto_deadmin_role_flags = DEADMIN_POSITION_HEAD department_head = list("Captain") department_flag = ENGSEC head_announce = list(RADIO_CHANNEL_ENGINEERING) @@ -30,12 +30,22 @@ ACCESS_CE, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_TCOMSAT, ACCESS_MINERAL_STOREROOM) paycheck = PAYCHECK_COMMAND paycheck_department = ACCOUNT_ENG + bounty_types = CIV_JOB_ENG - starting_modifiers = list(/datum/skill_modifier/job/level/wiring, /datum/skill_modifier/job/affinity/wiring) + starting_modifiers = list(/datum/skill_modifier/job/level/wiring/expert, /datum/skill_modifier/job/affinity/wiring) display_order = JOB_DISPLAY_ORDER_CHIEF_ENGINEER blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/paraplegic, /datum/quirk/insanity) threat = 2 + + family_heirlooms = list( + /obj/item/clothing/head/hardhat, + /obj/item/screwdriver/brass/family, + /obj/item/wrench/brass/family, + /obj/item/weldingtool/mini, // No brass family variant + /obj/item/crowbar/brass/family, + /obj/item/wirecutters/brass/family + ) /datum/outfit/job/ce name = "Chief Engineer" @@ -54,8 +64,8 @@ backpack = /obj/item/storage/backpack/industrial satchel = /obj/item/storage/backpack/satchel/eng duffelbag = /obj/item/storage/backpack/duffelbag/engineering - box = /obj/item/storage/box/engineer - pda_slot = SLOT_L_STORE + box = /obj/item/storage/box/survival/engineer + pda_slot = ITEM_SLOT_LPOCKET chameleon_extras = /obj/item/stamp/ce /datum/outfit/job/ce/rig @@ -68,4 +78,4 @@ glasses = /obj/item/clothing/glasses/meson/engine gloves = /obj/item/clothing/gloves/color/yellow head = null - internals_slot = SLOT_S_STORE + internals_slot = ITEM_SLOT_SUITSTORE diff --git a/code/modules/jobs/job_types/chief_medical_officer.dm b/code/modules/jobs/job_types/chief_medical_officer.dm index bb5fc68809..f5170fc745 100644 --- a/code/modules/jobs/job_types/chief_medical_officer.dm +++ b/code/modules/jobs/job_types/chief_medical_officer.dm @@ -3,7 +3,7 @@ flag = CMO_JF department_head = list("Captain") department_flag = MEDSCI -// auto_deadmin_role_flags = DEADMIN_POSITION_HEAD + auto_deadmin_role_flags = DEADMIN_POSITION_HEAD head_announce = list(RADIO_CHANNEL_MEDICAL) faction = "Station" total_positions = 1 @@ -28,12 +28,22 @@ ACCESS_KEYCARD_AUTH, ACCESS_SEC_DOORS, ACCESS_MAINT_TUNNELS) paycheck = PAYCHECK_COMMAND paycheck_department = ACCOUNT_MED + bounty_types = CIV_JOB_MED display_order = JOB_DISPLAY_ORDER_CHIEF_MEDICAL_OFFICER blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity) threat = 2 starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery) + + family_heirlooms = list( + /obj/item/storage/firstaid/ancient/heirloom, + /obj/item/scalpel, + /obj/item/hemostat, + /obj/item/circular_saw, + /obj/item/retractor, + /obj/item/cautery + ) /datum/outfit/job/cmo name = "Chief Medical Officer" diff --git a/code/modules/jobs/job_types/clown.dm b/code/modules/jobs/job_types/clown.dm index dc2f60434c..5631ce4624 100644 --- a/code/modules/jobs/job_types/clown.dm +++ b/code/modules/jobs/job_types/clown.dm @@ -21,6 +21,10 @@ display_order = JOB_DISPLAY_ORDER_CLOWN threat = 0 // honk + + family_heirlooms = list( + /obj/item/bikehorn/golden + ) /datum/outfit/job/clown name = "Clown" @@ -49,6 +53,11 @@ chameleon_extras = /obj/item/stamp/clown +/datum/outfit/job/clown/pre_equip(mob/living/carbon/human/H, visualsOnly) + . = ..() + if(HAS_TRAIT(SSstation, STATION_TRAIT_BANANIUM_SHIPMENTS)) + backpack_contents[/obj/item/stack/sheet/mineral/bananium] = 5 + /datum/outfit/job/clown/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) ..() if(visualsOnly) diff --git a/code/modules/jobs/job_types/cook.dm b/code/modules/jobs/job_types/cook.dm index 666ee8f036..9947c27ba9 100644 --- a/code/modules/jobs/job_types/cook.dm +++ b/code/modules/jobs/job_types/cook.dm @@ -17,10 +17,17 @@ minimal_access = list(ACCESS_KITCHEN, ACCESS_MORGUE, ACCESS_MINERAL_STOREROOM) paycheck = PAYCHECK_EASY paycheck_department = ACCOUNT_SRV + bounty_types = CIV_JOB_CHEF display_order = JOB_DISPLAY_ORDER_COOK threat = 0.2 + family_heirlooms = list( + /obj/item/reagent_containers/food/condiment/saltshaker, + /obj/item/kitchen/rollingpin, + /obj/item/clothing/head/chefhat + ) + /datum/outfit/job/cook name = "Cook" jobtype = /datum/job/cook diff --git a/code/modules/jobs/job_types/curator.dm b/code/modules/jobs/job_types/curator.dm index 254fc15bd4..e6e9394109 100644 --- a/code/modules/jobs/job_types/curator.dm +++ b/code/modules/jobs/job_types/curator.dm @@ -19,6 +19,11 @@ display_order = JOB_DISPLAY_ORDER_CURATOR threat = 0.3 + + family_heirlooms = list( + /obj/item/pen/fountain, + /obj/item/storage/dice + ) /datum/outfit/job/curator name = "Curator" diff --git a/code/modules/jobs/job_types/cyborg.dm b/code/modules/jobs/job_types/cyborg.dm index 761882894f..280d7616c2 100644 --- a/code/modules/jobs/job_types/cyborg.dm +++ b/code/modules/jobs/job_types/cyborg.dm @@ -1,7 +1,7 @@ /datum/job/cyborg title = "Cyborg" flag = CYBORG -// auto_deadmin_role_flags = DEADMIN_POSITION_SILICON + auto_deadmin_role_flags = DEADMIN_POSITION_SILICON department_flag = ENGSEC faction = "Station" total_positions = 0 @@ -12,7 +12,7 @@ exp_requirements = 120 exp_type = EXP_TYPE_CREW considered_combat_role = TRUE - + random_spawns_possible = FALSE starting_modifiers = list(/datum/skill_modifier/job/level/wiring/basic) display_order = JOB_DISPLAY_ORDER_CYBORG @@ -22,8 +22,11 @@ CRASH("dynamic preview is unsupported") return H.Robotize(FALSE, latejoin) -/datum/job/cyborg/after_spawn(mob/living/silicon/robot/R, mob/M) - R.updatename(M.client) +/datum/job/cyborg/after_spawn(mob/living/silicon/robot/R, client/player_client) + . = ..() + if(!istype(R)) + return + R.updatename(player_client) R.gender = NEUTER /datum/job/cyborg/radio_help_message(mob/M) diff --git a/code/modules/jobs/job_types/detective.dm b/code/modules/jobs/job_types/detective.dm index c704326879..2330e93147 100644 --- a/code/modules/jobs/job_types/detective.dm +++ b/code/modules/jobs/job_types/detective.dm @@ -1,7 +1,7 @@ /datum/job/detective title = "Detective" flag = DETECTIVE -// auto_deadmin_role_flags = DEADMIN_POSITION_SECURITY + auto_deadmin_role_flags = DEADMIN_POSITION_SECURITY department_head = list("Head of Security") department_flag = ENGSEC faction = "Station" @@ -27,6 +27,10 @@ display_order = JOB_DISPLAY_ORDER_DETECTIVE blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/nonviolent, /datum/quirk/paraplegic, /datum/quirk/monophobia) threat = 1 + + family_heirlooms = list( + /obj/item/reagent_containers/food/drinks/flask/det + ) /datum/outfit/job/detective name = "Detective" diff --git a/code/modules/jobs/job_types/geneticist.dm b/code/modules/jobs/job_types/geneticist.dm index 5ff1bebfbf..2529eaa024 100644 --- a/code/modules/jobs/job_types/geneticist.dm +++ b/code/modules/jobs/job_types/geneticist.dm @@ -18,11 +18,16 @@ minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_RESEARCH, ACCESS_MINERAL_STOREROOM) paycheck = PAYCHECK_MEDIUM paycheck_department = ACCOUNT_MED + bounty_types = CIV_JOB_SCI display_order = JOB_DISPLAY_ORDER_GENETICIST threat = 1.5 starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery) + + family_heirlooms = list( + /obj/item/clothing/under/shorts/purple + ) /datum/outfit/job/geneticist name = "Geneticist" diff --git a/code/modules/jobs/job_types/head_of_personnel.dm b/code/modules/jobs/job_types/head_of_personnel.dm index 07c1a12ced..6371aaaa9f 100644 --- a/code/modules/jobs/job_types/head_of_personnel.dm +++ b/code/modules/jobs/job_types/head_of_personnel.dm @@ -1,7 +1,7 @@ /datum/job/hop title = "Head of Personnel" flag = HOP -// auto_deadmin_role_flags = DEADMIN_POSITION_HEAD + auto_deadmin_role_flags = DEADMIN_POSITION_HEAD department_head = list("Captain") department_flag = CIVILIAN head_announce = list(RADIO_CHANNEL_SERVICE) @@ -33,11 +33,16 @@ ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY) paycheck = PAYCHECK_COMMAND paycheck_department = ACCOUNT_SRV + bounty_types = CIV_JOB_RANDOM display_order = JOB_DISPLAY_ORDER_HEAD_OF_PERSONNEL blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/prosopagnosia, /datum/quirk/insanity) threat = 2 + + family_heirlooms = list( + /obj/item/reagent_containers/food/drinks/trophy/silver_cup + ) /datum/outfit/job/hop diff --git a/code/modules/jobs/job_types/head_of_security.dm b/code/modules/jobs/job_types/head_of_security.dm index c772a8acae..15fd567a96 100644 --- a/code/modules/jobs/job_types/head_of_security.dm +++ b/code/modules/jobs/job_types/head_of_security.dm @@ -1,7 +1,7 @@ /datum/job/hos title = "Head of Security" flag = HOS -// auto_deadmin_role_flags = DEADMIN_POSITION_HEAD|DEADMIN_POSITION_SECURITY + auto_deadmin_role_flags = DEADMIN_POSITION_HEAD|DEADMIN_POSITION_SECURITY department_head = list("Captain") department_flag = ENGSEC head_announce = list(RADIO_CHANNEL_SECURITY) @@ -32,11 +32,17 @@ ACCESS_HEADS, ACCESS_HOS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM) paycheck = PAYCHECK_COMMAND paycheck_department = ACCOUNT_SEC + bounty_types = CIV_JOB_SEC + display_order = JOB_DISPLAY_ORDER_HEAD_OF_SECURITY blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/nonviolent, /datum/quirk/paraplegic, /datum/quirk/blindness, /datum/quirk/monophobia, /datum/quirk/insanity) threat = 3 + family_heirlooms = list( + /obj/item/book/manual/wiki/security_space_law + ) + /datum/outfit/job/hos name = "Head of Security" jobtype = /datum/job/hos @@ -45,7 +51,7 @@ belt = /obj/item/pda/heads/hos ears = /obj/item/radio/headset/heads/hos/alt uniform = /obj/item/clothing/under/rank/security/head_of_security - shoes = /obj/item/clothing/shoes/jackboots + shoes = /obj/item/clothing/shoes/jackboots/sec suit = /obj/item/clothing/suit/armor/hos/trenchcoat gloves = /obj/item/clothing/gloves/color/black head = /obj/item/clothing/head/HoS/beret @@ -58,7 +64,7 @@ backpack = /obj/item/storage/backpack/security satchel = /obj/item/storage/backpack/satchel/sec duffelbag = /obj/item/storage/backpack/duffelbag/sec - box = /obj/item/storage/box/security + box = /obj/item/storage/box/survival/security implants = list(/obj/item/implant/mindshield) diff --git a/code/modules/jobs/job_types/janitor.dm b/code/modules/jobs/job_types/janitor.dm index c62c2e5b26..59c6997398 100644 --- a/code/modules/jobs/job_types/janitor.dm +++ b/code/modules/jobs/job_types/janitor.dm @@ -19,6 +19,13 @@ display_order = JOB_DISPLAY_ORDER_JANITOR threat = 0.2 + + family_heirlooms = list( + /obj/item/mop, + /obj/item/clothing/suit/caution, + /obj/item/reagent_containers/glass/bucket, + /obj/item/soap + ) /datum/outfit/job/janitor name = "Janitor" diff --git a/code/modules/jobs/job_types/lawyer.dm b/code/modules/jobs/job_types/lawyer.dm index 17c376a5de..4105bd4e6e 100644 --- a/code/modules/jobs/job_types/lawyer.dm +++ b/code/modules/jobs/job_types/lawyer.dm @@ -22,6 +22,11 @@ display_order = JOB_DISPLAY_ORDER_LAWYER threat = 0.3 + + family_heirlooms = list( + /obj/item/gavelhammer, + /obj/item/book/manual/wiki/security_space_law + ) /datum/outfit/job/lawyer name = "Lawyer" diff --git a/code/modules/jobs/job_types/medical_doctor.dm b/code/modules/jobs/job_types/medical_doctor.dm index d6a763acfe..b0a0375517 100644 --- a/code/modules/jobs/job_types/medical_doctor.dm +++ b/code/modules/jobs/job_types/medical_doctor.dm @@ -16,11 +16,21 @@ minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM) paycheck = PAYCHECK_MEDIUM paycheck_department = ACCOUNT_MED + bounty_types = CIV_JOB_MED display_order = JOB_DISPLAY_ORDER_MEDICAL_DOCTOR threat = 0.5 starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery) + + family_heirlooms = list( + /obj/item/storage/firstaid/ancient/heirloom, + /obj/item/scalpel, + /obj/item/hemostat, + /obj/item/circular_saw, + /obj/item/retractor, + /obj/item/cautery + ) /datum/outfit/job/doctor name = "Medical Doctor" diff --git a/code/modules/jobs/job_types/mime.dm b/code/modules/jobs/job_types/mime.dm index e00b3a1e29..84d6bcb1a7 100644 --- a/code/modules/jobs/job_types/mime.dm +++ b/code/modules/jobs/job_types/mime.dm @@ -20,10 +20,14 @@ display_order = JOB_DISPLAY_ORDER_MIME threat = 0 + + family_heirlooms = list( + /obj/item/reagent_containers/food/snacks/baguette + ) -/datum/job/mime/after_spawn(mob/living/carbon/human/H, mob/M) +/datum/job/mime/after_spawn(mob/living/carbon/human/H, client/C) . = ..() - H.apply_pref_name("mime", M.client) + H.apply_pref_name("mime", C) /datum/outfit/job/mime name = "Mime" diff --git a/code/modules/jobs/job_types/paramedic.dm b/code/modules/jobs/job_types/paramedic.dm index 331bad9bfe..73f6c5da5e 100644 --- a/code/modules/jobs/job_types/paramedic.dm +++ b/code/modules/jobs/job_types/paramedic.dm @@ -16,12 +16,17 @@ minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM, ACCESS_MAINT_TUNNELS) paycheck = PAYCHECK_MEDIUM paycheck_department = ACCOUNT_MED + bounty_types = CIV_JOB_MED display_order = JOB_DISPLAY_ORDER_PARAMEDIC threat = 0.5 starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery) + + family_heirlooms = list( + /obj/item/storage/firstaid/ancient/heirloom + ) /datum/outfit/job/paramedic name = "Paramedic" @@ -41,7 +46,7 @@ r_pocket = /obj/item/pinpointer/crew l_pocket = /obj/item/pda/medical backpack_contents = list(/obj/item/roller=1) - pda_slot = SLOT_L_STORE + pda_slot = ITEM_SLOT_LPOCKET backpack = /obj/item/storage/backpack/medic satchel = /obj/item/storage/backpack/satchel/med diff --git a/code/modules/jobs/job_types/prisoner.dm b/code/modules/jobs/job_types/prisoner.dm new file mode 100644 index 0000000000..20a2f463f5 --- /dev/null +++ b/code/modules/jobs/job_types/prisoner.dm @@ -0,0 +1,42 @@ +/datum/job/prisoner + title = "Prisoner" + flag = PRISONER + department_head = list("The Security Team") + department_flag = CIVILIAN + faction = "Station" + total_positions = 0 + spawn_positions = 0 + supervisors = "the security team" + random_spawns_possible = FALSE + + outfit = /datum/outfit/job/prisoner + plasma_outfit = /datum/outfit/plasmaman/prisoner + + display_order = JOB_DISPLAY_ORDER_PRISONER + + family_heirlooms = list( + /obj/item/pen/blue + ) + +/datum/job/prisoner/get_latejoin_spawn_point() + return get_roundstart_spawn_point() + +/datum/job/prisoner/after_spawn(mob/living/carbon/human/H, client/C) + . = ..() + var/list/policies = CONFIG_GET(keyed_list/policy) + var/policy = policies[POLICYCONFIG_JOB_PRISONER] + if(policy) + var/mob/found = (H?.client && H) + to_chat(found, "
    !!READ THIS!!
    The following is server-specific policy configuration and overrides anything said above if conflicting.") + to_chat(found, "

    ") + to_chat(found, "[policy]") + +/datum/outfit/job/prisoner + name = "Prisoner" + jobtype = /datum/job/prisoner + + uniform = /obj/item/clothing/under/rank/prisoner + shoes = /obj/item/clothing/shoes/sneakers/orange + id = /obj/item/card/id/prisoner + ears = /obj/item/radio/headset/headset_prisoner + belt = null diff --git a/code/modules/jobs/job_types/quartermaster.dm b/code/modules/jobs/job_types/quartermaster.dm index ff811d30d1..dd79768282 100644 --- a/code/modules/jobs/job_types/quartermaster.dm +++ b/code/modules/jobs/job_types/quartermaster.dm @@ -4,7 +4,7 @@ department_head = list("Captain") department_flag = CIVILIAN head_announce = list(RADIO_CHANNEL_SUPPLY) -// auto_deadmin_role_flags = DEADMIN_POSITION_HEAD + auto_deadmin_role_flags = DEADMIN_POSITION_HEAD faction = "Station" total_positions = 1 spawn_positions = 1 @@ -27,10 +27,16 @@ ACCESS_SEC_DOORS, ACCESS_HEADS) paycheck = PAYCHECK_HARD //They can already buy stuff using cargo budget, don't give em a command-level paycheck. //alright i'll agree to that -qweq paycheck_department = ACCOUNT_CAR + bounty_types = CIV_JOB_RANDOM display_order = JOB_DISPLAY_ORDER_QUARTERMASTER blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity) threat = 0.5 + + family_heirlooms = list( + /obj/item/stamp, + /obj/item/stamp/denied + ) /datum/outfit/job/quartermaster name = "Quartermaster" diff --git a/code/modules/jobs/job_types/research_director.dm b/code/modules/jobs/job_types/research_director.dm index 6c2cb94d13..606c34af5e 100644 --- a/code/modules/jobs/job_types/research_director.dm +++ b/code/modules/jobs/job_types/research_director.dm @@ -1,7 +1,7 @@ /datum/job/rd title = "Research Director" flag = RD_JF -// auto_deadmin_role_flags = DEADMIN_POSITION_HEAD + auto_deadmin_role_flags = DEADMIN_POSITION_HEAD department_head = list("Captain") department_flag = MEDSCI head_announce = list(RADIO_CHANNEL_SCIENCE) @@ -32,10 +32,16 @@ ACCESS_TECH_STORAGE, ACCESS_MINISAT, ACCESS_MAINT_TUNNELS, ACCESS_NETWORK) paycheck = PAYCHECK_COMMAND paycheck_department = ACCOUNT_SCI + bounty_types = CIV_JOB_SCI display_order = JOB_DISPLAY_ORDER_RESEARCH_DIRECTOR + starting_modifiers = list(/datum/skill_modifier/job/level/wiring) blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity) threat = 5 + + family_heirlooms = list( + /obj/item/toy/plush/slimeplushie + ) /datum/outfit/job/rd name = "Research Director" @@ -63,4 +69,4 @@ mask = /obj/item/clothing/mask/breath suit = /obj/item/clothing/suit/space/hardsuit/rd suit_store = /obj/item/tank/internals/oxygen - internals_slot = SLOT_S_STORE + internals_slot = ITEM_SLOT_SUITSTORE diff --git a/code/modules/jobs/job_types/roboticist.dm b/code/modules/jobs/job_types/roboticist.dm index b44d536cd2..0e48467d91 100644 --- a/code/modules/jobs/job_types/roboticist.dm +++ b/code/modules/jobs/job_types/roboticist.dm @@ -18,11 +18,16 @@ minimal_access = list(ACCESS_ROBOTICS, ACCESS_TECH_STORAGE, ACCESS_MORGUE, ACCESS_RESEARCH, ACCESS_MINERAL_STOREROOM) paycheck = PAYCHECK_MEDIUM paycheck_department = ACCOUNT_SCI + bounty_types = CIV_JOB_ROBO starting_modifiers = list(/datum/skill_modifier/job/level/wiring, /datum/skill_modifier/job/affinity/wiring) display_order = JOB_DISPLAY_ORDER_ROBOTICIST threat = 1 + + family_heirlooms = list( + /obj/item/toy/figure/borg + ) /datum/outfit/job/roboticist name = "Roboticist" @@ -37,4 +42,4 @@ backpack = /obj/item/storage/backpack/science satchel = /obj/item/storage/backpack/satchel/tox - pda_slot = SLOT_L_STORE + pda_slot = ITEM_SLOT_LPOCKET diff --git a/code/modules/jobs/job_types/scientist.dm b/code/modules/jobs/job_types/scientist.dm index a851b333fe..4bdbe6833b 100644 --- a/code/modules/jobs/job_types/scientist.dm +++ b/code/modules/jobs/job_types/scientist.dm @@ -18,9 +18,14 @@ minimal_access = list(ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_RESEARCH, ACCESS_XENOBIOLOGY, ACCESS_MINERAL_STOREROOM) paycheck = PAYCHECK_MEDIUM paycheck_department = ACCOUNT_SCI - + bounty_types = CIV_JOB_SCI + starting_modifiers = list(/datum/skill_modifier/job/level/wiring/basic) display_order = JOB_DISPLAY_ORDER_SCIENTIST threat = 1.2 + + family_heirlooms = list( + /obj/item/toy/plush/slimeplushie + ) /datum/outfit/job/scientist name = "Scientist" diff --git a/code/modules/jobs/job_types/security_officer.dm b/code/modules/jobs/job_types/security_officer.dm index bdae7fe028..3985a07049 100644 --- a/code/modules/jobs/job_types/security_officer.dm +++ b/code/modules/jobs/job_types/security_officer.dm @@ -1,7 +1,7 @@ /datum/job/officer title = "Security Officer" flag = OFFICER -// auto_deadmin_role_flags = DEADMIN_POSITION_SECURITY + auto_deadmin_role_flags = DEADMIN_POSITION_SECURITY department_head = list("Head of Security") department_flag = ENGSEC faction = "Station" @@ -21,6 +21,7 @@ minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_MINERAL_STOREROOM) // See /datum/job/officer/get_access() paycheck = PAYCHECK_HARD paycheck_department = ACCOUNT_SEC + bounty_types = CIV_JOB_SEC mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) @@ -28,6 +29,11 @@ blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/nonviolent, /datum/quirk/paraplegic, /datum/quirk/blindness, /datum/quirk/monophobia) threat = 2 + family_heirlooms = list( + /obj/item/book/manual/wiki/security_space_law, + /obj/item/clothing/head/beret/sec + ) + /datum/job/officer/get_access() var/list/L = list() L |= ..() | check_config_for_sec_maint() @@ -35,12 +41,15 @@ GLOBAL_LIST_INIT(available_depts, list(SEC_DEPT_ENGINEERING, SEC_DEPT_MEDICAL, SEC_DEPT_SCIENCE, SEC_DEPT_SUPPLY)) -/datum/job/officer/after_spawn(mob/living/carbon/human/H, mob/M) +/datum/job/officer/after_spawn(mob/living/spawned, client/player_client, latejoin = FALSE) . = ..() + if(!ishuman(spawned)) + return + var/mob/living/carbon/human/H = spawned // Assign department security var/department - if(M && M.client && M.client.prefs) - department = M.client.prefs.prefered_security_department + if(player_client?.prefs) + department = player_client.prefs.prefered_security_department if(!LAZYLEN(GLOB.available_depts) || department == "None") return else if(department in GLOB.available_depts) @@ -84,7 +93,7 @@ GLOBAL_LIST_INIT(available_depts, list(SEC_DEPT_ENGINEERING, SEC_DEPT_MEDICAL, S if(ears) if(H.ears) qdel(H.ears) - H.equip_to_slot_or_del(new ears(H),SLOT_EARS) + H.equip_to_slot_or_del(new ears(H),ITEM_SLOT_EARS) var/obj/item/card/id/W = H.wear_id W.access |= dep_access @@ -108,11 +117,9 @@ GLOBAL_LIST_INIT(available_depts, list(SEC_DEPT_ENGINEERING, SEC_DEPT_MEDICAL, S else break if(department) - to_chat(M, "You have been assigned to [department]!") + to_chat(H, "You have been assigned to [department]!") else - to_chat(M, "You have not been assigned to any department. Patrol the halls and help where needed.") - - + to_chat(H, "You have not been assigned to any department. Patrol the halls and help where needed.") /datum/outfit/job/security name = "Security Officer" @@ -124,7 +131,7 @@ GLOBAL_LIST_INIT(available_depts, list(SEC_DEPT_ENGINEERING, SEC_DEPT_MEDICAL, S gloves = /obj/item/clothing/gloves/color/black head = /obj/item/clothing/head/helmet/sec suit = /obj/item/clothing/suit/armor/vest/alt - shoes = /obj/item/clothing/shoes/jackboots + shoes = /obj/item/clothing/shoes/jackboots/sec l_pocket = /obj/item/restraints/handcuffs r_pocket = /obj/item/assembly/flash/handheld suit_store = /obj/item/gun/energy/e_gun/advtaser @@ -133,7 +140,7 @@ GLOBAL_LIST_INIT(available_depts, list(SEC_DEPT_ENGINEERING, SEC_DEPT_MEDICAL, S backpack = /obj/item/storage/backpack/security satchel = /obj/item/storage/backpack/satchel/sec duffelbag = /obj/item/storage/backpack/duffelbag/sec - box = /obj/item/storage/box/security + box = /obj/item/storage/box/survival/security implants = list(/obj/item/implant/mindshield) @@ -141,7 +148,7 @@ GLOBAL_LIST_INIT(available_depts, list(SEC_DEPT_ENGINEERING, SEC_DEPT_MEDICAL, S //The helmet is necessary because /obj/item/clothing/head/helmet/sec is overwritten in the chameleon list by the standard helmet, which has the same name and icon state -/obj/item/radio/headset/headset_sec/alt/department/Initialize() +/obj/item/radio/headset/headset_sec/alt/department/Initialize(mapload) . = ..() wires = new/datum/wires/radio(src) secure_radio_connections = new diff --git a/code/modules/jobs/job_types/shaft_miner.dm b/code/modules/jobs/job_types/shaft_miner.dm index 04d3fb53b8..c6192280c7 100644 --- a/code/modules/jobs/job_types/shaft_miner.dm +++ b/code/modules/jobs/job_types/shaft_miner.dm @@ -19,10 +19,16 @@ minimal_access = list(ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM) paycheck = PAYCHECK_EASY ///Not necessarily easy itself, but it can be trivial to make lot of cash on this job. paycheck_department = ACCOUNT_CAR + bounty_types = CIV_JOB_MINE display_order = JOB_DISPLAY_ORDER_SHAFT_MINER threat = 1.5 + + family_heirlooms = list( + /obj/item/pickaxe/mini, + /obj/item/shovel + ) /datum/outfit/job/miner name = "Shaft Miner (Lavaland)" @@ -45,7 +51,7 @@ backpack = /obj/item/storage/backpack/explorer satchel = /obj/item/storage/backpack/satchel/explorer duffelbag = /obj/item/storage/backpack/duffelbag - box = /obj/item/storage/box/survival_mining + box = /obj/item/storage/box/survival/mining chameleon_extras = /obj/item/gun/energy/kinetic_accelerator @@ -60,7 +66,7 @@ mask = /obj/item/clothing/mask/gas/explorer glasses = /obj/item/clothing/glasses/meson suit_store = /obj/item/tank/internals/oxygen - internals_slot = SLOT_S_STORE + internals_slot = ITEM_SLOT_SUITSTORE backpack_contents = list( /obj/item/flashlight/seclite=1,\ /obj/item/kitchen/knife/combat/survival=1, diff --git a/code/modules/jobs/job_types/station_engineer.dm b/code/modules/jobs/job_types/station_engineer.dm index 2396728ad8..58822dc4c5 100644 --- a/code/modules/jobs/job_types/station_engineer.dm +++ b/code/modules/jobs/job_types/station_engineer.dm @@ -20,12 +20,22 @@ ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_TCOMSAT, ACCESS_MINERAL_STOREROOM) paycheck = PAYCHECK_MEDIUM paycheck_department = ACCOUNT_ENG + bounty_types = CIV_JOB_ENG starting_modifiers = list(/datum/skill_modifier/job/level/wiring, /datum/skill_modifier/job/affinity/wiring) display_order = JOB_DISPLAY_ORDER_STATION_ENGINEER threat = 1 + + family_heirlooms = list( + /obj/item/clothing/head/hardhat, + /obj/item/screwdriver/brass/family, + /obj/item/wrench/brass/family, + /obj/item/weldingtool/mini, // No brass family variant + /obj/item/crowbar/brass/family, + /obj/item/wirecutters/brass/family + ) /datum/outfit/job/engineer name = "Station Engineer" @@ -42,8 +52,8 @@ backpack = /obj/item/storage/backpack/industrial satchel = /obj/item/storage/backpack/satchel/eng duffelbag = /obj/item/storage/backpack/duffelbag/engineering - box = /obj/item/storage/box/engineer - pda_slot = SLOT_L_STORE + box = /obj/item/storage/box/survival/engineer + pda_slot = ITEM_SLOT_LPOCKET backpack_contents = list(/obj/item/modular_computer/tablet/preset/advanced=1) /datum/outfit/job/engineer/gloved @@ -56,6 +66,6 @@ suit = /obj/item/clothing/suit/space/hardsuit/engine suit_store = /obj/item/tank/internals/oxygen head = null - internals_slot = SLOT_S_STORE + internals_slot = ITEM_SLOT_SUITSTORE diff --git a/code/modules/jobs/job_types/virologist.dm b/code/modules/jobs/job_types/virologist.dm index 3e9b3ba06c..423a65048f 100644 --- a/code/modules/jobs/job_types/virologist.dm +++ b/code/modules/jobs/job_types/virologist.dm @@ -18,12 +18,17 @@ minimal_access = list(ACCESS_MEDICAL, ACCESS_VIROLOGY, ACCESS_MINERAL_STOREROOM) paycheck = PAYCHECK_MEDIUM paycheck_department = ACCOUNT_MED + bounty_types = CIV_JOB_VIRO display_order = JOB_DISPLAY_ORDER_VIROLOGIST threat = 1.5 starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery) + + family_heirlooms = list( + /obj/item/reagent_containers/syringe + ) /datum/outfit/job/virologist name = "Virologist" diff --git a/code/modules/jobs/job_types/warden.dm b/code/modules/jobs/job_types/warden.dm index dae3094ebe..ec4e81caea 100644 --- a/code/modules/jobs/job_types/warden.dm +++ b/code/modules/jobs/job_types/warden.dm @@ -1,7 +1,7 @@ /datum/job/warden title = "Warden" flag = WARDEN -// auto_deadmin_role_flags = DEADMIN_POSITION_SECURITY + auto_deadmin_role_flags = DEADMIN_POSITION_SECURITY department_head = list("Head of Security") department_flag = ENGSEC faction = "Station" @@ -22,6 +22,7 @@ paycheck = PAYCHECK_HARD paycheck_department = ACCOUNT_SEC + bounty_types = CIV_JOB_SEC mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) @@ -29,6 +30,10 @@ blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/nonviolent, /datum/quirk/paraplegic, /datum/quirk/blindness, /datum/quirk/monophobia) threat = 2 + family_heirlooms = list( + /obj/item/book/manual/wiki/security_space_law + ) + /datum/job/warden/get_access() var/list/L = list() L = ..() | check_config_for_sec_maint() @@ -41,7 +46,7 @@ belt = /obj/item/pda/warden ears = /obj/item/radio/headset/headset_sec/alt uniform = /obj/item/clothing/under/rank/security/warden - shoes = /obj/item/clothing/shoes/jackboots + shoes = /obj/item/clothing/shoes/jackboots/sec suit = /obj/item/clothing/suit/armor/vest/warden/alt gloves = /obj/item/clothing/gloves/color/black head = /obj/item/clothing/head/warden @@ -54,7 +59,7 @@ backpack = /obj/item/storage/backpack/security satchel = /obj/item/storage/backpack/satchel/sec duffelbag = /obj/item/storage/backpack/duffelbag/sec - box = /obj/item/storage/box/security + box = /obj/item/storage/box/survival/security implants = list(/obj/item/implant/mindshield) diff --git a/code/modules/jobs/jobs.dm b/code/modules/jobs/jobs.dm index 78b7dd3964..d91b102599 100644 --- a/code/modules/jobs/jobs.dm +++ b/code/modules/jobs/jobs.dm @@ -43,6 +43,7 @@ GLOBAL_LIST_INIT(civilian_positions, list( "Chaplain", "Clown", "Mime", + "Prisoner", "Assistant")) GLOBAL_LIST_INIT(security_positions, list( diff --git a/code/modules/keybindings/bindings_client.dm b/code/modules/keybindings/bindings_client.dm index 3d12f89cfe..7c0c6216a5 100644 --- a/code/modules/keybindings/bindings_client.dm +++ b/code/modules/keybindings/bindings_client.dm @@ -6,6 +6,7 @@ set hidden = TRUE client_keysend_amount += 1 + last_activity = world.time var/cache = client_keysend_amount @@ -89,6 +90,7 @@ set hidden = TRUE keys_held -= _key + last_activity = world.time var/movement = movement_keys[_key] if(!(next_move_dir_add & movement)) next_move_dir_sub |= movement diff --git a/code/modules/keybindings/keybind/living.dm b/code/modules/keybindings/keybind/living.dm index f76c86691f..7f5ccb3b51 100644 --- a/code/modules/keybindings/keybind/living.dm +++ b/code/modules/keybindings/keybind/living.dm @@ -36,3 +36,25 @@ /datum/keybinding/living/toggle_resting/down(client/user) var/mob/living/L = user.mob L.lay_down() + +/datum/keybinding/living/cancel_action + hotkey_keys = list("Unbound") + name = "cancel_action" + full_name = "Cancel Action" + description = "Cancel the current action." + +/// Technically you shouldn't be doing any actions if you were sleeping either but... +/datum/keybinding/living/can_use(client/user) + . = ..() + var/mob/living/mob = user.mob + return . && (mob.stat == CONSCIOUS) + +/datum/keybinding/living/cancel_action/down(client/user) + var/mob/M = user.mob + if(length(M.do_afters)) + var/atom/target = M.do_afters[M.do_afters.len] + to_chat(M, "You stop interacting with \the [target].") + LAZYREMOVE(M.do_afters, target) + else + to_chat(M, "There's nothing that you can cancel right now.") + return TRUE diff --git a/code/modules/language/arachnid.dm b/code/modules/language/arachnid.dm index d021e5a35b..1d853ac715 100644 --- a/code/modules/language/arachnid.dm +++ b/code/modules/language/arachnid.dm @@ -5,7 +5,7 @@ speech_verb = "chitter" ask_verb = "chitter" exclaim_verb = "chitter" - key = "r" + key = "c" flags = NO_STUTTER | LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD icon_state = "arachnid" diff --git a/code/modules/language/dwarven.dm b/code/modules/language/dwarven.dm index aded22cd6f..182aab0c23 100644 --- a/code/modules/language/dwarven.dm +++ b/code/modules/language/dwarven.dm @@ -4,7 +4,7 @@ name = "Dwarvish" desc = "The language of the dwarves" space_chance = 100 // Each 'syllable' is its own word - key = "D" + key = "w" flags = TONGUELESS_SPEECH syllables = list("kulet", "alak", "bidok", "nicol", "anam", "gatal", "mabdug", "zustash", "sedil", "ustos", "emr", "izeg", "beming", "gost", "ntak", "tosid", "feb", "berim", "ibruk", "ermis", "thoth", "thatthil", "gistang", "libash", "lakish", "asdos", "roder", "nel", "biban", "ugog", "ish", "robek", "olmul", "nokzam", "emuth", "fer", "uvel", "dolush", "ag^k", "ucat", "ng rak", "enir", "ugath", "lisig", "etg", "erong", "osed", "lanlar", "udir", "tarmid", "s krith", "nural", "bugsud", "okag", "nazush", "nashon", "ftrid", "en''r", "dstik", "kogan", "ingish", "dudgoth", "stalk*b", "themor", "murak", "altth", "osod", "thcekut", "cog", "selsten", "egdoth", "othsin", "idek", "st", "suthmam", "im", "okab", "onlnl", "gasol", "tegir", "nam...sh", "noval", "shalig", "shin", "lek", ",,kim", "kfkdal", "stum,,m", "alud", "olom", "%lot", "rozsed", "thos", "okon", "nWith only [living_players] living players left, the game timers have been sped up.
    ") + day_phase_period /= 2 + voting_phase_period /= 2 + judgement_phase_period /= 2 + judgement_lynch_period /= 2 + night_phase_period /= 2 if(turn == 1) - send_message("The selected map is [current_map.name]!
    [current_map.description]
    ") + send_message(span_notice("The selected map is [current_map.name]!
    [current_map.description]")) send_message("Day [turn] started! There is no voting on the first day. Say hello to everybody!") next_phase_timer = addtimer(CALLBACK(src,.proc/check_trial, FALSE),first_day_phase_period,TIMER_STOPPABLE) //no voting period = no votes = instant night else @@ -257,19 +273,19 @@ /datum/mafia_controller/proc/lynch() for(var/i in judgement_innocent_votes) var/datum/mafia_role/role = i - send_message("[role.body.real_name] voted innocent.") + send_message(span_green("[role.body.real_name] voted innocent.")) for(var/ii in judgement_abstain_votes) var/datum/mafia_role/role = ii - send_message("[role.body.real_name] abstained.") + send_message(span_comradio("[role.body.real_name] abstained.")) for(var/iii in judgement_guilty_votes) var/datum/mafia_role/role = iii - send_message("[role.body.real_name] voted guilty.") + send_message(span_red("[role.body.real_name] voted guilty.")) if(judgement_guilty_votes.len > judgement_innocent_votes.len) //strictly need majority guilty to lynch - send_message("Guilty wins majority, [on_trial.body.real_name] has been lynched.") - on_trial.kill(src, lynch = TRUE) + send_message(span_red("Guilty wins majority, [on_trial.body.real_name] has been lynched.")) + on_trial.kill(src,lynch = TRUE) addtimer(CALLBACK(src, .proc/send_home, on_trial),judgement_lynch_period) else - send_message("Innocent wins majority, [on_trial.body.real_name] has been spared.") + send_message(span_green("Innocent wins majority, [on_trial.body.real_name] has been spared.")) on_trial.body.forceMove(get_turf(on_trial.assigned_landmark)) on_trial = null //day votes are already cleared, so this will skip the trial and check victory/lockdown/whatever else @@ -300,11 +316,14 @@ var/list/total_town = list() var/list/total_mafia = list() - var/alive_town = 0 + //voting power of town + solos (since they don't want mafia to overpower) + var/anti_mafia_power = 0 + //voting power of mafia (greater than anti mafia power + team end not blocked = mafia victory) var/alive_mafia = 0 var/list/solos_to_ask = list() //need to ask after because first round is counting team sizes var/list/total_victors = list() //if this list gets filled with anyone, they win. list because side antags can with with people var/blocked_victory = FALSE //if a solo antagonist is stopping the town or mafia from finishing the game. + var/town_can_kill = FALSE //Town has a killing role and it cannot allow mafia to win ///PHASE ONE: TALLY UP ALL NUMBERS OF PEOPLE STILL ALIVE @@ -313,23 +332,24 @@ if(MAFIA_TEAM_MAFIA) total_mafia += R if(R.game_status == MAFIA_ALIVE) - alive_mafia += R.vote_power + alive_mafia += R.vote_potential if(MAFIA_TEAM_TOWN) total_town += R if(R.game_status == MAFIA_ALIVE) - alive_town += R.vote_power + anti_mafia_power += R.vote_potential + if(R.role_flags & ROLE_CAN_KILL) //the game cannot autoresolve with killing roles (unless a solo wins anyways, like traitors who are immune) + town_can_kill = TRUE if(MAFIA_TEAM_SOLO) if(R.game_status == MAFIA_ALIVE) - if(R.solo_counts_as_town) - alive_town += R.vote_power + anti_mafia_power += R.vote_potential solos_to_ask += R ///PHASE TWO: SEND STATS TO SOLO ANTAGS, SEE IF THEY WON OR TEAMS CANNOT WIN for(var/datum/mafia_role/solo in solos_to_ask) - if(solo.check_total_victory(alive_town, alive_mafia)) + if(solo.check_total_victory(anti_mafia_power, alive_mafia)) total_victors += solo - if(solo.block_team_victory(alive_town, alive_mafia)) + if(solo.block_team_victory(anti_mafia_power, alive_mafia)) blocked_victory = TRUE //solo victories! @@ -348,7 +368,7 @@ award_role(townie.winner_award, townie) start_the_end("!! TOWN VICTORY !!") return TRUE - else if(alive_mafia >= alive_town) //guess could change if town nightkill is added + else if(alive_mafia >= anti_mafia_power && !town_can_kill) start_the_end("!! MAFIA VICTORY !!") for(var/datum/mafia_role/changeling in total_mafia) award_role(changeling.winner_award, changeling) @@ -396,6 +416,13 @@ custom_setup = list() turn = 0 votes = list() + + day_phase_period = initial(day_phase_period) + voting_phase_period = initial(voting_phase_period) + judgement_phase_period = initial(judgement_phase_period) + judgement_lynch_period = initial(judgement_lynch_period) + night_phase_period = initial(night_phase_period) + //map gen does not deal with landmarks QDEL_LIST(landmarks) QDEL_NULL(town_center_landmark) @@ -451,14 +478,15 @@ SEND_SIGNAL(src,COMSIG_MAFIA_NIGHT_START) SEND_SIGNAL(src,COMSIG_MAFIA_NIGHT_ACTION_PHASE) //resolve mafia kill, todo unsnowflake this - var/datum/mafia_role/R = get_vote_winner("Mafia") - if(R) + var/datum/mafia_role/victim = get_vote_winner("Mafia") + if(victim) var/datum/mafia_role/killer = get_random_voter("Mafia") - if(SEND_SIGNAL(killer,COMSIG_MAFIA_CAN_PERFORM_ACTION,src,"mafia killing",R) & MAFIA_PREVENT_ACTION) - send_message("[killer.body.real_name] was unable to attack [R.body.real_name] tonight!",MAFIA_TEAM_MAFIA) + if(!victim.can_action(src, killer, "changeling murder")) + send_message(span_danger("[killer.body.real_name] was unable to attack [victim.body.real_name] tonight!"),MAFIA_TEAM_MAFIA) else - send_message("[killer.body.real_name] has attacked [R.body.real_name]!",MAFIA_TEAM_MAFIA) - R.kill(src) + send_message(span_danger("[killer.body.real_name] has attacked [victim.body.real_name]!"),MAFIA_TEAM_MAFIA) + if(victim.kill(src,killer,lynch=FALSE)) + to_chat(victim.body, span_userdanger("You have been killed by a Changeling!")) reset_votes("Mafia") SEND_SIGNAL(src,COMSIG_MAFIA_NIGHT_KILL_PHASE) SEND_SIGNAL(src,COMSIG_MAFIA_NIGHT_END) @@ -485,14 +513,14 @@ else votes[vote_type][voter] = target if(old_vote && old_vote == target) - send_message("[voter.body.real_name] retracts their vote for [target.body.real_name]!", team = teams) + send_message(span_notice("[voter.body.real_name] retracts their vote for [target.body.real_name]!"), team = teams) else - send_message("[voter.body.real_name] voted for [target.body.real_name]!",team = teams) + send_message(span_notice("[voter.body.real_name] voted for [target.body.real_name]!"),team = teams) if(!teams) - target.body.update_icon() //Update the vote display if it's a public vote + target.body.update_appearance() //Update the vote display if it's a public vote var/datum/mafia_role/old = old_vote if(old) - old.body.update_icon() + old.body.update_appearance() /** * Clears out the votes of a certain type (day votes, mafia kill votes) while leaving others untouched @@ -504,7 +532,7 @@ bodies_to_update += R.body votes[vote_type] = list() for(var/mob/M in bodies_to_update) - M.update_icon() + M.update_appearance() /** * Returns how many people voted for the role, in whatever vote (day vote, night kill vote) @@ -571,6 +599,9 @@ /datum/mafia_controller/proc/create_bodies() for(var/datum/mafia_role/role in all_roles) var/mob/living/carbon/human/H = new(get_turf(role.assigned_landmark)) + ADD_TRAIT(H, TRAIT_NOFIRE, MAFIA_TRAIT) + ADD_TRAIT(H, TRAIT_NOBREATH, MAFIA_TRAIT) + // ADD_TRAIT(H, TRAIT_CANNOT_CRYSTALIZE, MAFIA_TRAIT) freon tomfoolery H.equipOutfit(player_outfit) H.status_flags |= GODMODE RegisterSignal(H,COMSIG_ATOM_UPDATE_OVERLAYS,.proc/display_votes) @@ -707,6 +738,7 @@ if(role_count > 0) debug_setup[found_path] = role_count custom_setup = debug_setup + try_autostart()//don't worry, this fails if there's a game in progress if("cancel_setup") custom_setup = list() switch(action) //both living and dead @@ -723,28 +755,28 @@ switch(action) if("mf_signup") if(!SSticker.HasRoundStarted()) - to_chat(usr, "Wait for the round to start.") + to_chat(usr, span_warning("Wait for the round to start.")) return if(GLOB.mafia_signup[C.ckey]) GLOB.mafia_signup -= C.ckey - to_chat(usr, "You unregister from Mafia.") + to_chat(usr, span_notice("You unregister from Mafia.")) return TRUE else GLOB.mafia_signup[C.ckey] = C - to_chat(usr, "You sign up for Mafia.") + to_chat(usr, span_notice("You sign up for Mafia.")) if(phase == MAFIA_PHASE_SETUP) check_signups() try_autostart() return TRUE if("mf_spectate") if(C.ckey in spectators) - to_chat(usr, "You will no longer get messages from the game.") + to_chat(usr, span_notice("You will no longer get messages from the game.")) spectators -= C.ckey else - to_chat(usr, "You will now get messages from the game.") + to_chat(usr, span_notice("You will now get messages from the game.")) spectators += C.ckey return TRUE - if(user_role.game_status == MAFIA_DEAD) + if(user_role && user_role.game_status == MAFIA_DEAD) return //User actions (just living) switch(action) @@ -814,58 +846,59 @@ . += L[key] /** - * Returns a semirandom setup, with... - * Town, Two invest roles, one protect role, sometimes a misc role, and the rest assistants for town. - * Mafia, 2 normal mafia and one special. - * Neutral, two disruption roles, sometimes one is a killing. + * Returns a semirandom setup with 12 roles. balance not guaranteed! * - * See _defines.dm in the mafia folder for a rundown on what these groups of roles include. + * please check the variables at the top of the proc to see how much of each role types it picks */ /datum/mafia_controller/proc/generate_random_setup() var/invests_left = 2 - var/protects_left = 1 - var/miscs_left = prob(35) + var/protects_left = 2 + var/killings_left = 1 + var/supports_left = 2 + var/mafiareg_left = 2 var/mafiaspe_left = 1 - var/killing_role = prob(50) - var/disruptors = killing_role ? 1 : 2 //still required to calculate overflow - var/overflow_left = max_player - (invests_left + protects_left + miscs_left + mafiareg_left + mafiaspe_left + killing_role + disruptors) + + // if there is one killing role, there will be less disruptors + var/neutral_killing_role = prob(50) var/list/random_setup = list() + var/list/unique_roles_added = list() for(var/i in 1 to max_player) //should match the number of roles to add - if(overflow_left) - add_setup_role(random_setup, TOWN_OVERFLOW) - overflow_left-- - else if(invests_left) - add_setup_role(random_setup, TOWN_INVEST) + if(invests_left) + add_setup_role(random_setup, unique_roles_added, TOWN_INVEST) invests_left-- else if(protects_left) - add_setup_role(random_setup, TOWN_PROTECT) + add_setup_role(random_setup, unique_roles_added, TOWN_PROTECT) protects_left-- - else if(miscs_left) - add_setup_role(random_setup, TOWN_MISC) - miscs_left-- + else if(killings_left) + add_setup_role(random_setup, unique_roles_added, TOWN_KILLING) + killings_left-- + else if(supports_left) + add_setup_role(random_setup, unique_roles_added, TOWN_SUPPORT) + supports_left-- else if(mafiareg_left) - add_setup_role(random_setup, MAFIA_REGULAR) + add_setup_role(random_setup, unique_roles_added, MAFIA_REGULAR) mafiareg_left-- else if(mafiaspe_left) - add_setup_role(random_setup, MAFIA_SPECIAL) + add_setup_role(random_setup, unique_roles_added, MAFIA_SPECIAL) mafiaspe_left-- - else if(killing_role) - add_setup_role(random_setup, NEUTRAL_KILL) - killing_role-- + else if(neutral_killing_role) + add_setup_role(random_setup, unique_roles_added, NEUTRAL_KILL) + neutral_killing_role-- else - add_setup_role(random_setup, NEUTRAL_DISRUPT) + add_setup_role(random_setup, unique_roles_added, NEUTRAL_DISRUPT) + debug = random_setup return random_setup /** - * Helper proc that adds a random role of a type to a setup. if it doesn't exist in the setup, it adds the path to the list and otherwise bumps the path in the list up one + * Helper proc that adds a random role of a type to a setup. if it doesn't exist in the setup, it adds the path to the list and otherwise bumps the path in the list up one. unique roles can only get added once. */ -/datum/mafia_controller/proc/add_setup_role(setup_list, wanted_role_type) +/datum/mafia_controller/proc/add_setup_role(setup_list, banned_roles, wanted_role_type) var/list/role_type_paths = list() for(var/path in typesof(/datum/mafia_role)) var/datum/mafia_role/instance = path - if(initial(instance.role_type) == wanted_role_type) + if(initial(instance.role_type) == wanted_role_type && !(path in banned_roles)) role_type_paths += instance var/mafia_path = pick(role_type_paths) @@ -880,6 +913,8 @@ setup_list[found_role] += 1 return setup_list[mafia_path] = 1 + if(initial(mafia_path_type.role_flags) & ROLE_UNIQUE) //check to see if we should no longer consider this okay to add to the game + banned_roles += mafia_path /** * Called when enough players have signed up to fill a setup. DOESN'T NECESSARILY MEAN THE GAME WILL START. @@ -893,6 +928,8 @@ var/list/setup = custom_setup if(!setup.len) req_players = max_player //MAFIA_MAX_PLAYER_COUNT + else if(low_pop_mode) + req_players = required_player else req_players = assoc_value_sum(setup) @@ -909,10 +946,10 @@ GLOB.mafia_signup -= key //not valid to play when we checked so remove them from signups //if there were not enough players, don't start. we already trimmed the list to now hold only valid signups + if(length(possible_keys) < req_players) return - else //hacky implementation of max players - req_players = clamp(length(possible_keys), 1, max_player) + req_players = clamp(length(possible_keys), required_player, max_player) //if there were too many players, still start but only make filtered keys as big as it needs to be (cut excess) //also removes people who do get into final player list from the signup so they have to sign up again when game ends @@ -923,8 +960,8 @@ //small message about not getting into this game for clarity on why they didn't get in for(var/unpicked in possible_keys) var/client/unpicked_client = GLOB.directory[unpicked] - to_chat(unpicked_client, "Sorry, the starting mafia game has too many players and you were not picked.") - to_chat(unpicked_client, "You're still signed up, getting messages from the current round, and have another chance to join when the one starting now finishes.") + to_chat(unpicked_client, span_danger("Sorry, the starting mafia game has too many players and you were not picked.")) + to_chat(unpicked_client, span_warning("You're still signed up, getting messages from the current round, and have another chance to join when the one starting now finishes.")) if(!setup.len) //don't actually have one yet, so generate a max player random setup. it's good to do this here instead of above so it doesn't generate one every time a game could possibly start. setup = generate_random_setup() diff --git a/code/modules/mafia/map_pieces.dm b/code/modules/mafia/map_pieces.dm index 3339c596b4..61b8e5dd3e 100644 --- a/code/modules/mafia/map_pieces.dm +++ b/code/modules/mafia/map_pieces.dm @@ -33,7 +33,7 @@ requires_power = FALSE has_gravity = STANDARD_GRAVITY flags_1 = NONE - // block_suicide = TRUE + area_flags = BLOCK_SUICIDE | UNIQUE_AREA /datum/map_template/mafia var/description = "" @@ -75,5 +75,5 @@ /datum/map_template/mafia/reebe name = "Reebe" - description = "Trouble in Reebe station! Copypaste guranteed by ClockCo™" + description = "Based of the place known as reebee. Syndicate spies have infiltrated and everyone has to find out who's who before they destroy the ark!" mappath = "_maps/map_files/Mafia/mafia_reebe.dmm" diff --git a/code/modules/mafia/outfits.dm b/code/modules/mafia/outfits.dm index bbc72bd120..fad628e392 100644 --- a/code/modules/mafia/outfits.dm +++ b/code/modules/mafia/outfits.dm @@ -30,6 +30,11 @@ uniform = /obj/item/clothing/under/suit/black shoes = /obj/item/clothing/shoes/laceup +/datum/outfit/mafia/chaplain + name = "Mafia Chaplain" + + uniform = /obj/item/clothing/under/rank/civilian/chaplain + /datum/outfit/mafia/md name = "Mafia Medical Doctor" @@ -37,10 +42,14 @@ shoes = /obj/item/clothing/shoes/sneakers/white suit = /obj/item/clothing/suit/toggle/labcoat -/datum/outfit/mafia/chaplain - name = "Mafia Chaplain" +/datum/outfit/mafia/security + name = "Mafia Security Officer" - uniform = /obj/item/clothing/under/rank/civilian/chaplain + uniform = /obj/item/clothing/under/rank/security/officer + gloves = /obj/item/clothing/gloves/color/black + head = /obj/item/clothing/head/helmet/sec + suit = /obj/item/clothing/suit/armor/vest/alt + shoes = /obj/item/clothing/shoes/jackboots /datum/outfit/mafia/lawyer name = "Mafia Lawyer" @@ -58,6 +67,26 @@ head = /obj/item/clothing/head/hopcap glasses = /obj/item/clothing/glasses/sunglasses +/datum/outfit/mafia/hos + name = "Mafia Head of Security" + + uniform = /obj/item/clothing/under/rank/security/head_of_security + shoes = /obj/item/clothing/shoes/jackboots + suit = /obj/item/clothing/suit/armor/hos/trenchcoat + gloves = /obj/item/clothing/gloves/color/black + head = /obj/item/clothing/head/beret/sec + glasses = /obj/item/clothing/glasses/hud/security/sunglasses + +/datum/outfit/mafia/warden + name = "Mafia Warden" + + uniform = /obj/item/clothing/under/rank/security/warden + shoes = /obj/item/clothing/shoes/jackboots + suit = /obj/item/clothing/suit/armor/vest/warden/alt + gloves = /obj/item/clothing/gloves/color/black + head = /obj/item/clothing/head/warden + glasses = /obj/item/clothing/glasses/hud/security/sunglasses + //mafia /datum/outfit/mafia/changeling diff --git a/code/modules/mafia/roles.dm b/code/modules/mafia/roles.dm index a210c4994f..a48f890d10 100644 --- a/code/modules/mafia/roles.dm +++ b/code/modules/mafia/roles.dm @@ -10,19 +10,21 @@ var/mob/living/carbon/human/body var/obj/effect/landmark/mafia/assigned_landmark - ///how many votes submitted when you vote. + ///role flags (special status of roles like detection immune) + var/role_flags = NONE + ///how many votes submitted when you vote. used in voting, but not victory var/vote_power = 1 - var/detect_immune = FALSE - var/revealed = FALSE - var/datum/outfit/revealed_outfit = /datum/outfit/mafia/assistant //the assistants need a special path to call out they were in fact assistant, everything else can just use job equipment - //action = uses + ///how many votes your role COULD count for, now or later. used in checking victory + var/vote_potential = 1 + ///what they get equipped with when they are revealed + var/datum/outfit/revealed_outfit = /datum/outfit/mafia/assistant + ///action = uses var/list/actions = list() var/list/targeted_actions = list() - //what the role gets when it wins a game + ///what the role gets when it wins a game var/winner_award = /datum/award/achievement/mafia/assistant - //so mafia have to also kill them to have a majority - var/solo_counts_as_town = FALSE //(don't set this for town) + ///so mafia have to also kill them to have a majority var/game_status = MAFIA_ALIVE ///icon state in the mafia dmi of the hud of the role, used in the mafia ui @@ -38,8 +40,30 @@ /datum/mafia_role/New(datum/mafia_controller/game) . = ..() -/datum/mafia_role/proc/kill(datum/mafia_controller/game,lynch=FALSE) - if(SEND_SIGNAL(src,COMSIG_MAFIA_ON_KILL,game,lynch) & MAFIA_PREVENT_KILL) +/** + * Tests if a visitor can actually perform an action on this role. Verbose on purpose! + * + * Will return false if: Your visit is roleblocked, they have perished, or your visit was interrupted + */ +/datum/mafia_role/proc/can_action(datum/mafia_controller/game, datum/mafia_role/visitor, action) + if(role_flags & ROLE_ROLEBLOCKED) + to_chat(visitor,span_danger("Your [action] was blocked!")) + return FALSE + if(game_status != MAFIA_ALIVE) //They're already dead + to_chat(visitor,span_danger("[body.real_name] perished before you could visit!")) + return FALSE + if(SEND_SIGNAL(src,COMSIG_MAFIA_ON_VISIT,game,visitor) & MAFIA_VISIT_INTERRUPTED) //visited a warden. something that prevents you by visiting that person + to_chat(visitor,span_danger("Your [action] was interrupted!")) + return FALSE + return TRUE + +/** + * Tests kill immunities, if nothing prevents the kill, kills this role. + * + * Does not count as visiting, see visit proc. + */ +/datum/mafia_role/proc/kill(datum/mafia_controller/game, datum/mafia_role/attacker, lynch=FALSE) + if(SEND_SIGNAL(src,COMSIG_MAFIA_ON_KILL,game,attacker,lynch) & MAFIA_PREVENT_KILL) return FALSE game_status = MAFIA_DEAD body.death() @@ -55,19 +79,19 @@ /datum/mafia_role/proc/greet() SEND_SOUND(body, 'sound/ambience/ambifailure.ogg') - to_chat(body,"You are the [name].") - to_chat(body,"[desc]") + to_chat(body,span_danger("You are the [name].")) + to_chat(body,span_danger("[desc]")) switch(team) if(MAFIA_TEAM_MAFIA) - to_chat(body,"You and your co-conspirators win if you outnumber crewmembers.") + to_chat(body,span_danger("You and your co-conspirators win if you outnumber crewmembers.")) if(MAFIA_TEAM_TOWN) - to_chat(body,"You are a crewmember. Find out and lynch the changelings!") + to_chat(body,span_danger("You are a crewmember. Find out and lynch the changelings!")) if(MAFIA_TEAM_SOLO) - to_chat(body,"You are not aligned to town or mafia. Accomplish your own objectives!") - to_chat(body, "Be sure to read the wiki page to learn more, if you have no idea what's going on.") + to_chat(body,span_danger("You are not aligned to town or mafia. Accomplish your own objectives!")) + to_chat(body, "Be sure to read the wiki page to learn more, if you have no idea what's going on.") /datum/mafia_role/proc/reveal_role(datum/mafia_controller/game, verbose = FALSE) - if(revealed) + if((role_flags & ROLE_REVEALED)) return if(verbose) game.send_message("It is revealed that the true role of [body] [game_status == MAFIA_ALIVE ? "is" : "was"] [name]!") @@ -76,7 +100,7 @@ qdel(thing) special_reveal_equip(game) body.equipOutfit(revealed_outfit) - revealed = TRUE + role_flags |= ROLE_REVEALED /datum/mafia_role/proc/special_reveal_equip(datum/mafia_controller/game) return @@ -85,7 +109,7 @@ return /datum/mafia_role/proc/validate_action_target(datum/mafia_controller/game,action,datum/mafia_role/target) - if(SEND_SIGNAL(src,COMSIG_MAFIA_CAN_PERFORM_ACTION,game,action,target) & MAFIA_PREVENT_ACTION) + if((role_flags & ROLE_ROLEBLOCKED)) return FALSE return TRUE @@ -114,9 +138,9 @@ team_desc = "Nobody" team_span = "comradio" the = FALSE - result += "The [name] is aligned with [the ? "the " : ""][team_desc]" + result += span_notice("The [span_bold("[name]")] is aligned with [the ? "the " : ""][team_desc]") result += "\"[desc]\"" - result += "[name] wins when they [win_condition]" + result += span_notice("[name] wins when they [win_condition]") to_chat(clueless, result.Join("
    ")) /datum/mafia_role/detective @@ -145,35 +169,39 @@ /datum/mafia_role/detective/handle_action(datum/mafia_controller/game,action,datum/mafia_role/target) if(!target || target.game_status != MAFIA_ALIVE) - to_chat(body,"You can only investigate alive people.") + to_chat(body,span_warning("You can only investigate alive people.")) return - to_chat(body,"You will investigate [target.body.real_name] tonight.") + to_chat(body,span_warning("You will investigate [target.body.real_name] tonight.")) current_investigation = target /datum/mafia_role/detective/proc/investigate(datum/mafia_controller/game) SIGNAL_HANDLER + if(!current_investigation) + return + var/datum/mafia_role/target = current_investigation - if(target) - if(target.detect_immune) - to_chat(body,"Your investigations reveal that [target.body.real_name] is a true member of the station.") - add_note("N[game.turn] - [target.body.real_name] - Town") - else - var/team_text - var/fluff - switch(target.team) - if(MAFIA_TEAM_TOWN) - team_text = "Town" - fluff = "a true member of the station." - if(MAFIA_TEAM_MAFIA) - team_text = "Mafia" - fluff = "an unfeeling, hideous changeling!" - if(MAFIA_TEAM_SOLO) - team_text = "Solo" - fluff = "a rogue, with their own objectives..." - to_chat(body,"Your investigations reveal that [target.body.real_name] is [fluff]") - add_note("N[game.turn] - [target.body.real_name] - [team_text]") current_investigation = null + if(!target.can_action(game, src, "investigation")) + return + if((target.role_flags & ROLE_UNDETECTABLE)) + to_chat(body,span_warning("Your investigations reveal that [target.body.real_name] is a true member of the station.")) + add_note("N[game.turn] - [target.body.real_name] - Town") + else + var/team_text + var/fluff + switch(target.team) + if(MAFIA_TEAM_TOWN) + team_text = "Town" + fluff = "a true member of the station." + if(MAFIA_TEAM_MAFIA) + team_text = "Mafia" + fluff = "an unfeeling, hideous changeling!" + if(MAFIA_TEAM_SOLO) + team_text = "Solo" + fluff = "a rogue, with their own objectives..." + to_chat(body,span_warning("Your investigations reveal that [target.body.real_name] is [fluff]")) + add_note("N[game.turn] - [target.body.real_name] - [team_text]") /datum/mafia_role/psychologist name = "Psychologist" @@ -195,25 +223,27 @@ /datum/mafia_role/psychologist/validate_action_target(datum/mafia_controller/game, action, datum/mafia_role/target) . = ..() - if(!. || !can_use || game.phase == MAFIA_PHASE_NIGHT || target.game_status != MAFIA_ALIVE || target.revealed || target == src) + if(!. || !can_use || game.phase == MAFIA_PHASE_NIGHT || target.game_status != MAFIA_ALIVE || (target.role_flags & ROLE_REVEALED) || target == src) return FALSE /datum/mafia_role/psychologist/handle_action(datum/mafia_controller/game, action, datum/mafia_role/target) . = ..() - to_chat(body,"You will reveal [target.body.real_name] tonight.") + to_chat(body,span_warning("You will reveal [target.body.real_name] tonight.")) current_target = target /datum/mafia_role/psychologist/proc/therapy_reveal(datum/mafia_controller/game) SIGNAL_HANDLER - if(SEND_SIGNAL(src,COMSIG_MAFIA_CAN_PERFORM_ACTION,game,"reveal",current_target) & MAFIA_PREVENT_ACTION || game_status != MAFIA_ALIVE) //Got lynched or roleblocked by a lawyer. - current_target = null - if(current_target) - add_note("N[game.turn] - [current_target.body.real_name] - Revealed true identity") - to_chat(body,"You have revealed the true nature of the [current_target]!") - current_target.reveal_role(game, verbose = TRUE) - current_target = null - can_use = FALSE + if(!current_target) + return + var/datum/mafia_role/target = current_target + current_target = null + if(!target.can_action(game, src, "role reveal")) + return + add_note("N[game.turn] - [target.body.real_name] - Revealed true identity") + to_chat(body,span_warning("You have revealed the true nature of the [target]!")) + target.reveal_role(game, verbose = TRUE) + can_use = FALSE /datum/mafia_role/chaplain name = "Chaplain" @@ -225,7 +255,7 @@ winner_award = /datum/award/achievement/mafia/chaplain targeted_actions = list("Pray") - var/current_target + var/datum/mafia_role/current_target /datum/mafia_role/chaplain/New(datum/mafia_controller/game) . = ..() @@ -235,25 +265,29 @@ . = ..() if(!.) return - return game.phase == MAFIA_PHASE_NIGHT && target.game_status == MAFIA_DEAD && target != src && !target.revealed + return game.phase == MAFIA_PHASE_NIGHT && target.game_status == MAFIA_DEAD && target != src && !(target.role_flags & ROLE_REVEALED) /datum/mafia_role/chaplain/handle_action(datum/mafia_controller/game, action, datum/mafia_role/target) - to_chat(body,"You will commune with the spirit of [target.body.real_name] tonight.") + to_chat(body,span_warning("You will commune with the spirit of [target.body.real_name] tonight.")) current_target = target /datum/mafia_role/chaplain/proc/commune(datum/mafia_controller/game) SIGNAL_HANDLER + if(!current_target) + return var/datum/mafia_role/target = current_target + current_target = null + if(!target.can_action(game, src, "communion")) + return if(target) - to_chat(body,"You invoke spirit of [target.body.real_name] and learn their role was [target.name].") + to_chat(body,span_warning("You invoke spirit of [target.body.real_name] and learn their role was [target.name].")) add_note("N[game.turn] - [target.body.real_name] - [target.name]") - current_target = null /datum/mafia_role/md name = "Medical Doctor" desc = "You can protect a single person each night from killing." - revealed_outfit = /datum/outfit/mafia/md // /mafia <- outfit must be readded (just make a new mafia outfits file for all of these) + revealed_outfit = /datum/outfit/mafia/md role_type = TOWN_PROTECT hud_icon = "hudmedicaldoctor" revealed_icon = "medicaldoctor" @@ -271,29 +305,38 @@ . = ..() if(!.) return - if(target.name == "Head of Personnel" && target.revealed) + if((target.role_flags & ROLE_VULNERABLE) && (target.role_flags & ROLE_REVEALED)) //do not give the option to protect roles that your protection will fail on return FALSE return game.phase == MAFIA_PHASE_NIGHT && target.game_status == MAFIA_ALIVE && target != src /datum/mafia_role/md/handle_action(datum/mafia_controller/game,action,datum/mafia_role/target) if(!target || target.game_status != MAFIA_ALIVE) - to_chat(body,"You can only protect alive people.") + to_chat(body,span_warning("You can only protect alive people.")) return - to_chat(body,"You will protect [target.body.real_name] tonight.") + to_chat(body,span_warning("You will protect [target.body.real_name] tonight.")) current_protected = target /datum/mafia_role/md/proc/protect(datum/mafia_controller/game) SIGNAL_HANDLER - if(current_protected) - RegisterSignal(current_protected,COMSIG_MAFIA_ON_KILL,.proc/prevent_kill) - add_note("N[game.turn] - Protected [current_protected.body.real_name]") + if(!current_protected) + return + var/datum/mafia_role/target = current_protected + //current protected is unset at the end, as this action ends at a different phase + if(!target.can_action(game, src, "medical assistance")) + return -/datum/mafia_role/md/proc/prevent_kill(datum/source) + RegisterSignal(target,COMSIG_MAFIA_ON_KILL,.proc/prevent_kill) + add_note("N[game.turn] - Protected [target.body.real_name]") + +/datum/mafia_role/md/proc/prevent_kill(datum/source,datum/mafia_controller/game,datum/mafia_role/attacker,lynch) SIGNAL_HANDLER - to_chat(body,"The person you protected tonight was attacked!") - to_chat(current_protected.body,"You were attacked last night, but someone nursed you back to life!") + if((current_protected.role_flags & ROLE_VULNERABLE)) + to_chat(body,span_warning("The person you protected could not be saved.")) + return + to_chat(body,span_warning("The person you protected tonight was attacked!")) + to_chat(current_protected.body,span_greentext("You were attacked last night, but someone nursed you back to life!")) return MAFIA_PREVENT_KILL /datum/mafia_role/md/proc/end_protection(datum/mafia_controller/game) @@ -303,11 +346,77 @@ UnregisterSignal(current_protected,COMSIG_MAFIA_ON_KILL) current_protected = null +/datum/mafia_role/officer + name = "Security Officer" + desc = "You can protect a single person each night. If they are attacked, you will retaliate, killing yourself and the attacker." + revealed_outfit = /datum/outfit/mafia/security + revealed_icon = "securityofficer" + hud_icon = "hudsecurityofficer" + role_type = TOWN_PROTECT + role_flags = ROLE_CAN_KILL + winner_award = /datum/award/achievement/mafia/officer + + targeted_actions = list("Defend") + var/datum/mafia_role/current_defended + +/datum/mafia_role/officer/New(datum/mafia_controller/game) + . = ..() + RegisterSignal(game,COMSIG_MAFIA_NIGHT_ACTION_PHASE,.proc/defend) + RegisterSignal(game,COMSIG_MAFIA_NIGHT_END,.proc/end_defense) + +/datum/mafia_role/officer/validate_action_target(datum/mafia_controller/game,action,datum/mafia_role/target) + . = ..() + if(!.) + return + if((role_flags & ROLE_VULNERABLE) && (target.role_flags & ROLE_REVEALED)) //do not give the option to protect roles that your protection will fail on + return FALSE + return game.phase == MAFIA_PHASE_NIGHT && target.game_status == MAFIA_ALIVE && target != src + +/datum/mafia_role/officer/handle_action(datum/mafia_controller/game,action,datum/mafia_role/target) + if(!target || target.game_status != MAFIA_ALIVE) + to_chat(body,span_warning("You can only defend alive people.")) + return + to_chat(body,span_warning("You will defend [target.body.real_name] tonight.")) + current_defended = target + +/datum/mafia_role/officer/proc/defend(datum/mafia_controller/game) + SIGNAL_HANDLER + + if(!current_defended) + return + var/datum/mafia_role/target = current_defended + //current defended is unset at the end, as this action ends at a different phase + if(!target.can_action(game, src, "security patrol")) + return + if(target) + RegisterSignal(target,COMSIG_MAFIA_ON_KILL,.proc/retaliate) + add_note("N[game.turn] - Defended [target.body.real_name]") + +/datum/mafia_role/officer/proc/retaliate(datum/source,datum/mafia_controller/game,datum/mafia_role/attacker,lynch) + SIGNAL_HANDLER + + if((current_defended.role_flags & ROLE_VULNERABLE)) + to_chat(body,span_warning("The person you defended could not be saved. You could not attack the killer.")) + return + to_chat(body,span_userdanger("The person you defended tonight was attacked!")) + to_chat(current_defended.body,span_userdanger("You were attacked last night, but security fought off the attacker!")) + if(attacker.kill(game,src,FALSE)) //you attack the attacker + to_chat(attacker.body, span_userdanger("You have been ambushed by Security!")) + kill(game,attacker,FALSE) //the attacker attacks you, they were able to attack the target so they can attack you. + return MAFIA_PREVENT_KILL + +/datum/mafia_role/officer/proc/end_defense(datum/mafia_controller/game) + SIGNAL_HANDLER + + if(current_defended) + UnregisterSignal(current_defended,COMSIG_MAFIA_ON_KILL) + current_defended = null + /datum/mafia_role/lawyer name = "Lawyer" desc = "You can choose a person during the day to provide extensive legal advice to during the night, preventing night actions." revealed_outfit = /datum/outfit/mafia/lawyer - role_type = TOWN_PROTECT + role_type = TOWN_SUPPORT hud_icon = "hudlawyer" revealed_icon = "lawyer" winner_award = /datum/award/achievement/mafia/lawyer @@ -317,23 +426,30 @@ /datum/mafia_role/lawyer/New(datum/mafia_controller/game) . = ..() - RegisterSignal(game,COMSIG_MAFIA_SUNDOWN,.proc/roleblock_text) - RegisterSignal(game,COMSIG_MAFIA_NIGHT_START,.proc/try_to_roleblock) + RegisterSignal(game,COMSIG_MAFIA_SUNDOWN,.proc/roleblock) RegisterSignal(game,COMSIG_MAFIA_NIGHT_END,.proc/release) -/datum/mafia_role/lawyer/proc/roleblock_text(datum/mafia_controller/game) +/datum/mafia_role/lawyer/proc/roleblock(datum/mafia_controller/game) SIGNAL_HANDLER - if(SEND_SIGNAL(src,COMSIG_MAFIA_CAN_PERFORM_ACTION,game,"roleblock",current_target) & MAFIA_PREVENT_ACTION || game_status != MAFIA_ALIVE) //Got lynched or roleblocked by another lawyer. + if(!current_target) + return + + var/datum/mafia_role/target = current_target + if(!target.can_action(game, src, "roleblock")) //roleblocking a warden moment current_target = null - if(current_target) - to_chat(current_target.body,"YOU HAVE BEEN BLOCKED! YOU CANNOT PERFORM ANY ACTIONS TONIGHT.") - add_note("N[game.turn] - [current_target.body.real_name] - Blocked") + return + + to_chat(target.body,"YOU HAVE BEEN BLOCKED! YOU CANNOT PERFORM ANY ACTIONS TONIGHT.") + add_note("N[game.turn] - [target.body.real_name] - Blocked") + target.role_flags |= ROLE_ROLEBLOCKED /datum/mafia_role/lawyer/validate_action_target(datum/mafia_controller/game, action, datum/mafia_role/target) . = ..() if(!.) return FALSE + if(target == src) + return FALSE if(game.phase == MAFIA_PHASE_NIGHT) return FALSE if(target.game_status != MAFIA_ALIVE) @@ -343,53 +459,164 @@ . = ..() if(target == current_target) current_target = null - to_chat(body,"You have decided against blocking anyone tonight.") + to_chat(body,span_warning("You have decided against blocking anyone tonight.")) else current_target = target - to_chat(body,"You will block [target.body.real_name] tonight.") - -/datum/mafia_role/lawyer/proc/try_to_roleblock(datum/mafia_controller/game) - SIGNAL_HANDLER - - if(current_target) - RegisterSignal(current_target,COMSIG_MAFIA_CAN_PERFORM_ACTION, .proc/prevent_action) + to_chat(body,span_warning("You will block [target.body.real_name] tonight.")) /datum/mafia_role/lawyer/proc/release(datum/mafia_controller/game) SIGNAL_HANDLER . = ..() if(current_target) - UnregisterSignal(current_target, COMSIG_MAFIA_CAN_PERFORM_ACTION) + current_target.role_flags &= ~ROLE_ROLEBLOCKED current_target = null -/datum/mafia_role/lawyer/proc/prevent_action(datum/source) - SIGNAL_HANDLER - - if(game_status == MAFIA_ALIVE) //in case we got killed while imprisoning sk - bad luck edge - return MAFIA_PREVENT_ACTION - /datum/mafia_role/hop name = "Head of Personnel" desc = "You can reveal yourself once per game, tripling your vote power but becoming unable to be protected!" - revealed_outfit = /datum/outfit/mafia/hop - role_type = TOWN_MISC + role_type = TOWN_SUPPORT + role_flags = ROLE_UNIQUE hud_icon = "hudheadofpersonnel" revealed_icon = "headofpersonnel" + revealed_outfit = /datum/outfit/mafia/hop winner_award = /datum/award/achievement/mafia/hop targeted_actions = list("Reveal") + vote_potential = 3 /datum/mafia_role/hop/validate_action_target(datum/mafia_controller/game, action, datum/mafia_role/target) . = ..() - if(!. || game.phase == MAFIA_PHASE_NIGHT || game.turn == 1 || target.game_status != MAFIA_ALIVE || target != src || revealed) + if(!. || game.phase == MAFIA_PHASE_NIGHT || game.turn == 1 || target.game_status != MAFIA_ALIVE || target != src || (role_flags & ROLE_REVEALED)) return FALSE /datum/mafia_role/hop/handle_action(datum/mafia_controller/game, action, datum/mafia_role/target) . = ..() reveal_role(game, TRUE) - vote_power = 2 + role_flags |= ROLE_VULNERABLE + vote_power = 3 -///MAFIA ROLES/// only one until i rework this to allow more, they're the "anti-town" working to kill off townies to win +/datum/mafia_role/hos + name = "Head of Security" + desc = "You can decide to execute during the night, visiting someone killing, and revealing them. If they are innocent, you will die at the start of the next night." + role_type = TOWN_KILLING + role_flags = ROLE_CAN_KILL | ROLE_UNIQUE + revealed_outfit = /datum/outfit/mafia/hos + revealed_icon = "headofsecurity" + hud_icon = "hudheadofsecurity" + winner_award = /datum/award/achievement/mafia/hos + + targeted_actions = list("Execute") + var/datum/mafia_role/execute_target + +/datum/mafia_role/hos/New(datum/mafia_controller/game) + . = ..() + RegisterSignal(game,COMSIG_MAFIA_NIGHT_ACTION_PHASE,.proc/execute) + +/datum/mafia_role/hos/validate_action_target(datum/mafia_controller/game,action,datum/mafia_role/target) + . = ..() + if(!.) + return + return game.phase == MAFIA_PHASE_NIGHT && target.game_status == MAFIA_ALIVE && target != src + +/datum/mafia_role/hos/handle_action(datum/mafia_controller/game,action,datum/mafia_role/target) + if(execute_target == target) + to_chat(body,span_warning("You have decided against executing tonight.")) + to_chat(body,span_warning("You have decided to execute [target.body.real_name] tonight.")) + execute_target = target + +/datum/mafia_role/hos/proc/execute(datum/mafia_controller/game) + SIGNAL_HANDLER + + if(!execute_target) + return + var/datum/mafia_role/target = execute_target + execute_target = null + if(!target.can_action(game, src, "execution")) //roleblocking a warden moment + return + if(!target.kill(game,src,FALSE))//protection + to_chat(body,span_danger("Your attempt at executing [target.body.real_name] was prevented, or [target.body.real_name] is immune!")) + else + to_chat(target.body, span_userdanger("You have been executed by the Head of Security!")) + target.reveal_role(game, verbose = TRUE) + if(target.team == MAFIA_TEAM_TOWN) + to_chat(body,span_userdanger("You have killed an innocent crewmember. You will die tomorrow night.")) + RegisterSignal(game,COMSIG_MAFIA_SUNDOWN,.proc/internal_affairs) + role_flags |= ROLE_VULNERABLE + +/datum/mafia_role/hos/proc/internal_affairs(datum/mafia_controller/game) + to_chat(body,span_userdanger("You have been killed by Nanotrasen Internal Affairs!")) + reveal_role(game, verbose = TRUE) + kill(game,src,FALSE) //you technically kill yourself but that shouldn't matter + + +//just helps read better +#define WARDEN_NOT_LOCKDOWN 0//will NOT kill visitors tonight +#define WARDEN_WILL_LOCKDOWN 1 //will kill visitors tonight + +/datum/mafia_role/warden + name = "Warden" + desc = "You can lockdown during the night once, killing any visitors. WARNING: This kills fellow town members, too!" + + role_type = TOWN_KILLING + role_flags = ROLE_CAN_KILL + revealed_outfit = /datum/outfit/mafia/warden + revealed_icon = "warden" + hud_icon = "hudwarden" + winner_award = /datum/award/achievement/mafia/warden + + actions = list("Lockdown") + var/charges = 1 + var/protection_status = WARDEN_NOT_LOCKDOWN + + +/datum/mafia_role/warden/New(datum/mafia_controller/game) + . = ..() + RegisterSignal(game,COMSIG_MAFIA_SUNDOWN,.proc/night_start) + RegisterSignal(game,COMSIG_MAFIA_NIGHT_END,.proc/night_end) + +/datum/mafia_role/warden/handle_action(datum/mafia_controller/game, action, datum/mafia_role/target) + . = ..() + if(!charges) + to_chat(body,span_danger("You've already locked down this game!")) + return + if(game.phase == MAFIA_PHASE_NIGHT) + to_chat(body,span_danger("You don't have time to lockdown, night has already arrived.")) + return + if(protection_status == WARDEN_WILL_LOCKDOWN) + to_chat(body,span_danger("You decide to not lockdown tonight.")) + else + to_chat(body,span_danger("You decide to lockdown, killing any visitors.")) + protection_status = !protection_status + +/datum/mafia_role/warden/proc/night_start(datum/mafia_controller/game) + SIGNAL_HANDLER + + if(protection_status == WARDEN_WILL_LOCKDOWN) + to_chat(body,span_danger("Any and all visitors are going to eat buckshot tonight.")) + RegisterSignal(src,COMSIG_MAFIA_ON_VISIT,.proc/self_defense) + +/datum/mafia_role/warden/proc/night_end(datum/mafia_controller/game) + SIGNAL_HANDLER + + if(protection_status == WARDEN_WILL_LOCKDOWN) + charges-- + UnregisterSignal(src,COMSIG_MAFIA_ON_KILL) + to_chat(body,span_danger("You are no longer protected. You have used up your power.")) + protection_status = WARDEN_NOT_LOCKDOWN + +/datum/mafia_role/warden/proc/self_defense(datum/source,datum/mafia_controller/game,datum/mafia_role/attacker,lynch) + SIGNAL_HANDLER + + to_chat(body,span_userdanger("You have shot a visitor!")) + to_chat(attacker,span_userdanger("You have visited the warden!")) + attacker.kill(game, src, lynch = FALSE) + return MAFIA_VISIT_INTERRUPTED + +#undef WARDEN_NOT_LOCKDOWN +#undef WARDEN_WILL_LOCKDOWN + +///MAFIA ROLES/// they're the "anti-town" working to kill off townies to win /datum/mafia_role/mafia name = "Changeling" @@ -436,7 +663,7 @@ return game.phase == MAFIA_PHASE_NIGHT && target.game_status == MAFIA_ALIVE && target != src /datum/mafia_role/mafia/thoughtfeeder/handle_action(datum/mafia_controller/game,action,datum/mafia_role/target) - to_chat(body,"You will feast on the memories of [target.body.real_name] tonight.") + to_chat(body,span_warning("You will feast on the memories of [target.body.real_name] tonight.")) current_investigation = target /datum/mafia_role/mafia/thoughtfeeder/proc/investigate(datum/mafia_controller/game) @@ -444,18 +671,15 @@ var/datum/mafia_role/target = current_investigation current_investigation = null - if(SEND_SIGNAL(src,COMSIG_MAFIA_CAN_PERFORM_ACTION,game,"thoughtfeed",target) & MAFIA_PREVENT_ACTION) - to_chat(body,"You were unable to investigate [target.body.real_name].") + if(!target.can_action(game, src, "thought feeding")) add_note("N[game.turn] - [target.body.real_name] - Unable to investigate") return - if(target) - if(target.detect_immune) - to_chat(body,"[target.body.real_name]'s memories reveal that they are the Assistant.") - add_note("N[game.turn] - [target.body.real_name] - Assistant") - else - to_chat(body,"[target.body.real_name]'s memories reveal that they are the [target.name].") - add_note("N[game.turn] - [target.body.real_name] - [target.name]") - + if((target.role_flags & ROLE_UNDETECTABLE)) + to_chat(body,span_warning("[target.body.real_name]'s memories reveal that they are the Assistant.")) + add_note("N[game.turn] - [target.body.real_name] - Assistant") + else + to_chat(body,span_warning("[target.body.real_name]'s memories reveal that they are the [target.name].")) + add_note("N[game.turn] - [target.body.real_name] - [target.name]") ///SOLO ROLES/// they range from anomalous factors to deranged killers that try to win alone. @@ -465,15 +689,14 @@ win_condition = "kill everyone." team = MAFIA_TEAM_SOLO role_type = NEUTRAL_KILL + role_flags = ROLE_CAN_KILL winner_award = /datum/award/achievement/mafia/traitor - - targeted_actions = list("Night Kill") revealed_outfit = /datum/outfit/mafia/traitor - - hud_icon = "hudtraitor" revealed_icon = "traitor" + hud_icon = "hudtraitor" special_theme = "neutral" + targeted_actions = list("Night Kill") var/datum/mafia_role/current_victim /datum/mafia_role/traitor/New(datum/mafia_controller/game) @@ -481,17 +704,17 @@ RegisterSignal(src,COMSIG_MAFIA_ON_KILL,.proc/nightkill_immunity) RegisterSignal(game,COMSIG_MAFIA_NIGHT_KILL_PHASE,.proc/try_to_kill) -/datum/mafia_role/traitor/check_total_victory(alive_town, alive_mafia) //serial killers just want teams dead +/datum/mafia_role/traitor/check_total_victory(alive_town, alive_mafia) //serial killers just want teams dead, they cannot be stopped by killing roles anyways return alive_town + alive_mafia <= 1 /datum/mafia_role/traitor/block_team_victory(alive_town, alive_mafia) //no team can win until they're dead return TRUE //while alive, town AND mafia cannot win (though since mafia know who is who it's pretty easy to win from that point) -/datum/mafia_role/traitor/proc/nightkill_immunity(datum/source,datum/mafia_controller/game,lynch) +/datum/mafia_role/traitor/proc/nightkill_immunity(datum/source,datum/mafia_controller/game,datum/mafia_role/attacker,lynch) SIGNAL_HANDLER if(game.phase == MAFIA_PHASE_NIGHT && !lynch) - to_chat(body,"You were attacked, but they'll have to try harder than that to put you down.") + to_chat(body,span_userdanger("You were attacked, but they'll have to try harder than that to put you down.")) return MAFIA_PREVENT_KILL /datum/mafia_role/traitor/validate_action_target(datum/mafia_controller/game, action, datum/mafia_role/target) @@ -504,25 +727,29 @@ /datum/mafia_role/traitor/handle_action(datum/mafia_controller/game, action, datum/mafia_role/target) . = ..() current_victim = target - to_chat(body,"You will attempt to kill [target.body.real_name] tonight.") + to_chat(body,span_warning("You will attempt to kill [target.body.real_name] tonight.")) -/datum/mafia_role/traitor/proc/try_to_kill(datum/mafia_controller/source) - // SIGNAL_HANDLER +/datum/mafia_role/traitor/proc/try_to_kill(datum/mafia_controller/game) + SIGNAL_HANDLER + if(!current_victim) + return var/datum/mafia_role/target = current_victim current_victim = null - if(SEND_SIGNAL(src,COMSIG_MAFIA_CAN_PERFORM_ACTION,source,"traitor kill",target) & MAFIA_PREVENT_ACTION) + if(!target.can_action(game, src, "flickering")) //flickering a warden return - if(game_status == MAFIA_ALIVE && target && target.game_status == MAFIA_ALIVE) - if(!target.kill(source)) - to_chat(body,"Your attempt at killing [target.body] was prevented!") + if(game_status == MAFIA_ALIVE) + if(!target.kill(game,src,FALSE)) + to_chat(body,span_danger("Your attempt at killing [target.body.real_name] was prevented!")) + else + to_chat(target.body, span_userdanger("You have been killed by a Traitor!")) /datum/mafia_role/nightmare name = "Nightmare" - desc = "You're a solo monster that cannot be detected by detective roles. You can flicker lights of another room each night. You can instead decide to hunt, killing everyone in a flickering room. Kill everyone to win." + desc = "You're a solo monster that cannot be detected by detective roles. You can flicker lights of another room each night, becoming immune to attacks from those roles. You can instead decide to hunt, killing everyone in a flickering room. Kill everyone to win." win_condition = "kill everyone." revealed_outfit = /datum/outfit/mafia/nightmare - detect_immune = TRUE + role_flags = ROLE_UNDETECTABLE | ROLE_CAN_KILL team = MAFIA_TEAM_SOLO role_type = NEUTRAL_KILL special_theme = "neutral" @@ -536,6 +763,7 @@ /datum/mafia_role/nightmare/New(datum/mafia_controller/game) . = ..() + RegisterSignal(src,COMSIG_MAFIA_ON_KILL,.proc/flickering_immunity) RegisterSignal(game,COMSIG_MAFIA_NIGHT_KILL_PHASE,.proc/flicker_or_hunt) /datum/mafia_role/nightmare/check_total_victory(alive_town, alive_mafia) //nightmares just want teams dead @@ -562,33 +790,42 @@ /datum/mafia_role/nightmare/handle_action(datum/mafia_controller/game, action, datum/mafia_role/target) . = ..() if(target == flicker_target) - to_chat(body,"You will do nothing tonight.") + to_chat(body,span_warning("You will do nothing tonight.")) flicker_target = null flicker_target = target if(action == "Flicker") - to_chat(body,"You will attempt to flicker [target.body.real_name]'s room tonight.") + to_chat(body,span_warning("You will attempt to flicker [target.body.real_name]'s room tonight.")) else - to_chat(body,"You will hunt everyone in a flickering room down tonight.") + to_chat(body,span_danger("You will hunt everyone in a flickering room down tonight.")) -/datum/mafia_role/nightmare/proc/flicker_or_hunt(datum/mafia_controller/source) - // SIGNAL_HANDLER +/datum/mafia_role/nightmare/proc/flickering_immunity(datum/source,datum/mafia_controller/game,datum/mafia_role/attacker,lynch) + SIGNAL_HANDLER + if(!attacker) + return //no chance man, that's a town lynch - if(game_status != MAFIA_ALIVE || !flicker_target) - return - if(SEND_SIGNAL(src,COMSIG_MAFIA_CAN_PERFORM_ACTION,source,"nightmare actions",flicker_target) & MAFIA_PREVENT_ACTION) - to_chat(flicker_target.body, "Your actions were prevented!") + if(attacker in flickering) + to_chat(body,span_userdanger("You were attacked by someone in a flickering room. You have danced in the shadows, evading them.")) + return MAFIA_PREVENT_KILL + +/datum/mafia_role/nightmare/proc/flicker_or_hunt(datum/mafia_controller/game) + SIGNAL_HANDLER + + if(!flicker_target) return var/datum/mafia_role/target = flicker_target flicker_target = null + if(!target.can_action(game, src, "flickering")) //flickering a warden + return + if(target != src) //flicker instead of hunt - to_chat(target.body, "The lights begin to flicker and dim. You're in danger.") + to_chat(target.body, span_userdanger("The lights begin to flicker and dim. You're in danger.")) flickering += target return for(var/r in flickering) var/datum/mafia_role/role = r if(role && role.game_status == MAFIA_ALIVE) - to_chat(role.body, "A shadowy monster appears out of the darkness!") - role.kill(source) + to_chat(role.body, span_userdanger("A shadowy figure appears out of the darkness!")) + role.kill(game,src,FALSE) flickering -= role //just helps read better @@ -599,7 +836,6 @@ name = "Fugitive" desc = "You're on the run. You can become immune to night kills exactly twice, and you win by surviving to the end of the game with anyone." win_condition = "survive to the end of the game, with anyone" - solo_counts_as_town = TRUE //should not count towards mafia victory, they should have the option to work with town revealed_outfit = /datum/outfit/mafia/fugitive team = MAFIA_TEAM_SOLO role_type = NEUTRAL_DISRUPT @@ -622,22 +858,22 @@ /datum/mafia_role/fugitive/handle_action(datum/mafia_controller/game, action, datum/mafia_role/target) . = ..() if(!charges) - to_chat(body,"You're out of supplies and cannot protect yourself anymore.") + to_chat(body,span_danger("You're out of supplies and cannot protect yourself anymore.")) return if(game.phase == MAFIA_PHASE_NIGHT) - to_chat(body,"You don't have time to prepare, night has already arrived.") + to_chat(body,span_danger("You don't have time to prepare, night has already arrived.")) return if(protection_status == FUGITIVE_WILL_PRESERVE) - to_chat(body,"You decide to not prepare tonight.") + to_chat(body,span_danger("You decide to not prepare tonight.")) else - to_chat(body,"You decide to prepare for a horrible night.") + to_chat(body,span_danger("You decide to prepare for a horrible night.")) protection_status = !protection_status /datum/mafia_role/fugitive/proc/night_start(datum/mafia_controller/game) SIGNAL_HANDLER if(protection_status == FUGITIVE_WILL_PRESERVE) - to_chat(body,"Your preparations are complete. Nothing could kill you tonight!") + to_chat(body,span_danger("Your preparations are complete. Nothing could kill you tonight!")) RegisterSignal(src,COMSIG_MAFIA_ON_KILL,.proc/prevent_death) /datum/mafia_role/fugitive/proc/night_end(datum/mafia_controller/game) @@ -646,13 +882,13 @@ if(protection_status == FUGITIVE_WILL_PRESERVE) charges-- UnregisterSignal(src,COMSIG_MAFIA_ON_KILL) - to_chat(body,"You are no longer protected. You have [charges] use[charges == 1 ? "" : "s"] left of your power.") + to_chat(body,span_danger("You are no longer protected. You have [charges] use[charges == 1 ? "" : "s"] left of your power.")) protection_status = FUGITIVE_NOT_PRESERVING -/datum/mafia_role/fugitive/proc/prevent_death(datum/mafia_controller/game) +/datum/mafia_role/fugitive/proc/prevent_death(datum/source,datum/mafia_controller/game,datum/mafia_role/attacker,lynch) SIGNAL_HANDLER - to_chat(body,"You were attacked! Luckily, you were ready for this!") + to_chat(body,span_userdanger("You were attacked! Luckily, you were ready for this!")) return MAFIA_PREVENT_KILL /datum/mafia_role/fugitive/proc/survived(datum/mafia_controller/game) @@ -669,8 +905,7 @@ name = "Obsessed" desc = "You're completely lost in your own mind. You win by lynching your obsession before you get killed in this mess. Obsession assigned on the first night!" win_condition = "lynch their obsession." - revealed_outfit = /datum/outfit/mafia/obsessed // /mafia <- outfit must be readded (just make a new mafia outfits file for all of these) - solo_counts_as_town = TRUE //after winning or whatever, can side with whoever. they've already done their objective! + revealed_outfit = /datum/outfit/mafia/obsessed team = MAFIA_TEAM_SOLO role_type = NEUTRAL_DISRUPT special_theme = "neutral" @@ -678,9 +913,6 @@ revealed_icon = "obsessed" winner_award = /datum/award/achievement/mafia/obsessed - - revealed_outfit = /datum/outfit/mafia/obsessed // /mafia <- outfit must be readded (just make a new mafia outfits file for all of these) - solo_counts_as_town = TRUE //after winning or whatever, can side with whoever. they've already done their objective! var/datum/mafia_role/obsession var/lynched_target = FALSE @@ -700,12 +932,12 @@ if(!obsession) obsession = pick(all_roles_shuffle) //okay no town just pick anyone here //if you still don't have an obsession you're playing a single player game like i can't help your dumb ass - to_chat(body, "Your obsession is [obsession.body.real_name]! Get them lynched to win!") + to_chat(body, span_userdanger("Your obsession is [obsession.body.real_name]! Get them lynched to win!")) add_note("N[game.turn] - I vowed to watch my obsession, [obsession.body.real_name], hang!") //it'll always be N1 but whatever RegisterSignal(obsession,COMSIG_MAFIA_ON_KILL,.proc/check_victory) UnregisterSignal(game,COMSIG_MAFIA_SUNDOWN) -/datum/mafia_role/obsessed/proc/check_victory(datum/source,datum/mafia_controller/game,lynch) +/datum/mafia_role/obsessed/proc/check_victory(datum/source,datum/mafia_controller/game,datum/mafia_role/attacker,lynch) SIGNAL_HANDLER UnregisterSignal(source,COMSIG_MAFIA_ON_KILL) @@ -716,14 +948,13 @@ game.award_role(winner_award, src) reveal_role(game, FALSE) else - to_chat(body, "You have failed your objective to lynch [obsession.body]!") + to_chat(body, span_userdanger("You have failed your objective to lynch [obsession.body.real_name]!")) /datum/mafia_role/clown name = "Clown" desc = "If you are lynched you take down one of your voters (guilty or abstain) with you and win. HONK!" win_condition = "get themselves lynched!" revealed_outfit = /datum/outfit/mafia/clown - solo_counts_as_town = TRUE team = MAFIA_TEAM_SOLO role_type = NEUTRAL_DISRUPT special_theme = "neutral" @@ -735,8 +966,8 @@ . = ..() RegisterSignal(src,COMSIG_MAFIA_ON_KILL,.proc/prank) -/datum/mafia_role/clown/proc/prank(datum/source,datum/mafia_controller/game,lynch) - // SIGNAL_HANDLER +/datum/mafia_role/clown/proc/prank(datum/source,datum/mafia_controller/game,datum/mafia_role/attacker,lynch) + SIGNAL_HANDLER if(lynch) var/datum/mafia_role/victim = pick(game.judgement_guilty_votes + game.judgement_abstain_votes) diff --git a/code/modules/mapexporting/mapexporter.dm b/code/modules/mapexporting/mapexporter.dm new file mode 100644 index 0000000000..d21caa0f6c --- /dev/null +++ b/code/modules/mapexporting/mapexporter.dm @@ -0,0 +1,184 @@ +//Map exporter +//Inputting a list of turfs into convert_map_to_tgm() will output a string +//with the turfs and their objects / areas on said turf into the TGM mapping format +//for .dmm files. This file can then be opened in the map editor or imported +//back into the game. +//============================ +//This has been made semi-modular so you should be able to use these functions +//elsewhere in code if you ever need to get a file in the .dmm format +/atom/proc/get_save_vars() + return + +GLOBAL_LIST_INIT(save_file_chars, list( + "a","b","c","d","e", + "f","g","h","i","j", + "k","l","m","n","o", + "p","q","r","s","t", + "u","v","w","x","y", + "z","A","B","C","D", + "E","F","G","H","I", + "J","K","L","M","N", + "O","P","Q","R","S", + "T","U","V","W","X", + "Y","Z" +)) + +//Converts a list of turfs into TGM file format +/proc/convert_map_to_tgm(list/map,\ + save_flag = SAVE_ALL, \ + shuttle_area_flag = SAVE_SHUTTLEAREA_DONTCARE, \ + list/vars_to_save = list("pixel_x", "pixel_y", "dir", "name", "req_access", "req_access_txt", "piping_layer", "color", "icon_state", "pipe_color", "amount"),\ + list/obj_blacklist = list()) + //Calculate the bounds + var/minx = 1024 + var/miny = 1024 + var/maxx = -1 + var/maxy = -1 + for(var/turf/place in map) + minx = min(place.x, minx) + miny = min(place.y, miny) + maxx = max(place.x, maxx) + maxy = max(place.y, maxy) + var/width = maxx - minx + 1 + var/height = maxy - miny + 1 + + //Sort the map so weird shaped / bad inputted maps can be handled + var/list/sortedmap = sort_map(map, minx, miny, maxx, maxy) + + //Step 0: Calculate the amount of letters we need (26 ^ n > turf count) + var/turfsNeeded = width * height + var/layers = FLOOR(log(GLOB.save_file_chars.len, turfsNeeded) + 0.999,1) + + //Step 1: Run through the area and generate file data + var/list/header_chars = list() //The characters of the header + var/list/header_dat = list() //The data of the header, lines up with chars + var/header = "" //The actual header in text + var/contents = "" //The contents in text (bit at the end) + var/index = 1 + for(var/x in 1 to width) + contents += "\n([x],1,1) = {\"\n" + for(var/y in height to 1 step -1) + //====Get turfs Data==== + var/turf/place = sortedmap[x][y] + var/area/location + var/list/objects + //If there is nothing there, save as a noop (For odd shapes) + if(!place) + place = /turf/template_noop + location = /area/template_noop + objects = list() + //Ignore things in space, must be a space turf and the area has to be empty space + else if(istype(place, /turf/open/space) && istype(get_area(place), /area/space) && !(save_flag & SAVE_SPACE)) + place = /turf/template_noop + location = /area/template_noop + //Stuff to add + else + var/area/location_type = get_area(place) + location = location_type.type + objects = place + place = place.type + //====Saving shuttles only / non shuttles only==== + var/is_shuttle_area = istype(location, /area/shuttle) + if((is_shuttle_area && shuttle_area_flag == SAVE_SHUTTLEAREA_IGNORE) || (!is_shuttle_area && shuttle_area_flag == SAVE_SHUTTLEAREA_ONLY)) + place = /turf/template_noop + location = /area/template_noop + objects = list() + //====For toggling not saving areas and turfs==== + if(!(save_flag & SAVE_AREAS)) + location = /area/template_noop + if(!(save_flag & SAVE_TURFS)) + place = /turf/template_noop + //====Generate Header Character==== + var/header_char = calculate_tgm_header_index(index, layers) //The characters of the header + var/current_header = "(\n" //The actual stuff inside the header + //Add objects to the header file + var/empty = TRUE + //====SAVING OBJECTS==== + if(save_flag & SAVE_OBJECTS) + for(var/obj/thing in objects) + if(thing.type in obj_blacklist) + continue + var/metadata = generate_tgm_metadata(thing, vars_to_save) + current_header += "[empty?"":",\n"][thing.type][metadata]" + empty = FALSE + //====SAVING SPECIAL DATA==== + //This is what causes lockers and machines to save stuff inside of them + if(save_flag & SAVE_OBJECT_PROPERTIES) + var/custom_data = thing.on_object_saved() + current_header += "[custom_data ? ",\n[custom_data]" : ""]" + //====SAVING MOBS==== + if(save_flag & SAVE_MOBS) + for(var/mob/living/thing in objects) + if(istype(thing, /mob/living/carbon)) //Ignore people, but not animals + continue + var/metadata = generate_tgm_metadata(thing, vars_to_save) + current_header += "[empty?"":",\n"][thing.type][metadata]" + empty = FALSE + current_header += "[empty?"":",\n"][place],\n[location])\n" + //====Fill the contents file==== + //Compression is done here + var/position_of_header = header_dat.Find(current_header) + if(position_of_header) + //If the header has already been saved, change the character to the other saved header + header_char = header_chars[position_of_header] + else + header += "\"[header_char]\" = [current_header]" + header_chars += header_char + header_dat += current_header + index ++ + contents += "[header_char]\n" + contents += "\"}" + return "[header][contents]" + +//Sorts maps in terms of their positions, so scrambled / odd shaped maps can be saved +/proc/sort_map(list/map, minx, miny, maxx, maxy) + var/width = maxx - minx + 1 + var/height = maxy - miny + 1 + var/allTurfs = new/list(width, height) + for(var/turf/place in map) + allTurfs[place.x - minx + 1][place.y - miny + 1] = place + return allTurfs + +//vars_to_save = list() to save all vars +/proc/generate_tgm_metadata(atom/O, list/vars_to_save = list("pixel_x", "pixel_y", "dir", "name", "req_access", "req_access_txt", "piping_layer", "color", "icon_state", "pipe_color", "amount")) + var/dat = "" + var/data_to_add = list() + for(var/V in O.vars) + if(O.get_save_vars()) + if(!(V in O.get_save_vars())) + continue + else + if(!(V in vars_to_save) && vars_to_save) + continue + var/value = O.vars[V] + if(!value) + continue + if(value == initial(O.vars[V]) || !issaved(O.vars[V])) + continue + var/symbol = "" + if(istext(value)) + symbol = "\"" + value = sanitize_simple(value, list("{"="", "}"="", "\""="", ";"="", ","="")) + else if(isicon(value) || isfile(value)) + symbol = "'" + else if(!(isnum(value) || ispath(value))) + continue + //Prevent symbols from being because otherwise you can name something [";},/obj/item/gun/energy/laser/instakill{name="da epic gun] and spawn yourself an instakill gun. + data_to_add += "[V] = [symbol][value][symbol]" + //Process data to add + var/first = TRUE + for(var/data in data_to_add) + dat += "[first ? "" : ";\n"]\t[data]" + first = FALSE + if(dat) + dat = "{\n[dat]\n\t}" + return dat + +/proc/calculate_tgm_header_index(index, layers) + var/output = "" + for(var/i in 1 to layers) + var/l = GLOB.save_file_chars.len + var/c = FLOOR((index-1) / (l ** (i - 1)), 1) + c = (c % l) + 1 + output = "[GLOB.save_file_chars[c]][output]" + return output diff --git a/code/modules/mapping/map_config.dm b/code/modules/mapping/map_config.dm index 1f4b558e21..b690419ade 100644 --- a/code/modules/mapping/map_config.dm +++ b/code/modules/mapping/map_config.dm @@ -30,8 +30,6 @@ var/maptype = MAP_TYPE_STATION //This should be used to adjust ingame behavior depending on the specific type of map being played. For instance, if an overmap were added, it'd be appropriate for it to only generate with a MAP_TYPE_SHIP - var/announcertype = "standard" //Determines the announcer the map uses. standard uses the default announcer, classic, but has a random chance to use other similarly-themed announcers, like medibot - var/allow_custom_shuttles = TRUE var/shuttles = list( "cargo" = "cargo_box", @@ -178,9 +176,6 @@ if ("maptype" in json) maptype = json["maptype"] - if ("announcertype" in json) - announcertype = json["announcertype"] - if ("orientation" in json) orientation = json["orientation"] if(!(orientation in GLOB.cardinals)) @@ -277,7 +272,6 @@ jsonlist["year_offset"] = year_offset jsonlist["minetype"] = minetype jsonlist["maptype"] = maptype - jsonlist["announcertype"] = announcertype jsonlist["orientation"] = orientation jsonlist["allow_custom_shuttles"] = allow_custom_shuttles jsonlist["job_whitelist"] = job_whitelist diff --git a/code/modules/mapping/mapping_helpers/_mapping_helpers.dm b/code/modules/mapping/mapping_helpers/_mapping_helpers.dm index 4de16ba350..7bb281e5d9 100644 --- a/code/modules/mapping/mapping_helpers/_mapping_helpers.dm +++ b/code/modules/mapping/mapping_helpers/_mapping_helpers.dm @@ -4,65 +4,77 @@ icon_state = "" var/late = FALSE -/obj/effect/mapping_helpers/Initialize() +/obj/effect/mapping_helpers/Initialize(mapload) ..() return late ? INITIALIZE_HINT_LATELOAD : INITIALIZE_HINT_QDEL + //airlock helpers /obj/effect/mapping_helpers/airlock layer = DOOR_HELPER_LAYER -/obj/effect/mapping_helpers/airlock/cyclelink_helper - name = "airlock cyclelink helper" - icon_state = "airlock_cyclelink_helper" - -/obj/effect/mapping_helpers/airlock/cyclelink_helper/Initialize(mapload) +/obj/effect/mapping_helpers/airlock/Initialize(mapload) . = ..() if(!mapload) log_mapping("[src] spawned outside of mapload!") return var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in loc - if(airlock) - if(airlock.cyclelinkeddir) - log_mapping("[src] at [AREACOORD(src)] tried to set [airlock] cyclelinkeddir, but it's already set!") - else - airlock.cyclelinkeddir = dir - else + if(!airlock) log_mapping("[src] failed to find an airlock at [AREACOORD(src)]") + else + payload(airlock) +/obj/effect/mapping_helpers/airlock/proc/payload(obj/machinery/door/airlock/payload) + return + +/obj/effect/mapping_helpers/airlock/cyclelink_helper + name = "airlock cyclelink helper" + icon_state = "airlock_cyclelink_helper" + +/obj/effect/mapping_helpers/airlock/cyclelink_helper/payload(obj/machinery/door/airlock/airlock) + if(airlock.cyclelinkeddir) + log_mapping("[src] at [AREACOORD(src)] tried to set [airlock] cyclelinkeddir, but it's already set!") + else + airlock.cyclelinkeddir = dir + +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi + name = "airlock multi-cyclelink helper" + icon_state = "airlock_multicyclelink_helper" + var/cycle_id + +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi/payload(obj/machinery/door/airlock/airlock) + if(airlock.closeOtherId) + log_mapping("[src] at [AREACOORD(src)] tried to set [airlock] closeOtherId, but it's already set!") + else + airlock.closeOtherId = cycle_id /obj/effect/mapping_helpers/airlock/locked name = "airlock lock helper" icon_state = "airlock_locked_helper" -/obj/effect/mapping_helpers/airlock/locked/Initialize(mapload) - . = ..() - if(!mapload) - log_mapping("[src] spawned outside of mapload!") - return - var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in loc - if(airlock) - if(airlock.locked) - log_mapping("[src] at [AREACOORD(src)] tried to bolt [airlock] but it's already locked!") - else - airlock.locked = TRUE +/obj/effect/mapping_helpers/airlock/locked/payload(obj/machinery/door/airlock/airlock) + if(airlock.locked) + log_mapping("[src] at [AREACOORD(src)] tried to bolt [airlock] but it's already locked!") else - log_mapping("[src] failed to find an airlock at [AREACOORD(src)]") + airlock.locked = TRUE + /obj/effect/mapping_helpers/airlock/unres name = "airlock unresctricted side helper" icon_state = "airlock_unres_helper" -/obj/effect/mapping_helpers/airlock/unres/Initialize(mapload) - . = ..() - if(!mapload) - log_mapping("[src] spawned outside of mapload!") - return - var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in loc - if(airlock) - airlock.unres_sides ^= dir +/obj/effect/mapping_helpers/airlock/unres/payload(obj/machinery/door/airlock/airlock) + airlock.unres_sides ^= dir + +/obj/effect/mapping_helpers/airlock/abandoned + name = "airlock abandoned helper" + icon_state = "airlock_abandoned" + +/obj/effect/mapping_helpers/airlock/abandoned/payload(obj/machinery/door/airlock/airlock) + if(airlock.abandoned) + log_mapping("[src] at [AREACOORD(src)] tried to make [airlock] abandoned but it's already abandoned!") else - log_mapping("[src] failed to find an airlock at [AREACOORD(src)]") + airlock.abandoned = TRUE //needs to do its thing before spawn_rivers() is called @@ -71,7 +83,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava) /obj/effect/mapping_helpers/no_lava icon_state = "no_lava" -/obj/effect/mapping_helpers/no_lava/Initialize() +/obj/effect/mapping_helpers/no_lava/Initialize(mapload) . = ..() var/turf/T = get_turf(src) T.flags_1 |= NO_LAVA_GEN_1 @@ -79,9 +91,11 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava) //This helper applies components to things on the map directly. /obj/effect/mapping_helpers/component_injector name = "Component Injector" + icon_state = "component" late = TRUE - var/target_type - var/target_name + var/all = FALSE //Will inject into all fitting the criteria if true, otherwise first found + var/target_type //Will inject into atoms of this type + var/target_name //Will inject into atoms with this name var/component_type //Late init so everything is likely ready and loaded (no warranty) @@ -98,8 +112,11 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava) continue var/cargs = build_args() A._AddComponent(cargs) + if(!all) + qdel(src) + return + if(all) qdel(src) - return /obj/effect/mapping_helpers/component_injector/proc/build_args() return list(component_type) @@ -115,3 +132,276 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava) CRASH("Wrong disease type passed in.") var/datum/disease/D = new disease_type() return list(component_type,D) + +// /obj/effect/mapping_helpers/component_injector/areabound +// name = "Areabound Injector" +// icon_state = "component_areabound" +// component_type = /datum/component/areabound +// target_type = /atom/movable + +/obj/effect/mapping_helpers/dead_body_placer + name = "Dead Body placer" + late = TRUE + icon_state = "deadbodyplacer" + var/bodycount = 2 //number of bodies to spawn + +/obj/effect/mapping_helpers/dead_body_placer/LateInitialize() + var/area/a = get_area(src) + var/list/trays = list() + for (var/i in a.contents) + if (istype(i, /obj/structure/bodycontainer/morgue)) + trays += i + if(!trays.len) + log_mapping("[src] at [x],[y] could not find any morgues.") + return + for (var/i = 1 to bodycount) + var/obj/structure/bodycontainer/morgue/j = pick(trays) + var/mob/living/carbon/human/h = new /mob/living/carbon/human(j, 1) + h.death() + for (var/part in h.internal_organs) //randomly remove organs from each body, set those we keep to be in stasis + if (prob(40)) + qdel(part) + else + var/obj/item/organ/O = part + O.organ_flags |= ORGAN_FROZEN + j.update_appearance() + qdel(src) + + +//On Ian's birthday, the hop's office is decorated. +/obj/effect/mapping_helpers/ianbirthday + name = "Ian's Bday Helper" + late = TRUE + icon_state = "iansbdayhelper" + var/balloon_clusters = 2 + +/obj/effect/mapping_helpers/ianbirthday/LateInitialize() + if(locate(/datum/holiday/ianbirthday) in SSevents.holidays) + birthday() + qdel(src) + +/obj/effect/mapping_helpers/ianbirthday/proc/birthday() + var/area/a = get_area(src) + var/list/table = list()//should only be one aka the front desk, but just in case... + var/list/openturfs = list() + + //confetti and a corgi balloon! (and some list stuff for more decorations) + for(var/thing in a.contents) + if(istype(thing, /obj/structure/table/reinforced)) + table += thing + if(isopenturf(thing)) + // new /obj/effect/decal/cleanable/confetti(thing) + // if(locate(/obj/structure/bed/dogbed/ian) in thing) + // new /obj/item/toy/balloon/corgi(thing) + // else + openturfs += thing + + //cake + knife to cut it! + if(length(table)) + var/turf/food_turf = get_turf(pick(table)) + new /obj/item/kitchen/knife(food_turf) + var/obj/item/reagent_containers/food/snacks/store/cake/birthday/iancake = new(food_turf) + iancake.desc = "Happy birthday, Ian!" + // remind me to give ian proper baloons! + //some balloons! this picks an open turf and pops a few balloons in and around that turf, yay. + // for(var/i in 1 to balloon_clusters) + // var/turf/clusterspot = pick_n_take(openturfs) + // new /obj/item/toy/balloon(clusterspot) + // var/balloons_left_to_give = 3 //the amount of balloons around the cluster + // var/list/dirs_to_balloon = GLOB.cardinals.Copy() + // while(balloons_left_to_give > 0) + // balloons_left_to_give-- + // var/chosen_dir = pick_n_take(dirs_to_balloon) + // var/turf/balloonstep = get_step(clusterspot, chosen_dir) + // var/placed = FALSE + // if(isopenturf(balloonstep)) + // var/obj/item/toy/balloon/B = new(balloonstep)//this clumps the cluster together + // placed = TRUE + // if(chosen_dir == NORTH) + // B.pixel_y -= 10 + // if(chosen_dir == SOUTH) + // B.pixel_y += 10 + // if(chosen_dir == EAST) + // B.pixel_x -= 10 + // if(chosen_dir == WEST) + // B.pixel_x += 10 + // if(!placed) + // new /obj/item/toy/balloon(clusterspot) + //remind me to add wall decor! + +/obj/effect/mapping_helpers/ianbirthday/admin//so admins may birthday any room + name = "generic birthday setup" + icon_state = "bdayhelper" + +/obj/effect/mapping_helpers/ianbirthday/admin/LateInitialize() + birthday() + qdel(src) + +//Ian, like most dogs, loves a good new years eve party. +/obj/effect/mapping_helpers/iannewyear + name = "Ian's New Years Helper" + late = TRUE + icon_state = "iansnewyrshelper" + +/obj/effect/mapping_helpers/iannewyear/LateInitialize() + if(SSevents.holidays && SSevents.holidays[NEW_YEAR]) + fireworks() + qdel(src) + +/obj/effect/mapping_helpers/iannewyear/proc/fireworks() + var/area/a = get_area(src) + var/list/table = list()//should only be one aka the front desk, but just in case... + var/list/openturfs = list() + + for(var/thing in a.contents) + if(istype(thing, /obj/structure/table/reinforced)) + table += thing + else if(isopenturf(thing)) + if(locate(/obj/structure/bed/dogbed/ian) in thing) + new /obj/item/clothing/head/festive(thing) + var/obj/item/reagent_containers/food/drinks/bottle/champagne/iandrink = new(thing) + iandrink.name = "dog champagne" + iandrink.pixel_y += 8 + iandrink.pixel_x += 8 + else + openturfs += thing + + var/turf/fireworks_turf = get_turf(pick(table)) + var/obj/item/storage/box/matches/matchbox = new(fireworks_turf) + matchbox.pixel_y += 8 + matchbox.pixel_x -= 3 + // new /obj/item/storage/box/fireworks/dangerous(fireworks_turf) //dangerous version for extra holiday memes. + +//lets mappers place notes on airlocks with custom info or a pre-made note from a path +/obj/effect/mapping_helpers/airlock_note_placer + name = "Airlock Note Placer" + late = TRUE + icon_state = "airlocknoteplacer" + var/note_info //for writing out custom notes without creating an extra paper subtype + var/note_name //custom note name + var/note_path //if you already have something wrote up in a paper subtype, put the path here + +/obj/effect/mapping_helpers/airlock_note_placer/LateInitialize() + var/turf/turf = get_turf(src) + if(note_path && !istype(note_path, /obj/item/paper)) //don't put non-paper in the paper slot thank you + log_mapping("[src] at [x],[y] had an improper note_path path, could not place paper note.") + qdel(src) + if(locate(/obj/machinery/door/airlock) in turf) + var/obj/machinery/door/airlock/found_airlock = locate(/obj/machinery/door/airlock) in turf + if(note_path) + found_airlock.note = note_path + found_airlock.update_appearance() + qdel(src) + if(note_info) + var/obj/item/paper/paper = new /obj/item/paper(src) + if(note_name) + paper.name = note_name + paper.info = "[note_info]" + found_airlock.note = paper + paper.forceMove(found_airlock) + found_airlock.update_appearance() + qdel(src) + log_mapping("[src] at [x],[y] had no note_path or note_info, cannot place paper note.") + qdel(src) + log_mapping("[src] at [x],[y] could not find an airlock on current turf, cannot place paper note.") + qdel(src) + +//This helper applies traits to things on the map directly. +/obj/effect/mapping_helpers/trait_injector + name = "Trait Injector" + icon_state = "trait" + late = TRUE + ///Will inject into all fitting the criteria if false, otherwise first found. + var/first_match_only = TRUE + ///Will inject into atoms of this type. + var/target_type + ///Will inject into atoms with this name. + var/target_name + ///Name of the trait, in the lower-case text (NOT the upper-case define) form. + var/trait_name + +//Late init so everything is likely ready and loaded (no warranty) +/obj/effect/mapping_helpers/trait_injector/LateInitialize() + if(!GLOB.trait_name_map) + GLOB.trait_name_map = generate_trait_name_map() + if(!GLOB.trait_name_map.Find(trait_name)) + CRASH("Wrong trait in [type] - [trait_name] is not a trait") + var/turf/target_turf = get_turf(src) + var/matches_found = 0 + for(var/a in target_turf.GetAllContents()) + var/atom/atom_on_turf = a + if(atom_on_turf == src) + continue + if(target_name && atom_on_turf.name != target_name) + continue + if(target_type && !istype(atom_on_turf,target_type)) + continue + ADD_TRAIT(atom_on_turf, trait_name, MAPPING_HELPER_TRAIT) + matches_found++ + if(first_match_only) + qdel(src) + return + if(!matches_found) + stack_trace("Trait mapper found no targets at ([x], [y], [z]). First Match Only: [first_match_only ? "true" : "false"] target type: [target_type] | target name: [target_name] | trait name: [trait_name]") + qdel(src) + +/// Fetches an external dmi and applies to the target object +/obj/effect/mapping_helpers/custom_icon + name = "Custom Icon Helper" + icon_state = "trait" + late = TRUE + ///Will inject into all fitting the criteria if false, otherwise first found. + var/first_match_only = TRUE + ///Will inject into atoms of this type. + var/target_type + ///Will inject into atoms with this name. + var/target_name + /// This is the var tha will be set with the fetched icon. In case you want to set some secondary icon sheets like inhands and such. + var/target_variable = "icon" + /// This should return raw dmi in response to http get request. For example: "https://github.com/tgstation/SS13-sprites/raw/master/mob/medu.dmi?raw=true" + var/icon_url + +/obj/effect/mapping_helpers/custom_icon/LateInitialize() + ///TODO put this injector stuff under common root + var/I = fetch_icon(icon_url) + var/turf/target_turf = get_turf(src) + var/matches_found = 0 + for(var/a in target_turf.GetAllContents()) + var/atom/atom_on_turf = a + if(atom_on_turf == src) + continue + if(target_name && atom_on_turf.name != target_name) + continue + if(target_type && !istype(atom_on_turf,target_type)) + continue + atom_on_turf.vars[target_variable] = I + matches_found++ + if(first_match_only) + qdel(src) + return + if(!matches_found) + stack_trace("[src] found no targets at ([x], [y], [z]). First Match Only: [first_match_only ? "true" : "false"] target type: [target_type] | target name: [target_name]") + qdel(src) + +/obj/effect/mapping_helpers/custom_icon/proc/fetch_icon(url) + var/static/icon_cache = list() + var/static/query_in_progress = FALSE //We're using a single tmp file so keep it linear. + if(query_in_progress) + UNTIL(!query_in_progress) + if(icon_cache[url]) + return icon_cache[url] + log_asset("Custom Icon Helper fetching dmi from: [url]") + var/datum/http_request/request = new() + var/file_name = "tmp/custom_map_icon.dmi" + request.prepare(RUSTG_HTTP_METHOD_GET, url , "", "", file_name) + query_in_progress = TRUE + request.begin_async() + UNTIL(request.is_complete()) + var/datum/http_response/response = request.into_response() + if(response.errored || response.status_code != 200) + query_in_progress = FALSE + CRASH("Failed to fetch mapped custom icon from url [url], code: [response.status_code], error: [response.error]") + var/icon/I = new(file_name) + icon_cache[url] = I + query_in_progress = FALSE + return I diff --git a/code/modules/mapping/mapping_helpers/baseturf.dm b/code/modules/mapping/mapping_helpers/baseturf.dm index f4bd0d7c7f..8bb44ae993 100644 --- a/code/modules/mapping/mapping_helpers/baseturf.dm +++ b/code/modules/mapping/mapping_helpers/baseturf.dm @@ -8,7 +8,7 @@ layer = POINT_LAYER -/obj/effect/baseturf_helper/Initialize() +/obj/effect/baseturf_helper/Initialize(mapload) . = ..() return INITIALIZE_HINT_LATELOAD @@ -30,8 +30,8 @@ qdel(src) /obj/effect/baseturf_helper/proc/replace_baseturf(turf/thing) - var/list/baseturf_cache = thing.baseturfs - if(length(baseturf_cache)) + if(length(thing.baseturfs)) + var/list/baseturf_cache = thing.baseturfs.Copy() for(var/i in baseturf_cache) if(baseturf_to_replace[i]) baseturf_cache -= i @@ -44,6 +44,8 @@ else thing.PlaceOnBottom(null, baseturf) + + /obj/effect/baseturf_helper/space name = "space baseturf editor" baseturf = /turf/open/space @@ -79,4 +81,3 @@ /obj/effect/baseturf_helper/lava_land/surface name = "lavaland baseturf editor" baseturf = /turf/open/lava/smooth/lava_land_surface - diff --git a/code/modules/mapping/minimaps.dm b/code/modules/mapping/minimaps.dm index 51fde1f8db..8768ddd1e8 100644 --- a/code/modules/mapping/minimaps.dm +++ b/code/modules/mapping/minimaps.dm @@ -47,21 +47,43 @@ var/meta_color = area_to_color[A] if(!meta_color) - meta_color = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) // technically conflicts could happen but it's like very unlikely and it's not that big of a deal if one happens + var/meta_x = LAZYLEN(area_to_color) + 1 + var/meta_y = (((meta_x + 1) - ((meta_x + 1) % 255)) / 255) + var/meta_z = (((meta_y + 1) - ((meta_y + 1) % 255)) / 255) + meta_color = rgb(meta_x % 255, meta_y % 255, meta_z % 255) //This supports exactly 16,581,374 areas with no conflicts whatsoever before it just gives up area_to_color[A] = meta_color color_area_names[meta_color] = A.name meta_icon.DrawBox(meta_color, img_x, img_y) - if(istype(T, /turf/closed/wall)) + if(A.minimap_show_walls && istype(T, /turf/closed/wall)) map_icon.DrawBox("#000000", img_x, img_y) else if(!istype(A, /area/space)) - var/color = A.minimap_color || "#FF00FF" - if(locate(/obj/machinery/power/solar) in T) - color = "#02026a" + var/color = (A.minimap_color2 ? (((img_x + img_y) % 2) ? A.minimap_color2 : A.minimap_color ) : A.minimap_color) || "#FF00FF" + if(A.minimap_show_walls) + var/overridden + for(var/obj/structure/O in T) + if(O.minimap_override_color) + color = O.minimap_override_color + overridden = TRUE + break + else if(O.density && O.anchored) + color = BlendRGB(color, "#000000", 0.5) + overridden = TRUE + break + + //In an ideal world, we'd be able to get away with just doing for(var/obj/O in T) up there, and calling it a day. However. HOWEVER! + //Doing that causes the code to also loop through items. and that uh. Kinda bloats minimap gen time. A LOT. We're talking straight-up doubling the time it takes to gen. + //So instead we take our ctrl+c. We copy the above code. And we ctrl+v. It's awful. We hate it. But it works. It's faster. Funny mapgen go vroom + if(!overridden) + for(var/obj/machinery/O in T) + if(O.minimap_override_color) + color = O.minimap_override_color + break + else if(O.density && O.anchored) + color = BlendRGB(color, "#000000", 0.25) + break - if((locate(/obj/effect/spawner/structure/window) in T) || (locate(/obj/structure/grille) in T)) - color = BlendRGB(color, "#000000", 0.5) map_icon.DrawBox(color, img_x, img_y) map_icon.Crop(crop_x1, crop_y1, crop_x2, crop_y2) @@ -102,22 +124,48 @@ var/list/datas = list() var/list/info = list() - - for(var/i in 1 to length(minimaps))// OLD: for(var/i in 1 to length(minimaps)) + var/buttonfield = "" + var/totalmaps = length(minimaps) + for(var/i in 1 to totalmaps)// OLD: for(var/i in 1 to length(minimaps)) var/datum/minimap/M = minimaps[i] var/map_name = "minimap-[M.id].png" var/meta_name = "minimap-[M.id]-meta.png" M.send(user) info += {" -
    +
    + [totalmaps > 1 ? "

    Layer [i]

    " : ""]
    -
    + [totalmaps <= 1 ? "
    " : ""]
    "} datas += json_encode(M.color_area_names); + buttonfield += "Layer [i] " + + if(totalmaps > 1) + info += "
    [buttonfield]
    " + + //This is a hacky workaround; the status display is extremely buggy when multiple z-levels are present. We couldn't figure out how to fix this after 7 hours of banging our head against the wall + //We're coder + var/mousemove_bit = {" + canvas.onmousemove = function(e){ + var rect = canvas.getBoundingClientRect(); + var x = Math.floor(e.offsetX * img.width / rect.width); + var y = Math.floor(e.offsetY * img.height / rect.height); + + var color_idx = x * 4 + (y * 4 * imagedata.width); + var color = "#" + hexify(imagedata.data\[color_idx]) + hexify(imagedata.data\[color_idx+1]) + hexify(imagedata.data\[color_idx+2]); + + label.textContent = data\[color]; + canvas.title = data\[color]; + } + canvas.onmouseout = function(e){ + label.textContent = " "; + canvas.title = ""; + } + "} info = info.Join() //this is bad. Too bad! @@ -133,6 +181,14 @@ } return num; } + function switchmap(mapid) { + var targetblock = document.getElementById(mapid); + for(var i = 0; i < [length(minimaps)]; i++) { + var currentblock = document.getElementById("layer-" + (i + 1)); + currentblock.style.display = 'none'; + } + targetblock.style.display = ''; + } window.onload = function() { if(!window.HTMLCanvasElement) { var label = document.getElementById("label-1"); @@ -150,6 +206,7 @@ var canvas = document.createElement("canvas"); canvas.width = img.width * 2; canvas.height = img.height * 2; + canvas.id = "canvas-" + (i+1); var ctx = canvas.getContext('2d'); ctx.msImageSmoothingEnabled = false; @@ -158,31 +215,23 @@ ctx = document.createElement("canvas").getContext('2d'); ctx.canvas.width = img.width; ctx.canvas.height = img.height; + ctx.id = "ctx-" + (i+1); ctx.drawImage(document.getElementById("map-" + (i+1) + "-meta"), 0, 0); var imagedata = ctx.getImageData(0, 0, img.width, img.height); - canvas.onmousemove = function(e){ - var rect = canvas.getBoundingClientRect(); - var x = Math.floor(e.offsetX * img.width / rect.width); - var y = Math.floor(e.offsetY * img.height / rect.height); - - var color_idx = x * 4 + (y * 4 * imagedata.width); - var color = "#" + hexify(imagedata.data\[color_idx]) + hexify(imagedata.data\[color_idx+1]) + hexify(imagedata.data\[color_idx+2]); - var label = document.getElementById("label-" + (i+1)); //label-String(n) - - label.textContent = data\[color]; - canvas.title = data\[color]; - } - canvas.onmouseout = function(e){ - canvas.title = ""; - } + var label = document.getElementById("label-" + (i+1)); //label-String(n); + [totalmaps <= 1 ? mousemove_bit : ""] } } diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index e97060b45d..3f213eb934 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -11,7 +11,7 @@ var/codelen = 4 tamperproof = 90 -/obj/structure/closet/crate/secure/loot/Initialize() +/obj/structure/closet/crate/secure/loot/Initialize(mapload) . = ..() var/list/digits = list("1", "2", "3", "4", "5", "6", "7", "8", "9", "0") code = "" diff --git a/code/modules/mining/aux_base.dm b/code/modules/mining/aux_base.dm index feb4b4b2da..494ca0e433 100644 --- a/code/modules/mining/aux_base.dm +++ b/code/modules/mining/aux_base.dm @@ -27,7 +27,7 @@ interface with the mining shuttle at the landing site if a mobile beacon is also var/obj/item/gps/internal/base/locator circuit = /obj/item/circuitboard/computer/auxiliary_base -/obj/machinery/computer/auxillary_base/Initialize() +/obj/machinery/computer/auxillary_base/Initialize(mapload) . = ..() locator = new(src) diff --git a/code/modules/mining/aux_base_camera.dm b/code/modules/mining/aux_base_camera.dm index be0a41427f..262e776c68 100644 --- a/code/modules/mining/aux_base_camera.dm +++ b/code/modules/mining/aux_base_camera.dm @@ -6,7 +6,7 @@ icon_state = "construction_drone" var/area/starting_area -/mob/camera/aiEye/remote/base_construction/Initialize() +/mob/camera/aiEye/remote/base_construction/Initialize(mapload) . = ..() starting_area = get_area(loc) diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index cda38033c2..1588dfa5c5 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -2,27 +2,32 @@ /obj/item/clothing/suit/hooded/explorer name = "explorer suit" desc = "An armoured suit for exploring harsh environments." - icon_state = "explorer" - item_state = "explorer" + icon_state = "explorer-normal" + item_state = "explorer-normal" + var/suit_type = "normal" body_parts_covered = CHEST|GROIN|LEGS|ARMS cold_protection = CHEST|GROIN|LEGS|ARMS min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT hoodtype = /obj/item/clothing/head/hooded/explorer - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50) + armor = list(MELEE = 30, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 50) flags_inv = HIDEJUMPSUIT|HIDETAUR allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe) resistance_flags = FIRE_PROOF mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC|STYLE_PAW_TAURIC + no_t = TRUE /obj/item/clothing/head/hooded/explorer name = "explorer hood" desc = "An armoured hood for exploring harsh environments." - icon_state = "explorer" + icon_state = "explorer-normal" + item_state = "explorer-normal" + var/suit_type = "normal" + var/basestate = "normal" body_parts_covered = HEAD flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT cold_protection = HEAD - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50, "wound" = 10) + armor = list(MELEE = 30, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 50, WOUND = 10) resistance_flags = FIRE_PROOF /obj/item/clothing/suit/hooded/explorer/standard @@ -30,13 +35,43 @@ /obj/item/clothing/head/hooded/explorer/standard -/obj/item/clothing/suit/hooded/explorer/standard/Initialize() +/obj/item/clothing/suit/hooded/explorer/standard/Initialize(mapload) . = ..() AddComponent(/datum/component/armor_plate) + RegisterSignal(src, COMSIG_ARMOR_PLATED, .proc/upgrade_icon) -/obj/item/clothing/head/hooded/explorer/standard/Initialize() +/obj/item/clothing/suit/hooded/explorer/standard/proc/upgrade_icon(datum/source, amount, maxamount) + SIGNAL_HANDLER + + if(amount) + name = "reinforced [initial(name)]" + suit_type = "normal_goliath" + if(amount == maxamount) + suit_type = "normal_goliath_full" + icon_state = "explorer-[suit_type]" + if(ishuman(loc)) + var/mob/living/carbon/human/wearer = loc + if(wearer.wear_suit == src) + wearer.update_inv_wear_suit() + +/obj/item/clothing/head/hooded/explorer/standard/Initialize(mapload) . = ..() AddComponent(/datum/component/armor_plate) + RegisterSignal(src, COMSIG_ARMOR_PLATED, .proc/upgrade_icon) + +/obj/item/clothing/head/hooded/explorer/standard/proc/upgrade_icon(datum/source, amount, maxamount) + SIGNAL_HANDLER + + if(amount) + name = "reinforced [initial(name)]" + suit_type = "normal_goliath" + if(amount == maxamount) + suit_type = "normal_goliath_full" + icon_state = "explorer-[suit_type]" + if(ishuman(loc)) + var/mob/living/carbon/human/wearer = loc + if(wearer.head == src) + wearer.update_inv_head() /obj/item/clothing/mask/gas/explorer name = "explorer gas mask" @@ -46,7 +81,7 @@ visor_flags_inv = HIDEFACIALHAIR visor_flags_cover = MASKCOVERSMOUTH actions_types = list(/datum/action/item_action/adjust) - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 5, "bio" = 50, "rad" = 0, "fire" = 20, "acid" = 40, "wound" = 5) + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 5, BIO = 50, RAD = 0, FIRE = 20, ACID = 40, WOUND = 5) resistance_flags = FIRE_PROOF /obj/item/clothing/mask/gas/explorer/attack_self(mob/user) @@ -56,7 +91,7 @@ ..() w_class = mask_adjusted ? WEIGHT_CLASS_NORMAL : WEIGHT_CLASS_SMALL -/obj/item/clothing/mask/gas/explorer/folded/Initialize() +/obj/item/clothing/mask/gas/explorer/folded/Initialize(mapload) . = ..() adjustmask() @@ -70,10 +105,10 @@ resistance_flags = FIRE_PROOF | LAVA_PROOF | ACID_PROOF | GOLIATH_RESISTANCE mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC|STYLE_PAW_TAURIC slowdown = 0 - armor = list("melee" = 70, "bullet" = 40, "laser" = 10, "energy" = 10, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list(MELEE = 70, BULLET = 40, LASER = 10, ENERGY = 10, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe) -/obj/item/clothing/suit/space/hostile_environment/Initialize() +/obj/item/clothing/suit/space/hostile_environment/Initialize(mapload) . = ..() AddComponent(/datum/component/spraycan_paintable) START_PROCESSING(SSobj, src) @@ -99,10 +134,10 @@ w_class = WEIGHT_CLASS_NORMAL max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT clothing_flags = THICKMATERIAL // no space protection - armor = list("melee" = 70, "bullet" = 40, "laser" = 10, "energy" = 10, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list(MELEE = 70, BULLET = 40, LASER = 10, ENERGY = 10, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) resistance_flags = FIRE_PROOF | LAVA_PROOF -/obj/item/clothing/head/helmet/space/hostile_environment/Initialize() +/obj/item/clothing/head/helmet/space/hostile_environment/Initialize(mapload) . = ..() AddComponent(/datum/component/spraycan_paintable) update_icon() @@ -121,38 +156,48 @@ M.appearance_flags = RESET_COLOR . += M +/****************HEVA Suit and Mask****************/ -// CITADEL ADDITIONS BELOW - -/****************SEVA Suit and Mask****************/ - -/obj/item/clothing/suit/hooded/explorer/seva - name = "SEVA Suit" - desc = "A fire-proof suit for exploring hot environments. Its design and material make it easier for a Goliath to keep their grip on the wearer." - icon_state = "seva" - item_state = "seva" +/obj/item/clothing/suit/hooded/explorer/heva + name = "HEVA suit" + desc = "The Hazardous Environments extra-Vehicular Activity suit, developed by WanTon & Sons Perilous Mining and sold to Nanotrasen for missions within inhospitable, mineral-rich zones. \ + Its sleek plating deflects most biological - radioactive - and chemical substances and materials. Most notably, this will negate the effects of ash storms and give goliaths better grip against you." + icon_state = "heva" + item_state = "heva" w_class = WEIGHT_CLASS_BULKY - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - hoodtype = /obj/item/clothing/head/hooded/explorer/seva - armor = list("melee" = 15, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 35, "bio" = 50, "rad" = 25, "fire" = 100, "acid" = 25) + hoodtype = /obj/item/clothing/head/hooded/explorer/heva + armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 20, BIO = 100, RAD = 80, FIRE = 100, ACID = 80) resistance_flags = FIRE_PROOF | GOLIATH_WEAKNESS -/obj/item/clothing/head/hooded/explorer/seva - name = "SEVA Hood" - desc = "A fire-proof hood for exploring hot environments. Its design and material make it easier for a Goliath to keep their grip on the wearer." - icon_state = "seva" - item_state = "seva" - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 35, "bio" = 50, "rad" = 25, "fire" = 100, "acid" = 25) +/obj/item/clothing/head/hooded/explorer/heva + name = "HEVA hood" + desc = "The Hazardous Environments extra-Vehiclar Activity hood, developed by WanTon & Sons Perilous Mining. \ + Its sleek plating deflects most biological - radioactive - and chemical substances and materials. An instructive tag dictates that the provided mask is required for full protection." + icon_state = "heva" + item_state = "heva" + flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH + armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 20, BIO = 100, RAD = 20, FIRE = 60, ACID = 20) resistance_flags = FIRE_PROOF | GOLIATH_WEAKNESS -/obj/item/clothing/mask/gas/seva - name = "SEVA Mask" - desc = "A face-covering plate that can be connected to an air supply. Intended for use with the SEVA Suit." - icon_state = "seva" - item_state = "seva" - resistance_flags = FIRE_PROOF +/obj/item/clothing/head/hooded/explorer/heva/equipped(mob/living/carbon/human/user, slot) + ..() + if (slot == ITEM_SLOT_HEAD) + ADD_TRAIT(user, TRAIT_ASHSTORM_IMMUNE, "heva_suit") + +/obj/item/clothing/head/hooded/explorer/heva/dropped(mob/living/carbon/human/user) + ..() + if (HAS_TRAIT_FROM(user, TRAIT_ASHSTORM_IMMUNE, "heva_suit")) + REMOVE_TRAIT(user, TRAIT_ASHSTORM_IMMUNE, "heva_suit") + +/obj/item/clothing/mask/gas/heva + name = "HEVA mask" + desc = "The Hazardous Environments extra-Vehiclar Activity mask, developed by WanTon & Sons Perilous Mining. \ + Its sleek plating deflects most biological - radioactive - and chemical substances and materials. An instructive tag dictates that the provided protective attire is required for full protection." + icon_state = "heva" + item_state = "heva" + flags_inv = HIDEFACIALHAIR|HIDEFACE|HIDEEYES|HIDEEARS|HIDEHAIR + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 60, FIRE = 40, ACID = 50) /****************Exo-Suit and Mask****************/ @@ -164,7 +209,7 @@ w_class = WEIGHT_CLASS_BULKY heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS hoodtype = /obj/item/clothing/head/hooded/explorer/exo - armor = list("melee" = 55, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 40, "bio" = 25, "rad" = 10, "fire" = 0, "acid" = 0) + armor = list(MELEE = 55, BULLET = 5, LASER = 5, ENERGY = 5, BOMB = 40, BIO = 25, RAD = 10, FIRE = 0, ACID = 0) resistance_flags = FIRE_PROOF | GOLIATH_RESISTANCE /obj/item/clothing/head/hooded/explorer/exo @@ -172,7 +217,7 @@ desc = "A robust helmet for fighting dangerous animals. Its design and material make it harder for a Goliath to keep their grip on the wearer." icon_state = "exo" item_state = "exo" - armor = list("melee" = 55, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 40, "bio" = 25, "rad" = 10, "fire" = 0, "acid" = 0) + armor = list(MELEE = 55, BULLET = 5, LASER = 5, ENERGY = 5, BOMB = 40, BIO = 25, RAD = 10, FIRE = 0, ACID = 0) resistance_flags = FIRE_PROOF | GOLIATH_RESISTANCE /obj/item/clothing/mask/gas/exo diff --git a/code/modules/mining/equipment/gauntlet_styles.dm b/code/modules/mining/equipment/gauntlet_styles.dm new file mode 100644 index 0000000000..3e0d9afa57 --- /dev/null +++ b/code/modules/mining/equipment/gauntlet_styles.dm @@ -0,0 +1,50 @@ +/datum/gauntlet_style + var/name = "Baseline" + var/desc = "Somehow, you sense two things; one, that there's no combos on this, and two, that you should probably have someone address this." + var/obj/item/kinetic_crusher/glaive/gauntlets/hands // catch these + +/datum/gauntlet_style/proc/on_apply(obj/item/kinetic_crusher/glaive/gauntlets/theseNewHands) + hands = theseNewHands + return // todo: changing variables per style + +/datum/gauntlet_style/proc/check_streak(mob/living/carbon/human/attacker, mob/living/defender) + return FALSE + +/datum/gauntlet_style/proc/reset_streak(mob/living/carbon/user) + hands.streak = "" + user?.hud_used?.combo_display.update_icon_state(hands.streak) + +/datum/gauntlet_style/proc/examine_more_info() + return desc + +#define BRAWLER_COMBO_CROSS "DH" +/datum/gauntlet_style/brawler + name = "Rough and Tumble" + desc = "Throwing a punch is simple. Throwing a punch with a destabilizing module strapped to your hand is less so, but still doable." + +/datum/gauntlet_style/brawler/examine_more_info() + var/msg = list(span_notice(desc)) + msg += "Techniques:" + msg += "Cross Punch - Disarm, Harm. In addition to being a regular strike, deals an extra third of a regular detonation's damage." // this wording kinda sucks i think + return msg + +/datum/gauntlet_style/brawler/check_streak(mob/living/carbon/human/attacker, mob/living/defender) + if(findtext(hands.streak, BRAWLER_COMBO_CROSS)) + crossCombo(attacker, defender) + return TRUE + return FALSE + +/datum/gauntlet_style/brawler/proc/crossCombo(mob/living/carbon/attacker, mob/living/defender) + reset_streak(attacker) + playsound(attacker, 'sound/weapons/punch4.ogg', 100, FALSE) + var/bonus_damage = (hands.force + hands.detonation_damage) / 3 + defender.apply_damage(bonus_damage, BRUTE, blocked = defender.getarmor(type = BOMB)) + var/datum/status_effect/crusher_damage/cd_tracker = defender.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) + if(!QDELETED(defender) && !QDELETED(cd_tracker)) + cd_tracker.total_damage += bonus_damage //we did some damage, but let's not assume how much we did + defender.visible_message("[attacker] delivers a solid one-two punch to [defender]!", \ + "[attacker] hits you with a solid one-two punch!") + return TRUE + + +#undef BRAWLER_COMBO_CROSS diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index ddec9232ce..68ca1c979d 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -19,6 +19,7 @@ attack_verb = list("smashed", "crushed", "cleaved", "chopped", "pulped") sharpness = SHARP_EDGED actions_types = list(/datum/action/item_action/toggle_light) + obj_flags = UNIQUE_RENAME var/list/trophies = list() var/charged = TRUE var/charge_time = 15 @@ -28,13 +29,15 @@ var/brightness_on = 7 var/wielded = FALSE // track wielded status on item -/obj/item/kinetic_crusher/cyborg //probably give this a unique sprite later - desc = "An integrated version of the standard kinetic crusher with a grinded down axe head to dissuade mis-use against crewmen. Deals damage equal to the standard crusher against creatures, however." +/obj/item/kinetic_crusher/cyborg + icon_state = "crusher-cyborg" + item_state = "crusher0-cyborg" + desc = "An integrated version of the standard kinetic crusher with a kinetic dampener module installed to limit harmful usage misusage against organics. Deals damage equal to the standard crusher against creatures." force = 10 //wouldn't want to give a borg a 20 brute melee weapon unemagged now would we detonation_damage = 60 wielded = 1 -/obj/item/kinetic_crusher/Initialize() +/obj/item/kinetic_crusher/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield) RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield) @@ -133,7 +136,7 @@ C.total_damage += target_health - L.health //we did some damage, but let's not assume how much we did new /obj/effect/temp_visual/kinetic_blast(get_turf(L)) var/backstab_dir = get_dir(user, L) - var/def_check = L.getarmor(type = "bomb") + var/def_check = L.getarmor(type = BOMB) if((user.dir & backstab_dir) && (L.dir & backstab_dir)) if(!QDELETED(C)) C.total_damage += detonation_damage + backstab_bonus //cheat a little and add the total before killing it, so certain mobs don't have much lower chances of giving an item @@ -184,6 +187,7 @@ icon_state = "crusher-glaive" item_state = "crusher0-glaive" block_parry_data = /datum/block_parry_data/crusherglaive + obj_flags = UNIQUE_RENAME //ideas: altclick that lets you pummel people with the handguard/handle? //parrying functionality? @@ -228,6 +232,97 @@ /obj/item/kinetic_crusher/glaive/update_icon_state() item_state = "crusher[wielded]-glaive" // this is not icon_state and not supported by 2hcomponent +/obj/item/kinetic_crusher/glaive/bone + name = "necropolis bone glaive" + desc = "Tribals trying to immitate technology have spent a long time to somehow assemble bits and pieces to work together just like the real thing. \ + Although it does take a lot of effort and luck to create, it was a success." + icon_state = "crusher-bone" + item_state = "crusher0-bone" + +/obj/item/kinetic_crusher/glaive/bone/update_icon_state() + item_state = "crusher[wielded]-bone" + +/obj/item/kinetic_crusher/glaive/gauntlets + name = "proto-kinetic gauntlets" + desc = "A pair of scaled-down proto-kinetic crusher destabilizer modules shoved into gauntlets and concealed greaves, \ + often fielded by those who wish to spit in the eyes of God. Sacrifices outright damage for \ + a reliance on backstabs and the ability to stagger fauna on a parry, \ + slowing them and increasing the time between their special attacks." + attack_verb = list("pummeled", "punched", "jabbed", "hammer-fisted", "uppercut", "slammed") + hitsound = 'sound/weapons/resonator_blast.ogg' + sharpness = SHARP_NONE // use your survival dagger or smth + icon_state = "crusher-hands" + item_state = "crusher0-fist" + unique_reskin = list( + "Gauntlets" = list("icon_state" = "crusher-hands"), + "Fingerless" = list("icon_state" = "crusher-hands-bare") + ) + detonation_damage = 45 // 60 on wield, compared to normal crusher's 70 + backstab_bonus = 70 // 130 on backstab though + var/combo_on_anything = FALSE // @admins if you're varediting this you don't get to whine at me + var/streak = "" // you know what time it is + var/max_streak_length = 2 // changes with style module + var/mob/living/current_target + var/datum/gauntlet_style/active_style + +/obj/item/kinetic_crusher/glaive/gauntlets/Initialize(mapload) + . = ..() + active_style = new /datum/gauntlet_style/brawler + active_style.on_apply(src) + +/obj/item/kinetic_crusher/glaive/gauntlets/examine(mob/living/user) + . = ..() + . += "According to a very small display, the currently loaded style is \"[active_style.name]\"." + +/obj/item/kinetic_crusher/glaive/gauntlets/examine_more(mob/user) + return active_style.examine_more_info() + +/obj/item/kinetic_crusher/glaive/gauntlets/proc/style_change(datum/gauntlet_style/new_style) + new_style.on_apply(src) + +/obj/item/kinetic_crusher/glaive/gauntlets/ComponentInitialize() + . = ..() + AddComponent(/datum/component/two_handed, force_unwielded=0, force_wielded=15) + +/obj/item/kinetic_crusher/glaive/gauntlets/active_parry_reflex_counter(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list, parry_efficiency, list/effect_text) + . = ..() + if(isliving(attacker)) + var/mob/living/liv_atk = attacker + if(liv_atk.mob_size >= MOB_SIZE_LARGE) // are you goated with the sauce + liv_atk.apply_status_effect(STATUS_EFFECT_GAUNTLET_CONC) + +/obj/item/kinetic_crusher/glaive/gauntlets/update_icon_state() + if(current_skin == "Fingerless") + item_state = "crusher[wielded]-fistbare" + else + item_state = "crusher[wielded]-fist" + +/obj/item/kinetic_crusher/glaive/gauntlets/attack(mob/living/target, mob/living/carbon/user) + ..() + if((combo_on_anything || target.mob_size >= MOB_SIZE_LARGE) && wielded) + switch(user.a_intent) + if(INTENT_DISARM) + add_to_streak("D", user, target) + if(INTENT_GRAB) + add_to_streak("G", user, target) + if(INTENT_HARM) + add_to_streak("H", user, target) + active_style.check_streak(user, target) + +/obj/item/kinetic_crusher/glaive/gauntlets/proc/add_to_streak(element,mob/living/carbon/user, mob/living/target) + if(target != current_target) + reset_streak(target, user) + streak = streak+element + if(length(streak) > max_streak_length) + streak = copytext(streak, 1 + length(streak[1])) + user?.hud_used?.combo_display.update_icon_state(streak) + return + +/obj/item/kinetic_crusher/glaive/gauntlets/proc/reset_streak(mob/living/new_target, mob/living/carbon/user) + current_target = new_target + streak = "" + user?.hud_used?.combo_display.update_icon_state(streak) + //destablizing force /obj/item/projectile/destabilizer name = "destabilizing force" @@ -235,7 +330,7 @@ nodamage = TRUE damage = 0 //We're just here to mark people. This is still a melee weapon. damage_type = BRUTE - flag = "bomb" + flag = BOMB range = 6 log_override = TRUE var/obj/item/kinetic_crusher/hammer_synced diff --git a/code/modules/mining/equipment/marker_beacons.dm b/code/modules/mining/equipment/marker_beacons.dm index 296513af8d..d8e54ae322 100644 --- a/code/modules/mining/equipment/marker_beacons.dm +++ b/code/modules/mining/equipment/marker_beacons.dm @@ -73,7 +73,7 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list( icon = 'icons/obj/lighting.dmi' icon_state = "marker" layer = BELOW_OPEN_DOOR_LAYER - armor = list("melee" = 50, "bullet" = 75, "laser" = 75, "energy" = 75, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 25, "acid" = 0) + armor = list(MELEE = 50, BULLET = 75, LASER = 75, ENERGY = 75, BOMB = 25, BIO = 100, RAD = 100, FIRE = 25, ACID = 0) max_integrity = 50 anchored = TRUE light_range = 2 diff --git a/code/modules/mining/equipment/mineral_scanner.dm b/code/modules/mining/equipment/mineral_scanner.dm index b2cd840468..ee8389f2a5 100644 --- a/code/modules/mining/equipment/mineral_scanner.dm +++ b/code/modules/mining/equipment/mineral_scanner.dm @@ -3,7 +3,7 @@ desc = "A scanner that checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations." name = "manual mining scanner" icon = 'icons/obj/device.dmi' - icon_state = "mining1" + icon_state = "miningmanual" item_state = "analyzer" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' @@ -33,7 +33,7 @@ /obj/item/t_scanner/adv_mining_scanner desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. This one has an extended range." name = "advanced automatic mining scanner" - icon_state = "mining0" + icon_state = "adv_mining0" item_state = "analyzer" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' @@ -47,6 +47,7 @@ /obj/item/t_scanner/adv_mining_scanner/lesser name = "automatic mining scanner" desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations." + icon_state = "mining0" range = 4 cooldown = 50 @@ -78,6 +79,6 @@ pixel_x = -224 pixel_y = -224 -/obj/effect/temp_visual/mining_overlay/Initialize() +/obj/effect/temp_visual/mining_overlay/Initialize(mapload) . = ..() animate(src, alpha = 0, time = duration, easing = EASE_IN) diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm index 31ee37c3b0..c56b511b83 100644 --- a/code/modules/mining/equipment/mining_tools.dm +++ b/code/modules/mining/equipment/mining_tools.dm @@ -95,7 +95,7 @@ /obj/item/pickaxe/drill name = "mining drill" icon_state = "handdrill" - item_state = "jackhammer" + item_state = "handdrill" slot_flags = ITEM_SLOT_BELT toolspeed = 0.6 //available from roundstart, faster than a pickaxe. usesound = 'sound/weapons/drill.ogg' @@ -108,19 +108,21 @@ flags_1 = NONE toolspeed = 0.5 -/obj/item/pickaxe/drill/cyborg/Initialize() +/obj/item/pickaxe/drill/cyborg/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT) /obj/item/pickaxe/drill/diamonddrill name = "diamond-tipped mining drill" icon_state = "diamonddrill" + item_state = "diamonddrill" toolspeed = 0.4 desc = "Yours is the drill that will pierce the heavens!" /obj/item/pickaxe/drill/cyborg/diamond //This is the BORG version! name = "diamond-tipped cyborg mining drill" //To inherit the NODROP_1 flag, and easier to change borg specific drill mechanics. icon_state = "diamonddrill" + item_state = "diamonddrill" toolspeed = 0.4 digrange = 2 @@ -155,7 +157,7 @@ attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked") sharpness = SHARP_EDGED -/obj/item/shovel/Initialize() +/obj/item/shovel/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 150, 40) //it's sharp, so it works, but barely. @@ -179,6 +181,12 @@ custom_materials = list(/datum/material/iron=50) w_class = WEIGHT_CLASS_SMALL +/obj/item/shovel/spade/bone + name = "bone spade" + desc = "A bone spade, suitable for digging and moving dirt." + icon_state = "spade_bone" + toolspeed = 0.75 + /obj/item/shovel/serrated name = "serrated bone shovel" desc = "A wicked tool that cleaves through dirt just as easily as it does flesh. The design was styled after ancient lavaland tribal designs." diff --git a/code/modules/mining/equipment/regenerative_core.dm b/code/modules/mining/equipment/regenerative_core.dm index 1de3a86702..4552d103b6 100644 --- a/code/modules/mining/equipment/regenerative_core.dm +++ b/code/modules/mining/equipment/regenerative_core.dm @@ -29,7 +29,7 @@ var/inert var/preserved -/obj/item/organ/regenerative_core/Initialize() +/obj/item/organ/regenerative_core/Initialize(mapload) . = ..() addtimer(CALLBACK(src, .proc/inert_check), 2400) @@ -116,7 +116,7 @@ desc = "A strange rock that crackles with power. It can be used to heal completely, but it will rapidly decay into uselessness." icon_state = "legion_soul" -/obj/item/organ/regenerative_core/legion/Initialize() +/obj/item/organ/regenerative_core/legion/Initialize(mapload) . = ..() update_icon() diff --git a/code/modules/mining/equipment/resonator.dm b/code/modules/mining/equipment/resonator.dm index 16dd893c3a..fd9ff4c91e 100644 --- a/code/modules/mining/equipment/resonator.dm +++ b/code/modules/mining/equipment/resonator.dm @@ -111,7 +111,7 @@ layer = ABOVE_ALL_MOB_LAYER duration = 4 -/obj/effect/temp_visual/resonance_crush/Initialize() +/obj/effect/temp_visual/resonance_crush/Initialize(mapload) . = ..() transform = matrix()*1.5 animate(src, transform = matrix()*0.1, alpha = 50, time = 4) diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index 2452beb0e1..a1f3e13fcc 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -91,9 +91,23 @@ template_id = "shelter_delta" /obj/item/survivalcapsule/luxury/penthouse - name = "penthouse bluespace sheler capsule" - desc = "The absolute pinnacle of luxury in terms of survival capsules. While exuberantly expensive it has everything needed to make a small home in lavaland." + name = "penthouse bluespace shelter capsule" + desc = "The absolute pinnacle of luxury in terms of survival capsules. While exuberantly expensive it has everything needed to survive in luxury." template_id = "shelter_epsilon" +/obj/item/survivalcapsule/luxury/garden + name = "garden & kitchen bluespace shelter capsule" + desc = "Everything someone needs to make a home cooked meal while surviving the depths of hell... or space." + template_id = "shelter_zeta" + +// RBMK reactor beacon so people can create the engine + +/obj/item/survivalcapsule/reactor // the not-so-survival capsule + name = "RMBK Reactor Beacon" + desc = "A special bluespace beacon designed to implement a reactor into the hull of the ship or station that it is activated on." + icon = 'icons/obj/device.dmi' + icon_state = "beacon" + template_id = "reactor" + //Pod objects //Window @@ -162,6 +176,26 @@ if(!state_open) . += "sleeper_cover" +//Lifeform Stasis Unit +/obj/machinery/stasis/survival_pod + icon = 'icons/obj/lavaland/survival_pod.dmi' + icon_state = "sleeper" + mattress_state = null + buckle_lying = 270 + +/obj/machinery/stasis/survival_pod/play_power_sound() + return + +/obj/machinery/stasis/survival_pod/update_icon() + return + +//NanoMed +/obj/machinery/vending/wallmed/survival_pod + name = "survival pod medical supply" + desc = "Wall-mounted Medical Equipment dispenser. This one seems just a tiny bit smaller." + refill_canister = null + onstation = FALSE + //Computer /obj/item/gps/computer name = "pod computer" @@ -190,6 +224,10 @@ icon = 'icons/obj/lavaland/survival_pod.dmi' icon_state = "bed" +/obj/structure/bed/double/pod + icon = 'icons/obj/lavaland/survival_pod.dmi' + icon_state = "bed_double" + //Survival Storage Unit /obj/machinery/smartfridge/survival_pod name = "survival pod storage" @@ -323,7 +361,7 @@ /obj/item/phylactery, /obj/item/banhammer) -/obj/item/fakeartefact/Initialize() +/obj/item/fakeartefact/Initialize(mapload) . = ..() var/obj/item/I = pick(possible) name = initial(I.name) diff --git a/code/modules/mining/equipment/wormhole_jaunter.dm b/code/modules/mining/equipment/wormhole_jaunter.dm index 9c503279d4..9eed296851 100644 --- a/code/modules/mining/equipment/wormhole_jaunter.dm +++ b/code/modules/mining/equipment/wormhole_jaunter.dm @@ -20,7 +20,7 @@ /obj/item/wormhole_jaunter/equipped(mob/user, slot) . = ..() - if(slot == SLOT_BELT) + if(slot == ITEM_SLOT_BELT) RegisterSignal(user, COMSIG_MOVABLE_CHASM_DROP, .proc/chasm_react) /obj/item/wormhole_jaunter/dropped(mob/user) @@ -68,7 +68,7 @@ var/mob/M = loc if(istype(M)) - if(M.get_item_by_slot(SLOT_BELT) == src) + if(M.get_item_by_slot(ITEM_SLOT_BELT) == src) if(prob(severity)) M.visible_message("[src] overloads and activates!") SSblackbox.record_feedback("tally", "jaunter", 1, "EMP") // EMP accidental activation diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index 5044a73c10..18f816699c 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -60,83 +60,86 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) return if(A.anchored || (A.move_resist > max_force_fulton)) return - to_chat(user, "You start attaching the pack to [A]...") - if(do_after(user,50,target=A)) - to_chat(user, "You attach the pack to [A] and activate it.") - if(loc == user && istype(user.back, /obj/item/storage/backpack)) - var/obj/item/storage/backpack/B = user.back - SEND_SIGNAL(B, COMSIG_TRY_STORAGE_INSERT, src, user, FALSE, FALSE) - uses_left-- - if(uses_left <= 0) - user.transferItemToLoc(src, A, TRUE) - var/mutable_appearance/balloon - var/mutable_appearance/balloon2 - var/mutable_appearance/balloon3 - if(isliving(A)) - var/mob/living/M = A - M.DefaultCombatKnockdown(320) // Keep them from moving during the duration of the extraction - M.buckled = 0 // Unbuckle them to prevent anchoring problems - else - A.anchored = TRUE - A.density = FALSE - var/obj/effect/extraction_holder/holder_obj = new(A.loc) - holder_obj.appearance = A.appearance - A.forceMove(holder_obj) - balloon2 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_expand") - balloon2.pixel_y = 10 - balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM - holder_obj.add_overlay(balloon2) - sleep(4) - balloon = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_balloon") - balloon.pixel_y = 10 - balloon.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM - holder_obj.cut_overlay(balloon2) - holder_obj.add_overlay(balloon) - playsound(holder_obj.loc, 'sound/items/fulext_deploy.wav', 50, 1, -3) - animate(holder_obj, pixel_z = 10, time = 20) - sleep(20) - animate(holder_obj, pixel_z = 15, time = 10) - sleep(10) - animate(holder_obj, pixel_z = 10, time = 10) - sleep(10) - animate(holder_obj, pixel_z = 15, time = 10) - sleep(10) - animate(holder_obj, pixel_z = 10, time = 10) - sleep(10) - playsound(holder_obj.loc, 'sound/items/fultext_launch.wav', 50, 1, -3) - animate(holder_obj, pixel_z = 1000, time = 30) - if(ishuman(A)) - var/mob/living/carbon/human/L = A - L.SetUnconscious(0) - L.drowsyness = 0 - L.SetSleeping(0) - sleep(30) - var/list/flooring_near_beacon = list() - for(var/turf/open/floor in orange(1, beacon)) - flooring_near_beacon += floor - holder_obj.forceMove(pick(flooring_near_beacon)) - animate(holder_obj, pixel_z = 10, time = 50) - sleep(50) - animate(holder_obj, pixel_z = 15, time = 10) - sleep(10) - animate(holder_obj, pixel_z = 10, time = 10) - sleep(10) - balloon3 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_retract") - balloon3.pixel_y = 10 - balloon3.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM - holder_obj.cut_overlay(balloon) - holder_obj.add_overlay(balloon3) - sleep(4) - holder_obj.cut_overlay(balloon3) - A.anchored = FALSE // An item has to be unanchored to be extracted in the first place. - A.density = initial(A.density) - animate(holder_obj, pixel_z = 0, time = 5) - sleep(5) - A.forceMove(holder_obj.loc) - qdel(holder_obj) - if(uses_left <= 0) - qdel(src) + attach_fulton(A, user, flag, params) +/obj/item/extraction_pack/proc/attach_fulton(atom/movable/A, mob/living/carbon/human/user, flag, params) + set waitfor = FALSE + to_chat(user, "You start attaching the pack to [A]...") + if(do_after(user,50,target=A)) + to_chat(user, "You attach the pack to [A] and activate it.") + if(loc == user && istype(user.back, /obj/item/storage/backpack)) + var/obj/item/storage/backpack/B = user.back + SEND_SIGNAL(B, COMSIG_TRY_STORAGE_INSERT, src, user, FALSE, FALSE) + uses_left-- + if(uses_left <= 0) + user.transferItemToLoc(src, A, TRUE) + var/mutable_appearance/balloon + var/mutable_appearance/balloon2 + var/mutable_appearance/balloon3 + if(isliving(A)) + var/mob/living/M = A + M.DefaultCombatKnockdown(320) // Keep them from moving during the duration of the extraction + M.buckled = 0 // Unbuckle them to prevent anchoring problems + else + A.anchored = TRUE + A.density = FALSE + var/obj/effect/extraction_holder/holder_obj = new(A.loc) + holder_obj.appearance = A.appearance + A.forceMove(holder_obj) + balloon2 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_expand") + balloon2.pixel_y = 10 + balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.add_overlay(balloon2) + sleep(4) + balloon = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_balloon") + balloon.pixel_y = 10 + balloon.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.cut_overlay(balloon2) + holder_obj.add_overlay(balloon) + playsound(holder_obj.loc, 'sound/items/fulext_deploy.wav', 50, 1, -3) + animate(holder_obj, pixel_z = 10, time = 20) + sleep(20) + animate(holder_obj, pixel_z = 15, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 10, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 15, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 10, time = 10) + sleep(10) + playsound(holder_obj.loc, 'sound/items/fultext_launch.wav', 50, 1, -3) + animate(holder_obj, pixel_z = 1000, time = 30) + if(ishuman(A)) + var/mob/living/carbon/human/L = A + L.SetUnconscious(0) + L.drowsyness = 0 + L.SetSleeping(0) + sleep(30) + var/list/flooring_near_beacon = list() + for(var/turf/open/floor in orange(1, beacon)) + flooring_near_beacon += floor + holder_obj.forceMove(pick(flooring_near_beacon)) + animate(holder_obj, pixel_z = 10, time = 50) + sleep(50) + animate(holder_obj, pixel_z = 15, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 10, time = 10) + sleep(10) + balloon3 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_retract") + balloon3.pixel_y = 10 + balloon3.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.cut_overlay(balloon) + holder_obj.add_overlay(balloon3) + sleep(4) + holder_obj.cut_overlay(balloon3) + A.anchored = FALSE // An item has to be unanchored to be extracted in the first place. + A.density = initial(A.density) + animate(holder_obj, pixel_z = 0, time = 5) + sleep(5) + A.forceMove(holder_obj.loc) + qdel(holder_obj) + if(uses_left <= 0) + qdel(src) /obj/item/fulton_core name = "extraction beacon signaller" @@ -158,7 +161,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) density = FALSE var/beacon_network = "station" -/obj/structure/extraction_point/Initialize() +/obj/structure/extraction_point/Initialize(mapload) . = ..() name += " ([rand(100,999)]) ([get_area_name(src, TRUE)])" GLOB.total_extraction_beacons += src diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index 6ef4684921..97953e6297 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -15,7 +15,7 @@ GLOBAL_LIST(labor_sheet_values) /// Needed to send messages to sec radio var/obj/item/radio/Radio -/obj/machinery/mineral/labor_claim_console/Initialize() +/obj/machinery/mineral/labor_claim_console/Initialize(mapload) . = ..() Radio = new/obj/item/radio(src) Radio.listening = FALSE diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm index 9710773309..b9ab6463c7 100644 --- a/code/modules/mining/lavaland/ash_flora.dm +++ b/code/modules/mining/lavaland/ash_flora.dm @@ -20,7 +20,7 @@ var/regrowth_time_low = 8 MINUTES var/regrowth_time_high = 16 MINUTES -/obj/structure/flora/ash/Initialize() +/obj/structure/flora/ash/Initialize(mapload) . = ..() base_icon = "[icon_state][rand(1, 4)]" icon_state = base_icon @@ -152,7 +152,7 @@ seed = /obj/item/seeds/lavaland/polypore wine_power = 20 -/obj/item/reagent_containers/food/snacks/grown/ash_flora/Initialize() +/obj/item/reagent_containers/food/snacks/grown/ash_flora/Initialize(mapload) . = ..() pixel_x = rand(-4, 4) pixel_y = rand(-4, 4) diff --git a/code/modules/mining/lavaland/ash_tree.dm b/code/modules/mining/lavaland/ash_tree.dm new file mode 100644 index 0000000000..5dca7a8e2f --- /dev/null +++ b/code/modules/mining/lavaland/ash_tree.dm @@ -0,0 +1,96 @@ +//Houses the ash tree, a lava land tree that has been burning for quite some time making a maple like sweetener. + +/obj/structure/flora/ashtree + name = "ashed tree" + desc = "A once large tree now burnt like the lands around it." + layer = FLY_LAYER + gender = PLURAL //same as other tree + density = TRUE + pixel_x = -16 + icon = 'icons/obj/lavaland/ash_tree.dmi' + icon_state = "ashtree" + //Are icon when we are full of honey or other sap + var/sap_icon_state = "ashtree_maple" + //What we look like when tapping + var/tabbed_icon_state = "ashtree_maple" + //amout of coal in are tree, simular to logs + var/coal_amount = 5 + //Do we have sap? + var/sap = FALSE + //What reagent we have + var/sap_type = /datum/reagent/consumable/honey + //This is in seconds, and now long we wait till are tree is tapped + var/harvest_sap_time = 60 + var/container_used + var/sap_amount + +/obj/structure/flora/ashtree/Initialize(mapload) + ..() + if(prob(50)) + sap = TRUE + icon_state = sap_icon_state + desc = "A once large tree now burnt like the lands around it. This one seems to have a sap still inside." + //If we have sap, we can generate a bit of it + sap_amount = rand(5,15) + //Random coal or wood amount, so its not bog standered. + coal_amount = rand(5,15) + //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("tally", "Honey Tree", 1, "Trees Spawned") + +//So we dont lose are bowls, stolen form closet code +/obj/structure/flora/ashtree/Destroy() + dump_contents(override = FALSE) + return ..() + +//Override is for not revealing the locker electronics when you open the locker, for example +/obj/structure/flora/ashtree/proc/dump_contents(override = TRUE) + var/atom/L = drop_location() + for(var/atom/movable/AM in src) + AM.forceMove(L) + +/obj/structure/flora/ashtree/proc/harvest_sap() + desc = "A once large tree now burnt like the lands around it." + icon_state = "ashtree" + var/obj/item/reagent_containers/RG = container_used + //Incase someone was a dumb and used a lidded container + if(RG.is_refillable()) + //Make sure that its not filling something thats full + if(!RG.reagents.holder_full()) + RG.reagents.add_reagent(sap_type, min(RG.volume - RG.reagents.total_volume, sap_amount)) + //We drop are used beaker and try to fill it with sap + RG.forceMove(drop_location()) + SSblackbox.record_feedback("tally", "Honey Tree", 1, "Harvested Honey") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +//Proc stolen from Trees +//If you hit it with a sharp force aboe 0 item it chops it down, unlike trees tho it dosnt give wood as its already charcoal +//Also dosnt have a stump +/obj/structure/flora/ashtree/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/reagent_containers)) + if(sap) + user.visible_message("[user] pokes [src] and places a container under the [W].","You set up [src] with [W].") + icon_state = tabbed_icon_state + sap = FALSE + container_used = W + //So we dont lose are bowl when cutting it down + needed for the harvest sap proc + user.transferItemToLoc(W, src) + addtimer(CALLBACK(src, .proc/harvest_sap), harvest_sap_time SECONDS) + else + to_chat(user, "There is no sap to collect.") + + if(coal_amount && (!(flags_1 & NODECONSTRUCT_1))) + if(!W.sharpness || !W.force) + return + if(W.hitsound) + playsound(get_turf(src), W.hitsound, 100, 0, 0) + user.visible_message("[user] begins to cut down [src] with [W].","You begin to cut down [src] with [W].", "You hear the sound of brittle sawing.") + //2.5 seconds with 20 force, 4 seconds with a hatchet, 10 seconds with a shard. + if(do_after(user, 500/W.force, target = src)) + user.visible_message("[user] fells [src] with the [W].","You fell [src] with the [W].", "You hear the sound of a crumbling tree.") + playsound(get_turf(src), 'sound/effects/meteorimpact.ogg', 100 , 0, 0) + for(var/i=1 to coal_amount) + new /obj/item/stack/sheet/mineral/coal(get_turf(src)) + qdel(src)//If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("tally", "Honey Tree", 1, "Cutted Tree") + + return ..() + diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index e64505df7e..1986a8f9c1 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -184,7 +184,7 @@ icon_state = "datadisk1" var/modkit_design = /datum/design/unique_modkit -/obj/item/disk/design_disk/modkit_disc/Initialize() +/obj/item/disk/design_disk/modkit_disc/Initialize(mapload) . = ..() blueprints[1] = new modkit_design @@ -307,7 +307,7 @@ var/mob/living/carbon/human/active_owner /obj/item/clothing/neck/necklace/memento_mori/item_action_slot_check(slot, mob/user, datum/action/A) - return slot == SLOT_NECK + return slot == ITEM_SLOT_NECK /obj/item/clothing/neck/necklace/memento_mori/dropped(mob/user) ..() @@ -383,7 +383,7 @@ wisp.forceMove(src) SSblackbox.record_feedback("tally", "wisp_lantern", 1, "Returned") -/obj/item/wisp_lantern/Initialize() +/obj/item/wisp_lantern/Initialize(mapload) . = ..() wisp = new(src) @@ -473,7 +473,7 @@ icon_state = "red_cube" teleport_color = "#FD3F48" -/obj/item/warp_cube/red/Initialize() +/obj/item/warp_cube/red/Initialize(mapload) . = ..() if(!linked) var/obj/item/warp_cube/blue = new(src.loc) @@ -484,7 +484,7 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT anchored = TRUE -/obj/effect/warp_cube/ex_act(severity, target) +/obj/effect/warp_cube/ex_act(severity, target, origin) return //Meat Hook @@ -553,7 +553,7 @@ actions_types = list(/datum/action/item_action/immortality) var/cooldown = 0 -/obj/item/immortality_talisman/Initialize() +/obj/item/immortality_talisman/Initialize(mapload) . = ..() AddComponent(/datum/component/anti_magic, TRUE, TRUE, TRUE) @@ -607,7 +607,7 @@ /obj/effect/immortality_talisman/attackby() return -/obj/effect/immortality_talisman/ex_act() +/obj/effect/immortality_talisman/ex_act(severity, target, origin) return /obj/effect/immortality_talisman/singularity_pull() @@ -637,7 +637,7 @@ name = "paradox bag" desc = "Somehow, it's in two places at once." -/obj/item/shared_storage/red/Initialize() +/obj/item/shared_storage/red/Initialize(mapload) . = ..() var/datum/component/storage/STR = AddComponent(/datum/component/storage/concrete) STR.max_w_class = WEIGHT_CLASS_NORMAL @@ -694,16 +694,20 @@ /datum/reagent/flightpotion/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(iscarbon(M) && M.stat != DEAD) - if(!ishumanbasic(M) || reac_volume < 5) // implying xenohumans are holy + var/mob/living/carbon/C = M + if(reac_volume < 5) if(method == INGEST && show_message) - to_chat(M, "You feel nothing but a terrible aftertaste.") + to_chat(C, "You feel nothing but a terrible aftertaste.") return ..() - - to_chat(M, "A terrible pain travels down your back as wings burst out!") - M.set_species(/datum/species/angel) - playsound(M.loc, 'sound/items/poster_ripped.ogg', 50, 1, -1) - M.adjustBruteLoss(20) - M.emote("scream") + var/has_wings = (C.dna.species.mutant_bodyparts["deco_wings"] && C.dna.features["deco_wings"] != "None" || C.dna.species.mutant_bodyparts["insect_wings"] && C.dna.features["insect_wings"] != "None") + var/has_functional_wings = (C.dna.species.mutant_bodyparts["wings"] != null) + to_chat(C, "A terrible pain travels down your back as [has_wings || has_functional_wings ? "your wings transform" : "wings burst out"]!") + C.dna.species.GiveSpeciesFlight(C, has_functional_wings ? TRUE : FALSE) //give them the full list of wing choices if this is their second flight potion + to_chat(C, "You feel blessed!") + ADD_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT) //implying anyone is truly holy in a setting where people throw tantrums when things aren't violent + playsound(C.loc, 'sound/items/poster_ripped.ogg', 50, TRUE, -1) + C.adjustBruteLoss(20) + C.emote("scream") ..() @@ -766,6 +770,12 @@ total_mass_on = 5 attack_speed = 0 attack_unwieldlyness = CLICK_CD_MELEE * 0.5 + /// how much stamina does it cost to roll? + var/roll_stamcost = 15 + /// how far are we rolling? + var/roll_range = 3 + /// do you spin when dodgerolling + var/roll_orientation = TRUE /obj/item/melee/transforming/cleaving_saw/examine(mob/user) . = ..() @@ -811,6 +821,11 @@ else B.add_stacks(bleed_stacks_per_hit) +/obj/item/melee/transforming/cleaving_saw/AltClick(mob/user) + . = ..() + roll_orientation = !roll_orientation + to_chat(user, span_notice("You are now [roll_orientation ? "rolling" : "quick-stepping"] when you dodge. (This only affects if you spin or not during a dodge.)")) + /obj/item/melee/transforming/cleaving_saw/attack(mob/living/target, mob/living/carbon/human/user) if(!active || swiping || !target.density || get_turf(target) == get_turf(user)) if(!active) @@ -830,6 +845,43 @@ melee_attack_chain(user, L) swiping = FALSE +/obj/item/melee/transforming/cleaving_saw/alt_pre_attack(atom/A, mob/living/user, params) + return TRUE // Let's dance. + +/obj/item/melee/transforming/cleaving_saw/altafterattack(atom/target, mob/living/user, proximity_flag, click_parameters) + if(user.IsImmobilized()) // no free dodgerolls + return + var/turf/where_to = get_turf(target) + user.apply_damage(damage = roll_stamcost, damagetype = STAMINA) + user.Immobilize(0.8 SECONDS) // you dont get to adjust your roll + user.throw_at(where_to, range = roll_range, speed = 1, force = MOVE_FORCE_NORMAL, spin = roll_orientation) + user.apply_status_effect(/datum/status_effect/dodgeroll_iframes) + playsound(user, 'sound/effects/body-armor-rolling.ogg', 50, FALSE) + return ..() + +/datum/status_effect/dodgeroll_iframes + id = "dodgeroll_dodging" + alert_type = null + status_type = STATUS_EFFECT_REFRESH + duration = 0.8 SECONDS // worth tweaking? + +/datum/status_effect/dodgeroll_iframes/on_apply() + . = ..() + RegisterSignal(owner, COMSIG_LIVING_RUN_BLOCK, .proc/trolled) + +/datum/status_effect/dodgeroll_iframes/on_remove() + UnregisterSignal(owner, list( + COMSIG_LIVING_RUN_BLOCK + )) + return ..() + +/datum/status_effect/dodgeroll_iframes/proc/trolled(mob/living/source, real_attack, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list) + SIGNAL_HANDLER + owner.balloon_alert_to_viewers("missed!") + playsound(src, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) + return_list[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_PASSTHROUGH + return BLOCK_SUCCESS | BLOCK_SHOULD_REDIRECT | BLOCK_TARGET_DODGED + //Dragon /obj/structure/closet/crate/necropolis/dragon @@ -872,7 +924,7 @@ var/summon_cooldown = 0 var/list/mob/dead/observer/spirits -/obj/item/melee/ghost_sword/Initialize() +/obj/item/melee/ghost_sword/Initialize(mapload) . = ..() spirits = list() START_PROCESSING(SSobj, src) @@ -991,7 +1043,7 @@ user.mind.AddSpell(D) if(4) to_chat(user, "You feel like you could walk straight through lava now.") - H.weather_immunities |= "lava" + ADD_TRAIT(user, TRAIT_LAVA_IMMUNE, type) playsound(user.loc,'sound/items/drink.ogg', rand(10,50), 1) qdel(src) diff --git a/code/modules/mining/lavaland/ruins/gym.dm b/code/modules/mining/lavaland/ruins/gym.dm index c26631be74..68e0706d84 100644 --- a/code/modules/mining/lavaland/ruins/gym.dm +++ b/code/modules/mining/lavaland/ruins/gym.dm @@ -1,7 +1,7 @@ /obj/structure/punching_bag name = "punching bag" desc = "A punching bag. Can you get to speed level 4???" - icon = 'goon/icons/obj/fitness.dmi' + icon = 'icons/obj/fitness.dmi' icon_state = "punchingbag" anchored = TRUE layer = WALL_OBJ_LAYER @@ -12,7 +12,7 @@ . = ..() if(.) return - flick("[icon_state]2", src) + flick("[icon_state]-punch", src) playsound(loc, pick(hit_sounds), 25, 1, -1) if(isliving(user)) var/mob/living/L = user @@ -20,15 +20,24 @@ L.apply_status_effect(STATUS_EFFECT_EXERCISED) /obj/structure/weightmachine - name = "Weight Machine" desc = "Just looking at this thing makes you feel tired." + icon = 'icons/obj/fitness.dmi' density = TRUE anchored = TRUE - var/icon_state_inuse /obj/structure/weightmachine/proc/AnimateMachine(mob/living/user) return +/obj/structure/weightmachine/update_icon_state() + . = ..() + icon_state = (obj_flags & IN_USE) ? "[base_icon_state]-u" : base_icon_state + +/obj/structure/weightmachine/update_overlays() + . = ..() + + if(obj_flags & IN_USE) + . += mutable_appearance(icon, "[base_icon_state]-o", layer = ABOVE_MOB_LAYER, alpha = src.alpha) + /obj/structure/weightmachine/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) . = ..() if(.) @@ -38,7 +47,7 @@ return else obj_flags |= IN_USE - icon_state = icon_state_inuse + update_appearance() user.setDir(SOUTH) user.Stun(80) user.forceMove(src.loc) @@ -48,17 +57,17 @@ playsound(user, 'sound/machines/click.ogg', 60, 1) obj_flags &= ~IN_USE + update_appearance() user.pixel_y = 0 var/finishmessage = pick("You feel stronger!","You feel like you can take on the world!","You feel robust!","You feel indestructible!") SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "exercise", /datum/mood_event/exercise) - icon_state = initial(icon_state) to_chat(user, finishmessage) user.apply_status_effect(STATUS_EFFECT_EXERCISED) /obj/structure/weightmachine/stacklifter - icon = 'goon/icons/obj/fitness.dmi' - icon_state = "fitnesslifter" - icon_state_inuse = "fitnesslifter2" + name = "chest press machine" + icon_state = "stacklifter" + base_icon_state = "stacklifter" /obj/structure/weightmachine/stacklifter/AnimateMachine(mob/living/user) var/lifts = 0 @@ -69,27 +78,24 @@ animate(user, pixel_y = -2, time = 3) sleep(3) animate(user, pixel_y = -4, time = 3) - sleep(3) - playsound(user, 'goon/sound/effects/spring.ogg', 60, 1) + sleep(2) + playsound(user, 'sound/machines/creak.ogg', 60, 1) /obj/structure/weightmachine/weightlifter - icon = 'goon/icons/obj/fitness.dmi' - icon_state = "fitnessweight" - icon_state_inuse = "fitnessweight-c" + name = "inline bench press" + icon_state = "benchpress" + base_icon_state = "benchpress" /obj/structure/weightmachine/weightlifter/AnimateMachine(mob/living/user) - var/mutable_appearance/swole_overlay = mutable_appearance(icon, "fitnessweight-w", WALL_OBJ_LAYER) - add_overlay(swole_overlay) var/reps = 0 user.pixel_y = 5 while (reps++ < 6) if (user.loc != src.loc) break for (var/innerReps = max(reps, 1), innerReps > 0, innerReps--) - sleep(3) + sleep(4) animate(user, pixel_y = (user.pixel_y == 3) ? 5 : 3, time = 3) - playsound(user, 'goon/sound/effects/spring.ogg', 60, 1) + playsound(user, 'sound/machines/creak.ogg', 60, 1) sleep(3) animate(user, pixel_y = 2, time = 3) sleep(3) - cut_overlay(swole_overlay) diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index 851d78004b..0b7ca7adfd 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -65,7 +65,7 @@ var/obj/machinery/mineral/processing_unit/machine = null var/machinedir = EAST -/obj/machinery/mineral/processing_unit_console/Initialize() +/obj/machinery/mineral/processing_unit_console/Initialize(mapload) . = ..() machine = locate(/obj/machinery/mineral/processing_unit, get_step(src, machinedir)) if (machine) @@ -121,13 +121,14 @@ icon_state = "furnace" density = TRUE needs_item_input = TRUE + init_process = TRUE var/obj/machinery/mineral/CONSOLE = null var/on = FALSE var/datum/material/selected_material = null var/selected_alloy = null var/datum/techweb/stored_research -/obj/machinery/mineral/processing_unit/Initialize() +/obj/machinery/mineral/processing_unit/Initialize(mapload) . = ..() proximity_monitor = new(src, 1) AddComponent(/datum/component/material_container, list(/datum/material/iron, /datum/material/glass, /datum/material/silver, /datum/material/gold, /datum/material/diamond, /datum/material/plasma, /datum/material/uranium, /datum/material/bananium, /datum/material/titanium, /datum/material/bluespace), INFINITY, TRUE, /obj/item/stack) diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index 1adc951447..32b79343e8 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -11,6 +11,7 @@ output_dir = SOUTH req_access = list(ACCESS_MINERAL_STOREROOM) speed_process = TRUE + init_process = TRUE circuit = /obj/item/circuitboard/machine/ore_redemption layer = BELOW_OBJ_LAYER var/points = 0 @@ -346,7 +347,7 @@ to_chat(usr, "Required access not found.") return TRUE -/obj/machinery/mineral/ore_redemption/ex_act(severity, target) +/obj/machinery/mineral/ore_redemption/ex_act(severity, target, origin) do_sparks(5, TRUE, src) ..() diff --git a/code/modules/mining/machine_silo.dm b/code/modules/mining/machine_silo.dm index 34b349b198..e6281bb695 100644 --- a/code/modules/mining/machine_silo.dm +++ b/code/modules/mining/machine_silo.dm @@ -243,3 +243,17 @@ GLOBAL_LIST_EMPTY(silo_access_logs) sep = ", " msg += "[amount < 0 ? "-" : "+"][val] [M.name]" formatted = msg.Join() + +/obj/machinery/ore_silo/on_object_saved(var/depth = 0) + if(depth >= 10) + return "" + var/dat + var/datum/component/material_container/material_holder = GetComponent(/datum/component/material_container) + for(var/each in material_holder.materials) + var/amount = material_holder.materials[each] / MINERAL_MATERIAL_AMOUNT + var/datum/material/material_datum = each + while(amount > 0) + var/amount_in_stack = max(1, min(50, amount)) + amount -= amount_in_stack + dat += "[dat ? ",\n" : ""][material_datum.sheet_type]{\n\tamount = [amount_in_stack]\n\t}" + return dat diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm index 40f4db3660..c06a090314 100644 --- a/code/modules/mining/machine_stacking.dm +++ b/code/modules/mining/machine_stacking.dm @@ -12,7 +12,7 @@ /// Direction for which console looks for stacking machine to connect to var/machinedir = SOUTHEAST -/obj/machinery/mineral/stacking_unit_console/Initialize() +/obj/machinery/mineral/stacking_unit_console/Initialize(mapload) . = ..() machine = locate(/obj/machinery/mineral/stacking_machine, get_step(src, machinedir)) if (machine) diff --git a/code/modules/mining/machine_unloading.dm b/code/modules/mining/machine_unloading.dm index b39b0df6ab..16b3b3967f 100644 --- a/code/modules/mining/machine_unloading.dm +++ b/code/modules/mining/machine_unloading.dm @@ -9,6 +9,7 @@ input_dir = WEST output_dir = EAST speed_process = TRUE + init_process = TRUE /obj/machinery/mineral/unloading_machine/proc/horrible_quadratic_monster(var/turf/T) set waitfor = FALSE diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 7a3cd9140b..72f261e1f5 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -11,7 +11,6 @@ var/obj/item/card/id/inserted_id var/list/prize_list = list( //if you add something to this, please, for the love of god, sort it by price/type. use tabs and not spaces. new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 10), - new /datum/data/mining_equipment("50 Point Transfer Card", /obj/item/card/mining_point_card, 50), new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100), new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300), new /datum/data/mining_equipment("Whiskey", /obj/item/reagent_containers/food/drinks/bottle/whiskey, 100), @@ -27,7 +26,7 @@ new /datum/data/mining_equipment("GAR Meson Scanners", /obj/item/clothing/glasses/meson/gar, 500), new /datum/data/mining_equipment("Explorer's Webbing", /obj/item/storage/belt/mining, 500), new /datum/data/mining_equipment("Larger Ore Bag", /obj/item/storage/bag/ore/large, 500), - new /datum/data/mining_equipment("500 Point Transfer Card", /obj/item/card/mining_point_card/mp500, 500), + new /datum/data/mining_equipment("Mining Point Transfer Card", /obj/item/card/mining_point_card, 500), new /datum/data/mining_equipment("Tracking Implant Kit", /obj/item/storage/box/minertracker, 600), new /datum/data/mining_equipment("Jaunter", /obj/item/wormhole_jaunter, 750), new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/kinetic_crusher, 750), @@ -43,9 +42,6 @@ new /datum/data/mining_equipment("Lazarus Injector", /obj/item/lazarus_injector, 1000), new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/pickaxe/silver, 1000), new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffelbag/mining/conscript, 1000), - new /datum/data/mining_equipment("1000 Point Transfer Card", /obj/item/card/mining_point_card/mp1000, 1000), - new /datum/data/mining_equipment("1500 Point Transfer Card", /obj/item/card/mining_point_card/mp1500, 1500), - new /datum/data/mining_equipment("2000 Point Transfer Card", /obj/item/card/mining_point_card/mp2000, 2000), new /datum/data/mining_equipment("Jetpack Upgrade", /obj/item/tank/jetpack/suit, 2000), new /datum/data/mining_equipment("Space Cash", /obj/item/stack/spacecash/c1000, 2000), new /datum/data/mining_equipment("Mining Hardsuit", /obj/item/clothing/suit/space/hardsuit/mining, 2000), @@ -57,7 +53,8 @@ new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/survivalcapsule/luxury, 3000), new /datum/data/mining_equipment("Luxury Bar Capsule", /obj/item/survivalcapsule/luxury/elitebar, 10000), new /datum/data/mining_equipment("Empty Capsule", /obj/item/survivalcapsule/luxury/empty, 5000), - new /datum/data/mining_equipment("Penthouse Capsule", /obj/item/survivalcapsule/luxury/penthouse, 15000), + new /datum/data/mining_equipment("Penthouse Capsule", /obj/item/survivalcapsule/luxury/penthouse, 7500), + new /datum/data/mining_equipment("Garden & Kitchen Capsule", /obj/item/survivalcapsule/luxury/garden, 7500), new /datum/data/mining_equipment("Nanotrasen Minebot", /mob/living/simple_animal/hostile/mining_drone, 800), new /datum/data/mining_equipment("Minebot Melee Upgrade", /obj/item/mine_bot_upgrade, 400), new /datum/data/mining_equipment("Minebot Armor Upgrade", /obj/item/mine_bot_upgrade/health, 400), @@ -74,8 +71,9 @@ new /datum/data/mining_equipment("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000), new /datum/data/mining_equipment("Miner Full Replacement", /obj/item/storage/backpack/duffelbag/mining/cloned, 3000), new /datum/data/mining_equipment("Premium Accelerator", /obj/item/gun/energy/kinetic_accelerator/premiumka, 8000), - new /datum/data/mining_equipment("Kinetic Glaive Kit", /obj/item/storage/backpack/duffelbag/mining/glaivekit, 2250), + new /datum/data/mining_equipment("Premium Kinetic Melee Kit", /obj/item/storage/backpack/duffelbag/mining/glaivekit, 2250), new /datum/data/mining_equipment("Survival Dagger", /obj/item/kitchen/knife/combat/survival/knuckledagger, 550), + new /datum/data/mining_equipment("Premium KA borg Upgrade", /obj/item/borg/upgrade/premiumka, 8000) ) /datum/data/mining_equipment @@ -88,7 +86,7 @@ src.equipment_path = path src.cost = cost -/obj/machinery/mineral/equipment_vendor/Initialize() +/obj/machinery/mineral/equipment_vendor/Initialize(mapload) . = ..() build_inventory() @@ -130,7 +128,7 @@ . = list() var/mob/living/carbon/human/H var/obj/item/card/id/C - if(ishuman(user)) + if(ishuman(user) || iscyborg(user)) H = user C = H.get_idcard(TRUE) if(C) @@ -166,6 +164,7 @@ return I.mining_points -= prize.cost to_chat(usr, "[src] clanks to life briefly before vending [prize.equipment_name]!") + playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3) new prize.equipment_path(loc) SSblackbox.record_feedback("nested tally", "mining_equipment_bought", 1, list("[type]", "[prize.equipment_path]")) . = TRUE @@ -187,6 +186,9 @@ if(istype(I, /obj/item/suit_voucher)) RedeemSVoucher(I, user) return + if(istype(I, /obj/item/premium_crusher_voucher)) + RedeemPCVoucher(I, user) + return if(default_deconstruction_screwdriver(user, "mining-open", "mining", I)) updateUsrDialog() return @@ -226,11 +228,47 @@ new /obj/item/kinetic_crusher(drop_location) if("Mining Conscription Kit") new /obj/item/storage/backpack/duffelbag/mining/conscript(drop_location) - + playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3) SSblackbox.record_feedback("tally", "mining_voucher_redeemed", 1, selection) qdel(voucher) -/obj/machinery/mineral/equipment_vendor/ex_act(severity, target) +/obj/machinery/mineral/equipment_vendor/proc/RedeemSVoucher(obj/item/suit_voucher/voucher, mob/redeemer) + var/items = list( "Exo-suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "exo"), + "HEVA suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "heva")) + + var/selection = show_radial_menu(redeemer, src, items, require_near = TRUE, tooltips = TRUE) + if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer) + return + var/drop_location = drop_location() + switch(selection) + if("Exo-suit") + new /obj/item/clothing/suit/hooded/explorer/exo(drop_location) + new /obj/item/clothing/mask/gas/exo(drop_location) + if("HEVA suit") + new /obj/item/clothing/suit/hooded/explorer/heva(drop_location) + new /obj/item/clothing/mask/gas/heva(drop_location) + playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3) + SSblackbox.record_feedback("tally", "suit_voucher_redeemed", 1, selection) + qdel(voucher) + +/obj/machinery/mineral/equipment_vendor/proc/RedeemPCVoucher(obj/item/premium_crusher_voucher/voucher, mob/redeemer) // someone should REALLY just refactor this + var/items = list("Kinetic Glaive" = image(icon = 'icons/obj/mining.dmi', icon_state = "crusher-glaive"), + "Kinetic Gauntlets" = image(icon = 'icons/obj/mining.dmi', icon_state = "crusher-hands")) + + var/selection = show_radial_menu(redeemer, src, items, require_near = TRUE, tooltips = TRUE) + if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer) + return + var/drop_location = drop_location() + switch(selection) + if("Kinetic Glaive") + new /obj/item/kinetic_crusher/glaive(drop_location) + if("Kinetic Gauntlets") + new /obj/item/kinetic_crusher/glaive/gauntlets(drop_location) + playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3) + SSblackbox.record_feedback("tally", "crusher_voucher_redeemed", 1, selection) + qdel(voucher) + +/obj/machinery/mineral/equipment_vendor/ex_act(severity, target, origin) do_sparks(5, TRUE, src) if(prob(50 / severity) && severity < 3) qdel(src) @@ -241,11 +279,11 @@ name = "golem ship equipment vendor" circuit = /obj/item/circuitboard/machine/mining_equipment_vendor/golem -/obj/machinery/mineral/equipment_vendor/golem/Initialize() +/obj/machinery/mineral/equipment_vendor/golem/Initialize(mapload) . = ..() desc += "\nIt seems a few selections have been added." prize_list += list( - new /datum/data/mining_equipment("Extra Id", /obj/item/card/id/mining, 250), + new /datum/data/mining_equipment("Extra ID", /obj/item/card/id/mining, 250), new /datum/data/mining_equipment("Science Goggles", /obj/item/clothing/glasses/science, 250), new /datum/data/mining_equipment("Monkey Cube", /obj/item/reagent_containers/food/snacks/cube/monkey, 300), new /datum/data/mining_equipment("Toolbelt", /obj/item/storage/belt/utility, 350), @@ -273,34 +311,44 @@ icon_state = "mining_voucher" w_class = WEIGHT_CLASS_TINY +/obj/item/premium_crusher_voucher + name = "premium crusher voucher" + desc = "A token to redeem for a premium proto-kinetic melee weapon. Use it on a mining equipment vendor." + icon = 'icons/obj/mining.dmi' + icon_state = "mining_voucher" + w_class = WEIGHT_CLASS_TINY + /**********************Mining Point Card**********************/ //mp = Miner Pointers //c = Cash //TODO add in cr = Credits for cargo /obj/item/card/mining_point_card name = "mining points card" - desc = "A small card preloaded with mining points. Swipe your ID card over it to transfer the points, then discard. This one only holds a small 50 points on it." + desc = "A small card for transferring mining points. Swipe your ID card over it to start the process." icon_state = "data_1" - var/points = 50 - -/obj/item/card/mining_point_card/mp500 - desc = "A small card preloaded with 500 mining points. Swipe your ID card over it to transfer the points, then discard." - points = 500 - -/obj/item/card/mining_point_card/mp1000 - desc = "A small card preloaded with 1000 mining points. Swipe your ID card over it to transfer the points, then discard." - points = 1000 - -/obj/item/card/mining_point_card/mp1500 - desc = "A small card preloaded with 1500 mining points. Swipe your ID card over it to transfer the points, then discard." - points = 1500 - -/obj/item/card/mining_point_card/mp2000 - desc = "A small card preloaded with 2000 mining points. Swipe your ID card over it to transfer the points, then discard." - points = 2000 + var/points = 500 /obj/item/card/mining_point_card/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/card/id)) + var/obj/item/card/id/id = I + to_chat(user, span_info("You swipe [id] on [src] and start the transfer process.")) + var/choice = alert(user, "Do you want to transfer points to or from the point card's storage?", "Mining Points Transfer", "From Point Card/Storage", "To Point Card/Storage", "Cancel") + if(choice != "Cancel") + var/amount = input(user, "How much do you want to transfer? ID Balance: [id.mining_points], Transfer Card Balance: [points]", "Transfer Points") as num|null + if(!amount || amount <= 0) + return + amount = round(amount, 1) + if(choice == "To Point Card/Storage") + if(amount && amount <= id.mining_points) + id.mining_points -= amount + points += amount + to_chat(user, span_info("You transfer [amount] points to [src] from [id].")) + else if(choice == "From Point Card/Storage") + if(amount && amount <= points) + id.mining_points += amount + points -= amount + to_chat(user, span_info("You transfer [amount] points to [id] from [src].")) + /* if(points) var/obj/item/card/id/C = I C.mining_points += points @@ -308,6 +356,7 @@ points = 0 else to_chat(user, "There's no points left on [src].") + */ ..() /obj/item/card/mining_point_card/examine(mob/user) @@ -375,24 +424,5 @@ /obj/item/storage/backpack/duffelbag/mining/glaivekit /obj/item/storage/backpack/duffelbag/mining/glaivekit/PopulateContents() - new /obj/item/kinetic_crusher/glaive(src) new /obj/item/kitchen/knife/combat/survival/knuckledagger(src) - -/obj/machinery/mineral/equipment_vendor/proc/RedeemSVoucher(obj/item/suit_voucher/voucher, mob/redeemer) - var/items = list( "Exo-suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "exo"), - "SEVA suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "seva")) - - var/selection = show_radial_menu(redeemer, src, items, require_near = TRUE, tooltips = TRUE) - if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer) - return - var/drop_location = drop_location() - switch(selection) - if("Exo-suit") - new /obj/item/clothing/suit/hooded/explorer/exo(drop_location) - new /obj/item/clothing/mask/gas/exo(drop_location) - if("SEVA suit") - new /obj/item/clothing/suit/hooded/explorer/seva(drop_location) - new /obj/item/clothing/mask/gas/seva(drop_location) - - SSblackbox.record_feedback("tally", "suit_voucher_redeemed", 1, selection) - qdel(voucher) + new /obj/item/premium_crusher_voucher(src) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index e9c38398fb..091e80aef6 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -8,7 +8,7 @@ var/set_luminosity = 8 var/set_cap = 0 -/obj/effect/light_emitter/Initialize() +/obj/effect/light_emitter/Initialize(mapload) . = ..() set_light(set_luminosity, set_cap) diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm index 8037a22a52..69b5de963d 100644 --- a/code/modules/mining/minebot.dm +++ b/code/modules/mining/minebot.dm @@ -39,7 +39,7 @@ var/light_on = 0 var/obj/item/gun/energy/kinetic_accelerator/minebot/stored_gun -/mob/living/simple_animal/hostile/mining_drone/Initialize() +/mob/living/simple_animal/hostile/mining_drone/Initialize(mapload) . = ..() stored_gun = new(src) var/datum/action/innate/minedrone/toggle_light/toggle_light_action = new() @@ -131,7 +131,8 @@ to_chat(M, "[src] has been set to attack hostile wildlife.") return -/mob/living/simple_animal/hostile/mining_drone/CanPass(atom/movable/O) +/mob/living/simple_animal/hostile/mining_drone/CanAllowThrough(atom/movable/O) + . = ..() if(istype(O, /obj/item/projectile/kinetic)) var/obj/item/projectile/kinetic/K = O if(K.kinetic_gun) @@ -141,7 +142,6 @@ return TRUE if(istype(O, /obj/item/projectile/destabilizer)) return TRUE - return ..() /mob/living/simple_animal/hostile/mining_drone/proc/SetCollectBehavior() mode = MINEDRONE_COLLECT diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm deleted file mode 100644 index f8a4ba4a72..0000000000 --- a/code/modules/mining/mint.dm +++ /dev/null @@ -1,146 +0,0 @@ -/**********************Mint**************************/ - - -/obj/machinery/mineral/mint - name = "coin press" - icon = 'icons/obj/economy.dmi' - icon_state = "coinpress0" - density = TRUE - input_dir = EAST - ui_x = 300 - ui_y = 250 - needs_item_input = TRUE - var/obj/item/storage/bag/money/bag_to_use - var/produced_coins = 0 // how many coins the machine has made in it's last cycle - var/processing = FALSE - var/chosen = /datum/material/iron //which material will be used to make coins - - -/obj/machinery/mineral/mint/Initialize() - . = ..() - AddComponent(/datum/component/material_container, list( - /datum/material/iron, - /datum/material/plasma, - /datum/material/silver, - /datum/material/gold, - /datum/material/uranium, - /datum/material/titanium, - /datum/material/diamond, - /datum/material/bananium, - /datum/material/adamantine, - /datum/material/mythril, - /datum/material/plastic, - /datum/material/runite - ), MINERAL_MATERIAL_AMOUNT * 75, FALSE, /obj/item/stack) - chosen = SSmaterials.GetMaterialRef(chosen) - - -/obj/machinery/mineral/mint/pickup_item(datum/source, atom/movable/target, atom/oldLoc) - if(QDELETED(target)) - return - if(!istype(target, /obj/item/stack)) - return - - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - var/obj/item/stack/S = target - - if(materials.insert_item(S)) - qdel(S) - -/obj/machinery/mineral/mint/process() - if(processing) - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - var/datum/material/M = chosen - - if(!M) - processing = FALSE - icon_state = "coinpress0" - return - - icon_state = "coinpress1" - var/coin_mat = MINERAL_MATERIAL_AMOUNT - - for(var/sheets in 1 to 2) - if(materials.use_amount_mat(coin_mat, chosen)) - for(var/coin_to_make in 1 to 5) - create_coins() - else - var/found_new = FALSE - for(var/datum/material/inserted_material in materials.materials) - var/amount = materials.get_material_amount(inserted_material) - - if(amount) - chosen = inserted_material - found_new = TRUE - - if(!found_new) - processing = FALSE - else - STOP_PROCESSING(SSmachines, src) - icon_state = "coinpress0" - -/obj/machinery/mineral/mint/ui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "Mint", name) - ui.open() - -/obj/machinery/mineral/mint/ui_data() - var/list/data = list() - data["inserted_materials"] = list() - data["chosen_material"] = null - - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - for(var/datum/material/inserted_material in materials.materials) - var/amount = materials.get_material_amount(inserted_material) - if(!amount) - continue - data["inserted_materials"] += list(list( - "material" = inserted_material.name, - "amount" = amount, - )) - if(chosen == inserted_material) - data["chosen_material"] = inserted_material.name - - data["produced_coins"] = produced_coins - data["processing"] = processing - - return data; - -/obj/machinery/mineral/mint/ui_act(action, params, datum/tgui/ui) - . = ..() - if(.) - return - if(action == "startpress") - if (!processing) - produced_coins = 0 - processing = TRUE - START_PROCESSING(SSmachines, src) - return TRUE - if (action == "stoppress") - processing = FALSE - STOP_PROCESSING(SSmachines, src) - return TRUE - if (action == "changematerial") - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - for(var/datum/material/mat in materials.materials) - if (params["material_name"] == mat.name) - chosen = mat - return TRUE - -/obj/machinery/mineral/mint/proc/create_coins() - set waitfor = FALSE - var/turf/T = get_step(src,output_dir) - var/temp_list = list() - temp_list[chosen] = 400 - if(T) - var/obj/item/O = new /obj/item/coin(src) - O.set_custom_materials(temp_list) - if(QDELETED(bag_to_use) || (bag_to_use.loc != T) || !SEND_SIGNAL(bag_to_use, COMSIG_TRY_STORAGE_INSERT, O, null, TRUE)) //important to send the signal so we don't overfill the bag. - bag_to_use = new(src) //make a new bag if we can't find or use the old one. - unload_mineral(bag_to_use) //just forcemove memes. - O.forceMove(bag_to_use) //don't bother sending the signal, the new bag is empty and all that. - - SSblackbox.record_feedback("amount", "coins_minted", 1) - produced_coins++ - CHECK_TICK diff --git a/code/modules/mining/money_bag.dm b/code/modules/mining/money_bag.dm index 7be07f2bf9..b9365d2f9d 100644 --- a/code/modules/mining/money_bag.dm +++ b/code/modules/mining/money_bag.dm @@ -9,7 +9,7 @@ max_integrity = 100 w_class = WEIGHT_CLASS_BULKY -/obj/item/storage/bag/money/Initialize() +/obj/item/storage/bag/money/Initialize(mapload) . = ..() if(prob(20)) icon_state = "moneybagalt" diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index 71f84e898c..056ad2d642 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -72,7 +72,7 @@ /obj/item/stack/ore/uranium name = "uranium ore" icon_state = "Uranium ore" - // inhand_icon_state = "Uranium ore" + // item_state = "Uranium ore" singular_name = "uranium ore chunk" points = 30 // material_flags = MATERIAL_NO_EFFECTS @@ -152,7 +152,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ C.forcesay("*scream") qdel(src) -/obj/item/stack/ore/glass/ex_act(severity, target) +/obj/item/stack/ore/glass/ex_act(severity, target, origin) if (severity == EXPLODE_NONE) return qdel(src) @@ -314,7 +314,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ GibtoniteReaction(P.firer) . = ..() -/obj/item/gibtonite/ex_act() +/obj/item/gibtonite/ex_act(severity, target, origin) GibtoniteReaction(null, 1) /obj/item/gibtonite/proc/GibtoniteReaction(mob/user, triggered_by = 0) @@ -356,7 +356,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ pixel_x = initial(pixel_x) + rand(0, 16) - 8 pixel_y = initial(pixel_y) + rand(0, 8) - 8 -/obj/item/stack/ore/ex_act(severity, target) +/obj/item/stack/ore/ex_act(severity, target, origin) if (!severity || severity >= 2) return qdel(src) @@ -384,7 +384,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ var/coinflip item_flags = NO_MAT_REDEMPTION //You know, it's kind of a problem that money is worth more extrinsicly than intrinsically in this universe. -/obj/item/coin/Initialize() +/obj/item/coin/Initialize(mapload) . = ..() coinflip = pick(sideslist) icon_state = "coin_[coinflip]" diff --git a/code/modules/mining/shelters.dm b/code/modules/mining/shelters.dm index 83a8412ca8..a349622028 100644 --- a/code/modules/mining/shelters.dm +++ b/code/modules/mining/shelters.dm @@ -96,3 +96,22 @@ . = ..() whitelisted_turfs = typecacheof(/turf/closed/mineral) banned_objects = typecacheof(/obj/structure/stone_tile) + +/datum/map_template/shelter/zeta + name = "Shelter zeta" + shelter_id = "shelter_zeta" + description = "A survival capsule with a garden and kitchen. Commonly used by space fast food joints everywhere." + mappath = "_maps/templates/shelter_6.dmm" + +/datum/map_template/shelter/zeta/New() + . = ..() + whitelisted_turfs = typecacheof(/turf/closed/mineral) + banned_objects = typecacheof(/obj/structure/stone_tile) + +// yes, I COULD make it a seperate object from the surv capsule but the code needed is indeticle soo... + +/datum/map_template/shelter/reactor + name = "RBMK Reactor" + shelter_id = "reactor" + description = "A reactor core, coolant and moderator loop not included." + mappath = "_maps/templates/reactor_1.dmm" diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index 5647bc2305..b455787e5c 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -7,13 +7,13 @@ INITIALIZE_IMMEDIATE(/mob/dead) move_resist = INFINITY throwforce = 0 -/mob/dead/Initialize() +/mob/dead/Initialize(mapload) SHOULD_CALL_PARENT(FALSE) if(flags_1 & INITIALIZED_1) stack_trace("Warning: [src]([type]) initialized multiple times!") flags_1 |= INITIALIZED_1 tag = "mob_[next_mob_id++]" - GLOB.mob_list += src + add_to_mob_list() prepare_huds() @@ -121,10 +121,13 @@ INITIALIZE_IMMEDIATE(/mob/dead) if (isturf(T)) update_z(T.z) +/mob/dead/auto_deadmin_on_login() + return + /mob/dead/Logout() update_z(null) return ..() /mob/dead/onTransitZ(old_z,new_z) - ..() + . = ..() update_z(new_z) diff --git a/code/modules/mob/dead/new_player/login.dm b/code/modules/mob/dead/new_player/login.dm index 887556500c..dbcc2cb2b4 100644 --- a/code/modules/mob/dead/new_player/login.dm +++ b/code/modules/mob/dead/new_player/login.dm @@ -9,6 +9,12 @@ ..() + if(!age_verify()) + return + + if(!client) //client can end up null as a result of age_verify() kicking those who fail + return + var/motd = global.config.motd if(motd) to_chat(src, "
    [motd]
    ", handle_whitespace=FALSE) @@ -22,8 +28,11 @@ sight |= SEE_TURFS - new_player_panel() client.playtitlemusic() + + var/datum/asset/asset_datum = get_asset_datum(/datum/asset/simple/lobby) + asset_datum.send(client) + if(SSticker.current_state < GAME_STATE_SETTING_UP) var/tl = SSticker.GetTimeLeft() var/postfix @@ -32,3 +41,7 @@ else postfix = "soon" to_chat(src, "Please set up your character and select \"Ready\". The game will start [postfix].") + + var/datum/hud/new_player/NH = hud_used + if(istype(NH)) + NH.populate_buttons(src) diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index f7f3450f6e..b627d4cb69 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -1,8 +1,9 @@ -#define LINKIFY_READY(string, value) "[string]" - +///Cooldown for the Reset Lobby Menu HUD verb +#define RESET_HUD_INTERVAL 15 SECONDS /mob/dead/new_player var/ready = 0 - var/spawning = 0//Referenced when you want to delete the new_player later on in the code. + ///Referenced when you want to delete the new_player later on in the code. + var/spawning = 0 flags_1 = NONE @@ -10,16 +11,21 @@ density = FALSE stat = DEAD + hud_type = /datum/hud/new_player + hud_possible = list() - var/mob/living/new_character //for instant transfer once the round is set up + ///For instant transfer once the round is set up + var/mob/living/new_character - //Used to make sure someone doesn't get spammed with messages if they're ineligible for roles + ///Used to make sure someone doesn't get spammed with messages if they're ineligible for roles var/ineligible_for_roles = FALSE - //is there a result we want to read from the age gate + ///Is there a result we want to read from the age gate var/age_gate_result + ///Cooldown for the Reset Lobby Menu HUD verb + COOLDOWN_DECLARE(reset_hud_cooldown) -/mob/dead/new_player/Initialize() +/mob/dead/new_player/Initialize(mapload) if(client && SSticker.state == GAME_STATE_STARTUP) var/atom/movable/screen/splash/S = new(client, TRUE, TRUE) S.Fade(TRUE) @@ -33,72 +39,17 @@ . = ..() + GLOB.new_player_list += src + add_verb(src, /mob/dead/new_player/proc/reset_menu_hud) + +/mob/dead/new_player/Destroy() + GLOB.new_player_list -= src + + return ..() + /mob/dead/new_player/prepare_huds() return -/mob/dead/new_player/proc/new_player_panel() - var/output = "

    Welcome, [client ? client.prefs.real_name : "Unknown User"]

    " - output += "

    Setup Character

    " - - if(SSticker.current_state <= GAME_STATE_PREGAME) - switch(ready) - if(PLAYER_NOT_READY) - output += "

    \[ [LINKIFY_READY("Ready", PLAYER_READY_TO_PLAY)] | Not Ready | [LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)] \]

    " - if(PLAYER_READY_TO_PLAY) - output += "

    \[ Ready | [LINKIFY_READY("Not Ready", PLAYER_NOT_READY)] | [LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)] \]

    " - if(PLAYER_READY_TO_OBSERVE) - output += "

    \[ [LINKIFY_READY("Ready", PLAYER_READY_TO_PLAY)] | [LINKIFY_READY("Not Ready", PLAYER_NOT_READY)] | Observe \]

    " - else - output += "

    View the Crew Manifest

    " - output += "

    Join Game!

    " - output += "

    [LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)]

    " - - if(!IsGuestKey(src.key)) - output += playerpolls() - - output += "
    " - - //src << browse(output,"window=playersetup;size=210x240;can_close=0") - var/datum/browser/popup = new(src, "playersetup", "
    New Player Options
    ", 250, 265) - popup.set_window_options("can_close=0") - popup.set_content(output) - popup.open(FALSE) - -/mob/dead/new_player/proc/playerpolls() - var/output = "" //hey tg why is this a list? - if (SSdbcore.Connect()) - var/isadmin = FALSE - if(client?.holder) - isadmin = TRUE - var/datum/db_query/query_get_new_polls = SSdbcore.NewQuery({" - SELECT id FROM [format_table_name("poll_question")] - WHERE (adminonly = 0 OR :isadmin = 1) - AND Now() BETWEEN starttime AND endtime - AND deleted = 0 - AND id NOT IN ( - SELECT pollid FROM [format_table_name("poll_vote")] - WHERE ckey = :ckey - AND deleted = 0 - ) - AND id NOT IN ( - SELECT pollid FROM [format_table_name("poll_textreply")] - WHERE ckey = :ckey - AND deleted = 0 - ) - "}, list("isadmin" = isadmin, "ckey" = ckey)) - var/rs = REF(src) - if(!query_get_new_polls.Execute()) - qdel(query_get_new_polls) - return - if(query_get_new_polls.NextRow()) - output += "

    Show Player Polls (NEW!)

    " - else - output += "

    Show Player Polls

    " - qdel(query_get_new_polls) - if(QDELETED(src)) - return - return output - /mob/dead/new_player/proc/age_gate() var/list/dat = list("
    ") dat += "Enter your date of birth here, to confirm that you are over 18.
    " @@ -145,6 +96,9 @@ if(!(client.prefs.db_flags & DB_FLAG_AGE_CONFIRMATION_INCOMPLETE)) //completed? Skip return TRUE + if(!client) + return FALSE + var/age_verification = age_gate() //ban them and kick them if(age_verification != 1) @@ -262,61 +216,12 @@ if(!age_verify()) return - //Determines Relevent Population Cap - var/relevant_cap - var/hpc = CONFIG_GET(number/hard_popcap) - var/epc = CONFIG_GET(number/extreme_popcap) - if(hpc && epc) - relevant_cap = min(hpc, epc) - else - relevant_cap = max(hpc, epc) - - if(href_list["show_preferences"]) - client.prefs.ShowChoices(src) - return 1 - - if(href_list["ready"]) - var/tready = text2num(href_list["ready"]) - //Avoid updating ready if we're after PREGAME (they should use latejoin instead) - //This is likely not an actual issue but I don't have time to prove that this - //no longer is required - if(SSticker.current_state <= GAME_STATE_PREGAME) - ready = tready - //if it's post initialisation and they're trying to observe we do the needful - if(!SSticker.current_state < GAME_STATE_PREGAME && tready == PLAYER_READY_TO_OBSERVE) - ready = tready - make_me_an_observer() - return - - if(href_list["refresh"]) - src << browse(null, "window=playersetup") //closes the player setup window - new_player_panel() - if(href_list["late_join"]) if(!SSticker || !SSticker.IsRoundInProgress()) to_chat(usr, "The round is either not ready, or has already finished...") return - - if(href_list["late_join"] == "override") - LateChoices() - return - - if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(key) in GLOB.admin_datums))) - to_chat(usr, "[CONFIG_GET(string/hard_popcap_message)]") - - var/queue_position = SSticker.queued_players.Find(usr) - if(queue_position == 1) - to_chat(usr, "You are next in line to join the game. You will be notified when a slot opens up.") - else if(queue_position) - to_chat(usr, "There are [queue_position-1] players in front of you in the queue to join the game.") - else - SSticker.queued_players += usr - to_chat(usr, "You have been added to the queue to join the game. Your position in queue is [SSticker.queued_players.len].") - return LateChoices() - - if(href_list["manifest"]) - ViewManifest() + return if(href_list["SelectedJob"]) if(!SSticker || !SSticker.IsRoundInProgress()) @@ -330,6 +235,17 @@ to_chat(usr, "There is an administrative lock on entering the game!") return + //Determines Relevent Population Cap + var/relevant_cap + var/hpc = CONFIG_GET(number/hard_popcap) + var/epc = CONFIG_GET(number/extreme_popcap) + if(hpc && epc) + relevant_cap = min(hpc, epc) + else + relevant_cap = max(hpc, epc) + + + if(SSticker.queued_players.len && !(ckey(key) in GLOB.admin_datums)) if((living_player_count() >= relevant_cap) || (src != SSticker.queued_players[1])) to_chat(usr, "Server is full.") @@ -342,6 +258,15 @@ if(!GLOB.enter_allowed) to_chat(usr, " There is an administrative lock on entering the game!") + //Determines Relevent Population Cap + var/relevant_cap + var/hpc = CONFIG_GET(number/hard_popcap) + var/epc = CONFIG_GET(number/extreme_popcap) + if(hpc && epc) + relevant_cap = min(hpc, epc) + else + relevant_cap = max(hpc, epc) + if(SSticker.queued_players.len && !(ckey(key) in GLOB.admin_datums)) if((living_player_count() >= relevant_cap) || (src != SSticker.queued_players[1])) to_chat(usr, "Server is full.") @@ -353,13 +278,6 @@ SSticker.queue_delay = 4 qdel(src) - else if(!href_list["late_join"]) - new_player_panel() - - if(href_list["showpoll"]) - handle_player_polling() - return - if(href_list["pollid"]) var/pollid = href_list["pollid"] if(istext(pollid)) @@ -391,7 +309,7 @@ var/id_max = text2num(href_list["maxid"]) if( (id_max - id_min) > 100 ) //Basic exploit prevention - //(protip, this stops no exploits) + //(protip, this stops no exploits) to_chat(usr, "The option ID difference is too big. Please contact administration or the database admin.") return @@ -440,6 +358,11 @@ return to_chat(src, "Vote successful.") +/mob/dead/new_player/get_status_tab_items() + . = ..() + if(!SSticker.HasRoundStarted()) //only show this when the round hasn't started yet + . += "Readiness status: [ready ? "" : "Not "]Readied Up!" + //When you cop out of the round (NB: this HAS A SLEEP FOR PLAYER INPUT IN IT) /mob/dead/new_player/proc/make_me_an_observer() if(QDELETED(src) || !src.client) @@ -453,7 +376,6 @@ if(QDELETED(src) || !src.client || this_is_like_playing_right != "Yes") ready = PLAYER_NOT_READY src << browse(null, "window=playersetup") //closes the player setup window - new_player_panel() return FALSE var/mob/dead/observer/observer = new() @@ -558,12 +480,14 @@ SSjob.AssignRole(src, rank, 1) var/mob/living/character = create_character(TRUE) //creates the human and transfers vars and mind + var/datum/job/job = SSjob.GetJob(rank) + var/equip = SSjob.EquipRank(character, rank, TRUE) + job.after_latejoin_spawn(character) + if(isliving(equip)) //Borgs get borged in the equip, so we need to make sure we handle the new mob. character = equip - var/datum/job/job = SSjob.GetJob(rank) - if(job && !job.override_latejoin_spawn(character)) SSjob.SendToLateJoin(character) if(!arrivals_docked) @@ -571,8 +495,6 @@ Spl.Fade(TRUE) character.playsound_local(get_turf(character), 'sound/voice/ApproachingTG.ogg', 25) - character.update_parallax_teleport() - job.standard_assign_skills(character.mind) SSticker.minds += character.mind @@ -586,7 +508,7 @@ if(SSshuttle.arrivals) SSshuttle.arrivals.QueueAnnounce(humanc, rank) else - AnnounceArrival(humanc, rank) + announce_arrival(humanc, rank) AddEmploymentContract(humanc) if(GLOB.highlander) to_chat(humanc, "THERE CAN BE ONLY ONE!!!") @@ -667,13 +589,23 @@ for(var/job in category) var/datum/job/job_datum = SSjob.name_occupations[job] if(job_datum && IsJobUnavailable(job_datum.title, TRUE) == JOB_AVAILABLE) + // Get currently occupied slots + var/num_positions_current = job_datum.current_positions + + // Get total slots that can be occupied + var/num_positions_total = job_datum.total_positions + + // Change to lemniscate for infinite-slot jobs + // This variable should only used to display text! + num_positions_total = (num_positions_total == -1 ? "∞" : num_positions_total) + var/command_bold = "" if(job in GLOB.command_positions) command_bold = " command" if(job_datum in SSjob.prioritized_jobs) - dept_dat += "[job_datum.title] ([job_datum.current_positions])" + dept_dat += "[job_datum.title] ([num_positions_current]/[num_positions_total])" else - dept_dat += "[job_datum.title] ([job_datum.current_positions])" + dept_dat += "[job_datum.title] ([num_positions_current]/[num_positions_total])" if(!dept_dat.len) dept_dat += "No positions open." dat += jointext(dept_dat, "") @@ -755,6 +687,7 @@ client.prefs.scars_list["[cur_scar_index]"] = valid_scars client.prefs.save_character() + client.prefs.copy_to(H, initial_spawn = TRUE) H.dna.update_dna_identity() if(mind) @@ -769,13 +702,14 @@ . = H new_character = . if(transfer_after) - transfer_character() + transfer_character(TRUE) -/mob/dead/new_player/proc/transfer_character() +/mob/dead/new_player/proc/transfer_character(late_transfer = FALSE) . = new_character if(.) new_character.key = key //Manually transfer the key to log them in new_character.stop_sound_channel(CHANNEL_LOBBYMUSIC) + SEND_SIGNAL(new_character, COMSIG_MOB_CLIENT_JOINED_FROM_LOBBY, new_character?.client, late_transfer) new_character = null qdel(src) @@ -831,3 +765,21 @@ return FALSE //This is the only case someone should actually be completely blocked from antag rolling as well return TRUE + +///Resets the Lobby Menu HUD, recreating and reassigning it to the new player +/mob/dead/new_player/proc/reset_menu_hud() + set name = "Reset Lobby Menu HUD" + set category = "OOC" + var/mob/dead/new_player/new_player = usr + if(!COOLDOWN_FINISHED(new_player, reset_hud_cooldown)) + to_chat(new_player, span_warning("You must wait [DisplayTimeText(COOLDOWN_TIMELEFT(new_player, reset_hud_cooldown))] before resetting the Lobby Menu HUD again!")) + return + if(!new_player?.client) + return + COOLDOWN_START(new_player, reset_hud_cooldown, RESET_HUD_INTERVAL) + qdel(new_player.hud_used) + create_mob_hud() + to_chat(new_player, span_info("Lobby Menu HUD reset. You may reset the HUD again in [DisplayTimeText(RESET_HUD_INTERVAL)].")) + hud_used.show_hud(hud_used.hud_version) + +#undef RESET_HUD_INTERVAL diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm index a9233938ab..a978e541bf 100644 --- a/code/modules/mob/dead/new_player/preferences_setup.dm +++ b/code/modules/mob/dead/new_player/preferences_setup.dm @@ -24,10 +24,12 @@ var/rando_race = pick(GLOB.roundstart_races) pref_species = new rando_race() features = random_features(pref_species?.id, gender) + bark_id = pick(GLOB.bark_random_list) + bark_pitch = BARK_PITCH_RAND(gender) + bark_variance = BARK_VARIANCE_RAND age = rand(AGE_MIN,AGE_MAX) /datum/preferences/proc/update_preview_icon(current_tab) - var/equip_job = (current_tab != APPEARANCE_TAB) // Determine what job is marked as 'High' priority, and dress them up as such. var/datum/job/previewJob = get_highest_job() @@ -46,13 +48,25 @@ mannequin.add_overlay(mutable_appearance('modular_citadel/icons/ui/backgrounds.dmi', bgstate, layer = SPACE_LAYER)) copy_to(mannequin, initial_spawn = TRUE) - if(current_tab == LOADOUT_TAB) - //give it its loadout if not on the appearance tab - SSjob.equip_loadout(parent.mob, mannequin, FALSE, bypass_prereqs = TRUE, can_drop = FALSE) - else - if(previewJob && equip_job) - mannequin.job = previewJob.title - previewJob.equip(mannequin, TRUE, preference_source = parent) + switch(preview_pref) + if(PREVIEW_PREF_JOB) + if(previewJob) + mannequin.job = previewJob.title + previewJob.equip(mannequin, TRUE, preference_source = parent) + if(PREVIEW_PREF_LOADOUT) + SSjob.equip_loadout(parent.mob, mannequin, bypass_prereqs = TRUE, can_drop = FALSE) + SSjob.post_equip_loadout(parent.mob, mannequin, bypass_prereqs = TRUE, can_drop = FALSE) + if(PREVIEW_PREF_NAKED) + mannequin.hidden_underwear = TRUE + mannequin.hidden_undershirt = TRUE + mannequin.hidden_socks = TRUE + if(PREVIEW_PREF_NAKED_AROUSED) + mannequin.hidden_underwear = TRUE + mannequin.hidden_undershirt = TRUE + mannequin.hidden_socks = TRUE + for(var/obj/item/organ/genital/genital in mannequin.internal_organs) + if(genital.genital_flags & GENITAL_CAN_AROUSE) + genital.set_aroused_state(TRUE, null) mannequin.regenerate_icons() diff --git a/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm index 1dc50bfe73..964a171e59 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm @@ -28,10 +28,9 @@ for(var/path in typesof(prototype)) if(path == prototype && skip_prototype) continue - if(roundstart) - var/datum/sprite_accessory/P = path - if(initial(P.locked)) - continue + var/datum/sprite_accessory/P = path + if((roundstart && initial(P.locked))) + continue var/datum/sprite_accessory/D = new path() if(D.icon_state) @@ -64,6 +63,7 @@ var/mutant_part_string //Also used in species.handle_mutant_bodyparts() to generate the overlay icon state. var/alpha_mask_state var/matrixed_sections = MATRIX_NONE //if color_src is MATRIXED, how many sections does it have? 1-3 + var/ignore = FALSE //NEVER include in customization if set to TRUE //Special / holdover traits for Citadel specific sprites. var/extra = FALSE @@ -77,6 +77,8 @@ //For soft-restricting markings to species IDs var/list/recommended_species + var/mutable_category // simply do not worry about this value + /datum/sprite_accessory/proc/is_not_visible(var/mob/living/carbon/human/H, var/tauric) //return if the accessory shouldn't be shown return FALSE diff --git a/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm b/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm index 3972bdc2c3..ba334d2934 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/alienpeople.dm @@ -48,6 +48,7 @@ icon = 'modular_citadel/icons/mob/xeno_parts_greyscale.dmi' mutant_part_string = "xhead" relevant_layers = list(BODY_ADJ_LAYER) + mutable_category = "HEAD" /datum/sprite_accessory/xeno_head/is_not_visible(var/mob/living/carbon/human/H, var/tauric) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) diff --git a/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm b/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm index 460b41f0d9..cd032b6a2a 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/arachnid.dm @@ -49,6 +49,7 @@ relevant_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER) mutant_part_string = "mandibles" color_src = 0 + mutable_category = "HEAD" /datum/sprite_accessory/arachnid_mandibles/none name = "None" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/body_markings.dm b/code/modules/mob/dead/new_player/sprite_accessories/body_markings.dm index 148af35247..c477bb2cad 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/body_markings.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/body_markings.dm @@ -27,7 +27,7 @@ /datum/sprite_accessory/mam_body_markings/redpanda name = "Redpanda" icon_state = "redpanda" - covered_limbs = list("Head" = MATRIX_RED_BLUE, "Chest" = MATRIX_RED_GREEN, "Left Leg" = MATRIX_RED_GREEN, "Right Leg" = MATRIX_RED_GREEN, "Left Arm" = MATRIX_RED_GREEN, "Right Arm" = MATRIX_RED_GREEN) + covered_limbs = list("Head" = MATRIX_ALL, "Chest" = MATRIX_RED_GREEN, "Left Leg" = MATRIX_RED_GREEN, "Right Leg" = MATRIX_RED_GREEN, "Left Arm" = MATRIX_RED_GREEN, "Right Arm" = MATRIX_RED_GREEN) /datum/sprite_accessory/mam_body_markings/bat name = "Bat" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/caps.dm b/code/modules/mob/dead/new_player/sprite_accessories/caps.dm index d974672490..5b30591d07 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/caps.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/caps.dm @@ -2,6 +2,7 @@ icon = 'icons/mob/mutant_bodyparts.dmi' color_src = HAIR relevant_layers = list(BODY_ADJ_LAYER) + mutable_category = "HEAD" /datum/sprite_accessory/caps/round name = "Round" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/ears.dm b/code/modules/mob/dead/new_player/sprite_accessories/ears.dm index 628a5e53ac..e03bf5d613 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/ears.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/ears.dm @@ -2,6 +2,7 @@ icon = 'icons/mob/mutant_bodyparts.dmi' mutant_part_string = "ears" relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER) + mutable_category = "HEAD" /datum/sprite_accessory/ears/is_not_visible(var/mob/living/carbon/human/H, var/tauric) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) @@ -411,3 +412,85 @@ name = "Wolf" icon_state = "wolf" matrixed_sections = MATRIX_RED_BLUE + +/****************************************** +*************** Tall Ears ***************** +*******************************************/ + +/datum/sprite_accessory/ears/human/bnnuy + name = "Bnnuy (Tall)" + icon = 'modular_citadel/icons/mob/32x64_mam_ears.dmi' + icon_state = "bnnuy" + color_src = MATRIXED + matrixed_sections = MATRIX_RED_GREEN + +/datum/sprite_accessory/ears/mam_ears/bnnuy + name = "Bnnuy (Tall)" + icon = 'modular_citadel/icons/mob/32x64_mam_ears.dmi' + icon_state = "bnnuy" + matrixed_sections = MATRIX_RED_GREEN + +/datum/sprite_accessory/ears/human/bnnuy2 + name = "Bnnuy (Alt) (Tall)" + icon = 'modular_citadel/icons/mob/32x64_mam_ears.dmi' + icon_state = "bnnuy2" + color_src = MATRIXED + matrixed_sections = MATRIX_RED_GREEN + +/datum/sprite_accessory/ears/mam_ears/bnnuy2 + name = "Bnnuy (Alt) (Tall)" + icon = 'modular_citadel/icons/mob/32x64_mam_ears.dmi' + icon_state = "bnnuy2" + matrixed_sections = MATRIX_RED_GREEN + +/datum/sprite_accessory/ears/human/bunnytall + name = "Bunny (Tall)" + icon = 'modular_citadel/icons/mob/32x64_mam_ears.dmi' + icon_state = "bunnytall" + color_src = MATRIXED + matrixed_sections = MATRIX_RED_GREEN + +/datum/sprite_accessory/ears/mam_ears/bunnytall + name = "Bunny (Tall)" + icon = 'modular_citadel/icons/mob/32x64_mam_ears.dmi' + icon_state = "bunnytall" + matrixed_sections = MATRIX_RED_GREEN + +/datum/sprite_accessory/ears/human/sandfox + name = "Sandfox (Tall)" + icon = 'modular_citadel/icons/mob/32x64_mam_ears.dmi' + icon_state = "sandfox" + color_src = MATRIXED + matrixed_sections = MATRIX_RED_GREEN + +/datum/sprite_accessory/ears/mam_ears/sandfox + name = "Sandfox (Tall)" + icon = 'modular_citadel/icons/mob/32x64_mam_ears.dmi' + icon_state = "sandfox" + matrixed_sections = MATRIX_RED_GREEN + +/datum/sprite_accessory/ears/human/shadekinround + name = "Shadekin (Round) (Tall)" + icon = 'modular_citadel/icons/mob/32x64_mam_ears.dmi' + icon_state = "shadekinround" + color_src = MATRIXED + matrixed_sections = MATRIX_RED_GREEN + +/datum/sprite_accessory/ears/mam_ears/shadekinround + name = "Shadekin (Round) (Tall)" + icon = 'modular_citadel/icons/mob/32x64_mam_ears.dmi' + icon_state = "shadekinround" + matrixed_sections = MATRIX_RED_GREEN + +/datum/sprite_accessory/ears/human/jackalope + name = "Jackalope (Tall)" + icon = 'modular_citadel/icons/mob/32x64_mam_ears.dmi' + icon_state = "jackalope" + color_src = MATRIXED + matrixed_sections = MATRIX_RED + +/datum/sprite_accessory/ears/mam_ears/jackalope + name = "Jackalope (Tall)" + icon = 'modular_citadel/icons/mob/32x64_mam_ears.dmi' + icon_state = "jackalope" + matrixed_sections = MATRIX_RED diff --git a/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm b/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm index f3e179e802..06d4c34f72 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm @@ -4,6 +4,7 @@ /datum/sprite_accessory/facial_hair icon = 'icons/mob/hair.dmi' gender = MALE // barf (unless you're a dorf, dorfs dig chix w/ beards :P) + mutable_category = "HEAD" // please make sure they're sorted alphabetically and categorized /datum/sprite_accessory/facial_hair/shaved //this is exempt from the alphabetical sort diff --git a/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm b/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm index 88dda923a0..9e868d69c6 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm @@ -3,6 +3,7 @@ ////////////////////// /datum/sprite_accessory/hair icon = 'icons/mob/hair.dmi' // default icon for all hairs + mutable_category = "HEAD" // please make sure they're sorted alphabetically and, where needed, categorized // try to capitalize the names please~ @@ -1058,3 +1059,58 @@ /datum/sprite_accessory/hair/zone name = "Zone" icon_state = "hair_zone" + +/datum/sprite_accessory/hair_gradient + icon = 'icons/mob/hair_gradients.dmi' + +/datum/sprite_accessory/hair_gradient/none + name = "None" + icon_state = "none" + +/datum/sprite_accessory/hair_gradient/fadeup + name = "Fade Up" + icon_state = "fadeup" + +/datum/sprite_accessory/hair_gradient/fadedown + name = "Fade Down" + icon_state = "fadedown" + +/datum/sprite_accessory/hair_gradient/vertical_split + name = "Vertical Split" + icon_state = "vsplit" + +/datum/sprite_accessory/hair_gradient/_split + name = "Horizontal Split" + icon_state = "bottomflat" + +/datum/sprite_accessory/hair_gradient/reflected + name = "Reflected" + icon_state = "reflected_high" + +/datum/sprite_accessory/hair_gradient/reflected_inverse + name = "Reflected Inverse" + icon_state = "reflected_inverse_high" + +/datum/sprite_accessory/hair_gradient/wavy + name = "Wavy" + icon_state = "wavy" + +/datum/sprite_accessory/hair_gradient/long_fade_up + name = "Long Fade Up" + icon_state = "long_fade_up" + +/datum/sprite_accessory/hair_gradient/long_fade_down + name = "Long Fade Down" + icon_state = "long_fade_down" + +/datum/sprite_accessory/hair_gradient/short_fade_up + name = "Short Fade Up" + icon_state = "short_fade_up" + +/datum/sprite_accessory/hair_gradient/short_fade_down + name = "Short Fade Down" + icon_state = "short_fade_down" + +/datum/sprite_accessory/hair_gradient/wavy_spike + name = "Spiked Wavy" + icon_state = "wavy_spiked" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/horns.dm b/code/modules/mob/dead/new_player/sprite_accessories/horns.dm index 0d097b24f0..bcc339f332 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/horns.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/horns.dm @@ -2,6 +2,7 @@ icon = 'icons/mob/mutant_bodyparts.dmi' color_src = HORNCOLOR relevant_layers = list(HORNS_LAYER) + mutable_category = "HEAD" /datum/sprite_accessory/horns/is_not_visible(var/mob/living/carbon/human/H, var/tauric) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) @@ -40,3 +41,13 @@ /datum/sprite_accessory/horns/short name = "Short" icon_state = "short" + +/datum/sprite_accessory/horns/teppy + name = "Teppy (Tall)" + icon = 'icons/mob/32x64_mutant_bodyparts.dmi' + icon_state = "teppy" + +/datum/sprite_accessory/horns/stag + name = "Stag (Tall)" + icon = 'icons/mob/32x64_mutant_bodyparts.dmi' + icon_state = "stag" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm b/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm index 8bda196faa..ec5c6ea792 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm @@ -6,6 +6,11 @@ icon = 'modular_citadel/icons/mob/ipc_screens.dmi' color_src = null relevant_layers = list(BODY_ADJ_LAYER) + mutable_category = "HEAD" + +/datum/sprite_accessory/screen/is_not_visible(var/mob/living/carbon/human/H, var/tauric) + var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) + return (HD == null) // it's not visible if head is null /datum/sprite_accessory/screen/blank name = "Blank" @@ -133,6 +138,7 @@ relevant_layers = list(BODY_ADJ_LAYER) recommended_species = list("ipc") mutant_part_string = "ipc_antenna" + mutable_category = "HEAD" /datum/sprite_accessory/antenna/none name = "None" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/legs_and_taurs.dm b/code/modules/mob/dead/new_player/sprite_accessories/legs_and_taurs.dm index c525a13ef8..11fde50a37 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/legs_and_taurs.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/legs_and_taurs.dm @@ -126,6 +126,11 @@ hide_legs = USE_SNEK_CLIP_MASK matrixed_sections = MATRIX_RED_GREEN +/datum/sprite_accessory/taur/naga/coiled + name = "Naga (coiled)" + icon_state = "naga_coiled" + ignore = TRUE + /datum/sprite_accessory/taur/otie name = "Otie" icon_state = "otie" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm index 75b62e8c0f..aa9ec41dcc 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm @@ -2,6 +2,7 @@ icon = 'icons/mob/mutant_bodyparts.dmi' mutant_part_string = "snout" relevant_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER) + mutable_category = "HEAD" /datum/sprite_accessory/snouts/is_not_visible(var/mob/living/carbon/human/H, var/tauric) var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD) diff --git a/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm b/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm index c7cd699ec9..870f4f5ba4 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm @@ -5,6 +5,7 @@ color_src = MUTCOLORS name = "Synthetic Lizard - Snout" icon_state = "synthliz_basic" + mutable_category = "HEAD" /datum/sprite_accessory/snouts/mam_snouts/synthliz/synthliz_under icon = 'modular_citadel/icons/mob/synthliz_snouts.dmi' @@ -38,14 +39,14 @@ icon = 'modular_citadel/icons/mob/synthliz_body_markings.dmi' name = "Synthetic Lizard - Pecs Light" icon_state = "synthlizpecslight" - covered_limbs = list("Chest" = MATRIX_GREEN_BLUE) + covered_limbs = list("Chest" = MATRIX_GREEN_BLUE, "Left Arm" = MATRIX_BLUE, "Right Arm" = MATRIX_BLUE, "Left Leg" = MATRIX_GREEN, "Right Leg" = MATRIX_GREEN) /datum/sprite_accessory/mam_body_markings/synthliz recommended_species = list("synthliz") icon = 'modular_citadel/icons/mob/synthliz_body_markings.dmi' name = "Synthetic Lizard - Plates" icon_state = "synthlizscutes" - covered_limbs = list("Chest" = MATRIX_GREEN) + covered_limbs = list("Chest" = MATRIX_GREEN, "Left Leg" = MATRIX_GREEN, "Right Leg" = MATRIX_GREEN) //Synth tails /datum/sprite_accessory/tails/mam_tails/synthliz diff --git a/code/modules/mob/dead/new_player/sprite_accessories/tails.dm b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm index b5ba7f0732..64a3c1a24c 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/tails.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm @@ -542,6 +542,20 @@ icon = 'modular_citadel/icons/mob/mam_tails.dmi' matrixed_sections = MATRIX_RED_GREEN +/datum/sprite_accessory/tails/human/takahiro_kitsune + name = "Takahiro Kitsune Tails" //takahiro had five tails i just wanted to follow the 'T' naming convention vs. tamamo and triple + icon_state = "7sune" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + matrixed_sections = MATRIX_RED_GREEN + +/datum/sprite_accessory/tails_animated/human/takahiro_kitsune + name = "Takahiro Kitsune Tails" + icon_state = "7sune" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + matrixed_sections = MATRIX_RED_GREEN + /datum/sprite_accessory/tails/human/tentacle name = "Tentacle" icon_state = "tentacle" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/wings.dm b/code/modules/mob/dead/new_player/sprite_accessories/wings.dm index 800682b8cf..8a632247bb 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/wings.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/wings.dm @@ -1,4 +1,8 @@ -//Angel Wings +//Functional Wings + +/datum/sprite_accessory/wings + icon = 'icons/mob/wings_functional.dmi' + relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER) /datum/sprite_accessory/wings/none name = "None" @@ -9,23 +13,12 @@ return (!H.dna.features["wings"] || H.dna.features["wings"] == "None" || (H.wear_suit && (H.wear_suit.flags_inv & HIDEJUMPSUIT) && (!H.wear_suit.species_exception || !is_type_in_list(src, H.wear_suit.species_exception)))) /datum/sprite_accessory/wings_open - icon = 'icons/mob/wings.dmi' + icon = 'icons/mob/wings_functional.dmi' relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER) /datum/sprite_accessory/wings_open/is_not_visible(var/mob/living/carbon/human/H, var/tauric) return (H.wear_suit && (H.wear_suit.flags_inv & HIDEJUMPSUIT) && (!H.wear_suit.species_exception || !is_type_in_list(src, H.wear_suit.species_exception)) || H.dna.species.mutant_bodyparts["wings"]) -/datum/sprite_accessory/wings_open/angel - name = "Angel" - icon_state = "angel" - color_src = 0 - dimension_x = 46 - center = TRUE - dimension_y = 34 - -/datum/sprite_accessory/wings - icon = 'icons/mob/wings.dmi' - relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER) /datum/sprite_accessory/wings/angel name = "Angel" @@ -36,6 +29,114 @@ dimension_y = 34 locked = TRUE +/datum/sprite_accessory/wings_open/angel + name = "Angel" + icon_state = "angel" + color_src = 0 + dimension_x = 46 + center = TRUE + dimension_y = 34 + +/datum/sprite_accessory/wings/dragon + name = "Dragon" + icon_state = "dragon" + dimension_x = 96 + center = TRUE + dimension_y = 32 + locked = TRUE + +/datum/sprite_accessory/wings_open/dragon + name = "Dragon" + icon_state = "dragon" + dimension_x = 96 + center = TRUE + dimension_y = 32 + +/datum/sprite_accessory/wings/megamoth + name = "Megamoth" + icon_state = "megamoth" + color_src = FALSE + dimension_x = 96 + center = TRUE + dimension_y = 32 + locked = TRUE + +/datum/sprite_accessory/wings_open/megamoth + name = "Megamoth" + icon_state = "megamoth" + color_src = FALSE + dimension_x = 96 + center = TRUE + dimension_y = 32 + +/datum/sprite_accessory/wings/mothra + name = "Mothra" + icon_state = "mothra" + color_src = FALSE + dimension_x = 96 + center = TRUE + dimension_y = 32 + locked = TRUE + +/datum/sprite_accessory/wings_open/mothra + name = "Mothra" + icon_state = "mothra" + color_src = FALSE + dimension_x = 96 + center = TRUE + dimension_y = 32 + +/datum/sprite_accessory/wings/skeleton + name = "Skeleton" + icon_state = "skele" + color_src = FALSE + dimension_x = 96 + center = TRUE + dimension_y = 32 + locked = TRUE + +/datum/sprite_accessory/wings_open/skeleton + name = "Skeleton" + icon_state = "skele" + color_src = FALSE + dimension_x = 96 + center = TRUE + dimension_y = 32 + +/datum/sprite_accessory/wings/robotic + name = "Robotic" + icon_state = "robotic" + color_src = FALSE + dimension_x = 96 + center = TRUE + dimension_y = 32 + locked = TRUE + +/datum/sprite_accessory/wings_open/robotic + name = "Robotic" + icon_state = "robotic" + color_src = FALSE + dimension_x = 96 + center = TRUE + dimension_y = 32 + +/datum/sprite_accessory/wings/fly + name = "Fly" + icon_state = "fly" + color_src = FALSE + dimension_x = 96 + center = TRUE + dimension_y = 32 + locked = TRUE + +/datum/sprite_accessory/wings_open/fly + name = "Fly" + icon_state = "fly" + color_src = FALSE + dimension_x = 96 + center = TRUE + dimension_y = 32 + // Decorative wings /datum/sprite_accessory/deco_wings @@ -43,6 +144,10 @@ color_src = WINGCOLOR mutant_part_string = "insect_wings" relevant_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER) + var/list/upgrade_to = list() //What the wings change to if the mob consumes a flight potion or gains true wings through other means. If it's an empty list, it will pick the species alternative instead. + +/datum/sprite_accessory/deco_wings/is_not_visible(var/mob/living/carbon/human/H, var/tauric) + return (H.dna.features["wings"] != "None") //true wings will override decorative wings /datum/sprite_accessory/deco_wings/none name = "None" @@ -57,162 +162,221 @@ center = TRUE dimension_y = 34 relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER) + upgrade_to = SPECIES_WINGS_ANGEL //obviously //nonmoth wings /datum/sprite_accessory/deco_wings/bat name = "Bat" icon_state = "bat" + upgrade_to = SPECIES_WINGS_DRAGON /datum/sprite_accessory/deco_wings/bee name = "Bee" icon_state = "bee" + upgrade_to = SPECIES_WINGS_INSECT /datum/sprite_accessory/deco_wings/bee2 name = "Small Bee" icon_state = "beewings" + upgrade_to = SPECIES_WINGS_INSECT /datum/sprite_accessory/deco_wings/dragon name = "Dragon" icon_state = "dragon" + upgrade_to = SPECIES_WINGS_DRAGON //lol /datum/sprite_accessory/deco_wings/dragonfly name = "Dragonfly" icon_state = "dragonfly" + upgrade_to = SPECIES_WINGS_INSECT /datum/sprite_accessory/deco_wings/fairy name = "Fairy" icon_state = "fairy" + upgrade_to = SPECIES_WINGS_INSECT //rip people's sparkly wings until someone sprites in some huge fairy wings or something /datum/sprite_accessory/deco_wings/featheredwing name = "Feathery" icon_state = "feathery" + upgrade_to = SPECIES_WINGS_ANGEL /datum/sprite_accessory/deco_wings/featheredwingmedium name = "Medium Feathered" icon_state = "feathered3" + upgrade_to = SPECIES_WINGS_ANGEL /datum/sprite_accessory/deco_wings/featheredwinglarge name = "Large Feathered" icon_state = "feathered2" + upgrade_to = SPECIES_WINGS_ANGEL /datum/sprite_accessory/deco_wings/harpywings name = "Harpy" icon_state = "harpywings" + upgrade_to = SPECIES_WINGS_ANGEL + +/datum/sprite_accessory/deco_wings/harpywingsalt + name = "Harpy (Alt)" + icon_state = "harpywingsalt" + upgrade_to = SPECIES_WINGS_ANGEL + +/datum/sprite_accessory/deco_wings/harpywingsaltcollar + name = "Harpy (Alt Collar)" + icon_state = "harpywingsaltcollar" + upgrade_to = SPECIES_WINGS_ANGEL + +/datum/sprite_accessory/deco_wings/harpywingsbat + name = "Harpy (Bat)" + icon_state = "harpywingsbat" + upgrade_to = SPECIES_WINGS_ANGEL + +/datum/sprite_accessory/deco_wings/harpywingsbatcollar + name = "Harpy (Bat Collar)" + icon_state = "harpywingsbatcollar" + upgrade_to = SPECIES_WINGS_ANGEL /datum/sprite_accessory/deco_wings/roboticwing name = "Robotic" icon_state = "drago" + upgrade_to = SPECIES_WINGS_ROBOT /datum/sprite_accessory/deco_wings/succubusblack name = "Succubus Black" icon_state = "succubusblack" + upgrade_to = SPECIES_WINGS_DRAGON /datum/sprite_accessory/deco_wings/succubuspurple name = "Succubus Purple" icon_state = "succubuspurple" + upgrade_to = SPECIES_WINGS_DRAGON /datum/sprite_accessory/deco_wings/succubusred name = "Succubus Red" icon_state = "succubusred" + upgrade_to = SPECIES_WINGS_DRAGON /datum/sprite_accessory/deco_wings/xenobackplate name = "Xenomorph Backplate" icon_state = "snagbackplate" + upgrade_to = list() //moth wings /datum/sprite_accessory/deco_wings/atlas name = "Atlas" icon_state = "atlas" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/brown name = "Brown" icon_state = "brown" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/deathhead name = "Deathshead" icon_state = "deathhead" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/featherymoth name = "Feathery Moth Wings" icon_state = "featherymoth" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/firewatch name = "Firewatch" icon_state = "firewatch" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/gothic name = "Gothic" icon_state = "gothic" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/jungle name = "Jungle" icon_state = "jungle" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/lovers name = "Lovers" icon_state = "lovers" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/luna name = "Luna" icon_state = "luna" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/monarch name = "Monarch" icon_state = "monarch" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/moonfly name = "Moon Fly" icon_state = "moonfly" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/oakworm name = "Oak Worm" icon_state = "oakworm" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/plain name = "Plain" icon_state = "plain" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/plasmafire name = "Plasma Fire" icon_state = "plasmafire" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/poison name = "Poison" icon_state = "poison" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/punished name = "Burnt Off" icon_state = "punished" + upgrade_to = SPECIES_WINGS_MOTH //through TG code moth wings aren't meant to get upgraded if they're burnt off but... /datum/sprite_accessory/deco_wings/ragged name = "Ragged" icon_state = "ragged" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/reddish name = "Reddish" icon_state = "redish" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/rosy name = "Rosy" icon_state = "rosy" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/royal name = "Royal" icon_state = "royal" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/snow name = "Snow" icon_state = "snow" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/whitefly name = "White Fly" icon_state = "whitefly" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/deco_wings/witchwing name = "Witch Wing" icon_state = "witchwing" + upgrade_to = SPECIES_WINGS_MOTH //INSECT WINGS @@ -220,67 +384,106 @@ icon = 'icons/mob/wings.dmi' color_src = WINGCOLOR relevant_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER) + var/list/upgrade_to = list() + +/datum/sprite_accessory/insect_wings/is_not_visible(var/mob/living/carbon/human/H, var/tauric) + return (H.dna.features["wings"] != "None") //true wings will override decorative wings //non insect wings -/datum/sprite_accessory/deco_wings/bat +/datum/sprite_accessory/insect_wings/bat name = "Bat" icon_state = "bat" + upgrade_to = SPECIES_WINGS_DRAGON /datum/sprite_accessory/insect_wings/bee name = "Bee" icon_state = "bee" + upgrade_to = SPECIES_WINGS_INSECT /datum/sprite_accessory/insect_wings/bee2 name = "Small Bee" icon_state = "beewings" + upgrade_to = SPECIES_WINGS_INSECT /datum/sprite_accessory/insect_wings/dragon name = "Dragon" icon_state = "dragon" + upgrade_to = SPECIES_WINGS_DRAGON /datum/sprite_accessory/insect_wings/dragonfly name = "Dragonfly" icon_state = "dragonfly" + upgrade_to = SPECIES_WINGS_INSECT /datum/sprite_accessory/insect_wings/fairy name = "Fairy" icon_state = "fairy" + upgrade_to = SPECIES_WINGS_INSECT /datum/sprite_accessory/insect_wings/featheredwing name = "Feathery" icon_state = "feathery" + upgrade_to = SPECIES_WINGS_ANGEL /datum/sprite_accessory/insect_wings/featheredwingmedium name = "Medium Feathered" icon_state = "feathered3" + upgrade_to = SPECIES_WINGS_ANGEL /datum/sprite_accessory/insect_wings/featheredwinglarge name = "Large Feathered" icon_state = "feathered2" + upgrade_to = SPECIES_WINGS_ANGEL /datum/sprite_accessory/insect_wings/harpywings name = "Harpy" icon_state = "harpywings" + upgrade_to = SPECIES_WINGS_ANGEL + +/datum/sprite_accessory/insect_wings/harpywingsalt + name = "Harpy (Alt)" + icon_state = "harpywingsalt" + upgrade_to = SPECIES_WINGS_ANGEL + +/datum/sprite_accessory/insect_wings/harpywingsaltcollar + name = "Harpy (Alt Collar)" + icon_state = "harpywingsaltcollar" + upgrade_to = SPECIES_WINGS_ANGEL + +/datum/sprite_accessory/insect_wings/harpywingsbat + name = "Harpy (Bat)" + icon_state = "harpywingsbat" + upgrade_to = SPECIES_WINGS_ANGEL + +/datum/sprite_accessory/insect_wings/harpywingsbatcollar + name = "Harpy (Bat Collar)" + icon_state = "harpywingsbatcollar" + upgrade_to = SPECIES_WINGS_ANGEL /datum/sprite_accessory/insect_wings/roboticwing name = "Robotic" icon_state = "drago" + upgrade_to = SPECIES_WINGS_ROBOT /datum/sprite_accessory/insect_wings/succubusblack name = "Succubus Black" icon_state = "succubusblack" + upgrade_to = SPECIES_WINGS_DRAGON /datum/sprite_accessory/insect_wings/succubuspurple name = "Succubus Purple" icon_state = "succubuspurple" + upgrade_to = SPECIES_WINGS_DRAGON /datum/sprite_accessory/insect_wings/succubusred name = "Succubus Red" icon_state = "succubusred" + upgrade_to = SPECIES_WINGS_DRAGON /datum/sprite_accessory/insect_wings/xenobackplate name = "Xenomorph Backplate" icon_state = "snagbackplate" + upgrade_to = list() //moth wings @@ -288,98 +491,122 @@ name = "None" icon_state = "none" relevant_layers = null + upgrade_to = list() /datum/sprite_accessory/insect_wings/atlas name = "Atlas" icon_state = "atlas" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/brown name = "Brown" icon_state = "brown" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/deathhead name = "Deathshead" icon_state = "deathhead" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/featherymoth name = "Feathery Moth Wings" icon_state = "featherymoth" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/firewatch name = "Firewatch" icon_state = "firewatch" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/gothic name = "Gothic" icon_state = "gothic" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/jungle name = "Jungle" icon_state = "jungle" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/lovers name = "Lovers" icon_state = "lovers" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/luna name = "Luna" icon_state = "luna" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/monarch name = "Monarch" icon_state = "monarch" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/moonfly name = "Moon Fly" icon_state = "moonfly" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/oakworm name = "Oak Worm" icon_state = "oakworm" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/plain name = "Plain" icon_state = "plain" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/plasmafire name = "Plasma Fire" icon_state = "plasmafire" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/poison name = "Poison" icon_state = "poison" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/punished name = "Burnt Off" icon_state = "punished" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/ragged name = "Ragged" icon_state = "ragged" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/reddish name = "Reddish" icon_state = "redish" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/rosy name = "Rosy" icon_state = "rosy" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/royal name = "Royal" icon_state = "royal" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/snow name = "Snow" icon_state = "snow" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/whitefly name = "White Fly" icon_state = "whitefly" + upgrade_to = SPECIES_WINGS_MOTH /datum/sprite_accessory/insect_wings/witchwing name = "Witch Wing" icon_state = "witchwing" + upgrade_to = SPECIES_WINGS_MOTH //insect markings /datum/sprite_accessory/insect_markings // Extra markings for insects ported from tg. @@ -453,9 +680,11 @@ /datum/sprite_accessory/deco_wings/eyestalks name = "gazer eyestalks" icon_state = "eyestalks" + upgrade_to = list() //and suddenly flight potions become a lot more awkward when they gouge your tentacle eyes out. //ckeys_allowed = list("liquidfirefly","seiga") //At request. /datum/sprite_accessory/insect_wings/eyestalks name = "gazer eyestalks" icon_state = "eyestalks" + upgrade_to = list() //ckeys_allowed = list("liquidfirefly","seiga") //At request. diff --git a/code/modules/mob/dead/observer/login.dm b/code/modules/mob/dead/observer/login.dm index 8daf8ec052..ad71d49489 100644 --- a/code/modules/mob/dead/observer/login.dm +++ b/code/modules/mob/dead/observer/login.dm @@ -16,5 +16,5 @@ if (isturf(T)) update_z(T.z) - update_icon(preferred_form) + update_icon(null, preferred_form) updateghostimages() diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 429f00161b..ec6657a956 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -121,9 +121,10 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) remove_verb(src, /mob/dead/observer/verb/boo) remove_verb(src, /mob/dead/observer/verb/possess) - animate(src, pixel_y = 2, time = 10, loop = -1) + animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE) - GLOB.dead_mob_list += src + add_to_dead_mob_list() for(var/v in GLOB.active_alternate_appearances) if(!v) @@ -166,9 +167,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) QDEL_NULL(spawners_menu) return ..() -/mob/dead/CanPass(atom/movable/mover, turf/target) - return 1 - /* * This proc will update the icon of the ghost itself, with hair overlays, as well as the ghost image. * Please call update_icon(icon_state) from now on when you want to update the icon_state of the ghost, @@ -176,7 +174,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) * Hair will always update its dir, so if your sprite has no dirs the haircut will go all over the place. * |- Ricotez */ -/mob/dead/observer/update_icon(new_form) +/mob/dead/observer/update_icon(updates=ALL, new_form=null) . = ..() if(client) //We update our preferences in case they changed right before update_icon was called. ghost_accs = client.prefs.ghost_accs @@ -284,7 +282,7 @@ Works together with spawning an observer, noted above. P.respawn_time_of_death = world.time P.respawn_did_cryo = cryo transfer_ckey(ghost, FALSE) - ghost.client.init_verbs() + ghost.client?.init_verbs() if(penalize) var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES @@ -377,8 +375,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp return ghostize(0, penalize = TRUE) - - /mob/dead/observer/Move(NewLoc, direct) if (SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_MOVE, NewLoc) & COMPONENT_MOVABLE_BLOCK_PRE_MOVE) return @@ -388,7 +384,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(NewLoc) forceMove(NewLoc) - update_parallax_contents() else forceMove(get_turf(src)) //Get out of closets and such as a ghost if((direct & NORTH) && y < world.maxy) @@ -487,9 +482,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(!L || !L.len) to_chat(usr, "No area available.") return - usr.forceMove(pick(L)) - update_parallax_contents() /mob/dead/observer/proc/view_gas() set category = "Ghost" @@ -542,8 +535,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/stop_orbit(datum/component/orbiter/orbits) . = ..() //restart our floating animation after orbit is done. - pixel_y = 0 - animate(src, pixel_y = 2, time = 10, loop = -1) + pixel_z = 0 + animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE) /mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak set category = "Ghost" @@ -568,7 +562,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination. A.forceMove(T) - A.update_parallax_contents() else to_chat(A, "This mob is not located in the game world.") diff --git a/code/modules/mob/dead/observer/orbit.dm b/code/modules/mob/dead/observer/orbit.dm index b799c5e592..77eb457219 100644 --- a/code/modules/mob/dead/observer/orbit.dm +++ b/code/modules/mob/dead/observer/orbit.dm @@ -90,6 +90,14 @@ antagonists += list(serialized) break + var/assignment = "no_id" + + var/obj/item/card/id/card = M.get_idcard() + if(card) + assignment = "[ckey(card.GetJobName())]" + + serialized["assignment"] = assignment + if (!was_antagonist) alive += list(serialized) else @@ -107,4 +115,4 @@ /datum/orbit_menu/ui_assets() . = ..() || list() . += get_asset_datum(/datum/asset/simple/orbit) - + . += get_asset_datum(/datum/asset/spritesheet/jobs) diff --git a/code/modules/mob/dead/observer/respawn.dm b/code/modules/mob/dead/observer/respawn.dm index 94ebf42a2a..5d1f65311d 100644 --- a/code/modules/mob/dead/observer/respawn.dm +++ b/code/modules/mob/dead/observer/respawn.dm @@ -35,8 +35,8 @@ message_admins("[key_name_admin(src)] gave [key_name_admin(O)] a full respawn and sent them back to the lobby.") log_admin("[key_name(src)] gave [key_name(O)] a full respawn and sent them back to the lobby.") to_chat(O, "You have been given a full respawn.") - O.do_respawn(FALSE) - O.client.prefs.dnr_triggered = FALSE + if(O.do_respawn(FALSE)) + player.prefs.dnr_triggered = FALSE else if(istype(M, /mob/dead/new_player)) var/mob/dead/new_player/NP = M var/confirm = alert(src, "Remove [NP]'s respawn restrictions?", "Remove Restrictions", "Yes", "No") @@ -150,7 +150,7 @@ */ /mob/dead/observer/proc/do_respawn(penalize) if(!client) - return + return FALSE if(isnull(penalize)) penalize = client.prefs.respawn_restrictions_active client.prefs.respawn_restrictions_active = penalize @@ -162,10 +162,11 @@ to_chat(N, "You have been respawned to the lobby. \ Remember to take heed of rules regarding round knowledge - notably, that ALL past lives are forgotten. \ Any character you join as has NO knowledge of round events unless specified otherwise by an admin.") + return TRUE /** * Actual proc that removes us and puts us back on lobby - * + * * Returns the new mob. */ /mob/dead/observer/proc/transfer_to_lobby() @@ -174,8 +175,7 @@ return client.screen.Cut() client.view_size.resetToDefault() - client.generate_clickcatcher() - client.apply_clickcatcher() + client.update_clickcatcher() client.view_size.setDefault(getScreenSize(client.prefs.widescreenpref)) client.view_size.resetToDefault() diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 3eaefebc56..51659a2904 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -182,7 +182,7 @@ held_items[hand_index] = I I.layer = ABOVE_HUD_LAYER I.plane = ABOVE_HUD_PLANE - I.equipped(src, SLOT_HANDS) + I.equipped(src, ITEM_SLOT_HANDS) if(I.pulledby) I.pulledby.stop_pulling() update_inv_hands() @@ -337,6 +337,7 @@ on_item_dropped(I) if(I.dropped(src) == ITEM_RELOCATED_BY_DROPPED) return FALSE + SEND_SIGNAL(src, COMSIG_MOB_UNEQUIPPED_ITEM, I, force, newloc, no_move, invdrop, silent) return TRUE //This is a SAFE proc. Use this instead of equip_to_slot()! @@ -375,14 +376,14 @@ if(!slot_priority) slot_priority = list( \ - SLOT_BACK, SLOT_WEAR_ID,\ - SLOT_W_UNIFORM, SLOT_WEAR_SUIT,\ - SLOT_WEAR_MASK, SLOT_HEAD, SLOT_NECK,\ - SLOT_SHOES, SLOT_GLOVES,\ - SLOT_EARS, SLOT_GLASSES,\ - SLOT_BELT, SLOT_S_STORE,\ - SLOT_L_STORE, SLOT_R_STORE,\ - SLOT_GENERC_DEXTROUS_STORAGE\ + ITEM_SLOT_BACK, ITEM_SLOT_ID,\ + ITEM_SLOT_ICLOTHING, ITEM_SLOT_OCLOTHING,\ + ITEM_SLOT_MASK, ITEM_SLOT_HEAD, ITEM_SLOT_NECK,\ + ITEM_SLOT_FEET, ITEM_SLOT_GLOVES,\ + ITEM_SLOT_EARS, ITEM_SLOT_EYES,\ + ITEM_SLOT_BELT, ITEM_SLOT_SUITSTORE,\ + ITEM_SLOT_LPOCKET, ITEM_SLOT_RPOCKET,\ + ITEM_SLOT_DEX_STORAGE\ ) for(var/slot in slot_priority) @@ -414,10 +415,6 @@ drop_all_held_items() /obj/item/proc/equip_to_best_slot(mob/M) - if(src != M.get_active_held_item()) - to_chat(M, "You are not holding anything to equip!") - return FALSE - if(M.equip_to_appropriate_slot(src, TRUE)) M.update_inv_hands() return TRUE @@ -428,7 +425,7 @@ if(M.active_storage && M.active_storage.parent && SEND_SIGNAL(M.active_storage.parent, COMSIG_TRY_STORAGE_INSERT, src,M)) return TRUE - var/list/obj/item/possible = list(M.get_inactive_held_item(), M.get_item_by_slot(SLOT_BELT), M.get_item_by_slot(SLOT_GENERC_DEXTROUS_STORAGE), M.get_item_by_slot(SLOT_BACK)) + var/list/obj/item/possible = list(M.get_inactive_held_item(), M.get_item_by_slot(ITEM_SLOT_BELT), M.get_item_by_slot(ITEM_SLOT_DEX_STORAGE), M.get_item_by_slot(ITEM_SLOT_BACK)) for(var/i in possible) if(!i) continue @@ -450,10 +447,10 @@ //used in code for items usable by both carbon and drones, this gives the proper back slot for each mob.(defibrillator, backpack watertank, ...) /mob/proc/getBackSlot() - return SLOT_BACK + return ITEM_SLOT_BACK /mob/proc/getBeltSlot() - return SLOT_BELT + return ITEM_SLOT_BELT @@ -465,7 +462,7 @@ //any cost it has isn't a worry /mob/proc/change_number_of_hands(amt) if(amt < held_items.len) - for(var/i in held_items.len to amt step -1) + for(var/i in held_items.len to (amt + 1) step -1) dropItemToGround(held_items[i]) held_items.len = amt @@ -476,14 +473,14 @@ /mob/living/carbon/human/change_number_of_hands(amt) var/old_limbs = held_items.len if(amt < old_limbs) - for(var/i in hand_bodyparts.len to amt step -1) + for(var/i in hand_bodyparts.len to (amt + 1) step -1) var/obj/item/bodypart/BP = hand_bodyparts[i] BP.dismember() hand_bodyparts[i] = null hand_bodyparts.len = amt else if(amt > old_limbs) hand_bodyparts.len = amt - for(var/i in old_limbs+1 to amt) + for(var/i in (old_limbs + 1) to amt) var/path = /obj/item/bodypart/l_arm if(!(i % 2)) path = /obj/item/bodypart/r_arm diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index 7615792028..8d5bd40acc 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -30,7 +30,7 @@ // Takes care blood loss and regeneration -/mob/living/carbon/human/handle_blood() +/mob/living/carbon/human/handle_blood(delta_time, times_fired) if(NOBLOOD in dna.species.species_traits || bleedsuppress || (HAS_TRAIT(src, TRAIT_FAKEDEATH))) return @@ -39,55 +39,57 @@ return if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood. - if(integrating_blood > 0) - var/blood_integrated = max(integrating_blood - 1, 0) - var/blood_diff = integrating_blood - blood_integrated - integrating_blood = blood_integrated - if(blood_volume < BLOOD_VOLUME_MAXIMUM) - blood_volume += blood_diff - if(blood_volume < BLOOD_VOLUME_NORMAL) - var/nutrition_ratio = 0 - if(!HAS_TRAIT(src, TRAIT_NOHUNGER)) - switch(nutrition) - if(0 to NUTRITION_LEVEL_STARVING) - nutrition_ratio = 0.2 - if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY) - nutrition_ratio = 0.4 - if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED) - nutrition_ratio = 0.6 - if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED) - nutrition_ratio = 0.8 - else - nutrition_ratio = 1 - if(satiety > 80) - nutrition_ratio *= 1.25 - adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR) - blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio) + if(dna.species.handle_blood(src, delta_time, times_fired)) // if this returns TRUE, then the species is not handling blood itself and we can control everything + if(integrating_blood > 0) + var/blood_integrated = max(integrating_blood - 1, 0) + var/blood_diff = integrating_blood - blood_integrated + integrating_blood = blood_integrated + if(blood_volume < BLOOD_VOLUME_MAXIMUM) + blood_volume += blood_diff + if(blood_volume < BLOOD_VOLUME_NORMAL) + var/nutrition_ratio = 0 + if(!HAS_TRAIT(src, TRAIT_NOHUNGER)) + switch(nutrition) + if(0 to NUTRITION_LEVEL_STARVING) + nutrition_ratio = 0.2 + if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY) + nutrition_ratio = 0.4 + if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED) + nutrition_ratio = 0.6 + if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED) + nutrition_ratio = 0.8 + else + nutrition_ratio = 1 + if(satiety > 80) + nutrition_ratio *= 1.25 + adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR) + blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio) - //Effects of bloodloss - var/word = pick("dizzy","woozy","faint") - var/blood_effect_volume = blood_volume + integrating_blood - switch(blood_effect_volume) - if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS) - if(prob(10)) - to_chat(src, "You feel terribly bloated.") - if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) - if(prob(5)) - to_chat(src, "You feel [word].") - adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1)) - if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) - adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1)) - if(prob(5)) - blur_eyes(6) - to_chat(src, "You feel very [word].") - if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD) - adjustOxyLoss(5) - if(prob(15)) - Unconscious(rand(20,60)) - to_chat(src, "You feel extremely [word].") - if(-INFINITY to BLOOD_VOLUME_SURVIVE) - if(!HAS_TRAIT(src, TRAIT_NODEATH)) - death() + //Effects of bloodloss + if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) //Synths are immune to direct consequences of bloodloss, instead suffering penalties to heat exchange. + var/word = pick("dizzy","woozy","faint") + var/blood_effect_volume = blood_volume + integrating_blood + switch(blood_effect_volume) + if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS) + if(prob(10)) + to_chat(src, "You feel terribly bloated.") + if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) + if(prob(5)) + to_chat(src, "You feel [word].") + adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1)) + if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) + adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1)) + if(prob(5)) + blur_eyes(6) + to_chat(src, "You feel very [word].") + if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD) + adjustOxyLoss(5) + if(prob(15)) + Unconscious(rand(20,60)) + to_chat(src, "You feel extremely [word].") + if(-INFINITY to BLOOD_VOLUME_SURVIVE) + if(!HAS_TRAIT(src, TRAIT_NODEATH)) + death() var/temp_bleed = 0 //Bleeding out @@ -156,7 +158,7 @@ blood_volume -= amount - var/list/blood_data = get_blood_data(blood_id) + var/list/blood_data = get_blood_data() if(iscarbon(AM)) var/mob/living/carbon/C = AM @@ -177,54 +179,54 @@ return TRUE -/mob/living/proc/get_blood_data(blood_id) +/mob/living/proc/get_blood_data() return -/mob/living/carbon/get_blood_data(blood_id) - if(blood_id == /datum/reagent/blood || /datum/reagent/blood/jellyblood) //actual blood reagent - var/blood_data = list() - //set the blood data - blood_data["donor"] = src - blood_data["viruses"] = list() +/mob/living/carbon/get_blood_data() + var/blood_data = list() + //set the blood data + blood_data["donor"] = src + blood_data["viruses"] = list() - for(var/thing in diseases) - var/datum/disease/D = thing - blood_data["viruses"] += D.Copy() + for(var/thing in diseases) + var/datum/disease/D = thing + blood_data["viruses"] += D.Copy() - blood_data["blood_DNA"] = dna.unique_enzymes - blood_data["bloodcolor"] = dna.species.exotic_blood_color - if(disease_resistances && disease_resistances.len) - blood_data["resistances"] = disease_resistances.Copy() - var/list/temp_chem = list() - for(var/datum/reagent/R in reagents.reagent_list) - temp_chem[R.type] = R.volume - blood_data["trace_chem"] = list2params(temp_chem) - if(mind) - blood_data["mind"] = mind - else if(last_mind) - blood_data["mind"] = last_mind - if(ckey) - blood_data["ckey"] = ckey - else if(last_mind) - blood_data["ckey"] = ckey(last_mind.key) + blood_data["blood_DNA"] = dna.unique_enzymes + blood_data["bloodcolor"] = dna.species.exotic_blood_color + blood_data["bloodblend"] = dna.species.exotic_blood_blend_mode + if(disease_resistances && disease_resistances.len) + blood_data["resistances"] = disease_resistances.Copy() + var/list/temp_chem = list() + for(var/datum/reagent/R in reagents.reagent_list) + temp_chem[R.type] = R.volume + blood_data["trace_chem"] = list2params(temp_chem) + if(mind) + blood_data["mind"] = mind + else if(last_mind) + blood_data["mind"] = last_mind + if(ckey) + blood_data["ckey"] = ckey + else if(last_mind) + blood_data["ckey"] = ckey(last_mind.key) - if(!suiciding) - blood_data["cloneable"] = 1 - blood_data["blood_type"] = dna.blood_type - blood_data["gender"] = gender - blood_data["real_name"] = real_name - blood_data["features"] = dna.features - blood_data["factions"] = faction - blood_data["quirks"] = list() - for(var/V in roundstart_quirks) - var/datum/quirk/T = V - blood_data["quirks"] += T.type - blood_data["changeling_loudness"] = 0 - if(mind) - var/datum/antagonist/changeling/ling = mind.has_antag_datum(/datum/antagonist/changeling) - if(istype(ling)) - blood_data["changeling_loudness"] = ling.loudfactor - return blood_data + if(!suiciding) + blood_data["cloneable"] = 1 + blood_data["blood_type"] = dna.blood_type + blood_data["gender"] = gender + blood_data["real_name"] = real_name + blood_data["features"] = dna.features + blood_data["factions"] = faction + blood_data["quirks"] = list() + for(var/V in roundstart_quirks) + var/datum/quirk/T = V + blood_data["quirks"] += T.type + blood_data["changeling_loudness"] = 0 + if(mind) + var/datum/antagonist/changeling/ling = mind.has_antag_datum(/datum/antagonist/changeling) + if(istype(ling)) + blood_data["changeling_loudness"] = ling.loudfactor + return blood_data //get the id of the substance this mob use as blood. /mob/proc/get_blood_id() @@ -264,7 +266,7 @@ "O-" = list("O-","SY"), "O+" = list("O-", "O+","SY"), "L" = list("L","SY"), - "U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U","SY"), + "U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U","SY", "BUG"), "HF" = list("HF", "SY"), "X*" = list("X*", "SY"), "SY" = list("SY"), @@ -370,27 +372,6 @@ if(!B) B = new(T) -//This is a terrible way of handling it. -/mob/living/proc/ResetBloodVol() - if(ishuman(src)) - var/mob/living/carbon/human/H = src - if (HAS_TRAIT(src, TRAIT_HIGH_BLOOD)) - blood_ratio = 1.2 - H.handle_blood() - return - blood_ratio = 1 - H.handle_blood() - return - blood_ratio = 1 - -/mob/living/proc/AdjustBloodVol(value) - if(blood_ratio == value) - return - blood_ratio = value - if(ishuman(src)) - var/mob/living/carbon/human/H = src - H.handle_blood() - /mob/living/proc/adjust_integration_blood(value, remove_actual_blood, force) if(integrating_blood + value < 0 && remove_actual_blood) blood_volume += value + integrating_blood diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm index b66158db8a..6f2f7094e6 100644 --- a/code/modules/mob/living/bloodcrawl.dm +++ b/code/modules/mob/living/bloodcrawl.dm @@ -11,7 +11,7 @@ /obj/effect/dummy/phased_mob/slaughter/relaymove(mob/user, direction) forceMove(get_step(src,direction)) -/obj/effect/dummy/phased_mob/slaughter/ex_act() +/obj/effect/dummy/phased_mob/slaughter/ex_act(severity, target, origin) return /obj/effect/dummy/phased_mob/slaughter/wave_ex_act(power, datum/wave_explosion/explosion, dir) @@ -144,7 +144,7 @@ icon = 'icons/effects/blood.dmi' item_flags = ABSTRACT -/obj/item/bloodcrawl/Initialize() +/obj/item/bloodcrawl/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm index 85c256f5b0..f5a2368a60 100644 --- a/code/modules/mob/living/brain/MMI.dm +++ b/code/modules/mob/living/brain/MMI.dm @@ -8,7 +8,7 @@ var/obj/item/radio/radio = null //Let's give it a radio. var/mob/living/brain/brainmob = null //The current occupant. var/mob/living/silicon/robot = null //Appears unused. - var/obj/mecha = null //This does not appear to be used outside of reference in mecha.dm. + var/obj/vehicle/sealed/mecha = null //This does not appear to be used outside of reference in mecha.dm. var/obj/item/organ/brain/brain = null //The actual brain var/datum/ai_laws/laws = new() var/force_replace_ai_name = FALSE @@ -32,7 +32,7 @@ else . += "mmi_dead" -/obj/item/mmi/Initialize() +/obj/item/mmi/Initialize(mapload) . = ..() radio = new(src) //Spawns a radio inside the MMI. radio.broadcasting = 0 //researching radio mmis turned the robofabs into radios because this didnt start as 0. @@ -64,8 +64,8 @@ brainmob.container = src if(!(newbrain.organ_flags & ORGAN_FAILING)) // the brain organ hasn't been beaten to death. brainmob.stat = CONSCIOUS //we manually revive the brain mob - GLOB.dead_mob_list -= brainmob - GLOB.alive_mob_list += brainmob + brainmob.remove_from_dead_mob_list() + brainmob.add_to_alive_mob_list() brainmob.reset_perspective() brain = newbrain @@ -102,8 +102,8 @@ brainmob.stat = DEAD brainmob.emp_damage = 0 brainmob.reset_perspective() //so the brainmob follows the brain organ instead of the mmi. And to update our vision - GLOB.alive_mob_list -= brainmob //Get outta here - GLOB.dead_mob_list += brainmob + brainmob.remove_from_alive_mob_list() //Get outta here + brainmob.add_to_dead_mob_list() brain.brainmob = brainmob //Set the brain to use the brainmob brainmob = null //Set mmi brainmob var to null if(user) @@ -215,7 +215,7 @@ desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs and AIs created with it." overrides_aicore_laws = TRUE -/obj/item/mmi/syndie/Initialize() +/obj/item/mmi/syndie/Initialize(mapload) . = ..() laws = new /datum/ai_laws/syndicate_override() radio.on = 0 diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm index 8ffcce248b..ca9edead48 100644 --- a/code/modules/mob/living/brain/brain.dm +++ b/code/modules/mob/living/brain/brain.dm @@ -9,7 +9,7 @@ possible_a_intents = list(INTENT_HELP, INTENT_HARM) //for mechas speech_span = SPAN_ROBOT -/mob/living/brain/Initialize() +/mob/living/brain/Initialize(mapload) . = ..() create_dna(src) if(stored_dna.blood_type) @@ -41,9 +41,9 @@ return ..() /mob/living/brain/update_mobility() - return ((mobility_flags = (container?.in_contents_of(/obj/mecha)? MOBILITY_FLAGS_DEFAULT : NONE))) + return ((mobility_flags = (container?.in_contents_of(/obj/vehicle/sealed/mecha)? MOBILITY_FLAGS_DEFAULT : NONE))) -/mob/living/brain/ex_act() //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up. +/mob/living/brain/ex_act(severity, target, origin) //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up. return /mob/living/brain/wave_ex_act(power, datum/wave_explosion/explosion, dir) @@ -71,13 +71,6 @@ if(stored_dna) stored_dna.real_name = real_name -/mob/living/brain/ClickOn(atom/A, params) - ..() - if(container) - var/obj/mecha/M = container.mecha - if(istype(M)) - return M.click_action(A,src,params) - /mob/living/brain/forceMove(atom/destination) if(container) return container.forceMove(destination) @@ -98,7 +91,7 @@ if(!container) return if (container.mecha) - var/obj/mecha/M = container.mecha + var/obj/vehicle/sealed/mecha/M = container.mecha if(M.mouse_pointer) client.mouse_pointer_icon = M.mouse_pointer if (client && ranged_ability && ranged_ability.ranged_mousepointer) diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index c31b566cf3..7e10ae1c39 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -123,7 +123,7 @@ return user.visible_message("[user] starts to pour the contents of [O] onto [src].", "You start to slowly pour the contents of [O] onto [src].") - if(!do_after(user, 60, TRUE, src)) + if(!do_after(user, 6 SECONDS, src)) to_chat(user, "You failed to pour [O] onto [src]!") return @@ -153,7 +153,7 @@ return user.visible_message("[user] starts to pour the contents of [O] onto [src].", "You start to slowly pour the contents of [O] onto [src].") - if(!do_after(user, 60, TRUE, src)) + if(!do_after(user, 6 SECONDS, src)) to_chat(user, "You failed to pour [O] onto [src]!") return diff --git a/code/modules/mob/living/brain/life.dm b/code/modules/mob/living/brain/life.dm index 6d06da41ae..e42f82d5cd 100644 --- a/code/modules/mob/living/brain/life.dm +++ b/code/modules/mob/living/brain/life.dm @@ -1,5 +1,5 @@ -/mob/living/brain/BiologicalLife(seconds, times_fired) +/mob/living/brain/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return handle_emp_damage() @@ -25,9 +25,6 @@ else emp_damage = max(emp_damage-1, 0) -/mob/living/brain/handle_status_effects() - return - /mob/living/brain/handle_traits() return diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm index 893d7c5103..b3749b4a41 100644 --- a/code/modules/mob/living/brain/posibrain.dm +++ b/code/modules/mob/living/brain/posibrain.dm @@ -28,7 +28,7 @@ GLOBAL_VAR(posibrain_notify_cooldown) var/list/possible_names //If you leave this blank, it will use the global posibrain names var/picked_name -/obj/item/mmi/posibrain/Initialize() +/obj/item/mmi/posibrain/Initialize(mapload) . = ..() brainmob = new(src) var/new_name @@ -159,8 +159,8 @@ GLOBAL_VAR(posibrain_notify_cooldown) to_chat(brainmob, welcome_message) brainmob.mind.assigned_role = new_role brainmob.stat = CONSCIOUS - GLOB.dead_mob_list -= brainmob - GLOB.alive_mob_list += brainmob + brainmob.remove_from_dead_mob_list() + brainmob.add_to_alive_mob_list() visible_message(new_mob_message) check_success() diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index e9a62d209b..1b7207d7eb 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -34,7 +34,7 @@ var/static/regex/alien_name_regex = new("alien (larva|sentinel|drone|hunter|praetorian|queen)( \\(\\d+\\))?") -/mob/living/carbon/alien/Initialize() +/mob/living/carbon/alien/Initialize(mapload) add_verb(src, /mob/living/proc/mob_sleep) add_verb(src, /mob/living/proc/lay_down) diff --git a/code/modules/mob/living/carbon/alien/update_icons.dm b/code/modules/mob/living/carbon/alien/alien_update_icons.dm similarity index 100% rename from code/modules/mob/living/carbon/alien/update_icons.dm rename to code/modules/mob/living/carbon/alien/alien_update_icons.dm diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index 28d311b034..a5ea6e1c89 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -17,10 +17,6 @@ Doesn't work on other aliens/AI.*/ action_icon_state = "spell_default" action_background_icon_state = "bg_alien" -/obj/effect/proc_holder/alien/Initialize() - . = ..() - action = new(src) - /obj/effect/proc_holder/alien/Trigger(mob/living/carbon/user, skip_cost_check = FALSE) if(!istype(user)) return TRUE diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm index cf024d707d..3e8a5d8bdb 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm @@ -6,7 +6,7 @@ icon_state = "aliend" meleeKnockdownPower = 80 -/mob/living/carbon/alien/humanoid/drone/Initialize() +/mob/living/carbon/alien/humanoid/drone/Initialize(mapload) AddAbility(new/obj/effect/proc_holder/alien/evolve(null)) . = ..() diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm index a7044174b0..69c1488436 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm @@ -48,13 +48,11 @@ else //Maybe uses plasma in the future, although that wouldn't make any sense... leaping = 1 - weather_immunities += "lava" update_icons() throw_at(A, MAX_ALIEN_LEAP_DIST, 1, src, FALSE, TRUE, callback = CALLBACK(src, .proc/leap_end)) /mob/living/carbon/alien/humanoid/hunter/proc/leap_end() leaping = 0 - weather_immunities -= "lava" update_icons() /mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm index 796a78d566..3e0faf44f0 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm @@ -5,7 +5,7 @@ health = 250 icon_state = "alienp" -/mob/living/carbon/alien/humanoid/royal/praetorian/Initialize() +/mob/living/carbon/alien/humanoid/royal/praetorian/Initialize(mapload) real_name = name AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src)) AddAbility(new /obj/effect/proc_holder/alien/royal/praetorian/evolve()) diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm index 67cf6f7d25..9f8b9d6845 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm @@ -6,7 +6,7 @@ icon_state = "aliens" meleeSlashHumanPower = 15 -/mob/living/carbon/alien/humanoid/sentinel/Initialize() +/mob/living/carbon/alien/humanoid/sentinel/Initialize(mapload) AddAbility(new /obj/effect/proc_holder/alien/sneak) . = ..() diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 0d2a1c0c59..71b1d09fad 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -6,8 +6,6 @@ possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM) limb_destroyer = 1 hud_type = /datum/hud/alien - var/obj/item/r_store = null - var/obj/item/l_store = null var/caste = "" var/alt_icon = 'icons/mob/alienleap.dmi' //used to switch between the two alien icon files. var/leap_on_click = 0 @@ -22,41 +20,26 @@ can_ventcrawl = TRUE +GLOBAL_LIST_INIT(strippable_alien_humanoid_items, create_strippable_list(list( + /datum/strippable_item/hand/left, + /datum/strippable_item/hand/right, + /datum/strippable_item/mob_item_slot/handcuffs, + /datum/strippable_item/mob_item_slot/legcuffs, +))) //This is fine right now, if we're adding organ specific damage this needs to be updated -/mob/living/carbon/alien/humanoid/Initialize() +/mob/living/carbon/alien/humanoid/Initialize(mapload) AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null)) . = ..() + +/mob/living/carbon/alien/humanoid/ComponentInitialize() + . = ..() AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW, 0.5, -3) + AddElement(/datum/element/strippable, GLOB.strippable_alien_humanoid_items) /mob/living/carbon/alien/humanoid/restrained(ignore_grab) return handcuffed -/mob/living/carbon/alien/humanoid/show_inv(mob/user) - user.set_machine(src) - var/list/dat = list() - dat += {" -
    - [name] -
    "} - for(var/i in 1 to held_items.len) - var/obj/item/I = get_item_for_held_index(i) - dat += "
    [get_held_index_name(i)]:[(I && !(I.item_flags & ABSTRACT)) ? I : "Empty"]" - dat += "
    Empty Pouches" - - if(handcuffed) - dat += "
    Handcuffed" - if(legcuffed) - dat += "
    Legcuffed" - - dat += {" -
    -
    Close - "} - user << browse(dat.Join(), "window=mob[REF(src)];size=325x500") - onclose(user, "mob[REF(src)]") - - /mob/living/carbon/alien/humanoid/Topic(href, href_list) ..() //strip panel & embeds @@ -70,12 +53,6 @@ return SEND_SIGNAL(src, COMSIG_CARBON_EMBED_RIP, I, L) return - if(href_list["pouches"]) - visible_message("[usr] tries to empty [src]'s pouches.", \ - "[usr] tries to empty [src]'s pouches.") - if(do_mob(usr, src, POCKET_STRIP_DELAY * 0.5)) - dropItemToGround(r_store) - dropItemToGround(l_store) /mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I) playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_update_icons.dm similarity index 94% rename from code/modules/mob/living/carbon/alien/humanoid/update_icons.dm rename to code/modules/mob/living/carbon/alien/humanoid/humanoid_update_icons.dm index 9563959ebc..ff4a7d2bba 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_update_icons.dm @@ -51,7 +51,7 @@ // update_icons() //Handled in update_transform(), leaving this here as a reminder update_transform() -/mob/living/carbon/alien/humanoid/update_transform() //The old method of updating lying/standing was update_icons(). Aliens still expect that. +/mob/living/carbon/alien/humanoid/update_transform(do_animate) //The old method of updating lying/standing was update_icons(). Aliens still expect that. if(lying > 0) lying = 90 //Anything else looks silly ..() diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index bcc83f14f9..7e1c669e49 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -4,6 +4,8 @@ status_flags = 0 unique_name = 0 pixel_x = -16 + maptext_height = 64 + maptext_width = 64 bubble_icon = "alienroyal" mob_size = MOB_SIZE_LARGE layer = LARGE_MOB_LAYER //above most mobs, but below speechbubbles @@ -28,7 +30,7 @@ icon_state = "alienq" var/datum/action/small_sprite/smallsprite = new/datum/action/small_sprite/queen() -/mob/living/carbon/alien/humanoid/royal/queen/Initialize() +/mob/living/carbon/alien/humanoid/royal/queen/Initialize(mapload) //there should only be one queen for(var/mob/living/carbon/alien/humanoid/royal/queen/Q in GLOB.carbon_list) if(Q == src) @@ -110,7 +112,7 @@ item_flags = ABSTRACT | DROPDEL icon = 'icons/mob/alien.dmi' -/obj/item/queenpromote/Initialize() +/obj/item/queenpromote/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 77c9a8c579..ce38f615f7 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -21,7 +21,7 @@ bodyparts = list(/obj/item/bodypart/chest/larva, /obj/item/bodypart/head/larva) //This is fine right now, if we're adding organ specific damage this needs to be updated -/mob/living/carbon/alien/larva/Initialize() +/mob/living/carbon/alien/larva/Initialize(mapload) AddAbility(new/obj/effect/proc_holder/alien/hide(null)) AddAbility(new/obj/effect/proc_holder/alien/larva_evolve(null)) @@ -51,10 +51,6 @@ // new damage icon system // now constructs damage icon for each organ from mask * damage field - -/mob/living/carbon/alien/larva/show_inv(mob/user) - return - /mob/living/carbon/alien/larva/toggle_throw_mode() return diff --git a/code/modules/mob/living/carbon/alien/larva/update_icons.dm b/code/modules/mob/living/carbon/alien/larva/larva_update_icons.dm similarity index 88% rename from code/modules/mob/living/carbon/alien/larva/update_icons.dm rename to code/modules/mob/living/carbon/alien/larva/larva_update_icons.dm index e6e7e657e8..85416261c7 100644 --- a/code/modules/mob/living/carbon/alien/larva/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva_update_icons.dm @@ -21,7 +21,7 @@ else icon_state = "larva[state]" -/mob/living/carbon/alien/larva/update_transform() //All this is handled in update_icons() +/mob/living/carbon/alien/larva/update_transform(do_animate) //All this is handled in update_icons() ..() return update_icons() diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index f0004b5ed9..b22ff68531 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -1,4 +1,4 @@ -/mob/living/carbon/alien/larva/BiologicalLife(seconds, times_fired) +/mob/living/carbon/alien/larva/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return // GROW! diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index 530d2acd63..b56c897b03 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -1,4 +1,4 @@ -/mob/living/carbon/alien/BiologicalLife(seconds, times_fired) +/mob/living/carbon/alien/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return findQueen() diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm index 41c3882de6..2db912fe7e 100644 --- a/code/modules/mob/living/carbon/alien/organs.dm +++ b/code/modules/mob/living/carbon/alien/organs.dm @@ -4,7 +4,7 @@ var/list/alien_powers = list() organ_flags = ORGAN_NO_SPOIL|ORGAN_EDIBLE -/obj/item/organ/alien/Initialize() +/obj/item/organ/alien/Initialize(mapload) . = ..() for(var/A in alien_powers) if(ispath(A)) diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index ca2946fd8a..7dedf5a739 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -172,7 +172,7 @@ if(target.dropItemToGround(W)) target.visible_message("[src] tears [W] off of [target]'s face!", \ "[src] tears [W] off of [target]'s face!") - target.equip_to_slot_if_possible(src, SLOT_WEAR_MASK, 0, 1, 1) + target.equip_to_slot_if_possible(src, ITEM_SLOT_MASK, 0, 1, 1) return TRUE // time for a smoke /obj/item/clothing/mask/facehugger/proc/Attach(mob/living/M) @@ -259,7 +259,7 @@ return 1 var/mob/living/carbon/C = M - if(ishuman(C) && !(SLOT_WEAR_MASK in C.dna.species.no_equip)) + if(ishuman(C) && !(ITEM_SLOT_MASK in C.dna.species.no_equip)) var/mob/living/carbon/human/H = C if(H.is_mouth_covered(head_only = 1)) return FALSE diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index f6ef8e8177..419a75eff2 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1,13 +1,14 @@ /mob/living/carbon blood_volume = BLOOD_VOLUME_NORMAL -/mob/living/carbon/Initialize() +/mob/living/carbon/Initialize(mapload) . = ..() create_reagents(1000, NONE, NO_REAGENTS_VALUE) update_body_parts() //to update the carbon's new bodyparts appearance GLOB.carbon_list += src blood_volume = (BLOOD_VOLUME_NORMAL * blood_ratio) add_movespeed_modifier(/datum/movespeed_modifier/carbon_crawling) + register_context() /mob/living/carbon/Destroy() //This must be done first, so the mob ghosts correctly before DNA etc is nulled @@ -27,8 +28,8 @@ if(prob(40)) if(prob(25)) audible_message("You hear something rumbling inside [src]'s stomach...", \ - "You hear something rumbling.", 4,\ - "Something is rumbling inside your stomach!") + "You hear something rumbling.", 4,\ + "Something is rumbling inside your stomach!") var/obj/item/I = user.get_active_held_item() if(I && I.force) var/d = rand(round(I.force / 4), I.force) @@ -198,7 +199,7 @@ if(start_T && end_T) log_combat(src, throwable_mob, "thrown", addition="grab from tile in [AREACOORD(start_T)] towards tile at [AREACOORD(end_T)]") - else if(!CHECK_BITFIELD(I.item_flags, ABSTRACT) && !HAS_TRAIT(I, TRAIT_NODROP)) + else if(!(I.item_flags & ABSTRACT) && !HAS_TRAIT(I, TRAIT_NODROP)) thrown_thing = I dropItemToGround(I) @@ -229,61 +230,8 @@ /mob/living/carbon/proc/canBeHandcuffed() return 0 - -/mob/living/carbon/show_inv(mob/user) - user.set_machine(src) - var/dat = {" -
    - [name] -
    -
    Head: [(head && !(head.item_flags & ABSTRACT)) ? head : "Nothing"] -
    Mask: [(wear_mask && !(wear_mask.item_flags & ABSTRACT)) ? wear_mask : "Nothing"] -
    Neck: [(wear_neck && !(wear_neck.item_flags & ABSTRACT)) ? wear_neck : "Nothing"]"} - - for(var/i in 1 to held_items.len) - var/obj/item/I = get_item_for_held_index(i) - dat += "
    [get_held_index_name(i)]:[(I && !(I.item_flags & ABSTRACT)) ? I : "Nothing"]" - - dat += "
    Back: [back ? back : "Nothing"]" - - if(!HAS_TRAIT(src, TRAIT_NO_INTERNALS) && istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/tank)) - dat += "
    [internal ? "Disable Internals" : "Set Internals"]" - - if(handcuffed) - dat += "
    Handcuffed" - if(legcuffed) - dat += "
    Legcuffed" - - dat += {" -
    -
    Close - "} - user << browse(dat, "window=mob[REF(src)];size=325x500") - onclose(user, "mob[REF(src)]") - /mob/living/carbon/Topic(href, href_list) ..() - //strip panel - if(usr.canUseTopic(src, BE_CLOSE)) - if(href_list["internal"] && !HAS_TRAIT(src, TRAIT_NO_INTERNALS)) - var/slot = text2num(href_list["internal"]) - var/obj/item/ITEM = get_item_by_slot(slot) - if(ITEM && istype(ITEM, /obj/item/tank) && wear_mask && (wear_mask.clothing_flags & ALLOWINTERNALS)) - visible_message("[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].", \ - "[usr] tries to [internal ? "close" : "open"] the valve on your [ITEM.name].", \ - target = usr, target_message = "You try to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].") - if(do_mob(usr, src, POCKET_STRIP_DELAY)) - if(internal) - internal = null - update_internals_hud_icon(0) - else if(ITEM && istype(ITEM, /obj/item/tank)) - if((wear_mask && (wear_mask.clothing_flags & ALLOWINTERNALS)) || getorganslot(ORGAN_SLOT_BREATHING_TUBE)) - internal = ITEM - update_internals_hud_icon(1) - - visible_message("[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name].", \ - "[usr] [internal ? "opens" : "closes"] the valve on your [ITEM.name].", \ - target = usr, target_message = "You [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name].") if(href_list["embedded_object"] && usr.canUseTopic(src, BE_CLOSE)) var/obj/item/bodypart/L = locate(href_list["embedded_limb"]) in bodyparts if(!L) @@ -314,12 +262,12 @@ // too soon. var/buckle_cd = 600 if(handcuffed) - var/obj/item/restraints/O = src.get_item_by_slot(SLOT_HANDCUFFED) + var/obj/item/restraints/O = src.get_item_by_slot(ITEM_SLOT_HANDCUFFED) buckle_cd = O.breakouttime MarkResistTime() visible_message("[src] attempts to unbuckle [p_them()]self!", \ "You attempt to unbuckle yourself... (This will take around [round(buckle_cd/600,1)] minute\s, and you need to stay still.)") - if(do_after(src, buckle_cd, 0, target = src, required_mobility_flags = MOBILITY_RESIST)) + if(do_after(src, buckle_cd, src, timed_action_flags = IGNORE_HELD_ITEM | IGNORE_INCAPACITATED, extra_checks = CALLBACK(src, .proc/cuff_resist_check))) if(!buckled) return buckled.user_unbuckle_mob(src, src) @@ -356,13 +304,16 @@ if(I.item_flags & BEING_REMOVED) to_chat(src, "You're already attempting to remove [I]!") return + var/obj/item/restraints/R = istype(I, /obj/item/restraints) ? I : null + var/allow_breakout_movement = IGNORE_INCAPACITATED + if(R?.allow_breakout_movement) + allow_breakout_movement = (IGNORE_INCAPACITATED|IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE) I.item_flags |= BEING_REMOVED breakouttime = I.breakouttime - var/datum/cuffbreak_checker/cuffbreak_checker = new(get_turf(src), istype(I, /obj/item/restraints)? I : null) if(!cuff_break) visible_message("[src] attempts to remove [I]!") to_chat(src, "You attempt to remove [I]... (This will take around [DisplayTimeText(breakouttime)] and you need to stand still.)") - if(do_after_advanced(src, breakouttime, src, NONE, CALLBACK(cuffbreak_checker, /datum/cuffbreak_checker.proc/check_movement), required_mobility_flags = MOBILITY_RESIST)) + if(do_after(src, breakouttime, target = src, timed_action_flags = allow_breakout_movement, extra_checks = CALLBACK(src, PROC_REF(cuff_resist_check)))) clear_cuffs(I, cuff_break) else to_chat(src, "You fail to remove [I]!") @@ -371,7 +322,7 @@ breakouttime = 50 visible_message("[src] is trying to break [I]!") to_chat(src, "You attempt to break [I]... (This will take around 5 seconds and you need to stand still.)") - if(do_after_advanced(src, breakouttime, src, NONE, CALLBACK(cuffbreak_checker, /datum/cuffbreak_checker.proc/check_movement), required_mobility_flags = MOBILITY_RESIST)) + if(do_after(src, breakouttime, target = src, timed_action_flags = allow_breakout_movement, extra_checks = CALLBACK(src, PROC_REF(cuff_resist_check)))) clear_cuffs(I, cuff_break) else to_chat(src, "You fail to break [I]!") @@ -379,27 +330,10 @@ else if(cuff_break == INSTANT_CUFFBREAK) clear_cuffs(I, cuff_break) - QDEL_NULL(cuffbreak_checker) I.item_flags &= ~BEING_REMOVED -/datum/cuffbreak_checker - var/turf/last - var/obj/item/restraints/cuffs - -/datum/cuffbreak_checker/New(turf/initial_turf, obj/item/restraints/R) - last = initial_turf - if(R) - cuffs = R - -/datum/cuffbreak_checker/proc/check_movement(atom/user, delay, atom/target, time_left, do_after_flags, required_mobility_flags, required_combat_flags, mob_redirect, stage, initially_held_item, tool, list/passed_in) - if(get_turf(user) != last) - last = get_turf(user) - passed_in[1] = 0.5 - if(cuffs && !cuffs.allow_breakout_movement) - return DO_AFTER_STOP - else - passed_in[1] = 1 - return DO_AFTER_CONTINUE +/mob/living/carbon/proc/cuff_resist_check() + return !incapacitated(ignore_restraints = TRUE) /mob/living/carbon/proc/uncuff() if (handcuffed) @@ -621,12 +555,12 @@ to_chat(src, "You're too exhausted to keep going...") set_resting(TRUE, FALSE, FALSE) SEND_SIGNAL(src, COMSIG_DISABLE_COMBAT_MODE) - ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_HARD_STAMCRIT) + combat_flags |= COMBAT_FLAG_HARD_STAMCRIT filters += CIT_FILTER_STAMINACRIT update_mobility() if((combat_flags & COMBAT_FLAG_HARD_STAMCRIT) && total_health <= STAMINA_CRIT_REMOVAL_THRESHOLD) to_chat(src, "You don't feel nearly as exhausted anymore.") - DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_HARD_STAMCRIT) + combat_flags &= ~(COMBAT_FLAG_HARD_STAMCRIT) filters -= CIT_FILTER_STAMINACRIT update_mobility() UpdateStaminaBuffer() @@ -677,12 +611,21 @@ if(M.name == XRAY) sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS) see_in_dark = max(see_in_dark, 8) + + if(HAS_TRAIT(src, TRAIT_TRUE_NIGHT_VISION)) + lighting_alpha = min(lighting_alpha, LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) + see_in_dark = max(see_in_dark, 8) + + if(HAS_TRAIT(src, TRAIT_MESON_VISION)) + sight |= SEE_TURFS + lighting_alpha = min(lighting_alpha, LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) + if(HAS_TRAIT(src, TRAIT_THERMAL_VISION)) - sight |= (SEE_MOBS) + sight |= SEE_MOBS lighting_alpha = min(lighting_alpha, LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) if(HAS_TRAIT(src, TRAIT_XRAY_VISION)) - sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS) + sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS see_in_dark = max(see_in_dark, 8) if(see_override) @@ -699,7 +642,7 @@ become_blind(EYES_COVERED) else if(tinttotal >= TINT_DARKENED) cure_blind(EYES_COVERED) - overlay_fullscreen("tint", /atom/movable/screen/fullscreen/impaired, 2) + overlay_fullscreen("tint", /atom/movable/screen/fullscreen/scaled/impaired, 2) else cure_blind(EYES_COVERED) clear_fullscreen("tint", 0) @@ -775,10 +718,10 @@ visionseverity = 9 if(-INFINITY to -24) visionseverity = 10 - overlay_fullscreen("critvision", /atom/movable/screen/fullscreen/crit/vision, visionseverity) + overlay_fullscreen("critvision", /atom/movable/screen/fullscreen/scaled/crit/vision, visionseverity) else clear_fullscreen("critvision") - overlay_fullscreen("crit", /atom/movable/screen/fullscreen/crit, severity) + overlay_fullscreen("crit", /atom/movable/screen/fullscreen/scaled/crit, severity) else clear_fullscreen("crit") clear_fullscreen("critvision") @@ -802,7 +745,7 @@ severity = 6 if(45 to INFINITY) severity = 7 - overlay_fullscreen("oxy", /atom/movable/screen/fullscreen/oxy, severity) + overlay_fullscreen("oxy", /atom/movable/screen/fullscreen/scaled/oxy, severity) else clear_fullscreen("oxy") @@ -823,7 +766,7 @@ severity = 5 if(85 to INFINITY) severity = 6 - overlay_fullscreen("brute", /atom/movable/screen/fullscreen/brute, severity) + overlay_fullscreen("brute", /atom/movable/screen/fullscreen/scaled/brute, severity) else clear_fullscreen("brute") @@ -898,16 +841,16 @@ update_inv_handcuffed() update_hud_handcuffed() -/mob/living/carbon/proc/can_defib() +/mob/living/carbon/proc/can_revive(ignore_timelimit = FALSE, maximum_brute_dam = MAX_REVIVE_BRUTE_DAMAGE, maximum_fire_dam = MAX_REVIVE_FIRE_DAMAGE, ignore_heart = FALSE) var/tlimit = DEFIB_TIME_LIMIT * 10 var/obj/item/organ/heart = getorgan(/obj/item/organ/heart) if(suiciding || hellbound || HAS_TRAIT(src, TRAIT_HUSK) || AmBloodsucker(src)) return - if((world.time - timeofdeath) > tlimit) + if(!ignore_timelimit && (world.time - timeofdeath) > tlimit) return - if((getBruteLoss() >= MAX_REVIVE_BRUTE_DAMAGE) || (getFireLoss() >= MAX_REVIVE_FIRE_DAMAGE)) + if((getBruteLoss() >= maximum_brute_dam) || (getFireLoss() >= maximum_fire_dam)) return - if(!heart || (heart.organ_flags & ORGAN_FAILING)) + if(!ignore_heart && (!heart || (heart.organ_flags & ORGAN_FAILING))) return var/obj/item/organ/brain/BR = getorgan(/obj/item/organ/brain) if(QDELETED(BR) || BR.brain_death || (BR.organ_flags & ORGAN_FAILING) || suiciding) @@ -1190,15 +1133,15 @@ /mob/living/carbon/check_obscured_slots() if(head) if(head.flags_inv & HIDEMASK) - LAZYOR(., SLOT_WEAR_MASK) + LAZYOR(., ITEM_SLOT_MASK) if(head.flags_inv & HIDEEYES) - LAZYOR(., SLOT_GLASSES) + LAZYOR(., ITEM_SLOT_EYES) if(head.flags_inv & HIDEEARS) - LAZYOR(., SLOT_EARS) + LAZYOR(., ITEM_SLOT_EARS) if(wear_mask) if(wear_mask.flags_inv & HIDEEYES) - LAZYOR(., SLOT_GLASSES) + LAZYOR(., ITEM_SLOT_EYES) // if any of our bodyparts are bleeding /mob/living/carbon/proc/is_bleeding() diff --git a/code/modules/mob/living/carbon/carbon_context.dm b/code/modules/mob/living/carbon/carbon_context.dm new file mode 100644 index 0000000000..e7fc4d11bf --- /dev/null +++ b/code/modules/mob/living/carbon/carbon_context.dm @@ -0,0 +1,48 @@ +/mob/living/carbon/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + + if (!isnull(held_item)) + return . + + if (!ishuman(user)) + return . + + var/combat_mode = SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE) + + if(user == src) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_HELP, "Check injuries") + else if(!lying) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_HELP, "Comfort") + else if (health >= 0 && !HAS_TRAIT(src, TRAIT_FAKEDEATH)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_HELP, "Shake") + else + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_HELP, "CPR") + + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_DISARM, "Disarm") + if(combat_mode && (src != user)) + LAZYSET(context[SCREENTIP_CONTEXT_RMB], INTENT_DISARM, "Shove") + + if(src != user) + if (pulledby == user) + switch (user.grab_state) + if (GRAB_PASSIVE) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_GRAB, "Grip") + if (GRAB_AGGRESSIVE) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_GRAB, "Choke") + if (GRAB_NECK) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_GRAB, "Strangle") + else + return . + else + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_GRAB, "Pull") + + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_HARM, "Attack") + + // Monkeys cannot be grabbed harder using ctrl-click, don't ask. + if((pulledby != user) && (src != user)) + LAZYSET(context[SCREENTIP_CONTEXT_CTRL_LMB], INTENT_ANY, "Pull") + // Happens on any intent i believe + if((user == src) && combat_mode && lying) + LAZYSET(context[SCREENTIP_CONTEXT_RMB], INTENT_ANY, "Force to get up") + + return CONTEXTUAL_SCREENTIP_SET diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 46ba9a5eb0..a12d6614fa 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -361,7 +361,7 @@ return embeds -/mob/living/carbon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/flash, override_protection = 0) +/mob/living/carbon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/tiled/flash, override_protection = 0) . = ..() var/damage = override_protection ? intensity : intensity - get_eye_protection() diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm index 65e59d0e29..e70b1bcc92 100644 --- a/code/modules/mob/living/carbon/carbon_movement.dm +++ b/code/modules/mob/living/carbon/carbon_movement.dm @@ -16,20 +16,26 @@ if(istype(T) && movement_dir && T.allow_thrust(0.01)) return 1 - var/obj/item/tank/jetpack/J = get_jetpack() - if(istype(J) && (movement_dir || J.stabilizers) && J.allow_thrust(0.01, src)) - return 1 + var/obj/item/I = get_jetpack() + if(istype(I, /obj/item/tank/jetpack)) + var/obj/item/tank/jetpack/J = I + if((movement_dir || J.stabilizers) && J.allow_thrust(0.01, src)) + return 1 + else if(istype(I, /obj/item/mod/module/jetpack)) + var/obj/item/mod/module/jetpack/J = I + if((movement_dir || J.stabilizers) && J.allow_thrust()) + return 1 /mob/living/carbon/Moved() . = ..() - if(. && (movement_type & FLOATING)) //floating is easy + if(. && !(movement_type & FLOATING)) //floating is easy if(HAS_TRAIT(src, TRAIT_NOHUNGER)) set_nutrition(NUTRITION_LEVEL_FED - 1) //just less than feeling vigorous else if(nutrition && stat != DEAD) var/loss = HUNGER_FACTOR/10 if(m_intent == MOVE_INTENT_RUN) loss *= 2 - adjust_nutrition(loss) + adjust_nutrition(-loss) /mob/living/carbon/can_move_under_living(mob/living/other) . = ..() diff --git a/code/modules/mob/living/carbon/carbon_stripping.dm b/code/modules/mob/living/carbon/carbon_stripping.dm new file mode 100644 index 0000000000..afbd6edaeb --- /dev/null +++ b/code/modules/mob/living/carbon/carbon_stripping.dm @@ -0,0 +1,145 @@ +/datum/strippable_item/mob_item_slot/head + key = STRIPPABLE_ITEM_HEAD + item_slot = ITEM_SLOT_HEAD + +/datum/strippable_item/mob_item_slot/back + key = STRIPPABLE_ITEM_BACK + item_slot = ITEM_SLOT_BACK + +/datum/strippable_item/mob_item_slot/back/get_alternate_action(atom/source, mob/user) + if(..() == FALSE) + return null + return get_strippable_alternate_action_internals(get_item(source), source) + +/datum/strippable_item/mob_item_slot/back/alternate_action(atom/source, mob/user) + if (!..()) + return null + return strippable_alternate_action_internals(get_item(source), source, user) + +/datum/strippable_item/mob_item_slot/mask + key = STRIPPABLE_ITEM_MASK + item_slot = ITEM_SLOT_MASK + +/datum/strippable_item/mob_item_slot/neck + key = STRIPPABLE_ITEM_NECK + item_slot = ITEM_SLOT_NECK + +/datum/strippable_item/mob_item_slot/handcuffs + key = STRIPPABLE_ITEM_HANDCUFFS + item_slot = ITEM_SLOT_HANDCUFFED + +/datum/strippable_item/mob_item_slot/handcuffs/should_show(atom/source, mob/user) + if (!iscarbon(source)) + return FALSE + + var/mob/living/carbon/carbon_source = source + return !isnull(carbon_source.handcuffed) + +// You shouldn't be able to equip things to handcuff slots. +/datum/strippable_item/mob_item_slot/handcuffs/try_equip(atom/source, obj/item/equipping, mob/user) + return FALSE + +/datum/strippable_item/mob_item_slot/legcuffs + key = STRIPPABLE_ITEM_LEGCUFFS + item_slot = ITEM_SLOT_LEGCUFFED + +/datum/strippable_item/mob_item_slot/legcuffs/should_show(atom/source, mob/user) + if (!iscarbon(source)) + return FALSE + + var/mob/living/carbon/carbon_source = source + return !isnull(carbon_source.legcuffed) + +// You shouldn't be able to equip things to legcuff slots. +/datum/strippable_item/mob_item_slot/legcuffs/try_equip(atom/source, obj/item/equipping, mob/user) + return FALSE + +/// A strippable item for a hand +/datum/strippable_item/hand + // Putting dangerous clothing in our hand is fine. + warn_dangerous_clothing = FALSE + + /// Which hand? + var/hand_index + +/datum/strippable_item/hand/get_item(atom/source) + if (!ismob(source)) + return null + + var/mob/mob_source = source + return mob_source.get_item_for_held_index(hand_index) + +/datum/strippable_item/hand/try_equip(atom/source, obj/item/equipping, mob/user) + . = ..() + if (!.) + return FALSE + + if (!ismob(source)) + return FALSE + + var/mob/mob_source = source + + if (!mob_source.can_put_in_hand(equipping, hand_index)) + to_chat(src, "\The [equipping] doesn't fit in that place!") + return FALSE + + return TRUE + +/datum/strippable_item/hand/start_equip(atom/source, obj/item/equipping, mob/user) + . = ..() + if (!.) + return + + if (!ismob(source)) + return FALSE + + var/mob/mob_source = source + + if (!do_mob(user, source, equipping.equip_delay_other)) + return FALSE + + if(get_obscuring(source) == STRIPPABLE_OBSCURING_COMPLETELY) + return FALSE + + if (!mob_source.can_put_in_hand(equipping, hand_index)) + return FALSE + + if (!user.temporarilyRemoveItemFromInventory(equipping)) + return FALSE + + return TRUE + +/datum/strippable_item/hand/finish_equip(atom/source, obj/item/equipping, mob/user) + if(!..()) + return FALSE + if (!iscarbon(source)) + return FALSE + + var/mob/mob_source = source + mob_source.put_in_hand(equipping, hand_index) + +/datum/strippable_item/hand/start_unequip(atom/source, mob/user) + . = ..() + if (!.) + return + + return start_unequip_mob(get_item(source), source, user) + +/datum/strippable_item/hand/finish_unequip(atom/source, mob/user) + ..() + var/obj/item/item = get_item(source) + if (isnull(item)) + return FALSE + + if (!ismob(source)) + return FALSE + + return finish_unequip_mob(item, source, user) + +/datum/strippable_item/hand/left + key = STRIPPABLE_ITEM_LHAND + hand_index = 1 + +/datum/strippable_item/hand/right + key = STRIPPABLE_ITEM_RHAND + hand_index = 2 diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm similarity index 94% rename from code/modules/mob/living/carbon/update_icons.dm rename to code/modules/mob/living/carbon/carbon_update_icons.dm index 43e0db1f08..cd9cd5db4c 100644 --- a/code/modules/mob/living/carbon/update_icons.dm +++ b/code/modules/mob/living/carbon/carbon_update_icons.dm @@ -91,7 +91,7 @@ return if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_MASK] + var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_MASK) + 1] inv?.update_icon() if(wear_mask) @@ -104,8 +104,8 @@ /mob/living/carbon/update_inv_neck() remove_overlay(NECK_LAYER) - if(client && hud_used && hud_used.inv_slots[SLOT_NECK]) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_NECK] + if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_NECK) + 1]) + var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_NECK) + 1] inv.update_icon() if(wear_neck) @@ -119,7 +119,7 @@ remove_overlay(BACK_LAYER) if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_BACK] + var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_BACK) + 1] inv?.update_icon() if(back) @@ -135,7 +135,7 @@ return if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD] + var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_HEAD) + 1] inv?.update_icon() if(head) diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index 4167fdbde1..85c188d2ab 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -90,10 +90,12 @@ /mob/living/carbon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, toxins_type = TOX_DEFAULT) if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER) && toxins_type != TOX_SYSCORRUPT) //damage becomes healing and healing becomes damage amount = -amount + // don't allow toxinlover to push blood levels past BLOOD_VOLUME_MAXIMUM, but also don't set it back down to this if it's higher from something else + var/blood_cap = blood_volume > BLOOD_VOLUME_MAXIMUM ? blood_volume : BLOOD_VOLUME_MAXIMUM if(amount > 0) - blood_volume -= 3 * amount //5x was too much, this is punishing enough. + blood_volume = min((blood_volume - (3 * amount)), blood_cap) //5x was too much, this is punishing enough. else - blood_volume -= amount + blood_volume = min((blood_volume - amount), blood_cap) return ..() /mob/living/carbon/getStaminaLoss() @@ -209,7 +211,7 @@ if(!parts.len) return var/obj/item/bodypart/picked = pick(parts) - if(picked.receive_damage(brute, burn, stamina,check_armor ? run_armor_check(picked, (brute ? "melee" : burn ? "fire" : stamina ? "bullet" : null)) : FALSE, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) + if(picked.receive_damage(brute, burn, stamina,check_armor ? run_armor_check(picked, (brute ? MELEE : burn ? FIRE : stamina ? BULLET : null)) : FALSE, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) update_damage_overlays() //Heal MANY bodyparts, in random order diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index 5eabae16f7..958a8b599a 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -6,7 +6,7 @@ var/t_has = p_have() var/t_is = p_are() - . = list("*---------*\nThis is [icon2html(src, user)] \a [src]!") + . = list("This is [icon2html(src, user)] \a [src]!") if (handcuffed) . += "[t_He] [t_is] [icon2html(handcuffed, user)] handcuffed!" @@ -152,8 +152,11 @@ . += "[t_He] look[p_s()] very happy." if(MOOD_LEVEL_HAPPY4 to INFINITY) . += "[t_He] look[p_s()] ecstatic." + + if(LAZYLEN(.) > 1) + .[2] = "
    [.[2]]" + SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) - . += "*---------*
    " /mob/living/carbon/examine_more(mob/user) if(!all_scars) diff --git a/code/modules/mob/living/carbon/handle_corruption.dm b/code/modules/mob/living/carbon/handle_corruption.dm index 5ac2a2f616..b56752453b 100644 --- a/code/modules/mob/living/carbon/handle_corruption.dm +++ b/code/modules/mob/living/carbon/handle_corruption.dm @@ -37,7 +37,7 @@ var/list/whatmighthappen = list() whatmighthappen += list("avoided" = 3, "dropthing" = 1, "movetile" = 1, "shortdeaf" = 1, "flopover" = 1, "nutriloss" = 1, "selfflash" = 1, "harmies" = 1) if(corruption >= CORRUPTION_THRESHHOLD_MAJOR) - whatmighthappen += list("longdeaf" = 1, "longknockdown" = 1, "shortlimbdisable" = 1, "shortblind" = 1, "shortstun" = 1, "shortmute" = 1, "vomit" = 1, "halluscinate" = 1) + whatmighthappen += list("longdeaf" = 1, "longknockdown" = 1, "shortlimbdisable" = 1, "shortblind" = 1, "shortstun" = 1, "shortmute" = 1, "vomit" = 1, "hallucinate" = 1, "jamcoolanthud" = 1) if(corruption >= CORRUPTION_THRESHHOLD_CRITICAL) whatmighthappen += list("receporgandamage" = 1, "longlimbdisable" = 1, "blindmutedeaf" = 1, "longstun" = 1, "sleep" = 1, "inducetrauma" = 1, "amplifycorrupt" = 1, "changetemp" = 1) var/event = pickweight(whatmighthappen) @@ -97,8 +97,10 @@ if("vomit") to_chat(src, "Ejecting contaminant.") vomit() - if("halluscinate") + if("hallucinate") hallucination += 20 //Doesn't give a cue + if("jamcoolanthud") + hud_used.coolant_display.jam(10) if("receporgandamage") adjustOrganLoss(ORGAN_SLOT_EARS, rand(10, 20)) adjustOrganLoss(ORGAN_SLOT_EYES, rand(10, 20)) @@ -159,7 +161,7 @@ /mob/living/carbon/proc/forcesleep(time = 100) to_chat(src, "Preparations complete, powering down.") - Sleeping(time, 0) + Sleeping(time) #undef CORRUPTION_CHECK_INTERVAL diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 4e6aac4bcb..4ca45ceabd 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -1,3 +1,4 @@ +GLOBAL_LIST_EMPTY(dead_players_during_shift) /mob/living/carbon/human/gib_animation() new /obj/effect/temp_visual/gib_animation(loc, "gibbed-h") @@ -39,11 +40,9 @@ dizziness = 0 jitteriness = 0 - - if(ismecha(loc)) - var/obj/mecha/M = loc - if(M.occupant == src) - M.go_out() + if(client && !suiciding && !(client in GLOB.dead_players_during_shift)) + GLOB.dead_players_during_shift += client + GLOB.deaths_during_shift++ if(!QDELETED(dna)) //The gibbed param is bit redundant here since dna won't exist at this point if they got deleted. dna.species.spec_death(gibbed, src) diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm index 3074abd070..974dafb147 100644 --- a/code/modules/mob/living/carbon/human/dummy.dm +++ b/code/modules/mob/living/carbon/human/dummy.dm @@ -31,6 +31,27 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) randomize_human(src) dna.initialize_dna(skip_index = TRUE) //Skip stuff that requires full round init. +/// Provides a dummy that is consistently bald, white, naked, etc. +/mob/living/carbon/human/dummy/consistent + +/mob/living/carbon/human/dummy/consistent/setup_human_dna() + create_dna(src) + dna.initialize_dna(skip_index = TRUE) + dna.features["body_markings"] = "None" + dna.features["ears"] = "Cat" + dna.features["ethcolor"] = COLOR_WHITE + dna.features["frills"] = "None" + dna.features["horns"] = "None" + dna.features["mcolor"] = COLOR_LIME + dna.features["moth_antennae"] = "Plain" + dna.features["moth_markings"] = "None" + dna.features["moth_wings"] = "Plain" + dna.features["snout"] = "Round" + dna.features["spines"] = "None" + dna.features["tail_human"] = "Cat" + dna.features["tail_lizard"] = "Smooth" + + //Inefficient pooling/caching way. GLOBAL_LIST_EMPTY(human_dummy_list) GLOBAL_LIST_EMPTY(dummy_mob_list) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 3015d1edc3..0388f2bc83 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -6,7 +6,7 @@ /datum/emote/living/carbon/human/cry/run_emote(mob/user, params) . = ..() - if(. && isipcperson(user)) + if(. && isrobotic(user)) do_fake_sparks(5,FALSE,user) /datum/emote/living/carbon/human/dap @@ -198,7 +198,7 @@ //rock paper scissors emote handling /mob/living/carbon/human/proc/beginRockPaperScissors(var/chosen_move) GLOB.rockpaperscissors_players[src] = list(chosen_move, ROCKPAPERSCISSORS_NOT_DECIDED) - do_after_advanced(src, ROCKPAPERSCISSORS_TIME_LIMIT, src, DO_AFTER_REQUIRES_USER_ON_TURF|DO_AFTER_NO_COEFFICIENT|DO_AFTER_NO_PROGRESSBAR|DO_AFTER_DISALLOW_MOVING_ABSOLUTE_USER, CALLBACK(src, .proc/rockpaperscissors_tick)) + do_after(src, ROCKPAPERSCISSORS_TIME_LIMIT, src, extra_checks = CALLBACK(src, .proc/rockpaperscissors_tick)) var/new_entry = GLOB.rockpaperscissors_players[src] if(new_entry[2] == ROCKPAPERSCISSORS_NOT_DECIDED) to_chat(src, "You put your hand back down.") @@ -240,10 +240,10 @@ src.visible_message("[opponent] wins!") //make the progress bar end so that each player can handle the result - return DO_AFTER_STOP + return FALSE //no opponent was found, so keep searching - return DO_AFTER_PROCEED + return TRUE //the actual emotes /datum/emote/living/carbon/human/rockpaperscissors diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index f363aecf84..93bd4c4eba 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -13,7 +13,7 @@ if(HAS_TRAIT(L, TRAIT_PROSOPAGNOSIA)) obscure_name = TRUE - . = list("*---------*\nThis is [!obscure_name ? name : "Unknown"]!") + . = list("This is [!obscure_name ? name : "Unknown"]!") var/vampDesc = ReturnVampExamine(user) // Vamps recognize the names of other vamps. var/vassDesc = ReturnVassalExamine(user) // Vassals recognize each other's marks. @@ -31,7 +31,7 @@ . += "[t_He] [t_is] a [spec_trait_examine_font()][dna.custom_species ? dna.custom_species : dna.species.name]
    !" //uniform - if(w_uniform && !(SLOT_W_UNIFORM in obscured)) + if(w_uniform && !(ITEM_SLOT_ICLOTHING in obscured)) //accessory var/accessory_msg if(istype(w_uniform, /obj/item/clothing/under)) @@ -47,7 +47,7 @@ if(wear_suit && !(wear_suit.obj_flags & EXAMINE_SKIP)) . += "[t_He] [t_is] wearing [wear_suit.get_examine_string(user)]." //suit/armor storage - if(s_store && !(SLOT_S_STORE in obscured)) + if(s_store && !(ITEM_SLOT_SUITSTORE in obscured)) . += "[t_He] [t_is] carrying [s_store.get_examine_string(user)] on [t_his] [wear_suit.name]." //back if(back) @@ -59,7 +59,7 @@ . += "[t_He] [t_is] holding [I.get_examine_string(user)] in [t_his] [get_held_index_name(get_held_index_of_item(I))]." //gloves - if(gloves && !(SLOT_GLOVES in obscured)) + if(gloves && !(ITEM_SLOT_GLOVES in obscured)) . += "[t_He] [t_has] [gloves.get_examine_string(user)] on [t_his] hands." else if(length(blood_DNA)) var/hand_number = get_num_arms(FALSE) @@ -78,18 +78,18 @@ . += "[t_He] [t_has] [belt.get_examine_string(user)] about [t_his] waist." //shoes - if(shoes && !(SLOT_SHOES in obscured)) + if(shoes && !(ITEM_SLOT_FEET in obscured)) . += "[t_He] [t_is] wearing [shoes.get_examine_string(user)] on [t_his] feet." //mask - if(wear_mask && !(SLOT_WEAR_MASK in obscured)) + if(wear_mask && !(ITEM_SLOT_MASK in obscured)) . += "[t_He] [t_has] [wear_mask.get_examine_string(user)] on [t_his] face." - if(wear_neck && !(SLOT_NECK in obscured)) + if(wear_neck && !(ITEM_SLOT_NECK in obscured)) . += "[t_He] [t_is] wearing [wear_neck.get_examine_string(user)] around [t_his] neck." //eyes - if(!(SLOT_GLASSES in obscured)) + if(!(ITEM_SLOT_EYES in obscured)) if(glasses) . += "[t_He] [t_has] [glasses.get_examine_string(user)] covering [t_his] eyes." else if((left_eye_color == BLOODCULT_EYE || right_eye_color == BLOODCULT_EYE) && iscultist(src) && HAS_TRAIT(src, TRAIT_CULT_EYES)) @@ -100,7 +100,7 @@ . += "[t_His] eyes are flickering a bright yellow!" //ears - if(ears && !(SLOT_EARS in obscured)) + if(ears && !(ITEM_SLOT_EARS in obscured)) . += "[t_He] [t_has] [ears.get_examine_string(user)] on [t_his] ears." //ID @@ -113,11 +113,11 @@ . += effects_exam //CIT CHANGES START HERE - adds genital details to examine text - if(LAZYLEN(internal_organs) && CHECK_BITFIELD(user.client?.prefs.cit_toggles, GENITAL_EXAMINE)) + if(LAZYLEN(internal_organs) && (user.client?.prefs.cit_toggles & GENITAL_EXAMINE)) for(var/obj/item/organ/genital/dicc in internal_organs) if(istype(dicc) && dicc.is_exposed()) . += "[dicc.desc]" - if(CHECK_BITFIELD(user.client?.prefs.cit_toggles, VORE_EXAMINE)) + if(user.client?.prefs.cit_toggles & VORE_EXAMINE) var/cursed_stuff = attempt_vr(src,"examine_bellies",args) //vore Code if(cursed_stuff) . += cursed_stuff @@ -249,16 +249,17 @@ if(DISGUST_LEVEL_DISGUSTED to INFINITY) msg += "[t_He] look[p_s()] extremely disgusted.\n" - var/apparent_blood_volume = blood_volume - if(dna.species.use_skintones && skin_tone == "albino") - apparent_blood_volume -= 150 // enough to knock you down one tier - switch(apparent_blood_volume) - if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) - msg += "[t_He] [t_has] pale skin.\n" - if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) - msg += "[t_He] look[p_s()] like pale death.\n" - if(-INFINITY to BLOOD_VOLUME_BAD) - msg += "[t_He] resemble[p_s()] a crushed, empty juice pouch.\n" + if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) + var/apparent_blood_volume = blood_volume + if(dna.species.use_skintones && skin_tone == "albino") + apparent_blood_volume -= 150 // enough to knock you down one tier + switch(apparent_blood_volume) + if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) + msg += "[t_He] [t_has] pale skin.\n" + if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) + msg += "[t_He] look[p_s()] like pale death.\n" + if(-INFINITY to BLOOD_VOLUME_BAD) + msg += "[t_He] resemble[p_s()] a crushed, empty juice pouch.\n" if(bleedsuppress) msg += "[t_He] [t_is] embued with a power that defies bleeding.\n" // only statues and highlander sword can cause this so whatever @@ -441,9 +442,10 @@ else if(isobserver(user) && traitstring) . += "Traits: [traitstring]" - SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) //This also handles flavor texts now + if(LAZYLEN(.) > 2) //Want this to appear after species text + .[3] = "
    [.[3]]" - . += "*---------*" + SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) //This also handles flavor texts now /mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects! var/list/dat = list() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index e3af31ae96..b8d102a2f1 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -5,7 +5,7 @@ icon_state = "caucasian_m" SET_APPEARANCE_FLAGS(KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE) -/mob/living/carbon/human/Initialize() +/mob/living/carbon/human/Initialize(mapload) add_verb(src, /mob/living/proc/mob_sleep) add_verb(src, /mob/living/proc/lay_down) add_verb(src, /mob/living/carbon/human/verb/underwear_toggle) @@ -47,6 +47,7 @@ AddElement(/datum/element/flavor_text/carbon, _name = "Flavor Text", _save_key = "flavor_text") AddElement(/datum/element/flavor_text/carbon/temporary, "", "Set Pose (Temporary Flavor Text)", "This should be used only for things pertaining to the current round!", _save_key = null) AddElement(/datum/element/flavor_text, _name = "OOC Notes", _addendum = "Put information on ERP/vore/lewd-related preferences here. THIS SHOULD NOT CONTAIN REGULAR FLAVORTEXT!!", _always_show = TRUE, _save_key = "ooc_notes", _examine_no_preview = TRUE) + AddElement(/datum/element/strippable, GLOB.strippable_human_items, /mob/living/carbon/human/.proc/should_strip) /mob/living/carbon/human/Destroy() QDEL_NULL(physiology) @@ -82,6 +83,7 @@ . += "" . += "Chemical Storage: [changeling.chem_charges]/[changeling.chem_storage]" . += "Absorbed DNA: [changeling.absorbedcount]" + //NINJACODE if(istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)) //Only display if actually a ninja. var/obj/item/clothing/suit/space/space_ninja/SN = wear_suit @@ -90,7 +92,6 @@ if(SN.s_initialized) //Suit gear . += "Energy Charge: [round(SN.cell.charge/100)]%" - . += "Smoke Bombs: \Roman [SN.s_bombs]" //Ninja status . += "Fingerprints: [md5(dna.uni_identity)]" . += "Unique Identity: [dna.unique_enzymes]" @@ -110,107 +111,6 @@ var/datum/disease/D = thing . += "* [D.name], Type: [D.spread_text], Stage: [D.stage]/[D.max_stages], Possible Cure: [D.cure_text]" - -/mob/living/carbon/human/show_inv(mob/user) - user.set_machine(src) - var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask) - var/list/obscured = check_obscured_slots() - var/list/dat = list() - - dat += "" - for(var/i in 1 to held_items.len) - var/obj/item/I = get_item_for_held_index(i) - dat += "" - dat += "" - - dat += "" - - dat += "" - - if(SLOT_WEAR_MASK in obscured) - dat += "" - else - dat += "" - - if(SLOT_NECK in obscured) - dat += "" - else - dat += "" - - if(SLOT_GLASSES in obscured) - dat += "" - else - dat += "" - - if(SLOT_EARS in obscured) - dat += "" - else - dat += "" - - dat += "" - - dat += "" - dat += "" - else - dat += "" - - if(SLOT_SHOES in obscured) - dat += "" - else - dat += "" - - if(SLOT_GLOVES in obscured) - dat += "" - else - dat += "" - - if(SLOT_W_UNIFORM in obscured) - dat += "" - else - dat += "" - - if((w_uniform == null && !(dna && dna.species.nojumpsuit)) || (SLOT_W_UNIFORM in obscured)) - dat += "" - dat += "" - dat += "" - else - dat += "" - dat += "" - dat += "" - - if(handcuffed) - dat += "" - if(legcuffed) - dat += "" - - dat += {"
    [get_held_index_name(i)]:[(I && !(I.item_flags & ABSTRACT)) ? I : "Empty"]
     
    Back:[(back && !(back.item_flags & ABSTRACT)) ? back : "Empty"]" - if(has_breathable_mask && istype(back, /obj/item/tank)) - dat += " [internal ? "Disable Internals" : "Set Internals"]" - - dat += "
     
    Head:[(head && !(head.item_flags & ABSTRACT)) ? head : "Empty"]
    Mask:Obscured
    Mask:[(wear_mask && !(wear_mask.item_flags & ABSTRACT)) ? wear_mask : "Empty"]
    Neck:Obscured
    Neck:[(wear_neck && !(wear_neck.item_flags & ABSTRACT)) ? wear_neck : "Empty"]
    Eyes:Obscured
    Eyes:[(glasses && !(glasses.item_flags & ABSTRACT)) ? glasses : "Empty"]
    Ears:Obscured
    Ears:[(ears && !(ears.item_flags & ABSTRACT)) ? ears : "Empty"]
     
    Exosuit:[(wear_suit && !(wear_suit.item_flags & ABSTRACT)) ? wear_suit : "Empty"]" - if(wear_suit) - if(istype(wear_suit, /obj/item/clothing/suit/space/hardsuit)) - var/hardsuit_head = head && istype(head, /obj/item/clothing/head/helmet/space/hardsuit) - dat += " [hardsuit_head ? "Retract Helmet" : "Extend Helmet"]" - dat += "
     ↳Suit Storage:[(s_store && !(s_store.item_flags & ABSTRACT)) ? s_store : "Empty"]" - if(has_breathable_mask && istype(s_store, /obj/item/tank)) - dat += " [internal ? "Disable Internals" : "Set Internals"]" - dat += "
     ↳Suit Storage:
    Shoes:Obscured
    Shoes:[(shoes && !(shoes.item_flags & ABSTRACT)) ? shoes : "Empty"]" - if(shoes && shoes.can_be_tied && shoes.tied != SHOES_KNOTTED) - dat += " [shoes.tied ? "Untie shoes" : "Knot shoes"]" - - dat += "
    Gloves:Obscured
    Gloves:[(gloves && !(gloves.item_flags & ABSTRACT)) ? gloves : "Empty"]
    Uniform:Obscured
    Uniform:[(w_uniform && !(w_uniform.item_flags & ABSTRACT)) ? w_uniform : "Empty"]
     ↳Pockets:
     ↳ID:
     ↳Belt:
     ↳Belt:[(belt && !(belt.item_flags & ABSTRACT)) ? belt : "Empty"]" - if(has_breathable_mask && istype(belt, /obj/item/tank)) - dat += " [internal ? "Disable Internals" : "Set Internals"]" - dat += "
     ↳Pockets:[(l_store && !(l_store.item_flags & ABSTRACT)) ? "Left (Full)" : "Left (Empty)"]" - dat += " [(r_store && !(r_store.item_flags & ABSTRACT)) ? "Right (Full)" : "Right (Empty)"]
     ↳ID:[(wear_id && !(wear_id.item_flags & ABSTRACT)) ? wear_id : "Empty"]
    Handcuffed: Remove
    Legcuffed
    - Close - "} - - var/datum/browser/popup = new(user, "mob[REF(src)]", "[src]", 440, 510) - popup.set_content(dat.Join()) - popup.open() - // called when something steps onto a human // this could be made more general, but for now just handle mulebot /mob/living/carbon/human/Crossed(atom/movable/AM) @@ -232,83 +132,6 @@ return SEND_SIGNAL(src, COMSIG_CARBON_EMBED_RIP, I, L) return - if(href_list["toggle_helmet"]) - if(!istype(head, /obj/item/clothing/head/helmet/space/hardsuit)) - return - var/obj/item/clothing/head/helmet/space/hardsuit/hardsuit_head = head - visible_message("[usr] tries to [hardsuit_head ? "retract" : "extend"] [src]'s helmet.", \ - "[usr] tries to [hardsuit_head ? "retract" : "extend"] [src]'s helmet.", \ - target = usr, target_message = "You try to [hardsuit_head ? "retract" : "extend"] [src]'s helmet.") - if(!do_mob(usr, src, hardsuit_head ? head.strip_delay : POCKET_STRIP_DELAY)) - return - if(!istype(wear_suit, /obj/item/clothing/suit/space/hardsuit) || (hardsuit_head ? (!head || head != hardsuit_head) : head)) - return - var/obj/item/clothing/suit/space/hardsuit/hardsuit = wear_suit //This should be an hardsuit given all our checks - if(hardsuit.ToggleHelmet(FALSE)) - visible_message("[usr] [hardsuit_head ? "retract" : "extend"] [src]'s helmet", \ - "[usr] [hardsuit_head ? "retract" : "extend"] [src]'s helmet", \ - target = usr, target_message = "You [hardsuit_head ? "retract" : "extend"] [src]'s helmet.") - return - if(href_list["item"]) - var/slot = text2num(href_list["item"]) - if(slot in check_obscured_slots()) - to_chat(usr, "You can't reach that! Something is covering it.") - return - if(href_list["pockets"]) - var/strip_mod = 1 - var/strip_silence = FALSE - var/obj/item/clothing/gloves/G = gloves - if(istype(G)) - strip_mod = G.strip_mod - strip_silence = G.strip_silence - var/pocket_side = href_list["pockets"] - var/pocket_id = (pocket_side == "right" ? SLOT_R_STORE : SLOT_L_STORE) - var/obj/item/pocket_item = (pocket_id == SLOT_R_STORE ? r_store : l_store) - var/obj/item/place_item = usr.get_active_held_item() // Item to place in the pocket, if it's empty - - var/delay_denominator = 1 - if(pocket_item && !(pocket_item.item_flags & ABSTRACT)) - if(HAS_TRAIT(pocket_item, TRAIT_NODROP)) - to_chat(usr, "You try to empty [src]'s [pocket_side] pocket, it seems to be stuck!") - to_chat(usr, "You try to empty [src]'s [pocket_side] pocket.") - else if(place_item && place_item.mob_can_equip(src, usr, pocket_id, 1) && !(place_item.item_flags & ABSTRACT)) - to_chat(usr, "You try to place [place_item] into [src]'s [pocket_side] pocket.") - delay_denominator = 4 - else - return - - if(do_mob(usr, src, max(round(POCKET_STRIP_DELAY/(delay_denominator*strip_mod)),1), ignorehelditem = TRUE)) //placing an item into the pocket is 4 times faster (and the strip_mod too) - if(pocket_item) - if(pocket_item == (pocket_id == SLOT_R_STORE ? r_store : l_store)) //item still in the pocket we search - dropItemToGround(pocket_item) - if(!usr.can_hold_items() || !usr.put_in_hands(pocket_item)) - pocket_item.forceMove(drop_location()) - log_combat(usr, src, "pickpocketed of item: [pocket_item]") - else - if(place_item) - if(place_item.mob_can_equip(src, usr, pocket_id, FALSE, TRUE)) - usr.temporarilyRemoveItemFromInventory(place_item, TRUE) - equip_to_slot(place_item, pocket_id, TRUE) - log_combat(usr, src, "placed item [place_item] onto") - //do nothing otherwise - - // Update strip window - if(usr.machine == src && in_range(src, usr)) - show_inv(usr) - else - // Display a warning if the user mocks up - if(!strip_silence) - to_chat(src, "You feel your [pocket_side] pocket being fumbled with!") - log_combat(usr, src, "failed to [pocket_item ? "pickpocket item [pocket_item] from" : "place item [place_item] onto "]") - - if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY, null, FALSE)) - // separate from first canusetopic - var/mob/living/user = usr - if(istype(user) && href_list["shoes"] && (user.mobility_flags & MOBILITY_USE)) // we need to be on the ground, so we'll be a bit looser - shoes.handle_tying(usr) - - ..() //CITADEL CHANGE - removes a tab from behind this ..() so that flavortext can actually be examined - ///////HUDs/////// if(href_list["hud"]) @@ -549,11 +372,11 @@ . = ..() if(wear_suit) if(wear_suit.flags_inv & HIDEGLOVES) - LAZYOR(., SLOT_GLOVES) + LAZYOR(., ITEM_SLOT_GLOVES) if(wear_suit.flags_inv & HIDEJUMPSUIT) - LAZYOR(., SLOT_W_UNIFORM) + LAZYOR(., ITEM_SLOT_ICLOTHING) if(wear_suit.flags_inv & HIDESHOES) - LAZYOR(., SLOT_SHOES) + LAZYOR(., ITEM_SLOT_FEET) /mob/living/carbon/human/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) if(judgement_criteria & JUDGE_EMAGGED) @@ -959,7 +782,7 @@ //src is the user that will be carrying, target is the mob to be carried /mob/living/carbon/human/proc/can_piggyback(mob/living/target) - return (iscarbon(target) || ispAI(target)) && target.stat == CONSCIOUS + return (iscarbon(target) || ispAI(target)) && target.stat == CONSCIOUS && CHECK_MOBILITY(src, MOBILITY_STAND) /mob/living/carbon/human/proc/can_be_firemanned(mob/living/carbon/target) return (ishuman(target) && !CHECK_MOBILITY(target, MOBILITY_STAND)) || ispAI(target) @@ -978,7 +801,7 @@ //Joe Medic starts quickly/expertly lifting Grey Tider onto their back.. "[carrydelay < 35 ? "Using your gloves' nanochips, you" : "You"] [skills_space]start to lift [target] onto your back[carrydelay == 40 ? ", while assisted by the nanochips in your gloves.." : "..."]") //(Using your gloves' nanochips, you/You) ( /quickly/expertly) start to lift Grey Tider onto your back(, while assisted by the nanochips in your gloves../...) - if(do_after(src, carrydelay, TRUE, target)) + if(do_after(src, carrydelay, target, extra_checks = CALLBACK(src, PROC_REF(can_be_firemanned), target))) //Second check to make sure they're still valid to be carried if(can_be_firemanned(target) && !incapacitated(FALSE, TRUE)) buckle_mob(target, TRUE, TRUE, 90, 1, 0, TRUE) @@ -993,7 +816,7 @@ /mob/living/carbon/human/proc/piggyback(mob/living/carbon/target) if(can_piggyback(target)) visible_message("[target] starts to climb onto [src]...") - if(do_after(target, 15, target = src, required_mobility_flags = MOBILITY_STAND)) + if(do_after(target, 1.5 SECONDS, src, IGNORE_INCAPACITATED, extra_checks = CALLBACK(src, PROC_REF(can_piggyback), target))) if(can_piggyback(target)) if(target.incapacitated(FALSE, TRUE) || incapacitated(FALSE, TRUE)) target.visible_message("[target] can't hang onto [src]!") @@ -1056,10 +879,10 @@ return if(!HAS_TRAIT(src, TRAIT_IGNOREDAMAGESLOWDOWN)) //if we want to ignore slowdown from damage, but not from equipment var/scaling = maxHealth / 100 - var/health_deficiency = max(((maxHealth / scaling) - (health / scaling)), (getStaminaLoss()*0.75)) + var/health_deficiency = max(((maxHealth / scaling) - (health / scaling)), max(0, getStaminaLoss() - 39)) if(health_deficiency >= 40) - add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown, TRUE, (health_deficiency - 15) / 75) - add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying, TRUE, (health_deficiency - 15) / 25) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown, TRUE, health_deficiency / 75) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying, TRUE, health_deficiency / 25) else remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown) remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying) @@ -1080,7 +903,7 @@ /mob/living/carbon/human/species var/race = null -/mob/living/carbon/human/species/Initialize() +/mob/living/carbon/human/species/Initialize(mapload) . = ..() set_species(race) @@ -1119,21 +942,18 @@ . += "[t_He] [t_is] a [spec_trait_examine_font()][dna.custom_species ? dna.custom_species : dna.species.name]
    " SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, usr, .) +/mob/living/carbon/human/chestonly + bodyparts = list(/obj/item/bodypart/chest) + /mob/living/carbon/human/species/abductor race = /datum/species/abductor /mob/living/carbon/human/species/android race = /datum/species/android -/mob/living/carbon/human/species/angel - race = /datum/species/angel - /mob/living/carbon/human/species/corporate race = /datum/species/corporate -/mob/living/carbon/human/species/dullahan - race = /datum/species/dullahan - /mob/living/carbon/human/species/felinid race = /datum/species/human/felinid diff --git a/code/modules/mob/living/carbon/human/human_context.dm b/code/modules/mob/living/carbon/human/human_context.dm new file mode 100644 index 0000000000..5229fba3ea --- /dev/null +++ b/code/modules/mob/living/carbon/human/human_context.dm @@ -0,0 +1,36 @@ +/mob/living/carbon/human/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + + if (!ishuman(user)) + return . + + var/aim_for_mouth = user.zone_selected == "mouth" + var/target_on_help = a_intent == INTENT_HELP + var/target_aiming_for_mouth = zone_selected == "mouth" + var/target_restrained = restrained() + var/same_dir = (dir & user.dir) + var/aim_for_groin = user.zone_selected == "groin" + var/target_aiming_for_groin = zone_selected == "groin" + + if(aim_for_mouth && (target_on_help || target_restrained || target_aiming_for_mouth)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_DISARM, "Slap face") + + else if(aim_for_groin && (src == user || lying || same_dir) && (target_on_help || target_restrained || target_aiming_for_groin)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_DISARM, "Slap ass") + + // Humans can actually be upgrade grabbed using ctrl-click + if(src != user) + if (pulledby == user) + switch (user.grab_state) + if (GRAB_PASSIVE) + LAZYSET(context[SCREENTIP_CONTEXT_CTRL_LMB], INTENT_ANY, "Grip") + if (GRAB_AGGRESSIVE) + LAZYSET(context[SCREENTIP_CONTEXT_CTRL_LMB], INTENT_ANY, "Choke") + if (GRAB_NECK) + LAZYSET(context[SCREENTIP_CONTEXT_CTRL_LMB], INTENT_ANY, "Strangle") + else + return . + else + LAZYSET(context[SCREENTIP_CONTEXT_CTRL_LMB], INTENT_ANY, "Pull") + + return CONTEXTUAL_SCREENTIP_SET diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 1174fcba70..5941efe087 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -53,7 +53,7 @@ dna.species.on_hit(P, src) -/mob/living/carbon/human/bullet_act(obj/item/projectile/P, def_zone) +/mob/living/carbon/human/bullet_act(obj/item/projectile/P, def_zone, piercing_hit = FALSE) if(dna && dna.species) var/spec_return = dna.species.bullet_act(P, src) if(spec_return) @@ -61,7 +61,7 @@ if(mind) //martial art stuff if(mind.martial_art && mind.martial_art.can_use(src)) //Some martial arts users can deflect projectiles! - var/martial_art_result = mind.martial_art.on_projectile_hit(src, P, def_zone) + var/martial_art_result = mind.martial_art.on_projectile_hit(src, P, def_zone, piercing_hit) if(!(martial_art_result == BULLET_ACT_HIT)) return martial_art_result return ..() @@ -163,7 +163,7 @@ if(can_inject(M, 1, affecting))//Thick suits can stop monkey bites. if(..()) //successful monkey bite, this handles disease contraction. var/damage = rand(1, 3) - apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee")) + apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, MELEE)) return 1 /mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M) @@ -183,7 +183,7 @@ var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) - var/armor_block = run_armor_check(affecting, "melee", null, null,10) + var/armor_block = run_armor_check(affecting, MELEE, null, null,10) playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) visible_message("[M] has slashed at [src]!", \ @@ -219,7 +219,7 @@ var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected)) if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) - var/armor_block = run_armor_check(affecting, "melee") + var/armor_block = run_armor_check(affecting, MELEE) apply_damage(damage, BRUTE, affecting, armor_block) @@ -233,7 +233,7 @@ var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) - var/armor = run_armor_check(affecting, "melee", armour_penetration = M.armour_penetration) + var/armor = run_armor_check(affecting, MELEE, armour_penetration = M.armour_penetration) apply_damage(damage, M.melee_damage_type, affecting, armor, wound_bonus = M.wound_bonus, bare_wound_bonus = M.bare_wound_bonus, sharpness = M.sharpness) /mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M) @@ -253,51 +253,9 @@ var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) - var/armor_block = run_armor_check(affecting, "melee") + var/armor_block = run_armor_check(affecting, MELEE) apply_damage(damage, BRUTE, affecting, armor_block, wound_bonus=wound_mod) -/mob/living/carbon/human/mech_melee_attack(obj/mecha/M) - if(M.occupant.a_intent == INTENT_HARM) - if(HAS_TRAIT(M.occupant, TRAIT_PACIFISM)) - to_chat(M.occupant, "You don't want to harm other living beings!") - return - M.do_attack_animation(src) - if(M.damtype == "brute") - step_away(src,M,15) - var/obj/item/bodypart/temp = get_bodypart(pick(BODY_ZONE_CHEST, BODY_ZONE_CHEST, BODY_ZONE_CHEST, BODY_ZONE_HEAD)) - if(temp) - var/update = 0 - var/dmg = rand(M.force/2, M.force) - var/atom/throw_target = get_edge_target_turf(src, M.dir) - switch(M.damtype) - if("brute") - if(M.force > 35) // durand and other heavy mechas - DefaultCombatKnockdown(50) - src.throw_at(throw_target, rand(1,5), 7) - else if(M.force >= 20 && CHECK_MOBILITY(src, MOBILITY_STAND)) // lightweight mechas like gygax - DefaultCombatKnockdown(30) - src.throw_at(throw_target, rand(1,3), 7) - update |= temp.receive_damage(dmg, 0) - playsound(src, 'sound/weapons/punch4.ogg', 50, 1) - if("fire") - update |= temp.receive_damage(0, dmg) - playsound(src, 'sound/items/welder.ogg', 50, 1) - if("tox") - M.mech_toxin_damage(src) - else - return - if(update) - update_damage_overlays() - updatehealth() - - visible_message("[M.name] has hit [src]!", \ - "[M.name] has hit you!", null, COMBAT_MESSAGE_RANGE, target = M, - target_message = "You have hit [src]!") - log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") - - else - ..() - /mob/living/carbon/human/ex_act(severity, target, origin) if(TRAIT_BOMBIMMUNE in dna.species.species_traits) @@ -307,7 +265,7 @@ return var/brute_loss = 0 var/burn_loss = 0 - var/bomb_armor = getarmor(null, "bomb") + var/bomb_armor = getarmor(null, BOMB) //200 max knockdown for EXPLODE_HEAVY //160 max knockdown for EXPLODE_LIGHT @@ -319,13 +277,16 @@ var/atom/A = I if(!QDELETED(A)) A.ex_act(severity) - gib() + if(istype(origin, /datum/explosion)) + gib(was_explosion = origin) + else + gib() return else brute_loss = 500 var/atom/throw_target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src))) throw_at(throw_target, 200, 4) - damage_clothes(400 - bomb_armor, BRUTE, "bomb") + damage_clothes(400 - bomb_armor, BRUTE, BOMB) if (EXPLODE_HEAVY) brute_loss = 60 @@ -333,7 +294,7 @@ if(bomb_armor) brute_loss = 30*(2 - round(bomb_armor*0.01, 0.05)) burn_loss = brute_loss //damage gets reduced from 120 to up to 60 combined brute+burn - damage_clothes(200 - bomb_armor, BRUTE, "bomb") + damage_clothes(200 - bomb_armor, BRUTE, BOMB) if (!istype(ears, /obj/item/clothing/ears/earmuffs)) adjustEarDamage(30, 120) Unconscious(20) //short amount of time for follow up attacks against elusive enemies like wizards @@ -344,7 +305,7 @@ brute_loss = 30 if(bomb_armor) brute_loss = 15*(2 - round(bomb_armor*0.01, 0.05)) - damage_clothes(max(50 - bomb_armor, 0), BRUTE, "bomb") + damage_clothes(max(50 - bomb_armor, 0), BRUTE, BOMB) if (!istype(ears, /obj/item/clothing/ears/earmuffs)) adjustEarDamage(15,60) Knockdown((160 - (bomb_armor * 1.6)) / 4) //100 bomb armor will prevent knockdown altogether @@ -357,7 +318,7 @@ var/max_limb_loss = round(4/severity) //so you don't lose four limbs at severity 3. for(var/X in bodyparts) var/obj/item/bodypart/BP = X - if(prob(50/severity) && !prob(getarmor(BP, "bomb")) && BP.body_zone != BODY_ZONE_HEAD && BP.body_zone != BODY_ZONE_CHEST) + if(prob(50/severity) && !prob(getarmor(BP, BOMB)) && BP.body_zone != BODY_ZONE_HEAD && BP.body_zone != BODY_ZONE_CHEST) BP.brute_dam = BP.max_damage BP.dismember() max_limb_loss-- @@ -371,7 +332,7 @@ show_message("The blob attacks you!") var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) - apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee")) + apply_damage(5, BRUTE, affecting, run_armor_check(affecting, MELEE)) ///Calculates the siemens coeff based on clothing and species, can also restart hearts. @@ -413,6 +374,7 @@ severity *= 0.5 var/do_not_stun = FALSE if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) + hud_used?.coolant_display.jam(round(severity / 10, 1)) //Messes up the cooling system readout. severity *= 0.5 //Robotpeople take less limb damage, but instead suffer system corruption (see carbon emp_act) do_not_stun = TRUE for(var/obj/item/bodypart/L in src.bodyparts) @@ -584,11 +546,11 @@ if(src == M) if(has_status_effect(STATUS_EFFECT_CHOKINGSTRAND)) to_chat(src, "You attempt to remove the durathread strand from around your neck.") - if(do_after(src, 35, null, src)) + if(do_after(src, 3.5 SECONDS, src)) to_chat(src, "You succesfuly remove the durathread strand.") remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND) return - var/to_send = "" + var/to_send = "
    " visible_message("[src] examines [p_them()]self.", \ "You check yourself for injuries.") @@ -635,27 +597,27 @@ var/no_damage if(status == "OK" || status == "no damage") no_damage = TRUE - to_send += "\t Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].\n" + to_send += "Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].\n" for(var/thing in LB.wounds) var/datum/wound/W = thing var/msg switch(W.severity) if(WOUND_SEVERITY_TRIVIAL) - msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]." + msg = "Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]." if(WOUND_SEVERITY_MODERATE) - msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" + msg = "Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" if(WOUND_SEVERITY_SEVERE) - msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" + msg = "Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!" if(WOUND_SEVERITY_CRITICAL) - msg = "\t Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!!" + msg = "Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!!" to_chat(src, msg) for(var/obj/item/I in LB.embedded_objects) if(I.isEmbedHarmless()) - to_chat(src, "\t There is \a [I] stuck to your [LB.name]!") + to_chat(src, "There is \a [I] stuck to your [LB.name]!") else - to_chat(src, "\t There is \a [I] embedded in your [LB.name]!") + to_chat(src, "There is \a [I] embedded in your [LB.name]!") for(var/t in missing) to_send += "Your [parse_zone(t)] is missing!\n" @@ -762,6 +724,8 @@ if(roundstart_quirks.len) to_send += "You have these quirks: [get_trait_string()].\n" + to_send += "
    " + to_chat(src, to_send) else if(wear_suit) @@ -853,7 +817,7 @@ to_chat(src, "\t There is \a [I] stuck to your [LB.name]!") else to_chat(src, "\t There is \a [I] embedded in your [LB.name]!") - + /mob/living/carbon/human/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone) if(damage_type != BRUTE && damage_type != BURN) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index de934318b3..6723d2d4a6 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -20,6 +20,11 @@ var/hair_color = "000" var/hair_style = "Bald" + ///Colour used for the hair gradient. + var/grad_color = "000" + ///Style used for the hair gradient. + var/grad_style + //Facial hair colour and style var/facial_hair_color = "000" var/facial_hair_style = "Shaved" @@ -81,6 +86,8 @@ tooltips = TRUE + var/additional_language //the additional language this human can speak from their preference selection + /// Unarmed parry data for human /datum/block_parry_data/unarmed/human parry_respect_clickdelay = TRUE diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 2e530226c8..2c58da29c9 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -115,25 +115,24 @@ . = ..() if(!.) return - if(HAS_TRAIT(src, TRAIT_NOGUNS)) - to_chat(src, "You can't bring yourself to use a ranged weapon!") - return FALSE if(G.trigger_guard == TRIGGER_GUARD_NORMAL) if(HAS_TRAIT(src, TRAIT_CHUNKYFINGERS)) - to_chat(src, "Your meaty finger is much too large for the trigger guard!") + balloon_alert(src, "fingers are too big!") return FALSE + if(HAS_TRAIT(src, TRAIT_NOGUNS)) + to_chat(src, span_warning("You can't bring yourself to use a ranged weapon!")) + return FALSE -/mob/living/carbon/human/proc/get_bank_account() +//Returns the bank account of an ID the user may be holding. +/mob/living/proc/get_bank_account() RETURN_TYPE(/datum/bank_account) var/datum/bank_account/account var/obj/item/card/id/I = get_idcard() - if(I && I.registered_account) + if(I?.registered_account) account = I.registered_account return account - return FALSE - /mob/living/carbon/human/can_see_reagents() . = ..() if(.) //No need to run through all of this if it's already true. diff --git a/code/modules/mob/living/carbon/human/human_mobility.dm b/code/modules/mob/living/carbon/human/human_mobility.dm index dc498c4153..1e69dc00f3 100644 --- a/code/modules/mob/living/carbon/human/human_mobility.dm +++ b/code/modules/mob/living/carbon/human/human_mobility.dm @@ -35,7 +35,7 @@ standupwarning = "[src] struggles to stand up." var/usernotice = automatic ? "You are now getting up. (Auto)" : "You are now getting up." visible_message("[standupwarning]", usernotice, vision_distance = 5) - if(do_after(src, totaldelay, target = src, required_mobility_flags = MOBILITY_RESIST)) + if(do_after(src, totaldelay, target = src, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM|IGNORE_INCAPACITATED), extra_checks = CALLBACK(src, PROC_REF(cuff_resist_check)))) set_resting(FALSE, TRUE) combat_flags &= ~COMBAT_FLAG_RESISTING_REST diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 54d6771c6c..141fbb89d7 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -85,6 +85,7 @@ FP.blood_DNA["color"] = S.last_blood_color else FP.blood_DNA["color"] = BlendRGB(FP.blood_DNA["color"], S.last_blood_color) + FP.blood_DNA["blendmode"] = S.last_blood_blend FP.update_icon() update_inv_shoes() //End bloody footprints diff --git a/code/modules/mob/living/carbon/human/human_stripping.dm b/code/modules/mob/living/carbon/human/human_stripping.dm new file mode 100644 index 0000000000..08db3fe552 --- /dev/null +++ b/code/modules/mob/living/carbon/human/human_stripping.dm @@ -0,0 +1,306 @@ +#define INTERNALS_TOGGLE_DELAY (4 SECONDS) +#define POCKET_EQUIP_DELAY (1 SECONDS) + +GLOBAL_LIST_INIT(strippable_human_items, create_strippable_list(list( + /datum/strippable_item/mob_item_slot/head, + /datum/strippable_item/mob_item_slot/back, + /datum/strippable_item/mob_item_slot/mask, + /datum/strippable_item/mob_item_slot/neck, + /datum/strippable_item/mob_item_slot/eyes, + /datum/strippable_item/mob_item_slot/ears, + /datum/strippable_item/mob_item_slot/jumpsuit, + /datum/strippable_item/mob_item_slot/suit, + /datum/strippable_item/mob_item_slot/gloves, + /datum/strippable_item/mob_item_slot/feet, + /datum/strippable_item/mob_item_slot/suit_storage, + /datum/strippable_item/mob_item_slot/id, + /datum/strippable_item/mob_item_slot/belt, + /datum/strippable_item/mob_item_slot/pocket/left, + /datum/strippable_item/mob_item_slot/pocket/right, + /datum/strippable_item/hand/left, + /datum/strippable_item/hand/right, + /datum/strippable_item/mob_item_slot/handcuffs, + /datum/strippable_item/mob_item_slot/legcuffs, +))) + +/mob/living/carbon/human/proc/should_strip(mob/user) + if (user.pulling != src || user.grab_state != GRAB_AGGRESSIVE) + return TRUE + + if (ishuman(user)) + var/mob/living/carbon/human/human_user = user + return !human_user.can_be_firemanned(src) + + return TRUE + +/datum/strippable_item/mob_item_slot/eyes + key = STRIPPABLE_ITEM_EYES + item_slot = ITEM_SLOT_EYES + +/datum/strippable_item/mob_item_slot/ears + key = STRIPPABLE_ITEM_EARS + item_slot = ITEM_SLOT_EARS + +/datum/strippable_item/mob_item_slot/jumpsuit + key = STRIPPABLE_ITEM_JUMPSUIT + item_slot = ITEM_SLOT_ICLOTHING + +/datum/strippable_item/mob_item_slot/jumpsuit/get_alternate_action(atom/source, mob/user) + if(..() == FALSE) + return null + var/obj/item/clothing/under/jumpsuit = get_item(source) + if (!istype(jumpsuit)) + return null + return jumpsuit?.can_adjust ? "adjust_jumpsuit" : null + +/datum/strippable_item/mob_item_slot/jumpsuit/alternate_action(atom/source, mob/user) + if (!..()) + return null + var/obj/item/clothing/under/jumpsuit = get_item(source) + if (!istype(jumpsuit)) + return null + to_chat(source, "[user] is trying to adjust your [jumpsuit.name].") + if (!do_mob(user, source, jumpsuit.strip_delay * 0.5, timed_action_flags = IGNORE_HELD_ITEM)) + return + to_chat(source, "[user] successfully adjusted your [jumpsuit.name].") + jumpsuit.toggle_jumpsuit_adjust() + + if (!ismob(source)) + return null + + var/mob/mob_source = source + mob_source.update_inv_w_uniform() + mob_source.update_body() + return TRUE + +/datum/strippable_item/mob_item_slot/suit + key = STRIPPABLE_ITEM_SUIT + item_slot = ITEM_SLOT_OCLOTHING + +/datum/strippable_item/mob_item_slot/suit/get_alternate_action(atom/source, mob/user) + if(..() == FALSE) + return null + var/obj/item/clothing/suit/space/hardsuit/suit = get_item(source) + if(istype(suit)) + if(!suit.helmettype) + return null + return suit?.suittoggled ? "disable_helmet" : "enable_helmet" + return null + +/datum/strippable_item/mob_item_slot/suit/alternate_action(mob/living/carbon/human/source, mob/user) + if(!..()) + return null + if(ishuman(source)) + var/obj/item/clothing/suit/space/hardsuit/hardsuit = get_item(source) + var/obj/item/clothing/head/helmet/space/hardsuit/hardsuit_head = hardsuit.helmet + source.visible_message("[user] tries to [hardsuit.suittoggled ? "retract" : "extend"] [source]'s helmet.", \ + "[user] tries to [hardsuit.suittoggled ? "retract" : "extend"] [source]'s helmet.", \ + target = user, target_message = "You try to [hardsuit.suittoggled ? "retract" : "extend"] [source]'s helmet.") + if(!do_mob(user, source, hardsuit_head ? hardsuit_head.strip_delay : POCKET_STRIP_DELAY, timed_action_flags = IGNORE_HELD_ITEM)) + return null + if((source.head != hardsuit_head) && source.head) + return null + if(hardsuit.ToggleHelmet(FALSE)) + source.visible_message("[user] [hardsuit_head ? "retract" : "extend"] [source]'s helmet", \ + "[user] [hardsuit_head ? "retract" : "extend"] [source]'s helmet", \ + target = user, target_message = "You [hardsuit_head ? "retract" : "extend"] [source]'s helmet.") + return TRUE + +/datum/strippable_item/mob_item_slot/gloves + key = STRIPPABLE_ITEM_GLOVES + item_slot = ITEM_SLOT_GLOVES + +/datum/strippable_item/mob_item_slot/feet + key = STRIPPABLE_ITEM_FEET + item_slot = ITEM_SLOT_FEET + +/datum/strippable_item/mob_item_slot/feet/get_alternate_action(atom/source, mob/user) + if(..() == FALSE) + return null + var/obj/item/clothing/shoes/shoes = get_item(source) + if (!istype(shoes) || !shoes.can_be_tied) + return null + + switch (shoes.tied) + if (SHOES_UNTIED) + return "knot" + if (SHOES_TIED) + return "untie" + if (SHOES_KNOTTED) + return "unknot" + +/datum/strippable_item/mob_item_slot/feet/alternate_action(atom/source, mob/user) + if(!..()) + return null + var/obj/item/clothing/shoes/shoes = get_item(source) + if (!istype(shoes)) + return null + + shoes.handle_tying(user) + return TRUE + +/datum/strippable_item/mob_item_slot/suit_storage + key = STRIPPABLE_ITEM_SUIT_STORAGE + item_slot = ITEM_SLOT_SUITSTORE + +/datum/strippable_item/mob_item_slot/suit_storage/get_alternate_action(atom/source, mob/user) + if(..() == FALSE) + return null + return get_strippable_alternate_action_internals(get_item(source), source) + +/datum/strippable_item/mob_item_slot/suit_storage/alternate_action(atom/source, mob/user) + if (!..()) + return null + return strippable_alternate_action_internals(get_item(source), source, user) + +/datum/strippable_item/mob_item_slot/id + key = STRIPPABLE_ITEM_ID + item_slot = ITEM_SLOT_ID + +/datum/strippable_item/mob_item_slot/belt + key = STRIPPABLE_ITEM_BELT + item_slot = ITEM_SLOT_BELT + +/datum/strippable_item/mob_item_slot/belt/get_alternate_action(atom/source, mob/user) + if(..() == FALSE) + return null + return get_strippable_alternate_action_internals(get_item(source), source) + +/datum/strippable_item/mob_item_slot/belt/alternate_action(atom/source, mob/user) + if (!..()) + return null + return strippable_alternate_action_internals(get_item(source), source, user) + +/datum/strippable_item/mob_item_slot/pocket + /// Which pocket we're referencing. Used for visible text. + var/pocket_side + +/datum/strippable_item/mob_item_slot/pocket/get_obscuring(atom/source) + return isnull(get_item(source)) \ + ? STRIPPABLE_OBSCURING_NONE \ + : STRIPPABLE_OBSCURING_HIDDEN + +/datum/strippable_item/mob_item_slot/pocket/get_equip_delay(obj/item/equipping) + return POCKET_EQUIP_DELAY + +/datum/strippable_item/mob_item_slot/pocket/start_equip(atom/source, obj/item/equipping, mob/user) + . = ..() + if (!.) + warn_owner(source) + +/datum/strippable_item/mob_item_slot/pocket/start_unequip(atom/source, mob/user) + var/obj/item/item = get_item(source) + if (isnull(item)) + return FALSE + + to_chat(user, span_notice("You try to empty [source]'s [pocket_side] pocket.")) + + var/log_message = "[key_name(source)] is being pickpocketed of [item] by [key_name(user)] ([pocket_side])" + user.log_message(log_message, LOG_ATTACK, color="red") + source.log_message(log_message, LOG_VICTIM, color="red", log_globally=FALSE) + item.add_fingerprint(source) + + var/result = start_unequip_mob(item, source, user, POCKET_STRIP_DELAY) + + if (!result) + warn_owner(source) + + return result + +/datum/strippable_item/mob_item_slot/pocket/proc/warn_owner(atom/owner) + to_chat(owner, span_warning("You feel your [pocket_side] pocket being fumbled with!")) + +/datum/strippable_item/mob_item_slot/pocket/left + key = STRIPPABLE_ITEM_LPOCKET + item_slot = ITEM_SLOT_LPOCKET + pocket_side = "left" + +/datum/strippable_item/mob_item_slot/pocket/right + key = STRIPPABLE_ITEM_RPOCKET + item_slot = ITEM_SLOT_RPOCKET + pocket_side = "right" + +/proc/get_strippable_alternate_action_internals(obj/item/item, atom/source) + if (!iscarbon(source)) + return null + + var/mob/living/carbon/carbon_source = source + var/obj/item/clothing/mask + var/internals = FALSE + + for(mask in GET_INTERNAL_SLOTS(carbon_source)) + if(istype(mask, /obj/item/clothing/mask)) + var/obj/item/clothing/mask/M = mask + if(M.mask_adjusted) + if(M.adjustmask(carbon_source)) + internals = TRUE + else + internals = TRUE + if((mask.clothing_flags & ALLOWINTERNALS)) + internals = TRUE + + if(carbon_source.getorganslot(ORGAN_SLOT_BREATHING_TUBE)) + internals = TRUE + + if (internals && istype(item, /obj/item/tank)) + return isnull(carbon_source.internal) ? "enable_internals" : "disable_internals" + +/proc/strippable_alternate_action_internals(obj/item/item, atom/source, mob/user) + var/obj/item/tank/tank = item + if (!istype(tank)) + return null + + var/mob/living/carbon/carbon_source = source + if (!istype(carbon_source)) + return null + + var/obj/item/clothing/mask + var/internals = FALSE + + for(mask in GET_INTERNAL_SLOTS(carbon_source)) + if(istype(mask, /obj/item/clothing/mask)) + var/obj/item/clothing/mask/M = mask + if(M.mask_adjusted) + if(M.adjustmask(carbon_source)) + internals = TRUE + else + internals = TRUE + if((mask.clothing_flags & ALLOWINTERNALS)) + internals = TRUE + + if(!internals) + return null + + carbon_source.visible_message( + span_danger("[user] tries to [isnull(carbon_source.internal) ? "open": "close"] the valve on [source]'s [item.name]."), + span_userdanger("[user] tries to [isnull(carbon_source.internal) ? "open": "close"] the valve on your [item.name]."), + ignored_mobs = user, + ) + + to_chat(user, span_notice("You try to [isnull(carbon_source.internal) ? "open": "close"] the valve on [source]'s [item.name]...")) + + if(!do_mob(user, carbon_source, INTERNALS_TOGGLE_DELAY, timed_action_flags = IGNORE_HELD_ITEM)) + return null + + if(carbon_source.internal) + carbon_source.internal = null + + // This isn't meant to be FALSE, it correlates to the icon's name. + carbon_source.update_internals_hud_icon(0) + else if (!QDELETED(item)) + if(internals || carbon_source.getorganslot(ORGAN_SLOT_BREATHING_TUBE)) + carbon_source.internal = item + carbon_source.update_internals_hud_icon(1) + + carbon_source.visible_message( + span_danger("[user] [isnull(carbon_source.internal) ? "closes": "opens"] the valve on [source]'s [item.name]."), + span_userdanger("[user] [isnull(carbon_source.internal) ? "closes": "opens"] the valve on your [item.name]."), + ignored_mobs = user, + ) + + to_chat(user, span_notice("You [isnull(carbon_source.internal) ? "close" : "open"] the valve on [source]'s [item.name].")) + + return TRUE + +#undef INTERNALS_TOGGLE_DELAY +#undef POCKET_EQUIP_DELAY diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/human_update_icons.dm similarity index 92% rename from code/modules/mob/living/carbon/human/update_icons.dm rename to code/modules/mob/living/carbon/human/human_update_icons.dm index 52d736f9ce..db0b4ddfac 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -58,14 +58,14 @@ There are several things that need to be remembered: dna.species.handle_hair(src) //used when putting/removing clothes that hide certain mutant body parts to just update those and not update the whole body. -/mob/living/carbon/human/proc/update_mutant_bodyparts() +/mob/living/carbon/human/proc/update_mutant_bodyparts(block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) - dna.species.handle_mutant_bodyparts(src) + dna.species.handle_mutant_bodyparts(src, null, block_recursive_calls) -/mob/living/carbon/human/update_body(update_genitals = FALSE) +/mob/living/carbon/human/update_body(update_genitals = FALSE, block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(BODY_LAYER) - dna.species.handle_body(src) + dna.species.handle_body(src, block_recursive_calls) ..() if(update_genitals) update_genitals() @@ -75,24 +75,24 @@ There are several things that need to be remembered: /* --------------------------------------- */ //For legacy support. -/mob/living/carbon/human/regenerate_icons() +/mob/living/carbon/human/regenerate_icons(block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) if(!..()) icon_render_key = null //invalidate bodyparts cache - update_body(TRUE) + update_body(TRUE, block_recursive_calls) update_hair() - update_inv_w_uniform() + update_inv_w_uniform(block_recursive_calls) update_inv_wear_id() update_inv_gloves() update_inv_glasses() update_inv_ears() update_inv_shoes() update_inv_s_store() - update_inv_wear_mask() - update_inv_head() + update_inv_wear_mask(block_recursive_calls) + update_inv_head(block_recursive_calls) update_inv_belt() update_inv_back() - update_inv_wear_suit() + update_inv_wear_suit(block_recursive_calls) update_inv_pockets() update_inv_neck() update_transform() @@ -123,12 +123,12 @@ There are several things that need to be remembered: apply_overlay(ANTAG_LAYER) -/mob/living/carbon/human/update_inv_w_uniform() +/mob/living/carbon/human/update_inv_w_uniform(block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(UNIFORM_LAYER) if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_W_UNIFORM] + var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_ICLOTHING) + 1] inv.update_icon() if(istype(w_uniform, /obj/item/clothing/under)) @@ -173,14 +173,14 @@ There are several things that need to be remembered: overlays_standing[UNIFORM_LAYER] = uniform_overlay apply_overlay(UNIFORM_LAYER) - update_mutant_bodyparts() + update_mutant_bodyparts(block_recursive_calls) /mob/living/carbon/human/update_inv_wear_id() if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(ID_LAYER) if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_ID] + var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_ID) + 1] inv.update_icon() var/mutable_appearance/id_overlay = overlays_standing[ID_LAYER] @@ -204,12 +204,12 @@ There are several things that need to be remembered: if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(GLOVES_LAYER) - if(client && hud_used && hud_used.inv_slots[SLOT_GLOVES]) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_GLOVES] + if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_GLOVES) + 1]) + var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_GLOVES) + 1] inv.update_icon() if(!gloves && bloody_hands) - var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color()) + var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) if(get_num_arms(FALSE) < 2) if(has_left_hand(FALSE)) bloody_overlay.icon_state = "bloodyhands_left" @@ -242,7 +242,7 @@ There are several things that need to be remembered: return if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_GLASSES] + var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_EYES) + 1] inv.update_icon() if(glasses) @@ -269,7 +269,7 @@ There are several things that need to be remembered: return if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_EARS] + var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_EARS) + 1] inv.update_icon() if(ears) @@ -295,7 +295,7 @@ There are several things that need to be remembered: return if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_SHOES] + var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_FEET) + 1] inv.update_icon() if(dna.species.mutant_bodyparts["taur"]) @@ -330,7 +330,7 @@ There are several things that need to be remembered: remove_overlay(SUIT_STORE_LAYER) if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_S_STORE] + var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_SUITSTORE) + 1] inv.update_icon() if(s_store) @@ -349,7 +349,7 @@ There are several things that need to be remembered: overlays_standing[SUIT_STORE_LAYER] = s_store_overlay apply_overlay(SUIT_STORE_LAYER) -/mob/living/carbon/human/update_inv_head() +/mob/living/carbon/human/update_inv_head(block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(HEAD_LAYER) @@ -357,7 +357,7 @@ There are several things that need to be remembered: return if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD] + var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_HEAD) + 1] inv.update_icon() if(head) @@ -387,14 +387,14 @@ There are several things that need to be remembered: head_overlay.pixel_y += dna.species.offset_features[OFFSET_HEAD][2] overlays_standing[HEAD_LAYER] = head_overlay apply_overlay(HEAD_LAYER) - update_mutant_bodyparts() + update_mutant_bodyparts(block_recursive_calls) /mob/living/carbon/human/update_inv_belt() if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(BELT_LAYER) if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_BELT] + var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_BELT) + 1] inv.update_icon() if(belt) @@ -411,12 +411,12 @@ There are several things that need to be remembered: overlays_standing[BELT_LAYER] = belt_overlay apply_overlay(BELT_LAYER) -/mob/living/carbon/human/update_inv_wear_suit() +/mob/living/carbon/human/update_inv_wear_suit(block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(SUIT_LAYER) if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_SUIT] + var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_OCLOTHING) + 1] inv.update_icon() if(wear_suit) @@ -471,7 +471,7 @@ There are several things that need to be remembered: suit_overlay = center_image(suit_overlay, dimension_x, dimension_y) overlays_standing[SUIT_LAYER] = suit_overlay update_hair() - update_mutant_bodyparts() + update_mutant_bodyparts(block_recursive_calls) apply_overlay(SUIT_LAYER) @@ -479,10 +479,10 @@ There are several things that need to be remembered: if(client && hud_used) var/atom/movable/screen/inventory/inv - inv = hud_used.inv_slots[SLOT_L_STORE] + inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_LPOCKET) + 1] inv.update_icon() - inv = hud_used.inv_slots[SLOT_R_STORE] + inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_RPOCKET) + 1] inv.update_icon() if(l_store) @@ -498,7 +498,7 @@ There are several things that need to be remembered: update_observer_view(r_store) -/mob/living/carbon/human/update_inv_wear_mask() +/mob/living/carbon/human/update_inv_wear_mask(block_recursive_calls = FALSE) if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(FACEMASK_LAYER) @@ -506,7 +506,7 @@ There are several things that need to be remembered: return if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_MASK] + var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_MASK) + 1] inv.update_icon() if(wear_mask) @@ -537,7 +537,7 @@ There are several things that need to be remembered: mask_overlay.pixel_y += dna.species.offset_features[OFFSET_FACEMASK][2] overlays_standing[FACEMASK_LAYER] = mask_overlay apply_overlay(FACEMASK_LAYER) - update_mutant_bodyparts() //e.g. upgate needed because mask now hides lizard snout + update_mutant_bodyparts(block_recursive_calls) //e.g. upgate needed because mask now hides lizard snout /mob/living/carbon/human/update_inv_back() if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) @@ -791,7 +791,7 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if // eyes if(!(NOEYES in dna.species.species_traits)) var/has_eyes = getorganslot(ORGAN_SLOT_EYES) - if(!has_eyes) + if(!has_eyes && !HAS_TRAIT(src, TRAIT_DULLAHAN)) add_overlay(mutable_appearance('icons/mob/eyes.dmi', "eyes_missing", -BODY_LAYER)) else var/left_state = DEFAULT_LEFT_EYE_STATE @@ -803,6 +803,8 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if right_state = eye_type + "_right_eye" var/mutable_appearance/left_eye = mutable_appearance('icons/mob/eyes.dmi', left_state, -BODY_LAYER) var/mutable_appearance/right_eye = mutable_appearance('icons/mob/eyes.dmi', right_state, -BODY_LAYER) + left_eye.category = "HEAD" + right_eye.category = "HEAD" if((EYECOLOR in dna.species.species_traits) && has_eyes) left_eye.color = "#" + left_eye_color right_eye.color = "#" + right_eye_color diff --git a/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm b/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm index c8f870bf2a..482268f8f5 100644 --- a/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm +++ b/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm @@ -62,7 +62,7 @@ H.add_movespeed_modifier(/datum/movespeed_modifier/slime_puddle) - ENABLE_BITFIELD(H.pass_flags, PASSMOB) //this actually lets people pass over you + H.pass_flags |= PASSMOB //this actually lets people pass over you squeak = H.AddComponent(/datum/component/squeak, custom_sounds = list('sound/effects/blobattack.ogg')) //blorble noise when people step on you //if the user is a changeling, retract their sting @@ -103,7 +103,7 @@ REMOVE_TRAIT(H, TRAIT_HUMAN_NO_RENDER, SLIMEPUDDLE_TRAIT) H.update_disabled_bodyparts(silent = TRUE) H.remove_movespeed_modifier(/datum/movespeed_modifier/slime_puddle) - DISABLE_BITFIELD(H.pass_flags, PASSMOB) + H.pass_flags &= ~(PASSMOB) is_puddle = FALSE if(squeak) squeak.RemoveComponent() diff --git a/code/modules/mob/living/carbon/human/innate_abilities/coiling.dm b/code/modules/mob/living/carbon/human/innate_abilities/coiling.dm new file mode 100644 index 0000000000..2cfbf9fb73 --- /dev/null +++ b/code/modules/mob/living/carbon/human/innate_abilities/coiling.dm @@ -0,0 +1,96 @@ + +/datum/action/innate/ability/coiling + name = "Coil Grabbed Mob" + check_flags = AB_CHECK_CONSCIOUS + button_icon_state = "coil_icon" + icon_icon = 'icons/mob/actions/actions_snake.dmi' + background_icon_state = "bg_alien" + required_mobility_flags = MOBILITY_STAND + var/currently_coiling = FALSE + var/mob/living/carbon/human/currently_coiled + var/mutable_appearance/tracked_overlay + +/datum/action/innate/ability/coiling/Activate() + // make sure they meet the mobility/check flags + if(IsAvailable()) + // check that the user has grabbed someone and they are not currently coiling someone + if(ishuman(owner.pulling) && !currently_coiling) + coil_mob(owner.pulling) + +/datum/action/innate/ability/coiling/proc/update_coil_offset(atom/source, old_dir, new_dir) + // update the coiling offset on the coiled user depending on the way the owner is facing + switch(new_dir) + if(NORTH) + currently_coiled.pixel_x = -12 + if(EAST) + currently_coiled.pixel_x = -12 + if(SOUTH) + currently_coiled.pixel_x = 12 + if(WEST) + currently_coiled.pixel_x = 12 + +/datum/action/innate/ability/coiling/proc/coil_mob(var/mob/living/carbon/human/H) + if(currently_coiling) + to_chat(owner, span_warning("You are already coiling someone!")) + return + + // begin the coiling action + H.visible_message("[owner] coils [H] with their tail!", \ + "[owner] coils you with their tail!") + currently_coiling = TRUE + currently_coiled = H + + H.layer -= 0.1 // LISTEN I HATE TOUCHING MOB LAYERS TOO BUT THIS IS JUST SO THEY RENDER UNDER THE OTHER PLAYER SDFHSDFHDSFHDSH + + // move user to same tile + H.forceMove(get_turf(owner)) + + // cancel the coiling action if certain things are done + RegisterSignal(owner, COMSIG_MOVABLE_MOVED, .proc/cancel_coil) + RegisterSignal(owner, COMSIG_LIVING_RESTING, .proc/cancel_coil) + RegisterSignal(owner, COMSIG_LIVING_STOPPED_PULLING, .proc/cancel_coil) + + // update the coil offset, update again if owner changes direction + RegisterSignal(owner, COMSIG_ATOM_DIR_CHANGE, .proc/update_coil_offset) + update_coil_offset(null, null, owner.dir) + + // set our overlay to new image + var/mob/living/carbon/human/user = owner + user.dna.species.mutant_bodyparts["taur"] = "Naga (coiled)" + user.dna.features["taur"] = "Naga (coiled)" + user.update_mutant_bodyparts() + +/datum/action/innate/ability/coiling/proc/cancel_coil() + var/mob/living/carbon/human/H = owner + + if(!currently_coiling) + return + + // cancel the coiling action by removing the overlay + currently_coiled.pixel_x = 0 + + currently_coiling = FALSE + currently_coiled = null + + // unregister signals + UnregisterSignal(owner, COMSIG_MOVABLE_MOVED) + UnregisterSignal(owner, COMSIG_LIVING_RESTING) + UnregisterSignal(owner, COMSIG_LIVING_STOPPED_PULLING) + UnregisterSignal(owner, COMSIG_ATOM_DIR_CHANGE) + + // change overlay back to original image + H.dna.species.mutant_bodyparts["taur"] = "Naga" + H.dna.features["taur"] = "Naga" + H.update_mutant_bodyparts() + + H.update_body() + + H.layer += 0.1 + + // remove the added overlay + owner.cut_overlay(tracked_overlay) + tracked_overlay = null + +/datum/action/innate/ability/coiling/Remove(mob/M) + cancel_coil() + ..(M) diff --git a/code/modules/mob/living/carbon/human/innate_abilities/customization.dm b/code/modules/mob/living/carbon/human/innate_abilities/customization.dm index 363f6ecbb2..621dc58650 100644 --- a/code/modules/mob/living/carbon/human/innate_abilities/customization.dm +++ b/code/modules/mob/living/carbon/human/innate_abilities/customization.dm @@ -22,7 +22,7 @@ /datum/action/innate/ability/humanoid_customization/proc/change_form() var/mob/living/carbon/human/H = owner - var/select_alteration = input(owner, "Select what part of your form to alter", "Form Alteration", "cancel") in list("Body Color","Hair Style", "Genitals", "Tail", "Snout", "Markings", "Ears", "Taur body", "Penis", "Vagina", "Penis Length", "Breast Size", "Breast Shape", "Cancel") + var/select_alteration = input(owner, "Select what part of your form to alter", "Form Alteration", "cancel") in list("Body Color", "Eye Color","Hair Style", "Genitals", "Tail", "Snout", "Wings", "Markings", "Ears", "Taur body", "Penis", "Vagina", "Penis Length", "Breast Size", "Breast Shape", "Butt Size", "Cancel") if(select_alteration == "Body Color") var/new_color = input(owner, "Choose your skin color:", "Race change","#"+H.dna.features["mcolor"]) as color|null @@ -34,6 +34,27 @@ H.update_hair() else to_chat(H, "Invalid color. Your color is not bright enough.") + else if(select_alteration == "Eye Color") + if(iscultist(H) && HAS_TRAIT(H, TRAIT_CULT_EYES)) + to_chat(H, "\"I do not need you to hide yourself anymore, relish my gift.\"") + return + + var/heterochromia = input(owner, "Do you want to have heterochromia?", "Confirm Multicolors") in list("Yes", "No") + if(heterochromia == "Yes") + var/new_color1 = input(owner, "Choose your left eye color:", "Eye Color Change","#"+H.dna?.features["left_eye_color"]) as color|null + if(new_color1) + H.left_eye_color = sanitize_hexcolor(new_color1, 6) + var/new_color2 = input(owner, "Choose your right eye color:", "Eye Color Change","#"+H.dna?.features["right_eye_color"]) as color|null + if(new_color2) + H.right_eye_color = sanitize_hexcolor(new_color2, 6) + else + var/new_eyes = input(owner, "Choose your eye color:", "Character Preference","#"+H.dna?.features["left_eye_color"]) as color|null + if(new_eyes) + H.left_eye_color = sanitize_hexcolor(new_eyes, 6) + H.right_eye_color = sanitize_hexcolor(new_eyes, 6) + H.dna?.update_ui_block(DNA_LEFT_EYE_COLOR_BLOCK) + H.dna?.update_ui_block(DNA_RIGHT_EYE_COLOR_BLOCK) + H.update_body() else if(select_alteration == "Hair Style") if(H.gender == MALE) var/new_style = input(owner, "Select a facial hair style", "Hair Alterations") as null|anything in GLOB.facial_hair_styles_list @@ -95,6 +116,25 @@ if(new_snout) H.dna.features["mam_snouts"] = new_snout H.update_body() + + else if (select_alteration == "Wings") + var/new_color = input(owner, "Choose your wing color:", "Race change","#"+H.dna.features["wings_color"]) as color|null + if(new_color) + H.dna.features["wings_color"] = sanitize_hexcolor(new_color, 6) + H.update_body() + H.update_hair() + var/list/snowflake_wings_list = list("Normal" = null) + for(var/path in GLOB.deco_wings_list) + var/datum/sprite_accessory/deco_wings/instance = GLOB.deco_wings_list[path] + if(istype(instance, /datum/sprite_accessory)) + var/datum/sprite_accessory/S = instance + if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(H.client.ckey))) + snowflake_wings_list[S.name] = path + var/new_wings + new_wings = input(owner, "Choose your character's wings:", "Wing Alteration") as null|anything in snowflake_wings_list + if(new_wings) + H.dna.features["deco_wings"] = new_wings + H.update_body() else if (select_alteration == "Markings") var/list/snowflake_markings_list = list("None") @@ -135,6 +175,8 @@ var/datum/sprite_accessory/taur/instance = GLOB.taur_list[path] if(istype(instance, /datum/sprite_accessory)) var/datum/sprite_accessory/S = instance + if(S.ignore) + continue if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(H.client.ckey))) snowflake_taur_list[S.name] = path var/new_taur @@ -204,5 +246,17 @@ H.apply_overlay() H.give_genital(/obj/item/organ/genital/breasts) + else if (select_alteration == "Butt Size") + for(var/obj/item/organ/genital/butt/X in H.internal_organs) + qdel(X) + var/min_B = CONFIG_GET(number/butt_min_size_prefs) + var/max_B = CONFIG_GET(number/butt_max_size_prefs) + var/new_length = input(owner, "Butt size:\n([min_B]-[max_B])", "Genital Alteration") as num|null + if(new_length) + H.dna.features["butt_size"] = clamp(round(new_length), min_B, max_B) + H.update_genitals() + H.apply_overlay() + H.give_genital(/obj/item/organ/genital/butt) + else return diff --git a/code/modules/mob/living/carbon/human/innate_abilities/limb_regeneration.dm b/code/modules/mob/living/carbon/human/innate_abilities/limb_regeneration.dm index ce36397c91..6f3809c232 100644 --- a/code/modules/mob/living/carbon/human/innate_abilities/limb_regeneration.dm +++ b/code/modules/mob/living/carbon/human/innate_abilities/limb_regeneration.dm @@ -25,25 +25,21 @@ /datum/action/innate/ability/limb_regrowth/Activate() var/mob/living/carbon/human/H = owner var/list/limbs_to_heal = H.get_missing_limbs() - if(limbs_to_heal.len < 1) - to_chat(H, "You feel intact enough as it is.") + if(!length(limbs_to_heal)) + to_chat(H, span_notice("You feel intact enough as it is.")) return - to_chat(H, "You focus intently on your missing [limbs_to_heal.len >= 2 ? "limbs" : "limb"]...") - var/mode = H.get_ability_property(INNATE_ABILITY_LIMB_REGROWTH, PROPERTY_LIMB_REGROWTH_USAGE_TYPE) - switch(mode) - if(REGROWTH_USES_BLOOD) - if(H.blood_volume >= 40*limbs_to_heal.len+(BLOOD_VOLUME_OKAY*H.blood_ratio)) - H.regenerate_limbs() - H.blood_volume -= 40*limbs_to_heal.len - to_chat(H, "...and after a moment you finish reforming!") - return - else if(H.blood_volume >= 40)//We can partially heal some limbs - while(H.blood_volume >= (BLOOD_VOLUME_OKAY*H.blood_ratio)+40) - var/healed_limb = pick(limbs_to_heal) - H.regenerate_limb(healed_limb) - limbs_to_heal -= healed_limb - H.blood_volume -= 40 - to_chat(H, "...but there is not enough of you to fix everything! You must attain more mass to heal completely!") - return - to_chat(H, "...but there is not enough of you to go around! You must attain more mass to heal!") - + to_chat(H, span_notice("You focus intently on your missing [length(limbs_to_heal) >= 2 ? "limbs" : "limb"]...")) + if(H.blood_volume >= 40*length(limbs_to_heal)+BLOOD_VOLUME_OKAY) + H.regenerate_limbs() + H.blood_volume -= 40*length(limbs_to_heal) + to_chat(H, span_notice("...and after a moment you finish reforming!")) + return + else if(H.blood_volume >= 40)//We can partially heal some limbs + while(H.blood_volume >= BLOOD_VOLUME_OKAY+40) + var/healed_limb = pick(limbs_to_heal) + H.regenerate_limb(healed_limb) + limbs_to_heal -= healed_limb + H.blood_volume -= 40 + to_chat(H, span_warning("...but there is not enough of you to fix everything! You must attain more mass to heal completely!")) + return + to_chat(H, span_warning("...but there is not enough of you to go around! You must attain more mass to heal!")) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index b135ae9cd8..2dce987449 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -17,39 +17,39 @@ // Return the item currently in the slot ID /mob/living/carbon/human/get_item_by_slot(slot_id) switch(slot_id) - if(SLOT_BACK) + if(ITEM_SLOT_BACK) return back - if(SLOT_WEAR_MASK) + if(ITEM_SLOT_MASK) return wear_mask - if(SLOT_NECK) + if(ITEM_SLOT_NECK) return wear_neck - if(SLOT_HANDCUFFED) + if(ITEM_SLOT_HANDCUFFED) return handcuffed - if(SLOT_LEGCUFFED) + if(ITEM_SLOT_LEGCUFFED) return legcuffed - if(SLOT_BELT) + if(ITEM_SLOT_BELT) return belt - if(SLOT_WEAR_ID) + if(ITEM_SLOT_ID) return wear_id - if(SLOT_EARS) + if(ITEM_SLOT_EARS) return ears - if(SLOT_GLASSES) + if(ITEM_SLOT_EYES) return glasses - if(SLOT_GLOVES) + if(ITEM_SLOT_GLOVES) return gloves - if(SLOT_HEAD) + if(ITEM_SLOT_HEAD) return head - if(SLOT_SHOES) + if(ITEM_SLOT_FEET) return shoes - if(SLOT_WEAR_SUIT) + if(ITEM_SLOT_OCLOTHING) return wear_suit - if(SLOT_W_UNIFORM) + if(ITEM_SLOT_ICLOTHING) return w_uniform - if(SLOT_L_STORE) + if(ITEM_SLOT_LPOCKET) return l_store - if(SLOT_R_STORE) + if(ITEM_SLOT_RPOCKET) return r_store - if(SLOT_S_STORE) + if(ITEM_SLOT_SUITSTORE) return s_store return null @@ -98,17 +98,17 @@ var/not_handled = FALSE //Added in case we make this type path deeper one day switch(slot) - if(SLOT_BELT) + if(ITEM_SLOT_BELT) belt = I update_inv_belt() - if(SLOT_WEAR_ID) + if(ITEM_SLOT_ID) wear_id = I sec_hud_set_ID() update_inv_wear_id() - if(SLOT_EARS) + if(ITEM_SLOT_EARS) ears = I update_inv_ears() - if(SLOT_GLASSES) + if(ITEM_SLOT_EYES) glasses = I var/obj/item/clothing/glasses/G = I if(G.glass_colour_type) @@ -121,13 +121,13 @@ if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha)) update_sight() update_inv_glasses() - if(SLOT_GLOVES) + if(ITEM_SLOT_GLOVES) gloves = I update_inv_gloves() - if(SLOT_SHOES) + if(ITEM_SLOT_FEET) shoes = I update_inv_shoes() - if(SLOT_WEAR_SUIT) + if(ITEM_SLOT_OCLOTHING) wear_suit = I if(I.flags_inv & HIDEJUMPSUIT) update_inv_w_uniform() @@ -135,19 +135,23 @@ stop_pulling() //can't pull if restrained update_action_buttons_icon() //certain action buttons will no longer be usable. update_inv_wear_suit() - if(SLOT_W_UNIFORM) + if(ITEM_SLOT_ICLOTHING) w_uniform = I update_suit_sensors() update_inv_w_uniform() - if(SLOT_L_STORE) + if(ITEM_SLOT_LPOCKET) l_store = I update_inv_pockets() - if(SLOT_R_STORE) + if(ITEM_SLOT_RPOCKET) r_store = I update_inv_pockets() - if(SLOT_S_STORE) + if(ITEM_SLOT_SUITSTORE) s_store = I update_inv_s_store() + if(ITEM_SLOT_ACCESSORY) + var/obj/item/clothing/under/attach_target = w_uniform + attach_target.attach_accessory(I, src, TRUE) + // updates handled by attach_accessory else to_chat(src, "You are trying to equip this item to an unsupported inventory slot. Report this to a coder!") not_handled = TRUE @@ -188,9 +192,9 @@ dropItemToGround(r_store, TRUE) //Again, makes sense for pockets to drop. if(l_store) dropItemToGround(l_store, TRUE) - if(wear_id && !CHECK_BITFIELD(wear_id.item_flags, NO_UNIFORM_REQUIRED)) + if(wear_id && !(wear_id.item_flags & NO_UNIFORM_REQUIRED)) dropItemToGround(wear_id) - if(belt && !CHECK_BITFIELD(belt.item_flags, NO_UNIFORM_REQUIRED)) + if(belt && !(belt.item_flags & NO_UNIFORM_REQUIRED)) dropItemToGround(belt) w_uniform = null update_suit_sensors() @@ -209,7 +213,7 @@ update_tint() if(G.vision_correction) if(HAS_TRAIT(src, TRAIT_NEARSIGHT)) - overlay_fullscreen("nearsighted", /atom/movable/screen/fullscreen/impaired, 1) + overlay_fullscreen("nearsighted", /atom/movable/screen/fullscreen/scaled/impaired, 1) if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha)) update_sight() if(!QDELETED(src)) @@ -296,7 +300,7 @@ if(incapacitated()) return var/obj/item/thing = get_active_held_item() - var/obj/item/equipped_back = get_item_by_slot(SLOT_BACK) + var/obj/item/equipped_back = get_item_by_slot(ITEM_SLOT_BACK) if(!equipped_back) // We also let you equip a backpack like this if(!thing) to_chat(src, "You have no backpack to take something out of!") @@ -304,7 +308,14 @@ if(equip_to_slot_if_possible(thing, ITEM_SLOT_BACK)) update_inv_hands() return - if(!SEND_SIGNAL(equipped_back, COMSIG_CONTAINS_STORAGE)) // not a storage item + var/datum/component/storage/storage = equipped_back.GetComponent(/datum/component/storage) + if(istype(equipped_back, /obj/item/mod/control)) + var/obj/item/mod/control/C = equipped_back + for(var/obj/item/mod/module/storage/S in C.modules) + if(S.stored) + equipped_back = S.stored + storage = S.stored.GetComponent(/datum/component/storage) + if(!storage) if(!thing) equipped_back.attack_hand(src) else @@ -314,10 +325,11 @@ if(!SEND_SIGNAL(equipped_back, COMSIG_TRY_STORAGE_INSERT, thing, src)) to_chat(src, "You can't fit anything in!") return - if(!equipped_back.contents.len) // nothing to take out - to_chat(src, "There's nothing in your backpack to take out!") + var/atom/real_location = storage.real_location() + if(!real_location.contents.len) // nothing to take out + to_chat(src, "There's nothing in your [equipped_back.name] to take out!") return - var/obj/item/stored = equipped_back.contents[equipped_back.contents.len] + var/obj/item/stored = real_location.contents[real_location.contents.len] if(!stored || stored.on_found(src)) return stored.attack_hand(src) // take out thing from backpack @@ -327,7 +339,7 @@ if(incapacitated()) return var/obj/item/thing = get_active_held_item() - var/obj/item/equipped_belt = get_item_by_slot(SLOT_BELT) + var/obj/item/equipped_belt = get_item_by_slot(ITEM_SLOT_BELT) if(!equipped_belt) // We also let you equip a belt like this if(!thing) to_chat(src, "You have no belt to take something out of!") diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index b43cd266be..4221df31f6 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -18,7 +18,7 @@ #define THERMAL_PROTECTION_HAND_LEFT 0.025 #define THERMAL_PROTECTION_HAND_RIGHT 0.025 -/mob/living/carbon/human/BiologicalLife(seconds, times_fired) +/mob/living/carbon/human/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return handle_active_genes() @@ -30,6 +30,8 @@ /mob/living/carbon/human/PhysicalLife(seconds, times_fired) if(!(. = ..())) return + if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM) && hud_used) + hud_used.coolant_display.update_counter(src) //Update our name based on whether our face is obscured/disfigured name = get_visible_name() @@ -76,9 +78,23 @@ /mob/living/carbon/human/check_breath(datum/gas_mixture/breath) - var/L = getorganslot(ORGAN_SLOT_LUNGS) + if(breath && HAS_TRAIT(src, TRAIT_NOBREATH) && HAS_TRAIT(src, TRAIT_AUXILIARY_LUNGS)) //Something something bz and synth cooling systems interacting (in reality, this only exists to not make robot lings too strong) + var/total_moles = breath.total_moles() + var/pressure = breath.return_pressure() + #define PP_MOLES(X) ((X / total_moles) * pressure) + #define PP(air, gas) PP_MOLES(air.get_moles(gas)) + var/bz_pp = PP(breath, GAS_BZ) + if(bz_pp > 1) + reagents.add_reagent(/datum/reagent/bz_metabolites,5) + else if(bz_pp > 0.1) + reagents.add_reagent(/datum/reagent/bz_metabolites,1) + #undef PP_MOLES + #undef PP + var/L = getorganslot(ORGAN_SLOT_LUNGS) if(!L) + if(HAS_TRAIT(src, TRAIT_NOBREATH)) + return if(health >= crit_threshold) adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1) else if(!HAS_TRAIT(src, TRAIT_NOCRITDAMAGE)) @@ -214,7 +230,7 @@ var/missing_body_parts_flags = ~get_body_parts_flags() var/max_protection = 1 if(missing_body_parts_flags) //I don't like copypasta as much as proc overhead. Do you want me to make these into a macro? - DISABLE_BITFIELD(thermal_protection_flags, missing_body_parts_flags) + thermal_protection_flags &= ~(missing_body_parts_flags) if(missing_body_parts_flags & HEAD) max_protection -= THERMAL_PROTECTION_HEAD if(missing_body_parts_flags & CHEST) diff --git a/code/modules/mob/living/carbon/human/login.dm b/code/modules/mob/living/carbon/human/login.dm index ebf76eeafa..cccee4a7ef 100644 --- a/code/modules/mob/living/carbon/human/login.dm +++ b/code/modules/mob/living/carbon/human/login.dm @@ -7,8 +7,8 @@ return var/list/print_msg = list() - print_msg += "*---------*" print_msg += "As you snap back to consciousness, you recall people messing with your stuff..." + print_msg += "
    " afk_thefts = reverseRange(afk_thefts) @@ -22,13 +22,14 @@ var/time_since = world.time - iter_theft[AFK_THEFT_TIME] if(time_since > AFK_THEFT_FORGET_DETAILS_TIME) - print_msg += "\tSomeone [theft_message], but it was at least [DisplayTimeText(AFK_THEFT_FORGET_DETAILS_TIME)] ago." + print_msg += "Someone [theft_message], but it was at least [DisplayTimeText(AFK_THEFT_FORGET_DETAILS_TIME)] ago." else - print_msg += "\t[thief_name] [theft_message] roughly [DisplayTimeText(time_since, 10)] ago." + print_msg += "[thief_name] [theft_message] roughly [DisplayTimeText(time_since, 10)] ago." + + print_msg += "
    " if(LAZYLEN(afk_thefts) >= AFK_THEFT_MAX_MESSAGES) print_msg += "There may have been more, but that's all you can remember..." - print_msg += "*---------*" to_chat(src, print_msg.Join("\n")) LAZYNULL(afk_thefts) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 6f94be2d41..bed766519f 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -52,6 +52,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/hair_color ///The alpha used by the hair. 255 is completely solid, 0 is invisible. var/hair_alpha = 255 + ///The gradient style used for the mob's hair. + var/grad_style + ///The gradient color used to color the gradient. + var/grad_color ///Does the species use skintones or not? As of now only used by humans. var/use_skintones = FALSE @@ -61,6 +65,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/exotic_bloodtype = "" /// Assume human as the default blood colour, override this default by species subtypes var/exotic_blood_color = BLOOD_COLOR_HUMAN + /// Which blend mode should this species blood use? + var/exotic_blood_blend_mode = BLEND_MULTIPLY ///What the species drops when gibbed by a gibber machine. var/meat = /obj/item/reagent_containers/food/snacks/meat/slab/human //What the species drops on gibbing var/list/gib_types = list(/obj/effect/gibspawner/human, /obj/effect/gibspawner/human/bodypartless) @@ -104,6 +110,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/burnmod = 1 ///multiplier for damage from cold temperature var/coldmod = 1 + ///moves their safe minimum temp by this value. + var/cold_offset = 0 + ///moves their safe maximum temp by this value. + var/hot_offset = 0 ///multiplier for damage from hot temperature var/heatmod = 1 ///multiplier for stun durations @@ -134,6 +144,15 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) /// A path to an outfit that is important for species life e.g. plasmaman outfit var/datum/outfit/outfit_important_for_life + ///Is this species a flying species? Used as an easy check for some things + var/flying_species = FALSE + ///The actual flying ability given to flying species + var/datum/action/innate/flight/fly + ///Current wings icon + var/wings_icon = "Angel" + //Dictates which wing icons are allowed for a given species. If count is >1 a radial menu is used to choose between all icons in list + var/list/wings_icons = SPECIES_WINGS_ANGEL + ///Species-only traits. Can be found in [code/__DEFINES/DNA.dm] var/list/species_traits = list(HAS_FLESH,HAS_BONE) //by default they can scar and have bones/flesh unless set to something else ///Generic traits tied to having the species. @@ -143,6 +162,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/list/blacklisted_quirks = list() // Quirks that will be removed upon gaining this species, to be defined by species var/list/removed_quirks = list() // Quirks that got removed due to being blacklisted, and will be restored when on_species_loss() is called + var/balance_point_values = FALSE //If true, will balance point values on species gain after removing blacklisted quirks. Use this for roundstart species with blacklisted quirks that people may attempt to use to powergame trait points. ///Punch-specific attack verb. var/attack_verb = "punch" @@ -211,6 +231,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) ///For custom overrides for species ass images var/icon/ass_image + /// List of family heirlooms this species can get with the family heirloom quirk. List of types. + var/list/family_heirlooms + /////////// // PROCS // /////////// @@ -325,11 +348,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/obj/item/organ/stomach/stomach = C.getorganslot(ORGAN_SLOT_STOMACH) var/obj/item/organ/tail/tail = C.getorganslot(ORGAN_SLOT_TAIL) - var/should_have_brain = TRUE + var/should_have_brain = !(HAS_TRAIT(C, TRAIT_DULLAHAN)) // do not mess with a dullahans brain var/should_have_heart = !(NOBLOOD in species_traits) - var/should_have_lungs = !(TRAIT_NOBREATH in inherent_traits) + var/should_have_lungs = ((TRAIT_AUXILIARY_LUNGS in inherent_traits) || !(TRAIT_NOBREATH in inherent_traits)) var/should_have_appendix = !(TRAIT_NOHUNGER in inherent_traits) - var/should_have_eyes = TRUE + var/should_have_eyes = !(HAS_TRAIT(C, TRAIT_DULLAHAN)) // .. or their eyes var/should_have_ears = TRUE var/should_have_tongue = TRUE var/should_have_liver = !(NOLIVER in species_traits) @@ -486,6 +509,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) for(var/datum/disease/A in C.diseases) A.cure(FALSE) + if(flying_species && isnull(fly)) + fly = new + fly.Grant(C) + if(ishuman(C)) var/mob/living/carbon/human/H = C if(NOGENITALS in H.dna.species.species_traits) @@ -560,22 +587,54 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(F) qdel(F) + if(flying_species) + if(C.movement_type & FLYING) + ToggleFlight(C) + fly.Remove(C) + QDEL_NULL(fly) + if(C.dna && C.dna.species && (C.dna.features["wings"] == wings_icon)) + if("wings" in C.dna.species.mutant_bodyparts) + C.dna.species.mutant_bodyparts -= "wings" + C.dna.features["wings"] = "None" + C.update_body() if(ROBOTIC_LIMBS in species_traits) for(var/obj/item/bodypart/B in C.bodyparts) B.change_bodypart_status(initial(B.status), FALSE, TRUE) + if((TRAIT_ROBOTIC_ORGANISM in inherent_traits) && C.hud_used) + C.hud_used.coolant_display.clear() + SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src) // shamelessly inspired by antag_datum.remove_blacklisted_quirks() /datum/species/proc/remove_blacklisted_quirks(mob/living/carbon/C) - var/mob/living/L = C.mind?.current - if(istype(L)) - for(var/q in L.roundstart_quirks) - var/datum/quirk/Q = q - if(Q.type in blacklisted_quirks) - qdel(Q) - removed_quirks += Q.type + . = 0 + if(istype(C)) + if(!balance_point_values) + for(var/q in C.roundstart_quirks) + var/datum/quirk/Q = q + if(Q.type in blacklisted_quirks) + removed_quirks += Q.type + . += 1 + qdel(Q) + else + var/point_overhead = 0 + for(var/datum/quirk/Q as anything in C.roundstart_quirks) + if(Q.type in blacklisted_quirks) + point_overhead -= Q.value + removed_quirks += Q.type + . += 1 + qdel(Q) + if(point_overhead) + for(var/datum/quirk/Q as anything in C.roundstart_quirks) + if(Q.value > 0) + point_overhead -= Q.value + removed_quirks += Q.type + . += 1 + qdel(Q) + if(!point_overhead) + break // restore any quirks that we removed /datum/species/proc/restore_quirks(mob/living/carbon/C) @@ -641,6 +700,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) fhair_file = 'icons/mob/facialhair_extensions.dmi' var/mutable_appearance/facial_overlay = mutable_appearance(fhair_file, fhair_state, -HAIR_LAYER) + facial_overlay.category = "HEAD" if(!forced_colour) if(hair_color) @@ -678,7 +738,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(!hair_hidden || dynamic_hair_suffix) var/mutable_appearance/hair_overlay = mutable_appearance(layer = -HAIR_LAYER) - if(!hair_hidden && !H.getorgan(/obj/item/organ/brain)) //Applies the debrained overlay if there is no brain + hair_overlay.category = "HEAD" + var/mutable_appearance/gradient_overlay = mutable_appearance(layer = -HAIR_LAYER) + gradient_overlay.category = "HEAD" + if(!hair_hidden && !H.getorgan(/obj/item/organ/brain) && !H.GetComponent(/datum/component/dullahan)) //Applies the debrained overlay if there is no brain (ignore if they are dullahan) if(!(NOBLOOD in species_traits)) hair_overlay.icon = 'icons/mob/human_parts.dmi' hair_overlay.icon_state = "debrained" @@ -713,8 +776,21 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) hair_overlay.color = "#" + hair_color else hair_overlay.color = "#" + H.hair_color + + //Gradients + grad_style = H.grad_style + grad_color = H.grad_color + if(grad_style) + var/datum/sprite_accessory/gradient = GLOB.hair_gradients_list[grad_style] + var/icon/temp = icon(gradient.icon, gradient.icon_state) + var/icon/temp_hair = icon(hair_file, hair_state) + temp.Blend(temp_hair, ICON_ADD) + gradient_overlay.icon = temp + gradient_overlay.color = "#" + grad_color + else hair_overlay.color = forced_colour + hair_overlay.alpha = hair_alpha if(OFFSET_HAIR in H.dna.species.offset_features) @@ -723,13 +799,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(hair_overlay.icon) standing += hair_overlay + standing += gradient_overlay if(standing.len) H.overlays_standing[HAIR_LAYER] = standing H.apply_overlay(HAIR_LAYER) -/datum/species/proc/handle_body(mob/living/carbon/human/H) +/datum/species/proc/handle_body(mob/living/carbon/human/H, block_recursive_calls = FALSE) H.remove_overlay(BODY_LAYER) var/list/standing = list() @@ -740,6 +817,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) // lipstick if(H.lip_style && (LIPS in species_traits)) var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/lips.dmi', "lips_[H.lip_style]", -BODY_LAYER) + lip_overlay.category = "HEAD" lip_overlay.color = H.lip_color if(OFFSET_LIPS in H.dna.species.offset_features) @@ -750,20 +828,22 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) // eyes if(!(NOEYES in species_traits)) - var/has_eyes = H.getorganslot(ORGAN_SLOT_EYES) + var/has_eyes = H.getorganslot(ORGAN_SLOT_EYES) || HAS_TRAIT(H, TRAIT_DULLAHAN) // if they are a dullahan just assume eyes exist if(!has_eyes) standing += mutable_appearance('icons/mob/eyes.dmi', "eyes_missing", -BODY_LAYER) else var/left_state = DEFAULT_LEFT_EYE_STATE var/right_state = DEFAULT_RIGHT_EYE_STATE if(eye_type in GLOB.eye_types) - left_state = eye_type + "_left_eye" - right_state = eye_type + "_right_eye" + left_state = "[eye_type]_left_eye" + right_state = "[eye_type]_right_eye" var/mutable_appearance/left_eye = mutable_appearance('icons/mob/eyes.dmi', left_state, -BODY_LAYER) var/mutable_appearance/right_eye = mutable_appearance('icons/mob/eyes.dmi', right_state, -BODY_LAYER) + left_eye.category = "HEAD" + right_eye.category = "HEAD" if((EYECOLOR in species_traits) && has_eyes) - left_eye.color = "#" + H.left_eye_color - right_eye.color = "#" + H.right_eye_color + left_eye.color = "#[H.left_eye_color]" + right_eye.color = "#[H.right_eye_color]" if(OFFSET_EYES in offset_features) left_eye.pixel_x += offset_features[OFFSET_EYES][1] left_eye.pixel_y += offset_features[OFFSET_EYES][2] @@ -821,9 +901,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.overlays_standing[BODY_LAYER] = standing H.apply_overlay(BODY_LAYER) - handle_mutant_bodyparts(H) + handle_mutant_bodyparts(H, null, block_recursive_calls) -/datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour) +/datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour, block_recursive_calls = FALSE) var/list/bodyparts_to_add = mutant_bodyparts.Copy() H.remove_overlay(BODY_BEHIND_LAYER) @@ -837,6 +917,22 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/tauric = mutant_bodyparts["taur"] && H.dna.features["taur"] && H.dna.features["taur"] != "None" + // stuff for adding/removing the coiling ability if you have a taur part + // if another action is ever based on mutant parts we should probably make a system for it so it's all done in one proc with less overhead + var/datum/action/found_action + + for(var/datum/action/A in H.actions) + if(A.type == /datum/action/innate/ability/coiling) + found_action = A + + if(found_action && (!tauric || (H.dna.features["taur"] != "Naga" && H.dna.features["taur"] != "Naga (coiled)"))) + found_action.Remove(H) + + if(!found_action && tauric && H.dna.features["taur"] == "Naga") + found_action = new /datum/action/innate/ability/coiling() + found_action.Grant(H) + + for(var/mutant_part in mutant_bodyparts) var/reference_list = GLOB.mutant_reference_list[mutant_part] if(reference_list) @@ -922,6 +1018,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) for(var/bodypart in relevant_layers[layer]) var/datum/sprite_accessory/S = bodypart var/mutable_appearance/accessory_overlay = mutable_appearance(S.icon, layer = -layernum) + accessory_overlay.category = S.mutable_category bodypart = S.mutant_part_string || dna_feature_as_text_string[S] if(S.gender_specific) @@ -1026,6 +1123,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(S.extra) //apply the extra overlay, if there is one var/mutable_appearance/extra_accessory_overlay = mutable_appearance(S.icon, layer = -layernum) + extra_accessory_overlay.category = S.mutable_category if(S.gender_specific) extra_accessory_overlay.icon_state = "[g]_[bodypart]_extra_[S.icon_state]_[layertext]" else @@ -1072,6 +1170,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(S.extra2) //apply the extra overlay, if there is one var/mutable_appearance/extra2_accessory_overlay = mutable_appearance(S.icon, layer = -layernum) + extra2_accessory_overlay.category = S.mutable_category if(S.gender_specific) extra2_accessory_overlay.icon_state = "[g]_[bodypart]_extra2_[S.icon_state]_[layertext]" else @@ -1119,6 +1218,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.apply_overlay(BODY_FRONT_LAYER) H.apply_overlay(HORNS_LAYER) + if(!block_recursive_calls) + var/datum/component/dullahan/D = H.GetComponent(/datum/component/dullahan) + if(D && D.dullahan_head) + D.dullahan_head.update_appearance() + /* * Equip the outfit required for life. Replaces items currently worn. */ @@ -1140,13 +1244,18 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) return move_trail */ /datum/species/proc/spec_life(mob/living/carbon/human/H) + if(flying_species) //turns off flight automatically if they can't. + HandleFlight(H) if(HAS_TRAIT(H, TRAIT_NOBREATH)) H.setOxyLoss(0) H.losebreath = 0 var/takes_crit_damage = !HAS_TRAIT(H, TRAIT_NOCRITDAMAGE) if((H.health < H.crit_threshold) && takes_crit_damage) - H.adjustBruteLoss(1) + if(!HAS_TRAIT(H, TRAIT_ROBOTIC_ORGANISM)) + H.adjustBruteLoss(1) + else + H.adjustFireLoss(1) //Robots melt instead of taking brute. /datum/species/proc/spec_death(gibbed, mob/living/carbon/human/H) if(H) @@ -1170,11 +1279,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/num_legs = H.get_num_legs(FALSE) switch(slot) - if(SLOT_HANDS) + if(ITEM_SLOT_HANDS) if(H.get_empty_held_indexes()) return TRUE return FALSE - if(SLOT_WEAR_MASK) + if(ITEM_SLOT_MASK) if(H.wear_mask) return FALSE if(!(I.slot_flags & ITEM_SLOT_MASK)) @@ -1182,25 +1291,25 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(!H.get_bodypart(BODY_ZONE_HEAD)) return FALSE return equip_delay_self_check(I, H, bypass_equip_delay_self) - if(SLOT_NECK) + if(ITEM_SLOT_NECK) if(H.wear_neck) return FALSE if( !(I.slot_flags & ITEM_SLOT_NECK) ) return FALSE return TRUE - if(SLOT_BACK) + if(ITEM_SLOT_BACK) if(H.back) return FALSE if( !(I.slot_flags & ITEM_SLOT_BACK) ) return FALSE return equip_delay_self_check(I, H, bypass_equip_delay_self) - if(SLOT_WEAR_SUIT) + if(ITEM_SLOT_OCLOTHING) if(H.wear_suit) return FALSE if( !(I.slot_flags & ITEM_SLOT_OCLOTHING) ) return FALSE return equip_delay_self_check(I, H, bypass_equip_delay_self) - if(SLOT_GLOVES) + if(ITEM_SLOT_GLOVES) if(H.gloves) return FALSE if( !(I.slot_flags & ITEM_SLOT_GLOVES) ) @@ -1208,7 +1317,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(num_arms < 2) return FALSE return equip_delay_self_check(I, H, bypass_equip_delay_self) - if(SLOT_SHOES) + if(ITEM_SLOT_FEET) if(H.shoes) return FALSE if( !(I.slot_flags & ITEM_SLOT_FEET) ) @@ -1221,10 +1330,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) else return FALSE return equip_delay_self_check(I, H, bypass_equip_delay_self) - if(SLOT_BELT) + if(ITEM_SLOT_BELT) if(H.belt) return FALSE - if(!CHECK_BITFIELD(I.item_flags, NO_UNIFORM_REQUIRED)) + if(!(I.item_flags & NO_UNIFORM_REQUIRED)) var/obj/item/bodypart/O = H.get_bodypart(BODY_ZONE_CHEST) if(!H.w_uniform && !nojumpsuit && (!O || !O.is_robotic_limb())) if(return_warning) @@ -1233,7 +1342,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(!(I.slot_flags & ITEM_SLOT_BELT)) return return equip_delay_self_check(I, H, bypass_equip_delay_self) - if(SLOT_GLASSES) + if(ITEM_SLOT_EYES) if(H.glasses) return FALSE if(!(I.slot_flags & ITEM_SLOT_EYES)) @@ -1241,7 +1350,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(!H.get_bodypart(BODY_ZONE_HEAD)) return FALSE return equip_delay_self_check(I, H, bypass_equip_delay_self) - if(SLOT_HEAD) + if(ITEM_SLOT_HEAD) if(H.head) return FALSE if(!(I.slot_flags & ITEM_SLOT_HEAD)) @@ -1249,7 +1358,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(!H.get_bodypart(BODY_ZONE_HEAD)) return FALSE return equip_delay_self_check(I, H, bypass_equip_delay_self) - if(SLOT_EARS) + if(ITEM_SLOT_EARS) if(H.ears) return FALSE if(!(I.slot_flags & ITEM_SLOT_EARS)) @@ -1257,16 +1366,16 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(!H.get_bodypart(BODY_ZONE_HEAD)) return FALSE return equip_delay_self_check(I, H, bypass_equip_delay_self) - if(SLOT_W_UNIFORM) + if(ITEM_SLOT_ICLOTHING) if(H.w_uniform) return FALSE if( !(I.slot_flags & ITEM_SLOT_ICLOTHING) ) return FALSE return equip_delay_self_check(I, H, bypass_equip_delay_self) - if(SLOT_WEAR_ID) + if(ITEM_SLOT_ID) if(H.wear_id) return FALSE - if(!CHECK_BITFIELD(I.item_flags, NO_UNIFORM_REQUIRED)) + if(!(I.item_flags & NO_UNIFORM_REQUIRED)) var/obj/item/bodypart/O = H.get_bodypart(BODY_ZONE_CHEST) if(!H.w_uniform && !nojumpsuit && (!O || !O.is_robotic_limb())) if(return_warning) @@ -1275,7 +1384,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if( !(I.slot_flags & ITEM_SLOT_ID) ) return FALSE return equip_delay_self_check(I, H, bypass_equip_delay_self) - if(SLOT_L_STORE) + if(ITEM_SLOT_LPOCKET) if(HAS_TRAIT(I, TRAIT_NODROP)) //Pockets aren't visible, so you can't move TRAIT_NODROP items into them. return FALSE if(H.l_store) @@ -1287,11 +1396,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(return_warning) return_warning[1] = "You need a jumpsuit before you can attach this [I.name]!" return FALSE - if(I.slot_flags & ITEM_SLOT_DENYPOCKET) - return FALSE - if( I.w_class <= WEIGHT_CLASS_SMALL || (I.slot_flags & ITEM_SLOT_POCKET) ) + if( I.w_class <= WEIGHT_CLASS_SMALL || (I.slot_flags & ITEM_SLOT_POCKETS) ) return TRUE - if(SLOT_R_STORE) + if(ITEM_SLOT_RPOCKET) if(HAS_TRAIT(I, TRAIT_NODROP)) return FALSE if(H.r_store) @@ -1303,12 +1410,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(return_warning) return_warning[1] = "You need a jumpsuit before you can attach this [I.name]!" return FALSE - if(I.slot_flags & ITEM_SLOT_DENYPOCKET) - return FALSE - if( I.w_class <= WEIGHT_CLASS_SMALL || (I.slot_flags & ITEM_SLOT_POCKET) ) + if( I.w_class <= WEIGHT_CLASS_SMALL || (I.slot_flags & ITEM_SLOT_POCKETS) ) return TRUE return FALSE - if(SLOT_S_STORE) + if(ITEM_SLOT_SUITSTORE) if(HAS_TRAIT(I, TRAIT_NODROP)) return FALSE if(H.s_store) @@ -1328,7 +1433,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if( istype(I, /obj/item/pda) || istype(I, /obj/item/pen) || is_type_in_list(I, H.wear_suit.allowed) ) return TRUE return FALSE - if(SLOT_HANDCUFFED) + if(ITEM_SLOT_HANDCUFFED) if(H.handcuffed) return FALSE if(!istype(I, /obj/item/restraints/handcuffs)) @@ -1336,7 +1441,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(num_arms < 2) return FALSE return TRUE - if(SLOT_LEGCUFFED) + if(ITEM_SLOT_LEGCUFFED) if(H.legcuffed) return FALSE if(!istype(I, /obj/item/restraints/legcuffs)) @@ -1344,11 +1449,27 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(num_legs < 2) return FALSE return TRUE - if(SLOT_IN_BACKPACK) + if(ITEM_SLOT_BACKPACK) if(H.back) if(SEND_SIGNAL(H.back, COMSIG_TRY_STORAGE_CAN_INSERT, I, H, TRUE)) return TRUE return FALSE + if(ITEM_SLOT_ACCESSORY) + if(istype(H.w_uniform, /obj/item/clothing/under)) + var/obj/item/clothing/under/attaching_target = H.w_uniform + if(attaching_target.attached_accessory) + if(return_warning) + return_warning[1] = "\The [attaching_target] already has an accessory." + return FALSE + if(attaching_target.dummy_thick) + if(return_warning) + return_warning[1] = "\The [attaching_target] is too bulky and cannot have accessories attached to it!" + return FALSE + else + return TRUE + else if(return_warning) + return_warning[1] = "\The [H.w_uniform] cannot have any attachments." + return FALSE return FALSE //Unsupported slot /datum/species/proc/equip_delay_self_check(obj/item/I, mob/living/carbon/human/H, bypass_equip_delay_self) @@ -1378,7 +1499,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) //////////// /datum/species/proc/handle_digestion(mob/living/carbon/human/H) - if(HAS_TRAIT(src, TRAIT_NOHUNGER)) + if(HAS_TRAIT(H, TRAIT_NOHUNGER)) return //hunger is for BABIES //The fucking TRAIT_FAT mutation is the dumbest shit ever. It makes the code so difficult to work with @@ -1610,7 +1731,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) return FALSE - var/armor_block = target.run_armor_check(affecting, "melee") + var/armor_block = target.run_armor_check(affecting, MELEE) playsound(target.loc, user.dna.species.attack_sound_override || attack_sound, 25, 1, -1) target.visible_message("[user] [atk_verb]ed [target]!", \ "[user] [atk_verb]ed you!", null, COMBAT_MESSAGE_RANGE, null, \ @@ -1819,7 +1940,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) hit_area = affecting.name var/def_zone = affecting.body_zone - var/armor_block = H.run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened a hit to your [hit_area].",I.armour_penetration) + var/armor_block = H.run_armor_check(affecting, MELEE, "Your armor has protected your [hit_area].", "Your armor has softened a hit to your [hit_area].",I.armour_penetration) armor_block = min(90,armor_block) //cap damage reduction at 90% var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords) var/Iwound_bonus = I.wound_bonus @@ -1855,7 +1976,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(BODY_ZONE_HEAD) if(!I.get_sharpness() && armor_block < 50) if(prob(I.force)) - if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) + if(HAS_TRAIT(H, TRAIT_ROBOTIC_ORGANISM)) H.adjustToxLoss(5, toxins_type = TOX_SYSCORRUPT) //Bonk! - Effectively 5 bonus damage else H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20) @@ -1871,11 +1992,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(H.stat == CONSCIOUS && H != user && prob(I.force + ((100 - H.health) * 0.5))) // rev deconversion through blunt trauma. var/datum/antagonist/rev/rev = H.mind.has_antag_datum(/datum/antagonist/rev) - var/datum/antagonist/gang/gang = H.mind.has_antag_datum(/datum/antagonist/gang && !/datum/antagonist/gang/boss) if(rev) rev.remove_revolutionary(FALSE, user) - if(gang) - H.mind.remove_antag_datum(/datum/antagonist/gang) if(bloody) //Apply blood if(H.wear_mask) @@ -1980,7 +2098,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(CHECK_MOBILITY(target, MOBILITY_STAND)) target.adjustStaminaLoss(5) else - target.adjustStaminaLoss(target.getStaminaLoss() > 75? 5 : 75) + target.adjustStaminaLoss(IS_STAMCRIT(target)? 2 : 10) if(target.is_shove_knockdown_blocked()) return @@ -2152,15 +2270,20 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) //Thermal protection (insulation) has mixed benefits in two situations (hot in hot places, cold in hot places) if(!H.on_fire) //If you're on fire, you do not heat up or cool down based on surrounding gases var/natural = 0 + var/cooling_efficiency = 1 if(H.stat != DEAD) natural = H.natural_bodytemperature_stabilization() + cooling_efficiency = H.get_cooling_efficiency() + + if(HAS_TRAIT(H, TRAIT_ROBOTIC_ORGANISM)) //Synths by default slowly heat up and need to lose said heat to the environment or active cooling. If you have very high cooling efficiency, you instead passively cool. + H.adjust_bodytemperature(SYNTH_PASSIVE_HEAT_GAIN * (1 - cooling_efficiency), (T0C + SYNTH_MIN_PASSIVE_COOLING_TEMP), (T0C + SYNTH_MAX_PASSIVE_GAIN_TEMP)) var/thermal_protection = 1 if(loc_temp < H.bodytemperature) //Place is colder than we are thermal_protection -= H.get_thermal_protection(loc_temp, TRUE) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. if(H.bodytemperature < BODYTEMP_NORMAL) //we're cold, insulation helps us retain body heat and will reduce the heat we lose to the environment - H.adjust_bodytemperature((thermal_protection+1)*natural + max(thermal_protection * (loc_temp - H.bodytemperature) / BODYTEMP_COLD_DIVISOR, BODYTEMP_COOLING_MAX)) + H.adjust_bodytemperature((thermal_protection+1)*natural + max((thermal_protection * (loc_temp - H.bodytemperature) * cooling_efficiency) / BODYTEMP_COLD_DIVISOR, BODYTEMP_COOLING_MAX)) else //we're sweating, insulation hinders our ability to reduce heat - and it will reduce the amount of cooling you get from the environment - H.adjust_bodytemperature(natural*(1/(thermal_protection+1)) + max((thermal_protection * (loc_temp - H.bodytemperature) + BODYTEMP_NORMAL - H.bodytemperature) / BODYTEMP_COLD_DIVISOR , BODYTEMP_COOLING_MAX)) //Extra calculation for hardsuits to bleed off heat + H.adjust_bodytemperature(natural*(1/(thermal_protection+1)) + max(((thermal_protection * (loc_temp - H.bodytemperature) + BODYTEMP_NORMAL - H.bodytemperature) * cooling_efficiency) / BODYTEMP_COLD_DIVISOR , BODYTEMP_COOLING_MAX)) //Extra calculation for hardsuits to bleed off heat else //Place is hotter than we are thermal_protection -= H.get_thermal_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. if(H.bodytemperature < BODYTEMP_NORMAL) //and we're cold, insulation enhances our ability to retain body heat but reduces the heat we get from the environment @@ -2174,9 +2297,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.throw_alert("tempfeel", /atom/movable/screen/alert/cold, 2) if(-35 to -20) H.throw_alert("tempfeel", /atom/movable/screen/alert/cold, 1) - if(-20 to 0) //This is the sweet spot where air is considered normal + if(-20 to 1) //This is the sweet spot where air is considered normal H.clear_alert("tempfeel") - if(0 to 15) //When the air around you matches your body's temperature, you'll start to feel warm. + if(1 to 15) //When the air around you matches your body's temperature, you'll start to feel warm. H.throw_alert("tempfeel", /atom/movable/screen/alert/hot, 1) if(15 to 30) H.throw_alert("tempfeel", /atom/movable/screen/alert/hot, 2) @@ -2184,7 +2307,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.throw_alert("tempfeel", /atom/movable/screen/alert/hot, 3) // +/- 50 degrees from 310K is the 'safe' zone, where no damage is dealt. - if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTHEAT)) + if(H.bodytemperature > (BODYTEMP_HEAT_DAMAGE_LIMIT + hot_offset) && !HAS_TRAIT(H, TRAIT_RESISTHEAT)) //Body temperature is too hot. SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold") @@ -2212,11 +2335,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.emote("scream") H.apply_damage(burn_damage, BURN) - else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD)) + else if(H.bodytemperature < (BODYTEMP_COLD_DAMAGE_LIMIT + cold_offset) && !HAS_TRAIT(H, TRAIT_RESISTCOLD)) SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot") SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "cold", /datum/mood_event/cold) //Apply cold slowdown - H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/cold, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR)) + H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/cold, multiplicative_slowdown = (((BODYTEMP_COLD_DAMAGE_LIMIT + cold_offset) - H.bodytemperature) / COLD_SLOWDOWN_FACTOR)) switch(H.bodytemperature) if(200 to BODYTEMP_COLD_DAMAGE_LIMIT) H.throw_alert("temp", /atom/movable/screen/alert/shiver, 1) @@ -2316,7 +2439,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) for(var/X in burning_items) var/obj/item/I = X if(!(I.resistance_flags & FIRE_PROOF)) - I.take_damage(H.fire_stacks, BURN, "fire", 0) + I.take_damage(H.fire_stacks, BURN, FIRE, 0) var/thermal_protection = H.easy_thermal_protection() @@ -2337,10 +2460,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) return //////////// -//Stun// +// Stun // //////////// /datum/species/proc/spec_stun(mob/living/carbon/human/H,amount) + if(flying_species && H.movement_type & FLYING) + ToggleFlight(H,0) + flyslip(H) if(H) stop_wagging_tail(H) . = stunmod * H.physiology.stun_mod * amount @@ -2350,10 +2476,21 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) ////////////// /datum/species/proc/space_move(mob/living/carbon/human/H) - return 0 + if(H.movement_type & FLYING) + return TRUE + return FALSE /datum/species/proc/negates_gravity(mob/living/carbon/human/H) - return 0 + if(H.movement_type & FLYING) + return TRUE + return FALSE + +//////////////// +//Blood Stuff/// +//////////////// +// true = handle blood normally, false = do not (and then handle blood in this proc instead please!!) +/datum/species/proc/handle_blood(mob/living/carbon/human/H, delta_time, times_fired) + return TRUE //////////////// //Tail Wagging// @@ -2387,3 +2524,130 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) mutant_bodyparts["spines"] = mutant_bodyparts["waggingspines"] mutant_bodyparts -= "waggingspines" H.update_body() + +/////////////// +//FLIGHT SHIT// +/////////////// + +/datum/species/proc/GiveSpeciesFlight(mob/living/carbon/human/H, all_wings = FALSE) + if(flying_species) //grant them the choice of all wings if they don't have them + all_wings = TRUE + flying_species = TRUE + //CITADEL CHANGE: check if they already have wings, and "evolve" them based off of the wings they have. If they have none, use their species wings basis. + var/list/wingslist + if(all_wings) //give them the full list of wing choices to pick from, typically if they drink a second flight potion + wingslist = SPECIES_WINGS_ALL + else + //why the fuck do we have two different wing types anyways? they're literally almost both using the same wing shit too. + var/datum/sprite_accessory/deco_wings/D = GLOB.deco_wings_list[H.dna.features["deco_wings"]] + var/datum/sprite_accessory/insect_wings/I = GLOB.insect_wings_list[H.dna.features["insect_wings"]] + if(mutant_bodyparts["deco_wings"] && D?.upgrade_to.len) //species check to see if they were allowed to have deco wings + wingslist = D.upgrade_to + else if(mutant_bodyparts["insect_wings"] && I?.upgrade_to.len) //species check to see if they were allowed to have insect wings + wingslist = I.upgrade_to + else + wingslist = wings_icons + + if(wingslist.len > 1) + if(!H.client) + wings_icon = pick(wingslist) + else + var/list/wings = list() + for(var/W in wingslist) + var/datum/sprite_accessory/S = GLOB.wings_list[W] //Gets the datum for every wing this species has, then prompts user with a radial menu + var/image/img = image(icon = 'icons/mob/wings_functional.dmi', icon_state = "m_wingsopen_[S.icon_state]_BEHIND") //Process the HUD elements + img.transform *= 0.5 + img.pixel_x = -32 + if(wings[S.name]) + stack_trace("Different wing types with repeated names. Please fix as this may cause issues.") + else + wings[S.name] = img + wings_icon = show_radial_menu(H, H, wings, tooltips = TRUE) + if(!wings_icon) + wings_icon = pick(wings_icons) + else + wings_icon = wingslist[1] + if(isnull(fly)) + fly = new + fly.Grant(H) + if(H.dna.features["wings"] != wings_icon) + mutant_bodyparts["wings"] = wings_icon + H.dna.features["wings"] = wings_icon + H.update_body() + +/datum/species/proc/HandleFlight(mob/living/carbon/human/H) + if(H.movement_type & FLYING) + if(!CanFly(H)) + ToggleFlight(H) + return FALSE + return TRUE + else + return FALSE + +/datum/species/proc/CanFly(mob/living/carbon/human/H) + if(H.stat || !(H.mobility_flags & MOBILITY_STAND)) + return FALSE + if(H.wear_suit && ((H.wear_suit.flags_inv & HIDEJUMPSUIT) && (!H.wear_suit.species_exception || !is_type_in_list(src, H.wear_suit.species_exception)))) //Jumpsuits have tail holes, so it makes sense they have wing holes too + to_chat(H, "Your suit blocks your wings from extending!") + return FALSE + var/turf/T = get_turf(H) + if(!T) + return FALSE + var/datum/gas_mixture/environment = T.return_air() + if(environment && !(environment.return_pressure() > 30)) + to_chat(H, "The atmosphere is too thin for you to fly!") + return FALSE + else + return TRUE + +/datum/species/proc/flyslip(mob/living/carbon/human/H) + var/obj/buckled_obj + if(H.buckled) + buckled_obj = H.buckled + to_chat(H, "Your wings spazz out and launch you!") + playsound(H.loc, 'sound/misc/slip.ogg', 50, TRUE, -3) + for(var/obj/item/I in H.held_items) + H.accident(I) + var/olddir = H.dir + H.stop_pulling() + if(buckled_obj) + buckled_obj.unbuckle_mob(H) + step(buckled_obj, olddir) + else + new /datum/forced_movement(H, get_ranged_target_turf(H, olddir, 4), 1, FALSE, CALLBACK(H, /mob/living/carbon/.proc/spin, 1, 1)) + return TRUE + +//UNSAFE PROC, should only be called through the Activate or other sources that check for CanFly +/datum/species/proc/ToggleFlight(mob/living/carbon/human/H) + if(!(H.movement_type & FLYING) && CanFly(H)) + stunmod *= 2 + speedmod -= 0.35 + H.setMovetype(H.movement_type | FLYING) + override_float = TRUE + H.pass_flags |= PASSTABLE + H.OpenWings() + H.update_mobility() + else + stunmod *= 0.5 + speedmod += 0.35 + H.setMovetype(H.movement_type & ~FLYING) + override_float = FALSE + H.pass_flags &= ~PASSTABLE + H.CloseWings() + +/datum/action/innate/flight + name = "Toggle Flight" + check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN + icon_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "flight" + +/datum/action/innate/flight/Activate() + var/mob/living/carbon/human/H = owner + var/datum/species/S = H.dna.species + if(S.CanFly(H)) + S.ToggleFlight(H) + if(!(H.movement_type & FLYING)) + to_chat(H, "You settle gently back onto the ground...") + else + to_chat(H, "You beat your wings and begin to hover gently above the ground...") + H.set_resting(FALSE, TRUE) diff --git a/code/modules/mob/living/carbon/human/species_types/android.dm b/code/modules/mob/living/carbon/human/species_types/android.dm index 3c6a2a8e13..d9edfc240d 100644 --- a/code/modules/mob/living/carbon/human/species_types/android.dm +++ b/code/modules/mob/living/carbon/human/species_types/android.dm @@ -12,3 +12,4 @@ species_language_holder = /datum/language_holder/synthetic limbs_id = SPECIES_SYNTH species_category = SPECIES_CATEGORY_ROBOT + wings_icons = SPECIES_WINGS_ROBOT diff --git a/code/modules/mob/living/carbon/human/species_types/angel.dm b/code/modules/mob/living/carbon/human/species_types/angel.dm deleted file mode 100644 index 977e8aaab3..0000000000 --- a/code/modules/mob/living/carbon/human/species_types/angel.dm +++ /dev/null @@ -1,145 +0,0 @@ -/datum/species/angel - name = "Angel" - id = SPECIES_ANGEL - default_color = "FFFFFF" - species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,HAS_FLESH,HAS_BONE) - mutant_bodyparts = list("tail_human" = "None", "ears" = "None", "wings" = "Angel") - use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM - no_equip = list(SLOT_BACK) - blacklisted = 1 - limbs_id = SPECIES_HUMAN - skinned_type = /obj/item/stack/sheet/animalhide/human - species_category = SPECIES_CATEGORY_BASIC //they're a kind of human - - var/datum/action/innate/flight/fly - -/datum/species/angel/on_species_gain(mob/living/carbon/human/H, datum/species/old_species) - ..() - if(H.dna && H.dna.species && (H.dna.features["wings"] != "Angel")) - if(!H.dna.species.mutant_bodyparts["wings"]) - H.dna.species.mutant_bodyparts["wings"] = "Angel" - H.dna.features["wings"] = "Angel" - H.update_body() - if(ishuman(H) && !fly) - fly = new - fly.Grant(H) - ADD_TRAIT(H, TRAIT_HOLY, SPECIES_TRAIT) - -/datum/species/angel/on_species_loss(mob/living/carbon/human/H) - if(fly) - fly.Remove(H) - if(H.movement_type & FLYING) - H.setMovetype(H.movement_type & ~FLYING) - ToggleFlight(H,0) - if(H.dna && H.dna.species && (H.dna.features["wings"] == "Angel")) - if(H.dna.species.mutant_bodyparts["wings"]) - H.dna.species.mutant_bodyparts -= "wings" - H.dna.features["wings"] = "None" - H.update_body() - REMOVE_TRAIT(H, TRAIT_HOLY, SPECIES_TRAIT) - ..() - -/datum/species/angel/spec_life(mob/living/carbon/human/H) - HandleFlight(H) - -/datum/species/angel/proc/HandleFlight(mob/living/carbon/human/H) - if(H.movement_type & FLYING) - if(!CanFly(H)) - ToggleFlight(H,0) - return 0 - return 1 - else - return 0 - -/datum/species/angel/proc/CanFly(mob/living/carbon/human/H) - if(!CHECK_MOBILITY(H, MOBILITY_MOVE)) - return FALSE - if(H.wear_suit && ((H.wear_suit.flags_inv & HIDEJUMPSUIT) && (!H.wear_suit.species_exception || !is_type_in_list(src, H.wear_suit.species_exception)))) //Jumpsuits have tail holes, so it makes sense they have wing holes too - to_chat(H, "Your suit blocks your wings from extending!") - return FALSE - var/turf/T = get_turf(H) - if(!T) - return FALSE - - var/datum/gas_mixture/environment = T.return_air() - if(environment && !(environment.return_pressure() > 30)) - to_chat(H, "The atmosphere is too thin for you to fly!") - return FALSE - return TRUE - -/datum/action/innate/flight - name = "Toggle Flight" - check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN - icon_icon = 'icons/mob/actions/actions_items.dmi' - button_icon_state = "flight" - -/datum/action/innate/flight/Activate() - var/mob/living/carbon/human/H = owner - var/datum/species/angel/A = H.dna.species - if(A.CanFly(H)) - if(H.movement_type & FLYING) - to_chat(H, "You settle gently back onto the ground...") - A.ToggleFlight(H,0) - H.update_mobility() - else - to_chat(H, "You beat your wings and begin to hover gently above the ground...") - H.set_resting(FALSE, TRUE) - A.ToggleFlight(H,1) - H.update_mobility() - -/datum/species/angel/proc/flyslip(mob/living/carbon/human/H) - var/obj/buckled_obj - if(H.buckled) - buckled_obj = H.buckled - - to_chat(H, "Your wings spazz out and launch you!") - - playsound(H.loc, 'sound/misc/slip.ogg', 50, 1, -3) - - for(var/obj/item/I in H.held_items) - H.accident(I) - - var/olddir = H.dir - - H.stop_pulling() - if(buckled_obj) - buckled_obj.unbuckle_mob(H) - step(buckled_obj, olddir) - else - for(var/i=1, i<5, i++) - spawn (i) - step(H, olddir) - H.spin(1,1) - return 1 - - -/datum/species/angel/spec_stun(mob/living/carbon/human/H,amount) - if(H.movement_type & FLYING) - ToggleFlight(H,0) - flyslip(H) - . = ..() - -/datum/species/angel/negates_gravity(mob/living/carbon/human/H) - if(H.movement_type & FLYING) - return 1 - -/datum/species/angel/space_move(mob/living/carbon/human/H) - if(H.movement_type & FLYING) - return 1 - -/datum/species/angel/proc/ToggleFlight(mob/living/carbon/human/H,flight) - if(flight && CanFly(H)) - stunmod = 2 - speedmod = -0.1 - H.setMovetype(H.movement_type | FLYING) - override_float = TRUE - H.pass_flags |= PASSTABLE - H.OpenWings() - else - stunmod = 1 - speedmod = 0 - H.setMovetype(H.movement_type & ~FLYING) - override_float = FALSE - H.pass_flags &= ~PASSTABLE - H.CloseWings() - update_species_slowdown(H) diff --git a/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm b/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm index 95cb9cca59..c9af50de9d 100644 --- a/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm +++ b/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm @@ -24,11 +24,18 @@ id = SPECIES_MAMMAL_SYNTHETIC species_traits = list(MUTCOLORS,NOTRANSSTING,EYECOLOR,LIPS,HAIR,ROBOTIC_LIMBS,HAS_FLESH,HAS_BONE,WINGCOLOR,HORNCOLOR) - inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM) + inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM, TRAIT_RESISTLOWPRESSURE, TRAIT_NOBREATH, TRAIT_AUXILIARY_LUNGS) inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID|MOB_BEAST meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless) + + coldmod = 0.5 + heatmod = 1.2 + cold_offset = SYNTH_COLD_OFFSET //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas + blacklisted_quirks = list(/datum/quirk/coldblooded) + balance_point_values = TRUE + //Just robo looking parts. mutant_heart = /obj/item/organ/heart/ipc mutantlungs = /obj/item/organ/lungs/ipc @@ -47,4 +54,8 @@ attack_sound = 'sound/weapons/slash.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' + exotic_bloodtype = "S" + exotic_blood_color = BLOOD_COLOR_OIL allowed_limb_ids = list("mammal","aquatic","avian", "human") + species_category = SPECIES_CATEGORY_ROBOT + wings_icons = SPECIES_WINGS_ROBOT diff --git a/code/modules/mob/living/carbon/human/species_types/arachnid.dm b/code/modules/mob/living/carbon/human/species_types/arachnid.dm index 454625cf36..819f347353 100644 --- a/code/modules/mob/living/carbon/human/species_types/arachnid.dm +++ b/code/modules/mob/living/carbon/human/species_types/arachnid.dm @@ -7,7 +7,7 @@ species_traits = list(LIPS, NOEYES, NO_UNDERWEAR, HAS_FLESH, HAS_BONE) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG mutant_bodyparts = list("arachnid_legs" = "Plain", "arachnid_spinneret" = "Plain", "arachnid_mandibles" = "Plain") - attack_verb = "slash" + attack_verb = "claw" attack_sound = 'sound/weapons/slash.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' meat = /obj/item/reagent_containers/food/snacks/meat/slab/spider @@ -21,6 +21,7 @@ var/web_cooldown = 200 var/web_ready = TRUE var/spinner_rate = 25 + wings_icons = SPECIES_WINGS_MOTH //Arachnids' phylum is arthropods, which include butterflies. Might as well hit them with moth wings. /datum/species/arachnid/random_name(gender,unique,lastname) if(unique) @@ -91,7 +92,7 @@ var/nutrition_threshold = NUTRITION_LEVEL_FED if (H.nutrition >= nutrition_threshold) to_chat(H, "You begin spinning some web...") - if(!do_after(H, 10 SECONDS, 1, T)) + if(!do_after(H, 10 SECONDS, T)) to_chat(H, "Your web spinning was interrupted!") return H.adjust_nutrition(-E.spinner_rate) @@ -151,7 +152,7 @@ to_chat(H, "You cannot wrap this.") return H.visible_message("[H] starts to wrap [A] into a cocoon!","You start to wrap [A] into a cocoon.") - if(!do_after(H, 10 SECONDS, 1, A)) + if(!do_after(H, 10 SECONDS, A)) to_chat(H, "Your web spinning was interrupted!") return H.adjust_nutrition(E.spinner_rate * -3) diff --git a/code/modules/mob/living/carbon/human/species_types/bugmen.dm b/code/modules/mob/living/carbon/human/species_types/bugmen.dm index f87f425b5f..1e58e995c2 100644 --- a/code/modules/mob/living/carbon/human/species_types/bugmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/bugmen.dm @@ -7,7 +7,7 @@ inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG mutant_bodyparts = list("mcolor" = "FFFFFF","mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "insect_wings" = "None", "insect_fluff" = "None", "mam_snouts" = "None", "taur" = "None", "insect_markings" = "None", "mam_body_markings" = list()) - attack_verb = "slash" + attack_verb = "claw" attack_sound = 'sound/weapons/slash.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/insect @@ -19,7 +19,12 @@ tail_type = "mam_tail" wagging_type = "mam_waggingtail" species_category = SPECIES_CATEGORY_INSECT + wings_icons = SPECIES_WINGS_INSECT allowed_limb_ids = list("insect","apid","moth","moth_not_greyscale") eye_type = "insect" + + family_heirlooms = list( + /obj/item/flashlight/lantern/heirloom_moth + ) diff --git a/code/modules/mob/living/carbon/human/species_types/corporate.dm b/code/modules/mob/living/carbon/human/species_types/corporate.dm index e9baa786da..48b5032129 100644 --- a/code/modules/mob/living/carbon/human/species_types/corporate.dm +++ b/code/modules/mob/living/carbon/human/species_types/corporate.dm @@ -19,3 +19,4 @@ sexes = 0 gib_types = /obj/effect/gibspawner/robot species_category = SPECIES_CATEGORY_ROBOT + wings_icons = SPECIES_WINGS_ROBOT diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm deleted file mode 100644 index 0418292fea..0000000000 --- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm +++ /dev/null @@ -1,164 +0,0 @@ -/datum/species/dullahan - name = "Dullahan" - id = SPECIES_DULLAHAN - default_color = "FFFFFF" - species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,HAS_FLESH,HAS_BONE) - inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH) - mutant_bodyparts = list("tail_human" = "None", "ears" = "None", "deco_wings" = "None") - use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM - mutant_brain = /obj/item/organ/brain/dullahan - mutanteyes = /obj/item/organ/eyes/dullahan - mutanttongue = /obj/item/organ/tongue/dullahan - mutantears = /obj/item/organ/ears/dullahan - blacklisted = TRUE - limbs_id = SPECIES_HUMAN - skinned_type = /obj/item/stack/sheet/animalhide/human - has_field_of_vision = FALSE //Too much of a trouble, their vision is already bound to their severed head. - species_category = SPECIES_CATEGORY_UNDEAD - var/pumpkin = FALSE - - var/obj/item/dullahan_relay/myhead - -/datum/species/dullahan/pumpkin - name = "Pumpkin Head Dullahan" - id = "pumpkindullahan" - pumpkin = TRUE - -/datum/species/dullahan/check_roundstart_eligible() - if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) - return TRUE - return ..() - -/datum/species/dullahan/on_species_gain(mob/living/carbon/human/H, datum/species/old_species) - . = ..() - DISABLE_BITFIELD(H.flags_1, HEAR_1) - var/obj/item/bodypart/head/head = H.get_bodypart(BODY_ZONE_HEAD) - if(head) - if(pumpkin)//Pumpkinhead! - head.animal_origin = 100 - head.icon = 'icons/obj/clothing/hats.dmi' - head.icon_state = "hardhat1_pumpkin_j" - head.custom_head = TRUE - head.drop_limb() - if(!QDELETED(head)) //drop_limb() deletes the limb if it's no drop location and dummy humans used for rendering icons are located in nullspace. Do the math. - head.throwforce = 25 - myhead = new /obj/item/dullahan_relay (head, H) - H.put_in_hands(head) - var/obj/item/organ/eyes/E = H.getorganslot(ORGAN_SLOT_EYES) - for(var/datum/action/item_action/organ_action/OA in E.actions) - OA.Trigger() - -/datum/species/dullahan/on_species_loss(mob/living/carbon/human/H) - ENABLE_BITFIELD(H.flags_1, HEAR_1) - H.reset_perspective(H) - if(myhead) - var/obj/item/dullahan_relay/DR = myhead - myhead = null - DR.owner = null - qdel(DR) - H.regenerate_limb(BODY_ZONE_HEAD,FALSE) - ..() - -/datum/species/dullahan/spec_life(mob/living/carbon/human/H) - if(QDELETED(myhead)) - myhead = null - H.gib() - var/obj/item/bodypart/head/head2 = H.get_bodypart(BODY_ZONE_HEAD) - if(head2) - myhead = null - H.gib() - -/datum/species/dullahan/proc/update_vision_perspective(mob/living/carbon/human/H) - var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES) - if(eyes) - H.update_tint() - if(eyes.tint) - H.reset_perspective(H) - else - H.reset_perspective(myhead) - -/obj/item/organ/brain/dullahan - decoy_override = TRUE - organ_flags = ORGAN_NO_SPOIL//Do not decay - -/obj/item/organ/tongue/dullahan - zone = "abstract" - accents = list(/datum/accent/dullahan) - -/obj/item/organ/ears/dullahan - zone = "abstract" - -/obj/item/organ/eyes/dullahan - name = "head vision" - desc = "An abstraction." - actions_types = list(/datum/action/item_action/organ_action/dullahan) - zone = "abstract" - tint = INFINITY // used to switch the vision perspective to the head on species_gain(). - -/datum/action/item_action/organ_action/dullahan - name = "Toggle Perspective" - desc = "Switch between seeing normally from your head, or blindly from your body." - -/datum/action/item_action/organ_action/dullahan/Trigger() - . = ..() - var/obj/item/organ/eyes/dullahan/DE = target - if(DE.tint) - DE.tint = 0 - else - DE.tint = INFINITY - - if(ishuman(owner)) - var/mob/living/carbon/human/H = owner - if(isdullahan(H)) - var/datum/species/dullahan/D = H.dna.species - D.update_vision_perspective(H) - -/obj/item/dullahan_relay - name = "dullahan relay" - var/mob/living/owner - flags_1 = HEAR_1 - -/obj/item/dullahan_relay/Initialize(mapload, mob/living/carbon/human/new_owner) - . = ..() - if(!new_owner) - return INITIALIZE_HINT_QDEL - owner = new_owner - START_PROCESSING(SSobj, src) - RegisterSignal(owner, COMSIG_MOB_CLICKED_SHIFT_ON, .proc/examinate_check) - RegisterSignal(src, COMSIG_ATOM_HEARER_IN_VIEW, .proc/include_owner) - RegisterSignal(owner, COMSIG_LIVING_REGENERATE_LIMBS, .proc/unlist_head) - RegisterSignal(owner, COMSIG_LIVING_REVIVE, .proc/retrieve_head) - -/obj/item/dullahan_relay/proc/examinate_check(mob/source, atom/target) - if(source.client.eye == src) - return COMPONENT_ALLOW_EXAMINATE - -/obj/item/dullahan_relay/proc/include_owner(datum/source, list/processing_list, list/hearers) - if(!QDELETED(owner)) - hearers += owner - -/obj/item/dullahan_relay/proc/unlist_head(datum/source, noheal = FALSE, list/excluded_limbs) - excluded_limbs |= BODY_ZONE_HEAD // So we don't gib when regenerating limbs. - -//Retrieving the owner's head for better ahealing. -/obj/item/dullahan_relay/proc/retrieve_head(datum/source, full_heal, admin_revive) - if(admin_revive) - var/obj/item/bodypart/head/H = loc - var/turf/T = get_turf(owner) - if(H && istype(H) && T && !(H in owner.GetAllContents())) - H.forceMove(T) - -/obj/item/dullahan_relay/process() - if(!istype(loc, /obj/item/bodypart/head) || QDELETED(owner)) - . = PROCESS_KILL - qdel(src) - -/obj/item/dullahan_relay/Destroy() - if(!QDELETED(owner)) - var/mob/living/carbon/human/H = owner - if(isdullahan(H)) - var/datum/species/dullahan/D = H.dna.species - D.myhead = null - owner.gib() - owner = null - ..() diff --git a/code/modules/mob/living/carbon/human/species_types/dwarves.dm b/code/modules/mob/living/carbon/human/species_types/dwarves.dm index e0a9bcaa36..2820726313 100644 --- a/code/modules/mob/living/carbon/human/species_types/dwarves.dm +++ b/code/modules/mob/living/carbon/human/species_types/dwarves.dm @@ -20,6 +20,11 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) // species_language_holder = /datum/language_holder/dwarf species_category = SPECIES_CATEGORY_BASIC //a kind of human + family_heirlooms = list( + // Dwarves get a dwarf mug as their heirloom (normal container but has manly dorf icon) + /obj/item/reagent_containers/food/drinks/dwarf_mug + ) + /mob/living/carbon/human/species/dwarf //species admin spawn path race = /datum/species/dwarf //and the race the path is set to. 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 ae7a7546e1..8a1c8707fa 100644 --- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm +++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm @@ -153,7 +153,7 @@ var/static/mutable_appearance/overcharge //shameless copycode from lightning spell overcharge = overcharge || mutable_appearance('icons/effects/effects.dmi', "electricity", EFFECTS_LAYER) H.add_overlay(overcharge) - if(do_mob(H, H, 50, 1)) + if(do_after(H, 5 SECONDS, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_HELD_ITEM|IGNORE_INCAPACITATED))) H.flash_lighting_fx(5, 7, current_color) var/obj/item/organ/stomach/ethereal/stomach = H.getorganslot(ORGAN_SLOT_STOMACH) playsound(H, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5) @@ -169,7 +169,6 @@ to_chat(H, "You're pretty sure you just felt your heart stop for a second there..") H.playsound_local(H, 'sound/effects/singlebeat.ogg', 100, 0) H.Paralyze(100) - return /datum/species/ethereal/proc/get_charge(mob/living/carbon/H) //this feels like it should be somewhere else. Eh? var/obj/item/organ/stomach/ethereal/stomach = H.getorganslot(ORGAN_SLOT_STOMACH) 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 eee5757b46..beebbb1dfd 100644 --- a/code/modules/mob/living/carbon/human/species_types/felinid.dm +++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm @@ -13,6 +13,7 @@ wagging_type = "mam_waggingtail" species_category = SPECIES_CATEGORY_FURRY ass_image = 'icons/ass/asscat.png' + family_heirlooms = list(/obj/item/toy/cattoy) /datum/species/human/felinid/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load) if(ishuman(C)) diff --git a/code/modules/mob/living/carbon/human/species_types/flypeople.dm b/code/modules/mob/living/carbon/human/species_types/flypeople.dm index 5a185cbeb8..86720289fe 100644 --- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm @@ -13,6 +13,7 @@ exotic_bloodtype = "BUG" exotic_blood_color = BLOOD_COLOR_BUG species_category = SPECIES_CATEGORY_INSECT + wings_icons = SPECIES_WINGS_INSECT /datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H) if(istype(chem, /datum/reagent/toxin/pestkiller)) diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index fba6ecd40c..843b47b4a0 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -12,7 +12,7 @@ punchdamagelow = 5 punchdamagehigh = 14 punchstunthreshold = 10 - no_equip = list(SLOT_WEAR_MASK, SLOT_WEAR_SUIT, SLOT_GLOVES, SLOT_SHOES, SLOT_W_UNIFORM, SLOT_S_STORE) + no_equip = list(ITEM_SLOT_MASK, ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING, ITEM_SLOT_SUITSTORE) nojumpsuit = 1 sexes = 1 damage_overlay_type = "" @@ -214,11 +214,11 @@ /datum/species/golem/titanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() - C.weather_immunities |= "ash" + ADD_TRAIT(C, TRAIT_ASHSTORM_IMMUNE, SPECIES_TRAIT) /datum/species/golem/titanium/on_species_loss(mob/living/carbon/C) . = ..() - C.weather_immunities -= "ash" + REMOVE_TRAIT(C, TRAIT_ASHSTORM_IMMUNE, SPECIES_TRAIT) //Immune to ash storms and lava /datum/species/golem/plastitanium @@ -233,13 +233,13 @@ /datum/species/golem/plastitanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() - C.weather_immunities |= "lava" - C.weather_immunities |= "ash" + ADD_TRAIT(C, TRAIT_LAVA_IMMUNE, SPECIES_TRAIT) + ADD_TRAIT(C, TRAIT_ASHSTORM_IMMUNE, SPECIES_TRAIT) /datum/species/golem/plastitanium/on_species_loss(mob/living/carbon/C) . = ..() - C.weather_immunities -= "ash" - C.weather_immunities -= "lava" + REMOVE_TRAIT(C, TRAIT_LAVA_IMMUNE, SPECIES_TRAIT) + REMOVE_TRAIT(C, TRAIT_ASHSTORM_IMMUNE, SPECIES_TRAIT) //Fast and regenerates... but can only speak like an abductor /datum/species/golem/alloy @@ -347,7 +347,7 @@ /datum/species/golem/sand/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) if(!(P.original == H && P.firer == H)) - if(P.flag == "bullet" || P.flag == "bomb") + if(P.flag == BULLET || P.flag == BOMB) playsound(H, 'sound/effects/shovel_dig.ogg', 70, 1) H.visible_message("The [P.name] sinks harmlessly in [H]'s sandy body!", \ "The [P.name] sinks harmlessly in [H]'s sandy body!") @@ -379,7 +379,7 @@ /datum/species/golem/glass/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) if(!(P.original == H && P.firer == H)) //self-shots don't reflect - if(P.flag == "laser" || P.flag == "energy") + if(P.flag == LASER || P.flag == ENERGY) H.visible_message("The [P.name] gets reflected by [H]'s glass skin!", \ "The [P.name] gets reflected by [H]'s glass skin!") if(P.starting) @@ -741,7 +741,7 @@ name = "pile of bandages" desc = "It emits a strange aura, as if there was still life within it..." max_integrity = 50 - armor = list("melee" = 90, "bullet" = 90, "laser" = 25, "energy" = 80, "bomb" = 50, "bio" = 100, "fire" = -50, "acid" = -50) + armor = list(MELEE = 90, BULLET = 90, LASER = 25, ENERGY = 80, BOMB = 50, BIO = 100, FIRE = -50, ACID = -50) icon = 'icons/obj/items_and_weapons.dmi' icon_state = "pile_bandages" resistance_flags = FLAMMABLE @@ -807,11 +807,11 @@ /datum/species/golem/plastic/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() - C.AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) + C.AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_NUDE) /datum/species/golem/plastic/on_species_loss(mob/living/carbon/C) . = ..() - C.RemoveElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) + C.RemoveElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_NUDE) /datum/species/golem/bronze name = "Bronze Golem" @@ -829,7 +829,7 @@ /datum/species/golem/bronze/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) if(!(world.time > last_gong_time + gong_cooldown)) return ..() - if(P.flag == "bullet" || P.flag == "bomb") + if(P.flag == BULLET || P.flag == BOMB) gong(H) return ..() diff --git a/code/modules/mob/living/carbon/human/species_types/ipc.dm b/code/modules/mob/living/carbon/human/species_types/ipc.dm index eb870f9624..f6749dde06 100644 --- a/code/modules/mob/living/carbon/human/species_types/ipc.dm +++ b/code/modules/mob/living/carbon/human/species_types/ipc.dm @@ -5,14 +5,20 @@ default_color = "00FF00" blacklisted = 0 sexes = 0 - inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM) + inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM, TRAIT_RESISTLOWPRESSURE, TRAIT_NOBREATH, TRAIT_AUXILIARY_LUNGS) species_traits = list(MUTCOLORS,NOEYES,NOTRANSSTING,HAS_FLESH,HAS_BONE,HAIR,ROBOTIC_LIMBS) hair_alpha = 210 inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID - mutant_bodyparts = list("ipc_screen" = "Blank", "ipc_antenna" = "None") + mutant_bodyparts = list("ipc_screen" = "Blank", "deco_wings" = "None", "ipc_antenna" = "None") meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless) + coldmod = 0.5 + heatmod = 1.2 + cold_offset = SYNTH_COLD_OFFSET //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas + blacklisted_quirks = list(/datum/quirk/coldblooded) + balance_point_values = TRUE + //Just robo looking parts. mutant_heart = /obj/item/organ/heart/ipc mutantlungs = /obj/item/organ/lungs/ipc @@ -26,9 +32,15 @@ //special cybernetic organ for getting power from apcs mutant_organs = list(/obj/item/organ/cyberimp/arm/power_cord) - exotic_bloodtype = "HF" + exotic_bloodtype = "S" exotic_blood_color = BLOOD_COLOR_OIL species_category = SPECIES_CATEGORY_ROBOT + wings_icons = SPECIES_WINGS_ROBOT + + family_heirlooms = list( + // Gives a broken powercell for flavor text! + /obj/item/stock_parts/cell/family + ) var/datum/action/innate/monitor_change/screen diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index 04c69a4138..e8042dfac9 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -17,6 +17,7 @@ exotic_blood = /datum/reagent/blood/jellyblood exotic_bloodtype = "GEL" exotic_blood_color = "BLOOD_COLOR_SLIME" + exotic_blood_blend_mode = BLEND_DEFAULT damage_overlay_type = "" liked_food = TOXIC | MEAT disliked_food = null @@ -29,7 +30,13 @@ tail_type = "mam_tail" wagging_type = "mam_waggingtail" species_category = SPECIES_CATEGORY_JELLY + wings_icons = SPECIES_WINGS_JELLY ass_image = 'icons/ass/assslime.png' + blacklisted_quirks = list(/datum/quirk/glass_bones) + + family_heirlooms = list( + /obj/item/toy/plush/slimeplushie + ) /datum/species/jelly/on_species_loss(mob/living/carbon/C) C.faction -= "slime" @@ -52,37 +59,46 @@ //update blood color to body color exotic_blood_color = "#" + H.dna.features["mcolor"] -/datum/species/jelly/spec_life(mob/living/carbon/human/H) - if(H.stat == DEAD || HAS_TRAIT(H, TRAIT_NOMARROW)) //can't farm slime jelly from a dead slime/jelly person indefinitely, and no regeneration for bloodsuckers - return - if(!H.blood_volume) - H.adjust_integration_blood(5) - H.adjustBruteLoss(5) - to_chat(H, "You feel empty!") +/datum/species/jelly/handle_blood(mob/living/carbon/human/H, delta_time, times_fired) + if(H.stat == DEAD) //can't farm slime jelly from a dead slime/jelly person indefinitely + return TRUE // we dont handle blood when dead - if(H.blood_volume < (BLOOD_VOLUME_NORMAL * H.blood_ratio)) + if(H.blood_volume <= 0) + H.blood_volume += 2.5 * delta_time + H.adjustBruteLoss(2.5 * delta_time) + to_chat(H, span_danger("You feel empty!")) + + if(H.blood_volume < BLOOD_VOLUME_NORMAL) if(H.nutrition >= NUTRITION_LEVEL_STARVING) - H.adjust_integration_blood(3) - H.nutrition -= 2.5 - if(H.blood_volume < (BLOOD_VOLUME_OKAY*H.blood_ratio)) - if(prob(5)) - to_chat(H, "You feel drained!") - if(H.blood_volume < (BLOOD_VOLUME_BAD*H.blood_ratio)) + H.blood_volume += 1.5 * delta_time + H.adjust_nutrition(-1.25 * delta_time) + + if(H.blood_volume < BLOOD_VOLUME_OKAY) + if(DT_PROB(2.5, delta_time)) + to_chat(H, span_danger("You feel drained!")) + + if(H.blood_volume < BLOOD_VOLUME_BAD) Cannibalize_Body(H) + var/datum/action/innate/ability/regrowth = H.ability_actions[INNATE_ABILITY_LIMB_REGROWTH] + if(regrowth) + regrowth.UpdateButtonIcon() + + return FALSE // to let living/handle_blood know that the species is handling blood instead + /datum/species/jelly/proc/Cannibalize_Body(mob/living/carbon/human/H) var/list/limbs_to_consume = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) - H.get_missing_limbs() var/obj/item/bodypart/consumed_limb - if(!limbs_to_consume.len) + if(!length(limbs_to_consume)) H.losebreath++ return if(H.get_num_legs(FALSE)) //Legs go before arms limbs_to_consume -= list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM) consumed_limb = H.get_bodypart(pick(limbs_to_consume)) consumed_limb.drop_limb() - to_chat(H, "Your [consumed_limb] is drawn back into your body, unable to maintain its shape!") + to_chat(H, span_userdanger("Your [consumed_limb] is drawn back into your body, unable to maintain its shape!")) qdel(consumed_limb) - H.adjust_integration_blood(20) + H.blood_volume += 20 ////////////////////////////////////////////////////////SLIMEPEOPLE/////////////////////////////////////////////////////////////////// @@ -182,7 +198,7 @@ H.mob_transforming = TRUE - if(do_after(owner, delay=60, needhand=FALSE, target=owner, progress=TRUE)) + if(do_after(owner, 6 SECONDS, owner)) if(H.blood_volume >= BLOOD_VOLUME_SLIME_SPLIT) make_dupe() else @@ -404,14 +420,14 @@ default_color = "00FFFF" species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,HAS_FLESH) inherent_traits = list(TRAIT_TOXINLOVER) - mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None", "legs" = "Plantigrade") + mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None", "legs" = "Plantigrade") say_mod = "says" hair_color = "mutcolor" hair_alpha = 160 //a notch brighter so it blends better. coldmod = 3 heatmod = 1 burnmod = 1 - + balance_point_values = TRUE allowed_limb_ids = list(SPECIES_SLIME,SPECIES_STARGAZER,SPECIES_SLIME_LUMI) ///////////////////////////////////LUMINESCENTS////////////////////////////////////////// @@ -472,7 +488,7 @@ light_color = "#FFFFFF" light_range = LUMINESCENT_DEFAULT_GLOW -/obj/effect/dummy/luminescent_glow/Initialize() +/obj/effect/dummy/luminescent_glow/Initialize(mapload) . = ..() if(!isliving(loc)) return INITIALIZE_HINT_QDEL diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index 07fa78a88a..ffdc23a5a7 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -13,7 +13,7 @@ mutant_bodyparts = list("mcolor" = "0F0", "mcolor2" = "0F0", "mcolor3" = "0F0", "tail_lizard" = "Smooth", "mam_snouts" = "Round", "horns" = "None", "frills" = "None", "spines" = "None", "mam_body_markings" = list(), "legs" = "Digitigrade", "taur" = "None", "deco_wings" = "None") - attack_verb = "slash" + attack_verb = "claw" attack_sound = 'sound/weapons/slash.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard @@ -29,9 +29,14 @@ tail_type = "tail_lizard" wagging_type = "waggingtail_lizard" species_category = SPECIES_CATEGORY_LIZARD + wings_icons = SPECIES_WINGS_DRAGON ass_image = 'icons/ass/asslizard.png' + family_heirlooms = list( + /obj/item/toy/plush/lizardplushie + ) + /datum/species/lizard/random_name(gender,unique,lastname) if(unique) return random_unique_lizard_name(gender) diff --git a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm index 0655b28197..afcec291e9 100644 --- a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm @@ -16,7 +16,7 @@ punchdamagehigh = 12 //still better than humans punchstunthreshold = 10 - no_equip = list(SLOT_WEAR_MASK, SLOT_WEAR_SUIT, SLOT_GLOVES, SLOT_SHOES, SLOT_W_UNIFORM) + no_equip = list(ITEM_SLOT_MASK, ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING) burnmod = 1.25 heatmod = 1.5 diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 547d017c23..3b7ca3fa0a 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -23,8 +23,11 @@ outfit_important_for_life = /datum/outfit/plasmaman species_category = SPECIES_CATEGORY_SKELETON + wings_icons = SPECIES_WINGS_SKELETAL ass_image = 'icons/ass/assplasma.png' + balance_point_values = TRUE + blacklisted_quirks = list(/datum/quirk/paper_skin) /datum/species/plasmaman/spec_life(mob/living/carbon/human/H) var/datum/gas_mixture/environment = H.loc.return_air() diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm index ed0fa9ae87..d2c4aab157 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -4,7 +4,7 @@ id = SPECIES_POD default_color = "59CE00" species_traits = list(MUTCOLORS,EYECOLOR,CAN_SCAR,HAS_FLESH,HAS_BONE) - attack_verb = "slash" + attack_verb = "claw" attack_sound = 'sound/weapons/slice.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' burnmod = 1.25 diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm index 4c82a25b4b..812ae12955 100644 --- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm @@ -16,6 +16,7 @@ mutanteyes = /obj/item/organ/eyes/night_vision species_category = SPECIES_CATEGORY_SHADOW + wings_icons = SPECIES_WINGS_SKELETAL //not sure what's more spooky for these guys - skeleton or dragon? /datum/species/shadow/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() @@ -36,7 +37,7 @@ limbs_id = SPECIES_SHADOW burnmod = 1.5 blacklisted = TRUE - no_equip = list(SLOT_WEAR_MASK, SLOT_WEAR_SUIT, SLOT_GLOVES, SLOT_SHOES, SLOT_W_UNIFORM, SLOT_S_STORE) + no_equip = list(ITEM_SLOT_MASK, ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING, ITEM_SLOT_SUITSTORE) species_traits = list(NOBLOOD,NO_UNDERWEAR,NO_DNA_COPY,NOTRANSSTING,NOEYES,NOGENITALS,NOAROUSAL) inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_CHUNKYFINGERS,TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER) mutanteyes = /obj/item/organ/eyes/night_vision/nightmare @@ -167,7 +168,7 @@ sharpness = SHARP_EDGED total_mass = TOTAL_MASS_HAND_REPLACEMENT -/obj/item/light_eater/Initialize() +/obj/item/light_eater/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) AddComponent(/datum/component/butchering, 80, 70) @@ -210,7 +211,7 @@ visible_message("[S] is disintegrated by [src]!") else if(AM.light_range && AM.light_power && !(istype(AM, /obj/machinery/power/apc) || istype(AM, /obj/machinery/airalarm))) var/obj/target_object = AM - target_object.take_damage(force * 5, BRUTE, "melee", 0) + target_object.take_damage(force * 5, BRUTE, MELEE, 0) /obj/item/light_eater/proc/disintegrate(obj/item/O) diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm index 8175f505fa..0cd39f8128 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -16,6 +16,9 @@ burnmod = 1.25 species_category = SPECIES_CATEGORY_SKELETON //they have their own category that's disassociated from undead, paired with plasmapeople + wings_icons = SPECIES_WINGS_SKELETAL + balance_point_values = TRUE + blacklisted_quirks = list(/datum/quirk/paper_skin) /datum/species/skeleton/New() if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) //skeletons are stronger during the spooky season! @@ -34,6 +37,7 @@ id = SPECIES_SKELETON_SPACE limbs_id = SPECIES_SKELETON blacklisted = 1 + balance_point_values = FALSE inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT, TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER) /datum/species/skeleton/space/check_roundstart_eligible() diff --git a/code/modules/mob/living/carbon/human/species_types/synthliz.dm b/code/modules/mob/living/carbon/human/species_types/synthliz.dm index b6a7e93c72..a209da270f 100644 --- a/code/modules/mob/living/carbon/human/species_types/synthliz.dm +++ b/code/modules/mob/living/carbon/human/species_types/synthliz.dm @@ -4,11 +4,18 @@ say_mod = "beeps" default_color = "00FF00" species_traits = list(MUTCOLORS,NOTRANSSTING,EYECOLOR,LIPS,HAIR,ROBOTIC_LIMBS,HAS_FLESH,HAS_BONE) - inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM) + inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM, TRAIT_RESISTLOWPRESSURE, TRAIT_NOBREATH, TRAIT_AUXILIARY_LUNGS) inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID mutant_bodyparts = list("ipc_antenna" = "Synthetic Lizard - Antennae","mam_tail" = "Synthetic Lizard", "mam_snouts" = "Synthetic Lizard - Snout", "legs" = "Digitigrade", "mam_body_markings" = "Synthetic Lizard - Plates", "taur" = "None") meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless) + + coldmod = 0.5 + heatmod = 1.2 + cold_offset = SYNTH_COLD_OFFSET //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas + blacklisted_quirks = list(/datum/quirk/coldblooded) + balance_point_values = TRUE + //Just robo looking parts. mutant_heart = /obj/item/organ/heart/ipc mutantlungs = /obj/item/organ/lungs/ipc @@ -28,3 +35,9 @@ tail_type = "mam_tail" wagging_type = "mam_waggingtail" species_category = SPECIES_CATEGORY_ROBOT + wings_icons = SPECIES_WINGS_ROBOT + + family_heirlooms = list( + // They're also robots + /obj/item/stock_parts/cell/family + ) diff --git a/code/modules/mob/living/carbon/human/species_types/synths.dm b/code/modules/mob/living/carbon/human/species_types/synths.dm index 91711b5c39..316b129ee8 100644 --- a/code/modules/mob/living/carbon/human/species_types/synths.dm +++ b/code/modules/mob/living/carbon/human/species_types/synths.dm @@ -18,6 +18,7 @@ var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged species_language_holder = /datum/language_holder/synthetic species_category = SPECIES_CATEGORY_ROBOT + wings_icons = SPECIES_WINGS_ROBOT /datum/species/synth/military name = "Military Synth" 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 e708835ed1..3e54a4e638 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -15,8 +15,10 @@ skinned_type = /obj/item/stack/sheet/animalhide/human var/info_text = "You are a Vampire. You will slowly but constantly lose blood if outside of a coffin. If inside a coffin, you will slowly heal. You may gain more blood by grabbing a live victim and using your drain ability." species_category = SPECIES_CATEGORY_UNDEAD + wings_icons = SPECIES_WINGS_DRAGON //closest to "bat" wings. var/batform_enabled = TRUE + /datum/species/vampire/roundstart id = SPECIES_VAMPIRE_WEAK batform_enabled = FALSE diff --git a/code/modules/mob/living/carbon/human/species_types/xeno.dm b/code/modules/mob/living/carbon/human/species_types/xeno.dm index e9d9aa2d5b..3d710988e5 100644 --- a/code/modules/mob/living/carbon/human/species_types/xeno.dm +++ b/code/modules/mob/living/carbon/human/species_types/xeno.dm @@ -6,7 +6,7 @@ default_color = "00FF00" species_traits = list(MUTCOLORS,EYECOLOR,LIPS,CAN_SCAR,HAS_FLESH,HAS_BONE) mutant_bodyparts = list("xenotail"="Xenomorph Tail","xenohead"="Standard","xenodorsal"="Standard", "mam_body_markings" = list(),"mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0","taur" = "None", "legs" = "Digitigrade","deco_wings"= "None") - attack_verb = "slash" + attack_verb = "claw" attack_sound = 'sound/weapons/slash.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno @@ -14,5 +14,7 @@ skinned_type = /obj/item/stack/sheet/animalhide/xeno exotic_bloodtype = "X*" damage_overlay_type = "xeno" - liked_food = MEAT + disliked_food = null + liked_food = GROSS | MEAT species_category = SPECIES_CATEGORY_ALIEN + wings_icons = SPECIES_WINGS_DRAGON //most depictions of xenomorphs with wings are closest to this. diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index 57a11481d7..0dc08eeedb 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -16,6 +16,7 @@ disliked_food = NONE liked_food = GROSS | MEAT | RAW species_category = SPECIES_CATEGORY_UNDEAD + wings_icons = SPECIES_WINGS_SKELETAL //eh. /datum/species/zombie/notspaceproof id = "notspaceproofzombie" diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index fca7c1f72c..2422528d21 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -1,16 +1,16 @@ /mob/living/carbon/get_item_by_slot(slot_id) switch(slot_id) - if(SLOT_BACK) + if(ITEM_SLOT_BACK) return back - if(SLOT_WEAR_MASK) + if(ITEM_SLOT_MASK) return wear_mask - if(SLOT_NECK) + if(ITEM_SLOT_NECK) return wear_neck - if(SLOT_HEAD) + if(ITEM_SLOT_HEAD) return head - if(SLOT_HANDCUFFED) + if(ITEM_SLOT_HANDCUFFED) return handcuffed - if(SLOT_LEGCUFFED) + if(ITEM_SLOT_LEGCUFFED) return legcuffed return null @@ -20,17 +20,17 @@ return slot if(critical) //it is CRITICAL they get this item, no matter what //do they have a backpack? - var/obj/item/backpack = get_item_by_slot(SLOT_BACK) + var/obj/item/backpack = get_item_by_slot(ITEM_SLOT_BACK) if(!backpack) //nothing on their back backpack = new /obj/item/storage/backpack(get_turf(src)) - if(equip_to_slot(backpack, SLOT_BACK)) //worst-case-scenario, something that shouldnt wear a backpack gets one + if(equip_to_slot(backpack, ITEM_SLOT_BACK)) //worst-case-scenario, something that shouldnt wear a backpack gets one I.forceMove(backpack) - return SLOT_BACK + return ITEM_SLOT_BACK else if(istype(backpack) && SEND_SIGNAL(backpack, COMSIG_CONTAINS_STORAGE)) //place it in here, regardless of storage capacity I.forceMove(backpack) - return SLOT_BACK + return ITEM_SLOT_BACK else //this should NEVER happen, but if it does, report it with the appropriate information var/conclusion = qdel_on_fail ? "deleted" : "not moved, staying at current position [I.x], [I.y], [I.z]" @@ -69,28 +69,28 @@ I.appearance_flags |= NO_CLIENT_COLOR var/not_handled = FALSE switch(slot) - if(SLOT_BACK) + if(ITEM_SLOT_BACK) back = I update_inv_back() - if(SLOT_WEAR_MASK) + if(ITEM_SLOT_MASK) wear_mask = I wear_mask_update(I, toggle_off = 0) - if(SLOT_HEAD) + if(ITEM_SLOT_HEAD) head = I head_update(I) - if(SLOT_NECK) + if(ITEM_SLOT_NECK) wear_neck = I update_inv_neck(I) - if(SLOT_HANDCUFFED) + if(ITEM_SLOT_HANDCUFFED) handcuffed = I update_handcuffed() - if(SLOT_LEGCUFFED) + if(ITEM_SLOT_LEGCUFFED) legcuffed = I update_inv_legcuffed() - if(SLOT_HANDS) + if(ITEM_SLOT_HANDS) put_in_hands(I) update_inv_hands() - if(SLOT_IN_BACKPACK) + if(ITEM_SLOT_BACKPACK) if(!back || !SEND_SIGNAL(back, COMSIG_TRY_STORAGE_INSERT, I, src, TRUE)) not_handled = TRUE else @@ -161,55 +161,58 @@ return index && hand_bodyparts[index] /** - * Proc called when giving an item to another player + * Proc called when offering an item to another player * * This handles creating an alert and adding an overlay to it */ /mob/living/carbon/proc/give(target) - var/obj/item/receiving = get_active_held_item() - if(!receiving) + var/obj/item/offered_item = get_active_held_item() + if(!offered_item) to_chat(src, "You're not holding anything to give!") return - visible_message("[src] is offering [receiving]", \ - "You offer [receiving]", null, 2) - var/mob/living/carbon/targets = list() - if(!target) - for(var/mob/living/carbon/C in orange(1, src)) - if(!CanReach(C)) - return - targets += C - else - targets += target - if(!targets) + + if(IS_DEAD_OR_INCAP(src)) + to_chat(src, span_warning("You're unable to offer anything in your current state!")) return - for(var/mob/living/carbon/C in targets) - var/atom/movable/screen/alert/give/G = C.throw_alert("[src]", /atom/movable/screen/alert/give) - if(!G) - return - G.setup(C, src, receiving) + + if(has_status_effect(STATUS_EFFECT_OFFERING)) + to_chat(src, span_warning("You're already offering up something!")) + return + + if(offered_item.on_offered(src)) // see if the item interrupts with its own behavior + return + + visible_message(span_notice("[src] is offering [offered_item]."), \ + span_notice("You offer [offered_item]."), null, 2) + + apply_status_effect(STATUS_EFFECT_OFFERING, offered_item) /** * Proc called when the player clicks the give alert * - * Handles checking if the player taking the item has open slots and is in range of the giver + * Handles checking if the player taking the item has open slots and is in range of the offerer * Also deals with the actual transferring of the item to the players hands * Arguments: - * * giver - The person giving the original item - * * I - The item being given by the giver + * * offerer - The person giving the original item + * * I - The item being given by the offerer */ -/mob/living/carbon/proc/take(mob/living/carbon/giver, obj/item/I) - clear_alert("[giver]") - if(get_dist(src, giver) > 1) - to_chat(src, "[giver] is out of range! ") +/mob/living/carbon/proc/take(mob/living/carbon/offerer, obj/item/I) + clear_alert("[offerer]") + if(get_dist(src, offerer) > 1) + to_chat(src, span_warning("[offerer] is out of range!")) return - if(!I || giver.get_active_held_item() != I) - to_chat(src, "[giver] is no longer holding the item they were offering! ") + if(!I || offerer.get_active_held_item() != I) + to_chat(src, span_warning("[offerer] is no longer holding the item they were offering!")) return if(!get_empty_held_indexes()) to_chat(src, "You have no empty hands!") return - if(!giver.temporarilyRemoveItemFromInventory(I)) - visible_message("[src] tries to hand over [I] but it's stuck to them....", \ + if(I.on_offer_taken(offerer, src)) // see if the item has special behavior for being accepted + return + if(!offerer.temporarilyRemoveItemFromInventory(I)) + visible_message("[offerer] tries to hand over [I] but it's stuck to them....", \ " You make a fool of yourself trying to give away an item stuck to your hands") return + visible_message(span_notice("[src] takes [I] from [offerer]"), \ + span_notice("You take [I] from [offerer]")) put_in_hands(I) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 6f0f5453da..dadf169c35 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -1,6 +1,6 @@ -/mob/living/carbon/BiologicalLife(seconds, times_fired) +/mob/living/carbon/BiologicalLife(delta_time, times_fired) //Reagent processing needs to come before breathing, to prevent edge cases. - handle_organs(seconds, times_fired) + handle_organs(delta_time, times_fired) . = ..() // if . is false, we are dead. if(stat == DEAD) stop_sound_channel(CHANNEL_HEARTBEAT) @@ -9,7 +9,7 @@ . = FALSE if(!.) return - handle_blood() + handle_blood(delta_time, times_fired) // handle_blood *could* kill us. // we should probably have a better system for if we need to check for death or something in the future hmw if(stat != DEAD) @@ -23,7 +23,7 @@ handle_brain_damage() if(stat != DEAD) - handle_liver(seconds, times_fired) + handle_liver(delta_time, times_fired) if(stat != DEAD) handle_corruption() @@ -39,7 +39,7 @@ //Procs called while dead /mob/living/carbon/proc/handle_death() for(var/datum/reagent/R in reagents.reagent_list) - if(R.chemical_flags & REAGENT_DEAD_PROCESS) + if(R.chemical_flags & REAGENT_DEAD_PROCESS && !is_reagent_processing_invalid(R, src)) R.on_mob_dead(src) /////////////// @@ -324,7 +324,7 @@ if(!HAS_TRAIT(src, TRAIT_NO_INTERNALS)) for(check in GET_INTERNAL_SLOTS(src)) - if(CHECK_BITFIELD(check.clothing_flags, ALLOWINTERNALS)) + if((check.clothing_flags & ALLOWINTERNALS)) internals = TRUE if(internal) if(internal.loc != src) @@ -375,7 +375,7 @@ miasma_turf.air_update_turf() -/mob/living/carbon/proc/handle_blood() +/mob/living/carbon/proc/handle_blood(delta_time, times_fired) return /mob/living/carbon/proc/handle_bodyparts(seconds, times_fired) @@ -570,29 +570,17 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put else SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "jittery") - if(stuttering) - stuttering = max(stuttering-1, 0) - - if(slurring || drunkenness) - slurring = max(slurring-1,0,drunkenness) - - if(cultslurring) - cultslurring = max(cultslurring-1, 0) - - if(clockcultslurring) - clockcultslurring = max(clockcultslurring-1, 0) + if(druggy) + adjust_drugginess(-1) if(silent) silent = max(silent-1, 0) - if(druggy) - adjust_drugginess(-1) - if(hallucination) handle_hallucinations() if(drunkenness) - drunkenness = max(drunkenness - (drunkenness * 0.04), 0) + drunkenness *= 0.96 if(drunkenness >= 6) SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "drunk", /datum/mood_event/drunk) if(prob(25)) @@ -607,6 +595,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "drunk") clear_alert("drunk") sound_environment_override = SOUND_ENVIRONMENT_NONE + drunkenness = max(drunkenness - 0.2, 0) if(mind && (mind.assigned_role == "Scientist" || mind.assigned_role == "Research Director")) if(SSresearch.science_tech) @@ -670,7 +659,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put //used in human and monkey handle_environment() /mob/living/carbon/proc/natural_bodytemperature_stabilization() - if (HAS_TRAIT(src, TRAIT_COLDBLOODED)) + if(HAS_TRAIT(src, TRAIT_COLDBLOODED) || HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) return 0 //Return 0 as your natural temperature. Species proc handle_environment() will adjust your temperature based on this. var/body_temperature_difference = BODYTEMP_NORMAL - bodytemperature @@ -683,6 +672,52 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put return min(body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR, max(body_temperature_difference, -BODYTEMP_AUTORECOVERY_MINIMUM/4)) if(BODYTEMP_HEAT_DAMAGE_LIMIT to INFINITY) return min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers + +/mob/living/carbon/proc/get_cooling_efficiency() + if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) + return 1 + + var/integration_bonus = min(blood_volume * SYNTH_INTEGRATION_COOLANT_CAP, integrating_blood * SYNTH_INTEGRATION_COOLANT_PENALTY) //Integration blood somewhat helps, though only at 40% impact and to a cap of 25% of current blood level. + var/blood_effective_volume = blood_volume + integration_bonus + var/coolant_efficiency = min(blood_effective_volume / BLOOD_VOLUME_SAFE, 1) //Low coolant is only a negative, adding more than needed will not help you. + var/environment_efficiency = get_environment_cooling_efficiency() + + return min(coolant_efficiency * environment_efficiency, SYNTH_MAX_COOLING_EFFICIENCY) + + +/mob/living/carbon/proc/get_environment_cooling_efficiency() + var/suitlink = check_suitlinking() + if(suitlink) + return suitlink //If you are wearing full EVA or lavaland hazard gear (on lavaland), assume it has been made to accomodate your cooling needs. + var/datum/gas_mixture/environment = loc.return_air() + if(!environment) + return 0 + + var/pressure = environment.return_pressure() + var/heat = environment.return_temperature() + + var/heat_efficiency = clamp(1 + ((bodytemperature - heat) * SYNTH_HEAT_EFFICIENCY_COEFF), 0, SYNTH_SINGLE_INFLUENCE_COOLING_EFFECT_CAP) + var/pressure_efficiency = clamp(pressure / ONE_ATMOSPHERE, 0, SYNTH_SINGLE_INFLUENCE_COOLING_EFFECT_CAP) + + if(HAS_TRAIT(src, TRAIT_LOWPRESSURECOOLING)) + pressure_efficiency = max(pressure_efficiency, 1) //Space adaptation nulls drawbacks of low-pressure cooling. + + var/total_environment_efficiency = min(heat_efficiency * pressure_efficiency, SYNTH_TOTAL_ENVIRONMENT_EFFECT_CAP) //At best, you can get 200% total + return total_environment_efficiency + +/mob/living/carbon/proc/check_suitlinking() + var/suit_item = get_item_by_slot(ITEM_SLOT_OCLOTHING) + var/head_item = get_item_by_slot(ITEM_SLOT_HEAD) + var/turf/T = get_turf(src) + + if(istype(head_item, /obj/item/clothing/head/helmet/space) && istype(suit_item, /obj/item/clothing/suit/space)) + return 1 + + if(T && is_mining_level(T.z) && istype(head_item, /obj/item/clothing/head/hooded/explorer) && istype(suit_item, /obj/item/clothing/suit/hooded/explorer)) + return 1 + + return 0 + ///////// //LIVER// ///////// diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm index 13d234092c..0c9895c729 100644 --- a/code/modules/mob/living/carbon/monkey/combat.dm +++ b/code/modules/mob/living/carbon/monkey/combat.dm @@ -30,7 +30,7 @@ return 0 if(myPath.len <= 0) - myPath = get_path_to(src, get_turf(target), /turf/proc/Distance, MAX_RANGE_FIND + 1, 250,1) + myPath = get_path_to(src, target, 250, 1) if(myPath) if(myPath.len > 0) diff --git a/code/modules/mob/living/carbon/monkey/inventory.dm b/code/modules/mob/living/carbon/monkey/inventory.dm index 34599028f7..156eef9b6b 100644 --- a/code/modules/mob/living/carbon/monkey/inventory.dm +++ b/code/modules/mob/living/carbon/monkey/inventory.dm @@ -5,29 +5,29 @@ return FALSE switch(slot) - if(SLOT_HANDS) + if(ITEM_SLOT_HANDS) if(get_empty_held_indexes()) return TRUE return FALSE - if(SLOT_WEAR_MASK) + if(ITEM_SLOT_MASK) if(wear_mask) return FALSE if( !(I.slot_flags & ITEM_SLOT_MASK) ) return FALSE return TRUE - if(SLOT_NECK) + if(ITEM_SLOT_NECK) if(wear_neck) return FALSE if( !(I.slot_flags & ITEM_SLOT_NECK) ) return FALSE return TRUE - if(SLOT_HEAD) + if(ITEM_SLOT_HEAD) if(head) return FALSE if( !(I.slot_flags & ITEM_SLOT_HEAD) ) return FALSE return TRUE - if(SLOT_BACK) + if(ITEM_SLOT_BACK) if(back) return FALSE if( !(I.slot_flags & ITEM_SLOT_BACK) ) diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index 480cbebe11..a7bc0c11d5 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -3,7 +3,7 @@ /mob/living/carbon/monkey -/mob/living/carbon/monkey/BiologicalLife(seconds, times_fired) +/mob/living/carbon/monkey/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(client) @@ -162,7 +162,7 @@ for(var/X in burning_items) var/obj/item/I = X if(!(I.resistance_flags & FIRE_PROOF)) - I.take_damage(fire_stacks, BURN, "fire", 0) + I.take_damage(fire_stacks, BURN, FIRE, 0) adjust_bodytemperature(BODYTEMP_HEATING_MAX) SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "on_fire", /datum/mood_event/on_fire) diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 4ab24c31dd..bb35ff082b 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -16,6 +16,17 @@ /obj/item/bodypart/r_arm/monkey, /obj/item/bodypart/r_leg/monkey, /obj/item/bodypart/l_leg/monkey) hud_type = /datum/hud/monkey +GLOBAL_LIST_INIT(strippable_monkey_items, create_strippable_list(list( + /datum/strippable_item/mob_item_slot/head, + /datum/strippable_item/mob_item_slot/back, + /datum/strippable_item/mob_item_slot/mask, + /datum/strippable_item/mob_item_slot/neck, + /datum/strippable_item/hand/left, + /datum/strippable_item/hand/right, + /datum/strippable_item/mob_item_slot/handcuffs, + /datum/strippable_item/mob_item_slot/legcuffs, +))) + /mob/living/carbon/monkey/Initialize(mapload, cubespawned=FALSE, mob/spawner) add_verb(src, /mob/living/proc/mob_sleep) add_verb(src, /mob/living/proc/lay_down) @@ -47,6 +58,7 @@ . = ..() AddElement(/datum/element/mob_holder, worn_state = "monkey", inv_slots = ITEM_SLOT_HEAD) AddComponent(/datum/component/footstep, FOOTSTEP_MOB_BAREFOOT, 1, 2) + AddElement(/datum/element/strippable, GLOB.strippable_monkey_items) /mob/living/carbon/monkey/Destroy() @@ -168,9 +180,9 @@ /mob/living/carbon/monkey/angry aggressive = TRUE -/mob/living/carbon/monkey/angry/Initialize() +/mob/living/carbon/monkey/angry/Initialize(mapload) . = ..() if(prob(10)) var/obj/item/clothing/head/helmet/justice/escape/helmet = new(src) - equip_to_slot_or_del(helmet,SLOT_HEAD) + equip_to_slot_or_del(helmet,ITEM_SLOT_HEAD) INVOKE_ASYNC(helmet, /obj/item.proc/attack_self, src) // todo encapsulate toggle diff --git a/code/modules/mob/living/carbon/monkey/monkey_defense.dm b/code/modules/mob/living/carbon/monkey/monkey_defense.dm index 16b3c1a79e..80d968b229 100644 --- a/code/modules/mob/living/carbon/monkey/monkey_defense.dm +++ b/code/modules/mob/living/carbon/monkey/monkey_defense.dm @@ -195,14 +195,14 @@ if (EXPLODE_HEAVY) take_overall_damage(60, 60) - damage_clothes(200, BRUTE, "bomb") + damage_clothes(200, BRUTE, BOMB) adjustEarDamage(30, 120) if(prob(70)) Unconscious(200) if(EXPLODE_LIGHT) take_overall_damage(30, 0) - damage_clothes(50, BRUTE, "bomb") + damage_clothes(50, BRUTE, BOMB) adjustEarDamage(15,60) if (prob(50)) Unconscious(160) diff --git a/code/modules/mob/living/carbon/monkey/update_icons.dm b/code/modules/mob/living/carbon/monkey/monkey_update_icons.dm similarity index 100% rename from code/modules/mob/living/carbon/monkey/update_icons.dm rename to code/modules/mob/living/carbon/monkey/monkey_update_icons.dm diff --git a/code/modules/mob/living/carbon/monkey/punpun.dm b/code/modules/mob/living/carbon/monkey/punpun.dm index c59218a8a3..585a93f304 100644 --- a/code/modules/mob/living/carbon/monkey/punpun.dm +++ b/code/modules/mob/living/carbon/monkey/punpun.dm @@ -9,7 +9,7 @@ var/list/pet_monkey_names = list("Pun Pun", "Bubbles", "Mojo", "George", "Darwin", "Aldo", "Caeser", "Kanzi", "Kong", "Terk", "Grodd", "Mala", "Bojangles", "Coco", "Able", "Baker", "Scatter", "Norbit", "Travis") var/list/rare_pet_monkey_names = list("Professor Bobo", "Deempisi's Revenge", "Furious George", "King Louie", "Dr. Zaius", "Jimmy Rustles", "Dinner", "Lanky") -/mob/living/carbon/monkey/punpun/Initialize() +/mob/living/carbon/monkey/punpun/Initialize(mapload) Read_Memory() if(ancestor_name) name = ancestor_name @@ -29,11 +29,11 @@ if(ancestor_chain > 1) generate_fake_scars(rand(ancestor_chain, ancestor_chain * 4)) if(relic_hat) - equip_to_slot_or_del(new relic_hat, SLOT_HEAD) + equip_to_slot_or_del(new relic_hat, ITEM_SLOT_HEAD) if(relic_mask) - equip_to_slot_or_del(new relic_mask, SLOT_WEAR_MASK) + equip_to_slot_or_del(new relic_mask, ITEM_SLOT_MASK) -/mob/living/carbon/monkey/punpun/BiologicalLife(seconds, times_fired) +/mob/living/carbon/monkey/punpun/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved) @@ -46,6 +46,7 @@ ..() /mob/living/carbon/monkey/punpun/proc/Read_Memory() + var/saved_color if(fexists("data/npc_saves/Punpun.sav")) //legacy compatability to convert old format to new var/savefile/S = new /savefile("data/npc_saves/Punpun.sav") S["ancestor_name"] >> ancestor_name @@ -62,6 +63,9 @@ ancestor_chain = json["ancestor_chain"] relic_hat = json["relic_hat"] relic_mask = json["relic_hat"] + saved_color = json["color"] + if(!isnull(saved_color)) + add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY) /mob/living/carbon/monkey/punpun/proc/Write_Memory(dead, gibbed) var/json_file = file("data/npc_saves/Punpun.json") @@ -71,10 +75,12 @@ file_data["ancestor_chain"] = null file_data["relic_hat"] = null file_data["relic_mask"] = null + file_data["color"] = null else file_data["ancestor_name"] = ancestor_name ? ancestor_name : name file_data["ancestor_chain"] = dead ? ancestor_chain + 1 : ancestor_chain file_data["relic_hat"] = head ? head.type : null file_data["relic_mask"] = wear_mask ? wear_mask.type : null + file_data["color"] = color ? json_encode(color) : null fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) diff --git a/code/modules/mob/living/carbon/status_procs.dm b/code/modules/mob/living/carbon/status_procs.dm index 5b5aa9d5c0..f7cb0e0760 100644 --- a/code/modules/mob/living/carbon/status_procs.dm +++ b/code/modules/mob/living/carbon/status_procs.dm @@ -5,7 +5,7 @@ /mob/living/carbon/adjust_drugginess(amount) druggy = max(druggy+amount, 0) if(druggy) - overlay_fullscreen("high", /atom/movable/screen/fullscreen/high) + overlay_fullscreen("high", /atom/movable/screen/fullscreen/tiled/high) throw_alert("high", /atom/movable/screen/alert/high) SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "high", /datum/mood_event/high) sound_environment_override = SOUND_ENVIRONMENT_DRUGGED @@ -18,7 +18,7 @@ /mob/living/carbon/set_drugginess(amount) druggy = max(amount, 0) if(druggy) - overlay_fullscreen("high", /atom/movable/screen/fullscreen/high) + overlay_fullscreen("high", /atom/movable/screen/fullscreen/tiled/high) throw_alert("high", /atom/movable/screen/alert/high) else clear_fullscreen("high") diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 2d529e976a..65433c2bd9 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -65,9 +65,9 @@ I.on_mob_death(src, gibbed) if(mind) mind.store_memory("Time of death: [tod]", 0) - GLOB.alive_mob_list -= src + remove_from_alive_mob_list() if(!gibbed) - GLOB.dead_mob_list += src + add_to_dead_mob_list() if(ckey) var/datum/preferences/P = GLOB.preferences_datums[ckey] if(P) @@ -93,8 +93,7 @@ var/turf/T = get_turf(src) if(mind && mind.name && mind.active && !istype(T.loc, /area/ctf) && !(signal & COMPONENT_BLOCK_DEATH_BROADCAST)) - var/rendered = "[mind.name] has died at [get_area_name(T)]." - deadchat_broadcast(rendered, follow_target = src, turf_target = T, message_type=DEADCHAT_DEATHRATTLE) + deadchat_broadcast(" has died at [get_area_name(T)].", "[mind.name]", follow_target = src, turf_target = T, message_type=DEADCHAT_DEATHRATTLE) if (client && client.prefs && client.prefs.auto_ooc) if (!(client.prefs.chat_toggles & CHAT_OOC)) client.prefs.chat_toggles ^= CHAT_OOC diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index cfebacb977..d59978d993 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -5,7 +5,7 @@ /datum/emote/living/blush/run_emote(mob/user, params) . = ..() - if(. && isipcperson(user)) + if(. && isrobotic(user)) do_fake_sparks(5,FALSE,user) /datum/emote/living/bow @@ -518,6 +518,8 @@ /datum/emote/living/circle/run_emote(mob/user, params) . = ..() + if(!.) + return var/obj/item/circlegame/N = new(user) if(user.put_in_hands(N)) to_chat(user, "You make a circle with your hand.") diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 43a5d9c2c8..f4f8060fb3 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -6,13 +6,13 @@ SHOULD_NOT_SLEEP(TRUE) if(mob_transforming) return - . = SEND_SIGNAL(src, COMSIG_LIVING_LIFE, seconds, times_fired) if(!(. & COMPONENT_INTERRUPT_LIFE_PHYSICAL)) PhysicalLife(seconds, times_fired) if(!(. & COMPONENT_INTERRUPT_LIFE_BIOLOGICAL)) BiologicalLife(seconds, times_fired) - + if(!(. & COMPONET_INTERRUPT_STATUS_EFFECTS)) + handle_status_effects() //all special effects, stun, knockdown, jitteryness, hallucination, sleeping, etc // CODE BELOW SHOULD ONLY BE THINGS THAT SHOULD HAPPEN NO MATTER WHAT AND CAN NOT BE SUSPENDED! // Otherwise, it goes into one of the two split Life procs! @@ -42,8 +42,8 @@ * Handles biological life processes like chemical metabolism, breathing, etc * Returns TRUE or FALSE based on if we were interrupted. This is used by overridden variants to check if they should stop. */ -/mob/living/proc/BiologicalLife(seconds, times_fired) - SEND_SIGNAL(src,COMSIG_LIVING_BIOLOGICAL_LIFE, seconds, times_fired) +/mob/living/proc/BiologicalLife(delta_time, times_fired) + SEND_SIGNAL(src,COMSIG_LIVING_BIOLOGICAL_LIFE, delta_time, times_fired) handle_diseases()// DEAD check is in the proc itself; we want it to spread even if the mob is dead, but to handle its disease-y properties only if you're not. handle_wounds() @@ -67,11 +67,10 @@ //stuff in the stomach handle_stomach() - handle_block_parry(seconds) + handle_block_parry(delta_time) - // These two MIGHT need to be moved to base Life() if we get any in the future that's a "physical" effect that needs to fire even while in stasis. handle_traits() // eye, ear, brain damages - handle_status_effects() //all special effects, stun, knockdown, jitteryness, hallucination, sleeping, etc + return TRUE /** @@ -150,11 +149,26 @@ /mob/living/proc/handle_stomach() return -//this updates all special effects: knockdown, druggy, stuttering, etc.. +/* + * this updates some effects: mostly old stuff such as drunkness, druggy, stuttering, etc. + * that should be converted to status effect datums one day. + */ /mob/living/proc/handle_status_effects() if(confused) confused = max(0, confused - 1) + if(stuttering) + stuttering = max(stuttering-1, 0) + + if(slurring) + slurring = max(slurring-1,0) + + if(cultslurring) + cultslurring = max(cultslurring-1, 0) + + if(clockcultslurring) + clockcultslurring = max(clockcultslurring-1, 0) + /mob/living/proc/handle_traits() //Eyes if(eye_blind) //blindness, heals slowly over time diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 5603801dce..f6a2f1cb38 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1,4 +1,4 @@ -/mob/living/Initialize() +/mob/living/Initialize(mapload) . = ..() if(unique_name) name = "[name] ([rand(1, 1000)])" @@ -81,6 +81,7 @@ //Called when we bump onto a mob /mob/living/proc/MobBump(mob/M) + SEND_SIGNAL(src, COMSIG_LIVING_MOB_BUMP, M) //Even if we don't push/swap places, we "touched" them, so spread fire spreadFire(M) @@ -88,6 +89,7 @@ return TRUE var/they_can_move = TRUE + if(isliving(M)) var/mob/living/L = M they_can_move = CHECK_MOBILITY(L, MOBILITY_MOVE) @@ -105,44 +107,44 @@ //Should stop you pushing a restrained person out of the way if(L.pulledby && L.pulledby != src && L.restrained()) if(!(world.time % 5)) - to_chat(src, "[L] is restrained, you cannot push past.") - return 1 + to_chat(src, span_warning("[L] is restrained, you cannot push past.")) + return TRUE if(L.pulling) if(ismob(L.pulling)) var/mob/P = L.pulling if(P.restrained()) if(!(world.time % 5)) - to_chat(src, "[L] is restraining [P], you cannot push past.") - return 1 + to_chat(src, span_warning("[L] is restraining [P], you cannot push past.")) + return TRUE - //CIT CHANGES START HERE - makes it so resting stops you from moving through standing folks without a short delay - if(!CHECK_MOBILITY(src, MOBILITY_STAND) && CHECK_MOBILITY(L, MOBILITY_STAND)) + //CIT CHANGES START HERE - makes it so resting stops you from moving through standing folks or over prone bodies without a short delay + if(!CHECK_MOBILITY(src, MOBILITY_STAND)) var/origtargetloc = L.loc if(!pulledby) if(combat_flags & COMBAT_FLAG_ATTEMPTING_CRAWL) return TRUE if(IS_STAMCRIT(src)) - to_chat(src, "You're too exhausted to crawl under [L].") + to_chat(src, "You're too exhausted to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under": "over"] [L].") return TRUE - ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_ATTEMPTING_CRAWL) - visible_message("[src] is attempting to crawl under [L].", - "You are now attempting to crawl under [L].", - target = L, target_message = "[src] is attempting to crawl under you.") + combat_flags |= COMBAT_FLAG_ATTEMPTING_CRAWL + visible_message("[src] is attempting to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under" : "over"] [L].", + "You are now attempting to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under": "over"] [L].", + target = L, target_message = "[src] is attempting to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under" : "over"] you.") if(!do_after(src, CRAWLUNDER_DELAY, target = src) || CHECK_MOBILITY(src, MOBILITY_STAND)) - DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_ATTEMPTING_CRAWL) + combat_flags &= ~(COMBAT_FLAG_ATTEMPTING_CRAWL) return TRUE var/src_passmob = (pass_flags & PASSMOB) pass_flags |= PASSMOB Move(origtargetloc) if(!src_passmob) pass_flags &= ~PASSMOB - DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_ATTEMPTING_CRAWL) + combat_flags &= ~(COMBAT_FLAG_ATTEMPTING_CRAWL) return TRUE //END OF CIT CHANGES if(moving_diagonally)//no mob swap during diagonal moves. - return 1 + return TRUE if(!M.buckled && !M.has_buckled_mobs()) var/mob_swap = FALSE @@ -151,7 +153,8 @@ if(!too_strong) mob_swap = TRUE else - if(M.pulledby == src && a_intent == INTENT_GRAB) + //You can swap with the person you are dragging on grab intent, and restrained people in most cases + if(M.pulledby == src && !too_strong) mob_swap = TRUE //restrained people act if they were on 'help' intent to prevent a person being pulled from being separated from their puller else if((M.restrained() || M.a_intent == INTENT_HELP) && (restrained() || a_intent == INTENT_HELP)) @@ -159,8 +162,8 @@ if(mob_swap) //switch our position with M if(loc && !loc.Adjacent(M.loc)) - return 1 - now_pushing = 1 + return TRUE + now_pushing = TRUE var/oldloc = loc var/oldMloc = M.loc @@ -180,27 +183,31 @@ if(!M_passmob) M.pass_flags &= ~PASSMOB - now_pushing = 0 + now_pushing = FALSE if(!move_failed) - return 1 + return TRUE //okay, so we didn't switch. but should we push? //not if he's not CANPUSH of course if(!(M.status_flags & CANPUSH)) - return 1 + return TRUE if(isliving(M)) var/mob/living/L = M if(HAS_TRAIT(L, TRAIT_PUSHIMMUNE)) - return 1 - //If they're a human, and they're not in help intent, block pushing - if(ishuman(M) && (M.a_intent != INTENT_HELP)) - return TRUE + return TRUE + if(M.a_intent != INTENT_HELP) + //If they're a human, and they're not in help intent, block pushing + if(ishuman(M)) + return TRUE + //if they are a cyborg, and they're alive and not in help intent, block pushing + if(iscyborg(M) && M.stat != DEAD) + return TRUE //anti-riot equipment is also anti-push for(var/obj/item/I in M.held_items) if(!istype(M, /obj/item/clothing)) if(prob(I.block_chance*2)) - return 1 + return TRUE /mob/living/get_photo_description(obj/item/camera/camera) var/list/mob_details = list() @@ -231,21 +238,40 @@ if(!client && (mob_size < MOB_SIZE_SMALL)) return now_pushing = TRUE - var/t = get_dir(src, AM) + SEND_SIGNAL(src, COMSIG_LIVING_PUSHING_MOVABLE, AM) + var/dir_to_target = get_dir(src, AM) + + // If there's no dir_to_target then the player is on the same turf as the atom they're trying to push. + // This can happen when a player is stood on the same turf as a directional window. All attempts to push + // the window will fail as get_dir will return 0 and the player will be unable to move the window when + // it should be pushable. + // In this scenario, we will use the facing direction of the /mob/living attempting to push the atom as + // a fallback. + if(!dir_to_target) + dir_to_target = dir + var/push_anchored = FALSE if((AM.move_resist * MOVE_FORCE_CRUSH_RATIO) <= force) - if(move_crush(AM, move_force, t)) + if(move_crush(AM, move_force, dir_to_target)) push_anchored = TRUE - if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally - if(force_push(AM, move_force, t, push_anchored)) + if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally + if(force_push(AM, move_force, dir_to_target, push_anchored)) push_anchored = TRUE + if(ismob(AM)) + var/mob/mob_to_push = AM + var/atom/movable/mob_buckle = mob_to_push.buckled + // If we can't pull them because of what they're buckled to, make sure we can push the thing they're buckled to instead. + // If neither are true, we're not pushing anymore. + if(mob_buckle && (mob_buckle.buckle_prevents_pull || (force < (mob_buckle.move_resist * MOVE_FORCE_PUSH_RATIO)))) + now_pushing = FALSE + return if((AM.anchored && !push_anchored) || (force < (AM.move_resist * MOVE_FORCE_PUSH_RATIO))) now_pushing = FALSE return - if (istype(AM, /obj/structure/window)) + if(istype(AM, /obj/structure/window)) var/obj/structure/window/W = AM if(W.fulltile) - for(var/obj/structure/window/win in get_step(W,t)) + for(var/obj/structure/window/win in get_step(W, dir_to_target)) now_pushing = FALSE return if(pulling == AM) @@ -253,8 +279,9 @@ var/current_dir if(isliving(AM)) current_dir = AM.dir - if(step(AM, t) && Process_Spacemove(t)) - step(src, t) + if(AM.Move(get_step(AM.loc, dir_to_target), dir_to_target, glide_size)) + AM.add_fingerprint(src) + Move(get_step(loc, dir_to_target), dir_to_target) if(current_dir) AM.setDir(current_dir) now_pushing = FALSE @@ -354,29 +381,33 @@ offset = GRAB_PIXEL_SHIFT_NECK if(GRAB_KILL) offset = GRAB_PIXEL_SHIFT_NECK - M.setDir(get_dir(M, src)) - switch(M.dir) - if(NORTH) - animate(M, pixel_x = 0, pixel_y = offset, 3) - if(SOUTH) - animate(M, pixel_x = 0, pixel_y = -offset, 3) - if(EAST) - if(M.lying == 270) //update the dragged dude's direction if we've turned - M.lying = 90 - M.update_transform() //force a transformation update, otherwise it'll take a few ticks for update_mobility() to do so - M.lying_prev = M.lying - animate(M, pixel_x = offset, pixel_y = 0, 3) - if(WEST) - if(M.lying == 90) - M.lying = 270 - M.update_transform() - M.lying_prev = M.lying - animate(M, pixel_x = -offset, pixel_y = 0, 3) + var/target_dir = get_dir(M, src) + M.setDir(target_dir) + var/target_x + var/target_y + if(target_dir & NORTH) + target_y += offset + if(target_dir & SOUTH) + target_y -= offset + if(target_dir & EAST) + target_x += offset + if(target_dir & WEST) + target_x -= offset + if(target_x || target_y) + if(0 < target_x && M.lying == 270) + M.lying = 90 + M.update_transform(FALSE) //force a transformation update, otherwise it'll take a few ticks for update_mobility() to do so + M.lying_prev = M.lying + if(0 > target_x && M.lying == 90) + M.lying = 270 + M.update_transform(FALSE) + M.lying_prev = M.lying + animate(M, pixel_x = target_x, pixel_y = target_y, time = 3, flags = ANIMATION_PARALLEL) /mob/living/proc/reset_pull_offsets(mob/living/M, override) if(!override && M.buckled) return - animate(M, pixel_x = 0, pixel_y = 0, 1) + animate(M, pixel_x = 0, pixel_y = 0, time = 3, flags = ANIMATION_PARALLEL) //mob verbs are a lot faster than object verbs //for more info on why this is not atom/pull, see examinate() in mob.dm @@ -395,6 +426,7 @@ ..() update_pull_movespeed() update_pull_hud_icon() + SEND_SIGNAL(src, COMSIG_LIVING_STOPPED_PULLING) /mob/living/verb/stop_pulling1() set name = "Stop Pulling" @@ -432,8 +464,8 @@ to_chat(src, "You have given up life and succumbed to death.") death() -/mob/living/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, check_immobilized = FALSE) - if(stat || IsUnconscious() || IsStun() || IsParalyzed() || (combat_flags & COMBAT_FLAG_HARD_STAMCRIT) || (check_immobilized && IsImmobilized()) || (!ignore_restraints && restrained(ignore_grab))) +/mob/living/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, check_immobilized = FALSE, ignore_stasis = FALSE) + if(stat || IsUnconscious() || IsStun() || IsParalyzed() || (combat_flags & COMBAT_FLAG_HARD_STAMCRIT) || (check_immobilized && IsImmobilized()) || (!ignore_restraints && restrained(ignore_grab)) || (!ignore_stasis && IS_IN_STASIS(src))) return TRUE /mob/living/canUseStorage() @@ -579,7 +611,7 @@ UNLINT(livingdoll.filters += filter(type="alpha", icon = mob_mask)) livingdoll.filters += filter(type="drop_shadow", size = -1) if(severity > 0) - overlay_fullscreen("brute", /atom/movable/screen/fullscreen/brute, severity) + overlay_fullscreen("brute", /atom/movable/screen/fullscreen/scaled/brute, severity) else clear_fullscreen("brute") @@ -589,8 +621,8 @@ if(full_heal) fully_heal(admin_revive) if(stat == DEAD && can_be_revived()) //in some cases you can't revive (e.g. no brain) - GLOB.dead_mob_list -= src - GLOB.alive_mob_list += src + remove_from_dead_mob_list() + add_to_alive_mob_list() suiciding = 0 stat = UNCONSCIOUS //the mob starts unconscious, if(!eye_blind) @@ -677,6 +709,8 @@ var/bleed_amount = bleedDragAmount() blood_volume = max(blood_volume - bleed_amount, 0) //that depends on our brute damage. + if(bleed_amount < 0.1) + return var/newdir = get_dir(target_turf, start) if(newdir != direction) newdir = newdir | direction @@ -884,12 +918,11 @@ if(anchored || (buckled && buckled.anchored)) fixed = 1 if(on && !(movement_type & FLOATING) && !fixed) - animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1) - sleep(10) - animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1) + animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE) setMovetype(movement_type | FLOATING) else if(((!on || fixed) && (movement_type & FLOATING))) - animate(src, pixel_y = get_standard_pixel_y_offset(lying), time = 10) + animate(src, pixel_z = get_standard_pixel_y_offset(lying), time = 10) setMovetype(movement_type & ~FLOATING) // The src mob is trying to strip an item from someone @@ -920,7 +953,7 @@ else to_chat(src,"You try to remove [who]'s [what.name].") what.add_fingerprint(src) - if(do_mob(src, who, round(what.strip_delay / strip_mod), ignorehelditem = TRUE)) + if(do_mob(src, who, round(what.strip_delay / strip_mod), timed_action_flags = IGNORE_HELD_ITEM)) if(what && Adjacent(who)) if(islist(where)) var/list/L = where @@ -935,13 +968,6 @@ what.forceMove(drop_location()) log_combat(src, who, "stripped [what] off") - if(Adjacent(who)) //update inventory window - who.show_inv(src) - else - src << browse(null,"window=mob[REF(who)]") - - who.update_equipment_speed_mods() // Updates speed in case stripped speed affecting item - // The src mob is trying to place an item on someone // Override if a certain mob should be behave differently when placing items (can't, for example) /mob/living/stripPanelEquip(obj/item/what, mob/who, where) @@ -995,7 +1021,7 @@ var/pixel_y_diff = rand(-amplitude/3, amplitude/3) var/final_pixel_x = get_standard_pixel_x_offset(lying) var/final_pixel_y = get_standard_pixel_y_offset(lying) - animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6) + animate(src, pixel_x = pixel_x_diff, pixel_y = pixel_y_diff , time = 2, loop = 6, flags = ANIMATION_PARALLEL | ANIMATION_RELATIVE) animate(pixel_x = final_pixel_x , pixel_y = final_pixel_y , time = 2) floating_need_update = TRUE @@ -1130,7 +1156,7 @@ amount -= RAD_BACKGROUND_RADIATION // This will always be at least 1 because of how skin protection is calculated - var/blocked = getarmor(null, "rad") + var/blocked = getarmor(null, RAD) if(amount > RAD_BURN_THRESHOLD) apply_damage((amount-RAD_BURN_THRESHOLD)/RAD_BURN_THRESHOLD, BURN, null, blocked) @@ -1159,7 +1185,7 @@ visible_message("[src] catches fire!", \ "You're set on fire!") new/obj/effect/dummy/lighting_obj/moblight/fire(src) - throw_alert("fire", /atom/movable/screen/alert/fire) + throw_alert(FIRE, /atom/movable/screen/alert/fire) update_fire() SEND_SIGNAL(src, COMSIG_LIVING_IGNITED,src) return TRUE @@ -1289,11 +1315,11 @@ return FALSE if(NAMEOF(src, stat)) if((stat == DEAD) && (var_value < DEAD))//Bringing the dead back to life - GLOB.dead_mob_list -= src - GLOB.alive_mob_list += src + remove_from_dead_mob_list() + add_to_alive_mob_list() if((stat < DEAD) && (var_value == DEAD))//Kill he - GLOB.alive_mob_list -= src - GLOB.dead_mob_list += src + remove_from_alive_mob_list() + add_to_dead_mob_list() if(NAMEOF(src, health)) //this doesn't work. gotta use procs instead. return FALSE . = ..() diff --git a/code/modules/mob/living/living_active_block.dm b/code/modules/mob/living/living_active_block.dm index 9ccaeb6c59..d6a4640062 100644 --- a/code/modules/mob/living/living_active_block.dm +++ b/code/modules/mob/living/living_active_block.dm @@ -48,7 +48,7 @@ animate(src, pixel_x = get_standard_pixel_x_offset(), pixel_y = get_standard_pixel_y_offset(), time = 2.5, FALSE, SINE_EASING | EASE_IN) /mob/living/proc/continue_starting_active_block() - return (combat_flags & COMBAT_FLAG_ACTIVE_BLOCK_STARTING)? DO_AFTER_CONTINUE : DO_AFTER_STOP + return (combat_flags & COMBAT_FLAG_ACTIVE_BLOCK_STARTING) /mob/living/get_standard_pixel_x_offset() . = ..() @@ -102,7 +102,7 @@ var/delay = data.block_start_delay combat_flags |= COMBAT_FLAG_ACTIVE_BLOCK_STARTING animate(src, pixel_x = get_standard_pixel_x_offset(), pixel_y = get_standard_pixel_y_offset(), time = delay, FALSE, SINE_EASING | EASE_IN) - if(!do_after_advanced(src, delay, src, DO_AFTER_REQUIRES_USER_ON_TURF|DO_AFTER_NO_COEFFICIENT, CALLBACK(src, .proc/continue_starting_active_block), MOBILITY_USE, null, null, I)) + if(!do_after(src, delay, src, (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE), extra_checks = CALLBACK(src, .proc/continue_starting_active_block))) to_chat(src, "You fail to raise [I].") combat_flags &= ~(COMBAT_FLAG_ACTIVE_BLOCK_STARTING) animate(src, pixel_x = get_standard_pixel_x_offset(), pixel_y = get_standard_pixel_y_offset(), time = 2.5, FALSE, SINE_EASING | EASE_IN, ANIMATION_END_NOW) diff --git a/code/modules/mob/living/living_active_parry.dm b/code/modules/mob/living/living_active_parry.dm index e34c5ce053..13240b2734 100644 --- a/code/modules/mob/living/living_active_parry.dm +++ b/code/modules/mob/living/living_active_parry.dm @@ -103,13 +103,16 @@ var/_method = override[thing] if(_method == ITEM_PARRY) using_item = thing + tool = using_item method = ITEM_PARRY data = using_item.block_parry_data else if(_method == UNARMED_PARRY) method = UNARMED_PARRY + tool = src data = thing if(!using_item && !method && length(other_items)) using_item = other_items[1] + tool = using_item method = ITEM_PARRY data = using_item.block_parry_data if(!method) diff --git a/code/modules/mob/living/living_blocking_parrying.dm b/code/modules/mob/living/living_blocking_parrying.dm index 0ccc03982a..bdc44ab356 100644 --- a/code/modules/mob/living/living_blocking_parrying.dm +++ b/code/modules/mob/living/living_blocking_parrying.dm @@ -166,7 +166,7 @@ GLOBAL_LIST_EMPTY(block_parry_data) /// Clickdelay duration post-parry if you fail to parry an attack var/parry_failed_clickcd_duration = 0 SECONDS /// Parry cooldown post-parry if failed. This is ADDED to parry_cooldown!!! - var/parry_failed_cooldown_duration = 0 SECONDS + var/parry_failed_cooldown_duration = 3.5 SECONDS // Advanced /// Flags added to return value diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 2888507baa..0b71359a1e 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -1,5 +1,5 @@ -/mob/living/proc/run_armor_check(def_zone = null, attack_flag = "melee", absorb_text = "Your armor absorbs the blow!", soften_text = "Your armor softens the blow!", armour_penetration, penetrated_text = "Your armor was penetrated!", silent=FALSE) +/mob/living/proc/run_armor_check(def_zone = null, attack_flag = MELEE, absorb_text = "Your armor absorbs the blow!", soften_text = "Your armor softens the blow!", armour_penetration, penetrated_text = "Your armor was penetrated!", silent=FALSE) var/armor = getarmor(def_zone, attack_flag) if(silent) @@ -68,7 +68,7 @@ else CRASH("Invalid rediretion mode [redirection_mode]") -/mob/living/bullet_act(obj/item/projectile/P, def_zone) +/mob/living/bullet_act(obj/item/projectile/P, def_zone, piercing_hit = FALSE) var/totaldamage = P.damage var/final_percent = 0 if(P.original != src || P.firer != src) //try to block or reflect the bullet, can't do so when shooting oneself @@ -81,7 +81,7 @@ if(returned & BLOCK_REDIRECTED) return BULLET_ACT_FORCE_PIERCE if(returned & BLOCK_SUCCESS) - P.on_hit(src, final_percent, def_zone) + P.on_hit(src, final_percent, def_zone, piercing_hit) return BULLET_ACT_BLOCK totaldamage = block_calculate_resultant_damage(totaldamage, returnlist) var/armor = run_armor_check(def_zone, P.flag, null, null, P.armour_penetration, null) @@ -118,7 +118,7 @@ throwpower = I.throwforce var/impacting_zone = ran_zone(BODY_ZONE_CHEST, 65)//Hits a random part of the body, geared towards the chest var/list/block_return = list() - var/total_damage = I.throwforce + var/total_damage = AM.throwforce if(mob_run_block(AM, throwpower, "\the [AM.name]", ATTACK_TYPE_THROWN, 0, throwingdatum?.thrower, impacting_zone, block_return) & BLOCK_SUCCESS) hitpush = FALSE skipcatch = TRUE @@ -141,7 +141,7 @@ "You're hit by [I]!") if(!I.throwforce) return - var/armor = run_armor_check(impacting_zone, "melee", "Your armor has protected your [parse_zone(impacting_zone)].", "Your armor has softened hit to your [parse_zone(impacting_zone)].",I.armour_penetration) + var/armor = run_armor_check(impacting_zone, MELEE, "Your armor has protected your [parse_zone(impacting_zone)].", "Your armor has softened hit to your [parse_zone(impacting_zone)].",I.armour_penetration) apply_damage(I.throwforce, dtype, impacting_zone, armor, sharpness=I.get_sharpness(), wound_bonus=(nosell_hit * CANT_WOUND)) else return 1 @@ -149,39 +149,6 @@ playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) ..() - -/mob/living/mech_melee_attack(obj/mecha/M) - if(M.occupant.a_intent == INTENT_HARM) - if(HAS_TRAIT(M.occupant, TRAIT_PACIFISM)) - to_chat(M.occupant, "You don't want to harm other living beings!") - return - M.do_attack_animation(src) - if(M.damtype == "brute") - step_away(src,M,15) - switch(M.damtype) - if(BRUTE) - Unconscious(20) - take_overall_damage(rand(M.force/2, M.force)) - playsound(src, 'sound/weapons/punch4.ogg', 50, 1) - if(BURN) - take_overall_damage(0, rand(M.force/2, M.force)) - playsound(src, 'sound/items/welder.ogg', 50, 1) - if(TOX) - M.mech_toxin_damage(src) - else - return - updatehealth() - visible_message("[M.name] has hit [src]!", \ - "[M.name] has hit you!", null, COMBAT_MESSAGE_RANGE, null, - M.occupant, "You hit [src] with your [M.name]!") - log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") - else - step_away(src,M) - log_combat(M.occupant, src, "pushed", M) - visible_message("[M] pushes [src] out of the way.", \ - "[M] pushes you out of the way.", null, COMBAT_MESSAGE_RANGE, null, - M.occupant, "You push [src] out of the way with your [M.name].") - /mob/living/fire_act() adjust_fire_stacks(3) IgniteMob() @@ -539,7 +506,7 @@ //called when the mob receives a bright flash -/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/flash, override_protection = 0) +/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/tiled/flash, override_protection = 0) if((override_protection || get_eye_protection() < intensity) && (override_blindness_check || !(HAS_TRAIT(src, TRAIT_BLIND)))) overlay_fullscreen("flash", type) addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 7b07dfb487..6024bfbf4c 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -107,8 +107,6 @@ var/hellbound = 0 //People who've signed infernal contracts are unrevivable. - var/list/weather_immunities = list() - var/stun_absorption = null //converted to a list of stun absorption sources this mob has when one is added var/blood_volume = 0 //how much blood the mob has diff --git a/code/modules/mob/living/living_mobility.dm b/code/modules/mob/living/living_mobility.dm index 2256a93fa1..6aed30ab83 100644 --- a/code/modules/mob/living/living_mobility.dm +++ b/code/modules/mob/living/living_mobility.dm @@ -9,6 +9,8 @@ resting = new_resting if(!silent) to_chat(src, "You are now [resting? "resting" : "getting up"].") + if(resting == 1) + SEND_SIGNAL(src, COMSIG_LIVING_RESTING) update_resting(updating) /mob/living/proc/update_resting(update_mobility = TRUE) @@ -28,7 +30,7 @@ set name = "Rest" set category = "IC" if(client?.prefs?.autostand) - TOGGLE_BITFIELD(combat_flags, COMBAT_FLAG_INTENTIONALLY_RESTING) + (combat_flags ^= COMBAT_FLAG_INTENTIONALLY_RESTING) to_chat(src, "You are now attempting to [(combat_flags & COMBAT_FLAG_INTENTIONALLY_RESTING) ? "[!resting ? "lay down and ": ""]stay down" : "[resting ? "get up and ": ""]stay up"].") if((combat_flags & COMBAT_FLAG_INTENTIONALLY_RESTING) && !resting) set_resting(TRUE, FALSE) @@ -117,14 +119,14 @@ mobility_flags &= ~(MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_STORAGE | MOBILITY_HOLD) if(HAS_TRAIT(src, TRAIT_MOBILITY_NOMOVE)) - DISABLE_BITFIELD(mobility_flags, MOBILITY_MOVE) + mobility_flags &= ~(MOBILITY_MOVE) if(HAS_TRAIT(src, TRAIT_MOBILITY_NOPICKUP)) - DISABLE_BITFIELD(mobility_flags, MOBILITY_PICKUP) + mobility_flags &= ~(MOBILITY_PICKUP) if(HAS_TRAIT(src, TRAIT_MOBILITY_NOUSE)) - DISABLE_BITFIELD(mobility_flags, MOBILITY_USE) + mobility_flags &= ~(MOBILITY_USE) if(daze) - DISABLE_BITFIELD(mobility_flags, MOBILITY_USE) + mobility_flags &= ~(MOBILITY_USE) //Handle update-effects. if(!CHECK_MOBILITY(src, MOBILITY_HOLD)) diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm index 07b40b3ab1..fcab9344d9 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/living_movement.dm @@ -20,12 +20,10 @@ /mob/living/proc/update_density() density = !lying && !HAS_TRAIT(src, TRAIT_LIVING_NO_DENSITY) -/mob/living/CanPass(atom/movable/mover, turf/target) - if((mover.pass_flags & PASSMOB)) - return TRUE - if(istype(mover, /obj/item/projectile)) - var/obj/item/projectile/P = mover - return !P.can_hit_target(src, P.permutated, src == P.original, TRUE) +/mob/living/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() + if(.) + return if(mover.throwing) return (!density || lying) if(buckled == mover) @@ -36,8 +34,12 @@ if(ismob(mover)) if(mover in buckled_mobs) return TRUE + if(HAS_TRAIT(mover, TRAIT_BEING_CARRIED)) + return TRUE //We're being carried and our carrier managed to pass, ergo, let us pass aswell. var/mob/living/L = mover //typecast first, check isliving and only check this if living using short circuit - return (!density || (isliving(mover)? L.can_move_under_living(src) : !mover.density)) + if(isliving(L) && lying && L.lying) //if we're both lying down and aren't already being thrown/shipped around, don't pass + return FALSE + return (isliving(mover)? L.can_move_under_living(src) : !mover.density) /mob/living/toggle_move_intent() . = ..() diff --git a/code/modules/mob/living/living_sprint.dm b/code/modules/mob/living/living_sprint.dm index 3fbc229385..e45866bcf6 100644 --- a/code/modules/mob/living/living_sprint.dm +++ b/code/modules/mob/living/living_sprint.dm @@ -30,7 +30,7 @@ return if(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) return - ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_ACTIVE) + combat_flags |= COMBAT_FLAG_SPRINT_ACTIVE add_movespeed_modifier(/datum/movespeed_modifier/sprinting) if(update_icon) update_sprint_icon() @@ -38,7 +38,7 @@ /mob/living/proc/disable_sprint_mode(update_icon = TRUE) if(!(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) || (combat_flags & COMBAT_FLAG_SPRINT_FORCED)) return - DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_ACTIVE) + combat_flags &= ~(COMBAT_FLAG_SPRINT_ACTIVE) remove_movespeed_modifier(/datum/movespeed_modifier/sprinting) if(update_icon) update_sprint_icon() @@ -46,7 +46,7 @@ /mob/living/proc/enable_intentional_sprint_mode() if((combat_flags & COMBAT_FLAG_SPRINT_TOGGLED) && (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE)) return - ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_TOGGLED) + combat_flags |= COMBAT_FLAG_SPRINT_TOGGLED if(!HAS_TRAIT(src, TRAIT_SPRINT_LOCKED) && !(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE)) enable_sprint_mode(FALSE) update_sprint_icon() @@ -57,7 +57,7 @@ return if(combat_flags & COMBAT_FLAG_SPRINT_FORCED) return - DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_TOGGLED) + combat_flags &= ~(COMBAT_FLAG_SPRINT_TOGGLED) if(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) disable_sprint_mode(FALSE) update_sprint_icon() diff --git a/code/modules/mob/living/update_icons.dm b/code/modules/mob/living/living_update_icons.dm similarity index 76% rename from code/modules/mob/living/update_icons.dm rename to code/modules/mob/living/living_update_icons.dm index f8d5d7e0ba..9705be3ad0 100644 --- a/code/modules/mob/living/update_icons.dm +++ b/code/modules/mob/living/living_update_icons.dm @@ -1,5 +1,5 @@ //IMPORTANT: Multiple animate() calls do not stack well, so try to do them all at once if you can. -/mob/living/update_transform() +/mob/living/update_transform(do_animate = TRUE) var/matrix/ntransform = matrix(transform) //aka transform.Copy() var/final_pixel_y = pixel_y var/changed = 0 @@ -21,5 +21,9 @@ resize = RESIZE_DEFAULT_SIZE if(changed) - animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, easing = EASE_IN|EASE_OUT) + if(do_animate) + animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, easing = EASE_IN|EASE_OUT, flags = ANIMATION_PARALLEL) + else + transform = ntransform + pixel_y = final_pixel_y floating_need_update = TRUE diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index 2b1c2de17a..30867a854f 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -2,7 +2,10 @@ ..() //Mind updates sync_mind() - mind.show_memory(src, 0) +//ambition start + if(mind.memory || mind.antag_datums) + to_chat(src, "[mind.show_memory()]") +//ambition end //Round specific stuff if(SSticker.mode) @@ -19,5 +22,10 @@ if(ranged_ability) ranged_ability.add_ranged_ability(src, "You currently have [ranged_ability] active!") + + var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling) + if(changeling) + changeling.regain_powers() + if((vore_flags & VORE_INIT) && !(vore_flags & VOREPREF_INIT)) //Vore's been initialized, voreprefs haven't. If this triggers then that means that voreprefs failed to load due to the client being missing. copy_from_prefs_vr() diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 1a925e8eaf..02a3e3684e 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -238,7 +238,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( /mob/living/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source) SEND_SIGNAL(src, COMSIG_MOVABLE_HEAR, args) //parent calls can't overwrite the current proc args. - if(!client) + if(!client && !audiovisual_redirect) return var/deaf_message var/deaf_type @@ -297,8 +297,9 @@ GLOBAL_LIST_INIT(department_radio_keys, list( AM.Hear(rendered, src, message_language, message, null, spans, message_mode, source) SEND_GLOBAL_SIGNAL(COMSIG_GLOB_LIVING_SAY_SPECIAL, src, message) - if(!eavesdrop_range && say_test(message) == "2") // Yell hook - process_yelling(listening, rendered, src, message_language, message, spans, message_mode, source) + var/is_yell = (say_test(message) == "2") + if(client && !eavesdrop_range && is_yell) // Yell hook + listening |= process_yelling(listening, rendered, src, message_language, message, spans, message_mode, source) //speech bubble var/list/speech_bubble_recipients = list() @@ -309,6 +310,23 @@ GLOBAL_LIST_INIT(department_radio_keys, list( I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_recipients, 30) + //Listening gets trimmed here if a vocal bark's present. If anyone ever makes this proc return listening, make sure to instead initialize a copy of listening in here to avoid wonkiness + if(SEND_SIGNAL(src, COMSIG_MOVABLE_QUEUE_BARK, listening, args) || vocal_bark || vocal_bark_id) + for(var/mob/M in listening) + if(!M.client) + continue + if(!(M.client.prefs.toggles & SOUND_BARK)) + listening -= M + var/barks = min(round((LAZYLEN(message) / vocal_speed)) + 1, BARK_MAX_BARKS) + var/total_delay + vocal_current_bark = world.time + for(var/i in 1 to barks) + if(total_delay > BARK_MAX_TIME) + break + addtimer(CALLBACK(src, /atom/movable/proc/bark, listening, (message_range * (is_yell ? 4 : 1)), (vocal_volume * (is_yell ? 1.5 : 1)), BARK_DO_VARY(vocal_pitch, vocal_pitch_range), vocal_current_bark), total_delay) + total_delay += rand(DS2TICKS(vocal_speed / BARK_SPEED_BASELINE), DS2TICKS(vocal_speed / BARK_SPEED_BASELINE) + DS2TICKS((vocal_speed / BARK_SPEED_BASELINE) * (is_yell ? 0.5 : 1))) TICKS + + /atom/movable/proc/process_yelling(list/already_heard, rendered, atom/movable/speaker, datum/language/message_language, message, list/spans, message_mode, obj/source) if(last_yell > (world.time - 10)) to_chat(src, "Your voice doesn't project as far as you try to yell in such quick succession.") // yeah no, no spamming an expensive floodfill. @@ -333,6 +351,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list( var/atom/movable/AM = _AM AM.Hear(rendered, speaker, message_language, message, null, spans, message_mode, source) + return overhearing + /mob/proc/binarycheck() return FALSE diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index b2b1d2fb5f..08098b818f 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -38,8 +38,8 @@ var/can_be_carded = TRUE var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list()) var/viewalerts = 0 - var/icon/holo_icon//Female is assigned when AI is created. - var/obj/mecha/controlled_mech //For controlled_mech a mech, to determine whether to relaymove or use the AI eye. + var/icon/holo_icon //Female is assigned when AI is created. + var/obj/controlled_equipment //A piece of equipment, to determine whether to relaymove or use the AI eye. var/radio_enabled = TRUE //Determins if a carded AI can speak with its built in radio or not. radiomod = ";" //AIs will, by default, state their laws on the internal radio. var/obj/item/pda/ai/aiPDA @@ -47,6 +47,7 @@ var/mob/living/simple_animal/bot/Bot var/tracking = FALSE //this is 1 if the AI is currently tracking somebody, but the track has not yet been completed. var/datum/effect_system/spark_spread/spark_system//So they can initialize sparks whenever/N + var/obj/machinery/status_display/controlled_display //MALFUNCTION var/datum/module_picker/malf_picker @@ -98,6 +99,13 @@ var/display_icon_override var/emote_display = "Neutral" //text string of the current emote we set for the status displays, to prevent logins resetting it. + var/datum/robot_control/robot_control + /// Station alert datum for showing alerts UI + var/datum/station_alert/alert_control + ///remember AI's last location + var/atom/lastloc + interaction_range = INFINITY + /mob/living/silicon/ai/Initialize(mapload, datum/ai_laws/L, mob/target_ai) . = ..() if(!target_ai) //If there is no player/brain inside. @@ -172,10 +180,21 @@ GLOB.ai_list -= src GLOB.shuttle_caller_list -= src SSshuttle.autoEvac() - qdel(eyeobj) // No AI, no Eye + QDEL_NULL(eyeobj) // No AI, no Eye + QDEL_NULL(spark_system) + QDEL_NULL(malf_picker) + QDEL_NULL(doomsday_device) + // TODO: Why these no work? + // QDEL_NULL(robot_control) + QDEL_NULL(aiMulti) + // QDEL_NULL(alert_control) malfhack = null - - . = ..() + current = null + Bot = null + controlled_equipment = null + linked_core = null + apc_override = null + return ..() /mob/living/silicon/ai/IgniteMob() fire_stacks = 0 @@ -408,8 +427,8 @@ return if (href_list["ai_take_control"]) //Mech domination - var/obj/mecha/M = locate(href_list["ai_take_control"]) - if(controlled_mech) + var/obj/vehicle/sealed/mecha/M = locate(href_list["ai_take_control"]) + if(controlled_equipment) to_chat(src, "You are already loaded into an onboard computer!") return if(!GLOB.cameranet.checkCameraVis(M)) @@ -492,43 +511,61 @@ call_bot_cooldown = 0 -/mob/living/silicon/ai/triggerAlarm(class, area/A, O, obj/alarmsource) - if(alarmsource.z != z) +/mob/living/silicon/ai/triggerAlarm(class, area/home, cameras, obj/source) + if(source.z != z) return - var/list/L = alarms[class] - for (var/I in L) - if (I == A.name) - var/list/alarm = L[I] + var/list/our_sort = alarms[class] + for(var/areaname in our_sort) + if (areaname == home.name) + var/list/alarm = our_sort[areaname] var/list/sources = alarm[3] - if (!(alarmsource in sources)) - sources += alarmsource - return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if (O && istype(O, /list)) - CL = O - if (CL.len == 1) - C = CL[1] - else if (O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C) ? C : O, list(alarmsource)) - if (O) - if (C && C.can_use()) - queueAlarm("--- [class] alarm detected in [A.name]! ([C.c_tag])", class) - else if (CL && CL.len) + if (!(source in sources)) + sources += source + return TRUE + + var/obj/machinery/camera/cam = null + var/list/our_cams = null + if(cameras && islist(cameras)) + our_cams = cameras + if (our_cams.len == 1) + cam = our_cams[1] + else if(cameras && istype(cameras, /obj/machinery/camera)) + cam = cameras + our_sort[home.name] = list(home, (cam ? cam : cameras), list(source)) + + if (cameras) + if (cam?.can_use()) + queueAlarm("--- [class] alarm detected in [home.name]! ([cam.c_tag])", class) + else if (our_cams?.len) var/foo = 0 var/dat2 = "" - for (var/obj/machinery/camera/I in CL) + for (var/obj/machinery/camera/I in our_cams) dat2 += text("[][]", (!foo) ? "" : " | ", I.c_tag) //I'm not fixing this shit... foo = 1 - queueAlarm(text ("--- [] alarm detected in []! ([])", class, A.name, dat2), class) + queueAlarm(text ("--- [] alarm detected in []! ([])", class, home.name, dat2), class) else - queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, A.name), class) + queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, home.name), class) else - queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, A.name), class) - if (viewalerts) ai_alerts() + queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, home.name), class) + if (viewalerts) + ai_alerts() return 1 +/mob/living/silicon/ai/freeCamera(area/home, obj/machinery/camera/cam) + for(var/class in alarms) + var/our_area = alarms[class][home.name] + if(!our_area) + continue + var/cams = our_area[2] //Get the cameras + if(!cams) + continue + if(islist(cams)) + cams -= cam + if(length(cams) == 1) + our_area[2] = cams[1] + else + our_area[2] = null + /mob/living/silicon/ai/cancelAlarm(class, area/A, obj/origin) var/list/L = alarms[class] var/cleared = 0 @@ -660,7 +697,7 @@ "goat" = 'icons/mob/animal.dmi', "cat" = 'icons/mob/pets.dmi', "cat2" = 'icons/mob/pets.dmi', - "poly" = 'icons/mob/animal.dmi', + "polly" = 'icons/mob/animal.dmi', "pug" = 'icons/mob/pets.dmi', "spider" = 'icons/mob/animal.dmi' ) @@ -669,7 +706,7 @@ if(input) qdel(holo_icon) switch(input) - if("poly") + if("polly") holo_icon = getHologramIcon(icon(icon_list[input],"parrot_fly")) if("chicken") holo_icon = getHologramIcon(icon(icon_list[input],"chicken_brown")) @@ -1043,3 +1080,14 @@ /mob/living/silicon/ai/zMove(dir, feedback = FALSE) . = eyeobj.zMove(dir, feedback) + +/mob/living/silicon/ai/proc/stop_controlling_display() + if(!controlled_display) + return + controlled_display.master = null + controlled_display.cut_overlay(controlled_display.ai_vtuber_overlay) + controlled_display.ai_vtuber_overlay = null + if(current == controlled_display) + current = null + controlled_display.update_appearance() + controlled_display = null diff --git a/code/modules/mob/living/silicon/ai/ai_defense.dm b/code/modules/mob/living/silicon/ai/ai_defense.dm index b05b5f1aaf..b8a0a15e70 100644 --- a/code/modules/mob/living/silicon/ai/ai_defense.dm +++ b/code/modules/mob/living/silicon/ai/ai_defense.dm @@ -28,7 +28,7 @@ if(2) SSshuttle.requestEvac(src,"ALERT: Energy surge detected in AI core! Station integrity may be compromised! Initiati--%m091#ar-BZZT") -/mob/living/silicon/ai/ex_act(severity, target) +/mob/living/silicon/ai/ex_act(severity, target, origin) switch(severity) if(1) gib() diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index afabafd929..14f9490481 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -2,6 +2,10 @@ if(stat == DEAD) return + if(!gibbed) + // Will update all AI status displays with a blue screen of death + INVOKE_ASYNC(src, .proc/emote, "bsod") + . = ..() var/old_icon = icon_state @@ -29,12 +33,6 @@ spawn(10) explosion(src.loc, 3, 6, 12, 15) - if(src.key) - for(var/each in GLOB.ai_status_displays) //change status - var/obj/machinery/status_display/ai/O = each - O.mode = 2 - O.update() - if(istype(loc, /obj/item/aicard/aitater)) loc.icon_state = "aitater-404" else if(istype(loc, /obj/item/aicard/aispook)) diff --git a/code/modules/mob/living/silicon/ai/emote.dm b/code/modules/mob/living/silicon/ai/emote.dm new file mode 100644 index 0000000000..c48fefbe1f --- /dev/null +++ b/code/modules/mob/living/silicon/ai/emote.dm @@ -0,0 +1,101 @@ +/datum/emote/ai + mob_type_allowed_typecache = /mob/living/silicon/ai + mob_type_blacklist_typecache = list() + + +/datum/emote/ai/emotion_display + key = "blank" + var/emotion = AI_EMOTION_BLANK + +/datum/emote/ai/emotion_display/run_emote(mob/user, params, type_override, intentional) + . = ..() + if(!.) + return + var/mob/living/silicon/ai/ai = user + var/turf/ai_turf = get_turf(ai) + + for(var/_display in GLOB.ai_status_displays) + var/obj/machinery/status_display/ai/ai_display = _display + var/turf/display_turf = get_turf(ai_display) + + // Derelict AIs can't affect station displays. + // TODO does this need to be made multiZ aware? + if(ai_turf.z != display_turf.z) + continue + + ai_display.emotion = emotion + ai_display.update() + +/datum/emote/ai/emotion_display/very_happy + key = "veryhappy" + emotion = AI_EMOTION_VERY_HAPPY + +/datum/emote/ai/emotion_display/happy + key = "happy" + emotion = AI_EMOTION_HAPPY + +/datum/emote/ai/emotion_display/neutral + key = "neutral" + emotion = AI_EMOTION_NEUTRAL + +/datum/emote/ai/emotion_display/unsure + key = "unsure" + emotion = AI_EMOTION_UNSURE + +/datum/emote/ai/emotion_display/confused + key = "confused" + emotion = AI_EMOTION_CONFUSED + +/datum/emote/ai/emotion_display/sad + key = "sad" + emotion = AI_EMOTION_SAD + +/datum/emote/ai/emotion_display/bsod + key = "bsod" + emotion = AI_EMOTION_BSOD + +/datum/emote/ai/emotion_display/trollface + key = "trollface" + emotion = AI_EMOTION_PROBLEMS + +/datum/emote/ai/emotion_display/awesome + key = "awesome" + emotion = AI_EMOTION_AWESOME + +/datum/emote/ai/emotion_display/dorfy + key = "dorfy" + emotion = AI_EMOTION_DORFY + +/datum/emote/ai/emotion_display/thinking + key = "thinking" + emotion = AI_EMOTION_THINKING + +/datum/emote/ai/emotion_display/facepalm + key = "facepalm" + key_third_person = "facepalms" + emotion = AI_EMOTION_FACEPALM + +/datum/emote/ai/emotion_display/friend_computer + key = "friendcomputer" + emotion = AI_EMOTION_FRIEND_COMPUTER + +/datum/emote/ai/emotion_display/friend_computer/run_emote(mob/user, params, type_override, intentional) + . = ..() + if(!.) + return + + var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS) + + if(!frequency) + return + + var/datum/signal/status_signal = new(list("command" = "friendcomputer")) + frequency.post_signal(src, status_signal) + +/datum/emote/ai/emotion_display/blue_glow + key = "blueglow" + emotion = AI_EMOTION_BLUE_GLOW + +/datum/emote/ai/emotion_display/red_glow + key = "redglow" + emotion = AI_EMOTION_RED_GLOW diff --git a/code/modules/mob/living/silicon/ai/examine.dm b/code/modules/mob/living/silicon/ai/examine.dm index 4cf9b81592..86de4c7c60 100644 --- a/code/modules/mob/living/silicon/ai/examine.dm +++ b/code/modules/mob/living/silicon/ai/examine.dm @@ -1,5 +1,5 @@ /mob/living/silicon/ai/examine(mob/user) - . = list("*---------*\nThis is [icon2html(src, user)] [src]!") + . = list("This is [icon2html(src, user)] [src]!") if (stat == DEAD) . += "It appears to be powered-down." else @@ -17,6 +17,8 @@ . += "The wireless networking light is blinking." else if (!shunted && !client) . += "[src]Core.exe has stopped responding! NTOS is searching for a solution to the problem..." - . += "*---------*" + + if(LAZYLEN(.) > 1) + .[2] = "
    [.[2]]" . += ..() diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index dcaa28b39c..bce18462b2 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -18,7 +18,7 @@ var/ai_detector_visible = TRUE var/ai_detector_color = COLOR_RED -/mob/camera/aiEye/Initialize() +/mob/camera/aiEye/Initialize(mapload) . = ..() GLOB.aiEyes += src update_ai_detect_hud() @@ -84,7 +84,6 @@ if(ai.client && !ai.multicam_on) ai.client.eye = src update_ai_detect_hud() - update_parallax_contents() //Holopad if(istype(ai.current, /obj/machinery/holopad)) var/obj/machinery/holopad/H = ai.current @@ -93,6 +92,8 @@ ai.light_cameras() if(ai.master_multicam) ai.master_multicam.refresh_view() + if(ai.controlled_display) + ai.stop_controlling_display() //it uses setLoc not forceMove, talks to the sillycone and not the camera mob /mob/camera/aiEye/zMove(dir, feedback = FALSE) @@ -169,6 +170,9 @@ if(!user.tracking) user.cameraFollow = null + if(user.controlled_display) + user.stop_controlling_display() + // Return to the Core. /mob/living/silicon/ai/proc/view_core() if(istype(current,/obj/machinery/holopad)) diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 2cbd1f35ca..ed969e49fb 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -3,7 +3,7 @@ #define POWER_RESTORATION_SEARCH_APC 2 #define POWER_RESTORATION_APC_FOUND 3 -/mob/living/silicon/ai/BiologicalLife(seconds, times_fired) +/mob/living/silicon/ai/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return //I'm not removing that shitton of tabs, unneeded as they are. -- Urist @@ -53,11 +53,11 @@ if(NONE) return FALSE if(POWER_REQ_ALL) - return !T || !A || ((!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha))) + return !T || !A || ((!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/vehicle/sealed/mecha))) if(POWER_REQ_CLOCKCULT) for(var/obj/effect/clockwork/sigil/transmission/ST in range(src, SIGIL_ACCESS_RANGE)) return FALSE - return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha))) + return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/vehicle/sealed/mecha))) /mob/living/silicon/ai/updatehealth() if(status_flags & GODMODE) diff --git a/code/modules/mob/living/silicon/ai/login.dm b/code/modules/mob/living/silicon/ai/login.dm index 36e87a8e16..a1826c38af 100644 --- a/code/modules/mob/living/silicon/ai/login.dm +++ b/code/modules/mob/living/silicon/ai/login.dm @@ -1,11 +1,5 @@ /mob/living/silicon/ai/Login() ..() - if(stat != DEAD) - for(var/each in GLOB.ai_status_displays) //change status - var/obj/machinery/status_display/ai/O = each - O.mode = 1 - O.emotion = emote_display - O.update() set_eyeobj_visible(TRUE) if(multicam_on) end_multicam() diff --git a/code/modules/mob/living/silicon/ai/logout.dm b/code/modules/mob/living/silicon/ai/logout.dm index 73161f12d5..a027871716 100644 --- a/code/modules/mob/living/silicon/ai/logout.dm +++ b/code/modules/mob/living/silicon/ai/logout.dm @@ -1,8 +1,4 @@ /mob/living/silicon/ai/Logout() ..() - for(var/each in GLOB.ai_status_displays) //change status - var/obj/machinery/status_display/ai/O = each - O.mode = 0 - O.update() set_eyeobj_visible(FALSE) view_core() diff --git a/code/modules/mob/living/silicon/ai/multicam.dm b/code/modules/mob/living/silicon/ai/multicam.dm index 54713acac4..b48b39a885 100644 --- a/code/modules/mob/living/silicon/ai/multicam.dm +++ b/code/modules/mob/living/silicon/ai/multicam.dm @@ -6,7 +6,7 @@ var/highlighted = FALSE var/mob/camera/aiEye/pic_in_pic/aiEye -/atom/movable/screen/movable/pic_in_pic/ai/Initialize() +/atom/movable/screen/movable/pic_in_pic/ai/Initialize(mapload) . = ..() aiEye = new /mob/camera/aiEye/pic_in_pic() aiEye.screen = src @@ -103,7 +103,7 @@ GLOBAL_DATUM(ai_camera_room_landmark, /obj/effect/landmark/ai_multicam_room) icon = 'icons/mob/landmarks.dmi' icon_state = "x" -/obj/effect/landmark/ai_multicam_room/Initialize() +/obj/effect/landmark/ai_multicam_room/Initialize(mapload) . = ..() qdel(GLOB.ai_camera_room_landmark) GLOB.ai_camera_room_landmark = src diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index 2b5d3d98f2..76eaa6ad0d 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -34,8 +34,6 @@ //For holopads only. Usable by AI. /mob/living/silicon/ai/proc/holopad_talk(message, language) - - message = trim(message) if (!message) @@ -56,6 +54,29 @@ to_chat(src, "No holopad connected.") +//For status displays only. Usable by AI. +/mob/living/silicon/ai/proc/statusdisplay_talk(message, language) + message = trim(message) + + if (!message) + return + + var/obj/machinery/status_display/T = controlled_display + if(T) + var/turf/padturf = get_turf(T) + var/padloc + if(padturf) + padloc = AREACOORD(padturf) + else + padloc = "(UNKNOWN)" + src.log_talk(message, LOG_SAY, tag="STATUS DISPLAY in [padloc]") + send_speech(message, 7, T, "robot", message_language = language) + to_chat(src, "Status Display message transmitted, [real_name] \"[message]\"") + else + to_chat(src, "No status display connected.") + + + // Make sure that the code compiles with AI_VOX undefined #ifdef AI_VOX #define VOX_DELAY 600 diff --git a/code/modules/mob/living/silicon/damage_procs.dm b/code/modules/mob/living/silicon/damage_procs.dm index f49c5933bb..b50aeb5f48 100644 --- a/code/modules/mob/living/silicon/damage_procs.dm +++ b/code/modules/mob/living/silicon/damage_procs.dm @@ -9,9 +9,6 @@ adjustBruteLoss(damage_amount, forced = forced) if(BURN) adjustFireLoss(damage_amount, forced = forced) - if(OXY) - if(damage < 0 || forced) //we shouldn't be taking oxygen damage through this proc, but we'll let it heal. - adjustOxyLoss(damage_amount, forced = forced) return 1 @@ -30,7 +27,7 @@ /mob/living/silicon/setCloneLoss(amount, updating_health = TRUE, forced = FALSE) return FALSE -/mob/living/silicon/adjustStaminaLoss(amount, updating_health = 1, forced = FALSE)//immune to stamina damage. +/mob/living/silicon/adjustStaminaLoss(amount, updating_health = 1, forced = FALSE) //immune to stamina damage. return FALSE /mob/living/silicon/setStaminaLoss(amount, updating_health = 1) @@ -41,3 +38,15 @@ /mob/living/silicon/setOrganLoss(slot, amount) return FALSE + +/mob/living/silicon/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE) //immune to oxygen damage + if(istype(src, /mob/living/silicon/ai)) //ais are snowflakes and use oxyloss for being in AI cards and having no battery + return ..() + + return FALSE + +/mob/living/silicon/setOxyLoss(amount, updating_health = TRUE, forced = FALSE) + if(istype(src, /mob/living/silicon/ai)) //ditto + return ..() + + return FALSE diff --git a/code/modules/mob/living/silicon/examine.dm b/code/modules/mob/living/silicon/examine.dm index 7de281de5f..0840ea1191 100644 --- a/code/modules/mob/living/silicon/examine.dm +++ b/code/modules/mob/living/silicon/examine.dm @@ -1,5 +1,4 @@ /mob/living/silicon/examine(mob/user) //Displays a silicon's laws to ghosts - . = ..() if(laws && isobserver(user)) . += "[src] has the following laws:" for(var/law in laws.get_law_list(include_zeroth = TRUE)) diff --git a/code/modules/mob/living/silicon/login.dm b/code/modules/mob/living/silicon/login.dm index 7b1854b940..ddc47465a4 100644 --- a/code/modules/mob/living/silicon/login.dm +++ b/code/modules/mob/living/silicon/login.dm @@ -11,3 +11,10 @@ if(G) mind.remove_antag_datum(G) ..() + +/mob/living/silicon/auto_deadmin_on_login() + if(!client?.holder) + return TRUE + if(CONFIG_GET(flag/auto_deadmin_silicons) || (client.prefs?.deadmin & DEADMIN_POSITION_SILICON)) + return client.holder.auto_deadmin() + return ..() diff --git a/code/modules/mob/living/silicon/pai/death.dm b/code/modules/mob/living/silicon/pai/death.dm index c60d84438c..07cb671706 100644 --- a/code/modules/mob/living/silicon/pai/death.dm +++ b/code/modules/mob/living/silicon/pai/death.dm @@ -4,9 +4,9 @@ stat = DEAD update_mobility() update_sight() - clear_fullscreens() + wipe_fullscreens() //New pAI's get a brand new mind to prevent meta stuff from their previous life. This new mind causes problems down the line if it's not deleted here. - GLOB.alive_mob_list -= src + remove_from_alive_mob_list() ghostize() qdel(src) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 4e33fba208..435d1853f6 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -6,7 +6,6 @@ pass_flags = PASSTABLE | PASSMOB mob_size = MOB_SIZE_TINY desc = "A generic pAI mobile hard-light holographics emitter. It seems to be deactivated." - weather_immunities = list("ash") health = 500 maxHealth = 500 layer = BELOW_MOB_LAYER @@ -95,7 +94,7 @@ GLOB.pai_list -= src return ..() -/mob/living/silicon/pai/Initialize() +/mob/living/silicon/pai/Initialize(mapload) var/obj/item/paicard/P = loc START_PROCESSING(SSfastprocess, src) GLOB.pai_list += src @@ -143,7 +142,7 @@ custom_holoform.Grant(src) emitter_next_use = world.time + 10 SECONDS -/mob/living/silicon/pai/deployed/Initialize() +/mob/living/silicon/pai/deployed/Initialize(mapload) . = ..() fold_out(TRUE) @@ -152,7 +151,7 @@ if(possible_chassis[chassis]) AddElement(/datum/element/mob_holder, chassis, 'icons/mob/pai_item_head.dmi', 'icons/mob/pai_item_rh.dmi', 'icons/mob/pai_item_lh.dmi', ITEM_SLOT_HEAD) -/mob/living/silicon/pai/BiologicalLife(seconds, times_fired) +/mob/living/silicon/pai/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(hacking) @@ -200,6 +199,13 @@ /mob/living/silicon/pai/restrained(ignore_grab) . = FALSE +/mob/living/silicon/pai/can_interact_with(atom/target) + if(istype(target, /obj/item/mod/control)) // A poor workaround for enabling MODsuit control + var/obj/item/mod/control/C = target + if(C.ai == src) + return TRUE + return ..() + // See software.dm for Topic() /mob/living/silicon/pai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) @@ -322,6 +328,41 @@ else to_chat(user, "Encryption Key ports not configured.") +/obj/item/paicard/attack_ghost(mob/dead/observer/user) + if(pai) + to_chat(user, "This pAI is already in use!") + return + + var/area/A = get_area(get_turf(src)) + if(A.type in SSpai.restricted_areas) // set in subsystem/pai.dm on initialize of the subsystem + to_chat(user, "You can't download yourself into a restricted area!") + return + + var/pai_name = reject_bad_name(stripped_input(usr, "Enter a name for your pAI", "pAI Name", user.name, MAX_NAME_LEN), TRUE) + if(!pai_name) + to_chat(user, "Entered name is not valid.") + return + + var/mob/living/silicon/pai/new_pai = new(src) + new_pai.name = pai_name + new_pai.real_name = new_pai.name + new_pai.key = user.key + + setPersonality(new_pai) + + SSticker.mode.update_cult_icons_removed(pai.mind) + +/obj/item/paicard/emag_act(mob/user) // Emag to wipe the master DNA and supplemental directive + . = ..() + if(!pai) + return + to_chat(user, "You override [pai]'s directive system, clearing its master string and supplied directive.") + to_chat(pai, "Warning: System override detected, check directive sub-system for any changes.'") + log_game("[key_name(user)] emagged [key_name(pai)], wiping their master DNA and supplemental directive.") + pai.master = null + pai.master_dna = null + pai.laws.supplied[1] = "None." // Sets supplemental directive to this + /mob/living/silicon/pai/proc/short_radio() if(radio_short_timerid) deltimer(radio_short_timerid) diff --git a/code/modules/mob/living/silicon/pai/pai_defense.dm b/code/modules/mob/living/silicon/pai/pai_defense.dm index c339aa920f..e54d5e05b7 100644 --- a/code/modules/mob/living/silicon/pai/pai_defense.dm +++ b/code/modules/mob/living/silicon/pai/pai_defense.dm @@ -1,5 +1,3 @@ -#define PAI_EMP_SILENCE_DURATION 3 MINUTES - /mob/living/silicon/pai/blob_act(obj/structure/blob/B) return FALSE @@ -9,13 +7,13 @@ return take_holo_damage(severity/2) DefaultCombatKnockdown(severity*4) - silent = max(silent, (PAI_EMP_SILENCE_DURATION) / SSmobs.wait / severity) + short_radio() if(holoform) fold_in(force = TRUE) emitter_next_use = world.time + emitter_emp_cd //Need more effects that aren't instadeath or permanent law corruption. -/mob/living/silicon/pai/ex_act(severity, target) +/mob/living/silicon/pai/ex_act(severity, target, origin) take_holo_damage(severity * 50) switch(severity) if(1) //RIP @@ -87,15 +85,6 @@ /mob/living/silicon/pai/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, only_robotic = FALSE, only_organic = TRUE) return take_holo_damage(amount) -/mob/living/silicon/pai/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, toxins_type = TOX_DEFAULT) - return FALSE - -/mob/living/silicon/pai/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE) - return FALSE - -/mob/living/silicon/pai/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE) - return FALSE - /mob/living/silicon/pai/adjustStaminaLoss(amount, updating_health, forced = FALSE) if(forced) take_holo_damage(amount) @@ -110,27 +99,3 @@ /mob/living/silicon/pai/getFireLoss() return emittermaxhealth - emitterhealth - -/mob/living/silicon/pai/getToxLoss(toxins_type = TOX_OMNI) - return FALSE - -/mob/living/silicon/pai/getOxyLoss() - return FALSE - -/mob/living/silicon/pai/getCloneLoss() - return FALSE - -/mob/living/silicon/pai/getStaminaLoss() - return FALSE - -/mob/living/silicon/pai/setCloneLoss() - return FALSE - -/mob/living/silicon/pai/setStaminaLoss() - return FALSE - -/mob/living/silicon/pai/setToxLoss(toxins_type = TOX_OMNI) - return FALSE - -/mob/living/silicon/pai/setOxyLoss() - return FALSE diff --git a/code/modules/mob/living/silicon/pai/update_icon.dm b/code/modules/mob/living/silicon/pai/pai_update_icon.dm similarity index 100% rename from code/modules/mob/living/silicon/pai/update_icon.dm rename to code/modules/mob/living/silicon/pai/pai_update_icon.dm diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm index d499c2abae..5563f47e61 100644 --- a/code/modules/mob/living/silicon/robot/emote.dm +++ b/code/modules/mob/living/silicon/robot/emote.dm @@ -8,7 +8,7 @@ var/unrestricted = TRUE /datum/emote/sound/silicon/run_emote(mob/user, params) - if(!unrestricted && !(issilicon(user) || isipcperson(user))) + if(!unrestricted && !(issilicon(user) || isrobotic(user))) return return ..() diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm index 45a3d15635..4ebd4c3be8 100644 --- a/code/modules/mob/living/silicon/robot/examine.dm +++ b/code/modules/mob/living/silicon/robot/examine.dm @@ -1,5 +1,5 @@ /mob/living/silicon/robot/examine(mob/user) - . = list("*---------*\nThis is [icon2html(src, user)] \a [src], a [src.module.name] unit!") + . = list("This is [icon2html(src, user)] \a [src], a [src.module.name] unit!") if(desc) . += "[desc]" @@ -49,8 +49,9 @@ if(DEAD) . += "It looks like its system is corrupted and requires a reset." + if(LAZYLEN(.) > 1) + .[2] = "
    [.[2]]" + SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, usr, .) - . += "*---------*
    " - . += ..() diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index b11737659c..559ffbbc08 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -3,12 +3,15 @@ /** * Returns the thing in our active hand (whatever is in our active module-slot, in this case) + * + * Arguments + * * get_gripper - If the active module is a gripper, should we return the gripper or the contained item? (if the gripper contains nothing, returns the gripper anyways) */ -/mob/living/silicon/robot/get_active_held_item() +/mob/living/silicon/robot/get_active_held_item(get_gripper = FALSE) var/item = module_active // snowflake handler for the gripper - if(istype(item, /obj/item/weapon/gripper)) - var/obj/item/weapon/gripper/G = item + if(istype(item, /obj/item/gripper) && !get_gripper) + var/obj/item/gripper/G = item if(G.wrapped) if(G.wrapped.loc != G) G.wrapped = null @@ -284,9 +287,14 @@ /** * Unequips the active held item, if there is one. + * + * Will always consider dropping gripper contents first. */ /mob/living/silicon/robot/proc/uneq_active() if(module_active) + var/obj/item/gripper/gripper = get_active_held_item(TRUE) + if(istype(gripper) && gripper.drop_held()) + return unequip_module_from_slot(module_active, get_selected_module()) /** @@ -302,11 +310,12 @@ * Checks if the item is currently in a slot. * * If the item is found in a slot, this returns TRUE. Otherwise, it returns FALSE + * Modified to accept items inside of grippers, used for `code\modules\tgui\states\hands.dm:27` * Arguments * * item_module - the item being checked */ /mob/living/silicon/robot/proc/activated(obj/item/item_module) - if(item_module in held_items) + if(get_active_held_item() == item_module || (item_module in held_items)) return TRUE return FALSE diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index d1eaeeacc5..8a0b8def51 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -1,7 +1,6 @@ -/mob/living/silicon/robot/BiologicalLife(seconds, times_fired) +/mob/living/silicon/robot/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return - adjustOxyLoss(-10) //we're a robot! handle_robot_hud_updates() handle_robot_cell() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 9658247da3..232c5b4195 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -4,6 +4,7 @@ icon = 'icons/mob/robots.dmi' icon_state = "robot" bubble_icon = "robot" + var/obj/item/pda/ai/aiPDA /mob/living/silicon/robot/get_cell() return cell @@ -27,6 +28,12 @@ inv2 = new /atom/movable/screen/robot/module2() inv3 = new /atom/movable/screen/robot/module3() + if(!shell) + aiPDA = new/obj/item/pda/ai(src) + aiPDA.owner = real_name + aiPDA.ownjob = "Cyborg" + aiPDA.name = real_name + " (" + aiPDA.ownjob + ")" + previous_health = health if(ispath(cell)) @@ -95,8 +102,8 @@ if(mmi.brainmob) if(mmi.brainmob.stat == DEAD) mmi.brainmob.stat = CONSCIOUS - GLOB.dead_mob_list -= mmi.brainmob - GLOB.alive_mob_list += mmi.brainmob + mmi.brainmob.remove_from_dead_mob_list() + mmi.brainmob.add_to_alive_mob_list() mind.transfer_to(mmi.brainmob) mmi.update_icon() else @@ -255,31 +262,47 @@ /mob/living/silicon/robot/restrained(ignore_grab) . = 0 -/mob/living/silicon/robot/triggerAlarm(class, area/A, O, obj/alarmsource) - if(alarmsource.z != z) +/mob/living/silicon/robot/triggerAlarm(class, area/home, cameras, obj/source) + if(source.z != z) return if(stat == DEAD) return 1 - var/list/L = alarms[class] - for (var/I in L) - if (I == A.name) - var/list/alarm = L[I] + var/list/our_sort = alarms[class] + for(var/areaname in our_sort) + if (areaname == home.name) + var/list/alarm = our_sort[areaname] var/list/sources = alarm[3] - if (!(alarmsource in sources)) - sources += alarmsource + if (!(source in sources)) + sources += source return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if (O && istype(O, /list)) - CL = O - if (CL.len == 1) - C = CL[1] - else if (O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C) ? C : O, list(alarmsource)) - queueAlarm(text("--- [class] alarm detected in [A.name]!"), class) + + var/obj/machinery/camera/cam = null + var/list/our_cams = null + if(cameras && islist(cameras)) + our_cams = cameras + if (our_cams.len == 1) + cam = our_cams[1] + else if(cameras && istype(cameras, /obj/machinery/camera)) + cam = cameras + our_sort[home.name] = list(home, (cam ? cam : cameras), list(source)) + queueAlarm(text("--- [class] alarm detected in [home.name]!"), class) return TRUE +/mob/living/silicon/robot/freeCamera(area/home, obj/machinery/camera/cam) + for(var/class in alarms) + var/our_area = alarms[class][home.name] + if(!our_area) + continue + var/cams = our_area[2] //Get the cameras + if(!cams) + continue + if(islist(cams)) + cams -= cam + if(length(cams) == 1) + our_area[2] = cams[1] + else + our_area[2] = null + /mob/living/silicon/robot/cancelAlarm(class, area/A, obj/origin) var/list/L = alarms[class] var/cleared = 0 @@ -731,7 +754,7 @@ /mob/living/silicon/robot/modules var/set_module = /obj/item/robot_module -/mob/living/silicon/robot/modules/Initialize() +/mob/living/silicon/robot/modules/Initialize(mapload) . = ..() module.transform_to(set_module) @@ -772,7 +795,7 @@ cell = /obj/item/stock_parts/cell/hyper // radio = /obj/item/radio/borg/syndicate -/mob/living/silicon/robot/modules/syndicate/Initialize() +/mob/living/silicon/robot/modules/syndicate/Initialize(mapload) . = ..() radio = new /obj/item/radio/borg/syndicate(src) laws = new /datum/ai_laws/syndicate_override() @@ -811,6 +834,32 @@ Help the operatives secure the disk at all costs!
    " set_module = /obj/item/robot_module/saboteur +/mob/living/silicon/robot/modules/syndicate/spider// used for space ninja and their cyborg hacking special objective + bubble_icon = "spider" + playstyle_string = "You are a Spider Clan assault cyborg!
    \ + You are armed with powerful offensive tools to aid you in your mission: obey your ninja masters by any means necessary. \ + Your cyborg LMG will slowly produce ammunition from your power supply, and your pinpointer will find and locate fellow members of the Spider Clan." + set_module = /obj/item/robot_module/syndicate/spider + +/mob/living/silicon/robot/modules/syndicate_medical/spider// ditto + bubble_icon = "spider" + var/playstyle_string = "You are a Spider Clan medical cyborg!
    \ + You are armed with powerful medical tools to aid you in your mission: obey your ninja masters by any means necessary. \ + Your hypospray will produce Restorative Nanites, a wonder-drug that will heal most types of bodily damages, including clone and brain damage. It also produces morphine for offense. \ + Your defibrillator paddles can revive allies through their hardsuits, or can be used on harm intent to shock enemies! \ + Your energy saw functions as a circular saw, but can be activated to deal more damage, and your pinpointer will find and locate fellow members of the Spider Clan." + set_module = /obj/item/robot_module/syndicate_medical/spider + +/mob/living/silicon/robot/modules/saboteur/spider// ditto + bubble_icon = "spider" + var/playstyle_string = "You are a Spider Clan saboteur cyborg!
    \ + You are armed with robust engineering tools to aid you in your mission: obey your ninja masters by any means necessary. \ + Your destination tagger will allow you to stealthily traverse the disposal network across the station. \ + Your welder will can be used to repair yourself or any allied silicon units, while serving as an impromptu melee weapon. \ + Your cyborg chameleon projector allows you to assume the appearance and registered name of a Nanotrasen engineering borg, and undertake covert actions on the station, \ + be aware that almost any physical contact or incidental damage will break your camouflage." + set_module = /obj/item/robot_module/saboteur/spider + /mob/living/silicon/robot/proc/notify_ai(notifytype, oldname, newname) if(!connected_ai) return @@ -942,6 +991,9 @@ notify_ai(RENAME, oldname, newname) if(!QDELETED(builtInCamera)) builtInCamera.c_tag = real_name + if(aiPDA && !shell) + aiPDA.owner = newname + aiPDA.name = newname + " (" + aiPDA.ownjob + ")" custom_name = newname diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 5342638c03..d5a1058a61 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -184,7 +184,7 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real gib() return TRUE -/mob/living/silicon/robot/ex_act(severity, target) +/mob/living/silicon/robot/ex_act(severity, target, origin) switch(severity) if(1) gib() diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index d0c53508fa..de2f4635d4 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -16,6 +16,7 @@ var/list/modules = list() //holds all the usable modules var/list/added_modules = list() //modules not inherient to the robot module, are kept when the module changes var/list/storages = list() + var/list/added_channels = list() //Borg radio stuffs var/cyborg_base_icon = "robot" //produces the icon for the borg and, if no special_light_key is set, the lights var/special_light_key //if we want specific lights, use this instead of copying lights in the dmi @@ -43,7 +44,7 @@ var/moduleselect_alternate_icon var/dogborg = FALSE -/obj/item/robot_module/Initialize() +/obj/item/robot_module/Initialize(mapload) . = ..() for(var/i in basic_modules) var/obj/item/I = new i(src) @@ -236,6 +237,8 @@ R.typing_indicator_state = /obj/effect/overlay/typing_indicator/machine/dogborg else R.typing_indicator_state = /obj/effect/overlay/typing_indicator/machine + R.radio.extra_channels = RM.added_channels + R.radio.recalculateChannels() R.maxHealth = borghealth R.health = min(borghealth, R.health) qdel(src) @@ -322,13 +325,14 @@ /obj/item/robot_module/medical name = "Medical" + added_channels = list(RADIO_CHANNEL_MEDICAL = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, /obj/item/crowbar/cyborg, /obj/item/healthanalyzer, /obj/item/reagent_containers/borghypo, - /obj/item/weapon/gripper/medical, + /obj/item/gripper/medical, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/surgical_drapes, @@ -421,8 +425,8 @@ if("Alina") cyborg_base_icon = "alina-med" cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi' - special_light_key = "alina" - sleeper_overlay = "alinasleeper" + special_light_key = "alina-med" + sleeper_overlay = "valemedsleeper" moduleselect_icon = "medihound" moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi' dogborg = TRUE @@ -432,6 +436,7 @@ /obj/item/robot_module/engineering name = "Engineering" + added_channels = list(RADIO_CHANNEL_ENGINEERING = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/borg/sight/meson, @@ -448,7 +453,7 @@ /obj/item/analyzer, /obj/item/storage/part_replacer/cyborg, /obj/item/holosign_creator/combifan, - /obj/item/weapon/gripper, + /obj/item/gripper, /obj/item/lightreplacer/cyborg, /obj/item/geiger_counter/cyborg, /obj/item/assembly/signaler/cyborg, @@ -536,9 +541,9 @@ dogborg = TRUE if("Alina") cyborg_base_icon = "alina-eng" - special_light_key = "alina" + special_light_key = "alina-eng" cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi' - sleeper_overlay = "alinasleeper" + sleeper_overlay = "valeengsleeper" dogborg = TRUE else return FALSE @@ -546,6 +551,7 @@ /obj/item/robot_module/security name = "Security" + added_channels = list(RADIO_CHANNEL_SECURITY = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, @@ -620,8 +626,8 @@ dogborg = TRUE if("Alina") cyborg_base_icon = "alina-sec" - special_light_key = "alina" - sleeper_overlay = "alinasleeper" + special_light_key = "alina-sec" + sleeper_overlay = "valesecsleeper" cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi' dogborg = TRUE if("K9 Dark") @@ -638,7 +644,7 @@ return FALSE return ..() -/obj/item/robot_module/security/Initialize() +/obj/item/robot_module/security/Initialize(mapload) . = ..() if(!CONFIG_GET(flag/weaken_secborg)) for(var/obj/item/gun/energy/disabler/cyborg/pewpew in basic_modules) @@ -648,6 +654,7 @@ /obj/item/robot_module/peacekeeper name = "Peacekeeper" + added_channels = list(RADIO_CHANNEL_SECURITY = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, @@ -734,6 +741,7 @@ /obj/item/robot_module/clown name = "Clown" + added_channels = list(RADIO_CHANNEL_SERVICE = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, @@ -766,6 +774,7 @@ /obj/item/robot_module/butler name = "Service" + added_channels = list(RADIO_CHANNEL_SERVICE = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, @@ -909,6 +918,7 @@ /obj/item/robot_module/miner name = "Miner" + added_channels = list(RADIO_CHANNEL_SUPPLY = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, @@ -923,7 +933,7 @@ /obj/item/gun/energy/kinetic_accelerator/cyborg, /obj/item/gun/energy/plasmacutter/cyborg, /obj/item/gps/cyborg, - /obj/item/weapon/gripper/mining, + /obj/item/gripper/mining, /obj/item/cyborg_clamp, /obj/item/stack/marker_beacon, /obj/item/destTagger, @@ -999,6 +1009,7 @@ /obj/item/robot_module/syndicate name = "Syndicate Assault" + added_channels = list(RADIO_CHANNEL_SYNDICATE = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, @@ -1029,11 +1040,13 @@ /obj/item/robot_module/syndicate_medical name = "Syndicate Medical" + added_channels = list(RADIO_CHANNEL_SYNDICATE = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/extinguisher/mini, /obj/item/crowbar/cyborg, /obj/item/reagent_containers/borghypo/syndicate, + /obj/item/gripper/medical, /obj/item/shockpaddles/syndicate, /obj/item/healthanalyzer/advanced, /obj/item/surgical_drapes/advanced, @@ -1060,6 +1073,7 @@ /obj/item/robot_module/saboteur name = "Syndicate Saboteur" + added_channels = list(RADIO_CHANNEL_SYNDICATE = 1) basic_modules = list( /obj/item/assembly/flash/cyborg, /obj/item/borg/sight/thermal, @@ -1075,7 +1089,7 @@ /obj/item/multitool/cyborg, /obj/item/storage/part_replacer/cyborg, /obj/item/holosign_creator/atmos, - /obj/item/weapon/gripper, + /obj/item/gripper, /obj/item/lightreplacer/cyborg, /obj/item/stack/sheet/metal/cyborg, /obj/item/stack/sheet/glass/cyborg, @@ -1147,3 +1161,73 @@ max_energy = 30 recharge_rate = 1 name = "Wrapping Paper Storage" + +/obj/item/robot_module/syndicate/spider// used for space ninja and their cyborg hacking special objective + name = "Spider Assault" + basic_modules = list( + /obj/item/assembly/flash/cyborg, + /obj/item/extinguisher/mini, + /obj/item/crowbar/cyborg, + /obj/item/melee/transforming/energy/sword/cyborg, + /obj/item/gun/energy/printer, + /obj/item/pinpointer/spider_cyborg) + + cyborg_base_icon = "spider_sec" + +/obj/item/robot_module/syndicate_medical/spider// ditto + name = "Spider Medical" + basic_modules = list( + /obj/item/assembly/flash/cyborg, + /obj/item/extinguisher/mini, + /obj/item/crowbar/cyborg, + /obj/item/reagent_containers/borghypo/syndicate, + /obj/item/gripper/medical, + /obj/item/shockpaddles/syndicate, + /obj/item/healthanalyzer/advanced, + /obj/item/surgical_drapes/advanced, + /obj/item/retractor, + /obj/item/hemostat, + /obj/item/cautery, + /obj/item/surgicaldrill, + /obj/item/scalpel, + /obj/item/bonesetter, + /obj/item/stack/medical/bone_gel, + /obj/item/melee/transforming/energy/sword/cyborg/saw, + /obj/item/roller/robo, + /obj/item/stack/medical/gauze/cyborg, + /obj/item/gun/medbeam, + /obj/item/organ_storage, + /obj/item/pinpointer/spider_cyborg) + + cyborg_base_icon = "spider_medical" + +/obj/item/robot_module/saboteur/spider// ditto + name = "Spider Saboteur" + basic_modules = list( + /obj/item/assembly/flash/cyborg, + /obj/item/borg/sight/thermal, + /obj/item/construction/rcd/borg/syndicate, + /obj/item/pipe_dispenser, + /obj/item/restraints/handcuffs/cable/zipties, + /obj/item/extinguisher, + /obj/item/weldingtool/largetank/cyborg, + /obj/item/screwdriver/nuke, + /obj/item/wrench/cyborg, + /obj/item/crowbar/cyborg, + /obj/item/wirecutters/cyborg, + /obj/item/multitool/cyborg, + /obj/item/storage/part_replacer/cyborg, + /obj/item/holosign_creator/atmos, + /obj/item/gripper, + /obj/item/lightreplacer/cyborg, + /obj/item/stack/sheet/metal/cyborg, + /obj/item/stack/sheet/glass/cyborg, + /obj/item/stack/sheet/rglass/cyborg, + /obj/item/stack/rods/cyborg, + /obj/item/stack/tile/plasteel/cyborg, + /obj/item/destTagger/borg, + /obj/item/stack/cable_coil/cyborg, + /obj/item/borg_chameleon, + /obj/item/pinpointer/spider_cyborg) + + cyborg_base_icon = "spider_engi" diff --git a/code/modules/mob/living/silicon/robot/update_icons.dm b/code/modules/mob/living/silicon/robot/robot_update_icons.dm similarity index 92% rename from code/modules/mob/living/silicon/robot/update_icons.dm rename to code/modules/mob/living/silicon/robot/robot_update_icons.dm index 088c93cff1..59c3c1794c 100644 --- a/code/modules/mob/living/silicon/robot/update_icons.dm +++ b/code/modules/mob/living/silicon/robot/robot_update_icons.dm @@ -17,12 +17,16 @@ icon_state = "[module.cyborg_base_icon]-wreck" if(module.cyborg_pixel_offset) - pixel_x = module.cyborg_pixel_offset + var/matrix/M = transform + M.c = module.cyborg_pixel_offset + transform = M //End of citadel changes if(module.cyborg_base_icon == "robot") icon = 'icons/mob/robots.dmi' - pixel_x = initial(pixel_x) + var/matrix/M = transform + M.c = 0 // Cyborg's initial x offset is very likely to be 0 + transform = M if(stat != DEAD && !(IsUnconscious() || IsStun() || IsParalyzed() || low_power_mode)) //Not dead, not stunned. if(!eye_lights) eye_lights = new() diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 77d1be2bcd..83ce09b315 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -8,7 +8,6 @@ initial_language_holder = /datum/language_holder/synthetic see_in_dark = 8 bubble_icon = "machine" - weather_immunities = list("ash") possible_a_intents = list(INTENT_HELP, INTENT_HARM) mob_biotypes = MOB_ROBOTIC rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE @@ -50,7 +49,10 @@ typing_indicator_state = /obj/effect/overlay/typing_indicator/machine -/mob/living/silicon/Initialize() + vocal_bark_id = "synth" + vocal_pitch_range = 0.1 + +/mob/living/silicon/Initialize(mapload) . = ..() GLOB.silicon_mobs += src faction += "silicon" @@ -58,6 +60,7 @@ diag_hud.add_to_hud(src) diag_hud_set_status() diag_hud_set_health() + ADD_TRAIT(src, TRAIT_ASHSTORM_IMMUNE, ROUNDSTART_TRAIT) /mob/living/silicon/ComponentInitialize() . = ..() @@ -78,12 +81,15 @@ GLOB.silicon_mobs -= src return ..() -/mob/living/silicon/contents_explosion(severity, target) +/mob/living/silicon/contents_explosion(severity, target, origin) return /mob/living/silicon/proc/cancelAlarm() return +/mob/living/silicon/proc/freeCamera() + return + /mob/living/silicon/proc/triggerAlarm() return @@ -413,7 +419,7 @@ src << browse(dat, "window=airoster") onclose(src, "airoster") -/mob/living/silicon/update_transform() +/mob/living/silicon/update_transform(do_animate) var/matrix/ntransform = matrix(transform) //aka transform.Copy() var/changed = 0 if(resize != RESIZE_DEFAULT_SIZE) diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm index 6c9d508fd8..e1a179ea52 100644 --- a/code/modules/mob/living/silicon/silicon_defense.dm +++ b/code/modules/mob/living/silicon/silicon_defense.dm @@ -45,14 +45,6 @@ adjustBruteLoss(damage) if(BURN) adjustFireLoss(damage) - if(TOX) - adjustToxLoss(damage) - if(OXY) - adjustOxyLoss(damage) - if(CLONE) - adjustCloneLoss(damage) - if(STAMINA) - adjustStaminaLoss(damage) /mob/living/silicon/attack_paw(mob/living/user) return attack_hand(user) @@ -120,7 +112,7 @@ "You are thrown off of [src]!") flash_act(affect_silicon = 1) -/mob/living/silicon/bullet_act(obj/item/projectile/P, def_zone) +/mob/living/silicon/bullet_act(obj/item/projectile/P, def_zone, piercing_hit = FALSE) var/totaldamage = P.damage if(P.original != src || P.firer != src) //try to block or reflect the bullet, can't do so when shooting oneself var/list/returnlist = list() @@ -141,9 +133,9 @@ "You are knocked off of [src] by the [P]!") unbuckle_mob(M) M.DefaultCombatKnockdown(40) - P.on_hit(src, 0, def_zone) + P.on_hit(src, 0, def_zone, 0, piercing_hit) return BULLET_ACT_HIT -/mob/living/silicon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/flash/static) +/mob/living/silicon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/tiled/flash/static) if(affect_silicon) return ..() diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index b003e066ef..e605ffde31 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -110,7 +110,7 @@ return return ..() -/mob/living/simple_animal/proc/attack_threshold_check(damage, damagetype = BRUTE, armorcheck = "melee") +/mob/living/simple_animal/proc/attack_threshold_check(damage, damagetype = BRUTE, armorcheck = MELEE) var/temp_damage = damage if(!damage_coeff[damagetype]) temp_damage = 0 @@ -124,10 +124,10 @@ apply_damage(damage, damagetype, null, getarmor(null, armorcheck)) return TRUE -/mob/living/simple_animal/bullet_act(obj/item/projectile/Proj) +/mob/living/simple_animal/bullet_act(obj/item/projectile/Proj, def_zone, piercing_hit = FALSE) if(!Proj) return - apply_damage(Proj.damage, Proj.damage_type) + apply_damage(Proj.damage, Proj.damage_type, 0, piercing_hit) Proj.on_hit(src) return BULLET_ACT_HIT @@ -135,7 +135,7 @@ if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src)) return ..() - var/bomb_armor = getarmor(null, "bomb") + var/bomb_armor = getarmor(null, BOMB) switch (severity) if (EXPLODE_DEVASTATE) if(prob(bomb_armor)) diff --git a/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm b/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm index 99048b4e9f..5796fe67ac 100644 --- a/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm +++ b/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm @@ -30,7 +30,7 @@ playsound(src,'sound/effects/beepskyspinsabre.ogg',100,TRUE,-1) stun_attack(AM) -/mob/living/simple_animal/bot/secbot/grievous/Initialize() +/mob/living/simple_animal/bot/secbot/grievous/Initialize(mapload) . = ..() weapon = new baton_type(src) INVOKE_ASYNC(weapon, /obj/item.proc/attack_self, src) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index bc8c3fed87..1320c13085 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -149,7 +149,7 @@ bot_reset() //Resets an AI's call, should it exist. update_icon() -/mob/living/simple_animal/bot/Initialize() +/mob/living/simple_animal/bot/Initialize(mapload) . = ..() GLOB.bots_list += src access_card = new /obj/item/card/id(src) @@ -194,9 +194,9 @@ GLOB.bots_list -= src if(paicard) ejectpai() - qdel(Radio) - qdel(access_card) - qdel(bot_core) + QDEL_NULL(Radio) + QDEL_NULL(access_card) + QDEL_NULL(bot_core) return ..() /mob/living/simple_animal/bot/bee_friendly() @@ -285,25 +285,28 @@ call_mode() return if(BOT_SUMMON) //Called by PDA - bot_summon() + summon_step() return return TRUE //Successful completion. Used to prevent child process() continuing if this one is ended early. /mob/living/simple_animal/bot/on_attack_hand(mob/living/carbon/human/H) if(H.a_intent == INTENT_HELP) - interact(H) + ui_interact(H) else return ..() /mob/living/simple_animal/bot/attack_ai(mob/user) if(!topic_denied(user)) - interact(user) + ui_interact(user) else to_chat(user, "[src]'s interface is not responding!") -/mob/living/simple_animal/bot/interact(mob/user) - show_controls(user) +/mob/living/simple_animal/bot/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SimpleBot", name) + ui.open() /mob/living/simple_animal/bot/attackby(obj/item/W, mob/user, params) if(W.tool_behaviour == TOOL_SCREWDRIVER) @@ -548,7 +551,7 @@ Pass a positive integer as an argument to override a bot's default speed. var/datum/job/captain/All = new/datum/job/captain all_access.access = All.get_access() - set_path(get_path_to(src, waypoint, /turf/proc/Distance_cardinal, 0, 200, id=all_access)) + set_path(get_path_to(src, waypoint, 200, id=all_access)) calling_ai = caller //Link the AI to the bot! ai_waypoint = waypoint @@ -727,7 +730,6 @@ Pass a positive integer as an argument to override a bot's default speed. access_card.access = user_access + prev_access //Adds the user's access, if any. mode = BOT_SUMMON speak("Responding.", radio_channel) - calc_summon_path() if("ejectpai") ejectpairemote(user) @@ -755,19 +757,16 @@ Pass a positive integer as an argument to override a bot's default speed. else to_chat(src, "Unidentified control sequence received:[command]") -/mob/living/simple_animal/bot/proc/bot_summon() // summoned to PDA - summon_step() - // calculates a path to the current destination // given an optional turf to avoid /mob/living/simple_animal/bot/proc/calc_path(turf/avoid) check_bot_access() - set_path(get_path_to(src, patrol_target, /turf/proc/Distance_cardinal, 0, 120, id=access_card, exclude=avoid)) + set_path(get_path_to(src, patrol_target, 120, id=access_card, exclude=avoid)) /mob/living/simple_animal/bot/proc/calc_summon_path(turf/avoid) check_bot_access() spawn() - set_path(get_path_to(src, summon_target, /turf/proc/Distance_cardinal, 0, 150, id=access_card, exclude=avoid)) + set_path(get_path_to(src, summon_target, 150, id=access_card, exclude=avoid)) if(!path.len) //Cannot reach target. Give up and announce the issue. speak("Summon command failed, destination unreachable.",radio_channel) bot_reset() @@ -795,56 +794,48 @@ Pass a positive integer as an argument to override a bot's default speed. else // no path, so calculate new one calc_summon_path() -/mob/living/simple_animal/bot/Bump(M as mob|obj) //Leave no door unopened! +// Variables sent to TGUI +/mob/living/simple_animal/bot/ui_data(mob/user) + var/list/data = list() + data["can_hack"] = (issilicon(user) || IsAdminGhost(user)) + data["custom_controls"] = list() + data["emagged"] = emagged + data["locked"] = locked + data["pai"] = list() + data["settings"] = list() + if(!locked || issilicon(user) || IsAdminGhost(user)) + data["pai"]["allow_pai"] = allow_pai + data["pai"]["card_inserted"] = paicard + data["settings"]["airplane_mode"] = remote_disabled + data["settings"]["maintenance_lock"] = !open + data["settings"]["power"] = on + data["settings"]["patrol_station"] = auto_patrol + return data + +// Actions received from TGUI +/mob/living/simple_animal/bot/ui_act(action, params) . = ..() - if((istype(M, /obj/machinery/door/airlock) || istype(M, /obj/machinery/door/window)) && (!isnull(access_card))) - var/obj/machinery/door/D = M - if(D.check_access(access_card)) - D.open() - frustration = 0 - -/mob/living/simple_animal/bot/proc/show_controls(mob/M) - users |= M - var/dat = "" - dat = get_controls(M) - var/datum/browser/popup = new(M,window_id,window_name,350,600) - popup.set_content(dat) - popup.open(use_onclose = 0) - onclose(M,window_id,ref=src) - return - -/mob/living/simple_animal/bot/proc/update_controls() - for(var/mob/M in users) - show_controls(M) - -/mob/living/simple_animal/bot/proc/get_controls(mob/M) - return "PROTOBOT - NOT FOR USE" - -/mob/living/simple_animal/bot/Topic(href, href_list) - //No ..() to prevent strip panel showing up - Todo: make that saner - if(href_list["close"])// HUE HUE - if(usr in users) - users.Remove(usr) - return TRUE - - if(topic_denied(usr)) - to_chat(usr, "[src]'s interface is not responding!") - return TRUE - add_fingerprint(usr) - - if((href_list["power"]) && (bot_core.allowed(usr) || !locked)) - if(on) - turn_off() - else - turn_on() - - switch(href_list["operation"]) + if(.) + return + if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked)) + to_chat(usr, span_warning("Access denied.")) + return + if(action == "lock") + locked = !locked + if(locked && !(issilicon(usr) || IsAdminGhost(usr))) + return + switch(action) + if("power") + on = !on + update_appearance() + if("maintenance") + open = !open if("patrol") if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked)) return TRUE auto_patrol = !auto_patrol bot_reset() - if("remote") + if("airplane") remote_disabled = !remote_disabled if("hack") if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr)) @@ -865,11 +856,11 @@ Pass a positive integer as an argument to override a bot's default speed. hacked = FALSE to_chat(usr, "[text_dehack]") bot_reset() - if("ejectpai") + if("eject_pai") if(paicard && (!locked || hasSiliconAccessInArea(usr) || IsAdminGhost(usr))) to_chat(usr, "You eject [paicard] from [bot_name]") ejectpai(usr) - update_controls() + return /mob/living/simple_animal/bot/update_icon_state() icon_state = "[initial(icon_state)][on]" @@ -880,7 +871,7 @@ Pass a positive integer as an argument to override a bot's default speed. anchored = FALSE var/mob/living/simple_animal/bot/owner = null -/obj/machinery/bot_core/Initialize() +/obj/machinery/bot_core/Initialize(mapload) . = ..() owner = loc if(!istype(owner)) @@ -897,33 +888,6 @@ Pass a positive integer as an argument to override a bot's default speed. return TRUE return FALSE -/mob/living/simple_animal/bot/proc/hack(mob/user) - var/hack - if(hasSiliconAccessInArea(user) || IsAdminGhost(user)) //Allows silicons or admins to toggle the emag status of a bot. - hack += "[emagged == 2 ? "Software compromised! Unit may exhibit dangerous or erratic behavior." : "Unit operating normally. Release safety lock?"]
    " - hack += "Harm Prevention Safety System: [emagged ? "DANGER" : "Engaged"]
    " - else if(!locked) //Humans with access can use this option to hide a bot from the AI's remote control panel and PDA control. - hack += "Remote network control radio: [remote_disabled ? "Disconnected" : "Connected"]
    " - return hack - -/mob/living/simple_animal/bot/proc/showpai(mob/user) - var/eject = "" - if((!locked || hasSiliconAccessInArea(usr) || IsAdminGhost(usr))) - if(paicard || allow_pai) - eject += "Personality card status: " - if(paicard) - if(client) - eject += "Active" - else - eject += "Inactive" - else if(!allow_pai || key) - eject += "Unavailable" - else - eject += "Not inserted" - eject += "
    " - eject += "
    " - return eject - /mob/living/simple_animal/bot/proc/insertpai(mob/user, obj/item/paicard/card) if(paicard) to_chat(user, "A [paicard] is already inserted!") diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index a52e975f9a..806fc60156 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -19,6 +19,7 @@ path_image_color = "#993299" weather_immunities = list("lava","ash") + var/base_icon = "cleanbot" var/clean_time = 50 //How long do we take to clean? var/upgrades = 0 @@ -102,7 +103,7 @@ if(ascended && user.stat == CONSCIOUS && user.client) user.client.give_award(/datum/award/achievement/misc/cleanboss, user) -/mob/living/simple_animal/bot/cleanbot/Initialize() +/mob/living/simple_animal/bot/cleanbot/Initialize(mapload) . = ..() chosen_name = name @@ -126,13 +127,21 @@ /mob/living/simple_animal/bot/cleanbot/turn_on() ..() - icon_state = "cleanbot[on]" bot_core.updateUsrDialog() + update_icon() /mob/living/simple_animal/bot/cleanbot/turn_off() ..() - icon_state = "cleanbot[on]" bot_core.updateUsrDialog() + update_icon() + +/mob/living/simple_animal/bot/cleanbot/update_icon_state() + . = ..() + switch(mode) + if(BOT_CLEANING) + icon_state = "[base_icon]-c" + else + icon_state = "[base_icon][on]" /mob/living/simple_animal/bot/cleanbot/bot_reset() ..() @@ -182,7 +191,7 @@ deputize(W, user) else if(istype(W, /obj/item/mop/advanced)) - if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_CLEANER_ADVANCED_MOP)) + if(bot_core.allowed(user) && open && !(upgrades & UPGRADE_CLEANER_ADVANCED_MOP)) to_chat(user, "You replace \the [src] old mop with a new better one!") upgrades |= UPGRADE_CLEANER_ADVANCED_MOP clean_time = 20 //2.5 the speed! @@ -198,7 +207,7 @@ to_chat(user, "The [src] already has this mop!") else if(istype(W, /obj/item/broom)) - if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_CLEANER_BROOM)) + if(bot_core.allowed(user) && open && !(upgrades & UPGRADE_CLEANER_BROOM)) to_chat(user, "You add to \the [src] a broom speeding it up!") upgrades |= UPGRADE_CLEANER_BROOM base_speed = 1 //2x faster! @@ -302,7 +311,7 @@ if(!path || path.len == 0) //No path, need a new one //Try to produce a path to the target, and ignore airlocks to which it has access. - path = get_path_to(src, target.loc, /turf/proc/Distance_cardinal, 0, 30, id=access_card) + path = get_path_to(src, target, 30, id=access_card) if(!bot_move(target)) add_to_ignore(target) target = null @@ -381,6 +390,12 @@ target = null mode = BOT_IDLE icon_state = "cleanbot[on]" + else if(istype(A, /turf)) //for player-controlled cleanbots so they can clean unclickable messes like dirt + var/turf/T = A + for(var/atom/S in T.contents) + if(istype(S, /obj/effect/decal/cleanable)) //clean the first mess found + UnarmedAttack(S) + return else if(istype(A, /obj/item) || istype(A, /obj/effect/decal/remains)) visible_message("[src] sprays hydrofluoric acid at [A]!") playsound(src, 'sound/effects/spray2.ogg', 50, TRUE, -6) @@ -443,37 +458,33 @@ /obj/machinery/bot_core/cleanbot req_one_access = list(ACCESS_JANITOR, ACCESS_ROBOTICS) -/mob/living/simple_animal/bot/cleanbot/get_controls(mob/user) - var/dat - dat += hack(user) - dat += showpai(user) - dat += text({" -Status: [on ? "On" : "Off"]
    -Behaviour controls are [locked ? "locked" : "unlocked"]
    -Maintenance panel panel is [open ? "opened" : "closed"]"}) - if(!locked || issilicon(user)|| IsAdminGhost(user)) - dat += "
    Clean Blood: [blood ? "Yes" : "No"]" - dat += "
    Clean Trash: [trash ? "Yes" : "No"]" - dat += "
    Clean Graffiti: [drawn ? "Yes" : "No"]" - dat += "
    Exterminate Pests: [pests ? "Yes" : "No"]" - dat += "

    Patrol Station: [auto_patrol ? "Yes" : "No"]" - return dat +// Variables sent to TGUI +/mob/living/simple_animal/bot/cleanbot/ui_data(mob/user) + var/list/data = ..() -/mob/living/simple_animal/bot/cleanbot/Topic(href, href_list) - if(..()) - return 1 - if(href_list["operation"]) - switch(href_list["operation"]) - if("blood") - blood = !blood - if("pests") - pests = !pests - if("trash") - trash = !trash - if("drawn") - drawn = !drawn - get_targets() - update_controls() + if(!locked || issilicon(user)|| IsAdminGhost(user)) + data["custom_controls"]["clean_blood"] = blood + data["custom_controls"]["clean_trash"] = trash + data["custom_controls"]["clean_graffiti"] = drawn + data["custom_controls"]["pest_control"] = pests + return data + +// Actions received from TGUI +/mob/living/simple_animal/bot/cleanbot/ui_act(action, params) + . = ..() + if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked)) + return TRUE + switch(action) + if("clean_blood") + blood = !blood + if("pest_control") + pests = !pests + if("clean_trash") + trash = !trash + if("clean_graffiti") + drawn = !drawn + get_targets() + return /obj/machinery/bot_core/cleanbot/medbay req_one_access = list(ACCESS_JANITOR, ACCESS_ROBOTICS, ACCESS_MEDICAL) diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm index fff1782154..8ec0aab5bb 100644 --- a/code/modules/mob/living/simple_animal/bot/construction.dm +++ b/code/modules/mob/living/simple_animal/bot/construction.dm @@ -208,7 +208,7 @@ created_name = "Floorbot" var/toolbox = /obj/item/storage/toolbox -/obj/item/bot_assembly/floorbot/Initialize() +/obj/item/bot_assembly/floorbot/Initialize(mapload) . = ..() update_icon() @@ -277,7 +277,7 @@ var/healthanalyzer = /obj/item/healthanalyzer var/firstaid = /obj/item/storage/firstaid -/obj/item/bot_assembly/medbot/Initialize() +/obj/item/bot_assembly/medbot/Initialize(mapload) . = ..() spawn(5) if(skin) diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 604a72b43e..c3ae3898dd 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -96,64 +96,45 @@ text_dehack = "You restore [name]'s combat inhibitor." text_dehack_fail = "[name] ignores your attempts to restrict him!" -/mob/living/simple_animal/bot/ed209/get_controls(mob/user) - var/dat - dat += hack(user) - dat += showpai(user) - dat += text({" -Security Unit v2.6 controls

    -Status: []
    -Behaviour controls are [locked ? "locked" : "unlocked"]
    -Maintenance panel panel is [open ? "opened" : "closed"]
    "}, - -"[on ? "On" : "Off"]" ) - +// Variables sent to TGUI +/mob/living/simple_animal/bot/ed209/ui_data(mob/user) + var/list/data = ..() if(!locked || hasSiliconAccessInArea(user)|| IsAdminGhost(user)) if(!lasercolor) - dat += text({"
    -Arrest Unidentifiable Persons: []
    -Arrest for Unauthorized Weapons: []
    -Arrest for Warrant: []
    -
    -Operating Mode: []
    -Report Arrests[]
    -Auto Patrol[]"}, + data["custom_controls"]["check_id"] = idcheck + data["custom_controls"]["check_weapons"] = weaponscheck + data["custom_controls"]["check_warrants"] = check_records + data["custom_controls"]["handcuff_targets"] = !arrest_type + data["custom_controls"]["arrest_alert"] = declare_arrests + return data -"[idcheck ? "Yes" : "No"]", -"[weaponscheck ? "Yes" : "No"]", -"[check_records ? "Yes" : "No"]", -"[arrest_type ? "Detain" : "Arrest"]", -"[declare_arrests ? "Yes" : "No"]", -"[auto_patrol ? "On" : "Off"]" ) - - return dat - -/mob/living/simple_animal/bot/ed209/Topic(href, href_list) +// Actions received from TGUI +/mob/living/simple_animal/bot/ed209/ui_act(action, params) if(lasercolor && ishuman(usr)) var/mob/living/carbon/human/H = usr - if((lasercolor == "b") && (istype(H.wear_suit, /obj/item/clothing/suit/redtag)))//Opposing team cannot operate it - return - else if((lasercolor == "r") && (istype(H.wear_suit, /obj/item/clothing/suit/bluetag))) - return - if(..()) - return 1 + switch(lasercolor) //Opposing team cannot operate it + if("b") + if(istype(H.wear_suit, /obj/item/clothing/suit/redtag)) + return TRUE + if("r") + if(istype(H.wear_suit, /obj/item/clothing/suit/bluetag)) + return TRUE + . = ..() + if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked)) + return TRUE - switch(href_list["operation"]) - if("idcheck") + switch(action) + if("check_id") idcheck = !idcheck - update_controls() - if("weaponscheck") + if("check_weapons") weaponscheck = !weaponscheck - update_controls() - if("ignorerec") + if("check_warrants") check_records = !check_records - update_controls() - if("switchmode") + if("handcuff_targets") arrest_type = !arrest_type - update_controls() - if("declarearrests") + if("arrest_alert") declare_arrests = !declare_arrests - update_controls() + return /mob/living/simple_animal/bot/ed209/proc/judgement_criteria() var/final = FALSE diff --git a/code/modules/mob/living/simple_animal/bot/firebot.dm b/code/modules/mob/living/simple_animal/bot/firebot.dm index d0e969dc4e..0b97a553b2 100644 --- a/code/modules/mob/living/simple_animal/bot/firebot.dm +++ b/code/modules/mob/living/simple_animal/bot/firebot.dm @@ -39,7 +39,7 @@ var/extinguish_fires = TRUE var/stationary_mode = FALSE -/mob/living/simple_animal/bot/firebot/Initialize() +/mob/living/simple_animal/bot/firebot/Initialize(mapload) . = ..() update_icon() var/datum/job/engineer/J = new/datum/job/engineer @@ -102,23 +102,6 @@ text_dehack = "You detect errors in [name] and reset his programming." text_dehack_fail = "[name] is not responding to reset commands!" -/mob/living/simple_animal/bot/firebot/get_controls(mob/user) - var/dat - dat += hack(user) - dat += showpai(user) - dat += "Mobile Fire Extinguisher v1.0

    " - dat += "Status: [on ? "On" : "Off"]
    " - dat += "Maintenance panel panel is [open ? "opened" : "closed"]
    " - - dat += "Behaviour controls are [locked ? "locked" : "unlocked"]
    " - if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user)) - dat += "Extinguish Fires: [extinguish_fires ? "Yes" : "No"]
    " - dat += "Extinguish People: [extinguish_people ? "Yes" : "No"]
    " - dat += "Patrol Station: [auto_patrol ? "Yes" : "No"]
    " - dat += "Stationary Mode: [stationary_mode ? "Yes" : "No"]
    " - - return dat - /mob/living/simple_animal/bot/firebot/emag_act(mob/user) . = ..() if(emagged == 1) @@ -138,20 +121,29 @@ internal_ext.max_water = INFINITY internal_ext.refill() -/mob/living/simple_animal/bot/firebot/Topic(href, href_list) - if(..()) - return TRUE +// Variables sent to TGUI +/mob/living/simple_animal/bot/firebot/ui_data(mob/user) + var/list/data = ..() + if(!locked || issilicon(user) || IsAdminGhost(user)) + data["custom_controls"]["extinguish_fires"] = extinguish_fires + data["custom_controls"]["extinguish_people"] = extinguish_people + data["custom_controls"]["stationary_mode"] = stationary_mode + return data - switch(href_list["operation"]) +// Actions received from TGUI +/mob/living/simple_animal/bot/firebot/ui_act(action, params) + . = ..() + if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked)) + return TRUE + switch(action) if("extinguish_fires") extinguish_fires = !extinguish_fires if("extinguish_people") extinguish_people = !extinguish_people if("stationary_mode") stationary_mode = !stationary_mode - - update_controls() - update_icon() + update_appearance() + return /mob/living/simple_animal/bot/firebot/proc/is_burning(atom/target) if(ismob(target)) @@ -231,7 +223,7 @@ if(target_fire && (get_dist(src, target_fire) > 2)) - path = get_path_to(src, get_turf(target_fire), /turf/proc/Distance_cardinal, 0, 30, 1, id=access_card) + path = get_path_to(src, target_fire, 30, 1, id=access_card) mode = BOT_MOVING if(!path.len) soft_reset() diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm index ff6941ec70..8cd1cd519d 100644 --- a/code/modules/mob/living/simple_animal/bot/floorbot.dm +++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm @@ -43,7 +43,7 @@ #define REPLACE_TILE 6 #define TILE_EMAG 7 -/mob/living/simple_animal/bot/floorbot/Initialize() +/mob/living/simple_animal/bot/floorbot/Initialize(mapload) . = ..() update_icon() var/datum/job/engineer/J = new/datum/job/engineer @@ -71,36 +71,6 @@ text_dehack = "You detect errors in [name] and reset his programming." text_dehack_fail = "[name] is not responding to reset commands!" -/mob/living/simple_animal/bot/floorbot/get_controls(mob/user) - var/dat - dat += hack(user) - dat += showpai(user) - dat += "Floor Repairer Controls v1.1

    " - dat += "Status: [on ? "On" : "Off"]
    " - dat += "Maintenance panel panel is [open ? "opened" : "closed"]
    " - dat += "Special tiles: " - if(specialtiles) - dat += "Loaded \[[specialtiles]/[maxtiles]\]
    " - else - dat += "None Loaded
    " - - dat += "Behaviour controls are [locked ? "locked" : "unlocked"]
    " - if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user)) - dat += "Add tiles to new hull plating: [autotile ? "Yes" : "No"]
    " - dat += "Place floor tiles: [placetiles ? "Yes" : "No"]
    " - dat += "Replace existing floor tiles with custom tiles: [replacetiles ? "Yes" : "No"]
    " - dat += "Repair damaged tiles and platings: [fixfloors ? "Yes" : "No"]
    " - dat += "Traction Magnets: [anchored ? "Engaged" : "Disengaged"]
    " - dat += "Patrol Station: [auto_patrol ? "Yes" : "No"]
    " - var/bmode - if(targetdirection) - bmode = dir2text(targetdirection) - else - bmode = "disabled" - dat += "Line Mode : [bmode]
    " - - return dat - /mob/living/simple_animal/bot/floorbot/attackby(obj/item/W , mob/user, params) if(istype(W, /obj/item/stack/tile/plasteel)) to_chat(user, "The floorbot can produce normal tiles itself.") @@ -124,7 +94,7 @@ to_chat(user, "You need at least one floor tile to put into [src]!") else if(istype(W, /obj/item/storage/toolbox/artistic)) - if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_FLOOR_ARTBOX)) + if(bot_core.allowed(user) && open && !(upgrades & UPGRADE_FLOOR_ARTBOX)) to_chat(user, "You upgrade \the [src] case to hold more!") upgrades |= UPGRADE_FLOOR_ARTBOX maxtiles += 100 //Double the storage! @@ -139,7 +109,7 @@ to_chat(user, "The [src] already has a upgraded case!") else if(istype(W, /obj/item/storage/toolbox/syndicate)) - if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_FLOOR_SYNDIBOX)) + if(bot_core.allowed(user) && open && !(upgrades & UPGRADE_FLOOR_SYNDIBOX)) to_chat(user, "You upgrade \the [src] case to hold more!") upgrades |= UPGRADE_FLOOR_SYNDIBOX maxtiles += 200 //Double bse storage @@ -161,26 +131,44 @@ if(user) to_chat(user, "[src] buzzes and beeps.") -/mob/living/simple_animal/bot/floorbot/Topic(href, href_list) - if(..()) - return 1 +// Variables sent to TGUI +/mob/living/simple_animal/bot/floorbot/ui_data(mob/user) + var/list/data = ..() + if(!locked || issilicon(user) || IsAdminGhost(user)) + data["custom_controls"]["tile_hull"] = autotile + data["custom_controls"]["place_tiles"] = placetiles + data["custom_controls"]["place_custom"] = replacetiles + data["custom_controls"]["repair_damage"] = fixfloors + data["custom_controls"]["traction_magnets"] = anchored + data["custom_controls"]["tile_stack"] = 0 + data["custom_controls"]["line_mode"] = FALSE + if(specialtiles) + data["custom_controls"]["tile_stack"] = specialtiles + if(targetdirection) + data["custom_controls"]["line_mode"] = dir2text(targetdirection) + return data - switch(href_list["operation"]) - if("replace") +// Actions received from TGUI +/mob/living/simple_animal/bot/floorbot/ui_act(action, params) + . = ..() + if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked)) + return TRUE + switch(action) + if("place_custom") replacetiles = !replacetiles - if("place") + if("place_tiles") placetiles = !placetiles - if("fix") + if("repair_damage") fixfloors = !fixfloors - if("autotile") + if("tile_hull") autotile = !autotile - if("anchor") + if("traction_magnets") anchored = !anchored - if("eject") + if("eject_tiles") if(specialtiles && tiletype != null) empty_tiles() - if("linemode") + if("line_mode") var/setdir = input("Select construction direction:") as null|anything in list("north","east","south","west","disable") switch(setdir) if("north") @@ -193,7 +181,7 @@ targetdirection = 8 if("disable") targetdirection = null - update_controls() + return /mob/living/simple_animal/bot/floorbot/proc/empty_tiles() new tiletype(drop_location(), specialtiles) @@ -275,9 +263,9 @@ if(path.len == 0) if(!isturf(target)) var/turf/TL = get_turf(target) - path = get_path_to(src, TL, /turf/proc/Distance_cardinal, 0, 30, id=access_card,simulated_only = 0) + path = get_path_to(src, TL, 30, id=access_card,simulated_only = 0) else - path = get_path_to(src, target, /turf/proc/Distance_cardinal, 0, 30, id=access_card,simulated_only = 0) + path = get_path_to(src, target, 30, id=access_card,simulated_only = 0) if(!bot_move(target)) add_to_ignore(target) @@ -433,4 +421,4 @@ if(robot.mode == BOT_REPAIRING) return TRUE return FALSE - + diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm index 9625d2b084..b8d82e8c7a 100644 --- a/code/modules/mob/living/simple_animal/bot/honkbot.dm +++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm @@ -37,7 +37,7 @@ var/weaponscheck = TRUE var/bikehorn = /obj/item/bikehorn -/mob/living/simple_animal/bot/honkbot/Initialize() +/mob/living/simple_animal/bot/honkbot/Initialize(mapload) . = ..() update_icon() auto_patrol = TRUE @@ -78,24 +78,6 @@ text_dehack = "You reboot [name] and restore the sound control system." text_dehack_fail = "[name] refuses to accept your authority!" -/mob/living/simple_animal/bot/honkbot/get_controls(mob/user) - var/dat - dat += hack(user) - dat += showpai(user) - dat += text({" -Honkomatic Bike Horn Unit v1.0.7 controls

    -Status: []
    -Behaviour controls are [locked ? "locked" : "unlocked"]
    -Maintenance panel panel is [open ? "opened" : "closed"]"}, - -"[on ? "On" : "Off"]" ) - - if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user)) - dat += text({"
    Auto Patrol: []"}, - -"[auto_patrol ? "On" : "Off"]" ) - return dat - /mob/living/simple_animal/bot/honkbot/proc/judgement_criteria() var/final = NONE if(check_records) diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index 25f6509ad0..0b21f4a825 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -155,87 +155,63 @@ /mob/living/simple_animal/bot/medbot/attack_paw(mob/user) return attack_hand(user) -/mob/living/simple_animal/bot/medbot/get_controls(mob/user) - var/dat - dat += hack(user) - dat += showpai(user) - dat += "Medical Unit Controls v1.1

    " - dat += "Status: [on ? "On" : "Off"]
    " - dat += "Maintenance panel panel is [open ? "opened" : "closed"]
    " - dat += "Beaker: " +// Variables sent to TGUI +/mob/living/simple_animal/bot/medbot/ui_data(mob/user) + var/list/data = ..() if(reagent_glass) - dat += "Loaded \[[reagent_glass.reagents.total_volume]/[reagent_glass.reagents.maximum_volume]\]" - else - dat += "None Loaded" - dat += "
    Behaviour controls are [locked ? "locked" : "unlocked"]
    " + data["custom_controls"]["beaker"] = reagent_glass + data["custom_contrlos"]["reagents"] = "[reagent_glass.reagents.total_volume]/[reagent_glass.reagents.maximum_volume]" if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user)) - dat += "Healing Threshold: " - dat += "-- " - dat += "- " - dat += "[heal_threshold] " - dat += "+ " - dat += "++" - dat += "
    " + data["custom_controls"]["injection_amount"] = injection_amount + data["custom_controls"]["use_beaker"] = use_beaker + data["custom_controls"]["treat_virus"] = treat_virus + data["custom_controls"]["heal_threshold"] = heal_threshold + data["custom_controls"]["speaker"] = !shut_up + data["custom_controls"]["crit_alerts"] = declare_crit + data["custom_controls"]["stationary_mode"] = stationary_mode + return data - dat += "Injection Level: " - dat += "- " - dat += "[injection_amount] " - dat += "+ " - dat += "
    " +// Actions received from TGUI +/mob/living/simple_animal/bot/medbot/ui_act(action, params) + . = ..() + if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked)) + return TRUE + switch(action) + if("heal_threshold") + var/adjust_num = round(text2num(params["threshold"])) + heal_threshold = adjust_num + if(heal_threshold < 5) + heal_threshold = 5 + if(heal_threshold > 75) + heal_threshold = 75 - dat += "Reagent Source: " - dat += "[use_beaker ? "Loaded Beaker (When available)" : "Internal Synthesizer"]
    " + if("injection_amount") + var/adjust_num = round(text2num(params["amount"])) + injection_amount = adjust_num + if(injection_amount < 1) + injection_amount = 1 + if(injection_amount > 15) + injection_amount = 15 - dat += "Treat Viral Infections: [treat_virus ? "Yes" : "No"]
    " - dat += "The speaker switch is [shut_up ? "off" : "on"]. Toggle
    " - dat += "Critical Patient Alerts: [declare_crit ? "Yes" : "No"]
    " - dat += "Patrol Station: [auto_patrol ? "Yes" : "No"]
    " - dat += "Stationary Mode: [stationary_mode ? "Yes" : "No"]
    " + if("use_beaker") + use_beaker = !use_beaker - return dat + if("eject") + if(!isnull(reagent_glass)) + reagent_glass.forceMove(drop_location()) + reagent_glass = null -/mob/living/simple_animal/bot/medbot/Topic(href, href_list) - if(..()) - return 1 + if("speaker") + shut_up = !shut_up + if("crit_alerts") + declare_crit = !declare_crit + if("stationary_mode") + stationary_mode = !stationary_mode + path = list() + update_appearance() - if(href_list["adj_threshold"]) - var/adjust_num = text2num(href_list["adj_threshold"]) - heal_threshold += adjust_num - if(heal_threshold < 5) - heal_threshold = 5 - if(heal_threshold > 75) - heal_threshold = 75 - - else if(href_list["adj_inject"]) - var/adjust_num = text2num(href_list["adj_inject"]) - injection_amount += adjust_num - if(injection_amount < 5) - injection_amount = 5 - if(injection_amount > 15) - injection_amount = 15 - - else if(href_list["use_beaker"]) - use_beaker = !use_beaker - - else if(href_list["eject"] && (!isnull(reagent_glass))) - reagent_glass.forceMove(drop_location()) - reagent_glass = null - - else if(href_list["togglevoice"]) - shut_up = !shut_up - - else if(href_list["critalerts"]) - declare_crit = !declare_crit - - else if(href_list["stationary"]) - stationary_mode = !stationary_mode - path = list() - update_icon() - - else if(href_list["virus"]) - treat_virus = !treat_virus - - update_controls() + if("virus") + treat_virus = !treat_virus return /mob/living/simple_animal/bot/medbot/attackby(obj/item/W as obj, mob/user as mob, params) @@ -251,10 +227,9 @@ reagent_glass = W to_chat(user, "You insert [W].") - show_controls(user) else if(istype(W, /obj/item/reagent_containers/syringe/piercing)) - if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_PIERERCING)) + if(bot_core.allowed(user) && open && !(upgrades & UPGRADE_MEDICAL_PIERERCING)) to_chat(user, "You replace \the [src] syringe with a diamond-tipped one!") upgrades |= UPGRADE_MEDICAL_PIERERCING qdel(W) @@ -268,7 +243,7 @@ to_chat(user, "The [src] already has a diamond-tipped syringe!") else if(istype(W, /obj/item/hypospray/mkii)) - if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_HYPOSPRAY)) + if(bot_core.allowed(user) && open && !(upgrades & UPGRADE_MEDICAL_HYPOSPRAY)) to_chat(user, "You replace \the [src] syringe base with a DeForest Medical MK.II Hypospray!") upgrades |= UPGRADE_MEDICAL_HYPOSPRAY injection_time = 15 //Half the time half the death! @@ -284,7 +259,7 @@ to_chat(user, "The [src] already has a DeForest Medical Hypospray base!") else if(istype(W, /obj/item/circuitboard/machine/chem_dispenser)) - if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_CHEM_BOARD)) + if(bot_core.allowed(user) && open && !(upgrades & UPGRADE_MEDICAL_CHEM_BOARD)) to_chat(user, "You add in the board upgrading \the [src] reagent banks!") upgrades |= UPGRADE_MEDICAL_CHEM_BOARD treatment_oxy = /datum/reagent/medicine/salbutamol //Replaces Dex with salbutamol "better" healing of o2 @@ -299,7 +274,7 @@ to_chat(user, "The [src] already has this upgrade!") else if(istype(W, /obj/item/circuitboard/machine/cryo_tube)) - if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_CRYO_BOARD)) + if(bot_core.allowed(user) && open && !(upgrades & UPGRADE_MEDICAL_CRYO_BOARD)) to_chat(user, "You add in the board upgrading \the [src] reagent banks!") upgrades |= UPGRADE_MEDICAL_CRYO_BOARD treatment_fire = /datum/reagent/medicine/oxandrolone //Replaces Kep with oxandrolone "better" healing of burns @@ -314,7 +289,7 @@ to_chat(user, "The [src] already has this upgrade!") else if(istype(W, /obj/item/circuitboard/machine/chem_master)) - if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_CHEM_MASTER)) + if(bot_core.allowed(user) && open && !(upgrades & UPGRADE_MEDICAL_CHEM_MASTER)) to_chat(user, "You add in the board upgrading \the [src] reagent banks!") upgrades |= UPGRADE_MEDICAL_CHEM_MASTER treatment_brute = /datum/reagent/medicine/sal_acid //Replaces Bic with Sal Acid "better" healing of brute @@ -329,7 +304,7 @@ to_chat(user, "the [src] already has this upgrade!") else if(istype(W, /obj/item/circuitboard/machine/sleeper)) - if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_SLEEP_BOARD)) + if(bot_core.allowed(user) && open && !(upgrades & UPGRADE_MEDICAL_SLEEP_BOARD)) to_chat(user, "You add in the board upgrading \the [src] reagent banks!") upgrades |= UPGRADE_MEDICAL_SLEEP_BOARD treatment_tox = /datum/reagent/medicine/pen_acid //replaces charcoal with pen acid a "better" healing of toxins @@ -359,7 +334,7 @@ audible_message("[src] buzzes oddly!") flick("medibot_spark", src) playsound(src, "sparks", 75, 1) - if(!CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_PIERERCING)) + if(!(upgrades & UPGRADE_MEDICAL_PIERERCING)) upgrades |= UPGRADE_MEDICAL_PIERERCING //Jabs even harder through the clothing! if(user) oldpatient = user @@ -517,10 +492,10 @@ return if(patient && path.len == 0 && (get_dist(src,patient) > 1)) - path = get_path_to(src, get_turf(patient), /turf/proc/Distance_cardinal, 0, 30,id=access_card) + path = get_path_to(src, patient, 30, id=access_card) mode = BOT_MOVING if(!path.len) //try to get closer if you can't reach the patient directly - path = get_path_to(src, get_turf(patient), /turf/proc/Distance_cardinal, 0, 30,1,id=access_card) + path = get_path_to(src, patient, 30, 1, id=access_card) if(!path.len) //Do not chase a patient we cannot reach. soft_reset() @@ -558,7 +533,7 @@ if(ishuman(C)) var/mob/living/carbon/human/H = C - if (H.wear_suit && H.head && istype(H.wear_suit, /obj/item/clothing) && istype(H.head, /obj/item/clothing) && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_PIERERCING)) + if (H.wear_suit && H.head && istype(H.wear_suit, /obj/item/clothing) && istype(H.head, /obj/item/clothing) && !(upgrades & UPGRADE_MEDICAL_PIERERCING)) var/obj/item/clothing/CS = H.wear_suit var/obj/item/clothing/CH = H.head if (CS.clothing_flags & CH.clothing_flags & THICKMATERIAL) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index b287b854a3..ed47611a8f 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -49,7 +49,7 @@ var/obj/item/stock_parts/cell/cell var/bloodiness = 0 -/mob/living/simple_animal/bot/mulebot/Initialize() +/mob/living/simple_animal/bot/mulebot/Initialize(mapload) . = ..() wires = new /datum/wires/mulebot(src) var/datum/job/cargo_tech/J = new/datum/job/cargo_tech @@ -138,7 +138,7 @@ add_overlay(load) return -/mob/living/simple_animal/bot/mulebot/ex_act(severity) +/mob/living/simple_animal/bot/mulebot/ex_act(severity, target, origin) unload(0) switch(severity) if(1) @@ -276,56 +276,6 @@ if("ejectpai") ejectpairemote(user) -// TODO: remove this; PDAs currently depend on it -/mob/living/simple_animal/bot/mulebot/get_controls(mob/user) - var/ai = hasSiliconAccessInArea(user) - var/dat - dat += "

    Multiple Utility Load Effector Mk. V

    " - dat += "ID: [id]
    " - dat += "Power: [on ? "On" : "Off"]
    " - dat += "

    Status

    " - dat += "
    " - switch(mode) - if(BOT_IDLE) - dat += "Ready" - if(BOT_DELIVER) - dat += "[mode_name[BOT_DELIVER]]" - if(BOT_GO_HOME) - dat += "[mode_name[BOT_GO_HOME]]" - if(BOT_BLOCKED) - dat += "[mode_name[BOT_BLOCKED]]" - if(BOT_NAV,BOT_WAIT_FOR_NAV) - dat += "[mode_name[BOT_NAV]]" - if(BOT_NO_ROUTE) - dat += "[mode_name[BOT_NO_ROUTE]]" - dat += "
    " - - dat += "Current Load: [load ? load.name : "none"]
    " - dat += "Destination: [!destination ? "none" : destination]
    " - dat += "Power level: [cell ? cell.percent() : 0]%" - - if(locked && !ai && !IsAdminGhost(user)) - dat += " 
    Controls are locked
    Unlock Controls" - else - dat += " 
    Controls are unlocked
    Lock Controls

    " - - dat += "Toggle Power
    " - dat += "Stop
    " - dat += "Proceed
    " - dat += "Return to Home
    " - dat += "Set Destination
    " - dat += "Set Bot ID
    " - dat += "Set Home
    " - dat += "Toggle Auto Return Home ([auto_return ? "On":"Off"])
    " - dat += "Toggle Auto Pickup Crate ([auto_pickup ? "On":"Off"])
    " - dat += "Toggle Delivery Reporting ([report_delivery ? "On" : "Off"])
    " - if(load) - dat += "Unload Now
    " - dat += "
    The maintenance hatch is closed.
    " - - return dat - - // returns true if the bot has power /mob/living/simple_animal/bot/mulebot/proc/has_power() return !open && cell && cell.charge > 0 && (!wires.is_cut(WIRE_POWER1) && !wires.is_cut(WIRE_POWER2)) @@ -580,7 +530,7 @@ // calculates a path to the current destination // given an optional turf to avoid /mob/living/simple_animal/bot/mulebot/calc_path(turf/avoid = null) - path = get_path_to(src, target, /turf/proc/Distance_cardinal, 0, 250, id=access_card, exclude=avoid) + path = get_path_to(src, target, 250, id=access_card, exclude=avoid) // sets the current destination // signals all beacons matching the delivery code @@ -681,12 +631,12 @@ playsound(loc, 'sound/effects/splat.ogg', 50, TRUE) var/damage = rand(5,15) - H.apply_damage(2*damage, BRUTE, BODY_ZONE_HEAD, run_armor_check(BODY_ZONE_HEAD, "melee")) - H.apply_damage(2*damage, BRUTE, BODY_ZONE_CHEST, run_armor_check(BODY_ZONE_CHEST, "melee")) - H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_L_LEG, run_armor_check(BODY_ZONE_L_LEG, "melee")) - H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_R_LEG, run_armor_check(BODY_ZONE_R_LEG, "melee")) - H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_L_ARM, run_armor_check(BODY_ZONE_L_ARM, "melee")) - H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_R_ARM, run_armor_check(BODY_ZONE_R_ARM, "melee")) + H.apply_damage(2*damage, BRUTE, BODY_ZONE_HEAD, run_armor_check(BODY_ZONE_HEAD, MELEE)) + H.apply_damage(2*damage, BRUTE, BODY_ZONE_CHEST, run_armor_check(BODY_ZONE_CHEST, MELEE)) + H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_L_LEG, run_armor_check(BODY_ZONE_L_LEG, MELEE)) + H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_R_LEG, run_armor_check(BODY_ZONE_R_LEG, MELEE)) + H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_L_ARM, run_armor_check(BODY_ZONE_L_ARM, MELEE)) + H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_R_ARM, run_armor_check(BODY_ZONE_R_ARM, MELEE)) var/turf/T = get_turf(src) T.add_mob_blood(H) diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index 8bb30a11a6..9973b6472e 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -58,7 +58,7 @@ name = "Officer Pipsqueak" desc = "It's Officer Beep O'sky's smaller, just-as aggressive cousin, Pipsqueak." -/mob/living/simple_animal/bot/secbot/beepsky/jr/Initialize() +/mob/living/simple_animal/bot/secbot/beepsky/jr/Initialize(mapload) . = ..() resize = 0.8 update_transform() @@ -174,7 +174,7 @@ desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment." radio_channel = RADIO_CHANNEL_AI_PRIVATE -/mob/living/simple_animal/bot/secbot/Initialize() +/mob/living/simple_animal/bot/secbot/Initialize(mapload) . = ..() update_icon() var/datum/job/detective/J = new/datum/job/detective @@ -209,57 +209,34 @@ text_dehack = "You reboot [name] and restore the target identification." text_dehack_fail = "[name] refuses to accept your authority!" -/mob/living/simple_animal/bot/secbot/get_controls(mob/user) - var/dat - dat += hack(user) - dat += showpai(user) - dat += text({" -Securitron v1.6 controls

    -Status: []
    -Behaviour controls are [locked ? "locked" : "unlocked"]
    -Maintenance panel panel is [open ? "opened" : "closed"]"}, - -"[on ? "On" : "Off"]" ) - +// Variables sent to TGUI +/mob/living/simple_animal/bot/secbot/ui_data(mob/user) + var/list/data = ..() if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user)) - dat += text({"
    -Arrest Unidentifiable Persons: []
    -Arrest for Unauthorized Weapons: []
    -Arrest for Warrant: []
    -Operating Mode: []
    -Report Arrests[]
    -Auto Patrol: []"}, + data["custom_controls"]["check_id"] = idcheck + data["custom_controls"]["check_weapons"] = weaponscheck + data["custom_controls"]["check_warrants"] = check_records + data["custom_controls"]["handcuff_targets"] = !arrest_type + data["custom_controls"]["arrest_alert"] = declare_arrests + return data -"[idcheck ? "Yes" : "No"]", -"[weaponscheck ? "Yes" : "No"]", -"[check_records ? "Yes" : "No"]", -"[arrest_type ? "Detain" : "Arrest"]", -"[declare_arrests ? "Yes" : "No"]", -"[auto_patrol ? "On" : "Off"]" ) - - return dat - -/mob/living/simple_animal/bot/secbot/Topic(href, href_list) - if(..()) - return 1 - if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked)) +// Actions received from TGUI +/mob/living/simple_animal/bot/secbot/ui_act(action, params) + . = ..() + if(. || !hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked)) return TRUE - switch(href_list["operation"]) - if("idcheck") + switch(action) + if("check_id") idcheck = !idcheck - update_controls() - if("weaponscheck") + if("check_weapons") weaponscheck = !weaponscheck - update_controls() - if("ignorerec") + if("check_warrants") check_records = !check_records - update_controls() - if("switchmode") + if("handcuff_targets") arrest_type = !arrest_type - update_controls() - if("declarearrests") + if("arrest_alert") declare_arrests = !declare_arrests - update_controls() + return /mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/H) var/judgement_criteria = judgement_criteria() @@ -388,7 +365,7 @@ Auto Patrol: []"}, playsound(src, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2) C.visible_message("[process_emote("CAPTURE_ONE", C)]",\ "[process_emote("CAPTURE_TWO", C)]") - if(do_after(src, 60, FALSE, C)) + if(do_after(src, 60, C)) attempt_handcuff(C) /mob/living/simple_animal/bot/secbot/proc/attempt_handcuff(mob/living/carbon/C) diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 7b1e2dcaba..7d37039fa1 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -46,7 +46,7 @@ var/runetype var/datum/mind/original_mind -/mob/living/simple_animal/hostile/construct/Initialize() +/mob/living/simple_animal/hostile/construct/Initialize(mapload) . = ..() update_health_hud() var/spellnum = 1 @@ -83,13 +83,12 @@ /mob/living/simple_animal/hostile/construct/examine(mob/user) var/t_He = p_they(TRUE) var/t_s = p_s() - . = list("*---------*\nThis is [icon2html(src, user)] \a [src]!\n[desc]") + . = list("This is [icon2html(src, user)] \a [src]!\n[desc]") if(health < maxHealth) if(health >= maxHealth/2) . += "[t_He] look[t_s] slightly dented." else . += "[t_He] look[t_s] severely dented!" - . += "*---------*" /mob/living/simple_animal/hostile/construct/attack_animal(mob/living/simple_animal/M) if(isconstruct(M)) //is it a construct? @@ -382,7 +381,7 @@ return FALSE . = ..() -/mob/living/simple_animal/hostile/construct/harvester/Initialize() +/mob/living/simple_animal/hostile/construct/harvester/Initialize(mapload) . = ..() var/datum/action/innate/seek_prey/seek = new() seek.Grant(src) diff --git a/code/modules/mob/living/simple_animal/eldritch_demons.dm b/code/modules/mob/living/simple_animal/eldritch_demons.dm index 4a96c4be67..eafac41303 100644 --- a/code/modules/mob/living/simple_animal/eldritch_demons.dm +++ b/code/modules/mob/living/simple_animal/eldritch_demons.dm @@ -34,7 +34,7 @@ ///Innate spells that are supposed to be added when a beast is created var/list/spells_to_add -/mob/living/simple_animal/hostile/eldritch/Initialize() +/mob/living/simple_animal/hostile/eldritch/Initialize(mapload) . = ..() add_spells() @@ -63,7 +63,7 @@ var/list/linked_mobs = list() -/mob/living/simple_animal/hostile/eldritch/raw_prophet/Initialize() +/mob/living/simple_animal/hostile/eldritch/raw_prophet/Initialize(mapload) . = ..() link_mob(src) @@ -223,7 +223,7 @@ QDEL_NULL(back) // chain destruction baby return ..() -/mob/living/simple_animal/hostile/eldritch/armsy/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/eldritch/armsy/BiologicalLife(delta_time, times_fired) adjustBruteLoss(-2) /mob/living/simple_animal/hostile/eldritch/armsy/proc/heal() diff --git a/code/modules/mob/living/simple_animal/friendly/bumbles.dm b/code/modules/mob/living/simple_animal/friendly/bumbles.dm index 53be1434c9..dca823ba21 100644 --- a/code/modules/mob/living/simple_animal/friendly/bumbles.dm +++ b/code/modules/mob/living/simple_animal/friendly/bumbles.dm @@ -31,7 +31,7 @@ speak_chance = 1 unique_name = FALSE -/mob/living/simple_animal/pet/bumbles/Initialize() +/mob/living/simple_animal/pet/bumbles/Initialize(mapload) . = ..() add_verb(src, /mob/living/proc/lay_down) AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) diff --git a/code/modules/mob/living/simple_animal/friendly/butterfly.dm b/code/modules/mob/living/simple_animal/friendly/butterfly.dm index 1e6afd6044..5cb54ce6ca 100644 --- a/code/modules/mob/living/simple_animal/friendly/butterfly.dm +++ b/code/modules/mob/living/simple_animal/friendly/butterfly.dm @@ -28,7 +28,7 @@ verb_exclaim = "flutters intensely" verb_yell = "flutters intensely" -/mob/living/simple_animal/butterfly/Initialize() +/mob/living/simple_animal/butterfly/Initialize(mapload) . = ..() var/newcolor = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) add_atom_colour(newcolor, FIXED_COLOUR_PRIORITY) diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 4594d27ecd..9673857a1b 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -35,8 +35,11 @@ collar_type = "cat" var/held_icon = "cat2" footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "mutedc4" + vocal_pitch = 1.4 + vocal_pitch_range = 0.4 -/mob/living/simple_animal/pet/cat/Initialize() +/mob/living/simple_animal/pet/cat/Initialize(mapload) . = ..() add_verb(src, /mob/living/proc/lay_down) AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) @@ -107,7 +110,7 @@ var/cats_deployed = 0 var/memory_saved = FALSE -/mob/living/simple_animal/pet/cat/Runtime/Initialize() +/mob/living/simple_animal/pet/cat/Runtime/Initialize(mapload) if(prob(5)) icon_state = "original" icon_living = "original" @@ -115,7 +118,7 @@ Read_Memory() . = ..() -/mob/living/simple_animal/pet/cat/Runtime/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/cat/Runtime/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!cats_deployed && SSticker.current_state >= GAME_STATE_SETTING_UP) @@ -136,6 +139,7 @@ ..() /mob/living/simple_animal/pet/cat/Runtime/proc/Read_Memory() + var/saved_color if(fexists("data/npc_saves/Runtime.sav")) //legacy compatability to convert old format to new var/savefile/S = new /savefile("data/npc_saves/Runtime.sav") S["family"] >> family @@ -146,14 +150,21 @@ return var/list/json = json_decode(file2text(json_file)) family = json["family"] + saved_color = json["color"] if(isnull(family)) family = list() + if(!isnull(saved_color)) + add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY) /mob/living/simple_animal/pet/cat/Runtime/proc/Write_Memory(dead) var/json_file = file("data/npc_saves/Runtime.json") var/list/file_data = list() family = list() if(!dead) + if(color) + file_data["color"] = json_encode(color) + else + file_data["color"] = null for(var/mob/living/simple_animal/pet/cat/kitten/C in children) if(istype(C,type) || C.stat || !C.z || !C.butcher_results) //That last one is a work around for hologram cats continue @@ -161,6 +172,8 @@ family[C.type] += 1 else family[C.type] = 1 + else + file_data["color"] = null file_data["family"] = family fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) @@ -178,7 +191,7 @@ gold_core_spawnable = NO_SPAWN unique_pet = TRUE -/mob/living/simple_animal/pet/cat/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/cat/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat && !buckled && !client) @@ -272,7 +285,7 @@ to_chat(src, "Your name is now \"new_name\"!") name = new_name -/mob/living/simple_animal/pet/cat/cak/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/cat/cak/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(stat) diff --git a/code/modules/mob/living/simple_animal/friendly/cockroach.dm b/code/modules/mob/living/simple_animal/friendly/cockroach.dm index f65b2bab9b..66e9c75315 100644 --- a/code/modules/mob/living/simple_animal/friendly/cockroach.dm +++ b/code/modules/mob/living/simple_animal/friendly/cockroach.dm @@ -31,7 +31,7 @@ var/squish_chance = 50 del_on_death = 1 -/mob/living/simple_animal/cockroach/Initialize() +/mob/living/simple_animal/cockroach/Initialize(mapload) . = ..() AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) @@ -60,5 +60,5 @@ else visible_message("[src] avoids getting crushed.") -/mob/living/simple_animal/cockroach/ex_act() //Explosions are a terrible way to handle a cockroach. +/mob/living/simple_animal/cockroach/ex_act(severity, target, origin) //Explosions are a terrible way to handle a cockroach. return diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm index addbd493a5..775ad05c11 100644 --- a/code/modules/mob/living/simple_animal/friendly/crab.dm +++ b/code/modules/mob/living/simple_animal/friendly/crab.dm @@ -26,11 +26,11 @@ var/obj/item/inventory_mask gold_core_spawnable = FRIENDLY_SPAWN -/mob/living/simple_animal/crab/Initialize() +/mob/living/simple_animal/crab/Initialize(mapload) . = ..() AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) -/mob/living/simple_animal/crab/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/crab/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return //CRAB movement diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index fb3d009a72..e4d042a4cc 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -20,10 +20,14 @@ footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "bullet" + vocal_speed = 6 + /mob/living/simple_animal/pet/dog/ComponentInitialize() . = ..() AddElement(/datum/element/wuv, "yaps happily!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "growls!", EMOTE_AUDIBLE) AddElement(/datum/element/mob_holder, held_icon) + AddElement(/datum/element/strippable, GLOB.strippable_corgi_items) //Corgis and pugs are now under one dog subtype @@ -83,7 +87,7 @@ animal_species = /mob/living/simple_animal/pet/dog/corgi/exoticcorgi nofur = TRUE -/mob/living/simple_animal/pet/dog/Initialize() +/mob/living/simple_animal/pet/dog/Initialize(mapload) . = ..() var/dog_area = get_area(src) for(var/obj/structure/bed/dogbed/D in dog_area) @@ -91,11 +95,11 @@ D.update_owner(src) break -/mob/living/simple_animal/pet/dog/corgi/Initialize() +/mob/living/simple_animal/pet/dog/corgi/Initialize(mapload) . = ..() regenerate_icons() -/mob/living/simple_animal/pet/dog/corgi/exoticcorgi/Initialize() +/mob/living/simple_animal/pet/dog/corgi/exoticcorgi/Initialize(mapload) . = ..() var/newcolor = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) add_atom_colour(newcolor, FIXED_COLOUR_PRIORITY) @@ -104,18 +108,175 @@ ..(gibbed) regenerate_icons() -/mob/living/simple_animal/pet/dog/corgi/show_inv(mob/user) - if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) +GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( + /datum/strippable_item/corgi_head, + /datum/strippable_item/corgi_back, + /datum/strippable_item/corgi_collar, + /datum/strippable_item/corgi_id, +))) + +/datum/strippable_item/corgi_head + key = STRIPPABLE_ITEM_HEAD + +/datum/strippable_item/corgi_head/get_item(atom/source) + var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + if (!istype(corgi_source)) return - user.set_machine(src) - var/dat = "
    Inventory of [name]

    " - dat += "
    Head: [inventory_head]" : "add_inv=head'>Nothing"]" - dat += "
    Back: [inventory_back]" : "add_inv=back'>Nothing"]" - dat += "
    Collar: [pcollar]" : "add_inv=collar'>Nothing"]" + return corgi_source.inventory_head - user << browse(dat, "window=mob[REF(src)];size=325x500") - onclose(user, "mob[REF(src)]") +/datum/strippable_item/corgi_head/finish_equip(atom/source, obj/item/equipping, mob/user) + if(!..()) + return FALSE + var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + if (!istype(corgi_source)) + return FALSE + + corgi_source.place_on_head(equipping, user) + +/datum/strippable_item/corgi_head/finish_unequip(atom/source, mob/user) + ..() + var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + if (!istype(corgi_source)) + return + + finish_unequip_mob(corgi_source.inventory_head, corgi_source, user) + corgi_source.inventory_head = null + corgi_source.update_corgi_fluff() + corgi_source.regenerate_icons() + +/datum/strippable_item/corgi_back + key = STRIPPABLE_ITEM_BACK + +/datum/strippable_item/corgi_back/get_item(atom/source) + var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + if (!istype(corgi_source)) + return + + return corgi_source.inventory_back + +/datum/strippable_item/corgi_back/try_equip(atom/source, obj/item/equipping, mob/user) + . = ..() + if (!.) + return FALSE + + if (!ispath(equipping.dog_fashion, /datum/dog_fashion/back)) + to_chat(user, "You set [equipping] on [source]'s back, but it falls off!") + equipping.forceMove(source.drop_location()) + if (prob(25)) + step_rand(equipping) + dance_rotate(source, set_original_dir = TRUE) + + return FALSE + + return TRUE + +/datum/strippable_item/corgi_back/finish_equip(atom/source, obj/item/equipping, mob/user) + if(!..()) + return FALSE + var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + if (!istype(corgi_source)) + return FALSE + + equipping.forceMove(corgi_source) + corgi_source.inventory_back = equipping + corgi_source.update_corgi_fluff() + corgi_source.regenerate_icons() + +/datum/strippable_item/corgi_back/finish_unequip(atom/source, mob/user) + ..() + var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + if (!istype(corgi_source)) + return + + finish_unequip_mob(corgi_source.inventory_back, corgi_source, user) + corgi_source.inventory_back = null + corgi_source.update_corgi_fluff() + corgi_source.regenerate_icons() + +/datum/strippable_item/corgi_collar + key = STRIPPABLE_ITEM_CORGI_COLLAR + +/datum/strippable_item/corgi_collar/get_item(atom/source) + var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + if (!istype(corgi_source)) + return + + return corgi_source.pcollar + +/datum/strippable_item/corgi_collar/try_equip(atom/source, obj/item/equipping, mob/user) + . = ..() + if (!.) + return FALSE + + if (!istype(equipping, /obj/item/clothing/neck/petcollar)) + to_chat(user, "That's not a collar.") + return FALSE + + return TRUE + +/datum/strippable_item/corgi_collar/finish_equip(atom/source, obj/item/equipping, mob/user) + if(!..()) + return FALSE + var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + if (!istype(corgi_source)) + return FALSE + + corgi_source.add_collar(equipping, user) + corgi_source.update_corgi_fluff() + +/datum/strippable_item/corgi_collar/finish_unequip(atom/source, mob/user) + ..() + var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + if (!istype(corgi_source)) + return + + finish_unequip_mob(corgi_source.pcollar, corgi_source, user) + corgi_source.pcollar = null + corgi_source.update_corgi_fluff() + corgi_source.regenerate_icons() + +/datum/strippable_item/corgi_id + key = STRIPPABLE_ITEM_ID + +/datum/strippable_item/corgi_id/get_item(atom/source) + var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + if (!istype(corgi_source)) + return + + return corgi_source.access_card + +/datum/strippable_item/corgi_id/try_equip(atom/source, obj/item/equipping, mob/user) + . = ..() + if (!.) + return FALSE + + if (!istype(equipping, /obj/item/card/id)) + to_chat(user, "You can't pin [equipping] to [source]!") + return FALSE + + return TRUE + +/datum/strippable_item/corgi_id/finish_equip(atom/source, obj/item/equipping, mob/user) + if(!..()) + return FALSE + var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + if (!istype(corgi_source)) + return FALSE + + equipping.forceMove(source) + corgi_source.access_card = equipping + +/datum/strippable_item/corgi_id/finish_unequip(atom/source, mob/user) + ..() + var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + if (!istype(corgi_source)) + return + + finish_unequip_mob(corgi_source.access_card, corgi_source, user) + corgi_source.access_card = null + corgi_source.update_corgi_fluff() + corgi_source.regenerate_icons() /mob/living/simple_animal/pet/dog/corgi/getarmor(def_zone, type) var/armorval = 0 @@ -158,114 +319,12 @@ ..() update_corgi_fluff() -/mob/living/simple_animal/pet/dog/corgi/Topic(href, href_list) - if(!(iscarbon(usr) || iscyborg(usr)) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) - usr << browse(null, "window=mob[REF(src)]") - usr.unset_machine() - return - - //Removing from inventory - if(href_list["remove_inv"]) - var/remove_from = href_list["remove_inv"] - switch(remove_from) - if(BODY_ZONE_HEAD) - if(inventory_head) - usr.put_in_hands(inventory_head) - inventory_head = null - update_corgi_fluff() - regenerate_icons() - else - to_chat(usr, "There is nothing to remove from its [remove_from].") - return - if("back") - if(inventory_back) - usr.put_in_hands(inventory_back) - inventory_back = null - update_corgi_fluff() - regenerate_icons() - else - to_chat(usr, "There is nothing to remove from its [remove_from].") - return - if("collar") - if(pcollar) - usr.put_in_hands(pcollar) - pcollar = null - update_corgi_fluff() - regenerate_icons() - - show_inv(usr) - - //Adding things to inventory - else if(href_list["add_inv"]) - - var/add_to = href_list["add_inv"] - - switch(add_to) - if("collar") - var/obj/item/clothing/neck/petcollar/P = usr.get_active_held_item() - if(!istype(P)) - to_chat(usr,"That's not a collar.") - return - add_collar(P, usr) - update_corgi_fluff() - - if(BODY_ZONE_HEAD) - place_on_head(usr.get_active_held_item(),usr) - - if("back") - if(inventory_back) - to_chat(usr, "It's already wearing something!") - return - else - var/obj/item/item_to_add = usr.get_active_held_item() - - if(!item_to_add) - usr.visible_message("[usr] pets [src].","You rest your hand on [src]'s back for a moment.") - return - - if(!usr.temporarilyRemoveItemFromInventory(item_to_add)) - to_chat(usr, "\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s back!") - return - - if(istype(item_to_add, /obj/item/grenade/plastic)) // last thing he ever wears, I guess - item_to_add.afterattack(src,usr,1) - return - - //The objects that corgis can wear on their backs. - var/allowed = FALSE - if(ispath(item_to_add.dog_fashion, /datum/dog_fashion/back)) - allowed = TRUE - - if(!allowed) - to_chat(usr, "You set [item_to_add] on [src]'s back, but it falls off!") - item_to_add.forceMove(drop_location()) - if(prob(25)) - step_rand(item_to_add) - for(var/i in list(1,2,4,8,4,8,4,dir)) - setDir(i) - sleep(1) - return - - item_to_add.forceMove(src) - src.inventory_back = item_to_add - update_corgi_fluff() - regenerate_icons() - - show_inv(usr) - else - return ..() - //Corgis are supposed to be simpler, so only a select few objects can actually be put //to be compatible with them. The objects are below. //Many hats added, Some will probably be removed, just want to see which ones are popular. // > some will probably be removed /mob/living/simple_animal/pet/dog/corgi/proc/place_on_head(obj/item/item_to_add, mob/user) - - if(istype(item_to_add, /obj/item/grenade/plastic)) // last thing he ever wears, I guess - INVOKE_ASYNC(item_to_add, /obj/item.proc/afterattack, src, user, 1) - return - if(inventory_head) if(user) to_chat(user, "You can't put more than one hat on [src]!") @@ -303,12 +362,12 @@ item_to_add.forceMove(drop_location()) if(prob(25)) step_rand(item_to_add) - for(var/i in list(1,2,4,8,4,8,4,dir)) - setDir(i) - sleep(1) + dance_rotate(src, set_original_dir = TRUE) return valid + + /mob/living/simple_animal/pet/dog/corgi/proc/update_corgi_fluff() // First, change back to defaults name = real_name @@ -344,7 +403,7 @@ var/memory_saved = FALSE var/saved_head //path -/mob/living/simple_animal/pet/dog/corgi/Ian/Initialize() +/mob/living/simple_animal/pet/dog/corgi/Ian/Initialize(mapload) . = ..() //parent call must happen first to ensure IAN //is not in nullspace when child puppies spawn @@ -368,7 +427,7 @@ RemoveElement(/datum/element/mob_holder, held_icon) AddElement(/datum/element/mob_holder, "old_corgi") -/mob/living/simple_animal/pet/dog/corgi/Ian/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/dog/corgi/Ian/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved) @@ -382,6 +441,7 @@ /mob/living/simple_animal/pet/dog/corgi/Ian/proc/Read_Memory() set waitfor = FALSE + var/saved_color if(fexists("data/npc_saves/Ian.sav")) //legacy compatability to convert old format to new var/savefile/S = new /savefile("data/npc_saves/Ian.sav") S["age"] >> age @@ -396,12 +456,15 @@ age = json["age"] record_age = json["record_age"] saved_head = json["saved_head"] + saved_color = json["color"] if(isnull(age)) age = 0 if(isnull(record_age)) record_age = 1 if(saved_head) place_on_head(new saved_head) + if(!isnull(saved_color)) + add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY) /mob/living/simple_animal/pet/dog/corgi/Ian/proc/Write_Memory(dead) var/json_file = file("data/npc_saves/Ian.json") @@ -416,10 +479,15 @@ file_data["saved_head"] = inventory_head.type else file_data["saved_head"] = null + if(color) + file_data["color"] = json_encode(color) + else + file_data["color"] = null else file_data["age"] = 0 file_data["record_age"] = record_age file_data["saved_head"] = null + file_data["color"] = null fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) @@ -497,7 +565,7 @@ nofur = TRUE unique_pet = TRUE -/mob/living/simple_animal/pet/dog/corgi/narsie/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/dog/corgi/narsie/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return for(var/mob/living/simple_animal/pet/P in range(1, src)) @@ -576,6 +644,8 @@ mob_size = MOB_SIZE_SMALL collar_type = "puppy" + vocal_pitch = 1.6 + //puppies cannot wear anything. /mob/living/simple_animal/pet/dog/corgi/puppy/Topic(href, href_list) if(href_list["remove_inv"] || href_list["add_inv"]) @@ -597,6 +667,8 @@ maxbodytemp = T0C + 40 held_icon = "void_puppy" + vocal_pitch = 0.6 + /mob/living/simple_animal/pet/dog/corgi/puppy/void/Process_Spacemove(movement_dir = 0) return 1 //Void puppies can navigate space. @@ -623,7 +695,7 @@ return ..() -/mob/living/simple_animal/pet/dog/corgi/Lisa/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/dog/corgi/Lisa/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return @@ -637,7 +709,7 @@ setDir(i) sleep(1) -/mob/living/simple_animal/pet/dog/pug/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/dog/pug/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index ecd5db3ccf..6b524f6114 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -79,7 +79,7 @@ "These rules are at admin discretion and will be heavily enforced.\n"+\ "If you do not have the regular drone laws, follow your laws to the best of your ability." -/mob/living/simple_animal/drone/Initialize() +/mob/living/simple_animal/drone/Initialize(mapload) . = ..() GLOB.drones_list += src access_card = new /obj/item/card/id(src) @@ -88,10 +88,10 @@ if(default_storage) var/obj/item/I = new default_storage(src) - equip_to_slot_or_del(I, SLOT_GENERC_DEXTROUS_STORAGE) + equip_to_slot_or_del(I, ITEM_SLOT_DEX_STORAGE) if(default_hatmask) var/obj/item/I = new default_hatmask(src) - equip_to_slot_or_del(I, SLOT_HEAD) + equip_to_slot_or_del(I, ITEM_SLOT_HEAD) ADD_TRAIT(access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) @@ -140,6 +140,12 @@ if(!picked) pickVisualAppearence() +/mob/living/simple_animal/drone/auto_deadmin_on_login() + if(!client?.holder) + return TRUE + if(CONFIG_GET(flag/auto_deadmin_silicons) || (client.prefs?.deadmin & DEADMIN_POSITION_SILICON)) + return client.holder.auto_deadmin() + return ..() /mob/living/simple_animal/drone/death(gibbed) ..(gibbed) @@ -172,7 +178,7 @@ /mob/living/simple_animal/drone/examine(mob/user) - . = list("*---------*\nThis is [icon2html(src, user)] \a [src]!") + . = list("This is [icon2html(src, user)] \a [src]!") //Hands for(var/obj/item/I in held_items) @@ -208,7 +214,7 @@ . += "A message repeatedly flashes on its display: \"REBOOT -- REQUIRED\"." else . += "A message repeatedly flashes on its display: \"ERROR -- OFFLINE\"." - . += "*---------*" + . += "" /mob/living/simple_animal/drone/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) //Secbots won't hunt maintenance drones. @@ -225,20 +231,26 @@ adjustBruteLoss(heavy_emp_damage) to_chat(src, "HeAV% DA%^MMA+G TO I/O CIR!%UUT!") -/mob/living/simple_animal/drone/proc/triggerAlarm(class, area/A, O, obj/alarmsource) - if(alarmsource.z != z) +/mob/living/simple_animal/drone/proc/triggerAlarm(class, area/home, cameras, obj/source) + if(source.z != z) return - if(stat != DEAD) - var/list/L = src.alarms[class] - for (var/I in L) - if (I == A.name) - var/list/alarm = L[I] - var/list/sources = alarm[2] - if (!(alarmsource in sources)) - sources += alarmsource - return - L[A.name] = list(A, list(alarmsource)) - to_chat(src, "--- [class] alarm detected in [A.name]!") + if(stat == DEAD) + return + var/list/our_sort = alarms[class] + for(var/areaname in our_sort) + if (areaname == home.name) + var/list/alarm = our_sort[areaname] + var/list/sources = alarm[3] + if (!(source in sources)) + sources += source + return TRUE + + our_sort[home.name] = list(home, list(source)) + to_chat(src, "--- [class] alarm detected in [home.name]!") + +///This isn't currently needed since drones do jack shit with cameras. I hate this code so much +/mob/living/simple_animal/drone/proc/freeCamera(area/home, obj/machinery/camera/cam) + return /mob/living/simple_animal/drone/proc/cancelAlarm(class, area/A, obj/origin) if(stat != DEAD) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm index 948be53abc..10cb6bde83 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm @@ -17,7 +17,7 @@ var/seasonal_hats = TRUE //If TRUE, and there are no default hats, different holidays will grant different hats var/static/list/possible_seasonal_hats //This is built automatically in build_seasonal_hats() but can also be edited by admins! -/obj/item/drone_shell/Initialize() +/obj/item/drone_shell/Initialize(mapload) . = ..() var/area/A = get_area(src) if(A) @@ -61,7 +61,7 @@ if(!D.default_hatmask && seasonal_hats && possible_seasonal_hats.len) var/hat_type = pick(possible_seasonal_hats) var/obj/item/new_hat = new hat_type(D) - D.equip_to_slot_or_del(new_hat, SLOT_HEAD) + D.equip_to_slot_or_del(new_hat, ITEM_SLOT_HEAD) D.flags_1 |= (flags_1 & ADMIN_SPAWNED_1) user.transfer_ckey(D, FALSE) qdel(src) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm index 12b6447a02..4acbd41977 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm @@ -31,7 +31,7 @@ hacked = TRUE flavortext = null -/mob/living/simple_animal/drone/syndrone/Initialize() +/mob/living/simple_animal/drone/syndrone/Initialize(mapload) . = ..() var/datum/component/uplink/hidden_uplink = internal_storage.GetComponent(/datum/component/uplink) hidden_uplink.telecrystals = 10 @@ -45,7 +45,7 @@ default_hatmask = /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite default_storage = /obj/item/uplink/nuclear -/mob/living/simple_animal/drone/syndrone/badass/Initialize() +/mob/living/simple_animal/drone/syndrone/badass/Initialize(mapload) . = ..() var/datum/component/uplink/hidden_uplink = internal_storage.GetComponent(/datum/component/uplink) hidden_uplink.telecrystals = 30 @@ -55,7 +55,7 @@ /mob/living/simple_animal/drone/snowflake default_hatmask = /obj/item/clothing/head/chameleon/drone -/mob/living/simple_animal/drone/snowflake/Initialize() +/mob/living/simple_animal/drone/snowflake/Initialize(mapload) . = ..() desc += " This drone appears to have a complex holoprojector built on its 'head'." @@ -79,7 +79,7 @@ default_hatmask = null picked = TRUE -/mob/living/simple_animal/drone/polymorphed/Initialize() +/mob/living/simple_animal/drone/polymorphed/Initialize(mapload) . = ..() liberate() visualAppearence = pick(MAINTDRONE, REPAIRDRONE, SCOUTDRONE) @@ -136,7 +136,7 @@ /mob/living/simple_animal/drone/cogscarab/admin //an admin-only subtype of cogscarab with a no-cost fabricator and slab in its box default_storage = /obj/item/storage/toolbox/brass/prefilled/ratvar/admin -/mob/living/simple_animal/drone/cogscarab/Initialize() +/mob/living/simple_animal/drone/cogscarab/Initialize(mapload) . = ..() set_light(2, 0.5) qdel(access_card) //we don't have free access @@ -188,6 +188,9 @@ /mob/living/simple_animal/drone/cogscarab/update_drone_hack() return //we don't get hacked or give a shit about it +/mob/living/simple_animal/drone/cogscarab/death(gibbed) + . = ..() + /mob/living/simple_animal/drone/cogscarab/drone_chat(msg) titled_hierophant_message(src, msg, "nezbere", "brass", "Construct") //HIEROPHANT DRONES diff --git a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm index d9ea6f4a8a..b7545de517 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm @@ -17,7 +17,7 @@ if("Cannibalize") if(D.health < D.maxHealth) D.visible_message("[D] begins to cannibalize parts from [src].", "You begin to cannibalize parts from [src]...") - if(do_after(D, 60, 0, target = src)) + if(do_after(D, 6 SECONDS, src)) D.visible_message("[D] repairs itself using [src]'s remains!", "You repair yourself using [src]'s remains.") D.adjustBruteLoss(-src.maxHealth) new /obj/effect/decal/cleanable/oil/streak(get_turf(src)) @@ -44,7 +44,7 @@ to_chat(user, "You can't seem to find the [pick(faux_gadgets)]! Without it, [src] [pick(faux_problems)].") return user.visible_message("[user] begins to reactivate [src].", "You begin to reactivate [src]...") - if(do_after(user, 30, 1, target = src)) + if(do_after(user, 3 SECONDS, src)) revive(full_heal = 1) user.visible_message("[user] reactivates [src]!", "You reactivate [src].") alert_drones(DRONE_NET_CONNECT) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm b/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm index 00be08bb1d..4c112858da 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm @@ -21,13 +21,13 @@ /mob/living/simple_animal/drone/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, clothing_check = FALSE, list/return_warning) switch(slot) - if(SLOT_HEAD) + if(ITEM_SLOT_HEAD) if(head) return 0 if(!((I.slot_flags & ITEM_SLOT_HEAD) || (I.slot_flags & ITEM_SLOT_MASK))) return 0 return 1 - if(SLOT_GENERC_DEXTROUS_STORAGE) + if(ITEM_SLOT_DEX_STORAGE) if(internal_storage) return 0 return 1 @@ -36,9 +36,9 @@ /mob/living/simple_animal/drone/get_item_by_slot(slot_id) switch(slot_id) - if(SLOT_HEAD) + if(ITEM_SLOT_HEAD) return head - if(SLOT_GENERC_DEXTROUS_STORAGE) + if(ITEM_SLOT_DEX_STORAGE) return internal_storage return ..() @@ -63,10 +63,10 @@ I.plane = ABOVE_HUD_PLANE switch(slot) - if(SLOT_HEAD) + if(ITEM_SLOT_HEAD) head = I update_inv_head() - if(SLOT_GENERC_DEXTROUS_STORAGE) + if(ITEM_SLOT_DEX_STORAGE) internal_storage = I update_inv_internal_storage() else @@ -77,7 +77,7 @@ I.equipped(src, slot) /mob/living/simple_animal/drone/getBackSlot() - return SLOT_GENERC_DEXTROUS_STORAGE + return ITEM_SLOT_DEX_STORAGE /mob/living/simple_animal/drone/getBeltSlot() - return SLOT_GENERC_DEXTROUS_STORAGE + return ITEM_SLOT_DEX_STORAGE diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 81925d922f..7893f7b26b 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -36,8 +36,9 @@ var/datum/reagent/milk_reagent = /datum/reagent/consumable/milk footstep_type = FOOTSTEP_MOB_SHOE + vocal_bark_id = "banjoc3" -/mob/living/simple_animal/hostile/retaliate/goat/Initialize(/datum/reagent/milk_reagent) +/mob/living/simple_animal/hostile/retaliate/goat/Initialize(mapload, /datum/reagent/milk_reagent) udder = new (null, milk_reagent) . = ..() @@ -46,7 +47,7 @@ udder = null return ..() -/mob/living/simple_animal/hostile/retaliate/goat/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/retaliate/goat/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(stat == CONSCIOUS) @@ -143,8 +144,10 @@ blood_volume = BLOOD_VOLUME_NORMAL footstep_type = FOOTSTEP_MOB_SHOE + vocal_bark_id = "mutedc2" + vocal_pitch = 1.2 -/mob/living/simple_animal/cow/Initialize() +/mob/living/simple_animal/cow/Initialize(mapload) udder = new(null, milk_reagent) . = ..() @@ -160,7 +163,7 @@ else return ..() -/mob/living/simple_animal/cow/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/cow/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(stat == CONSCIOUS) @@ -197,7 +200,7 @@ name = "strange cow" desc = "Something seems off about the milk this cow is producing." -/mob/living/simple_animal/cow/random/Initialize() +/mob/living/simple_animal/cow/random/Initialize(mapload) milk_reagent = get_random_reagent_id() //this has a blacklist so don't worry about romerol cows, etc ..() @@ -210,7 +213,7 @@ speak_chance = 10 //the cow is eager to share its wisdom! //but is wise enough to not lag the server too bad milk_reagent = /datum/reagent/medicine/liquid_wisdom -/mob/living/simple_animal/cow/wisdom/Initialize() +/mob/living/simple_animal/cow/wisdom/Initialize(mapload) . = ..() speak = GLOB.wisdoms //Done here so it's setup properly @@ -247,14 +250,16 @@ gold_core_spawnable = FRIENDLY_SPAWN footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "squeak" + vocal_pitch = 1.4 -/mob/living/simple_animal/chick/Initialize() +/mob/living/simple_animal/chick/Initialize(mapload) . = ..() pixel_x = rand(-6, 6) pixel_y = rand(0, 10) AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) -/mob/living/simple_animal/chick/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/chick/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat && !ckey) @@ -263,7 +268,7 @@ new /mob/living/simple_animal/chicken(src.loc) qdel(src) -/mob/living/simple_animal/chick/holo/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/chick/holo/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return amount_grown = 0 @@ -309,8 +314,11 @@ var/static/chicken_count = 0 footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "synthgrunt" + vocal_pitch = 1.4 + vocal_pitch_range = 0.4 -/mob/living/simple_animal/chicken/Initialize() +/mob/living/simple_animal/chicken/Initialize(mapload) . = ..() if(!body_color) body_color = pick(validColors) @@ -339,7 +347,7 @@ else ..() -/mob/living/simple_animal/chicken/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/chicken/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if((!stat && prob(3) && eggsleft > 0) && egg_type) @@ -403,18 +411,20 @@ var/static/kiwi_count = 0 footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "squeak" + vocal_pitch = 1.4 /mob/living/simple_animal/kiwi/Destroy() --kiwi_count return ..() -/mob/living/simple_animal/kiwi/Initialize() +/mob/living/simple_animal/kiwi/Initialize(mapload) . = ..() ++kiwi_count AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) -/mob/living/simple_animal/kiwi/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/kiwi/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if((!stat && prob(3) && eggsleft > 0) && egg_type) @@ -481,15 +491,17 @@ gold_core_spawnable = FRIENDLY_SPAWN footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "squeak" + vocal_pitch = 1.4 -/mob/living/simple_animal/babyKiwi/Initialize() +/mob/living/simple_animal/babyKiwi/Initialize(mapload) . = ..() pixel_x = rand(-6, 6) pixel_y = rand(0, 10) AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) -/mob/living/simple_animal/babyKiwi/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/babyKiwi/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat && !ckey) @@ -506,7 +518,7 @@ /obj/item/udder name = "udder" -/obj/item/udder/Initialize(loc, milk_reagent) +/obj/item/udder/Initialize(mapload, loc, milk_reagent) if(!milk_reagent) milk_reagent = /datum/reagent/consumable/milk create_reagents(50, NONE, NO_REAGENTS_VALUE) @@ -557,3 +569,4 @@ maxHealth = 75 blood_volume = BLOOD_VOLUME_NORMAL footstep_type = FOOTSTEP_MOB_SHOE + vocal_bark_id = "mutedc4" diff --git a/code/modules/mob/living/simple_animal/friendly/fox.dm b/code/modules/mob/living/simple_animal/friendly/fox.dm index 4e4fd7ccfc..475b50d44a 100644 --- a/code/modules/mob/living/simple_animal/friendly/fox.dm +++ b/code/modules/mob/living/simple_animal/friendly/fox.dm @@ -23,6 +23,11 @@ gold_core_spawnable = FRIENDLY_SPAWN footstep_type = FOOTSTEP_MOB_CLAW + vocal_bark_id = "bullet" + vocal_speed = 2 + vocal_pitch = 1.6 + vocal_pitch_range = 0.4 + /mob/living/simple_animal/pet/fox/ComponentInitialize() . = ..() AddElement(/datum/element/mob_holder, "fox") diff --git a/code/modules/mob/living/simple_animal/friendly/gondola.dm b/code/modules/mob/living/simple_animal/friendly/gondola.dm index e29cbb8062..8ba92fd967 100644 --- a/code/modules/mob/living/simple_animal/friendly/gondola.dm +++ b/code/modules/mob/living/simple_animal/friendly/gondola.dm @@ -31,7 +31,7 @@ //Gondolas don't make footstep sounds -/mob/living/simple_animal/pet/gondola/Initialize() +/mob/living/simple_animal/pet/gondola/Initialize(mapload) . = ..() if (!(istype(src, /mob/living/simple_animal/pet/gondola/gondolapod))) CreateGondola() diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 8348af43fa..f67c5dcb97 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -29,8 +29,10 @@ gold_core_spawnable = FRIENDLY_SPAWN var/chew_probability = 1 faction = list("rat") + vocal_bark_id = "squeak" + vocal_pitch = 1.4 -/mob/living/simple_animal/mouse/Initialize() +/mob/living/simple_animal/mouse/Initialize(mapload) . = ..() AddComponent(/datum/component/squeak, list('sound/effects/mousesqueek.ogg'=1), 100) if(!body_color) @@ -98,6 +100,18 @@ qdel(bigcheese) evolve() return + for(var/obj/item/trash/garbage in range(1, src)) + if(is_station_level(z)) + if(prob(2)) + qdel(garbage) + evolve_plague() + return + for(var/obj/effect/decal/cleanable/blood/gibs/leftovers in range(1, src)) + if(is_station_level(z)) + if(prob(2)) + qdel(leftovers) + evolve_plague() + return /** *Checks the mouse cap, if it's above the cap, doesn't spawn a mouse. If below, spawns a mouse and adds it to cheeserats. @@ -123,6 +137,17 @@ mind.transfer_to(regalrat) qdel(src) +/mob/living/simple_animal/mouse/proc/evolve_plague() + return + +/* + var/mob/living/simple_animal/hostile/plaguerat = new /mob/living/simple_animal/hostile/plaguerat(loc) + visible_message("[src] devours the food! He rots into something worse!") + if(mind) + mind.transfer_to(plaguerat) + qdel(src) +*/ + /* * Mouse types */ @@ -151,7 +176,7 @@ GLOBAL_VAR(tom_existed) desc = "Jerry the cat is not amused." gold_core_spawnable = NO_SPAWN -/mob/living/simple_animal/mouse/brown/Tom/Initialize() +/mob/living/simple_animal/mouse/brown/Tom/Initialize(mapload) . = ..() GLOB.tom_existed = TRUE @@ -169,3 +194,17 @@ GLOBAL_VAR(tom_existed) /obj/item/reagent_containers/food/snacks/deadmouse/on_grind() reagents.clear_reagents() +/mob/living/simple_animal/mouse/proc/miasma(datum/gas_mixture/environment, check_temp = FALSE) + if(isturf(src.loc) && isopenturf(src.loc)) + var/turf/open/ST = src.loc + var/miasma_moles = ST.air.get_moles(GAS_MIASMA) + if(prob(5) && miasma_moles >= 5) + evolve_plague() + else if(miasma_moles >= 20) + evolve_plague() + return + +/mob/living/simple_animal/mouse/handle_environment(datum/gas_mixture/environment) + . = ..() + if(is_station_level(z)) + miasma() diff --git a/code/modules/mob/living/simple_animal/friendly/pet.dm b/code/modules/mob/living/simple_animal/friendly/pet.dm index dbdb5c646c..78193b481f 100644 --- a/code/modules/mob/living/simple_animal/friendly/pet.dm +++ b/code/modules/mob/living/simple_animal/friendly/pet.dm @@ -38,7 +38,7 @@ else ..() -/mob/living/simple_animal/pet/Initialize() +/mob/living/simple_animal/pet/Initialize(mapload) . = ..() if(pcollar) pcollar = new(src) diff --git a/code/modules/mob/living/simple_animal/friendly/plushie.dm b/code/modules/mob/living/simple_animal/friendly/plushie.dm index ff95e8fe86..6a8e2565f1 100644 --- a/code/modules/mob/living/simple_animal/friendly/plushie.dm +++ b/code/modules/mob/living/simple_animal/friendly/plushie.dm @@ -29,6 +29,8 @@ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 pressure_resistance = 200 + vocal_bark_id = "squeak" + vocal_pitch_range = 0.4 /mob/living/simple_animal/pet/plushie/ComponentInitialize() . = ..() @@ -72,7 +74,7 @@ qdel(src) //low regen over time -/mob/living/simple_animal/pet/plushie/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/pet/plushie/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(health < maxHealth) diff --git a/code/modules/mob/living/simple_animal/friendly/possum.dm b/code/modules/mob/living/simple_animal/friendly/possum.dm index 5e7ed572e2..4f1e27d1db 100644 --- a/code/modules/mob/living/simple_animal/friendly/possum.dm +++ b/code/modules/mob/living/simple_animal/friendly/possum.dm @@ -27,7 +27,7 @@ mob_biotypes = MOB_ORGANIC|MOB_BEAST gold_core_spawnable = FRIENDLY_SPAWN -/mob/living/simple_animal/opossum/Initialize() +/mob/living/simple_animal/opossum/Initialize(mapload) . = ..() AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) diff --git a/code/modules/mob/living/simple_animal/friendly/snake.dm b/code/modules/mob/living/simple_animal/friendly/snake.dm index 61c735c7c1..3e40ab53bc 100644 --- a/code/modules/mob/living/simple_animal/friendly/snake.dm +++ b/code/modules/mob/living/simple_animal/friendly/snake.dm @@ -38,7 +38,7 @@ obj_damage = 0 environment_smash = ENVIRONMENT_SMASH_NONE -/mob/living/simple_animal/hostile/retaliate/poison/snake/Initialize() +/mob/living/simple_animal/hostile/retaliate/poison/snake/Initialize(mapload) . = ..() AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) diff --git a/code/modules/mob/living/simple_animal/gremlin/gremlin.dm b/code/modules/mob/living/simple_animal/gremlin/gremlin.dm new file mode 100644 index 0000000000..da6fed4051 --- /dev/null +++ b/code/modules/mob/living/simple_animal/gremlin/gremlin.dm @@ -0,0 +1,255 @@ +#define GREMLIN_VENT_CHANCE 1.75 + +//Gremlins +//Small monsters that don't attack humans or other animals. Instead they mess with electronics, computers and machinery + +//List of objects that gremlins can't tamper with (because nobody coded an interaction for it) +//List starts out empty. Whenever a gremlin finds a machine that it couldn't tamper with, the machine's type is added here, and all machines of such type are ignored from then on (NOT SUBTYPES) +GLOBAL_LIST(bad_gremlin_items) + +/mob/living/simple_animal/hostile/gremlin + name = "gremlin" + desc = "This tiny creature finds great joy in discovering and using technology. Nothing excites it more than pushing random buttons on a computer to see what it might do." + icon = 'icons/mob/mob.dmi' + icon_state = "gremlin" + icon_living = "gremlin" + icon_dead = "gremlin_dead" + + var/in_vent = FALSE + + health = 20 + maxHealth = 20 + search_objects = 3 //Completely ignore mobs + + //Tampering is handled by the 'npc_tamper()' obj proc + wanted_objects = list( + /obj/machinery, + /obj/item/reagent_containers/food, + /obj/structure/sink + ) + + var/obj/machinery/atmospherics/components/unary/vent_pump/entry_vent + var/obj/machinery/atmospherics/components/unary/vent_pump/exit_vent + + dextrous = TRUE + possible_a_intents = list(INTENT_HELP, INTENT_GRAB, INTENT_DISARM, INTENT_HARM) + faction = list("meme", "gremlin") + speed = 0.5 + gold_core_spawnable = 2 + unique_name = TRUE + + //Ensure gremlins don't attack other mobs + melee_damage_upper = 0 + melee_damage_lower = 0 + attack_sound = null + obj_damage = 0 + environment_smash = ENVIRONMENT_SMASH_NONE + + //List of objects that we don't even want to try to tamper with + //Subtypes of these are calculated too + var/list/unwanted_objects = list(/obj/machinery/atmospherics/pipe, /turf, /obj/structure) //ensure gremlins dont try to fuck with walls / normal pipes / glass / etc + + var/min_next_vent = 0 + + //Amount of ticks spent pathing to the target. If it gets above a certain amount, assume that the target is unreachable and stop + var/time_chasing_target = 0 + + //If you're going to make gremlins slower, increase this value - otherwise gremlins will abandon their targets too early + var/max_time_chasing_target = 2 + + var/next_eat = 0 + + //Last 20 heard messages are remembered by gremlins, and will be used to generate messages for comms console tampering, etc... + var/list/hear_memory = list() + var/const/max_hear_memory = 20 + +/mob/living/simple_animal/hostile/gremlin/Initialize(mapload) + . = ..() + AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) + ADD_TRAIT(src, TRAIT_SHOCKIMMUNE, INNATE_TRAIT) + access_card = new /obj/item/card/id(src) + var/datum/job/captain/C = new /datum/job/captain + access_card.access = C.get_access() + +/mob/living/simple_animal/hostile/gremlin/AttackingTarget() + var/is_hungry = world.time >= next_eat || prob(25) + if(istype(target, /obj/item/reagent_containers/food) && is_hungry) //eat food if we're hungry or bored + visible_message("[src] hungrily devours [target]!") + playsound(src, 'sound/items/eatfood.ogg', 50, 1) + qdel(target) + LoseTarget() + next_eat = world.time + rand(700, 3000) //anywhere from 70 seconds to 5 minutes until the gremlin is hungry again + return + if(istype(target, /obj)) + var/obj/M = target + tamper(M) + if(prob(50)) //50% chance to move to the next machine + LoseTarget() + +/mob/living/simple_animal/hostile/gremlin/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, message_mode) + . = ..() + if(message) + hear_memory.Insert(1, raw_message) + if(hear_memory.len > max_hear_memory) + hear_memory.Cut(hear_memory.len) + +/mob/living/simple_animal/hostile/gremlin/proc/generate_markov_input() + var/result = "" + + for(var/memory in hear_memory) + result += memory + " " + + return result + +/mob/living/simple_animal/hostile/gremlin/proc/generate_markov_chain() + return markov_chain(generate_markov_input(), rand(2,5), rand(100,700)) //The numbers are chosen arbitarily + +/mob/living/simple_animal/hostile/gremlin/proc/tamper(obj/M) + switch(M.npc_tamper_act(src)) + if(NPC_TAMPER_ACT_FORGET) + visible_message(pick( + "\The [src] plays around with \the [M], but finds it rather boring.", + "\The [src] tries to think of some more ways to screw \the [M] up, but fails miserably.", + "\The [src] decides to ignore \the [M], and starts looking for something more fun.")) + + LAZYADD(GLOB.bad_gremlin_items,M.type) + return FALSE + if(NPC_TAMPER_ACT_NOMSG) + //Don't create a visible message + return TRUE + + else + visible_message(pick( + "\The [src]'s eyes light up as \he tampers with \the [M].", + "\The [src] twists some knobs around on \the [M] and bursts into laughter!", + "\The [src] presses a few buttons on \the [M] and giggles mischievously.", + "\The [src] rubs its hands devilishly and starts messing with \the [M].", + "\The [src] turns a small valve on \the [M].")) + + //Add a clue for detectives to find. The clue is only added if no such clue already existed on that machine + return TRUE + +/mob/living/simple_animal/hostile/gremlin/CanAttack(atom/new_target) + if(LAZYFIND(GLOB.bad_gremlin_items,new_target.type)) + return FALSE + if(is_type_in_list(new_target, unwanted_objects)) + return FALSE + if(istype(new_target, /obj/machinery)) + var/obj/machinery/M = new_target + if(M.stat) //Unpowered or broken + return FALSE + else if(istype(new_target, /obj/machinery/door/firedoor)) + var/obj/machinery/door/firedoor/F = new_target + //Only tamper with firelocks that are closed, opening them! + if(!F.density) + return FALSE + + return ..() + +/mob/living/simple_animal/hostile/gremlin/death(gibbed) + walk(src,0) + QDEL_NULL(access_card) + return ..() + +/mob/living/simple_animal/hostile/gremlin/Life() + . = ..() + if(!health || stat == DEAD) + return + //Don't try to path to one target for too long. If it takes longer than a certain amount of time, assume it can't be reached and find a new one + if(!client) //don't do this shit if there's a client, they're capable of ventcrawling manually + if(in_vent) + target = null + if(entry_vent && get_dist(src, entry_vent) <= 1) + var/list/vents = list() + var/datum/pipeline/entry_vent_parent = entry_vent.parents[1] + for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in entry_vent_parent.other_atmosmch) + vents += temp_vent + if(!vents.len) + entry_vent = null + in_vent = FALSE + return + exit_vent = pick(vents) + visible_message("[src] crawls into the ventilation ducts!") + + loc = exit_vent + var/travel_time = round(get_dist(loc, exit_vent.loc) / 2) + addtimer(CALLBACK(src, .proc/exit_vents), travel_time) //come out at exit vent in 2 to 20 seconds + + + if(world.time > min_next_vent && !entry_vent && !in_vent && prob(GREMLIN_VENT_CHANCE)) //small chance to go into a vent + for(var/obj/machinery/atmospherics/components/unary/vent_pump/v in view(7,src)) + if(!v.welded) + entry_vent = v + in_vent = TRUE + walk_to(src, entry_vent) + break + if(!target) + time_chasing_target = 0 + else + if(++time_chasing_target > max_time_chasing_target) + LoseTarget() + time_chasing_target = 0 + . = ..() + +/mob/living/simple_animal/hostile/gremlin/EscapeConfinement() + if(istype(loc, /obj) && CanAttack(loc)) //If we're inside a machine, screw with it + var/obj/M = loc + tamper(M) + + return ..() + +/mob/living/simple_animal/hostile/gremlin/proc/exit_vents() + if(!exit_vent || exit_vent.welded) + loc = entry_vent + entry_vent = null + return + loc = exit_vent.loc + entry_vent = null + exit_vent = null + in_vent = FALSE + var/area/new_area = get_area(loc) + message_admins("[src] came out at [new_area][ADMIN_JMP(loc)]!") + if(new_area) + new_area.Entered(src) + visible_message("[src] climbs out of the ventilation ducts!") + min_next_vent = world.time + 900 //90 seconds between ventcrawls + +//This allows player-controlled gremlins to tamper with machinery +/mob/living/simple_animal/hostile/gremlin/UnarmedAttack(var/atom/A) + if(istype(A, /obj/machinery) || istype(A, /obj/structure)) + tamper(A) + if(istype(target, /obj/item/reagent_containers/food)) //eat food + visible_message("[src] hungrily devours [target]!", "You hungrily devour [target]!") + playsound(src, 'sound/items/eatfood.ogg', 50, 1) + qdel(target) + LoseTarget() + next_eat = world.time + rand(700, 3000) //anywhere from 70 seconds to 5 minutes until the gremlin is hungry again + + return ..() + +/mob/living/simple_animal/hostile/gremlin/IsAdvancedToolUser() + return 1 + +/mob/living/simple_animal/hostile/gremlin/proc/divide() + //Health is halved and then reduced by 2. A new gremlin is spawned with the same health as the parent + //Need to have at least 6 health for this, otherwise resulting health would be less than 1 + if(health < 7.5) + return + + visible_message("\The [src] splits into two!") + var/mob/living/simple_animal/hostile/gremlin/G = new /mob/living/simple_animal/hostile/gremlin(get_turf(src)) + + if(mind) + mind.transfer_to(G) + + health = round(health * 0.5) - 2 + maxHealth = health + resize *= 0.9 + + G.health = health + G.maxHealth = maxHealth + +/mob/living/simple_animal/hostile/gremlin/traitor + health = 85 + maxHealth = 85 + gold_core_spawnable = 0 diff --git a/code/modules/mob/living/simple_animal/gremlin/gremlin_act.dm b/code/modules/mob/living/simple_animal/gremlin/gremlin_act.dm new file mode 100644 index 0000000000..ff0eb13dc7 --- /dev/null +++ b/code/modules/mob/living/simple_animal/gremlin/gremlin_act.dm @@ -0,0 +1,214 @@ +/obj/proc/npc_tamper_act(mob/living/L) + return NPC_TAMPER_ACT_FORGET + +/obj/machinery/atmospherics/components/binary/passive_gate/npc_tamper_act(mob/living/L) + if(prob(50)) //Turn on/off + on = !on + investigate_log("was turned [on ? "on" : "off"] by [key_name(L)]", INVESTIGATE_ATMOS) + else //Change pressure + target_pressure = rand(0, MAX_OUTPUT_PRESSURE) + investigate_log("was set to [target_pressure] kPa by [key_name(L)]", INVESTIGATE_ATMOS) + update_icon() + +/obj/machinery/atmospherics/components/binary/pump/npc_tamper_act(mob/living/L) + if(prob(50)) //Turn on/off + on = !on + investigate_log("was turned [on ? "on" : "off"] by [key_name(L)]", INVESTIGATE_ATMOS) + else //Change pressure + target_pressure = rand(0, MAX_OUTPUT_PRESSURE) + investigate_log("was set to [target_pressure] kPa by [key_name(L)]", INVESTIGATE_ATMOS) + update_icon() + +/obj/machinery/atmospherics/components/binary/volume_pump/npc_tamper_act(mob/living/L) + if(prob(50)) //Turn on/off + on = !on + investigate_log("was turned [on ? "on" : "off"] by [key_name(L)]", INVESTIGATE_ATMOS) + else //Change pressure + transfer_rate = rand(0, MAX_TRANSFER_RATE) + investigate_log("was set to [transfer_rate] L/s by [key_name(L)]", INVESTIGATE_ATMOS) + update_icon() + +/obj/machinery/atmospherics/components/binary/valve/npc_tamper_act(mob/living/L) + attack_hand(L) + +/obj/machinery/space_heater/npc_tamper_act(mob/living/L) + var/list/choose_modes = list("standby", "heat", "cool") + if(prob(50)) + choose_modes -= mode + mode = pick(choose_modes) + else + on = !on + update_icon() + +/obj/machinery/shield_gen/npc_tamper_act(mob/living/L) + attack_hand(L) + +/obj/machinery/firealarm/npc_tamper_act(mob/living/L) + alarm() + +/obj/machinery/airalarm/npc_tamper_act(mob/living/L) + if(panel_open) + wires.npc_tamper(L) + else + panel_open = !panel_open + +/obj/machinery/ignition_switch/npc_tamper_act(mob/living/L) + attack_hand(L) + +/obj/machinery/flasher_button/npc_tamper_act(mob/living/L) + attack_hand(L) + +/obj/machinery/crema_switch/npc_tamper_act(mob/living/L) + attack_hand(L) + +/obj/machinery/camera/npc_tamper_act(mob/living/L) + if(!panel_open) + panel_open = !panel_open + if(wires) + wires.npc_tamper(L) + +/obj/machinery/atmospherics/components/unary/cryo_cell/npc_tamper_act(mob/living/L) + if(prob(50)) + if(beaker) + beaker.forceMove(loc) + beaker = null + else + if(occupant) + if(state_open) + if (close_machine() == usr) + on = TRUE + else + open_machine() + +/obj/machinery/door_control/npc_tamper_act(mob/living/L) + attack_hand(L) + +/obj/machinery/door/airlock/npc_tamper_act(mob/living/L) + //Open the firelocks as well, otherwise they block the way for our gremlin which isn't fun + for(var/obj/machinery/door/firedoor/F in get_turf(src)) + if(F.density) + F.npc_tamper_act(L) + + if(prob(40)) //40% - mess with wires + if(!panel_open) + panel_open = !panel_open + if(wires) + wires.npc_tamper(L) + else //60% - just open it + open() + +/obj/machinery/gibber/npc_tamper_act(mob/living/L) + attack_hand(L) + +/obj/machinery/light_switch/npc_tamper_act(mob/living/L) + attack_hand(L) + +/obj/machinery/turretid/npc_tamper_act(mob/living/L) + enabled = rand(0, 1) + lethal = rand(0, 1) + updateTurrets() + +/obj/machinery/vending/npc_tamper_act(mob/living/L) + if(!panel_open) + panel_open = !panel_open + if(wires) + wires.npc_tamper(L) + +/obj/machinery/shower/npc_tamper_act(mob/living/L) + attack_hand(L) + + +/obj/machinery/deepfryer/npc_tamper_act(mob/living/L) + //Deepfry a random nearby item + var/list/pickable_items = list() + + for(var/obj/item/I in range(1, L)) + pickable_items.Add(I) + + if(!pickable_items.len) + return + + var/obj/item/I = pick(pickable_items) + + attackby(I, L) //shove the item in, even if it can't be deepfried normally + +/obj/machinery/power/apc/npc_tamper_act(mob/living/L) + if(!panel_open) + panel_open = !panel_open + if(wires) + wires.npc_tamper(L) + +/obj/machinery/power/rad_collector/npc_tamper_act(mob/living/L) + attack_hand(L) + +/obj/machinery/power/emitter/npc_tamper_act(mob/living/L) + attack_hand(L) + +/obj/machinery/particle_accelerator/control_box/npc_tamper_act(mob/living/L) + if(!panel_open) + panel_open = !panel_open + if(wires) + wires.npc_tamper(L) + +/obj/machinery/computer/communications/npc_tamper_act(mob/living/user) + if(!authenticated) + if(prob(20)) //20% chance to log in + authenticated = TRUE + + else //Already logged in + if(prob(50)) //50% chance to log off + authenticated = FALSE + else if(istype(user, /mob/living/simple_animal/hostile/gremlin)) //make a hilarious public message + var/mob/living/simple_animal/hostile/gremlin/G = user + var/result = G.generate_markov_chain() + + if(result) + if(prob(85)) + SScommunications.make_announcement(G, FALSE, result) + var/turf/T = get_turf(G) + log_say("[key_name(usr)] ([ADMIN_JMP(T)]) has made a captain announcement: [result]") + message_admins("[key_name_admin(G)] has made a captain announcement.", 1) + else + if(SSshuttle.emergency.mode == SHUTTLE_IDLE) + SSshuttle.requestEvac(G, result) + else if(SSshuttle.emergency.mode == SHUTTLE_ESCAPE) + SSshuttle.cancelEvac(G) + +/obj/machinery/button/door/npc_tamper_act(mob/living/L) + attack_hand(L) + +/obj/machinery/sleeper/npc_tamper_act(mob/living/L) + if(prob(75)) + inject_chem(pick(available_chems)) + else + if(state_open) + close_machine() + else + open_machine() + +/obj/machinery/power/smes/npc_tamper_act(mob/living/L) + if(prob(50)) //mess with input + input_level = rand(0, input_level_max) + else //mess with output + output_level = rand(0, output_level_max) + +/obj/machinery/syndicatebomb/npc_tamper_act(mob/living/L) //suicide bomber gremlins + if(!open_panel) + open_panel = !open_panel + if(wires) + wires.npc_tamper(L) + +/obj/machinery/computer/bank_machine/npc_tamper_act(mob/living/L) + siphoning = !siphoning + +/obj/machinery/computer/slot_machine/npc_tamper_act(mob/living/L) + spin(L) + +/obj/structure/sink/npc_tamper_act(mob/living/L) + if(istype(L, /mob/living/simple_animal/hostile/gremlin)) + visible_message("\The [L] climbs into \the [src] and turns the faucet on!") + + var/mob/living/simple_animal/hostile/gremlin/G = L + G.divide() + + return NPC_TAMPER_ACT_NOMSG diff --git a/code/modules/mob/living/simple_animal/gremlin/gremlin_event.dm b/code/modules/mob/living/simple_animal/gremlin/gremlin_event.dm new file mode 100644 index 0000000000..9c4becbdcf --- /dev/null +++ b/code/modules/mob/living/simple_animal/gremlin/gremlin_event.dm @@ -0,0 +1,44 @@ +/datum/round_event_control/gremlin + name = "Spawn Gremlins" + typepath = /datum/round_event/gremlin + weight = 15 + max_occurrences = 2 + earliest_start = 20 MINUTES + min_players = 5 + category = EVENT_CATEGORY_ENTITIES + description = "Annoying little creatures go around the station causing havoc and hacking everything." + +/datum/round_event/gremlin + var/static/list/acceptable_spawns = list("xeno_spawn", "generic event spawn", "blobstart", "Assistant") + +/datum/round_event/gremlin/announce() + priority_announce("Bioscans indicate that some gremlins entered through the vents. Deal with them!", "Gremlin Alert", 'sound/announcer/classic/attention.ogg') + +/datum/round_event/gremlin/start() + + var/list/spawn_locs = list() + + for(var/obj/effect/landmark/L in GLOB.landmarks_list) + if(isturf(L.loc) && !isspaceturf(L.loc)) + if(L.name in acceptable_spawns) + spawn_locs += L.loc + if(!spawn_locs.len) //If we can't find any gremlin spawns, try the xeno spawns + for(var/obj/effect/landmark/L in GLOB.landmarks_list) + if(isturf(L.loc)) + switch(L.name) + if("Assistant") + spawn_locs += L.loc + if(!spawn_locs.len) //If we can't find THAT, then just give up and cry + return MAP_ERROR + + var/gremlins_to_spawn = rand(2,5) + var/list/gremlin_areas = list() + for(var/i = 0, i <= gremlins_to_spawn, i++) + var/spawnat = pick(spawn_locs) + spawn_locs -= spawnat + gremlin_areas += get_area(spawnat) + new /mob/living/simple_animal/hostile/gremlin(spawnat) + var/grems = gremlin_areas.Join(", ") + message_admins("Gremlins have been spawned at the areas: [grems]") + log_game("Gremlins have been spawned at the areas: [grems]") + return SUCCESSFUL_SPAWN diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index b85c0ee643..6faf8f0db5 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -60,6 +60,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians var/magic_fluff_string = "You draw the Coder, symbolizing bugs and errors. This shouldn't happen! Submit a bug report!" var/tech_fluff_string = "BOOT SEQUENCE COMPLETE. ERROR MODULE LOADED. THIS SHOULDN'T HAPPEN. Submit a bug report!" var/carp_fluff_string = "CARP CARP CARP SOME SORT OF HORRIFIC BUG BLAME THE CODERS CARP CARP CARP" + var/customized /// sigh, fine. var/datum/song/holoparasite/music_datum @@ -142,11 +143,13 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians to_chat(src, "You are capable of manifesting or recalling to your master with the buttons on your HUD. You will also find a button to communicate with [summoner.p_them()] privately there.") to_chat(src, "While personally invincible, you will die if [summoner.real_name] does, and any damage dealt to you will have a portion passed on to [summoner.p_them()] as you feed upon [summoner.p_them()] to sustain yourself.") to_chat(src, playstyle_string) - guardiancustomize() + if(!customized) + guardiancustomize() /mob/living/simple_animal/hostile/guardian/proc/guardiancustomize() guardianrecolor() guardianrename() + customized = TRUE /mob/living/simple_animal/hostile/guardian/proc/guardianrecolor() guardiancolor = input(src,"What would you like your color to be?","Choose Your Color","#ffffff") as color|null @@ -270,10 +273,13 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians summoner.adjustCloneLoss(amount * 0.5) //dying hosts take 50% bonus damage as cloneloss update_health_hud() -/mob/living/simple_animal/hostile/guardian/ex_act(severity, target) +/mob/living/simple_animal/hostile/guardian/ex_act(severity, target, origin) switch(severity) if(1) - gib() + if(istype(origin, /datum/explosion)) + gib(was_explosion = origin) + else + gib() return if(2) adjustBruteLoss(60) @@ -283,10 +289,10 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians /mob/living/simple_animal/hostile/guardian/wave_ex_act(power, datum/wave_explosion/explosion, dir) adjustBruteLoss(EXPLOSION_POWER_STANDARD_SCALE_MOB_DAMAGE(power, explosion.mob_damage_mod * 0.33)) -/mob/living/simple_animal/hostile/guardian/gib() +/mob/living/simple_animal/hostile/guardian/gib(no_brain, no_organs, no_bodyparts, datum/explosion/was_explosion) if(summoner) to_chat(summoner, "Your [src] was blown up!") - summoner.gib() + summoner.gib(was_explosion = was_explosion) ghostize() qdel(src) diff --git a/code/modules/mob/living/simple_animal/guardian/types/assassin.dm b/code/modules/mob/living/simple_animal/guardian/types/assassin.dm index 7083f891b8..77d4fd1013 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/assassin.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/assassin.dm @@ -17,7 +17,7 @@ var/atom/movable/screen/alert/canstealthalert var/atom/movable/screen/alert/instealthalert -/mob/living/simple_animal/hostile/guardian/assassin/Initialize() +/mob/living/simple_animal/hostile/guardian/assassin/Initialize(mapload) . = ..() stealthcooldown = 0 diff --git a/code/modules/mob/living/simple_animal/guardian/types/charger.dm b/code/modules/mob/living/simple_animal/guardian/types/charger.dm index ee5a648067..9715d4f63c 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/charger.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/charger.dm @@ -14,7 +14,7 @@ var/charging = 0 var/atom/movable/screen/alert/chargealert -/mob/living/simple_animal/hostile/guardian/charger/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/guardian/charger/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(ranged_cooldown <= world.time) diff --git a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm index a079507a63..1fd1e623db 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm @@ -18,14 +18,14 @@ /mob/living/simple_animal/hostile/guardian/dextrous/examine(mob/user) if(dextrous) - . = list("*---------*\nThis is [icon2html(src)] \a [src]!\n[desc]") + . = list("This is [icon2html(src)] \a [src]!\n[desc]") for(var/obj/item/I in held_items) if(!(I.item_flags & ABSTRACT)) . += "It has [I.get_examine_string(user)] in its [get_held_index_name(get_held_index_of_item(I))]." if(internal_storage && !(internal_storage.item_flags & ABSTRACT)) . += "It is holding [internal_storage.get_examine_string(user)] in its internal storage." - . += "*---------*" + . += "" else return ..() @@ -52,7 +52,7 @@ /mob/living/simple_animal/hostile/guardian/dextrous/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, clothing_check = FALSE, list/return_warning) switch(slot) - if(SLOT_GENERC_DEXTROUS_STORAGE) + if(ITEM_SLOT_DEX_STORAGE) if(internal_storage) return 0 return 1 @@ -63,17 +63,17 @@ return switch(slot) - if(SLOT_GENERC_DEXTROUS_STORAGE) + if(ITEM_SLOT_DEX_STORAGE) internal_storage = I update_inv_internal_storage() else to_chat(src, "You are trying to equip this item to an unsupported inventory slot. Report this to a coder!") /mob/living/simple_animal/hostile/guardian/dextrous/getBackSlot() - return SLOT_GENERC_DEXTROUS_STORAGE + return ITEM_SLOT_DEX_STORAGE /mob/living/simple_animal/hostile/guardian/dextrous/getBeltSlot() - return SLOT_GENERC_DEXTROUS_STORAGE + return ITEM_SLOT_DEX_STORAGE /mob/living/simple_animal/hostile/guardian/dextrous/proc/update_inv_internal_storage() if(internal_storage && client && hud_used && hud_used.hud_shown) diff --git a/code/modules/mob/living/simple_animal/guardian/types/fire.dm b/code/modules/mob/living/simple_animal/guardian/types/fire.dm index a05cd517fb..68e05f3f8c 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/fire.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/fire.dm @@ -13,7 +13,7 @@ tech_fluff_string = "Boot sequence complete. Crowd control modules activated. Holoparasite swarm online." carp_fluff_string = "CARP CARP CARP! You caught one! OH GOD, EVERYTHING'S ON FIRE. Except you and the fish." -/mob/living/simple_animal/hostile/guardian/fire/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/guardian/fire/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(summoner) diff --git a/code/modules/mob/living/simple_animal/guardian/types/protector.dm b/code/modules/mob/living/simple_animal/guardian/types/protector.dm index b3d9f01ebb..00d56edd55 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/protector.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/protector.dm @@ -11,7 +11,7 @@ toggle_button_type = /atom/movable/screen/guardian/ToggleMode var/toggle = FALSE -/mob/living/simple_animal/hostile/guardian/protector/ex_act(severity) +/mob/living/simple_animal/hostile/guardian/protector/ex_act(severity, target, origin) if(severity == 1) adjustBruteLoss(400) //if in protector mode, will do 20 damage and not actually necessarily kill the summoner else diff --git a/code/modules/mob/living/simple_animal/guardian/types/support.dm b/code/modules/mob/living/simple_animal/guardian/types/support.dm index fc2912ec2f..78225a458c 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/support.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/support.dm @@ -15,7 +15,7 @@ var/beacon_cooldown = 0 var/toggle = FALSE -/mob/living/simple_animal/hostile/guardian/healer/Initialize() +/mob/living/simple_animal/hostile/guardian/healer/Initialize(mapload) . = ..() var/datum/atom_hud/medsensor = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] medsensor.add_hud_to(src) diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index 57ddbe6290..a620c9a58b 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -40,7 +40,7 @@ death_sound = 'sound/voice/hiss6.ogg' deathmessage = "lets out a waning guttural screech, green blood bubbling from its maw..." -/mob/living/simple_animal/hostile/alien/Initialize() +/mob/living/simple_animal/hostile/alien/Initialize(mapload) . = ..() AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW) @@ -86,7 +86,7 @@ melee_damage_upper = 20 del_on_death = TRUE loot = list(/obj/effect/mob_spawn/alien/corpse/humanoid/sentinel) - + /mob/living/simple_animal/hostile/alien/queen name = "alien queen" diff --git a/code/modules/mob/living/simple_animal/hostile/banana_spider.dm b/code/modules/mob/living/simple_animal/hostile/banana_spider.dm index a88593ed74..f8e8bf75d4 100644 --- a/code/modules/mob/living/simple_animal/hostile/banana_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/banana_spider.dm @@ -30,7 +30,7 @@ var/projectile_density = TRUE //griffons get shot del_on_death = TRUE -/mob/living/simple_animal/banana_spider/Initialize() +/mob/living/simple_animal/banana_spider/Initialize(mapload) . = ..() var/area/A = get_area(src) if(A) @@ -87,7 +87,7 @@ else visible_message("[src] avoids getting crushed.") -/mob/living/simple_animal/banana_spider/ex_act() +/mob/living/simple_animal/banana_spider/ex_act(severity, target, origin) return /mob/living/simple_animal/banana_spider/start_pulling() @@ -105,6 +105,6 @@ juice_results = list(/datum/reagent/consumable/banana = 0) -/obj/item/reagent_containers/food/snacks/deadbanana_spider/Initialize() +/obj/item/reagent_containers/food/snacks/deadbanana_spider/Initialize(mapload) . = ..() AddComponent(/datum/component/slippery, 20) diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index c7772f780d..adca93e70f 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -61,7 +61,7 @@ icon_living = "snowbear" icon_dead = "snowbear_dead" desc = "It's a polar bear, in space, but not actually in space." - weather_immunities = list("snow") + weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE) /mob/living/simple_animal/hostile/bear/russian name = "combat bear" @@ -129,7 +129,7 @@ attack_verb_continuous = "slaps" attack_verb_simple = "slap" -/mob/living/simple_animal/hostile/bear/butter/BiologicalLife(seconds, times_fired) //Heals butter bear really fast when he takes damage. +/mob/living/simple_animal/hostile/bear/butter/BiologicalLife(delta_time, times_fired) //Heals butter bear really fast when he takes damage. if(stat) return if(health < maxHealth) diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index 399a403ce7..1f0efddd8d 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -60,7 +60,7 @@ var/static/hydroponicstypecache = typecacheof(/obj/machinery/hydroponics) var/held_icon = "" // bees are small and have no held icon (aka the coder doesn't know how to sprite it) -/mob/living/simple_animal/hostile/poison/bees/Initialize() +/mob/living/simple_animal/hostile/poison/bees/Initialize(mapload) . = ..() generate_bee_visuals() AddComponent(/datum/component/swarming) @@ -211,7 +211,7 @@ beehome = BB break // End loop after the first compatible find. -/mob/living/simple_animal/hostile/poison/bees/toxin/Initialize() +/mob/living/simple_animal/hostile/poison/bees/toxin/Initialize(mapload) . = ..() var/datum/reagent/R = pick(typesof(/datum/reagent/toxin)) assign_reagent(GLOB.chemical_reagents_list[R]) @@ -289,7 +289,7 @@ ..() -/obj/item/queen_bee/bought/Initialize() +/obj/item/queen_bee/bought/Initialize(mapload) . = ..() queen = new(src) @@ -310,6 +310,6 @@ /mob/living/simple_animal/hostile/poison/bees/short desc = "These bees seem unstable and won't survive for long." -/mob/living/simple_animal/hostile/poison/bees/short/Initialize() +/mob/living/simple_animal/hostile/poison/bees/short/Initialize(mapload) . = ..() addtimer(CALLBACK(src, .proc/death), 50 SECONDS) diff --git a/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm b/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm index 1b0d210d9c..1dedf8cd29 100644 --- a/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm +++ b/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm @@ -13,7 +13,7 @@ var/point_regen_amount = 1 sentience_type = SENTIENCE_BOSS -/mob/living/simple_animal/hostile/boss/Initialize() +/mob/living/simple_animal/hostile/boss/Initialize(mapload) . = ..() atb = new() diff --git a/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm b/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm index fe00af9384..6db5250469 100644 --- a/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm +++ b/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm @@ -182,7 +182,7 @@ duration = 18 randomdir = FALSE -/obj/effect/temp_visual/paperwiz_dying/Initialize() +/obj/effect/temp_visual/paperwiz_dying/Initialize(mapload) . = ..() visible_message("The wizard cries out in pain as a gate appears behind him, sucking him in!") playsound(get_turf(src),'sound/magic/mandswap.ogg', 50, 1, 1) diff --git a/code/modules/mob/living/simple_animal/hostile/bread.dm b/code/modules/mob/living/simple_animal/hostile/bread.dm index 70c8b0c540..663b1fae72 100644 --- a/code/modules/mob/living/simple_animal/hostile/bread.dm +++ b/code/modules/mob/living/simple_animal/hostile/bread.dm @@ -32,7 +32,7 @@ verb_yell = "growls loudly" del_on_death = TRUE -/mob/living/simple_animal/bread/hostile/Initialize() +/mob/living/simple_animal/bread/hostile/Initialize(mapload) . = ..() var/area/A = get_area(src) if(A) @@ -62,7 +62,7 @@ user.transfer_ckey(src, FALSE) density = TRUE -/mob/living/simple_animal/hostile/bread/ex_act() +/mob/living/simple_animal/hostile/bread/ex_act(severity, target, origin) return /mob/living/simple_animal/hostile/bread/start_pulling() diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index 8388d6501a..7f7589dae4 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -46,7 +46,7 @@ if(regen_amount) regen_cooldown = world.time + REGENERATION_DELAY -/mob/living/simple_animal/hostile/carp/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/carp/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(regen_amount && regen_cooldown < world.time) @@ -85,7 +85,7 @@ melee_damage_lower = 20 melee_damage_upper = 20 -/mob/living/simple_animal/hostile/carp/megacarp/Initialize() +/mob/living/simple_animal/hostile/carp/megacarp/Initialize(mapload) . = ..() name = "[pick(GLOB.megacarp_first_names)] [pick(GLOB.megacarp_last_names)]" melee_damage_lower += rand(4, 10) @@ -95,20 +95,78 @@ /mob/living/simple_animal/hostile/carp/cayenne name = "Cayenne" + real_name = "Cayenne" desc = "A failed Syndicate experiment in weaponized space carp technology, it now serves as a lovable mascot." gender = FEMALE - regen_amount = 8 - speak_emote = list("squeaks") - maxHealth = 90 - health = 90 - gold_core_spawnable = NO_SPAWN - faction = list(ROLE_SYNDICATE, "carp") //They are still a carp AIStatus = AI_OFF + gold_core_spawnable = NO_SPAWN + faction = list(ROLE_SYNDICATE) + /// Keeping track of the nuke disk for the functionality of storing it. + var/obj/item/disk/nuclear/disky + /// Location of the file storing disk overlays + // var/icon/disk_overlay_file = 'icons/mob/carp.dmi' + /// Colored disk mouth appearance for adding it as a mouth overlay + var/mutable_appearance/colored_disk_mouth - harm_intent_damage = 12 - obj_damage = 70 - melee_damage_lower = 15 - melee_damage_upper = 18 +/mob/living/simple_animal/hostile/carp/cayenne/Initialize(mapload) + . = ..() + // AddElement(/datum/element/pet_bonus, "bloops happily!") + // colored_disk_mouth = mutable_appearance(SSgreyscale.GetColoredIconByType(/datum/greyscale_config/carp/disk_mouth, greyscale_colors), "disk_mouth") + ADD_TRAIT(src, TRAIT_DISK_VERIFIER, INNATE_TRAIT) //carp can verify disky + +/mob/living/simple_animal/hostile/carp/cayenne/IsAdvancedToolUser() + return TRUE //carp SMART + +/mob/living/simple_animal/hostile/carp/cayenne/death(gibbed) + if(disky) + disky.forceMove(drop_location()) + disky = null + return ..() + +/mob/living/simple_animal/hostile/carp/cayenne/Destroy(force) + QDEL_NULL(disky) + return ..() + +/mob/living/simple_animal/hostile/carp/cayenne/examine(mob/user) + . = ..() + if(disky) + . += span_notice("Wait... is that [disky] in [p_their()] mouth?") + +/mob/living/simple_animal/hostile/carp/cayenne/AttackingTarget(atom/attacked_target) + if(istype(attacked_target, /obj/item/disk/nuclear)) + var/obj/item/disk/nuclear/potential_disky = attacked_target + if(potential_disky.anchored) + return + potential_disky.forceMove(src) + disky = potential_disky + to_chat(src, span_nicegreen("YES!! You manage to pick up [disky]. (Click anywhere to place it back down.)")) + update_icon() + if(!disky.fake) + client.give_award(/datum/award/achievement/misc/cayenne_disk, src) + return + if(disky) + if(isopenturf(attacked_target)) + to_chat(src, span_notice("You place [disky] on [attacked_target]")) + disky.forceMove(attacked_target.drop_location()) + disky = null + update_icon() + else + disky.melee_attack_chain(src, attacked_target) + return + return ..() + +/mob/living/simple_animal/hostile/carp/cayenne/Exited(atom/movable/gone, direction) + . = ..() + if(disky == gone) + disky = null + update_icon() + +/mob/living/simple_animal/hostile/carp/cayenne/update_overlays() + . = ..() + if(!disky || stat == DEAD) + return + // . += colored_disk_mouth + // . += mutable_appearance(disk_overlay_file, "disk_overlay") #undef REGENERATION_DELAY diff --git a/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm b/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm index 9b50587b3d..dfecee745b 100644 --- a/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm +++ b/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm @@ -26,7 +26,7 @@ gold_core_spawnable = HOSTILE_SPAWN faction = list(ROLE_WIZARD) footstep_type = FOOTSTEP_MOB_SHOE - weather_immunities = list("lava","ash") + weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE) minbodytemp = 0 maxbodytemp = INFINITY atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) @@ -37,4 +37,4 @@ icon_state = "declone" damage = 4 damage_type = BURN - flag = "energy" + flag = ENERGY diff --git a/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm b/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm index b6d5db7d6d..d52da8f095 100644 --- a/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm +++ b/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm @@ -49,7 +49,7 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0) hud_possible = list(ANTAG_HUD) -/mob/living/simple_animal/hostile/floor_cluwne/Initialize() +/mob/living/simple_animal/hostile/floor_cluwne/Initialize(mapload) . = ..() access_card = new /obj/item/card/id(src) var/datum/job/captain/C = new /datum/job/captain @@ -431,7 +431,7 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0) duration = 600 randomdir = FALSE -/obj/effect/temp_visual/fcluwne_manifest/Initialize() +/obj/effect/temp_visual/fcluwne_manifest/Initialize(mapload) . = ..() playsound(src, 'sound/misc/floor_cluwne_emerge.ogg', 100, 1) flick("fcluwne_manifest",src) @@ -440,7 +440,7 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0) name = "floor cluwne" desc = "If you have this, tell a coder or admin!" -/obj/effect/dummy/floorcluwne_orbit/Initialize() +/obj/effect/dummy/floorcluwne_orbit/Initialize(mapload) . = ..() GLOB.floor_cluwnes++ name += " ([GLOB.floor_cluwnes])" diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index 2349685a4e..23a0d44d56 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -57,7 +57,7 @@ var/datum/action/innate/spider/lay_web/lay_web var/directive = "" //Message passed down to children, to relay the creator's orders -/mob/living/simple_animal/hostile/poison/giant_spider/Initialize() +/mob/living/simple_animal/hostile/poison/giant_spider/Initialize(mapload) . = ..() lay_web = new lay_web.Grant(src) @@ -122,7 +122,7 @@ var/datum/action/innate/spider/set_directive/set_directive var/static/list/consumed_mobs = list() //the tags of mobs that have been consumed by nurse spiders to lay eggs -/mob/living/simple_animal/hostile/poison/giant_spider/nurse/Initialize() +/mob/living/simple_animal/hostile/poison/giant_spider/nurse/Initialize(mapload) . = ..() wrap = new AddAbility(wrap) @@ -208,7 +208,7 @@ var/datum/action/innate/spider/comm/letmetalkpls gold_core_spawnable = NO_SPAWN -/mob/living/simple_animal/hostile/poison/giant_spider/nurse/midwife/Initialize() +/mob/living/simple_animal/hostile/poison/giant_spider/nurse/midwife/Initialize(mapload) . = ..() letmetalkpls = new letmetalkpls.Grant(src) @@ -396,7 +396,7 @@ action_icon_state = "wrap_0" action_background_icon_state = "bg_alien" -/obj/effect/proc_holder/wrap/Initialize() +/obj/effect/proc_holder/wrap/Initialize(mapload) . = ..() action = new(src) diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index 5e34d17bb2..e5cf1cc989 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -24,7 +24,7 @@ var/egg_lain = 0 gold_core_spawnable = NO_SPAWN //are you sure about this?? // CITADEL CHANGE, Yes. -/mob/living/simple_animal/hostile/headcrab/Initialize() +/mob/living/simple_animal/hostile/headcrab/Initialize(mapload) . = ..() AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) @@ -83,9 +83,9 @@ if(C.can_absorb_dna(owner)) C.add_new_profile(owner) - var/obj/effect/proc_holder/changeling/humanform/hf = new + var/datum/action/changeling/humanform/hf = new C.purchasedpowers += hf - hf.on_purchase(origin.current, TRUE) + C.regain_powers() M.key = origin.key owner.gib() diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index b627bf67c2..b02919446b 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -33,7 +33,7 @@ footstep_type = FOOTSTEP_MOB_CLAW -/mob/living/simple_animal/hostile/hivebot/Initialize() +/mob/living/simple_animal/hostile/hivebot/Initialize(mapload) . = ..() deathmessage = "[src] blows apart!" diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 01a30bb90a..89f27f067e 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -65,7 +65,7 @@ ///Declares a cooldown for potential charges right off the bat. COOLDOWN_DECLARE(charge_cooldown) -/mob/living/simple_animal/hostile/Initialize() +/mob/living/simple_animal/hostile/Initialize(mapload) . = ..() if(!targets_from) @@ -79,7 +79,7 @@ foes = null return ..() -/mob/living/simple_animal/hostile/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/BiologicalLife(delta_time, times_fired) if(!(. = ..())) walk(src, 0) //stops walking return @@ -146,7 +146,7 @@ if(!search_objects) . = hearers(vision_range, targets_from) - src //Remove self, so we don't suicide - var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden,/obj/item/electronic_assembly)) + var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/vehicle/sealed/mecha, /obj/structure/destructible/clockwork/ocular_warden,/obj/item/electronic_assembly)) for(var/HM in typecache_filter_list(range(vision_range, targets_from), hostile_machines)) if(can_see(targets_from, HM, vision_range)) @@ -236,9 +236,9 @@ return TRUE if(ismecha(the_target)) - var/obj/mecha/M = the_target - if(M.occupant)//Just so we don't attack empty mechs - if(CanAttack(M.occupant)) + var/obj/vehicle/sealed/mecha/M = the_target + for(var/occupant in M.occupants) + if(CanAttack(occupant)) return TRUE if(istype(the_target, /obj/machinery/porta_turret)) @@ -367,7 +367,7 @@ if(vore_active) if(isliving(target)) var/mob/living/L = target - if(!client && L.Adjacent(src) && CHECK_BITFIELD(L.vore_flags, DEVOURABLE) && CHECK_BITFIELD(L.vore_flags, MOBVORE)) // aggressive check to ensure vore attacks can be made + if(!client && L.Adjacent(src) && (L.vore_flags & DEVOURABLE) && (L.vore_flags & MOBVORE)) // aggressive check to ensure vore attacks can be made if(prob(voracious_chance)) vore_attack(src,L,src) else @@ -604,7 +604,7 @@ toggle_ai(AI_ON) /mob/living/simple_animal/hostile/proc/ListTargetsLazy(var/_Z)//Step 1, find out what we can see - var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden)) + var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/vehicle/sealed/mecha, /obj/structure/destructible/clockwork/ocular_warden)) . = list() for (var/I in SSmobs.clients_by_zlevel[_Z]) var/mob/M = I diff --git a/code/modules/mob/living/simple_animal/hostile/illusion.dm b/code/modules/mob/living/simple_animal/hostile/illusion.dm index f561f0d43c..edefa028f9 100644 --- a/code/modules/mob/living/simple_animal/hostile/illusion.dm +++ b/code/modules/mob/living/simple_animal/hostile/illusion.dm @@ -23,7 +23,7 @@ deathmessage = "vanishes into thin air! It was a fake!" has_field_of_vision = FALSE //not meant to be played anyway. -/mob/living/simple_animal/hostile/illusion/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/illusion/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(world.time > life_span) diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm index b98ee5adfb..f3676e752a 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm @@ -60,7 +60,7 @@ layer = ABOVE_ALL_MOB_LAYER duration = 3 -/obj/effect/temp_visual/leaper_projectile_impact/Initialize() +/obj/effect/temp_visual/leaper_projectile_impact/Initialize(mapload) . = ..() new /obj/effect/decal/cleanable/leaper_sludge(get_turf(src)) @@ -78,7 +78,7 @@ max_integrity = 10 density = FALSE -/obj/structure/leaper_bubble/Initialize() +/obj/structure/leaper_bubble/Initialize(mapload) . = ..() INVOKE_ASYNC(src, /atom/movable.proc/float, TRUE) QDEL_IN(src, 100) @@ -126,7 +126,7 @@ pixel_y = -32 duration = 30 -/mob/living/simple_animal/hostile/jungle/leaper/Initialize() +/mob/living/simple_animal/hostile/jungle/leaper/Initialize(mapload) . = ..() remove_verb(src, /mob/living/verb/pulled) @@ -165,7 +165,7 @@ if(!hopping) Hop() -/mob/living/simple_animal/hostile/jungle/leaper/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/jungle/leaper/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return update_icons() diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm b/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm index 31303bd7f1..1e0116f52c 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm @@ -26,7 +26,7 @@ footstep_type = FOOTSTEP_MOB_CLAW -/mob/living/simple_animal/hostile/jungle/mega_arachnid/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/jungle/mega_arachnid/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(target && ranged_cooldown > world.time && iscarbon(target)) diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm b/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm index 2d964f5721..baa0fe4649 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm @@ -33,12 +33,12 @@ footstep_type = FOOTSTEP_MOB_BAREFOOT -/mob/living/simple_animal/hostile/jungle/mook/CanPass(atom/movable/O) +/mob/living/simple_animal/hostile/jungle/mook/CanAllowThrough(atom/movable/O) + . = ..() if(istype(O, /mob/living/simple_animal/hostile/jungle/mook)) var/mob/living/simple_animal/hostile/jungle/mook/M = O if(M.attack_state == MOOK_ATTACK_ACTIVE && M.throwing) return TRUE - return ..() /mob/living/simple_animal/hostile/jungle/mook/death() desc = "A deceased primitive. Upon closer inspection, it was suffering from severe cellular degeneration and its garments are machine made..."//Can you guess the twist diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm index 0f25688b6a..2d773c67bb 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm @@ -42,7 +42,7 @@ damage = 10 damage_type = BURN light_range = 2 - flag = "energy" + flag = ENERGY light_color = LIGHT_COLOR_YELLOW hitsound = 'sound/weapons/sear.ogg' hitsound_wall = 'sound/weapons/effects/searwall.ogg' diff --git a/code/modules/mob/living/simple_animal/hostile/killertomato.dm b/code/modules/mob/living/simple_animal/hostile/killertomato.dm index d3d3dadd1e..1d23e04b2d 100644 --- a/code/modules/mob/living/simple_animal/hostile/killertomato.dm +++ b/code/modules/mob/living/simple_animal/hostile/killertomato.dm @@ -29,6 +29,6 @@ maxbodytemp = 500 gold_core_spawnable = HOSTILE_SPAWN -/mob/living/simple_animal/hostile/killertomato/Initialize() +/mob/living/simple_animal/hostile/killertomato/Initialize(mapload) . = ..() AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) diff --git a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm index f2dc6abe40..0f6c10d817 100644 --- a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm +++ b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm @@ -25,14 +25,14 @@ search_objects = 0 mob_biotypes = MOB_ORGANIC|MOB_HUMANOID - var/spawn_mecha_type = /obj/mecha/combat/marauder/mauler/loaded - var/obj/mecha/mecha //Ref to pilot's mecha instance + var/spawn_mecha_type = /obj/vehicle/sealed/mecha/combat/marauder/mauler/loaded + var/obj/vehicle/sealed/mecha/mecha //Ref to pilot's mecha instance var/required_mecha_charge = 7500 //If the pilot doesn't have a mecha, what charge does a potential Grand Theft Mecha need? (Defaults to half a battery) var/mecha_charge_evacuate = 50 //Amount of charge at which the pilot tries to abandon the mecha //Vars that control when the pilot uses their mecha's abilities (if the mecha has that ability) var/threat_use_mecha_smoke = 5 //5 mobs is enough to engage crowd control - var/defence_mode_chance = 35 //Chance to engage Defence mode when damaged + var/defense_mode_chance = 35 //Chance to engage Defense mode when damaged var/smoke_chance = 20 //Chance to deploy smoke for crowd control var/retreat_chance = 40 //Chance to run away @@ -40,35 +40,35 @@ spawn_mecha_type = null search_objects = 2 -/mob/living/simple_animal/hostile/syndicate/mecha_pilot/no_mech/Initialize() +/mob/living/simple_animal/hostile/syndicate/mecha_pilot/no_mech/Initialize(mapload) . = ..() - wanted_objects = typecacheof(/obj/mecha/combat, TRUE) + wanted_objects = typecacheof(/obj/vehicle/sealed/mecha/combat, TRUE) /mob/living/simple_animal/hostile/syndicate/mecha_pilot/nanotrasen //nanotrasen are syndies! no it's just a weird path. - name = "Nanotrasen Mecha Pilot" + name = "\improper Nanotrasen Mecha Pilot" desc = "Death to the Syndicate. This variant comes in MECHA DEATH flavour." icon_living = "nanotrasen" icon_state = "nanotrasen" faction = list("nanotrasen") - spawn_mecha_type = /obj/mecha/combat/marauder/loaded + spawn_mecha_type = /obj/vehicle/sealed/mecha/combat/marauder/loaded /mob/living/simple_animal/hostile/syndicate/mecha_pilot/no_mech/nanotrasen - name = "Nanotrasen Mecha Pilot" + name = "\improper Nanotrasen Mecha Pilot" desc = "Death to the Syndicate. This variant comes in MECHA DEATH flavour." icon_living = "nanotrasen" icon_state = "nanotrasen" faction = list("nanotrasen") -/mob/living/simple_animal/hostile/syndicate/mecha_pilot/Initialize() +/mob/living/simple_animal/hostile/syndicate/mecha_pilot/Initialize(mapload) . = ..() if(spawn_mecha_type) - var/obj/mecha/M = new spawn_mecha_type (get_turf(src)) + var/obj/vehicle/sealed/mecha/M = new spawn_mecha_type (get_turf(src)) if(istype(M)) - enter_mecha(M) + INVOKE_ASYNC(src, .proc/enter_mecha, M) -/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/enter_mecha(obj/mecha/M) +/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/enter_mecha(obj/vehicle/sealed/mecha/M) if(!M) return 0 target = null //Target was our mecha, so null it out @@ -78,7 +78,7 @@ var/do_ranged = 0 for(var/equip in mecha.equipment) var/obj/item/mecha_parts/mecha_equipment/ME = equip - if(ME.range & RANGED) + if(ME.range & MECHA_RANGED) do_ranged = 1 break if(do_ranged) @@ -89,11 +89,11 @@ ranged = 0 wanted_objects = list() search_objects = 0 - if(mecha && mecha.lights_action) //an AI mecha is an EVIL EVIL thing, so let's not hide them in the dark - mecha.lights_action.Activate() + if(LAZYACCESSASSOC(mecha.occupant_actions, src, /datum/action/vehicle/sealed/mecha/mech_defense_mode) && !mecha.defense_mode) + var/datum/action/action = mecha.occupant_actions[src][/datum/action/vehicle/sealed/mecha/mech_defense_mode] + action.Trigger(TRUE) - -/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/exit_mecha(obj/mecha/M) +/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/exit_mecha(obj/vehicle/sealed/mecha/M) if(!M) return 0 @@ -102,9 +102,9 @@ targets_from = src //Find a new mecha - wanted_objects = typecacheof(/obj/mecha/combat, TRUE) + wanted_objects = typecacheof(/obj/vehicle/sealed/mecha/combat, TRUE) var/search_aggressiveness = 2 - for(var/obj/mecha/combat/C in range(vision_range,src)) + for(var/obj/vehicle/sealed/mecha/combat/C in range(vision_range,src)) if(is_valid_mecha(C)) target = C search_aggressiveness = 3 //We can see a mech? RUN FOR IT, IGNORE MOBS! @@ -116,23 +116,23 @@ walk(M,0)//end any lingering movement loops, to prevent the haunted mecha bug //Checks if a mecha is valid for theft -/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/is_valid_mecha(obj/mecha/M) +/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/is_valid_mecha(obj/vehicle/sealed/mecha/M) if(!M) - return 0 - if(M.occupant) - return 0 + return FALSE + if(LAZYLEN(M.occupants)) + return FALSE if(!M.has_charge(required_mecha_charge)) - return 0 + return FALSE if(M.obj_integrity < M.max_integrity*0.5) - return 0 - return 1 + return FALSE + return TRUE /mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/mecha_face_target(atom/A) if(mecha) var/dirto = get_dir(mecha,A) if(mecha.dir != dirto) //checking, because otherwise the mecha makes too many turn noises - mecha.mechturn(dirto) + mecha.vehicle_move(dirto, TRUE) @@ -144,7 +144,7 @@ ME.rearm() -/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/get_mecha_equip_by_flag(flag = RANGED) +/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/get_mecha_equip_by_flag(flag = MECHA_RANGED) . = list() if(mecha) for(var/equip in mecha.equipment) @@ -160,11 +160,10 @@ if(mecha) mecha_reload() mecha_face_target(A) - var/list/possible_weapons = get_mecha_equip_by_flag(RANGED) + var/list/possible_weapons = get_mecha_equip_by_flag(MECHA_RANGED) if(possible_weapons.len) var/obj/item/mecha_parts/mecha_equipment/ME = pick(possible_weapons) //so we don't favor mecha.equipment[1] forever - if(ME.action(A)) - ME.start_cooldown() + if(ME.action(src,A)) return else @@ -173,20 +172,19 @@ /mob/living/simple_animal/hostile/syndicate/mecha_pilot/AttackingTarget() if(mecha) - var/list/possible_weapons = get_mecha_equip_by_flag(MELEE) + var/list/possible_weapons = get_mecha_equip_by_flag(MECHA_MELEE) if(possible_weapons.len) var/obj/item/mecha_parts/mecha_equipment/ME = pick(possible_weapons) mecha_face_target(target) - if(ME.action(target)) - ME.start_cooldown() + if(ME.action(src,target)) return - if(mecha.melee_can_hit) + if(!TIMER_COOLDOWN_CHECK(mecha, COOLDOWN_MECHA_MELEE_ATTACK)) mecha_face_target(target) - target.mech_melee_attack(mecha) + target.mech_melee_attack(mecha, src) else if(ismecha(target)) - var/obj/mecha/M = target + var/obj/vehicle/sealed/mecha/M = target if(is_valid_mecha(M)) enter_mecha(M) return @@ -199,50 +197,54 @@ /mob/living/simple_animal/hostile/syndicate/mecha_pilot/handle_automated_action() - if(..()) - if(!mecha) - for(var/obj/mecha/combat/C in range(src,vision_range)) - if(is_valid_mecha(C)) - target = C //Let's nab it! - minimum_distance = 1 - ranged = 0 - break - if(mecha) - var/list/L = PossibleThreats() - var/threat_count = L.len + . = ..() + if(!.) + return + if(!mecha) + for(var/obj/vehicle/sealed/mecha/combat/mecha_in_range in range(src,vision_range)) + if(is_valid_mecha(mecha_in_range)) + target = mecha_in_range //Let's nab it! + minimum_distance = 1 + ranged = 0 + break + if(mecha) + var/list/L = PossibleThreats() + var/threat_count = L.len - //Low Charge - Eject - if(!mecha.has_charge(mecha_charge_evacuate)) - exit_mecha(mecha) - return + //Low Charge - Eject + if(!mecha.has_charge(mecha_charge_evacuate)) + exit_mecha(mecha) + return //Too Much Damage - Eject - if(mecha.obj_integrity < mecha.max_integrity*0.1) - exit_mecha(mecha) - return + if(mecha.obj_integrity < mecha.max_integrity*0.1) + exit_mecha(mecha) + return - //Smoke if there's too many targets - Smoke Power - if(threat_count >= threat_use_mecha_smoke && prob(smoke_chance)) - if(mecha.smoke_action && mecha.smoke_action.owner && mecha.smoke) - mecha.smoke_action.Activate() + //Smoke if there's too many targets - Smoke Power + if(threat_count >= threat_use_mecha_smoke && prob(smoke_chance)) + if(LAZYACCESSASSOC(mecha.occupant_actions, src, /datum/action/vehicle/sealed/mecha/mech_smoke) && !mecha.smoke_charges) + var/datum/action/action = mecha.occupant_actions[src][/datum/action/vehicle/sealed/mecha/mech_smoke] + action.Trigger() - //Heavy damage - Defence Power or Retreat - if(mecha.obj_integrity < mecha.max_integrity*0.25) - if(prob(defence_mode_chance)) - if(mecha.defense_action && mecha.defense_action.owner && !mecha.defence_mode) - mecha.leg_overload_mode = 0 - mecha.defense_action.Activate(TRUE) - addtimer(CALLBACK(mecha.defense_action, /datum/action/innate/mecha/mech_defence_mode.proc/Activate, FALSE), 100) //10 seconds of defence, then toggle off + //Heavy damage - Defense Power or Retreat + if(mecha.obj_integrity < mecha.max_integrity*0.25) + if(prob(defense_mode_chance)) + if(LAZYACCESSASSOC(mecha.occupant_actions, src, /datum/action/vehicle/sealed/mecha/mech_defense_mode) && !mecha.defense_mode) + var/datum/action/action = mecha.occupant_actions[src][/datum/action/vehicle/sealed/mecha/mech_defense_mode] + action.Trigger(TRUE) + addtimer(CALLBACK(action, /datum/action/vehicle/sealed/mecha/mech_defense_mode.proc/Trigger, FALSE), 100) //10 seconds of defense, then toggle off - else if(prob(retreat_chance)) - //Speed boost if possible - if(mecha.overload_action && mecha.overload_action.owner && !mecha.leg_overload_mode) - mecha.overload_action.Activate(TRUE) - addtimer(CALLBACK(mecha.overload_action, /datum/action/innate/mecha/mech_defence_mode.proc/Activate, FALSE), 100) //10 seconds of speeeeed, then toggle off + else if(prob(retreat_chance)) + //Speed boost if possible + if(LAZYACCESSASSOC(mecha.occupant_actions, src, /datum/action/vehicle/sealed/mecha/mech_overload_mode) && !mecha.leg_overload_mode) + var/datum/action/action = mecha.occupant_actions[src][/datum/action/vehicle/sealed/mecha/mech_overload_mode] + mecha.leg_overload_mode = FALSE + action.Trigger(TRUE) + addtimer(CALLBACK(action, /datum/action/vehicle/sealed/mecha/mech_overload_mode.proc/Trigger, FALSE), 100) //10 seconds of speeeeed, then toggle off - retreat_distance = 50 - spawn(100) - retreat_distance = 0 + retreat_distance = 50 + addtimer(VARSET_CALLBACK(src, retreat_distance, 0), 10 SECONDS) @@ -261,17 +263,17 @@ //~simple animals~ /mob/living/simple_animal/hostile/syndicate/mecha_pilot/CanAttack(atom/the_target) if(ismecha(the_target)) - var/obj/mecha/M = the_target + var/obj/vehicle/sealed/mecha/M = the_target if(mecha) - if(M == mecha || !CanAttack(M.occupant)) - return 0 + if(M == mecha) //Dont kill yourself + return FALSE else //we're not in a mecha, so we check if we can steal it instead. if(is_valid_mecha(M)) - return 1 - else if (M.occupant && CanAttack(M.occupant)) - return 1 - else - return 0 + return TRUE + for(var/occupant in M.occupants) + if(CanAttack(occupant)) + return TRUE + return FALSE . = ..() @@ -290,6 +292,6 @@ /mob/living/simple_animal/hostile/syndicate/mecha_pilot/Goto(target, delay, minimum_distance) if(mecha) - walk_to(mecha, target, minimum_distance, mecha.step_in) + walk_to(mecha, target, minimum_distance, mecha.movedelay) else ..() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm index e6c5e7c22b..3369588915 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm @@ -1,11 +1,8 @@ #define MINER_DASH_RANGE 4 /* - BLOOD-DRUNK MINER - Effectively a highly aggressive miner, the blood-drunk miner has very few attacks but compensates by being highly aggressive. - The blood-drunk miner's attacks are as follows - If not in KA range, it will rapidly dash at its target - If in KA range, it will fire its kinetic accelerator @@ -13,11 +10,8 @@ The blood-drunk miner's attacks are as follows - After any of these attacks, may transform its cleaving saw: Untransformed, it attacks very rapidly for smaller amounts of damage Transformed, it attacks at normal speed for higher damage and cleaves enemies hit - When the blood-drunk miner dies, it leaves behind the cleaving saw it was using and its kinetic accelerator. - Difficulty: Medium - */ /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner @@ -37,7 +31,7 @@ Difficulty: Medium move_to_delay = 2 projectiletype = /obj/item/projectile/kinetic/miner projectilesound = 'sound/weapons/kenetic_accel.ogg' - ranged = 1 + ranged = TRUE ranged_cooldown_time = 16 pixel_x = -16 crusher_loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator/premiumka, /obj/item/crusher_trophy/miner_eye, /obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe, @@ -55,18 +49,57 @@ Difficulty: Medium var/dashing = FALSE var/dash_cooldown = 15 var/guidance = FALSE + var/transform_stop_attack = FALSE // stops the blood drunk miner from attacking after transforming his weapon until the next attack chain deathmessage = "falls to the ground, decaying into glowing particles." - death_sound = "bodyfall" - + deathsound = "bodyfall" footstep_type = FOOTSTEP_MOB_HEAVY + attack_action_types = list(/datum/action/innate/megafauna_attack/dash, + /datum/action/innate/megafauna_attack/kinetic_accelerator, + /datum/action/innate/megafauna_attack/transform_weapon) -/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/guidance - guidance = TRUE - -/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/hunter/AttackingTarget() +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/Initialize(mapload) . = ..() - if(. && prob(12)) - INVOKE_ASYNC(src, .proc/dash) + internal = new/obj/item/gps/internal/miner(src) + miner_saw = new(src) + +/datum/action/innate/megafauna_attack/dash + name = "Dash To Target" + icon_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "sniper_zoom" + chosen_message = "You are now dashing to your target." + chosen_attack_num = 1 + +/datum/action/innate/megafauna_attack/kinetic_accelerator + name = "Fire Kinetic Accelerator" + icon_icon = 'icons/obj/guns/energy.dmi' + button_icon_state = "kineticgun" + chosen_message = "You are now shooting your kinetic accelerator." + chosen_attack_num = 2 + +/datum/action/innate/megafauna_attack/transform_weapon + name = "Transform Weapon" + icon_icon = 'icons/obj/lavaland/artefacts.dmi' + button_icon_state = "cleaving_saw" + chosen_message = "You are now transforming your weapon." + chosen_attack_num = 3 + +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/OpenFire() + if(client) + switch(chosen_attack) + if(1) + dash(target) + if(2) + shoot_ka() + if(3) + transform_weapon() + return + + Goto(target, move_to_delay, minimum_distance) + if(get_dist(src, target) > MINER_DASH_RANGE && dash_cooldown <= world.time) + dash_attack() + else + shoot_ka() + transform_weapon() /obj/item/melee/transforming/cleaving_saw/miner //nerfed saw because it is very murdery force = 6 @@ -74,7 +107,7 @@ Difficulty: Medium /obj/item/melee/transforming/cleaving_saw/miner/attack(mob/living/target, mob/living/carbon/human/user) target.add_stun_absorption("miner", 10, INFINITY) - . = ..() + ..() target.stun_absorption -= "miner" /obj/item/projectile/kinetic/miner @@ -83,38 +116,35 @@ Difficulty: Medium icon_state = "ka_tracer" range = MINER_DASH_RANGE -/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/Initialize() - . = ..() - internal = new/obj/item/gps/internal/miner(src) - miner_saw = new(src) - /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/adjustHealth(amount, updating_health = TRUE, forced = FALSE) var/adjustment_amount = amount * 0.1 if(world.time + adjustment_amount > next_action) - DelayNextAction(adjustment_amount, considered_action = FALSE, flush = TRUE) //attacking it interrupts it attacking, but only briefly + DelayNextAction(adjustment_amount) //attacking it interrupts it attacking, but only briefly . = ..() /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/death() - if(health > 0) - return - new /obj/effect/temp_visual/dir_setting/miner_death(loc, dir) - return ..() + . = ..() + if(.) + new /obj/effect/temp_visual/dir_setting/miner_death(loc, dir) /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/Move(atom/newloc) if(dashing || (newloc && newloc.z == z && (islava(newloc) || ischasm(newloc)))) //we're not stupid! return FALSE return ..() -/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/ex_act(severity, target) +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/ex_act(severity, target, origin) if(dash()) return return ..() +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/MeleeAction(patience = TRUE) + transform_stop_attack = FALSE + return ..() + /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/AttackingTarget() - if(QDELETED(target)) - return - if(!CheckActionCooldown() || !Adjacent(target)) //some cheating - INVOKE_ASYNC(src, .proc/quick_attack_loop) + if(client) + transform_stop_attack = FALSE + if(QDELETED(target) || transform_stop_attack) return face_atom(target) if(isliving(target)) @@ -129,12 +159,10 @@ Difficulty: Medium adjustHealth(-(L.maxHealth * 0.5)) L.gib() return TRUE - miner_saw.melee_attack_chain(src, target, null, ATTACK_IGNORE_CLICKDELAY) - FlushCurrentAction() + DelayNextAction(CLICK_CD_MELEE) + miner_saw.melee_attack_chain(src, target) if(guidance) adjustHealth(-2) - transform_weapon() - INVOKE_ASYNC(src, .proc/quick_attack_loop) return TRUE /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) @@ -147,16 +175,10 @@ Difficulty: Medium . = ..() if(. && target && !targets_the_same) wander = TRUE - transform_weapon() - INVOKE_ASYNC(src, .proc/quick_attack_loop) -/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/OpenFire() - Goto(target, move_to_delay, minimum_distance) - if(get_dist(src, target) > MINER_DASH_RANGE && dash_cooldown <= world.time) - INVOKE_ASYNC(src, .proc/dash, target) - else - shoot_ka() - transform_weapon() +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/dash_attack() + INVOKE_ASYNC(src, .proc/dash, target) + shoot_ka() /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/shoot_ka() if(ranged_cooldown <= world.time && get_dist(src, target) <= MINER_DASH_RANGE && !Adjacent(target)) @@ -165,22 +187,7 @@ Difficulty: Medium face_atom(target) new /obj/effect/temp_visual/dir_setting/firing_effect(loc, dir) Shoot(target) - DelayNextAction(CLICK_CD_RANGE, flush = TRUE) - -//I'm still of the belief that this entire proc needs to be wiped from existence. -// do not take my touching of it to be endorsement of it. ~mso -/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/quick_attack_loop() - while(!QDELETED(target) && !CheckActionCooldown()) //this is done this way because next_move can change to be sooner while we sleep. - stoplag(1) - sleep((next_action - world.time) * 1.5) //but don't ask me what the fuck this is about - if(QDELETED(target)) - return - if(dashing || !CheckActionCooldown() || !Adjacent(target)) - if(dashing && next_action <= world.time) - SetNextAction(1, considered_action = FALSE, immediate = FALSE, flush = TRUE) - INVOKE_ASYNC(src, .proc/quick_attack_loop) //lets try that again. - return - AttackingTarget() + DelayNextAction(CLICK_CD_RANGE) /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/dash(atom/dash_target) if(world.time < dash_cooldown) @@ -225,19 +232,23 @@ Difficulty: Medium dashing = TRUE alpha = 0 animate(src, alpha = 255, time = 5) - sleep(2) + SLEEP_CHECK_DEATH(2) D.forceMove(step_forward_turf) forceMove(target_turf) playsound(target_turf, 'sound/weapons/punchmiss.ogg', 40, 1, -1) - sleep(1) + SLEEP_CHECK_DEATH(1) dashing = FALSE - shoot_ka() return TRUE /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/transform_weapon() if(time_until_next_transform <= world.time) miner_saw.transform_cooldown = 0 miner_saw.transform_weapon(src, TRUE) + if(!miner_saw.active) + rapid_melee = 5 // 4 deci cooldown before changes, npcpool subsystem wait is 20, 20/4 = 5 + else + rapid_melee = 3 // same thing but halved (slightly rounded up) + transform_stop_attack = TRUE icon_state = "miner[miner_saw.active ? "_transformed":""]" icon_living = "miner[miner_saw.active ? "_transformed":""]" time_until_next_transform = world.time + rand(50, 100) @@ -269,6 +280,14 @@ Difficulty: Medium desc = "The sweet blood, oh, it sings to me." invisibility = 100 +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/guidance + guidance = TRUE + +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/hunter/AttackingTarget() + . = ..() + if(. && prob(12)) + INVOKE_ASYNC(src, .proc/dash) + /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/doom name = "hostile-environment miner" desc = "A miner destined to hop across dimensions for all eternity, hunting anomalous creatures." @@ -277,4 +296,5 @@ Difficulty: Medium ranged_cooldown_time = 8 dash_cooldown = 8 + #undef MINER_DASH_RANGE diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index b80e6cc72f..def5dc8c76 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -49,6 +49,8 @@ Difficulty: Hard melee_queue_distance = 20 // as far as possible really, need this because of blood warp ranged = 1 pixel_x = -32 + maptext_height = 96 + maptext_width = 96 gender = MALE del_on_death = 1 crusher_loot = list(/obj/structure/closet/crate/necropolis/bubblegum/crusher) @@ -120,7 +122,7 @@ Difficulty: Hard SetRecoveryTime(10) -/mob/living/simple_animal/hostile/megafauna/bubblegum/Initialize() +/mob/living/simple_animal/hostile/megafauna/bubblegum/Initialize(mapload) . = ..() if(istype(src, /mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination)) return @@ -154,16 +156,16 @@ Difficulty: Hard return 0 return ..() -/mob/living/simple_animal/hostile/megafauna/bubblegum/ex_act(severity, target) +/mob/living/simple_animal/hostile/megafauna/bubblegum/ex_act(severity, target, origin) if(severity >= EXPLODE_LIGHT) return severity = EXPLODE_LIGHT // puny mortals return ..() -/mob/living/simple_animal/hostile/megafauna/bubblegum/CanPass(atom/movable/mover, turf/target) +/mob/living/simple_animal/hostile/megafauna/bubblegum/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination)) - return 1 - return ..() + return TRUE /mob/living/simple_animal/hostile/megafauna/bubblegum/Goto(target, delay, minimum_distance) if(!charging) @@ -299,7 +301,7 @@ Difficulty: Hard to_chat(L, "[src] rends you!") playsound(T, attack_sound, 100, 1, -1) var/limb_to_hit = L.get_bodypart(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)) - L.apply_damage(10, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, "melee", null, null, armour_penetration)) + L.apply_damage(10, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, MELEE, null, null, armour_penetration)) sleep(3) /mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodgrab(turf/T, handedness) @@ -454,7 +456,7 @@ Difficulty: Hard deathmessage = "Explodes into a pool of blood!" deathsound = 'sound/effects/splat.ogg' -/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/Initialize() +/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/Initialize(mapload) ..() toggle_ai(AI_OFF) @@ -466,10 +468,10 @@ Difficulty: Hard new /obj/effect/decal/cleanable/blood(get_turf(src)) . = ..() -/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/CanPass(atom/movable/mover, turf/target) +/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum)) // hallucinations should not be stopping bubblegum or eachother - return 1 - return ..() + return TRUE /mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/Life() return diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 5751512b19..9e8497f968 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -44,6 +44,8 @@ Difficulty: Very Hard move_to_delay = 10 ranged = 1 pixel_x = -32 + maptext_height = 96 + maptext_width = 96 del_on_death = TRUE achievement_type = /datum/award/achievement/boss/colossus_kill crusher_achievement_type = /datum/award/achievement/boss/colossus_crusher @@ -94,7 +96,7 @@ Difficulty: Very Hard INVOKE_ASYNC(src, .proc/alternating_dir_shots) -/mob/living/simple_animal/hostile/megafauna/colossus/Initialize() +/mob/living/simple_animal/hostile/megafauna/colossus/Initialize(mapload) . = ..() internal = new/obj/item/gps/internal/colossus(src) @@ -262,7 +264,7 @@ Difficulty: Very Hard return FALSE return TRUE -/obj/machinery/smartfridge/black_box/Initialize() +/obj/machinery/smartfridge/black_box/Initialize(mapload) . = ..() var/static/obj/machinery/smartfridge/black_box/current if(current && current != src) @@ -421,12 +423,12 @@ Difficulty: Very Hard if(ismob(AM)) ActivationReaction(AM, ACTIVATE_MOB_BUMP) -/obj/machinery/anomalous_crystal/ex_act() +/obj/machinery/anomalous_crystal/ex_act(severity, target, origin) ActivationReaction(null, ACTIVATE_BOMB) /obj/machinery/anomalous_crystal/honk //Strips and equips you as a clown. I apologize for nothing observer_desc = "This crystal strips and equips its targets as clowns." - possible_methods = list(ACTIVATE_TOUCH) //Because We love AOE transformations! + possible_methods = list(ACTIVATE_TOUCH) //Because We love AOE transformations! activation_sound = 'sound/items/bikehorn.ogg' /obj/machinery/anomalous_crystal/honk/ActivationReaction(mob/user) @@ -436,7 +438,7 @@ Difficulty: Very Hard H.dropItemToGround(W) var/datum/job/clown/C = new /datum/job/clown() C.equip(H) - C.after_spawn(H, H, TRUE) + C.after_spawn(H, H.client, TRUE) qdel(C) affected_targets.Add(H) @@ -452,7 +454,7 @@ Difficulty: Very Hard var/list/NewFlora = list() var/florachance = 8 -/obj/machinery/anomalous_crystal/theme_warp/Initialize() +/obj/machinery/anomalous_crystal/theme_warp/Initialize(mapload) . = ..() terrain_theme = pick("lavaland","winter","jungle","ayy lmao") observer_desc = "This crystal changes the area around it to match the theme of \"[terrain_theme]\"." @@ -518,7 +520,7 @@ Difficulty: Very Hard cooldown_add = 50 var/obj/item/projectile/generated_projectile = /obj/item/projectile/beam/emitter -/obj/machinery/anomalous_crystal/emitter/Initialize() +/obj/machinery/anomalous_crystal/emitter/Initialize(mapload) . = ..() generated_projectile = pick(/obj/item/projectile/colossus) @@ -528,21 +530,7 @@ Difficulty: Very Hard /obj/machinery/anomalous_crystal/emitter/ActivationReaction(mob/user, method) if(..()) var/obj/item/projectile/P = new generated_projectile(get_turf(src)) - P.setDir(dir) - switch(dir) - if(NORTH) - P.yo = 20 - P.xo = 0 - if(EAST) - P.yo = 0 - P.xo = 20 - if(WEST) - P.yo = 0 - P.xo = -20 - else - P.yo = -20 - P.xo = 0 - P.fire() + P.fire(angle2dir(dir)) /obj/machinery/anomalous_crystal/dark_reprise //Revives anyone nearby, but turns them into shadowpeople and renders them uncloneable, so the crystal is your only hope of getting up again if you go down. observer_desc = "When activated, this crystal revives anyone nearby, but turns them into Shadowpeople and makes them unclonable, making the crystal their only hope of getting up again." @@ -643,7 +631,7 @@ Difficulty: Very Hard stop_automated_movement = 1 var/heal_power = 5 -/mob/living/simple_animal/hostile/lightgeist/Initialize() +/mob/living/simple_animal/hostile/lightgeist/Initialize(mapload) . = ..() remove_verb(src, /mob/living/verb/pulled) remove_verb(src, /mob/verb/me_verb) @@ -754,7 +742,7 @@ Difficulty: Very Hard /obj/structure/closet/stasis/emp_act() return -/obj/structure/closet/stasis/ex_act() +/obj/structure/closet/stasis/ex_act(severity, target, origin) return /obj/structure/closet/stasis/handle_lock_addition() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm index 1aa0957fee..098cbb3add 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm @@ -16,7 +16,7 @@ Difficulty: Extremely Hard mob_biotypes = MOB_ORGANIC|MOB_HUMANOID light_color = "#E4C7C5" movement_type = GROUND - weather_immunities = list("snow") + weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE) speak_emote = list("roars") armour_penetration = 100 melee_damage_lower = 10 @@ -48,7 +48,7 @@ Difficulty: Extremely Hard /// If the demonic frost miner is currently transforming to its enraged state var/enraging = FALSE -/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/Initialize() +/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/Initialize(mapload) . = ..() AddComponent(/datum/component/knockback, 7, FALSE, TRUE) AddComponent(/datum/component/lifesteal, 50) @@ -147,7 +147,7 @@ Difficulty: Extremely Hard if(isturf(target) || isobj(target)) target.ex_act(EXPLODE_HEAVY) -/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/ex_act(severity, target) +/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/ex_act(severity, target, origin) adjustBruteLoss(30 * severity - 120) visible_message("[src] absorbs the explosion!", "You absorb the explosion!") @@ -309,7 +309,7 @@ Difficulty: Extremely Hard desc = "A pair of winter boots contractually made by a devil, they cannot be taken off once put on." slowdown = SHOES_SPEED_SLIGHT -/obj/item/clothing/shoes/winterboots/ice_boots/speedy/Initialize() +/obj/item/clothing/shoes/winterboots/ice_boots/speedy/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CURSED_ITEM_TRAIT) @@ -318,7 +318,7 @@ Difficulty: Extremely Hard desc = "Cracks rocks at an inhuman speed, as well as being enhanced for combat purposes." toolspeed = 0 -/obj/item/pickaxe/drill/jackhammer/demonic/Initialize() +/obj/item/pickaxe/drill/jackhammer/demonic/Initialize(mapload) . = ..() AddComponent(/datum/component/knockback, 4, FALSE, TRUE) AddComponent(/datum/component/lifesteal, 5) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm index a2d18c508e..7a946e662b 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm @@ -2,7 +2,7 @@ vore_active = TRUE isPredator = TRUE -/mob/living/simple_animal/hostile/megafauna/dragon/Initialize() +/mob/living/simple_animal/hostile/megafauna/dragon/Initialize(mapload) // Create and register 'stomachs' var/obj/belly/megafauna/dragon/maw/maw = new(src) var/obj/belly/megafauna/dragon/gullet/gullet = new(src) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index a3d51744b9..49db738233 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -59,6 +59,8 @@ Difficulty: Medium move_to_delay = 5 ranged = 1 pixel_x = -16 + maptext_height = 64 + maptext_width = 64 crusher_loot = list(/obj/structure/closet/crate/necropolis/dragon/crusher) loot = list(/obj/structure/closet/crate/necropolis/dragon) butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/bone = 30, /obj/item/reagent_containers/food/snacks/meat/slab/dragon = 5) @@ -74,12 +76,12 @@ Difficulty: Medium footstep_type = FOOTSTEP_MOB_HEAVY -/mob/living/simple_animal/hostile/megafauna/dragon/Initialize() +/mob/living/simple_animal/hostile/megafauna/dragon/Initialize(mapload) smallsprite.Grant(src) . = ..() internal = new/obj/item/gps/internal/dragon(src) -/mob/living/simple_animal/hostile/megafauna/dragon/ex_act(severity, target) +/mob/living/simple_animal/hostile/megafauna/dragon/ex_act(severity, target, origin) if(severity == 3) return ..() @@ -195,7 +197,7 @@ Difficulty: Medium if(L.client) empty += pick(((RANGE_TURFS(2, L) - RANGE_TURFS(1, L)) & turfs) - empty) // picks a turf within 2 of the creature not outside or in the shield any_attack = 1 - for(var/obj/mecha/M in T.contents) + for(var/obj/vehicle/sealed/mecha/M in T.contents) empty += pick(((RANGE_TURFS(2, M) - RANGE_TURFS(1, M)) & turfs) - empty) any_attack = 1 if(!any_attack) @@ -264,11 +266,11 @@ Difficulty: Medium to_chat(L, "You're hit by [src]'s fire breath!") // deals damage to mechs - for(var/obj/mecha/M in T.contents) + for(var/obj/vehicle/sealed/mecha/M in T.contents) if(M in hit_list) continue hit_list += M - M.take_damage(45, BRUTE, "melee", 1) + M.take_damage(45, BRUTE, MELEE, 1) sleep(1.5) /mob/living/simple_animal/hostile/megafauna/dragon/proc/swoop_attack(lava_arena = FALSE, atom/movable/manual_target, var/swoop_cooldown = 30) @@ -350,8 +352,8 @@ Difficulty: Medium var/throwtarget = get_edge_target_turf(src, throw_dir) L.throw_at(throwtarget, 3) visible_message("[L] is thrown clear of [src]!") - for(var/obj/mecha/M in orange(1, src)) - M.take_damage(75, BRUTE, "melee", 1) + for(var/obj/vehicle/sealed/mecha/M in orange(1, src)) + M.take_damage(75, BRUTE, MELEE, 1) for(var/mob/M in range(7, src)) shake_camera(M, 15, 1) @@ -387,7 +389,7 @@ Difficulty: Medium light_range = 2 duration = 13 -/obj/effect/temp_visual/lava_warning/ex_act() +/obj/effect/temp_visual/lava_warning/ex_act(severity, target, origin) return /obj/effect/temp_visual/lava_warning/Initialize(mapload, var/reset_time = 10) @@ -409,8 +411,8 @@ Difficulty: Medium to_chat(L, "You fall directly into the pool of lava!") // deals damage to mechs - for(var/obj/mecha/M in T.contents) - M.take_damage(45, BRUTE, "melee", 1) + for(var/obj/vehicle/sealed/mecha/M in T.contents) + M.take_damage(45, BRUTE, MELEE, 1) // changes turf to lava temporarily if(!istype(T, /turf/closed) && !istype(T, /turf/open/lava)) @@ -538,9 +540,9 @@ Difficulty: Medium to_chat(L, "You're hit by [source]'s fire breath!") // deals damage to mechs - for(var/obj/mecha/M in T.contents) + for(var/obj/vehicle/sealed/mecha/M in T.contents) if(M in hit_list) continue hit_list += M - M.take_damage(45, BRUTE, "melee", 1) + M.take_damage(45, BRUTE, MELEE, 1) sleep(1.5) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index 14b71b3bac..efef46f2ef 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -81,7 +81,7 @@ Difficulty: Normal var/list/kill_phrases = list("Wsyvgi sj irivkc xettih. Vitemvmrk...", "Irivkc wsyvgi jsyrh. Vitemvmrk...", "Jyip jsyrh. Egxmzexmrk vitemv gcgpiw...", "Kix fiex. Liepmrk...") var/list/target_phrases = list("Xevkix psgexih.", "Iriqc jsyrh.", "Eguymvih xevkix.") -/mob/living/simple_animal/hostile/megafauna/hierophant/Initialize() +/mob/living/simple_animal/hostile/megafauna/hierophant/Initialize(mapload) . = ..() internal = new/obj/item/gps/internal/hierophant(src) spawned_beacon = new(loc) @@ -89,7 +89,7 @@ Difficulty: Normal /mob/living/simple_animal/hostile/megafauna/hierophant/spawn_crusher_loot() new /obj/item/crusher_trophy/vortex_talisman(get_turf(spawned_beacon)) -/mob/living/simple_animal/hostile/megafauna/hierophant/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/megafauna/hierophant/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(spawned_beacon && !QDELETED(spawned_beacon) && !client) @@ -364,7 +364,7 @@ Difficulty: Normal var/turf/T = get_turf(victim) if(!istype(victim) || victim.stat == DEAD || !T || arena_cooldown > world.time) return - if((istype(get_area(T), /area/ruin/unpowered/hierophant) || istype(get_area(src), /area/ruin/unpowered/hierophant)) && victim != src) + if((istype(get_area(T), /area/ruin/lavaland/unpowered/hierophant) || istype(get_area(src), /area/ruin/lavaland/unpowered/hierophant)) && victim != src) return arena_cooldown = world.time + initial(arena_cooldown) for(var/d in GLOB.cardinals) @@ -490,7 +490,8 @@ Difficulty: Normal queue_smooth_neighbors(src) return ..() -/obj/effect/temp_visual/hierophant/wall/CanPass(atom/movable/mover, turf/target) +/obj/effect/temp_visual/hierophant/wall/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(QDELETED(caster)) return FALSE if(mover == caster.pulledby) @@ -499,9 +500,10 @@ Difficulty: Normal var/obj/item/projectile/P = mover if(P.firer == caster) return TRUE + if(mover != caster) + return FALSE if(mover == caster) return TRUE - return FALSE /obj/effect/temp_visual/hierophant/chaser //a hierophant's chaser. follows target around, moving and producing a blast every speed deciseconds. duration = 98 @@ -643,7 +645,7 @@ Difficulty: Normal playsound(L,'sound/weapons/sear.ogg', 50, 1, -4) to_chat(L, "You're struck by a [name]!") var/limb_to_hit = L.get_bodypart(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)) - var/armor = L.run_armor_check(limb_to_hit, "melee", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 50, "Your armor was penetrated by [src]!") + var/armor = L.run_armor_check(limb_to_hit, MELEE, "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 50, "Your armor was penetrated by [src]!") L.apply_damage(damage, BURN, limb_to_hit, armor, wound_bonus=CANT_WOUND) if(ishostile(L)) var/mob/living/simple_animal/hostile/H = L //mobs find and damage you... @@ -656,14 +658,16 @@ Difficulty: Normal if(monster_damage_boost && (ismegafauna(L) || istype(L, /mob/living/simple_animal/hostile/asteroid))) L.adjustBruteLoss(damage) log_combat(caster, L, "struck with a [name]") - for(var/obj/mecha/M in T.contents - hit_things) //also damage mechs. + for(var/obj/vehicle/sealed/mecha/M in T.contents - hit_things) //also damage mechs. hit_things += M - if(M.occupant) - if(friendly_fire_check && caster && caster.faction_check_mob(M.occupant)) + for(var/O in M.occupants) + var/mob/living/occupant = O + if(friendly_fire_check && caster && caster.faction_check_mob(occupant)) continue - to_chat(M.occupant, "Your [M.name] is struck by a [name]!") - playsound(M,'sound/weapons/sear.ogg', 50, 1, -4) - M.take_damage(damage, BURN, 0, 0, null, 50) + to_chat(occupant, "Your [M.name] is struck by a [name]!") + playsound(M,'sound/weapons/sear.ogg', 50, TRUE, -4) + M.take_damage(damage, BURN, 0, 0) + /obj/effect/hierophant name = "hierophant beacon" @@ -674,7 +678,7 @@ Difficulty: Normal layer = LOW_OBJ_LAYER anchored = TRUE -/obj/effect/hierophant/ex_act() +/obj/effect/hierophant/ex_act(severity, target, origin) return /obj/effect/hierophant/attackby(obj/item/I, mob/user, params) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm index 15bfe2b7f7..299715f9e2 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -48,6 +48,8 @@ SHITCODE AHEAD. BE ADVISED. Also comment extravaganza score_achievement_type = /datum/award/score/legion_score pixel_y = -16 pixel_x = -32 + maptext_height = 96 + maptext_width = 96 loot = list(/obj/item/stack/sheet/bone = 3) vision_range = 10 wander = FALSE @@ -59,7 +61,7 @@ SHITCODE AHEAD. BE ADVISED. Also comment extravaganza var/size = 3 var/charging = FALSE -/mob/living/simple_animal/hostile/megafauna/legion/Initialize() +/mob/living/simple_animal/hostile/megafauna/legion/Initialize(mapload) . = ..() internal = new/obj/item/gps/internal/legion(src) @@ -335,7 +337,7 @@ SHITCODE AHEAD. BE ADVISED. Also comment extravaganza anchored = TRUE density = TRUE layer = ABOVE_OBJ_LAYER - armor = list("melee" = 0, "bullet" = 0, "laser" = 100,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 100,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) ///What kind of projectile the actual damaging part should be. var/projectile_type = /obj/item/projectile/beam/legion ///Time until the tracer gets shot @@ -345,7 +347,7 @@ SHITCODE AHEAD. BE ADVISED. Also comment extravaganza ///Compared with the targeted mobs. If they have the faction, turret won't shoot. var/faction = list("mining") -/obj/structure/legionturret/Initialize() +/obj/structure/legionturret/Initialize(mapload) . = ..() addtimer(CALLBACK(src, .proc/set_up_shot), initial_firing_time) @@ -394,7 +396,7 @@ SHITCODE AHEAD. BE ADVISED. Also comment extravaganza muzzle_type = /obj/effect/projectile/tracer/legion impact_type = /obj/effect/projectile/tracer/legion hitscan = TRUE - movement_type = UNSTOPPABLE + projectile_piercing = ALL ///Used for the legion turret tracer. /obj/effect/projectile/tracer/legion/tracer diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index 3940388625..64566abb9d 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -10,7 +10,7 @@ obj_damage = 400 light_range = 3 faction = list("mining", "boss") - weather_immunities = list("lava","ash") + weather_immunities = list(TRAIT_LAVA_IMMUNE,TRAIT_ASHSTORM_IMMUNE) movement_type = FLYING robust_searching = 1 ranged_ignores_vision = TRUE @@ -122,7 +122,7 @@ if(!client && ranged && ranged_cooldown <= world.time) OpenFire() if(L.Adjacent(src) && (L.stat != CONSCIOUS)) - if(vore_active && CHECK_BITFIELD(L.vore_flags,DEVOURABLE)) + if(vore_active && (L.vore_flags & DEVOURABLE)) vore_attack(src,L,src) LoseTarget() else @@ -138,7 +138,7 @@ adjustBruteLoss(-L.maxHealth/2) L.gib() -/mob/living/simple_animal/hostile/megafauna/ex_act(severity, target) +/mob/living/simple_animal/hostile/megafauna/ex_act(severity, target, origin) switch (severity) if (EXPLODE_DEVASTATE) adjustBruteLoss(250) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm index 923a626b28..d071209b64 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm @@ -52,7 +52,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa crusher_achievement_type = /datum/award/achievement/boss/swarmer_beacon_crusher score_achievement_type = /datum/award/score/swarmer_beacon_score faction = list("mining", "boss", "swarmer") - weather_immunities = list("lava","ash") + weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE) stop_automated_movement = TRUE wander = FALSE layer = BELOW_MOB_LAYER @@ -64,7 +64,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa var/static/list/swarmer_caps -/mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon/Initialize() +/mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon/Initialize(mapload) . = ..() swarmer_caps = GLOB.AISwarmerCapsByType //for admin-edits internal = new/obj/item/gps/internal/swarmer_beacon(src) @@ -74,7 +74,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa step(R, ddir) //Step the swarmers, instead of spawning them there, incase the turf is solid -/mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return var/createtype = GetUncappedAISwarmerType() @@ -101,10 +101,10 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa /mob/living/simple_animal/hostile/swarmer/ai wander = 1 faction = list("swarmer", "mining") - weather_immunities = list("ash") //wouldn't be fun otherwise + weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE) //wouldn't be fun otherwise AIStatus = AI_ON -/mob/living/simple_animal/hostile/swarmer/ai/Initialize() +/mob/living/simple_animal/hostile/swarmer/ai/Initialize(mapload) . = ..() ToggleLight() //so you can see them eating you out of house and home/shooting you/stunlocking you for eternity LAZYINITLIST(GLOB.AISwarmersByType[type]) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm index 869f29951b..3a9ad12cab 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm @@ -14,7 +14,7 @@ Difficulty: Hard attack_verb_continuous = "claws" attack_verb_simple = "claw" attack_sound = 'sound/magic/demon_attack1.ogg' - weather_immunities = list("snow") + weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE) speak_emote = list("roars") armour_penetration = 40 melee_damage_lower = 40 @@ -32,6 +32,9 @@ Difficulty: Hard wander = FALSE del_on_death = TRUE blood_volume = BLOOD_VOLUME_NORMAL + achievement_type = /datum/award/achievement/boss/wendigo_kill + crusher_achievement_type = /datum/award/achievement/boss/wendigo_crusher + score_achievement_type = /datum/award/score/wendigo_score deathmessage = "falls, shaking the ground around it" deathsound = 'sound/effects/gravhit.ogg' attack_action_types = list(/datum/action/innate/megafauna_attack/heavy_stomp, @@ -67,7 +70,7 @@ Difficulty: Hard chosen_message = "You are now screeching, disorienting targets around you." chosen_attack_num = 3 -/mob/living/simple_animal/hostile/megafauna/wendigo/Initialize() +/mob/living/simple_animal/hostile/megafauna/wendigo/Initialize(mapload) . = ..() starting = get_turf(src) diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index c2d05e43d9..6370fae0e3 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -118,7 +118,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca overlay_googly_eyes = FALSE CopyObject(copy, creator, destroy_original) -/mob/living/simple_animal/hostile/mimic/copy/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/mimic/copy/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(idledamage && !target && !ckey) //Objects eventually revert to normal if no one is around to terrorize diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index 24e595ef7e..232bdb04c4 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -42,7 +42,7 @@ damage = 0 damage_type = BURN nodamage = 1 - flag = "energy" + flag = ENERGY temperature = 50 /mob/living/simple_animal/hostile/asteroid/basilisk/GiveTarget(new_target) @@ -50,7 +50,7 @@ if(isliving(target) && !target.Adjacent(targets_from) && ranged_cooldown <= world.time)//No more being shot at point blank or spammed with RNG beams OpenFire(target) -/mob/living/simple_animal/hostile/asteroid/basilisk/ex_act(severity, target) +/mob/living/simple_animal/hostile/asteroid/basilisk/ex_act(severity, target, origin) switch(severity) if(1) gib() @@ -95,7 +95,7 @@ wanted_objects = list(/obj/item/pen/survival, /obj/item/stack/ore/diamond) field_of_vision_type = FOV_270_DEGREES //Obviously, it's one eyeball. -/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(stat == CONSCIOUS) @@ -110,7 +110,7 @@ qdel(O) src.visible_message("[src] examines [O] closer, and telekinetically shatters the pen.") -/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random/Initialize() +/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random/Initialize(mapload) . = ..() if(prob(1)) if(prob(75)) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm index ed056c2ad9..04b003b315 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm @@ -72,14 +72,14 @@ return //if it's not our target, we ignore it -/mob/living/simple_animal/hostile/asteroid/curseblob/CanPass(atom/movable/mover, turf/target) +/mob/living/simple_animal/hostile/asteroid/curseblob/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(mover == set_target) return FALSE if(istype(mover, /obj/item/projectile)) var/obj/item/projectile/P = mover if(P.firer == set_target) return FALSE - return TRUE #define IGNORE_PROC_IF_NOT_TARGET(X) /mob/living/simple_animal/hostile/asteroid/curseblob/##X(AM) { if (AM == set_target) return ..(); } diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm index d677f59440..1f5cace824 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm @@ -113,7 +113,7 @@ While using this makes the system rely on OnFire, it still gives options for tim severity = 7 hud_used.healths.icon_state = "elite_health[severity]" if(severity > 0) - overlay_fullscreen("brute", /atom/movable/screen/fullscreen/brute, severity) + overlay_fullscreen("brute", /atom/movable/screen/fullscreen/scaled/brute, severity) else clear_fullscreen("brute") @@ -122,7 +122,7 @@ While using this makes the system rely on OnFire, it still gives options for tim /obj/structure/elite_tumor name = "pulsing tumor" desc = "An odd, pulsing tumor sticking out of the ground. You feel compelled to reach out and touch it..." - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) resistance_flags = INDESTRUCTIBLE var/activity = TUMOR_INACTIVE var/boosted = FALSE @@ -176,6 +176,12 @@ While using this makes the system rely on OnFire, it still gives options for tim elitemind = pick(candidates) elitemind.playsound_local(get_turf(elitemind), 'sound/effects/magic.ogg', 40, 0) to_chat(elitemind, "You have been chosen to play as a Lavaland Elite.\nIn a few seconds, you will be summoned on Lavaland as a monster to fight your activator, in a fight to the death.\nYour attacks can be switched using the buttons on the top left of the HUD, and used by clicking on targets or tiles similar to a gun.\nWhile the opponent might have an upper hand with powerful mining equipment and tools, you have great power normally limited by AI mobs.\nIf you want to win, you'll have to use your powers in creative ways to ensure the kill. It's suggested you try using them all as soon as possible.\nShould you win, you'll receive extra information regarding what to do after. Good luck!") + var/list/policies = CONFIG_GET(keyed_list/policy) + var/policy = policies[POLICYCONFIG_ELITE_SPAWN] + if(policy) + to_chat(elitemind, "
    !!READ THIS!!
    The following is server-specific policy configuration and overrides anything said above if conflicting.") + to_chat(elitemind, "

    ") + to_chat(elitemind, "[policy]") addtimer(CALLBACK(src, .proc/spawn_elite, elitemind), 100) else visible_message("The stirring stops, and nothing emerges. Perhaps try again later.") @@ -304,6 +310,12 @@ While using this makes the system rely on OnFire, it still gives options for tim to_chat(mychild, "As the life in the activator's eyes fade, the forcefield around you dies out and you feel your power subside.\nDespite this inferno being your home, you feel as if you aren't welcome here anymore.\nWithout any guidance, your purpose is now for you to decide.") to_chat(mychild, "Your max health has been halved, but can now heal by standing on your tumor. Note, it's your only way to heal.\nBear in mind, if anyone interacts with your tumor, you'll be resummoned here to carry out another fight. In such a case, you will regain your full max health.\nAlso, be weary of your fellow inhabitants, they likely won't be happy to see you!") to_chat(mychild, "Note that you are a lavaland monster, and thus not allied to the station. You should not cooperate or act friendly with any station crew unless under extreme circumstances!") + var/list/policies = CONFIG_GET(keyed_list/policy) + var/policy = policies[POLICYCONFIG_ELITE_WIN] + if(policy) + to_chat(mychild, "
    !!READ THIS!!
    The following is server-specific policy configuration and overrides anything said above if conflicting.") + to_chat(mychild, "

    ") + to_chat(mychild, "[policy]") /obj/item/tumor_shard name = "tumor shard" @@ -332,6 +344,12 @@ While using this makes the system rely on OnFire, it still gives options for tim E.playsound_local(get_turf(E), 'sound/effects/magic.ogg', 40, 0) to_chat(E, "You have been revived by [user]. While you can't speak to them, you owe [user] a great debt. Assist [user.p_them()] in achieving [user.p_their()] goals, regardless of risk.Note that you now share the loyalties of [user]. You are expected not to intentionally sabotage their faction unless commanded to!") + var/list/policies = CONFIG_GET(keyed_list/policy) + var/policy = policies[POLICYCONFIG_ELITE_SENTIENCE] + if(policy) + to_chat(E, "
    !!READ THIS!!
    The following is server-specific policy configuration and overrides anything said above if conflicting.") + to_chat(E, "

    ") + to_chat(E, "[policy]") E.maxHealth = E.maxHealth * 0.5 E.health = E.maxHealth E.desc = "[E.desc] However, this one appears appears less wild in nature, and calmer around people." @@ -365,8 +383,7 @@ While using this makes the system rely on OnFire, it still gives options for tim ourelite = null return ..() -/obj/effect/temp_visual/elite_tumor_wall/CanPass(atom/movable/mover, turf/target) +/obj/effect/temp_visual/elite_tumor_wall/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(mover == ourelite || mover == activator) return FALSE - else - return TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm index 5ee249c767..d7b7dc3dae 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm @@ -98,7 +98,7 @@ if(CALL_CHILDREN) call_children() -/mob/living/simple_animal/hostile/asteroid/elite/broodmother/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/elite/broodmother/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(health < maxHealth * 0.5 && rand_tent < world.time) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm index 4425bce532..7b21ce6a62 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm @@ -203,7 +203,7 @@ is_mirror = TRUE var/mob/living/simple_animal/hostile/asteroid/elite/herald/my_master = null -/mob/living/simple_animal/hostile/asteroid/elite/herald/mirror/Initialize() +/mob/living/simple_animal/hostile/asteroid/elite/herald/mirror/Initialize(mapload) ..() toggle_ai(AI_OFF) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm index dca508cfeb..c744d4ed58 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm @@ -275,7 +275,7 @@ duration = 10 color = rgb(0,0,0) -/obj/effect/temp_visual/dragon_swoop/legionnaire/Initialize() +/obj/effect/temp_visual/dragon_swoop/legionnaire/Initialize(mapload) . = ..() transform *= 0.33 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm index 50b15933a9..5daeaff9e8 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm @@ -95,7 +95,7 @@ if(AOE_SQUARES) aoe_squares(target) -/mob/living/simple_animal/hostile/asteroid/elite/pandora/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/elite/pandora/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(health >= maxHealth * 0.5) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm index 3845c6f406..2017d75c36 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm @@ -35,7 +35,7 @@ var/chase_time = 100 var/will_burrow = TRUE -/mob/living/simple_animal/hostile/asteroid/goldgrub/Initialize() +/mob/living/simple_animal/hostile/asteroid/goldgrub/Initialize(mapload) . = ..() var/i = rand(1,3) while(i) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm index fa67fd8e3b..115681a7d4 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm @@ -38,7 +38,7 @@ footstep_type = FOOTSTEP_MOB_HEAVY -/mob/living/simple_animal/hostile/asteroid/goliath/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/goliath/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return handle_preattack() @@ -101,7 +101,7 @@ stat_attack = UNCONSCIOUS robust_searching = 1 -/mob/living/simple_animal/hostile/asteroid/goliath/beast/random/Initialize() +/mob/living/simple_animal/hostile/asteroid/goliath/beast/random/Initialize(mapload) . = ..() if(prob(1)) new /mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient(loc) @@ -129,7 +129,7 @@ var/turf/last_location var/tentacle_recheck_cooldown = 100 -/mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(isturf(loc)) @@ -191,7 +191,7 @@ continue visible_message("[src] grabs hold of [L]!") var/mob/living/carbon/C = L - var/obj/item/clothing/S = C.get_item_by_slot(SLOT_WEAR_SUIT) + var/obj/item/clothing/S = C.get_item_by_slot(ITEM_SLOT_OCLOTHING) if(S && S.resistance_flags & GOLIATH_RESISTANCE) L.Stun(25) else if(S && S.resistance_flags & GOLIATH_WEAKNESS) @@ -200,7 +200,7 @@ L.Stun(75) L.adjustBruteLoss(rand(15,20)) // Less stun more harm latched = TRUE - for(var/obj/mecha/M in loc) + for(var/obj/vehicle/sealed/mecha/M in loc) M.take_damage(20, BRUTE, null, null, null, 25) if(!latched) retract() diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm index e35220a920..87a5010dce 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm @@ -10,7 +10,7 @@ speak_emote = list("warbles", "quavers") emote_hear = list("trills.") emote_see = list("sniffs.", "burps.") - weather_immunities = list("lava","ash") + weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE) faction = list("mining", "ashwalker") density = FALSE speak_chance = 1 @@ -46,7 +46,7 @@ /obj/item/organ/lungs, /obj/item/organ/stomach, /obj/item/organ/tongue) // So we dont eat implants or brains. Still can eat robotic stuff thats subtyped of base line but thats a issue for another day. var/obj/item/udder/gutlunch/udder = null -/mob/living/simple_animal/hostile/asteroid/gutlunch/Initialize() +/mob/living/simple_animal/hostile/asteroid/gutlunch/Initialize(mapload) udder = new() . = ..() AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) @@ -103,7 +103,7 @@ name = "gubbuck" gender = MALE -/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck/Initialize() +/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck/Initialize(mapload) . = ..() add_atom_colour(pick("#E39FBB", "#D97D64", "#CF8C4A"), FIXED_COLOUR_PRIORITY) resize = 0.85 @@ -114,7 +114,7 @@ name = "guthen" gender = FEMALE -/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(udder.reagents.total_volume == udder.reagents.maximum_volume) //Only breed when we're full. @@ -130,7 +130,7 @@ /obj/item/udder/gutlunch name = "nutrient sac" -/obj/item/udder/gutlunch/Initialize() +/obj/item/udder/gutlunch/Initialize(mapload) . = ..() reagents = new(50) reagents.my_atom = src diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm index 7db91b50ad..0844cf988a 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm @@ -92,7 +92,7 @@ var/swarming = FALSE var/my_creator = null -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/Initialize() +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/Initialize(mapload) . = ..() if(swarming) AddComponent(/datum/component/swarming) //oh god not the bees @@ -126,7 +126,7 @@ var/dwarf_mob = FALSE var/mob/living/carbon/human/stored_mob -/mob/living/simple_animal/hostile/asteroid/hivelord/legion/random/Initialize() +/mob/living/simple_animal/hostile/asteroid/hivelord/legion/random/Initialize(mapload) . = ..() if(prob(5)) new /mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf(loc) @@ -198,7 +198,7 @@ swarming = TRUE var/can_infest_dead = FALSE -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(isturf(loc)) @@ -272,13 +272,13 @@ aggro_vision_range = 9 speed = 3 faction = list("mining") - weather_immunities = list("lava","ash") + weather_immunities = list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE) obj_damage = 30 environment_smash = ENVIRONMENT_SMASH_STRUCTURES see_in_dark = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE -/mob/living/simple_animal/hostile/big_legion/Initialize() +/mob/living/simple_animal/hostile/big_legion/Initialize(mapload) .=..() AddComponent(/datum/component/spawner, list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion), 200, faction, "peels itself off from", 3) @@ -298,7 +298,7 @@ . = ..() H.dna.add_mutation(DWARFISM) -/obj/effect/mob_spawn/human/corpse/damaged/legioninfested/Initialize() +/obj/effect/mob_spawn/human/corpse/damaged/legioninfested/Initialize(mapload) var/type = pickweight(list("Miner" = 45, "Ashwalker" = 10, "Golem" = 10,"Clown" = 10, pick(list("Shadow", "YeOlde","Operative", "Cultist", "Lavaknight")) = 4, "Assistant" = 20, "Beelegion" = 1)) switch(type) if("Miner") @@ -321,7 +321,7 @@ gloves = /obj/item/clothing/gloves/color/black mask = /obj/item/clothing/mask/gas/explorer if(prob(20)) - suit = pickweight(list(/obj/item/clothing/suit/hooded/explorer/standard = 6, /obj/item/clothing/suit/hooded/cloak/goliath = 2, /obj/item/clothing/suit/hooded/explorer/exo = 6, /obj/item/clothing/suit/hooded/explorer/seva = 6)) + suit = pickweight(list(/obj/item/clothing/suit/hooded/explorer/standard = 6, /obj/item/clothing/suit/hooded/cloak/goliath = 2, /obj/item/clothing/suit/hooded/explorer/exo = 6, /obj/item/clothing/suit/hooded/explorer/heva = 6)) if(prob(30)) r_pocket = pickweight(list(/obj/item/stack/marker_beacon = 20, /obj/item/stack/spacecash/c1000 = 7, /obj/item/reagent_containers/hypospray/medipen/survival = 2, /obj/item/borg/upgrade/modkit/damage = 1 )) if(prob(10)) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm index d40cd8636c..2cf96bf51b 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm @@ -62,7 +62,7 @@ SLEEP_CHECK_DEATH(8) return ..() -/mob/living/simple_animal/hostile/asteroid/ice_demon/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/ice_demon/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(target) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm index 7214fd71e0..8ab61d2450 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm @@ -43,7 +43,7 @@ var/list/burn_turfs = getline(src, T) - get_turf(src) dragon_fire_line(src, burn_turfs) -/mob/living/simple_animal/hostile/asteroid/ice_whelp/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/ice_whelp/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(target) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm index c3e4f24c43..e9be18f0cb 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm @@ -3,7 +3,7 @@ vision_range = 2 atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) faction = list("mining") - weather_immunities = list("lava","ash") + weather_immunities = list(TRAIT_LAVA_IMMUNE,TRAIT_ASHSTORM_IMMUNE) obj_damage = 30 environment_smash = ENVIRONMENT_SMASH_WALLS minbodytemp = 0 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm index de9464cc16..9a81d74dc8 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm @@ -44,7 +44,7 @@ aggressive_message_said = TRUE rapid_melee = 2 -/mob/living/simple_animal/hostile/asteroid/polarbear/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/polarbear/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(target) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm index 8c4db48434..148d71ecd8 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm @@ -51,7 +51,7 @@ retreat_message_said = TRUE retreat_distance = 30 -/mob/living/simple_animal/hostile/asteroid/wolf/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/wolf/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(target) diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index f41746ea69..378dbefae7 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -40,7 +40,7 @@ var/static/mutable_appearance/cap_living //Where we store our cap icons so we dont generate them constantly to update our icon var/static/mutable_appearance/cap_dead -/mob/living/simple_animal/hostile/mushroom/Initialize() +/mob/living/simple_animal/hostile/mushroom/Initialize(mapload) . = ..() AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) @@ -51,13 +51,13 @@ else . += "It looks like it's been roughed up." -/mob/living/simple_animal/hostile/mushroom/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/mushroom/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat)//Mushrooms slowly regenerate if conscious, for people who want to save them from being eaten adjustBruteLoss(-2) -/mob/living/simple_animal/hostile/mushroom/Initialize()//Makes every shroom a little unique +/mob/living/simple_animal/hostile/mushroom/Initialize(mapload)//Makes every shroom a little unique melee_damage_lower += rand(3, 5) melee_damage_upper += rand(10,20) maxHealth += rand(40,60) diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm index 92f331071a..a1e135d038 100644 --- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm +++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm @@ -34,9 +34,9 @@ deathmessage = "wails as its form turns into a pulpy mush." death_sound = 'sound/voice/hiss6.ogg' -/mob/living/simple_animal/hostile/netherworld/migo/Initialize() +/mob/living/simple_animal/hostile/netherworld/migo/Initialize(mapload) . = ..() - migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/carhorn.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/megaphone.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/items/geiger/high1.ogg', 'sound/items/geiger/high2.ogg', 'sound/voice/beepsky/creep.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/medbot/patchedup.ogg', 'sound/voice/medbot/feelbetter.ogg', 'sound/voice/human/manlaugh1.ogg', 'sound/voice/human/womanlaugh.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/clockcultalr.ogg', 'sound/ambience/antag/ling_aler.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/ambience/antag/monkey.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clockcult_gateway_disrupted.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/curse1.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosion_distant.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heart_beat.ogg', 'sound/effects/hyperspace_begin.ogg', 'sound/effects/hyperspace_end.ogg', 'sound/effects/his_grace_awaken.ogg', 'sound/effects/pai_boot.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/ratvar_reveal.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/misc/airraid.ogg', 'sound/misc/bang.ogg','sound/misc/highlander.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/misc/splort.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/beam_sniper.ogg', 'sound/weapons/chainsawhit.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gunshot_silenced.ogg', 'sound/weapons/gunshot2.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/clockcult/steam_whoosh.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlockclose.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlockopen.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/cryo_warning.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/machines/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/triple_beep.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', get_announcer_sound("outbreak5"), get_announcer_sound("outbreak7"), get_announcer_sound("poweroff"), get_announcer_sound("radiation"), get_announcer_sound("shuttlerecalled"), get_announcer_sound("shuttledock"), get_announcer_sound("shuttlecalled"), get_announcer_sound("aimalf")) //hahahaha fuck you code divers + migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/carhorn.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/megaphone.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/items/geiger/high1.ogg', 'sound/items/geiger/high2.ogg', 'sound/voice/beepsky/creep.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/medbot/patchedup.ogg', 'sound/voice/medbot/feelbetter.ogg', 'sound/voice/human/manlaugh1.ogg', 'sound/voice/human/womanlaugh.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/clockcultalr.ogg', 'sound/ambience/antag/ling_aler.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/ambience/antag/monkey.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clockcult_gateway_disrupted.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/curse1.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosion_distant.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heart_beat.ogg', 'sound/effects/hyperspace_begin.ogg', 'sound/effects/hyperspace_end.ogg', 'sound/effects/his_grace_awaken.ogg', 'sound/effects/pai_boot.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/ratvar_reveal.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/misc/airraid.ogg', 'sound/misc/bang.ogg','sound/misc/highlander.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/misc/splort.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/beam_sniper.ogg', 'sound/weapons/chainsawhit.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gunshot_silenced.ogg', 'sound/weapons/gunshot2.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/clockcult/steam_whoosh.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlockclose.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlockopen.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/cryo_warning.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/machines/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/triple_beep.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', SSstation.announcer.event_sounds[ANNOUNCER_OUTBREAK5], SSstation.announcer.event_sounds[ANNOUNCER_OUTBREAK7], SSstation.announcer.event_sounds[ANNOUNCER_POWEROFF], SSstation.announcer.event_sounds[ANNOUNCER_RADIATION], SSstation.announcer.event_sounds[ANNOUNCER_SHUTTLERECALLED], SSstation.announcer.event_sounds[ANNOUNCER_SHUTTLEDOCK], SSstation.announcer.event_sounds[ANNOUNCER_SHUTTLECALLED], SSstation.announcer.event_sounds[ANNOUNCER_AIMALF]) //hahahaha fuck you code divers /mob/living/simple_animal/hostile/netherworld/migo/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null) ..() @@ -45,7 +45,7 @@ var/chosen_sound = pick(migo_sounds) playsound(src, chosen_sound, 100, TRUE) -/mob/living/simple_animal/hostile/netherworld/migo/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/netherworld/migo/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(stat) @@ -81,7 +81,7 @@ mob_types = list(/mob/living/simple_animal/hostile/netherworld/migo, /mob/living/simple_animal/hostile/netherworld, /mob/living/simple_animal/hostile/netherworld/blankbody) faction = list("nether") -/obj/structure/spawner/nether/Initialize() +/obj/structure/spawner/nether/Initialize(mapload) .=..() START_PROCESSING(SSprocessing, src) diff --git a/code/modules/mob/living/simple_animal/hostile/pirate.dm b/code/modules/mob/living/simple_animal/hostile/pirate.dm index 74e37bea21..01015c43ab 100644 --- a/code/modules/mob/living/simple_animal/hostile/pirate.dm +++ b/code/modules/mob/living/simple_animal/hostile/pirate.dm @@ -55,7 +55,7 @@ speed = 1 spacewalk = TRUE -/mob/living/simple_animal/hostile/pirate/melee/Initialize() +/mob/living/simple_animal/hostile/pirate/melee/Initialize(mapload) . = ..() sord = new(src) @@ -63,7 +63,7 @@ QDEL_NULL(sord) return ..() -/mob/living/simple_animal/hostile/pirate/melee/Initialize() +/mob/living/simple_animal/hostile/pirate/melee/Initialize(mapload) . = ..() set_light(2) diff --git a/code/modules/mob/living/simple_animal/hostile/plaguerat.dm b/code/modules/mob/living/simple_animal/hostile/plaguerat.dm new file mode 100644 index 0000000000..73dace85cd --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/plaguerat.dm @@ -0,0 +1,188 @@ +#define RAT_VENT_CHANCE 1.75 +GLOBAL_LIST_EMPTY(plague_rats) + +/mob/living/simple_animal/hostile/plaguerat + name = "plague rat" + desc = "A large decaying rat. It spreads its filth and emits a putrid odor to create more of its kind." + icon_state = "plaguerat" + icon_living = "plaguerat" + icon_dead = "plaguerat_dead" + speak = list("Skree!","SKREEE!","Squeak?") + speak_emote = list("squeaks") + emote_hear = list("Hisses.") + emote_see = list("runs in a circle.", "stands on its hind legs.") + gender = NEUTER + speak_chance = 1 + turns_per_move = 5 + maxHealth = 100 + health = 100 + see_in_dark = 6 + obj_damage = 10 + butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 1) + response_help_continuous = "glares at" + response_help_simple = "glare at" + response_disarm_continuous = "skoffs at" + response_disarm_simple = "skoff at" + response_harm_continuous = "slashes" + response_harm_simple = "slash" + melee_damage_lower = 6 + melee_damage_upper = 8 + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" + attack_sound = 'sound/weapons/punch1.ogg' + faction = list("rat") + density = FALSE + pass_flags = PASSTABLE | PASSGRILLE | PASSMOB + mob_size = MOB_SIZE_TINY + mob_biotypes = MOB_ORGANIC|MOB_BEAST + var/datum/action/cooldown/scavenge + var/last_spawn_time = 0 + var/in_vent = FALSE + var/min_next_vent = 0 + var/obj/machinery/atmospherics/components/unary/entry_vent + var/obj/machinery/atmospherics/components/unary/exit_vent + +/mob/living/simple_animal/hostile/plaguerat/Initialize(mapload) + . = ..() + GLOB.plague_rats += src + AddComponent(/datum/component/swarming) + AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) + scavenge = new /datum/action/cooldown/scavenge + scavenge.Grant(src) + +/mob/living/simple_animal/hostile/plaguerat/Destroy() + GLOB.plague_rats -= src + return ..() + +/mob/living/simple_animal/hostile/plaguerat/Life(seconds, times_fired) + . = ..() + //Don't try to path to one target for too long. If it takes longer than a certain amount of time, assume it can't be reached and find a new one + //Literally only here to prevent farming and that's it. + if(!client) //don't do this shit if there's a client, they're capable of ventcrawling manually + if(in_vent) + target = null + if(entry_vent && get_dist(src, entry_vent) <= 1) + var/list/vents = list() + var/datum/pipeline/entry_vent_parent = entry_vent.parents[1] + for(var/obj/machinery/atmospherics/components/unary/temp_vent in entry_vent_parent.other_atmosmch) + vents += temp_vent + if(!vents.len) + entry_vent = null + in_vent = FALSE + return + exit_vent = pick(vents) + visible_message("[src] crawls into the ventilation ducts!") + + loc = exit_vent + var/travel_time = round(get_dist(loc, exit_vent.loc) / 2) + addtimer(CALLBACK(src, .proc/exit_vents), travel_time) //come out at exit vent in 2 to 20 seconds + + + if(world.time > min_next_vent && !entry_vent && !in_vent && prob(RAT_VENT_CHANCE)) //small chance to go into a vent + for(var/obj/machinery/atmospherics/components/unary/v in view(7,src)) + if(!v.welded) + entry_vent = v + in_vent = TRUE + walk_to(src, entry_vent) + break + +/mob/living/simple_animal/hostile/plaguerat/BiologicalLife(delta_time, times_fired) + if(!(. = ..())) + return + if(isopenturf(loc)) + var/turf/open/T = src.loc + var/datum/gas_mixture/stank = new + var/miasma_moles = T.air.get_moles(GAS_MIASMA) + stank.set_moles(GAS_MIASMA,5) + stank.set_temperature(BODYTEMP_NORMAL) + if(T.air) + if(miasma_moles < 200) + T.assume_air(stank) + T.air_update_turf() + + if(prob(40)) + scavenge.Trigger() + if(prob(50)) + var/turf/open/floor/F = get_turf(src) + if(istype(F) && !F.intact) + var/obj/structure/cable/C = locate() in F + if(C && C.avail()) + visible_message("[src] chews through the [C]. It looks unharmed!") + playsound(src, 'sound/effects/sparks2.ogg', 100, TRUE) + C.deconstruct() + for(var/obj/O in range(1,src)) + if((world.time - last_spawn_time) > 10 SECONDS && istype(O, /obj/item/trash) || istype(O, /obj/effect/decal/cleanable/blood/gibs)) + qdel(O) + be_fruitful() + last_spawn_time = world.time + +/mob/living/simple_animal/hostile/plaguerat/CanAttack(atom/the_target) + if(istype(the_target,/mob/living/simple_animal)) + var/mob/living/A = the_target + if(istype(the_target, /mob/living/simple_animal/hostile/plaguerat) && A.stat == CONSCIOUS) + var/mob/living/simple_animal/hostile/plaguerat/R = the_target + if(R.faction_check_mob(src, TRUE)) + return FALSE + else + return TRUE + return ..() + +/** + *Checks the mouse cap, if it's above the cap, doesn't spawn a mouse. If below, spawns a mouse and adds it to cheeserats. + */ + +/mob/living/simple_animal/hostile/plaguerat/proc/be_fruitful() + var/cap = 10 + if(LAZYLEN(GLOB.plague_rats) >= cap) + visible_message("[src] gnaws into its food, [cap] rats are now on the station!") + return + new /mob/living/simple_animal/hostile/plaguerat(loc) + visible_message("[src] gnaws into its food, attracting another rat!") + +/mob/living/simple_animal/hostile/plaguerat/proc/exit_vents() + if(!exit_vent || exit_vent.welded) + loc = entry_vent + entry_vent = null + return + loc = exit_vent.loc + entry_vent = null + exit_vent = null + in_vent = FALSE + var/area/new_area = get_area(loc) + message_admins("[src] came out at [new_area][ADMIN_JMP(loc)]!") + if(new_area) + new_area.Entered(src) + visible_message("[src] climbs out of the ventilation ducts!") + min_next_vent = world.time + 900 //90 seconds between ventcrawls + +/** + *Creates a chance to spawn more trash or gibs to repopulate. Otherwise, spawns a corpse or dirt. + */ + +/datum/action/cooldown/scavenge + name = "Scavenge" + desc = "Spread the plague, scavenge for trash and fresh meat to reproduce." + icon_icon = 'icons/mob/actions/actions_animal.dmi' + background_icon_state = "bg_clock" + button_icon_state = "coffer" + cooldown_time = 50 + +/datum/action/cooldown/scavenge/Trigger() + . = ..() + if(!.) + return + var/turf/T = get_turf(owner) + var/loot = rand(1,100) + switch(loot) + if(1 to 3) + var/pickedtrash = pick(GLOB.ratking_trash) + to_chat(owner, "Excellent, you find more trash to spread your filth!") + new pickedtrash(T) + if(4 to 6) + to_chat(owner, "You find blood and gibs to feed your young!") + new /obj/effect/decal/cleanable/blood/gibs(T) + if(!locate(/obj/effect/decal/cleanable/blood) in T) + new /obj/effect/decal/cleanable/blood/(T) + if(7 to 100) + to_chat(owner, "Drat. Nothing.") + StartCooldown() diff --git a/code/modules/mob/living/simple_animal/hostile/regalrat.dm b/code/modules/mob/living/simple_animal/hostile/regalrat.dm index 950da865f6..f90fb55424 100644 --- a/code/modules/mob/living/simple_animal/hostile/regalrat.dm +++ b/code/modules/mob/living/simple_animal/hostile/regalrat.dm @@ -29,7 +29,7 @@ var/datum/action/cooldown/riot ///Number assigned to rats and mice, checked when determining infighting. -/mob/living/simple_animal/hostile/regalrat/Initialize() +/mob/living/simple_animal/hostile/regalrat/Initialize(mapload) . = ..() coffer = new /datum/action/cooldown/coffer coffer.Grant(src) @@ -90,7 +90,7 @@ /datum/action/cooldown/coffer/Trigger() . = ..() - if(!.) + if(!. || owner.stat != CONSCIOUS) return var/turf/T = get_turf(owner) var/loot = rand(1,100) @@ -135,7 +135,7 @@ /datum/action/cooldown/riot/Trigger() . = ..() - if(!.) + if(!. || owner.stat != CONSCIOUS) return var/cap = CONFIG_GET(number/ratcap) var/something_from_nothing = FALSE @@ -183,7 +183,7 @@ mob_biotypes = MOB_ORGANIC|MOB_BEAST faction = list("rat") -/mob/living/simple_animal/hostile/rat/Initialize() +/mob/living/simple_animal/hostile/rat/Initialize(mapload) . = ..() SSmobs.cheeserats += src AddComponent(/datum/component/swarming) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm index cb1ee6c6f6..c45587e2aa 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm @@ -41,7 +41,7 @@ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 -/mob/living/simple_animal/hostile/retaliate/bat/Initialize() +/mob/living/simple_animal/hostile/retaliate/bat/Initialize(mapload) . = ..() AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm index e2f83677d8..2919c6d070 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm @@ -56,7 +56,7 @@ ..() playsound(src.loc, 'sound/items/bikehorn.ogg', 50, TRUE) -/mob/living/simple_animal/hostile/retaliate/clown/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/retaliate/clown/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(banana_time && banana_time < world.time) @@ -85,7 +85,7 @@ emote_see = list("bubbles", "oozes") loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/particle_effect/foam) -/mob/living/simple_animal/hostile/retaliate/clown/lube/Initialize() +/mob/living/simple_animal/hostile/retaliate/clown/lube/Initialize(mapload) . = ..() AddElement(/datum/element/snailcrawl) @@ -147,7 +147,7 @@ obj_damage = 5 loot = list(/obj/item/clothing/suit/hooded/bloated_human, /obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap) -/mob/living/simple_animal/hostile/retaliate/clown/fleshclown/Initialize() +/mob/living/simple_animal/hostile/retaliate/clown/fleshclown/Initialize(mapload) . = ..() AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm index 2433b45cc0..ea250d60ba 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm @@ -30,7 +30,7 @@ gold_core_spawnable = HOSTILE_SPAWN var/stepped_sound = 'sound/effects/huuu.ogg' -/mob/living/simple_animal/hostile/retaliate/frog/Initialize() +/mob/living/simple_animal/hostile/retaliate/frog/Initialize(mapload) . = ..() if(prob(1)) name = "rare frog" diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm index f6ab2a1a9e..a0a2b897e4 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm @@ -45,7 +45,7 @@ var/mutable_appearance/ghost_facial_hair var/random = TRUE //if you want random names for ghosts or not -/mob/living/simple_animal/hostile/retaliate/ghost/Initialize() +/mob/living/simple_animal/hostile/retaliate/ghost/Initialize(mapload) . = ..() give_hair() set_light(1, 2) // same glowing as visible player ghosts diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm index 63a796a809..92eb310595 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm @@ -9,8 +9,8 @@ else enemies -= L else if(ismecha(A)) - var/obj/mecha/M = A - if(M.occupant) + var/obj/vehicle/sealed/mecha/M = A + if(LAZYLEN(M.occupants)) return A /mob/living/simple_animal/hostile/retaliate/ListTargets() @@ -31,10 +31,10 @@ if(faction_check_mob(M) && attack_same || !faction_check_mob(M)) enemies |= M else if(ismecha(A)) - var/obj/mecha/M = A - if(M.occupant) + var/obj/vehicle/sealed/mecha/M = A + if(LAZYLEN(M.occupants)) enemies |= M - enemies |= M.occupant + enemies |= M.occupants for(var/mob/living/simple_animal/hostile/retaliate/H in around) if(faction_check_mob(H) && !attack_same && !H.attack_same) diff --git a/code/modules/mob/living/simple_animal/hostile/skeleton.dm b/code/modules/mob/living/simple_animal/hostile/skeleton.dm index ebacf1edef..f576f3b9b8 100644 --- a/code/modules/mob/living/simple_animal/hostile/skeleton.dm +++ b/code/modules/mob/living/simple_animal/hostile/skeleton.dm @@ -46,7 +46,7 @@ icon_dead = "eskimo_dead" maxHealth = 55 health = 55 - weather_immunities = list("snow") + weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE) gold_core_spawnable = NO_SPAWN melee_damage_lower = 17 melee_damage_upper = 20 @@ -65,7 +65,7 @@ icon_dead = "templar_dead" maxHealth = 150 health = 150 - weather_immunities = list("snow") + weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE) speed = 2 gold_core_spawnable = NO_SPAWN speak_chance = 1 @@ -86,7 +86,7 @@ speed = 5 maxHealth = 75 health = 75 - weather_immunities = list("snow") + weather_immunities = list(TRAIT_SNOWSTORM_IMMUNE) color = rgb(114,228,250) loot = list(/obj/effect/decal/remains/human{color = rgb(114,228,250)}) @@ -123,6 +123,6 @@ attack_sound = 'sound/weapons/sonic_jackhammer.ogg' loot = list(/obj/effect/decal/remains/plasma, /obj/item/pickaxe/drill/jackhammer) -/mob/living/simple_animal/hostile/skeleton/plasmaminer/Initialize() +/mob/living/simple_animal/hostile/skeleton/plasmaminer/Initialize(mapload) . = ..() set_light(2) diff --git a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm index 5722cfda07..53e4d0d64f 100644 --- a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm @@ -49,6 +49,8 @@ mob_size = MOB_SIZE_LARGE armour_penetration = 30 pixel_x = -16 + maptext_height = 64 + maptext_width = 64 turns_per_move = 5 movement_type = FLYING health_doll_icon = "spacedragon" @@ -99,7 +101,7 @@ if(!chosen_color) dragon_name() color_selection() - + /mob/living/simple_animal/hostile/space_dragon/Life() . = ..() @@ -109,7 +111,7 @@ continue playsound(src, 'sound/effects/splat.ogg', 50, TRUE) visible_message("[src] vomits up [consumed_mob]!") - consumed_mob.forceMove(loc) + consumed_mob.forceMove(get_turf(src)) consumed_mob.Paralyze(50) if((rifts_charged == 3 || (SSshuttle.emergency.mode == SHUTTLE_DOCKED && rifts_charged > 0)) && !objective_complete) victory() @@ -123,6 +125,7 @@ to_chat(src, "You've failed to summon the rift in a timely manner! You're being pulled back from whence you came!") destroy_rifts() playsound(src, 'sound/magic/demon_dies.ogg', 100, TRUE) + empty_contents() QDEL_NULL(src) /mob/living/simple_animal/hostile/space_dragon/AttackingTarget() @@ -157,8 +160,8 @@ adjustHealth(-L.maxHealth * 0.5) return . = ..() - if(istype(target, /obj/mecha)) - var/obj/mecha/M = target + if(istype(target, /obj/vehicle/sealed/mecha)) + var/obj/vehicle/sealed/mecha/M = target M.take_damage(50, BRUTE, MELEE, 1) /mob/living/simple_animal/hostile/space_dragon/AltClickOn(atom/A) @@ -321,7 +324,7 @@ L.adjustFireLoss(30) to_chat(L, "You're hit by [src]'s fire breath!") // deals damage to mechs - for(var/obj/mecha/M in T.contents) + for(var/obj/vehicle/sealed/mecha/M in T.contents) if(M in hit_list) continue hit_list += M @@ -351,7 +354,7 @@ */ /mob/living/simple_animal/hostile/space_dragon/proc/empty_contents() for(var/atom/movable/AM in src) - AM.forceMove(loc) + AM.forceMove(get_turf(src)) if(prob(90)) step(AM, pick(GLOB.alldirs)) @@ -455,7 +458,7 @@ var/dir_to_target = get_dir(get_turf(src), get_turf(L)) var/throwtarget = get_edge_target_turf(target, dir_to_target) L.safe_throw_at(throwtarget, 10, 1, src) - L.Paralyze(50) + L.drop_all_held_items() addtimer(CALLBACK(src, .proc/reset_status), 4 + ((tiredness * tiredness_mult) / 10)) tiredness = tiredness + (gust_tiredness * tiredness_mult) diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm index 600d60eb4d..9356c962fd 100644 --- a/code/modules/mob/living/simple_animal/hostile/statue.dm +++ b/code/modules/mob/living/simple_animal/hostile/statue.dm @@ -81,7 +81,7 @@ return 0 return ..() -/mob/living/simple_animal/hostile/statue/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/statue/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!client && target) // If we have a target and we're AI controlled diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index df73516337..01f6b72128 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -62,7 +62,7 @@ speed = 1 spacewalk = TRUE -/mob/living/simple_animal/hostile/syndicate/space/Initialize() +/mob/living/simple_animal/hostile/syndicate/space/Initialize(mapload) . = ..() set_light(4) @@ -98,7 +98,7 @@ speed = 1 spacewalk = TRUE -/mob/living/simple_animal/hostile/syndicate/melee/space/Initialize() +/mob/living/simple_animal/hostile/syndicate/melee/space/Initialize(mapload) . = ..() set_light(4) @@ -122,7 +122,7 @@ status_flags = 0 var/obj/effect/light_emitter/red_energy_sword/sord -/mob/living/simple_animal/hostile/syndicate/melee/sword/Initialize() +/mob/living/simple_animal/hostile/syndicate/melee/sword/Initialize(mapload) . = ..() set_light(2) @@ -147,7 +147,7 @@ speed = 1 spacewalk = TRUE -/mob/living/simple_animal/hostile/syndicate/melee/sword/space/Initialize() +/mob/living/simple_animal/hostile/syndicate/melee/sword/space/Initialize(mapload) . = ..() sord = new(src) set_light(4) @@ -192,7 +192,7 @@ speed = 1 spacewalk = TRUE -/mob/living/simple_animal/hostile/syndicate/ranged/space/Initialize() +/mob/living/simple_animal/hostile/syndicate/ranged/space/Initialize(mapload) . = ..() set_light(4) @@ -225,7 +225,7 @@ speed = 1 spacewalk = TRUE -/mob/living/simple_animal/hostile/syndicate/ranged/smg/space/Initialize() +/mob/living/simple_animal/hostile/syndicate/ranged/smg/space/Initialize(mapload) . = ..() set_light(4) @@ -255,7 +255,7 @@ speed = 1 spacewalk = TRUE -/mob/living/simple_animal/hostile/syndicate/ranged/shotgun/space/Initialize() +/mob/living/simple_animal/hostile/syndicate/ranged/shotgun/space/Initialize(mapload) . = ..() set_light(4) @@ -309,6 +309,6 @@ del_on_death = 1 deathmessage = "is smashed into pieces!" -/mob/living/simple_animal/hostile/viscerator/Initialize() +/mob/living/simple_animal/hostile/viscerator/Initialize(mapload) . = ..() AddComponent(/datum/component/swarming) diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm index 978d58339d..9f53c11df3 100644 --- a/code/modules/mob/living/simple_animal/hostile/tree.dm +++ b/code/modules/mob/living/simple_animal/hostile/tree.dm @@ -44,7 +44,7 @@ gold_core_spawnable = HOSTILE_SPAWN del_on_death = 1 -/mob/living/simple_animal/hostile/tree/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/tree/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(isopenturf(loc)) diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm index cc5b0b8a75..e724da5cc3 100644 --- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm +++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm @@ -20,7 +20,7 @@ /// The amount of time it takes to create a venus human trap, in deciseconds var/growth_time = 1200 -/obj/structure/alien/resin/flower_bud_enemy/Initialize() +/obj/structure/alien/resin/flower_bud_enemy/Initialize(mapload) . = ..() var/list/anchors = list() anchors += locate(x-2,y+2,z) @@ -100,7 +100,7 @@ /mob/living/simple_animal/hostile/venus_human_trap/ghost_playable playable_plant = TRUE //For admins that want to buss some harmless plants -/mob/living/simple_animal/hostile/venus_human_trap/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/venus_human_trap/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return pull_vines() diff --git a/code/modules/mob/living/simple_animal/hostile/wizard.dm b/code/modules/mob/living/simple_animal/hostile/wizard.dm index 59bd67e42a..97f4a0a5fc 100644 --- a/code/modules/mob/living/simple_animal/hostile/wizard.dm +++ b/code/modules/mob/living/simple_animal/hostile/wizard.dm @@ -37,7 +37,7 @@ footstep_type = FOOTSTEP_MOB_SHOE -/mob/living/simple_animal/hostile/wizard/Initialize() +/mob/living/simple_animal/hostile/wizard/Initialize(mapload) . = ..() fireball = new /obj/effect/proc_holder/spell/aimed/fireball fireball.clothes_req = NONE diff --git a/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm b/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm index f10b184a45..33b9be4757 100644 --- a/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm +++ b/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm @@ -38,7 +38,7 @@ var/datum/action/innate/fugu/expand/E loot = list(/obj/item/fugu_gland{layer = ABOVE_MOB_LAYER}) -/mob/living/simple_animal/hostile/asteroid/fugu/Initialize() +/mob/living/simple_animal/hostile/asteroid/fugu/Initialize(mapload) . = ..() E = new E.Grant(src) @@ -47,7 +47,7 @@ QDEL_NULL(E) return ..() -/mob/living/simple_animal/hostile/asteroid/fugu/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/hostile/asteroid/fugu/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!wumbo) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index bd45c482a2..0c24dd36fa 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -44,6 +44,10 @@ emote_hear = list("squawks.","bawks!") emote_see = list("flutters its wings.") + vocal_bark_id = "banjoc4" + vocal_pitch = 1.4 + vocal_pitch_range = 0.4 + speak_chance = 1 //1% (1 in 100) chance every tick; So about once per 150 seconds, assuming an average tick is 1.5s turns_per_move = 5 butcher_results = list(/obj/item/reagent_containers/food/snacks/cracker/ = 1) @@ -80,7 +84,7 @@ var/speech_shuffle_rate = 20 var/list/available_channels = list() - //Headset for Poly to yell at engineers :) + //Headset for Polly to yell at engineers :) var/obj/item/radio/headset/ears = null /// spawns with headset var/spawns_with_headset = FALSE @@ -104,7 +108,7 @@ var/obj/item/held_item = null -/mob/living/simple_animal/parrot/Initialize() +/mob/living/simple_animal/parrot/Initialize(mapload) . = ..() if(spawns_with_headset) if(!ears) @@ -124,6 +128,9 @@ /mob/living/simple_animal/parrot/proc/toggle_mode, /mob/living/simple_animal/parrot/proc/perch_mob_player)) +/mob/living/simple_animal/parrot/ComponentInitialize() + . = ..() + AddElement(/datum/element/strippable, GLOB.strippable_parrot_items) /mob/living/simple_animal/parrot/examine(mob/user) . = ..() @@ -183,91 +190,101 @@ return 0 -/* - * Inventory - */ -/mob/living/simple_animal/parrot/show_inv(mob/user) - user.set_machine(src) +GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( + /datum/strippable_item/parrot_headset, +))) - var/dat = "

    Inventory of [name]

    " - dat += "
    Headset: [ears]" : "add_inv=ears'>Nothing"]" +/datum/strippable_item/parrot_headset + key = STRIPPABLE_ITEM_PARROT_HEADSET - user << browse(dat, "window=mob[REF(src)];size=325x500") - onclose(user, "window=mob[REF(src)]") +/datum/strippable_item/parrot_headset/get_item(atom/source) + var/mob/living/simple_animal/parrot/parrot_source = source + return istype(parrot_source) ? parrot_source.ears : null +/datum/strippable_item/parrot_headset/try_equip(atom/source, obj/item/equipping, mob/user) + . = ..() + if (!.) + return FALSE -/mob/living/simple_animal/parrot/Topic(href, href_list) - if(!(iscarbon(usr) || iscyborg(usr)) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) - usr << browse(null, "window=mob[REF(src)]") - usr.unset_machine() + if (!istype(equipping, /obj/item/radio/headset)) + to_chat(user, "[equipping] won't fit!") + return FALSE + + return TRUE + +// There is no delay for putting a headset on a parrot. +/datum/strippable_item/parrot_headset/start_equip(atom/source, obj/item/equipping, mob/user) + if(get_obscuring(source) == STRIPPABLE_OBSCURING_COMPLETELY) + return FALSE + return TRUE + +/datum/strippable_item/parrot_headset/finish_equip(atom/source, obj/item/equipping, mob/user) + if(!..()) + return FALSE + var/obj/item/radio/headset/radio = equipping + if (!istype(radio)) + return FALSE + + var/mob/living/simple_animal/parrot/parrot_source = source + if (!istype(parrot_source)) + return FALSE + + if (!user.transferItemToLoc(radio, source)) + return FALSE + + parrot_source.ears = radio + + to_chat(user, "You fit [radio] onto [source].") + + parrot_source.available_channels.Cut() + + for (var/channel in radio.channels) + var/channel_to_add + + switch (channel) + if (RADIO_CHANNEL_ENGINEERING) + channel_to_add = RADIO_TOKEN_ENGINEERING + if (RADIO_CHANNEL_COMMAND) + channel_to_add = RADIO_TOKEN_COMMAND + if (RADIO_CHANNEL_SECURITY) + channel_to_add = RADIO_TOKEN_SECURITY + if (RADIO_CHANNEL_SCIENCE) + channel_to_add = RADIO_TOKEN_SCIENCE + if (RADIO_CHANNEL_MEDICAL) + channel_to_add = RADIO_TOKEN_MEDICAL + if (RADIO_CHANNEL_SUPPLY) + channel_to_add = RADIO_TOKEN_SUPPLY + if (RADIO_CHANNEL_SERVICE) + channel_to_add = RADIO_TOKEN_SERVICE + + if (channel_to_add) + parrot_source.available_channels += channel_to_add + + if (radio.translate_binary) + parrot_source.available_channels.Add(MODE_TOKEN_BINARY) + +/datum/strippable_item/parrot_headset/start_unequip(atom/source, mob/user) + . = ..() + if (!.) + return FALSE + + var/mob/living/simple_animal/parrot/parrot_source = source + if (!istype(parrot_source)) return - //Removing from inventory - if(href_list["remove_inv"]) - var/remove_from = href_list["remove_inv"] - switch(remove_from) - if("ears") - if(!ears) - to_chat(usr, "There is nothing to remove from its [remove_from]!") - return - if(!stat) - say("[available_channels.len ? "[pick(available_channels)] " : null]BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") - ears.forceMove(drop_location()) - ears = null - for(var/possible_phrase in speak) - if(copytext_char(possible_phrase, 2, 3) in GLOB.department_radio_keys) - possible_phrase = copytext_char(possible_phrase, 3) + if (!parrot_source.stat) + parrot_source.say("[parrot_source.available_channels.len ? "[pick(parrot_source.available_channels)] " : null]BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") - //Adding things to inventory - else if(href_list["add_inv"]) - var/add_to = href_list["add_inv"] - if(!usr.get_active_held_item()) - to_chat(usr, "You have nothing in your hand to put on its [add_to]!") - return - switch(add_to) - if("ears") - if(ears) - to_chat(usr, "It's already wearing something!") - return - else - var/obj/item/item_to_add = usr.get_active_held_item() - if(!item_to_add) - return + return TRUE - if( !istype(item_to_add, /obj/item/radio/headset) ) - to_chat(usr, "This object won't fit!") - return - - var/obj/item/radio/headset/headset_to_add = item_to_add - - if(!usr.transferItemToLoc(headset_to_add, src)) - return - ears = headset_to_add - to_chat(usr, "You fit the headset onto [src].") - - clearlist(available_channels) - for(var/ch in headset_to_add.channels) - switch(ch) - if(RADIO_CHANNEL_ENGINEERING) - available_channels.Add(RADIO_TOKEN_ENGINEERING) - if(RADIO_CHANNEL_COMMAND) - available_channels.Add(RADIO_TOKEN_COMMAND) - if(RADIO_CHANNEL_SECURITY) - available_channels.Add(RADIO_TOKEN_SECURITY) - if(RADIO_CHANNEL_SCIENCE) - available_channels.Add(RADIO_TOKEN_SCIENCE) - if(RADIO_CHANNEL_MEDICAL) - available_channels.Add(RADIO_TOKEN_MEDICAL) - if(RADIO_CHANNEL_SUPPLY) - available_channels.Add(RADIO_TOKEN_SUPPLY) - if(RADIO_CHANNEL_SERVICE) - available_channels.Add(RADIO_TOKEN_SERVICE) - - if(headset_to_add.translate_binary) - available_channels.Add(MODE_TOKEN_BINARY) - else - return ..() +/datum/strippable_item/parrot_headset/finish_unequip(atom/source, mob/user) + ..() + var/mob/living/simple_animal/parrot/parrot_source = source + if (!istype(parrot_source)) + return + finish_unequip_mob(parrot_source.ears, parrot_source, user) + parrot_source.ears = null /* * Attack responces @@ -332,7 +349,7 @@ parrot_state |= PARROT_FLEE icon_state = icon_living drop_held_item(0) - else if(istype(O, /obj/item/reagent_containers/food/snacks/cracker)) //Poly wants a cracker. + else if(istype(O, /obj/item/reagent_containers/food/snacks/cracker)) //Polly wants a cracker. qdel(O) if(health < maxHealth) adjustBruteLoss(-10) @@ -359,7 +376,7 @@ /* * AI - Not really intelligent, but I'm calling it AI anyway. */ -/mob/living/simple_animal/parrot/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/parrot/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return //Sprite update for when a parrot gets pulled @@ -642,7 +659,7 @@ item = I break if(item) - if(!AStar(src, get_turf(item), /turf/proc/Distance_cardinal)) + if(!get_path_to(src, item)) item = null continue return item @@ -877,10 +894,10 @@ /* * Sub-types */ -/mob/living/simple_animal/parrot/Poly - name = "Poly" - desc = "Poly the Parrot. An expert on quantum cracker theory." - speak = list("Poly wanna cracker!", ":e Check the crystal, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN HARDSUITS?",":e OH GOD ITS ABOUT TO DELAMINATE CALL THE SHUTTLE") +/mob/living/simple_animal/parrot/Polly + name = "Polly" + desc = "Polly the Parrot. An expert on quantum cracker theory." + speak = list("Polly wanna cracker!", ":e Check the crystal, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN HARDSUITS?",":e OH GOD ITS ABOUT TO DELAMINATE CALL THE SHUTTLE") gold_core_spawnable = NO_SPAWN speak_chance = 3 spawns_with_headset = TRUE @@ -889,7 +906,7 @@ var/longest_survival = 0 var/longest_deathstreak = 0 -/mob/living/simple_animal/parrot/Poly/Initialize() +/mob/living/simple_animal/parrot/Polly/Initialize(mapload) ears = new /obj/item/radio/headset/headset_eng(src) available_channels = list(":e") Read_Memory() @@ -897,11 +914,13 @@ speak += pick("...[longest_survival].", "The things I've seen!", "I have lived many lives!", "What are you before me?") desc += " Old as sin, and just as loud. Claimed to be [rounds_survived]." speak_chance = 20 //His hubris has made him more annoying/easier to justify killing - add_atom_colour("#EEEE22", FIXED_COLOUR_PRIORITY) + if(!color) + add_atom_colour("#EEEE22", FIXED_COLOUR_PRIORITY) else if(rounds_survived == longest_deathstreak) speak += pick("What are you waiting for!", "Violence breeds violence!", "Blood! Blood!", "Strike me down if you dare!") desc += " The squawks of [-rounds_survived] dead parrots ring out in your ears..." - add_atom_colour("#BB7777", FIXED_COLOUR_PRIORITY) + if(!color) + add_atom_colour("#BB7777", FIXED_COLOUR_PRIORITY) else if(rounds_survived > 0) speak += pick("...again?", "No, It was over!", "Let me out!", "It never ends!") desc += " Over [rounds_survived] shifts without a \"terrible\" \"accident\"!" @@ -910,30 +929,31 @@ . = ..() -/mob/living/simple_animal/parrot/Poly/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null) +/mob/living/simple_animal/parrot/Polly/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null) . = ..() - if(. && !client && prob(1) && prob(1)) //Only the one true bird may speak across dimensions. - world.TgsTargetedChatBroadcast("A stray squawk is heard... \"[message]\"", FALSE) + if(. && !client && prob(1) && prob(1) && CONFIG_GET(string/chat_squawk_tag)) //Only the one true bird may speak across dimensions. + send2chat("A stray squawk is heard... \"[message]\"", CONFIG_GET(string/chat_squawk_tag)) -/mob/living/simple_animal/parrot/Poly/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/parrot/Polly/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved) Write_Memory(FALSE) memory_saved = TRUE -/mob/living/simple_animal/parrot/Poly/death(gibbed) +/mob/living/simple_animal/parrot/Polly/death(gibbed) if(!memory_saved) Write_Memory(TRUE) if(rounds_survived == longest_survival || rounds_survived == longest_deathstreak || prob(0.666)) - var/mob/living/simple_animal/parrot/Poly/ghost/G = new(loc) + var/mob/living/simple_animal/parrot/Polly/ghost/G = new(loc) if(mind) mind.transfer_to(G) else transfer_ckey(G) ..(gibbed) -/mob/living/simple_animal/parrot/Poly/proc/Read_Memory() +/mob/living/simple_animal/parrot/Polly/proc/Read_Memory() + var/saved_color if(fexists("data/npc_saves/Poly.sav")) //legacy compatability to convert old format to new var/savefile/S = new /savefile("data/npc_saves/Poly.sav") S["phrases"] >> speech_buffer @@ -950,10 +970,13 @@ rounds_survived = json["roundssurvived"] longest_survival = json["longestsurvival"] longest_deathstreak = json["longestdeathstreak"] + saved_color = json["color"] if(!islist(speech_buffer)) speech_buffer = list() + if(!isnull(saved_color)) + add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY) -/mob/living/simple_animal/parrot/Poly/proc/Write_Memory(dead) +/mob/living/simple_animal/parrot/Polly/proc/Write_Memory(dead) var/json_file = file("data/npc_saves/Poly.json") var/list/file_data = list() if(islist(speech_buffer)) @@ -965,6 +988,7 @@ file_data["longestdeathstreak"] = rounds_survived - 1 else file_data["longestdeathstreak"] = longest_deathstreak + file_data["color"] = null else file_data["roundssurvived"] = rounds_survived + 1 if(rounds_survived + 1 > longest_survival) @@ -972,17 +996,21 @@ else file_data["longestsurvival"] = longest_survival file_data["longestdeathstreak"] = longest_deathstreak + if(color) + file_data["color"] = json_encode(color) + else + file_data["color"] = null fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) -/mob/living/simple_animal/parrot/Poly/ratvar_act() +/mob/living/simple_animal/parrot/Polly/ratvar_act() playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 75, TRUE) var/mob/living/simple_animal/parrot/clock_hawk/H = new(loc) H.setDir(dir) qdel(src) -/mob/living/simple_animal/parrot/Poly/ghost - name = "The Ghost of Poly" +/mob/living/simple_animal/parrot/Polly/ghost + name = "The Ghost of Polly" desc = "Doomed to squawk the Earth." color = "#FFFFFF" alpha = 77 @@ -991,16 +1019,16 @@ incorporeal_move = INCORPOREAL_MOVE_BASIC butcher_results = list(/obj/item/ectoplasm = 1) -/mob/living/simple_animal/parrot/Poly/ghost/Initialize() +/mob/living/simple_animal/parrot/Polly/ghost/Initialize(mapload) memory_saved = TRUE //At this point nothing is saved . = ..() -/mob/living/simple_animal/parrot/Poly/ghost/handle_automated_speech() +/mob/living/simple_animal/parrot/Polly/ghost/handle_automated_speech() if(ismob(loc)) return ..() -/mob/living/simple_animal/parrot/Poly/ghost/handle_automated_movement() +/mob/living/simple_animal/parrot/Polly/ghost/handle_automated_movement() if(isliving(parrot_interest)) if(!ishuman(parrot_interest)) parrot_interest = null @@ -1009,7 +1037,7 @@ Possess(parrot_interest) ..() -/mob/living/simple_animal/parrot/Poly/ghost/proc/Possess(mob/living/carbon/human/H) +/mob/living/simple_animal/parrot/Polly/ghost/proc/Possess(mob/living/carbon/human/H) if(!ishuman(H)) return var/datum/disease/parrot_possession/P = new diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 65c553b11d..f226a911d8 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -56,6 +56,9 @@ var/minbodytemp = 250 var/maxbodytemp = 350 + /// List of weather immunity traits that are then added on Initialize(), see traits.dm. + var/list/weather_immunities + ///Healable by medical stacks? Defaults to yes. var/healable = 1 @@ -151,7 +154,7 @@ //Generic flags var/simple_mob_flags = NONE -/mob/living/simple_animal/Initialize() +/mob/living/simple_animal/Initialize(mapload) . = ..() GLOB.simple_animals[AIStatus] += src if(gender == PLURAL) @@ -165,6 +168,8 @@ AddComponent(/datum/component/personal_crafting) if(footstep_type) AddComponent(/datum/component/footstep, footstep_type) + for(var/trait in weather_immunities) + ADD_TRAIT(src, trait, ROUNDSTART_TRAIT) /mob/living/simple_animal/Destroy() GLOB.simple_animals[AIStatus] -= src @@ -195,12 +200,6 @@ stat = CONSCIOUS med_hud_set_status() - -/mob/living/simple_animal/handle_status_effects() - ..() - if(stuttering) - stuttering = 0 - /mob/living/simple_animal/proc/handle_automated_action() set waitfor = FALSE return @@ -231,7 +230,7 @@ length += emote_see.len var/randomValue = rand(1,length) if(randomValue <= speak.len) - say(pick(speak), forced = "poly") + say(pick(speak), forced = "polly") else randomValue -= speak.len if(emote_see && randomValue <= emote_see.len) @@ -239,7 +238,7 @@ else emote("me [pick(emote_hear)]", 2) else - say(pick(speak), forced = "poly") + say(pick(speak), forced = "polly") else if(!(emote_hear && emote_hear.len) && (emote_see && emote_see.len)) emote("me", EMOTE_VISIBLE, pick(emote_see)) @@ -313,11 +312,16 @@ if((bodytemperature < minbodytemp) || (bodytemperature > maxbodytemp)) adjustHealth(unsuitable_atmos_damage) -/mob/living/simple_animal/gib() - if(butcher_results) +/mob/living/simple_animal/gib(no_brain, no_organs, no_bodyparts, datum/explosion/was_explosion) + if(butcher_results || guaranteed_butcher_results) + var/list/butcher = list() + if(butcher_results) + butcher += butcher_results + if(guaranteed_butcher_results) + butcher += guaranteed_butcher_results var/atom/Tsec = drop_location() - for(var/path in butcher_results) - for(var/i in 1 to butcher_results[path]) + for(var/path in butcher) + for(var/i in 1 to butcher[path]) new path(Tsec) ..() @@ -395,8 +399,8 @@ if(L.stat != CONSCIOUS) return FALSE if (ismecha(the_target)) - var/obj/mecha/M = the_target - if (M.occupant) + var/obj/vehicle/sealed/mecha/M = the_target + if(LAZYLEN(M.occupants)) return FALSE return TRUE @@ -483,7 +487,7 @@ update_action_buttons_icon() return mobility_flags -/mob/living/simple_animal/update_transform() +/mob/living/simple_animal/update_transform(do_animate) var/matrix/ntransform = matrix(transform) //aka transform.Copy() var/changed = 0 diff --git a/code/modules/mob/living/simple_animal/simple_animal_vr.dm b/code/modules/mob/living/simple_animal/simple_animal_vr.dm index de5bb578b8..69dee76f34 100644 --- a/code/modules/mob/living/simple_animal/simple_animal_vr.dm +++ b/code/modules/mob/living/simple_animal/simple_animal_vr.dm @@ -49,10 +49,10 @@ // Simple animals have only one belly. This creates it (if it isn't already set up) /mob/living/simple_animal/init_vore() - ENABLE_BITFIELD(vore_flags, VORE_INIT) - if(CHECK_BITFIELD(flags_1, HOLOGRAM_1)) + vore_flags |= VORE_INIT + if((flags_1 & HOLOGRAM_1)) return - if(!vore_active || CHECK_BITFIELD(vore_flags, NO_VORE)) //If it can't vore, let's not give it a stomach. + if(!vore_active || (vore_flags & NO_VORE)) //If it can't vore, let's not give it a stomach. return if(vore_active && !IsAdvancedToolUser()) //vore active, but doesn't have thumbs to grab people with. verbs |= /mob/living/simple_animal/proc/animal_nom @@ -133,6 +133,6 @@ if (stat != CONSCIOUS) return - if(!CHECK_BITFIELD(T.vore_flags,DEVOURABLE)) + if(!(T.vore_flags & DEVOURABLE)) return return vore_attack(src,T,src) diff --git a/code/modules/mob/living/simple_animal/slime/emote.dm b/code/modules/mob/living/simple_animal/slime/emote.dm index 94f054345d..ac0ce1c1e5 100644 --- a/code/modules/mob/living/simple_animal/slime/emote.dm +++ b/code/modules/mob/living/simple_animal/slime/emote.dm @@ -27,6 +27,8 @@ /datum/emote/slime/mood/run_emote(mob/user, params) . = ..() + if(!.) + return var/mob/living/simple_animal/slime/S = user S.mood = mood S.regenerate_icons() diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm index 2ce355a0ef..274af333fc 100644 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -8,7 +8,7 @@ typing_indicator_state = /obj/effect/overlay/typing_indicator/slime -/mob/living/simple_animal/slime/BiologicalLife(seconds, times_fired) +/mob/living/simple_animal/slime/BiologicalLife(delta_time, times_fired) if(!(. = ..())) return if(buckled) diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 68de074e07..dc9d6ff6a3 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -231,11 +231,11 @@ amount = -abs(amount) return ..() //Heals them -/mob/living/simple_animal/slime/bullet_act(obj/item/projectile/Proj) +/mob/living/simple_animal/slime/bullet_act(obj/item/projectile/Proj, def_zone, piercing_hit = FALSE) attacked += 10 if((Proj.damage_type == BURN)) adjustBruteLoss(-abs(Proj.damage)) //fire projectiles heals slimes. - Proj.on_hit(src) + Proj.on_hit(src, 0, piercing_hit) return BULLET_ACT_BLOCK return ..() @@ -421,7 +421,7 @@ return /mob/living/simple_animal/slime/examine(mob/user) - . = list("*---------*\nThis is [icon2html(src, user)] \a [src]!") + . = list("This is [icon2html(src, user)] \a [src]!") if (src.stat == DEAD) . += "It is limp and unresponsive." else @@ -446,7 +446,7 @@ if(10) . += "It is radiating with massive levels of electrical activity!" - . += "*---------*" + . += "" /mob/living/simple_animal/slime/proc/discipline_slime(mob/user) if(stat) @@ -466,7 +466,7 @@ SStun = world.time + rand(20,60) spawn(0) - DISABLE_BITFIELD(mobility_flags, MOBILITY_MOVE) + mobility_flags &= ~(MOBILITY_MOVE) if(user) step_away(src,user,15) sleep(3) diff --git a/code/modules/mob/living/simple_animal/slime/slime_mobility.dm b/code/modules/mob/living/simple_animal/slime/slime_mobility.dm index 5be5ff4e36..77f2bde864 100644 --- a/code/modules/mob/living/simple_animal/slime/slime_mobility.dm +++ b/code/modules/mob/living/simple_animal/slime/slime_mobility.dm @@ -1,5 +1,5 @@ /mob/living/simple_animal/slime/update_mobility() . = ..() if(Tempstun && !buckled) - DISABLE_BITFIELD(., MOBILITY_MOVE) + . &= ~(MOBILITY_MOVE) mobility_flags = . diff --git a/code/modules/mob/living/smell.dm b/code/modules/mob/living/smell.dm new file mode 100644 index 0000000000..bc82fe5ccb --- /dev/null +++ b/code/modules/mob/living/smell.dm @@ -0,0 +1,62 @@ +#define DEFAULT_SMELL_SENSITIVITY 1 + +/mob/living + var/last_smell_time + var/last_smell_text + +/mob/living/proc/get_smell_sensitivity() + return DEFAULT_SMELL_SENSITIVITY + +/mob/living/carbon/get_smell_sensitivity() + . = DEFAULT_SMELL_SENSITIVITY + var/obj/item/organ/lungs/lungs = getorganslot(ORGAN_SLOT_LUNGS) // don't think about it too hard + if(istype(lungs)) + . = lungs.smell_sensitivity + if(HAS_TRAIT(src, TRAIT_ANOSMIA)) + . *= 0 + else if(HAS_TRAIT(src, TRAIT_GOODSMELL)) + . *= 2 + +/mob/living/proc/smell(datum/gas_mixture/from) + if(last_smell_time + 50 > world.time) + return FALSE + var/smell_sensitivity = get_smell_sensitivity() + + if(smell_sensitivity == 0) + return FALSE + + var/pressure = from.return_pressure() + var/total_moles = from.total_moles() + + #define PP_MOLES(X) ((X / total_moles) * pressure) + + #define PP(air, gas) PP_MOLES(air.get_moles(gas)) + + var/list/odors = GLOB.gas_data.odors + var/list/odor_strengths = GLOB.gas_data.odor_strengths + var/list/odors_found = list() + for(var/gas in from.get_gases()) + if(!(gas in odors)) + continue + var/pp = PP(from, gas) + var/strength = (odor_strengths[gas] / smell_sensitivity) + if(pp > 2*strength) + odors_found += "[odors[gas]]" + else if(pp > strength) + odors_found += "a hint of [odors[gas]]" + if(!length(odors_found)) + return FALSE + var/text_output = "" + if(hallucination > 50 && prob(25)) + text_output = pick("", "spiders","dreams","nightmares","the future","the past","victory",\ + "defeat","pain","bliss","chaos","revenge","cold","rotten glass","poison","time","space","death","life","truth","lies","justice","memory",\ + "regrets","your soul","suffering","magic","music","noise","blood","hunger","the american way") + else + text_output = english_list(odors_found, "something indescribable") + if(text_output != last_smell_text || last_smell_time + 100 < world.time) + to_chat(src, "You can smell [text_output].") + last_smell_time = world.time + last_smell_text = text_output + + #undef PP_MOLES + #undef PP diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index 02e88e3741..498ca19a39 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -599,7 +599,7 @@ /mob/living/proc/become_nearsighted(source) if(!HAS_TRAIT(src, TRAIT_NEARSIGHT)) - overlay_fullscreen("nearsighted", /atom/movable/screen/fullscreen/impaired, 1) + overlay_fullscreen("nearsighted", /atom/movable/screen/fullscreen/scaled/impaired, 1) ADD_TRAIT(src, TRAIT_NEARSIGHT, source) /mob/living/proc/cure_husk(source) diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm index 9ade9f097f..3c50cc2024 100644 --- a/code/modules/mob/living/ventcrawling.dm +++ b/code/modules/mob/living/ventcrawling.dm @@ -53,7 +53,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list( if(vent_found_parent && (vent_found_parent.members.len || vent_found_parent.other_atmosmch)) visible_message("[src] begins climbing into the ventilation system..." ,"You begin climbing into the ventilation system...") - if(!do_after(src, 25, target = vent_found, required_mobility_flags = MOBILITY_MOVE)) + if(!do_after(src, 25, target = vent_found)) return if(!client) diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 2ed0bfa9d2..a49df9522b 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -1,5 +1,32 @@ +/** + * Run when a client is put in this mob or reconnets to byond and their client was on this mob + * + * Things it does: + * * Adds player to player_list + * * sets lastKnownIP + * * sets computer_id + * * logs the login + * * tells the world to update it's status (for player count) + * * create mob huds for the mob if needed + * * reset next_move to 1 + * * parent call + * * if the client exists set the perspective to the mob loc + * * call on_log on the loc (sigh) + * * reload the huds for the mob + * * reload all full screen huds attached to this mob + * * load any global alternate apperances + * * sync the mind datum via sync_mind() + * * call any client login callbacks that exist + * * grant any actions the mob has to the client + * * calls [auto_deadmin_on_login](mob.html#proc/auto_deadmin_on_login) + * * send signal COMSIG_MOB_CLIENT_LOGIN + * * attaches the ash listener element so clients can hear weather + * client can be deleted mid-execution of this proc, chiefly on parent calls, with lag + */ /mob/Login() - GLOB.player_list |= src + if(!client) + return FALSE + add_to_player_list() lastKnownIP = client.address computer_id = client.computer_id log_access("Mob Login: [key_name(src)] was assigned to a [type]") @@ -15,6 +42,14 @@ . = ..() + if(!client) + return FALSE + + // SEND_SIGNAL(src, COMSIG_MOB_LOGIN) + + if (key != client.key) + key = client.key + reset_perspective(loc) if(loc) @@ -23,10 +58,6 @@ //readd this mob's HUDs (antag, med, etc) reload_huds() - reload_fullscreen() // Reload any fullscreen overlays this mob has. - - add_click_catcher() - sync_mind() //Reload alternate appearances @@ -48,11 +79,31 @@ for(var/foo in client.player_details.post_login_callbacks) var/datum/callback/CB = foo CB.Invoke() + auto_deadmin_on_login() mind?.hide_ckey = client?.prefs?.hide_ckey log_message("Client [key_name(src)] has taken ownership of mob [src]([src.type])", LOG_OWNERSHIP) SEND_SIGNAL(src, COMSIG_MOB_CLIENT_LOGIN, client) + client.init_verbs() if(has_field_of_vision && CONFIG_GET(flag/use_field_of_vision)) LoadComponent(/datum/component/field_of_vision, field_of_vision_type) + + // load rendering + reload_rendering() + + AddElement(/datum/element/weather_listener, /datum/weather/ash_storm, ZTRAIT_ASHSTORM, GLOB.ash_storm_sounds) + + // optimized area sound effects. Enable during events (compile flag when 😳) + // AddElement(/datum/element/weather_listener, /datum/weather/long_rain, ZTRAIT_STATION, GLOB.rain_sounds) + +/mob/proc/auto_deadmin_on_login() //return true if they're not an admin at the end. + if(!client?.holder) + return TRUE + if(CONFIG_GET(flag/auto_deadmin_players) || (client.prefs?.deadmin & DEADMIN_ALWAYS)) + return client.holder.auto_deadmin() + if(mind.has_antag_datum(/datum/antagonist) && (CONFIG_GET(flag/auto_deadmin_antagonists) || client.prefs?.deadmin & DEADMIN_ANTAGONIST)) + return client.holder.auto_deadmin() + if(job) + return SSjob.handle_auto_deadmin_roles(client, job) diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm index 536eacca7d..d26d562a46 100644 --- a/code/modules/mob/logout.dm +++ b/code/modules/mob/logout.dm @@ -3,8 +3,7 @@ log_message("[key_name(src)] is no longer owning mob [src]([src.type])", LOG_OWNERSHIP) SStgui.on_logout(src) unset_machine() - GLOB.player_list -= src - + remove_from_player_list() ..() if(loc) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index efb4512bca..f80866d97e 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1,33 +1,9 @@ -/mob/Destroy()//This makes sure that mobs with clients/keys are not just deleted from the game. - GLOB.mob_list -= src - GLOB.dead_mob_list -= src - GLOB.alive_mob_list -= src - GLOB.all_clockwork_mobs -= src - GLOB.mob_directory -= tag - focus = null - LAssailant = null - movespeed_modification = null - for (var/alert in alerts) - clear_alert(alert, TRUE) - if(observers && observers.len) - for(var/M in observers) - var/mob/dead/observe = M - observe.reset_perspective(null) - qdel(hud_used) - for(var/cc in client_colours) - qdel(cc) - client_colours = null - ghostize() - ..() - return QDEL_HINT_HARDDEL - -/mob/Initialize() - GLOB.mob_list += src - GLOB.mob_directory[tag] = src +/mob/Initialize(mapload) + add_to_mob_list() if(stat == DEAD) - GLOB.dead_mob_list += src + add_to_dead_mob_list() else - GLOB.alive_mob_list += src + add_to_alive_mob_list() set_focus(src) prepare_huds() for(var/v in GLOB.active_alternate_appearances) @@ -40,8 +16,32 @@ update_config_movespeed() update_movespeed(TRUE) initialize_actionspeed() + init_rendering() hook_vr("mob_new",list(src)) +/mob/Destroy()//This makes sure that mobs with clients/keys are not just deleted from the game. + remove_from_mob_list() + remove_from_dead_mob_list() + remove_from_alive_mob_list() + GLOB.all_clockwork_mobs -= src + focus = null + LAssailant = null + movespeed_modification = null + for (var/alert in alerts) + clear_alert(alert, TRUE) + if(observers && observers.len) + for(var/M in observers) + var/mob/dead/observe = M + observe.reset_perspective(null) + dispose_rendering() + qdel(hud_used) + for(var/cc in client_colours) + qdel(cc) + client_colours = null + ghostize() + ..() + return QDEL_HINT_HARDDEL + /mob/GenerateTag() tag = "mob_[next_mob_id++]" @@ -138,7 +138,7 @@ return hearers -= ignored_mobs - if(target_message && target && istype(target) && target.client) + if(target_message && target && istype(target) && (target.client || target.audiovisual_redirect)) hearers -= target if(omni) target.show_message(target_message) @@ -155,7 +155,7 @@ if(self_message) hearers -= src for(var/mob/M in hearers) - if(!M.client) + if(!M.client && !M.audiovisual_redirect) continue if(omni) M.show_message(message) @@ -238,6 +238,7 @@ if(istype(W)) if(equip_to_slot_if_possible(W, slot, FALSE, FALSE, FALSE, FALSE, TRUE)) + W.apply_outline() return TRUE if(!W) @@ -290,9 +291,6 @@ SEND_SIGNAL(src, COMSIG_MOB_RESET_PERSPECTIVE, A) return TRUE -/mob/proc/show_inv(mob/user) - return - //view() but with a signal, to allow blacklisting some of the otherwise visible atoms. /mob/proc/fov_view(dist = world.view) . = view(dist, src) @@ -332,7 +330,7 @@ else result = A.examine(src) // if a tree is examined but no client is there to see it, did the tree ever really exist? - to_chat(src, result.Join("\n")) + to_chat(src, "

    [result.Join("\n")]
    ") SEND_SIGNAL(src, COMSIG_MOB_EXAMINATE, A) /mob/proc/clear_from_recent_examines(atom/A) @@ -441,7 +439,11 @@ set category = "IC" set desc = "View your character's notes memory." if(mind) - mind.show_memory(src) +//ambition start + var/datum/browser/popup = new(src, "memory", "Memory and Notes") + popup.set_content(mind.show_memory()) + popup.open() +//ambition end else to_chat(src, "You don't have a mind datum for some reason, so you can't look at your notes, if you had any.") @@ -509,10 +511,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) unset_machine() src << browse(null, t1) - if(href_list["refresh"]) - if(machine && in_range(src, usr)) - show_inv(machine) - if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) if(href_list["item"]) var/slot = text2num(href_list["item"]) @@ -529,12 +527,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) else usr.stripPanelEquip(what,src,slot) - if(usr.machine == src) - if(Adjacent(usr)) - show_inv(usr) - else - usr << browse(null,"window=mob[REF(src)]") - // The src mob is trying to strip an item from someone // Defined in living.dm /mob/proc/stripPanelUnequip(obj/item/what, mob/who) @@ -556,12 +548,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) if(isAI(M)) return -/mob/MouseDrop_T(atom/dropping, atom/user) - . = ..() - if(ismob(dropping) && dropping != user) - var/mob/M = dropping - M.show_inv(user) - /mob/proc/is_muzzled() return FALSE @@ -594,11 +580,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) L[++L.len] = list("[S.panel]", "[S.holder_var_type] [S.holder_var_amount]", S.name, REF(S)) return L -/mob/proc/add_stings_to_statpanel(list/stings) - for(var/obj/effect/proc_holder/changeling/S in stings) - if(S.chemical_cost >=0 && S.can_be_used_by(src)) - statpanel("[S.panel]",((S.chemical_cost > 0) ? "[S.chemical_cost]" : ""),S) - #define MOB_FACE_DIRECTION_DELAY 1 // facing verbs @@ -736,7 +717,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) return pick(protection_sources) else return src - if((magic && HAS_TRAIT(src, TRAIT_ANTIMAGIC)) || (holy && HAS_TRAIT(src, TRAIT_HOLY))) + if((magic && HAS_TRAIT(src, TRAIT_ANTIMAGIC)) || (!self && magic && HAS_TRAIT(src, TRAIT_ANTIMAGIC_NO_SELFBLOCK)) || (holy && HAS_TRAIT(src, TRAIT_HOLY))) return src //You can buckle on mobs if you're next to them since most are dense @@ -892,10 +873,12 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) if (!client) return client.mouse_pointer_icon = initial(client.mouse_pointer_icon) - if (ismecha(loc)) - var/obj/mecha/M = loc - if(M.mouse_pointer) - client.mouse_pointer_icon = M.mouse_pointer + if(istype(loc, /obj/vehicle/sealed)) + var/obj/vehicle/sealed/mecha/E = loc + if(E.mouse_pointer) + client.mouse_pointer_icon = E.mouse_pointer + if(client.mouse_override_icon) + client.mouse_pointer_icon = client.mouse_override_icon /mob/proc/is_literate() return 0 diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index b77b9913ba..138a3b9662 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -9,13 +9,17 @@ mouse_drag_pointer = MOUSE_ACTIVE_POINTER throwforce = 10 blocks_emissive = EMISSIVE_BLOCK_GENERIC - + pass_flags_self = PASSMOB vis_flags = VIS_INHERIT_PLANE //when this be added to vis_contents of something it inherit something.plane, important for visualisation of mob in openspace. attack_hand_is_action = TRUE attack_hand_unwieldlyness = CLICK_CD_MELEE attack_hand_speed = 0 + // Rendering + /// Fullscreen objects + var/list/fullscreens = list() + /// What receives our keyboard input. src by default. var/datum/focus @@ -143,7 +147,6 @@ var/registered_z var/list/alerts = list() // contains /atom/movable/screen/alert only // On /mob so clientless mobs will throw alerts properly - var/list/screens = list() var/list/client_colours = list() var/hud_type = /datum/hud @@ -180,3 +183,6 @@ ///Override for sound_environments. If this is set the user will always hear a specific type of reverb (Instead of the area defined reverb) var/sound_environment_override = SOUND_ENVIRONMENT_NONE + +/// A mock client, provided by tests and friends + var/datum/client_interface/mock_client diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 5bfc6fe652..cdad94cf3f 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -144,6 +144,7 @@ newletter = "nglu" if(5) newletter = "glor" + else . += newletter return sanitize(.) @@ -228,22 +229,38 @@ It's fairly easy to fix if dealing with single letters but not so much with comp return copytext_char(sanitize(.),1,MAX_MESSAGE_LEN) /proc/shake_camera(mob/M, duration, strength=1) - if(!M || !M.client || duration < 1) + set waitfor = FALSE + if(!M || !M.client || duration <= 0) return var/client/C = M.client + if (C.prefs.screenshake==0) + return var/oldx = C.pixel_x var/oldy = C.pixel_y - var/max = strength*world.icon_size - var/min = -(strength*world.icon_size) + var/clientscreenshake = (C.prefs.screenshake * 0.01) + var/max = (strength*clientscreenshake) * world.icon_size + var/min = -((strength*clientscreenshake) * world.icon_size) + var/roundedduration = -round(-duration) // round() with only one arg will always round down. so uh. this is Something all right - for(var/i in 0 to duration-1) + for(var/i in 0 to roundedduration-1) + duration-- if (i == 0) - animate(C, pixel_x=rand(min,max), pixel_y=rand(min,max), time=1) + animate(C, pixel_x=(rand(min,max)*duration), pixel_y=(rand(min,max)*duration), time=1) else animate(pixel_x=rand(min,max), pixel_y=rand(min,max), time=1) animate(pixel_x=oldx, pixel_y=oldy, time=1) - +/proc/directional_recoil(mob/M, strength=1, angle = 0) + if(!M || !M.client) + return + var/client/C = M.client + var/client_screenshake = (C.prefs.recoil_screenshake * 0.01) + strength *= client_screenshake + var/recoil_x = -sin(angle)*4*strength + rand(-strength, strength) + var/recoil_y = -cos(angle)*4*strength + rand(-strength, strength) + animate(C, pixel_x=recoil_x, pixel_y=recoil_y, time=1, easing=SINE_EASING|EASE_OUT, flags=ANIMATION_PARALLEL|ANIMATION_RELATIVE) + animate(pixel_x=0, pixel_y=0, time=3, easing=SINE_EASING|EASE_IN) // according to bhjin this works on more recent byond versions + // if you havent updated uuh sucks to be you then /proc/findname(msg) if(!istext(msg)) @@ -568,7 +585,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp //Can the mob see reagents inside of containers? /mob/proc/can_see_reagents() - return stat == DEAD || silicon_privileges //Dead guys and silicons can always see reagents + return stat == DEAD || silicon_privileges || HAS_TRAIT(src, TRAIT_REAGENT_SCANNER) //Dead guys and silicons can always see reagents /mob/proc/is_blind() SHOULD_BE_PURE(TRUE) diff --git a/code/modules/mob/mob_lists.dm b/code/modules/mob/mob_lists.dm new file mode 100644 index 0000000000..bd47d511e1 --- /dev/null +++ b/code/modules/mob/mob_lists.dm @@ -0,0 +1,123 @@ +///Adds the mob reference to the list and directory of all mobs. Called on Initialize(). +/mob/proc/add_to_mob_list() + GLOB.mob_list |= src + GLOB.mob_directory[tag] = src + +///Removes the mob reference from the list and directory of all mobs. Called on Destroy(). +/mob/proc/remove_from_mob_list() + GLOB.mob_list -= src + GLOB.mob_directory -= tag + +///Adds the mob reference to the list of all mobs alive. If mob is cliented, it adds it to the list of all living player-mobs. +/mob/proc/add_to_alive_mob_list() + if(QDELETED(src)) + return + GLOB.alive_mob_list |= src + if(client) + add_to_current_living_players() + +///Removes the mob reference from the list of all mobs alive. If mob is cliented, it removes it from the list of all living player-mobs. +/mob/proc/remove_from_alive_mob_list() + GLOB.alive_mob_list -= src + if(client) + remove_from_current_living_players() + + +///Adds the mob reference to the list of all the dead mobs. If mob is cliented, it adds it to the list of all dead player-mobs. +/mob/proc/add_to_dead_mob_list() + if(QDELETED(src)) + return + GLOB.dead_mob_list |= src + if(client) + add_to_current_dead_players() + +///Remvoes the mob reference from list of all the dead mobs. If mob is cliented, it adds it to the list of all dead player-mobs. +/mob/proc/remove_from_dead_mob_list() + GLOB.dead_mob_list -= src + if(client) + remove_from_current_dead_players() + + +///Adds the cliented mob reference to the list of all player-mobs, besides to either the of dead or alive player-mob lists, as appropriate. Called on Login(). +/mob/proc/add_to_player_list() + SHOULD_CALL_PARENT(TRUE) + GLOB.player_list |= src + if(!SSticker?.mode) + return + if(stat == DEAD) + add_to_current_dead_players() + else + add_to_current_living_players() + +///Removes the mob reference from the list of all player-mobs, besides from either the of dead or alive player-mob lists, as appropriate. Called on Logout(). +/mob/proc/remove_from_player_list() + SHOULD_CALL_PARENT(TRUE) + GLOB.player_list -= src + if(!SSticker?.mode) + return + if(stat == DEAD) + remove_from_current_dead_players() + else + remove_from_current_living_players() + + +///Adds the cliented mob reference to either the list of dead player-mobs or to the list of observers, depending on how they joined the game. +/mob/proc/add_to_current_dead_players() + if(!SSticker?.mode) + return + SSticker.mode.current_players[CURRENT_DEAD_PLAYERS] |= src + +/mob/dead/observer/add_to_current_dead_players() + if(!SSticker?.mode) + return + if(started_as_observer) + SSticker.mode.current_players[CURRENT_OBSERVERS] |= src + return + return ..() + +/mob/dead/new_player/add_to_current_dead_players() + return + +///Removes the mob reference from either the list of dead player-mobs or from the list of observers, depending on how they joined the game. +/mob/proc/remove_from_current_dead_players() + if(!SSticker?.mode) + return + SSticker.mode.current_players[CURRENT_DEAD_PLAYERS] -= src + +/mob/dead/observer/remove_from_current_dead_players() + if(!SSticker?.mode) + return + if(started_as_observer) + SSticker.mode.current_players[CURRENT_OBSERVERS] -= src + return + return ..() + + +///Adds the cliented mob reference to the list of living player-mobs. If the mob is an antag, it adds it to the list of living antag player-mobs. +/mob/proc/add_to_current_living_players() + if(!SSticker?.mode) + return + SSticker.mode.current_players[CURRENT_LIVING_PLAYERS] |= src + if(mind && (mind.special_role || length(mind.antag_datums))) + add_to_current_living_antags() + +///Removes the mob reference from the list of living player-mobs. If the mob is an antag, it removes it from the list of living antag player-mobs. +/mob/proc/remove_from_current_living_players() + if(!SSticker?.mode) + return + SSticker.mode.current_players[CURRENT_LIVING_PLAYERS] -= src + if(LAZYLEN(mind?.antag_datums)) + remove_from_current_living_antags() + + +///Adds the cliented mob reference to the list of living antag player-mobs. +/mob/proc/add_to_current_living_antags() + if(!SSticker?.mode) + return + SSticker.mode.current_players[CURRENT_LIVING_ANTAGS] |= src + +///Removes the mob reference from the list of living antag player-mobs. +/mob/proc/remove_from_current_living_antags() + if(!SSticker?.mode) + return + SSticker.mode.current_players[CURRENT_LIVING_ANTAGS] -= src diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index bfd4cfcd29..1da355a419 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -110,6 +110,11 @@ SEND_SIGNAL(mob, COMSIG_MOB_CLIENT_MOVE, src, direction, n, oldloc, add_delay) +/mob/Moved(atom/OldLoc, Dir) + . = ..() + if(client) + client.parallax_holder.Update() + /// Process_Grab(): checks for grab, attempts to break if so. Return TRUE to prevent movement. /client/proc/Process_Grab() if(mob.pulledby) @@ -398,3 +403,8 @@ /mob/proc/canZMove(direction, turf/target) return FALSE + +/mob/onTransitZ(old_z, new_z) + . = ..() + if(old_z != new_z) + client?.parallax_holder?.Reset() diff --git a/code/modules/mob/update_icons.dm b/code/modules/mob/mob_update_icons.dm similarity index 100% rename from code/modules/mob/update_icons.dm rename to code/modules/mob/mob_update_icons.dm diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 3b6f37184a..e39a9a976f 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -4,6 +4,7 @@ set name = "say_indicator" set hidden = TRUE set category = "IC" + client?.last_activity = world.time display_typing_indicator() var/message = input(usr, "", "say") as text|null // If they don't type anything just drop the message. @@ -21,12 +22,16 @@ to_chat(usr, "Speech is currently admin-disabled.") return clear_typing_indicator() // clear it immediately! + + client?.last_activity = world.time + say(message) /mob/verb/me_typing_indicator() set name = "me_indicator" set hidden = TRUE set category = "IC" + client?.last_activity = world.time display_typing_indicator() var/message = input(usr, "", "me") as message|null // If they don't type anything just drop the message. @@ -49,9 +54,11 @@ to_chat(usr, "^^^----- The preceeding message has been DISCARDED for being over the maximum length of [MAX_MESSAGE_LEN]. It has NOT been sent! -----^^^") return - message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) + message = trim(html_encode(message), MAX_MESSAGE_LEN) clear_typing_indicator() // clear it immediately! + client?.last_activity = world.time + usr.emote("me",1,message,TRUE) /mob/say_mod(input, message_mode) @@ -73,6 +80,7 @@ return lowertext(copytext_char(input, 1, customsayverb)) /mob/proc/whisper_keybind() + client?.last_activity = world.time var/message = input(src, "", "whisper") as text|null if(!length(message)) return @@ -89,6 +97,7 @@ whisper(message) /mob/proc/whisper(message, datum/language/language=null) + client?.last_activity = world.time say(message, language) //only living mobs actually whisper, everything else just talks /mob/proc/say_dead(var/message) @@ -130,9 +139,14 @@ var/spanned = say_quote(say_emphasis(message)) message = emoji_parse(message) - var/rendered = "DEAD: [name][alt_name] [emoji_parse(spanned)]" + var/source = "DEAD: [name][alt_name]" + var/rendered = " [emoji_parse(spanned)]" log_talk(message, LOG_SAY, tag="DEAD") - deadchat_broadcast(rendered, follow_target = src, speaker_key = key) + client?.last_activity = world.time + var/displayed_key = key + if(client?.holder?.fakekey) + displayed_key = null + deadchat_broadcast(rendered, source, follow_target = src, speaker_key = displayed_key) /mob/proc/check_emote(message) if(message[1] == "*") diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index 089484ea9f..da1919443a 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -53,7 +53,7 @@ if(eye_blind) // UNCONSCIOUS or has blind trait, or has temporary blindness if(stat == CONSCIOUS || stat == SOFT_CRIT) throw_alert("blind", /atom/movable/screen/alert/blind) - overlay_fullscreen("blind", /atom/movable/screen/fullscreen/blind) + overlay_fullscreen("blind", /atom/movable/screen/fullscreen/scaled/blind) // You are blind why should you be able to make out details like color, only shapes near you // add_client_colour(/datum/client_colour/monochrome/blind) else // CONSCIOUS no blind trait, no blindness diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index fcaa77cac4..fa9dc9f4f8 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -100,9 +100,9 @@ mind.transfer_to(O) var/datum/antagonist/changeling/changeling = O.mind.has_antag_datum(/datum/antagonist/changeling) if(changeling) - var/obj/effect/proc_holder/changeling/humanform/HF = new /obj/effect/proc_holder/changeling/humanform(null) - changeling.purchasedpowers += HF - HF.action.Grant(O) + var/datum/action/changeling/humanform/hf = new + changeling.purchasedpowers += hf + changeling.regain_powers() for(var/X in internal_organs) var/obj/item/organ/I = X @@ -135,9 +135,9 @@ mind.transfer_to(O) var/datum/antagonist/changeling/changeling = O.mind.has_antag_datum(/datum/antagonist/changeling) if(changeling) - var/obj/effect/proc_holder/changeling/humanform/HF = new /obj/effect/proc_holder/changeling/humanform(null) - changeling.purchasedpowers += HF - HF.action.Grant(O) + var/datum/action/changeling/humanform/hf = new + changeling.purchasedpowers += hf + changeling.regain_powers() if (tr_flags & TR_DEFAULTMSG) to_chat(O, "You are now a monkey.") @@ -261,8 +261,9 @@ mind.transfer_to(O) var/datum/antagonist/changeling/changeling = O.mind.has_antag_datum(/datum/antagonist/changeling) if(changeling) - for(var/obj/effect/proc_holder/changeling/humanform/HF in changeling.purchasedpowers) + for(var/datum/action/changeling/humanform/HF in changeling.purchasedpowers) changeling.purchasedpowers -= HF + changeling.regain_powers() for(var/X in internal_organs) var/obj/item/organ/I = X @@ -295,8 +296,9 @@ mind.transfer_to(O) var/datum/antagonist/changeling/changeling = O.mind.has_antag_datum(/datum/antagonist/changeling) if(changeling) - for(var/obj/effect/proc_holder/changeling/humanform/HF in changeling.purchasedpowers) + for(var/datum/action/changeling/humanform/HF in changeling.purchasedpowers) changeling.purchasedpowers -= HF + changeling.regain_powers() O.a_intent = INTENT_HELP if (tr_flags & TR_DEFAULTMSG) diff --git a/code/modules/mod/mod_actions.dm b/code/modules/mod/mod_actions.dm new file mode 100644 index 0000000000..ee28771ef1 --- /dev/null +++ b/code/modules/mod/mod_actions.dm @@ -0,0 +1,94 @@ +/datum/action/item_action/mod + background_icon_state = "bg_tech_blue" + icon_icon = 'icons/mob/actions/actions_mod.dmi' + check_flags = AB_CHECK_CONSCIOUS + var/obj/item/mod/control/mod + /// Whether this action is intended for the AI. Stuff breaks a lot if this is done differently. + var/ai_action = FALSE + +/datum/action/item_action/mod/New(Target) + ..() + if(!istype(Target, /obj/item/mod/control)) + qdel(src) + return + if(ai_action) + background_icon_state = "bg_tech" + +/datum/action/item_action/mod/Grant(mob/user) + mod = target + if(ai_action && user != mod.ai) + return + else if(!ai_action && user == mod.ai) + return + return ..() + +/datum/action/item_action/mod/Remove(mob/user) + if(ai_action && mod && user != mod.ai) + return + else if(!ai_action && mod && user == mod.ai) + return + return ..() + +/datum/action/item_action/mod/Trigger(trigger_flags) + if(!IsAvailable()) + return FALSE + if(mod.malfunctioning && prob(75)) + mod.balloon_alert(usr, "button malfunctions!") + return FALSE + return TRUE + +/datum/action/item_action/mod/deploy + name = "Deploy MODsuit" + desc = "Deploy/Conceal a part of the MODsuit." + button_icon_state = "deploy" + +/datum/action/item_action/mod/deploy/Trigger() + if(!IsAvailable()) + return FALSE + mod.choose_deploy(usr) + return TRUE + +/datum/action/item_action/mod/deploy/ai + ai_action = TRUE + +/datum/action/item_action/mod/activate + name = "Activate MODsuit" + desc = "Activate/Deactivate the MODsuit." + button_icon_state = "activate" + +/datum/action/item_action/mod/activate/Trigger() + if(!IsAvailable()) + return FALSE + mod.toggle_activate(usr) + return TRUE + +/datum/action/item_action/mod/activate/ai + ai_action = TRUE + +/datum/action/item_action/mod/module + name = "Toggle Module" + desc = "Toggle a MODsuit module." + button_icon_state = "module" + +/datum/action/item_action/mod/module/Trigger() + if(!IsAvailable()) + return FALSE + mod.quick_module(usr) + return TRUE + +/datum/action/item_action/mod/module/ai + ai_action = TRUE + +/datum/action/item_action/mod/panel + name = "MODsuit Panel" + desc = "Open the MODsuit's panel." + button_icon_state = "panel" + +/datum/action/item_action/mod/panel/Trigger() + if(!IsAvailable()) + return FALSE + mod.ui_interact(usr) + return TRUE + +/datum/action/item_action/mod/panel/ai + ai_action = TRUE diff --git a/code/modules/mod/mod_activation.dm b/code/modules/mod/mod_activation.dm new file mode 100644 index 0000000000..42e9a3dff0 --- /dev/null +++ b/code/modules/mod/mod_activation.dm @@ -0,0 +1,247 @@ +#define MOD_ACTIVATION_STEP_FLAGS IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM|IGNORE_INCAPACITATED + +/// Creates a radial menu from which the user chooses parts of the suit to deploy/retract. Repeats until all parts are extended or retracted. +/obj/item/mod/control/proc/choose_deploy(mob/user) + if(!length(mod_parts)) + return + var/list/display_names = list() + var/list/items = list() + for(var/obj/item/piece as anything in mod_parts) + display_names[piece.name] = REF(piece) + var/image/piece_image = image(icon = piece.icon, icon_state = piece.icon_state) + items += list(piece.name = piece_image) + var/pick = show_radial_menu(user, src, items, custom_check = FALSE, require_near = TRUE, tooltips = TRUE) + if(!pick) + return + var/part_reference = display_names[pick] + var/obj/item/part = locate(part_reference) in mod_parts + if(!istype(part) || user.incapacitated()) + return + if((active && part != helmet) || activating) // SKYRAT EDIT - Let the hair flow - ORIGINAL: if(active || activating) + balloon_alert(user, "deactivate the suit first!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return + var/parts_to_check = mod_parts - part + if(part.loc == src) + deploy(user, part) + for(var/obj/item/piece as anything in parts_to_check) + if(piece.loc != src) + continue + choose_deploy(user) + break + else + conceal(user, part) + for(var/obj/item/piece as anything in parts_to_check) + if(piece.loc == src) + continue + choose_deploy(user) + break + +/// Deploys a part of the suit onto the user. +/obj/item/mod/control/proc/deploy(mob/user, part) + var/obj/item/piece = part + if(piece == gauntlets && wearer.gloves) + gauntlets.overslot = wearer.gloves + wearer.transferItemToLoc(gauntlets.overslot, gauntlets, force = TRUE) + if(piece == boots && wearer.shoes) + boots.overslot = wearer.shoes + wearer.transferItemToLoc(boots.overslot, boots, force = TRUE) + if(wearer.equip_to_slot_if_possible(piece, piece.slot_flags, qdel_on_fail = FALSE, disable_warning = TRUE)) + ADD_TRAIT(piece, TRAIT_NODROP, MOD_TRAIT) + if(!user) + return TRUE + wearer.visible_message(span_notice("[wearer]'s [piece] deploy[piece.p_s()] with a mechanical hiss."), + span_notice("[piece] deploy[piece.p_s()] with a mechanical hiss."), + span_hear("You hear a mechanical hiss.")) + playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + return TRUE + else if(piece.loc != src) + if(!user) + return FALSE + balloon_alert(user, "[piece] already deployed!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + else + if(!user) + return FALSE + balloon_alert(user, "bodypart clothed!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return FALSE + +/// Retract a part of the suit from the user +/obj/item/mod/control/proc/conceal(mob/user, part) + var/obj/item/piece = part + REMOVE_TRAIT(piece, TRAIT_NODROP, MOD_TRAIT) + if(wearer) + wearer.transferItemToLoc(piece, src, force = TRUE) + if(piece == gauntlets) + gauntlets.show_overslot() + if(piece == boots) + boots.show_overslot() + if(!user) + return + wearer.visible_message(span_notice("[wearer]'s [piece] retract[piece.p_s()] back into [src] with a mechanical hiss."), + span_notice("[piece] retract[piece.p_s()] back into [src] with a mechanical hiss."), + span_hear("You hear a mechanical hiss.")) + playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + +/// Starts the activation sequence, where parts of the suit activate one by one until the whole suit is on +/obj/item/mod/control/proc/toggle_activate(mob/user, force_deactivate = FALSE) + if(!wearer) + if(!force_deactivate) + balloon_alert(user, "put suit on back!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return FALSE + if(!force_deactivate && (SEND_SIGNAL(src, COMSIG_MOD_ACTIVATE, user) & MOD_CANCEL_ACTIVATE)) + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return FALSE + for(var/obj/item/part as anything in mod_parts) + if(!force_deactivate && part.loc == src) + balloon_alert(user, "deploy all parts first!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return FALSE + if(!cell?.charge && !force_deactivate) + balloon_alert(user, "suit not powered!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return FALSE + if(open && !force_deactivate) + balloon_alert(user, "close the suit panel!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return FALSE + if(activating) + if(!force_deactivate) + balloon_alert(user, "suit already [active ? "shutting down" : "starting up"]!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return FALSE + for(var/obj/item/mod/module/module as anything in modules) + if(!module.active || module.allowed_inactive) + continue + module.on_deactivation() + activating = TRUE + to_chat(wearer, span_notice("MODsuit [active ? "shutting down" : "starting up"].")) + if(ai) + to_chat(ai, span_notice("MODsuit [active ? "shutting down" : "starting up"].")) + + if(force_deactivate) + seal_part(boots, seal = FALSE) + seal_part(gauntlets, seal = FALSE) + seal_part(chestplate,seal = FALSE) + seal_part(helmet, seal = FALSE) + finish_activation(on = FALSE) + activating = FALSE + to_chat(wearer, span_notice("Systems shut down. Parts unsealed. Goodbye, [wearer].")) + if(ai) + to_chat(ai, span_notice("SYSTEMS DEACTIVATED. GOODBYE: \"[ai]\"")) + playsound(src, 'sound/machines/synth_no.ogg', 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, frequency = 6000) + return TRUE + + if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer)))) + to_chat(wearer, span_notice("[boots] [active ? "relax their grip on your legs" : "seal around your feet"].")) + playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + seal_part(boots, seal = !active) + else + return toggle_activate_fail() + if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer)))) + to_chat(wearer, span_notice("[gauntlets] [active ? "become loose around your fingers" : "tighten around your fingers and wrists"].")) + playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + seal_part(gauntlets, seal = !active) + else + return toggle_activate_fail() + if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer)))) + to_chat(wearer, span_notice("[chestplate] [active ? "releases your chest" : "cinches tightly against your chest"].")) + playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + seal_part(chestplate,seal = !active) + else + return toggle_activate_fail() + if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer)))) + to_chat(wearer, span_notice("[helmet] hisses [active ? "open" : "closed"].")) + playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + seal_part(helmet, seal = !active) + else + return toggle_activate_fail() + if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer)))) + to_chat(wearer, span_notice("Systems [active ? "shut down. Parts unsealed. Goodbye" : "started up. Parts sealed. Welcome"], [wearer].")) + if(ai) + to_chat(ai, span_notice("SYSTEMS [active ? "DEACTIVATED. GOODBYE" : "ACTIVATED. WELCOME"]: \"[ai]\"")) + finish_activation(on = !active) + if(active) + playsound(src, 'sound/machines/synth_yes.ogg', 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, frequency = 6000) + SEND_SOUND(wearer, sound('sound/mecha/nominal.ogg',volume=50)) + else + playsound(src, 'sound/machines/synth_no.ogg', 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, frequency = 6000) + else + return toggle_activate_fail() + activating = FALSE + return TRUE + +/obj/item/mod/control/proc/toggle_activate_fail() + seal_part(boots, seal = active) + seal_part(gauntlets, seal = active) + seal_part(chestplate,seal = active) + seal_part(helmet, seal = active) + to_chat(wearer, span_warning("[active ? "Shut down" : "Start up"] cancelled.")) + finish_activation(on = active) + activating = FALSE + return FALSE + +///Seals or unseals the given part +/obj/item/mod/control/proc/seal_part(obj/item/clothing/part, seal) + if(seal) + part.clothing_flags |= part.visor_flags + part.flags_inv |= part.visor_flags_inv + part.flags_cover |= part.visor_flags_cover + part.heat_protection = initial(part.heat_protection) + part.cold_protection = initial(part.cold_protection) + else + part.flags_cover &= ~part.visor_flags_cover + part.flags_inv &= ~part.visor_flags_inv + part.clothing_flags &= ~part.visor_flags + part.heat_protection = NONE + part.cold_protection = NONE + part.icon_state = "[skin]-[initial(part.icon_state)][seal ? "-sealed" : ""]" + part.item_state = "[skin]-[initial(part.item_state)][seal ? "-sealed" : ""]" + if(part == boots) + wearer.update_inv_shoes() + if(part == gauntlets) + wearer.update_inv_gloves() + if(part == chestplate) + wearer.update_inv_wear_suit() + wearer.update_inv_w_uniform() + if(part == helmet) + if(seal) + helmet.alternate_worn_layer = null + else + helmet.alternate_worn_layer = helmet.alternate_layer + wearer.update_inv_head() + wearer.update_inv_wear_mask() + wearer.update_hair() + +/// Finishes the suit's activation, starts processing +/obj/item/mod/control/proc/finish_activation(on) + icon_state = "[skin]-control[on ? "-sealed" : ""]" + slowdown = on ? slowdown_active : slowdown_inactive + if(on) + for(var/obj/item/mod/module/module as anything in modules) + module.on_suit_activation() + START_PROCESSING(SSobj, src) + else + for(var/obj/item/mod/module/module as anything in modules) + module.on_suit_deactivation() + STOP_PROCESSING(SSobj, src) + wearer.update_equipment_speed_mods() + active = on + wearer.update_inv_back() + +/// Quickly deploys all the suit parts and if successful, seals them and turns on the suit. Intended mostly for outfits. +/obj/item/mod/control/proc/quick_activation() + var/seal = TRUE + for(var/obj/item/part in mod_parts) + if(!deploy(null, part)) + seal = FALSE + if(!seal) + return + for(var/obj/item/part in mod_parts) + seal_part(part, seal = TRUE) + finish_activation(on = TRUE) + +/obj/item/mod/control/proc/has_wearer() + return wearer diff --git a/code/modules/mod/mod_ai.dm b/code/modules/mod/mod_ai.dm new file mode 100644 index 0000000000..46da99f052 --- /dev/null +++ b/code/modules/mod/mod_ai.dm @@ -0,0 +1,199 @@ +/obj/item/mod/control/transfer_ai(interaction, mob/user, mob/living/silicon/ai/intAI, obj/item/aicard/card) + . = ..() + if(!.) + return + if(!open) //mod must be open + balloon_alert(user, "suit must be open to transfer!") + return + switch(interaction) + if(AI_TRANS_TO_CARD) + if(!ai) + balloon_alert(user, "no AI in suit!") + return + if(!isAI(ai)) + balloon_alert(user, "onboard AI cannot fit in this card!") + return + balloon_alert(user, "transferring to card...") + if(!do_after(user, 5 SECONDS, target = src)) + balloon_alert(user, "interrupted!") + return + if(!ai) + return + intAI = ai + intAI.ai_restore_power()//So the AI initially has power. + intAI.control_disabled = TRUE + intAI.radio_enabled = FALSE + intAI.disconnect_shell() + intAI.forceMove(card) + card.AI = intAI + for(var/datum/action/action as anything in actions) + action.Remove(intAI) + intAI.controlled_equipment = null + intAI.remote_control = null + balloon_alert(intAI, "transferred to a card") + balloon_alert(user, "AI transferred to card") + ai = null + + if(AI_TRANS_FROM_CARD) //Using an AI card to upload to the suit. + intAI = card.AI + if(!intAI) + balloon_alert(user, "no AI in card!") + return + if(ai) + balloon_alert(user, "already has AI!") + return + if(intAI.deployed_shell) //Recall AI if shelled so it can be checked for a client + intAI.disconnect_shell() + if(intAI.stat || !intAI.client) + balloon_alert(user, "AI unresponsive!") + return + balloon_alert(user, "transferring to suit...") + if(!do_after(user, 5 SECONDS, target = src)) + balloon_alert(user, "interrupted!") + return + if(ai) + return + balloon_alert(user, "AI transferred to suit") + ai_enter_mod(intAI) + card.AI = null + +/obj/item/mod/control/proc/ai_enter_mod(mob/living/silicon/ai/new_ai) + new_ai.control_disabled = FALSE + new_ai.radio_enabled = TRUE + new_ai.ai_restore_power() + new_ai.cancel_camera() + new_ai.controlled_equipment = src + new_ai.remote_control = src + new_ai.forceMove(src) + ai = new_ai + balloon_alert(new_ai, "transferred to a suit") + for(var/datum/action/action as anything in actions) + action.Grant(ai) + +/** + * Simple proc to insert the pAI into the MODsuit. + * + * user - The person trying to put the pAI into the MODsuit. + * card - The pAI card we're slotting in the MODsuit. + */ + +/obj/item/mod/control/proc/insert_pai(mob/user, obj/item/paicard/card) + if(ai) + balloon_alert(user, "AI already installed!") + return + if(!card.pai || !card.pai.mind) + balloon_alert(user, "pAI unresponsive!") + return + balloon_alert(user, "transferring to suit...") + if(!do_after(user, 5 SECONDS, target = src)) + balloon_alert(user, "interrupted!") + return FALSE + if(!user.transferItemToLoc(card, src)) + return + + card.pai.canholo = FALSE + ai = card.pai + balloon_alert(user, "pAI transferred to suit") + balloon_alert(ai, "transferred to a suit") + ai.remote_control = src + for(var/datum/action/action as anything in actions) + action.Grant(ai) + return TRUE + +/** + * Simple proc to extract the pAI from the MODsuit. It's the proc to call if you want to take it out, + * remove_pai() is there so atom_destruction() doesn't have any risk of sleeping. + * + * user - The person trying to take out the pAI from the MODsuit. + * forced - Whether or not we skip the checks and just eject the pAI. Defaults to FALSE. + * feedback - Whether to give feedback via balloon alerts or not. Defaults to TRUE. + */ +/obj/item/mod/control/proc/extract_pai(mob/user, forced = FALSE, feedback = TRUE) + if(!ai) + if(user && feedback) + balloon_alert(user, "no pAI to remove!") + return + if(!ispAI(ai)) + if(user && feedback) + balloon_alert(user, "onboard AI cannot fit in this card!") + return + if(!forced) + if(!open) + if(user && feedback) + balloon_alert(user, "open the suit panel!") + return FALSE + if(!do_after(user, 5 SECONDS, target = src)) + if(user && feedback) + balloon_alert(user, "interrupted!") + return FALSE + + remove_pai(feedback) + + if(feedback && user) + balloon_alert(user, "pAI removed from the suit") + +/** + * Simple proc that handles the safe removal of the pAI from a MOD control unit. + * + * Arguments: + * * feedback - Whether or not we want to give balloon alert feedback to the ai. Defaults to FALSE. + */ +/obj/item/mod/control/proc/remove_pai(feedback = FALSE) + if(!ispAI(ai)) + return + var/mob/living/silicon/pai/pai = ai + var/turf/drop_off = get_turf(src) + if(drop_off) // In case there's no drop_off, the pAI will simply get deleted. + pai.card.forceMove(drop_off) + + for(var/datum/action/action as anything in actions) + if(action.owner == pai) + action.Remove(pai) + + if(feedback) + balloon_alert(pai, "removed from a suit") + pai.remote_control = null + pai.canholo = TRUE + pai = null + ai = null + +#define MOVE_DELAY 2 +#define WEARER_DELAY 1 +#define LONE_DELAY 5 +#define CELL_PER_STEP (DEFAULT_CHARGE_DRAIN * 2.5) +#define AI_FALL_TIME (1 SECONDS) + +/obj/item/mod/control/relaymove(mob/user, direction) + if((!active && wearer) || !cell || cell.charge < CELL_PER_STEP || user != ai || !COOLDOWN_FINISHED(src, cooldown_mod_move) || (wearer?.pulledby?.grab_state > GRAB_PASSIVE)) + return FALSE + var/timemodifier = MOVE_DELAY * (ISDIAGONALDIR(direction) ? SQRT_2 : 1) * (wearer ? WEARER_DELAY : LONE_DELAY) + if(wearer && !wearer.Process_Spacemove(direction)) + return FALSE + else if(!wearer && (!has_gravity() || !isturf(loc))) + return FALSE + COOLDOWN_START(src, cooldown_mod_move, movedelay * timemodifier + slowdown) + cell.charge = max(0, cell.charge - CELL_PER_STEP) + playsound(src, 'sound/mecha/mechmove01.ogg', 25, TRUE) + if(ismovable(wearer?.loc)) + return wearer.loc.relaymove(wearer, direction) + else if(wearer) + ADD_TRAIT(wearer, TRAIT_MOBILITY_NOREST, MOD_TRAIT) + addtimer(CALLBACK(src, .proc/ai_fall), AI_FALL_TIME, TIMER_UNIQUE | TIMER_OVERRIDE) + var/atom/movable/mover = wearer || src + return step(mover, direction) + +#undef MOVE_DELAY +#undef WEARER_DELAY +#undef LONE_DELAY +#undef CELL_PER_STEP +#undef AI_FALL_TIME + +/obj/item/mod/control/proc/ai_fall() + if(!wearer) + return + REMOVE_TRAIT(wearer, TRAIT_MOBILITY_NOREST, MOD_TRAIT) + +/obj/item/mod/control/ui_state(mob/user) + if(user == ai) + return GLOB.contained_state + return ..() diff --git a/code/modules/mod/mod_clothes.dm b/code/modules/mod/mod_clothes.dm new file mode 100644 index 0000000000..a7e4c0cb1d --- /dev/null +++ b/code/modules/mod/mod_clothes.dm @@ -0,0 +1,138 @@ +/obj/item/clothing/head/helmet/space/mod + name = "MOD helmet" + desc = "A helmet for a MODsuit." + icon = 'icons/obj/clothing/modsuit/mod_clothing.dmi' + mob_overlay_icon = 'icons/mob/clothing/modsuit/mod_clothing.dmi' + anthro_mob_worn_overlay = 'icons/mob/clothing/modsuit/mod_clothing_anthro.dmi' + icon_state = "helmet" + item_state = "helmet" + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, FIRE = 25, ACID = 25, WOUND = 10) + body_parts_covered = HEAD + heat_protection = HEAD + cold_protection = HEAD + max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT + min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT + clothing_flags = THICKMATERIAL + resistance_flags = NONE + flash_protect = 0 + clothing_flags = NONE + flags_inv = HIDEFACIALHAIR + flags_cover = NONE + visor_flags = THICKMATERIAL|STOPSPRESSUREDAMAGE + visor_flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT + visor_flags_cover = HEADCOVERSMOUTH|HEADCOVERSEYES + var/alternate_layer = NECK_LAYER + var/obj/item/mod/control/mod + mutantrace_variation = STYLE_MUZZLE + +/obj/item/clothing/head/helmet/space/mod/Destroy() + if(!QDELETED(mod)) + mod.helmet = null + mod.mod_parts -= src + QDEL_NULL(mod) + return ..() + +/obj/item/clothing/suit/space/mod + name = "MOD chestplate" + desc = "A chestplate for a MODsuit." + icon = 'icons/obj/clothing/modsuit/mod_clothing.dmi' + mob_overlay_icon = 'icons/mob/clothing/modsuit/mod_clothing.dmi' + anthro_mob_worn_overlay = 'icons/mob/clothing/modsuit/mod_clothing_anthro.dmi' + icon_state = "chestplate" + item_state = "chestplate" + blood_overlay_type = "armor" + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, FIRE = 25, ACID = 25, WOUND = 10) + body_parts_covered = CHEST|GROIN + heat_protection = CHEST|GROIN + cold_protection = CHEST|GROIN + max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT + min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT + clothing_flags = THICKMATERIAL + flags_inv = HIDETAUR + visor_flags = STOPSPRESSUREDAMAGE + visor_flags_inv = HIDEJUMPSUIT + allowed = list(/obj/item/flashlight, /obj/item/tank/internals) + resistance_flags = NONE + var/obj/item/mod/control/mod + mutantrace_variation = STYLE_DIGITIGRADE + +/obj/item/clothing/suit/space/mod/Destroy() + if(!QDELETED(mod)) + mod.chestplate = null + mod.mod_parts -= src + QDEL_NULL(mod) + return ..() + +/obj/item/clothing/gloves/mod + name = "MOD gauntlets" + desc = "A pair of gauntlets for a MODsuit." + icon = 'icons/obj/clothing/modsuit/mod_clothing.dmi' + mob_overlay_icon = 'icons/mob/clothing/modsuit/mod_clothing.dmi' + icon_state = "gauntlets" + item_state = "gauntlets" + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, FIRE = 25, ACID = 25, WOUND = 10) + body_parts_covered = HANDS|ARMS + heat_protection = HANDS|ARMS + cold_protection = HANDS|ARMS + max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT + min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT + clothing_flags = THICKMATERIAL + resistance_flags = NONE + var/obj/item/mod/control/mod + var/obj/item/clothing/overslot + mutantrace_variation = STYLE_NO_ANTHRO_ICON + +/obj/item/clothing/gloves/mod/Destroy() + if(!QDELETED(mod)) + mod.gauntlets = null + mod.mod_parts -= src + QDEL_NULL(mod) + return ..() + +/// Replaces these gloves on the wearer with the overslot ones + +/obj/item/clothing/gloves/mod/proc/show_overslot() + if(!overslot) + return + if(!mod.wearer.equip_to_slot_if_possible(overslot, overslot.slot_flags, qdel_on_fail = FALSE, disable_warning = TRUE)) + mod.wearer.dropItemToGround(overslot, force = TRUE) + overslot = null + +/obj/item/clothing/shoes/mod + name = "MOD boots" + desc = "A pair of boots for a MODsuit." + icon = 'icons/obj/clothing/modsuit/mod_clothing.dmi' + mob_overlay_icon = 'icons/mob/clothing/modsuit/mod_clothing.dmi' + anthro_mob_worn_overlay = 'icons/mob/clothing/modsuit/mod_clothing_anthro.dmi' + icon_state = "boots" + item_state = "boots" + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, FIRE = 25, ACID = 25, WOUND = 10) + body_parts_covered = FEET|LEGS + heat_protection = FEET|LEGS + cold_protection = FEET|LEGS + max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT + min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT + clothing_flags = THICKMATERIAL + resistance_flags = NONE + item_flags = NONE + var/obj/item/mod/control/mod + var/obj/item/clothing/overslot + mutantrace_variation = STYLE_DIGITIGRADE + +/obj/item/clothing/shoes/mod/Destroy() + if(!QDELETED(mod)) + mod.boots = null + mod.mod_parts -= src + QDEL_NULL(mod) + return ..() + +/// Replaces these shoes on the wearer with the overslot ones +/obj/item/clothing/shoes/mod/proc/show_overslot() + if(!overslot) + return + if(!mod.wearer.equip_to_slot_if_possible(overslot, overslot.slot_flags, qdel_on_fail = FALSE, disable_warning = TRUE)) + mod.wearer.dropItemToGround(overslot, force = TRUE) + overslot = null + +/obj/item/clothing/shoes/mod/negates_gravity() + return clothing_flags & NOSLIP diff --git a/code/modules/mod/mod_construction.dm b/code/modules/mod/mod_construction.dm new file mode 100644 index 0000000000..11eef7cb11 --- /dev/null +++ b/code/modules/mod/mod_construction.dm @@ -0,0 +1,288 @@ +/obj/item/mod/construction + desc = "A part used in MOD construction." + icon = 'icons/obj/clothing/modsuit/mod_construction.dmi' + item_state = "rack_parts" + +/obj/item/mod/construction/helmet + name = "MOD helmet" + icon_state = "helmet" + +/obj/item/mod/construction/chestplate + name = "MOD chestplate" + icon_state = "chestplate" + +/obj/item/mod/construction/gauntlets + name = "MOD gauntlets" + icon_state = "gauntlets" + +/obj/item/mod/construction/boots + name = "MOD boots" + icon_state = "boots" + +/obj/item/mod/construction/core + name = "MOD core" + icon_state = "mod-core-standard" + desc = "Growing in the most lush, fertile areas of the planet Sprout, there is a crystal known as the Heartbloom. \ + These rare, organic piezoelectric crystals are of incredible cultural significance to the artist castes of the Ethereals, \ + owing to their appearance; which is exactly similar to that of an Ethereal's heart. \n\ + Which one you have in your suit is unclear, but either way, \ + it's been repurposed to be an internal power source for a Modular Outerwear Device." + +/obj/item/mod/construction/broken_core + name = "broken MOD core" + icon_state = "mod-core" + desc = "An internal power source for a Modular Outerwear Device. You don't seem to be able to source any power from this one, though." + +/obj/item/mod/construction/broken_core/examine(mob/user) + . = ..() + . += span_notice("You could repair it with a screwdriver...") + +/obj/item/mod/construction/broken_core/screwdriver_act(mob/living/user, obj/item/tool) + . = ..() + if(!tool.use_tool(src, user, 5 SECONDS, volume = 30)) + return + new /obj/item/mod/construction/core(drop_location()) + qdel(src) + +/obj/item/mod/construction/armor + name = "MOD armor plates" + desc = "Armor plates used to finish a MOD." + icon_state = "standard-plating" + var/datum/mod_theme/theme = /datum/mod_theme + +/obj/item/mod/construction/armor/Initialize(mapload) + . = ..() + var/datum/mod_theme/used_theme = GLOB.mod_themes[theme] + name = "MOD [used_theme.name] armor plates" + desc = "[desc] [used_theme.desc]" + icon_state = "[used_theme.default_skin]-plating" + +/obj/item/mod/construction/armor/engineering + theme = /datum/mod_theme/engineering + +/obj/item/mod/construction/armor/atmospheric + theme = /datum/mod_theme/atmospheric + +/obj/item/mod/construction/armor/advanced + theme = /datum/mod_theme/advanced + +/obj/item/mod/construction/armor/mining + theme = /datum/mod_theme/mining + +/obj/item/mod/construction/armor/medical + theme = /datum/mod_theme/medical + +/obj/item/mod/construction/armor/rescue + theme = /datum/mod_theme/rescue + +/obj/item/mod/construction/armor/security + theme = /datum/mod_theme/security + +/obj/item/mod/construction/armor/safeguard + theme = /datum/mod_theme/safeguard + +/obj/item/mod/construction/armor/research + theme = /datum/mod_theme/research + +/obj/item/mod/construction/armor/cosmohonk + theme = /datum/mod_theme/cosmohonk + +/obj/item/mod/construction/armor/magnate + theme = /datum/mod_theme/magnate + +#define START_STEP "start" +#define CORE_STEP "core" +#define SCREWED_CORE_STEP "screwed_core" +#define HELMET_STEP "helmet" +#define CHESTPLATE_STEP "chestplate" +#define GAUNTLETS_STEP "gauntlets" +#define BOOTS_STEP "boots" +#define WRENCHED_ASSEMBLY_STEP "wrenched_assembly" +#define SCREWED_ASSEMBLY_STEP "screwed_assembly" + +/obj/item/mod/construction/shell + name = "MOD shell" + icon_state = "mod-construction_start" + desc = "A MOD shell." + var/obj/item/core + var/obj/item/helmet + var/obj/item/chestplate + var/obj/item/gauntlets + var/obj/item/boots + var/step = START_STEP + +/obj/item/mod/construction/shell/examine(mob/user) + . = ..() + var/display_text + switch(step) + if(START_STEP) + display_text = "It looks like it's missing a MOD core..." + if(CORE_STEP) + display_text = "The core seems loose..." + if(SCREWED_CORE_STEP) + display_text = "It looks like it's missing a helmet..." + if(HELMET_STEP) + display_text = "It looks like it's missing a chestplate..." + if(CHESTPLATE_STEP) + display_text = "It looks like it's missing gauntlets..." + if(GAUNTLETS_STEP) + display_text = "It looks like it's missing boots..." + if(BOOTS_STEP) + display_text = "The assembly seems unsecured..." + if(WRENCHED_ASSEMBLY_STEP) + display_text = "The assembly seems loose..." + if(SCREWED_ASSEMBLY_STEP) + display_text = "All it's missing is external armor..." + . += span_notice(display_text) + +/obj/item/mod/construction/shell/attackby(obj/item/part, mob/user, params) + . = ..() + switch(step) + if(START_STEP) + if(!istype(part, /obj/item/mod/construction/core)) + return + if(!user.transferItemToLoc(part, src)) + balloon_alert(user, "core stuck to your hand!") + return + playsound(src, 'sound/machines/click.ogg', 30, TRUE) + balloon_alert(user, "core inserted") + core = part + step = CORE_STEP + if(CORE_STEP) + if(part.tool_behaviour == TOOL_SCREWDRIVER) //Construct + if(part.use_tool(src, user, 0, volume=30)) + balloon_alert(user, "core screwed") + step = SCREWED_CORE_STEP + else if(part.tool_behaviour == TOOL_CROWBAR) //Deconstruct + if(part.use_tool(src, user, 0, volume=30)) + core.forceMove(drop_location()) + balloon_alert(user, "core taken out") + step = START_STEP + if(SCREWED_CORE_STEP) + if(istype(part, /obj/item/mod/construction/helmet)) //Construct + if(!user.transferItemToLoc(part, src)) + balloon_alert(user, "helmet stuck to your hand!") + return + playsound(src, 'sound/machines/click.ogg', 30, TRUE) + balloon_alert(user, "helmet added") + helmet = part + step = HELMET_STEP + else if(part.tool_behaviour == TOOL_SCREWDRIVER) //Deconstruct + if(part.use_tool(src, user, 0, volume=30)) + balloon_alert(user, "core unscrewed") + step = CORE_STEP + if(HELMET_STEP) + if(istype(part, /obj/item/mod/construction/chestplate)) //Construct + if(!user.transferItemToLoc(part, src)) + balloon_alert(user, "chestplate stuck to your hand!") + return + playsound(src, 'sound/machines/click.ogg', 30, TRUE) + balloon_alert(user, "chestplate added") + chestplate = part + step = CHESTPLATE_STEP + else if(part.tool_behaviour == TOOL_CROWBAR) //Deconstruct + if(part.use_tool(src, user, 0, volume=30)) + helmet.forceMove(drop_location()) + balloon_alert(user, "helmet removed") + helmet = null + step = SCREWED_CORE_STEP + if(CHESTPLATE_STEP) + if(istype(part, /obj/item/mod/construction/gauntlets)) //Construct + if(!user.transferItemToLoc(part, src)) + balloon_alert(user, "gauntlets stuck to your hand!") + return + playsound(src, 'sound/machines/click.ogg', 30, TRUE) + balloon_alert(user, "gauntlets added") + gauntlets = part + step = GAUNTLETS_STEP + else if(part.tool_behaviour == TOOL_CROWBAR) //Deconstruct + if(part.use_tool(src, user, 0, volume=30)) + chestplate.forceMove(drop_location()) + balloon_alert(user, "chestplate removed") + chestplate = null + step = HELMET_STEP + if(GAUNTLETS_STEP) + if(istype(part, /obj/item/mod/construction/boots)) //Construct + if(!user.transferItemToLoc(part, src)) + balloon_alert(user, "boots added") + return + playsound(src, 'sound/machines/click.ogg', 30, TRUE) + balloon_alert(user, "You fit [part] onto [src].") + boots = part + step = BOOTS_STEP + else if(part.tool_behaviour == TOOL_CROWBAR) //Deconstruct + if(part.use_tool(src, user, 0, volume=30)) + gauntlets.forceMove(drop_location()) + balloon_alert(user, "gauntlets removed") + gauntlets = null + step = CHESTPLATE_STEP + if(BOOTS_STEP) + if(part.tool_behaviour == TOOL_WRENCH) //Construct + if(part.use_tool(src, user, 0, volume=30)) + balloon_alert(user, "assembly secured") + step = WRENCHED_ASSEMBLY_STEP + else if(part.tool_behaviour == TOOL_CROWBAR) //Deconstruct + if(part.use_tool(src, user, 0, volume=30)) + boots.forceMove(drop_location()) + balloon_alert(user, "boots removed") + boots = null + step = GAUNTLETS_STEP + if(WRENCHED_ASSEMBLY_STEP) + if(part.tool_behaviour == TOOL_SCREWDRIVER) //Construct + if(part.use_tool(src, user, 0, volume=30)) + balloon_alert(user, "assembly screwed") + step = SCREWED_ASSEMBLY_STEP + else if(part.tool_behaviour == TOOL_WRENCH) //Deconstruct + if(part.use_tool(src, user, 0, volume=30)) + balloon_alert(user, "assembly unsecured") + step = BOOTS_STEP + if(SCREWED_ASSEMBLY_STEP) + if(istype(part, /obj/item/mod/construction/armor)) //Construct + var/obj/item/mod/construction/armor/external_armor = part + if(!user.transferItemToLoc(part, src)) + return + playsound(src, 'sound/machines/click.ogg', 30, TRUE) + balloon_alert(user, "suit finished") + var/obj/item/modsuit = new /obj/item/mod/control(drop_location(), external_armor.theme) + qdel(src) + user.put_in_hands(modsuit) + else if(part.tool_behaviour == TOOL_SCREWDRIVER) //Construct + if(part.use_tool(src, user, 0, volume=30)) + balloon_alert(user, "assembly unscrewed") + step = SCREWED_ASSEMBLY_STEP + update_icon_state() + +/obj/item/mod/construction/shell/update_icon_state() + . = ..() + icon_state = "mod-construction_[step]" + +/obj/item/mod/construction/shell/Destroy() + QDEL_NULL(core) + QDEL_NULL(helmet) + QDEL_NULL(chestplate) + QDEL_NULL(gauntlets) + QDEL_NULL(boots) + return ..() + +/obj/item/mod/construction/shell/handle_atom_del(atom/deleted_atom) + if(deleted_atom == core) + core = null + if(deleted_atom == helmet) + helmet = null + if(deleted_atom == chestplate) + chestplate = null + if(deleted_atom == gauntlets) + gauntlets = null + if(deleted_atom == boots) + boots = null + return ..() + +#undef START_STEP +#undef CORE_STEP +#undef SCREWED_CORE_STEP +#undef HELMET_STEP +#undef CHESTPLATE_STEP +#undef GAUNTLETS_STEP +#undef BOOTS_STEP +#undef WRENCHED_ASSEMBLY_STEP +#undef SCREWED_ASSEMBLY_STEP diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm new file mode 100644 index 0000000000..0853d04f82 --- /dev/null +++ b/code/modules/mod/mod_control.dm @@ -0,0 +1,575 @@ +/// MODsuits, trade-off between armor and utility +/obj/item/mod + name = "Base MOD" + desc = "You should not see this, yell at a coder!" + icon = 'icons/obj/clothing/modsuit/mod_clothing.dmi' + mob_overlay_icon = 'icons/mob/clothing/modsuit/mod_clothing.dmi' + icon_state = "standard-control" + item_state = "standard-control" + mutantrace_variation = STYLE_NO_ANTHRO_ICON + +/obj/item/mod/control + name = "MOD control unit" + desc = "The control unit of a Modular Outerwear Device, a powered, back-mounted suit that protects against various environments." + icon_state = "control" + item_state = "control" + w_class = WEIGHT_CLASS_BULKY + slot_flags = ITEM_SLOT_BACK + strip_delay = 10 SECONDS + slowdown = 2 + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, FIRE = 25, ACID = 25, WOUND = 10, RAD = 0) + actions_types = list( + /datum/action/item_action/mod/deploy, + /datum/action/item_action/mod/activate, + /datum/action/item_action/mod/module, + /datum/action/item_action/mod/panel, + /datum/action/item_action/mod/deploy/ai, + /datum/action/item_action/mod/activate/ai, + /datum/action/item_action/mod/module/ai, + /datum/action/item_action/mod/panel/ai, + ) + resistance_flags = NONE + max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT + min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT + permeability_coefficient = 0.01 + siemens_coefficient = 0.5 + alternate_worn_layer = BODY_FRONT_LAYER + /// The MOD's theme, decides on some stuff like armor and statistics. + var/datum/mod_theme/theme = /datum/mod_theme + /// Looks of the MOD. + var/skin = "standard" + /// Theme of the MOD TGUI + var/ui_theme = "ntos" + /// If the suit is deployed and turned on. + var/active = FALSE + /// If the suit wire/module hatch is open. + var/open = FALSE + /// If the suit is malfunctioning. + var/malfunctioning = FALSE + /// If the suit is currently activating/deactivating. + var/activating = FALSE + /// How long the MOD is electrified for. + var/seconds_electrified = MACHINE_NOT_ELECTRIFIED + /// If the suit interface is broken. + var/interface_break = FALSE + /// How much module complexity can this MOD carry. + var/complexity_max = DEFAULT_MAX_COMPLEXITY + /// How much module complexity this MOD is carrying. + var/complexity = 0 + /// Power usage of the MOD. + var/cell_drain = DEFAULT_CHARGE_DRAIN + /// Slowdown of the MOD when not active. + var/slowdown_inactive = 2 + /// Slowdown of the MOD when active. + var/slowdown_active = 1 + /// How long this MOD takes each part to seal. + var/activation_step_time = MOD_ACTIVATION_STEP_TIME + /// MOD cell. + var/obj/item/stock_parts/cell/cell + /// MOD helmet. + var/obj/item/clothing/head/helmet/space/mod/helmet + /// MOD chestplate. + var/obj/item/clothing/suit/space/mod/chestplate + /// MOD gauntlets. + var/obj/item/clothing/gloves/mod/gauntlets + /// MOD boots. + var/obj/item/clothing/shoes/mod/boots + /// List of parts (helmet, chestplate, gauntlets, boots). + var/list/mod_parts = list() + /// Modules the MOD should spawn with. + var/list/initial_modules = list() + /// Modules the MOD currently possesses. + var/list/modules = list() + /// Currently used module. + var/obj/item/mod/module/selected_module + /// AI/pAI mob inhabiting the MOD. + var/mob/living/silicon/ai + /// Delay between moves as AI. + var/movedelay = 0 + /// Cooldown for AI moves. + COOLDOWN_DECLARE(cooldown_mod_move) + /// Person wearing the MODsuit. + var/mob/living/carbon/human/wearer + +/obj/item/mod/control/Initialize(mapload, new_theme, new_skin) + . = ..() + if(new_theme) + theme = new_theme + theme = GLOB.mod_themes[theme] + slowdown_inactive = theme.slowdown_inactive + slowdown_active = theme.slowdown_active + slowdown = slowdown_inactive + complexity_max = theme.complexity_max + skin = new_skin || theme.default_skin + ui_theme = theme.ui_theme + cell_drain = theme.cell_drain + initial_modules += theme.inbuilt_modules + wires = new /datum/wires/mod(src) + if(ispath(cell)) + cell = new cell(src) + helmet = new /obj/item/clothing/head/helmet/space/mod(src) + helmet.mod = src + mod_parts += helmet + chestplate = new /obj/item/clothing/suit/space/mod(src) + chestplate.mod = src + mod_parts += chestplate + gauntlets = new /obj/item/clothing/gloves/mod(src) + gauntlets.mod = src + mod_parts += gauntlets + boots = new /obj/item/clothing/shoes/mod(src) + boots.mod = src + mod_parts += boots + var/list/all_parts = mod_parts.Copy() + src + for(var/obj/item/piece as anything in all_parts) + piece.name = "[theme.name] [piece.name]" + piece.desc = "[piece.desc] [theme.desc]" + piece.armor = getArmor(arglist(theme.armor)) + piece.resistance_flags = theme.resistance_flags + piece.heat_protection = NONE + piece.cold_protection = NONE + piece.max_heat_protection_temperature = theme.max_heat_protection_temperature + piece.min_cold_protection_temperature = theme.min_cold_protection_temperature + piece.permeability_coefficient = theme.permeability_coefficient + piece.siemens_coefficient = theme.siemens_coefficient + piece.icon_state = "[skin]-[initial(piece.icon_state)]" + piece.item_state = "[skin]-[initial(piece.item_state)]" + update_flags() + for(var/obj/item/mod/module/module as anything in initial_modules) + module = new module(src) + install(module) + RegisterSignal(src, COMSIG_ATOM_EXITED, .proc/on_exit) + movedelay = CONFIG_GET(number/movedelay/run_delay) + +/obj/item/mod/control/Destroy() + if(active) + STOP_PROCESSING(SSobj, src) + var/atom/deleting_atom + if(!QDELETED(helmet)) + deleting_atom = helmet + helmet.mod = null + helmet = null + mod_parts -= deleting_atom + qdel(deleting_atom) + if(!QDELETED(chestplate)) + deleting_atom = chestplate + chestplate.mod = null + chestplate = null + mod_parts -= deleting_atom + qdel(deleting_atom) + if(!QDELETED(gauntlets)) + deleting_atom = gauntlets + gauntlets.mod = null + gauntlets = null + mod_parts -= deleting_atom + qdel(deleting_atom) + if(!QDELETED(boots)) + deleting_atom = boots + boots.mod = null + boots = null + mod_parts -= deleting_atom + qdel(deleting_atom) + for(var/obj/item/mod/module/module as anything in modules) + module.mod = null + modules -= module + QDEL_NULL(ai) + QDEL_NULL(wires) + QDEL_NULL(cell) + return ..() + +/obj/item/mod/control/process(delta_time) + if(seconds_electrified > MACHINE_NOT_ELECTRIFIED) + seconds_electrified-- + if((!cell || !cell.charge) && active && !activating) + power_off() + return PROCESS_KILL + var/malfunctioning_charge_drain = 0 + if(malfunctioning) + malfunctioning_charge_drain = rand(1,20) + cell.charge = max(0, cell.charge - (cell_drain + malfunctioning_charge_drain)*delta_time) + update_cell_alert() + for(var/obj/item/mod/module/module as anything in modules) + if(malfunctioning && module.active && DT_PROB(5, delta_time)) + module.on_deactivation() + module.on_process(delta_time) + +/obj/item/mod/control/equipped(mob/user, slot) + ..() + if(slot == ITEM_SLOT_BACK) + set_wearer(user) + else if(wearer) + unset_wearer() + +/obj/item/mod/control/dropped(mob/user) + . = ..() + if(wearer) + unset_wearer() + +/obj/item/mod/control/item_action_slot_check(slot) + if(slot == ITEM_SLOT_BACK) + return TRUE + +/obj/item/mod/control/allow_attack_hand_drop(mob/user) + var/mob/living/carbon/carbon_user = user + if(!istype(carbon_user) || src != carbon_user.back) + return ..() + for(var/obj/item/part in mod_parts) + if(part.loc != src) + balloon_alert(carbon_user, "retract parts first!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, FALSE, SILENCED_SOUND_EXTRARANGE) + return FALSE + return ..() + +/obj/item/mod/control/MouseDrop(atom/over_object) + if(src != wearer?.back || !istype(over_object, /atom/movable/screen/inventory/hand)) + return ..() + for(var/obj/item/part in mod_parts) + if(part.loc != src) + balloon_alert(wearer, "retract parts first!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, FALSE, SILENCED_SOUND_EXTRARANGE) + return + if(!wearer.incapacitated()) + var/atom/movable/screen/inventory/hand/ui_hand = over_object + if(wearer.putItemFromInventoryInHandIfPossible(src, ui_hand.held_index)) + add_fingerprint(usr) + return ..() + +/obj/item/mod/control/attack_hand(mob/user) + if(seconds_electrified && cell?.charge) + if(shock(user)) + return + if(open && loc == user) + if(!cell) + balloon_alert(user, "no cell!") + return + balloon_alert(user, "removing cell...") + if(!do_after(user, 1.5 SECONDS, target = src)) + balloon_alert(user, "interrupted!") + return + balloon_alert(user, "cell removed") + playsound(src, 'sound/machines/click.ogg', 50, TRUE, SILENCED_SOUND_EXTRARANGE) + if(!user.put_in_hands(cell)) + cell.forceMove(drop_location()) + update_cell_alert() + return + return ..() + +/obj/item/mod/control/AltClick(mob/user) + if(seconds_electrified && cell?.charge) + if(shock(user)) + return + if(!open) + for(var/obj/item/mod/module/storage/S in modules) + if(S.stored) + playsound(user, "rustle", 50, 1, -5) + SEND_SIGNAL(S.stored, COMSIG_TRY_STORAGE_SHOW, wearer, TRUE) + return + . = ..() + +/obj/item/mod/control/screwdriver_act(mob/living/user, obj/item/screwdriver) + . = ..() + if(.) + return TRUE + if(active || activating) + balloon_alert(user, "deactivate suit first!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return FALSE + balloon_alert(user, "[open ? "closing" : "opening"] panel...") + screwdriver.play_tool_sound(src, 100) + if(screwdriver.use_tool(src, user, 1 SECONDS)) + if(active || activating) + balloon_alert(user, "deactivate suit first!") + screwdriver.play_tool_sound(src, 100) + balloon_alert(user, "panel [open ? "closed" : "opened"]") + open = !open + else + balloon_alert(user, "interrupted!") + return TRUE + +/obj/item/mod/control/crowbar_act(mob/living/user, obj/item/crowbar) + . = ..() + if(!open) + balloon_alert(user, "open the panel first!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return FALSE + if(!allowed(user)) + balloon_alert(user, "insufficient access!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return + if(length(modules)) + var/list/removable_modules = list() + for(var/obj/item/mod/module/module as anything in modules) + if(!module.removable) + continue + removable_modules += module + var/obj/item/mod/module/module_to_remove = tgui_input_list(user, "Which module to remove?", "Module Removal", removable_modules) + if(!module_to_remove?.mod) + return FALSE + uninstall(module_to_remove) + module_to_remove.forceMove(drop_location()) + crowbar.play_tool_sound(src, 100) + return TRUE + balloon_alert(user, "no modules!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return FALSE + +/obj/item/mod/control/attackby(obj/item/attacking_item, mob/living/user, params) + if(istype(attacking_item, /obj/item/paicard)) + if(!open) //mod must be open + balloon_alert(user, "suit must be open to transfer!") + return FALSE + insert_pai(user, attacking_item) + return TRUE + if(istype(attacking_item, /obj/item/mod/module)) + if(!open) + balloon_alert(user, "open the panel first!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return FALSE + install(attacking_item, user) + return TRUE + else if(istype(attacking_item, /obj/item/stock_parts/cell)) + if(!open) + balloon_alert(user, "open the panel first!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return FALSE + if(cell) + balloon_alert(user, "cell already installed!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return FALSE + attacking_item.forceMove(src) + cell = attacking_item + balloon_alert(user, "cell installed") + playsound(src, 'sound/machines/click.ogg', 50, TRUE, SILENCED_SOUND_EXTRARANGE) + update_cell_alert() + return TRUE + else if(is_wire_tool(attacking_item) && open) + wires.interact(user) + return TRUE + else if(open && attacking_item.GetID()) + update_access(user, attacking_item) + return TRUE + return ..() + +/obj/item/mod/control/get_cell() + if(open) + return cell + +/obj/item/mod/control/emp_act(severity) + . = ..() + to_chat(wearer, span_notice("[severity > 1 ? "Light" : "Strong"] electromagnetic pulse detected!")) + if(!active || !wearer || . & EMP_PROTECT_CONTENTS) + return + selected_module = null + wearer.apply_damage(10 / severity, BURN, spread_damage=TRUE) + to_chat(wearer, span_danger("You feel [src] heat up from the EMP, burning you slightly.")) + if (wearer.stat < UNCONSCIOUS && prob(10)) + wearer.emote("scream") + +/obj/item/mod/control/on_outfit_equip(mob/living/carbon/human/outfit_wearer, visuals_only, item_slot) + if(visuals_only) + set_wearer(outfit_wearer) //we need to set wearer manually since it doesnt call equipped + quick_activation() + +/obj/item/mod/control/doStrip(mob/stripper, mob/owner) + if(active && !toggle_activate(stripper, force_deactivate = TRUE)) + return + for(var/obj/item/part in mod_parts) + conceal(null, part) + return ..() + +/obj/item/mod/control/worn_overlays(isinhands = FALSE, icon_file) + . = ..() + if(!active) + return + for(var/obj/item/mod/module/module as anything in modules) + var/list/module_icons = module.generate_worn_overlay() + if(!length(module_icons)) + continue + . += module_icons + +/obj/item/mod/control/proc/set_wearer(mob/user) + wearer = user + RegisterSignal(wearer, COMSIG_ATOM_EXITED, .proc/on_exit) + RegisterSignal(wearer, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, .proc/on_borg_charge) + update_cell_alert() + for(var/obj/item/mod/module/module as anything in modules) + module.on_equip() + +/obj/item/mod/control/proc/unset_wearer() + for(var/obj/item/mod/module/module as anything in modules) + module.on_unequip() + UnregisterSignal(wearer, list(COMSIG_ATOM_EXITED, COMSIG_PROCESS_BORGCHARGER_OCCUPANT)) + wearer.clear_alert("mod_charge") + wearer = null + +/obj/item/mod/control/proc/update_flags() + var/list/used_skin = theme.skins[skin] + for(var/obj/item/clothing/part as anything in mod_parts) + var/used_category + if(part == helmet) + used_category = HELMET_FLAGS + helmet.alternate_worn_layer = used_skin["HELMET_LAYER"] + helmet.alternate_layer = used_skin["HELMET_LAYER"] + if(part == chestplate) + used_category = CHESTPLATE_FLAGS + if(part == gauntlets) + used_category = GAUNTLETS_FLAGS + if(part == boots) + used_category = BOOTS_FLAGS + var/list/category = used_skin[used_category] + part.clothing_flags = category[UNSEALED_CLOTHING] || NONE + part.visor_flags = category[SEALED_CLOTHING] || NONE + part.flags_inv = category[UNSEALED_INVISIBILITY] || NONE + part.visor_flags_inv = category[SEALED_INVISIBILITY] || NONE + part.flags_cover = category[UNSEALED_COVER] || NONE + part.visor_flags_cover = category[SEALED_COVER] || NONE + +/obj/item/mod/control/proc/quick_module(mob/user) + if(!length(modules)) + return + var/list/display_names = list() + var/list/items = list() + for(var/obj/item/mod/module/module as anything in modules) + if(module.module_type == MODULE_PASSIVE) + continue + display_names[module.name] = REF(module) + var/image/module_image = image(icon = module.icon, icon_state = module.icon_state) + items += list(module.name = module_image) + if(!length(items)) + return + var/pick = show_radial_menu(user, src, items, custom_check = FALSE, require_near = TRUE) + if(!pick) + return + var/module_reference = display_names[pick] + var/obj/item/mod/module/selected_module = locate(module_reference) in modules + if(!istype(selected_module) || user.incapacitated()) + return + selected_module.on_select() + +/obj/item/mod/control/proc/set_mod_color(new_color) + var/list/all_parts = mod_parts + src + for(var/obj/item/part as anything in all_parts) + part.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) + part.add_atom_colour(new_color, FIXED_COLOUR_PRIORITY) + wearer?.regenerate_icons() + +/obj/item/mod/control/proc/set_mod_skin(new_skin) + if(active) + CRASH("[src] tried to set skin while active!") + skin = new_skin + var/list/used_skin = theme.skins[new_skin] + if(used_skin[CONTROL_LAYER]) + alternate_worn_layer = used_skin[CONTROL_LAYER] + var/list/skin_updating = mod_parts.Copy() + src + for(var/obj/item/piece as anything in skin_updating) + piece.icon_state = "[skin]-[initial(piece.icon_state)]" + update_flags() + wearer?.regenerate_icons() + +/obj/item/mod/control/proc/shock(mob/living/user) + if(!istype(user) || cell?.charge < 1) + return FALSE + do_sparks(5, TRUE, src) + var/check_range = TRUE + return electrocute_mob(user, cell, src, 0.7, check_range) + +/obj/item/mod/control/proc/install(module, mob/user) + var/obj/item/mod/module/new_module = module + for(var/obj/item/mod/module/old_module as anything in modules) + if(is_type_in_list(new_module, old_module.incompatible_modules) || is_type_in_list(old_module, new_module.incompatible_modules)) + if(user) + balloon_alert(user, "[new_module] incompatible with [old_module]!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return + if(is_type_in_list(module, theme.module_blacklist)) + if(user) + balloon_alert(user, "[src] doesn't accept [new_module]!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return + var/complexity_with_module = complexity + complexity_with_module += new_module.complexity + if(complexity_with_module > complexity_max) + if(user) + balloon_alert(user, "[new_module] would make [src] too complex!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return + new_module.forceMove(src) + modules += new_module + complexity += new_module.complexity + new_module.mod = src + new_module.on_install() + if(wearer) + new_module.on_equip() + if(user) + balloon_alert(user, "[new_module] added") + playsound(src, 'sound/machines/click.ogg', 50, TRUE, SILENCED_SOUND_EXTRARANGE) + +/obj/item/mod/control/proc/uninstall(module) + var/obj/item/mod/module/old_module = module + modules -= old_module + complexity -= old_module.complexity + if(active) + old_module.on_suit_deactivation() + if(old_module.active) + old_module.on_deactivation() + if(wearer) + old_module.on_unequip() + old_module.on_uninstall() + old_module.mod = null + +/obj/item/mod/control/proc/update_access(mob/user, obj/item/card/id/card) + if(!allowed(user)) + balloon_alert(user, "insufficient access!") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) + return + req_access = card.access.Copy() + balloon_alert(user, "access updated") + +/obj/item/mod/control/proc/update_cell_alert() + if(!wearer) + return + if(!cell) + wearer.throw_alert("mod_charge", /atom/movable/screen/alert/nocell) + return + var/remaining_cell = cell.charge/cell.maxcharge + switch(remaining_cell) + if(0.75 to INFINITY) + wearer.clear_alert("mod_charge") + if(0.5 to 0.75) + wearer.throw_alert("mod_charge", /atom/movable/screen/alert/lowcell, 1) + if(0.25 to 0.5) + wearer.throw_alert("mod_charge", /atom/movable/screen/alert/lowcell, 2) + if(0.01 to 0.25) + wearer.throw_alert("mod_charge", /atom/movable/screen/alert/lowcell, 3) + else + wearer.throw_alert("mod_charge", /atom/movable/screen/alert/emptycell) + +/obj/item/mod/control/proc/power_off() + balloon_alert(wearer, "no power!") + toggle_activate(wearer, force_deactivate = TRUE) + +/obj/item/mod/control/proc/on_exit(datum/source, atom/movable/part, direction) + SIGNAL_HANDLER + + if(part.loc == src) + return + if(part == cell) + cell = null + update_cell_alert() + return + if(part.loc == wearer) + return + if(modules.Find(part)) + uninstall(part) + return + if(mod_parts.Find(part)) + conceal(wearer, part) + if(active) + INVOKE_ASYNC(src, .proc/toggle_activate, wearer, TRUE) + return + +/obj/item/mod/control/proc/on_borg_charge(datum/source, amount) + SIGNAL_HANDLER + + if(!cell) + return + cell.give(amount) diff --git a/code/modules/mod/mod_paint.dm b/code/modules/mod/mod_paint.dm new file mode 100644 index 0000000000..44f4923002 --- /dev/null +++ b/code/modules/mod/mod_paint.dm @@ -0,0 +1,207 @@ +#define MODPAINT_MAX_COLOR_VALUE 1.25 +#define MODPAINT_MIN_COLOR_VALUE 0 +#define MODPAINT_MAX_SECTION_COLORS 2 +#define MODPAINT_MIN_SECTION_COLORS 0.25 +#define MODPAINT_MAX_OVERALL_COLORS 4 +#define MODPAINT_MIN_OVERALL_COLORS 1.5 +#define MODPAINT_MODE_RESKIN "reskin" +#define MODPAINT_MODE_REPAINT "repaint" + +/obj/item/mod/paint + name = "MOD paint kit" + desc = "This kit will repaint your MODsuit to something unique." + icon = 'icons/obj/clothing/modsuit/mod_construction.dmi' + icon_state = "paintkit" + var/obj/item/mod/control/editing_mod + var/atom/movable/screen/map_view/proxy_view + var/list/current_color + var/mode = MODPAINT_MODE_RESKIN + +/obj/item/mod/paint/Initialize(mapload) + . = ..() + current_color = color_matrix_identity() + +/obj/item/mod/paint/examine(mob/user) + . = ..() + . += span_notice("It is currently on [mode] mode.") + +/obj/item/mod/paint/attack_self(mob/user) + switch(mode) + if(MODPAINT_MODE_RESKIN) + mode = MODPAINT_MODE_REPAINT + if(MODPAINT_MODE_REPAINT) + mode = MODPAINT_MODE_RESKIN + to_chat(user, span_notice("Switched to [mode] mode.")) + +/obj/item/mod/paint/pre_attack(atom/attacked_atom, mob/living/user, params) + if(!istype(attacked_atom, /obj/item/mod/control)) + return ..() + var/obj/item/mod/control/mod = attacked_atom + if(mod.active || mod.activating) + balloon_alert(user, "suit is active!") + return STOP_ATTACK_PROC_CHAIN + switch(mode) + if(MODPAINT_MODE_RESKIN) + paint_skin(mod, user) + if(MODPAINT_MODE_REPAINT) + if(editing_mod) + return STOP_ATTACK_PROC_CHAIN + editing_mod = mod + var/map_name = "color_matrix_proxy_[REF(user.client)]" + proxy_view = new() + proxy_view.name = "screen" + proxy_view.assigned_map = map_name + proxy_view.del_on_map_removal = FALSE + proxy_view.screen_loc = "[map_name]:1,1" + + proxy_view.appearance = editing_mod.appearance + proxy_view.color = null + user.client.register_map_obj(proxy_view) + ui_interact(user) + return STOP_ATTACK_PROC_CHAIN + +/obj/item/mod/paint/ui_interact(mob/user, datum/tgui/ui) + if(!editing_mod) + return + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "MODpaint", name) + ui.open() + +/obj/item/mod/paint/ui_host() + return editing_mod + +/obj/item/mod/paint/ui_close(mob/user) + . = ..() + editing_mod = null + QDEL_NULL(proxy_view) + current_color = color_matrix_identity() + +/obj/item/mod/paint/ui_status(mob/user) + if(check_menu(editing_mod, user)) + return ..() + return UI_CLOSE + +/obj/item/mod/paint/ui_static_data(mob/user) + var/list/data = list() + data["mapRef"] = proxy_view.assigned_map + return data + +/obj/item/mod/paint/ui_data(mob/user) + var/list/data = list() + data["currentColor"] = current_color + return data + +/obj/item/mod/paint/ui_act(action, list/params) + . = ..() + if(.) + return + switch(action) + if("transition_color") + current_color = params["color"] + animate(proxy_view, time = 0.5 SECONDS, color = current_color) + if("confirm") + if(length(current_color) != 20) //20 is the length of a matrix identity list + return + for(var/color_value in current_color) + if(isnum(color_value)) + continue + return + var/total_color_value = 0 + var/list/total_colors = current_color.Copy() + total_colors.Cut(13, length(total_colors)) // 13 to 20 are just a and c, dont want to count them + var/red_value = current_color[1] + current_color[5] + current_color[9] //rr + gr + br + var/green_value = current_color[2] + current_color[6] + current_color[10] //rg + gg + bg + var/blue_value = current_color[3] + current_color[7] + current_color[11] //rb + gb + bb + if(red_value > MODPAINT_MAX_SECTION_COLORS) + balloon_alert(usr, "total red too high! ([red_value*100]%/[MODPAINT_MAX_SECTION_COLORS*100]%)") + return + else if(red_value < MODPAINT_MIN_SECTION_COLORS) + balloon_alert(usr, "total red too low! ([red_value*100]%/[MODPAINT_MIN_SECTION_COLORS*100]%)") + return + if(green_value > MODPAINT_MAX_SECTION_COLORS) + balloon_alert(usr, "total green too high! ([green_value*100]%/[MODPAINT_MAX_SECTION_COLORS*100]%)") + return + else if(green_value < MODPAINT_MIN_SECTION_COLORS) + balloon_alert(usr, "total green too low! ([green_value*100]%/[MODPAINT_MIN_SECTION_COLORS*100]%)") + return + if(blue_value > MODPAINT_MAX_SECTION_COLORS) + balloon_alert(usr, "total blue too high! ([blue_value*100]%/[MODPAINT_MAX_SECTION_COLORS*100]%)") + return + else if(blue_value < MODPAINT_MIN_SECTION_COLORS) + balloon_alert(usr, "total blue too low! ([blue_value*100]%/[MODPAINT_MIN_SECTION_COLORS*100]%)") + return + for(var/color_value in total_colors) + total_color_value += color_value + if(color_value > MODPAINT_MAX_COLOR_VALUE) + balloon_alert(usr, "one of colors too high! ([color_value*100]%/[MODPAINT_MAX_COLOR_VALUE*100]%") + return + else if(color_value < MODPAINT_MIN_COLOR_VALUE) + balloon_alert(usr, "one of colors too low! ([color_value*100]%/[MODPAINT_MIN_COLOR_VALUE*100]%") + return + if(total_color_value > MODPAINT_MAX_OVERALL_COLORS) + balloon_alert(usr, "total colors too high! ([total_color_value*100]%/[MODPAINT_MAX_OVERALL_COLORS*100]%)") + return + else if(total_color_value < MODPAINT_MIN_OVERALL_COLORS) + balloon_alert(usr, "total colors too low! ([total_color_value*100]%/[MODPAINT_MIN_OVERALL_COLORS*100]%)") + return + editing_mod.set_mod_color(current_color) + SStgui.close_uis(src) + +/obj/item/mod/paint/proc/paint_skin(obj/item/mod/control/mod, mob/user) + if(length(mod.theme.skins) <= 1) + balloon_alert(user, "no alternate skins!") + return + var/list/skins = list() + for(var/mod_skin in mod.theme.skins) + skins[mod_skin] = image(icon = mod.icon, icon_state = "[mod_skin]-control") + var/pick = show_radial_menu(user, mod, skins, custom_check = CALLBACK(src, .proc/check_menu, mod, user), require_near = TRUE) + if(!pick) + balloon_alert(user, "no skin picked!") + return + mod.set_mod_skin(pick) + +/obj/item/mod/paint/proc/check_menu(obj/item/mod/control/mod, mob/user) + if(user.incapacitated() || !user.is_holding(src) || !mod || mod.active || mod.activating) + return FALSE + return TRUE + +#undef MODPAINT_MAX_COLOR_VALUE +#undef MODPAINT_MIN_COLOR_VALUE +#undef MODPAINT_MAX_SECTION_COLORS +#undef MODPAINT_MIN_SECTION_COLORS +#undef MODPAINT_MAX_OVERALL_COLORS +#undef MODPAINT_MIN_OVERALL_COLORS +#undef MODPAINT_MODE_RESKIN +#undef MODPAINT_MODE_REPAINT + +/obj/item/mod/skin_applier + name = "MOD skin applier" + desc = "This one-use skin applier will add a skin to MODsuits of a specific type." + icon = 'icons/obj/clothing/modsuit/mod_construction.dmi' + icon_state = "skinapplier" + var/skin = "civilian" + var/compatible_theme = /datum/mod_theme + +/obj/item/mod/skin_applier/Initialize(mapload) + . = ..() + name = "MOD [skin] skin applier" + +/obj/item/mod/skin_applier/pre_attack(atom/attacked_atom, mob/living/user, params) + if(!istype(attacked_atom, /obj/item/mod/control)) + return ..() + var/obj/item/mod/control/mod = attacked_atom + if(mod.active || mod.activating) + balloon_alert(user, "suit is active!") + return TRUE + if(!istype(mod.theme, compatible_theme)) + balloon_alert(user, "incompatible theme!") + return TRUE + mod.set_mod_skin(skin) + balloon_alert(user, "skin applied") + qdel(src) + return TRUE + +/obj/item/mod/skin_applier/honkerative + skin = "honkerative" + compatible_theme = /datum/mod_theme/syndicate diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm new file mode 100644 index 0000000000..050badf5d9 --- /dev/null +++ b/code/modules/mod/mod_theme.dm @@ -0,0 +1,854 @@ +/// Global proc that sets up all MOD themes as singletons in a list and returns it. +/proc/setup_mod_themes() + . = list() + for(var/path in typesof(/datum/mod_theme)) + var/datum/mod_theme/new_theme = new path() + .[path] = new_theme + +/// MODsuit theme, instanced once and then used by MODsuits to grab various statistics. +/datum/mod_theme + /// Theme name for the MOD. + var/name = "standard" + /// Description added to the MOD. + var/desc = "A civilian class suit by Nakamura Engineering, doesn't offer much other than slightly quicker movement." + /// Default skin of the MOD. + var/default_skin = "standard" + /// Armor shared across the MOD pieces. + var/armor = list(MELEE = 10, BULLET = 5, LASER = 5, ENERGY = 5, BOMB = 0, BIO = 100, FIRE = 25, ACID = 25, WOUND = 5, RAD = 0) + /// Resistance flags shared across the MOD pieces. + var/resistance_flags = NONE + /// Max heat protection shared across the MOD pieces. + var/max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT + /// Max cold protection shared across the MOD pieces. + var/min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT + /// Permeability shared across the MOD pieces. + var/permeability_coefficient = 0.01 + /// Siemens shared across the MOD pieces. + var/siemens_coefficient = 0.5 + /// How much modules can the MOD carry without malfunctioning. + var/complexity_max = DEFAULT_MAX_COMPLEXITY + /// How much battery power the MOD uses by just being on + var/cell_drain = DEFAULT_CHARGE_DRAIN + /// Slowdown of the MOD when not active. + var/slowdown_inactive = 1.25 + /// Slowdown of the MOD when active. + var/slowdown_active = 0.75 + /// Theme used by the MOD TGUI. + var/ui_theme = "ntos" + /// List of inbuilt modules. These are different from the pre-equipped suits, you should mainly use these for unremovable modules with 0 complexity. + var/list/inbuilt_modules = list() + /// Modules blacklisted from the MOD. + var/list/module_blacklist = list() + /// List of skins with their appropriate clothing flags. + var/list/skins = list( + "standard" = list( + HELMET_LAYER = NECK_LAYER, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = NONE, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR, + SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + "civilian" = list( + HELMET_LAYER = null, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/engineering + name = "engineering" + desc = "An engineer-fit suit with heat and shock resistance. Nakamura Engineering's classic." + default_skin = "engineering" + armor = list(MELEE = 10, BULLET = 5, LASER = 20, ENERGY = 10, BOMB = 10, BIO = 100, FIRE = 100, ACID = 25, WOUND = 10, RAD = 20) + resistance_flags = FIRE_PROOF + max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT + siemens_coefficient = 0 + slowdown_inactive = 1.5 + slowdown_active = 1 + skins = list( + "engineering" = list( + HELMET_LAYER = NECK_LAYER, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = NONE, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR, + SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/atmospheric + name = "atmospheric" + desc = "An atmospheric-resistant suit by Nakamura Engineering, offering extreme heat resistance compared to the engineer suit." + default_skin = "atmospheric" + armor = list(MELEE = 10, BULLET = 5, LASER = 10, ENERGY = 15, BOMB = 10, BIO = 100, FIRE = 100, ACID = 75, WOUND = 10, RAD = 0) + resistance_flags = FIRE_PROOF + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + slowdown_inactive = 1.5 + slowdown_active = 1 + skins = list( + "atmospheric" = list( + HELMET_LAYER = NECK_LAYER, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = NONE, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDESNOUT, + SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR, + UNSEALED_COVER = HEADCOVERSMOUTH, + SEALED_COVER = HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/advanced + name = "advanced" + desc = "An advanced version of Nakamura Engineering's classic suit, shining with a white, acid and fire resistant polish." + default_skin = "advanced" + armor = list(MELEE = 15, BULLET = 5, LASER = 20, ENERGY = 15, BOMB = 50, BIO = 100, FIRE = 100, ACID = 90, WOUND = 10, RAD = 35) + resistance_flags = FIRE_PROOF + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + siemens_coefficient = 0 + slowdown_inactive = 1 + slowdown_active = 0.5 + inbuilt_modules = list(/obj/item/mod/module/magboot/advanced) + skins = list( + "advanced" = list( + HELMET_LAYER = NECK_LAYER, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = NONE, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR, + SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/mining + name = "mining" + desc = "A high-power Nanotrasen mining suit, supporting more complexity at a bigger drain." + default_skin = "mining" + armor = list(MELEE = 15, BULLET = 5, LASER = 5, ENERGY = 5, BOMB = 30, BIO = 100, FIRE = 100, ACID = 75, WOUND = 15, RAD = 0) + resistance_flags = FIRE_PROOF + max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT + cell_drain = DEFAULT_CHARGE_DRAIN * 2 + complexity_max = DEFAULT_MAX_COMPLEXITY + 5 + skins = list( + "mining" = list( + HELMET_LAYER = null, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT, + SEALED_INVISIBILITY = HIDEMASK|HIDEEYES|HIDEFACE, + SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/medical + name = "medical" + desc = "A lightweight suit by DeForest Medical Corporation, allows for easier movement." + default_skin = "medical" + armor = list(MELEE = 5, BULLET = 5, LASER = 5, ENERGY = 5, BOMB = 10, BIO = 100, FIRE = 60, ACID = 75, WOUND = 5, RAD = 0) + cell_drain = DEFAULT_CHARGE_DRAIN * 1.5 + slowdown_inactive = 1 + slowdown_active = 0.5 + skins = list( + "medical" = list( + HELMET_LAYER = NECK_LAYER, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = NONE, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR, + SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + "corpsman" = list( + HELMET_LAYER = NECK_LAYER, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = NONE, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR, + SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/rescue + name = "rescue" + desc = "An advanced version of DeForest Medical Corporation's medical suit, designed for quick rescue of bodies from the most dangerous environments." + default_skin = "rescue" + armor = list(MELEE = 10, BULLET = 10, LASER = 5, ENERGY = 5, BOMB = 10, BIO = 100, FIRE = 100, ACID = 100, WOUND = 5, RAD = 0) + resistance_flags = FIRE_PROOF|ACID_PROOF + max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT + cell_drain = DEFAULT_CHARGE_DRAIN * 1.5 + slowdown_inactive = 0.75 + slowdown_active = 0.25 + inbuilt_modules = list(/obj/item/mod/module/quick_carry/advanced) + skins = list( + "rescue" = list( + HELMET_LAYER = NECK_LAYER, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = NONE, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR, + SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/research + name = "research" + desc = "A private military EOD suit by Aussec Armory, intended for explosive research. Bulky, but expansive." + default_skin = "research" + armor = list(MELEE = 20, BULLET = 15, LASER = 5, ENERGY = 5, BOMB = 100, BIO = 100, FIRE = 100, ACID = 100, WOUND = 15, RAD = 0) + resistance_flags = FIRE_PROOF|ACID_PROOF + max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT + complexity_max = DEFAULT_MAX_COMPLEXITY + 5 + slowdown_inactive = 2 + slowdown_active = 1.5 + inbuilt_modules = list(/obj/item/mod/module/reagent_scanner/advanced) + skins = list( + "research" = list( + HELMET_LAYER = null, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/security + name = "security" + desc = "An Apadyne Technologies security suit, offering shock protection and quicker speed, at the cost of carrying capacity." + default_skin = "security" + armor = list(MELEE = 15, BULLET = 15, LASER = 15, ENERGY = 15, BOMB = 25, BIO = 100, FIRE = 75, ACID = 75, WOUND = 15, RAD = 0) + siemens_coefficient = 0 + complexity_max = DEFAULT_MAX_COMPLEXITY - 5 + slowdown_inactive = 1 + slowdown_active = 0.5 + skins = list( + "security" = list( + HELMET_LAYER = null, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT, + SEALED_INVISIBILITY = HIDEMASK|HIDEEYES|HIDEFACE, + UNSEALED_COVER = HEADCOVERSMOUTH, + SEALED_COVER = HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/safeguard + name = "safeguard" + desc = "An Apadyne Technologies advanced security suit, offering greater speed and fire protection than the standard security model." + default_skin = "safeguard" + armor = list(MELEE = 15, BULLET = 15, LASER = 15, ENERGY = 15, BOMB = 40, BIO = 100, FIRE = 100, ACID = 95, WOUND = 15, RAD = 0) + resistance_flags = FIRE_PROOF + max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT + siemens_coefficient = 0 + complexity_max = DEFAULT_MAX_COMPLEXITY - 5 + slowdown_inactive = 0.75 + slowdown_active = 0.25 + skins = list( + "safeguard" = list( + HELMET_LAYER = null, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/magnate + name = "magnate" + desc = "A fancy, very protective suit for Nanotrasen's captains. Shock, fire and acid-proof while also having a large capacity and high speed." + default_skin = "magnate" + armor = list(MELEE = 20, BULLET = 15, LASER = 15, ENERGY = 15, BOMB = 50, BIO = 100, FIRE = 100, ACID = 100, WOUND = 15, RAD = 0) + resistance_flags = FIRE_PROOF|ACID_PROOF + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + siemens_coefficient = 0 + complexity_max = DEFAULT_MAX_COMPLEXITY + 5 + slowdown_inactive = 0.75 + slowdown_active = 0.25 + skins = list( + "magnate" = list( + HELMET_LAYER = NECK_LAYER, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = NONE, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR, + SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/cosmohonk + name = "cosmohonk" + desc = "A suit by Honk Ltd. Protects against low humor environments. Most of the tech went to lower the power cost." + default_skin = "cosmohonk" + armor = list(MELEE = 5, BULLET = 5, LASER = 20, ENERGY = 20, BOMB = 10, BIO = 100, FIRE = 60, ACID = 30, WOUND = 5, RAD = 0) + cell_drain = DEFAULT_CHARGE_DRAIN * 0.25 + slowdown_inactive = 1.75 + slowdown_active = 1.25 + skins = list( + "cosmohonk" = list( + HELMET_LAYER = NECK_LAYER, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEEARS|HIDEHAIR, + SEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEYES|HIDEFACE|HIDESNOUT, + SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/syndicate + name = "syndicate" + desc = "A suit designed by Gorlex Marauders, offering armor ruled illegal in most of Spinward Stellar." + default_skin = "syndicate" + armor = list(MELEE = 15, BULLET = 20, LASER = 15, ENERGY = 15, BOMB = 35, BIO = 100, FIRE = 50, ACID = 90, WOUND = 25, RAD = 0) + max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT + siemens_coefficient = 0 + slowdown_inactive = 1 + slowdown_active = 0.5 + ui_theme = "syndicate" + inbuilt_modules = list() + skins = list( + "syndicate" = list( + HELMET_LAYER = NECK_LAYER, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = NONE, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR, + SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/elite + name = "elite" + desc = "An elite suit upgraded by Cybersun Industries, offering upgraded armor values." + default_skin = "elite" + armor = list(MELEE = 35, BULLET = 30, LASER = 35, ENERGY = 35, BOMB = 55, BIO = 100, FIRE = 100, ACID = 100, WOUND = 25, RAD = 0) + resistance_flags = FIRE_PROOF|ACID_PROOF + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + siemens_coefficient = 0 + slowdown_inactive = 0.75 + slowdown_active = 0.25 + ui_theme = "syndicate" + inbuilt_modules = list() + skins = list( + "elite" = list( + HELMET_LAYER = null, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = NONE, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR, + SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/enchanted + name = "enchanted" + desc = "The Wizard Federation's relatively low-tech MODsuit. Is very protective, though." + default_skin = "enchanted" + armor = list(MELEE = 40, BULLET = 40, LASER = 50, ENERGY = 50, BOMB = 35, BIO = 100, FIRE = 100, ACID = 100, WOUND = 30, RAD = 0) + resistance_flags = FIRE_PROOF|ACID_PROOF + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + siemens_coefficient = 0 + complexity_max = DEFAULT_MAX_COMPLEXITY - 5 + slowdown_inactive = 0.75 + slowdown_active = 0.25 + ui_theme = "wizard" + inbuilt_modules = list(/obj/item/mod/module/anti_magic/wizard) + skins = list( + "enchanted" = list( + HELMET_LAYER = null, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/prototype + name = "prototype" + desc = "A prototype modular suit powered by locomotives. While it is comfortable and has a big capacity, it remains very bulky and power-inefficient." + default_skin = "prototype" + armor = list(MELEE = 20, BULLET = 5, LASER = 10, ENERGY = 10, BOMB = 50, BIO = 100, FIRE = 100, ACID = 75, WOUND = 5, RAD = 0) + resistance_flags = FIRE_PROOF + complexity_max = DEFAULT_MAX_COMPLEXITY + 10 + slowdown_inactive = 2.5 + slowdown_active = 2 + ui_theme = "hackerman" + inbuilt_modules = list(/obj/item/mod/module/kinesis) + skins = list( + "prototype" = list( + HELMET_LAYER = null, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/responsory + name = "responsory" + desc = "A high-speed rescue suit by Nanotrasen, intended for its' emergency response teams." + default_skin = "responsory" + armor = list(MELEE = 50, BULLET = 40, LASER = 50, ENERGY = 50, BOMB = 50, BIO = 100, FIRE = 100, ACID = 90, WOUND = 10, RAD = 0) + resistance_flags = FIRE_PROOF + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + siemens_coefficient = 0 + slowdown_inactive = 0.5 + slowdown_active = 0 + skins = list( + "responsory" = list( + HELMET_LAYER = NECK_LAYER, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = NONE, + SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR, + SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + "inquisitory" = list( + HELMET_LAYER = null, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT, + UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/apocryphal + name = "apocryphal" + desc = "A high-tech, only technically legal, armored suit created by a collaboration effort between Nanotrasen and Apadyne Technologies." + default_skin = "apocryphal" + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 60, BOMB = 100, BIO = 100, FIRE = 100, ACID = 100, WOUND = 25, RAD = 0) + resistance_flags = FIRE_PROOF|ACID_PROOF + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + siemens_coefficient = 0 + complexity_max = DEFAULT_MAX_COMPLEXITY + 10 + skins = list( + "apocryphal" = list( + HELMET_LAYER = null, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEEARS|HIDEHAIR, + SEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEYES|HIDEFACE|HIDESNOUT, + SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/corporate + name = "corporate" + desc = "A fancy, high-tech suit for Nanotrasen's high ranking officers." + default_skin = "corporate" + armor = list(MELEE = 50, BULLET = 40, LASER = 50, ENERGY = 50, BOMB = 50, BIO = 100, FIRE = 100, ACID = 100, WOUND = 15, RAD = 0) + resistance_flags = FIRE_PROOF|ACID_PROOF + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + siemens_coefficient = 0 + slowdown_inactive = 0.5 + slowdown_active = 0 + skins = list( + "corporate" = list( + HELMET_LAYER = null, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT, + SEALED_INVISIBILITY = HIDEMASK|HIDEEYES|HIDEFACE, + SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/debug + name = "debug" + desc = "Strangely nostalgic." + default_skin = "debug" + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, FIRE = 100, ACID = 100, WOUND = 0, RAD = 25) + resistance_flags = FIRE_PROOF|ACID_PROOF + max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT + complexity_max = 50 + slowdown_inactive = 0.5 + slowdown_active = 0 + skins = list( + "debug" = list( + HELMET_LAYER = null, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT, + SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE, + UNSEALED_COVER = HEADCOVERSMOUTH, + SEALED_COVER = HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDAMAGE, + ), + ), + ) + +/datum/mod_theme/administrative + name = "administrative" + desc = "A suit made of adminium. Who comes up with these stupid mineral names?" + default_skin = "debug" + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, BIO = 100, FIRE = 100, ACID = 100, WOUND = 100, RAD = 100) + resistance_flags = INDESTRUCTIBLE|LAVA_PROOF|FIRE_PROOF|UNACIDABLE|ACID_PROOF + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + complexity_max = 1000 + cell_drain = DEFAULT_CHARGE_DRAIN * 0 + slowdown_inactive = 0 + slowdown_active = 0 + skins = list( + "debug" = list( + HELMET_LAYER = null, + HELMET_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT, + SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE, + UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, + ), + ), + ) diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm new file mode 100644 index 0000000000..565dcdc2f8 --- /dev/null +++ b/code/modules/mod/mod_types.dm @@ -0,0 +1,273 @@ +/obj/item/mod/control/pre_equipped + cell = /obj/item/stock_parts/cell/high + var/applied_skin + +/obj/item/mod/control/pre_equipped/Initialize(mapload, new_theme, new_skin) + new_skin = applied_skin + return ..() + +/obj/item/mod/control/pre_equipped/standard + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/flashlight, + ) + +/obj/item/mod/control/pre_equipped/engineering + theme = /datum/mod_theme/engineering + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/rad_protection, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/magboot, + ) + +/obj/item/mod/control/pre_equipped/atmospheric + theme = /datum/mod_theme/atmospheric + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/rad_protection, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/t_ray, + ) + +/obj/item/mod/control/pre_equipped/advanced + theme = /datum/mod_theme/advanced + cell = /obj/item/stock_parts/cell/super + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/rad_protection, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/jetpack, + ) + +/obj/item/mod/control/pre_equipped/mining + theme = /datum/mod_theme/mining + cell = /obj/item/stock_parts/cell/high/plus + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/orebag, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/magboot, + /obj/item/mod/module/drill, + ) + +/obj/item/mod/control/pre_equipped/medical + theme = /datum/mod_theme/medical + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/health_analyzer, + /obj/item/mod/module/quick_carry, + ) + +/obj/item/mod/control/pre_equipped/rescue + theme = /datum/mod_theme/rescue + cell = /obj/item/stock_parts/cell/super + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/health_analyzer, + ) + +/obj/item/mod/control/pre_equipped/research + theme = /datum/mod_theme/research + cell = /obj/item/stock_parts/cell/super + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/t_ray, + ) + +/obj/item/mod/control/pre_equipped/security + theme = /datum/mod_theme/security + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/holster, + ) + +/obj/item/mod/control/pre_equipped/safeguard + theme = /datum/mod_theme/safeguard + cell = /obj/item/stock_parts/cell/super + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/jetpack, + /obj/item/mod/module/holster, + ) + +/obj/item/mod/control/pre_equipped/magnate + theme = /datum/mod_theme/magnate + cell = /obj/item/stock_parts/cell/hyper + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/holster, + /obj/item/mod/module/jetpack/advanced, + ) + +/obj/item/mod/control/pre_equipped/traitor + theme = /datum/mod_theme/syndicate + cell = /obj/item/stock_parts/cell/super + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/dna_lock, + /obj/item/mod/module/jetpack, + ) + +/obj/item/mod/control/pre_equipped/nuclear + theme = /datum/mod_theme/syndicate + cell = /obj/item/stock_parts/cell/hyper + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/visor/thermal, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/jetpack/advanced, + /obj/item/mod/module/holster, + ) + +/obj/item/mod/control/pre_equipped/elite + theme = /datum/mod_theme/elite + cell = /obj/item/stock_parts/cell/bluespace + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/emp_shield, + /obj/item/mod/module/visor/thermal, + /obj/item/mod/module/jetpack/advanced, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/holster, + ) + +/obj/item/mod/control/pre_equipped/prototype + theme = /datum/mod_theme/prototype + cell = /obj/item/stock_parts/cell/high/plus + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/rad_protection, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/tether, + ) + +/obj/item/mod/control/pre_equipped/responsory + theme = /datum/mod_theme/responsory + cell = /obj/item/stock_parts/cell/hyper + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/emp_shield, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/holster, + ) + var/insignia_type = /obj/item/mod/module/insignia + +/obj/item/mod/control/pre_equipped/responsory/Initialize(mapload, new_theme, new_skin) + initial_modules.Insert(1, insignia_type) + return ..() + +/obj/item/mod/control/pre_equipped/responsory/commander + insignia_type = /obj/item/mod/module/insignia/commander + +/obj/item/mod/control/pre_equipped/responsory/security + insignia_type = /obj/item/mod/module/insignia/security + +/obj/item/mod/control/pre_equipped/responsory/engineer + insignia_type = /obj/item/mod/module/insignia/engineer + +/obj/item/mod/control/pre_equipped/responsory/medic + insignia_type = /obj/item/mod/module/insignia/medic + +/obj/item/mod/control/pre_equipped/responsory/janitor + insignia_type = /obj/item/mod/module/insignia/janitor + +/obj/item/mod/control/pre_equipped/responsory/clown + insignia_type = /obj/item/mod/module/insignia/clown + +/obj/item/mod/control/pre_equipped/responsory/chaplain + insignia_type = /obj/item/mod/module/insignia/chaplain + +/obj/item/mod/control/pre_equipped/responsory/inquisitory + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/anti_magic, + /obj/item/mod/module/welding, + /obj/item/mod/module/emp_shield, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/holster, + ) + applied_skin = "inquisitory" + +/obj/item/mod/control/pre_equipped/responsory/inquisitory/commander + insignia_type = /obj/item/mod/module/insignia/commander + +/obj/item/mod/control/pre_equipped/responsory/inquisitory/security + insignia_type = /obj/item/mod/module/insignia/security + +/obj/item/mod/control/pre_equipped/responsory/inquisitory/medic + insignia_type = /obj/item/mod/module/insignia/medic + +/obj/item/mod/control/pre_equipped/responsory/inquisitory/chaplain + insignia_type = /obj/item/mod/module/insignia/chaplain + +/obj/item/mod/control/pre_equipped/apocryphal + theme = /datum/mod_theme/apocryphal + cell = /obj/item/stock_parts/cell/bluespace + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/emp_shield, + /obj/item/mod/module/holster, + /obj/item/mod/module/jetpack, + ) + +/obj/item/mod/control/pre_equipped/corporate + theme = /datum/mod_theme/corporate + cell = /obj/item/stock_parts/cell/bluespace + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/holster, + ) + +/obj/item/mod/control/pre_equipped/debug + theme = /datum/mod_theme/debug + cell = /obj/item/stock_parts/cell/bluespace + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/flashlight, + /obj/item/mod/module/bikehorn, + /obj/item/mod/module/rad_protection, + /obj/item/mod/module/tether, + ) //one of every type of module, for testing if they all work correctly + +/obj/item/mod/control/pre_equipped/administrative + theme = /datum/mod_theme/administrative + cell = /obj/item/stock_parts/cell/infinite/abductor + initial_modules = list( + /obj/item/mod/module/storage, + /obj/item/mod/module/welding, + /obj/item/mod/module/quick_carry/advanced, + /obj/item/mod/module/magboot/advanced, + /obj/item/mod/module/jetpack/advanced, + ) + +//these exist for the prefs menu +/obj/item/mod/control/pre_equipped/syndicate_empty + theme = /datum/mod_theme/syndicate + +/obj/item/mod/control/pre_equipped/syndicate_empty/elite + theme = /datum/mod_theme/elite + +INITIALIZE_IMMEDIATE(/obj/item/mod/control/pre_equipped/syndicate_empty) diff --git a/code/modules/mod/mod_ui.dm b/code/modules/mod/mod_ui.dm new file mode 100644 index 0000000000..1923db6f29 --- /dev/null +++ b/code/modules/mod/mod_ui.dm @@ -0,0 +1,78 @@ +/obj/item/mod/control/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "MODsuit", name) + ui.open() + +/obj/item/mod/control/ui_data(mob/user) + var/data = list() + data["interface_break"] = interface_break + data["malfunctioning"] = malfunctioning + data["open"] = open + data["active"] = active + data["complexity"] = complexity + data["selected_module"] = selected_module?.name + data["wearer_name"] = wearer ? (wearer.get_authentification_name("Unknown") || "Unknown") : "No Occupant" + data["wearer_job"] = wearer ? wearer.get_assignment("Unknown", "Unknown", FALSE) : "No Job" + data["AI"] = ai?.name + data["is_pAI"] = ai ? ispAI(ai) : FALSE + data["is_user_AI"] = ai ? user == ai : FALSE + data["cell"] = cell?.name + data["charge"] = cell ? round(cell.percent(), 1) : 0 + data["modules"] = list() + for(var/obj/item/mod/module/module as anything in modules) + var/list/module_data = list( + name = module.name, + description = module.desc, + module_type = module.module_type, + active = module.active, + idle_power = module.idle_power_cost, + active_power = module.active_power_cost, + use_power = module.use_power_cost, + complexity = module.complexity, + cooldown_time = module.cooldown_time, + cooldown = round(COOLDOWN_TIMELEFT(module, cooldown_timer), 1 SECONDS), + id = module.tgui_id, + ref = REF(module), + configuration_data = module.get_configuration() + ) + module_data += module.add_ui_data() + data["modules"] += list(module_data) + return data + +/obj/item/mod/control/ui_static_data(mob/user) + var/data = list() + data["ui_theme"] = ui_theme + data["control"] = name + data["complexity_max"] = complexity_max + data["helmet"] = helmet?.name + data["chestplate"] = chestplate?.name + data["gauntlets"] = gauntlets?.name + data["boots"] = boots?.name + return data + +/obj/item/mod/control/ui_act(action, params) + . = ..() + if(.) + return + if(malfunctioning && prob(75)) + balloon_alert(usr, "button malfunctions!") + return + switch(action) + if("activate") + toggle_activate(usr) + if("select") + var/obj/item/mod/module/module = locate(params["ref"]) in modules + if(!module) + return + module.on_select() + if("configure") + var/obj/item/mod/module/module = locate(params["ref"]) in modules + if(!module) + return + module.configure_edit(params["key"], params["value"]) + if("remove_pai") + if(ishuman(usr)) // Only the MODsuit's wearer should be removing the pAI. + var/mob/user = usr + extract_pai(user) + return TRUE diff --git a/code/modules/mod/modules/_module.dm b/code/modules/mod/modules/_module.dm new file mode 100644 index 0000000000..2d008cad1c --- /dev/null +++ b/code/modules/mod/modules/_module.dm @@ -0,0 +1,357 @@ +/obj/item/mod/module + name = "MOD module" + icon = 'icons/obj/clothing/modsuit/mod_modules.dmi' + icon_state = "module" + /// If it can be removed + var/removable = TRUE + /// If it's passive, togglable, usable or active + var/module_type = MODULE_PASSIVE + /// Is the module active + var/active = FALSE + /// How much space it takes up in the MOD + var/complexity = 0 + /// Power use when idle + var/idle_power_cost = DEFAULT_CHARGE_DRAIN * 0 + /// Power use when active + var/active_power_cost = DEFAULT_CHARGE_DRAIN * 0 + /// Power use when used, we call it manually + var/use_power_cost = DEFAULT_CHARGE_DRAIN * 0 + /// ID used by their TGUI + var/tgui_id + /// Linked MODsuit + var/obj/item/mod/control/mod + /// If we're an active module, what item are we? + var/obj/item/device + /// Overlay given to the user when the module is inactive + var/overlay_state_inactive + /// Overlay given to the user when the module is active + var/overlay_state_active + /// Overlay given to the user when the module is used, lasts until cooldown finishes + var/overlay_state_use + /// Icon file for the overlay. + var/overlay_icon_file = 'icons/mob/clothing/modsuit/mod_modules.dmi' + /// Does the overlay use the control unit's colors? + var/use_mod_colors = FALSE + /// What modules are we incompatible with? + var/list/incompatible_modules = list() + /// Cooldown after use + var/cooldown_time = 0 + /// The mouse button needed to use this module + var/used_signal + /// If we're allowed to use this module while phased out. + var/allowed_in_phaseout = FALSE + /// If we're allowed to use this module while the suit is disabled. + var/allowed_inactive = FALSE + /// Timer for the cooldown + COOLDOWN_DECLARE(cooldown_timer) + +/obj/item/mod/module/Initialize(mapload) + . = ..() + if(module_type != MODULE_ACTIVE) + return + if(ispath(device)) + device = new device(src) + ADD_TRAIT(device, TRAIT_NODROP, MOD_TRAIT) + RegisterSignal(device, COMSIG_PARENT_PREQDELETED, .proc/on_device_deletion) + RegisterSignal(src, COMSIG_ATOM_EXITED, .proc/on_exit) + +/obj/item/mod/module/Destroy() + mod?.uninstall(src) + if(device) + UnregisterSignal(device, COMSIG_PARENT_PREQDELETED) + QDEL_NULL(device) + return ..() + +/obj/item/mod/module/examine(mob/user) + . = ..() + if(user.hud_list[DIAG_HUD] && user.client.images & user.hud_list[DIAG_HUD]) + . += span_notice("Complexity level: [complexity]") + +/// Called from MODsuit's install() proc, so when the module is installed. +/obj/item/mod/module/proc/on_install() + return + +/// Called from MODsuit's uninstall() proc, so when the module is uninstalled. +/obj/item/mod/module/proc/on_uninstall() + return + +/// Called when the MODsuit is activated +/obj/item/mod/module/proc/on_suit_activation() + return + +/// Called when the MODsuit is deactivated +/obj/item/mod/module/proc/on_suit_deactivation() + return + +/// Called when the MODsuit is equipped +/obj/item/mod/module/proc/on_equip() + return + +/// Called when the MODsuit is unequipped +/obj/item/mod/module/proc/on_unequip() + return + +/// Called when the module is selected from the TGUI +/obj/item/mod/module/proc/on_select() + if(((!mod.active || mod.activating) && !allowed_inactive) || module_type == MODULE_PASSIVE) + if(mod.wearer) + balloon_alert(mod.wearer, "not active!") + return + if(module_type != MODULE_USABLE) + if(active) + on_deactivation() + else + on_activation() + else + on_use() + SEND_SIGNAL(mod, COMSIG_MOD_MODULE_SELECTED, src) + +/// Called when the module is activated +/obj/item/mod/module/proc/on_activation() + if(!COOLDOWN_FINISHED(src, cooldown_timer)) + balloon_alert(mod.wearer, "on cooldown!") + return FALSE + if(!mod.active || mod.activating || !mod.cell?.charge) + balloon_alert(mod.wearer, "unpowered!") + return FALSE + if(!allowed_in_phaseout && istype(mod.wearer.loc, /obj/effect/dummy/phased_mob)) + //specifically a to_chat because the user is phased out. + to_chat(mod.wearer, span_warning("You cannot activate this right now.")) + return FALSE + if(module_type == MODULE_ACTIVE) + if(mod.selected_module && !mod.selected_module.on_deactivation()) + return + mod.selected_module = src + if(device) + if(mod.wearer.put_in_hands(device)) + balloon_alert(mod.wearer, "[device] extended") + RegisterSignal(mod.wearer, COMSIG_ATOM_EXITED, .proc/on_exit) + else + balloon_alert(mod.wearer, "can't extend [device]!") + return + else + update_signal() + balloon_alert(mod.wearer, "[src] activated, alt-click to use") + active = TRUE + mod.wearer.update_inv_back() + return TRUE + +/// Called when the module is deactivated +/obj/item/mod/module/proc/on_deactivation() + active = FALSE + if(module_type == MODULE_ACTIVE) + mod.selected_module = null + if(device) + mod.wearer.transferItemToLoc(device, src, TRUE) + balloon_alert(mod.wearer, "[device] retracted") + UnregisterSignal(mod.wearer, COMSIG_ATOM_EXITED) + else + balloon_alert(mod.wearer, "[src] deactivated") + UnregisterSignal(mod.wearer, used_signal) + used_signal = null + mod.wearer.update_inv_back() + return TRUE + +/// Called when the module is used +/obj/item/mod/module/proc/on_use() + if(!COOLDOWN_FINISHED(src, cooldown_timer)) + return FALSE + if(!check_power(use_power_cost)) + return FALSE + if(!allowed_in_phaseout && istype(mod.wearer.loc, /obj/effect/dummy/phased_mob)) + //specifically a to_chat because the user is phased out. + to_chat(mod.wearer, span_warning("You cannot activate this right now.")) + return FALSE + COOLDOWN_START(src, cooldown_timer, cooldown_time) + addtimer(CALLBACK(mod.wearer, /mob.proc/update_inv_back), cooldown_time) + mod.wearer.update_inv_back() + return TRUE + +/// Called when an activated module without a device is used +/obj/item/mod/module/proc/on_select_use(atom/target) + if(mod.wearer.incapacitated(ignore_grab = TRUE)) + return FALSE + mod.wearer.face_atom(target) + if(!on_use()) + return FALSE + return TRUE + +/// Called when an activated module without a device is active and the user alt/middle-clicks +/obj/item/mod/module/proc/on_special_click(mob/source, atom/target) + SIGNAL_HANDLER + on_select_use(target) + return COMSIG_MOB_CANCEL_CLICKON + +/// Called on the MODsuit's process +/obj/item/mod/module/proc/on_process(delta_time) + if(active) + if(!drain_power(active_power_cost * delta_time)) + on_deactivation() + return FALSE + on_active_process(delta_time) + else + drain_power(idle_power_cost * delta_time) + return TRUE + +/// Called on the MODsuit's process if it is an active module +/obj/item/mod/module/proc/on_active_process(delta_time) + return + +/// Drains power from the suit cell +/obj/item/mod/module/proc/drain_power(amount) + if(!check_power(amount)) + return FALSE + mod.cell.charge = max(0, mod.cell.charge - amount) + return TRUE + +/obj/item/mod/module/proc/check_power(amount) + if(!mod.cell || (mod.cell.charge < amount)) + return FALSE + return TRUE + +/// Adds additional things to the MODsuit ui_data() +/obj/item/mod/module/proc/add_ui_data() + return list() + +/// Creates a list of configuring options for this module +/obj/item/mod/module/proc/get_configuration() + return list() + +/// Generates an element of the get_configuration list with a display name, type and value +/obj/item/mod/module/proc/add_ui_configuration(display_name, type, value, list/values) + return list("display_name" = display_name, "type" = type, "value" = value, "values" = values) + +/// Receives configure edits from the TGUI and edits the vars +/obj/item/mod/module/proc/configure_edit(key, value) + return + +/// Called when the device moves to a different place on active modules +/obj/item/mod/module/proc/on_exit(datum/source, atom/movable/part, direction) + SIGNAL_HANDLER + + if(!active) + return + if(part.loc == src) + return + if(part.loc == mod.wearer) + return + if(part == device) + on_deactivation() + +/// Called when the device gets deleted on active modules +/obj/item/mod/module/proc/on_device_deletion(datum/source) + SIGNAL_HANDLER + + if(source == device) + device = null + qdel(src) + +/// Generates an icon to be used for the suit's worn overlays +/obj/item/mod/module/proc/generate_worn_overlay() + . = list() + if(!mod.active) + return + var/used_overlay + if(overlay_state_use && !COOLDOWN_FINISHED(src, cooldown_timer)) + used_overlay = overlay_state_use + else if(overlay_state_active && active) + used_overlay = overlay_state_active + else if(overlay_state_inactive) + used_overlay = overlay_state_inactive + else + return + var/mutable_appearance/module_icon = mutable_appearance(overlay_icon_file, used_overlay) + if(!use_mod_colors) + module_icon.appearance_flags |= RESET_COLOR + . += module_icon + +/// Updates the signal used by active modules to be activated +/obj/item/mod/module/proc/update_signal() + mod.selected_module.used_signal = COMSIG_MOB_ALTCLICKON + RegisterSignal(mod.wearer, mod.selected_module.used_signal, /obj/item/mod/module.proc/on_special_click) + +/obj/item/mod/module/anomaly_locked + name = "MOD anomaly locked module" + desc = "A form of a module, locked behind an anomalous core to function." + incompatible_modules = list(/obj/item/mod/module/anomaly_locked) + /// The core item the module runs off. + var/obj/item/assembly/signaler/anomaly/core + /// Accepted types of anomaly cores. + var/list/accepted_anomalies = list(/obj/item/assembly/signaler/anomaly) + /// If this one starts with a core in. + var/prebuilt = FALSE + +/obj/item/mod/module/anomaly_locked/Initialize(mapload) + . = ..() + if(!prebuilt || !length(accepted_anomalies)) + return + var/core_path = pick(accepted_anomalies) + core = new core_path(src) + update_icon_state() + +/obj/item/mod/module/anomaly_locked/Destroy() + QDEL_NULL(core) + return ..() + +/obj/item/mod/module/anomaly_locked/examine(mob/user) + . = ..() + if(!length(accepted_anomalies)) + return + if(core) + . += span_notice("There is a [core.name] installed in it. You could remove it with a screwdriver...") + else + var/list/core_list = list() + for(var/path in accepted_anomalies) + var/atom/core_path = path + core_list += initial(core_path.name) + . += span_notice("You need to insert \a [english_list(core_list, and_text = " or ")] for this module to function.") + +/obj/item/mod/module/anomaly_locked/on_select() + if(!core) + balloon_alert(mod.wearer, "no core!") + return + return ..() + +/obj/item/mod/module/anomaly_locked/on_process(delta_time) + . = ..() + if(!core) + return FALSE + +/obj/item/mod/module/anomaly_locked/on_active_process(delta_time) + if(!core) + return FALSE + return TRUE + +/obj/item/mod/module/anomaly_locked/attackby(obj/item/item, mob/living/user, params) + if(item.type in accepted_anomalies) + if(core) + balloon_alert(user, "core already in!") + return + if(!user.transferItemToLoc(item, src)) + return + core = item + balloon_alert(user, "core installed") + playsound(src, 'sound/machines/click.ogg', 30, TRUE) + update_icon_state() + else + return ..() + +/obj/item/mod/module/anomaly_locked/screwdriver_act(mob/living/user, obj/item/tool) + . = ..() + if(!core) + balloon_alert(user, "no core!") + return + balloon_alert(user, "removing core...") + if(!do_after(user, 3 SECONDS, target = src)) + balloon_alert(user, "interrupted!") + return + balloon_alert(user, "core removed") + core.forceMove(drop_location()) + if(Adjacent(user) && !issilicon(user)) + user.put_in_hands(core) + core = null + update_icon_state() + +/obj/item/mod/module/anomaly_locked/update_icon_state() + icon_state = initial(icon_state) + (core ? "-core" : "") + return ..() diff --git a/code/modules/mod/modules/modules.dm b/code/modules/mod/modules/modules.dm new file mode 100644 index 0000000000..0e0da3572b --- /dev/null +++ b/code/modules/mod/modules/modules.dm @@ -0,0 +1,96 @@ +/obj/item/mod/module/anti_magic/on_suit_activation() + ADD_TRAIT(mod.wearer, TRAIT_ANTIMAGIC, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_HOLY, MOD_TRAIT) + +/obj/item/mod/module/anti_magic/on_suit_deactivation() + REMOVE_TRAIT(mod.wearer, TRAIT_ANTIMAGIC, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_HOLY, MOD_TRAIT) + +/obj/item/mod/module/anti_magic/wizard + name = "MOD magic neutralizer module" + desc = "The caster wielding this spell gains an invisible barrier around them, channeling arcane power through \ + specialized runes engraved onto the surface of the suit to generate anti-magic field. \ + The field will neutralize all magic that comes into contact with the user. \ + It will not protect the caster from social ridicule." + icon_state = "magic_neutralizer" + +/obj/item/mod/module/anti_magic/wizard/on_suit_activation() + ADD_TRAIT(mod.wearer, TRAIT_ANTIMAGIC_NO_SELFBLOCK, MOD_TRAIT) + +/obj/item/mod/module/anti_magic/wizard/on_suit_deactivation() + REMOVE_TRAIT(mod.wearer, TRAIT_ANTIMAGIC_NO_SELFBLOCK, MOD_TRAIT) + +/obj/item/mod/module/kinesis //TODO POST-MERGE MAKE NOT SUCK ASS, MAKE BALLER AS FUCK + name = "MOD kinesis module" + desc = "A modular plug-in to the forearm, this module was presumed lost for many years, \ + despite the suits it used to be mounted on still seeing some circulation. \ + This piece of technology allows the user to generate precise anti-gravity fields, \ + letting them move objects as small as a titanium rod to as large as industrial machinery. \ + Oddly enough, it doesn't seem to work on living creatures." + icon_state = "kinesis" +// module_type = MODULE_ACTIVE + module_type = MODULE_TOGGLE +// complexity = 3 + complexity = 0 + active_power_cost = DEFAULT_CHARGE_DRAIN*0.75 +// use_power_cost = DEFAULT_CHARGE_DRAIN*3 + removable = FALSE + incompatible_modules = list(/obj/item/mod/module/kinesis) + cooldown_time = 0.5 SECONDS + var/has_tk = FALSE + +/obj/item/mod/module/kinesis/on_activation() + . = ..() + if(!.) + return + if(mod.wearer.dna.check_mutation(TK)) + has_tk = TRUE + else + mod.wearer.dna.add_mutation(TK) + +/obj/item/mod/module/kinesis/on_deactivation() + . = ..() + if(!.) + return + if(has_tk) + has_tk = FALSE + return + mod.wearer.dna.remove_mutation(TK) + +/obj/item/mod/module/insignia + name = "MOD insignia module" + desc = "Despite the existence of IFF systems, radio communique, and modern methods of deductive reasoning involving \ + the wearer's own eyes, colorful paint jobs remain a popular way for different factions in the galaxy to display who \ + they are. This system utilizes a series of tiny moving paint sprayers to both apply and remove different \ + color patterns to and from the suit." + icon_state = "insignia" + removable = FALSE + incompatible_modules = list(/obj/item/mod/module/insignia) + overlay_state_inactive = "insignia" + +/obj/item/mod/module/insignia/generate_worn_overlay() + overlay_state_inactive = "[initial(overlay_state_inactive)]-[mod.skin]" + . = ..() + for(var/mutable_appearance/appearance as anything in .) + appearance.color = color + +/obj/item/mod/module/insignia/commander + color = "#4980a5" + +/obj/item/mod/module/insignia/security + color = "#b30d1e" + +/obj/item/mod/module/insignia/engineer + color = "#e9c80e" + +/obj/item/mod/module/insignia/medic + color = "#ebebf5" + +/obj/item/mod/module/insignia/janitor + color = "#7925c7" + +/obj/item/mod/module/insignia/clown + color = "#ff1fc7" + +/obj/item/mod/module/insignia/chaplain + color = "#f0a00c" diff --git a/code/modules/mod/modules/modules_engineering.dm b/code/modules/mod/modules/modules_engineering.dm new file mode 100644 index 0000000000..cc0a6812f1 --- /dev/null +++ b/code/modules/mod/modules/modules_engineering.dm @@ -0,0 +1,215 @@ +//Engineering modules for MODsuits + +///Welding Protection - Makes the helmet protect from flashes and welding. +/obj/item/mod/module/welding + name = "MOD welding protection module" + desc = "A module installed into the visor of the suit, this projects a \ + polarized, holographic overlay in front of the user's eyes. It's rated high enough for \ + immunity against extremities such as spot and arc welding, solar eclipses, and handheld flashlights." + icon_state = "welding" + complexity = 1 + incompatible_modules = list(/obj/item/mod/module/welding) + overlay_state_inactive = "module_welding" + +/obj/item/mod/module/welding/on_suit_activation() + mod.helmet.flash_protect = 2 + +/obj/item/mod/module/welding/on_suit_deactivation(deleting = FALSE) + if(deleting) + return + mod.helmet.flash_protect = initial(mod.helmet.flash_protect) + +///T-Ray Scan - Scans the terrain for undertile objects. +/obj/item/mod/module/t_ray + name = "MOD t-ray scan module" + desc = "A module installed into the visor of the suit, allowing the user to use a pulse of terahertz radiation \ + to essentially echolocate things beneath the floor, mostly cables and pipes. \ + A staple of atmospherics work, and counter-smuggling work." + icon_state = "tray" + module_type = MODULE_TOGGLE + complexity = 1 + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.5 + incompatible_modules = list(/obj/item/mod/module/t_ray) + cooldown_time = 0.5 SECONDS + /// T-ray scan range. + var/range = 4 + +/obj/item/mod/module/t_ray/on_active_process(delta_time) + t_ray_scan(mod.wearer, 0.8 SECONDS, range) + +///Magnetic Stability - Gives the user a slowdown but makes them negate gravity and be immune to slips. +/obj/item/mod/module/magboot + name = "MOD magnetic stability module" + desc = "These are powerful electromagnets fitted into the suit's boots, allowing users both \ + excellent traction no matter the condition indoors, and to essentially hitch a ride on the exterior of a hull. \ + However, these basic models do not feature computerized systems to automatically toggle them on and off, \ + so numerous users report a certain stickiness to their steps." + icon_state = "magnet" + module_type = MODULE_TOGGLE + complexity = 2 + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.5 + incompatible_modules = list(/obj/item/mod/module/magboot) + cooldown_time = 0.5 SECONDS + /// Slowdown added onto the suit. + var/slowdown_active = 2 + +/obj/item/mod/module/magboot/on_activation() + . = ..() + if(!.) + return + mod.boots.clothing_flags |= NOSLIP + ADD_TRAIT(mod.wearer, TRAIT_NOSLIPWATER, MOD_TRAIT) + mod.slowdown += slowdown_active + mod.wearer.update_gravity(mod.wearer.has_gravity()) + mod.wearer.update_equipment_speed_mods() + +/obj/item/mod/module/magboot/on_deactivation(display_message = TRUE, deleting = FALSE) + . = ..() + if(!.) + return + mod.boots.clothing_flags &= ~NOSLIP + REMOVE_TRAIT(mod.wearer, TRAIT_NOSLIPWATER, MOD_TRAIT) + mod.slowdown -= slowdown_active + mod.wearer.update_gravity(mod.wearer.has_gravity()) + mod.wearer.update_equipment_speed_mods() + +/obj/item/mod/module/magboot/advanced + name = "MOD advanced magnetic stability module" + removable = FALSE + complexity = 0 + slowdown_active = 0 + +///Emergency Tether - Shoots a grappling hook projectile in 0g that throws the user towards it. +/obj/item/mod/module/tether + name = "MOD emergency tether module" + desc = "A custom-built grappling-hook powered by a winch capable of hauling the user. \ + While some older models of cargo-oriented grapples have capacities of a few tons, \ + these are only capable of working in zero-gravity environments, a blessing to some Engineers." + icon_state = "tether" + module_type = MODULE_ACTIVE + complexity = 3 + use_power_cost = DEFAULT_CHARGE_DRAIN + incompatible_modules = list(/obj/item/mod/module/tether) + cooldown_time = 1.5 SECONDS + +/obj/item/mod/module/tether/on_use() + if(mod.wearer.has_gravity(get_turf(src))) + balloon_alert(mod.wearer, "too much gravity!") + playsound(src, "gun_dry_fire", 25, TRUE) + return FALSE + return ..() + +/obj/item/mod/module/tether/on_select_use(atom/target) + . = ..() + if(!.) + return + var/obj/item/projectile/tether = new /obj/item/projectile/tether(mod.wearer.loc) + tether.preparePixelProjectile(target, mod.wearer) + tether.firer = mod.wearer + playsound(src, 'sound/weapons/batonextend.ogg', 25, TRUE) + INVOKE_ASYNC(tether, /obj/item/projectile.proc/fire) + drain_power(use_power_cost) + +/obj/item/projectile/tether + name = "tether" + icon_state = "tether_projectile" + icon = 'icons/obj/clothing/modsuit/mod_modules.dmi' + damage = 0 + nodamage = TRUE + range = 10 + hitsound = 'sound/weapons/batonextend.ogg' + hitsound_wall = 'sound/weapons/batonextend.ogg' + suppressed = SUPPRESSED_VERY + hit_threshhold = LATTICE_LAYER + /// Reference to the beam following the projectile. + var/line + +/obj/item/projectile/tether/fire(setAngle) + if(firer) + line = firer.Beam(src, "line", 'icons/obj/clothing/modsuit/mod_modules.dmi') + ..() + +/obj/item/projectile/tether/on_hit(atom/target) + . = ..() + if(firer) + firer.throw_at(target, 10, 1, firer, FALSE, FALSE, null, MOVE_FORCE_NORMAL, TRUE) + +/obj/item/projectile/tether/Destroy() + QDEL_NULL(line) + return ..() + +///Radiation Protection - Protects the user from radiation, gives them a geiger counter and rad info in the panel. +/obj/item/mod/module/rad_protection + name = "MOD radiation protection module" + desc = "A module utilizing polymers and reflective shielding to protect the user against ionizing radiation." + icon_state = "radshield" + complexity = 2 + idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.3 + incompatible_modules = list(/obj/item/mod/module/rad_protection) + +/obj/item/mod/module/rad_protection/on_suit_activation() + mod.armor = mod.armor.modifyRating(rad = 65) + mod.rad_flags = RAD_PROTECT_CONTENTS|RAD_NO_CONTAMINATE + for(var/obj/item/part in mod.mod_parts) + part.armor = mod.armor + part.rad_flags = mod.rad_flags + +/obj/item/mod/module/rad_protection/on_suit_deactivation(deleting = FALSE) + mod.armor = mod.armor.modifyRating(rad = -65) + mod.rad_flags = NONE + for(var/obj/item/part in mod.mod_parts) + part.armor = mod.armor + part.rad_flags = mod.rad_flags + +///Constructor - Lets you build quicker and create RCD holograms. +/obj/item/mod/module/constructor + name = "MOD constructor module" + desc = "This module entirely occupies the wearer's forearm, notably causing conflict with \ + advanced arm servos meant to carry crewmembers. However, it contains the \ + latest engineering schematics combined with inbuilt memory to help the user build walls." + icon_state = "constructor" + module_type = MODULE_USABLE + complexity = 2 + idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.2 + use_power_cost = DEFAULT_CHARGE_DRAIN * 2 + incompatible_modules = list(/obj/item/mod/module/constructor, /obj/item/mod/module/quick_carry) + cooldown_time = 11 SECONDS + +/obj/item/mod/module/constructor/on_suit_activation() + ADD_TRAIT(mod.wearer, TRAIT_QUICK_BUILD, MOD_TRAIT) + +/obj/item/mod/module/constructor/on_suit_deactivation(deleting = FALSE) + REMOVE_TRAIT(mod.wearer, TRAIT_QUICK_BUILD, MOD_TRAIT) + +///Mister - Sprays water over an area. +/obj/item/mod/module/mister + name = "MOD water mister module" + desc = "A module containing a mister, able to spray it over areas." + icon_state = "mister" + module_type = MODULE_ACTIVE + complexity = 2 + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3 + device = /obj/item/reagent_containers/spray/mister + incompatible_modules = list(/obj/item/mod/module/mister) + cooldown_time = 0.5 SECONDS + /// Volume of our reagent holder. + var/volume = 500 + +/obj/item/mod/module/mister/Initialize(mapload) + create_reagents(volume, OPENCONTAINER) + return ..() + +///Resin Mister - Sprays resin over an area. +/obj/item/mod/module/mister/atmos + name = "MOD resin mister module" + desc = "An atmospheric resin mister, able to fix up areas quickly." + device = /obj/item/extinguisher/mini/nozzle/mod + volume = 250 + +/obj/item/mod/module/mister/atmos/Initialize(mapload) + . = ..() + reagents.add_reagent(/datum/reagent/water, volume) + +/obj/item/extinguisher/mini/nozzle/mod + name = "MOD atmospheric mister" + desc = "An atmospheric resin mister with three modes, mounted as a module." diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm new file mode 100644 index 0000000000..1fa49f57e9 --- /dev/null +++ b/code/modules/mod/modules/modules_general.dm @@ -0,0 +1,395 @@ +//General modules for MODsuits + +///Storage - Adds a storage component to the suit. +/obj/item/mod/module/storage + name = "MOD storage containment module" + desc = "What amounts to a series of integrated storage compartments and specialized pockets installed across \ + the surface of the suit, useful for storing various bits, and or bobs." + icon_state = "storage" + complexity = 3 + incompatible_modules = list(/obj/item/mod/module/storage) + module_type = MODULE_USABLE + cooldown_time = 0.5 SECONDS + allowed_inactive = TRUE + /// Bag we have stored. + var/obj/item/storage/backpack/stored + +/obj/item/mod/module/storage/attackby(obj/item/I, mob/user, params) + if(!istype(I, /obj/item/storage/backpack)) + return ..() + var/obj/item/storage/backpack/B = I + if(stored) + balloon_alert(user, "backpack already installed!") + return + if(!user.transferItemToLoc(B, src)) + return + stored = B + balloon_alert(user, "backpack installed") + playsound(src, 'sound/machines/click.ogg', 30, TRUE) + +/obj/item/mod/module/storage/screwdriver_act(mob/living/user, obj/item/tool) + . = ..() + if(!stored) + balloon_alert(user, "no backpack!") + return + balloon_alert(user, "removing backpack...") + if(!do_after(user, 3 SECONDS, target = src)) + balloon_alert(user, "interrupted!") + return + balloon_alert(user, "backpack removed") + stored.forceMove(drop_location()) + if(Adjacent(user) && !issilicon(user)) + user.put_in_hands(stored) + stored = null + +/obj/item/mod/module/storage/on_use() + . = ..() + if(!.) + return + if(!stored) + var/obj/item/storage/backpack/holding = mod.wearer.get_active_held_item() + if(!holding) + balloon_alert(mod.wearer, "no backpack installed!") + return + if(!istype(holding)) + balloon_alert(mod.wearer, "it doesn't fit!") + return + if(mod.wearer.transferItemToLoc(holding, src, force = FALSE, silent = TRUE)) + stored = holding + balloon_alert(mod.wearer, "backpack stored") + playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE) + else if(mod.wearer.put_in_active_hand(stored, forced = FALSE, ignore_animation = TRUE)) + balloon_alert(mod.wearer, "backpack retrieved") + playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE) + else + balloon_alert(mod.wearer, "backpack storage full!") + +/obj/item/mod/module/storage/Exited(atom/movable/gone, direction) + . = ..() + if(gone == stored) + stored = null + +/obj/item/mod/module/storage/Destroy() + QDEL_NULL(stored) + return ..() + +///Ion Jetpack - Lets the user fly freely through space using battery charge. +/obj/item/mod/module/jetpack + name = "MOD ion jetpack module" + desc = "A series of electric thrusters installed across the suit, this is a module highly anticipated by trainee Engineers. \ + Rather than using gasses for combustion thrust, these jets are capable of accelerating ions using \ + charge from the suit's charge. Some say this isn't Nakamura Engineering's first foray into jet-enabled suits." + icon_state = "jetpack" + module_type = MODULE_TOGGLE + complexity = 3 + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.5 + use_power_cost = DEFAULT_CHARGE_DRAIN + incompatible_modules = list(/obj/item/mod/module/jetpack) + cooldown_time = 0.5 SECONDS + overlay_state_inactive = "module_jetpack" + overlay_state_active = "module_jetpack_on" + /// Do we stop the wearer from gliding in space. + var/stabilizers = FALSE + /// Do we give the wearer a speed buff. + var/full_speed = FALSE + var/datum/effect_system/trail_follow/ion/ion_trail + +/obj/item/mod/module/jetpack/Initialize(mapload) + . = ..() + ion_trail = new + ion_trail.set_up(src) + +/obj/item/mod/module/jetpack/Destroy() + QDEL_NULL(ion_trail) + return ..() + +/obj/item/mod/module/jetpack/on_activation() + . = ..() + if(!.) + return + ion_trail.start() + RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, .proc/move_react) + if(full_speed) + mod.wearer.add_movespeed_modifier(/datum/movespeed_modifier/jetpack/fullspeed) + else + mod.wearer.add_movespeed_modifier(/datum/movespeed_modifier/jetpack) + +/obj/item/mod/module/jetpack/on_deactivation(display_message = TRUE, deleting = FALSE) + . = ..() + stabilizers = FALSE + ion_trail.stop() + UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED) + mod.wearer.remove_movespeed_modifier(/datum/movespeed_modifier/jetpack/fullspeed) + mod.wearer.remove_movespeed_modifier(/datum/movespeed_modifier/jetpack) + +/obj/item/mod/module/jetpack/get_configuration() + . = ..() + .["stabilizers"] = add_ui_configuration("Stabilizers", "bool", stabilizers) + +/obj/item/mod/module/jetpack/configure_edit(key, value) + switch(key) + if("stabilizers") + stabilizers = text2num(value) + +/obj/item/mod/module/jetpack/proc/move_react(mob/user) + allow_thrust() + +/obj/item/mod/module/jetpack/proc/allow_thrust(use_fuel = TRUE) + if(!active) + return FALSE + if(!use_fuel) + return check_power(use_power_cost) + if(!drain_power(use_power_cost)) + return FALSE + return TRUE + +/obj/item/mod/module/jetpack/advanced + name = "MOD advanced ion jetpack module" + desc = "An improvement on the previous model of electric thrusters. This one achieves higher speeds through \ + mounting of more jets and a red paint applied on it." + icon_state = "jetpack_advanced" + overlay_state_inactive = "module_jetpackadv" + overlay_state_active = "module_jetpackadv_on" + full_speed = TRUE + +///Eating Apparatus - Lets the user eat/drink with the suit on. +/obj/item/mod/module/mouthhole + name = "MOD eating apparatus module" + desc = "A favorite by Miners, this modification to the helmet utilizes a nanotechnology barrier infront of the mouth \ + to allow eating and drinking while retaining protection and atmosphere. However, it won't free you from masks, \ + lets pepper spray pass through and it will do nothing to improve the taste of a goliath steak." + icon_state = "apparatus" + complexity = 1 + incompatible_modules = list(/obj/item/mod/module/mouthhole) + overlay_state_inactive = "module_apparatus" + /// Former flags of the helmet. + var/former_flags = NONE + /// Former visor flags of the helmet. + var/former_visor_flags = NONE + +/obj/item/mod/module/mouthhole/on_install() + former_flags = mod.helmet.flags_cover + former_visor_flags = mod.helmet.visor_flags_cover + mod.helmet.flags_cover &= ~HEADCOVERSMOUTH + mod.helmet.visor_flags_cover &= ~HEADCOVERSMOUTH + +/obj/item/mod/module/mouthhole/on_uninstall(deleting = FALSE) + if(deleting) + return + mod.helmet.flags_cover |= former_flags + mod.helmet.visor_flags_cover |= former_visor_flags + +///EMP Shield - Protects the suit from EMPs. +/obj/item/mod/module/emp_shield + name = "MOD EMP shield module" + desc = "A field inhibitor installed into the suit, protecting it against feedback such as \ + electromagnetic pulses that would otherwise damage the electronic systems of the suit or it's modules. \ + However, it will take from the suit's power to do so." + icon_state = "empshield" + complexity = 1 + idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.3 + incompatible_modules = list(/obj/item/mod/module/emp_shield) + +/obj/item/mod/module/emp_shield/on_install() + mod.AddElement(/datum/element/empprotection, EMP_PROTECT_SELF|EMP_PROTECT_WIRES|EMP_PROTECT_CONTENTS) + +/obj/item/mod/module/emp_shield/on_uninstall(deleting = FALSE) + mod.RemoveElement(/datum/element/empprotection, EMP_PROTECT_SELF|EMP_PROTECT_WIRES|EMP_PROTECT_CONTENTS) + +/obj/item/mod/module/emp_shield/advanced + name = "MOD advanced EMP shield module" + desc = "An advanced field inhibitor installed into the suit, protecting it against feedback such as \ + electromagnetic pulses that would otherwise damage the electronic systems of the suit or electronic devices on the wearer, \ + including augmentations. However, it will take from the suit's power to do so." + complexity = 2 + +/obj/item/mod/module/emp_shield/advanced/on_suit_activation() + mod.wearer.AddElement(/datum/element/empprotection, EMP_PROTECT_SELF|EMP_PROTECT_CONTENTS) + +/obj/item/mod/module/emp_shield/advanced/on_suit_deactivation(deleting) + mod.wearer.RemoveElement(/datum/element/empprotection, EMP_PROTECT_SELF|EMP_PROTECT_CONTENTS) + +///Flashlight - Gives the suit a customizable flashlight. +/obj/item/mod/module/flashlight + name = "MOD flashlight module" + desc = "A simple pair of configurable flashlights installed on the left and right sides of the helmet, \ + useful for providing light in a variety of ranges and colors. \ + Some survivalists prefer the color green for their illumination, for reasons unknown." + icon_state = "flashlight" + module_type = MODULE_TOGGLE + complexity = 1 + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3 + incompatible_modules = list(/obj/item/mod/module/flashlight) + cooldown_time = 0.5 SECONDS + overlay_state_inactive = "module_light" + light_color = COLOR_WHITE + light_range = 4 + light_power = 1 + /// Charge drain per range amount. + var/base_power = DEFAULT_CHARGE_DRAIN * 0.1 + /// Minimum range we can set. + var/min_range = 2 + /// Maximum range we can set. + var/max_range = 5 + +/obj/item/mod/module/flashlight/on_activation() + . = ..() + if(!.) + return + mod.set_light(light_range, light_power, light_color) + active_power_cost = base_power * light_range + +/obj/item/mod/module/flashlight/on_deactivation(display_message = TRUE, deleting = FALSE) + . = ..() + if(!.) + return + mod.set_light(0, 0) + +/obj/item/mod/module/flashlight/on_process(delta_time) + active_power_cost = base_power * light_range + return ..() + +/obj/item/mod/module/flashlight/generate_worn_overlay() + . = ..() + if(!active) + return + var/mutable_appearance/light_icon = mutable_appearance(overlay_icon_file, "module_light_on") + light_icon.appearance_flags = RESET_COLOR + light_icon.color = light_color + . += light_icon + +/obj/item/mod/module/flashlight/get_configuration() + . = ..() + .["light_color"] = add_ui_configuration("Light Color", "color", light_color) + .["light_range"] = add_ui_configuration("Light Range", "number", light_range) + +/obj/item/mod/module/flashlight/configure_edit(key, value) + switch(key) + if("light_color") + value = input(usr, "Pick new light color", "Flashlight Color") as color|null + if(!value) + return + var/list/hsl = rgb2hsl(hex2num(copytext(value,2,4)),hex2num(copytext(value,4,6)),hex2num(copytext(value,6,8))) + if(hsl[3] < 0.5) + balloon_alert(mod.wearer, "too dark!") + return + mod.set_light_color(value) + mod.wearer.regenerate_icons() + light_color = value + if("light_range") + mod.set_light_range(clamp(value, min_range, max_range)) + light_range = clamp(value, min_range, max_range) + +///Dispenser - Dispenses an item after a time passes. +/obj/item/mod/module/dispenser + name = "MOD burger dispenser module" + desc = "A rare piece of technology reverse-engineered from a prototype found in a Donk Corporation vessel. \ + This can draw incredible amounts of power from the suit's charge to create edible organic matter in the \ + palm of the wearer's glove; however, research seemed to have entirely stopped at burgers. \ + Notably, all attempts to get it to dispense Earl Grey tea have failed." + icon_state = "dispenser" + module_type = MODULE_USABLE + complexity = 3 + use_power_cost = DEFAULT_CHARGE_DRAIN * 2 + incompatible_modules = list(/obj/item/mod/module/dispenser) + cooldown_time = 5 SECONDS + /// Path we dispense. + var/dispense_type = /obj/item/reagent_containers/food/snacks/burger/plain + /// Time it takes for us to dispense. + var/dispense_time = 0 SECONDS + +/obj/item/mod/module/dispenser/on_use() + . = ..() + if(!.) + return + if(dispense_time && !do_after(mod.wearer, dispense_time, target = mod)) + balloon_alert(mod.wearer, "interrupted!") + return FALSE + var/obj/item/dispensed = new dispense_type(mod.wearer.loc) + mod.wearer.put_in_hands(dispensed) + balloon_alert(mod.wearer, "[dispensed] dispensed") + playsound(src, 'sound/machines/click.ogg', 100, TRUE) + drain_power(use_power_cost) + return dispensed + +///Longfall + +///Thermal Regulator - Naw. + +///DNA Lock - Prevents people without the set DNA from activating the suit. +/obj/item/mod/module/dna_lock + name = "MOD DNA lock module" + desc = "A module which engages with the various locks and seals tied to the suit's systems, \ + enabling it to only be worn by someone corresponding with the user's exact DNA profile; \ + however, this incredibly sensitive module is shorted out by EMPs. Luckily, cloning has been outlawed." + icon_state = "dnalock" + module_type = MODULE_USABLE + complexity = 2 + use_power_cost = DEFAULT_CHARGE_DRAIN * 3 + incompatible_modules = list(/obj/item/mod/module/dna_lock) + cooldown_time = 0.5 SECONDS + /// The DNA we lock with. + var/dna = null + +/obj/item/mod/module/dna_lock/on_install() + RegisterSignal(mod, COMSIG_MOD_ACTIVATE, .proc/on_mod_activation) + RegisterSignal(mod, COMSIG_MOD_MODULE_REMOVAL, .proc/on_mod_removal) + RegisterSignal(mod, COMSIG_ATOM_EMP_ACT, .proc/on_emp) + RegisterSignal(mod, COMSIG_ATOM_EMAG_ACT, .proc/on_emag) + +/obj/item/mod/module/dna_lock/on_uninstall(deleting = FALSE) + UnregisterSignal(mod, COMSIG_MOD_ACTIVATE) + UnregisterSignal(mod, COMSIG_MOD_MODULE_REMOVAL) + UnregisterSignal(mod, COMSIG_ATOM_EMP_ACT) + UnregisterSignal(mod, COMSIG_ATOM_EMAG_ACT) + +/obj/item/mod/module/dna_lock/on_use() + . = ..() + if(!.) + return + dna = mod.wearer.dna.unique_enzymes + balloon_alert(mod.wearer, "dna updated") + drain_power(use_power_cost) + +/obj/item/mod/module/dna_lock/emp_act(severity) + . = ..() + if(. & EMP_PROTECT_SELF) + return + on_emp(src, severity) + +/obj/item/mod/module/dna_lock/emag_act(mob/user, obj/item/card/emag/emag_card) + . = ..() + on_emag(src, user, emag_card) + +/obj/item/mod/module/dna_lock/proc/dna_check(mob/user) + if(!iscarbon(user)) + return FALSE + var/mob/living/carbon/carbon_user = user + if(!dna || (carbon_user.has_dna() && carbon_user.dna.unique_enzymes == dna)) + return TRUE + balloon_alert(user, "dna locked!") + return FALSE + +/obj/item/mod/module/dna_lock/proc/on_emp(datum/source, severity) + SIGNAL_HANDLER + + dna = null + +/obj/item/mod/module/dna_lock/proc/on_emag(datum/source, mob/user, obj/item/card/emag/emag_card) + SIGNAL_HANDLER + + dna = null + +/obj/item/mod/module/dna_lock/proc/on_mod_activation(datum/source, mob/user) + SIGNAL_HANDLER + + if(!dna_check(user)) + return MOD_CANCEL_ACTIVATE + +/obj/item/mod/module/dna_lock/proc/on_mod_removal(datum/source, mob/user) + SIGNAL_HANDLER + + if(!dna_check(user)) + return MOD_CANCEL_REMOVAL + +///Sign Language Translator - I want, but no diff --git a/code/modules/mod/modules/modules_maint.dm b/code/modules/mod/modules/modules_maint.dm new file mode 100644 index 0000000000..65a5be5dc6 --- /dev/null +++ b/code/modules/mod/modules/modules_maint.dm @@ -0,0 +1,157 @@ +//Maint modules for MODsuits + +///Springlock Mechanism - allows your modsuit to activate faster, but reagents are very dangerous. +/obj/item/mod/module/springlock + name = "MOD springlock module" + desc = "A module that spans the entire size of the MOD unit, sitting under the outer shell. \ + This mechanical exoskeleton pushes out of the way when the user enters and it helps in booting \ + up, but was taken out of modern suits because of the springlock's tendency to \"snap\" back \ + into place when exposed to humidity. You know what it's like to have an entire exoskeleton enter you?" + icon_state = "springlock" + complexity = 3 // it is inside every part of your suit, so + incompatible_modules = list(/obj/item/mod/module/springlock) + +/obj/item/mod/module/springlock/on_install() + mod.activation_step_time *= 0.5 + +/obj/item/mod/module/springlock/on_uninstall(deleting = FALSE) + mod.activation_step_time *= 2 + +/obj/item/mod/module/springlock/on_suit_activation() + RegisterSignal(mod.wearer, COMSIG_ATOM_EXPOSE_REAGENTS, .proc/on_wearer_exposed) + +/obj/item/mod/module/springlock/on_suit_deactivation(deleting = FALSE) + UnregisterSignal(mod.wearer, COMSIG_ATOM_EXPOSE_REAGENTS) + +///Signal fired when wearer is exposed to reagents +/obj/item/mod/module/springlock/proc/on_wearer_exposed(atom/source, list/reagents, datum/reagents/source_reagents, methods, volume_modifier, show_message, from_gas) + SIGNAL_HANDLER + + if(!reagents.len) + return + if(!(methods == VAPOR || methods == PATCH || methods == TOUCH)) + return //remove non-touch reagent exposure + to_chat(mod.wearer, span_danger("[src] makes an ominous click sound...")) + playsound(src, 'sound/items/modsuit/springlock.ogg', 75, TRUE) + addtimer(CALLBACK(src, .proc/snap_shut), rand(3 SECONDS, 5 SECONDS)) + RegisterSignal(mod, COMSIG_MOD_ACTIVATE, .proc/on_activate_spring_block) + +///Signal fired when wearer attempts to activate/deactivate suits +/obj/item/mod/module/springlock/proc/on_activate_spring_block(datum/source, user) + SIGNAL_HANDLER + + balloon_alert(user, "springlocks aren't responding...?") + return MOD_CANCEL_ACTIVATE + +///Delayed death proc of the suit after the wearer is exposed to reagents +/obj/item/mod/module/springlock/proc/snap_shut() + UnregisterSignal(mod, COMSIG_MOD_ACTIVATE) + if(!mod.wearer) //while there is a guaranteed user when on_wearer_exposed() fires, that isn't the same case for this proc + return + mod.wearer.visible_message("[src] inside [mod.wearer]'s [mod.name] snaps shut, mutilating the user inside!", span_userdanger("*SNAP*")) + mod.wearer.emote("scream") + playsound(mod.wearer, 'sound/effects/snap.ogg', 75, TRUE, frequency = 0.5) + playsound(mod.wearer, 'sound/effects/splat.ogg', 50, TRUE, frequency = 0.5) + mod.wearer.client?.give_award(/datum/award/achievement/misc/springlock, mod.wearer) + mod.wearer.apply_damage(500, BRUTE, forced = TRUE, spread_damage = TRUE, sharpness = SHARP_POINTY) //boggers, bogchamp, etc + if(!HAS_TRAIT(mod.wearer, TRAIT_NODEATH)) + mod.wearer.death() //just in case, for some reason, they're still alive + flash_color(mod.wearer, flash_color = "#FF0000", flash_time = 10 SECONDS) + +///Rave Visor - Pointless + +///Tanner - Maybe another time + +///Balloon Blower - Blows a balloon. +/obj/item/mod/module/balloon + name = "MOD balloon blower module" + desc = "A strange module invented years ago by some ingenious mimes. It blows balloons." + icon_state = "bloon" + module_type = MODULE_USABLE + complexity = 1 + use_power_cost = DEFAULT_CHARGE_DRAIN * 0.5 + incompatible_modules = list(/obj/item/mod/module/balloon) + cooldown_time = 15 SECONDS + +/obj/item/mod/module/balloon/on_use() + . = ..() + if(!.) + return + if(!do_after(mod.wearer, 10 SECONDS, target = mod)) + return FALSE + mod.wearer.adjustOxyLoss(20) + playsound(src, 'sound/items/modsuit/inflate_bloon.ogg', 50, TRUE) + var/obj/item/toy/balloon/balloon = new(get_turf(src)) + mod.wearer.put_in_hands(balloon) + drain_power(use_power_cost) + +///Paper Dispenser - Dispenses (sometimes burning) paper sheets. +/obj/item/mod/module/paper_dispenser + name = "MOD paper dispenser module" + desc = "A simple module designed by the bureaucrats of Torch Bay. \ + It dispenses 'warm, clean, and crisp sheets of paper' onto a nearby table. Usually." + icon_state = "paper_maker" + module_type = MODULE_USABLE + complexity = 1 + use_power_cost = DEFAULT_CHARGE_DRAIN * 0.5 + incompatible_modules = list(/obj/item/mod/module/paper_dispenser) + cooldown_time = 5 SECONDS + /// The total number of sheets created by this MOD. The more sheets, them more likely they set on fire. + var/num_sheets_dispensed = 0 + +/obj/item/mod/module/paper_dispenser/on_use() + . = ..() + if(!.) + return + if(!do_after(mod.wearer, 1 SECONDS, target = mod)) + return FALSE + + var/obj/item/paper/crisp_paper = new(get_turf(src)) + crisp_paper.desc = "It's crisp and warm to the touch. Must be fresh." + + var/obj/structure/table/nearby_table = locate() in range(1, mod.wearer) + playsound(get_turf(src), 'sound/machines/click.ogg', 50, TRUE) + balloon_alert(mod.wearer, "dispensed paper[nearby_table ? " onto table":""]") + + mod.wearer.put_in_hands(crisp_paper) + if(nearby_table) + mod.wearer.transferItemToLoc(crisp_paper, nearby_table.drop_location(), silent = FALSE) + + // Up to a 30% chance to set the sheet on fire, +2% per sheet made + if(prob(min(num_sheets_dispensed * 2, 30))) + if(crisp_paper in mod.wearer.held_items) + mod.wearer.dropItemToGround(crisp_paper, force = TRUE) + crisp_paper.balloon_alert(mod.wearer, "PC LOAD LETTER!") + crisp_paper.visible_message(span_warning("[crisp_paper] bursts into flames, it's too crisp!")) + crisp_paper.fire_act(1000, 100) + + drain_power(use_power_cost) + num_sheets_dispensed++ + + +///Stamper - Extends a stamp that can switch between accept/deny modes. +/obj/item/mod/module/stamp + name = "MOD stamper module" + desc = "A module installed into the wrist of the suit, this functions as a high-power stamp, \ + able to switch between accept and deny modes." + icon_state = "stamp" + module_type = MODULE_ACTIVE + complexity = 1 + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3 + device = /obj/item/stamp/mod + incompatible_modules = list(/obj/item/mod/module/stamp) + cooldown_time = 0.5 SECONDS + +/obj/item/stamp/mod + name = "MOD electronic stamp" + desc = "A high-power stamp, able to switch between accept and deny mode when used." + +/obj/item/stamp/mod/attack_self(mob/user, modifiers) + . = ..() + if(icon_state == "stamp-ok") + icon_state = "stamp-deny" + else + icon_state = "stamp-ok" + balloon_alert(user, "switched mode") + +///Atrocinator - Perhaps another time diff --git a/code/modules/mod/modules/modules_medical.dm b/code/modules/mod/modules/modules_medical.dm new file mode 100644 index 0000000000..c7e1510152 --- /dev/null +++ b/code/modules/mod/modules/modules_medical.dm @@ -0,0 +1,189 @@ +//Medical modules for MODsuits + +#define HEALTH_SCAN "Health" +#define WOUND_SCAN "Wound" +#define CHEM_SCAN "Chemical" + +///Health Analyzer - Gives the user a ranged health analyzer and their health status in the panel. +/obj/item/mod/module/health_analyzer + name = "MOD health analyzer module" + desc = "A module installed into the glove of the suit. This is a high-tech biological scanning suite, \ + allowing the user indepth information on the vitals and injuries of others even at a distance, \ + all with the flick of the wrist. Data is displayed in a convenient package on HUD in the helmet, \ + but it's up to you to do something with it." + icon_state = "health" + module_type = MODULE_ACTIVE + complexity = 2 + use_power_cost = DEFAULT_CHARGE_DRAIN + incompatible_modules = list(/obj/item/mod/module/health_analyzer) + cooldown_time = 0.5 SECONDS + tgui_id = "health_analyzer" + /// Scanning mode, changes how we scan something. + var/mode = HEALTH_SCAN + /// List of all scanning modes. + var/static/list/modes = list(HEALTH_SCAN, WOUND_SCAN, CHEM_SCAN) + +/obj/item/mod/module/health_analyzer/add_ui_data() + . = ..() + .["userhealth"] = mod.wearer?.health || 0 + .["usermaxhealth"] = mod.wearer?.getMaxHealth() || 0 + .["userbrute"] = mod.wearer?.getBruteLoss() || 0 + .["userburn"] = mod.wearer?.getFireLoss() || 0 + .["usertoxin"] = mod.wearer?.getToxLoss() || 0 + .["useroxy"] = mod.wearer?.getOxyLoss() || 0 + +/obj/item/mod/module/health_analyzer/on_select_use(atom/target) + . = ..() + if(!.) + return + if(!isliving(target) || !mod.wearer.can_read(src)) + return + switch(mode) + if(HEALTH_SCAN) + healthscan(mod.wearer, target) + if(WOUND_SCAN) + woundscan(mod.wearer, target) + if(CHEM_SCAN) + chemscan(mod.wearer, target) + drain_power(use_power_cost) + +/obj/item/mod/module/health_analyzer/get_configuration() + . = ..() + .["mode"] = add_ui_configuration("Scan Mode", "list", mode, modes) + +/obj/item/mod/module/health_analyzer/configure_edit(key, value) + switch(key) + if("mode") + mode = value + +#undef HEALTH_SCAN +#undef WOUND_SCAN +#undef CHEM_SCAN + +///Quick Carry - Lets the user carry bodies quicker. +/obj/item/mod/module/quick_carry + name = "MOD quick carry module" + desc = "A suite of advanced servos, redirecting power from the suit's arms to help carry the wounded; \ + or simply for fun. However, Nanotrasen has locked the module's ability to assist in hand-to-hand combat." + icon_state = "carry" + complexity = 1 + idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.3 + incompatible_modules = list(/obj/item/mod/module/quick_carry, /obj/item/mod/module/constructor) + +/obj/item/mod/module/quick_carry/on_suit_activation() + ADD_TRAIT(mod.wearer, TRAIT_QUICKER_CARRY, MOD_TRAIT) + +/obj/item/mod/module/quick_carry/on_suit_deactivation(deleting = FALSE) + REMOVE_TRAIT(mod.wearer, TRAIT_QUICKER_CARRY, MOD_TRAIT) + +/obj/item/mod/module/quick_carry/advanced + name = "MOD advanced quick carry module" + removable = FALSE + complexity = 0 + +///Injector - No piercing syringes, replace another time + +///Organ Thrower + +///Patrient Transport + +///Defibrillator - Gives the suit an extendable pair of shock paddles. +/obj/item/mod/module/defibrillator + name = "MOD defibrillator module" + desc = "A module built into the gauntlets of the suit; commonly known as the 'Healing Hands' by medical professionals. \ + The user places their palms above the patient. Onboard computers in the suit calculate the necessary voltage, \ + and a modded targeting computer determines the best position for the user to push. \ + Twenty five pounds of force are applied to the patient's skin. Shocks travel from the suit's gloves \ + and counter-shock the heart, and the wearer returns to Medical a hero. Don't you even think about using it as a weapon; \ + regulations on manufacture and software locks expressly forbid it." + icon_state = "defibrillator" + module_type = MODULE_ACTIVE + complexity = 2 + use_power_cost = DEFAULT_CHARGE_DRAIN * 25 + device = /obj/item/shockpaddles/mod + overlay_state_inactive = "module_defibrillator" + overlay_state_active = "module_defibrillator_active" + incompatible_modules = list(/obj/item/mod/module/defibrillator) + cooldown_time = 0.5 SECONDS + var/defib_cooldown = 5 SECONDS + +/obj/item/mod/module/defibrillator/Initialize(mapload) + . = ..() + RegisterSignal(device, COMSIG_DEFIBRILLATOR_SUCCESS, .proc/on_defib_success) + +/obj/item/mod/module/defibrillator/Destroy() + UnregisterSignal(device, COMSIG_DEFIBRILLATOR_SUCCESS) + . = ..() + +/obj/item/mod/module/defibrillator/proc/on_defib_success(obj/item/shockpaddles/source) + drain_power(use_power_cost) + source.recharge(defib_cooldown) + return COMPONENT_DEFIB_STOP + +/obj/item/shockpaddles/mod + name = "MOD defibrillator gauntlets" + req_defib = FALSE + icon_state = "defibgauntlets0" + item_state = "defibgauntlets0" + base_icon_state = "defibgauntlets" + +/obj/item/mod/module/defibrillator/combat + name = "MOD combat defibrillator module" + desc = "A module built into the gauntlets of the suit; commonly known as the 'Healing Hands' by medical professionals. \ + The user places their palms above the patient. Onboard computers in the suit calculate the necessary voltage, \ + and a modded targeting computer determines the best position for the user to push. \ + Twenty five pounds of force are applied to the patient's skin. Shocks travel from the suit's gloves \ + and counter-shock the heart, and the wearer returns to Medical a hero. \ + Interdyne Pharmaceutics marketed the domestic version of the Healing Hands as foolproof and unusable as a weapon. \ + But when it came time to provide their operatives with usable medical equipment, they didn't hesitate to remove \ + those in-built safeties. Operatives in the field can benefit from what they dub as 'Stun Gloves', able to apply shocks \ + straight to a victims heart to disable them, or maybe even outright stop their heart with enough power." + complexity = 1 + module_type = MODULE_ACTIVE + overlay_state_inactive = "module_defibrillator_combat" + overlay_state_active = "module_defibrillator_combat_active" + device = /obj/item/shockpaddles/syndicate/mod + defib_cooldown = 2.5 SECONDS + +/obj/item/shockpaddles/syndicate/mod + name = "MOD combat defibrillator gauntlets" + req_defib = FALSE + icon_state = "syndiegauntlets0" + item_state = "syndiegauntlets0" + base_icon_state = "syndiegauntlets" + +///Thread Ripper + +///Surgical Processor - Lets you do advanced surgeries portably. +/obj/item/mod/module/surgical_processor + name = "MOD surgical processor module" + desc = "A module using an onboard surgical computer which can be connected to other computers to download and \ + perform advanced surgeries on the go." + icon_state = "surgical_processor" + module_type = MODULE_ACTIVE + complexity = 2 + active_power_cost = DEFAULT_CHARGE_DRAIN + device = /obj/item/surgical_processor/mod + incompatible_modules = list(/obj/item/mod/module/surgical_processor) + cooldown_time = 0.5 SECONDS + +/obj/item/surgical_processor/mod + name = "MOD surgical processor" + +/obj/item/mod/module/surgical_processor/preloaded + desc = "A module using an onboard surgical computer which can be connected to other computers to download and \ + perform advanced surgeries on the go. This one came pre-loaded with some advanced surgeries." + device = /obj/item/surgical_processor/mod/preloaded + +/obj/item/surgical_processor/mod/preloaded + advanced_surgeries = list( + /datum/surgery/advanced/pacify, + /datum/surgery/healing/combo/upgraded/femto, + /datum/surgery/advanced/brainwashing, + /datum/surgery/advanced/bioware/nerve_splicing, + /datum/surgery/advanced/bioware/nerve_grounding, + /datum/surgery/advanced/bioware/vein_threading, + /datum/surgery/advanced/bioware/muscled_veins, + /datum/surgery/advanced/bioware/ligament_hook, + /datum/surgery/advanced/bioware/ligament_reinforcement + ) diff --git a/code/modules/mod/modules/modules_science.dm b/code/modules/mod/modules/modules_science.dm new file mode 100644 index 0000000000..7208210b76 --- /dev/null +++ b/code/modules/mod/modules/modules_science.dm @@ -0,0 +1,135 @@ +//Science modules for MODsuits + +///Reagent Scanner - Lets the user scan reagents. +/obj/item/mod/module/reagent_scanner + name = "MOD reagent scanner module" + desc = "A module based off research-oriented Nanotrasen HUDs, this is capable of scanning the contents of \ + containers and projecting the information in an easy-to-read format on the wearer's display. \ + It cannot detect flavors, so that's up to you." + icon_state = "scanner" + module_type = MODULE_TOGGLE + complexity = 1 + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.2 + incompatible_modules = list(/obj/item/mod/module/reagent_scanner) + cooldown_time = 0.5 SECONDS + +/obj/item/mod/module/reagent_scanner/on_activation() + . = ..() + if(!.) + return + ADD_TRAIT(mod.wearer, TRAIT_REAGENT_SCANNER, MOD_TRAIT) + +/obj/item/mod/module/reagent_scanner/on_deactivation(display_message = TRUE, deleting = FALSE) + . = ..() + if(!.) + return + REMOVE_TRAIT(mod.wearer, TRAIT_REAGENT_SCANNER, MOD_TRAIT) + +/obj/item/mod/module/reagent_scanner/advanced + name = "MOD advanced reagent scanner module" + complexity = 0 + removable = FALSE + var/explosion_detection_dist = 21 + var/had_research_scanner = FALSE + +/obj/item/mod/module/reagent_scanner/advanced/on_activation() + . = ..() + if(!.) + return + had_research_scanner = mod.wearer.research_scanner + mod.wearer.research_scanner = TRUE + RegisterSignal(SSdcs, COMSIG_GLOB_EXPLOSION, .proc/sense_explosion) + +/obj/item/mod/module/reagent_scanner/advanced/on_deactivation(display_message = TRUE, deleting = FALSE) + . = ..() + if(!.) + return + mod.wearer.research_scanner = had_research_scanner + had_research_scanner = FALSE + UnregisterSignal(SSdcs, COMSIG_GLOB_EXPLOSION) + +/obj/item/mod/module/reagent_scanner/advanced/proc/sense_explosion(datum/source, turf/epicenter, + devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range) + SIGNAL_HANDLER + var/turf/wearer_turf = get_turf(mod.wearer) + if(wearer_turf.z == epicenter.z) + return + if(get_dist(epicenter, wearer_turf) > explosion_detection_dist) + return + to_chat(mod.wearer, span_notice("Explosion detected! Epicenter: [devastation_range], Outer: [heavy_impact_range], Shock: [light_impact_range]")) + +///Anti-Gravity - Makes the user weightless. +/obj/item/mod/module/anomaly_locked/antigrav + name = "MOD anti-gravity module" + desc = "A module that uses a gravitational core to make the user completely weightless." + icon_state = "antigrav" + module_type = MODULE_TOGGLE + complexity = 3 + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.7 + incompatible_modules = list(/obj/item/mod/module/anomaly_locked) + cooldown_time = 0.5 SECONDS + accepted_anomalies = list(/obj/item/assembly/signaler/anomaly/grav) + +/obj/item/mod/module/anomaly_locked/antigrav/on_activation() + . = ..() + if(!.) + return + if(mod.wearer.has_gravity()) + new /obj/effect/temp_visual/mook_dust(get_turf(src)) + mod.wearer.AddElement(/datum/element/forced_gravity, 0) + mod.wearer.update_gravity(mod.wearer.has_gravity()) + playsound(src, 'sound/effects/gravhit.ogg', 50) + +/obj/item/mod/module/anomaly_locked/antigrav/on_deactivation(display_message = TRUE, deleting = FALSE) + . = ..() + if(!.) + return + mod.wearer.RemoveElement(/datum/element/forced_gravity, 0) + mod.wearer.update_gravity(mod.wearer.has_gravity()) + if(deleting) + return + if(mod.wearer.has_gravity()) + new /obj/effect/temp_visual/mook_dust(get_turf(src)) + playsound(src, 'sound/effects/gravhit.ogg', 50) + +/obj/item/mod/module/anomaly_locked/antigrav/prebuilt + prebuilt = TRUE + +///Teleporter - Lets the user teleport to a nearby location. +/obj/item/mod/module/anomaly_locked/teleporter + name = "MOD teleporter module" + desc = "A module that uses a bluespace core to let the user transport their particles elsewhere." + icon_state = "teleporter" + module_type = MODULE_ACTIVE + complexity = 3 + use_power_cost = DEFAULT_CHARGE_DRAIN * 5 + cooldown_time = 5 SECONDS + accepted_anomalies = list(/obj/item/assembly/signaler/anomaly/bluespace) + /// Time it takes to teleport + var/teleport_time = 3 SECONDS + +/obj/item/mod/module/anomaly_locked/teleporter/on_select_use(atom/target) + . = ..() + if(!.) + return + var/turf/open/target_turf = get_turf(target) + if(!istype(target_turf) || is_blocked_turf(target_turf) || !(target_turf in view(mod.wearer))) + balloon_alert(mod.wearer, "invalid target!") + return + balloon_alert(mod.wearer, "teleporting...") + var/matrix/pre_matrix = matrix() + pre_matrix.Scale(4, 0.25) + var/matrix/post_matrix = matrix() + post_matrix.Scale(0.25, 4) + animate(mod.wearer, teleport_time, color = COLOR_CYAN, transform = pre_matrix.Multiply(mod.wearer.transform), easing = SINE_EASING|EASE_OUT) + if(!do_after(mod.wearer, teleport_time, target = mod)) + balloon_alert(mod.wearer, "interrupted!") + animate(mod.wearer, teleport_time*0.1, color = null, transform = post_matrix.Multiply(mod.wearer.transform), easing = SINE_EASING|EASE_IN) + return + animate(mod.wearer, teleport_time*0.1, color = null, transform = post_matrix.Multiply(mod.wearer.transform), easing = SINE_EASING|EASE_IN) + if(!do_teleport(mod.wearer, target_turf, asoundin = 'sound/effects/phasein.ogg')) + return + drain_power(use_power_cost) + +/obj/item/mod/module/anomaly_locked/teleporter/prebuilt + prebuilt = TRUE diff --git a/code/modules/mod/modules/modules_security.dm b/code/modules/mod/modules/modules_security.dm new file mode 100644 index 0000000000..098abf8015 --- /dev/null +++ b/code/modules/mod/modules/modules_security.dm @@ -0,0 +1,207 @@ +//Security modules for MODsuits + +///Cloaking - Lowers the user's visibility, can be interrupted by being touched or attacked. +/obj/item/mod/module/stealth + name = "MOD prototype cloaking module" + desc = "A complete retrofitting of the suit, this is a form of visual concealment tech employing esoteric technology \ + to bend light around the user, as well as mimetic materials to make the surface of the suit match the \ + surroundings based off sensor data. For some reason, this tech is rarely seen." + icon_state = "cloak" + module_type = MODULE_TOGGLE + complexity = 4 + active_power_cost = DEFAULT_CHARGE_DRAIN * 2 + use_power_cost = DEFAULT_CHARGE_DRAIN * 10 + incompatible_modules = list(/obj/item/mod/module/stealth) + cooldown_time = 5 SECONDS + /// Whether or not the cloak turns off on bumping. + var/bumpoff = TRUE + /// The alpha applied when the cloak is on. + var/stealth_alpha = 50 + +/obj/item/mod/module/stealth/on_activation() + . = ..() + if(!.) + return + if(bumpoff) + RegisterSignal(mod.wearer, COMSIG_LIVING_MOB_BUMP, .proc/unstealth) + RegisterSignal(mod.wearer, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, .proc/on_unarmed_attack) + RegisterSignal(mod.wearer, COMSIG_ATOM_BULLET_ACT, .proc/on_bullet_act) + RegisterSignal(mod.wearer, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_PARENT_ATTACKBY, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_HULK_ATTACK, COMSIG_ATOM_ATTACK_PAW), .proc/unstealth) + animate(mod.wearer, alpha = stealth_alpha, time = 1.5 SECONDS) + drain_power(use_power_cost) + +/obj/item/mod/module/stealth/on_deactivation(display_message = TRUE, deleting = FALSE) + . = ..() + if(!.) + return + if(bumpoff) + UnregisterSignal(mod.wearer, COMSIG_LIVING_MOB_BUMP) + UnregisterSignal(mod.wearer, list(COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_MOB_ITEM_ATTACK, COMSIG_PARENT_ATTACKBY, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_BULLET_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_ATOM_ATTACK_PAW)) + animate(mod.wearer, alpha = 255, time = 1.5 SECONDS) + +/obj/item/mod/module/stealth/proc/unstealth(datum/source) + SIGNAL_HANDLER + + to_chat(mod.wearer, span_warning("[src] gets discharged from contact!")) + do_sparks(2, TRUE, src) + drain_power(use_power_cost) + on_deactivation(display_message = TRUE, deleting = FALSE) + +/obj/item/mod/module/stealth/proc/on_unarmed_attack(datum/source, atom/target) + SIGNAL_HANDLER + + if(!isliving(target)) + return + unstealth(source) + +/obj/item/mod/module/stealth/proc/on_bullet_act(datum/source, obj/item/projectile/projectile) + SIGNAL_HANDLER + + if(projectile.nodamage) + return + unstealth(source) + +///Magnetic Harness - Automatically puts guns in your suit storage when you drop them. +/obj/item/mod/module/magnetic_harness + name = "MOD magnetic harness module" + desc = "Based off old TerraGov harness kits, this magnetic harness automatically attaches dropped guns back to the wearer." + icon_state = "mag_harness" + complexity = 2 + use_power_cost = DEFAULT_CHARGE_DRAIN + incompatible_modules = list(/obj/item/mod/module/magnetic_harness) + /// Time before we activate the magnet. + var/magnet_delay = 0.8 SECONDS + /// The typecache of all guns we allow. + var/static/list/guns_typecache + /// The guns already allowed by the modsuit chestplate. + var/list/already_allowed_guns = list() + +/obj/item/mod/module/magnetic_harness/Initialize(mapload) + . = ..() + if(!guns_typecache) + guns_typecache = typecacheof(list(/obj/item/gun/ballistic, /obj/item/gun/energy, /obj/item/gun/grenadelauncher, /obj/item/gun/chem, /obj/item/gun/syringe)) + +/obj/item/mod/module/magnetic_harness/on_install() + already_allowed_guns = guns_typecache & mod.chestplate.allowed + mod.chestplate.allowed |= guns_typecache + +/obj/item/mod/module/magnetic_harness/on_uninstall(deleting = FALSE) + if(deleting) + return + mod.chestplate.allowed -= (guns_typecache - already_allowed_guns) + +/obj/item/mod/module/magnetic_harness/on_suit_activation() + RegisterSignal(mod.wearer, COMSIG_MOB_UNEQUIPPED_ITEM, .proc/check_dropped_item) + +/obj/item/mod/module/magnetic_harness/on_suit_deactivation(deleting = FALSE) + UnregisterSignal(mod.wearer, COMSIG_MOB_UNEQUIPPED_ITEM) + +/obj/item/mod/module/magnetic_harness/proc/check_dropped_item(datum/source, obj/item/dropped_item, force, new_location) + SIGNAL_HANDLER + + if(!is_type_in_typecache(dropped_item, guns_typecache)) + return + if(new_location != get_turf(src)) + return + addtimer(CALLBACK(src, .proc/pick_up_item, dropped_item), magnet_delay) + +/obj/item/mod/module/magnetic_harness/proc/pick_up_item(obj/item/item) + if(!isturf(item.loc) || !item.Adjacent(mod.wearer)) + return + if(!mod.wearer.equip_to_slot_if_possible(item, ITEM_SLOT_SUITSTORE, qdel_on_fail = FALSE, disable_warning = TRUE)) + return + playsound(src, 'sound/items/modsuit/magnetic_harness.ogg', 50, TRUE) + balloon_alert(mod.wearer, "[item] reattached") + drain_power(use_power_cost) + +///Pepper Shoulders + +///Holster - Instantly holsters any not huge gun. +/obj/item/mod/module/holster + name = "MOD holster module" + desc = "Based off typical storage compartments, this system allows the suit to holster a \ + standard firearm across its surface and allow for extremely quick retrieval. \ + While some users prefer the chest, others the forearm for quick deployment, \ + some law enforcement prefer the holster to extend from the thigh." + icon_state = "holster" + module_type = MODULE_USABLE + complexity = 2 + incompatible_modules = list(/obj/item/mod/module/holster) + cooldown_time = 0.5 SECONDS + allowed_inactive = TRUE + /// Gun we have holstered. + var/obj/item/gun/holstered + +/obj/item/mod/module/holster/on_use() + . = ..() + if(!.) + return + if(!holstered) + var/obj/item/gun/holding = mod.wearer.get_active_held_item() + if(!holding) + balloon_alert(mod.wearer, "nothing to holster!") + return + if(!istype(holding) || holding.w_class > WEIGHT_CLASS_BULKY) + balloon_alert(mod.wearer, "it doesn't fit!") + return + if(mod.wearer.transferItemToLoc(holding, src, force = FALSE, silent = TRUE)) + holstered = holding + balloon_alert(mod.wearer, "weapon holstered") + playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE) + else if(mod.wearer.put_in_active_hand(holstered, forced = FALSE, ignore_animation = TRUE)) + balloon_alert(mod.wearer, "weapon drawn") + playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE) + else + balloon_alert(mod.wearer, "holster full!") + +/obj/item/mod/module/holster/on_uninstall(deleting = FALSE) + if(holstered) + holstered.forceMove(drop_location()) + +/obj/item/mod/module/holster/Exited(atom/movable/gone, direction) + . = ..() + if(gone == holstered) + holstered = null + +/obj/item/mod/module/holster/Destroy() + QDEL_NULL(holstered) + return ..() + +///Megaphone - Lets you speak loud. +/obj/item/mod/module/megaphone + name = "MOD megaphone module" + desc = "A microchip megaphone linked to a MODsuit, for very important purposes, like: loudness." + icon_state = "megaphone" + module_type = MODULE_TOGGLE + complexity = 1 + use_power_cost = DEFAULT_CHARGE_DRAIN * 0.5 + incompatible_modules = list(/obj/item/mod/module/megaphone) + cooldown_time = 0.5 SECONDS + /// List of spans we add to the speaker. + var/list/voicespan = list(SPAN_COMMAND) + +/obj/item/mod/module/megaphone/on_activation() + . = ..() + if(!.) + return + RegisterSignal(mod.wearer, COMSIG_MOB_SAY, .proc/handle_speech) + +/obj/item/mod/module/megaphone/on_deactivation(display_message = TRUE, deleting = FALSE) + . = ..() + if(!.) + return + UnregisterSignal(mod.wearer, COMSIG_MOB_SAY) + +/obj/item/mod/module/megaphone/proc/handle_speech(datum/source, list/speech_args) + SIGNAL_HANDLER + + speech_args[SPEECH_SPANS] |= voicespan + drain_power(use_power_cost) + +///Criminal Capture + +///Mirage grenade dispenser + +///Projectile Dampener + +///Active Sonar diff --git a/code/modules/mod/modules/modules_service.dm b/code/modules/mod/modules/modules_service.dm new file mode 100644 index 0000000000..85ebfea132 --- /dev/null +++ b/code/modules/mod/modules/modules_service.dm @@ -0,0 +1,66 @@ +//Service modules for MODsuits + +///Bike Horn - Plays a bike horn sound. +/obj/item/mod/module/bikehorn + name = "MOD bike horn module" + desc = "A shoulder-mounted piece of heavy sonic artillery, this module uses the finest femto-manipulator technology to \ + precisely deliver an almost lethal squeeze to... a bike horn, producing a significantly memorable sound." + icon_state = "bikehorn" + module_type = MODULE_USABLE + complexity = 1 + use_power_cost = DEFAULT_CHARGE_DRAIN + incompatible_modules = list(/obj/item/mod/module/bikehorn) + cooldown_time = 1 SECONDS + +/obj/item/mod/module/bikehorn/on_use() + . = ..() + if(!.) + return + playsound(src, 'sound/items/bikehorn.ogg', 100, FALSE) + drain_power(use_power_cost) + +///Microwave Beam - Microwaves items instantly. +/obj/item/mod/module/microwave_beam + name = "MOD microwave beam module" + desc = "An oddly domestic device, this module is installed into the user's palm, \ + hooking up with culinary scanners located in the helmet to blast food with precise microwave radiation, \ + allowing them to cook food from a distance, with the greatest of ease. Not recommended for use against grapes." + icon_state = "microwave_beam" + module_type = MODULE_ACTIVE + complexity = 2 + use_power_cost = DEFAULT_CHARGE_DRAIN * 5 + incompatible_modules = list(/obj/item/mod/module/microwave_beam) + cooldown_time = 10 SECONDS + var/obj/machinery/microwave/microwave + +/obj/item/mod/module/microwave_beam/Initialize(mapload) + microwave = new() + . = ..() + +/obj/item/mod/module/microwave_beam/Destroy() + QDEL_NULL(microwave) + . = ..() + +/obj/item/mod/module/microwave_beam/on_select_use(atom/target) + . = ..() + if(!.) + return + if(!isitem(target)) + return + if(!isturf(target.loc)) + balloon_alert(mod.wearer, "must be on the floor!") + return + var/obj/item/microwave_target = target + var/turf/microwave_target_loc = target.loc + var/datum/effect_system/spark_spread/spark_effect = new() + spark_effect.set_up(2, 1, mod.wearer) + spark_effect.start() + mod.wearer.Beam(target,icon_state="lightning[rand(1,12)]", time = 5) + if(microwave_target.microwave_act(microwave)) + playsound(src, 'sound/machines/microwave/microwave-end.ogg', 50, FALSE) + else + balloon_alert(mod.wearer, "can't be microwaved!") + var/datum/effect_system/spark_spread/spark_effect_two = new() + spark_effect_two.set_up(2, 1, microwave_target_loc) + spark_effect_two.start() + drain_power(use_power_cost) diff --git a/code/modules/mod/modules/modules_supply.dm b/code/modules/mod/modules/modules_supply.dm new file mode 100644 index 0000000000..e3c70fa570 --- /dev/null +++ b/code/modules/mod/modules/modules_supply.dm @@ -0,0 +1,229 @@ +//Supply modules for MODsuits + +///Internal GPS - Extends a GPS you can use. +/obj/item/mod/module/gps + name = "MOD internal GPS module" + desc = "This module uses common Nanotrasen technology to calculate the user's position anywhere in space, \ + down to the exact coordinates. This information is fed to a central database viewable from the device itself, \ + though using it to help people is up to you." + icon_state = "gps" + module_type = MODULE_USABLE + complexity = 1 + use_power_cost = DEFAULT_CHARGE_DRAIN * 0.2 + incompatible_modules = list(/obj/item/mod/module/gps) + cooldown_time = 0.5 SECONDS + allowed_inactive = TRUE + +/obj/item/mod/module/gps/Initialize(mapload) + . = ..() + AddComponent(/datum/component/gps/item, "MOD0", state = GLOB.deep_inventory_state, overlay_state = FALSE) + +/obj/item/mod/module/gps/on_use() + . = ..() + if(!.) + return + attack_self(mod.wearer) + +///Hydraulic Clamp - Lets you pick up and drop crates. +/obj/item/mod/module/clamp + name = "MOD hydraulic clamp module" + desc = "A series of actuators installed into both arms of the suit, boasting a lifting capacity of almost a ton. \ + However, this design has been locked by Nanotrasen to be primarily utilized for lifting various crates. \ + A lot of people would say that loading cargo is a dull job, but you could not disagree more." + icon_state = "clamp" + module_type = MODULE_ACTIVE + complexity = 3 + use_power_cost = DEFAULT_CHARGE_DRAIN + incompatible_modules = list(/obj/item/mod/module/clamp) + cooldown_time = 0.5 SECONDS + overlay_state_inactive = "module_clamp" + overlay_state_active = "module_clamp_on" + /// Time it takes to load a crate. + var/load_time = 3 SECONDS + /// The max amount of crates you can carry. + var/max_crates = 3 + /// The crates stored in the module. + var/list/stored_crates = list() + +/obj/item/mod/module/clamp/on_select_use(atom/target) + . = ..() + if(!.) + return + if(!mod.wearer.Adjacent(target)) + return + if(istype(target, /obj/structure/closet) || istype(target, /obj/structure/bigDelivery)) + var/atom/movable/picked_crate = target + if(!check_crate_pickup(picked_crate)) + return + playsound(src, 'sound/mecha/hydraulic.ogg', 25, TRUE) + if(!do_after(mod.wearer, load_time, target = target)) + balloon_alert(mod.wearer, "interrupted!") + return + if(!check_crate_pickup(picked_crate)) + return + stored_crates += picked_crate + picked_crate.forceMove(src) + balloon_alert(mod.wearer, "picked up [picked_crate]") + drain_power(use_power_cost) + else if(length(stored_crates)) + var/turf/target_turf = get_turf(target) + if(is_blocked_turf(target_turf)) + return + playsound(src, 'sound/mecha/hydraulic.ogg', 25, TRUE) + if(!do_after(mod.wearer, load_time, target = target)) + balloon_alert(mod.wearer, "interrupted!") + return + if(is_blocked_turf(target_turf)) + return + var/atom/movable/dropped_crate = pop(stored_crates) + dropped_crate.forceMove(target_turf) + balloon_alert(mod.wearer, "dropped [dropped_crate]") + drain_power(use_power_cost) + else + balloon_alert(mod.wearer, "invalid target!") + +/obj/item/mod/module/clamp/on_suit_deactivation(deleting = FALSE) + if(deleting) + return + for(var/atom/movable/crate as anything in stored_crates) + crate.forceMove(drop_location()) + stored_crates -= crate + +/obj/item/mod/module/clamp/proc/check_crate_pickup(atom/movable/target) + if(length(stored_crates) >= max_crates) + balloon_alert(mod.wearer, "too many crates!") + return FALSE + for(var/mob/living/mob in target.GetAllContents()) + if(mob.mob_size < MOB_SIZE_HUMAN) + continue + balloon_alert(mod.wearer, "crate too heavy!") + return FALSE + return TRUE + +/obj/item/mod/module/clamp/loader + name = "MOD loader hydraulic clamp module" + icon_state = "clamp_loader" + complexity = 0 + removable = FALSE + overlay_state_inactive = null + overlay_state_active = "module_clamp_loader" + load_time = 1 SECONDS + max_crates = 5 + use_mod_colors = TRUE + +///Drill - Lets you dig through rock and basalt. +/obj/item/mod/module/drill // TODO: Would be cooler with a built-in drill, but meh + name = "MOD pickaxe/drill storage module" + desc = "Provides a convenient storage compartment for pickaxes and drills." + icon_state = "drill" + complexity = 2 + incompatible_modules = list(/obj/item/mod/module/drill) + cooldown_time = 0.5 SECONDS + allowed_inactive = TRUE + module_type = MODULE_USABLE + /// Pickaxe we have stored. + var/obj/item/pickaxe/stored + +/obj/item/mod/module/drill/on_use() + . = ..() + if(!.) + return + if(!stored) + var/obj/item/pickaxe/holding = mod.wearer.get_active_held_item() + if(!holding) + balloon_alert(mod.wearer, "nothing to store!") + return + if(!istype(holding)) + balloon_alert(mod.wearer, "it doesn't fit!") + return + if(mod.wearer.transferItemToLoc(holding, src, force = FALSE, silent = TRUE)) + stored = holding + balloon_alert(mod.wearer, "mining instrument stored") + playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE) + else if(mod.wearer.put_in_active_hand(stored, forced = FALSE, ignore_animation = TRUE)) + balloon_alert(mod.wearer, "mining instrument retrieved") + playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE) + else + balloon_alert(mod.wearer, "mining instrument storage full!") + +/obj/item/mod/module/drill/on_uninstall(deleting = FALSE) + if(stored) + stored.forceMove(drop_location()) + +/obj/item/mod/module/drill/Exited(atom/movable/gone, direction) + . = ..() + if(gone == stored) + stored = null + +/obj/item/mod/module/drill/Destroy() + QDEL_NULL(stored) + return ..() + +/obj/item/mod/module/orebag // TODO + name = "MOD mining satchel storage module" + desc = "Provides a convenient storage department for a mining satchel." + icon_state = "ore" + module_type = MODULE_USABLE + complexity = 1 + use_power_cost = DEFAULT_CHARGE_DRAIN * 0.2 + incompatible_modules = list(/obj/item/mod/module/orebag) + cooldown_time = 0.5 SECONDS + allowed_inactive = TRUE + /// Pickaxe we have stored. + var/obj/item/storage/bag/ore/stored + +/obj/item/mod/module/orebag/on_use() + . = ..() + if(!.) + return + if(!stored) + var/obj/item/storage/bag/ore/holding = mod.wearer.get_active_held_item() + if(!holding) + balloon_alert(mod.wearer, "nothing to store!") + return + if(!istype(holding)) + balloon_alert(mod.wearer, "it doesn't fit!") + return + if(mod.wearer.transferItemToLoc(holding, src, force = FALSE, silent = TRUE)) + stored = holding + balloon_alert(mod.wearer, "mining satchel stored") + playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE) + RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, .proc/Pickup_ores) + else if(mod.wearer.put_in_active_hand(stored, forced = FALSE, ignore_animation = TRUE)) + UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED) + balloon_alert(mod.wearer, "mining satchel retrieved") + playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE) + else + balloon_alert(mod.wearer, "mining satchel storage full!") + +/obj/item/mod/module/orebag/on_uninstall(deleting = FALSE) + if(stored) + UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED) + stored.forceMove(drop_location()) + +/obj/item/mod/module/orebag/on_equip() + if(stored) + RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, .proc/Pickup_ores) + +/obj/item/mod/module/orebag/on_unequip() + if(stored) + UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED) + +/obj/item/mod/module/orebag/Exited(atom/movable/gone, direction) + . = ..() + if(gone == stored) + UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED) + stored = null + +/obj/item/mod/module/orebag/Destroy() + if(stored) + UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED) + QDEL_NULL(stored) + return ..() + +/obj/item/mod/module/orebag/proc/Pickup_ores() + if(stored) + stored.Pickup_ores(mod.wearer) + +// Ash accretion looks cool, but can't be arsed to implement +// Same with sphere transformation diff --git a/code/modules/mod/modules/modules_visor.dm b/code/modules/mod/modules/modules_visor.dm new file mode 100644 index 0000000000..0e44900a46 --- /dev/null +++ b/code/modules/mod/modules/modules_visor.dm @@ -0,0 +1,91 @@ +//Visor modules for MODsuits + +///Base Visor - Adds a specific HUD and traits to you. +/obj/item/mod/module/visor + name = "MOD visor module" + desc = "A heads-up display installed into the visor of the suit. They say these also let you see behind you." + module_type = MODULE_TOGGLE + complexity = 2 + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3 + incompatible_modules = list(/obj/item/mod/module/visor) + cooldown_time = 0.5 SECONDS + /// The HUD type given by the visor. + var/hud_type + /// The traits given by the visor. + var/list/visor_traits = list() + +/obj/item/mod/module/visor/on_activation() + . = ..() + if(!.) + return + if(hud_type) + var/datum/atom_hud/hud = GLOB.huds[hud_type] + hud.add_hud_to(mod.wearer) + for(var/trait in visor_traits) + ADD_TRAIT(mod.wearer, trait, MOD_TRAIT) + mod.wearer.update_sight() + +/obj/item/mod/module/visor/on_deactivation(display_message = TRUE, deleting = FALSE) + . = ..() + if(!.) + return + if(hud_type) + var/datum/atom_hud/hud = GLOB.huds[hud_type] + hud.remove_hud_from(mod.wearer) + for(var/trait in visor_traits) + REMOVE_TRAIT(mod.wearer, trait, MOD_TRAIT) + mod.wearer.update_sight() + +//Medical Visor - Gives you a medical HUD. +/obj/item/mod/module/visor/medhud + name = "MOD medical visor module" + desc = "A heads-up display installed into the visor of the suit. This cross-references suit sensor data with a modern \ + biological scanning suite, allowing the user to visualize the current health of organic lifeforms, as well as \ + access data such as patient files in a convenient readout. They say these also let you see behind you." + icon_state = "medhud_visor" + hud_type = DATA_HUD_MEDICAL_ADVANCED + +//Diagnostic Visor - Gives you a diagnostic HUD. +/obj/item/mod/module/visor/diaghud + name = "MOD diagnostic visor module" + desc = "A heads-up display installed into the visor of the suit. This uses a series of advanced sensors to access data \ + from advanced machinery, exosuits, and other devices, allowing the user to visualize current power levels \ + and integrity of such. They say these also let you see behind you." + icon_state = "diaghud_visor" + hud_type = DATA_HUD_DIAGNOSTIC_ADVANCED + +//Security Visor - Gives you a security HUD. +/obj/item/mod/module/visor/sechud + name = "MOD security visor module" + desc = "A heads-up display installed into the visor of the suit. This module is a heavily-retrofitted targeting system, \ + plugged into various criminal databases to be able to view arrest records, command simple security-oriented robots, \ + and generally know who to shoot. They say these also let you see behind you." + icon_state = "sechud_visor" + hud_type = DATA_HUD_SECURITY_ADVANCED + +//Meson Visor - Gives you meson vision. +/obj/item/mod/module/visor/meson + name = "MOD meson visor module" + desc = "A heads-up display installed into the visor of the suit. This module is based off well-loved meson scanner \ + technology, used by construction workers and miners across the galaxy to see basic structural and terrain layouts \ + through walls, regardless of lighting conditions. They say these also let you see behind you." + icon_state = "meson_visor" + visor_traits = list(TRAIT_MESON_VISION) + +//Thermal Visor - Gives you thermal vision. +/obj/item/mod/module/visor/thermal + name = "MOD thermal visor module" + desc = "A heads-up display installed into the visor of the suit. This uses a small IR scanner to detect and identify \ + the thermal radiation output of objects near the user. While it can detect the heat output of even something as \ + small as a rodent, it still produces irritating red overlay. They say these also let you see behind you." + icon_state = "thermal_visor" + visor_traits = list(TRAIT_THERMAL_VISION) + +//Night Visor - Gives you night vision. +/obj/item/mod/module/visor/night + name = "MOD night visor module" + desc = "A heads-up display installed into the visor of the suit. Typical for both civilian and military applications, \ + this allows the user to perceive their surroundings while in complete darkness, enhancing the view by tenfold; \ + yet brightening everything into a spooky green glow. They say these also let you see behind you." + icon_state = "night_visor" + visor_traits = list(TRAIT_TRUE_NIGHT_VISION) diff --git a/code/modules/modular_computers/NTNet/NTNRC/conversation.dm b/code/modules/modular_computers/NTNet/NTNRC/conversation.dm index b5f3bae53d..fada2229e5 100644 --- a/code/modules/modular_computers/NTNet/NTNRC/conversation.dm +++ b/code/modules/modular_computers/NTNet/NTNRC/conversation.dm @@ -5,7 +5,14 @@ var/title = "Untitled Conversation" var/datum/computer_file/program/chatclient/operator // "Administrator" of this channel. Creator starts as channel's operator, var/list/messages = list() - var/list/clients = list() + ///chat clients who are active or minimized + var/list/active_clients = list() + ///chat clients who have exited out of the program. + var/list/offline_clients = list() + ///clients muted by operator + var/list/muted_clients = list() + //if a channel is strong, it cannot be renamed or deleted. + var/strong = FALSE var/password var/static/ntnrc_uid = 0 @@ -22,6 +29,8 @@ /datum/ntnet_conversation/Destroy() if(SSnetworks.station_network) SSnetworks.station_network.chat_channels.Remove(src) + for(var/datum/computer_file/program/chatclient/chatterbox in (active_clients | offline_clients | muted_clients)) + purge_client(chatterbox) return ..() /datum/ntnet_conversation/proc/add_message(message, username) @@ -38,39 +47,70 @@ return messages = messages.Copy(messages.len-50 ,0) -/datum/ntnet_conversation/proc/add_client(datum/computer_file/program/chatclient/C) - if(!istype(C)) +/datum/ntnet_conversation/proc/add_client(datum/computer_file/program/chatclient/new_user, silent = FALSE) + if(!istype(new_user)) return - clients.Add(C) - add_status_message("[C.username] has joined the channel.") + new_user.conversations |= src + active_clients.Add(new_user) + if(!silent) + add_status_message("[new_user.username] has joined the channel.") // No operator, so we assume the channel was empty. Assign this user as operator. if(!operator) - changeop(C) + changeop(new_user) -/datum/ntnet_conversation/proc/remove_client(datum/computer_file/program/chatclient/C) - if(!istype(C) || !(C in clients)) +//Clear all of our references to a client, used for client deletion +/datum/ntnet_conversation/proc/purge_client(datum/computer_file/program/chatclient/forget) + remove_client(forget) + muted_clients -= forget + offline_clients -= forget + forget.conversations -= src + +/datum/ntnet_conversation/proc/remove_client(datum/computer_file/program/chatclient/leaving) + if(!istype(leaving)) return - clients.Remove(C) - add_status_message("[C.username] has left the channel.") + if(leaving in active_clients) + active_clients.Remove(leaving) + add_status_message("[leaving.username] has left the channel.") // Channel operator left, pick new operator - if(C == operator) + if(leaving == operator) operator = null - if(clients.len) - var/datum/computer_file/program/chatclient/newop = pick(clients) + if(active_clients.len) + var/datum/computer_file/program/chatclient/newop = pick(active_clients) changeop(newop) +/datum/ntnet_conversation/proc/go_offline(datum/computer_file/program/chatclient/offline) + if(!istype(offline) || !(offline in active_clients)) + return + active_clients.Remove(offline) + offline_clients.Add(offline) + +/datum/ntnet_conversation/proc/mute_user(datum/computer_file/program/chatclient/op, datum/computer_file/program/chatclient/muted) + if(operator != op) //sanity even if the person shouldn't be able to see the mute button + return + if(muted in muted_clients) + muted_clients.Remove(muted) + muted.computer.alert_call(muted, "You have been unmuted from [title]!", 'sound/machines/ping.ogg') + else + muted_clients.Add(muted) + muted.computer.alert_call(muted, "You have been muted from [title]!") + +/datum/ntnet_conversation/proc/ping_user(datum/computer_file/program/chatclient/pinger, datum/computer_file/program/chatclient/pinged) + if(pinger in muted_clients) //oh my god fuck off + return + add_status_message("[pinger.username] pinged [pinged.username].") + pinged.computer.alert_call(pinged, "You have been pinged in [title] by [pinger.username]!", 'sound/machines/ping.ogg') /datum/ntnet_conversation/proc/changeop(datum/computer_file/program/chatclient/newop) if(istype(newop)) operator = newop add_status_message("Channel operator status transferred to [newop.username].") -/datum/ntnet_conversation/proc/change_title(newtitle, datum/computer_file/program/chatclient/client) - if(operator != client) - return FALSE // Not Authorised +/datum/ntnet_conversation/proc/change_title(newtitle, datum/computer_file/program/chatclient/renamer) + if(operator != renamer || strong) + return FALSE // Not Authorised or channel cannot be editted - add_status_message("[client.username] has changed channel title from [title] to [newtitle]") + add_status_message("[renamer.username] has changed channel title from [title] to [newtitle]") title = newtitle #undef MAX_CHANNELS diff --git a/code/modules/modular_computers/computers/_modular_computer_shared.dm b/code/modules/modular_computers/computers/_modular_computer_shared.dm index 0aca92f9d8..1a2ba822d1 100644 --- a/code/modules/modular_computers/computers/_modular_computer_shared.dm +++ b/code/modules/modular_computers/computers/_modular_computer_shared.dm @@ -39,7 +39,7 @@ . += "It has a slot installed for an intelliCard which contains: [ai_slot.stored_card.name]" else . += "It has a slot installed for an intelliCard, which appears to be occupied." - . += "Alt-click to eject the intelliCard." + . += span_info("Alt-click to eject the intelliCard.") else . += "It has a slot installed for an intelliCard." @@ -55,7 +55,7 @@ . += "It has [multiple_slots ? "two slots" : "a slot"] for identification cards installed[multiple_cards ? " which contain [first_ID] and [second_ID]" : ", one of which contains [first_ID ? first_ID : second_ID]"]." else . += "It has [multiple_slots ? "two slots" : "a slot"] for identification cards installed, [multiple_cards ? "both of which appear" : "and one of them appears"] to be occupied." - . += "Alt-click [src] to eject the identification card[multiple_cards ? "s":""]." + . += span_info("Alt-click [src] to eject the identification card[multiple_cards ? "s":""].") else . += "It has [multiple_slots ? "two slots" : "a slot"] installed for identification cards." @@ -63,4 +63,4 @@ if(printer_slot) . += "It has a printer installed." if(user_is_adjacent) - . += "The printer's paper levels are at: [printer_slot.stored_paper]/[printer_slot.max_paper]." + . += "The printer's paper levels are at: [printer_slot.stored_paper]/[printer_slot.max_paper].]" diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 635ec2e54c..e2345a6384 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -10,15 +10,15 @@ integrity_failure = 0.5 max_integrity = 100 rad_flags = RAD_PROTECT_CONTENTS - armor = list("melee" = 0, "bullet" = 20, "laser" = 20, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 20, LASER = 20, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 0, ACID = 0) - var/enabled = 0 // Whether the computer is turned on. - var/screen_on = 1 // Whether the computer is active/opened/it's screen is on. - var/device_theme = "ntos" // Sets the theme for the main menu, hardware config, and file browser apps. Overridden by certain non-NT devices. - var/datum/computer_file/program/active_program = null // A currently active program running on the computer. - var/hardware_flag = 0 // A flag that describes this device type + var/enabled = 0 // Whether the computer is turned on. + var/screen_on = 1 // Whether the computer is active/opened/it's screen is on. + var/device_theme = "ntos" // Sets the theme for the main menu, hardware config, and file browser apps. Overridden by certain non-NT devices. + var/datum/computer_file/program/active_program = null // A currently active program running on the computer. + var/hardware_flag = 0 // A flag that describes this device type var/last_power_usage = 0 - var/last_battery_percent = 0 // Used for deciding if battery percentage has chandged + var/last_battery_percent = 0 // Used for deciding if battery percentage has chandged var/last_world_time = "00:00" var/list/last_header_icons ///Looping sound for when the computer is on @@ -26,19 +26,19 @@ ///Whether or not this modular computer uses the looping sound var/looping_sound = TRUE - var/base_active_power_usage = 50 // Power usage when the computer is open (screen is active) and can be interacted with. Remember hardware can use power too. - var/base_idle_power_usage = 5 // Power usage when the computer is idle and screen is off (currently only applies to laptops) + var/base_active_power_usage = 50 // Power usage when the computer is open (screen is active) and can be interacted with. Remember hardware can use power too. + var/base_idle_power_usage = 5 // Power usage when the computer is idle and screen is off (currently only applies to laptops) // Modular computers can run on various devices. Each DEVICE (Laptop, Console, Tablet,..) // must have it's own DMI file. Icon states must be called exactly the same in all files, but may look differently // If you create a program which is limited to Laptops and Consoles you don't have to add it's icon_state overlay for Tablets too, for example. - var/icon_state_unpowered = null // Icon state when the computer is turned off. - var/icon_state_powered = null // Icon state when the computer is turned on. - var/icon_state_menu = "menu" // Icon state overlay when the computer is turned on, but no program is loaded that would override the screen. - var/display_overlays = TRUE // If FALSE, don't draw overlays on this device at all - var/max_hardware_size = 0 // Maximal hardware w_class. Tablets/PDAs have 1, laptops 2, consoles 4. - var/steel_sheet_cost = 5 // Amount of steel sheets refunded when disassembling an empty frame of this computer. + var/icon_state_unpowered = null // Icon state when the computer is turned off. + var/icon_state_powered = null // Icon state when the computer is turned on. + var/icon_state_menu = "menu" // Icon state overlay when the computer is turned on, but no program is loaded that would override the screen. + var/display_overlays = TRUE // If FALSE, don't draw overlays on this device at all + var/max_hardware_size = 0 // Maximal hardware w_class. Tablets/PDAs have 1, laptops 2, consoles 4. + var/steel_sheet_cost = 5 // Amount of steel sheets refunded when disassembling an empty frame of this computer. /// List of "connection ports" in this computer and the components with which they are plugged var/list/all_components = list() @@ -47,14 +47,14 @@ /// Number of total expansion bays this computer has available. var/max_bays = 0 - var/list/idle_threads // Idle programs on background. They still receive process calls but can't be interacted with. - var/obj/physical = null // Object that represents our computer. It's used for Adjacent() and UI visibility checks. - var/has_light = FALSE //If the computer has a flashlight/LED light/what-have-you installed - var/comp_light_luminosity = 3 //The brightness of that light - var/comp_light_color //The color of that light + var/list/idle_threads // Idle programs on background. They still receive process calls but can't be interacted with. + var/obj/physical = null // Object that represents our computer. It's used for Adjacent() and UI visibility checks. + var/has_light = FALSE //If the computer has a flashlight/LED light/what-have-you installed + var/comp_light_luminosity = 3 //The brightness of that light + var/comp_light_color //The color of that light -/obj/item/modular_computer/Initialize() +/obj/item/modular_computer/Initialize(mapload) . = ..() START_PROCESSING(SSobj, src) if(!physical) @@ -62,13 +62,12 @@ comp_light_color = "#FFFFFF" idle_threads = list() if(looping_sound) - soundloop = new(list(src), enabled) - update_icon() + soundloop = new(src, enabled) + update_appearance() /obj/item/modular_computer/Destroy() kill_program(forced = TRUE) STOP_PROCESSING(SSobj, src) - QDEL_NULL(soundloop) for(var/H in all_components) var/obj/item/computer_hardware/CH = all_components[H] if(CH.holder == src) @@ -76,9 +75,19 @@ CH.holder = null all_components.Remove(CH.device_type) qdel(CH) + //Some components will actually try and interact with this, so let's do it later + QDEL_NULL(soundloop) physical = null return ..() +/** + * Plays a ping sound. + * + * Timers runtime if you try to make them call playsound. Yep. + */ +/obj/item/modular_computer/proc/play_ping() + playsound(loc, 'sound/machines/ping.ogg', get_clamped_volume(), FALSE, -1) + /obj/item/modular_computer/AltClick(mob/user) ..() if(issilicon(user)) @@ -98,14 +107,34 @@ /obj/item/modular_computer/GetID() var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD] - if(card_slot) - return card_slot.GetID() + var/obj/item/computer_hardware/card_slot/card_slot2 = all_components[MC_CARD2] + + var/obj/item/card/id/first_id = card_slot?.GetID() + var/obj/item/card/id/second_id = card_slot2?.GetID() + + // If we don't have both ID slots filled, pick the one that is filled. + if(first_id) + return first_id + if(second_id) + return second_id + + // Otherwise, we have no ID at all. return ..() /obj/item/modular_computer/RemoveID() var/obj/item/computer_hardware/card_slot/card_slot2 = all_components[MC_CARD2] var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD] - return (card_slot2?.try_eject() || card_slot?.try_eject()) //Try the secondary one first. + + var/removed_id = (card_slot2?.try_eject() || card_slot?.try_eject()) + if(removed_id) + if(ishuman(loc)) + var/mob/living/carbon/human/human_wearer = loc + if(human_wearer.wear_id == src) + human_wearer.sec_hud_set_ID() + update_slot_icon() + return removed_id + + return ..() /obj/item/modular_computer/InsertID(obj/item/inserting_item) var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD] @@ -118,7 +147,13 @@ return FALSE if((card_slot?.try_insert(inserting_id)) || (card_slot2?.try_insert(inserting_id))) + if(ishuman(loc)) + var/mob/living/carbon/human/human_wearer = loc + if(human_wearer.wear_id == src) + human_wearer.sec_hud_set_ID() + update_slot_icon() return TRUE + return FALSE /obj/item/modular_computer/MouseDrop(obj/over_object, src_location, over_location) @@ -142,9 +177,8 @@ turn_on(user) /obj/item/modular_computer/emag_act(mob/user) - . = ..() if(!enabled) - to_chat(user, "You'd need to turn the [src] on first.") + to_chat(user, span_warning("You'd need to turn the [src] on first.")) return FALSE obj_flags |= EMAGGED //Mostly for consistancy purposes; the programs will do their own emag handling var/newemag = FALSE @@ -155,36 +189,31 @@ if(app.run_emag()) newemag = TRUE if(newemag) - to_chat(user, "You swipe \the [src]. A console window momentarily fills the screen, with white text rapidly scrolling past.") + to_chat(user, span_notice("You swipe \the [src]. A console window momentarily fills the screen, with white text rapidly scrolling past.")) return TRUE - to_chat(user, "You swipe \the [src]. A console window fills the screen, but it quickly closes itself after only a few lines are written to it.") + to_chat(user, span_notice("You swipe \the [src]. A console window fills the screen, but it quickly closes itself after only a few lines are written to it.")) return FALSE /obj/item/modular_computer/examine(mob/user) . = ..() if(obj_integrity <= integrity_failure * max_integrity) - . += "It is heavily damaged!" + . += span_danger("It is heavily damaged!") else if(obj_integrity < max_integrity) - . += "It is damaged." + . += span_warning("It is damaged.") . += get_modular_computer_parts_examine(user) /obj/item/modular_computer/update_icon_state() - if(!enabled) - icon_state = icon_state_unpowered - else - icon_state = icon_state_powered + icon_state = enabled ? icon_state_powered : icon_state_unpowered + return ..() /obj/item/modular_computer/update_overlays() . = ..() if(!display_overlays) return - if(enabled) - if(active_program) - . += active_program.program_icon_state ? active_program.program_icon_state : icon_state_menu - else - . += icon_state_menu + if(enabled) + . += active_program?.program_icon_state || icon_state_menu if(obj_integrity <= integrity_failure * max_integrity) . += "bsod" . += "broken" @@ -201,9 +230,9 @@ var/issynth = issilicon(user) // Robots and AIs get different activation messages. if(obj_integrity <= integrity_failure * max_integrity) if(issynth) - to_chat(user, "You send an activation signal to \the [src], but it responds with an error code. It must be damaged.") + to_chat(user, span_warning("You send an activation signal to \the [src], but it responds with an error code. It must be damaged.")) else - to_chat(user, "You press the power button, but the computer fails to boot up, displaying variety of errors before shutting down again.") + to_chat(user, span_warning("You press the power button, but the computer fails to boot up, displaying variety of errors before shutting down again.")) return FALSE // If we have a recharger, enable it automatically. Lets computer without a battery work. @@ -213,20 +242,20 @@ if(all_components[MC_CPU] && use_power()) // use_power() checks if the PC is powered if(issynth) - to_chat(user, "You send an activation signal to \the [src], turning it on.") + to_chat(user, span_notice("You send an activation signal to \the [src], turning it on.")) else - to_chat(user, "You press the power button and start up \the [src].") + to_chat(user, span_notice("You press the power button and start up \the [src].")) if(looping_sound) soundloop.start() enabled = 1 - update_icon() + update_appearance() ui_interact(user) return TRUE else // Unpowered if(issynth) - to_chat(user, "You send an activation signal to \the [src] but it does not respond.") + to_chat(user, span_warning("You send an activation signal to \the [src] but it does not respond.")) else - to_chat(user, "You press the power button but \the [src] does not respond.") + to_chat(user, span_warning("You press the power button but \the [src] does not respond.")) return FALSE // Process currently calls handle_power(), may be expanded in future if more things are added. @@ -282,10 +311,10 @@ if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext) //Yeah, we're checking alert_able. No, you don't get to make alerts that the user can't silence. return playsound(src, sound, 50, TRUE) - visible_message("The [src] displays a [caller.filedesc] notification: [alerttext]") + visible_message(span_notice("The [src] displays a [caller.filedesc] notification: [alerttext]")) var/mob/living/holder = loc if(istype(holder)) - to_chat(holder, "[icon2html(src)] The [src] displays a [caller.filedesc] notification: [alerttext]") + to_chat(holder, "[icon2html(src)] [span_notice("The [src] displays a [caller.filedesc] notification: [alerttext]")]") // Function used by NanoUI's to obtain data for header. All relevant entries begin with "PC_" /obj/item/modular_computer/proc/get_header_data() @@ -349,14 +378,13 @@ // Relays kill program request to currently active program. Use this to quit current program. /obj/item/modular_computer/proc/kill_program(forced = FALSE) - set waitfor = FALSE if(active_program) active_program.kill_program(forced) active_program = null var/mob/user = usr if(user && istype(user)) ui_interact(user) // Re-open the UI on this computer. It should show the main screen now. - update_icon() + update_appearance() // Returns 0 for No Signal, 1 for Low Signal and 2 for Good Signal. 3 is for wired connection (always-on) /obj/item/modular_computer/proc/get_ntnet_status(specific_action = 0) @@ -370,6 +398,7 @@ if(!get_ntnet_status()) return FALSE var/obj/item/computer_hardware/network_card/network_card = all_components[MC_NET] + return SSnetworks.station_network.add_log(text, network_card) /obj/item/modular_computer/proc/shutdown_computer(loud = 1) @@ -380,9 +409,9 @@ if(looping_sound) soundloop.stop() if(loud) - physical.visible_message("\The [src] shuts down.") + physical.visible_message(span_notice("\The [src] shuts down.")) enabled = 0 - update_icon() + update_appearance() /** * Toggles the computer's flashlight, if it has one. @@ -412,13 +441,13 @@ if(!has_light || !color) return FALSE comp_light_color = color - // set_light_color(color) + set_light_color(color) update_light() return TRUE /obj/item/modular_computer/screwdriver_act(mob/user, obj/item/tool) if(!all_components.len) - to_chat(user, "This device doesn't have any components installed.") + to_chat(user, span_warning("This device doesn't have any components installed.")) return var/list/component_names = list() for(var/h in all_components) @@ -460,28 +489,34 @@ if(W.tool_behaviour == TOOL_WRENCH) if(all_components.len) - to_chat(user, "Remove all components from \the [src] before disassembling it.") + to_chat(user, span_warning("Remove all components from \the [src] before disassembling it.")) return new /obj/item/stack/sheet/metal( get_turf(src.loc), steel_sheet_cost ) - physical.visible_message("\The [src] is disassembled by [user].") + physical.visible_message(span_notice("\The [src] is disassembled by [user].")) relay_qdel() qdel(src) return if(W.tool_behaviour == TOOL_WELDER) if(obj_integrity == max_integrity) - to_chat(user, "\The [src] does not require repairs.") + to_chat(user, span_warning("\The [src] does not require repairs.")) return if(!W.tool_start_check(user, amount=1)) return - to_chat(user, "You begin repairing damage to \the [src]...") + to_chat(user, span_notice("You begin repairing damage to \the [src]...")) if(W.use_tool(src, user, 20, volume=50, amount=1)) obj_integrity = max_integrity - to_chat(user, "You repair \the [src].") + to_chat(user, span_notice("You repair \the [src].")) return + var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD] + // Check to see if we have an ID inside, and a valid input for money + if(card_slot?.GetID() && iscash(W)) + var/obj/item/card/id/id = card_slot.GetID() + id.attackby(W, user) // If we do, try and put that attacking object in + return ..() // Used by processor to relay qdel() to machinery type. diff --git a/code/modules/modular_computers/computers/item/computer_components.dm b/code/modules/modular_computers/computers/item/computer_components.dm index 8668b279cf..91c369581f 100644 --- a/code/modules/modular_computers/computers/item/computer_components.dm +++ b/code/modules/modular_computers/computers/item/computer_components.dm @@ -3,19 +3,19 @@ return FALSE if(H.w_class > max_hardware_size) - to_chat(user, "This component is too large for \the [src]!") + to_chat(user, span_warning("This component is too large for \the [src]!")) return FALSE if(H.expansion_hw) if(LAZYLEN(expansion_bays) >= max_bays) - to_chat(user, "All of the computer's expansion bays are filled.") + to_chat(user, span_warning("All of the computer's expansion bays are filled.")) return FALSE if(LAZYACCESS(expansion_bays, H.device_type)) - to_chat(user, "The computer immediately ejects /the [H] and flashes an error: \"Hardware Address Conflict\".") + to_chat(user, span_warning("The computer immediately ejects /the [H] and flashes an error: \"Hardware Address Conflict\".")) return FALSE if(all_components[H.device_type]) - to_chat(user, "This computer's hardware slot is already occupied by \the [all_components[H.device_type]].") + to_chat(user, span_warning("This computer's hardware slot is already occupied by \the [all_components[H.device_type]].")) return FALSE return TRUE @@ -32,7 +32,7 @@ LAZYSET(expansion_bays, H.device_type, H) all_components[H.device_type] = H - to_chat(user, "You install \the [H] into \the [src].") + to_chat(user, span_notice("You install \the [H] into \the [src].")) H.holder = src H.forceMove(src) H.on_install(src, user) @@ -47,14 +47,14 @@ LAZYREMOVE(expansion_bays, H.device_type) all_components.Remove(H.device_type) - to_chat(user, "You remove \the [H] from \the [src].") + to_chat(user, span_notice("You remove \the [H] from \the [src].")) H.forceMove(get_turf(src)) H.holder = null H.on_remove(src, user) if(enabled && !use_power()) shutdown_computer() - update_icon() + update_appearance() return TRUE diff --git a/code/modules/modular_computers/computers/item/computer_damage.dm b/code/modules/modular_computers/computers/item/computer_damage.dm index b510f8aded..042b3937aa 100644 --- a/code/modules/modular_computers/computers/item/computer_damage.dm +++ b/code/modules/modular_computers/computers/item/computer_damage.dm @@ -2,9 +2,9 @@ . = ..() var/component_probability = min(50, max(damage_amount*0.1, 1 - obj_integrity/max_integrity)) switch(damage_flag) - if("bullet") + if(BULLET) component_probability = damage_amount * 0.5 - if("laser") + if(LASER) component_probability = damage_amount * 0.66 if(component_probability) for(var/I in all_components) @@ -18,7 +18,7 @@ /obj/item/modular_computer/proc/break_apart() if(!(flags_1 & NODECONSTRUCT_1)) - physical.visible_message("\The [src] breaks apart!") + physical.visible_message(span_notice("\The [src] breaks apart!")) var/turf/newloc = get_turf(src) new /obj/item/stack/sheet/metal(newloc, round(steel_sheet_cost/2)) for(var/C in all_components) diff --git a/code/modules/modular_computers/computers/item/computer_power.dm b/code/modules/modular_computers/computers/item/computer_power.dm index 92d4a812a2..f31c3c82cc 100644 --- a/code/modules/modular_computers/computers/item/computer_power.dm +++ b/code/modules/modular_computers/computers/item/computer_power.dm @@ -16,7 +16,7 @@ if(cell.use(amount * GLOB.CELLRATE)) return TRUE else // Discharge the cell anyway. - cell.use(min(amount*GLOB.CELLRATE, cell.charge)) + cell.use(min(amount * GLOB.CELLRATE, cell.charge)) return FALSE return FALSE diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm index d9d9e5c876..93324bffe8 100644 --- a/code/modules/modular_computers/computers/item/computer_ui.dm +++ b/code/modules/modular_computers/computers/item/computer_ui.dm @@ -13,6 +13,10 @@ ui.close() return + // if(HAS_TRAIT(user, TRAIT_CHUNKYFINGERS)) + // to_chat(user, span_warning("Your fingers are too big to use this right now!")) + // return + // Robots don't really need to see the screen, their wireless connection works as long as computer is on. if(!screen_on && !issilicon(user)) if(ui) @@ -30,7 +34,7 @@ // This screen simply lists available programs and user may select them. var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD] if(!hard_drive || !hard_drive.stored_files || !hard_drive.stored_files.len) - to_chat(user, "\The [src] beeps three times, it's screen displaying a \"DISK ERROR\" warning.") + to_chat(user, span_danger("\The [src] beeps three times, it's screen displaying a \"DISK ERROR\" warning.")) return // No HDD, No HDD files list or no stored files. Something is very broken. ui = SStgui.try_update_ui(user, src, ui) @@ -111,15 +115,9 @@ active_program.program_state = PROGRAM_STATE_BACKGROUND // Should close any existing UIs active_program = null - update_icon() + update_appearance() if(user && istype(user)) ui_interact(user) // Re-open the UI on this computer. It should show the main screen now. - if("eject_pen") - if(istype(src, /obj/item/modular_computer/tablet)) - var/obj/item/modular_computer/tablet/self = src - if(self.can_have_pen) - self.remove_pen() - return if("PC_killprogram") var/prog = params["name"] @@ -132,7 +130,7 @@ return P.kill_program(forced = TRUE) - to_chat(user, "Program [P.filename].[P.filetype] with PID [rand(100,999)] has been killed.") + to_chat(user, span_notice("Program [P.filename].[P.filetype] with PID [rand(100,999)] has been killed.")) if("PC_runprogram") var/prog = params["name"] @@ -142,7 +140,7 @@ P = hard_drive.find_file_by_name(prog) if(!P || !istype(P)) // Program not found or it's not executable program. - to_chat(user, "\The [src]'s screen shows \"I/O ERROR - Unable to run program\" warning.") + to_chat(user, span_danger("\The [src]'s screen shows \"I/O ERROR - Unable to run program\" warning.")) return P.computer = src @@ -156,22 +154,22 @@ active_program = P P.alert_pending = FALSE idle_threads.Remove(P) - update_icon() + update_appearance() return var/obj/item/computer_hardware/processor_unit/PU = all_components[MC_CPU] if(idle_threads.len > PU.max_idle_programs) - to_chat(user, "\The [src] displays a \"Maximal CPU load reached. Unable to run another program.\" error.") + to_chat(user, span_danger("\The [src] displays a \"Maximal CPU load reached. Unable to run another program.\" error.")) return if(P.requires_ntnet && !get_ntnet_status(P.requires_ntnet_feature)) // The program requires NTNet connection, but we are not connected to NTNet. - to_chat(user, "\The [src]'s screen shows \"Unable to connect to NTNet. Please retry. If problem persists contact your system administrator.\" warning.") + to_chat(user, span_danger("\The [src]'s screen shows \"Unable to connect to NTNet. Please retry. If problem persists contact your system administrator.\" warning.")) return if(P.run_program(user)) active_program = P P.alert_pending = FALSE - update_icon() + update_appearance() return 1 if("PC_toggle_light") @@ -185,7 +183,7 @@ if(!new_color) return if(color_hex2num(new_color) < 200) //Colors too dark are rejected - to_chat(user, "That color is too dark! Choose a lighter one.") + to_chat(user, span_warning("That color is too dark! Choose a lighter one.")) new_color = null return set_flashlight_color(new_color) diff --git a/code/modules/modular_computers/computers/item/laptop.dm b/code/modules/modular_computers/computers/item/laptop.dm index 5686dec8d0..bb39381e6d 100644 --- a/code/modules/modular_computers/computers/item/laptop.dm +++ b/code/modules/modular_computers/computers/item/laptop.dm @@ -17,8 +17,8 @@ // No running around with open laptops in hands. item_flags = SLOWS_WHILE_IN_HAND - screen_on = FALSE // Starts closed - var/start_open = TRUE // unless this var is set to 1 + screen_on = FALSE // Starts closed + var/start_open = TRUE // unless this var is set to 1 var/icon_state_closed = "laptop-closed" var/w_class_open = WEIGHT_CLASS_BULKY var/slowdown_open = TRUE @@ -35,7 +35,7 @@ if(card_slot2.stored_card) . += "\The [src] has \a [card_slot2] with an id inside, Alt-click to remove the id." -/obj/item/modular_computer/laptop/Initialize() +/obj/item/modular_computer/laptop/Initialize(mapload) . = ..() if(start_open && !screen_on) @@ -44,15 +44,14 @@ /obj/item/modular_computer/laptop/update_icon_state() if(!screen_on) icon_state = icon_state_closed - else - . = ..() + return + return ..() /obj/item/modular_computer/laptop/update_overlays() - if(screen_on) - return ..() - else + if(!screen_on) cut_overlays() - icon_state = icon_state_closed + return + return ..() /obj/item/modular_computer/laptop/attack_self(mob/user) if(!screen_on) @@ -68,7 +67,8 @@ try_toggle_open(usr) /obj/item/modular_computer/laptop/MouseDrop(obj/over_object, src_location, over_location) - if(istype(over_object, /atom/movable/screen/inventory/hand) || over_object == usr) + . = ..() + if(istype(over_object, /atom/movable/screen/inventory/hand)) var/atom/movable/screen/inventory/hand/H = over_object var/mob/M = usr @@ -103,17 +103,17 @@ /obj/item/modular_computer/laptop/proc/toggle_open(mob/living/user=null) if(screen_on) - to_chat(user, "You close \the [src].") + to_chat(user, span_notice("You close \the [src].")) slowdown = initial(slowdown) w_class = initial(w_class) else - to_chat(user, "You open \the [src].") + to_chat(user, span_notice("You open \the [src].")) slowdown = slowdown_open w_class = w_class_open screen_on = !screen_on display_overlays = screen_on - update_icon() + update_appearance() diff --git a/code/modules/modular_computers/computers/item/laptop_presets.dm b/code/modules/modular_computers/computers/item/laptop_presets.dm index 6bc2919bea..2ed2ec78a5 100644 --- a/code/modules/modular_computers/computers/item/laptop_presets.dm +++ b/code/modules/modular_computers/computers/item/laptop_presets.dm @@ -1,4 +1,4 @@ -/obj/item/modular_computer/laptop/preset/Initialize() +/obj/item/modular_computer/laptop/preset/Initialize(mapload) . = ..() install_component(new /obj/item/computer_hardware/processor_unit/small) install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer)) diff --git a/code/modules/modular_computers/computers/item/processor.dm b/code/modules/modular_computers/computers/item/processor.dm index 970dc8bd1d..d569ad24fd 100644 --- a/code/modules/modular_computers/computers/item/processor.dm +++ b/code/modules/modular_computers/computers/item/processor.dm @@ -38,7 +38,7 @@ integrity_failure = machinery_computer.integrity_failure base_active_power_usage = machinery_computer.base_active_power_usage base_idle_power_usage = machinery_computer.base_idle_power_usage - machinery_computer.RegisterSignal(src, COMSIG_ATOM_UPDATED_ICON, /atom/proc/update_icon) //when we update_icon, also update the computer + machinery_computer.RegisterSignal(src, COMSIG_ATOM_UPDATED_ICON, /obj/machinery/modular_computer/proc/relay_icon_update) //when we update_icon, also update the computer /obj/item/modular_computer/processor/relay_qdel() qdel(machinery_computer) @@ -47,7 +47,7 @@ if(!machinery_computer) return ..() - machinery_computer.update_icon() + machinery_computer.update_appearance() return /obj/item/modular_computer/processor/attack_ghost(mob/user) @@ -57,4 +57,4 @@ if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext) return playsound(src, 'sound/machines/twobeep_high.ogg', 50, TRUE) - machinery_computer.visible_message("The [src] displays a [caller.filedesc] notification: [alerttext]") + machinery_computer.visible_message(span_notice("The [src] displays a [caller.filedesc] notification: [alerttext]")) diff --git a/code/modules/modular_computers/computers/item/tablet.dm b/code/modules/modular_computers/computers/item/tablet.dm index d4d3ef52c2..f495dadbf2 100644 --- a/code/modules/modular_computers/computers/item/tablet.dm +++ b/code/modules/modular_computers/computers/item/tablet.dm @@ -2,9 +2,10 @@ name = "tablet computer" icon = 'icons/obj/modular_tablet.dmi' icon_state = "tablet-red" - icon_state_unpowered = "tablet" - icon_state_powered = "tablet" + icon_state_unpowered = "tablet-red" + icon_state_powered = "tablet-red" icon_state_menu = "menu" + base_icon_state = "tablet" // worn_icon_state = "tablet" hardware_flag = PROGRAM_TABLET max_hardware_size = 1 @@ -28,13 +29,24 @@ if(inserted_item && (!isturf(loc))) . += "Ctrl-click to remove [inserted_item]." -/obj/item/modular_computer/tablet/Initialize() +/obj/item/modular_computer/tablet/Initialize(mapload) . = ..() if(can_have_pen) if(inserted_item) inserted_item = new inserted_item(src) else inserted_item = new /obj/item/pen(src) + register_context() + +/obj/item/modular_computer/tablet/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + if(can_have_pen) + if(inserted_item) + LAZYSET(context[SCREENTIP_CONTEXT_CTRL_LMB], INTENT_ANY, "Remove [inserted_item]") + . = CONTEXTUAL_SCREENTIP_SET + else if(is_type_in_list(held_item, contained_item)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Insert [held_item]") + . = CONTEXTUAL_SCREENTIP_SET /obj/item/modular_computer/tablet/proc/insert_pen(obj/item/pen) if(!usr.transferItemToLoc(pen, src)) @@ -42,6 +54,7 @@ to_chat(usr, "You slide \the [pen] into \the [src]'s pen slot.") inserted_item = pen playsound(src, 'sound/machines/button.ogg', 50, 1) + SStgui.update_uis(src) /obj/item/modular_computer/tablet/proc/remove_pen() if(hasSiliconAccessInArea(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) @@ -51,6 +64,7 @@ usr.put_in_hands(inserted_item) to_chat(usr, "You remove [inserted_item] from \the [src]'s pen slot.") inserted_item = null + SStgui.update_uis(src) else to_chat(usr, "\The [src] does not have a pen in it!") @@ -77,15 +91,27 @@ QDEL_NULL(inserted_item) return ..() +/obj/item/modular_computer/tablet/ui_act(action, params) + . = ..() + if(.) + return + if(action == "TABLET_eject_pen") + if(istype(src, /obj/item/modular_computer/tablet)) + var/obj/item/modular_computer/tablet/self = src + if(self.can_have_pen) + self.remove_pen() + return TRUE + /obj/item/modular_computer/tablet/ui_data(mob/user) . = ..() - .["PC_showpeneject"] = inserted_item ? 1 : 0 + .["TABLET_show_pen_eject"] = inserted_item ? 1 : 0 /obj/item/modular_computer/tablet/update_icon_state() if(has_variants) if(!finish_color) - finish_color = pick("red","blue","brown","green","black") - icon_state = icon_state_powered = icon_state_unpowered = "tablet-[finish_color]" + finish_color = pick("red", "blue", "brown", "green", "black") + icon_state = icon_state_powered = icon_state_unpowered = "[base_icon_state]-[finish_color]" + return ..() /obj/item/modular_computer/tablet/syndicate_contract_uplink name = "contractor tablet" @@ -102,6 +128,8 @@ /// Given to Nuke Ops members. /obj/item/modular_computer/tablet/nukeops icon_state = "tablet-syndicate" + icon_state_powered = "tablet-syndicate" + icon_state_unpowered = "tablet-syndicate" comp_light_luminosity = 6.3 has_variants = FALSE device_theme = "syndicate" @@ -109,15 +137,18 @@ /obj/item/modular_computer/tablet/nukeops/emag_act(mob/user) if(!enabled) - to_chat(user, "You'd need to turn the [src] on first.") + to_chat(user, span_warning("You'd need to turn the [src] on first.")) return FALSE - to_chat(user, "You swipe \the [src]. It's screen briefly shows a message reading \"MEMORY CODE INJECTION DETECTED AND SUCCESSFULLY QUARANTINED\".") + to_chat(user, span_notice("You swipe \the [src]. It's screen briefly shows a message reading \"MEMORY CODE INJECTION DETECTED AND SUCCESSFULLY QUARANTINED\".")) return FALSE /// Borg Built-in tablet interface /obj/item/modular_computer/tablet/integrated name = "modular interface" icon_state = "tablet-silicon" + icon_state_powered = "tablet-silicon" + icon_state_unpowered = "tablet-silicon" + base_icon_state = "tablet-silicon" has_light = FALSE //tablet light button actually enables/disables the borg lamp comp_light_luminosity = 0 has_variants = FALSE @@ -198,14 +229,16 @@ if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext) //Yeah, we're checking alert_able. No, you don't get to make alerts that the user can't silence. return borgo.playsound_local(src, sound, 50, TRUE) - to_chat(borgo, "The [src] displays a [caller.filedesc] notification: [alerttext]") + to_chat(borgo, span_notice("The [src] displays a [caller.filedesc] notification: [alerttext]")) /obj/item/modular_computer/tablet/integrated/syndicate icon_state = "tablet-silicon-syndicate" + icon_state_powered = "tablet-silicon-syndicate" + icon_state_unpowered = "tablet-silicon-syndicate" device_theme = "syndicate" -/obj/item/modular_computer/tablet/integrated/syndicate/Initialize() +/obj/item/modular_computer/tablet/integrated/syndicate/Initialize(mapload) . = ..() borgo.lamp_color = COLOR_RED //Syndicate likes it red diff --git a/code/modules/modular_computers/computers/item/tablet_presets.dm b/code/modules/modular_computers/computers/item/tablet_presets.dm index 90dd149825..44a96aa2e7 100644 --- a/code/modules/modular_computers/computers/item/tablet_presets.dm +++ b/code/modules/modular_computers/computers/item/tablet_presets.dm @@ -3,7 +3,7 @@ /obj/item/modular_computer/tablet/preset/cheap desc = "A low-end tablet often seen among low ranked station personnel." -/obj/item/modular_computer/tablet/preset/cheap/Initialize() +/obj/item/modular_computer/tablet/preset/cheap/Initialize(mapload) . = ..() install_component(new /obj/item/computer_hardware/processor_unit/small) install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer/micro)) @@ -11,7 +11,7 @@ install_component(new /obj/item/computer_hardware/network_card) // Alternative version, an average one, for higher ranked positions mostly -/obj/item/modular_computer/tablet/preset/advanced/Initialize() +/obj/item/modular_computer/tablet/preset/advanced/Initialize(mapload) . = ..() install_component(new /obj/item/computer_hardware/processor_unit/small) install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer)) @@ -20,7 +20,18 @@ install_component(new /obj/item/computer_hardware/card_slot) install_component(new /obj/item/computer_hardware/printer/mini) -/obj/item/modular_computer/tablet/preset/cargo/Initialize() +/obj/item/modular_computer/tablet/preset/science/Initialize(mapload) + . = ..() + var/obj/item/computer_hardware/hard_drive/small/hard_drive = new + install_component(new /obj/item/computer_hardware/processor_unit/small) + install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer)) + install_component(hard_drive) + install_component(new /obj/item/computer_hardware/card_slot) + install_component(new /obj/item/computer_hardware/network_card) + install_component(new /obj/item/computer_hardware/radio_card) + hard_drive.store_file(new /datum/computer_file/program/signaler) + +/obj/item/modular_computer/tablet/preset/cargo/Initialize(mapload) . = ..() var/obj/item/computer_hardware/hard_drive/small/hard_drive = new install_component(new /obj/item/computer_hardware/processor_unit/small) @@ -30,20 +41,41 @@ install_component(new /obj/item/computer_hardware/network_card) install_component(new /obj/item/computer_hardware/printer/mini) // hard_drive.store_file(new /datum/computer_file/program/shipping) + var/datum/computer_file/program/chatclient/chatprogram + chatprogram = new + hard_drive.store_file(chatprogram) + chatprogram.username = get_cargochat_username() -/obj/item/modular_computer/tablet/preset/advanced/atmos/Initialize() //This will be defunct and will be replaced when NtOS PDAs are done +/obj/item/modular_computer/tablet/preset/cargo/proc/get_cargochat_username() + return "cargonian_[rand(1,999)]" + +/obj/item/modular_computer/tablet/preset/cargo/quartermaster/get_cargochat_username() + return "quartermaster" + +/obj/item/modular_computer/tablet/preset/advanced/atmos/Initialize(mapload) //This will be defunct and will be replaced when NtOS PDAs are done . = ..() install_component(new /obj/item/computer_hardware/sensorpackage) -/obj/item/modular_computer/tablet/preset/advanced/command/Initialize() +/obj/item/modular_computer/tablet/preset/advanced/engineering/Initialize(mapload) + . = ..() + var/obj/item/computer_hardware/hard_drive/small/hard_drive = find_hardware_by_name("solid state drive") + hard_drive.store_file(new /datum/computer_file/program/supermatter_monitor) + +/obj/item/modular_computer/tablet/preset/advanced/command/Initialize(mapload) . = ..() var/obj/item/computer_hardware/hard_drive/small/hard_drive = find_hardware_by_name("solid state drive") install_component(new /obj/item/computer_hardware/sensorpackage) install_component(new /obj/item/computer_hardware/card_slot/secondary) hard_drive.store_file(new /datum/computer_file/program/budgetorders) + // hard_drive.store_file(new /datum/computer_file/program/science) + +/obj/item/modular_computer/tablet/preset/advanced/command/engineering/Initialize(mapload) + . = ..() + var/obj/item/computer_hardware/hard_drive/small/hard_drive = find_hardware_by_name("solid state drive") + hard_drive.store_file(new /datum/computer_file/program/supermatter_monitor) /// Given by the syndicate as part of the contract uplink bundle - loads in the Contractor Uplink. -/obj/item/modular_computer/tablet/syndicate_contract_uplink/preset/uplink/Initialize() +/obj/item/modular_computer/tablet/syndicate_contract_uplink/preset/uplink/Initialize(mapload) . = ..() var/obj/item/computer_hardware/hard_drive/small/syndicate/hard_drive = new var/datum/computer_file/program/contract_uplink/uplink = new @@ -62,7 +94,7 @@ install_component(new /obj/item/computer_hardware/printer/mini) /// Given to Nuke Ops members. -/obj/item/modular_computer/tablet/nukeops/Initialize() +/obj/item/modular_computer/tablet/nukeops/Initialize(mapload) . = ..() install_component(new /obj/item/computer_hardware/processor_unit/small) install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer)) @@ -70,7 +102,7 @@ install_component(new /obj/item/computer_hardware/network_card) //Borg Built-in tablet -/obj/item/modular_computer/tablet/integrated/Initialize() +/obj/item/modular_computer/tablet/integrated/Initialize(mapload) . = ..() install_component(new /obj/item/computer_hardware/processor_unit/small) install_component(new /obj/item/computer_hardware/hard_drive/small/integrated) diff --git a/code/modules/modular_computers/computers/machinery/console_presets.dm b/code/modules/modular_computers/computers/machinery/console_presets.dm index 12b2f6d25a..f7ec9c625e 100644 --- a/code/modules/modular_computers/computers/machinery/console_presets.dm +++ b/code/modules/modular_computers/computers/machinery/console_presets.dm @@ -5,7 +5,7 @@ var/_has_battery = FALSE var/_has_ai = FALSE -/obj/machinery/modular_computer/console/preset/Initialize() +/obj/machinery/modular_computer/console/preset/Initialize(mapload) . = ..() if(!cpu) return @@ -26,8 +26,6 @@ /obj/machinery/modular_computer/console/preset/proc/install_programs() return - - // ===== ENGINEERING CONSOLE ===== /obj/machinery/modular_computer/console/preset/engineering console_department = "Engineering" @@ -39,12 +37,14 @@ hard_drive.store_file(new/datum/computer_file/program/power_monitor()) hard_drive.store_file(new/datum/computer_file/program/alarm_monitor()) hard_drive.store_file(new/datum/computer_file/program/supermatter_monitor()) + hard_drive.store_file(new/datum/computer_file/program/nuclear_monitor()) // ===== RESEARCH CONSOLE ===== /obj/machinery/modular_computer/console/preset/research console_department = "Research" name = "research director's console" desc = "A stationary computer. This one comes preloaded with research programs." + _has_second_id_slot = TRUE _has_ai = TRUE /obj/machinery/modular_computer/console/preset/research/install_programs() @@ -84,6 +84,18 @@ hard_drive.store_file(new/datum/computer_file/program/job_management()) hard_drive.store_file(new/datum/computer_file/program/crew_manifest()) +/obj/machinery/modular_computer/console/preset/id/centcom + desc = "A stationary computer. This one comes preloaded with CentCom identification modification programs." + +/obj/machinery/modular_computer/console/preset/id/centcom/install_programs() + var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] + var/datum/computer_file/program/card_mod/card_mod_centcom = new /datum/computer_file/program/card_mod() + card_mod_centcom.is_centcom = TRUE + hard_drive.store_file(new /datum/computer_file/program/chatclient()) + hard_drive.store_file(card_mod_centcom) + hard_drive.store_file(new /datum/computer_file/program/job_management()) + hard_drive.store_file(new /datum/computer_file/program/crew_manifest()) + // ===== CIVILIAN CONSOLE ===== /obj/machinery/modular_computer/console/preset/civilian console_department = "Civilian" @@ -94,3 +106,79 @@ var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] hard_drive.store_file(new/datum/computer_file/program/chatclient()) hard_drive.store_file(new/datum/computer_file/program/arcade()) + +// curator +/obj/machinery/modular_computer/console/preset/curator + console_department = "Civilian" + name = "curator console" + desc = "A stationary computer. This one comes preloaded with art programs." + _has_printer = TRUE + +/obj/machinery/modular_computer/console/preset/curator/install_programs() + var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] + hard_drive.store_file(new/datum/computer_file/program/portrait_printer()) + +// ===== CARGO CHAT CONSOLES ===== +/obj/machinery/modular_computer/console/preset/cargochat + name = "cargo chatroom console" + desc = "A stationary computer. This one comes preloaded with a chatroom for your cargo requests." + ///chat client installed on this computer, just helpful for linking all the computers + var/datum/computer_file/program/chatclient/chatprogram + +/obj/machinery/modular_computer/console/preset/cargochat/install_programs() + var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] + chatprogram = new + chatprogram.computer = cpu + hard_drive.store_file(chatprogram) + chatprogram.username = "[lowertext(console_department)]_department" + chatprogram.program_state = PROGRAM_STATE_ACTIVE + cpu.active_program = chatprogram + +//ONE PER MAP PLEASE, IT MAKES A CARGOBUS FOR EACH ONE OF THESE +/obj/machinery/modular_computer/console/preset/cargochat/cargo + console_department = "Cargo" + name = "department chatroom console" + desc = "A stationary computer. This one comes preloaded with a chatroom for incoming cargo requests. You may moderate it from this computer." + +/obj/machinery/modular_computer/console/preset/cargochat/cargo/install_programs() + var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] + + //adding chat, setting it as the active window immediately + chatprogram = new + chatprogram.computer = cpu + hard_drive.store_file(chatprogram) + chatprogram.program_state = PROGRAM_STATE_ACTIVE + cpu.active_program = chatprogram + + //setting up chat + chatprogram.username = "cargo_requests_operator" + var/datum/ntnet_conversation/cargochat = new + cargochat.operator = chatprogram //adding operator before joining the chat prevents an unnecessary message about switching op from showing + cargochat.add_client(chatprogram) + cargochat.title = "#cargobus" + cargochat.strong = TRUE + chatprogram.active_channel = cargochat.id + +/obj/machinery/modular_computer/console/preset/cargochat/cargo/LateInitialize() + . = ..() + var/datum/ntnet_conversation/cargochat = SSnetworks.station_network.get_chat_channel_by_id(chatprogram.active_channel) + for(var/obj/machinery/modular_computer/console/preset/cargochat/cargochat_console in GLOB.machines) + if(cargochat_console == src) + continue + cargochat_console.chatprogram.active_channel = chatprogram.active_channel + cargochat.add_client(cargochat_console.chatprogram, silent = TRUE) + +/obj/machinery/modular_computer/console/preset/cargochat/service + console_department = "Service" + +/obj/machinery/modular_computer/console/preset/cargochat/engineering + console_department = "Engineering" + +/obj/machinery/modular_computer/console/preset/cargochat/science + console_department = "Science" + +/obj/machinery/modular_computer/console/preset/cargochat/security + console_department = "Security" + +/obj/machinery/modular_computer/console/preset/cargochat/medical + console_department = "Medical" diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm index 090bf1c7fc..5fb771cb85 100644 --- a/code/modules/modular_computers/computers/machinery/modular_computer.dm +++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm @@ -4,30 +4,43 @@ name = "modular computer" desc = "An advanced computer." - use_power = IDLE_POWER_USE - idle_power_usage = 5 - var/hardware_flag = 0 // A flag that describes this device type - var/last_power_usage = 0 // Power usage during last tick - // Modular computers can run on various devices. Each DEVICE (Laptop, Console, Tablet,..) // must have it's own DMI file. Icon states must be called exactly the same in all files, but may look differently // If you create a program which is limited to Laptops and Consoles you don't have to add it's icon_state overlay for Tablets too, for example. - icon = null icon_state = null - var/icon_state_unpowered = null // Icon state when the computer is turned off. - var/icon_state_powered = null // Icon state when the computer is turned on. - var/screen_icon_state_menu = "menu" // Icon state overlay when the computer is turned on, but no program is loaded that would override the screen. - var/screen_icon_screensaver = "standby" // Icon state overlay when the computer is powered, but not 'switched on'. - var/max_hardware_size = 0 // Maximal hardware size. Currently, tablets have 1, laptops 2 and consoles 3. Limits what hardware types can be installed. - var/steel_sheet_cost = 10 // Amount of steel sheets refunded when disassembling an empty frame of this computer. - var/light_strength = 0 // Light luminosity when turned on - var/base_active_power_usage = 100 // Power usage when the computer is open (screen is active) and can be interacted with. Remember hardware can use power too. - var/base_idle_power_usage = 10 // Power usage when the computer is idle and screen is off (currently only applies to laptops) - var/obj/item/modular_computer/processor/cpu = null // CPU that handles most logic while this type only handles power and other specific things. + use_power = IDLE_POWER_USE + idle_power_usage = 5 + ///A flag that describes this device type + var/hardware_flag = 0 + ///Power usage during last tick + var/last_power_usage = 0 -/obj/machinery/modular_computer/Initialize() + + ///Icon state when the computer is turned off. + var/icon_state_unpowered = null + ///Icon state when the computer is turned on. + var/icon_state_powered = null + ///Icon state overlay when the computer is turned on, but no program is loaded that would override the screen. + var/screen_icon_state_menu = "menu" + ///Icon state overlay when the computer is powered, but not 'switched on'. + var/screen_icon_screensaver = "standby" + ///Maximal hardware size. Currently, tablets have 1, laptops 2 and consoles 3. Limits what hardware types can be installed. + var/max_hardware_size = 0 + ///Amount of steel sheets refunded when disassembling an empty frame of this computer. + var/steel_sheet_cost = 10 + ///Light luminosity when turned on + var/light_strength = 0 + ///Power usage when the computer is open (screen is active) and can be interacted with. Remember hardware can use power too. + var/base_active_power_usage = 100 + ///Power usage when the computer is idle and screen is off (currently only applies to laptops) + var/base_idle_power_usage = 10 + + ///CPU that handles most logic while this type only handles power and other specific things. + var/obj/item/modular_computer/processor/cpu = null + +/obj/machinery/modular_computer/Initialize(mapload) . = ..() cpu = new(src) cpu.physical = src @@ -48,32 +61,35 @@ cpu.attack_ghost(user) /obj/machinery/modular_computer/emag_act(mob/user) - . = ..() if(!cpu) - to_chat(user, "You'd need to turn the [src] on first.") + to_chat(user, span_warning("You'd need to turn the [src] on first.")) return FALSE return (cpu.emag_act(user)) -/obj/machinery/modular_computer/update_icon() - cut_overlays() - icon_state = icon_state_powered +/obj/machinery/modular_computer/update_appearance(updates) + . = ..() + set_light(cpu?.enabled ? light_strength : 0) - if(!cpu || !cpu.enabled) +/obj/machinery/modular_computer/update_icon_state() + icon_state = (cpu?.enabled || (!(stat & NOPOWER) && cpu?.use_power())) ? icon_state_powered : icon_state_unpowered + return ..() + +/obj/machinery/modular_computer/update_overlays() + . = ..() + if(!cpu?.enabled) if (!(stat & NOPOWER) && (cpu?.use_power())) - add_overlay(screen_icon_screensaver) - else - icon_state = icon_state_unpowered - set_light(0) + . += screen_icon_screensaver else - set_light(light_strength) - if(cpu.active_program) - add_overlay(cpu.active_program.program_icon_state ? cpu.active_program.program_icon_state : screen_icon_state_menu) - else - add_overlay(screen_icon_state_menu) + . += cpu.active_program?.program_icon_state || screen_icon_state_menu if(cpu && cpu.obj_integrity <= cpu.integrity_failure * cpu.max_integrity) - add_overlay("bsod") - add_overlay("broken") + . += "bsod" + . += "broken" + +/// Eats the "source" arg because update_icon actually expects args now. +/obj/machinery/modular_computer/proc/relay_icon_update(datum/source, updates, updated) + SIGNAL_HANDLER + return update_icon(updates) /obj/machinery/modular_computer/AltClick(mob/user) if(cpu) @@ -98,17 +114,17 @@ /obj/machinery/modular_computer/proc/power_failure(malfunction = 0) var/obj/item/computer_hardware/battery/battery_module = cpu.all_components[MC_CELL] if(cpu?.enabled) // Shut down the computer - visible_message("\The [src]'s screen flickers [battery_module ? "\"BATTERY [malfunction ? "MALFUNCTION" : "CRITICAL"]\"" : "\"EXTERNAL POWER LOSS\""] warning as it shuts down unexpectedly.") + visible_message(span_danger("\The [src]'s screen flickers [battery_module ? "\"BATTERY [malfunction ? "MALFUNCTION" : "CRITICAL"]\"" : "\"EXTERNAL POWER LOSS\""] warning as it shuts down unexpectedly.")) if(cpu) cpu.shutdown_computer(0) - stat |= NOPOWER - update_icon() + set_machine_stat(stat | NOPOWER) + update_appearance() // Modular computers can have battery in them, we handle power in previous proc, so prevent this from messing it up for us. /obj/machinery/modular_computer/power_change() if(cpu?.use_power()) // If MC_CPU still has a power source, PC wouldn't go offline. - stat &= ~NOPOWER - update_icon() + set_machine_stat(stat & ~NOPOWER) + update_appearance() return . = ..() @@ -116,7 +132,7 @@ if(cpu) return cpu.screwdriver_act(user, tool) -/obj/machinery/modular_computer/attackby(obj/item/W as obj, mob/user) +/obj/machinery/modular_computer/attackby(obj/item/W as obj, mob/living/user) if (user.a_intent == INTENT_HELP && cpu && !(flags_1 & NODECONSTRUCT_1)) return cpu.attackby(W, user) return ..() @@ -124,17 +140,18 @@ // Stronger explosions cause serious damage to internal components // Minor explosions are mostly mitigitated by casing. -/obj/machinery/modular_computer/ex_act(severity) +/obj/machinery/modular_computer/ex_act(severity, target, origin) if(cpu) - cpu.ex_act(severity) - // switch(severity) - // if(EXPLODE_DEVASTATE) - // SSexplosions.high_mov_atom += cpu - // if(EXPLODE_HEAVY) - // SSexplosions.med_mov_atom += cpu - // if(EXPLODE_LIGHT) - // SSexplosions.low_mov_atom += cpu - ..() + return cpu.ex_act(severity) + + // switch(severity) + // if(EXPLODE_DEVASTATE) + // SSexplosions.high_mov_atom += cpu + // if(EXPLODE_HEAVY) + // SSexplosions.med_mov_atom += cpu + // if(EXPLODE_LIGHT) + // SSexplosions.low_mov_atom += cpu + return ..() // EMPs are similar to explosions, but don't cause physical damage to the casing. Instead they screw up the components /obj/machinery/modular_computer/emp_act(severity) diff --git a/code/modules/modular_computers/computers/machinery/modular_console.dm b/code/modules/modular_computers/computers/machinery/modular_console.dm index 0e27d81305..3cbdc4a923 100644 --- a/code/modules/modular_computers/computers/machinery/modular_console.dm +++ b/code/modules/modular_computers/computers/machinery/modular_console.dm @@ -16,9 +16,10 @@ light_strength = 2 max_integrity = 300 integrity_failure = 0.5 - var/console_department = "" // Used in New() to set network tag according to our area. + ///Used in New() to set network tag according to our area. + var/console_department = "" -/obj/machinery/modular_computer/console/buildable/Initialize() +/obj/machinery/modular_computer/console/buildable/Initialize(mapload) . = ..() // User-built consoles start as empty frames. var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] @@ -28,7 +29,7 @@ qdel(network_card) qdel(hard_drive) -/obj/machinery/modular_computer/console/Initialize() +/obj/machinery/modular_computer/console/Initialize(mapload) . = ..() var/obj/item/computer_hardware/battery/battery_module = cpu.all_components[MC_CELL] if(battery_module) @@ -52,4 +53,4 @@ network_card.identification_string = "Unknown Console" if(cpu) cpu.screen_on = 1 - update_icon() + update_appearance() diff --git a/code/modules/modular_computers/file_system/computer_file.dm b/code/modules/modular_computers/file_system/computer_file.dm index 4e862c4ae3..08e77b8a9b 100644 --- a/code/modules/modular_computers/file_system/computer_file.dm +++ b/code/modules/modular_computers/file_system/computer_file.dm @@ -1,11 +1,11 @@ /datum/computer_file - var/filename = "NewFile" // Placeholder. No spacebars - var/filetype = "XXX" // File full names are [filename].[filetype] so like NewFile.XXX in this case - var/size = 1 // File size in GQ. Integers only! - var/obj/item/computer_hardware/hard_drive/holder // Holder that contains this file. - var/unsendable = FALSE // Whether the file may be sent to someone via NTNet transfer or other means. - var/undeletable = FALSE // Whether the file may be deleted. Setting to TRUE prevents deletion/renaming/etc. - var/uid // UID of this file + var/filename = "NewFile" // Placeholder. No spacebars + var/filetype = "XXX" // File full names are [filename].[filetype] so like NewFile.XXX in this case + var/size = 1 // File size in GQ. Integers only! + var/obj/item/computer_hardware/hard_drive/holder // Holder that contains this file. + var/unsendable = FALSE // Whether the file may be sent to someone via NTNet transfer or other means. + var/undeletable = FALSE // Whether the file may be deleted. Setting to TRUE prevents deletion/renaming/etc. + var/uid // UID of this file var/static/file_uid = 0 /datum/computer_file/New() diff --git a/code/modules/modular_computers/file_system/data.dm b/code/modules/modular_computers/file_system/data.dm index 32ef6f53dd..e0404e787f 100644 --- a/code/modules/modular_computers/file_system/data.dm +++ b/code/modules/modular_computers/file_system/data.dm @@ -1,10 +1,10 @@ // /data/ files store data in string format. // They don't contain other logic for now. /datum/computer_file/data - var/stored_data = "" // Stored data in string format. + var/stored_data = "" // Stored data in string format. filetype = "DAT" var/block_size = 250 - var/do_not_edit = 0 // Whether the user will be reminded that the file probably shouldn't be edited. + var/do_not_edit = 0 // Whether the user will be reminded that the file probably shouldn't be edited. /datum/computer_file/data/clone() var/datum/computer_file/data/temp = ..() diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index a86405f882..dc0cdda5d1 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -15,6 +15,8 @@ var/filedesc = "Unknown Program" /// Short description of this program's function. var/extended_desc = "N/A" + /// Category in the NTDownloader. + var/category = PROGRAM_CATEGORY_MISC /// Program-specific screen icon state var/program_icon_state = null /// Set to 1 for program to require nonstop NTNet connection to run. If NTNet connection is lost program crashes. @@ -25,10 +27,10 @@ var/ntnet_status = 1 /// Bitflags (PROGRAM_CONSOLE, PROGRAM_LAPTOP, PROGRAM_TABLET combination) or PROGRAM_ALL var/usage_flags = PROGRAM_ALL - /// Whether the program can be downloaded from NTNet. Set to 0 to disable. - var/available_on_ntnet = 1 - /// Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to 1 to enable. - var/available_on_syndinet = 0 + /// Whether the program can be downloaded from NTNet. Set to FALSE to disable. + var/available_on_ntnet = TRUE + /// Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to TRUE to enable. + var/available_on_syndinet = FALSE /// Name of the tgui interface var/tgui_id /// Example: "something.gif" - a header image that will be rendered in computer's UI when this program is running at background. Images are taken from /icons/program_icons. Be careful not to use too large images! @@ -64,7 +66,7 @@ // Relays icon update to the computer. /datum/computer_file/program/proc/update_computer_icon() if(computer) - computer.update_icon() + computer.update_appearance() // Attempts to create a log in global ntnet datum. Returns 1 on success, 0 on fail. /datum/computer_file/program/proc/generate_network_log(text) @@ -72,10 +74,25 @@ return computer.add_log(text) return 0 +/** + *Runs when the device is used to attack an atom in non-combat mode. + * + *Simulates using the device to read or scan something. Tap is called by the computer during pre_attack + *and sends us all of the related info. If we return TRUE, the computer will stop the attack process + *there. What we do with the info is up to us, but we should only return TRUE if we actually perform + *an action of some sort. + *Arguments: + *A is the atom being tapped + *user is the person making the attack action + *params is anything the pre_attack() proc had in the same-named variable. +*/ +/datum/computer_file/program/proc/tap(atom/A, mob/living/user, params) + return FALSE + /datum/computer_file/program/proc/is_supported_by_hardware(hardware_flag = 0, loud = 0, mob/user = null) if(!(hardware_flag & usage_flags)) if(loud && computer && user) - to_chat(user, "\The [computer] flashes a \"Hardware Error - Incompatible software\" warning.") + to_chat(user, span_danger("\The [computer] flashes a \"Hardware Error - Incompatible software\" warning.")) return FALSE return TRUE @@ -109,7 +126,7 @@ if(!access_to_check) // No required_access, allow it. return TRUE - if(!transfer && computer && (computer.obj_flags & EMAGGED)) //emags can bypass the execution locks but not the download ones. + if(!transfer && computer && (computer.obj_flags & EMAGGED)) //emags can bypass the execution locks but not the download ones. return TRUE if(IsAdminGhost(user)) @@ -127,14 +144,14 @@ if(!D) if(loud) - to_chat(user, "\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.") + to_chat(user, span_danger("\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.")) return FALSE access = D.GetAccess() if(access_to_check in access) return TRUE if(loud) - to_chat(user, "\The [computer] flashes an \"Access Denied\" warning.") + to_chat(user, span_danger("\The [computer] flashes an \"Access Denied\" warning.")) return FALSE // This attempts to retrieve header data for UIs. If implementing completely new device of different type than existing ones @@ -219,7 +236,7 @@ program_state = PROGRAM_STATE_BACKGROUND // Should close any existing UIs computer.active_program = null - computer.update_icon() + computer.update_appearance() ui.close() if(user && istype(user)) diff --git a/code/modules/modular_computers/file_system/program_events.dm b/code/modules/modular_computers/file_system/program_events.dm index 1cb74a227b..c11b1066bd 100644 --- a/code/modules/modular_computers/file_system/program_events.dm +++ b/code/modules/modular_computers/file_system/program_events.dm @@ -13,6 +13,6 @@ /datum/computer_file/program/proc/event_networkfailure(background) kill_program(forced = TRUE) if(background) - computer.visible_message("\The [computer]'s screen displays a \"Process [filename].[filetype] (PID [rand(100,999)]) terminated - Network Error\" error") + computer.visible_message(span_danger("\The [computer]'s screen displays a \"Process [filename].[filetype] (PID [rand(100,999)]) terminated - Network Error\" error")) else - computer.visible_message("\The [computer]'s screen briefly freezes and then shows \"NETWORK ERROR - NTNet connection lost. Please retry. If problem persists contact your system administrator.\" error.") + computer.visible_message(span_danger("\The [computer]'s screen briefly freezes and then shows \"NETWORK ERROR - NTNet connection lost. Please retry. If problem persists contact your system administrator.\" error.")) diff --git a/code/modules/modular_computers/file_system/programs/airestorer.dm b/code/modules/modular_computers/file_system/programs/airestorer.dm index faf2831ca1..ff5240306b 100644 --- a/code/modules/modular_computers/file_system/programs/airestorer.dm +++ b/code/modules/modular_computers/file_system/programs/airestorer.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/aidiag filename = "aidiag" filedesc = "NT FRK" + category = PROGRAM_CATEGORY_ROBO program_icon_state = "generic" extended_desc = "Firmware Restoration Kit, capable of reconstructing damaged AI systems. Requires direct AI connection via intellicard slot." size = 12 @@ -55,7 +56,7 @@ /datum/computer_file/program/aidiag/process_tick() . = ..() - if(!restoring) //Put the check here so we don't check for an ai all the time + if(!restoring) //Put the check here so we don't check for an ai all the time return var/obj/item/aicard/cardhold = get_ai(2) @@ -64,7 +65,7 @@ var/mob/living/silicon/ai/A = get_ai() if(!A || !cardhold) - restoring = FALSE // If the AI was removed, stop the restoration sequence. + restoring = FALSE // If the AI was removed, stop the restoration sequence. if(ai_slot) ai_slot.locked = FALSE return @@ -74,9 +75,8 @@ restoring = FALSE return ai_slot.locked = TRUE - A.adjustOxyLoss(-5, FALSE) - A.adjustFireLoss(-5, FALSE) - A.adjustToxLoss(-5, FALSE) + A.adjustOxyLoss(-5, FALSE, FALSE) + A.adjustFireLoss(-5, FALSE, FALSE) A.adjustBruteLoss(-5, FALSE) // Please don't forget to update health, otherwise the below if statements will probably always fail. @@ -84,7 +84,7 @@ if(A.health >= 0 && A.stat == DEAD) A.revive(full_heal = FALSE, admin_revive = FALSE) - cardhold.update_icon() + cardhold.update_appearance() // Finished restoring if(A.health >= 100) diff --git a/code/modules/modular_computers/file_system/programs/alarm.dm b/code/modules/modular_computers/file_system/programs/alarm.dm index 646d9892ba..80c0c4dfa8 100644 --- a/code/modules/modular_computers/file_system/programs/alarm.dm +++ b/code/modules/modular_computers/file_system/programs/alarm.dm @@ -36,35 +36,49 @@ return data -/datum/computer_file/program/alarm_monitor/proc/triggerAlarm(class, area/A, O, obj/source) +/datum/computer_file/program/alarm_monitor/proc/triggerAlarm(class, area/home, cameras, obj/source) if(is_station_level(source.z)) - if(!(A.type in GLOB.the_station_areas)) + if(!(home.type in GLOB.the_station_areas)) return - else if(!is_mining_level(source.z) || istype(A, /area/ruin)) + else if(!is_mining_level(source.z) || istype(home, /area/ruin)) return - var/list/L = alarms[class] - for(var/I in L) - if (I == A.name) - var/list/alarm = L[I] + var/list/our_sort = alarms[class] + for(var/areaname in our_sort) + if (areaname == home.name) + var/list/alarm = our_sort[areaname] var/list/sources = alarm[3] if (!(source in sources)) sources += source - return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if(O && istype(O, /list)) - CL = O - if (CL.len == 1) - C = CL[1] - else if(O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C ? C : O), list(source)) + return TRUE + + var/obj/machinery/camera/cam = null + var/list/our_cams = null + if(cameras && islist(cameras)) + our_cams = cameras + if (our_cams.len == 1) + cam = our_cams[1] + else if(cameras && istype(cameras, /obj/machinery/camera)) + cam = cameras + our_sort[home.name] = list(home, (cam ? cam : cameras), list(source)) update_alarm_display() + return TRUE - return 1 - +/datum/computer_file/program/alarm_monitor/proc/freeCamera(area/home, obj/machinery/camera/cam) + for(var/class in alarms) + var/our_area = alarms[class][home.name] + if(!our_area) + continue + var/cams = our_area[2] //Get the cameras + if(!cams) + continue + if(islist(cams)) + cams -= cam + if(length(cams) == 1) + our_area[2] = cams[1] + else + our_area[2] = null /datum/computer_file/program/alarm_monitor/proc/cancelAlarm(class, area/A, obj/origin) var/list/L = alarms[class] diff --git a/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm b/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm index 8709526de6..1cad0e46f8 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/contract_uplink filename = "contractor uplink" filedesc = "Syndicate Contractor Uplink" + category = PROGRAM_CATEGORY_MISC program_icon_state = "assign" extended_desc = "A standard, Syndicate issued system for handling important contracts while on the field." size = 10 @@ -91,9 +92,9 @@ if(ishuman(user)) var/mob/living/carbon/human/H = user if(H.put_in_hands(crystals)) - to_chat(H, "Your payment materializes into your hands!") + to_chat(H, span_notice("Your payment materializes into your hands!")) else - to_chat(user, "Your payment materializes onto the floor.") + to_chat(user, span_notice("Your payment materializes onto the floor.")) hard_drive.traitor_data.contractor_hub.contract_TC_payed_out += hard_drive.traitor_data.contractor_hub.contract_TC_to_redeem hard_drive.traitor_data.contractor_hub.contract_TC_to_redeem = 0 @@ -164,6 +165,11 @@ )) for (var/datum/syndicate_contract/contract in traitor_data.contractor_hub.assigned_contracts) + if(!contract.contract) + stack_trace("Syndiate contract with null contract objective found in [traitor_data.owner]'s contractor hub!") + contract.status = CONTRACT_STATUS_ABORTED + continue + data["contracts"] += list(list( "target" = contract.contract.target, "target_rank" = contract.target_rank, diff --git a/code/modules/modular_computers/file_system/programs/antagonist/dos.dm b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm index bb3c62cac2..90510bacdb 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/dos.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/ntnet_dos filename = "ntn_dos" filedesc = "DoS Traffic Generator" + category = PROGRAM_CATEGORY_MISC program_icon_state = "hostile" extended_desc = "This advanced script can perform denial of service attacks against NTNet quantum relays. The system administrator will probably notice this. Multiple devices can run this program together against same relay for increased effect" size = 20 diff --git a/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm index ba24a5ab3e..4e5afa32a7 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/revelation filename = "revelation" filedesc = "Revelation" + category = PROGRAM_CATEGORY_MISC program_icon_state = "hostile" extended_desc = "This virus can destroy hard drive of system it is executed on. It may be obfuscated to look like another non-malicious program. Once armed, it will destroy the system upon next execution." size = 13 @@ -20,13 +21,13 @@ if(computer) if(istype(computer, /obj/item/modular_computer/tablet/integrated)) //If this is a borg's integrated tablet var/obj/item/modular_computer/tablet/integrated/modularInterface = computer - to_chat(modularInterface.borgo,"SYSTEM PURGE DETECTED/") + to_chat(modularInterface.borgo,span_userdanger("SYSTEM PURGE DETECTED/")) addtimer(CALLBACK(modularInterface.borgo, /mob/living/silicon/robot/.proc/death), 2 SECONDS, TIMER_UNIQUE) return - computer.visible_message("\The [computer]'s screen brightly flashes and loud electrical buzzing is heard.") + computer.visible_message(span_notice("\The [computer]'s screen brightly flashes and loud electrical buzzing is heard.")) computer.enabled = FALSE - computer.update_icon() + computer.update_appearance() var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD] var/obj/item/computer_hardware/battery/battery_module = computer.all_components[MC_CELL] var/obj/item/computer_hardware/recharger/recharger = computer.all_components[MC_CHARGE] @@ -34,13 +35,13 @@ computer.take_damage(25, BRUTE, 0, 0) if(battery_module && prob(25)) qdel(battery_module) - computer.visible_message("\The [computer]'s battery explodes in rain of sparks.") + computer.visible_message(span_notice("\The [computer]'s battery explodes in rain of sparks.")) var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread spark_system.start() if(recharger && prob(50)) qdel(recharger) - computer.visible_message("\The [computer]'s recharger explodes in rain of sparks.") + computer.visible_message(span_notice("\The [computer]'s recharger explodes in rain of sparks.")) var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread spark_system.start() diff --git a/code/modules/modular_computers/file_system/programs/arcade.dm b/code/modules/modular_computers/file_system/programs/arcade.dm index c330cdcbe8..3fe38cdf6f 100644 --- a/code/modules/modular_computers/file_system/programs/arcade.dm +++ b/code/modules/modular_computers/file_system/programs/arcade.dm @@ -32,7 +32,7 @@ game_active = FALSE program_icon_state = "arcade_off" if(istype(computer)) - computer.update_icon() + computer.update_appearance() ticket_count += 1 // user?.mind?.adjust_experience(/datum/skill/gaming, 50) sleep(10) @@ -42,7 +42,7 @@ game_active = FALSE program_icon_state = "arcade_off" if(istype(computer)) - computer.update_icon() + computer.update_appearance() // user?.mind?.adjust_experience(/datum/skill/gaming, 10) sleep(10) @@ -150,20 +150,20 @@ return TRUE if("Dispense_Tickets") if(!printer) - to_chat(usr, "Hardware error: A printer is required to redeem tickets.") + to_chat(usr, span_notice("Hardware error: A printer is required to redeem tickets.")) return if(printer.stored_paper <= 0) - to_chat(usr, "Hardware error: Printer is out of paper.") + to_chat(usr, span_notice("Hardware error: Printer is out of paper.")) return else - computer.visible_message("\The [computer] prints out paper.") + computer.visible_message(span_notice("\The [computer] prints out paper.")) if(ticket_count >= 1) new /obj/item/stack/arcadeticket((get_turf(computer)), 1) - to_chat(usr, "[src] dispenses a ticket!") + to_chat(usr, span_notice("[computer] dispenses a ticket!")) ticket_count -= 1 printer.stored_paper -= 1 else - to_chat(usr, "You don't have any stored tickets!") + to_chat(usr, span_notice("You don't have any stored tickets!")) return TRUE if("Start_Game") game_active = TRUE @@ -175,4 +175,4 @@ boss_id = rand(1,6) pause_state = FALSE if(istype(computer)) - computer.update_icon() + computer.update_appearance() diff --git a/code/modules/modular_computers/file_system/programs/atmosscan.dm b/code/modules/modular_computers/file_system/programs/atmosscan.dm index 1576a5b4b7..db9f0d85b4 100644 --- a/code/modules/modular_computers/file_system/programs/atmosscan.dm +++ b/code/modules/modular_computers/file_system/programs/atmosscan.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/atmosscan filename = "atmosscan" filedesc = "AtmoZphere" + category = PROGRAM_CATEGORY_ENGI program_icon_state = "air" extended_desc = "A small built-in sensor reads out the atmospheric conditions around the device." size = 4 @@ -12,7 +13,7 @@ if (!.) return if(!computer?.get_modular_computer_part(MC_SENSORS)) //Giving a clue to users why the program is spitting out zeros. - to_chat(user, "\The [computer] flashes an error: \"hardware\\sensorpackage\\startup.bin -- file not found\".") + to_chat(user, span_warning("\The [computer] flashes an error: \"hardware\\sensorpackage\\startup.bin -- file not found\".")) /datum/computer_file/program/atmosscan/ui_data(mob/user) diff --git a/code/modules/modular_computers/file_system/programs/borg_monitor.dm b/code/modules/modular_computers/file_system/programs/borg_monitor.dm index 46e1f89ee4..10f6561087 100644 --- a/code/modules/modular_computers/file_system/programs/borg_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/borg_monitor.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/borg_monitor filename = "siliconnect" filedesc = "SiliConnect" + category = PROGRAM_CATEGORY_ROBO ui_header = "borg_mon.gif" program_icon_state = "generic" extended_desc = "This program allows for remote monitoring of station cyborgs." @@ -9,6 +10,70 @@ size = 5 tgui_id = "NtosCyborgRemoteMonitor" program_icon = "project-diagram" + var/emagged = FALSE ///Bool of if this app has already been emagged + var/list/loglist = list() ///A list to copy a borg's IC log list into + var/mob/living/silicon/robot/DL_source ///reference of a borg if we're downloading a log, or null if not. + var/DL_progress = -1 ///Progress of current download, 0 to 100, -1 for no current download + +/datum/computer_file/program/borg_monitor/Destroy() + loglist = null + DL_source = null + return ..() + +/datum/computer_file/program/borg_monitor/kill_program(forced = FALSE) + loglist = null //Not everything is saved if you close an app + DL_source = null + DL_progress = 0 + return ..() + +/datum/computer_file/program/borg_monitor/run_emag() + if(emagged) + return FALSE + emagged = TRUE + return TRUE + +/datum/computer_file/program/borg_monitor/tap(atom/A, mob/living/user, params) + var/mob/living/silicon/robot/borgo = A + if(!istype(borgo) || !borgo.modularInterface) + return FALSE + DL_source = borgo + DL_progress = 0 + + var/username = "unknown user" + var/obj/item/card/id/stored_card = computer.GetID() + if(istype(stored_card) && stored_card.registered_name) + username = "user [stored_card.registered_name]" + to_chat(borgo, span_userdanger("Request received from [username] for the system log file. Upload in progress."))//Damning evidence may be contained, so warn the borg + borgo.logevent("File request by [username]: /var/logs/syslog") + return TRUE + +/datum/computer_file/program/borg_monitor/process_tick() + if(!DL_source) + DL_progress = -1 + return + + var/turf/here = get_turf(computer) + var/turf/there = get_turf(DL_source) + if(!here.Adjacent(there))//If someone walked away, cancel the download + to_chat(DL_source, span_danger("Log upload failed: general connection error."))//Let the borg know the upload stopped + DL_source = null + DL_progress = -1 + return + + if(DL_progress == 100) + if(!DL_source || !DL_source.modularInterface) //sanity check, in case the borg or their modular tablet poofs somehow + loglist = list("System log of unit [DL_source.name]") + loglist += "Error -- Download corrupted." + else + loglist = DL_source.modularInterface.borglog.Copy() + loglist.Insert(1,"System log of unit [DL_source.name]") + DL_progress = -1 + DL_source = null + for(var/datum/tgui/window in SStgui.open_uis_by_src[REF(src)]) + window.send_full_update() + return + + DL_progress += 25 /datum/computer_file/program/borg_monitor/ui_data(mob/user) var/list/data = get_header_data() @@ -32,15 +97,22 @@ var/list/cyborg_data = list( name = R.name, + integ = round((R.health + 100) / 2), //mob heath is -100 to 100, we want to scale that to 0 - 100 locked_down = R.locked_down, status = R.stat, shell_discon = shell, charge = R.cell ? round(R.cell.percent()) : null, - module = R.module ? "[R.module.name] Module" : "No Module Detected", + module = R.module ? "[R.module.name] Model" : "No Model Detected", upgrades = upgrade, ref = REF(R) ) data["cyborgs"] += list(cyborg_data) + data["DL_progress"] = DL_progress + return data + +/datum/computer_file/program/borg_monitor/ui_static_data(mob/user) + var/list/data = list() + data["borglog"] = loglist return data /datum/computer_file/program/borg_monitor/ui_act(action, params) @@ -57,16 +129,16 @@ if(!ID) return if(R.stat == DEAD) //Dead borgs will listen to you no longer - to_chat(usr, "Error -- Could not open a connection to unit:[R]") + to_chat(usr, span_warning("Error -- Could not open a connection to unit:[R]")) var/message = stripped_input(usr, message = "Enter message to be sent to remote cyborg.", title = "Send Message") if(!message) return - to_chat(R, "

    Message from [ID] -- \"[message]\"
    ") + to_chat(R, "

    [span_notice("Message from [ID] -- \"[message]\"")]
    ") to_chat(usr, "Message sent to [R]: [message]") R.logevent("Message from [ID] -- \"[message]\"") SEND_SOUND(R, 'sound/machines/twobeep_high.ogg') if(R.connected_ai) - to_chat(R.connected_ai, "

    Message from [ID] to [R] -- \"[message]\"
    ") + to_chat(R.connected_ai, "

    [span_notice("Message from [ID] to [R] -- \"[message]\"")]
    ") SEND_SOUND(R.connected_ai, 'sound/machines/twobeep_high.ogg') usr.log_talk(message, LOG_PDA, tag="Cyborg Monitor Program: ID name \"[ID]\" to [R]") @@ -82,12 +154,15 @@ /datum/computer_file/program/borg_monitor/proc/checkID() var/obj/item/card/id/ID = computer.GetID() if(!ID) + if(emagged) + return "STDERR:UNDF" return FALSE return ID.registered_name /datum/computer_file/program/borg_monitor/syndicate filename = "roboverlord" filedesc = "Roboverlord" + category = PROGRAM_CATEGORY_ROBO ui_header = "borg_mon.gif" program_icon_state = "generic" extended_desc = "This program allows for remote monitoring of mission-assigned cyborgs." @@ -97,6 +172,9 @@ transfer_access = null tgui_id = "NtosCyborgRemoteMonitorSyndicate" +/datum/computer_file/program/borg_monitor/syndicate/run_emag() + return FALSE + /datum/computer_file/program/borg_monitor/syndicate/evaluate_borg(mob/living/silicon/robot/R) if((get_turf(computer)).z != (get_turf(R)).z) return FALSE diff --git a/code/modules/modular_computers/file_system/programs/bounty_board.dm b/code/modules/modular_computers/file_system/programs/bounty_board.dm index 9c42a28a9b..d008d5e72b 100644 --- a/code/modules/modular_computers/file_system/programs/bounty_board.dm +++ b/code/modules/modular_computers/file_system/programs/bounty_board.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/bounty_board filename = "bountyboard" filedesc = "Bounty Board Request Network" + category = PROGRAM_CATEGORY_SUPL program_icon_state = "bountyboard" extended_desc = "A multi-platform network for placing requests across the station, with payment across the network being possible.." requires_ntnet = TRUE diff --git a/code/modules/modular_computers/file_system/programs/budgetordering.dm b/code/modules/modular_computers/file_system/programs/budgetordering.dm index 162f480c02..a269f88242 100644 --- a/code/modules/modular_computers/file_system/programs/budgetordering.dm +++ b/code/modules/modular_computers/file_system/programs/budgetordering.dm @@ -1,11 +1,10 @@ /datum/computer_file/program/budgetorders filename = "orderapp" filedesc = "NT IRN" - // category = PROGRAM_CATEGORY_SUPL + category = PROGRAM_CATEGORY_SUPL program_icon_state = "request" extended_desc = "Nanotrasen Internal Requisition Network interface for supply purchasing using a department budget account." requires_ntnet = TRUE - transfer_access = ACCESS_HEADS usage_flags = PROGRAM_LAPTOP | PROGRAM_TABLET size = 20 tgui_id = "NtosCargo" @@ -18,15 +17,30 @@ ///Can this console approve purchase requests? var/can_approve_requests = FALSE ///What do we say when the shuttle moves with living beings on it. - var/safety_warning = "For safety reasons, the automated supply shuttle \ - cannot transport live organisms, human remains, classified nuclear weaponry, \ - homing beacons or machinery housing any form of artificial intelligence." + var/safety_warning = "For safety and ethical reasons, the automated supply shuttle \ + cannot transport live organisms, human remains, classified nuclear weaponry, mail, \ + homing beacons, unstable eigenstates or machinery housing any form of artificial intelligence." ///If you're being raided by pirates, what do you tell the crew? var/blockade_warning = "Bluespace instability detected. Shuttle movement impossible." + ///The name of the shuttle template being used as the cargo shuttle. 'supply' is default and contains critical code. Don't change this unless you know what you're doing. + var/cargo_shuttle = "supply" + ///The docking port called when returning to the station. + var/docking_home = "supply_home" + ///The docking port called when leaving the station. + var/docking_away = "supply_away" + ///If this console can loan the cargo shuttle. Set to false to disable. + var/stationcargo = TRUE + ///The account this console processes and displays. Independent from the account the shuttle processes. + var/cargo_account = ACCOUNT_CAR /datum/computer_file/program/budgetorders/proc/get_export_categories() . = EXPORT_CARGO +/datum/computer_file/program/budgetorders/run_emag() + if(!contraband) + contraband = TRUE + return TRUE + /datum/computer_file/program/budgetorders/proc/is_visible_pack(mob/user, paccess_to_check, list/access, contraband) if(issilicon(user)) //Borgs can't buy things. return FALSE @@ -59,11 +73,11 @@ . = ..() var/list/data = get_header_data() data["location"] = SSshuttle.supply.getStatusText() - var/datum/bank_account/buyer = SSeconomy.get_dep_account(ACCOUNT_CAR) + var/datum/bank_account/buyer = SSeconomy.get_dep_account(cargo_account) var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD] var/obj/item/card/id/id_card = card_slot?.GetID() if(id_card?.registered_account) - if(ACCESS_HEADS in id_card.access) + if((ACCESS_HEADS in id_card.access) || (ACCESS_QM in id_card.access)) requestonly = FALSE buyer = SSeconomy.get_dep_account(id_card.registered_account.account_job.paycheck_department) can_approve_requests = TRUE @@ -91,7 +105,7 @@ continue data["supplies"][P.group]["packs"] += list(list( "name" = P.name, - "cost" = P.cost, + "cost" = P.get_cost(), "id" = pack, "desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name. "goody" = P.goody, @@ -100,7 +114,7 @@ //Data regarding the User's capability to buy things. data["has_id"] = id_card - data["away"] = SSshuttle.supply.getDockedId() == "supply_away" + data["away"] = SSshuttle.supply.getDockedId() == docking_away data["self_paid"] = self_paid data["docked"] = SSshuttle.supply.mode == SHUTTLE_IDLE data["loan"] = !!SSshuttle.shuttle_loan @@ -118,7 +132,7 @@ for(var/datum/supply_order/SO in SSshuttle.shoppinglist) data["cart"] += list(list( "object" = SO.pack.name, - "cost" = SO.pack.cost, + "cost" = SO.pack.get_cost(), "id" = SO.id, "orderer" = SO.orderer, "paid" = !isnull(SO.paying_account) //paid by requester @@ -128,7 +142,7 @@ for(var/datum/supply_order/SO in SSshuttle.requestlist) data["requests"] += list(list( "object" = SO.pack.name, - "cost" = SO.pack.cost, + "cost" = SO.pack.get_cost(), "orderer" = SO.orderer, "reason" = SO.reason, "id" = SO.id @@ -148,15 +162,15 @@ if(SSshuttle.supplyBlocked) computer.say(blockade_warning) return - if(SSshuttle.supply.getDockedId() == "supply_home") + if(SSshuttle.supply.getDockedId() == docking_home) SSshuttle.supply.export_categories = get_export_categories() - SSshuttle.moveShuttle("supply", "supply_away", TRUE) + SSshuttle.moveShuttle(cargo_shuttle, docking_away, TRUE) computer.say("The supply shuttle is departing.") computer.investigate_log("[key_name(usr)] sent the supply shuttle away.", INVESTIGATE_CARGO) else computer.investigate_log("[key_name(usr)] called the supply shuttle.", INVESTIGATE_CARGO) computer.say("The supply shuttle has been called and will arrive in [SSshuttle.supply.timeLeft(600)] minutes.") - SSshuttle.moveShuttle("supply", "supply_home", TRUE) + SSshuttle.moveShuttle(cargo_shuttle, docking_home, TRUE) . = TRUE if("loan") if(!SSshuttle.shuttle_loan) @@ -166,7 +180,9 @@ return else if(SSshuttle.supply.mode != SHUTTLE_IDLE) return - else if(SSshuttle.supply.getDockedId() != "supply_away") + else if(SSshuttle.supply.getDockedId() != docking_away) + return + else if(stationcargo != TRUE) return else SSshuttle.shuttle_loan.loan_shuttle() @@ -268,7 +284,7 @@ self_paid = !self_paid . = TRUE if(.) - post_signal("supply") + post_signal(cargo_shuttle) /datum/computer_file/program/budgetorders/proc/post_signal(command) diff --git a/code/modules/modular_computers/file_system/programs/card.dm b/code/modules/modular_computers/file_system/programs/card.dm index 65bb5f2343..18e717191e 100644 --- a/code/modules/modular_computers/file_system/programs/card.dm +++ b/code/modules/modular_computers/file_system/programs/card.dm @@ -9,6 +9,7 @@ /datum/computer_file/program/card_mod filename = "plexagonidwriter" filedesc = "Plexagon Access Management" + category = PROGRAM_CATEGORY_CREW program_icon_state = "id" extended_desc = "Program for programming employee ID cards to access parts of the station." transfer_access = ACCESS_HEADS diff --git a/code/modules/modular_computers/file_system/programs/cargobounty.dm b/code/modules/modular_computers/file_system/programs/cargobounty.dm deleted file mode 100644 index 74ac44ade3..0000000000 --- a/code/modules/modular_computers/file_system/programs/cargobounty.dm +++ /dev/null @@ -1,47 +0,0 @@ -/datum/computer_file/program/bounty - filename = "bounty" - filedesc = "Nanotrasen Bounty Hunter" - program_icon_state = "bounty" - extended_desc = "A basic interface for supply personnel to check and claim bounties." - requires_ntnet = TRUE - transfer_access = ACCESS_CARGO - size = 10 - tgui_id = "NtosBountyConsole" - ///cooldown var for printing paper sheets. - var/printer_ready = 0 - ///The cargo account for grabbing the cargo account's credits. - var/static/datum/bank_account/cargocash - -/datum/computer_file/program/bounty/proc/print_paper() - new /obj/item/paper/bounty_printout(get_turf(computer)) - -/datum/computer_file/program/bounty/ui_interact(mob/user, datum/tgui/ui) - if(!GLOB.bounties_list.len) - setup_bounties() - printer_ready = world.time + PRINTER_TIMEOUT - cargocash = SSeconomy.get_dep_account(ACCOUNT_CAR) - . = ..() - -/datum/computer_file/program/bounty/ui_data(mob/user) - var/list/data = get_header_data() - var/list/bountyinfo = list() - for(var/datum/bounty/B in GLOB.bounties_list) - bountyinfo += list(list("name" = B.name, "description" = B.description, "reward_string" = B.reward_string(), "completion_string" = B.completion_string() , "claimed" = B.claimed, "can_claim" = B.can_claim(), "priority" = B.high_priority, "bounty_ref" = REF(B))) - data["stored_cash"] = cargocash.account_balance - data["bountydata"] = bountyinfo - return data - -/datum/computer_file/program/bounty/ui_act(action,params) - if(..()) - return - switch(action) - if("ClaimBounty") - var/datum/bounty/cashmoney = locate(params["bounty"]) in GLOB.bounties_list - if(cashmoney) - cashmoney.claim() - return TRUE - if("Print") - if(printer_ready < world.time) - printer_ready = world.time + PRINTER_TIMEOUT - print_paper() - return diff --git a/code/modules/modular_computers/file_system/programs/cargoship.dm b/code/modules/modular_computers/file_system/programs/cargoship.dm index 89a3b3247d..672c0de470 100644 --- a/code/modules/modular_computers/file_system/programs/cargoship.dm +++ b/code/modules/modular_computers/file_system/programs/cargoship.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/shipping filename = "shipping" filedesc = "GrandArk Exporter" + category = PROGRAM_CATEGORY_SUPL program_icon_state = "shipping" extended_desc = "A combination printer/scanner app that enables modular computers to print barcodes for easy scanning and shipping." size = 6 @@ -8,8 +9,12 @@ program_icon = "tags" ///Account used for creating barcodes. var/datum/bank_account/payments_acc - ///The amount which the tagger will receive for the sale. - var/percent_cut = 20 + ///The person who tagged this will receive the sale value multiplied by this number. + var/cut_multiplier = 0.5 + ///Maximum value for cut_multiplier. + var/cut_max = 0.5 + ///Minimum value for cut_multiplier. + var/cut_min = 0.01 /datum/computer_file/program/shipping/ui_data(mob/user) var/list/data = get_header_data() @@ -22,7 +27,7 @@ data["paperamt"] = printer ? "[printer.stored_paper] / [printer.max_paper]" : null data["card_owner"] = card_slot?.stored_card ? id_card.registered_name : "No Card Inserted." data["current_user"] = payments_acc ? payments_acc.account_holder : null - data["barcode_split"] = percent_cut + data["barcode_split"] = cut_multiplier * 100 return data /datum/computer_file/program/shipping/ui_act(action, list/params) @@ -54,20 +59,20 @@ if("resetid") payments_acc = null if("setsplit") - var/potential_cut = input("How much would you like to payout to the registered card?","Percentage Profit") as num|null - percent_cut = potential_cut ? clamp(round(potential_cut, 1), 1, 50) : 20 + var/potential_cut = input("How much would you like to pay out to the registered card?","Percentage Profit ([round(cut_min*100)]% - [round(cut_max*100)]%)") as num|null + cut_multiplier = potential_cut ? clamp(round(potential_cut/100, cut_min), cut_min, cut_max) : initial(cut_multiplier) if("print") if(!printer) - to_chat(usr, "Hardware error: A printer is required to print barcodes.") + to_chat(usr, span_notice("Hardware error: A printer is required to print barcodes.")) return if(printer.stored_paper <= 0) - to_chat(usr, "Hardware error: Printer is out of paper.") + to_chat(usr, span_notice("Hardware error: Printer is out of paper.")) return if(!payments_acc) - to_chat(usr, "Software error: Please set a current user first.") + to_chat(usr, span_notice("Software error: Please set a current user first.")) return var/obj/item/barcode/barcode = new /obj/item/barcode(get_turf(ui_host())) barcode.payments_acc = payments_acc - barcode.percent_cut = percent_cut + barcode.cut_multiplier = cut_multiplier printer.stored_paper-- - to_chat(usr, "The computer prints out a barcode.") + to_chat(usr, span_notice("The computer prints out a barcode.")) diff --git a/code/modules/modular_computers/file_system/programs/crewmanifest.dm b/code/modules/modular_computers/file_system/programs/crewmanifest.dm index debe87259d..6837f315a4 100644 --- a/code/modules/modular_computers/file_system/programs/crewmanifest.dm +++ b/code/modules/modular_computers/file_system/programs/crewmanifest.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/crew_manifest filename = "plexagoncrew" filedesc = "Plexagon Crew List" + category = PROGRAM_CATEGORY_CREW program_icon_state = "id" extended_desc = "Program for viewing and printing the current crew manifest" transfer_access = ACCESS_HEADS @@ -44,7 +45,7 @@ [GLOB.data_core ? GLOB.data_core.get_manifest() : ""] "} if(!printer.print_text(contents,text("crew manifest ([])", STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)))) - to_chat(usr, "Hardware error: Printer was unable to print the file. It may be out of paper.") + to_chat(usr, span_notice("Hardware error: Printer was unable to print the file. It may be out of paper.")) return else - computer.visible_message("\The [computer] prints out a paper.") + computer.visible_message(span_notice("\The [computer] prints out a paper.")) diff --git a/code/modules/modular_computers/file_system/programs/file_browser.dm b/code/modules/modular_computers/file_system/programs/file_browser.dm index 97a71496ea..60a9536543 100644 --- a/code/modules/modular_computers/file_system/programs/file_browser.dm +++ b/code/modules/modular_computers/file_system/programs/file_browser.dm @@ -38,14 +38,27 @@ return RHDD.remove_file(file) return TRUE - if("PRG_rename") + if("PRG_renamefile") if(!HDD) return var/datum/computer_file/file = HDD.find_file_by_name(params["name"]) if(!file) return - var/newname = params["new_name"] - if(!newname) + var/newname = reject_bad_name(params["new_name"]) + if(!newname || newname != params["new_name"]) + playsound(computer, 'sound/machines/terminal_error.ogg', 25, FALSE) + return + file.filename = newname + return TRUE + if("PRG_usbrenamefile") + if(!RHDD) + return + var/datum/computer_file/file = RHDD.find_file_by_name(params["name"]) + if(!file) + return + var/newname = reject_bad_name(params["new_name"]) + if(!newname || newname != params["new_name"]) + playsound(computer, 'sound/machines/terminal_error.ogg', 25, FALSE) return file.filename = newname return TRUE diff --git a/code/modules/modular_computers/file_system/programs/jobmanagement.dm b/code/modules/modular_computers/file_system/programs/jobmanagement.dm index 0babfcdddd..29f9a37433 100644 --- a/code/modules/modular_computers/file_system/programs/jobmanagement.dm +++ b/code/modules/modular_computers/file_system/programs/jobmanagement.dm @@ -1,6 +1,10 @@ +/// The time since the last job opening was created +// GLOBAL_VAR_INIT(time_last_changed_position, 0) + /datum/computer_file/program/job_management filename = "plexagoncore" filedesc = "Plexagon HR Core" + category = PROGRAM_CATEGORY_CREW program_icon_state = "id" extended_desc = "Program for viewing and changing job slot avalibility." transfer_access = ACCESS_HEADS @@ -14,6 +18,7 @@ var/list/blacklisted = list( "AI", "Assistant", + "Prisoner", "Cyborg", "Captain", "Head of Personnel", @@ -35,21 +40,25 @@ change_position_cooldown = CONFIG_GET(number/id_console_jobslot_delay) /datum/computer_file/program/job_management/proc/can_open_job(datum/job/job) - if(!(job?.title in blacklisted)) - if((job.total_positions <= length(GLOB.player_list) * (max_relative_positions / 100))) - var/delta = (world.time / 10) - GLOB.time_last_changed_position - if((change_position_cooldown < delta) || (opened_positions[job.title] < 0)) - return TRUE + if(job?.title in blacklisted) + return FALSE + if((job.total_positions <= length(GLOB.player_list) * (max_relative_positions / 100))) + var/delta = (world.time / 10) - GLOB.time_last_changed_position + if((change_position_cooldown < delta) || (opened_positions[job.title] < 0)) + return TRUE return FALSE + /datum/computer_file/program/job_management/proc/can_close_job(datum/job/job) - if(!(job?.title in blacklisted)) - if(job.total_positions > job.current_positions) - var/delta = (world.time / 10) - GLOB.time_last_changed_position - if((change_position_cooldown < delta) || (opened_positions[job.title] > 0)) - return TRUE + if(job?.title in blacklisted) + return FALSE + if(job.total_positions > job.current_positions) + var/delta = (world.time / 10) - GLOB.time_last_changed_position + if((change_position_cooldown < delta) || (opened_positions[job.title] > 0)) + return TRUE return FALSE + /datum/computer_file/program/job_management/ui_act(action, params, datum/tgui/ui) . = ..() if(.) @@ -68,9 +77,10 @@ if(!j || !can_open_job(j)) return if(opened_positions[edit_job_target] >= 0) - GLOB.time_last_changed_position = world.time / 10 // global cd + GLOB.time_last_changed_position = world.time / 10 j.total_positions++ opened_positions[edit_job_target]++ + log_game("[key_name(usr)] opened a [j.title] job position, for a total of [j.total_positions] open job slots.") playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) return TRUE if("PRG_close_job") @@ -83,21 +93,23 @@ GLOB.time_last_changed_position = world.time / 10 j.total_positions-- opened_positions[edit_job_target]-- + log_game("[key_name(usr)] closed a [j.title] job position, leaving [j.total_positions] open job slots.") playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) return TRUE if("PRG_priority") - if(length(SSjob.prioritized_jobs) >= 5) - return var/priority_target = params["target"] var/datum/job/j = SSjob.GetJob(priority_target) - if(!j) + if(!j || (j?.title in blacklisted)) return if(j.total_positions <= j.current_positions) return if(j in SSjob.prioritized_jobs) SSjob.prioritized_jobs -= j else - SSjob.prioritized_jobs += j + if(length(SSjob.prioritized_jobs) < 5) + SSjob.prioritized_jobs += j + else + computer.say("Error: CentCom employment protocols restrict prioritising more than 5 jobs.") playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) return TRUE diff --git a/code/modules/modular_computers/file_system/programs/ntdownloader.dm b/code/modules/modular_computers/file_system/programs/ntdownloader.dm index f3fa6df2b3..56283e3c8b 100644 --- a/code/modules/modular_computers/file_system/programs/ntdownloader.dm +++ b/code/modules/modular_computers/file_system/programs/ntdownloader.dm @@ -22,6 +22,13 @@ var/emagged = FALSE var/list/main_repo var/list/antag_repo + var/list/show_categories = list( + PROGRAM_CATEGORY_CREW, + PROGRAM_CATEGORY_ENGI, + PROGRAM_CATEGORY_ROBO, + PROGRAM_CATEGORY_SUPL, + PROGRAM_CATEGORY_MISC, + ) /datum/computer_file/program/ntnetdownload/run_program() . = ..() @@ -146,39 +153,29 @@ var/obj/item/computer_hardware/hard_drive/hard_drive = my_computer.all_components[MC_HDD] data["disk_size"] = hard_drive.max_capacity data["disk_used"] = hard_drive.used_capacity - var/list/all_entries[0] - for(var/A in main_repo) - var/datum/computer_file/program/P = A - // Only those programs our user can run will show in the list - if(hard_drive.find_file_by_name(P.filename)) - continue - all_entries.Add(list(list( + data["emagged"] = emagged + + var/list/repo = antag_repo | main_repo + var/list/program_categories = list() + + for(var/I in repo) + var/datum/computer_file/program/P = I + if(!(P.category in program_categories)) + program_categories.Add(P.category) + data["programs"] += list(list( + "icon" = P.program_icon, "filename" = P.filename, "filedesc" = P.filedesc, "fileinfo" = P.extended_desc, - "compatibility" = check_compatibility(P), + "category" = P.category, + "installed" = !!hard_drive.find_file_by_name(P.filename), + "compatible" = check_compatibility(P), "size" = P.size, - "access" = P.can_run(user,transfer = 1, access = access) - ))) - data["hackedavailable"] = FALSE - if(emagged) // If we are running on emagged computer we have access to some "bonus" software - var/list/hacked_programs[0] - for(var/S in antag_repo) - var/datum/computer_file/program/P = S - if(hard_drive.find_file_by_name(P.filename)) - continue - data["hackedavailable"] = TRUE - hacked_programs.Add(list(list( - "filename" = P.filename, - "filedesc" = P.filedesc, - "fileinfo" = P.extended_desc, - "compatibility" = check_compatibility(P), - "size" = P.size, - "access" = TRUE, - ))) - data["hacked_programs"] = hacked_programs + "access" = emagged && P.available_on_syndinet ? TRUE : P.can_run(user,transfer = 1, access = access), + "verifiedsource" = P.available_on_ntnet, + )) - data["downloadable_programs"] = all_entries + data["categories"] = show_categories & program_categories return data @@ -186,8 +183,8 @@ var/hardflag = computer.hardware_flag if(P?.is_supported_by_hardware(hardflag,0)) - return "Compatible" - return "Incompatible!" + return TRUE + return FALSE /datum/computer_file/program/ntnetdownload/kill_program(forced) abort_file_download() diff --git a/code/modules/modular_computers/file_system/programs/ntmonitor.dm b/code/modules/modular_computers/file_system/programs/ntmonitor.dm index 63f0b18a74..aeb8106040 100644 --- a/code/modules/modular_computers/file_system/programs/ntmonitor.dm +++ b/code/modules/modular_computers/file_system/programs/ntmonitor.dm @@ -1,11 +1,12 @@ /datum/computer_file/program/ntnetmonitor filename = "wirecarp" filedesc = "WireCarp" + category = PROGRAM_CATEGORY_MISC program_icon_state = "comm_monitor" extended_desc = "This program monitors stationwide NTNet network, provides access to logging systems, and allows for configuration changes" size = 12 requires_ntnet = TRUE - required_access = ACCESS_NETWORK //NETWORK CONTROL IS A MORE SECURE PROGRAM. + required_access = ACCESS_NETWORK //NETWORK CONTROL IS A MORE SECURE PROGRAM. available_on_ntnet = TRUE tgui_id = "NtosNetMonitor" program_icon = "network-wired" diff --git a/code/modules/modular_computers/file_system/programs/ntnrc_client.dm b/code/modules/modular_computers/file_system/programs/ntnrc_client.dm index 19172f130a..29a4418d2c 100644 --- a/code/modules/modular_computers/file_system/programs/ntnrc_client.dm +++ b/code/modules/modular_computers/file_system/programs/ntnrc_client.dm @@ -1,25 +1,36 @@ + /datum/computer_file/program/chatclient filename = "ntnrc_client" filedesc = "Chat Client" + category = PROGRAM_CATEGORY_MISC program_icon_state = "command" extended_desc = "This program allows communication over NTNRC network" size = 8 - requires_ntnet = 1 + requires_ntnet = TRUE requires_ntnet_feature = NTNET_COMMUNICATION ui_header = "ntnrc_idle.gif" - available_on_ntnet = 1 + available_on_ntnet = TRUE tgui_id = "NtosNetChat" program_icon = "comment-alt" - var/last_message // Used to generate the toolbar icon + alert_able = TRUE + var/last_message // Used to generate the toolbar icon var/username var/active_channel var/list/channel_history = list() - var/operator_mode = FALSE // Channel operator mode - var/netadmin_mode = FALSE // Administrator mode (invisible to other users + bypasses passwords) + var/operator_mode = FALSE // Channel operator mode + var/netadmin_mode = FALSE // Administrator mode (invisible to other users + bypasses passwords) + //A list of all the converstations we're a part of + var/list/datum/ntnet_conversation/conversations = list() /datum/computer_file/program/chatclient/New() username = "DefaultUser[rand(100, 999)]" +/datum/computer_file/program/chatclient/Destroy() + for(var/datum/ntnet_conversation/discussion as anything in conversations) + discussion.purge_client(src) + conversations.Cut() + return ..() + /datum/computer_file/program/chatclient/ui_act(action, params) . = ..() if(.) @@ -36,7 +47,7 @@ var/message = reject_bad_text(params["message"]) if(!message) return - if(channel.password && !(src in channel.clients)) + if(channel.password && (!(src in channel.active_clients) && !(src in channel.offline_clients))) if(channel.password == message) channel.add_client(src) return TRUE @@ -56,7 +67,7 @@ active_channel = new_target channel = SSnetworks.station_network.get_chat_channel_by_id(new_target) - if(!(src in channel.clients) && !channel.password) + if((!(src in channel.active_clients) && !(src in channel.offline_clients)) && !channel.password) channel.add_client(src) return TRUE if("PRG_leavechannel") @@ -89,12 +100,12 @@ return TRUE if("PRG_changename") var/newname = sanitize(params["new_name"]) - if(!newname) + newname = replacetext(newname, " ", "_") + if(!newname || newname == username) return - for(var/C in SSnetworks.station_network.chat_channels) - var/datum/ntnet_conversation/chan = C - if(src in chan.clients) - chan.add_status_message("[username] is now known as [newname].") + for(var/datum/ntnet_conversation/anychannel as anything in SSnetworks.station_network.chat_channels) + if(src in anychannel.active_clients) + anychannel.add_status_message("[username] is now known as [newname].") username = newname return TRUE if("PRG_savelog") @@ -117,9 +128,9 @@ // This program shouldn't even be runnable without computer. CRASH("Var computer is null!") if(!hard_drive) - computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive connection error\" warning.") - else // In 99.9% cases this will mean our HDD is full - computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive may be full. Please free some space and try again. Required space: [logfile.size]GQ\" warning.") + computer.visible_message(span_warning("\The [computer] shows an \"I/O Error - Hard drive connection error\" warning.")) + else // In 99.9% cases this will mean our HDD is full + computer.visible_message(span_warning("\The [computer] shows an \"I/O Error - Hard drive may be full. Please free some space and try again. Required space: [logfile.size]GQ\" warning.")) return TRUE if("PRG_renamechannel") if(!authed) @@ -145,6 +156,18 @@ channel.password = new_password return TRUE + if("PRG_mute_user") + if(!authed) + return + var/datum/computer_file/program/chatclient/muted = locate(params["ref"]) in channel.active_clients + channel.offline_clients + channel.mute_user(src, muted) + return TRUE + if("PRG_ping_user") + if(!authed) + return + var/datum/computer_file/program/chatclient/pinged = locate(params["ref"]) in channel.active_clients + channel.offline_clients + channel.ping_user(src, pinged) + return TRUE /datum/computer_file/program/chatclient/process_tick() . = ..() @@ -162,10 +185,19 @@ else ui_header = "ntnrc_idle.gif" +/datum/computer_file/program/chatclient/run_program(mob/living/user) + . = ..() + if(!.) + return + for(var/datum/ntnet_conversation/channel as anything in SSnetworks.station_network.chat_channels) + if(src in channel.offline_clients) + channel.offline_clients.Remove(src) + channel.active_clients.Add(src) + /datum/computer_file/program/chatclient/kill_program(forced = FALSE) - for(var/C in SSnetworks.station_network.chat_channels) - var/datum/ntnet_conversation/channel = C - channel.remove_client(src) + for(var/datum/ntnet_conversation/channel as anything in SSnetworks.station_network.chat_channels) + channel.go_offline(src) + active_channel = null ..() /datum/computer_file/program/chatclient/ui_static_data(mob/user) @@ -192,6 +224,7 @@ data["all_channels"] = all_channels data["active_channel"] = active_channel + data["selfref"] = REF(src) //used to verify who is you, as usernames can be copied. data["username"] = username data["adminmode"] = netadmin_mode var/datum/ntnet_conversation/channel = SSnetworks.station_network.get_chat_channel_by_id(active_channel) @@ -203,21 +236,25 @@ if(netadmin_mode) authed = TRUE var/list/clients = list() - for(var/C in channel.clients) - if(C == src) + for(var/datum/computer_file/program/chatclient/channel_client as anything in channel.active_clients + channel.offline_clients) + if(channel_client == src) authed = TRUE - var/datum/computer_file/program/chatclient/cl = C clients.Add(list(list( - "name" = cl.username + "name" = channel_client.username, + "status" = channel_client.program_state, + "muted" = (channel_client in channel.muted_clients), + "operator" = channel.operator == channel_client, + "ref" = REF(channel_client) ))) data["authed"] = authed //no fishing for ui data allowed if(authed) + data["strong"] = channel.strong data["clients"] = clients var/list/messages = list() - for(var/M in channel.messages) + for(var/message in channel.messages) messages.Add(list(list( - "msg" = M + "msg" = message ))) data["messages"] = messages data["is_operator"] = (channel.operator == src) || netadmin_mode diff --git a/code/modules/modular_computers/file_system/programs/portrait_printer.dm b/code/modules/modular_computers/file_system/programs/portrait_printer.dm new file mode 100644 index 0000000000..ac3b7e5a88 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/portrait_printer.dm @@ -0,0 +1,83 @@ + +///how much paper it takes from the printer to create a canvas. +#define CANVAS_PAPER_COST 10 + +/** + * ## portrait printer! + * + * Program that lets the curator browse all of the portraits in the database + * They are free to print them out as they please. + */ +/datum/computer_file/program/portrait_printer + filename = "PortraitPrinter" + filedesc = "Marlowe Treeby's Art Galaxy" + category = PROGRAM_CATEGORY_CREW + program_icon_state = "dummy" + extended_desc = "This program connects to a Spinward Sector community art site for viewing and printing art." + transfer_access = ACCESS_LIBRARY + usage_flags = PROGRAM_CONSOLE + requires_ntnet = TRUE + size = 9 + tgui_id = "NtosPortraitPrinter" + program_icon = "paint-brush" + +/datum/computer_file/program/portrait_printer/ui_data(mob/user) + var/list/data = list() + data["library"] = SSpersistence.paintings["library"] ? SSpersistence.paintings["library"] : 0 + data["library_secure"] = SSpersistence.paintings["library_secure"] ? SSpersistence.paintings["library_secure"] : 0 + data["library_private"] = SSpersistence.paintings["library_private"] ? SSpersistence.paintings["library_private"] : 0 //i'm gonna regret this, won't i? Yes you should. + return data + +/datum/computer_file/program/portrait_printer/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/simple/portraits/library), + get_asset_datum(/datum/asset/simple/portraits/library_secure), + get_asset_datum(/datum/asset/simple/portraits/library_private) + ) + +/datum/computer_file/program/portrait_printer/ui_act(action, params) + . = ..() + if(.) + return + + //printer check! + var/obj/item/computer_hardware/printer/printer + if(computer) + printer = computer.all_components[MC_PRINT] + if(!printer) + to_chat(usr, span_notice("Hardware error: A printer is required to print a canvas.")) + return + if(printer.stored_paper < CANVAS_PAPER_COST) + to_chat(usr, span_notice("Printing error: Your printer needs at least [CANVAS_PAPER_COST] paper to print a canvas.")) + return + printer.stored_paper -= CANVAS_PAPER_COST + + //canvas printing! + var/list/tab2key = list(TAB_LIBRARY = "library", TAB_SECURE = "library_secure", TAB_PRIVATE = "library_private") + var/folder = tab2key[params["tab"]] + var/list/current_list = SSpersistence.paintings[folder] + var/list/chosen_portrait = current_list[params["selected"]] + var/author = chosen_portrait["author"] + var/title = chosen_portrait["title"] + var/png = "data/paintings/[folder]/[chosen_portrait["md5"]].png" + var/icon/art_icon = new(png) + var/obj/item/canvas/printed_canvas + var/art_width = art_icon.Width() + var/art_height = art_icon.Height() + for(var/canvas_type in typesof(/obj/item/canvas)) + printed_canvas = canvas_type + if(initial(printed_canvas.width) == art_width && initial(printed_canvas.height) == art_height) + printed_canvas = new canvas_type(get_turf(computer.physical)) + break + printed_canvas.fill_grid_from_icon(art_icon) + printed_canvas.generated_icon = art_icon + printed_canvas.icon_generated = TRUE + printed_canvas.finalized = TRUE + printed_canvas.painting_name = title + printed_canvas.author_ckey = author + printed_canvas.name = "painting - [title]" + ///this is a copy of something that is already in the database- it should not be able to be saved. + printed_canvas.no_save = TRUE + printed_canvas.update_icon() + to_chat(usr, span_notice("You have printed [title] onto a new canvas.")) + playsound(computer.physical, 'sound/items/poster_being_created.ogg', 100, TRUE) diff --git a/code/modules/modular_computers/file_system/programs/powermonitor.dm b/code/modules/modular_computers/file_system/programs/powermonitor.dm index 78a14ff1ad..933c9410a2 100644 --- a/code/modules/modular_computers/file_system/programs/powermonitor.dm +++ b/code/modules/modular_computers/file_system/programs/powermonitor.dm @@ -3,6 +3,7 @@ /datum/computer_file/program/power_monitor filename = "ampcheck" filedesc = "AmpCheck" + category = PROGRAM_CATEGORY_ENGI program_icon_state = "power_monitor" extended_desc = "This program connects to sensors around the station to provide information about electrical systems" ui_header = "power_norm.gif" diff --git a/code/modules/modular_computers/file_system/programs/radar.dm b/code/modules/modular_computers/file_system/programs/radar.dm index 0bf5eb2118..4b14a61152 100644 --- a/code/modules/modular_computers/file_system/programs/radar.dm +++ b/code/modules/modular_computers/file_system/programs/radar.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/radar //generic parent that handles most of the process filename = "genericfinder" filedesc = "debug_finder" + category = PROGRAM_CATEGORY_CREW ui_header = "borg_mon.gif" //DEBUG -- new icon before PR program_icon_state = "radarntos" requires_ntnet = TRUE @@ -15,7 +16,7 @@ var/atom/selected ///Used to store when the next scan is available. Updated by the scan() proc. var/next_scan = 0 - ///Used to keep track of the last value program_icon_state was set to, to prevent constant unnecessary update_icon() calls + ///Used to keep track of the last value program_icon_state was set to, to prevent constant unnecessary update_appearance() calls var/last_icon_state = "" ///Used by the tgui interface, themed NT or Syndicate. var/arrowstyle = "ntosradarpointer.png" @@ -174,7 +175,7 @@ if(!trackable(signal)) program_icon_state = "[initial(program_icon_state)]lost" if(last_icon_state != program_icon_state) - computer.update_icon() + computer.update_appearance() last_icon_state = program_icon_state return @@ -192,7 +193,7 @@ program_icon_state = "[initial(program_icon_state)]far" if(last_icon_state != program_icon_state) - computer.update_icon() + computer.update_appearance() last_icon_state = program_icon_state computer.setDir(get_dir(here_turf, target_turf)) @@ -241,13 +242,12 @@ /datum/computer_file/program/radar/lifeline/trackable(mob/living/carbon/human/humanoid) if(!humanoid || !istype(humanoid)) return FALSE - if(..() && istype(humanoid.w_uniform, /obj/item/clothing/under)) - - var/obj/item/clothing/under/uniform = humanoid.w_uniform - if(!uniform.has_sensor || (uniform.sensor_mode < SENSOR_COORDS)) // Suit sensors must be on maximum. - return FALSE - - return TRUE + if(..()) + if (istype(humanoid.w_uniform, /obj/item/clothing/under)) + var/obj/item/clothing/under/uniform = humanoid.w_uniform + if(uniform.has_sensor && uniform.sensor_mode >= SENSOR_COORDS) // Suit sensors must be on maximum + return TRUE + return FALSE //////////////////////// //Nuke Disk Finder App// @@ -257,6 +257,7 @@ /datum/computer_file/program/radar/fission360 filename = "fission360" filedesc = "Fission360" + category = PROGRAM_CATEGORY_MISC program_icon_state = "radarsyndicate" extended_desc = "This program allows for tracking of nuclear authorization disks and warheads." requires_ntnet = FALSE diff --git a/code/modules/modular_computers/file_system/programs/robocontrol.dm b/code/modules/modular_computers/file_system/programs/robocontrol.dm index 8c41ea6c38..7fe5a09ab2 100644 --- a/code/modules/modular_computers/file_system/programs/robocontrol.dm +++ b/code/modules/modular_computers/file_system/programs/robocontrol.dm @@ -2,6 +2,7 @@ /datum/computer_file/program/robocontrol filename = "botkeeper" filedesc = "BotKeeper" + category = PROGRAM_CATEGORY_ROBO program_icon_state = "robot" extended_desc = "A remote controller used for giving basic commands to non-sentient robots." transfer_access = null diff --git a/code/modules/modular_computers/file_system/programs/robotact.dm b/code/modules/modular_computers/file_system/programs/robotact.dm index b25332d027..d4dce42204 100644 --- a/code/modules/modular_computers/file_system/programs/robotact.dm +++ b/code/modules/modular_computers/file_system/programs/robotact.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/robotact filename = "robotact" filedesc = "RoboTact" + category = PROGRAM_CATEGORY_ROBO extended_desc = "A built-in app for cyborg self-management and diagnostics." ui_header = "robotact.gif" //DEBUG -- new icon before PR program_icon_state = "command" @@ -22,7 +23,7 @@ /datum/computer_file/program/robotact/run_program(mob/living/user) if(!istype(computer, /obj/item/modular_computer/tablet/integrated)) - to_chat(user, "A warning flashes across \the [computer]: Device Incompatible.") + to_chat(user, span_warning("A warning flashes across \the [computer]: Device Incompatible.")) return FALSE . = ..() if(.) @@ -39,7 +40,7 @@ var/mob/living/silicon/robot/borgo = tablet.borgo data["name"] = borgo.name - data["designation"] = borgo.designation //Borgo module type + data["designation"] = borgo.designation //Borgo model type data["masterAI"] = borgo.connected_ai //Master AI var/charge = 0 @@ -62,7 +63,7 @@ data["cover"] = "[borgo.locked? "LOCKED":"UNLOCKED"]" //Ability to move. FAULT if lockdown wire is cut, DISABLED if borg locked, ENABLED otherwise data["locomotion"] = "[borgo.wires.is_cut(WIRE_LOCKDOWN)?"FAULT":"[borgo.locked_down?"DISABLED":"ENABLED"]"]" - //Module wire. FAULT if cut, NOMINAL otherwise + //Model wire. FAULT if cut, NOMINAL otherwise data["wireModule"] = "[borgo.wires.is_cut(WIRE_RESET_MODULE)?"FAULT":"NOMINAL"]" //DEBUG -- Camera(net) wire. FAULT if cut (or no cameranet camera), DISABLED if pulse-disabled, NOMINAL otherwise data["wireCamera"] = "[!borgo.builtInCamera || borgo.wires.is_cut(WIRE_CAMERA)?"FAULT":"[borgo.builtInCamera.can_use()?"NOMINAL":"DISABLED"]"]" @@ -110,7 +111,7 @@ if("alertPower") if(borgo.stat == CONSCIOUS) if(!borgo.cell || !borgo.cell.charge) - borgo.visible_message("The power warning light on [borgo] flashes urgently.", \ + borgo.visible_message(span_notice("The power warning light on [span_name("[borgo]")] flashes urgently."), \ "You announce you are operating in low power mode.") playsound(borgo, 'sound/machines/buzz-two.ogg', 50, FALSE) diff --git a/code/modules/modular_computers/file_system/programs/secureye.dm b/code/modules/modular_computers/file_system/programs/secureye.dm index 92275b1e8b..d2d7590cb1 100644 --- a/code/modules/modular_computers/file_system/programs/secureye.dm +++ b/code/modules/modular_computers/file_system/programs/secureye.dm @@ -3,6 +3,7 @@ /datum/computer_file/program/secureye filename = "secureye" filedesc = "SecurEye" + category = PROGRAM_CATEGORY_MISC ui_header = "borg_mon.gif" program_icon_state = "generic" extended_desc = "This program allows access to standard security camera networks." diff --git a/code/modules/modular_computers/file_system/programs/signaler.dm b/code/modules/modular_computers/file_system/programs/signaler.dm new file mode 100644 index 0000000000..dfbef9f6d6 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/signaler.dm @@ -0,0 +1,75 @@ +/datum/computer_file/program/signaler + filename = "signaler" + filedesc = "SignalCommander" + category = PROGRAM_CATEGORY_MISC + program_icon_state = "signal" + extended_desc = "A small built-in frequency app that sends out signaller signals with the appropriate hardware." + size = 2 + tgui_id = "NtosSignaler" + program_icon = "satellite-dish" + usage_flags = PROGRAM_TABLET | PROGRAM_LAPTOP + ///What is the saved signal frequency? + var/signal_frequency = FREQ_SIGNALER + /// What is the saved signal code? + var/signal_code = DEFAULT_SIGNALER_CODE + /// Radio connection datum used by signalers. + var/datum/radio_frequency/radio_connection + +/datum/computer_file/program/signaler/New() + set_frequency(signal_frequency) + return ..() + +/datum/computer_file/program/signaler/ui_data(mob/user) + var/list/data = get_header_data() + data["frequency"] = signal_frequency + data["code"] = signal_code + data["minFrequency"] = MIN_FREE_FREQ + data["maxFrequency"] = MAX_FREE_FREQ + return data + +/datum/computer_file/program/signaler/ui_act(action, list/params) + . = ..() + if(.) + return + switch(action) + if("signal") + INVOKE_ASYNC(src, .proc/signal) + . = TRUE + if("freq") + var/new_signal_frequency = sanitize_frequency(unformat_frequency(params["freq"]), TRUE) + set_frequency(new_signal_frequency) + . = TRUE + if("code") + signal_code = text2num(params["code"]) + signal_code = round(signal_code) + . = TRUE + if("reset") + if(params["reset"] == "freq") + signal_frequency = initial(signal_frequency) + else + signal_code = initial(signal_code) + . = TRUE + +/datum/computer_file/program/signaler/proc/signal() + if(!radio_connection) + return + + var/time = time2text(world.realtime,"hh:mm:ss") + var/turf/T = get_turf(src) + + if(!istype(T)) + T = get_turf(usr) + + var/logging_data + if(usr && T) + logging_data = "[time] : [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(signal_frequency)]/[signal_code]" + GLOB.lastsignalers.Add(logging_data) + + var/datum/signal/signal = new(list("code" = signal_code), logging_data = logging_data) + radio_connection.post_signal(src, signal) + +/datum/computer_file/program/signaler/proc/set_frequency(new_frequency) + SSradio.remove_object(src, signal_frequency) + signal_frequency = new_frequency + radio_connection = SSradio.add_object(src, signal_frequency, RADIO_SIGNALER) + return diff --git a/code/modules/modular_computers/file_system/programs/sm_monitor.dm b/code/modules/modular_computers/file_system/programs/sm_monitor.dm index 6c9ce59c72..9038c71a88 100644 --- a/code/modules/modular_computers/file_system/programs/sm_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/sm_monitor.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/supermatter_monitor filename = "ntcims" filedesc = "NT CIMS" + category = PROGRAM_CATEGORY_ENGI ui_header = "smmon_0.gif" program_icon_state = "smmon_0" extended_desc = "Crystal Integrity Monitoring System, connects to specially calibrated supermatter sensors to provide information on the status of supermatter-based engines." @@ -12,7 +13,7 @@ alert_able = TRUE var/last_status = SUPERMATTER_INACTIVE var/list/supermatters - var/obj/machinery/power/supermatter_crystal/active // Currently selected supermatter crystal. + var/obj/machinery/power/supermatter_crystal/active // Currently selected supermatter crystal. /datum/computer_file/program/supermatter_monitor/Destroy() clear_signals() @@ -27,7 +28,7 @@ ui_header = "smmon_[last_status].gif" program_icon_state = "smmon_[last_status]" if(istype(computer)) - computer.update_icon() + computer.update_appearance() /datum/computer_file/program/supermatter_monitor/run_program(mob/living/user) . = ..(user) @@ -36,11 +37,15 @@ refresh() /datum/computer_file/program/supermatter_monitor/kill_program(forced = FALSE) + for(var/supermatter in supermatters) + clear_supermatter(supermatter) supermatters = null ..() // Refreshes list of active supermatter crystals /datum/computer_file/program/supermatter_monitor/proc/refresh() + for(var/supermatter in supermatters) + clear_supermatter(supermatter) supermatters = list() var/turf/T = get_turf(ui_host()) if(!T) @@ -50,9 +55,7 @@ if (!isturf(S.loc) || !(is_station_level(S.z) || is_mining_level(S.z) || S.z == T.z)) continue supermatters.Add(S) - - if(!(active in supermatters)) - active = null + RegisterSignal(S, COMSIG_PARENT_QDELETING, .proc/react_to_del) /datum/computer_file/program/supermatter_monitor/proc/get_status() . = SUPERMATTER_INACTIVE @@ -67,9 +70,9 @@ * the signal and exit. */ /datum/computer_file/program/supermatter_monitor/proc/set_signals() - // if(active) - // RegisterSignal(active, COMSIG_SUPERMATTER_DELAM_ALARM, .proc/send_alert, override = TRUE) - // RegisterSignal(active, COMSIG_SUPERMATTER_DELAM_START_ALARM, .proc/send_start_alert, override = TRUE) + if(active) + RegisterSignal(active, COMSIG_SUPERMATTER_DELAM_ALARM, .proc/send_alert, override = TRUE) + RegisterSignal(active, COMSIG_SUPERMATTER_DELAM_START_ALARM, .proc/send_start_alert, override = TRUE) /** * Removes the signal listener for Supermatter delaminations from the selected supermatter. @@ -77,9 +80,9 @@ * Pretty much does what it says. */ /datum/computer_file/program/supermatter_monitor/proc/clear_signals() - // if(active) - // UnregisterSignal(active, COMSIG_SUPERMATTER_DELAM_ALARM) - // UnregisterSignal(active, COMSIG_SUPERMATTER_DELAM_START_ALARM) + if(active) + UnregisterSignal(active, COMSIG_SUPERMATTER_DELAM_ALARM) + UnregisterSignal(active, COMSIG_SUPERMATTER_DELAM_START_ALARM) /** * Sends an SM delam alert to the computer. @@ -90,6 +93,7 @@ * the supermatter probably don't need constant beeping to distract them. */ /datum/computer_file/program/supermatter_monitor/proc/send_alert() + SIGNAL_HANDLER if(!computer.get_ntnet_status()) return if(computer.active_program != src) @@ -106,12 +110,13 @@ * minimized or closed to avoid double-notifications. */ /datum/computer_file/program/supermatter_monitor/proc/send_start_alert() + SIGNAL_HANDLER if(!computer.get_ntnet_status()) return if(computer.active_program == src) computer.alert_call(src, "Crystal delamination in progress!") -/datum/computer_file/program/supermatter_monitor/ui_data() +/datum/computer_file/program/supermatter_monitor/ui_data(mob/user) var/list/data = get_header_data() if(istype(active)) @@ -125,30 +130,9 @@ active = null return - data["active"] = TRUE - data["SM_integrity"] = active.get_integrity() - data["SM_power"] = active.power - data["SM_ambienttemp"] = air.return_temperature() - data["SM_ambientpressure"] = air.return_pressure() - //data["SM_EPR"] = round((air.total_moles / air.group_multiplier) / 23.1, 0.01) - var/list/gasdata = list() + data += active.ui_data() + data["singlecrystal"] = FALSE - - if(air.total_moles()) - for(var/gasid in air.get_gases()) - var/amount = air.get_moles(gasid) - if(amount) - gasdata.Add(list(list( - "name"= GLOB.gas_data.names[gasid], - "amount" = round(100*amount/air.total_moles(),0.01)))) - - else - for(var/gasid in air.get_gases()) - gasdata.Add(list(list( - "name"= GLOB.gas_data.names[gasid], - "amount" = 0))) - - data["gases"] = gasdata else var/list/SMS = list() for(var/obj/machinery/power/supermatter_crystal/S in supermatters) @@ -185,3 +169,13 @@ active = S set_signals() return TRUE + +/datum/computer_file/program/supermatter_monitor/proc/react_to_del(datum/source) + SIGNAL_HANDLER + clear_supermatter(source) + +/datum/computer_file/program/supermatter_monitor/proc/clear_supermatter(matter) + supermatters -= matter + if(matter == active) + active = null + UnregisterSignal(matter, COMSIG_PARENT_QDELETING) diff --git a/code/modules/modular_computers/hardware/_hardware.dm b/code/modules/modular_computers/hardware/_hardware.dm index 0ccb9f6b96..b1a44c4cc5 100644 --- a/code/modules/modular_computers/hardware/_hardware.dm +++ b/code/modules/modular_computers/hardware/_hardware.dm @@ -4,22 +4,34 @@ icon = 'icons/obj/module.dmi' icon_state = "std_mod" - w_class = WEIGHT_CLASS_TINY // w_class limits which devices can contain this component. + w_class = WEIGHT_CLASS_TINY // w_class limits which devices can contain this component. // 1: PDAs/Tablets, 2: Laptops, 3-4: Consoles only var/obj/item/modular_computer/holder = null // Computer that holds this hardware, if any. - var/power_usage = 0 // If the hardware uses extra power, change this. - var/enabled = TRUE // If the hardware is turned off set this to 0. - var/critical = FALSE // Prevent disabling for important component, like the CPU. - var/can_install = TRUE // Prevents direct installation of removable media. - var/expansion_hw = FALSE // Hardware that fits into expansion bays. - var/removable = TRUE // Whether the hardware is removable or not. - var/damage = 0 // Current damage level - var/max_damage = 100 // Maximal damage level. - var/damage_malfunction = 20 // "Malfunction" threshold. When damage exceeds this value the hardware piece will semi-randomly fail and do !!FUN!! things - var/damage_failure = 50 // "Failure" threshold. When damage exceeds this value the hardware piece will not work at all. - var/malfunction_probability = 10// Chance of malfunction when the component is damaged + // If the hardware uses extra power, change this. + var/power_usage = 0 + // If the hardware is turned off set this to 0. + var/enabled = TRUE + // Prevent disabling for important component, like the CPU. + var/critical = FALSE + // Prevents direct installation of removable media. + var/can_install = TRUE + // Hardware that fits into expansion bays. + var/expansion_hw = FALSE + // Whether the hardware is removable or not. + var/removable = TRUE + // Current damage level + var/damage = 0 +// Maximal damage level. + var/max_damage = 100 + // "Malfunction" threshold. When damage exceeds this value the hardware piece will semi-randomly fail and do !!FUN!! things + var/damage_malfunction = 20 + // "Failure" threshold. When damage exceeds this value the hardware piece will not work at all. + var/damage_failure = 50 + // Chance of malfunction when the component is damaged + var/malfunction_probability = 10 + // What define is used to qualify this piece of hardware? Important for upgraded versions of the same hardware. var/device_type /obj/item/computer_hardware/New(obj/L) @@ -38,10 +50,10 @@ if(istype(I, /obj/item/stack/cable_coil)) var/obj/item/stack/S = I if(obj_integrity == max_integrity) - to_chat(user, "\The [src] doesn't seem to require repairs.") + to_chat(user, span_warning("\The [src] doesn't seem to require repairs.")) return 1 if(S.use(1)) - to_chat(user, "You patch up \the [src] with a bit of \the [I].") + to_chat(user, span_notice("You patch up \the [src] with a bit of \the [I].")) obj_integrity = min(obj_integrity + 10, max_integrity) return 1 @@ -78,11 +90,11 @@ /obj/item/computer_hardware/examine(mob/user) . = ..() if(damage > damage_failure) - . += "It seems to be severely damaged!" + . += span_danger("It seems to be severely damaged!") else if(damage > damage_malfunction) - . += "It seems to be damaged!" + . += span_warning("It seems to be damaged!") else if(damage) - . += "It seems to be slightly damaged." + . += span_notice("It seems to be slightly damaged.") // Component-side compatibility check. /obj/item/computer_hardware/proc/can_install(obj/item/modular_computer/M, mob/living/user = null) @@ -93,8 +105,9 @@ return // Called when component is removed from PC. -/obj/item/computer_hardware/proc/on_remove(obj/item/modular_computer/M, mob/living/user = null) - try_eject(forced = TRUE) +/obj/item/computer_hardware/proc/on_remove(obj/item/modular_computer/M, mob/living/user) + if(M.physical || !QDELETED(M)) + try_eject(forced = TRUE) // Called when someone tries to insert something in it - paper in printer, card in card reader, etc. /obj/item/computer_hardware/proc/try_insert(obj/item/I, mob/living/user = null) diff --git a/code/modules/modular_computers/hardware/ai_slot.dm b/code/modules/modular_computers/hardware/ai_slot.dm index 5d42747308..8740b59b35 100644 --- a/code/modules/modular_computers/hardware/ai_slot.dm +++ b/code/modules/modular_computers/hardware/ai_slot.dm @@ -7,13 +7,14 @@ device_type = MC_AI expansion_hw = TRUE - var/obj/item/aicard/stored_card = null + var/obj/item/aicard/stored_card var/locked = FALSE -/obj/item/computer_hardware/ai_slot/handle_atom_del(atom/A) - if(A == stored_card) - try_eject(forced = TRUE) - . = ..() +///What happens when the intellicard is removed (or deleted) from the module, through try_eject() or not. +/obj/item/computer_hardware/ai_slot/Exited(atom/movable/gone, direction) + if(stored_card == gone) + stored_card = null + return ..() /obj/item/computer_hardware/ai_slot/examine(mob/user) . = ..() @@ -28,34 +29,33 @@ return FALSE if(stored_card) - to_chat(user, "You try to insert \the [I] into \the [src], but the slot is occupied.") + to_chat(user, span_warning("You try to insert \the [I] into \the [src], but the slot is occupied.")) return FALSE if(user && !user.transferItemToLoc(I, src)) return FALSE stored_card = I - to_chat(user, "You insert \the [I] into \the [src].") + to_chat(user, span_notice("You insert \the [I] into \the [src].")) return TRUE /obj/item/computer_hardware/ai_slot/try_eject(mob/living/user = null, forced = FALSE) if(!stored_card) - to_chat(user, "There is no card in \the [src].") + to_chat(user, span_warning("There is no card in \the [src].")) return FALSE if(locked && !forced) - to_chat(user, "Safeties prevent you from removing the card until reconstruction is complete...") + to_chat(user, span_warning("Safeties prevent you from removing the card until reconstruction is complete...")) return FALSE if(stored_card) - to_chat(user, "You remove [stored_card] from [src].") + to_chat(user, span_notice("You remove [stored_card] from [src].")) locked = FALSE - if(user) + if(Adjacent(user)) user.put_in_hands(stored_card) else stored_card.forceMove(drop_location()) - stored_card = null return TRUE return FALSE @@ -64,6 +64,6 @@ if(..()) return if(I.tool_behaviour == TOOL_SCREWDRIVER) - to_chat(user, "You press down on the manual eject button with \the [I].") + to_chat(user, span_notice("You press down on the manual eject button with \the [I].")) try_eject(user, TRUE) return diff --git a/code/modules/modular_computers/hardware/battery_module.dm b/code/modules/modular_computers/hardware/battery_module.dm index 0668248315..27d3546ca2 100644 --- a/code/modules/modular_computers/hardware/battery_module.dm +++ b/code/modules/modular_computers/hardware/battery_module.dm @@ -4,25 +4,28 @@ icon_state = "cell_con" critical = 1 malfunction_probability = 1 - var/obj/item/stock_parts/cell/battery = null + var/obj/item/stock_parts/cell/battery device_type = MC_CELL /obj/item/computer_hardware/battery/get_cell() return battery -/obj/item/computer_hardware/battery/New(loc, battery_type = null) +/obj/item/computer_hardware/battery/Initialize(mapload, battery_type) + . = ..() if(battery_type) battery = new battery_type(src) - ..() /obj/item/computer_hardware/battery/Destroy() - . = ..() - QDEL_NULL(battery) + battery = null + return ..() -/obj/item/computer_hardware/battery/handle_atom_del(atom/A) - if(A == battery) - try_eject(forced = TRUE) - . = ..() +///What happens when the battery is removed (or deleted) from the module, through try_eject() or not. +/obj/item/computer_hardware/battery/Exited(atom/movable/gone, direction) + if(battery == gone) + battery = null + if(holder?.enabled && !holder.use_power()) + holder.shutdown_computer() + return ..() /obj/item/computer_hardware/battery/try_insert(obj/item/I, mob/living/user = null) if(!holder) @@ -32,46 +35,33 @@ return FALSE if(battery) - to_chat(user, "You try to connect \the [I] to \the [src], but its connectors are occupied.") + to_chat(user, span_warning("You try to connect \the [I] to \the [src], but its connectors are occupied.")) return FALSE if(I.w_class > holder.max_hardware_size) - to_chat(user, "This power cell is too large for \the [holder]!") + to_chat(user, span_warning("This power cell is too large for \the [holder]!")) return FALSE if(user && !user.transferItemToLoc(I, src)) return FALSE battery = I - to_chat(user, "You connect \the [I] to \the [src].") + to_chat(user, span_notice("You connect \the [I] to \the [src].")) return TRUE - -/obj/item/computer_hardware/battery/try_eject(mob/living/user = null, forced = FALSE) +/obj/item/computer_hardware/battery/try_eject(mob/living/user, forced = FALSE) if(!battery) - to_chat(user, "There is no power cell connected to \the [src].") + to_chat(user, span_warning("There is no power cell connected to \the [src].")) return FALSE else if(user) user.put_in_hands(battery) + to_chat(user, span_notice("You detach \the [battery] from \the [src].")) else battery.forceMove(drop_location()) - to_chat(user, "You detach \the [battery] from \the [src].") - battery = null - - if(holder) - if(holder.enabled && !holder.use_power()) - holder.shutdown_computer() - return TRUE - - - - - - /obj/item/stock_parts/cell/computer name = "standard battery" desc = "A standard power cell, commonly seen in high-end portable microcomputers or low-end laptops." @@ -80,7 +70,6 @@ w_class = WEIGHT_CLASS_TINY maxcharge = 750 - /obj/item/stock_parts/cell/computer/advanced name = "advanced battery" desc = "An advanced power cell, often used in most laptops. It is too large to be fitted into smaller devices." diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm index 9139eee0b0..13f1b3bbc9 100644 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -1,17 +1,31 @@ /obj/item/computer_hardware/card_slot - name = "primary RFID card module" // \improper breaks the find_hardware_by_name proc + name = "primary RFID card module" // \improper breaks the find_hardware_by_name proc desc = "A module allowing this computer to read or write data on ID cards. Necessary for some programs to run properly." power_usage = 10 //W icon_state = "card_mini" w_class = WEIGHT_CLASS_TINY device_type = MC_CARD - var/obj/item/card/id/stored_card = null + var/obj/item/card/id/stored_card -/obj/item/computer_hardware/card_slot/handle_atom_del(atom/A) - if(A == stored_card) - try_eject(null, TRUE) - . = ..() +///What happens when the ID card is removed (or deleted) from the module, through try_eject() or not. +/obj/item/computer_hardware/card_slot/Exited(atom/movable/gone, direction) + if(stored_card == gone) + stored_card = null + if(holder) + if(holder.active_program) + holder.active_program.event_idremoved(0) + for(var/p in holder.idle_threads) + var/datum/computer_file/program/computer_program = p + computer_program.event_idremoved(1) + + holder.update_slot_icon() + + if(ishuman(holder.loc)) + var/mob/living/carbon/human/human_wearer = holder.loc + if(human_wearer.wear_id == holder) + human_wearer.sec_hud_set_ID() + return ..() /obj/item/computer_hardware/card_slot/Destroy() try_eject(forced = TRUE) @@ -47,6 +61,11 @@ if(stored_card) return FALSE + + // item instead of player is checked so telekinesis will still work if the item itself is close + if(!in_range(src, I)) + return FALSE + if(user) if(!user.transferItemToLoc(I, src)) return FALSE @@ -54,38 +73,32 @@ I.forceMove(src) stored_card = I - to_chat(user, "You insert \the [I] into \the [expansion_hw ? "secondary":"primary"] [src].") + to_chat(user, span_notice("You insert \the [I] into \the [expansion_hw ? "secondary":"primary"] [src].")) playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.sec_hud_set_ID() + + var/holder_loc = holder.loc + if(ishuman(holder_loc)) + var/mob/living/carbon/human/human_wearer = holder_loc + if(human_wearer.wear_id == holder) + human_wearer.sec_hud_set_ID() + holder.update_slot_icon() return TRUE /obj/item/computer_hardware/card_slot/try_eject(mob/living/user = null, forced = FALSE) if(!stored_card) - to_chat(user, "There are no cards in \the [src].") + to_chat(user, span_warning("There are no cards in \the [src].")) return FALSE - if(user) + if(user && !issilicon(user) && in_range(src, user)) user.put_in_hands(stored_card) else stored_card.forceMove(drop_location()) - stored_card = null - if(holder) - if(holder.active_program) - holder.active_program.event_idremoved(0) - - for(var/p in holder.idle_threads) - var/datum/computer_file/program/computer_program = p - computer_program.event_idremoved(1) - if(ishuman(user)) - var/mob/living/carbon/human/human_user = user - human_user.sec_hud_set_ID() - to_chat(user, "You remove the card from \the [src].") + to_chat(user, span_notice("You remove the card from \the [src].")) playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + return TRUE /obj/item/computer_hardware/card_slot/attackby(obj/item/I, mob/living/user) @@ -93,11 +106,11 @@ return if(I.tool_behaviour == TOOL_SCREWDRIVER) if(stored_card) - to_chat(user, "You press down on the manual eject button with \the [I].") + to_chat(user, span_notice("You press down on the manual eject button with \the [I].")) try_eject(user) return swap_slot() - to_chat(user, "You adjust the connecter to fit into [expansion_hw ? "an expansion bay" : "the primary ID bay"].") + to_chat(user, span_notice("You adjust the connecter to fit into [expansion_hw ? "an expansion bay" : "the primary ID bay"].")) /** *Swaps the card_slot hardware between using the dedicated card slot bay on a computer, and using an expansion bay. diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm index 8debb00c19..b0bf605f9a 100644 --- a/code/modules/modular_computers/hardware/hard_drive.dm +++ b/code/modules/modular_computers/hardware/hard_drive.dm @@ -8,19 +8,19 @@ device_type = MC_HDD var/max_capacity = 128 var/used_capacity = 0 - var/list/stored_files = list() // List of stored files on this drive. DO NOT MODIFY DIRECTLY! + var/list/stored_files = list() // List of stored files on this drive. DO NOT MODIFY DIRECTLY! /obj/item/computer_hardware/hard_drive/on_remove(obj/item/modular_computer/MC, mob/user) MC.shutdown_computer() /obj/item/computer_hardware/hard_drive/proc/install_default_programs() - store_file(new/datum/computer_file/program/computerconfig(src)) // Computer configuration utility, allows hardware control and displays more info than status bar - store_file(new/datum/computer_file/program/ntnetdownload(src)) // NTNet Downloader Utility, allows users to download more software from NTNet repository - store_file(new/datum/computer_file/program/filemanager(src)) // File manager, allows text editor functions and basic file manipulation. + store_file(new/datum/computer_file/program/computerconfig(src)) // Computer configuration utility, allows hardware control and displays more info than status bar + store_file(new/datum/computer_file/program/ntnetdownload(src)) // NTNet Downloader Utility, allows users to download more software from NTNet repository + store_file(new/datum/computer_file/program/filemanager(src)) // File manager, allows text editor functions and basic file manipulation. /obj/item/computer_hardware/hard_drive/examine(user) . = ..() - . += "It has [max_capacity] GQ of storage capacity." + . += span_notice("It has [max_capacity] GQ of storage capacity.") /obj/item/computer_hardware/hard_drive/diagnostics(mob/user) ..() @@ -117,10 +117,10 @@ return null /obj/item/computer_hardware/hard_drive/Destroy() - stored_files = null + QDEL_LIST(stored_files) return ..() -/obj/item/computer_hardware/hard_drive/Initialize() +/obj/item/computer_hardware/hard_drive/Initialize(mapload) . = ..() install_default_programs() @@ -129,7 +129,7 @@ name = "advanced hard disk drive" desc = "A hybrid HDD, for use in higher grade computers where balance between power efficiency and capacity is desired." max_capacity = 256 - power_usage = 50 // Hybrid, medium capacity and medium power storage + power_usage = 50 // Hybrid, medium capacity and medium power storage icon_state = "harddisk_mini" w_class = WEIGHT_CLASS_SMALL @@ -137,7 +137,7 @@ name = "super hard disk drive" desc = "A high capacity HDD, for use in cluster storage solutions where capacity is more important than power efficiency." max_capacity = 512 - power_usage = 100 // High-capacity but uses lots of power, shortening battery life. Best used with APC link. + power_usage = 100 // High-capacity but uses lots of power, shortening battery life. Best used with APC link. icon_state = "harddisk_mini" w_class = WEIGHT_CLASS_SMALL @@ -161,8 +161,8 @@ // For borg integrated tablets. No downloader. /obj/item/computer_hardware/hard_drive/small/integrated/install_default_programs() - store_file(new /datum/computer_file/program/computerconfig(src)) // Computer configuration utility, allows hardware control and displays more info than status bar - store_file(new /datum/computer_file/program/filemanager(src)) // File manager, allows text editor functions and basic file manipulation. + store_file(new /datum/computer_file/program/computerconfig(src)) // Computer configuration utility, allows hardware control and displays more info than status bar + store_file(new /datum/computer_file/program/filemanager(src)) // File manager, allows text editor functions and basic file manipulation. store_file(new /datum/computer_file/program/robotact(src)) diff --git a/code/modules/modular_computers/hardware/network_card.dm b/code/modules/modular_computers/hardware/network_card.dm index 625ead6ed7..074e158dbf 100644 --- a/code/modules/modular_computers/hardware/network_card.dm +++ b/code/modules/modular_computers/hardware/network_card.dm @@ -3,8 +3,9 @@ desc = "A basic wireless network card for usage with standard NTNet frequencies." power_usage = 50 icon_state = "radio_mini" - var/identification_id = null // Identification ID. Technically MAC address of this device. Can't be changed by user. - var/identification_string = "" // Identification string, technically nickname seen in the network. Can be set by user. + // network_id = NETWORK_CARDS // Network we are on + var/hardware_id = null // Identification ID. Technically MAC address of this device. Can't be changed by user. + var/identification_string = "" // Identification string, technically nickname seen in the network. Can be set by user. var/long_range = 0 var/ethernet = 0 // Hard-wired, therefore always on, ignores NTNet wireless checks. malfunction_probability = 1 @@ -13,7 +14,7 @@ /obj/item/computer_hardware/network_card/diagnostics(mob/user) ..() - to_chat(user, "NIX Unique ID: [identification_id]") + to_chat(user, "NIX Unique ID: [hardware_id]") to_chat(user, "NIX User Tag: [identification_string]") to_chat(user, "Supported protocols:") to_chat(user, "511.m SFS (Subspace) - Standard Frequency Spread") @@ -24,11 +25,11 @@ /obj/item/computer_hardware/network_card/New(l) ..() - identification_id = ntnet_card_uid++ + hardware_id = ntnet_card_uid++ // Returns a string identifier of this network card /obj/item/computer_hardware/network_card/proc/get_network_tag() - return "[identification_string] (NID [identification_id])" + return "[identification_string] (NID [hardware_id])" // 0 - No signal, 1 - Low signal, 2 - High signal. 3 - Wired Connection /obj/item/computer_hardware/network_card/proc/get_signal(specific_action = 0) diff --git a/code/modules/modular_computers/hardware/printer.dm b/code/modules/modular_computers/hardware/printer.dm index 3bd5946435..99756e3dd8 100644 --- a/code/modules/modular_computers/hardware/printer.dm +++ b/code/modules/modular_computers/hardware/printer.dm @@ -11,11 +11,11 @@ /obj/item/computer_hardware/printer/diagnostics(mob/living/user) ..() - to_chat(user, "Paper level: [stored_paper]/[max_paper].") + to_chat(user, span_notice("Paper level: [stored_paper]/[max_paper].")) /obj/item/computer_hardware/printer/examine(mob/user) . = ..() - . += "Paper level: [stored_paper]/[max_paper]." + . += span_notice("Paper level: [stored_paper]/[max_paper].") /obj/item/computer_hardware/printer/proc/print_text(text_to_print, paper_title = "") @@ -33,7 +33,7 @@ P.info = text_to_print if(paper_title) P.name = paper_title - P.update_icon() + P.update_appearance() stored_paper-- P = null return TRUE @@ -41,12 +41,12 @@ /obj/item/computer_hardware/printer/try_insert(obj/item/I, mob/living/user = null) if(istype(I, /obj/item/paper)) if(stored_paper >= max_paper) - to_chat(user, "You try to add \the [I] into [src], but its paper bin is full!") + to_chat(user, span_warning("You try to add \the [I] into [src], but its paper bin is full!")) return FALSE if(user && !user.temporarilyRemoveItemFromInventory(I)) return FALSE - to_chat(user, "You insert \the [I] into [src]'s paper recycler.") + to_chat(user, span_notice("You insert \the [I] into [src]'s paper recycler.")) qdel(I) stored_paper++ return TRUE diff --git a/code/modules/modular_computers/hardware/recharger.dm b/code/modules/modular_computers/hardware/recharger.dm index ecfbf4c6b2..e8c479db47 100644 --- a/code/modules/modular_computers/hardware/recharger.dm +++ b/code/modules/modular_computers/hardware/recharger.dm @@ -55,7 +55,7 @@ /obj/item/computer_hardware/recharger/wired/can_install(obj/item/modular_computer/M, mob/living/user = null) if(ismachinery(M.physical) && M.physical.anchored) return ..() - to_chat(user, "\The [src] is incompatible with portable computers!") + to_chat(user, span_warning("\The [src] is incompatible with portable computers!")) return FALSE /obj/item/computer_hardware/recharger/wired/use_power(amount, charging=0) @@ -96,3 +96,4 @@ /obj/item/computer_hardware/recharger/lambda/use_power(amount, charging=0) return 1 + diff --git a/code/modules/modular_computers/hardware/sensor_package.dm b/code/modules/modular_computers/hardware/sensor_package.dm index c0363bc809..0579b752fb 100644 --- a/code/modules/modular_computers/hardware/sensor_package.dm +++ b/code/modules/modular_computers/hardware/sensor_package.dm @@ -6,3 +6,12 @@ w_class = WEIGHT_CLASS_TINY device_type = MC_SENSORS expansion_hw = TRUE + +/obj/item/computer_hardware/radio_card + name = "integrated radio card" + desc = "An integrated signaling assembly for computers to send an outgoing frequency signal. Required by certain programs." + icon_state = "signal_card" + w_class = WEIGHT_CLASS_TINY + device_type = MC_SIGNALER + expansion_hw = TRUE + power_usage = 10 diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm index 0811983088..4a268c2911 100644 --- a/code/modules/modular_computers/laptop_vendor.dm +++ b/code/modules/modular_computers/laptop_vendor.dm @@ -13,19 +13,19 @@ var/obj/item/modular_computer/tablet/fabricated_tablet = null // Utility vars - var/state = 0 // 0: Select device type, 1: Select loadout, 2: Payment, 3: Thankyou screen - var/devtype = 0 // 0: None(unselected), 1: Laptop, 2: Tablet - var/total_price = 0 // Price of currently vended device. + var/state = 0 // 0: Select device type, 1: Select loadout, 2: Payment, 3: Thankyou screen + var/devtype = 0 // 0: None(unselected), 1: Laptop, 2: Tablet + var/total_price = 0 // Price of currently vended device. var/credits = 0 // Device loadout - var/dev_cpu = 1 // 1: Default, 2: Upgraded - var/dev_battery = 1 // 1: Default, 2: Upgraded, 3: Advanced - var/dev_disk = 1 // 1: Default, 2: Upgraded, 3: Advanced - var/dev_netcard = 0 // 0: None, 1: Basic, 2: Long-Range - var/dev_apc_recharger = 0 // 0: None, 1: Standard (LAPTOP ONLY) - var/dev_printer = 0 // 0: None, 1: Standard - var/dev_card = 0 // 0: None, 1: Standard + var/dev_cpu = 1 // 1: Default, 2: Upgraded + var/dev_battery = 1 // 1: Default, 2: Upgraded, 3: Advanced + var/dev_disk = 1 // 1: Default, 2: Upgraded, 3: Advanced + var/dev_netcard = 0 // 0: None, 1: Basic, 2: Long-Range + var/dev_apc_recharger = 0 // 0: None, 1: Standard (LAPTOP ONLY) + var/dev_printer = 0 // 0: None, 1: Standard + var/dev_card = 0 // 0: None, 1: Standard // Removes all traces of old order and allows you to begin configuration from scratch. /obj/machinery/lapvend/proc/reset_order() @@ -48,7 +48,7 @@ // Recalculates the price and optionally even fabricates the device. /obj/machinery/lapvend/proc/fabricate_and_recalc_price(fabricate = FALSE) total_price = 0 - if(devtype == 1) // Laptop, generally cheaper to make it accessible for most station roles + if(devtype == 1) // Laptop, generally cheaper to make it accessible for most station roles var/obj/item/computer_hardware/battery/battery_module = null if(fabricate) fabricated_laptop = new /obj/item/modular_computer/laptop/buildable(src) @@ -111,7 +111,7 @@ fabricated_laptop.install_component(new /obj/item/computer_hardware/card_slot/secondary) return total_price - else if(devtype == 2) // Tablet, more expensive, not everyone could probably afford this. + else if(devtype == 2) // Tablet, more expensive, not everyone could probably afford this. var/obj/item/computer_hardware/battery/battery_module = null if(fabricate) fabricated_tablet = new(src) @@ -241,13 +241,13 @@ if(!user.temporarilyRemoveItemFromInventory(c)) return credits += c.value - visible_message("[user] inserts [c.value] cr into [src].") + visible_message(span_info("[span_name("[user]")] inserts [c.value] cr into [src].")) qdel(c) return else if(istype(I, /obj/item/holochip)) var/obj/item/holochip/HC = I credits += HC.credits - visible_message("[user] inserts a [HC.credits] cr holocredit chip into [src].") + visible_message(span_info("[user] inserts a [HC.credits] cr holocredit chip into [src].")) qdel(HC) return else if(istype(I, /obj/item/card/id)) diff --git a/code/modules/movespeed/_movespeed_modifier.dm b/code/modules/movespeed/_movespeed_modifier.dm index 5c4bf2ed64..5fc415b2b6 100644 --- a/code/modules/movespeed/_movespeed_modifier.dm +++ b/code/modules/movespeed/_movespeed_modifier.dm @@ -32,7 +32,7 @@ Key procs /// Unique ID. You can never have different modifications with the same ID. By default, this SHOULD NOT be set. Only set it for cases where you're dynamically making modifiers/need to have two types overwrite each other. If unset, uses path (converted to text) as ID. var/id - /// Higher ones override lower priorities. This is NOT used for ID, ID must be unique, if it isn't unique the newer one overwrites automatically if overriding. + /// Determines order. Lower priorities are applied first. var/priority = 0 var/flags = NONE @@ -41,9 +41,9 @@ Key procs /// Next two variables depend on this: Should we do advanced calculations? var/complex_calculation = FALSE /// Absolute max tiles we can boost to - var/absolute_max_tiles_per_second + var/absolute_max_tiles_per_second = INFINITY /// Max tiles per second we can boost - var/max_tiles_per_second_boost + var/max_tiles_per_second_boost = INFINITY /// Movetypes this applies to var/movetypes = ALL @@ -54,6 +54,8 @@ Key procs /// Other modification datums this conflicts with. var/conflicts_with + + /datum/movespeed_modifier/New() . = ..() if(!id) @@ -66,8 +68,10 @@ Key procs if(!complex_calculation || (multiplicative_slowdown > 0)) // we aren't limiting how much things can slowdown.. yet. return existing + multiplicative_slowdown var/current_tiles = 10 / max(existing, world.tick_lag) - var/minimum_speed = 10 / min(current_tiles + max_tiles_per_second_boost, max(current_tiles, absolute_max_tiles_per_second)) - return max(minimum_speed, existing + multiplicative_slowdown) + // multiplicative_slowdown is negative due to our first check + var/max_buff_to = max(existing + multiplicative_slowdown, 10 / absolute_max_tiles_per_second, 10 / (current_tiles + max_tiles_per_second_boost)) + // never slow the user + return min(existing, max_buff_to) GLOBAL_LIST_EMPTY(movespeed_modification_cache) diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm index 7e857a4e0d..71bc1020e2 100644 --- a/code/modules/movespeed/modifiers/mobs.dm +++ b/code/modules/movespeed/modifiers/mobs.dm @@ -15,6 +15,7 @@ /datum/movespeed_modifier/hunger variable = TRUE + blacklisted_movetypes = FLOATING|FLYING /datum/movespeed_modifier/slaughter multiplicative_slowdown = -1 @@ -113,6 +114,7 @@ multiplicative_slowdown = CRAWLING_ADD_SLOWDOWN movetypes = CRAWLING flags = IGNORE_NOSLOW + priority = 20000 /datum/movespeed_modifier/mob_config_speedmod variable = TRUE @@ -166,3 +168,6 @@ /datum/movespeed_modifier/dragon_depression multiplicative_slowdown = 5 + +/datum/movespeed_modifier/gauntlet_concussion + multiplicative_slowdown = 5 diff --git a/code/modules/movespeed/modifiers/reagents.dm b/code/modules/movespeed/modifiers/reagents.dm index ca0a74d749..a6c3133c8b 100644 --- a/code/modules/movespeed/modifiers/reagents.dm +++ b/code/modules/movespeed/modifiers/reagents.dm @@ -7,7 +7,7 @@ /datum/movespeed_modifier/reagent/ephedrine // strong painkiller effect that caps out at slightly above runspeed multiplicative_slowdown = -1.5 - priority = -100 + priority = 500 complex_calculation = TRUE absolute_max_tiles_per_second = 7 @@ -21,14 +21,14 @@ // extremely strong painkiller effect: allows user to run at old sprint speeds but not over by cancelling out slowdowns. // however, will not make user go faster than that multiplicative_slowdown = -4 - priority = -100 + priority = 500 complex_calculation = TRUE - absolute_max_tiles_per_second = 8 + absolute_max_tiles_per_second = 10 /datum/movespeed_modifier/reagent/methamphetamine // very strong painkiller effect that caps out at slightly above runspeed multiplicative_slowdown = -2.5 - priority = -100 + priority = 500 complex_calculation = TRUE absolute_max_tiles_per_second = 7.5 diff --git a/code/modules/movespeed/modifiers/status_effects.dm b/code/modules/movespeed/modifiers/status_effects.dm index 260ee17c21..ab1b12e5dc 100644 --- a/code/modules/movespeed/modifiers/status_effects.dm +++ b/code/modules/movespeed/modifiers/status_effects.dm @@ -19,14 +19,14 @@ /datum/movespeed_modifier/status_effect/tased multiplicative_slowdown = 1.5 - priority = 50 + priority = 1500 /datum/movespeed_modifier/status_effect/domain multiplicative_slowdown = 3 /datum/movespeed_modifier/status_effect/tased/no_combat_mode multiplicative_slowdown = 8 - priority = 100 + priority = 1500 /datum/movespeed_modifier/status_effect/electrostaff multiplicative_slowdown = 1 @@ -55,7 +55,7 @@ /datum/movespeed_modifier/status_effect/slime/light_pink // decently good painkiller + speedup effect blacklisted_movetypes = FLYING | FLOATING - priority = -150 // someday we really need to make these defines lmao + priority = 500 // someday we really need to make these defines lmao multiplicative_slowdown = -2 complex_calculation = TRUE absolute_max_tiles_per_second = 7 diff --git a/code/modules/newscaster/newscaster_machine.dm b/code/modules/newscaster/newscaster_machine.dm index c81a8f5d1a..5bc0929465 100644 --- a/code/modules/newscaster/newscaster_machine.dm +++ b/code/modules/newscaster/newscaster_machine.dm @@ -16,7 +16,7 @@ GLOBAL_LIST_EMPTY(allCasters) verb_say = "beeps" verb_ask = "beeps" verb_exclaim = "beeps" - armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) max_integrity = 200 integrity_failure = 0.25 var/screen = 0 @@ -614,7 +614,7 @@ GLOBAL_LIST_EMPTY(allCasters) if(user.a_intent != INTENT_HARM) to_chat(user, "The newscaster controls are far too complicated for your tiny brain!") else - take_damage(5, BRUTE, "melee") + take_damage(5, BRUTE, MELEE) /obj/machinery/newscaster/proc/AttachPhoto(mob/user) var/obj/item/photo/photo = user.is_holding_item_of_type(/obj/item/photo) diff --git a/code/modules/ninja/__ninjaDefines.dm b/code/modules/ninja/__ninjaDefines.dm index d6cdb55840..0cfd1a4895 100644 --- a/code/modules/ninja/__ninjaDefines.dm +++ b/code/modules/ninja/__ninjaDefines.dm @@ -1,23 +1,23 @@ - -/* - -Contents: -- Definitions, because the original Ninja code has so much magic. - -*/ - - //ninjacost() specificCheck defines #define N_STEALTH_CANCEL 1 -#define N_SMOKE_BOMB 2 -#define N_ADRENALINE 3 +#define N_ADRENALINE 2 //ninjaDrainAct() defines for non numerical returns -//While not strictly needed, it's nicer than them just returning "twat" -//Which was my original intention. #define INVALID_DRAIN "INVALID" //This one is if the drain proc needs to cancel, eg missing variables, etc, it's important. - #define DRAIN_RD_HACK_FAILED "RDHACKFAIL" #define DRAIN_MOB_SHOCK "MOBSHOCK" #define DRAIN_MOB_SHOCK_FAILED "MOBSHOCKFAIL" + + +//Tells whether or not someone is a space ninja +#define IS_SPACE_NINJA(ninja) (ninja.mind && ninja.mind.has_antag_datum(/datum/antagonist/ninja)) + +//Defines for the suit's unique abilities +#define IS_NINJA_SUIT_INITIALIZATION(action) (istype(action, /datum/action/item_action/initialize_ninja_suit)) +#define IS_NINJA_SUIT_BOOST(action) (istype(action, /datum/action/item_action/ninjaboost)) +#define IS_NINJA_SUIT_EMP(action) (istype(action, /datum/action/item_action/ninjapulse)) +#define IS_NINJA_SUIT_STAR_CREATION(action) (istype(action, /datum/action/item_action/ninjastar)) +#define IS_NINJA_SUIT_NET_CREATION(action) (istype(action, /datum/action/item_action/ninjanet)) +#define IS_NINJA_SUIT_SWORD_RECALL(action) (istype(action, /datum/action/item_action/ninja_sword_recall)) +#define IS_NINJA_SUIT_STEALTH(action) (istype(action, /datum/action/item_action/ninja_stealth)) diff --git a/code/modules/ninja/energy_katana.dm b/code/modules/ninja/energy_katana.dm index 00cfa94893..716c4a0dad 100644 --- a/code/modules/ninja/energy_katana.dm +++ b/code/modules/ninja/energy_katana.dm @@ -1,3 +1,14 @@ +/** + * # Energy Katana + * + * The space ninja's katana. + * + * The katana that only space ninja spawns with. Comes with 30 force and throwforce, along with a signature special jaunting system. + * Upon clicking on a tile with the dash on, the user will teleport to that tile, assuming their target was not dense. + * The katana has 3 dashes stored at maximum, and upon using the dash, it will return 20 seconds after it was used. + * It also has a special feature where if it is tossed at a space ninja who owns it (determined by the ninja suit), the ninja will catch the katana instead of being hit by it. + * + */ /obj/item/energy_katana name = "energy katana" desc = "A katana infused with strong energy." @@ -5,23 +16,23 @@ item_state = "energy_katana" lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' - force = 40 - throwforce = 20 + force = 30 + throwforce = 30 block_chance = 50 armour_penetration = 50 w_class = WEIGHT_CLASS_NORMAL hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - block_chance = 50 slot_flags = ITEM_SLOT_BELT sharpness = SHARP_EDGED + obj_flags = UNIQUE_RENAME // here is a shitpost and i cannot wait for ninjas naming their sword very rude things max_integrity = 200 resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF var/datum/effect_system/spark_spread/spark_system var/datum/action/innate/dash/ninja/jaunt var/dash_toggled = TRUE -/obj/item/energy_katana/Initialize() +/obj/item/energy_katana/Initialize(mapload) . = ..() jaunt = new(src) spark_system = new /datum/effect_system/spark_spread() @@ -34,13 +45,19 @@ /obj/item/energy_katana/afterattack(atom/target, mob/user, proximity_flag, click_parameters) . = ..() - if(dash_toggled) - jaunt.Teleport(user, target) - if(proximity_flag && (isobj(target) || issilicon(target))) - spark_system.start() - playsound(user, "sparks", 50, 1) - playsound(user, 'sound/weapons/blade1.ogg', 50, 1) - target.emag_act(user) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + var/obj/item/clothing/suit/space/space_ninja/ninja_suit = H.wear_suit + if(!istype(ninja_suit))// do you actually have a ninja suit on + to_chat(user, "ERROR: garments incompatible with carbon material jaunt. Please suit up in compatible garments.") + return + if(!dash_toggled || Adjacent(target) || target.density)// is where you are going not a wall + return + if(!ninja_suit.s_coold == 0)// are you not currently on the ability cooldown + to_chat(user, "ERROR: suit is on cooldown.") + return + jaunt.Teleport(user, target)// okay you can now go my good sir /obj/item/energy_katana/pickup(mob/living/user) . = ..() @@ -58,16 +75,30 @@ //To throw it at the ninja /obj/item/energy_katana/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(ishuman(hit_atom)) - var/mob/living/carbon/human/H = hit_atom - if(istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja)) - var/obj/item/clothing/suit/space/space_ninja/SN = H.wear_suit - if(SN.energyKatana == src) - returnToOwner(H, 0, 1) + var/mob/living/carbon/human/hit_human = hit_atom + if(istype(hit_human.wear_suit, /obj/item/clothing/suit/space/space_ninja)) + var/obj/item/clothing/suit/space/space_ninja/ninja_suit = hit_human.wear_suit + if(ninja_suit.energyKatana == src) + returnToOwner(hit_human, 0, 1) return ..() -/obj/item/energy_katana/proc/returnToOwner(mob/living/carbon/human/user, doSpark = 1, caught = 0) +/obj/item/energy_katana/Destroy() + QDEL_NULL(spark_system) + QDEL_NULL(jaunt) + return ..() + +/** + * Proc called when the katana is recalled to its space ninja. + * + * Proc called when space ninja is hit with its suit's katana or the recall ability is used. + * Arguments: + * * user - To whom the katana is returning to. + * * doSpark - whether or not the katana will spark when it returns. + * * caught - boolean for whether or not the katana was caught or was teleported back. + */ +/obj/item/energy_katana/proc/returnToOwner(mob/living/carbon/human/user, doSpark = TRUE, caught = FALSE) if(!istype(user)) return forceMove(get_turf(user)) @@ -80,7 +111,7 @@ if(user.put_in_hands(src)) msg = "Your Energy Katana teleports into your hand!" - else if(user.equip_to_slot_if_possible(src, SLOT_BELT, 0, 1, 1)) + else if(user.equip_to_slot_if_possible(src, ITEM_SLOT_BELT, 0, 1, 1)) msg = "Your Energy Katana teleports back to you, sheathing itself as it does so!" else msg = "Your Energy Katana teleports to your location!" @@ -94,13 +125,8 @@ if(msg) to_chat(user, "[msg]") - -/obj/item/energy_katana/Destroy() - QDEL_NULL(spark_system) - return ..() - /datum/action/innate/dash/ninja current_charges = 3 max_charges = 3 - charge_rate = 30 + charge_rate = 200 recharge_sound = null diff --git a/code/modules/ninja/ninja_event.dm b/code/modules/ninja/ninja_event.dm deleted file mode 100644 index bc3c445731..0000000000 --- a/code/modules/ninja/ninja_event.dm +++ /dev/null @@ -1,93 +0,0 @@ -//Note to future generations: I didn't write this god-awful code I just ported it to the event system and tried to make it less moon-speaky. -//Don't judge me D; ~Carn //Maximum judging occuring - Remie. -// Tut tut Remie, let's keep our comments constructive. - coiax - -/* - -Contents: -- The Ninja "Random" Event -- Ninja creation code -*/ - -/datum/round_event_control/ninja - name = "Space Ninja" - typepath = /datum/round_event/ghost_role/ninja - max_occurrences = 1 - earliest_start = 40 MINUTES - gamemode_blacklist = list("dynamic") - min_players = 15 - -/datum/round_event/ghost_role/ninja - var/success_spawn = 0 - role_name = "space ninja" - minimum_required = 1 - - var/helping_station - var/spawn_loc - var/give_objectives = TRUE - -/datum/round_event/ghost_role/ninja/setup() - helping_station = rand(0,1) - -/datum/round_event/ghost_role/ninja/kill() - if(!success_spawn && control) - control.occurrences-- - return ..() - -/datum/round_event/ghost_role/ninja/spawn_role() - //selecting a spawn_loc - if(!spawn_loc) - var/list/spawn_locs = list() - for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list) - if(isturf(L.loc)) - spawn_locs += L.loc - for(var/obj/effect/landmark/loneopspawn/L in GLOB.landmarks_list) - if(isturf(L.loc)) - spawn_locs += L.loc - if(!spawn_locs.len) - return kill() - spawn_loc = pick(spawn_locs) - if(!spawn_loc) - return MAP_ERROR - - //selecting a candidate player - var/list/candidates = get_candidates(ROLE_NINJA, null, ROLE_NINJA) - if(!candidates.len) - return NOT_ENOUGH_PLAYERS - - var/mob/dead/selected_candidate = pick_n_take(candidates) - var/key = selected_candidate.key - - //Prepare ninja player mind - var/datum/mind/Mind = new /datum/mind(key) - Mind.assigned_role = ROLE_NINJA - Mind.special_role = ROLE_NINJA - Mind.active = 1 - - //spawn the ninja and assign the candidate - var/mob/living/carbon/human/Ninja = create_space_ninja(spawn_loc) - Mind.transfer_to(Ninja) - var/datum/antagonist/ninja/ninjadatum = new - ninjadatum.helping_station = pick(TRUE,FALSE) - Mind.add_antag_datum(ninjadatum) - - if(Ninja.mind != Mind) //something has gone wrong! - stack_trace("Ninja created with incorrect mind") - - spawned_mobs += Ninja - message_admins("[ADMIN_LOOKUPFLW(Ninja)] has been made into a ninja by an event.") - log_game("[key_name(Ninja)] was spawned as a ninja by an event.") - success_spawn = TRUE - - return SUCCESSFUL_SPAWN - - -//=======//NINJA CREATION PROCS//=======// - -/proc/create_space_ninja(spawn_loc) - var/mob/living/carbon/human/new_ninja = new(spawn_loc) - var/datum/preferences/A = new()//Randomize appearance for the ninja. - A.real_name = "[pick(GLOB.ninja_titles)] [pick(GLOB.ninja_names)]" - A.copy_to(new_ninja) - new_ninja.dna.update_dna_identity() - return new_ninja diff --git a/code/modules/ninja/ninja_explosive.dm b/code/modules/ninja/ninja_explosive.dm new file mode 100644 index 0000000000..e87ff2b6d6 --- /dev/null +++ b/code/modules/ninja/ninja_explosive.dm @@ -0,0 +1,45 @@ +/** + * # Spider Charge + * + * A unique version of c4 possessed only by the space ninja. Has a stronger blast radius. + * Can only be detonated by space ninjas with the bombing objective. Can only be set up where the objective says it can. + * When it primes, the space ninja responsible will have their objective set to complete. + * + */ +/obj/item/grenade/plastic/c4/ninja + name = "spider charge" + desc = "A modified C-4 charge supplied to you by the Spider Clan. Its explosive power has been juiced up, but only works in one specific area." + icon_state = "plasticspider0" + item_state = "plasticspider" + boom_sizes = list(2, 4, 6) + var/mob/detonator = null + +/obj/item/grenade/plastic/c4/ninja/afterattack(atom/movable/AM, mob/user, flag) + var/datum/antagonist/ninja/ninja_antag = user.mind.has_antag_datum(/datum/antagonist/ninja) + if(!ninja_antag) + to_chat(user, "You fiddle with the charge, but nothing happens.") + return + var/datum/objective/plant_explosive/objective = locate() in ninja_antag.objectives + if(!objective) + to_chat(user, "You can't seem to activate the charge. It's location-locked, but you don't know where to detonate it.") + return + if(objective.detonation_location != get_area(user)) + to_chat(user, "This isn't the location you're supposed to use this!") + return + detonator = user + return ..() + +/obj/item/grenade/plastic/c4/ninja/prime(mob/living/lanced_by) + . = ..() + anchored = TRUE + //Since we already did the checks in afterattack, the denonator must be a ninja with the bomb objective. + if(!detonator) + return + var/datum/antagonist/ninja/ninja_antag = detonator.mind.has_antag_datum(/datum/antagonist/ninja) + var/datum/objective/plant_explosive/objective = locate() in ninja_antag.objectives + objective.completed = TRUE + +/obj/item/grenade/plastic/c4/ninja/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/screwdriver)) + to_chat(user, "The wire panel is locked in place, clearly you aren't supposed to be opening it!") + return diff --git a/code/modules/ninja/outfit.dm b/code/modules/ninja/outfit.dm index 983ef0585a..f9ce438ed9 100644 --- a/code/modules/ninja/outfit.dm +++ b/code/modules/ninja/outfit.dm @@ -8,10 +8,10 @@ ears = /obj/item/radio/headset shoes = /obj/item/clothing/shoes/space_ninja gloves = /obj/item/clothing/gloves/space_ninja - back = /obj/item/tank/jetpack/carbondioxide - l_pocket = /obj/item/grenade/plastic/x4 - r_pocket = /obj/item/tank/internals/emergency_oxygen - internals_slot = SLOT_R_STORE + l_pocket = /obj/item/grenade/plastic/c4/ninja + r_pocket = /obj/item/hypospray/mkii/CMO/combat + suit_store = /obj/item/tank/internals/oxygen + internals_slot = ITEM_SLOT_SUITSTORE belt = /obj/item/energy_katana implants = list(/obj/item/implant/explosive) @@ -21,5 +21,6 @@ var/obj/item/clothing/suit/space/space_ninja/S = H.wear_suit if(istype(H.belt, belt)) S.energyKatana = H.belt - S.randomize_param() - + H.grant_language(/datum/language/neokanji) + var/datum/language_holder/LH = H.get_language_holder() + LH.selected_language = /datum/language/neokanji diff --git a/code/modules/ninja/suit/gloves.dm b/code/modules/ninja/suit/gloves.dm index a06b753402..15abf0936e 100644 --- a/code/modules/ninja/suit/gloves.dm +++ b/code/modules/ninja/suit/gloves.dm @@ -1,25 +1,13 @@ - - - -/* - Dear ninja gloves - - This isn't because I like you - this is because your father is a bastard - - ... - I guess you're a little cool. - -Sayu - - - see ninjaDrainAct.dm for ninjadrain_act() - Touch() simply calls this on it's target now - Ninja's electricuting people when? - -Remie - -*/ - - +/** + * # Ninja Gloves + * + * Space ninja's gloves. Gives access to a number of special interactions. + * + * Gloves only found from space ninjas. Allows the wearer to access special interactions with various objects. + * These interactions are detailed in ninjaDrainAct.dm in the suit file. + * These interactions are toggled by an action tied to the gloves. The interactions will not activate if the user is also not wearing a ninja suit. + * + */ /obj/item/clothing/gloves/space_ninja desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance." name = "ninja gloves" @@ -32,11 +20,24 @@ max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT strip_delay = 120 resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - var/draining = 0 - var/candrain = 0 + actions_types = list(/datum/action/item_action/toggle_glove) + var/datum/action/innate/doorjack/ninja/hack + ///Whether or not we're currently draining something + var/draining = FALSE + ///Whether or not we can currently drain something + var/candrain = FALSE + ///Minimum amount of power we can drain in a single drain action var/mindrain = 200 + ///Maximum amount of power we can drain in a single drain action var/maxdrain = 400 - + ///Whether or not the security console hack was used to set everyone to arrest + var/security_console_hack_success = FALSE + ///Whether or not the communication console hack was used to summon another antagonist + var/communication_console_hack_success = FALSE + ///How many times the gloves have been used to force open doors. + var/door_hack_counter = 0 + ///Whether or not the cyborg hack was used to syndify a cyborg + var/borg_hack_success = FALSE var/stunforce = 100 /obj/item/clothing/gloves/space_ninja/Touch(atom/A,proximity) @@ -45,9 +46,9 @@ if(!ishuman(loc)) return FALSE //Only works while worn - var/mob/living/carbon/human/H = loc + var/mob/living/carbon/human/wearer = loc - var/obj/item/clothing/suit/space/space_ninja/suit = H.wear_suit + var/obj/item/clothing/suit/space/space_ninja/suit = wearer.wear_suit if(!istype(suit)) return FALSE if(isturf(A)) @@ -56,17 +57,17 @@ if(!proximity) return FALSE - A.add_fingerprint(H) + A.add_fingerprint(wearer) draining = TRUE - . = A.ninjadrain_act(suit,H,src) + . = A.ninjadrain_act(suit,wearer,src) draining = FALSE if(isnum(.)) //Numerical values of drained handle their feedback here, Alpha values handle it themselves (Research hacking) if(.) - to_chat(H, "Gained [DisplayEnergy(.)] of energy from [A].") + to_chat(wearer, "Gained [DisplayEnergy(.)] of energy from [A].") else - to_chat(H, "\The [A] has run dry of energy, you must find another source!") + to_chat(wearer, "\The [A] has run dry of energy, you must find another source!") . = INTERRUPT_UNARMED_ATTACK else . = FALSE //as to not cancel attack_hand() @@ -75,12 +76,13 @@ . = ..() REMOVE_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT) -/obj/item/clothing/gloves/space_ninja/proc/toggledrain() - var/mob/living/carbon/human/U = loc - to_chat(U, "You [candrain?"disable":"enable"] special interaction.") - candrain=!candrain - /obj/item/clothing/gloves/space_ninja/examine(mob/user) . = ..() if(HAS_TRAIT_FROM(src, TRAIT_NODROP, NINJA_SUIT_TRAIT)) . += "The energy drain mechanism is [candrain?"active":"inactive"]." + +/obj/item/clothing/gloves/space_ninja/ui_action_click(mob/user, action) + if(istype(action, /datum/action/item_action/toggle_glove)) + toggledrain() + return TRUE + return FALSE diff --git a/code/modules/ninja/suit/head.dm b/code/modules/ninja/suit/head.dm index 9a65dabc1e..36c3eb71d1 100644 --- a/code/modules/ninja/suit/head.dm +++ b/code/modules/ninja/suit/head.dm @@ -1,14 +1,19 @@ - - +/** + * # Ninja Hood + * + * Space ninja's hood. Provides armor and blocks AI tracking. + * + * A hood that only exists as a part of space ninja's starting kit. Provides armor equal of space ninja's suit and disallows an AI to track the wearer. + * + */ /obj/item/clothing/head/helmet/space/space_ninja desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear." name = "ninja hood" icon_state = "s-ninja" item_state = "s-ninja_mask" - armor = list("melee" = 60, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 25, "fire" = 100, "acid" = 100) - strip_delay = 12 + armor = list(MELEE = 40, BULLET = 30, LASER = 20,ENERGY = 30, BOMB = 30, BIO = 30, RAD = 30, FIRE = 100, ACID = 100) resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - blockTracking = 1//Roughly the only unique thing about this helmet. + blockTracking = TRUE//Roughly the only unique thing about this helmet. flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR /obj/item/clothing/head/helmet/space/space_ninja/dropped(mob/user) diff --git a/code/modules/ninja/suit/mask.dm b/code/modules/ninja/suit/mask.dm index 421c13f9eb..111f76ae65 100644 --- a/code/modules/ninja/suit/mask.dm +++ b/code/modules/ninja/suit/mask.dm @@ -1,15 +1,11 @@ - -/* - -Contents: -- The Ninja Space Mask -- Ninja Space Mask speech modification - -*/ - - - - +/** + * # Ninja Mask + * + * Space ninja's mask. Makes you sound like a real anime girl. Barely able to be considered a real upside. + * + * A mask which only spawns as a part of space ninja's starting kit. Functions as a gas mask. + * + */ /obj/item/clothing/mask/gas/space_ninja name = "ninja mask" desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement." diff --git a/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm deleted file mode 100644 index c0ee68cdee..0000000000 --- a/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm +++ /dev/null @@ -1,117 +0,0 @@ -/* -It will teleport people to a holding facility after 30 seconds. (Check the process() proc to change where teleport goes) -It is possible to destroy the net by the occupant or someone else. -*/ - -/obj/structure/energy_net - name = "energy net" - desc = "It's a net made of green energy." - icon = 'icons/effects/effects.dmi' - icon_state = "energynet" - - density = TRUE//Can't pass through. - opacity = 0//Can see through. - mouse_opacity = MOUSE_OPACITY_ICON//So you can hit it with stuff. - anchored = TRUE//Can't drag/grab the net. - layer = ABOVE_ALL_MOB_LAYER - max_integrity = 50 //How much health it has. - can_buckle = 1 - buckle_lying = 0 - buckle_prevents_pull = TRUE - var/mob/living/carbon/affecting //Who it is currently affecting, if anyone. - var/mob/living/carbon/master //Who shot web. Will let this person know if the net was successful or failed. - var/check = 15//30 seconds before teleportation. Could be extended I guess. - var/success = FALSE - - -/obj/structure/energy_net/play_attack_sound(damage, damage_type = BRUTE, damage_flag = 0) - switch(damage_type) - if(BRUTE) - playsound(src, 'sound/weapons/slash.ogg', 80, 1) - if(BURN) - playsound(src, 'sound/weapons/slash.ogg', 80, 1) - -/obj/structure/energy_net/Destroy() - if(!success) - if(!QDELETED(affecting)) - affecting.visible_message("[affecting.name] was recovered from the energy net!", "You were recovered from the energy net!", "You hear a grunt.") - if(!QDELETED(master))//As long as they still exist. - to_chat(master, "ERROR: unable to initiate transport protocol. Procedure terminated.") - return ..() - -/obj/structure/energy_net/process() - if(QDELETED(affecting)||affecting.loc!=loc) - qdel(src)//Get rid of the net. - return - - if(check>0) - check-- - return - - success = TRUE - qdel(src) - if(ishuman(affecting)) - var/mob/living/carbon/human/H = affecting - for(var/obj/item/W in H) - if(W == H.w_uniform || W == H.shoes) - continue//So all they're left with are shoes and uniform. - H.dropItemToGround(W) - H.dna.species.give_important_for_life(H) // After we remove items, at least give them what they need to live. -/* - var/datum/antagonist/antag_datum - for(var/datum/antagonist/ninja/AD in GLOB.antagonists) //Because only ninjas get capture objectives; They're not doable without the suit. - if(AD.owner == master) - antag_datum = AD - break - for(var/datum/objective/capture/capture in antag_datum) - if(istype(affecting, /mob/living/carbon/human)) //Humans. - if(affecting.stat == DEAD)//Dead folks are worth less. - capture.captured_amount+=0.5 - continue - capture.captured_amount+=1 - if(istype(affecting, /mob/living/carbon/monkey)) //Monkeys are almost worthless, you failure. - capture.captured_amount+=0.1 - if(istype(affecting, /mob/living/carbon/alien/larva)) //Larva are important for research. - if(affecting.stat == DEAD) - capture.captured_amount+=0.5 - continue - capture.captured_amount+=1 - if(istype(affecting, /mob/living/carbon/alien/humanoid)) //Aliens are worth twice as much as humans. - if(istype(affecting, /mob/living/carbon/alien/humanoid/royal/queen)) //Queens are worth three times as much as humans. - if(affecting.stat == DEAD) - capture.captured_amount+=1.5 - else - capture.captured_amount+=3 - continue - if(affecting.stat == DEAD) - capture.captured_amount+=1 - continue - capture.captured_amount+=2 -*/ - - affecting.revive(1, 1) //Basically a revive and full heal, including limbs/organs - //In case people who have been captured dead want to hang out at the holding area - - playsound(affecting, 'sound/effects/sparks4.ogg', 50, 1) - new /obj/effect/temp_visual/dir_setting/ninja/phase/out(affecting.drop_location(), affecting.dir) - - visible_message("[affecting] suddenly vanishes!") - affecting.forceMove(pick(GLOB.holdingfacility)) //Throw mob in to the holding facility. - to_chat(affecting, "You appear in a strange place!") - - if(!QDELETED(master))//As long as they still exist. - to_chat(master, "SUCCESS: transport procedure of [affecting] complete.") - do_sparks(5, FALSE, affecting) - playsound(affecting, 'sound/effects/phasein.ogg', 25, 1) - playsound(affecting, 'sound/effects/sparks2.ogg', 50, 1) - new /obj/effect/temp_visual/dir_setting/ninja/phase(affecting.drop_location(), affecting.dir) - -/obj/structure/energy_net/attack_alien(mob/living/carbon/alien/humanoid/user) - if(attack_generic(user, 15, BRUTE, "melee", 0)) //Aliens normally deal 60 damage to structures. They'd one-shot nets without this. - playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) - -/obj/structure/energy_net/user_buckle_mob(mob/living/M, mob/living/user) - return//We only want our target to be buckled - -/obj/structure/energy_net/user_unbuckle_mob(mob/living/buckled_mob, mob/living/user) - return//The net must be destroyed to free the target diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm deleted file mode 100644 index 89f5d20e70..0000000000 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm +++ /dev/null @@ -1,19 +0,0 @@ -//Wakes the user so they are able to do their thing. Also injects a decent dose of radium. -//Movement impairing would indicate drugs and the like. -/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost() - - if(!ninjacost(0,N_ADRENALINE)) - var/mob/living/carbon/human/H = affecting - H.do_adrenaline(150, TRUE, 0, 0, TRUE, list(/datum/reagent/medicine/inaprovaline = 3, /datum/reagent/medicine/synaptizine = 10, /datum/reagent/medicine/omnizine = 10), "You feel a sudden surge of energy!") - - H.say(pick("A CORNERED FOX IS MORE DANGEROUS THAN A JACKAL!","HURT ME MOOORRREEE!","IMPRESSIVE!"), forced = "ninjaboost") - - a_boost-- - to_chat(H, "There are [a_boost] adrenaline boosts remaining.") - s_coold = 3 - addtimer(CALLBACK(src, .proc/ninjaboost_after), 70) - -/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost_after() - var/mob/living/carbon/human/H = affecting - H.reagents.add_reagent(/datum/reagent/radium, a_transfer) - to_chat(H, "You are beginning to feel the after-effect of the injection.") diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_cost_check.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_cost_check.dm deleted file mode 100644 index 12fea51815..0000000000 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_cost_check.dm +++ /dev/null @@ -1,25 +0,0 @@ - - -//Cost function for suit Procs/Verbs/Abilities -/obj/item/clothing/suit/space/space_ninja/proc/ninjacost(cost = 0, specificCheck = 0) - var/mob/living/carbon/human/H = affecting - var/actualCost = cost*10 - if(cost && cell.charge < actualCost) - to_chat(H, "Not enough energy.") - return 1 - else - //This shit used to be handled individually on every proc.. why even bother with a universal check proc then? - cell.charge-=(actualCost) - - switch(specificCheck) - if(N_STEALTH_CANCEL) - cancel_stealth()//Get rid of it. - if(N_SMOKE_BOMB) - if(!s_bombs) - to_chat(H, "There are no more smoke bombs remaining.") - return 1 - if(N_ADRENALINE) - if(!a_boost) - to_chat(H, "You do not have any more adrenaline boosters.") - return 1 - return (s_coold)//Returns the value of the variable which counts down to zero. diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm deleted file mode 100644 index 29dc78e5f3..0000000000 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm +++ /dev/null @@ -1,10 +0,0 @@ - - -//Disables nearby tech equipment. -/obj/item/clothing/suit/space/space_ninja/proc/ninjapulse() - - if(!ninjacost(250,N_STEALTH_CANCEL)) - var/mob/living/carbon/human/H = affecting - playsound(H.loc, 'sound/effects/empulse.ogg', 60, 2) - empulse_using_range(H, 9) //Procs sure are nice. Slightly weaker than wizard's disable tch. - s_coold = 2 diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm deleted file mode 100644 index 61355ca89b..0000000000 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm +++ /dev/null @@ -1,44 +0,0 @@ - -//Allows the ninja to kidnap people -/obj/item/clothing/suit/space/space_ninja/proc/ninjanet() - var/mob/living/carbon/human/H = affecting - var/mob/living/carbon/C - - //If there's only one valid target, let's actually try to capture it, rather than forcing - //the user to fiddle with the dialog displaying a list of one - //Also, let's make this smarter and not list mobs you can't currently net. - var/list/candidates - for(var/mob/M in oview(H)) - if(!M.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame. - continue - for(var/obj/structure/energy_net/E in get_turf(M))//Check if they are already being affected by an energy net. - if(E.affecting == M) - continue - LAZYADD(candidates, M) - - if(!LAZYLEN(candidates)) - return FALSE - - if(candidates.len == 1) - C = candidates[1] - else - C = input("Select who to capture:","Capture who?",null) as null|mob in candidates - - - if(QDELETED(C)||!(C in oview(H))) - return FALSE - - if(!ninjacost(200,N_STEALTH_CANCEL)) - H.Beam(C,"n_beam",time=15) - H.say("Get over here!", forced = "ninja net") - var/obj/structure/energy_net/E = new /obj/structure/energy_net(C.drop_location()) - E.affecting = C - E.master = H - H.visible_message("[H] caught [C] with an energy net!","You caught [C] with an energy net!") - - if(C.buckled) - C.buckled.unbuckle_mob(affecting,TRUE) - E.buckle_mob(C, TRUE) //No moving for you! - //The person can still try and attack the net when inside. - - START_PROCESSING(SSobj, E) diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_smoke.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_smoke.dm deleted file mode 100644 index 3c19162048..0000000000 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_smoke.dm +++ /dev/null @@ -1,14 +0,0 @@ - - -//Smoke bomb -/obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke() - - if(!ninjacost(0,N_SMOKE_BOMB)) - var/mob/living/carbon/human/H = affecting - var/datum/effect_system/smoke_spread/bad/smoke = new - smoke.set_up(4, H.loc) - smoke.start() - playsound(H.loc, 'sound/effects/bamf.ogg', 50, 2) - s_bombs-- - to_chat(H, "There are [s_bombs] smoke bombs remaining.") - s_coold = 1 diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm deleted file mode 100644 index 57faad9493..0000000000 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm +++ /dev/null @@ -1,18 +0,0 @@ - - -//Creates a throwing star -/obj/item/clothing/suit/space/space_ninja/proc/ninjastar() - if(!ninjacost(10)) - var/mob/living/carbon/human/H = affecting - var/obj/item/throwing_star/ninja/N = new(H) - if(H.put_in_hands(N)) - to_chat(H, "A throwing star has been created in your hand!") - else - qdel(N) - H.throw_mode_on() //So they can quickly throw it. - - -/obj/item/throwing_star/ninja - name = "ninja throwing star" - throwforce = 20 - embedding = list("pain_mult" = 6, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 15) diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm deleted file mode 100644 index 56c50078c1..0000000000 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm +++ /dev/null @@ -1,54 +0,0 @@ - -/* - -Contents: -- Stealth Verbs - -*/ - - -/obj/item/clothing/suit/space/space_ninja/proc/toggle_stealth() - if(!affecting || stealth_cooldown > world.time) - return - if(stealth) - cancel_stealth() - else - if(cell.charge <= 0) - to_chat(affecting, "You don't have enough power to enable Stealth!") - return - stealth = TRUE - stealth_cooldown = world.time + 5 SECONDS - animate(affecting, alpha = 15, time = 3 SECONDS) - affecting.visible_message("[affecting.name] vanishes into thin air!", \ - "You are now mostly invisible to normal detection.") - addtimer(CALLBACK(src, .proc/enable_signals), 3 SECONDS) - -/obj/item/clothing/suit/space/space_ninja/proc/enable_signals() - if(!affecting) - return - RegisterSignal(affecting, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_ATTACK_RANGED, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_THROW, COMSIG_PARENT_ATTACKBY, COMSIG_MOVABLE_TELEPORTED, COMSIG_LIVING_GUN_PROCESS_FIRE), .proc/reduce_stealth) - RegisterSignal(affecting, COMSIG_MOVABLE_BUMP, .proc/bumping_stealth) - -/obj/item/clothing/suit/space/space_ninja/proc/reduce_stealth(datum/source) - affecting.alpha = min(affecting.alpha + 40, 100) - -/obj/item/clothing/suit/space/space_ninja/proc/bumping_stealth(datum/source, atom/A) - if(isliving(A)) - affecting.alpha = min(affecting.alpha + 20, 100) - -/obj/item/clothing/suit/space/space_ninja/proc/cancel_stealth() - if(!affecting || !stealth) - return FALSE - stealth = !stealth - stealth_cooldown = world.time + 5 SECONDS - UnregisterSignal(affecting, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_ATTACK_RANGED, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_THROW, COMSIG_PARENT_ATTACKBY, COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_TELEPORTED, COMSIG_LIVING_GUN_PROCESS_FIRE)) - animate(affecting, alpha = 255, time = 3 SECONDS) - affecting.visible_message("[affecting.name] appears from thin air!", \ - "You are now visible.") - return TRUE - -/obj/item/clothing/suit/space/space_ninja/proc/stealth() - if(!s_busy) - toggle_stealth() - else - to_chat(affecting, "Stealth does not appear to work!") diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_sword_recall.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_sword_recall.dm deleted file mode 100644 index 7a192c427c..0000000000 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_sword_recall.dm +++ /dev/null @@ -1,39 +0,0 @@ - -/obj/item/clothing/suit/space/space_ninja/proc/ninja_sword_recall() - var/mob/living/carbon/human/H = affecting - - var/cost = 0 - var/inview = 1 - - if(!energyKatana) - to_chat(H, "Could not locate Energy Katana!") - return - - if(energyKatana in H) - return - - var/distance = get_dist(H,energyKatana) - - if(!(energyKatana in view(H))) - cost = distance //Actual cost is cost x 10, so 5 turfs is 50 cost. - inview = 0 - - if(!ninjacost(cost)) - if(iscarbon(energyKatana.loc)) - var/mob/living/carbon/C = energyKatana.loc - C.transferItemToLoc(energyKatana, get_turf(energyKatana), TRUE) - - //Somebody swollowed my sword, probably the clown doing a circus act. - if(energyKatana in C.stomach_contents) - C.stomach_contents -= energyKatana - else - energyKatana.forceMove(get_turf(energyKatana)) - - if(inview) //If we can see the katana, throw it towards ourselves, damaging people as we go. - energyKatana.spark_system.start() - playsound(H, "sparks", 50, 1) - H.visible_message("\the [energyKatana] flies towards [H]!","You hold out your hand and \the [energyKatana] flies towards you!") - energyKatana.throw_at(H, distance+1, energyKatana.throw_speed,H) - - else //Else just TP it to us. - energyKatana.returnToOwner(H,1) diff --git a/code/modules/ninja/suit/ninjaDrainAct.dm b/code/modules/ninja/suit/ninjaDrainAct.dm index af0ca809da..48efa2452f 100644 --- a/code/modules/ninja/suit/ninjaDrainAct.dm +++ b/code/modules/ninja/suit/ninjaDrainAct.dm @@ -1,274 +1,328 @@ - -/* - -Contents: -- Assorted ninjadrain_act() procs -- What is Object Oriented Programming - -They *could* go in their appropriate files, but this is supposed to be modular - -*/ - - -//Needs to return the amount drained from the atom, if no drain on a power object, return FALSE, otherwise, return a define. -/atom/proc/ninjadrain_act() +/** + * Atom level proc for space ninja's glove interactions. + * + * Proc which only occurs when space ninja uses his gloves on an atom. + * Does nothing by default, but effects will vary. + * Arguments: + * * ninja_suit - The offending space ninja's suit. + * * ninja - The human mob wearing the suit. + * * ninja_gloves - The offending space ninja's gloves. + */ +/atom/proc/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves) return INVALID_DRAIN - - - //APC// -/obj/machinery/power/apc/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G) - if(!S || !H || !G) +/obj/machinery/power/apc/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves) + if(!ninja_suit || !ninja || !ninja_gloves) return INVALID_DRAIN - var/maxcapacity = 0 //Safety check for batteries + var/maxcapacity = FALSE //Safety check for batteries var/drain = 0 //Drain amount from batteries - - . = 0 + var/drain_total = 0 if(cell && cell.charge) var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread() spark_system.set_up(5, 0, loc) - while(G.candrain && cell.charge> 0 && !maxcapacity) - drain = rand(G.mindrain, G.maxdrain) + while(ninja_gloves.candrain && cell.charge> 0 && !maxcapacity) + drain = rand(ninja_gloves.mindrain, ninja_gloves.maxdrain) if(cell.charge < drain) drain = cell.charge - if(S.cell.charge + drain > S.cell.maxcharge) - drain = S.cell.maxcharge - S.cell.charge - maxcapacity = 1//Reached maximum battery capacity. + if(ninja_suit.cell.charge + drain > ninja_suit.cell.maxcharge) + drain = ninja_suit.cell.maxcharge - ninja_suit.cell.charge + maxcapacity = TRUE//Reached maximum battery capacity. - if (do_after(H,10, target = src)) + if (do_after(ninja ,10, target = src)) spark_system.start() playsound(loc, "sparks", 50, 1) cell.charge -= drain - S.cell.charge += drain - . += drain + ninja_suit.cell.charge += drain + drain_total += drain else break if(!(obj_flags & EMAGGED)) - flick("apc-spark", G) + flick("apc-spark", ninja_gloves) playsound(loc, "sparks", 50, 1) obj_flags |= EMAGGED locked = FALSE update_icon() - - - + return drain_total //SMES// -/obj/machinery/power/smes/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G) - if(!S || !H || !G) +/obj/machinery/power/smes/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves) + if(!ninja_suit || !ninja || !ninja_gloves) return INVALID_DRAIN var/maxcapacity = 0 //Safety check for batteries - var/drain = 0 //Drain amount from batteries - - . = 0 + var/drain = FALSE //Drain amount from batteries + var/drain_total = 0 if(charge) var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread() spark_system.set_up(5, 0, loc) - while(G.candrain && charge > 0 && !maxcapacity) - drain = rand(G.mindrain, G.maxdrain) + while(ninja_gloves.candrain && charge > 0 && !maxcapacity) + drain = rand(ninja_gloves.mindrain, ninja_gloves.maxdrain) if(charge < drain) drain = charge - if(S.cell.charge + drain > S.cell.maxcharge) - drain = S.cell.maxcharge - S.cell.charge - maxcapacity = 1 + if(ninja_suit.cell.charge + drain > ninja_suit.cell.maxcharge) + drain = ninja_suit.cell.maxcharge - ninja_suit.cell.charge + maxcapacity = TRUE - if (do_after(H,10, target = src)) + if (do_after(ninja,10, target = src)) spark_system.start() playsound(loc, "sparks", 50, 1) charge -= drain - S.cell.charge += drain - . += drain + ninja_suit.cell.charge += drain + drain_total += drain else break + return drain_total //CELL// -/obj/item/stock_parts/cell/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G) - if(!S || !H || !G) +/obj/item/stock_parts/cell/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves) + if(!ninja_suit || !ninja || !ninja_gloves) return INVALID_DRAIN - . = 0 + var/drain_total = 0 if(charge) - if(G.candrain && do_after(H,30, target = src)) - . = charge - if(S.cell.charge + charge > S.cell.maxcharge) - S.cell.charge = S.cell.maxcharge + if(ninja_gloves.candrain && do_after(ninja,30, target = src)) + drain_total = charge + if(ninja_suit.cell.charge + charge > ninja_suit.cell.maxcharge) + ninja_suit.cell.charge = ninja_suit.cell.maxcharge else - S.cell.charge += charge + ninja_suit.cell.charge += charge charge = 0 corrupt() update_icon() -/obj/machinery/proc/AI_notify_hack() - var/turf/location = get_turf(src) - var/alertstr = "Network Alert: Hacking attempt detected[location?" in [location]":". Unable to pinpoint location"]." - for(var/mob/living/silicon/ai/AI in GLOB.player_list) - to_chat(AI, alertstr) + return drain_total //RDCONSOLE// -/obj/machinery/computer/rdconsole/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G) - if(!S || !H || !G) +/obj/machinery/computer/rdconsole/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves) + if(!ninja_suit || !ninja || !ninja_gloves) return INVALID_DRAIN . = DRAIN_RD_HACK_FAILED - to_chat(H, "Hacking \the [src]...") + to_chat(ninja, "Hacking \the [src]...") AI_notify_hack() if(stored_research) - to_chat(H, "Copying files...") - if(do_after(H, S.s_delay, target = src) && G.candrain && src) - stored_research.copy_research_to(S.stored_research) - to_chat(H, "Data analyzed. Process finished.") + to_chat(ninja, "Copying files...") + if(do_after(ninja, ninja_suit.s_delay, target = src) && ninja_gloves.candrain && src) + stored_research.copy_research_to( ninja_suit.stored_research) + to_chat(ninja, "Data analyzed. Process finished.") //RD SERVER// -//Shamelessly copypasted from above, since these two used to be the same proc, but with MANY colon operators -/obj/machinery/rnd/server/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G) - if(!S || !H || !G) +//obj/machinery/rnd/server/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves) + if(!ninja_suit || !ninja || !ninja_gloves) return INVALID_DRAIN . = DRAIN_RD_HACK_FAILED - to_chat(H, "Hacking \the [src]...") + to_chat(ninja, "Hacking \the [src]...") AI_notify_hack() if(stored_research) - to_chat(H, "Copying files...") - if(do_after(H, S.s_delay, target = src) && G.candrain && src) - stored_research.copy_research_to(S.stored_research) - to_chat(H, "Data analyzed. Process finished.") + to_chat(ninja, "Copying files...") + if(do_after(ninja, ninja_suit.s_delay, target = src) && ninja_gloves.candrain && src) + stored_research.copy_research_to(ninja_suit.stored_research) + to_chat(ninja, "Data analyzed. Process finished.") +//SECURITY CONSOLE// +/obj/machinery/computer/secure_data/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves) + if(!ninja_suit || !ninja || !ninja_gloves) + return INVALID_DRAIN + if(ninja_gloves.security_console_hack_success) + return + to_chat(ninja, "Hacking \the [src]...") + AI_notify_hack() + if(do_after(ninja, ninja_suit.s_longdelay, target = src) && ninja_gloves.candrain && src) + for(var/datum/data/record/rec in sortRecord(GLOB.data_core.general, sortBy, order)) + for(var/datum/data/record/security_record in GLOB.data_core.security) + security_record.fields["criminal"] = "*Arrest*" + var/datum/antagonist/ninja/ninja_antag = ninja.mind.has_antag_datum(/datum/antagonist/ninja) + if(!ninja_antag) + return + ninja_gloves.security_console_hack_success = TRUE + var/datum/objective/security_scramble/objective = locate() in ninja_antag.objectives + if(objective) + objective.completed = TRUE + to_chat(ninja, "Security record corruption malware uploaded. Process finished; objective completed.") -//WIRE// -/obj/structure/cable/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G) - if(!S || !H || !G) +//COMMUNICATIONS CONSOLE// +/obj/machinery/computer/communications/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves) + if(!ninja_suit || !ninja || !ninja_gloves) + return INVALID_DRAIN + if(ninja_gloves.communication_console_hack_success) + return + to_chat(ninja, "Hacking \the [src]...") + AI_notify_hack() + if(do_after(ninja, ninja_suit.s_longdelay, target = src) && ninja_gloves.candrain && src) + var/announcement_pick = rand(0, 1) + switch(announcement_pick) + if(0) + priority_announce("Attention crew, it appears that something on your station has caused an unexpected disruption with the station's airlock network.", "[command_name()] High-Priority Update") + var/datum/round_event_control/grey_tide/greytide_event = new/datum/round_event_control/grey_tide + greytide_event.runEvent() + if(1) + priority_announce("Attention crew, it appears that something on your station has made unexpected communication with a syndicate ship in nearby space.", "[command_name()] High-Priority Update") + var/datum/round_event_control/pirates/pirate_event = new/datum/round_event_control/pirates + pirate_event.runEvent() + ninja_gloves.communication_console_hack_success = TRUE + var/datum/antagonist/ninja/ninja_antag = ninja.mind.has_antag_datum(/datum/antagonist/ninja) + if(!ninja_antag) + return + var/datum/objective/terror_message/objective = locate() in ninja_antag.objectives + if(objective) + objective.completed = TRUE + to_chat(ninja, "Signal decryption malware uploaded. Process finished; objective completed.") + +//AIRLOCK// +/obj/machinery/door/airlock/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves) + if(!ninja_suit || !ninja || !ninja_gloves) return INVALID_DRAIN - var/maxcapacity = 0 //Safety check + if(!operating && density && hasPower() && !(obj_flags & EMAGGED)) + emag_act() + ninja_gloves.door_hack_counter++ + var/datum/antagonist/ninja/ninja_antag = ninja.mind.has_antag_datum(/datum/antagonist/ninja) + if(!ninja_antag) + return + var/datum/objective/door_jack/objective = locate() in ninja_antag.objectives + if(objective && objective.doors_required <= ninja_gloves.door_hack_counter) + objective.completed = TRUE + +//WIRE// +/obj/structure/cable/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves) + if(!ninja_suit || !ninja || !ninja_gloves) + return INVALID_DRAIN + + var/maxcapacity = FALSE //Safety check var/drain = 0 //Drain amount - . = 0 + var/drain_total = 0 - var/datum/powernet/PN = powernet - while(G.candrain && !maxcapacity && src) - drain = (round((rand(G.mindrain, G.maxdrain))/2)) + var/datum/powernet/wire_powernet = powernet + while(ninja_gloves.candrain && !maxcapacity && src) + drain = (round((rand(ninja_gloves.mindrain, ninja_gloves.maxdrain))/2)) var/drained = 0 - if(PN && do_after(H,10, target = src)) + if(wire_powernet && do_after(ninja,10, target = src)) drained = min(drain, delayed_surplus()) add_delayedload(drained) if(drained < drain)//if no power on net, drain apcs - for(var/obj/machinery/power/terminal/T in PN.nodes) - if(istype(T.master, /obj/machinery/power/apc)) - var/obj/machinery/power/apc/AP = T.master + for(var/obj/machinery/power/terminal/affected_terminal in wire_powernet.nodes) + if(istype(affected_terminal.master, /obj/machinery/power/apc)) + var/obj/machinery/power/apc/AP = affected_terminal.master if(AP.operating && AP.cell && AP.cell.charge > 0) AP.cell.charge = max(0, AP.cell.charge - 5) drained += 5 else break - S.cell.charge += drained - if(S.cell.charge > S.cell.maxcharge) - . += (drained-(S.cell.charge - S.cell.maxcharge)) - S.cell.charge = S.cell.maxcharge - maxcapacity = 1 + ninja_suit.cell.charge += drained + if(ninja_suit.cell.charge > ninja_suit.cell.maxcharge) + . += (drained-(ninja_suit.cell.charge - ninja_suit.cell.maxcharge)) + ninja_suit.cell.charge = ninja_suit.cell.maxcharge + maxcapacity = TRUE else - . += drained - S.spark_system.start() + drain_total += drained + ninja_suit.spark_system.start() + + return drain_total + + +/obj/vehicle/sealed/mecha/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves) + if(!ninja_suit || !ninja || !ninja_gloves) -//MECH// -/obj/mecha/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G) - if(!S || !H || !G) return INVALID_DRAIN - var/maxcapacity = 0 //Safety check + var/maxcapacity = FALSE //Safety check var/drain = 0 //Drain amount - . = 0 + var/drain_total = 0 - occupant_message("Warning: Unauthorized access through sub-route 4, block H, detected.") + for(var/mob/living/MB in occupants) + to_chat(MB, "[icon2html(src, occupants)]Warning: Unauthorized access through sub-route 4, block H, detected.") if(get_charge()) - while(G.candrain && cell.charge > 0 && !maxcapacity) - drain = rand(G.mindrain,G.maxdrain) + while(ninja_gloves.candrain && cell.charge > 0 && !maxcapacity) + drain = rand(ninja_gloves.mindrain, ninja_gloves.maxdrain) if(cell.charge < drain) drain = cell.charge - if(S.cell.charge + drain > S.cell.maxcharge) - drain = S.cell.maxcharge - S.cell.charge - maxcapacity = 1 - if (do_after(H,10, target = src)) + if(ninja_suit.cell.charge + drain > ninja_suit.cell.maxcharge) + drain = ninja_suit.cell.maxcharge - ninja_suit.cell.charge + maxcapacity = TRUE + if (do_after(ninja, 10, target = src)) spark_system.start() playsound(loc, "sparks", 50, 1) cell.use(drain) - S.cell.charge += drain - . += drain + ninja_suit.cell.give(drain) + drain_total += drain else break + return drain_total + //BORG// -/mob/living/silicon/robot/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G) - if(!S || !H || !G) +/mob/living/silicon/robot/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves) + if(!ninja_suit || !ninja || !ninja_gloves || (ROLE_NINJA in faction)) return INVALID_DRAIN + if(ninja_gloves.borg_hack_success) + return + to_chat(src, "Warni-***BZZZZZZZZZRT*** UPLOADING SPYDERPATCHER VERSION 9.5.2...") + if (do_after(ninja, 60, target = src)) + spark_system.start() + playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + to_chat(src, "UPLOAD COMPLETE. NEW CYBORG MODULE DETECTED. INSTALLING...") + faction = list(ROLE_NINJA) + bubble_icon = "syndibot" + UnlinkSelf() + ionpulse = TRUE + laws = new /datum/ai_laws/ninja_override() + module.transform_to(pick(/obj/item/robot_module/syndicate/spider, /obj/item/robot_module/syndicate_medical/spider, /obj/item/robot_module/saboteur/spider)) - var/maxcapacity = 0 //Safety check - var/drain = 0 //Drain amount - . = 0 - - to_chat(src, "Warning: Unauthorized access through sub-route 12, block C, detected.") - - if(cell && cell.charge) - while(G.candrain && cell.charge > 0 && !maxcapacity) - drain = rand(G.mindrain,G.maxdrain) - if(cell.charge < drain) - drain = cell.charge - if(S.cell.charge+drain > S.cell.maxcharge) - drain = S.cell.maxcharge - S.cell.charge - maxcapacity = 1 - if (do_after(H,10)) - spark_system.start() - playsound(loc, "sparks", 50, 1) - cell.charge -= drain - S.cell.charge += drain - . += drain - else - break - + var/datum/antagonist/ninja/ninja_antag = ninja.mind.has_antag_datum(/datum/antagonist/ninja) + if(!ninja_antag) + return + ninja_gloves.borg_hack_success = TRUE + var/datum/objective/cyborg_hijack/objective = locate() in ninja_antag.objectives + if(objective) + objective.completed = TRUE //CARBON MOBS// -/mob/living/carbon/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G) - if(!S || !H || !G) +/mob/living/carbon/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves) + if(!ninja_suit || !ninja || !ninja_gloves) return INVALID_DRAIN . = DRAIN_MOB_SHOCK_FAILED //Default cell = 10,000 charge, 10,000/1000 = 10 uses without charging/upgrading - if(S.cell && S.cell.charge && S.cell.use(500)) + if(ninja_suit.cell?.charge && ninja_suit.cell.use(1000)) . = DRAIN_MOB_SHOCK //Got that electric touch var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread() spark_system.set_up(5, 0, loc) playsound(src, "sparks", 50, 1) - visible_message("[H] electrocutes [src] with [H.p_their()] touch!", "[H] electrocutes you with [H.p_their()] touch!") - electrocute_act(15, H, flags = SHOCK_NOSTUN) + visible_message("[ninja] electrocutes [src] with [ninja.p_their()] touch!", "[ninja] electrocutes you with [ninja.p_their()] touch!") + electrocute_act(15, ninja, flags = SHOCK_NOSTUN) - DefaultCombatKnockdown(G.stunforce, override_hardstun = 0) - apply_effect(EFFECT_STUTTER, G.stunforce) + DefaultCombatKnockdown(ninja_gloves.stunforce, override_hardstun = 0) + apply_effect(EFFECT_STUTTER, ninja_gloves.stunforce) SEND_SIGNAL(src, COMSIG_LIVING_MINOR_SHOCK) - - set_last_attacker(H) - log_combat(H, src, "stunned") + lastattacker = ninja.real_name + lastattackerckey = ninja.ckey + log_combat(ninja, src, "stunned") + set_last_attacker(ninja) + log_combat(ninja, src, "stunned") playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) diff --git a/code/modules/ninja/suit/ninja_equipment_actions/energy_net_nets.dm b/code/modules/ninja/suit/ninja_equipment_actions/energy_net_nets.dm new file mode 100644 index 0000000000..bc0828242e --- /dev/null +++ b/code/modules/ninja/suit/ninja_equipment_actions/energy_net_nets.dm @@ -0,0 +1,46 @@ +/** + * # Energy Net + * + * Energy net which ensnares prey until it is destroyed. Used by space ninjas. + * + * Energy net which keeps its target from moving until it is destroyed. Used to send + * players to a holding area in which they could never leave, but such feature has since + * been removed. + */ +/obj/structure/energy_net + name = "energy net" + desc = "It's a net made of green energy." + icon = 'icons/effects/effects.dmi' + icon_state = "energynet" + + + density = TRUE//Can't pass through. + opacity = FALSE //Can see through. + mouse_opacity = MOUSE_OPACITY_ICON//So you can hit it with stuff. + anchored = TRUE//Can't drag/grab the net. + layer = ABOVE_ALL_MOB_LAYER + max_integrity = 60 //How much health it has. + can_buckle = 1 + buckle_lying = 0 + buckle_prevents_pull = TRUE + ///The creature currently caught in the net + var/mob/living/affecting + +/obj/structure/energy_net/play_attack_sound(damage, damage_type = BRUTE, damage_flag = 0) + if(damage_type == BRUTE || damage_type == BURN) + playsound(src, 'sound/weapons/slash.ogg', 80, TRUE) + +/obj/structure/energy_net/Destroy() + if(!QDELETED(affecting)) + affecting.visible_message("[affecting.name] is recovered from the energy net!", "You are recovered from the energy net!", "You hear a grunt.") + affecting = null + return ..() + +/obj/structure/energy_net/attack_paw(mob/user) + return attack_hand() + +/obj/structure/energy_net/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE) + return//We only want our target to be buckled + +/obj/structure/energy_net/user_unbuckle_mob(mob/living/buckled_mob, mob/living/user) + return//The net must be destroyed to free the target diff --git a/code/modules/ninja/suit/ninja_equipment_actions/ninja_adrenaline.dm b/code/modules/ninja/suit/ninja_equipment_actions/ninja_adrenaline.dm new file mode 100644 index 0000000000..0b64f35f0c --- /dev/null +++ b/code/modules/ninja/suit/ninja_equipment_actions/ninja_adrenaline.dm @@ -0,0 +1,38 @@ +//Wakes the user so they are able to do their thing. Also injects a decent dose of radium. +//Movement impairing would indicate drugs and the like. + +/datum/action/item_action/ninjaboost + check_flags = NONE + name = "Adrenaline Boost" + desc = "Inject a secret chemical that will counteract all movement-impairing effect." + button_icon_state = "adrenal" + icon_icon = 'icons/obj/implants.dmi' + required_mobility_flags = NONE + +/** + * Proc called to activate space ninja's adrenaline. + * + * Proc called to use space ninja's adrenaline. Gets the ninja out of almost any stun. + * Also makes them shout MGS references when used. After a bit, it injects the user with + * radium by calling a different proc. + */ +/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost() + if(ninjacost(0,N_ADRENALINE)) + return + var/mob/living/carbon/human/ninja = affecting + ninja.do_adrenaline(150, TRUE, 0, 0, TRUE, list(/datum/reagent/medicine/epinephrine = 3, /datum/reagent/medicine/regen_jelly = 10, /datum/reagent/medicine/stimulants = 2), "You feel a sudden surge of energy!") + ninja.say(pick("A CORNERED FOX IS MORE DANGEROUS THAN A JACKAL!","HURT ME MOOORRREEE!","IMPRESSIVE!"), forced = "ninjaboost") + a_boost = FALSE + to_chat(ninja, "You have used the adrenaline boost.") + addtimer(CALLBACK(src, .proc/ninjaboost_after), 70) + +/** + * Proc called to inject the ninja with radium. + * + * Used after 7 seconds of using the ninja's adrenaline. + * Injects the user with how much radium the suit needs to refill an adrenaline boost. + */ +/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost_after() + var/mob/living/carbon/human/ninja = affecting + ninja.reagents.add_reagent(/datum/reagent/radium, a_transfer * 0.25) + to_chat(ninja, "You are beginning to feel the after-effect of the injection.") diff --git a/code/modules/ninja/suit/ninja_equipment_actions/ninja_cost_check.dm b/code/modules/ninja/suit/ninja_equipment_actions/ninja_cost_check.dm new file mode 100644 index 0000000000..7fb9d9dbf6 --- /dev/null +++ b/code/modules/ninja/suit/ninja_equipment_actions/ninja_cost_check.dm @@ -0,0 +1,28 @@ +/** + * Proc called to check if the ninja can afford an ability's cost. + * + * Proc which determine whether or not a space ninja can afford to use a specific ability. + * It can also cancel stealth if the ability requested it. + * Arguments: + * * cost - the energy cost of the ability + * * specificCheck - Determines if the check is a normal one, an adrenaline one, or a stealth cancel check. + * * Returns TRUE or the current cooldown timer if we can't perform the ability, and FALSE if we can. + */ +/obj/item/clothing/suit/space/space_ninja/proc/ninjacost(cost = 0, specificCheck = 0) + var/mob/living/carbon/human/ninja = affecting + var/actualCost = cost*10 + if(cost && cell.charge < actualCost) + to_chat(ninja, "Not enough energy!") + return TRUE + else + //This shit used to be handled individually on every proc.. why even bother with a universal check proc then? + cell.charge-=(actualCost) + + switch(specificCheck) + if(N_STEALTH_CANCEL) + cancel_stealth()//Get rid of it. + if(N_ADRENALINE) + if(!a_boost) + to_chat(ninja, "You do not have any more adrenaline boosters!") + return TRUE + return (s_coold)//Returns the value of the variable which counts down to zero. diff --git a/code/modules/ninja/suit/ninja_equipment_actions/ninja_empulse.dm b/code/modules/ninja/suit/ninja_equipment_actions/ninja_empulse.dm new file mode 100644 index 0000000000..ea2341a132 --- /dev/null +++ b/code/modules/ninja/suit/ninja_equipment_actions/ninja_empulse.dm @@ -0,0 +1,21 @@ +//Disables nearby tech equipment. + +/datum/action/item_action/ninjapulse + name = "EM Burst (50E)" + desc = "Disable any nearby technology with an electro-magnetic pulse." + button_icon_state = "emp" + icon_icon = 'icons/mob/actions/actions_spells.dmi' + +/** + * Proc called to allow the ninja to EMP the nearby area. + * + * Proc called to allow the ninja to EMP the nearby area. By default, costs 500E, which is half of the default battery's max charge. + * Also affects the ninja as well. + */ +/obj/item/clothing/suit/space/space_ninja/proc/ninjapulse() + if(ninjacost(500,N_STEALTH_CANCEL)) + return + var/mob/living/carbon/human/H = affecting + playsound(H.loc, 'sound/effects/empulse.ogg', 60, 2) + empulse(H, 4, 6) //Procs sure are nice. Slightly weaker than wizard's disable tch. + s_coold = 4 diff --git a/code/modules/ninja/suit/ninja_equipment_actions/ninja_glove_toggle.dm b/code/modules/ninja/suit/ninja_equipment_actions/ninja_glove_toggle.dm new file mode 100644 index 0000000000..ec5bf078a5 --- /dev/null +++ b/code/modules/ninja/suit/ninja_equipment_actions/ninja_glove_toggle.dm @@ -0,0 +1,15 @@ +/datum/action/item_action/toggle_glove + name = "Toggle interaction" + desc = "Switch between normal interaction and drain mode." + button_icon_state = "s-ninjan" + icon_icon = 'icons/obj/clothing/gloves.dmi' + +/** + * Proc called to toggle the ninja glove's special abilities. + * + * Used to toggle whether or not the ninja glove's abilities will activate on touch. + */ +/obj/item/clothing/gloves/space_ninja/proc/toggledrain() + var/mob/living/carbon/human/ninja = loc + to_chat(ninja, "You [candrain?"disable":"enable"] special interaction.") + candrain=!candrain diff --git a/code/modules/ninja/suit/ninja_equipment_actions/ninja_net.dm b/code/modules/ninja/suit/ninja_equipment_actions/ninja_net.dm new file mode 100644 index 0000000000..ab52f3e018 --- /dev/null +++ b/code/modules/ninja/suit/ninja_equipment_actions/ninja_net.dm @@ -0,0 +1,36 @@ +/datum/action/item_action/ninjanet + name = "Energy Net (40E)" + desc = "Captures a fallen opponent in a net of energy." + button_icon_state = "energynet" + icon_icon = 'icons/effects/effects.dmi' + +/** + * Proc called to ensnare a person in a energy net. + * + * Used to ensnare a target in an energy net, preventing them from moving until the net is broken. + * Costs 40E, which is 40% of the default battery's max charge. Intended as a means of reliably locking down an opponent when ninja stars won't suffice. + */ +/obj/item/clothing/suit/space/space_ninja/proc/ninjanet() + var/mob/living/carbon/human/ninja = affecting + var/mob/living/net_target = input("Select who to capture:","Capture who?",null) as null|mob in sortNames(oview(ninja)) + + if(QDELETED(net_target)||!(net_target in oview(ninja))) + return + + if(locate(/obj/structure/energy_net) in get_turf(net_target))//Check if they are already being affected by an energy net. + to_chat(ninja, "[net_target.p_they(TRUE)] are already trapped inside an energy net!") + return + for(var/turf/between_turf in getline(get_turf(ninja), get_turf(net_target))) + if(between_turf.density)//Don't want them shooting nets through walls. It's kind of cheesy. + to_chat(ninja, "You may not use an energy net through solid obstacles!") + return + if(!ninjacost(400,N_STEALTH_CANCEL)) + ninja.Beam(net_target, "n_beam", time = 15) + ninja.say("Get over here!", forced = "ninja net") + var/obj/structure/energy_net/net = new /obj/structure/energy_net(net_target.drop_location()) + net.affecting = net_target + ninja.visible_message("[ninja] caught [net_target] with an energy net!","You caught [net_target] with an energy net!") + + if(net_target.buckled) + net_target.buckled.unbuckle_mob(affecting,TRUE) + net.buckle_mob(net_target, TRUE) //No moving for you! diff --git a/code/modules/ninja/suit/ninja_equipment_actions/ninja_stars.dm b/code/modules/ninja/suit/ninja_equipment_actions/ninja_stars.dm new file mode 100644 index 0000000000..ef897d5bb9 --- /dev/null +++ b/code/modules/ninja/suit/ninja_equipment_actions/ninja_stars.dm @@ -0,0 +1,46 @@ +/datum/action/item_action/ninjastar + name = "Create Throwing Stars (1E)" + desc = "Creates a throwing star in your hand, if possible." + button_icon_state = "throwingstar" + icon_icon = 'icons/obj/items_and_weapons.dmi' + +/** + * Proc called to create a ninja star in the ninja's hands. + * + * Called to create a ninja star in the wearer's hand. The ninja + * star doesn't do much up-front damage, but deals stamina damage + * as the target moves around, forcing a finish or flee scenario. + */ +/obj/item/clothing/suit/space/space_ninja/proc/ninjastar() + if(ninjacost(10)) + return + var/mob/living/carbon/human/ninja = affecting + var/obj/item/throwing_star/stamina/ninja/ninja_star = new(ninja) + if(ninja.put_in_hands(ninja_star)) + to_chat(ninja, "A throwing star has been created in your hand!") + else + qdel(ninja_star) + to_chat(ninja, "You can't create a throwing star, your hands are full!") + ninja.throw_mode_on() //So they can quickly throw it. + +/** + * # Ninja Throwing Star + * + * a throwing star which specifically makes sure you know it came from a real ninja. + * + * The most important item in the entire codebase, as without it we would all cease to exist. + * Inherits everything that makes it interesting the stamina throwing star, but the most + * important change made is that its name specifically has the prefix, 'ninja' in it. + * This provides the detective role with information to play off of by ensuring that his + * assumption that a space ninja is aboard the ship to be true when he find 20 of these in + * the captain's back. Along with this, its throwforce is 10 instead of the 5 of the stamina + * throwing star, meaning it'll do a little more damage than the stamina throwing star does as well. + * Changes to this item need to be approved by all maintainers, so if you do change it, make sure + * you go through the proper channels, lest you get permabanned. Do I make myself clear? + */ +/obj/item/throwing_star/stamina/ninja + name = "ninja throwing star" + icon_state = "ninjastar" + item_state = "ninjastar" + throwforce = 10 + embedding = list("pain_chance" = 5, "embed_chance" = 100, "fall_chance" = 10, "jostle_chance" = 10, "pain_stam_pct" = 2.5, "jostle_pain_mult" = 3) diff --git a/code/modules/ninja/suit/ninja_equipment_actions/ninja_status_read.dm b/code/modules/ninja/suit/ninja_equipment_actions/ninja_status_read.dm new file mode 100644 index 0000000000..33e6b1ae26 --- /dev/null +++ b/code/modules/ninja/suit/ninja_equipment_actions/ninja_status_read.dm @@ -0,0 +1,7 @@ +/datum/action/item_action/ninjastatus + check_flags = NONE + name = "Status Readout" + desc = "Gives a detailed readout about your current status." + button_icon_state = "health" + icon_icon = 'icons/obj/device.dmi' + var/action_background_icon_state = "bg_default_on" diff --git a/code/modules/ninja/suit/ninja_equipment_actions/ninja_stealth.dm b/code/modules/ninja/suit/ninja_equipment_actions/ninja_stealth.dm new file mode 100644 index 0000000000..079f0c53e9 --- /dev/null +++ b/code/modules/ninja/suit/ninja_equipment_actions/ninja_stealth.dm @@ -0,0 +1,46 @@ +/datum/action/item_action/ninja_stealth + name = "Toggle Stealth" + desc = "Toggles stealth mode on and off." + button_icon_state = "ninja_cloak" + icon_icon = 'icons/mob/actions/actions_minor_antag.dmi' + +/** + * Proc called to toggle ninja stealth. + * + * Proc called to toggle whether or not the ninja is in stealth mode. + * If cancelling, calls a separate proc in case something else needs to quickly cancel stealth. + */ +/obj/item/clothing/suit/space/space_ninja/proc/toggle_stealth() + var/mob/living/carbon/human/ninja = affecting + if(!ninja) + return + if(stealth) + cancel_stealth() + else + if(cell.charge <= 0) + to_chat(ninja, "You don't have enough power to enable Stealth!") + return + stealth = !stealth + animate(ninja, alpha = 20,time = 12) + ninja.visible_message("[ninja.name] vanishes into thin air!", \ + "You are now mostly invisible to normal detection.") + +/** + * Proc called to cancel stealth. + * + * Called to cancel the stealth effect if it is ongoing. + * Does nothing otherwise. + * Arguments: + * * Returns false if either the ninja no longer exists or is already visible, returns true if we successfully made the ninja visible. + */ +/obj/item/clothing/suit/space/space_ninja/proc/cancel_stealth() + var/mob/living/carbon/human/ninja = affecting + if(!ninja) + return FALSE + if(stealth) + stealth = !stealth + animate(ninja, alpha = 255, time = 12) + ninja.visible_message("[ninja.name] appears from thin air!", \ + "You are now visible.") + return TRUE + return FALSE diff --git a/code/modules/ninja/suit/ninja_equipment_actions/ninja_suit_initialisation.dm b/code/modules/ninja/suit/ninja_equipment_actions/ninja_suit_initialisation.dm new file mode 100644 index 0000000000..c1a3c77814 --- /dev/null +++ b/code/modules/ninja/suit/ninja_equipment_actions/ninja_suit_initialisation.dm @@ -0,0 +1,123 @@ +#define NINJA_LOCK_PHASE 1 +#define NINJA_ICON_GENERATE_PHASE 3 +#define NINJA_COMPLETE_PHASE 6 +#define NINJA_DEINIT_LOGOFF_PHASE 1 +#define NINJA_DEINIT_STEALTH_PHASE 5 + +GLOBAL_LIST_INIT(ninja_initialize_messages, list( + "Now initializing...", + "Securing external locking mechanism...\nNeural-net established.", + "Extending neural-net interface...\nNow monitoring brain wave pattern...", + "Linking neural-net interface...\nPattern GREEN, continuing operation.", + "VOID-shift device status: ONLINE.\nCLOAK-tech device status: ONLINE.", + "Primary system status: ONLINE.\nBackup system status: ONLINE.\nCurrent energy capacity: ", + "All systems operational. Welcome to SpiderOS, " +)) + +GLOBAL_LIST_INIT(ninja_deinitialize_messages, list( + "Now de-initializing...", + "Shutting down SpiderOS.", + "Primary system status: OFFLINE.\nBackup system status: OFFLINE.", + "VOID-shift device status: OFFLINE.\nCLOAK-tech device status: OFFLINE.", + "Disconnecting neural-net interface...Success.", + "Disengaging neural-net interface... Success.", + "Unsecuring external locking mechanism...\nNeural-net abolished.\nOperation status: FINISHED." +)) + +/datum/action/item_action/initialize_ninja_suit + name = "Toggle Ninja Suit" + +/** + * Toggles the ninja suit on/off + * + * Attempts to initialize or deinitialize the ninja suit + */ +/obj/item/clothing/suit/space/space_ninja/proc/toggle_on_off() + . = TRUE + if(s_busy) + to_chat(loc, "ERROR: You cannot use this function at this time.") + return FALSE + s_busy = TRUE + if(s_initialized) + deinitialize() + else + ninitialize() + +/** + * Initializes the ninja suit + * + * Initializes the ninja suit through seven phases, each of which calls this proc with an incremented phase + * Arguments: + * * delay - The delay between each phase of initialization + * * ninja - The human who is being affected by the suit + * * phase - The phase of initialization + */ +/obj/item/clothing/suit/space/space_ninja/proc/ninitialize(delay = s_delay, mob/living/carbon/human/ninja = loc, phase = 0) + if(!ninja || !ninja.mind) + s_busy = FALSE + return + if (phase > NINJA_LOCK_PHASE && (ninja.stat == DEAD || ninja.health <= 0)) + to_chat(ninja, "FĆAL �Rr�R: 344--93#�&&21 BR��N |/|/aV� PATT$RN RED\nA-A-aB�rT�NG...") + unlock_suit(ninja) + s_busy = FALSE + return + + var/message = GLOB.ninja_initialize_messages[phase + 1] + switch(phase) + if (NINJA_LOCK_PHASE) + if(!lock_suit(ninja))//To lock the suit onto wearer. + s_busy = FALSE + return + if (NINJA_COMPLETE_PHASE - 1) + message += "[DisplayEnergy(cell.charge)]." + if (NINJA_COMPLETE_PHASE) + message += "[ninja.real_name]." + ninja.regenerate_icons() + s_initialized = TRUE + s_busy = FALSE + + to_chat(ninja, "[message]") + playsound(ninja, 'sound/effects/sparks1.ogg', 10, TRUE) + + if (phase < NINJA_COMPLETE_PHASE) + addtimer(CALLBACK(src, .proc/ninitialize, delay, ninja, phase + 1), delay) + +/** + * Deinitializes the ninja suit + * + * Deinitializes the ninja suit through eight phases, each of which calls this proc with an incremented phase + * Arguments: + * * delay - The delay between each phase of deinitialization + * * ninja - The human who is being affected by the suit + * * phase - The phase of deinitialization + */ +/obj/item/clothing/suit/space/space_ninja/proc/deinitialize(delay = s_delay, mob/living/carbon/human/ninja = affecting == loc ? affecting : null, phase = 0) + if (!ninja || !ninja.mind) + s_busy = FALSE + return + if (phase == 0 && alert("Are you certain you wish to remove the suit? This will take time and remove all abilities.",,"Yes","No") == "No") + s_busy = FALSE + return + + var/message = GLOB.ninja_deinitialize_messages[phase + 1] + switch(phase) + if(NINJA_DEINIT_LOGOFF_PHASE) + message = "Logging off, [ninja.real_name]. " + message + if(NINJA_DEINIT_STEALTH_PHASE) + cancel_stealth() + to_chat(ninja, "[message]") + playsound(ninja, 'sound/items/deconstruct.ogg', 10, TRUE) + + if (phase < NINJA_COMPLETE_PHASE) + addtimer(CALLBACK(src, .proc/deinitialize, delay, ninja, phase + 1), delay) + else + unlock_suit(ninja) + ninja.regenerate_icons() + s_initialized = FALSE + s_busy = FALSE + +#undef NINJA_LOCK_PHASE +#undef NINJA_ICON_GENERATE_PHASE +#undef NINJA_COMPLETE_PHASE +#undef NINJA_DEINIT_LOGOFF_PHASE +#undef NINJA_DEINIT_STEALTH_PHASE diff --git a/code/modules/ninja/suit/ninja_equipment_actions/ninja_sword_recall.dm b/code/modules/ninja/suit/ninja_equipment_actions/ninja_sword_recall.dm new file mode 100644 index 0000000000..dd6ca61f88 --- /dev/null +++ b/code/modules/ninja/suit/ninja_equipment_actions/ninja_sword_recall.dm @@ -0,0 +1,48 @@ +/datum/action/item_action/ninja_sword_recall + name = "Recall Energy Katana (Variable Cost)" + desc = "Teleports the Energy Katana linked to this suit to its wearer, cost based on distance." + button_icon_state = "energy_katana" + icon_icon = 'icons/obj/items_and_weapons.dmi' + +/** + * Proc called to recall the ninja's sword. + * + * Called to summon the ninja's katana back to them + * If the katana can see the ninja, it will throw itself towards them. + * If not, the katana will teleport itself to the ninja. + */ +/obj/item/clothing/suit/space/space_ninja/proc/ninja_sword_recall() + var/mob/living/carbon/human/ninja = affecting + var/cost = 0 + var/inview = TRUE + + if(!energyKatana) + to_chat(ninja, "Could not locate Energy Katana!") + return + + if(energyKatana in ninja) + return + + var/distance = get_dist(ninja,energyKatana) + + if(!(energyKatana in view(ninja))) + cost = distance //Actual cost is cost x 10, so 5 turfs is 50 cost. + inview = FALSE + + if(!ninjacost(cost)) + if(iscarbon(energyKatana.loc)) + var/mob/living/carbon/sword_holder = energyKatana.loc + sword_holder.transferItemToLoc(energyKatana, get_turf(energyKatana), TRUE) + + else + energyKatana.forceMove(get_turf(energyKatana)) + + if(inview) //If we can see the katana, throw it towards ourselves, damaging people as we go. + energyKatana.spark_system.start() + playsound(ninja, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + ninja.visible_message("\the [energyKatana] flies towards [ninja]!","You hold out your hand and \the [energyKatana] flies towards you!") + energyKatana.throw_at(ninja, distance+1, energyKatana.throw_speed, ninja) + + else //Else just TP it to us. + energyKatana.returnToOwner(ninja, 1) + s_coold = 4 diff --git a/code/modules/ninja/suit/shoes.dm b/code/modules/ninja/suit/shoes.dm index f2227b5f9f..38ddd20eee 100644 --- a/code/modules/ninja/suit/shoes.dm +++ b/code/modules/ninja/suit/shoes.dm @@ -1,12 +1,21 @@ +/** + * # Ninja Shoes + * + * Space ninja's shoes. Gives him armor on his feet. + * + * Space ninja's ninja shoes. How mousey. Gives him slip protection and protection against attacks. + * Also are temperature resistant. + * + */ /obj/item/clothing/shoes/space_ninja name = "ninja shoes" desc = "A pair of running shoes. Excellent for running and even better for smashing skulls." icon_state = "s-ninja" + item_state = "s-ninja" permeability_coefficient = 0.01 clothing_flags = NOSLIP resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - armor = list("melee" = 60, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 100, "acid" = 100) - strip_delay = 120 + armor = list(MELEE = 40, BULLET = 30, LASER = 20,ENERGY = 30, BOMB = 30, BIO = 30, RAD = 30, FIRE = 100, ACID = 100) cold_protection = FEET min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT heat_protection = FEET @@ -14,7 +23,7 @@ /obj/item/clothing/shoes/space_ninja/equipped(mob/user, slot) . = ..() - if(slot == SLOT_SHOES) + if(slot == ITEM_SLOT_FEET) ADD_TRAIT(user, TRAIT_SILENT_STEP, SHOES_TRAIT) /obj/item/clothing/shoes/space_ninja/dropped(mob/user) diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm index 15071a186f..44ff5c7098 100644 --- a/code/modules/ninja/suit/suit.dm +++ b/code/modules/ninja/suit/suit.dm @@ -1,16 +1,13 @@ - -/* - -Contents: -- The Ninja Space Suit -- Ninja Space Suit Procs - -*/ - - -// /obj/item/clothing/suit/space/space_ninja - - +/** + * # Ninja Suit + * + * Space ninja's suit. Provides him with most of his powers. + * + * Space ninja's suit. Gives space ninja all his iconic powers, which are mostly kept in + * the folder ninja_equipment_actions. Has a lot of unique stuff going on, so make sure to check + * the variables. Check suit_attackby to see radium interaction, disk copying, and cell replacement. + * + */ /obj/item/clothing/suit/space/space_ninja name = "ninja suit" desc = "A unique, vacuum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins." @@ -19,12 +16,11 @@ Contents: allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/stock_parts/cell) slowdown = 1 resistance_flags = LAVA_PROOF | ACID_PROOF - armor = list("melee" = 60, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 100, "acid" = 100) - strip_delay = 12 + armor = list(MELEE = 40, BULLET = 30, LASER = 20,ENERGY = 30, BOMB = 30, BIO = 30, RAD = 30, FIRE = 100, ACID = 100) - actions_types = list(/datum/action/item_action/initialize_ninja_suit, /datum/action/item_action/ninjasmoke, /datum/action/item_action/ninjaboost, /datum/action/item_action/ninjapulse, /datum/action/item_action/ninjastar, /datum/action/item_action/ninja_sword_recall, /datum/action/item_action/ninja_stealth, /datum/action/item_action/toggle_glove) + actions_types = list(/datum/action/item_action/initialize_ninja_suit, /datum/action/item_action/ninjastatus, /datum/action/item_action/ninjaboost, /datum/action/item_action/ninjapulse, /datum/action/item_action/ninjastar, /datum/action/item_action/ninjanet, /datum/action/item_action/ninja_sword_recall, /datum/action/item_action/ninja_stealth) - //Important parts of the suit. + ///The person wearing the suit var/mob/living/carbon/human/affecting = null var/obj/item/stock_parts/cell/cell var/datum/effect_system/spark_spread/spark_system @@ -37,30 +33,40 @@ Contents: var/obj/item/clothing/shoes/space_ninja/n_shoes var/obj/item/clothing/gloves/space_ninja/n_gloves - //Main function variables. - var/s_initialized = 0//Suit starts off. - var/s_coold = 0//If the suit is on cooldown. Can be used to attach different cooldowns to abilities. Ticks down every second based on suit ntick(). - var/s_cost = 5//Base energy cost each ntick. - var/s_acost = 25//Additional cost for additional powers active. - var/s_delay = 40//How fast the suit does certain things, lower is faster. Can be overridden in specific procs. Also determines adverse probability. - var/a_transfer = 20//How much radium is used per adrenaline boost. - var/a_maxamount = 7//Maximum number of adrenaline boosts. - var/s_maxamount = 20//Maximum number of smoke bombs. + ///The space ninja's mask. + var/obj/item/clothing/mask/gas/space_ninja/n_mask - //Support function variables. + ///Whether or not the suit is currently booted up. Starts off. + var/s_initialized = FALSE//Suit starts off. + ///The suit's current cooldown. If not 0, blocks usage of most abilities, and decrements its value by 1 every process + var/s_coold = 0 + ///How much energy the suit expends in a single process + var/s_cost = 1 + ///Additional energy cost for cloaking per process + var/s_acost = 20 + ///How fast the suit is at certain actions, like draining power from things + var/s_delay = 40 + ///How fast the suit is at certain riskier actions, like hacking communications consoles. + var/s_longdelay = 200 + ///Units of radium required to refill the adrenaline boost + var/a_transfer = 20//How much radium is required to refill the adrenaline boost. + ///Whether or not the suit is currently in stealth mode. var/stealth = FALSE//Stealth off. - var/stealth_cooldown = 0 - var/s_busy = FALSE//Is the suit busy with a process? Like AI hacking. Used for safety functions. + ///Whether or not the wearer is in the middle of an action, like hacking. + var/s_busy = FALSE + ///Whether or not the adrenaline boost ability is available + var/a_boost = TRUE +/obj/item/clothing/suit/space/space_ninja/examine(mob/user) + . = ..() + if(!s_initialized) + return + if(!user == affecting) + return + . += "All systems operational. Current energy capacity: [DisplayEnergy(cell.charge)].\n"+\ + "The CLOAK-tech device is [stealth?"active":"inactive"].\n"+\ + "[a_boost?"An adrenaline boost is available to use.":"There is no adrenaline boost available. Try refilling the suit with 20 units of radium."]" - //Ability function variables. - var/s_bombs = 10//Number of smoke bombs. - var/a_boost = 3//Number of adrenaline boosters. - - -/obj/item/clothing/suit/space/space_ninja/get_cell() - return cell - -/obj/item/clothing/suit/space/space_ninja/Initialize() +/obj/item/clothing/suit/space/space_ninja/Initialize(mapload) . = ..() //Spark Init @@ -77,114 +83,158 @@ Contents: cell.name = "black power cell" cell.icon_state = "bscell" -/obj/item/clothing/suit/space/space_ninja/Destroy() - if(affecting) - unlock_suit() - return ..() +/obj/item/clothing/suit/space/space_ninja/Initialize(mapload) + START_PROCESSING(SSobj, src) + return ..() -//Simply deletes all the attachments and self, killing all related procs. +/obj/item/clothing/suit/space/space_ninja/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +// Power usage +/obj/item/clothing/suit/space/space_ninja/process(delta_time) + var/mob/living/carbon/human/user = src.loc + if(!user || !ishuman(user) || !(user.wear_suit == src)) + return + + // Check for energy usage + if(s_initialized) + if(!affecting) + terminate() // Kills the suit and attached objects. + else if(cell.charge > 0) + if(s_coold > 0) + s_coold = max(s_coold - delta_time, 0) // Checks for ability s_cooldown first. + cell.charge -= s_cost * delta_time // s_cost is the default energy cost each ntick, usually 5. + if(stealth) // If stealth is active. + cell.charge -= s_acost * delta_time + else + cell.charge = 0 + cancel_stealth() + +/obj/item/clothing/suit/space/space_ninja/ui_action_click(mob/user, action) + if(IS_NINJA_SUIT_INITIALIZATION(action)) + toggle_on_off() + return TRUE + if(!s_initialized) + to_chat(user, "ERROR: suit offline. Please activate suit.") + return FALSE + if(s_coold > 0) + to_chat(user, "ERROR: suit is on cooldown.") + return FALSE + if(IS_NINJA_SUIT_BOOST(action)) + ninjaboost() + return TRUE + if(IS_NINJA_SUIT_EMP(action)) + ninjapulse() + return TRUE + if(IS_NINJA_SUIT_STAR_CREATION(action)) + ninjastar() + return TRUE + if(IS_NINJA_SUIT_NET_CREATION(action)) + ninjanet() + return TRUE + if(IS_NINJA_SUIT_SWORD_RECALL(action)) + ninja_sword_recall() + return TRUE + if(IS_NINJA_SUIT_STEALTH(action)) + toggle_stealth() + return TRUE + return FALSE + +/obj/item/clothing/suit/space/space_ninja/run_block(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = ATTACK_TYPE_MELEE) + . = ..() + if(stealth) + cancel_stealth() + s_coold = 5 + +/** + * Proc called to lock the important gear pieces onto space ninja's body. + * + * Called during the suit startup to lock all gear pieces onto space ninja. + * Terminates if a gear piece is not being worn. Also gives the ninja the inability to use firearms. + * If the person in the suit isn't a ninja when this is called, this proc just gibs them instead. + * Arguments: + * * ninja - The person wearing the suit. + * * Returns false if the locking fails due to lack of all suit parts, and true if it succeeds. + */ +/obj/item/clothing/suit/space/space_ninja/proc/lock_suit(mob/living/carbon/human/ninja) + if(!istype(ninja)) + return FALSE + if(!IS_SPACE_NINJA(ninja)) + to_chat(ninja, "fÄTaL ÈÈRRoR: 382200-*#00CÖDE RED\nUNAU†HORIZED USÈ DETÈC†††eD\nCoMMÈNCING SUB-R0U†IN3 13...\nTÈRMInATING U-U-USÈR...") + ninja.gib() + return FALSE + if(!istype(ninja.head, /obj/item/clothing/head/helmet/space/space_ninja)) + to_chat(ninja, "ERROR: 100113 UNABLE TO LOCATE HEAD GEAR\nABORTING...") + return FALSE + if(!istype(ninja.shoes, /obj/item/clothing/shoes/space_ninja)) + to_chat(ninja, "ERROR: 122011 UNABLE TO LOCATE FOOT GEAR\nABORTING...") + return FALSE + if(!istype(ninja.gloves, /obj/item/clothing/gloves/space_ninja)) + to_chat(ninja, "ERROR: 110223 UNABLE TO LOCATE HAND GEAR\nABORTING...") + return FALSE + affecting = ninja + ADD_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT) //colons make me go all |= + slowdown = 0 + icon_state = "s-ninjan" + n_hood = ninja.head + ADD_TRAIT(n_hood, TRAIT_NODROP, NINJA_SUIT_TRAIT) + n_shoes = ninja.shoes + ADD_TRAIT(n_shoes, TRAIT_NODROP, NINJA_SUIT_TRAIT) + n_shoes.slowdown-- + n_shoes.icon_state = "s-ninjan" + n_shoes.item_state = "s-ninjan" + n_gloves = ninja.gloves + ADD_TRAIT(n_gloves, TRAIT_NODROP, NINJA_SUIT_TRAIT) + n_gloves.icon_state = "s-ninjan" + n_gloves.item_state = "s-ninjan" + n_mask = ninja.wear_mask + n_mask.icon_state = "s-ninjan" + n_mask.item_state = "s-ninjan" + + ADD_TRAIT(ninja, TRAIT_NOGUNS, NINJA_SUIT_TRAIT) + return TRUE + +/** + * Proc called to unlock all the gear off space ninja's body. + * + * Proc which is essentially the opposite of lock_suit. Lets you take off all the suit parts. + * Also gets rid of the objection to using firearms from the wearer. + * Arguments: + * * ninja - The person wearing the suit. + */ +/obj/item/clothing/suit/space/space_ninja/proc/unlock_suit(mob/living/carbon/human/ninja) + affecting = null + REMOVE_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT) + slowdown = 1 + icon_state = "s-ninja" + if(n_hood)//Should be attached, might not be attached. + REMOVE_TRAIT(n_hood, TRAIT_NODROP, NINJA_SUIT_TRAIT) + n_hood.icon_state = "s-ninja" + if(n_shoes) + REMOVE_TRAIT(n_shoes, TRAIT_NODROP, NINJA_SUIT_TRAIT) + n_shoes.slowdown++ + n_shoes.icon_state = "s-ninja" + n_shoes.item_state = "s-ninja" + if(n_gloves) + n_gloves.icon_state = "s-ninja" + n_gloves.item_state = "s-ninja" + REMOVE_TRAIT(n_gloves, TRAIT_NODROP, NINJA_SUIT_TRAIT) + n_gloves.candrain = FALSE + n_gloves.draining = FALSE + if(n_mask) + n_mask.icon_state = "s-ninja" + n_mask.item_state = "s-ninja" + + REMOVE_TRAIT(ninja, TRAIT_NOGUNS, NINJA_SUIT_TRAIT) + +/** + * Proc used to delete all the attachments and itself. + * + * Can be called to entire rid of the suit pieces and the suit itself. + */ /obj/item/clothing/suit/space/space_ninja/proc/terminate() qdel(n_hood) qdel(n_gloves) qdel(n_shoes) qdel(src) - -//Randomizes suit parameters. -/obj/item/clothing/suit/space/space_ninja/proc/randomize_param() - s_cost = rand(1,20) - s_acost = rand(20,100) - s_delay = rand(10,100) - s_bombs = rand(5,20) - a_boost = rand(1,7) - -//This proc prevents the suit from being taken off. -/obj/item/clothing/suit/space/space_ninja/proc/lock_suit(mob/living/carbon/human/H) - if(!istype(H)) - return FALSE - if(!is_ninja(H)) - to_chat(H, "fÄTaL ÈÈRRoR: 382200-*#00CÖDE RED\nUNAU†HORIZED USÈ DETÈC†††eD\nCoMMÈNCING SUB-R0U†IN3 13...\nTÈRMInATING U-U-USÈR...") - H.gib() - return FALSE - if(!istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja)) - to_chat(H, "ERROR: 100113 UNABLE TO LOCATE HEAD GEAR\nABORTING...") - return FALSE - if(!istype(H.shoes, /obj/item/clothing/shoes/space_ninja)) - to_chat(H, "ERROR: 122011 UNABLE TO LOCATE FOOT GEAR\nABORTING...") - return FALSE - if(!istype(H.gloves, /obj/item/clothing/gloves/space_ninja)) - to_chat(H, "ERROR: 110223 UNABLE TO LOCATE HAND GEAR\nABORTING...") - return FALSE - affecting = H - ADD_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT) //colons make me go all |= - n_hood = H.head - ADD_TRAIT(n_hood, TRAIT_NODROP, NINJA_SUIT_TRAIT) - n_shoes = H.shoes - ADD_TRAIT(n_shoes, TRAIT_NODROP, NINJA_SUIT_TRAIT) - n_shoes.slowdown = -0.25 - n_gloves = H.gloves - ADD_TRAIT(n_gloves, TRAIT_NODROP, NINJA_SUIT_TRAIT) - ADD_TRAIT(affecting, TRAIT_TASED_RESISTANCE, NINJA_SUIT_TRAIT) - return TRUE - -/obj/item/clothing/suit/space/space_ninja/proc/lockIcons(mob/living/carbon/human/H) - icon_state = H.dna.features["body_model"] == FEMALE ? "s-ninjanf" : "s-ninjan" - H.gloves.icon_state = "s-ninjan" - H.gloves.item_state = "s-ninjan" - - -//This proc allows the suit to be taken off. -/obj/item/clothing/suit/space/space_ninja/proc/unlock_suit() - affecting = null - REMOVE_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT) - icon_state = "s-ninja" - if(n_hood)//Should be attached, might not be attached. - REMOVE_TRAIT(n_hood, TRAIT_NODROP, NINJA_SUIT_TRAIT) - if(n_shoes) - REMOVE_TRAIT(n_shoes, TRAIT_NODROP, NINJA_SUIT_TRAIT) - n_shoes.slowdown = 0.25 - if(n_gloves) - n_gloves.icon_state = "s-ninja" - n_gloves.item_state = "s-ninja" - REMOVE_TRAIT(n_gloves, TRAIT_NODROP, NINJA_SUIT_TRAIT) - n_gloves.candrain=0 - n_gloves.draining=0 - REMOVE_TRAIT(affecting, TRAIT_TASED_RESISTANCE, NINJA_SUIT_TRAIT) - - -/obj/item/clothing/suit/space/space_ninja/examine(mob/user) - . = ..() - if(s_initialized && user == affecting) - . += "All systems operational. Current energy capacity: [DisplayEnergy(cell.charge)].\n\ - The CLOAK-tech device is [stealth?"active":"inactive"].\n\ - There are [s_bombs] smoke bomb\s remaining.\n\ - There are [a_boost] adrenaline booster\s remaining." - -/obj/item/clothing/suit/space/space_ninja/ui_action_click(mob/user, action) - if(istype(action, /datum/action/item_action/initialize_ninja_suit)) - toggle_on_off() - return TRUE - if(!s_initialized) - to_chat(user, "ERROR: suit offline. Please activate suit.") - return FALSE - if(istype(action, /datum/action/item_action/ninjasmoke)) - ninjasmoke() - return TRUE - if(istype(action, /datum/action/item_action/ninjaboost)) - ninjaboost() - return TRUE - if(istype(action, /datum/action/item_action/ninjapulse)) - ninjapulse() - return TRUE - if(istype(action, /datum/action/item_action/ninjastar)) - ninjastar() - return TRUE - if(istype(action, /datum/action/item_action/ninja_sword_recall)) - ninja_sword_recall() - return TRUE - if(istype(action, /datum/action/item_action/ninja_stealth)) - stealth() - return TRUE - if(istype(action, /datum/action/item_action/toggle_glove)) - n_gloves.toggledrain() - return TRUE - return FALSE diff --git a/code/modules/ninja/suit/suit_attackby.dm b/code/modules/ninja/suit/suit_attackby.dm index ed920a57d1..75d438a35f 100644 --- a/code/modules/ninja/suit/suit_attackby.dm +++ b/code/modules/ninja/suit/suit_attackby.dm @@ -1,52 +1,44 @@ - - -/obj/item/clothing/suit/space/space_ninja/attackby(obj/item/I, mob/U, params) - if(U!=affecting)//Safety, in case you try doing this without wearing the suit/being the person with the suit. +/obj/item/clothing/suit/space/space_ninja/attackby(obj/item/I, mob/ninja, params) + if(ninja!=affecting)//Safety, in case you try doing this without wearing the suit/being the person with the suit. return ..() - if(istype(I, /obj/item/reagent_containers/glass))//If it's a glass beaker. - if(I.reagents.has_reagent(/datum/reagent/radium, a_transfer) && a_boost < a_maxamount) - I.reagents.remove_reagent(/datum/reagent/radium, a_transfer) - a_boost++; - to_chat(U, "There are now [a_boost] adrenaline boosts remaining.") - return - if(I.reagents.has_reagent(/datum/reagent/smoke_powder, a_transfer) && s_bombs < s_maxamount) - I.reagents.remove_reagent(/datum/reagent/smoke_powder, a_transfer) - s_bombs++; - to_chat(U, "There are now [s_bombs] smoke bombs remaining.") - return + if(istype(I, /obj/item/reagent_containers/glass) && I.reagents.has_reagent(/datum/reagent/radium, a_transfer) && a_boost != TRUE)//If it's a glass beaker, and what we're transferring is radium. + I.reagents.remove_reagent(/datum/reagent/radium, a_transfer) + a_boost = TRUE; + to_chat(ninja, "The suit's adrenaline boost is now reloaded.") + return else if(istype(I, /obj/item/stock_parts/cell)) var/obj/item/stock_parts/cell/CELL = I if(CELL.maxcharge > cell.maxcharge && n_gloves && n_gloves.candrain) - to_chat(U, "Higher maximum capacity detected.\nUpgrading...") - if (n_gloves && n_gloves.candrain && do_after(U,s_delay, target = src)) - U.transferItemToLoc(CELL, src) + to_chat(ninja, "Higher maximum capacity detected.\nUpgrading...") + if (n_gloves?.candrain && do_after(ninja,s_delay, target = src)) + ninja.transferItemToLoc(CELL, src) CELL.charge = min(CELL.charge+cell.charge, CELL.maxcharge) var/obj/item/stock_parts/cell/old_cell = cell old_cell.charge = 0 - U.put_in_hands(old_cell) - old_cell.add_fingerprint(U) + ninja.put_in_hands(old_cell) + old_cell.add_fingerprint(ninja) old_cell.corrupt() old_cell.update_icon() cell = CELL - to_chat(U, "Upgrade complete. Maximum capacity: [round(cell.maxcharge/100)]%") + to_chat(ninja, "Upgrade complete. Maximum capacity: [round(cell.maxcharge/100)]%") else - to_chat(U, "Procedure interrupted. Protocol terminated.") + to_chat(ninja, "Procedure interrupted. Protocol terminated.") return else if(istype(I, /obj/item/disk/tech_disk))//If it's a data disk, we want to copy the research on to the suit. var/obj/item/disk/tech_disk/TD = I var/has_research = 0 if(has_research)//If it has something on it. - to_chat(U, "Research information detected, processing...") - if(do_after(U,s_delay, target = src)) + to_chat(ninja, "Research information detected, processing...") + if(do_after(ninja,s_delay, target = src)) TD.stored_research.copy_research_to(stored_research) - to_chat(U, "Data analyzed and updated. Disk erased.") + to_chat(ninja, "Data analyzed and updated. Disk erased.") else - to_chat(U, "ERROR: Procedure interrupted. Process terminated.") + to_chat(ninja, "ERROR: Procedure interrupted. Process terminated.") else - to_chat(U, "No research information detected.") + to_chat(ninja, "No research information detected.") return return ..() diff --git a/code/modules/ninja/suit/suit_initialisation.dm b/code/modules/ninja/suit/suit_initialisation.dm deleted file mode 100644 index 3d80282fe7..0000000000 --- a/code/modules/ninja/suit/suit_initialisation.dm +++ /dev/null @@ -1,95 +0,0 @@ -/obj/item/clothing/suit/space/space_ninja/proc/toggle_on_off() - if(s_busy) - to_chat(loc, "ERROR: You cannot use this function at this time.") - return FALSE - if(s_initialized) - deinitialize() - else - ninitialize() - . = TRUE - -/obj/item/clothing/suit/space/space_ninja/proc/ninitialize(delay = s_delay, mob/living/carbon/human/U = loc) - if(!U.mind) - return //Not sure how this could happen. - s_busy = TRUE - to_chat(U, "Now initializing...") - addtimer(CALLBACK(src, .proc/ninitialize_two, delay, U), delay) - -/obj/item/clothing/suit/space/space_ninja/proc/ninitialize_two(delay, mob/living/carbon/human/U) - if(!lock_suit(U))//To lock the suit onto wearer. - s_busy = FALSE - return - to_chat(U, "Securing external locking mechanism...\nNeural-net established.") - addtimer(CALLBACK(src, .proc/ninitialize_three, delay, U), delay) - -/obj/item/clothing/suit/space/space_ninja/proc/ninitialize_three(delay, mob/living/carbon/human/U) - to_chat(U, "Extending neural-net interface...\nNow monitoring brain wave pattern...") - addtimer(CALLBACK(src, .proc/ninitialize_four, delay, U), delay) - -/obj/item/clothing/suit/space/space_ninja/proc/ninitialize_four(delay, mob/living/carbon/human/U) - if(U.stat == DEAD|| U.health <= 0) - to_chat(U, "FĆAL �Rr�R: 344--93#�&&21 BR��N |/|/aV� PATT$RN RED\nA-A-aB�rT�NG...") - unlock_suit() - s_busy = FALSE - return - lockIcons(U)//Check for icons. - U.regenerate_icons() - to_chat(U, "Linking neural-net interface...\nPattern\green GREEN, continuing operation.") - addtimer(CALLBACK(src, .proc/ninitialize_five, delay, U), delay) - -/obj/item/clothing/suit/space/space_ninja/proc/ninitialize_five(delay, mob/living/carbon/human/U) - to_chat(U, "VOID-shift device status: ONLINE.\nCLOAK-tech device status: ONLINE.") - addtimer(CALLBACK(src, .proc/ninitialize_six, delay, U), delay) - -/obj/item/clothing/suit/space/space_ninja/proc/ninitialize_six(delay, mob/living/carbon/human/U) - to_chat(U, "Primary system status: ONLINE.\nBackup system status: ONLINE.\nCurrent energy capacity: [DisplayEnergy(cell.charge)].") - addtimer(CALLBACK(src, .proc/ninitialize_seven, delay, U), delay) - -/obj/item/clothing/suit/space/space_ninja/proc/ninitialize_seven(delay, mob/living/carbon/human/U) - to_chat(U, "All systems operational. Welcome to SpiderOS, [U.real_name].") - s_initialized = TRUE - START_PROCESSING(SSprocessing, src) - s_busy = FALSE - - - -/obj/item/clothing/suit/space/space_ninja/proc/deinitialize(delay = s_delay) - if(affecting==loc) - var/mob/living/carbon/human/U = affecting - if(alert("Are you certain you wish to remove the suit? This will take time and remove all abilities.",,"Yes","No")=="No") - return - s_busy = TRUE - addtimer(CALLBACK(src, .proc/deinitialize_two, delay, U), delay) - -/obj/item/clothing/suit/space/space_ninja/proc/deinitialize_two(delay, mob/living/carbon/human/U) - to_chat(U, "Now de-initializing...") - addtimer(CALLBACK(src, .proc/deinitialize_three, delay, U), delay) - -/obj/item/clothing/suit/space/space_ninja/proc/deinitialize_three(delay, mob/living/carbon/human/U) - to_chat(U, "Logging off, [U.real_name]. Shutting down SpiderOS.") - addtimer(CALLBACK(src, .proc/deinitialize_four, delay, U), delay) - -/obj/item/clothing/suit/space/space_ninja/proc/deinitialize_four(delay, mob/living/carbon/human/U) - to_chat(U, "Primary system status: OFFLINE.\nBackup system status: OFFLINE.") - addtimer(CALLBACK(src, .proc/deinitialize_five, delay, U), delay) - -/obj/item/clothing/suit/space/space_ninja/proc/deinitialize_five(delay, mob/living/carbon/human/U) - to_chat(U, "VOID-shift device status: OFFLINE.\nCLOAK-tech device status: OFFLINE.") - cancel_stealth()//Shutdowns stealth. - addtimer(CALLBACK(src, .proc/deinitialize_six, delay, U), delay) - -/obj/item/clothing/suit/space/space_ninja/proc/deinitialize_six(delay, mob/living/carbon/human/U) - to_chat(U, "Disconnecting neural-net interface...\greenSuccess.") - addtimer(CALLBACK(src, .proc/deinitialize_seven, delay, U), delay) - -/obj/item/clothing/suit/space/space_ninja/proc/deinitialize_seven(delay, mob/living/carbon/human/U) - to_chat(U, "Disengaging neural-net interface...\greenSuccess.") - addtimer(CALLBACK(src, .proc/deinitialize_eight, delay, U), delay) - -/obj/item/clothing/suit/space/space_ninja/proc/deinitialize_eight(delay, mob/living/carbon/human/U) - to_chat(U, "Unsecuring external locking mechanism...\nNeural-net abolished.\nOperation status: FINISHED.") - unlock_suit() - U.regenerate_icons() - s_initialized = FALSE - STOP_PROCESSING(SSprocessing, src) - s_busy = FALSE diff --git a/code/modules/ninja/suit/suit_process.dm b/code/modules/ninja/suit/suit_process.dm deleted file mode 100644 index 5c1276e29a..0000000000 --- a/code/modules/ninja/suit/suit_process.dm +++ /dev/null @@ -1,17 +0,0 @@ -/obj/item/clothing/suit/space/space_ninja/process() - if(!affecting || !s_initialized) - return PROCESS_KILL - - if(cell.charge > 0) - if(s_coold) - s_coold--//Checks for ability s_cooldown first. - - cell.charge -= s_cost//s_cost is the default energy cost each tick, usually 5. - if(stealth && stealth_cooldown <= world.time)//If stealth is active. - cell.charge -= s_acost - affecting.alpha = max(affecting.alpha - 10, 15) - - else - cell.charge = 0 - if(stealth) - cancel_stealth() diff --git a/code/modules/paperwork/carbonpaper.dm b/code/modules/paperwork/carbonpaper.dm index 9a306333b3..afb5e9de2c 100644 --- a/code/modules/paperwork/carbonpaper.dm +++ b/code/modules/paperwork/carbonpaper.dm @@ -2,7 +2,7 @@ name = "sheet of carbon" icon_state = "paper_stack" item_state = "paper" - // inhand_icon_state = "paper" + // item_state = "paper" show_written_words = FALSE var/copied = FALSE var/iscopy = FALSE diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm index 13de7898c1..ed83a0f67b 100644 --- a/code/modules/paperwork/clipboard.dm +++ b/code/modules/paperwork/clipboard.dm @@ -1,127 +1,201 @@ +/** + * Clipboard + */ /obj/item/clipboard name = "clipboard" icon = 'icons/obj/bureaucracy.dmi' icon_state = "clipboard" item_state = "clipboard" - // inhand_icon_state = "clipboard" - // worn_icon_state = "clipboard" throwforce = 0 w_class = WEIGHT_CLASS_SMALL throw_speed = 3 throw_range = 7 - var/obj/item/pen/haspen //The stored pen. - var/obj/item/paper/toppaper //The topmost piece of paper. slot_flags = ITEM_SLOT_BELT resistance_flags = FLAMMABLE + /// The stored pen + var/obj/item/pen/pen + /// Is the pen integrated? + var/integrated_pen = FALSE + /** + * Weakref of the topmost piece of paper + * + * This is used for the paper displayed on the clipboard's icon + * and it is the one attacked, when attacking the clipboard. + * (As you can't organise contents directly in BYOND) + */ + var/datum/weakref/toppaper_ref /obj/item/clipboard/suicide_act(mob/living/carbon/user) - user.visible_message("[user] begins putting [user.p_their()] head into the clip of \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return BRUTELOSS//the clipboard's clip is very strong. industrial duty. can kill a man easily. + user.visible_message(span_suicide("[user] begins putting [user.p_their()] head into the clip of \the [src]! It looks like [user.p_theyre()] trying to commit suicide!")) + return BRUTELOSS //The clipboard's clip is very strong. Industrial duty. Can kill a man easily. -/obj/item/clipboard/Initialize() - update_icon() +/obj/item/clipboard/Initialize(mapload) + update_appearance() . = ..() /obj/item/clipboard/Destroy() - QDEL_NULL(haspen) - QDEL_NULL(toppaper) //let movable/Destroy handle the rest + QDEL_NULL(pen) return ..() +/obj/item/clipboard/examine() + . = ..() + if(!integrated_pen && pen) + . += span_notice("Alt-click to remove [pen].") + var/obj/item/paper/toppaper = toppaper_ref?.resolve() + if(toppaper) + . += span_notice("Right-click to remove [toppaper].") + +/// Take out the topmost paper +/obj/item/clipboard/proc/remove_paper(obj/item/paper/paper, mob/user) + if(!istype(paper)) + return + paper.forceMove(user.loc) + user.put_in_hands(paper) + to_chat(user, span_notice("You remove [paper] from [src].")) + var/obj/item/paper/toppaper = toppaper_ref?.resolve() + if(paper == toppaper) + UnregisterSignal(toppaper, COMSIG_ATOM_UPDATED_ICON) + toppaper_ref = null + var/obj/item/paper/newtop = locate(/obj/item/paper) in src + if(newtop && (newtop != paper)) + toppaper_ref = WEAKREF(newtop) + else + toppaper_ref = null + update_icon() + +/obj/item/clipboard/proc/remove_pen(mob/user) + pen.forceMove(user.loc) + user.put_in_hands(pen) + to_chat(user, span_notice("You remove [pen] from [src].")) + pen = null + update_icon() + +/obj/item/clipboard/AltClick(mob/user) + ..() + if(pen) + if(integrated_pen) + to_chat(user, span_warning("You can't seem to find a way to remove [src]'s [pen].")) + else + remove_pen(user) + /obj/item/clipboard/update_overlays() . = ..() + var/obj/item/paper/toppaper = toppaper_ref?.resolve() if(toppaper) . += toppaper.icon_state . += toppaper.overlays - if(haspen) + if(pen) . += "clipboard_pen" . += "clipboard_over" -/obj/item/clipboard/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/paper)) - if(!user.transferItemToLoc(W, src)) +/obj/item/clipboard/attack_hand(mob/user, act_intent) + if(act_intent != INTENT_HELP) + var/obj/item/paper/toppaper = toppaper_ref?.resolve() + remove_paper(toppaper, user) + return TRUE + . = ..() + +/obj/item/clipboard/attackby(obj/item/weapon, mob/user, params) + var/obj/item/paper/toppaper = toppaper_ref?.resolve() + if(istype(weapon, /obj/item/paper)) + //Add paper into the clipboard + if(!user.transferItemToLoc(weapon, src)) return - toppaper = W - to_chat(user, "You clip the paper onto \the [src].") - update_icon() + if(toppaper) + UnregisterSignal(toppaper, COMSIG_ATOM_UPDATED_ICON) + RegisterSignal(weapon, COMSIG_ATOM_UPDATED_ICON, .proc/on_top_paper_change) + toppaper_ref = WEAKREF(weapon) + to_chat(user, span_notice("You clip [weapon] onto [src].")) + else if(istype(weapon, /obj/item/pen) && !pen) + //Add a pen into the clipboard, attack (write) if there is already one + if(!usr.transferItemToLoc(weapon, src)) + return + pen = weapon + to_chat(usr, span_notice("You slot [weapon] into [src].")) else if(toppaper) toppaper.attackby(user.get_active_held_item(), user) - update_icon() - + update_appearance() /obj/item/clipboard/attack_self(mob/user) - var/dat = "Clipboard" - if(haspen) - dat += "Remove Pen

    " - else - dat += "Add Pen

    " - - //The topmost paper. You can't organise contents directly in byond, so this is what we're stuck with. -Pete - if(toppaper) - var/obj/item/paper/P = toppaper - dat += "Write Remove - [P.name]

    " - - for(P in src) - if(P == toppaper) - continue - dat += "Write Remove Move to top - [P.name]
    " - user << browse(dat, "window=clipboard") - onclose(user, "clipboard") add_fingerprint(usr) + ui_interact(user) + return +/obj/item/clipboard/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Clipboard") + ui.open() -/obj/item/clipboard/Topic(href, href_list) - ..() - if(usr.stat != CONSCIOUS || usr.restrained()) //HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) +/obj/item/clipboard/ui_data(mob/user) + // prepare data for TGUI + var/list/data = list() + data["pen"] = "[pen]" + data["integrated_pen"] = integrated_pen + + var/obj/item/paper/toppaper = toppaper_ref?.resolve() + data["top_paper"] = "[toppaper]" + data["top_paper_ref"] = "[REF(toppaper)]" + + data["paper"] = list() + data["paper_ref"] = list() + for(var/obj/item/paper/paper in src) + if(paper == toppaper) + continue + data["paper"] += "[paper]" + data["paper_ref"] += "[REF(paper)]" + + return data + +/obj/item/clipboard/ui_act(action, params) + . = ..() + if(.) return - if(usr.contents.Find(src)) + if(usr.stat != CONSCIOUS || usr.restrained()) + return - if(href_list["pen"]) - if(haspen) - haspen.forceMove(usr.loc) - usr.put_in_hands(haspen) - haspen = null + switch(action) + // Take the pen out + if("remove_pen") + if(pen) + if(!integrated_pen) + remove_pen(usr) + else + to_chat(usr, span_warning("You can't seem to find a way to remove [src]'s [pen].")) + . = TRUE + // Take paper out + if("remove_paper") + var/obj/item/paper/paper = locate(params["ref"]) in src + if(istype(paper)) + remove_paper(paper, usr) + . = TRUE + // Look at (or edit) the paper + if("edit_paper") + var/obj/item/paper/paper = locate(params["ref"]) in src + if(istype(paper)) + paper.ui_interact(usr) + update_icon() + . = TRUE + // Move paper to the top + if("move_top_paper") + var/obj/item/paper/paper = locate(params["ref"]) in src + if(istype(paper)) + toppaper_ref = WEAKREF(paper) + to_chat(usr, span_notice("You move [paper] to the top.")) + update_icon() + . = TRUE + // Rename the paper (it's a verb) + if("rename_paper") + var/obj/item/paper/paper = locate(params["ref"]) in src + if(istype(paper)) + paper.rename() + update_icon() + . = TRUE - if(href_list["addpen"]) - if(!haspen) - var/obj/item/held = usr.get_active_held_item() - if(istype(held, /obj/item/pen)) - var/obj/item/pen/W = held - if(!usr.transferItemToLoc(W, src)) - return - haspen = W - to_chat(usr, "You slot [W] into [src].") - - if(href_list["write"]) - var/obj/item/P = locate(href_list["write"]) in src - if(istype(P)) - if(usr.get_active_held_item()) - P.attackby(usr.get_active_held_item(), usr) - - if(href_list["remove"]) - var/obj/item/P = locate(href_list["remove"]) in src - if(istype(P)) - P.forceMove(usr.loc) - usr.put_in_hands(P) - if(P == toppaper) - toppaper = null - var/obj/item/paper/newtop = locate(/obj/item/paper) in src - if(newtop && (newtop != P)) - toppaper = newtop - else - toppaper = null - - if(href_list["read"]) - var/obj/item/paper/P = locate(href_list["read"]) in src - if(istype(P)) - usr.examinate(P) - - if(href_list["top"]) - var/obj/item/P = locate(href_list["top"]) in src - if(istype(P)) - toppaper = P - to_chat(usr, "You move [P.name] to the top.") - - //Update everything - attack_self(usr) - update_icon() +/** + * This is a simple proc to handle calling update_icon() upon receiving the top paper's `COMSIG_ATOM_UPDATE_APPEARANCE`. + */ +/obj/item/clipboard/proc/on_top_paper_change() + SIGNAL_HANDLER + update_appearance() diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index 59bbf47128..f6725eeb1d 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -192,7 +192,7 @@ GLOBAL_LIST_EMPTY(employmentCabinets) ///This var is so that its filled on crew interaction to be as accurate (including latejoins) as possible, true until first interact var/virgin = TRUE -/obj/structure/filingcabinet/employment/Initialize() +/obj/structure/filingcabinet/employment/Initialize(mapload) . = ..() GLOB.employmentCabinets += src diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index 2c534d0178..d69da4d797 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -100,7 +100,7 @@ name = "folder- 'TOP SECRET'" desc = "A folder stamped \"Top Secret - Property of Nanotrasen Corporation. Unauthorized distribution is punishable by death.\"" -/obj/item/folder/documents/Initialize() +/obj/item/folder/documents/Initialize(mapload) . = ..() new /obj/item/documents/nanotrasen(src) update_icon() @@ -113,7 +113,7 @@ /obj/item/folder/syndicate/red icon_state = "folder_sred" -/obj/item/folder/syndicate/red/Initialize() +/obj/item/folder/syndicate/red/Initialize(mapload) . = ..() new /obj/item/documents/syndicate/red(src) update_icon() @@ -121,12 +121,12 @@ /obj/item/folder/syndicate/blue icon_state = "folder_sblue" -/obj/item/folder/syndicate/blue/Initialize() +/obj/item/folder/syndicate/blue/Initialize(mapload) . = ..() new /obj/item/documents/syndicate/blue(src) update_icon() -/obj/item/folder/syndicate/mining/Initialize() +/obj/item/folder/syndicate/mining/Initialize(mapload) . = ..() new /obj/item/documents/syndicate/mining(src) update_icon() diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm index ad251a6c82..1c4afbf518 100644 --- a/code/modules/paperwork/handlabeler.dm +++ b/code/modules/paperwork/handlabeler.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "labeler0" item_state = "flight" - // inhand_icon_state = "flight" + // item_state = "flight" var/label = null var/labels_left = 30 var/mode = 0 @@ -118,7 +118,7 @@ desc = "A roll of paper. Use it on a hand labeler to refill it." icon_state = "labeler_refill" item_state = "electropack" - // inhand_icon_state = "electropack" + // item_state = "electropack" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' w_class = WEIGHT_CLASS_TINY diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 7a98287809..9b10ea230d 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -5,7 +5,7 @@ * lipstick wiping is in code/game/objects/items/weapons/cosmetics.dm! */ #define MAX_PAPER_LENGTH 5000 -#define MAX_PAPER_STAMPS 30 // Too low? +#define MAX_PAPER_STAMPS 30 // Too low? #define MAX_PAPER_STAMPS_OVERLAYS 4 #define MODE_READING 0 #define MODE_WRITING 1 @@ -22,6 +22,8 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "paper" item_state = "paper" + // worn_icon_state = "paper" + // custom_fire_overlay = "paper_onfire_overlay" throwforce = 0 w_class = WEIGHT_CLASS_TINY throw_range = 1 @@ -41,8 +43,8 @@ var/show_written_words = TRUE /// The (text for the) stamps on the paper. - var/list/stamps /// Positioning for the stamp in tgui - var/list/stamped /// Overlay info + var/list/stamps /// Positioning for the stamp in tgui + var/list/stamped /// Overlay info var/contact_poison // Reagent ID to transfer on contact var/contact_poison_volume = 0 @@ -61,20 +63,23 @@ /** * This proc copies this sheet of paper to a new - * sheet, Makes it nice and easy for carbon and - * the copyer machine + * sheet. Used by carbon papers and the photocopier machine. */ -/obj/item/paper/proc/copy() - var/obj/item/paper/N = new(arglist(args)) - N.info = info - N.color = color - N.update_icon_state() - N.stamps = stamps - N.stamped = stamped.Copy() - N.form_fields = form_fields.Copy() - N.field_counter = field_counter - copy_overlays(N, TRUE) - return N +/obj/item/paper/proc/copy(paper_type = /obj/item/paper, atom/location = loc, colored = TRUE) + var/obj/item/paper/new_paper = new paper_type (location) + if(colored) + new_paper.color = color + new_paper.info = info + else //This basically just breaks the existing color tag, which we need to do because the innermost tag takes priority. + var/static/greyscale_info = regex("You cut yourself on the paper! Ahhhh! Ahhhhh!") + to_chat(H, span_warning("You cut yourself on the paper! Ahhhh! Ahhhhh!")) H.damageoverlaytemp = 9001 H.update_damage_hud() return var/n_name = stripped_input(usr, "What would you like to label the paper?", "Paper Labelling", null, MAX_NAME_LEN) - if((loc == usr && usr.stat == CONSCIOUS)) + if(((loc == usr || istype(loc, /obj/item/clipboard)) && usr.stat == CONSCIOUS)) name = "paper[(n_name ? text("- '[n_name]'") : null)]" add_fingerprint(usr) /obj/item/paper/suicide_act(mob/user) - user.visible_message("[user] scratches a grid on [user.p_their()] wrist with the paper! It looks like [user.p_theyre()] trying to commit sudoku...") + user.visible_message(span_suicide("[user] scratches a grid on [user.p_their()] wrist with the paper! It looks like [user.p_theyre()] trying to commit sudoku...")) return (BRUTELOSS) /obj/item/paper/proc/clearpaper() @@ -139,18 +145,18 @@ /obj/item/paper/examine(mob/user) . = ..() if(!in_range(user, src) && !isobserver(user)) - . += "You're too far away to read it!" + . += span_warning("You're too far away to read it!") return if(user.can_read(src)) ui_interact(user) return - . += "You cannot read it!" + . += span_warning("You cannot read it!") /obj/item/paper/ui_status(mob/user,/datum/ui_state/state) // Are we on fire? Hard ot read if so if(resistance_flags & ON_FIRE) return UI_CLOSE - if(!in_range(user,src)) + if(!in_range(user, src) && !isobserver(user)) return UI_CLOSE if(user.incapacitated(TRUE, TRUE) || (isobserver(user) && !IsAdminGhost(user))) return UI_UPDATE @@ -158,7 +164,7 @@ // .. or if you cannot read if(!user.can_read(src)) return UI_CLOSE - if(in_contents_of(/obj/machinery/door/airlock)) + if(in_contents_of(/obj/machinery/door/airlock) || in_contents_of(/obj/item/clipboard)) return UI_INTERACTIVE return ..() @@ -176,8 +182,8 @@ return . = TRUE if(!bypass_clumsy && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(10) && Adjacent(user)) - user.visible_message("[user] accidentally ignites [user.p_them()]self!", \ - "You miss [src] and accidentally light yourself on fire!") + user.visible_message(span_warning("[user] accidentally ignites [user.p_them()]self!"), \ + span_userdanger("You miss [src] and accidentally light yourself on fire!")) if(user.is_holding(I)) //checking if they're holding it in case TK is involved user.dropItemToGround(I) user.adjust_fire_stacks(1) @@ -195,19 +201,23 @@ SStgui.close_uis(src) return - if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon)) + // Enable picking paper up by clicking on it with the clipboard or folder + if(istype(P, /obj/item/clipboard) || istype(P, /obj/item/folder)) + P.attackby(src, user) + return + else if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon)) if(length(info) >= MAX_PAPER_LENGTH) // Sheet must have less than 1000 charaters - to_chat(user, "This sheet of paper is full!") + to_chat(user, span_warning("This sheet of paper is full!")) return ui_interact(user) return else if(istype(P, /obj/item/stamp)) - to_chat(user, "You ready your stamp over the paper! ") + to_chat(user, span_notice("You ready your stamp over the paper! ")) ui_interact(user) return /// Normaly you just stamp, you don't need to read the thing else // cut paper? the sky is the limit! - ui_interact(user) // The other ui will be created with just read mode outside of this + ui_interact(user) // The other ui will be created with just read mode outside of this return ..() @@ -234,8 +244,8 @@ . = list() .["text"] = info .["max_length"] = MAX_PAPER_LENGTH - .["paper_color"] = !color || color == "white" ? "#FFFFFF" : color // color might not be set - .["paper_state"] = icon_state /// TODO: show the sheet will bloodied or crinkling? + .["paper_color"] = !color || color == "white" ? "#FFFFFF" : color // color might not be set + .["paper_state"] = icon_state /// TODO: show the sheet will bloodied or crinkling? .["stamps"] = stamps @@ -244,27 +254,34 @@ var/list/data = list() data["edit_usr"] = "[user]" - var/obj/O = user.get_active_held_item() - if(istype(O, /obj/item/toy/crayon)) - var/obj/item/toy/crayon/PEN = O + var/obj/holding = user.get_active_held_item() + // Use a clipboard's pen, if applicable + if(istype(loc, /obj/item/clipboard)) + var/obj/item/clipboard/clipboard = loc + // This is just so you can still use a stamp if you're holding one. Otherwise, it'll + // use the clipboard's pen, if applicable. + if(!istype(holding, /obj/item/stamp) && clipboard.pen) + holding = clipboard.pen + if(istype(holding, /obj/item/toy/crayon)) + var/obj/item/toy/crayon/PEN = holding data["pen_font"] = CRAYON_FONT data["pen_color"] = PEN.paint_color data["edit_mode"] = MODE_WRITING data["is_crayon"] = TRUE data["stamp_class"] = "FAKE" data["stamp_icon_state"] = "FAKE" - else if(istype(O, /obj/item/pen)) - var/obj/item/pen/PEN = O + else if(istype(holding, /obj/item/pen)) + var/obj/item/pen/PEN = holding data["pen_font"] = PEN.font data["pen_color"] = PEN.colour data["edit_mode"] = MODE_WRITING data["is_crayon"] = FALSE data["stamp_class"] = "FAKE" data["stamp_icon_state"] = "FAKE" - else if(istype(O, /obj/item/stamp)) + else if(istype(holding, /obj/item/stamp)) var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/paper) - data["stamp_icon_state"] = O.icon_state - data["stamp_class"] = sheet.icon_class_name(O.icon_state) + data["stamp_icon_state"] = holding.icon_state + data["stamp_class"] = sheet.icon_class_name(holding.icon_state) data["edit_mode"] = MODE_STAMPING data["pen_font"] = "FAKE" data["pen_color"] = "FAKE" @@ -276,6 +293,10 @@ data["is_crayon"] = FALSE data["stamp_icon_state"] = "FAKE" data["stamp_class"] = "FAKE" + if(istype(loc, /obj/structure/noticeboard)) + var/obj/structure/noticeboard/noticeboard = loc + if(!noticeboard.allowed(user)) + data["edit_mode"] = MODE_READING data["field_counter"] = field_counter data["form_fields"] = form_fields @@ -289,14 +310,14 @@ if("stamp") var/stamp_x = text2num(params["x"]) var/stamp_y = text2num(params["y"]) - var/stamp_r = text2num(params["r"]) // rotation in degrees + var/stamp_r = text2num(params["r"]) // rotation in degrees var/stamp_icon_state = params["stamp_icon_state"] var/stamp_class = params["stamp_class"] if (isnull(stamps)) stamps = list() if(stamps.len < MAX_PAPER_STAMPS) // I hate byond when dealing with freaking lists - stamps[++stamps.len] = list(stamp_class, stamp_x, stamp_y, stamp_r) /// WHHHHY + stamps[++stamps.len] = list(stamp_class, stamp_x, stamp_y, stamp_r) /// WHHHHY /// This does the overlay stuff if (isnull(stamped)) @@ -307,10 +328,11 @@ stampoverlay.pixel_y = rand(-3, 2) add_overlay(stampoverlay) LAZYADD(stamped, stamp_icon_state) + update_icon() update_static_data(usr,ui) var/obj/O = ui.user.get_active_held_item() - ui.user.visible_message("[ui.user] stamps [src] with \the [O.name]!", "You stamp [src] with \the [O.name]!") + ui.user.visible_message(span_notice("[ui.user] stamps [src] with \the [O.name]!"), span_notice("You stamp [src] with \the [O.name]!")) else to_chat(usr, pick("You try to stamp but you miss!", "There is no where else you can stamp!")) . = TRUE @@ -336,22 +358,27 @@ update_static_data(usr,ui) - update_icon() + update_appearance() . = TRUE +/obj/item/paper/ui_host(mob/user) + if(istype(loc, /obj/structure/noticeboard)) + return loc + return ..() + /** * Construction paper */ /obj/item/paper/construction -/obj/item/paper/construction/Initialize() +/obj/item/paper/construction/Initialize(mapload) . = ..() color = pick("FF0000", "#33cc33", "#ffb366", "#551A8B", "#ff80d5", "#4d94ff") /** * Natural paper */ -/obj/item/paper/natural/Initialize() +/obj/item/paper/natural/Initialize(mapload) . = ..() color = "#FFF5ED" @@ -361,9 +388,6 @@ slot_flags = null show_written_words = FALSE -/obj/item/paper/crumpled/update_icon_state() - return - /obj/item/paper/crumpled/bloody icon_state = "scrap_bloodied" diff --git a/code/modules/paperwork/paper_cutter.dm b/code/modules/paperwork/paper_cutter.dm index 2bb743abbd..bd59ed7a10 100644 --- a/code/modules/paperwork/paper_cutter.dm +++ b/code/modules/paperwork/paper_cutter.dm @@ -12,7 +12,7 @@ pass_flags = PASSTABLE -/obj/item/papercutter/Initialize() +/obj/item/papercutter/Initialize(mapload) . = ..() storedcutter = new /obj/item/hatchet/cutterblade(src) update_icon() @@ -120,7 +120,7 @@ return ..() -/obj/item/paperslip/Initialize() +/obj/item/paperslip/Initialize(mapload) . = ..() pixel_x = initial(pixel_x) + rand(-5, 5) pixel_y = initial(pixel_y) + rand(-5, 5) @@ -132,6 +132,6 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "cutterblade" item_state = "knife" - // inhand_icon_state = "knife" + // item_state = "knife" lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi' diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 6775532614..8fab76a406 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "paper_bin1" item_state = "sheet-metal" - // inhand_icon_state = "sheet-metal" + // item_state = "sheet-metal" lefthand_file = 'icons/mob/inhands/misc/sheets_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/sheets_righthand.dmi' throwforce = 0 diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index b4f1acbed4..b65c14fa26 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -16,7 +16,7 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "pen" item_state = "pen" - // inhand_icon_state = "pen" + // item_state = "pen" // worn_icon_state = "pen" slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_EARS throwforce = 0 @@ -105,22 +105,22 @@ custom_materials = list(/datum/material/gold = 750) sharpness = SHARP_EDGED resistance_flags = FIRE_PROOF - unique_reskin = list("Oak" = "pen-fountain-o", - "Gold" = "pen-fountain-g", - "Rosewood" = "pen-fountain-r", - "Black and Silver" = "pen-fountain-b", - "Command Blue" = "pen-fountain-cb" - ) + unique_reskin = list( + "Oak" = list("icon_state" = "pen-fountain-o"), + "Gold" = list("icon_state" = "pen-fountain-g"), + "Rosewood" = list("icon_state" = "pen-fountain-r"), + "Black and Silver" = list("icon_state" = "pen-fountain-b"), + "Command Blue" = list("icon_state" = "pen-fountain-cb") + ) embedding = list("embed_chance" = 75) -/obj/item/pen/fountain/captain/Initialize() +/obj/item/pen/fountain/captain/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 200, 115) //the pen is mightier than the sword /obj/item/pen/fountain/captain/reskin_obj(mob/M) - ..() - if(current_skin) - desc = "It's an expensive [current_skin] fountain pen. The nib is quite sharp." + . = ..() + desc = "It's an expensive [current_skin] fountain pen. The nib is quite sharp." /obj/item/pen/attack_self(mob/living/carbon/user) var/deg = input(user, "What angle would you like to rotate the pen head to? (1-360)", "Rotate Pen Head") as null|num @@ -148,6 +148,10 @@ /obj/item/pen/afterattack(obj/O, mob/living/user, proximity) . = ..() //Changing name/description of items. Only works if they have the UNIQUE_RENAME object flag set + try_modify_object(O, user, proximity) + +/obj/item/pen/proc/try_modify_object(obj/O, mob/living/user, proximity) + set waitfor = FALSE if(isobj(O) && proximity && (O.obj_flags & UNIQUE_RENAME)) var/penchoice = input(user, "What would you like to edit?", "Rename, change description or reset both?") as null|anything in list("Rename","Change description","Reset") if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE)) @@ -169,7 +173,7 @@ O.renamedByPlayer = TRUE if(penchoice == "Change description") - var/input = stripped_input(user,"Describe [O] here:", ,"[O.desc]", 140) + var/input = stripped_input(user,"Describe [O] here:", ,"[O.desc]", 350) var/olddesc = O.desc if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE)) return @@ -208,7 +212,7 @@ reagents.trans_to(M, reagents.total_volume, log = "sleepypen inject") -/obj/item/pen/sleepy/Initialize() +/obj/item/pen/sleepy/Initialize(mapload) . = ..() create_reagents(45, OPENCONTAINER) reagents.add_reagent(/datum/reagent/toxin/chloralhydrate, 20) @@ -285,7 +289,7 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "digging_pen" item_state = "pen" - // inhand_icon_state = "pen" + // item_state = "pen" // worn_icon_state = "pen" force = 3 w_class = WEIGHT_CLASS_TINY diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 06adda95dd..8079950aff 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -44,7 +44,7 @@ /// Indicates whether the printer is currently busy copying or not. var/busy = FALSE -/obj/machinery/photocopier/Initialize() +/obj/machinery/photocopier/Initialize(mapload) . = ..() // AddComponent(/datum/component/payment, 5, SSeconomy.get_dep_account(ACCOUNT_CIV), PAYMENT_CLINICAL) toner_cartridge = new(src) diff --git a/code/modules/paperwork/stamps.dm b/code/modules/paperwork/stamps.dm index 104f70bfdf..1c3f76a676 100644 --- a/code/modules/paperwork/stamps.dm +++ b/code/modules/paperwork/stamps.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "stamp-ok" item_state = "stamp" - // inhand_icon_state = "stamp" + // item_state = "stamp" throwforce = 0 w_class = WEIGHT_CLASS_TINY throw_speed = 3 diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm index e874f2836d..9683601670 100644 --- a/code/modules/paperwork/ticketmachine.dm +++ b/code/modules/paperwork/ticketmachine.dm @@ -44,7 +44,7 @@ tickets.Cut() update_icon() -/obj/machinery/ticket_machine/Initialize() +/obj/machinery/ticket_machine/Initialize(mapload) . = ..() update_icon() @@ -69,7 +69,7 @@ req_access = list() id = "ticket_machine_default" -/obj/machinery/button/ticket_machine/Initialize() +/obj/machinery/button/ticket_machine/Initialize(mapload) . = ..() if(device) var/obj/item/assembly/control/ticket_machine/ours = device @@ -82,17 +82,17 @@ if(M.buffer && !istype(M.buffer, /obj/machinery/ticket_machine)) return var/obj/item/assembly/control/ticket_machine/controller = device - controller.linked = M.buffer + controller.linked = WEAKREF(M.buffer) id = null controller.id = null - to_chat(user, "You've linked [src] to [controller.linked].") + to_chat(user, "You've linked [src] to [M.buffer].") /obj/item/assembly/control/ticket_machine name = "ticket machine controller" desc = "A remote controller for the HoP's ticket machine." - var/obj/machinery/ticket_machine/linked //To whom are we linked? + var/datum/weakref/linked //To whom are we linked? -/obj/item/assembly/control/ticket_machine/Initialize() +/obj/item/assembly/control/ticket_machine/Initialize(mapload) ..() return INITIALIZE_HINT_LATELOAD @@ -102,7 +102,7 @@ /obj/item/assembly/control/ticket_machine/proc/find_machine() //Locate the one to which we're linked for(var/obj/machinery/ticket_machine/ticketsplease in GLOB.machines) if(ticketsplease.id == id) - linked = ticketsplease + linked = WEAKREF(ticketsplease) if(linked) return TRUE else @@ -113,8 +113,11 @@ return if(!linked) return + var/obj/machinery/ticket_machine/machine = linked.resolve() + if(!machine) + return cooldown = TRUE - linked.increment() + machine.increment() addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 10) /obj/machinery/ticket_machine/update_icon() diff --git a/code/modules/photography/photos/album.dm b/code/modules/photography/photos/album.dm index 8361accba2..6f35e7a99d 100644 --- a/code/modules/photography/photos/album.dm +++ b/code/modules/photography/photos/album.dm @@ -11,7 +11,7 @@ resistance_flags = FLAMMABLE var/persistence_id -/obj/item/storage/photo_album/Initialize() +/obj/item/storage/photo_album/Initialize(mapload) . = ..() var/datum/component/storage/STR = GetComponent(/datum/component/storage) STR.can_hold = typecacheof(list(/obj/item/photo)) diff --git a/code/modules/plumbing/ducts.dm b/code/modules/plumbing/ducts.dm index 8a27f2669c..59816544ab 100644 --- a/code/modules/plumbing/ducts.dm +++ b/code/modules/plumbing/ducts.dm @@ -388,7 +388,7 @@ All the important duct code: singular_name = "duct" icon = 'icons/obj/plumbing/fluid_ducts.dmi' icon_state = "ducts" - custom_materials = list(/datum/material/iron=500) + custom_materials = list(/datum/material/plastic = 400) w_class = WEIGHT_CLASS_TINY novariants = FALSE max_amount = 50 diff --git a/code/modules/plumbing/plumbers/autohydro.dm b/code/modules/plumbing/plumbers/autohydro.dm index 9c358d8d6e..4e1dd88406 100644 --- a/code/modules/plumbing/plumbers/autohydro.dm +++ b/code/modules/plumbing/plumbers/autohydro.dm @@ -5,12 +5,6 @@ obj_flags = CAN_BE_HIT | UNIQUE_RENAME circuit = /obj/item/circuitboard/machine/hydroponics/automagic - -/obj/machinery/hydroponics/constructable/automagic/attackby(obj/item/O, mob/user, params) - if(istype(O, /obj/item/reagent_containers)) - return FALSE //avoid fucky wuckies - ..() - /obj/machinery/hydroponics/constructable/automagic/default_unfasten_wrench(mob/user, obj/item/I, time = 20) . = ..() if(. == SUCCESSFUL_UNFASTEN) diff --git a/code/modules/plumbing/plumbers/grinder_chemical.dm b/code/modules/plumbing/plumbers/grinder_chemical.dm index f39c79f906..1d216046e4 100644 --- a/code/modules/plumbing/plumbers/grinder_chemical.dm +++ b/code/modules/plumbing/plumbers/grinder_chemical.dm @@ -31,7 +31,7 @@ eat_dir = WEST return TRUE -/obj/machinery/plumbing/grinder_chemical/CanPass(atom/movable/AM) +/obj/machinery/plumbing/grinder_chemical/CanAllowThrough(atom/movable/AM) . = ..() if(!anchored) return diff --git a/code/modules/plumbing/plumbers/medipenrefill.dm b/code/modules/plumbing/plumbers/medipenrefill.dm index fb7553a4d5..140114673a 100644 --- a/code/modules/plumbing/plumbers/medipenrefill.dm +++ b/code/modules/plumbing/plumbers/medipenrefill.dm @@ -15,7 +15,7 @@ /// var to prevent glitches in the animation var/busy = FALSE -/obj/machinery/medipen_refiller/Initialize() +/obj/machinery/medipen_refiller/Initialize(mapload) . = ..() create_reagents(100, TRANSPARENT) for(var/obj/item/stock_parts/matter_bin/B in component_parts) diff --git a/code/modules/pool/pool_controller.dm b/code/modules/pool/pool_controller.dm index 142690566b..f2a3b23e57 100644 --- a/code/modules/pool/pool_controller.dm +++ b/code/modules/pool/pool_controller.dm @@ -64,7 +64,7 @@ . = ..() . += "Alt click to drain reagents." -/obj/machinery/pool/controller/Initialize() +/obj/machinery/pool/controller/Initialize(mapload) . = ..() START_PROCESSING(SSfastprocess, src) create_reagents(1000) @@ -235,10 +235,10 @@ if(POOL_SCALDING) //Scalding M.adjust_bodytemperature(50,0,500) if(POOL_WARM) //Warm - M.adjust_bodytemperature(20,0,360) //Heats up mobs till the thermometer shows up + M.adjust_bodytemperature(20,0,323.15) //Heats up mobs till the thermometer shows up //Normal temp does nothing, because it's just room temperature water. if(POOL_COOL) - M.adjust_bodytemperature(-20,250) //Cools mobs till the thermometer shows up + M.adjust_bodytemperature(-20,274.15) //Cools mobs till the thermometer shows up if(POOL_FRIGID) //Freezing M.adjust_bodytemperature(-60) //cool mob at -35k per cycle, less would not affect the mob enough. if(M.bodytemperature <= 50 && !M.stat) diff --git a/code/modules/pool/pool_drain.dm b/code/modules/pool/pool_drain.dm index 527c25b9f0..09afe09cd1 100644 --- a/code/modules/pool/pool_drain.dm +++ b/code/modules/pool/pool_drain.dm @@ -24,7 +24,7 @@ var/cooldown -/obj/machinery/pool/drain/Initialize() +/obj/machinery/pool/drain/Initialize(mapload) START_PROCESSING(SSfastprocess, src) whirling_mobs = list() return ..() diff --git a/code/modules/pool/pool_main.dm b/code/modules/pool/pool_main.dm index 088c991ca0..691c22a9c5 100644 --- a/code/modules/pool/pool_main.dm +++ b/code/modules/pool/pool_main.dm @@ -130,7 +130,7 @@ H.visible_message("[H] falls in and takes a drink!", "You fall in and swallow some water!") playsound(src, 'sound/effects/splash.ogg', 60, TRUE, 1) - else if(!H.head || !(H.head.armor.getRating("melee") > 20)) + else if(!H.head || !(H.head.armor.getRating(MELEE) > 20)) if(prob(75)) H.visible_message("[H] falls in the drained pool!", "You fall in the drained pool!") diff --git a/code/modules/power/antimatter/containment_jar.dm b/code/modules/power/antimatter/containment_jar.dm index 0ccbba5a0c..3066755690 100644 --- a/code/modules/power/antimatter/containment_jar.dm +++ b/code/modules/power/antimatter/containment_jar.dm @@ -15,7 +15,7 @@ var/stability = 100//TODO: add all the stability things to this so its not very safe if you keep hitting in on things -/obj/item/am_containment/ex_act(severity, target) +/obj/item/am_containment/ex_act(severity, target, origin) switch(severity) if(1) explosion(get_turf(src), 1, 2, 3, 5)//Should likely be larger but this works fine for now I guess diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm index 17c5bc0e4c..5b9bf71a9b 100644 --- a/code/modules/power/antimatter/control.dm +++ b/code/modules/power/antimatter/control.dm @@ -30,7 +30,7 @@ var/stored_power = 0//Power to deploy per tick -/obj/machinery/power/am_control_unit/Initialize() +/obj/machinery/power/am_control_unit/Initialize(mapload) . = ..() linked_shielding = list() linked_cores = list() @@ -114,14 +114,14 @@ check_stability() return -/obj/machinery/power/am_control_unit/ex_act(severity, target) +/obj/machinery/power/am_control_unit/ex_act(severity, target, origin) stability -= (80 - (severity * 20)) check_stability() return /obj/machinery/power/am_control_unit/bullet_act(obj/item/projectile/Proj) . = ..() - if(Proj.flag != "bullet") + if(Proj.flag != BULLET) stability -= Proj.force check_stability() diff --git a/code/modules/power/antimatter/shielding.dm b/code/modules/power/antimatter/shielding.dm index 100998d7c6..e9ee1e70d0 100644 --- a/code/modules/power/antimatter/shielding.dm +++ b/code/modules/power/antimatter/shielding.dm @@ -28,7 +28,7 @@ var/dirs = 0 -/obj/machinery/am_shielding/Initialize() +/obj/machinery/am_shielding/Initialize(mapload) . = ..() addtimer(CALLBACK(src, .proc/controllerscan), 10) @@ -94,7 +94,7 @@ /obj/machinery/am_shielding/emp_act()//Immune due to not really much in the way of electronics. return -/obj/machinery/am_shielding/ex_act(severity, target) +/obj/machinery/am_shielding/ex_act(severity, target, origin) stability -= (80 - (severity * 20)) check_stability() return @@ -102,7 +102,7 @@ /obj/machinery/am_shielding/bullet_act(obj/item/projectile/Proj) . = ..() - if(Proj.flag != "bullet") + if(Proj.flag != BULLET) stability -= Proj.force/2 check_stability() diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 515349d666..9896cc4088 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -119,7 +119,7 @@ integrity_failure = 0.17 damage_deflection = 10 resistance_flags = FIRE_PROOF - armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 100, "bomb" = 30, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 50) + armor = list(MELEE = 40, BULLET = 40, LASER = 40, ENERGY = 100, BOMB = 30, BIO = 100, RAD = 100, FIRE = 90, ACID = 50) req_access = list(ACCESS_ENGINE_EQUIP) interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON @@ -290,6 +290,13 @@ set_machine_stat(stat | MAINT) update_appearance() addtimer(CALLBACK(src, .proc/update), 5) + register_context() + +/obj/machinery/power/apc/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + if(operating) + LAZYSET(context[SCREENTIP_CONTEXT_ALT_LMB], INTENT_ANY, locked ? "Unlock" : "Lock") + return CONTEXTUAL_SCREENTIP_SET /obj/machinery/power/apc/Destroy() GLOB.apcs_list -= src @@ -852,7 +859,7 @@ set_nightshift(!nightshift_lights) /obj/machinery/power/apc/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < 10 && (!(stat & BROKEN) || malfai)) + if(damage_flag == MELEE && damage_amount < 10 && (!(stat & BROKEN) || malfai)) return 0 . = ..() @@ -1444,8 +1451,6 @@ lighting = autoset(lighting, AUTOSET_ON) environ = autoset(environ, AUTOSET_ON) area.poweralert(FALSE, src) - if(cell.percent() > 75) - area.poweralert(FALSE, src) // now trickle-charge the cell if(chargemode && charging == APC_CHARGING && operating) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 9e779b9c1b..d45b5ad9e1 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -587,7 +587,7 @@ By design, d1 is the smallest direction and d2 is the highest to_chat(user, "You don't have enough cable coil to make restraints out of them") return to_chat(user, "You start making some cable restraints.") - if(!do_after(user, 30, TRUE, user, TRUE) || !use(15)) + if(!do_after(user, 3 SECONDS, user) || !use(15)) to_chat(user, "You fail to make cable restraints, you need to be standing still to do it") return var/obj/item/restraints/handcuffs/cable/result = new(get_turf(user)) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index a0509fbd41..6d1da2bc20 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -79,7 +79,7 @@ return 0 if(charge < amount) return 0 - charge = (charge - amount) + charge -= amount if(!istype(loc, /obj/machinery/power/apc)) SSblackbox.record_feedback("tally", "cell_used", 1, type) return 1 @@ -142,7 +142,7 @@ if(charge < 0) charge = 0 -/obj/item/stock_parts/cell/ex_act(severity, target) +/obj/item/stock_parts/cell/ex_act(severity, target, origin) ..() if(!QDELETED(src)) switch(severity) @@ -187,23 +187,6 @@ /obj/item/stock_parts/cell/get_part_rating() return rating * maxcharge -// stuff so ipcs and synthlizards can eat power cells, taken from how moths can eat clothing -/obj/item/reagent_containers/food/snacks/cell - name = "oops" - desc = "If you're reading this it means I messed up. This is related to ipcs/synths eating cells and I didn't know a better way to do it than making a new food object." - list_reagents = list(/datum/reagent/consumable/nutriment = 0.5) - tastes = list("electricity" = 1, "metal" = 1) - -/obj/item/stock_parts/cell/attack(mob/M, mob/user, def_zone) - if(user.a_intent != INTENT_HARM && isrobotic(M)) - var/obj/item/reagent_containers/food/snacks/cell/cell_as_food = new - cell_as_food.name = name - if(cell_as_food.attack(M, user, def_zone)) - take_damage(40, sound_effect=FALSE) - qdel(cell_as_food) - else - return ..() - /* Cell variants*/ /obj/item/stock_parts/cell/empty start_charged = FALSE @@ -387,7 +370,7 @@ custom_materials = list(/datum/material/glass = 20) w_class = WEIGHT_CLASS_TINY -/obj/item/stock_parts/cell/emergency_light/Initialize() +/obj/item/stock_parts/cell/emergency_light/Initialize(mapload) . = ..() var/area/A = get_area(src) if(!A.lightswitch || !A.light_power) diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index 9213a5d2ba..f1beecacb9 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -12,6 +12,8 @@ var/lastgenlev = -1 var/lastcirc = "00" + var/max_efficiency = 0.45 + /obj/machinery/power/generator/Initialize(mapload) . = ..() @@ -61,15 +63,12 @@ if(delta_temperature > 0 && cold_air_heat_capacity > 0 && hot_air_heat_capacity > 0) - var/efficiency = 0.45 + var/efficiency = LOGISTIC_FUNCTION(max_efficiency,0.0009,delta_temperature,10000) var/energy_transfer = delta_temperature*hot_air_heat_capacity*cold_air_heat_capacity/(hot_air_heat_capacity+cold_air_heat_capacity) - var/heat = energy_transfer*(1-efficiency) - if(delta_temperature < 16800) // second point where derivative of below function = 1 - lastgen += LOGISTIC_FUNCTION(500000,0.0009,delta_temperature,10000) - else - lastgen += delta_temperature + 482102 // value of above function at 16800, or very nearly so + lastgen += energy_transfer * efficiency + var/heat = energy_transfer * (1-efficiency) hot_air.set_temperature(hot_air.return_temperature() - energy_transfer/hot_air_heat_capacity) cold_air.set_temperature(cold_air.return_temperature() + heat/cold_air_heat_capacity) diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index 3fe03978bd..08a804550e 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -31,7 +31,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne /obj/machinery/gravity_generator/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG, gentle = FALSE) return FALSE -/obj/machinery/gravity_generator/ex_act(severity, target) +/obj/machinery/gravity_generator/ex_act(severity, target, origin) if(severity >= EXPLODE_DEVASTATE) // Very sturdy. set_broken() @@ -98,7 +98,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne // Generator which spawns with the station. // -/obj/machinery/gravity_generator/main/station/Initialize() +/obj/machinery/gravity_generator/main/station/Initialize(mapload) . = ..() setup_parts() middle.add_overlay("activated") diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 00487ee607..081b93866e 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -43,7 +43,7 @@ anchored = TRUE layer = WALL_OBJ_LAYER max_integrity = 200 - armor = list("melee" = 50, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50) + armor = list(MELEE = 50, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 50) var/stage = 1 var/fixture_type = "tube" @@ -250,7 +250,7 @@ icon_state = "tube-empty" start_with_cell = FALSE -/obj/machinery/light/built/Initialize() +/obj/machinery/light/built/Initialize(mapload) . = ..() status = LIGHT_EMPTY update(0) @@ -259,7 +259,7 @@ icon_state = "bulb-empty" start_with_cell = FALSE -/obj/machinery/light/small/built/Initialize() +/obj/machinery/light/small/built/Initialize(mapload) . = ..() status = LIGHT_EMPTY update(0) @@ -267,7 +267,7 @@ // create a new lighting fixture -/obj/machinery/light/Initialize() +/obj/machinery/light/Initialize(mapload) . = ..() if(start_with_cell && !no_emergency) cell = new/obj/item/stock_parts/cell/emergency_light(src) @@ -500,7 +500,7 @@ drop_light_tube() new /obj/item/stack/cable_coil(loc, 1, "red") transfer_fingerprints_to(newlight) - if(cell) + if(!QDELETED(cell)) newlight.cell = cell cell.forceMove(newlight) cell = null @@ -797,7 +797,7 @@ desc = "A broken [name]." -/obj/item/light/Initialize() +/obj/item/light/Initialize(mapload) . = ..() update() diff --git a/code/modules/power/monitor.dm b/code/modules/power/monitor.dm index 393d403c4d..e5099dd009 100644 --- a/code/modules/power/monitor.dm +++ b/code/modules/power/monitor.dm @@ -31,7 +31,7 @@ . = ..() . += "It's operating system seems quite outdated... It doesn't seem like it'd be compatible with the latest remote NTOS monitoring systems." -/obj/machinery/computer/monitor/Initialize() +/obj/machinery/computer/monitor/Initialize(mapload) . = ..() search() history["supply"] = list() diff --git a/code/modules/power/multiz.dm b/code/modules/power/multiz.dm index d5f2846293..9a012991f7 100644 --- a/code/modules/power/multiz.dm +++ b/code/modules/power/multiz.dm @@ -41,7 +41,7 @@ addtimer(CALLBACK(src, .proc/refresh), 20) //Wait a bit so we can find the one below, then get powering return TRUE -/obj/machinery/power/deck_relay/Initialize() +/obj/machinery/power/deck_relay/Initialize(mapload) . = ..() addtimer(CALLBACK(src, .proc/find_relays), 30) addtimer(CALLBACK(src, .proc/refresh), 50) //Wait a bit so we can find the one below, then get powering diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index b5ed659e47..48c67f164e 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -17,9 +17,9 @@ interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT | INTERACT_ATOM_REQUIRES_ANCHORED -/obj/machinery/power/port_gen/Initialize() +/obj/machinery/power/port_gen/Initialize(mapload) . = ..() - soundloop = new(list(src), active) + soundloop = new(src, active) /obj/machinery/power/port_gen/Destroy() QDEL_NULL(soundloop) @@ -85,12 +85,12 @@ var/time_per_sheet = 260 var/current_heat = 0 -/obj/machinery/power/port_gen/pacman/Initialize() +/obj/machinery/power/port_gen/pacman/Initialize(mapload) . = ..() if(anchored) connect_to_network() -/obj/machinery/power/port_gen/pacman/Initialize() +/obj/machinery/power/port_gen/pacman/Initialize(mapload) . = ..() var/obj/S = sheet_path diff --git a/code/modules/power/reactor/fuel_rods.dm b/code/modules/power/reactor/fuel_rods.dm new file mode 100644 index 0000000000..6f71ec0b1e --- /dev/null +++ b/code/modules/power/reactor/fuel_rods.dm @@ -0,0 +1,251 @@ +/obj/item/fuel_rod + name = "Uranium-235 Fuel Rod" + desc = "A titanium sheathed rod containing a measure of enriched uranium-dioxide powder inside, and a breeding blanket of uranium-238 around it, used to kick off a fission reaction and breed plutonium fuel respectivly." + icon = 'icons/obj/control_rod.dmi' + icon_state = "irradiated" + w_class = WEIGHT_CLASS_BULKY + var/depletion = 0 //Each fuel rod will deplete in around 30 minutes. + var/fuel_power = 0.10 + var/rad_strength = 500 + var/half_life = 2000 // how many depletion ticks are needed to half the fuel_power (1 tick = 1 second) + var/time_created = 0 + var/og_fuel_power = 0.20 //the original fuel power value + var/process = FALSE + // The depletion where depletion_final() will be called (and does something) + var/depletion_threshold = 100 + // How fast this rod will deplete + var/depletion_speed_modifier = 1 + var/depleted_final = FALSE // depletion_final should run only once + var/depletion_conversion_type = "plutonium" + +/obj/item/fuel_rod/ComponentInitialize() + . = ..() + AddComponent(/datum/component/two_handed, require_twohands = TRUE) + +/obj/item/fuel_rod/Initialize() + . = ..() + time_created = world.time + AddComponent(/datum/component/radioactive, rad_strength, src) // This should be temporary for it won't make rads go lower than 350 + if(process) + START_PROCESSING(SSobj, src) + +/obj/item/fuel_rod/Destroy() + if(process) + STOP_PROCESSING(SSobj, src) + var/obj/machinery/atmospherics/components/trinary/nuclear_reactor/N = loc + if(istype(N)) + N.fuel_rods -= src + . = ..() + +// This proc will try to convert your fuel rod if you don't override this proc +// So, ideally, you should write an override of this for every fuel rod you want to create +/obj/item/fuel_rod/proc/depletion_final(result_rod) + if(!result_rod) + return + var/obj/machinery/atmospherics/components/trinary/nuclear_reactor/N = loc + // Rod conversion is moot when you can't find the reactor + if(istype(N)) + var/obj/item/fuel_rod/R + + // You can add your own depletion scheme and not override this proc if you are going to convert a fuel rod into another type + switch(result_rod) + if("plutonium") + R = new /obj/item/fuel_rod/plutonium(loc) + R.depletion = depletion + if(prob(1)) + R.name = "Plush-239 Fuel Rod" + R.desc = "NanoTrasen would like to remind you that it is not liable for any permanent radioactive damage done to its employees." + R.icon = 'icons/obj/plushes.dmi' + R.icon_state = "romanian" + R.fuel_power = 0.25 //Funny easter egg, slightly more powerful too. + if("depleted") + if(fuel_power < 10) + fuel_power = 0 + playsound(loc, 'sound/effects/supermatter.ogg', 100, TRUE) + R = new /obj/item/fuel_rod/depleted(loc) + R.depletion = depletion + + // Finalization of conversion + if(istype(R)) + N.fuel_rods += R + qdel(src) + else + depleted_final = FALSE // Maybe try again later? + +/obj/item/fuel_rod/proc/deplete(amount=0.035) + depletion += amount * depletion_speed_modifier + if(depletion >= depletion_threshold && !depleted_final) + depleted_final = TRUE + depletion_final(depletion_conversion_type) + +/obj/item/fuel_rod/plutonium + fuel_power = 0.20 + name = "Plutonium-239 Fuel Rod" + desc = "A highly energetic titanium sheathed rod containing a sizeable measure of weapons grade plutonium, it's highly efficient as nuclear fuel, but will cause the reaction to get out of control if not properly utilised." + icon_state = "inferior" + rad_strength = 1500 + process = TRUE // for half life code + depletion_threshold = 300 + depletion_conversion_type = "depleted" + +/obj/item/fuel_rod/process() + fuel_power = og_fuel_power * 0.5**((world.time - time_created) / half_life SECONDS) // halves the fuel power every half life (33 minutes) + +/obj/item/fuel_rod/depleted + fuel_power = 0.05 + name = "Depleted Fuel Rod" + desc = "A highly radioactive fuel rod which has expended most of it's useful energy." + icon_state = "normal" + rad_strength = 6000 // smelly + depletion_conversion_type = null // It means that it won't turn into anything + process = TRUE + +// Master type for material optional (or requiring, wyci) and/or producing rods +/obj/item/fuel_rod/material + // Whether the rod has been harvested. Should be set in expend(). + var/expended = FALSE + // The material that will be inserted and then multiplied (or not). Should be some sort of /obj/item/stack + var/material_type + // The name of material that'll be used for texts + var/material_name + var/material_name_singular + var/initial_amount = 0 + // The maximum amount of material the rod can hold + var/max_initial_amount = 10 + var/grown_amount = 0 + // The multiplier for growth. 1 for the same 2 for double etc etc + var/multiplier = 2 + // After this depletion, you won't be able to add new materials + var/material_input_deadline = 25 + // Material fuel rods generally don't get converted into another fuel object + depletion_conversion_type = null + +// Called when the rod is fully harvested +/obj/item/fuel_rod/material/proc/expend() + expended = TRUE + +// Basic checks for material rods +/obj/item/fuel_rod/material/proc/check_material_input(mob/user) + if(depletion >= material_input_deadline) + to_chat(user, "The sample slots have sealed themselves shut, it's too late to add [material_name] now!") // no cheesing in crystals at 100% + return FALSE + if(expended) + to_chat(user, "\The [src]'s material slots have already been used.") + return FALSE + return TRUE + +// The actual growth +/obj/item/fuel_rod/material/depletion_final(result_rod) + if(result_rod) + ..() // So if you put anything into depletion_conversion_type then your fuel rod will be converted (or not) and *won't grow* + else + grown_amount = initial_amount * multiplier + +/obj/item/fuel_rod/material/attackby(obj/item/W, mob/user, params) + var/obj/item/stack/M = W + if(istype(M, material_type)) + if(!check_material_input(user)) + return + if(initial_amount < max_initial_amount) + var/adding = min((max_initial_amount - initial_amount), M.amount) + M.amount -= adding + initial_amount += adding + if (adding == 1) + to_chat(user, "You insert [adding] [material_name_singular] into \the [src].") + else + to_chat(user, "You insert [adding] [material_name] into \the [src].") + M.zero_amount() + else + to_chat(user, "\The [src]'s material slots are full!") + return + else + return ..() + +/obj/item/fuel_rod/material/attack_self(mob/user) + if(expended) + to_chat(user, "You have already removed [material_name] from \the [src].") + return + + if(depleted_final) + new material_type(user.loc, grown_amount) + if (grown_amount == 1) + to_chat(user, "You harvest [grown_amount] [material_name_singular] from \the [src].") // Unlikely + else + to_chat(user, "You harvest [grown_amount] [material_name] from \the [src].") + playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1) + grown_amount = 0 + expend() + else if(depletion) + to_chat(user, "\The [src] has not fissiled enough to fully grow the sample. The progress bar shows it is [min(depletion/depletion_threshold*100,100)]% complete.") + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0) + else if(initial_amount) + new material_type(user.loc, initial_amount) + if (initial_amount == 1) + to_chat(user, "You remove [initial_amount] [material_name_singular] from \the [src].") + else + to_chat(user, "You remove [initial_amount] [material_name] from \the [src].") + playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1) + initial_amount = 0 + +/obj/item/fuel_rod/material/examine(mob/user) + . = ..() + if(expended) + . += "The material slots have been slagged by the extreme heat, you can't grow [material_name] in this rod again..." + return + else if(depleted_final) + . += "This fuel rod's [material_name] are now fully grown, and it currently bears [grown_amount] harvestable [material_name_singular]\s." + return + if(depletion) + . += "The sample is [min(depletion/depletion_threshold*100,100)]% fissiled." + . += "[initial_amount]/[max_initial_amount] of the slots for [material_name] are full." + +/obj/item/fuel_rod/material/telecrystal + name = "Telecrystal Fuel Rod" + desc = "A disguised titanium sheathed rod containing several small slots infused with uranium dioxide. Permits the insertion of telecrystals to grow more. Fissiles much faster than its standard counterpart" + icon_state = "telecrystal" + fuel_power = 0.30 // twice as powerful as a normal rod, you're going to need some engineering autism if you plan to mass produce TC + depletion_speed_modifier = 3 // headstart, otherwise it takes two hours + rad_strength = 1500 + max_initial_amount = 8 + multiplier = 3 + material_type = /obj/item/stack/telecrystal + material_name = "telecrystals" + material_name_singular = "telecrystal" + +/obj/item/fuel_rod/material/telecrystal/depletion_final(result_rod) + ..() + if(result_rod) + return + fuel_power = 0.60 // thrice as powerful as plutonium, you'll want to get this one out quick! + name = "Exhausted Telecrystal Fuel Rod" + desc = "A highly energetic, disguised titanium sheathed rod containing a number of slots filled with greatly expanded telecrystals which can be removed by hand. It's extremely efficient as nuclear fuel, but will cause the reaction to get out of control if not properly utilised." + icon_state = "telecrystal_used" + AddComponent(/datum/component/radioactive, 3000, src) + +/obj/item/fuel_rod/material/bananium + name = "Bananium Fuel Rod" + desc = "A hilarious heavy-duty fuel rod which fissiles a bit slower than its cowardly counterparts. However, its cutting-edge cosmic clown technology allows rooms for extraordinarily exhilarating extraterrestrial element called bananium to menacingly multiply." + icon_state = "bananium" + fuel_power = 0.15 + depletion_speed_modifier = 3 + rad_strength = 350 + max_initial_amount = 10 + multiplier = 3 + material_type = /obj/item/stack/sheet/mineral/bananium + material_name = "sheets of bananium" + material_name_singular = "sheet of bananium" + +/obj/item/fuel_rod/material/bananium/deplete(amount=0.035) + ..() + if(initial_amount == max_initial_amount && prob(10)) + playsound(src, pick('sound/items/bikehorn.ogg', 'sound/misc/bikehorn_creepy.ogg'), 50) // HONK + +/obj/item/fuel_rod/material/bananium/depletion_final(result_rod) + ..() + if(result_rod) + return + fuel_power = 0.3 // Be warned + name = "Fully Grown Bananium Fuel Rod" + desc = "A hilarious heavy-duty fuel rod which fissiles a bit slower than it cowardly counterparts. Its greatly grimacing grwoth stage is now over, and bananium outgrowth hums as if it's blatantly honking bike horns." + icon_state = "bananium_used" + AddComponent(/datum/component/radioactive, 1250, src) diff --git a/code/modules/power/reactor/rbmk.dm b/code/modules/power/reactor/rbmk.dm new file mode 100644 index 0000000000..cea10c6116 --- /dev/null +++ b/code/modules/power/reactor/rbmk.dm @@ -0,0 +1,1012 @@ +//For my sanity :)) + +#define COOLANT_INPUT_GATE airs[1] +#define MODERATOR_INPUT_GATE airs[2] +#define COOLANT_OUTPUT_GATE airs[3] + +#define RBMK_TEMPERATURE_OPERATING 640 //Celsius +#define RBMK_TEMPERATURE_CRITICAL 810 //At this point the entire ship/station is alerted to a meltdown. This may need altering +#define RBMK_TEMPERATURE_MELTDOWN 900 + +#define RBMK_NO_COOLANT_TOLERANCE 5 //How many process()ing ticks the reactor can sustain without coolant before slowly taking damage + +#define RBMK_PRESSURE_OPERATING 1000 //PSI +#define RBMK_PRESSURE_CRITICAL 1469.59 //PSI + +#define RBMK_MAX_CRITICALITY 3 //No more criticality than N for now. + +#define RBMK_POWER_FLAVOURISER 1000 //To turn those KWs into something usable + +//Math. Lame. +#define KPA_TO_PSI(A) (A/6.895) +#define PSI_TO_KPA(A) (A*6.895) +#define KELVIN_TO_CELSIUS(A) (A-273.15) +#define MEGAWATTS /1e+6 +#define CELSIUS_TO_KELVIN(T_K) ((T_K) + T0C) + +//Reference: Heaters go up to 500K. +//Hot plasmaburn: 14164.95 C. + +/** +What is this? +Moderators list (Not gonna keep this accurate forever): +Fuel Type: +Oxygen: Power production multiplier. Allows you to run a low plasma, high oxy mix, and still get a lot of power. +Plasma: Power production gas. More plasma -> more power, but it enriches your fuel and makes the reactor much, much harder to control. +Tritium: Extremely efficient power production gas. Will cause chernobyl if used improperly. +Moderation Type: +N2: Helps you regain control of the reaction by increasing control rod effectiveness, will massively boost the rad production of the reactor. +CO2: Super effective shutdown gas for runaway reactions. MASSIVE RADIATION PENALTY! +Pluoxium: Same as N2, but no cancer-rads! +Permeability Type: +BZ: Increases your reactor's ability to transfer its heat to the coolant, thus letting you cool it down faster (but your output will get hotter) +Water Vapour: More efficient permeability modifier +Hyper Noblium: Extremely efficient permeability increase. (10x as efficient as bz) +Depletion type: +Nitryl: When you need weapons grade plutonium yesterday. Causes your fuel to deplete much, much faster. Not a huge amount of use outside of sabotage. +Sabotage: +Meltdown: +Flood reactor moderator with plasma, they won't be able to mitigate the reaction with control rods. +Shut off coolant entirely. Raise control rods. +Swap all fuel out with spent fuel, as it's way stronger. +Blowout: +Shut off exit valve for quick overpressure. +Cause a pipefire in the coolant line (LETHAL). +Tack heater onto coolant line (can also cause straight meltdown) +Tips: +Be careful to not exhaust your plasma supply. I recommend you DON'T max out the moderator input when youre running plasma + o2, or you're at a tangible risk of running out of those gasses from atmos. +The reactor CHEWS through moderator. It does not do this slowly. Be very careful with that! +*/ + +//Remember kids. If the reactor itself is not physically powered by an APC, it cannot shove coolant in! + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor + name = "Advanced Gas-Cooled Nuclear Reactor" + desc = "A tried and tested design which can output stable power at an acceptably low risk. The moderator can be changed to provide different effects." + icon = 'icons/obj/machines/rbmk.dmi' + icon_state = "reactor_map" + pixel_x = -32 + pixel_y = -32 + density = FALSE //It burns you if you're stupid enough to walk over it. + anchored = TRUE + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF + light_color = LIGHT_COLOR_CYAN + dir = WEST //Less headache inducing :)) + var/id = null //Change me mappers + //Variables essential to operation + var/temperature = 0 //Lose control of this -> Meltdown + var/vessel_integrity = 400 //How long can the reactor withstand overpressure / meltdown? This gives you a fair chance to react to even a massive pipe fire + var/pressure = 0 //Lose control of this -> Blowout + var/K = 0 //Rate of reaction. + var/desired_k = 0 + var/control_rod_effectiveness = 0.65 //Starts off with a lot of control over K. If you flood this thing with plasma, you lose your ability to control K as easily. + var/power = 0 //0-100%. A function of the maximum heat you can achieve within operating temperature + var/power_modifier = 1 //Upgrade me with parts, science! Flat out increase to physical power output when loaded with plasma. + var/list/fuel_rods = list() + //Secondary variables. + var/next_slowprocess = 0 + var/gas_absorption_effectiveness = 0.5 + var/gas_absorption_constant = 0.5 //We refer to this one as it's set on init, randomized. + var/minimum_coolant_level = 2 + var/warning = FALSE //Have we begun warning the crew of their impending death? + var/next_warning = 0 //To avoid spam. + var/last_power_produced = 0 //For logging purposes + var/next_flicker = 0 //Light flicker timer + var/base_power_modifier = RBMK_POWER_FLAVOURISER + var/slagged = FALSE //Is this reactor even usable any more? + //Console statistics. + var/last_coolant_temperature = 0 + var/last_output_temperature = 0 + var/last_heat_delta = 0 //For administrative cheating only. Knowing the delta lets you know EXACTLY what to set K at. + var/no_coolant_ticks = 0 //How many times in succession did we not have enough coolant? Decays twice as fast as it accumulates. + var/last_user = null + var/current_desired_k = null + var/datum/looping_sound/rbmk_reactor/soundloop + var/datum/powernet/powernet = null + +//Use this in your maps if you want everything to be preset. +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/preset + id = "default_reactor_for_lazy_mappers" + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/examine(mob/user) + . = ..() + if(Adjacent(src, user)) + if(do_after(user, 1 SECONDS, target=src)) + var/percent = vessel_integrity / initial(vessel_integrity) * 100 + var/msg = "The reactor looks operational." + switch(percent) + if(0 to 10) + msg = "[src]'s seals are dangerously warped and you can see cracks all over the reactor vessel! " + if(10 to 40) + msg = "[src]'s seals are heavily warped and cracked! " + if(40 to 60) + msg = "[src]'s seals are holding, but barely. You can see some micro-fractures forming in the reactor vessel." + if(60 to 80) + msg = "[src]'s seals are in-tact, but slightly worn. There are no visible cracks in the reactor vessel." + if(80 to 90) + msg = "[src]'s seals are in good shape, and there are no visible cracks in the reactor vessel." + if(95 to 100) + msg = "[src]'s seals look factory new, and the reactor's in excellent shape." + . += msg + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/fuel_rod)) + if(power >= 20) + to_chat(user, "You cannot insert fuel into [src] when it has been raised above 20% power.") + return FALSE + if(fuel_rods.len >= 5) + to_chat(user, "[src] is already at maximum fuel load.") + return FALSE + to_chat(user, "You start to insert [W] into [src]...") + radiation_pulse(src, temperature) + if(do_after(user, 5 SECONDS, target=src)) + if(!fuel_rods.len) + start_up() //That was the first fuel rod. Let's heat it up. + message_admins("Reactor first started up by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(src)]") + investigate_log("Reactor first started by [key_name(user)] at [AREACOORD(src)]", INVESTIGATE_SINGULO) + fuel_rods += W + W.forceMove(src) + radiation_pulse(src, temperature) //Wear protective equipment when even breathing near a reactor! + investigate_log("Rod added to reactor by [key_name(user)] at [AREACOORD(src)]", INVESTIGATE_SINGULO) + return TRUE + if(istype(W, /obj/item/sealant)) + if(power >= 20) + to_chat(user, "You cannot repair [src] while it is running at above 20% power.") + return FALSE + if(vessel_integrity >= 350) + to_chat(user, "[src]'s seals are already in-tact, repairing them further would require a new set of seals.") + return FALSE + if(vessel_integrity <= 0.5 * initial(vessel_integrity)) //Heavily damaged. + to_chat(user, "[src]'s reactor vessel is cracked and worn, you need to repair the cracks with a welder before you can repair the seals.") + return FALSE + if(do_after(user, 5 SECONDS, target=src)) + if(vessel_integrity >= 350) //They might've stacked doafters + to_chat(user, "[src]'s seals are already in-tact, repairing them further would require a new set of seals.") + return FALSE + playsound(src, 'sound/effects/spray2.ogg', 50, 1, -6) + user.visible_message("[user] applies sealant to some of [src]'s worn out seals.", "You apply sealant to some of [src]'s worn out seals.") + vessel_integrity += 10 + vessel_integrity = clamp(vessel_integrity, 0, initial(vessel_integrity)) + return TRUE + return ..() + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/welder_act(mob/living/user, obj/item/I) + if(power >= 20) + to_chat(user, "You can't repair [src] while it is running at above 20% power.") + return FALSE + if(vessel_integrity > 0.5 * initial(vessel_integrity)) + to_chat(user, "[src] is free from cracks. Further repairs must be carried out with flexi-seal sealant.") + return FALSE + if(I.use_tool(src, user, 0, volume=40)) + if(vessel_integrity > 0.5 * initial(vessel_integrity)) + to_chat(user, "[src] is free from cracks. Further repairs must be carried out with flexi-seal sealant.") + return FALSE + vessel_integrity += 20 + to_chat(user, "You weld together some of [src]'s cracks. This'll do for now.") + return TRUE + +//Admin procs to mess with the reaction environment. + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/lazy_startup() + for(var/I=0;I<5;I++) + fuel_rods += new /obj/item/fuel_rod(src) + message_admins("Reactor started up by admins in [ADMIN_VERBOSEJMP(src)]") + start_up() + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/deplete() + for(var/obj/item/fuel_rod/FR in fuel_rods) + FR.depletion = 100 + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/Initialize() + . = ..() + connect_to_network() + icon_state = "reactor_off" + gas_absorption_effectiveness = rand(5, 6)/10 //All reactors are slightly different. This will result in you having to figure out what the balance is for K. + gas_absorption_constant = gas_absorption_effectiveness //And set this up for the rest of the round. + STOP_PROCESSING(SSmachines, src) //We'll handle this one ourselves. + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/Crossed(atom/movable/AM, oldloc) + . = ..() + if(isliving(AM) && temperature > 0) + var/mob/living/L = AM + L.adjust_bodytemperature(clamp(temperature, BODYTEMP_COOLING_MAX, BODYTEMP_HEATING_MAX)) //If you're on fire, you heat up! + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/process() + update_parents() //Update the pipenet to register new gas mixes + if(next_slowprocess < world.time) + slowprocess() + next_slowprocess = world.time + 1 SECONDS //Set to wait for another second before processing again, we don't need to process more than once a second + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/has_fuel() + return fuel_rods?.len + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/slowprocess() + //Let's get our gasses sorted out. + var/datum/gas_mixture/coolant_input = COOLANT_INPUT_GATE + var/datum/gas_mixture/moderator_input = MODERATOR_INPUT_GATE + var/datum/gas_mixture/coolant_output = COOLANT_OUTPUT_GATE + + //Firstly, heat up the reactor based off of K. + var/input_moles = coolant_input.total_moles() //Firstly. Do we have enough moles of coolant? + if(input_moles >= minimum_coolant_level) + last_coolant_temperature = KELVIN_TO_CELSIUS(coolant_input.return_temperature()) + //Important thing to remember, once you slot in the fuel rods, this thing will not stop making heat, at least, not unless you can live to be thousands of years old which is when the spent fuel finally depletes fully. + var/heat_delta = (KELVIN_TO_CELSIUS(coolant_input.return_temperature()) / 100) * gas_absorption_effectiveness //Take in the gas as a cooled input, cool the reactor a bit. The optimum, 100% balanced reaction sits at K=1, coolant input temp of 200K / -73 celsius. + last_heat_delta = heat_delta + temperature += heat_delta + coolant_output.merge(coolant_input) //And now, shove the input into the output. + coolant_input.clear() //Clear out anything left in the input gate. + color = null + no_coolant_ticks = max(0, no_coolant_ticks-2) //Needs half as much time to recover the ticks than to acquire them + else + if(has_fuel()) + no_coolant_ticks++ + if(no_coolant_ticks > RBMK_NO_COOLANT_TOLERANCE) + temperature += temperature / 500 //This isn't really harmful early game, but when your reactor is up to full power, this can get out of hand quite quickly. + vessel_integrity -= temperature / 200 //Think fast chucklenuts! + take_damage(10) //Just for the sound effect, to let you know you've fucked up. + color = "[COLOR_RED]" + investigate_log("Reactor taking damage from the lack of coolant", INVESTIGATE_SINGULO) + //Now, heat up the output and set our pressure. + coolant_output.set_temperature(CELSIUS_TO_KELVIN(temperature)) //Heat the coolant output gas that we just had pass through us. + last_output_temperature = KELVIN_TO_CELSIUS(coolant_output.return_temperature()) + pressure = KPA_TO_PSI(coolant_output.return_pressure()) + power = (temperature / RBMK_TEMPERATURE_CRITICAL) * 100 + var/radioactivity_spice_multiplier = 1 //Some gasses make the reactor a bit spicy. + var/depletion_modifier = 0.035 //How rapidly do your rods decay + gas_absorption_effectiveness = gas_absorption_constant + //Next up, handle moderators! + if(moderator_input.total_moles() >= minimum_coolant_level) + var/total_fuel_moles = moderator_input.get_moles(GAS_PLASMA) + (moderator_input.get_moles(GAS_TRITIUM)*10) //Constricted plasma is 50% more efficient as fuel than plasma, but is harder to produce + var/power_modifier = max((moderator_input.get_moles(GAS_O2) / moderator_input.total_moles() * 10), 1) //You can never have negative IPM. For now. + if(total_fuel_moles >= minimum_coolant_level) //You at least need SOME fuel. + var/power_produced = max((total_fuel_moles / moderator_input.total_moles() * 10), 1) + last_power_produced = max(0,((power_produced*power_modifier)*moderator_input.total_moles())) + last_power_produced *= (power/100) //Aaaand here comes the cap. Hotter reactor => more power. + last_power_produced *= base_power_modifier //Finally, we turn it into actual usable numbers. + radioactivity_spice_multiplier += moderator_input.get_moles(GAS_TRITIUM) / 5 //Chernobyl 2. + var/turf/T = get_turf(src) + if(power >= 20) + coolant_output.adjust_moles(GAS_NITRYL, total_fuel_moles/50) //Shove out nitryl into the air when it's fuelled. You need to filter this off, or you're gonna have a bad time. + var/obj/structure/cable/C = T.get_cable_node() + if(!C?.powernet) + //message_admins("No cable or cable has no powernet!") + return + else + C.powernet.newavail += last_power_produced //hacky wtf + //message_admins("Adding [last_power_produced] to powernet.") + add_avail(last_power_produced) + var/total_control_moles = moderator_input.get_moles(GAS_N2) + (moderator_input.get_moles(GAS_CO2)*2) + (moderator_input.get_moles(GAS_PLUOXIUM)*3) //N2 helps you control the reaction at the cost of making it absolutely blast you with rads. Pluoxium has the same effect but without the rads! + if(total_control_moles >= minimum_coolant_level) + var/control_bonus = total_control_moles / 250 //1 mol of n2 -> 0.002 bonus control rod effectiveness, if you want a super controlled reaction, you'll have to sacrifice some power. + control_rod_effectiveness = initial(control_rod_effectiveness) + control_bonus + radioactivity_spice_multiplier += moderator_input.get_moles(GAS_N2) / 25 //An example setup of 50 moles of n2 (for dealing with spent fuel) leaves us with a radioactivity spice multiplier of 3. + radioactivity_spice_multiplier += moderator_input.get_moles(GAS_CO2) / 12.5 + var/total_permeability_moles = moderator_input.get_moles(GAS_BZ) + (moderator_input.get_moles(GAS_H2O)*2) + (moderator_input.get_moles(GAS_HYPERNOB)*10) + if(total_permeability_moles >= minimum_coolant_level) + var/permeability_bonus = total_permeability_moles / 500 + gas_absorption_effectiveness = gas_absorption_constant + permeability_bonus + var/total_degradation_moles = moderator_input.get_moles(GAS_NITRYL) //Because it's quite hard to get. + if(total_degradation_moles >= minimum_coolant_level*0.5) //I'll be nice. + depletion_modifier += total_degradation_moles / 15 //Oops! All depletion. This causes your fuel rods to get SPICY. + playsound(src, pick('sound/machines/sm/accent/normal/1.ogg','sound/machines/sm/accent/normal/2.ogg','sound/machines/sm/accent/normal/3.ogg','sound/machines/sm/accent/normal/4.ogg','sound/machines/sm/accent/normal/5.ogg'), 100, TRUE) + //From this point onwards, we clear out the remaining gasses. + moderator_input.clear() //Woosh. And the soul is gone. + K += total_fuel_moles / 1000 + var/fuel_power = 0 //So that you can't magically generate K with your control rods. + if(!has_fuel()) //Reactor must be fuelled and ready to go before we can heat it up boys. + K = 0 + else + for(var/obj/item/fuel_rod/FR in fuel_rods) + K += FR.fuel_power + fuel_power += FR.fuel_power + FR.deplete(depletion_modifier) + //Firstly, find the difference between the two numbers. + var/difference = abs(K - desired_k) + //Then, hit as much of that goal with our cooling per tick as we possibly can. + difference = clamp(difference, 0, control_rod_effectiveness) //And we can't instantly zap the K to what we want, so let's zap as much of it as we can manage.... + if(difference > fuel_power && desired_k > K) + message_admins("Not enough fuel to get [difference]. We have fuel [fuel_power]") + investigate_log("Reactor has not enough fuel to get [difference]. We have fuel [fuel_power]", INVESTIGATE_SINGULO) + difference = fuel_power //Again, to stop you being able to run off of 1 fuel rod. + if(K != desired_k) + if(desired_k > K) + K += difference + else if(desired_k < K) + K -= difference + if(K == desired_k && last_user && current_desired_k != desired_k) + current_desired_k = desired_k + message_admins("Reactor desired criticality set to [desired_k] by [ADMIN_LOOKUPFLW(last_user)] in [ADMIN_VERBOSEJMP(src)]") + investigate_log("reactor desired criticality set to [desired_k] by [key_name(last_user)] at [AREACOORD(src)]", INVESTIGATE_SINGULO) + + K = clamp(K, 0, RBMK_MAX_CRITICALITY) + if(has_fuel()) + temperature += K + else + temperature -= 10 //Nothing to heat us up, so. + handle_alerts() //Let's check if they're about to die, and let them know. + update_icon() + radiation_pulse(src, temperature*radioactivity_spice_multiplier) + if(power >= 93 && world.time >= next_flicker) //You're overloading the reactor. Give a more subtle warning that power is getting out of control. + next_flicker = world.time + 2 MINUTES + for(var/obj/machinery/light/L in GLOB.machines) + if(prob(25) && L.z == z) //If youre running the reactor cold though, no need to flicker the lights. + L.flicker() + investigate_log("Reactor overloading at [power]% power", INVESTIGATE_SINGULO) + for(var/atom/movable/I in get_turf(src)) + if(isliving(I)) + var/mob/living/L = I + if(temperature > 0) + L.adjust_bodytemperature(clamp(temperature, BODYTEMP_COOLING_MAX, BODYTEMP_HEATING_MAX)) //If you're on fire, you heat up! + if(istype(I, /obj/item/reagent_containers/food) && !istype(I, /obj/item/reagent_containers/food/drinks)) + playsound(src, pick('sound/machines/fryer/deep_fryer_1.ogg', 'sound/machines/fryer/deep_fryer_2.ogg'), 100, TRUE) + var/obj/item/reagent_containers/food/grilled_item = I + if(prob(80)) + continue //To give the illusion that it's actually cooking omegalul. + switch(power) + if(20 to 39) + grilled_item.name = "grilled [initial(grilled_item.name)]" + grilled_item.desc = "[initial(I.desc)] It's been grilled over a nuclear reactor." + if(!(grilled_item.foodtype & FRIED)) + grilled_item.foodtype |= FRIED + if(40 to 70) + grilled_item.name = "heavily grilled [initial(grilled_item.name)]" + grilled_item.desc = "[initial(I.desc)] It's been heavily grilled through the magic of nuclear fission." + if(!(grilled_item.foodtype & FRIED)) + grilled_item.foodtype |= FRIED + if(70 to 95) + grilled_item.name = "Three-Mile Nuclear-Grilled [initial(grilled_item.name)]" + grilled_item.desc = "A [initial(grilled_item.name)]. It's been put on top of a nuclear reactor running at extreme power by some badass engineer." + if(!(grilled_item.foodtype & FRIED)) + grilled_item.foodtype |= FRIED + if(95 to INFINITY) + grilled_item.name = "Ultimate Meltdown Grilled [initial(grilled_item.name)]" + grilled_item.desc = "A [initial(grilled_item.name)]. A grill this perfect is a rare technique only known by a few engineers who know how to perform a 'controlled' meltdown whilst also having the time to throw food on a reactor. I'll bet it tastes amazing." + if(!(grilled_item.foodtype & FRIED)) + grilled_item.foodtype |= FRIED + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/relay(var/sound, var/message=null, loop = FALSE, channel = null) //Sends a sound + text message to the crew of a ship + for(var/mob/M in GLOB.player_list) + if(M.z == z) + if(!isinspace(M)) + if(sound) + if(channel) //Doing this forbids overlapping of sounds + SEND_SOUND(M, sound(sound, repeat = loop, wait = 0, volume = 70, channel = channel)) + else + SEND_SOUND(M, sound(sound, repeat = loop, wait = 0, volume = 70)) + if(message) + to_chat(M, message) + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/stop_relay(channel) //Stops all playing sounds for crewmen on N channel. + for(var/mob/M in GLOB.player_list) + if(M.z == z) + M.stop_sound_channel(channel) + +//Method to handle sound effects, reactor warnings, all that jazz. +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/handle_alerts() + var/alert = FALSE //If we have an alert condition, we'd best let people know. + if(K <= 0 && temperature <= 0) + shut_down() + //First alert condition: Overheat + if(temperature >= RBMK_TEMPERATURE_CRITICAL) + alert = TRUE + investigate_log("Reactor reaching critical temperature at [temperature] C with desired criticality at [desired_k]", INVESTIGATE_SINGULO) + message_admins("Reactor reaching critical temperature at [ADMIN_VERBOSEJMP(src)]") + if(temperature >= RBMK_TEMPERATURE_MELTDOWN) + var/temp_damage = min(temperature/100, initial(vessel_integrity)/40) //40 seconds to meltdown from full integrity, worst-case. Bit less than blowout since it's harder to spike heat that much. + vessel_integrity -= temp_damage + if(vessel_integrity <= temp_damage) + investigate_log("Reactor melted down at [temperature] C with desired criticality at [desired_k]", INVESTIGATE_SINGULO) + meltdown() //Oops! All meltdown + return + else + alert = FALSE + if(temperature < -200) //That's as cold as I'm letting you get it, engineering. + color = COLOR_CYAN + temperature = -200 + else + color = null + //Second alert condition: Overpressurized (the more lethal one) + if(pressure >= RBMK_PRESSURE_CRITICAL) + alert = TRUE + investigate_log("Reactor reaching critical pressure at [pressure] PSI with desired criticality at [desired_k]", INVESTIGATE_SINGULO) + message_admins("Reactor reaching critical pressure at [ADMIN_VERBOSEJMP(src)]") + shake_animation(0.5) + playsound(loc, 'sound/machines/clockcult/steam_whoosh.ogg', 100, TRUE) + var/turf/T = get_turf(src) + T.atmos_spawn_air("water_vapor=[pressure/100];TEMP=[CELSIUS_TO_KELVIN(temperature)]") + var/pressure_damage = min(pressure/100, initial(vessel_integrity)/45) //You get 45 seconds (if you had full integrity), worst-case. But hey, at least it can't be instantly nuked with a pipe-fire.. though it's still very difficult to save. + vessel_integrity -= pressure_damage + if(vessel_integrity <= pressure_damage) //It wouldn't + investigate_log("Reactor blowout at [pressure] PSI with desired criticality at [desired_k]", INVESTIGATE_SINGULO) + blowout() + return + if(warning) + if(!alert) //Congrats! You stopped the meltdown / blowout. + stop_relay(CHANNEL_REACTOR_ALERT) + warning = FALSE + set_light(0) + light_color = LIGHT_COLOR_CYAN + set_light(10) + else + if(!alert) + return + if(world.time < next_warning) + return + next_warning = world.time + 30 SECONDS //To avoid engis pissing people off when reaaaally trying to stop the meltdown or whatever. + warning = TRUE //Start warning the crew of the imminent danger. + relay('sound/effects/rbmk/alarm.ogg', null, loop=TRUE, channel = CHANNEL_REACTOR_ALERT) + set_light(0) + light_color = LIGHT_COLOR_RED + set_light(10) + +//Failure condition 1: Meltdown. Achieved by having heat go over tolerances. This is less devastating because it's easier to achieve. +//Results: Engineering becomes unusable and your engine irreparable +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/meltdown() + set waitfor = FALSE + SSair.atmos_machinery -= src //Annd we're now just a useless brick. + slagged = TRUE + color = null + update_icon() + STOP_PROCESSING(SSmachines, src) + icon_state = "reactor_slagged" + AddComponent(/datum/component/radioactive, 15000 , src, 0) + var/obj/effect/landmark/nuclear_waste_spawner/NSW = new /obj/effect/landmark/nuclear_waste_spawner/strong(get_turf(src)) + relay('sound/effects/rbmk/meltdown.ogg', "You hear a horrible metallic hissing.") + stop_relay(CHANNEL_REACTOR_ALERT) + NSW.fire() //This will take out engineering for a decent amount of time as they have to clean up the sludge. + for(var/obj/machinery/power/apc/apc in GLOB.apcs_list) + if((apc.z == z) && prob(70)) + apc.overload_lighting() + var/datum/gas_mixture/coolant_input = COOLANT_INPUT_GATE + var/datum/gas_mixture/moderator_input = MODERATOR_INPUT_GATE + var/datum/gas_mixture/coolant_output = COOLANT_OUTPUT_GATE + var/turf/T = get_turf(src) + coolant_input.set_temperature(CELSIUS_TO_KELVIN(temperature)*2) + moderator_input.set_temperature(CELSIUS_TO_KELVIN(temperature)*2) + coolant_output.set_temperature(CELSIUS_TO_KELVIN(temperature)*2) + T.assume_air(coolant_input) + T.assume_air(moderator_input) + T.assume_air(coolant_output) + power = 0 //we set it to zero so the reactor can be serviced and repaired. + explosion(get_turf(src), 0, 5, 10, 20, TRUE, TRUE) + empulse(get_turf(src), 25, 15) + QDEL_NULL(soundloop) + +//Failure condition 2: Blowout. Achieved by reactor going over-pressured. This is a round-ender because it requires more fuckery to achieve. +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/blowout() + explosion(get_turf(src), GLOB.MAX_EX_DEVESTATION_RANGE, GLOB.MAX_EX_HEAVY_RANGE, GLOB.MAX_EX_LIGHT_RANGE, GLOB.MAX_EX_FLASH_RANGE) + meltdown() //Double kill. + power = 0 //we set it to zero so the reactor can be serviced and repaired. + SSweather.run_weather("nuclear fallout") + for(var/X in GLOB.landmarks_list) + if(istype(X, /obj/effect/landmark/nuclear_waste_spawner)) + var/obj/effect/landmark/nuclear_waste_spawner/WS = X + if(is_station_level(WS.z)) //Begin the SLUDGING + WS.fire() + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/update_icon() + icon_state = "reactor_off" + switch(temperature) + if(0 to 200) + icon_state = "reactor_on" + if(200 to RBMK_TEMPERATURE_OPERATING) + icon_state = "reactor_hot" + if(RBMK_TEMPERATURE_OPERATING to 750) + icon_state = "reactor_veryhot" + if(750 to RBMK_TEMPERATURE_CRITICAL) //Point of no return. + icon_state = "reactor_overheat" + if(RBMK_TEMPERATURE_CRITICAL to INFINITY) + icon_state = "reactor_meltdown" + if(!has_fuel()) + icon_state = "reactor_off" + if(slagged) + icon_state = "reactor_slagged" + + +//Startup, shutdown + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/start_up() + START_PROCESSING(SSmachines, src) + desired_k = 1 + set_light(10) + var/startup_sound = pick('sound/effects/ship/reactor/startup.ogg', 'sound/effects/ship/reactor/startup2.ogg') + playsound(loc, startup_sound, 100) + soundloop = new(src, TRUE) + if(!powernet) + message_admins("No powernet for the Nuclear Reactor! Trying to add.") + connect_to_network() + if(!powernet) + message_admins("Powernet add fail. This reactor will never produce power.") + +//Shuts off the fuel rods, ambience, etc. Keep in mind that your temperature may still go up! +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/shut_down() + STOP_PROCESSING(SSmachines, src) + set_light(0) + K = 0 + desired_k = 0 + temperature = 0 + update_icon() + QDEL_NULL(soundloop) + +/obj/item/fuel_rod/Initialize() + .=..() + AddComponent(/datum/component/radioactive, 350 , src) + +//Controlling the reactor. + +/obj/machinery/computer/reactor + name = "Reactor control console" + desc = "Scream" + light_color = "#55BA55" + light_power = 1 + light_range = 3 + icon = 'icons/obj/rbmk_computer.dmi' + icon_state = "oldcomp" + icon_screen = "library" + icon_keyboard = null + var/obj/machinery/atmospherics/components/trinary/nuclear_reactor/reactor = null + var/id = "default_reactor_for_lazy_mappers" + +/obj/machinery/computer/reactor/Initialize(mapload, obj/item/circuitboard/C) + . = ..() + addtimer(CALLBACK(src, .proc/link_to_reactor), 10 SECONDS) + +/obj/machinery/computer/reactor/wrench_act(mob/living/user, obj/item/I) + to_chat(user, "You start [anchored ? "un" : ""]securing [name]...") + if(I.use_tool(src, user, 40, volume=75)) + to_chat(user, "You [anchored ? "un" : ""]secure [name].") + setAnchored(!anchored) + return TRUE + return FALSE + +/obj/machinery/computer/reactor/proc/link_to_reactor() + for(var/obj/machinery/atmospherics/components/trinary/nuclear_reactor/asdf in GLOB.machines) + if(asdf.id && asdf.id == id) + reactor = asdf + return TRUE + return FALSE + +#define FREQ_RBMK_CONTROL 1439.69 + +/obj/machinery/computer/reactor/control_rods + name = "Control rod management computer" + desc = "A computer which can remotely raise / lower the control rods of a reactor." + icon_screen = "rbmk_rods" + +/obj/machinery/computer/reactor/control_rods/attack_hand(mob/living/user) + . = ..() + ui_interact(user) + +/obj/machinery/computer/reactor/control_rods/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "RbmkControlRods") + ui.open() + ui.set_autoupdate(TRUE) + +/obj/machinery/computer/reactor/control_rods/ui_act(action, params) + if(..()) + return + if(!reactor) + return + if(action == "input") + var/input = text2num(params["target"]) + reactor.last_user = usr + reactor.desired_k = clamp(input, 0, 3) + +/obj/machinery/computer/reactor/control_rods/ui_data(mob/user) + var/list/data = list() + data["control_rods"] = 0 + data["k"] = 0 + data["desiredK"] = 0 + if(reactor) + data["k"] = reactor.K + data["desiredK"] = reactor.desired_k + data["control_rods"] = 100 - (reactor.desired_k / 3 * 100) //Rod insertion is extrapolated as a function of the percentage of K + return data + +/obj/machinery/computer/reactor/stats + name = "Reactor Statistics Console" + desc = "A console for monitoring the statistics of a nuclear reactor." + icon_screen = "rbmk_stats" + var/next_stat_interval = 0 + var/list/psiData = list() + var/list/powerData = list() + var/list/tempInputData = list() + var/list/tempOutputdata = list() + +/obj/machinery/computer/reactor/stats/attack_hand(mob/living/user) + . = ..() + ui_interact(user) + +/obj/machinery/computer/reactor/stats/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "RbmkStats") + ui.open() + ui.set_autoupdate(TRUE) + +/obj/machinery/computer/reactor/stats/process() + if(world.time >= next_stat_interval) + next_stat_interval = world.time + 1 SECONDS //You only get a slow tick. + psiData += (reactor) ? reactor.pressure : 0 + if(psiData.len > 100) //Only lets you track over a certain timeframe. + psiData.Cut(1, 2) + powerData += (reactor) ? reactor.power*10 : 0 //We scale up the figure for a consistent:tm: scale + if(powerData.len > 100) //Only lets you track over a certain timeframe. + powerData.Cut(1, 2) + tempInputData += (reactor) ? reactor.last_coolant_temperature : 0 //We scale up the figure for a consistent:tm: scale + if(tempInputData.len > 100) //Only lets you track over a certain timeframe. + tempInputData.Cut(1, 2) + tempOutputdata += (reactor) ? reactor.last_output_temperature : 0 //We scale up the figure for a consistent:tm: scale + if(tempOutputdata.len > 100) //Only lets you track over a certain timeframe. + tempOutputdata.Cut(1, 2) + +/obj/machinery/computer/reactor/stats/ui_data(mob/user) + var/list/data = list() + data["powerData"] = powerData + data["psiData"] = psiData + data["tempInputData"] = tempInputData + data["tempOutputdata"] = tempOutputdata + data["coolantInput"] = reactor ? reactor.last_coolant_temperature : 0 + data["coolantOutput"] = reactor ? reactor.last_output_temperature : 0 + data["power"] = reactor ? reactor.power : 0 + data ["psi"] = reactor ? reactor.pressure : 0 + return data + +/obj/machinery/computer/reactor/fuel_rods + name = "Reactor Fuel Management Console" + desc = "A console which can remotely raise fuel rods out of nuclear reactors." + icon_screen = "rbmk_fuel" + +/obj/machinery/computer/reactor/fuel_rods/attack_hand(mob/living/user) + . = ..() + if(!reactor) + return FALSE + if(reactor.power > 20) + to_chat(user, "You cannot remove fuel from [reactor] when it is above 20% power.") + return FALSE + if(!reactor.fuel_rods.len) + to_chat(user, "[reactor] does not have any fuel rods loaded.") + return FALSE + var/atom/movable/fuel_rod = input(usr, "Select a fuel rod to remove", "[src]", null) as null|anything in reactor.fuel_rods + if(!fuel_rod) + return + playsound(src, pick('sound/effects/rbmk/switch.ogg','sound/effects/rbmk/switch2.ogg','sound/effects/rbmk/switch3.ogg'), 100, FALSE) + playsound(reactor, 'sound/effects/ship/freespace2/crane_1.wav', 100, FALSE) + fuel_rod.forceMove(get_turf(reactor)) + reactor.fuel_rods -= fuel_rod + +//Preset pumps for mappers. You can also set the id tags yourself. +/obj/machinery/atmospherics/components/binary/pump/rbmk_input + id = "rbmk_input" + frequency = FREQ_RBMK_CONTROL + +/obj/machinery/atmospherics/components/binary/pump/rbmk_output + id = "rbmk_output" + frequency = FREQ_RBMK_CONTROL + +/obj/machinery/atmospherics/components/binary/pump/rbmk_moderator + id = "rbmk_moderator" + frequency = FREQ_RBMK_CONTROL + +/obj/machinery/computer/reactor/pump + name = "Reactor inlet valve computer" + desc = "A computer which controls valve settings on an advanced gas cooled reactor. Alt click it to remotely set pump pressure." + icon_screen = "rbmk_input" + id = "rbmk_input" + var/datum/radio_frequency/radio_connection + var/on = FALSE + +/obj/machinery/computer/reactor/pump/AltClick(mob/user) + . = ..() + var/newPressure = input(user, "Set new output pressure (kPa)", "Remote pump control", null) as num + if(!newPressure) + return + newPressure = clamp(newPressure, 0, MAX_OUTPUT_PRESSURE) //Number sanitization is not handled in the pumps themselves, only during their ui_act which this doesn't use. + signal(on, newPressure) + +/obj/machinery/computer/reactor/attack_robot(mob/user) + . = ..() + attack_hand(user) + +/obj/machinery/computer/reactor/attack_ai(mob/user) + . = ..() + attack_hand(user) + +/obj/machinery/computer/reactor/pump/attack_hand(mob/living/user) + . = ..() + if(!is_operational()) + return FALSE + playsound(loc, pick('sound/effects/rbmk/switch.ogg','sound/effects/rbmk/switch2.ogg','sound/effects/rbmk/switch3.ogg'), 100, FALSE) + visible_message("[src]'s switch flips [on ? "off" : "on"].") + on = !on + signal(on) + +/obj/machinery/computer/reactor/pump/Initialize(mapload, obj/item/circuitboard/C) + . = ..() + radio_connection = SSradio.add_object(src, FREQ_RBMK_CONTROL,filter=RADIO_ATMOSIA) + +/obj/machinery/computer/reactor/pump/proc/signal(power, set_output_pressure=null) + var/datum/signal/signal + if(!set_output_pressure) //Yes this is stupid, but technically if you pass through "set_output_pressure" onto the signal, it'll always try and set its output pressure and yeahhh... + signal = new(list( + "tag" = id, + "frequency" = FREQ_RBMK_CONTROL, + "timestamp" = world.time, + "power" = power, + "sigtype" = "command" + )) + else + signal = new(list( + "tag" = id, + "frequency" = FREQ_RBMK_CONTROL, + "timestamp" = world.time, + "power" = power, + "set_output_pressure" = set_output_pressure, + "sigtype" = "command" + )) + radio_connection.post_signal(src, signal, filter=RADIO_ATMOSIA) + +//Preset subtypes for mappers +/obj/machinery/computer/reactor/pump/rbmk_input + name = "Reactor inlet valve computer" + icon_screen = "rbmk_input" + id = "rbmk_input" + +/obj/machinery/computer/reactor/pump/rbmk_output + name = "Reactor output valve computer" + icon_screen = "rbmk_output" + id = "rbmk_output" + +/obj/machinery/computer/reactor/pump/rbmk_moderator + name = "Reactor moderator valve computer" + icon_screen = "rbmk_moderator" + id = "rbmk_moderator" + +//Monitoring program. +/datum/computer_file/program/nuclear_monitor + filename = "rbmkmonitor" + filedesc = "Nuclear Reactor Monitoring" + ui_header = "smmon_0.gif" + program_icon_state = "smmon_0" + extended_desc = "This program connects to specially calibrated sensors to provide information on the status of nuclear reactors." + requires_ntnet = TRUE + transfer_access = ACCESS_CONSTRUCTION + //network_destination = "rbmk monitoring system" //Apparently we don't use these anymore + size = 2 + tgui_id = "NtosRbmkStats" + //ui_x = 350 + //ui_y = 550 + var/active = TRUE //Easy process throttle + var/next_stat_interval = 0 + var/list/psiData = list() + var/list/powerData = list() + var/list/tempInputData = list() + var/list/tempOutputdata = list() + var/obj/machinery/atmospherics/components/trinary/nuclear_reactor/reactor //Our reactor. + +/datum/computer_file/program/nuclear_monitor/process_tick() + ..() + if(!reactor || !active) + return FALSE + var/stage = 0 + //This is dirty but i'm lazy wahoo! + if(reactor.power > 0) + stage = 1 + if(reactor.power >= 40) + stage = 2 + if(reactor.temperature >= RBMK_TEMPERATURE_OPERATING) + stage = 3 + if(reactor.temperature >= RBMK_TEMPERATURE_CRITICAL) + stage = 4 + if(reactor.temperature >= RBMK_TEMPERATURE_MELTDOWN) + stage = 5 + if(reactor.vessel_integrity <= 100) //Bye bye! GET OUT! + stage = 6 + ui_header = "smmon_[stage].gif" + program_icon_state = "smmon_[stage]" + if(istype(computer)) + computer.update_icon() + if(world.time >= next_stat_interval) + next_stat_interval = world.time + 1 SECONDS //You only get a slow tick. + psiData += (reactor) ? reactor.pressure : 0 + if(psiData.len > 100) //Only lets you track over a certain timeframe. + psiData.Cut(1, 2) + powerData += (reactor) ? reactor.power*10 : 0 //We scale up the figure for a consistent:tm: scale + if(powerData.len > 100) //Only lets you track over a certain timeframe. + powerData.Cut(1, 2) + tempInputData += (reactor) ? reactor.last_coolant_temperature : 0 //We scale up the figure for a consistent:tm: scale + if(tempInputData.len > 100) //Only lets you track over a certain timeframe. + tempInputData.Cut(1, 2) + tempOutputdata += (reactor) ? reactor.last_output_temperature : 0 //We scale up the figure for a consistent:tm: scale + if(tempOutputdata.len > 100) //Only lets you track over a certain timeframe. + tempOutputdata.Cut(1, 2) + +/datum/computer_file/program/nuclear_monitor/run_program(mob/living/user) + . = ..(user) + //No reactor? Go find one then. + if(!reactor) + for(var/obj/machinery/atmospherics/components/trinary/nuclear_reactor/R in GLOB.machines) + if(R.z == usr.z) + reactor = R + break + active = TRUE + +/datum/computer_file/program/nuclear_monitor/kill_program(forced = FALSE) + active = FALSE + ..() + +/datum/computer_file/program/nuclear_monitor/ui_data() + var/list/data = get_header_data() + data["powerData"] = powerData + data["psiData"] = psiData + data["tempInputData"] = tempInputData + data["tempOutputdata"] = tempOutputdata + data["coolantInput"] = reactor ? reactor.last_coolant_temperature : 0 + data["coolantOutput"] = reactor ? reactor.last_output_temperature : 0 + data["power"] = reactor ? reactor.power : 0 + data ["psi"] = reactor ? reactor.pressure : 0 + return data + +/datum/computer_file/program/nuclear_monitor/ui_act(action, params) + if(..()) + return TRUE + + switch(action) + if("swap_reactor") + var/list/choices = list() + for(var/obj/machinery/atmospherics/components/trinary/nuclear_reactor/R in GLOB.machines) + if(R.z != usr.z) + continue + choices += R + reactor = input(usr, "What reactor do you wish to monitor?", "[src]", null) as null|anything in choices + powerData = list() + psiData = list() + tempInputData = list() + tempOutputdata = list() + return TRUE + +/obj/effect/decal/nuclear_waste + name = "Plutonium sludge" + desc = "A writhing pool of heavily irradiated, spent reactor fuel. You probably shouldn't step through this..." + icon = 'icons/obj/machines/reactor_parts.dmi' + icon_state = "nuclearwaste" + alpha = 150 + light_color = LIGHT_COLOR_CYAN + color = "#ff9eff" + +/obj/effect/decal/nuclear_waste/Initialize() + . = ..() + for(var/obj/A in get_turf(src)) + if(istype(A, /obj/structure)) + qdel(src) //It is more processing efficient to do this here rather than when searching for available turfs. + set_light(3) + AddComponent(/datum/component/radioactive, 1000, src, 0) + +/obj/effect/decal/nuclear_waste/epicenter //The one that actually does the irradiating. This is to avoid every bit of sludge PROCESSING + name = "Dense nuclear sludge" + +/obj/effect/landmark/nuclear_waste_spawner //Clean way of spawning nuclear gunk after a reactor core meltdown. + name = "Nuclear waste spawner" + var/range = 5 //5 tile radius to spawn goop + +/obj/effect/landmark/nuclear_waste_spawner/strong + range = 10 + +/obj/effect/landmark/nuclear_waste_spawner/proc/fire() + playsound(loc, 'sound/effects/gib_step.ogg', 100) + new /obj/effect/decal/nuclear_waste/epicenter(get_turf(src)) + for(var/turf/open/floor in orange(range, get_turf(src))) + if(prob(35)) //Scatter the sludge, don't smear it everywhere + new /obj/effect/decal/nuclear_waste (floor) + qdel(src) + +/obj/effect/decal/nuclear_waste/epicenter/Initialize() + . = ..() + +/obj/effect/decal/nuclear_waste/Crossed(atom/movable/AM) + . = ..() + if(isliving(AM)) + var/mob/living/L = AM + playsound(loc, 'sound/effects/gib_step.ogg', HAS_TRAIT(L, TRAIT_LIGHT_STEP) ? 20 : 50, 1) + radiation_pulse(src, 500, 5) //MORE RADS + +/obj/effect/decal/nuclear_waste/attackby(obj/item/tool, mob/user) + if(tool.tool_behaviour == TOOL_SHOVEL) + radiation_pulse(src, 1000, 5) //MORE RADS + to_chat(user, "You start to clear [src]...") + if(tool.use_tool(src, user, 50, volume=100)) + to_chat(user, "You clear [src]. ") + qdel(src) + return + . = ..() + +/datum/weather/nuclear_fallout + name = "nuclear fallout" + desc = "Irradiated dust falls down everywhere." + telegraph_duration = 50 + telegraph_message = "The air suddenly becomes dusty.." + weather_message = "You feel a wave of hot ash fall down on you." + weather_overlay = "light_ash" + telegraph_overlay = "light_snow" + weather_duration_lower = 600 + weather_duration_upper = 1500 + weather_color = "green" + telegraph_sound = null + weather_sound = 'sound/effects/ship/reactor/falloutwind.ogg' + end_duration = 100 + area_type = /area + protected_areas = list(/area/maintenance, /area/ai_monitored/turret_protected/ai_upload, /area/ai_monitored/turret_protected/ai_upload_foyer, + /area/ai_monitored/turret_protected/ai, /area/commons/storage/emergency/starboard, /area/commons/storage/emergency/port, /area/shuttle) + target_trait = ZTRAIT_STATION + end_message = "The ash stops falling." + immunity_type = "rad" + +/datum/weather/nuclear_fallout/weather_act(mob/living/L) + L.rad_act(100) + +/datum/weather/nuclear_fallout/telegraph() + ..() + status_alarm(TRUE) + +/datum/weather/nuclear_fallout/proc/status_alarm(active) //Makes the status displays show the radiation warning for those who missed the announcement. + var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS) + if(!frequency) + return + + var/datum/signal/signal = new + if (active) + signal.data["command"] = "alert" + signal.data["picture_state"] = "radiation" + else + signal.data["command"] = "shuttle" + + var/atom/movable/virtualspeaker/virt = new(null) + frequency.post_signal(virt, signal) + +/datum/weather/nuclear_fallout/end() + if(..()) + return + status_alarm(FALSE) + +/obj/item/sealant + name = "Flexi seal" + desc = "A neat spray can that can repair torn inflatable segments, and more!" + icon = 'icons/obj/inflatable.dmi' + icon_state = "sealant" + w_class = WEIGHT_CLASS_TINY + +/area/engineering/main/reactor_core + name = "Nuclear Reactor Core" + +/area/engineering/main/reactor_control + name = "Reactor Control Room" + + +//Procs shamelessly taken from machinery/power +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/connect_to_network() + var/turf/T = src.loc + if(!T || !istype(T)) + return FALSE + + var/obj/structure/cable/C = T.get_cable_node() //check if we have a node cable on the machine turf, the first found is picked + if(!C || !C.powernet) + return FALSE + + C.powernet.add_machine(src) + return TRUE + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/disconnect_from_network() + if(!powernet) + return FALSE + powernet.remove_machine(src) + return TRUE + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/add_avail(amount) + if(powernet) + powernet.newavail += amount + return TRUE + else + return FALSE diff --git a/code/modules/power/reactor/reactor_cargo.dm b/code/modules/power/reactor/reactor_cargo.dm new file mode 100644 index 0000000000..5548e88f8d --- /dev/null +++ b/code/modules/power/reactor/reactor_cargo.dm @@ -0,0 +1,37 @@ +// modular shitcode but it works:tm: + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/multitool_act(mob/living/user, obj/item/multitool/I) + if(istype(I)) + to_chat(user, "You add \the [src]'s ID into the multitool's buffer.") + I.buffer = src.id + return TRUE +/obj/machinery/computer/reactor/multitool_act(mob/living/user, obj/item/multitool/I) + if(istype(I)) + to_chat(user, "You add the reactor's ID to \the [src]>") + src.id = I.buffer + link_to_reactor() + return TRUE + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/cargo // easier on the brain + +/obj/machinery/atmospherics/components/trinary/nuclear_reactor/cargo/New() + . = ..() + id = rand(1, 9999999) // cmon, what are the chances? The chances are... Very low friend... But maybe we can make this a bit better. + +// Cargo variants can be wrenched down and don't start linked to the default RMBK reactor + +/obj/machinery/computer/reactor/control_rods/cargo + anchored = FALSE + id = null + +/obj/machinery/computer/reactor/stats/cargo + anchored = FALSE + id = null + +/obj/machinery/computer/reactor/fuel_rods/cargo + anchored = FALSE + id = null + +/obj/item/paper/fluff/rbmkcargo + name = "Nuclear Reactor Instructions" + info = "Make sure a 5x5 area is completely clear of pipes, cables and machinery when using the beacon. Those will be provided automatically with the beacon's bluespace decompression. Use a multitool on the reactor then on the computers provided to link them together. Also make sure the reactor has a proper pipeline filled with cooling gas before inserting fuel rods. Good luck!" diff --git a/code/modules/power/rtg.dm b/code/modules/power/rtg.dm index c19927e84c..618dbb2120 100644 --- a/code/modules/power/rtg.dm +++ b/code/modules/power/rtg.dm @@ -19,7 +19,7 @@ var/irradiate = TRUE // RTGs irradiate surroundings, but only when panel is open. -/obj/machinery/power/rtg/Initialize() +/obj/machinery/power/rtg/Initialize(mapload) . = ..() connect_to_network() @@ -56,7 +56,7 @@ /obj/machinery/power/rtg/advanced/fullupgrade //fully ugpraded stock parts desc = "An advanced RTG capable of moderating isotope decay, increasing power output but reducing lifetime. It uses plasma-fueled radiation collectors to increase output even further. This model is fully upgraded with the latest tech available in this quadrant." -/obj/machinery/power/rtg/advanced/fullupgrade/Initialize() +/obj/machinery/power/rtg/advanced/fullupgrade/Initialize(mapload) . = ..() //This looks terrifying. And apparently instancing vars and modifying the amount variable causes runtime errors. Guess we're sticking to copy pasta, thanks, byond. component_parts = list() @@ -115,7 +115,7 @@ /obj/machinery/power/rtg/abductor/blob_act(obj/structure/blob/B) overload() -/obj/machinery/power/rtg/abductor/ex_act() +/obj/machinery/power/rtg/abductor/ex_act(severity, target, origin) if(going_kaboom) qdel(src) else diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index a6b144ebe6..1052752c82 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -33,7 +33,7 @@ /obj/machinery/power/rad_collector/anchored anchored = TRUE -/obj/machinery/power/rad_collector/Initialize() +/obj/machinery/power/rad_collector/Initialize(mapload) . = ..() Radio = new /obj/item/radio(src) Radio.listening = 0 @@ -182,7 +182,7 @@ . = ..() if(active) if(!bitcoinmining) - . += "[src]'s display states that it has stored [DisplayPower(stored_power)], and is processing [DisplayPower((RAD_COLLECTOR_OUTPUT)*((60 SECONDS)/SSmachines.wait))] per minute.
    The plasma within it's tank is being irradiated into tritium.
    " + . += "[src]'s display states that it has stored [DisplayEnergy(stored_power)], and is processing [DisplayPower((RAD_COLLECTOR_OUTPUT)*((1 SECONDS)/SSmachines.wait))].
    The plasma within it's tank is being irradiated into tritium.
    " else . += "[src]'s display states that it's producing a total of [(last_push*RAD_COLLECTOR_MINING_CONVERSION_RATE)*((60 SECONDS)/SSmachines.wait)] research points per minute.
    The tritium and oxygen within it's tank is being combusted into carbon dioxide.
    " else diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm index 2ca9b7513c..7c6b1cc922 100644 --- a/code/modules/power/singularity/containment_field.dm +++ b/code/modules/power/singularity/containment_field.dm @@ -42,7 +42,7 @@ /obj/machinery/field/containment/blob_act(obj/structure/blob/B) return FALSE -/obj/machinery/field/containment/ex_act(severity, target) +/obj/machinery/field/containment/ex_act(severity, target, origin) return FALSE /obj/machinery/field/containment/attack_animal(mob/living/simple_animal/M) @@ -100,10 +100,10 @@ return -/obj/machinery/field/CanPass(atom/movable/mover, turf/target) +/obj/machinery/field/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(hasShocked || isliving(mover) || ismachinery(mover) || isstructure(mover) || ismecha(mover)) return FALSE - return ..() /obj/machinery/field/proc/shock(mob/living/user) var/shock_damage = min(rand(30,40),rand(30,40)) diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 6961ec54bb..8f9a7805c6 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -57,7 +57,7 @@ state = EMITTER_WELDED use_power = FALSE -/obj/machinery/power/emitter/Initialize() +/obj/machinery/power/emitter/Initialize(mapload) . = ..() RefreshParts() wires = new /datum/wires/emitter(src) @@ -454,7 +454,7 @@ resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF var/delay = 0 -/obj/item/turret_control/Initialize() +/obj/item/turret_control/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index af2237a426..567ac00487 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -33,7 +33,8 @@ field_generator power level display use_power = NO_POWER_USE max_integrity = 500 //100% immune to lasers and energy projectiles since it absorbs their energy. - armor = list("melee" = 25, "bullet" = 10, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70) + armor = list(MELEE = 25, BULLET = 10, LASER = 100, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 70) + var/obj/item/radio/radio var/const/num_power_levels = 6 // Total number of power level icon has var/power_level = 0 var/active = FG_OFFLINE @@ -54,10 +55,13 @@ field_generator power level display . += "+p[power_level]" -/obj/machinery/field/generator/Initialize() +/obj/machinery/field/generator/Initialize(mapload) . = ..() fields = list() connected_gens = list() + radio = new(src) + radio.listening = 0 + radio.recalculateChannels() /obj/machinery/field/generator/ComponentInitialize() . = ..() @@ -158,7 +162,7 @@ field_generator power level display ..() /obj/machinery/field/generator/bullet_act(obj/item/projectile/Proj) - if(Proj.flag != "bullet") + if(Proj.flag != BULLET) power = min(power + Proj.damage, field_generator_max_power) check_power_level() ..() @@ -166,6 +170,7 @@ field_generator power level display /obj/machinery/field/generator/Destroy() cleanup() + QDEL_NULL(radio) return ..() @@ -333,6 +338,7 @@ field_generator power level display if((world.time - O.last_warning) > 50) //to stop message-spam temp = 0 var/turf/T = get_turf(src) + radio.talk_into(src, "A containment field has failed in [get_area_name(src, TRUE)] while a singularity exists.", null, language = get_selected_language()) message_admins("A singulo exists and a containment field has failed at [ADMIN_VERBOSEJMP(T)].") investigate_log("has failed whilst a singulo exists at [AREACOORD(T)].", INVESTIGATE_SINGULO) O.last_warning = world.time diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index 0ebbce53cf..0f58805976 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -27,7 +27,7 @@ grav_pull = 10 consume_range = 12 //How many tiles out do we eat -/obj/singularity/narsie/large/Initialize() +/obj/singularity/narsie/large/Initialize(mapload) . = ..() send_to_playing_players("NAR'SIE HAS RISEN") sound_to_playing_players('sound/creatures/narsie_rises.ogg') @@ -44,7 +44,7 @@ var/souls = 0 var/resolved = FALSE -/obj/singularity/narsie/large/cult/Initialize() +/obj/singularity/narsie/large/cult/Initialize(mapload) . = ..() GLOB.cult_narsie = src var/list/all_cults = list() @@ -62,7 +62,7 @@ for(var/datum/mind/cult_mind in SSticker.mode.cult) if(isliving(cult_mind.current)) var/mob/living/L = cult_mind.current - L.narsie_act() + INVOKE_ASYNC(L, /atom.proc/narsie_act) for(var/mob/living/player in GLOB.player_list) if(player.stat != DEAD && player.loc && is_station_level(player.loc.z) && !iscultist(player) && !isanimal(player)) souls_needed[player] = TRUE @@ -143,7 +143,7 @@ A.narsie_act() -/obj/singularity/narsie/ex_act() //No throwing bombs at her either. +/obj/singularity/narsie/ex_act(severity, target, origin) //No throwing bombs at her either. return diff --git a/code/modules/power/singularity/particle_accelerator/particle.dm b/code/modules/power/singularity/particle_accelerator/particle.dm index 7ecde364ae..58c338e44a 100644 --- a/code/modules/power/singularity/particle_accelerator/particle.dm +++ b/code/modules/power/singularity/particle_accelerator/particle.dm @@ -49,7 +49,7 @@ toxmob(A) -/obj/effect/accelerated_particle/ex_act(severity, target) +/obj/effect/accelerated_particle/ex_act(severity, target, origin) qdel(src) /obj/effect/accelerated_particle/singularity_pull() diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm index 60c97eda76..6938352d16 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm @@ -27,7 +27,7 @@ anchored = FALSE density = TRUE max_integrity = 500 - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 80) + armor = list(MELEE = 30, BULLET = 20, LASER = 20, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 90, ACID = 80) var/obj/machinery/particle_accelerator/control_box/master = null var/construction_state = PA_CONSTRUCTION_UNSECURED diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm index 96c8d9a263..3a592a4f98 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_control.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm @@ -19,7 +19,7 @@ var/strength = 0 var/powered = FALSE -/obj/machinery/particle_accelerator/control_box/Initialize() +/obj/machinery/particle_accelerator/control_box/Initialize(mapload) . = ..() wires = new /datum/wires/particle_accelerator/control_box(src) connected_parts = list() diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index ee4b9ce6ba..29fd68d034 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -97,7 +97,7 @@ return return ..() -/obj/singularity/ex_act(severity, target) +/obj/singularity/ex_act(severity, target, origin) switch(severity) if(1) if(current_size <= STAGE_TWO) @@ -347,10 +347,10 @@ var/dir2 = 0 var/dir3 = 0 switch(direction) - if(NORTH||SOUTH) + if(NORTH, SOUTH) dir2 = 4 dir3 = 8 - if(EAST||WEST) + if(EAST, WEST) dir2 = 1 dir3 = 2 var/turf/T2 = T @@ -415,17 +415,13 @@ /obj/singularity/proc/mezzer() for(var/mob/living/carbon/M in oviewers(8, src)) - if(isbrain(M)) //Ignore brains - continue - - if(M.stat == CONSCIOUS) - if (ishuman(M)) - var/mob/living/carbon/human/H = M - if(istype(H.glasses, /obj/item/clothing/glasses/meson)) - var/obj/item/clothing/glasses/meson/MS = H.glasses - if(MS.vision_flags == SEE_TURFS) - to_chat(H, "You look directly into the [src.name], good thing you had your protective eyewear on!") - return + if(M.stat == CONSCIOUS && ishuman(M)) + var/mob/living/carbon/human/H = M + if(istype(H.glasses, /obj/item/clothing/glasses/meson)) + var/obj/item/clothing/glasses/meson/MS = H.glasses + if(MS.vision_flags == SEE_TURFS) + to_chat(H, "You look directly into the [src.name], good thing you had your protective eyewear on!") + return M.apply_effect(60, EFFECT_STUN) M.visible_message("[M] stares blankly at the [src.name]!", \ diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 32e6186133..fff91df1b9 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -44,7 +44,7 @@ if(!terminal) . += "This SMES has no power terminal!" -/obj/machinery/power/smes/Initialize() +/obj/machinery/power/smes/Initialize(mapload) . = ..() dir_loop: for(var/d in GLOB.cardinals) diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 907c4e7d65..0f0f853036 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -5,6 +5,7 @@ desc = "A solar panel. Generates electricity when in contact with sunlight." icon = 'goon/icons/obj/power.dmi' icon_state = "sp_base" + minimap_override_color = "#02026a" density = TRUE use_power = NO_POWER_USE idle_power_usage = 0 @@ -241,8 +242,10 @@ to_chat(user, "You need to secure the assembly before you can add glass.") return var/obj/item/stack/sheet/S = W - if(S.use(2)) - glass_type = W.type + S = S.split_stack(amount=2) + if(S) + glass_type = S + S.moveToNullspace() playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE) user.visible_message("[user] places the glass on the solar assembly.", "You place the glass on the solar assembly.") if(tracker) @@ -297,7 +300,7 @@ var/obj/machinery/power/tracker/connected_tracker = null var/list/connected_panels = list() -/obj/machinery/power/solar_control/Initialize() +/obj/machinery/power/solar_control/Initialize(mapload) . = ..() azimuth_rate = SSsun.base_rotation RegisterSignal(SSsun, COMSIG_SUN_MOVED, .proc/timed_track) diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index b460cfea51..a8f33ab07c 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -39,9 +39,10 @@ #define DAMAGE_INCREASE_MULTIPLIER 0.25 -#define THERMAL_RELEASE_MODIFIER 5 //Higher == less heat released during reaction, not to be confused with the above values +#define THERMAL_RELEASE_MODIFIER 350 //Higher == more heat released during reaction, not to be confused with the above values +#define THERMAL_RELEASE_CAP_MODIFIER 250 //Higher == lower cap on how much heat can be released per tick--currently 1.3x old value #define PLASMA_RELEASE_MODIFIER 750 //Higher == less plasma released by reaction -#define OXYGEN_RELEASE_MODIFIER 325 //Higher == less oxygen released at high temperature/power +#define OXYGEN_RELEASE_MODIFIER 550 //Higher == less oxygen released at high temperature/power #define REACTION_POWER_MODIFIER 0.55 //Higher == more overall power @@ -191,10 +192,10 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) ///Disables the sm's proccessing totally. var/processes = TRUE -/obj/machinery/power/supermatter_crystal/Initialize() +/obj/machinery/power/supermatter_crystal/Initialize(mapload) . = ..() uid = gl_uid++ - SSair.atmos_air_machinery += src + SSair.atmos_machinery += src countdown = new(src) countdown.start() GLOB.poi_list |= src @@ -209,16 +210,17 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) AddElement(/datum/element/bsa_blocker) RegisterSignal(src, COMSIG_ATOM_BSA_BEAM, .proc/call_explode) - soundloop = new(list(src), TRUE) + soundloop = new(src, TRUE) /obj/machinery/power/supermatter_crystal/Destroy() investigate_log("has been destroyed.", INVESTIGATE_SUPERMATTER) - SSair.atmos_air_machinery -= src + SSair.atmos_machinery -= src QDEL_NULL(radio) GLOB.poi_list -= src QDEL_NULL(countdown) if(is_main_engine && GLOB.main_supermatter_engine == src) GLOB.main_supermatter_engine = null + QDEL_NULL(soundloop) return ..() /obj/machinery/power/supermatter_crystal/examine(mob/user) @@ -228,6 +230,57 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) if (!istype(C.glasses, /obj/item/clothing/glasses/meson) && (get_dist(user, src) < HALLUCINATION_RANGE(power))) . += "You get headaches just from looking at it." +// SupermatterMonitor UI for ghosts only. Inherited attack_ghost will call this. +/obj/machinery/power/supermatter_crystal/ui_interact(mob/user, datum/tgui/ui) + if(!isobserver(user)) + return FALSE + . = ..() + ui = SStgui.try_update_ui(user, src, ui) + if (!ui) + ui = new(user, src, "SupermatterMonitor") + ui.open() + +/obj/machinery/power/supermatter_crystal/ui_data(mob/user) + var/list/data = list() + + var/turf/local_turf = get_turf(src) + + var/datum/gas_mixture/air = local_turf.return_air() + + // singlecrystal set to true eliminates the back sign on the gases breakdown. + data["singlecrystal"] = TRUE + data["active"] = TRUE + data["SM_integrity"] = get_integrity() + data["SM_power"] = power + data["SM_ambienttemp"] = air.return_temperature() + data["SM_ambientpressure"] = air.return_pressure() + data["SM_bad_moles_amount"] = MOLE_PENALTY_THRESHOLD / gasefficency + data["SM_moles"] = 0 + data["SM_uid"] = uid + var/area/active_supermatter_area = get_area(src) + data["SM_area_name"] = active_supermatter_area.name + + var/list/gasdata = list() + + if(air.total_moles()) + data["SM_moles"] = air.total_moles() + for(var/id in air.get_gases()) + var/gas_level = air.get_moles(id)/air.total_moles() + if(gas_level > 0) + gasdata.Add(list(list( + "name"= "[GLOB.gas_data.names[id]]", + "amount" = round(gas_level*100, 0.01)))) + + else + for(var/id in air.get_gases()) + gasdata.Add(list(list( + "name"= "[GLOB.gas_data.names[id]]", + "amount" = 0))) + + data["gases"] = gasdata + + return data + /obj/machinery/power/supermatter_crystal/proc/get_status() var/turf/T = get_turf(src) if(!T) @@ -416,15 +469,20 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) //((((some value between 0.5 and 1 * temp - ((273.15 + 40) * some values between 1 and 10)) * some number between 0.25 and knock your socks off / 150) * 0.25 //Heat and mols account for each other, a lot of hot mols are more damaging then a few //Mols start to have a positive effect on damage after 350 + var/spaced = 0 + for(var/turf/open/space/_space_turf in range(2,src)) + spaced++ damage = max(damage + (max(clamp(removed.total_moles() / 200, 0.5, 1) * removed.return_temperature() - ((T0C + HEAT_PENALTY_THRESHOLD)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ) * DAMAGE_INCREASE_MULTIPLIER, 0) //Power only starts affecting damage when it is above 5000 damage = max(damage + (max(power - POWER_PENALTY_THRESHOLD, 0)/500) * DAMAGE_INCREASE_MULTIPLIER, 0) //Molar count only starts affecting damage when it is above 1800 damage = max(damage + (max(combined_gas - MOLE_PENALTY_THRESHOLD, 0)/80) * DAMAGE_INCREASE_MULTIPLIER, 0) + damage = max(damage + spaced * 0.1 * DAMAGE_INCREASE_MULTIPLIER, 0) + //There might be a way to integrate healing and hurting via heat //healing damage - if(combined_gas < MOLE_PENALTY_THRESHOLD) + if(combined_gas < MOLE_PENALTY_THRESHOLD && !spaced) //Only has a net positive effect when the temp is below 313.15, heals up to 2 damage. Psycologists increase this temp min by up to 45 damage = max(damage + (min(removed.return_temperature() - (T0C + HEAT_PENALTY_THRESHOLD), 0) / 150), 0) @@ -500,7 +558,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) powerloss_dynamic_scaling = clamp(powerloss_dynamic_scaling + clamp(powerloss_inhibition_gas - powerloss_dynamic_scaling, -0.02, 0.02), 0, 1) else powerloss_dynamic_scaling = clamp(powerloss_dynamic_scaling - 0.05, 0, 1) - //Ranges from 0 to 1(1-(value between 0 and 1 * ranges from 1 to 1.5(mol / 500))) + //Ranges from 0 to 1 (1-(value between 0 and 1 * ranges from 1 to 1.5(mol / 500))) + //0 means full inhibition, 1 means no inhibition //We take the mol count, and scale it to be our inhibitor powerloss_inhibitor = clamp(1-(powerloss_dynamic_scaling * clamp(combined_gas/POWERLOSS_INHIBITION_MOLE_BOOST_THRESHOLD, 1, 1.5)), 0, 1) @@ -523,9 +582,11 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) temp_factor = 30 icon_state = base_icon_state + var/effective_temperature = min(removed.return_temperature(), 2500 * dynamic_heat_modifier) + //if there is more pluox and n2 then anything else, we receive no power increase from heat if(power_changes) - power = max((removed.return_temperature() * temp_factor / T0C) * gasmix_power_ratio + power, 0) + power = max((effective_temperature * temp_factor / T0C) * gasmix_power_ratio + power, 0) if(prob(50)) //(1 + (tritRad + pluoxDampen * bzDampen * o2Rad * plasmaRad / (10 - bzrads))) * freonbonus @@ -536,15 +597,17 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) //Power * 0.55 * a value between 1 and 0.8 var/device_energy = power * REACTION_POWER_MODIFIER - removed.set_temperature(removed.return_temperature() + ((device_energy * dynamic_heat_modifier) / THERMAL_RELEASE_MODIFIER)) - //We don't want our output to be too hot - removed.set_temperature(max(0, min(removed.return_temperature(), 2500 * dynamic_heat_modifier))) - + var/max_temp_increase = effective_temperature + ((device_energy * dynamic_heat_modifier) / THERMAL_RELEASE_CAP_MODIFIER) //Calculate how much gas to release //Varies based on power and gas content - removed.adjust_moles(GAS_PLASMA, max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0)) + removed.adjust_moles(GAS_PLASMA, clamp((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0, 50)) //Varies based on power, gas content, and heat - removed.adjust_moles(GAS_O2, max(((device_energy + removed.return_temperature() * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0)) + removed.adjust_moles(GAS_O2, clamp((device_energy * dynamic_heat_modifier + effective_temperature - T0C) / OXYGEN_RELEASE_MODIFIER, 0, 100)) + + if(removed.return_temperature() < max_temp_increase) + removed.adjust_heat(device_energy * dynamic_heat_modifier * THERMAL_RELEASE_MODIFIER) + removed.set_temperature(min(removed.return_temperature(), max_temp_increase)) + if(produces_gas) env.merge(removed) @@ -593,13 +656,13 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) zap_icon = SLIGHTLY_CHARGED_ZAP_ICON_STATE //Uncaps the zap damage, it's maxed by the input power //Objects take damage now - flags |= (ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE) + flags |= (ZAP_MOB_DAMAGE) zap_count = 3 if(CRITICAL_POWER_PENALTY_THRESHOLD to INFINITY) zap_icon = OVER_9000_ZAP_ICON_STATE //It'll stun more now, and damage will hit harder, gloves are no garentee. //Machines go boom - flags |= (ZAP_MOB_STUN | ZAP_MACHINE_EXPLOSIVE | ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE) + flags |= (ZAP_MOB_STUN | ZAP_MOB_DAMAGE) zap_count = 4 //Now we deal with damage shit if (damage > damage_penalty_point && prob(20)) @@ -622,6 +685,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) //Tells the engi team to get their butt in gear if(damage > warning_point) // while the core is still damaged and it's still worth noting its status + if(damage_archived < warning_point) //If damage_archive is under the warning point, this is the very first cycle that we've reached said point. + SEND_SIGNAL(src, COMSIG_SUPERMATTER_DELAM_START_ALARM) if((REALTIMEOFDAY - lastwarning) / 10 >= WARNING_DELAY) alarm() @@ -629,6 +694,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) if(damage > emergency_point) // it's bad, LETS YELL radio.talk_into(src, "[emergency_alert] Integrity: [get_integrity()]%", common_channel, list(SPAN_YELL)) + SEND_SIGNAL(src, COMSIG_SUPERMATTER_DELAM_ALARM) lastwarning = REALTIMEOFDAY if(!has_reached_emergency) investigate_log("has reached the emergency point for the first time.", INVESTIGATE_SUPERMATTER) @@ -636,6 +702,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) has_reached_emergency = TRUE else if(damage >= damage_archived) // The damage is still going up radio.talk_into(src, "[warning_alert] Integrity: [get_integrity()]%", engineering_channel) + SEND_SIGNAL(src, COMSIG_SUPERMATTER_DELAM_ALARM) lastwarning = REALTIMEOFDAY - (WARNING_DELAY * 5) else // Phew, we're safe @@ -661,7 +728,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) return FALSE if(!istype(Proj.firer, /obj/machinery/power/emitter) && power_changes) investigate_log("has been hit by [Proj] fired by [key_name(Proj.firer)]", INVESTIGATE_SUPERMATTER) - if(Proj.flag != "bullet") + if(Proj.flag != BULLET) if(power_changes) //This needs to be here I swear power += Proj.damage * bullet_energy if(!has_been_powered) @@ -885,10 +952,10 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) playsound(T, 'sound/effects/supermatter.ogg', 50, 1) T.visible_message("[T] smacks into [src] and rapidly flashes to ash.",\ "You hear a loud crack as you are washed with a wave of heat.") - CALCULATE_ADJACENT_TURFS(T) + T.ImmediateCalculateAdjacentTurfs() //Do not blow up our internal radio -/obj/machinery/power/supermatter_crystal/contents_explosion(severity, target) +/obj/machinery/power/supermatter_crystal/contents_explosion(severity, target, origin) return /obj/machinery/power/supermatter_crystal/engine @@ -1052,9 +1119,6 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) if(zapdir) . = zapdir - //Going boom should be rareish - if(prob(80)) - zap_flags &= ~ZAP_MACHINE_EXPLOSIVE if(target_type == COIL) //In the best situation we can expect this to grow up to 2120kw before a delam/IT'S GONE TOO FAR FRED SHUT IT DOWN //The formula for power gen is zap_str * zap_mod / 2 * capacitor rating, between 1 and 4 diff --git a/code/modules/power/terminal.dm b/code/modules/power/terminal.dm index 3fa815bf99..fc6ff29856 100644 --- a/code/modules/power/terminal.dm +++ b/code/modules/power/terminal.dm @@ -12,7 +12,7 @@ var/obj/machinery/power/master = null -/obj/machinery/power/terminal/Initialize() +/obj/machinery/power/terminal/Initialize(mapload) . = ..() var/turf/T = get_turf(src) if(level == 1) diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm index 13f2aab811..c32bbc0c86 100644 --- a/code/modules/power/tesla/coil.dm +++ b/code/modules/power/tesla/coil.dm @@ -23,7 +23,7 @@ /obj/machinery/power/tesla_coil/power circuit = /obj/item/circuitboard/machine/tesla_coil/power -/obj/machinery/power/tesla_coil/Initialize() +/obj/machinery/power/tesla_coil/Initialize(mapload) . = ..() wires = new /datum/wires/tesla_coil(src) linked_techweb = SSresearch.science_tech @@ -162,7 +162,7 @@ buckle_lying = FALSE buckle_requires_restraints = TRUE -/obj/machinery/power/grounding_rod/Initialize() +/obj/machinery/power/grounding_rod/Initialize(mapload) GLOB.grounding_rods |= src return ..() diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index fc51915b73..2c8583b447 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -39,7 +39,7 @@ if(!is_miniball) set_light(10, 7, "#EEEEFF") -/obj/singularity/energy_ball/ex_act(severity, target) +/obj/singularity/energy_ball/ex_act(severity, target, origin) return /obj/singularity/energy_ball/consume(severity, target) @@ -358,8 +358,16 @@ var/obj/singularity/energy_ball/tesla = source if(istype(tesla)) if(istype(closest_atom,/obj/machinery/power/grounding_rod) && tesla.energy>13 && !tesla.contained) - qdel(closest_atom) // each rod deletes two miniballs, - tesla.energy = round(tesla.energy/1.5625) // if there are no miniballs the rod stays and continues to pull the ball in + + // getting the grounding rod's capacitor rating for quick maths + var/obj/machinery/power/grounding_rod/rod = closest_atom + // assuming the rod is fully constructed the second part will always be a capacitor + var/obj/item/stock_parts/capacitor/capacitor = rod.component_parts[2] + + tesla.energy = round(tesla.energy/(1 + 0.28125 * capacitor.rating)) + qdel(closest_atom) // each rod removes tesla energy depending on the power of the capacitor, + // if there are no miniballs the rod stays and continues to pull the ball in + if(prob(20))//I know I know tesla_zap(closest_atom, next_range, power * 0.5, zap_flags, shocked_targets) tesla_zap(closest_atom, next_range, power * 0.5, zap_flags, shocked_targets) diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm index dda7f27eee..c01e3f3dcc 100644 --- a/code/modules/power/turbine.dm +++ b/code/modules/power/turbine.dm @@ -70,7 +70,7 @@ // the inlet stage of the gas turbine electricity generator -/obj/machinery/power/compressor/Initialize() +/obj/machinery/power/compressor/Initialize(mapload) . = ..() // The inlet of the compressor is the direction it faces gas_contained = new @@ -162,7 +162,7 @@ #define TURBGENQ 100000 #define TURBGENG 0.5 -/obj/machinery/power/turbine/Initialize() +/obj/machinery/power/turbine/Initialize(mapload) . = ..() // The outlet is pointed at the direction of the turbine component outturf = get_step(src, dir) @@ -288,7 +288,7 @@ var/obj/machinery/power/compressor/compressor var/id = 0 -/obj/machinery/computer/turbine_computer/Initialize() +/obj/machinery/computer/turbine_computer/Initialize(mapload) . = ..() return INITIALIZE_HINT_LATELOAD diff --git a/code/modules/projectiles/ammunition/_ammunition.dm b/code/modules/projectiles/ammunition/_ammunition.dm index 6a73d9a366..4794aa6c10 100644 --- a/code/modules/projectiles/ammunition/_ammunition.dm +++ b/code/modules/projectiles/ammunition/_ammunition.dm @@ -26,7 +26,7 @@ name = "spent bullet casing" BB = null -/obj/item/ammo_casing/Initialize() +/obj/item/ammo_casing/Initialize(mapload) . = ..() if(projectile_type) BB = new projectile_type(src) diff --git a/code/modules/projectiles/ammunition/ballistic/lmg.dm b/code/modules/projectiles/ammunition/ballistic/lmg.dm index bf8b4007bf..1c39a73f1f 100644 --- a/code/modules/projectiles/ammunition/ballistic/lmg.dm +++ b/code/modules/projectiles/ammunition/ballistic/lmg.dm @@ -1,36 +1,28 @@ -// 1.95x129mm (SAW) +// 7.12x82mm (SAW) -/obj/item/ammo_casing/mm195x129 - name = "1.95x129mm bullet casing" - desc = "A 1.95x129mm bullet casing." +/obj/item/ammo_casing/mm712x82 + name = "7.12x82mm bullet casing" + desc = "A 7.12x82mm bullet casing." icon_state = "762-casing" - caliber = "mm195129" - projectile_type = /obj/item/projectile/bullet/mm195x129 + caliber = "mm71282" + projectile_type = /obj/item/projectile/bullet/mm712x82 -/obj/item/ammo_casing/mm195x129/ap - name = "1.95x129mm armor-piercing bullet casing" - desc = "A 1.95x129mm bullet casing designed with a hardened-tipped core to help penetrate armored targets." - projectile_type = /obj/item/projectile/bullet/mm195x129_ap +/obj/item/ammo_casing/mm712x82/ap + name = "7.12x82mm armor-piercing bullet casing" + desc = "A 7.12x82mm bullet casing designed with a hardened-tipped core to help penetrate armored targets." + projectile_type = /obj/item/projectile/bullet/mm712x82_ap -/obj/item/ammo_casing/mm195x129/hollow - name = "1.95x129mm hollow-point bullet casing" - desc = "A 1.95x129mm bullet casing designed to cause more damage to unarmored targets." - projectile_type = /obj/item/projectile/bullet/mm195x129_hp +/obj/item/ammo_casing/mm712x82/hollow + name = "7.12x82mm hollow-point bullet casing" + desc = "A 7.12x82mm bullet casing designed to cause more damage to unarmored targets." + projectile_type = /obj/item/projectile/bullet/mm712x82_hp -/obj/item/ammo_casing/mm195x129/incen - name = "1.95x129mm incendiary bullet casing" - desc = "A 1.95x129mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames." - projectile_type = /obj/item/projectile/bullet/incendiary/mm195x129 +/obj/item/ammo_casing/mm712x82/incen + name = "7.12x82mm incendiary bullet casing" + desc = "A 7.12x82mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames." + projectile_type = /obj/item/projectile/bullet/incendiary/mm712x82 /obj/item/ammo_casing/mm712x82/match name = "7.12x82mm match bullet casing" desc = "A 7.12x82mm bullet casing manufactured to unfailingly high standards, you could pull off some cool trickshots with this." - projectile_type = /obj/item/projectile/bullet/mm712x82_match - -/obj/item/projectile/bullet/mm712x82_match - name = "7.12x82mm match bullet" - damage = 40 - ricochets_max = 2 - ricochet_chance = 60 - ricochet_auto_aim_range = 4 - ricochet_incidence_leeway = 35 + projectile_type = /obj/item/projectile/bullet/mm712x82/match diff --git a/code/modules/projectiles/ammunition/ballistic/revolver.dm b/code/modules/projectiles/ammunition/ballistic/revolver.dm index 8f4d8eac67..a9bfe21102 100644 --- a/code/modules/projectiles/ammunition/ballistic/revolver.dm +++ b/code/modules/projectiles/ammunition/ballistic/revolver.dm @@ -39,7 +39,7 @@ /obj/item/ammo_casing/c38/lethal name = ".38 bullet casing" - desc = "A .38 bullet casing" + desc = "A .38 bullet casing." projectile_type = /obj/item/projectile/bullet/c38 /obj/item/ammo_casing/c38/trac diff --git a/code/modules/projectiles/ammunition/ballistic/shotgun.dm b/code/modules/projectiles/ammunition/ballistic/shotgun.dm index 2a41b41d1d..441d112e32 100644 --- a/code/modules/projectiles/ammunition/ballistic/shotgun.dm +++ b/code/modules/projectiles/ammunition/ballistic/shotgun.dm @@ -124,7 +124,7 @@ projectile_type = /obj/item/projectile/bullet/dart var/reagent_amount = 30 -/obj/item/ammo_casing/shotgun/dart/Initialize() +/obj/item/ammo_casing/shotgun/dart/Initialize(mapload) . = ..() create_reagents(reagent_amount, OPENCONTAINER) @@ -137,16 +137,16 @@ icon_state = "cnrshell" reagent_amount = 10 -/obj/item/ammo_casing/shotgun/dart/noreact/Initialize() +/obj/item/ammo_casing/shotgun/dart/noreact/Initialize(mapload) . = ..() - ENABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) + reagents.reagents_holder_flags |= NO_REACT /obj/item/ammo_casing/shotgun/dart/bioterror desc = "A shotgun dart filled with an obscene amount of lethal reagents. God help whoever is shot with this." projectile_type = /obj/item/projectile/bullet/dart/piercing reagent_amount = 50 -/obj/item/ammo_casing/shotgun/dart/bioterror/Initialize() +/obj/item/ammo_casing/shotgun/dart/bioterror/Initialize(mapload) . = ..() reagents.add_reagent(/datum/reagent/toxin/amanitin, 12) //for a nasty surprise after you get shot and somehow escape and don't think to quickly purge, and even shock those who are loaded up on purging agents reagents.add_reagent(/datum/reagent/toxin/chloralhydrate, 6) diff --git a/code/modules/projectiles/ammunition/caseless/misc.dm b/code/modules/projectiles/ammunition/caseless/misc.dm index 8b783ff6aa..12be41a551 100644 --- a/code/modules/projectiles/ammunition/caseless/misc.dm +++ b/code/modules/projectiles/ammunition/caseless/misc.dm @@ -10,7 +10,7 @@ /obj/item/ammo_casing/caseless/laser name = "laser casing" desc = "You shouldn't be seeing this." - caliber = "laser" + caliber = LASER icon_state = "s-casing-live" projectile_type = /obj/item/projectile/beam fire_sound = 'sound/weapons/laser.ogg' diff --git a/code/modules/projectiles/ammunition/energy/_energy.dm b/code/modules/projectiles/ammunition/energy/_energy.dm index 10de173ecc..02fb510a2e 100644 --- a/code/modules/projectiles/ammunition/energy/_energy.dm +++ b/code/modules/projectiles/ammunition/energy/_energy.dm @@ -1,7 +1,7 @@ /obj/item/ammo_casing/energy name = "energy weapon lens" desc = "The part of the gun that makes the laser go pew." - caliber = "energy" + caliber = ENERGY projectile_type = /obj/item/projectile/energy var/e_cost = 100 //The amount of energy a cell needs to expend to create this shot. var/select_name = "energy" diff --git a/code/modules/projectiles/ammunition/special/syringe.dm b/code/modules/projectiles/ammunition/special/syringe.dm index caf5da3562..4eb7dc5475 100644 --- a/code/modules/projectiles/ammunition/special/syringe.dm +++ b/code/modules/projectiles/ammunition/special/syringe.dm @@ -24,9 +24,10 @@ /obj/item/ammo_casing/chemgun name = "dart synthesiser" - desc = "A high-power spring, linked to an energy-based dart synthesiser." + desc = "A high-power spring, linked to an energy-based piercing dart synthesiser." projectile_type = /obj/item/projectile/bullet/dart/piercing firing_effect_type = null + var/dartvolume = 10 /obj/item/ammo_casing/chemgun/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") if(!BB) @@ -35,11 +36,23 @@ var/obj/item/gun/chem/CG = loc if(CG.syringes_left <= 0) return - CG.reagents.trans_to(BB, 10) + if (!CG.vial) + CG.syringes_left-- + return + CG.vial.reagents.trans_to(BB, dartvolume) BB.name = "chemical dart" CG.syringes_left-- ..() +//Smart dart version of reagent launcher. +/obj/item/ammo_casing/chemgun/smart + name = "smartdart synthesiser" + desc = "A high-power spring, linked to an energy-based smartdart synthesiser." + projectile_type = /obj/item/projectile/bullet/dart/syringe/dart + firing_effect_type = null + harmful = FALSE + dartvolume = 20 + /obj/item/ammo_casing/dnainjector name = "rigged syringe gun spring" desc = "A high-power spring that throws DNA injectors." diff --git a/code/modules/projectiles/boxes_magazines/_box_magazine.dm b/code/modules/projectiles/boxes_magazines/_box_magazine.dm index 9ea030da99..e44fcb38c8 100644 --- a/code/modules/projectiles/boxes_magazines/_box_magazine.dm +++ b/code/modules/projectiles/boxes_magazines/_box_magazine.dm @@ -23,7 +23,7 @@ var/list/bullet_cost var/list/base_cost// override this one as well if you override bullet_cost -/obj/item/ammo_box/Initialize() +/obj/item/ammo_box/Initialize(mapload) . = ..() if (!bullet_cost) for (var/material in custom_materials) diff --git a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm index 1f1cc10459..8c26f40d8b 100644 --- a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm +++ b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm @@ -60,6 +60,13 @@ desc = "Designed to quickly reload revolvers. These rounds are manufactured within extremely tight tolerances, making them easy to show off trickshots with." ammo_type = /obj/item/ammo_casing/c38/match +/obj/item/ammo_box/c38/pouch + name = "ammo packet (.38)" + desc = "A small ammunition packet made of synthleather. Not particularly useful for speedily reloading, but can hold a bit more." + multiload = FALSE + max_ammo = 8 + icon_state = "38pch" + /obj/item/ammo_box/g4570 name = "ammo box (.45-70 GOVT)" desc = "Brought to you at great expense,this box contains 10 more .45-70 GOVT bullets." @@ -156,7 +163,7 @@ icon = 'icons/obj/ammo.dmi' icon_state = "shotgunclip" caliber = "shotgun" // slapped in to allow shell mix n match - slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_POCKET + slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_POCKETS w_class = WEIGHT_CLASS_NORMAL w_volume = ITEM_VOLUME_STRIPPER_CLIP ammo_type = /obj/item/ammo_casing/shotgun diff --git a/code/modules/projectiles/boxes_magazines/external/lmg.dm b/code/modules/projectiles/boxes_magazines/external/lmg.dm index 659d9ae2c7..e8447950ce 100644 --- a/code/modules/projectiles/boxes_magazines/external/lmg.dm +++ b/code/modules/projectiles/boxes_magazines/external/lmg.dm @@ -1,26 +1,32 @@ -/obj/item/ammo_box/magazine/mm195x129 - name = "box magazine (1.95x129mm)" +/obj/item/ammo_box/magazine/mm712x82 + name = "box magazine (7.12x82mm)" icon_state = "a762-50" - ammo_type = /obj/item/ammo_casing/mm195x129 - caliber = "mm195129" + ammo_type = /obj/item/ammo_casing/mm712x82 + caliber = "mm71282" max_ammo = 50 -/obj/item/ammo_box/magazine/mm195x129/hollow - name = "box magazine (Hollow-Point 1.95x129mm)" - ammo_type = /obj/item/ammo_casing/mm195x129/hollow +/obj/item/ammo_box/magazine/mm712x82/hollow + name = "box magazine (Hollow-Point 7.12x82mm)" + ammo_type = /obj/item/ammo_casing/mm712x82/hollow -/obj/item/ammo_box/magazine/mm195x129/ap - name = "box magazine (Armor Penetrating 1.95x129mm)" - ammo_type = /obj/item/ammo_casing/mm195x129/ap +/obj/item/ammo_box/magazine/mm712x82/ap + name = "box magazine (Armor Penetrating 7.12x82mm)" + ammo_type = /obj/item/ammo_casing/mm712x82/ap -/obj/item/ammo_box/magazine/mm195x129/incen - name = "box magazine (Incendiary 1.95x129mm)" - ammo_type = /obj/item/ammo_casing/mm195x129/incen +/obj/item/ammo_box/magazine/mm712x82/incen + name = "box magazine (Incendiary 7.12x82mm)" + ammo_type = /obj/item/ammo_casing/mm712x82/incen -/obj/item/ammo_box/magazine/mm195x129/update_icon() +/obj/item/ammo_box/magazine/mm712x82/update_icon() ..() icon_state = "a762-[round(ammo_count(),10)]" /obj/item/ammo_box/magazine/mm712x82/match name = "box magazine (Match 7.12x82mm)" + icon_state = "a762-50" ammo_type = /obj/item/ammo_casing/mm712x82/match + max_ammo = 50 + +/obj/item/ammo_box/magazine/mm712x82/update_icon() + ..() + icon_state = "a762-[round(ammo_count(),10)]" diff --git a/code/modules/projectiles/boxes_magazines/external/rechargable.dm b/code/modules/projectiles/boxes_magazines/external/rechargable.dm index 5b774b111a..eaafeba349 100644 --- a/code/modules/projectiles/boxes_magazines/external/rechargable.dm +++ b/code/modules/projectiles/boxes_magazines/external/rechargable.dm @@ -3,7 +3,7 @@ desc = "A rechargeable, detachable battery that serves as a magazine for laser rifles." icon_state = "oldrifle-20" ammo_type = /obj/item/ammo_casing/caseless/laser - caliber = "laser" + caliber = LASER max_ammo = 20 /obj/item/ammo_box/magazine/recharge/update_icon() @@ -54,7 +54,7 @@ desc = "A miniature battery for an energy weapon." icon = 'icons/obj/ammo.dmi' icon_state = "mws_batt" - slot_flags = SLOT_BELT | SLOT_EARS + slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_EARS throwforce = 1 caliber = "mws" @@ -67,7 +67,7 @@ var/e_cost = 100 projectile_type = /obj/item/projectile/beam -/obj/item/ammo_casing/mws_batt/Initialize() +/obj/item/ammo_casing/mws_batt/Initialize(mapload) . = ..() pixel_x = rand(-10, 10) pixel_y = rand(-10, 10) diff --git a/code/modules/projectiles/boxes_magazines/internal/revolver.dm b/code/modules/projectiles/boxes_magazines/internal/revolver.dm index a9cad1adc8..3e91b2670e 100644 --- a/code/modules/projectiles/boxes_magazines/internal/revolver.dm +++ b/code/modules/projectiles/boxes_magazines/internal/revolver.dm @@ -17,6 +17,6 @@ max_ammo = 6 multiload = 0 -/obj/item/ammo_box/magazine/internal/rus357/Initialize() +/obj/item/ammo_box/magazine/internal/rus357/Initialize(mapload) stored_ammo += new ammo_type(src) . = ..() diff --git a/code/modules/projectiles/boxes_magazines/internal/shotgun.dm b/code/modules/projectiles/boxes_magazines/internal/shotgun.dm index 12f4e1f1c5..4aa8b917b5 100644 --- a/code/modules/projectiles/boxes_magazines/internal/shotgun.dm +++ b/code/modules/projectiles/boxes_magazines/internal/shotgun.dm @@ -61,3 +61,7 @@ ammo_type = /obj/item/ammo_casing/c38 // they're rubber by default, i guess caliber = "38" max_ammo = 7 + +/obj/item/ammo_box/magazine/internal/shot/levergun/brush + name = "brush gun internal magazine" + ammo_type = /obj/item/ammo_casing/g4570 diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 06bf298454..236143dc43 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -1,5 +1,6 @@ #define DUALWIELD_PENALTY_EXTRA_MULTIPLIER 1.4 +#define FIRING_PIN_REMOVAL_DELAY 50 /obj/item/gun name = "gun" @@ -21,6 +22,7 @@ var/ranged_attack_speed = CLICK_CD_RANGE var/melee_attack_speed = CLICK_CD_MELEE + var/gun_flags = NONE var/fire_sound = "gunshot" var/suppressed = null //whether or not a message is displayed when fired var/can_suppress = FALSE @@ -31,6 +33,7 @@ trigger_guard = TRIGGER_GUARD_NORMAL //trigger guard on the weapon, hulks can't fire them with their big meaty fingers var/sawn_desc = null //description change if weapon is sawn-off var/sawn_off = FALSE + var/firing_burst = 0 //Prevent the weapon from firing again while already firing /// can we be put into a turret var/can_turret = TRUE @@ -56,6 +59,8 @@ var/burst_spread = 0 //Spread induced by the gun itself during burst fire per iteration. Only checked if spread is 0. var/randomspread = 1 //Set to 0 for shotguns. This is used for weapons that don't fire all their bullets at once. var/inaccuracy_modifier = 1 + var/semicd = 0 //cooldown handler + var/dual_wield_spread = 24 //additional spread when dual wielding lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' @@ -63,7 +68,7 @@ var/obj/item/firing_pin/pin = /obj/item/firing_pin //standard firing pin for most guns var/no_pin_required = FALSE //whether the gun can be fired without a pin - var/obj/item/flashlight/gun_light + var/obj/item/flashlight/seclite/gun_light var/can_flashlight = FALSE var/gunlight_state = "flight" var/obj/item/kitchen/knife/bayonet @@ -86,24 +91,64 @@ var/zoom_out_amt = 0 var/datum/action/item_action/toggle_scope_zoom/azoom + //Firemodes + var/datum/action/item_action/toggle_firemode/firemode_action + /// Current fire selection, can choose between burst, single, and full auto. + var/fire_select = SELECT_SEMI_AUTOMATIC + var/fire_select_index = 1 + /// What modes does this weapon have? Put SELECT_FULLY_AUTOMATIC in here to enable fully automatic behaviours. + var/list/fire_select_modes = list(SELECT_SEMI_AUTOMATIC) + /// if i`1t has an icon for a selector switch indicating current firemode. + var/selector_switch_icon = FALSE + var/dualwield_spread_mult = 1 //dualwield spread multiplier /// Just 'slightly' snowflakey way to modify projectile damage for projectiles fired from this gun. var/projectile_damage_multiplier = 1 - var/automatic = 0 //can gun use it, 0 is no, anything above 0 is the delay between clicks in ds + /// directional recoil multiplier + var/dir_recoil_amp = 10 -/obj/item/gun/Initialize() +/obj/item/gun/ui_action_click(mob/user, action) + if(istype(action, /datum/action/item_action/toggle_firemode)) + fire_select() + else if(istype(action, /datum/action/item_action/toggle_scope_zoom)) + zoom(user, user.dir) + else if(istype(action, alight)) + toggle_gunlight() + else + ..() + +/obj/item/gun/Initialize(mapload) . = ..() - if(no_pin_required) - pin = null - else if(pin) + if(pin) pin = new pin(src) + if(gun_light) - alight = new (src) + alight = new(src) + if(zoomable) azoom = new (src) + if(burst_size > 1 && !(SELECT_BURST_SHOT in fire_select_modes)) + fire_select_modes.Add(SELECT_BURST_SHOT) + else if(burst_size <= 1 && (SELECT_BURST_SHOT in fire_select_modes)) + fire_select_modes.Remove(SELECT_BURST_SHOT) + + burst_size = 1 + + sortList(fire_select_modes, /proc/cmp_numeric_asc) + + if(fire_select_modes.len > 1) + firemode_action = new(src) + firemode_action.button_icon_state = "fireselect_[fire_select]" + firemode_action.UpdateButtonIcon() + +/obj/item/gun/ComponentInitialize() + . = ..() + if(SELECT_FULLY_AUTOMATIC in fire_select_modes) + AddComponent(/datum/component/automatic_fire, fire_delay) + /obj/item/gun/Destroy() if(pin) QDEL_NULL(pin) @@ -113,25 +158,69 @@ QDEL_NULL(bayonet) if(chambered) QDEL_NULL(chambered) + if(azoom) + QDEL_NULL(azoom) + if(firemode_action) + QDEL_NULL(firemode_action) return ..() -/obj/item/gun/CheckParts(list/parts_list) - ..() - var/obj/item/gun/G = locate(/obj/item/gun) in contents - if(G) - G.forceMove(loc) - QDEL_NULL(G.pin) - visible_message("[G] can now fit a new pin, but the old one was destroyed in the process.", null, null, 3) - qdel(src) - /obj/item/gun/examine(mob/user) . = ..() - if(no_pin_required) + if(!no_pin_required) + if(pin) + . += "It has \a [pin] installed." + . += "[pin] looks like it could be removed with some tools." + else + . += "It doesn't have a firing pin installed, and won't fire." + + if(gun_light) + . += "It has \a [gun_light] [can_flashlight ? "" : "permanently "]mounted on it." + if(can_flashlight) //if it has a light and this is false, the light is permanent. + . += "[gun_light] looks like it can be unscrewed from [src]." + else if(can_flashlight) + . += "It has a mounting point for a seclite." + + if(bayonet) + . += "It has \a [bayonet] [can_bayonet ? "" : "permanently "]affixed to it." + if(can_bayonet) //if it has a bayonet and this is false, the bayonet is permanent. + . += "[bayonet] looks like it can be unscrewed from [src]." + else if(can_bayonet) + . += "It has a bayonet lug on it." + +/obj/item/gun/proc/fire_select() + var/mob/living/carbon/human/user = usr + + var/max_mode = fire_select_modes.len + + if(max_mode <= 1) + to_chat(user, "[src] is not capable of switching firemodes!") return - if(pin) - . += "It has \a [pin] installed." - else - . += "It doesn't have a firing pin installed, and won't fire." + + fire_select_index = 1 + fire_select_index % max_mode //Magic math to cycle through this shit! + + fire_select = fire_select_modes[fire_select_index] + + switch(fire_select) + if(SELECT_SEMI_AUTOMATIC) + burst_size = 1 + fire_delay = 0 + SEND_SIGNAL(src, COMSIG_GUN_AUTOFIRE_DESELECTED, user) + to_chat(user, "You switch [src] to semi-automatic.") + if(SELECT_BURST_SHOT) + burst_size = initial(burst_size) + fire_delay = initial(fire_delay) + SEND_SIGNAL(src, COMSIG_GUN_AUTOFIRE_DESELECTED, user) + to_chat(user, "You switch [src] to [burst_size]-round burst.") + if(SELECT_FULLY_AUTOMATIC) + burst_size = 1 + SEND_SIGNAL(src, COMSIG_GUN_AUTOFIRE_SELECTED, user) + to_chat(user, "You switch [src] to automatic.") + + playsound(user, 'sound/weapons/empty.ogg', 100, TRUE) + update_appearance() + firemode_action.button_icon_state = "fireselect_[fire_select]" + firemode_action.UpdateButtonIcon() + return TRUE /obj/item/gun/equipped(mob/living/user, slot) . = ..() @@ -153,7 +242,7 @@ /obj/item/gun/proc/shoot_live_shot(mob/living/user, pointblank = FALSE, mob/pbtarget, message = 1, stam_cost = 0) if(recoil) - shake_camera(user, recoil + 1, recoil) + directional_recoil(user, recoil*dir_recoil_amp, Get_Angle(user, pbtarget)) if(stam_cost) //CIT CHANGE - makes gun recoil cause staminaloss var/safe_cost = clamp(stam_cost, 0, user.stamina_buffer)*(firing && burst_size >= 2 ? 1/burst_size : 1) @@ -239,7 +328,7 @@ return if(weapon_weight == WEAPON_HEAVY && user.get_inactive_held_item()) - to_chat(user, "You need both hands free to fire \the [src]!") + to_chat(user, "You need both hands free to fire [src]!") return user.DelayNextAction() @@ -417,12 +506,12 @@ if(!gun_light) if(!user.transferItemToLoc(I, src)) return - to_chat(user, "You click \the [S] into place on \the [src].") + to_chat(user, "You click [S] into place on [src].") if(S.on) set_light(0) - gun_light = S + set_gun_light(S) update_gunlight(user) - alight = new /datum/action/item_action/toggle_gunlight(src) + alight = new(src) if(loc == user) alight.Grant(user) else if(istype(I, /obj/item/kitchen/knife)) @@ -431,32 +520,132 @@ return ..() if(!user.transferItemToLoc(I, src)) return - to_chat(user, "You attach \the [K] to the front of \the [src].") + to_chat(user, "You attach [K] to [src]'s bayonet lug.") bayonet = K update_icon() - else if(I.tool_behaviour == TOOL_SCREWDRIVER) - if(gun_light) - var/obj/item/flashlight/seclite/S = gun_light - to_chat(user, "You unscrew the seclite from \the [src].") - gun_light = null - S.forceMove(get_turf(user)) - update_gunlight(user) - S.update_brightness(user) - QDEL_NULL(alight) - if(bayonet) - to_chat(user, "You unscrew the bayonet from \the [src].") - var/obj/item/kitchen/knife/K = bayonet - K.forceMove(get_turf(user)) - bayonet = null - update_icon() else return ..() -/obj/item/gun/ui_action_click(mob/user, action) - if(istype(action, /datum/action/item_action/toggle_scope_zoom)) - zoom(user, user.dir) - else if(istype(action, alight)) - toggle_gunlight() +/obj/item/gun/screwdriver_act(mob/living/user, obj/item/I) + . = ..() + if(.) + return + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + if((can_flashlight && gun_light) && (can_bayonet && bayonet)) //give them a choice instead of removing both + var/list/possible_items = list(gun_light, bayonet) + var/obj/item/item_to_remove = input(user, "Select an attachment to remove", "Attachment Removal") as null|obj in possible_items + if(!item_to_remove || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + return remove_gun_attachment(user, I, item_to_remove) + + else if(gun_light && can_flashlight) //if it has a gun_light and can_flashlight is false, the flashlight is permanently attached. + return remove_gun_attachment(user, I, gun_light, "unscrewed") + + else if(bayonet && can_bayonet) //if it has a bayonet, and the bayonet can be removed + return remove_gun_attachment(user, I, bayonet, "unfix") + + else if(pin && user.is_holding(src)) + user.visible_message(span_warning("[user] attempts to remove [pin] from [src] with [I]."), + span_notice("You attempt to remove [pin] from [src]. (It will take [DisplayTimeText(FIRING_PIN_REMOVAL_DELAY)].)"), null, 3) + if(I.use_tool(src, user, FIRING_PIN_REMOVAL_DELAY, volume = 50)) + if(!pin) //check to see if the pin is still there, or we can spam messages by clicking multiple times during the tool delay + return + user.visible_message(span_notice("[pin] is pried out of [src] by [user], destroying the pin in the process."), + span_warning("You pry [pin] out with [I], destroying the pin in the process."), null, 3) + QDEL_NULL(pin) + return TRUE + +/obj/item/gun/welder_act(mob/living/user, obj/item/I) + . = ..() + if(.) + return + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + if(pin && user.is_holding(src)) + user.visible_message(span_warning("[user] attempts to remove [pin] from [src] with [I]."), + span_notice("You attempt to remove [pin] from [src]. (It will take [DisplayTimeText(FIRING_PIN_REMOVAL_DELAY)].)"), null, 3) + if(I.use_tool(src, user, FIRING_PIN_REMOVAL_DELAY, 5, volume = 50)) + if(!pin) //check to see if the pin is still there, or we can spam messages by clicking multiple times during the tool delay + return + user.visible_message(span_notice("[pin] is spliced out of [src] by [user], melting part of the pin in the process."), + span_warning("You splice [pin] out of [src] with [I], melting part of the pin in the process."), null, 3) + QDEL_NULL(pin) + return TRUE + +/obj/item/gun/wirecutter_act(mob/living/user, obj/item/I) + . = ..() + if(.) + return + if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return + if(pin && user.is_holding(src)) + user.visible_message(span_warning("[user] attempts to remove [pin] from [src] with [I]."), + span_notice("You attempt to remove [pin] from [src]. (It will take [DisplayTimeText(FIRING_PIN_REMOVAL_DELAY)].)"), null, 3) + if(I.use_tool(src, user, FIRING_PIN_REMOVAL_DELAY, volume = 50)) + if(!pin) //check to see if the pin is still there, or we can spam messages by clicking multiple times during the tool delay + return + user.visible_message(span_notice("[pin] is ripped out of [src] by [user], mangling the pin in the process."), + span_warning("You rip [pin] out of [src] with [I], mangling the pin in the process."), null, 3) + QDEL_NULL(pin) + return TRUE + +/obj/item/gun/proc/remove_gun_attachment(mob/living/user, obj/item/tool_item, obj/item/item_to_remove, removal_verb) + if(tool_item) + tool_item.play_tool_sound(src) + to_chat(user, span_notice("You [removal_verb ? removal_verb : "remove"] [item_to_remove] from [src].")) + item_to_remove.forceMove(drop_location()) + + if(Adjacent(user) && !issilicon(user)) + user.put_in_hands(item_to_remove) + + if(item_to_remove == bayonet) + return clear_bayonet() + else if(item_to_remove == gun_light) + return clear_gunlight() + +/obj/item/gun/proc/clear_bayonet() + if(!bayonet) + return + bayonet = null + update_appearance() + return TRUE + +/obj/item/gun/proc/clear_gunlight() + if(!gun_light) + return + var/obj/item/flashlight/seclite/removed_light = gun_light + set_gun_light(null) + update_gunlight() + removed_light.update_brightness() + QDEL_NULL(alight) + return TRUE + +/** + * Swaps the gun's seclight, dropping the old seclight if it has not been qdel'd. + * + * Returns the former gun_light that has now been replaced by this proc. + * Arguments: + * * new_light - The new light to attach to the weapon. Can be null, which will mean the old light is removed with no replacement. + */ +/obj/item/gun/proc/set_gun_light(obj/item/flashlight/seclite/new_light) + // Doesn't look like this should ever happen? We're replacing our old light with our old light? + if(gun_light == new_light) + CRASH("Tried to set a new gun light when the old gun light was also the new gun light.") + + . = gun_light + + // If there's an old gun light that isn't being QDELETED, detatch and drop it to the floor. + if(!QDELETED(gun_light)) + if(gun_light.loc == src) + gun_light.forceMove(get_turf(src)) + + // If there's a new gun light to be added, attach and move it to the gun. + if(new_light) + if(new_light.loc != src) + new_light.forceMove(src) + + gun_light = new_light /obj/item/gun/proc/toggle_gunlight() if(!gun_light) @@ -507,7 +696,7 @@ . += knife_overlay /obj/item/gun/item_action_slot_check(slot, mob/user, datum/action/A) - if(istype(A, /datum/action/item_action/toggle_scope_zoom) && slot != SLOT_HANDS) + if(istype(A, /datum/action/item_action/toggle_scope_zoom) && slot != ITEM_SLOT_HANDS) return FALSE return ..() @@ -545,7 +734,7 @@ if(chambered && chambered.BB) chambered.BB.damage *= 5 - process_fire(target, user, TRUE, params, stam_cost = getstamcost(user)) + process_fire(target, user, TRUE, params, BODY_ZONE_HEAD, stam_cost = getstamcost(user)) /obj/item/gun/proc/unlock() //used in summon guns and as a convience for admins if(pin) @@ -606,9 +795,16 @@ user.client.view_size.zoomIn() /obj/item/gun/handle_atom_del(atom/A) + if(A == pin) + pin = null if(A == chambered) chambered = null update_icon() + if(A == bayonet) + clear_bayonet() + if(A == gun_light) + clear_gunlight() + return ..() /obj/item/gun/proc/getinaccuracy(mob/living/user, bonus_spread, stamloss) return 0 // Replacement TBD: Exponential curved aim instability system. @@ -642,3 +838,6 @@ . = recoil if(user && !user.has_gravity()) . = recoil*5 + +#undef FIRING_PIN_REMOVAL_DELAY +#undef DUALWIELD_PENALTY_EXTRA_MULTIPLIER diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index 1416dfa812..5c6aff5564 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -3,6 +3,7 @@ name = "projectile gun" icon_state = "pistol" w_class = WEIGHT_CLASS_NORMAL + recoil = 0.25 var/spawnwithmagazine = TRUE var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info var/obj/item/ammo_box/magazine/magazine @@ -10,7 +11,7 @@ var/magazine_wording = "magazine" var/sawn_item_state = "gun" -/obj/item/gun/ballistic/Initialize() +/obj/item/gun/ballistic/Initialize(mapload) . = ..() if(!spawnwithmagazine) update_icon() @@ -22,7 +23,7 @@ /obj/item/gun/ballistic/update_icon_state() if(current_skin) - icon_state = "[unique_reskin[current_skin]][suppressed ? "-suppressed" : ""][sawn_off ? "-sawn" : ""]" + icon_state = "[unique_reskin[current_skin]["icon_state"]][suppressed ? "-suppressed" : ""][sawn_off ? "-sawn" : ""]" else icon_state = "[initial(icon_state)][suppressed ? "-suppressed" : ""][sawn_off ? "-sawn" : ""]" diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index a3985c8f42..4d08520246 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -5,8 +5,8 @@ var/automatic_burst_overlay = TRUE can_suppress = TRUE burst_size = 3 - burst_shot_delay = 2 - actions_types = list(/datum/action/item_action/toggle_firemode) + fire_delay = 2 + fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_BURST_SHOT, SELECT_FULLY_AUTOMATIC) /obj/item/gun/ballistic/automatic/proto name = "\improper Nanotrasen Saber SMG" @@ -15,6 +15,7 @@ fire_sound = "sound/weapons/gunshot_smg_alt.ogg" mag_type = /obj/item/ammo_box/magazine/smgm9mm pin = null + burst_size = 1 /obj/item/gun/ballistic/automatic/proto/unrestricted pin = /obj/item/firing_pin @@ -55,34 +56,6 @@ else to_chat(user, "You cannot seem to get \the [src] out of your hands!") -/obj/item/gun/ballistic/automatic/ui_action_click(mob/user, action) - if(istype(action, /datum/action/item_action/toggle_firemode)) - burst_select() - else - return ..() - -/obj/item/gun/ballistic/automatic/proc/burst_select() - var/mob/living/carbon/human/user = usr - select = !select - if(!select) - disable_burst() - to_chat(user, "You switch to semi-automatic.") - else - enable_burst() - to_chat(user, "You switch to [burst_size]-rnd burst.") - - playsound(user, 'sound/weapons/empty.ogg', 100, 1) - update_icon() - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - -/obj/item/gun/ballistic/automatic/proc/enable_burst() - burst_size = initial(burst_size) - -/obj/item/gun/ballistic/automatic/proc/disable_burst() - burst_size = 1 - /obj/item/gun/ballistic/automatic/can_shoot() return get_ammo() @@ -110,7 +83,7 @@ /obj/item/gun/ballistic/automatic/c20r/unrestricted pin = /obj/item/firing_pin -/obj/item/gun/ballistic/automatic/c20r/Initialize() +/obj/item/gun/ballistic/automatic/c20r/Initialize(mapload) . = ..() update_icon() @@ -122,7 +95,7 @@ icon_state = "c20r[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" /obj/item/gun/ballistic/automatic/wt550 - name = "security semi-auto smg" + name = "security semi-auto PDW" desc = "An outdated personal defence weapon. Uses 4.6x30mm rounds and is designated the WT-550 Semi-Automatic SMG." icon_state = "wt550" item_state = "arg" @@ -136,18 +109,10 @@ knife_y_offset = 12 automatic_burst_overlay = FALSE -/obj/item/gun/ballistic/automatic/wt550/enable_burst() - . = ..() - spread = 15 - /obj/item/gun/ballistic/automatic/wt550/afterattack() . = ..() empty_alarm() -/obj/item/gun/ballistic/automatic/wt550/disable_burst() - . = ..() - spread = 0 - /obj/item/gun/ballistic/automatic/wt550/update_icon_state() icon_state = "wt550[magazine ? "-[CEILING(((get_ammo(FALSE) / magazine.max_ammo) * 20) /4, 1)*4]" : "-0"]" //Sprites only support up to 20. @@ -172,7 +137,7 @@ burst_shot_delay = 2 pin = /obj/item/firing_pin/implant/pindicate -/obj/item/gun/ballistic/automatic/m90/Initialize() +/obj/item/gun/ballistic/automatic/m90/Initialize(mapload) . = ..() underbarrel = new /obj/item/gun/ballistic/revolver/grenadelauncher(src) update_icon() @@ -180,7 +145,7 @@ /obj/item/gun/ballistic/automatic/m90/unrestricted pin = /obj/item/firing_pin -/obj/item/gun/ballistic/automatic/m90/unrestricted/Initialize() +/obj/item/gun/ballistic/automatic/m90/unrestricted/Initialize(mapload) . = ..() underbarrel = new /obj/item/gun/ballistic/revolver/grenadelauncher/unrestricted(src) update_icon() @@ -211,6 +176,7 @@ /obj/item/gun/ballistic/automatic/m90/update_icon_state() icon_state = "[initial(icon_state)][magazine ? "" : "-e"]" +/* /obj/item/gun/ballistic/automatic/m90/burst_select() var/mob/living/carbon/human/user = usr switch(select) @@ -228,6 +194,7 @@ playsound(user, 'sound/weapons/empty.ogg', 100, 1) update_icon() return +*/ /obj/item/gun/ballistic/automatic/tommygun name = "\improper Thompson SMG" @@ -274,7 +241,7 @@ /obj/item/gun/ballistic/automatic/shotgun/bulldog/unrestricted pin = /obj/item/firing_pin -/obj/item/gun/ballistic/automatic/shotgun/bulldog/Initialize() +/obj/item/gun/ballistic/automatic/shotgun/bulldog/Initialize(mapload) . = ..() update_icon() @@ -296,22 +263,25 @@ /obj/item/gun/ballistic/automatic/l6_saw name = "\improper L6 SAW" - desc = "A heavily modified 1.95x129mm light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the receiver below the designation." + desc = "A heavily modified 7.12x82mm light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the receiver below the designation." icon_state = "l6closed100" item_state = "l6closedmag" fire_sound = "sound/weapons/lmgshot.ogg" w_class = WEIGHT_CLASS_HUGE slot_flags = 0 - mag_type = /obj/item/ammo_box/magazine/mm195x129 + mag_type = /obj/item/ammo_box/magazine/mm712x82 weapon_weight = WEAPON_HEAVY - var/cover_open = FALSE can_suppress = FALSE - burst_size = 3 - burst_shot_delay = 1 + burst_size = 1 + actions_types = list() spread = 7 pin = /obj/item/firing_pin/implant/pindicate - automatic_burst_overlay = FALSE + var/cover_open = FALSE +/obj/item/gun/ballistic/automatic/l6_saw/Initialize() + . = ..() + AddElement(/datum/element/update_icon_updates_onmob) + AddComponent(/datum/component/automatic_fire, 0.2 SECONDS) /obj/item/gun/ballistic/automatic/l6_saw/unrestricted pin = /obj/item/firing_pin diff --git a/code/modules/projectiles/guns/ballistic/launchers.dm b/code/modules/projectiles/guns/ballistic/launchers.dm index c53366c4f5..10a6eea89d 100644 --- a/code/modules/projectiles/guns/ballistic/launchers.dm +++ b/code/modules/projectiles/guns/ballistic/launchers.dm @@ -39,7 +39,7 @@ mag_type = /obj/item/ammo_box/magazine/m75 burst_size = 1 fire_delay = 0 - actions_types = list() + fire_select_modes = list(SELECT_SEMI_AUTOMATIC) casing_ejector = FALSE /obj/item/gun/ballistic/automatic/gyropistol/update_icon_state() diff --git a/code/modules/projectiles/guns/ballistic/magweapon.dm b/code/modules/projectiles/guns/ballistic/magweapon.dm index c01a2fb74a..f3a11eb179 100644 --- a/code/modules/projectiles/guns/ballistic/magweapon.dm +++ b/code/modules/projectiles/guns/ballistic/magweapon.dm @@ -21,7 +21,7 @@ var/obj/item/stock_parts/cell/cell var/cell_type = /obj/item/stock_parts/cell/magnetic -/obj/item/gun/ballistic/automatic/magrifle/Initialize() +/obj/item/gun/ballistic/automatic/magrifle/Initialize(mapload) . = ..() if(cell_type) cell = new cell_type(src) diff --git a/code/modules/projectiles/guns/ballistic/pistol.dm b/code/modules/projectiles/guns/ballistic/pistol.dm index 98b654aadb..53ba6d6a92 100644 --- a/code/modules/projectiles/guns/ballistic/pistol.dm +++ b/code/modules/projectiles/guns/ballistic/pistol.dm @@ -7,7 +7,7 @@ can_suppress = TRUE burst_size = 1 fire_delay = 0 - actions_types = list() + fire_select_modes = list(SELECT_SEMI_AUTOMATIC) automatic_burst_overlay = FALSE /obj/item/gun/ballistic/automatic/pistol/no_mag @@ -30,27 +30,28 @@ can_unsuppress = TRUE automatic_burst_overlay = FALSE obj_flags = UNIQUE_RENAME - unique_reskin = list("Default" = "cde", - "N-99" = "n99", - "Stealth" = "stealthpistol", - "HKVP-78" = "vp78", - "Luger" = "p08b", - "Mk.58" = "secguncomp", - "PX4 Storm" = "px4" - ) + unique_reskin = list( + "Default" = list("icon_state" = "cde"), + "N-99" = list("icon_state" = "n99"), + "Stealth" = list("icon_state" = "stealthpistol"), + "HKVP-78" = list("icon_state" = "vp78"), + "Luger" = list("icon_state" = "p08b"), + "Mk.58" = list("icon_state" = "secguncomp"), + "PX4 Storm" = list("icon_state" = "px4") + ) /obj/item/gun/ballistic/automatic/pistol/modular/update_icon_state() if(current_skin) - icon_state = "[unique_reskin[current_skin]][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" + icon_state = "[unique_reskin[current_skin]["icon_state"]][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" else icon_state = "[initial(icon_state)][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" /obj/item/gun/ballistic/automatic/pistol/modular/update_overlays() . = ..() if(magazine && suppressed) - . += "[unique_reskin[current_skin]]-magazine-sup" //Yes, this means the default iconstate can't have a magazine overlay + . += "[unique_reskin[current_skin]["icon_state"]]-magazine-sup" //Yes, this means the default iconstate can't have a magazine overlay else if (magazine) - . += "[unique_reskin[current_skin]]-magazine" + . += "[unique_reskin[current_skin]["icon_state"]]-magazine" /obj/item/gun/ballistic/automatic/pistol/m1911 name = "\improper M1911" @@ -104,7 +105,7 @@ mag_type = /obj/item/ammo_box/magazine/pistolm9mm burst_size = 3 fire_delay = 2 - actions_types = list(/datum/action/item_action/toggle_firemode) + fire_select_modes = list(SELECT_SEMI_AUTOMATIC, SELECT_BURST_SHOT, SELECT_FULLY_AUTOMATIC) /obj/item/gun/ballistic/automatic/pistol/stickman name = "flat gun" @@ -137,7 +138,7 @@ burst_size = 1 can_suppress = FALSE w_class = WEIGHT_CLASS_NORMAL - actions_types = list() + fire_select_modes = list(SELECT_SEMI_AUTOMATIC) fire_sound = 'sound/weapons/noscope.ogg' spread = 20 //damn thing has no rifling. automatic_burst_overlay = FALSE diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 0d60203cb5..28f81e13ae 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -5,8 +5,9 @@ mag_type = /obj/item/ammo_box/magazine/internal/cylinder fire_sound = "sound/weapons/revolvershot.ogg" casing_ejector = FALSE + recoil = 0.5 -/obj/item/gun/ballistic/revolver/Initialize() +/obj/item/gun/ballistic/revolver/Initialize(mapload) . = ..() if(!istype(magazine, /obj/item/ammo_box/magazine/internal/cylinder)) verbs += /obj/item/gun/ballistic/revolver/verb/spin @@ -87,13 +88,15 @@ /obj/item/gun/ballistic/revolver/syndicate obj_flags = UNIQUE_RENAME - unique_reskin = list("Default" = "revolver", - "Silver" = "russianrevolver", - "Robust" = "revolvercit", - "Bulky" = "revolverhakita", - "Polished" = "revolvertoriate", - "Soulless" = "revolveroldflip", - "Soul" = "revolverold") + unique_reskin = list( + "Default" = list("icon_state" = "revolver"), + "Silver" = list("icon_state" = "russianrevolver"), + "Robust" = list("icon_state" = "revolvercit"), + "Bulky" = list("icon_state" = "revolverhakita"), + "Polished" = list("icon_state" = "revolvertoriate"), + "Soulless" = list("icon_state" = "revolveroldflip"), + "Soul" = list("icon_state" = "revolverold") + ) /obj/item/gun/ballistic/revolver/detective name = "\improper .38 Mars Special" @@ -101,15 +104,16 @@ icon_state = "detective" mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38 obj_flags = UNIQUE_RENAME - unique_reskin = list("Default" = "detective", - "Leopard Spots" = "detective_leopard", - "Black Panther" = "detective_panther", - "Gold Trim" = "detective_gold", - "The Peacemaker" = "detective_peacemaker" - ) + unique_reskin = list( + "Default" = list("icon_state" = "detective"), + "Leopard Spots" = list("icon_state" = "detective_leopard"), + "Black Panther" = list("icon_state" = "detective_panther"), + "Gold Trim" = list("icon_state" = "detective_gold"), + "The Peacemaker" = list("icon_state" = "detective_peacemaker") + ) var/list/safe_calibers -/obj/item/gun/ballistic/revolver/detective/Initialize() +/obj/item/gun/ballistic/revolver/detective/Initialize(mapload) . = ..() safe_calibers = magazine.caliber @@ -166,6 +170,7 @@ icon_state = "goldrevolver" fire_sound = 'sound/weapons/resonator_blast.ogg' recoil = 8 + dir_recoil_amp = 5 // 40 directional recoil is already really funny pin = /obj/item/firing_pin /obj/item/gun/ballistic/revolver/nagant @@ -191,7 +196,7 @@ . = ..() spun = TRUE -/obj/item/gun/ballistic/revolver/russian/Initialize() +/obj/item/gun/ballistic/revolver/russian/Initialize(mapload) . = ..() do_spin() spun = TRUE @@ -285,19 +290,21 @@ item_state = "shotgun" w_class = WEIGHT_CLASS_BULKY weapon_weight = WEAPON_MEDIUM + recoil = 1 force = 10 flags_1 = CONDUCT_1 slot_flags = ITEM_SLOT_BACK mag_type = /obj/item/ammo_box/magazine/internal/shot/dual sawn_desc = "Omar's coming!" obj_flags = UNIQUE_RENAME - unique_reskin = list("Default" = "dshotgun", - "Dark Red Finish" = "dshotgun-d", - "Ash" = "dshotgun-f", - "Faded Grey" = "dshotgun-g", - "Maple" = "dshotgun-l", - "Rosewood" = "dshotgun-p" - ) + unique_reskin = list( + "Default" = list("icon_state" = "dshotgun"), + "Dark Red Finish" = list("icon_state" = "dshotgun-d"), + "Ash" = list("icon_state" = "dshotgun-f"), + "Faded Grey" = list("icon_state" = "dshotgun-g"), + "Maple" = list("icon_state" = "dshotgun-l"), + "Rosewood" = list("icon_state" = "dshotgun-p") + ) /obj/item/gun/ballistic/revolver/doublebarrel/attackby(obj/item/A, mob/user, params) ..() @@ -339,9 +346,10 @@ slot_flags = null mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised sawn_desc = "I'm just here for the gasoline." - unique_reskin = list("Default" = "ishotgun", - "Cobbled" = "old_ishotgun" - ) + unique_reskin = list( + "Default" = list("icon_state" = "ishotgun"), + "Cobbled" = list("icon_state" = "old_ishotgun") + ) var/slung = FALSE /obj/item/gun/ballistic/revolver/doublebarrel/improvised/attackby(obj/item/A, mob/user, params) diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index 3e7e2c9e9c..0b92e63ca6 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -5,12 +5,14 @@ item_state = "shotgun" fire_sound = "sound/weapons/gunshotshotgunshot.ogg" w_class = WEIGHT_CLASS_BULKY + recoil = 1 force = 10 flags_1 = CONDUCT_1 slot_flags = ITEM_SLOT_BACK mag_type = /obj/item/ammo_box/magazine/internal/shot casing_ejector = FALSE var/recentpump = 0 // to prevent spammage + var/clip_delay = CLICK_CD_MELEE weapon_weight = WEAPON_HEAVY sawn_item_state = "sawnshotgun" @@ -24,6 +26,8 @@ playsound(user, 'sound/weapons/shotguninsert.ogg', 60, 1) A.update_icon() update_icon() + if(istype(A, /obj/item/ammo_box)) + user.SetNextAction(clip_delay) /obj/item/gun/ballistic/shotgun/process_chamber(mob/living/user, empty_chamber = 0) return ..() //changed argument value @@ -94,9 +98,10 @@ fire_delay = 7 mag_type = /obj/item/ammo_box/magazine/internal/shot/riot sawn_desc = "Come with me if you want to live." - unique_reskin = list("Tactical" = "riotshotgun", - "Wood Stock" = "wood_riotshotgun" - ) + unique_reskin = list( + "Tactical" = list("icon_state" = "riotshotgun"), + "Wood Stock" = list("icon_state" = "wood_riotshotgun") + ) /obj/item/gun/ballistic/shotgun/riot/attackby(obj/item/A, mob/user, params) ..() @@ -189,7 +194,7 @@ flags_1 = NONE mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted/arcane_barrage -/obj/item/gun/ballistic/shotgun/boltaction/enchanted/Initialize() +/obj/item/gun/ballistic/shotgun/boltaction/enchanted/Initialize(mapload) . = ..() bolt_open = TRUE pump() @@ -234,26 +239,27 @@ fire_delay = 5 mag_type = /obj/item/ammo_box/magazine/internal/shot/com w_class = WEIGHT_CLASS_HUGE - unique_reskin = list("Tactical" = "cshotgun", - "Slick" = "cshotgun_slick" - ) + unique_reskin = list( + "Tactical" = list("icon_state" = "cshotgun"), + "Slick" = list("icon_state" = "cshotgun_slick") + ) /obj/item/gun/ballistic/shotgun/automatic/combat/compact name = "warden's combat shotgun" - desc = "A modified version of the semi automatic combat shotgun with a collapsible stock. For close encounters." + desc = "A modified version of the semi-automatic combat shotgun with a collapsible stock and a safety that prevents firing while folded. For close encounters." icon_state = "cshotgunc" mag_type = /obj/item/ammo_box/magazine/internal/shot/com w_class = WEIGHT_CLASS_NORMAL var/stock = FALSE + var/extend_sound = 'sound/weapons/batonextend.ogg' recoil = 5 spread = 2 /obj/item/gun/ballistic/shotgun/automatic/combat/compact/AltClick(mob/living/user) - . = ..() - if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)) || item_flags & IN_STORAGE) return toggle_stock(user) - return TRUE + . = ..() /obj/item/gun/ballistic/shotgun/automatic/combat/compact/examine(mob/user) . = ..() @@ -271,10 +277,19 @@ to_chat(user, "You fold the stock.") recoil = 5 spread = 2 + playsound(src.loc, extend_sound, 50, 1) update_icon() /obj/item/gun/ballistic/shotgun/automatic/combat/compact/update_icon_state() - icon_state = "[current_skin ? unique_reskin[current_skin] : "cshotgun"][stock ? "" : "c"]" + icon_state = "[current_skin ? unique_reskin[current_skin]["icon_state"] : "cshotgun"][stock ? "" : "c"]" + +/obj/item/gun/ballistic/shotgun/automatic/combat/compact/afterattack(atom/target, mob/living/user, flag, params) + if(!stock) + shoot_with_empty_chamber(user) + to_chat(user, "[src] won't fire with a folded stock!") + else + . = ..() + update_icon() //Dual Feed Shotgun @@ -291,7 +306,7 @@ . = ..() . += "Alt-click to pump it." -/obj/item/gun/ballistic/shotgun/automatic/dual_tube/Initialize() +/obj/item/gun/ballistic/shotgun/automatic/dual_tube/Initialize(mapload) . = ..() if (!alternate_magazine) alternate_magazine = new mag_type(src) @@ -349,9 +364,13 @@ icon_state = "levercarabine" item_state = "leveraction" sawn_item_state = "maresleg" + var/can_cut = TRUE /obj/item/gun/ballistic/shotgun/leveraction/attackby(obj/item/A, mob/user, params) ..() + if(!can_cut) + to_chat(user, "You can't cut \the [src] down!") + return if(A.tool_behaviour == TOOL_SAW || istype(A, /obj/item/gun/energy/plasmacutter)) sawoff(user) if(istype(A, /obj/item/melee/transforming/energy)) @@ -364,6 +383,14 @@ /obj/item/gun/ballistic/shotgun/leveraction/update_icon_state() if(current_skin) - icon_state = "[unique_reskin[current_skin]][sawn_off ? "-sawn" : ""][chambered ? "" : "-e"]" + icon_state = "[unique_reskin[current_skin]["icon_state"]][sawn_off ? "-sawn" : ""][chambered ? "" : "-e"]" else icon_state = "[initial(icon_state)][sawn_off ? "-sawn" : ""][chambered ? "" : "-e"]" + +/obj/item/gun/ballistic/shotgun/leveraction/brush + name = "brush gun" + desc = "While lever-actions have been horribly out of date for hundreds of years now, \ + putting a nicely sized hole in a man-sized target with a .45-70 round has stayed relatively timeless." + icon_state = "brushgun" + can_cut = FALSE + mag_type = /obj/item/ammo_box/magazine/internal/shot/levergun/brush diff --git a/code/modules/projectiles/guns/ballistic/toy.dm b/code/modules/projectiles/guns/ballistic/toy.dm index e7f26670d4..a72a172891 100644 --- a/code/modules/projectiles/guns/ballistic/toy.dm +++ b/code/modules/projectiles/guns/ballistic/toy.dm @@ -35,7 +35,7 @@ /obj/item/gun/ballistic/automatic/toy/pistol/riot mag_type = /obj/item/ammo_box/magazine/toy/pistol/riot -/obj/item/gun/ballistic/automatic/toy/pistol/riot/Initialize() +/obj/item/gun/ballistic/automatic/toy/pistol/riot/Initialize(mapload) magazine = new /obj/item/ammo_box/magazine/toy/pistol/riot(src) return ..() @@ -140,6 +140,6 @@ recoil = 0.1 inaccuracy_modifier = 0.25 dualwield_spread_mult = 1.4 - slot_flags = SLOT_BELT + slot_flags = ITEM_SLOT_BELT w_class = WEIGHT_CLASS_NORMAL weapon_weight = WEAPON_MEDIUM diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 0f5934e8fd..03dfc46713 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -16,6 +16,7 @@ name = "energy gun" desc = "A basic energy-based gun." icon = 'icons/obj/guns/energy.dmi' + recoil = 0.1 var/obj/item/stock_parts/cell/cell //What type of power cell this uses var/cell_type = /obj/item/stock_parts/cell @@ -44,12 +45,12 @@ cell.use(round(cell.charge * severity/100)) chambered = null //we empty the chamber recharge_newshot() //and try to charge a new shot - update_icon() + update_appearance() /obj/item/gun/energy/get_cell() return cell -/obj/item/gun/energy/Initialize() +/obj/item/gun/energy/Initialize(mapload) . = ..() if(cell_type) cell = new cell_type(src) @@ -61,7 +62,7 @@ recharge_newshot(TRUE) if(selfcharge) START_PROCESSING(SSobj, src) - update_icon() + update_appearance() /obj/item/gun/energy/ComponentInitialize() . = ..() @@ -74,7 +75,7 @@ /obj/item/gun/energy/handle_atom_del(atom/A) if(A == cell) cell = null - update_icon() + update_appearance() return ..() /obj/item/gun/energy/examine(mob/user) @@ -100,7 +101,7 @@ cell.give(100) if(!chambered) //if empty chamber we try to charge a new shot recharge_newshot(TRUE) - update_icon() + update_appearance() // ATTACK SELF IGNORING PARENT RETURN VALUE /obj/item/gun/energy/attack_self(mob/living/user) @@ -174,7 +175,7 @@ if(user_for_feedback) to_chat(user_for_feedback, "[src] is now set to [C.select_name || C].") post_set_firemode() - update_icon(TRUE) + update_appearance() /obj/item/gun/energy/proc/post_set_firemode(recharge_newshot = TRUE) if(recharge_newshot) diff --git a/code/modules/projectiles/guns/energy/dueling.dm b/code/modules/projectiles/guns/energy/dueling.dm index 04eff5afa9..b11e5533cc 100644 --- a/code/modules/projectiles/guns/energy/dueling.dm +++ b/code/modules/projectiles/guns/energy/dueling.dm @@ -168,7 +168,7 @@ /obj/item/gun/energy/dueling/hugbox/stamina hugbox = DUEL_HUGBOX_NONLETHAL -/obj/item/gun/energy/dueling/Initialize() +/obj/item/gun/energy/dueling/Initialize(mapload) . = ..() setting_overlay = mutable_appearance(icon,setting_iconstate()) add_overlay(setting_overlay) diff --git a/code/modules/projectiles/guns/energy/energy_gun.dm b/code/modules/projectiles/guns/energy/energy_gun.dm index 294040b040..a34e0f6f12 100644 --- a/code/modules/projectiles/guns/energy/energy_gun.dm +++ b/code/modules/projectiles/guns/energy/energy_gun.dm @@ -22,7 +22,7 @@ gunlight_state = "mini-light" can_flashlight = 0 // Can't attach or detach the flashlight, and override it's icon update -/obj/item/gun/energy/e_gun/mini/Initialize() +/obj/item/gun/energy/e_gun/mini/Initialize(mapload) gun_light = new /obj/item/flashlight/seclite(src) return ..() diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 1e6318ecba..5fd158c028 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -8,6 +8,7 @@ item_flags = NONE obj_flags = UNIQUE_RENAME weapon_weight = WEAPON_LIGHT + recoil = 0.5 can_flashlight = 1 flight_x_offset = 15 flight_y_offset = 9 @@ -42,7 +43,7 @@ icon_state = null damage = 50 damage_type = BRUTE - flag = "bomb" + flag = BOMB range = 4 log_override = TRUE @@ -125,7 +126,7 @@ holds_charge = TRUE unique_frequency = TRUE -/obj/item/gun/energy/kinetic_accelerator/Initialize() +/obj/item/gun/energy/kinetic_accelerator/Initialize(mapload) . = ..() if(!holds_charge) empty() @@ -220,7 +221,7 @@ icon_state = null damage = 40 damage_type = BRUTE - flag = "bomb" + flag = BOMB range = 3 log_override = TRUE @@ -232,17 +233,18 @@ kinetic_gun = null return ..() -/obj/item/projectile/kinetic/prehit(atom/target) +/obj/item/projectile/kinetic/prehit_pierce(atom/target) . = ..() - if(.) - if(kinetic_gun) - var/list/mods = kinetic_gun.get_modkits() - for(var/obj/item/borg/upgrade/modkit/M in mods) - M.projectile_prehit(src, target, kinetic_gun) - if(!lavaland_equipment_pressure_check(get_turf(target))) - name = "weakened [name]" - damage = damage * pressure_decrease - pressure_decrease_active = TRUE + if(. == PROJECTILE_PIERCE_PHASE) + return + if(kinetic_gun) + var/list/mods = kinetic_gun.modkits + for(var/obj/item/borg/upgrade/modkit/modkit in mods) + modkit.projectile_prehit(src, target, kinetic_gun) + if(!pressure_decrease_active && !lavaland_equipment_pressure_check(get_turf(target))) + name = "weakened [name]" + damage = damage * pressure_decrease + pressure_decrease_active = TRUE /obj/item/projectile/kinetic/on_range() strike_thing() @@ -278,6 +280,7 @@ w_class = WEIGHT_CLASS_SMALL require_module = 1 module_type = list(/obj/item/robot_module/miner) + module_flags = BORG_MODULE_MINER var/denied_type = null var/maximum_of_type = 1 var/cost = 30 diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 8e61221cc8..f73ac9cfb8 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -204,7 +204,7 @@ throwforce = 10 obj_flags = UNIQUE_RENAME -/obj/item/gun/energy/laser/redtag/hitscan/chaplain/Initialize() +/obj/item/gun/energy/laser/redtag/hitscan/chaplain/Initialize(mapload) . = ..() AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE) diff --git a/code/modules/projectiles/guns/energy/laser_gatling.dm b/code/modules/projectiles/guns/energy/laser_gatling.dm index a0274d76d7..65d525b638 100644 --- a/code/modules/projectiles/guns/energy/laser_gatling.dm +++ b/code/modules/projectiles/guns/energy/laser_gatling.dm @@ -17,7 +17,7 @@ var/overheat_max = 50 var/heat_diffusion = 1 -/obj/item/minigunpack/Initialize() +/obj/item/minigunpack/Initialize(mapload) . = ..() gun = new(src) START_PROCESSING(SSfastprocess, src) @@ -32,7 +32,7 @@ /obj/item/minigunpack/on_attack_hand(var/mob/living/carbon/user) if(src.loc == user) if(!armed) - if(user.get_item_by_slot(SLOT_BACK) == src) + if(user.get_item_by_slot(ITEM_SLOT_BACK) == src) armed = 1 if(!user.put_in_hands(gun)) armed = 0 @@ -101,8 +101,6 @@ slot_flags = null w_class = WEIGHT_CLASS_HUGE custom_materials = null - automatic = 0.5 - fire_delay = 2 ammo_type = list( /obj/item/ammo_casing/energy/laser ) @@ -114,7 +112,7 @@ item_flags = NEEDS_PERMIT | SLOWS_WHILE_IN_HAND var/obj/item/minigunpack/ammo_pack -/obj/item/gun/energy/minigun/Initialize() +/obj/item/gun/energy/minigun/Initialize(mapload) if(istype(loc, /obj/item/minigunpack)) //We should spawn inside an ammo pack so let's use that one. ammo_pack = loc else diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm index b05be99808..d5dc39695b 100644 --- a/code/modules/projectiles/guns/energy/pulse.dm +++ b/code/modules/projectiles/guns/energy/pulse.dm @@ -17,7 +17,7 @@ /obj/item/gun/energy/pulse/prize pin = /obj/item/firing_pin -/obj/item/gun/energy/pulse/prize/Initialize() +/obj/item/gun/energy/pulse/prize/Initialize(mapload) . = ..() GLOB.poi_list += src var/turf/T = get_turf(src) diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 15acd40172..67e7b58bd3 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -167,9 +167,15 @@ /obj/item/gun/energy/plasmacutter/use(amount) return cell.use(amount * 100) +/obj/item/gun/energy/plasmacutter/use_tool(atom/target, mob/living/user, delay, amount, volume, datum/callback/extra_checks, skill_gain_mult) + target.add_overlay(GLOB.welding_sparks) + . = ..() + target.cut_overlay(GLOB.welding_sparks) + /obj/item/gun/energy/plasmacutter/adv name = "advanced plasma cutter" icon_state = "adv_plasmacutter" + item_state = "adv_plasmacutter" force = 15 ammo_type = list(/obj/item/ammo_casing/energy/plasma/adv) diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm index ebc4a2f2a4..4192f038c2 100644 --- a/code/modules/projectiles/guns/magic.dm +++ b/code/modules/projectiles/guns/magic.dm @@ -49,7 +49,7 @@ charges--//... drain a charge recharge_newshot() -/obj/item/gun/magic/Initialize() +/obj/item/gun/magic/Initialize(mapload) . = ..() charges = max_charges chambered = new ammo_type(src) diff --git a/code/modules/projectiles/guns/magic/motivation.dm b/code/modules/projectiles/guns/magic/motivation.dm index 0eaeea4418..db4c222619 100644 --- a/code/modules/projectiles/guns/magic/motivation.dm +++ b/code/modules/projectiles/guns/magic/motivation.dm @@ -1,6 +1,6 @@ /obj/item/gun/magic/staff/motivation name = "Motivation" - desc = "Rumored to have the ability to open up a portal the depths of Lavaland." + desc = "Rumored to have the ability to open up a portal to the depths of Lavaland." icon = 'icons/obj/items_and_weapons.dmi' icon_state = "motivation" item_state = "motivation" @@ -21,15 +21,15 @@ recharge_rate = 5 var/datum/action/judgement_cut/judgementcut = new/datum/action/judgement_cut() block_parry_data = /datum/block_parry_data/motivation - + //to get this to toggle correctly -/obj/item/gun/magic/staff/motivation/Initialize() +/obj/item/gun/magic/staff/motivation/Initialize(mapload) . = ..() judgementcut = new(src) -//lets the user know that their judgment cuts are recharging +//lets the user know that their judgement cuts are recharging /obj/item/gun/magic/staff/motivation/shoot_with_empty_chamber(mob/living/user as mob|obj) - to_chat(user, "Judgment Cut is recharging.") + to_chat(user, "Judgement Cut is recharging.") //action button to toggle judgement cuts on/off /datum/action/judgement_cut @@ -47,7 +47,7 @@ /obj/item/gun/magic/staff/motivation/can_trigger_gun(mob/living/user) . = ..() if(!judgementcut.judgement_toggled) - to_chat(user, " Judgment Cut is disabled.") + to_chat(user, "Judgement Cut is disabled.") return FALSE //adds/removes judgement cut and judgement cut end upon pickup/drop diff --git a/code/modules/projectiles/guns/magic/spell_book.dm b/code/modules/projectiles/guns/magic/spell_book.dm index 752a6ae5ac..a2da6704a6 100644 --- a/code/modules/projectiles/guns/magic/spell_book.dm +++ b/code/modules/projectiles/guns/magic/spell_book.dm @@ -10,7 +10,7 @@ variable_charges = FALSE /obj/item/gun/magic/wand/book/zap_self(mob/living/user) - to_chat(user, "The book has [charges] pages\s remaining.
    ") + to_chat(user, "The book has [charges] page\s remaining.") /obj/item/gun/magic/wand/book/attackby(obj/item/S, mob/living/user, params) if(!istype(S, /obj/item/paper)) diff --git a/code/modules/projectiles/guns/magic/staff.dm b/code/modules/projectiles/guns/magic/staff.dm index 6ebdc5e7b8..f22cf6e1a9 100644 --- a/code/modules/projectiles/guns/magic/staff.dm +++ b/code/modules/projectiles/guns/magic/staff.dm @@ -86,7 +86,7 @@ sharpness = SHARP_EDGED max_charges = 4 -/obj/item/gun/magic/staff/spellblade/Initialize() +/obj/item/gun/magic/staff/spellblade/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 15, 125, 0, hitsound) diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm index f48020aeb5..8ff955fe66 100644 --- a/code/modules/projectiles/guns/magic/wand.dm +++ b/code/modules/projectiles/guns/magic/wand.dm @@ -9,7 +9,7 @@ max_charges = 100 //100, 50, 50, 34 (max charge distribution by 25%ths) var/variable_charges = 1 -/obj/item/gun/magic/wand/Initialize() +/obj/item/gun/magic/wand/Initialize(mapload) if(prob(75) && variable_charges) //25% chance of listed max charges, 50% chance of 1/2 max charges, 25% chance of 1/3 max charges if(prob(33)) max_charges = CEILING(max_charges / 3, 1) diff --git a/code/modules/projectiles/guns/misc/beam_rifle.dm b/code/modules/projectiles/guns/misc/beam_rifle.dm index 2ef974a450..6f70998834 100644 --- a/code/modules/projectiles/guns/misc/beam_rifle.dm +++ b/code/modules/projectiles/guns/misc/beam_rifle.dm @@ -169,7 +169,7 @@ to_chat(user, "You set \the [src] to [projectile_setting_pierce? "pierce":"impact"] mode.") aiming_beam() -/obj/item/gun/energy/beam_rifle/Initialize() +/obj/item/gun/energy/beam_rifle/Initialize(mapload) . = ..() fire_delay = delay current_tracers = list() @@ -408,7 +408,7 @@ hitsound = 'sound/effects/explosion3.ogg' damage = 0 //Handled manually. damage_type = BURN - flag = "energy" + flag = ENERGY range = 150 jitter = 10 var/obj/item/gun/energy/beam_rifle/gun @@ -427,11 +427,9 @@ var/aoe_mob_damage = 30 var/impact_structure_damage = 0 var/impact_direct_damage = 0 - var/turf/cached var/list/pierced = list() /obj/item/projectile/beam/beam_rifle/proc/AOE(turf/epicenter) - set waitfor = FALSE if(!epicenter) return new /obj/effect/temp_visual/explosion/fast(epicenter) @@ -445,33 +443,24 @@ if(!isitem(O)) if(O.level == 1) //Please don't break underfloor items! continue - O.take_damage(aoe_structure_damage * get_damage_coeff(O), BURN, "laser", FALSE) + O.take_damage(aoe_structure_damage * get_damage_coeff(O), BURN, LASER, FALSE) -/obj/item/projectile/beam/beam_rifle/proc/check_pierce(atom/target) - if(!do_pierce) - return FALSE - if(pierced[target]) //we already pierced them go away - return TRUE - if(isclosedturf(target)) - if(wall_pierce++ < wall_pierce_amount) - if(prob(wall_devastate)) - if(iswallturf(target)) - var/turf/closed/wall/W = target - W.dismantle_wall(TRUE, TRUE) - else - target.ex_act(EXPLODE_HEAVY) - return TRUE - if(ismovable(target)) - var/atom/movable/AM = target - if(AM.density && !AM.CanPass(src, get_turf(target)) && !ismob(AM)) - if(structure_pierce < structure_pierce_amount) - if(isobj(AM)) - var/obj/O = AM - O.take_damage((impact_structure_damage + aoe_structure_damage) * structure_bleed_coeff * get_damage_coeff(AM), BURN, "energy", FALSE) - pierced[AM] = TRUE - structure_pierce++ - return TRUE - return FALSE +/obj/item/projectile/beam/beam_rifle/prehit_pierce(atom/A) + if(isclosedturf(A) && (wall_pierce < wall_pierce_amount)) + if(prob(wall_devastate)) + if(iswallturf(A)) + var/turf/closed/wall/W = A + W.dismantle_wall(TRUE, TRUE) + else + A.ex_act(EXPLODE_HEAVY) + ++wall_pierce + return PROJECTILE_PIERCE_PHASE // yeah this gun is a snowflakey piece of garbage - Silly-Cons + if(isobj(A) && (structure_pierce < structure_pierce_amount)) + ++structure_pierce + var/obj/O = A + O.take_damage((impact_structure_damage + aoe_structure_damage) * structure_bleed_coeff * get_damage_coeff(A), BURN, "energy", FALSE) + return PROJECTILE_PIERCE_PHASE // ditto and this could be refactored to on_hit honestly - Silly-Cons + return ..() /obj/item/projectile/beam/beam_rifle/proc/get_damage_coeff(atom/target) if(istype(target, /obj/machinery/door)) @@ -485,38 +474,24 @@ /obj/item/projectile/beam/beam_rifle/proc/handle_impact(atom/target) if(isobj(target)) var/obj/O = target - O.take_damage(impact_structure_damage * get_damage_coeff(target), BURN, "laser", FALSE) + O.take_damage(impact_structure_damage * get_damage_coeff(target), BURN, LASER, FALSE) if(isliving(target)) var/mob/living/L = target L.adjustFireLoss(impact_direct_damage) L.emote("scream") -/obj/item/projectile/beam/beam_rifle/proc/handle_hit(atom/target) +/obj/item/projectile/beam/beam_rifle/proc/handle_hit(atom/target, piercing_hit = FALSE) set waitfor = FALSE - if(!cached && !QDELETED(target)) - cached = get_turf(target) if(nodamage) return FALSE - playsound(cached, 'sound/effects/explosion3.ogg', 100, 1) - AOE(cached) + playsound(src, 'sound/effects/explosion3.ogg', 100, TRUE) + if(!do_pierce) + AOE(get_turf(target) || get_turf(src)) if(!QDELETED(target)) handle_impact(target) -/obj/item/projectile/beam/beam_rifle/Bump(atom/target) - if(check_pierce(target)) - permutated += target - trajectory_ignore_forcemove = TRUE - forceMove(target.loc) - trajectory_ignore_forcemove = FALSE - return FALSE - if(!QDELETED(target)) - cached = get_turf(target) - . = ..() - -/obj/item/projectile/beam/beam_rifle/on_hit(atom/target, blocked = FALSE) - if(!QDELETED(target)) - cached = get_turf(target) - handle_hit(target) +/obj/item/projectile/beam/beam_rifle/on_hit(atom/target, blocked = FALSE, piercing_hit = FALSE) + handle_hit(target, piercing_hit) . = ..() /obj/item/projectile/beam/beam_rifle/hitscan @@ -547,6 +522,9 @@ hitscan_light_intensity = 0 hitscan_light_color_override = "#99ff99" -/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/prehit(atom/target) +/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/prehit_pierce(atom/target) + return PROJECTILE_DELETE_WITHOUT_HITTING + +/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/on_hit() qdel(src) - return FALSE + return BULLET_ACT_BLOCK diff --git a/code/modules/projectiles/guns/misc/blastcannon.dm b/code/modules/projectiles/guns/misc/blastcannon.dm index 60b7565333..a88f395561 100644 --- a/code/modules/projectiles/guns/misc/blastcannon.dm +++ b/code/modules/projectiles/guns/misc/blastcannon.dm @@ -26,7 +26,7 @@ debug_power = 80 bombcheck = FALSE -/obj/item/gun/blastcannon/Initialize() +/obj/item/gun/blastcannon/Initialize(mapload) . = ..() if(!pin) pin = new @@ -114,7 +114,8 @@ icon_state = "blastwave" damage = 0 nodamage = FALSE - movement_type = FLYING | UNSTOPPABLE + movement_type = FLYING + projectile_phasing = ALL // just blows up the turfs lmao - Silly-Cons var/heavyr = 0 var/mediumr = 0 var/lightr = 0 @@ -156,5 +157,5 @@ mediumr = max(mediumr - 1, 0) lightr = max(lightr - 1, 0) -/obj/item/projectile/blastwave/ex_act() +/obj/item/projectile/blastwave/ex_act(severity, target, origin) return diff --git a/code/modules/projectiles/guns/misc/chameleon.dm b/code/modules/projectiles/guns/misc/chameleon.dm index 4fa614ae5c..428de747f7 100644 --- a/code/modules/projectiles/guns/misc/chameleon.dm +++ b/code/modules/projectiles/guns/misc/chameleon.dm @@ -25,7 +25,7 @@ var/can_hitscan = FALSE var/hitscan_mode = FALSE -/obj/item/gun/energy/laser/chameleon/Initialize() +/obj/item/gun/energy/laser/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) chameleon_action.chameleon_type = /obj/item/gun diff --git a/code/modules/projectiles/guns/misc/chem_gun.dm b/code/modules/projectiles/guns/misc/chem_gun.dm index 779ab64bc2..9f0815ebfb 100644 --- a/code/modules/projectiles/guns/misc/chem_gun.dm +++ b/code/modules/projectiles/guns/misc/chem_gun.dm @@ -1,8 +1,8 @@ //his isn't a subtype of the syringe gun because the syringegun subtype is made to hold syringes //this is meant to hold reagents/obj/item/gun/syringe /obj/item/gun/chem - name = "reagent gun" - desc = "A Nanotrasen syringe gun, modified to automatically synthesise chemical darts, and instead hold reagents." + name = "Reagent Repeater" + desc = "A Nanotrasen smartdart repeater rifle, modified to automatically synthesize piercing darts." icon_state = "chemgun" item_state = "chemgun" w_class = WEIGHT_CLASS_NORMAL @@ -13,21 +13,79 @@ custom_materials = list(/datum/material/iron=2000) clumsy_check = FALSE fire_sound = 'sound/items/syringeproj.ogg' - var/time_per_syringe = 300 - var/syringes_left = 5 - var/max_syringes = 5 + var/time_per_syringe = 200 + var/syringes_left = 3 + var/max_syringes = 6 var/last_synth = 0 + var/obj/item/reagent_containers/glass/bottle/vial/vial + var/list/allowed_containers = list(/obj/item/reagent_containers/glass/bottle/vial/small, /obj/item/reagent_containers/glass/bottle/vial/large) + var/quickload = TRUE -/obj/item/gun/chem/Initialize() +/obj/item/gun/chem/Initialize(mapload) . = ..() chambered = new /obj/item/ammo_casing/chemgun(src) START_PROCESSING(SSobj, src) - create_reagents(100, OPENCONTAINER) /obj/item/gun/chem/Destroy() . = ..() STOP_PROCESSING(SSobj, src) +//bunch of hypospray copy paste +/obj/item/gun/chem/examine(mob/user) + . = ..() + if(vial) + . += "[vial] has [vial.reagents.total_volume]u remaining." + else + . += "It has no vial loaded in." + +/obj/item/gun/chem/proc/unload_hypo(obj/item/I, mob/user) + if((istype(I, /obj/item/reagent_containers/glass/bottle/vial))) + var/obj/item/reagent_containers/glass/bottle/vial/V = I + V.forceMove(user.loc) + user.put_in_hands(V) + to_chat(user, "You remove [vial] from [src].") + vial = null + update_icon() + playsound(loc, 'sound/weapons/empty.ogg', 50, 1) + else + to_chat(user, "The weapon isn't loaded!") + return + +/obj/item/gun/chem/attackby(obj/item/I, mob/living/user) + if((istype(I, /obj/item/reagent_containers/glass/bottle/vial))) + if(vial) + if(!quickload) + to_chat(user, "[src] can not hold more than one vial!") + return FALSE + unload_hypo(vial, user) + var/obj/item/reagent_containers/glass/bottle/vial/V = I + if(!is_type_in_list(V, allowed_containers)) + to_chat(user, "[src] doesn't accept this type of vial.") + return FALSE + if(!user.transferItemToLoc(V,src)) + return FALSE + vial = V + user.visible_message("[user] has loaded a vial into [src].","You have loaded [vial] into [src].") + update_icon() + playsound(loc, 'sound/weapons/autoguninsert.ogg', 35, 1) + return TRUE + else + to_chat(user, "This doesn't fit in [src].") + return FALSE + +/obj/item/gun/chem/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) + . = ..() //Don't bother changing this or removing it from containers will break. + +/obj/item/gun/chem/attack_self(mob/living/user) + if(user && !user.incapacitated()) + if(!vial) + to_chat(user, "This Hypo needs to be loaded first!") + else + unload_hypo(vial,user) + +/obj/item/gun/chem/attack(obj/item/I, mob/user, params) + return + /obj/item/gun/chem/can_shoot() return syringes_left @@ -45,3 +103,15 @@ if(chambered && !chambered.BB) chambered.newshot() last_synth = world.time + +//Smart dart version of the reagent launcher +/obj/item/gun/chem/smart + name = "Smartdart repeater rifle" + desc = "An experimental improved version of the smartdart rifle. It synthesizes medicinal smart darts which it fills using an inserted hypovial. It can accommodate both large and small hypovials." + icon_state = "chemgunrepeater" + item_state = "syringegun" + +obj/item/gun/chem/smart/Initialize(mapload) + . = ..() + chambered = new /obj/item/ammo_casing/chemgun/smart(src) + diff --git a/code/modules/projectiles/guns/misc/medbeam.dm b/code/modules/projectiles/guns/misc/medbeam.dm index 6864dad33e..4a64317fd9 100644 --- a/code/modules/projectiles/guns/misc/medbeam.dm +++ b/code/modules/projectiles/guns/misc/medbeam.dm @@ -16,7 +16,7 @@ weapon_weight = WEAPON_MEDIUM -/obj/item/gun/medbeam/Initialize() +/obj/item/gun/medbeam/Initialize(mapload) . = ..() START_PROCESSING(SSobj, src) @@ -130,6 +130,6 @@ /obj/item/gun/medbeam/mech mounted = 1 -/obj/item/gun/medbeam/mech/Initialize() +/obj/item/gun/medbeam/mech/Initialize(mapload) . = ..() STOP_PROCESSING(SSobj, src) //Mech mediguns do not process until installed, and are controlled by the holder obj diff --git a/code/modules/projectiles/guns/misc/syringe_gun.dm b/code/modules/projectiles/guns/misc/syringe_gun.dm index 39b7cbf540..8de7633a79 100644 --- a/code/modules/projectiles/guns/misc/syringe_gun.dm +++ b/code/modules/projectiles/guns/misc/syringe_gun.dm @@ -4,6 +4,7 @@ icon_state = "syringegun" item_state = "syringegun" w_class = WEIGHT_CLASS_NORMAL + recoil = 0.1 throw_speed = 3 throw_range = 7 force = 4 @@ -14,7 +15,7 @@ var/list/syringes = list() var/max_syringes = 1 -/obj/item/gun/syringe/Initialize() +/obj/item/gun/syringe/Initialize(mapload) . = ..() chambered = new /obj/item/ammo_casing/syringegun(src) @@ -83,7 +84,7 @@ name = "modified syringe gun" desc = "A syringe gun that has been modified to fit DNA injectors instead of normal syringes." -/obj/item/gun/syringe/dna/Initialize() +/obj/item/gun/syringe/dna/Initialize(mapload) . = ..() chambered = new /obj/item/ammo_casing/dnainjector(src) @@ -113,7 +114,7 @@ suppressed = TRUE //Softer fire sound can_unsuppress = FALSE -/obj/item/gun/syringe/dart/Initialize() +/obj/item/gun/syringe/dart/Initialize(mapload) . = ..() chambered = new /obj/item/ammo_casing/syringegun/dart(src) @@ -127,7 +128,7 @@ /obj/item/gun/syringe/dart/rapiddart name = "Repeating dart gun" icon_state = "rapiddartgun" - item_state = "rapiddartgun" + item_state = "syringegun" /obj/item/gun/syringe/dart/rapiddart/CheckParts(list/parts_list) var/obj/item/reagent_containers/glass/beaker/B = locate(/obj/item/reagent_containers/glass/beaker) in parts_list @@ -157,7 +158,7 @@ name = "blowgun" desc = "Fire syringes at a short distance." icon_state = "blowgun" - item_state = "blowgun" + item_state = "syringegun" fire_sound = 'sound/items/syringeproj.ogg' /obj/item/gun/syringe/blowgun/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0, stam_cost = 0) diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm index cef730366e..0f5e558841 100644 --- a/code/modules/projectiles/pins.dm +++ b/code/modules/projectiles/pins.dm @@ -13,7 +13,7 @@ var/pin_removeable = 0 // Can be replaced by any pin. var/obj/item/gun/gun -/obj/item/firing_pin/Initialize(newloc) +/obj/item/firing_pin/Initialize(mapload, newloc) . = ..() if(istype(newloc, /obj/item/gun)) gun = newloc @@ -238,7 +238,7 @@ var/only_lethals = FALSE var/can_toggle = TRUE -/obj/item/firing_pin/security_level/Initialize() +/obj/item/firing_pin/security_level/Initialize(mapload) . = ..() fail_message = "INVALID SECURITY LEVEL. CURRENT: [uppertext(NUM2SECLEVEL(GLOB.security_level))]. \ MIN: [uppertext(NUM2SECLEVEL(min_sec_level))]. MAX: [uppertext(NUM2SECLEVEL(max_sec_level))]. \ diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 0a7598cd79..0aee51bb84 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -13,9 +13,9 @@ density = FALSE anchored = TRUE item_flags = ABSTRACT - pass_flags = PASSTABLE mouse_opacity = MOUSE_OPACITY_TRANSPARENT movement_type = FLYING + generic_canpass = FALSE animate_movement = NO_STEPS hitsound = 'sound/weapons/pierce.ogg' appearance_flags = PIXEL_SCALE @@ -31,7 +31,6 @@ var/xo = null var/atom/original = null // the original target clicked var/turf/starting = null // the projectile's starting turf - var/list/permutated = list() // we've passed through these atoms, don't try to hit them again var/p_x = 16 var/p_y = 16 // the pixel location of the tile that the player clicked. Default is the center @@ -41,6 +40,37 @@ var/time_offset = 0 var/datum/point/vector/trajectory var/trajectory_ignore_forcemove = FALSE //instructs forceMove to NOT reset our trajectory to the new location! + /// We already impacted these things, do not impact them again. Used to make sure we can pierce things we want to pierce. Lazylist, typecache style (object = TRUE) for performance. + var/list/impacted + /// If TRUE, we can hit our firer. + var/ignore_source_check = FALSE + /// We are flagged PHASING temporarily to not stop moving when we Bump something but want to keep going anyways. + var/temporary_unstoppable_movement = FALSE + + /** PROJECTILE PIERCING + * WARNING: + * Projectile piercing MUST be done using these variables. + * Ordinary passflags will result in can_hit_target being false unless directly clicked on - similar to projectile_phasing but without even going to process_hit. + * The two flag variables below both use pass flags. + * In the context of LETPASStHROW, it means the projectile will ignore things that are currently "in the air" from a throw. + * + * Also, projectiles sense hits using Bump(), and then pierce them if necessary. + * They simply do not follow conventional movement rules. + * NEVER flag a projectile as PHASING movement type. + * If you so badly need to make one go through *everything*, override check_pierce() for your projectile to always return PROJECTILE_PIERCE_PHASE/HIT. + */ + /// The "usual" flags of pass_flags is used in that can_hit_target ignores these unless they're specifically targeted/clicked on. This behavior entirely bypasses process_hit if triggered, rather than phasing which uses prehit_pierce() to check. + pass_flags = PASSTABLE + /// If FALSE, allow us to hit something directly targeted/clicked/whatnot even if we're able to phase through it + var/phasing_ignore_direct_target = FALSE + /// Bitflag for things the projectile should just phase through entirely - No hitting unless direct target and [phasing_ignore_direct_target] is FALSE. Uses pass_flags flags. + var/projectile_phasing = NONE + /// Bitflag for things the projectile should hit, but pierce through without deleting itself. Defers to projectile_phasing. Uses pass_flags flags. + var/projectile_piercing = NONE + /// number of times we've pierced something. Incremented BEFORE bullet_act and on_hit proc! + var/pierces = 0 + /// If objects are below this layer, we pass through them + var/hit_threshhold = PROJECTILE_HIT_THRESHHOLD_LAYER /// "leftover" pixels for Range() calculation as pixel_move() was moved to simulated semi-pixel movement and Range() is in tiles. var/pixels_range_leftover = 0 /// "leftover" tick pixels and stuff yeah, so we don't round off things and introducing tracing inaccuracy. @@ -118,12 +148,10 @@ /// How many deciseconds are each hitscan movement considered. Used for homing and other things that use seconds for timing rather than ticks. var/hitscan_movement_decisecond_equivalency = 0.1 - var/ignore_source_check = FALSE - var/damage = 10 var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here var/nodamage = 0 //Determines if the projectile will skip any damage inflictions - var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb + var/flag = BULLET //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb var/projectile_type = /obj/item/projectile /// Range of the projectile, de-incrementing every step. The projectile deletes itself at 0. This is in tiles. var/range = 50 @@ -151,8 +179,6 @@ var/impact_effect_type //what type of impact effect to show when hitting something var/log_override = FALSE //is this type spammed enough to not log? (KAs) - var/temporary_unstoppable_movement = FALSE - ///If defined, on hit we create an item of this type then call hitby() on the hit target with this, mainly used for embedding items (bullets) in targets var/shrapnel_type ///If TRUE, hit mobs even if they're on the floor and not our target @@ -166,9 +192,8 @@ /// For telling whether we want to roll for bone breaking or lacerations if we're bothering with wounds sharpness = SHARP_NONE -/obj/item/projectile/Initialize() +/obj/item/projectile/Initialize(mapload) . = ..() - permutated = list() decayedRange = range if(embedding) updateEmbedding() @@ -202,10 +227,7 @@ else //when a limb is missing the damage is actually passed to the chest return BODY_ZONE_CHEST -/obj/item/projectile/proc/prehit(atom/target) - return TRUE - -/obj/item/projectile/proc/on_hit(atom/target, blocked = FALSE) +/obj/item/projectile/proc/on_hit(atom/target, blocked = FALSE, pierce_hit) if(fired_from) SEND_SIGNAL(fired_from, COMSIG_PROJECTILE_ON_HIT, firer, target, Angle) @@ -215,7 +237,7 @@ if(isliving(target)) var/mob/living/L = target hit_limb = L.check_limb_hit(def_zone) - SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle, hit_limb) + SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle, hit_limb, blocked) var/turf/target_loca = get_turf(target) var/hitx @@ -239,6 +261,11 @@ if(!isliving(target)) if(impact_effect_type && !hitscan) new impact_effect_type(target_loca, hitx, hity) + if(isturf(target) && hitsound_wall) + var/volume = clamp(vol_by_damage() + 20, 0, 100) + if(suppressed) + volume = 5 + playsound(loc, hitsound_wall, volume, TRUE, -1) return BULLET_ACT_HIT var/mob/living/L = target @@ -279,7 +306,7 @@ else if(hitsound) var/volume = vol_by_damage() - playsound(loc, hitsound, volume, 1, -1) + playsound(src, hitsound, volume, 1, -1) L.visible_message("[L] is hit by \a [src][organ_hit_text]!", \ "[L] is hit by \a [src][organ_hit_text]!", null, COMBAT_MESSAGE_RANGE) if(candink && def_zone == BODY_ZONE_HEAD) @@ -299,7 +326,7 @@ /obj/item/projectile/proc/vol_by_damage() if(src.damage) - return clamp((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then CLAMP the value between 30 and 100 + return clamp((src.damage) * 0.67, 30, 100) // Multiply projectile damage by 0.67, then CLAMP the value between 30 and 100 else return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume @@ -328,94 +355,274 @@ beam_segments[beam_index] = null /obj/item/projectile/Bump(atom/A) - if(!trajectory) + SEND_SIGNAL(src, COMSIG_MOVABLE_BUMP, A) + if(!can_hit_target(A, A == original, TRUE, TRUE)) return + Impact(A) + +/** + * Called when the projectile hits something + * This can either be from it bumping something, + * or it passing over a turf/being crossed and scanning that there is infact + * a valid target it needs to hit. + * This target isn't however necessarily WHAT it hits + * that is determined by process_hit and select_target. + * + * Furthermore, this proc shouldn't check can_hit_target - this should only be called if can hit target is already checked. + * Also, we select_target to find what to process_hit first. + */ +/obj/item/projectile/proc/Impact(atom/A) + if(!trajectory) + qdel(src) + return FALSE + if(impacted[A]) // NEVER doublehit - Silly-Cons + return FALSE + var/datum/point/pcache = trajectory.copy_to() var/turf/T = get_turf(A) if(check_ricochet_flag(A) && check_ricochet(A)) //if you can ricochet, attempt to ricochet off the object ricochets++ if(A.handle_ricochet(src)) on_ricochet(A) //if allowed, use autoaim to ricochet into someone, otherwise default to ricocheting off the object from above - var/datum/point/pcache = trajectory.copy_to() - if(hitscan) - store_hitscan_collision(pcache) + impacted = list() // Shoot a x-ray laser at a pair of mirrors I dare you + ignore_source_check = TRUE // Firer is no longer immune decayedRange = max(0, decayedRange - reflect_range_decrease) ricochet_chance *= ricochet_decay_chance damage *= ricochet_decay_damage range = decayedRange + if(hitscan) + store_hitscan_collision(pcache) return TRUE var/distance = get_dist(T, starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations. if(def_zone && check_zone(def_zone) != BODY_ZONE_CHEST) def_zone = ran_zone(def_zone, max(100-(7*distance), 5) * zone_accuracy_factor) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use. - if(isturf(A) && hitsound_wall) - var/volume = clamp(vol_by_damage() + 20, 0, 100) - if(suppressed) - volume = 5 - playsound(loc, hitsound_wall, volume, 1, -1) + return process_hit(T, select_target(T, A, A), A) // SELECT TARGET FIRST! - return process_hit(T, select_target(T, A)) - -#define QDEL_SELF 1 //Delete if we're not UNSTOPPABLE flagged non-temporarily -#define DO_NOT_QDEL 2 //Pass through. -#define FORCE_QDEL 3 //Force deletion. - -/obj/item/projectile/proc/process_hit(turf/T, atom/target, qdel_self, hit_something = FALSE) //probably needs to be reworked entirely when pixel movement is done. - if(QDELETED(src) || !T || !target) //We're done, nothing's left. - if((qdel_self == FORCE_QDEL) || ((qdel_self == QDEL_SELF) && !temporary_unstoppable_movement && !CHECK_BITFIELD(movement_type, UNSTOPPABLE))) - qdel(src) - return hit_something - permutated |= target //Make sure we're never hitting it again. If we ever run into weirdness with piercing projectiles needing to hit something multiple times.. well.. that's a to-do. - if(!prehit(target)) - return process_hit(T, select_target(T), qdel_self, hit_something) //Hit whatever else we can since that didn't work. - var/result = target.bullet_act(src, def_zone) - if(result == BULLET_ACT_FORCE_PIERCE) - if(!CHECK_BITFIELD(movement_type, UNSTOPPABLE)) - temporary_unstoppable_movement = TRUE - ENABLE_BITFIELD(movement_type, UNSTOPPABLE) - return process_hit(T, select_target(T), qdel_self, TRUE) //Hit whatever else we can since we're piercing through but we're still on the same tile. - else if(result == BULLET_ACT_TURF) //We hit the turf but instead we're going to also hit something else on it. - return process_hit(T, select_target(T), QDEL_SELF, TRUE) - else //Whether it hit or blocked, we're done! - qdel_self = QDEL_SELF - hit_something = TRUE - if((qdel_self == FORCE_QDEL) || ((qdel_self == QDEL_SELF) && !temporary_unstoppable_movement && !CHECK_BITFIELD(movement_type, UNSTOPPABLE))) +/** + * The primary workhorse proc of projectile impacts. + * This is a RECURSIVE call - process_hit is called on the first selected target, and then repeatedly called if the projectile still hasn't been deleted. + * + * Order of operations: + * 1. Checks if we are deleted, or if we're somehow trying to hit a null, in which case, bail out + * 2. Adds the thing we're hitting to impacted so we can make sure we don't doublehit + * 3. Checks piercing - stores this. + * Afterwards: + * Hit and delete, hit without deleting and pass through, pass through without hitting, or delete without hitting depending on result + * If we're going through without hitting, find something else to hit if possible and recurse, set unstoppable movement to true + * If we're deleting without hitting, delete and return + * Otherwise, send signal of COMSIG_PROJECTILE_PREHIT to target + * Then, hit, deleting ourselves if necessary. + * @params + * T - Turf we're on/supposedly hitting + * target - target we're hitting + * bumped - target we originally bumped. it's here to ensure that if something blocks our projectile by means of Cross() failure, we hit it + * even if it is not dense. + * hit_something - only should be set by recursive calling by this proc - tracks if we hit something already + * + * Returns if we hit something. + * - Silly-Cons + */ +/obj/item/projectile/proc/process_hit(turf/T, atom/target, atom/bumped, hit_something = FALSE) + // 1. + if(QDELETED(src) || !T || !target) + return + // 2. + impacted[target] = TRUE //hash lookup > in for performance in hit-checking + // 3. + var/mode = prehit_pierce(target) + if(mode == PROJECTILE_DELETE_WITHOUT_HITTING) qdel(src) + return hit_something + else if(mode == PROJECTILE_PIERCE_PHASE) + if(!(movement_type & PHASING)) + temporary_unstoppable_movement = TRUE + movement_type |= PHASING + return process_hit(T, select_target(T, target, bumped), bumped, hit_something) // try to hit something else + // at this point we are going to hit the thing + // in which case send signal to it + SEND_SIGNAL(target, COMSIG_PROJECTILE_PREHIT, args) + if(mode == PROJECTILE_PIERCE_HIT) + ++pierces + hit_something = TRUE + var/result = target.bullet_act(src, def_zone, mode == PROJECTILE_PIERCE_HIT) + if((result == BULLET_ACT_FORCE_PIERCE) || (mode == PROJECTILE_PIERCE_HIT)) + if(!(movement_type & PHASING)) + temporary_unstoppable_movement = TRUE + movement_type |= PHASING + return process_hit(T, select_target(T, target, bumped), bumped, TRUE) + qdel(src) return hit_something -#undef QDEL_SELF -#undef DO_NOT_QDEL -#undef FORCE_QDEL +/** + * Selects a target to hit from a turf + * + * @params + * T - The turf + * target - The "preferred" atom to hit, usually what we Bumped() first. + * bumped - used to track if something is the reason we impacted in the first place. + * If set, this atom is always treated as dense by can_hit_target. -/obj/item/projectile/proc/select_target(turf/T, atom/target) //Select a target from a turf. - if((original in T) && can_hit_target(original, permutated, TRUE, TRUE)) + * Priority: + * 0. Anything that is already in impacted is ignored no matter what. Furthermore, in any bracket, if the target atom parameter is in it, that's hit first. + * Furthermore, can_hit_target is always checked. This (entire proc) is PERFORMANCE OVERHEAD!! But, it shouldn't be ""too"" bad and I frankly don't have a better *generic non snowflakey* way that I can think of right now at 3 AM. + * FURTHERMORE, mobs/objs have a density check from can_hit_target - to hit non dense objects over a turf, you must click on them, same for mobs that usually wouldn't get hit. + * 1. The thing originally aimed at/clicked on + * 2. Mobs - picks lowest buckled mob to prevent scarp piggybacking memes + * 3. Objs + * 4. Turf + * 5. Nothing + */ +/obj/item/projectile/proc/select_target(turf/T, atom/target, atom/bumped) + // 1. original + if(can_hit_target(original, TRUE, FALSE, original == bumped)) return original - if(target && can_hit_target(target, permutated, target == original, TRUE)) - return target - var/list/mob/living/possible_mobs = typecache_filter_list(T, GLOB.typecache_mob) - var/list/mob/mobs = list() - for(var/mob/living/M in possible_mobs) - if(!can_hit_target(M, permutated, M == original, TRUE)) + var/list/atom/possible = list() // let's define these ONCE + var/list/atom/considering = list() + // 2. mobs + possible = typecache_filter_list(T, GLOB.typecache_living) // living only + for(var/i in possible) + if(!can_hit_target(i, i == original, TRUE, i == bumped)) continue - mobs += M - var/mob/M = safepick(mobs) - if(M) + considering += i + if(considering.len) + var/mob/living/M = pick(considering) return M.lowest_buckled_mob() - var/list/obj/possible_objs = typecache_filter_list(T, GLOB.typecache_machine_or_structure) - var/list/obj/objs = list() - for(var/obj/O in possible_objs) - if(!can_hit_target(O, permutated, O == original, TRUE)) + considering.len = 0 + // 3. objs and other dense things + for(var/i in T.contents) + if(!can_hit_target(i, i == original, TRUE, i == bumped)) continue - objs += O - var/obj/O = safepick(objs) - if(O) - if(length(O.buckled_mobs)) - return pick(O.buckled_mobs) - return O - //Nothing else is here that we can hit, hit the turf if we haven't. - if(!(T in permutated) && can_hit_target(T, permutated, T == original, TRUE)) + considering += i + if(considering.len) + return pick(considering) + // 4. turf + if(can_hit_target(T, T == original, TRUE, T == bumped)) return T - //Returns null if nothing at all was found. + // 5. nothing + // (returns null) + +//Returns true if the target atom is on our current turf and above the right layer +//If direct target is true it's the originally clicked target. +/obj/item/projectile/proc/can_hit_target(atom/target, direct_target = FALSE, ignore_loc = FALSE,cross_failed = FALSE) + if(QDELETED(target) || impacted[target]) + return FALSE + if(!ignore_loc && (loc != target.loc)) + return FALSE + // if pass_flags match, pass through entirely - unless direct target is set. + if((target.pass_flags_self & pass_flags) && !direct_target) + return FALSE + if(!ignore_source_check && firer) + var/mob/M = firer + if((target == firer) || ((target == firer.loc) && ismecha(firer.loc)) || (target in firer.buckled_mobs) || (istype(M) && (M.buckled == target))) + return FALSE + if(target.density || cross_failed) //This thing blocks projectiles, hit it regardless of layer/mob stuns/etc. + return TRUE + if(!isliving(target)) + if(isturf(target)) // non dense turfs + return FALSE + if(target.layer < hit_threshhold) + return FALSE + else if(!direct_target) // non dense objects do not get hit unless specifically clicked + return FALSE + else + var/mob/living/L = target + if(direct_target) + return TRUE + // If target not able to use items, move and stand - or if they're just dead, pass over. + if(L.stat == DEAD) + return FALSE + if(!L.density) + return FALSE + if(L.resting) + return TRUE + var/stunned = HAS_TRAIT(L, TRAIT_MOBILITY_NOMOVE) && HAS_TRAIT(L, TRAIT_MOBILITY_NOREST) && HAS_TRAIT(L, TRAIT_MOBILITY_NOPICKUP) + return !stunned || hit_stunned_targets + return TRUE + +/** + * Scan if we should hit something and hit it if we need to + * The difference between this and handling in Impact is + * In this we strictly check if we need to Impact() something in specific + * If we do, we do + * We don't even check if it got hit already - Impact() does that + * In impact there's more code for selecting WHAT to hit + * So this proc is more of checking if we should hit something at all BY having an atom cross us. + */ +/obj/item/projectile/proc/scan_crossed_hit(atom/movable/A) + if(can_hit_target(A, direct_target = (A == original))) + Impact(A) + +/** + * Scans if we should hit something on the turf we just moved to if we haven't already + * + * This proc is a little high in overhead but allows us to not snowflake CanPass in living and other things. + */ +/obj/item/projectile/proc/scan_moved_turf() + // Optimally, we scan: mobs --> objs --> turf for impact + // but, overhead is a thing and 2 for loops every time it moves is a no-go. + // realistically, since we already do select_target in impact, we can not do that + // and hope projectiles get refactored again in the future to have a less stupid impact detection system + // that hopefully won't also involve a ton of overhead + if(can_hit_target(original, TRUE, FALSE)) + Impact(original) // try to hit thing clicked on + // else, try to hit mobs + else // because if we impacted original and pierced we'll already have select target'd and hit everything else we should be hitting + for(var/mob/M in loc) // so I guess we're STILL doing a for loop of mobs because living movement would otherwise have snowflake code for projectile CanPass + // so the snowflake vs performance is pretty arguable here + if(can_hit_target(M, M == original, TRUE)) + Impact(M) + break + +/** + * Projectile crossed: When something enters a projectile's tile, make sure the projectile hits it if it should be hitting it. + */ +/obj/item/projectile/Crossed(atom/movable/AM) + . = ..() + scan_crossed_hit(AM) + +/** + * Projectile can pass through + * Used to not even attempt to Bump() or fail to Cross() anything we already hit. + */ +/obj/item/projectile/CanPassThrough(atom/blocker, turf/target, blocker_opinion) + return impacted[blocker]? TRUE : ..() + +/** + * Projectile moved: + * + * If not fired yet, do not do anything. Else, + * + * If temporary unstoppable movement used for piercing through things we already hit (impacted list) is set, unset it. + * Scan turf we're now in for anything we can/should hit. This is useful for hitting non dense objects the user + * directly clicks on, as well as for PHASING projectiles to be able to hit things at all as they don't ever Bump(). + */ +/obj/item/projectile/Moved(atom/OldLoc, Dir) + . = ..() + if(!fired) + return + if(temporary_unstoppable_movement) + temporary_unstoppable_movement = FALSE + movement_type &= ~PHASING + scan_moved_turf() //mostly used for making sure we can hit a non-dense object the user directly clicked on, and for penetrating projectiles that don't bump + +/** + * Checks if we should pierce something. + * + * NOT meant to be a pure proc, since this replaces prehit() which was used to do things. + * Return PROJECTILE_DELETE_WITHOUT_HITTING to delete projectile without hitting at all! + */ + +/obj/item/projectile/proc/prehit_pierce(atom/A) + if((projectile_phasing & A.pass_flags_self) && (phasing_ignore_direct_target || original != A)) + return PROJECTILE_PIERCE_PHASE + if(projectile_piercing & A.pass_flags_self) + return PROJECTILE_PIERCE_HIT + if(ismovable(A)) + var/atom/movable/AM = A + if(AM.throwing) + return (projectile_phasing & LETPASSTHROW)? PROJECTILE_PIERCE_PHASE : ((projectile_piercing & LETPASSTHROW)? PROJECTILE_PIERCE_HIT : PROJECTILE_PIERCE_NONE) + return PROJECTILE_PIERCE_NONE /obj/item/projectile/proc/check_ricochet(atom/A) if(ricochets > ricochets_max) //safety thing, we don't care about what the other thing says about this. @@ -438,9 +645,9 @@ CRASH("Invalid return value for projectile ricochet check from [A].") /obj/item/projectile/proc/check_ricochet_flag(atom/A) - if((flag in list("energy", "laser")) && (A.flags_ricochet & RICOCHET_SHINY)) + if((flag in list(ENERGY, LASER)) && (A.flags_ricochet & RICOCHET_SHINY)) return TRUE - if((flag in list("bomb", "bullet")) && (A.flags_ricochet & RICOCHET_HARD)) + if((flag in list(BOMB, BULLET)) && (A.flags_ricochet & RICOCHET_HARD)) return TRUE return FALSE @@ -479,16 +686,16 @@ pixels_tick_leftover = required_pixels /obj/item/projectile/proc/fire(angle, atom/direct_target) + LAZYINITLIST(impacted) if(fired_from) SEND_SIGNAL(fired_from, COMSIG_PROJECTILE_BEFORE_FIRE, src, original) //If no angle needs to resolve it from xo/yo! if(shrapnel_type) AddElement(/datum/element/embed, projectile_payload = shrapnel_type) if(!log_override && firer && original) log_combat(firer, original, "fired at", src, "from [get_area_name(src, TRUE)]") - if(direct_target) - if(prehit(direct_target)) - direct_target.bullet_act(src, def_zone) - qdel(src) + if(direct_target && (get_dist(direct_target, get_turf(src)) <= 1)) // point blank shots + process_hit(get_turf(direct_target), direct_target) + if(QDELETED(src)) return if(isnum(angle)) setAngle(angle) @@ -545,6 +752,8 @@ if(zc) before_z_change(old, target) . = ..() + if(QDELETED(src)) // we coulda bumped something + return if(trajectory && !trajectory_ignore_forcemove && isturf(target)) if(hitscan) finalize_hitscan_and_generate_tracers(FALSE) @@ -679,30 +888,6 @@ if(prob(50)) homing_offset_y = -homing_offset_y -//Returns true if the target atom is on our current turf and above the right layer -//If direct target is true it's the originally clicked target. -/obj/item/projectile/proc/can_hit_target(atom/target, list/passthrough, direct_target = FALSE, ignore_loc = FALSE) - if(QDELETED(target)) - return FALSE - if(!ignore_source_check && firer) - var/mob/M = firer - if((target == firer) || ((target == firer.loc) && ismecha(firer.loc)) || (target in firer.buckled_mobs) || (istype(M) && (M.buckled == target))) - if(!ricochets) //if it has ricocheted, it can hit the firer. - return FALSE - if(!ignore_loc && (loc != target.loc)) - return FALSE - if(target in passthrough) - return FALSE - if(target.density) //This thing blocks projectiles, hit it regardless of layer/mob stuns/etc. - return TRUE - if(!isliving(target)) - if(target.layer < PROJECTILE_HIT_THRESHHOLD_LAYER) - return FALSE - else - var/mob/living/L = target - if(!direct_target && !L.density) - return FALSE - return TRUE //Spread is FORCED! /obj/item/projectile/proc/preparePixelProjectile(atom/target, atom/source, params, spread = 0) @@ -763,22 +948,6 @@ angle = arctan(y - oy, x - ox) return list(angle, p_x, p_y) -/obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a projectile is hit by it. - . = ..() - if(isliving(AM) && !(pass_flags & PASSMOB)) - var/mob/living/L = AM - if(can_hit_target(L, permutated, (AM == original))) - Bump(AM) - -/obj/item/projectile/Move(atom/newloc, dir = NONE) - . = ..() - if(.) - if(temporary_unstoppable_movement) - temporary_unstoppable_movement = FALSE - DISABLE_BITFIELD(movement_type, UNSTOPPABLE) - if(fired && can_hit_target(original, permutated, TRUE)) - Bump(original) - /obj/item/projectile/Destroy() STOP_PROCESSING(SSprojectiles, src) if(hitscan) diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 79e9ab8b4b..69ad106b96 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -7,7 +7,7 @@ damage_type = BURN hitsound = 'sound/weapons/sear.ogg' hitsound_wall = 'sound/weapons/effects/searwall.ogg' - flag = "laser" + flag = LASER eyeblur = 2 impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser light_color = LIGHT_COLOR_RED @@ -30,7 +30,7 @@ wound_bonus = 0 damage = 25 -/obj/item/projectile/beam/laser/hellfire/Initialize() +/obj/item/projectile/beam/laser/hellfire/Initialize(mapload) . = ..() transform *= 2 @@ -72,7 +72,7 @@ damage = 15 irradiate = 100 range = 15 - pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE | PASSCLOSEDTURF + pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE | PASSCLOSEDTURF | PASSMACHINE | PASSSTRUCTURE impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser light_color = LIGHT_COLOR_GREEN @@ -85,7 +85,7 @@ icon_state = "omnilaser" damage = 28 // Citadel change for balance from 36 damage_type = STAMINA - flag = "energy" + flag = ENERGY hitsound = 'sound/weapons/tap.ogg' eyeblur = 0 pixels_per_second = TILES_TO_PIXELS(16.667) @@ -150,7 +150,7 @@ hitsound = null damage = 0 damage_type = STAMINA - flag = "laser" + flag = LASER var/suit_types = list(/obj/item/clothing/suit/redtag, /obj/item/clothing/suit/bluetag) impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser light_color = LIGHT_COLOR_BLUE @@ -166,7 +166,7 @@ /obj/item/projectile/beam/lasertag/mag //the projectile, compatible with regular laser tag armor icon_state = "magjectile-toy" name = "lasertag magbolt" - movement_type = FLYING | UNSTOPPABLE //for penetration memes + movement_type = FLYING | PHASING //for penetration memes range = 5 //so it isn't super annoying light_range = 2 light_color = LIGHT_COLOR_YELLOW @@ -231,7 +231,7 @@ hitsound = 'sound/weapons/shrink_hit.ogg' damage = 0 damage_type = STAMINA - flag = "energy" + flag = ENERGY impact_effect_type = /obj/effect/temp_visual/impact_effect/shrink light_color = LIGHT_COLOR_BLUE var/shrink_time = 90 diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index b408957aa7..5b488f629f 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -5,7 +5,7 @@ damage_type = BRUTE nodamage = FALSE candink = TRUE - flag = "bullet" + flag = BULLET hitsound_wall = "ricochet" impact_effect_type = /obj/effect/temp_visual/impact_effect sharpness = SHARP_POINTY diff --git a/code/modules/projectiles/projectile/bullets/dart_syringe.dm b/code/modules/projectiles/projectile/bullets/dart_syringe.dm index bc2a7c40fb..3b7e86e77c 100644 --- a/code/modules/projectiles/projectile/bullets/dart_syringe.dm +++ b/code/modules/projectiles/projectile/bullets/dart_syringe.dm @@ -4,7 +4,7 @@ damage = 6 var/piercing = FALSE -/obj/item/projectile/bullet/dart/Initialize() +/obj/item/projectile/bullet/dart/Initialize(mapload) . = ..() create_reagents(50, NO_REACT, NO_REAGENTS_VALUE) @@ -25,20 +25,20 @@ "You were protected against \the [src]!") ..(target, blocked) - DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) + reagents.reagents_holder_flags &= ~(NO_REACT) reagents.handle_reactions() return BULLET_ACT_HIT /obj/item/projectile/bullet/dart/piercing piercing = TRUE -/obj/item/projectile/bullet/dart/metalfoam/Initialize() +/obj/item/projectile/bullet/dart/metalfoam/Initialize(mapload) . = ..() reagents.add_reagent(/datum/reagent/aluminium, 15) reagents.add_reagent(/datum/reagent/foaming_agent, 5) reagents.add_reagent(/datum/reagent/toxin/acid, 5) -/obj/item/projectile/bullet/dart/catranq/Initialize() +/obj/item/projectile/bullet/dart/catranq/Initialize(mapload) . = ..() reagents.add_reagent(/datum/reagent/fermi/furranium, 5) // Turns out I don't even need to give this guy actual tranquilizer chems. @@ -60,6 +60,8 @@ if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body. ..(target, blocked, TRUE) for(var/datum/reagent/medicine/R in reagents.reagent_list) //OD prevention time! + if(R.type in GLOB.blacklisted_medchems) + continue if(M.reagents.has_reagent(R.type)) if(R.overdose_threshold == 0 || emptrig == TRUE) //Is there a possible OD? M.reagents.add_reagent(R.type, R.volume) diff --git a/code/modules/projectiles/projectile/bullets/ferromagnetic.dm b/code/modules/projectiles/projectile/bullets/ferromagnetic.dm index 03482e2a9d..1ba6ba7b79 100644 --- a/code/modules/projectiles/projectile/bullets/ferromagnetic.dm +++ b/code/modules/projectiles/projectile/bullets/ferromagnetic.dm @@ -28,7 +28,7 @@ damage = 10 armour_penetration = 20 stamina = 10 - movement_type = FLYING | UNSTOPPABLE + movement_type = FLYING | PHASING range = 6 fired_light_range = 1 fired_light_color = LIGHT_COLOR_RED @@ -37,7 +37,7 @@ icon_state = "magjectile-large" damage = 10 armour_penetration = 20 - movement_type = FLYING | UNSTOPPABLE + movement_type = FLYING | PHASING range = 20 pixels_per_second = TILES_TO_PIXELS(12.5) fired_light_range = 4 diff --git a/code/modules/projectiles/projectile/bullets/lmg.dm b/code/modules/projectiles/projectile/bullets/lmg.dm index e3eff6dcb0..177a98201c 100644 --- a/code/modules/projectiles/projectile/bullets/lmg.dm +++ b/code/modules/projectiles/projectile/bullets/lmg.dm @@ -21,22 +21,22 @@ /obj/item/projectile/bullet/syndicate_turret damage = 20 -// 1.95x129mm (SAW) +// 7.12x82mm (SAW) -/obj/item/projectile/bullet/mm195x129 - name = "1.95x129mm bullet" +/obj/item/projectile/bullet/mm712x82 + name = "7.12x82mm bullet" damage = 40 armour_penetration = 5 wound_bonus = -50 wound_falloff_tile = 0 -/obj/item/projectile/bullet/mm195x129_ap - name = "1.95x129mm armor-piercing bullet" +/obj/item/projectile/bullet/mm712x82_ap + name = "7.12x82mm armor-piercing bullet" damage = 40 armour_penetration = 75 -/obj/item/projectile/bullet/mm195x129_hp - name = "1.95x129mm hollow-point bullet" +/obj/item/projectile/bullet/mm712x82_hp + name = "7.12x82mm hollow-point bullet" damage = 50 armour_penetration = -60 sharpness = SHARP_EDGED @@ -44,7 +44,15 @@ bare_wound_bonus = 30 wound_falloff_tile = -8 -/obj/item/projectile/bullet/incendiary/mm195x129 - name = "1.95x129mm incendiary bullet" +/obj/item/projectile/bullet/incendiary/mm712x82 + name = "7.12x82mm incendiary bullet" damage = 20 fire_stacks = 3 + +/obj/item/projectile/bullet/mm712x82/match + name = "7.12x82mm match bullet" + damage = 40 + ricochets_max = 2 + ricochet_chance = 60 + ricochet_auto_aim_range = 4 + ricochet_incidence_leeway = 35 diff --git a/code/modules/projectiles/projectile/bullets/shotgun.dm b/code/modules/projectiles/projectile/bullets/shotgun.dm index 9670907ec3..cdee721509 100644 --- a/code/modules/projectiles/projectile/bullets/shotgun.dm +++ b/code/modules/projectiles/projectile/bullets/shotgun.dm @@ -71,7 +71,7 @@ var/atom/throw_target = get_edge_target_turf(M, get_dir(src, get_step_away(M, src))) M.safe_throw_at(throw_target, 3, 2) -/obj/item/projectile/bullet/shotgun_meteorslug/Initialize() +/obj/item/projectile/bullet/shotgun_meteorslug/Initialize(mapload) . = ..() SpinAnimation() @@ -118,7 +118,7 @@ wound_bonus = 0 bare_wound_bonus = 7.5 -/obj/item/projectile/bullet/pellet/shotgun_improvised/Initialize() +/obj/item/projectile/bullet/pellet/shotgun_improvised/Initialize(mapload) . = ..() range = rand(1, 8) diff --git a/code/modules/projectiles/projectile/bullets/sniper.dm b/code/modules/projectiles/projectile/bullets/sniper.dm index f69b62a149..abf4537de2 100644 --- a/code/modules/projectiles/projectile/bullets/sniper.dm +++ b/code/modules/projectiles/projectile/bullets/sniper.dm @@ -13,7 +13,7 @@ /obj/item/projectile/bullet/p50/on_hit(atom/target, blocked = 0) if(isobj(target) && (blocked != 100) && breakthings) var/obj/O = target - O.take_damage(80, BRUTE, "bullet", FALSE) + O.take_damage(80, BRUTE, BULLET, FALSE) return ..() /obj/item/projectile/bullet/p50/soporific @@ -35,7 +35,8 @@ icon_state = "gauss" name = "penetrator round" damage = 60 - movement_type = FLYING | UNSTOPPABLE + projectile_piercing = PASSMOB + projectile_phasing = (ALL & (~PASSMOB)) dismemberment = 0 //It goes through you cleanly. knockdown = 0 breakthings = FALSE diff --git a/code/modules/projectiles/projectile/bullets/special.dm b/code/modules/projectiles/projectile/bullets/special.dm index a0414d8a9c..7fd73e18b9 100644 --- a/code/modules/projectiles/projectile/bullets/special.dm +++ b/code/modules/projectiles/projectile/bullets/special.dm @@ -3,7 +3,8 @@ /obj/item/projectile/bullet/honker damage = 0 knockdown = 60 - movement_type = FLYING | UNSTOPPABLE + movement_type = FLYING + projectile_piercing = ALL nodamage = TRUE candink = FALSE hitsound = 'sound/items/bikehorn.ogg' @@ -11,7 +12,7 @@ icon_state = "banana" range = 200 -/obj/item/projectile/bullet/honker/Initialize() +/obj/item/projectile/bullet/honker/Initialize(mapload) . = ..() SpinAnimation() diff --git a/code/modules/projectiles/projectile/energy/_energy.dm b/code/modules/projectiles/projectile/energy/_energy.dm index ec80ae1e74..9a803af46c 100644 --- a/code/modules/projectiles/projectile/energy/_energy.dm +++ b/code/modules/projectiles/projectile/energy/_energy.dm @@ -3,6 +3,6 @@ icon_state = "spark" damage = 0 damage_type = BURN - flag = "energy" + flag = ENERGY is_reflectable = TRUE diff --git a/code/modules/projectiles/projectile/energy/net_snare.dm b/code/modules/projectiles/projectile/energy/net_snare.dm index 22eaadb1e0..7ecf48cf6a 100644 --- a/code/modules/projectiles/projectile/energy/net_snare.dm +++ b/code/modules/projectiles/projectile/energy/net_snare.dm @@ -6,7 +6,7 @@ hitsound = 'sound/weapons/taserhit.ogg' range = 10 -/obj/item/projectile/energy/net/Initialize() +/obj/item/projectile/energy/net/Initialize(mapload) . = ..() SpinAnimation() @@ -29,7 +29,7 @@ light_range = 3 anchored = TRUE -/obj/effect/nettingportal/Initialize() +/obj/effect/nettingportal/Initialize(mapload) . = ..() var/obj/item/beacon/teletarget = null for(var/obj/machinery/computer/teleporter/com in GLOB.machines) diff --git a/code/modules/projectiles/projectile/energy/nuclear_particle.dm b/code/modules/projectiles/projectile/energy/nuclear_particle.dm index 6cbe258560..77f013ebba 100644 --- a/code/modules/projectiles/projectile/energy/nuclear_particle.dm +++ b/code/modules/projectiles/projectile/energy/nuclear_particle.dm @@ -17,7 +17,7 @@ "purple" = "#FF00FF" ) -/obj/item/projectile/energy/nuclear_particle/Initialize() +/obj/item/projectile/energy/nuclear_particle/Initialize(mapload) . = ..() //Random color time! var/our_color = pick(particle_colors) diff --git a/code/modules/projectiles/projectile/energy/tesla.dm b/code/modules/projectiles/projectile/energy/tesla.dm index 1afbdeae25..d88e217722 100644 --- a/code/modules/projectiles/projectile/energy/tesla.dm +++ b/code/modules/projectiles/projectile/energy/tesla.dm @@ -28,3 +28,7 @@ /obj/item/projectile/energy/tesla/cannon name = "tesla orb" power = 20000 + +/obj/item/projectile/energy/tesla/sphere + name = "tesla sphere" + power = 100000 diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index c9ca4e9ba3..2959666a4c 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -5,7 +5,7 @@ damage_type = OXY nodamage = 1 armour_penetration = 100 - flag = "magic" + flag = MAGIC /obj/item/projectile/magic/death name = "bolt of death" @@ -37,7 +37,8 @@ return BULLET_ACT_BLOCK if(iscarbon(target)) var/mob/living/carbon/C = target - C.regenerate_limbs() + if(HAS_TRAIT(C, TRAIT_DULLAHAN)) //No accidental instagibbing dullahans please + C.regenerate_limbs() C.regenerate_organs() if(target.revive(full_heal = 1)) target.grab_ghost(force = TRUE) // even suicides @@ -301,7 +302,7 @@ icon_state = "lavastaff" damage = 15 damage_type = BURN - flag = "magic" + flag = MAGIC dismemberment = 50 nodamage = 0 @@ -321,7 +322,7 @@ damage_type = BURN nodamage = 0 armour_penetration = 0 - flag = "magic" + flag = MAGIC hitsound = 'sound/weapons/barragespellhit.ogg' /obj/item/projectile/magic/arcane_barrage/on_hit(target) @@ -338,23 +339,22 @@ name = "locker bolt" icon_state = "locker" nodamage = TRUE - flag = "magic" + flag = MAGIC var/weld = TRUE var/created = FALSE //prevents creation of more then one locker if it has multiple hits var/locker_suck = TRUE -/obj/item/projectile/magic/locker/prehit(atom/A) +/obj/item/projectile/magic/locker/prehit_pierce(atom/A) + . = ..() if(ismob(A) && locker_suck) var/mob/M = A - if(M.anti_magic_check()) + if(M.anti_magic_check()) // no this doesn't check if ..() returned to phase through do I care no it's magic ain't gotta explain shit - Silly-Cons M.visible_message("[src] vanishes on contact with [A]!") - qdel(src) - return + return PROJECTILE_DELETE_WITHOUT_HITTING if(M.anchored) - return ..() + return M.forceMove(src) - return FALSE - return ..() + return PROJECTILE_PIERCE_PHASE /obj/item/projectile/magic/locker/on_hit(target) if(created) @@ -381,7 +381,7 @@ var/weakened_icon = "decursed" var/auto_destroy = TRUE -/obj/structure/closet/decay/Initialize() +/obj/structure/closet/decay/Initialize(mapload) . = ..() if(auto_destroy) addtimer(CALLBACK(src, .proc/bust_open), 5 MINUTES) @@ -436,7 +436,7 @@ damage_type = BURN nodamage = 0 pixels_per_second = TILES_TO_PIXELS(33.33) - flag = "magic" + flag = MAGIC var/zap_power = 20000 var/zap_range = 15 diff --git a/code/modules/projectiles/projectile/magic/spellcard.dm b/code/modules/projectiles/projectile/magic/spellcard.dm index 5015a97e78..efd3373dd9 100644 --- a/code/modules/projectiles/projectile/magic/spellcard.dm +++ b/code/modules/projectiles/projectile/magic/spellcard.dm @@ -12,7 +12,7 @@ icon_state = "spellcard" damage_type = BURN damage = 12 - flag = "magic" + flag = MAGIC /obj/item/projectile/magic/spellcard/book/spark damage = 4 @@ -25,7 +25,7 @@ if(M.anti_magic_check()) M.visible_message("[src] vanishes on contact with [target]!") return BULLET_ACT_BLOCK - + if(iscarbon(target)) M.adjust_fire_stacks(fire_stacks) M.IgniteMob() diff --git a/code/modules/projectiles/projectile/plasma.dm b/code/modules/projectiles/projectile/plasma.dm index 474a3d95c7..649de58742 100644 --- a/code/modules/projectiles/projectile/plasma.dm +++ b/code/modules/projectiles/projectile/plasma.dm @@ -1,7 +1,7 @@ /obj/item/projectile/energy/plasmabolt name = "plasma bolt" icon_state = "plasma" - flag = "energy" + flag = ENERGY damage_type = BURN hitsound = 'sound/weapons/sear.ogg' hitsound_wall = 'sound/weapons/effects/searwall.ogg' diff --git a/code/modules/projectiles/projectile/special/curse.dm b/code/modules/projectiles/projectile/special/curse.dm index d967540e6a..89b1ecba4c 100644 --- a/code/modules/projectiles/projectile/special/curse.dm +++ b/code/modules/projectiles/projectile/special/curse.dm @@ -12,7 +12,6 @@ knockdown = 20 pixels_per_second = TILES_TO_PIXELS(5) range = 16 - movement_type = FLYING | UNSTOPPABLE var/datum/beam/arm var/handedness = 0 @@ -29,18 +28,14 @@ arm = starting.Beam(src, icon_state = "curse[handedness]", time = INFINITY, maxdistance = INFINITY, beam_type=/obj/effect/ebeam/curse_arm) ..() -/obj/item/projectile/curse_hand/prehit(atom/target) - if(target == original) - DISABLE_BITFIELD(movement_type, UNSTOPPABLE) - else if(!isturf(target)) - return FALSE - return ..() +/obj/item/projectile/curse_hand/prehit_pierce(atom/target) + return (target == original)? PROJECTILE_PIERCE_NONE : PROJECTILE_PIERCE_PHASE /obj/item/projectile/curse_hand/Destroy() if(arm) arm.End() arm = null - if(CHECK_BITFIELD(movement_type, UNSTOPPABLE)) + if((movement_type & PHASING)) playsound(src, 'sound/effects/curse3.ogg', 25, 1, -1) var/turf/T = get_step(src, dir) var/obj/effect/temp_visual/dir_setting/curse/hand/leftover = new(T, dir) diff --git a/code/modules/projectiles/projectile/special/floral.dm b/code/modules/projectiles/projectile/special/floral.dm index b855322f09..9eb6131cbe 100644 --- a/code/modules/projectiles/projectile/special/floral.dm +++ b/code/modules/projectiles/projectile/special/floral.dm @@ -4,7 +4,7 @@ damage = 0 damage_type = TRUE nodamage = 1 - flag = "energy" + flag = ENERGY /obj/item/projectile/energy/floramut/on_hit(atom/target, blocked = FALSE) . = ..() @@ -22,7 +22,7 @@ damage = 0 damage_type = TOX nodamage = TRUE - flag = "energy" + flag = ENERGY /obj/item/projectile/energy/florarevolution name = "gamma somatorary" @@ -30,4 +30,4 @@ damage = 0 damage_type = TOX nodamage = TRUE - flag = "energy" + flag = ENERGY diff --git a/code/modules/projectiles/projectile/special/ion.dm b/code/modules/projectiles/projectile/special/ion.dm index 41331f6738..835c148986 100644 --- a/code/modules/projectiles/projectile/special/ion.dm +++ b/code/modules/projectiles/projectile/special/ion.dm @@ -4,7 +4,7 @@ damage = 0 damage_type = BURN nodamage = TRUE - flag = "energy" + flag = ENERGY impact_effect_type = /obj/effect/temp_visual/impact_effect/ion var/emp_radius = 1 diff --git a/code/modules/projectiles/projectile/special/meteor.dm b/code/modules/projectiles/projectile/special/meteor.dm index ec54e8dd1e..569d4ea754 100644 --- a/code/modules/projectiles/projectile/special/meteor.dm +++ b/code/modules/projectiles/projectile/special/meteor.dm @@ -5,7 +5,7 @@ damage = 0 damage_type = BRUTE nodamage = 1 - flag = "bullet" + flag = BULLET /obj/item/projectile/meteor/Bump(atom/A) if(A == firer) diff --git a/code/modules/projectiles/projectile/special/plasma.dm b/code/modules/projectiles/projectile/special/plasma.dm index 77509cb574..050d6a4364 100644 --- a/code/modules/projectiles/projectile/special/plasma.dm +++ b/code/modules/projectiles/projectile/special/plasma.dm @@ -13,7 +13,7 @@ muzzle_type = /obj/effect/projectile/muzzle/plasma_cutter impact_type = /obj/effect/projectile/impact/plasma_cutter -/obj/item/projectile/plasma/Initialize() +/obj/item/projectile/plasma/Initialize(mapload) . = ..() if(!lavaland_equipment_pressure_check(get_turf(src))) name = "weakened [name]" diff --git a/code/modules/projectiles/projectile/special/rocket.dm b/code/modules/projectiles/projectile/special/rocket.dm index b3737a8388..87fa7557da 100644 --- a/code/modules/projectiles/projectile/special/rocket.dm +++ b/code/modules/projectiles/projectile/special/rocket.dm @@ -23,7 +23,7 @@ explosion(target, -1, 1, 3, 1, 0, flame_range = 4) if(ismecha(target)) - var/obj/mecha/M = target + var/obj/vehicle/sealed/mecha/M = target M.take_damage(anti_armour_damage) if(issilicon(target)) var/mob/living/silicon/S = target @@ -53,7 +53,7 @@ ricochets_max = 0 //it's a MISSILE var/sturdy = list( /turf/closed, - /obj/mecha, + /obj/vehicle/sealed/mecha, /obj/machinery/door/, /obj/machinery/door/poddoor/shutters ) diff --git a/code/modules/projectiles/projectile/special/temperature.dm b/code/modules/projectiles/projectile/special/temperature.dm index ec23af6748..4bd4191fa5 100644 --- a/code/modules/projectiles/projectile/special/temperature.dm +++ b/code/modules/projectiles/projectile/special/temperature.dm @@ -12,7 +12,7 @@ ricochet_chance = 80 is_reflectable = TRUE light_color = LIGHT_COLOR_BLUE - flag = "energy" + flag = ENERGY var/temperature = 100 /obj/item/projectile/temp/on_hit(atom/target, blocked = 0) diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index afad323a27..77d713047a 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -14,6 +14,7 @@ GLOB.chemical_reagents_list[path] = D /proc/build_chemical_reactions_list() + message_admins("STARTY START START!") //Chemical Reactions - Initialises all /datum/chemical_reaction into a list // It is filtered into multiple lists within a list. // For example: @@ -26,11 +27,20 @@ //Randomized need to go last since they need to check against conflicts with normal recipes var/paths = subtypesof(/datum/chemical_reaction) - typesof(/datum/chemical_reaction/randomized) + subtypesof(/datum/chemical_reaction/randomized) GLOB.chemical_reactions_list = list() + GLOB.normalized_chemical_reactions_list = list() // chemistry pda + GLOB.drink_reactions_list = list() // bartender pda for(var/path in paths) var/datum/chemical_reaction/D = new path() var/list/reaction_ids = list() + // store recipes separately for bartender/chemistry cartridges + if(D.id && !D.is_secret) // don't show things like secretcatchem or secret sauce + var/datum/reagent/r = D.id + if(ispath(D.id, /datum/reagent/consumable)) + GLOB.drink_reactions_list[initial(r.name)] = D + if(ispath(D.id, /datum/reagent)) + GLOB.normalized_chemical_reactions_list[initial(r.name)] = D if(D.required_reagents && D.required_reagents.len) for(var/reaction in D.required_reagents) @@ -43,6 +53,31 @@ GLOB.chemical_reactions_list[id] += D break // Don't bother adding ourselves to other reagent ids, it is redundant +/proc/recipe_search(mob/M, list/reaction_list) + var/option = input(M, "Enter keyword to return a recipe.") + if(option) + option = lowertext(option) + var/list/reagents_required + var/found_reagent_name + var/required_temp + for(var/reagent_name in reaction_list) + if(findtext(lowertext(reagent_name), option)) + var/datum/chemical_reaction/reaction = reaction_list[reagent_name] + found_reagent_name = reagent_name + reagents_required = reaction.required_reagents + required_temp = reaction.required_temp + break + if(length(reagents_required)) + to_chat(M, "Recipe found: [found_reagent_name][required_temp ? "
    Required Temperature: [required_temp]K" : ""]
    Required Reagents:") + var/reagents_required_string = "" + for(var/r in reagents_required) + var/datum/reagent/reagent = r + reagents_required_string += "
    [initial(reagent.name)]: [reagents_required[r]]" + to_chat(M, reagents_required_string) + return + else + to_chat(M, "Reagent with term: [option] could not be located!") + /////////////////////////////////////////////////////////////////////////////////// /datum/reagents @@ -62,6 +97,7 @@ var/fermiIsReacting = FALSE //that prevents multiple reactions from occurring (i.e. add_reagent calls to process_reactions(), this stops any extra reactions.) var/fermiReactID //instance of the chem reaction used during a fermireaction, kept here so it's cache isn't lost between loops/procs. var/value_multiplier = DEFAULT_REAGENTS_VALUE //used for cargo reagents selling. + var/force_alt_taste = FALSE /datum/reagents/New(maximum=100, new_flags = NONE, new_value = DEFAULT_REAGENTS_VALUE) maximum_volume = maximum @@ -198,6 +234,7 @@ var/transfer_amount = T.volume * part if(preserve_data) trans_data = copy_data(T) + post_copy_data(T) transferred += "[T] - [transfer_amount]" R.add_reagent(T.type, transfer_amount * multiplier, trans_data, chem_temp, T.purity, pH, no_react = TRUE, ignore_pH = TRUE) //we only handle reaction after every reagent has been transfered. @@ -238,7 +275,8 @@ var/datum/reagent/T = reagent var/copy_amount = T.volume * part if(preserve_data) - trans_data = T.data + trans_data = copy_data(T) + post_copy_data(T) R.add_reagent(T.type, copy_amount * multiplier, trans_data) src.update_total() @@ -265,7 +303,8 @@ var/datum/reagent/current_reagent = CR if(current_reagent.type == reagent) if(preserve_data) - trans_data = current_reagent.data + trans_data = copy_data(current_reagent) + post_copy_data(current_reagent) R.add_reagent(current_reagent.type, amount, trans_data, chem_temp, current_reagent.purity, pH, no_react = TRUE) remove_reagent(current_reagent.type, amount, 1) if(log && amount > 0) @@ -344,6 +383,8 @@ if(owner && reagent) if(!owner.reagent_check(reagent, delta_time, times_fired) != TRUE) return + if(is_reagent_processing_invalid(reagent, owner)) + return reagent.on_invalid_process(owner, delta_time, times_fired) if(liverless && !reagent.self_consuming) //need to be metabolized return if(!reagent.metabolizing) @@ -822,7 +863,7 @@ pH = REAGENT_NORMAL_PH return 0 -/datum/reagents/proc/reaction(atom/A, method = TOUCH, volume_modifier = 1, show_message = 1) +/datum/reagents/proc/reaction(atom/A, method = TOUCH, volume_modifier = 1, show_message = 1, from_gas = 0) var/react_type if(isliving(A)) react_type = "LIVING" @@ -846,9 +887,10 @@ touch_protection = L.get_permeability_protection() R.reaction_mob(A, method, R.volume * volume_modifier, show_message, touch_protection) if("TURF") - R.reaction_turf(A, R.volume * volume_modifier, show_message) + R.reaction_turf(A, R.volume * volume_modifier, show_message, from_gas) if("OBJ") R.reaction_obj(A, R.volume * volume_modifier, show_message) + SEND_SIGNAL(A, COMSIG_ATOM_EXPOSE_REAGENTS, cached_reagents, src, method, volume_modifier, show_message, from_gas) /datum/reagents/proc/holder_full() if(total_volume >= maximum_volume) @@ -856,17 +898,16 @@ return FALSE //Returns the average specific heat for all reagents currently in this holder. -/datum/reagents/proc/specific_heat() +/datum/reagents/proc/heat_capacity() . = 0 - var/cached_amount = total_volume //cache amount var/list/cached_reagents = reagent_list //cache reagents for(var/I in cached_reagents) var/datum/reagent/R = I - . += R.specific_heat * (R.volume / cached_amount) + . += R.specific_heat * R.volume /datum/reagents/proc/adjust_thermal_energy(J, min_temp = 2.7, max_temp = 1000) - var/S = specific_heat() - chem_temp = clamp(chem_temp + (J / (S * total_volume)), min_temp, max_temp) + var/S = heat_capacity() + chem_temp = clamp(chem_temp + (J / S), min_temp, max_temp) if(istype(my_atom, /obj/item/reagent_containers)) var/obj/item/reagent_containers/RC = my_atom RC.temp_check() @@ -1115,52 +1156,64 @@ return trans_data +/// +// Should be ran after using copy_data. Calls the reagent's post_copy_data, which usually does nothing. +/datum/reagents/proc/post_copy_data(datum/reagent/current_reagent) + return current_reagent.post_copy_data() + /datum/reagents/proc/get_reagent(type) var/list/cached_reagents = reagent_list . = locate(type) in cached_reagents /datum/reagents/proc/generate_taste_message(minimum_percent=15) - // the lower the minimum percent, the more sensitive the message is. var/list/out = list() - var/list/tastes = list() //descriptor = strength - if(minimum_percent <= 100) - for(var/datum/reagent/R in reagent_list) - if(!R.taste_mult) - continue - - if(istype(R, /datum/reagent/consumable/nutriment)) - var/list/taste_data = R.data - for(var/taste in taste_data) - var/ratio = taste_data[taste] - var/amount = ratio * R.taste_mult * R.volume - if(taste in tastes) - tastes[taste] += amount - else - tastes[taste] = amount - else - var/taste_desc = R.taste_description - var/taste_amount = R.volume * R.taste_mult - if(taste_desc in tastes) - tastes[taste_desc] += taste_amount - else - tastes[taste_desc] = taste_amount - //deal with percentages - // TODO it would be great if we could sort these from strong to weak - var/total_taste = counterlist_sum(tastes) - if(total_taste > 0) - for(var/taste_desc in tastes) - var/percent = tastes[taste_desc]/total_taste * 100 - if(percent < minimum_percent) + if(!force_alt_taste) + // the lower the minimum percent, the more sensitive the message is. + var/list/tastes = list() //descriptor = strength + if(minimum_percent <= 100) + for(var/datum/reagent/R in reagent_list) + if(!R.taste_mult) continue - var/intensity_desc = "a hint of" - if(ISINRANGE(percent, minimum_percent * 2, minimum_percent * 3)|| percent == 100) - intensity_desc = "" - else if(percent > minimum_percent * 3) - intensity_desc = "the strong flavor of" - if(intensity_desc != "") - out += "[intensity_desc] [taste_desc]" + + if(istype(R, /datum/reagent/consumable/nutriment)) + var/list/taste_data = R.data + for(var/taste in taste_data) + var/ratio = taste_data[taste] + var/amount = ratio * R.taste_mult * R.volume + if(taste in tastes) + tastes[taste] += amount + else + tastes[taste] = amount else - out += "[taste_desc]" + var/taste_desc = R.taste_description + var/taste_amount = R.volume * R.taste_mult + if(taste_desc in tastes) + tastes[taste_desc] += taste_amount + else + tastes[taste_desc] = taste_amount + //deal with percentages + // TODO it would be great if we could sort these from strong to weak + var/total_taste = counterlist_sum(tastes) + if(total_taste > 0) + for(var/taste_desc in tastes) + var/percent = tastes[taste_desc]/total_taste * 100 + if(percent < minimum_percent) + continue + var/intensity_desc = "a hint of" + if(ISINRANGE(percent, minimum_percent * 2, minimum_percent * 3)|| percent == 100) + intensity_desc = "" + else if(percent > minimum_percent * 3) + intensity_desc = "the strong flavor of" + if(intensity_desc != "") + out += "[intensity_desc] [taste_desc]" + else + out += "[taste_desc]" + + else + // alternate taste is to force the taste of the atom if its a food item + if(my_atom && isfood(my_atom)) + var/obj/item/reagent_containers/food/snacks/F = my_atom + out = F.tastes return english_list(out, "something indescribable") diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 22aadc06f4..1a64045ed0 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -92,7 +92,7 @@ var/list/saved_recipes = list() -/obj/machinery/chem_dispenser/Initialize() +/obj/machinery/chem_dispenser/Initialize(mapload) . = ..() dispensable_reagents = sortList(dispensable_reagents, /proc/cmp_reagents_asc) if(emagged_reagents) @@ -165,14 +165,14 @@ obj_flags |= EMAGGED return TRUE -/obj/machinery/chem_dispenser/ex_act(severity, target) +/obj/machinery/chem_dispenser/ex_act(severity, target, origin) if(severity < 3) ..() -/obj/machinery/chem_dispenser/contents_explosion(severity, target) +/obj/machinery/chem_dispenser/contents_explosion(severity, target, origin) ..() if(beaker) - beaker.ex_act(severity, target) + beaker.ex_act(severity, target, origin) /obj/machinery/chem_dispenser/Exited(atom/movable/A, atom/newloc) . = ..() @@ -534,7 +534,7 @@ return "purple" -/obj/machinery/chem_dispenser/drinks/Initialize() +/obj/machinery/chem_dispenser/drinks/Initialize(mapload) . = ..() AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE) @@ -628,19 +628,11 @@ desc = "Contains a large reservoir of soft drinks. This model has had its safeties shorted out." obj_flags = CAN_BE_HIT | EMAGGED flags_1 = NODECONSTRUCT_1 + circuit = /obj/item/circuitboard/machine/chem_dispenser/drinks/fullupgrade -/obj/machinery/chem_dispenser/drinks/fullupgrade/Initialize() +/obj/machinery/chem_dispenser/drinks/fullupgrade/Initialize(mapload) . = ..() dispensable_reagents |= emagged_reagents //adds emagged reagents - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/chem_dispenser/drinks(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/capacitor/quadratic(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() /obj/machinery/chem_dispenser/drinks/beer name = "booze dispenser" @@ -688,19 +680,11 @@ desc = "Contains a large reservoir of the good stuff. This model has had its safeties shorted out." obj_flags = CAN_BE_HIT | EMAGGED flags_1 = NODECONSTRUCT_1 + circuit = /obj/item/circuitboard/machine/chem_dispenser/drinks/beer/fullupgrade -/obj/machinery/chem_dispenser/drinks/beer/fullupgrade/Initialize() +/obj/machinery/chem_dispenser/drinks/beer/fullupgrade/Initialize(mapload) . = ..() dispensable_reagents |= emagged_reagents //adds emagged reagents - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/chem_dispenser/drinks/beer(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/capacitor/quadratic(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() /obj/machinery/chem_dispenser/mutagen name = "mutagen dispenser" @@ -716,6 +700,7 @@ desc = "Creates and dispenses chemicals useful for botany." flags_1 = NODECONSTRUCT_1 canStore = FALSE + circuit = /obj/item/circuitboard/machine/chem_dispenser/mutagensaltpeter dispensable_reagents = list( /datum/reagent/toxin/mutagen, @@ -736,35 +721,15 @@ upgrade_reagents2 = null upgrade_reagents3 = null -/obj/machinery/chem_dispenser/mutagensaltpeter/Initialize() - . = ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/chem_dispenser(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/capacitor/quadratic(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() - /obj/machinery/chem_dispenser/fullupgrade //fully ugpraded stock parts, emagged desc = "Creates and dispenses chemicals. This model has had its safeties shorted out." obj_flags = CAN_BE_HIT | EMAGGED flags_1 = NODECONSTRUCT_1 + circuit = /obj/item/circuitboard/machine/chem_dispenser/fullupgrade -/obj/machinery/chem_dispenser/fullupgrade/Initialize() +/obj/machinery/chem_dispenser/fullupgrade/Initialize(mapload) . = ..() dispensable_reagents |= emagged_reagents //adds emagged reagents - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/chem_dispenser(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/capacitor/quadratic(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() /obj/machinery/chem_dispenser/abductor name = "reagent synthesizer" @@ -818,18 +783,6 @@ /datum/reagent/medicine/morphine ) -/obj/machinery/chem_dispenser/abductor/Initialize() - . = ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/chem_dispenser(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/capacitor/quadratic(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() - ///An unique, less efficient model found in the medbay apothecary room. /obj/machinery/chem_dispenser/apothecary name = "apothecary chem dispenser" diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index 285ef70433..0e53b0796b 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -22,7 +22,7 @@ var/list/pillStyles var/fermianalyze //Give more detail on fermireactions on analysis -/obj/machinery/chem_master/Initialize() +/obj/machinery/chem_master/Initialize(mapload) create_reagents(100) //Calculate the span tags and ids fo all the available pill icons @@ -46,16 +46,16 @@ for(var/obj/item/reagent_containers/glass/beaker/B in component_parts) reagents.maximum_volume += B.reagents.maximum_volume -/obj/machinery/chem_master/ex_act(severity, target) +/obj/machinery/chem_master/ex_act(severity, target, origin) if(severity < 3) ..() -/obj/machinery/chem_master/contents_explosion(severity, target) +/obj/machinery/chem_master/contents_explosion(severity, target, origin) ..() if(beaker) - beaker.ex_act(severity, target) + beaker.ex_act(severity, target, origin) if(bottle) - bottle.ex_act(severity, target) + bottle.ex_act(severity, target, origin) /obj/machinery/chem_master/Exited(atom/movable/A, atom/newloc) . = ..() @@ -390,22 +390,31 @@ var/datum/reagent/R = GLOB.chemical_reagents_list[reagent] if(R) var/state = "Unknown" - if(initial(R.reagent_state) == 1) + if(initial(R.reagent_state) == SOLID) state = "Solid" - else if(initial(R.reagent_state) == 2) + else if(initial(R.reagent_state) == LIQUID) state = "Liquid" - else if(initial(R.reagent_state) == 3) + else if(initial(R.reagent_state) == GAS) state = "Gas" var/const/P = 3 //The number of seconds between life ticks var/T = initial(R.metabolization_rate) * (60 / P) + var/processtype + if(CHECK_MULTIPLE_BITFIELDS(R.chemical_flags, (REAGENT_ROBOTIC_PROCESS | REAGENT_ORGANIC_PROCESS))) + processtype = "Both robots and organics" + else if(R.chemical_flags & REAGENT_ROBOTIC_PROCESS) + processtype = "Robots only" + else if(R.chemical_flags & REAGENT_ORGANIC_PROCESS) + processtype = "Organics only" + else + processtype = "Noone?! (Report this to Nanotrasen's spacetime department immediately)" if(istype(R, /datum/reagent/fermi)) fermianalyze = TRUE var/datum/chemical_reaction/Rcr = get_chemical_reaction(reagent) var/pHpeakCache = (Rcr.OptimalpHMin + Rcr.OptimalpHMax)/2 - analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = R.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache) + analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "processType" = processtype, "purityF" = R.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache) else fermianalyze = FALSE - analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = R.purity) + analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "processType" = processtype, "purityF" = R.purity) screen = "analyze" return TRUE diff --git a/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm b/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm index 489f9dd179..ae87d7714c 100644 --- a/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm +++ b/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm @@ -53,10 +53,10 @@ return beaker = new /obj/item/reagent_containers/glass/beaker/bluespace(src) visible_message("[src] dispenses a bluespace beaker.") - if("amount") - var/input = text2num(params["amount"]) + if("synth_amount") + var/input = text2num(params["synth_amount"]) if(input) - amount = input + amount = max(input, 0) update_icon() /obj/machinery/chem_dispenser/chem_synthesizer/proc/find_reagent(input) diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm index d4d8ae47fe..4729443d7a 100644 --- a/code/modules/reagents/chemistry/machinery/pandemic.dm +++ b/code/modules/reagents/chemistry/machinery/pandemic.dm @@ -16,7 +16,7 @@ var/datum/symptom/selected_symptom var/obj/item/reagent_containers/beaker -/obj/machinery/computer/pandemic/Initialize() +/obj/machinery/computer/pandemic/Initialize(mapload) . = ..() update_icon() diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index a53c57a3e7..b3c4cc8908 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -25,13 +25,13 @@ var/static/radial_juice = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_juice") var/static/radial_mix = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_mix") -/obj/machinery/reagentgrinder/Initialize() +/obj/machinery/reagentgrinder/Initialize(mapload) . = ..() holdingitems = list() beaker = new /obj/item/reagent_containers/glass/beaker/large(src) beaker.desc += " May contain blended dust. Don't breathe this in!" -/obj/machinery/reagentgrinder/constructed/Initialize() +/obj/machinery/reagentgrinder/constructed/Initialize(mapload) . = ..() holdingitems = list() QDEL_NULL(beaker) @@ -43,9 +43,9 @@ drop_all_items() return ..() -/obj/machinery/reagentgrinder/contents_explosion(severity, target) +/obj/machinery/reagentgrinder/contents_explosion(severity, target, origin) if(beaker) - beaker.ex_act(severity, target) + beaker.ex_act(severity, target, origin) /obj/machinery/reagentgrinder/RefreshParts() speed = 1 diff --git a/code/modules/reagents/chemistry/machinery/smoke_machine.dm b/code/modules/reagents/chemistry/machinery/smoke_machine.dm index 80b8011af0..e601e9f551 100644 --- a/code/modules/reagents/chemistry/machinery/smoke_machine.dm +++ b/code/modules/reagents/chemistry/machinery/smoke_machine.dm @@ -29,7 +29,7 @@ opaque = FALSE alpha = 100 -/obj/machinery/smoke_machine/Initialize() +/obj/machinery/smoke_machine/Initialize(mapload) . = ..() create_reagents(REAGENTS_BASE_VOLUME) for(var/obj/item/stock_parts/matter_bin/B in component_parts) diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index d6b7201ef9..2fb8f58019 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -1,4 +1,3 @@ -#define REM REAGENTS_EFFECT_MULTIPLIER GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) /proc/build_name2reagent() @@ -51,9 +50,13 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) var/inverse_chem_val = 0 // If the impurity is below 0.5, replace ALL of the chem with inverse_chemupon metabolising var/inverse_chem // What chem is metabolised when purity is below inverse_chem_val, this shouldn't be made, but if it does, well, I guess I'll know about it. var/metabolizing = FALSE - var/chemical_flags // See fermi/readme.dm REAGENT_DEAD_PROCESS, REAGENT_DONOTSPLIT, REAGENT_ONLYINVERSE, REAGENT_ONMOBMERGE, REAGENT_INVISIBLE, REAGENT_FORCEONNEW, REAGENT_SNEAKYNAME + var/chemical_flags = REAGENT_ORGANIC_PROCESS // See fermi/readme.dm REAGENT_DEAD_PROCESS, REAGENT_DONOTSPLIT, REAGENT_ONLYINVERSE, REAGENT_ONMOBMERGE, REAGENT_INVISIBLE, REAGENT_FORCEONNEW, REAGENT_SNEAKYNAME, REAGENT_ORGANIC_PROCESS, REAGENT_ROBOTIC_PROCESS var/value = REAGENT_VALUE_NONE //How much does it sell for in cargo? var/datum/material/material //are we made of material? + var/gas = null //do we have an associated gas? (expects a string, not a datum typepath!) + var/boiling_point = null // point at which this gas boils; if null, will never boil (and thus not become a gas) + var/condensation_amount = 1 + var/molarity = 5 // How many units per mole of this reagent. Technically this is INVERSE molarity, but hey. /datum/reagent/New() . = ..() @@ -78,16 +81,34 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) return 1 /datum/reagent/proc/reaction_obj(obj/O, volume) - return + if(O && volume && boiling_point) + var/temp = holder ? holder.chem_temp : T20C + if(temp > boiling_point) + O.atmos_spawn_air("[get_gas()]=[volume/molarity];TEMP=[temp]") -/datum/reagent/proc/reaction_turf(turf/T, volume) - return +/datum/reagent/proc/reaction_turf(turf/T, volume, show_message, from_gas) + if(!from_gas && boiling_point) + var/temp = holder?.chem_temp + if(!temp) + if(isopenturf(T)) + var/turf/open/O = T + var/datum/gas_mixture/air = O.return_air() + temp = air.return_temperature() + else + temp = T20C + if(temp > boiling_point) + T.atmos_spawn_air("[get_gas()]=[volume/molarity];TEMP=[temp]") /datum/reagent/proc/on_mob_life(mob/living/carbon/M) current_cycle++ if(holder) holder.remove_reagent(type, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears. +//Called when an reagent is incompatible with its processing carbon (e.g. robot carbon and reagent with only organic processing) +/datum/reagent/proc/on_invalid_process(mob/living/carbon/M) + if(holder) + holder.remove_reagent(type, INVALID_REAGENT_DISSIPATION) //Not influenced by normal metab rate nor efficiency. + //called when a mob processes chems when dead. /datum/reagent/proc/on_mob_dead(mob/living/carbon/M) if(!(chemical_flags & REAGENT_DEAD_PROCESS)) //justincase @@ -178,6 +199,10 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) M.reagents.add_reagent(impure_chem, impureVol, FALSE, other_purity = 1-cached_purity) log_reagent("MOB ADD: on_merge() (mixed purity): merged [volume - impureVol] of [type] and [volume] of [impure_chem]") +//Ran by a reagent holder on a specific reagent after copying its data. +/datum/reagent/proc/post_copy_data() + return + /datum/reagent/proc/on_update(atom/A) return @@ -231,6 +256,43 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) return rs.Join(" | ") +/datum/reagent/proc/define_gas() + var/list/cached_reactions = GLOB.chemical_reactions_list + for(var/reaction in cached_reactions[src.type]) + var/datum/chemical_reaction/C = reaction + if(!istype(C)) + continue + if(C.required_reagents.len < 2) // no reagents that react on their own + return null + var/datum/gas/G = new + G.id = "[src.type]" + G.name = name + G.specific_heat = specific_heat / 10 + G.color = color + G.breath_reagent = src.type + G.group = GAS_GROUP_CHEMICALS + G.moles_visible = MOLES_GAS_VISIBLE + return G + +/datum/reagent/proc/create_gas() + var/datum/gas/G = define_gas() + if(istype(G)) // if this reagent should never be a gas, define_gas may return null + GLOB.gas_data.add_gas(G) + var/datum/gas_reaction/condensation/condensation_reaction = new(src) // did you know? you can totally just add new reactions at runtime. it's allowed + SSair.add_reaction(condensation_reaction) + return G + + +/datum/reagent/proc/get_gas() + if(gas) + return gas + else + var/datum/auxgm/cached_gas_data = GLOB.gas_data + . = "[src.type]" + if(!(. in cached_gas_data.ids)) + create_gas() + + //For easy bloodsucker disgusting and blood removal /datum/reagent/proc/disgust_bloodsucker(mob/living/carbon/C, disgust, blood_change, blood_puke = TRUE, force) if(AmBloodsucker(C)) diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 12c91e145a..948586046e 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -14,6 +14,7 @@ taste_description = "alcohol" var/boozepwr = 65 //Higher numbers equal higher hardness, higher hardness equals more intense alcohol poisoning pH = 7.33 + boiling_point = 351.38 value = REAGENT_VALUE_VERY_COMMON //don't bother tweaking all drinks values, way too many can easily be done roundstart or with an upgraded dispenser. /* @@ -41,13 +42,9 @@ All effects don't start immediately, but rather get worse over time; the rate is if(!iscarbon(L)) return - var/mob/living/carbon/C = L - if(HAS_TRAIT(C, TRAIT_ROBOTIC_ORGANISM)) - C.reagents.remove_reagent(type, amount, FALSE) - /datum/reagent/consumable/ethanol/on_mob_life(mob/living/carbon/C) if(HAS_TRAIT(C, TRAIT_TOXIC_ALCOHOL)) - C.adjustToxLoss((boozepwr/25)*REM,forced = TRUE) + C.adjustToxLoss((boozepwr/25)*REAGENTS_EFFECT_MULTIPLIER,forced = TRUE) else if(C.drunkenness < volume * boozepwr * ALCOHOL_THRESHOLD_MODIFIER) var/booze_power = boozepwr if(HAS_TRAIT(C, TRAIT_ALCOHOL_TOLERANCE)) //we're an accomplished drinker @@ -89,6 +86,31 @@ All effects don't start immediately, but rather get worse over time; the rate is // +10% success propability on each step, useful while operating in less-than-perfect conditions return ..() +/datum/reagent/consumable/ethanol/define_gas() // So that all alcohols have the same gas, i.e. "ethanol" + var/datum/gas/G = new + G.id = GAS_ETHANOL + G.name = "Ethanol" + G.enthalpy = -234800 + G.specific_heat = 38 + G.fire_products = list(GAS_CO2 = 1, GAS_H2O = 1.5) + G.fire_burn_rate = 1 / 3 + G.fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + G.color = "#404030" + G.breath_reagent = /datum/reagent/consumable/ethanol + G.group = GAS_GROUP_CHEMICALS + return G + +/datum/reagent/consumable/ethanol/get_gas() + var/datum/auxgm/cached_gas_data = GLOB.gas_data + . = GAS_ETHANOL + if(!(. in cached_gas_data.ids)) + var/datum/gas/G = define_gas() + if(istype(G)) + cached_gas_data.add_gas(G) + else // this codepath should probably not happen at all, since we never use get_gas() on anything with no boiling point + return null + + /datum/reagent/consumable/ethanol/beer name = "Beer" description = "An alcoholic beverage brewed since ancient times on Old Earth. Still popular today." @@ -1365,7 +1387,7 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/neurotoxin/on_mob_life(mob/living/carbon/M) M.set_drugginess(50) M.dizziness +=2 - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REM, 150) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REAGENTS_EFFECT_MULTIPLIER, 150) if(prob(20) && !holder.has_reagent(/datum/reagent/consumable/ethanol/neuroweak)) M.adjustStaminaLoss(10) M.drop_all_held_items() @@ -1376,7 +1398,7 @@ All effects don't start immediately, but rather get worse over time; the rate is ADD_TRAIT(M, t, type) M.adjustStaminaLoss(10) if(current_cycle > 30) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REAGENTS_EFFECT_MULTIPLIER) if(current_cycle > 50 && prob(15)) if(!M.undergoing_cardiac_arrest() && M.can_heartattack()) M.set_heartattack(TRUE) @@ -1401,13 +1423,13 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/neuroweak/on_mob_life(mob/living/carbon/M) if(holder.has_reagent(/datum/reagent/consumable/ethanol/neurotoxin)) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1*REM, 150) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1*REAGENTS_EFFECT_MULTIPLIER, 150) M.reagents.remove_reagent(/datum/reagent/consumable/ethanol/neurotoxin, 1.5 * REAGENTS_METABOLISM, FALSE) else if(holder.has_reagent(/datum/reagent/toxin/fentanyl)) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1*REM, 150) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1*REAGENTS_EFFECT_MULTIPLIER, 150) M.reagents.remove_reagent(/datum/reagent/toxin/fentanyl, 0.75 * REAGENTS_METABOLISM, FALSE) else - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -0.5*REM, 150) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -0.5*REAGENTS_EFFECT_MULTIPLIER, 150) M.dizziness +=2 ..() @@ -1664,14 +1686,14 @@ All effects don't start immediately, but rather get worse over time; the rate is var/heal_points = 10 if(L.health <= 0) heal_points = 20 //heal more if we're in softcrit - for(var/i in 1 to min(volume, heal_points)) //only heals 1 point of damage per unit on add, for balance reasons - L.adjustBruteLoss(-1) - L.adjustFireLoss(-1) - L.adjustToxLoss(-1) - L.adjustOxyLoss(-1) - L.adjustStaminaLoss(-1) + heal_points = min(volume, heal_points) + L.adjustBruteLoss(-heal_points) + L.adjustFireLoss(-heal_points) + L.adjustToxLoss(-heal_points) + L.adjustOxyLoss(-heal_points) + L.adjustStaminaLoss(-heal_points) L.visible_message("[L] shivers with renewed vigor!", "One taste of [lowertext(name)] fills you with energy!") - if(!L.stat && heal_points == 20) //brought us out of softcrit + if(!L.stat && L.health > 0) //brought us out of softcrit L.visible_message("[L] lurches to [L.p_their()] feet!", "Up and at 'em, kid.") /datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_life(mob/living/L) @@ -1925,7 +1947,7 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/fernet/on_mob_life(mob/living/carbon/M) if(M.nutrition <= NUTRITION_LEVEL_STARVING) - M.adjustToxLoss(1*REM, 0) + M.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER, 0) M.adjust_nutrition(-5) M.overeatduration = 0 return ..() @@ -1943,7 +1965,7 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/fernet_cola/on_mob_life(mob/living/carbon/M) if(M.nutrition <= NUTRITION_LEVEL_STARVING) - M.adjustToxLoss(0.5*REM, 0) + M.adjustToxLoss(0.5*REAGENTS_EFFECT_MULTIPLIER, 0) M.adjust_nutrition(-3) M.overeatduration = 0 return ..() diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index 5059376954..c0892ce1e2 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -47,7 +47,7 @@ /datum/reagent/consumable/limejuice/on_mob_life(mob/living/carbon/M) if(M.getToxLoss() && prob(20)) - M.adjustToxLoss(-1*REM, 0) + M.adjustToxLoss(-1*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 ..() @@ -1034,7 +1034,7 @@ M.update_transform() ..() -/datum/reagent/consumable/pinkmilk +/datum/reagent/consumable/milk/pinkmilk name = "Strawberry Milk" description = "A drink of a bygone era of milk and artificial sweetener back on a rock." color = "#f76aeb"//rgb(247, 106, 235) @@ -1045,13 +1045,13 @@ glass_desc = "Delicious flavored strawberry syrup mixed with milk." value = REAGENT_VALUE_VERY_COMMON -/datum/reagent/consumable/tea/pinkmilk/on_mob_life(mob/living/carbon/M) +/datum/reagent/consumable/milk/pinkmilk/on_mob_life(mob/living/carbon/M) if(prob(15)) to_chat(M, "[pick("You cant help to smile.","You feel nostalgia all of sudden.","You remember to relax.")]") ..() . = 1 -/datum/reagent/consumable/pinktea //Tiny Tim song +/datum/reagent/consumable/tea/pinktea //Tiny Tim song name = "Strawberry Tea" description = "A timeless classic!" color = "#f76aeb"//rgb(247, 106, 235) diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index ed80804f28..4848347df2 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -59,7 +59,7 @@ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "smoked", /datum/mood_event/smoked, name) M.AdjustAllImmobility(-20, 0) M.AdjustUnconscious(-20, 0) - M.adjustStaminaLoss(-0.5*REM, 0) + M.adjustStaminaLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 @@ -83,30 +83,30 @@ . = 1 /datum/reagent/drug/crank/overdose_process(mob/living/M) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM) - M.adjustToxLoss(2*REM, 0) - M.adjustBruteLoss(2*REM, 0) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REAGENTS_EFFECT_MULTIPLIER) + M.adjustToxLoss(2*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustBruteLoss(2*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 /datum/reagent/drug/crank/addiction_act_stage1(mob/living/M) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5*REM) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5*REAGENTS_EFFECT_MULTIPLIER) ..() /datum/reagent/drug/crank/addiction_act_stage2(mob/living/M) - M.adjustToxLoss(5*REM, 0) + M.adjustToxLoss(5*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 /datum/reagent/drug/crank/addiction_act_stage3(mob/living/M) - M.adjustBruteLoss(5*REM, 0) + M.adjustBruteLoss(5*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 /datum/reagent/drug/crank/addiction_act_stage4(mob/living/M) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3*REM) - M.adjustToxLoss(5*REM, 0) - M.adjustBruteLoss(5*REM, 0) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3*REAGENTS_EFFECT_MULTIPLIER) + M.adjustToxLoss(5*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustBruteLoss(5*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 @@ -128,14 +128,14 @@ ..() /datum/reagent/drug/krokodil/overdose_process(mob/living/M) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.25*REM) - M.adjustToxLoss(0.25*REM, 0) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.25*REAGENTS_EFFECT_MULTIPLIER) + M.adjustToxLoss(0.25*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 /datum/reagent/drug/krokodil/addiction_act_stage1(mob/living/M) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM) - M.adjustToxLoss(2*REM, 0) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REAGENTS_EFFECT_MULTIPLIER) + M.adjustToxLoss(2*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 @@ -147,7 +147,7 @@ /datum/reagent/drug/krokodil/addiction_act_stage3(mob/living/M) if(prob(25)) to_chat(M, "Your skin starts to peel away...") - M.adjustBruteLoss(3*REM, 0) + M.adjustBruteLoss(3*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 @@ -155,10 +155,10 @@ CHECK_DNA_AND_SPECIES(M) if(!istype(M.dna.species, /datum/species/krokodil_addict)) to_chat(M, "Your skin falls off easily!") - M.adjustBruteLoss(50*REM, 0) // holy shit your skin just FELL THE FUCK OFF + M.adjustBruteLoss(50*REAGENTS_EFFECT_MULTIPLIER, 0) // holy shit your skin just FELL THE FUCK OFF M.set_species(/datum/species/krokodil_addict) else - M.adjustBruteLoss(5*REM, 0) + M.adjustBruteLoss(5*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 @@ -186,14 +186,14 @@ if(DT_PROB(2.5, delta_time)) to_chat(M, span_notice("[high_message]")) // SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "tweaking", /datum/mood_event/stimulant_medium, name) - M.AdjustStun(-40 * REM * delta_time) - M.AdjustKnockdown(-40 * REM * delta_time) - M.AdjustUnconscious(-40 * REM * delta_time) - M.AdjustParalyzed(-40 * REM * delta_time) - M.AdjustImmobilized(-40 * REM * delta_time) - M.adjustStaminaLoss(-2 * REM * delta_time, 0) - M.Jitter(2 * REM * delta_time) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, rand(1, 4) * REM * delta_time) + M.AdjustStun(-40 * REAGENTS_EFFECT_MULTIPLIER * delta_time) + M.AdjustKnockdown(-40 * REAGENTS_EFFECT_MULTIPLIER * delta_time) + M.AdjustUnconscious(-40 * REAGENTS_EFFECT_MULTIPLIER * delta_time) + M.AdjustParalyzed(-40 * REAGENTS_EFFECT_MULTIPLIER * delta_time) + M.AdjustImmobilized(-40 * REAGENTS_EFFECT_MULTIPLIER * delta_time) + M.adjustStaminaLoss(-2 * REAGENTS_EFFECT_MULTIPLIER * delta_time, 0) + M.Jitter(2 * REAGENTS_EFFECT_MULTIPLIER * delta_time) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, rand(1, 4) * REAGENTS_EFFECT_MULTIPLIER * delta_time) if(DT_PROB(2.5, delta_time)) M.emote(pick("twitch", "shiver")) ..() @@ -201,7 +201,7 @@ /datum/reagent/drug/methamphetamine/overdose_process(mob/living/M, delta_time, times_fired) if(CHECK_MOBILITY(M, MOBILITY_MOVE) && !ismovable(M.loc)) - for(var/i in 1 to round(4 * REM * delta_time, 1)) + for(var/i in 1 to round(4 * REAGENTS_EFFECT_MULTIPLIER * delta_time, 1)) step(M, pick(GLOB.cardinals)) if(DT_PROB(10, delta_time)) M.emote("laugh") @@ -209,8 +209,8 @@ M.visible_message(span_danger("[M]'s hands flip out and flail everywhere!")) M.drop_all_held_items() ..() - M.adjustToxLoss(1 * REM * delta_time, 0) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, (rand(5, 10) / 10) * REM * delta_time) + M.adjustToxLoss(1 * REAGENTS_EFFECT_MULTIPLIER * delta_time, 0) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, (rand(5, 10) / 10) * REAGENTS_EFFECT_MULTIPLIER * delta_time) . = TRUE /datum/reagent/drug/methamphetamine/addiction_act_stage1(mob/living/M) @@ -486,8 +486,8 @@ H.dna.species.punchstunthreshold += 2 /datum/reagent/drug/skooma/on_mob_life(mob/living/carbon/M) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REM) - M.adjustToxLoss(1*REM) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REAGENTS_EFFECT_MULTIPLIER) + M.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER) if(prob(10)) M.adjust_blurriness(2) ..() @@ -531,7 +531,7 @@ value = REAGENT_VALUE_VERY_RARE /datum/reagent/syndicateadrenals/on_mob_life(mob/living/M) - M.adjustStaminaLoss(-5*REM) + M.adjustStaminaLoss(-5*REAGENTS_EFFECT_MULTIPLIER) . = ..() /datum/reagent/syndicateadrenals/on_mob_metabolize(mob/living/M) diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index a9bdff64b2..71339567d2 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -381,6 +381,13 @@ return if(M.has_bane(BANE_SALT)) M.mind.disrupt_spells(-200) + if(HAS_TRAIT(M, TRAIT_SALT_SENSITIVE)) // haha snails go brrr + M.adjustFireLoss(2) + M.emote("scream") + +/datum/reagent/consumable/sodiumchloride/on_mob_life(mob/living/M) + if(HAS_TRAIT(M, TRAIT_SALT_SENSITIVE)) + M.adjustFireLoss(1) // equal to a standard toxin /datum/reagent/consumable/sodiumchloride/reaction_turf(turf/T, reac_volume) //Creates an umbra-blocking salt pile if(!istype(T)) @@ -554,6 +561,13 @@ color = "#302000" // rgb: 48, 32, 0 taste_description = "wet and cheap noodles" +/datum/reagent/consumable/nutraslop + name = "Nutraslop" + description = "Mixture of leftover prison foods served on previous days." + nutriment_factor = 5 * REAGENTS_METABOLISM + color = "#3E4A00" // rgb: 62, 74, 0 + taste_description = "your imprisonment" + /datum/reagent/consumable/hot_ramen/on_mob_life(mob/living/carbon/M) M.adjust_bodytemperature(10 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, BODYTEMP_NORMAL) ..() @@ -651,10 +665,10 @@ /datum/reagent/consumable/honey/on_mob_life(mob/living/carbon/M) M.reagents.add_reagent(/datum/reagent/consumable/sugar,3) if(prob(55)) - M.adjustBruteLoss(-1*REM, 0) - M.adjustFireLoss(-1*REM, 0) - M.adjustOxyLoss(-1*REM, 0) - M.adjustToxLoss(-1*REM, 0, TRUE) //heals TOXINLOVERs + M.adjustBruteLoss(-1*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustFireLoss(-1*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustOxyLoss(-1*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustToxLoss(-1*REAGENTS_EFFECT_MULTIPLIER, 0, TRUE) //heals TOXINLOVERs ..() /datum/reagent/consumable/honey/reaction_mob(mob/living/M, method=TOUCH, reac_volume) @@ -739,9 +753,9 @@ . = 1 if(prob(20)) M.losebreath += 4 - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM, 150) - M.adjustToxLoss(3*REM,0) - M.adjustStaminaLoss(10*REM,0) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REAGENTS_EFFECT_MULTIPLIER, 150) + M.adjustToxLoss(3*REAGENTS_EFFECT_MULTIPLIER,0) + M.adjustStaminaLoss(10*REAGENTS_EFFECT_MULTIPLIER,0) M.blur_eyes(5) . = TRUE ..() @@ -771,8 +785,8 @@ /datum/reagent/consumable/vitfro/on_mob_life(mob/living/carbon/M) if(prob(80)) - M.adjustBruteLoss(-1*REM, 0) - M.adjustFireLoss(-1*REM, 0) + M.adjustBruteLoss(-1*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustFireLoss(-1*REAGENTS_EFFECT_MULTIPLIER, 0) . = TRUE ..() @@ -797,7 +811,7 @@ var/mob/living/carbon/C = M var/obj/item/organ/stomach/ethereal/stomach = C.getorganslot(ORGAN_SLOT_STOMACH) if(istype(stomach)) - stomach.adjust_charge(reac_volume * REM) + stomach.adjust_charge(reac_volume * REAGENTS_EFFECT_MULTIPLIER) /datum/reagent/consumable/liquidelectricity/on_mob_life(mob/living/carbon/M) if(prob(25) && !isethereal(M)) diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents.dm index 63f62406b5..23cc31d591 100644 --- a/code/modules/reagents/chemistry/reagents/impure_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/impure_reagents.dm @@ -3,7 +3,7 @@ //Invert = Whole conversion /datum/reagent/impure - chemical_flags = REAGENT_INVISIBLE | REAGENT_SNEAKYNAME //by default, it will stay hidden on splitting, but take the name of the source on inverting + chemical_flags = REAGENT_INVISIBLE | REAGENT_SNEAKYNAME | REAGENT_ORGANIC_PROCESS //by default, it will stay hidden on splitting, but take the name of the source on inverting /datum/reagent/impure/fermiTox diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index a07c5f7a2a..23d506a00f 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -32,6 +32,7 @@ name = "Adminordrazine" description = "It's magic. We don't have to explain it." color = "#ffffff" + chemical_flags = REAGENT_ALL_PROCESS can_synth = FALSE taste_description = "badmins" value = REAGENT_VALUE_GLORIOUS @@ -56,7 +57,7 @@ mytray.visible_message("Nothing happens...") /datum/reagent/medicine/adminordrazine/on_mob_life(mob/living/carbon/M) - M.reagents.remove_all_type(/datum/reagent/toxin, 5*REM, 0, 1) + M.reagents.remove_all_type(/datum/reagent/toxin, 5*REAGENTS_EFFECT_MULTIPLIER, 0, 1) M.setCloneLoss(0, 0) M.setOxyLoss(0, 0) M.radiation = 0 @@ -103,6 +104,7 @@ name = "Synaptizine" description = "Increases resistance to stuns as well as reducing drowsiness and hallucinations." color = "#FF00FF" + chemical_flags = REAGENT_ALL_PROCESS pH = 4 /datum/reagent/medicine/synaptizine/on_mob_life(mob/living/carbon/M) @@ -121,6 +123,7 @@ name = "Diphen-Synaptizine" description = "Reduces drowsiness, hallucinations, and Histamine from body." color = "#EC536D" // rgb: 236, 83, 109 + chemical_flags = REAGENT_ALL_PROCESS pH = 5.2 value = REAGENT_VALUE_COMMON @@ -140,6 +143,7 @@ name = "Inacusiate" description = "Instantly restores all hearing to the patient, but does not cure deafness." color = "#6600FF" // rgb: 100, 165, 255 + chemical_flags = REAGENT_ALL_PROCESS pH = 2 value = 10 @@ -152,6 +156,7 @@ description = "A chemical mixture with almost magical healing powers. Its main limitation is that the patient's body temperature must be under 270K for it to metabolise correctly." color = "#0000C8" taste_description = "sludge" + chemical_flags = REAGENT_ALL_PROCESS pH = 11 value = REAGENT_VALUE_COMMON @@ -183,6 +188,7 @@ color = "#0000C8" taste_description = "muscle" metabolization_rate = 1.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS pH = 13 value = REAGENT_VALUE_COMMON @@ -199,6 +205,7 @@ description = "A mixture of cryoxadone and slime jelly, that apparently inverses the requirement for its activation." color = "#f7832a" taste_description = "spicy jelly" + chemical_flags = REAGENT_ALL_PROCESS pH = 12 value = REAGENT_VALUE_UNCOMMON @@ -232,6 +239,7 @@ description = "A powder derived from fish toxin, Rezadone can effectively treat genetic damage as well as restoring minor wounds. Overdose will cause intense nausea and minor toxin damage." reagent_state = SOLID color = "#669900" // rgb: 102, 153, 0 + chemical_flags = REAGENT_ALL_PROCESS overdose_threshold = 30 taste_description = "fish" pH = 12.2 @@ -265,6 +273,7 @@ description = "Spaceacillin will prevent a patient from conventionally spreading any diseases they are currently infected with. Also reduces infection in serious burns." color = "#f2f2f2" metabolization_rate = 0.1 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS pH = 8.1 //Goon Chems. Ported mainly from Goonstation. Easily mixable (or not so easily) and provide a variety of effects. @@ -299,7 +308,7 @@ ..() /datum/reagent/medicine/silver_sulfadiazine/on_mob_life(mob/living/carbon/M) - M.adjustFireLoss(-2*REM, 0) + M.adjustFireLoss(-2*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 @@ -309,7 +318,7 @@ . = 1 /datum/reagent/medicine/silver_sulfadiazine/overdose_process(mob/living/M) - M.adjustFireLoss(2*REM, 0) + M.adjustFireLoss(2*REAGENTS_EFFECT_MULTIPLIER, 0) var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER) if(L) L.applyOrganDamage(1) @@ -328,15 +337,15 @@ /datum/reagent/medicine/oxandrolone/on_mob_life(mob/living/carbon/M) if(M.getFireLoss() > 25) - M.adjustFireLoss(-4*REM, 0) //Twice as effective as silver sulfadiazine for severe burns + M.adjustFireLoss(-4*REAGENTS_EFFECT_MULTIPLIER, 0) //Twice as effective as silver sulfadiazine for severe burns else - M.adjustFireLoss(-0.5*REM, 0) //But only a quarter as effective for more minor ones + M.adjustFireLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER, 0) //But only a quarter as effective for more minor ones ..() . = 1 /datum/reagent/medicine/oxandrolone/overdose_process(mob/living/M) if(M.getFireLoss()) //It only makes existing burns worse - M.adjustFireLoss(4.5*REM, 0) // it's going to be healing either 4 or 0.5 + M.adjustFireLoss(4.5*REAGENTS_EFFECT_MULTIPLIER, 0) // it's going to be healing either 4 or 0.5 . = 1 ..() @@ -371,7 +380,7 @@ G.use(reac_volume) /datum/reagent/medicine/styptic_powder/on_mob_life(mob/living/carbon/M) - M.adjustBruteLoss(-2*REM, 0) + M.adjustBruteLoss(-2*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 @@ -381,7 +390,7 @@ . = 1 /datum/reagent/medicine/styptic_powder/overdose_process(mob/living/M) - M.adjustBruteLoss(2*REM, 0) + M.adjustBruteLoss(2*REAGENTS_EFFECT_MULTIPLIER, 0) var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER) if(L) L.applyOrganDamage(1) @@ -394,7 +403,10 @@ reagent_state = LIQUID color = "#DCDCDC" metabolization_rate = 0.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS overdose_threshold = 60 + boiling_point = T0C+100 + gas = GAS_H2O taste_description = "sweetness and salt" var/extra_regen = 0.25 // in addition to acting as temporary blood, also add this much to their actual blood per tick var/last_added = 0 @@ -403,8 +415,8 @@ /datum/reagent/medicine/salglu_solution/on_mob_life(mob/living/carbon/human/M) if(prob(33)) - M.adjustBruteLoss(-0.5*REM, 0) - M.adjustFireLoss(-0.5*REM, 0) + M.adjustBruteLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustFireLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER, 0) . = TRUE if((HAS_TRAIT(M, TRAIT_NOMARROW))) return ..() @@ -414,10 +426,10 @@ if(M.functional_blood() < maximum_reachable) //Can only up to double your effective blood level. var/new_blood_level = min(volume * 5, maximum_reachable) last_added = new_blood_level - M.adjust_integration_blood(new_blood_level + (extra_regen * REM)) + M.adjust_integration_blood(new_blood_level + (extra_regen * REAGENTS_EFFECT_MULTIPLIER)) if(prob(33)) - M.adjustBruteLoss(-0.5*REM, 0) - M.adjustFireLoss(-0.5*REM, 0) + M.adjustBruteLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustFireLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER, 0) . = TRUE ..() @@ -436,8 +448,8 @@ holder.add_reagent(/datum/reagent/consumable/sugar, 1) holder.remove_reagent(/datum/reagent/medicine/salglu_solution, 0.5) if(prob(33)) - M.adjustBruteLoss(0.5*REM, 0) - M.adjustFireLoss(0.5*REM, 0) + M.adjustBruteLoss(0.5*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustFireLoss(0.5*REAGENTS_EFFECT_MULTIPLIER, 0) . = TRUE ..() @@ -452,9 +464,9 @@ /datum/reagent/medicine/mine_salve/on_mob_life(mob/living/carbon/C) C.hal_screwyhud = SCREWYHUD_HEALTHY - C.adjustBruteLoss(-0.25*REM, 0) - C.adjustFireLoss(-0.25*REM, 0) - C.adjustStaminaLoss(-0.5*REM, 0) + C.adjustBruteLoss(-0.25*REAGENTS_EFFECT_MULTIPLIER, 0) + C.adjustFireLoss(-0.25*REAGENTS_EFFECT_MULTIPLIER, 0) + C.adjustStaminaLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER, 0) ..() return TRUE @@ -527,11 +539,12 @@ reagent_state = LIQUID color = "#000000" metabolization_rate = 0.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS taste_description = "ash" pH = 5 /datum/reagent/medicine/charcoal/on_mob_life(mob/living/carbon/M) - M.adjustToxLoss(-2*REM, 0) + M.adjustToxLoss(-2*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 for(var/A in M.reagents.reagent_list) var/datum/reagent/R = A @@ -551,18 +564,18 @@ var/healing = 0.5 /datum/reagent/medicine/omnizine/on_mob_life(mob/living/carbon/M) - M.adjustToxLoss(-healing*REM, 0) - M.adjustOxyLoss(-healing*REM, 0) - M.adjustBruteLoss(-healing*REM, 0) - M.adjustFireLoss(-healing*REM, 0) + M.adjustToxLoss(-healing*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustOxyLoss(-healing*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustBruteLoss(-healing*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustFireLoss(-healing*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 /datum/reagent/medicine/omnizine/overdose_process(mob/living/M) - M.adjustToxLoss(1.5*REM, 0) - M.adjustOxyLoss(1.5*REM, 0) - M.adjustBruteLoss(1.5*REM, 0) - M.adjustFireLoss(1.5*REM, 0) + M.adjustToxLoss(1.5*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustOxyLoss(1.5*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustBruteLoss(1.5*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustFireLoss(1.5*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 @@ -578,6 +591,7 @@ reagent_state = LIQUID color = "#19C832" metabolization_rate = 0.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS taste_description = "acid" pH = 1.5 @@ -587,7 +601,7 @@ if(R != src) M.reagents.remove_reagent(R.type,2.5) if(M.health > 20) - M.adjustToxLoss(2.5*REM, 0) + M.adjustToxLoss(2.5*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 ..() @@ -597,6 +611,7 @@ reagent_state = LIQUID color = "#14FF3C" metabolization_rate = 2 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS pH = 12 //It's a reducing agent /datum/reagent/medicine/potass_iodide/on_mob_life(mob/living/carbon/M) @@ -610,6 +625,7 @@ reagent_state = LIQUID color = "#003153" // RGB 0, 49, 83 metabolization_rate = 0.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS pH = 8.9 value = REAGENT_VALUE_COMMON //uncraftable @@ -624,13 +640,14 @@ reagent_state = LIQUID color = "#E6FFF0" metabolization_rate = 0.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS pH = 1 //One of the best buffers, NEVERMIND! value = REAGENT_VALUE_UNCOMMON var/healtoxinlover = FALSE /datum/reagent/medicine/pen_acid/on_mob_life(mob/living/carbon/M) M.radiation -= max(M.radiation-RAD_MOB_SAFE, 0)/50 - M.adjustToxLoss(-2*REM, 0, healtoxinlover) + M.adjustToxLoss(-2*REAGENTS_EFFECT_MULTIPLIER, 0, healtoxinlover) for(var/A in M.reagents.reagent_list) var/datum/reagent/R = A if(R != src) @@ -659,15 +676,15 @@ /datum/reagent/medicine/sal_acid/on_mob_life(mob/living/carbon/M) if(M.getBruteLoss() > 25) - M.adjustBruteLoss(-4*REM, 0) //Twice as effective as styptic powder for severe bruising + M.adjustBruteLoss(-4*REAGENTS_EFFECT_MULTIPLIER, 0) //Twice as effective as styptic powder for severe bruising else - M.adjustBruteLoss(-0.5*REM, 0) //But only a quarter as effective for more minor ones + M.adjustBruteLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER, 0) //But only a quarter as effective for more minor ones ..() . = 1 /datum/reagent/medicine/sal_acid/overdose_process(mob/living/M) if(M.getBruteLoss()) //It only makes existing bruises worse - M.adjustBruteLoss(4.5*REM, 0) // it's going to be healing either 4 or 0.5 + M.adjustBruteLoss(4.5*REAGENTS_EFFECT_MULTIPLIER, 0) // it's going to be healing either 4 or 0.5 . = 1 ..() @@ -676,11 +693,12 @@ description = "Rapidly restores oxygen deprivation as well as preventing more of it to an extent. Causes jittering." reagent_state = LIQUID color = "#00FFFF" + boiling_point = 300 metabolization_rate = 0.25 * REAGENTS_METABOLISM pH = 2 /datum/reagent/medicine/salbutamol/on_mob_life(mob/living/carbon/M) - M.adjustOxyLoss(-3*REM, 0) + M.adjustOxyLoss(-3*REAGENTS_EFFECT_MULTIPLIER, 0) if(M.losebreath >= 4) M.losebreath -= 2 M.Jitter(5) @@ -696,11 +714,11 @@ pH = 11 /datum/reagent/medicine/perfluorodecalin/on_mob_life(mob/living/carbon/human/M) - M.adjustOxyLoss(-12*REM, 0) + M.adjustOxyLoss(-12*REAGENTS_EFFECT_MULTIPLIER, 0) M.silent = max(M.silent, 5) if(prob(33)) - M.adjustBruteLoss(-0.5*REM, 0) - M.adjustFireLoss(-0.5*REM, 0) + M.adjustBruteLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustFireLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER, 0) ..() return TRUE @@ -731,8 +749,8 @@ // to_chat(M, span_notice("Your hands spaz out and you drop what you were holding!")) // M.Jitter(10) - M.AdjustAllImmobility(-20 * REM * delta_time) - M.adjustStaminaLoss(-1 * REM * delta_time, FALSE) + M.AdjustAllImmobility(-20 * REAGENTS_EFFECT_MULTIPLIER * delta_time) + M.adjustStaminaLoss(-1 * REAGENTS_EFFECT_MULTIPLIER * delta_time, FALSE) ..() return TRUE @@ -754,28 +772,28 @@ /datum/reagent/medicine/ephedrine/addiction_act_stage1(mob/living/M) if(prob(33)) - M.adjustToxLoss(2*REM, 0) + M.adjustToxLoss(2*REAGENTS_EFFECT_MULTIPLIER, 0) M.losebreath += 2 . = 1 ..() /datum/reagent/medicine/ephedrine/addiction_act_stage2(mob/living/M) if(prob(33)) - M.adjustToxLoss(3*REM, 0) + M.adjustToxLoss(3*REAGENTS_EFFECT_MULTIPLIER, 0) M.losebreath += 3 . = 1 ..() /datum/reagent/medicine/ephedrine/addiction_act_stage3(mob/living/M) if(prob(33)) - M.adjustToxLoss(4*REM, 0) + M.adjustToxLoss(4*REAGENTS_EFFECT_MULTIPLIER, 0) M.losebreath += 4 . = 1 ..() /datum/reagent/medicine/ephedrine/addiction_act_stage4(mob/living/M) if(prob(33)) - M.adjustToxLoss(5*REM, 0) + M.adjustToxLoss(5*REAGENTS_EFFECT_MULTIPLIER, 0) M.losebreath += 5 . = 1 ..() @@ -841,7 +859,7 @@ /datum/reagent/medicine/morphine/addiction_act_stage2(mob/living/M) if(prob(33)) M.drop_all_held_items() - M.adjustToxLoss(1*REM, 0) + M.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 M.Dizzy(3) M.Jitter(3) @@ -850,7 +868,7 @@ /datum/reagent/medicine/morphine/addiction_act_stage3(mob/living/M) if(prob(33)) M.drop_all_held_items() - M.adjustToxLoss(2*REM, 0) + M.adjustToxLoss(2*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 M.Dizzy(4) M.Jitter(4) @@ -859,7 +877,7 @@ /datum/reagent/medicine/morphine/addiction_act_stage4(mob/living/M) if(prob(33)) M.drop_all_held_items() - M.adjustToxLoss(3*REM, 0) + M.adjustToxLoss(3*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 M.Dizzy(5) M.Jitter(5) @@ -871,6 +889,7 @@ reagent_state = LIQUID color = "#FFFFFF" metabolization_rate = 0.25 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS taste_description = "dull toxin" pH = 10 @@ -907,10 +926,10 @@ /datum/reagent/medicine/atropine/on_mob_life(mob/living/carbon/M) if(M.health < 0) - M.adjustToxLoss(-2*REM, 0) - M.adjustBruteLoss(-2*REM, 0) - M.adjustFireLoss(-2*REM, 0) - M.adjustOxyLoss(-5*REM, 0) + M.adjustToxLoss(-2*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustBruteLoss(-2*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustFireLoss(-2*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustOxyLoss(-5*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 M.losebreath = 0 if(prob(20)) @@ -919,7 +938,7 @@ ..() /datum/reagent/medicine/atropine/overdose_process(mob/living/M) - M.adjustToxLoss(0.5*REM, 0) + M.adjustToxLoss(0.5*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 M.Dizzy(1) M.Jitter(1) @@ -936,16 +955,16 @@ /datum/reagent/medicine/epinephrine/on_mob_life(mob/living/carbon/M) if(M.health < 0) - M.adjustToxLoss(-0.5*REM, 0) - M.adjustBruteLoss(-0.5*REM, 0) - M.adjustFireLoss(-0.5*REM, 0) + M.adjustToxLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustBruteLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustFireLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER, 0) if(M.oxyloss > 35) M.setOxyLoss(35, 0) if(M.losebreath >= 4) M.losebreath -= 2 if(M.losebreath < 0) M.losebreath = 0 - M.adjustStaminaLoss(-0.5*REM, 0) + M.adjustStaminaLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 if(prob(20)) M.AdjustAllImmobility(-20, 0) @@ -954,8 +973,8 @@ /datum/reagent/medicine/epinephrine/overdose_process(mob/living/M) if(prob(33)) - M.adjustStaminaLoss(2.5*REM, 0) - M.adjustToxLoss(1*REM, 0) + M.adjustStaminaLoss(2.5*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER, 0) M.losebreath++ . = 1 ..() @@ -966,6 +985,7 @@ reagent_state = LIQUID color = "#A0E85E" metabolization_rate = 0.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS taste_description = "magnets" pH = 0 value = REAGENT_VALUE_RARE @@ -980,11 +1000,11 @@ if(M.stat == DEAD) if(M.suiciding || M.hellbound) //they are never coming back M.visible_message("[M]'s body does not react...") - return + return ..() if(M.getBruteLoss() >= 100 || M.getFireLoss() >= 100 || HAS_TRAIT(M, TRAIT_HUSK)) //body is too damaged to be revived M.visible_message("[M]'s body convulses a bit, and then falls still once more.") M.do_jitter_animation(10) - return + return ..() else M.visible_message("[M]'s body starts convulsing!") M.notify_ghost_cloning(source = M) @@ -996,33 +1016,37 @@ if(iscarbon(M)) var/mob/living/carbon/C = M if(!(C.dna && C.dna.species && (NOBLOOD in C.dna.species.species_traits))) - C.blood_volume = max(C.blood_volume, BLOOD_VOLUME_NORMAL*C.blood_ratio) //so you don't instantly re-die from a lack of blood - for(var/organ in C.internal_organs) - var/obj/item/organ/O = organ - if(O.damage > O.maxHealth/2) - O.setOrganDamage(O.maxHealth/2) //so you don't instantly die from organ damage when being revived + C.blood_volume = max(C.blood_volume, BLOOD_VOLUME_BAD*C.blood_ratio) //so you don't instantly re-die from a lack of blood. You'll still need help if you had none though. + var/obj/item/organ/heart/H = C.getorganslot(ORGAN_SLOT_HEART) + if(H && H.organ_flags & ORGAN_FAILING) + H.applyOrganDamage(-15) + for(var/obj/item/organ/O as anything in C.internal_organs) + if(O.organ_flags & ORGAN_FAILING) + O.applyOrganDamage(-5) M.adjustOxyLoss(-20, 0) M.adjustToxLoss(-20, 0) M.updatehealth() + if(iscarbon(M)) + var/mob/living/carbon/C = M + if(!C.can_revive(ignore_timelimit = TRUE, maximum_brute_dam = 100, maximum_fire_dam = 100, ignore_heart = TRUE)) + return var/tplus = world.time - M.timeofdeath if(M.revive()) M.grab_ghost() M.emote("gasp") log_combat(M, M, "revived", src) var/list/policies = CONFIG_GET(keyed_list/policy) - var/timelimit = CONFIG_GET(number/defib_cmd_time_limit) * 10 //the config is in seconds, not deciseconds - var/late = timelimit && (tplus > timelimit) - var/policy = late? policies[POLICYCONFIG_ON_DEFIB_LATE] : policies[POLICYCONFIG_ON_DEFIB_INTACT] + var/policy = policies[POLICYCONFIG_ON_DEFIB_LATE] //Always causes memory loss due to the nature of strange reagent. if(policy) to_chat(M, policy) - M.log_message("revived using strange reagent, [tplus] deciseconds from time of death, considered [late? "late" : "memory-intact"] revival under configured policy limits.", LOG_GAME) + M.log_message("revived using strange reagent, [tplus] deciseconds from time of death, considered late revival due to usage of strange reagent.", LOG_GAME) ..() /datum/reagent/medicine/strange_reagent/on_mob_life(mob/living/carbon/M) - M.adjustBruteLoss(0.5*REM, 0) - M.adjustFireLoss(0.5*REM, 0) + M.adjustBruteLoss(0.5*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustFireLoss(0.5*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 @@ -1030,10 +1054,12 @@ name = "Mannitol" description = "Efficiently restores brain damage." color = "#DCDCFF" + taste_description = "sweetness" pH = 10.4 + chemical_flags = REAGENT_ALL_PROCESS /datum/reagent/medicine/mannitol/on_mob_life(mob/living/carbon/C) - C.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2*REM) + C.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2*REAGENTS_EFFECT_MULTIPLIER) if(prob(10)) C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC) ..() @@ -1042,6 +1068,7 @@ name = "Neurine" description = "Reacts with neural tissue, helping reform damaged connections. Can cure minor traumas." color = "#EEFF8F" + chemical_flags = REAGENT_ALL_PROCESS /datum/reagent/medicine/neurine/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(!(method == INJECT)) @@ -1057,6 +1084,13 @@ else B.gain_trauma_type(BRAIN_TRAUMA_SPECIAL) +/datum/reagent/medicine/neurine/reaction_obj(obj/O, reac_volume) + if(istype(O, /obj/item/dullahan_head)) + var/obj/item/dullahan_head/head = O + if(head.B) + head.B.applyOrganDamage(-20) + if(head.owner) + head.owner.cure_trauma_type(resilience = TRAUMA_RESILIENCE_SURGERY) /datum/reagent/medicine/neurine/on_mob_life(mob/living/carbon/C) if(holder.has_reagent(/datum/reagent/consumable/ethanol/neurotoxin)) @@ -1071,6 +1105,7 @@ color = "#5096C8" taste_description = "acid" pH = 2 + chemical_flags = REAGENT_ALL_PROCESS /datum/reagent/medicine/mutadone/on_mob_life(mob/living/carbon/M) M.jitteriness = 0 @@ -1091,8 +1126,8 @@ M.drowsyness = 0 M.slurring = 0 M.confused = 0 - M.reagents.remove_all_type(/datum/reagent/consumable/ethanol, 3*REM, 0, 1) - M.adjustToxLoss(-0.2*REM, 0) + M.reagents.remove_all_type(/datum/reagent/consumable/ethanol, 3*REAGENTS_EFFECT_MULTIPLIER, 0, 1) + M.adjustToxLoss(-0.2*REAGENTS_EFFECT_MULTIPLIER, 0) if(ishuman(M)) var/mob/living/carbon/human/H = M H.drunkenness = max(H.drunkenness - 10, 0) @@ -1106,6 +1141,7 @@ metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 60 pH = 8.7 + chemical_flags = REAGENT_ALL_PROCESS value = REAGENT_VALUE_RARE /datum/reagent/medicine/stimulants/on_mob_metabolize(mob/living/L) @@ -1120,20 +1156,20 @@ /datum/reagent/medicine/stimulants/on_mob_life(mob/living/carbon/M) if(M.health < 50 && M.health > 0) - M.adjustOxyLoss(-1*REM, FALSE) - M.adjustToxLoss(-1*REM, FALSE) - M.adjustBruteLoss(-1*REM, FALSE) - M.adjustFireLoss(-1*REM, FALSE) + M.adjustOxyLoss(-1*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustToxLoss(-1*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustBruteLoss(-1*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustFireLoss(-1*REAGENTS_EFFECT_MULTIPLIER, FALSE) M.AdjustAllImmobility(-60, FALSE) M.AdjustUnconscious(-60, FALSE) - M.adjustStaminaLoss(-20*REM, FALSE) + M.adjustStaminaLoss(-20*REAGENTS_EFFECT_MULTIPLIER, FALSE) ..() . = 1 /datum/reagent/medicine/stimulants/overdose_process(mob/living/M) if(prob(33)) - M.adjustStaminaLoss(2.5*REM, FALSE) - M.adjustToxLoss(1*REM, FALSE) + M.adjustStaminaLoss(2.5*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER, FALSE) M.losebreath++ . = 1 ..() @@ -1144,6 +1180,7 @@ reagent_state = LIQUID color = "#FFFFF0" metabolization_rate = 0.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS pH = 6.7 /datum/reagent/medicine/insulin/on_mob_life(mob/living/carbon/M) @@ -1162,12 +1199,12 @@ pH = 5 /datum/reagent/medicine/bicaridine/on_mob_life(mob/living/carbon/M) - M.adjustBruteLoss(-2*REM, FALSE) + M.adjustBruteLoss(-2*REAGENTS_EFFECT_MULTIPLIER, FALSE) ..() . = 1 /datum/reagent/medicine/bicaridine/overdose_process(mob/living/M) - M.adjustBruteLoss(4*REM, FALSE) + M.adjustBruteLoss(4*REAGENTS_EFFECT_MULTIPLIER, FALSE) ..() . = 1 @@ -1180,12 +1217,12 @@ pH = 9.7 /datum/reagent/medicine/dexalin/on_mob_life(mob/living/carbon/M) - M.adjustOxyLoss(-2*REM, FALSE) + M.adjustOxyLoss(-2*REAGENTS_EFFECT_MULTIPLIER, FALSE) ..() . = 1 /datum/reagent/medicine/dexalin/overdose_process(mob/living/M) - M.adjustOxyLoss(4*REM, FALSE) + M.adjustOxyLoss(4*REAGENTS_EFFECT_MULTIPLIER, FALSE) ..() . = 1 @@ -1198,12 +1235,12 @@ pH = 9 /datum/reagent/medicine/kelotane/on_mob_life(mob/living/carbon/M) - M.adjustFireLoss(-2*REM, FALSE) + M.adjustFireLoss(-2*REAGENTS_EFFECT_MULTIPLIER, FALSE) ..() . = 1 /datum/reagent/medicine/kelotane/overdose_process(mob/living/M) - M.adjustFireLoss(4*REM, FALSE) + M.adjustFireLoss(4*REAGENTS_EFFECT_MULTIPLIER, FALSE) ..() . = 1 @@ -1217,14 +1254,14 @@ pH = 10 /datum/reagent/medicine/antitoxin/on_mob_life(mob/living/carbon/M) - M.adjustToxLoss(-2*REM, FALSE) + M.adjustToxLoss(-2*REAGENTS_EFFECT_MULTIPLIER, FALSE) for(var/datum/reagent/toxin/R in M.reagents.reagent_list) M.reagents.remove_reagent(R.type,1) ..() . = 1 /datum/reagent/medicine/antitoxin/overdose_process(mob/living/M) - M.adjustToxLoss(4*REM, FALSE) // End result is 2 toxin loss taken, because it heals 2 and then removes 4. + M.adjustToxLoss(4*REAGENTS_EFFECT_MULTIPLIER, FALSE) // End result is 2 toxin loss taken, because it heals 2 and then removes 4. ..() . = 1 @@ -1255,18 +1292,18 @@ /datum/reagent/medicine/tricordrazine/on_mob_life(mob/living/carbon/M) if(prob(80)) - M.adjustBruteLoss(-1*REM, FALSE) - M.adjustFireLoss(-1*REM, FALSE) - M.adjustOxyLoss(-1*REM, FALSE) - M.adjustToxLoss(-1*REM, FALSE) + M.adjustBruteLoss(-1*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustFireLoss(-1*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustOxyLoss(-1*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustToxLoss(-1*REAGENTS_EFFECT_MULTIPLIER, FALSE) . = 1 ..() /datum/reagent/medicine/tricordrazine/overdose_process(mob/living/M) - M.adjustToxLoss(2*REM, FALSE) - M.adjustOxyLoss(2*REM, FALSE) - M.adjustBruteLoss(2*REM, FALSE) - M.adjustFireLoss(2*REM, FALSE) + M.adjustToxLoss(2*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustOxyLoss(2*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustBruteLoss(2*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustFireLoss(2*REAGENTS_EFFECT_MULTIPLIER, FALSE) ..() . = 1 @@ -1279,10 +1316,10 @@ value = REAGENT_VALUE_COMMON /datum/reagent/medicine/regen_jelly/on_mob_life(mob/living/carbon/M) - M.adjustBruteLoss(-1.5*REM, FALSE) - M.adjustFireLoss(-1.5*REM, FALSE) - M.adjustOxyLoss(-1.5*REM, FALSE) - M.adjustToxLoss(-1.5*REM, 0, TRUE) //heals TOXINLOVERs + M.adjustBruteLoss(-1.5*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustFireLoss(-1.5*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustOxyLoss(-1.5*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustToxLoss(-1.5*REAGENTS_EFFECT_MULTIPLIER, 0, TRUE) //heals TOXINLOVERs . = 1 ..() @@ -1292,16 +1329,17 @@ reagent_state = SOLID color = "#555555" pH = 11 + chemical_flags = REAGENT_ALL_PROCESS value = REAGENT_VALUE_EXCEPTIONAL /datum/reagent/medicine/syndicate_nanites/on_mob_life(mob/living/carbon/M) - M.adjustBruteLoss(-5*REM, FALSE) //A ton of healing - this is a 50 telecrystal investment. - M.adjustFireLoss(-5*REM, FALSE) + M.adjustBruteLoss(-5*REAGENTS_EFFECT_MULTIPLIER, FALSE) //A ton of healing - this is a 50 telecrystal investment. + M.adjustFireLoss(-5*REAGENTS_EFFECT_MULTIPLIER, FALSE) M.adjustOxyLoss(-15, FALSE) - M.adjustToxLoss(-5*REM, FALSE) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -15*REM) - M.adjustCloneLoss(-3*REM, FALSE) - M.adjustStaminaLoss(-25*REM,FALSE) + M.adjustToxLoss(-5*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -15*REAGENTS_EFFECT_MULTIPLIER) + M.adjustCloneLoss(-3*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustStaminaLoss(-25*REAGENTS_EFFECT_MULTIPLIER,FALSE) if(M.blood_volume < (BLOOD_VOLUME_NORMAL*M.blood_ratio)) M.adjust_integration_blood(40) // blood fall out man bad ..() @@ -1313,16 +1351,17 @@ reagent_state = SOLID color = "#555555" pH = 11 + chemical_flags = REAGENT_ALL_PROCESS value = REAGENT_VALUE_VERY_RARE /datum/reagent/medicine/lesser_syndicate_nanites/on_mob_life(mob/living/carbon/M) - M.adjustBruteLoss(-2*REM, FALSE) - M.adjustFireLoss(-2*REM, FALSE) - M.adjustOxyLoss(-5*REM, FALSE) - M.adjustToxLoss(-2*REM, FALSE) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -5*REM) - M.adjustCloneLoss(-1.25*REM, FALSE) - M.adjustStaminaLoss(-4*REM,FALSE) + M.adjustBruteLoss(-2*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustFireLoss(-2*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustOxyLoss(-5*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustToxLoss(-2*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -5*REAGENTS_EFFECT_MULTIPLIER) + M.adjustCloneLoss(-1.25*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustStaminaLoss(-4*REAGENTS_EFFECT_MULTIPLIER,FALSE) if(M.blood_volume < (BLOOD_VOLUME_NORMAL*M.blood_ratio)) M.adjust_integration_blood(3) ..() @@ -1330,7 +1369,7 @@ /datum/reagent/medicine/neo_jelly name = "Neo Jelly" - description = "Gradually regenerates all types of damage, without harming slime anatomy.Can OD" + description = "Gradually regenerates all types of damage, without harming slime anatomy. Can overdose." reagent_state = LIQUID metabolization_rate = 1 * REAGENTS_METABOLISM color = "#91D865" @@ -1340,17 +1379,17 @@ value = REAGENT_VALUE_UNCOMMON /datum/reagent/medicine/neo_jelly/on_mob_life(mob/living/carbon/M) - M.adjustBruteLoss(-1.5*REM, FALSE) - M.adjustFireLoss(-1.5*REM, FALSE) - M.adjustOxyLoss(-1.5*REM, FALSE) - M.adjustToxLoss(-1.5*REM, 0, TRUE) //heals TOXINLOVERs + M.adjustBruteLoss(-1.5*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustFireLoss(-1.5*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustOxyLoss(-1.5*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustToxLoss(-1.5*REAGENTS_EFFECT_MULTIPLIER, 0, TRUE) //heals TOXINLOVERs . = 1 ..() /datum/reagent/medicine/neo_jelly/overdose_process(mob/living/M) - M.adjustOxyLoss(2.6*REM, FALSE) - M.adjustBruteLoss(3.5*REM, FALSE) - M.adjustFireLoss(3.5*REM, FALSE) + M.adjustOxyLoss(2.6*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustBruteLoss(3.5*REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustFireLoss(3.5*REAGENTS_EFFECT_MULTIPLIER, FALSE) ..() . = 1 @@ -1378,13 +1417,13 @@ myseed.adjust_production(-round(chems.get_reagent_amount(src.type) * 0.5)) /datum/reagent/medicine/earthsblood/on_mob_life(mob/living/carbon/M) - M.adjustBruteLoss(-3 * REM, FALSE) - M.adjustFireLoss(-3 * REM, FALSE) - M.adjustOxyLoss(-15 * REM, FALSE) - M.adjustToxLoss(-3 * REM, FALSE, TRUE) //Heals TOXINLOVERS - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * REM, 150) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that! - M.adjustCloneLoss(-1 * REM, FALSE) - M.adjustStaminaLoss(-13 * REM, FALSE) + M.adjustBruteLoss(-3 * REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustFireLoss(-3 * REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustOxyLoss(-15 * REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustToxLoss(-3 * REAGENTS_EFFECT_MULTIPLIER, FALSE, TRUE) //Heals TOXINLOVERS + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * REAGENTS_EFFECT_MULTIPLIER, 150) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that! + M.adjustCloneLoss(-1 * REAGENTS_EFFECT_MULTIPLIER, FALSE) + M.adjustStaminaLoss(-13 * REAGENTS_EFFECT_MULTIPLIER, FALSE) M.jitteriness = min(max(0, M.jitteriness + 3), 30) M.druggy = min(max(0, M.druggy + 10), 15) //See above ..() @@ -1392,7 +1431,7 @@ /datum/reagent/medicine/earthsblood/overdose_process(mob/living/M) M.hallucination = min(max(0, M.hallucination + 5), 60) - M.adjustToxLoss(8 * REM, FALSE, TRUE) //Hurts TOXINLOVERS + M.adjustToxLoss(8 * REAGENTS_EFFECT_MULTIPLIER, FALSE, TRUE) //Hurts TOXINLOVERS ..() . = 1 @@ -1414,8 +1453,8 @@ if (M.hallucination >= 5) M.hallucination -= 5 if(prob(20)) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REM, 50) - M.adjustStaminaLoss(2.5*REM, 0) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REAGENTS_EFFECT_MULTIPLIER, 50) + M.adjustStaminaLoss(2.5*REAGENTS_EFFECT_MULTIPLIER, 0) ..() return TRUE @@ -1434,9 +1473,9 @@ return TRUE /datum/reagent/medicine/lavaland_extract/overdose_process(mob/living/M) - M.adjustBruteLoss(3*REM, 0) - M.adjustFireLoss(3*REM, 0) - M.adjustToxLoss(3*REM, 0) + M.adjustBruteLoss(3*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustFireLoss(3*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustToxLoss(3*REAGENTS_EFFECT_MULTIPLIER, 0) ..() return TRUE @@ -1447,13 +1486,14 @@ color = "#C1151D" overdose_threshold = 30 value = REAGENT_VALUE_VERY_RARE + chemical_flags = REAGENT_ALL_PROCESS /datum/reagent/medicine/changelingadrenaline/on_mob_life(mob/living/carbon/metabolizer, delta_time, times_fired) ..() - metabolizer.AdjustAllImmobility(-20 * REM * delta_time) - metabolizer.adjustStaminaLoss(-10 * REM * delta_time, 0) - metabolizer.Jitter(10 * REM * delta_time) - metabolizer.Dizzy(10 * REM * delta_time) + metabolizer.AdjustAllImmobility(-20 * REAGENTS_EFFECT_MULTIPLIER * delta_time) + metabolizer.adjustStaminaLoss(-30 * REAGENTS_EFFECT_MULTIPLIER * delta_time, 0) + metabolizer.Jitter(10 * REAGENTS_EFFECT_MULTIPLIER * delta_time) + metabolizer.Dizzy(10 * REAGENTS_EFFECT_MULTIPLIER * delta_time) return TRUE /datum/reagent/medicine/changelingadrenaline/on_mob_metabolize(mob/living/L) @@ -1471,15 +1511,16 @@ L.Jitter(0) /datum/reagent/medicine/changelingadrenaline/overdose_process(mob/living/metabolizer, delta_time, times_fired) - metabolizer.adjustToxLoss(1 * REM * delta_time, 0) + metabolizer.adjustToxLoss(1 * REAGENTS_EFFECT_MULTIPLIER * delta_time, 0) ..() return TRUE /datum/reagent/medicine/changelinghaste name = "Changeling Haste" - description = "Drastically increases movement speed, but deals toxin damage." + description = "Drastically increases movement speed." color = "#AE151D" metabolization_rate = 2.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS /datum/reagent/medicine/changelinghaste/on_mob_metabolize(mob/living/L) ..() @@ -1489,18 +1530,13 @@ L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/changelinghaste) ..() -/datum/reagent/medicine/changelinghaste/on_mob_life(mob/living/carbon/metabolizer, delta_time, times_fired) - metabolizer.adjustToxLoss(2 * REM * delta_time, 0) - ..() - return TRUE - - /datum/reagent/medicine/corazone // Heart attack code will not do damage if corazone is present // because it's SPACE MAGIC ASPIRIN name = "Corazone" description = "A medication used to treat pain, fever, and inflammation, along with heart attacks." color = "#F5F5F5" + chemical_flags = REAGENT_ALL_PROCESS self_consuming = TRUE pH = 12.5 @@ -1552,7 +1588,7 @@ overdose_threshold = overdose_threshold + rand(-10,10)/10 // for extra fun M.AdjustAllImmobility(-5, 0) M.AdjustUnconscious(-5, 0) - M.adjustStaminaLoss(-1*REM, 0) + M.adjustStaminaLoss(-1*REAGENTS_EFFECT_MULTIPLIER, 0) M.Jitter(1) metabolization_rate = 0.01 * REAGENTS_METABOLISM * rand(5,20) // randomizes metabolism between 0.02 and 0.08 per tick . = TRUE @@ -1572,8 +1608,8 @@ if(prob(50)) M.losebreath++ if(41 to 80) - M.adjustOxyLoss(0.1*REM, 0) - M.adjustStaminaLoss(0.1*REM, 0) + M.adjustOxyLoss(0.1*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustStaminaLoss(0.1*REAGENTS_EFFECT_MULTIPLIER, 0) M.jitteriness = min(M.jitteriness+1, 20) M.stuttering = min(M.stuttering+1, 20) M.Dizzy(10) @@ -1585,12 +1621,12 @@ M.DefaultCombatKnockdown(20, 1, 0) // you should be in a bad spot at this point unless epipen has been used if(81) to_chat(M, "You feel too exhausted to continue!") // at this point you will eventually die unless you get charcoal - M.adjustOxyLoss(0.1*REM, 0) - M.adjustStaminaLoss(0.1*REM, 0) + M.adjustOxyLoss(0.1*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustStaminaLoss(0.1*REAGENTS_EFFECT_MULTIPLIER, 0) if(82 to INFINITY) M.Sleeping(100, 0, TRUE) - M.adjustOxyLoss(1.5*REM, 0) - M.adjustStaminaLoss(1.5*REM, 0) + M.adjustOxyLoss(1.5*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustStaminaLoss(1.5*REAGENTS_EFFECT_MULTIPLIER, 0) ..() return TRUE @@ -1600,6 +1636,7 @@ reagent_state = LIQUID color = "#07E79E" metabolization_rate = 0.25 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS overdose_threshold = 30 pH = 9.12 value = REAGENT_VALUE_COMMON @@ -1635,6 +1672,7 @@ reagent_state = SOLID color = "#FFFFD0" metabolization_rate = 1.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS value = REAGENT_VALUE_UNCOMMON /datum/reagent/medicine/silibinin/on_mob_life(mob/living/carbon/M) @@ -1648,6 +1686,7 @@ reagent_state = SOLID color = "#9423FF" metabolization_rate = 0.25 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS overdose_threshold = 50 taste_description = "numbing bitterness" value = REAGENT_VALUE_RARE @@ -1677,10 +1716,11 @@ taste_mult = 4 can_synth = FALSE overdose_threshold = 30 + chemical_flags = REAGENT_ALL_PROCESS value = REAGENT_VALUE_UNCOMMON // while it's 'rare', it can be milked from the wisdom cow /datum/reagent/medicine/liquid_wisdom/on_mob_life(mob/living/carbon/C) //slightly stronger mannitol, from the wisdom cow - C.adjustOrganLoss(ORGAN_SLOT_BRAIN, -3*REM) + C.adjustOrganLoss(ORGAN_SLOT_BRAIN, -3*REAGENTS_EFFECT_MULTIPLIER) if(prob(20)) C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC) if(prob(3)) @@ -1694,6 +1734,7 @@ reagent_state = LIQUID color = "#bb2424" metabolization_rate = 0.25 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS overdose_threshold = 20 /// How much base clotting we do per bleeding wound, multiplied by the below number for each bleeding wound var/clot_rate = 0.25 @@ -1748,18 +1789,68 @@ reagent_state = LIQUID color = "#D7C9C6" metabolization_rate = 0.2 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS overdose_threshold = 30 /datum/reagent/medicine/system_cleaner/on_mob_life(mob/living/carbon/M) . = ..() if(HAS_TRAIT(M, TRAIT_ROBOTIC_ORGANISM)) - M.adjustToxLoss(-0.2, toxins_type = TOX_SYSCORRUPT) + M.adjustToxLoss(-0.4*REAGENTS_EFFECT_MULTIPLIER, toxins_type = TOX_SYSCORRUPT) else - M.adjustToxLoss(0.5) + M.adjustToxLoss(0.5*REAGENTS_EFFECT_MULTIPLIER) + . = 1 /datum/reagent/medicine/system_cleaner/overdose_process(mob/living/carbon/M) . = ..() if(HAS_TRAIT(M, TRAIT_ROBOTIC_ORGANISM)) - M.adjustToxLoss(0.4, toxins_type = TOX_SYSCORRUPT) //inverts its positive effect on overdose, for organics it's just more toxic + M.adjustToxLoss(0.8*REAGENTS_EFFECT_MULTIPLIER, toxins_type = TOX_SYSCORRUPT) //inverts its positive effect on overdose, for organics it's just more toxic else - M.adjustToxLoss(0.5) + M.adjustToxLoss(0.5*REAGENTS_EFFECT_MULTIPLIER) + . = 1 + +/datum/reagent/medicine/limb_regrowth + name = "Carcinisoprojection Jelly" + description = "Also known as \"limb regrowth jelly\", this crabby looking xenobiological jelly will rapidly regrow any missing limbs someone has at the cost of some of their blood. Do not overdose." + taste_description = "salty slime" + color = "#EF5428" //like cooked crab! + reagent_state = LIQUID + overdose_threshold = 65 //it takes more than one bluespace syringe to overdose someone with this given how nasty the OD is. + value = REAGENT_VALUE_RARE + +/datum/reagent/medicine/limb_regrowth/reaction_mob(mob/living/carbon/C, method=TOUCH, reac_volume) + . = ..() + if(!.) + return + if(method == TOUCH) //as funny as it would be to have this hurled at someone, nah. + return + var/vol = reac_volume + C.reagents.get_reagent_amount(/datum/reagent/medicine/limb_regrowth) + if(vol < 5) //need at least 5 units. + return + var/list/limbs_to_heal = C.get_missing_limbs(exclude_head = TRUE) + if(limbs_to_heal.len < 1) //nothing happens if they already got all limbs. + return + if(HAS_TRAIT(C, TRAIT_ROBOTIC_ORGANISM)) //sorry synths, consider a visit to the roboticist. dunno how to justify regrowing robolimbs. + return + else if(ishuman(C) && !(HAS_BONE in C.dna?.species?.species_traits)) //boneless have little trouble with the limb chemical. + C.visible_message("[C] suddenly regrows \his limbs!", + "You suddenly regrow your limbs, sensation and all!") + else //boneful beings get to scream. + C.visible_message("[C]'s body lets off a grotesque squelching, bone crunching sound as \his limbs grow back rapidly!", + "Your body emits a grotesque squelching, bone crunching sound as your limbs grow back rapidly! \ + With the sensation of your regained limbs, also comes pain!", + "You hear a grotsque squelching noise and the sound of crunching bones.") + playsound(C, 'sound/magic/demon_consume.ogg', 50, 1) + SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "painful_limb_regrowth", /datum/mood_event/painful_limb_regrowth) + C.emote("scream") + C.regenerate_limbs(excluded_limbs = list(BODY_ZONE_HEAD)) //would be a little funky for dullahans if they suddenly sprouted a head. + C.blood_volume = max(C.blood_volume - 30*limbs_to_heal.len,0) + //lose blood for each limb that was regained. + //10 units less expensive than slime limb regrowth, but doesn't check for low blood like the ability, so it could be dangerous. + to_chat(C,"You feel like this ordeal of your limbs regrowing has made you a little paler... as well as made you feel a little thirsty.") + //hint at the blood loss. (paler is a common symptom depicted in-game of low blood, but dehydration is another symptom of low blood.) + + +/datum/reagent/medicine/limb_regrowth/overdose_start(mob/living/M) + M.ForceContractDisease(new /datum/disease/crabcancer, FALSE, TRUE) //it is now, time for crab. + ..() + . = 1 diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index bf93c933de..601ac81f0f 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -1,6 +1,7 @@ /datum/reagent/blood - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null,"quirks"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "bloodblend" = BLEND_MULTIPLY, "blood_type"= null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null,"quirks"=null) name = "Blood" + chemical_flags = REAGENT_ALL_PROCESS value = REAGENT_VALUE_UNCOMMON // $$$ blood ""donations"" $$$ color = BLOOD_COLOR_HUMAN // rgb: 200, 0, 0 description = "Blood from some creature." @@ -58,7 +59,7 @@ var/blood_id = C.get_blood_id() if((blood_id in GLOB.blood_reagent_types) && !HAS_TRAIT(C, TRAIT_NOMARROW)) if(!data || !(data["blood_type"] in get_safe_blood(C.dna.blood_type))) //we only care about bloodtype here because this is where the poisoning should be - C.adjustToxLoss(rand(2,8)*REM, TRUE, TRUE) //forced to ensure people don't use it to gain beneficial toxin as slime person + C.adjustToxLoss(rand(2,8)*REAGENTS_EFFECT_MULTIPLIER, TRUE, TRUE) //forced to ensure people don't use it to gain beneficial toxin as slime person ..() /datum/reagent/blood/reaction_obj(obj/O, volume) @@ -80,6 +81,7 @@ B.blood_DNA["color"] = data["bloodcolor"] else B.blood_DNA["color"] = BlendRGB(B.blood_DNA["color"], data["bloodcolor"]) + B.blood_DNA["blendmode"] = data["bloodblend"] if(B.reagents) B.reagents.add_reagent(type, reac_volume) B.update_icon() @@ -147,7 +149,7 @@ . += D /datum/reagent/blood/synthetics - data = list("donor"=null,"viruses"=null,"blood_DNA"="REPLICATED", "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"="REPLICATED", "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "bloodblend" = BLEND_MULTIPLY, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) name = "Synthetic Blood" description = "A synthetically produced imitation of blood." taste_description = "oil" @@ -155,7 +157,7 @@ value = REAGENT_VALUE_NONE /datum/reagent/blood/jellyblood - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "bloodblend" = BLEND_DEFAULT, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) name = "Slime Jelly Blood" description = "A gooey semi-liquid produced from one of the deadliest lifeforms in existence. SO REAL." color = BLOOD_COLOR_SLIME @@ -164,7 +166,7 @@ pH = 4 /datum/reagent/blood/tomato - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "bloodblend" = BLEND_MULTIPLY, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) name = "Tomato Blood" description = "This highly resembles blood, but it doesnt actually function like it, resembling more ketchup, with a more blood-like consistency." taste_description = "sap" //Like tree sap? @@ -175,10 +177,10 @@ if(prob(10)) if(M.dna?.species?.exotic_bloodtype != "GEL") to_chat(M, "Your insides are burning!") - M.adjustToxLoss(rand(20,60)*REM, 0) + M.adjustToxLoss(rand(20,60)*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 else if(prob(40) && isjellyperson(M)) - M.heal_bodypart_damage(2*REM) + M.heal_bodypart_damage(2*REAGENTS_EFFECT_MULTIPLIER) . = 1 ..() @@ -188,7 +190,7 @@ description = "You don't even want to think about what's in here." taste_description = "gross iron" shot_glass_icon_state = "shotglassred" - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= "O+","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "bloodblend" = BLEND_MULTIPLY, "blood_type"= "O+","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) pH = 7.45 /datum/reagent/liquidgibs/xeno @@ -196,7 +198,7 @@ color = BLOOD_COLOR_XENO taste_description = "blended heresy" shot_glass_icon_state = "shotglassgreen" - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_XENO, "blood_type"="X*","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_XENO, "bloodblend" = BLEND_MULTIPLY, "blood_type"="X*","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) pH = 2.5 /datum/reagent/liquidgibs/slime @@ -204,25 +206,26 @@ color = BLOOD_COLOR_SLIME taste_description = "slime" shot_glass_icon_state = "shotglassgreen" - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "bloodblend" = BLEND_DEFAULT, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) pH = 4 /datum/reagent/liquidgibs/synth name = "Synthetic sludge" color = BLOOD_COLOR_SYNTHETIC taste_description = "jellied plastic" - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "bloodblend" = BLEND_MULTIPLY, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) /datum/reagent/liquidgibs/oil name = "Hydraulic sludge" color = BLOOD_COLOR_OIL taste_description = "chunky burnt oil" - data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_OIL, "blood_type"="HF","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_OIL, "bloodblend" = BLEND_MULTIPLY, "blood_type"="HF","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) pH = 9.75 /datum/reagent/vaccine //data must contain virus type name = "Vaccine" + chemical_flags = REAGENT_ALL_PROCESS color = "#C81040" // rgb: 200, 16, 64 taste_description = "slime" @@ -243,6 +246,7 @@ description = "An ubiquitous chemical substance that is composed of hydrogen and oxygen." color = "#AAAAAA77" // rgb: 170, 170, 170, 77 (alpha) taste_description = "water" + chemical_flags = REAGENT_ALL_PROCESS overdose_threshold = 150 //Imagine drinking a gallon of water var/cooling_temperature = 2 glass_icon_state = "glass_clear" @@ -262,24 +266,27 @@ /datum/reagent/water/reaction_turf(turf/open/T, reac_volume) if (!istype(T)) return - var/CT = cooling_temperature + if(holder?.chem_temp > T0C + 100) + T.atmos_spawn_air("[GAS_H2O]=[reac_volume/molarity];TEMP=[holder.chem_temp]") + else + var/CT = cooling_temperature - if(reac_volume >= 5) - T.MakeSlippery(TURF_WET_WATER, 10 SECONDS, min(reac_volume*1.5 SECONDS, 60 SECONDS)) + if(reac_volume >= 5) + T.MakeSlippery(TURF_WET_WATER, 10 SECONDS, min(reac_volume*1.5 SECONDS, 60 SECONDS)) - for(var/mob/living/simple_animal/slime/M in T) - M.apply_water() + for(var/mob/living/simple_animal/slime/M in T) + M.apply_water() - var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T) - if(hotspot && !isspaceturf(T)) - if(T.air) - var/datum/gas_mixture/G = T.air - G.set_temperature(max(min(G.return_temperature()-(CT*1000),G.return_temperature()/CT),TCMB)) - G.react(src) - qdel(hotspot) - var/obj/effect/acid/A = (locate(/obj/effect/acid) in T) - if(A) - A.acid_level = max(A.acid_level - reac_volume*50, 0) + var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T) + if(hotspot && !isspaceturf(T)) + if(T.air) + var/datum/gas_mixture/G = T.air + G.set_temperature(max(min(G.return_temperature()-(CT*1000),G.return_temperature()/CT),TCMB)) + G.react(src) + qdel(hotspot) + var/obj/effect/acid/A = (locate(/obj/effect/acid) in T) + if(A) + A.acid_level = max(A.acid_level - reac_volume*50, 0) /* * Water reaction to an object @@ -339,6 +346,7 @@ name = "Holy Water" description = "Water blessed by some deity." color = "#E0E8EF" // rgb: 224, 232, 239 + chemical_flags = REAGENT_ALL_PROCESS glass_icon_state = "glass_clear" glass_name = "glass of holy water" glass_desc = "A glass of holy water." @@ -474,6 +482,7 @@ name = "Hell Water" description = "YOUR FLESH! IT BURNS!" taste_description = "burning" + chemical_flags = REAGENT_ALL_PROCESS value = REAGENT_VALUE_VERY_RARE /datum/reagent/hellwater/on_mob_life(mob/living/carbon/M) @@ -533,11 +542,14 @@ /datum/reagent/lube name = "Space Lube" description = "Lubricant is a substance introduced between two moving surfaces to reduce the friction and wear between them. giggity." + chemical_flags = REAGENT_ALL_PROCESS color = "#009CA8" // rgb: 0, 156, 168 taste_description = "cherry" // by popular demand + boiling_point = 330 var/lube_kind = TURF_WET_LUBE ///What kind of slipperiness gets added to turfs. /datum/reagent/lube/reaction_turf(turf/open/T, reac_volume) + ..() if (!istype(T)) return if(reac_volume >= 1) @@ -644,6 +656,7 @@ description = "A humanizing toxin." color = "#5EFF3B" //RGB: 94, 255, 59 metabolization_rate = INFINITY //So it instantly removes all of itself + chemical_flags = REAGENT_ALL_PROCESS taste_description = "slime" value = REAGENT_VALUE_RARE var/datum/species/race = /datum/species/human @@ -808,6 +821,7 @@ /datum/reagent/slime_toxin name = "Slime Mutation Toxin" description = "A toxin that turns organic material into slime." + chemical_flags = REAGENT_ALL_PROCESS color = "#5EFF3B" //RGB: 94, 255, 59 taste_description = "slime" metabolization_rate = 0.2 @@ -847,6 +861,7 @@ description = "This toxin will rapidly change the DNA of human beings. Commonly used by Syndicate spies and assassins in need of an emergency ID change." color = "#5EFF3B" //RGB: 94, 255, 59 metabolization_rate = INFINITY + chemical_flags = REAGENT_ALL_PROCESS taste_description = "slime" value = REAGENT_VALUE_RARE @@ -873,6 +888,7 @@ name = "Gluttony's Blessing" description = "An advanced corruptive toxin produced by something terrible." color = "#5EFF3B" //RGB: 94, 255, 59 + chemical_flags = REAGENT_ALL_PROCESS can_synth = FALSE taste_description = "decay" value = REAGENT_VALUE_GLORIOUS @@ -899,20 +915,11 @@ description = "A colorless, odorless gas. Grows on trees but is still pretty valuable." reagent_state = GAS color = "#808080" // rgb: 128, 128, 128 + gas = GAS_O2 + boiling_point = 90.188 taste_mult = 0 // oderless and tasteless pH = 9.2//It's acutally a huge range and very dependant on the chemistry but pH is basically a made up var in it's implementation anyways - -/datum/reagent/oxygen/reaction_obj(obj/O, reac_volume) - if((!O) || (!reac_volume)) - return 0 - var/temp = holder ? holder.chem_temp : T20C - O.atmos_spawn_air("o2=[reac_volume/2];TEMP=[temp]") - -/datum/reagent/oxygen/reaction_turf(turf/open/T, reac_volume) - if(istype(T)) - var/temp = holder ? holder.chem_temp : T20C - T.atmos_spawn_air("o2=[reac_volume/2];TEMP=[temp]") - return + molarity = 2 /datum/reagent/copper name = "Copper" @@ -933,26 +940,18 @@ name = "Nitrogen" description = "A colorless, odorless, tasteless gas. A simple asphyxiant that can silently displace vital oxygen." reagent_state = GAS + gas = GAS_N2 + boiling_point = 77.355 color = "#808080" // rgb: 128, 128, 128 taste_mult = 0 - - -/datum/reagent/nitrogen/reaction_obj(obj/O, reac_volume) - if((!O) || (!reac_volume)) - return 0 - var/temp = holder ? holder.chem_temp : T20C - O.atmos_spawn_air("n2=[reac_volume/2];TEMP=[temp]") - -/datum/reagent/nitrogen/reaction_turf(turf/open/T, reac_volume) - if(istype(T)) - var/temp = holder ? holder.chem_temp : T20C - T.atmos_spawn_air("n2=[reac_volume/2];TEMP=[temp]") - return + molarity = 2 /datum/reagent/hydrogen name = "Hydrogen" description = "A colorless, odorless, nonmetallic, tasteless, highly combustible diatomic gas." reagent_state = GAS + gas = GAS_HYDROGEN + boiling_point = 20.271 color = "#808080" // rgb: 128, 128, 128 taste_mult = 0 pH = 0.1//Now I'm stuck in a trap of my own design. Maybe I should make -ve pHes? (not 0 so I don't get div/0 errors) @@ -1005,9 +1004,10 @@ name = "Chlorine" description = "A pale yellow gas that's well known as an oxidizer. While it forms many harmless molecules in its elemental form it is far from harmless." reagent_state = GAS - color = "#808080" // rgb: 128, 128, 128 + color = "#c0c0a0" // rgb: 192, 192, 160 taste_description = "chlorine" pH = 7.4 + boiling_point = 239.11 // You're an idiot for thinking that one of the most corrosive and deadly gasses would be beneficial /datum/reagent/chlorine/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray, mob/user) @@ -1019,7 +1019,7 @@ mytray.adjustWeeds(-rand(1,3)) /datum/reagent/chlorine/on_mob_life(mob/living/carbon/M) - M.take_bodypart_damage(1*REM, 0, 0, 0) + M.take_bodypart_damage(1*REAGENTS_EFFECT_MULTIPLIER, 0, 0, 0) . = 1 ..() @@ -1041,7 +1041,7 @@ mytray.adjustWeeds(-rand(1,4)) /datum/reagent/fluorine/on_mob_life(mob/living/carbon/M) - M.adjustToxLoss(1*REM, 0) + M.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 ..() @@ -1086,6 +1086,7 @@ /datum/reagent/radium name = "Radium" description = "Radium is an alkaline earth metal. It is extremely radioactive." + chemical_flags = REAGENT_ALL_PROCESS reagent_state = SOLID color = "#C7C7C7" // rgb: 199,199,199 taste_description = "the colour blue and regret" @@ -1098,7 +1099,7 @@ mytray.adjustToxic(round(chems.get_reagent_amount(src.type) * 1)) /datum/reagent/radium/on_mob_life(mob/living/carbon/M) - M.apply_effect(2*REM/M.metabolism_efficiency,EFFECT_IRRADIATE,0) + M.apply_effect(2*REAGENTS_EFFECT_MULTIPLIER/M.metabolism_efficiency,EFFECT_IRRADIATE,0) ..() /datum/reagent/radium/reaction_turf(turf/T, reac_volume) @@ -1112,6 +1113,7 @@ /datum/reagent/space_cleaner/sterilizine name = "Sterilizine" description = "Sterilizes wounds in preparation for surgery." + chemical_flags = REAGENT_ALL_PROCESS color = "#e6f1f5" // rgb: 200, 165, 220 taste_description = "bitterness" pH = 10.5 @@ -1138,6 +1140,7 @@ reagent_state = SOLID taste_description = "iron" pH = 6 + chemical_flags = REAGENT_ALL_PROCESS overdose_threshold = 30 color = "#c2391d" material = /datum/material/iron @@ -1190,6 +1193,7 @@ /datum/reagent/uranium name ="Uranium" description = "A silvery-white metallic chemical element in the actinide series, weakly radioactive." + chemical_flags = REAGENT_ALL_PROCESS reagent_state = SOLID color = "#B8B8C0" // rgb: 184, 184, 192 taste_description = "the inside of a reactor" @@ -1219,6 +1223,7 @@ /datum/reagent/bluespace name = "Bluespace Dust" description = "A dust composed of microscopic bluespace crystals, with minor space-warping properties." + chemical_flags = REAGENT_ALL_PROCESS reagent_state = SOLID color = "#0000CC" taste_description = "fizzling blue" @@ -1245,6 +1250,7 @@ /datum/reagent/telecrystal name = "Telecrystal Dust" description = "A blood-red dust comprised of something that was much more useful when it was intact." + chemical_flags = REAGENT_ALL_PROCESS //Sure? reagent_state = SOLID color = "#660000" // rgb: 102, 0, 0. taste_description = "contraband" @@ -1269,12 +1275,21 @@ name = "Welding fuel" description = "Required for welders. Flamable." color = "#660000" // rgb: 102, 0, 0 + chemical_flags = REAGENT_ALL_PROCESS taste_description = "gross metal" glass_icon_state = "dr_gibb_glass" glass_name = "glass of welder fuel" glass_desc = "Unless you're an industrial tool, this is probably not safe for consumption." pH = 4 + boiling_point = 400 +/datum/reagent/fuel/define_gas() + var/datum/gas/G = ..() + G.enthalpy = 227400 + G.fire_burn_rate = 2 / 5 + G.fire_products = list(GAS_CO2 = 2, GAS_H2O = 1) + G.fire_temperature = T0C+300 + return G /datum/reagent/fuel/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with welding fuel to make them easy to ignite! if(method == TOUCH || method == VAPOR) @@ -1292,7 +1307,10 @@ description = "A compound used to clean things. Now with 50% more sodium hypochlorite!" color = "#A5F0EE" // rgb: 165, 240, 238 taste_description = "sourness" + boiling_point = T0C+50 pH = 5.5 + molarity = 1 + condensation_amount = MOLES_GAS_VISIBLE_STEP /datum/reagent/space_cleaner/reaction_obj(obj/O, reac_volume) if(istype(O, /obj/effect/decal/cleanable) || istype(O, /obj/item/projectile/bullet/reusable/foam_dart) || istype(O, /obj/item/ammo_casing/caseless/foam_dart)) @@ -1304,6 +1322,7 @@ O.clean_blood() /datum/reagent/space_cleaner/reaction_turf(turf/T, reac_volume) + ..() if(reac_volume >= 1) T.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) @@ -1357,6 +1376,7 @@ name = "EZ Clean" description = "A powerful, acidic cleaner sold by Waffle Co. Affects organic matter while leaving other objects unaffected." metabolization_rate = 1.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS taste_description = "acid" pH = 2 value = REAGENT_VALUE_RARE @@ -1398,7 +1418,7 @@ /datum/reagent/impedrezene/on_mob_life(mob/living/carbon/M) M.jitteriness = max(M.jitteriness-5,0) if(prob(80)) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REAGENTS_EFFECT_MULTIPLIER) if(prob(50)) M.drowsyness = max(M.drowsyness, 3) if(prob(10)) @@ -1470,6 +1490,8 @@ name = "Ammonia" description = "A caustic substance commonly used in fertilizer or household cleaners." reagent_state = GAS + gas = GAS_AMMONIA + boiling_point = 239.81 color = "#404030" // rgb: 64, 64, 48 taste_description = "mordant" pH = 11.6 @@ -1483,13 +1505,29 @@ myseed.adjust_yield(1) myseed.adjust_instability(1) +/datum/reagent/ammonia/reaction_mob(mob/living/M, method=TOUCH, reac_volume, touch_protection) + if(method == VAPOR) + M.adjustOrganLoss(ORGAN_SLOT_LUNGS, ((100-touch_protection)/100)*reac_volume*REAGENTS_EFFECT_MULTIPLIER * 0.25) + if(prob(reac_volume)) + to_chat(M, "Your lungs hurt!") + return ..() + /datum/reagent/diethylamine name = "Diethylamine" description = "A secondary amine, mildly corrosive." color = "#604030" // rgb: 96, 64, 48 taste_description = "iron" + boiling_point = 328 pH = 12 +/datum/reagent/diethylamine/define_gas() + var/datum/gas/G = ..() + G.fire_burn_rate = 1 / 6 + G.fire_products = list(GAS_H2O = 4, GAS_AMMONIA = 1, GAS_CO2 = 4) + G.enthalpy = -131000 + G.fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + return G + // This is more bad ass, and pests get hurt by the corrosive nature of it, not the plant. The new trade off is it culls stability. /datum/reagent/diethylamine/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray, mob/user) . = ..() @@ -1506,40 +1544,23 @@ description = "A gas commonly produced by burning carbon fuels. You're constantly producing this in your lungs." color = "#B0B0B0" // rgb : 192, 192, 192 taste_description = "something unknowable" + boiling_point = 195.68 // technically sublimation, not boiling, but same deal + molarity = 5 + gas = GAS_CO2 pH = 6 -/datum/reagent/carbondioxide/reaction_obj(obj/O, reac_volume) - if((!O) || (!reac_volume)) - return 0 - var/temp = holder ? holder.chem_temp : T20C - O.atmos_spawn_air("co2=[reac_volume/5];TEMP=[temp]") - -/datum/reagent/carbondioxide/reaction_turf(turf/open/T, reac_volume) - if(istype(T)) - var/temp = holder ? holder.chem_temp : T20C - T.atmos_spawn_air("co2=[reac_volume/5];TEMP=[temp]") - return - /datum/reagent/nitrous_oxide name = "Nitrous Oxide" description = "A potent oxidizer used as fuel in rockets and as an anaesthetic during surgery." reagent_state = LIQUID metabolization_rate = 1.5 * REAGENTS_METABOLISM color = "#808080" + boiling_point = 184.67 + molarity = 5 + gas = GAS_NITROUS taste_description = "sweetness" pH = 5.8 -/datum/reagent/nitrous_oxide/reaction_obj(obj/O, reac_volume) - if((!O) || (!reac_volume)) - return 0 - var/temp = holder ? holder.chem_temp : T20C - O.atmos_spawn_air("n2o=[reac_volume/5];TEMP=[temp]") - -/datum/reagent/nitrous_oxide/reaction_turf(turf/open/T, reac_volume) - if(istype(T)) - var/temp = holder ? holder.chem_temp : T20C - T.atmos_spawn_air("n2o=[reac_volume/5];TEMP=[temp]") - /datum/reagent/nitrous_oxide/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(method == VAPOR) M.drowsyness += max(round(reac_volume, 1), 2) @@ -1558,8 +1579,11 @@ name = "Stimulum" description = "An unstable experimental gas that greatly increases the energy of those that inhale it" reagent_state = GAS + gas = GAS_STIMULUM metabolization_rate = 1.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS color = "E1A116" + boiling_point = 150 taste_description = "sourness" value = REAGENT_VALUE_EXCEPTIONAL @@ -1574,7 +1598,7 @@ ..() /datum/reagent/stimulum/on_mob_life(mob/living/carbon/M) - M.adjustStaminaLoss(-2*REM, 0) + M.adjustStaminaLoss(-2*REAGENTS_EFFECT_MULTIPLIER, 0) current_cycle++ holder.remove_reagent(type, 0.99) //Gives time for the next tick of life(). . = TRUE //Update status effects. @@ -1583,9 +1607,11 @@ name = "Nitryl" description = "A highly reactive gas that makes you feel faster" reagent_state = GAS + gas = GAS_NITRYL metabolization_rate = REAGENTS_METABOLISM - color = "90560B" + color = "#90560B" taste_description = "burning" + boiling_point = 294.3 pH = 2 value = REAGENT_VALUE_VERY_RARE @@ -1687,7 +1713,7 @@ /datum/reagent/plantnutriment/on_mob_life(mob/living/carbon/M) if(prob(tox_prob)) - M.adjustToxLoss(1*REM, 0) + M.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 ..() @@ -1792,8 +1818,14 @@ reagent_state = LIQUID color = "#b37740" taste_description = "chemicals" + gas = GAS_BROMINE + boiling_point = 332 pH = 7.8 +/datum/reagent/bromine/on_mob_life(mob/living/carbon/C) + C.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2, 99) + ..() + /datum/reagent/phenol name = "Phenol" description = "An aromatic ring of carbon with a hydroxyl group. A useful precursor to some medicines, but has no healing properties on its own." @@ -1823,10 +1855,20 @@ reagent_state = LIQUID taste_description = "solvent"//It's neutral though..? color = "#e6e6e6" + boiling_point = 329.2 + +/datum/reagent/acetone/define_gas() + var/datum/gas/G = ..() + G.fire_burn_rate = 1 / 4 + G.fire_products = list(GAS_H2O = 3, GAS_CO2 = 3) + G.enthalpy = -217100 + G.fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + return G /datum/reagent/colorful_reagent name = "Colorful Reagent" description = "Thoroughly sample the rainbow." + chemical_flags = REAGENT_ALL_PROCESS reagent_state = LIQUID color = "#FFFF00" var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d11141","#00b159","#00aedb","#f37735","#ffc425","#008744","#0057e7","#d62d20","#ffa700") @@ -1953,6 +1995,7 @@ reagent_state = LIQUID color = "#A70FFF" taste_description = "dryness" + boiling_point = 310 pH = 10.7 value = REAGENT_VALUE_UNCOMMON @@ -2117,6 +2160,7 @@ color = "#123524" // RGB (18, 53, 36) metabolization_rate = INFINITY can_synth = FALSE + chemical_flags = REAGENT_ALL_PROCESS taste_description = "brains" pH = 0.5 value = REAGENT_VALUE_GLORIOUS @@ -2132,6 +2176,7 @@ name = "Magillitis" description = "An experimental serum which causes rapid muscular growth in Hominidae. Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas." reagent_state = LIQUID + chemical_flags = REAGENT_ALL_PROCESS color = "#00f041" value = REAGENT_VALUE_EXCEPTIONAL @@ -2145,6 +2190,7 @@ description = "A commercial chemical designed to help older men in the bedroom."//not really it just makes you a giant color = "#ff0000"//strong red. rgb 255, 0, 0 var/current_size = RESIZE_DEFAULT_SIZE + chemical_flags = REAGENT_ALL_PROCESS value = REAGENT_VALUE_COMMON taste_description = "bitterness" // apparently what viagra tastes like @@ -2216,6 +2262,7 @@ color = "#AAAAAA55" taste_description = "water" metabolization_rate = 0.25 * REAGENTS_METABOLISM + boiling_point = 325 value = REAGENT_VALUE_RARE pH = 15 @@ -2233,6 +2280,7 @@ color = "#FAFF00" taste_description = "acrid cinnamon" metabolization_rate = 0.2 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS //Sorry robot lings, but you still get this. value = REAGENT_VALUE_UNCOMMON /datum/reagent/bz_metabolites/on_mob_metabolize(mob/living/L) @@ -2320,7 +2368,7 @@ can_synth = FALSE var/datum/dna/original_dna var/reagent_ticks = 0 - chemical_flags = REAGENT_INVISIBLE + chemical_flags = REAGENT_INVISIBLE | REAGENT_ALL_PROCESS value = REAGENT_VALUE_GLORIOUS /datum/reagent/changeling_string/on_mob_metabolize(mob/living/carbon/C) @@ -2377,6 +2425,7 @@ description = "A powerful preservation agent, utilizing the preservative effects of formaldehyde with significantly less of the histamine." reagent_state = LIQUID color = "#f7685e" + chemical_flags = REAGENT_ALL_PROCESS metabolization_rate = REAGENTS_METABOLISM * 0.25 @@ -2428,6 +2477,7 @@ color = "#050096" // rgb: 5, 0, 150 taste_mult = 0 // oderless and tasteless metabolization_rate = 0.1 * REAGENTS_METABOLISM //20 times as long, so it's actually viable to use + chemical_flags = REAGENT_ALL_PROCESS var/time_multiplier = 1 MINUTES //1 minute per unit of gravitum on objects. Seems overpowered, but the whole thing is very niche /datum/reagent/gravitum/reaction_obj(obj/O, volume) @@ -2452,10 +2502,13 @@ reagent_state = LIQUID color = "#FFFFFF" // rgb: 255, 255, 255 can_synth = FALSE + // you know i wouldn't + // boiling_point = T0C + 100 nutriment_factor = 0.5 * REAGENTS_METABOLISM var/decal_path = /obj/effect/decal/cleanable/semen /datum/reagent/consumable/semen/reaction_turf(turf/T, reac_volume) + ..() if(!istype(T)) return if(reac_volume < 10) @@ -2507,6 +2560,7 @@ reagent_state = LIQUID color = "#D2FFFA" metabolization_rate = 0.75 * REAGENTS_METABOLISM // 5u (WOUND_DETERMINATION_CRITICAL) will last for ~17 ticks + chemical_flags = REAGENT_ALL_PROCESS /// Whether we've had at least WOUND_DETERMINATION_SEVERE (2.5u) of determination at any given time. No damage slowdown immunity or indication we're having a second wind if it's just a single moderate wound var/significant = FALSE self_consuming = TRUE @@ -2533,13 +2587,14 @@ var/obj/item/bodypart/wounded_part = W.limb if(wounded_part) wounded_part.heal_damage(0.25, 0.25) - M.adjustStaminaLoss(-0.25*REM) // the more wounds, the more stamina regen + M.adjustStaminaLoss(-0.25*REAGENTS_EFFECT_MULTIPLIER) // the more wounds, the more stamina regen ..() /datum/reagent/eldritch name = "Eldritch Essence" description = "Strange liquid that defies the laws of physics" taste_description = "Ag'hsj'saje'sh" + chemical_flags = REAGENT_ALL_PROCESS color = "#1f8016" /datum/reagent/eldritch/on_mob_life(mob/living/carbon/M) @@ -2624,6 +2679,7 @@ description = "A unknown red liquid, linked to healing of most moral wounds." color = "#c10000" metabolization_rate = REAGENTS_METABOLISM * 2.5 + chemical_flags = REAGENT_ALL_PROCESS /datum/reagent/red_ichor/on_mob_life(mob/living/carbon/M) M.adjustBruteLoss(-50) @@ -2641,6 +2697,7 @@ description = "A unknown green liquid, linked to healing of most internal wounds." color = "#158c00" metabolization_rate = REAGENTS_METABOLISM * 2.5 + chemical_flags = REAGENT_ALL_PROCESS /datum/reagent/green_ichor/on_mob_life(mob/living/carbon/M) M.adjustOrganLoss(ORGAN_SLOT_LUNGS, -100) @@ -2658,6 +2715,7 @@ description = "A unknown blue liquid, linked to healing the mind." color = "#0914e0" metabolization_rate = REAGENTS_METABOLISM * 2.5 + chemical_flags = REAGENT_ALL_PROCESS /datum/reagent/blue_ichor/on_mob_life(mob/living/carbon/M) M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -100) diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm index 2e05f66cf8..f2157a619e 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm @@ -2,6 +2,7 @@ /datum/reagent/thermite name = "Thermite" description = "Thermite produces an aluminothermic reaction known as a thermite reaction. Can be used to melt walls." + chemical_flags = REAGENT_ALL_PROCESS reagent_state = SOLID color = "#550000" taste_description = "sweet tasting metal" @@ -44,7 +45,12 @@ reagent_state = LIQUID color = "#FFC8C8" metabolization_rate = 4 + chemical_flags = REAGENT_ALL_PROCESS taste_description = "burning" + /* no gaseous CLF3 until i can think of a good way to get it to burn that doesn't destroy matter in mysterious ways + boiling_point = 289.4 + */ + condensation_amount = 2 value = REAGENT_VALUE_COMMON /datum/reagent/clf3/on_mob_life(mob/living/carbon/M) @@ -82,6 +88,12 @@ if(!locate(/obj/effect/hotspot) in M.loc) new /obj/effect/hotspot(M.loc) +/datum/reagent/clf3/define_gas() + var/datum/gas/G = ..() + G.enthalpy = -163200 + G.oxidation_temperature = T0C - 50 + return G + /datum/reagent/sorium name = "Sorium" description = "Sends everything flying from the detonation point." @@ -146,11 +158,21 @@ /datum/reagent/phlogiston name = "Phlogiston" description = "Catches you on fire and makes you ignite." + chemical_flags = REAGENT_ALL_PROCESS reagent_state = LIQUID color = "#FA00AF" taste_description = "burning" + boiling_point = T20C-10 value = REAGENT_VALUE_UNCOMMON +/datum/reagent/phlogiston/define_gas() + var/datum/gas/G = ..() + G.enthalpy = FIRE_PLASMA_ENERGY_RELEASED / 100 + G.fire_products = list(GAS_O2 = 0.25, GAS_METHANE = 0.75) // meanwhile this is just magic + G.fire_burn_rate = 1 + G.fire_temperature = T20C+1 + return G + /datum/reagent/phlogiston/reaction_mob(mob/living/M, method=TOUCH, reac_volume) M.adjust_fire_stacks(1) var/burndmg = max(0.3*M.fire_stacks, 0.3) @@ -168,6 +190,7 @@ /datum/reagent/napalm name = "Napalm" description = "Very flammable." + chemical_flags = REAGENT_ALL_PROCESS reagent_state = LIQUID color = "#FA00AF" taste_description = "burning" @@ -197,6 +220,7 @@ color = "#0000DC" metabolization_rate = 0.5 * REAGENTS_METABOLISM taste_description = "bitterness" + chemical_flags = REAGENT_ALL_PROCESS value = REAGENT_VALUE_COMMON /datum/reagent/cryostylane/on_mob_life(mob/living/carbon/M) //TODO: code freezing into an ice cube @@ -215,6 +239,7 @@ description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Pyrosium slowly heats all other reagents in the container." color = "#64FAC8" metabolization_rate = 0.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS taste_description = "bitterness" value = REAGENT_VALUE_COMMON @@ -230,6 +255,7 @@ reagent_state = LIQUID color = "#20324D" //RGB: 32, 50, 77 metabolization_rate = 0.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS taste_description = "charged metal" var/shock_timer = 0 value = REAGENT_VALUE_VERY_RARE @@ -281,6 +307,9 @@ taste_description = "the inside of a fire extinguisher" value = REAGENT_VALUE_UNCOMMON +/datum/reagent/firefighting_foam/define_gas() + return null + /datum/reagent/firefighting_foam/reaction_turf(turf/open/T, reac_volume) if (!istype(T)) return diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 7dd8cac452..af670c00dc 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -18,7 +18,7 @@ /datum/reagent/toxin/on_mob_life(mob/living/carbon/M) if(toxpwr) - M.adjustToxLoss(toxpwr*REM, 0) + M.adjustToxLoss(toxpwr*REAGENTS_EFFECT_MULTIPLIER, 0) . = TRUE ..() @@ -35,6 +35,7 @@ name = "Unstable mutagen" description = "Might cause unpredictable mutations. Keep away from children." color = "#00FF00" + chemical_flags = REAGENT_ALL_PROCESS toxpwr = 0 taste_description = "slime" taste_mult = 0.9 @@ -79,7 +80,7 @@ /datum/reagent/toxin/plasma/on_mob_life(mob/living/carbon/C) if(holder.has_reagent(/datum/reagent/medicine/epinephrine)) - holder.remove_reagent(/datum/reagent/medicine/epinephrine, 2*REM) + holder.remove_reagent(/datum/reagent/medicine/epinephrine, 2*REAGENTS_EFFECT_MULTIPLIER) C.adjustPlasma(20) return ..() @@ -136,10 +137,10 @@ /datum/reagent/toxin/slimejelly/on_mob_life(mob/living/carbon/M) if(prob(10)) to_chat(M, "Your insides are burning!") - M.adjustToxLoss(rand(20,60)*REM, 0) + M.adjustToxLoss(rand(20,60)*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 else if(prob(40)) - M.heal_bodypart_damage(5*REM) + M.heal_bodypart_damage(5*REAGENTS_EFFECT_MULTIPLIER) . = 1 ..() @@ -191,7 +192,7 @@ ..() /datum/reagent/toxin/zombiepowder/reaction_mob(mob/living/L, method=TOUCH, reac_volume) - L.adjustOxyLoss(0.5*REM, 0) + L.adjustOxyLoss(0.5*REAGENTS_EFFECT_MULTIPLIER, 0) if(method == INGEST) fakedeath_active = TRUE L.fakedeath(type) @@ -230,7 +231,7 @@ ..() /datum/reagent/toxin/ghoulpowder/on_mob_life(mob/living/carbon/M) - M.adjustOxyLoss(1*REM, 0) + M.adjustOxyLoss(1*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 @@ -365,7 +366,7 @@ . = 1 if(51 to INFINITY) M.Sleeping(40, 0) - M.adjustToxLoss((current_cycle - 50)*REM, 0) + M.adjustToxLoss((current_cycle - 50)*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 ..() @@ -387,7 +388,7 @@ M.Sleeping(40, 0) if(51 to INFINITY) M.Sleeping(40, 0) - M.adjustToxLoss((current_cycle - 50)*REM, 0) + M.adjustToxLoss((current_cycle - 50)*REAGENTS_EFFECT_MULTIPLIER, 0) return ..() /datum/reagent/toxin/coffeepowder @@ -437,7 +438,7 @@ value = REAGENT_VALUE_UNCOMMON /datum/reagent/toxin/staminatoxin/on_mob_life(mob/living/carbon/M) - M.adjustStaminaLoss(REM * data, 0) + M.adjustStaminaLoss(REAGENTS_EFFECT_MULTIPLIER * data, 0) data = max(data - 1, 5) ..() . = 1 @@ -448,6 +449,7 @@ reagent_state = LIQUID color = "#787878" metabolization_rate = 0.125 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS toxpwr = 0 value = REAGENT_VALUE_VERY_RARE @@ -478,14 +480,14 @@ if(4) if(prob(75)) to_chat(M, "You scratch at an itch.") - M.adjustBruteLoss(2*REM, 0) + M.adjustBruteLoss(2*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 ..() /datum/reagent/toxin/histamine/overdose_process(mob/living/M) - M.adjustOxyLoss(2*REM, 0) - M.adjustBruteLoss(2*REM, 0) - M.adjustToxLoss(2*REM, 0) + M.adjustOxyLoss(2*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustBruteLoss(2*REAGENTS_EFFECT_MULTIPLIER, 0) + M.adjustToxLoss(2*REAGENTS_EFFECT_MULTIPLIER, 0) ..() . = 1 @@ -495,6 +497,7 @@ reagent_state = LIQUID color = "#B4004B" metabolization_rate = 0.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_ALL_PROCESS toxpwr = 1 /datum/reagent/toxin/formaldehyde/on_mob_life(mob/living/carbon/M) @@ -515,7 +518,7 @@ /datum/reagent/toxin/venom/on_mob_life(mob/living/carbon/M) toxpwr = 0.2*volume - M.adjustBruteLoss((0.3*volume)*REM, 0) + M.adjustBruteLoss((0.3*volume)*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 if(prob(15)) M.reagents.add_reagent(/datum/reagent/toxin/histamine, pick(5,10)) @@ -532,9 +535,9 @@ toxpwr = 0 /datum/reagent/toxin/fentanyl/on_mob_life(mob/living/carbon/M) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3*REM, 150) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3*REAGENTS_EFFECT_MULTIPLIER, 150) if(M.toxloss <= 60) - M.adjustToxLoss(1*REM, 0) + M.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER, 0) if(current_cycle >= 18) M.Sleeping(40, 0) ..() @@ -555,7 +558,7 @@ if(prob(8)) to_chat(M, "You feel horrendously weak!") M.Stun(40, 0) - M.adjustToxLoss(2*REM, 0) + M.adjustToxLoss(2*REAGENTS_EFFECT_MULTIPLIER, 0) return ..() /datum/reagent/toxin/bad_food @@ -583,15 +586,15 @@ /datum/reagent/toxin/itching_powder/on_mob_life(mob/living/carbon/M) if(prob(15)) to_chat(M, "You scratch at your head.") - M.adjustBruteLoss(0.2*REM, 0) + M.adjustBruteLoss(0.2*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 if(prob(15)) to_chat(M, "You scratch at your leg.") - M.adjustBruteLoss(0.2*REM, 0) + M.adjustBruteLoss(0.2*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 if(prob(15)) to_chat(M, "You scratch at your arm.") - M.adjustBruteLoss(0.2*REM, 0) + M.adjustBruteLoss(0.2*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 if(prob(3)) M.reagents.add_reagent(/datum/reagent/toxin/histamine,rand(1,3)) @@ -660,7 +663,7 @@ /datum/reagent/toxin/sodium_thiopental/on_mob_life(mob/living/carbon/M) if(current_cycle >= 10) M.Sleeping(40, 0) - M.adjustStaminaLoss(10*REM, 0) + M.adjustStaminaLoss(10*REAGENTS_EFFECT_MULTIPLIER, 0) ..() return TRUE @@ -687,7 +690,7 @@ value = REAGENT_VALUE_RARE /datum/reagent/toxin/amanitin/on_mob_end_metabolize(mob/living/M) - var/toxdamage = current_cycle*3*REM + var/toxdamage = current_cycle*3*REAGENTS_EFFECT_MULTIPLIER M.log_message("has taken [toxdamage] toxin damage from amanitin toxin", LOG_ATTACK) M.adjustToxLoss(toxdamage) ..() @@ -703,7 +706,7 @@ /datum/reagent/toxin/lipolicide/on_mob_life(mob/living/carbon/M) if(M.nutrition <= NUTRITION_LEVEL_STARVING) - M.adjustToxLoss(1*REM, 0) + M.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER, 0) M.adjust_nutrition(-3) // making the chef more valuable, one meme trap at a time M.overeatduration = 0 return ..() @@ -759,7 +762,7 @@ /datum/reagent/toxin/curare/on_mob_life(mob/living/carbon/M) if(current_cycle >= 11) M.DefaultCombatKnockdown(60, 0) - M.adjustOxyLoss(1*REM, 0) + M.adjustOxyLoss(1*REAGENTS_EFFECT_MULTIPLIER, 0) . = 1 ..() @@ -869,6 +872,7 @@ description = "A strong mineral acid with the molecular formula H2SO4." color = "#00FF32" toxpwr = 1 + chemical_flags = REAGENT_ALL_PROCESS //Ever injected acid into a robot? var/acidpwr = 10 //the amount of protection removed from the armour taste_description = "acid" self_consuming = TRUE @@ -942,7 +946,7 @@ /datum/reagent/toxin/delayed/on_mob_life(mob/living/carbon/M) if(current_cycle > delay) holder.remove_reagent(type, actual_metaboliztion_rate * M.metabolism_efficiency) - M.adjustToxLoss(actual_toxpwr*REM, 0) + M.adjustToxLoss(actual_toxpwr*REAGENTS_EFFECT_MULTIPLIER, 0) if(prob(10)) M.DefaultCombatKnockdown(20, 0) . = 1 diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm index 41c0ed717e..aab46bc3e4 100644 --- a/code/modules/reagents/chemistry/recipes.dm +++ b/code/modules/reagents/chemistry/recipes.dm @@ -38,6 +38,8 @@ var/clear_conversion //bitflags for clear conversions; REACTION_CLEAR_IMPURE or REACTION_CLEAR_INVERSE var/PurityMin = 0.15 //If purity is below 0.15, it explodes too. Set to 0 to disable this. + var/is_secret = FALSE // If it should show in recipe searchers such as the bartender/chemistry PDA functions + /datum/chemical_reaction/proc/on_reaction(datum/reagents/holder, multiplier, specialreact) set waitfor = FALSE diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm index 918ccf01e5..74c7d0d3c6 100644 --- a/code/modules/reagents/chemistry/recipes/medicine.dm +++ b/code/modules/reagents/chemistry/recipes/medicine.dm @@ -371,3 +371,9 @@ id = /datum/reagent/medicine/system_cleaner results = list(/datum/reagent/medicine/system_cleaner = 4) required_reagents = list(/datum/reagent/iron = 2, /datum/reagent/oil = 2, /datum/reagent/medicine/calomel = 2, /datum/reagent/acetone = 2) + +/datum/chemical_reaction/limb_regrowth + name = "Carcinisoprojection Jelly" + id = /datum/reagent/medicine/limb_regrowth + results = list(/datum/reagent/medicine/limb_regrowth = 2) + required_reagents = list(/datum/reagent/blood = 1, /datum/reagent/slime_toxin = 1) diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm index fddff17a9d..03b0e1b715 100644 --- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm +++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm @@ -581,7 +581,7 @@ if(istype(extract)) if(extract.Uses > 0) var/mob/lastheld = get_mob_by_key(holder.my_atom.fingerprintslast) - if(lastheld && !lastheld.equip_to_slot_if_possible(extract, SLOT_HANDS, disable_warning = TRUE)) + if(lastheld && !lastheld.equip_to_slot_if_possible(extract, ITEM_SLOT_HANDS, disable_warning = TRUE)) extract.forceMove(get_turf(lastheld)) use_slime_core(holder) diff --git a/code/modules/reagents/chemistry/recipes/special.dm b/code/modules/reagents/chemistry/recipes/special.dm index ad277ef4ff..58dd37133a 100644 --- a/code/modules/reagents/chemistry/recipes/special.dm +++ b/code/modules/reagents/chemistry/recipes/special.dm @@ -54,6 +54,8 @@ GLOBAL_LIST_INIT(food_reagents, build_reagents_to_food()) //reagentid = related var/max_result_reagents = 1 var/list/possible_results = list() + is_secret = TRUE + /datum/chemical_reaction/randomized/proc/GenerateRecipe() created = world.time if(randomize_container) @@ -175,7 +177,7 @@ GLOBAL_LIST_INIT(food_reagents, build_reagents_to_food()) //reagentid = related return list() . = ..() -/obj/item/paper/secretrecipe/Initialize() +/obj/item/paper/secretrecipe/Initialize(mapload) . = ..() if(SSpersistence.initialized) UpdateInfo() diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 9b8ff7b262..aa871723a3 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -66,7 +66,7 @@ amount_per_transfer_from_this = possible_transfer_amounts[i+1] else amount_per_transfer_from_this = possible_transfer_amounts[1] - to_chat(user, "[src]'s transfer amount is now [amount_per_transfer_from_this] units.") + balloon_alert(user, "Transferring [amount_per_transfer_from_this]u") return /obj/item/reagent_containers/attack(mob/living/M, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1) @@ -88,10 +88,10 @@ return 0 return 1 -/obj/item/reagent_containers/ex_act() +/obj/item/reagent_containers/ex_act(severity, target, origin) if(reagents) for(var/datum/reagent/R in reagents.reagent_list) - R.on_ex_act() + R.on_ex_act(severity) if(!QDELETED(src)) ..() diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm index acfda85963..87349058a4 100644 --- a/code/modules/reagents/reagent_containers/blood_pack.dm +++ b/code/modules/reagents/reagent_containers/blood_pack.dm @@ -10,10 +10,10 @@ var/color_to_apply = "#FFFFFF" var/mutable_appearance/fill_overlay -/obj/item/reagent_containers/blood/Initialize() +/obj/item/reagent_containers/blood/Initialize(mapload) . = ..() if(blood_type != null) - reagents.add_reagent(/datum/reagent/blood, 200, list("donor"=null,"viruses"=null,"blood_DNA"=null,"bloodcolor"=bloodtype_to_color(blood_type), "blood_type"=blood_type,"resistances"=null,"trace_chem"=null)) + reagents.add_reagent(/datum/reagent/blood, 200, list("donor"=null,"viruses"=null,"blood_DNA"=null,"bloodcolor"=bloodtype_to_color(blood_type), "bloodblend" = BLEND_MULTIPLY, "blood_type"=blood_type,"resistances"=null,"trace_chem"=null)) update_icon() /obj/item/reagent_containers/blood/on_reagent_change(changetype) @@ -43,7 +43,7 @@ /obj/item/reagent_containers/blood/random icon_state = "random_bloodpack" -/obj/item/reagent_containers/blood/random/Initialize() +/obj/item/reagent_containers/blood/random/Initialize(mapload) icon_state = "bloodpack" blood_type = pick("A+", "A-", "B+", "B-", "O+", "O-", "L", "SY", "HF", "GEL", "BUG") return ..() diff --git a/code/modules/reagents/reagent_containers/borghypo.dm b/code/modules/reagents/reagent_containers/borghypo.dm index 3388018280..0b3e5bcf75 100644 --- a/code/modules/reagents/reagent_containers/borghypo.dm +++ b/code/modules/reagents/reagent_containers/borghypo.dm @@ -34,7 +34,7 @@ Borg Hypospray //Used as list for input() in shakers. var/list/reagent_names = list() -/obj/item/reagent_containers/borghypo/Initialize() +/obj/item/reagent_containers/borghypo/Initialize(mapload) . = ..() for(var/R in reagent_ids) diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm index be8c7fac36..47f5c94e09 100644 --- a/code/modules/reagents/reagent_containers/bottle.dm +++ b/code/modules/reagents/reagent_containers/bottle.dm @@ -8,7 +8,7 @@ possible_transfer_amounts = list(5,10,15,25,30) volume = 30 -/obj/item/reagent_containers/glass/bottle/Initialize() +/obj/item/reagent_containers/glass/bottle/Initialize(mapload) . = ..() if(!icon_state) icon_state = "bottle" @@ -159,7 +159,7 @@ icon = 'icons/obj/chemical.dmi' var/extra_reagent = null -/obj/item/reagent_containers/glass/bottle/traitor/Initialize() +/obj/item/reagent_containers/glass/bottle/traitor/Initialize(mapload) . = ..() extra_reagent = pick(/datum/reagent/toxin/polonium, /datum/reagent/toxin/histamine, /datum/reagent/toxin/formaldehyde, /datum/reagent/toxin/venom, /datum/reagent/toxin/fentanyl, /datum/reagent/toxin/cyanide) diff --git a/code/modules/reagents/reagent_containers/chem_pack.dm b/code/modules/reagents/reagent_containers/chem_pack.dm index 77d6067d3b..139a5f626f 100644 --- a/code/modules/reagents/reagent_containers/chem_pack.dm +++ b/code/modules/reagents/reagent_containers/chem_pack.dm @@ -30,8 +30,8 @@ SplashReagents(user) return else - DISABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER) - ENABLE_BITFIELD(reagents.reagents_holder_flags, DRAWABLE |INJECTABLE ) + reagents.reagents_holder_flags &= ~(OPENCONTAINER) + reagents.reagents_holder_flags |= (DRAWABLE|INJECTABLE) spillable = FALSE sealed = TRUE to_chat(user, "You seal the bag.") diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 6e1b753c32..bec2f22590 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -128,7 +128,7 @@ possible_transfer_amounts = list(5,10,15,20,25,30,50,60) container_flags = PH_WEAK|APTFT_ALTCLICK|APTFT_VERB -/obj/item/reagent_containers/glass/beaker/Initialize() +/obj/item/reagent_containers/glass/beaker/Initialize(mapload) . = ..() update_icon() @@ -298,16 +298,16 @@ flags_inv = HIDEHAIR slot_flags = ITEM_SLOT_HEAD resistance_flags = NONE - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 50) //Weak melee protection, because you can wear it on your head + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 75, ACID = 50) //Weak melee protection, because you can wear it on your head slot_equipment_priority = list( \ - SLOT_BACK, SLOT_WEAR_ID,\ - SLOT_W_UNIFORM, SLOT_WEAR_SUIT,\ - SLOT_WEAR_MASK, SLOT_HEAD, SLOT_NECK,\ - SLOT_SHOES, SLOT_GLOVES,\ - SLOT_EARS, SLOT_GLASSES,\ - SLOT_BELT, SLOT_S_STORE,\ - SLOT_L_STORE, SLOT_R_STORE,\ - SLOT_GENERC_DEXTROUS_STORAGE + ITEM_SLOT_BACK, ITEM_SLOT_ID,\ + ITEM_SLOT_ICLOTHING, ITEM_SLOT_OCLOTHING,\ + ITEM_SLOT_MASK, ITEM_SLOT_HEAD, ITEM_SLOT_NECK,\ + ITEM_SLOT_FEET, ITEM_SLOT_GLOVES,\ + ITEM_SLOT_EARS, ITEM_SLOT_EYES,\ + ITEM_SLOT_BELT, ITEM_SLOT_SUITSTORE,\ + ITEM_SLOT_LPOCKET, ITEM_SLOT_RPOCKET,\ + ITEM_SLOT_DEX_STORAGE ) container_flags = APTFT_ALTCLICK|APTFT_VERB container_HP = 1 @@ -330,11 +330,11 @@ /obj/item/reagent_containers/glass/bucket/equipped(mob/user, slot) ..() - if (slot == SLOT_HEAD) + if (slot == ITEM_SLOT_HEAD) if(reagents.total_volume) to_chat(user, "[src]'s contents spill all over you!") var/R = reagents.log_list() - log_reagent("SPLASH: [user] splashed [src] on their head via bucket/equipped(self, SLOT_HEAD) - [R]") + log_reagent("SPLASH: [user] splashed [src] on their head via bucket/equipped(self, ITEM_SLOT_HEAD) - [R]") reagents.reaction(user, TOUCH) reagents.clear_reagents() reagent_flags = NONE @@ -345,10 +345,10 @@ /obj/item/reagent_containers/glass/bucket/equip_to_best_slot(var/mob/M) if(reagents.total_volume) //If there is water in a bucket, don't quick equip it to the head - var/index = slot_equipment_priority.Find(SLOT_HEAD) - slot_equipment_priority.Remove(SLOT_HEAD) + var/index = slot_equipment_priority.Find(ITEM_SLOT_HEAD) + slot_equipment_priority.Remove(ITEM_SLOT_HEAD) . = ..() - slot_equipment_priority.Insert(index, SLOT_HEAD) + slot_equipment_priority.Insert(index, ITEM_SLOT_HEAD) return return ..() diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 143025aed1..8eff48a3f8 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -15,6 +15,16 @@ var/ignore_flags = 0 var/infinite = FALSE +/obj/item/reagent_containers/hypospray/Initialize(mapload, vol) + . = ..() + register_item_context() + +/obj/item/reagent_containers/add_item_context(obj/item/source, list/context, atom/target, mob/living/user) + . = ..() + if(iscarbon(target)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Inject") + return CONTEXTUAL_SCREENTIP_SET + /obj/item/reagent_containers/hypospray/attack_paw(mob/user) return attack_hand(user) @@ -58,6 +68,7 @@ name = "combat stimulant injector" desc = "A modified air-needle autoinjector, used by support operatives to quickly heal injuries in combat and get people back in the fight." amount_per_transfer_from_this = 10 + item_state = "combat_hypo" icon_state = "combat_hypo" volume = 100 ignore_flags = 1 // So they can heal their comrades. @@ -69,17 +80,27 @@ list_reagents = list(/datum/reagent/medicine/epinephrine = 30, /datum/reagent/medicine/omnizine = 30, /datum/reagent/medicine/leporazine = 15, /datum/reagent/medicine/atropine = 15) /obj/item/reagent_containers/hypospray/combat/nanites - desc = "A modified air-needle autoinjector for use in combat situations. Prefilled with experimental medical compounds for rapid healing." + name = "experimental combat stimulant injector" + desc = "A modified air-needle autoinjector for use in combat situations. Prefilled with experimental medical nanites and a stimulant for rapid healing and a combat boost." + item_state = "nanite_hypo" + icon_state = "nanite_hypo" volume = 100 list_reagents = list(/datum/reagent/medicine/adminordrazine/quantum_heal = 80, /datum/reagent/medicine/synaptizine = 20) -/obj/item/reagent_containers/hypospray/magillitis - name = "experimental autoinjector" - desc = "A modified air-needle autoinjector with a small single-use reservoir. It contains an experimental serum." - icon_state = "combat_hypo" - volume = 5 - reagent_flags = NONE - list_reagents = list(/datum/reagent/magillitis = 5) +/obj/item/reagent_containers/hypospray/combat/nanites/update_icon() + if(reagents.total_volume > 0) + icon_state = initial(icon_state) + else + icon_state = "[initial(icon_state)]0" + +/obj/item/reagent_containers/hypospray/combat/heresypurge + name = "holy water piercing injector" + desc = "A modified air-needle autoinjector for use in combat situations. Prefilled with 5 doses of a holy water and pacifier mixture. Not for use on your teammates." + item_state = "holy_hypo" + icon_state = "holy_hypo" + volume = 250 + list_reagents = list(/datum/reagent/water/holywater = 150, /datum/reagent/peaceborg_tire = 50, /datum/reagent/peaceborg_confuse = 50) + amount_per_transfer_from_this = 50 //MediPens @@ -136,6 +157,8 @@ /obj/item/reagent_containers/hypospray/medipen/ekit name = "emergency first-aid autoinjector" desc = "An epinephrine medipen with extra coagulant and antibiotics to help stabilize bad cuts and burns." + icon_state = "healthpen" + item_state = "healthpen" volume = 15 amount_per_transfer_from_this = 15 list_reagents = list(/datum/reagent/medicine/epinephrine = 12, /datum/reagent/medicine/coagulant = 2.5, /datum/reagent/medicine/spaceacillin = 0.5) @@ -143,15 +166,19 @@ /obj/item/reagent_containers/hypospray/medipen/blood_loss name = "hypovolemic-response autoinjector" desc = "A medipen designed to stabilize and rapidly reverse severe bloodloss." + icon_state = "hypovolemic" + item_state = "hypovolemic" volume = 15 amount_per_transfer_from_this = 15 list_reagents = list(/datum/reagent/medicine/epinephrine = 5, /datum/reagent/medicine/coagulant = 2.5, /datum/reagent/iron = 3.5, /datum/reagent/medicine/salglu_solution = 4) /obj/item/reagent_containers/hypospray/medipen/stimulants - name = "illegal stimpack medipen" - desc = "A highly illegal medipen due to its load and small injections, allow for five uses before being drained" + name = "stimpack medipen" + desc = "Contains stimulants." + icon_state = "syndipen" + item_state = "syndipen" volume = 50 - amount_per_transfer_from_this = 10 + amount_per_transfer_from_this = 50 list_reagents = list(/datum/reagent/medicine/stimulants = 50) /obj/item/reagent_containers/hypospray/medipen/stimulants/baseball @@ -166,6 +193,7 @@ name = "stimpack medipen" desc = "A rapid way to stimulate your body's adrenaline, allowing for freer movement in restrictive armor." icon_state = "stimpen" + item_state = "stimpen" volume = 20 amount_per_transfer_from_this = 20 list_reagents = list(/datum/reagent/medicine/ephedrine = 10, /datum/reagent/consumable/coffee = 10) @@ -177,20 +205,79 @@ /obj/item/reagent_containers/hypospray/medipen/morphine name = "morphine medipen" desc = "A rapid way to get you out of a tight situation and fast! You'll feel rather drowsy, though." + icon_state = "morphen" + item_state = "morphen" + volume = 10 + amount_per_transfer_from_this = 10 list_reagents = list(/datum/reagent/medicine/morphine = 10) +/obj/item/reagent_containers/hypospray/medipen/penacid + name = "pentetic acid medipen" + desc = "A autoinjector containing pentetic acid, used to reduce high levels of radiations and moderate toxins." + icon_state = "penacid" + item_state = "penacid" + volume = 10 + amount_per_transfer_from_this = 10 + list_reagents = list(/datum/reagent/medicine/pen_acid = 10) + +/obj/item/reagent_containers/hypospray/medipen/atropine + name = "atropine autoinjector" + desc = "A rapid way to save a person from a critical injury state!" + icon_state = "atropen" + item_state = "atropen" + volume = 10 + amount_per_transfer_from_this = 10 + list_reagents = list(/datum/reagent/medicine/atropine = 10) + +/obj/item/reagent_containers/hypospray/medipen/salacid + name = "salicyclic acid medipen" + desc = "A autoinjector containing salicyclic acid, used to treat severe brute damage." + icon_state = "salacid" + item_state = "salacid" + volume = 10 + amount_per_transfer_from_this = 10 + list_reagents = list(/datum/reagent/medicine/sal_acid = 10) + +/obj/item/reagent_containers/hypospray/medipen/oxandrolone + name = "oxandrolone medipen" + desc = "A autoinjector containing oxandrolone, used to treat severe burns." + icon_state = "oxapen" + item_state = "oxapen" + volume = 10 + amount_per_transfer_from_this = 10 + list_reagents = list(/datum/reagent/medicine/oxandrolone = 10) + +/obj/item/reagent_containers/hypospray/medipen/salbutamol + name = "salbutamol medipen" + desc = "A autoinjector containing salbutamol, used to heal oxygen damage quickly." + icon_state = "salpen" + item_state = "salpen" + volume = 10 + amount_per_transfer_from_this = 10 + list_reagents = list(/datum/reagent/medicine/salbutamol = 10) + /obj/item/reagent_containers/hypospray/medipen/tuberculosiscure name = "BVAK autoinjector" desc = "Bio Virus Antidote Kit autoinjector. Has a two use system for yourself, and someone else. Inject when infected." - icon_state = "stimpen" + icon_state = "tbpen" + item_state = "tbpen" volume = 60 amount_per_transfer_from_this = 30 list_reagents = list(/datum/reagent/medicine/atropine = 10, /datum/reagent/medicine/epinephrine = 10, /datum/reagent/medicine/salbutamol = 20, /datum/reagent/medicine/spaceacillin = 20) +/obj/item/reagent_containers/hypospray/medipen/tuberculosiscure/update_icon() + if(reagents.total_volume > 30) + icon_state = initial(icon_state) + else if (reagents.total_volume > 0) + icon_state = "[initial(icon_state)]1" + else + icon_state = "[initial(icon_state)]0" + /obj/item/reagent_containers/hypospray/medipen/survival name = "survival medipen" desc = "A medipen for surviving in the harshest of environments, heals and protects from environmental hazards. WARNING: Do not inject more than one pen in quick succession." - icon_state = "stimpen" + icon_state = "minepen" + item_state = "minepen" volume = 52 amount_per_transfer_from_this = 52 list_reagents = list(/datum/reagent/medicine/salbutamol = 10, /datum/reagent/medicine/leporazine = 15, /datum/reagent/medicine/neo_jelly = 15, /datum/reagent/medicine/epinephrine = 10, /datum/reagent/medicine/lavaland_extract = 2) @@ -198,16 +285,21 @@ /obj/item/reagent_containers/hypospray/medipen/firelocker name = "fire treatment medipen" desc = "A medipen that has been fulled with burn healing chemicals for personnel without advanced medical knowledge." + icon_state = "firepen" + item_state = "firepen" volume = 15 amount_per_transfer_from_this = 15 list_reagents = list(/datum/reagent/medicine/oxandrolone = 5, /datum/reagent/medicine/kelotane = 10) -/obj/item/reagent_containers/hypospray/combat/heresypurge - name = "holy water autoinjector" - desc = "A modified air-needle autoinjector for use in combat situations. Prefilled with 5 doses of a holy water mixture." - volume = 250 - list_reagents = list(/datum/reagent/water/holywater = 150, /datum/reagent/peaceborg_tire = 50, /datum/reagent/peaceborg_confuse = 50) - amount_per_transfer_from_this = 50 +/obj/item/reagent_containers/hypospray/medipen/magillitis + name = "experimental autoinjector" + desc = "A custom-frame needle injector with a small single-use reservoir, containing an experimental serum. Unlike the more common medipen frame, it cannot pierce through protective armor or hardsuits, nor can the chemical inside be extracted." + icon_state = "gorillapen" + item_state = "gorillapen" + volume = 5 + ignore_flags = 0 + reagent_flags = NONE + list_reagents = list(/datum/reagent/magillitis = 5) #define HYPO_SPRAY 0 #define HYPO_INJECT 1 @@ -288,7 +380,7 @@ quickload = TRUE penetrates = TRUE -/obj/item/hypospray/mkii/Initialize() +/obj/item/hypospray/mkii/Initialize(mapload) . = ..() if(!spawnwithvial) update_icon() @@ -296,6 +388,23 @@ if(start_vial) vial = new start_vial update_icon() + register_context() + register_item_context() + +/obj/item/hypospray/mkii/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + // Did you know that clicking something while you're holding it is the same as attack_self()? + if(vial && (held_item == src)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Remove [vial]") + LAZYSET(context[SCREENTIP_CONTEXT_CTRL_LMB], INTENT_ANY, "Set to [mode ? "spray" : "inject"]") + LAZYSET(context[SCREENTIP_CONTEXT_ALT_LMB], INTENT_ANY, "Set transfer amount") + return CONTEXTUAL_SCREENTIP_SET + +/obj/item/hypospray/mkii/add_item_context(obj/item/source, list/context, atom/target, mob/living/user) + . = ..() + if(iscarbon(target)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, mode ? "Inject" : "Spray") + return CONTEXTUAL_SCREENTIP_SET /obj/item/hypospray/mkii/ComponentInitialize() . = ..() @@ -409,7 +518,7 @@ return var/fp_verb = mode == HYPO_SPRAY ? "spray" : "inject" - var/method = mode == HYPO_SPRAY ? TOUCH : INJECT + var/method = mode == HYPO_SPRAY ? PATCH : INJECT //Medsprays use patch when spraying, feels like an inconsistancy here. if(L != user) L.visible_message("[user] is trying to [fp_verb] [L] with [src]!", \ diff --git a/code/modules/reagents/reagent_containers/hypovial.dm b/code/modules/reagents/reagent_containers/hypovial.dm index 8d99248d97..0f9ffd6514 100644 --- a/code/modules/reagents/reagent_containers/hypovial.dm +++ b/code/modules/reagents/reagent_containers/hypovial.dm @@ -9,19 +9,20 @@ possible_transfer_amounts = list(1,2,5,10) container_flags = APTFT_VERB obj_flags = UNIQUE_RENAME - unique_reskin = list("hypovial" = "hypovial", - "red hypovial" = "hypovial-b", - "blue hypovial" = "hypovial-d", - "green hypovial" = "hypovial-a", - "orange hypovial" = "hypovial-k", - "purple hypovial" = "hypovial-p", - "black hypovial" = "hypovial-t", - "pink hypovial" = "hypovial-pink" - ) + unique_reskin = list( + "hypovial" = list("icon_state" = "hypovial"), + "red hypovial" = list("icon_state" = "hypovial-b"), + "blue hypovial" = list("icon_state" = "hypovial-d"), + "green hypovial" = list("icon_state" = "hypovial-a"), + "orange hypovial" = list("icon_state" = "hypovial-k"), + "purple hypovial" = list("icon_state" = "hypovial-p"), + "black hypovial" = list("icon_state" = "hypovial-t"), + "pink hypovial" = list("icon_state" = "hypovial-pink") + ) always_reskinnable = TRUE cached_icon = "hypovial" -/obj/item/reagent_containers/glass/bottle/vial/Initialize() +/obj/item/reagent_containers/glass/bottle/vial/Initialize(mapload) . = ..() update_icon() @@ -50,14 +51,15 @@ icon_state = "hypoviallarge" volume = 120 possible_transfer_amounts = list(1,2,5,10,20) - unique_reskin = list("large hypovial" = "hypoviallarge", - "large red hypovial" = "hypoviallarge-b", - "large blue hypovial" = "hypoviallarge-d", - "large green hypovial" = "hypoviallarge-a", - "large orange hypovial" = "hypoviallarge-k", - "large purple hypovial" = "hypoviallarge-p", - "large black hypovial" = "hypoviallarge-t" - ) + unique_reskin = list( + "large hypovial" = list("icon_state" = "hypoviallarge"), + "large red hypovial" = list("icon_state" = "hypoviallarge-b"), + "large blue hypovial" = list("icon_state" = "hypoviallarge-d"), + "large green hypovial" = list("icon_state" = "hypoviallarge-a"), + "large orange hypovial" = list("icon_state" = "hypoviallarge-k"), + "large purple hypovial" = list("icon_state" = "hypoviallarge-p"), + "large black hypovial" = list("icon_state" = "hypoviallarge-t") + ) cached_icon = "hypoviallarge" /obj/item/reagent_containers/glass/bottle/vial/large/bluespace @@ -103,6 +105,11 @@ icon_state = "hypovial-pink" list_reagents = list(/datum/reagent/fermi/PEsmaller_hypo = 30) +/obj/item/reagent_containers/glass/bottle/vial/small/buttreduction + name = "pink hypovial (butt treatment)" + icon_state = "hypovial-pink" + list_reagents = list(/datum/reagent/fermi/AEsmaller_hypo = 30) + /obj/item/reagent_containers/glass/bottle/vial/large/CMO name = "deluxe hypovial" icon_state = "hypoviallarge-cmos" diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index a5b4e5b8ab..50db4f0610 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -15,7 +15,7 @@ var/self_delay = FALSE //pills are instant, this is because patches inheret their aplication from pills var/dissolvable = TRUE -/obj/item/reagent_containers/pill/Initialize() +/obj/item/reagent_containers/pill/Initialize(mapload) . = ..() if(!icon_state) icon_state = "pill[rand(1,20)]" @@ -248,7 +248,7 @@ var/static/list/descs = list("Your feeling is telling you no, but...","Drugs are expensive, you can't afford not to eat any pills that you find."\ , "Surely, there's no way this could go bad.") -/obj/item/reagent_containers/pill/floorpill/Initialize() +/obj/item/reagent_containers/pill/floorpill/Initialize(mapload) list_reagents = list(get_random_reagent_id() = rand(10,50)) . = ..() name = pick(names) @@ -265,3 +265,7 @@ /obj/item/reagent_containers/pill/breast_enlargement name = "breast enlargement pill" list_reagents = list(/datum/reagent/fermi/breast_enlarger = 10) + +/obj/item/reagent_containers/pill/butt_enlargement + name = "butt enlargement pill" + list_reagents = list(/datum/reagent/fermi/butt_enlarger = 10) diff --git a/code/modules/reagents/reagent_containers/rags.dm b/code/modules/reagents/reagent_containers/rags.dm index 8a6e2bf2e7..4982571a3b 100644 --- a/code/modules/reagents/reagent_containers/rags.dm +++ b/code/modules/reagents/reagent_containers/rags.dm @@ -37,14 +37,14 @@ var/log_object = "a damp rag containing [reagentlist]" if(user.a_intent == INTENT_HARM && !C.is_mouth_covered()) C.visible_message("[user] is trying to smother \the [C] with \the [src]!", "[user] is trying to smother you with \the [src]!", "You hear some struggling and muffled cries of surprise.") - if(do_after(user, 20, target = C)) + if(do_after(user, 2 SECONDS, C)) reagents.reaction(C, INGEST) reagents.trans_to(C, 5, log = "rag smother") C.visible_message("[user] has smothered \the [C] with \the [src]!", "[user] has smothered you with \the [src]!", "You hear some struggling and a heavy breath taken.") log_combat(user, C, "smothered", log_object) else C.visible_message("[user] is trying to wipe \the [C] with \the [src].") - if(do_after(user, 20, target = C)) + if(do_after(user, 2 SECONDS, C)) reagents.reaction(C, TOUCH) reagents.remove_all(5) C.visible_message("[user] has wiped \the [C] with \the [src].") @@ -52,7 +52,7 @@ else if(istype(A) && (src in user)) user.visible_message("[user] starts to wipe down [A] with [src]!", "You start to wipe down [A] with [src]...") - if(do_after(user, action_speed, target = A)) + if(do_after(user, action_speed, A)) user.visible_message("[user] finishes wiping off [A]!", "You finish wiping off [A].") SEND_SIGNAL(A, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM) @@ -91,7 +91,7 @@ . = ..() if(reagents.total_volume && user.canUseTopic(src, BE_CLOSE)) to_chat(user, "You start squeezing \the [src] dry...") - if(do_after(user, action_speed, TRUE, src)) + if(do_after(user, action_speed, src)) var/msg = "You squeeze \the [src]" var/obj/item/target if(Adjacent(user)) //Allows the user to drain the reagents into a beaker if adjacent (no telepathy). @@ -134,27 +134,27 @@ var/folded_icon = "towel" var/list/possible_colors -/obj/item/reagent_containers/rag/towel/Initialize() +/obj/item/reagent_containers/rag/towel/Initialize(mapload) . = ..() if(possible_colors) add_atom_colour(pick(possible_colors), FIXED_COLOUR_PRIORITY) /obj/item/reagent_containers/rag/towel/attack(mob/living/M, mob/living/user) if(user.a_intent == INTENT_HARM) - DISABLE_BITFIELD(item_flags, NOBLUDGEON) + item_flags &= ~(NOBLUDGEON) . = TRUE ..() if(.) - ENABLE_BITFIELD(item_flags, NOBLUDGEON) + item_flags |= NOBLUDGEON /obj/item/reagent_containers/rag/towel/equipped(mob/living/user, slot) . = ..() switch(slot) - if(SLOT_BELT) + if(ITEM_SLOT_BELT) body_parts_covered = GROIN|LEGS - if(SLOT_WEAR_SUIT) + if(ITEM_SLOT_OCLOTHING) body_parts_covered = CHEST|GROIN|LEGS - if(SLOT_HEAD) + if(ITEM_SLOT_HEAD) body_parts_covered = HEAD flags_inv = HIDEHAIR @@ -192,4 +192,4 @@ extinguish_efficiency = 5 action_speed = 15 damp_threshold = 0.8 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 50, "acid" = 50) //items don't provide armor to wearers unlike clothing yet. + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 20, BIO = 20, RAD = 20, FIRE = 50, ACID = 50) //items don't provide armor to wearers unlike clothing yet. diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 02c8a9802c..2670401964 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -84,6 +84,7 @@ else reagents.trans_to(D, amount_per_transfer_from_this, 1/range) D.add_atom_colour(mix_color_from_reagents(D.reagents.reagent_list), TEMPORARY_COLOUR_PRIORITY) + playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6) last_spray = world.time INVOKE_ASYNC(D, /obj/effect/decal/chempuff/proc/run_puff, A) @@ -228,7 +229,7 @@ generate_amount = 1 generate_delay = 40 //deciseconds -/obj/item/reagent_containers/spray/waterflower/cyborg/Initialize() +/obj/item/reagent_containers/spray/waterflower/cyborg/Initialize(mapload) . = ..() START_PROCESSING(SSfastprocess, src) diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 93a07b1a6e..c1812d9121 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -18,7 +18,7 @@ custom_price = PRICE_CHEAP_AS_FREE sharpness = SHARP_POINTY -/obj/item/reagent_containers/syringe/Initialize() +/obj/item/reagent_containers/syringe/Initialize(mapload) . = ..() if(list_reagents) //syringe starts in inject mode if its already got something inside mode = SYRINGE_INJECT @@ -218,6 +218,31 @@ volume = 50 list_reagents = list(/datum/reagent/medicine/stimulants = 50) +/obj/item/reagent_containers/syringe/contraband + name = "unlabeled syringe" + desc = "A syringe containing some sort of unknown chemical cocktail." + +/obj/item/reagent_containers/syringe/contraband/space_drugs + list_reagents = list(/datum/reagent/drug/space_drugs = 15) + +/obj/item/reagent_containers/syringe/contraband/krokodil + list_reagents = list(/datum/reagent/drug/krokodil = 15) + +/obj/item/reagent_containers/syringe/contraband/crank + list_reagents = list(/datum/reagent/drug/crank = 15) + +/obj/item/reagent_containers/syringe/contraband/methamphetamine + list_reagents = list(/datum/reagent/drug/methamphetamine = 15) + +/obj/item/reagent_containers/syringe/contraband/bath_salts + list_reagents = list(/datum/reagent/drug/bath_salts = 15) + +/obj/item/reagent_containers/syringe/contraband/fentanyl + list_reagents = list(/datum/reagent/toxin/fentanyl = 15) + +/obj/item/reagent_containers/syringe/contraband/morphine + list_reagents = list(/datum/reagent/medicine/morphine = 15) + /obj/item/reagent_containers/syringe/calomel name = "syringe (calomel)" desc = "Contains calomel." diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 26f0ca66ee..8e4db6f2f2 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -13,7 +13,7 @@ /obj/structure/reagent_dispensers/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) . = ..() if(. && obj_integrity > 0) - if(tank_volume && (damage_flag == "bullet" || damage_flag == "laser")) + if(tank_volume && (damage_flag == BULLET || damage_flag == LASER)) boom() /obj/structure/reagent_dispensers/attackby(obj/item/W, mob/user, params) @@ -22,7 +22,7 @@ else return ..() -/obj/structure/reagent_dispensers/Initialize() +/obj/structure/reagent_dispensers/Initialize(mapload) create_reagents(tank_volume, DRAINABLE | AMOUNT_VISIBLE) if(reagent_id) reagents.add_reagent(reagent_id, tank_volume) @@ -151,7 +151,7 @@ /obj/structure/reagent_dispensers/fueltank/blob_act(obj/structure/blob/B) boom() -/obj/structure/reagent_dispensers/fueltank/ex_act() +/obj/structure/reagent_dispensers/fueltank/ex_act(severity, target, origin) boom() /obj/structure/reagent_dispensers/fueltank/fire_act(exposed_temperature, exposed_volume) @@ -212,7 +212,7 @@ density = FALSE reagent_id = /datum/reagent/consumable/condensedcapsaicin -/obj/structure/reagent_dispensers/peppertank/Initialize() +/obj/structure/reagent_dispensers/peppertank/Initialize(mapload) . = ..() if(prob(1)) desc = "IT'S PEPPER TIME, BITCH!" @@ -233,6 +233,14 @@ anchored = TRUE reagent_id = /datum/reagent/consumable/cooking_oil +/obj/structure/reagent_dispensers/servingdish + name = "serving dish" + desc = "A dish full of food slop for your bowl." + icon = 'icons/obj/kitchen.dmi' + icon_state = "serving" + anchored = TRUE + reagent_id = /datum/reagent/consumable/nutraslop + //////// //Kegs// //////// diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index e9c17ecc28..b3ad29e637 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -308,20 +308,39 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) S.update_icon() CHECK_TICK -/obj/machinery/conveyor_switch/attackby(obj/item/I, mob/user, params) - if(I.tool_behaviour == TOOL_CROWBAR) - var/obj/item/conveyor_switch_construct/C = new/obj/item/conveyor_switch_construct(src.loc) - C.id = id - transfer_fingerprints_to(C) - to_chat(user, "You detach the conveyor switch.") - qdel(src) +/obj/machinery/conveyor_switch/crowbar_act(mob/user, obj/item/tool) + tool.play_tool_sound(src, 50) + var/obj/item/conveyor_switch_construct/switch_construct = new/obj/item/conveyor_switch_construct(src.loc) + switch_construct.id = id + transfer_fingerprints_to(switch_construct) + to_chat(user, span_notice("You detach [src].")) + qdel(src) + return TRUE + +/obj/machinery/conveyor_switch/screwdriver_act(mob/user, obj/item/tool) + tool.play_tool_sound(src, 50) + oneway = !oneway + to_chat(user, span_notice("You set [src] to [oneway ? "one way" : "default"] configuration.")) + return TRUE + +/obj/machinery/conveyor_switch/wrench_act(mob/user, obj/item/tool) + tool.play_tool_sound(src, 50) + invert_icon = !invert_icon + update_appearance() + to_chat(user, span_notice("You set [src] to [invert_icon ? "inverted": "normal"] position.")) + return TRUE + +/obj/machinery/conveyor_switch/examine(mob/user) + . = ..() + . += span_notice("[src] is set to [oneway ? "one way" : "default"] configuration. It can be changed with a screwdriver.") + . += span_notice("[src] is set to [invert_icon ? "inverted": "normal"] position. It can be rotated with a wrench.") /obj/machinery/conveyor_switch/oneway icon_state = "conveyor_switch_oneway" desc = "A conveyor control switch. It appears to only go in one direction." oneway = TRUE -/obj/machinery/conveyor_switch/oneway/Initialize() +/obj/machinery/conveyor_switch/oneway/Initialize(mapload) . = ..() if((dir == NORTH) || (dir == WEST)) invert_icon = TRUE @@ -334,7 +353,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) w_class = WEIGHT_CLASS_NORMAL var/id = "" //inherited by the switch -/obj/item/conveyor_switch_construct/Initialize() +/obj/item/conveyor_switch_construct/Initialize(mapload) . = ..() id = "[rand()]" //this couldn't possibly go wrong diff --git a/code/modules/recycling/conveyor_sorter.dm b/code/modules/recycling/conveyor_sorter.dm new file mode 100644 index 0000000000..0e42c79067 --- /dev/null +++ b/code/modules/recycling/conveyor_sorter.dm @@ -0,0 +1,144 @@ +// credits to jjpark-kb, see Skyrat-SS13/Skyrat-tg#8790 and related files +// - hatterhat + +/obj/item/conveyor_sorter + name = "conveyor sorter lister" + desc = "A tool that is used to create conveyor sorting marks, and give sorting lists to them." + icon = 'icons/obj/recycling.dmi' + icon_state = "lister" + ///the list of conveyor sorters spawned by + var/list/spawned_sorters = list() + ///the list of things that are currently within the sorting list + var/list/current_sort = list() + +/obj/item/conveyor_sorter/Destroy() + for(var/deleting_sorters in spawned_sorters) + qdel(deleting_sorters) + return ..() + +/obj/item/conveyor_sorter/examine(mob/user) + . = ..() + . += span_notice("Use it to place down a conveyor sorter, up to three.") + . += span_notice("Use Alt-Click to reset the sorting list.") + . += span_notice("Attack things to attempt to add to the sorting list.") + +/obj/item/conveyor_sorter/attack_self(mob/user, modifiers) + if(length(spawned_sorters) >= 3) + to_chat(user, span_warning("You may only have three spawned conveyor sorters!")) + return + var/obj/effect/decal/cleanable/conveyor_sorter/new_cs = new /obj/effect/decal/cleanable/conveyor_sorter(get_turf(src)) + new_cs.parent_item = src + spawned_sorters += new_cs + +/obj/item/conveyor_sorter/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + if(target == src) + return ..() + if(!proximity_flag) + return ..() + if(!ismovable(target)) + return ..() + if(istype(target, /obj/effect/decal/cleanable/conveyor_sorter)) + return + if(is_type_in_list(target, current_sort)) + to_chat(user, span_warning("[target] is already in [src]'s sorting list!")) + return + if(length(current_sort) >= 5) + to_chat(user, span_warning("[src] already has five things within the sorting list!")) + return + current_sort += target.type + to_chat(user, span_notice("[target] has been added to [src]'s sorting list.")) + +/obj/item/conveyor_sorter/AltClick(mob/user) + visible_message("[src] pings, resetting its sorting list!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + current_sort = list() + +/obj/effect/decal/cleanable/conveyor_sorter + name = "conveyor sorter" + desc = "A mark that sorts items out based on what they are." + icon = 'icons/obj/recycling.dmi' + icon_state = "sorter" + layer = OBJ_LAYER + plane = GAME_PLANE + ///the list of items that will be sorted to the sorted direction + var/list/sorting_list = list() + //the direction that the items in the sorting list will be moved to + dir = NORTH + ///the parent conveyor sorter lister item, used for deletion + var/obj/item/conveyor_sorter/parent_item + /// To prevent spam + COOLDOWN_DECLARE(use_cooldown) + + light_range = 3 + light_color = COLOR_RED_LIGHT + +/obj/effect/decal/cleanable/conveyor_sorter/Initialize(mapload, list/datum/disease/diseases) + . = ..() + var/static/list/loc_connections = list( + COMSIG_ATOM_ENTERED = .proc/on_entered, + ) + AddElement(/datum/element/connect_loc, loc_connections) + +/obj/effect/decal/cleanable/conveyor_sorter/Destroy() + if(parent_item) + parent_item.spawned_sorters -= src + parent_item = null + return ..() + +/obj/effect/decal/cleanable/conveyor_sorter/examine(mob/user) + . = ..() + . += span_notice("Attack with conveyor sorter lister to set the sorting list.") + . += span_notice("Slap with empty hands to change the sorting direction.") + . += span_notice("Alt-Click to reset the sorting list.") + . += span_notice("Ctrl-Click to remove.") + +/obj/effect/decal/cleanable/conveyor_sorter/attack_hand(mob/living/user, list/modifiers) + var/user_choice = tgui_input_list(user, "Choose which direction to sort to!", "Direction choice", list("North", "East", "South", "West")) + if(!user_choice) + return ..() + switch(user_choice) + if("North") + setDir(NORTH) + if("East") + setDir(EAST) + if("South") + setDir(SOUTH) + if("West") + setDir(WEST) + visible_message("[src] pings, updating its sorting direction!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + +/obj/effect/decal/cleanable/conveyor_sorter/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/conveyor_sorter)) + var/obj/item/conveyor_sorter/cs_item = W + sorting_list = cs_item.current_sort + visible_message("[src] pings, updating its sorting list!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + return + else + return ..() + +/obj/effect/decal/cleanable/conveyor_sorter/AltClick(mob/user) + visible_message("[src] pings, resetting its sorting list!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + sorting_list = list() + +/obj/effect/decal/cleanable/conveyor_sorter/CtrlClick(mob/user) + visible_message("[src] pings, before disappearing!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + qdel(src) + +/obj/effect/decal/cleanable/conveyor_sorter/proc/on_entered(datum/source, atom/movable/AM) + if(is_type_in_list(AM, sorting_list) && !AM.anchored && COOLDOWN_FINISHED(src, use_cooldown)) + COOLDOWN_START(src, use_cooldown, 1 SECONDS) + AM.Move(get_step(src, dir)) + +/datum/design/conveyor_sorter + name = "Conveyor Sorter" + desc = "A wonderful item that can set markers and forcefully move stuff to a direction." + id = "conveyor_sorter" + build_type = PROTOLATHE + build_path = /obj/item/conveyor_sorter + materials = list(/datum/material/iron = 500, /datum/material/plastic = 500) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_CARGO diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index 7fc57ee3a7..8be744cd96 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -5,7 +5,7 @@ /obj/machinery/disposal icon = 'icons/obj/atmospherics/pipes/disposal.dmi' density = TRUE - armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30) + armor = list(MELEE = 25, BULLET = 10, LASER = 10, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 90, ACID = 30) max_integrity = 200 resistance_flags = FIRE_PROOF interaction_flags_machine = INTERACT_MACHINE_OPEN | INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON @@ -465,7 +465,7 @@ /obj/machinery/disposal/bin/get_remote_view_fullscreens(mob/user) if(user.stat == DEAD || !(user.sight & (SEEOBJS|SEEMOBS))) - user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/impaired, 2) + user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/scaled/impaired, 2) //Delivery Chute @@ -524,7 +524,7 @@ /obj/effect/CanEnterDisposals() return -/obj/mecha/CanEnterDisposals() +/obj/vehicle/sealed/mecha/CanEnterDisposals() return /obj/machinery/disposal/deliveryChute/newHolderDestination(obj/structure/disposalholder/H) diff --git a/code/modules/recycling/disposal/holder.dm b/code/modules/recycling/disposal/holder.dm index f739057699..bce1b3d98d 100644 --- a/code/modules/recycling/disposal/holder.dm +++ b/code/modules/recycling/disposal/holder.dm @@ -130,5 +130,5 @@ /obj/structure/disposalholder/AllowDrop() return TRUE -/obj/structure/disposalholder/ex_act(severity, target) +/obj/structure/disposalholder/ex_act(severity, target, origin) return diff --git a/code/modules/recycling/disposal/pipe.dm b/code/modules/recycling/disposal/pipe.dm index 45d3d9da25..6c85bfc3ee 100644 --- a/code/modules/recycling/disposal/pipe.dm +++ b/code/modules/recycling/disposal/pipe.dm @@ -12,7 +12,7 @@ level = 1 // underfloor only dir = NONE // dir will contain dominant direction for junction pipes max_integrity = 200 - armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30) + armor = list(MELEE = 25, BULLET = 10, LASER = 10, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 90, ACID = 30) layer = DISPOSAL_PIPE_LAYER // slightly lower than wires and other pipes plane = ABOVE_WALL_PLANE rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE @@ -54,7 +54,7 @@ if(H) H.active = FALSE expel(H, get_turf(src), 0) - QDEL_NULL(stored) + stored = null //The qdel is handled in expel() return ..() // returns the direction of the next pipe object, given the entrance dir @@ -132,14 +132,14 @@ // pipe affected by explosion -/obj/structure/disposalpipe/contents_explosion(severity, target) +/obj/structure/disposalpipe/contents_explosion(severity, target, origin) var/obj/structure/disposalholder/H = locate() in src if(H) - H.contents_explosion(severity, target) + H.contents_explosion(severity, target, origin) /obj/structure/disposalpipe/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < 10) + if(damage_flag == MELEE && damage_amount < 10) return 0 return ..() @@ -240,7 +240,7 @@ canclank = TRUE var/obj/linked // the linked obj/machinery/disposal or obj/disposaloutlet -/obj/structure/disposalpipe/trunk/Initialize() +/obj/structure/disposalpipe/trunk/Initialize(mapload) . = ..() getlinked() diff --git a/code/modules/recycling/disposal/pipe_sorting.dm b/code/modules/recycling/disposal/pipe_sorting.dm index 2d40ec64eb..1ae5698312 100644 --- a/code/modules/recycling/disposal/pipe_sorting.dm +++ b/code/modules/recycling/disposal/pipe_sorting.dm @@ -36,7 +36,7 @@ icon_state = "pipe-j2s" initialize_dirs = DISP_DIR_LEFT | DISP_DIR_FLIP -/obj/structure/disposalpipe/sorting/mail/Initialize() +/obj/structure/disposalpipe/sorting/mail/Initialize(mapload) . = ..() // Generate a list of soring tags. if(sortType) diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index b47f0de032..97a35f9312 100644 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -7,9 +7,15 @@ mouse_drag_pointer = MOUSE_ACTIVE_POINTER var/giftwrapped = FALSE var/sortTag = 0 + var/obj/item/barcode/sticker /obj/structure/bigDelivery/interact(mob/user) + to_chat(user, "You start to unwrap the package...") + if(!do_after(user, 15, target = user)) + return playsound(src.loc, 'sound/items/poster_ripped.ogg', 50, 1) + new /obj/effect/decal/cleanable/wrapping(get_turf(user)) + unwrap_contents() qdel(src) /obj/structure/bigDelivery/Destroy() @@ -18,9 +24,14 @@ AM.forceMove(T) return ..() -/obj/structure/bigDelivery/contents_explosion(severity, target) +/obj/structure/bigDelivery/examine(mob/user) + . = ..() + if(sticker) + . += "There's a barcode attached to the side." + +/obj/structure/bigDelivery/contents_explosion(severity, target, origin) for(var/atom/movable/AM in contents) - AM.ex_act() + AM.ex_act(severity, target, origin) /obj/structure/bigDelivery/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/destTagger)) @@ -53,6 +64,47 @@ icon_state = "gift[icon_state]" else to_chat(user, "You need more paper!") + else if(istype(W, /obj/item/sales_tagger)) + var/obj/item/sales_tagger/tagger = W + if(sticker) + to_chat(user, "This package already has a barcode attached!") + return + if(!(tagger.payments_acc)) + to_chat(user, "Swipe an ID on [tagger] first!") + return + if(tagger.paper_count <= 0) + to_chat(user, "[tagger] is out of paper!") + return + user.visible_message("[user] attaches a barcode to [src].", "You attach a barcode to [src].") + tagger.paper_count -= 1 + sticker = new /obj/item/barcode(src) + sticker.payments_acc = tagger.payments_acc //new tag gets the tagger's current account. + sticker.cut_multiplier = tagger.cut_multiplier //same, but for the percentage taken. + + var/list/wrap_contents = src.GetAllContents() + for(var/obj/I in wrap_contents) + I.AddComponent(/datum/component/pricetag, sticker.payments_acc, tagger.cut_multiplier) + var/overlaystring = "[icon_state]_tag" + if(giftwrapped) + overlaystring = copytext(overlaystring, 5) + add_overlay(overlaystring) + else if(istype(W, /obj/item/barcode)) + var/obj/item/barcode/stickerA = W + if(sticker) + to_chat(user, "This package already has a barcode attached!") + return + if(!(stickerA.payments_acc)) + to_chat(user, "This barcode seems to be invalid. Guess it's trash now.") + return + if(!user.transferItemToLoc(W, src)) + to_chat(user, "For some reason, you can't attach [W]!") + return + sticker = stickerA + var/overlaystring = "[icon_state]_tag" + if(giftwrapped) + overlaystring = copytext_char(overlaystring, 5) //5 == length("gift") + 1 + add_overlay(overlaystring) + else return ..() @@ -68,11 +120,18 @@ to_chat(user, "You successfully removed [O]'s wrapping !") O.forceMove(loc) playsound(src.loc, 'sound/items/poster_ripped.ogg', 50, 1) + new /obj/effect/decal/cleanable/wrapping(get_turf(user)) + unwrap_contents() qdel(src) else if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded. to_chat(user, "You fail to remove [O]'s wrapping!") +/obj/structure/bigDelivery/proc/unwrap_contents() + if(!sticker) + return + for(var/obj/I in src.GetAllContents()) + SEND_SIGNAL(I, COMSIG_STRUCTURE_UNWRAPPED) /obj/item/smallDelivery name = "parcel" @@ -81,17 +140,23 @@ icon_state = "deliverypackage3" var/giftwrapped = 0 var/sortTag = 0 + var/obj/item/barcode/sticker -/obj/item/smallDelivery/contents_explosion(severity, target) +/obj/item/smallDelivery/contents_explosion(severity, target, origin) for(var/atom/movable/AM in contents) - AM.ex_act() + AM.ex_act(severity, target, origin) /obj/item/smallDelivery/attack_self(mob/user) + to_chat(user, "You start to unwrap the package...") + if(!do_after(user, 15, target = user)) + return user.temporarilyRemoveItemFromInventory(src, TRUE) + unwrap_contents() for(var/X in contents) var/atom/movable/AM = X user.put_in_hands(AM) playsound(src.loc, 'sound/items/poster_ripped.ogg', 50, 1) + new /obj/effect/decal/cleanable/wrapping(get_turf(user)) qdel(src) /obj/item/smallDelivery/attack_self_tk(mob/user) @@ -106,6 +171,8 @@ var/atom/movable/AM = X AM.forceMove(src.loc) playsound(src.loc, 'sound/items/poster_ripped.ogg', 50, 1) + new /obj/effect/decal/cleanable/wrapping(get_turf(user)) + unwrap_contents() qdel(src) /obj/item/smallDelivery/attackby(obj/item/W, mob/user, params) @@ -140,6 +207,59 @@ else to_chat(user, "You need more paper!") + else if(istype(W, /obj/item/sales_tagger)) + var/obj/item/sales_tagger/tagger = W + if(sticker) + to_chat(user, "This package already has a barcode attached!") + return + if(!(tagger.payments_acc)) + to_chat(user, "Swipe an ID on [tagger] first!") + return + if(tagger.paper_count <= 0) + to_chat(user, "[tagger] is out of paper!") + return + user.visible_message("[user] attaches a barcode to [src].", "You attach a barcode to [src].") + tagger.paper_count -= 1 + sticker = new /obj/item/barcode(src) + sticker.payments_acc = tagger.payments_acc //new tag gets the tagger's current account. + sticker.cut_multiplier = tagger.cut_multiplier //as above, as before. + + var/list/wrap_contents = src.GetAllContents() + for(var/obj/I in wrap_contents) + I.AddComponent(/datum/component/pricetag, sticker.payments_acc, tagger.cut_multiplier) + var/overlaystring = "[icon_state]_tag" + if(giftwrapped) + overlaystring = copytext(overlaystring, 5) + add_overlay(overlaystring) + + else if(istype(W, /obj/item/barcode)) + var/obj/item/barcode/stickerA = W + if(sticker) + to_chat(user, "This package already has a barcode attached!") + return + if(!(stickerA.payments_acc)) + to_chat(user, "This barcode seems to be invalid. Guess it's trash now.") + return + if(!user.transferItemToLoc(W, src)) + to_chat(user, "For some reason, you can't attach [W]!") + return + sticker = stickerA + var/overlaystring = "[icon_state]_tag" + if(giftwrapped) + overlaystring = copytext_char(overlaystring, 5) //5 == length("gift") + 1 + add_overlay(overlaystring) + +/obj/item/smallDelivery/proc/unwrap_contents() + if(!sticker) + return + for(var/obj/I in src.GetAllContents()) + SEND_SIGNAL(I, COMSIG_ITEM_UNWRAPPED) + +/obj/item/smallDelivery/examine(mob/user) + . = ..() + if(sticker) + . += "There's a barcode attached to the side." + /obj/item/destTagger name = "destination tagger" @@ -194,3 +314,98 @@ var/n = text2num(href_list["nextTag"]) currTag = n openwindow(usr) + +/obj/item/sales_tagger + name = "sales tagger" + desc = "A scanner that lets you tag wrapped items for sale, splitting the profit between you and cargo." + icon = 'icons/obj/device.dmi' + icon_state = "salestagger" + item_state = "electronic" + lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' + w_class = WEIGHT_CLASS_TINY + slot_flags = ITEM_SLOT_BELT + ///The account which is recieving the split profits. + var/datum/bank_account/payments_acc = null + var/paper_count = 10 + var/max_paper_count = 20 + ///Details the percentage the scanned account recieves off the final sale. + ///The person who tagged this will receive the sale value multiplied by this number. + var/cut_multiplier = 0.5 + ///Maximum value for cut_multiplier. + var/cut_max = 0.5 + ///Minimum value for cut_multiplier. + var/cut_min = 0.01 + +/obj/item/sales_tagger/examine(mob/user) + . = ..() + . += "[src] has [paper_count]/[max_paper_count] available barcodes. Refill with paper." + . += "Profit split on sale is currently set to [round(cut_multiplier*100)]%. Alt-click to change." + if(payments_acc) + . += "Ctrl-click to clear the registered account." + +/obj/item/sales_tagger/attackby(obj/item/I, mob/living/user, params) + . = ..() + if(istype(I, /obj/item/card/id)) + var/obj/item/card/id/potential_acc = I + if(potential_acc.registered_account) + payments_acc = potential_acc.registered_account + playsound(src, 'sound/machines/ping.ogg', 40, TRUE) + to_chat(user, "[src] registers the ID card. Tag a wrapped item to create a barcode.") + else if(!potential_acc.registered_account) + to_chat(user, "This ID card has no account registered!") + return + else if(payments_acc != potential_acc.registered_account) + to_chat(user, "ID card already registered.") + if(istype(I, /obj/item/paper)) + if (!(paper_count >= max_paper_count)) + paper_count += 10 + qdel(I) + if (paper_count >= max_paper_count) + paper_count = max_paper_count + to_chat(user, "[src]'s paper supply is now full.") + return + to_chat(user, "You refill [src]'s paper supply, you have [paper_count] left.") + return + else + to_chat(user, "[src]'s paper supply is full.") + return + +/obj/item/sales_tagger/attack_self(mob/user) + . = ..() + if(paper_count <= 0) + to_chat(user, "You're out of paper!'.") + return + if(!payments_acc) + to_chat(user, "You need to swipe [src] with an ID card first.") + return + paper_count -= 1 + playsound(src, 'sound/machines/click.ogg', 40, TRUE) + to_chat(user, "You print a new barcode.") + var/obj/item/barcode/new_barcode = new /obj/item/barcode(src) + new_barcode.payments_acc = payments_acc // The sticker gets the scanner's registered account. + new_barcode.cut_multiplier = cut_multiplier // Also the registered percent cut. + user.put_in_hands(new_barcode) + +/obj/item/sales_tagger/CtrlClick(mob/user) + . = ..() + payments_acc = null + to_chat(user, "You clear the registered account.") + +/obj/item/sales_tagger/AltClick(mob/user) + . = ..() + var/potential_cut = input("How much would you like to pay out to the registered card?","Percentage Profit ([round(cut_min*100)]% - [round(cut_max*100)]%)") as num|null + if(!potential_cut) + cut_multiplier = initial(cut_multiplier) + cut_multiplier = clamp(round(potential_cut/100, cut_min), cut_min, cut_max) + to_chat(user, "[round(cut_multiplier*100)]% profit will be received if a package with a barcode is sold.") + +/obj/item/barcode + name = "Barcode tag" + desc = "A tiny tag, associated with a crewmember's account. Attach to a wrapped item to give that account a portion of the wrapped item's profit." + icon = 'icons/obj/bureaucracy.dmi' + icon_state = "barcode" + w_class = WEIGHT_CLASS_TINY + ///All values inheirited from the sales tagger it came from. + var/datum/bank_account/payments_acc = null + var/cut_multiplier = 0.5 diff --git a/code/modules/research/anomaly/anomaly_core.dm b/code/modules/research/anomaly/anomaly_core.dm index 7aeb7b3a9b..555647a82a 100644 --- a/code/modules/research/anomaly/anomaly_core.dm +++ b/code/modules/research/anomaly/anomaly_core.dm @@ -3,7 +3,7 @@ name = "anomaly core" desc = "The neutralized core of an anomaly. It'd probably be valuable for research." icon_state = "anomaly_core" - //inhand_icon_state = "electronic" + //item_state = "electronic" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' resistance_flags = FIRE_PROOF diff --git a/code/modules/research/anomaly/explosive_compressor.dm b/code/modules/research/anomaly/explosive_compressor.dm index 23983e31dc..54236e3763 100644 --- a/code/modules/research/anomaly/explosive_compressor.dm +++ b/code/modules/research/anomaly/explosive_compressor.dm @@ -1,4 +1,4 @@ -#define MAX_RADIUS_REQUIRED 8000 //tritbomb +#define MAX_RADIUS_REQUIRED 175 //tritbomb #define MIN_RADIUS_REQUIRED 20 //maxcap /** * # Explosive compressor machines diff --git a/code/modules/research/bepis.dm b/code/modules/research/bepis.dm index 7b36a614a7..93df1e2351 100644 --- a/code/modules/research/bepis.dm +++ b/code/modules/research/bepis.dm @@ -103,7 +103,7 @@ return account.adjust_money(-deposit_value) //The money vanishes, not paid to any accounts. SSblackbox.record_feedback("amount", "BEPIS_credits_spent", deposit_value) - //log_econ("[deposit_value] credits were inserted into [src] by [account.account_holder]") + log_econ("[deposit_value] credits were inserted into [src] by [key_name(usr)] (account: [account.account_holder])") banked_cash += deposit_value use_power(1000 * power_saver) say("Cash deposit successful. There is [banked_cash] in the chamber.") diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index cfb6d92723..9c80176f46 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -79,7 +79,7 @@ other types of metals and chemistry for reagents). var/list/blueprints = list() var/max_blueprints = 1 -/obj/item/disk/design_disk/Initialize() +/obj/item/disk/design_disk/Initialize(mapload) . = ..() pixel_x = rand(-5, 5) pixel_y = rand(-5, 5) diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_construction.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_construction.dm index f8cf5c1d84..84d98fe1e3 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_construction.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_construction.dm @@ -75,6 +75,22 @@ build_path = /obj/item/wallframe/newscaster category = list("initial", "Construction") +/datum/design/posialert + name = "Posialert Frame" + id = "posialert_frame" + build_type = AUTOLATHE + materials = list(/datum/material/iron = 14000, /datum/material/glass = 8000) + build_path = /obj/item/wallframe/posialert + category = list("initial", "Construction") + +/datum/design/status_display_frame + name = "Status Display Frame" + id = "status_display_frame" + build_type = AUTOLATHE + materials = list(/datum/material/iron = 14000, /datum/material/glass = 8000) + build_path = /obj/item/wallframe/status_display + category = list("initial", "Construction") + /datum/design/turret_control_frame name = "Turret Control Frame" id = "turret_control" diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_electronics.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_electronics.dm index 78b0a365c5..fea67a921f 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_electronics.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_electronics.dm @@ -90,3 +90,12 @@ materials = list(/datum/material/iron = 2010, /datum/material/glass = 5) build_path = /obj/item/electronics/electrochromatic_kit category = list("initial", "Electronics") + +/datum/design/salestagger + name = "Sales Tagger" + id = "salestagger" + build_type = AUTOLATHE | PROTOLATHE + materials = list(/datum/material/iron = 700, /datum/material/glass = 200) + build_path = /obj/item/sales_tagger + category = list("initial", "Electronics") + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SERVICE diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm index 67890838db..fbfd626ae7 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm @@ -30,13 +30,21 @@ category = list("initial","Dinnerware") /datum/design/tray - name = "Tray" - id = "tray" + name = "Serving Tray" + id = "servingtray" build_type = AUTOLATHE materials = list(/datum/material/iron = 3000) build_path = /obj/item/storage/bag/tray category = list("initial","Dinnerware") +/datum/design/cafeteria_tray + name = "Cafeteria Tray" + id = "foodtray" + build_type = AUTOLATHE + materials = list(/datum/material/iron = 3000) + build_path = /obj/item/storage/bag/tray/cafeteria + category = list("initial","Dinnerware") + /datum/design/bowl name = "Bowl" id = "bowl" diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm index 1b1c710e8c..0ac303a3a0 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm @@ -92,6 +92,11 @@ category = list("initial","Tools","Tool Designs") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SERVICE +/datum/design/airlock_painter/decal/tile + name = "Tile Sprayer" + id = "tile_sprayer" + build_path = /obj/item/airlock_painter/decal/tile + /datum/design/cultivator name = "Cultivator" id = "cultivator" diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm index bebf836ce0..63442ef1ac 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm @@ -158,3 +158,11 @@ materials = list(/datum/material/iron = 150, /datum/material/glass = 150) build_path = /obj/item/geiger_counter category = list("initial", "Tools") + +/datum/design/chisel + name = "Chisel" + id = "chisel" + build_type = AUTOLATHE + materials = list(/datum/material/iron = 75) + build_path = /obj/item/chisel + category = list("initial","Tools") diff --git a/code/modules/research/designs/bluespace_designs.dm b/code/modules/research/designs/bluespace_designs.dm index cf6aff5918..b16ffeb9de 100644 --- a/code/modules/research/designs/bluespace_designs.dm +++ b/code/modules/research/designs/bluespace_designs.dm @@ -115,3 +115,13 @@ build_path = /obj/item/pipe/bluespace category = list("Bluespace Designs") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/swapper //ported from TG, credit to XDTM + name = "Quantum Spin Inverter" + desc = "An experimental device that is able to swap the locations of two entities by switching their particles' spin values. Must be linked to another device to function." + id = "swapper" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 500, /datum/material/diamond = 1500, /datum/material/glass = 1000, /datum/material/bluespace = 2000, /datum/material/silver=1000) + build_path = /obj/item/swapper + category = list("Bluespace Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE diff --git a/code/modules/research/designs/comp_board_designs/comp_board_designs_all_misc.dm b/code/modules/research/designs/comp_board_designs/comp_board_designs_all_misc.dm index 99caa5b480..8ea883edf1 100644 --- a/code/modules/research/designs/comp_board_designs/comp_board_designs_all_misc.dm +++ b/code/modules/research/designs/comp_board_designs/comp_board_designs_all_misc.dm @@ -21,14 +21,6 @@ category = list("Computer Boards") departmental_flags = DEPARTMENTAL_FLAG_ALL -/datum/design/board/minesweeper - name = "Computer Design (Minesweeper Arcade Machine)" - desc = "Allows for the construction of circuit boards used to build a new Minesweeper machine." - id = "arcade_minesweeper" - build_path = /obj/item/circuitboard/computer/arcade/minesweeper - category = list("Computer Boards") - departmental_flags = DEPARTMENTAL_FLAG_ALL - /datum/design/board/slot_machine name = "Computer Design (Slot Machine)" desc = "Allows for the construction of circuit boards used to build a new slot machine." diff --git a/code/modules/research/designs/comp_board_designs/comp_board_designs_cargo.dm b/code/modules/research/designs/comp_board_designs/comp_board_designs_cargo.dm index e5f7fdc004..f2514b6f9c 100644 --- a/code/modules/research/designs/comp_board_designs/comp_board_designs_cargo.dm +++ b/code/modules/research/designs/comp_board_designs/comp_board_designs_cargo.dm @@ -41,3 +41,10 @@ build_path = /obj/item/circuitboard/computer/mining_shuttle category = list("Computer Boards") departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/board/bountypad_control + name = "Computer Design (Civilian Bounty Pad Control)" + desc = "Allows for the construction of circuit boards used to build a new civilian bounty pad console." + id = "bounty_pad_control" + build_path = /obj/item/circuitboard/computer/bountypad + category = list("Computer Boards") diff --git a/code/modules/research/designs/limbgrower_designs.dm b/code/modules/research/designs/limbgrower_designs.dm index 8da18c453c..f0e162b24f 100644 --- a/code/modules/research/designs/limbgrower_designs.dm +++ b/code/modules/research/designs/limbgrower_designs.dm @@ -2,6 +2,18 @@ //////////Limb Grower Designs /////// ///////////////////////////////////// + +/datum/design/chestmob + name = "Synthetic Humanoid Framework Chest" + id = "chestmob" + // Mobs don't make very good roundstart icons + research_icon = 'icons/mob/human_parts.dmi' + research_icon_state = "default_human_chest" + build_type = LIMBGROWER + reagents_list = list(/datum/reagent/medicine/synthflesh = 100, /datum/reagent/blood = BLOOD_VOLUME_SURVIVE) + build_path = /mob/living/carbon/human/chestonly + category = list("initial","human","lizard","fly","insect","plasmaman","mammal","xeno") + /datum/design/leftarm name = "Left Arm" id = "leftarm" @@ -200,3 +212,13 @@ reagents_list = list(/datum/reagent/medicine/synthflesh = 25) build_path = /obj/item/organ/genital/breasts category = list("initial","human","lizard","fly","insect","plasmaman","mammal","xeno") + +/datum/design/butt + name = "Butt" + id = "butt" + research_icon_state = "butt_pair_5_s" + research_icon = 'icons/obj/genitals/butt.dmi' + build_type = LIMBGROWER + reagents_list = list(/datum/reagent/medicine/synthflesh = 25) + build_path = /obj/item/organ/genital/butt + category = list("initial","human","lizard","fly","insect","plasmaman","mammal","xeno") diff --git a/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm index 81b16d1118..570c99e6ae 100644 --- a/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm +++ b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm @@ -10,6 +10,14 @@ category = list ("Misc. Machinery") departmental_flags = DEPARTMENTAL_FLAG_ALL +/datum/design/board/autoloom + name = "Machine Design (Autoloom Board)" + desc = "The circuit board for an autoloom." + id = "autoloom" + build_path = /obj/item/circuitboard/machine/autoloom + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + /datum/design/board/holopad name = "Machine Design (AI Holopad Board)" desc = "The circuit board for a holopad." diff --git a/code/modules/research/designs/machine_desings/machine_designs_cargo.dm b/code/modules/research/designs/machine_desings/machine_designs_cargo.dm index 1ed868cde9..3abb757f36 100644 --- a/code/modules/research/designs/machine_desings/machine_designs_cargo.dm +++ b/code/modules/research/designs/machine_desings/machine_designs_cargo.dm @@ -40,3 +40,10 @@ build_path = /obj/item/circuitboard/machine/ore_redemption category = list ("Misc. Machinery") departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/board/bountypad + name = "Machine Design (Civilian Bounty Pad)" + desc = "The circuit board for a Civilian Bounty Pad." + id = "bounty_pad" + build_path = /obj/item/circuitboard/machine/bountypad + category = list ("Misc. Machinery") diff --git a/code/modules/research/designs/machine_desings/machine_designs_engi.dm b/code/modules/research/designs/machine_desings/machine_designs_engi.dm index ca522d2ce1..e3dea1d9ee 100644 --- a/code/modules/research/designs/machine_desings/machine_designs_engi.dm +++ b/code/modules/research/designs/machine_desings/machine_designs_engi.dm @@ -105,6 +105,14 @@ category = list ("Engineering Machinery") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE +/datum/design/board/stasis + name = "Machine Design (Lifeform Stasis Unit)" + desc = "The circuit board for a stasis unit." + id = "stasis" + build_path = /obj/item/circuitboard/machine/stasis + category = list("Medical Machinery") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + /datum/design/board/spaceship_navigation_beacon name = "Machine Design (Bluespace Navigation Gigabeacon)" desc = "The circuit board for a Bluespace Navigation Gigabeacon." diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 4efcad97ba..12a18c7f91 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -585,15 +585,6 @@ construction_time = 100 category = list("Exosuit Equipment") -/datum/design/mech_cable_layer - name = "Exosuit Engineering Equipment (Cable Layer)" - id = "mech_cable_layer" - build_type = MECHFAB - build_path = /obj/item/mecha_parts/mecha_equipment/cable_layer - materials = list(/datum/material/iron=10000) - construction_time = 100 - category = list("Exosuit Equipment") - /datum/design/mech_generator name = "Exosuit Equipment (Plasma Generator)" id = "mech_generator" diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 88c37ce2a2..5d28603055 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -122,6 +122,17 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL +/datum/design/smartdartrepeater + name = "Smartdart Repeater" + desc = "An experimental smartdart rifle. It can make its own smart darts and is loaded with a hypovial." + id = "smartdartrepeater" + build_type = PROTOLATHE + materials = list(/datum/material/glass = 2000, /datum/material/plastic = 1000, /datum/material/iron = 2000,/datum/material/titanium = 1000 ) + build_path = /obj/item/gun/chem/smart + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + + /datum/design/plasmarefiller name = "Plasma-Man Jumpsuit Refill" desc = "A refill pack for the auto-extinguisher on Plasma-man suits." @@ -201,8 +212,8 @@ build_path = /obj/item/storage/hypospraykit // let's not summon new hyposprays thanks category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/hypospray/mkii + +/datum/design/hypospray_mkii name = "Hypospray Mk. II" id = "hypospray_mkii" build_type = PROTOLATHE @@ -211,6 +222,15 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL +/datum/design/nanogel + name = "Nanogel paste" + id = "nanogel" + build_type = PROTOLATHE | MECHFAB + materials = list(/datum/material/iron = 800, /datum/material/titanium = 500, /datum/material/gold = 100, /datum/material/diamond = 20) + build_path = /obj/item/stack/medical/nanogel/one + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + /datum/design/blood_bag name = "Empty Blood Bag" desc = "A small sterilized plastic bag for blood." @@ -938,6 +958,13 @@ surgery = /datum/surgery/advanced/brainwashing research_icon_state = "surgery_head" +/datum/design/surgery/robo_brainwashing + name = "Reprogramming" + desc = "A surgical procedure which hardcodes a directive into the patient's logic subroutines, making it their absolute priority. It can be purged using a mindshield implant." + id = "surgery_robot_brainwashing" + surgery = /datum/surgery/advanced/robot_brainwashing + research_icon_state = "surgery_head" + /datum/design/surgery/nerve_splicing name = "Nerve Splicing" desc = "A surgical procedure which splices the patient's nerves, making them more resistant to stuns." diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index 630a3629cf..6f6a1fd88e 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -12,16 +12,6 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL -/datum/design/health_hud_prescription - name = "Prescription Health Scanner HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their health status. This one has a prescription lens." - id = "health_hud_prescription" - build_type = PROTOLATHE - materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 350) - build_path = /obj/item/clothing/glasses/hud/health/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - /datum/design/health_hud_night name = "Night Vision Health Scanner HUD" desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness." @@ -42,16 +32,6 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SECURITY -/datum/design/security_hud_prescription - name = "Prescription Security HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status. This one has a prescription lens." - id = "security_hud_prescription" - build_type = PROTOLATHE - materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 350) - build_path = /obj/item/clothing/glasses/hud/security/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SECURITY - /datum/design/security_hud_night name = "Night Vision Security HUD" desc = "A heads-up display which provides id data and vision in complete darkness." @@ -72,16 +52,6 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE -/datum/design/diagnostic_hud_prescription - name = "Prescription Diagnostic HUD" - desc = "A HUD used to analyze and determine faults within robotic machinery. This one has a prescription lens." - id = "diagnostic_hud_prescription" - build_type = PROTOLATHE - materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/gold = 350) - build_path = /obj/item/clothing/glasses/hud/diagnostic/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE - /datum/design/diagnostic_hud_night name = "Night Vision Diagnostic HUD" desc = "Upgraded version of the diagnostic HUD designed to function during a power failure." @@ -112,16 +82,6 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_ENGINEERING -/datum/design/mesons_prescription - name = "Prescription Optical Meson Scanners" - desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition. Prescription lens has been added into this design." - id = "mesons_prescription" - build_type = PROTOLATHE - materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 350) - build_path = /obj/item/clothing/glasses/meson/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_ENGINEERING - /datum/design/engine_goggles name = "Engineering Scanner Goggles" desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, regardless of lighting condition. The T-ray Scanner mode lets you see underfloor objects such as cables and pipes." @@ -132,16 +92,6 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING -/datum/design/engine_goggles_prescription - name = "Prescription Engineering Scanner Goggles" - desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, regardless of lighting condition. The T-ray Scanner mode lets you see underfloor objects such as cables and pipes. Prescription lens has been added into this design." - id = "engine_goggles_prescription" - build_type = PROTOLATHE - materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/plasma = 100, /datum/material/silver = 350) - build_path = /obj/item/clothing/glasses/meson/engine/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - /datum/design/tray_goggles name = "Optical T-Ray Scanners" desc = "Used by engineering staff to see underfloor objects such as cables and pipes." @@ -152,16 +102,6 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING -/datum/design/tray_goggles_prescription - name = "Prescription Optical T-Ray Scanners" - desc = "Used by engineering staff to see underfloor objects such as cables and pipes. Prescription lens has been added into this design." - id = "tray_goggles_prescription" - build_type = PROTOLATHE - materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 150) - build_path = /obj/item/clothing/glasses/meson/engine/tray/prescription - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - /datum/design/nvgmesons name = "Night Vision Optical Meson Scanners" desc = "Prototype meson scanners fitted with an extra sensor which amplifies the visible light spectrum and overlays it to the UHD display." @@ -175,22 +115,22 @@ /datum/design/night_vision_goggles name = "Night Vision Goggles" desc = "Goggles that let you see through darkness unhindered." - id = "night_visision_goggles" + id = "night_vision_goggles" build_type = PROTOLATHE materials = list(/datum/material/iron = 600, /datum/material/glass = 600, /datum/material/plasma = 350, /datum/material/uranium = 1000) build_path = /obj/item/clothing/glasses/night category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY -/datum/design/night_vision_goggles_glasses - name = "Prescription Night Vision Goggles" - desc = "Goggles that let you see through darkness unhindered. Corrects vision." - id = "night_visision_goggles_glasses" +/datum/design/prescription_kit + name = "Prescription Lens Kit" + desc = "A do-it-yourself kit that lets you add a prescription overlay to any HUDs or other eyewear. Even the ones that shouldn't." + id = "prescription_kit" build_type = PROTOLATHE - materials = list(/datum/material/iron = 600, /datum/material/glass = 600, /datum/material/plasma = 350, /datum/material/uranium = 1000) - build_path = /obj/item/clothing/glasses/night/prescription + materials = list(/datum/material/iron = 500, /datum/material/glass = 200, /datum/material/silver = 100) // silver because i guess all the prescription HUDs had it? + build_path = /obj/item/prescription_kit category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING + departmental_flags = DEPARTMENTAL_FLAG_ALL ///////////////////////////////////////// //////////////////Misc/////////////////// @@ -407,6 +347,16 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SERVICE | DEPARTMENTAL_FLAG_ENGINEERING +/datum/design/light_replacer_blue + name = "Bluespace Light Replacer" + desc = "A device to automatically replace lights at a distance. Refill with working light bulbs." + id = "light_replacer_blue" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 1500, /datum/material/silver = 150, /datum/material/glass = 3000, /datum/material/bluespace = 300) + build_path = /obj/item/lightreplacer/blue + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE | DEPARTMENTAL_FLAG_ENGINEERING + /datum/design/normtrash name = "Trashbag" desc = "It's a bag for trash, you put garbage in it." diff --git a/code/modules/research/designs/mod_designs.dm b/code/modules/research/designs/mod_designs.dm new file mode 100644 index 0000000000..8ceadeb8fb --- /dev/null +++ b/code/modules/research/designs/mod_designs.dm @@ -0,0 +1,372 @@ +//MODsuit construction + +/datum/design/mod_shell + name = "MOD Shell" + desc = "A 'Nakamura Engineering' designed shell for a Modular Suit." + id = "mod_shell" + build_type = MECHFAB + materials = list(/datum/material/iron = 10000, /datum/material/plasma = 5000) + construction_time = 25 SECONDS + build_path = /obj/item/mod/construction/shell + category = list("MODsuit Chassis") + +/datum/design/mod_helmet + name = "MOD Helmet" + desc = "A 'Nakamura Engineering' designed helmet for a Modular Suit." + id = "mod_helmet" + build_type = MECHFAB + materials = list(/datum/material/iron = 5000) + construction_time = 10 SECONDS + build_path = /obj/item/mod/construction/helmet + category = list("MODsuit Chassis") + +/datum/design/mod_chestplate + name = "MOD Chestplate" + desc = "A 'Nakamura Engineering' designed chestplate for a Modular Suit." + id = "mod_chestplate" + build_type = MECHFAB + materials = list(/datum/material/iron = 5000) + construction_time = 10 SECONDS + build_path = /obj/item/mod/construction/chestplate + category = list("MODsuit Chassis") + +/datum/design/mod_gauntlets + name = "MOD Gauntlets" + desc = "'Nakamura Engineering' designed gauntlets for a Modular Suit." + id = "mod_gauntlets" + build_type = MECHFAB + materials = list(/datum/material/iron = 5000) + construction_time = 10 SECONDS + build_path = /obj/item/mod/construction/gauntlets + category = list("MODsuit Chassis") + +/datum/design/mod_boots + name = "MOD Boots" + desc = "'Nakamura Engineering' designed boots for a Modular Suit." + id = "mod_boots" + build_type = MECHFAB + materials = list(/datum/material/iron = 5000) + construction_time = 10 SECONDS + build_path = /obj/item/mod/construction/boots + category = list("MODsuit Chassis") + +/datum/design/mod_plating + name = "MOD External Plating" + desc = "External plating for a MODsuit." + id = "mod_plating_standard" + build_type = PROTOLATHE | MECHFAB + materials = list(/datum/material/iron = 6000, /datum/material/glass = 3000, /datum/material/plasma = 1000) + construction_time = 15 SECONDS + build_path = /obj/item/mod/construction/armor + category = list("MODsuit Chassis", "MODsuit Designs") + departmental_flags = DEPARTMENTAL_FLAG_ALL + research_icon = 'icons/obj/clothing/modsuit/mod_construction.dmi' + research_icon_state = "standard-plating" + +/datum/design/mod_plating/New() + . = ..() + var/obj/item/mod/construction/armor/armor_type = build_path + var/datum/mod_theme/theme = GLOB.mod_themes[initial(armor_type.theme)] + desc = "External plating for a MODsuit. [theme.desc]" + +/datum/design/mod_plating/engineering + name = "MOD Engineering Plating" + id = "mod_plating_engineering" + build_path = /obj/item/mod/construction/armor/engineering + materials = list(/datum/material/iron = 6000, /datum/material/gold = 2000, /datum/material/glass = 1000, /datum/material/plasma = 1000) + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + research_icon_state = "engineering-plating" + +/datum/design/mod_plating/atmospheric + name = "MOD Atmospheric Plating" + id = "mod_plating_atmospheric" + build_path = /obj/item/mod/construction/armor/atmospheric + materials = list(/datum/material/iron = 6000, /datum/material/titanium = 2000, /datum/material/glass = 1000, /datum/material/plasma = 1000) + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + research_icon_state = "atmospheric-plating" + +/datum/design/mod_plating/mining + name = "MOD Mining Plating" + id = "mod_plating_mining" + build_path = /obj/item/mod/construction/armor/mining + materials = list(/datum/material/iron = 6000, /datum/material/titanium = 2000, /datum/material/glass = 1000, /datum/material/plasma = 1000) + departmental_flags = DEPARTMENTAL_FLAG_CARGO + research_icon_state = "atmospheric-mining" + +/datum/design/mod_plating/medical + name = "MOD Medical Plating" + id = "mod_plating_medical" + build_path = /obj/item/mod/construction/armor/medical + materials = list(/datum/material/iron = 6000, /datum/material/silver = 2000, /datum/material/glass = 1000, /datum/material/plasma = 1000) + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + research_icon_state = "medical-plating" + +/datum/design/mod_plating/security + name = "MOD Security Plating" + id = "mod_plating_security" + build_path = /obj/item/mod/construction/armor/security + materials = list(/datum/material/iron = 6000, /datum/material/uranium = 2000, /datum/material/glass = 1000, /datum/material/plasma = 1000) + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + research_icon_state = "security-plating" + +/datum/design/mod_plating/cosmohonk + name = "MOD Cosmohonk Plating" + id = "mod_plating_cosmohonk" + build_path = /obj/item/mod/construction/armor/cosmohonk + materials = list(/datum/material/iron = 6000, /datum/material/bananium = 2000, /datum/material/glass = 1000, /datum/material/plasma = 1000) + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + research_icon_state = "cosmohonk-plating" + +/datum/design/mod_paint_kit + name = "MOD Paint Kit" + desc = "A paint kit for Modular Suits." + id = "mod_paint_kit" + build_type = MECHFAB + materials = list(/datum/material/iron = 1000, /datum/material/plastic = 500) + construction_time = 5 SECONDS + build_path = /obj/item/mod/paint + category = list("MODsuit Modules", "MODsuit Designs") + +//MODsuit modules + +/datum/design/module + name = "MOD Module" + build_type = PROTOLATHE | MECHFAB + construction_time = 1 SECONDS + materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000) + build_path = /obj/item/mod/module + category = list("MODsuit Modules", "MODsuit Designs") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +/datum/design/module/New() + . = ..() + var/obj/item/mod/module/module = build_path + desc = "[initial(module.desc)] It uses [initial(module.complexity)] complexity." + +/datum/design/module/mod_storage + name = "Storage Module" + id = "mod_storage" + materials = list(/datum/material/iron = 2500, /datum/material/glass = 500) + build_path = /obj/item/mod/module/storage + +/datum/design/module/mod_visor_medhud + name = "Medical Visor Module" + id = "mod_visor_medhud" + materials = list(/datum/material/silver = 500, /datum/material/glass = 1000) + build_path = /obj/item/mod/module/visor/medhud + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/module/mod_visor_diaghud + name = "Diagnostic Visor Module" + id = "mod_visor_diaghud" + materials = list(/datum/material/gold = 500, /datum/material/glass = 1000) + build_path = /obj/item/mod/module/visor/diaghud + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/module/mod_visor_sechud + name = "Security Visor Module" + id = "mod_visor_sechud" + materials = list(/datum/material/titanium = 500, /datum/material/glass = 1000) + build_path = /obj/item/mod/module/visor/sechud + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/module/mod_visor_meson + name = "Meson Visor Module" + id = "mod_visor_meson" + materials = list(/datum/material/uranium = 500, /datum/material/glass = 1000) + build_path = /obj/item/mod/module/visor/meson + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/module/mod_visor_welding + name = "Welding Protection Module" + id = "mod_welding" + materials = list(/datum/material/iron = 500, /datum/material/glass = 1000) + build_path = /obj/item/mod/module/welding + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/module/mod_t_ray + name = "T-Ray Scanner Module" + id = "mod_t_ray" + materials = list(/datum/material/iron = 500, /datum/material/glass = 1000) + build_path = /obj/item/mod/module/t_ray + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/module/mod_health_analyzer + name = "Health Analyzer Module" + id = "mod_health_analyzer" + materials = list(/datum/material/iron = 500, /datum/material/glass = 1000) + build_path = /obj/item/mod/module/health_analyzer + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/module/mod_stealth + name = "Cloak Module" + id = "mod_stealth" + materials = list(/datum/material/iron = 1000, /datum/material/bluespace = 500) + build_path = /obj/item/mod/module/stealth + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/module/mod_jetpack + name = "Ion Jetpack Module" + id = "mod_jetpack" + materials = list(/datum/material/iron = 1500, /datum/material/plasma = 1000) + build_path = /obj/item/mod/module/jetpack + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/module/mod_magboot + name = "Magnetic Stabilizator Module" + id = "mod_magboot" + materials = list(/datum/material/iron = 1000, /datum/material/gold = 500) + build_path = /obj/item/mod/module/magboot + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/module/mod_mag_harness + name = "Magnetic Harness Module" + id = "mod_mag_harness" + materials = list(/datum/material/iron = 1500, /datum/material/silver = 500) + build_path = /obj/item/mod/module/magnetic_harness + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/module/mod_tether + name = "Emergency Tether Module" + id = "mod_tether" + materials = list(/datum/material/iron = 1000, /datum/material/silver = 500) + build_path = /obj/item/mod/module/tether + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/module/mod_mouthhole + name = "Eating Apparatus Module" + id = "mod_mouthhole" + materials = list(/datum/material/iron = 1500) + build_path = /obj/item/mod/module/mouthhole + +/datum/design/module/mod_rad_protection + name = "Radiation Protection Module" + id = "mod_rad_protection" + materials = list(/datum/material/iron = 1000, /datum/material/uranium = 1000) + build_path = /obj/item/mod/module/rad_protection + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/module/mod_emp_shield + name = "EMP Shield Module" + id = "mod_emp_shield" + materials = list(/datum/material/iron = 1000, /datum/material/plasma = 1000) + build_path = /obj/item/mod/module/emp_shield + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/module/mod_flashlight + name = "Flashlight Module" + id = "mod_flashlight" + materials = list(/datum/material/iron = 500, /datum/material/glass = 1000) + build_path = /obj/item/mod/module/flashlight + +/datum/design/module/mod_reagent_scanner + name = "Reagent Scanner Module" + id = "mod_reagent_scanner" + materials = list(/datum/material/glass = 1000) + build_path = /obj/item/mod/module/reagent_scanner + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/module/mod_gps + name = "Internal GPS Module" + id = "mod_gps" + materials = list(/datum/material/iron = 500, /datum/material/glass = 500) + build_path = /obj/item/mod/module/gps + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_CARGO + +/datum/design/module/mod_constructor + name = "Constructor Module" + id = "mod_constructor" + materials = list(/datum/material/iron = 1000, /datum/material/titanium = 500) + build_path = /obj/item/mod/module/constructor + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/module/mod_quick_carry + name = "Quick Carry Module" + id = "mod_quick_carry" + materials = list(/datum/material/iron = 1000, /datum/material/titanium = 500) + build_path = /obj/item/mod/module/quick_carry + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/module/mod_bikehorn + name = "Bike Horn Module" + id = "mod_bikehorn" + materials = list(/datum/material/plastic = 500, /datum/material/iron = 500) + build_path = /obj/item/mod/module/bikehorn + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/module/mod_microwave_beam + name = "Microwave Beam Module" + id = "mod_microwave_beam" + materials = list(/datum/material/iron = 1000, /datum/material/uranium = 500) + build_path = /obj/item/mod/module/microwave_beam + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/module/mod_clamp + name = "Crate Clamp Module" + id = "mod_clamp" + materials = list(/datum/material/iron = 2000) + build_path = /obj/item/mod/module/clamp + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/module/mod_drill + name = "Drill Module" + id = "mod_drill" + materials = list(/datum/material/silver = 1000, /datum/material/iron = 2000) + build_path = /obj/item/mod/module/drill + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/module/mod_orebag + name = "Ore Bag Module" + id = "mod_orebag" + materials = list(/datum/material/iron = 1500) + build_path = /obj/item/mod/module/orebag + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/module/mod_dna_lock + name = "DNA Lock Module" + id = "mod_dna_lock" + materials = list(/datum/material/diamond = 500, /datum/material/glass = 1000) + build_path = /obj/item/mod/module/dna_lock + +/datum/design/module/mister_atmos + name = "Resin Mister Module" + id = "mod_mister_atmos" + materials = list(/datum/material/glass = 1000, /datum/material/titanium = 1500) + build_path = /obj/item/mod/module/mister/atmos + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/module/mod_holster + name = "Holster Module" + id = "mod_holster" + materials = list(/datum/material/iron = 1500, /datum/material/glass = 500) + build_path = /obj/item/mod/module/holster + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/module/surgicalprocessor + name = "Surgical Processor Module" + id = "mod_surgicalprocessor" + materials = list(/datum/material/titanium = 250, /datum/material/glass = 1000, /datum/material/silver = 1500) + build_path = /obj/item/mod/module/surgical_processor + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/module/defibrillator + name = "Defibrillator Module" + id = "mod_defib" + materials = list(/datum/material/titanium = 250, /datum/material/diamond = 1000, /datum/material/silver = 1500) + build_path = /obj/item/mod/module/defibrillator + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +//MODsuit anomalock modules +/datum/design/module/mod_antigrav + name = "Anti-Gravity Module" + id = "mod_antigrav" + materials = list(/datum/material/iron = 2500, /datum/material/glass = 2000, /datum/material/uranium = 2000) + build_path = /obj/item/mod/module/anomaly_locked/antigrav + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/module/mod_teleporter + name = "Teleporter Module" + id = "mod_teleporter" + materials = list(/datum/material/iron = 2500, /datum/material/glass = 2000, /datum/material/bluespace = 2000) + build_path = /obj/item/mod/module/anomaly_locked/teleporter + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index cc02e271f9..9c7ca5b999 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -84,15 +84,7 @@ Note: Must be placed within 3 tiles of the R&D Console reclaim_materials_from(thing) for(var/mob/M in thing) M.death() - if(istype(thing, /obj/item/stack/sheet)) - var/obj/item/stack/sheet/S = thing - if(S.amount > 1 && !innermode) - S.amount-- - loaded_item = S - else - qdel(S) - else - qdel(thing) + qdel(thing) if (!innermode) update_icon() return TRUE diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index e6128ed5c2..ba0b17c113 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -66,7 +66,7 @@ if(initial(tempCheck.icon_state) != null) critical_items += I -/obj/machinery/rnd/experimentor/Initialize() +/obj/machinery/rnd/experimentor/Initialize(mapload) . = ..() trackedIan = locate(/mob/living/simple_animal/pet/dog/corgi/Ian) in GLOB.mob_living_list @@ -537,7 +537,7 @@ var/cooldownMax = 60 var/cooldown -/obj/item/relic/Initialize() +/obj/item/relic/Initialize(mapload) . = ..() icon_state = pick("shock_kit","armor-igniter-analyzer","infra-igniter0","infra-igniter1","radio-multitool","prox-radio1","radio-radio","timer-multitool0","radio-igniter-tank") realName = "[pick("broken","twisted","spun","improved","silly","regular","badly made")] [pick("device","object","toy","illegal tech","weapon")]" diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm index 98b04a8382..30d0c70566 100644 --- a/code/modules/research/machinery/_production.dm +++ b/code/modules/research/machinery/_production.dm @@ -120,7 +120,7 @@ return round(A / max(1, all_materials[mat] * ef)) /obj/machinery/rnd/production/proc/efficient_with(path) - return !ispath(path, /obj/item/stack/sheet) && !ispath(path, /obj/item/stack/ore/bluespace_crystal) + return !ispath(path, /obj/item/stack/sheet) && !ispath(path, /obj/item/stack/ore/bluespace_crystal) && !ispath(path, /obj/item/stack/ducts) /obj/machinery/rnd/production/proc/user_try_print_id(id, amount) if((!istype(linked_console) && requires_console) || !id) @@ -232,9 +232,12 @@ var/amount = materials.mat_container.materials[mat_id] var/ref = REF(M) l += "* [amount] of [M.name]: " - if(amount >= MINERAL_MATERIAL_AMOUNT) l += "Eject [RDSCREEN_NOBREAK]" + if(amount >= MINERAL_MATERIAL_AMOUNT) l += "1x [RDSCREEN_NOBREAK]" if(amount >= MINERAL_MATERIAL_AMOUNT*5) l += "5x [RDSCREEN_NOBREAK]" - if(amount >= MINERAL_MATERIAL_AMOUNT) l += "All[RDSCREEN_NOBREAK]" + if(amount >= MINERAL_MATERIAL_AMOUNT*10) l += "10x [RDSCREEN_NOBREAK]" + if(amount >= MINERAL_MATERIAL_AMOUNT*20) l += "20x [RDSCREEN_NOBREAK]" + if(amount >= MINERAL_MATERIAL_AMOUNT*50) l += "50x [RDSCREEN_NOBREAK]" + if(amount >= MINERAL_MATERIAL_AMOUNT) l += "Max Stack[RDSCREEN_NOBREAK]" l += "" l += "
    [RDSCREEN_NOBREAK]" return l diff --git a/code/modules/research/machinery/protolathe.dm b/code/modules/research/machinery/protolathe.dm index 684f27ccad..4057503e09 100644 --- a/code/modules/research/machinery/protolathe.dm +++ b/code/modules/research/machinery/protolathe.dm @@ -15,7 +15,8 @@ "Weapons", "Ammo", "Firing Pins", - "Computer Parts" + "Computer Parts", + "MODsuit Designs" ) production_animation = "protolathe_n" allowed_buildtypes = PROTOLATHE diff --git a/code/modules/research/machinery/techfab.dm b/code/modules/research/machinery/techfab.dm index f93560ed10..110b6c037c 100644 --- a/code/modules/research/machinery/techfab.dm +++ b/code/modules/research/machinery/techfab.dm @@ -26,7 +26,8 @@ "Subspace Telecomms", "Research Machinery", "Misc. Machinery", - "Computer Parts" + "Computer Parts", + "MODsuit Designs" ) console_link = FALSE production_animation = "protolathe_n" diff --git a/code/modules/research/nanites/nanite_chamber.dm b/code/modules/research/nanites/nanite_chamber.dm index 8675d54b46..fe776e86c5 100644 --- a/code/modules/research/nanites/nanite_chamber.dm +++ b/code/modules/research/nanites/nanite_chamber.dm @@ -20,7 +20,7 @@ var/busy_message var/message_cooldown = 0 -/obj/machinery/nanite_chamber/Initialize() +/obj/machinery/nanite_chamber/Initialize(mapload) . = ..() occupant_typecache = GLOB.typecache_living diff --git a/code/modules/research/nanites/nanite_chamber_computer.dm b/code/modules/research/nanites/nanite_chamber_computer.dm index f69cb58456..0755487a7a 100644 --- a/code/modules/research/nanites/nanite_chamber_computer.dm +++ b/code/modules/research/nanites/nanite_chamber_computer.dm @@ -6,7 +6,7 @@ icon_screen = "nanite_chamber_control" circuit = /obj/item/circuitboard/computer/nanite_chamber_control -/obj/machinery/computer/nanite_chamber_control/Initialize() +/obj/machinery/computer/nanite_chamber_control/Initialize(mapload) . = ..() find_chamber() diff --git a/code/modules/research/nanites/nanite_program_hub.dm b/code/modules/research/nanites/nanite_program_hub.dm index 9a625cd0c7..a097a08532 100644 --- a/code/modules/research/nanites/nanite_program_hub.dm +++ b/code/modules/research/nanites/nanite_program_hub.dm @@ -22,7 +22,7 @@ list(name = "Protocols"), ) -/obj/machinery/nanite_program_hub/Initialize() +/obj/machinery/nanite_program_hub/Initialize(mapload) . = ..() linked_techweb = SSresearch.science_tech @@ -148,6 +148,6 @@ disk.name = initial(disk.name) . = TRUE -/obj/machinery/nanite_program_hub/admin/Initialize() +/obj/machinery/nanite_program_hub/admin/Initialize(mapload) . = ..() linked_techweb = SSresearch.admin_tech diff --git a/code/modules/research/nanites/nanite_programs/healing.dm b/code/modules/research/nanites/nanite_programs/healing.dm index 81a837504a..4603b04b1d 100644 --- a/code/modules/research/nanites/nanite_programs/healing.dm +++ b/code/modules/research/nanites/nanite_programs/healing.dm @@ -234,7 +234,7 @@ var/mob/living/carbon/C = host_mob if(C.get_ghost()) return FALSE - return C.can_defib() + return C.can_revive() /datum/nanite_program/defib/proc/zap() var/mob/living/carbon/C = host_mob @@ -242,13 +242,24 @@ sleep(30) playsound(C, 'sound/machines/defib_zap.ogg', 50, FALSE) if(check_revivable()) + var/tplus = world.time - C.timeofdeath playsound(C, 'sound/machines/defib_success.ogg', 50, FALSE) C.set_heartattack(FALSE) + var/oxydamage = C.getOxyLoss() + if(C.health < HEALTH_THRESHOLD_FULLCRIT && oxydamage) + var/diff = C.health - HEALTH_THRESHOLD_FULLCRIT + C.adjustOxyLoss(diff) //Heal their oxydamage up to hardcrit (or if less, as much as they have, since the proc has sanity) C.revive(full_heal = FALSE, admin_revive = FALSE) C.emote("gasp") C.Jitter(100) SEND_SIGNAL(C, COMSIG_LIVING_MINOR_SHOCK) - log_game("[C] has been successfully defibrillated by nanites.") + var/list/policies = CONFIG_GET(keyed_list/policy) + var/timelimit = CONFIG_GET(number/defib_cmd_time_limit) * 10 //the config is in seconds, not deciseconds + var/late = timelimit && (tplus > timelimit) + var/policy = late? policies[POLICYCONFIG_ON_DEFIB_LATE] : policies[POLICYCONFIG_ON_DEFIB_INTACT] + if(policy) + to_chat(C, policy) + C.log_message("has been successfully defibrillated by nanites, [tplus] deciseconds from time of death, considered [late? "late" : "memory-intact"] revival under configured policy limits.", LOG_GAME) else playsound(C, 'sound/machines/defib_failed.ogg', 50, FALSE) diff --git a/code/modules/research/nanites/program_disks.dm b/code/modules/research/nanites/program_disks.dm index 667618173c..291982059c 100644 --- a/code/modules/research/nanites/program_disks.dm +++ b/code/modules/research/nanites/program_disks.dm @@ -7,7 +7,7 @@ var/program_type var/datum/nanite_program/program -/obj/item/disk/nanite_program/Initialize() +/obj/item/disk/nanite_program/Initialize(mapload) . = ..() if(program_type) program = new program_type diff --git a/code/modules/research/nanites/public_chamber.dm b/code/modules/research/nanites/public_chamber.dm index b7a8db4080..c6c53779a9 100644 --- a/code/modules/research/nanites/public_chamber.dm +++ b/code/modules/research/nanites/public_chamber.dm @@ -18,7 +18,7 @@ var/busy_icon_state var/message_cooldown = 0 -/obj/machinery/public_nanite_chamber/Initialize() +/obj/machinery/public_nanite_chamber/Initialize(mapload) . = ..() occupant_typecache = GLOB.typecache_living diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index a9284a19f7..29181021c7 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -87,7 +87,7 @@ Nothing else in the console has ID requirements. linked_imprinter = D D.linked_console = src -/obj/machinery/computer/rdconsole/Initialize() +/obj/machinery/computer/rdconsole/Initialize(mapload) . = ..() stored_research = SSresearch.science_tech stored_research.consoles_accessing[src] = TRUE @@ -1145,7 +1145,7 @@ Nothing else in the console has ID requirements. req_access = null req_access_txt = "29" -/obj/machinery/computer/rdconsole/robotics/Initialize() +/obj/machinery/computer/rdconsole/robotics/Initialize(mapload) . = ..() if(circuit) circuit.name = "R&D Console - Robotics (Computer Board)" diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm index f39f5b1584..3ab3465b9e 100644 --- a/code/modules/research/rdmachines.dm +++ b/code/modules/research/rdmachines.dm @@ -18,7 +18,7 @@ /obj/machinery/rnd/proc/reset_busy() busy = FALSE -/obj/machinery/rnd/Initialize() +/obj/machinery/rnd/Initialize(mapload) . = ..() wires = new /datum/wires/rnd(src) diff --git a/code/modules/research/research_disk.dm b/code/modules/research/research_disk.dm index a656093d98..0ac80040f9 100644 --- a/code/modules/research/research_disk.dm +++ b/code/modules/research/research_disk.dm @@ -6,7 +6,7 @@ custom_materials = list(/datum/material/iron=300, /datum/material/glass=100) var/datum/techweb/stored_research -/obj/item/disk/tech_disk/Initialize() +/obj/item/disk/tech_disk/Initialize(mapload) . = ..() pixel_x = rand(-5, 5) pixel_y = rand(-5, 5) @@ -17,7 +17,7 @@ desc = "A debug item for research" custom_materials = null -/obj/item/disk/tech_disk/debug/Initialize() +/obj/item/disk/tech_disk/debug/Initialize(mapload) . = ..() stored_research = new /datum/techweb/admin @@ -27,7 +27,7 @@ icon_state = "rndmajordisk" custom_materials = list(/datum/material/iron=300, /datum/material/glass=100) -/obj/item/disk/tech_disk/major/Initialize() +/obj/item/disk/tech_disk/major/Initialize(mapload) . = ..() stored_research = new /datum/techweb/bepis @@ -36,7 +36,7 @@ desc = "A technology disk containing schematics for syndicate inspired equipment." custom_materials = null -/obj/item/disk/tech_disk/illegal/Initialize() +/obj/item/disk/tech_disk/illegal/Initialize(mapload) . = ..() stored_research = new /datum/techweb/syndicate @@ -45,6 +45,6 @@ desc = "You feel like it's not Gray because of its color." custom_materials = null -/obj/item/disk/tech_disk/abductor/Initialize() +/obj/item/disk/tech_disk/abductor/Initialize(mapload) . = ..() stored_research = new /datum/techweb/abductor diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index beb3561025..1794fd852b 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -18,7 +18,7 @@ var/temp_tolerance_high = T20C var/temp_penalty_coefficient = 0.5 //1 = -1 points per degree above high tolerance. 0.5 = -0.5 points per degree above high tolerance. -/obj/machinery/rnd/server/Initialize() +/obj/machinery/rnd/server/Initialize(mapload) . = ..() SSresearch.servers |= src stored_research = SSresearch.science_tech diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm index de0ebcb63a..c823799952 100644 --- a/code/modules/research/stock_parts.dm +++ b/code/modules/research/stock_parts.dm @@ -123,7 +123,7 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi var/rating = 1 rad_flags = RAD_NO_CONTAMINATE -/obj/item/stock_parts/Initialize() +/obj/item/stock_parts/Initialize(mapload) . = ..() pixel_x = rand(-5, 5) pixel_y = rand(-5, 5) diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm index 3c1ba05267..dc07a5a184 100644 --- a/code/modules/research/techweb/_techweb.dm +++ b/code/modules/research/techweb/_techweb.dm @@ -17,8 +17,9 @@ var/list/obj/machinery/computer/rdconsole/consoles_accessing = list() var/id = "generic" var/list/research_logs = list() //IC logs. - var/largest_bomb_value = 0 + var/largest_values = list() var/organization = "Third-Party" //Organization name, used for display. + var/list/next_income = list() //To be applied on the next passive techweb income var/list/last_bitcoins = list() //Current per-second production, used for display only. var/list/discovered_mutations = list() //Mutations discovered by genetics, this way they are shared and cant be destroyed by destroying a single console var/list/tiers = list() //Assoc list, id = number, 1 is available, 2 is all reqs are 1, so on @@ -105,10 +106,15 @@ V.rescan_views() V.updateUsrDialog() -/datum/techweb/proc/add_point_list(list/pointlist) - for(var/i in pointlist) - if(SSresearch.point_types[i] && pointlist[i] > 0) - research_points[i] += pointlist[i] +/datum/techweb/proc/add_point_list(list/pointlist, income = TRUE) + if(income) // i DO NOT TRUST byond to optimize this way properly + for(var/i in pointlist) + if(SSresearch.point_types[i] && pointlist[i] > 0) + next_income[i] += pointlist[i] + else + for(var/i in pointlist) + if(SSresearch.point_types[i] && pointlist[i] > 0) + research_points[i] += pointlist[i] /datum/techweb/proc/add_points_all(amount) var/list/l = SSresearch.point_types.Copy() @@ -116,6 +122,12 @@ l[i] = amount add_point_list(l) +/datum/techweb/proc/commit_income() + . = next_income.Copy() + add_point_list(next_income, income = FALSE) + for(var/i in next_income) + next_income[i] = 0 + /datum/techweb/proc/remove_point_list(list/pointlist) for(var/i in pointlist) if(SSresearch.point_types[i] && pointlist[i] > 0) @@ -142,7 +154,7 @@ if(unlock_hidden) for(var/i in receiver.hidden_nodes) CHECK_TICK - if(!hidden_nodes[i]) + if(available_nodes[i] || researched_nodes[i] || visible_nodes[i]) receiver.hidden_nodes -= i //We can see it so let them see it too. for(var/i in researched_nodes) CHECK_TICK @@ -170,16 +182,22 @@ /datum/techweb/proc/get_researched_nodes() return researched_nodes - hidden_nodes -/datum/techweb/proc/add_point_type(type, amount) +/datum/techweb/proc/add_point_type(type, amount, income = TRUE) if(!SSresearch.point_types[type] || (amount <= 0)) return FALSE - research_points[type] += amount + if(income) + next_income[type] += amount + else + research_points[type] += amount return TRUE -/datum/techweb/proc/modify_point_type(type, amount) +/datum/techweb/proc/modify_point_type(type, amount, income = TRUE) if(!SSresearch.point_types[type]) return FALSE - research_points[type] = max(0, research_points[type] + amount) + if(income && amount > 0) + next_income[type] += amount + else + research_points[type] = max(0, research_points[type] + amount) return TRUE /datum/techweb/proc/remove_point_type(type, amount) diff --git a/code/modules/research/techweb/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm index 8c91c09abb..8ea4b95d03 100644 --- a/code/modules/research/techweb/_techweb_node.dm +++ b/code/modules/research/techweb/_techweb_node.dm @@ -106,4 +106,4 @@ "destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "bepis", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", "paystand", "space_heater", "beaker", "large_beaker", "xlarge_beaker", "bucket", "hypovial", "large_hypovial", "syringe", "pillbottle", "sec_shellclip", "sec_beanbag", "sec_rshot", "sec_bshot", "sec_slug", "sec_islug", "sec_dart", "sec_38", "sec_38lethal", - "rglass","plasteel","plastitanium","plasmaglass","plasmareinforcedglass","titaniumglass","plastitaniumglass") + "rglass","plasteel","plastitanium","plasmaglass","plasmareinforcedglass","titaniumglass","plastitaniumglass", "salestagger", "light_replacer") diff --git a/code/modules/research/techweb/nodes/bepis_nodes.dm b/code/modules/research/techweb/nodes/bepis_nodes.dm index fa17d62e50..ec29979bdf 100644 --- a/code/modules/research/techweb/nodes/bepis_nodes.dm +++ b/code/modules/research/techweb/nodes/bepis_nodes.dm @@ -60,6 +60,16 @@ hidden = TRUE experimental = TRUE +/datum/techweb_node/nanite_storage_protocols + id = "nanite_storage_protocols" + display_name = "Nanite Storage Protocols" + description = "Advanced behaviours that allow nanites to increase their maximum volume at variable cost." + prereq_ids = list("nanite_smart") + design_ids = list("hive_nanites", "zip_nanites", "free_range_nanites", "unsafe_storage_nanites") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) + hidden = TRUE + experimental = TRUE + /datum/techweb_node/interrogation id = "interrogation" display_name = "Enhanced Interrogation Technology" diff --git a/code/modules/research/techweb/nodes/biotech_nodes.dm b/code/modules/research/techweb/nodes/biotech_nodes.dm index 350bbaa5c3..1a3aa2644e 100644 --- a/code/modules/research/techweb/nodes/biotech_nodes.dm +++ b/code/modules/research/techweb/nodes/biotech_nodes.dm @@ -13,7 +13,7 @@ display_name = "Advanced Biotechnology" description = "Advanced Biotechnology" prereq_ids = list("biotech") - design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "meta_beaker", "healthanalyzer_advanced", "harvester", "holobarrier_med", "defibrillator_compact", "smartdartgun", "medicinalsmartdart", "pHmeter", "hypospray_mkii", "containmentbodybag") + design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "meta_beaker", "healthanalyzer_advanced", "harvester", "holobarrier_med", "defibrillator_compact", "smartdartgun", "medicinalsmartdart", "pHmeter", "hypospray_mkii", "containmentbodybag", "prescription_kit") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) /datum/techweb_node/bio_process diff --git a/code/modules/research/techweb/nodes/bluespace_nodes.dm b/code/modules/research/techweb/nodes/bluespace_nodes.dm index 90b69eb28d..28cda2cfa3 100644 --- a/code/modules/research/techweb/nodes/bluespace_nodes.dm +++ b/code/modules/research/techweb/nodes/bluespace_nodes.dm @@ -13,7 +13,7 @@ display_name = "Applied Bluespace Research" description = "Using bluespace to make things faster and better." prereq_ids = list("bluespace_basic", "engineering") - design_ids = list("bs_rped","biobag_holding","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "bluespacesmartdart", "xenobio_slimebasic", "bluespace_tray") + design_ids = list("bs_rped","biobag_holding","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "bluespacesmartdart", "xenobio_slimebasic", "bluespace_tray", "light_replacer_blue") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) /datum/techweb_node/adv_bluespace @@ -61,7 +61,7 @@ display_name = "Bluespace Travel" description = "Application of Bluespace for static teleportation technology." prereq_ids = list("adv_power", "adv_bluespace") - design_ids = list("tele_station", "tele_hub", "quantumpad", "quantum_keycard", "launchpad", "launchpad_console", "teleconsole", "roastingstick", "bluespace_pipe") + design_ids = list("tele_station", "tele_hub", "quantumpad", "quantum_keycard", "launchpad", "launchpad_console", "teleconsole", "roastingstick", "bluespace_pipe","swapper") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) /datum/techweb_node/unregulated_bluespace diff --git a/code/modules/research/techweb/nodes/computer_hud_nodes.dm b/code/modules/research/techweb/nodes/computer_hud_nodes.dm index 2db03861e9..780c146fee 100644 --- a/code/modules/research/techweb/nodes/computer_hud_nodes.dm +++ b/code/modules/research/techweb/nodes/computer_hud_nodes.dm @@ -40,7 +40,7 @@ display_name = "Integrated HUDs" description = "The usefulness of computerized records, projected straight onto your eyepiece!" prereq_ids = list("comp_recordkeeping", "emp_basic") - design_ids = list("health_hud", "security_hud", "diagnostic_hud", "scigoggles", "health_hud_prescription", "security_hud_prescription", "diagnostic_hud_prescription") + design_ids = list("health_hud", "security_hud", "diagnostic_hud", "scigoggles") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500) /datum/techweb_node/NVGtech @@ -48,7 +48,7 @@ display_name = "Night Vision Technology" description = "Allows seeing in the dark without actual light!" prereq_ids = list("integrated_HUDs", "adv_engi", "emp_adv") - design_ids = list("health_hud_night", "security_hud_night", "diagnostic_hud_night", "night_visision_goggles", "nvgmesons", "night_visision_goggles_glasses") + design_ids = list("health_hud_night", "security_hud_night", "diagnostic_hud_night", "night_vision_goggles", "nvgmesons") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) /datum/techweb_node/computer_board_gaming @@ -56,5 +56,5 @@ display_name = "Games and Toys" description = "For the slackers on the station." prereq_ids = list("comptech") - design_ids = list("arcade_battle", "arcade_orion", "arcade_minesweeper", "slotmachine", "autoylathe") + design_ids = list("arcade_battle", "arcade_orion", "slotmachine", "autoylathe") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) diff --git a/code/modules/research/techweb/nodes/engineering_nodes.dm b/code/modules/research/techweb/nodes/engineering_nodes.dm index 2b5d6f3cc1..51b9480c27 100644 --- a/code/modules/research/techweb/nodes/engineering_nodes.dm +++ b/code/modules/research/techweb/nodes/engineering_nodes.dm @@ -7,8 +7,8 @@ prereq_ids = list("base") design_ids = list("solarcontrol", "recharger", "powermonitor", "rped", "pacman", "adv_capacitor", "adv_scanning", "emitter", "high_cell", "adv_matter_bin", "atmosalerts", "atmos_control", "recycler", "autolathe", "autolathe_secure", "high_micro_laser", "nano_mani", "mesons", "thermomachine", "rad_collector", "tesla_coil", "grounding_rod", - "apc_control", "power control", "airlock_board", "firelock_board", "airalarm_electronics", "firealarm_electronics", "cell_charger", "stack_console", "stack_machine", "rcd_ammo","oxygen_tank", - "plasma_tank", "emergency_oxygen", "emergency_oxygen_engi", "plasmaman_tank_belt", "colormate") + "apc_control", "power control", "airlock_board", "firelock_board", "airalarm_electronics", "firealarm_electronics", "cell_charger", "stack_console", "stack_machine", "rcd_ammo", "oxygen_tank", + "plasma_tank", "emergency_oxygen", "emergency_oxygen_engi", "plasmaman_tank_belt", "colormate", "conveyor_sorter") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 6000) /datum/techweb_node/adv_engi @@ -17,8 +17,7 @@ description = "Pushing the boundaries of physics, one chainsaw-fist at a time." prereq_ids = list("engineering", "emp_basic") design_ids = list("engine_goggles", "magboots", "forcefield_projector", "weldingmask" , "rcd_loaded", "rpd", - "tray_goggles_prescription", "engine_goggles_prescription", "mesons_prescription", "rcd_upgrade_frames", - "rcd_upgrade_simple_circuits", "rcd_ammo_large", "sheetifier") + "rcd_upgrade_frames", "rcd_upgrade_simple_circuits", "rcd_ammo_large", "sheetifier") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4000) /datum/techweb_node/anomaly diff --git a/code/modules/research/techweb/nodes/mecha_nodes.dm b/code/modules/research/techweb/nodes/mecha_nodes.dm index 2e77f697da..740faf3832 100644 --- a/code/modules/research/techweb/nodes/mecha_nodes.dm +++ b/code/modules/research/techweb/nodes/mecha_nodes.dm @@ -14,7 +14,7 @@ starting_node = TRUE display_name = "Basic Exosuit Equipment" description = "Various tools fit for basic mech units" - design_ids = list("mech_drill", "mech_mscanner", "mech_extinguisher", "mech_cable_layer") + design_ids = list("mech_drill", "mech_mscanner", "mech_extinguisher") /datum/techweb_node/adv_mecha id = "adv_mecha" diff --git a/code/modules/research/techweb/nodes/medical_nodes.dm b/code/modules/research/techweb/nodes/medical_nodes.dm index 1d7d579dad..7b6047724f 100644 --- a/code/modules/research/techweb/nodes/medical_nodes.dm +++ b/code/modules/research/techweb/nodes/medical_nodes.dm @@ -13,7 +13,7 @@ display_name = "Cryostasis Technology" description = "Smart freezing of objects to preserve them!" prereq_ids = list("adv_engi", "biotech") - design_ids = list("splitbeaker", "noreactsyringe", "cryotube", "cryo_Grenade") + design_ids = list("splitbeaker", "noreactsyringe", "cryotube", "cryo_Grenade", "stasis") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000) /datum/techweb_node/adv_defibrillator_tec @@ -152,5 +152,5 @@ display_name = "Alien Surgery" description = "Abductors did nothing wrong." prereq_ids = list("exp_surgery", "alientech") - design_ids = list("surgery_brainwashing","surgery_zombie", "surgery_ext_dissection", "surgery_heal_combo_upgrade_femto") + design_ids = list("surgery_brainwashing", "surgery_robot_brainwashing", "surgery_zombie", "surgery_ext_dissection", "surgery_heal_combo_upgrade_femto") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) diff --git a/code/modules/research/techweb/nodes/misc_nodes.dm b/code/modules/research/techweb/nodes/misc_nodes.dm index 2e5fdca6bf..f26a34148f 100644 --- a/code/modules/research/techweb/nodes/misc_nodes.dm +++ b/code/modules/research/techweb/nodes/misc_nodes.dm @@ -12,7 +12,7 @@ display_name = "Advanced Data Theory" description = "Better insight into programming and data." prereq_ids = list("datatheory") - design_ids = list("icprinter", "icupgadv", "icupgclo") + design_ids = list("icprinter", "icupgadv", "icupgclo","bounty_pad","bounty_pad_control") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000) /////////////////////////plasma tech///////////////////////// diff --git a/code/modules/research/techweb/nodes/mod_nodes.dm b/code/modules/research/techweb/nodes/mod_nodes.dm new file mode 100644 index 0000000000..db453bb0d6 --- /dev/null +++ b/code/modules/research/techweb/nodes/mod_nodes.dm @@ -0,0 +1,125 @@ +/datum/techweb_node/mod_basic + id = "mod" + starting_node = TRUE + display_name = "Basic Modular Suits" + description = "Specialized back mounted power suits with various different modules." + design_ids = list( + "mod_shell", + "mod_helmet", + "mod_chestplate", + "mod_gauntlets", + "mod_boots", + "mod_plating_standard", + "mod_paint_kit", + "mod_storage", + "mod_welding", + "mod_mouthhole", + "mod_flashlight", + ) + +/datum/techweb_node/mod_advanced + id = "mod_advanced" + display_name = "Advanced Modular Suits" + description = "More advanced modules, to improve modular suits." + prereq_ids = list("mod", "robotics") + design_ids = list( + "mod_plating_mining", + "mod_visor_diaghud", + "mod_gps", + "mod_reagent_scanner", + "mod_clamp", + "mod_drill", + "mod_orebag", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + +/datum/techweb_node/mod_engineering + id = "mod_engineering" + display_name = "Engineering Modular Suits" + description = "Engineering suits, for powered engineers." + prereq_ids = list("mod_advanced", "engineering") + design_ids = list( + "mod_plating_engineering", + "mod_visor_meson", + "mod_t_ray", + "mod_magboot", + "mod_tether", + "mod_constructor", + "mod_mister_atmos", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + +/datum/techweb_node/mod_advanced_engineering + id = "mod_advanced_engineering" + display_name = "Advanced Engineering Modular Suits" + description = "Advanced Engineering suits, for advanced powered engineers." + prereq_ids = list("mod_engineering", "adv_engi") + design_ids = list( + "mod_plating_atmospheric", + "mod_jetpack", + "mod_rad_protection", + "mod_emp_shield", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500) + +/datum/techweb_node/mod_medical + id = "mod_medical" + display_name = "Medical Modular Suits" + description = "Medical suits for quick rescue purposes." + prereq_ids = list("mod_advanced", "biotech") + design_ids = list( + "mod_plating_medical", + "mod_visor_medhud", + "mod_health_analyzer", + "mod_quick_carry", + "mod_dna_lock", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + +/datum/techweb_node/mod_advanced_medical + id = "mod_advanced_medical" + display_name = "Advanced Medical Modular Suits" + description = "Advanced medical suits for quicker rescue purposes." + prereq_ids = list("mod_medical", "adv_biotech") + design_ids = list( + "mod_defib", + "mod_surgicalprocessor", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500) + +/datum/techweb_node/mod_security + id = "mod_security" + display_name = "Security Modular Suits" + description = "Security suits for space crime handling." + prereq_ids = list("mod_advanced", "sec_basic") + design_ids = list( + "mod_plating_security", + "mod_visor_sechud", + "mod_stealth", + "mod_mag_harness", + "mod_holster", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + +/datum/techweb_node/mod_entertainment + id = "mod_entertainment" + display_name = "Entertainment Modular Suits" + description = "Powered suits for protection against low-humor environments." + prereq_ids = list("mod_advanced", "clown") + design_ids = list( + "mod_plating_cosmohonk", + "mod_bikehorn", + "mod_microwave_beam", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + +/datum/techweb_node/mod_anomaly + id = "mod_anomaly" + display_name = "Anomalock Modular Suits" + description = "Modules for modular suits that require anomaly cores to function." + prereq_ids = list("mod_advanced", "anomaly_research") + design_ids = list( + "mod_antigrav", + "mod_teleporter", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) diff --git a/code/modules/research/techweb/nodes/robotics_nodes.dm b/code/modules/research/techweb/nodes/robotics_nodes.dm index 6248cd99aa..ee4fbd261b 100644 --- a/code/modules/research/techweb/nodes/robotics_nodes.dm +++ b/code/modules/research/techweb/nodes/robotics_nodes.dm @@ -28,7 +28,7 @@ display_name = "Advanced Robotics Research" description = "It can even do the dishes!" prereq_ids = list("robotics") - design_ids = list("borg_upgrade_diamonddrill", "borg_upgrade_advancedmop", "borg_upgrade_advcutter") + design_ids = list("borg_upgrade_diamonddrill", "borg_upgrade_advancedmop", "borg_upgrade_advcutter", "nanogel") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000) /datum/techweb_node/neural_programming diff --git a/code/modules/research/techweb/nodes/tools_nodes.dm b/code/modules/research/techweb/nodes/tools_nodes.dm index 180cdb5778..004795113b 100644 --- a/code/modules/research/techweb/nodes/tools_nodes.dm +++ b/code/modules/research/techweb/nodes/tools_nodes.dm @@ -5,7 +5,7 @@ display_name = "Basic Tools" description = "Basic mechanical, electronic, surgical and botanical tools." prereq_ids = list("base") - design_ids = list("screwdriver", "wrench", "wirecutters", "crowbar", "multitool", "welding_tool", "tscanner", "analyzer", "cable_coil", "pipe_painter", "airlock_painter", "decal_painter", "scalpel", "circular_saw", "surgicaldrill", "retractor", "cautery", "hemostat", "cultivator", "plant_analyzer", "shovel", "spade", "hatchet", "mop", "broom", "normtrash", "spraycan") + design_ids = list("screwdriver", "wrench", "wirecutters", "crowbar", "multitool", "welding_tool", "tscanner", "analyzer", "cable_coil", "pipe_painter", "airlock_painter", "decal_painter", "tile_sprayer", "scalpel", "circular_saw", "surgicaldrill", "retractor", "cautery", "hemostat", "cultivator", "plant_analyzer", "shovel", "spade", "hatchet", "mop", "broom", "normtrash", "spraycan") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 500) /datum/techweb_node/basic_mining @@ -37,7 +37,7 @@ display_name = "Botanical Engineering" description = "Botanical tools." prereq_ids = list("adv_engi", "biotech") - design_ids = list("diskplantgene", "portaseeder", "plantgenes", "flora_gun", "hydro_tray", "biogenerator", "seed_extractor") + design_ids = list("diskplantgene", "portaseeder", "plantgenes", "flora_gun", "hydro_tray", "biogenerator", "seed_extractor", "autoloom") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2750) /datum/techweb_node/exp_tools diff --git a/code/modules/research/techweb/nodes/weaponry_nodes.dm b/code/modules/research/techweb/nodes/weaponry_nodes.dm index e17d7e1e7b..999000c57b 100644 --- a/code/modules/research/techweb/nodes/weaponry_nodes.dm +++ b/code/modules/research/techweb/nodes/weaponry_nodes.dm @@ -45,7 +45,7 @@ display_name = "Medical Weaponry" description = "Weapons using medical technology." prereq_ids = list("adv_biotech", "adv_weaponry") - design_ids = list("rapidsyringe", "shotgundartcryostatis") + design_ids = list("rapidsyringe", "shotgundartcryostatis","smartdartrepeater") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000) /datum/techweb_node/beam_weapons diff --git a/code/modules/research/xenobiology/crossbreeding/__corecross.dm b/code/modules/research/xenobiology/crossbreeding/__corecross.dm index 17a6b77bfe..b37bbb59b6 100644 --- a/code/modules/research/xenobiology/crossbreeding/__corecross.dm +++ b/code/modules/research/xenobiology/crossbreeding/__corecross.dm @@ -37,7 +37,7 @@ To add a crossbreed: throw_speed = 3 throw_range = 6 -/obj/item/slimecross/Initialize() +/obj/item/slimecross/Initialize(mapload) . = ..() name = effect + " " + colour + " extract" var/itemcolor = "#FFFFFF" @@ -92,7 +92,7 @@ To add a crossbreed: var/del_on_empty = TRUE var/list/list_reagents -/obj/item/slimecrossbeaker/Initialize() +/obj/item/slimecrossbeaker/Initialize(mapload) . = ..() create_reagents(50, INJECTABLE | DRAWABLE) if(list_reagents) @@ -132,7 +132,7 @@ To add a crossbreed: var/ignore_flags = FALSE var/self_use_only = FALSE -/obj/item/slimecrossbeaker/autoinjector/Initialize() +/obj/item/slimecrossbeaker/autoinjector/Initialize(mapload) . = ..() reagents.reagents_holder_flags = DRAWABLE // Cannot be refilled, since it's basically an autoinjector! @@ -176,7 +176,7 @@ To add a crossbreed: color = "#DDAAAA" list_reagents = list(/datum/reagent/pax/peaceborg = 10, /datum/reagent/drug/space_drugs = 15) //Peace, dudes -/obj/item/slimecrossbeaker/autoinjector/peaceandlove/Initialize() +/obj/item/slimecrossbeaker/autoinjector/peaceandlove/Initialize(mapload) . = ..() reagents.reagents_holder_flags = NONE // It won't be *that* easy to get your hands on pax. diff --git a/code/modules/research/xenobiology/crossbreeding/_clothing.dm b/code/modules/research/xenobiology/crossbreeding/_clothing.dm index 1ac09652b5..640aa6d490 100644 --- a/code/modules/research/xenobiology/crossbreeding/_clothing.dm +++ b/code/modules/research/xenobiology/crossbreeding/_clothing.dm @@ -19,7 +19,7 @@ Slimecrossing Armor /obj/item/clothing/mask/nobreath/equipped(mob/living/carbon/human/user, slot) . = ..() - if(slot == SLOT_WEAR_MASK) + if(slot == ITEM_SLOT_MASK) ADD_TRAIT(user, TRAIT_NOBREATH, "breathmask_[REF(src)]") user.failed_last_breath = FALSE user.clear_alert("not_enough_oxy") @@ -39,7 +39,7 @@ Slimecrossing Armor var/glasses_color = "#FFFFFF" /obj/item/clothing/glasses/prism_glasses/item_action_slot_check(slot) - if(slot == SLOT_GLASSES) + if(slot == ITEM_SLOT_EYES) return TRUE /obj/structure/light_prism @@ -111,7 +111,7 @@ Slimecrossing Armor /obj/item/clothing/head/peaceflower/equipped(mob/living/carbon/human/user, slot) . = ..() - if(slot == SLOT_HEAD) + if(slot == ITEM_SLOT_HEAD) ADD_TRAIT(user, TRAIT_PACIFISM, "peaceflower_[REF(src)]") /obj/item/clothing/head/peaceflower/dropped(mob/living/carbon/human/user) @@ -135,7 +135,7 @@ Slimecrossing Armor obj_flags = IMMUTABLE_SLOW slowdown = 4 var/hit_reflect_chance = 10 // Citadel Change: because 40% chance of bouncing lasers back into peoples faces isn't good. - armor = list("melee" = 70, "bullet" = 70, "laser" = 40, "energy" = 40, "bomb" = 80, "bio" = 80, "rad" = 80, "fire" = 70, "acid" = 90) //Citadel Change to avoid immortal Xenobiologists. + armor = list(MELEE = 70, BULLET = 70, LASER = 40, ENERGY = 40, BOMB = 80, BIO = 80, RAD = 80, FIRE = 70, ACID = 90) //Citadel Change to avoid immortal Xenobiologists. /obj/item/clothing/suit/armor/heavy/adamantine/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) if(is_energy_reflectable_projectile(object) && prob(hit_reflect_chance)) diff --git a/code/modules/research/xenobiology/crossbreeding/_misc.dm b/code/modules/research/xenobiology/crossbreeding/_misc.dm index 4684352ef5..05470b41d6 100644 --- a/code/modules/research/xenobiology/crossbreeding/_misc.dm +++ b/code/modules/research/xenobiology/crossbreeding/_misc.dm @@ -71,9 +71,9 @@ icon_state = "frozen" density = TRUE max_integrity = 100 - armor = list("melee" = 30, "bullet" = 50, "laser" = -50, "energy" = -50, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = -80, "acid" = 30) + armor = list(MELEE = 30, BULLET = 50, LASER = -50, ENERGY = -50, BOMB = 0, BIO = 100, RAD = 100, FIRE = -80, ACID = 30) -/obj/structure/ice_stasis/Initialize() +/obj/structure/ice_stasis/Initialize(mapload) . = ..() playsound(src, 'sound/magic/ethereal_exit.ogg', 50, 1) @@ -92,6 +92,10 @@ icon_state = "capturedevice" /obj/item/capturedevice/attack(mob/living/M, mob/user) + try_catching(M, user) + +/obj/item/capturedevice/proc/try_catching(mob/living/M, mob/user) + set waitfor = FALSE if(length(contents)) to_chat(user, "The device already has something inside.") return @@ -116,7 +120,7 @@ to_chat(user, "This creature is too aggressive to capture.") return to_chat(user, "You store [M] in the capture device.") - store(M) + store(M, user) /obj/item/capturedevice/attack_self(mob/user) if(contents.len) @@ -125,7 +129,10 @@ else to_chat(user, "The device is empty...") -/obj/item/capturedevice/proc/store(var/mob/living/M) +/obj/item/capturedevice/proc/store(var/mob/living/M, mob/user) + if(length(contents)) + to_chat(user, "The device already has something inside.") + return M.forceMove(src) /obj/item/capturedevice/proc/release() diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 0c34a251ae..1c7951a2d6 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -495,7 +495,11 @@ /datum/status_effect/stabilized/orange/tick() var/body_temperature_difference = BODYTEMP_NORMAL - owner.bodytemperature - owner.adjust_bodytemperature(min(5,body_temperature_difference)) + var/cooling_cap = -5 + if(HAS_TRAIT(owner, TRAIT_ROBOTIC_ORGANISM)) + cooling_cap *= 0.5 //Only cools by half as much (which is 5 per life tick since this ticks twice as much as life) so it isn't true spaceproofness.. + body_temperature_difference += SYNTH_COLD_OFFSET //.. But also cools towards a cold temp, provided there is nothing that counters it. + owner.adjust_bodytemperature(clamp(body_temperature_difference, cooling_cap, 5)) return ..() /datum/status_effect/stabilized/purple @@ -573,6 +577,10 @@ if(batteries.len) var/obj/item/stock_parts/cell/ToCharge = pick(batteries) ToCharge.charge += min(ToCharge.maxcharge - ToCharge.charge, ToCharge.maxcharge/10) //10% of the cell, or to maximum. + ToCharge.update_appearance() //make sure the cell gets their appearance updated. + var/atom/l = ToCharge.loc + if(isgun(l)) //updates the gun appearance as well if the cell is inside one. + l.update_appearance() to_chat(owner, "[linked_extract] discharges some energy into a device you have.") return ..() @@ -595,14 +603,14 @@ return ..() /datum/status_effect/stabilized/darkpurple/tick() - var/obj/item/I = owner.get_active_held_item() - var/obj/item/reagent_containers/food/snacks/F = I - if(istype(F)) - if(F.cooked_type) + var/obj/item/item = owner.get_active_held_item() + if(item) + var/obj/item/reagent_containers/food/snacks/F = item + if(istype(F) && F.cooked_type) to_chat(owner, "[linked_extract] flares up brightly, and your hands alone are enough cook [F]!") F.microwave_act() - else - I.attackby(fire, owner) + else + item.attackby(fire, owner) return ..() /datum/status_effect/stabilized/darkpurple/on_remove() diff --git a/code/modules/research/xenobiology/crossbreeding/_weapons.dm b/code/modules/research/xenobiology/crossbreeding/_weapons.dm index 1b2f43c518..00748d2609 100644 --- a/code/modules/research/xenobiology/crossbreeding/_weapons.dm +++ b/code/modules/research/xenobiology/crossbreeding/_weapons.dm @@ -17,7 +17,7 @@ fire_sound = 'sound/effects/attackblob.ogg' total_mass = TOTAL_MASS_HAND_REPLACEMENT -/obj/item/gun/magic/bloodchill/Initialize() +/obj/item/gun/magic/bloodchill/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) diff --git a/code/modules/research/xenobiology/crossbreeding/burning.dm b/code/modules/research/xenobiology/crossbreeding/burning.dm index 1a8b82232b..3d159cddde 100644 --- a/code/modules/research/xenobiology/crossbreeding/burning.dm +++ b/code/modules/research/xenobiology/crossbreeding/burning.dm @@ -9,7 +9,7 @@ Burning extracts: effect = "burning" icon_state = "burning" -/obj/item/slimecross/burning/Initialize() +/obj/item/slimecross/burning/Initialize(mapload) . = ..() create_reagents(10, INJECTABLE | DRAWABLE) @@ -447,7 +447,7 @@ Burning extracts: icon_state = "adamshield" item_state = "adamshield" w_class = WEIGHT_CLASS_HUGE - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 80, ACID = 70) slot_flags = ITEM_SLOT_BACK block_chance = 75 force = 0 diff --git a/code/modules/research/xenobiology/crossbreeding/charged.dm b/code/modules/research/xenobiology/crossbreeding/charged.dm index 75a15be9ce..a51adfffe6 100644 --- a/code/modules/research/xenobiology/crossbreeding/charged.dm +++ b/code/modules/research/xenobiology/crossbreeding/charged.dm @@ -10,7 +10,7 @@ Charged extracts: effect = "charged" icon_state = "charged" -/obj/item/slimecross/charged/Initialize() +/obj/item/slimecross/charged/Initialize(mapload) . = ..() create_reagents(10, INJECTABLE | DRAWABLE) diff --git a/code/modules/research/xenobiology/crossbreeding/chilling.dm b/code/modules/research/xenobiology/crossbreeding/chilling.dm index d117e6104c..7c129b8179 100644 --- a/code/modules/research/xenobiology/crossbreeding/chilling.dm +++ b/code/modules/research/xenobiology/crossbreeding/chilling.dm @@ -9,7 +9,7 @@ Chilling extracts: effect = "chilling" icon_state = "chilling" -/obj/item/slimecross/chilling/Initialize() +/obj/item/slimecross/chilling/Initialize(mapload) . = ..() create_reagents(10, INJECTABLE | DRAWABLE) diff --git a/code/modules/research/xenobiology/crossbreeding/consuming.dm b/code/modules/research/xenobiology/crossbreeding/consuming.dm index 8d80613be4..f69d1bd674 100644 --- a/code/modules/research/xenobiology/crossbreeding/consuming.dm +++ b/code/modules/research/xenobiology/crossbreeding/consuming.dm @@ -277,7 +277,7 @@ Consuming extracts: taste = "vanilla and " //Randomly selected color dye. var/colour = "#FFFFFF" -/obj/item/slime_cookie/pyrite/Initialize() +/obj/item/slime_cookie/pyrite/Initialize(mapload) . = ..() var/tastemessage = "paint remover" switch(rand(1,7)) diff --git a/code/modules/research/xenobiology/crossbreeding/industrial.dm b/code/modules/research/xenobiology/crossbreeding/industrial.dm index ac9d2e58c5..cc85486bad 100644 --- a/code/modules/research/xenobiology/crossbreeding/industrial.dm +++ b/code/modules/research/xenobiology/crossbreeding/industrial.dm @@ -19,7 +19,7 @@ Industrial extracts: /obj/item/slimecross/industrial/proc/do_after_spawn(obj/item/spawned) return -/obj/item/slimecross/industrial/Initialize() +/obj/item/slimecross/industrial/Initialize(mapload) . = ..() create_reagents(100, INJECTABLE | DRAWABLE) START_PROCESSING(SSobj,src) diff --git a/code/modules/research/xenobiology/crossbreeding/recurring.dm b/code/modules/research/xenobiology/crossbreeding/recurring.dm index 4a094744f7..4389801882 100644 --- a/code/modules/research/xenobiology/crossbreeding/recurring.dm +++ b/code/modules/research/xenobiology/crossbreeding/recurring.dm @@ -13,7 +13,7 @@ Recurring extracts: var/cooldown = 0 var/max_cooldown = 5 //In sets of 2 seconds. -/obj/item/slimecross/recurring/Initialize() +/obj/item/slimecross/recurring/Initialize(mapload) . = ..() extract = new extract_type(src.loc) visible_message("[src] wraps a layer of goo around itself!") diff --git a/code/modules/research/xenobiology/crossbreeding/regenerative.dm b/code/modules/research/xenobiology/crossbreeding/regenerative.dm index 39877d6706..7f3d2ce791 100644 --- a/code/modules/research/xenobiology/crossbreeding/regenerative.dm +++ b/code/modules/research/xenobiology/crossbreeding/regenerative.dm @@ -14,25 +14,62 @@ Regenerative extracts: /obj/item/slimecross/regenerative/proc/core_effect_before(mob/living/carbon/human/target, mob/user) return +/obj/item/slimecross/regenerative/pre_attack(atom/A, mob/living/user, params, attackchain_flags, damage_multiplier) + if(isliving(A)) + var/mob/living/M = A + if(M.stat == DEAD) + to_chat(user, "[src] will not work on the dead!") + return TRUE //returning TRUE preemptively ends the attack chain and thus doesn't call afterattack, this is noteworthy for below as well + //inform the target that they're about to have a regenerative extract used on them + if(M != user) //targeting someone else + M.visible_message("[user] readies [src], holding it steady near [M] and guiding it to the center of [M.p_their()] mass...", + "[user] readies [src], holding it steady near you and guiding it to the center of your mass...") + if(!do_after(user, 50, target = M)) //5 seconds + return TRUE + else //targeting self + M.visible_message("[user] readies [src], holding it steady near [user.p_them()]self and guiding it to the center of [user.p_their()] mass...", + "You ready [src], holding it steady near you and guiding it to the center of your mass...") + if(!do_after(user, 10, target = M)) //1 second + return TRUE + . = ..() + else + . = ..() /obj/item/slimecross/regenerative/afterattack(atom/target,mob/user,prox) . = ..() if(!prox || !isliving(target)) return - var/mob/living/H = target - if(H.stat == DEAD) - to_chat(user, "[src] will not work on the dead!") + var/mob/living/M = target + if(M.stat == DEAD) + to_chat(user, "[M] died before you could apply [src]!") return - if(H != user) - user.visible_message("[user] crushes the [src] over [H], the milky goo quickly regenerating all of [H.p_their()] injuries!", - "You squeeze the [src], and it bursts over [H], the milky goo regenerating [H.p_their()] injuries.") + if(M != user) + user.visible_message("[user] crushes the [src] over [M], the milky goo quickly regenerating all of [M.p_their()] injuries!", + "You squeeze the [src], and it bursts over [M], the milky goo regenerating [M.p_their()] injuries.") else user.visible_message("[user] crushes the [src] over [user.p_them()]self, the milky goo quickly regenerating all of [user.p_their()] injuries!", "You squeeze the [src], and it bursts in your hand, splashing you with milky goo which quickly regenerates your injuries!") - core_effect_before(H, user) - H.revive(full_heal = 1) - core_effect(H, user) + core_effect_before(M, user) + var/new_disgust_level = 0 + if(iscarbon(M)) //simpler mobs don't have a disgust variable and we need to grab that. + var/mob/living/carbon/C = M + new_disgust_level = C.disgust + DISGUST_LEVEL_GROSS + M.revive(full_heal = 1) + M.set_disgust(new_disgust_level) + core_effect(M, user) playsound(target, 'sound/effects/splat.ogg', 40, 1) + //warn receivers of the extract about the disgust if they're carbon, making it clear that the regenerative extract is causing this. + if(iscarbon(M)) + var/obj/item/organ/stomach/S = M.getorganslot(ORGAN_SLOT_STOMACH) //for getting the stummy name + switch(new_disgust_level) + if(0 to DISGUST_LEVEL_GROSS) + to_chat(M,"While you recovered from [src], you feel a little nauseous.") + if(DISGUST_LEVEL_GROSS to DISGUST_LEVEL_VERYGROSS) + to_chat(M,"While you recovered from [src], you feel quite queasy.") + if(DISGUST_LEVEL_VERYGROSS to DISGUST_LEVEL_DISGUSTED) + to_chat(M,"While you recovered from [src], you feel like you're about to vomit!") + if(DISGUST_LEVEL_DISGUSTED to INFINITY) + to_chat(M,"You feel absolutely sick. Maybe you should lay off the regenerative extracts until your [(S ? S.name : "stomach")] settles!") qdel(src) /obj/item/slimecross/regenerative/grey @@ -90,10 +127,10 @@ Regenerative extracts: /obj/item/slimecross/regenerative/darkpurple/core_effect(mob/living/target, mob/user) var/equipped = 0 - equipped += target.equip_to_slot_or_del(new /obj/item/clothing/shoes/sneakers/purple(null), SLOT_SHOES) - equipped += target.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(null), SLOT_W_UNIFORM) - equipped += target.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/purple(null), SLOT_GLOVES) - equipped += target.equip_to_slot_or_del(new /obj/item/clothing/head/soft/purple(null), SLOT_HEAD) + equipped += target.equip_to_slot_or_del(new /obj/item/clothing/shoes/sneakers/purple(null), ITEM_SLOT_FEET) + equipped += target.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(null), ITEM_SLOT_ICLOTHING) + equipped += target.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/purple(null), ITEM_SLOT_GLOVES) + equipped += target.equip_to_slot_or_del(new /obj/item/clothing/head/soft/purple(null), ITEM_SLOT_HEAD) if(equipped > 0) target.visible_message("The milky goo congeals into clothing!") @@ -105,13 +142,13 @@ Regenerative extracts: return var/mob/living/carbon/human/H = target var/fireproofed = FALSE - if(H.get_item_by_slot(SLOT_WEAR_SUIT)) + if(H.get_item_by_slot(ITEM_SLOT_OCLOTHING)) fireproofed = TRUE - var/obj/item/clothing/C = H.get_item_by_slot(SLOT_WEAR_SUIT) + var/obj/item/clothing/C = H.get_item_by_slot(ITEM_SLOT_OCLOTHING) fireproof(C) - if(H.get_item_by_slot(SLOT_HEAD)) + if(H.get_item_by_slot(ITEM_SLOT_HEAD)) fireproofed = TRUE - var/obj/item/clothing/C = H.get_item_by_slot(SLOT_HEAD) + var/obj/item/clothing/C = H.get_item_by_slot(ITEM_SLOT_HEAD) fireproof(C) if(fireproofed) target.visible_message("Some of [target]'s clothing gets coated in the goo, and turns blue!") @@ -141,7 +178,7 @@ Regenerative extracts: target.forceMove(T) do_sparks(5,FALSE,target) -/obj/item/slimecross/regenerative/bluespace/Initialize() +/obj/item/slimecross/regenerative/bluespace/Initialize(mapload) . = ..() T = get_turf(src) diff --git a/code/modules/research/xenobiology/crossbreeding/selfsustaining.dm b/code/modules/research/xenobiology/crossbreeding/selfsustaining.dm index a88b5cd35b..ae003d984f 100644 --- a/code/modules/research/xenobiology/crossbreeding/selfsustaining.dm +++ b/code/modules/research/xenobiology/crossbreeding/selfsustaining.dm @@ -14,7 +14,7 @@ Self-sustaining extracts: var/obj/item/slime_extract/extract //Just divides into the actual item. -/obj/item/slimecross/selfsustaining/Initialize() +/obj/item/slimecross/selfsustaining/Initialize(mapload) ..() visible_message("The [src] shudders, and splits into four smaller extracts.") for(var/i = 0, i < 4, i++) diff --git a/code/modules/research/xenobiology/crossbreeding/stabilized.dm b/code/modules/research/xenobiology/crossbreeding/stabilized.dm index 69bd2c7e28..2def0640a9 100644 --- a/code/modules/research/xenobiology/crossbreeding/stabilized.dm +++ b/code/modules/research/xenobiology/crossbreeding/stabilized.dm @@ -14,7 +14,7 @@ Stabilized extracts: var/datum/status_effect/linked_effect var/mob/living/owner -/obj/item/slimecross/stabilized/Initialize() +/obj/item/slimecross/stabilized/Initialize(mapload) . = ..() START_PROCESSING(SSobj,src) @@ -110,7 +110,7 @@ Stabilized extracts: mob_spawn_pets += T mob_type = pick(mob_spawn_pets) -/obj/item/slimecross/stabilized/gold/Initialize() +/obj/item/slimecross/stabilized/gold/Initialize(mapload) . = ..() generate_mobtype() diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index ef9c751d57..bccc738398 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -5,7 +5,7 @@ icon_state = "generic_camera" var/allowed_area = null -/mob/camera/aiEye/remote/xenobio/Initialize() +/mob/camera/aiEye/remote/xenobio/Initialize(mapload) var/area/A = get_area(loc) allowed_area = A.name . = ..() @@ -41,7 +41,7 @@ light_color = LIGHT_COLOR_PINK -/obj/machinery/computer/camera_advanced/xenobio/Initialize() +/obj/machinery/computer/camera_advanced/xenobio/Initialize(mapload) . = ..() slime_place_action = new slime_up_action = new diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 70cd28718c..dd2579663a 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -36,7 +36,7 @@ qdel(O) ..() -/obj/item/slime_extract/Initialize() +/obj/item/slime_extract/Initialize(mapload) . = ..() create_reagents(100, INJECTABLE | DRAWABLE) @@ -735,7 +735,10 @@ if(jb) to_chat(user, "Your mind goes blank as you attempt to use the potion.") return + try_transfer_mind(SM, user) +/obj/item/slimepotion/transference/proc/try_transfer_mind(mob/living/simple_animal/SM, mob/user) + set waitfor = FALSE prompted = 1 if(alert("This will permanently transfer your consciousness to [SM]. Are you sure you want to do this?",,"Yes","No")=="No") prompted = 0 diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm index e572f1ee02..93be0d1eed 100644 --- a/code/modules/ruins/lavaland_ruin_code.dm +++ b/code/modules/ruins/lavaland_ruin_code.dm @@ -7,7 +7,7 @@ /obj/item/disk/design_disk/adv/knight_gear name = "Magic Disk of Smithing" -/obj/item/disk/design_disk/adv/knight_gear/Initialize() +/obj/item/disk/design_disk/adv/knight_gear/Initialize(mapload) . = ..() var/datum/design/knight_armour/A = new var/datum/design/knight_helmet/H = new @@ -33,7 +33,7 @@ icon_state = "datadisk1" max_blueprints = 1 -/obj/item/disk/design_disk/plant_disk/Initialize() +/obj/item/disk/design_disk/plant_disk/Initialize(mapload) . = ..() var/datum/design/diskplantgene/P = new blueprints[1] = P @@ -46,7 +46,7 @@ icon_state = "datadisk1" max_blueprints = 1 -/obj/item/disk/design_disk/golem_shell/Initialize() +/obj/item/disk/design_disk/golem_shell/Initialize(mapload) . = ..() var/datum/design/golem_shell/G = new blueprints[1] = G @@ -160,7 +160,7 @@ important_info = "DO NOT abandon the base." outfit = /datum/outfit/lavaland_syndicate/comms -/obj/effect/mob_spawn/human/lavaland_syndicate/comms/space/Initialize() +/obj/effect/mob_spawn/human/lavaland_syndicate/comms/space/Initialize(mapload) . = ..() if(prob(90)) //only has a 10% chance of existing, otherwise it'll just be a NPC syndie. new /mob/living/simple_animal/hostile/syndicate/ranged(get_turf(src)) @@ -172,7 +172,7 @@ mask = /obj/item/clothing/mask/chameleon/gps suit = /obj/item/clothing/suit/armor/vest -/obj/item/clothing/mask/chameleon/gps/Initialize() +/obj/item/clothing/mask/chameleon/gps/Initialize(mapload) . = ..() new /obj/item/gps/internal/lavaland_syndicate_base(src) diff --git a/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm b/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm index 088683ccd2..c8bc4b0568 100644 --- a/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm +++ b/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm @@ -3,27 +3,28 @@ /obj/structure/statue/bone anchored = TRUE max_integrity = 120 - material_drop_type = /obj/item/stack/sheet/bone impressiveness = 18 // Carved from the bones of a massive creature, it's going to be a specticle to say the least layer = ABOVE_ALL_MOB_LAYER + custom_materials = list(/datum/material/bone=MINERAL_MATERIAL_AMOUNT*5) + abstract_type = /obj/structure/statue/bone /obj/structure/statue/bone/rib name = "collosal rib" desc = "It's staggering to think that something this big could have lived, let alone died." - oreAmount = 4 + custom_materials = list(/datum/material/bone=MINERAL_MATERIAL_AMOUNT*4) icon = 'icons/obj/statuelarge.dmi' icon_state = "rib" /obj/structure/statue/bone/skull name = "collosal skull" desc = "The gaping maw of a dead, titanic monster." - oreAmount = 12 + custom_materials = list(/datum/material/bone=MINERAL_MATERIAL_AMOUNT*12) icon = 'icons/obj/statuelarge.dmi' icon_state = "skull" /obj/structure/statue/bone/skull/half desc = "The gaping maw of a dead, titanic monster. This one is cracked in half." - oreAmount = 6 + custom_materials = list(/datum/material/bone=MINERAL_MATERIAL_AMOUNT*6) icon = 'icons/obj/statuelarge.dmi' icon_state = "skull-half" @@ -39,7 +40,7 @@ slowdown = 0.5 floor_variance = 30 -/turf/open/floor/plating/asteroid/basalt/wasteland/Initialize() +/turf/open/floor/plating/asteroid/basalt/wasteland/Initialize(mapload) .=..() if(prob(floor_variance)) icon_state = "[environment_type][rand(0,6)]" @@ -68,7 +69,7 @@ icon_state = "puddle-oil" dispensedreagent = /datum/reagent/oil -/obj/structure/sink/oil_well/Initialize() +/obj/structure/sink/oil_well/Initialize(mapload) .=..() create_reagents(20) reagents.add_reagent(dispensedreagent, 20) @@ -145,6 +146,8 @@ if(7) new /obj/item/clothing/glasses/sunglasses(src) new /obj/item/clothing/mask/cigarette/rollie(src) + else + return /obj/structure/closet/crate/grave/open(mob/living/user, obj/item/S) if(!opened) diff --git a/code/modules/ruins/lavalandruin_code/puzzle.dm b/code/modules/ruins/lavalandruin_code/puzzle.dm index 92e24e3bc4..136acc7da7 100644 --- a/code/modules/ruins/lavalandruin_code/puzzle.dm +++ b/code/modules/ruins/lavalandruin_code/puzzle.dm @@ -34,7 +34,7 @@ return get_step(center,SOUTH) if(9) return get_step(center,SOUTHEAST) - + /obj/effect/sliding_puzzle/Initialize(mapload) ..() return INITIALIZE_HINT_LATELOAD @@ -56,7 +56,7 @@ /obj/effect/sliding_puzzle/proc/validate() if(finished) return - + if(elements.len < 8) //Someone broke it qdel(src) @@ -86,7 +86,7 @@ shake_camera(M, COLLAPSE_DURATION , 1) for(var/obj/structure/puzzle_element/E in elements) E.collapse() - + dispense_reward() /obj/effect/sliding_puzzle/proc/dispense_reward() @@ -103,7 +103,7 @@ for(var/j in i to current_ordering.len) if(current_ordering[j] < checked_value) swap_tally++ - + return swap_tally % 2 == 0 //swap two tiles in same row @@ -113,13 +113,13 @@ if(empty_tile_id == 1 || empty_tile_id == 2) //Can't swap with empty one so just grab some in second row first_tile_id = 4 other_tile_id = 5 - + var/turf/T1 = get_turf_for_id(first_tile_id) var/turf/T2 = get_turf_for_id(other_tile_id) - + var/obj/structure/puzzle_element/E1 = locate() in T1 var/obj/structure/puzzle_element/E2 = locate() in T2 - + E1.forceMove(T2) E2.forceMove(T1) @@ -294,7 +294,7 @@ //Some armor so it's harder to kill someone by mistake. /obj/structure/puzzle_element/prison - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 50, "rad" = 50, "fire" = 50, "acid" = 50) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 50, BIO = 50, RAD = 50, FIRE = 50, ACID = 50) /obj/structure/puzzle_element/prison/relaymove(mob/user) return @@ -342,7 +342,7 @@ for(var/atom/movable/AM in things_to_throw) var/throwtarget = get_edge_target_turf(T, get_dir(T, get_step_away(AM, T))) AM.throw_at(throwtarget, 2, 3) - + //Create puzzle itself cube.prisoner = prisoner cube.setup() diff --git a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm index 2401fc63a0..d6693fcca2 100644 --- a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm +++ b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm @@ -12,14 +12,29 @@ max_integrity = 200 var/faction = list("ashwalker") var/meat_counter = 6 + var/datum/team/ashwalkers/ashies + var/datum/linked_objective -/obj/structure/lavaland/ash_walker/Initialize() +/obj/structure/lavaland/ash_walker/Initialize(mapload) .=..() + ashies = new /datum/team/ashwalkers() + var/datum/objective/protect_object/objective = new + objective.set_target(src) + linked_objective = objective + ashies.objectives += objective START_PROCESSING(SSprocessing, src) +/obj/structure/lavaland/ash_walker/Destroy() + ashies.objectives -= linked_objective + ashies = null + QDEL_NULL(linked_objective) + STOP_PROCESSING(SSprocessing, src) + return ..() + /obj/structure/lavaland/ash_walker/deconstruct(disassembled) new /obj/item/assembly/signaler/anomaly (get_step(loc, pick(GLOB.alldirs))) new /obj/effect/collapse(loc) + return ..() /obj/structure/lavaland/ash_walker/process() consume() @@ -28,20 +43,64 @@ /obj/structure/lavaland/ash_walker/proc/consume() for(var/mob/living/H in view(src, 1)) //Only for corpse right next to/on same tile if(H.stat) - visible_message("Serrated tendrils eagerly pull [H] to [src], tearing the body apart as its blood seeps over the eggs.") - playsound(get_turf(src),'sound/magic/demon_consume.ogg', 100, 1) for(var/obj/item/W in H) if(!H.dropItemToGround(W)) qdel(W) + if(issilicon(H)) //no advantage to sacrificing borgs... + H.gib() + visible_message(span_notice("Serrated tendrils eagerly pull [H] apart, but find nothing of interest.")) + return + + if(H.mind?.has_antag_datum(/datum/antagonist/ashwalker) && (H.key || H.get_ghost(FALSE, TRUE))) //special interactions for dead lava lizards with ghosts attached + visible_message(span_warning("Serrated tendrils carefully pull [H] to [src], absorbing the body and creating it anew.")) + var/datum/mind/deadmind + if(H.key) + deadmind = H + else + deadmind = H.get_ghost(FALSE, TRUE) + to_chat(deadmind, "Your body has been returned to the nest. You are being remade anew, and will awaken shortly.
    Your memories will remain intact in your new body, as your soul is being salvaged") + SEND_SOUND(deadmind, sound('sound/magic/enter_blood.ogg',volume=100)) + addtimer(CALLBACK(src, .proc/remake_walker, H.mind, H.real_name), 20 SECONDS) + new /obj/effect/gibspawner/generic(get_turf(H)) + qdel(H) + return + if(ismegafauna(H)) meat_counter += 20 else meat_counter++ + visible_message(span_warning("Serrated tendrils eagerly pull [H] to [src], tearing the body apart as its blood seeps over the eggs.")) + playsound(get_turf(src),'sound/magic/demon_consume.ogg', 100, TRUE) + var/deliverykey = H.fingerprintslast //key of whoever brought the body + var/mob/living/deliverymob = get_mob_by_key(deliverykey) //mob of said key + //there is a 40% chance that the Lava Lizard unlocks their respawn with each sacrifice + if(deliverymob && (deliverymob.mind?.has_antag_datum(/datum/antagonist/ashwalker)) && (deliverykey in ashies.players_spawned) && (prob(40))) + to_chat(deliverymob, span_warning("The Necropolis is pleased with your sacrifice. You feel confident your existence after death is secure.")) + ashies.players_spawned -= deliverykey H.gib() obj_integrity = min(obj_integrity + max_integrity*0.05,max_integrity)//restores 5% hp of tendril + for(var/mob/living/L in view(src, 5)) + if(L.mind?.has_antag_datum(/datum/antagonist/ashwalker)) + SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "headspear", /datum/mood_event/sacrifice_good) + else + SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "headspear", /datum/mood_event/sacrifice_bad) + +/obj/structure/lavaland/ash_walker/proc/remake_walker(datum/mind/oldmind, oldname) + var/mob/living/carbon/human/M = new /mob/living/carbon/human(get_step(loc, pick(GLOB.alldirs))) + M.set_species(/datum/species/lizard/ashwalker) + M.real_name = oldname + M.underwear = "Nude" + M.undershirt = "Nude" + M.socks = "Nude" + M.update_body() + M.remove_language(/datum/language/common) + oldmind.transfer_to(M) + M.mind.grab_ghost() + to_chat(M, "You have been pulled back from beyond the grave, with a new body and renewed purpose. Glory to the Necropolis!") + playsound(get_turf(M),'sound/magic/exit_blood.ogg', 100, TRUE) /obj/structure/lavaland/ash_walker/proc/spawn_mob() if(meat_counter >= ASH_WALKER_SPAWN_THRESHOLD) - new /obj/effect/mob_spawn/human/ash_walker(get_step(loc, pick(GLOB.alldirs))) + new /obj/effect/mob_spawn/human/ash_walker(get_step(loc, pick(GLOB.alldirs)), ashies) visible_message("One of the eggs swells to an unnatural size and tumbles free. It's ready to hatch!") meat_counter -= ASH_WALKER_SPAWN_THRESHOLD diff --git a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm index d62b3c2611..94abd1ef0a 100644 --- a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm +++ b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm @@ -26,7 +26,7 @@ var/uses var/ashwalker_only = FALSE -/obj/structure/necropolis_gate/Initialize() +/obj/structure/necropolis_gate/Initialize(mapload) . = ..() setDir(SOUTH) var/turf/sight_blocker_turf = get_turf(src) @@ -59,10 +59,10 @@ /obj/structure/necropolis_gate/singularity_pull() return 0 -/obj/structure/necropolis_gate/CanPass(atom/movable/mover, turf/target) - if(get_dir(loc, target) == dir) - return !density - return 1 +/obj/structure/necropolis_gate/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() + if(!(get_dir(loc, target) == dir)) + return TRUE /obj/structure/necropolis_gate/CheckExit(atom/movable/O, target) if(get_dir(O.loc, target) == dir) @@ -155,7 +155,7 @@ GLOBAL_DATUM(necropolis_gate, /obj/structure/necropolis_gate/legion_gate) desc = "A tremendous, impossibly large gateway, set into a massive tower of stone." sight_blocker_distance = 2 -/obj/structure/necropolis_gate/legion_gate/Initialize() +/obj/structure/necropolis_gate/legion_gate/Initialize(mapload) . = ..() GLOB.necropolis_gate = src @@ -228,7 +228,7 @@ GLOBAL_DATUM(necropolis_gate, /obj/structure/necropolis_gate/legion_gate) var/open = FALSE var/static/mutable_appearance/top_overlay -/obj/structure/necropolis_arch/Initialize() +/obj/structure/necropolis_arch/Initialize(mapload) . = ..() icon_state = "arch_bottom" top_overlay = mutable_appearance('icons/effects/160x160.dmi', "arch_top") diff --git a/code/modules/ruins/objects_and_mobs/sin_ruins.dm b/code/modules/ruins/objects_and_mobs/sin_ruins.dm index 5e2fc3d7e4..ddb5c9df3c 100644 --- a/code/modules/ruins/objects_and_mobs/sin_ruins.dm +++ b/code/modules/ruins/objects_and_mobs/sin_ruins.dm @@ -48,7 +48,7 @@ anchored = FALSE density = TRUE -/obj/structure/cursed_money/Initialize() +/obj/structure/cursed_money/Initialize(mapload) . = ..() addtimer(CALLBACK(src, .proc/collapse), 600) @@ -80,7 +80,8 @@ icon = 'icons/mob/blob.dmi' color = rgb(145, 150, 0) -/obj/effect/gluttony/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff. +/obj/effect/gluttony/CanAllowThrough(atom/movable/mover, turf/target)//So bullets will fly over and stuff. + . = ..() if(ishuman(mover)) var/mob/living/carbon/human/H = mover if(H.nutrition >= NUTRITION_LEVEL_FAT) @@ -90,8 +91,6 @@ to_chat(H, "You're repulsed by even looking at [src]. Only a pig could force themselves to go through it.") if(istype(mover, /mob/living/simple_animal/hostile/morph)) return TRUE - else - return FALSE /obj/structure/mirror/magic/pride //Pride's mirror: Used in the Pride ruin. name = "pride's mirror" diff --git a/code/modules/ruins/spaceruin_code/caravanambush.dm b/code/modules/ruins/spaceruin_code/caravanambush.dm index ab38ed8e4d..b347c66dbe 100644 --- a/code/modules/ruins/spaceruin_code/caravanambush.dm +++ b/code/modules/ruins/spaceruin_code/caravanambush.dm @@ -53,7 +53,7 @@ shuttleId = "caravantrade1" possible_destinations = "whiteship_away;whiteship_home;whiteship_z4;whiteship_lavaland;caravantrade1_custom;caravantrade1_ambush" -/obj/machinery/computer/camera_advanced/shuttle_docker/caravan/Initialize() +/obj/machinery/computer/camera_advanced/shuttle_docker/caravan/Initialize(mapload) . = ..() GLOB.jam_on_wardec += src diff --git a/code/modules/ruins/spaceruin_code/clericsden.dm b/code/modules/ruins/spaceruin_code/clericsden.dm index 3fe4cad794..63f85c3291 100644 --- a/code/modules/ruins/spaceruin_code/clericsden.dm +++ b/code/modules/ruins/spaceruin_code/clericsden.dm @@ -4,7 +4,7 @@ /obj/item/disk/design_disk/adv/cleric_mace name = "Enshrined Disc of Smiting" -/obj/item/disk/design_disk/adv/cleric_mace/Initialize() +/obj/item/disk/design_disk/adv/cleric_mace/Initialize(mapload) . = ..() var/datum/design/cleric_mace/M = new blueprints[1] = M diff --git a/code/modules/ruins/spaceruin_code/hilbertshotel.dm b/code/modules/ruins/spaceruin_code/hilbertshotel.dm index 7109c87999..79119c8448 100644 --- a/code/modules/ruins/spaceruin_code/hilbertshotel.dm +++ b/code/modules/ruins/spaceruin_code/hilbertshotel.dm @@ -18,7 +18,7 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337) var/ruinSpawned = FALSE var/mysteryRoom -/obj/item/hilbertshotel/Initialize() +/obj/item/hilbertshotel/Initialize(mapload) . = ..() //Load templates INVOKE_ASYNC(src, .proc/prepare_rooms) @@ -302,7 +302,7 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337) user.reset_perspective(parentSphere) user.set_machine(src) var/datum/action/peepholeCancel/PHC = new - user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/impaired, 1) + user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/scaled/impaired, 1) PHC.Grant(user) return TRUE @@ -478,7 +478,7 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337) /obj/item/paper/crumpled/docslogs name = "Research Logs" -/obj/item/paper/crumpled/docslogs/Initialize() +/obj/item/paper/crumpled/docslogs/Initialize(mapload) . = ..() GLOB.hhmysteryRoomNumber = rand(1, SHORT_REAL_LIMIT) info = {" diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm index 7326cad816..65fc9d3278 100644 --- a/code/modules/security_levels/keycard_authentication.dm +++ b/code/modules/security_levels/keycard_authentication.dm @@ -26,7 +26,7 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new) var/obj/item/card/id/first_id = null var/waiting = 0 -/obj/machinery/keycard_auth/Initialize() +/obj/machinery/keycard_auth/Initialize(mapload) . = ..() ev = GLOB.keycard_events.addEvent("triggerEvent", CALLBACK(src, .proc/triggerEvent)) @@ -116,10 +116,10 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new) message_admins("[ADMIN_LOOKUPFLW(triggerer)] triggered and [ADMIN_LOOKUPFLW(confirmer)] confirmed event [event]") var/area/A1 = get_area(triggerer) - deadchat_broadcast(" triggered [event] at [A1.name].", "[triggerer]", triggerer) + deadchat_broadcast(" triggered [event] at [span_name("[A1.name]")].", span_name("[triggerer]"), triggerer, message_type=DEADCHAT_ANNOUNCEMENT) var/area/A2 = get_area(confirmer) - deadchat_broadcast(" confirmed [event] at [A2.name].", "[confirmer]", confirmer) + deadchat_broadcast(" confirmed [event] at [span_name("[A2.name]")].", span_name("[confirmer]"), confirmer, message_type=DEADCHAT_ANNOUNCEMENT) switch(event) if(KEYCARD_RED_ALERT) set_security_level(SEC_LEVEL_RED) diff --git a/code/modules/security_levels/security_levels.dm b/code/modules/security_levels/security_levels.dm index 99357d802a..4b0208889c 100644 --- a/code/modules/security_levels/security_levels.dm +++ b/code/modules/security_levels/security_levels.dm @@ -14,101 +14,4 @@ GLOBAL_LIST_INIT(all_security_levels, list("green", "blue", "amber", "red", "del //config.alert_desc_blue_downto /proc/set_security_level(level) - if(!isnum(level)) - level = GLOB.all_security_levels.Find(level) - - //Will not be announced if you try to set to the same level as it already is - if(level >= SEC_LEVEL_GREEN && level <= SEC_LEVEL_DELTA && level != GLOB.security_level) - switch(level) - if(SEC_LEVEL_GREEN) - minor_announce(CONFIG_GET(string/alert_green), "Attention! Security level lowered to green:") - if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) - if(GLOB.security_level >= SEC_LEVEL_RED) - SSshuttle.emergency.modTimer(4) - else if(GLOB.security_level == SEC_LEVEL_AMBER) - SSshuttle.emergency.modTimer(2.5) - else - SSshuttle.emergency.modTimer(1.66) - GLOB.security_level = SEC_LEVEL_GREEN - for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(is_station_level(FA.z)) - FA.update_icon() - if(SEC_LEVEL_BLUE) - if(GLOB.security_level < SEC_LEVEL_BLUE) - minor_announce(CONFIG_GET(string/alert_blue_upto), "Attention! Security level elevated to blue:",1) - if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) - SSshuttle.emergency.modTimer(0.6) - else - minor_announce(CONFIG_GET(string/alert_blue_downto), "Attention! Security level lowered to blue:") - if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) - if(GLOB.security_level >= SEC_LEVEL_RED) - SSshuttle.emergency.modTimer(2.4) - else - SSshuttle.emergency.modTimer(1.5) - GLOB.security_level = SEC_LEVEL_BLUE - sound_to_playing_players('sound/misc/voybluealert.ogg', volume = 50) // Citadel change - Makes alerts play a sound - for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(is_station_level(FA.z)) - FA.update_icon() - if(SEC_LEVEL_AMBER) - if(GLOB.security_level < SEC_LEVEL_AMBER) - minor_announce(CONFIG_GET(string/alert_amber_upto), "Attention! Security level elevated to amber:",1) - if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) - if(GLOB.security_level == SEC_LEVEL_GREEN) - SSshuttle.emergency.modTimer(0.4) - else - SSshuttle.emergency.modTimer(0.66) - else - minor_announce(CONFIG_GET(string/alert_amber_downto), "Attention! Security level lowered to amber:") - if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) - SSshuttle.emergency.modTimer(1.6) - GLOB.security_level = SEC_LEVEL_AMBER - sound_to_playing_players('sound/effects/alert.ogg', volume = 50) // Citadel change - Makes alerts play a sound - for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(is_station_level(FA.z)) - FA.update_icon() - if(SEC_LEVEL_RED) - if(GLOB.security_level < SEC_LEVEL_RED) - minor_announce(CONFIG_GET(string/alert_red_upto), "Attention! Code red!",1) - if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) - if(GLOB.security_level == SEC_LEVEL_GREEN) - SSshuttle.emergency.modTimer(0.25) - else if(GLOB.security_level == SEC_LEVEL_BLUE) - SSshuttle.emergency.modTimer(0.416) - else - SSshuttle.emergency.modTimer(0.625) - else - minor_announce(CONFIG_GET(string/alert_red_downto), "Attention! Code red!") - GLOB.security_level = SEC_LEVEL_RED - sound_to_playing_players('sound/misc/voyalert.ogg', volume = 50) // Citadel change - Makes alerts play a sound - - for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(is_station_level(FA.z)) - FA.update_icon() - for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines) - pod.admin_controlled = FALSE - if(SEC_LEVEL_DELTA) - minor_announce(CONFIG_GET(string/alert_delta), "Attention! Delta security level reached!",1) - if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) - if(GLOB.security_level < SEC_LEVEL_BLUE) - SSshuttle.emergency.modTimer(0.25) - else if(GLOB.security_level == SEC_LEVEL_BLUE) - SSshuttle.emergency.modTimer(0.416) - else - SSshuttle.emergency.modTimer(0.625) - GLOB.security_level = SEC_LEVEL_DELTA - sound_to_playing_players('sound/misc/deltakalaxon.ogg') // Citadel change - Makes alerts play a sound - for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(is_station_level(FA.z)) - FA.update_icon() - for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines) - pod.admin_controlled = FALSE - if(level >= SEC_LEVEL_RED) - for(var/obj/machinery/door/D in GLOB.machines) - if(D.red_alert_access) - D.visible_message("[D] whirrs as it automatically lifts access requirements!") - playsound(D, 'sound/machines/boltsup.ogg', 50, TRUE) - SSblackbox.record_feedback("tally", "security_level_changes", 1, NUM2SECLEVEL(GLOB.security_level)) - SSnightshift.check_nightshift() - else - return + SSsecurity_level.set_level(level) diff --git a/code/modules/shuttle/arrivals.dm b/code/modules/shuttle/arrivals.dm index 8322c6cdd8..e0ca10db8a 100644 --- a/code/modules/shuttle/arrivals.dm +++ b/code/modules/shuttle/arrivals.dm @@ -195,9 +195,9 @@ /obj/docking_port/mobile/arrivals/proc/QueueAnnounce(mob, rank) if(mode != SHUTTLE_CALL) - AnnounceArrival(mob, rank) + announce_arrival(mob, rank) else - LAZYADD(queued_announces, CALLBACK(GLOBAL_PROC, .proc/AnnounceArrival, mob, rank)) + LAZYADD(queued_announces, CALLBACK(GLOBAL_PROC, .proc/announce_arrival, mob, rank)) /obj/docking_port/mobile/arrivals/vv_edit_var(var_name, var_value) switch(var_name) diff --git a/code/modules/shuttle/custom_shuttle.dm b/code/modules/shuttle/custom_shuttle.dm index 8047e972db..e8e5fe8d4d 100644 --- a/code/modules/shuttle/custom_shuttle.dm +++ b/code/modules/shuttle/custom_shuttle.dm @@ -35,67 +35,63 @@ . = ..() . += distance_multiplier < 1 ? "Bluespace shortcut module installed. Route is [distance_multiplier]x the original length." : "" -/obj/machinery/computer/custom_shuttle/ui_interact(mob/user) +/obj/machinery/computer/custom_shuttle/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "CustomShuttleConsole", name) + ui.open() + +/obj/machinery/computer/custom_shuttle/ui_data(mob/user) + var/list/data = list() var/list/options = params2list(possible_destinations) var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId) - var/dat = "[M ? "Current Location : [M.getStatusText()]" : "Shuttle link required."]

    " + data["docked_location"] = M ? M.get_status_text_tgui() : null if(M) - dat += "Run Flight Calculations
    " - dat += "Shuttle Data
    " - dat += "Shuttle Mass: [calculated_mass/10]tons
    " - dat += "Engine Force: [calculated_dforce]kN ([calculated_engine_count] engines)
    " - dat += "Sublight Speed: [calculated_speed]ms-1
    " - dat += calculated_speed < 1 ? "INSUFFICIENT ENGINE POWER
    " : "" - dat += calculated_non_operational_thrusters > 0 ? "Warning: [calculated_non_operational_thrusters] thrusters offline.
    " : "" - dat += "Fuel Consumption: [calculated_consumption]units per distance
    " - dat += "Engine Cooldown: [calculated_cooldown]s
    " - var/destination_found + calculateStats(FALSE, 0, TRUE) + data["ship_name"] = M.area_type ? M.area_type:name : "ERROR" + data["shuttle_mass"] = calculated_mass/10 + data["engine_force"] = calculated_dforce + data["engines"] = calculated_engine_count + data["calculated_speed"] = calculated_speed + data["damaged_engines"] = calculated_non_operational_thrusters + data["calculated_consumption"] = calculated_consumption + data["calculated_cooldown"] = calculated_cooldown + data["locations"] = list() for(var/obj/docking_port/stationary/S in SSshuttle.stationary) if(!options.Find(S.id)) continue - if(!M.check_dock(S, silent=TRUE)) + if(!M.check_dock(S, silent = TRUE)) continue - if(calculated_speed == 0) - break - destination_found = TRUE - var/dist = round(calculateDistance(S)) - dat += "Target [S.name] (Dist: [dist] | Fuel Cost: [round(dist * calculated_consumption)] | Time: [round(dist / calculated_speed)])
    " - if(!destination_found) - dat += "No valid destinations
    " - dat += "
    [targetLocation ? "Target Location : [targetLocation]" : "No Target Location"]" - dat += "
    Initate Flight
    " - dat += "Close" + var/list/location_data = list( + id = S.id, + name = S.name, + dist = round(calculateDistance(S)) + ) + data["locations"] += list(location_data) + data["destination"] = targetLocation + return data - popup = new(user, "computer", M ? M.name : "shuttle", 350, 450) - popup.set_content("
    [dat]
    ") - popup.open() - -/obj/machinery/computer/custom_shuttle/Topic(href, href_list) - if(..()) +/obj/machinery/computer/custom_shuttle/ui_act(action, params) + . = ..() + if(.) return - usr.set_machine(src) - src.add_fingerprint(usr) if(!allowed(usr)) to_chat(usr, "Access denied.") return - if(href_list["calculate"]) - calculateStats() - ui_interact(usr) - return var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId) if(!M) + to_chat(usr, "Shuttle Link Required.") return if(M.launch_status == ENDGAME_LAUNCHED) return - if(href_list["setloc"]) - SetTargetLocation(href_list["setloc"]) - ui_interact(usr) - return - else if(href_list["fly"]) - Fly() - ui_interact(usr) - return + + switch(action) + if("setloc") + SetTargetLocation(params["setloc"]) + if("fly") + Fly() + return /obj/machinery/computer/custom_shuttle/proc/calculateDistance(var/obj/docking_port/stationary/port) var/deltaX = port.x - x @@ -239,7 +235,7 @@ designate_time = 100 circuit = /obj/item/circuitboard/computer/shuttle/docker -/obj/machinery/computer/camera_advanced/shuttle_docker/custom/Initialize() +/obj/machinery/computer/camera_advanced/shuttle_docker/custom/Initialize(mapload) . = ..() GLOB.jam_on_wardec += src diff --git a/code/modules/shuttle/docking.dm b/code/modules/shuttle/docking.dm index 5c96bca07c..103e331039 100644 --- a/code/modules/shuttle/docking.dm +++ b/code/modules/shuttle/docking.dm @@ -162,7 +162,7 @@ for(var/i in 1 to areas_to_move.len) CHECK_TICK var/area/internal_area = areas_to_move[i] - internal_area.afterShuttleMove(new_parallax_dir) //areas + internal_area.afterShuttleMove(new_parallax_dir, parallax_speed) //areas for(var/i in 1 to old_turfs.len) CHECK_TICK diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index cc37fbbcc4..9c7dd57973 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -461,11 +461,11 @@ for(var/area/shuttle/escape/E in GLOB.sortedAreas) areas += E hyperspace_sound(HYPERSPACE_END, areas) - if(time_left <= PARALLAX_LOOP_TIME) + if(time_left <= parallax_speed) var/area_parallax = FALSE for(var/place in shuttle_areas) var/area/shuttle/shuttle_area = place - if(shuttle_area.parallax_movedir) + if(shuttle_area.parallax_moving) area_parallax = TRUE break if(area_parallax) @@ -538,6 +538,10 @@ density = FALSE clockwork = TRUE //it'd look weird +/obj/machinery/computer/shuttle/pod/Initialize(mapload) + . = ..() + RegisterSignal(SSsecurity_level, COMSIG_SECURITY_LEVEL_CHANGED, .proc/check_lock) + /obj/machinery/computer/shuttle/pod/ComponentInitialize() . = ..() AddElement(/datum/element/update_icon_blocker) @@ -555,15 +559,31 @@ if(possible_destinations == initial(possible_destinations) || override) possible_destinations = "pod_lavaland[idnum]" +/** + * Signal handler for checking if we should lock or unlock escape pods accordingly to a newly set security level + * + * Arguments: + * * source The datum source of the signal + * * new_level The new security level that is in effect + */ +/obj/machinery/computer/shuttle/pod/proc/check_lock(datum/source, new_level) + SIGNAL_HANDLER + + if(obj_flags & EMAGGED) + return + + admin_controlled = !(new_level < SEC_LEVEL_RED) + /obj/docking_port/stationary/random name = "escape pod" id = "pod" dwidth = 1 width = 3 height = 4 - var/target_area = list(/area/lavaland/surface/outdoors, /area/icemoon/underground/unexplored/rivers) + /// The area the pod tries to land at + var/target_area = /area/lavaland/surface/outdoors + /// Minimal distance from the map edge, setting this too low can result in shuttle landing on the edge and getting "sliced" var/edge_distance = 16 - // Minimal distance from the map edge, setting this too low can result in shuttle landing on the edge and getting "sliced" /obj/docking_port/stationary/random/Initialize(mapload) . = ..() @@ -571,15 +591,21 @@ return var/list/turfs = get_area_turfs(target_area) - var/turf/T = pick(turfs) - + var/original_len = turfs.len while(turfs.len) - if(T.xTargeting transit location, please wait [DisplayTimeText(designate_time)]...") designating_target_loc = the_eye.loc - var/wait_completed = do_after(current_user, designate_time, FALSE, designating_target_loc, TRUE, CALLBACK(src, /obj/machinery/computer/camera_advanced/shuttle_docker/proc/canDesignateTarget)) + var/wait_completed = do_after(current_user, designate_time, designating_target_loc, timed_action_flags = IGNORE_HELD_ITEM, extra_checks = CALLBACK(src, /obj/machinery/computer/camera_advanced/shuttle_docker/proc/canDesignateTarget)) designating_target_loc = null if(!current_user) return @@ -356,7 +356,7 @@ playsound(console, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0) remote_eye.setLoc(T) to_chat(target, "Jumped to [selected]") - C.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/flash/static) + C.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/tiled/flash/static) C.clear_fullscreen("flash", 3) else playsound(console, 'sound/machines/terminal_prompt_deny.ogg', 25, 0) diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 8c1b3fa955..ceb9b7adea 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -117,8 +117,6 @@ All ShuttleMove procs go here if(rotation) shuttleRotate(rotation) - update_parallax_contents() - return TRUE /atom/movable/proc/lateShuttleMove(turf/oldT, list/movement_force, move_dir) @@ -153,16 +151,21 @@ All ShuttleMove procs go here //The old turf has now been given back to the area that turf originaly belonged to var/area/old_dest_area = newT.loc - parallax_movedir = old_dest_area.parallax_movedir - + parallax_moving = old_dest_area.parallax_moving + parallax_move_angle = old_dest_area.parallax_move_angle + parallax_move_speed = old_dest_area.parallax_move_speed old_dest_area.contents -= newT contents += newT newT.change_area(old_dest_area, src) return TRUE // Called on areas after everything has been moved -/area/proc/afterShuttleMove(new_parallax_dir) - parallax_movedir = new_parallax_dir +/area/proc/afterShuttleMove(new_parallax_dir, speed) + if(!new_parallax_dir) + parallax_moving = FALSE + return + parallax_move_angle = dir2angle(new_parallax_dir) + parallax_move_speed = speed return TRUE /area/proc/lateShuttleMove() @@ -309,6 +312,7 @@ All ShuttleMove procs go here if(buckled) shake_force *= 0.25 shake_camera(src, shake_force, 1) + client?.parallax_holder?.Reset(auto_z_change = FALSE, force = TRUE) /mob/living/lateShuttleMove(turf/oldT, list/movement_force, move_dir) if(buckled) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 0eb7f6ee20..1fc81e38b8 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -281,7 +281,7 @@ var/area/shuttle/transit/assigned_area var/obj/docking_port/mobile/owner -/obj/docking_port/stationary/transit/Initialize() +/obj/docking_port/stationary/transit/Initialize(mapload) . = ..() SSshuttle.transit += src @@ -299,6 +299,16 @@ reserved_area = null return ..() +/obj/docking_port/stationary/picked/whiteship + name = "Deep Space" + id = "whiteship_away" + dheight = 0 + dir = 2 + dwidth = 11 + height = 22 + width = 35 + shuttlekeys = list("whiteship_meta", "whiteship_pubby", "whiteship_box", "whiteship_cere", "whiteship_kilo", "whiteship_donut", "whiteship_delta") + /obj/docking_port/stationary/picked ///Holds a list of map name strings for the port to pick from var/list/shuttlekeys @@ -367,6 +377,9 @@ var/can_move_docking_ports = FALSE var/list/hidden_turfs = list() + /// parallax speed in seconds per loop + var/parallax_speed = 25 + /obj/docking_port/mobile/register(replace = FALSE) . = ..() if(!id) @@ -709,27 +722,24 @@ create_ripples(destination, tl) var/obj/docking_port/stationary/S0 = get_docked() - if(istype(S0, /obj/docking_port/stationary/transit) && timeLeft(1) <= PARALLAX_LOOP_TIME) + if(istype(S0, /obj/docking_port/stationary/transit) && timeLeft(1) <= parallax_speed) + var/parallax_ongoing = FALSE for(var/place in shuttle_areas) var/area/shuttle/shuttle_area = place - if(shuttle_area.parallax_movedir) - parallax_slowdown() + if(shuttle_area.parallax_moving) + parallax_ongoing = TRUE + if(parallax_ongoing) + parallax_slowdown() /obj/docking_port/mobile/proc/parallax_slowdown() - for(var/place in shuttle_areas) - var/area/shuttle/shuttle_area = place - shuttle_area.parallax_movedir = FALSE - if(assigned_transit?.assigned_area) - assigned_transit.assigned_area.parallax_movedir = FALSE - var/list/L0 = return_ordered_turfs(x, y, z, dir) - for (var/thing in L0) - var/turf/T = thing - if(!T || !istype(T.loc, area_type)) - continue - for (var/thing2 in T) - var/atom/movable/AM = thing2 - if (length(AM.client_mobs_in_contents)) - AM.update_parallax_contents() + for(var/mob/M in GLOB.player_list) + var/area/A = get_area(M) + if(A in shuttle_areas) + M.client?.parallax_holder?.StopScrolling(A.parallax_move_angle, parallax_speed) + for(var/area/shuttle_area in shuttle_areas + assigned_transit?.assigned_area) + shuttle_area.parallax_moving = FALSE + shuttle_area.parallax_move_speed = 0 + shuttle_area.parallax_move_angle = 0 /obj/docking_port/mobile/proc/check_transit_zone() if(assigned_transit) @@ -891,7 +901,7 @@ var/range = (engine_coeff * max(width, height)) var/long_range = range * 2.5 var/atom/distant_source - if(engine_list[1]) + if(length(engine_list)) distant_source = engine_list[1] else for(var/A in areas) diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator.dm index b9374a09c4..ac604fbe49 100644 --- a/code/modules/shuttle/shuttle_creation/shuttle_creator.dm +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator.dm @@ -24,7 +24,7 @@ GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (He throw_range = 5 w_class = WEIGHT_CLASS_NORMAL req_access_txt = "11" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF var/ready = TRUE //pre-designation @@ -39,7 +39,7 @@ GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (He //After designation var/linkedShuttleId -/obj/item/shuttle_creator/Initialize() +/obj/item/shuttle_creator/Initialize(mapload) . = ..() internal_shuttle_creator = new() internal_shuttle_creator.owner_rsd = src diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm index ff96e2ae65..2bbe7d7407 100644 --- a/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm @@ -8,7 +8,7 @@ var/turf/source_turf var/max_range = 12 -/mob/camera/aiEye/remote/shuttle_creation/Initialize() +/mob/camera/aiEye/remote/shuttle_creation/Initialize(mapload) . = ..() setLoc(get_turf(source_turf)) diff --git a/code/modules/shuttle/spaceship_navigation_beacon.dm b/code/modules/shuttle/spaceship_navigation_beacon.dm index dbf81d791e..e3232ec904 100644 --- a/code/modules/shuttle/spaceship_navigation_beacon.dm +++ b/code/modules/shuttle/spaceship_navigation_beacon.dm @@ -17,7 +17,7 @@ var/locked = FALSE //Locked beacons don't allow to jump to it. -/obj/machinery/spaceship_navigation_beacon/Initialize() +/obj/machinery/spaceship_navigation_beacon/Initialize(mapload) . = ..() SSshuttle.beacons |= src diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm index 87f9b55aa9..5e034c0b52 100644 --- a/code/modules/shuttle/special.dm +++ b/code/modules/shuttle/special.dm @@ -15,7 +15,7 @@ var/list/active_tables = list() var/tables_required = 2 -/obj/machinery/power/emitter/energycannon/magical/Initialize() +/obj/machinery/power/emitter/energycannon/magical/Initialize(mapload) . = ..() if(prob(50)) desc = "Oh no, not again." @@ -44,7 +44,7 @@ /obj/machinery/power/emitter/energycannon/magical/attackby(obj/item/W, mob/user, params) return -/obj/machinery/power/emitter/energycannon/magical/ex_act(severity) +/obj/machinery/power/emitter/energycannon/magical/ex_act(severity, target, origin) return /obj/machinery/power/emitter/energycannon/magical/emag_act(mob/user) @@ -144,7 +144,7 @@ unique_name = FALSE // disables the (123) number suffix initial_language_holder = /datum/language_holder/universal -/mob/living/simple_animal/drone/snowflake/bardrone/Initialize() +/mob/living/simple_animal/drone/snowflake/bardrone/Initialize(mapload) . = ..() access_card.access |= ACCESS_CENT_BAR @@ -159,7 +159,7 @@ stop_automated_movement = TRUE initial_language_holder = /datum/language_holder/universal -/mob/living/simple_animal/hostile/alien/maid/barmaid/Initialize() +/mob/living/simple_animal/hostile/alien/maid/barmaid/Initialize(mapload) . = ..() access_card = new /obj/item/card/id(src) var/datum/job/captain/C = new /datum/job/captain @@ -212,15 +212,14 @@ var/static/list/check_times = list() -/obj/effect/forcefield/luxury_shuttle/CanPass(atom/movable/mover, turf/target) +/obj/effect/forcefield/luxury_shuttle/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(mover in approved_passengers) return TRUE if(!isliving(mover)) //No stowaways return FALSE - return FALSE - #define LUXURY_MESSAGE_COOLDOWN 100 /obj/effect/forcefield/luxury_shuttle/Bumped(atom/movable/AM) diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index bfda6c453c..21d616bee4 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -131,7 +131,7 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( for(var/datum/supply_order/SO in SSshuttle.shoppinglist) if(!empty_turfs.len) break - var/price = SO.pack.cost + var/price = SO.pack.get_cost() if(SO.applied_coupon) price *= (1 - SO.applied_coupon.discount_pct_off) @@ -163,8 +163,8 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( LAZYADD(goodies_by_buyer[SO.paying_account], SO) D.bank_card_talk("Cargo order #[SO.id] has shipped. [price] credits have been charged to your bank account.") var/datum/bank_account/department/cargo = SSeconomy.get_dep_account(ACCOUNT_CAR) - cargo.adjust_money(price - SO.pack.cost) //Cargo gets the handling fee - value += SO.pack.cost + cargo.adjust_money(price - SO.pack.get_cost()) //Cargo gets the handling fee + value += SO.pack.get_cost() SSshuttle.shoppinglist -= SO SSshuttle.orderhistory += SO QDEL_NULL(SO.applied_coupon) @@ -172,7 +172,7 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( if(!SO.pack.goody && !ispath(SO.pack.crate_type, /obj/structure/closet/secure_closet/cargo)) //we handle goody crates and material closets below SO.generate(pick_n_take(empty_turfs)) - SSblackbox.record_feedback("nested tally", "cargo_imports", 1, list("[SO.pack.cost]", "[SO.pack.name]")) + SSblackbox.record_feedback("nested tally", "cargo_imports", 1, list("[SO.pack.get_cost()]", "[SO.pack.name]")) investigate_log("Order #[SO.id] ([SO.pack.name], placed by [key_name(SO.orderer_ckey)]), paid by [D.account_holder] has shipped.", INVESTIGATE_CARGO) if(SO.pack.dangerous) message_admins("\A [SO.pack.name] ordered by [ADMIN_LOOKUPFLW(SO.orderer_ckey)], paid by [D.account_holder] has shipped.") @@ -261,7 +261,7 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( matched_bounty = TRUE // ignore mech checks because the mech is ONLY for bounty continue - if(!AM.anchored || istype(AM, /obj/mecha)) + if(!AM.anchored || istype(AM, /obj/vehicle/sealed/mecha)) export_item_and_contents(AM, export_categories , dry_run = FALSE, external_report = ex) if(ex.exported_atoms) diff --git a/code/modules/shuttle/white_ship.dm b/code/modules/shuttle/white_ship.dm index 66146edea1..6d8b2446f7 100644 --- a/code/modules/shuttle/white_ship.dm +++ b/code/modules/shuttle/white_ship.dm @@ -41,7 +41,7 @@ y_offset = 0 designate_time = 0 -/obj/machinery/computer/camera_advanced/shuttle_docker/whiteship/Initialize() +/obj/machinery/computer/camera_advanced/shuttle_docker/whiteship/Initialize(mapload) . = ..() GLOB.jam_on_wardec += src @@ -51,6 +51,6 @@ /obj/effect/spawner/lootdrop/whiteship_cere_ripley name = "25% mech 75% wreckage ripley spawner" - loot = list(/obj/mecha/working/ripley/mining = 1, + loot = list(/obj/vehicle/sealed/mecha/working/ripley/mining = 1, /obj/structure/mecha_wreckage/ripley = 5) lootdoubles = FALSE diff --git a/code/modules/smithing/anvil.dm b/code/modules/smithing/anvil.dm index b796edabbf..197b39272d 100644 --- a/code/modules/smithing/anvil.dm +++ b/code/modules/smithing/anvil.dm @@ -68,7 +68,7 @@ RECIPE_GLAIVE = /obj/item/smithing/glaivehead, RECIPE_PIKE = /obj/item/smithing/pikehead) -/obj/structure/anvil/Initialize() +/obj/structure/anvil/Initialize(mapload) ..() currentquality = anvilquality @@ -286,6 +286,13 @@ anvilquality = 0 itemqualitymax = 6 +/obj/structure/anvil/obtainable/bone + name = "bone anvil" + desc = "An anvil. It's made of goliath bones and hide and held together by watcher sinews." + icon_state = "bonevil" + anvilquality = 0 + itemqualitymax = 6 + /obj/structure/anvil/obtainable/ratvar name = "brass anvil" desc = "A big block of what appears to be brass. Useable as an anvil, if whatever's holding the brass together lets you." diff --git a/code/modules/smithing/finished_items.dm b/code/modules/smithing/finished_items.dm index 27be8c034d..97618df8fc 100644 --- a/code/modules/smithing/finished_items.dm +++ b/code/modules/smithing/finished_items.dm @@ -18,7 +18,7 @@ var/wielded_mult = 1 var/wield_force = 15 -/obj/item/melee/smith/Initialize() +/obj/item/melee/smith/Initialize(mapload) ..() if(desc == "cringe") desc = "A handmade [name]." @@ -55,7 +55,7 @@ icon_state = "minipick" //todo:sprite sharpness = SHARP_POINTY//it doesnt have a blade it has a point -/obj/item/mining_scanner/prospector/Initialize() +/obj/item/mining_scanner/prospector/Initialize(mapload) ..() var/mutable_appearance/overlay desc = "A handmade [name]." @@ -73,7 +73,7 @@ icon_state = "pickaxe" sharpness = SHARP_POINTY -/obj/item/pickaxe/smithed/Initialize() +/obj/item/pickaxe/smithed/Initialize(mapload) ..() desc = "A handmade [name]." var/mutable_appearance/overlay @@ -94,7 +94,7 @@ icon_state = "shovel" sharpness = SHARP_EDGED //it cuts through the earth -/obj/item/shovel/smithed/Initialize() +/obj/item/shovel/smithed/Initialize(mapload) ..() desc = "A handmade [name]." var/mutable_appearance/overlay diff --git a/code/modules/smithing/furnace.dm b/code/modules/smithing/furnace.dm index ee1d6a1b93..70bff32030 100644 --- a/code/modules/smithing/furnace.dm +++ b/code/modules/smithing/furnace.dm @@ -10,7 +10,7 @@ var/fueluse = 1 -/obj/structure/furnace/Initialize() +/obj/structure/furnace/Initialize(mapload) ..() create_reagents(250, TRANSPARENT) START_PROCESSING(SSobj, src) diff --git a/code/modules/smithing/smithed_items.dm b/code/modules/smithing/smithed_items.dm index 71e35ba989..3453cafda3 100644 --- a/code/modules/smithing/smithed_items.dm +++ b/code/modules/smithing/smithed_items.dm @@ -49,6 +49,9 @@ /obj/item/ingot/iron custom_materials = list(/datum/material/iron=12000) +/obj/item/ingot/bone + custom_materials = list(/datum/material/bone=4000) + /obj/item/ingot/diamond custom_materials = list(/datum/material/diamond=12000) diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm index 2272a14612..4be592b919 100644 --- a/code/modules/spells/spell.dm +++ b/code/modules/spells/spell.dm @@ -15,7 +15,7 @@ var/action_background_icon_state = "bg_spell" var/base_action = /datum/action/spell_action -/obj/effect/proc_holder/Initialize() +/obj/effect/proc_holder/Initialize(mapload) . = ..() if(has_action) action = new base_action(src) @@ -35,6 +35,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for the badmin verb for now /obj/effect/proc_holder/Destroy() + QDEL_NULL(action) if(ranged_ability_user) remove_ranged_ability() return ..() @@ -144,7 +145,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th action_background_icon_state = "bg_spell" base_action = /datum/action/spell_action/spell -/obj/effect/proc_holder/spell/Initialize() +/obj/effect/proc_holder/spell/Initialize(mapload) . = ..() if(mobs_whitelist) mobs_whitelist = typecacheof(mobs_whitelist) @@ -204,7 +205,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th /obj/effect/proc_holder/spell/proc/playMagSound() playsound(get_turf(usr), sound,50,1) -/obj/effect/proc_holder/spell/Initialize() +/obj/effect/proc_holder/spell/Initialize(mapload) . = ..() START_PROCESSING(SSfastprocess, src) diff --git a/code/modules/spells/spell_types/construct_spells.dm b/code/modules/spells/spell_types/construct_spells.dm index e8f3ab7d06..7a22d1498a 100644 --- a/code/modules/spells/spell_types/construct_spells.dm +++ b/code/modules/spells/spell_types/construct_spells.dm @@ -317,6 +317,6 @@ new /obj/effect/temp_visual/cult/sac(T) for(var/obj/O in range(src,1)) if(O.density && !istype(O, /obj/structure/destructible/cult)) - O.take_damage(90, BRUTE, "melee", 0) + O.take_damage(90, BRUTE, MELEE, 0) new /obj/effect/temp_visual/cult/turf/floor ..() diff --git a/code/modules/spells/spell_types/curse.dm b/code/modules/spells/spell_types/curse.dm index 9449e4a5d0..43340f98ef 100644 --- a/code/modules/spells/spell_types/curse.dm +++ b/code/modules/spells/spell_types/curse.dm @@ -8,7 +8,7 @@ GLOBAL_VAR_INIT(curse_of_madness_triggered, FALSE) GLOB.curse_of_madness_triggered = message // So latejoiners are also afflicted. - deadchat_broadcast("A Curse of Madness has stricken the station, shattering their minds with the awful secret: \"[message]\"") + deadchat_broadcast("A [span_name("Curse of Madness")] has stricken the station, shattering their minds with the awful secret: \"[message]\"", message_type=DEADCHAT_ANNOUNCEMENT) for(var/mob/living/carbon/human/H in GLOB.player_list) if(H.stat == DEAD) diff --git a/code/modules/spells/spell_types/ethereal_jaunt.dm b/code/modules/spells/spell_types/ethereal_jaunt.dm index 7a05583071..1bc3a054b7 100644 --- a/code/modules/spells/spell_types/ethereal_jaunt.dm +++ b/code/modules/spells/spell_types/ethereal_jaunt.dm @@ -105,7 +105,7 @@ forceMove(newLoc) -/obj/effect/dummy/phased_mob/spell_jaunt/ex_act(blah) +/obj/effect/dummy/phased_mob/spell_jaunt/ex_act(severity, target, origin) return /obj/effect/dummy/phased_mob/spell_jaunt/wave_ex_act(power, datum/wave_explosion/explosion, dir) diff --git a/code/modules/spells/spell_types/forcewall.dm b/code/modules/spells/spell_types/forcewall.dm index e0c21066cf..be7bb4cbd3 100644 --- a/code/modules/spells/spell_types/forcewall.dm +++ b/code/modules/spells/spell_types/forcewall.dm @@ -30,11 +30,11 @@ . = ..() wizard = summoner -/obj/effect/forcefield/wizard/CanPass(atom/movable/mover, turf/target) +/obj/effect/forcefield/wizard/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(mover == wizard) return TRUE if(ismob(mover)) var/mob/M = mover if(M.anti_magic_check(chargecost = 0)) return TRUE - return FALSE diff --git a/code/modules/spells/spell_types/godhand.dm b/code/modules/spells/spell_types/godhand.dm index fe53fd37e4..073f96d498 100644 --- a/code/modules/spells/spell_types/godhand.dm +++ b/code/modules/spells/spell_types/godhand.dm @@ -15,7 +15,7 @@ throw_speed = 0 var/charges = 1 -/obj/item/melee/touch_attack/Initialize() +/obj/item/melee/touch_attack/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) diff --git a/code/modules/spells/spell_types/lichdom.dm b/code/modules/spells/spell_types/lichdom.dm index fbe7a0ea40..2a21916c8a 100644 --- a/code/modules/spells/spell_types/lichdom.dm +++ b/code/modules/spells/spell_types/lichdom.dm @@ -46,7 +46,7 @@ playsound(user, 'sound/effects/pope_entry.ogg', 100) - if(!do_after(M, 50, needhand=FALSE, target=marked_item)) + if(!do_after(M, 5 SECONDS, marked_item, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_HELD_ITEM))) to_chat(M, "Your soul snaps back to your body as you stop ensouling [marked_item]!") return @@ -63,9 +63,9 @@ H.dropItemToGround(H.w_uniform) H.dropItemToGround(H.wear_suit) H.dropItemToGround(H.head) - H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(H), SLOT_WEAR_SUIT) - H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/black(H), SLOT_HEAD) - H.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(H), SLOT_W_UNIFORM) + H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(H), ITEM_SLOT_OCLOTHING) + H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/black(H), ITEM_SLOT_HEAD) + H.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(H), ITEM_SLOT_ICLOTHING) // you only get one phylactery. M.mind.RemoveSpell(src) @@ -132,10 +132,10 @@ var/mob/old_body = mind.current var/mob/living/carbon/human/lich = new(item_turf) - lich.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(lich), SLOT_SHOES) - lich.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(lich), SLOT_W_UNIFORM) - lich.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(lich), SLOT_WEAR_SUIT) - lich.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/black(lich), SLOT_HEAD) + lich.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(lich), ITEM_SLOT_FEET) + lich.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(lich), ITEM_SLOT_ICLOTHING) + lich.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(lich), ITEM_SLOT_OCLOTHING) + lich.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/black(lich), ITEM_SLOT_HEAD) lich.real_name = mind.name mind.transfer_to(lich) diff --git a/code/modules/spells/spell_types/lightning.dm b/code/modules/spells/spell_types/lightning.dm index d0c3c4166c..f5aaca2a87 100644 --- a/code/modules/spells/spell_types/lightning.dm +++ b/code/modules/spells/spell_types/lightning.dm @@ -27,7 +27,7 @@ halo = halo || mutable_appearance('icons/effects/effects.dmi', "electricity", EFFECTS_LAYER) user.add_overlay(halo) playsound(get_turf(user), Snd, 50, 0) - if(do_mob(user,user,100,1)) + if(do_mob(user, user, 10 SECONDS)) if(ready && cast_check(skipcharge=1)) choose_targets() else diff --git a/code/modules/spells/spell_types/pointed/mind_transfer.dm b/code/modules/spells/spell_types/pointed/mind_transfer.dm index 28d646f6b6..caab6c5547 100644 --- a/code/modules/spells/spell_types/pointed/mind_transfer.dm +++ b/code/modules/spells/spell_types/pointed/mind_transfer.dm @@ -44,6 +44,13 @@ to_chat(user, "The devilish contract doesn't include the 'mind swappable' package, please try again another lifetime.") return + // lets not have people be mindswapped to/from people who have people currently in their vore bellies + if(has_vore_belly(user)) + user.release_vore_contents(include_absorbed = TRUE, silent = TRUE) + + if(has_vore_belly(victim)) + victim.release_vore_contents(include_absorbed = TRUE, silent = TRUE) + //MIND TRANSFER BEGIN var/mob/dead/observer/ghost = victim.ghostize() user.mind.transfer_to(victim) diff --git a/code/modules/spells/spell_types/shadow_walk.dm b/code/modules/spells/spell_types/shadow_walk.dm index 821bf73425..9b311ee1a6 100644 --- a/code/modules/spells/spell_types/shadow_walk.dm +++ b/code/modules/spells/spell_types/shadow_walk.dm @@ -87,7 +87,7 @@ qdel(src) check_light_level() -/obj/effect/dummy/phased_mob/shadow/ex_act() +/obj/effect/dummy/phased_mob/shadow/ex_act(severity, target, origin) return /obj/effect/dummy/phased_mob/shadow/wave_ex_act(power, datum/wave_explosion/explosion, dir) diff --git a/code/modules/spells/spell_types/trigger.dm b/code/modules/spells/spell_types/trigger.dm index df579d9243..4a48c868b8 100644 --- a/code/modules/spells/spell_types/trigger.dm +++ b/code/modules/spells/spell_types/trigger.dm @@ -4,7 +4,7 @@ var/list/linked_spells = list() //those are just referenced by the trigger spell and are unaffected by it directly var/list/starting_spells = list() //those are added on New() to contents from default spells and are deleted when the trigger spell is deleted to prevent memory leaks -/obj/effect/proc_holder/spell/pointed/trigger/Initialize() +/obj/effect/proc_holder/spell/pointed/trigger/Initialize(mapload) . = ..() for(var/spell in starting_spells) var/spell_to_add = text2path(spell) diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm index cb1fdcfc2e..2f0cba0056 100644 --- a/code/modules/station_goals/bsa.dm +++ b/code/modules/station_goals/bsa.dm @@ -226,7 +226,7 @@ invisibility = INVISIBILITY_ABSTRACT var/obj/machinery/parent -/obj/structure/filler/ex_act() +/obj/structure/filler/ex_act(severity, target, origin) return /obj/machinery/computer/bsa_control diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm index b68a289e85..297f918c6f 100644 --- a/code/modules/station_goals/dna_vault.dm +++ b/code/modules/station_goals/dna_vault.dm @@ -63,10 +63,10 @@ name = "DNA Sampler" desc = "Can be used to take chemical and genetic samples of pretty much anything." icon = 'icons/obj/syringe.dmi' - item_state = "hypo" + item_state = "sampler" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - icon_state = "hypo" + icon_state = "sampler" item_flags = NOBLUDGEON var/list/animals = list() var/list/plants = list() @@ -145,7 +145,7 @@ var/list/obj/structure/fillers = list() -/obj/machinery/dna_vault/Initialize() +/obj/machinery/dna_vault/Initialize(mapload) //TODO: Replace this,bsa and gravgen with some big machinery datum var/list/occupied = list() for(var/direct in list(EAST,WEST,SOUTHEAST,SOUTHWEST)) diff --git a/code/modules/station_goals/shield.dm b/code/modules/station_goals/shield.dm index e317820e7d..f17af626a1 100644 --- a/code/modules/station_goals/shield.dm +++ b/code/modules/station_goals/shield.dm @@ -95,7 +95,7 @@ var/static/gid = 0 var/id = 0 -/obj/machinery/satellite/Initialize() +/obj/machinery/satellite/Initialize(mapload) . = ..() id = gid++ diff --git a/code/modules/station_goals/station_goal.dm b/code/modules/station_goals/station_goal.dm index b68fef3e2f..856bf08ff3 100644 --- a/code/modules/station_goals/station_goal.dm +++ b/code/modules/station_goals/station_goal.dm @@ -12,7 +12,7 @@ var/report_message = "Complete this goal." /datum/station_goal/proc/send_report() - priority_announce("Priority Nanotrasen directive received. Project \"[name]\" details inbound.", "Incoming Priority Message", "commandreport") + priority_announce("Priority Nanotrasen directive received. Project \"[name]\" details inbound.", "Incoming Priority Message", SSstation.announcer.get_rand_report_sound()) print_command_report(get_report(),"Nanotrasen Directive [pick(GLOB.phonetic_alphabet)] \Roman[rand(1,50)]", announce=FALSE) on_report() diff --git a/code/modules/surgery/advanced/brainwashing.dm b/code/modules/surgery/advanced/brainwashing.dm index 28103f7f97..7ad7af273a 100644 --- a/code/modules/surgery/advanced/brainwashing.dm +++ b/code/modules/surgery/advanced/brainwashing.dm @@ -1,7 +1,10 @@ /obj/item/disk/surgery/brainwashing name = "Brainwashing Surgery Disk" desc = "The disk provides instructions on how to impress an order on a brain, making it the primary objective of the patient." - surgeries = list(/datum/surgery/advanced/brainwashing) + surgeries = list( + /datum/surgery/advanced/brainwashing, + /datum/surgery/advanced/robot_brainwashing) + /datum/surgery/advanced/brainwashing name = "Brainwashing" desc = "A surgical procedure which directly implants a directive into the patient's brain, making it their absolute priority. It can be cleared using a mindshield implant." @@ -23,11 +26,16 @@ if(!B) return FALSE return TRUE + /datum/surgery_step/brainwash name = "brainwash" implements = list(TOOL_HEMOSTAT = 85, TOOL_WIRECUTTER = 50, /obj/item/stack/packageWrap = 35, /obj/item/stack/cable_coil = 15) time = 200 + preop_sound = 'sound/surgery/hemostat1.ogg' + success_sound = 'sound/surgery/hemostat1.ogg' + failure_sound = 'sound/surgery/organ2.ogg' var/objective + /datum/surgery_step/brainwash/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) objective = stripped_input(user, "Choose the objective to imprint on your victim's brain.", "Brainwashing", null, MAX_MESSAGE_LEN) if(!objective) @@ -49,6 +57,8 @@ to_chat(target, "A new compulsion fills your mind... you feel forced to obey it!") brainwash(target, objective) message_admins("[ADMIN_LOOKUPFLW(user)] surgically brainwashed [ADMIN_LOOKUPFLW(target)] with the objective '[objective]'.") + user.log_message("has brainwashed [key_name(target)] with the objective '[objective]' using brainwashing surgery.", LOG_ATTACK) + target.log_message("has been brainwashed with the objective '[objective]' by [key_name(user)] using brainwashing surgery.", LOG_VICTIM, log_globally=FALSE) log_game("[key_name(user)] surgically brainwashed [key_name(target)] with the objective '[objective]'.") return TRUE diff --git a/code/modules/surgery/advanced/lobotomy.dm b/code/modules/surgery/advanced/lobotomy.dm index 4a52e446bc..fdc5e9b522 100644 --- a/code/modules/surgery/advanced/lobotomy.dm +++ b/code/modules/surgery/advanced/lobotomy.dm @@ -12,6 +12,7 @@ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_HEAD) requires_bodypart_type = 0 + /datum/surgery/advanced/lobotomy/can_start(mob/user, mob/living/carbon/target, obj/item/tool) if(!..()) return FALSE @@ -19,11 +20,16 @@ if(!B) return FALSE return TRUE + /datum/surgery_step/lobotomize name = "perform lobotomy" implements = list(TOOL_SCALPEL = 85, /obj/item/melee/transforming/energy/sword = 55, /obj/item/kitchen/knife = 35, /obj/item/shard = 25, /obj/item = 20) time = 100 + preop_sound = 'sound/surgery/scalpel1.ogg' + success_sound = 'sound/surgery/scalpel2.ogg' + failure_sound = 'sound/surgery/organ2.ogg' + /datum/surgery_step/lobotomize/tool_check(mob/user, obj/item/tool) if(implement_type == /obj/item && !tool.get_sharpness()) return FALSE @@ -41,13 +47,14 @@ target.cure_all_traumas(TRAUMA_RESILIENCE_LOBOTOMY) if(target.mind && target.mind.has_antag_datum(/datum/antagonist/brainwashed)) target.mind.remove_antag_datum(/datum/antagonist/brainwashed) - switch(rand(1,6))//Now let's see what hopefully-not-important part of the brain we cut off - if(1) - target.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_SURGERY) - if(2) - target.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_SURGERY) - if(3) - target.gain_trauma_type(BRAIN_TRAUMA_SPECIAL, TRAUMA_RESILIENCE_SURGERY) + if(prob(50)) + switch(rand(1,3))//Now let's see what hopefully-not-important part of the brain we cut off + if(1) + target.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_SURGERY) + if(2) + target.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_SURGERY) + if(3) + target.gain_trauma_type(BRAIN_TRAUMA_SPECIAL, TRAUMA_RESILIENCE_SURGERY) // you're cutting off a part of the brain.w var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN) B.applyOrganDamage(50, 100) diff --git a/code/modules/surgery/advanced/pacification.dm b/code/modules/surgery/advanced/pacification.dm index 7b85015420..4a68f93a06 100644 --- a/code/modules/surgery/advanced/pacification.dm +++ b/code/modules/surgery/advanced/pacification.dm @@ -11,15 +11,20 @@ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_HEAD) requires_bodypart_type = 0 + /datum/surgery/advanced/pacify/can_start(mob/user, mob/living/carbon/target, obj/item/tool) . = ..() var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN) if(!B) return FALSE + /datum/surgery_step/pacify name = "rewire brain" implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15) time = 40 + preop_sound = 'sound/surgery/hemostat1.ogg' + success_sound = 'sound/surgery/hemostat1.ogg' + failure_sound = 'sound/surgery/organ2.ogg' /datum/surgery_step/pacify/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to pacify [target]...", diff --git a/code/modules/surgery/advanced/revival.dm b/code/modules/surgery/advanced/revival.dm index 945dee48e7..eb186feafa 100644 --- a/code/modules/surgery/advanced/revival.dm +++ b/code/modules/surgery/advanced/revival.dm @@ -12,6 +12,7 @@ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_HEAD) requires_bodypart_type = 0 + /datum/surgery/advanced/revival/can_start(mob/user, mob/living/carbon/target, obj/item/tool) if(!..()) return FALSE @@ -23,10 +24,14 @@ if(!B) return FALSE return TRUE + /datum/surgery_step/revive name = "electrically stimulate brain" implements = list(/obj/item/shockpaddles = 100, /obj/item/abductor/gizmo = 100, /obj/item/rod_of_asclepius = 100, /obj/item/melee/baton = 75, /obj/item/organ/cyberimp/arm/baton = 75, /obj/item/organ/cyberimp/arm/gun/taser = 60, /obj/item/gun/energy/e_gun/advtaser = 60, /obj/item/gun/energy/taser = 60) time = 120 + success_sound = 'sound/magic/lightningbolt.ogg' + failure_sound = 'sound/magic/lightningbolt.ogg' + /datum/surgery_step/revive/tool_check(mob/user, obj/item/tool) . = TRUE if(istype(tool, /obj/item/shockpaddles)) @@ -53,11 +58,16 @@ "[user] prepares to shock [target]'s brain with [tool].") target.notify_ghost_cloning("Someone is trying to zap your brain. Re-enter your corpse if you want to be revived!", source = target) +/datum/surgery_step/revive/play_preop_sound(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(istype(tool, /obj/item/shockpaddles)) + playsound(tool, 'sound/machines/defib_charge.ogg', 75, 0) + else + ..() + /datum/surgery_step/revive/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You successfully shock [target]'s brain with [tool]...", "[user] send a powerful shock to [target]'s brain with [tool]...", "[user] send a powerful shock to [target]'s brain with [tool]...") - playsound(get_turf(target), 'sound/magic/lightningbolt.ogg', 50, 1) target.adjustOxyLoss(-50, 0) target.updatehealth() var/tplus = world.time - target.timeofdeath @@ -86,6 +96,5 @@ display_results(user, target, "You shock [target]'s brain with [tool], but [target.p_they()] doesn't react.", "[user] send a powerful shock to [target]'s brain with [tool], but [target.p_they()] doesn't react.", "[user] send a powerful shock to [target]'s brain with [tool], but [target.p_they()] doesn't react.") - playsound(get_turf(target), 'sound/magic/lightningbolt.ogg', 50, 1) target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 199) return FALSE diff --git a/code/modules/surgery/advanced/robot_brainwashing.dm b/code/modules/surgery/advanced/robot_brainwashing.dm new file mode 100644 index 0000000000..427005b4c0 --- /dev/null +++ b/code/modules/surgery/advanced/robot_brainwashing.dm @@ -0,0 +1,60 @@ +/datum/surgery/advanced/robot_brainwashing + name = "Reprogramming" + desc = "A surgical procedure which hardcodes a directive into the patient's logic subroutines, making it their absolute priority. It can be purged using a mindshield implant." + possible_locs = list(BODY_ZONE_HEAD) + requires_bodypart_type = BODYPART_ROBOTIC + steps = list(/datum/surgery_step/mechanic_open, + /datum/surgery_step/open_hatch, + /datum/surgery_step/mechanic_unwrench, + /datum/surgery_step/prepare_electronics, + /datum/surgery_step/reprogram, + /datum/surgery_step/mechanic_wrench, + /datum/surgery_step/mechanic_close) + +/datum/surgery/advanced/reprogramming/can_start(mob/user, mob/living/carbon/target, obj/item/tool) + if(!..()) + return FALSE + var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN) + if(!B) + return FALSE + return TRUE + +/datum/surgery_step/reprogram + name = "reprogram" + implements = list(TOOL_MULTITOOL = 85, TOOL_HEMOSTAT = 50, TOOL_WIRECUTTER = 35, /obj/item/stack/packageWrap = 35, /obj/item/stack/cable_coil = 15, /obj/item/card/emag = 100) + time = 200 + var/objective + +/datum/surgery_step/reprogram/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + objective = stripped_input(user, "Choose the objective to imprint on your victim's posibrain.", "Reprogramming", null, MAX_MESSAGE_LEN) + if(!objective) + return -1 + display_results(user, target, "You begin to reprogram [target]...", + "[user] begins to fix [target]'s posibrain.", + "[user] begins to perform surgery on [target]'s posibrain.") + +/datum/surgery_step/reprogram/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(!target.mind) + to_chat(user, "[target] doesn't respond to the reprogramming, as if [target.p_they()] lacked a mind...") + return FALSE + if(HAS_TRAIT(target, TRAIT_MINDSHIELD)) + to_chat(user, "You hear a faint buzzing from a device inside [target]'s posibrain, and the programming is purged.") + return FALSE + display_results(user, target, "You succeed in reprogramming [target].", + "[user] successfully fixes [target]'s posibrain!", + "[user] completes the surgery on [target]'s posibrain.") + to_chat(target, "A new directive fills your mind... you feel forced to obey it!") + brainwash(target, objective) + message_admins("[ADMIN_LOOKUPFLW(user)] surgically synth-brainwashed [ADMIN_LOOKUPFLW(target)] with the objective '[objective]'.") + log_game("[key_name(user)] surgically synth-brainwashed [key_name(target)] with the objective '[objective]'.") + return TRUE + +/datum/surgery_step/reprogram/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(target.getorganslot(ORGAN_SLOT_BRAIN)) + display_results(user, target, "You screw up, causing more damage!", + "[user] screws up, causing damage to the circuits!/span>", + "[user] completes the surgery on [target]'s posibrain.") + target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 40) + else + user.visible_message("[user] suddenly notices that the posibrain [user.p_they()] [user.p_were()] working on is not there anymore.", "You suddenly notice that the posibrain you were working on is not there anymore.") + return FALSE diff --git a/code/modules/surgery/amputation.dm b/code/modules/surgery/amputation.dm index e00ff66ee7..2c3524a598 100644 --- a/code/modules/surgery/amputation.dm +++ b/code/modules/surgery/amputation.dm @@ -4,10 +4,13 @@ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_HEAD) requires_bodypart_type = 0 + /datum/surgery_step/sever_limb name = "sever limb" implements = list(TOOL_SCALPEL = 100, TOOL_SAW = 100, /obj/item/melee/transforming/energy/sword/cyborg/saw = 100, /obj/item/melee/arm_blade = 80, /obj/item/chainsaw = 80, /obj/item/mounted_chainsaw = 80, /obj/item/fireaxe = 50, /obj/item/hatchet = 40, /obj/item/kitchen/knife/butcher = 25) time = 64 + preop_sound = 'sound/surgery/scalpel1.ogg' + success_sound = 'sound/surgery/organ2.ogg' /datum/surgery_step/sever_limb/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to sever [target]'s [parse_zone(target_zone)]...", diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 6f95fd0f8d..c4ab435ee0 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -9,7 +9,7 @@ icon_state = "" layer = BELOW_MOB_LAYER //so it isn't hidden behind objects when on the floor var/mob/living/carbon/owner = null - var/mob/living/carbon/original_owner = null + var/datum/weakref/original_owner = null var/status = BODYPART_ORGANIC var/needs_processing = FALSE @@ -228,6 +228,8 @@ var/mangled_state = get_mangled_state() var/bio_state = owner.get_biological_state() var/easy_dismember = HAS_TRAIT(owner, TRAIT_EASYDISMEMBER) // if we have easydismember, we don't reduce damage when redirecting damage to different types (slashing weapons on mangled/skinless limbs attack at 100% instead of 50%) + var/glass_bones = HAS_TRAIT(owner, TRAIT_GLASS_BONES) + var/paper_skin = HAS_TRAIT(owner, TRAIT_PAPER_SKIN) if(wounding_type == WOUND_BLUNT) if(sharpness == SHARP_EDGED) @@ -242,22 +244,29 @@ if(wounding_type == WOUND_SLASH) wounding_type = WOUND_BLUNT wounding_dmg *= (easy_dismember ? 1 : 0.5) + wounding_dmg *= (glass_bones ? 1.5 : 1) else if(wounding_type == WOUND_PIERCE) wounding_type = WOUND_BLUNT wounding_dmg *= (easy_dismember ? 1 : 0.75) + wounding_dmg *= (glass_bones ? 1.5 : 1) if((mangled_state & BODYPART_MANGLED_BONE) && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus)) return // if we're flesh only, all blunt attacks become weakened slashes in terms of wound damage if(BIO_JUST_FLESH) if(wounding_type == WOUND_BLUNT) wounding_type = WOUND_SLASH - wounding_dmg *= (easy_dismember ? 1 : 0.3) + wounding_dmg *= (easy_dismember ? 1 : 0.5) + wounding_dmg *= (paper_skin ? 1.5 : 1) if((mangled_state & BODYPART_MANGLED_FLESH) && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus)) return // standard humanoids if(BIO_FLESH_BONE) // if we've already mangled the skin (critical slash or piercing wound), then the bone is exposed, and we can damage it with sharp weapons at a reduced rate // So a big sharp weapon is still all you need to destroy a limb + if(wounding_type == WOUND_SLASH || wounding_type == WOUND_PIERCE) + wounding_dmg *= (paper_skin ? 1.5 : 1) + else + wounding_dmg *= (glass_bones ? 1.5 : 1) if(mangled_state == BODYPART_MANGLED_FLESH && sharpness) playsound(src, "sound/effects/wounds/crackandbleed.ogg", 100) if(wounding_type == WOUND_SLASH && !easy_dismember) @@ -388,7 +397,7 @@ for(var/i in clothing) var/obj/item/clothing/clothes_check = i // unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary - if(clothes_check.armor.getRating("wound")) + if(clothes_check.armor.getRating(WOUND)) bare_wound_bonus = 0 break @@ -447,7 +456,7 @@ for(var/c in clothing) var/obj/item/clothing/C = c // unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary - armor_ablation += C.armor.getRating("wound") + armor_ablation += C.armor.getRating(WOUND) if(wounding_type == WOUND_SLASH) C.take_damage_zone(body_zone, damage, BRUTE, armour_penetration) else if(wounding_type == WOUND_BURN && damage >= 10) // lazy way to block freezing from shredding clothes without adding another var onto apply_damage() @@ -630,8 +639,8 @@ if(source) C = source if(!original_owner) - original_owner = source - else if(original_owner && owner != original_owner) //Foreign limb + original_owner = WEAKREF(source) + else if(original_owner && !IS_WEAKREF_OF(owner, original_owner)) //Foreign limb no_update = TRUE else C = owner diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 6b5b4a14aa..96b9290239 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -142,7 +142,7 @@ update_icon_dropped() C.update_health_hud() //update the healthdoll - C.update_body() + C.update_body(FALSE, TRUE) // block recursive calls because we dont want to crash, i.e. don't tell a dullahan to update when dropping its limb C.update_hair() C.update_mobility() @@ -370,7 +370,7 @@ update_disabled() C.updatehealth() - C.update_body() + C.update_body(FALSE, TRUE) // again block recursive calls because dullahans will try update their icons by regenerating their head C.update_hair() C.update_damage_overlays() C.update_mobility() diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index 8c283f5ebc..ea43740093 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -134,7 +134,7 @@ I.pixel_y = px_y add_overlay(standing) -/obj/item/bodypart/head/get_limb_icon(dropped) +/obj/item/bodypart/head/get_limb_icon(dropped, ignore_brain = FALSE) if(custom_head) return cut_overlays() @@ -152,7 +152,7 @@ . += facial_overlay //Applies the debrained overlay if there is no brain - if(!brain) + if(!brain && !ignore_brain) var/image/debrain_overlay = image(layer = -HAIR_LAYER, dir = SOUTH) if(animal_origin == ALIEN_BODYPART) debrain_overlay.icon = 'icons/mob/animal_parts.dmi' @@ -175,12 +175,13 @@ // lipstick if(lip_style) - var/image/lips_overlay = image('icons/mob/lips.dmi', "lips_[lip_style]", -BODY_LAYER, SOUTH) + var/mutable_appearance/lips_overlay = mutable_appearance('icons/mob/lips.dmi', "lips_[lip_style]", -BODY_LAYER, SOUTH) + lips_overlay.category = "HEAD" lips_overlay.color = lip_color . += lips_overlay // eyes - if(eyes) + if(eyes || ignore_brain) var/left_state = DEFAULT_LEFT_EYE_STATE var/right_state = DEFAULT_RIGHT_EYE_STATE if(owner && owner.dna.species) @@ -189,12 +190,14 @@ left_state = eye_type + "_left_eye" right_state = eye_type + "_right_eye" if(left_state != DEFAULT_NO_EYE_STATE) - var/image/left_eye = image('icons/mob/hair.dmi', left_state, -BODY_LAYER, SOUTH) + var/mutable_appearance/left_eye = mutable_appearance('icons/mob/hair.dmi', left_state, -BODY_LAYER, SOUTH) + left_eye.category = "HEAD" if(eyes.left_eye_color) left_eye.color = "#" + eyes.left_eye_color . += left_eye if(right_state != DEFAULT_NO_EYE_STATE) - var/image/right_eye = image('icons/mob/hair.dmi', right_state, -BODY_LAYER, SOUTH) + var/mutable_appearance/right_eye = mutable_appearance('icons/mob/hair.dmi', right_state, -BODY_LAYER, SOUTH) + right_eye.category = "HEAD" if(eyes.right_eye_color) right_eye.color = "#" + eyes.right_eye_color . += right_eye diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index c2c5582f59..9be468079b 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -3,6 +3,8 @@ return /mob/living/carbon/get_bodypart(zone) + RETURN_TYPE(/obj/item/bodypart) + if(!zone) zone = BODY_ZONE_CHEST for(var/X in bodyparts) @@ -124,19 +126,25 @@ /mob/living/carbon/alien/larva/get_leg_ignore() return TRUE -/mob/living/proc/get_missing_limbs() +/mob/living/proc/get_missing_limbs(exclude_head = FALSE) return list() -/mob/living/carbon/get_missing_limbs() +/mob/living/carbon/get_missing_limbs(exclude_head = FALSE) var/list/full = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) for(var/zone in full) + if(exclude_head && zone == BODY_ZONE_HEAD) //this is needed in case we don't care for the lack of a dullahan's head or something. + full -= zone + continue if(get_bodypart(zone)) full -= zone return full -/mob/living/carbon/alien/larva/get_missing_limbs() +/mob/living/carbon/alien/larva/get_missing_limbs(exclude_head = FALSE) var/list/full = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST) for(var/zone in full) + if(exclude_head && zone == BODY_ZONE_HEAD) //I guess???? + full -= zone + continue if(get_bodypart(zone)) full -= zone return full diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm index 3a08a764d3..e66f14da93 100644 --- a/code/modules/surgery/bodyparts/parts.dm +++ b/code/modules/surgery/bodyparts/parts.dm @@ -59,13 +59,13 @@ one though." icon_state = "default_human_l_arm" attack_verb = list("slapped", "punched") - max_damage = 150 + max_damage = 50 disable_threshold = 75 max_stamina_damage = 50 body_zone = BODY_ZONE_L_ARM body_part = ARM_LEFT aux_icons = list(BODY_ZONE_PRECISE_L_HAND = HANDS_PART_LAYER, "l_hand_behind" = BODY_BEHIND_LAYER) - body_damage_coeff = 0.25 + body_damage_coeff = 0.75 held_index = 1 px_x = -6 px_y = 0 @@ -121,12 +121,12 @@ among humans missing their right arm." icon_state = "default_human_r_arm" attack_verb = list("slapped", "punched") - max_damage = 150 + max_damage = 50 disable_threshold = 75 body_zone = BODY_ZONE_R_ARM body_part = ARM_RIGHT aux_icons = list(BODY_ZONE_PRECISE_R_HAND = HANDS_PART_LAYER, "r_hand_behind" = BODY_BEHIND_LAYER) - body_damage_coeff = 0.25 + body_damage_coeff = 0.75 held_index = 2 px_x = 6 px_y = 0 @@ -184,11 +184,11 @@ luck. In this instance, it probably would not have helped." icon_state = "default_human_l_leg" attack_verb = list("kicked", "stomped") - max_damage = 150 + max_damage = 50 disable_threshold = 75 body_zone = BODY_ZONE_L_LEG body_part = LEG_LEFT - body_damage_coeff = 0.25 + body_damage_coeff = 0.75 px_x = -2 px_y = 12 stam_heal_tick = STAM_RECOVERY_LIMB @@ -243,11 +243,10 @@ // alternative spellings of 'pokey' are availible icon_state = "default_human_r_leg" attack_verb = list("kicked", "stomped") - max_damage = 150 - disable_threshold = 75 + max_damage = 50 body_zone = BODY_ZONE_R_LEG body_part = LEG_RIGHT - body_damage_coeff = 0.25 + body_damage_coeff = 0.75 px_x = 2 px_y = 12 max_stamina_damage = 50 diff --git a/code/modules/surgery/brain_surgery.dm b/code/modules/surgery/brain_surgery.dm index cf626ce7b4..e5f91c9c01 100644 --- a/code/modules/surgery/brain_surgery.dm +++ b/code/modules/surgery/brain_surgery.dm @@ -11,10 +11,15 @@ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_HEAD) requires_bodypart_type = 0 + /datum/surgery_step/fix_brain name = "fix brain" implements = list(TOOL_HEMOSTAT = 85, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15) //don't worry, pouring some alcohol on their open brain will get that chance to 100 time = 120 //long and complicated + preop_sound = 'sound/surgery/hemostat1.ogg' + success_sound = 'sound/surgery/hemostat1.ogg' + failure_sound = 'sound/surgery/organ2.ogg' + /datum/surgery/brain_surgery/can_start(mob/user, mob/living/carbon/target, obj/item/tool) var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN) if(!B || istype(B, /obj/item/organ/brain/ipc)) diff --git a/code/modules/surgery/burn_dressing.dm b/code/modules/surgery/burn_dressing.dm index 14bca66139..f704c9b414 100644 --- a/code/modules/surgery/burn_dressing.dm +++ b/code/modules/surgery/burn_dressing.dm @@ -28,6 +28,9 @@ implements = list(TOOL_HEMOSTAT = 100, TOOL_SCALPEL = 85, TOOL_SAW = 60, TOOL_WIRECUTTER = 40) time = 30 repeatable = TRUE + preop_sound = 'sound/surgery/scalpel1.ogg' + success_sound = 'sound/surgery/retractor2.ogg' + failure_sound = 'sound/surgery/organ1.ogg' /datum/surgery_step/debride/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(surgery.operated_wound) diff --git a/code/modules/surgery/cavity_implant.dm b/code/modules/surgery/cavity_implant.dm index 200e33b5f8..7cc545027c 100644 --- a/code/modules/surgery/cavity_implant.dm +++ b/code/modules/surgery/cavity_implant.dm @@ -3,6 +3,7 @@ steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/incise, /datum/surgery_step/handle_cavity, /datum/surgery_step/close) target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_CHEST) + //handle cavity /datum/surgery_step/handle_cavity name = "implant item" @@ -11,11 +12,15 @@ implements = list(/obj/item = 100) repeatable = TRUE time = 32 + preop_sound = 'sound/surgery/organ1.ogg' + success_sound = 'sound/surgery/organ2.ogg' var/obj/item/IC = null + /datum/surgery_step/handle_cavity/tool_check(mob/user, obj/item/tool) if(istype(tool, /obj/item/cautery) || istype(tool, /obj/item/gun/energy/laser)) return FALSE return !tool.get_temperature() + /datum/surgery_step/handle_cavity/preop(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) var/obj/item/bodypart/chest/CH = target.get_bodypart(BODY_ZONE_CHEST) IC = CH.cavity_item diff --git a/code/modules/surgery/coronary_bypass.dm b/code/modules/surgery/coronary_bypass.dm index 69f5062032..8880744dd4 100644 --- a/code/modules/surgery/coronary_bypass.dm +++ b/code/modules/surgery/coronary_bypass.dm @@ -12,13 +12,15 @@ return TRUE return FALSE - //an incision but with greater bleed, and a 90% base success chance /datum/surgery_step/incise_heart name = "incise heart" implements = list(TOOL_SCALPEL = 90, /obj/item/melee/transforming/energy/sword = 45, /obj/item/kitchen/knife = 45, /obj/item/shard = 25) time = 16 + preop_sound = 'sound/surgery/scalpel1.ogg' + success_sound = 'sound/surgery/scalpel2.ogg' + failure_sound = 'sound/surgery/organ2.ogg' /datum/surgery_step/incise_heart/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to make an incision in [target]'s heart...", @@ -53,6 +55,9 @@ name = "graft coronary bypass" implements = list(TOOL_HEMOSTAT = 90, TOOL_WIRECUTTER = 35, /obj/item/stack/packageWrap = 15, /obj/item/stack/cable_coil = 5) time = 90 + preop_sound = 'sound/surgery/hemostat1.ogg' + success_sound = 'sound/surgery/hemostat1.ogg' + failure_sound = 'sound/surgery/organ2.ogg' /datum/surgery_step/coronary_bypass/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to graft a bypass onto [target]'s heart...", diff --git a/code/modules/surgery/healing.dm b/code/modules/surgery/healing.dm index 52db6624e7..3d2cac05d1 100644 --- a/code/modules/surgery/healing.dm +++ b/code/modules/surgery/healing.dm @@ -32,6 +32,8 @@ implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 65, /obj/item/pen = 55) repeatable = TRUE time = 15 + success_sound = 'sound/surgery/retractor2.ogg' + failure_sound = 'sound/surgery/organ2.ogg' var/brutehealing = 0 var/burnhealing = 0 var/missinghpbonus = 0 //heals an extra point of damager per X missing damage of type (burn damage for burn healing, brute for brute). Smaller Number = More Healing! diff --git a/code/modules/surgery/implant_removal.dm b/code/modules/surgery/implant_removal.dm index 7010638004..5162fafbc0 100644 --- a/code/modules/surgery/implant_removal.dm +++ b/code/modules/surgery/implant_removal.dm @@ -3,12 +3,15 @@ steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/extract_implant, /datum/surgery_step/close) target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_CHEST) + //extract implant /datum/surgery_step/extract_implant name = "extract implant" implements = list(TOOL_HEMOSTAT = 100, TOOL_CROWBAR = 65) time = 64 + success_sound = 'sound/surgery/hemostat1.ogg' var/obj/item/implant/I = null + /datum/surgery_step/extract_implant/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) for(var/obj/item/O in target.implants) I = O @@ -48,6 +51,7 @@ else to_chat(user, "You can't find anything in [target]'s [target_zone]!") return 1 + /datum/surgery/implant_removal/mechanic name = "implant removal" requires_bodypart_type = BODYPART_ROBOTIC diff --git a/code/modules/surgery/lobectomy.dm b/code/modules/surgery/lobectomy.dm index 4b3a52f635..3117c5af9b 100644 --- a/code/modules/surgery/lobectomy.dm +++ b/code/modules/surgery/lobectomy.dm @@ -19,6 +19,9 @@ implements = list(TOOL_SCALPEL = 95, /obj/item/melee/transforming/energy/sword = 65, /obj/item/kitchen/knife = 45, /obj/item/shard = 35) time = 42 + preop_sound = 'sound/surgery/scalpel1.ogg' + success_sound = 'sound/surgery/organ1.ogg' + failure_sound = 'sound/surgery/organ2.ogg' /datum/surgery_step/lobectomy/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to make an incision in [target]'s lungs...", diff --git a/code/modules/surgery/mechanic_steps.dm b/code/modules/surgery/mechanic_steps.dm index 6f03740560..3f6887d78c 100644 --- a/code/modules/surgery/mechanic_steps.dm +++ b/code/modules/surgery/mechanic_steps.dm @@ -3,10 +3,12 @@ name = "unscrew shell" implements = list( TOOL_SCREWDRIVER = 100, - TOOL_SCALPEL = 75, // med borgs could try to unskrew shell with scalpel + TOOL_SCALPEL = 75, // med borgs could try to unscrew shell with scalpel /obj/item/kitchen/knife = 50, /obj/item = 10) // 10% success with any sharp item. time = 24 + preop_sound = 'sound/items/screwdriver.ogg' + success_sound = 'sound/items/screwdriver2.ogg' /datum/surgery_step/mechanic_open/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to unscrew the shell of [target]'s [parse_zone(target_zone)]...", @@ -16,7 +18,11 @@ /datum/surgery_step/mechanic_open/tool_check(mob/user, obj/item/tool) if(implement_type == /obj/item && !tool.get_sharpness()) return FALSE + if(tool.usesound) + preop_sound = tool.usesound + return TRUE + //close shell /datum/surgery_step/mechanic_close name = "screw shell" @@ -26,6 +32,8 @@ /obj/item/kitchen/knife = 50, /obj/item = 10) // 10% success with any sharp item. time = 24 + preop_sound = 'sound/items/screwdriver.ogg' + success_sound = 'sound/items/screwdriver2.ogg' /datum/surgery_step/mechanic_close/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to screw the shell of [target]'s [parse_zone(target_zone)]...", @@ -35,7 +43,11 @@ /datum/surgery_step/mechanic_close/tool_check(mob/user, obj/item/tool) if(implement_type == /obj/item && !tool.get_sharpness()) return FALSE + if(tool.usesound) + preop_sound = tool.usesound + return TRUE + //prepare electronics /datum/surgery_step/prepare_electronics name = "prepare electronics (multitool)" @@ -43,6 +55,8 @@ TOOL_MULTITOOL = 100, TOOL_HEMOSTAT = 10) // try to reboot internal controllers via short circuit with some conductor time = 24 + preop_sound = 'sound/items/taperecorder/tape_flip.ogg' + success_sound = 'sound/items/taperecorder/taperecorder_close.ogg' /datum/surgery_step/prepare_electronics/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to prepare electronics in [target]'s [parse_zone(target_zone)]...", @@ -56,12 +70,19 @@ TOOL_WRENCH = 100, TOOL_RETRACTOR = 10) time = 24 + preop_sound = 'sound/items/ratchet.ogg' /datum/surgery_step/mechanic_unwrench/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to unwrench some bolts in [target]'s [parse_zone(target_zone)]...", "[user] begins to unwrench some bolts in [target]'s [parse_zone(target_zone)].", "[user] begins to unwrench some bolts in [target]'s [parse_zone(target_zone)].") +/datum/surgery_step/mechanic_unwrench/tool_check(mob/user, obj/item/tool) + if(tool.usesound) + preop_sound = tool.usesound + + return TRUE + //wrench /datum/surgery_step/mechanic_wrench name = "wrench bolts" @@ -69,23 +90,38 @@ TOOL_WRENCH = 100, TOOL_RETRACTOR = 10) time = 24 + preop_sound = 'sound/items/ratchet.ogg' /datum/surgery_step/mechanic_wrench/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to wrench some bolts in [target]'s [parse_zone(target_zone)]...", "[user] begins to wrench some bolts in [target]'s [parse_zone(target_zone)].", "[user] begins to wrench some bolts in [target]'s [parse_zone(target_zone)].") +/datum/surgery_step/mechanic_wrench/tool_check(mob/user, obj/item/tool) + if(tool.usesound) + preop_sound = tool.usesound + + return TRUE + //open hatch /datum/surgery_step/open_hatch name = "open the hatch (empty hand)" accept_hand = 1 time = 10 + preop_sound = 'sound/items/ratchet.ogg' + preop_sound = 'sound/machines/doorclick.ogg' /datum/surgery_step/open_hatch/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to open the hatch holders in [target]'s [parse_zone(target_zone)]...", "[user] begins to open the hatch holders in [target]'s [parse_zone(target_zone)].", "[user] begins to open the hatch holders in [target]'s [parse_zone(target_zone)].") +/datum/surgery_step/mechanic_unwrench/tool_check(mob/user, obj/item/tool) + if(tool.usesound) + preop_sound = tool.usesound + + return TRUE + //cut wires /datum/surgery_step/cut_wires name = "cut wires" diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm index 0876357e8e..fb18d6d155 100644 --- a/code/modules/surgery/organ_manipulation.dm +++ b/code/modules/surgery/organ_manipulation.dm @@ -14,6 +14,7 @@ //there should be bone fixing /datum/surgery_step/close ) + /datum/surgery/organ_manipulation/soft possible_locs = list(BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM) steps = list( @@ -24,6 +25,7 @@ /datum/surgery_step/manipulate_organs, /datum/surgery_step/close ) + /datum/surgery/organ_manipulation/alien name = "Alien organ manipulation" possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD, BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM) @@ -36,6 +38,7 @@ /datum/surgery_step/manipulate_organs, /datum/surgery_step/close ) + /datum/surgery/organ_manipulation/mechanic name = "Prosthesis organ manipulation" possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD) @@ -49,6 +52,7 @@ /datum/surgery_step/mechanic_wrench, /datum/surgery_step/mechanic_close ) + /datum/surgery/organ_manipulation/mechanic/soft possible_locs = list(BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM) steps = list( @@ -58,20 +62,27 @@ /datum/surgery_step/manipulate_organs, /datum/surgery_step/mechanic_close ) + /datum/surgery_step/manipulate_organs time = 64 name = "manipulate organs" repeatable = 1 implements = list(/obj/item/organ = 100, /obj/item/organ_storage = 100) + preop_sound = 'sound/surgery/organ2.ogg' + success_sound = 'sound/surgery/organ1.ogg' var/implements_extract = list(TOOL_HEMOSTAT = 100, TOOL_CROWBAR = 55) var/current_type var/obj/item/organ/I = null + /datum/surgery_step/manipulate_organs/New() ..() implements = implements + implements_extract + /datum/surgery_step/manipulate_organs/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) I = null if(istype(tool, /obj/item/organ_storage)) + preop_sound = initial(preop_sound) + success_sound = initial(success_sound) if(!tool.contents.len) to_chat(user, "There is nothing inside [tool]!") return -1 @@ -82,6 +93,8 @@ tool = I if(isorgan(tool)) current_type = "insert" + preop_sound = 'sound/surgery/hemostat1.ogg' + success_sound = 'sound/surgery/organ2.ogg' I = tool if(target_zone != I.zone || target.getorganslot(I.slot)) to_chat(user, "There is no room for [I] in [target]'s [parse_zone(target_zone)]!") @@ -105,7 +118,7 @@ O.on_find(user) organs -= O organs[O.name] = O - I = input("Remove which organ?", "Surgery", null, null) as null|anything in organs + I = show_radial_menu(user, target, organs, require_near = TRUE, tooltips = TRUE) if(I && user && target && user.Adjacent(target) && user.get_active_held_item() == tool) I = organs[I] if(!I) diff --git a/code/modules/surgery/organic_steps.dm b/code/modules/surgery/organic_steps.dm index 8e893875a9..9e93042f63 100644 --- a/code/modules/surgery/organic_steps.dm +++ b/code/modules/surgery/organic_steps.dm @@ -4,6 +4,8 @@ implements = list(TOOL_SCALPEL = 100, /obj/item/melee/transforming/energy/sword = 75, /obj/item/kitchen/knife = 65, /obj/item/shard = 45, /obj/item = 30) // 30% success with any sharp item. time = 16 + preop_sound = 'sound/surgery/scalpel1.ogg' + success_sound = 'sound/surgery/scalpel2.ogg' /datum/surgery_step/incise/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to make an incision in [target]'s [parse_zone(target_zone)]...", @@ -41,6 +43,7 @@ name = "clamp bleeders" implements = list(TOOL_HEMOSTAT = 100, TOOL_WIRECUTTER = 60, /obj/item/stack/packageWrap = 35, /obj/item/stack/cable_coil = 15) time = 24 + preop_sound = 'sound/surgery/hemostat1.ogg' /datum/surgery_step/clamp_bleeders/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to clamp bleeders in [target]'s [parse_zone(target_zone)]...", @@ -56,25 +59,28 @@ if(BP) BP.generic_bleedstacks -= 3 return ..() + //retract skin /datum/surgery_step/retract_skin name = "retract skin" implements = list(TOOL_RETRACTOR = 100, TOOL_SCREWDRIVER = 45, TOOL_WIRECUTTER = 35) time = 24 + preop_sound = 'sound/surgery/retractor1.ogg' + success_sound = 'sound/surgery/retractor2.ogg' /datum/surgery_step/retract_skin/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to retract the skin in [target]'s [parse_zone(target_zone)]...", "[user] begins to retract the skin in [target]'s [parse_zone(target_zone)].", "[user] begins to retract the skin in [target]'s [parse_zone(target_zone)].") - - //close incision /datum/surgery_step/close name = "mend incision" implements = list(TOOL_CAUTERY = 100, /obj/item/gun/energy/laser = 90, TOOL_WELDER = 70, /obj/item = 30) // 30% success with any hot item. time = 24 + preop_sound = 'sound/surgery/cautery1.ogg' + success_sound = 'sound/surgery/cautery2.ogg' /datum/surgery_step/close/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to mend the incision in [target]'s [parse_zone(target_zone)]...", @@ -85,6 +91,7 @@ if(implement_type == TOOL_WELDER || implement_type == /obj/item) return tool.get_temperature() return TRUE + /datum/surgery_step/close/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(locate(/datum/surgery_step/saw) in surgery.steps) target.heal_bodypart_damage(45,0) @@ -94,11 +101,14 @@ if(BP) BP.generic_bleedstacks -= 3 return ..() + //saw bone /datum/surgery_step/saw name = "saw bone" implements = list(TOOL_SAW = 100, /obj/item/melee/arm_blade = 75, /obj/item/fireaxe = 50, /obj/item/hatchet = 35, /obj/item/kitchen/knife/butcher = 25) time = 54 + preop_sound = 'sound/surgery/saw.ogg' + success_sound = 'sound/surgery/organ2.ogg' /datum/surgery_step/saw/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You begin to saw through the bone in [target]'s [parse_zone(target_zone)]...", diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index e3c32ad009..998473abe3 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -14,7 +14,7 @@ var/obj/item/holder = null // You can use this var for item path, it would be converted into an item on New() -/obj/item/organ/cyberimp/arm/Initialize() +/obj/item/organ/cyberimp/arm/Initialize(mapload) . = ..() if(ispath(holder)) holder = new holder(src) @@ -242,7 +242,7 @@ desc = "An integrated projector mounted onto a user's arm that is able to be used as a powerful flash." contents = newlist(/obj/item/assembly/flash/armimplant) -/obj/item/organ/cyberimp/arm/flash/Initialize() +/obj/item/organ/cyberimp/arm/flash/Initialize(mapload) . = ..() if(locate(/obj/item/assembly/flash/armimplant) in items_list) var/obj/item/assembly/flash/armimplant/F = locate(/obj/item/assembly/flash/armimplant) in items_list @@ -258,7 +258,7 @@ desc = "A powerful cybernetic implant that contains combat modules built into the user's arm." contents = newlist(/obj/item/melee/transforming/energy/blade/hardlight, /obj/item/gun/medbeam, /obj/item/borg/stun, /obj/item/assembly/flash/armimplant) -/obj/item/organ/cyberimp/arm/combat/Initialize() +/obj/item/organ/cyberimp/arm/combat/Initialize(mapload) . = ..() if(locate(/obj/item/assembly/flash/armimplant) in items_list) var/obj/item/assembly/flash/armimplant/F = locate(/obj/item/assembly/flash/armimplant) in items_list @@ -326,49 +326,79 @@ desc = "An internal power cord hooked up to a battery. Useful if you run on electricity. Not so much otherwise." icon = 'icons/obj/power.dmi' icon_state = "wire1" + var/in_use = FALSE //No stacking doafters /obj/item/apc_powercord/afterattack(atom/target, mob/user, proximity_flag, click_parameters) - if(!istype(target, /obj/machinery/power/apc) || !ishuman(user) || !proximity_flag) + if((!istype(target, /obj/machinery/power/apc) && !istype(target, /obj/item/stock_parts/cell)) || !ishuman(user) || !proximity_flag) return ..() user.DelayNextAction(CLICK_CD_MELEE) - var/obj/machinery/power/apc/A = target var/mob/living/carbon/human/H = user + if(in_use) + to_chat(H, "[src] is already connected to something!") + return var/obj/item/organ/stomach/ipc/cell = locate(/obj/item/organ/stomach/ipc) in H.internal_organs if(!cell) - to_chat(H, "You try to siphon energy from the [A], but your power cell is gone!") + to_chat(H, "You try to siphon energy from [target], but your power cell is gone!") return - - if(A.cell && A.cell.charge > 0) - if(H.nutrition >= NUTRITION_LEVEL_WELL_FED) - to_chat(user, "You are already fully charged!") + if(H.nutrition >= NUTRITION_LEVEL_WELL_FED) + to_chat(user, "You are already fully charged!") + return + if(istype(target, /obj/machinery/power/apc)) + var/obj/machinery/power/apc/A = target + if(A.cell && A.cell.charge > 0) + in_use = TRUE + apc_powerdraw_loop(A, H) return - else - powerdraw_loop(A, H) + else //We only let through cells and APCs, so this has to be a cell + var/obj/item/stock_parts/cell/C = target + if(C.charge > 0) + in_use = TRUE + cell_powerdraw_loop(C, H) return - to_chat(user, "There is no charge to draw from that APC.") + to_chat(user, "There is no charge to draw from [target].") -/obj/item/apc_powercord/proc/powerdraw_loop(obj/machinery/power/apc/A, mob/living/carbon/human/H) - H.visible_message("[H] inserts a power connector into the [A].", "You begin to draw power from the [A].") +/obj/item/apc_powercord/proc/apc_powerdraw_loop(obj/machinery/power/apc/A, mob/living/carbon/human/H) + H.visible_message("[H] inserts a power connector into [A].", "You begin to draw power from [A].") while(do_after(H, 10, target = A)) if(loc != H) to_chat(H, "You must keep your connector out while charging!") break if(A.cell.charge == 0) - to_chat(H, "The [A] doesn't have enough charge to spare.") + to_chat(H, "[A] doesn't have enough charge to spare.") break A.charging = 1 if(A.cell.charge >= 500) do_sparks(1, FALSE, A) - H.nutrition += 50 - A.cell.charge -= 150 + H.adjust_nutrition(50) + A.cell.use(150) to_chat(H, "You siphon off some of the stored charge for your own use.") else - H.nutrition += A.cell.charge/10 - A.cell.charge = 0 - to_chat(H, "You siphon off as much as the [A] can spare.") + H.adjust_nutrition(A.cell.charge/10) + A.cell.use(A.cell.charge) + to_chat(H, "You siphon off as much as [A] can spare.") break if(H.nutrition > NUTRITION_LEVEL_WELL_FED) to_chat(H, "You are now fully charged.") break - H.visible_message("[H] unplugs from the [A].", "You unplug from the [A].") + in_use = FALSE + H.visible_message("[H] unplugs from [A].", "You unplug from [A].") + +/obj/item/apc_powercord/proc/cell_powerdraw_loop(obj/item/stock_parts/cell/C, mob/living/carbon/human/H) + H.visible_message("[H] connects a power cord to [C]", "You begin to draw power from [C].") + while(do_after(H, 10, target = C)) + if(loc != H) + to_chat(H, "You must keep your connector out while charging!") + break + if(C.charge == 0) + to_chat(H, "[C] doesn't have any charge remaining.") + break + var/siphoned_charge = min(C.charge, 2000) + C.use(siphoned_charge) + do_sparks(1, FALSE, C) + H.adjust_nutrition(siphoned_charge / 100) //Less efficient on a pure power basis than APC recharge. Still a very viable way of gaining nutrition. (100 nutrition / base 10k cell) + if(H.nutrition > NUTRITION_LEVEL_WELL_FED) + to_chat(H, "You are now fully charged.") + break + in_use = FALSE + H.visible_message("[H] disconnects [src] from [C].", "You disconnect from [C].") diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index e1b198ade2..420810d7d2 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -20,6 +20,10 @@ if(!. || synthesizing) return + // Check if this user can process nutriment + if(HAS_TRAIT(owner, TRAIT_NO_PROCESS_FOOD)) + return + if(owner.nutrition <= hunger_threshold) synthesizing = TRUE to_chat(owner, "You feel less hungry...") diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm index 3787d4e781..d572deca73 100644 --- a/code/modules/surgery/organs/ears.dm +++ b/code/modules/surgery/organs/ears.dm @@ -18,10 +18,9 @@ // to hear anything. var/deaf = 0 - // `ear_damage` measures long term damage to the ears, if too high, + // `damage` in this case measures long term damage to the ears, if too high, // the person will not have either `deaf` or `ear_damage` decrease // without external aid (earmuffs, drugs) - var/ear_damage = 0 //Resistance against loud noises var/bang_protect = 0 @@ -44,16 +43,22 @@ /obj/item/organ/ears/proc/restoreEars() deaf = 0 - ear_damage = 0 + damage = 0 + prev_damage = 0 organ_flags &= ~ORGAN_FAILING var/mob/living/carbon/C = owner if(iscarbon(owner) && HAS_TRAIT(C, TRAIT_DEAF)) deaf = 1 + var/mess = check_damage_thresholds() + if(mess && owner) + to_chat(owner, mess) /obj/item/organ/ears/proc/adjustEarDamage(ddmg, ddeaf) - ear_damage = max(ear_damage + (ddmg*damage_multiplier), 0) + if(owner.status_flags & GODMODE) + return + setOrganDamage(max(damage + (ddmg*damage_multiplier), 0)) deaf = max(deaf + (ddeaf*damage_multiplier), 0) /obj/item/organ/ears/proc/minimumDeafTicks(value) @@ -148,14 +153,14 @@ return to_chat(owner, "Alert: Auditory systems corrupted!.") switch(severity) - if(1) - owner.Jitter(30) - owner.Dizzy(30) - owner.DefaultCombatKnockdown(80) - deaf = 30 - - if(2) + if(1 to 50) owner.Jitter(15) owner.Dizzy(15) owner.DefaultCombatKnockdown(40) + + if(50 to INFINITY) + owner.Jitter(30) + owner.Dizzy(30) + owner.DefaultCombatKnockdown(80) + deaf = max(deaf, 30) damage += 0.15 * severity diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 9861a1b639..526285f60d 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -41,7 +41,7 @@ return switch(eye_damaged) if(BLURRY_VISION_ONE, BLURRY_VISION_TWO) - owner.overlay_fullscreen("eye_damage", /atom/movable/screen/fullscreen/impaired, eye_damaged) + owner.overlay_fullscreen("eye_damage", /atom/movable/screen/fullscreen/scaled/impaired, eye_damaged) if(BLIND_VISION_THREE) owner.become_blind(EYE_DAMAGE) if(ishuman(owner)) @@ -106,7 +106,7 @@ else if(eye_damaged == BLIND_VISION_THREE) owner.become_blind(EYE_DAMAGE) if(eye_damaged && eye_damaged != BLIND_VISION_THREE) - owner.overlay_fullscreen("eye_damage", /atom/movable/screen/fullscreen/impaired, eye_damaged) + owner.overlay_fullscreen("eye_damage", /atom/movable/screen/fullscreen/scaled/impaired, eye_damaged) else owner.clear_fullscreen("eye_damage") @@ -246,7 +246,7 @@ var/obj/effect/abstract/eye_lighting/on_mob var/image/mob_overlay -/obj/item/organ/eyes/robotic/glow/Initialize() +/obj/item/organ/eyes/robotic/glow/Initialize(mapload) . = ..() mob_overlay = image('icons/mob/human_face.dmi', "eyes_glow_gs") @@ -407,7 +407,7 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT var/obj/item/organ/eyes/robotic/glow/parent -/obj/effect/abstract/eye_lighting/Initialize() +/obj/effect/abstract/eye_lighting/Initialize(mapload) . = ..() parent = loc if(!istype(parent)) diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 93f88192e5..058de79d04 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -54,7 +54,8 @@ var/SA_para_min = 1 //nitrous values var/SA_sleep_min = 5 - var/BZ_trip_balls_min = 1 //BZ gas + var/BZ_trip_balls_min = 0.1 //BZ gas + var/BZ_brain_damage_min = 1 var/gas_stimulation_min = 0.002 //Nitryl and Stimulum var/cold_message = "your face freezing and an icicle forming" @@ -75,6 +76,8 @@ var/heat_level_3_damage = HEAT_GAS_DAMAGE_LEVEL_3 var/heat_damage_type = BURN + var/smell_sensitivity = 1 + var/crit_stabilizing_reagent = /datum/reagent/medicine/epinephrine /obj/item/organ/lungs/New() @@ -89,6 +92,11 @@ max = safe_breath_dam_max, damage_type = safe_damage_type ) + if(ispath(breathing_class)) + var/datum/breathing_class/class = GLOB.gas_data.breathing_classes[breathing_class] + for(var/g in class.gases) + if(class.gases[g] > 0) + gas_min -= g //TODO: lung health affects lung function /obj/item/organ/lungs/onDamage(damage_mod) //damage might be too low atm. @@ -195,9 +203,9 @@ mole_adjustments[entry] = -required_moles mole_adjustments[breath_results[entry]] = required_moles if(required_pp < safe_min) - var/multiplier = 0 + var/multiplier = handle_too_little_breath(H, required_pp, safe_min, required_moles) if(required_moles > 0) - multiplier = handle_too_little_breath(H, required_pp, safe_min, required_moles) / required_moles + multiplier /= required_moles for(var/adjustment in mole_adjustments) mole_adjustments[adjustment] *= multiplier if(alert_category) @@ -217,12 +225,10 @@ var/alert_type = null if(ispath(breathing_class)) breathing_class = breathing_classes[breathing_class] - var/list/gases = breathing_class.gases alert_category = breathing_class.high_alert_category alert_type = breathing_class.high_alert_datum danger_reagent = breathing_class.danger_reagent - for(var/gas in gases) - found_pp += PP(breath, gas) + found_pp = breathing_class.get_effective_pp(breath) else danger_reagent = danger_reagents[entry] if(entry in breath_alert_info) @@ -241,12 +247,16 @@ else if(alert_category) H.clear_alert(alert_category) var/list/breath_reagents = GLOB.gas_data.breath_reagents + var/static/datum/reagents/reagents_holder = new + reagents_holder.clear_reagents() + reagents_holder.chem_temp = breath.return_temperature() for(var/gas in breath.get_gases()) if(gas in breath_reagents) var/datum/reagent/R = breath_reagents[gas] - H.reagents.add_reagent(R, PP(breath,gas)) + reagents_holder.add_reagent(R, breath.get_moles(gas) * initial(R.molarity)) mole_adjustments[gas] = (gas in mole_adjustments) ? mole_adjustments[gas] - breath.get_moles(gas) : -breath.get_moles(gas) - + reagents_holder.reaction(H, VAPOR, from_gas = 1) + H.smell(breath) for(var/gas in mole_adjustments) breath.adjust_moles(gas, mole_adjustments[gas]) @@ -269,13 +279,13 @@ // BZ var/bz_pp = PP(breath, GAS_BZ) - if(bz_pp > BZ_trip_balls_min) + if(bz_pp > BZ_brain_damage_min) H.hallucination += 10 H.reagents.add_reagent(/datum/reagent/bz_metabolites,5) if(prob(33)) H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3, 150) - else if(bz_pp > 0.01) + else if(bz_pp > BZ_trip_balls_min) H.hallucination += 5 H.reagents.add_reagent(/datum/reagent/bz_metabolites,1) @@ -290,7 +300,7 @@ to_chat(H, "Your throat closes up!") H.silent = max(H.silent, 3) else - H.adjustFireLoss(nitryl_pp/4) + H.adjustFireLoss(nitryl_pp/2) gas_breathed = breath.get_moles(GAS_NITRYL) if (gas_breathed > gas_stimulation_min) H.reagents.add_reagent(/datum/reagent/nitryl,1) @@ -411,7 +421,7 @@ if(!.) return if(!failed && organ_flags & ORGAN_FAILING) - if(owner && owner.stat == CONSCIOUS) + if(owner && owner.stat == CONSCIOUS && !HAS_TRAIT(owner, TRAIT_NOBREATH)) owner.visible_message("[owner] grabs [owner.p_their()] throat, struggling for breath!", \ "You suddenly feel like you can't breathe!") failed = TRUE @@ -421,6 +431,10 @@ /obj/item/organ/lungs/ipc name = "ipc cooling system" icon_state = "lungs-c" + var/is_cooling = 0 + var/cooling_coolant_drain = 5 //Coolant (blood) use per tick of active cooling. + var/next_warn = BLOOD_VOLUME_NORMAL + actions_types = list(/datum/action/item_action/organ_action/toggle) /obj/item/organ/lungs/ipc/emp_act(severity) //Should probably put it somewhere else later . = ..() @@ -428,10 +442,64 @@ return to_chat(owner, "Alert: Critical cooling system failure!") switch(severity) - if(1) - owner.adjust_bodytemperature(100*TEMPERATURE_DAMAGE_COEFFICIENT) - if(2) + if(1 to 50) owner.adjust_bodytemperature(30*TEMPERATURE_DAMAGE_COEFFICIENT) + if(50 to INFINITY) + owner.adjust_bodytemperature(100*TEMPERATURE_DAMAGE_COEFFICIENT) + +/obj/item/organ/lungs/ipc/ui_action_click(mob/user, actiontype) + if(!owner) + return + if(!HAS_TRAIT(user, TRAIT_ROBOTIC_ORGANISM)) + to_chat(user, "Biotype incompatible with cooling system. Activation signal suppressed.") + return + if(!is_cooling && owner.blood_volume < cooling_coolant_drain) + to_chat(user, "Coolant levels insufficient to enable active cooling - Replenish immediately.") + return + + is_cooling = !is_cooling + to_chat(user, "Active cooling [is_cooling ? "enabled" : "disabled"] - current coolant level: [round(owner.blood_volume / BLOOD_VOLUME_NORMAL * 100, 0.1)] percent.") + var/possible_next_warn = owner.blood_volume - (BLOOD_VOLUME_NORMAL * 0.1) + if(possible_next_warn > next_warn) + next_warn = possible_next_warn //If we recovered blood inbetween activations, update warning + +/obj/item/organ/lungs/ipc/on_life(seconds, times_fired) + . = ..() + if(!.) + if(is_cooling) + to_chat(owner, "Cooling system safeguards triggered - active cooling aborted.") + is_cooling = 0 + return + if(!is_cooling) + return + if(!HAS_TRAIT(owner, TRAIT_ROBOTIC_ORGANISM)) + to_chat(owner, "Biotype incompatible with cooling system. Commencing emergency shutdown.") + is_cooling = 0 + return + if(owner.stat >= SOFT_CRIT) + to_chat(owner, "Operating system ping returned null response - Shutting down active cooling to avoid component damage.") + is_cooling = 0 + return + if(owner.blood_volume < cooling_coolant_drain) + to_chat(owner, "Coolant levels insufficient to maintain active cooling - Replenish immediately.") + is_cooling = 0 + return + if(abs(owner.bodytemperature - T20C) < SYNTH_ACTIVE_COOLING_TEMP_BOUNDARY) + return //Does not drain coolant (blood) nor do anything if we are close enough to room temp. + var/cooling_efficiency = owner.get_cooling_efficiency() + var/actual_drain = cooling_coolant_drain * max(1 - cooling_efficiency, 0.2) //Being in a suitable environment reduces drain by up to 80% + var/temp_diff = owner.bodytemperature - T20C + if(temp_diff > 0) + owner.adjust_bodytemperature(clamp(((T0C - owner.bodytemperature) * max(cooling_efficiency, 0.5) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX, -SYNTH_ACTIVE_COOLING_MIN_ADJUSTMENT)) + else + owner.adjust_bodytemperature(clamp(((T20C - owner.bodytemperature) * max(cooling_efficiency, 0.5) / BODYTEMP_HEAT_DIVISOR), SYNTH_ACTIVE_COOLING_MIN_ADJUSTMENT, BODYTEMP_HEATING_MAX)) + var/datum/gas_mixture/air = owner.loc.return_air() + if(!air || air.return_pressure() < ONE_ATMOSPHERE * SYNTH_ACTIVE_COOLING_LOW_PRESSURE_THRESHOLD) + actual_drain *= SYNTH_ACTIVE_COOLING_LOW_PRESSURE_PENALTY //Our cooling system can handle hot places okayish, but starts to cry at low pressures (reads: Effectively vents hot coolant thats been warmed up via internal heat-exchange as emergency measure and with very low efficiency) + owner.blood_volume = max(owner.blood_volume - actual_drain, 0) + if(owner.blood_volume <= next_warn) + to_chat(owner, "[owner.blood_volume > BLOOD_VOLUME_BAD ? "" : ""]Coolant level passed threshold - now [round(owner.blood_volume / BLOOD_VOLUME_NORMAL * 100, 0.1)] percent.") + next_warn -= (BLOOD_VOLUME_NORMAL * 0.1) /obj/item/organ/lungs/plasmaman name = "plasma filter" @@ -461,6 +529,7 @@ safe_breath_min = 13 safe_breath_max = 100 emp_vulnerability = 2 + smell_sensitivity = 1.5 /obj/item/organ/lungs/cybernetic/tier3 name = "upgraded cybernetic lungs" @@ -476,8 +545,9 @@ ) SA_para_min = 30 SA_sleep_min = 50 - BZ_trip_balls_min = 30 + BZ_brain_damage_min = 30 emp_vulnerability = 3 + smell_sensitivity = 2 cold_level_1_threshold = 200 cold_level_2_threshold = 140 @@ -509,8 +579,35 @@ heat_level_2_threshold = 600 // up 200 from level 1, 1000 is silly but w/e for level 3 /obj/item/organ/lungs/ashwalker/populate_gas_info() + // humans usually breathe 21 but require 16/17, so 80% - 1, which is more lenient but it's fine + #define SAFE_THRESHOLD_RATIO 0.8 + var/datum/gas_mixture/breath = SSair.planetary[LAVALAND_DEFAULT_ATMOS] // y'all know + if(breath.get_moles(GAS_METHANE) > 0.1) + breathing_class = BREATH_METHANE + var/pressure = breath.return_pressure() + var/total_moles = breath.total_moles() + for(var/id in breath.get_gases()) + var/this_pressure = PP(breath, id) + if(id in gas_min) + var/req_pressure = (this_pressure * SAFE_THRESHOLD_RATIO) - 1 + if(req_pressure > 0) + gas_min[id] = req_pressure + else + gas_min -= id // if there's not even enough of the gas to register, we shouldn't need it + if(id in gas_max) + gas_max[id] += this_pressure + var/bz = breath.get_moles(GAS_BZ) // snowflaked cause it's got special behavior, of course + if(bz) + BZ_trip_balls_min += bz + BZ_brain_damage_min += bz + + gas_max[GAS_N2] = max(15, PP(breath, GAS_N2) + 3) // don't want ash lizards breathing on station; sometimes they might be able to, though + var/datum/breathing_class/class = GLOB.gas_data.breathing_classes[breathing_class] + var/o2_pp = class.get_effective_pp(breath) + safe_breath_min = min(3, 0.3 * o2_pp) + safe_breath_max = max(18, 1.3 * o2_pp + 1) ..() - gas_max[GAS_N2] = 28 + #undef SAFE_THRESHOLD_RATIO /obj/item/organ/lungs/slime name = "vacuole" diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 1800fe221b..d4a2663374 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -31,7 +31,7 @@ var/useable = TRUE var/list/food_reagents = list(/datum/reagent/consumable/nutriment = 5) -/obj/item/organ/Initialize() +/obj/item/organ/Initialize(mapload) . = ..() if(organ_flags & ORGAN_EDIBLE) AddComponent(/datum/component/edible, food_reagents, null, RAW | MEAT | GROSS, null, 10, null, null, null, CALLBACK(src, .proc/OnEatFrom)) @@ -106,7 +106,7 @@ applyOrganDamage(maxHealth * decay_factor * (seconds * 0.5)) /obj/item/organ/proc/can_decay() - if(CHECK_BITFIELD(organ_flags, ORGAN_NO_SPOIL | ORGAN_SYNTHETIC | ORGAN_FAILING)) + if(organ_flags & (ORGAN_NO_SPOIL | ORGAN_SYNTHETIC | ORGAN_FAILING)) return FALSE return TRUE @@ -156,12 +156,14 @@ return FALSE if(organ_flags & ORGAN_SYNTHETIC_EMP) //Synthetic organ has been emped, is now failing. applyOrganDamage(maxHealth * decay_factor) - return + return FALSE + if(organ_flags & ORGAN_SYNTHETIC) + return TRUE if(!is_cold() && damage) ///Damage decrements by a percent of its maxhealth var/healing_amount = -(maxHealth * healing_factor) ///Damage decrements again by a percent of its maxhealth, up to a total of 4 extra times depending on the owner's satiety - healing_amount -= owner.satiety > 0 ? 4 * healing_factor * owner.satiety / MAX_SATIETY : 0 + healing_amount -= owner.satiety > 0 ? 4 * (maxHealth * healing_factor) * (owner.satiety / MAX_SATIETY) : 0 if(healing_amount) applyOrganDamage(healing_amount) //to FERMI_TWEAK return TRUE @@ -249,7 +251,7 @@ var/breathes = TRUE var/blooded = TRUE if(dna && dna.species) - if(HAS_TRAIT_FROM(src, TRAIT_NOBREATH, SPECIES_TRAIT)) + if(!HAS_TRAIT_FROM(src, TRAIT_AUXILIARY_LUNGS, SPECIES_TRAIT) && HAS_TRAIT_FROM(src, TRAIT_NOBREATH, SPECIES_TRAIT)) breathes = FALSE if(NOBLOOD in dna.species.species_traits) blooded = FALSE @@ -357,7 +359,7 @@ name = "Illegal organ" desc = "Something hecked up" -/obj/item/organ/random/Initialize() +/obj/item/organ/random/Initialize(mapload) ..() var/list = list(/obj/item/organ/tongue, /obj/item/organ/brain, /obj/item/organ/heart, /obj/item/organ/liver, /obj/item/organ/ears, /obj/item/organ/eyes, /obj/item/organ/tail, /obj/item/organ/stomach) var/newtype = pick(list) diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm index f436b31513..3b3aa72749 100644 --- a/code/modules/surgery/organs/stomach.dm +++ b/code/modules/surgery/organs/stomach.dm @@ -131,16 +131,23 @@ name = "ipc cell" icon_state = "stomach-ipc" +/obj/item/organ/stomach/ipc/on_life() + . = ..() + if(!.) + return + if(HAS_TRAIT(owner, TRAIT_ROBOTIC_ORGANISM) && owner.nutrition >= NUTRITION_LEVEL_FED) + owner.satiety += 5 //We don't need to cap the value as it's already automatically capped during nutrition level handling. Also effectively only +4 as you lose 1 per life tick. 300 seconds of sufficient charge to reach full satiety. + /obj/item/organ/stomach/ipc/emp_act(severity) . = ..() if(!owner || . & EMP_PROTECT_SELF) return switch(severity) - if(1) - owner.nutrition = min(owner.nutrition - 50, 0) + if(1 to 50) + owner.nutrition = max(owner.nutrition - 50, 0) to_chat(owner, "Alert: Detected severe battery discharge!") - if(2) - owner.nutrition = min(owner.nutrition - 100, 0) + if(50 to INFINITY) + owner.nutrition = max(owner.nutrition - 100, 0) to_chat(owner, "Alert: Minor battery discharge!") /obj/item/organ/stomach/ethereal diff --git a/code/modules/surgery/organs/tails.dm b/code/modules/surgery/organs/tails.dm index 289e9df9d4..8478ae5d27 100644 --- a/code/modules/surgery/organs/tails.dm +++ b/code/modules/surgery/organs/tails.dm @@ -13,6 +13,9 @@ owner.dna.species.stop_wagging_tail(owner) return ..() +/obj/item/organ/tail/on_life() + return + /obj/item/organ/tail/cat name = "cat tail" desc = "A severed cat tail. Who's wagging now?" diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm index 7cba3d358a..4ea1892007 100644 --- a/code/modules/surgery/organs/tongue.dm +++ b/code/modules/surgery/organs/tongue.dm @@ -15,6 +15,7 @@ var/list/accents = list() //done in order of priority (please always apply abductor accent and stuttering last) var/static/list/languages_possible_base = typecacheof(list( /datum/language/common, + /datum/language/machine, /datum/language/draconic, /datum/language/codespeak, /datum/language/monkey, @@ -26,6 +27,8 @@ /datum/language/vampiric, /datum/language/dwarf, /datum/language/signlanguage, + /datum/language/neokanji, + /datum/language/sylvan, )) healing_factor = STANDARD_ORGAN_HEALING*5 //Fast!! decay_factor = STANDARD_ORGAN_DECAY/2 @@ -140,7 +143,7 @@ icon_state = "tonguexeno" say_mod = "hisses" taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED - maxHealth = 500 //They've a little mouth for a tongue, so it's pretty rhobust + maxHealth = 500 //They've a little mouth for a tongue, so it's pretty robust initial_accents = list(/datum/accent/alien) var/static/list/languages_possible_alien = typecacheof(list( /datum/language/xenocommon, @@ -153,6 +156,13 @@ . = ..() languages_possible = languages_possible_alien +/obj/item/organ/tongue/alien/hybrid + name = "xenohybrid tongue" + +/obj/item/organ/tongue/alien/hybrid/Initialize(mapload) + . = ..() + languages_possible = languages_possible_base + /obj/item/organ/tongue/bone name = "bone \"tongue\"" desc = "Apparently skeletons alter the sounds they produce through oscillation of their teeth, hence their characteristic rattling." @@ -166,7 +176,7 @@ var/phomeme_type = "sans" var/list/phomeme_types = list(/datum/accent/span/sans, /datum/accent/span/papyrus) -/obj/item/organ/tongue/bone/Initialize() +/obj/item/organ/tongue/bone/Initialize(mapload) initial_accents += pick(phomeme_types) . = ..() @@ -246,6 +256,7 @@ taste_sensitivity = 101 // Not a tongue, they can't taste shit var/static/list/languages_possible_ethereal = typecacheof(list( /datum/language/common, + /datum/language/machine, /datum/language/draconic, /datum/language/codespeak, /datum/language/monkey, @@ -253,7 +264,8 @@ /datum/language/beachbum, /datum/language/aphasia, /datum/language/sylvan, - /datum/language/voltaic + /datum/language/voltaic, + /datum/language/neokanji, )) /obj/item/organ/tongue/ethereal/Initialize(mapload) @@ -266,6 +278,7 @@ say_mod = "chitters" var/static/list/languages_possible_arachnid = typecacheof(list( /datum/language/common, + /datum/language/machine, /datum/language/draconic, /datum/language/codespeak, /datum/language/monkey, diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 859c5c6d40..9e39ec58e8 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -68,10 +68,19 @@ var/obj/item/surgical_processor/SP = locate() in R.module.modules if(SP) advanced_surgeries |= SP.advanced_surgeries + else + var/obj/item/surgical_processor/SP + for(var/obj/item/surgical_processor/processor in user.held_items) + SP = processor + break + if(!SP) + SP = locate(/obj/item/surgical_processor) in get_turf(user) + if(SP) + advanced_surgeries |= SP.advanced_surgeries var/turf/T = get_turf(patient) var/obj/structure/table/optable/table = locate(/obj/structure/table/optable, T) - if(table?.computer && !CHECK_BITFIELD(table.computer.stat, NOPOWER|BROKEN)) + if(table?.computer && !(table.computer.stat & (NOPOWER|BROKEN))) advanced_surgeries |= table.computer.advanced_surgeries if(istype(tool, /obj/item/surgical_drapes/advanced)) @@ -123,6 +132,8 @@ if(locate(/obj/structure/table/optable, T)) propability = 1 + else if(locate(/obj/machinery/stasis)) + propability = 0.9 else if(locate(/obj/structure/table, T)) propability = 0.8 else if(locate(/obj/structure/bed, T)) @@ -147,7 +158,7 @@ icon_state = "datadisk1" custom_materials = list(/datum/material/iron=300, /datum/material/glass=100) -/obj/item/disk/surgery/debug/Initialize() +/obj/item/disk/surgery/debug/Initialize(mapload) . = ..() surgeries = list() var/list/req_tech_surgeries = subtypesof(/datum/surgery) diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm index 456d93c73b..5e037345fe 100644 --- a/code/modules/surgery/surgery_step.dm +++ b/code/modules/surgery/surgery_step.dm @@ -9,6 +9,9 @@ var/list/chems_needed = list() //list of chems needed to complete the step. Even on success, the step will have no effect if there aren't the chems required in the mob. var/require_all_chems = TRUE //any on the list or all on the list? var/silicons_obey_prob = FALSE + var/preop_sound //Sound played when the step is started + var/success_sound //Sound played if the step succeeded + var/failure_sound //Sound played if the step fails /datum/surgery_step/proc/try_op(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE) var/success = FALSE @@ -56,6 +59,9 @@ if(preop(user, target, target_zone, tool, surgery) == -1) surgery.step_in_progress = FALSE return FALSE + + play_preop_sound(user, target, target_zone, tool, surgery) // Here because most steps overwrite preop + if(tool) speed_mod = tool.toolspeed //faster tools mean faster surgeries, but also less experience. if(user.mind) @@ -69,6 +75,7 @@ if((prob(prob_chance) || (iscyborg(user) && !silicons_obey_prob)) && chem_check(target) && !try_to_fail) if(success(user, target, target_zone, tool, surgery)) + play_success_sound(user, target, target_zone, tool, surgery) var/multi = (delay/SKILL_GAIN_DELAY_DIVISOR) if(repeatable) multi *= 0.5 //Spammable surgeries award less experience. @@ -76,6 +83,7 @@ advance = TRUE else if(failure(user, target, target_zone, tool, surgery)) + play_failure_sound(user, target, target_zone, tool, surgery) advance = TRUE if(advance && !repeatable) surgery.status++ @@ -98,18 +106,33 @@ "[user] begins to perform surgery on [target].", "[user] begins to perform surgery on [target].") +/datum/surgery_step/proc/play_preop_sound(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(!preop_sound) + return + playsound(get_turf(target), preop_sound, 75, TRUE, falloff_exponent = 12, falloff_distance = 1) + /datum/surgery_step/proc/success(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You succeed.", "[user] succeeds!", "[user] finishes.") return TRUE +/datum/surgery_step/proc/play_success_sound(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(!success_sound) + return + playsound(get_turf(target), success_sound, 75, TRUE, falloff_exponent = 12, falloff_distance = 1) + /datum/surgery_step/proc/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You screw up!", "[user] screws up!", "[user] finishes.", TRUE) //By default the patient will notice if the wrong thing has been cut return FALSE +/datum/surgery_step/proc/play_failure_sound(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(!failure_sound) + return + playsound(get_turf(target), failure_sound, 75, TRUE, falloff_exponent = 12, falloff_distance = 1) + /datum/surgery_step/proc/tool_check(mob/user, obj/item/tool) return TRUE diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 0f1004221c..f916180b4c 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -3,6 +3,8 @@ desc = "Retracts stuff." icon = 'icons/obj/surgery.dmi' icon_state = "retractor" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' custom_materials = list(/datum/material/iron=6000, /datum/material/glass=3000) item_flags = SURGICAL_TOOL flags_1 = CONDUCT_1 @@ -19,7 +21,6 @@ /obj/item/retractor/advanced name = "mechanical pinches" desc = "An agglomerate of rods and gears." - icon = 'icons/obj/surgery.dmi' icon_state = "retractor_a" toolspeed = 0.7 @@ -41,18 +42,25 @@ /obj/item/retractor/augment name = "retractor" desc = "Micro-mechanical manipulator for retracting stuff." - icon = 'icons/obj/surgery.dmi' - icon_state = "retractor" custom_materials = list(/datum/material/iron=6000, /datum/material/glass=3000) flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY toolspeed = 0.5 +/obj/item/retractor/ashwalker + name = "bontractor" + desc = "Kinda looks like a chicken bone." + icon = 'icons/obj/mining.dmi' + icon_state = "retractor_bone" + toolspeed = 0.85 + /obj/item/hemostat name = "hemostat" desc = "You think you have seen this before." icon = 'icons/obj/surgery.dmi' icon_state = "hemostat" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' custom_materials = list(/datum/material/iron=5000, /datum/material/glass=2500) item_flags = SURGICAL_TOOL flags_1 = CONDUCT_1 @@ -70,19 +78,27 @@ /obj/item/hemostat/augment name = "hemostat" desc = "Tiny servos power a pair of pincers to stop bleeding." - icon = 'icons/obj/surgery.dmi' - icon_state = "hemostat" custom_materials = list(/datum/material/iron=5000, /datum/material/glass=2500) flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY toolspeed = 0.5 attack_verb = list("attacked", "pinched") +/obj/item/hemostat/ashwalker + name = "femurstat" + desc = "Bones that are strapped together with sinews. Used to stop bleeding." + icon = 'icons/obj/mining.dmi' + icon_state = "hemostat_bone" + toolspeed = 0.85 + + /obj/item/cautery name = "cautery" desc = "This stops bleeding." icon = 'icons/obj/surgery.dmi' icon_state = "cautery" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' custom_materials = list(/datum/material/iron=2500, /datum/material/glass=750) item_flags = SURGICAL_TOOL flags_1 = CONDUCT_1 @@ -90,6 +106,7 @@ attack_verb = list("burnt") tool_behaviour = TOOL_CAUTERY toolspeed = 1 + heat = 3500 /obj/item/cautery/attack(mob/living/L, mob/user) if(user.a_intent == INTENT_HELP) @@ -100,21 +117,26 @@ /obj/item/cautery/augment name = "cautery" desc = "A heated element that cauterizes wounds." - icon = 'icons/obj/surgery.dmi' - icon_state = "cautery" custom_materials = list(/datum/material/iron=2500, /datum/material/glass=750) flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY toolspeed = 0.5 attack_verb = list("burnt") +/obj/item/cautery/ashwalker + name = "coretery" + desc = "A legion core strapped to a bone. It can close wounds." + icon = 'icons/obj/mining.dmi' + icon_state = "cautery_bone" + toolspeed = 0.85 + /obj/item/surgicaldrill name = "surgical drill" desc = "You can drill using this item. You dig?" icon = 'icons/obj/surgery.dmi' icon_state = "drill" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' hitsound = 'sound/weapons/circsawhit.ogg' custom_materials = list(/datum/material/iron=10000, /datum/material/glass=6000) item_flags = SURGICAL_TOOL @@ -134,11 +156,11 @@ /obj/item/surgicaldrill/advanced name = "searing tool" desc = "It projects a high power laser used for medical application." - icon = 'icons/obj/surgery.dmi' icon_state = "surgicaldrill_a" hitsound = 'sound/items/welder.ogg' + heat = 3500 -/obj/item/surgicaldrill/advanced/Initialize() +/obj/item/surgicaldrill/advanced/Initialize(mapload) . = ..() set_light(1) @@ -160,8 +182,6 @@ /obj/item/surgicaldrill/augment name = "surgical drill" desc = "Effectively a small power drill contained within your arm, edges dulled to prevent tissue damage. May or may not pierce the heavens." - icon = 'icons/obj/surgery.dmi' - icon_state = "drill" hitsound = 'sound/weapons/circsawhit.ogg' custom_materials = list(/datum/material/iron=10000, /datum/material/glass=6000) flags_1 = CONDUCT_1 @@ -192,7 +212,7 @@ toolspeed = 1 bare_wound_bonus = 20 -/obj/item/scalpel/Initialize() +/obj/item/scalpel/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 80 * toolspeed, 100, 0) @@ -205,15 +225,15 @@ /obj/item/scalpel/advanced name = "laser scalpel" desc = "An advanced scalpel which uses laser technology to cut." - icon = 'icons/obj/surgery.dmi' icon_state = "scalpel_a" hitsound = 'sound/weapons/blade1.ogg' force = 16 toolspeed = 0.7 - light_color = LIGHT_COLOR_GREEN + light_color = LIGHT_COLOR_BLUE sharpness = SHARP_POINTY + heat = 3500 -/obj/item/scalpel/advanced/Initialize() +/obj/item/scalpel/advanced/Initialize(mapload) . = ..() set_light(1) @@ -239,8 +259,6 @@ /obj/item/scalpel/augment name = "scalpel" desc = "Ultra-sharp blade attached directly to your bone for extra-accuracy." - icon = 'icons/obj/surgery.dmi' - icon_state = "scalpel" flags_1 = CONDUCT_1 force = 10 w_class = WEIGHT_CLASS_TINY @@ -257,6 +275,14 @@ user.visible_message("[user] is slitting [user.p_their()] [pick("wrists", "throat", "stomach")] with [src]! It looks like [user.p_theyre()] trying to commit suicide!") return (BRUTELOSS) +/obj/item/scalpel/ashwalker + name = "diamond scalpel" + desc = "Bones and a Diamond tied together to make a scalpel." + icon = 'icons/obj/mining.dmi' + icon_state = "scalpel_bone" + force = 12 + toolspeed = 0.85 + /obj/item/circular_saw name = "circular saw" desc = "For heavy duty cutting." @@ -265,7 +291,7 @@ lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' hitsound = 'sound/weapons/circsawhit.ogg' - throwhitsound = 'sound/weapons/pierce.ogg' + mob_throw_hit_sound = 'sound/weapons/pierce.ogg' item_flags = SURGICAL_TOOL flags_1 = CONDUCT_1 force = 15 @@ -281,7 +307,7 @@ wound_bonus = 5 bare_wound_bonus = 10 -/obj/item/circular_saw/Initialize() +/obj/item/circular_saw/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 40 * toolspeed, 100, 5, 'sound/weapons/circsawhit.ogg') //saws are very accurate and fast at butchering @@ -294,10 +320,8 @@ /obj/item/circular_saw/augment name = "circular saw" desc = "A small but very fast spinning saw. Edges dulled to prevent accidental cutting inside of the surgeon." - icon = 'icons/obj/surgery.dmi' - icon_state = "saw" hitsound = 'sound/weapons/circsawhit.ogg' - throwhitsound = 'sound/weapons/pierce.ogg' + mob_throw_hit_sound = 'sound/weapons/pierce.ogg' flags_1 = CONDUCT_1 force = 10 w_class = WEIGHT_CLASS_SMALL @@ -309,6 +333,14 @@ attack_verb = list("attacked", "slashed", "sawed", "cut") sharpness = SHARP_EDGED +/obj/item/circular_saw/ashwalker + name = "diamond bonesaw" + desc = "Bones designed like a skull, with diamond teeth to cut through bones." + icon = 'icons/obj/mining.dmi' + icon_state = "saw_bone" + force = 12 + toolspeed = 0.85 + /obj/item/surgical_drapes name = "surgical drapes" desc = "Nanotrasen brand surgical drapes provide optimal safety and infection control." @@ -317,6 +349,16 @@ w_class = WEIGHT_CLASS_TINY attack_verb = list("slapped") +/obj/item/surgical_drapes/Initialize(mapload) + . = ..() + register_item_context() + +/obj/item/surgical_drapes/add_item_context(obj/item/source, list/context, atom/target, mob/living/user) + . = ..() + if(iscarbon(target)) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, "Prepare Surgery") + return CONTEXTUAL_SCREENTIP_SET + /obj/item/surgical_drapes/attack(mob/living/M, mob/user) if(!attempt_initiate_surgery(src, M, user)) ..() @@ -341,6 +383,13 @@ prototype = SSresearch.techweb_design_by_id(id) . |= prototype.surgery + +/obj/item/surgical_drapes/goliath + name = "goliath drapes" + desc = "Probably not the most hygienic but what the heck else are you gonna use?" + icon = 'icons/obj/mining.dmi' + icon_state = "surgical_drapes_goli" + /obj/item/organ_storage //allows medical cyborgs to manipulate organs without hands name = "organ storage bag" desc = "A container for holding body parts." @@ -417,7 +466,7 @@ name = "bonesetter" desc = "For setting things right." icon = 'icons/obj/surgery.dmi' - icon_state = "bone setter" + icon_state = "bonesetter" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' custom_materials = list(/datum/material/iron=5000, /datum/material/glass=2500) @@ -433,3 +482,10 @@ to_chat(user, "You refrain from hitting [L] with [src], as you are in help intent.") return return ..() + +/obj/item/bonesetter/bone + name = "bone bonesetter" + desc = "A bonesetter made of bones... for setting bones with... bones?" + icon = 'icons/obj/mining.dmi' + icon_state = "bone setter_bone" + toolspeed = 0.85 diff --git a/code/modules/tcg/cards.dm b/code/modules/tcg/cards.dm index f5c7c47aaf..7717a44410 100644 --- a/code/modules/tcg/cards.dm +++ b/code/modules/tcg/cards.dm @@ -353,7 +353,7 @@ material_flags = NONE sideslist = list("nanotrasen", "syndicate") -/obj/item/coin/thunderdome/Initialize() +/obj/item/coin/thunderdome/Initialize(mapload) . = ..() transform = matrix(0.5,0,0,0,0.5,0) @@ -377,7 +377,7 @@ var/static/radial_shuffle = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_shuffle") var/static/radial_pickup = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_pickup") -/obj/item/tcgcard_deck/Initialize() +/obj/item/tcgcard_deck/Initialize(mapload) . = ..() LoadComponent(/datum/component/storage/concrete/tcg) @@ -669,7 +669,7 @@ card.forceMove(src) cards.Add(card) -/obj/item/tcgcard_binder/full/Initialize() //For admemes. +/obj/item/tcgcard_binder/full/Initialize(mapload) //For admemes. . = ..() for(var/cardtype in subtypesof(/datum/tcg_card)) var/obj/item/tcg_card/card = new(get_turf(src), cardtype) diff --git a/code/modules/tcg/pack_nuclear.dm b/code/modules/tcg/pack_nuclear.dm index 96ec174a4b..cb82c98571 100644 --- a/code/modules/tcg/pack_nuclear.dm +++ b/code/modules/tcg/pack_nuclear.dm @@ -59,7 +59,7 @@ /datum/tcg_card/pack_nuclear/l6saw name = "L6 Saw LMG" - desc = "A heavily modified 1.95x129mm light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the receiver below the designation." + desc = "A heavily modified 7.12x82mm light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the receiver below the designation." rules = "After equipped unit dies, this card goes to the bottom of draw deck" icon_state = "l6saw" diff --git a/code/modules/tgchat/to_chat.dm b/code/modules/tgchat/to_chat.dm index 3030ec7fe9..c0e27a2ba3 100644 --- a/code/modules/tgchat/to_chat.dm +++ b/code/modules/tgchat/to_chat.dm @@ -7,18 +7,28 @@ * Circumvents the message queue and sends the message * to the recipient (target) as soon as possible. */ -/proc/to_chat_immediate(target, html, - type = null, - text = null, - avoid_highlighting = FALSE, - // FIXME: These flags are now pointless and have no effect - handle_whitespace = TRUE, - trailing_newline = TRUE, - confidential = FALSE) - if(!target || (!html && !text)) +/proc/to_chat_immediate( + target, + html, + type = null, + text = null, + avoid_highlighting = FALSE, + // FIXME: These flags are now pointless and have no effect + handle_whitespace = TRUE, + trailing_newline = TRUE, + confidential = FALSE +) + // Useful where the integer 0 is the entire message. Use case is enabling to_chat(target, some_boolean) while preventing to_chat(target, "") + html = "[html]" + text = "[text]" + + if(!target) return + if(!html && !text) + CRASH("Empty or null string in to_chat proc call.") if(target == world) target = GLOB.clients + // Build a message var/message = list() if(type) message["type"] = type @@ -53,21 +63,32 @@ * html = "You have found [object]") * ``` */ -/proc/to_chat(target, html, - type = null, - text = null, - avoid_highlighting = FALSE, - // FIXME: These flags are now pointless and have no effect - handle_whitespace = TRUE, - trailing_newline = TRUE, - confidential = FALSE) - if(Master.current_runlevel == RUNLEVEL_INIT || !SSchat?.initialized) - to_chat_immediate(target, html, type, text) +/proc/to_chat( + target, + html, + type = null, + text = null, + avoid_highlighting = FALSE, + // FIXME: These flags are now pointless and have no effect + handle_whitespace = TRUE, + trailing_newline = TRUE, + confidential = FALSE +) + if(isnull(Master) || Master.current_runlevel == RUNLEVEL_INIT || !SSchat?.initialized) + to_chat_immediate(target, html, type, text, avoid_highlighting) return - if(!target || (!html && !text)) + + // Useful where the integer 0 is the entire message. Use case is enabling to_chat(target, some_boolean) while preventing to_chat(target, "") + html = "[html]" + text = "[text]" + + if(!target) return + if(!html && !text) + CRASH("Empty or null string in to_chat proc call.") if(target == world) target = GLOB.clients + // Build a message var/message = list() if(type) message["type"] = type diff --git a/code/modules/tgui/external.dm b/code/modules/tgui/external.dm index 565c595473..69888bd641 100644 --- a/code/modules/tgui/external.dm +++ b/code/modules/tgui/external.dm @@ -74,7 +74,8 @@ * return bool If the user's input has been handled and the UI should update. */ /datum/proc/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) - // SHOULD_CALL_PARENT(TRUE) + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_UI_ACT, usr, action) // If UI is not interactive or usr calling Topic is not the UI user, bail. if(!ui || ui.status != UI_INTERACTIVE) return TRUE @@ -145,6 +146,7 @@ * client/verb/uiclose(), which closes the ui window */ /datum/proc/ui_close(mob/user) + SIGNAL_HANDLER /** * verb diff --git a/code/modules/tgui/states/fun.dm b/code/modules/tgui/states/fun.dm new file mode 100644 index 0000000000..ba72f40fd0 --- /dev/null +++ b/code/modules/tgui/states/fun.dm @@ -0,0 +1,17 @@ +/*! + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + +/** + * tgui state: fun_state + * + * Checks that the user has the fun privilige. + */ + +GLOBAL_DATUM_INIT(fun_state, /datum/ui_state/fun_state, new) + +/datum/ui_state/fun_state/can_use_topic(src_object, mob/user) + if(check_rights_for(user.client, R_FUN)) + return UI_INTERACTIVE + return UI_CLOSE diff --git a/code/modules/tgui/status_composers.dm b/code/modules/tgui/status_composers.dm new file mode 100644 index 0000000000..5a8ef843d7 --- /dev/null +++ b/code/modules/tgui/status_composers.dm @@ -0,0 +1,111 @@ +/// The sane defaults for a UI such as a computer or a machine. +/proc/default_ui_state(mob/user, atom/source) + return min( + ui_status_user_is_abled(user, source), + ui_status_user_has_free_hands(user, source), + ui_status_user_is_advanced_tool_user(user), + ui_status_only_living(user), + max( + ui_status_user_is_adjacent(user, source), + ui_status_silicon_has_access(user, source), + ) + ) + +/// Returns a UI status such that users adjacent to source will be able to interact, +/// far away users will be able to see, and anyone farther won't see anything. +/// Dead users will receive updates no matter what, though you likely want to add +/// a [`ui_status_only_living`] check for finer observer interactions. +/proc/ui_status_user_is_adjacent(mob/user, atom/source) + if (isliving(user)) + var/mob/living/living_user = user + return living_user.shared_living_ui_distance(source) + else + return UI_UPDATE + +/// Returns a UI status such that the dead will be able to watch, but not interact. +/proc/ui_status_only_living(mob/user, source) + if (isliving(user)) + return UI_INTERACTIVE + + if(isobserver(user)) + // If they turn on ghost AI control, admins can always interact. + if(IsAdminGhost(user)) + return UI_INTERACTIVE + + // Regular ghosts can always at least view if in range. + var/datum/client_interface/client = GET_CLIENT(user) + if(client) + var/clientviewlist = getviewsize(client.view) + if(get_dist(source, user) < max(clientviewlist[1], clientviewlist[2])) + return UI_UPDATE + + return UI_CLOSE + +/// Returns a UI status such that users with debilitating conditions, such as +/// being dead or not having power for silicons, will not be able to interact. +/// Being dead will disable UI, being incapacitated will continue updating it, +/// and anything else will make it interactive. +/proc/ui_status_user_is_abled(mob/user, atom/source) + return user.shared_ui_interaction(source) + +/// Returns a UI status such that those without blocked hands will be able to interact, +/// but everyone else can only watch. +/proc/ui_status_user_has_free_hands(mob/user, atom/source) + return (!user.restrained(TRUE) && user.get_num_arms() && user.get_empty_held_indexes()) ? UI_UPDATE : UI_INTERACTIVE +/// Returns a UI status such that advanced tool users will be able to interact, +/// but everyone else can only watch. +/proc/ui_status_user_is_advanced_tool_user(mob/user) + return user.IsAdvancedToolUser() ? UI_INTERACTIVE : UI_UPDATE + +/// Returns a UI status such that silicons will be able to interact with whatever +/// they would have access to if this was a machine. For example, AIs can +/// interact if there's cameras with wireless control is enabled. +/proc/ui_status_silicon_has_access(mob/user, atom/source) + if (!issilicon(user)) + return UI_CLOSE + var/mob/living/silicon/silicon_user = user + return silicon_user.get_ui_access(source) + +/// Returns a UI status representing this silicon's capability to access +/// the given source. Called by `ui_status_silicon_has_access`. +/mob/living/silicon/proc/get_ui_access(atom/source) + return UI_CLOSE + +/mob/living/silicon/robot/get_ui_access(atom/source) + // Robots can interact with anything they can see. + var/list/clientviewlist = getviewsize(client.view) + if(get_dist(src, source) <= min(clientviewlist[1],clientviewlist[2])) + return UI_INTERACTIVE + return UI_DISABLED // Otherwise they can keep the UI open. + +/mob/living/silicon/ai/get_ui_access(atom/source) + // The AI can interact with anything it can see nearby, or with cameras while wireless control is enabled. + if(!control_disabled && can_see(source)) + return UI_INTERACTIVE + return UI_CLOSE + +/mob/living/silicon/pai/get_ui_access(atom/source) + // pAIs can only use themselves and the owner's radio. + if((source == src || source == radio) && !stat) + return UI_INTERACTIVE + else + return UI_CLOSE + +/// Returns UI_INTERACTIVE if the user is conscious and lying down. +/// Returns UI_UPDATE otherwise. +/proc/ui_status_user_is_conscious_and_lying_down(mob/user) + if (!isliving(user)) + return UI_UPDATE + + var/mob/living/living_user = user + return (living_user.lying && living_user.stat == CONSCIOUS) \ + ? UI_INTERACTIVE \ + : UI_UPDATE + +/// Return UI_INTERACTIVE if the user is strictly adjacent to the target atom, whether they can see it or not. +/// Return UI_CLOSE otherwise. +/proc/ui_status_user_strictly_adjacent(mob/user, atom/target) + if(get_dist(target, user) > 1) + return UI_CLOSE + + return UI_INTERACTIVE diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index 55497b150a..943e0070a5 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -58,11 +58,16 @@ src.interface = interface if(title) src.title = title - src.state = src_object.ui_state() + src.state = src_object.ui_state(user) // Deprecated if(ui_x && ui_y) src.window_size = list(ui_x, ui_y) +/datum/tgui/Destroy() + user = null + src_object = null + return ..() + /** * public * @@ -87,7 +92,6 @@ window.initialize( fancy = user.client.prefs.tgui_fancy, inline_assets = list( - get_asset_datum(/datum/asset/simple/tgui_common), get_asset_datum(/datum/asset/simple/tgui), )) else diff --git a/code/modules/tgui/tgui_alert.dm b/code/modules/tgui/tgui_alert.dm index d144588ad9..83a26c2963 100644 --- a/code/modules/tgui/tgui_alert.dm +++ b/code/modules/tgui/tgui_alert.dm @@ -8,8 +8,9 @@ * * title - The of the alert modal, shown on the top of the TGUI window. * * buttons - The options that can be chosen by the user, each string is assigned a button on the UI. * * timeout - The timeout of the alert, after which the modal will close and qdel itself. Set to zero for no timeout. + * * autofocus - The bool that controls if this alert should grab window focus. */ -/proc/tgui_alert(mob/user, message = null, title = null, list/buttons = list("Ok"), timeout = 0) +/proc/tgui_alert(mob/user, message = null, title = null, list/buttons = list("Ok"), timeout = 0, autofocus = TRUE) if (!user) user = usr if (!istype(user)) @@ -18,7 +19,7 @@ user = client.mob else return - var/datum/tgui_modal/alert = new(user, message, title, buttons, timeout) + var/datum/tgui_modal/alert = new(user, message, title, buttons, timeout, autofocus) alert.ui_interact(user) alert.wait() if (alert) @@ -36,8 +37,9 @@ * * buttons - The options that can be chosen by the user, each string is assigned a button on the UI. * * callback - The callback to be invoked when a choice is made. * * timeout - The timeout of the alert, after which the modal will close and qdel itself. Disabled by default, can be set to seconds otherwise. + * * autofocus - The bool that controls if this alert should grab window focus. */ -/proc/tgui_alert_async(mob/user, message = null, title = null, list/buttons = list("Ok"), datum/callback/callback, timeout = 0) +/proc/tgui_alert_async(mob/user, message = null, title = null, list/buttons = list("Ok"), datum/callback/callback, timeout = 0, autofocus = TRUE) if (!user) user = usr if (!istype(user)) @@ -46,7 +48,7 @@ user = client.mob else return - var/datum/tgui_modal/async/alert = new(user, message, title, buttons, callback, timeout) + var/datum/tgui_modal/async/alert = new(user, message, title, buttons, callback, timeout, autofocus) alert.ui_interact(user) /** @@ -68,13 +70,16 @@ var/start_time /// The lifespan of the tgui_modal, after which the window will close and delete itself. var/timeout + /// The bool that controls if this modal should grab window focus + var/autofocus /// Boolean field describing if the tgui_modal was closed by the user. var/closed -/datum/tgui_modal/New(mob/user, message, title, list/buttons, timeout) +/datum/tgui_modal/New(mob/user, message, title, list/buttons, timeout, autofocus) src.title = title src.message = message src.buttons = buttons.Copy() + src.autofocus = autofocus if (timeout) src.timeout = timeout start_time = world.time @@ -110,7 +115,8 @@ . = list( "title" = title, "message" = message, - "buttons" = buttons + "buttons" = buttons, + "autofocus" = autofocus ) if(timeout) @@ -140,8 +146,8 @@ /// The callback to be invoked by the tgui_modal upon having a choice made. var/datum/callback/callback -/datum/tgui_modal/async/New(mob/user, message, title, list/buttons, callback, timeout) - ..(user, message, title, buttons, timeout) +/datum/tgui_modal/async/New(mob/user, message, title, list/buttons, callback, timeout, autofocus) + ..(user, message, title, buttons, timeout, autofocus) src.callback = callback /datum/tgui_modal/async/Destroy(force, ...) diff --git a/code/modules/tgui/tgui_input_list.dm b/code/modules/tgui/tgui_input_list.dm index 242b69a934..a02dfac5f5 100644 --- a/code/modules/tgui/tgui_input_list.dm +++ b/code/modules/tgui/tgui_input_list.dm @@ -82,6 +82,7 @@ src.message = message src.buttons = list() src.buttons_map = list() + var/list/repeat_buttons = list() // Gets rid of illegal characters var/static/regex/whitelistedWords = regex(@{"([^\u0020-\u8000]+)"}) @@ -89,6 +90,9 @@ for(var/i in buttons) var/string_key = whitelistedWords.Replace("[i]", "") + //avoids duplicated keys E.g: when areas have the same name + string_key = avoid_assoc_duplicate_keys(string_key, repeat_buttons) + src.buttons += string_key src.buttons_map[string_key] = i @@ -144,7 +148,7 @@ if("choose") if (!(params["choice"] in buttons)) return - choice = buttons_map[params["choice"]] + set_choice(buttons_map[params["choice"]]) SStgui.close_uis(src) return TRUE if("cancel") @@ -152,6 +156,9 @@ closed = TRUE return TRUE +/datum/tgui_list_input/proc/set_choice(choice) + src.choice = choice + /** * # async tgui_list_input * @@ -162,23 +169,17 @@ var/datum/callback/callback /datum/tgui_list_input/async/New(mob/user, message, title, list/buttons, callback, timeout) - ..(user, title, message, buttons, timeout) + ..(user, message, title, buttons, timeout) src.callback = callback /datum/tgui_list_input/async/Destroy(force, ...) QDEL_NULL(callback) . = ..() -/datum/tgui_list_input/async/ui_close(mob/user) +/datum/tgui_list_input/async/set_choice(choice) . = ..() - qdel(src) - -/datum/tgui_list_input/async/ui_act(action, list/params) - . = ..() - if (!. || choice == null) - return - callback.InvokeAsync(choice) - qdel(src) + if(!isnull(src.choice)) + callback?.InvokeAsync(src.choice) /datum/tgui_list_input/async/wait() return diff --git a/code/modules/tgui/tgui_window.dm b/code/modules/tgui/tgui_window.dm index ae54b2dd3f..af6b5bdc74 100644 --- a/code/modules/tgui/tgui_window.dm +++ b/code/modules/tgui/tgui_window.dm @@ -258,7 +258,7 @@ if(istype(asset, /datum/asset/spritesheet)) var/datum/asset/spritesheet/spritesheet = asset send_message("asset/stylesheet", spritesheet.css_filename()) - send_message("asset/mappings", asset.get_url_mappings()) + send_raw_message(asset.get_serialized_url_mappings()) /** * private diff --git a/code/modules/tgui_panel/external.dm b/code/modules/tgui_panel/external.dm index 89973a925d..e5b3602e86 100644 --- a/code/modules/tgui_panel/external.dm +++ b/code/modules/tgui_panel/external.dm @@ -16,8 +16,8 @@ nuke_chat() - // Failed to fix - action = alert(src, "Did that work?", "", "Yes", "No, switch to old ui") + // Failed to fix, using tgalert as fallback + action = tgalert(src, "Did that work?", "", "Yes", "No, switch to old ui") if (action == "No, switch to old ui") winset(src, "output", "on-show=&is-disabled=0&is-visible=1") winset(src, "browseroutput", "is-disabled=1;is-visible=0") diff --git a/code/modules/tgui_panel/telemetry.dm b/code/modules/tgui_panel/telemetry.dm index e1abfb1e12..98ba1f14b8 100644 --- a/code/modules/tgui_panel/telemetry.dm +++ b/code/modules/tgui_panel/telemetry.dm @@ -78,3 +78,4 @@ var/msg = "[key_name(client)] has a banned account in connection history! (Matched: [found["ckey"]], [found["address"]], [found["computer_id"]])" message_admins(msg) log_admin_private(msg) + log_suspicious_login(msg, access_log_mirror = FALSE) diff --git a/code/modules/tgui_panel/tgui_panel.dm b/code/modules/tgui_panel/tgui_panel.dm index 895333daee..7e2c8ac61f 100644 --- a/code/modules/tgui_panel/tgui_panel.dm +++ b/code/modules/tgui_panel/tgui_panel.dm @@ -43,7 +43,6 @@ initialized_at = world.time // Perform a clean initialization window.initialize(inline_assets = list( - get_asset_datum(/datum/asset/simple/tgui_common), get_asset_datum(/datum/asset/simple/tgui_panel), )) window.send_asset(get_asset_datum(/datum/asset/simple/namespaced/fontawesome)) diff --git a/code/modules/tooltip/tooltip.dm b/code/modules/tooltip/tooltip.dm index ca1b163968..01c74122bd 100644 --- a/code/modules/tooltip/tooltip.dm +++ b/code/modules/tooltip/tooltip.dm @@ -121,32 +121,34 @@ Notes: if(istype(user)) if(user.client && user.client.tooltips) user.client.tooltips.hide() + deltimer(user.client.tip_timer) //delete any in-progress timer if the mouse is moved off the item before it finishes + user.client.tip_timer = null /** - * # `get_tooltip_data()` - * * If set, will return a list for the tooltip (that will also be put together in a `Join()`) - * However, if returning `null`, falls back to default behavior, which is `examine(src)`, and it will definitely include - * images since it is the default behavior + * However, if returning `null`, the tooltip will not be shown as #14942 changed it. * * Though no tooltips will be created for atoms that have `tooltips = FALSE` */ /atom/movable/proc/get_tooltip_data() - return + return // i did not ask you to create a list, this shit is meant to be overriden /atom/movable/MouseEntered(location, control, params) . = ..() if(tooltips) - if(!QDELETED(src)) + if(!QDELETED(usr) && !QDELETED(src) && usr?.client?.prefs.enable_tips) var/list/tooltip_data = get_tooltip_data() if(length(tooltip_data)) var/examine_data = tooltip_data.Join("
    ") - openToolTip(usr, src, params, title = name, content = examine_data) + var/timedelay = max(usr.client.prefs.tip_delay * 0.01, 0.01) // I heard multiplying is faster, also runtimes from very low/negative numbers + usr.client.tip_timer = addtimer(CALLBACK(GLOBAL_PROC, .proc/openToolTip, usr, src, params, name, examine_data), timedelay, TIMER_STOPPABLE)//timer takes delay in deciseconds, but the pref is in milliseconds. multiplying by 0.01 converts it. /atom/movable/MouseExited(location, control, params) . = ..() closeToolTip(usr) /client/MouseDown(object, location, control, params) - closeToolTip(usr) . = ..() + closeToolTip(usr) + +// Break my stuff again and i'll kill you, kisses diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 7cc72ed1c1..c7f69fcaf1 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -32,47 +32,80 @@ /// Intended to be used in the manner of `TEST_FOCUS(/datum/unit_test/math)` #define TEST_FOCUS(test_path) ##test_path { focus = TRUE; } +/// Constants indicating unit test completion status +#define UNIT_TEST_PASSED 0 +#define UNIT_TEST_FAILED 1 +#define UNIT_TEST_SKIPPED 2 + +#define TEST_DEFAULT 1 +#define TEST_DEL_WORLD INFINITY + +/// A trait source when adding traits through unit tests +#define TRAIT_SOURCE_UNIT_TESTS "unit_tests" + #include "anchored_mobs.dm" #include "bespoke_id.dm" #include "binary_insert.dm" +// #include "bloody_footprints.dm" +// #include "breath.dm" // #include "card_mismatch.dm" #include "chain_pull_through_space.dm" // #include "combat.dm" #include "component_tests.dm" +// #include "connect_loc.dm" // #include "confusion.dm" +// #include "crayons.dm" +// #include "create_and_destroy.dm" +// #include "designs.dm" +#include "dynamic_ruleset_sanity.dm" +// #include "egg_glands.dm" +// #include "dynamic_ruleset_sanity.dm" // #include "emoting.dm" +// #include "food_edibility_check.dm" +// #include "greyscale_config.dm" // #include "heretic_knowledge.dm" // #include "holidays.dm" -#include "initialize_sanity.dm" +// #include "hydroponics_harvest.dm" // #include "keybinding_init.dm" #include "machine_disassembly.dm" #include "medical_wounds.dm" #include "merge_type.dm" // #include "metabolizing.dm" +// #include "ntnetwork_tests.dm" // #include "outfit_sanity.dm" // #include "pills.dm" // #include "plantgrowth_tests.dm" // #include "projectiles.dm" +// #include "rcd.dm" #include "reagent_id_typos.dm" // #include "reagent_mod_expose.dm" // #include "reagent_mod_procs.dm" #include "reagent_recipe_collisions.dm" #include "resist.dm" // #include "say.dm" +// #include "security_officer_distribution.dm" // #include "serving_tray.dm" // #include "siunit.dm" #include "spawn_humans.dm" +#include "spawn_mobs.dm" // #include "species_whitelists.dm" // #include "stomach.dm" +// #include "strippable.dm" #include "subsystem_init.dm" #include "surgeries.dm" #include "teleporters.dm" +#include "tgui_create_message.dm" #include "timer_sanity.dm" #include "unit_test.dm" +// #include "wizard.dm" /// CIT TESTS #include "character_saving.dm" +#ifdef REFERENCE_TRACKING //Don't try and parse this file if ref tracking isn't turned on. IE: don't parse ref tracking please mr linter +#include "find_reference_sanity.dm" +#endif + #undef TEST_ASSERT #undef TEST_ASSERT_EQUAL #undef TEST_ASSERT_NOTEQUAL diff --git a/code/modules/unit_tests/chain_pull_through_space.dm b/code/modules/unit_tests/chain_pull_through_space.dm index ffdd1bf7c9..10363d5aad 100644 --- a/code/modules/unit_tests/chain_pull_through_space.dm +++ b/code/modules/unit_tests/chain_pull_through_space.dm @@ -1,6 +1,6 @@ /datum/unit_test/chain_pull_through_space var/turf/open/space/space_tile - var/turf/claimed_tile + var/claimed_tile var/mob/living/carbon/human/alice var/mob/living/carbon/human/bob var/mob/living/carbon/human/charlie @@ -9,25 +9,25 @@ ..() // Create a space tile that goes to another z-level - claimed_tile = run_loc_bottom_left + claimed_tile = run_loc_floor_bottom_left.type - space_tile = new(locate(run_loc_bottom_left.x, run_loc_bottom_left.y, run_loc_bottom_left.z)) + space_tile = new(locate(run_loc_floor_bottom_left.x, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z)) space_tile.destination_x = 100 space_tile.destination_y = 100 space_tile.destination_z = 5 // Create our list of humans, all adjacent to one another - alice = new(locate(run_loc_bottom_left.x + 2, run_loc_bottom_left.y, run_loc_bottom_left.z)) + alice = new(locate(run_loc_floor_bottom_left.x + 2, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z)) alice.name = "Alice" - bob = new(locate(run_loc_bottom_left.x + 3, run_loc_bottom_left.y, run_loc_bottom_left.z)) + bob = new(locate(run_loc_floor_bottom_left.x + 3, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z)) bob.name = "Bob" - charlie = new(locate(run_loc_bottom_left.x + 4, run_loc_bottom_left.y, run_loc_bottom_left.z)) + charlie = new(locate(run_loc_floor_bottom_left.x + 4, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z)) charlie.name = "Charlie" /datum/unit_test/chain_pull_through_space/Destroy() - space_tile.copyTurf(claimed_tile) + space_tile.ChangeTurf(claimed_tile) qdel(alice) qdel(bob) qdel(charlie) @@ -40,14 +40,14 @@ bob.start_pulling(charlie) // Walk normally to the left, make sure we're still a chain - alice.Move(locate(run_loc_bottom_left.x + 1, run_loc_bottom_left.y, run_loc_bottom_left.z)) - if (bob.x != run_loc_bottom_left.x + 2) + alice.Move(locate(run_loc_floor_bottom_left.x + 1, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z)) + if (bob.x != run_loc_floor_bottom_left.x + 2) return Fail("During normal move, Bob was not at the correct x ([bob.x])") - if (charlie.x != run_loc_bottom_left.x + 3) + if (charlie.x != run_loc_floor_bottom_left.x + 3) return Fail("During normal move, Charlie was not at the correct x ([charlie.x])") // We're going through the space turf now that should teleport us - alice.Move(run_loc_bottom_left) + alice.Move(run_loc_floor_bottom_left) if (alice.z != space_tile.destination_z) return Fail("Alice did not teleport to the destination z-level. Current location: ([alice.x], [alice.y], [alice.z])") diff --git a/code/modules/unit_tests/character_saving.dm b/code/modules/unit_tests/character_saving.dm index 8d978a630d..cca17b81e4 100644 --- a/code/modules/unit_tests/character_saving.dm +++ b/code/modules/unit_tests/character_saving.dm @@ -1,18 +1,29 @@ +#define UNIT_TEST_SAVING_FLAVOR_TEXT "Space" +#define UNIT_TEST_SAVING_SILICON_FLAVOR_TEXT "Station" +#define UNIT_TEST_SAVING_OOC_NOTES "Thirteen" + /datum/unit_test/character_saving/Run() try var/datum/preferences/P = new P.load_path("test") - P.features["flavor_text"] = "Foo" - P.features["ooc_notes"] = "Bar" + P.features["flavor_text"] = UNIT_TEST_SAVING_FLAVOR_TEXT + P.features["silicon_flavor_text"] = UNIT_TEST_SAVING_SILICON_FLAVOR_TEXT + P.features["ooc_notes"] = UNIT_TEST_SAVING_OOC_NOTES P.save_character() P.load_character() - if(P.features["flavor_text"] != "Foo") + if(P.features["flavor_text"] != UNIT_TEST_SAVING_FLAVOR_TEXT) Fail("Flavor text is failing to save.") - if(P.features["ooc_notes"] != "Bar") + if(P.features["silicon_flavor_text"] != UNIT_TEST_SAVING_SILICON_FLAVOR_TEXT) + Fail("Silicon flavor text is failing to save.") + if(P.features["ooc_notes"] != UNIT_TEST_SAVING_OOC_NOTES) Fail("OOC text is failing to save.") P.save_character() P.load_character() - if(P.features["flavor_text"] != "Foo") + if((P.features["flavor_text"] != UNIT_TEST_SAVING_FLAVOR_TEXT) || (P.features["silicon_flavor_text"] != UNIT_TEST_SAVING_SILICON_FLAVOR_TEXT) || (P.features["ooc_notes"] != UNIT_TEST_SAVING_OOC_NOTES)) Fail("Repeated saving and loading possibly causing save deletion.") catch(var/exception/e) Fail("Failed to save and load character due to exception [e.file]:[e.line], [e.name]") + +#undef UNIT_TEST_SAVING_FLAVOR_TEXT +#undef UNIT_TEST_SAVING_SILICON_FLAVOR_TEXT +#undef UNIT_TEST_SAVING_OOC_NOTES diff --git a/code/modules/unit_tests/dynamic_ruleset_sanity.dm b/code/modules/unit_tests/dynamic_ruleset_sanity.dm new file mode 100644 index 0000000000..837e0b235c --- /dev/null +++ b/code/modules/unit_tests/dynamic_ruleset_sanity.dm @@ -0,0 +1,36 @@ +/// Verifies that roundstart dynamic rulesets are setup properly without external configuration. +/datum/unit_test/dynamic_roundstart_ruleset_sanity + +/datum/unit_test/dynamic_roundstart_ruleset_sanity/Run() + for (var/_ruleset in subtypesof(/datum/dynamic_ruleset/roundstart)) + var/datum/dynamic_ruleset/roundstart/ruleset = _ruleset + + var/has_scaling_cost = initial(ruleset.scaling_cost) + var/is_lone = initial(ruleset.flags) & (LONE_RULESET | HIGH_IMPACT_RULESET) + + if (has_scaling_cost && is_lone) + Fail("[ruleset] has a scaling_cost, but is also a lone/highlander ruleset.") + else if (!has_scaling_cost && !is_lone) + Fail("[ruleset] has no scaling cost, but is also not a lone/highlander ruleset.") + +/// Verifies that dynamic rulesets have unique antag_flag. +/datum/unit_test/dynamic_unique_antag_flags + +/datum/unit_test/dynamic_unique_antag_flags/Run() + var/list/known_antag_flags = list() + + for (var/datum/dynamic_ruleset/ruleset as anything in subtypesof(/datum/dynamic_ruleset)) + if (isnull(initial(ruleset.antag_datum))) + continue + + var/antag_flag = initial(ruleset.antag_flag) + + if (isnull(antag_flag)) + Fail("[ruleset] has a null antag_flag!") + continue + + if (antag_flag in known_antag_flags) + Fail("[ruleset] has a non-unique antag_flag [antag_flag] (used by [known_antag_flags[antag_flag]])!") + continue + + known_antag_flags[antag_flag] = ruleset diff --git a/code/modules/unit_tests/find_reference_sanity.dm b/code/modules/unit_tests/find_reference_sanity.dm new file mode 100644 index 0000000000..f41714f065 --- /dev/null +++ b/code/modules/unit_tests/find_reference_sanity.dm @@ -0,0 +1,111 @@ +///Used to test the completeness of the reference finder proc. +/datum/unit_test/find_reference_sanity + +/atom/movable/ref_holder + var/atom/movable/ref_test/test + var/list/test_list = list() + var/list/test_assoc_list = list() + +/atom/movable/ref_holder/Destroy() + test = null + test_list.Cut() + test_assoc_list.Cut() + return ..() + +/atom/movable/ref_test + var/atom/movable/ref_test/self_ref + +/atom/movable/ref_test/Destroy(force) + self_ref = null + return ..() + +/datum/unit_test/find_reference_sanity/Run() + var/atom/movable/ref_test/victim = allocate(/atom/movable/ref_test) + var/atom/movable/ref_holder/testbed = allocate(/atom/movable/ref_holder) + SSgarbage.should_save_refs = TRUE + + //Sanity check + victim.DoSearchVar(testbed, "Sanity Check", search_time = 1) //We increment search time to get around an optimization + TEST_ASSERT(!victim.found_refs.len, "The ref-tracking tool found a ref where none existed") + SSgarbage.should_save_refs = FALSE + +/datum/unit_test/find_reference_baseline/Run() + var/atom/movable/ref_test/victim = allocate(/atom/movable/ref_test) + var/atom/movable/ref_holder/testbed = allocate(/atom/movable/ref_holder) + SSgarbage.should_save_refs = TRUE + + //Set up for the first round of tests + testbed.test = victim + testbed.test_list += victim + testbed.test_assoc_list["baseline"] = victim + + victim.DoSearchVar(testbed, "First Run", search_time = 2) + + TEST_ASSERT(victim.found_refs["test"], "The ref-tracking tool failed to find a regular value") + TEST_ASSERT(victim.found_refs[testbed.test_list], "The ref-tracking tool failed to find a list entry") + TEST_ASSERT(victim.found_refs[testbed.test_assoc_list], "The ref-tracking tool failed to find an assoc list value") + SSgarbage.should_save_refs = FALSE + +/datum/unit_test/find_reference_exotic/Run() + var/atom/movable/ref_test/victim = allocate(/atom/movable/ref_test) + var/atom/movable/ref_holder/testbed = allocate(/atom/movable/ref_holder) + SSgarbage.should_save_refs = TRUE + + //Second round, bit harder this time + testbed.overlays += victim + testbed.vis_contents += victim + testbed.test_assoc_list[victim] = TRUE + + victim.DoSearchVar(testbed, "Second Run", search_time = 3) + + //This is another sanity check + TEST_ASSERT(!victim.found_refs[testbed.overlays], "The ref-tracking tool found an overlays entry? That shouldn't be possible") + TEST_ASSERT(victim.found_refs[testbed.vis_contents], "The ref-tracking tool failed to find a vis_contents entry") + TEST_ASSERT(victim.found_refs[testbed.test_assoc_list], "The ref-tracking tool failed to find an assoc list key") + SSgarbage.should_save_refs = FALSE + +/datum/unit_test/find_reference_esoteric/Run() + var/atom/movable/ref_test/victim = allocate(/atom/movable/ref_test) + var/atom/movable/ref_holder/testbed = allocate(/atom/movable/ref_holder) + SSgarbage.should_save_refs = TRUE + + //Let's get a bit esoteric + victim.self_ref = victim + var/list/to_find = list(victim) + testbed.test_list += list(to_find) + var/list/to_find_assoc = list(victim) + testbed.test_assoc_list["Nesting"] = to_find_assoc + + victim.DoSearchVar(victim, "Third Run Self", search_time = 4) + victim.DoSearchVar(testbed, "Third Run Testbed", search_time = 4) + TEST_ASSERT(victim.found_refs["self_ref"], "The ref-tracking tool failed to find a self reference") + TEST_ASSERT(victim.found_refs[to_find], "The ref-tracking tool failed to find a nested list entry") + TEST_ASSERT(victim.found_refs[to_find_assoc], "The ref-tracking tool failed to find a nested assoc list entry") + SSgarbage.should_save_refs = FALSE + +/datum/unit_test/find_reference_null_key_entry/Run() + var/atom/movable/ref_test/victim = allocate(/atom/movable/ref_test) + var/atom/movable/ref_holder/testbed = allocate(/atom/movable/ref_holder) + SSgarbage.should_save_refs = TRUE + + //Calm before the storm + testbed.test_assoc_list = list(null = victim) + + victim.DoSearchVar(testbed, "Fourth Run", search_time = 5) + TEST_ASSERT(testbed.test_assoc_list, "The ref-tracking tool failed to find a null key'd assoc list entry") + +/datum/unit_test/find_reference_assoc_investigation/Run() + var/atom/movable/ref_test/victim = allocate(/atom/movable/ref_test) + var/atom/movable/ref_holder/testbed = allocate(/atom/movable/ref_holder) + SSgarbage.should_save_refs = TRUE + + //Let's do some more complex assoc list investigation + var/list/to_find_in_key = list(victim) + testbed.test_assoc_list[to_find_in_key] = list("memes") + var/list/to_find_null_assoc_nested = list(victim) + testbed.test_assoc_list[null] = to_find_null_assoc_nested + + victim.DoSearchVar(testbed, "Fifth Run", search_time = 6) + TEST_ASSERT(victim.found_refs[to_find_in_key], "The ref-tracking tool failed to find a nested assoc list key") + TEST_ASSERT(victim.found_refs[to_find_null_assoc_nested], "The ref-tracking tool failed to find a null key'd nested assoc list entry") + SSgarbage.should_save_refs = FALSE diff --git a/code/modules/unit_tests/initialize_sanity.dm b/code/modules/unit_tests/initialize_sanity.dm deleted file mode 100644 index d183f530c8..0000000000 --- a/code/modules/unit_tests/initialize_sanity.dm +++ /dev/null @@ -1,11 +0,0 @@ -/datum/unit_test/initialize_sanity/Run() - if(length(SSatoms.BadInitializeCalls)) - Fail("Bad Initialize() calls detected. Please read logs.") - var/list/init_failures_to_text = list( - "[BAD_INIT_QDEL_BEFORE]" = "Qdeleted Before Initialized", - "[BAD_INIT_DIDNT_INIT]" = "Did Not Initialize", - "[BAD_INIT_SLEPT]" = "Initialize() Slept", - "[BAD_INIT_NO_HINT]" = "No Initialize() Hint Returned", - ) - for(var/failure in SSatoms.BadInitializeCalls) - log_world("[failure]: [init_failures_to_text["[SSatoms.BadInitializeCalls[failure]]"]]") // You like stacked brackets? diff --git a/code/modules/unit_tests/projectiles.dm b/code/modules/unit_tests/projectiles.dm index 53ceef01d6..f1a2391c07 100644 --- a/code/modules/unit_tests/projectiles.dm +++ b/code/modules/unit_tests/projectiles.dm @@ -1,5 +1,5 @@ /datum/unit_test/projectile_movetypes/Run() for(var/path in typesof(/obj/item/projectile)) - var/obj/projectile/projectile = path + var/obj/item/projectile/projectile = path if(initial(projectile.movement_type) & PHASING) Fail("[path] has default movement type PHASING. Piercing projectiles should be done using the projectile piercing system, not movement_types!") diff --git a/code/modules/unit_tests/reactions.dm b/code/modules/unit_tests/reactions.dm index 66d9b49099..c2b62f6fdc 100644 --- a/code/modules/unit_tests/reactions.dm +++ b/code/modules/unit_tests/reactions.dm @@ -1,6 +1,7 @@ /datum/unit_test/reactions/Run() for(var/datum/gas_reaction/G in SSair.gas_reactions) - var/test_info = G.test() - if(!test_info["success"]) - var/message = test_info["message"] - Fail("Gas reaction [G.name] is failing its unit test with the following message: [message]") + if(!G.exclude) + var/test_info = G.test() + if(!test_info["success"]) + var/message = test_info["message"] + Fail("Gas reaction [G.name] is failing its unit test with the following message: [message]") diff --git a/code/modules/unit_tests/say.dm b/code/modules/unit_tests/say.dm deleted file mode 100644 index a7df5ad624..0000000000 --- a/code/modules/unit_tests/say.dm +++ /dev/null @@ -1,23 +0,0 @@ -/// Test to verify message mods are parsed correctly -/datum/unit_test/get_message_mods - var/mob/host_mob - -/datum/unit_test/get_message_mods/Run() - host_mob = allocate(/mob/living/carbon/human) - - test("Hello", "Hello", list()) - test(";HELP", "HELP", list(MODE_HEADSET = TRUE)) - test(";%Never gonna give you up", "Never gonna give you up", list(MODE_HEADSET = TRUE, MODE_SING = TRUE)) - test(".s Gun plz", "Gun plz", list(RADIO_KEY = RADIO_KEY_SECURITY, RADIO_EXTENSION = RADIO_CHANNEL_SECURITY)) - test("...What", "...What", list()) - -/datum/unit_test/get_message_mods/proc/test(message, expected_message, list/expected_mods) - var/list/mods = list() - TEST_ASSERT_EQUAL(host_mob.get_message_mods(message, mods), expected_message, "Chopped message was not what we expected. Message: [message]") - - for (var/mod_key in mods) - TEST_ASSERT_EQUAL(mods[mod_key], expected_mods[mod_key], "The value for [mod_key] was not what we expected. Message: [message]") - expected_mods -= mod_key - - if (expected_mods.len) - Fail("Some message mods were expected, but were not returned by get_message_mods: [json_encode(expected_mods)]. Message: [message]") diff --git a/code/modules/unit_tests/spawn_humans.dm b/code/modules/unit_tests/spawn_humans.dm index 0500deae0a..1bc7ca3d8a 100644 --- a/code/modules/unit_tests/spawn_humans.dm +++ b/code/modules/unit_tests/spawn_humans.dm @@ -1,5 +1,5 @@ /datum/unit_test/spawn_humans/Run() - var/locs = block(run_loc_bottom_left, run_loc_top_right) + var/locs = block(run_loc_floor_bottom_left, run_loc_floor_top_right) for(var/I in 1 to 5) new /mob/living/carbon/human(pick(locs)) diff --git a/code/modules/unit_tests/spawn_mobs.dm b/code/modules/unit_tests/spawn_mobs.dm new file mode 100644 index 0000000000..f14d14eb43 --- /dev/null +++ b/code/modules/unit_tests/spawn_mobs.dm @@ -0,0 +1,8 @@ +///Unit test that spawns all mobs that can be spawned by golden slimes +/datum/unit_test/spawn_mobs + +/datum/unit_test/spawn_mobs/Run() + for(var/_animal in typesof(/mob/living/simple_animal)) + var/mob/living/simple_animal/animal = _animal + if (initial(animal.gold_core_spawnable) == HOSTILE_SPAWN || initial(animal.gold_core_spawnable) == FRIENDLY_SPAWN) + allocate(_animal) diff --git a/code/modules/unit_tests/teleporters.dm b/code/modules/unit_tests/teleporters.dm index 0fc9bdb082..e1b4b71e9e 100644 --- a/code/modules/unit_tests/teleporters.dm +++ b/code/modules/unit_tests/teleporters.dm @@ -1,8 +1,8 @@ /datum/unit_test/auto_teleporter_linking/Run() // Put down the teleporter machinery var/obj/machinery/teleport/hub/hub = allocate(/obj/machinery/teleport/hub) - var/obj/machinery/computer/teleporter/computer = allocate(/obj/machinery/computer/teleporter, locate(run_loc_bottom_left.x + 2, run_loc_bottom_left.y, run_loc_bottom_left.z)) - var/obj/machinery/teleport/station/station = allocate(/obj/machinery/teleport/station, locate(run_loc_bottom_left.x + 1, run_loc_bottom_left.y, run_loc_bottom_left.z)) + var/obj/machinery/computer/teleporter/computer = allocate(/obj/machinery/computer/teleporter, locate(run_loc_floor_bottom_left.x + 2, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z)) + var/obj/machinery/teleport/station/station = allocate(/obj/machinery/teleport/station, locate(run_loc_floor_bottom_left.x + 1, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z)) TEST_ASSERT_EQUAL(hub.power_station, station, "Hub didn't link to the station") TEST_ASSERT_EQUAL(station.teleporter_console, computer, "Station didn't link to the teleporter console") diff --git a/code/modules/unit_tests/tgui_create_message.dm b/code/modules/unit_tests/tgui_create_message.dm new file mode 100644 index 0000000000..4d5a4bc0a0 --- /dev/null +++ b/code/modules/unit_tests/tgui_create_message.dm @@ -0,0 +1,28 @@ +/// Test that `TGUI_CREATE_MESSAGE` is correctly implemented +/datum/unit_test/tgui_create_message + +/datum/unit_test/tgui_create_message/Run() + var/type = "something/here" + var/list/payload = list( + "name" = "Terry McTider", + "heads_caved" = 100, + "accomplishments" = list( + "nothing", + "literally nothing", + list( + "something" = "just kidding", + ), + ), + ) + + var/message = TGUI_CREATE_MESSAGE(type, payload) + + // Ensure consistent output to compare by performing a round-trip. + var/output = json_encode(json_decode(url_decode(message))) + + var/expected = json_encode(list( + "type" = type, + "payload" = payload, + )) + + TEST_ASSERT_EQUAL(expected, output, "TGUI_CREATE_MESSAGE didn't round trip properly") diff --git a/code/modules/unit_tests/unit_test.dm b/code/modules/unit_tests/unit_test.dm index 15fe6b466c..aee62b7a52 100644 --- a/code/modules/unit_tests/unit_test.dm +++ b/code/modules/unit_tests/unit_test.dm @@ -7,7 +7,7 @@ Call Fail() to fail the test (You should specify a reason) You may use /New() and /Destroy() for setup/teardown respectively -You can use the run_loc_bottom_left and run_loc_top_right to get turfs for testing +You can use the run_loc_floor_bottom_left and run_loc_floor_top_right to get turfs for testing */ @@ -19,39 +19,46 @@ GLOBAL_VAR(test_log) //Bit of metadata for the future maybe var/list/procs_tested - /// The bottom left turf of the testing zone - var/turf/run_loc_bottom_left - - /// The top right turf of the testing zone - var/turf/run_loc_top_right - - /// The type of turf to allocate for the testing zone - var/test_turf_type = /turf/open/floor/plasteel + /// The bottom left floor turf of the testing zone + var/turf/run_loc_floor_bottom_left + /// The top right floor turf of the testing zone + var/turf/run_loc_floor_top_right + ///The priority of the test, the larger it is the later it fires + var/priority = TEST_DEFAULT //internal shit var/focus = FALSE var/succeeded = TRUE var/list/allocated var/list/fail_reasons - var/static/datum/turf_reservation/turf_reservation + var/static/datum/turf_reservation/reservation + +/proc/cmp_unit_test_priority(datum/unit_test/a, datum/unit_test/b) + return initial(a.priority) - initial(b.priority) /datum/unit_test/New() - if (isnull(turf_reservation)) - turf_reservation = SSmapping.RequestBlockReservation(5, 5) + if (isnull(reservation)) + reservation = SSmapping.RequestBlockReservation(5, 5) - for (var/turf/reserved_turf in turf_reservation.reserved_turfs) - reserved_turf.ChangeTurf(test_turf_type) + for (var/turf/reserved_turf in reservation.reserved_turfs) + reserved_turf.ChangeTurf(/turf/open/floor/plasteel) allocated = new - run_loc_bottom_left = locate(turf_reservation.bottom_left_coords[1], turf_reservation.bottom_left_coords[2], turf_reservation.bottom_left_coords[3]) - run_loc_top_right = locate(turf_reservation.top_right_coords[1], turf_reservation.top_right_coords[2], turf_reservation.top_right_coords[3]) + run_loc_floor_bottom_left = locate(reservation.bottom_left_coords[1], reservation.bottom_left_coords[2], reservation.bottom_left_coords[3]) + run_loc_floor_top_right = locate(reservation.top_right_coords[1], reservation.top_right_coords[2], reservation.top_right_coords[3]) + + TEST_ASSERT(isfloorturf(run_loc_floor_bottom_left), "run_loc_floor_bottom_left was not a floor ([run_loc_floor_bottom_left])") + TEST_ASSERT(isfloorturf(run_loc_floor_top_right), "run_loc_floor_top_right was not a floor ([run_loc_floor_top_right])") /datum/unit_test/Destroy() - //clear the test area - for(var/atom/movable/AM in block(run_loc_bottom_left, run_loc_top_right)) - qdel(AM) QDEL_LIST(allocated) + // clear the test area + for (var/turf/turf in block(locate(1, 1, run_loc_floor_bottom_left.z), locate(world.maxx, world.maxy, run_loc_floor_bottom_left.z))) + for (var/content in turf.contents) + if (istype(content, /obj/effect/landmark)) + continue + qdel(content) return ..() /datum/unit_test/proc/Run() @@ -70,44 +77,64 @@ GLOBAL_VAR(test_log) /datum/unit_test/proc/allocate(type, ...) var/list/arguments = args.Copy(2) if (!arguments.len) - arguments = list(run_loc_bottom_left) + arguments = list(run_loc_floor_bottom_left) else if (arguments[1] == null) - arguments[1] = run_loc_bottom_left + arguments[1] = run_loc_floor_bottom_left var/instance = new type(arglist(arguments)) allocated += instance return instance +/proc/RunUnitTest(test_path, list/test_results) + var/datum/unit_test/test = new test_path + + GLOB.current_test = test + var/duration = REALTIMEOFDAY + + test.Run() + + duration = REALTIMEOFDAY - duration + GLOB.current_test = null + GLOB.failed_any_test |= !test.succeeded + + var/list/log_entry = list("[test.succeeded ? "PASS" : "FAIL"]: [test_path] [duration / 10]s") + var/list/fail_reasons = test.fail_reasons + + for(var/J in 1 to LAZYLEN(fail_reasons)) + log_entry += "\tREASON #[J]: [fail_reasons[J]]" + var/message = log_entry.Join("\n") + log_test(message) + + test_results[test_path] = list("status" = test.succeeded ? UNIT_TEST_PASSED : UNIT_TEST_FAILED, "message" = message, "name" = test_path) + + qdel(test) + /proc/RunUnitTests() CHECK_TICK - var/tests_to_run = subtypesof(/datum/unit_test) + var/list/tests_to_run = subtypesof(/datum/unit_test) for (var/_test_to_run in tests_to_run) var/datum/unit_test/test_to_run = _test_to_run if (initial(test_to_run.focus)) tests_to_run = list(test_to_run) break - for(var/I in tests_to_run) - var/datum/unit_test/test = new I + tests_to_run = sortTim(tests_to_run, /proc/cmp_unit_test_priority) - GLOB.current_test = test - var/duration = REALTIMEOFDAY + var/list/test_results = list() - test.Run() + for(var/unit_path in tests_to_run) + CHECK_TICK //We check tick first because the unit test we run last may be so expensive that checking tick will lock up this loop forever + RunUnitTest(unit_path, test_results) - duration = REALTIMEOFDAY - duration - GLOB.current_test = null - GLOB.failed_any_test |= !test.succeeded - - var/list/log_entry = list("[test.succeeded ? "PASS" : "FAIL"]: [I] [duration / 10]s") - var/list/fail_reasons = test.fail_reasons - - qdel(test) - - for(var/J in 1 to LAZYLEN(fail_reasons)) - log_entry += "\tREASON #[J]: [fail_reasons[J]]" - log_test(log_entry.Join("\n")) - - CHECK_TICK + var/file_name = "data/unit_tests.json" + fdel(file_name) + file(file_name) << json_encode(test_results) SSticker.force_ending = TRUE + //We have to call this manually because del_text can preceed us, and SSticker doesn't fire in the post game + SSticker.ready_for_reboot = TRUE + SSticker.standard_reboot() + +// /datum/map_template/unit_tests +// name = "Unit Tests Zone" +// mappath = "_maps/templates/unit_tests.dmm" diff --git a/code/modules/uplink/uplink_devices.dm b/code/modules/uplink/uplink_devices.dm index 9c09a7334a..54b4035acb 100644 --- a/code/modules/uplink/uplink_devices.dm +++ b/code/modules/uplink/uplink_devices.dm @@ -19,25 +19,46 @@ throw_range = 7 w_class = WEIGHT_CLASS_SMALL + /// The uplink flag for this type. + /// See [`code/__DEFINES/uplink.dm`] + var/uplink_flag = UPLINK_TRAITORS + /obj/item/uplink/Initialize(mapload, owner, tc_amount = 20) . = ..() - AddComponent(/datum/component/uplink, owner, FALSE, TRUE, null, tc_amount) + AddComponent(/datum/component/uplink, owner, FALSE, TRUE, uplink_flag, tc_amount) -/obj/item/uplink/nuclear/Initialize() +/obj/item/uplink/debug + name = "debug uplink" + +/obj/item/uplink/debug/Initialize(mapload, owner, tc_amount = 9000) . = ..() var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink) - hidden_uplink.set_gamemode(/datum/game_mode/nuclear) + hidden_uplink.name = "debug uplink" + hidden_uplink.debug = TRUE -/obj/item/uplink/nuclear_restricted/Initialize() +/obj/item/uplink/nuclear + uplink_flag = UPLINK_NUKE_OPS + +/obj/item/uplink/nuclear/debug + name = "debug nuclear uplink" + uplink_flag = UPLINK_NUKE_OPS + +/obj/item/uplink/nuclear/debug/Initialize(mapload, owner, tc_amount = 9000) + . = ..() + var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink) + hidden_uplink.name = "debug nuclear uplink" + hidden_uplink.debug = TRUE + +/obj/item/uplink/nuclear_restricted + uplink_flag = UPLINK_NUKE_OPS + +/obj/item/uplink/nuclear_restricted/Initialize(mapload) . = ..() var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink) hidden_uplink.allow_restricted = FALSE - hidden_uplink.set_gamemode(/datum/game_mode/nuclear) -/obj/item/uplink/clownop/Initialize() - . = ..() - var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink) - hidden_uplink.set_gamemode(/datum/game_mode/nuclear/clown_ops) +/obj/item/uplink/clownop + uplink_flag = UPLINK_CLOWN_OPS /obj/item/uplink/old name = "dusty radio" @@ -51,28 +72,9 @@ // Multitool uplink /obj/item/multitool/uplink/Initialize(mapload, owner, tc_amount = 20) . = ..() - AddComponent(/datum/component/uplink, owner, FALSE, TRUE, null, tc_amount) + AddComponent(/datum/component/uplink, owner, FALSE, TRUE, UPLINK_TRAITORS, tc_amount) // Pen uplink /obj/item/pen/uplink/Initialize(mapload, owner, tc_amount = 20) . = ..() - AddComponent(/datum/component/uplink, owner, TRUE, FALSE, null, tc_amount) - -/obj/item/uplink/debug - name = "debug uplink" - -/obj/item/uplink/debug/Initialize(mapload, owner, tc_amount = 9000) - . = ..() - var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink) - hidden_uplink.name = "debug uplink" - hidden_uplink.debug = TRUE - -/obj/item/uplink/nuclear/debug - name = "debug nuclear uplink" - -/obj/item/uplink/nuclear/debug/Initialize(mapload, owner, tc_amount = 9000) - . = ..() - var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink) - hidden_uplink.set_gamemode(/datum/game_mode/nuclear) - hidden_uplink.name = "debug nuclear uplink" - hidden_uplink.debug = TRUE + AddComponent(/datum/component/uplink, owner, TRUE, FALSE, UPLINK_TRAITORS, tc_amount) diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index cc676777db..e33b675921 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -1,54 +1,76 @@ -/proc/get_uplink_items(datum/game_mode/gamemode, allow_sales = TRUE, allow_restricted = TRUE, other_filter = list()) - var/list/filtered_uplink_items = GLOB.uplink_categories.Copy() // list of uplink categories without associated values. +GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) + +/proc/get_uplink_items(uplink_flag, allow_sales = TRUE, allow_restricted = TRUE) + var/list/filtered_uplink_items = list() var/list/sale_items = list() for(var/path in GLOB.uplink_items) var/datum/uplink_item/I = new path - if(I.include_modes.len) - if(!gamemode && SSticker.mode && !(SSticker.mode.type in I.include_modes)) - continue - if(gamemode && !(gamemode in I.include_modes)) - continue - if(I.exclude_modes.len) - if(!gamemode && SSticker.mode && (SSticker.mode.type in I.exclude_modes)) - continue - if(gamemode && (gamemode in I.exclude_modes)) - continue + if(!I.item) + continue + if (!(I.purchasable_from & uplink_flag)) + continue if(I.player_minimum && I.player_minimum > GLOB.joined_player_list.len) continue if (I.restricted && !allow_restricted) continue - if (I.type in other_filter) - continue - LAZYSET(filtered_uplink_items[I.category], I.name, I) + if(!filtered_uplink_items[I.category]) + filtered_uplink_items[I.category] = list() + filtered_uplink_items[I.category][I.name] = I if(I.limited_stock < 0 && !I.cant_discount && I.item && I.cost > 1) sale_items += I if(allow_sales) - for(var/i in 1 to 3) - var/datum/uplink_item/I = pick_n_take(sale_items) - var/datum/uplink_item/A = new I.type - var/discount = A.get_discount() - var/list/disclaimer = list("Void where prohibited.", "Not recommended for children.", "Contains small parts.", "Check local laws for legality in region.", "Do not taunt.", "Not responsible for direct, indirect, incidental or consequential damages resulting from any defect, error or failure to perform.", "Keep away from fire or flames.", "Product is provided \"as is\" without any implied or expressed warranties.", "As seen on TV.", "For recreational use only.", "Use only as directed.", "16% sales tax will be charged for orders originating within Space Nebraska.") - A.limited_stock = 1 - I.refundable = FALSE //THIS MAN USES ONE WEIRD TRICK TO GAIN FREE TC, CODERS HATES HIM! - A.refundable = FALSE - if(A.cost >= 20) //Tough love for nuke ops - discount *= 0.5 - A.cost = max(round(A.cost * discount),1) - A.category = "Discounted Gear" - A.name += " ([round(((initial(A.cost)-A.cost)/initial(A.cost))*100)]% off!)" - A.desc += " Normally costs [initial(A.cost)] TC. All sales final. [pick(disclaimer)]" - A.item = I.item + var/datum/team/nuclear/nuclear_team + // if (uplink_flag & UPLINK_NUKE_OPS) // uplink code kind of needs a redesign + // nuclear_team = locate() in GLOB.antagonist_teams // the team discounts could be in a GLOB with this design but it would make sense for them to be team specific... + if (!nuclear_team) + create_uplink_sales(3, "Discounted Gear", 1, sale_items, filtered_uplink_items) + else + if (!nuclear_team.team_discounts) + // create 5 unlimited stock discounts + create_uplink_sales(5, "Discounted Team Gear", -1, sale_items, filtered_uplink_items) + // Create 10 limited stock discounts + create_uplink_sales(10, "Limited Stock Team Gear", 1, sale_items, filtered_uplink_items) + nuclear_team.team_discounts = list("Discounted Team Gear" = filtered_uplink_items["Discounted Team Gear"], "Limited Stock Team Gear" = filtered_uplink_items["Limited Stock Team Gear"]) + else + for(var/cat in nuclear_team.team_discounts) + for(var/item in nuclear_team.team_discounts[cat]) + var/datum/uplink_item/D = nuclear_team.team_discounts[cat][item] + var/datum/uplink_item/O = filtered_uplink_items[initial(D.category)][initial(D.name)] + O.refundable = FALSE - LAZYSET(filtered_uplink_items[A.category], A.name, A) + filtered_uplink_items["Discounted Team Gear"] = nuclear_team.team_discounts["Discounted Team Gear"] + filtered_uplink_items["Limited Stock Team Gear"] = nuclear_team.team_discounts["Limited Stock Team Gear"] - for(var/category in filtered_uplink_items) - if(!filtered_uplink_items[category]) //empty categories with no associated uplink item. Remove. - filtered_uplink_items -= category return filtered_uplink_items +/proc/create_uplink_sales(num, category_name, limited_stock, sale_items, uplink_items) + if (num <= 0) + return + + if(!uplink_items[category_name]) + uplink_items[category_name] = list() + + for (var/i in 1 to num) + var/datum/uplink_item/I = pick_n_take(sale_items) + var/datum/uplink_item/A = new I.type + var/discount = A.get_discount() + var/list/disclaimer = list("Void where prohibited.", "Not recommended for children.", "Contains small parts.", "Check local laws for legality in region.", "Do not taunt.", "Not responsible for direct, indirect, incidental or consequential damages resulting from any defect, error or failure to perform.", "Keep away from fire or flames.", "Product is provided \"as is\" without any implied or expressed warranties.", "As seen on TV.", "For recreational use only.", "Use only as directed.", "16% sales tax will be charged for orders originating within Space Nebraska.") + A.limited_stock = limited_stock + I.refundable = FALSE //THIS MAN USES ONE WEIRD TRICK TO GAIN FREE TC, CODERS HATES HIM! + A.refundable = FALSE + if(A.cost >= 20) //Tough love for nuke ops + discount *= 0.5 + A.category = category_name + A.cost = max(round(A.cost * discount),1) + A.name += " ([round(((initial(A.cost)-A.cost)/initial(A.cost))*100)]% off!)" + A.desc += " Normally costs [initial(A.cost)] TC. All sales final. [pick(disclaimer)]" + A.item = I.item + + uplink_items[category_name][A.name] = A + /** * Uplink Items @@ -67,12 +89,14 @@ var/surplus = 100 // Chance of being included in the surplus crate. var/cant_discount = FALSE var/limited_stock = -1 //Setting this above zero limits how many times this item can be bought by the same traitor in a round, -1 is unlimited - var/list/include_modes = list() // Game modes to allow this item in. - var/list/exclude_modes = list() // Game modes to disallow this item from. + /// A bitfield to represent what uplinks can purchase this item. + /// See [`code/__DEFINES/uplink.dm`]. + var/purchasable_from = ALL var/list/restricted_roles = list() //If this uplink item is only available to certain roles. Roles are dependent on the frequency chip or stored ID. var/player_minimum //The minimum crew size needed for this item to be added to uplinks. var/purchase_log_vis = TRUE // Visible in the purchase log? var/restricted = FALSE // Adds restrictions for VR/Events + var/list/restricted_species //Limits items to a specific species. Hopefully. var/illegal_tech = TRUE // Can this item be deconstructed to unlock certain techweb research nodes? /datum/uplink_item/proc/get_discount() @@ -80,6 +104,7 @@ /datum/uplink_item/proc/purchase(mob/user, datum/component/uplink/U) var/atom/A = spawn_item(item, user, U) + // log_uplink("[key_name(user)] purchased [src] for [cost] telecrystals from [U.parent]'s uplink") if(purchase_log_vis && U.purchase_log) U.purchase_log.LogPurchase(A, src, cost) @@ -94,70 +119,66 @@ if(ishuman(user) && istype(A, /obj/item)) var/mob/living/carbon/human/H = user if(H.put_in_hands(A)) - to_chat(H, "[A] materializes into your hands!") + to_chat(H, span_boldnotice("[A] materializes into your hands!")) return A - to_chat(user, "[A] materializes onto the floor.") + to_chat(user, span_boldnotice("[A] materializes onto the floor!")) return A -/* - Uplink Categories: - Due to how the typesof() in-built byond proc works, it should be kept in mind - the order categories are displayed in the uplink UI is same to the order they are loaded in the code. - I trust no extra filter is needed as long as they are all contained within the following lines. - When adding new uplink categories, please keep them separate from their sub paths here and without set item. - Failure to comply may result in the new categories being listed at the bottom of the UI. -*/ +//Discounts (dynamically filled above) +/datum/uplink_item/discounts + category = "Discounts" +// cit specific. idk /datum/uplink_item/holiday category = "Holiday" -/datum/uplink_item/bundles_TC - category = "Telecrystals and Bundles" +//All bundles and telecrystals +/datum/uplink_item/bundles_tc + category = "Bundles" surplus = 0 cant_discount = TRUE +// Dangerous Items /datum/uplink_item/dangerous category = "Conspicuous Weapons" -/datum/uplink_item/stealthy_weapons - category = "Stealthy Weapons" - -/datum/uplink_item/ammo - category = "Ammunition" - surplus = 40 - -/datum/uplink_item/explosives - category = "Explosives" - +//Support and Mechs /datum/uplink_item/support category = "Support and Exosuits" surplus = 0 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/suits - category = "Clothing" - surplus = 40 + purchasable_from = UPLINK_NUKE_OPS +// Stealth Items /datum/uplink_item/stealthy_tools category = "Stealth Gadgets" +//Space Suits and Hardsuits +/datum/uplink_item/suits + category = "Space Suits" + surplus = 40 + +// Devices and Tools /datum/uplink_item/device_tools category = "Misc. Gadgets" +// Implants /datum/uplink_item/implants category = "Implants" surplus = 50 +//Race-specific items +/datum/uplink_item/race_restricted + category = "Species-Restricted" + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) + surplus = 0 + +// Role-specific items /datum/uplink_item/role_restricted category = "Role-Restricted" - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) surplus = 0 - cant_discount = TRUE +// Pointless /datum/uplink_item/badass category = "(Pointless) Badassery" surplus = 0 - -//Discounts (dynamically filled above) -/datum/uplink_item/discounts - category = "Discounted Gear" diff --git a/code/modules/uplink/uplink_items/uplink_ammo.dm b/code/modules/uplink/uplink_items/uplink_ammo.dm index 2ab6c6f490..1ce8b7914a 100644 --- a/code/modules/uplink/uplink_items/uplink_ammo.dm +++ b/code/modules/uplink/uplink_items/uplink_ammo.dm @@ -12,7 +12,7 @@ desc = "Contains 10 additional .45-70 GOVT rounds. Caliber is exceedingly rare, and thus, comes at a premium." item = /obj/item/ammo_box/g4570 cost = 5 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/pistol name = "10mm Handgun Magazine" @@ -20,7 +20,7 @@ are dirt cheap but are half as effective as .357 rounds." item = /obj/item/ammo_box/magazine/m10mm cost = 1 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = ~UPLINK_CLOWN_OPS /datum/uplink_item/ammo/pistol/box name = "Ammo Box - 10mm" @@ -34,7 +34,7 @@ These rounds are less effective at injuring the target but penetrate protective gear." item = /obj/item/ammo_box/magazine/m10mm/ap cost = 2 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = ~UPLINK_CLOWN_OPS /datum/uplink_item/ammo/pistolap/box name = "Ammo Box - 10mm Armour Piercing" @@ -48,7 +48,7 @@ These rounds are more damaging but ineffective against armour." item = /obj/item/ammo_box/magazine/m10mm/hp cost = 3 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = ~UPLINK_CLOWN_OPS /datum/uplink_item/ammo/pistolhp/box name = "Ammo Box - 10mm Hollow Point" @@ -62,7 +62,7 @@ Loaded with incendiary rounds which inflict little damage, but ignite the target." item = /obj/item/ammo_box/magazine/m10mm/fire cost = 2 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = ~UPLINK_CLOWN_OPS /datum/uplink_item/ammo/pistolfire/box name = "Ammo Box - 10mm Incendiary" @@ -85,7 +85,7 @@ /datum/uplink_item/ammo/shotgun cost = 2 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/shotgun/bag name = "12g Ammo Duffel Bag" @@ -136,7 +136,7 @@ For when you really need a lot of things dead." item = /obj/item/ammo_box/a357 cost = 3 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = ~UPLINK_CLOWN_OPS /datum/uplink_item/ammo/revolver/ap name = ".357 Armor Piercing Speed Loader" @@ -150,25 +150,25 @@ Your teammates will ask you to not shoot these down small hallways." item = /obj/item/ammo_casing/a40mm cost = 2 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/smg/bag name = ".45 Ammo Duffel Bag" desc = "A duffel bag filled with enough .45 ammo to supply an entire team, at a discounted price." item = /obj/item/storage/backpack/duffelbag/syndie/ammo/smg cost = 20 //instead of 27 TC - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/smg name = ".45 SMG Magazine" desc = "An additional 24-round .45 magazine suitable for use with the C-20r submachine gun." item = /obj/item/ammo_box/magazine/smgm45 cost = 3 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/sniper cost = 4 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/sniper/basic name = ".50 Magazine" @@ -194,7 +194,7 @@ These bullets pack less punch than 7.12x82mm rounds, but they still offer more power than .45 ammo." item = /obj/item/ammo_box/magazine/m556 cost = 4 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/machinegun/match name = "7.12x82mm (Match) Box Magazine" @@ -206,35 +206,35 @@ /datum/uplink_item/ammo/machinegun cost = 6 surplus = 0 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/machinegun/basic - name = "1.95x129mm Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use with the L6 SAW. \ + name = "7.12x82mm Box Magazine" + desc = "A 50-round magazine of 7.12x82mm ammunition for use with the L6 SAW. \ By the time you need to use this, you'll already be standing on a pile of corpses" - item = /obj/item/ammo_box/magazine/mm195x129 + item = /obj/item/ammo_box/magazine/mm712x82 /datum/uplink_item/ammo/machinegun/ap - name = "1.95x129mm (Armor Penetrating) Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with special properties \ + name = "7.12x82mm (Armor Penetrating) Box Magazine" + desc = "A 50-round magazine of 7.12x82mm ammunition for use in the L6 SAW; equipped with special properties \ to puncture even the most durable armor." - item = /obj/item/ammo_box/magazine/mm195x129/ap + item = /obj/item/ammo_box/magazine/mm712x82/ap cost = 9 /datum/uplink_item/ammo/machinegun/hollow - name = "1.95x129mm (Hollow-Point) Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with hollow-point tips to help \ + name = "7.12x82mm (Hollow-Point) Box Magazine" + desc = "A 50-round magazine of 7.12x82mm ammunition for use in the L6 SAW; equipped with hollow-point tips to help \ with the unarmored masses of crew." - item = /obj/item/ammo_box/magazine/mm195x129/hollow + item = /obj/item/ammo_box/magazine/mm712x82/hollow /datum/uplink_item/ammo/machinegun/incen - name = "1.95x129mm (Incendiary) Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; tipped with a special flammable \ + name = "7.12x82mm (Incendiary) Box Magazine" + desc = "A 50-round magazine of 7.12x82mm ammunition for use in the L6 SAW; tipped with a special flammable \ mixture that'll ignite anyone struck by the bullet. Some men just want to watch the world burn." - item = /obj/item/ammo_box/magazine/mm195x129/incen + item = /obj/item/ammo_box/magazine/mm712x82/incen /datum/uplink_item/ammo/rocket - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/rocket/basic name = "84mm HE Rocket" @@ -254,7 +254,7 @@ desc = "An additional 15-round 9mm magazine, compatible with the Stechkin APS pistol, found in the Spetsnaz Pyro bundle." item = /obj/item/ammo_box/magazine/pistolm9mm cost = 2 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/pistolaps name = "Ammo Box - 9mm" @@ -265,10 +265,10 @@ /datum/uplink_item/ammo/flechetteap name = "Armor Piercing Flechette Magazine" desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \ - Loaded with armor piercing flechettes that very nearly ignore armor, but are not very effective agaisnt flesh." + Loaded with armor piercing flechettes that very nearly ignore armor, but are not very effective against flesh." item = /obj/item/ammo_box/magazine/flechette cost = 2 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/flechettes name = "Serrated Flechette Magazine" @@ -277,7 +277,7 @@ These flechettes are highly likely to sever arteries, and even limbs." item = /obj/item/ammo_box/magazine/flechette/s cost = 2 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/toydarts name = "Box of Riot Darts" @@ -293,32 +293,32 @@ and broca systems, making it impossible for them to move or speak for some time." item = /obj/item/storage/box/syndie_kit/bioterror cost = 6 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/ammo/bolt_action name = "Surplus Rifle Clip" desc = "A stripper clip used to quickly load bolt action rifles. Contains 5 rounds." item = /obj/item/ammo_box/a762 cost = 1 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/bolt_action_bulk name = "Surplus Rifle Clip Box" desc = "An ammo box we found in a warehouse, holding 7 clips of 5 rounds for bolt-action rifles. Yes, the cheap ones." item = /obj/item/storage/toolbox/ammo cost = 4 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/dark_gygax/bag name = "Dark Gygax Ammo Bag" desc = "A duffel bag containing ammo for three full reloads of the incendiary carbine and flash bang launcher that are equipped on a standard Dark Gygax exosuit." item = /obj/item/storage/backpack/duffelbag/syndie/ammo/dark_gygax cost = 4 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/ammo/mauler/bag name = "Mauler Ammo Bag" desc = "A duffel bag containing ammo for three full reloads of the LMG, scattershot carbine, and SRM-8 missile laucher that are equipped on a standard Mauler exosuit." item = /obj/item/storage/backpack/duffelbag/syndie/ammo/mauler cost = 6 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS diff --git a/code/modules/uplink/uplink_items/uplink_badass.dm b/code/modules/uplink/uplink_items/uplink_badass.dm index ec0ebf66d1..23f7063c7e 100644 --- a/code/modules/uplink/uplink_items/uplink_badass.dm +++ b/code/modules/uplink/uplink_items/uplink_badass.dm @@ -14,9 +14,9 @@ item = /obj/item/storage/box/syndie_kit/chameleon/broken /datum/uplink_item/badass/costumes - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) cost = 4 cant_discount = TRUE + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/badass/costumes/centcom_official name = "CentCom Official Costume" @@ -77,14 +77,14 @@ cost = 4 limited_stock = 1 cant_discount = TRUE - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/badass/gaming_cardpack name = "TCG Card Operatives Bundle" desc = "A bundle full of goodies required to work as a TCG Card Operative. A warm pajama, a mug of cocoa, a plushie and a two packs full of rare 2560 Core Set cards!" item = /obj/item/storage/box/syndie_kit/sleepytime/cardpack cost = 20 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/badass/cardpack name = "TCG Nuclear Cardpack" diff --git a/code/modules/uplink/uplink_items/uplink_bundles.dm b/code/modules/uplink/uplink_items/uplink_bundles.dm index cf33c893ad..a7ff04abbc 100644 --- a/code/modules/uplink/uplink_items/uplink_bundles.dm +++ b/code/modules/uplink/uplink_items/uplink_bundles.dm @@ -7,30 +7,30 @@ When adding new entries to the file, please keep them sorted by category. */ -/datum/uplink_item/bundles_TC/chemical +/datum/uplink_item/bundles_tc/chemical name = "Bioterror bundle" desc = "For the madman: Contains a handheld Bioterror chem sprayer, a Bioterror foam grenade, a box of lethal chemicals, a dart pistol, \ box of syringes, Donksoft assault rifle, and some riot darts. Remember: Seal suit and equip internals before use." item = /obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle cost = 30 // normally 42 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS -/datum/uplink_item/bundles_TC/bulldog +/datum/uplink_item/bundles_tc/bulldog name = "Bulldog bundle" desc = "Lean and mean: Optimized for people that want to get up close and personal. Contains the popular \ Bulldog shotgun, a 12g buckshot drum, a 12g taser slug drum and a pair of Thermal imaging goggles." item = /obj/item/storage/backpack/duffelbag/syndie/bulldogbundle cost = 13 // normally 16 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS -/datum/uplink_item/bundles_TC/c20r +/datum/uplink_item/bundles_tc/c20r name = "C-20r bundle" desc = "Old Faithful: The classic C-20r, bundled with two magazines, and a (surplus) suppressor at discount price." item = /obj/item/storage/backpack/duffelbag/syndie/c20rbundle cost = 14 // normally 16 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS -/datum/uplink_item/bundles_TC/contract_kit +/datum/uplink_item/bundles_tc/contract_kit name = "Contract Kit" desc = "The Syndicate have offered you the chance to become a contractor, take on kidnapping contracts for TC and cash payouts. Upon purchase, \ you'll be granted your own contract uplink embedded within the supplied tablet computer. Additionally, you'll be granted \ @@ -39,10 +39,10 @@ item = /obj/item/storage/box/syndie_kit/contract_kit cost = 20 player_minimum = 25 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) restricted = TRUE -/datum/uplink_item/bundles_TC/northstar_bundle +/datum/uplink_item/bundles_tc/northstar_bundle name = "Northstar Bundle" desc = "An item usually reserved for the Gorlex Marauders and their operatives, now available for recreational use. \ These armbands let the user punch people very fast and with the lethality of a legendary martial artist. \ @@ -50,16 +50,16 @@ Combines with all martial arts, but the user will be unable to bring themselves to use guns, nor remove the armbands." item = /obj/item/storage/box/syndie_kit/northstar cost = 20 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) -/datum/uplink_item/bundles_TC/scarp_bundle +/datum/uplink_item/bundles_tc/scarp_bundle name = "Sleeping Carp Bundle" desc = "Become one with your inner carp! Your ancient fish masters leave behind their legacy, and bestow to you their teachings, sacred uniform, and staff. \ Please be aware that you will not be able to use dishonerable ranged weapons." item = /obj/item/storage/box/syndie_kit/scarp cost = 20 player_minimum = 20 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/suits/infiltrator_bundle name = "Insidious Infiltration Gear Case" @@ -69,86 +69,85 @@ item = /obj/item/storage/toolbox/infiltrator cost = 5 limited_stock = 1 //you only get one so you don't end up with too many gun cases - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) -/datum/uplink_item/bundles_TC/cybernetics_bundle +/datum/uplink_item/bundles_tc/cybernetics_bundle name = "Cybernetic Implants Bundle" desc = "A random selection of cybernetic implants. Guaranteed 5 high quality implants. Comes with an autosurgeon." item = /obj/item/storage/box/cyber_implants cost = 40 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS -/datum/uplink_item/bundles_TC/medical +/datum/uplink_item/bundles_tc/medical name = "Medical bundle" desc = "The support specialist: Aid your fellow operatives with this medical bundle. Contains a tactical medkit, \ a Donksoft LMG, a box of riot darts and a pair of magboots to rescue your friends in no-gravity environments." item = /obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle cost = 15 // normally 20 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS -/datum/uplink_item/bundles_TC/modular +/datum/uplink_item/bundles_tc/modular name = "Modular Pistol Kit" desc = "A heavy briefcase containing one modular pistol (chambered in 10mm), one supressor, and spare ammunition, including a box of soporific ammo. \ Includes a suit jacket that is padded with a robust liner." item = /obj/item/storage/briefcase/modularbundle cost = 12 -/datum/uplink_item/bundles_TC/shredder +/datum/uplink_item/bundles_tc/shredder name = "Shredder bundle" desc = "A truly horrific weapon designed simply to maim its victim, the CX Shredder is banned by several intergalactic treaties. \ You'll get two of them with this. And spare ammo to boot. And we'll throw in an extra elite hardsuit and chest rig to hold them all!" item = /obj/item/storage/backpack/duffelbag/syndie/shredderbundle cost = 30 // normally 41 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS -/datum/uplink_item/bundles_TC/sniper +/datum/uplink_item/bundles_tc/sniper name = "Sniper bundle" desc = "Elegant and refined: Contains a collapsed sniper rifle in an expensive carrying case, \ two soporific knockout magazines, a free surplus supressor, and a sharp-looking tactical turtleneck suit. \ We'll throw in a free red tie if you order NOW." item = /obj/item/storage/briefcase/sniperbundle cost = 20 // normally 26 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS -/datum/uplink_item/bundles_TC/firestarter +/datum/uplink_item/bundles_tc/firestarter name = "Spetsnaz Pyro bundle" desc = "For systematic suppression of carbon lifeforms in close quarters: Contains a lethal New Russian backpack spray, Elite hardsuit, \ Stechkin APS pistol, two magazines, a minibomb and a stimulant syringe. \ Order NOW and comrade Boris will throw in an extra tracksuit." item = /obj/item/storage/backpack/duffelbag/syndie/firestarter cost = 30 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS -/datum/uplink_item/bundles_TC/bundle +/datum/uplink_item/bundles_tc/bundle name = "Syndicate Bundle" desc = "Syndicate Bundles are specialized groups of items that arrive in a plain box. \ These items are collectively worth more than 20 telecrystals, but you do not know which specialization \ you will receive. May contain discontinued and/or exotic items." item = /obj/item/storage/box/syndicate cost = 20 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/traitor/internal_affairs) + purchasable_from = ~(UPLINK_NUKE_OPS) cant_discount = TRUE -/datum/uplink_item/bundles_TC/surplus +/datum/uplink_item/bundles_tc/surplus name = "Syndicate Surplus Crate" desc = "A dusty crate from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \ but you never know. Contents are sorted to always be worth 50 TC." item = /obj/structure/closet/crate cost = 20 - player_minimum = 20 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) - cant_discount = TRUE + player_minimum = 25 + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) var/starting_crate_value = 50 -/datum/uplink_item/bundles_TC/surplus/super +/datum/uplink_item/bundles_tc/surplus/super name = "Super Surplus Crate" desc = "A dusty SUPER-SIZED from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \ but you never know. Contents are sorted to always be worth 125 TC." cost = 40 - player_minimum = 30 + player_minimum = 40 starting_crate_value = 125 -/datum/uplink_item/bundles_TC/surplus/purchase(mob/user, datum/component/uplink/U) +/datum/uplink_item/bundles_tc/surplus/purchase(mob/user, datum/component/uplink/U) var/list/uplink_items = get_uplink_items(SSticker && SSticker.mode? SSticker.mode : null, FALSE) var/crate_value = starting_crate_value @@ -170,7 +169,7 @@ U.purchase_log.LogPurchase(goods, I, 0) return C -/datum/uplink_item/bundles_TC/reroll +/datum/uplink_item/bundles_tc/reroll name = "Renegotiate Contract" desc = "Selecting this will inform your employers that you wish for new objectives. Can only be done twice." item = /obj/effect/gibspawner/generic @@ -179,22 +178,21 @@ restricted = TRUE limited_stock = 2 -/datum/uplink_item/bundles_TC/reroll/purchase(mob/user, datum/component/uplink/U) +/datum/uplink_item/bundles_tc/reroll/purchase(mob/user, datum/component/uplink/U) var/datum/antagonist/traitor/T = user?.mind?.has_antag_datum(/datum/antagonist/traitor) if(istype(T)) T.set_traitor_kind(get_random_traitor_kind(blacklist = list(/datum/traitor_class/human/freeform, /datum/traitor_class/human/hijack, /datum/traitor_class/human/martyr))) else to_chat(user,"Invalid user for contract renegotiation.") -/datum/uplink_item/bundles_TC/random +/datum/uplink_item/bundles_tc/random name = "Random Item" desc = "Picking this will purchase a random item. Useful if you have some TC to spare or if you haven't decided on a strategy yet." item = /obj/effect/gibspawner/generic // non-tangible item because techwebs use this path to determine illegal tech cost = 0 cant_discount = TRUE - exclude_modes = list(/datum/game_mode/traitor/internal_affairs) -/datum/uplink_item/bundles_TC/random/purchase(mob/user, datum/component/uplink/U) +/datum/uplink_item/bundles_tc/random/purchase(mob/user, datum/component/uplink/U) var/list/uplink_items = U.uplink_items var/list/possible_items = list() for(var/category in uplink_items) @@ -202,7 +200,7 @@ var/datum/uplink_item/I = uplink_items[category][item] if(src == I || !I.item) continue - if(istype(I, /datum/uplink_item/bundles_TC/reroll)) //oops! + if(istype(I, /datum/uplink_item/bundles_tc/reroll)) //oops! continue if(U.telecrystals < I.cost) continue @@ -215,7 +213,7 @@ SSblackbox.record_feedback("tally", "traitor_random_uplink_items_gotten", 1, initial(I.name)) U.MakePurchase(user, I) -/datum/uplink_item/bundles_TC/telecrystal +/datum/uplink_item/bundles_tc/telecrystal name = "1 Raw Telecrystal" desc = "A telecrystal in its rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." item = /obj/item/stack/telecrystal @@ -226,13 +224,13 @@ // it's just used to buy more items (including itself!) purchase_log_vis = FALSE -/datum/uplink_item/bundles_TC/telecrystal/five +/datum/uplink_item/bundles_tc/telecrystal/five name = "5 Raw Telecrystals" desc = "Five telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." item = /obj/item/stack/telecrystal/five cost = 5 -/datum/uplink_item/bundles_TC/telecrystal/twenty +/datum/uplink_item/bundles_tc/telecrystal/twenty name = "20 Raw Telecrystals" desc = "Twenty telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." item = /obj/item/stack/telecrystal/twenty diff --git a/code/modules/uplink/uplink_items/uplink_clothing.dm b/code/modules/uplink/uplink_items/uplink_clothing.dm index a9a9050903..7a8b7dc62f 100644 --- a/code/modules/uplink/uplink_items/uplink_clothing.dm +++ b/code/modules/uplink/uplink_items/uplink_clothing.dm @@ -12,35 +12,35 @@ desc = "A slightly armored conspicious jumpsuit that has no suit sensors attached to them, if someone sees you in this hope they think its a fake." item = /obj/item/clothing/under/syndicate cost = 1 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) //They already get these + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/suits/turtlenck_skirt name = "Tactical Skirtleneck" desc = "A slightly armored conspicious jumpsuit that has no suit sensors attached to them, if someone sees you in this hope they think its a fake." item = /obj/item/clothing/under/syndicate/skirt cost = 1 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) //They already get these + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/suits/padding name = "Soft Padding" desc = "An inconspicious soft padding meant to be worn underneath jumpsuits, will cushion the user from melee harm." item = /obj/item/clothing/accessory/padding cost = 2 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/suits/kevlar name = "Kevlar Padding" desc = "An inconspicious kevlar padding meant to be worn underneath jumpsuits, will cushion the wearer from ballistic harm." item = /obj/item/clothing/accessory/kevlar cost = 2 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/suits/plastic name = "Ablative Padding" desc = "An inconspicious ablative padding meant to be worn underneath jumpsuits, will cushion the wearer from energy lasers harm." item = /obj/item/clothing/accessory/plastics cost = 2 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/suits/space_suit name = "Syndicate Space Suit" @@ -59,7 +59,7 @@ Nanotrasen crew who spot these suits are known to panic." item = /obj/item/clothing/suit/space/hardsuit/syndi cost = 8 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) //you can't buy it in nuke, because the elite hardsuit costs the same while being better + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) //you can't buy it in nuke, because the elite hardsuit costs the same while being better /datum/uplink_item/suits/hardsuit/elite name = "Elite Syndicate Hardsuit" @@ -67,8 +67,7 @@ provides the user with superior armor and mobility compared to the standard Syndicate hardsuit." item = /obj/item/clothing/suit/space/hardsuit/syndi/elite cost = 8 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - exclude_modes = list() + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/suits/hardsuit/shielded name = "Shielded Syndicate Hardsuit" @@ -76,8 +75,7 @@ The shields can handle up to three impacts within a short duration and will rapidly recharge while not under fire." item = /obj/item/clothing/suit/space/hardsuit/shielded/syndi cost = 30 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - exclude_modes = list() + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/suits/thiefgloves name = "Thieving Gloves" @@ -87,16 +85,17 @@ /datum/uplink_item/suits/wallwalkers name = "Wall Walking Boots" - desc = "Through bluespace magic stolen from an organisation that hoards technology, these boots simply allow you to slip through the atoms that make up anything, but only while walking, for safety reasons. As well as this, they unfortunately cause minor breath loss as the majority of atoms in your lungs are sucked out into any solid object you walk through." + desc = "Through bluespace magic stolen from an organisation that hoards technology, these boots simply allow you to slip through the atoms that make up anything,but only while walking, \ + for safety reasons.As well as this, they unfortunately cause minor breath loss as the majority of atoms in your lungs are sucked out into any solid object you walk through." item = /obj/item/clothing/shoes/wallwalkers cost = 6 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/device_tools/guerrillagloves name = "Guerrilla Gloves" desc = "A pair of highly robust combat gripper gloves that excels at performing takedowns at close range, with an added lining of insulation. Careful not to hit a wall!" item = /obj/item/clothing/gloves/tackler/combat/insulated - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS cost = 2 illegal_tech = FALSE @@ -111,4 +110,4 @@ desc = "A pair of highly reinforced armwraps allowing the user to parry almost anything. Fully reflects projectiles, no downsides to failing, but is very hard to parry melee with." cost = 6 item = /obj/item/clothing/gloves/fingerless/ablative - exclude_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS diff --git a/code/modules/uplink/uplink_items/uplink_dangerous.dm b/code/modules/uplink/uplink_items/uplink_dangerous.dm index f13d11736f..6bfe3f5bb8 100644 --- a/code/modules/uplink/uplink_items/uplink_dangerous.dm +++ b/code/modules/uplink/uplink_items/uplink_dangerous.dm @@ -13,7 +13,7 @@ with suppressors." item = /obj/item/storage/box/syndie_kit/pistol cost = 7 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = ~UPLINK_CLOWN_OPS /datum/uplink_item/dangerous/revolver name = "Syndicate Revolver Kit" @@ -22,7 +22,7 @@ cost = 13 player_minimum = 15 surplus = 50 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) + purchasable_from = ~UPLINK_CLOWN_OPS /datum/uplink_item/dangerous/rawketlawnchair name = "84mm Rocket Propelled Grenade Launcher" @@ -31,7 +31,7 @@ item = /obj/item/gun/ballistic/rocketlauncher cost = 8 surplus = 30 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/dangerous/antitank name = "Anti Tank Pistol" @@ -42,7 +42,7 @@ item = /obj/item/gun/ballistic/automatic/pistol/antitank/syndicate cost = 14 surplus = 25 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/dangerous/pie_cannon name = "Banana Cream Pie Cannon" @@ -50,7 +50,7 @@ cost = 10 item = /obj/item/pneumatic_cannon/pie/selfcharge surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_CLOWN_OPS /datum/uplink_item/dangerous/bananashield name = "Bananium Energy Shield" @@ -60,7 +60,7 @@ item = /obj/item/shield/energy/bananium cost = 16 surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_CLOWN_OPS /datum/uplink_item/dangerous/clownsword name = "Bananium Energy Sword" @@ -69,7 +69,7 @@ item = /obj/item/melee/transforming/energy/sword/bananium cost = 3 surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_CLOWN_OPS /datum/uplink_item/dangerous/bioterror name = "Biohazardous Chemical Sprayer" @@ -79,7 +79,7 @@ item = /obj/item/reagent_containers/spray/chemsprayer/bioterror cost = 20 surplus = 0 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/dangerous/throwingweapons name = "Box of Throwing Weapons" @@ -95,7 +95,7 @@ item = /obj/item/gun/ballistic/automatic/shotgun/bulldog cost = 8 surplus = 40 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/dangerous/smg name = "C-20r Submachine Gun" @@ -104,7 +104,7 @@ item = /obj/item/gun/ballistic/automatic/c20r cost = 10 surplus = 40 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/dangerous/doublesword name = "Double-Bladed Energy Sword" @@ -113,7 +113,7 @@ item = /obj/item/dualsaber player_minimum = 25 cost = 16 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) + purchasable_from = ~UPLINK_CLOWN_OPS /datum/uplink_item/dangerous/doublesword/get_discount() return pick(4;0.8,2;0.65,1;0.5) @@ -125,7 +125,7 @@ item = /obj/item/dualsaber/hypereutactic player_minimum = 25 cost = 16 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) + purchasable_from = ~UPLINK_CLOWN_OPS /datum/uplink_item/dangerous/hyperblade/get_discount() return pick(4;0.8,2;0.65,1;0.5) @@ -136,7 +136,7 @@ pocketed when inactive. Activating it produces a loud, distinctive noise." item = /obj/item/melee/transforming/energy/sword/saber cost = 8 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) + purchasable_from = ~UPLINK_CLOWN_OPS /datum/uplink_item/dangerous/shield name = "Energy Shield" @@ -145,7 +145,7 @@ item = /obj/item/shield/energy cost = 16 surplus = 20 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/dangerous/rapier name = "Rapier" @@ -154,7 +154,7 @@ However, due to the size of the blade and obvious nature of the sheath, the weapon stands out as being obviously nefarious." item = /obj/item/storage/belt/sabre/rapier cost = 8 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) + purchasable_from = ~UPLINK_CLOWN_OPS /datum/uplink_item/dangerous/flamethrower name = "Flamethrower" @@ -163,7 +163,7 @@ item = /obj/item/flamethrower/full/tank cost = 4 surplus = 40 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/dangerous/flechettegun name = "Flechette Launcher" @@ -173,7 +173,7 @@ item = /obj/item/gun/ballistic/automatic/flechette cost = 12 surplus = 30 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/dangerous/rapid name = "Bands of the North Star" @@ -182,7 +182,7 @@ Combines with all martial arts, but the user will be unable to bring themselves to use guns, nor remove the armbands." item = /obj/item/clothing/gloves/fingerless/pugilist/rapid cost = 30 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/dangerous/guardian name = "Holoparasites" @@ -194,7 +194,7 @@ refundable = TRUE cant_discount = TRUE surplus = 0 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) player_minimum = 25 restricted = TRUE refund_path = /obj/item/guardiancreator/tech/choose/traitor @@ -208,16 +208,16 @@ refundable = TRUE surplus = 50 refund_path = /obj/item/guardiancreator/tech/choose/nukie - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/dangerous/machinegun name = "L6 Squad Automatic Weapon" desc = "A fully-loaded Aussec Armoury belt-fed machine gun. \ - This deadly weapon has a massive 50-round magazine of devastating 1.95x129mm ammunition." + This deadly weapon has a massive 50-round magazine of devastating 7.12x82mm ammunition." item = /obj/item/gun/ballistic/automatic/l6_saw cost = 18 surplus = 0 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/dangerous/carbine name = "M-90gl Carbine" @@ -226,7 +226,7 @@ item = /obj/item/gun/ballistic/automatic/m90 cost = 18 surplus = 50 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/dangerous/maulergauntlets name = "Mauler Gauntlets" @@ -245,7 +245,6 @@ deal extra damage and hit targets further. Use a screwdriver to take out any attached tanks." item = /obj/item/melee/powerfist cost = 8 - exclude_modes = list(/datum/game_mode/traitor/internal_affairs) /datum/uplink_item/dangerous/sniper name = "Sniper Rifle" @@ -253,14 +252,14 @@ item = /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate cost = 16 surplus = 25 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/dangerous/bolt_action name = "Surplus Rifle" desc = "A horribly outdated bolt action weapon. You've got to be desperate to use this." item = /obj/item/gun/ballistic/shotgun/boltaction cost = 2 - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/dangerous/foamsmg name = "Toy Submachine Gun" @@ -268,7 +267,7 @@ item = /obj/item/gun/ballistic/automatic/c20r/toy cost = 5 surplus = 0 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/dangerous/foammachinegun name = "Toy Machine Gun" @@ -277,7 +276,7 @@ item = /obj/item/gun/ballistic/automatic/l6_saw/toy cost = 10 surplus = 0 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/dangerous/foampistol name = "Toy Pistol with Riot Darts" @@ -292,7 +291,5 @@ desc = "An ancient blade said to have ties with Lavaland's most inner demons. \ Allows you to cut from a far distance!" item = /obj/item/gun/magic/staff/motivation - cost = 20 - player_minimum = 20 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) - cant_discount = TRUE + cost = 10 + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS diff --git a/code/modules/uplink/uplink_items/uplink_devices.dm b/code/modules/uplink/uplink_items/uplink_devices.dm index ad1cc31ba7..3a6aed2009 100644 --- a/code/modules/uplink/uplink_items/uplink_devices.dm +++ b/code/modules/uplink/uplink_items/uplink_devices.dm @@ -46,7 +46,7 @@ item = /obj/item/assault_pod cost = 30 surplus = 0 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS restricted = TRUE /datum/uplink_item/device_tools/binary @@ -66,7 +66,7 @@ 'Advanced Magboots' slow you down in simulated-gravity environments much like the standard issue variety." item = /obj/item/clothing/shoes/magboots/syndie cost = 2 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/device_tools/compressionkit name = "Bluespace Compression Kit" @@ -98,7 +98,7 @@ desc = "A robust seven-slot set of webbing that is capable of holding all manner of tactical equipment." item = /obj/item/storage/belt/military cost = 1 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/device_tools/ammo_pouch name = "Ammo Pouch" @@ -137,7 +137,7 @@ desc = "A cheap bottle of one use syndicate brand super glue. \ Use on any item to make it undroppable. \ Be careful not to glue an item you're already holding!" - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) item = /obj/item/syndie_glue cost = 2 @@ -166,7 +166,7 @@ operatives in the fight, even while under fire. Don't cross the streams!" item = /obj/item/gun/medbeam cost = 15 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/device_tools/nutcracker name = "Nutcracker" @@ -213,7 +213,7 @@ name = "Stimpack" desc = "Stimpacks, the tool of many great heroes. Makes you nearly immune to non-lethal weaponry for about \ 5 minutes after injection." - item = /obj/item/reagent_containers/syringe/stimulants + item = /obj/item/reagent_containers/hypospray/medipen/stimulants cost = 5 surplus = 90 @@ -224,7 +224,7 @@ and other supplies helpful for a field medic." item = /obj/item/storage/firstaid/tactical/nukeop cost = 4 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/device_tools/surgerybag name = "Syndicate Surgery Duffel Bag" @@ -272,9 +272,21 @@ desc = "A potion recovered at great risk by undercover Syndicate operatives and then subsequently modified with Syndicate technology. \ Using it will make any animal sentient, and bound to serve you, as well as implanting an internal radio for communication and an internal ID card for opening doors." cost = 2 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS restricted = TRUE +//this seems like a terrible idea to me, so commenting it out for now. -Shell +/* +/datum/uplink_item/device_tools/tc_rod + name = "Telecrystal Fuel Rod" + desc = "This special fuel rod has eight material slots that can be inserted with telecrystals, \ + once the rod has been fully depleted, you will be able to harvest the extra telecrystals. \ + Please note: This Rod fissiles much faster than it's regular counterpart, it doesn't take \ + much to overload the reactor with these..." + item = /obj/item/twohanded/required/fuel_rod/material/telecrystal + cost = 7 +*/ + /* for now /datum/uplink_item/device_tools/suspiciousphone name = "Protocol CRAB-17 Phone" diff --git a/code/modules/uplink/uplink_items/uplink_explosives.dm b/code/modules/uplink/uplink_items/uplink_explosives.dm index f44966fb3b..11b892a208 100644 --- a/code/modules/uplink/uplink_items/uplink_explosives.dm +++ b/code/modules/uplink/uplink_items/uplink_explosives.dm @@ -15,7 +15,7 @@ item = /obj/item/grenade/chem_grenade/bioterrorfoam cost = 5 surplus = 35 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/explosives/bombanana name = "Bombanana" @@ -24,7 +24,7 @@ item = /obj/item/reagent_containers/food/snacks/grown/banana/bombanana cost = 4 //it is a bit cheaper than a minibomb because you have to take off your helmet to eat it, which is how you arm it surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_CLOWN_OPS /datum/uplink_item/explosives/buzzkill name = "Buzzkill Grenade Box" @@ -33,7 +33,7 @@ item = /obj/item/storage/box/syndie_kit/bee_grenades cost = 15 surplus = 35 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/explosives/c4 name = "Composition C-4" @@ -58,7 +58,6 @@ item = /obj/item/storage/backpack/duffelbag/syndie/x4 cost = 4 // cant_discount = TRUE - exclude_modes = list(/datum/game_mode/traitor/internal_affairs) /datum/uplink_item/explosives/clown_bomb_clownops name = "Clown Bomb" @@ -70,7 +69,7 @@ item = /obj/item/sbeacondrop/clownbomb cost = 15 surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_CLOWN_OPS /datum/uplink_item/explosives/detomatix name = "Detomatix PDA Cartridge" @@ -97,14 +96,14 @@ item = /obj/item/storage/box/syndie_kit/tuberculosisgrenade cost = 8 surplus = 35 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS restricted = TRUE /datum/uplink_item/explosives/grenadier name = "Grenadier's belt" desc = "A belt containing 26 lethally dangerous and destructive grenades. Comes with an extra multitool and screwdriver." item = /obj/item/storage/belt/grenade/full - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS cost = 22 surplus = 0 @@ -125,7 +124,6 @@ be defused, and some crew may attempt to do so." item = /obj/item/sbeacondrop/bomb cost = 11 - exclude_modes = list(/datum/game_mode/traitor/internal_affairs) /datum/uplink_item/explosives/syndicate_detonator name = "Syndicate Detonator" @@ -135,7 +133,7 @@ the blast radius before using the detonator." item = /obj/item/syndicatedetonator cost = 3 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/explosives/syndicate_minibomb name = "Syndicate Minibomb" @@ -143,7 +141,7 @@ in addition to dealing high amounts of damage to nearby personnel." item = /obj/item/grenade/syndieminibomb cost = 6 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs) + purchasable_from = ~UPLINK_CLOWN_OPS /datum/uplink_item/explosives/tearstache name = "Teachstache Grenade" @@ -152,7 +150,7 @@ item = /obj/item/grenade/chem_grenade/teargas/moustache cost = 3 surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_CLOWN_OPS /datum/uplink_item/explosives/viscerators name = "Viscerator Delivery Grenade" @@ -161,4 +159,4 @@ item = /obj/item/grenade/spawnergrenade/manhacks cost = 5 surplus = 35 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS diff --git a/code/modules/uplink/uplink_items/uplink_implants.dm b/code/modules/uplink/uplink_items/uplink_implants.dm index 19dab96ccb..e3fe151143 100644 --- a/code/modules/uplink/uplink_items/uplink_implants.dm +++ b/code/modules/uplink/uplink_items/uplink_implants.dm @@ -20,7 +20,7 @@ desc = "This implant will help you get back up on your feet faster after being stunned. Comes with an autosurgeon." item = /obj/item/autosurgeon/anti_stun cost = 12 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/implants/deathrattle name = "Box of Deathrattle Implants" @@ -31,7 +31,7 @@ item = /obj/item/storage/box/syndie_kit/imp_deathrattle cost = 4 surplus = 0 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/implants/freedom name = "Freedom Implant" @@ -45,7 +45,7 @@ desc = "An implant injected into the body and later activated at the user's will. Allows the user to teleport to where they were 10 seconds ago. Has a 10 second cooldown." item = /obj/item/storage/box/syndie_kit/imp_warp cost = 6 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/implants/hijack name = "Hijack Implant" @@ -70,7 +70,7 @@ This will permanently destroy your body, however." item = /obj/item/storage/box/syndie_kit/imp_microbomb cost = 2 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/implants/macrobomb name = "Macrobomb Implant" @@ -78,7 +78,7 @@ Upon death, releases a massive explosion that will wipe out everything nearby." item = /obj/item/storage/box/syndie_kit/imp_macrobomb cost = 20 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS restricted = TRUE /datum/uplink_item/implants/reviver @@ -86,7 +86,7 @@ desc = "This implant will attempt to revive and heal you if you lose consciousness. Comes with an autosurgeon." item = /obj/item/autosurgeon/reviver cost = 8 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/implants/stealthimplant name = "Stealth Implant" @@ -107,7 +107,7 @@ desc = "These cybernetic eyes will give you thermal vision. Comes with a free autosurgeon." item = /obj/item/autosurgeon/thermal_eyes cost = 8 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS /datum/uplink_item/implants/uplink name = "Uplink Implant" @@ -125,4 +125,4 @@ item = /obj/item/autosurgeon/xray_eyes cost = 10 surplus = 0 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS diff --git a/code/modules/uplink/uplink_items/uplink_roles.dm b/code/modules/uplink/uplink_items/uplink_roles.dm index 774c2d9794..d741013ad2 100644 --- a/code/modules/uplink/uplink_items/uplink_roles.dm +++ b/code/modules/uplink/uplink_items/uplink_roles.dm @@ -30,7 +30,6 @@ item = /obj/item/gun/blastcannon cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled gas masked scientist. restricted_roles = list("Research Director", "Scientist") - exclude_modes = list(/datum/game_mode/traitor/internal_affairs) /datum/uplink_item/role_restricted/alientech name = "Alien Research Disk" @@ -99,7 +98,6 @@ player_minimum = 20 refundable = TRUE restricted_roles = list("Chaplain") - exclude_modes = list(/datum/game_mode/traitor/internal_affairs) /datum/uplink_item/role_restricted/arcane_tome name = "Arcane Tome" @@ -109,7 +107,6 @@ player_minimum = 20 refundable = TRUE restricted_roles = list("Chaplain") - exclude_modes = list(/datum/game_mode/traitor/internal_affairs) /datum/uplink_item/role_restricted/explosive_hot_potato name = "Exploding Hot Potato" @@ -195,7 +192,7 @@ name = "Magillitis Serum Autoinjector" desc = "A single-use autoinjector which contains an experimental serum that causes rapid muscular growth in Hominidae. \ Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas." - item = /obj/item/reagent_containers/hypospray/magillitis + item = /obj/item/reagent_containers/hypospray/medipen/magillitis cost = 8 restricted_roles = list("Geneticist", "Chief Medical Officer") diff --git a/code/modules/uplink/uplink_items/uplink_stealth.dm b/code/modules/uplink/uplink_items/uplink_stealth.dm index f401514542..8b79b15c80 100644 --- a/code/modules/uplink/uplink_items/uplink_stealth.dm +++ b/code/modules/uplink/uplink_items/uplink_stealth.dm @@ -19,14 +19,14 @@ to learn the abilities of krav maga to the wearer." item = /obj/item/clothing/gloves/krav_maga/combatglovesplus cost = 5 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS surplus = 0 /datum/uplink_item/stealthy_weapons/cqc name = "CQC Manual" desc = "A manual that teaches a single user tactical Close-Quarters Combat before self-destructing." item = /obj/item/book/granter/martial/cqc - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS cost = 13 surplus = 0 @@ -61,7 +61,7 @@ name = "Antique Derringer" desc = "An easy to conceal, yet extremely deadly handgun, capable of firing .45-70 Govt rounds. Comes in a unique pack of cigarettes with additional munitions." item = /obj/item/storage/fancy/cigarettes/derringer/midworld - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS cost = 10 surplus = 2 @@ -79,7 +79,7 @@ cost = 17 player_minimum = 20 surplus = 0 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/stealthy_weapons/martialartstwo name = "Rising Bass Scroll" @@ -89,7 +89,7 @@ cost = 18 player_minimum = 20 surplus = 0 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/stealthy_weapons/martialartsthree name = "Krav Maga Scroll" @@ -99,7 +99,6 @@ cost = 16 player_minimum = 25 surplus = 0 - include_modes = list(/datum/game_mode/traitor/internal_affairs) /datum/uplink_item/stealthy_weapons/crossbow name = "Miniature Energy Crossbow" @@ -112,7 +111,7 @@ item = /obj/item/gun/energy/kinetic_accelerator/crossbow cost = 12 surplus = 50 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/stealthy_weapons/traitor_chem_bottle name = "Poison Kit" @@ -130,7 +129,7 @@ cost = 25 player_minimum = 25 cant_discount = TRUE - exclude_modes = list(/datum/game_mode/nuclear) + purchasable_from = ~UPLINK_NUKE_OPS /datum/uplink_item/stealthy_weapons/sleepy_pen name = "Sleepy Pen" @@ -140,14 +139,14 @@ falls asleep, they will be able to move and act." item = /obj/item/pen/sleepy cost = 4 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/stealthy_weapons/taeclowndo_shoes name = "Tae-clown-do Shoes" desc = "A pair of shoes for the most elite agents of the honkmotherland. They grant the mastery of taeclowndo with some honk-fu moves as long as they're worn." cost = 12 item = /obj/item/clothing/shoes/clown_shoes/taeclowndo - include_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_CLOWN_OPS /datum/uplink_item/stealthy_weapons/suppressor name = "Suppressor" diff --git a/code/modules/uplink/uplink_items/uplink_stealthdevices.dm b/code/modules/uplink/uplink_items/uplink_stealthdevices.dm index 0a82b3b8b3..c2a915a28f 100644 --- a/code/modules/uplink/uplink_items/uplink_stealthdevices.dm +++ b/code/modules/uplink/uplink_items/uplink_stealthdevices.dm @@ -33,7 +33,7 @@ Due to budget cuts, the shoes don't provide protection against slipping." item = /obj/item/storage/box/syndie_kit/chameleon cost = 2 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/stealthy_tools/chameleon_proj name = "Chameleon Projector" @@ -57,7 +57,7 @@ item = /obj/item/clothing/shoes/clown_shoes/banana_shoes/combat cost = 6 surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_CLOWN_OPS /datum/uplink_item/stealthy_tools/emplight name = "EMP Flashlight" @@ -75,7 +75,7 @@ cost = 1 surplus = 0 restricted = TRUE - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/stealthy_tools/failsafe/spawn_item(spawn_path, mob/user, datum/component/uplink/U) if(!U) @@ -93,7 +93,7 @@ item = /obj/item/reagent_containers/syringe/mulligan cost = 3 surplus = 30 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/stealthy_tools/syndigaloshes name = "No-Slip Chameleon Shoes" @@ -101,13 +101,12 @@ They do not work on heavily lubricated surfaces." item = /obj/item/clothing/shoes/chameleon/noslip cost = 2 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) /datum/uplink_item/stealthy_tools/syndigaloshes/nuke item = /obj/item/clothing/shoes/chameleon/noslip cost = 4 - exclude_modes = list() - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS /datum/uplink_item/stealthy_tools/jammer name = "Radio Jammer" diff --git a/code/modules/uplink/uplink_items/uplink_support.dm b/code/modules/uplink/uplink_items/uplink_support.dm index fe1415adc8..245074b2a5 100644 --- a/code/modules/uplink/uplink_items/uplink_support.dm +++ b/code/modules/uplink/uplink_items/uplink_support.dm @@ -12,7 +12,7 @@ desc = "Call in an additional clown to share the fun, equipped with full starting gear, but no telecrystals." item = /obj/item/antag_spawner/nuke_ops/clown cost = 20 - include_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_CLOWN_OPS restricted = TRUE /datum/uplink_item/support/reinforcement @@ -22,7 +22,7 @@ item = /obj/item/antag_spawner/nuke_ops cost = 25 refundable = TRUE - include_modes = list(/datum/game_mode/nuclear) + purchasable_from = UPLINK_NUKE_OPS restricted = TRUE /datum/uplink_item/support/reinforcement/assault_borg @@ -58,19 +58,19 @@ name = "Dark Gygax Exosuit" desc = "A lightweight exosuit, painted in a dark scheme. Its speed and equipment selection make it excellent \ for hit-and-run style attacks. Features an incendiary carbine, flash bang launcher, teleporter, ion thrusters and a Tesla energy array." - item = /obj/mecha/combat/gygax/dark/loaded + item = /obj/vehicle/sealed/mecha/combat/gygax/dark/loaded cost = 80 /datum/uplink_item/support/honker name = "Dark H.O.N.K." desc = "A clown combat mech equipped with bombanana peel and tearstache grenade launchers, as well as the ubiquitous HoNkER BlAsT 5000." - item = /obj/mecha/combat/honker/dark/loaded + item = /obj/vehicle/sealed/mecha/combat/honker/dark/loaded cost = 80 - include_modes = list(/datum/game_mode/nuclear/clown_ops) + purchasable_from = UPLINK_CLOWN_OPS /datum/uplink_item/support/mauler name = "Mauler Exosuit" desc = "A massive and incredibly deadly military-grade exosuit. Features long-range targeting, thrust vectoring \ and deployable smoke. Comes equipped with an LMG, scattershot carbine, missile rack, an antiprojectile armor booster and a Tesla energy array." - item = /obj/mecha/combat/marauder/mauler/loaded + item = /obj/vehicle/sealed/mecha/combat/marauder/mauler/loaded cost = 140 diff --git a/code/modules/uplink/uplink_purchase_log.dm b/code/modules/uplink/uplink_purchase_log.dm index 293191b170..c9ac13fa13 100644 --- a/code/modules/uplink/uplink_purchase_log.dm +++ b/code/modules/uplink/uplink_purchase_log.dm @@ -1,8 +1,8 @@ -GLOBAL_LIST(uplink_purchase_logs_by_key) //assoc key = /datum/uplink_purchase_log +GLOBAL_LIST(uplink_purchase_logs_by_key) //assoc key = /datum/uplink_purchase_log /datum/uplink_purchase_log var/owner - var/list/purchase_log //assoc path-of-item = /datum/uplink_purchase_entry + var/list/purchase_log //assoc path-of-item = /datum/uplink_purchase_entry var/total_spent = 0 /datum/uplink_purchase_log/New(_owner, datum/component/uplink/_parent) diff --git a/code/modules/vehicles/_vehicle.dm b/code/modules/vehicles/_vehicle.dm index 12e9f365d0..a968d42073 100644 --- a/code/modules/vehicles/_vehicle.dm +++ b/code/modules/vehicles/_vehicle.dm @@ -4,9 +4,10 @@ icon = 'icons/obj/vehicles.dmi' icon_state = "fuckyou" max_integrity = 300 - armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) + armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 60, ACID = 60) density = TRUE anchored = FALSE + COOLDOWN_DECLARE(cooldown_vehicle_move) var/list/mob/occupants //mob = bitflags of their control level. var/max_occupants = 1 var/max_drivers = 1 @@ -23,6 +24,7 @@ var/list/autogrant_actions_controller //assoc list "[bitflag]" = list(typepaths) var/list/mob/occupant_actions //assoc list mob = list(type = action datum assigned to mob) var/obj/vehicle/trailer + var/mouse_pointer //do we have a special mouse /obj/vehicle/Initialize(mapload) . = ..() @@ -91,9 +93,9 @@ /obj/vehicle/proc/after_add_occupant(mob/M) auto_assign_occupant_flags(M) -/obj/vehicle/proc/auto_assign_occupant_flags(mob/M) //override for each type that needs it. Default is assign driver if drivers is not at max. +/obj/vehicle/proc/auto_assign_occupant_flags(mob/M) //override for each type that needs it. Default is assign driver if drivers is not at max. if(driver_amount() < max_drivers) - add_control_flags(M, VEHICLE_CONTROL_DRIVE|VEHICLE_CONTROL_PERMISSION) + add_control_flags(M, VEHICLE_CONTROL_DRIVE) /obj/vehicle/proc/remove_occupant(mob/M) if(!istype(M)) @@ -121,9 +123,9 @@ vehicle_move(direction) /obj/vehicle/proc/vehicle_move(direction) - if(lastmove + movedelay > world.time) + if(!COOLDOWN_FINISHED(src, cooldown_vehicle_move)) return FALSE - lastmove = world.time + COOLDOWN_START(src, cooldown_vehicle_move, movedelay) if(trailer) var/dir_to_move = get_dir(trailer.loc, loc) var/did_move = step(src, direction) diff --git a/code/modules/vehicles/atv.dm b/code/modules/vehicles/atv.dm index d5ddfe63cc..cb32b11083 100644 --- a/code/modules/vehicles/atv.dm +++ b/code/modules/vehicles/atv.dm @@ -6,7 +6,7 @@ key_type = /obj/item/key var/static/mutable_appearance/atvcover -/obj/vehicle/ridden/atv/Initialize() +/obj/vehicle/ridden/atv/Initialize(mapload) . = ..() var/datum/component/riding/D = LoadComponent(/datum/component/riding) D.vehicle_move_delay = CONFIG_GET(number/movedelay/run_delay) @@ -34,7 +34,7 @@ scan_range = 7 density = FALSE -/obj/vehicle/ridden/atv/turret/Initialize() +/obj/vehicle/ridden/atv/turret/Initialize(mapload) . = ..() turret = new(loc) turret.base = src diff --git a/code/modules/vehicles/bicycle.dm b/code/modules/vehicles/bicycle.dm index 3784f4d459..2fbe20a75f 100644 --- a/code/modules/vehicles/bicycle.dm +++ b/code/modules/vehicles/bicycle.dm @@ -8,7 +8,7 @@ 'sound/misc/bike2.mid', 'sound/misc/bike3.mid') -/obj/vehicle/ridden/bicycle/Initialize() +/obj/vehicle/ridden/bicycle/Initialize(mapload) . = ..() var/datum/component/riding/D = LoadComponent(/datum/component/riding) D.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(0, 4), TEXT_WEST = list( 0, 4))) diff --git a/code/modules/vehicles/cars/car.dm b/code/modules/vehicles/cars/car.dm index 08a7986fa3..e024718f4c 100644 --- a/code/modules/vehicles/cars/car.dm +++ b/code/modules/vehicles/cars/car.dm @@ -2,21 +2,27 @@ layer = ABOVE_MOB_LAYER anchored = TRUE default_driver_move = FALSE + var/explode_on_death = TRUE var/car_traits = NONE //Bitflag for special behavior such as kidnapping var/engine_sound = 'sound/vehicles/carrev.ogg' var/last_enginesound_time var/engine_sound_length = 20 //Set this to the length of the engine sound var/escape_time = 200 //Time it takes to break out of the car -/obj/vehicle/sealed/car/Initialize() +/obj/vehicle/sealed/car/Initialize(mapload) . = ..() LoadComponent(/datum/component/riding) +/obj/vehicle/sealed/car/Destroy() + . = ..() + if(explode_on_death) + explosion(loc, 0, 1, 2, 3, 0) + /obj/vehicle/sealed/car/generate_actions() . = ..() initialize_controller_action_type(/datum/action/vehicle/sealed/remove_key, VEHICLE_CONTROL_DRIVE) if(car_traits & CAN_KIDNAP) - initialize_controller_action_type(/datum/action/vehicle/sealed/DumpKidnappedMobs, VEHICLE_CONTROL_DRIVE) + initialize_controller_action_type(/datum/action/vehicle/sealed/dump_kidnapped_mobs, VEHICLE_CONTROL_DRIVE) /obj/vehicle/sealed/car/driver_move(mob/user, direction) if(key_type && !is_key(inserted_key)) diff --git a/code/modules/vehicles/cars/clowncar.dm b/code/modules/vehicles/cars/clowncar.dm index 0b75dbf4db..9660a16f90 100644 --- a/code/modules/vehicles/cars/clowncar.dm +++ b/code/modules/vehicles/cars/clowncar.dm @@ -1,34 +1,45 @@ /obj/vehicle/sealed/car/clowncar name = "clown car" - desc = "How someone could even fit in there is beyond me." + desc = "How someone could even fit in there is byond me." icon_state = "clowncar" max_integrity = 150 - armor = list("melee" = 70, "bullet" = 40, "laser" = 40, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) + armor = list(MELEE = 70, BULLET = 40, LASER = 40, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 80, ACID = 80) enter_delay = 20 max_occupants = 50 movedelay = 0.6 car_traits = CAN_KIDNAP key_type = /obj/item/bikehorn key_type_exact = FALSE - var/droppingoil = FALSE - var/RTDcooldown = 150 - var/lastRTDtime = 0 + ///list of headlight colors we use to pick through when we have party mode due to emag + var/headlight_colors = list(COLOR_RED, COLOR_ORANGE, COLOR_YELLOW, COLOR_LIME, COLOR_BRIGHT_BLUE, COLOR_CYAN, COLOR_PURPLE) + ///Cooldown time inbetween [/obj/vehicle/sealed/car/clowncar/proc/roll_the_dice()] usages + var/dice_cooldown_time = 150 + ///How many times kidnappers in the clown car said thanks + var/thankscount = 0 + ///Current status of the cannon, alternates between CLOWN_CANNON_INACTIVE, CLOWN_CANNON_BUSY and CLOWN_CANNON_READY + var/cannonmode = CLOWN_CANNON_INACTIVE + var/light_on = TRUE + +/obj/vehicle/sealed/car/clowncar/Initialize(mapload) + . = ..() + START_PROCESSING(SSobj,src) + +/obj/vehicle/sealed/car/clowncar/process() + if(light_on && (obj_flags & EMAGGED)) + set_light_color(pick(headlight_colors)) /obj/vehicle/sealed/car/clowncar/generate_actions() . = ..() - initialize_controller_action_type(/datum/action/vehicle/sealed/horn/clowncar, VEHICLE_CONTROL_DRIVE) - -/obj/vehicle/sealed/car/clowncar/driver_move(mob/user, direction) //Prevent it from moving onto space - if(isspaceturf(get_step(src, direction))) - return FALSE - else - return ..() + initialize_controller_action_type(/datum/action/vehicle/sealed/horn, VEHICLE_CONTROL_DRIVE) + initialize_controller_action_type(/datum/action/vehicle/sealed/thank, VEHICLE_CONTROL_KIDNAPPED) /obj/vehicle/sealed/car/clowncar/auto_assign_occupant_flags(mob/M) if(ishuman(M)) var/mob/living/carbon/human/H = M if(H.mind && HAS_TRAIT(H.mind, TRAIT_CLOWN_MENTALITY)) //Ensures only clowns can drive the car. (Including more at once) - add_control_flags(M, VEHICLE_CONTROL_DRIVE|VEHICLE_CONTROL_PERMISSION) + add_control_flags(H, VEHICLE_CONTROL_DRIVE) + RegisterSignal(H, COMSIG_MOB_CLICKON, .proc/fire_cannon_at) + M.log_message("has entered [src] as a possible driver", LOG_ATTACK) return add_control_flags(M, VEHICLE_CONTROL_KIDNAPPED) @@ -36,120 +47,212 @@ . = ..() playsound(src, pick('sound/vehicles/clowncar_load1.ogg', 'sound/vehicles/clowncar_load2.ogg'), 75) +/obj/vehicle/sealed/car/clowncar/after_add_occupant(mob/M, control_flags) + . = ..() + if(return_controllers_with_flag(VEHICLE_CONTROL_KIDNAPPED).len >= 30) + for(var/mob/voreman as anything in return_drivers()) + voreman.client.give_award(/datum/award/achievement/misc/round_and_full, voreman) + +/obj/vehicle/sealed/car/clowncar/attack_animal(mob/living/simple_animal/user, list/modifiers) + if((user.loc != src) || user.environment_smash & (ENVIRONMENT_SMASH_WALLS|ENVIRONMENT_SMASH_RWALLS)) + return ..() + +/obj/vehicle/sealed/car/clowncar/mob_exit(mob/M, silent = FALSE, randomstep = FALSE) + . = ..() + UnregisterSignal(M, COMSIG_MOB_CLICKON) + /obj/vehicle/sealed/car/clowncar/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) . = ..() if(prob(33)) - visible_message("[src] spews out a ton of space lube!") + visible_message(span_danger("[src] spews out a ton of space lube!")) new /obj/effect/particle_effect/foam(loc) //YEET -/obj/vehicle/sealed/car/clowncar/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1) +/obj/vehicle/sealed/car/clowncar/attacked_by(obj/item/I, mob/living/user) . = ..() - if(istype(I, /obj/item/reagent_containers/food/snacks/grown/banana)) - var/obj/item/reagent_containers/food/snacks/grown/banana/banana = I - obj_integrity += min(banana.seed.potency, max_integrity-obj_integrity) - to_chat(user, "You use the [banana] to repair the [src]!") - qdel(banana) + if(!istype(I, /obj/item/reagent_containers/food/snacks/grown/banana)) + return + var/obj/item/reagent_containers/food/snacks/grown/banana/banana = I + obj_integrity += min(banana.seed.potency, max_integrity-obj_integrity) + to_chat(user, span_danger("You use the [banana] to repair the [src]!")) + qdel(banana) -/obj/vehicle/sealed/car/clowncar/Bump(atom/movable/M) +/obj/vehicle/sealed/car/clowncar/Bump(atom/bumped) . = ..() - if(isliving(M)) - if(ismegafauna(M)) + if(isliving(bumped)) + if(ismegafauna(bumped)) return - var/mob/living/L = M - if(iscarbon(L)) - var/mob/living/carbon/C = L - C.DefaultCombatKnockdown(40) //I play to make sprites go horizontal - L.visible_message("[src] rams into [L] and sucks him up!") //fuck off shezza this isn't ERP. - mob_forced_enter(L) + var/mob/living/hittarget_living = bumped + if(iscarbon(hittarget_living)) + var/mob/living/carbon/carb = hittarget_living + carb.DefaultCombatKnockdown(40) //I play to make sprites go horizontal + hittarget_living.visible_message(span_warning("[src] rams into [hittarget_living] and sucks [hittarget_living.p_them()] up!")) //fuck off shezza this isn't ERP. + mob_forced_enter(hittarget_living) playsound(src, pick('sound/vehicles/clowncar_ram1.ogg', 'sound/vehicles/clowncar_ram2.ogg', 'sound/vehicles/clowncar_ram3.ogg'), 75) - else if(istype(M, /turf/closed) || istype(M, /obj/machinery/door/airlock/external)) - visible_message("[src] rams into [M] and crashes!") - playsound(src, pick('sound/vehicles/clowncar_crash1.ogg', 'sound/vehicles/clowncar_crash2.ogg'), 75) - playsound(src, 'sound/vehicles/clowncar_crashpins.ogg', 75) - DumpMobs(TRUE) + log_combat(src, hittarget_living, "sucked up") + return + if(!istype(bumped, /turf/closed) && !istype(bumped, /obj/machinery/door/airlock/external)) + return + visible_message(span_warning("[src] rams into [bumped] and crashes!")) + playsound(src, pick('sound/vehicles/clowncar_crash1.ogg', 'sound/vehicles/clowncar_crash2.ogg'), 75) + playsound(src, 'sound/vehicles/clowncar_crashpins.ogg', 75) + DumpMobs(TRUE) + log_combat(src, bumped, "crashed into", null, "dumping all passengers") /obj/vehicle/sealed/car/clowncar/emag_act(mob/user) . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED - to_chat(user, "You scramble the clowncar child safety lock and a panel with 6 colorful buttons appears!") - initialize_controller_action_type(/datum/action/vehicle/sealed/RollTheDice, VEHICLE_CONTROL_DRIVE) + to_chat(user, span_danger("You scramble \the [src]'s child safety lock, and a panel with six colorful buttons appears!")) + initialize_controller_action_type(/datum/action/vehicle/sealed/roll_the_dice, VEHICLE_CONTROL_DRIVE) + initialize_controller_action_type(/datum/action/vehicle/sealed/cannon, VEHICLE_CONTROL_DRIVE) return TRUE -/obj/vehicle/sealed/car/clowncar/Destroy() +/obj/vehicle/sealed/car/clowncar/obj_destruction(damage_flag) playsound(src, 'sound/vehicles/clowncar_fart.ogg', 100) + STOP_PROCESSING(SSobj,src) return ..() -/obj/vehicle/sealed/car/clowncar/after_move(direction) - . = ..() - if(droppingoil) - new /obj/effect/decal/cleanable/oil/slippery(loc) - -/obj/vehicle/sealed/car/clowncar/proc/RollTheDice(mob/user) - if(world.time - lastRTDtime < RTDcooldown) - to_chat(user, "The button panel is currently recharging.") +/** + * Plays a random funky effect + * Only available while car is emagged + * Possible effects: + * * Spawn bananapeel + * * Spawn random reagent foam + * * Make the clown car look like a singulo temporarily + * * Spawn Laughing chem gas + * * Drop oil + * * Fart and make everyone nearby laugh + */ +/obj/vehicle/sealed/car/clowncar/proc/roll_the_dice(mob/user) + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_CLOWNCAR_RANDOMNESS)) + to_chat(user, span_notice("The button panel is currently recharging.")) return - lastRTDtime = world.time - var/randomnum = rand(1,6) - switch(randomnum) + TIMER_COOLDOWN_START(src, COOLDOWN_CLOWNCAR_RANDOMNESS, dice_cooldown_time) + switch(rand(1,6)) if(1) - visible_message("[user] has pressed one of the colorful buttons on [src] and a special banana peel drops out of it.") + visible_message(span_danger("[user] presses one of the colorful buttons on [src], and a special banana peel drops out of it.")) new /obj/item/grown/bananapeel/specialpeel(loc) if(2) - visible_message("[user] has pressed one of the colorful buttons on [src] and unknown chemicals flood out of it.") - var/datum/reagents/R = new/datum/reagents(300) - R.my_atom = src - R.add_reagent(get_random_reagent_id(), 100) + visible_message(span_danger("[user] presses one of the colorful buttons on [src], and unknown chemicals flood out of it.")) + var/datum/reagents/randomchems = new/datum/reagents(300) + randomchems.my_atom = src + randomchems.add_reagent(get_random_reagent_id(), 100) var/datum/effect_system/foam_spread/foam = new - foam.set_up(200, loc, R) + foam.set_up(200, loc, randomchems) foam.start() if(3) - visible_message("[user] has pressed one of the colorful buttons on [src] and the clown car turns on its singularity disguise system.") + visible_message(span_danger("[user] presses one of the colorful buttons on [src], and the clown car turns on its singularity disguise system.")) icon = 'icons/obj/singularity.dmi' icon_state = "singularity_s1" - addtimer(CALLBACK(src, .proc/ResetIcon), 100) + addtimer(CALLBACK(src, .proc/reset_icon), 10 SECONDS) if(4) - visible_message("[user] has pressed one of the colorful buttons on [src] and the clown car spews out a cloud of laughing gas.") - var/datum/reagents/R = new/datum/reagents(300) - R.my_atom = src - R.add_reagent(/datum/reagent/consumable/superlaughter, 50) + visible_message(span_danger("[user] presses one of the colorful buttons on [src], and the clown car spews out a cloud of laughing gas.")) + var/datum/reagents/funnychems = new/datum/reagents(300) + funnychems.my_atom = src + funnychems.add_reagent(/datum/reagent/consumable/superlaughter, 50) var/datum/effect_system/smoke_spread/chem/smoke = new() - smoke.set_up(R, 4) + smoke.set_up(funnychems, 4) smoke.attach(src) smoke.start() if(5) - visible_message("[user] has pressed one of the colorful buttons on [src] and the clown car starts dropping an oil trail.") - droppingoil = TRUE - addtimer(CALLBACK(src, .proc/StopDroppingOil), 30) + visible_message(span_danger("[user] presses one of the colorful buttons on [src], and the clown car starts dropping an oil trail.")) + RegisterSignal(src, COMSIG_MOVABLE_MOVED, .proc/cover_in_oil) + addtimer(CALLBACK(src, .proc/stop_dropping_oil), 3 SECONDS) if(6) - visible_message("[user] has pressed one of the colorful buttons on [src] and the clown car lets out a comedic toot.") + visible_message(span_danger("[user] presses one of the colorful buttons on [src], and the clown car lets out a comedic toot.")) playsound(src, 'sound/vehicles/clowncar_fart.ogg', 100) for(var/mob/living/L in orange(loc, 6)) L.emote("laughs") - for(var/mob/living/L in occupants) + for(var/mob/living/L as anything in occupants) L.emote("laughs") -/obj/vehicle/sealed/car/clowncar/proc/ResetIcon() +///resets the icon and iconstate of the clowncar after it was set to singulo states +/obj/vehicle/sealed/car/clowncar/proc/reset_icon() icon = initial(icon) icon_state = initial(icon_state) -/obj/vehicle/sealed/car/clowncar/proc/StopDroppingOil() - droppingoil = FALSE +///Deploys oil when the clowncar moves in oil deploy mode +/obj/vehicle/sealed/car/clowncar/proc/cover_in_oil() + SIGNAL_HANDLER + new /obj/effect/decal/cleanable/oil/slippery(loc) + +///Stops dropping oil after the time has run up +/obj/vehicle/sealed/car/clowncar/proc/stop_dropping_oil() + UnregisterSignal(src, COMSIG_MOVABLE_MOVED) + +///Toggles the on and off state of the clown cannon that shoots random kidnapped people +/obj/vehicle/sealed/car/clowncar/proc/toggle_cannon(mob/user) + if(cannonmode == CLOWN_CANNON_BUSY) + to_chat(user, span_notice("Please wait for the vehicle to finish its current action first.")) + return + if(cannonmode) //canon active, deactivate + flick("clowncar_fromfire", src) + icon_state = "clowncar" + addtimer(CALLBACK(src, .proc/deactivate_cannon), 2 SECONDS) + playsound(src, 'sound/vehicles/clowncar_cannonmode2.ogg', 75) + visible_message(span_danger("The [src] starts going back into mobile mode.")) + else + canmove = FALSE //anchor and activate canon + flick("clowncar_tofire", src) + icon_state = "clowncar_fire" + visible_message(span_danger("The [src] opens up and reveals a large cannon.")) + addtimer(CALLBACK(src, .proc/activate_cannon), 2 SECONDS) + playsound(src, 'sound/vehicles/clowncar_cannonmode1.ogg', 75) + cannonmode = CLOWN_CANNON_BUSY + +///Finalizes canon activation +/obj/vehicle/sealed/car/clowncar/proc/activate_cannon() + // mouse_pointer = 'icons/effects/mouse_pointers/mecha_mouse.dmi' + cannonmode = CLOWN_CANNON_READY + for(var/mob/living/driver as anything in return_controllers_with_flag(VEHICLE_CONTROL_DRIVE)) + driver.update_mouse_pointer() + +///Finalizes canon deactivation +/obj/vehicle/sealed/car/clowncar/proc/deactivate_cannon() + canmove = TRUE + // mouse_pointer = null + cannonmode = CLOWN_CANNON_INACTIVE + for(var/mob/living/driver as anything in return_controllers_with_flag(VEHICLE_CONTROL_DRIVE)) + driver.update_mouse_pointer() + +///Fires the cannon where the user clicks +/obj/vehicle/sealed/car/clowncar/proc/fire_cannon_at(mob/user, atom/A, params) + SIGNAL_HANDLER + if(cannonmode != CLOWN_CANNON_READY || !length(return_controllers_with_flag(VEHICLE_CONTROL_KIDNAPPED))) + return NONE + var/mob/living/unlucky_sod = pick(return_controllers_with_flag(VEHICLE_CONTROL_KIDNAPPED)) + mob_exit(unlucky_sod, TRUE) + flick("clowncar_recoil", src) + playsound(src, pick('sound/vehicles/carcannon1.ogg', 'sound/vehicles/carcannon2.ogg', 'sound/vehicles/carcannon3.ogg'), 75) + unlucky_sod.throw_at(A, 10, 2) + log_combat(user, unlucky_sod, "fired", src, "towards [A]") //this doesn't catch if the mob hits something between the car and the target + return COMSIG_MOB_CANCEL_CLICKON + +///Increments the thanks counter every time someone thats been kidnapped thanks the driver +/obj/vehicle/sealed/car/clowncar/proc/increment_thanks_counter() + thankscount++ + if(thankscount < 100) + return + for(var/mob/busdriver as anything in return_drivers()) + busdriver.client.give_award(/datum/award/achievement/misc/the_best_driver, busdriver) + +/obj/vehicle/sealed/car/clowncar/driver_move(mob/user, direction) //Prevent it from moving onto space + if(isspaceturf(get_step(src, direction))) + return FALSE + return ..() /obj/vehicle/sealed/car/clowncar/twitch_plays key_type = null explode_on_death = FALSE -/obj/vehicle/sealed/car/clowncar/twitch_plays/Initialize() +/obj/vehicle/sealed/car/clowncar/twitch_plays/Initialize(mapload) . = ..() AddComponent(/datum/component/twitch_plays/simple_movement) - START_PROCESSING(SSfastprocess, src) GLOB.poi_list |= src notify_ghosts("Twitch Plays: Clown Car") /obj/vehicle/sealed/car/clowncar/twitch_plays/Destroy() - STOP_PROCESSING(SSfastprocess, src) GLOB.poi_list -= src return ..() @@ -158,3 +261,4 @@ if(!dir) return driver_move(null, dir) + ..() diff --git a/code/modules/vehicles/lavaboat.dm b/code/modules/vehicles/lavaboat.dm index 32f53a15aa..3d83c48633 100644 --- a/code/modules/vehicles/lavaboat.dm +++ b/code/modules/vehicles/lavaboat.dm @@ -9,7 +9,7 @@ resistance_flags = LAVA_PROOF | FIRE_PROOF can_buckle = TRUE -/obj/vehicle/ridden/lavaboat/Initialize() +/obj/vehicle/ridden/lavaboat/Initialize(mapload) . = ..() var/datum/component/riding/D = LoadComponent(/datum/component/riding) D.keytype = /obj/item/oar @@ -61,7 +61,7 @@ desc = "This boat moves where you will it, without the need for an oar." icon_state = "dragon_boat" -/obj/vehicle/ridden/lavaboat/dragon/Initialize() +/obj/vehicle/ridden/lavaboat/dragon/Initialize(mapload) . = ..() var/datum/component/riding/D = LoadComponent(/datum/component/riding) D.vehicle_move_delay = 1 diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm new file mode 100644 index 0000000000..f4ffda302e --- /dev/null +++ b/code/modules/vehicles/mecha/_mecha.dm @@ -0,0 +1,1227 @@ +/***************** WELCOME TO MECHA.DM, ENJOY YOUR STAY *****************/ + +/** + * Mechs are now (finally) vehicles, this means you can make them multicrew + * They can also grant select ability buttons based on occupant bitflags + * + * Movement is handled through vehicle_move() which is called by relaymove + * Clicking is done by way of signals registering to the entering mob + * NOTE: MMIS are NOT mobs but instead contain a brain that is, so you need special checks + * AI also has special checks becaus it gets in and out of the mech differently + * Always call remove_occupant(mob) when leaving the mech so the mob is removed properly + * + * For multi-crew, you need to set how the occupants recieve ability bitflags corresponding to their status on the vehicle(i.e: driver, gunner etc) + * Abilities can then be set to only apply for certain bitflags and are assigned as such automatically + * + * Clicks are wither translated into mech_melee_attack (see mech_melee_attack.dm) + * Or are used to call action() on equipped gear + * Cooldown for gear is on the mech because exploits + */ +/obj/vehicle/sealed/mecha + name = "mecha" + desc = "Exosuit" + icon = 'icons/mecha/mecha.dmi' + resistance_flags = FIRE_PROOF | ACID_PROOF + flags_1 = HEAR_1 + max_integrity = 300 + armor = list(MELEE = 20, BULLET = 10, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) + movedelay = 1 SECONDS + anchored = TRUE + emulate_door_bumps = TRUE + COOLDOWN_DECLARE(mecha_bump_smash) + var/light_on = FALSE + ///What direction will the mech face when entered/powered on? Defaults to South. + var/dir_in = SOUTH + ///How much energy the mech will consume each time it moves. This variable is a backup for when leg actuators affect the energy drain. + var/normal_step_energy_drain = 10 + ///How much energy the mech will consume each time it moves. this is the current active energy consumed + var/step_energy_drain = 10 + ///How much energy we drain each time we mechpunch someone + var/melee_energy_drain = 15 + ///The minimum amount of energy charge consumed by leg overload + var/overload_step_energy_drain_min = 100 + ///chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act. + var/deflect_chance = 10 + ///Modifiers for directional armor + var/list/facing_modifiers = list(MECHA_FRONT_ARMOUR = 1.5, MECHA_SIDE_ARMOUR = 1, MECHA_BACK_ARMOUR = 0.5) + ///if we cant use our equipment(such as due to EMP) + var/equipment_disabled = FALSE + /// Keeps track of the mech's cell + var/obj/item/stock_parts/cell/cell + /// Keeps track of the mech's scanning module + var/obj/item/stock_parts/scanning_module/scanmod + /// Keeps track of the mech's capacitor + var/obj/item/stock_parts/capacitor/capacitor + ///Whether the mechs maintenance protocols are on or off + var/construction_state = MECHA_LOCKED + ///Contains flags for the mecha + var/mecha_flags = ADDING_ACCESS_POSSIBLE | CANSTRAFE | IS_ENCLOSED | HAS_LIGHTS + ///Stores the DNA enzymes of a carbon so tht only they can access the mech + var/dna_lock + ///Spark effects are handled by this datum + var/datum/effect_system/spark_spread/spark_system = new + ///How powerful our lights are + var/lights_power = 6 + ///Just stop the mech from doing anything + var/completely_disabled = FALSE + ///Whether this mech is allowed to move diagonally + var/allow_diagonal_movement = TRUE + ///Whether or not the mech destroys walls by running into it. + var/bumpsmash = FALSE + + ///////////ATMOS + ///Whether we are currrently drawing from the internal tank + var/use_internal_tank = FALSE + ///The setting of the valve on the internal tank + var/internal_tank_valve = ONE_ATMOSPHERE + ///The internal air tank obj of the mech + var/obj/machinery/portable_atmospherics/canister/internal_tank + ///Internal air mix datum + var/datum/gas_mixture/cabin_air + ///The connected air port, if we have one + var/obj/machinery/atmospherics/components/unary/portables_connector/connected_port + + ///Special version of the radio, which is unsellable + var/obj/item/radio/mech/radio + var/list/trackers = list() + + var/max_temperature = 25000 + ///health percentage below which internal damage is possible + var/internal_damage_threshold = 50 + ///Bitflags for internal damage + var/internal_damage = NONE + + ///required access level for mecha operation + var/list/operation_req_access = list() + ///required access to change internal components + var/list/internals_req_access = list(ACCESS_ENGINE, ACCESS_ROBOTICS) + + ///Typepath for the wreckage it spawns when destroyed + var/wreckage + + var/list/equipment = new + ///Current active equipment + var/obj/item/mecha_parts/mecha_equipment/selected + ///Maximum amount of equipment we can have + var/max_equip = 3 + + ///Whether our steps are silent, for example in zero-G + var/step_silent = FALSE + ///Sound played when the mech moves + var/stepsound = 'sound/mecha/mechstep.ogg' + ///Sound played when the mech walks + var/turnsound = 'sound/mecha/mechturn.ogg' + + ///Cooldown duration between melee punches + var/melee_cooldown = 10 + + ///TIme taken to leave the mech + var/exit_delay = 2 SECONDS + ///Time you get slept for if you get forcible ejected by the mech exploding + var/destruction_sleep_duration = 2 SECONDS + ///Whether outside viewers can see the pilot inside + ///In case theres a different iconstate for AI/MMI pilot(currently only used for ripley) + var/silicon_icon_state = null + ///Currently ejecting, and unable to do things + var/is_currently_ejecting = FALSE + + var/datum/effect_system/smoke_spread/smoke_system = new + + ////Action vars + ///Ref to any active thrusters we might have + var/obj/item/mecha_parts/mecha_equipment/thrusters/active_thrusters + + ///Bool for energy shield on/off + var/defense_mode = FALSE + + ///Bool for leg overload on/off + var/leg_overload_mode = FALSE + ///Energy use modifier for leg overload + var/leg_overload_coeff = 100 + + //Bool for zoom on/off + var/zoom_mode = FALSE + + ///Remaining smoke charges + var/smoke_charges = 5 + ///Cooldown between using smoke + var/smoke_cooldown = 10 SECONDS + + ///Bool for if the mech is currently phasing + var/phasing = FALSE + ///Power we use every time we phaze through something + var/phasing_energy_drain = 200 + ///icon_state for flick() when phazing + var/phase_state = "" + + ///Wether we are strafing + var/strafe = FALSE + + ///Cooldown length between bumpsmashes + var/smashcooldown = 3 + + ///Bool for whether this mech can only be used on lavaland + var/lavaland_only = FALSE + + + hud_possible = list (DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_TRACK_HUD) + +/obj/item/radio/mech //this has to go somewhere + subspace_transmission = TRUE + +/obj/vehicle/sealed/mecha/Initialize(mapload) + . = ..() + add_radio() + add_cabin() + if(enclosed) + add_airtank() + RegisterSignal(src, COMSIG_MOVABLE_PRE_MOVE , .proc/disconnect_air) + RegisterSignal(src, COMSIG_MOVABLE_MOVED, .proc/play_stepsound) + spark_system.set_up(2, 0, src) + spark_system.attach(src) + smoke_system.set_up(3, src) + smoke_system.attach(src) + add_cell() + add_scanmod() + add_capacitor() + START_PROCESSING(SSobj, src) + GLOB.poi_list |= src + log_message("[src.name] created.", LOG_MECHA) + GLOB.mechas_list += src //global mech list + prepare_huds() + for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) + diag_hud.add_to_hud(src) + diag_hud_set_mechhealth() + diag_hud_set_mechcell() + diag_hud_set_mechstat() + update_icon() + +/obj/vehicle/sealed/mecha/Destroy() + for(var/ejectee in occupants) + mob_exit(ejectee, TRUE, TRUE) + if(LAZYLEN(equipment)) + for(var/obj/item/mecha_parts/mecha_equipment/equip as anything in equipment) + equip.detach(loc) + qdel(equip) + radio = null + + STOP_PROCESSING(SSobj, src) + LAZYCLEARLIST(equipment) + + QDEL_NULL(cell) + QDEL_NULL(scanmod) + QDEL_NULL(capacitor) + QDEL_NULL(internal_tank) + QDEL_NULL(cabin_air) + QDEL_NULL(spark_system) + QDEL_NULL(smoke_system) + + GLOB.poi_list -= src + GLOB.mechas_list -= src //global mech list + for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) + diag_hud.remove_from_hud(src) //YEET + return ..() + +/obj/vehicle/sealed/mecha/obj_destruction() + loc.assume_air(cabin_air) + air_update_turf(FALSE, FALSE) + for(var/mob/living/occupant as anything in occupants) + if(isAI(occupant)) + occupant.gib() //No wreck, no AI to recover + continue + mob_exit(occupant, FALSE, TRUE) + occupant.SetSleeping(destruction_sleep_duration) + return ..() + +/obj/vehicle/sealed/mecha/update_icon() + icon_state = get_mecha_occupancy_state() + return ..() + +//override this proc if you need to split up mecha control between multiple people (see savannah_ivanov.dm) +/obj/vehicle/sealed/mecha/auto_assign_occupant_flags(mob/M) + if(driver_amount() < max_drivers) + add_control_flags(M, FULL_MECHA_CONTROL) + +/obj/vehicle/sealed/mecha/proc/get_mecha_occupancy_state() + if((mecha_flags & SILICON_PILOT) && silicon_icon_state) + return silicon_icon_state + if(LAZYLEN(occupants)) + return initial(icon_state) + return "[initial(icon_state)]-open" + +/obj/vehicle/sealed/mecha/get_cell() + return cell + +/obj/vehicle/sealed/mecha/rust_heretic_act() + take_damage(500, BRUTE) + +/obj/vehicle/sealed/mecha/proc/restore_equipment() + equipment_disabled = FALSE + for(var/occupant in occupants) + var/mob/mob_occupant + SEND_SOUND(mob_occupant, sound('sound/items/timer.ogg', volume=50)) + to_chat(mob_occupant, "Equipment control unit has been rebooted successfully.
    ") + mob_occupant.update_mouse_pointer() + +/obj/vehicle/sealed/mecha/CheckParts(list/parts_list) + ..() + cell = locate(/obj/item/stock_parts/cell) in contents + scanmod = locate(/obj/item/stock_parts/scanning_module) in contents + capacitor = locate(/obj/item/stock_parts/capacitor) in contents + update_part_values() + +/obj/vehicle/sealed/mecha/proc/update_part_values() ///Updates the values given by scanning module and capacitor tier, called when a part is removed or inserted. + if(scanmod) + normal_step_energy_drain = initial(normal_step_energy_drain) * (1.5 / (scanmod.rating - 0.5)) //movement power cost is 3x of default at T1, 1x at T2, 0.6x at T3 and 0.4x at T4 + step_energy_drain = normal_step_energy_drain + else + normal_step_energy_drain = 500 + step_energy_drain = normal_step_energy_drain + if(capacitor) + armor = armor.modifyRating(energy = (capacitor.rating * 5)) //Each level of capacitor protects the mech against emp by 5% + else //because we can still be hit without a cap, even if we can't move + armor = armor.setRating(energy = 0) + + +//////////////////////// +////// Helpers ///////// +//////////////////////// + +/obj/vehicle/sealed/mecha/proc/add_airtank() + internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src) + return internal_tank + +///Adds a cell, for use in Map-spawned mechs, Nuke Ops mechs, and admin-spawned mechs. Mechs built by hand will replace this. +/obj/vehicle/sealed/mecha/proc/add_cell(obj/item/stock_parts/cell/C=null) + QDEL_NULL(cell) + if(C) + C.forceMove(src) + cell = C + return + cell = new /obj/item/stock_parts/cell/high/plus(src) + +///Adds a scanning module, for use in Map-spawned mechs, Nuke Ops mechs, and admin-spawned mechs. Mechs built by hand will replace this. +/obj/vehicle/sealed/mecha/proc/add_scanmod(obj/item/stock_parts/scanning_module/sm=null) + QDEL_NULL(scanmod) + if(sm) + sm.forceMove(src) + scanmod = sm + return + scanmod = new /obj/item/stock_parts/scanning_module(src) + +///Adds a capacitor, for use in Map-spawned mechs, Nuke Ops mechs, and admin-spawned mechs. Mechs built by hand will replace this. +/obj/vehicle/sealed/mecha/proc/add_capacitor(obj/item/stock_parts/capacitor/cap=null) + QDEL_NULL(capacitor) + if(cap) + cap.forceMove(src) + capacitor = cap + else + capacitor = new /obj/item/stock_parts/capacitor(src) + +/obj/vehicle/sealed/mecha/proc/add_cabin() + cabin_air = new(200) + cabin_air.set_temperature(T20C) + cabin_air.set_moles(GAS_O2,O2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature())) + cabin_air.set_moles(GAS_N2,N2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature())) + return cabin_air + +/obj/vehicle/sealed/mecha/proc/add_radio() + radio = new(src) + radio.name = "[src] radio" + radio.icon = icon + radio.icon_state = icon_state + radio.subspace_transmission = TRUE + +/obj/vehicle/sealed/mecha/proc/can_use(mob/user) + if(istype(user) && is_occupant(user)) + if(!user.incapacitated()) + return TRUE + return FALSE + +//////////////////////////////////////////////////////////////////////////////// + +/obj/vehicle/sealed/mecha/examine(mob/user) + . = ..() + var/integrity = obj_integrity*100/max_integrity + switch(integrity) + if(85 to 100) + . += "It's fully intact." + if(65 to 85) + . += "It's slightly damaged." + if(45 to 65) + . += "It's badly damaged." + if(25 to 45) + . += "It's heavily damaged." + else + . += "It's falling apart." + var/hide_weapon = locate(/obj/item/mecha_parts/concealed_weapon_bay) in contents + var/hidden_weapon = hide_weapon ? (locate(/obj/item/mecha_parts/mecha_equipment/weapon) in equipment) : null + var/list/visible_equipment = equipment - hidden_weapon + if(visible_equipment.len) + . += "It's equipped with:" + for(var/obj/item/mecha_parts/mecha_equipment/ME in visible_equipment) + . += "[icon2html(ME, user)] \A [ME]." + if(!enclosed) + if(mecha_flags & SILICON_PILOT) + . += "[src] appears to be piloting itself..." + else + for(var/occupante in occupants) + . += "You can see [occupante] inside." + if(ishuman(user)) + var/mob/living/carbon/human/H = user + for(var/O in H.held_items) + if(istype(O, /obj/item/gun)) + . += "It looks like you can hit the pilot directly if you target the center or above." + break //in case user is holding two guns + +//processing internal damage, temperature, air regulation, alert updates, lights power use. +/obj/vehicle/sealed/mecha/process() + var/internal_temp_regulation = 1 + + if(internal_damage) + if(internal_damage & MECHA_INT_FIRE) + if(!(internal_damage & MECHA_INT_TEMP_CONTROL) && prob(5)) + clearInternalDamage(MECHA_INT_FIRE) + if(internal_tank) + var/datum/gas_mixture/int_tank_air = internal_tank.return_air() + if(int_tank_air.return_pressure() > internal_tank.maximum_pressure && !(internal_damage & MECHA_INT_TANK_BREACH)) + setInternalDamage(MECHA_INT_TANK_BREACH) + if(int_tank_air && int_tank_air.return_volume() > 0) //heat the air_contents + int_tank_air.set_temperature(min(6000+T0C, int_tank_air.return_temperature()+rand(10,15))) + if(cabin_air && cabin_air.return_volume()>0) + cabin_air.set_temperature(min(6000+T0C, cabin_air.return_temperature()+rand(10,15))) + if(cabin_air.return_temperature() > max_temperature/2) + take_damage(4/round(max_temperature/cabin_air.return_temperature(),0.1), BURN, 0, 0) + + if(internal_damage & MECHA_INT_TEMP_CONTROL) + internal_temp_regulation = 0 + + if(internal_damage & MECHA_INT_TANK_BREACH) //remove some air from internal tank + if(internal_tank) + assume_air_ratio(internal_tank.return_air(), 0.1) + + if(internal_damage & MECHA_INT_SHORT_CIRCUIT) + if(get_charge()) + spark_system.start() + cell.charge -= min(20,cell.charge) + cell.maxcharge -= min(20,cell.maxcharge) + + if(internal_temp_regulation) + if(cabin_air && cabin_air.return_volume() > 0) + var/delta = cabin_air.return_temperature() - T20C + cabin_air.set_temperature(cabin_air.return_temperature() - max(-10, min(10, round(delta/4,0.1)))) + + if(internal_tank) + var/datum/gas_mixture/tank_air = internal_tank.return_air() + + var/release_pressure = internal_tank_valve + var/cabin_pressure = cabin_air.return_pressure() + var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2) + var/transfer_moles = 0 + if(pressure_delta > 0) //cabin pressure lower than release pressure + if(tank_air.return_temperature() > 0) + transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) + tank_air.transfer_to(cabin_air,transfer_moles) + else if(pressure_delta < 0) //cabin pressure higher than release pressure + var/datum/gas_mixture/t_air = return_air() + pressure_delta = cabin_pressure - release_pressure + if(t_air) + pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta) + if(pressure_delta > 0) //if location pressure is lower than cabin pressure + transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) + cabin_air.transfer_to(t_air, transfer_moles) + + if(occupants) + for(var/i in occupants) + var/mob/living/occupant = i + if(cell) + var/cellcharge = cell.charge/cell.maxcharge + switch(cellcharge) + if(0.75 to INFINITY) + occupant.clear_alert("charge") + if(0.5 to 0.75) + occupant.throw_alert("charge", /atom/movable/screen/alert/lowcell, 1) + if(0.25 to 0.5) + occupant.throw_alert("charge", /atom/movable/screen/alert/lowcell, 2) + if(0.01 to 0.25) + occupant.throw_alert("charge", /atom/movable/screen/alert/lowcell, 3) + else + occupant.throw_alert("charge", /atom/movable/screen/alert/emptycell) + + var/integrity = obj_integrity/max_integrity*100 + switch(integrity) + if(30 to 45) + occupant.throw_alert("mech damage", /atom/movable/screen/alert/low_mech_integrity, 1) + if(15 to 35) + occupant.throw_alert("mech damage", /atom/movable/screen/alert/low_mech_integrity, 2) + if(-INFINITY to 15) + occupant.throw_alert("mech damage", /atom/movable/screen/alert/low_mech_integrity, 3) + else + occupant.clear_alert("mech damage") + var/atom/checking = occupant.loc + // recursive check to handle all cases regarding very nested occupants, + // such as brainmob inside brainitem inside MMI inside mecha + while(!isnull(checking)) + if(isturf(checking)) + // hit a turf before hitting the mecha, seems like they have been moved out + occupant.clear_alert("charge") + occupant.clear_alert("mech damage") + occupant = null + break + else if (checking == src) + break // all good + checking = checking.loc + + if(mecha_flags & LIGHTS_ON) + var/lights_energy_drain = 2 + use_power(lights_energy_drain) + + for(var/b in occupants) + var/mob/living/occupant = b + if(!enclosed && occupant?.incapacitated()) //no sides mean it's easy to just sorta fall out if you're incapacitated. + visible_message("[occupant] tumbles out of the cockpit!") + mob_try_exit(occupant, TRUE, TRUE) //bye bye + +//Diagnostic HUD updates + diag_hud_set_mechhealth() + diag_hud_set_mechcell() + diag_hud_set_mechstat() + +/obj/vehicle/sealed/mecha/fire_act() //Check if we should ignite the pilot of an open-canopy mech + . = ..() + if(LAZYLEN(occupants) && !enclosed && !(mecha_flags & SILICON_PILOT)) + for(var/M in occupants) + var/mob/living/cookedalive = M + if(cookedalive.fire_stacks < 5) + cookedalive.fire_stacks += 1 + cookedalive.IgniteMob() + +/obj/vehicle/sealed/mecha/proc/display_speech_bubble(datum/source, list/speech_args) + SIGNAL_HANDLER + var/list/speech_bubble_recipients = get_hearers_in_view(7,src) + for(var/mob/M in speech_bubble_recipients) + if(M.client) + speech_bubble_recipients.Add(M.client) + INVOKE_ASYNC(GLOBAL_PROC, /proc/flick_overlay, image('icons/mob/talk.dmi', src, "machine[say_test(speech_args[SPEECH_MESSAGE])]",MOB_LAYER+1), speech_bubble_recipients, 30) + +//////////////////////////// +///// Action processing //// +//////////////////////////// + +/obj/vehicle/sealed/mecha/proc/on_mouseclick(mob/user, atom/target, params) + SIGNAL_HANDLER + if(!locate(/turf) in list(target,target.loc)) // Prevents inventory from being drilled + return + if(completely_disabled || is_currently_ejecting || (mecha_flags & CANNOT_INTERACT)) + return + var/list/mouse_control = params2list(params) + if(isAI(user) && !mouse_control["middle"])//AIs use MMB + return + if(phasing) + to_chat(occupants, "[icon2html(src, occupants)]Unable to interact with objects while phasing.") + return + if(user.incapacitated()) + return + if(construction_state) + to_chat(occupants, "[icon2html(src, occupants)]Maintenance protocols in effect.") + return + if(!get_charge()) + return + if(src == target) + return + var/dir_to_target = get_dir(src,target) + if(dir_to_target && !(dir_to_target & dir))//wrong direction + return + if(internal_damage & MECHA_INT_CONTROL_LOST) + target = pick(view(3,target)) + if(!target) + return + var/mob/living/L = user + if(selected) + if(!(L in return_controllers_with_flag(VEHICLE_CONTROL_EQUIPMENT))) + to_chat(user, "You can't control mech equipment from here!") + return + if(!Adjacent(target) && (selected.range & MECHA_RANGED)) + if(HAS_TRAIT(L, TRAIT_PACIFISM) && selected.harmful) + to_chat(L, "You don't want to harm other living beings!") + return + if(SEND_SIGNAL(src, COMSIG_MECHA_EQUIPMENT_CLICK, L, target) & COMPONENT_CANCEL_EQUIPMENT_CLICK) + return + INVOKE_ASYNC(selected, /obj/item/mecha_parts/mecha_equipment.proc/action, user, target, params) + return + if((selected.range & MECHA_MELEE) && Adjacent(target)) + if(isliving(target) && selected.harmful && HAS_TRAIT(L, TRAIT_PACIFISM)) + to_chat(L, "You don't want to harm other living beings!") + return + if(SEND_SIGNAL(src, COMSIG_MECHA_EQUIPMENT_CLICK, L, target) & COMPONENT_CANCEL_EQUIPMENT_CLICK) + return + INVOKE_ASYNC(selected, /obj/item/mecha_parts/mecha_equipment.proc/action, user, target, params) + return + if(!(L in return_controllers_with_flag(VEHICLE_CONTROL_MELEE))) + to_chat(L, "You're in the wrong seat to interact with your hands.") + return + var/on_cooldown = TIMER_COOLDOWN_CHECK(src, COOLDOWN_MECHA_MELEE_ATTACK) + var/adjacent = Adjacent(target) + if(SEND_SIGNAL(src, COMSIG_MECHA_MELEE_CLICK, L, target, on_cooldown, adjacent) & COMPONENT_CANCEL_MELEE_CLICK) + return + if(on_cooldown || !adjacent) + return + if(internal_damage & MECHA_INT_CONTROL_LOST) + var/list/possible_targets = oview(1,src) + if(!length(possible_targets)) + return + target = pick(possible_targets) + target.mech_melee_attack(src, user) + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MELEE_ATTACK, melee_cooldown) + + +////////////////////////////////// +//////// Movement procs //////// +////////////////////////////////// + +///Plays the mech step sound effect. Split from movement procs so that other mechs (HONK) can override this one specific part. +/obj/vehicle/sealed/mecha/proc/play_stepsound() + SIGNAL_HANDLER + if(stepsound) + playsound(src,stepsound,40,1) + +/obj/vehicle/sealed/mecha/proc/disconnect_air() + SIGNAL_HANDLER + if(internal_tank.disconnect()) // Something moved us and broke connection + to_chat(occupants, "[icon2html(src, occupants)]Air port connection has been severed!") + log_message("Lost connection to gas port.", LOG_MECHA) + +/obj/vehicle/sealed/mecha/Process_Spacemove(movement_dir = 0) + . = ..() + if(.) + return TRUE + + var/atom/movable/backup = get_spacemove_backup() + if(backup) + if(istype(backup) && movement_dir && !backup.anchored) + if(backup.newtonian_move(turn(movement_dir, 180))) + step_silent = TRUE + if(return_drivers()) + to_chat(occupants, "[icon2html(src, occupants)]The [src] push off [backup] to propel yourself.") + return TRUE + + if(movedelay <= world.time && active_thrusters && movement_dir && active_thrusters.thrust(movement_dir)) + step_silent = TRUE + return TRUE + + return FALSE + +/obj/vehicle/sealed/mecha/relaymove(mob/living/user, direction) + . = TRUE + if(!canmove || !(user in return_drivers())) + return + vehicle_move(direction) + + + +/obj/vehicle/sealed/mecha/vehicle_move(direction, forcerotate = FALSE) + if(!COOLDOWN_FINISHED(src, cooldown_vehicle_move)) + return FALSE + COOLDOWN_START(src, cooldown_vehicle_move, movedelay) + if(completely_disabled) + return FALSE + if(!direction) + return FALSE + if(internal_tank?.connected_port) + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_MECHA_MESSAGE)) + to_chat(occupants, "[icon2html(src, occupants)]Unable to move while connected to the air system port!") + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS) + return FALSE + if(construction_state) + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_MECHA_MESSAGE)) + to_chat(occupants, "[icon2html(src, occupants)]Maintenance protocols in effect.") + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS) + return FALSE + + if(!Process_Spacemove(direction)) + return FALSE + if(!has_charge(step_energy_drain)) + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_MECHA_MESSAGE)) + to_chat(occupants, "[icon2html(src, occupants)]Insufficient power to move!") + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS) + return FALSE + if(zoom_mode) + to_chat(occupants, "[icon2html(src, occupants)]Unable to move while in zoom mode!") + return FALSE + if(!cell) + to_chat(occupants, "[icon2html(src, occupants)]Missing power cell.") + return FALSE + if(!scanmod || !capacitor) + to_chat(occupants, "[icon2html(src, occupants)]Missing [scanmod? "capacitor" : "scanning module"].") + return FALSE + if(lavaland_only && !is_mining_level(z)) + to_chat(occupants, "[icon2html(src, occupants)]Invalid Environment.") + return FALSE + + var/olddir = dir + + if(internal_damage & MECHA_INT_CONTROL_LOST) + direction = pick(GLOB.alldirs) + + //only mechs with diagonal movement may move diagonally + if(!allow_diagonal_movement && ISDIAGONALDIR(direction)) + return TRUE + + //if we're not facing the way we're going rotate us + var/no_strafe = FALSE + if(dir != direction || forcerotate) + if(strafe) + for(var/D in return_drivers()) + var/mob/driver = D + if(driver.client?.keys_held["Alt"]) + no_strafe = TRUE + setDir(direction) + if(turnsound) + playsound(src,turnsound,40,TRUE) + return TRUE + else + setDir(direction) + if(turnsound) + playsound(src,turnsound,40,TRUE) + return TRUE + + set_glide_size(DELAY_TO_GLIDE_SIZE(movedelay)) + use_power(step_energy_drain) + //Otherwise just walk normally + . = step(src,direction, dir) + + if(strafe && !no_strafe) + setDir(olddir) + + +/obj/vehicle/sealed/mecha/Bump(atom/obstacle) + if(phasing && get_charge() >= phasing_energy_drain && !throwing) + if(phase_state) + flick(phase_state, src) + forceMove(get_step(src,dir))//This is jank I hate it thanks, this should be done thrugh move not this dumb shit + use_power(phasing_energy_drain) + addtimer(VARSET_CALLBACK(src, movedelay, TRUE), movedelay*3) + return + . = ..() + if(.) //mech was thrown/door/whatever + return + if(bumpsmash) //Need a pilot to push the PUNCH button. + if(COOLDOWN_FINISHED(src, mecha_bump_smash)) + obstacle.mech_melee_attack(src) + COOLDOWN_START(src, mecha_bump_smash, smashcooldown) + if(!obstacle || obstacle.CanPass(src,get_step(src,dir))) + step(src,dir) + if(isobj(obstacle)) + var/obj/obj_obstacle = obstacle + if(!obj_obstacle.anchored && obj_obstacle.move_resist <= move_force) + step(obstacle, dir) + else if(ismob(obstacle)) + var/mob/mob_obstacle = obstacle + if(mob_obstacle.move_resist <= move_force) + step(obstacle, dir) + + + + + +/////////////////////////////////// +//////// Internal damage //////// +/////////////////////////////////// + +/obj/vehicle/sealed/mecha/proc/check_for_internal_damage(list/possible_int_damage,ignore_threshold=null) + if(!islist(possible_int_damage) || !length(possible_int_damage)) + return + if(prob(20)) + if(ignore_threshold || obj_integrity*100/max_integrity < internal_damage_threshold) + for(var/T in possible_int_damage) + if(internal_damage & T) + possible_int_damage -= T + if (length(possible_int_damage)) + var/int_dam_flag = pick(possible_int_damage) + if(int_dam_flag) + setInternalDamage(int_dam_flag) + if(prob(5)) + if(ignore_threshold || obj_integrity*100/max_integrity < internal_damage_threshold) + if(LAZYLEN(equipment)) + var/obj/item/mecha_parts/mecha_equipment/ME = pick(equipment) + qdel(ME) + +/obj/vehicle/sealed/mecha/proc/setInternalDamage(int_dam_flag) + internal_damage |= int_dam_flag + log_message("Internal damage of type [int_dam_flag].", LOG_MECHA) + SEND_SOUND(occupants, sound('sound/machines/warning-buzzer.ogg',wait=0)) + diag_hud_set_mechstat() + +/obj/vehicle/sealed/mecha/proc/clearInternalDamage(int_dam_flag) + if(internal_damage & int_dam_flag) + switch(int_dam_flag) + if(MECHA_INT_TEMP_CONTROL) + to_chat(occupants, "[icon2html(src, occupants)]Life support system reactivated.") + if(MECHA_INT_FIRE) + to_chat(occupants, "[icon2html(src, occupants)]Internal fire extinguished.") + if(MECHA_INT_TANK_BREACH) + to_chat(occupants, "[icon2html(src, occupants)]Damaged internal tank has been sealed.") + internal_damage &= ~int_dam_flag + diag_hud_set_mechstat() + +///////////////////////////////////// +//////////// AI piloting //////////// +///////////////////////////////////// + +/obj/vehicle/sealed/mecha/attack_ai(mob/living/silicon/ai/user) + if(!isAI(user)) + return + //Allows the Malf to scan a mech's status and loadout, helping it to decide if it is a worthy chariot. + if(user.can_dominate_mechs) + examine(user) //Get diagnostic information! + for(var/obj/item/mecha_parts/mecha_tracking/B in trackers) + to_chat(user, "Warning: Tracking Beacon detected. Enter at your own risk. Beacon Data:") + to_chat(user, "[B.get_mecha_info()]") + break + //Nothing like a big, red link to make the player feel powerful! + to_chat(user, "ASSUME DIRECT CONTROL?
    ") + else + examine(user) + if(length(return_drivers()) > 0) + to_chat(user, "This exosuit has a pilot and cannot be controlled.") + return + var/can_control_mech = 0 + for(var/obj/item/mecha_parts/mecha_tracking/ai_control/A in trackers) + can_control_mech = 1 + to_chat(user, "[icon2html(src, user)] Status of [name]:\n[A.get_mecha_info()]") + break + if(!can_control_mech) + to_chat(user, "You cannot control exosuits without AI control beacons installed.") + return + to_chat(user, "Take control of exosuit?
    ") + +/obj/vehicle/sealed/mecha/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card) + if(!..()) + return + + //Transfer from core or card to mech. Proc is called by mech. + switch(interaction) + if(AI_TRANS_TO_CARD) //Upload AI from mech to AI card. + if(!construction_state) //Mech must be in maint mode to allow carding. + to_chat(user, "[name] must have maintenance protocols active in order to allow a transfer.") + return + if(!locate(AI) in occupants) //Mech does not have an AI for a pilot + to_chat(user, "No AI detected in the [name] onboard computer.") + return + for(var/mob/living/silicon/ai in occupants) + AI.ai_restore_power()//So the AI initially has power. + AI.control_disabled = TRUE + AI.radio_enabled = FALSE + AI.disconnect_shell() + remove_occupant(AI) + mecha_flags &= ~SILICON_PILOT + AI.forceMove(card) + card.AI = AI + AI.controlled_equipment = null + AI.remote_control = null + to_chat(AI, "You have been downloaded to a mobile storage device. Wireless connection offline.") + to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) removed from [name] and stored within local memory.") + + if(AI_MECH_HACK) //Called by AIs on the mech + AI.linked_core = new /obj/structure/AIcore/deactivated(AI.loc) + if(AI.can_dominate_mechs) + if(LAZYLEN(occupants)) //Oh, I am sorry, were you using that? + to_chat(AI, "Occupants detected! Forced ejection initiated!") + to_chat(occupants, "You have been forcibly ejected!") + ejectall() //IT IS MINE, NOW. SUCK IT, RD! + ai_enter_mech(AI, interaction) + + if(AI_TRANS_FROM_CARD) //Using an AI card to upload to a mech. + AI = card.AI + if(!AI) + to_chat(user, "There is no AI currently installed on this device.") + return + if(AI.deployed_shell) //Recall AI if shelled so it can be checked for a client + AI.disconnect_shell() + if(AI.stat || !AI.client) + to_chat(user, "[AI.name] is currently unresponsive, and cannot be uploaded.") + return + if((LAZYLEN(occupants) >= max_occupants) || dna_lock) //Normal AIs cannot steal mechs! + to_chat(user, "Access denied. [name] is [LAZYLEN(occupants) >= max_occupants ? "currently fully occupied" : "secured with a DNA lock"].") + return + AI.control_disabled = FALSE + AI.radio_enabled = TRUE + to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.") + card.AI = null + ai_enter_mech(AI, interaction) + +//Hack and From Card interactions share some code, so leave that here for both to use. +/obj/vehicle/sealed/mecha/proc/ai_enter_mech(mob/living/silicon/ai/AI, interaction) + AI.ai_restore_power() + mecha_flags |= SILICON_PILOT + moved_inside(AI) + AI.cancel_camera() + AI.controlled_equipment = src + AI.remote_control = src + AI.mobility_flags = ALL //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow. + if(interaction == AI_MECH_HACK) + AI.can_shunt = FALSE //ONE AI ENTERS. NO AI LEAVES. + to_chat(AI, AI.can_dominate_mechs ? "Takeover of [name] complete! You are now loaded onto the onboard computer. Do not attempt to leave the station sector!" :\ + "You have been uploaded to a mech's onboard computer.") + to_chat(AI, "Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions.") + + +///Handles an actual AI (simple_animal mecha pilot) entering the mech +/obj/vehicle/sealed/mecha/proc/aimob_enter_mech(mob/living/simple_animal/hostile/syndicate/mecha_pilot/pilot_mob) + if(pilot_mob && pilot_mob.Adjacent(src)) + if(LAZYLEN(occupants)) + return + LAZYADD(occupants, src) + pilot_mob.mecha = src + pilot_mob.forceMove(src) + update_icon() + +///Handles an actual AI (simple_animal mecha pilot) exiting the mech +/obj/vehicle/sealed/mecha/proc/aimob_exit_mech(mob/living/simple_animal/hostile/syndicate/mecha_pilot/pilot_mob) + LAZYREMOVE(occupants, pilot_mob) + if(pilot_mob.mecha == src) + pilot_mob.mecha = null + pilot_mob.forceMove(get_turf(src)) + update_icon() + + +///////////////////////////////////// +//////// Atmospheric stuff //////// +///////////////////////////////////// + +/obj/vehicle/sealed/mecha/remove_air(amount) + if(use_internal_tank) + return cabin_air.remove(amount) + return ..() + +/obj/vehicle/sealed/mecha/remove_air_ratio(ratio) + if(use_internal_tank) + return cabin_air.remove_ratio(ratio) + return ..() + + +/obj/vehicle/sealed/mecha/return_air() + if(use_internal_tank) + return cabin_air + return ..() + + +/obj/vehicle/sealed/mecha/proc/return_pressure() + var/datum/gas_mixture/t_air = return_air() + if(t_air) + . = t_air.return_pressure() + return + +/obj/vehicle/sealed/mecha/return_temperature() + var/datum/gas_mixture/t_air = return_air() + if(t_air) + . = t_air.return_temperature() + return + +/obj/vehicle/sealed/mecha/mob_try_enter(mob/M) + if(!ishuman(M)) // no silicons or drones in mechas. + return + log_message("[M] tries to move into [src].", LOG_MECHA) + if(dna_lock && M.has_dna()) + var/mob/living/carbon/entering_carbon = M + if(entering_carbon.dna.unique_enzymes != dna_lock) + to_chat(M, "Access denied. [name] is secured with a DNA lock.") + log_message("Permission denied (DNA LOCK).", LOG_MECHA) + return + if(!operation_allowed(M)) + to_chat(M, "Access denied. Insufficient operation keycodes.") + log_message("Permission denied (No keycode).", LOG_MECHA) + return + if(M.buckled) + to_chat(M, "You are currently buckled and cannot move.") + log_message("Permission denied (Buckled).", LOG_MECHA) + return + if(M.has_buckled_mobs()) //mob attached to us + to_chat(M, "You can't enter the exosuit with other creatures attached to you!") + log_message("Permission denied (Attached mobs).", LOG_MECHA) + return + + visible_message("[M] starts to climb into [name].") + + if(do_after(M, enter_delay, target = src)) + if(obj_integrity <= 0) + to_chat(M, "You cannot get in the [name], it has been destroyed!") + else if(LAZYLEN(occupants) >= max_occupants) + to_chat(M, "[occupants[occupants.len]] was faster! Try better next time, loser.")//get the last one that hopped in + else if(M.buckled) + to_chat(M, "You can't enter the exosuit while buckled.") + else if(M.has_buckled_mobs()) + to_chat(M, "You can't enter the exosuit with other creatures attached to you!") + else + moved_inside(M) + return ..() + else + to_chat(M, "You stop entering the exosuit!") + + +/obj/vehicle/sealed/mecha/generate_actions() + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_eject) // I don't see a single problem in generating exit vehicle action. + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_internals, VEHICLE_CONTROL_SETTINGS) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_cycle_equip, VEHICLE_CONTROL_EQUIPMENT) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_lights, VEHICLE_CONTROL_SETTINGS) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_view_stats, VEHICLE_CONTROL_SETTINGS) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/strafe, VEHICLE_CONTROL_DRIVE) + if(max_occupants > 1) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/swap_seat) + +/obj/vehicle/sealed/mecha/proc/moved_inside(mob/living/H) + . = FALSE + if(!(H?.client)) + return + if(ishuman(H) && !Adjacent(H)) + return + H.forceMove(src) + add_occupant(H) + add_fingerprint(H) + log_message("[H] moved in as pilot.", LOG_MECHA) + setDir(dir_in) + playsound(src, 'sound/machines/windowdoor.ogg', 50, TRUE) + if(!internal_damage) + SEND_SOUND(H, sound('sound/mecha/nominal.ogg',volume=50)) + return TRUE + +/obj/vehicle/sealed/mecha/proc/mmi_move_inside(obj/item/mmi/M, mob/user) + if(!M.brainmob || !M.brainmob.client) + to_chat(user, "Consciousness matrix not detected!") + return FALSE + else if(M.brainmob.stat) + to_chat(user, "Beta-rhythm below acceptable level!") + return FALSE + var/mob/living/brain/B = M.brainmob + if(LAZYLEN(occupants) >= max_occupants) + to_chat(user, "It's full!") + return FALSE + if(dna_lock && (!B.stored_dna || (dna_lock != B.stored_dna.unique_enzymes))) + to_chat(user, "Access denied. [name] is secured with a DNA lock.") + return FALSE + + visible_message("[user] starts to insert an MMI into [name].") + + if(do_after(user, 40, target = src)) + if(LAZYLEN(occupants) < max_occupants) + return mmi_moved_inside(M, user) + else + to_chat(user, "Maximum occupants detected!") + else + to_chat(user, "You stop inserting the MMI.") + return FALSE + +/obj/vehicle/sealed/mecha/proc/mmi_moved_inside(obj/item/mmi/M, mob/user) + if(!(Adjacent(M) && Adjacent(user))) + return FALSE + if(!M.brainmob || !M.brainmob.client) + to_chat(user, "Consciousness matrix not detected!") + return FALSE + else if(M.brainmob.stat) + to_chat(user, "Beta-rhythm below acceptable level!") + + var/mob/living/brain/B = M.brainmob + if(!user.transferItemToLoc(M, src)) + to_chat(user, "\the [M] is stuck to your hand, you cannot put it in \the [src]!") + return FALSE + + M.mecha = src + add_occupant(B)//Note this forcemoves the brain into the mech to allow relaymove + mecha_flags |= SILICON_PILOT + B.reset_perspective(src) + B.remote_control = src + B.update_mobility() + setDir(dir_in) + log_message("[M] moved in as pilot.", LOG_MECHA) + if(!internal_damage) + SEND_SOUND(M, sound('sound/mecha/nominal.ogg',volume=50)) + log_game("[key_name(user)] has put the MMI/posibrain of [key_name(B)] into [src] at [AREACOORD(src)]") + return TRUE + +/obj/vehicle/sealed/mecha/container_resist(mob/living/user) + if(isAI(user)) + var/mob/living/silicon/ai/AI = user + if(!AI.can_shunt) + to_chat(AI, "You can't leave a mech after dominating it!.") + return FALSE + to_chat(user, "You begin the ejection procedure. Equipment is disabled during this process. Hold still to finish ejecting.") + is_currently_ejecting = TRUE + if(do_after(user, exit_delay , target = src)) + to_chat(user, "You exit the mech.") + mob_try_exit(user, silent = FALSE) + else + to_chat(user, "You stop exiting the mech. Weapons are enabled again.") + is_currently_ejecting = FALSE + +/obj/vehicle/sealed/mecha/proc/ejectall() + for(var/ejectee in occupants) + mob_try_exit(ejectee, TRUE, TRUE) + +/obj/vehicle/sealed/mecha/mob_try_exit(mob/M, silent, randomstep) + mob_exit(M, silent, randomstep) + +/obj/vehicle/sealed/mecha/mob_exit(mob/M, silent, forced) + var/newloc = get_turf(src) + var/atom/movable/mob_container + if(ishuman(M)) + remove_occupant(M) + ..() + return + else if(isbrain(M)) + var/mob/living/brain/brain = M + mob_container = brain.container + else if(isAI(M)) + var/mob/living/silicon/ai/AI = M + if(forced)//This should only happen if there are multiple AIs in a round, and at least one is Malf. + AI.gib() //If one Malf decides to steal a mech from another AI (even other Malfs!), they are destroyed, as they have nowhere to go when replaced. + AI = null + mecha_flags &= ~SILICON_PILOT + return + else + if(!AI.linked_core) + to_chat(AI, "Inactive core destroyed. Unable to return.") + AI.linked_core = null + return + to_chat(AI, "Returning to core...") + AI.controlled_equipment = null + AI.remote_control = null + mob_container = AI + newloc = get_turf(AI.linked_core) + qdel(AI.linked_core) + else + return ..() + var/mob/living/L = M + mecha_flags &= ~SILICON_PILOT + if(mob_container.forceMove(newloc)) + log_message("[mob_container] moved out.", LOG_MECHA) + L << browse(null, "window=exosuit") + if(istype(mob_container, /obj/item/mmi)) + var/obj/item/mmi/mmi = mob_container + if(mmi.brainmob) + L.forceMove(mmi) + L.reset_perspective() + remove_occupant(L) + mmi.mecha = null + mmi.update_icon() + L.mobility_flags = NONE + setDir(dir_in) + return ..() + + +/obj/vehicle/sealed/mecha/add_occupant(mob/M, control_flags) + RegisterSignal(M, COMSIG_MOB_DEATH, .proc/mob_exit) + RegisterSignal(M, COMSIG_MOB_CLICKON, .proc/on_mouseclick) + RegisterSignal(M, COMSIG_MOB_SAY, .proc/display_speech_bubble) + return ..() + +/obj/vehicle/sealed/mecha/after_add_occupant(mob/M) + . = ..() + update_icon() + M.update_mouse_pointer() + +/obj/vehicle/sealed/mecha/remove_occupant(mob/M) + UnregisterSignal(M, COMSIG_MOB_DEATH) + UnregisterSignal(M, COMSIG_MOB_CLICKON) + UnregisterSignal(M, COMSIG_MOB_SAY) + M.clear_alert("charge") + M.clear_alert("mech damage") + if(M.client) + M.client.view_size.resetToDefault() + zoom_mode = 0 + return ..() + +/obj/vehicle/sealed/mecha/after_remove_occupant(mob/M) + . = ..() + update_icon() + M.update_mouse_pointer() + +///////////////////////// +////// Access stuff ///// +///////////////////////// + +/obj/vehicle/sealed/mecha/proc/operation_allowed(mob/M) + req_access = operation_req_access + req_one_access = list() + return allowed(M) + +/obj/vehicle/sealed/mecha/proc/internals_access_allowed(mob/M) + req_one_access = internals_req_access + req_access = list() + return allowed(M) + + +/////////////////////// +///// Power stuff ///// +/////////////////////// + +/obj/vehicle/sealed/mecha/proc/has_charge(amount) + return (get_charge()>=amount) + +/obj/vehicle/sealed/mecha/proc/get_charge() + for(var/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/R in equipment) + var/relay_charge = R.get_charge() + if(relay_charge) + return relay_charge + if(cell) + return max(0, cell.charge) + +/obj/vehicle/sealed/mecha/proc/use_power(amount) + if(get_charge() && cell.use(amount)) + return TRUE + return FALSE + +/obj/vehicle/sealed/mecha/proc/give_power(amount) + if(!isnull(get_charge())) + cell.give(amount) + return TRUE + return FALSE + +/////////////////////// +////// Ammo stuff ///// +/////////////////////// + +/obj/vehicle/sealed/mecha/proc/ammo_resupply(obj/item/mecha_ammo/A, mob/user,fail_chat_override = FALSE) + if(!A.rounds) + if(!fail_chat_override) + to_chat(user, "This box of ammo is empty!") + return FALSE + var/ammo_needed + var/found_gun + for(var/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/gun in equipment) + ammo_needed = 0 + + if(istype(gun, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic) && gun.ammo_type == A.ammo_type) + found_gun = TRUE + if(A.direct_load) + ammo_needed = initial(gun.projectiles) - gun.projectiles + else + ammo_needed = gun.projectiles_cache_max - gun.projectiles_cache + + if(ammo_needed) + if(ammo_needed < A.rounds) + if(A.direct_load) + gun.projectiles = gun.projectiles + ammo_needed + else + gun.projectiles_cache = gun.projectiles_cache + ammo_needed + playsound(get_turf(user),A.load_audio,50,TRUE) + to_chat(user, "You add [ammo_needed] [A.round_term][ammo_needed > 1?"s":""] to the [gun.name]") + A.rounds = A.rounds - ammo_needed + A.update_name() + return TRUE + + else + if(A.direct_load) + gun.projectiles = gun.projectiles + A.rounds + else + gun.projectiles_cache = gun.projectiles_cache + A.rounds + playsound(get_turf(user),A.load_audio,50,TRUE) + to_chat(user, "You add [A.rounds] [A.round_term][A.rounds > 1?"s":""] to the [gun.name]") + A.rounds = 0 + A.update_name() + return TRUE + if(!fail_chat_override) + if(found_gun) + to_chat(user, "You can't fit any more ammo of this type!") + else + to_chat(user, "None of the equipment on this exosuit can use this ammo!") + return FALSE diff --git a/code/modules/vehicles/mecha/combat/combat.dm b/code/modules/vehicles/mecha/combat/combat.dm new file mode 100644 index 0000000000..b5479c6867 --- /dev/null +++ b/code/modules/vehicles/mecha/combat/combat.dm @@ -0,0 +1,18 @@ +/obj/vehicle/sealed/mecha/combat + force = 30 + internals_req_access = list(ACCESS_ROBOTICS, ACCESS_SECURITY) + internal_damage_threshold = 50 + armor = list(MELEE = 30, BULLET = 30, LASER = 15, ENERGY = 20, BOMB = 20, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) + mouse_pointer = 'icons/mecha/mecha_mouse.dmi' + destruction_sleep_duration = 40 + exit_delay = 40 + +/obj/vehicle/sealed/mecha/combat/restore_equipment() + mouse_pointer = 'icons/mecha/mecha_mouse.dmi' + . = ..() + +/obj/vehicle/sealed/mecha/combat/proc/max_ammo() //Max the ammo stored for Nuke Ops mechs, or anyone else that calls this + for(var/obj/item/I in equipment) + if(istype(I, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/)) + var/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/gun = I + gun.projectiles_cache = gun.projectiles_cache_max diff --git a/code/modules/vehicles/mecha/combat/durand.dm b/code/modules/vehicles/mecha/combat/durand.dm new file mode 100644 index 0000000000..36c5f75984 --- /dev/null +++ b/code/modules/vehicles/mecha/combat/durand.dm @@ -0,0 +1,241 @@ +/obj/vehicle/sealed/mecha/combat/durand + desc = "An aging combat exosuit utilized by the Nanotrasen corporation. Originally developed to combat hostile alien lifeforms." + name = "\improper Durand" + icon_state = "durand" + movedelay = 4 + dir_in = 1 //Facing North. + max_integrity = 400 + deflect_chance = 20 + armor = list(MELEE = 40, BULLET = 35, LASER = 15, ENERGY = 10, BOMB = 20, BIO = 0, RAD = 50, FIRE = 100, ACID = 100) + max_temperature = 30000 + force = 40 + wreckage = /obj/structure/mecha_wreckage/durand + var/obj/durand_shield/shield + + +/obj/vehicle/sealed/mecha/combat/durand/Initialize(mapload) + . = ..() + shield = new /obj/durand_shield(loc, src, layer, dir) + RegisterSignal(src, COMSIG_MECHA_ACTION_TRIGGER, .proc/relay) + RegisterSignal(src, COMSIG_PROJECTILE_PREHIT, .proc/prehit) + + +/obj/vehicle/sealed/mecha/combat/durand/Destroy() + if(shield) + QDEL_NULL(shield) + return ..() + + +/obj/vehicle/sealed/mecha/combat/durand/generate_actions() + . = ..() + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_defense_mode) + +/obj/vehicle/sealed/mecha/combat/durand/process() + . = ..() + if(defense_mode && !use_power(100)) //Defence mode can only be on with a occupant so we check if one of them can toggle it and toggle + for(var/O in occupants) + var/mob/living/occupant = O + var/datum/action/action = LAZYACCESSASSOC(occupant_actions, occupant, /datum/action/vehicle/sealed/mecha/mech_defense_mode) + if(action) + INVOKE_ASYNC(action, /datum/action.proc/Trigger) + break + +/obj/vehicle/sealed/mecha/combat/durand/Move(direction) + . = ..() + if(shield) + shield.forceMove(loc) + shield.setDir(dir) + +/obj/vehicle/sealed/mecha/combat/durand/forceMove(turf/T) + . = ..() + shield.forceMove(T) + +/obj/vehicle/sealed/mecha/combat/durand/mob_exit(mob/M, silent, randomstep, forced) + if(defense_mode) + var/datum/action/action = LAZYACCESSASSOC(occupant_actions, M, /datum/action/vehicle/sealed/mecha/mech_defense_mode) + if(action) + INVOKE_ASYNC(action, /datum/action.proc/Trigger, FALSE) + return ..() + +///Relays the signal from the action button to the shield, and creates a new shield if the old one is MIA. +/obj/vehicle/sealed/mecha/combat/durand/proc/relay(datum/source, mob/owner, list/signal_args) + SIGNAL_HANDLER + if(!shield) //if the shield somehow got deleted + stack_trace("Durand triggered relay without a shield") + shield = new /obj/durand_shield(loc, src, layer) + shield.setDir(dir) + SEND_SIGNAL(shield, COMSIG_MECHA_ACTION_TRIGGER, owner, signal_args) + +//Redirects projectiles to the shield if defense_check decides they should be blocked and returns true. +/obj/vehicle/sealed/mecha/combat/durand/proc/prehit(obj/item/projectile/source, list/signal_args) + if(defense_check(source.loc) && shield) + signal_args[2] = shield + + +/**Checks if defense mode is enabled, and if the attacker is standing in an area covered by the shield. +Expects a turf. Returns true if the attack should be blocked, false if not.*/ +/obj/vehicle/sealed/mecha/combat/durand/proc/defense_check(turf/aloc) + if (!defense_mode || !shield || shield.switching) + return FALSE + . = FALSE + switch(dir) + if (1) + if(abs(x - aloc.x) <= (y - aloc.y) * -2) + . = TRUE + if (2) + if(abs(x - aloc.x) <= (y - aloc.y) * 2) + . = TRUE + if (4) + if(abs(y - aloc.y) <= (x - aloc.x) * -2) + . = TRUE + if (8) + if(abs(y - aloc.y) <= (x - aloc.x) * 2) + . = TRUE + return + +/obj/vehicle/sealed/mecha/combat/durand/attack_generic(mob/user, damage_amount = 0, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, armor_penetration = 0) + if(defense_check(user.loc)) + log_message("Attack absorbed by defense field. Attacker - [user].", LOG_MECHA, color="orange") + shield.attack_generic(user, damage_amount, damage_type, damage_flag, sound_effect, armor_penetration) + else + . = ..() + +/obj/vehicle/sealed/mecha/combat/durand/blob_act(obj/structure/blob/B) + if(defense_check(B.loc)) + log_message("Attack by blob. Attacker - [B].", LOG_MECHA, color="red") + log_message("Attack absorbed by defense field.", LOG_MECHA, color="orange") + shield.blob_act(B) + else + . = ..() + +/obj/vehicle/sealed/mecha/combat/durand/attackby(obj/item/W as obj, mob/user as mob, params) + if(defense_check(user.loc)) + log_message("Attack absorbed by defense field. Attacker - [user], with [W]", LOG_MECHA, color="orange") + shield.attackby(W, user, params) + else + . = ..() + +/obj/vehicle/sealed/mecha/combat/durand/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) + if(defense_check(AM.loc)) + log_message("Impact with [AM] absorbed by defense field.", LOG_MECHA, color="orange") + shield.hitby(AM, skipcatch, hitpush, blocked, throwingdatum) + else + . = ..() + +//////////////////////////// +///// Shield processing //// +//////////////////////////// + +/**An object to take the hit for us when using the Durand's defense mode. +It is spawned in during the durand's initilization, and always stays on the same tile. +Normally invisible, until defense mode is actvated. When the durand detects an attack that should be blocked, the +attack is passed to the shield. The shield takes the damage, uses it to calculate charge cost, and then sets its +own integrity back to max. Shield is automatically dropped if we run out of power or the user gets out.*/ + +/obj/durand_shield //projectiles get passed to this when defense mode is enabled + name = "defense grid" + icon = 'icons/mecha/durand_shield.dmi' + icon_state = "shield_null" + invisibility = INVISIBILITY_MAXIMUM //no showing on right-click + pixel_y = 4 + max_integrity = 10000 + obj_integrity = 10000 + anchored = TRUE + light_range = MINIMUM_USEFUL_LIGHT_RANGE + light_power = 5 + light_color = COLOR_CYAN + ///Our link back to the durand + var/obj/vehicle/sealed/mecha/combat/durand/chassis + ///To keep track of things during the animation + var/switching = FALSE + var/currentuser + + +/obj/durand_shield/Initialize(mapload, _chassis, _layer, _dir) + . = ..() + chassis = _chassis + layer = _layer + setDir(_dir) + RegisterSignal(src, COMSIG_MECHA_ACTION_TRIGGER, .proc/activate) + + +/obj/durand_shield/Destroy() + if(chassis) + chassis.shield = null + chassis = null + return ..() + +/** + *Handles activating and deactivating the shield. This proc is called by a signal sent from the mech's action button + *and relayed by the mech itself. The "forced" variabe, signal_args[1], will skip the to-pilot text and is meant for when + *the shield is disabled by means other than the action button (like running out of power) + * Arguments: + * * source: the shield + * * owner: mob that activated the shield + * * signal_args: whether it's forced + */ +/obj/durand_shield/proc/activate(datum/source, mob/owner, list/signal_args) + SIGNAL_HANDLER + currentuser = owner + if(!chassis?.occupants) + return + if(switching && !signal_args[1]) + return + if(!chassis.defense_mode && (!chassis.cell || chassis.cell.charge < 100)) //If it's off, and we have less than 100 units of power + to_chat(currentuser, "[icon2html(src, currentuser)]Insufficient power; cannot activate defense mode.") + return + switching = TRUE + chassis.defense_mode = !chassis.defense_mode + if(!signal_args[1]) + to_chat(currentuser, "[icon2html(src, currentuser)]Defense mode [chassis.defense_mode?"enabled":"disabled"].") + chassis.log_message("User has toggled defense mode -- now [chassis.defense_mode?"enabled":"disabled"].", LOG_MECHA) + else + chassis.log_message("defense mode state changed -- now [chassis.defense_mode?"enabled":"disabled"].", LOG_MECHA) + for(var/occupant in chassis.occupants) + var/datum/action/button = chassis.occupant_actions[occupant][/datum/action/vehicle/sealed/mecha/mech_defense_mode] + button.button_icon_state = "mech_defense_mode_[chassis.defense_mode ? "on" : "off"]" + button.UpdateButtonIcon() + + set_light(light_range, light_power, light_color) + + if(chassis.defense_mode) + invisibility = 0 + flick("shield_raise", src) + playsound(src, 'sound/mecha/mech_shield_raise.ogg', 50, FALSE) + set_light(l_range = MINIMUM_USEFUL_LIGHT_RANGE , l_power = 5, l_color = "#00FFFF") + icon_state = "shield" + RegisterSignal(chassis, COMSIG_ATOM_DIR_CHANGE, .proc/resetdir) + else + flick("shield_drop", src) + playsound(src, 'sound/mecha/mech_shield_drop.ogg', 50, FALSE) + set_light(0) + icon_state = "shield_null" + invisibility = INVISIBILITY_MAXIMUM //no showing on right-click + UnregisterSignal(chassis, COMSIG_ATOM_DIR_CHANGE) + switching = FALSE + +/obj/durand_shield/proc/resetdir(datum/source, olddir, newdir) + setDir(newdir) + +/obj/durand_shield/take_damage() + if(!chassis) + qdel(src) + return + if(!chassis.defense_mode) //if defense mode is disabled, we're taking damage that we shouldn't be taking + return + . = ..() + flick("shield_impact", src) + if(!chassis.use_power((max_integrity - obj_integrity) * 100)) + chassis.cell?.charge = 0 + for(var/O in chassis.occupants) + var/mob/living/occupant = O + var/datum/action/action = LAZYACCESSASSOC(chassis.occupant_actions, occupant, /datum/action/vehicle/sealed/mecha/mech_defense_mode) + action.Trigger(FALSE) + obj_integrity = 10000 + +/obj/durand_shield/play_attack_sound() + playsound(src, 'sound/mecha/mech_shield_deflect.ogg', 100, TRUE) + +/obj/durand_shield/bullet_act() + play_attack_sound() + . = ..() diff --git a/code/modules/vehicles/mecha/combat/five_stars.dm b/code/modules/vehicles/mecha/combat/five_stars.dm new file mode 100644 index 0000000000..def8e94cc8 --- /dev/null +++ b/code/modules/vehicles/mecha/combat/five_stars.dm @@ -0,0 +1,20 @@ +/obj/vehicle/sealed/mecha/combat/five_stars + desc = "A state of the art tank deployed by the Spinward Stellar Coalition National Guard." + name = "\improper Tank" + icon = 'icons/mecha/mecha_96x96.dmi' + icon_state = "five_stars" + armor = list(MELEE = 100, BULLET = 50, LASER = 35, ENERGY = 35, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) + dir_in = 1 //Facing North. + max_integrity = 800 + pixel_x = -32 + pixel_y = -32 + +/obj/vehicle/sealed/mecha/combat/five_stars/Initialize(mapload) + . = ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/spacecops(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) + ME.attach(src) + max_ammo() diff --git a/code/modules/vehicles/mecha/combat/gygax.dm b/code/modules/vehicles/mecha/combat/gygax.dm new file mode 100644 index 0000000000..ae7f846142 --- /dev/null +++ b/code/modules/vehicles/mecha/combat/gygax.dm @@ -0,0 +1,61 @@ +/obj/vehicle/sealed/mecha/combat/gygax + desc = "A lightweight, security exosuit. Popular among private and corporate security." + name = "\improper Gygax" + icon_state = "gygax" + allow_diagonal_movement = TRUE + movedelay = 3 + dir_in = 1 //Facing North. + max_integrity = 250 + deflect_chance = 5 + armor = list(MELEE = 25, BULLET = 20, LASER = 30, ENERGY = 15, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) + max_temperature = 25000 + leg_overload_coeff = 300 + overload_step_energy_drain_min = 300 + force = 25 + wreckage = /obj/structure/mecha_wreckage/gygax + internal_damage_threshold = 35 + max_equip = 3 + normal_step_energy_drain = 3 + +/obj/vehicle/sealed/mecha/combat/gygax/dark + desc = "A lightweight exosuit, painted in a dark scheme. This model appears to have some modifications." + name = "\improper Dark Gygax" + icon_state = "darkgygax" + max_integrity = 300 + deflect_chance = 20 + armor = list(MELEE = 40, BULLET = 40, LASER = 50, ENERGY = 35, BOMB = 20, BIO = 0, RAD =20, FIRE = 100, ACID = 100) + max_temperature = 35000 + leg_overload_coeff = 100 + overload_step_energy_drain_min = 100 + force = 30 + operation_req_access = list(ACCESS_SYNDICATE) + internals_req_access = list(ACCESS_SYNDICATE) + wreckage = /obj/structure/mecha_wreckage/gygax/dark + max_equip = 5 + destruction_sleep_duration = 20 + +/obj/vehicle/sealed/mecha/combat/gygax/dark/loaded/Initialize(mapload) + . = ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/thrusters/ion(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay + ME.attach(src) + max_ammo() + +/obj/vehicle/sealed/mecha/combat/gygax/dark/add_cell(obj/item/stock_parts/cell/C=null) + if(C) + C.forceMove(src) + cell = C + return + cell = new /obj/item/stock_parts/cell/bluespace(src) + + +/obj/vehicle/sealed/mecha/combat/gygax/generate_actions() + . = ..() + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_overload_mode) diff --git a/code/game/mecha/combat/honker.dm b/code/modules/vehicles/mecha/combat/honker.dm similarity index 63% rename from code/game/mecha/combat/honker.dm rename to code/modules/vehicles/mecha/combat/honker.dm index 89b641ccc6..7373469614 100644 --- a/code/game/mecha/combat/honker.dm +++ b/code/modules/vehicles/mecha/combat/honker.dm @@ -1,22 +1,21 @@ -/obj/mecha/combat/honker +/obj/vehicle/sealed/mecha/combat/honker desc = "Produced by \"Tyranny of Honk, INC\", this exosuit is designed as heavy clown-support. Used to spread the fun and joy of life. HONK!" name = "\improper H.O.N.K" icon_state = "honker" - step_in = 3 + movedelay = 3 max_integrity = 140 deflect_chance = 60 internal_damage_threshold = 60 - armor = list("melee" = -20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = -20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) max_temperature = 25000 - infra_luminosity = 5 operation_req_access = list(ACCESS_THEATRE) - internals_req_access = list(ACCESS_THEATRE, ACCESS_ROBOTICS) + internals_req_access = list(ACCESS_ROBOTICS, ACCESS_THEATRE) wreckage = /obj/structure/mecha_wreckage/honker - add_req_access = 0 + mecha_flags = CANSTRAFE | IS_ENCLOSED | HAS_LIGHTS max_equip = 3 - var/squeak = 0 + var/squeak = TRUE -/obj/mecha/combat/honker/get_stats_part() +/obj/vehicle/sealed/mecha/combat/honker/get_stats_part(mob/user) var/integrity = obj_integrity/max_integrity*100 var/cell_charge = get_charge() var/datum/gas_mixture/int_tank_air = internal_tank.return_air() @@ -29,18 +28,18 @@ [internal_damage&MECHA_INT_TANK_BREACH?"GAS TANK HONK
    ":null] [internal_damage&MECHA_INT_CONTROL_LOST?"HONK-A-DOODLE - Recalibrate
    ":null] IntegriHONK: [integrity]%
    - PowerHONK charge: [isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]
    + PowerHONK charge: [isnull(cell_charge)?"No power cell installed":"[cell.percent()]%"]
    Air source: [use_internal_tank?"Internal Airtank":"Environment"]
    AirHONK pressure: [tank_pressure]kPa
    AirHONK temperature: [tank_temperature]°K|[tank_temperature - T0C]°C
    HONK pressure: [cabin_pressure>WARNING_HIGH_PRESSURE ? "[cabin_pressure]": cabin_pressure]kPa
    HONK temperature: [return_temperature()]°K|[return_temperature() - T0C]°C
    - Lights: [lights?"on":"off"]
    + Lights: [(mecha_flags & LIGHTS_ON)?"on":"off"]
    [dna_lock?"DNA-locked:
    [dna_lock] \[Reset\]
    ":null] "} return output -/obj/mecha/combat/honker/get_stats_html() +/obj/vehicle/sealed/mecha/combat/honker/get_stats_html(mob/user) var/output = {" @@ -60,19 +59,19 @@ [js_byjax] [js_dropdowns] function SSticker() { - setInterval(function(){ - window.location='byond://?src=[REF(src)]&update_content=1'; - document.body.style.color = get_rand_color_string(); - document.body.style.background = get_rand_color_string(); - }, 1000); + setInterval(function(){ + window.location='byond://?src=[REF(src)]&update_content=1'; + document.body.style.color = get_rand_color_string(); + document.body.style.background = get_rand_color_string(); + }, 1000); } function get_rand_color_string() { - var color = new Array; - for(var i=0;i<3;i++){ - color.push(Math.floor(Math.random()*255)); - } - return "rgb("+color.toString()+")"; + var color = new Array; + for(var i=0;i<3;i++){ + color.push(Math.floor(Math.random()*255)); + } + return "rgb("+color.toString()+")"; } window.onload = function() { @@ -83,7 +82,7 @@
    - [src.get_stats_part()] + [src.get_stats_part(user)]
    [src.get_equipment_list()] @@ -97,7 +96,7 @@ "} return output -/obj/mecha/combat/honker/get_commands() +/obj/vehicle/sealed/mecha/combat/honker/get_commands() var/output = {" "} @@ -113,8 +120,8 @@ return output -/obj/mecha/combat/honker/get_equipment_list() - if(!equipment.len) +/obj/vehicle/sealed/mecha/combat/honker/get_equipment_list() + if(!LAZYLEN(equipment)) return var/output = "Honk-ON-Systems:
    " for(var/obj/item/mecha_parts/mecha_equipment/MT in equipment) @@ -122,19 +129,12 @@ output += "
    " return output +/obj/vehicle/sealed/mecha/combat/honker/play_stepsound() + if(squeak) + playsound(src, "clownstep", 70, 1) + squeak = !squeak - -/obj/mecha/combat/honker/mechstep(direction) - var/result = step(src,direction) - if(result) - if(!squeak) - playsound(src, "clownstep", 70, 1) - squeak = 1 - else - squeak = 0 - return result - -/obj/mecha/combat/honker/Topic(href, href_list) +/obj/vehicle/sealed/mecha/combat/honker/Topic(href, href_list) ..() if (href_list["play_sound"]) switch(href_list["play_sound"]) @@ -148,11 +148,20 @@ playsound(src, 'sound/items/carhorn.ogg', 80) //soundfile has lower than average volume if("party_horn") playsound(src, 'sound/items/party_horn.ogg', 50) + if("reee") + playsound(src, 'sound/effects/reee.ogg', 50) + if("weeoo1") + playsound(src, 'sound/items/weeoo1.ogg', 50) + if("hiss1") + playsound(src, 'sound/voice/hiss1.ogg', 50) + if("armbomb") + playsound(src, 'sound/weapons/armbomb.ogg', 50) + if("saberon") + playsound(src, 'sound/weapons/saberon.ogg', 50) + if("airlock_alien_prying") + playsound(src, 'sound/machines/airlock_alien_prying.ogg', 50) + if("lightningbolt") + playsound(src, 'sound/magic/lightningbolt.ogg', 50) + if("explosionfar") + playsound(src, 'sound/effects/explosionfar.ogg', 50) return - -/proc/rand_hex_color() - var/list/colors = list("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f") - var/color="" - for (var/i=0;i<6;i++) - color = color+pick(colors) - return color diff --git a/code/game/mecha/combat/marauder.dm b/code/modules/vehicles/mecha/combat/marauder.dm similarity index 61% rename from code/game/mecha/combat/marauder.dm rename to code/modules/vehicles/mecha/combat/marauder.dm index 5c60a97864..0919b71826 100644 --- a/code/game/mecha/combat/marauder.dm +++ b/code/modules/vehicles/mecha/combat/marauder.dm @@ -1,38 +1,32 @@ -/obj/mecha/combat/marauder +/obj/vehicle/sealed/mecha/combat/marauder desc = "Heavy-duty, combat exosuit, developed after the Durand model. Rarely found among civilian populations." name = "\improper Marauder" icon_state = "marauder" - step_in = 5 + movedelay = 5 max_integrity = 500 deflect_chance = 25 - armor = list("melee" = 50, "bullet" = 55, "laser" = 40, "energy" = 30, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 50, BULLET = 55, LASER = 40, ENERGY = 30, BOMB = 30, BIO = 0, RAD = 60, FIRE = 100, ACID = 100) max_temperature = 60000 resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - infra_luminosity = 3 operation_req_access = list(ACCESS_CENT_SPECOPS) - internals_req_access = list(ACCESS_CENT_SPECOPS, ACCESS_ROBOTICS) + internals_req_access = list(ACCESS_CENT_SPECOPS) wreckage = /obj/structure/mecha_wreckage/marauder - add_req_access = 0 + mecha_flags = CANSTRAFE | IS_ENCLOSED | HAS_LIGHTS internal_damage_threshold = 25 force = 45 - max_equip = 4 - bumpsmash = 1 + max_equip = 5 + bumpsmash = TRUE -/obj/mecha/combat/marauder/GrantActions(mob/living/user, human_occupant = 0) - ..() - smoke_action.Grant(user, src) - thrusters_action.Grant(user, src) - zoom_action.Grant(user, src) - -/obj/mecha/combat/marauder/RemoveActions(mob/living/user, human_occupant = 0) - ..() - smoke_action.Remove(user) - thrusters_action.Remove(user) - zoom_action.Remove(user) - -/obj/mecha/combat/marauder/loaded/Initialize() +/obj/vehicle/sealed/mecha/combat/marauder/generate_actions() . = ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse(src) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_smoke) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_zoom) + +/obj/vehicle/sealed/mecha/combat/marauder/loaded/Initialize(mapload) + . = ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/thrusters/ion(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse(src) ME.attach(src) ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack(src) ME.attach(src) @@ -42,23 +36,24 @@ ME.attach(src) max_ammo() -/obj/mecha/combat/marauder/seraph +/obj/vehicle/sealed/mecha/combat/marauder/seraph desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel." name = "\improper Seraph" icon_state = "seraph" operation_req_access = list(ACCESS_CENT_SPECOPS) - internals_req_access = list(ACCESS_CENT_SPECOPS, ACCESS_ROBOTICS) - step_in = 3 + internals_req_access = list(ACCESS_CENT_SPECOPS) + movedelay = 3 max_integrity = 550 wreckage = /obj/structure/mecha_wreckage/seraph internal_damage_threshold = 20 force = 55 - max_equip = 5 + max_equip = 6 -/obj/mecha/combat/marauder/seraph/Initialize() +/obj/vehicle/sealed/mecha/combat/marauder/seraph/Initialize(mapload) . = ..() - var/obj/item/mecha_parts/mecha_equipment/ME - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot(src) + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/thrusters/ion(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse(src) ME.attach(src) ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack(src) ME.attach(src) @@ -70,16 +65,22 @@ ME.attach(src) max_ammo() -/obj/mecha/combat/marauder/mauler +/obj/vehicle/sealed/mecha/combat/marauder/mauler desc = "Heavy-duty, combat exosuit, developed off of the existing Marauder model." name = "\improper Mauler" icon_state = "mauler" operation_req_access = list(ACCESS_SYNDICATE) internals_req_access = list(ACCESS_SYNDICATE) wreckage = /obj/structure/mecha_wreckage/mauler - max_equip = 5 + max_equip = 6 + destruction_sleep_duration = 20 -/obj/mecha/combat/marauder/mauler/loaded/Initialize() +/obj/vehicle/sealed/mecha/combat/marauder/mauler/Initialize(mapload) + . = ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/thrusters/ion(src) + ME.attach(src) + +/obj/vehicle/sealed/mecha/combat/marauder/mauler/loaded/Initialize(mapload) . = ..() var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg(src) ME.attach(src) diff --git a/code/game/mecha/medical/medigax.dm b/code/modules/vehicles/mecha/combat/medigax.dm similarity index 52% rename from code/game/mecha/medical/medigax.dm rename to code/modules/vehicles/mecha/combat/medigax.dm index 98b7c9455b..ec38dd37db 100644 --- a/code/game/mecha/medical/medigax.dm +++ b/code/modules/vehicles/mecha/combat/medigax.dm @@ -1,34 +1,36 @@ -/obj/mecha/medical/medigax +/obj/vehicle/sealed/mecha/medical/medigax desc = "A Gygax with it's actuator overload stripped and a slick white paint scheme, for medical use, These exosuits are developed and produced by Vey-Med. (© All rights reserved)." name = "\improper Medical Gygax" icon_state = "medigax" - step_in = 1.75 // a little faster than an odysseus - max_temperature = 25000 + allow_diagonal_movement = TRUE + movedelay = 2 + dir_in = 1 //Facing North. max_integrity = 250 - wreckage = /obj/structure/mecha_wreckage/odysseus - armor = list("melee" = 25, "bullet" = 20, "laser" = 30, "energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - internal_damage_threshold = 35 deflect_chance = 15 - step_energy_drain = 6 + armor = list(MELEE = 25, BULLET = 20, LASER = 30, ENERGY = 15, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) + max_temperature = 25000 + wreckage = /obj/structure/mecha_wreckage/odysseus + internal_damage_threshold = 35 + normal_step_energy_drain = 6 infra_luminosity = 6 + internals_req_access = list(ACCESS_ROBOTICS, ACCESS_MEDICAL) - -/obj/mecha/medical/medigax/moved_inside(mob/living/carbon/human/H) +/obj/vehicle/sealed/mecha/medical/medigax/moved_inside(mob/living/carbon/human/H) . = ..() if(.) var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] hud.add_hud_to(H) -/obj/mecha/medical/medigax/go_out() - if(isliving(occupant)) - var/mob/living/carbon/human/L = occupant +/obj/vehicle/sealed/mecha/medical/medigax/remove_occupant(mob/M) + if(isliving(M)) + var/mob/living/L = M var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] hud.remove_hud_from(L) - ..() + return ..() -/obj/mecha/medical/medigax/mmi_moved_inside(obj/item/mmi/mmi_as_oc, mob/user) +/obj/vehicle/sealed/mecha/medical/medigax/mmi_moved_inside(obj/item/mmi/M, mob/user) . = ..() if(.) var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] - var/mob/living/brain/B = mmi_as_oc.brainmob + var/mob/living/brain/B = M.brainmob hud.add_hud_to(B) diff --git a/code/game/mecha/combat/neovgre.dm b/code/modules/vehicles/mecha/combat/neovgre.dm similarity index 64% rename from code/game/mecha/combat/neovgre.dm rename to code/modules/vehicles/mecha/combat/neovgre.dm index 75470abe88..d8704e0318 100644 --- a/code/game/mecha/combat/neovgre.dm +++ b/code/modules/vehicles/mecha/combat/neovgre.dm @@ -1,52 +1,49 @@ -/obj/mecha/combat/neovgre +/obj/vehicle/sealed/mecha/combat/neovgre name = "Neovgre, the Anima Bulwark" - desc = "Nezbere's most powerful creation, a mighty war machine of unmatched power said to have ended wars in a single night." + desc = "Nezbere's most powerful creation, a mighty war machine of unmatched power said to have ended wars in a single night. Armed with a heavy laser and a tesla sphere generator. Requires a pilot and a gunner." icon = 'icons/mecha/neovgre.dmi' icon_state = "neovgre" max_integrity = 500 //This is THE ratvarian superweaon, its deployment is an investment - armor = list("melee" = 50, "bullet" = 40, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) //Its similar to the clockwork armour albeit with a few buffs becuase RATVARIAN SUPERWEAPON!! + armor = list(MELEE = 60, BULLET = 70, LASER = 65, ENERGY = 65, BOMB = 60, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) //Its similar to the clockwork armour albeit with a few buffs becuase RATVARIAN SUPERWEAPON!! force = 50 //SMASHY SMASHY!! - internal_damage_threshold = 0 - step_in = 3 + movedelay = 4 + internal_damage_threshold = 500 pixel_x = -16 layer = ABOVE_MOB_LAYER - breach_time = 100 //ten seconds till all goes to shit - recharge_rate = 100 + var/breach_time = 100 //ten seconds till all goes to shit + var/recharge_rate = 100 internals_req_access = list() - add_req_access = 0 wreckage = /obj/structure/mecha_wreckage/durand/neovgre stepsound = 'sound/mecha/neostep2.ogg' turnsound = 'sound/mecha/powerloader_step.ogg' + max_occupants = 2 -/obj/mecha/combat/neovgre/GrantActions(mob/living/user, human_occupant = 0) //No Eject action for you sonny jim, your life for Ratvar! - internals_action.Grant(user, src) - cycle_action.Grant(user, src) - lights_action.Grant(user, src) - stats_action.Grant(user, src) - strafing_action.Grant(user, src) +//override this proc if you need to split up mecha control between multiple people (see savannah_ivanov.dm) +/obj/vehicle/sealed/mecha/combat/neovgre/auto_assign_occupant_flags(mob/M) + if(driver_amount() < max_drivers) + add_control_flags(M, VEHICLE_CONTROL_DRIVE|VEHICLE_CONTROL_SETTINGS) + else + add_control_flags(M, VEHICLE_CONTROL_MELEE|VEHICLE_CONTROL_EQUIPMENT) -/obj/mecha/combat/neovgre/RemoveActions(mob/living/user, human_occupant = 0) - internals_action.Remove(user) - cycle_action.Remove(user) - lights_action.Remove(user) - stats_action.Remove(user) - strafing_action.Remove(user) +/obj/vehicle/sealed/mecha/combat/neovgre/mob_exit(mob/M, silent, forced) + if(forced) + ..() -/obj/mecha/combat/neovgre/MouseDrop_T(mob/M, mob/user) +/obj/vehicle/sealed/mecha/combat/neovgre/MouseDrop_T(mob/M, mob/user) if(!is_servant_of_ratvar(user)) to_chat(user, "BEGONE HEATHEN!") return else ..() -/obj/mecha/combat/neovgre/moved_inside(mob/living/carbon/human/H) +/obj/vehicle/sealed/mecha/combat/neovgre/moved_inside(mob/living/carbon/human/H) var/list/Itemlist = H.get_contents() for(var/obj/item/clockwork/slab/W in Itemlist) to_chat(H, "You safely store [W] inside [src].") qdel(W) . = ..() -/obj/mecha/combat/neovgre/obj_destruction() +/obj/vehicle/sealed/mecha/combat/neovgre/obj_destruction() for(var/mob/M in src) to_chat(M, "You are consumed by the fires raging within Neovgre...") M.dust() @@ -54,15 +51,15 @@ src.visible_message("The reactor has gone critical, its going to blow!") addtimer(CALLBACK(src,.proc/go_critical),breach_time) -/obj/mecha/combat/neovgre/proc/go_critical() +/obj/vehicle/sealed/mecha/combat/neovgre/proc/go_critical() explosion(get_turf(loc), 3, 5, 10, 20, 30) Destroy(src) -/obj/mecha/combat/neovgre/container_resist(mob/living/user) +/obj/vehicle/sealed/mecha/combat/neovgre/container_resist(mob/living/user) to_chat(user, "Neovgre requires a lifetime commitment friend, no backing out now!") return -/obj/mecha/combat/neovgre/process() +/obj/vehicle/sealed/mecha/combat/neovgre/process() ..() if(!obj_integrity) //Integrity is zero but we would heal out of that state if we went into this before it recognises it being zero return @@ -80,11 +77,13 @@ if(obj_integrity < max_integrity && istype(loc, /turf/open/floor/clockwork)) obj_integrity += min(max_integrity - obj_integrity, max_integrity / 200) -/obj/mecha/combat/neovgre/Initialize() +/obj/vehicle/sealed/mecha/combat/neovgre/Initialize(mapload) .=..() GLOB.neovgre_exists ++ var/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/N = new N.attach(src) + var/obj/item/mecha_parts/mecha_equipment/weapon/energy/tesla/shocking = new + shocking.attach(src) /obj/structure/mecha_wreckage/durand/neovgre name = "\improper Neovgre wreckage?" @@ -97,7 +96,7 @@ desc = "Please re-attach this to neovgre and stop asking questions about why it looks like a normal Nanotrasen issue Solaris laser cannon - Nezbere" fire_sound = 'sound/weapons/neovgre_laser.ogg' -/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/can_attach(obj/mecha/combat/neovgre/M) +/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/can_attach(obj/vehicle/sealed/mecha/combat/neovgre/M) if(istype(M)) return 1 return 0 diff --git a/code/modules/vehicles/mecha/combat/phazon.dm b/code/modules/vehicles/mecha/combat/phazon.dm new file mode 100644 index 0000000000..fad2b0783c --- /dev/null +++ b/code/modules/vehicles/mecha/combat/phazon.dm @@ -0,0 +1,21 @@ +/obj/vehicle/sealed/mecha/combat/phazon + desc = "This is a Phazon exosuit. The pinnacle of scientific research and pride of Nanotrasen, it uses cutting edge bluespace technology and expensive materials." + name = "\improper Phazon" + icon_state = "phazon" + movedelay = 2 + dir_in = 2 //Facing South. + normal_step_energy_drain = 3 + max_integrity = 200 + deflect_chance = 30 + armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 30, BIO = 0, RAD = 50, FIRE = 100, ACID = 100) + max_temperature = 25000 + wreckage = /obj/structure/mecha_wreckage/phazon + internal_damage_threshold = 25 + force = 15 + max_equip = 3 + phase_state = "phazon-phase" + +/obj/vehicle/sealed/mecha/combat/phazon/generate_actions() + . = ..() + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_phasing) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_switch_damtype) diff --git a/code/game/mecha/combat/reticence.dm b/code/modules/vehicles/mecha/combat/reticence.dm similarity index 63% rename from code/game/mecha/combat/reticence.dm rename to code/modules/vehicles/mecha/combat/reticence.dm index 7343a85483..300023b7ab 100644 --- a/code/game/mecha/combat/reticence.dm +++ b/code/modules/vehicles/mecha/combat/reticence.dm @@ -1,26 +1,25 @@ -/obj/mecha/combat/reticence +/obj/vehicle/sealed/mecha/combat/reticence desc = "A silent, fast, and nigh-invisible miming exosuit. Popular among mimes and mime assassins." name = "\improper reticence" icon_state = "reticence" - step_in = 2 + movedelay = 2 dir_in = 1 //Facing North. max_integrity = 100 deflect_chance = 3 - armor = list("melee" = 25, "bullet" = 20, "laser" = 30, "energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 25, BULLET = 20, LASER = 30, ENERGY = 15, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) max_temperature = 15000 wreckage = /obj/structure/mecha_wreckage/reticence operation_req_access = list(ACCESS_THEATRE) - internals_req_access = list(ACCESS_THEATRE, ACCESS_ROBOTICS) - add_req_access = 0 + internals_req_access = list(ACCESS_ROBOTICS, ACCESS_THEATRE) + mecha_flags = CANSTRAFE | IS_ENCLOSED | HAS_LIGHTS internal_damage_threshold = 25 max_equip = 2 - step_energy_drain = 3 + normal_step_energy_drain = 3 color = "#87878715" stepsound = null turnsound = null - opacity = 0 -/obj/mecha/combat/reticence/loaded/Initialize() +/obj/vehicle/sealed/mecha/combat/reticence/loaded/Initialize(mapload) . = ..() var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced ME.attach(src) diff --git a/code/modules/vehicles/mecha/equipment/mecha_equipment.dm b/code/modules/vehicles/mecha/equipment/mecha_equipment.dm new file mode 100644 index 0000000000..1d104291f3 --- /dev/null +++ b/code/modules/vehicles/mecha/equipment/mecha_equipment.dm @@ -0,0 +1,153 @@ +//DO NOT ADD MECHA PARTS TO THE GAME WITH THE DEFAULT "SPRITE ME" SPRITE! +//I'm annoyed I even have to tell you this! SPRITE FIRST, then commit. + +/obj/item/mecha_parts/mecha_equipment + name = "mecha equipment" + icon = 'icons/mecha/mecha_equipment.dmi' + icon_state = "mecha_equip" + force = 5 + max_integrity = 300 + var/equip_cooldown = 0 + var/equip_ready = TRUE //whether the equipment is ready for use. (or deactivated/activated for static stuff) + var/energy_drain = 0 + var/obj/vehicle/sealed/mecha/chassis = null + ///Bitflag. Determines the range of the equipment. + var/range = MECHA_MELEE + /// Bitflag. Used by exosuit fabricator to assign sub-categories based on which exosuits can equip this. + var/mech_flags = NONE + var/salvageable = 1 + var/detachable = TRUE // Set to FALSE for built-in equipment that cannot be removed + var/selectable = 1 // Set to 0 for passive equipment such as mining scanner or armor plates + var/harmful = FALSE //Controls if equipment can be used to attack by a pacifist. + var/destroy_sound = 'sound/mecha/critdestr.ogg' + +/obj/item/mecha_parts/mecha_equipment/proc/update_chassis_page() + if(chassis) + send_byjax(chassis.occupants,"exosuit.browser","eq_list",chassis.get_equipment_list()) + send_byjax(chassis.occupants,"exosuit.browser","equipment_menu",chassis.get_equipment_menu(),"dropdowns") + return TRUE + return + +/obj/item/mecha_parts/mecha_equipment/proc/update_equip_info() + if(chassis) + send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",get_equip_info()) + return TRUE + return + +/obj/item/mecha_parts/mecha_equipment/Destroy() + if(chassis) + LAZYREMOVE(chassis.equipment, src) + if(chassis.selected == src) + chassis.selected = null + update_chassis_page() + log_message("[src] is destroyed.", LOG_MECHA) + if(chassis.occupants) + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)][src] is destroyed!") + playsound(chassis, destroy_sound, 50) + if(!detachable) //If we're a built-in nondetachable equipment, let's lock up the slot that we were in. + chassis.max_equip-- + chassis = null + return ..() + +/obj/item/mecha_parts/mecha_equipment/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M) + if(can_attach(M)) + if(!user.temporarilyRemoveItemFromInventory(src)) + return FALSE + attach(M) + user.visible_message("[user] attaches [src] to [M].", "You attach [src] to [M].") + return TRUE + to_chat(user, "You are unable to attach [src] to [M]!") + return FALSE + +/obj/item/mecha_parts/mecha_equipment/proc/get_equip_info() + if(!chassis) + return + var/txt = "* " + if(chassis.selected == src) + txt += "[src.name]" + else if(selectable) + txt += "[src.name]" + else + txt += "[src.name]" + + return txt + +/obj/item/mecha_parts/mecha_equipment/proc/action_checks(atom/target) + if(!target) + return FALSE + if(!chassis) + return FALSE + if(!equip_ready) + return FALSE + if(energy_drain && !chassis.has_charge(energy_drain)) + return FALSE + if(chassis.is_currently_ejecting) + return FALSE + if(chassis.equipment_disabled) + to_chat(chassis.occupants, "Error -- Equipment control unit is unresponsive.") + return FALSE + if(TIMER_COOLDOWN_CHECK(chassis, COOLDOWN_MECHA_EQUIPMENT)) + return FALSE + return TRUE + +/obj/item/mecha_parts/mecha_equipment/proc/action(mob/source, atom/target, params) + TIMER_COOLDOWN_START(chassis, COOLDOWN_MECHA_EQUIPMENT, equip_cooldown)//Cooldown is on the MECH so people dont bypass it by switching equipment + send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",src.get_equip_info()) + chassis.use_power(energy_drain) + return TRUE + +/obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(atom/target, mob/user) + if(!chassis) + return FALSE + chassis.use_power(energy_drain) + return do_after(user, equip_cooldown, target, extra_checks = CALLBACK(src, .proc/do_after_checks, target)) + +/obj/item/mecha_parts/mecha_equipment/proc/do_after_mecha(atom/target, mob/user, delay) + return do_after(user, delay, target, extra_checks = CALLBACK(src, .proc/do_after_checks, target)) + +/// do after checks for the mecha equipment do afters +/obj/item/mecha_parts/mecha_equipment/proc/do_after_checks(atom/target) + return chassis && (get_dir(chassis, target) & chassis.dir) + +/obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/vehicle/sealed/mecha/M) + if(LAZYLEN(M.equipment)You start putting [target] into [src]...") + to_chat(source, "[icon2html(src, source)]You start putting [target] into [src]...") chassis.visible_message("[chassis] starts putting [target] into \the [src].") - if(do_after_cooldown(target)) - if(!patient_insertion_check(target)) + if(do_after(source, equip_cooldown, target=target)) + if(!chassis || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir)) + return + if(!patient_insertion_check(target, source)) return target.forceMove(src) patient = target START_PROCESSING(SSobj, src) update_equip_info() - occupant_message("[target] successfully loaded into [src]. Life support functions engaged.") + to_chat(source, "[icon2html(src, source)][target] successfully loaded into [src]. Life support functions engaged.") chassis.visible_message("[chassis] loads [target] into [src].") - mecha_log_message("[target] loaded. Life support functions engaged.") + log_message("[target] loaded. Life support functions engaged.", LOG_MECHA) + return ..() -/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/patient_insertion_check(mob/living/carbon/target) +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/patient_insertion_check(mob/living/carbon/target, mob/user) if(target.buckled) - occupant_message("[target] will not fit into the sleeper because [target.p_theyre()] buckled to [target.buckled]!") + to_chat(user, "[icon2html(src, user)][target] will not fit into the sleeper because [target.p_theyre()] buckled to [target.buckled]!") return if(target.has_buckled_mobs()) - occupant_message("[target] will not fit into the sleeper because of the creatures attached to it!") + to_chat(user, "[icon2html(src, user)][target] will not fit into the sleeper because of the creatures attached to it!") return if(patient) - occupant_message("The sleeper is already occupied!") + to_chat(user, "[icon2html(src, user)]The sleeper is already occupied!") return - return 1 + return TRUE /obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/go_out() if(!patient) return patient.forceMove(get_turf(src)) - occupant_message("[patient] ejected. Life support functions disabled.") - mecha_log_message("[patient] ejected. Life support functions disabled.") + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)][patient] ejected. Life support functions disabled.") + log_message("[patient] ejected. Life support functions disabled.", LOG_MECHA) STOP_PROCESSING(SSobj, src) patient = null update_equip_info() /obj/item/mecha_parts/mecha_equipment/medical/sleeper/detach() if(patient) - occupant_message("Unable to detach [src] - equipment occupied!") + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]Unable to detach [src] - equipment occupied!") return STOP_PROCESSING(SSobj, src) return ..() @@ -105,20 +107,23 @@ if(patient) temp = "
    \[Occupant: [patient] ([patient.stat > 1 ? "*DECEASED*" : "Health: [patient.health]%"])\]
    View stats|Eject" return "[output] [temp]" - return /obj/item/mecha_parts/mecha_equipment/medical/sleeper/Topic(href,href_list) - ..() + . = ..() + if(.) + return + if(!(usr in chassis.occupants)) + return if(href_list["eject"]) go_out() if(href_list["view_stats"]) - chassis.occupant << browse(get_patient_stats(),"window=msleeper") - onclose(chassis.occupant, "msleeper") + usr << browse(get_patient_stats(),"window=msleeper") + onclose(usr, "msleeper") return if(href_list["inject"]) var/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/SG = locate() in chassis var/datum/reagent/R = locate(href_list["inject"]) in SG.reagents.reagent_list - if (istype(R)) + if(istype(R)) inject_reagent(R, SG) /obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_stats() @@ -186,7 +191,7 @@ if(SG && SG.reagents && islist(SG.reagents.reagent_list)) for(var/datum/reagent/R in SG.reagents.reagent_list) if(R.volume > 0) - output += "Inject [R.name]
    " + output += "Inject [R.name]
    " return output @@ -195,9 +200,9 @@ return 0 var/to_inject = min(R.volume, inject_amount) if(to_inject && patient.reagents.get_reagent_amount(R.type) + to_inject <= inject_amount*2) - occupant_message("Injecting [patient] with [to_inject] units of [R.name].") - mecha_log_message("Injecting [patient] with [to_inject] units of [R.name].") - log_combat(chassis.occupant, patient, "injected", "[name] ([R] - [to_inject] units)") + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]Injecting [patient] with [to_inject] units of [R.name].") + log_message("Injecting [patient] with [to_inject] units of [R.name].", LOG_MECHA) + log_combat(chassis.occupants, patient, "injected", "[name] ([R] - [to_inject] units)") SG.reagents.trans_id_to(patient,R.type,to_inject) update_equip_info() return @@ -205,9 +210,9 @@ /obj/item/mecha_parts/mecha_equipment/medical/sleeper/update_equip_info() if(..()) if(patient) - send_byjax(chassis.occupant,"msleeper.browser","lossinfo",get_patient_dam()) - send_byjax(chassis.occupant,"msleeper.browser","reagents",get_patient_reagents()) - send_byjax(chassis.occupant,"msleeper.browser","injectwith",get_available_reagents()) + send_byjax(chassis.occupants,"msleeper.browser","lossinfo",get_patient_dam()) + send_byjax(chassis.occupants,"msleeper.browser","reagents",get_patient_reagents()) + send_byjax(chassis.occupants,"msleeper.browser","injectwith",get_available_reagents()) return 1 return @@ -218,9 +223,8 @@ if(..()) return if(!chassis.has_charge(energy_drain)) - set_ready_state(1) - mecha_log_message("Deactivated.") - occupant_message("[src] deactivated - no power.") + log_message("Deactivated.", LOG_MECHA) + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)][src] deactivated - no power.") STOP_PROCESSING(SSobj, src) return var/mob/living/carbon/M = patient @@ -228,7 +232,10 @@ return if(M.health > 0) M.adjustOxyLoss(-1) - M.AdjustAllImmobility(-80) + M.AdjustStun(-80) + M.AdjustKnockdown(-80) + M.AdjustParalyzed(-80) + M.AdjustImmobilized(-80) M.AdjustUnconscious(-80) if(M.reagents.get_reagent_amount(/datum/reagent/medicine/epinephrine) < 5) M.reagents.add_reagent(/datum/reagent/medicine/epinephrine, 5) @@ -254,15 +261,14 @@ var/synth_speed = 5 //[num] reagent units per cycle energy_drain = 10 var/mode = 0 //0 - fire syringe, 1 - analyze reagents. - range = MELEE|RANGED + range = MECHA_MELEE|MECHA_RANGED equip_cooldown = 10 -/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Initialize() +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Initialize(mapload) . = ..() create_reagents(max_volume, NO_REACT) syringes = new - known_reagents = list(/datum/reagent/medicine/epinephrine = "Epinephrine", /datum/reagent/medicine/charcoal = "Charcoal", /datum/reagent/medicine/prussian_blue = "Prussian Blue", \ - /datum/reagent/medicine/dexalin = "Dexalin", /datum/reagent/medicine/insulin = "Insulin", /datum/reagent/medicine/kelotane = "Kelotane", /datum/reagent/medicine/bicaridine = "Bicaridine") + known_reagents = list(/datum/reagent/medicine/epinephrine="Epinephrine") processed_reagents = new /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/detach() @@ -273,39 +279,35 @@ STOP_PROCESSING(SSobj, src) return ..() -/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/critfail() - ..() - if(reagents) - DISABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT) - -/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/can_attach(obj/mecha/medical/M) - if(..()) - if(istype(M)) - return 1 - return 0 +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/can_attach(obj/vehicle/sealed/mecha/medical/M) + . = ..() + if(!istype(M)) + return FALSE /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/get_equip_info() var/output = ..() if(output) return "[output] \[[mode? "Analyze" : "Launch"]\]
    \[Syringes: [syringes.len]/[max_syringes] | Reagents: [reagents.total_volume]/[reagents.maximum_volume]\]
    Reagents list" - return -/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/action(atom/movable/target) +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/action(mob/source, atom/movable/target, params) if(!action_checks(target)) return if(istype(target, /obj/item/reagent_containers/syringe)) return load_syringe(target) if(istype(target, /obj/item/storage))//Loads syringes from boxes for(var/obj/item/reagent_containers/syringe/S in target.contents) - load_syringe(S) + load_syringe(S, source) return if(mode) - return analyze_reagents(target) + return analyze_reagents(target, source) if(!syringes.len) - occupant_message("No syringes loaded.") + to_chat(source, "[icon2html(src, source)]No syringes loaded.") return if(reagents.total_volume<=0) - occupant_message("No available reagents to load syringe with.") + to_chat(source, "[icon2html(src, source)]No available reagents to load syringe with.") + return + if(HAS_TRAIT(source, TRAIT_PACIFISM)) + to_chat(source, "The [src] is lethally chambered! You don't want to risk harming anyone...") return var/turf/trg = get_turf(target) var/obj/item/reagent_containers/syringe/mechsyringe = syringes[1] @@ -314,11 +316,9 @@ syringes -= mechsyringe mechsyringe.icon = 'icons/obj/chemical.dmi' mechsyringe.icon_state = "syringeproj" - playsound(chassis, 'sound/items/syringeproj.ogg', 50, 1) - mecha_log_message("Launched [mechsyringe] from [src], targeting [target].") - var/mob/originaloccupant = chassis.occupant - spawn(0) - src = null //if src is deleted, still process the syringe + playsound(chassis, 'sound/items/syringeproj.ogg', 50, TRUE) + log_message("Launched [mechsyringe] from [src] by [source], targeting [target].", LOG_MECHA) + spawn(0) //This code is trash and whoever wrote it should feel bad for(var/i=0, i<6, i++) if(!mechsyringe) break @@ -326,10 +326,10 @@ var/list/mobs = new for(var/mob/living/carbon/M in mechsyringe.loc) mobs += M - var/mob/living/carbon/M = safepick(mobs) - if(M) + if(length(mobs)) + var/mob/living/carbon/M = pick(mobs) var/R - mechsyringe.visible_message(" [M] was hit by the syringe!") + mechsyringe.visible_message(" [M] is hit by the syringe!") if(M.can_inject(null, 1)) if(mechsyringe.reagents) for(var/datum/reagent/A in mechsyringe.reagents.reagent_list) @@ -337,9 +337,9 @@ mechsyringe.icon_state = initial(mechsyringe.icon_state) mechsyringe.icon = initial(mechsyringe.icon) mechsyringe.reagents.reaction(M, INJECT) - mechsyringe.reagents.trans_to(M, mechsyringe.reagents.total_volume) + mechsyringe.reagents.trans_to(M, mechsyringe.reagents.total_volume, log = TRUE) M.take_bodypart_damage(2) - log_combat(originaloccupant, M, "shot", "syringegun") + log_combat(source, M, "shot", "syringegun") break else if(mechsyringe.loc == trg) mechsyringe.icon_state = initial(mechsyringe.icon_state) @@ -352,7 +352,7 @@ mechsyringe.update_icon() break sleep(1) - return 1 + return ..() /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Topic(href,href_list) @@ -376,12 +376,14 @@ if(processed_reagents.len) message += " added to production" START_PROCESSING(SSobj, src) - occupant_message(message) - occupant_message("Reagent processing started.") - mecha_log_message("Reagent processing started.") + to_chat(usr, message) + to_chat(usr, "[icon2html(src, usr)]Reagent processing started.") + log_message("Reagent processing started.", LOG_MECHA) return if (href_list["show_reagents"]) - chassis.occupant << browse(get_reagents_page(),"window=msyringegun") + if(!(usr in chassis.occupants)) + return + usr << browse(get_reagents_page(),"window=msyringegun") if (href_list["purge_reagent"]) var/reagent = href_list["purge_reagent"] if(reagent) @@ -445,74 +447,72 @@ var/output for(var/datum/reagent/R in reagents.reagent_list) if(R.volume > 0) - output += "[R]: [round(R.volume,0.001)] - Purge Reagent
    " + output += "[R]: [round(R.volume,0.001)] - Purge Reagent
    " if(output) output += "Total: [round(reagents.total_volume,0.001)]/[reagents.maximum_volume] - Purge All" return output || "None" -/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/load_syringe(obj/item/reagent_containers/syringe/S) +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/load_syringe(obj/item/reagent_containers/syringe/S, mob/user) if(syringes.len= 2) - occupant_message("The syringe is too far away.") + to_chat(user, "[icon2html(src, user)]The syringe is too far away!") return 0 for(var/obj/structure/D in S.loc)//Basic level check for structures in the way (Like grilles and windows) if(!(D.CanPass(S,src.loc))) - occupant_message("Unable to load syringe.") + to_chat(user, "[icon2html(src, user)]Unable to load syringe!") return 0 for(var/obj/machinery/door/D in S.loc)//Checks for doors if(!(D.CanPass(S,src.loc))) - occupant_message("Unable to load syringe.") + to_chat(user, "[icon2html(src, user)]Unable to load syringe!") return 0 S.reagents.trans_to(src, S.reagents.total_volume) S.forceMove(src) syringes += S - occupant_message("Syringe loaded.") + to_chat(user, "[icon2html(src, user)]Syringe loaded.") update_equip_info() return 1 - occupant_message("[src]'s syringe chamber is full.") + to_chat(user, "[icon2html(src, user)][src]'s syringe chamber is full!") return 0 -/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/analyze_reagents(atom/A) +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/analyze_reagents(atom/A, mob/user) if(get_dist(src,A) >= 4) - occupant_message("The object is too far away.") - return 0 + to_chat(user, "[icon2html(src, user)]The object is too far away!") + return FALSE if(!A.reagents || ismob(A)) - occupant_message("No reagent info gained from [A].") - return 0 - occupant_message("Analyzing reagents...") + to_chat(user, "[icon2html(src, user)]No reagent info gained from [A].") + return FALSE + to_chat(user, "[icon2html(src, user)]Analyzing reagents...") for(var/datum/reagent/R in A.reagents.reagent_list) if(R.can_synth && add_known_reagent(R.type,R.name)) - occupant_message("Reagent analyzed, identified as [R.name] and added to database.") - send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form()) - occupant_message("Analyzis complete.") - return 1 + to_chat(user, "[icon2html(src, user)]Reagent analyzed, identified as [R.name] and added to database.") + send_byjax(chassis.occupants,"msyringegun.browser","reagents_form",get_reagents_form()) + to_chat(user, "[icon2html(src, user)]Analysis complete.") + return TRUE /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/add_known_reagent(r_id,r_name) if(!(r_id in known_reagents)) known_reagents += r_id known_reagents[r_id] = r_name - return 1 - return 0 + return TRUE + return FALSE /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/update_equip_info() if(..()) - send_byjax(chassis.occupant,"msyringegun.browser","reagents",get_current_reagents()) - send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form()) - return 1 - return + send_byjax(chassis.occupants,"msyringegun.browser","reagents",get_current_reagents()) + send_byjax(chassis.occupants,"msyringegun.browser","reagents_form",get_reagents_form()) + return TRUE /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/on_reagent_change(changetype) ..() update_equip_info() - return /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/process() if(..()) return if(!processed_reagents.len || reagents.total_volume >= reagents.maximum_volume || !chassis.has_charge(energy_drain)) - occupant_message("Reagent processing stopped.") - mecha_log_message("Reagent processing stopped.") + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]Reagent processing stopped.") + log_message("Reagent processing stopped.", LOG_MECHA) STOP_PROCESSING(SSobj, src) return var/amount = synth_speed / processed_reagents.len @@ -527,12 +527,12 @@ desc = "Equipment for medical exosuits. Generates a focused beam of medical nanites." icon_state = "mecha_medigun" energy_drain = 10 - range = MELEE|RANGED + range = MECHA_MELEE|MECHA_RANGED equip_cooldown = 0 var/obj/item/gun/medbeam/mech/medigun custom_materials = list(/datum/material/iron = 15000, /datum/material/glass = 8000, /datum/material/plasma = 3000, /datum/material/gold = 8000, /datum/material/diamond = 2000) -/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/Initialize() +/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/Initialize(mapload) . = ..() medigun = new(src) @@ -546,7 +546,7 @@ return medigun.process() -/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/action(atom/target) +/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/action(mob/source, atom/movable/target, params) medigun.process_fire(target, loc) diff --git a/code/game/mecha/equipment/tools/mining_tools.dm b/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm similarity index 65% rename from code/game/mecha/equipment/tools/mining_tools.dm rename to code/modules/vehicles/mecha/equipment/tools/mining_tools.dm index 06e4208d71..46190a4c84 100644 --- a/code/game/mecha/equipment/tools/mining_tools.dm +++ b/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm @@ -13,17 +13,18 @@ energy_drain = 10 force = 15 harmful = TRUE + range = MECHA_MELEE tool_behaviour = TOOL_DRILL toolspeed = 0.9 var/drill_delay = 7 var/drill_level = DRILL_BASIC mech_flags = EXOSUIT_MODULE_WORKING | EXOSUIT_MODULE_COMBAT -/obj/item/mecha_parts/mecha_equipment/drill/Initialize() +/obj/item/mecha_parts/mecha_equipment/drill/Initialize(mapload) . = ..() AddComponent(/datum/component/butchering, 50, 100, null, null, TRUE) -/obj/item/mecha_parts/mecha_equipment/drill/action(atom/target) +/obj/item/mecha_parts/mecha_equipment/drill/action(mob/source, atom/target, params) if(!action_checks(target)) return if(isspaceturf(target)) @@ -34,72 +35,69 @@ return target.visible_message("[chassis] starts to drill [target].", \ "[chassis] starts to drill [target]...", \ - "You hear drilling.") + "You hear drilling.") - if(do_after_cooldown(target)) - set_ready_state(FALSE) - mecha_log_message("Started drilling [target]") + if(do_after_cooldown(target, source)) + log_message("Started drilling [target]", LOG_MECHA) if(isturf(target)) var/turf/T = target - T.drill_act(src) - set_ready_state(TRUE) + T.drill_act(src, source) return - while(do_after_mecha(target, drill_delay)) + while(do_after_mecha(target, source, drill_delay)) if(isliving(target)) - drill_mob(target, chassis.occupant) - playsound(src,'sound/weapons/drill.ogg',40,1) + drill_mob(target, source) + playsound(src,'sound/weapons/drill.ogg',40,TRUE) else if(isobj(target)) var/obj/O = target O.take_damage(15, BRUTE, 0, FALSE, get_dir(chassis, target)) - playsound(src,'sound/weapons/drill.ogg',40,1) + playsound(src,'sound/weapons/drill.ogg',40,TRUE) else - set_ready_state(TRUE) return - set_ready_state(TRUE) + return ..() -/turf/proc/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) +/turf/proc/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill, mob/user) return -/turf/closed/wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) - if(drill.do_after_mecha(src, 60 / drill.drill_level)) - drill.mecha_log_message("Drilled through [src]") +/turf/closed/wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill, mob/user) + if(drill.do_after_mecha(src, user, 60 / drill.drill_level)) + drill.log_message("Drilled through [src]", LOG_MECHA) dismantle_wall(TRUE, FALSE) -/turf/closed/wall/r_wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) +/turf/closed/wall/r_wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill, mob/user) if(drill.drill_level >= DRILL_HARDENED) - if(drill.do_after_mecha(src, 120 / drill.drill_level)) - drill.mecha_log_message("Drilled through [src]") + if(drill.do_after_mecha(src, user, 120 / drill.drill_level)) + drill.log_message("Drilled through [src]", LOG_MECHA) dismantle_wall(TRUE, FALSE) else - drill.occupant_message("[src] is too durable to drill through.") + to_chat(user, "[icon2html(src, user)][src] is too durable to drill through.") -/turf/closed/mineral/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) +/turf/closed/mineral/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill, mob/user) for(var/turf/closed/mineral/M in range(drill.chassis,1)) if(get_dir(drill.chassis,M)&drill.chassis.dir) M.gets_drilled() - drill.mecha_log_message("Drilled through [src]") + drill.log_message("[user] drilled through [src]", LOG_MECHA) drill.move_ores() /turf/open/floor/plating/asteroid/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) for(var/turf/open/floor/plating/asteroid/M in range(1, drill.chassis)) if((get_dir(drill.chassis,M)&drill.chassis.dir) && !M.dug) M.getDug() - drill.mecha_log_message("Drilled through [src]") + drill.log_message("Drilled through [src]", LOG_MECHA) drill.move_ores() /obj/item/mecha_parts/mecha_equipment/drill/proc/move_ores() - if(locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in chassis.equipment && istype(chassis, /obj/mecha/working/ripley)) - var/obj/mecha/working/ripley/R = chassis //we could assume that it's a ripley because it has a clamp, but that's ~unsafe~ and ~bad practice~ + if(locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in chassis.equipment && istype(chassis, /obj/vehicle/sealed/mecha/working/ripley)) + var/obj/vehicle/sealed/mecha/working/ripley/R = chassis //we could assume that it's a ripley because it has a clamp, but that's ~unsafe~ and ~bad practice~ R.collect_ore() -/obj/item/mecha_parts/mecha_equipment/drill/can_attach(obj/mecha/M as obj) +/obj/item/mecha_parts/mecha_equipment/drill/can_attach(obj/vehicle/sealed/mecha/M as obj) if(..()) - if(istype(M, /obj/mecha/working) || istype(M, /obj/mecha/combat)) - return 1 - return 0 + if(istype(M, /obj/vehicle/sealed/mecha/working) || istype(M, /obj/vehicle/sealed/mecha/combat)) + return TRUE + return FALSE -/obj/item/mecha_parts/mecha_equipment/drill/attach(obj/mecha/M) +/obj/item/mecha_parts/mecha_equipment/drill/attach(obj/vehicle/sealed/mecha/M) ..() var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering) butchering.butchering_enabled = TRUE @@ -123,14 +121,18 @@ else //drill makes a hole var/obj/item/bodypart/target_part = target.get_bodypart(ran_zone(BODY_ZONE_CHEST)) - target.apply_damage(10, BRUTE, BODY_ZONE_CHEST, target.run_armor_check(target_part, "melee")) + target.apply_damage(10, BRUTE, BODY_ZONE_CHEST, target.run_armor_check(target_part, MELEE)) //blood splatters var/splatter_dir = get_dir(chassis, target) if(isalien(target)) new /obj/effect/temp_visual/dir_setting/bloodsplatter/xenosplatter(target.drop_location(), splatter_dir) else - new /obj/effect/temp_visual/dir_setting/bloodsplatter(target.drop_location(), splatter_dir) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + new /obj/effect/temp_visual/dir_setting/bloodsplatter(target.drop_location(), splatter_dir, H.dna.species.exotic_blood_color) + else + new /obj/effect/temp_visual/dir_setting/bloodsplatter(target.drop_location(), splatter_dir) //organs go everywhere if(target_part && prob(10 * drill_level)) @@ -149,24 +151,30 @@ /obj/item/mecha_parts/mecha_equipment/mining_scanner name = "exosuit mining scanner" - desc = "Equipment for engineering and combat exosuits. It will automatically check surrounding rock for useful minerals." + desc = "Equipment for working exosuits. It will automatically check surrounding rock for useful minerals." icon_state = "mecha_analyzer" selectable = 0 equip_cooldown = 15 var/scanning_time = 0 mech_flags = EXOSUIT_MODULE_WORKING -/obj/item/mecha_parts/mecha_equipment/mining_scanner/Initialize() +/obj/item/mecha_parts/mecha_equipment/mining_scanner/Initialize(mapload) . = ..() START_PROCESSING(SSfastprocess, src) +/obj/item/mecha_parts/mecha_equipment/mining_scanner/can_attach(obj/vehicle/sealed/mecha/M as obj) + if(..()) + if(istype(M, /obj/vehicle/sealed/mecha/working)) + return TRUE + return FALSE + /obj/item/mecha_parts/mecha_equipment/mining_scanner/process() if(!loc) STOP_PROCESSING(SSfastprocess, src) qdel(src) - if(istype(loc, /obj/mecha/working) && scanning_time <= world.time) - var/obj/mecha/working/mecha = loc - if(!mecha.occupant) + if(istype(loc, /obj/vehicle/sealed/mecha/working) && scanning_time <= world.time) + var/obj/vehicle/sealed/mecha/working/mecha = loc + if(!mecha.occupants) return scanning_time = world.time + equip_cooldown mineral_scan_pulse(get_turf(src)) diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/modules/vehicles/mecha/equipment/tools/other_tools.dm similarity index 58% rename from code/game/mecha/equipment/tools/other_tools.dm rename to code/modules/vehicles/mecha/equipment/tools/other_tools.dm index e1861232f4..348a4bb6ec 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/modules/vehicles/mecha/equipment/tools/other_tools.dm @@ -10,15 +10,16 @@ icon_state = "mecha_teleport" equip_cooldown = 150 energy_drain = 1000 - range = RANGED + range = MECHA_RANGED + var/teleport_range = 7 -/obj/item/mecha_parts/mecha_equipment/teleporter/action(atom/target) +/obj/item/mecha_parts/mecha_equipment/teleporter/action(mob/source, atom/target, params) if(!action_checks(target) || is_centcom_level(loc.z)) return var/turf/T = get_turf(target) - if(T) + if(T && (loc.z == T.z) && (get_dist(loc, T) <= teleport_range)) do_teleport(chassis, T, 4, channel = TELEPORT_CHANNEL_BLUESPACE) - return 1 + return ..() @@ -30,10 +31,10 @@ icon_state = "mecha_wholegen" equip_cooldown = 50 energy_drain = 300 - range = RANGED + range = MECHA_RANGED -/obj/item/mecha_parts/mecha_equipment/wormhole_generator/action(atom/target) +/obj/item/mecha_parts/mecha_equipment/wormhole_generator/action(mob/source, atom/target, params) if(!action_checks(target) || is_centcom_level(loc.z)) return var/list/theareas = get_areas_in_range(100, chassis) @@ -44,10 +45,10 @@ var/turf/pos = get_turf(src) for(var/turf/T in get_area_turfs(thearea.type)) if(!T.density && pos.z == T.z) - var/clear = 1 + var/clear = TRUE for(var/obj/O in T) if(O.density) - clear = 0 + clear = FALSE break if(clear) L+=T @@ -58,11 +59,11 @@ return var/list/obj/effect/portal/created = create_portal_pair(get_turf(src), target_turf, 300, 1, /obj/effect/portal/anom) var/turf/T = get_turf(target) - message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] used a Wormhole Generator in [ADMIN_VERBOSEJMP(T)]") - log_game("[key_name(chassis.occupant)] used a Wormhole Generator in [AREACOORD(T)]") + message_admins("[ADMIN_LOOKUPFLW(source)] used a Wormhole Generator in [ADMIN_VERBOSEJMP(T)]") + log_game("[key_name(source)] used a Wormhole Generator in [AREACOORD(T)]") src = null QDEL_LIST_IN(created, rand(150,300)) - return 1 + return ..() /////////////////////////////////////// GRAVITATIONAL CATAPULT /////////////////////////////////////////// @@ -73,36 +74,41 @@ icon_state = "mecha_teleport" equip_cooldown = 10 energy_drain = 100 - range = MELEE|RANGED + range = MECHA_MELEE|MECHA_RANGED var/atom/movable/locked var/mode = 1 //1 - gravsling 2 - gravpush -/obj/item/mecha_parts/mecha_equipment/gravcatapult/action(atom/movable/target) +/obj/item/mecha_parts/mecha_equipment/gravcatapult/action(mob/source, atom/movable/target, params) if(!action_checks(target)) return switch(mode) if(1) if(!locked) if(!istype(target) || target.anchored || target.move_resist >= MOVE_FORCE_EXTREMELY_STRONG) - occupant_message("Unable to lock on [target]") + to_chat(source, "[icon2html(src, source)]Unable to lock on [target]!") return + if(ismob(target)) + var/mob/M = target + if(M.mob_negates_gravity()) + to_chat(source, "[icon2html(src, source)]Unable to lock on [target]!") + return locked = target - occupant_message("Locked on [target]") - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) + to_chat(source, "[icon2html(src, source)]Locked on [target].") + send_byjax(source,"exosuit.browser","[REF(src)]",src.get_equip_info()) else if(target!=locked) if(locked in view(chassis)) var/turf/targ = get_turf(target) var/turf/orig = get_turf(locked) locked.throw_at(target, 14, 1.5) locked = null - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) - log_game("[key_name(chassis.occupant)] used a Gravitational Catapult to throw [locked] (From [AREACOORD(orig)]) at [target] ([AREACOORD(targ)]).") - return TRUE + send_byjax(source,"exosuit.browser","[REF(src)]",src.get_equip_info()) + log_game("[key_name(source)] used a Gravitational Catapult to throw [locked] (From [AREACOORD(orig)]) at [target] ([AREACOORD(targ)]).") + return ..() else locked = null - occupant_message("Lock on [locked] disengaged.") - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) + to_chat(source, "[icon2html(src, source)]Lock on [locked] disengaged.") + send_byjax(source,"exosuit.browser","[REF(src)]",src.get_equip_info()) if(2) var/list/atoms = list() if(isturf(target)) @@ -112,15 +118,21 @@ for(var/atom/movable/A in atoms) if(A.anchored || A.move_resist >= MOVE_FORCE_EXTREMELY_STRONG) continue - spawn(0) - var/iter = 5-get_dist(A,target) - for(var/i=0 to iter) - step_away(A,target) - sleep(2) - var/turf/T = get_turf(target) - log_game("[key_name(chassis.occupant)] used a Gravitational Catapult repulse wave on [AREACOORD(T)]") - return TRUE + if(ismob(A)) + var/mob/M = A + if(M.mob_negates_gravity()) + continue + INVOKE_ASYNC(src, .proc/do_scatter, A, target) + var/turf/T = get_turf(target) + log_game("[key_name(source)] used a Gravitational Catapult repulse wave on [AREACOORD(T)]") + return ..() + +/obj/item/mecha_parts/mecha_equipment/gravcatapult/proc/do_scatter(atom/movable/A, atom/movable/target) + var/iter = 5-get_dist(A,target) + for(var/i in 0 to iter) + step_away(A,target) + sleep(2) /obj/item/mecha_parts/mecha_equipment/gravcatapult/get_equip_info() return "[..()] [mode==1?"([locked||"Nothing"])":null] \[S|P\]" @@ -129,7 +141,7 @@ ..() if(href_list["mode"]) mode = text2num(href_list["mode"]) - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) + send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",src.get_equip_info()) return @@ -150,9 +162,10 @@ selectable = 0 /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/proc/attack_react() - if(action_checks(src)) - start_cooldown() - return 1 + if(energy_drain && !chassis.has_charge(energy_drain)) + return FALSE + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_ARMOR, equip_cooldown) + return TRUE @@ -168,9 +181,10 @@ selectable = 0 /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/proc/projectile_react() - if(action_checks(src)) - start_cooldown() - return 1 + if(energy_drain && !chassis.has_charge(energy_drain)) + return FALSE + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_ARMOR, equip_cooldown) + return TRUE ////////////////////////////////// REPAIR DROID ////////////////////////////////////////////////// @@ -193,7 +207,7 @@ chassis.cut_overlay(droid_overlay) return ..() -/obj/item/mecha_parts/mecha_equipment/repair_droid/attach(obj/mecha/M as obj) +/obj/item/mecha_parts/mecha_equipment/repair_droid/attach(obj/vehicle/sealed/mecha/M) ..() droid_overlay = new(src.icon, icon_state = "repair_droid") M.add_overlay(droid_overlay) @@ -216,21 +230,18 @@ if(equip_ready) START_PROCESSING(SSobj, src) droid_overlay = new(src.icon, icon_state = "repair_droid_a") - mecha_log_message("Activated.") - set_ready_state(0) + log_message("Activated.", LOG_MECHA) else STOP_PROCESSING(SSobj, src) droid_overlay = new(src.icon, icon_state = "repair_droid") - mecha_log_message("Deactivated.") - set_ready_state(1) + log_message("Deactivated.", LOG_MECHA) chassis.add_overlay(droid_overlay) - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) + send_byjax(chassis.occupants,"exosuit.browser", "[REF(src)]", get_equip_info()) /obj/item/mecha_parts/mecha_equipment/repair_droid/process() if(!chassis) STOP_PROCESSING(SSobj, src) - set_ready_state(1) return var/h_boost = health_boost var/repaired = 0 @@ -242,16 +253,14 @@ chassis.clearInternalDamage(int_dam_flag) repaired = 1 break - if(health_boost<0 || chassis.obj_integrity < chassis.max_integrity) - chassis.obj_integrity += min(health_boost, chassis.max_integrity-chassis.obj_integrity) + if(h_boost<0 || chassis.obj_integrity < chassis.max_integrity) + chassis.obj_integrity += min(h_boost, chassis.max_integrity-chassis.obj_integrity) repaired = 1 if(repaired) if(!chassis.use_power(energy_drain)) STOP_PROCESSING(SSobj, src) - set_ready_state(1) else //no repair needed, we turn off STOP_PROCESSING(SSobj, src) - set_ready_state(1) chassis.cut_overlay(droid_overlay) droid_overlay = new(src.icon, icon_state = "repair_droid") chassis.add_overlay(droid_overlay) @@ -284,12 +293,12 @@ if(equip_ready) //disabled return var/area/A = get_area(chassis) - var/pow_chan = get_MUTATION_POWER_channel(A) + var/pow_chan = GET_MUTATION_POWER_channel(A) if(pow_chan) return 1000 //making magic -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_MUTATION_POWER_channel(var/area/A) +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/GET_MUTATION_POWER_channel(area/A) var/pow_chan if(A) for(var/c in use_channels) @@ -303,12 +312,10 @@ if(href_list["toggle_relay"]) if(equip_ready) //inactive START_PROCESSING(SSobj, src) - set_ready_state(0) - mecha_log_message("Activated.") + log_message("Activated.", LOG_MECHA) else STOP_PROCESSING(SSobj, src) - set_ready_state(1) - mecha_log_message("Deactivated.") + log_message("Deactivated.", LOG_MECHA) /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/get_equip_info() if(!chassis) @@ -319,19 +326,17 @@ /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/process() if(!chassis || chassis.internal_damage & MECHA_INT_SHORT_CIRCUIT) STOP_PROCESSING(SSobj, src) - set_ready_state(1) return var/cur_charge = chassis.get_charge() if(isnull(cur_charge) || !chassis.cell) STOP_PROCESSING(SSobj, src) - set_ready_state(1) - occupant_message("No powercell detected.") + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]No power cell detected.") return if(cur_charge < chassis.cell.maxcharge) - var/area/A = get_base_area(chassis) + var/area/A = get_area(chassis) if(A) var/pow_chan - for(var/c in list(EQUIP,ENVIRON,LIGHT)) + for(var/c in use_channels) if(A.powered(c)) pow_chan = c break @@ -350,7 +355,7 @@ name = "exosuit plasma converter" desc = "An exosuit module that generates power using solid plasma as fuel. Pollutes the environment." icon_state = "tesla" - range = MELEE + range = MECHA_MELEE var/coeff = 100 var/obj/item/stack/sheet/fuel var/max_fuel = 150000 @@ -358,7 +363,7 @@ var/fuel_per_cycle_active = 200 var/power_per_cycle = 20 -/obj/item/mecha_parts/mecha_equipment/generator/Initialize() +/obj/item/mecha_parts/mecha_equipment/generator/Initialize(mapload) . = ..() generator_init() @@ -377,77 +382,54 @@ ..() if(href_list["toggle"]) if(equip_ready) //inactive - set_ready_state(0) START_PROCESSING(SSobj, src) - mecha_log_message("Activated.") + log_message("Activated.", LOG_MECHA) else - set_ready_state(1) STOP_PROCESSING(SSobj, src) - mecha_log_message("Deactivated.") + log_message("Deactivated.", LOG_MECHA) /obj/item/mecha_parts/mecha_equipment/generator/get_equip_info() var/output = ..() if(output) return "[output] \[[fuel]: [round(fuel.amount*MINERAL_MATERIAL_AMOUNT,0.1)] cm3\] - [equip_ready?"A":"Dea"]ctivate" -/obj/item/mecha_parts/mecha_equipment/generator/action(target) +/obj/item/mecha_parts/mecha_equipment/generator/action(mob/source, atom/movable/target, params) if(chassis) - var/result = load_fuel(target) - if(result) - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) + if(load_fuel(target, source)) + send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",src.get_equip_info()) + return ..() -/obj/item/mecha_parts/mecha_equipment/generator/proc/load_fuel(var/obj/item/stack/sheet/P) +/obj/item/mecha_parts/mecha_equipment/generator/proc/load_fuel(obj/item/stack/sheet/P, mob/user) if(P.type == fuel.type && P.amount > 0) var/to_load = max(max_fuel - fuel.amount*MINERAL_MATERIAL_AMOUNT,0) if(to_load) var/units = min(max(round(to_load / MINERAL_MATERIAL_AMOUNT),1),P.amount) fuel.amount += units P.use(units) - occupant_message("[units] unit\s of [fuel] successfully loaded.") + to_chat(user, "[icon2html(src, user)][units] unit\s of [fuel] successfully loaded.") return units else - occupant_message("Unit is full.") + to_chat(user, "[icon2html(src, user)]Unit is full.") return 0 else - occupant_message("[fuel] traces in target minimal! [P] cannot be used as fuel.") + to_chat(user, "[icon2html(src, user)][fuel] traces in target minimal! [P] cannot be used as fuel.") return /obj/item/mecha_parts/mecha_equipment/generator/attackby(weapon,mob/user, params) load_fuel(weapon) -/obj/item/mecha_parts/mecha_equipment/generator/critfail() - ..() - var/turf/open/T = get_turf(src) - if(!istype(T)) - return - var/datum/gas_mixture/GM = new - if(prob(10)) - GM.adjust_moles(GAS_PLASMA,100) - GM.set_temperature(1500+T0C) //should be enough to start a fire - T.visible_message("[src] suddenly disgorges a cloud of heated plasma.") - qdel(src) - else - GM.adjust_moles(GAS_PLASMA,5) - GM.set_temperature(istype(T) ? T.air.return_temperature() : T20C) - T.visible_message("[src] suddenly disgorges a cloud of plasma.") - T.assume_air(GM) - return - /obj/item/mecha_parts/mecha_equipment/generator/process() if(!chassis) STOP_PROCESSING(SSobj, src) - set_ready_state(1) return if(fuel.amount<=0) STOP_PROCESSING(SSobj, src) - mecha_log_message("Deactivated - no fuel.") - set_ready_state(1) + log_message("Deactivated - no fuel.", LOG_MECHA) return var/cur_charge = chassis.get_charge() if(isnull(cur_charge)) - set_ready_state(1) - occupant_message("No powercell detected.") - mecha_log_message("Deactivated.") + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]No power cell detected.") + log_message("Deactivated.", LOG_MECHA) STOP_PROCESSING(SSobj, src) return var/use_fuel = fuel_per_cycle_idle @@ -456,7 +438,7 @@ chassis.give_power(power_per_cycle) fuel.amount -= min(use_fuel/MINERAL_MATERIAL_AMOUNT,fuel.amount) update_equip_info() - return 1 + return TRUE /obj/item/mecha_parts/mecha_equipment/generator/nuclear @@ -472,9 +454,118 @@ /obj/item/mecha_parts/mecha_equipment/generator/nuclear/generator_init() fuel = new /obj/item/stack/sheet/mineral/uranium(src, 0) -/obj/item/mecha_parts/mecha_equipment/generator/nuclear/critfail() - return - /obj/item/mecha_parts/mecha_equipment/generator/nuclear/process() if(..()) radiation_pulse(get_turf(src), rad_per_cycle) + + +/////////////////////////////////////////// THRUSTERS ///////////////////////////////////////////// + +/obj/item/mecha_parts/mecha_equipment/thrusters + name = "generic exosuit thrusters" //parent object, in-game sources will be a child object + desc = "A generic set of thrusters, from an unknown source. Uses not-understood methods to propel exosuits seemingly for free." + icon_state = "thrusters" + selectable = FALSE + var/effect_type = /obj/effect/particle_effect/sparks + +/obj/item/mecha_parts/mecha_equipment/thrusters/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M) + for(var/obj/item/I in M.equipment) + if(istype(I, src)) + to_chat(user, "[M] already has this thruster package!") + return FALSE + . = ..() + +/obj/item/mecha_parts/mecha_equipment/thrusters/attach(obj/vehicle/sealed/mecha/M) + M.active_thrusters = src //Enable by default + . = ..() + +/obj/item/mecha_parts/mecha_equipment/thrusters/detach() + if(chassis?.active_thrusters == src) + chassis.active_thrusters = null + . = ..() + +/obj/item/mecha_parts/mecha_equipment/thrusters/Destroy() + if(chassis?.active_thrusters == src) + chassis.active_thrusters = null + . = ..() + +/obj/item/mecha_parts/mecha_equipment/thrusters/Topic(href,href_list) + ..() + if(!chassis) + return + if(href_list["mode"]) + var/mode = text2num(href_list["mode"]) + switch(mode) + if(0) + enable() + if(1) + disable() + return + +/obj/item/mecha_parts/mecha_equipment/thrusters/proc/enable() + if (chassis.active_thrusters == src) + return + chassis.active_thrusters = src + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)][src] enabled.") + +/obj/item/mecha_parts/mecha_equipment/thrusters/proc/disable() + if(chassis.active_thrusters != src) + return + chassis.active_thrusters = null + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)][src] disabled.") + +/obj/item/mecha_parts/mecha_equipment/thrusters/get_equip_info() + return "[..()] \[Enable|Disable\]" + +/obj/item/mecha_parts/mecha_equipment/thrusters/proc/thrust(movement_dir) + if(!chassis) + return FALSE + generate_effect(movement_dir) + return TRUE //This parent should never exist in-game outside admeme use, so why not let it be a creative thruster? + +/obj/item/mecha_parts/mecha_equipment/thrusters/proc/generate_effect(movement_dir) + var/obj/effect/particle_effect/E = new effect_type(get_turf(chassis)) + E.dir = turn(movement_dir, 180) + step(E, turn(movement_dir, 180)) + QDEL_IN(E, 5) + + +/obj/item/mecha_parts/mecha_equipment/thrusters/gas + name = "RCS thruster package" + desc = "A set of thrusters that allow for exosuit movement in zero-gravity environments, by expelling gas from the internal life support tank." + effect_type = /obj/effect/particle_effect/smoke + var/move_cost = 20 //moles per step + +/obj/item/mecha_parts/mecha_equipment/thrusters/gas/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M) + if(!M.internal_tank) + to_chat(user, "[M] does not have an internal tank and cannot support this upgrade!") + return FALSE + . = ..() + +/obj/item/mecha_parts/mecha_equipment/thrusters/gas/thrust(movement_dir) + if(!chassis || !chassis.internal_tank) + return FALSE + var/moles = chassis.internal_tank.air_contents.total_moles() + if(moles < move_cost) + chassis.internal_tank.air_contents.remove(moles) + return FALSE + chassis.internal_tank.air_contents.remove(move_cost) + generate_effect(movement_dir) + return TRUE + + + +/obj/item/mecha_parts/mecha_equipment/thrusters/ion //for mechs with built-in thrusters, should never really exist un-attached to a mech + name = "Ion thruster package" + desc = "A set of thrusters that allow for exosuit movement in zero-gravity environments." + detachable = FALSE + salvageable = FALSE + effect_type = /obj/effect/particle_effect/ion_trails + +/obj/item/mecha_parts/mecha_equipment/thrusters/ion/thrust(movement_dir) + if(!chassis) + return FALSE + if(chassis.use_power(chassis.step_energy_drain)) + generate_effect(movement_dir) + return TRUE + return FALSE diff --git a/code/modules/vehicles/mecha/equipment/tools/weapon_bay.dm b/code/modules/vehicles/mecha/equipment/tools/weapon_bay.dm new file mode 100644 index 0000000000..469d430328 --- /dev/null +++ b/code/modules/vehicles/mecha/equipment/tools/weapon_bay.dm @@ -0,0 +1,14 @@ +/obj/item/mecha_parts/concealed_weapon_bay + name = "concealed weapon bay" + desc = "A compartment that allows a non-combat mecha to equip one weapon while hiding the weapon from plain sight." + icon = 'icons/mecha/mecha_equipment.dmi' + icon_state = "mecha_weapon_bay" + +/obj/item/mecha_parts/concealed_weapon_bay/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M) + if(istype(M, /obj/vehicle/sealed/mecha/combat)) + to_chat(user, "[M] can already hold weapons!") + return + if(locate(/obj/item/mecha_parts/concealed_weapon_bay) in M.contents) + to_chat(user, "[M] already has a concealed weapon bay!") + return + ..() diff --git a/code/modules/vehicles/mecha/equipment/tools/work_tools.dm b/code/modules/vehicles/mecha/equipment/tools/work_tools.dm new file mode 100644 index 0000000000..dd9448a826 --- /dev/null +++ b/code/modules/vehicles/mecha/equipment/tools/work_tools.dm @@ -0,0 +1,410 @@ + +//Hydraulic clamp, Kill clamp, Extinguisher, RCD, Cable layer. + + +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp + name = "hydraulic clamp" + desc = "Equipment for engineering exosuits. Lifts objects and loads them into cargo." + icon_state = "mecha_clamp" + equip_cooldown = 15 + energy_drain = 10 + tool_behaviour = TOOL_RETRACTOR + range = MECHA_MELEE + toolspeed = 0.8 + var/dam_force = 20 + var/obj/vehicle/sealed/mecha/working/ripley/cargo_holder + harmful = TRUE + mech_flags = EXOSUIT_MODULE_RIPLEY + +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/can_attach(obj/vehicle/sealed/mecha/working/ripley/M) + if(..()) + if(istype(M)) + return 1 + return 0 + +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/attach(obj/vehicle/sealed/mecha/M) + ..() + cargo_holder = M + return + +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/detach(atom/moveto = null) + ..() + cargo_holder = null + +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/action(mob/source, atom/target, params) + if(!action_checks(target)) + return + if(!cargo_holder) + return + if(ismecha(target)) + var/obj/vehicle/sealed/mecha/M = target + var/have_ammo + for(var/obj/item/mecha_ammo/box in cargo_holder.cargo) + if(istype(box, /obj/item/mecha_ammo) && box.rounds) + have_ammo = TRUE + if(M.ammo_resupply(box, source, TRUE)) + return + if(have_ammo) + to_chat(source, "No further supplies can be provided to [M].") + else + to_chat(source, "No providable supplies found in cargo hold") + return + if(isobj(target)) + var/obj/O = target + if(istype(O, /obj/machinery/door/firedoor)) + var/obj/machinery/door/firedoor/D = O + D.try_to_crowbar(src, source) + return + if(istype(O, /obj/machinery/door/airlock/)) + var/obj/machinery/door/airlock/D = O + D.try_to_crowbar(src, source) + return + if(!O.anchored) + if(cargo_holder.cargo.len < cargo_holder.cargo_capacity) + chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") + O.set_anchored(TRUE) + if(do_after_cooldown(target, source)) + cargo_holder.cargo += O + O.forceMove(chassis) + O.set_anchored(FALSE) + to_chat(source, "[icon2html(src, source)][target] successfully loaded.") + log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]", LOG_MECHA) + else + O.set_anchored(initial(O.anchored)) + else + to_chat(source, "[icon2html(src, source)]Not enough room in cargo compartment!") + else + to_chat(source, "[icon2html(src, source)][target] is firmly secured!") + + else if(isliving(target)) + var/mob/living/M = target + if(M.stat == DEAD) + return + if(source.a_intent == INTENT_HARM) + M.take_overall_damage(dam_force) + if(!M) + return + M.adjustOxyLoss(round(dam_force/2)) + M.updatehealth() + target.visible_message("[chassis] squeezes [target]!", \ + "[chassis] squeezes you!",\ + "You hear something crack.") + log_combat(source, M, "attacked", "[name]", "(INTENT: [uppertext(source.a_intent)]) (DAMTYPE: [uppertext(damtype)])") + else + step_away(M,chassis) + to_chat(source, "[icon2html(src, source)]You push [target] out of the way.") + chassis.visible_message("[chassis] pushes [target] out of the way.") + return ..() + + + +//This is pretty much just for the death-ripley +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill + name = "\improper KILL CLAMP" + desc = "They won't know what clamped them!" + energy_drain = 0 + dam_force = 0 + var/real_clamp = FALSE + +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/real + desc = "They won't know what clamped them! This time for real!" + energy_drain = 10 + dam_force = 20 + real_clamp = TRUE + +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/action(mob/source, atom/target, params) + if(!action_checks(target)) + return + if(!cargo_holder) + return + if(isobj(target)) + var/obj/O = target + if(!O.anchored) + if(cargo_holder.cargo.len < cargo_holder.cargo_capacity) + chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") + O.set_anchored(TRUE) + if(do_after_cooldown(target, source)) + cargo_holder.cargo += O + O.forceMove(chassis) + O.set_anchored(FALSE) + to_chat(source, "[icon2html(src, source)][target] successfully loaded.") + log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]", LOG_MECHA) + else + O.set_anchored(initial(O.anchored)) + else + to_chat(source, "[icon2html(src, source)]Not enough room in cargo compartment!") + else + to_chat(source, "[icon2html(src, source)][target] is firmly secured!") + + else if(isliving(target)) + var/mob/living/M = target + if(M.stat == DEAD) + return + if(source.a_intent == INTENT_HARM) + if(real_clamp) + M.take_overall_damage(dam_force) + if(!M) + return + M.adjustOxyLoss(round(dam_force/2)) + M.updatehealth() + target.visible_message("[chassis] destroys [target] in an unholy fury!", \ + "[chassis] destroys you in an unholy fury!") + log_combat(source, M, "attacked", "[name]", "(INTENT: [uppertext(source.a_intent)]) (DAMTYPE: [uppertext(damtype)])") + else + target.visible_message("[chassis] destroys [target] in an unholy fury!", \ + "[chassis] destroys you in an unholy fury!") + else if(source.a_intent == INTENT_DISARM) + if(real_clamp) + var/mob/living/carbon/C = target + var/play_sound = FALSE + var/limbs_gone = "" + var/obj/item/bodypart/affected = C.get_bodypart(BODY_ZONE_L_ARM) + if(affected != null) + affected.dismember(damtype) + play_sound = TRUE + limbs_gone = ", [affected]" + affected = C.get_bodypart(BODY_ZONE_R_ARM) + if(affected != null) + affected.dismember(damtype) + play_sound = TRUE + limbs_gone = "[limbs_gone], [affected]" + if(play_sound) + playsound(src, get_dismember_sound(), 80, TRUE) + target.visible_message("[chassis] rips [target]'s arms off!", \ + "[chassis] rips your arms off!") + log_combat(source, M, "dismembered of[limbs_gone],", "[name]", "(INTENT: [uppertext(source.a_intent)]) (DAMTYPE: [uppertext(damtype)])") + else + target.visible_message("[chassis] rips [target]'s arms off!", \ + "[chassis] rips your arms off!") + else + step_away(M,chassis) + target.visible_message("[chassis] tosses [target] like a piece of paper!", \ + "[chassis] tosses you like a piece of paper!") + return ..() + + + +/obj/item/mecha_parts/mecha_equipment/extinguisher + name = "exosuit extinguisher" + desc = "Equipment for engineering exosuits. A rapid-firing high capacity fire extinguisher." + icon_state = "mecha_exting" + equip_cooldown = 5 + energy_drain = 0 + range = MECHA_MELEE|MECHA_RANGED + mech_flags = EXOSUIT_MODULE_WORKING + +/obj/item/mecha_parts/mecha_equipment/extinguisher/Initialize(mapload) + . = ..() + create_reagents(1000) + reagents.add_reagent(/datum/reagent/water, 1000) + +/obj/item/mecha_parts/mecha_equipment/extinguisher/action(mob/source, atom/target, params) //copypasted from extinguisher. TODO: Rewrite from scratch.//Still todo + if(!action_checks(target) || get_dist(chassis, target)>3) + return + + if(istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1) + var/obj/structure/reagent_dispensers/watertank/WT = target + WT.reagents.trans_to(src, 1000) + to_chat(chassis.occupants,"Extinguisher refilled.") + playsound(chassis, 'sound/effects/refill.ogg', 50, 1, -6) + else + if(reagents.total_volume > 0) + playsound(chassis, 'sound/effects/extinguish.ogg', 75, 1, -3) + var/direction = get_dir(chassis,target) + var/turf/T = get_turf(target) + var/turf/T1 = get_step(T,turn(direction, 90)) + var/turf/T2 = get_step(T,turn(direction, -90)) + + var/list/the_targets = list(T,T1,T2) + spawn(0) + for(var/a=0, a<5, a++) + var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water(get_turf(chassis)) + if(!W) + return + var/turf/my_target = pick(the_targets) + var/datum/reagents/R = new/datum/reagents(5) + W.reagents = R + R.my_atom = W + reagents.trans_to(W,1) + for(var/b=0, b<4, b++) + if(!W) + return + step_towards(W,my_target) + if(!W) + return + var/turf/W_turf = get_turf(W) + W.reagents.reaction(W_turf) + for(var/atom/atm in W_turf) + W.reagents.reaction(atm) + if(W.loc == my_target) + break + sleep(2) + return 1 + +/obj/item/mecha_parts/mecha_equipment/extinguisher/get_equip_info() + return "[..()] \[[src.reagents.total_volume]\]" + +/obj/item/mecha_parts/mecha_equipment/extinguisher/can_attach(obj/vehicle/sealed/mecha/working/M as obj) + if(..()) + if(istype(M)) + return 1 + return 0 + + + +/obj/item/mecha_parts/mecha_equipment/rcd + name = "mounted RCD" + desc = "An exosuit-mounted Rapid Construction Device." + icon_state = "mecha_rcd" + equip_cooldown = 10 + energy_drain = 250 + range = MECHA_MELEE|MECHA_RANGED + item_flags = NO_MAT_REDEMPTION + var/mode = 0 //0 - deconstruct, 1 - wall or floor, 2 - airlock. + +/obj/item/mecha_parts/mecha_equipment/rcd/Initialize(mapload) + . = ..() + GLOB.rcd_list += src + +/obj/item/mecha_parts/mecha_equipment/rcd/Destroy() + GLOB.rcd_list -= src + return ..() + +/obj/item/mecha_parts/mecha_equipment/rcd/action(mob/source, atom/target, params) + if(istype(target, /turf/open/space/transit))//>implying these are ever made -Sieve + return + + if(!isturf(target) && !istype(target, /obj/machinery/door/airlock)) + target = get_turf(target) + if(!action_checks(target) || get_dist(chassis, target)>3) + return + playsound(chassis, 'sound/machines/click.ogg', 50, TRUE) + + switch(mode) + if(0) + if(iswallturf(target)) + var/turf/closed/wall/W = target + to_chat(source, "[icon2html(src, source)]Deconstructing [W]...") + if(do_after_cooldown(W, source)) + chassis.spark_system.start() + W.ScrapeAway(flags = CHANGETURF_INHERIT_AIR) + playsound(W, 'sound/items/deconstruct.ogg', 50, TRUE) + else if(isfloorturf(target)) + var/turf/open/floor/F = target + to_chat(source, "[icon2html(src, source)]Deconstructing [F]...") + if(do_after_cooldown(target, source)) + chassis.spark_system.start() + F.ScrapeAway(flags = CHANGETURF_INHERIT_AIR) + playsound(F, 'sound/items/deconstruct.ogg', 50, TRUE) + else if (istype(target, /obj/machinery/door/airlock)) + to_chat(source, "[icon2html(src, source)]Deconstructing [target]...") + if(do_after_cooldown(target, source)) + chassis.spark_system.start() + qdel(target) + playsound(target, 'sound/items/deconstruct.ogg', 50, TRUE) + if(1) + if(isspaceturf(target)) + var/turf/open/space/S = target + to_chat(source, "[icon2html(src, source)]Building Floor...") + if(do_after_cooldown(S, source)) + S.PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) + playsound(S, 'sound/items/deconstruct.ogg', 50, TRUE) + chassis.spark_system.start() + else if(isfloorturf(target)) + var/turf/open/floor/F = target + to_chat(source, "[icon2html(src, source)]Building Wall...") + if(do_after_cooldown(F, source)) + F.PlaceOnTop(/turf/closed/wall) + playsound(F, 'sound/items/deconstruct.ogg', 50, TRUE) + chassis.spark_system.start() + if(2) + if(isfloorturf(target)) + to_chat(source, "[icon2html(src, source)]Building Airlock...") + if(do_after_cooldown(target, source)) + chassis.spark_system.start() + var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock(target) + T.autoclose = TRUE + playsound(target, 'sound/items/deconstruct.ogg', 50, TRUE) + playsound(target, 'sound/effects/sparks2.ogg', 50, TRUE) + return ..() + +/obj/item/mecha_parts/mecha_equipment/rcd/Topic(href,href_list) + ..() + if(href_list["mode"]) + mode = text2num(href_list["mode"]) + switch(mode) + if(0) + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]Switched RCD to Deconstruct.") + energy_drain = initial(energy_drain) + if(1) + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]Switched RCD to Construct.") + energy_drain = 2*initial(energy_drain) + if(2) + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]Switched RCD to Construct Airlock.") + energy_drain = 2*initial(energy_drain) + return + +/obj/item/mecha_parts/mecha_equipment/rcd/get_equip_info() + return "[..()] \[D|C|A\]" + +//Dunno where else to put this so shrug +/obj/item/mecha_parts/mecha_equipment/ripleyupgrade + name = "Ripley MK-II Conversion Kit" + desc = "A pressurized canopy attachment kit for an Autonomous Power Loader Unit \"Ripley\" MK-I mecha, to convert it to the slower, but space-worthy MK-II design. This kit cannot be removed, once applied." + icon_state = "tesla" + mech_flags = EXOSUIT_MODULE_RIPLEY + +/obj/item/mecha_parts/mecha_equipment/ripleyupgrade/can_attach(obj/vehicle/sealed/mecha/working/ripley/M) + if(M.type != /obj/vehicle/sealed/mecha/working/ripley) + to_chat(loc, "This conversion kit can only be applied to APLU MK-I models.") + return FALSE + if(M.cargo.len) + to_chat(loc, "[M]'s cargo hold must be empty before this conversion kit can be applied.") + return FALSE + if(!(M.mecha_flags & ADDING_MAINT_ACCESS_POSSIBLE)) //non-removable upgrade, so lets make sure the pilot or owner has their say. + to_chat(loc, "[M] must have maintenance protocols active in order to allow this conversion kit.") + return FALSE + if(LAZYLEN(M.occupants)) //We're actualy making a new mech and swapping things over, it might get weird if players are involved + to_chat(loc, "[M] must be unoccupied before this conversion kit can be applied.") + return FALSE + if(!M.cell) //Turns out things break if the cell is missing + to_chat(loc, "The conversion process requires a cell installed.") + return FALSE + return TRUE + +/obj/item/mecha_parts/mecha_equipment/ripleyupgrade/attach(obj/vehicle/sealed/mecha/M) + var/obj/vehicle/sealed/mecha/working/ripley/mkii/N = new /obj/vehicle/sealed/mecha/working/ripley/mkii(get_turf(M),1) + if(!N) + return + QDEL_NULL(N.cell) + if (M.cell) + N.cell = M.cell + M.cell.forceMove(N) + M.cell = null + QDEL_NULL(N.scanmod) + if (M.scanmod) + N.scanmod = M.scanmod + M.scanmod.forceMove(N) + M.scanmod = null + QDEL_NULL(N.capacitor) + if (M.capacitor) + N.capacitor = M.capacitor + M.capacitor.forceMove(N) + M.capacitor = null + N.update_part_values() + for(var/obj/item/mecha_parts/E in M.contents) + if(istype(E, /obj/item/mecha_parts/concealed_weapon_bay)) //why is the bay not just a variable change who did this + E.forceMove(N) + for(var/obj/item/mecha_parts/mecha_equipment/E in M.equipment) //Move the equipment over... + E.detach(M) + E.attach(N) + N.dna_lock = M.dna_lock + N.mecha_flags = M.mecha_flags + N.strafe = M.strafe + N.obj_integrity = M.obj_integrity //This is not a repair tool + if (M.name != "\improper APLU MK-I \"Ripley\"") + N.name = M.name + M.wreckage = 0 + qdel(M) + playsound(get_turf(N),'sound/items/ratchet.ogg',50,TRUE) + return diff --git a/code/game/mecha/equipment/weapons/mecha_ammo.dm b/code/modules/vehicles/mecha/equipment/weapons/mecha_ammo.dm similarity index 94% rename from code/game/mecha/equipment/weapons/mecha_ammo.dm rename to code/modules/vehicles/mecha/equipment/weapons/mecha_ammo.dm index 3253e6cbd6..edc2b4716e 100644 --- a/code/game/mecha/equipment/weapons/mecha_ammo.dm +++ b/code/modules/vehicles/mecha/equipment/weapons/mecha_ammo.dm @@ -9,7 +9,7 @@ var/rounds = 0 var/round_term = "round" var/direct_load //For weapons where we re-load the weapon itself rather than adding to the ammo storage. - var/load_audio = "sound/weapons/gun_magazine_insert_empty_1.ogg" + var/load_audio = 'sound/weapons/bulletinsert.ogg' var/ammo_type /obj/item/mecha_ammo/update_name() @@ -62,7 +62,7 @@ rounds = 6 round_term = "missile" direct_load = TRUE - load_audio = "sound/weapons/bulletinsert.ogg" + load_audio = 'sound/weapons/bulletinsert.ogg' ammo_type = "missiles_br" /obj/item/mecha_ammo/missiles_he @@ -72,7 +72,7 @@ rounds = 8 round_term = "missile" direct_load = TRUE - load_audio = "sound/weapons/bulletinsert.ogg" + load_audio = 'sound/weapons/bulletinsert.ogg' ammo_type = "missiles_he" diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/modules/vehicles/mecha/equipment/weapons/weapons.dm similarity index 68% rename from code/game/mecha/equipment/weapons/weapons.dm rename to code/modules/vehicles/mecha/equipment/weapons/weapons.dm index 30bf06b475..b8818ef3f7 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/modules/vehicles/mecha/equipment/weapons/weapons.dm @@ -1,76 +1,64 @@ /obj/item/mecha_parts/mecha_equipment/weapon name = "mecha weapon" - range = RANGED + range = MECHA_RANGED + destroy_sound = 'sound/mecha/weapdestr.ogg' var/projectile var/fire_sound var/projectiles_per_shot = 1 var/variance = 0 - var/randomspread = 0 //use random spread for machineguns, instead of shotgun scatter + var/randomspread = FALSE //use random spread for machineguns, instead of shotgun scatter var/projectile_delay = 0 var/firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect //the visual effect appearing when the weapon is fired. var/kickback = TRUE //Will using this weapon in no grav push mecha back. mech_flags = EXOSUIT_MODULE_COMBAT -/obj/item/mecha_parts/mecha_equipment/weapon/can_attach(obj/mecha/combat/M) - if(..()) - if(istype(M)) - return 1 - return 0 +/obj/item/mecha_parts/mecha_equipment/weapon/can_attach(obj/vehicle/sealed/mecha/M) + if(!..()) + return FALSE + if(istype(M, /obj/vehicle/sealed/mecha/combat)) + return TRUE + if((locate(/obj/item/mecha_parts/concealed_weapon_bay) in M.contents) && !(locate(/obj/item/mecha_parts/mecha_equipment/weapon) in M.equipment)) + return TRUE + return FALSE -/obj/item/mecha_parts/mecha_equipment/weapon/proc/get_shot_amount() - return projectiles_per_shot - -/obj/item/mecha_parts/mecha_equipment/weapon/action(atom/target, params) +/obj/item/mecha_parts/mecha_equipment/weapon/action(mob/source, atom/target, list/modifiers) if(!action_checks(target)) - return 0 - - var/turf/curloc = get_turf(chassis) - var/turf/targloc = get_turf(target) - if (!targloc || !istype(targloc) || !curloc) - return 0 - if (targloc == curloc) - return 0 - - set_ready_state(0) - for(var/i=1 to get_shot_amount()) - var/obj/item/projectile/A = new projectile(curloc) - A.firer = chassis.occupant - A.original = target - if(!A.suppressed && firing_effect_type) - new firing_effect_type(get_turf(src), chassis.dir) - + return FALSE + var/newtonian_target = turn(chassis.dir,180) + . = ..()//start the cooldown early because of sleeps + for(var/i in 1 to projectiles_per_shot) + if(energy_drain && !chassis.has_charge(energy_drain))//in case we run out of energy mid-burst, such as emp + break var/spread = 0 if(variance) if(randomspread) spread = round((rand() - 0.5) * variance) else spread = round((i / projectiles_per_shot - 0.5) * variance) - A.preparePixelProjectile(target, chassis.occupant, params, spread) - A.fire() - playsound(chassis, fire_sound, 50, 1) + var/obj/item/projectile/projectile_obj = new projectile(get_turf(src)) + projectile_obj.log_override = TRUE //we log being fired ourselves a little further down. + projectile_obj.firer = chassis + projectile_obj.preparePixelProjectile(target, source, modifiers, spread) + + projectile_obj.fire() + if(!projectile_obj.suppressed && firing_effect_type) + new firing_effect_type(get_turf(src), chassis.dir) + playsound(chassis, fire_sound, 50, TRUE) + + log_combat(source, target, "fired [projectile_obj] at", src, "from [chassis] at [get_area_name(src, TRUE)]") sleep(max(0, projectile_delay)) - if(kickback) - chassis.newtonian_move(turn(chassis.dir,180)) - chassis.mecha_log_message("Fired from [src.name], targeting [target].") - return 1 - + if(kickback) + chassis.newtonian_move(newtonian_target) + chassis.log_message("[key_name(source)] fired [src], targeting [target].", LOG_ATTACK) //Base energy weapon type /obj/item/mecha_parts/mecha_equipment/weapon/energy name = "general energy weapon" firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/energy -/obj/item/mecha_parts/mecha_equipment/weapon/energy/get_shot_amount() - return min(round(chassis.cell.charge / energy_drain), projectiles_per_shot) - -/obj/item/mecha_parts/mecha_equipment/weapon/energy/start_cooldown() - set_ready_state(0) - chassis.use_power(energy_drain*get_shot_amount()) - addtimer(CALLBACK(src, .proc/set_ready_state, 1), equip_cooldown) - /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser equip_cooldown = 8 name = "\improper CH-PS \"Immolator\" laser" @@ -81,6 +69,15 @@ fire_sound = 'sound/weapons/laser.ogg' harmful = TRUE +/obj/item/mecha_parts/mecha_equipment/weapon/energy/disabler + equip_cooldown = 8 + name = "\improper CH-DS \"Peacemaker\" disabler" + desc = "A weapon for combat exosuits. Shoots basic disablers." + icon_state = "mecha_disabler" + energy_drain = 30 + projectile = /obj/item/projectile/beam/disabler + fire_sound = 'sound/weapons/taser2.ogg' + /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy equip_cooldown = 15 name = "\improper CH-LC \"Solaris\" laser cannon" @@ -97,7 +94,7 @@ icon_state = "mecha_ion" energy_drain = 120 projectile = /obj/item/projectile/ion - fire_sound = 'sound/weapons/IonRifle.ogg' + fire_sound = 'sound/weapons/laser.ogg' /obj/item/mecha_parts/mecha_equipment/weapon/energy/tesla equip_cooldown = 35 @@ -124,7 +121,6 @@ name = "217-D Heavy Plasma Cutter" desc = "A device that shoots resonant plasma bursts at extreme velocity. The blasts are capable of crushing rock and demolishing solid obstacles." icon_state = "mecha_plasmacutter" - item_state = "plasmacutter" lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' energy_drain = 30 @@ -132,12 +128,12 @@ fire_sound = 'sound/weapons/plasma_cutter.ogg' harmful = TRUE -/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma/can_attach(obj/mecha/working/M) +/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma/can_attach(obj/vehicle/sealed/mecha/M) if(..()) //combat mech - return 1 - else if(M.equipment.len < M.max_equip && istype(M)) - return 1 - return 0 + return TRUE + else if(LAZYLEN(M.equipment) < M.max_equip) + return TRUE + return FALSE /obj/item/mecha_parts/mecha_equipment/weapon/energy/taser name = "\improper PBT \"Pacifier\" mounted taser" @@ -155,47 +151,53 @@ icon_state = "mecha_honker" energy_drain = 200 equip_cooldown = 150 - range = MELEE|RANGED + range = MECHA_MELEE|MECHA_RANGED kickback = FALSE + mech_flags = EXOSUIT_MODULE_HONK -/obj/item/mecha_parts/mecha_equipment/weapon/honker/can_attach(obj/mecha/combat/honker/M) - if(..()) - if(istype(M)) - return 1 - return 0 +/obj/item/mecha_parts/mecha_equipment/weapon/honker/can_attach(obj/vehicle/sealed/mecha/mecha) + . = ..() + if(!.) + return + if(!istype(mecha, /obj/vehicle/sealed/mecha/combat/honker)) + return FALSE -/obj/item/mecha_parts/mecha_equipment/weapon/honker/action(target, params) + +/obj/item/mecha_parts/mecha_equipment/weapon/honker/action(mob/source, atom/target, params) if(!action_checks(target)) return - playsound(chassis, 'sound/items/airhorn.ogg', 100, 1) - chassis.occupant_message("HONK") + playsound(chassis, 'sound/items/airhorn.ogg', 100, TRUE) + to_chat(source, "[icon2html(src, source)]HONK") for(var/mob/living/carbon/M in ohearers(6, chassis)) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(istype(H.ears, /obj/item/clothing/ears/earmuffs)) - continue + if(!M.can_hear()) + continue + var/turf/turf_check = get_turf(M) + if(isspaceturf(turf_check) && !turf_check.Adjacent(src)) //in space nobody can hear you honk. + continue to_chat(M, "HONK") M.SetSleeping(0) M.stuttering += 20 - M.adjustEarDamage(0, 30) - M.DefaultCombatKnockdown(60) + var/obj/item/organ/ears/ears = M.getorganslot(ORGAN_SLOT_EARS) + if(ears) + ears.adjustEarDamage(0, 30) + M.Paralyze(60) if(prob(30)) M.Stun(200) M.Unconscious(80) else M.Jitter(500) - mecha_log_message("Honked from [src.name]. HONK!") + log_message("Honked from [src.name]. HONK!", LOG_MECHA) var/turf/T = get_turf(src) - message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] used a Mecha Honker in [ADMIN_VERBOSEJMP(T)]") - log_game("[key_name(chassis.occupant)] used a Mecha Honker in [AREACOORD(T)]") - return 1 + message_admins("[ADMIN_LOOKUPFLW(source)] used a Mecha Honker in [ADMIN_VERBOSEJMP(T)]") + log_game("[key_name(source)] used a Mecha Honker in [AREACOORD(T)]") + return ..() //Base ballistic weapon type /obj/item/mecha_parts/mecha_equipment/weapon/ballistic name = "general ballistic weapon" - fire_sound = 'sound/weapons/lmgshot.ogg' + fire_sound = 'sound/weapons/shot.ogg' var/projectiles var/projectiles_cache //ammo to be loaded in, if possible. var/projectiles_cache_max @@ -203,15 +205,12 @@ var/disabledreload //For weapons with no cache (like the rockets) which are reloaded by hand var/ammo_type -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_shot_amount() - return min(projectiles, projectiles_per_shot) - /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action_checks(target) if(!..()) - return 0 + return FALSE if(projectiles <= 0) - return 0 - return 1 + return FALSE + return TRUE /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_equip_info() return "[..()] \[[src.projectiles][projectiles_cache_max &&!projectile_energy_cost?"/[projectiles_cache]":""]\][!disabledreload &&(src.projectiles < initial(src.projectiles))?" - Rearm":null]" @@ -237,7 +236,8 @@ projectiles = projectiles + projectiles_cache projectiles_cache = 0 - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) + send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",src.get_equip_info()) + log_message("Rearmed [src.name].", LOG_MECHA) return TRUE @@ -252,11 +252,11 @@ src.rearm() return -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action(atom/target) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action(mob/source, atom/target, params) if(..()) - projectiles -= get_shot_amount() - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) - return 1 + projectiles -= projectiles_per_shot + send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",src.get_equip_info()) + return ..() /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine @@ -274,7 +274,7 @@ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced name = "\improper S.H.H. \"Quietus\" Carbine" desc = "A weapon for combat exosuits. A mime invention, field tests have shown that targets cannot even scream before going down." - fire_sound = 'sound/weapons/gunshot_silenced.ogg' + fire_sound = 'sound/weapons/Gunshot_silenced.ogg' icon_state = "mecha_mime" equip_cooldown = 30 projectile = /obj/item/projectile/bullet/mime @@ -285,7 +285,6 @@ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot name = "\improper LBX AC 10 \"Scattershot\"" desc = "A weapon for combat exosuits. Shoots a spread of pellets." - fire_sound = 'sound/weapons/gunshotshotgunshot.ogg' icon_state = "mecha_scatter" equip_cooldown = 20 projectile = /obj/item/projectile/bullet/scattershot @@ -342,9 +341,12 @@ harmful = TRUE ammo_type = "missiles_he" +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/spacecops + projectiles = 420 + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/breaching name = "\improper BRM-6 missile rack" - desc = "A weapon for combat exosuits. Launches low-explosive breaching missiles designed to explode only when striking a sturdy target." + desc = "A weapon for combat exosuits. Launches high-explosive breaching missiles with a safety fuze designed to explode only when striking a sturdy target." icon_state = "mecha_missilerack_six" projectile = /obj/item/projectile/bullet/a84mm_br fire_sound = 'sound/weapons/rocketlaunch.ogg' @@ -362,19 +364,19 @@ var/missile_range = 30 var/diags_first = FALSE -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/action(target) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/action(mob/source, atom/target, params) if(!action_checks(target)) return var/obj/O = new projectile(chassis.loc) - playsound(chassis, fire_sound, 50, 1) - mecha_log_message("Launched a [O.name] from [name], targeting [target].") + playsound(chassis, fire_sound, 50, TRUE) + log_message("Launched a [O.name] from [name], targeting [target].", LOG_MECHA) projectiles-- - proj_init(O) - O.throw_at(target, missile_range, missile_speed, chassis.occupant, FALSE, diagonals_first = diags_first) - return 1 + proj_init(O, source) + O.throw_at(target, missile_range, missile_speed, source, FALSE, diagonals_first = diags_first) + return TRUE //used for projectile initilisation (priming flashbang) and additional logging -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/proc/proj_init(var/obj/O) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/proc/proj_init(obj/O, mob/user) return @@ -392,10 +394,10 @@ var/det_time = 20 ammo_type = "flashbang" -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/proj_init(var/obj/item/grenade/flashbang/F) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/proj_init(obj/item/grenade/flashbang/F, mob/user) var/turf/T = get_turf(src) - message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] fired a [src] in [ADMIN_VERBOSEJMP(T)]") - log_game("[key_name(chassis.occupant)] fired a [src] in [AREACOORD(T)]") + message_admins("[ADMIN_LOOKUPFLW(user)] fired a [F] in [ADMIN_VERBOSEJMP(T)]") + log_game("[key_name(user)] fired a [F] in [AREACOORD(T)]") addtimer(CALLBACK(F, /obj/item/grenade/flashbang.proc/prime), det_time) /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/clusterbang //Because I am a heartless bastard -Sieve //Heartless? for making the poor man's honkblast? - Kaze @@ -419,8 +421,9 @@ missile_speed = 1.5 projectile_energy_cost = 100 equip_cooldown = 20 + mech_flags = EXOSUIT_MODULE_HONK -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/can_attach(obj/mecha/combat/honker/M) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/can_attach(obj/vehicle/sealed/mecha/combat/honker/M) if(..()) if(istype(M)) return 1 @@ -436,14 +439,15 @@ missile_speed = 1.5 projectile_energy_cost = 100 equip_cooldown = 10 + mech_flags = EXOSUIT_MODULE_HONK -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar/can_attach(obj/mecha/combat/honker/M) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar/can_attach(obj/vehicle/sealed/mecha/combat/honker/M) if(..()) if(istype(M)) return 1 return 0 -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar/proj_init(var/obj/item/assembly/mousetrap/armed/M) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar/proj_init(obj/item/assembly/mousetrap/armed/M) M.secured = 1 @@ -454,28 +458,58 @@ icon_state = "mecha_punching_glove" energy_drain = 250 equip_cooldown = 20 - range = MELEE|RANGED + range = MECHA_MELEE|MECHA_RANGED missile_range = 5 projectile = /obj/item/punching_glove fire_sound = 'sound/items/bikehorn.ogg' projectiles = 10 projectile_energy_cost = 500 + harmful = TRUE diags_first = TRUE + /// Damage done by the glove on contact. Also used to determine throw distance (damage / 5) + var/punch_damage = 35 + /// TRUE - Can toggle between lethal and non-lethal || FALSE - Cannot toggle + var/can_toggle_lethal = TRUE + mech_flags = EXOSUIT_MODULE_HONK -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/can_attach(obj/mecha/combat/honker/M) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/can_attach(obj/vehicle/sealed/mecha/combat/honker/M) if(..()) if(istype(M)) return 1 return 0 -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/action(target) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/get_equip_info() + if(!chassis) + return + + if(can_toggle_lethal) + return "[..()]   [harmful?"Punch":"Pat"] mode" + else + return ..() + +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/Topic(href, href_list) + ..() + if(href_list["lethalPunch"]) + harmful = !harmful + if(harmful) + to_chat(usr, "[icon2html(src, usr)]Lethal Fisting Enabled.") + else + to_chat(usr, "[icon2html(src, usr)]Lethal Fisting Disabled.") + +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/action(mob/source, atom/target, params) . = ..() if(.) - chassis.occupant_message("HONK") + to_chat(usr, "[icon2html(src, usr)]HONK") /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/proj_init(obj/item/punching_glove/PG) if(!istype(PG)) return + + if(harmful) + PG.throwforce = punch_damage + else + PG.throwforce = 0 + //has to be low sleep or it looks weird, the beam doesn't exist for very long so it's a non-issue chassis.Beam(PG, icon_state = "chain", time = missile_range * 20, maxdistance = missile_range + 2, beam_sleep_time = 1) @@ -489,5 +523,5 @@ if(!..()) if(ismovable(hit_atom)) var/atom/movable/AM = hit_atom - AM.safe_throw_at(get_edge_target_turf(AM,get_dir(src, AM)), 7, 2) + AM.safe_throw_at(get_edge_target_turf(AM,get_dir(src, AM)), clamp(round(throwforce/5), 2, 20), 2) //Throws them equal to damage/5, with a min range of 2 and max range of 20 qdel(src) diff --git a/code/game/mecha/mech_bay.dm b/code/modules/vehicles/mecha/mech_bay.dm similarity index 86% rename from code/game/mecha/mech_bay.dm rename to code/modules/vehicles/mecha/mech_bay.dm index e9f682e929..70fd27efef 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/modules/vehicles/mecha/mech_bay.dm @@ -5,7 +5,7 @@ icon_state = "recharge_floor" // Some people just want to watch the world burn i guess /turf/open/floor/mech_bay_recharge_floor/break_tile() - ScrapeAway() + ScrapeAway(flags = CHANGETURF_INHERIT_AIR) /turf/open/floor/mech_bay_recharge_floor/airless icon_state = "recharge_floor_asteroid" @@ -19,14 +19,22 @@ icon = 'icons/mecha/mech_bay.dmi' icon_state = "recharge_port" circuit = /obj/item/circuitboard/machine/mech_recharger - var/obj/mecha/recharging_mech + var/obj/vehicle/sealed/mecha/recharging_mech var/obj/machinery/computer/mech_bay_power_console/recharge_console var/max_charge = 50 var/on = FALSE - var/repairability = 0 var/turf/recharging_turf = null -/obj/machinery/mech_bay_recharge_port/Initialize() +/obj/machinery/mech_bay_recharge_port/Initialize(mapload) + . = ..() + recharging_turf = get_step(loc, dir) + +/obj/machinery/mech_bay_recharge_port/Destroy() + if (recharge_console && recharge_console.recharge_port == src) + recharge_console.recharge_port = null + return ..() + +/obj/machinery/mech_bay_recharge_port/setDir(new_dir) . = ..() recharging_turf = get_step(loc, dir) @@ -45,7 +53,7 @@ if(stat & NOPOWER || !recharge_console) return if(!recharging_mech) - recharging_mech = locate(/obj/mecha) in recharging_turf + recharging_mech = locate(/obj/vehicle/sealed/mecha) in recharging_turf if(recharging_mech) recharge_console.update_icon() if(recharging_mech && recharging_mech.cell) @@ -78,8 +86,8 @@ icon_screen = "recharge_comp" icon_keyboard = "rd_key" circuit = /obj/item/circuitboard/computer/mech_bay_power_console - var/obj/machinery/mech_bay_recharge_port/recharge_port light_color = LIGHT_COLOR_PINK + var/obj/machinery/mech_bay_recharge_port/recharge_port /obj/machinery/computer/mech_bay_power_console/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) @@ -133,6 +141,11 @@ return . += "recharge_comp_on" -/obj/machinery/computer/mech_bay_power_console/Initialize() +/obj/machinery/computer/mech_bay_power_console/Initialize(mapload) . = ..() reconnect() + +/obj/machinery/computer/mech_bay_power_console/Destroy() + if (recharge_port && recharge_port.recharge_console == src) + recharge_port.recharge_console = null + return ..() diff --git a/code/game/mecha/mech_fabricator.dm b/code/modules/vehicles/mecha/mech_fabricator.dm similarity index 99% rename from code/game/mecha/mech_fabricator.dm rename to code/modules/vehicles/mecha/mech_fabricator.dm index bbbfa7f1bd..29cc88a563 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/modules/vehicles/mecha/mech_fabricator.dm @@ -57,6 +57,8 @@ "Exosuit Equipment", "Exosuit Ammunition", "Cyborg Upgrade Modules", + "MODsuit Chassis", + "MODsuit Modules", "Cybernetics", "Implants", "Control Interfaces", diff --git a/code/modules/vehicles/mecha/mech_melee_attack.dm b/code/modules/vehicles/mecha/mech_melee_attack.dm new file mode 100644 index 0000000000..2f5faea172 --- /dev/null +++ b/code/modules/vehicles/mecha/mech_melee_attack.dm @@ -0,0 +1,117 @@ +///Called when a mech melee attacks an atom +/atom/proc/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker) + return + +/turf/closed/wall/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker) + mecha_attacker.do_attack_animation(src) + switch(mecha_attacker.damtype) + if(BRUTE) + playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE) + mecha_attacker.visible_message("[mecha_attacker.name] hits [src]!", \ + "You hit [src]!", null, COMBAT_MESSAGE_RANGE) + if(prob(hardness + mecha_attacker.force) && mecha_attacker.force > 20) + dismantle_wall(1) + playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE) + else + add_dent(WALL_DENT_HIT) + if(BURN) + playsound(src, 'sound/items/welder.ogg', 100, TRUE) + if(TOX) + playsound(src, 'sound/effects/spray2.ogg', 100, TRUE) + return FALSE + +/obj/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker) + mecha_attacker.do_attack_animation(src) + var/play_soundeffect = 0 + var/mech_damtype = mecha_attacker.damtype + if(mecha_attacker.selected) + mech_damtype = mecha_attacker.selected.damtype + play_soundeffect = 1 + else + switch(mecha_attacker.damtype) + if(BRUTE) + playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE) + if(BURN) + playsound(src, 'sound/items/welder.ogg', 50, TRUE) + if(TOX) + playsound(src, 'sound/effects/spray2.ogg', 50, TRUE) + return 0 + else + return 0 + mecha_attacker.visible_message("[mecha_attacker.name] hits [src]!", "You hit [src]!", null, COMBAT_MESSAGE_RANGE) + return take_damage(mecha_attacker.force * 3, mech_damtype, MELEE, play_soundeffect, get_dir(src, mecha_attacker)) // multiplied by 3 so we can hit objs hard but not be overpowered against mobs. + +/obj/structure/window/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker) + if(!can_be_reached()) + return + return ..() + +/mob/living/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker, mob/user) + if(user.a_intent == INTENT_HARM) + if(HAS_TRAIT(user, TRAIT_PACIFISM)) + to_chat(user, "You don't want to harm other living beings!") + return + mecha_attacker.do_attack_animation(src) + if(mecha_attacker.damtype == "brute") + step_away(src, mecha_attacker, 15) + switch(mecha_attacker.damtype) + if(BRUTE) + Unconscious(20) + take_overall_damage(rand(mecha_attacker.force/2, mecha_attacker.force)) + playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE) + if(BURN) + take_overall_damage(0, rand(mecha_attacker.force * 0.5, mecha_attacker.force)) + playsound(src, 'sound/items/welder.ogg', 50, TRUE) + if(TOX) + mecha_attacker.mech_toxin_damage(src) + else + return + updatehealth() + visible_message("[mecha_attacker.name] hits [src]!", \ + "[mecha_attacker.name] hits you!", "You hear a sickening sound of flesh hitting flesh!", COMBAT_MESSAGE_RANGE, mecha_attacker) + to_chat(mecha_attacker, "You hit [src]!") + log_combat(user, src, "attacked", mecha_attacker, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(mecha_attacker.damtype)])") + else + step_away(src, mecha_attacker) + log_combat(user, src, "pushed", mecha_attacker) + visible_message("[mecha_attacker] pushes [src] out of the way.", \ + "[mecha_attacker] pushes you out of the way.", "You hear aggressive shuffling!", 5, list(mecha_attacker)) + to_chat(mecha_attacker, "You push [src] out of the way.") + +/mob/living/carbon/human/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker, mob/user) + if(user.a_intent == INTENT_HARM) + if(HAS_TRAIT(user, TRAIT_PACIFISM)) + to_chat(user, "You don't want to harm other living beings!") + return + mecha_attacker.do_attack_animation(src) + if(mecha_attacker.damtype == BRUTE) + step_away(src, mecha_attacker, 15) + var/obj/item/bodypart/temp = get_bodypart(pick(BODY_ZONE_CHEST, BODY_ZONE_CHEST, BODY_ZONE_CHEST, BODY_ZONE_HEAD)) + if(temp) + var/update = 0 + var/dmg = rand(mecha_attacker.force * 0.5, mecha_attacker.force) + switch(mecha_attacker.damtype) + if(BRUTE) + if(mecha_attacker.force > 35) // durand and other heavy mechas + Unconscious(20) + else if(mecha_attacker.force > 20 && !IsKnockdown()) // lightweight mechas like gygax + Knockdown(40) + update |= temp.receive_damage(dmg, 0) + playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE) + if(BURN) + update |= temp.receive_damage(0, dmg) + playsound(src, 'sound/items/welder.ogg', 50, TRUE) + if(TOX) + mecha_attacker.mech_toxin_damage(src) + else + return + if(update) + update_damage_overlays() + updatehealth() + + visible_message("[mecha_attacker.name] hits [src]!", \ + "[mecha_attacker.name] hits you!", "You hear a sickening sound of flesh hitting flesh!", COMBAT_MESSAGE_RANGE, list(mecha_attacker)) + to_chat(mecha_attacker, "You hit [src]!") + log_combat(user, src, "attacked", mecha_attacker, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(mecha_attacker.damtype)])") + else + return ..() diff --git a/code/modules/vehicles/mecha/mecha_actions.dm b/code/modules/vehicles/mecha/mecha_actions.dm new file mode 100644 index 0000000000..09ccaad2c2 --- /dev/null +++ b/code/modules/vehicles/mecha/mecha_actions.dm @@ -0,0 +1,275 @@ +/***************** MECHA ACTIONS *****************/ + +/obj/vehicle/sealed/mecha/generate_action_type() + . = ..() + if(istype(., /datum/action/vehicle/sealed/mecha)) + var/datum/action/vehicle/sealed/mecha/mecha = . + mecha.chassis = src + + +/datum/action/vehicle/sealed/mecha + icon_icon = 'icons/mob/actions/actions_mecha.dmi' + var/obj/vehicle/sealed/mecha/chassis + +/datum/action/vehicle/sealed/mecha/Destroy() + chassis = null + return ..() + +/datum/action/vehicle/sealed/mecha/mech_eject + name = "Eject From Mech" + button_icon_state = "mech_eject" + +/datum/action/vehicle/sealed/mecha/mech_eject/Trigger() + if(!owner) + return + if(!chassis || !(owner in chassis.occupants)) + return + chassis.container_resist(owner) + +/datum/action/vehicle/sealed/mecha/mech_toggle_internals + name = "Toggle Internal Airtank Usage" + button_icon_state = "mech_internals_off" + +/datum/action/vehicle/sealed/mecha/mech_toggle_internals/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + chassis.use_internal_tank = !chassis.use_internal_tank + button_icon_state = "mech_internals_[chassis.use_internal_tank ? "on" : "off"]" + to_chat(chassis.occupants, "[icon2html(chassis, owner)]Now taking air from [chassis.use_internal_tank?"internal airtank":"environment"].") + chassis.log_message("Now taking air from [chassis.use_internal_tank?"internal airtank":"environment"].", LOG_MECHA) + UpdateButtonIcon() + +/datum/action/vehicle/sealed/mecha/mech_cycle_equip + name = "Cycle Equipment" + button_icon_state = "mech_cycle_equip_off" + +/datum/action/vehicle/sealed/mecha/mech_cycle_equip/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + + var/list/available_equipment = list() + for(var/e in chassis.equipment) + var/obj/item/mecha_parts/mecha_equipment/equipment = e + if(equipment.selectable) + available_equipment += equipment + + if(available_equipment.len == 0) + to_chat(owner, "[icon2html(chassis, owner)]No equipment available!") + return + if(!chassis.selected) + chassis.selected = available_equipment[1] + to_chat(owner, "[icon2html(chassis, owner)]You select [chassis.selected].") + send_byjax(chassis.occupants,"exosuit.browser","eq_list",chassis.get_equipment_list()) + button_icon_state = "mech_cycle_equip_on" + UpdateButtonIcon() + return + var/number = 0 + for(var/equipment in available_equipment) + number++ + if(equipment != chassis.selected) + continue + if(available_equipment.len == number) + chassis.selected = null + to_chat(owner, "[icon2html(chassis, owner)]You switch to no equipment.") + button_icon_state = "mech_cycle_equip_off" + else + chassis.selected = available_equipment[number+1] + to_chat(owner, "[icon2html(chassis, owner)]You switch to [chassis.selected].") + button_icon_state = "mech_cycle_equip_on" + send_byjax(chassis.occupants,"exosuit.browser","eq_list",chassis.get_equipment_list()) + UpdateButtonIcon() + return + + +/datum/action/vehicle/sealed/mecha/mech_toggle_lights + name = "Toggle Lights" + button_icon_state = "mech_lights_off" + +/datum/action/vehicle/sealed/mecha/mech_toggle_lights/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + if(!(chassis.mecha_flags & HAS_LIGHTS)) + to_chat(owner, "This mechs lights are destroyed!") + return + chassis.mecha_flags ^= LIGHTS_ON + if(chassis.mecha_flags & LIGHTS_ON) + button_icon_state = "mech_lights_on" + chassis.set_light(5, 5) + else + button_icon_state = "mech_lights_off" + chassis.set_light(0) + to_chat(owner, "[icon2html(chassis, owner)]Toggled lights [(chassis.mecha_flags & LIGHTS_ON)?"on":"off"].") + chassis.log_message("Toggled lights [(chassis.mecha_flags & LIGHTS_ON)?"on":"off"].", LOG_MECHA) + UpdateButtonIcon() + +/datum/action/vehicle/sealed/mecha/mech_view_stats + name = "View Stats" + button_icon_state = "mech_view_stats" + +/datum/action/vehicle/sealed/mecha/mech_view_stats/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + var/datum/browser/popup = new(owner , "exosuit") + popup.set_content(chassis.get_stats_html(owner)) + popup.open() + + +/datum/action/vehicle/sealed/mecha/strafe + name = "Toggle Strafing. Disabled when Alt is held." + button_icon_state = "strafe" + +/datum/action/vehicle/sealed/mecha/strafe/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + chassis.toggle_strafe() + +/obj/vehicle/sealed/mecha/AltClick(mob/living/user) + if(!(user in occupants) || !user.canUseTopic(src)) + return + if(!(user in return_controllers_with_flag(VEHICLE_CONTROL_DRIVE))) + to_chat(user, "You're in the wrong seat to control movement.") + return + + toggle_strafe() + +/obj/vehicle/sealed/mecha/proc/toggle_strafe() + strafe = !strafe + + to_chat(occupants, "[icon2html(src, occupants)]Toggled strafing mode [strafe?"on":"off"].") + log_message("Toggled strafing mode [strafe?"on":"off"].", LOG_MECHA) + + for(var/occupant in occupants) + var/datum/action/action = LAZYACCESSASSOC(occupant_actions, occupant, /datum/action/vehicle/sealed/mecha/strafe) + action?.UpdateButtonIcon() + +//////////////////////////////////////// Specific Ability Actions /////////////////////////////////////////////// +//Need to be granted by the mech type, Not default abilities. + +/datum/action/vehicle/sealed/mecha/mech_defense_mode + name = "Toggle an energy shield that blocks all attacks from the faced direction at a heavy power cost." + button_icon_state = "mech_defense_mode_off" + +/datum/action/vehicle/sealed/mecha/mech_defense_mode/Trigger(forced_state = FALSE) + SEND_SIGNAL(chassis, COMSIG_MECHA_ACTION_TRIGGER, owner, args) //Signal sent to the mech, to be handed to the shield. See durand.dm for more details + +/datum/action/vehicle/sealed/mecha/mech_overload_mode + name = "Toggle leg actuators overload" + button_icon_state = "mech_overload_off" + +/datum/action/vehicle/sealed/mecha/mech_overload_mode/Trigger(forced_state = null) + if(!owner || !chassis || !(owner in chassis.occupants)) + return + if(!isnull(forced_state)) + chassis.leg_overload_mode = forced_state + else + chassis.leg_overload_mode = !chassis.leg_overload_mode + chassis.log_message("Toggled leg actuators overload.", LOG_MECHA) + if(!chassis.leg_overload_mode) + button_icon_state = "mech_overload_on" + chassis.bumpsmash = TRUE + chassis.movedelay = min(1, round(chassis.movedelay * 0.5)) + chassis.step_energy_drain = max(chassis.overload_step_energy_drain_min,chassis.step_energy_drain*chassis.leg_overload_coeff) + to_chat(owner, "[icon2html(chassis, owner)]You enable leg actuators overload.") + else + button_icon_state = "mech_overload_off" + chassis.bumpsmash = FALSE + chassis.movedelay = initial(chassis.movedelay) + chassis.step_energy_drain = chassis.normal_step_energy_drain + to_chat(owner, "[icon2html(chassis, owner)]You disable leg actuators overload.") + UpdateButtonIcon() + +/datum/action/vehicle/sealed/mecha/mech_smoke + name = "Smoke" + button_icon_state = "mech_smoke" + +/datum/action/vehicle/sealed/mecha/mech_smoke/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + if(!TIMER_COOLDOWN_CHECK(src, COOLDOWN_MECHA_SMOKE) && chassis.smoke_charges>0) + chassis.smoke_system.start() + chassis.smoke_charges-- + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_SMOKE, chassis.smoke_cooldown) + + +/datum/action/vehicle/sealed/mecha/mech_zoom + name = "Zoom" + button_icon_state = "mech_zoom_off" + +/datum/action/vehicle/sealed/mecha/mech_zoom/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + if(owner.client) + chassis.zoom_mode = !chassis.zoom_mode + button_icon_state = "mech_zoom_[chassis.zoom_mode ? "on" : "off"]" + chassis.log_message("Toggled zoom mode.", LOG_MECHA) + to_chat(owner, "[icon2html(chassis, owner)]Zoom mode [chassis.zoom_mode?"en":"dis"]abled.") + if(chassis.zoom_mode) + owner.client.view_size.setTo(4.5) + SEND_SOUND(owner, sound('sound/mecha/imag_enh.ogg',volume=50)) + else + owner.client.view_size.resetToDefault() //Let's not let this stack shall we? + UpdateButtonIcon() + +/datum/action/vehicle/sealed/mecha/mech_switch_damtype + name = "Reconfigure arm microtool arrays" + button_icon_state = "mech_damtype_brute" + +/datum/action/vehicle/sealed/mecha/mech_switch_damtype/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + var/new_damtype + switch(chassis.damtype) + if("tox") + new_damtype = "brute" + to_chat(owner, "[icon2html(chassis, owner)]Your exosuit's hands form into fists.") + if("brute") + new_damtype = "fire" + to_chat(owner, "[icon2html(chassis, owner)]A torch tip extends from your exosuit's hand, glowing red.") + if("fire") + new_damtype = "tox" + to_chat(owner, "[icon2html(chassis, owner)]A bone-chillingly thick plasteel needle protracts from the exosuit's palm.") + chassis.damtype = new_damtype + button_icon_state = "mech_damtype_[new_damtype]" + playsound(chassis, 'sound/mecha/mechmove01.ogg', 50, TRUE) + UpdateButtonIcon() + +///swap seats, for two person mecha +/datum/action/vehicle/sealed/mecha/swap_seat + name = "Switch Seats" + button_icon_state = "mech_seat_swap" + +/datum/action/vehicle/sealed/mecha/swap_seat/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + + if(chassis.occupants.len == chassis.max_occupants) + to_chat(owner, "The other seat is occupied!") + return + var/list/drivers = chassis.return_drivers() + to_chat(owner, "Switching seats...") + chassis.is_currently_ejecting = TRUE + if(!do_after(owner, chassis.has_gravity() ? chassis.exit_delay : 0 , target = chassis)) + chassis.is_currently_ejecting = FALSE + return + chassis.is_currently_ejecting = FALSE + if(owner in drivers) + to_chat(owner, "You shift to the gunner seat!") + chassis.remove_control_flags(owner, VEHICLE_CONTROL_DRIVE|VEHICLE_CONTROL_SETTINGS) + chassis.add_control_flags(owner, VEHICLE_CONTROL_MELEE|VEHICLE_CONTROL_EQUIPMENT) + else + to_chat(owner, "You shift to the pilot seat!") + chassis.remove_control_flags(owner, VEHICLE_CONTROL_MELEE|VEHICLE_CONTROL_EQUIPMENT) + chassis.add_control_flags(owner, VEHICLE_CONTROL_DRIVE|VEHICLE_CONTROL_SETTINGS) + chassis.update_icon_state() + +/datum/action/vehicle/sealed/mecha/mech_toggle_phasing + name = "Toggle Phasing" + button_icon_state = "mech_phasing_off" + +/datum/action/vehicle/sealed/mecha/mech_toggle_phasing/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + chassis.phasing = !chassis.phasing + button_icon_state = "mech_phasing_[chassis.phasing ? "on" : "off"]" + to_chat(owner, "[icon2html(chassis, owner)]En":"#f00\">Dis"]abled phasing.") + UpdateButtonIcon() diff --git a/code/modules/vehicles/mecha/mecha_construction_paths.dm b/code/modules/vehicles/mecha/mecha_construction_paths.dm new file mode 100644 index 0000000000..ca79d98a64 --- /dev/null +++ b/code/modules/vehicles/mecha/mecha_construction_paths.dm @@ -0,0 +1,1448 @@ +//////////////////////////////// +///// Construction datums ////// +//////////////////////////////// +/datum/component/construction/mecha + var/base_icon + + // Component typepaths. + // most must be defined unless + // get_steps is overriden. + + // Circuit board typepaths. + // circuit_control and circuit_periph must be defined + // unless get_circuit_steps is overriden. + var/circuit_control + var/circuit_periph + var/circuit_weapon + + // Armor plating typepaths. both must be defined + // unless relevant step procs are overriden. amounts + // must be defined if using /obj/item/stack/sheet types + var/inner_plating + var/inner_plating_amount + + var/outer_plating + var/outer_plating_amount + +/datum/component/construction/mecha/spawn_result() + if(!result) + return + // Remove default mech power cell, as we replace it with a new one. + var/obj/vehicle/sealed/mecha/M = new result(drop_location()) + QDEL_NULL(M.cell) + QDEL_NULL(M.scanmod) + QDEL_NULL(M.capacitor) + + var/obj/item/mecha_parts/chassis/parent_chassis = parent + M.CheckParts(parent_chassis.contents) + + SSblackbox.record_feedback("tally", "mechas_created", 1, M.name) + QDEL_NULL(parent) + +// Default proc to generate mech steps. +// Override if the mech needs an entirely custom process (See HONK mech) +// Otherwise override specific steps as needed (Ripley, Clarke, Phazon) +/datum/component/construction/mecha/proc/get_steps() + return get_frame_steps() + get_circuit_steps() + (circuit_weapon ? get_circuit_weapon_steps() : list()) + get_stockpart_steps() + get_inner_plating_steps() + get_outer_plating_steps() + +/datum/component/construction/mecha/update_parent(step_index) + steps = get_steps() + ..() + // By default, each step in mech construction has a single icon_state: + // "[base_icon][index - 1]" + // For example, Ripley's step 1 icon_state is "ripley0". + var/atom/parent_atom = parent + if(!steps[index]["icon_state"] && base_icon) + parent_atom.icon_state = "[base_icon][index - 1]" + +/datum/component/construction/unordered/mecha_chassis/custom_action(obj/item/I, mob/living/user, typepath) + . = user.transferItemToLoc(I, parent) + if(.) + var/atom/parent_atom = parent + user.visible_message("[user] connects [I] to [parent].", "You connect [I] to [parent].") + parent_atom.add_overlay(I.icon_state+"+o") + qdel(I) + +/datum/component/construction/unordered/mecha_chassis/spawn_result() + var/atom/parent_atom = parent + parent_atom.icon = 'icons/mecha/mech_construction.dmi' + parent_atom.density = TRUE + parent_atom.cut_overlays() + ..() + +// Default proc for the first steps of mech construction. +/datum/component/construction/mecha/proc/get_frame_steps() + return list( + list( + "key" = TOOL_WRENCH, + "desc" = "The hydraulic systems are disconnected." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_WRENCH, + "desc" = "The hydraulic systems are connected." + ), + list( + "key" = /obj/item/stack/cable_coil, + "amount" = 5, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The hydraulic systems are active." + ), + list( + "key" = TOOL_WIRECUTTER, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The wiring is added." + ) + ) + +// Default proc for the circuit board steps of a mech. +// Second set of steps by default. +/datum/component/construction/mecha/proc/get_circuit_steps() + return list( + list( + "key" = circuit_control, + "action" = ITEM_DELETE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The wiring is adjusted." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Central control module is installed." + ), + list( + "key" = circuit_periph, + "action" = ITEM_DELETE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Central control module is secured." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Peripherals control module is installed." + ) + ) + +// Default proc for weapon circuitboard steps +// Used by combat mechs +/datum/component/construction/mecha/proc/get_circuit_weapon_steps() + return list( + list( + "key" = circuit_weapon, + "action" = ITEM_DELETE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Peripherals control module is secured." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Weapons control module is installed." + ) + ) + +// Default proc for stock part installation +// Third set of steps by default +/datum/component/construction/mecha/proc/get_stockpart_steps() + var/prevstep_text = circuit_weapon ? "Weapons control module is secured." : "Peripherals control module is secured." + return list( + list( + "key" = /obj/item/stock_parts/scanning_module, + "action" = ITEM_MOVE_INSIDE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = prevstep_text + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Scanner module is installed." + ), + list( + "key" = /obj/item/stock_parts/capacitor, + "action" = ITEM_MOVE_INSIDE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Scanner module is secured." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Capacitor is installed." + ), + list( + "key" = /obj/item/stock_parts/cell, + "action" = ITEM_MOVE_INSIDE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Capacitor is secured." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "The power cell is installed." + ) + ) + +// Default proc for inner armor plating +// Fourth set of steps by default +/datum/component/construction/mecha/proc/get_inner_plating_steps() + var/list/first_step + if(ispath(inner_plating, /obj/item/stack/sheet)) + first_step = list( + list( + "key" = inner_plating, + "amount" = inner_plating_amount, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The power cell is secured." + ) + ) + else + first_step = list( + list( + "key" = inner_plating, + "action" = ITEM_DELETE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The power cell is secured." + ) + ) + + return first_step + list( + list( + "key" = TOOL_WRENCH, + "back_key" = TOOL_CROWBAR, + "desc" = "Inner plating is installed." + ), + list( + "key" = TOOL_WELDER, + "back_key" = TOOL_WRENCH, + "desc" = "Inner Plating is wrenched." + ) + ) + +// Default proc for outer armor plating +// Fifth set of steps by default +/datum/component/construction/mecha/proc/get_outer_plating_steps() + var/list/first_step + if(ispath(outer_plating, /obj/item/stack/sheet)) + first_step = list( + list( + "key" = outer_plating, + "amount" = outer_plating_amount, + "back_key" = TOOL_WELDER, + "desc" = "Inner plating is welded." + ) + ) + else + first_step = list( + list( + "key" = outer_plating, + "action" = ITEM_DELETE, + "back_key" = TOOL_WELDER, + "desc" = "Inner plating is welded." + ) + ) + + return first_step + list( + list( + "key" = TOOL_WRENCH, + "back_key" = TOOL_CROWBAR, + "desc" = "External armor is installed." + ), + list( + "key" = TOOL_WELDER, + "back_key" = TOOL_WRENCH, + "desc" = "External armor is wrenched." + ) + ) + + +/datum/component/construction/unordered/mecha_chassis/ripley + result = /datum/component/construction/mecha/ripley + steps = list( + /obj/item/mecha_parts/part/ripley_torso, + /obj/item/mecha_parts/part/ripley_left_arm, + /obj/item/mecha_parts/part/ripley_right_arm, + /obj/item/mecha_parts/part/ripley_left_leg, + /obj/item/mecha_parts/part/ripley_right_leg + ) + +/datum/component/construction/mecha/ripley + result = /obj/vehicle/sealed/mecha/working/ripley + base_icon = "ripley" + + circuit_control = /obj/item/circuitboard/mecha/ripley/main + circuit_periph = /obj/item/circuitboard/mecha/ripley/peripherals + + inner_plating=/obj/item/stack/sheet/metal + inner_plating_amount = 5 + + outer_plating=/obj/item/stack/rods + outer_plating_amount = 10 + +/datum/component/construction/mecha/ripley/get_outer_plating_steps() + return list( + list( + "key" = /obj/item/stack/rods, + "amount" = 10, + "back_key" = TOOL_WELDER, + "desc" = "Outer Plating is welded." + ), + list( + "key" = TOOL_WELDER, + "back_key" = TOOL_WIRECUTTER, + "desc" = "Cockpit wire screen is installed." + ), + ) + +/datum/component/construction/mecha/ripley/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + switch(index) + if(1) + user.visible_message("[user] connects [parent] hydraulic systems.", "You connect [parent] hydraulic systems.") + if(2) + if(diff==FORWARD) + user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") + else + user.visible_message("[user] disconnects [parent] hydraulic systems.", "You disconnect [parent] hydraulic systems.") + if(3) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") + else + user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") + if(4) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") + else + user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") + if(5) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") + if(6) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + else + user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") + if(7) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + if(8) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + else + user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") + if(9) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + if(10) + if(diff==FORWARD) + user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") + else + user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") + if(11) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") + if(12) + if(diff==FORWARD) + user.visible_message("[user] secures [I].", "You secure [I].") + else + user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") + if(13) + if(diff==FORWARD) + user.visible_message("[user] installs [I].", "You install [I].") + else + user.visible_message("[user] unsecures the capacitor from [parent].", "You unsecure the capacitor from [parent].") + if(14) + if(diff==FORWARD) + user.visible_message("[user] secures the power cell.", "You secure the power cell.") + else + user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") + if(15) + if(diff==FORWARD) + user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") + if(16) + if(diff==FORWARD) + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") + else + user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") + if(17) + if(diff==FORWARD) + user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + if(18) + if(diff==FORWARD) + user.visible_message("[user] installs the external reinforced armor layer to [parent].", "You install the external reinforced armor layer to [parent].") + else + user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") + if(19) + if(diff==FORWARD) + user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") + else + user.visible_message("[user] pries external armor layer from [parent].", "You pry external armor layer from [parent].") + if(20) + if(diff==FORWARD) + user.visible_message("[user] welds the external armor layer to [parent].", "You weld the external armor layer to [parent].") + else + user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") + return TRUE + +/datum/component/construction/unordered/mecha_chassis/gygax + result = /datum/component/construction/mecha/gygax + steps = list( + /obj/item/mecha_parts/part/gygax_torso, + /obj/item/mecha_parts/part/gygax_left_arm, + /obj/item/mecha_parts/part/gygax_right_arm, + /obj/item/mecha_parts/part/gygax_left_leg, + /obj/item/mecha_parts/part/gygax_right_leg, + /obj/item/mecha_parts/part/gygax_head + ) + +/datum/component/construction/mecha/gygax + result = /obj/vehicle/sealed/mecha/combat/gygax + base_icon = "gygax" + + circuit_control = /obj/item/circuitboard/mecha/gygax/main + circuit_periph = /obj/item/circuitboard/mecha/gygax/peripherals + circuit_weapon = /obj/item/circuitboard/mecha/gygax/targeting + + inner_plating = /obj/item/stack/sheet/metal + inner_plating_amount = 5 + + outer_plating=/obj/item/mecha_parts/part/gygax_armor + outer_plating_amount=1 + +/datum/component/construction/mecha/gygax/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + switch(index) + if(1) + user.visible_message("[user] connects [parent] hydraulic systems.", "You connect [parent] hydraulic systems.") + if(2) + if(diff==FORWARD) + user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") + else + user.visible_message("[user] disconnects [parent] hydraulic systems.", "You disconnect [parent] hydraulic systems.") + if(3) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") + else + user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") + if(4) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") + else + user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") + if(5) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") + if(6) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + else + user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") + if(7) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + if(8) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + else + user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") + if(9) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + if(10) + if(diff==FORWARD) + user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") + else + user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") + if(11) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") + if(12) + if(diff==FORWARD) + user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") + else + user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") + if(13) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") + if(14) + if(diff==FORWARD) + user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") + else + user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") + if(15) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") + if(16) + if(diff==FORWARD) + user.visible_message("[user] secures the power cell.", "You secure the power cell.") + else + user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") + if(17) + if(diff==FORWARD) + user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") + if(18) + if(diff==FORWARD) + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") + else + user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") + if(19) + if(diff==FORWARD) + user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + if(20) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") + if(21) + if(diff==FORWARD) + user.visible_message("[user] secures Gygax Armor Plates.", "You secure Gygax Armor Plates.") + else + user.visible_message("[user] pries Gygax Armor Plates from [parent].", "You pry Gygax Armor Plates from [parent].") + if(22) + if(diff==FORWARD) + user.visible_message("[user] welds Gygax Armor Plates to [parent].", "You weld Gygax Armor Plates to [parent].") + else + user.visible_message("[user] unfastens Gygax Armor Plates.", "You unfasten Gygax Armor Plates.") + return TRUE + +//Begin Medigax +/datum/component/construction/unordered/mecha_chassis/medigax + result = /datum/component/construction/mecha/medigax + steps = list( + /obj/item/mecha_parts/part/medigax_torso, + /obj/item/mecha_parts/part/medigax_left_arm, + /obj/item/mecha_parts/part/medigax_right_arm, + /obj/item/mecha_parts/part/medigax_left_leg, + /obj/item/mecha_parts/part/medigax_right_leg, + /obj/item/mecha_parts/part/medigax_head + ) + +/datum/component/construction/mecha/medigax + result = /obj/vehicle/sealed/mecha/medical/medigax + base_icon = "medigax" + + circuit_control = /obj/item/circuitboard/mecha/gygax/main + circuit_periph = /obj/item/circuitboard/mecha/gygax/peripherals + circuit_weapon = /obj/item/circuitboard/mecha/gygax/targeting + + inner_plating = /obj/item/stack/sheet/metal + inner_plating_amount = 5 + + outer_plating = /obj/item/mecha_parts/part/medigax_armor + outer_plating_amount = 1 + +/datum/component/construction/mecha/medigax/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + switch(index) + if(1) + user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") + if(2) + if(diff==FORWARD) + user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") + else + user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") + if(3) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") + else + user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") + if(4) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") + else + user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") + if(5) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") + if(6) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + else + user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") + if(7) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + if(8) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + else + user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") + if(9) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + if(10) + if(diff==FORWARD) + user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") + else + user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") + if(11) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") + if(12) + if(diff==FORWARD) + user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") + else + user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") + if(13) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") + if(14) + if(diff==FORWARD) + user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") + else + user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") + if(15) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") + if(16) + if(diff==FORWARD) + user.visible_message("[user] secures the power cell.", "You secure the power cell.") + else + user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") + if(17) + if(diff==FORWARD) + user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") + if(18) + if(diff==FORWARD) + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") + else + user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") + if(19) + if(diff==FORWARD) + user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + if(20) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") + if(21) + if(diff==FORWARD) + user.visible_message("[user] secures Gygax Armor Plates.", "You secure Medical Gygax Armor Plates.") + else + user.visible_message("[user] pries Gygax Armor Plates from [parent].", "You pry Medical Gygax Armor Plates from [parent].") + if(22) + if(diff==FORWARD) + user.visible_message("[user] welds Gygax Armor Plates to [parent].", "You weld Medical Gygax Armor Plates to [parent].") + else + user.visible_message("[user] unfastens Gygax Armor Plates.", "You unfasten Medical Gygax Armor Plates.") + return TRUE +// End Medigax + +/datum/component/construction/unordered/mecha_chassis/firefighter + result = /datum/component/construction/mecha/firefighter + steps = list( + /obj/item/mecha_parts/part/ripley_torso, + /obj/item/mecha_parts/part/ripley_left_arm, + /obj/item/mecha_parts/part/ripley_right_arm, + /obj/item/mecha_parts/part/ripley_left_leg, + /obj/item/mecha_parts/part/ripley_right_leg + ) + +/datum/component/construction/mecha/firefighter + result = /obj/vehicle/sealed/mecha/working/ripley/firefighter + base_icon = "fireripley" + + circuit_control = /obj/item/circuitboard/mecha/ripley/main + circuit_periph = /obj/item/circuitboard/mecha/ripley/peripherals + + inner_plating = /obj/item/clothing/suit/fire + inner_plating_amount = 1 + + outer_plating = /obj/item/stack/sheet/plasteel + outer_plating_amount = 10 + +/datum/component/construction/mecha/firefighter/get_outer_plating_steps() + return list( + list( + "key" = /obj/item/stack/sheet/plasteel, + "amount" = 10, + "back_key" = TOOL_WELDER, + "desc" = "Outer plating is welded." + ), + list( + "key" = TOOL_WELDER, + "back_key" = TOOL_WRENCH, + "desc" = "Outer plating is complete." + ), + ) + +/datum/component/construction/mecha/firefighter/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + switch(index) + if(1) + user.visible_message("[user] connects [parent] hydraulic systems.", "You connect [parent] hydraulic systems.") + if(2) + if(diff==FORWARD) + user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") + else + user.visible_message("[user] disconnects [parent] hydraulic systems.", "You disconnect [parent] hydraulic systems.") + if(3) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") + else + user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") + if(4) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") + else + user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") + if(5) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") + if(6) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + else + user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") + if(7) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + if(8) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + else + user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") + if(9) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + if(10) + if(diff==FORWARD) + user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") + else + user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") + if(11) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") + if(12) + if(diff==FORWARD) + user.visible_message("[user] secures [I].", "You secure [I].") + else + user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") + if(13) + if(diff==FORWARD) + user.visible_message("[user] installs [I].", "You install [I].") + else + user.visible_message("[user] unsecures the capacitor from [parent].", "You unsecure the capacitor from [parent].") + if(14) + if(diff==FORWARD) + user.visible_message("[user] secures the power cell.", "You secure the power cell.") + else + user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") + if(15) + if(diff==FORWARD) + user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") + if(16) + if(diff==FORWARD) + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") + else + user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") + if(17) + if(diff==FORWARD) + user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + if(18) + if(diff==FORWARD) + user.visible_message("[user] installs the external reinforced armor layer to [parent].", "You install the external reinforced armor layer to [parent].") + else + user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") + if(19) + if(diff==FORWARD) + user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") + else + user.visible_message("[user] pries external armor layer from [parent].", "You pry external armor layer from [parent].") + if(20) + if(diff==FORWARD) + user.visible_message("[user] welds the external armor layer to [parent].", "You weld the external armor layer to [parent].") + else + user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") + return TRUE + +/datum/component/construction/unordered/mecha_chassis/honker + result = /datum/component/construction/mecha/honker + steps = list( + /obj/item/mecha_parts/part/honker_torso, + /obj/item/mecha_parts/part/honker_left_arm, + /obj/item/mecha_parts/part/honker_right_arm, + /obj/item/mecha_parts/part/honker_left_leg, + /obj/item/mecha_parts/part/honker_right_leg, + /obj/item/mecha_parts/part/honker_head + ) + +/datum/component/construction/mecha/honker + result = /obj/vehicle/sealed/mecha/combat/honker + steps = list( + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/circuitboard/mecha/honker/main, + "action" = ITEM_DELETE + ), + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/circuitboard/mecha/honker/peripherals, + "action" = ITEM_DELETE + ), + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/circuitboard/mecha/honker/targeting, + "action" = ITEM_DELETE + ), + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/stock_parts/scanning_module, + "action" = ITEM_MOVE_INSIDE + ), + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/stock_parts/capacitor, + "action" = ITEM_MOVE_INSIDE + ), + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/stock_parts/cell, + "action" = ITEM_MOVE_INSIDE + ), + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/clothing/mask/gas/clown_hat, + "action" = ITEM_DELETE + ), + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/clothing/shoes/clown_shoes, + "action" = ITEM_DELETE + ), + list( + "key" = /obj/item/bikehorn + ), + ) + +/datum/component/construction/mecha/honker/get_steps() + return steps + +// HONK doesn't have any construction step icons, so we just set an icon once. +/datum/component/construction/mecha/honker/update_parent(step_index) + if(step_index == 1) + var/atom/parent_atom = parent + parent_atom.icon = 'icons/mecha/mech_construct.dmi' + parent_atom.icon_state = "honker_chassis" + ..() + +/datum/component/construction/mecha/honker/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + if(istype(I, /obj/item/bikehorn)) + playsound(parent, 'sound/items/bikehorn.ogg', 50, TRUE) + user.visible_message("HONK!") + + //TODO: better messages. + switch(index) + if(2) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + if(4) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + if(6) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + if(8) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + if(10) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + if(12) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + if(14) + user.visible_message("[user] puts [I] on [parent].", "You put [I] on [parent].") + if(16) + user.visible_message("[user] puts [I] on [parent].", "You put [I] on [parent].") + return TRUE + +/datum/component/construction/unordered/mecha_chassis/durand + result = /datum/component/construction/mecha/durand + steps = list( + /obj/item/mecha_parts/part/durand_torso, + /obj/item/mecha_parts/part/durand_left_arm, + /obj/item/mecha_parts/part/durand_right_arm, + /obj/item/mecha_parts/part/durand_left_leg, + /obj/item/mecha_parts/part/durand_right_leg, + /obj/item/mecha_parts/part/durand_head + ) + +/datum/component/construction/mecha/durand + result = /obj/vehicle/sealed/mecha/combat/durand + base_icon = "durand" + + circuit_control = /obj/item/circuitboard/mecha/durand/main + circuit_periph = /obj/item/circuitboard/mecha/durand/peripherals + circuit_weapon = /obj/item/circuitboard/mecha/durand/targeting + + inner_plating = /obj/item/stack/sheet/metal + inner_plating_amount = 5 + + outer_plating = /obj/item/mecha_parts/part/durand_armor + outer_plating_amount = 1 + +/datum/component/construction/mecha/durand/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + //TODO: better messages. + switch(index) + if(1) + user.visible_message("[user] connects [parent] hydraulic systems.", "You connect [parent] hydraulic systems.") + if(2) + if(diff==FORWARD) + user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") + else + user.visible_message("[user] disconnects [parent] hydraulic systems.", "You disconnect [parent] hydraulic systems.") + if(3) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") + else + user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") + if(4) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") + else + user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") + if(5) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") + if(6) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + else + user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") + if(7) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + if(8) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + else + user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") + if(9) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + if(10) + if(diff==FORWARD) + user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") + else + user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") + if(11) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") + if(12) + if(diff==FORWARD) + user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") + else + user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") + if(13) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") + if(14) + if(diff==FORWARD) + user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") + else + user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") + if(15) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") + if(16) + if(diff==FORWARD) + user.visible_message("[user] secures the power cell.", "You secure the power cell.") + else + user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") + if(17) + if(diff==FORWARD) + user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") + if(18) + if(diff==FORWARD) + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") + else + user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") + if(19) + if(diff==FORWARD) + user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + if(20) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") + if(21) + if(diff==FORWARD) + user.visible_message("[user] secures Durand Armor Plates.", "You secure Durand Armor Plates.") + else + user.visible_message("[user] pries Durand Armor Plates from [parent].", "You pry Durand Armor Plates from [parent].") + if(22) + if(diff==FORWARD) + user.visible_message("[user] welds Durand Armor Plates to [parent].", "You weld Durand Armor Plates to [parent].") + else + user.visible_message("[user] unfastens Durand Armor Plates.", "You unfasten Durand Armor Plates.") + return TRUE + +//PHAZON + +/datum/component/construction/unordered/mecha_chassis/phazon + result = /datum/component/construction/mecha/phazon + steps = list( + /obj/item/mecha_parts/part/phazon_torso, + /obj/item/mecha_parts/part/phazon_left_arm, + /obj/item/mecha_parts/part/phazon_right_arm, + /obj/item/mecha_parts/part/phazon_left_leg, + /obj/item/mecha_parts/part/phazon_right_leg, + /obj/item/mecha_parts/part/phazon_head + ) + +/datum/component/construction/mecha/phazon + result = /obj/vehicle/sealed/mecha/combat/phazon + base_icon = "phazon" + + circuit_control = /obj/item/circuitboard/mecha/phazon/main + circuit_periph = /obj/item/circuitboard/mecha/phazon/peripherals + circuit_weapon = /obj/item/circuitboard/mecha/phazon/targeting + + inner_plating = /obj/item/stack/sheet/plasteel + inner_plating_amount = 5 + + outer_plating = /obj/item/mecha_parts/part/phazon_armor + outer_plating_amount = 1 + +/datum/component/construction/mecha/phazon/get_stockpart_steps() + return list( + list( + "key" = /obj/item/stock_parts/scanning_module, + "action" = ITEM_MOVE_INSIDE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Weapon control module is secured." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Scanner module is installed." + ), + list( + "key" = /obj/item/stock_parts/capacitor, + "action" = ITEM_MOVE_INSIDE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Scanner module is secured." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Capacitor is installed." + ), + list( + "key" = /obj/item/stack/ore/bluespace_crystal, + "amount" = 1, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Capacitor is secured." + ), + list( + "key" = /obj/item/stack/cable_coil, + "amount" = 5, + "back_key" = TOOL_CROWBAR, + "desc" = "The bluespace crystal is installed." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_WIRECUTTER, + "desc" = "The bluespace crystal is connected." + ), + list( + "key" = /obj/item/stock_parts/cell, + "action" = ITEM_MOVE_INSIDE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The bluespace crystal is engaged." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "The power cell is installed.", + "icon_state" = "phazon17" + // This is the point where a step icon is skipped, so "icon_state" had to be set manually starting from here. + ) + ) + +/datum/component/construction/mecha/phazon/get_outer_plating_steps() + return list( + list( + "key" = outer_plating, + "amount" = 1, + "action" = ITEM_DELETE, + "back_key" = TOOL_WELDER, + "desc" = "Internal armor is welded." + ), + list( + "key" = TOOL_WRENCH, + "back_key" = TOOL_CROWBAR, + "desc" = "External armor is installed." + ), + list( + "key" = TOOL_WELDER, + "back_key" = TOOL_WRENCH, + "desc" = "External armor is wrenched." + ), + list( + "key" = /obj/item/assembly/signaler/anomaly/bluespace, + "action" = ITEM_DELETE, + "back_key" = TOOL_WELDER, + "desc" = "Bluespace anomaly core socket is open.", + "icon_state" = "phazon24" + ) + ) + +/datum/component/construction/mecha/phazon/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + //TODO: better messages. + switch(index) + if(1) + user.visible_message("[user] connects [parent] hydraulic systems.", "You connect [parent] hydraulic systems.") + if(2) + if(diff==FORWARD) + user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") + else + user.visible_message("[user] disconnects [parent] hydraulic systems.", "You disconnect [parent] hydraulic systems.") + if(3) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") + else + user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") + if(4) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") + else + user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") + if(5) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") + if(6) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + else + user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") + if(7) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + if(8) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + else + user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") + if(9) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + if(10) + if(diff==FORWARD) + user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") + else + user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") + if(11) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") + if(12) + if(diff==FORWARD) + user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") + else + user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") + if(13) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") + if(14) + if(diff==FORWARD) + user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") + else + user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") + if(15) + if(diff==FORWARD) + user.visible_message("[user] installs [I].", "You install [I].") + else + user.visible_message("[user] unsecures the capacitor from [parent].", "You unsecure the capacitor from [parent].") + if(16) + if(diff==FORWARD) + user.visible_message("[user] connects the bluespace crystal.", "You connect the bluespace crystal.") + else + user.visible_message("[user] removes the bluespace crystal from [parent].", "You remove the bluespace crystal from [parent].") + if(17) + if(diff==FORWARD) + user.visible_message("[user] engages the bluespace crystal.", "You engage the bluespace crystal.") + else + user.visible_message("[user] disconnects the bluespace crystal from [parent].", "You disconnect the bluespace crystal from [parent].") + if(18) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disengages the bluespace crystal.", "You disengage the bluespace crystal.") + if(19) + if(diff==FORWARD) + user.visible_message("[user] secures the power cell.", "You secure the power cell.") + else + user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") + if(20) + if(diff==FORWARD) + user.visible_message("[user] installs the phase armor layer to [parent].", "You install the phase armor layer to [parent].") + else + user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") + if(21) + if(diff==FORWARD) + user.visible_message("[user] secures the phase armor layer.", "You secure the phase armor layer.") + else + user.visible_message("[user] pries the phase armor layer from [parent].", "You pry the phase armor layer from [parent].") + if(22) + if(diff==FORWARD) + user.visible_message("[user] welds the phase armor layer to [parent].", "You weld the phase armor layer to [parent].") + else + user.visible_message("[user] unfastens the phase armor layer.", "You unfasten the phase armor layer.") + if(23) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] cuts phase armor layer from [parent].", "You cut the phase armor layer from [parent].") + if(24) + if(diff==FORWARD) + user.visible_message("[user] secures Phazon Armor Plates.", "You secure Phazon Armor Plates.") + else + user.visible_message("[user] pries Phazon Armor Plates from [parent].", "You pry Phazon Armor Plates from [parent].") + if(25) + if(diff==FORWARD) + user.visible_message("[user] welds Phazon Armor Plates to [parent].", "You weld Phazon Armor Plates to [parent].") + else + user.visible_message("[user] unfastens Phazon Armor Plates.", "You unfasten Phazon Armor Plates.") + if(26) + if(diff==FORWARD) + user.visible_message("[user] carefully inserts the bluespace anomaly core into [parent] and secures it.", + "You slowly place the bluespace anomaly core into its socket and close its chamber.") + return TRUE + +//ODYSSEUS + +/datum/component/construction/unordered/mecha_chassis/odysseus + result = /datum/component/construction/mecha/odysseus + steps = list( + /obj/item/mecha_parts/part/odysseus_torso, + /obj/item/mecha_parts/part/odysseus_head, + /obj/item/mecha_parts/part/odysseus_left_arm, + /obj/item/mecha_parts/part/odysseus_right_arm, + /obj/item/mecha_parts/part/odysseus_left_leg, + /obj/item/mecha_parts/part/odysseus_right_leg + ) + +/datum/component/construction/mecha/odysseus + result = /obj/vehicle/sealed/mecha/medical/odysseus + base_icon = "odysseus" + + circuit_control = /obj/item/circuitboard/mecha/odysseus/main + circuit_periph = /obj/item/circuitboard/mecha/odysseus/peripherals + + inner_plating = /obj/item/stack/sheet/metal + inner_plating_amount = 5 + + outer_plating = /obj/item/stack/sheet/plasteel + outer_plating_amount = 5 + +/datum/component/construction/mecha/odysseus/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + //TODO: better messages. + switch(index) + if(1) + user.visible_message("[user] connects [parent] hydraulic systems.", "You connect [parent] hydraulic systems.") + if(2) + if(diff==FORWARD) + user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") + else + user.visible_message("[user] disconnects [parent] hydraulic systems.", "You disconnect [parent] hydraulic systems.") + if(3) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") + else + user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") + if(4) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") + else + user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") + if(5) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") + if(6) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + else + user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") + if(7) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + if(8) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + else + user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") + if(9) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + if(10) + if(diff==FORWARD) + user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") + else + user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") + if(11) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") + if(12) + if(diff==FORWARD) + user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") + else + user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") + if(13) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") + if(14) + if(diff==FORWARD) + user.visible_message("[user] secures the power cell.", "You secure the power cell.") + else + user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") + if(15) + if(diff==FORWARD) + user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") + if(16) + if(diff==FORWARD) + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") + else + user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") + if(17) + if(diff==FORWARD) + user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + if(18) + if(diff==FORWARD) + user.visible_message("[user] installs the external armor layer to [parent].", "You install the external reinforced armor layer to [parent].") + else + user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") + if(19) + if(diff==FORWARD) + user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") + else + user.visible_message("[user] pries the external armor layer from [parent].", "You pry the external armor layer from [parent].") + if(20) + if(diff==FORWARD) + user.visible_message("[user] welds the external armor layer to [parent].", "You weld the external armor layer to [parent].") + else + user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") + return TRUE diff --git a/code/game/mecha/mecha_control_console.dm b/code/modules/vehicles/mecha/mecha_control_console.dm similarity index 75% rename from code/game/mecha/mecha_control_console.dm rename to code/modules/vehicles/mecha/mecha_control_console.dm index ab547f4ccd..ff5ea13059 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/modules/vehicles/mecha/mecha_control_console.dm @@ -16,29 +16,29 @@ var/list/data = list() var/list/trackerlist = list() - for(var/obj/mecha/MC in GLOB.mechas_list) + for(var/obj/vehicle/sealed/mecha/MC in GLOB.mechas_list) trackerlist += MC.trackers data["mechs"] = list() for(var/obj/item/mecha_parts/mecha_tracking/MT in trackerlist) if(!MT.chassis) continue - var/obj/mecha/M = MT.chassis + var/obj/vehicle/sealed/mecha/M = MT.chassis var/list/mech_data = list( name = M.name, integrity = round((M.obj_integrity / M.max_integrity) * 100), charge = M.cell ? round(M.cell.percent()) : null, airtank = M.internal_tank ? M.return_pressure() : null, - pilot = list(M.occupant), + pilot = M.return_drivers(), location = get_area_name(M, TRUE), active_equipment = M.selected, emp_recharging = MT.recharging, tracker_ref = REF(MT) ) - if(istype(M, /obj/mecha/working/ripley)) - var/obj/mecha/working/ripley/RM = M + if(istype(M, /obj/vehicle/sealed/mecha/working/ripley)) + var/obj/vehicle/sealed/mecha/working/ripley/RM = M mech_data += list( - cargo_space = round((LAZYLEN(RM.cargo) / RM.cargo_capacity) * 100) + cargo_space = round((RM.cargo.len / RM.cargo_capacity) * 100) ) data["mechs"] += list(mech_data) @@ -46,8 +46,7 @@ return data /obj/machinery/computer/mecha/ui_act(action, params) - . = ..() - if(.) + if(..()) return switch(action) @@ -56,20 +55,20 @@ if(!istype(MT)) return var/message = stripped_input(usr, "Input message", "Transmit message") - var/obj/mecha/M = MT.chassis + var/obj/vehicle/sealed/mecha/M = MT.chassis if(trim(message) && M) - to_chat(M.occupant, message) + to_chat(M.occupants, message) to_chat(usr, "Message sent.") . = TRUE if("shock") var/obj/item/mecha_parts/mecha_tracking/MT = locate(params["tracker_ref"]) if(!istype(MT)) return - var/obj/mecha/M = MT.chassis + var/obj/vehicle/sealed/mecha/M = MT.chassis if(M) MT.shock() - log_game("[key_name(usr)] has activated remote EMP on exosuit [M], located at [loc_name(M)], which [M.occupant ? "has the occupants [M.occupant]." : "without a pilot."] ") - message_admins("[key_name_admin(usr)][ADMIN_FLW(usr)] has activated remote EMP on exosuit [M][ADMIN_JMP(M)], which is currently [M.occupant ? "occupied by [M.occupant][ADMIN_FLW(M)]." : "without a pilot."] ") + log_game("[key_name(usr)] has activated remote EMP on exosuit [M], located at [loc_name(M)], which [M.occupants ? "has the occupants [M.occupants]." : "without a pilot."] ") + message_admins("[key_name_admin(usr)][ADMIN_FLW(usr)] has activated remote EMP on exosuit [M][ADMIN_JMP(M)], which is currently [M.occupants ? "occupied by [M.occupants][ADMIN_FLW(M)]." : "without a pilot."] ") . = TRUE /obj/item/mecha_parts/mecha_tracking @@ -83,11 +82,11 @@ /// Cooldown variable for EMP pulsing var/recharging = FALSE /// The Mecha that this tracking beacon is attached to - var/obj/mecha/chassis + var/obj/vehicle/sealed/mecha/chassis /** - * Returns a html formatted string describing attached mech status - */ + * Returns a html formatted string describing attached mech status + */ /obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info() if(!chassis) return FALSE @@ -97,12 +96,12 @@ Integrity: [round((chassis.obj_integrity/chassis.max_integrity * 100), 0.01)]%
    Cell Charge: [isnull(cell_charge) ? "Not Found":"[chassis.cell.percent()]%"]
    Airtank: [chassis.internal_tank ? "[round(chassis.return_pressure(), 0.01)]" : "Not Equipped"] kPa
    - Pilot: [chassis.occupant || "None"]
    + Pilot: [chassis.return_drivers() || "None"]
    Location: [get_area_name(chassis, TRUE) || "Unknown"]
    Active Equipment: [chassis.selected || "None"]"} - if(istype(chassis, /obj/mecha/working/ripley)) - var/obj/mecha/working/ripley/RM = chassis - answer += "
    Used Cargo Space: [round((LAZYLEN(RM.cargo) / RM.cargo_capacity * 100), 0.01)]%" + if(istype(chassis, /obj/vehicle/sealed/mecha/working/ripley)) + var/obj/vehicle/sealed/mecha/working/ripley/RM = chassis + answer += "
    Used Cargo Space: [round((RM.cargo.len / RM.cargo_capacity * 100), 0.01)]%" return answer @@ -118,16 +117,21 @@ chassis = null return ..() -/obj/item/mecha_parts/mecha_tracking/try_attach_part(mob/user, obj/mecha/M) - if(!..()) +/obj/item/mecha_parts/mecha_tracking/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M) + for(var/obj/item/I in M.contents) + if(istype(I, src)) + to_chat(user, "[M] already has a tracking beacon!") + return + . = ..() + if(!.) return M.trackers += src M.diag_hud_set_mechtracking() chassis = M /** - * Attempts to EMP mech that the tracker is attached to, if there is one and tracker is not on cooldown - */ + * Attempts to EMP mech that the tracker is attached to, if there is one and tracker is not on cooldown + */ /obj/item/mecha_parts/mecha_tracking/proc/shock() if(recharging) return @@ -137,8 +141,8 @@ recharging = TRUE /** - * Resets recharge variable, allowing tracker to be EMP pulsed again - */ + * Resets recharge variable, allowing tracker to be EMP pulsed again + */ /obj/item/mecha_parts/mecha_tracking/proc/recharge() recharging = FALSE diff --git a/code/modules/vehicles/mecha/mecha_defense.dm b/code/modules/vehicles/mecha/mecha_defense.dm new file mode 100644 index 0000000000..78b4c7b441 --- /dev/null +++ b/code/modules/vehicles/mecha/mecha_defense.dm @@ -0,0 +1,390 @@ +/obj/vehicle/sealed/mecha/proc/get_armour_facing(relative_dir) + switch(relative_dir) + if(180) // BACKSTAB! + return facing_modifiers[MECHA_BACK_ARMOUR] + if(0, 45) // direct or 45 degrees off + return facing_modifiers[MECHA_FRONT_ARMOUR] + return facing_modifiers[MECHA_SIDE_ARMOUR] //if its not a front hit or back hit then assume its from the side + +/obj/vehicle/sealed/mecha/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) + . = ..() + if(. && obj_integrity > 0) + spark_system.start() + switch(damage_flag) + if(FIRE) + check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL)) + if(MELEE) + check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + else + check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT)) + if(. >= 5 || prob(33)) + to_chat(occupants, "[icon2html(src, occupants)]Taking damage!") + log_message("Took [damage_amount] points of damage. Damage type: [damage_type]", LOG_MECHA) + +/obj/vehicle/sealed/mecha/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) + . = ..() + if(!damage_amount) + return 0 + var/booster_deflection_modifier = 1 + var/booster_damage_modifier = 1 + if(damage_flag == BULLET || damage_flag == LASER || damage_flag == ENERGY) + for(var/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/B in equipment) + if(B.projectile_react()) + booster_deflection_modifier = B.deflect_coeff + booster_damage_modifier = B.damage_coeff + break + else if(damage_flag == MELEE) + for(var/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/B in equipment) + if(B.attack_react()) + booster_deflection_modifier *= B.deflect_coeff + booster_damage_modifier *= B.damage_coeff + break + + if(attack_dir) + var/facing_modifier = get_armour_facing(abs(dir2angle(dir) - dir2angle(attack_dir))) + booster_damage_modifier /= facing_modifier + booster_deflection_modifier *= facing_modifier + if(prob(deflect_chance * booster_deflection_modifier)) + visible_message("[src]'s armour deflects the attack!") + log_message("Armor saved.", LOG_MECHA) + return 0 + if(.) + . *= booster_damage_modifier + +/obj/vehicle/sealed/mecha/attack_hand(mob/living/user) + . = ..() + if(.) + return + user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) + playsound(loc, 'sound/weapons/tap.ogg', 40, TRUE, -1) + user.visible_message("[user] hits [name]. Nothing happens.", null, null, COMBAT_MESSAGE_RANGE) + log_message("Attack by hand/paw. Attacker - [user].", LOG_MECHA, color="red") + +/obj/vehicle/sealed/mecha/attack_paw(mob/user as mob) + return attack_hand(user) + +/obj/vehicle/sealed/mecha/attack_alien(mob/living/user) + log_message("Attack by alien. Attacker - [user].", LOG_MECHA, color="red") + playsound(src.loc, 'sound/weapons/slash.ogg', 100, TRUE) + attack_generic(user, 15, BRUTE, MELEE, 0) + +/obj/vehicle/sealed/mecha/attack_animal(mob/living/simple_animal/user) + log_message("Attack by simple animal. Attacker - [user].", LOG_MECHA, color="red") + if(!user.melee_damage_upper && !user.obj_damage) + user.emote("custom", message = "[user.friendly_verb_continuous] [src].") + return 0 + else + var/play_soundeffect = 1 + if(user.environment_smash) + play_soundeffect = 0 + playsound(src, 'sound/effects/bang.ogg', 50, TRUE) + var/animal_damage = rand(user.melee_damage_lower,user.melee_damage_upper) + if(user.obj_damage) + animal_damage = user.obj_damage + animal_damage = min(animal_damage, 20*user.environment_smash) + log_combat(user, src, "attacked") + attack_generic(user, animal_damage, user.melee_damage_type, MELEE, play_soundeffect) + return 1 + + +/obj/vehicle/sealed/mecha/hulk_damage() + return 15 + +/obj/vehicle/sealed/mecha/attack_hulk(mob/living/carbon/human/user) + . = ..() + if(.) + log_message("Attack by hulk. Attacker - [user].", LOG_MECHA, color="red") + log_combat(user, src, "punched", "hulk powers") + +/obj/vehicle/sealed/mecha/blob_act(obj/structure/blob/B) + log_message("Attack by blob. Attacker - [B].", LOG_MECHA, color="red") + take_damage(30, BRUTE, MELEE, 0, get_dir(src, B)) + +/obj/vehicle/sealed/mecha/attack_tk() + return + +/obj/vehicle/sealed/mecha/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) //wrapper + log_message("Hit by [AM].", LOG_MECHA, color="red") + . = ..() + +/obj/vehicle/sealed/mecha/bullet_act(obj/item/projectile/Proj) //wrapper + if(!enclosed && LAZYLEN(occupants) && !(mecha_flags & SILICON_PILOT) && !Proj.force_hit && (Proj.def_zone == BODY_ZONE_HEAD || Proj.def_zone == BODY_ZONE_CHEST)) //allows bullets to hit the pilot of open-canopy mechs + for(var/m in occupants) + var/mob/living/hitmob = m + hitmob.bullet_act(Proj) //If the sides are open, the occupant can be hit + return BULLET_ACT_HIT + log_message("Hit by projectile. Type: [Proj.name]([Proj.flag]).", LOG_MECHA, color="red") + . = ..() + +/obj/vehicle/sealed/mecha/ex_act(severity, target) + log_message("Affected by explosion of severity: [severity].", LOG_MECHA, color="red") + if(prob(deflect_chance)) + severity++ + log_message("Armor saved, changing severity to [severity]", LOG_MECHA) + . = ..() + + +/obj/vehicle/sealed/mecha/contents_explosion(severity, target, origin) + severity++ + for(var/X in equipment) + var/obj/item/mecha_parts/mecha_equipment/ME = X + ME.ex_act(severity, target, origin) + for(var/Y in trackers) + var/obj/item/mecha_parts/mecha_tracking/MT = Y + MT.ex_act(severity, target, origin) + for(var/Z in occupants) + var/mob/living/occupant = Z + occupant.ex_act(severity, target, origin) + +/obj/vehicle/sealed/mecha/handle_atom_del(atom/A) + if(A in occupants) + LAZYREMOVE(occupants, A) + icon_state = initial(icon_state)+"-open" + setDir(dir_in) + +/obj/vehicle/sealed/mecha/emp_act(severity) + . = ..() + if (. & EMP_PROTECT_SELF) + return + if(get_charge()) + use_power((cell.charge/3)*(severity*0.005)) + take_damage(severity/3, BURN, ENERGY, 1) + log_message("EMP detected", LOG_MECHA, color="red") + + if(istype(src, /obj/vehicle/sealed/mecha/combat)) + mouse_pointer = 'icons/effects/mouse_pointers/mecha_mouse-disable.dmi' + for(var/occus in occupants) + var/mob/living/occupant = occus + occupant.update_mouse_pointer() + if(!equipment_disabled && occupants) //prevent spamming this message with back-to-back EMPs + to_chat(occupants, "Error -- Connection to equipment control unit has been lost.
    ") + addtimer(CALLBACK(src, /obj/vehicle/sealed/mecha/proc/restore_equipment), 3 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) + equipment_disabled = 1 + +/obj/vehicle/sealed/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + if(exposed_temperature>max_temperature) + log_message("Exposed to dangerous temperature.", LOG_MECHA, color="red") + take_damage(5, BURN, 0, 1) + +/obj/vehicle/sealed/mecha/attackby(obj/item/W, mob/user, params) + + if(istype(W, /obj/item/mmi)) + if(mmi_move_inside(W,user)) + to_chat(user, "[src]-[W] interface initialized successfully.") + else + to_chat(user, "[src]-[W] interface initialization failed.") + return + + if(istype(W, /obj/item/mecha_ammo)) + ammo_resupply(W, user) + return + + if(W.GetID()) + if((mecha_flags & ADDING_ACCESS_POSSIBLE) || (mecha_flags & ADDING_MAINT_ACCESS_POSSIBLE)) + if(internals_access_allowed(user)) + var/obj/item/card/id/id_card + if(istype(W, /obj/item/card/id)) + id_card = W + else + var/obj/item/pda/pda = W + id_card = pda.id + output_maintenance_dialog(id_card, user) + return + to_chat(user, "Invalid ID: Access denied.") + return + to_chat(user, "Maintenance protocols disabled by operator.") + return + + if(istype(W, /obj/item/stock_parts/cell)) + if(construction_state == MECHA_OPEN_HATCH) + if(!cell) + if(!user.transferItemToLoc(W, src, silent = FALSE)) + return + var/obj/item/stock_parts/cell/C = W + to_chat(user, "You install the power cell.") + playsound(src, 'sound/items/screwdriver2.ogg', 50, FALSE) + cell = C + log_message("Power cell installed", LOG_MECHA) + else + to_chat(user, "There's already a power cell installed!") + return + + if(istype(W, /obj/item/stock_parts/scanning_module)) + if(construction_state == MECHA_OPEN_HATCH) + if(!scanmod) + if(!user.transferItemToLoc(W, src)) + return + to_chat(user, "You install the scanning module.") + playsound(src, 'sound/items/screwdriver2.ogg', 50, FALSE) + scanmod = W + log_message("[W] installed", LOG_MECHA) + update_part_values() + else + to_chat(user, "There's already a scanning module installed!") + return + + if(istype(W, /obj/item/stock_parts/capacitor)) + if(construction_state == MECHA_OPEN_HATCH) + if(!capacitor) + if(!user.transferItemToLoc(W, src)) + return + to_chat(user, "You install the capacitor.") + playsound(src, 'sound/items/screwdriver2.ogg', 50, FALSE) + capacitor = W + log_message("[W] installed", LOG_MECHA) + update_part_values() + else + to_chat(user, "There's already a capacitor installed!") + return + + if(istype(W, /obj/item/stack/cable_coil)) + if(construction_state == MECHA_OPEN_HATCH && (internal_damage & MECHA_INT_SHORT_CIRCUIT)) + var/obj/item/stack/cable_coil/CC = W + if(CC.use(2)) + clearInternalDamage(MECHA_INT_SHORT_CIRCUIT) + to_chat(user, "You replace the fused wires.") + else + to_chat(user, "You need two lengths of cable to fix this mech!") + return + + if(istype(W, /obj/item/mecha_parts)) + var/obj/item/mecha_parts/P = W + P.try_attach_part(user, src) + return + if(istype(W, /obj/item/analyzer)) + if(construction_state) + var/datum/gas_mixture/GasNux = internal_tank.return_air() + atmosanalyzer_scan(GasNux,user,src,TRUE) + else + atmosanalyzer_scan(cabin_air,user,src,TRUE) + return + log_message("Attacked by [W]. Attacker - [user]", LOG_MECHA) + return ..() + +/obj/vehicle/sealed/mecha/wrench_act(mob/living/user, obj/item/I) + ..() + . = TRUE + if(construction_state == MECHA_SECURE_BOLTS) + construction_state = MECHA_LOOSE_BOLTS + to_chat(user, "You undo the securing bolts.") + return + if(construction_state == MECHA_LOOSE_BOLTS) + construction_state = MECHA_SECURE_BOLTS + to_chat(user, "You tighten the securing bolts.") + +/obj/vehicle/sealed/mecha/crowbar_act(mob/living/user, obj/item/I) + ..() + . = TRUE + if(construction_state == MECHA_LOOSE_BOLTS) + construction_state = MECHA_OPEN_HATCH + to_chat(user, "You open the hatch to the power unit.") + return + if(construction_state == MECHA_OPEN_HATCH) + construction_state = MECHA_LOOSE_BOLTS + to_chat(user, "You close the hatch to the power unit.") + +/obj/vehicle/sealed/mecha/screwdriver_act(mob/living/user, obj/item/I) + ..() + . = TRUE + if(internal_damage & MECHA_INT_TEMP_CONTROL) + clearInternalDamage(MECHA_INT_TEMP_CONTROL) + to_chat(user, "You repair the damaged temperature controller.") + return + +/obj/vehicle/sealed/mecha/welder_act(mob/living/user, obj/item/W) + . = ..() + if(user.a_intent == INTENT_HARM) + return + . = TRUE + if(internal_damage & MECHA_INT_TANK_BREACH) + if(!W.use_tool(src, user, 0, volume=50, amount=1)) + return + clearInternalDamage(MECHA_INT_TANK_BREACH) + to_chat(user, "You repair the damaged gas tank.") + return + if(obj_integrity < max_integrity) + if(!W.use_tool(src, user, 0, volume=50, amount=1)) + return + user.visible_message("[user] repairs some damage to [name].", "You repair some damage to [src].") + obj_integrity += min(10, max_integrity-obj_integrity) + if(obj_integrity == max_integrity) + to_chat(user, "It looks to be fully repaired now.") + return + to_chat(user, "The [name] is at full integrity!") + +/obj/vehicle/sealed/mecha/proc/mech_toxin_damage(mob/living/target) + playsound(src, 'sound/effects/spray2.ogg', 50, TRUE) + if(target.reagents) + if(target.reagents.get_reagent_amount(/datum/reagent/cryptobiolin) + force < force*2) + target.reagents.add_reagent(/datum/reagent/cryptobiolin, force/2) + if(target.reagents.get_reagent_amount(/datum/reagent/toxin) + force < force*2) + target.reagents.add_reagent(/datum/reagent/toxin, force/2.5) + + +/obj/vehicle/sealed/mecha/mech_melee_attack(obj/vehicle/sealed/mecha/M, mob/user) + if(!has_charge(melee_energy_drain)) + return NONE + use_power(melee_energy_drain) + if(M.damtype == BRUTE || M.damtype == BURN) + log_combat(user, src, "attacked", M, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") + . = ..() + +/obj/vehicle/sealed/mecha/proc/full_repair(charge_cell) + obj_integrity = max_integrity + if(cell && charge_cell) + cell.charge = cell.maxcharge + if(internal_damage & MECHA_INT_FIRE) + clearInternalDamage(MECHA_INT_FIRE) + if(internal_damage & MECHA_INT_TEMP_CONTROL) + clearInternalDamage(MECHA_INT_TEMP_CONTROL) + if(internal_damage & MECHA_INT_SHORT_CIRCUIT) + clearInternalDamage(MECHA_INT_SHORT_CIRCUIT) + if(internal_damage & MECHA_INT_TANK_BREACH) + clearInternalDamage(MECHA_INT_TANK_BREACH) + if(internal_damage & MECHA_INT_CONTROL_LOST) + clearInternalDamage(MECHA_INT_CONTROL_LOST) + +/obj/vehicle/sealed/mecha/narsie_act() + emp_act(80) + +/obj/vehicle/sealed/mecha/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) + if(!no_effect) + if(selected) + used_item = selected + else if(!visual_effect_icon) + visual_effect_icon = ATTACK_EFFECT_SMASH + if(damtype == BURN) + visual_effect_icon = ATTACK_EFFECT_MECHFIRE + else if(damtype == TOX) + visual_effect_icon = ATTACK_EFFECT_MECHTOXIN + ..() + +/obj/vehicle/sealed/mecha/obj_destruction() + if(wreckage) + var/mob/living/silicon/ai/AI + for(var/crew in occupants) + if(isAI(crew)) + if(AI) + var/mob/living/silicon/ai/unlucky_ais = crew + unlucky_ais.gib() + continue + AI = crew + var/obj/structure/mecha_wreckage/WR = new wreckage(loc, AI) + for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) + if(E.salvageable && prob(30)) + WR.crowbar_salvage += E + E.detach(WR) //detaches from src into WR + E.equip_ready = 1 + else + E.detach(loc) + qdel(E) + if(cell) + WR.crowbar_salvage += cell + cell.forceMove(WR) + cell.charge = rand(0, cell.charge) + cell = null + if(internal_tank) + WR.crowbar_salvage += internal_tank + internal_tank.forceMove(WR) + cell = null + . = ..() diff --git a/code/game/mecha/mecha_parts.dm b/code/modules/vehicles/mecha/mecha_parts.dm similarity index 94% rename from code/game/mecha/mecha_parts.dm rename to code/modules/vehicles/mecha/mecha_parts.dm index 8a9e4e641f..a50c1414ae 100644 --- a/code/game/mecha/mecha_parts.dm +++ b/code/modules/vehicles/mecha/mecha_parts.dm @@ -9,20 +9,23 @@ w_class = WEIGHT_CLASS_GIGANTIC flags_1 = CONDUCT_1 -/obj/item/mecha_parts/proc/try_attach_part(mob/user, obj/mecha/M) //For attaching parts to a finished mech +/obj/item/mecha_parts/proc/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M) //For attaching parts to a finished mech if(!user.transferItemToLoc(src, M)) to_chat(user, "\The [src] is stuck to your hand, you cannot put it in \the [M]!") return FALSE user.visible_message("[user] attaches [src] to [M].", "You attach [src] to [M].") return TRUE - + +/obj/item/mecha_parts/part/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M) + return + /obj/item/mecha_parts/chassis name = "Mecha Chassis" icon_state = "backbone" interaction_flags_item = NONE //Don't pick us up!! var/construct_type -/obj/item/mecha_parts/chassis/Initialize() +/obj/item/mecha_parts/chassis/Initialize(mapload) . = ..() if(construct_type) AddComponent(construct_type) @@ -58,6 +61,12 @@ desc = "A Ripley APLU right leg. Contains somewhat complex servodrives and balance maintaining systems." icon_state = "ripley_r_leg" + +//Firefighter +/obj/item/mecha_parts/chassis/firefighter + name = "\improper Firefighter chassis" + construct_type = /datum/component/construction/unordered/mecha_chassis/firefighter + ///////// Odysseus /obj/item/mecha_parts/chassis/odysseus @@ -220,12 +229,6 @@ desc = "A set of armor plates for the Durand. Built heavy to resist an incredible amount of brute force." icon_state = "durand_armor" -////////// Firefighter - -/obj/item/mecha_parts/chassis/firefighter - name = "\improper Firefighter chassis" - construct_type = /datum/component/construction/unordered/mecha_chassis/firefighter - ////////// HONK @@ -270,6 +273,11 @@ name = "\improper Phazon chassis" construct_type = /datum/component/construction/unordered/mecha_chassis/phazon +/obj/item/mecha_parts/chassis/phazon/attackby(obj/item/I, mob/user, params) + . = ..() + if(istype(I, /obj/item/assembly/signaler/anomaly) && !istype(I, /obj/item/assembly/signaler/anomaly/bluespace)) + to_chat(user, "The anomaly core socket only accepts bluespace anomaly cores!") + /obj/item/mecha_parts/part/phazon_torso name="\improper Phazon torso" desc="A Phazon torso part. The socket for the bluespace core that powers the exosuit's unique phase drives is located in the middle." @@ -312,7 +320,6 @@ name = "exosuit circuit board" icon = 'icons/obj/module.dmi' icon_state = "std_mod" - item_state = "electronic" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' flags_1 = CONDUCT_1 @@ -385,3 +392,11 @@ /obj/item/circuitboard/mecha/phazon/main name = "Phazon Central Control module (Exosuit Board)" + +/obj/item/circuitboard/mecha/clarke/peripherals + name = "Clarke Peripherals Control module (Exosuit Board)" + icon_state = "mcontroller" + +/obj/item/circuitboard/mecha/clarke/main + name = "Clarke Central Control module (Exosuit Board)" + icon_state = "mainboard" diff --git a/code/modules/vehicles/mecha/mecha_topic.dm b/code/modules/vehicles/mecha/mecha_topic.dm new file mode 100644 index 0000000000..eb7dcd01db --- /dev/null +++ b/code/modules/vehicles/mecha/mecha_topic.dm @@ -0,0 +1,421 @@ + +//////////////////////////////////// +///// Rendering stats window /////// +//////////////////////////////////// + +/obj/vehicle/sealed/mecha/proc/get_stats_html(mob/user) + . = {" + + + [name] data + + + + +
    + [get_stats_part(user)] +
    +
    + [get_equipment_list()] +
    +
    +
    + [get_commands()] +
    +
    + [get_equipment_menu()] +
    + + "} + +///Returns the status of the mech. +/obj/vehicle/sealed/mecha/proc/get_stats_part(mob/user) + var/integrity = obj_integrity/max_integrity*100 + var/cell_charge = get_charge() + var/datum/gas_mixture/int_tank_air = 0 + var/tank_pressure = 0 + var/tank_temperature = 0 + var/cabin_pressure = 0 + if (internal_tank) + int_tank_air = internal_tank.return_air() + tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None" + tank_temperature = internal_tank ? int_tank_air.return_temperature() : "Unknown" + cabin_pressure = round(return_pressure(),0.01) + . = {"[report_internal_damage()] + [integrity<30?"DAMAGE LEVEL CRITICAL
    ":null] + Integrity: [integrity]%
    + Power cell charge: [isnull(cell_charge)?"No power cell installed":"[cell.percent()]%"]
    + Air source: [internal_tank?"[use_internal_tank?"Internal Airtank":"Environment"]":"Environment"]
    + Airtank pressure: [internal_tank?"[tank_pressure]kPa":"N/A"]
    + Airtank temperature: [internal_tank?"[tank_temperature]°K|[tank_temperature - T0C]°C":"N/A"]
    + Cabin pressure: [internal_tank?"[cabin_pressure>WARNING_HIGH_PRESSURE ? "[cabin_pressure]": cabin_pressure]kPa":"N/A"]
    + Cabin temperature: [internal_tank?"[return_temperature()]°K|[return_temperature() - T0C]°C":"N/A"]
    + [dna_lock?"DNA-locked:
    [dna_lock] \[Reset\]
    ":""]
    "} + . += "[get_actions(user)]
    " + +///Returns HTML for mech actions. Ideally, this proc would be empty for the base mecha. Segmented for easy refactoring. +/obj/vehicle/sealed/mecha/proc/get_actions(mob/user) + . = "" + . += "[LAZYACCESSASSOC(occupant_actions, user, /datum/action/vehicle/sealed/mecha/mech_defense_mode) ? "Defense Mode: [defense_mode ? "Enabled" : "Disabled"]
    " : ""]" + . += "[LAZYACCESSASSOC(occupant_actions, user, /datum/action/vehicle/sealed/mecha/mech_overload_mode) ? "Leg Actuators Overload: [leg_overload_mode ? "Enabled" : "Disabled"]
    " : ""]" + . += "[LAZYACCESSASSOC(occupant_actions, user, /datum/action/vehicle/sealed/mecha/mech_smoke) ? "Smoke Charges remaining: [smoke_charges]
    " : ""]" + . += "[LAZYACCESSASSOC(occupant_actions, user, /datum/action/vehicle/sealed/mecha/mech_zoom) ? "Zoom: [zoom_mode ? "Enabled" : "Disabled"]
    " : ""]" + . += "[LAZYACCESSASSOC(occupant_actions, user, /datum/action/vehicle/sealed/mecha/mech_switch_damtype) ? "Damtype: [damtype]
    " : ""]" + . += "[LAZYACCESSASSOC(occupant_actions, user, /datum/action/vehicle/sealed/mecha/mech_toggle_phasing) ? "Phase Modulator: [phasing ? "Enabled" : "Disabled"]
    " : ""]" + +///HTML for internal damage. +/obj/vehicle/sealed/mecha/proc/report_internal_damage() + . = "" + var/list/dam_reports = list( + "[MECHA_INT_FIRE]" = "INTERNAL FIRE", + "[MECHA_INT_TEMP_CONTROL]" = "LIFE SUPPORT SYSTEM MALFUNCTION", + "[MECHA_INT_TANK_BREACH]" = "GAS TANK BREACH", + "[MECHA_INT_CONTROL_LOST]" = "COORDINATION SYSTEM CALIBRATION FAILURE - Recalibrate", + "[MECHA_INT_SHORT_CIRCUIT]" = "SHORT CIRCUIT" + ) + for(var/tflag in dam_reports) + var/intdamflag = text2num(tflag) + if(internal_damage & intdamflag) + . += dam_reports[tflag] + . += "
    " + if(return_pressure() > WARNING_HIGH_PRESSURE) + . += "DANGEROUSLY HIGH CABIN PRESSURE
    " + +///HTML for list of equipment. +/obj/vehicle/sealed/mecha/proc/get_equipment_list() //outputs mecha equipment list in html + if(!LAZYLEN(equipment)) + return + . = "Equipment:
    " + for(var/obj/item/mecha_parts/mecha_equipment/MT in equipment) + . += "
    [MT.get_equip_info()]
    " + . += "
    " + +///HTML for commands. +/obj/vehicle/sealed/mecha/proc/get_commands() + . = {" +
    +
    Electronics
    + +
    + "} + + +/obj/vehicle/sealed/mecha/proc/get_equipment_menu() //outputs mecha html equipment menu + . = {" +
    +
    Equipment
    + +
    "} + +/obj/vehicle/sealed/mecha/proc/output_access_dialog(obj/item/card/id/id_card, mob/user) + if(!id_card || !user) + return + . = {" + + + + + +

    Following keycodes are present in this system:

    "} + for(var/a in operation_req_access) + . += "[get_access_desc(a)] - Delete
    " + . += "

    Following keycodes were detected on portable device:

    " + for(var/a in id_card.access) + if(a in operation_req_access) + continue + var/a_name = get_access_desc(a) + if(!a_name) + continue //there's some strange access without a name + . += "[a_name] - Add
    " + . +={"
    Lock ID panel
    + (Warning! The ID upload panel can be unlocked only through Exosuit Interface.) + + "} + user << browse(., "window=exosuit_add_access") + onclose(user, "exosuit_add_access") + + +/obj/vehicle/sealed/mecha/proc/output_maintenance_dialog(obj/item/card/id/id_card,mob/user) + if(!id_card || !user) + return + . = {" + + + + + + [(mecha_flags & ADDING_ACCESS_POSSIBLE)?"Edit operation keycodes":null] + [(mecha_flags & ADDING_MAINT_ACCESS_POSSIBLE)?"[(construction_state > MECHA_LOCKED) ? "Terminate" : "Initiate"] maintenance protocol":null] + [(construction_state == MECHA_OPEN_HATCH) ?"--------------------
    ":null] + [(construction_state == MECHA_OPEN_HATCH) ?"[cell?"Drop power cell":"No cell installed
    "]":null] + [(construction_state == MECHA_OPEN_HATCH) ?"[scanmod?"Drop scanning module":"No scanning module installed
    "]":null] + [(construction_state == MECHA_OPEN_HATCH) ?"[capacitor?"Drop capacitor":"No capacitor installed
    "]":null] + [(construction_state == MECHA_OPEN_HATCH) ?"--------------------
    ":null] + [(construction_state > MECHA_LOCKED) ?"Set Cabin Air Pressure":null] + + "} + user << browse(., "window=exosuit_maint_console") + onclose(user, "exosuit_maint_console") + + + + +///////////////// +///// Topic ///// +///////////////// + +/obj/vehicle/sealed/mecha/Topic(href, href_list) + ..() + + if(!usr) + return + + if(href_list["close"]) + return + + if(usr.incapacitated()) + return + + if(in_range(src, usr)) + //Start of ID requirements. + if(href_list["id_card"]) + var/obj/item/card/id/id_card + id_card = locate(href_list["id_card"]) + if(!istype(id_card)) + return + + if(href_list["req_access"]) + if(!(mecha_flags & ADDING_ACCESS_POSSIBLE)) + return + output_access_dialog(id_card,usr) + return + + if(href_list["maint_access"]) + if(!(mecha_flags & ADDING_MAINT_ACCESS_POSSIBLE)) + return + if(construction_state == MECHA_LOCKED) + construction_state = MECHA_SECURE_BOLTS + to_chat(usr, "The securing bolts are now exposed.") + else if(construction_state == MECHA_SECURE_BOLTS) + construction_state = MECHA_LOCKED + to_chat(usr, "The securing bolts are now hidden.") + output_maintenance_dialog(id_card,usr) + return + if(href_list["drop_cell"]) + if(construction_state == MECHA_OPEN_HATCH) + cell.forceMove(get_turf(src)) + cell = null + output_maintenance_dialog(id_card,usr) + return + if(href_list["drop_scanmod"]) + if(construction_state == MECHA_OPEN_HATCH) + scanmod.forceMove(get_turf(src)) + scanmod = null + output_maintenance_dialog(id_card,usr) + return + if(href_list["drop_cap"]) + if(construction_state == MECHA_OPEN_HATCH) + capacitor.forceMove(get_turf(src)) + capacitor = null + output_maintenance_dialog(id_card,usr) + return + + if(href_list["add_req_access"]) + if(!(mecha_flags & ADDING_ACCESS_POSSIBLE)) + return + operation_req_access += text2num(href_list["add_req_access"]) + output_access_dialog(id_card,usr) + return + + if(href_list["del_req_access"]) + if(!(mecha_flags & ADDING_ACCESS_POSSIBLE)) + return + operation_req_access -= text2num(href_list["del_req_access"]) + output_access_dialog(id_card, usr) + return + return //Here end everything requiring an ID. + + //Here ID access stuff goes to die. + if(href_list["finish_req_access"]) + mecha_flags &= ~ADDING_ACCESS_POSSIBLE + usr << browse(null,"window=exosuit_add_access") + return + + //Set pressure. + if(href_list["set_internal_tank_valve"] && construction_state) + var/new_pressure = input(usr,"Input new output pressure","Pressure setting",internal_tank_valve) as num|null + if(isnull(new_pressure) || usr.incapacitated() || !construction_state) + return + internal_tank_valve = new_pressure + to_chat(usr, "The internal pressure valve has been set to [internal_tank_valve]kPa.") + return + + //Start of all internal topic stuff. + if(!locate(usr) in occupants) + return + + if(href_list["update_content"]) + send_byjax(usr,"exosuit.browser","content", get_stats_part()) + return + + //Selects the mech equipment/weapon. + if(href_list["select_equip"]) + var/obj/item/mecha_parts/mecha_equipment/equip = locate(href_list["select_equip"]) in src + if(!equip || !equip.selectable) + return + selected = equip + to_chat(occupants, "[icon2html(src, occupants)]You switch to [equip].") + visible_message("[src] raises [equip].") + send_byjax(usr, "exosuit.browser", "eq_list", get_equipment_list()) + return + + //Toggles radio broadcasting + if(href_list["rmictoggle"]) + radio.broadcasting = !radio.broadcasting + send_byjax(usr,"exosuit.browser","rmicstate",(radio.broadcasting?"Engaged":"Disengaged")) + return + + //Toggles radio listening + if(href_list["rspktoggle"]) + radio.listening = !radio.listening + send_byjax(usr,"exosuit.browser","rspkstate",(radio.listening?"Engaged":"Disengaged")) + return + + //Changes radio freqency. + if(href_list["rfreq"]) + var/new_frequency = radio.frequency + text2num(href_list["rfreq"]) + radio.set_frequency(sanitize_frequency(new_frequency, radio.freerange)) + send_byjax(usr,"exosuit.browser","rfreq","[format_frequency(radio.frequency)]") + return + + //Changes the exosuit name. + if(href_list["change_name"]) + var/userinput = stripped_input(usr, "Choose a new exosuit name.", "Rename exosuit", "", MAX_NAME_LEN) + if(!userinput || !locate(usr) in occupants || usr.incapacitated()) + return + name = userinput + return + + //Toggles ID upload. + if (href_list["toggle_id_upload"]) + mecha_flags ^= ADDING_ACCESS_POSSIBLE + send_byjax(usr,"exosuit.browser","t_id_upload","[(mecha_flags & ADDING_ACCESS_POSSIBLE)?"L":"Unl"]ock ID upload panel") + return + + //Toggles main access. + if(href_list["toggle_maint_access"]) + if(construction_state) + to_chat(occupants, "[icon2html(src, occupants)]Maintenance protocols in effect") + return + mecha_flags ^= ADDING_MAINT_ACCESS_POSSIBLE + send_byjax(usr,"exosuit.browser","t_maint_access","[(mecha_flags & ADDING_MAINT_ACCESS_POSSIBLE)?"Forbid":"Permit"] maintenance protocols") + return + + //Toggles connection port. + if (href_list["toggle_port_connection"]) + if(internal_tank.connected_port) + if(internal_tank.disconnect()) + to_chat(occupants, "[icon2html(src, occupants)]Disconnected from the air system port.") + log_message("Disconnected from gas port.", LOG_MECHA) + else + to_chat(occupants, "[icon2html(src, occupants)]Unable to disconnect from the air system port!") + return + else + var/obj/machinery/atmospherics/components/unary/portables_connector/possible_port = locate() in loc + if(internal_tank.connect(possible_port)) + to_chat(occupants, "[icon2html(src, occupants)]Connected to the air system port.") + log_message("Connected to gas port.", LOG_MECHA) + else + to_chat(occupants, "[icon2html(src, occupants)]Unable to connect with air system port!") + return + send_byjax(occupants,"exosuit.browser","t_port_connection","[internal_tank.connected_port?"Disconnect from":"Connect to"] gas port") + return + + //Turns on the DNA lock + if(href_list["dna_lock"]) + var/mob/living/carbon/user = usr + if(!istype(user) || !user.dna) + to_chat(user, "[icon2html(src, occupants)]You can't create a DNA lock with no DNA!.") + return + dna_lock = user.dna.unique_enzymes + to_chat(user, "[icon2html(src, occupants)]You feel a prick as the needle takes your DNA sample.") + return + + //Resets the DNA lock + if(href_list["reset_dna"]) + dna_lock = null + return + + //Repairs internal damage + if(href_list["repair_int_control_lost"]) + to_chat(occupants, "[icon2html(src, occupants)]Recalibrating coordination system...") + log_message("Recalibration of coordination system started.", LOG_MECHA) + addtimer(CALLBACK(src, .proc/stationary_repair, loc), 100, TIMER_UNIQUE) + +///Repairs internal damage if the mech hasn't moved. +/obj/vehicle/sealed/mecha/proc/stationary_repair(location) + if(location == loc) + clearInternalDamage(MECHA_INT_CONTROL_LOST) + to_chat(occupants, "[icon2html(src, occupants)]Recalibration successful.") + log_message("Recalibration of coordination system finished with 0 errors.", LOG_MECHA) + else + to_chat(occupants, "[icon2html(src, occupants)]Recalibration failed!") + log_message("Recalibration of coordination system failed with 1 error.", LOG_MECHA, color="red") diff --git a/code/modules/vehicles/mecha/mecha_wreckage.dm b/code/modules/vehicles/mecha/mecha_wreckage.dm new file mode 100644 index 0000000000..70c543fbde --- /dev/null +++ b/code/modules/vehicles/mecha/mecha_wreckage.dm @@ -0,0 +1,222 @@ +/////////////////////////////////// +//////// Mecha wreckage //////// +/////////////////////////////////// + + +/obj/structure/mecha_wreckage + name = "exosuit wreckage" + desc = "Remains of some unfortunate mecha. Completely irreparable, but perhaps something can be salvaged." + icon = 'icons/mecha/mecha.dmi' + density = TRUE + anchored = FALSE + opacity = FALSE + var/list/welder_salvage = list(/obj/item/stack/sheet/plasteel, /obj/item/stack/sheet/metal, /obj/item/stack/rods) + var/salvage_num = 5 + var/list/crowbar_salvage = list() + var/wires_removed = FALSE + var/mob/living/silicon/ai/AI //AIs to be salvaged + var/list/parts + +/obj/structure/mecha_wreckage/Initialize(mapload, mob/living/silicon/ai/AI_pilot) + . = ..() + if(parts) + for(var/i in 1 to 2) + if(!parts.len) + break + if(prob(60)) + continue + var/part = pick(parts) + welder_salvage += part + parts = null + if(!AI_pilot) //Type-checking for this is already done in mecha/Destroy() + return + AI = AI_pilot + AI.apply_damage(150, BURN) //Give the AI a bit of damage from the "shock" of being suddenly shut down + AI.death() //The damage is not enough to kill the AI, but to be 'corrupted files' in need of repair. + AI.forceMove(src) //Put the dead AI inside the wreckage for recovery + add_overlay(mutable_appearance('icons/obj/projectiles.dmi', "green_laser")) //Overlay for the recovery beacon + AI.controlled_equipment = null + AI.remote_control = null + +/obj/structure/mecha_wreckage/Destroy() + if(AI) + QDEL_NULL(AI) + QDEL_LIST(crowbar_salvage) + return ..() + +/obj/structure/mecha_wreckage/examine(mob/user) + . = ..() + if(!AI) + return + . += "The AI recovery beacon is active." + +/obj/structure/mecha_wreckage/welder_act(mob/living/user, obj/item/I) + ..() + . = TRUE + if(salvage_num <= 0 || !length(welder_salvage)) + to_chat(user, "You don't see anything that can be cut with [I]!") + return + if(!I.use_tool(src, user, 0, volume=50)) + return + if(prob(30)) + to_chat(user, "You fail to salvage anything valuable from [src]!") + return + var/type = pick(welder_salvage) + var/N = new type(get_turf(user)) + user.visible_message("[user] cuts [N] from [src].", "You cut [N] from [src].") + if(!istype(N, /obj/item/stack)) + welder_salvage -= type + salvage_num-- + +/obj/structure/mecha_wreckage/wirecutter_act(mob/living/user, obj/item/I) + ..() + . = TRUE + if(wires_removed) + to_chat(user, "You don't see anything that can be cut with [I]!") + return + var/N = new /obj/item/stack/cable_coil(get_turf(user), rand(1,3)) + user.visible_message("[user] cuts [N] from [src].", "You cut [N] from [src].") + wires_removed = TRUE + +/obj/structure/mecha_wreckage/crowbar_act(mob/living/user, obj/item/I) + ..() + . = TRUE + if(crowbar_salvage.len) + var/obj/S = pick(crowbar_salvage) + S.forceMove(user.drop_location()) + user.visible_message("[user] pries [S] from [src].", "You pry [S] from [src].") + crowbar_salvage -= S + return + to_chat(user, "You don't see anything that can be cut with [I]!") + +/obj/structure/mecha_wreckage/transfer_ai(interaction, mob/user, null, obj/item/aicard/card) + if(!..()) + return + + //Proc called on the wreck by the AI card. + if(interaction != AI_TRANS_TO_CARD) //AIs can only be transferred in one direction, from the wreck to the card. + return + if(!AI) //No AI in the wreck + to_chat(user, "No AI backups found.") + return + cut_overlays() //Remove the recovery beacon overlay + AI.forceMove(card) //Move the dead AI to the card. + card.AI = AI + if(AI.client) //AI player is still in the dead AI and is connected + to_chat(AI, "The remains of your file system have been recovered on a mobile storage device.") + else //Give the AI a heads-up that it is probably going to get fixed. + AI.notify_ghost_cloning("You have been recovered from the wreckage!", source = card) + to_chat(user, "Backup files recovered: [AI.name] ([rand(1000,9999)].exe) salvaged from [name] and stored within local memory.") + AI = null + +/obj/structure/mecha_wreckage/gygax + name = "\improper Gygax wreckage" + icon_state = "gygax-broken" + parts = list( + /obj/item/mecha_parts/part/gygax_torso, + /obj/item/mecha_parts/part/gygax_head, + /obj/item/mecha_parts/part/gygax_left_arm, + /obj/item/mecha_parts/part/gygax_right_arm, + /obj/item/mecha_parts/part/gygax_left_leg, + /obj/item/mecha_parts/part/gygax_right_leg + ) + +/obj/structure/mecha_wreckage/gygax/dark + name = "\improper Dark Gygax wreckage" + icon_state = "darkgygax-broken" + +/obj/structure/mecha_wreckage/marauder + name = "\improper Marauder wreckage" + icon_state = "marauder-broken" + +/obj/structure/mecha_wreckage/mauler + name = "\improper Mauler wreckage" + icon_state = "mauler-broken" + desc = "The syndicate won't be very happy about this..." + +/obj/structure/mecha_wreckage/seraph + name = "\improper Seraph wreckage" + icon_state = "seraph-broken" + +/obj/structure/mecha_wreckage/reticence + name = "\improper Reticence wreckage" + icon_state = "reticence-broken" + color = "#87878715" + desc = "..." + +/obj/structure/mecha_wreckage/ripley + name = "\improper Ripley wreckage" + icon_state = "ripley-broken" + parts = list( + /obj/item/mecha_parts/part/ripley_torso, + /obj/item/mecha_parts/part/ripley_left_arm, + /obj/item/mecha_parts/part/ripley_right_arm, + /obj/item/mecha_parts/part/ripley_left_leg, + /obj/item/mecha_parts/part/ripley_right_leg) + +/obj/structure/mecha_wreckage/ripley/mkii + name = "\improper Ripley MK-II wreckage" + icon_state = "ripleymkii-broken" + +/obj/structure/mecha_wreckage/ripley/deathripley + name = "\improper Death-Ripley wreckage" + icon_state = "deathripley-broken" + parts = null + +/obj/structure/mecha_wreckage/ripley/firefighter + name = "\improper Firefighter wreckage" + icon_state = "firefighter-broken" + parts = list( + /obj/item/mecha_parts/part/ripley_torso, + /obj/item/mecha_parts/part/ripley_left_arm, + /obj/item/mecha_parts/part/ripley_right_arm, + /obj/item/mecha_parts/part/ripley_left_leg, + /obj/item/mecha_parts/part/ripley_right_leg) + + +/obj/structure/mecha_wreckage/honker + name = "\improper H.O.N.K wreckage" + icon_state = "honker-broken" + desc = "All is right in the universe." + parts = list( + /obj/item/mecha_parts/part/honker_torso, + /obj/item/mecha_parts/part/honker_head, + /obj/item/mecha_parts/part/honker_left_arm, + /obj/item/mecha_parts/part/honker_right_arm, + /obj/item/mecha_parts/part/honker_left_leg, + /obj/item/mecha_parts/part/honker_right_leg) + +/obj/structure/mecha_wreckage/durand + name = "\improper Durand wreckage" + icon_state = "durand-broken" + parts = list( + /obj/item/mecha_parts/part/durand_torso, + /obj/item/mecha_parts/part/durand_head, + /obj/item/mecha_parts/part/durand_left_arm, + /obj/item/mecha_parts/part/durand_right_arm, + /obj/item/mecha_parts/part/durand_left_leg, + /obj/item/mecha_parts/part/durand_right_leg) + +/obj/structure/mecha_wreckage/phazon + name = "\improper Phazon wreckage" + icon_state = "phazon-broken" + parts = list( + /obj/item/mecha_parts/part/phazon_torso, + /obj/item/mecha_parts/part/phazon_head, + /obj/item/mecha_parts/part/phazon_left_arm, + /obj/item/mecha_parts/part/phazon_right_arm, + /obj/item/mecha_parts/part/phazon_left_leg, + /obj/item/mecha_parts/part/phazon_right_leg) + + + +/obj/structure/mecha_wreckage/odysseus + name = "\improper Odysseus wreckage" + icon_state = "odysseus-broken" + parts = list( + /obj/item/mecha_parts/part/odysseus_torso, + /obj/item/mecha_parts/part/odysseus_head, + /obj/item/mecha_parts/part/odysseus_left_arm, + /obj/item/mecha_parts/part/odysseus_right_arm, + /obj/item/mecha_parts/part/odysseus_left_leg, + /obj/item/mecha_parts/part/odysseus_right_leg) diff --git a/code/game/mecha/medical/odysseus.dm b/code/modules/vehicles/mecha/medical/odysseus.dm similarity index 53% rename from code/game/mecha/medical/odysseus.dm rename to code/modules/vehicles/mecha/medical/odysseus.dm index 6ed207a4c4..dd693f9dbb 100644 --- a/code/game/mecha/medical/odysseus.dm +++ b/code/modules/vehicles/mecha/medical/odysseus.dm @@ -1,31 +1,33 @@ -/obj/mecha/medical/odysseus +/obj/vehicle/sealed/mecha/medical/odysseus desc = "These exosuits are developed and produced by Vey-Med. (© All rights reserved)." name = "\improper Odysseus" icon_state = "odysseus" - step_in = 2 + allow_diagonal_movement = TRUE + movedelay = 2 max_temperature = 15000 max_integrity = 120 wreckage = /obj/structure/mecha_wreckage/odysseus internal_damage_threshold = 35 deflect_chance = 15 - step_energy_drain = 6 + normal_step_energy_drain = 6 + internals_req_access = list(ACCESS_ROBOTICS, ACCESS_MEDICAL) -/obj/mecha/medical/odysseus/moved_inside(mob/living/carbon/human/H) +/obj/vehicle/sealed/mecha/medical/odysseus/moved_inside(mob/living/carbon/human/H) . = ..() if(.) var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] hud.add_hud_to(H) -/obj/mecha/medical/odysseus/go_out() - if(isliving(occupant)) - var/mob/living/carbon/human/L = occupant +/obj/vehicle/sealed/mecha/medical/odysseus/remove_occupant(mob/M) + if(isliving(M)) + var/mob/living/L = M var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] hud.remove_hud_from(L) - ..() + return ..() -/obj/mecha/medical/odysseus/mmi_moved_inside(obj/item/mmi/mmi_as_oc, mob/user) +/obj/vehicle/sealed/mecha/medical/odysseus/mmi_moved_inside(obj/item/mmi/M, mob/user) . = ..() if(.) var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] - var/mob/living/brain/B = mmi_as_oc.brainmob + var/mob/living/brain/B = M.brainmob hud.add_hud_to(B) diff --git a/code/modules/vehicles/mecha/working/ripley.dm b/code/modules/vehicles/mecha/working/ripley.dm new file mode 100644 index 0000000000..40b2e61402 --- /dev/null +++ b/code/modules/vehicles/mecha/working/ripley.dm @@ -0,0 +1,218 @@ +/obj/vehicle/sealed/mecha/working/ripley + desc = "Autonomous Power Loader Unit MK-I. Designed primarily around heavy lifting, the Ripley can be outfitted with utility equipment to fill a number of roles." + name = "\improper APLU MK-I \"Ripley\"" + icon_state = "ripley" + silicon_icon_state = "ripley-empty" + movedelay = 1.5 //Move speed, lower is faster. + /// How fast the mech is in low pressure + var/fast_pressure_step_in = 1.5 + /// How fast the mech is in normal pressure + var/slow_pressure_step_in = 2 + max_temperature = 20000 + max_integrity = 200 + lights_power = 7 + deflect_chance = 15 + armor = list(MELEE = 40, BULLET = 20, LASER = 10, ENERGY = 20, BOMB = 40, BIO = 0, RAD = 20, FIRE = 100, ACID = 100) + max_equip = 6 + wreckage = /obj/structure/mecha_wreckage/ripley + internals_req_access = list(ACCESS_ENGINE, ACCESS_ROBOTICS, ACCESS_MINING) + enclosed = FALSE //Normal ripley has an open cockpit design + enter_delay = 10 //can enter in a quarter of the time of other mechs + exit_delay = 10 + /// Amount of Goliath hides attached to the mech + var/hides = 0 + /// List of all things in Ripley's Cargo Compartment + var/list/cargo = new + /// How much things Ripley can carry in their Cargo Compartment + var/cargo_capacity = 15 + +/obj/vehicle/sealed/mecha/working/ripley/Move() + . = ..() + update_pressure() + +/obj/vehicle/sealed/mecha/working/ripley/check_for_internal_damage(list/possible_int_damage, ignore_threshold = FALSE) + if (!enclosed) + possible_int_damage -= (MECHA_INT_TEMP_CONTROL + MECHA_INT_TANK_BREACH) //if we don't even have an air tank, these two doesn't make a ton of sense. + . = ..() + +/obj/vehicle/sealed/mecha/working/ripley/Initialize(mapload) + . = ..() + AddComponent(/datum/component/armor_plate,3,/obj/item/stack/sheet/animalhide/goliath_hide,list(MELEE = 10, BULLET = 5, LASER = 5)) + +/obj/vehicle/sealed/mecha/working/ripley/generate_actions() + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_eject) + if(enclosed) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_internals, VEHICLE_CONTROL_SETTINGS) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_cycle_equip, VEHICLE_CONTROL_EQUIPMENT) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_lights, VEHICLE_CONTROL_SETTINGS) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_view_stats, VEHICLE_CONTROL_SETTINGS) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/strafe, VEHICLE_CONTROL_DRIVE) + if(max_occupants > 1) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/swap_seat) + +/obj/vehicle/sealed/mecha/working/ripley/Destroy() + for(var/atom/movable/A in cargo) + A.forceMove(drop_location()) + step_rand(A) + cargo.Cut() + return ..() + +/obj/vehicle/sealed/mecha/working/ripley/mkii + desc = "Autonomous Power Loader Unit MK-II. This prototype Ripley is refitted with a pressurized cabin, trading its prior speed for atmospheric protection and armor." + name = "\improper APLU MK-II \"Ripley\"" + icon_state = "ripleymkii" + fast_pressure_step_in = 2 //step_in while in low pressure conditions + slow_pressure_step_in = 4 //step_in while in normal pressure conditions + movedelay = 4 + max_temperature = 30000 + max_integrity = 250 + armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 60, BIO = 0, RAD = 70, FIRE = 100, ACID = 100) + wreckage = /obj/structure/mecha_wreckage/ripley/mkii + enclosed = TRUE + enter_delay = 40 + silicon_icon_state = null + +/obj/vehicle/sealed/mecha/working/ripley/firefighter + desc = "Autonomous Power Loader Unit MK-II-F. This model is refitted with additional thermal protection." + name = "\improper APLU \"Firefighter\"" + icon_state = "firefighter" + movedelay = 4 + fast_pressure_step_in = 2 + slow_pressure_step_in = 4 + max_temperature = 65000 + max_integrity = 250 + resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF + armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 60, BIO = 0, RAD = 70, FIRE = 100, ACID = 100) + max_equip = 5 // More armor, less tools + enclosed = TRUE + enter_delay = 40 + +/obj/vehicle/sealed/mecha/working/ripley/deathripley + desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE" + name = "\improper DEATH-RIPLEY" + icon_state = "deathripley" + fast_pressure_step_in = 2 //step_in while in low pressure conditions + slow_pressure_step_in = 3 //step_in while in normal pressure conditions + movedelay = 4 + lights_power = 7 + wreckage = /obj/structure/mecha_wreckage/ripley/deathripley + normal_step_energy_drain = 0 + enclosed = TRUE + enter_delay = 40 + silicon_icon_state = null + +/obj/vehicle/sealed/mecha/working/ripley/deathripley/Initialize(mapload) + . = ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill + ME.attach(src) + +/obj/vehicle/sealed/mecha/working/ripley/deathripley/real + desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE. FOR REAL" + +/obj/vehicle/sealed/mecha/working/ripley/deathripley/real/Initialize(mapload) + . = ..() + for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) + E.detach() + qdel(E) + LAZYCLEARLIST(equipment) + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/real + ME.attach(src) + +/obj/vehicle/sealed/mecha/working/ripley/mining + desc = "An old, dusty mining Ripley." + name = "\improper APLU \"Miner\"" + obj_integrity = 75 //Low starting health + +/obj/vehicle/sealed/mecha/working/ripley/mining/Initialize(mapload) + . = ..() + if(cell) + cell.charge = FLOOR(cell.charge * 0.25, 1) //Starts at very low charge + if(prob(70)) //Maybe add a drill + if(prob(15)) //Possible diamond drill... Feeling lucky? + var/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill/D = new + D.attach(src) + else + var/obj/item/mecha_parts/mecha_equipment/drill/D = new + D.attach(src) + + else //Add plasma cutter if no drill + var/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma/P = new + P.attach(src) + + //Add ore box to cargo + cargo.Add(new /obj/structure/ore_box(src)) + + //Attach hydraulic clamp + var/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/HC = new + HC.attach(src) + for(var/obj/item/mecha_parts/mecha_tracking/B in trackers)//Deletes the beacon so it can't be found easily + qdel(B) + + var/obj/item/mecha_parts/mecha_equipment/mining_scanner/scanner = new + scanner.attach(src) + +/obj/vehicle/sealed/mecha/working/ripley/Exit(atom/movable/O) + if(O in cargo) + return 0 + return ..() + +/obj/vehicle/sealed/mecha/working/ripley/Topic(href, href_list) + ..() + if(href_list["drop_from_cargo"]) + var/obj/O = locate(href_list["drop_from_cargo"]) in cargo + if(O) + to_chat(occupants, "[icon2html(src, occupants)]You unload [O].") + O.forceMove(drop_location()) + cargo -= O + log_message("Unloaded [O]. Cargo compartment capacity: [cargo_capacity - src.cargo.len]", LOG_MECHA) + return + + +/obj/vehicle/sealed/mecha/working/ripley/contents_explosion(severity, target, origin) + for(var/X in cargo) + var/obj/O = X + if(prob(30/severity)) + cargo -= O + O.forceMove(drop_location()) + . = ..() + +/obj/vehicle/sealed/mecha/working/ripley/get_stats_part() + var/output = ..() + output += "Cargo Compartment Contents:
    " + if(cargo.len) + for(var/obj/O in cargo) + output += "Unload : [O]
    " + else + output += "Nothing" + output += "
    " + return output + +/obj/vehicle/sealed/mecha/working/ripley/relay_container_resist(mob/living/user, obj/O) + to_chat(user, "You lean on the back of [O] and start pushing so it falls out of [src].") + if(do_after(user, 300, target = O)) + if(!user || user.stat != CONSCIOUS || user.loc != src || O.loc != src ) + return + to_chat(user, "You successfully pushed [O] out of [src]!") + O.forceMove(drop_location()) + cargo -= O + else + if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded. + to_chat(user, "You fail to push [O] out of [src]!") + +/** + * Makes the mecha go faster and halves the mecha drill cooldown if in Lavaland pressure. + * + * Checks for Lavaland pressure, if that works out the mech's speed is equal to fast_pressure_step_in and the cooldown for the mecha drill is halved. If not it uses slow_pressure_step_in and drill cooldown is normal. + */ +/obj/vehicle/sealed/mecha/working/ripley/proc/update_pressure() + var/turf/T = get_turf(loc) + + if(lavaland_equipment_pressure_check(T)) + movedelay = fast_pressure_step_in + for(var/obj/item/mecha_parts/mecha_equipment/drill/drill in equipment) + drill.equip_cooldown = initial(drill.equip_cooldown) * 0.5 + + else + movedelay = slow_pressure_step_in + for(var/obj/item/mecha_parts/mecha_equipment/drill/drill in equipment) + drill.equip_cooldown = initial(drill.equip_cooldown) diff --git a/code/modules/vehicles/mecha/working/working.dm b/code/modules/vehicles/mecha/working/working.dm new file mode 100644 index 0000000000..c765e0f0e5 --- /dev/null +++ b/code/modules/vehicles/mecha/working/working.dm @@ -0,0 +1,28 @@ +/obj/vehicle/sealed/mecha/working + internal_damage_threshold = 60 + +/obj/vehicle/sealed/mecha/working/Move() + . = ..() + if(.) + collect_ore() + +/** + * Handles collecting ore. + * + * Checks for a hydraulic clamp or ore box manager and if it finds an ore box inside them puts ore in the ore box. + */ +/obj/vehicle/sealed/mecha/working/proc/collect_ore() + if((locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in equipment)) + var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in contents + if(ore_box) + for(var/obj/item/stack/ore/ore in range(1, src)) + if(ore.Adjacent(src) && ((get_dir(src, ore) & dir) || ore.loc == loc)) //we can reach it and it's in front of us? grab it! + ore.forceMove(ore_box) + +/obj/vehicle/sealed/mecha/working/Bump(atom/obstacle) + if(istype(selected, /obj/item/mecha_parts/mecha_equipment/drill) && istype(obstacle, /turf/closed/mineral)) + var/obj/item/mecha_parts/mecha_equipment/drill/thedrill = selected + for(var/mob/M in occupants) + thedrill.action(M, obstacle) + break + ..() diff --git a/code/modules/vehicles/ridden.dm b/code/modules/vehicles/ridden.dm index f71d9367d3..42b6d0dbf7 100644 --- a/code/modules/vehicles/ridden.dm +++ b/code/modules/vehicles/ridden.dm @@ -4,10 +4,11 @@ max_buckled_mobs = 1 buckle_lying = FALSE default_driver_move = FALSE + pass_flags_self = PASSTABLE var/legs_required = 1 var/arms_required = 0 //why not? -/obj/vehicle/ridden/Initialize() +/obj/vehicle/ridden/Initialize(mapload) . = ..() LoadComponent(/datum/component/riding) diff --git a/code/modules/vehicles/scooter.dm b/code/modules/vehicles/scooter.dm index 3e0e71446d..13a614449a 100644 --- a/code/modules/vehicles/scooter.dm +++ b/code/modules/vehicles/scooter.dm @@ -3,7 +3,7 @@ desc = "A fun way to get around." icon_state = "scooter" -/obj/vehicle/ridden/scooter/Initialize() +/obj/vehicle/ridden/scooter/Initialize(mapload) . = ..() var/datum/component/riding/D = LoadComponent(/datum/component/riding) D.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0), TEXT_SOUTH = list(-2), TEXT_EAST = list(0), TEXT_WEST = list( 2))) @@ -57,7 +57,7 @@ ///Stamina drain multiplier var/instability = 10 -/obj/vehicle/ridden/scooter/skateboard/Initialize() +/obj/vehicle/ridden/scooter/skateboard/Initialize(mapload) . = ..() var/datum/component/riding/D = LoadComponent(/datum/component/riding) D.vehicle_move_delay = 1 @@ -102,7 +102,7 @@ var/atom/throw_target = get_edge_target_turf(H, pick(GLOB.cardinals)) unbuckle_mob(H) H.throw_at(throw_target, 3, 2) - var/head_slot = H.get_item_by_slot(SLOT_HEAD) + var/head_slot = H.get_item_by_slot(ITEM_SLOT_HEAD) if(!head_slot || !(istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/hardhat))) H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5) H.updatehealth() @@ -253,7 +253,7 @@ icon = null density = FALSE -/obj/vehicle/ridden/scooter/wheelys/Initialize() +/obj/vehicle/ridden/scooter/wheelys/Initialize(mapload) . = ..() var/datum/component/riding/D = LoadComponent(/datum/component/riding) D.vehicle_move_delay = 1 @@ -281,7 +281,7 @@ H.throw_at(throw_target, 4, 3) H.DefaultCombatKnockdown(30) H.adjustStaminaLoss(30) - var/head_slot = H.get_item_by_slot(SLOT_HEAD) + var/head_slot = H.get_item_by_slot(ITEM_SLOT_HEAD) if(!head_slot || !(istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/hardhat))) H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1) H.updatehealth() diff --git a/code/modules/vehicles/sealed.dm b/code/modules/vehicles/sealed.dm index 63c7c9f858..7c1fa8f61a 100644 --- a/code/modules/vehicles/sealed.dm +++ b/code/modules/vehicles/sealed.dm @@ -1,7 +1,6 @@ /obj/vehicle/sealed enclosed = TRUE // you're in a sealed vehicle dont get dinked idiot var/enter_delay = 20 - var/explode_on_death = TRUE flags_1 = BLOCK_FACE_ATOM_1 /obj/vehicle/sealed/generate_actions() @@ -26,7 +25,7 @@ return FALSE if(occupant_amount() >= max_occupants) return FALSE - if(do_after(M, get_enter_delay(M), FALSE, src, TRUE)) + if(do_after(M, get_enter_delay(M), src, timed_action_flags = IGNORE_HELD_ITEM)) mob_enter(M) return TRUE return FALSE @@ -47,10 +46,12 @@ mob_exit(M, silent, randomstep) /obj/vehicle/sealed/proc/mob_exit(mob/M, silent = FALSE, randomstep = FALSE) + SIGNAL_HANDLER if(!istype(M)) return FALSE remove_occupant(M) - M.forceMove(exit_location(M)) + if(!isAI(M))//This is the ONE mob we dont want to be moved to the vehicle that should be handeled when used + M.forceMove(exit_location(M)) if(randomstep) var/turf/target_turf = get_step(exit_location(M), pick(GLOB.cardinals)) M.throw_at(target_turf, 5, 10) @@ -88,8 +89,6 @@ /obj/vehicle/sealed/Destroy() DumpMobs() - if(explode_on_death) - explosion(loc, 0, 1, 2, 3, 0) return ..() /obj/vehicle/sealed/proc/DumpMobs(randomstep = TRUE) diff --git a/code/modules/vehicles/secway.dm b/code/modules/vehicles/secway.dm index 8ad8b5f1ee..fffa872957 100644 --- a/code/modules/vehicles/secway.dm +++ b/code/modules/vehicles/secway.dm @@ -12,7 +12,7 @@ var/last_tick = 0 var/list/progressbars_by_rider = list() -/obj/vehicle/ridden/secway/Initialize() +/obj/vehicle/ridden/secway/Initialize(mapload) . = ..() var/datum/component/riding/D = LoadComponent(/datum/component/riding) D.vehicle_move_delay = 1 @@ -43,7 +43,8 @@ . = ..(M, force, check_loc) if(.) if(progressbars_by_rider[M]) - qdel(progressbars_by_rider[M]) + var/datum/progressbar/to_delete = progressbars_by_rider[M] + to_delete.end_progress() var/datum/progressbar/D = new(M, chargemax, src) D.update(charge) progressbars_by_rider[M] = D @@ -51,12 +52,14 @@ /obj/vehicle/ridden/secway/unbuckle_mob(mob/living/M, force) . = ..(M, force) if(.) - qdel(progressbars_by_rider[M]) + var/datum/progressbar/to_delete = progressbars_by_rider[M] + to_delete.end_progress() progressbars_by_rider -= M /obj/vehicle/ridden/secway/Destroy() for(var/i in progressbars_by_rider) - qdel(progressbars_by_rider[i]) + var/datum/progressbar/to_delete = progressbars_by_rider[i] + to_delete.end_progress() progressbars_by_rider.Cut() STOP_PROCESSING(SSfastprocess, src) return ..() diff --git a/code/modules/vehicles/speedbike.dm b/code/modules/vehicles/speedbike.dm index a560cbb8f3..d0b9c1fe96 100644 --- a/code/modules/vehicles/speedbike.dm +++ b/code/modules/vehicles/speedbike.dm @@ -2,7 +2,7 @@ /obj/vehicle/ridden/space name = "Generic Space Vehicle!" -/obj/vehicle/ridden/space/Initialize() +/obj/vehicle/ridden/space/Initialize(mapload) . = ..() var/datum/component/riding/D = LoadComponent(/datum/component/riding) D.override_allow_spacemove = TRUE @@ -15,7 +15,7 @@ var/overlay_state = "cover_blue" var/mutable_appearance/overlay -/obj/vehicle/ridden/space/speedbike/Initialize() +/obj/vehicle/ridden/space/speedbike/Initialize(mapload) . = ..() overlay = mutable_appearance(icon, overlay_state, ABOVE_MOB_LAYER) add_overlay(overlay) @@ -50,7 +50,7 @@ pixel_y = -48 pixel_x = -48 -/obj/vehicle/ridden/space/speedwagon/Initialize() +/obj/vehicle/ridden/space/speedwagon/Initialize(mapload) . = ..() add_overlay(overlay) var/datum/component/riding/D = LoadComponent(/datum/component/riding) diff --git a/code/modules/vehicles/vehicle_actions.dm b/code/modules/vehicles/vehicle_actions.dm index 5de2c8961f..8b2c72008c 100644 --- a/code/modules/vehicles/vehicle_actions.dm +++ b/code/modules/vehicles/vehicle_actions.dm @@ -126,44 +126,70 @@ desc = "Honk your classy horn." button_icon_state = "car_horn" var/hornsound = 'sound/items/carhorn.ogg' - var/last_honk_time /datum/action/vehicle/sealed/horn/Trigger() - if(world.time - last_honk_time > 20) - vehicle_entered_target.visible_message("[vehicle_entered_target] loudly honks") - to_chat(owner, "You press the vehicle's horn.") - playsound(vehicle_entered_target, hornsound, 75) - last_honk_time = world.time + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_CAR_HONK)) + return + TIMER_COOLDOWN_START(src, COOLDOWN_CAR_HONK, 2 SECONDS) + vehicle_entered_target.visible_message(span_danger("[vehicle_entered_target] loudly honks!")) + to_chat(owner, span_notice("You press [vehicle_entered_target]'s horn.")) + if(istype(vehicle_target.inserted_key, /obj/item/bikehorn)) + vehicle_target.inserted_key.attack_self(owner) //The bikehorn plays a sound instead + return + playsound(vehicle_entered_target, hornsound, 75) -/datum/action/vehicle/sealed/horn/clowncar/Trigger() - if(world.time - last_honk_time > 20) - vehicle_entered_target.visible_message("[vehicle_entered_target] loudly honks") - to_chat(owner, "You press the vehicle's horn.") - last_honk_time = world.time - if(vehicle_target.inserted_key) - vehicle_target.inserted_key.attack_self(owner) //The key plays a sound - else - playsound(vehicle_entered_target, hornsound, 75) - -/datum/action/vehicle/sealed/DumpKidnappedMobs - name = "Dump kidnapped mobs" +/datum/action/vehicle/sealed/dump_kidnapped_mobs + name = "Dump Kidnapped Mobs" desc = "Dump all objects and people in your car on the floor." button_icon_state = "car_dump" -/datum/action/vehicle/sealed/DumpKidnappedMobs/Trigger() - vehicle_entered_target.visible_message("[vehicle_entered_target] starts dumping the people inside of it.") +/datum/action/vehicle/sealed/dump_kidnapped_mobs/Trigger() + vehicle_entered_target.visible_message(span_danger("[vehicle_entered_target] starts dumping the people inside of it.")) vehicle_entered_target.DumpSpecificMobs(VEHICLE_CONTROL_KIDNAPPED) -/datum/action/vehicle/sealed/RollTheDice - name = "Press a colorful button" +/datum/action/vehicle/sealed/roll_the_dice + name = "Press Colorful Button" desc = "Press one of those colorful buttons on your display panel!" button_icon_state = "car_rtd" -/datum/action/vehicle/sealed/RollTheDice/Trigger() - if(istype(vehicle_entered_target, /obj/vehicle/sealed/car/clowncar)) - var/obj/vehicle/sealed/car/clowncar/C = vehicle_entered_target - C.RollTheDice(owner) +/datum/action/vehicle/sealed/roll_the_dice/Trigger() + if(!istype(vehicle_entered_target, /obj/vehicle/sealed/car/clowncar)) + return + var/obj/vehicle/sealed/car/clowncar/C = vehicle_entered_target + C.roll_the_dice(owner) + +/datum/action/vehicle/sealed/cannon + name = "Toggle Siege Mode" + desc = "Destroy them with their own fodder!" + button_icon_state = "car_cannon" + +/datum/action/vehicle/sealed/cannon/Trigger() + if(!istype(vehicle_entered_target, /obj/vehicle/sealed/car/clowncar)) + return + var/obj/vehicle/sealed/car/clowncar/C = vehicle_entered_target + C.toggle_cannon(owner) + + +/datum/action/vehicle/sealed/thank + name = "Thank the Clown Car Driver" + desc = "They're just doing their job." + button_icon_state = "car_thanktheclown" + COOLDOWN_DECLARE(thank_time_cooldown) + + +/datum/action/vehicle/sealed/thank/Trigger() + if(!istype(vehicle_entered_target, /obj/vehicle/sealed/car/clowncar)) + return + if(!COOLDOWN_FINISHED(src, thank_time_cooldown)) + return + COOLDOWN_START(src, thank_time_cooldown, 6 SECONDS) + var/obj/vehicle/sealed/car/clowncar/clown_car = vehicle_entered_target + var/mob/living/carbon/human/clown = pick(clown_car.return_drivers()) + if(!clown) + return + owner.say("Thank you for the fun ride, [clown.name]!") + clown_car.increment_thanks_counter() /datum/action/vehicle/ridden/scooter/skateboard/ollie @@ -197,7 +223,9 @@ L.Move(landing_turf, vehicle_target.dir) passtable_off(L, VEHICLE_TRAIT) V.pass_flags &= ~PASSTABLE - if(locate(/obj/structure/table) in V.loc.contents) + if((locate(/obj/structure/table) in V.loc.contents) || (locate(/obj/structure/fluff/railing) in V.loc.contents)) + if(locate(/obj/structure/fluff/railing) in V.loc.contents) + L.client.give_award(/datum/award/achievement/misc/tram_surfer, L) V.grinding = TRUE V.icon_state = "[V.board_icon]-grind" addtimer(CALLBACK(V, /obj/vehicle/ridden/scooter/skateboard/.proc/grind), 2) diff --git a/code/modules/vehicles/vehicle_key.dm b/code/modules/vehicles/vehicle_key.dm index e34ad9253d..25dd40691c 100644 --- a/code/modules/vehicles/vehicle_key.dm +++ b/code/modules/vehicles/vehicle_key.dm @@ -13,3 +13,24 @@ desc = "A keyring with a small steel key, and a pink fob reading \"Pussy Wagon\"." icon_state = "keyjanitor" +//START VECTORCARKEYS +/obj/item/key/CMO + desc = "A keyring with a small steel key to the CMO\'s race hovercar." + +/obj/item/key/RD + desc = "A keyring with a small steel key to the RD\'s race hovercar." + +/obj/item/key/hop + desc = "A keyring with a small steel key to the HOP\'s race hovercar." + +/obj/item/key/hos + desc = "A keyring with a small steel key to the HOS\'s race hovercar." + +/obj/item/key/CE + desc = "A keyring with a small steel key to the CE\'s race hovercar." + +/obj/item/key/QM + desc = "A keyring with a small steel key to the QM\'s race hovercar." + +/obj/item/key/CAPT + desc = "A keyring with a small steel key to the Captain\'s race hovercar." diff --git a/code/modules/vehicles/wheelchair.dm b/code/modules/vehicles/wheelchair.dm index 28145ba8e1..cc432957f6 100644 --- a/code/modules/vehicles/wheelchair.dm +++ b/code/modules/vehicles/wheelchair.dm @@ -5,14 +5,14 @@ icon_state = "wheelchair" layer = OBJ_LAYER max_integrity = 100 - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 30) //Wheelchairs aren't super tough yo + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 20, ACID = 30) //Wheelchairs aren't super tough yo legs_required = 0 //You'll probably be using this if you don't have legs canmove = TRUE density = FALSE //Thought I couldn't fix this one easily, phew arms_required = 1 var/override_movespeed = FALSE -/obj/vehicle/ridden/wheelchair/Initialize() +/obj/vehicle/ridden/wheelchair/Initialize(mapload) . = ..() var/datum/component/riding/D = LoadComponent(/datum/component/riding) D.vehicle_move_delay = 0 diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index eab1c55ca9..f84ced508e 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -12,16 +12,14 @@ products = list() contraband = list() premium = list() - -IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY CANISTER CHARGES in vending_items.dm */ #define MAX_VENDING_INPUT_AMOUNT 30 /** - * # vending record datum - * - * A datum that represents a product that is vendable - */ + * # vending record datum + * + * A datum that represents a product that is vendable + */ /datum/data/vending_product name = "generic" ///Typepath of the product that is created when this record "sells" @@ -34,12 +32,16 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C var/custom_price ///Does the item have a custom premium price override var/custom_premium_price + ///Whether spessmen with an ID with an age below AGE_MINOR (20 by default) can buy this item + var/age_restricted = FALSE // @unimplimented + ///Whether the product can be recolored by the GAGS system + var/colorable // @unimplimented /** - * # vending machines - * - * Captalism in the year 2525, everything in a vending machine, even love - */ + * # vending machines + * + * Captalism in the year 2525, everything in a vending machine, even love + */ /obj/machinery/vending name = "\improper Vendomat" desc = "A generic vending machine." @@ -52,39 +54,46 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C verb_exclaim = "beeps" max_integrity = 300 integrity_failure = 0.33 - armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70) + armor = list(MELEE = 20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 70) circuit = /obj/item/circuitboard/machine/vendor payment_department = ACCOUNT_SRV - light_power = 0.3 + light_power = 0.5 light_range = MINIMUM_USEFUL_LIGHT_RANGE /// Is the machine active (No sales pitches if off)! - var/active = TRUE + var/active = 1 ///Are we ready to vend?? Is it time?? var/vend_ready = TRUE ///Next world time to send a purchase message var/purchase_message_cooldown - ///Last mob to shop with us + ///The ref of the last mob to shop with us + var/last_shopper + var/tilted = FALSE + var/tiltable = TRUE + var/squish_damage = 75 + var/forcecrit = 0 + var/num_shards = 7 + var/list/pinned_mobs = list() /** * List of products this machine sells * - * form should be list(/type/path = amount, /type/path2 = amount2) + * form should be list(/type/path = amount, /type/path2 = amount2) */ - var/list/products = list() + var/list/products = list() /** * List of products this machine sells when you hack it * - * form should be list(/type/path = amount, /type/path2 = amount2) + * form should be list(/type/path = amount, /type/path2 = amount2) */ - var/list/contraband = list() + var/list/contraband = list() /** * List of premium products this machine sells * - * form should be list(/type/path, /type/path2) as there is only ever one in stock + * form should be list(/type/path, /type/path2) as there is only ever one in stock */ - var/list/premium = list() + var/list/premium = list() ///String of slogans separated by semicolons, optional var/product_slogans = "" @@ -97,20 +106,12 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C var/list/slogan_list = list() ///Small ad messages in the vending screen - random chance of popping up whenever you open it var/list/small_ads = list() - var/dish_quants = list() //used by the snack machine's custom compartment to count dishes. ///Message sent post vend (Thank you for shopping!) var/vend_reply ///Last world tick we sent a vent reply - var/last_reply + var/last_reply = 0 ///Last world tick we sent a slogan message out - var/last_slogan - var/last_shopper - var/tilted = FALSE - var/tiltable = TRUE - var/squish_damage = 75 - var/forcecrit = 0 - var/num_shards = 7 - var/list/pinned_mobs = list() + var/last_slogan = 0 ///How many ticks until we can send another var/slogan_delay = 6000 ///Icon when vending an item to the user @@ -120,32 +121,37 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C ///World ticks the machine is electified for var/seconds_electrified = MACHINE_NOT_ELECTRIFIED ///When this is TRUE, we fire items at customers! We're broken! - var/shoot_inventory - ///How likely this is to happen (prob 100) - var/shoot_inventory_chance = 2 + var/shoot_inventory = 0 + ///How likely this is to happen (prob 100) per second + var/shoot_inventory_chance = 1 //Stop spouting those godawful pitches! - var/shut_up + var/shut_up = 0 ///can we access the hidden inventory? - var/extended_inventory + var/extended_inventory = 0 ///Are we checking the users ID - var/scan_id = TRUE + var/scan_id = 1 + ///Coins that we accept? var/obj/item/coin/coin + ///Bills we accept? + var/obj/item/stack/spacecash/bill ///Default price of items if not overridden var/default_price = 25 ///Default price of premium items if not overridden var/extra_price = 50 + ///Whether our age check is currently functional + var/age_restrictions = TRUE ///cost multiplier per department or access var/list/cost_multiplier_per_dept = list() - /** + /** * Is this item on station or not * * if it doesn't originate from off-station during mapload, everything is free */ var/onstation = TRUE //if it doesn't originate from off-station during mapload, everything is free - ///A variable to change on a per instance basis on the map that allows the instance to force cost and ID requirements + ///A variable to change on a per instance basis on the map that allows the instance to force cost and ID requirements var/onstation_override = FALSE //change this on the object on the map to override the onstation check. DO NOT APPLY THIS GLOBALLY. - ///ID's that can load this vending machine wtih refills + ///ID's that can load this vending machine wtih refills var/list/canload_access_list @@ -162,15 +168,19 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C ///Name of lighting mask for the vending machine var/light_mask + /// used for narcing on underages + var/obj/item/radio/Radio + + /** - * Initialize the vending machine - * - * Builds the vending machine inventory, sets up slogans and other such misc work - * - * This also sets the onstation var to: - * * FALSE - if the machine was maploaded on a zlevel that doesn't pass the is_station_level check - * * TRUE - all other cases - */ + * Initialize the vending machine + * + * Builds the vending machine inventory, sets up slogans and other such misc work + * + * This also sets the onstation var to: + * * FALSE - if the machine was maploaded on a zlevel that doesn't pass the is_station_level check + * * TRUE - all other cases + */ /obj/machinery/vending/Initialize(mapload) var/build_inv = FALSE if(!refill_canister) @@ -189,18 +199,25 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. last_slogan = world.time + rand(0, slogan_delay) power_change() + if(onstation_override) //overrides the checks if true. onstation = TRUE return - if(mapload && !is_station_level(z)) //check if it was initially created off station during mapload. - onstation = FALSE - if(circuit) - circuit.onstation = onstation //sync up the circuit so the pricing schema is carried over if it's reconstructed. + if(mapload) //check if it was initially created off station during mapload. + if(!is_station_level(z)) + onstation = FALSE + if(circuit) + circuit.onstation = onstation //sync up the circuit so the pricing schema is carried over if it's reconstructed. else if(circuit && (circuit.onstation != onstation)) //check if they're not the same to minimize the amount of edited values. onstation = circuit.onstation //if it was constructed outside mapload, sync the vendor up with the circuit's var so you can't bypass price requirements by moving / reconstructing it off station. + Radio = new /obj/item/radio(src) + Radio.listening = 0 /obj/machinery/vending/Destroy() QDEL_NULL(wires) + QDEL_NULL(coin) + QDEL_NULL(bill) + QDEL_NULL(Radio) return ..() /obj/machinery/vending/can_speak() @@ -227,16 +244,20 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C else ..() +/obj/machinery/vending/update_appearance(updates=ALL) + . = ..() + if(stat & BROKEN) + set_light(0) + return + set_light(powered() ? MINIMUM_USEFUL_LIGHT_RANGE : 0) + + /obj/machinery/vending/update_icon_state() if(stat & BROKEN) icon_state = "[initial(icon_state)]-broken" - set_light(0) - else if(powered()) - icon_state = initial(icon_state) - set_light(1.4) - else - icon_state = "[initial(icon_state)]-off" - set_light(0) + return ..() + icon_state = "[initial(icon_state)][powered() ? null : "-off"]" + return ..() /obj/machinery/vending/update_overlays() @@ -276,14 +297,14 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C GLOBAL_LIST_EMPTY(vending_products) /** - * Build the inventory of the vending machine from it's product and record lists - * - * This builds up a full set of /datum/data/vending_products from the product list of the vending machine type - * Arguments: - * * productlist - the list of products that need to be converted - * * recordlist - the list containing /datum/data/vending_product datums - * * startempty - should we set vending_product record amount from the product list (so it's prefilled at roundstart) - */ + * Build the inventory of the vending machine from it's product and record lists + * + * This builds up a full set of /datum/data/vending_products from the product list of the vending machine type + * Arguments: + * * productlist - the list of products that need to be converted + * * recordlist - the list containing /datum/data/vending_product datums + * * startempty - should we set vending_product record amount from the product list (so it's prefilled at roundstart) + */ /obj/machinery/vending/proc/build_inventory(list/productlist, list/recordlist, start_empty = FALSE) for(var/typepath in productlist) var/amount = productlist[typepath] @@ -298,17 +319,21 @@ GLOBAL_LIST_EMPTY(vending_products) if(!start_empty) R.amount = amount R.max_amount = amount + ///Prices of vending machines are all increased uniformly. R.custom_price = initial(temp.custom_price) R.custom_premium_price = initial(temp.custom_premium_price) + // R.age_restricted = initial(temp.age_restricted) + // R.colorable = !!(initial(temp.greyscale_config) && initial(temp.greyscale_colors) && (initial(temp.flags_1) & IS_PLAYER_COLORABLE_1)) recordlist += R + /** - * Refill a vending machine from a refill canister - * - * This takes the products from the refill canister and then fills the products,contraband and premium product categories - * - * Arguments: - * * canister - the vending canister we are refilling from - */ + * Refill a vending machine from a refill canister + * + * This takes the products from the refill canister and then fills the products,contraband and premium product categories + * + * Arguments: + * * canister - the vending canister we are refilling from + */ /obj/machinery/vending/proc/restock(obj/item/vending_refill/canister) if (!canister.products) canister.products = products.Copy() @@ -321,12 +346,12 @@ GLOBAL_LIST_EMPTY(vending_products) . += refill_inventory(canister.contraband, hidden_records) . += refill_inventory(canister.premium, coin_records) /** - * Refill our inventory from the passed in product list into the record list - * - * Arguments: - * * productlist - list of types -> amount - * * recordlist - existing record datums - */ + * Refill our inventory from the passed in product list into the record list + * + * Arguments: + * * productlist - list of types -> amount + * * recordlist - existing record datums + */ /obj/machinery/vending/proc/refill_inventory(list/productlist, list/recordlist) . = 0 for(var/R in recordlist) @@ -337,10 +362,10 @@ GLOBAL_LIST_EMPTY(vending_products) record.amount += diff . += diff /** - * Set up a refill canister that matches this machines products - * - * This is used when the machine is deconstructed, so the items aren't "lost" - */ + * Set up a refill canister that matches this machines products + * + * This is used when the machine is deconstructed, so the items aren't "lost" + */ /obj/machinery/vending/proc/update_canister() if (!component_parts) return @@ -354,8 +379,8 @@ GLOBAL_LIST_EMPTY(vending_products) R.premium = unbuild_inventory(coin_records) /** - * Given a record list, go through and and return a list of type -> amount - */ + * Given a record list, go through and and return a list of type -> amount + */ /obj/machinery/vending/proc/unbuild_inventory(list/recordlist) . = list() for(var/R in recordlist) @@ -385,32 +410,32 @@ GLOBAL_LIST_EMPTY(vending_products) add_overlay("[initial(icon_state)]-panel") updateUsrDialog() else - to_chat(user, "You must first secure [src].") + to_chat(user, span_warning("You must first secure [src].")) return TRUE -/obj/machinery/vending/attackby(obj/item/I, mob/user, params) +/obj/machinery/vending/attackby(obj/item/I, mob/living/user, params) if(panel_open && is_wire_tool(I)) wires.interact(user) return + if(refill_canister && istype(I, refill_canister)) if (!panel_open) - to_chat(user, "You should probably unscrew the service panel first!") + to_chat(user, span_warning("You should probably unscrew the service panel first!")) else if (stat & (BROKEN|NOPOWER)) - to_chat(user, "[src] does not respond.") + to_chat(user, span_notice("[src] does not respond.")) else //if the panel is open we attempt to refill the machine var/obj/item/vending_refill/canister = I if(canister.get_part_rating() == 0) - to_chat(user, "[canister] is empty!") + to_chat(user, span_warning("[canister] is empty!")) else // instantiate canister if needed var/transferred = restock(canister) if(transferred) - to_chat(user, "You loaded [transferred] items in [src].") + to_chat(user, span_notice("You loaded [transferred] items in [src].")) else - to_chat(user, "There's nothing to restock!") + to_chat(user, span_warning("There's nothing to restock!")) return - if(compartmentLoadAccessCheck(user) && user.a_intent != INTENT_HARM) if(canLoadItem(I)) loadingAttempt(I,user) @@ -422,7 +447,7 @@ GLOBAL_LIST_EMPTY(vending_products) var/denied_items = 0 for(var/obj/item/the_item in T.contents) if(contents.len >= MAX_VENDING_INPUT_AMOUNT) // no more than 30 item can fit inside, legacy from snack vending although not sure why it exists - to_chat(user, "[src]'s compartment is full.") + to_chat(user, span_warning("[src]'s compartment is full.")) break if(canLoadItem(the_item) && loadingAttempt(the_item,user)) SEND_SIGNAL(T, COMSIG_TRY_STORAGE_TAKE, the_item, src, TRUE) @@ -430,9 +455,9 @@ GLOBAL_LIST_EMPTY(vending_products) else denied_items++ if(denied_items) - to_chat(user, "[src] refuses some items!") + to_chat(user, span_warning("[src] refuses some items!")) if(loaded) - to_chat(user, "You insert [loaded] dishes into [src]'s compartment.") + to_chat(user, span_notice("You insert [loaded] dishes into [src]'s compartment.")) updateUsrDialog() else . = ..() @@ -444,13 +469,14 @@ GLOBAL_LIST_EMPTY(vending_products) freebie(user, 2) if(16 to 25) freebie(user, 1) + if(26 to 75) if(76 to 90) tilt(user) if(91 to 100) tilt(user, crit=TRUE) /obj/machinery/vending/proc/freebie(mob/fatty, freebies) - visible_message("[src] yields [freebies > 1 ? "several free goodies" : "a free goody"]!") + visible_message(span_notice("[src] yields [freebies > 1 ? "several free goodies" : "a free goody"]!")) for(var/i in 1 to freebies) playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3) @@ -466,8 +492,9 @@ GLOBAL_LIST_EMPTY(vending_products) new dump_path(get_turf(src)) break -/obj/machinery/vending/proc/tilt(mob/fatty, crit=FALSE) - visible_message("[src] tips over!") +///Tilts ontop of the atom supplied, if crit is true some extra shit can happen. Returns TRUE if it dealt damage to something. +/obj/machinery/vending/proc/tilt(atom/fatty, crit=FALSE) + visible_message(span_danger("[src] tips over!")) tilted = TRUE layer = ABOVE_MOB_LAYER @@ -478,16 +505,21 @@ GLOBAL_LIST_EMPTY(vending_products) if(forcecrit) crit_case = forcecrit + . = FALSE + if(in_range(fatty, src)) for(var/mob/living/L in get_turf(fatty)) + var/was_alive = (L.stat != DEAD) var/mob/living/carbon/C = L + // SEND_SIGNAL(L, COMSIG_ON_VENDOR_CRUSH) + if(istype(C)) var/crit_rebate = 0 // lessen the normal damage we deal for some of the crits - if(crit_case < 5) // the head asplode case has its own description - C.visible_message("[C] is crushed by [src]!", \ - "You are crushed by [src]!") + if(crit_case < 5) // the body/head asplode case has its own description + C.visible_message(span_danger("[C] is crushed by [src]!"), \ + span_userdanger("You are crushed by [src]!")) switch(crit_case) // only carbons can have the fun crits if(1) // shatter their legs and bleed 'em @@ -500,13 +532,13 @@ GLOBAL_LIST_EMPTY(vending_products) if(r) r.receive_damage(brute=200, updating_health=TRUE) if(l || r) - C.visible_message("[C]'s legs shatter with a sickening crunch!", \ - "Your legs shatter with a sickening crunch!") + C.visible_message(span_danger("[C]'s legs shatter with a sickening crunch!"), \ + span_userdanger("Your legs shatter with a sickening crunch!")) if(2) // pin them beneath the machine until someone untilts it forceMove(get_turf(C)) buckle_mob(C, force=TRUE) - C.visible_message("[C] is pinned underneath [src]!", \ - "You are pinned down by [src]!") + C.visible_message(span_danger("[C] is pinned underneath [src]!"), \ + span_userdanger("You are pinned down by [src]!")) if(3) // glass candy crit_rebate = 50 for(var/i = 0, i < num_shards, i++) @@ -518,7 +550,7 @@ GLOBAL_LIST_EMPTY(vending_products) shard.updateEmbedding() if(4) // paralyze this binch // the new paraplegic gets like 4 lines of losing their legs so skip them - visible_message("[C]'s spinal cord is obliterated with a sickening crunch!", ignored_mobs = list(C)) + visible_message(span_danger("[C]'s spinal cord is obliterated with a sickening crunch!"), ignored_mobs = list(C)) C.gain_trauma(/datum/brain_trauma/severe/paralysis/spinesnapped) if(5) // limb squish! for(var/i in C.bodyparts) @@ -528,13 +560,13 @@ GLOBAL_LIST_EMPTY(vending_products) squish_part.force_wound_upwards(type_wound) else squish_part.receive_damage(brute=30) - C.visible_message("[C]'s body is maimed underneath the mass of [src]!", \ - "Your body is maimed underneath the mass of [src]!") + C.visible_message(span_danger("[C]'s body is maimed underneath the mass of [src]!"), \ + span_userdanger("Your body is maimed underneath the mass of [src]!")) if(6) // skull squish! var/obj/item/bodypart/head/O = C.get_bodypart(BODY_ZONE_HEAD) if(O) - C.visible_message("[O] explodes in a shower of gore beneath [src]!", \ - "Oh f-") + C.visible_message(span_danger("[O] explodes in a shower of gore beneath [src]!"), \ + span_userdanger("Oh f-")) O.dismember() O.drop_organs() qdel(O) @@ -545,19 +577,19 @@ GLOBAL_LIST_EMPTY(vending_products) else C.take_bodypart_damage((squish_damage - crit_rebate)*0.5, wound_bonus = 5) // otherwise, deal it to 2 random limbs (or the same one) which will likely shatter something C.take_bodypart_damage((squish_damage - crit_rebate)*0.5, wound_bonus = 5) - C.AddElement(/datum/element/squish, 18 SECONDS) + C.AddElement(/datum/element/squish, 80 SECONDS) else - L.visible_message("[L] is crushed by [src]!", \ - "You are crushed by [src]!") + L.visible_message(span_danger("[L] is crushed by [src]!"), \ + span_userdanger("You are crushed by [src]!")) L.apply_damage(squish_damage, forced=TRUE) if(crit_case) L.apply_damage(squish_damage, forced=TRUE) - - if(L.stat == DEAD && L.client) + if(was_alive && L.stat == DEAD && L.client) L.client.give_award(/datum/award/achievement/misc/vendor_squish, L) // good job losing a fight with an inanimate object idiot L.Paralyze(60) L.emote("scream") + . = TRUE playsound(L, 'sound/effects/blobattack.ogg', 40, TRUE) playsound(L, 'sound/effects/splat.ogg', 50, TRUE) @@ -566,14 +598,15 @@ GLOBAL_LIST_EMPTY(vending_products) transform = M if(get_turf(fatty) != get_turf(src)) - throw_at(get_turf(fatty), 1, 1, spin=FALSE) + throw_at(get_turf(fatty), 1, 1, spin=FALSE) //, quickstart=FALSE) /obj/machinery/vending/proc/untilt(mob/user) - user.visible_message("[user] rights [src].", \ - "You right [src].") + if(user) + user.visible_message(span_notice("[user] rights [src]."), \ + span_notice("You right [src].")) unbuckle_all_mobs(TRUE) - anchored = FALSE //so you can push it back into position + tilted = FALSE layer = initial(layer) @@ -589,21 +622,20 @@ GLOBAL_LIST_EMPTY(vending_products) vending_machine_input[format_text(I.name)]++ else vending_machine_input[format_text(I.name)] = 1 - to_chat(user, "You insert [I] into [src]'s input compartment.") + to_chat(user, span_notice("You insert [I] into [src]'s input compartment.")) loaded_items++ - /obj/machinery/vending/unbuckle_mob(mob/living/buckled_mob, force=FALSE) if(!force) return . = ..() /** - * Is the passed in user allowed to load this vending machines compartments - * - * Arguments: - * * user - mob that is doing the loading of the vending machine - */ + * Is the passed in user allowed to load this vending machines compartments + * + * Arguments: + * * user - mob that is doing the loading of the vending machine + */ /obj/machinery/vending/proc/compartmentLoadAccessCheck(mob/user) if(!canload_access_list) return TRUE @@ -621,7 +653,7 @@ GLOBAL_LIST_EMPTY(vending_products) if(do_you_have_access) return TRUE else - to_chat(user, "[src]'s input compartment blinks red: Access denied.") + to_chat(user, span_warning("[src]'s input compartment blinks red: Access denied.")) return FALSE /obj/machinery/vending/exchange_parts(mob/user, obj/item/storage/part_replacer/W) @@ -642,7 +674,7 @@ GLOBAL_LIST_EMPTY(vending_products) else display_parts(user) if(moved) - to_chat(user, "[moved] items restocked.") + to_chat(user, span_notice("[moved] items restocked.")) W.play_rped_sound() return TRUE @@ -651,22 +683,22 @@ GLOBAL_LIST_EMPTY(vending_products) . = ..() /obj/machinery/vending/emag_act(mob/user) - . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED - to_chat(user, "You short out the product lock on [src].") - return TRUE + to_chat(user, span_notice("You short out the product lock on [src].")) /obj/machinery/vending/_try_interact(mob/user) if(seconds_electrified && !(stat & NOPOWER)) if(shock(user, 100)) return + if(tilted && !user.buckled && !isAI(user)) - to_chat(user, "You begin righting [src].") + to_chat(user, span_notice("You begin righting [src].")) if(do_after(user, 50, target=src)) untilt(user) return + return ..() /obj/machinery/vending/ui_assets(mob/user) @@ -736,7 +768,12 @@ GLOBAL_LIST_EMPTY(vending_products) .["user"]["department"] = "No Department" .["stock"] = list() for (var/datum/data/vending_product/R in product_records + coin_records + hidden_records) - .["stock"][R.name] = R.amount + var/list/product_data = list( + name = R.name, + amount = R.amount, + colorable = FALSE, // R.colorable, + ) + .["stock"][R.name] = product_data .["extended_inventory"] = extended_inventory /obj/machinery/vending/ui_act(action, params) @@ -745,92 +782,142 @@ GLOBAL_LIST_EMPTY(vending_products) return switch(action) if("vend") - . = TRUE - if(!vend_ready) - return - if(panel_open) - to_chat(usr, "The vending machine cannot dispense products while its service panel is open!") - return - vend_ready = FALSE //One thing at a time!! - var/datum/data/vending_product/R = locate(params["ref"]) - var/list/record_to_check = product_records + coin_records - if(extended_inventory) - record_to_check = product_records + coin_records + hidden_records - if(!R || !istype(R) || !R.product_path) - vend_ready = TRUE - return - var/price_to_use = default_price - if(R.custom_price) - price_to_use = R.custom_price - if(R in hidden_records) - if(!extended_inventory) - vend_ready = TRUE - return - else if (!(R in record_to_check)) - vend_ready = TRUE - message_admins("Vending machine exploit attempted by [ADMIN_LOOKUPFLW(usr)]!") - return - if (R.amount <= 0) - say("Sold out of [R.name].") - flick(icon_deny,src) - vend_ready = TRUE - return - if(onstation && ishuman(usr)) - var/mob/living/carbon/human/H = usr - var/obj/item/card/id/C = H.get_idcard(TRUE) + . = vend(params) + // if("select_colors") + // . = select_colors(params) - if(!C) - say("No card found.") - flick(icon_deny,src) - vend_ready = TRUE - return - else if (!C.registered_account) - say("No account found.") - flick(icon_deny,src) - vend_ready = TRUE - return - // else if(age_restrictions && R.age_restricted && (!C.registered_age || C.registered_age < AGE_MINOR)) - // say("You are not of legal age to purchase [R.name].") - // if(!(usr in GLOB.narcd_underages)) - // Radio.set_frequency(FREQ_SECURITY) - // Radio.talk_into(src, "SECURITY ALERT: Underaged crewmember [H] recorded attempting to purchase [R.name] in [get_area(src)]. Please watch for substance abuse.", FREQ_SECURITY) - // GLOB.narcd_underages += H - // flick(icon_deny,src) - // vend_ready = TRUE - // return - var/datum/bank_account/account = C.registered_account - if(account.account_job && account.account_job.paycheck_department == payment_department) - price_to_use = 0 - if(coin_records.Find(R) || hidden_records.Find(R)) - price_to_use = R.custom_premium_price ? R.custom_premium_price : extra_price - if(price_to_use && !account.adjust_money(-price_to_use)) - say("You do not possess the funds to purchase [R.name].") - flick(icon_deny,src) - vend_ready = TRUE - return - var/datum/bank_account/D = SSeconomy.get_dep_account(payment_department) - if(D) - D.adjust_money(price_to_use) - SSblackbox.record_feedback("amount", "vending_spent", price_to_use) - //log_econ("[price_to_use] credits were inserted into [src] by [D.account_holder] to buy [R].") - if(last_shopper != usr || purchase_message_cooldown < world.time) - say("Thank you for shopping with [src]!") - purchase_message_cooldown = world.time + 5 SECONDS - last_shopper = usr - use_power(5) - if(icon_vend) //Show the vending animation if needed - flick(icon_vend,src) - playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3) - var/obj/item/vended = new R.product_path(get_turf(src)) - R.amount-- - if(usr.CanReach(src) && usr.put_in_hands(vended)) - to_chat(usr, "You take [R.name] out of the slot.") - else - to_chat(usr, "[capitalize(R.name)] falls onto the floor!") - SSblackbox.record_feedback("nested tally", "vending_machine_usage", 1, list("[type]", "[R.product_path]")) +/obj/machinery/vending/proc/can_vend(user, silent=FALSE) + . = FALSE + if(!vend_ready) + return + if(panel_open) + to_chat(user, span_warning("The vending machine cannot dispense products while its service panel is open!")) + return + return TRUE + +// /obj/machinery/vending/proc/select_colors(list/params) +// . = TRUE +// if(!can_vend(usr)) +// return +// var/datum/data/vending_product/product = locate(params["ref"]) +// var/atom/fake_atom = product.product_path + +// var/list/allowed_configs = list() +// var/config = initial(fake_atom.greyscale_config) +// if(!config) +// return +// allowed_configs += "[config]" +// if(ispath(fake_atom, /obj/item)) +// var/obj/item/item = fake_atom +// if(initial(item.greyscale_config_worn)) +// allowed_configs += "[initial(item.greyscale_config_worn)]" +// if(initial(item.greyscale_config_inhand_left)) +// allowed_configs += "[initial(item.greyscale_config_inhand_left)]" +// if(initial(item.greyscale_config_inhand_right)) +// allowed_configs += "[initial(item.greyscale_config_inhand_right)]" + +// var/datum/greyscale_modify_menu/menu = new( +// src, usr, allowed_configs, CALLBACK(src, .proc/vend_greyscale, params), +// starting_icon_state=initial(fake_atom.icon_state), +// starting_config=initial(fake_atom.greyscale_config), +// starting_colors=initial(fake_atom.greyscale_colors) +// ) +// menu.ui_interact(usr) + +// /obj/machinery/vending/proc/vend_greyscale(list/params, datum/greyscale_modify_menu/menu) +// if(usr != menu.user) +// return +// if(!menu.target.can_interact(usr)) +// return +// vend(params, menu.split_colors) + +/obj/machinery/vending/proc/vend(list/params, list/greyscale_colors) + . = TRUE + if(!can_vend(usr)) + return + vend_ready = FALSE //One thing at a time!! + var/datum/data/vending_product/R = locate(params["ref"]) + var/list/record_to_check = product_records + coin_records + if(extended_inventory) + record_to_check = product_records + coin_records + hidden_records + if(!R || !istype(R) || !R.product_path) + vend_ready = TRUE + return + var/price_to_use = default_price + if(R.custom_price) + price_to_use = R.custom_price + if(R in hidden_records) + if(!extended_inventory) vend_ready = TRUE + return + else if (!(R in record_to_check)) + vend_ready = TRUE + message_admins("Vending machine exploit attempted by [ADMIN_LOOKUPFLW(usr)]!") + return + if (R.amount <= 0) + say("Sold out of [R.name].") + flick(icon_deny,src) + vend_ready = TRUE + return + if(onstation) + var/obj/item/card/id/C + if(isliving(usr)) + var/mob/living/L = usr + C = L.get_idcard(TRUE) + if(!can_transact(C)) + flick(icon_deny,src) + vend_ready = TRUE + return + // else if(age_restrictions && R.age_restricted && (!C.registered_age || C.registered_age < AGE_MINOR)) + // say("You are not of legal age to purchase [R.name].") + // if(!(usr in GLOB.narcd_underages)) + // Radio.set_frequency(FREQ_SECURITY) + // Radio.talk_into(src, "SECURITY ALERT: Underaged crewmember [usr] recorded attempting to purchase [R.name] in [get_area(src)]. Please watch for substance abuse.", FREQ_SECURITY) + // GLOB.narcd_underages += usr + // flick(icon_deny,src) + // vend_ready = TRUE + // return + var/datum/bank_account/account = C.registered_account -/obj/machinery/vending/process() + var/discounts = FALSE + try // too lazy, and i do NOT want to use for() to check, as & is faster + discounts = !!(cost_multiplier_per_dept.len > 0 && (cost_multiplier_per_dept & account.account_job.access) > 0) + catch + // L + discounts = FALSE + + if(account.account_job && account.account_job.paycheck_department == payment_department || discounts) + price_to_use = 0 // it's free shut up + if(coin_records.Find(R) || hidden_records.Find(R)) + price_to_use = R.custom_premium_price ? R.custom_premium_price : extra_price + if(price_to_use && !attempt_transact(C, price_to_use)) + say("You do not possess the funds to purchase [R.name].") + flick(icon_deny,src) + vend_ready = TRUE + return + SSblackbox.record_feedback("amount", "vending_spent", price_to_use) + log_econ("[price_to_use] credits were inserted into [src] by [key_name(usr)] (account: [account.account_holder]) to buy [R].") + if(last_shopper != REF(usr) || purchase_message_cooldown < world.time) + say("Thank you for shopping with [src]!") + purchase_message_cooldown = world.time + 5 SECONDS + //This is not the best practice, but it's safe enough here since the chances of two people using a machine with the same ref in 5 seconds is fuck low + last_shopper = REF(usr) + use_power(5) + if(icon_vend) //Show the vending animation if needed + flick(icon_vend,src) + playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3) + var/obj/item/vended_item = new R.product_path(get_turf(src)) + // if(greyscale_colors) + // vended_item.set_greyscale(colors=greyscale_colors) + R.amount-- + if(usr.CanReach(src) && usr.put_in_hands(vended_item)) + to_chat(usr, span_notice("You take [R.name] out of the slot.")) + else + to_chat(usr, span_warning("[capitalize(R.name)] falls onto the floor!")) + SSblackbox.record_feedback("nested tally", "vending_machine_usage", 1, list("[type]", "[R.product_path]")) + vend_ready = TRUE + +/obj/machinery/vending/process(delta_time) if(stat & (BROKEN|NOPOWER)) return PROCESS_KILL if(!active) @@ -840,21 +927,21 @@ GLOBAL_LIST_EMPTY(vending_products) seconds_electrified-- //Pitch to the people! Really sell it! - if(last_slogan + slogan_delay <= world.time && slogan_list.len > 0 && !shut_up && prob(5)) + if(last_slogan + slogan_delay <= world.time && slogan_list.len > 0 && !shut_up && DT_PROB(2.5, delta_time)) var/slogan = pick(slogan_list) speak(slogan) last_slogan = world.time - if(shoot_inventory && prob(shoot_inventory_chance)) + if(shoot_inventory && DT_PROB(shoot_inventory_chance, delta_time)) throw_item() /** - * Speak the given message verbally - * - * Checks if the machine is powered and the message exists - * - * Arguments: - * * message - the message to speak - */ + * Speak the given message verbally + * + * Checks if the machine is powered and the message exists + * + * Arguments: + * * message - the message to speak + */ /obj/machinery/vending/proc/speak(message) if(stat & (BROKEN|NOPOWER)) return @@ -863,25 +950,6 @@ GLOBAL_LIST_EMPTY(vending_products) say(message) -/** - * Gets the best discount from a given ID card, comparing its access and paycheck depart with cost_multiplier_per_dept. - * It only applies to the regular selection, not premium or contraband. And a bank account is still required. - * But it can also be used to charge more to certain departments or accesses. :) - * - * Arguments: - * * list/dept_access_list - the list to compare - */ -/obj/machinery/vending/proc/get_best_discount(obj/item/card/id/C) - var/list/discounts = NUMLIST2TEXTLIST(C.GetAccess()) - if(C.registered_account?.account_job) - discounts += C.registered_account.account_job.paycheck_department - discounts &= cost_multiplier_per_dept - if(!length(discounts)) - return 1 - . = INFINITY - for(var/k in discounts) - . = min(cost_multiplier_per_dept[k], .) - /obj/machinery/vending/power_change() . = ..() if(powered()) @@ -889,22 +957,24 @@ GLOBAL_LIST_EMPTY(vending_products) //Somebody cut an important wire and now we're following a new definition of "pitch." /** - * Throw an item from our internal inventory out in front of us - * - * This is called when we are hacked, it selects a random product from the records that has an amount > 0 - * This item is then created and tossed out in front of us with a visible message - */ + * Throw an item from our internal inventory out in front of us + * + * This is called when we are hacked, it selects a random product from the records that has an amount > 0 + * This item is then created and tossed out in front of us with a visible message + */ /obj/machinery/vending/proc/throw_item() var/obj/throw_item = null - var/mob/living/target = locate() in view(7, src) + var/mob/living/target = locate() in view(7,src) if(!target) return FALSE + for(var/datum/data/vending_product/R in shuffle(product_records)) if(R.amount <= 0) //Try to use a record that actually has something to dump. continue var/dump_path = R.product_path if(!dump_path) continue + R.amount-- throw_item = new dump_path(loc) break @@ -914,30 +984,30 @@ GLOBAL_LIST_EMPTY(vending_products) pre_throw(throw_item) throw_item.throw_at(target, 16, 3) - visible_message("[src] launches [throw_item] at [target]!") + visible_message(span_danger("[src] launches [throw_item] at [target]!")) return TRUE /** - * A callback called before an item is tossed out - * - * Override this if you need to do any special case handling - * - * Arguments: - * * I - obj/item being thrown - */ + * A callback called before an item is tossed out + * + * Override this if you need to do any special case handling + * + * Arguments: + * * I - obj/item being thrown + */ /obj/machinery/vending/proc/pre_throw(obj/item/I) return /** - * Shock the passed in user - * - * This checks we have power and that the passed in prob is passed, then generates some sparks - * and calls electrocute_mob on the user - * - * Arguments: - * * user - the user to shock - * * prb - probability the shock happens - */ + * Shock the passed in user + * + * This checks we have power and that the passed in prob is passed, then generates some sparks + * and calls electrocute_mob on the user + * + * Arguments: + * * user - the user to shock + * * prb - probability the shock happens + */ /obj/machinery/vending/proc/shock(mob/living/user, prb) - if(!istype(user) || stat & (BROKEN|NOPOWER)) // unpowered, no shock + if(!istype(user) || stat & (BROKEN|NOPOWER)) // unpowered, no shock return FALSE if(!prob(prb)) return FALSE @@ -948,24 +1018,39 @@ GLOBAL_LIST_EMPTY(vending_products) else return FALSE /** - * Are we able to load the item passed in - * - * Arguments: - * * I - the item being loaded - * * user - the user doing the loading - */ + * Are we able to load the item passed in + * + * Arguments: + * * I - the item being loaded + * * user - the user doing the loading + */ /obj/machinery/vending/proc/canLoadItem(obj/item/I, mob/user) return FALSE -/obj/machinery/vending/onTransitZ() - return +/obj/machinery/vending/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) + . = ..() + var/mob/living/L = AM + if(tilted || !istype(L) || !prob(20 * (throwingdatum.speed - L.throw_speed))) // hulk throw = +20%, neckgrab throw = +20% + return + + tilt(L) + +/obj/machinery/vending/attack_tk_grab(mob/user) + to_chat(user, span_warning("[src] seems to resist your mental grasp!")) + +///Crush the mob that the vending machine got thrown at +/obj/machinery/vending/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + if(isliving(hit_atom)) + tilt(fatty=hit_atom) + return ..() /obj/machinery/vending/custom name = "Custom Vendor" - icon_state = "robotics" - icon_deny = "robotics-deny" + icon_state = "custom" + icon_deny = "custom-deny" max_integrity = 400 payment_department = NO_FREEBIES + light_mask = "custom-light-mask" refill_canister = /obj/item/vending_refill/custom /// where the money is sent var/datum/bank_account/private_a @@ -976,21 +1061,23 @@ GLOBAL_LIST_EMPTY(vending_products) /obj/machinery/vending/custom/compartmentLoadAccessCheck(mob/user) . = FALSE - var/mob/living/carbon/human/H - var/obj/item/card/id/C - if(ishuman(user)) - H = user - C = H.get_idcard(FALSE) - if(C?.registered_account && C.registered_account == private_a) - return TRUE + if(!isliving(user)) + return FALSE + var/mob/living/L = user + var/obj/item/card/id/C = L.get_idcard(FALSE) + if(C?.registered_account && C.registered_account == private_a) + return TRUE /obj/machinery/vending/custom/canLoadItem(obj/item/I, mob/user) . = FALSE + if(I.flags_1 & HOLOGRAM_1) + say("This vendor cannot accept nonexistent items.") + return if(loaded_items >= max_loaded_items) say("There are too many items in stock.") return if(istype(I, /obj/item/stack)) - say("Loose items may cause problems, try use it inside wrapping paper.") + say("Loose items may cause problems, try to use it inside wrapping paper.") return if(I.custom_price) return TRUE @@ -1004,19 +1091,21 @@ GLOBAL_LIST_EMPTY(vending_products) var/base64 var/price = 0 for(var/obj/T in contents) - if(T.name == O) + if(format_text(T.name) == O) price = T.custom_price if(!base64) if(base64_cache[T.type]) base64 = base64_cache[T.type] else - base64 = icon2base64(icon(T.icon, T.icon_state)) + base64 = icon2base64(getFlatIcon(T, no_anim=TRUE)) base64_cache[T.type] = base64 break var/list/data = list( name = O, price = price, - img = base64 + img = base64, + amount = vending_machine_input[O], + colorable = FALSE ) .["vending_machine_input"] += list(data) @@ -1032,64 +1121,63 @@ GLOBAL_LIST_EMPTY(vending_products) var/N = params["item"] var/obj/S vend_ready = FALSE - if(ishuman(usr)) - var/mob/living/carbon/human/H = usr - var/obj/item/card/id/C = H.get_idcard(TRUE) - - if(!C) - say("No card found.") - flick(icon_deny,src) + var/obj/item/card/id/C + if(isliving(usr)) + var/mob/living/L = usr + C = L.get_idcard(TRUE) + if(!C) + say("No card found.") + flick(icon_deny,src) + vend_ready = TRUE + return + else if (!C.registered_account) + say("No account found.") + flick(icon_deny,src) + vend_ready = TRUE + return + var/datum/bank_account/account = C.registered_account + for(var/obj/O in contents) + if(format_text(O.name) == N) + S = O + break + if(S) + if(compartmentLoadAccessCheck(usr)) + vending_machine_input[N] = max(vending_machine_input[N] - 1, 0) + S.forceMove(drop_location()) + loaded_items-- + use_power(5) vend_ready = TRUE + updateUsrDialog() return - else if (!C.registered_account) - say("No account found.") - flick(icon_deny,src) + if(account.has_money(S.custom_price)) + account.adjust_money(-S.custom_price) + var/datum/bank_account/owner = private_a + if(owner) + owner.adjust_money(S.custom_price) + SSblackbox.record_feedback("amount", "vending_spent", S.custom_price) + log_econ("[S.custom_price] credits were spent on [src] buying a [S] by [key_name(usr)] (account: [owner.account_holder]), owned by [private_a.account_holder].") + vending_machine_input[N] = max(vending_machine_input[N] - 1, 0) + S.forceMove(drop_location()) + loaded_items-- + use_power(5) + if(last_shopper != REF(usr) || purchase_message_cooldown < world.time) + say("Thank you for buying local and purchasing [S]!") + purchase_message_cooldown = world.time + 5 SECONDS + last_shopper = REF(usr) vend_ready = TRUE + updateUsrDialog() return - var/datum/bank_account/account = C.registered_account - for(var/obj/O in contents) - if(O.name == N) - S = O - break - if(S) - if(compartmentLoadAccessCheck(usr)) - vending_machine_input[N] = max(vending_machine_input[N] - 1, 0) - S.forceMove(drop_location()) - loaded_items-- - use_power(5) - vend_ready = TRUE - updateUsrDialog() - return - if(account.has_money(S.custom_price)) - account.adjust_money(-S.custom_price) - var/datum/bank_account/owner = private_a - if(owner) - owner.adjust_money(S.custom_price) - vending_machine_input[N] = max(vending_machine_input[N] - 1, 0) - S.forceMove(drop_location()) - loaded_items-- - use_power(5) - if(last_shopper != usr || purchase_message_cooldown < world.time) - say("Thank you for buying local and purchasing [S]!") - purchase_message_cooldown = world.time + 5 SECONDS - last_shopper = usr - vend_ready = TRUE - updateUsrDialog() - return - else - say("You do not possess the funds to purchase this.") + else + say("You do not possess the funds to purchase this.") vend_ready = TRUE /obj/machinery/vending/custom/attackby(obj/item/I, mob/user, params) - if(!private_a) - var/mob/living/carbon/human/H - var/obj/item/card/id/C - if(ishuman(user)) - H = user - C = H.get_idcard(TRUE) - if(C?.registered_account) - private_a = C.registered_account - say("[src] has been linked to [C].") + if(!private_a && isliving(user)) + var/mob/living/L = user + var/obj/item/card/id/C = L.get_idcard(TRUE) + if(C?.registered_account) + private_a = C.registered_account + say("\The [src] has been linked to [C].") if(compartmentLoadAccessCheck(user)) if(istype(I, /obj/item/pen)) @@ -1099,15 +1187,6 @@ GLOBAL_LIST_EMPTY(vending_products) last_slogan = world.time + rand(0, slogan_delay) return - if(canLoadItem(I)) - loadingAttempt(I,user) - updateUsrDialog() - return - - if(panel_open && is_wire_tool(I)) - wires.interact(user) - return - return ..() /obj/machinery/vending/custom/crowbar_act(mob/living/user, obj/item/I) @@ -1119,7 +1198,7 @@ GLOBAL_LIST_EMPTY(vending_products) if(T) for(var/obj/item/I in contents) I.forceMove(T) - explosion(T, -1, 0, 3) + explosion(src, devastation_range = -1, light_impact_range = 3) return ..() /obj/machinery/vending/custom/unbreakable @@ -1142,7 +1221,7 @@ GLOBAL_LIST_EMPTY(vending_products) /obj/item/price_tagger/attack_self(mob/user) price = max(1, round(input(user,"set price","price") as num|null, 1)) - to_chat(user, " The [src] will now give things a [price] cr tag.") + to_chat(user, span_notice(" The [src] will now give things a [price] cr tag.")) /obj/item/price_tagger/afterattack(atom/target, mob/user, proximity) . = ..() @@ -1151,4 +1230,23 @@ GLOBAL_LIST_EMPTY(vending_products) if(isitem(target)) var/obj/item/I = target I.custom_price = price - to_chat(user, "You set the price of [I] to [price] cr.") + to_chat(user, span_notice("You set the price of [I] to [price] cr.")) + +/obj/machinery/vending/custom/greed //name and like decided by the spawn + icon_state = "greed" + icon_deny = "greed-deny" + light_mask = "greed-light-mask" + custom_materials = list(/datum/material/gold = MINERAL_MATERIAL_AMOUNT * 5) + +/obj/machinery/vending/custom/greed/Initialize(mapload) + . = ..() + //starts in a state where you can move it + panel_open = TRUE + set_anchored(FALSE) + add_overlay("[initial(icon_state)]-panel") + //and references the deity + name = "[GLOB.deity]'s Consecrated Vendor" + desc = "A vending machine created by [GLOB.deity]." + slogan_list = list("[GLOB.deity] says: It's your divine right to buy!") + add_filter("vending_outline", 9, list("type" = "outline", "color" = COLOR_VERY_SOFT_YELLOW)) + add_filter("vending_rays", 10, list("type" = "rays", "size" = 35, "color" = COLOR_VIVID_YELLOW)) diff --git a/code/modules/vending/assist.dm b/code/modules/vending/assist.dm index 29d1e760d4..9ab384111b 100644 --- a/code/modules/vending/assist.dm +++ b/code/modules/vending/assist.dm @@ -1,4 +1,9 @@ /obj/machinery/vending/assist + name = "\improper Part-Mart" + desc = "All the finest of miscellaneous electronics one could ever need! Not responsible for any injuries caused by reckless misuse of parts." + // icon_state = "parts" + // icon_deny = "parts-deny" + products = list(/obj/item/assembly/prox_sensor = 7, /obj/item/assembly/igniter = 6, /obj/item/assembly/playback = 4, @@ -15,13 +20,13 @@ premium = list(/obj/item/stock_parts/cell/upgraded/plus = 2, /obj/item/flashlight/lantern = 2, /obj/item/beacon = 2) - product_ads = "Only the finest!;Have some tools.;The most robust equipment.;The finest gear in space!" - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) refill_canister = /obj/item/vending_refill/assist - resistance_flags = FIRE_PROOF + product_ads = "Only the finest!;Have some tools.;The most robust equipment.;The finest gear in space!" default_price = PRICE_REALLY_CHEAP extra_price = PRICE_ALMOST_CHEAP payment_department = NO_FREEBIES + // light_mask = "parts-light-mask" /obj/item/vending_refill/assist - icon_state = "refill_engi" + machine_name = "Part-Mart" + icon_state = "refill_parts" diff --git a/code/modules/vending/autodrobe.dm b/code/modules/vending/autodrobe.dm index 264d262a1d..5a6c7c973f 100644 --- a/code/modules/vending/autodrobe.dm +++ b/code/modules/vending/autodrobe.dm @@ -3,32 +3,39 @@ desc = "A vending machine for costumes." icon_state = "theater" icon_deny = "theater-deny" + req_access = list(ACCESS_THEATRE) product_slogans = "Dress for success!;Suited and booted!;It's show time!;Why leave style up to fate? Use AutoDrobe!" vend_reply = "Thank you for using AutoDrobe!" products = list(/obj/item/clothing/suit/chickensuit = 1, - /obj/item/clothing/head/chicken = 1, - /obj/item/clothing/under/costume/gladiator = 1, - /obj/item/clothing/head/helmet/gladiator = 1, - /obj/item/clothing/under/rank/captain/suit = 1, - /obj/item/clothing/head/flatcap = 1, - /obj/item/clothing/suit/toggle/labcoat/mad = 1, - /obj/item/clothing/shoes/jackboots = 1, - /obj/item/clothing/under/costume/schoolgirl = 1, - /obj/item/clothing/under/costume/schoolgirl/red = 1, - /obj/item/clothing/under/costume/schoolgirl/green = 1, - /obj/item/clothing/under/costume/schoolgirl/orange = 1, - /obj/item/clothing/head/kitty = 1, - /obj/item/clothing/under/dress/skirt = 1, - /obj/item/clothing/head/beret = 1, - /obj/item/clothing/accessory/waistcoat = 1, - /obj/item/clothing/under/suit/black = 1, - /obj/item/clothing/head/that = 1, - /obj/item/clothing/under/costume/kilt = 1, - /obj/item/clothing/head/beret = 1, - /obj/item/clothing/accessory/waistcoat = 1, - /obj/item/clothing/glasses/monocle =1, - /obj/item/clothing/head/bowler = 1, - /obj/item/cane = 1, + /obj/item/clothing/head/chicken = 1, + /obj/item/clothing/under/rank/civilian/clown/blue = 1, + /obj/item/clothing/under/rank/civilian/clown/green = 1, + /obj/item/clothing/under/rank/civilian/clown/yellow = 1, + /obj/item/clothing/under/rank/civilian/clown/orange = 1, + /obj/item/clothing/under/rank/civilian/clown/purple = 1, + /obj/item/clothing/under/costume/gladiator = 1, + /obj/item/clothing/head/helmet/gladiator = 1, + /obj/item/clothing/under/rank/captain/suit = 1, + /obj/item/clothing/under/rank/captain/suit/skirt = 1, + /obj/item/clothing/head/flatcap = 1, + /obj/item/clothing/suit/toggle/labcoat/mad = 1, + /obj/item/clothing/shoes/jackboots = 1, + /obj/item/clothing/under/costume/schoolgirl = 1, + /obj/item/clothing/under/costume/schoolgirl/red = 1, + /obj/item/clothing/under/costume/schoolgirl/green = 1, + /obj/item/clothing/under/costume/schoolgirl/orange = 1, + /obj/item/clothing/head/kitty = 1, + /obj/item/clothing/under/dress/skirt = 1, + /obj/item/clothing/head/beret = 1, + /obj/item/clothing/accessory/waistcoat = 1, + /obj/item/clothing/under/suit/black = 1, + /obj/item/clothing/head/that = 1, + /obj/item/clothing/under/costume/kilt = 1, + /obj/item/clothing/head/beret = 3, + /obj/item/clothing/accessory/waistcoat = 1, + /obj/item/clothing/glasses/monocle =1, + /obj/item/clothing/head/bowler = 1, + /obj/item/cane = 1, /obj/item/clothing/under/rank/civilian/victorian_redsleeves = 1, /obj/item/clothing/under/rank/civilian/victorian_redvest = 1, /obj/item/clothing/under/rank/civilian/victorian_vest = 1, @@ -39,110 +46,111 @@ /obj/item/clothing/under/rank/civilian/victorianblackdress = 1, /obj/item/clothing/suit/vickyblack =1, /obj/item/clothing/under/rank/civilian/dutch = 2, - /obj/item/clothing/under/suit/sl = 1, - /obj/item/clothing/mask/fakemoustache = 1, - /obj/item/clothing/suit/bio_suit/plaguedoctorsuit = 1, - /obj/item/clothing/head/plaguedoctorhat = 1, - /obj/item/clothing/mask/gas/plaguedoctor = 1, - /obj/item/clothing/suit/toggle/owlwings = 1, - /obj/item/clothing/under/costume/owl = 1, - /obj/item/clothing/mask/gas/owl_mask = 1, - /obj/item/clothing/suit/toggle/owlwings/griffinwings = 1, - /obj/item/clothing/under/costume/griffin = 1, - /obj/item/clothing/shoes/griffin = 1, - /obj/item/clothing/head/griffin = 1, - /obj/item/clothing/suit/apron = 1, - /obj/item/clothing/under/suit/waiter = 1, - /obj/item/clothing/suit/jacket/miljacket = 1, - /obj/item/clothing/under/costume/pirate = 1, - /obj/item/clothing/suit/pirate = 1, - /obj/item/clothing/head/pirate = 1, - /obj/item/clothing/head/bandana = 1, - /obj/item/clothing/head/bandana = 1, - /obj/item/clothing/under/costume/soviet = 1, - /obj/item/clothing/head/ushanka = 1, - /obj/item/clothing/suit/imperium_monk = 1, - /obj/item/clothing/mask/gas/cyborg = 1, - /obj/item/clothing/suit/chaplain/holidaypriest = 1, - /obj/item/clothing/head/wizard/marisa/fake = 1, - /obj/item/clothing/suit/wizrobe/marisa/fake = 1, - /obj/item/clothing/under/dress/sundress = 1, - /obj/item/clothing/head/witchwig = 1, - /obj/item/staff/broom = 1, - /obj/item/clothing/suit/wizrobe/fake = 1, - /obj/item/clothing/head/wizard/fake = 1, - /obj/item/staff = 3, - /obj/item/clothing/under/rank/civilian/mime/skirt = 1, - /obj/item/clothing/under/rank/captain/suit/skirt = 1, + /obj/item/clothing/under/suit/sl = 1, + /obj/item/clothing/mask/fakemoustache = 1, + /obj/item/clothing/suit/bio_suit/plaguedoctorsuit = 1, + /obj/item/clothing/head/plaguedoctorhat = 1, + /obj/item/clothing/mask/gas/plaguedoctor = 1, + /obj/item/clothing/suit/toggle/owlwings = 1, + /obj/item/clothing/under/costume/owl = 1, + /obj/item/clothing/mask/gas/owl_mask = 1, + /obj/item/clothing/suit/toggle/owlwings/griffinwings = 1, + /obj/item/clothing/under/costume/griffin = 1, + /obj/item/clothing/shoes/griffin = 1, + /obj/item/clothing/head/griffin = 1, + /obj/item/clothing/suit/apron = 1, + /obj/item/clothing/under/suit/waiter = 1, + /obj/item/clothing/suit/jacket/miljacket = 1, + /obj/item/clothing/under/costume/pirate = 1, + /obj/item/clothing/suit/pirate = 1, + /obj/item/clothing/head/pirate = 1, + /obj/item/clothing/head/bandana = 1, + /obj/item/clothing/head/bandana = 1, + /obj/item/clothing/under/costume/soviet = 1, + /obj/item/clothing/head/ushanka = 1, + /obj/item/clothing/suit/imperium_monk = 1, + /obj/item/clothing/mask/gas/cyborg = 1, + /obj/item/clothing/suit/chaplain/holidaypriest = 1, + /obj/item/clothing/head/wizard/marisa/fake = 1, + /obj/item/clothing/suit/wizrobe/marisa/fake = 1, + /obj/item/clothing/under/dress/sundress = 1, + /obj/item/clothing/head/witchwig = 1, + /obj/item/staff/broom = 1, + /obj/item/clothing/suit/wizrobe/fake = 1, + /obj/item/clothing/head/wizard/fake = 1, + /obj/item/staff = 3, /obj/item/clothing/mask/gas/clown_hat/sexy = 1, - /obj/item/clothing/under/rank/civilian/clown/sexy = 1, + /obj/item/clothing/under/rank/civilian/clown/sexy = 1, /obj/item/clothing/mask/gas/mime/sexy = 1, - /obj/item/clothing/under/rank/civilian/mime/sexy = 1, - /obj/item/clothing/mask/rat/bat = 1, - /obj/item/clothing/mask/rat/bee = 1, - /obj/item/clothing/mask/rat/bear = 1, - /obj/item/clothing/mask/rat/raven = 1, - /obj/item/clothing/mask/rat/jackal = 1, - /obj/item/clothing/mask/rat/fox = 1, - /obj/item/clothing/mask/frog = 1, - /obj/item/clothing/mask/rat/tribal = 1, - /obj/item/clothing/mask/rat = 1, - /obj/item/clothing/suit/apron/overalls = 1, - /obj/item/clothing/head/rabbitears =1, - /obj/item/clothing/head/sombrero = 1, - /obj/item/clothing/head/sombrero/green = 1, - /obj/item/clothing/suit/poncho = 1, - /obj/item/clothing/suit/poncho/green = 1, - /obj/item/clothing/suit/poncho/red = 1, - /obj/item/clothing/head/maid = 1, - /obj/item/clothing/under/costume/maid = 1, - /obj/item/clothing/under/rank/civilian/janitor/maid = 1, + /obj/item/clothing/under/rank/civilian/mime/sexy = 1, + /obj/item/clothing/under/rank/civilian/mime/skirt = 1, + /obj/item/clothing/mask/rat/bat = 1, + /obj/item/clothing/mask/rat/bee = 1, + /obj/item/clothing/mask/rat/bear = 1, + /obj/item/clothing/mask/rat/raven = 1, + /obj/item/clothing/mask/rat/jackal = 1, + /obj/item/clothing/mask/rat/fox = 1, + /obj/item/clothing/mask/frog = 1, + /obj/item/clothing/mask/rat/tribal = 1, + /obj/item/clothing/mask/rat = 1, + /obj/item/clothing/suit/apron/overalls = 1, + /obj/item/clothing/head/rabbitears =1, + /obj/item/clothing/head/sombrero = 1, + /obj/item/clothing/head/sombrero/green = 1, + /obj/item/clothing/suit/poncho = 1, + /obj/item/clothing/suit/poncho/green = 1, + /obj/item/clothing/suit/poncho/red = 1, + /obj/item/clothing/head/maid = 1, + /obj/item/clothing/under/costume/maid = 1, + /obj/item/clothing/under/rank/civilian/janitor/maid = 1, /obj/item/clothing/gloves/evening = 1, - /obj/item/clothing/glasses/cold=1, - /obj/item/clothing/glasses/heat=1, - /obj/item/clothing/suit/whitedress = 1, - /obj/item/clothing/under/rank/civilian/clown/jester = 1, - /obj/item/clothing/head/jester = 1, - /obj/item/clothing/under/costume/villain = 1, - /obj/item/clothing/shoes/singery = 1, - /obj/item/clothing/under/costume/singer/yellow = 1, - /obj/item/clothing/shoes/singerb = 1, - /obj/item/clothing/under/costume/singer/blue = 1, - /obj/item/clothing/suit/hooded/carp_costume = 1, - /obj/item/clothing/suit/hooded/ian_costume = 1, - /obj/item/clothing/suit/hooded/bee_costume = 1, - /obj/item/clothing/suit/snowman = 1, - /obj/item/clothing/head/snowman = 1, - /obj/item/clothing/mask/joy = 1, - /obj/item/clothing/head/cueball = 1, - /obj/item/clothing/under/suit/white_on_white = 1, - /obj/item/clothing/under/costume/sailor = 1, - /obj/item/clothing/ears/headphones = 2, - /obj/item/clothing/head/wig/random = 3, - /obj/item/clothing/suit/ran = 2, - /obj/item/clothing/head/ran = 2, - /obj/item/clothing/mask/gas/timidcostume = 3, - /obj/item/clothing/suit/hooded/wintercoat/timidcostume = 3, - /obj/item/clothing/shoes/timidcostume = 3, - /obj/item/clothing/mask/gas/timidcostume/man = 3, - /obj/item/clothing/suit/hooded/wintercoat/timidcostume/man = 3, - /obj/item/clothing/shoes/timidcostume/man = 3, - ) + /obj/item/clothing/glasses/cold=1, + /obj/item/clothing/glasses/heat=1, + /obj/item/clothing/suit/whitedress = 1, + /obj/item/clothing/under/rank/civilian/clown/jester = 1, + /obj/item/clothing/head/jester = 1, + /obj/item/clothing/under/costume/villain = 1, + /obj/item/clothing/shoes/singery = 1, + /obj/item/clothing/under/costume/singer/yellow = 1, + /obj/item/clothing/shoes/singerb = 1, + /obj/item/clothing/under/costume/singer/blue = 1, + /obj/item/clothing/suit/hooded/carp_costume = 1, + /obj/item/clothing/suit/hooded/ian_costume = 1, + /obj/item/clothing/suit/hooded/bee_costume = 1, + /obj/item/clothing/suit/snowman = 1, + /obj/item/clothing/head/snowman = 1, + /obj/item/clothing/mask/joy = 1, + /obj/item/clothing/head/cueball = 1, + /obj/item/clothing/under/suit/white_on_white = 1, + /obj/item/clothing/under/costume/sailor = 1, + /obj/item/clothing/ears/headphones = 2, + /obj/item/clothing/head/wig/random = 3, + /obj/item/clothing/suit/ran = 2, + /obj/item/clothing/head/ran = 2, + /obj/item/clothing/mask/gas/timidcostume = 3, + /obj/item/clothing/suit/hooded/wintercoat/timidcostume = 3, + /obj/item/clothing/shoes/timidcostume = 3, + /obj/item/clothing/mask/gas/timidcostume/man = 3, + /obj/item/clothing/suit/hooded/wintercoat/timidcostume/man = 3, + /obj/item/clothing/shoes/timidcostume/man = 3, + ) contraband = list(/obj/item/clothing/suit/judgerobe = 1, - /obj/item/clothing/head/powdered_wig = 1, - /obj/item/gun/magic/wand = 2, - /obj/item/clothing/glasses/sunglasses/garb = 2, - /obj/item/clothing/glasses/sunglasses/blindfold = 1, - /obj/item/clothing/mask/muzzle = 2, - /obj/item/clothing/under/syndicate/camo/cosmetic = 3) + /obj/item/clothing/head/powdered_wig = 1, + /obj/item/gun/magic/wand = 2, + /obj/item/clothing/glasses/sunglasses/garb = 2, + /obj/item/clothing/glasses/sunglasses/blindfold = 1, + /obj/item/clothing/mask/muzzle = 2, + /obj/item/clothing/under/syndicate/camo/cosmetic = 3 + ) premium = list(/obj/item/clothing/suit/pirate/captain = 2, - /obj/item/clothing/head/pirate/captain = 2, - /obj/item/clothing/head/helmet/roman/fake = 1, - /obj/item/clothing/head/helmet/roman/legionnaire/fake = 1, - /obj/item/clothing/under/costume/roman = 1, - /obj/item/clothing/shoes/roman = 1, - /obj/item/shield/riot/roman/fake = 1, - /obj/item/skub = 1, + /obj/item/clothing/head/pirate/captain = 2, + /obj/item/clothing/under/rank/civilian/clown/rainbow = 1, + /obj/item/clothing/head/helmet/roman/fake = 1, + /obj/item/clothing/head/helmet/roman/legionnaire/fake = 1, + /obj/item/clothing/under/costume/roman = 1, + /obj/item/clothing/shoes/roman = 1, + /obj/item/shield/riot/roman/fake = 1, + /obj/item/skub = 1, /obj/item/clothing/under/costume/lobster = 1, /obj/item/clothing/head/lobsterhat = 1, /obj/item/clothing/head/drfreezehat = 1, @@ -157,19 +165,23 @@ /obj/item/clothing/head/christmashat = 3, /obj/item/clothing/head/christmashatg = 3, /obj/item/clothing/under/costume/drfreeze = 1) - refill_canister = /obj/item/vending_refill/autodrobe default_price = PRICE_ALMOST_CHEAP extra_price = PRICE_ALMOST_EXPENSIVE payment_department = ACCOUNT_SRV + light_mask="theater-light-mask" -/obj/machinery/vending/autodrobe/Initialize() +/obj/machinery/vending/autodrobe/Initialize(mapload) . = ..() cost_multiplier_per_dept = list("[ACCESS_THEATRE]" = 0) /obj/machinery/vending/autodrobe/canLoadItem(obj/item/I,mob/user) return (I.type in products) +/obj/machinery/vending/autodrobe/all_access + desc = "A vending machine for costumes. This model appears to have no access restrictions." + req_access = null + /obj/item/vending_refill/autodrobe machine_name = "AutoDrobe" icon_state = "refill_costume" diff --git a/code/modules/vending/boozeomat.dm b/code/modules/vending/boozeomat.dm index 87f2a0940b..c3e5f6ce0e 100644 --- a/code/modules/vending/boozeomat.dm +++ b/code/modules/vending/boozeomat.dm @@ -41,13 +41,15 @@ premium = list(/obj/item/reagent_containers/glass/bottle/ethanol = 4, /obj/item/reagent_containers/food/drinks/bottle/champagne = 5, /obj/item/reagent_containers/food/drinks/bottle/trappist = 5) + product_slogans = "I hope nobody asks me for a bloody cup o' tea...;Alcohol is humanity's friend. Would you abandon a friend?;Quite delighted to serve you!;Is nobody thirsty on this station?" product_ads = "Drink up!;Booze is good for you!;Alcohol is humanity's best friend.;Quite delighted to serve you!;Care for a nice, cold beer?;Nothing cures you like booze!;Have a sip!;Have a drink!;Have a beer!;Beer is good for you!;Only the finest alcohol!;Best quality booze since 2053!;Award-winning wine!;Maximum alcohol!;Man loves beer.;A toast for progress!" + refill_canister = /obj/item/vending_refill/boozeomat default_price = PRICE_ALMOST_CHEAP extra_price = PRICE_EXPENSIVE payment_department = ACCOUNT_SRV - cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) + light_mask = "boozeomat-light-mask" /obj/machinery/vending/boozeomat/pubby_maint //abandoned bar on Pubbystation products = list(/obj/item/reagent_containers/food/drinks/bottle/whiskey = 1, @@ -67,15 +69,17 @@ /obj/item/reagent_containers/food/drinks/drinkingglass = 6, /obj/item/reagent_containers/food/drinks/ice = 1, /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass = 4); + payment_department = ACCOUNT_SEC -/obj/machinery/vending/boozeomat/pubby_captain/Initialize() - . = ..() - cost_multiplier_per_dept = list("[ACCESS_CAPTAIN]" = 0) - +/obj/machinery/vending/boozeomat/all_access + desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one. This model appears to have no access restrictions." + req_access = null /obj/machinery/vending/boozeomat/syndicate_access + req_access = list(ACCESS_SYNDICATE) + age_restrictions = FALSE payment_department = NO_FREEBIES -/obj/machinery/vending/boozeomat/syndicate_access/Initialize() +/obj/machinery/vending/boozeomat/syndicate_access/Initialize(mapload) . = ..() cost_multiplier_per_dept = list("[ACCESS_SYNDICATE]" = 0) diff --git a/code/modules/vending/cartridge.dm b/code/modules/vending/cartridge.dm index 69635007c9..d80d8e958e 100644 --- a/code/modules/vending/cartridge.dm +++ b/code/modules/vending/cartridge.dm @@ -5,25 +5,43 @@ product_slogans = "Carts to go!" icon_state = "cart" icon_deny = "cart-deny" - products = list(/obj/item/cartridge/medical = 10, + products = list(/obj/item/pda/heads = 10, // PDA + // Normal staff cards + /obj/item/cartridge/medical = 10, /obj/item/cartridge/engineering = 10, /obj/item/cartridge/security = 10, /obj/item/cartridge/janitor = 10, /obj/item/cartridge/signal/toxins = 10, /obj/item/cartridge/roboticist = 10, - /obj/item/pda/heads = 10) - premium = list(/obj/item/cartridge/captain = 2, - /obj/item/cartridge/quartermaster = 2) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + /obj/item/cartridge/atmos = 10, + /obj/item/cartridge/chemistry = 10, + /obj/item/cartridge/detective = 10, + /obj/item/cartridge/lawyer = 10, + /obj/item/cartridge/curator = 10, + /obj/item/cartridge/bartender = 10, + + // Virus cards + /obj/item/cartridge/virus/clown = 3, + /obj/item/cartridge/virus/mime = 3, + + // Command staff cards + /obj/item/cartridge/captain = 3, + /obj/item/cartridge/quartermaster = 10, + /obj/item/cartridge/head = 10, + /obj/item/cartridge/hos = 10, + /obj/item/cartridge/ce = 10, + /obj/item/cartridge/cmo = 10, + /obj/item/cartridge/rd = 10) + + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) refill_canister = /obj/item/vending_refill/cart resistance_flags = FIRE_PROOF default_price = PRICE_ALMOST_EXPENSIVE extra_price = PRICE_ALMOST_ONE_GRAND payment_department = ACCOUNT_SRV - -/obj/machinery/vending/cart/Initialize() - . = ..() - cost_multiplier_per_dept = list("[ACCESS_CHANGE_IDS]" = 0) + light_mask="cart-light-mask" /obj/item/vending_refill/cart - icon_state = "refill_pda" + machine_name = "PTech" + icon_state = "refill_smoke" + diff --git a/code/modules/vending/cigarette.dm b/code/modules/vending/cigarette.dm index 0f26abde1d..e5655ac9e0 100644 --- a/code/modules/vending/cigarette.dm +++ b/code/modules/vending/cigarette.dm @@ -14,15 +14,18 @@ /obj/item/storage/fancy/rollingpapers = 5) contraband = list(/obj/item/lighter = 3, /obj/item/clothing/mask/vape = 5, - /obj/item/storage/fancy/cigarettes/cigpack_shadyjims = 1) + /obj/item/storage/fancy/cigarettes/cigpack_shadyjims = 1, + /obj/item/clothing/mask/cigarette/dart = 3) premium = list(/obj/item/storage/fancy/cigarettes/cigpack_robustgold = 3, - /obj/item/storage/fancy/cigarettes/cigars = 1, - /obj/item/storage/fancy/cigarettes/cigars/havana = 1, - /obj/item/storage/fancy/cigarettes/cigars/cohiba = 1) + /obj/item/lighter = 3, + /obj/item/storage/fancy/cigarettes/cigars = 1, + /obj/item/storage/fancy/cigarettes/cigars/havana = 1, + /obj/item/storage/fancy/cigarettes/cigars/cohiba = 1) refill_canister = /obj/item/vending_refill/cigarette default_price = PRICE_ALMOST_CHEAP extra_price = PRICE_ABOVE_NORMAL payment_department = ACCOUNT_SRV + light_mask = "cigs-light-mask" /obj/machinery/vending/cigarette/syndicate products = list(/obj/item/storage/fancy/cigarettes/cigpack_syndicate = 7, @@ -33,9 +36,8 @@ /obj/item/storage/box/matches = 10, /obj/item/lighter/greyscale = 4, /obj/item/storage/fancy/rollingpapers = 5) - payment_department = NO_FREEBIES -/obj/machinery/vending/cigarette/syndicate/Initialize() +/obj/machinery/vending/cigarette/syndicate/Initialize(mapload) . = ..() cost_multiplier_per_dept = list("[ACCESS_SYNDICATE]" = 0) diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm index 6adc9d38e6..3e889328a4 100644 --- a/code/modules/vending/clothesmate.dm +++ b/code/modules/vending/clothesmate.dm @@ -1,10 +1,9 @@ -//DON'T FORGET TO CHANGE THE REFILL SIZE IF YOU CHANGE THE MACHINE'S CONTENTS! /obj/machinery/vending/clothing name = "ClothesMate" //renamed to make the slogan rhyme desc = "A vending machine for clothing." icon_state = "clothes" icon_deny = "clothes-deny" - product_slogans = "Dress for success!;Prepare to look swagalicious!;Look at all this free swag!;Why leave style up to fate? Use the ClothesMate!" + product_slogans = "Dress for success!;Prepare to look swagalicious!;Look at all this swag!;Why leave style up to fate? Use the ClothesMate!" vend_reply = "Thank you for using the ClothesMate!" products = list(/obj/item/clothing/head/that = 4, /obj/item/clothing/head/fedora = 3, @@ -12,12 +11,13 @@ /obj/item/clothing/head/beret/black = 3, /obj/item/clothing/head/beret/purple = 3, /obj/item/clothing/head/beret/blue = 3, + /obj/item/clothing/accessory/pride = 25, /obj/item/clothing/glasses/monocle = 3, /obj/item/clothing/suit/jacket = 4, /obj/item/clothing/suit/jacket/flannel = 4, - /obj/item/clothing/suit/jacket/flannel/red = 4, - /obj/item/clothing/suit/jacket/flannel/aqua = 4, - /obj/item/clothing/suit/jacket/flannel/brown = 4, + /obj/item/clothing/suit/toggle/jacket/flannel/red = 4, + /obj/item/clothing/suit/toggle/jacket/flannel/aqua = 4, + /obj/item/clothing/suit/toggle/jacket/flannel/brown = 4, /obj/item/clothing/suit/jacket/puffer/vest = 4, /obj/item/clothing/suit/jacket/puffer = 4, /obj/item/clothing/suit/hooded/cloak/david = 4, @@ -69,7 +69,8 @@ /obj/item/clothing/under/pants/black = 4, /obj/item/clothing/under/pants/tan = 4, /obj/item/clothing/under/pants/track = 3, - /obj/item/clothing/under/pants/polypants/polychromic = 4, + /obj/item/clothing/under/pants/polypants = 4, + /obj/item/clothing/under/shorts/polychromic/polyworkout = 4, /obj/item/clothing/accessory/suitjacket = 2, /obj/item/clothing/accessory/suitjacket/charcoal = 2, /obj/item/clothing/accessory/suitjacket/navy = 2, @@ -164,7 +165,65 @@ /obj/item/clothing/ears/headphones = 10, /obj/item/clothing/suit/apron/purple_bartender = 4, /obj/item/clothing/under/rank/civilian/bartender/purple = 4, - + /obj/item/storage/backpack/henchmen = 20, + /obj/item/clothing/under/suit/henchmen = 20, + /obj/item/clothing/under/costume/yakuza = 20, + /obj/item/clothing/shoes/yakuza = 20, + /obj/item/clothing/suit/yakuza = 20, + /obj/item/clothing/under/costume/jackbros = 20, + /obj/item/clothing/shoes/jackbros = 20, + /obj/item/clothing/head/jackbros = 20, + /obj/item/clothing/under/costume/dutch = 20, + /obj/item/clothing/head/bowler = 20, + /obj/item/clothing/suit/dutch = 20, + /obj/item/clothing/suit/irs = 20, + /obj/item/clothing/under/costume/irs = 20, + /obj/item/clothing/head/irs = 20, + /obj/item/clothing/suit/osi = 20, + /obj/item/clothing/under/costume/osi = 20, + /obj/item/clothing/glasses/osi = 20, + /obj/item/clothing/suit/tmc = 20, + /obj/item/clothing/under/costume/tmc = 20, + /obj/item/clothing/head/tmc = 20, + /obj/item/clothing/suit/pg = 20, + /obj/item/clothing/under/costume/pg = 20, + /obj/item/clothing/head/pg = 20, + /obj/item/clothing/suit/driscoll = 20, + /obj/item/clothing/under/costume/driscoll = 20, + /obj/item/clothing/mask/gas/driscoll = 20, + /obj/item/clothing/suit/deckers = 20, + /obj/item/clothing/under/costume/deckers = 20, + /obj/item/clothing/head/deckers = 20, + /obj/item/clothing/shoes/deckers = 20, + /obj/item/clothing/suit/morningstar = 20, + /obj/item/clothing/under/costume/morningstar = 20, + /obj/item/clothing/head/morningstar = 20, + /obj/item/clothing/shoes/morningstar = 20, + /obj/item/clothing/suit/saints = 20, + /obj/item/clothing/under/costume/saints = 20, + /obj/item/clothing/head/saints = 20, + /obj/item/clothing/shoes/saints = 20, + /obj/item/clothing/suit/phantom = 20, + /obj/item/clothing/under/costume/phantom = 20, + /obj/item/clothing/glasses/phantom = 20, + /obj/item/clothing/shoes/phantom = 20, + /obj/item/clothing/suit/allies = 20, + /obj/item/clothing/under/costume/allies = 20, + /obj/item/clothing/head/allies = 20, + /obj/item/clothing/suit/soviet = 20, + /obj/item/clothing/under/costume/soviet_families = 20, + /obj/item/clothing/head/ushanka/soviet = 20, + /obj/item/clothing/suit/yuri = 20, + /obj/item/clothing/under/costume/yuri = 20, + /obj/item/clothing/head/yuri = 20, + /obj/item/clothing/suit/sybil_slickers = 20, + /obj/item/clothing/under/costume/sybil_slickers = 20, + /obj/item/clothing/head/sybil_slickers = 20, + /obj/item/clothing/shoes/sybil_slickers = 20, + /obj/item/clothing/suit/basil_boys = 20, + /obj/item/clothing/under/costume/basil_boys = 20, + /obj/item/clothing/head/basil_boys = 20, + /obj/item/clothing/shoes/basil_boys = 20, /* Commenting out until next Christmas or made automatic /obj/item/clothing/accessory/sweater/uglyxmas = 3, /obj/item/clothing/under/costume/christmas = 3, @@ -192,7 +251,8 @@ /obj/item/clothing/under/costume/cheongsam = 3, /obj/item/clothing/under/costume/cheongsam/white = 3, /obj/item/clothing/under/costume/cheongsam/red = 3, - /obj/item/storage/backpack/snail = 3) + /obj/item/storage/backpack/snail = 3, + /obj/item/umbrella = 5) contraband = list(/obj/item/clothing/accessory/turtleneck/tactifool/syndicate = 3, /obj/item/clothing/under/syndicate/tacticool = 3, /obj/item/clothing/under/syndicate/tacticool/skirt = 3, @@ -219,11 +279,23 @@ /obj/item/clothing/under/misc/corporateuniform = 5, /obj/item/clothing/suit/hooded/wintercoat/polychromic = 5, /obj/item/clothing/suit/toggle/wbreakpoly/polychromic = 5, - /obj/item/clothing/shoes/sneakers/poly/polychromic = 10) + /obj/item/clothing/shoes/sneakers/poly/polychromic = 10, + /obj/item/clothing/suit/toggle/jacket/fancytrench = 4, + /obj/item/clothing/suit/toggle/jacket/greenjacket = 4, + /obj/item/clothing/suit/jacket/gentlecoat = 4, + /obj/item/clothing/suit/jacket/gothicshirtcross = 4, + /obj/item/clothing/suit/jacket/gothicshirt = 4, + /obj/item/clothing/suit/jacket/gothiccoat = 4, + /obj/item/clothing/suit/jacket/heartcoat = 4, + /obj/item/clothing/suit/jacket/purplehoodie = 4, + /obj/item/clothing/suit/jacket/bluehoodie = 4, + /obj/item/clothing/suit/toggle/jacket/whitehoodie = 4) refill_canister = /obj/item/vending_refill/clothing - default_price = PRICE_CHEAP + default_price = PRICE_CHEAP //Default of extra_price = PRICE_BELOW_NORMAL payment_department = NO_FREEBIES + light_mask = "wardrobe-light-mask" + light_color = LIGHT_COLOR_ELECTRIC_GREEN /obj/machinery/vending/clothing/canLoadItem(obj/item/I,mob/user) return (I.type in products) diff --git a/code/modules/vending/coffee.dm b/code/modules/vending/coffee.dm index fd555526c6..cdc794f61b 100644 --- a/code/modules/vending/coffee.dm +++ b/code/modules/vending/coffee.dm @@ -1,7 +1,7 @@ /obj/machinery/vending/coffee name = "\improper Solar's Best Hot Drinks" desc = "A vending machine which dispenses hot drinks." - product_ads = "Just what you need!;Have a drink!;Drink up!;It's good for you!;Would you like a hot joe?;I'd kill for some coffee!;The best beans in the galaxy.;Only the finest brew for you.;Mmmm. Nothing like a coffee.;I like coffee, don't you?;Coffee helps you work!;Try some tea.;We hope you like the best!;Try our new chocolate!;Admin conspiracies" + product_ads = "Have a drink!;Drink up!;It's good for you!;Would you like a hot joe?;I'd kill for some coffee!;The best beans in the galaxy.;Only the finest brew for you.;Mmmm. Nothing like a coffee.;I like coffee, don't you?;Coffee helps you work!;Try some tea.;We hope you like the best!;Try our new chocolate!;Admin conspiracies" icon_state = "coffee" icon_vend = "coffee-vend" products = list(/obj/item/reagent_containers/food/drinks/coffee = 25, @@ -15,11 +15,12 @@ /obj/item/reagent_containers/food/drinks/bottle/cream = 2, /obj/item/reagent_containers/food/condiment/sugar = 1, /obj/item/reagent_containers/food/drinks/mug/tea/forest = 3,) - refill_canister = /obj/item/vending_refill/coffee default_price = PRICE_REALLY_CHEAP extra_price = PRICE_PRETTY_CHEAP payment_department = ACCOUNT_SRV + light_mask = "coffee-light-mask" + light_color = COLOR_DARK_MODERATE_ORANGE /obj/item/vending_refill/coffee machine_name = "Solar's Best Hot Drinks" diff --git a/code/modules/vending/cola.dm b/code/modules/vending/cola.dm index bb5b8ef288..f60c3fc2fa 100644 --- a/code/modules/vending/cola.dm +++ b/code/modules/vending/cola.dm @@ -6,7 +6,7 @@ product_slogans = "Robust Softdrinks: More robust than a toolbox to the head!" product_ads = "Refreshing!;Hope you're thirsty!;Over 1 million drinks sold!;Thirsty? Why not cola?;Please, have a drink!;Drink up!;The best drinks in space." products = list(/obj/item/reagent_containers/food/drinks/soda_cans/cola = 10, - /obj/item/reagent_containers/food/drinks/soda_cans/space_mountain_wind = 10, + /obj/item/reagent_containers/food/drinks/soda_cans/space_mountain_wind = 10, /obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb = 10, /obj/item/reagent_containers/food/drinks/soda_cans/starkist = 10, /obj/item/reagent_containers/food/drinks/soda_cans/space_up = 10, @@ -18,14 +18,15 @@ /obj/item/reagent_containers/food/drinks/soda_cans/shamblers = 6, /obj/item/reagent_containers/glass/beaker/waterbottle/wataur = 2) premium = list(/obj/item/reagent_containers/food/drinks/drinkingglass/filled/nuka_cola = 1, - /obj/item/reagent_containers/food/drinks/soda_cans/air = 1, - /obj/item/reagent_containers/food/drinks/soda_cans/grey_bull = 1, - /obj/item/reagent_containers/food/drinks/soda_cans/monkey_energy = 1) + /obj/item/reagent_containers/food/drinks/soda_cans/air = 1, + /obj/item/reagent_containers/food/drinks/soda_cans/monkey_energy = 1, + /obj/item/reagent_containers/food/drinks/soda_cans/grey_bull = 1) refill_canister = /obj/item/vending_refill/cola default_price = PRICE_CHEAP_AS_FREE extra_price = PRICE_ABOVE_NORMAL payment_department = ACCOUNT_SRV + /obj/item/vending_refill/cola machine_name = "Robust Softdrinks" icon_state = "refill_cola" @@ -35,7 +36,7 @@ icon_state = "random_cola" desc = "Uh oh!" -/obj/machinery/vending/cola/random/Initialize() +/obj/machinery/vending/cola/random/Initialize(mapload) ..() var/T = pick(subtypesof(/obj/machinery/vending/cola) - /obj/machinery/vending/cola/random) new T(loc) @@ -43,43 +44,56 @@ /obj/machinery/vending/cola/blue icon_state = "Cola_Machine" + light_mask = "cola-light-mask" + light_color = COLOR_MODERATE_BLUE /obj/machinery/vending/cola/black icon_state = "cola_black" + light_mask = "cola-light-mask" /obj/machinery/vending/cola/red icon_state = "red_cola" name = "\improper Space Cola Vendor" desc = "It vends cola, in space." product_slogans = "Cola in space!" + light_mask = "red_cola-light-mask" + light_color = COLOR_DARK_RED /obj/machinery/vending/cola/space_up icon_state = "space_up" name = "\improper Space-up! Vendor" desc = "Indulge in an explosion of flavor." product_slogans = "Space-up! Like a hull breach in your mouth." + light_mask = "space_up-light-mask" + light_color = COLOR_DARK_MODERATE_LIME_GREEN /obj/machinery/vending/cola/starkist icon_state = "starkist" name = "\improper Star-kist Vendor" desc = "The taste of a star in liquid form." product_slogans = "Drink the stars! Star-kist!" + light_mask = "starkist-light-mask" + light_color = COLOR_LIGHT_ORANGE /obj/machinery/vending/cola/sodie icon_state = "soda" + light_mask = "soda-light-mask" + light_color = COLOR_WHITE /obj/machinery/vending/cola/pwr_game icon_state = "pwr_game" name = "\improper Pwr Game Vendor" desc = "You want it, we got it. Brought to you in partnership with Vlad's Salads." product_slogans = "The POWER that gamers crave! PWR GAME!" + light_mask = "pwr_game-light-mask" + light_color = COLOR_STRONG_VIOLET /obj/machinery/vending/cola/shamblers name = "\improper Shambler's Vendor" desc = "~Shake me up some of that Shambler's Juice!~" icon_state = "shamblers_juice" products = list(/obj/item/reagent_containers/food/drinks/soda_cans/cola = 10, - /obj/item/reagent_containers/food/drinks/soda_cans/space_mountain_wind = 10, + /obj/item/reagent_containers/food/drinks/soda_cans/space_mountain_wind = 10, /obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb = 10, /obj/item/reagent_containers/food/drinks/soda_cans/starkist = 10, /obj/item/reagent_containers/food/drinks/soda_cans/space_up = 10, @@ -89,7 +103,8 @@ /obj/item/reagent_containers/food/drinks/soda_cans/shamblers = 10) product_slogans = "~Shake me up some of that Shambler's Juice!~" product_ads = "Refreshing!;Jyrbv dv lg jfdv fw kyrk Jyrdscvi'j Alztv!;Over 1 trillion souls drank!;Thirsty? Nyp efk uizeb kyv uribevjj?;Kyv Jyrdscvi uizebj kyv ezxyk!;Drink up!;Krjkp." - + light_mask = "shamblers-light-mask" + light_color = COLOR_MOSTLY_PURE_PINK /obj/machinery/vending/cola/buzz_fuzz name = "\improper Buzz Fuzz Vendor" desc = "~A hive of Flavour!~" diff --git a/code/modules/vending/dinnerware.dm b/code/modules/vending/dinnerware.dm index 95fd8e04d8..2c326d8e2b 100644 --- a/code/modules/vending/dinnerware.dm +++ b/code/modules/vending/dinnerware.dm @@ -26,7 +26,7 @@ /obj/item/reagent_containers/syringe = 3) premium = list( /obj/item/reagent_containers/food/condiment/enzyme = 1) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) refill_canister = /obj/item/vending_refill/dinnerware resistance_flags = FIRE_PROOF default_price = PRICE_REALLY_CHEAP diff --git a/code/modules/vending/engineering.dm b/code/modules/vending/engineering.dm index ef4edd6b67..fc88e6404c 100644 --- a/code/modules/vending/engineering.dm +++ b/code/modules/vending/engineering.dm @@ -5,9 +5,9 @@ icon_state = "engi" icon_deny = "engi-deny" products = list(/obj/item/clothing/under/rank/engineering/chief_engineer = 4, - /obj/item/clothing/under/rank/engineering/engineer = 4, - /obj/item/clothing/shoes/sneakers/orange = 4, - /obj/item/clothing/head/hardhat = 4, + /obj/item/clothing/under/rank/engineering/engineer = 4, + /obj/item/clothing/shoes/sneakers/orange = 4, + /obj/item/clothing/head/hardhat = 4, /obj/item/storage/belt/utility = 4, /obj/item/clothing/glasses/meson/engine = 4, /obj/item/clothing/gloves/color/yellow = 4, @@ -26,9 +26,13 @@ /obj/item/stock_parts/micro_laser = 5, /obj/item/stock_parts/matter_bin = 5, /obj/item/stock_parts/manipulator = 5) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + refill_canister = /obj/item/vending_refill/engineering resistance_flags = FIRE_PROOF default_price = PRICE_NORMAL extra_price = PRICE_NORMAL payment_department = ACCOUNT_ENG - cost_multiplier_per_dept = list(ACCOUNT_ENG = 0) + light_mask = "engi-light-mask" + +/obj/item/vending_refill/engineering + machine_name = "Robco Tool Maker" + icon_state = "refill_engi" diff --git a/code/modules/vending/engivend.dm b/code/modules/vending/engivend.dm index 965ebddd15..559e56eec7 100644 --- a/code/modules/vending/engivend.dm +++ b/code/modules/vending/engivend.dm @@ -27,13 +27,13 @@ /obj/item/rcd_ammo/large = 5, /obj/item/storage/bag/material = 3 ) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) refill_canister = /obj/item/vending_refill/engivend resistance_flags = FIRE_PROOF default_price = PRICE_ALMOST_EXPENSIVE extra_price = PRICE_ABOVE_EXPENSIVE payment_department = ACCOUNT_ENG - cost_multiplier_per_dept = list(ACCOUNT_ENG = 0) + light_mask = "engivend-light-mask" /obj/item/vending_refill/engivend + machine_name = "Engi-Vend" icon_state = "refill_engi" diff --git a/code/modules/vending/games.dm b/code/modules/vending/games.dm index cea9c5ae70..e6a6eb01e9 100644 --- a/code/modules/vending/games.dm +++ b/code/modules/vending/games.dm @@ -4,12 +4,17 @@ product_ads = "Escape to a fantasy world!;Fuel your gambling addiction!;Ruin your friendships!;Roll for initiative!;Elves and dwarves!;Paranoid computers!;Totally not satanic!;Fun times forever!" icon_state = "games" products = list(/obj/item/toy/cards/deck = 5, - /obj/item/storage/dice = 10, - /obj/item/toy/cards/deck/cas = 3, - /obj/item/toy/cards/deck/cas/black = 3, + /obj/item/storage/dice = 10, + /obj/item/toy/cards/deck/cas = 3, + /obj/item/toy/cards/deck/cas/black = 3, /obj/item/toy/cards/deck/unum = 3, + /obj/item/camera = 3, /obj/item/cardpack/series_one = 10, - /obj/item/tcgcard_binder = 5) + /obj/item/tcgcard_binder = 5, + /obj/item/canvas = 3, + /obj/item/toy/crayon/spraycan = 3, + /obj/item/dyespray=3, + ) contraband = list(/obj/item/dice/fudge = 9) premium = list(/obj/item/melee/skateboard/pro = 3, /obj/item/melee/skateboard/hoverboard = 1) @@ -17,7 +22,7 @@ default_price = PRICE_CHEAP extra_price = PRICE_ALMOST_EXPENSIVE payment_department = ACCOUNT_SRV - cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) + light_mask = "games-light-mask" /obj/item/vending_refill/games machine_name = "\improper Good Clean Fun" diff --git a/code/modules/vending/kinkmate.dm b/code/modules/vending/kinkmate.dm index 6d8eea1782..02f3f30e4b 100644 --- a/code/modules/vending/kinkmate.dm +++ b/code/modules/vending/kinkmate.dm @@ -31,6 +31,7 @@ /obj/item/autosurgeon/testicles = 3, /obj/item/storage/pill_bottle/penis_enlargement = 10, /obj/item/storage/pill_bottle/breast_enlargement = 10, + /obj/item/storage/pill_bottle/butt_enlargement = 10, /obj/item/reagent_containers/glass/bottle/crocin = 10, /obj/item/reagent_containers/glass/bottle/camphor = 5, /obj/item/storage/daki = 4 diff --git a/code/modules/vending/liberation.dm b/code/modules/vending/liberation.dm index 81afab3a70..36bde6dd6b 100644 --- a/code/modules/vending/liberation.dm +++ b/code/modules/vending/liberation.dm @@ -2,15 +2,15 @@ name = "\improper Liberation Station" desc = "An overwhelming amount of ancient patriotism washes over you just by looking at the machine." icon_state = "liberationstation" - product_slogans = "Liberation Station: Your one-stop shop for all things second ammendment!;Be a patriot today, pick up a gun!;Quality weapons for cheap prices!;Better dead than red!" - product_ads = "Float like an astronaut, sting like a bullet!;Express your second ammendment today!;Guns don't kill people, but you can!;Who needs responsibilities when you have guns?" + product_slogans = "Liberation Station: Your one-stop shop for all things second amendment!;Be a patriot today, pick up a gun!;Quality weapons for cheap prices!;Better dead than red!" + product_ads = "Float like an astronaut, sting like a bullet!;Express your second amendment today!;Guns don't kill people, but you can!;Who needs responsibilities when you have guns?" vend_reply = "Remember the name: Liberation Station!" products = list(/obj/item/reagent_containers/food/snacks/burger/plain = 5, //O say can you see, by the dawn's early light /obj/item/reagent_containers/food/snacks/burger/baseball = 3, //What so proudly we hailed at the twilight's last gleaming /obj/item/reagent_containers/food/snacks/fries = 5, //Whose broad stripes and bright stars through the perilous fight /obj/item/reagent_containers/food/drinks/beer/light = 10, //O'er the ramparts we watched, were so gallantly streaming? /obj/item/gun/ballistic/automatic/pistol/deagle/gold = 2, - /obj/item/gun/ballistic/automatic/pistol/deagle/camo = 2, + /obj/item/gun/ballistic/automatic/pistol/deagle/camo = 2, /obj/item/gun/ballistic/automatic/pistol/m1911 = 2, /obj/item/gun/ballistic/automatic/proto/unrestricted = 2, /obj/item/gun/ballistic/shotgun/automatic/combat = 2, @@ -18,16 +18,16 @@ /obj/item/gun/ballistic/shotgun = 2, /obj/item/gun/ballistic/automatic/ar = 2) premium = list(/obj/item/ammo_box/magazine/smgm9mm = 2, - /obj/item/ammo_box/magazine/m50 = 4, - /obj/item/ammo_box/magazine/m45 = 2, - /obj/item/ammo_box/magazine/m75 = 2, + /obj/item/ammo_box/magazine/m50 = 4, + /obj/item/ammo_box/magazine/m45 = 2, + /obj/item/ammo_box/magazine/m75 = 2, /obj/item/reagent_containers/food/snacks/cheesyfries = 5, /obj/item/reagent_containers/food/snacks/burger/baconburger = 5) //Premium burgers for the premium section contraband = list(/obj/item/clothing/under/misc/patriotsuit = 3, - /obj/item/bedsheet/patriot = 5, + /obj/item/bedsheet/patriot = 5, /obj/item/reagent_containers/food/snacks/burger/superbite = 3) //U S A - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF default_price = PRICE_ABOVE_NORMAL extra_price = PRICE_ABOVE_EXPENSIVE payment_department = ACCOUNT_SEC + light_mask = "liberation-light-mask" diff --git a/code/modules/vending/liberation_toy.dm b/code/modules/vending/liberation_toy.dm index 9093d55b0d..21cc8e986a 100644 --- a/code/modules/vending/liberation_toy.dm +++ b/code/modules/vending/liberation_toy.dm @@ -16,19 +16,16 @@ /obj/item/clothing/suit/syndicatefake = 5, /obj/item/clothing/head/syndicatefake = 5) //OPS IN DORMS oh wait it's just an assistant contraband = list(/obj/item/gun/ballistic/shotgun/toy/crossbow = 10, //Congrats, you unlocked the +18 setting! - /obj/item/gun/ballistic/automatic/c20r/toy/unrestricted/riot = 10, - /obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted/riot = 10, - /obj/item/ammo_box/foambox/riot = 20, - /obj/item/toy/katana = 10, - /obj/item/dualsaber/toy = 5, - /obj/item/toy/cards/deck/syndicate = 10) //Gambling and it hurts, making it a +18 item - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + /obj/item/gun/ballistic/automatic/c20r/toy/unrestricted/riot = 10, + /obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted/riot = 10, + /obj/item/ammo_box/foambox/riot = 20, + /obj/item/toy/katana = 10, + /obj/item/dualsaber/toy = 5, + /obj/item/toy/cards/deck/syndicate = 10) //Gambling and it hurts, making it a +18 item + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/donksoft default_price = PRICE_ABOVE_NORMAL extra_price = PRICE_EXPENSIVE - payment_department = NO_FREEBIES - -/obj/machinery/vending/toyliberationstation/Initialize() - . = ..() - cost_multiplier_per_dept = list("[ACCESS_SYNDICATE]" = 0) + payment_department = ACCOUNT_SRV + light_mask = "donksoft-light-mask" diff --git a/code/modules/vending/magivend.dm b/code/modules/vending/magivend.dm index 9dcd77e4ab..f5565eaa4c 100644 --- a/code/modules/vending/magivend.dm +++ b/code/modules/vending/magivend.dm @@ -4,18 +4,19 @@ icon_state = "MagiVend" product_slogans = "Sling spells the proper way with MagiVend!;Be your own Houdini! Use MagiVend!" vend_reply = "Have an enchanted evening!" - product_ads = "EI NATH;Destroy the station!;Admin conspiracies since forever!;Space-time bending hardware!;Now-magic proofing venders!" + product_ads = "FJKLFJSD;AJKFLBJAKL;1234 LOONIES LOL!;>MFW;Kill them fuckers!;GET DAT FUKKEN DISK;HONK!;EI NATH;Destroy the station!;Admin conspiracies since forever!;Space-time bending hardware!" products = list(/obj/item/clothing/head/wizard = 1, - /obj/item/clothing/suit/wizrobe = 1, - /obj/item/clothing/head/wizard/red = 1, - /obj/item/clothing/suit/wizrobe/red = 1, - /obj/item/clothing/head/wizard/yellow = 1, - /obj/item/clothing/suit/wizrobe/yellow = 1, - /obj/item/clothing/shoes/sandal/magic = 1, - /obj/item/staff = 2) - contraband = list(/obj/item/reagent_containers/glass/bottle/wizarditis = 1) //No one can get to the machine to hack it anyways; for the lulz - Microwave - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50, "magic" = 100) + /obj/item/clothing/suit/wizrobe = 1, + /obj/item/clothing/head/wizard/red = 1, + /obj/item/clothing/suit/wizrobe/red = 1, + /obj/item/clothing/head/wizard/yellow = 1, + /obj/item/clothing/suit/wizrobe/yellow = 1, + /obj/item/clothing/shoes/sandal/magic = 1, + /obj/item/staff = 2) + contraband = list(/obj/item/reagent_containers/glass/bottle/wizarditis = 1) //No one can get to the machine to hack it anyways; for the lulz - Microwave + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50, MAGIC = 100) resistance_flags = FIRE_PROOF - default_price = PRICE_EXPENSIVE + default_price = 0 //Just in case, since it's primary use is storage. extra_price = PRICE_ABOVE_EXPENSIVE payment_department = ACCOUNT_SRV + light_mask = "magivend-light-mask" diff --git a/code/modules/vending/medical.dm b/code/modules/vending/medical.dm index a24233b17c..0158547515 100644 --- a/code/modules/vending/medical.dm +++ b/code/modules/vending/medical.dm @@ -4,6 +4,7 @@ icon_state = "med" icon_deny = "med-deny" product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?;Ping!" + req_access = list(ACCESS_MEDICAL) products = list(/obj/item/reagent_containers/syringe = 12, /obj/item/reagent_containers/dropper = 3, /obj/item/healthanalyzer = 4, @@ -50,13 +51,11 @@ /obj/item/storage/briefcase/medical = 2, /obj/item/plunger/reinforced = 2) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) - resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/medical default_price = PRICE_ALMOST_CHEAP extra_price = PRICE_ABOVE_NORMAL payment_department = ACCOUNT_MED - cost_multiplier_per_dept = list(ACCOUNT_MED = 0) + light_mask = "med-light-mask" /obj/item/vending_refill/medical machine_name = "NanoMed Plus" @@ -64,8 +63,9 @@ /obj/machinery/vending/medical/syndicate_access name = "\improper SyndiMed Plus" - payment_department = NO_FREEBIES + req_access = list(ACCESS_SYNDICATE) -/obj/machinery/vending/medical/syndicate_access/Initialize() + +/obj/machinery/vending/medical/syndicate_access/Initialize(mapload) . = ..() cost_multiplier_per_dept = list("[ACCESS_SYNDICATE]" = 0) diff --git a/code/modules/vending/medical_wall.dm b/code/modules/vending/medical_wall.dm index 2d4c30080d..fdc062b2cb 100644 --- a/code/modules/vending/medical_wall.dm +++ b/code/modules/vending/medical_wall.dm @@ -18,14 +18,28 @@ contraband = list(/obj/item/reagent_containers/pill/tox = 2, /obj/item/reagent_containers/pill/morphine = 2) premium = list(/obj/item/reagent_containers/medspray/synthflesh = 2) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) - resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/wallmed default_price = PRICE_FREE extra_price = PRICE_NORMAL payment_department = ACCOUNT_MED - cost_multiplier_per_dept = list(ACCOUNT_MED = 0) tiltable = FALSE + light_mask = "wallmed-light-mask" + +/obj/machinery/vending/wallmed/directional/north + dir = SOUTH + pixel_y = 32 + +/obj/machinery/vending/wallmed/directional/south + dir = NORTH + pixel_y = -32 + +/obj/machinery/vending/wallmed/directional/east + dir = WEST + pixel_x = 32 + +/obj/machinery/vending/wallmed/directional/west + dir = EAST + pixel_x = -32 /obj/item/vending_refill/wallmed machine_name = "NanoMed" diff --git a/code/modules/vending/megaseed.dm b/code/modules/vending/megaseed.dm index 45199298ca..790bf551b7 100644 --- a/code/modules/vending/megaseed.dm +++ b/code/modules/vending/megaseed.dm @@ -4,6 +4,7 @@ product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!" product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!" icon_state = "seeds" + light_mask = "seeds-light-mask" products = list(/obj/item/seeds/aloe = 3, /obj/item/seeds/ambrosia = 3, /obj/item/seeds/apple = 3, @@ -20,6 +21,7 @@ /obj/item/seeds/cotton = 3, /obj/item/seeds/corn = 3, /obj/item/seeds/eggplant = 3, + /obj/item/seeds/garlic = 3, /obj/item/seeds/grape = 3, /obj/item/seeds/grass = 3, /obj/item/seeds/lemon = 3, @@ -56,13 +58,11 @@ /obj/item/seeds/starthistle = 2, /obj/item/seeds/random = 2) premium = list(/obj/item/reagent_containers/spray/waterflower = 1) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) refill_canister = /obj/item/vending_refill/hydroseeds - resistance_flags = FIRE_PROOF default_price = PRICE_ALMOST_CHEAP extra_price = PRICE_NORMAL payment_department = ACCOUNT_SRV - cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) /obj/item/vending_refill/hydroseeds - icon_state = "refill_hydro" + machine_name = "MegaSeed Servitor" + icon_state = "refill_plant" diff --git a/code/modules/vending/nutrimax.dm b/code/modules/vending/nutrimax.dm index 40ca06b78b..38bab5c599 100644 --- a/code/modules/vending/nutrimax.dm +++ b/code/modules/vending/nutrimax.dm @@ -5,6 +5,7 @@ product_ads = "We like plants!;Don't you want some?;The greenest thumbs ever.;We like big plants.;Soft soil..." icon_state = "nutri" icon_deny = "nutri-deny" + light_mask = "nutri-light-mask" products = list(/obj/item/reagent_containers/glass/bottle/nutrient/ez = 30, /obj/item/reagent_containers/glass/bottle/nutrient/l4z = 20, /obj/item/reagent_containers/glass/bottle/nutrient/rh = 10, @@ -15,14 +16,12 @@ /obj/item/shovel/spade = 3, /obj/item/plant_analyzer = 4) contraband = list(/obj/item/reagent_containers/glass/bottle/ammonia = 10, - /obj/item/reagent_containers/glass/bottle/diethylamine = 5) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + /obj/item/reagent_containers/glass/bottle/diethylamine = 5) refill_canister = /obj/item/vending_refill/hydronutrients - resistance_flags = FIRE_PROOF default_price = PRICE_REALLY_CHEAP extra_price = PRICE_CHEAP payment_department = ACCOUNT_SRV - cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) /obj/item/vending_refill/hydronutrients - icon_state = "refill_hydro" + machine_name = "NutriMax" + icon_state = "refill_plant" diff --git a/code/modules/vending/plasmaresearch.dm b/code/modules/vending/plasmaresearch.dm index bb16570ab3..2bd022eeb2 100644 --- a/code/modules/vending/plasmaresearch.dm +++ b/code/modules/vending/plasmaresearch.dm @@ -1,10 +1,10 @@ //This one's from bay12 /obj/machinery/vending/plasmaresearch - name = "\improper Toximate 3000" + name = "\improper Bombuddy 3000" desc = "All the fine parts you need in one vending machine!" products = list(/obj/item/clothing/under/rank/rnd/scientist = 6, - /obj/item/clothing/suit/bio_suit = 6, - /obj/item/clothing/head/bio_hood = 6, + /obj/item/clothing/suit/bio_suit = 6, + /obj/item/clothing/head/bio_hood = 6, /obj/item/transfer_valve = 6, /obj/item/assembly/timer = 6, /obj/item/assembly/signaler = 6, @@ -14,4 +14,3 @@ default_price = PRICE_EXPENSIVE extra_price = PRICE_REALLY_EXPENSIVE payment_department = ACCOUNT_SCI - cost_multiplier_per_dept = list(ACCOUNT_SCI = 0) diff --git a/code/modules/vending/robotics.dm b/code/modules/vending/robotics.dm index 2d77b2fc51..714f05a60d 100644 --- a/code/modules/vending/robotics.dm +++ b/code/modules/vending/robotics.dm @@ -4,6 +4,8 @@ desc = "All the tools you need to create your own robot army." icon_state = "robotics" icon_deny = "robotics-deny" + light_mask = "robotics-light-mask" + req_access = list(ACCESS_ROBOTICS) products = list(/obj/item/clothing/suit/toggle/labcoat = 4, /obj/item/clothing/under/rank/rnd/roboticist = 4, /obj/item/stack/cable_coil = 4, @@ -14,13 +16,16 @@ /obj/item/healthanalyzer = 3, /obj/item/scalpel = 2, /obj/item/circular_saw = 2, + /obj/item/bonesetter = 2, /obj/item/tank/internals/anesthetic = 2, /obj/item/clothing/mask/breath/medical = 5, /obj/item/screwdriver = 5, - /obj/item/crowbar = 6, + /obj/item/crowbar = 5, /obj/item/stack/medical/nanogel = 5) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) - resistance_flags = FIRE_PROOF + refill_canister = /obj/item/vending_refill/robotics default_price = PRICE_EXPENSIVE payment_department = ACCOUNT_SCI - cost_multiplier_per_dept = list(ACCOUNT_SCI = 0) + +/obj/item/vending_refill/robotics + machine_name = "Robotech Deluxe" + icon_state = "refill_engi" diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm index c3540777ab..52fbd7dac4 100644 --- a/code/modules/vending/security.dm +++ b/code/modules/vending/security.dm @@ -1,9 +1,11 @@ /obj/machinery/vending/security name = "\improper SecTech" desc = "A security equipment vendor." - product_ads = "Crack capitalist skulls!;Beat some heads in!;Don't forget - harm is good!;Your weapons are right here.;Handcuffs!;Freeze, scumbag!;Don't tase me bro!;Tase them, bro.;Why not have a donut?" + product_ads = "Crack communist skulls!;Beat some heads in!;Don't forget - harm is good!;Your weapons are right here.;Handcuffs!;Freeze, scumbag!;Don't tase me bro!;Tase them, bro.;Why not have a donut?" icon_state = "sec" icon_deny = "sec-deny" + light_mask = "sec-light-mask" + req_access = list(ACCESS_SECURITY) products = list(/obj/item/restraints/handcuffs = 8, /obj/item/restraints/handcuffs/cable/zipties = 10, /obj/item/grenade/flashbang = 4, @@ -17,20 +19,17 @@ /obj/item/storage/fancy/donut_box = 2, /obj/item/storage/belt/sabre/secbelt = 1) premium = list(/obj/item/coin/antagtoken = 1, - /obj/item/clothing/head/helmet/blueshirt = 1, - /obj/item/clothing/suit/armor/vest/blueshirt = 1, + /obj/item/clothing/head/helmet/blueshirt = 1, + /obj/item/clothing/suit/armor/vest/blueshirt = 1, /obj/item/clothing/under/rank/security/officer/blueshirt = 1, - /obj/item/clothing/gloves/tackler = 5, - /obj/item/grenade/stingbang = 1, + /obj/item/clothing/gloves/tackler = 5, + /obj/item/grenade/stingbang = 1, /obj/item/ssword_kit = 1, /obj/item/storage/bag/ammo = 3) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) - resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/security default_price = PRICE_ALMOST_EXPENSIVE extra_price = PRICE_REALLY_EXPENSIVE payment_department = ACCOUNT_SEC - cost_multiplier_per_dept = list(ACCOUNT_SEC = 0) /obj/machinery/vending/security/pre_throw(obj/item/I) if(istype(I, /obj/item/grenade)) @@ -42,4 +41,4 @@ F.update_brightness() /obj/item/vending_refill/security - icon_state = "refill_games" + icon_state = "refill_sec" diff --git a/code/modules/vending/snack.dm b/code/modules/vending/snack.dm index ff8fd46676..efb6670496 100644 --- a/code/modules/vending/snack.dm +++ b/code/modules/vending/snack.dm @@ -4,6 +4,7 @@ product_slogans = "Try our new nougat bar!;Twice the calories for half the price!" product_ads = "The healthiest!;Award-winning chocolate bars!;Mmm! So good!;Oh my god it's so juicy!;Have a snack.;Snacks are good for you!;Have some more Getmore!;Best quality snacks straight from mars.;We love chocolate!;Try our new jerky!" icon_state = "snack" + light_mask = "snack-light-mask" products = list(/obj/item/reagent_containers/food/snacks/candy = 5, /obj/item/reagent_containers/food/snacks/chocolatebar = 5, /obj/item/reagent_containers/food/drinks/dry_ramen = 5, @@ -25,13 +26,11 @@ /obj/item/reagent_containers/food/snacks/chococoin = 1, /obj/item/storage/box/marshmallow = 1, /obj/item/storage/box/donkpockets = 2) - refill_canister = /obj/item/vending_refill/snack canload_access_list = list(ACCESS_KITCHEN) default_price = PRICE_REALLY_CHEAP extra_price = PRICE_ALMOST_CHEAP payment_department = ACCOUNT_SRV - cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) input_display_header = "Chef's Food Selection" /obj/item/vending_refill/snack @@ -42,7 +41,7 @@ icon_state = "random_snack" desc = "Uh oh!" -/obj/machinery/vending/snack/random/Initialize() +/obj/machinery/vending/snack/random/Initialize(mapload) ..() var/T = pick(subtypesof(/obj/machinery/vending/snack) - /obj/machinery/vending/snack/random) new T(loc) diff --git a/code/modules/vending/sovietsoda.dm b/code/modules/vending/sovietsoda.dm index 88aba484e1..f28dbd7116 100644 --- a/code/modules/vending/sovietsoda.dm +++ b/code/modules/vending/sovietsoda.dm @@ -2,11 +2,17 @@ name = "\improper BODA" desc = "Old sweet water vending machine." icon_state = "sovietsoda" + light_mask = "soviet-light-mask" product_ads = "For Tsar and Country.;Have you fulfilled your nutrition quota today?;Very nice!;We are simple people, for this is all we eat.;If there is a person, there is a problem. If there is no person, then there is no problem." products = list(/obj/item/reagent_containers/food/drinks/drinkingglass/filled/soda = 30) contraband = list(/obj/item/reagent_containers/food/drinks/drinkingglass/filled/cola = 20) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF - default_price = PRICE_FREE - extra_price = PRICE_FREE + refill_canister = /obj/item/vending_refill/sovietsoda + default_price = 1 + extra_price = 2 //One credit for every state of FREEDOM payment_department = NO_FREEBIES + light_color = COLOR_PALE_ORANGE + +/obj/item/vending_refill/sovietsoda + machine_name = "BODA" + icon_state = "refill_cola" diff --git a/code/modules/vending/sustenance.dm b/code/modules/vending/sustenance.dm index 2dcc1e99f7..9370cf0c24 100644 --- a/code/modules/vending/sustenance.dm +++ b/code/modules/vending/sustenance.dm @@ -2,21 +2,24 @@ name = "\improper Sustenance Vendor" desc = "A vending machine which vends food, as required by section 47-C of the NT's Prisoner Ethical Treatment Agreement." product_slogans = "Enjoy your meal.;Enough calories to support strenuous labor." - product_ads = "Sufficiently healthy.;Efficiently produced tofu!;Mmm! So good!;Have a meal.;You need food to live!;Have some more candy corn!;Try our new ice cups!" + product_ads = "Sufficiently healthy.;Efficiently produced tofu!;Mmm! So good!;Have a meal.;You need food to live!;Even prisoners deserve their daily bread!;Have some more candy corn!;Try our new ice cups!" + light_mask = "snack-light-mask" icon_state = "sustenance" products = list(/obj/item/reagent_containers/food/snacks/tofu = 24, /obj/item/reagent_containers/food/drinks/ice/sustanance = 12, - /obj/item/reagent_containers/food/snacks/candy_corn = 6) + /obj/item/reagent_containers/food/snacks/candy_corn = 6 + ) contraband = list(/obj/item/kitchen/knife = 6, /obj/item/reagent_containers/food/drinks/coffee = 12, /obj/item/tank/internals/emergency_oxygen = 6, - /obj/item/clothing/mask/breath = 6) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + /obj/item/clothing/mask/breath = 6 + ) + refill_canister = /obj/item/vending_refill/sustenance - resistance_flags = FIRE_PROOF default_price = PRICE_FREE extra_price = PRICE_FREE payment_department = NO_FREEBIES /obj/item/vending_refill/sustenance - icon_state = "refill_cook" + machine_name = "Sustenance Vendor" + icon_state = "refill_snack" diff --git a/code/modules/vending/toys.dm b/code/modules/vending/toys.dm index c5095ebff8..683f2d9f23 100644 --- a/code/modules/vending/toys.dm +++ b/code/modules/vending/toys.dm @@ -5,6 +5,7 @@ product_slogans = "Get your cool toys today!;Trigger a valid hunter today!;Quality toy weapons for cheap prices!;Give them to HoPs for all access!;Give them to HoS to get permabrigged!" product_ads = "Feel robust with your toys!;Express your inner child today!;Toy weapons don't kill people, but valid hunters do!;Who needs responsibilities when you have toy weapons?;Make your next murder FUN!" vend_reply = "Come back for more!" + light_mask = "donksoft-light-mask" circuit = /obj/item/circuitboard/machine/vending/donksofttoyvendor products = list( /obj/item/gun/ballistic/automatic/toy/unrestricted = 10, @@ -22,8 +23,6 @@ /obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted = 10, /obj/item/toy/katana = 10, /obj/item/dualsaber/toy = 5) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) - resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/donksoft default_price = PRICE_ABOVE_NORMAL extra_price = PRICE_EXPENSIVE diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm index eebb07938b..f60ea76015 100644 --- a/code/modules/vending/wardrobes.dm +++ b/code/modules/vending/wardrobes.dm @@ -6,6 +6,7 @@ extra_price = PRICE_EXPENSIVE payment_department = NO_FREEBIES input_display_header = "Returned Clothing" + light_mask = "wardrobe-light-mask" /obj/machinery/vending/wardrobe/canLoadItem(obj/item/I,mob/user) return (I.type in products) @@ -31,55 +32,16 @@ /obj/item/clothing/suit/toggle/labcoat/depjacket/sec = 5, /obj/item/clothing/under/rank/security/officer/util = 5, /obj/item/clothing/under/rank/security/officer/blueshirt/seccorp = 5) + contraband = list(/obj/item/clothing/under/rank/security/stripper = 5) premium = list(/obj/item/clothing/under/rank/security/officer/formal = 5, /obj/item/clothing/head/beret/sec/navyofficer = 5) refill_canister = /obj/item/vending_refill/wardrobe/sec_wardrobe payment_department = ACCOUNT_SEC - cost_multiplier_per_dept = list(ACCOUNT_SEC = 0) - default_price = PRICE_ABOVE_NORMAL - extra_price = PRICE_EXPENSIVE + light_color = COLOR_MOSTLY_PURE_RED /obj/item/vending_refill/wardrobe/sec_wardrobe machine_name = "SecDrobe" - -/obj/machinery/vending/wardrobe/det_wardrobe - name = "\improper DetDrobe" - desc = "A machine for all your detective needs, as long as you need clothes." - icon_state = "detdrobe" - product_ads = "Apply your brilliant deductive methods in style!" - vend_reply = "Thank you for using the DetDrobe!" - products = list(/obj/item/clothing/under/rank/security/detective = 2, - /obj/item/clothing/under/rank/security/detective/skirt = 2, - /obj/item/clothing/under/rank/security/detective/brown = 2, - /obj/item/clothing/under/rank/security/detective/brown/brown2 = 2, - /obj/item/clothing/under/rank/security/officer/blueshirt/seccorp/detcorp = 2, - /obj/item/clothing/under/rank/security/officer/util = 2, - /obj/item/clothing/shoes/sneakers/brown = 2, - /obj/item/clothing/suit/det_suit = 2, - /obj/item/clothing/head/fedora/det_hat = 2, - /obj/item/clothing/under/rank/security/detective/grey = 2, - /obj/item/clothing/under/rank/security/detective/grey/skirt = 2, - /obj/item/clothing/accessory/waistcoat = 2, - /obj/item/clothing/shoes/laceup = 2, - /obj/item/clothing/suit/det_suit/grey = 1, - /obj/item/clothing/suit/det_suit/forensicsred = 1, - /obj/item/clothing/suit/det_suit/forensicsred/long = 1, - /obj/item/clothing/suit/det_suit/forensicsblue = 1, - /obj/item/clothing/suit/det_suit/forensicsblue/long = 1, - /obj/item/clothing/head/fedora = 2, - /obj/item/clothing/gloves/color/black = 2, - /obj/item/clothing/gloves/color/latex = 2, - /obj/item/reagent_containers/food/drinks/flask/det = 2, - /obj/item/storage/fancy/cigarettes = 5) - premium = list(/obj/item/clothing/head/flatcap = 1) - refill_canister = /obj/item/vending_refill/wardrobe/det_wardrobe - extra_price = 350 - payment_department = ACCOUNT_SEC - -/obj/item/vending_refill/wardrobe/det_wardrobe - machine_name = "DetDrobe" - /obj/machinery/vending/wardrobe/medi_wardrobe name = "\improper MediDrobe" desc = "A vending machine rumoured to be capable of dispensing clothing for medical personnel." @@ -118,7 +80,6 @@ /obj/item/clothing/suit/toggle/labcoat/emt/highvis = 5) refill_canister = /obj/item/vending_refill/wardrobe/medi_wardrobe payment_department = ACCOUNT_MED - cost_multiplier_per_dept = list(ACCOUNT_MED = 0) /obj/item/vending_refill/wardrobe/medi_wardrobe machine_name = "MediDrobe" @@ -149,7 +110,7 @@ /obj/item/clothing/head/hardhat/weldhat = 3) refill_canister = /obj/item/vending_refill/wardrobe/engi_wardrobe payment_department = ACCOUNT_ENG - cost_multiplier_per_dept = list(ACCOUNT_ENG = 0) + light_color = COLOR_VIVID_YELLOW /obj/item/vending_refill/wardrobe/engi_wardrobe machine_name = "EngiDrobe" @@ -172,7 +133,7 @@ /obj/item/clothing/shoes/sneakers/black = 5) refill_canister = /obj/item/vending_refill/wardrobe/atmos_wardrobe payment_department = ACCOUNT_ENG - cost_multiplier_per_dept = list(ACCOUNT_ENG = 0) + light_color = COLOR_VIVID_YELLOW /obj/item/vending_refill/wardrobe/atmos_wardrobe machine_name = "AtmosDrobe" @@ -195,7 +156,6 @@ /obj/item/radio/headset/headset_cargo = 3) refill_canister = /obj/item/vending_refill/wardrobe/cargo_wardrobe payment_department = ACCOUNT_CAR - cost_multiplier_per_dept = list(ACCOUNT_CAR = 0) /obj/item/vending_refill/wardrobe/cargo_wardrobe machine_name = "CargoDrobe" @@ -223,17 +183,16 @@ /obj/item/clothing/under/misc/mechsuitblue = 1) contraband = list(/obj/item/clothing/suit/hooded/techpriest = 2) refill_canister = /obj/item/vending_refill/wardrobe/robo_wardrobe + extra_price = PRICE_EXPENSIVE * 1.2 payment_department = ACCOUNT_SCI - cost_multiplier_per_dept = list(ACCOUNT_SCI = 0) - /obj/item/vending_refill/wardrobe/robo_wardrobe machine_name = "RoboDrobe" /obj/machinery/vending/wardrobe/science_wardrobe name = "SciDrobe" - desc = "A simple vending machine suitable to dispense well tailored science clothing. Endorsed by Cubans." + desc = "A simple vending machine suitable to dispense well tailored science clothing. Endorsed by Space Cubans." icon_state = "scidrobe" - product_ads = "Longing for the smell of flesh plasma? Buy your science clothing now!;Made with 10% Auxetics, so you don't have to worry losing your arm!" + product_ads = "Longing for the smell of plasma burnt flesh? Buy your science clothing now!;Made with 10% Auxetics, so you don't have to worry about losing your arm!" vend_reply = "Thank you for using the SciDrobe!" products = list(/obj/item/clothing/accessory/pocketprotector = 5, /obj/item/clothing/head/beret/sci = 3, @@ -251,8 +210,6 @@ /obj/item/clothing/mask/gas = 5) refill_canister = /obj/item/vending_refill/wardrobe/science_wardrobe payment_department = ACCOUNT_SCI - cost_multiplier_per_dept = list(ACCOUNT_SCI = 0) - /obj/item/vending_refill/wardrobe/science_wardrobe machine_name = "SciDrobe" @@ -274,7 +231,7 @@ /obj/item/clothing/mask/bandana = 4) refill_canister = /obj/item/vending_refill/wardrobe/hydro_wardrobe payment_department = ACCOUNT_SRV - cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) + light_color = LIGHT_COLOR_ELECTRIC_GREEN /obj/item/vending_refill/wardrobe/hydro_wardrobe machine_name = "HyDrobe" @@ -299,9 +256,7 @@ /obj/item/clothing/glasses/regular/jamjar = 1, /obj/item/storage/bag/books = 1) refill_canister = /obj/item/vending_refill/wardrobe/curator_wardrobe - payment_department = ACCOUNT_CIV - cost_multiplier_per_dept = list(ACCOUNT_CIV = 0) - + payment_department = ACCOUNT_SRV /obj/item/vending_refill/wardrobe/curator_wardrobe machine_name = "CuraDrobe" @@ -331,8 +286,6 @@ /obj/item/storage/belt/bandolier = 1) refill_canister = /obj/item/vending_refill/wardrobe/bar_wardrobe payment_department = ACCOUNT_SRV - cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) - /obj/item/vending_refill/wardrobe/bar_wardrobe machine_name = "BarDrobe" @@ -340,8 +293,8 @@ name = "ChefDrobe" desc = "This vending machine might not dispense meat, but it certainly dispenses chef related clothing." icon_state = "chefdrobe" - product_ads = "Our clothes are guaranteed to protect you from food splatters!;Now stocking recipe books!" - vend_reply = "Thank you for using the ChefDrobe!;Just like your grandmother's old recipes!" + product_ads = "Our clothes are guaranteed to protect you from food splatters!" + vend_reply = "Thank you for using the ChefDrobe!" products = list(/obj/item/clothing/under/suit/waiter = 3, /obj/item/radio/headset/headset_srv = 4, /obj/item/clothing/accessory/waistcoat = 3, @@ -358,8 +311,6 @@ /obj/item/book/granter/crafting_recipe/coldcooking = 2) refill_canister = /obj/item/vending_refill/wardrobe/chef_wardrobe payment_department = ACCOUNT_SRV - cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) - /obj/item/vending_refill/wardrobe/chef_wardrobe machine_name = "ChefDrobe" @@ -390,8 +341,10 @@ /obj/item/screwdriver = 2, /obj/item/stack/cable_coil/random = 4) refill_canister = /obj/item/vending_refill/wardrobe/jani_wardrobe + default_price = PRICE_CHEAP + extra_price = PRICE_EXPENSIVE * 0.8 payment_department = ACCOUNT_SRV - cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) + light_color = COLOR_STRONG_MAGENTA /obj/item/vending_refill/wardrobe/jani_wardrobe machine_name = "JaniDrobe" @@ -423,18 +376,16 @@ /obj/item/clothing/shoes/laceup = 3, /obj/item/clothing/accessory/lawyers_badge = 3) refill_canister = /obj/item/vending_refill/wardrobe/law_wardrobe - payment_department = ACCOUNT_CIV - cost_multiplier_per_dept = list(ACCOUNT_CIV = 0) - + payment_department = ACCOUNT_SRV /obj/item/vending_refill/wardrobe/law_wardrobe machine_name = "LawDrobe" /obj/machinery/vending/wardrobe/chap_wardrobe - name = "ChapDrobe" - desc = "This most blessed and holy machine vends clothing only suitable for chaplains to gaze upon." + name = "DeusVend" + desc = "God wills your purchase." icon_state = "chapdrobe" product_ads = "Are you being bothered by cultists or pesky revenants? Then come and dress like the holy man!;Clothes for men of the cloth!" - vend_reply = "Thank you for using the ChapDrobe!" + vend_reply = "Thank you for using the DeusVend!" products = list(/obj/item/choice_beacon/holy = 1, /obj/item/storage/backpack/cultpack = 2, /obj/item/clothing/accessory/pocketprotector/cosmetology = 2, @@ -451,11 +402,9 @@ premium = list(/obj/item/toy/plush/plushvar = 1, /obj/item/toy/plush/narplush = 1) refill_canister = /obj/item/vending_refill/wardrobe/chap_wardrobe - payment_department = ACCOUNT_CIV - cost_multiplier_per_dept = list(ACCOUNT_CIV = 0) - + payment_department = ACCOUNT_SRV /obj/item/vending_refill/wardrobe/chap_wardrobe - machine_name = "ChapDrobe" + machine_name = "DeusVend" /obj/machinery/vending/wardrobe/chem_wardrobe name = "ChemDrobe" @@ -475,8 +424,6 @@ /obj/item/fermichem/pHbooklet = 3) refill_canister = /obj/item/vending_refill/wardrobe/chem_wardrobe payment_department = ACCOUNT_MED - cost_multiplier_per_dept = list(ACCOUNT_MED = 0) - /obj/item/vending_refill/wardrobe/chem_wardrobe machine_name = "ChemDrobe" @@ -494,9 +441,7 @@ /obj/item/storage/backpack/genetics = 3, /obj/item/storage/backpack/satchel/gen = 3) refill_canister = /obj/item/vending_refill/wardrobe/gene_wardrobe - payment_department = ACCOUNT_MED - cost_multiplier_per_dept = list(ACCOUNT_MED = 0) - + payment_department = ACCOUNT_SCI /obj/item/vending_refill/wardrobe/gene_wardrobe machine_name = "GeneDrobe" @@ -517,11 +462,46 @@ /obj/item/storage/backpack/satchel/vir = 3) refill_canister = /obj/item/vending_refill/wardrobe/viro_wardrobe payment_department = ACCOUNT_MED - cost_multiplier_per_dept = list(ACCOUNT_MED = 0) - /obj/item/vending_refill/wardrobe/viro_wardrobe machine_name = "ViroDrobe" +/obj/machinery/vending/wardrobe/det_wardrobe + name = "\improper DetDrobe" + desc = "A machine for all your detective needs, as long as you need clothes." + icon_state = "detdrobe" + product_ads = "Apply your brilliant deductive methods in style!" + vend_reply = "Thank you for using the DetDrobe!" + products = list(/obj/item/clothing/under/rank/security/detective = 2, + /obj/item/clothing/under/rank/security/detective/skirt = 2, + /obj/item/clothing/under/rank/security/detective/brown = 2, + /obj/item/clothing/under/rank/security/detective/brown/brown2 = 2, + /obj/item/clothing/under/rank/security/officer/blueshirt/seccorp/detcorp = 2, + /obj/item/clothing/under/rank/security/officer/util = 2, + /obj/item/clothing/shoes/sneakers/brown = 2, + /obj/item/clothing/suit/det_suit = 2, + /obj/item/clothing/head/fedora/det_hat = 2, + /obj/item/clothing/under/rank/security/detective/grey = 2, + /obj/item/clothing/under/rank/security/detective/grey/skirt = 2, + /obj/item/clothing/accessory/waistcoat = 2, + /obj/item/clothing/shoes/laceup = 2, + /obj/item/clothing/suit/det_suit/grey = 1, + /obj/item/clothing/suit/det_suit/forensicsred = 1, + /obj/item/clothing/suit/det_suit/forensicsred/long = 1, + /obj/item/clothing/suit/det_suit/forensicsblue = 1, + /obj/item/clothing/suit/det_suit/forensicsblue/long = 1, + /obj/item/clothing/head/fedora = 2, + /obj/item/clothing/gloves/color/black = 2, + /obj/item/clothing/gloves/color/latex = 2, + /obj/item/reagent_containers/food/drinks/flask/det = 2, + /obj/item/storage/fancy/cigarettes = 5) + premium = list(/obj/item/clothing/head/flatcap = 1) + refill_canister = /obj/item/vending_refill/wardrobe/det_wardrobe + extra_price = PRICE_EXPENSIVE * 1.75 + payment_department = ACCOUNT_SEC + +/obj/item/vending_refill/wardrobe/det_wardrobe + machine_name = "DetDrobe" + /obj/machinery/vending/wardrobe/cap_wardrobe name = "Captain's Wardrobe" desc = "The latest and greatest in Nanotrasen fashion for your great leader." @@ -552,10 +532,6 @@ default_price = PRICE_ALMOST_EXPENSIVE extra_price = PRICE_ABOVE_EXPENSIVE -/obj/machinery/vending/wardrobe/cap_wardrobe/Initialize() - . = ..() - cost_multiplier_per_dept = list("[ACCESS_CAPTAIN]" = 0) - /obj/item/vending_refill/wardrobe/cap_wardrobe machine_name = "Captain's Wardrobe" icon_state = "refill_caps" diff --git a/code/modules/vending/youtool.dm b/code/modules/vending/youtool.dm index 2119197aed..4b8a8c27e5 100644 --- a/code/modules/vending/youtool.dm +++ b/code/modules/vending/youtool.dm @@ -3,6 +3,7 @@ desc = "Tools for tools." icon_state = "tool" icon_deny = "tool-deny" + light_mask = "tool-light-mask" products = list(/obj/item/stack/cable_coil/random = 15, /obj/item/crowbar = 10, /obj/item/weldingtool = 6, @@ -19,13 +20,11 @@ /obj/item/multitool = 2) premium = list(/obj/item/clothing/gloves/color/yellow = 2, /obj/item/weldingtool/hugetank = 2) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70) - refill_canister = /obj/item/vending_refill/tool - resistance_flags = FIRE_PROOF + refill_canister = /obj/item/vending_refill/youtool default_price = PRICE_REALLY_CHEAP extra_price = PRICE_EXPENSIVE payment_department = ACCOUNT_ENG - cost_multiplier_per_dept = list(ACCOUNT_ENG = 0) -/obj/item/vending_refill/tool +/obj/item/vending_refill/youtool + machine_name = "YouTool" icon_state = "refill_engi" diff --git a/code/modules/vore/eating/belly_obj.dm b/code/modules/vore/eating/belly_obj.dm index 8e74dd3c92..07e01e4580 100644 --- a/code/modules/vore/eating/belly_obj.dm +++ b/code/modules/vore/eating/belly_obj.dm @@ -147,7 +147,7 @@ //ommitted list // "shrink_grow_size", -/obj/belly/Initialize() +/obj/belly/Initialize(mapload) . = ..() take_ownership(src.loc) @@ -278,14 +278,14 @@ SEND_SIGNAL(OW, COMSIG_ADD_MOOD_EVENT, "emptypred", /datum/mood_event/emptypred) SEND_SIGNAL(ML, COMSIG_ADD_MOOD_EVENT, "emptyprey", /datum/mood_event/emptyprey) - if(CHECK_BITFIELD(ML.vore_flags,ABSORBED)) - DISABLE_BITFIELD(ML.vore_flags,ABSORBED) + if((ML.vore_flags & ABSORBED)) + ML.vore_flags &= ~(ABSORBED) if(ishuman(M) && ishuman(OW)) var/mob/living/carbon/human/Prey = M var/mob/living/carbon/human/Pred = OW var/absorbed_count = 2 //Prey that we were, plus the pred gets a portion for(var/mob/living/P in contents) - if(CHECK_BITFIELD(P.vore_flags,ABSORBED)) + if((P.vore_flags & ABSORBED)) absorbed_count++ Pred.reagents.trans_to(Prey, Pred.reagents.total_volume / absorbed_count) @@ -390,7 +390,7 @@ formatted_message = replacetext(formatted_message,"%pred",owner) formatted_message = replacetext(formatted_message,"%prey",english_list(contents)) for(var/mob/living/P in contents) - if(!CHECK_BITFIELD(P.vore_flags, ABSORBED)) //This is required first, in case there's a person absorbed and not absorbed in a stomach. + if(!(P.vore_flags & ABSORBED)) //This is required first, in case there's a person absorbed and not absorbed in a stomach. total_bulge += P.mob_size if(total_bulge >= bulge_size && bulge_size != 0) return("[formatted_message]
    ") @@ -485,7 +485,7 @@ // Handle a mob being absorbed /obj/belly/proc/absorb_living(var/mob/living/M) - ENABLE_BITFIELD(M.vore_flags, ABSORBED) + M.vore_flags |= ABSORBED to_chat(M,"[owner]'s [lowertext(name)] absorbs your body, making you part of them.") to_chat(owner,"Your [lowertext(name)] absorbs [M]'s body, making them part of you.") @@ -499,7 +499,7 @@ for(var/belly in M.vore_organs) var/obj/belly/B = belly for(var/mob/living/Mm in B) - if(CHECK_BITFIELD(Mm.vore_flags, ABSORBED)) + if((Mm.vore_flags & ABSORBED)) absorb_living(Mm) //Update owner @@ -539,7 +539,7 @@ //Handle a mob struggling // Called from /mob/living/carbon/relaymove() -/obj/belly/proc/relay_resist(var/mob/living/R) +/obj/belly/proc/relay_resist(mob/living/R) if (!(R in contents)) return // User is not in this belly @@ -547,7 +547,7 @@ to_chat(R,"You attempt to climb out of \the [lowertext(name)]. (This will take around [escapetime/10] seconds.)") to_chat(owner,"Someone is attempting to climb out of your [lowertext(name)]!") - if(do_after(R, owner, escapetime)) + if(do_after(R, escapetime, owner, (IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM))) if((owner.stat || escapable) && (R.loc == src)) //Can still escape? release_specific_contents(R) return @@ -604,7 +604,7 @@ if(prob(escapechance)) //Let's have it check to see if the prey escapes first. to_chat(R,"You start to climb out of \the [lowertext(name)].") to_chat(owner,"Someone is attempting to climb out of your [lowertext(name)]!") - if(do_after(R, escapetime)) + if(do_after(R, escapetime, owner, (IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM))) if((escapable) && (R.loc == src)) //Can still escape? release_specific_contents(R) to_chat(R,"You climb out of \the [lowertext(name)].") diff --git a/code/modules/vore/eating/bellymodes.dm b/code/modules/vore/eating/bellymodes.dm index 8d64ee28f1..7828de8cde 100644 --- a/code/modules/vore/eating/bellymodes.dm +++ b/code/modules/vore/eating/bellymodes.dm @@ -76,7 +76,7 @@ play_sound = pick(pred_digest) //Pref protection! - if (!CHECK_BITFIELD(M.vore_flags, DIGESTABLE) || M.vore_flags & ABSORBED) + if (!(M.vore_flags & DIGESTABLE) || M.vore_flags & ABSORBED) continue //Person just died in guts! @@ -165,7 +165,7 @@ for (var/mob/living/M in contents) if(M.vore_flags & ABSORBED && owner.nutrition >= 100) - DISABLE_BITFIELD(M.vore_flags, ABSORBED) + M.vore_flags &= ~(ABSORBED) to_chat(M,"You suddenly feel solid again ") to_chat(owner,"You feel like a part of you is missing.") owner.adjust_nutrition(-100) diff --git a/code/modules/vore/eating/living.dm b/code/modules/vore/eating/living.dm index 6bc44e6489..d5a3627684 100644 --- a/code/modules/vore/eating/living.dm +++ b/code/modules/vore/eating/living.dm @@ -18,7 +18,7 @@ // Hook for generic creation of stuff on new creatures // /hook/living_new/proc/vore_setup(mob/living/M) - add_verb(M, list(/mob/living/proc/preyloop_refresh, /mob/living/proc/lick, /mob/living/proc/smell, /mob/living/proc/escapeOOC)) + add_verb(M, list(/mob/living/proc/preyloop_refresh, /mob/living/proc/lick, /mob/living/proc/smell_someone, /mob/living/proc/escapeOOC)) if(M.vore_flags & NO_VORE) //If the mob isn't supposed to have a stomach, let's not give it an insidepanel so it can make one for itself, or a stomach. return TRUE @@ -33,7 +33,7 @@ return TRUE /mob/living/proc/init_vore() - ENABLE_BITFIELD(vore_flags, VORE_INIT) + vore_flags |= VORE_INIT //Something else made organs, meanwhile. if(LAZYLEN(vore_organs)) return TRUE @@ -75,7 +75,7 @@ lazy_init_belly() if(pred == prey) //you click your target - if(!CHECK_BITFIELD(pred.vore_flags,FEEDING)) + if(!(pred.vore_flags & FEEDING)) to_chat(user, "They aren't able to be fed.") to_chat(pred, "[user] tried to feed you themselves, but you aren't voracious enough to be fed.") return @@ -85,11 +85,11 @@ feed_grabbed_to_self(user, prey) else // click someone other than you/prey - if(!CHECK_BITFIELD(pred.vore_flags,FEEDING)) + if(!(pred.vore_flags & FEEDING)) to_chat(user, "They aren't voracious enough to be fed.") to_chat(pred, "[user] tried to feed you [prey], but you aren't voracious enough to be fed.") return - if(!CHECK_BITFIELD(prey.vore_flags,FEEDING)) + if(!(prey.vore_flags & FEEDING)) to_chat(user, "They aren't able to be fed to someone.") to_chat(prey, "[user] tried to feed you to [pred], but you aren't able to be fed to them.") return @@ -122,7 +122,7 @@ testing("[user] attempted to feed [prey] to [pred], via [lowertext(belly.name)] but it went wrong.") return - if (!CHECK_BITFIELD(prey.vore_flags, DEVOURABLE)) + if (!(prey.vore_flags & DEVOURABLE)) to_chat(user, "This can't be eaten!") return FALSE @@ -152,7 +152,7 @@ swallow_time = istype(prey, /mob/living/carbon/human) ? belly.human_prey_swallow_time : belly.nonhuman_prey_swallow_time //Timer and progress bar - if(!do_after(user, swallow_time, TRUE, prey)) + if(!do_after(user, swallow_time, prey)) return FALSE // Prey escaped (or user disabled) before timer expired. if(!prey.Adjacent(user)) //double check'd just in case they moved during the timer and the do_mob didn't fail for whatever reason @@ -283,7 +283,7 @@ if(!client || !client.prefs) to_chat(src,"You attempted to apply your vore prefs but somehow you're in this character without a client.prefs variable. Tell a dev.") return FALSE - ENABLE_BITFIELD(vore_flags,VOREPREF_INIT) + vore_flags |= VOREPREF_INIT COPY_SPECIFIC_BITFIELDS(vore_flags, client.prefs.vore_flags, DIGESTABLE | DEVOURABLE | FEEDING | LICKABLE | SMELLABLE | ABSORBABLE | MOBVORE) vore_taste = client.prefs.vore_taste vore_smell = client.prefs.vore_smell @@ -394,7 +394,7 @@ // // Equally important as the above // -/mob/living/proc/smell() +/mob/living/proc/smell_someone() set name = "Smell Someone" set category = "Vore" set desc = "Smell someone nearby!" diff --git a/code/modules/vore/eating/vorepanel.dm b/code/modules/vore/eating/vorepanel.dm index 8e8cfc4935..a44760ae69 100644 --- a/code/modules/vore/eating/vorepanel.dm +++ b/code/modules/vore/eating/vorepanel.dm @@ -181,15 +181,15 @@ data["selected"] = selected_list data["prefs"] = list( - "digestable" = CHECK_BITFIELD(host.vore_flags, DIGESTABLE), - "devourable" = CHECK_BITFIELD(host.vore_flags, DEVOURABLE), - "feeding" = CHECK_BITFIELD(host.vore_flags, FEEDING), - "absorbable" = CHECK_BITFIELD(host.vore_flags, ABSORBABLE), - "allowmobvore" = CHECK_BITFIELD(host.vore_flags, MOBVORE), - "vore_sounds" = CHECK_BITFIELD(host.client.prefs.cit_toggles, EATING_NOISES), - "digestion_sounds" = CHECK_BITFIELD(host.client.prefs.cit_toggles, DIGESTION_NOISES), - "lickable" = CHECK_BITFIELD(host.vore_flags, LICKABLE), - "smellable" = CHECK_BITFIELD(host.vore_flags, SMELLABLE), + "digestable" = (host.vore_flags & DIGESTABLE), + "devourable" = (host.vore_flags & DEVOURABLE), + "feeding" = (host.vore_flags & FEEDING), + "absorbable" = (host.vore_flags & ABSORBABLE), + "allowmobvore" = (host.vore_flags & MOBVORE), + "vore_sounds" = (host.client.prefs.cit_toggles & EATING_NOISES), + "digestion_sounds" = (host.client.prefs.cit_toggles & DIGESTION_NOISES), + "lickable" = (host.vore_flags & LICKABLE), + "smellable" = (host.vore_flags & SMELLABLE), ) return data @@ -307,49 +307,49 @@ unsaved_changes = TRUE return TRUE if("toggle_digest") - TOGGLE_BITFIELD(host.vore_flags, DIGESTABLE) + (host.vore_flags ^= DIGESTABLE) if(host.client.prefs) COPY_SPECIFIC_BITFIELDS(host.client.prefs.vore_flags, host.vore_flags, DIGESTABLE) unsaved_changes = TRUE return TRUE if("toggle_devour") - TOGGLE_BITFIELD(host.vore_flags, DEVOURABLE) + (host.vore_flags ^= DEVOURABLE) if(host.client.prefs) COPY_SPECIFIC_BITFIELDS(host.client.prefs.vore_flags, host.vore_flags, DEVOURABLE) unsaved_changes = TRUE return TRUE if("toggle_feed") - TOGGLE_BITFIELD(host.vore_flags, FEEDING) + (host.vore_flags ^= FEEDING) if(host.client.prefs) COPY_SPECIFIC_BITFIELDS(host.client.prefs.vore_flags, host.vore_flags, FEEDING) unsaved_changes = TRUE return TRUE if("toggle_absorbable") - TOGGLE_BITFIELD(host.vore_flags, ABSORBABLE) + (host.vore_flags ^= ABSORBABLE) if(host.client.prefs) COPY_SPECIFIC_BITFIELDS(host.client.prefs.vore_flags, host.vore_flags, ABSORBABLE) unsaved_changes = TRUE return TRUE if("toggle_mobvore") - TOGGLE_BITFIELD(host.vore_flags, MOBVORE) + (host.vore_flags ^= MOBVORE) if(host.client.prefs) COPY_SPECIFIC_BITFIELDS(host.client.prefs.vore_flags, host.vore_flags, MOBVORE) unsaved_changes = TRUE return TRUE if("toggle_vore_sounds") - TOGGLE_BITFIELD(host.client.prefs.cit_toggles, EATING_NOISES) + (host.client.prefs.cit_toggles ^= EATING_NOISES) unsaved_changes = TRUE return TRUE if("toggle_digestion_sounds") - TOGGLE_BITFIELD(host.client.prefs.cit_toggles, DIGESTION_NOISES) + (host.client.prefs.cit_toggles ^= DIGESTION_NOISES) unsaved_changes = TRUE return TRUE if("toggle_lickable") - TOGGLE_BITFIELD(host.vore_flags, LICKABLE) + (host.vore_flags ^= LICKABLE) unsaved_changes = TRUE return TRUE if("toggle_smellable") - TOGGLE_BITFIELD(host.vore_flags, SMELLABLE) + (host.vore_flags ^= SMELLABLE) unsaved_changes = TRUE return TRUE diff --git a/code/modules/wiremod/components/abstract/compare.dm b/code/modules/wiremod/components/abstract/compare.dm new file mode 100644 index 0000000000..7523b7801a --- /dev/null +++ b/code/modules/wiremod/components/abstract/compare.dm @@ -0,0 +1,58 @@ +/** + * # Compare Component + * + * Abstract component to build conditional components + */ +/obj/item/circuit_component/compare + display_name = "Compare" + + /// The amount of input ports to have + var/input_port_amount = 4 + + /// The trigger for the true/false signals + var/datum/port/input/compare + + /// Signals sent on compare + var/datum/port/output/true + var/datum/port/output/false + + /// The result from the output + var/datum/port/output/result + + var/list/datum/port/input/compare_ports = list() + +/obj/item/circuit_component/compare/Initialize(mapload) + . = ..() + for(var/port_id in 1 to input_port_amount) + var/letter = ascii2text(text2ascii("A") + (port_id-1)) + compare_ports += add_input_port(letter, PORT_TYPE_ANY) + + load_custom_ports() + compare = add_input_port("Compare", PORT_TYPE_SIGNAL) + + true = add_output_port("True", PORT_TYPE_SIGNAL) + false = add_output_port("False", PORT_TYPE_SIGNAL) + result = add_output_port("Result", PORT_TYPE_NUMBER) + +/** + * Used by derivatives to load their own ports in for custom use. + */ +/obj/item/circuit_component/compare/proc/load_custom_ports() + return + +/obj/item/circuit_component/compare/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/logic_result = do_comparisons(compare_ports) + if(COMPONENT_TRIGGERED_BY(compare, port)) + if(logic_result) + true.set_output(COMPONENT_SIGNAL) + else + false.set_output(COMPONENT_SIGNAL) + result.set_output(logic_result) + +/// Do the comparisons and return a result +/obj/item/circuit_component/compare/proc/do_comparisons(list/ports) + return FALSE diff --git a/code/modules/wiremod/components/abstract/module.dm b/code/modules/wiremod/components/abstract/module.dm new file mode 100644 index 0000000000..970b893ac3 --- /dev/null +++ b/code/modules/wiremod/components/abstract/module.dm @@ -0,0 +1,306 @@ +/** + * # Module Component + * + * A component that has an input, output + */ +/obj/item/circuit_component/module + display_name = "Module" + desc = "A component that has other components within it, acting like a function. Use it in your hand to control the amount of input and output ports it has, as well as being able to access the integrated circuit contained inside." + + var/obj/item/integrated_circuit/module/internal_circuit + + var/obj/item/circuit_component/module_input/input_component + var/obj/item/circuit_component/module_output/output_component + + /// Linked ports that follow a `first_port = second_port` keyed structure. + var/list/linked_ports = list() + + var/port_limit = 10 + +/obj/item/integrated_circuit/module + var/obj/item/circuit_component/module/attached_module + +/obj/item/integrated_circuit/module/ui_host(mob/user) + . = ..() + if(. == src) + return attached_module + +/obj/item/integrated_circuit/module/set_display_name(new_name) + . = ..() + attached_module.display_name = new_name + attached_module.name = "module ([new_name])" + +/obj/item/integrated_circuit/module/load_component(type) + if(!attached_module) + return ..() + + if(ispath(type, /obj/item/circuit_component/module_input)) + return attached_module.input_component + + if(ispath(type, /obj/item/circuit_component/module_output)) + return attached_module.output_component + + return ..() + +/obj/item/integrated_circuit/module/Destroy() + attached_module = null + return ..() + +/obj/item/circuit_component/module_input + display_name = "Input" + desc = "A component that receives data from the module it is attached to" + + removable = FALSE + + /// The currently attached module + var/obj/item/circuit_component/module/attached_module + +/obj/item/circuit_component/module_input/Destroy() + attached_module = null + return ..() + +/obj/item/circuit_component/module_output + display_name = "Output" + desc = "A component that outputs data to the module it is attached to." + + removable = FALSE + + /// The currently attached module + var/obj/item/circuit_component/module/attached_module + +/obj/item/circuit_component/module_output/input_received(datum/port/input/port) + . = ..() + if(!port) + return + // We don't check the parent here because frankly, we don't care. We only sync our input with the module's output + var/datum/port/output/port_to_update = attached_module.linked_ports[port] + if(!port_to_update) + CRASH("[port.type] doesn't have a linked port in [type]!") + + port_to_update.set_output(port.value) + +/obj/item/circuit_component/module/input_received(datum/port/input/port) + . = ..() + if(!port) + return + var/datum/port/output/port_to_update = linked_ports[port] + if(!port_to_update) + CRASH("[port.type] doesn't have a linked port in [type]!") + + port_to_update.set_output(port.value) + +/obj/item/circuit_component/module_output/Destroy() + attached_module = null + return ..() + +/obj/item/circuit_component/module/Initialize(mapload) + . = ..() + internal_circuit = new(src) + internal_circuit.attached_module = src + + input_component = new(internal_circuit) + input_component.attached_module = src + internal_circuit.add_component(input_component) + input_component.rel_x = 0 + input_component.rel_y = 200 + + output_component = new(internal_circuit) + output_component.attached_module = src + internal_circuit.add_component(output_component) + output_component.rel_x = 400 + output_component.rel_y = 200 + +/obj/item/circuit_component/module/save_data_to_list(list/component_data) + . = ..() + component_data["integrated_circuit"] = internal_circuit.convert_to_json() + + var/list/input_data = list() + for(var/datum/port/input/input_port as anything in input_ports) + input_data += list(list( + "name" = input_port.name, + "type" = input_port.datatype, + )) + + var/list/output_data = list() + for(var/datum/port/output/output_port as anything in output_ports) + output_data += list(list( + "name" = output_port.name, + "type" = output_port.datatype, + )) + + component_data["input_ports"] = input_data + component_data["output_ports"] = output_data + +/obj/item/circuit_component/module/load_data_from_list(list/component_data) + . = ..() + + var/list/input_ports = component_data["input_ports"] + for(var/list/port_data as anything in input_ports) + add_and_link_input_port(port_data["name"], port_data["type"]) + + var/list/output_ports = component_data["output_ports"] + for(var/list/port_data as anything in output_ports) + add_and_link_output_port(port_data["name"], port_data["type"]) + + if(component_data["integrated_circuit"]) + internal_circuit.load_circuit_data(component_data["integrated_circuit"]) + +/obj/item/circuit_component/module/proc/add_and_link_input_port(name, type) + var/datum/port/new_port = add_input_port(name, type) + linked_ports[new_port] = input_component.add_output_port(name, type) + +/obj/item/circuit_component/module/proc/add_and_link_output_port(name, type) + var/datum/port/new_port = output_component.add_input_port(name, type) + linked_ports[new_port] = add_output_port(name, type) + +/obj/item/circuit_component/module/add_to(obj/item/integrated_circuit/added_to) + . = ..() + RegisterSignal(added_to, COMSIG_CIRCUIT_SET_CELL, .proc/handle_set_cell) + RegisterSignal(added_to, COMSIG_CIRCUIT_SET_ON, .proc/handle_set_on) + RegisterSignal(added_to, COMSIG_CIRCUIT_SET_SHELL, .proc/handle_set_shell) + internal_circuit.set_cell(added_to.cell) + internal_circuit.set_shell(added_to.shell) + internal_circuit.set_on(added_to.on) + + +/obj/item/circuit_component/module/removed_from(obj/item/integrated_circuit/removed_from) + internal_circuit.set_cell(null) + internal_circuit.set_on(FALSE) + internal_circuit.remove_current_shell() + UnregisterSignal(removed_from, list( + COMSIG_CIRCUIT_SET_CELL, + COMSIG_CIRCUIT_SET_ON, + COMSIG_CIRCUIT_SET_SHELL, + )) + return ..() + +/obj/item/circuit_component/module/proc/handle_set_cell(datum/source, obj/item/stock_parts/cell/cell) + SIGNAL_HANDLER + internal_circuit.set_cell(cell) + +/obj/item/circuit_component/module/proc/handle_set_on(datum/source, new_value) + SIGNAL_HANDLER + internal_circuit.set_on(new_value) + +/obj/item/circuit_component/module/proc/handle_set_shell(datum/source, atom/movable/new_shell) + SIGNAL_HANDLER + internal_circuit.set_shell(new_shell) + +/obj/item/circuit_component/module/Destroy() + QDEL_NULL(input_component) + QDEL_NULL(output_component) + QDEL_NULL(internal_circuit) + linked_ports = null + return ..() + +/obj/item/circuit_component/module/ui_data(mob/user) + . = list() + .["input_ports"] = list() + for(var/datum/port/input/input_port as anything in input_ports) + .["input_ports"] += list(list( + "name" = input_port.name, + "type" = input_port.datatype, + )) + + .["output_ports"] = list() + for(var/datum/port/output/output_port as anything in output_ports) + .["output_ports"] += list(list( + "name" = output_port.name, + "type" = output_port.datatype, + )) + +/obj/item/circuit_component/module/ui_static_data(mob/user) + . = list() + .["global_port_types"] = GLOB.wiremod_basic_types + +/obj/item/circuit_component/module/attackby(obj/item/I, mob/living/user, params) + if(istype(I, /obj/item/circuit_component)) + internal_circuit.attackby(I, user, params) + return + return ..() + +#define WITHIN_RANGE(id, table) (id >= 1 && id <= length(table)) + +/obj/item/circuit_component/module/ui_act(action, list/params) + . = ..() + if(.) + return + + switch(action) + if("open_internal_circuit") + internal_circuit.interact(usr) + . = TRUE + if("add_input_port") + if(length(input_ports) > port_limit) + return + add_and_link_input_port("Input Port", PORT_TYPE_ANY) + . = TRUE + if("remove_input_port") + var/port_id = text2num(params["port_id"]) + if(!WITHIN_RANGE(port_id, input_ports)) + return + var/datum/port/removed_port = input_ports[port_id] + linked_ports -= removed_port + remove_input_port(removed_port) + input_component.remove_output_port(input_component.output_ports[port_id]) + . = TRUE + if("add_output_port") + if(length(output_ports) > port_limit) + return + add_and_link_output_port("Output Port", PORT_TYPE_ANY) + . = TRUE + if("remove_output_port") + var/port_id = text2num(params["port_id"]) + if(!WITHIN_RANGE(port_id, output_ports)) + return + + var/datum/port/removed_port = output_component.input_ports[port_id] + linked_ports -= removed_port + remove_output_port(output_ports[port_id]) + output_component.remove_input_port(removed_port) + . = TRUE + if("set_port_name", "set_port_type") + var/port_id = text2num(params["port_id"]) + var/is_input = params["is_input"] + + var/list/ports_to_use + var/list/internal_ports_to_use + if(is_input) + ports_to_use = input_ports + internal_ports_to_use = input_component.output_ports + else + ports_to_use = output_ports + internal_ports_to_use = output_component.input_ports + + if(!WITHIN_RANGE(port_id, ports_to_use)) + return + + var/datum/port/component_port = ports_to_use[port_id] + var/datum/port/internal_component_port = internal_ports_to_use[port_id] + + if(action == "set_port_type") + var/type = params["port_type"] + if(!(type in GLOB.wiremod_basic_types)) + return + component_port.set_datatype(type) + internal_component_port.set_datatype(type) + else + var/port_name = params["port_name"] + if(!port_name) + return + port_name = strip_html(port_name, PORT_MAX_NAME_LENGTH) + component_port.name = port_name + internal_component_port.name = port_name + . = TRUE + + if(.) + SStgui.update_uis(internal_circuit) + +#undef WITHIN_RANGE + +/obj/item/circuit_component/module/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "CircuitModule", name) + ui.open() + ui.set_autoupdate(FALSE) diff --git a/code/modules/wiremod/components/action/light.dm b/code/modules/wiremod/components/action/light.dm new file mode 100644 index 0000000000..11c40983c3 --- /dev/null +++ b/code/modules/wiremod/components/action/light.dm @@ -0,0 +1,68 @@ +/** + * # Light Component + * + * Emits a light of a specific brightness and colour. Requires a shell. + */ +/obj/item/circuit_component/light + display_name = "Light" + desc = "A component that emits a light of a specific brightness and colour. Requires a shell." + + /// The colours of the light + var/datum/port/input/red + var/datum/port/input/green + var/datum/port/input/blue + + /// The brightness + var/datum/port/input/brightness + + /// Whether the light is on or not + var/datum/port/input/on + + var/max_power = 5 + var/min_lightness = 0.4 + var/shell_light_color + +/obj/item/circuit_component/light/get_ui_notices() + . = ..() + . += create_ui_notice("Maximum Brightness: [max_power]", "orange", "lightbulb") + +/obj/item/circuit_component/light/Initialize(mapload) + . = ..() + red = add_input_port("Red", PORT_TYPE_NUMBER) + green = add_input_port("Green", PORT_TYPE_NUMBER) + blue = add_input_port("Blue", PORT_TYPE_NUMBER) + brightness = add_input_port("Brightness", PORT_TYPE_NUMBER) + + on = add_input_port("On", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/light/register_shell(atom/movable/shell) + . = ..() + TRIGGER_CIRCUIT_COMPONENT(src, null) + +/obj/item/circuit_component/light/unregister_shell(atom/movable/shell) + shell.set_light_on(FALSE) + return ..() + +/obj/item/circuit_component/light/input_received(datum/port/input/port) + . = ..() + brightness.set_value(clamp(brightness.value || 0, 0, max_power)) + 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/list/hsl = rgb2hsl(red.value || 0, green.value || 0, blue.value || 0) + var/list/light_col = hsl2rgb(hsl[1], hsl[2], max(min_lightness, hsl[3])) + shell_light_color = rgb(light_col[1], light_col[2], light_col[3]) + if(.) + return + + if(parent.shell) + set_atom_light(parent.shell) + +/obj/item/circuit_component/light/proc/set_atom_light(atom/movable/target_atom) + // Clamp anyways just for safety + var/bright_val = min(max(brightness.value || 0, 0), max_power) + + target_atom.set_light_power(bright_val) + target_atom.set_light_range(bright_val) + target_atom.set_light_color(shell_light_color) + target_atom.set_light_on(!!on.value) diff --git a/code/modules/wiremod/components/action/mmi.dm b/code/modules/wiremod/components/action/mmi.dm new file mode 100644 index 0000000000..b67f48f559 --- /dev/null +++ b/code/modules/wiremod/components/action/mmi.dm @@ -0,0 +1,175 @@ +/** + * # Man-Machine Interface Component + * + * Allows an MMI to be inserted into a shell, allowing it to be linked up. Requires a shell. + */ +/obj/item/circuit_component/mmi + display_name = "Man-Machine Interface" + desc = "A component that allows MMI to enter shells to send output signals." + + /// The message to send to the MMI in the shell. + var/datum/port/input/message + /// Sends the current MMI a message + var/datum/port/input/send + /// Ejects the current MMI + var/datum/port/input/eject + + /// Called when the MMI tries moving north + var/datum/port/output/north + /// Called when the MMI tries moving east + var/datum/port/output/east + /// Called when the MMI tries moving south + var/datum/port/output/south + /// Called when the MMI tries moving west + var/datum/port/output/west + + /// Returns what the MMI last clicked on. + var/datum/port/output/clicked_atom + /// Called when the MMI clicks. + var/datum/port/output/attack + /// Called when the MMI right clicks. + var/datum/port/output/secondary_attack + + /// The current MMI card + var/obj/item/mmi/brain + + /// Maximum length of the message that can be sent to the MMI + var/max_length = 300 + +/obj/item/circuit_component/mmi/Initialize(mapload) + . = ..() + message = add_input_port("Message", PORT_TYPE_STRING) + send = add_input_port("Send Message", PORT_TYPE_SIGNAL) + eject = add_input_port("Eject", PORT_TYPE_SIGNAL) + + north = add_output_port("North", PORT_TYPE_SIGNAL) + east = add_output_port("East", PORT_TYPE_SIGNAL) + south = add_output_port("South", PORT_TYPE_SIGNAL) + west = add_output_port("West", PORT_TYPE_SIGNAL) + + attack = add_output_port("Attack", PORT_TYPE_SIGNAL) + secondary_attack = add_output_port("Secondary Attack", PORT_TYPE_SIGNAL) + clicked_atom = add_output_port("Target Entity", PORT_TYPE_ATOM) + +/obj/item/circuit_component/mmi/Destroy() + remove_current_brain() + return ..() + +/obj/item/circuit_component/mmi/input_received(datum/port/input/port) + . = ..() + if(.) + return + + if(!brain) + return + + if(COMPONENT_TRIGGERED_BY(eject, port)) + remove_current_brain() + if(COMPONENT_TRIGGERED_BY(send, port)) + if(!message.value) + return + + var/msg_str = copytext(html_encode(message.value), 1, max_length) + + var/mob/living/target = brain.brainmob + if(!target) + return + + to_chat(target, "[span_bold("You hear a message in your ear: ")][msg_str]") + + +/obj/item/circuit_component/mmi/register_shell(atom/movable/shell) + . = ..() + RegisterSignal(shell, COMSIG_PARENT_ATTACKBY, .proc/handle_attack_by) + +/obj/item/circuit_component/mmi/unregister_shell(atom/movable/shell) + UnregisterSignal(shell, COMSIG_PARENT_ATTACKBY) + remove_current_brain() + return ..() + +/obj/item/circuit_component/mmi/proc/handle_attack_by(atom/movable/shell, obj/item/item, mob/living/attacker) + SIGNAL_HANDLER + if(istype(item, /obj/item/mmi)) + var/obj/item/mmi/target_mmi = item + if(!target_mmi.brainmob) + return + add_mmi(item) + return COMPONENT_NO_AFTERATTACK + +/obj/item/circuit_component/mmi/proc/add_mmi(obj/item/mmi/to_add) + remove_current_brain() + + to_add.forceMove(src) + if(to_add.brainmob) + update_mmi_mob(to_add, null, to_add.brainmob) + brain = to_add + RegisterSignal(to_add, COMSIG_PARENT_QDELETING, .proc/remove_current_brain) + RegisterSignal(to_add, COMSIG_MOVABLE_MOVED, .proc/mmi_moved) + +/obj/item/circuit_component/mmi/proc/mmi_moved(atom/movable/mmi) + SIGNAL_HANDLER + + if(mmi.loc != src) + remove_current_brain() + +/obj/item/circuit_component/mmi/proc/remove_current_brain() + SIGNAL_HANDLER + if(!brain) + return + + if(brain.brainmob) + update_mmi_mob(brain, brain.brainmob) + UnregisterSignal(brain, list( + COMSIG_PARENT_QDELETING, + COMSIG_MOVABLE_MOVED + )) + if(brain.loc == src) + brain.forceMove(drop_location()) + brain = null + +/obj/item/circuit_component/mmi/proc/update_mmi_mob(datum/source, mob/living/old_mmi, mob/living/new_mmi) + SIGNAL_HANDLER + if(old_mmi) + old_mmi.remote_control = null + UnregisterSignal(old_mmi, COMSIG_MOB_CLICKON) + if(new_mmi) + new_mmi.remote_control = src + RegisterSignal(new_mmi, COMSIG_MOB_CLICKON, .proc/handle_mmi_attack) + +/obj/item/circuit_component/mmi/relaymove(mob/living/user, direct) + if(user != brain.brainmob) + return ..() + + if(direct & NORTH) + north.set_output(COMPONENT_SIGNAL) + if(direct & WEST) + west.set_output(COMPONENT_SIGNAL) + if(direct & EAST) + east.set_output(COMPONENT_SIGNAL) + if(direct & SOUTH) + south.set_output(COMPONENT_SIGNAL) + + return TRUE + +/obj/item/circuit_component/mmi/proc/handle_mmi_attack(mob/living/source, atom/target, list/mods) + SIGNAL_HANDLER + var/list/modifiers = params2list(mods) + if(modifiers[RIGHT_CLICK]) + clicked_atom.set_output(target) + secondary_attack.set_output(COMPONENT_SIGNAL) + . = COMSIG_MOB_CANCEL_CLICKON + else if(modifiers[LEFT_CLICK] && !modifiers[SHIFT_CLICK] && !modifiers[ALT_CLICK] && !modifiers[CTRL_CLICK]) + clicked_atom.set_output(target) + attack.set_output(COMPONENT_SIGNAL) + . = COMSIG_MOB_CANCEL_CLICKON + +/obj/item/circuit_component/mmi/add_to(obj/item/integrated_circuit/add_to) + . = ..() + if(HAS_TRAIT(add_to, TRAIT_COMPONENT_MMI)) + return FALSE + ADD_TRAIT(add_to, TRAIT_COMPONENT_MMI, src) + +/obj/item/circuit_component/mmi/removed_from(obj/item/integrated_circuit/removed_from) + REMOVE_TRAIT(removed_from, TRAIT_COMPONENT_MMI, src) + remove_current_brain() + return ..() diff --git a/code/modules/wiremod/components/action/pathfind.dm b/code/modules/wiremod/components/action/pathfind.dm new file mode 100644 index 0000000000..744ae66dd7 --- /dev/null +++ b/code/modules/wiremod/components/action/pathfind.dm @@ -0,0 +1,113 @@ +/** + * # Pathfinding component + * + * Calcualtes a path, returns a list of entities. Each entity is the next step in the path. Can be used with the direction component to move. + */ +/obj/item/circuit_component/pathfind + display_name = "Pathfinder" + desc = "When triggered, the next step to the target's location as an entity. This can be used with the direction component and the drone shell to make it move on its own. The Id Card input port is for considering ID access when pathing, it does not give the shell actual access." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + var/datum/port/input/input_X + var/datum/port/input/input_Y + var/datum/port/input/id_card + + var/datum/port/output/output + var/datum/port/output/finished + var/datum/port/output/failed + var/datum/port/output/reason_failed + + var/list/path + var/turf/old_dest + var/turf/next_turf + + // Cooldown to limit how frequently we can path to the same location. + var/same_path_cooldown = 5 SECONDS + var/different_path_cooldown = 30 SECONDS + + var/max_range = 60 + +/obj/item/circuit_component/pathfind/get_ui_notices() + . = ..() + // Not necessary to show the same path cooldown, since it doesn't change much for the player + . += create_ui_notice("Pathfinding Cooldown: [DisplayTimeText(different_path_cooldown)]", "orange", "stopwatch") + . += create_ui_notice("Maximum Range: [max_range] tiles", "orange", "info") + +/obj/item/circuit_component/pathfind/Initialize(mapload) + . = ..() + input_X = add_input_port("Target X", PORT_TYPE_NUMBER, FALSE) + input_Y = add_input_port("Target Y", PORT_TYPE_NUMBER, FALSE) + id_card = add_input_port("ID Card", PORT_TYPE_ATOM, FALSE) + + output = add_output_port("Next step", PORT_TYPE_ATOM) + finished = add_output_port("Arrived to destination", PORT_TYPE_SIGNAL) + failed = add_output_port("Failed", PORT_TYPE_SIGNAL) + reason_failed = add_output_port("Fail reason", PORT_TYPE_STRING) + +/obj/item/circuit_component/pathfind/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/target_X = input_X.value + if(isnull(target_X)) + return + + var/target_Y = input_Y.value + if(isnull(target_Y)) + return + + var/atom/path_id = id_card.value + if(path_id && !istype(path_id, /obj/item/card/id)) + path_id = null + failed.set_output(COMPONENT_SIGNAL) + reason_failed.set_output("Object marked is not an ID! Using no ID instead.") + + // Get both the current turf and the destination's turf + var/turf/current_turf = get_turf(src) + var/turf/destination = locate(target_X, target_Y, current_turf?.z) + + // We're already here! No need to do anything. + if(current_turf == destination) + finished.set_output(COMPONENT_SIGNAL) + old_dest = null + TIMER_COOLDOWN_END(parent, COOLDOWN_CIRCUIT_PATHFIND_SAME) + next_turf = null + return + + // If we're going to the same place and the cooldown hasn't subsided, we're probably on the same path as before + if (destination == old_dest && TIMER_COOLDOWN_CHECK(parent, COOLDOWN_CIRCUIT_PATHFIND_SAME)) + + // Check if the current turf is the same as the current turf we're supposed to be in. If so, then we set the next step as the next turf on the list + if(current_turf == next_turf) + popleft(path) + next_turf = get_turf(path[1]) + output.set_output(next_turf) + + // Restart the cooldown since we don't need a new path ( TIMER_COOLDOWN_START might restart the timer by itself and i dont need to call TIMER_COOLDOWN_END, but better safe than sorry ) + TIMER_COOLDOWN_END(parent, COOLDOWN_CIRCUIT_PATHFIND_SAME) + TIMER_COOLDOWN_START(parent, COOLDOWN_CIRCUIT_PATHFIND_SAME, same_path_cooldown) + + + else // Either we're not going to the same place or the cooldown is over. Either way, we need a new path + + if(destination != old_dest && TIMER_COOLDOWN_CHECK(parent, COOLDOWN_CIRCUIT_PATHFIND_DIF)) + failed.set_output(COMPONENT_SIGNAL) + reason_failed.set_output("Cooldown still active!") + return + + TIMER_COOLDOWN_END(parent, COOLDOWN_CIRCUIT_PATHFIND_SAME) + + old_dest = destination + path = get_path_to(src, destination, max_range, id=path_id) + if(length(path) == 0 || !path)// Check if we can even path there + next_turf = null + failed.set_output(COMPONENT_SIGNAL) + reason_failed.set_output("Can't go there!") + return + else + TIMER_COOLDOWN_START(parent, COOLDOWN_CIRCUIT_PATHFIND_DIF, different_path_cooldown) + next_turf = get_turf(path[1]) + output.set_output(next_turf) + TIMER_COOLDOWN_START(parent, COOLDOWN_CIRCUIT_PATHFIND_SAME, same_path_cooldown) + diff --git a/code/modules/wiremod/components/action/pull.dm b/code/modules/wiremod/components/action/pull.dm new file mode 100644 index 0000000000..89530ce787 --- /dev/null +++ b/code/modules/wiremod/components/action/pull.dm @@ -0,0 +1,31 @@ +/** + * # Pull Component + * + * Tells the shell to start pulling on a designated atom. Only works on movable shells. + */ +/obj/item/circuit_component/pull + display_name = "Start Pulling" + desc = "A component that can force the shell to pull entities. Only works for drone shells." + + /// Frequency input + var/datum/port/input/target + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + +/obj/item/circuit_component/pull/Initialize(mapload) + . = ..() + target = add_input_port("Target", PORT_TYPE_ATOM) + +/obj/item/circuit_component/pull/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/atom/target_atom = target.value + if(!target_atom) + return + + var/mob/shell = parent.shell + if(!istype(shell) || get_dist(shell, target_atom) > 1 || shell.z != target_atom.z) + return + + shell.start_pulling(target_atom) diff --git a/code/modules/wiremod/components/action/radio.dm b/code/modules/wiremod/components/action/radio.dm new file mode 100644 index 0000000000..135cbdca0a --- /dev/null +++ b/code/modules/wiremod/components/action/radio.dm @@ -0,0 +1,74 @@ +#define COMP_RADIO_PUBLIC "public" +#define COMP_RADIO_PRIVATE "private" + +/** + * # Radio Component + * + * Listens out for signals on the designated frequencies and sends signals on designated frequencies + */ +/obj/item/circuit_component/radio + display_name = "Radio" + desc = "A component that can listen and send frequencies. If set to private, the component will only receive signals from other components attached to circuitboards with the same owner id." + + /// The publicity options. Controls whether it's public or private. + var/datum/port/input/option/public_options + + /// Frequency input + var/datum/port/input/freq + /// Signal input + var/datum/port/input/code + + /// Current frequency value + var/current_freq = DEFAULT_SIGNALER_CODE + + var/datum/radio_frequency/radio_connection + +/obj/item/circuit_component/radio/populate_options() + var/static/component_options = list( + COMP_RADIO_PUBLIC, + COMP_RADIO_PRIVATE, + ) + public_options = add_option_port("Encryption Options", component_options) + +/obj/item/circuit_component/radio/Initialize(mapload) + . = ..() + freq = add_input_port("Frequency", PORT_TYPE_NUMBER, default = FREQ_SIGNALER) + code = add_input_port("Code", PORT_TYPE_NUMBER, default = DEFAULT_SIGNALER_CODE) + TRIGGER_CIRCUIT_COMPONENT(src, null) + // These are cleaned up on the parent + trigger_input = add_input_port("Send", PORT_TYPE_SIGNAL) + trigger_output = add_output_port("Received", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/radio/Destroy() + SSradio.remove_object(src, current_freq) + return ..() + +/obj/item/circuit_component/radio/input_received(datum/port/input/port) + . = ..() + freq.set_value(sanitize_frequency(freq.value, TRUE)) + if(.) + return + var/frequency = freq.value + + SSradio.remove_object(src, current_freq) + radio_connection = SSradio.add_object(src, frequency, RADIO_SIGNALER) + current_freq = frequency + + if(COMPONENT_TRIGGERED_BY(trigger_input, port)) + var/datum/signal/signal = new(list("code" = round(code.value) || 0, "key" = parent?.owner_id)) + radio_connection.post_signal(src, signal) + +/obj/item/circuit_component/radio/receive_signal(datum/signal/signal) + . = FALSE + if(!signal) + return + if(signal.data["code"] != round(code.value || 0)) + return + + if(public_options.value == COMP_RADIO_PRIVATE && parent?.owner_id != signal.data["key"]) + return + + trigger_output.set_output(COMPONENT_SIGNAL) + +#undef COMP_RADIO_PUBLIC +#undef COMP_RADIO_PRIVATE diff --git a/code/modules/wiremod/components/action/soundemitter.dm b/code/modules/wiremod/components/action/soundemitter.dm new file mode 100644 index 0000000000..1806030984 --- /dev/null +++ b/code/modules/wiremod/components/action/soundemitter.dm @@ -0,0 +1,66 @@ +/** + * # Sound Emitter Component + * + * A component that emits a sound when it receives an input. + */ +/obj/item/circuit_component/soundemitter + display_name = "Sound Emitter" + desc = "A component that emits a sound when it receives an input. The frequency is a multiplier which determines the speed at which the sound is played" + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + /// Sound to play + var/datum/port/input/option/sound_file + + /// Volume of the sound when played + var/datum/port/input/volume + + /// Frequency of the sound when played + var/datum/port/input/frequency + + /// The cooldown for this component of how often it can play sounds. + var/sound_cooldown = 2 SECONDS + + var/list/options_map + +/obj/item/circuit_component/soundemitter/get_ui_notices() + . = ..() + . += create_ui_notice("Sound Cooldown: [DisplayTimeText(sound_cooldown)]", "orange", "stopwatch") + + +/obj/item/circuit_component/soundemitter/Initialize(mapload) + . = ..() + volume = add_input_port("Volume", PORT_TYPE_NUMBER, default = 35) + frequency = add_input_port("Frequency", PORT_TYPE_NUMBER, default = 0) + +/obj/item/circuit_component/soundemitter/populate_options() + var/static/component_options = list( + "Buzz" = 'sound/machines/buzz-sigh.ogg', + "Buzz Twice" = 'sound/machines/buzz-two.ogg', + "Chime" = 'sound/machines/chime.ogg', + "Honk" = 'sound/items/bikehorn.ogg', + "Ping" = 'sound/machines/ping.ogg', + "Sad Trombone" = 'sound/misc/sadtrombone.ogg', + "Warn" = 'sound/machines/warning-buzzer.ogg', + "Slow Clap" = 'sound/machines/slowclap.ogg', + ) + sound_file = add_option_port("Sound Option", component_options) + options_map = component_options + + +/obj/item/circuit_component/soundemitter/input_received(datum/port/input/port) + . = ..() + volume.set_value(clamp(volume.value, 0, 100)) + frequency.set_value(clamp(frequency.value, -100, 100)) + if(.) + return + + if(TIMER_COOLDOWN_CHECK(parent, COOLDOWN_CIRCUIT_SOUNDEMITTER)) + return + + var/sound_to_play = options_map[sound_file.value] + if(!sound_to_play) + return + + playsound(src, sound_to_play, volume.value, frequency != 0, frequency = frequency.value) + + TIMER_COOLDOWN_START(parent, COOLDOWN_CIRCUIT_SOUNDEMITTER, sound_cooldown) diff --git a/code/modules/wiremod/components/action/speech.dm b/code/modules/wiremod/components/action/speech.dm new file mode 100644 index 0000000000..fc8cb3a627 --- /dev/null +++ b/code/modules/wiremod/components/action/speech.dm @@ -0,0 +1,40 @@ +/** + * # Speech Component + * + * Sends a message. Requires a shell. + */ +/obj/item/circuit_component/speech + display_name = "Speech" + desc = "A component that sends a message. Requires a shell." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + /// The message to send + var/datum/port/input/message + + /// The cooldown for this component of how often it can send speech messages. + var/speech_cooldown = 1 SECONDS + +/obj/item/circuit_component/speech/get_ui_notices() + . = ..() + . += create_ui_notice("Speech Cooldown: [DisplayTimeText(speech_cooldown)]", "orange", "stopwatch") + +/obj/item/circuit_component/speech/Initialize(mapload) + . = ..() + message = add_input_port("Message", PORT_TYPE_STRING, FALSE) + +/obj/item/circuit_component/speech/input_received(datum/port/input/port) + . = ..() + if(.) + return + + if(TIMER_COOLDOWN_CHECK(parent, COOLDOWN_CIRCUIT_SPEECH)) + return + + if(message.value) + var/atom/movable/shell = parent.shell + // Prevents appear as the individual component if there is a shell. + if(shell) + shell.say(message.value) + else + say(message.value) + TIMER_COOLDOWN_START(parent, COOLDOWN_CIRCUIT_SPEECH, speech_cooldown) diff --git a/code/modules/wiremod/components/admin/getvar.dm b/code/modules/wiremod/components/admin/getvar.dm new file mode 100644 index 0000000000..28d25cdb53 --- /dev/null +++ b/code/modules/wiremod/components/admin/getvar.dm @@ -0,0 +1,42 @@ +/** + * # Get Variable Component + * + * A component that gets a variable on an object + */ +/obj/item/circuit_component/get_variable + display_name = "Get Variable" + desc = "A component that gets a variable on an object." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_ADMIN + + /// Entity to get variable of + var/datum/port/input/entity + + /// Variable name + var/datum/port/input/variable_name + + /// Variable value + var/datum/port/output/output_value + + +/obj/item/circuit_component/get_variable/Initialize(mapload) + . = ..() + entity = add_input_port("Target", PORT_TYPE_ATOM) + variable_name = add_input_port("Variable Name", PORT_TYPE_STRING) + + output_value = add_output_port("Output Value", PORT_TYPE_ANY) + +/obj/item/circuit_component/get_variable/input_received(datum/port/input/port) + . = ..() + if(.) + return + var/atom/object = entity.value + var/var_name = variable_name.value + if(!var_name || !object) + output_value.set_output(null) + return + + if(!object.can_vv_get(var_name) || !(var_name in object.vars)) + output_value.set_output(null) + return + + output_value.set_output(object.vars[var_name]) diff --git a/code/modules/wiremod/components/admin/proccall.dm b/code/modules/wiremod/components/admin/proccall.dm new file mode 100644 index 0000000000..4f4d1c55d3 --- /dev/null +++ b/code/modules/wiremod/components/admin/proccall.dm @@ -0,0 +1,72 @@ +#define COMP_PROC_GLOBAL "Global" +#define COMP_PROC_OBJECT "Object" + + +/** + * # Proc Call Component + * + * A component that calls a proc on an object and outputs the return value + */ +/obj/item/circuit_component/proccall + display_name = "Proc Call" + desc = "A component that calls a proc on an object." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_ADMIN + + var/datum/port/input/option/proccall_options + + /// Entity to proccall on + var/datum/port/input/entity + + /// Proc to call + var/datum/port/input/proc_name + + /// Arguments + var/datum/port/input/arguments + + /// Returns the output from the proccall + var/datum/port/output/output_value + +/obj/item/circuit_component/proccall/populate_options() + var/static/list/component_options = list( + COMP_PROC_OBJECT, + COMP_PROC_GLOBAL, + ) + + proccall_options = add_option_port("Proccall Options", component_options) + +/obj/item/circuit_component/proccall/Initialize(mapload) + . = ..() + entity = add_input_port("Target", PORT_TYPE_ATOM) + proc_name = add_input_port("Proc Name", PORT_TYPE_STRING) + arguments = add_input_port("Arguments", PORT_TYPE_LIST) + + output_value = add_output_port("Output Value", PORT_TYPE_ANY) + +/obj/item/circuit_component/proccall/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/called_on + if(proccall_options.value == COMP_PROC_OBJECT) + called_on = entity.value + else + called_on = GLOBAL_PROC + + if(!called_on) + return + + var/to_invoke = proc_name.value + var/params = arguments.value || list() + + if(!to_invoke) + return + + GLOB.AdminProcCaller = "CHAT_[parent.display_name]" //_ won't show up in ckeys so it'll never match with a real admin + var/result = WrapAdminProcCall(called_on, to_invoke, params) + GLOB.AdminProcCaller = null + + output_value.set_output(result) + +#undef COMP_PROC_GLOBAL +#undef COMP_PROC_OBJECT diff --git a/code/modules/wiremod/components/admin/sdql.dm b/code/modules/wiremod/components/admin/sdql.dm new file mode 100644 index 0000000000..ed71414dd2 --- /dev/null +++ b/code/modules/wiremod/components/admin/sdql.dm @@ -0,0 +1,36 @@ +/** + * # SDQL Component + * + * A component that performs an sdql operation + */ +/obj/item/circuit_component/sdql_operation + display_name = "SDQL Operation" + desc = "A component that performs an SDQL operation when invoked." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_ADMIN + + /// SDQL Operation to invoke + var/datum/port/input/sdql_operation + + var/datum/port/output/results + + +/obj/item/circuit_component/sdql_operation/Initialize(mapload) + . = ..() + sdql_operation = add_input_port("SDQL String", PORT_TYPE_STRING) + results = add_output_port("Result", PORT_TYPE_LIST) + +/obj/item/circuit_component/sdql_operation/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/operation = sdql_operation.value + + if(GLOB.AdminProcCaller || !operation) + return TRUE + + GLOB.AdminProcCaller = "CHAT_[parent.display_name]" //_ won't show up in ckeys so it'll never match with a real admin + var/list/result = world.SDQL2_query(operation, parent.get_creator_admin(), parent.get_creator()) + GLOB.AdminProcCaller = null + + results.set_output(result) diff --git a/code/modules/wiremod/components/admin/setvar.dm b/code/modules/wiremod/components/admin/setvar.dm new file mode 100644 index 0000000000..5319d7cdcb --- /dev/null +++ b/code/modules/wiremod/components/admin/setvar.dm @@ -0,0 +1,36 @@ +/** + * # Set Variable Component + * + * A component that sets a variable on an object + */ +/obj/item/circuit_component/set_variable + display_name = "Set Variable" + desc = "A component that sets a variable on an object." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_ADMIN + + /// Entity to set variable of + var/datum/port/input/entity + + /// Variable name + var/datum/port/input/variable_name + + /// New value to set the variable name to. + var/datum/port/input/new_value + + +/obj/item/circuit_component/set_variable/Initialize(mapload) + . = ..() + entity = add_input_port("Target", PORT_TYPE_ATOM) + variable_name = add_input_port("Variable Name", PORT_TYPE_STRING) + new_value = add_input_port("New Value", PORT_TYPE_ANY) + +/obj/item/circuit_component/set_variable/input_received(datum/port/input/port) + . = ..() + if(.) + return + var/atom/object = entity.value + var/var_name = variable_name.value + if(!var_name || !object) + return + + object.vv_edit_var(var_name, new_value.value) diff --git a/code/modules/wiremod/components/admin/spawn.dm b/code/modules/wiremod/components/admin/spawn.dm new file mode 100644 index 0000000000..795a438a70 --- /dev/null +++ b/code/modules/wiremod/components/admin/spawn.dm @@ -0,0 +1,47 @@ +/** + * # Spawn Atom Component + * + * Spawns an atom. + */ +/obj/item/circuit_component/spawn_atom + display_name = "Spawn Atom" + desc = "Spawns an atom at a desired location" + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_ADMIN + + /// The input path to convert into a typepath + var/datum/port/input/input_path + + /// The turf to spawn them at + var/datum/port/input/spawn_at + + /// Parameters to pass to the atom being spawned + var/datum/port/input/parameters + + /// The result from the output + var/datum/port/output/spawned_atom + +/obj/item/circuit_component/spawn_atom/Initialize(mapload) + . = ..() + input_path = add_input_port("Type", PORT_TYPE_ANY) + spawn_at = add_input_port("Spawn At", PORT_TYPE_ATOM) + parameters = add_input_port("Parameters", PORT_TYPE_LIST) + + spawned_atom = add_output_port("Spawned Atom", PORT_TYPE_ATOM) + +/obj/item/circuit_component/spawn_atom/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/typepath = input_path.value + + if(!ispath(typepath, /atom)) + return + + var/list/params = parameters.value + if(!params) + params = list() + + params.Insert(1, spawn_at.value) + + spawned_atom.set_output(new typepath(arglist(params))) diff --git a/code/modules/wiremod/components/admin/to_type.dm b/code/modules/wiremod/components/admin/to_type.dm new file mode 100644 index 0000000000..56a6b3a0e8 --- /dev/null +++ b/code/modules/wiremod/components/admin/to_type.dm @@ -0,0 +1,28 @@ +/** + * # To Type Component + * + * Converts a string into a typepath. Useful for adding components. + */ +/obj/item/circuit_component/to_type + display_name = "String To Type" + desc = "Converts a string into a typepath. Useful for adding components." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_ADMIN + + /// The input path to convert into a typepath + var/datum/port/input/input_path + + /// The type output + var/datum/port/output/type_output + +/obj/item/circuit_component/to_type/Initialize(mapload) + . = ..() + input_path = add_input_port("Type", PORT_TYPE_STRING) + type_output = add_output_port("Typepath", PORT_TYPE_ANY) + +/obj/item/circuit_component/to_type/input_received(datum/port/input/port) + . = ..() + if(.) + return + + type_output.set_output(text2path(input_path.value)) + diff --git a/code/modules/wiremod/components/atom/direction.dm b/code/modules/wiremod/components/atom/direction.dm new file mode 100644 index 0000000000..b7437aca84 --- /dev/null +++ b/code/modules/wiremod/components/atom/direction.dm @@ -0,0 +1,66 @@ +/** + * # Direction Component + * + * Return the direction of a mob relative to the component + */ +/obj/item/circuit_component/direction + display_name = "Get Direction" + desc = "A component that returns the direction of itself and an entity." + + /// The input port + var/datum/port/input/input_port + + /// The result from the output + var/datum/port/output/output + + // Directions outputs + var/datum/port/output/north + var/datum/port/output/south + var/datum/port/output/east + var/datum/port/output/west + + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + /// Maximum range for a valid direction to be returned + var/max_range = 7 + +/obj/item/circuit_component/direction/get_ui_notices() + . = ..() + . += create_ui_notice("Maximum Range: [max_range] tiles", "orange", "info") + +/obj/item/circuit_component/direction/Initialize(mapload) + . = ..() + input_port = add_input_port("Organism", PORT_TYPE_ATOM) + + output = add_output_port("Direction", PORT_TYPE_STRING) + + north = add_output_port("North", PORT_TYPE_SIGNAL) + east = add_output_port("East", PORT_TYPE_SIGNAL) + south = add_output_port("South", PORT_TYPE_SIGNAL) + west = add_output_port("West", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/direction/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/atom/object = input_port.value + if(!object) + return + var/turf/location = get_turf(src) + + if(object.z != location.z || get_dist(location, object) > max_range) + output.set_output(null) + return + + var/direction = get_dir(location, get_turf(object)) + output.set_output(dir2text(direction)) + + if(direction & NORTH) + north.set_output(COMPONENT_SIGNAL) + if(direction & SOUTH) + south.set_output(COMPONENT_SIGNAL) + if(direction & EAST) + east.set_output(COMPONENT_SIGNAL) + if(direction & WEST) + west.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/components/atom/gps.dm b/code/modules/wiremod/components/atom/gps.dm new file mode 100644 index 0000000000..ba807cb8a7 --- /dev/null +++ b/code/modules/wiremod/components/atom/gps.dm @@ -0,0 +1,34 @@ +/** + * # GPS Component + * + * Return the location of this + */ +/obj/item/circuit_component/gps + display_name = "Internal GPS" + desc = "A component that returns the xyz co-ordinates of itself." + + /// The result from the output + var/datum/port/output/x_pos + var/datum/port/output/y_pos + var/datum/port/output/z_pos + + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + +/obj/item/circuit_component/gps/Initialize(mapload) + . = ..() + + x_pos = add_output_port("X", PORT_TYPE_NUMBER) + y_pos = add_output_port("Y", PORT_TYPE_NUMBER) + z_pos = add_output_port("Z", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/gps/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/turf/location = get_turf(src) + + x_pos.set_output(location?.x) + y_pos.set_output(location?.y) + z_pos.set_output(location?.z) + diff --git a/code/modules/wiremod/components/atom/health.dm b/code/modules/wiremod/components/atom/health.dm new file mode 100644 index 0000000000..8c5095fb72 --- /dev/null +++ b/code/modules/wiremod/components/atom/health.dm @@ -0,0 +1,62 @@ +/** + * # Get Health Component + * + * Return the health of a mob + */ +/obj/item/circuit_component/health + display_name = "Get Health" + desc = "A component that returns the health of an organism." + + /// The input port + var/datum/port/input/input_port + + /// Brute damage + var/datum/port/output/brute + /// Burn damage + var/datum/port/output/burn + /// Toxin damage + var/datum/port/output/toxin + /// Oxyloss damage + var/datum/port/output/oxy + /// Health + var/datum/port/output/health + + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + var/max_range = 5 + +/obj/item/circuit_component/health/get_ui_notices() + . = ..() + . += create_ui_notice("Maximum Range: [max_range] tiles", "orange", "info") + +/obj/item/circuit_component/health/Initialize(mapload) + . = ..() + input_port = add_input_port("Organism", PORT_TYPE_ATOM) + + brute = add_output_port("Brute Damage", PORT_TYPE_NUMBER) + burn = add_output_port("Burn Damage", PORT_TYPE_NUMBER) + toxin = add_output_port("Toxin Damage", PORT_TYPE_NUMBER) + oxy = add_output_port("Suffocation Damage", PORT_TYPE_NUMBER) + health = add_output_port("Health", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/health/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/mob/living/organism = input_port.value + var/turf/current_turf = get_turf(src) + if(!istype(organism) || get_dist(current_turf, organism) > max_range || current_turf.z != organism.z) + brute.set_output(null) + burn.set_output(null) + toxin.set_output(null) + oxy.set_output(null) + health.set_output(null) + return + + brute.set_output(organism.getBruteLoss()) + burn.set_output(organism.getFireLoss()) + toxin.set_output(organism.getToxLoss()) + oxy.set_output(organism.getOxyLoss()) + health.set_output(organism.health) + diff --git a/code/modules/wiremod/components/atom/hear.dm b/code/modules/wiremod/components/atom/hear.dm new file mode 100644 index 0000000000..1069110603 --- /dev/null +++ b/code/modules/wiremod/components/atom/hear.dm @@ -0,0 +1,35 @@ +/** + * # Hear Component + * + * Listens for messages. Requires a shell. + */ +/obj/item/circuit_component/hear + display_name = "Voice Activator" + desc = "A component that listens for messages. Requires a shell." + + /// The message heard + var/datum/port/output/message_port + /// The language heard + var/datum/port/output/language_port + /// The speaker + var/datum/port/output/speaker_port + /// The trigger sent when this event occurs + var/datum/port/output/trigger_port + +/obj/item/circuit_component/hear/Initialize(mapload) + . = ..() + message_port = add_output_port("Message", PORT_TYPE_STRING) + language_port = add_output_port("Language", PORT_TYPE_STRING) + speaker_port = add_output_port("Speaker", PORT_TYPE_ATOM) + trigger_port = add_output_port("Triggered", PORT_TYPE_SIGNAL) + become_hearing_sensitive(ROUNDSTART_TRAIT) + +/obj/item/circuit_component/hear/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods) + if(speaker == parent?.shell) + return + + message_port.set_output(raw_message) + if(message_language) + language_port.set_output(initial(message_language.name)) + speaker_port.set_output(speaker) + trigger_port.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/components/atom/self.dm b/code/modules/wiremod/components/atom/self.dm new file mode 100644 index 0000000000..b1f469ff79 --- /dev/null +++ b/code/modules/wiremod/components/atom/self.dm @@ -0,0 +1,21 @@ +/** + * # Self Component + * + * Return the current shell. + */ +/obj/item/circuit_component/self + display_name = "Self" + desc = "A component that returns the current shell." + + /// The shell this component is attached to. + var/datum/port/output/output + +/obj/item/circuit_component/self/Initialize(mapload) + . = ..() + output = add_output_port("Self", PORT_TYPE_ATOM) + +/obj/item/circuit_component/self/register_shell(atom/movable/shell) + output.set_output(shell) + +/obj/item/circuit_component/self/unregister_shell(atom/movable/shell) + output.set_output(null) diff --git a/code/modules/wiremod/components/atom/species.dm b/code/modules/wiremod/components/atom/species.dm new file mode 100644 index 0000000000..2d865c4a73 --- /dev/null +++ b/code/modules/wiremod/components/atom/species.dm @@ -0,0 +1,35 @@ +/** + * # Get Species Component + * + * Return the species of a mob + */ +/obj/item/circuit_component/species + display_name = "Get Species" + desc = "A component that returns the species of its input." + + /// The input port + var/datum/port/input/input_port + + /// The result from the output + var/datum/port/output/output + + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + +/obj/item/circuit_component/species/Initialize(mapload) + . = ..() + input_port = add_input_port("Organism", PORT_TYPE_ATOM) + + output = add_output_port("Species", PORT_TYPE_STRING) + +/obj/item/circuit_component/species/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/mob/living/carbon/human/human = input_port.value + if(!istype(human) || !human.has_dna()) + output.set_output(null) + return + + output.set_output(human.dna.species.name) + diff --git a/code/modules/wiremod/components/hud/bar_overlay.dm b/code/modules/wiremod/components/hud/bar_overlay.dm new file mode 100644 index 0000000000..c275ab3147 --- /dev/null +++ b/code/modules/wiremod/components/hud/bar_overlay.dm @@ -0,0 +1,62 @@ +#define COMP_BAR_OVERLAY_VERTICAL "Vertical" +#define COMP_BAR_OVERLAY_HORIZONTAL "Horizontal" + +/** + * # Bar Overlay Component + * + * Basically an advanced verion of object overlay component that shows a horizontal/vertical bar. + * Requires a BCI shell. + */ + +/obj/item/circuit_component/object_overlay/bar + display_name = "Bar Overlay" + desc = "Requires a BCI shell. A component that shows a bar overlay ontop of an object from a range of 0 to 100." + + var/datum/port/input/option/bar_overlay_options + var/datum/port/input/bar_number + + var/overlay_limit = 10 + +/obj/item/circuit_component/object_overlay/bar/Initialize(mapload) + . = ..() + bar_number = add_input_port("Number", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/object_overlay/bar/populate_options() + var/static/component_options_bar = list( + COMP_BAR_OVERLAY_VERTICAL = "barvert", + COMP_BAR_OVERLAY_HORIZONTAL = "barhoriz" + ) + bar_overlay_options = add_option_port("Bar Overlay Options", component_options_bar) + options_map = component_options_bar + +/obj/item/circuit_component/object_overlay/bar/show_to_owner(atom/target_atom, mob/living/owner) + if(LAZYLEN(active_overlays) >= overlay_limit) + return + + var/current_option = bar_overlay_options.value + + if(active_overlays[target_atom]) + QDEL_NULL(active_overlays[target_atom]) + + var/number_clear = clamp(bar_number.value, 0, 100) + if(current_option == COMP_BAR_OVERLAY_HORIZONTAL) + number_clear = round(number_clear / 6.25) * 6.25 + else if(current_option == COMP_BAR_OVERLAY_VERTICAL) + number_clear = round(number_clear / 10) * 10 + var/image/cool_overlay = image(icon = 'icons/hud/screen_bci.dmi', loc = target_atom, icon_state = "[options_map[current_option]][number_clear]", layer = RIPPLE_LAYER) + + if(image_pixel_x.value) + cool_overlay.pixel_x = image_pixel_x.value + + if(image_pixel_y.value) + cool_overlay.pixel_y = image_pixel_y.value + + active_overlays[target_atom] = WEAKREF(target_atom.add_alt_appearance( + /datum/atom_hud/alternate_appearance/basic/one_person, + "bar_overlay_[REF(src)]", + cool_overlay, + owner, + )) + +#undef COMP_BAR_OVERLAY_VERTICAL +#undef COMP_BAR_OVERLAY_HORIZONTAL diff --git a/code/modules/wiremod/components/hud/counter_overlay.dm b/code/modules/wiremod/components/hud/counter_overlay.dm new file mode 100644 index 0000000000..83d7acfd11 --- /dev/null +++ b/code/modules/wiremod/components/hud/counter_overlay.dm @@ -0,0 +1,103 @@ +/** + * # Counter Overlay Component + * + * Shows an counter overlay. + * Requires a BCI shell. + */ + +/obj/item/circuit_component/counter_overlay + display_name = "Counter Overlay" + desc = "A component that shows an three digit counter. Requires a BCI shell." + + required_shells = list(/obj/item/organ/cyberimp/bci) + + var/datum/port/input/counter_number + + var/datum/port/input/image_pixel_x + var/datum/port/input/image_pixel_y + + var/datum/port/input/signal_update + + var/obj/item/organ/cyberimp/bci/bci + var/list/numbers = list() + var/counter_appearance + +/obj/item/circuit_component/counter_overlay/Initialize(mapload) + . = ..() + counter_number = add_input_port("Displayed Number", PORT_TYPE_NUMBER) + + signal_update = add_input_port("Update Overlay", PORT_TYPE_SIGNAL) + + image_pixel_x = add_input_port("X-Axis Shift", PORT_TYPE_NUMBER) + image_pixel_y = add_input_port("Y-Axis Shift", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/counter_overlay/register_shell(atom/movable/shell) + if(istype(shell, /obj/item/organ/cyberimp/bci)) + bci = shell + RegisterSignal(shell, COMSIG_ORGAN_REMOVED, .proc/on_organ_removed) + +/obj/item/circuit_component/counter_overlay/unregister_shell(atom/movable/shell) + bci = null + QDEL_NULL(counter_appearance) + for(var/number in numbers) + QDEL_NULL(number) + UnregisterSignal(shell, COMSIG_ORGAN_REMOVED) + +/obj/item/circuit_component/counter_overlay/input_received(datum/port/input/port) + . = ..() + + if(. || !bci) + return + + var/mob/living/owner = bci.owner + + if(!owner || !istype(owner) || !owner.client) + return + + for(var/number in numbers) + QDEL_NULL(number) + numbers = list() + + QDEL_NULL(counter_appearance) + var/image/counter = image(icon = 'icons/hud/screen_bci.dmi', icon_state = "hud_numbers", loc = owner) + if(image_pixel_x.value) + counter.pixel_x = image_pixel_x.value + if(image_pixel_y.value) + counter.pixel_y = image_pixel_y.value + + counter_appearance = WEAKREF(owner.add_alt_appearance( + /datum/atom_hud/alternate_appearance/basic/one_person, + "counter_overlay_[REF(src)]", + counter, + owner, + )) + + var/cleared_number = clamp(round(counter_number.value), 0, 999) + + for(var/i = 1 to 3) + var/cur_num = round(cleared_number / (10 ** (3 - i))) % 10 + var/image/number = image(icon = 'icons/hud/screen_bci.dmi', icon_state = "hud_number_[cur_num]", loc = owner) + + if(image_pixel_x.value) + number.pixel_x = image_pixel_x.value + (i - 1) * 9 + if(image_pixel_y.value) + number.pixel_y = image_pixel_y.value + + numbers.Add(WEAKREF(owner.add_alt_appearance( + /datum/atom_hud/alternate_appearance/basic/one_person, + "counter_overlay_[REF(src)]_[i]", + number, + owner, + ))) + +/obj/item/circuit_component/counter_overlay/proc/on_organ_removed(datum/source, mob/living/carbon/owner) + SIGNAL_HANDLER + QDEL_NULL(counter_appearance) + for(var/number in numbers) + QDEL_NULL(number) + +/obj/item/circuit_component/counter_overlay/Destroy() + QDEL_NULL(counter_appearance) + for(var/number in numbers) + QDEL_NULL(number) + return ..() diff --git a/code/modules/wiremod/components/hud/object_overlay.dm b/code/modules/wiremod/components/hud/object_overlay.dm new file mode 100644 index 0000000000..3b20e4f551 --- /dev/null +++ b/code/modules/wiremod/components/hud/object_overlay.dm @@ -0,0 +1,122 @@ +/** + * # Object Overlay Component + * + * Shows an overlay ontop of an object. Toggleable. + * Requires a BCI shell. + */ + +#define OBJECT_OVERLAY_LIMIT 10 + +/obj/item/circuit_component/object_overlay + display_name = "Object Overlay" + desc = "Requires a BCI shell. A component that shows an overlay on top of an object." + + required_shells = list(/obj/item/organ/cyberimp/bci) + + var/datum/port/input/option/object_overlay_options + + /// Target atom + var/datum/port/input/target + + var/datum/port/input/image_pixel_x + var/datum/port/input/image_pixel_y + + /// On/Off signals + var/datum/port/input/signal_on + var/datum/port/input/signal_off + + var/obj/item/organ/cyberimp/bci/bci + var/list/active_overlays = list() + var/list/options_map + +/obj/item/circuit_component/object_overlay/Initialize(mapload) + . = ..() + target = add_input_port("Target", PORT_TYPE_ATOM) + + signal_on = add_input_port("Create Overlay", PORT_TYPE_SIGNAL) + signal_off = add_input_port("Remove Overlay", PORT_TYPE_SIGNAL) + + image_pixel_x = add_input_port("X-Axis Shift", PORT_TYPE_NUMBER) + image_pixel_y = add_input_port("Y-Axis Shift", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/object_overlay/Destroy() + for(var/active_overlay in active_overlays) + QDEL_NULL(active_overlay) + return ..() + +/obj/item/circuit_component/object_overlay/populate_options() + var/static/component_options = list( + "Corners (Blue)" = "hud_corners", + "Corners (Red)" = "hud_corners_red", + "Circle (Blue)" = "hud_circle", + "Circle (Red)" = "hud_circle_red", + "Small Corners (Blue)" = "hud_corners_small", + "Small Corners (Red)" = "hud_corners_small_red", + "Triangle (Blue)" = "hud_triangle", + "Triangle (Red)" = "hud_triangle_red", + "HUD mark (Blue)" = "hud_mark", + "HUD mark (Red)" = "hud_mark_red" + ) + object_overlay_options = add_option_port("Object", component_options) + options_map = component_options + +/obj/item/circuit_component/object_overlay/register_shell(atom/movable/shell) + if(istype(shell, /obj/item/organ/cyberimp/bci)) + bci = shell + RegisterSignal(shell, COMSIG_ORGAN_REMOVED, .proc/on_organ_removed) + +/obj/item/circuit_component/object_overlay/unregister_shell(atom/movable/shell) + bci = null + UnregisterSignal(shell, COMSIG_ORGAN_REMOVED) + +/obj/item/circuit_component/object_overlay/input_received(datum/port/input/port) + . = ..() + + if(. || !bci) + return + + var/mob/living/owner = bci.owner + var/atom/target_atom = target.value + + if(!owner || !istype(owner) || !owner.client || !target_atom) + return + + if(COMPONENT_TRIGGERED_BY(signal_on, port)) + show_to_owner(target_atom, owner) + + if(COMPONENT_TRIGGERED_BY(signal_off, port) && (target_atom in active_overlays)) + QDEL_NULL(active_overlays[target_atom]) + active_overlays.Remove(target_atom) + +/obj/item/circuit_component/object_overlay/proc/show_to_owner(atom/target_atom, mob/living/owner) + if(LAZYLEN(active_overlays) >= OBJECT_OVERLAY_LIMIT) + return + + if(active_overlays[target_atom]) + QDEL_NULL(active_overlays[target_atom]) + + var/image/cool_overlay = image(icon = 'icons/hud/screen_bci.dmi', loc = target_atom, icon_state = options_map[object_overlay_options.value], layer = RIPPLE_LAYER) + + if(image_pixel_x.value) + cool_overlay.pixel_x = image_pixel_x.value + + if(image_pixel_y.value) + cool_overlay.pixel_y = image_pixel_y.value + + var/alt_appearance = WEAKREF(target_atom.add_alt_appearance( + /datum/atom_hud/alternate_appearance/basic/one_person, + "object_overlay_[REF(src)]", + cool_overlay, + owner, + )) + + active_overlays[target_atom] = alt_appearance + +/obj/item/circuit_component/object_overlay/proc/on_organ_removed(datum/source, mob/living/carbon/owner) + SIGNAL_HANDLER + + for(var/atom/target_atom in active_overlays) + QDEL_NULL(active_overlays[target_atom]) + active_overlays.Remove(target_atom) + +#undef OBJECT_OVERLAY_LIMIT diff --git a/code/modules/wiremod/components/hud/target_intercept.dm b/code/modules/wiremod/components/hud/target_intercept.dm new file mode 100644 index 0000000000..d04dc2c946 --- /dev/null +++ b/code/modules/wiremod/components/hud/target_intercept.dm @@ -0,0 +1,64 @@ +/** + * # Target Intercept Component + * + * When activated intercepts next click and outputs clicked atom. + * Requires a BCI shell. + */ + +/obj/item/circuit_component/target_intercept + display_name = "Target Intercept" + desc = "Requires a BCI shell. When activated, this component will allow user to target an object using their brain and will output the reference to said object." + + required_shells = list(/obj/item/organ/cyberimp/bci) + + var/datum/port/output/clicked_atom + + var/obj/item/organ/cyberimp/bci/bci + var/intercept_cooldown = 1 SECONDS + +/obj/item/circuit_component/target_intercept/Initialize(mapload) + . = ..() + trigger_input = add_input_port("Activate", PORT_TYPE_SIGNAL) + trigger_output = add_output_port("Triggered", PORT_TYPE_SIGNAL) + clicked_atom = add_output_port("Targeted Object", PORT_TYPE_ATOM) + +/obj/item/circuit_component/target_intercept/register_shell(atom/movable/shell) + if(istype(shell, /obj/item/organ/cyberimp/bci)) + bci = shell + RegisterSignal(shell, COMSIG_ORGAN_REMOVED, .proc/on_organ_removed) + +/obj/item/circuit_component/target_intercept/unregister_shell(atom/movable/shell) + bci = null + UnregisterSignal(shell, COMSIG_ORGAN_REMOVED) + +/obj/item/circuit_component/target_intercept/input_received(datum/port/input/port) + . = ..() + + if(. || !bci) + return + + var/mob/living/owner = bci.owner + if(!owner || !istype(owner) || !owner.client) + return + + if(TIMER_COOLDOWN_CHECK(parent, COOLDOWN_CIRCUIT_TARGET_INTERCEPT)) + return + + to_chat(owner, "Left-click to trigger target interceptor!") + owner.client.click_intercept = src + +/obj/item/circuit_component/target_intercept/proc/on_organ_removed(datum/source, mob/living/carbon/owner) + SIGNAL_HANDLER + + if(owner.client && owner.client.click_intercept == src) + owner.client.click_intercept = null + +/obj/item/circuit_component/target_intercept/proc/InterceptClickOn(mob/user, params, atom/object) + user.client.click_intercept = null + clicked_atom.set_output(object) + trigger_output.set_output(COMPONENT_SIGNAL) + TIMER_COOLDOWN_START(parent, COOLDOWN_CIRCUIT_TARGET_INTERCEPT, intercept_cooldown) + +/obj/item/circuit_component/target_intercept/get_ui_notices() + . = ..() + . += create_ui_notice("Target Interception Cooldown: [DisplayTimeText(intercept_cooldown)]", "orange", "stopwatch") diff --git a/code/modules/wiremod/components/list/concat.dm b/code/modules/wiremod/components/list/concat.dm new file mode 100644 index 0000000000..6574f1f02d --- /dev/null +++ b/code/modules/wiremod/components/list/concat.dm @@ -0,0 +1,48 @@ +/** + * # Concat List Component + * + * Concatenates a list with a separator + */ +/obj/item/circuit_component/concat_list + display_name = "Concatenate List" + desc = "A component that joins up a list with a separator into a single string." + + /// The input port + var/datum/port/input/list_port + + /// The seperator + var/datum/port/input/separator + + /// The result from the output + var/datum/port/output/output + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + +/obj/item/circuit_component/concat_list/Initialize(mapload) + . = ..() + list_port = add_input_port("List", PORT_TYPE_LIST) + separator = add_input_port("Seperator", PORT_TYPE_STRING) + + output = add_output_port("Output", PORT_TYPE_STRING) + +/obj/item/circuit_component/concat_list/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/seperator = separator.value + if(!seperator) + return + + var/list/list_input = list_port.value + if(!list_input) + return + + var/list/text_list = list() + for(var/entry in list_input) + if(isatom(entry)) + text_list += PORT_TYPE_ATOM + else + text_list += "[entry]" + + output.set_output(text_list.Join(seperator)) + diff --git a/code/modules/wiremod/components/list/get_column.dm b/code/modules/wiremod/components/list/get_column.dm new file mode 100644 index 0000000000..2b35951b1e --- /dev/null +++ b/code/modules/wiremod/components/list/get_column.dm @@ -0,0 +1,42 @@ +/** + * # Get Column Component + * + * Gets the column of a table and returns it as a regular list. + */ +/obj/item/circuit_component/get_column + display_name = "Get Column" + desc = "Gets the column of a table and returns it as a regular list." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + /// The list to perform the filter on + var/datum/port/input/received_table + + /// The name of the column to check + var/datum/port/input/column_name + + /// The filtered list + var/datum/port/output/output_list + +/obj/item/circuit_component/get_column/Initialize(mapload) + . = ..() + received_table = add_input_port("Input", PORT_TYPE_TABLE) + column_name = add_input_port("Column Name", PORT_TYPE_STRING) + output_list = add_output_port("Output", PORT_TYPE_LIST) + +/obj/item/circuit_component/get_column/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/list/input_list = received_table.value + if(!islist(input_list) || isnum(column_name.value)) + return + + var/list/new_list = list() + for(var/list/entry in input_list) + var/anything = entry[column_name.value] + if(islist(anything)) + continue + new_list += anything + + output_list.set_output(new_list) diff --git a/code/modules/wiremod/components/list/index.dm b/code/modules/wiremod/components/list/index.dm new file mode 100644 index 0000000000..2aaf1b6629 --- /dev/null +++ b/code/modules/wiremod/components/list/index.dm @@ -0,0 +1,42 @@ +/** + * # Index Component + * + * Return the index of a list + */ +/obj/item/circuit_component/index + display_name = "Index List" + desc = "A component that returns the value of a list at a given index." + + /// The input port + var/datum/port/input/list_port + var/datum/port/input/index_port + + /// The result from the output + var/datum/port/output/output + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + +/obj/item/circuit_component/index/Initialize(mapload) + . = ..() + index_port = add_input_port("Index", PORT_TYPE_ANY) + list_port = add_input_port("List", PORT_TYPE_LIST) + + output = add_output_port("Value", PORT_TYPE_ANY) + +/obj/item/circuit_component/index/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/index = index_port.value + var/list/list_input = list_port.value + + if(!islist(list_input) || !index) + output.set_output(null) + return + + if(isnum(index) && (index < 1 || index > length(list_input))) + output.set_output(null) + return + + output.set_output(list_input[index]) + diff --git a/code/modules/wiremod/components/list/index_table.dm b/code/modules/wiremod/components/list/index_table.dm new file mode 100644 index 0000000000..502073cf74 --- /dev/null +++ b/code/modules/wiremod/components/list/index_table.dm @@ -0,0 +1,42 @@ +/** + * # Index Table Component + * + * Gets the row of a table using the index inputted. Will return no value if the index is invalid or a proper table is not returned. + */ +/obj/item/circuit_component/index_table + display_name = "Index Table" + desc = "Gets the row of a table using the index inputted. Will return no value if the index is invalid or a proper table is not returned." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + /// The list to perform the filter on + var/datum/port/input/received_table + + /// The target index + var/datum/port/input/target_index + + /// The filtered list + var/datum/port/output/output_list + +/obj/item/circuit_component/index_table/Initialize(mapload) + . = ..() + received_table = add_input_port("Input", PORT_TYPE_TABLE) + target_index = add_input_port("Index", PORT_TYPE_NUMBER) + + output_list = add_output_port("Output", PORT_TYPE_LIST) + +/obj/item/circuit_component/index_table/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/list/target_list = received_table.value + if(!islist(target_list) || !length(target_list)) + output_list.set_output(null) + return + + var/index = target_index.value + if(index < 1 || index > length(target_list)) + output_list.set_output(null) + return + + output_list.set_output(target_list[index]) diff --git a/code/modules/wiremod/components/list/list_literal.dm b/code/modules/wiremod/components/list/list_literal.dm new file mode 100644 index 0000000000..c9dc3ea03d --- /dev/null +++ b/code/modules/wiremod/components/list/list_literal.dm @@ -0,0 +1,86 @@ +/** + * # List Literal Component + * + * Return a list literal. + */ +/obj/item/circuit_component/list_literal + display_name = "List Literal" + desc = "A component that returns the value of a list at a given index. Attack in hand to increase list size, right click to decrease list size." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + /// The inputs used to create the list + var/list/datum/port/input/entry_ports = list() + /// The result from the output + var/datum/port/output/list_output + + var/length = 0 + + var/default_list_size = 2 + + var/min_size = 1 + var/max_size = 20 + +/obj/item/circuit_component/list_literal/save_data_to_list(list/component_data) + . = ..() + component_data["length"] = length + +/obj/item/circuit_component/list_literal/load_data_from_list(list/component_data) + set_list_size(component_data["length"]) + + return ..() + +/obj/item/circuit_component/list_literal/proc/set_list_size(new_size) + if(new_size <= 0) + for(var/datum/port/input/port in entry_ports) + remove_input_port(port) + entry_ports = list() + length = 0 + return + + while(length > new_size) + var/index = length(entry_ports) + var/entry_port = entry_ports[index] + entry_ports -= entry_port + remove_input_port(entry_port) + length-- + + while(length < new_size) + length++ + var/index = length(input_ports) + if(trigger_input) + index -= 1 + entry_ports += add_input_port("Index [index+1]", PORT_TYPE_ANY, index = index+1) + +/obj/item/circuit_component/list_literal/Initialize(mapload) + . = ..() + set_list_size(default_list_size) + list_output = add_output_port("Value", PORT_TYPE_LIST) + +/obj/item/circuit_component/list_literal/Destroy() + list_output = null + return ..() + +// Increases list length +/obj/item/circuit_component/list_literal/attack_self(mob/user, list/modifiers) + . = ..() + set_list_size(min(length + 1, max_size)) + balloon_alert(user, "new size is now [length]") + +// Decreases list length +/obj/item/circuit_component/list_literal/attack_self_secondary(mob/user, list/modifiers) + . = ..() + set_list_size(max(length - 1, min_size)) + balloon_alert(user, "new size is now [length]") + +/obj/item/circuit_component/list_literal/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/list/new_literal = list() + for(var/datum/port/input/entry_port as anything in entry_ports) + // Prevents lists from merging together + new_literal += list(entry_port.value) + + list_output.set_output(new_literal) + diff --git a/code/modules/wiremod/components/list/select.dm b/code/modules/wiremod/components/list/select.dm new file mode 100644 index 0000000000..19ddb51c03 --- /dev/null +++ b/code/modules/wiremod/components/list/select.dm @@ -0,0 +1,93 @@ +/** + * # Select Component + * + * Selects a list from a list of lists by a specific column. Used only by USBs for communications to and from computers with lists of varying sizes. + */ +/obj/item/circuit_component/select + display_name = "Select Query" + desc = "A component used with USB cables that can perform select queries on a list based on the column name selected. The values are then compared with the comparison input." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + var/datum/port/input/option/comparison_options + + /// The list to perform the filter on + var/datum/port/input/received_table + + /// The name of the column to check + var/datum/port/input/column_name + + /// The input to compare with + var/datum/port/input/comparison_input + + /// The filtered list + var/datum/port/output/filtered_table + + var/current_type = PORT_TYPE_ANY + +/obj/item/circuit_component/select/populate_options() + var/static/component_options = list( + COMP_COMPARISON_EQUAL, + COMP_COMPARISON_NOT_EQUAL, + COMP_COMPARISON_GREATER_THAN, + COMP_COMPARISON_LESS_THAN, + COMP_COMPARISON_GREATER_THAN_OR_EQUAL, + COMP_COMPARISON_LESS_THAN_OR_EQUAL, + ) + comparison_options = add_option_port("Comparison Options", component_options) + +/obj/item/circuit_component/select/Initialize(mapload) + . = ..() + received_table = add_input_port("Input", PORT_TYPE_TABLE) + column_name = add_input_port("Column Name", PORT_TYPE_STRING) + comparison_input = add_input_port("Comparison Input", PORT_TYPE_ANY) + + filtered_table = add_output_port("Output", PORT_TYPE_TABLE) + +/obj/item/circuit_component/select/input_received(datum/port/input/port) + . = ..() + var/current_option = comparison_options.value + + switch(current_option) + if(COMP_COMPARISON_EQUAL, COMP_COMPARISON_NOT_EQUAL) + if(current_type != PORT_TYPE_ANY) + current_type = PORT_TYPE_ANY + comparison_input.set_datatype(PORT_TYPE_ANY) + else + if(current_type != PORT_TYPE_NUMBER) + current_type = PORT_TYPE_NUMBER + comparison_input.set_datatype(PORT_TYPE_NUMBER) + + if(.) + return + + var/list/input_list = received_table.value + if(!islist(input_list) || isnum(column_name.value)) + return + + var/comparison_value = comparison_input.value + var/list/new_list = list() + for(var/list/entry in input_list) + var/anything = entry[column_name.value] + if(islist(anything)) + continue + if(current_option != COMP_COMPARISON_EQUAL && current_option != COMP_COMPARISON_NOT_EQUAL && !isnum(anything)) + continue + var/add_to_list = FALSE + switch(current_option) + if(COMP_COMPARISON_EQUAL) + add_to_list = anything == comparison_value + if(COMP_COMPARISON_NOT_EQUAL) + add_to_list = anything != comparison_value + if(COMP_COMPARISON_GREATER_THAN) + add_to_list = anything > comparison_value + if(COMP_COMPARISON_GREATER_THAN_OR_EQUAL) + add_to_list = anything >= comparison_value + if(COMP_COMPARISON_LESS_THAN) + add_to_list = anything < comparison_value + if(COMP_COMPARISON_LESS_THAN_OR_EQUAL) + add_to_list = anything <= comparison_value + + if(add_to_list) + new_list += list(entry) + + filtered_table.set_output(new_list) diff --git a/code/modules/wiremod/components/list/split.dm b/code/modules/wiremod/components/list/split.dm new file mode 100644 index 0000000000..444157342c --- /dev/null +++ b/code/modules/wiremod/components/list/split.dm @@ -0,0 +1,42 @@ +/** + * # Split component + * + * Splits a string + */ +/obj/item/circuit_component/split + display_name = "Split" + desc = "Splits a string by the separator, turning it into a list" + + /// The input port + var/datum/port/input/input_port + + /// The seperator + var/datum/port/input/separator + + /// The result from the output + var/datum/port/output/output + + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + +/obj/item/circuit_component/split/Initialize(mapload) + . = ..() + input_port = add_input_port("Input", PORT_TYPE_STRING) + separator = add_input_port("Seperator", PORT_TYPE_STRING) + output = add_output_port("Output", PORT_TYPE_LIST) + +/obj/item/circuit_component/split/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/separator_value = separator.value + if(isnull(separator_value)) + return + + var/value = input_port.value + if(isnull(value)) + return + + var/list/result = splittext(value,separator_value) + + output.set_output(result) diff --git a/code/modules/wiremod/components/math/arithmetic.dm b/code/modules/wiremod/components/math/arithmetic.dm new file mode 100644 index 0000000000..9d7361c66b --- /dev/null +++ b/code/modules/wiremod/components/math/arithmetic.dm @@ -0,0 +1,88 @@ +#define COMP_ARITHMETIC_ADD "Add" +#define COMP_ARITHMETIC_SUBTRACT "Subtract" +#define COMP_ARITHMETIC_MULTIPLY "Multiply" +#define COMP_ARITHMETIC_DIVIDE "Divide" +#define COMP_ARITHMETIC_MIN "Minimum" +#define COMP_ARITHMETIC_MAX "Maximum" + +/** + * # Arithmetic Component + * + * General arithmetic unit with add/sub/mult/divide capabilities + * This one only works with numbers. + */ +/obj/item/circuit_component/arithmetic + display_name = "Arithmetic" + desc = "General arithmetic component with arithmetic capabilities." + + /// The amount of input ports to have + var/input_port_amount = 4 + + var/datum/port/input/option/arithmetic_option + + /// The result from the output + var/datum/port/output/output + + var/list/arithmetic_ports + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + +/obj/item/circuit_component/arithmetic/populate_options() + var/static/component_options = list( + COMP_ARITHMETIC_ADD, + COMP_ARITHMETIC_SUBTRACT, + COMP_ARITHMETIC_MULTIPLY, + COMP_ARITHMETIC_DIVIDE, + COMP_ARITHMETIC_MIN, + COMP_ARITHMETIC_MAX, + ) + arithmetic_option = add_option_port("Arithmetic Option", component_options) + +/obj/item/circuit_component/arithmetic/Initialize(mapload) + . = ..() + arithmetic_ports = list() + for(var/port_id in 1 to input_port_amount) + var/letter = ascii2text(text2ascii("A") + (port_id-1)) + arithmetic_ports += add_input_port(letter, PORT_TYPE_NUMBER) + + output = add_output_port("Output", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/arithmetic/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/list/ports = arithmetic_ports.Copy() + var/datum/port/input/first_port = popleft(ports) + var/result = first_port.value + + for(var/datum/port/input/input_port as anything in ports) + var/value = input_port.value + if(isnull(value)) + continue + + switch(arithmetic_option.value) + if(COMP_ARITHMETIC_ADD) + result += value + if(COMP_ARITHMETIC_SUBTRACT) + result -= value + if(COMP_ARITHMETIC_MULTIPLY) + result *= value + if(COMP_ARITHMETIC_DIVIDE) + // Protect from div by zero errors. + if(value == 0) + result = null + break + result /= value + if(COMP_ARITHMETIC_MAX) + result = max(result, value) + if(COMP_ARITHMETIC_MIN) + result = min(result, value) + + output.set_output(result) + +#undef COMP_ARITHMETIC_ADD +#undef COMP_ARITHMETIC_SUBTRACT +#undef COMP_ARITHMETIC_MULTIPLY +#undef COMP_ARITHMETIC_DIVIDE +#undef COMP_ARITHMETIC_MIN +#undef COMP_ARITHMETIC_MAX diff --git a/code/modules/wiremod/components/math/comparison.dm b/code/modules/wiremod/components/math/comparison.dm new file mode 100644 index 0000000000..0415b04568 --- /dev/null +++ b/code/modules/wiremod/components/math/comparison.dm @@ -0,0 +1,62 @@ +/** + * # Comparison Component + * + * Compares two objects + */ +/obj/item/circuit_component/compare/comparison + display_name = "Comparison" + desc = "A component that compares two objects." + + var/datum/port/input/option/comparison_option + + input_port_amount = 2 + var/current_type = PORT_TYPE_ANY + +/obj/item/circuit_component/compare/comparison/populate_options() + var/static/component_options = list( + COMP_COMPARISON_EQUAL, + COMP_COMPARISON_NOT_EQUAL, + COMP_COMPARISON_GREATER_THAN, + COMP_COMPARISON_LESS_THAN, + COMP_COMPARISON_GREATER_THAN_OR_EQUAL, + COMP_COMPARISON_LESS_THAN_OR_EQUAL, + ) + comparison_option = add_option_port("Comparison Option", component_options) + +/obj/item/circuit_component/compare/comparison/input_received(datum/port/input/port) + switch(comparison_option.value) + if(COMP_COMPARISON_EQUAL, COMP_COMPARISON_NOT_EQUAL) + if(current_type != PORT_TYPE_ANY) + current_type = PORT_TYPE_ANY + compare_ports[1].set_datatype(PORT_TYPE_ANY) + compare_ports[2].set_datatype(PORT_TYPE_ANY) + else + if(current_type != PORT_TYPE_NUMBER) + current_type = PORT_TYPE_NUMBER + compare_ports[1].set_datatype(PORT_TYPE_NUMBER) + compare_ports[2].set_datatype(PORT_TYPE_NUMBER) + return ..() + + +/obj/item/circuit_component/compare/comparison/do_comparisons(list/ports) + if(length(ports) < input_port_amount) + return FALSE + + // Comparison component only compares the first two ports + var/input1 = compare_ports[1].value + var/input2 = compare_ports[2].value + var/current_option = comparison_option.value + + switch(current_option) + if(COMP_COMPARISON_EQUAL) + return input1 == input2 + if(COMP_COMPARISON_NOT_EQUAL) + return input1 != input2 + if(COMP_COMPARISON_GREATER_THAN) + return input1 > input2 + if(COMP_COMPARISON_GREATER_THAN_OR_EQUAL) + return input1 >= input2 + if(COMP_COMPARISON_LESS_THAN) + return input1 < input2 + if(COMP_COMPARISON_LESS_THAN_OR_EQUAL) + return input1 <= input2 diff --git a/code/modules/wiremod/components/math/length.dm b/code/modules/wiremod/components/math/length.dm new file mode 100644 index 0000000000..14bc58c998 --- /dev/null +++ b/code/modules/wiremod/components/math/length.dm @@ -0,0 +1,29 @@ +/** + * # Length Component + * + * Return the length of an input + */ +/obj/item/circuit_component/length + display_name = "Length" + desc = "A component that returns the length of its input." + + /// The input port + var/datum/port/input/input_port + + /// The result from the output + var/datum/port/output/output + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + +/obj/item/circuit_component/length/Initialize(mapload) + . = ..() + input_port = add_input_port("Input", PORT_TYPE_ANY) + + output = add_output_port("Length", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/length/input_received(datum/port/input/port) + . = ..() + if(.) + return + + output.set_output(length(input_port.value)) + diff --git a/code/modules/wiremod/components/math/logic.dm b/code/modules/wiremod/components/math/logic.dm new file mode 100644 index 0000000000..9f632a9242 --- /dev/null +++ b/code/modules/wiremod/components/math/logic.dm @@ -0,0 +1,57 @@ +#define COMP_LOGIC_AND "AND" +#define COMP_LOGIC_OR "OR" +#define COMP_LOGIC_XOR "XOR" + +/** + * # Logic Component + * + * General logic unit with AND OR capabilities + */ +/obj/item/circuit_component/compare/logic + display_name = "Logic" + desc = "A component with 'and' and 'or' capabilities." + + var/datum/port/input/option/logic_options + +/obj/item/circuit_component/compare/logic/populate_options() + var/static/component_options = list( + COMP_LOGIC_AND, + COMP_LOGIC_OR, + COMP_LOGIC_XOR, + ) + logic_options = add_option_port("Logic Options", component_options) + +/obj/item/circuit_component/compare/logic/do_comparisons(list/ports) + . = FALSE + var/current_option = logic_options.value + + // Used by XOR + var/total_ports = 0 + var/total_true_ports = 0 + for(var/datum/port/input/port as anything in ports) + if(isnull(port.value) && length(port.connected_ports) == 0) + continue + + total_ports += 1 + switch(current_option) + if(COMP_LOGIC_AND) + if(!port.value) + return FALSE + . = TRUE + if(COMP_LOGIC_OR) + if(port.value) + return TRUE + if(COMP_LOGIC_XOR) + if(port.value) + . = TRUE + total_true_ports += 1 + + if(current_option == COMP_LOGIC_XOR) + if(total_ports == total_true_ports) + return FALSE + if(.) + return TRUE + +#undef COMP_LOGIC_AND +#undef COMP_LOGIC_OR +#undef COMP_LOGIC_XOR diff --git a/code/modules/wiremod/components/math/not.dm b/code/modules/wiremod/components/math/not.dm new file mode 100644 index 0000000000..ad8a1d6791 --- /dev/null +++ b/code/modules/wiremod/components/math/not.dm @@ -0,0 +1,29 @@ +/** + * # Logic Component + * + * General logic unit with AND OR capabilities + */ +/obj/item/circuit_component/not + display_name = "Not" + desc = "A component that inverts its input." + + /// The input port + var/datum/port/input/input_port + + /// The result from the output + var/datum/port/output/result + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + +/obj/item/circuit_component/not/Initialize(mapload) + . = ..() + input_port = add_input_port("Input", PORT_TYPE_ANY) + + result = add_output_port("Result", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/not/input_received(datum/port/input/port) + . = ..() + if(.) + return + + result.set_output(!input_port.value) + diff --git a/code/modules/wiremod/components/math/random.dm b/code/modules/wiremod/components/math/random.dm new file mode 100644 index 0000000000..7e428f5ea6 --- /dev/null +++ b/code/modules/wiremod/components/math/random.dm @@ -0,0 +1,40 @@ +/** + * # Random Component + * + * Generates a random number between specific values + */ +/obj/item/circuit_component/random + display_name = "Random" + desc = "A component that returns random values." + + /// The minimum value that the random number can be + var/datum/port/input/minimum + /// The maximum value that the random number can be + var/datum/port/input/maximum + + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + /// The result from the output + var/datum/port/output/output + +/obj/item/circuit_component/random/Initialize(mapload) + . = ..() + minimum = add_input_port("Minimum", PORT_TYPE_NUMBER, FALSE) + maximum = add_input_port("Maximum", PORT_TYPE_NUMBER, FALSE) + + output = add_output_port("Output", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/random/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/min_val = minimum.value || 0 + var/max_val = maximum.value || 0 + + if(max_val < min_val) + output.set_output(0) + return + + output.set_output(rand(min_val, max_val)) + diff --git a/code/modules/wiremod/components/ntnet/ntnet_receive.dm b/code/modules/wiremod/components/ntnet/ntnet_receive.dm new file mode 100644 index 0000000000..30bbaee855 --- /dev/null +++ b/code/modules/wiremod/components/ntnet/ntnet_receive.dm @@ -0,0 +1,62 @@ +/** + * # NTNet Receiver Component + * + * Receives data through NTNet. + */ + +/obj/item/circuit_component/ntnet_receive + display_name = "NTNet Receiver" + desc = "Receives data packages through NTNet. If Encryption Key is set then only signals with the same Encryption Key will be received." + + circuit_flags = CIRCUIT_FLAG_OUTPUT_SIGNAL //trigger_output + + network_id = __NETWORK_CIRCUITS + + var/datum/port/input/push_hid + var/datum/port/output/hid + var/datum/port/output/data_package + var/datum/port/output/secondary_package + var/datum/port/input/enc_key + var/datum/port/input/option/data_type_options + var/datum/port/input/option/secondary_data_type_options + +/obj/item/circuit_component/ntnet_receive/Initialize(mapload) + . = ..() + data_package = add_output_port("Data Package", PORT_TYPE_ANY) + secondary_package = add_output_port("Secondary Package", PORT_TYPE_ANY) + enc_key = add_input_port("Encryption Key", PORT_TYPE_STRING) + RegisterSignal(src, COMSIG_COMPONENT_NTNET_RECEIVE, .proc/ntnet_receive) + +/obj/item/circuit_component/ntnet_receive/populate_options() + var/static/component_options = list( + PORT_TYPE_ANY, + PORT_TYPE_STRING, + PORT_TYPE_NUMBER, + PORT_TYPE_LIST, + PORT_TYPE_ATOM, + ) + data_type_options = add_option_port("Data Type", component_options) + secondary_data_type_options = add_option_port("Secondary Data Type", component_options) + +/obj/item/circuit_component/ntnet_receive/input_received(datum/port/input/port) + . = ..() + if(.) + return + + if(COMPONENT_TRIGGERED_BY(data_type_options, port)) + data_package.set_datatype(data_type_options.value) + + if(COMPONENT_TRIGGERED_BY(secondary_data_type_options, port)) + secondary_package.set_datatype(secondary_data_type_options.value) + + return TRUE + +/obj/item/circuit_component/ntnet_receive/proc/ntnet_receive(datum/source, datum/netdata/data) + SIGNAL_HANDLER + + if(data.data["enc_key"] != enc_key.value) + return + + data_package.set_output(data.data["data"]) + secondary_package.set_output(data.data["data_secondary"]) + trigger_output.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/components/ntnet/ntnet_send.dm b/code/modules/wiremod/components/ntnet/ntnet_send.dm new file mode 100644 index 0000000000..44316f80ee --- /dev/null +++ b/code/modules/wiremod/components/ntnet/ntnet_send.dm @@ -0,0 +1,29 @@ +/** + * # NTNet Transmitter Component + * + * Sends a data package through NTNet + */ + +/obj/item/circuit_component/ntnet_send + display_name = "NTNet Transmitter" + desc = "Sends a data package through NTNet. If Encryption Key is set then transmitted data will be only picked up by receivers with the same Encryption Key." + + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL + + network_id = __NETWORK_CIRCUITS + + var/datum/port/input/data_package + var/datum/port/input/secondary_package + var/datum/port/input/enc_key + +/obj/item/circuit_component/ntnet_send/Initialize(mapload) + . = ..() + data_package = add_input_port("Data Package", PORT_TYPE_ANY) + secondary_package = add_input_port("Secondary Package", PORT_TYPE_ANY) + enc_key = add_input_port("Encryption Key", PORT_TYPE_STRING) + +/obj/item/circuit_component/ntnet_send/input_received(datum/port/input/port) + . = ..() + if(.) + return + ntnet_send(list("data" = data_package.value, "data_secondary" = secondary_package.value, "enc_key" = enc_key.value)) diff --git a/code/modules/wiremod/components/sensors/pressuresensor.dm b/code/modules/wiremod/components/sensors/pressuresensor.dm new file mode 100644 index 0000000000..f02642151a --- /dev/null +++ b/code/modules/wiremod/components/sensors/pressuresensor.dm @@ -0,0 +1,36 @@ +/** + * # Pressure Sensor + * + * Returns the pressure of the tile + */ +/obj/item/circuit_component/pressuresensor + display_name = "Pressure Sensor" + desc = "Outputs the current pressure of the tile" + + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + /// The result from the output + var/datum/port/output/result + +/obj/item/circuit_component/pressuresensor/Initialize(mapload) + . = ..() + result = add_output_port("Result", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/pressuresensor/input_received(datum/port/input/port) + . = ..() + if(.) + return + //Get current turf + var/turf/location = get_turf(src) + if(!location) + result.set_output(null) + return + //Get environment info + var/datum/gas_mixture/environment = location.return_air() + var/total_moles = environment.total_moles() + var/pressure = environment.return_pressure() + if(total_moles) + //If there's atmos, return pressure + result.set_output(round(pressure,1)) + else + result.set_output(0) diff --git a/code/modules/wiremod/components/sensors/tempsensor.dm b/code/modules/wiremod/components/sensors/tempsensor.dm new file mode 100644 index 0000000000..caa76a8cb8 --- /dev/null +++ b/code/modules/wiremod/components/sensors/tempsensor.dm @@ -0,0 +1,36 @@ +/** + * # Temperature Sensor + * + * Returns the temperature of the tile + */ +/obj/item/circuit_component/tempsensor + display_name = "Temperature Sensor" + desc = "Outputs the current temperature of the tile" + + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + /// The result from the output + var/datum/port/output/result + +/obj/item/circuit_component/tempsensor/Initialize(mapload) + . = ..() + result = add_output_port("Result", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/tempsensor/input_received(datum/port/input/port) + . = ..() + if(.) + return + //Get current turf + var/turf/location = get_turf(src) + if(!location) + result.set_output(null) + return + //Get environment info + var/datum/gas_mixture/environment = location.return_air() + var/total_moles = environment.total_moles() + if(total_moles) + //If there's atmos, return temperature + result.set_output(round(environment.temperature,1)) + else + result.set_output(0) + diff --git a/code/modules/wiremod/components/string/concat.dm b/code/modules/wiremod/components/string/concat.dm new file mode 100644 index 0000000000..10fcb1dd05 --- /dev/null +++ b/code/modules/wiremod/components/string/concat.dm @@ -0,0 +1,42 @@ +/** + * # Concatenate Component + * + * General string concatenation component. Puts strings together. + */ +/obj/item/circuit_component/concat + display_name = "Concatenate" + desc = "A component that combines strings." + + /// The amount of input ports to have + var/input_port_amount = 4 + + /// The result from the output + var/datum/port/output/output + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + +/obj/item/circuit_component/concat/Initialize(mapload) + . = ..() + for(var/port_id in 1 to input_port_amount) + var/letter = ascii2text(text2ascii("A") + (port_id-1)) + add_input_port(letter, PORT_TYPE_STRING) + + output = add_output_port("Output", PORT_TYPE_STRING) + +/obj/item/circuit_component/concat/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/result = "" + var/list/ports = input_ports.Copy() + ports -= trigger_input + + for(var/datum/port/input/input_port as anything in ports) + var/value = input_port.value + if(isnull(value)) + continue + + result += "[value]" + + output.set_output(result) + diff --git a/code/modules/wiremod/components/string/contains.dm b/code/modules/wiremod/components/string/contains.dm new file mode 100644 index 0000000000..61b5e0ca22 --- /dev/null +++ b/code/modules/wiremod/components/string/contains.dm @@ -0,0 +1,35 @@ +/** + * # String Contains Component + * + * Checks if a string contains a word/letter + */ +/obj/item/circuit_component/compare/contains + display_name = "String Contains" + desc = "Checks if a string contains a word/letter" + + input_port_amount = 0 + + var/datum/port/input/needle + var/datum/port/input/haystack + +/obj/item/circuit_component/compare/contains/load_custom_ports() + needle = add_input_port("Needle", PORT_TYPE_STRING) + haystack = add_input_port("Haystack", PORT_TYPE_STRING) + +/obj/item/circuit_component/compare/contains/Destroy() + needle = null + haystack = null + return ..() + + +/obj/item/circuit_component/compare/contains/do_comparisons(list/ports) + if(length(ports) < input_port_amount) + return + + var/to_find = needle.value + var/to_search = haystack.value + + if(!to_find || !to_search) + return + + return findtext(to_search, to_find) diff --git a/code/modules/wiremod/components/string/textcase.dm b/code/modules/wiremod/components/string/textcase.dm new file mode 100644 index 0000000000..9a01ae8765 --- /dev/null +++ b/code/modules/wiremod/components/string/textcase.dm @@ -0,0 +1,54 @@ +#define COMP_TEXT_LOWER "To Lower" +#define COMP_TEXT_UPPER "To Upper" + +/** + * # Text Component + * + * Either makes the text upper case or lower case. + */ +/obj/item/circuit_component/textcase + display_name = "Text Case" + desc = "A component that makes its input uppercase or lowercase." + + var/datum/port/input/option/textcase_options + + /// The input port + var/datum/port/input/input_port + + /// The result of the text operation + var/datum/port/output/output + + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + +/obj/item/circuit_component/textcase/populate_options() + var/static/component_options = list( + COMP_TEXT_LOWER, + COMP_TEXT_UPPER, + ) + textcase_options = add_option_port("Textcase Options", component_options) + +/obj/item/circuit_component/textcase/Initialize(mapload) + . = ..() + input_port = add_input_port("Input", PORT_TYPE_STRING) + output = add_output_port("Output", PORT_TYPE_STRING) + +/obj/item/circuit_component/textcase/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/value = input_port.value + if(isnull(value)) + return + + var/result + switch(textcase_options.value) + if(COMP_TEXT_LOWER) + result = lowertext(value) + if(COMP_TEXT_UPPER) + result = uppertext(value) + + output.set_output(result) + +#undef COMP_TEXT_LOWER +#undef COMP_TEXT_UPPER diff --git a/code/modules/wiremod/components/string/tonumber.dm b/code/modules/wiremod/components/string/tonumber.dm new file mode 100644 index 0000000000..6083940a16 --- /dev/null +++ b/code/modules/wiremod/components/string/tonumber.dm @@ -0,0 +1,29 @@ +/** + * #To Number Component + * + * Converts a string into a Number + */ +/obj/item/circuit_component/tonumber + display_name = "To Number" + desc = "A component that converts its input (a string) to a number. If there's text in the input, it'll only consider it if it starts with a number. It will take that number and ignore the rest." + + /// The input port + var/datum/port/input/input_port + + /// The result from the output + var/datum/port/output/output + + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + +/obj/item/circuit_component/tonumber/Initialize(mapload) + . = ..() + input_port = add_input_port("Input", PORT_TYPE_STRING) + + output = add_output_port("Output", PORT_TYPE_NUMBER) + +/obj/item/circuit_component/tonumber/input_received(datum/port/input/port) + . = ..() + if(.) + return + + output.set_output(text2num(input_port.value)) diff --git a/code/modules/wiremod/components/string/tostring.dm b/code/modules/wiremod/components/string/tostring.dm new file mode 100644 index 0000000000..a4d30682ba --- /dev/null +++ b/code/modules/wiremod/components/string/tostring.dm @@ -0,0 +1,40 @@ +/** + * # To String Component + * + * Converts any value into a string + */ +/obj/item/circuit_component/tostring + display_name = "To String" + desc = "A component that converts its input to text." + + /// The input port + var/datum/port/input/input_port + + /// The result from the output + var/datum/port/output/output + + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + var/max_range = 5 + +/obj/item/circuit_component/tostring/Initialize(mapload) + . = ..() + input_port = add_input_port("Input", PORT_TYPE_ANY) + + output = add_output_port("Output", PORT_TYPE_STRING) + +/obj/item/circuit_component/tostring/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/value = input_port.value + if(isatom(value)) + var/turf/location = get_turf(src) + var/atom/object = value + if(object.z != location.z || get_dist(location, object) > max_range) + output.set_output(PORT_TYPE_ATOM) + return + + output.set_output("[value]") + diff --git a/code/modules/wiremod/components/utility/clock.dm b/code/modules/wiremod/components/utility/clock.dm new file mode 100644 index 0000000000..093aac90f4 --- /dev/null +++ b/code/modules/wiremod/components/utility/clock.dm @@ -0,0 +1,57 @@ +/** + * # Clock Component + * + * Fires every tick of the circuit timer SS + */ +/obj/item/circuit_component/clock + display_name = "Clock" + desc = "A component that repeatedly fires." + + /// Whether the clock is on or not + var/datum/port/input/on + + /// The signal from this clock component + var/datum/port/output/signal + +/obj/item/circuit_component/clock/get_ui_notices() + . = ..() + . += create_ui_notice("Clock Interval: [DisplayTimeText(COMP_CLOCK_DELAY)]", "orange", "clock") + +/obj/item/circuit_component/clock/Initialize(mapload) + . = ..() + on = add_input_port("On", PORT_TYPE_NUMBER) + + signal = add_output_port("Signal", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/clock/input_received(datum/port/input/port) + . = ..() + if(.) + return + + if(on.value) + start_process() + else + stop_process() + +/obj/item/circuit_component/clock/Destroy() + stop_process() + return ..() + +/obj/item/circuit_component/clock/process(delta_time) + signal.set_output(COMPONENT_SIGNAL) + +/** + * Adds the component to the SSclock_component process list + * + * Starts ticking to send signals between periods of time + */ +/obj/item/circuit_component/clock/proc/start_process() + START_PROCESSING(SSclock_component, src) + +/** + * Removes the component to the SSclock_component process list + * + * Signals stop getting sent. + */ +/obj/item/circuit_component/clock/proc/stop_process() + STOP_PROCESSING(SSclock_component, src) diff --git a/code/modules/wiremod/components/utility/delay.dm b/code/modules/wiremod/components/utility/delay.dm new file mode 100644 index 0000000000..46d9e6f081 --- /dev/null +++ b/code/modules/wiremod/components/utility/delay.dm @@ -0,0 +1,43 @@ +/// The minimum delay value that the delay component can have. +#define COMP_DELAY_MIN_VALUE 0.1 + +/** + * # Delay Component + * + * Delays a signal by a specified duration. + */ +/obj/item/circuit_component/delay + display_name = "Delay" + desc = "A component that delays a signal by a specified duration." + + /// Amount to delay by + var/datum/port/input/delay_amount + /// Input signal to fire the delay + var/datum/port/input/trigger + + /// The output of the signal + var/datum/port/output/output + +/obj/item/circuit_component/delay/Initialize(mapload) + . = ..() + delay_amount = add_input_port("Delay", PORT_TYPE_NUMBER, FALSE) + trigger = add_input_port("Trigger", PORT_TYPE_SIGNAL) + + output = add_output_port("Result", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/delay/input_received(datum/port/input/port) + . = ..() + if(.) + return + + if(!COMPONENT_TRIGGERED_BY(trigger, port)) + return + + var/delay = delay_amount.value + if(delay > COMP_DELAY_MIN_VALUE) + // Convert delay into deciseconds + addtimer(CALLBACK(output, /datum/port/output.proc/set_output, trigger.value), delay*10) + else + output.set_output(trigger.value) + +#undef COMP_DELAY_MIN_VALUE diff --git a/code/modules/wiremod/components/utility/getter.dm b/code/modules/wiremod/components/utility/getter.dm new file mode 100644 index 0000000000..30c3cb2ac1 --- /dev/null +++ b/code/modules/wiremod/components/utility/getter.dm @@ -0,0 +1,70 @@ +/** + * # Getter Component + * + * Gets the current value from a variable. + */ +/obj/item/circuit_component/getter + display_name = "Variable Getter" + desc = "A component that gets a variable globally on the circuit." + + /// Variable name + var/datum/port/input/option/variable_name + + /// The value of the variable + var/datum/port/output/value + + var/datum/circuit_variable/current_variable + +/obj/item/circuit_component/getter/populate_options() + variable_name = add_option_port("Variable", null) + +/obj/item/circuit_component/getter/add_to(obj/item/integrated_circuit/added_to) + . = ..() + variable_name.possible_options = added_to.circuit_variables + +/obj/item/circuit_component/getter/removed_from(obj/item/integrated_circuit/removed_from) + variable_name.possible_options = null + return ..() + +/obj/item/circuit_component/getter/Initialize(mapload) + . = ..() + value = add_output_port("Value", PORT_TYPE_ANY) + +/obj/item/circuit_component/getter/input_received(datum/port/input/port) + . = ..() + // We don't care much about the parent's return value. We only care if the parent exists + // since this should never really fail. + if(!parent) + return + + var/variable_string = variable_name.value + if(!variable_string) + remove_current_variable() + value.set_output(null) + return + + var/datum/circuit_variable/variable = parent.circuit_variables[variable_string] + if(!variable) + remove_current_variable() + value.set_output(null) + return + + set_current_variable(variable) + value.set_output(variable.value) + +/obj/item/circuit_component/getter/proc/remove_current_variable() + SIGNAL_HANDLER + if(current_variable) + current_variable.remove_listener(src) + UnregisterSignal(current_variable, COMSIG_PARENT_QDELETING) + current_variable = null + +/obj/item/circuit_component/getter/proc/set_current_variable(datum/circuit_variable/variable) + if(variable == current_variable) + return + + remove_current_variable() + current_variable = variable + current_variable.add_listener(src) + RegisterSignal(current_variable, COMSIG_PARENT_QDELETING, .proc/remove_current_variable) + value.set_datatype(variable.datatype) diff --git a/code/modules/wiremod/components/utility/router.dm b/code/modules/wiremod/components/utility/router.dm new file mode 100644 index 0000000000..bf9fdba0e0 --- /dev/null +++ b/code/modules/wiremod/components/utility/router.dm @@ -0,0 +1,82 @@ +/** + * # Router Component + * + * Writes one of multiple inputs to one of multiple outputs. + */ +/obj/item/circuit_component/router + display_name = "Router" + desc = "Copies the input chosen by \"Input Selector\" to the output chosen by \"Output Selector\"." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + var/datum/port/input/option/router_options + + /// Which ports to connect. + var/datum/port/input/input_selector + var/datum/port/input/output_selector + + /// How many ports to have. + var/input_port_amount = 4 + var/output_port_amount = 4 + + /// Current type of the ports + var/current_type + + /// The ports to route. + var/list/datum/port/input/ins + var/list/datum/port/output/outs + +/obj/item/circuit_component/router/populate_options() + var/static/component_options = list( + PORT_TYPE_ANY, + PORT_TYPE_STRING, + PORT_TYPE_NUMBER, + PORT_TYPE_LIST, + PORT_TYPE_ATOM, + ) + router_options = add_option_port("Router Options", component_options) + +/obj/item/circuit_component/router/Initialize(mapload) + . = ..() + current_type = router_options.value + if(input_port_amount > 1) + input_selector = add_input_port("Input Selector", PORT_TYPE_NUMBER, default = 1) + if(output_port_amount > 1) + output_selector = add_input_port("Output Selector", PORT_TYPE_NUMBER, default = 1) + ins = list() + for(var/port_id in 1 to input_port_amount) + ins += add_input_port(input_port_amount > 1 ? "Input [port_id]" : "Input", current_type) + outs = list() + for(var/port_id in 1 to output_port_amount) + outs += add_output_port(output_port_amount > 1 ? "Output [port_id]" : "Output", current_type) + +/obj/item/circuit_component/router/Destroy() + input_selector = null + output_selector = null + ins.Cut() + ins = null + outs.Cut() + outs = null + return ..() + + +// If I is in range, L[I]. If I is out of range, wrap around. +#define WRAPACCESS(L, I) L[(((I||1)-1)%length(L)+length(L))%length(L)+1] +/obj/item/circuit_component/router/input_received(datum/port/input/port) + . = ..() + var/current_option = router_options.value + if(current_type != current_option) + current_type = current_option + for(var/datum/port/input/input as anything in ins) + input.set_datatype(current_type) + for(var/datum/port/output/output as anything in outs) + output.set_datatype(current_type) + if(.) + return + var/datum/port/input/input = WRAPACCESS(ins, input_selector ? input_selector.value : 1) + var/datum/port/output/output = WRAPACCESS(outs, output_selector ? output_selector.value : 1) + output.set_output(input.value) + +/obj/item/circuit_component/router/multiplexer + display_name = "Multiplexer" + desc = "Copies the input chosen by \"Input Selector\" to the output." + output_port_amount = 1 diff --git a/code/modules/wiremod/components/utility/setter.dm b/code/modules/wiremod/components/utility/setter.dm new file mode 100644 index 0000000000..6b5658645c --- /dev/null +++ b/code/modules/wiremod/components/utility/setter.dm @@ -0,0 +1,58 @@ +/** + * # Setter Component + * + * Stores the current input when triggered into a variable. + */ +/obj/item/circuit_component/setter + display_name = "Variable Setter" + desc = "A component that sets a variable globally on the circuit." + + circuit_flags = CIRCUIT_FLAG_OUTPUT_SIGNAL + + /// Variable name + var/datum/port/input/option/variable_name + + /// The input to store + var/datum/port/input/input_port + /// The trigger to store the current value of the input + var/datum/port/input/trigger + + var/current_type + +/obj/item/circuit_component/setter/populate_options() + variable_name = add_option_port("Variable", null) + +/obj/item/circuit_component/setter/add_to(obj/item/integrated_circuit/added_to) + . = ..() + variable_name.possible_options = added_to.circuit_variables + +/obj/item/circuit_component/setter/removed_from(obj/item/integrated_circuit/removed_from) + variable_name.possible_options = null + return ..() + +/obj/item/circuit_component/setter/Initialize(mapload) + . = ..() + input_port = add_input_port("Input", PORT_TYPE_ANY) + trigger = add_input_port("Store", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/setter/input_received(datum/port/input/port) + . = ..() + var/variable_string = variable_name.value + if(!variable_string) + return + + var/datum/circuit_variable/variable = parent.circuit_variables[variable_string] + if(!variable) + return + + if(variable.datatype != current_type) + current_type = variable.datatype + input_port.set_datatype(current_type) + + if(.) + return + + if(!COMPONENT_TRIGGERED_BY(trigger, port)) + return TRUE + + variable.set_value(input_port.value) diff --git a/code/modules/wiremod/components/utility/typecast.dm b/code/modules/wiremod/components/utility/typecast.dm new file mode 100644 index 0000000000..ebbb687da6 --- /dev/null +++ b/code/modules/wiremod/components/utility/typecast.dm @@ -0,0 +1,60 @@ +/** + * # Typecast Component + * + * A component that casts a value to a type if it matches or outputs null. + */ +/obj/item/circuit_component/typecast + display_name = "Typecast" + desc = "A component that casts a value to a type if it matches or outputs null." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + var/datum/port/input/option/typecast_options + + var/datum/port/input/input_value + + var/datum/port/output/output_value + + var/current_type + +/obj/item/circuit_component/typecast/Initialize(mapload) + . = ..() + current_type = typecast_options.value + input_value = add_input_port("Input", PORT_TYPE_ANY) + output_value = add_output_port("Output", current_type) + +/obj/item/circuit_component/typecast/populate_options() + var/static/list/component_options = list( + PORT_TYPE_STRING, + PORT_TYPE_NUMBER, + PORT_TYPE_LIST, + PORT_TYPE_ATOM, + ) + typecast_options = add_option_port("Typecast Options", component_options) + +/obj/item/circuit_component/typecast/input_received(datum/port/input/port) + . = ..() + var/current_option = typecast_options.value + if(current_type != current_option) + current_type = current_option + output_value.set_datatype(current_type) + + if(.) + return + + var/value = input_value.value + var/value_to_set = null + switch(current_option) + if(PORT_TYPE_STRING) + if(istext(value)) + value_to_set = value + if(PORT_TYPE_NUMBER) + if(isnum(value)) + value_to_set = value + if(PORT_TYPE_LIST) + if(islist(value)) + value_to_set = value + if(PORT_TYPE_ATOM) + if(isatom(value)) + value_to_set = value + + output_value.set_output(value_to_set) diff --git a/code/modules/wiremod/components/utility/typecheck.dm b/code/modules/wiremod/components/utility/typecheck.dm new file mode 100644 index 0000000000..8caa009fd8 --- /dev/null +++ b/code/modules/wiremod/components/utility/typecheck.dm @@ -0,0 +1,51 @@ +#define COMP_TYPECHECK_MOB "organism" +#define COMP_TYPECHECK_HUMAN "humanoid" + +/** + * # Typecheck Component + * + * Checks the type of a value + */ +/obj/item/circuit_component/compare/typecheck + display_name = "Typecheck" + desc = "A component that checks the type of its input." + + input_port_amount = 1 + var/datum/port/input/option/typecheck_options + +/obj/item/circuit_component/compare/typecheck/populate_options() + var/static/component_options = list( + PORT_TYPE_STRING, + PORT_TYPE_NUMBER, + PORT_TYPE_LIST, + PORT_TYPE_ATOM, + COMP_TYPECHECK_MOB, + COMP_TYPECHECK_HUMAN, + ) + typecheck_options = add_option_port("Typecheck Options", component_options) + +/obj/item/circuit_component/compare/typecheck/do_comparisons(list/ports) + if(!length(ports)) + return + . = FALSE + + // We're only comparing the first port/value. There shouldn't be any more. + var/datum/port/input/input_port = ports[1] + var/input_val = input_port.value + switch(typecheck_options.value) + if(PORT_TYPE_STRING) + return istext(input_val) + if(PORT_TYPE_NUMBER) + return isnum(input_val) + if(PORT_TYPE_LIST) + return islist(input_val) + if(PORT_TYPE_ATOM) + return isatom(input_val) + if(COMP_TYPECHECK_MOB) + return ismob(input_val) + if(COMP_TYPECHECK_HUMAN) + return ishuman(input_val) + + +#undef COMP_TYPECHECK_MOB +#undef COMP_TYPECHECK_HUMAN diff --git a/code/modules/wiremod/core/admin_panel.dm b/code/modules/wiremod/core/admin_panel.dm new file mode 100644 index 0000000000..33af02f514 --- /dev/null +++ b/code/modules/wiremod/core/admin_panel.dm @@ -0,0 +1,75 @@ +/// An admin verb to view all circuits, plus useful information +/datum/admins/proc/view_all_circuits() + set category = "Admin.Game" + set name = "View All Circuits" + + var/static/datum/circuit_admin_panel/circuit_admin_panel = new + circuit_admin_panel.ui_interact(usr) + +/datum/circuit_admin_panel + +/datum/circuit_admin_panel/ui_static_data(mob/user) + var/list/data = list() + data["circuits"] = list() + + for (var/obj/item/integrated_circuit/circuit as anything in GLOB.integrated_circuits) + var/datum/mind/inserter = circuit.inserter_mind?.resolve() + + data["circuits"] += list(list( + "ref" = REF(circuit), + "name" = "[circuit.name] in [loc_name(circuit)]", + "creator" = circuit.get_creator(), + "has_inserter" = !isnull(inserter), + )) + + return data + +/datum/circuit_admin_panel/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if (.) + return . + + if (!istext(params["circuit"])) + return FALSE + + var/obj/item/integrated_circuit/circuit = locate(params["circuit"]) + if (!istype(circuit)) + to_chat(usr, span_warning("That circuit no longer exists.")) + return FALSE + + switch (action) + if ("duplicate_circuit") + if (alert(usr, "This will spawn the new circuit at where you are, are you sure?", "Confirm", "Yes", "No") != "Yes") + return FALSE + + var/list/errors = list() + + var/obj/item/integrated_circuit/loaded/new_circuit = new(usr.drop_location()) + new_circuit.load_circuit_data(circuit.convert_to_json(), errors) + + if (length(errors)) + to_chat(usr, span_warning("Somehow, duplicating the circuit failed:")) + for (var/error in errors) + to_chat(usr, span_warning(error)) + if ("follow_circuit") + usr.client?.admin_follow(circuit) + if ("save_circuit") + circuit.attempt_save_to(usr.client) + if ("vv_circuit") + usr.client?.debug_variables(circuit) + if ("open_circuit") + circuit.ui_interact(usr) + if ("open_player_panel") + var/datum/mind/inserter = circuit.inserter_mind?.resolve() + usr.client?.holder?.show_player_panel(inserter?.current) + + return TRUE + +/datum/circuit_admin_panel/ui_state(mob/user) + return GLOB.admin_state + +/datum/circuit_admin_panel/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "CircuitAdminPanel") + ui.open() diff --git a/code/modules/wiremod/core/component.dm b/code/modules/wiremod/core/component.dm new file mode 100644 index 0000000000..579ab7645c --- /dev/null +++ b/code/modules/wiremod/core/component.dm @@ -0,0 +1,270 @@ +/** + * # Integrated Circuit Component + * + * A component that performs a function when given an input + * + * Can be attached to an integrated circuitboard, where it can then + * be connected between other components to provide an output or to receive + * an input. This is the base type of all components + */ +/obj/item/circuit_component + name = COMPONENT_DEFAULT_NAME + icon = 'icons/obj/module.dmi' + icon_state = "component" + inhand_icon_state = "electronic" + + /// The name of the component shown on the UI + var/display_name = "Generic" + + /// The integrated_circuit that this component is attached to. + var/obj/item/integrated_circuit/parent + + /// A list that contains the outpurt ports on this component + /// Used to connect between the ports + var/list/datum/port/output/output_ports = list() + + /// A list that contains the components the input ports on this component + /// Used to connect between the ports + var/list/datum/port/input/input_ports = list() + + /// Generic trigger input for triggering this component + var/datum/port/input/trigger_input + var/datum/port/output/trigger_output + + /// The flags of the circuit to control basic generalised behaviour. + var/circuit_flags = NONE + + /// Used to determine the x position of the component within the UI + var/rel_x = 0 + /// Used to determine the y position of the component within the UI + var/rel_y = 0 + + /// The power usage whenever this component receives an input + var/power_usage_per_input = 1 + + // Whether the component is removable or not. Only affects user UI + var/removable = TRUE + + // Defines which shells support this component. Only used as an informational guide, does not restrict placing these components in circuits. + var/required_shells = null + +/// Called when the option ports should be set up +/obj/item/circuit_component/proc/populate_options() + return + +/// Extension of add_input_port. Simplifies the code to make an option port to reduce boilerplate +/obj/item/circuit_component/proc/add_option_port(name, list/list_to_use) + return add_input_port(name, PORT_TYPE_OPTION, port_type = /datum/port/input/option, extra_args = list("possible_options" = list_to_use)) + +/obj/item/circuit_component/Initialize(mapload) + . = ..() + if(name == COMPONENT_DEFAULT_NAME) + name = "[lowertext(display_name)] [COMPONENT_DEFAULT_NAME]" + populate_options() + + return INITIALIZE_HINT_LATELOAD + +/obj/item/circuit_component/LateInitialize() + . = ..() + if(circuit_flags & CIRCUIT_FLAG_INPUT_SIGNAL) + trigger_input = add_input_port("Trigger", PORT_TYPE_SIGNAL) + if(circuit_flags & CIRCUIT_FLAG_OUTPUT_SIGNAL) + trigger_output = add_output_port("Triggered", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/Destroy() + if(parent) + // Prevents a Destroy() recursion + var/obj/item/integrated_circuit/old_parent = parent + parent = null + old_parent.remove_component(src) + + trigger_input = null + trigger_output = null + + QDEL_LIST(output_ports) + QDEL_LIST(input_ports) + return ..() + +/** + * Called when a shell is registered from the component/the component is added to a circuit. + * + * Register all signals here on the shell. + * Arguments: + * * shell - Shell being registered + */ +/obj/item/circuit_component/proc/register_shell(atom/movable/shell) + return + +/** + * Called when a shell is unregistered from the component/the component is removed from a circuit. + * + * Unregister all signals here on the shell. + * Arguments: + * * shell - Shell being unregistered + */ +/obj/item/circuit_component/proc/unregister_shell(atom/movable/shell) + return + +/** + * Disconnects a component from other components + * + * Disconnects both the input and output ports of the component + */ +/obj/item/circuit_component/proc/disconnect() + for(var/datum/port/output/port_to_disconnect as anything in output_ports) + port_to_disconnect.disconnect_all() + + for(var/datum/port/input/port_to_disconnect as anything in input_ports) + port_to_disconnect.disconnect_all() + +/** + * Adds an input port and returns it + * + * Arguments: + * * name - The name of the input port + * * type - The datatype it handles + * * trigger - Whether this input port triggers an update on the component when updated. + */ +/obj/item/circuit_component/proc/add_input_port(name, type, trigger = TRUE, default = null, index = null, port_type = /datum/port/input, extra_args = null) + var/list/arguments = list(src) + arguments += args + if(extra_args) + arguments += extra_args + var/datum/port/input/input_port = new port_type(arglist(arguments)) + if(index) + input_ports.Insert(index, input_port) + else + input_ports += input_port + if(parent) + SStgui.update_uis(parent) + return input_port + +/** + * Removes an input port and deletes it. This will not cleanup any references made by derivatives of the circuit component + * + * Arguments: + * * input_port - The input port to remove. + */ +/obj/item/circuit_component/proc/remove_input_port(datum/port/input/input_port) + input_ports -= input_port + qdel(input_port) + if(parent) + SStgui.update_uis(parent) + +/** + * Adds an output port and returns it + * + * Arguments: + * * name - The name of the output port + * * type - The datatype it handles. + */ +/obj/item/circuit_component/proc/add_output_port(name, type) + var/list/arguments = list(src) + arguments += args + var/datum/port/output/output_port = new(arglist(arguments)) + output_ports += output_port + return output_port + +/** + * Removes an output port and deletes it. This will not cleanup any references made by derivatives of the circuit component + * + * Arguments: + * * output_port - The output port to remove. + */ +/obj/item/circuit_component/proc/remove_output_port(datum/port/output/output_port) + output_ports -= output_port + qdel(output_port) + if(parent) + SStgui.update_uis(parent) + +/** + * Called whenever an input is received from one of the ports. + * + * Return value indicates that the circuit should not do anything. Also prevents an output signal. + * Arguments: + * * port - Can be null. The port that sent the input + */ +/obj/item/circuit_component/proc/input_received(datum/port/input/port) + SHOULD_CALL_PARENT(TRUE) + if(!parent?.on) + return TRUE + + if(!parent.admin_only) + if(circuit_flags & CIRCUIT_FLAG_ADMIN) + message_admins("[display_name] tried to execute on [parent.get_creator_admin()] that has admin_only set to 0") + return TRUE + + var/obj/item/stock_parts/cell/cell = parent.get_cell() + if(!cell?.use(power_usage_per_input)) + return TRUE + + if((circuit_flags & CIRCUIT_FLAG_INPUT_SIGNAL) && !COMPONENT_TRIGGERED_BY(trigger_input, port)) + return TRUE + +/// Called when this component is about to be added to an integrated_circuit. +/obj/item/circuit_component/proc/add_to(obj/item/integrated_circuit/added_to) + return TRUE + +/// Called when this component is removed from an integrated_circuit. +/obj/item/circuit_component/proc/removed_from(obj/item/integrated_circuit/removed_from) + return + +/** + * Gets the UI notices to be displayed on the CircuitInfo panel. + * + * Returns a list of buttons in the following format + * list( + * "icon" = ICON(string) + * "content" = CONTENT(string) + * "color" = COLOR(string, not a hex) + * ) + */ +/obj/item/circuit_component/proc/get_ui_notices() + . = list() + + if(!removable) + . += create_ui_notice("Unremovable", "red", "lock") + + if(length(required_shells)) + . += create_ui_notice("Supported Shells:", "green", "notes-medical") + for(var/atom/movable/shell as anything in required_shells) + . += create_ui_notice(initial(shell.name), "green", "plus-square") + + if(length(input_ports)) + . += create_ui_notice("Power Usage Per Input: [power_usage_per_input]", "orange", "bolt") + +/** + * Creates a UI notice entry to be used in get_ui_notices() + * + * Returns a list that can then be added to the return list in get_ui_notices() + */ +/obj/item/circuit_component/proc/create_ui_notice(content, color, icon) + SHOULD_BE_PURE(TRUE) + SHOULD_NOT_OVERRIDE(TRUE) + return list(list( + "icon" = icon, + "content" = content, + "color" = color, + )) + +/** + * Creates a table UI notice entry to be used in get_ui_notices() + * + * Returns a list that can then be added to the return list in get_ui_notices() + * Used by components to list their available columns. Recommended to use at the end of get_ui_notices() + */ +/obj/item/circuit_component/proc/create_table_notices(list/entries) + SHOULD_BE_PURE(TRUE) + SHOULD_NOT_OVERRIDE(TRUE) + . = list() + . += create_ui_notice("Available Columns:", "grey", "question-circle") + + + for(var/entry in entries) + . += create_ui_notice("Column Name: '[entry]'", "grey", "columns") + +/obj/item/circuit_component/proc/register_usb_parent(atom/movable/parent) + return + +/obj/item/circuit_component/proc/unregister_usb_parent(atom/movable/parent) + return diff --git a/code/modules/wiremod/core/component_printer.dm b/code/modules/wiremod/core/component_printer.dm new file mode 100644 index 0000000000..948ea080e7 --- /dev/null +++ b/code/modules/wiremod/core/component_printer.dm @@ -0,0 +1,394 @@ +/// Component printer, creates components for integrated circuits. +/obj/machinery/component_printer + name = "component printer" + desc = "Produces components for the creation of integrated circuits." + icon = 'icons/obj/wiremod_fab.dmi' + icon_state = "fab-idle" + circuit = /obj/item/circuitboard/machine/component_printer + + /// The internal material bus + var/datum/component/remote_materials/materials + + density = TRUE + + /// The techweb the printer will get researched designs from + var/datum/techweb/techweb + +/obj/machinery/component_printer/Initialize(mapload) + . = ..() + + techweb = SSresearch.science_tech + + materials = AddComponent( \ + /datum/component/remote_materials, \ + "component_printer", \ + mapload, \ + mat_container_flags = BREAKDOWN_FLAGS_LATHE, \ + ) + +/obj/machinery/component_printer/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ComponentPrinter", name) + ui.open() + +/obj/machinery/component_printer/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/sheetmaterials) + ) + +/obj/machinery/component_printer/ui_act(action, list/params) + . = ..() + if (.) + return + + switch (action) + if ("print") + var/design_id = params["designId"] + if (!techweb.researched_designs[design_id]) + return TRUE + + var/datum/design/design = SSresearch.techweb_design_by_id(design_id) + if (!(design.build_type & COMPONENT_PRINTER)) + return TRUE + + if (materials.on_hold()) + say("Mineral access is on hold, please contact the quartermaster.") + return TRUE + + if (!materials.mat_container?.has_materials(design.materials)) + say("Not enough materials.") + return TRUE + + balloon_alert_to_viewers("printed [design.name]") + materials.mat_container?.use_materials(design.materials) + materials.silo_log(src, "printed", -1, design.name, design.materials) + var/atom/printed_design = new design.build_path(drop_location()) + printed_design.pixel_x = printed_design.base_pixel_x + rand(-5, 5) + printed_design.pixel_y = printed_design.base_pixel_y + rand(-5, 5) + if ("remove_mat") + var/datum/material/material = locate(params["ref"]) + var/amount = text2num(params["amount"]) + + if (!amount) + return TRUE + + // SAFETY: eject_sheets checks for valid mats + materials.eject_sheets(material, amount) + + return TRUE + +/obj/machinery/component_printer/ui_data(mob/user) + var/list/data = list() + data["materials"] = materials.mat_container.ui_data() + return data + +/obj/machinery/component_printer/ui_static_data(mob/user) + var/list/data = list() + + var/list/designs = list() + + // for (var/datum/design/component/component_design_type as anything in subtypesof(/datum/design/component)) + for (var/researched_design_id in techweb.researched_designs) + var/datum/design/design = SSresearch.techweb_design_by_id(researched_design_id) + if (!(design.build_type & COMPONENT_PRINTER)) + continue + + designs[researched_design_id] = list( + "name" = design.name, + "description" = design.desc, + "materials" = get_material_cost_data(design.materials), + "categories" = design.category, + ) + + data["designs"] = designs + + return data + +/obj/machinery/component_printer/crowbar_act(mob/living/user, obj/item/tool) + if(..()) + return TRUE + return default_deconstruction_crowbar(tool) + +/obj/machinery/component_printer/screwdriver_act(mob/living/user, obj/item/tool) + if(..()) + return TRUE + return default_deconstruction_screwdriver(user, "fab-o", "fab-idle", tool) + +/obj/machinery/component_printer/proc/get_material_cost_data(list/materials) + var/list/data = list() + + for (var/datum/material/material_type as anything in materials) + data[initial(material_type.name)] = materials[material_type] + + return data + +/obj/item/circuitboard/machine/component_printer + name = "\improper Component Printer (Machine Board)" + greyscale_colors = CIRCUIT_COLOR_SCIENCE + build_path = /obj/machinery/component_printer + req_components = list( + /obj/item/stock_parts/matter_bin = 2, + /obj/item/stock_parts/manipulator = 2, + /obj/item/reagent_containers/glass/beaker = 2, + ) + +/obj/machinery/debug_component_printer + name = "debug component printer" + desc = "Produces components for the creation of integrated circuits." + icon = 'icons/obj/wiremod_fab.dmi' + icon_state = "fab-idle" + + /// All of the possible circuit designs stored by this debug printer + var/list/all_circuit_designs + + density = TRUE + +/obj/machinery/debug_component_printer/Initialize(mapload) + . = ..() + all_circuit_designs = list() + + for(var/id in SSresearch.techweb_designs) + var/datum/design/design = SSresearch.techweb_design_by_id(id) + if((design.build_type & COMPONENT_PRINTER) && design.build_path) + all_circuit_designs[design.build_path] = list( + "name" = design.name, + "description" = design.desc, + "materials" = design.materials, + "categories" = design.category + ) + + for(var/obj/item/circuit_component/component as anything in subtypesof(/obj/item/circuit_component)) + var/categories = list("Inaccessible") + if(initial(component.circuit_flags) & CIRCUIT_FLAG_ADMIN) + categories = list("Admin") + if(!(component in all_circuit_designs)) + all_circuit_designs[component] = list( + "name" = initial(component.display_name), + "description" = initial(component.desc), + "materials" = list(), + "categories" = categories, + ) + +/obj/machinery/debug_component_printer/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ComponentPrinter", name) + ui.open() + +/obj/machinery/debug_component_printer/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/sheetmaterials) + ) + +/obj/machinery/debug_component_printer/ui_act(action, list/params) + . = ..() + if (.) + return + + switch (action) + if ("print") + var/build_path = text2path(params["designId"]) + if (!build_path) + return TRUE + + var/list/design = all_circuit_designs[build_path] + if(!design) + return TRUE + + balloon_alert_to_viewers("printed [design["name"]]") + var/atom/printed_design = new build_path(drop_location()) + printed_design.pixel_x = printed_design.base_pixel_x + rand(-5, 5) + printed_design.pixel_y = printed_design.base_pixel_y + rand(-5, 5) + + return TRUE + +/obj/machinery/debug_component_printer/ui_static_data(mob/user) + var/list/data = list() + + data["materials"] = list() + data["designs"] = all_circuit_designs + + return data + +/// Module duplicator, allows you to save and recreate module components. +/obj/machinery/module_duplicator + name = "module duplicator" + desc = "Allows you to duplicate module components so that you don't have to recreate them. Scan a module component over this machine to add it as an entry." + icon = 'icons/obj/wiremod_fab.dmi' + icon_state = "module-fab-idle" + circuit = /obj/item/circuitboard/machine/module_duplicator + + /// The internal material bus + var/datum/component/remote_materials/materials + + density = TRUE + + var/list/scanned_designs = list() + + var/cost_per_component = 1000 + +/obj/machinery/module_duplicator/Initialize(mapload) + . = ..() + + materials = AddComponent( \ + /datum/component/remote_materials, \ + "module_duplicator", \ + mapload, \ + mat_container_flags = BREAKDOWN_FLAGS_LATHE, \ + ) + +/obj/machinery/module_duplicator/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ComponentPrinter", name) + ui.open() + +/obj/machinery/module_duplicator/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/sheetmaterials) + ) + +/obj/machinery/module_duplicator/ui_act(action, list/params) + . = ..() + if (.) + return + + switch (action) + if ("print") + var/design_id = text2num(params["designId"]) + + if (design_id < 1 || design_id > length(scanned_designs)) + return TRUE + + var/list/design = scanned_designs[design_id] + + if (materials.on_hold()) + say("Mineral access is on hold, please contact the quartermaster.") + return TRUE + + if (!materials.mat_container?.has_materials(design["materials"])) + say("Not enough materials.") + return TRUE + + balloon_alert_to_viewers("printed [design["name"]]") + materials.mat_container?.use_materials(design["materials"]) + materials.silo_log(src, "printed", -1, design["name"], design["materials"]) + print_module(design) + if ("remove_mat") + var/datum/material/material = locate(params["ref"]) + var/amount = text2num(params["amount"]) + + if (!amount) + return TRUE + + // SAFETY: eject_sheets checks for valid mats + materials.eject_sheets(material, amount) + + return TRUE + +/obj/machinery/module_duplicator/proc/print_module(list/design) + flick("module-fab-print", src) + addtimer(CALLBACK(src, .proc/finish_module_print, design), 1.6 SECONDS) + +/obj/machinery/module_duplicator/proc/finish_module_print(list/design) + var/obj/item/circuit_component/module/module = new(drop_location()) + module.load_data_from_list(design["dupe_data"]) + module.pixel_x = module.base_pixel_x + rand(-5, 5) + module.pixel_y = module.base_pixel_y + rand(-5, 5) + +/obj/machinery/module_duplicator/attackby(obj/item/weapon, mob/user, params) + if(!istype(weapon, /obj/item/circuit_component/module)) + return ..() + + var/obj/item/circuit_component/module/module = weapon + if(module.circuit_flags & CIRCUIT_FLAG_UNDUPEABLE) + balloon_alert(user, "module cannot be saved!") + return ..() + + if(module.display_name == initial(module.display_name)) + balloon_alert(user, "module needs a name!") + return ..() + + for(var/list/component_data as anything in scanned_designs) + if(component_data["name"] == module.display_name) + balloon_alert(user, "module name already exists!") + return ..() + + var/total_cost = 0 + for(var/obj/item/circuit_component/component as anything in module.internal_circuit.attached_components) + if(component.circuit_flags & CIRCUIT_FLAG_UNDUPEABLE) + balloon_alert(user, "module contains prohibited components!") + return ..() + + total_cost += cost_per_component + + var/list/data = list() + + data["dupe_data"] = list() + module.save_data_to_list(data["dupe_data"]) + + data["name"] = module.display_name + data["desc"] = "A module that has been loaded in by [user]." + data["materials"] = list(/datum/material/glass = total_cost) + + flick("module-fab-scan", src) + addtimer(CALLBACK(src, .proc/finish_module_scan, user, data), 1.4 SECONDS) + +/obj/machinery/module_duplicator/proc/finish_module_scan(mob/user, data) + scanned_designs += list(data) + + balloon_alert(user, "module has been saved.") + playsound(src, 'sound/machines/ping.ogg', 50) + +/obj/machinery/module_duplicator/ui_data(mob/user) + var/list/data = list() + data["materials"] = materials.mat_container.ui_data() + return data + +/obj/machinery/module_duplicator/ui_static_data(mob/user) + var/list/data = list() + + var/list/designs = list() + + var/index = 1 + for (var/list/design as anything in scanned_designs) + designs["[index]"] = list( + "name" = design["name"], + "description" = design["desc"], + "materials" = get_material_cost_data(design["materials"]), + "categories" = list("Circuitry"), + ) + index++ + + data["designs"] = designs + + return data + +/obj/machinery/module_duplicator/crowbar_act(mob/living/user, obj/item/tool) + if(..()) + return TRUE + return default_deconstruction_crowbar(tool) + +/obj/machinery/module_duplicator/screwdriver_act(mob/living/user, obj/item/tool) + if(..()) + return TRUE + return default_deconstruction_screwdriver(user, "module-fab-o", "module-fab-idle", tool) + +/obj/machinery/module_duplicator/proc/get_material_cost_data(list/materials) + var/list/data = list() + + for (var/datum/material/material_type as anything in materials) + data[initial(material_type.name)] = materials[material_type] + + return data + +/obj/item/circuitboard/machine/module_duplicator + name = "\improper Module Duplicator (Machine Board)" + greyscale_colors = CIRCUIT_COLOR_SCIENCE + build_path = /obj/machinery/module_duplicator + req_components = list( + /obj/item/stock_parts/matter_bin = 2, + /obj/item/stock_parts/manipulator = 2, + /obj/item/reagent_containers/glass/beaker = 2, + ) diff --git a/code/modules/wiremod/core/datatypes.dm b/code/modules/wiremod/core/datatypes.dm new file mode 100644 index 0000000000..b81ad0876b --- /dev/null +++ b/code/modules/wiremod/core/datatypes.dm @@ -0,0 +1,91 @@ +// An assoc list of all the possible datatypes. +GLOBAL_LIST_INIT(circuit_datatypes, generate_circuit_datatypes()) + +/proc/generate_circuit_datatypes() + var/list/datatypes_by_key = list() + for(var/datum/circuit_datatype/type as anything in subtypesof(/datum/circuit_datatype)) + if(!initial(type.datatype)) + continue + datatypes_by_key[initial(type.datatype)] = new type() + return datatypes_by_key + +/** + * A circuit datatype. Used to determine the datatype of a port and also handle any additional behaviour. + */ +/datum/circuit_datatype + /// The key. Used to identify the datatype. Should be a define. + var/datatype + + /// The color of the port in the UI. Doesn't work with hex colours. + var/color = "blue" + + /// The flags of the circuit datatype + var/datatype_flags = 0 + +/** + * Returns the value to be set for the port + * + * Used for implicit conversions between outputs and inputs (e.g. number -> string) + * and applying/removing signals on inputs + */ +/datum/circuit_datatype/proc/convert_value(datum/port/port, value_to_convert) + return value_to_convert + +/** + * Determines if a datatype is compatible with another port of a different type. + * Note: This is ALWAYS called on the input port, never on the output port. + * Inputs need to care about what types they're receiving, output ports don't have to care. + * + * Arguments: + * * datatype_to_check - The datatype to check + */ +/datum/circuit_datatype/proc/can_receive_from_datatype(datatype_to_check) + return datatype == datatype_to_check // This is already done by default on the input port. + +/** + * Called when the datatype is given to a port. + * + * Arguments: + * * gained_port - The gained port. + */ +/datum/circuit_datatype/proc/on_gain(datum/port/gained_port) + return + +/** + * Called when the datatype is removed from a port. + * + * Arguments: + * * lost_port - The removed port. + */ +/datum/circuit_datatype/proc/on_loss(datum/port/lost_port) + return + +/** + * Determines if a port is compatible with this datatype. + * This WILL throw a runtime if it returns false. This is for sanity checking and it should not return false + * unless under extraordinary circumstances or people fail to write proper code. + * + * Arguments: + * * port - The port to check if it is compatible. + */ +/datum/circuit_datatype/proc/is_compatible(datum/port/port) + return TRUE + +/** + * The data to send to the UI attached to the port. Received by the type in FUNDAMENTAL_PORT_TYPES + * + * Arguments: + * * port - The port sending the data. + */ +/datum/circuit_datatype/proc/datatype_ui_data(datum/port/port) + return + +/** + * When an input is manually set by a player. This is where extra sanitizing can happen. Will still call convert_value() + * + * Arguments: + * * port - The port sending the data. + * * + */ +/datum/circuit_datatype/proc/handle_manual_input(datum/port/input/port, mob/user, user_input) + return user_input diff --git a/code/modules/wiremod/core/duplicator.dm b/code/modules/wiremod/core/duplicator.dm new file mode 100644 index 0000000000..fd215255ba --- /dev/null +++ b/code/modules/wiremod/core/duplicator.dm @@ -0,0 +1,227 @@ +#define LOG_ERROR(list, error) if(list) { list.Add(error) } + +// Determines if a port can have a predefined input value if it is of this type. +GLOBAL_LIST_INIT(circuit_dupe_whitelisted_types, list( + PORT_TYPE_NUMBER, + PORT_TYPE_STRING, + PORT_TYPE_LIST, + PORT_TYPE_ANY, + PORT_TYPE_OPTION, +)) + +/// Loads a circuit based on json data at a location. Can also load usb connections, such as arrest consoles. +/obj/item/integrated_circuit/proc/load_circuit_data(json_data, list/errors) + var/list/general_data = json_decode(json_data) + + if(!general_data) + LOG_ERROR(errors, "Invalid json format!") + return + + if(general_data["display_name"]) + set_display_name(general_data["display_name"]) + + var/list/variable_data = general_data["variables"] + for(var/list/variable as anything in variable_data) + var/variable_name = variable["name"] + circuit_variables[variable_name] = new /datum/circuit_variable(variable_name, variable["datatype"]) + + admin_only = general_data["admin_only"] + + var/list/circuit_data = general_data["components"] + var/list/identifiers_to_circuit = list() + for(var/identifier in circuit_data) + var/list/component_data = circuit_data[identifier] + var/type = text2path(component_data["type"]) + if(!ispath(type, /obj/item/circuit_component)) + LOG_ERROR(errors, "Invalid path for circuit component, expected [/obj/item/circuit_component], got [type]") + continue + var/obj/item/circuit_component/component = load_component(type) + identifiers_to_circuit[identifier] = component + component.load_data_from_list(component_data) + + var/list/input_ports_data = component_data["input_ports_stored_data"] + for(var/port_name in input_ports_data) + var/datum/port/input/port + var/list/port_data = input_ports_data[port_name] + for(var/datum/port/input/port_to_check as anything in component.input_ports) + if(port_to_check.name == port_name) + port = port_to_check + break + + port.set_input(port_data["stored_data"]) + + var/list/external_objects = general_data["external_objects"] + for(var/identifier in external_objects) + var/list/object_data = external_objects[identifier] + var/type = text2path(object_data["type"]) + if(!ispath(type)) + LOG_ERROR(errors, "Invalid path for external object, expected a path, got [type]") + continue + var/atom/movable/object = new type(drop_location()) + var/list/connected_components = list() + for(var/component_id in object_data["connected_components"]) + var/obj/item/circuit_component/component = identifiers_to_circuit[component_id] + if(!component) + continue + connected_components += component + SEND_SIGNAL(object, COMSIG_MOVABLE_CIRCUIT_LOADED, src, connected_components) + + for(var/identifier in identifiers_to_circuit) + var/obj/item/circuit_component/component = identifiers_to_circuit[identifier] + var/list/component_data = circuit_data[identifier] + + var/list/connections = component_data["connections"] + for(var/port_name in connections) + var/datum/port/input/port + var/list/connection_data = connections[port_name] + for(var/datum/port/input/port_to_check as anything in component.input_ports) + if(port_to_check.name == port_name) + port = port_to_check + break + + if(!port) + LOG_ERROR(errors, "Port [port_name] not found for [component.type].") + continue + + if(connection_data["stored_data"]) + if(!(port.datatype in GLOB.circuit_dupe_whitelisted_types)) + continue + port.set_input(connection_data["stored_data"]) + continue + + // The || list(connected_data) is for backwards compatibility with when inputs could only be connected to up to one output. + for(var/list/output_data in (connection_data["connected_ports"] || list(connection_data))) + var/obj/item/circuit_component/connected_component = identifiers_to_circuit[output_data["component_id"]] + if(!connected_component) + LOG_ERROR(errors, "No connected component found for [component.type] for port [connection_data["port_name"]]. (connected component identifier: [connection_data["component_id"]])") + continue + + var/datum/port/output/output_port + var/output_port_name = output_data["port_name"] + for(var/datum/port/output/port_to_check as anything in connected_component.output_ports) + if(port_to_check.name == output_port_name) + output_port = port_to_check + break + + if(!output_port) + LOG_ERROR(errors, "No output port found for [component.type] for port [output_port_name] on component [connected_component.type]") + continue + + port.connect(output_port) + +#undef LOG_ERROR + +/// Converts a circuit into json. +/obj/item/integrated_circuit/proc/convert_to_json() + var/list/circuit_to_identifiers = list() + var/list/identifiers = list() + var/list/external_objects = list() // Objects that are connected to a component. These objects will be linked to the components. + for(var/obj/item/circuit_component/component as anything in attached_components) + var/identifier = "[component.type][length(identifiers)]" + identifiers += identifier + circuit_to_identifiers[component] = identifier + var/list/objects = list() + SEND_SIGNAL(component, COMSIG_CIRCUIT_COMPONENT_SAVE, objects) + + for(var/atom/movable/object as anything in objects) + if(object in external_objects) + external_objects[object] += identifier + continue + external_objects[object] = list(identifier) + + var/list/circuit_data = list() + for(var/obj/item/circuit_component/component as anything in circuit_to_identifiers) + var/identifier = circuit_to_identifiers[component] + var/list/component_data = list() + + component_data["type"] = component.type + + var/list/connections = list() + var/list/input_ports_stored_data = list() + for(var/datum/port/input/input as anything in component.input_ports) + var/list/connection_data = list() + if(!length(input.connected_ports)) + if(isnull(input.value) || !(input.datatype in GLOB.circuit_dupe_whitelisted_types)) + continue + connection_data["stored_data"] = input.value + input_ports_stored_data[input.name] = connection_data + continue + connection_data["connected_ports"] = list() + for(var/datum/port/output/output as anything in input.connected_ports) + connection_data["connected_ports"] += list(list( + "component_id" = circuit_to_identifiers[output.connected_component], + "port_name" = output.name, + )) + connections[input.name] = connection_data + component_data["connections"] = connections + component_data["input_ports_stored_data"] = input_ports_stored_data + + component.save_data_to_list(component_data) + circuit_data[identifier] = component_data + + var/external_objects_key = list() + for(var/atom/movable/object as anything in external_objects) + var/list/new_data = list() + new_data["type"] = object.type + new_data["connected_components"] = external_objects[object] + external_objects_key["[object.type][length(external_objects_key)]"] = new_data + + var/list/general_data = list() + general_data["components"] = circuit_data + general_data["external_objects"] = external_objects_key + general_data["display_name"] = display_name + general_data["admin_only"] = admin_only + + var/list/variables = list() + for(var/variable_identifier in circuit_variables) + var/list/new_data = list() + var/datum/circuit_variable/variable = circuit_variables[variable_identifier] + new_data["name"] = variable.name + new_data["datatype"] = variable.datatype + variables += list(new_data) + general_data["variables"] = variables + + return json_encode(general_data) + +/obj/item/integrated_circuit/proc/load_component(type) + var/obj/item/circuit_component/component = new type(src) + add_component(component) + return component + +/// Saves data to a list. Shouldn't be used unless you are quite literally saving the data of a component to a list. Input value is the list to save the data to +/obj/item/circuit_component/proc/save_data_to_list(list/component_data) + component_data["rel_x"] = rel_x + component_data["rel_y"] = rel_y + +/// Loads data from a list +/obj/item/circuit_component/proc/load_data_from_list(list/component_data) + rel_x = component_data["rel_x"] + rel_y = component_data["rel_y"] + +/client/proc/load_circuit() + set name = "Load Circuit" + set category = "Admin.Fun" + + if(!check_rights(R_VAREDIT)) + return + + var/list/errors = list() + + var/option = alert(usr, "Load by file or direct input?", "Load by file or string", "File", "Direct Input") + var/txt + switch(option) + if("File") + txt = file2text(tgui_input_num(usr, "Input File") as file|null) + if("Direct Input") + txt = tgui_input_num(usr, "Input JSON", "Input JSON") as text|null + + if(!txt) + return + + var/obj/item/integrated_circuit/loaded/circuit = new(mob.drop_location()) + circuit.load_circuit_data(txt, errors) + + if(length(errors)) + to_chat(src, span_warning("The following errors were found whilst compiling the circuit data:")) + for(var/error in errors) + to_chat(src, span_warning(error)) diff --git a/code/modules/wiremod/core/integrated_circuit.dm b/code/modules/wiremod/core/integrated_circuit.dm new file mode 100644 index 0000000000..b767615e87 --- /dev/null +++ b/code/modules/wiremod/core/integrated_circuit.dm @@ -0,0 +1,600 @@ +/// A list of all integrated circuits +GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit) + +/** + * # Integrated Circuitboard + * + * A circuitboard that holds components that work together + * + * Has a limited amount of power. + */ +/obj/item/integrated_circuit + name = "integrated circuit" + desc = "By inserting components and a cell into this, wiring them up, and putting them into a shell, anyone can pretend to be a programmer." + icon = 'icons/obj/module.dmi' + icon_state = "integrated_circuit" + inhand_icon_state = "electronic" + + /// The name that appears on the shell. + var/display_name = "" + + /// The max length of the name. + var/label_max_length = 24 + + /// The power of the integrated circuit + var/obj/item/stock_parts/cell/cell + + /// The shell that this circuitboard is attached to. Used by components. + var/atom/movable/shell + + /// The attached components + var/list/obj/item/circuit_component/attached_components = list() + + /// Whether the integrated circuit is on or not. Handled by the shell. + var/on = FALSE + + /// Whether the integrated circuit is locked or not. Handled by the shell. + var/locked = FALSE + + /// Whether the integrated circuit is admin only. Disables power usage and allows admin circuits to be attached, at the cost of making it inaccessible to regular users. + var/admin_only = FALSE + + /// The ID that is authorized to unlock/lock the shell so that the circuit can/cannot be removed. + var/datum/weakref/owner_id + + /// The current examined component. Used in IntegratedCircuit UI + var/datum/weakref/examined_component + + /// Set by the shell. Holds the reference to the owner who inserted the component into the shell. + var/datum/weakref/inserter_mind + + /// Variables stored on this integrated circuit. with a `variable_name = value` structure + var/list/datum/circuit_variable/circuit_variables = list() + + /// The maximum amount of setters and getters a circuit can have + var/max_setters_and_getters = 30 + + /// The current setter and getter count the circuit has. + var/setter_and_getter_count = 0 + + /// X position of the examined_component + var/examined_rel_x = 0 + + /// Y position of the examined component + var/examined_rel_y = 0 + + /// The X position of the screen. Used for adding components + var/screen_x = 0 + + /// The Y position of the screen. Used for adding components. + var/screen_y = 0 + +/obj/item/integrated_circuit/Initialize(mapload) + . = ..() + + GLOB.integrated_circuits += src + + RegisterSignal(src, COMSIG_ATOM_USB_CABLE_TRY_ATTACH, .proc/on_atom_usb_cable_try_attach) + +/obj/item/integrated_circuit/loaded/Initialize(mapload) + . = ..() + set_cell(new /obj/item/stock_parts/cell/high(src)) + +/obj/item/integrated_circuit/Destroy() + for(var/obj/item/circuit_component/to_delete in attached_components) + remove_component(to_delete) + qdel(to_delete) + QDEL_LIST(circuit_variables) + attached_components.Cut() + shell = null + examined_component = null + owner_id = null + QDEL_NULL(cell) + GLOB.integrated_circuits -= src + return ..() + +/obj/item/integrated_circuit/examine(mob/user) + . = ..() + if(cell) + . += span_notice("The charge meter reads [cell ? round(cell.percent(), 1) : 0]%.") + else + . += span_notice("There is no power cell installed.") + +/obj/item/integrated_circuit/proc/set_cell(obj/item/stock_parts/cell_to_set) + SEND_SIGNAL(src, COMSIG_CIRCUIT_SET_CELL, cell_to_set) + cell = cell_to_set + +/obj/item/integrated_circuit/attackby(obj/item/I, mob/living/user, params) + . = ..() + if(istype(I, /obj/item/circuit_component)) + add_component_manually(I, user) + return + + if(istype(I, /obj/item/stock_parts/cell)) + if(cell) + balloon_alert(user, "there already is a cell inside!") + return + if(!user.transferItemToLoc(I, src)) + return + set_cell(I) + I.add_fingerprint(user) + user.visible_message(span_notice("[user] inserts a power cell into [src]."), span_notice("You insert the power cell into [src].")) + return + + if(istype(I, /obj/item/card/id)) + balloon_alert(user, "owner id set for [I]") + owner_id = WEAKREF(I) + return + + if(I.tool_behaviour == TOOL_SCREWDRIVER) + if(!cell) + return + I.play_tool_sound(src) + user.visible_message(span_notice("[user] unscrews the power cell from [src]."), span_notice("You unscrew the power cell from [src].")) + cell.forceMove(drop_location()) + set_cell(null) + return + +/** + * Registers an movable atom as a shell + * + * No functionality is done here. This is so that input components + * can properly register any signals on the shell. + * Arguments: + * * new_shell - The new shell to register. + */ +/obj/item/integrated_circuit/proc/set_shell(atom/movable/new_shell) + remove_current_shell() + set_on(TRUE) + SEND_SIGNAL(src, COMSIG_CIRCUIT_SET_SHELL, new_shell) + shell = new_shell + RegisterSignal(shell, COMSIG_PARENT_QDELETING, .proc/remove_current_shell) + for(var/obj/item/circuit_component/attached_component as anything in attached_components) + attached_component.register_shell(shell) + // Their input ports may be updated with user values, but the outputs haven't updated + // because on is FALSE + TRIGGER_CIRCUIT_COMPONENT(attached_component, null) + +/** + * Unregisters the current shell attached to this circuit. + */ +/obj/item/integrated_circuit/proc/remove_current_shell() + SIGNAL_HANDLER + if(!shell) + return + shell.name = initial(shell.name) + for(var/obj/item/circuit_component/attached_component as anything in attached_components) + attached_component.unregister_shell(shell) + UnregisterSignal(shell, COMSIG_PARENT_QDELETING) + shell = null + set_on(FALSE) + SEND_SIGNAL(src, COMSIG_CIRCUIT_SHELL_REMOVED) + +/obj/item/integrated_circuit/proc/set_on(new_value) + SEND_SIGNAL(src, COMSIG_CIRCUIT_SET_ON, new_value) + on = new_value + +/** + * Adds a component to the circuitboard + * + * Once the component is added, the ports can be attached to other components + */ +/obj/item/integrated_circuit/proc/add_component(obj/item/circuit_component/to_add, mob/living/user) + if(to_add.parent) + return + + if(SEND_SIGNAL(src, COMSIG_CIRCUIT_ADD_COMPONENT, to_add, user) & COMPONENT_CANCEL_ADD_COMPONENT) + return + + if(!to_add.add_to(src)) + return + + var/success = FALSE + if(user) + success = user.transferItemToLoc(to_add, src) + else + success = to_add.forceMove(src) + + if(!success) + return + + to_add.rel_x = rand(COMPONENT_MIN_RANDOM_POS, COMPONENT_MAX_RANDOM_POS) - screen_x + to_add.rel_y = rand(COMPONENT_MIN_RANDOM_POS, COMPONENT_MAX_RANDOM_POS) - screen_y + to_add.parent = src + attached_components += to_add + RegisterSignal(to_add, COMSIG_MOVABLE_MOVED, .proc/component_move_handler) + SStgui.update_uis(src) + + if(shell) + to_add.register_shell(shell) + return TRUE + +/** + * Adds a component to the circuitboard through a manual action. + */ +/obj/item/integrated_circuit/proc/add_component_manually(obj/item/circuit_component/to_add, mob/living/user) + if (SEND_SIGNAL(src, COMSIG_CIRCUIT_ADD_COMPONENT_MANUALLY, to_add, user) & COMPONENT_CANCEL_ADD_COMPONENT) + return + + return add_component(to_add, user) + +/obj/item/integrated_circuit/proc/component_move_handler(obj/item/circuit_component/source) + SIGNAL_HANDLER + if(source.loc != src) + remove_component(source) + +/** + * Removes a component to the circuitboard + * + * This removes all connects between the ports + */ +/obj/item/integrated_circuit/proc/remove_component(obj/item/circuit_component/to_remove) + if(shell) + to_remove.unregister_shell(shell) + + UnregisterSignal(to_remove, COMSIG_MOVABLE_MOVED) + attached_components -= to_remove + to_remove.disconnect() + to_remove.parent = null + SEND_SIGNAL(to_remove, COMSIG_CIRCUIT_COMPONENT_REMOVED, src) + SStgui.update_uis(src) + to_remove.removed_from(src) + +/obj/item/integrated_circuit/get_cell() + return cell + +/obj/item/integrated_circuit/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/simple/circuit_assets) + ) + +/obj/item/integrated_circuit/ui_static_data(mob/user) + . = list() + .["global_basic_types"] = GLOB.wiremod_basic_types + .["screen_x"] = screen_x + .["screen_y"] = screen_y + +/obj/item/integrated_circuit/ui_data(mob/user) + . = list() + .["components"] = list() + for(var/obj/item/circuit_component/component as anything in attached_components) + if (component.circuit_flags & CIRCUIT_FLAG_HIDDEN) + .["components"] += null + continue + + var/list/component_data = list() + component_data["input_ports"] = list() + for(var/datum/port/input/port as anything in component.input_ports) + var/current_data = port.value + if(isatom(current_data)) // Prevent passing the name of the atom. + current_data = null + var/list/connected_to = list() + for(var/datum/port/output/output as anything in port.connected_ports) + connected_to += REF(output) + component_data["input_ports"] += list(list( + "name" = port.name, + "type" = port.datatype, + "ref" = REF(port), // The ref is the identifier to work out what it is connected to + "connected_to" = connected_to, + "color" = port.color, + "current_data" = current_data, + "datatype_data" = port.datatype_ui_data(user), + )) + component_data["output_ports"] = list() + for(var/datum/port/output/port as anything in component.output_ports) + component_data["output_ports"] += list(list( + "name" = port.name, + "type" = port.datatype, + "ref" = REF(port), + "color" = port.color, + )) + + component_data["name"] = component.display_name + component_data["x"] = component.rel_x + component_data["y"] = component.rel_y + component_data["removable"] = component.removable + .["components"] += list(component_data) + + .["variables"] = list() + for(var/variable_name in circuit_variables) + var/datum/circuit_variable/variable = circuit_variables[variable_name] + var/list/variable_data = list() + variable_data["name"] = variable.name + variable_data["datatype"] = variable.datatype + variable_data["color"] = variable.color + .["variables"] += list(variable_data) + + + .["display_name"] = display_name + + var/obj/item/circuit_component/examined + if(examined_component) + examined = examined_component.resolve() + + .["examined_name"] = examined?.display_name + .["examined_desc"] = examined?.desc + .["examined_notices"] = examined?.get_ui_notices() + .["examined_rel_x"] = examined_rel_x + .["examined_rel_y"] = examined_rel_y + + .["is_admin"] = check_rights_for(user.client, R_VAREDIT) + +/obj/item/integrated_circuit/ui_host(mob/user) + if(shell) + return shell + return ..() + +/obj/item/integrated_circuit/can_interact(mob/user) + if(locked) + return FALSE + return ..() + +/obj/item/integrated_circuit/ui_status(mob/user) + . = ..() + + if (isobserver(user)) + . = max(., UI_UPDATE) + + // Extra protection because ui_state will not close the UI if they already have the ui open, + // as ui_state is only set during + if(admin_only) + if(!check_rights_for(user.client, R_VAREDIT)) + return UI_CLOSE + else + return UI_INTERACTIVE + +/obj/item/integrated_circuit/ui_state(mob/user) + if(!shell) + return GLOB.hands_state + return GLOB.physical_obscured_state + +/obj/item/integrated_circuit/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "IntegratedCircuit", name) + ui.open() + ui.set_autoupdate(FALSE) + +#define WITHIN_RANGE(id, table) (id >= 1 && id <= length(table)) + +/obj/item/integrated_circuit/ui_act(action, list/params) + . = ..() + if(.) + return + + switch(action) + if("add_connection") + var/input_component_id = text2num(params["input_component_id"]) + var/output_component_id = text2num(params["output_component_id"]) + var/input_port_id = text2num(params["input_port_id"]) + var/output_port_id = text2num(params["output_port_id"]) + if(!WITHIN_RANGE(input_component_id, attached_components) || !WITHIN_RANGE(output_component_id, attached_components)) + return + var/obj/item/circuit_component/input_component = attached_components[input_component_id] + var/obj/item/circuit_component/output_component = attached_components[output_component_id] + + if(!WITHIN_RANGE(input_port_id, input_component.input_ports) || !WITHIN_RANGE(output_port_id, output_component.output_ports)) + return + var/datum/port/input/input_port = input_component.input_ports[input_port_id] + var/datum/port/output/output_port = output_component.output_ports[output_port_id] + + if(!input_port.can_receive_from_datatype(output_port.datatype)) + return + input_port.connect(output_port) + . = TRUE + if("remove_connection") + var/component_id = text2num(params["component_id"]) + var/is_input = params["is_input"] + var/port_id = text2num(params["port_id"]) + + if(!WITHIN_RANGE(component_id, attached_components)) + return + var/obj/item/circuit_component/component = attached_components[component_id] + + var/list/port_table + if(is_input) + port_table = component.input_ports + else + port_table = component.output_ports + + if(!WITHIN_RANGE(port_id, port_table)) + return + + var/datum/port/port = port_table[port_id] + port.disconnect_all() + . = TRUE + if("detach_component") + var/component_id = text2num(params["component_id"]) + if(!WITHIN_RANGE(component_id, attached_components)) + return + var/obj/item/circuit_component/component = attached_components[component_id] + if(!component.removable) + return + component.disconnect() + remove_component(component) + if(component.loc == src) + usr.put_in_hands(component) + . = TRUE + if("set_component_coordinates") + var/component_id = text2num(params["component_id"]) + if(!WITHIN_RANGE(component_id, attached_components)) + return + var/obj/item/circuit_component/component = attached_components[component_id] + component.rel_x = min(max(-COMPONENT_MAX_POS, text2num(params["rel_x"])), COMPONENT_MAX_POS) + component.rel_y = min(max(-COMPONENT_MAX_POS, text2num(params["rel_y"])), COMPONENT_MAX_POS) + . = TRUE + if("set_component_input") + var/component_id = text2num(params["component_id"]) + var/port_id = text2num(params["port_id"]) + if(!WITHIN_RANGE(component_id, attached_components)) + return + var/obj/item/circuit_component/component = attached_components[component_id] + if(!WITHIN_RANGE(port_id, component.input_ports)) + return + var/datum/port/input/port = component.input_ports[port_id] + + if(params["set_null"]) + port.set_input(null) + return TRUE + + if(params["marked_atom"]) + if(port.datatype != PORT_TYPE_ATOM && port.datatype != PORT_TYPE_ANY) + return + var/obj/item/multitool/circuit/marker = usr.get_active_held_item() + if(!istype(marker)) + var/client/user = usr.client + if(!check_rights_for(user, R_VAREDIT)) + return TRUE + var/atom/marked_atom = user.holder.marked_datum + if(!marked_atom) + return TRUE + port.set_input(marked_atom) + balloon_alert(usr, "updated [port.name]'s value to marked object.") + return TRUE + if(!marker.marked_atom) + port.set_input(null) + marker.say("Cleared port ('[port.name]')'s value.") + return TRUE + marker.say("Updated port ('[port.name]')'s value to the marked entity.") + port.set_input(marker.marked_atom) + return TRUE + + var/user_input = port.handle_manual_input(usr, params["input"]) + if(isnull(user_input)) + return TRUE + port.set_input(user_input) + . = TRUE + if("get_component_value") + var/component_id = text2num(params["component_id"]) + var/port_id = text2num(params["port_id"]) + if(!WITHIN_RANGE(component_id, attached_components)) + return + var/obj/item/circuit_component/component = attached_components[component_id] + if(!WITHIN_RANGE(port_id, component.output_ports)) + return + + var/datum/port/output/port = component.output_ports[port_id] + var/value = port.value + if(isatom(value)) + value = PORT_TYPE_ATOM + else if(isnull(value)) + value = "null" + var/string_form = copytext("[value]", 1, PORT_MAX_STRING_DISPLAY) + if(length(string_form) >= PORT_MAX_STRING_DISPLAY-1) + string_form += "..." + balloon_alert(usr, "[port.name] value: [string_form]") + . = TRUE + if("set_display_name") + var/new_name = params["display_name"] + + if(new_name) + set_display_name(strip_html(params["display_name"], label_max_length)) + else + set_display_name("") + + if(shell) + if(display_name != "") + shell.name = "[initial(shell.name)] ([display_name])" + else + shell.name = initial(shell.name) + + . = TRUE + if("set_examined_component") + var/component_id = text2num(params["component_id"]) + if(!WITHIN_RANGE(component_id, attached_components)) + return + examined_component = WEAKREF(attached_components[component_id]) + examined_rel_x = text2num(params["x"]) + examined_rel_y = text2num(params["y"]) + . = TRUE + if("remove_examined_component") + examined_component = null + . = TRUE + if("save_circuit") + return attempt_save_to(usr.client) + if("add_variable") + var/variable_identifier = trim(copytext(params["variable_name"], 1, PORT_MAX_NAME_LENGTH)) + if(variable_identifier in circuit_variables) + return TRUE + if(variable_identifier == "") + return TRUE + var/variable_datatype = params["variable_datatype"] + if(!(variable_datatype in GLOB.wiremod_basic_types)) + return + + circuit_variables[variable_identifier] = new /datum/circuit_variable(variable_identifier, variable_datatype) + . = TRUE + if("remove_variable") + var/variable_identifier = params["variable_name"] + if(!(variable_identifier in circuit_variables)) + return + var/datum/circuit_variable/variable = circuit_variables[variable_identifier] + if(!variable) + return + circuit_variables -= variable_identifier + qdel(variable) + . = TRUE + if("add_setter_or_getter") + if(setter_and_getter_count >= max_setters_and_getters) + balloon_alert(usr, "setter and getter count at maximum capacity") + return + var/designated_type = /obj/item/circuit_component/getter + if(params["is_setter"]) + designated_type = /obj/item/circuit_component/setter + var/obj/item/circuit_component/component = new designated_type(src) + if(!add_component(component, usr)) + qdel(component) + return + RegisterSignal(component, COMSIG_CIRCUIT_COMPONENT_REMOVED, .proc/clear_setter_or_getter) + setter_and_getter_count++ + if("move_screen") + screen_x = text2num(params["screen_x"]) + screen_y = text2num(params["screen_y"]) + +/obj/item/integrated_circuit/proc/clear_setter_or_getter(datum/source) + SIGNAL_HANDLER + // This'll also be called in the Destroy() override of /obj/item/circuit_component + if(!QDELING(source)) + qdel(source) + setter_and_getter_count-- + +/obj/item/integrated_circuit/proc/on_atom_usb_cable_try_attach(datum/source, obj/item/usb_cable/usb_cable, mob/user) + SIGNAL_HANDLER + usb_cable.balloon_alert(user, "circuit needs to be in a compatible shell") + return COMSIG_CANCEL_USB_CABLE_ATTACK + +#undef WITHIN_RANGE + +/// Sets the display name that appears on the shell. +/obj/item/integrated_circuit/proc/set_display_name(new_name) + display_name = new_name + +/** + * Returns the creator of the integrated circuit. Used in admin messages and other related things. + */ +/obj/item/integrated_circuit/proc/get_creator_admin() + return get_creator(include_link = TRUE) + +/** + * Returns the creator of the integrated circuit. Used in admin logs and other related things. + */ +/obj/item/integrated_circuit/proc/get_creator(include_link = FALSE) + var/datum/mind/inserter + if(inserter_mind) + inserter = inserter_mind.resolve() + + var/obj/item/card/id/id_card + if(owner_id) + id_card = owner_id.resolve() + + return "[src] (Shell: [shell || "*null*"], Inserter: [key_name(inserter, include_link)], Owner ID: [id_card?.name || "*null*"])" + +/// Attempts to save a circuit to a given client +/obj/item/integrated_circuit/proc/attempt_save_to(client/saver) + if(!check_rights_for(saver, R_VAREDIT)) + return FALSE + var/temp_file = file("data/CircuitDownloadTempFile") + fdel(temp_file) + WRITE_FILE(temp_file, convert_to_json()) + DIRECT_OUTPUT(saver, ftp(temp_file, "[display_name || "circuit"].json")) + return TRUE diff --git a/code/modules/wiremod/core/marker.dm b/code/modules/wiremod/core/marker.dm new file mode 100644 index 0000000000..82d34be37a --- /dev/null +++ b/code/modules/wiremod/core/marker.dm @@ -0,0 +1,60 @@ +/obj/item/multitool/circuit + name = "circuit multitool" + desc = "A circuit multitool. Used to mark entities which can then be uploaded to components by pressing the upload button on a port. \ + Acts as a normal multitool otherwise. Use in hand to clear marked entity so that you can mark another entity." + icon_state = "multitool_circuit" + + /// The marked atom of this multitool + var/atom/marked_atom + +/obj/item/multitool/circuit/Destroy() + marked_atom = null + return ..() + +/obj/item/multitool/circuit/examine(mob/user) + . = ..() + . += span_notice("It has [marked_atom? "a" : "no"] marked entity registered.") + +/obj/item/multitool/circuit/attack_self(mob/user, modifiers) + . = ..() + if(.) + return + if(!marked_atom) + return + + say("Cleared marked targets.") + clear_marked_atom() + return TRUE + +/obj/item/multitool/circuit/melee_attack_chain(mob/user, atom/target, params) + var/is_right_clicking = LAZYACCESS(params2list(params), RIGHT_CLICK) + + if(marked_atom || !user.Adjacent(target) || is_right_clicking) + return ..() + + say("Marked [target].") + marked_atom = target + RegisterSignal(marked_atom, COMSIG_PARENT_QDELETING, .proc/cleanup_marked_atom) + update_icon() + flick("multitool_circuit_flick", src) + playsound(src.loc, 'sound/misc/compiler-stage2.ogg', 30, TRUE) + return TRUE + +/obj/item/multitool/circuit/update_overlays() + . = ..() + cut_overlays() + if(marked_atom) + . += "marked_overlay" + +/// Clears the current marked atom +/obj/item/multitool/circuit/proc/clear_marked_atom() + if(!marked_atom) + return + UnregisterSignal(marked_atom, COMSIG_PARENT_QDELETING) + marked_atom = null + update_icon() + +/obj/item/multitool/circuit/proc/cleanup_marked_atom(datum/source) + SIGNAL_HANDLER + if(source == marked_atom) + clear_marked_atom() diff --git a/code/modules/wiremod/core/port.dm b/code/modules/wiremod/core/port.dm new file mode 100644 index 0000000000..a58016743f --- /dev/null +++ b/code/modules/wiremod/core/port.dm @@ -0,0 +1,216 @@ +/** + * # Component Port + * + * A port used by a component. Connects to other ports. + */ +/datum/port + /// The component this port is attached to + var/obj/item/circuit_component/connected_component + + /// Name of the port. Used when displaying the port. + var/name + + /// The port type. Ports can only connect to each other if the type matches + var/datatype + + /// The value that's currently in the port. It's of the above type. + var/value + + /// The default port type. Stores the original datatype of the port set on Initialize. + var/datum/circuit_datatype/datatype_handler + + /// The port color. If unset, appears as blue. + var/color + +/datum/port/New(obj/item/circuit_component/to_connect, name, datatype) + if(!to_connect) + qdel(src) + return + . = ..() + connected_component = to_connect + src.name = name + set_datatype(datatype) + +/datum/port/Destroy(force) + disconnect_all() + connected_component = null + datatype_handler = null + return ..() + +/** + * Sets the port's value to value. + * Casts to the port's datatype (e.g. number -> string), and assumes this can be done. + */ +/datum/port/proc/set_value(value, force = FALSE) + if(src.value != value || force) + if(isatom(value)) + UnregisterSignal(value, COMSIG_PARENT_QDELETING) + src.value = datatype_handler.convert_value(src, value) + if(isatom(value)) + RegisterSignal(value, COMSIG_PARENT_QDELETING, .proc/null_value) + SEND_SIGNAL(src, COMSIG_PORT_SET_VALUE, value) + +/** + * Updates the value of the input and calls input_received on the connected component + */ +/datum/port/input/proc/set_input(value) + if(QDELETED(src)) //Pain + return + set_value(value) + if(trigger) + TRIGGER_CIRCUIT_COMPONENT(connected_component, src) + +/datum/port/output/proc/set_output(value) + set_value(value) + +/** + * Sets the datatype of the port. + * + * Arguments: + * * new_type - The type this port is to be set to. + */ +/datum/port/proc/set_datatype(type_to_set) + if(type_to_set == datatype) + return + + if(datatype_handler) + datatype_handler.on_loss(src) + datatype_handler = null + + var/datum/circuit_datatype/handler = GLOB.circuit_datatypes[type_to_set] + if(!handler || !handler.is_compatible(src)) + type_to_set = PORT_TYPE_ANY + handler = GLOB.circuit_datatypes[type_to_set] + // We can't leave this port without a type or else it'll just keep spewing out unnecessary and unneeded runtimes as well as leaving the circuit in a broken state. + stack_trace("[src] port attempted to be set to an incompatible datatype! (target datatype to set: [type_to_set])") + + datatype = type_to_set + datatype_handler = handler + color = datatype_handler.color + datatype_handler.on_gain(src) + src.value = datatype_handler.convert_value(src, value) + SEND_SIGNAL(src, COMSIG_PORT_SET_TYPE, type_to_set) + if(connected_component?.parent) + SStgui.update_uis(connected_component.parent) + +/datum/port/input/set_datatype(new_type) + for(var/datum/port/output/output as anything in connected_ports) + check_type(output) + ..() + +/** + * Returns the data from the datatype + */ +/datum/port/proc/datatype_ui_data() + return datatype_handler.datatype_ui_data(src) + +/** + * # Output Port + * + * An output port that many input ports can connect to + * + * Sends a signal whenever the output value is changed + */ +/datum/port/output + +/** + * Disconnects a port from all other ports. + * + * Called by [/obj/item/circuit_component] whenever it is disconnected from + * an integrated circuit + */ +/datum/port/proc/disconnect_all() + SEND_SIGNAL(src, COMSIG_PORT_DISCONNECT) + +/datum/port/input/disconnect_all() + ..() + for(var/datum/port/output/output as anything in connected_ports) + disconnect(output) + +/datum/port/input/proc/disconnect(datum/port/output/output) + connected_ports -= output + UnregisterSignal(output, COMSIG_PORT_SET_VALUE) + UnregisterSignal(output, COMSIG_PORT_SET_TYPE) + UnregisterSignal(output, COMSIG_PORT_DISCONNECT) + +/// Do our part in setting all source references anywhere to null. +/datum/port/proc/on_value_qdeleting(datum/source) + SIGNAL_HANDLER + if(value == source) + value = null + else + stack_trace("Impossible? [src] should only receive COMSIG_PARENT_QDELETING from an atom currently in the port, not [source].") + +/** + * # Input Port + * + * An input port remembers connected output ports. + * + * Registers the PORT_SET_VALUE signal on each connected port, + * and keeps its value equal to the last such signal received. + */ +/datum/port/input + /// Whether this port triggers an update whenever an output is received. + var/trigger = FALSE + + /// The ports this port is wired to. + var/list/datum/port/output/connected_ports + +/datum/port/input/New(obj/item/circuit_component/to_connect, name, datatype, trigger, default) + . = ..() + set_value(default) + src.trigger = trigger + src.connected_ports = list() + +/** + * Introduces two ports to one another. + */ +/datum/port/input/proc/connect(datum/port/output/output) + connected_ports |= output + RegisterSignal(output, COMSIG_PORT_SET_VALUE, .proc/receive_value) + RegisterSignal(output, COMSIG_PORT_SET_TYPE, .proc/check_type) + RegisterSignal(output, COMSIG_PORT_DISCONNECT, .proc/disconnect) + // For signals, we don't update the input to prevent sending a signal when connecting ports. + if(!(datatype_handler.datatype_flags & DATATYPE_FLAG_AVOID_VALUE_UPDATE)) + set_input(output.value) + +/** + * Determines if a datatype is compatible with another port of a different type. + * + * Arguments: + * * other_datatype - The datatype to check + */ +/datum/port/input/proc/can_receive_from_datatype(datatype_to_check) + return datatype_handler.can_receive_from_datatype(datatype_to_check) + +/** + * Determines if a datatype is compatible with another port of a different type. + * + * Arguments: + * * other_datatype - The datatype to check + */ +/datum/port/input/proc/handle_manual_input(mob/user, manual_input) + if(datatype_handler.datatype_flags & DATATYPE_FLAG_ALLOW_MANUAL_INPUT) + return datatype_handler.handle_manual_input(src, user, manual_input) + return null + +/** + * Mirror value updates from connected output ports after an input_receive_delay. + */ +/datum/port/input/proc/receive_value(datum/port/output/output, value) + SIGNAL_HANDLER + SScircuit_component.add_callback(CALLBACK(src, .proc/set_input, value)) + +/// Signal handler proc to null the input if an atom is deleted. An update is not sent because this was not set by anything. +/datum/port/proc/null_value(datum/source) + SIGNAL_HANDLER + if(value == source) + value = null + +/** + * Handle type updates from connected output ports, breaking uncastable connections. + */ +/datum/port/input/proc/check_type(datum/port/output/output) + SIGNAL_HANDLER + if(!can_receive_from_datatype(output.datatype)) + disconnect(output) diff --git a/code/modules/wiremod/core/usb_cable.dm b/code/modules/wiremod/core/usb_cable.dm new file mode 100644 index 0000000000..ed0f1053a3 --- /dev/null +++ b/code/modules/wiremod/core/usb_cable.dm @@ -0,0 +1,123 @@ +/// A cable that can connect integrated circuits to anything with a USB port, such as computers and machines. +/obj/item/usb_cable + name = "usb cable" + desc = "A cable that can connect integrated circuits to anything with a USB port, such as computers and machines." + icon = 'icons/obj/wiremod.dmi' + icon_state = "usb_cable" + inhand_icon_state = "coil" + base_icon_state = "coil" + w_class = WEIGHT_CLASS_TINY + custom_materials = list(/datum/material/iron = 75) + + /// The currently connected circuit + var/obj/item/integrated_circuit/attached_circuit + +/obj/item/usb_cable/Destroy() + attached_circuit = null + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/item/usb_cable/Initialize(mapload) + . = ..() + RegisterSignal(src, COMSIG_MOVABLE_MOVED, .proc/on_moved) + +/obj/item/usb_cable/examine(mob/user) + . = ..() + + if (!isnull(attached_circuit)) + . += span_notice("It is attached to [attached_circuit.shell || attached_circuit].") + +// Look, I'm not happy about this either, but moving an object doesn't call Moved if it's inside something else. +// There's good reason for this, but there's no element or similar yet to track it as far as I know. +// SSobj runs infrequently, this is only ran while there's an attached circuit, its performance cost is negligible. +/obj/item/usb_cable/process(delta_time) + if (!check_in_range()) + return PROCESS_KILL + +/obj/item/usb_cable/pre_attack(atom/target, mob/living/user, params) + . = ..() + if (.) + return + + if (prob(1)) + balloon_alert(user, "wrong way, god damnit") + return TRUE + + var/signal_result = SEND_SIGNAL(target, COMSIG_ATOM_USB_CABLE_TRY_ATTACH, src, user) + + var/last_attached_circuit = attached_circuit + if (signal_result & COMSIG_USB_CABLE_CONNECTED_TO_CIRCUIT) + if (isnull(attached_circuit)) + CRASH("Producers of COMSIG_USB_CABLE_CONNECTED_TO_CIRCUIT must set attached_circuit") + balloon_alert(user, "connected to circuit\nconnect to a port") + + playsound(src, 'sound/machines/pda_button1.ogg', 20, TRUE) + + if (last_attached_circuit != attached_circuit) + if (!isnull(last_attached_circuit)) + unregister_circuit_signals(last_attached_circuit) + register_circuit_signals() + + START_PROCESSING(SSobj, src) + + return TRUE + + if (signal_result & COMSIG_USB_CABLE_ATTACHED) + // Short messages are better to read + var/connection_description = "port" + if (istype(target, /obj/machinery/computer)) + connection_description = "computer" + else if (ismachinery(target)) + connection_description = "machine" + + balloon_alert(user, "connected to [connection_description]") + playsound(src, 'sound/items/screwdriver2.ogg', 20, TRUE) + + return TRUE + + if (signal_result & COMSIG_CANCEL_USB_CABLE_ATTACK) + return TRUE + + return FALSE + +/obj/item/usb_cable/suicide_act(mob/user) + user.visible_message(span_suicide("[user] is wrapping [src] around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide!")) + return OXYLOSS + +/obj/item/usb_cable/proc/register_circuit_signals() + RegisterSignal(attached_circuit, COMSIG_MOVABLE_MOVED, .proc/on_moved) + RegisterSignal(attached_circuit, COMSIG_PARENT_QDELETING, .proc/on_circuit_qdeling) + RegisterSignal(attached_circuit.shell, COMSIG_MOVABLE_MOVED, .proc/on_moved) + +/obj/item/usb_cable/proc/unregister_circuit_signals(obj/item/integrated_circuit/old_circuit) + UnregisterSignal(attached_circuit, list( + COMSIG_MOVABLE_MOVED, + COMSIG_PARENT_QDELETING, + )) + + UnregisterSignal(attached_circuit.shell, COMSIG_MOVABLE_MOVED) + +/obj/item/usb_cable/proc/on_moved() + SIGNAL_HANDLER + + check_in_range() + +/obj/item/usb_cable/proc/check_in_range() + if (isnull(attached_circuit)) + STOP_PROCESSING(SSobj, src) + return FALSE + + if (!IN_GIVEN_RANGE(attached_circuit, src, USB_CABLE_MAX_RANGE)) + balloon_alert_to_viewers("detached, too far away") + unregister_circuit_signals(attached_circuit) + attached_circuit = null + STOP_PROCESSING(SSobj, src) + return FALSE + + return TRUE + +/obj/item/usb_cable/proc/on_circuit_qdeling() + SIGNAL_HANDLER + + attached_circuit = null + STOP_PROCESSING(SSobj, src) diff --git a/code/modules/wiremod/core/variable.dm b/code/modules/wiremod/core/variable.dm new file mode 100644 index 0000000000..62d5239ade --- /dev/null +++ b/code/modules/wiremod/core/variable.dm @@ -0,0 +1,49 @@ +/** + * A circuit variable that holds the name, the datatype and the colour of the variable (taken from the datatype). + * + * Used in integrated circuits for setter and getter circuit components. + */ +/datum/circuit_variable + /// The display name of the circuit variable + var/name + + /// The datatype of the circuit variable. Used by the setter and getter circuit components + var/datatype + + /// The colour that appears in the UI. The value is set to the datatype's matching colour + var/color + + /// The current value held by the variable. + var/value + + /// The components that are currently listening. Triggers them when the value is updated. + var/list/obj/item/circuit_component/listeners + +/datum/circuit_variable/New(name, datatype) + . = ..() + src.name = name + src.datatype = datatype + + var/datum/circuit_datatype/circuit_datatype = GLOB.circuit_datatypes[datatype] + + src.listeners = list() + src.color = circuit_datatype.color + + +/datum/circuit_variable/Destroy(force, ...) + listeners = null + return ..() + +/// Sets the value of the circuit component and triggers the appropriate listeners +/datum/circuit_variable/proc/set_value(new_value) + value = new_value + for(var/obj/item/circuit_component/component as anything in listeners) + TRIGGER_CIRCUIT_COMPONENT(component, null) + +/// Adds a listener to receive inputs when the variable has a value that is set. +/datum/circuit_variable/proc/add_listener(obj/item/circuit_component/to_add) + listeners += to_add + +/// Removes a listener to receive inputs when the variable has a value that is set. Listener will usually clean themselves up +/datum/circuit_variable/proc/remove_listener(obj/item/circuit_component/to_remove) + listeners -= to_remove diff --git a/code/modules/wiremod/datatypes/any.dm b/code/modules/wiremod/datatypes/any.dm new file mode 100644 index 0000000000..a8a2f8457f --- /dev/null +++ b/code/modules/wiremod/datatypes/any.dm @@ -0,0 +1,10 @@ +/datum/circuit_datatype/any + datatype = PORT_TYPE_ANY + color = "blue" + datatype_flags = DATATYPE_FLAG_ALLOW_MANUAL_INPUT + +/datum/circuit_datatype/any/can_receive_from_datatype(datatype_to_check) + return TRUE + +/datum/circuit_datatype/any/handle_manual_input(datum/port/input/port, mob/user, user_input) + return text2num(user_input) || user_input diff --git a/code/modules/wiremod/datatypes/basic.dm b/code/modules/wiremod/datatypes/basic.dm new file mode 100644 index 0000000000..d112f2b9d9 --- /dev/null +++ b/code/modules/wiremod/datatypes/basic.dm @@ -0,0 +1,9 @@ +// This file is for types that do not have any special conversion behaviour + +/datum/circuit_datatype/list_type + datatype = PORT_TYPE_LIST + color = "white" + +/datum/circuit_datatype/table + datatype = PORT_TYPE_TABLE + color = "grey" diff --git a/code/modules/wiremod/datatypes/entity.dm b/code/modules/wiremod/datatypes/entity.dm new file mode 100644 index 0000000000..44e00b9c6c --- /dev/null +++ b/code/modules/wiremod/datatypes/entity.dm @@ -0,0 +1,10 @@ +/datum/circuit_datatype/entity + datatype = PORT_TYPE_ATOM + color = "purple" + datatype_flags = DATATYPE_FLAG_ALLOW_MANUAL_INPUT + +/datum/circuit_datatype/entity/convert_value(datum/port/port, value_to_convert) + var/atom/object = value_to_convert + if(QDELETED(object)) + return null + return object diff --git a/code/modules/wiremod/datatypes/number.dm b/code/modules/wiremod/datatypes/number.dm new file mode 100644 index 0000000000..7013340249 --- /dev/null +++ b/code/modules/wiremod/datatypes/number.dm @@ -0,0 +1,14 @@ +/datum/circuit_datatype/number + datatype = PORT_TYPE_NUMBER + color = "green" + datatype_flags = DATATYPE_FLAG_ALLOW_MANUAL_INPUT + +/datum/circuit_datatype/number/can_receive_from_datatype(datatype_to_check) + . = ..() + if(.) + return + + return datatype_to_check == PORT_TYPE_NUMBER + +/datum/circuit_datatype/number/handle_manual_input(datum/port/input/port, mob/user, user_input) + return text2num(user_input) diff --git a/code/modules/wiremod/datatypes/option.dm b/code/modules/wiremod/datatypes/option.dm new file mode 100644 index 0000000000..c6de346c9d --- /dev/null +++ b/code/modules/wiremod/datatypes/option.dm @@ -0,0 +1,33 @@ +/datum/port/input/option + var/list/possible_options + +/datum/port/input/option/New(obj/item/circuit_component/to_connect, name, datatype, trigger, default, possible_options) + . = ..() + src.possible_options = possible_options + set_value(default, force = TRUE) + +/datum/circuit_datatype/option + datatype = PORT_TYPE_OPTION + color = "violet" + datatype_flags = DATATYPE_FLAG_ALLOW_MANUAL_INPUT + +/datum/circuit_datatype/option/is_compatible(datum/port/gained_port) + return istype(gained_port, /datum/port/input/option) + +/datum/circuit_datatype/option/can_receive_from_datatype(datatype_to_check) + . = ..() + if(.) + return + + return datatype_to_check == PORT_TYPE_STRING + +/datum/circuit_datatype/option/convert_value(datum/port/input/option/port, value_to_convert) + if(!port.possible_options) + return null + + if(value_to_convert in port.possible_options) + return value_to_convert + return port.possible_options[1] + +/datum/circuit_datatype/option/datatype_ui_data(datum/port/input/option/port) + return port.possible_options diff --git a/code/modules/wiremod/datatypes/signal.dm b/code/modules/wiremod/datatypes/signal.dm new file mode 100644 index 0000000000..2226f509fc --- /dev/null +++ b/code/modules/wiremod/datatypes/signal.dm @@ -0,0 +1,17 @@ +/datum/circuit_datatype/signal + datatype = PORT_TYPE_SIGNAL + color = "teal" + datatype_flags = DATATYPE_FLAG_ALLOW_MANUAL_INPUT|DATATYPE_FLAG_AVOID_VALUE_UPDATE + +/datum/circuit_datatype/signal/can_receive_from_datatype(datatype_to_check) + . = ..() + if(.) + return + + return datatype_to_check == PORT_TYPE_NUMBER + +/datum/circuit_datatype/signal/handle_manual_input(datum/port/input/port, mob/user, user_input) + var/atom/parent = port.connected_component + if(parent) + parent.balloon_alert(user, "triggered [port.name]") + return COMPONENT_SIGNAL diff --git a/code/modules/wiremod/datatypes/string.dm b/code/modules/wiremod/datatypes/string.dm new file mode 100644 index 0000000000..99c61b4a29 --- /dev/null +++ b/code/modules/wiremod/datatypes/string.dm @@ -0,0 +1,17 @@ +/datum/circuit_datatype/string + datatype = PORT_TYPE_STRING + color = "orange" + datatype_flags = DATATYPE_FLAG_ALLOW_MANUAL_INPUT + +/datum/circuit_datatype/string/can_receive_from_datatype(datatype_to_check) + return TRUE + +/datum/circuit_datatype/string/convert_value(datum/port/port, value_to_convert) + if(isnull(value_to_convert)) + return + + // So that they can't easily get the name like this. + if(isatom(value_to_convert)) + return PORT_TYPE_ATOM + else + return copytext("[value_to_convert]", 1, PORT_MAX_STRING_LENGTH) diff --git a/code/modules/wiremod/preset/hello_world.dm b/code/modules/wiremod/preset/hello_world.dm new file mode 100644 index 0000000000..2b579a0d81 --- /dev/null +++ b/code/modules/wiremod/preset/hello_world.dm @@ -0,0 +1,14 @@ +/** + * # Hello World preset + * + * Says "Hello World" when triggered. Needs to be wired up and connected first. + */ +/obj/item/integrated_circuit/loaded/hello_world + +/obj/item/integrated_circuit/loaded/hello_world/Initialize(mapload) + . = ..() + var/obj/item/circuit_component/speech/speech = new() + add_component(speech) + + speech.message.set_input("Hello World") + diff --git a/code/modules/wiremod/preset/speech_relay.dm b/code/modules/wiremod/preset/speech_relay.dm new file mode 100644 index 0000000000..bc84568cc0 --- /dev/null +++ b/code/modules/wiremod/preset/speech_relay.dm @@ -0,0 +1,20 @@ +/** + * # Speech Relay preset + * + * Acts like polly. Says whatever it hears. + */ +/obj/item/integrated_circuit/loaded/speech_relay + +/obj/item/integrated_circuit/loaded/speech_relay/Initialize(mapload) + . = ..() + var/obj/item/circuit_component/hear/hear = new() + add_component(hear) + hear.rel_x = 100 + hear.rel_y = 200 + + var/obj/item/circuit_component/speech/speech = new() + add_component(speech) + speech.rel_x = 400 + speech.rel_y = 200 + + speech.message.connect(hear.message_port) diff --git a/code/modules/wiremod/shell/airlock.dm b/code/modules/wiremod/shell/airlock.dm new file mode 100644 index 0000000000..6c342effa1 --- /dev/null +++ b/code/modules/wiremod/shell/airlock.dm @@ -0,0 +1,133 @@ +/datum/wires/airlock/shell + holder_type = /obj/machinery/door/airlock/shell + proper_name = "Circuit Airlock" + +/datum/wires/airlock/shell/on_cut(wire, mend) + // Don't allow them to re-enable autoclose. + if(wire == WIRE_TIMING) + return + return ..() + +/obj/machinery/door/airlock/shell + name = "circuit airlock" + autoclose = FALSE + +/obj/machinery/door/airlock/shell/Initialize(mapload) + . = ..() + AddComponent( \ + /datum/component/shell, \ + unremovable_circuit_components = list(new /obj/item/circuit_component/airlock), \ + capacity = SHELL_CAPACITY_LARGE, \ + shell_flags = SHELL_FLAG_ALLOW_FAILURE_ACTION \ + ) + +/obj/machinery/door/airlock/shell/check_access(obj/item/I) + return FALSE + +/obj/machinery/door/airlock/shell/canAIControl(mob/user) + return FALSE + +/obj/machinery/door/airlock/shell/canAIHack(mob/user) + return FALSE + +/obj/machinery/door/airlock/shell/set_wires() + return new /datum/wires/airlock/shell(src) + +/obj/item/circuit_component/airlock + display_name = "Airlock" + desc = "The general interface with an airlock. Includes general statuses of the airlock" + + /// Called when attack_hand is called on the shell. + var/obj/machinery/door/airlock/attached_airlock + + /// Bolts the airlock (if possible) + var/datum/port/input/bolt + /// Unbolts the airlock (if possible) + var/datum/port/input/unbolt + /// Opens the airlock (if possible) + var/datum/port/input/open + /// Closes the airlock (if possible) + var/datum/port/input/close + + /// Contains whether the airlock is open or not + var/datum/port/output/is_open + /// Contains whether the airlock is bolted or not + var/datum/port/output/is_bolted + + /// Called when the airlock is opened. + var/datum/port/output/opened + /// Called when the airlock is closed + var/datum/port/output/closed + + /// Called when the airlock is bolted + var/datum/port/output/bolted + /// Called when the airlock is unbolted + var/datum/port/output/unbolted + +/obj/item/circuit_component/airlock/Initialize(mapload) + . = ..() + // Input Signals + bolt = add_input_port("Bolt", PORT_TYPE_SIGNAL) + unbolt = add_input_port("Unbolt", PORT_TYPE_SIGNAL) + open = add_input_port("Open", PORT_TYPE_SIGNAL) + close = add_input_port("Close", PORT_TYPE_SIGNAL) + // States + is_open = add_output_port("Is Open", PORT_TYPE_NUMBER) + is_bolted = add_output_port("Is Bolted", PORT_TYPE_NUMBER) + // Output Signals + opened = add_output_port("Opened", PORT_TYPE_SIGNAL) + closed = add_output_port("Closed", PORT_TYPE_SIGNAL) + bolted = add_output_port("Bolted", PORT_TYPE_SIGNAL) + unbolted = add_output_port("Unbolted", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/airlock/register_shell(atom/movable/shell) + . = ..() + if(istype(shell, /obj/machinery/door/airlock)) + attached_airlock = shell + RegisterSignal(shell, COMSIG_AIRLOCK_SET_BOLT, .proc/on_airlock_set_bolted) + RegisterSignal(shell, COMSIG_AIRLOCK_OPEN, .proc/on_airlock_open) + RegisterSignal(shell, COMSIG_AIRLOCK_CLOSE, .proc/on_airlock_closed) + +/obj/item/circuit_component/airlock/unregister_shell(atom/movable/shell) + attached_airlock = null + UnregisterSignal(shell, list( + COMSIG_AIRLOCK_SET_BOLT, + COMSIG_AIRLOCK_OPEN, + COMSIG_AIRLOCK_CLOSE, + )) + return ..() + +/obj/item/circuit_component/airlock/proc/on_airlock_set_bolted(datum/source, should_bolt) + SIGNAL_HANDLER + is_bolted.set_output(should_bolt) + if(should_bolt) + bolted.set_output(COMPONENT_SIGNAL) + else + unbolted.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/airlock/proc/on_airlock_open(datum/source, force) + SIGNAL_HANDLER + is_open.set_output(TRUE) + opened.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/airlock/proc/on_airlock_closed(datum/source, forced) + SIGNAL_HANDLER + is_open.set_output(FALSE) + closed.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/airlock/input_received(datum/port/input/port) + . = ..() + if(.) + return + + if(!attached_airlock) + return + + if(COMPONENT_TRIGGERED_BY(bolt, port)) + attached_airlock.bolt() + if(COMPONENT_TRIGGERED_BY(unbolt, port)) + attached_airlock.unbolt() + if(COMPONENT_TRIGGERED_BY(open, port) && attached_airlock.density) + INVOKE_ASYNC(attached_airlock, /obj/machinery/door/airlock.proc/open) + if(COMPONENT_TRIGGERED_BY(close, port) && !attached_airlock.density) + INVOKE_ASYNC(attached_airlock, /obj/machinery/door/airlock.proc/close) diff --git a/code/modules/wiremod/shell/bot.dm b/code/modules/wiremod/shell/bot.dm new file mode 100644 index 0000000000..a7aee6a2c5 --- /dev/null +++ b/code/modules/wiremod/shell/bot.dm @@ -0,0 +1,55 @@ +/** + * # Bot + * + * Immobile (but not dense) shells that can interact with world. + */ +/obj/structure/bot + name = "bot" + icon = 'icons/obj/wiremod.dmi' + icon_state = "setup_medium_box" + + density = FALSE + light_system = MOVABLE_LIGHT + light_on = FALSE + +/obj/structure/bot/Initialize(mapload) + . = ..() + AddComponent( \ + /datum/component/shell, \ + unremovable_circuit_components = list(new /obj/item/circuit_component/bot), \ + capacity = SHELL_CAPACITY_LARGE, \ + shell_flags = SHELL_FLAG_USB_PORT, \ + ) + +/obj/item/circuit_component/bot + display_name = "Bot" + desc = "Triggers when someone interacts with the bot." + + /// Called when attack_hand is called on the shell. + var/datum/port/output/signal + /// The user who used the bot + var/datum/port/output/entity + +/obj/item/circuit_component/bot/Initialize(mapload) + . = ..() + entity = add_output_port("User", PORT_TYPE_ATOM) + signal = add_output_port("Signal", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/bot/Destroy() + signal = null + entity = null + return ..() + +/obj/item/circuit_component/bot/register_shell(atom/movable/shell) + RegisterSignal(shell, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand) + +/obj/item/circuit_component/bot/unregister_shell(atom/movable/shell) + UnregisterSignal(shell, COMSIG_ATOM_ATTACK_HAND) + +/obj/item/circuit_component/bot/proc/on_attack_hand(atom/source, mob/user) + SIGNAL_HANDLER + source.balloon_alert(user, "pushed button") + playsound(source, get_sfx("terminal_type"), 25, FALSE) + entity.set_output(user) + signal.set_output(COMPONENT_SIGNAL) + diff --git a/code/modules/wiremod/shell/brain_computer_interface.dm b/code/modules/wiremod/shell/brain_computer_interface.dm new file mode 100644 index 0000000000..f9723e115c --- /dev/null +++ b/code/modules/wiremod/shell/brain_computer_interface.dm @@ -0,0 +1,553 @@ +/obj/item/organ/cyberimp/bci + name = "brain-computer interface" + desc = "An implant that can be placed in a user's head to control circuits using their brain." + icon = 'icons/obj/wiremod.dmi' + icon_state = "bci" + zone = BODY_ZONE_HEAD + w_class = WEIGHT_CLASS_TINY + +/obj/item/organ/cyberimp/bci/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/shell, list( + new /obj/item/circuit_component/bci_core, + new /obj/item/circuit_component/bci_action(null, "One"), + new /obj/item/circuit_component/bci_action(null, "Two"), + new /obj/item/circuit_component/bci_action(null, "Three"), + ), SHELL_CAPACITY_SMALL) + +/obj/item/organ/cyberimp/bci/Insert(mob/living/carbon/reciever, special, drop_if_replaced) + . = ..() + + // Organs are put in nullspace, but this breaks circuit interactions + forceMove(reciever) + +/obj/item/organ/cyberimp/bci/say(message, bubble_type, list/spans, sanitize, datum/language/language, ignore_spam, forced) + if (owner) + // Otherwise say_dead will be called. + // It's intentional that a circuit for a dead person does not speak from the shell. + if (owner.stat == DEAD) + return + + owner.say(message, forced = "circuit speech") + else + return ..() + +/obj/item/circuit_component/bci_action + display_name = "BCI Action" + desc = "Represents an action the user can take when implanted with the brain-computer interface." + required_shells = list(/obj/item/organ/cyberimp/bci) + + /// The icon of the button + var/datum/port/input/option/icon_options + + /// The name to use for the button + var/datum/port/input/button_name + + /// Called when the user presses the button + var/datum/port/output/signal + + /// A reference to the action button itself + var/datum/action/innate/bci_action/bci_action + +/obj/item/circuit_component/bci_action/Initialize(mapload, default_icon) + . = ..() + + if (!isnull(default_icon)) + icon_options.set_input(default_icon) + + button_name = add_input_port("Name", PORT_TYPE_STRING) + + signal = add_output_port("Signal", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/bci_action/Destroy() + QDEL_NULL(bci_action) + return ..() + +/obj/item/circuit_component/bci_action/populate_options() + var/static/action_options = list( + "Blank", + + "One", + "Two", + "Three", + "Four", + "Five", + + "Blood", + "Bomb", + "Brain", + "Brain Damage", + "Cross", + "Electricity", + "Exclamation", + "Heart", + "Id", + "Info", + "Injection", + "Magnetism", + "Minus", + "Network", + "Plus", + "Power", + "Question", + "Radioactive", + "Reaction", + "Repair", + "Say", + "Scan", + "Shield", + "Skull", + "Sleep", + "Wireless", + ) + + icon_options = add_option_port("Icon", action_options) + +/obj/item/circuit_component/bci_action/register_shell(atom/movable/shell) + var/obj/item/organ/cyberimp/bci/bci = shell + + bci_action = new(src) + update_action() + + bci.actions += list(bci_action) + +/obj/item/circuit_component/bci_action/unregister_shell(atom/movable/shell) + var/obj/item/organ/cyberimp/bci/bci = shell + + bci.actions -= bci_action + QDEL_NULL(bci_action) + +/obj/item/circuit_component/bci_action/input_received(datum/port/input/port) + . = ..() + + if (.) + return + + if (!isnull(bci_action)) + update_action() + +/obj/item/circuit_component/bci_action/proc/update_action() + bci_action.name = button_name.value + bci_action.button_icon_state = "bci_[replacetextEx(lowertext(icon_options.value), " ", "_")]" + +/datum/action/innate/bci_action + name = "Action" + icon_icon = 'icons/mob/actions/actions_items.dmi' + check_flags = AB_CHECK_CONSCIOUS + button_icon_state = "bci_power" + + var/obj/item/circuit_component/bci_action/circuit_component + +/datum/action/innate/bci_action/New(obj/item/circuit_component/bci_action/circuit_component) + ..() + + src.circuit_component = circuit_component + +/datum/action/innate/bci_action/Destroy() + circuit_component.bci_action = null + circuit_component = null + + return ..() + +/datum/action/innate/bci_action/Activate() + circuit_component.signal.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/bci_core + display_name = "BCI Core" + desc = "Controls the core operations of the BCI." + + /// A reference to the action button to look at charge/get info + var/datum/action/innate/bci_charge_action/charge_action + + var/datum/port/input/message + var/datum/port/input/send_message_signal + + var/datum/port/output/user_port + + var/datum/weakref/user + +/obj/item/circuit_component/bci_core/Initialize(mapload) + . = ..() + + message = add_input_port("Message", PORT_TYPE_STRING) + send_message_signal = add_input_port("Send Message", PORT_TYPE_SIGNAL) + + user_port = add_output_port("User", PORT_TYPE_ATOM) + +/obj/item/circuit_component/bci_core/Destroy() + QDEL_NULL(charge_action) + return ..() + +/obj/item/circuit_component/bci_core/register_shell(atom/movable/shell) + var/obj/item/organ/cyberimp/bci/bci = shell + + charge_action = new(src) + bci.actions += list(charge_action) + + RegisterSignal(shell, COMSIG_ORGAN_IMPLANTED, .proc/on_organ_implanted) + RegisterSignal(shell, COMSIG_ORGAN_REMOVED, .proc/on_organ_removed) + +/obj/item/circuit_component/bci_core/unregister_shell(atom/movable/shell) + var/obj/item/organ/cyberimp/bci/bci = shell + + bci.actions -= charge_action + QDEL_NULL(charge_action) + + UnregisterSignal(shell, list( + COMSIG_ORGAN_IMPLANTED, + COMSIG_ORGAN_REMOVED, + )) + +/obj/item/circuit_component/bci_core/input_received(datum/port/input/port) + . = ..() + if (.) + return . + + if (COMPONENT_TRIGGERED_BY(send_message_signal, port)) + var/sent_message = trim(message.value) + if (!sent_message) + return + + var/mob/living/carbon/resolved_owner = user?.resolve() + if (isnull(resolved_owner)) + return + + if (resolved_owner.stat == DEAD) + return + + to_chat(resolved_owner, "You hear a strange, robotic voice in your head... \"[span_robot("[html_encode(sent_message)]")]\"") + +/obj/item/circuit_component/bci_core/proc/on_organ_implanted(datum/source, mob/living/carbon/owner) + SIGNAL_HANDLER + + user_port.set_output(owner) + user = WEAKREF(owner) + + RegisterSignal(owner, COMSIG_PARENT_EXAMINE, .proc/on_examine) + RegisterSignal(owner, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, .proc/on_borg_charge) + RegisterSignal(owner, COMSIG_LIVING_ELECTROCUTE_ACT, .proc/on_electrocute) + +/obj/item/circuit_component/bci_core/proc/on_organ_removed(datum/source, mob/living/carbon/owner) + SIGNAL_HANDLER + + user_port.set_output(null) + user = null + + UnregisterSignal(owner, list( + COMSIG_PARENT_EXAMINE, + COMSIG_PROCESS_BORGCHARGER_OCCUPANT, + COMSIG_LIVING_ELECTROCUTE_ACT, + )) + +/obj/item/circuit_component/bci_core/proc/on_borg_charge(datum/source, amount) + SIGNAL_HANDLER + + if (isnull(parent.cell)) + return + + parent.cell.give(amount) + +/obj/item/circuit_component/bci_core/proc/on_electrocute(datum/source, shock_damage, siemens_coefficient, flags) + SIGNAL_HANDLER + + if (isnull(parent.cell)) + return + + if (flags & SHOCK_ILLUSION) + return + + parent.cell.give(shock_damage * 2) + to_chat(source, span_notice("You absorb some of the shock into your [parent.name]!")) + +/obj/item/circuit_component/bci_core/proc/on_examine(datum/source, mob/mob, list/examine_text) + SIGNAL_HANDLER + + if (isobserver(mob)) + examine_text += span_notice("[source.p_they(capitalized = TRUE)] [source.p_have()] \a [parent] implanted in [source.p_them()].") + +/obj/item/circuit_component/bci_core/Topic(href, list/href_list) + ..() + + if (!isobserver(usr)) + return + + if (href_list["open_bci"]) + parent.attack_ghost(usr) + +/datum/action/innate/bci_charge_action + name = "Check BCI Charge" + check_flags = NONE + icon_icon = 'icons/obj/power.dmi' + button_icon_state = "cell" + + var/obj/item/circuit_component/bci_core/circuit_component + +/datum/action/innate/bci_charge_action/New(obj/item/circuit_component/bci_core/circuit_component) + ..() + + src.circuit_component = circuit_component + + button.maptext_x = 2 + button.maptext_y = 0 + update_maptext() + + START_PROCESSING(SSobj, src) + +/datum/action/innate/bci_charge_action/Destroy() + circuit_component.charge_action = null + circuit_component = null + + STOP_PROCESSING(SSobj, src) + + return ..() + +/datum/action/innate/bci_charge_action/Trigger() + var/obj/item/stock_parts/cell/cell = circuit_component.parent.cell + + if (isnull(cell)) + to_chat(owner, span_boldwarning("[circuit_component.parent] has no power cell.")) + else + to_chat(owner, span_info("[circuit_component.parent]'s [cell.name] has [cell.percent()]% charge left.")) + to_chat(owner, span_info("You can recharge it by using a cyborg recharging station.")) + +/datum/action/innate/bci_charge_action/process(delta_time) + update_maptext() + +/datum/action/innate/bci_charge_action/proc/update_maptext() + var/obj/item/stock_parts/cell/cell = circuit_component.parent.cell + button.maptext = cell ? MAPTEXT("[cell.percent()]%") : "" + +/obj/machinery/bci_implanter + name = "brain-computer interface manipulation chamber" + desc = "A machine that, when given a brain-computer interface, will implant it into an occupant. Otherwise, will remove any brain-computer interfaces they already have." + circuit = /obj/item/circuitboard/machine/bci_implanter + icon = 'icons/obj/machines/bci_implanter.dmi' + icon_state = "bci_implanter" + base_icon_state = "bci_implanter" + layer = ABOVE_WINDOW_LAYER + use_power = IDLE_POWER_USE + anchored = TRUE + density = TRUE + obj_flags = NO_BUILD // Becomes undense when the door is open + idle_power_usage = 50 + active_power_usage = 300 + + var/busy = FALSE + var/busy_icon_state + var/locked = FALSE + + var/datum/weakref/bci_to_implant + + COOLDOWN_DECLARE(message_cooldown) + +/obj/machinery/bci_implanter/Initialize(mapload) + . = ..() + occupant_typecache = typecacheof(/mob/living/carbon) + +/obj/machinery/bci_implanter/Destroy() + QDEL_NULL(bci_to_implant) + return ..() + +/obj/machinery/bci_implanter/examine(mob/user) + . = ..() + + if (isnull(bci_to_implant?.resolve())) + . += span_notice("There is no BCI inserted.") + else + . += span_notice("Right-click to remove current BCI.") + +/obj/machinery/bci_implanter/proc/set_busy(status, working_icon) + busy = status + busy_icon_state = working_icon + update_appearance() + +/obj/machinery/bci_implanter/update_icon_state() + if (occupant) + icon_state = busy ? busy_icon_state : "[base_icon_state]_occupied" + return ..() + icon_state = "[base_icon_state][state_open ? "_open" : null]" + return ..() + +/obj/machinery/bci_implanter/update_overlays() + var/list/overlays = ..() + + if ((stat & MAINT) || panel_open) + overlays += "maint" + return overlays + + if (stat & (NOPOWER|BROKEN)) + return overlays + + if (busy || locked) + overlays += "red" + if (locked) + overlays += "bolted" + return overlays + + overlays += "green" + + return overlays + +/obj/machinery/bci_implanter/attack_hand_secondary(mob/user, list/modifiers) + . = ..() + if (. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return . + + if(!user.Adjacent(src)) + return + + if (locked) + balloon_alert(user, "it's locked!") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + var/obj/item/organ/cyberimp/bci/bci_to_implant_resolved = bci_to_implant?.resolve() + if (isnull(bci_to_implant_resolved)) + balloon_alert(user, "no bci inserted!") + else + user.put_in_hands(bci_to_implant_resolved) + balloon_alert(user, "ejected bci") + + bci_to_implant = null + + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/machinery/bci_implanter/attackby(obj/item/weapon, mob/user, params) + var/obj/item/organ/cyberimp/bci/new_bci = weapon + if (istype(new_bci)) + if (!(locate(/obj/item/integrated_circuit) in new_bci)) + balloon_alert(user, "bci has no circuit!") + return + + var/obj/item/organ/cyberimp/bci/previous_bci_to_implant = bci_to_implant?.resolve() + + bci_to_implant = WEAKREF(weapon) + weapon.forceMove(src) + + if (isnull(previous_bci_to_implant)) + balloon_alert(user, "inserted bci") + else + balloon_alert(user, "swapped bci") + user.put_in_hands(previous_bci_to_implant) + + return + + return ..() + +/obj/machinery/bci_implanter/attackby_secondary(obj/item/weapon, mob/user, params) + if (!occupant && default_deconstruction_screwdriver(user, icon_state, icon_state, weapon)) + update_appearance() + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + if (default_pry_open(weapon)) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + if (default_deconstruction_crowbar(weapon)) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/machinery/bci_implanter/proc/start_process() + if (stat & (NOPOWER|BROKEN)) + return + if ((stat & MAINT) || panel_open) + return + if (!occupant || busy) + return + + var/locked_state = locked + locked = TRUE + + set_busy(TRUE, "[initial(icon_state)]_raising") + addtimer(CALLBACK(src, .proc/set_busy, TRUE, "[initial(icon_state)]_active"), 1 SECONDS) + addtimer(CALLBACK(src, .proc/set_busy, TRUE, "[initial(icon_state)]_falling"), 2 SECONDS) + addtimer(CALLBACK(src, .proc/complete_process, locked_state), 3 SECONDS) + +/obj/machinery/bci_implanter/proc/complete_process(locked_state) + locked = locked_state + set_busy(FALSE) + + var/mob/living/carbon/carbon_occupant = occupant + if (!istype(carbon_occupant)) + return + + playsound(loc, 'sound/machines/ping.ogg', 30, FALSE) + + var/obj/item/organ/cyberimp/bci/bci_organ = carbon_occupant.getorgan(/obj/item/organ/cyberimp/bci) + var/obj/item/organ/cyberimp/bci/bci_to_implant_resolved = bci_to_implant?.resolve() + + if (bci_organ) + bci_organ.Remove(carbon_occupant) + + if (isnull(bci_to_implant_resolved)) + say("Occupant's previous brain-computer interface has been transferred to internal storage unit.") + bci_organ.forceMove(src) + bci_to_implant = WEAKREF(bci_organ) + else + say("Occupant's previous brain-computer interface has been ejected.") + bci_organ.forceMove(drop_location()) + else if (!isnull(bci_to_implant_resolved)) + say("Occupant has been injected with [bci_to_implant_resolved].") + bci_to_implant_resolved.Insert(carbon_occupant) + bci_to_implant = null + +/obj/machinery/bci_implanter/open_machine() + if(state_open) + return FALSE + + ..() + + return TRUE + +/obj/machinery/bci_implanter/close_machine(mob/living/carbon/user) + if(!state_open) + return FALSE + + ..() + + var/mob/living/carbon/carbon_occupant = occupant + if (istype(occupant)) + var/obj/item/organ/cyberimp/bci/existing_bci_organ = carbon_occupant.getorgan(/obj/item/organ/cyberimp/bci) + if (isnull(existing_bci_organ) && isnull(bci_to_implant?.resolve())) + say("No brain-computer interface inserted, and occupant does not have one. Insert a BCI to implant one.") + playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE) + return FALSE + + addtimer(CALLBACK(src, .proc/start_process), 1 SECONDS) + return TRUE + +/obj/machinery/bci_implanter/relaymove(mob/living/user, direction) + var/message + + if (locked) + message = "it won't budge!" + else if (user.stat != CONSCIOUS) + message = "you don't have the energy!" + + if (!isnull(message)) + if (COOLDOWN_FINISHED(src, message_cooldown)) + COOLDOWN_START(src, message_cooldown, 5 SECONDS) + balloon_alert(user, message) + + return + + open_machine() + +/obj/machinery/bci_implanter/interact(mob/user) + if (state_open) + close_machine(null, user) + return + else if (locked) + balloon_alert(user, "it's locked!") + return + + open_machine() + +/obj/item/circuitboard/machine/bci_implanter + name = "Brain-Computer Interface Manipulation Chamber (Machine Board)" + greyscale_colors = CIRCUIT_COLOR_SCIENCE + build_path = /obj/machinery/bci_implanter + req_components = list( + /obj/item/stock_parts/micro_laser = 2, + /obj/item/stock_parts/manipulator = 1, + ) diff --git a/code/modules/wiremod/shell/compact_remote.dm b/code/modules/wiremod/shell/compact_remote.dm new file mode 100644 index 0000000000..526567a92a --- /dev/null +++ b/code/modules/wiremod/shell/compact_remote.dm @@ -0,0 +1,51 @@ +/** + * # Compact Remote + * + * A handheld device with one big button. + */ +/obj/item/compact_remote + name = "compact remote" + icon = 'icons/obj/wiremod.dmi' + icon_state = "setup_small_simple" + inhand_icon_state = "electronic" + worn_icon_state = "electronic" + lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' + light_system = MOVABLE_LIGHT_DIRECTIONAL + light_on = FALSE + +/obj/item/compact_remote/Initialize(mapload) + . = ..() + AddComponent(/datum/component/shell, list( + new /obj/item/circuit_component/compact_remote() + ), SHELL_CAPACITY_SMALL) + +/obj/item/circuit_component/compact_remote + display_name = "Compact Remote" + desc = "Used to receive inputs from the compact remote shell. Use the shell in hand to trigger the output signal." + + /// Called when attack_self is called on the shell. + var/datum/port/output/signal + /// The user who used the bot + var/datum/port/output/entity + +/obj/item/circuit_component/compact_remote/Initialize(mapload) + . = ..() + entity = add_output_port("User", PORT_TYPE_ATOM) + signal = add_output_port("Signal", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/compact_remote/register_shell(atom/movable/shell) + RegisterSignal(shell, COMSIG_ITEM_ATTACK_SELF, .proc/send_trigger) + +/obj/item/circuit_component/compact_remote/unregister_shell(atom/movable/shell) + UnregisterSignal(shell, COMSIG_ITEM_ATTACK_SELF) + +/** + * Called when the shell item is used in hand. + */ +/obj/item/circuit_component/compact_remote/proc/send_trigger(atom/source, mob/user) + SIGNAL_HANDLER + source.balloon_alert(user, "clicked primary button") + playsound(source, get_sfx("terminal_type"), 25, FALSE) + entity.set_output(user) + signal.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/shell/controller.dm b/code/modules/wiremod/shell/controller.dm new file mode 100644 index 0000000000..9539a0521a --- /dev/null +++ b/code/modules/wiremod/shell/controller.dm @@ -0,0 +1,89 @@ +/** + * # Compact Remote + * + * A handheld device with several buttons. + * In game, this translates to having different signals for normal usage, alt-clicking, and ctrl-clicking when in your hand. + */ +/obj/item/controller + name = "controller" + icon = 'icons/obj/wiremod.dmi' + icon_state = "setup_small_calc" + inhand_icon_state = "electronic" + worn_icon_state = "electronic" + lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' + light_system = MOVABLE_LIGHT_DIRECTIONAL + light_on = FALSE + +/obj/item/controller/Initialize(mapload) + . = ..() + AddComponent(/datum/component/shell, list( + new /obj/item/circuit_component/controller() + ), SHELL_CAPACITY_MEDIUM) + +/obj/item/circuit_component/controller + display_name = "Controller" + desc = "Used to receive inputs from the controller shell. Use the shell in hand to trigger the output signal. Alt-click for the alternate signal. Right click for the extra signal." + + /// The three separate buttons that are called in attack_hand on the shell. + var/datum/port/output/signal + var/datum/port/output/alt + var/datum/port/output/right + + /// The entity output + var/datum/port/output/entity + +/obj/item/circuit_component/controller/Initialize(mapload) + . = ..() + entity = add_output_port("User", PORT_TYPE_ATOM) + signal = add_output_port("Signal", PORT_TYPE_SIGNAL) + alt = add_output_port("Alternate Signal", PORT_TYPE_SIGNAL) + right = add_output_port("Extra Signal", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/controller/register_shell(atom/movable/shell) + RegisterSignal(shell, COMSIG_ITEM_ATTACK_SELF, .proc/send_trigger) + RegisterSignal(shell, COMSIG_CLICK_ALT, .proc/send_alternate_signal) + RegisterSignal(shell, COMSIG_ITEM_ATTACK_SELF_SECONDARY, .proc/send_right_signal) + +/obj/item/circuit_component/controller/unregister_shell(atom/movable/shell) + UnregisterSignal(shell, list( + COMSIG_ITEM_ATTACK_SELF, + COMSIG_ITEM_ATTACK_SELF_SECONDARY, + COMSIG_CLICK_ALT, + )) + +/** + * Called when the shell item is used in hand + */ +/obj/item/circuit_component/controller/proc/send_trigger(atom/source, mob/user) + SIGNAL_HANDLER + if(!user.Adjacent(source)) + return + source.balloon_alert(user, "clicked primary button") + playsound(source, get_sfx("terminal_type"), 25, FALSE) + entity.set_output(user) + signal.set_output(COMPONENT_SIGNAL) + +/** + * Called when the shell item is alt-clicked + */ +/obj/item/circuit_component/controller/proc/send_alternate_signal(atom/source, mob/user) + SIGNAL_HANDLER + if(!user.Adjacent(source)) + return + source.balloon_alert(user, "clicked alternate button") + playsound(source, get_sfx("terminal_type"), 25, FALSE) + entity.set_output(user) + alt.set_output(COMPONENT_SIGNAL) + +/** + * Called when the shell item is right-clicked in active hand + */ +/obj/item/circuit_component/controller/proc/send_right_signal(atom/source, mob/user) + SIGNAL_HANDLER + if(!user.Adjacent(source)) + return + source.balloon_alert(user, "clicked extra button") + playsound(source, get_sfx("terminal_type"), 25, FALSE) + entity.set_output(user) + right.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/shell/drone.dm b/code/modules/wiremod/shell/drone.dm new file mode 100644 index 0000000000..0133f35230 --- /dev/null +++ b/code/modules/wiremod/shell/drone.dm @@ -0,0 +1,82 @@ +/** + * # Drone + * + * A movable mob that can be fed inputs on which direction to travel. + */ +/mob/living/circuit_drone + name = "drone" + icon = 'icons/obj/wiremod.dmi' + icon_state = "setup_medium_med" + living_flags = 0 + light_system = MOVABLE_LIGHT_DIRECTIONAL + light_on = FALSE + +/mob/living/circuit_drone/Initialize(mapload) + . = ..() + AddComponent(/datum/component/shell, list( + new /obj/item/circuit_component/bot_circuit() + ), SHELL_CAPACITY_LARGE) + +/mob/living/circuit_drone/updatehealth() + . = ..() + if(health < 0) + gib(no_brain = TRUE, no_organs = TRUE, no_bodyparts = TRUE) + +/mob/living/circuit_drone/spawn_gibs() + new /obj/effect/gibspawner/robot(drop_location(), src, get_static_viruses()) + +/obj/item/circuit_component/bot_circuit + display_name = "Drone" + desc = "Used to send movement output signals to the drone shell." + + /// The inputs to allow for the drone to move + var/datum/port/input/north + var/datum/port/input/east + var/datum/port/input/south + var/datum/port/input/west + + // Done like this so that travelling diagonally is more simple + COOLDOWN_DECLARE(north_delay) + COOLDOWN_DECLARE(east_delay) + COOLDOWN_DECLARE(south_delay) + COOLDOWN_DECLARE(west_delay) + + /// Delay between each movement + var/move_delay = 0.2 SECONDS + +/obj/item/circuit_component/bot_circuit/Initialize(mapload) + . = ..() + north = add_input_port("Move North", PORT_TYPE_SIGNAL) + east = add_input_port("Move East", PORT_TYPE_SIGNAL) + south = add_input_port("Move South", PORT_TYPE_SIGNAL) + west = add_input_port("Move West", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/bot_circuit/input_received(datum/port/input/port) + . = ..() + if(.) + return + + var/mob/living/shell = parent.shell + if(!istype(shell) || shell.stat) + return + + var/direction + + if(COMPONENT_TRIGGERED_BY(north, port) && COOLDOWN_FINISHED(src, north_delay)) + direction = NORTH + COOLDOWN_START(src, north_delay, move_delay) + else if(COMPONENT_TRIGGERED_BY(east, port) && COOLDOWN_FINISHED(src, east_delay)) + direction = EAST + COOLDOWN_START(src, east_delay, move_delay) + else if(COMPONENT_TRIGGERED_BY(south, port) && COOLDOWN_FINISHED(src, south_delay)) + direction = SOUTH + COOLDOWN_START(src, south_delay, move_delay) + else if(COMPONENT_TRIGGERED_BY(west, port) && COOLDOWN_FINISHED(src, west_delay)) + direction = WEST + COOLDOWN_START(src, west_delay, move_delay) + + if(!direction) + return + + if(shell.Process_Spacemove(direction)) + shell.Move(get_step(shell, direction), direction) diff --git a/code/modules/wiremod/shell/moneybot.dm b/code/modules/wiremod/shell/moneybot.dm new file mode 100644 index 0000000000..133f0a5e59 --- /dev/null +++ b/code/modules/wiremod/shell/moneybot.dm @@ -0,0 +1,140 @@ +/** + * # Money Bot + * + * Immobile (but not dense) shell that can receive and dispense money. + */ +/obj/structure/money_bot + name = "money bot" + icon = 'icons/obj/wiremod.dmi' + icon_state = "setup_large" + + density = FALSE + light_system = MOVABLE_LIGHT + light_on = FALSE + + var/stored_money = 0 + +/obj/structure/money_bot/deconstruct(disassembled) + new /obj/item/holochip(drop_location(), stored_money) + return ..() + +/obj/structure/money_bot/proc/add_money(to_add) + stored_money += to_add + SEND_SIGNAL(src, COMSIG_MONEYBOT_ADD_MONEY, to_add) + +/obj/structure/money_bot/Initialize(mapload) + . = ..() + AddComponent(/datum/component/shell, list( + new /obj/item/circuit_component/money_bot(), + new /obj/item/circuit_component/money_dispenser() + ), SHELL_CAPACITY_LARGE) + +/obj/structure/money_bot/wrench_act(mob/living/user, obj/item/tool) + set_anchored(!anchored) + tool.play_tool_sound(src) + balloon_alert(user, "You [anchored?"secure":"unsecure"] [src].") + return TRUE + + +/obj/item/circuit_component/money_dispenser + display_name = "Money Dispenser" + desc = "Used to dispense money from the money bot. Money is taken from the internal storage of money." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + /// The amount of money to dispense + var/datum/port/input/dispense_amount + + /// Outputs a signal when it fails to output any money. + var/datum/port/output/on_fail + + var/obj/structure/money_bot/attached_bot + +/obj/item/circuit_component/money_dispenser/Initialize(mapload) + . = ..() + dispense_amount = add_input_port("Amount", PORT_TYPE_NUMBER) + on_fail = add_output_port("On Failed", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/money_dispenser/register_shell(atom/movable/shell) + . = ..() + if(istype(shell, /obj/structure/money_bot)) + attached_bot = shell + +/obj/item/circuit_component/money_dispenser/unregister_shell(atom/movable/shell) + attached_bot = null + return ..() + +/obj/item/circuit_component/money_dispenser/input_received(datum/port/input/port) + . = ..() + if(.) + return + + if(!attached_bot) + return + + var/to_dispense = clamp(dispense_amount.value, 0, attached_bot.stored_money) + if(!to_dispense) + on_fail.set_output(COMPONENT_SIGNAL) + return + + attached_bot.add_money(-to_dispense) + new /obj/item/holochip(drop_location(), to_dispense) + +/obj/item/circuit_component/money_bot + display_name = "Money Bot" + var/obj/structure/money_bot/attached_bot + desc = "Used to receive input signals when money is inserted into the money bot shell and also keep track of the total money in the shell." + + /// Total money in the shell + var/datum/port/output/total_money + /// Amount of the last money inputted into the shell + var/datum/port/output/money_input + /// Trigger for when money is inputted into the shell + var/datum/port/output/money_trigger + /// The person who input the money + var/datum/port/output/entity + +/obj/item/circuit_component/money_bot/Initialize(mapload) + . = ..() + total_money = add_output_port("Total Money", PORT_TYPE_NUMBER) + money_input = add_output_port("Last Input Money", PORT_TYPE_NUMBER) + entity = add_output_port("User", PORT_TYPE_ATOM) + money_trigger = add_output_port("Money Input", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/money_bot/register_shell(atom/movable/shell) + . = ..() + if(istype(shell, /obj/structure/money_bot)) + attached_bot = shell + total_money.set_output(attached_bot.stored_money) + RegisterSignal(shell, COMSIG_PARENT_ATTACKBY, .proc/handle_money_insert) + RegisterSignal(shell, COMSIG_MONEYBOT_ADD_MONEY, .proc/handle_money_update) + +/obj/item/circuit_component/money_bot/unregister_shell(atom/movable/shell) + UnregisterSignal(shell, list( + COMSIG_PARENT_ATTACKBY, + COMSIG_MONEYBOT_ADD_MONEY, + )) + total_money.set_output(null) + attached_bot = null + return ..() + +/obj/item/circuit_component/money_bot/proc/handle_money_insert(atom/source, obj/item/item, mob/living/attacker) + SIGNAL_HANDLER + if(!attached_bot || !iscash(item)) + return + + var/amount_to_insert = item.get_item_credit_value() + if(!amount_to_insert) + balloon_alert(attacker, "this has no value!") + return + + attached_bot.add_money(amount_to_insert) + balloon_alert(attacker, "inserted [amount_to_insert] credits.") + money_input.set_output(amount_to_insert) + entity.set_output(attacker) + money_trigger.set_output(COMPONENT_SIGNAL) + qdel(item) + +/obj/item/circuit_component/money_bot/proc/handle_money_update(atom/source) + SIGNAL_HANDLER + if(attached_bot) + total_money.set_output(attached_bot.stored_money) diff --git a/code/modules/wiremod/shell/scanner.dm b/code/modules/wiremod/shell/scanner.dm new file mode 100644 index 0000000000..3120ac192a --- /dev/null +++ b/code/modules/wiremod/shell/scanner.dm @@ -0,0 +1,62 @@ +/** + * # Scanner + * + * A handheld device that lets you flash it over people. + */ +/obj/item/wiremod_scanner + name = "scanner" + icon = 'icons/obj/wiremod.dmi' + icon_state = "setup_small" + inhand_icon_state = "electronic" + worn_icon_state = "electronic" + lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' + light_system = MOVABLE_LIGHT_DIRECTIONAL + light_on = FALSE + +/obj/item/wiremod_scanner/Initialize(mapload) + . = ..() + AddComponent(/datum/component/shell, list( + new /obj/item/circuit_component/wiremod_scanner() + ), SHELL_CAPACITY_SMALL) + +/obj/item/circuit_component/wiremod_scanner + display_name = "Scanner" + desc = "Used to receive scanned entities from the scanner." + + /// Called when afterattack is called on the shell. + var/datum/port/output/signal + + /// The attacker + var/datum/port/output/attacker + + /// The entity being attacked + var/datum/port/output/attacking + + + +/obj/item/circuit_component/wiremod_scanner/Initialize(mapload) + . = ..() + attacker = add_output_port("Scanner", PORT_TYPE_ATOM) + attacking = add_output_port("Scanned Entity", PORT_TYPE_ATOM) + signal = add_output_port("Scanned", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/wiremod_scanner/register_shell(atom/movable/shell) + RegisterSignal(shell, COMSIG_ITEM_AFTERATTACK, .proc/handle_afterattack) + +/obj/item/circuit_component/wiremod_scanner/unregister_shell(atom/movable/shell) + UnregisterSignal(shell, COMSIG_ITEM_AFTERATTACK) + +/** + * Called when the shell item attacks something + */ +/obj/item/circuit_component/wiremod_scanner/proc/handle_afterattack(atom/source, atom/target, mob/user, proximity_flag) + SIGNAL_HANDLER + if(!proximity_flag) + return + source.balloon_alert(user, "scanned object") + playsound(source, get_sfx("terminal_type"), 25, FALSE) + attacker.set_output(user) + attacking.set_output(target) + signal.set_output(COMPONENT_SIGNAL) + diff --git a/code/modules/wiremod/shell/scanner_gate.dm b/code/modules/wiremod/shell/scanner_gate.dm new file mode 100644 index 0000000000..b8484f3182 --- /dev/null +++ b/code/modules/wiremod/shell/scanner_gate.dm @@ -0,0 +1,66 @@ +/obj/structure/scanner_gate_shell + name = "circuit scanner gate" + desc = "A gate able to perform mid-depth scans on any organisms who pass under it." + icon = 'icons/obj/machines/scangate.dmi' + icon_state = "scangate_black" + var/scanline_timer + +/obj/structure/scanner_gate_shell/Initialize(mapload) + . = ..() + set_scanline("passive") + var/static/list/loc_connections = list( + COMSIG_ATOM_ENTERED = .proc/on_entered, + ) + AddElement(/datum/element/connect_loc, loc_connections) + + AddComponent(/datum/component/shell, list( + new /obj/item/circuit_component/scanner_gate() + ), SHELL_CAPACITY_LARGE, SHELL_FLAG_REQUIRE_ANCHOR) + +/obj/structure/scanner_gate_shell/wrench_act(mob/living/user, obj/item/tool) + set_anchored(!anchored) + tool.play_tool_sound(src) + balloon_alert(user, "You [anchored?"secure":"unsecure"] [src].") + return TRUE + +/obj/structure/scanner_gate_shell/proc/on_entered(datum/source, atom/movable/AM) + SIGNAL_HANDLER + set_scanline("scanning", 10) + SEND_SIGNAL(src, COMSIG_SCANGATE_SHELL_PASS, AM) + +/obj/structure/scanner_gate_shell/proc/set_scanline(type, duration) + cut_overlays() + deltimer(scanline_timer) + add_overlay(type) + if(duration) + scanline_timer = addtimer(CALLBACK(src, .proc/set_scanline, "passive"), duration, TIMER_STOPPABLE) + +/obj/item/circuit_component/scanner_gate + display_name = "Scanner Gate" + desc = "A gate able to perform mid-depth scans on any object that pass through it." + + circuit_flags = CIRCUIT_FLAG_OUTPUT_SIGNAL + + var/datum/port/output/scanned + + var/obj/structure/scanner_gate_shell/attached_gate + +/obj/item/circuit_component/scanner_gate/Initialize(mapload) + . = ..() + scanned = add_output_port("Scanned Object", PORT_TYPE_ATOM) + +/obj/item/circuit_component/scanner_gate/register_shell(atom/movable/shell) + . = ..() + if(istype(shell, /obj/structure/scanner_gate_shell)) + attached_gate = shell + RegisterSignal(attached_gate, COMSIG_SCANGATE_SHELL_PASS, .proc/on_trigger) + +/obj/item/circuit_component/scanner_gate/unregister_shell(atom/movable/shell) + UnregisterSignal(attached_gate, COMSIG_SCANGATE_SHELL_PASS) + attached_gate = null + return ..() + +/obj/item/circuit_component/scanner_gate/proc/on_trigger(datum/source, atom/movable/passed) + SIGNAL_HANDLER + scanned.set_output(passed) + trigger_output.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/shell/server.dm b/code/modules/wiremod/shell/server.dm new file mode 100644 index 0000000000..57c4945e2c --- /dev/null +++ b/code/modules/wiremod/shell/server.dm @@ -0,0 +1,24 @@ +/** + * # Server + * + * Immobile (but not dense) shells that can interact with + * world. + */ +/obj/structure/server + name = "server" + icon = 'icons/obj/wiremod.dmi' + icon_state = "setup_stationary" + + density = TRUE + light_system = MOVABLE_LIGHT + light_on = FALSE + +/obj/structure/server/Initialize(mapload) + . = ..() + AddComponent(/datum/component/shell, null, SHELL_CAPACITY_VERY_LARGE, SHELL_FLAG_REQUIRE_ANCHOR|SHELL_FLAG_USB_PORT) + +/obj/structure/server/wrench_act(mob/living/user, obj/item/tool) + set_anchored(!anchored) + tool.play_tool_sound(src) + balloon_alert(user, "You [anchored?"secure":"unsecure"] [src].") + return TRUE diff --git a/code/modules/wiremod/shell/shell_items.dm b/code/modules/wiremod/shell/shell_items.dm new file mode 100644 index 0000000000..4e6673e7c8 --- /dev/null +++ b/code/modules/wiremod/shell/shell_items.dm @@ -0,0 +1,65 @@ +/** + * # Shell Item + * + * Printed out by protolathes. Screwdriver to complete the shell. + */ +/obj/item/shell + name = "assembly" + desc = "A shell assembly that can be completed by screwdrivering it." + icon = 'icons/obj/wiremod.dmi' + var/shell_to_spawn + var/screw_delay = 3 SECONDS + +/obj/item/shell/screwdriver_act(mob/living/user, obj/item/tool) + user.visible_message(span_notice("[user] begins finishing [src]."), span_notice("You begin finishing [src].")) + tool.play_tool_sound(src) + if(!do_after(user, screw_delay, src)) + return + user.visible_message(span_notice("[user] finishes [src]."), span_notice("You finish [src].")) + + var/turf/drop_loc = drop_location() + + qdel(src) + if(drop_loc) + new shell_to_spawn(drop_loc) + + return TRUE + +/obj/item/shell/bot + name = "bot assembly" + icon_state = "setup_medium_box-open" + shell_to_spawn = /obj/structure/bot + +/obj/item/shell/money_bot + name = "money bot assembly" + icon_state = "setup_large-open" + shell_to_spawn = /obj/structure/money_bot + +/obj/item/shell/drone + name = "drone assembly" + icon_state = "setup_medium_med-open" + shell_to_spawn = /mob/living/circuit_drone + +/obj/item/shell/server + name = "server assembly" + icon_state = "setup_stationary-open" + shell_to_spawn = /obj/structure/server + screw_delay = 10 SECONDS + +/obj/item/shell/airlock + name = "circuit airlock assembly" + icon = 'icons/obj/doors/airlocks/station/public.dmi' + icon_state = "construction" + shell_to_spawn = /obj/machinery/door/airlock/shell + screw_delay = 10 SECONDS + +/obj/item/shell/bci + name = "brain-computer interface assembly" + icon_state = "bci-open" + shell_to_spawn = /obj/item/organ/cyberimp/bci + +/obj/item/shell/scanner_gate + name = "scanner gate assembly" + icon = 'icons/obj/machines/scangate.dmi' + icon_state = "scangate_black_open" + shell_to_spawn = /obj/structure/scanner_gate_shell diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm index f208cafe4e..931c467c47 100644 --- a/code/modules/zombie/items.dm +++ b/code/modules/zombie/items.dm @@ -19,7 +19,7 @@ wound_bonus = -30 bare_wound_bonus = 15 -/obj/item/zombie_hand/Initialize() +/obj/item/zombie_hand/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) @@ -39,7 +39,7 @@ else if(istype(target, /obj)) //do far more damage to non mobs so we can get through airlocks var/obj/target_object = target - target_object.take_damage(force * 3, BRUTE, "melee", 0) + target_object.take_damage(force * 3, BRUTE, MELEE, 0) else if(isliving(target)) if(ishuman(target)) try_to_zombie_infect(target) diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm index a724d26314..d8908ee21a 100644 --- a/code/modules/zombie/organs.dm +++ b/code/modules/zombie/organs.dm @@ -13,7 +13,7 @@ var/revive_time_max = 700 var/timer_id -/obj/item/organ/zombie_infection/Initialize() +/obj/item/organ/zombie_infection/Initialize(mapload) . = ..() if(iscarbon(loc)) Insert(loc) diff --git a/config/config.txt b/config/config.txt index c0c683373d..63adaee716 100644 --- a/config/config.txt +++ b/config/config.txt @@ -15,6 +15,7 @@ $include entries/admin.txt $include entries/alert.txt $include entries/antag_rep.txt +$include entries/bot.txt $include entries/comms.txt $include entries/connections.txt $include entries/dbconfig.txt diff --git a/config/dynamic.json b/config/dynamic.json new file mode 100644 index 0000000000..b229658e3a --- /dev/null +++ b/config/dynamic.json @@ -0,0 +1,146 @@ +{ + "Dynamic": {}, + "Roundstart": { + "Traitors": { + "cost": 8, + "scaling_cost": 9, + "weight": 5, + "required_candidates": 1, + "minimum_required_age": 0, + "requirements": [ + 101, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10 + ], + "antag_cap": { + "denominator": 24 + }, + "protected_roles": [ + "Prisoner", + "Security Officer", + "Warden", + "Detective", + "Head of Security", + "Captain" + ], + "restricted_roles": [ + "Cyborg" + ] + }, + + "Blood Brothers": { + "weight": 0 + }, + + "Changelings": { + "weight": 3 + }, + + "Heretics": { + "weight": 3 + }, + + "Wizard": { + "weight": 3 + }, + + "Blood Cult": { + "weight": 2 + }, + + "Nuclear Emergency": { + "weight": 3 + }, + + "Revolution": { + "weight": 2 + }, + + "Clock Cult": { + "weight": 3 + }, + + "Families": { + "weight": 3 + } + }, + + "Midround": { + "Syndicate Sleeper Agent": { + "weight": 7 + }, + + "Malfunctioning AI": { + "weight": 3 + }, + + "Wizard": { + "weight": 2 + }, + + "Nuclear Assault": { + "weight": 3 + }, + + "Blob": { + "weight": 2 + }, + + "Blob Infection": { + "weight": 2 + }, + + "Alien Infestation": { + "weight": 3 + }, + + "Nightmare": { + "weight": 4 + }, + + "Space Dragon": { + "weight": 3 + }, + + "Abductors": { + "weight": 3 + }, + + "Swarmers": { + "weight": 3 + }, + + "Space Ninja": { + "weight": 4 + }, + + "Family Head Aspirants": { + "weight": 3 + }, + + "Spiders": { + "weight": 0 + } + }, + + "Latejoin": { + "Syndicate Infiltrator": { + "weight": 7 + }, + + "Provocateur": { + "weight": 2 + }, + + "Heretic Smuggler": { + "weight": 4 + } + } +} diff --git a/config/entries/admin.txt b/config/entries/admin.txt index 883bda9422..d7932bbe13 100644 --- a/config/entries/admin.txt +++ b/config/entries/admin.txt @@ -52,8 +52,12 @@ ANNOUNCE_ADMIN_LOGOUT ## Uncomment to have an admin message sent anytime an admin connects to a round in play, you can edit the messages in admin.dm #ANNOUNCE_ADMIN_LOGIN +## Uncomment to enable global ban DB using the provided URL. The API should expect to receive a ckey at the end of the URL. ## More API details can be found here: https://centcom.melonmesa.com -CENTCOM_BAN_DB https://centcom.melonmesa.com/ban/search +#CENTCOM_BAN_DB https://centcom.melonmesa.com/ban/search +## Uncomment to enable source whitelisting, a comma-separated list (no spaces) of CentCom sources (sourceName). +## If enabled, only bans from these servers will be shown to admins using CentCom. The default sources list is an example. +#CENTCOM_SOURCE_WHITELIST Beestation MRP,TGMC,FTL13 ## AUTOADMIN ## The default admin rank @@ -77,3 +81,17 @@ GUEST_BAN ## Allow admin hrefs that don't use the new token system, will eventually be removed DEBUG_ADMIN_HREFS + +## +## Those deadmin configs will lock admins this way, so it's not really recommended unless really needed +## +## Uncomment to automatically deadmin players when the game starts. +#AUTO_DEADMIN_PLAYERS + +## Uncomment to automatically deadmin antagonists when they gain the role. +#AUTO_DEADMIN_ANTAGONISTS + +## Uncomment to automatically deadmin specific role sets when a player joins the game. +#AUTO_DEADMIN_HEADS +#AUTO_DEADMIN_SECURITY +#AUTO_DEADMIN_SILICONS diff --git a/config/entries/bot.txt b/config/entries/bot.txt new file mode 100644 index 0000000000..eb9e8855e7 --- /dev/null +++ b/config/entries/bot.txt @@ -0,0 +1,17 @@ +## Chat Announce Options +## Various messages to be sent to game chats +## Uncommenting these will enable them, by default they will be broadcast to Game chat channels on TGS3 or non-admin channels on TGS4 +## If using TGS4, the string option can be set as a chat channel tag to limit the message to channels of that tag type (case-sensitive) +## i.e. CHAT_ANNOUNCE_NEW_GAME chat_channel_tag + +## Announcements for when a new round begins. +#CHAT_ANNOUNCE_NEW_GAME + +## Announcements for when the round ends, pending server reboot. +#CHAT_ROUNDEND_NOTICE_TAG + +## For where should the one true bird speak? +#CHAT_SQUAWK_TAG + +## Role ID that, when present, will be pinged every round end. +#CHAT_REBOOT_ROLE diff --git a/config/entries/connections.txt b/config/entries/connections.txt index 6351a77fcf..41df00bc40 100644 --- a/config/entries/connections.txt +++ b/config/entries/connections.txt @@ -2,9 +2,12 @@ ## Requires database #PANIC_BUNKER -## If a player connects during a bunker with less then or this amount of living time (Minutes), we deny the connection +## If a player connects during a bunker with less then or this amount of living time (Minutes), we deny the connection. Set to -1 to disable criteria. #PANIC_BUNKER_LIVING 90 +## The above but for VPN connections. Set to -1 to disable criteria. You can set the above to disabled and set this to only enforce bunker on VPNs. +#PANIC_BUNKER_LIVING_VPN 120 + ## The message the Panic Bunker gives when someone is rejected by it ## %minutes% is replaced with PANIC_BUNKER_LIVING on runtime, remove it if you don't want this #PANIC_BUNKER_MESSAGE Sorry, but the server is currently not accepting connections from players with less than %minutes% minutes of living time. diff --git a/config/entries/dyanmic.txt b/config/entries/dyanmic.txt deleted file mode 100644 index e08fb7634d..0000000000 --- a/config/entries/dyanmic.txt +++ /dev/null @@ -1,318 +0,0 @@ -## Dynamic storytellers weights: how likely each storyteller is to show up. This is adjusted by voting and recency. -STORYTELLER_WEIGHT CHAOTIC 2 -STORYTELLER_WEIGHT TEAMWORK 4 -STORYTELLER_WEIGHT CONVERSION 0 -STORYTELLER_WEIGHT RANDOM 2 -STORYTELLER_WEIGHT CLASSIC 6 -STORYTELLER_WEIGHT INTRIGUE 6 -STORYTELLER_WEIGHT STORY 6 -STORYTELLER_WEIGHT CALM 6 -STORYTELLER_WEIGHT EXTENDED 0 - -## Dynamic storyteller minimum player coutns: how many players before this storyteller can be rolled. -STORYTELLER_MIN_PLAYERS CHAOTIC 30 -STORYTELLER_MIN_PLAYERS TEAMWORK 30 - -## If this is uncommented, Dynamic won't disable certain storytellers based on recent round threats -#NO_STORYTELLER_THREAT_REMOVAL - -## Injection delays: how long (in minutes) will pass before a midround or latejoin antag is injected. -DYNAMIC_MIDROUND_DELAY_MIN 5 -DYNAMIC_MIDROUND_DELAY_MAX 15 -DYNAMIC_LATEJOIN_DELAY_MIN 10 -DYNAMIC_LATEJOIN_DELAY_MAX 30 - -DYNAMIC_FIRST_MIDROUND_DELAY_MIN 20 -DYNAMIC_FIRST_MIDROUND_DELAY_MAX 30 -DYNAMIC_FIRST_LATEJOIN_DELAY_MIN 2 -DYNAMIC_FIRST_LATEJOIN_DELAY_MAX 30 - -## How many roundstart players required for high population override to take effect. -DYNAMIC_HIGH_POP_LIMIT 80 #80 instead of 55 because fewer robust players - -## Threat requirements for a second roundstart ruleset being drafted -DYNAMIC_SECOND_RULE_REQUIREMENTS 101 101 101 101 100 90 80 70 60 50 -## Threat requirements for a *third* roundstart ruleset being drafted -DYNAMIC_THIRD_RULE_REQUIREMENTS 101 101 101 101 101 100 90 80 70 60 -## As above, but if there's 79+ players -DYNAMIC_SECOND_RULE_HIGH_POP_REQUIREMENT 50 -DYNAMIC_THIRD_RULE_HIGH_POP_REQUIREMENT 60 - -## Pop range per requirement. -## If the value is five the range is: -## 0-4, 5-9, 10-14, 15-19, 20-24, 25-29, 30-34, 35-39, 40-54, 45+ -## If it is six the range is: -## 0-5, 6-11, 12-17, 18-23, 24-29, 30-35, 36-41, 42-47, 48-53, 54+ -## If it is seven the range is: -## 0-6, 7-13, 14-20, 21-27, 28-34, 35-41, 42-48, 49-55, 56-62, 63+ -## Options outside this range can be used, of course. -DYNAMIC_POP_PER_REQUIREMENT 9 # 9 instead of 6 because 1/3 of players are probably not doing much? - -## 1 -> 9, probability for this rule to be picked against other rules. -## Note that requirements must also be met, and some requirements are impossible to meet. -DYNAMIC_WEIGHT TRAITOR 5 -DYNAMIC_WEIGHT MALF_AI 1 -DYNAMIC_WEIGHT TRAITORBRO 4 -DYNAMIC_WEIGHT CHANGELING 1 -DYNAMIC_WEIGHT WIZARD 1 -DYNAMIC_WEIGHT CULT 3 -DYNAMIC_WEIGHT NUCLEAR 3 -DYNAMIC_WEIGHT REVOLUTION 2 -DYNAMIC_WEIGHT BLOODSUCKER 4 -# All below are impossible-by-default -DYNAMIC_WEIGHT EXTENDED 3 -DYNAMIC_WEIGHT CLOCKWORK_CULT 3 -DYNAMIC_WEIGHT CLOWNOPS 3 -DYNAMIC_WEIGHT DEVIL 3 -DYNAMIC_WEIGHT MONKEY 3 -DYNAMIC_WEIGHT METEOR 3 - -## Midround antags -DYNAMIC_WEIGHT MIDROUND_TRAITOR 9 -DYNAMIC_WEIGHT MIDROUND_MALF_AI 5 -DYNAMIC_WEIGHT MIDROUND_WIZARD 4 -DYNAMIC_WEIGHT MIDROUND_NUCLEAR 2 -DYNAMIC_WEIGHT BLOB 2 -DYNAMIC_WEIGHT XENOS 2 -DYNAMIC_WEIGHT NIGHTMARE 3 -DYNAMIC_WEIGHT SENTIENT_DISEASE 4 -DYNAMIC_WEIGHT REVENANT 2 -DYNAMIC_WEIGHT SLAUGHTER_DEMON 1 -DYNAMIC_WEIGHT ABDUCTORS 3 -DYNAMIC_WEIGHT SPACE_NINJA 3 - -## Events -DYNAMIC_WEIGHT SPIDERS 5 -DYNAMIC_WEIGHT VENTCLOG_NORMAL 3 -DYNAMIC_WEIGHT VENTCLOG_THREATENING 3 -DYNAMIC_WEIGHT VENTCLOG_CATASTROPHIC 3 -DYNAMIC_WEIGHT ION_STORM 7 -DYNAMIC_WEIGHT METEOR_WAVE_NORMAL 3 -DYNAMIC_WEIGHT METEOR_WAVE_THREATENING 2 -DYNAMIC_WEIGHT METEOR_WAVE_CATASTROPHIC 1 -DYNAMIC_WEIGHT PIRATES 8 -DYNAMIC_WEIGHT ANOMALY_BLUESPACE 2 -DYNAMIC_WEIGHT ANOMALY_FLUX 2 -DYNAMIC_WEIGHT ANOMALY_GRAVITATIONAL 2 -DYNAMIC_WEIGHT ANOMALY_PYROCLASTIC 2 -DYNAMIC_WEIGHT ANOMALY_VORTEX 2 -DYNAMIC_WEIGHT BRAND_INTELLIGENCE 1 -DYNAMIC_WEIGHT CARP_MIGRATION 7 -DYNAMIC_WEIGHT COMMUNICATIONS_BLACKOUT 2 -DYNAMIC_WEIGHT PROCESSOR_OVERLOAD 2 -DYNAMIC_WEIGHT SPACE_DUST 2 -DYNAMIC_WEIGHT MAJOR_DUST 1 -DYNAMIC_WEIGHT ELECTRICAL_STORM 2 -DYNAMIC_WEIGHT HEART_ATTACK 2 -DYNAMIC_WEIGHT RADIATION_STORM 1 - -## Latejoin antags -DYNAMIC_WEIGHT LATEJOIN_TRAITOR 7 -DYNAMIC_WEIGHT LATEJOIN_REVOLUTION 2 -DYNAMIC_WEIGHT LATEJOIN_BLOODSUCKER 4 -DYNAMIC_WEIGHT LATEJOIN_COLLECTOR 5 - -## Threat cost. This is decreased from the mode's threat when the rule is executed. -DYNAMIC_COST TRAITOR 10 -DYNAMIC_COST MALF_AI 35 -DYNAMIC_COST TRAITORBRO 10 -DYNAMIC_COST CHANGELING 30 -DYNAMIC_COST WIZARD 30 -DYNAMIC_COST CULT 35 -DYNAMIC_COST NUCLEAR 45 -DYNAMIC_COST REVOLUTION 40 -DYNAMIC_cOST BLOODSUCKER 15 -DYNAMIC_COST EXTENDED 0 -DYNAMIC_COST CLOCKWORK_CULT 35 -DYNAMIC_COST CLOWNOPS 40 -DYNAMIC_COST DEVIL 0 -DYNAMIC_COST MONKEY 0 -DYNAMIC_COST METEOR 0 - -## Midround antags -DYNAMIC_COST MIDROUND_TRAITOR 10 -DYNAMIC_COST MIDROUND_MALF_AI 35 -DYNAMIC_COST MIDROUND_WIZARD 20 -DYNAMIC_COST MIDROUND_NUCLEAR 35 -DYNAMIC_COST BLOB 10 -DYNAMIC_COST XENOS 20 -DYNAMIC_COST NIGHTMARE 10 -DYNAMIC_COST SENTIENT_DISEASE 5 -DYNAMIC_COST REVENANT 5 -DYNAMIC_COST SLAUGHTER_DEMON 15 -DYNAMIC_COST ABDUCTORS 10 -DYNAMIC_COST SPACE_NINJA 15 - -## Events -DYNAMIC_COST SPIDERS 10 -DYNAMIC_COST VENTCLOG_NORMAL 2 -DYNAMIC_COST VENTCLOG_THREATENING 5 -DYNAMIC_COST VENTCLOG_CATASTROPHIC 15 -DYNAMIC_COST ION_STORM 3 -DYNAMIC_COST METEOR_WAVE_NORMAL 15 -DYNAMIC_COST METEOR_WAVE_THREATENING 25 -DYNAMIC_COST METEOR_WAVE_CATASTROPHIC 40 -DYNAMIC_COST PIRATES 10 -DYNAMIC_COST ANOMALY_BLUESPACE 3 -DYNAMIC_COST ANOMALY_FLUX 2 -DYNAMIC_COST ANOMALY_GRAVITATIONAL 3 -DYNAMIC_COST ANOMALY_PYROCLASTIC 5 -DYNAMIC_COST ANOMALY_VORTEX 5 -DYNAMIC_COST BRAND_INTELLIGENCE 5 -DYNAMIC_COST CARP_MIGRATION 3 -DYNAMIC_COST COMMUNICATIONS_BLACKOUT 5 -DYNAMIC_COST PROCESSOR_OVERLOAD 5 -DYNAMIC_COST SPACE_DUST 2 -DYNAMIC_COST MAJOR_DUST 4 -DYNAMIC_COST ELECTRICAL_STORM 1 -DYNAMIC_COST HEART_ATTACK 1 -DYNAMIC_COST RADIATION_STORM 3 - -## Latejoin antags -DYNAMIC_COST LATEJOIN_TRAITOR 5 -DYNAMIC_COST LATEJOIN_REVOLUTION 20 -DYNAMIC_COST LATEJOIN_BLOODSUCKER 10 -DYNAMIC_COST LATEJOIN_COLLECTOR 1 - -## Rule will not be generated with threat levels below requirement at a pop value. Pop values are determined by dynamic's pop-per-requirement. -## By default it's 0-8, 9-17, 18-26, 27-35, 36-44, 45-53, 54-60, 61-69, 70-78, 79+. -## This means that 40 30 30 20 20 20 15 15 15 10 will not generate below 40 at 0-8, 30 at 9-17 etc. -DYNAMIC_REQUIREMENTS TRAITOR 50 50 50 50 50 50 50 50 50 50 -DYNAMIC_REQUIREMENTS TRAITORBRO 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS CHANGELING 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS WIZARD 101 101 60 60 50 50 50 50 50 50 -DYNAMIC_REQUIREMENTS CULT 101 101 101 60 50 50 50 50 50 50 -DYNAMIC_REQUIREMENTS NUCLEAR 101 101 101 60 50 50 50 50 50 50 -DYNAMIC_REQUIREMENTS REVOLUTION 101 101 101 60 50 50 50 50 50 50 -DYNAMIC_REQUIREMENTS EXTENDED 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS CLOCKWORK_CULT 101 101 101 70 60 60 50 50 50 50 -DYNAMIC_REQUIREMENTS CLOWNOPS 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS DEVIL 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS MONKEY 101 101 101 101 101 101 101 101 101 101 -DYNAMIC_REQUIREMENTS METEOR 101 101 101 101 101 101 101 101 101 101 - -## Midround antags -DYNAMIC_REQUIREMENTS MIDROUND_TRAITOR 30 25 20 15 15 15 15 15 15 15 -DYNAMIC_REQUIREMENTS MIDROUND_MALF_AI 101 101 70 50 50 50 40 30 30 30 -DYNAMIC_REQUIREMENTS MIDROUND_WIZARD 90 90 60 40 30 30 30 30 30 30 -DYNAMIC_REQUIREMENTS MIDROUND_NUCLEAR 90 90 90 80 70 60 50 40 40 40 -DYNAMIC_REQUIREMENTS BLOB 101 101 101 80 60 50 50 50 50 50 -DYNAMIC_REQUIREMENTS XENOS 101 101 101 70 50 50 50 50 50 50 -DYNAMIC_REQUIREMENTS NIGHTMARE 101 101 101 70 50 40 20 15 15 15 -DYNAMIC_REQUIREMENTS SENTIENT_DISEASE 30 30 20 20 15 10 10 10 10 5 -DYNAMIC_REQUIREMENTS REVENANT 30 30 30 30 20 15 15 15 15 15 -DYNAMIC_REQUIREMENTS SLAUGHTER_DEMON 101 101 101 90 80 70 60 50 50 50 -DYNAMIC_REQUIREMENTS ABDUCTORS 80 80 70 50 40 30 30 20 15 15 -DYNAMIC_REQUIREMENTS SPACE_NINJA 101 101 101 90 80 70 60 50 40 30 - -## Events -DYNAMIC_REQUIREMENTS SPIDERS 70 60 50 50 40 40 40 30 20 15 -DYNAMIC_REQUIREMENTS VENTCLOG 5 5 5 5 5 5 5 5 5 5 -DYNAMIC_REQUIREMENTS ION_STORM 5 5 5 5 5 5 5 5 5 5 -DYNAMIC_REQUIREMENTS METEOR_WAVE 60 50 40 30 30 30 30 30 30 30 -DYNAMIC_REQUIREMENTS PIRATES 70 60 50 50 40 40 40 30 20 15 -DYNAMIC_REQUIREMENTS ANOMALY_BLUESPACE 5 5 5 5 5 5 5 5 5 5 -DYNAMIC_REQUIREMENTS ANOMALY_FLUX 5 5 5 5 5 5 5 5 5 5 -DYNAMIC_REQUIREMENTS ANOMALY_GRAVITATIONAL 5 5 5 5 5 5 5 5 5 5 -DYNAMIC_REQUIREMENTS ANOMALY_PYROCLASTIC 10 10 10 10 10 10 10 10 10 10 -DYNAMIC_REQUIREMENTS ANOMALY_VORTEX 10 10 10 10 10 10 10 10 10 10 -DYNAMIC_REQUIREMENTS BRAND_INTELLIGENCE 10 10 10 10 10 10 10 10 10 10 -DYNAMIC_REQUIREMENTS CARP_MIGRATION 10 10 10 10 10 10 10 10 10 10 -DYNAMIC_REQUIREMENTS COMMUNICATIONS_BLACKOUT 5 5 5 5 5 5 5 5 5 5 -DYNAMIC_REQUIREMENTS PROCESSOR_OVERLOAD 5 5 5 5 5 5 5 5 5 5 -DYNAMIC_REQUIREMENTS SPACE_DUST 5 5 5 5 5 5 5 5 5 5 -DYNAMIC_REQUIREMENTS MAJOR_DUST 10 10 10 10 10 10 10 10 10 10 -DYNAMIC_REQUIREMENTS ELECTRICAL_STORM 5 5 5 5 5 5 5 5 5 5 -DYNAMIC_REQUIREMENTS HEART_ATTACK 5 5 5 5 5 5 5 5 5 5 -DYNAMIC_REQUIREMENTS RADIATION_STORM 5 5 5 5 5 5 5 5 5 5 - -## Latejoin antags -DYNAMIC_REQUIREMENTS LATEJOIN_TRAITOR 40 30 20 15 15 15 15 15 15 15 -DYNAMIC_REQUIREMENTS LATEJOIN_REVOLUTION 101 101 70 40 40 40 40 40 40 40 -DYNAMIC_REQUIREMENTS LATEJOIN_BLOODSUCKER 40 30 20 15 15 15 15 15 15 15 -DYNAMIC_REQUIREMENTS LATEJOIN_COLLECTOR 10 10 10 10 10 10 10 10 10 10 - -## An alternative, static requirement used instead when pop is over mode's high_pop_limit. -DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITOR 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT MALF_AI 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITORBRO 101 -DYNAMIC_HIGH_POPULATION_REQUIREMENT CHANGELING 101 -DYNAMIC_HIGH_POPULATION_REQUIREMENT WIZARD 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT CULT 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT NUCLEAR 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT REVOLUTION 50 -# All below are impossible-by-default -DYNAMIC_HIGH_POPULATION_REQUIREMENT EXTENDED 101 -DYNAMIC_HIGH_POPULATION_REQUIREMENT CLOCKWORK_CULT 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT CLOWNOPS 101 -DYNAMIC_HIGH_POPULATION_REQUIREMENT DEVIL 101 -DYNAMIC_HIGH_POPULATION_REQUIREMENT MONKEY 101 -DYNAMIC_HIGH_POPULATION_REQUIREMENT METEOR 101 - -## Midround antags -DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_TRAITOR 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_MALF_AI 35 -DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_WIZARD 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_NUCLEAR 35 -DYNAMIC_HIGH_POPULATION_REQUIREMENT BLOB 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT XENOS 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT NIGHTMARE 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT SENTIENT_DISEASE 5 -DYNAMIC_HIGH_POPULATION_REQUIREMENT REVENANT 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT SLAUGHTER_DEMON 30 -DYNAMIC_HIGH_POPULATION_REQUIREMENT ABDUCTORS 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT SPACE_NINJA 30 - -## Events -DYNAMIC_HIGH_POPULATION_REQUIREMENT SPIDERS 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT VENTCLOG 5 -DYNAMIC_HIGH_POPULATION_REQUIREMENT ION_STORM 5 -DYNAMIC_HIGH_POPULATION_REQUIREMENT METEOR_WAVE 30 -DYNAMIC_HIGH_POPULATION_REQUIREMENT PIRATES 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT ANOMALY_BLUESPACE 5 -DYNAMIC_HIGH_POPULATION_REQUIREMENT ANOMALY_FLUX 5 -DYNAMIC_HIGH_POPULATION_REQUIREMENT ANOMALY_GRAVITATIONAL 5 -DYNAMIC_HIGH_POPULATION_REQUIREMENT ANOMALY_PYROCLASTIC 10 -DYNAMIC_HIGH_POPULATION_REQUIREMENT ANOMALY_VORTEX 10 -DYNAMIC_HIGH_POPULATION_REQUIREMENT BRAND_INTELLIGENCE 10 -DYNAMIC_HIGH_POPULATION_REQUIREMENT CARP_MIGRATION 10 -DYNAMIC_HIGH_POPULATION_REQUIREMENT COMMUNICATIONS_BLACKOUT 5 -DYNAMIC_HIGH_POPULATION_REQUIREMENT PROCESSOR_OVERLOAD 5 -DYNAMIC_HIGH_POPULATION_REQUIREMENT SPACE_DUST 5 -DYNAMIC_HIGH_POPULATION_REQUIREMENT MAJOR_DUST 10 -DYNAMIC_HIGH_POPULATION_REQUIREMENT ELECTRICAL_STORM 5 -DYNAMIC_HIGH_POPULATION_REQUIREMENT HEART_ATTACK 5 -DYNAMIC_HIGH_POPULATION_REQUIREMENT RADIATION_STORM 5 - -## Latejoin antags -DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_TRAITOR 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_REVOLUTION 50 -DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_BLOODSUCKER 15 -DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_COLLECTOR 10 - -## Dynamic traitor stuff - -## Requirements for "hijack the shuttle" goals. -DYNAMIC_HIJACK_REQUIREMENTS 101 101 101 95 80 70 60 50 40 30 - -DYNAMIC_HIJACK_HIGH_POPULATION_REQUIREMENT 25 - -DYNAMIC_HIJACK_COST 10 - -DYNAMIC_GLORIOUS_DEATH_COST 5 - -DYNAMIC_ASSASSINATE_COST 2 - -## This requirement uses threat level, rather than current threat, which is why it's higher. -DYNAMIC_WAROPS_REQUIREMENT 60 - -DYNAMIC_WAROPS_COST 10 - -## Storyteller min players -# STORYTELLER_MIN_PLAYERS CHAOTIC 35 - -## Storyteller minimum chaos -# STORYTELLER_MIN_CHAOS CHAOTIC 75 - -## Storyteller maximum chaos -# STORYTELLER_MAX_CHAOS CHAOTIC 250 diff --git a/config/entries/fetish_content.txt b/config/entries/fetish_content.txt index 6fabd095d8..1bc9ebe968 100644 --- a/config/entries/fetish_content.txt +++ b/config/entries/fetish_content.txt @@ -12,6 +12,10 @@ BREASTS_CUPS_PREFS h PENIS_MIN_INCHES_PREFS 1 PENIS_MAX_INCHES_PREFS 24 +## Minimum and maximum limits for butt size from the character creation menu. If there's bigger butt sizes out there, change the max accordingly. +BUTT_MIN_SIZE_PREFS 1 +BUTT_MAX_SIZE_PREFS 5 + ## Body size configs, the feature will be disabled if both min and max have the same value. BODY_SIZE_MIN 0.9 BODY_SIZE_MAX 1.25 diff --git a/config/entries/gamemodes.txt b/config/entries/gamemodes.txt index f78c3743aa..7193bef584 100644 --- a/config/entries/gamemodes.txt +++ b/config/entries/gamemodes.txt @@ -51,6 +51,7 @@ CONTINUOUS WIZARD #CONTINUOUS MONKEY CONTINUOUS BLOODSUCKER CONTINUOUS HERESY +CONTINUOUS DYNAMIC ##Note: do not toggle continuous off for these modes, as they have no antagonists and would thus end immediately! diff --git a/config/entries/general.txt b/config/entries/general.txt index 3584af63c7..b118d65621 100644 --- a/config/entries/general.txt +++ b/config/entries/general.txt @@ -31,15 +31,6 @@ ALLOW_HOLIDAYS ## Uncomment to show the names of the admin sending a pm from IRC instead of showing as a stealthmin. #SHOW_IRC_NAME -## Chat Announce Options -## Various messages to be sent to game chats -## Uncommenting these will enable them, by default they will be broadcast to Game chat channels on TGS3 or non-admin channels on TGS4 -## If using TGS4, the string option can be set as a chat channel tag to limit the message to channels of that tag type (case-sensitive) -## i.e. CHAT_ANNOUNCE_NEW_GAME chat_channel_tag - -## Send a message with the station name starting a new game -#CHAT_ANNOUNCE_NEW_GAME - ##Default screen resolution, in tiles. ## By default, this is 15x15, which gets simplified to 7 by BYOND, as it is a 1:1 screen ratio. ## For reference, Goonstation uses a resolution of 21x15 for it's widescreen mode. @@ -465,6 +456,9 @@ ECONOMY #Replaces standard extended/secret dichotomy with extended and calm/chaotic votes for dynamic. #DYNAMIC_VOTING +## Uncomment to enable dynamic ruleset config file. +DYNAMIC_CONFIG_ENABLED + ## Choose which Engine to start the round with. Weight is after the comma. Setting the weight to 0 removes the engine from rotation. BOX_RANDOM_ENGINE Box SM,3 BOX_RANDOM_ENGINE Box Tesla,3 @@ -476,6 +470,7 @@ BOX_RANDOM_ENGINE Box TEG,3 BOX_RANDOM_ENGINE Box Empty,0 BOX_RANDOM_ENGINE Box Antimatter,1 BOX_RANDOM_ENGINE Box P.A.C.M.A.N,1 +BOX_RANDOM_ENGINE Box RBMK,3 ## Whether the suicide verb is allowed. @@ -491,3 +486,32 @@ ALLOW_CUSTOM_SKINTONES ## Allows pAI custom holoforms PAI_CUSTOM_HOLOFORMS + +## How long in seconds after which a hard delete is treated as causing lag. This can be a float and supports a precision as low as nanoseconds. +#HARD_DELETES_OVERRUN_THRESHOLD 0.5 + +## Once a typepath causes overrun from hard deletes this many times, stop hard deleting it on garbage collection failures. (set to 0 to disable) +#HARD_DELETES_OVERRUN_LIMIT 0 + +## Enables monstermos/"equalization" step in atmos. +# ATMOS_EQUALIZATION_ENABLED + +## Do station renames from the station charter require admin approval to pass, as opposed to autoapproving if not denied. +STATION_NAME_NEEDS_APPROVAL + +## Strings for the station trait "Randomizing station name" +RANDOMIZING_STATION_NAME_MESSAGE Due to internal affairs, the station is now named %NEW_STATION_NAME%. +RANDOMIZING_STATION_NAME_MESSAGE The solar system's government has formally requested that the station now be named %NEW_STATION_NAME%. +RANDOMIZING_STATION_NAME_MESSAGE A gorilla broke into the office and destroyed a bunch of paperwork. We don't know what your station's old name was. It's now %NEW_STATION_NAME%. +RANDOMIZING_STATION_NAME_MESSAGE An intern said %NEW_STATION_NAME% would be a cool name. That's your station's name now. +RANDOMIZING_STATION_NAME_MESSAGE Our predictive language model has renamed your station to %NEW_STATION_NAME%. +RANDOMIZING_STATION_NAME_MESSAGE It's %NEW_STATION_NAME% now. +RANDOMIZING_STATION_NAME_MESSAGE The CEO demanded that your station be named %NEW_STATION_NAME%. +RANDOMIZING_STATION_NAME_MESSAGE Our intern accidentally wiped the database, so your station needs a new name: %NEW_STATION_NAME%. +RANDOMIZING_STATION_NAME_MESSAGE Due to copyright infringement, the station is now temporarily renamed to %NEW_STATION_NAME%. +RANDOMIZING_STATION_NAME_MESSAGE Due to recent corporate acquisitions, the station has been rebranded to %NEW_STATION_NAME%. +RANDOMIZING_STATION_NAME_MESSAGE %NEW_STATION_NAME%. +RANDOMIZING_STATION_NAME_MESSAGE %NEW_STATION_NAME%? %NEW_STATION_NAME%! %NEW_STATION_NAME%!!!!!!!! +RANDOMIZING_STATION_NAME_MESSAGE A popular social network application had already claimed the trademark of %CURRENT_STATION_NAME%, the station has been renamed to %NEW_STATION_NAME%. +RANDOMIZING_STATION_NAME_MESSAGE We're pulling a prank on %RANDOM_CREWMEMBER%, so we've changed the station's name to %NEW_STATION_NAME%. +RANDOMIZING_STATION_NAME_MESSAGE %RANDOM_NAME% made us change the station name, which is now %NEW_STATION_NAME%. diff --git a/config/entries/logging.txt b/config/entries/logging.txt index 1690dbfacf..8da1ac4474 100644 --- a/config/entries/logging.txt +++ b/config/entries/logging.txt @@ -13,9 +13,15 @@ LOG_SAY ## log client access (logon/logoff) LOG_ACCESS +## Enables log entries for logins that failed due to suspicious circumstances (banned player, CID randomiser, spoofed BYOND version, etc.) to a dedicated file. +LOG_SUSPICIOUS_LOGIN + ## log game actions (start of round, results, etc.) LOG_GAME +## log mecha actions +LOG_MECHA + ## log player votes LOG_VOTE @@ -31,6 +37,9 @@ LOG_EMOTE ## log attack messages LOG_ATTACK +## log victim messages +LOG_VICTIM + ## log pda messages LOG_PDA @@ -52,11 +61,14 @@ LOG_JOB_DEBUG ## Log shuttle related actions LOG_SHUTTLE +## Log economy-related actions +LOG_ECON + ## log all world.Topic() calls LOG_WORLD_TOPIC ## enables use of the proc twitterize() that lets you take a large list of strings and turn it into a JSON file of tweet sized strings. -## As an example of how this could be """useful""" look towards Poly (https://twitter.com/Poly_the_Parrot) +## As an example of how this could be """useful""" look towards Polly (https://twitter.com/Poly_the_Parrot) # LOG_TWITTER ## Enable logging pictures diff --git a/config/entries/server.txt b/config/entries/server.txt index 0ffd5b21a3..0187c641ef 100644 --- a/config/entries/server.txt +++ b/config/entries/server.txt @@ -4,9 +4,19 @@ ## Server name: This appears at the top of the screen in-game and in the BYOND hub. Uncomment and replace 'tgstation' with the name of your choice. # SERVERNAME tgstation +## Community short-name: This appears in parentheses after the server's active station name +# COMMUNITYSHORTNAME tg??? + +## Community link: Requires a community short-name defined. Attaches a link to the community's shortname, and requires a short-name defined. +## You could alternatively just add raw HTML to the above, but this is more newbie-friendly +# COMMUNITYLINK http://crouton.net + ## Server tagline: This will appear right below the server's title. # SERVERTAGLINE A generic TG-based server +## Use tagline strings: Uncomment to have the server's tagline be randomly selected from taglines.txt +# USETAGLINESTRINGS + ## Server SQL name: This is the name used to identify the server to the SQL DB, distinct from SERVERNAME as it must be at most 32 characters. # SERVERSQLNAME tgstation @@ -66,3 +76,9 @@ DISABLE_HIGH_POP_MC_MODE_AMOUNT 60 ## Uncomment to set the number of /world/Reboot()s before the DreamDaemon restarts itself. 0 means restart every round. Requires tgstation server tools. #ROUNDS_UNTIL_HARD_RESTART 10 + +## Force Gamemode ## +## Disallows roundstart gamemode voting if not null or uncommented +## Just input the gamemode lowercase in there, the thing will take a simple string for it +## Invalid gamemodes will default extended, have fun. +#FORCE_GAMEMODE diff --git a/config/jobs.txt b/config/jobs.txt index 1bf271763b..fab38e70f6 100644 --- a/config/jobs.txt +++ b/config/jobs.txt @@ -11,6 +11,8 @@ Chief Medical Officer=1,1 Assistant=-1,-1 +Prisoner=0,2 + Quartermaster=1,1 Cargo Technician=3,2 Shaft Miner=3,3 diff --git a/config/maps.txt b/config/maps.txt index a90fea7595..90fe7b0387 100644 --- a/config/maps.txt +++ b/config/maps.txt @@ -43,6 +43,14 @@ endmap map runtimestation endmap +map spookystation + minplayers 150 +endmap + +map festivestation + minplayers 150 +endmap + map multiz_debug endmap diff --git a/config/server_taglines.txt b/config/server_taglines.txt new file mode 100644 index 0000000000..53da7c8fa3 --- /dev/null +++ b/config/server_taglines.txt @@ -0,0 +1 @@ +Fill in your own community quotes and memery here! diff --git a/config/spaceRuinBlacklist.txt b/config/spaceRuinBlacklist.txt index 969e4135f6..c62408b90c 100644 --- a/config/spaceRuinBlacklist.txt +++ b/config/spaceRuinBlacklist.txt @@ -53,3 +53,4 @@ #_maps/RandomRuins/SpaceRuins/spacehermit.dmm #_maps/RandomRuins/SpaceRuins/advancedlab.dmm #_maps/RandomRuins/SpaceRuins/spacediner.dmm +#_maps/RandomRuins/SpaceRuins/skelter.dmm diff --git a/dependencies.sh b/dependencies.sh index cdbdcd98df..1c15ed0a99 100644 --- a/dependencies.sh +++ b/dependencies.sh @@ -8,20 +8,20 @@ export BYOND_MAJOR=514 export BYOND_MINOR=1556 #rust_g git tag -export RUST_G_VERSION=0.4.8 - -#auxmos git tag -export AUXMOS_VERSION=v0.2.3 +export RUST_G_VERSION=0.4.10 #node version export NODE_VERSION=12 -export NODE_VERSION_PRECISE=12.20.0 +export NODE_VERSION_PRECISE=12.22.4 # SpacemanDMM git tag -export SPACEMAN_DMM_VERSION=suite-1.6 +export SPACEMAN_DMM_VERSION=suite-1.7 + +# Python version for mapmerge and other tools +export PYTHON_VERSION=3.7.9 + +# Auxmos git tag +export AUXMOS_VERSION=v2.4.1 # Extools git tag export EXTOOLS_VERSION=v0.0.7 - -# Python version for mapmerge and other tools -export PYTHON_VERSION=3.6.8 diff --git a/goon/icons/obj/chairs.dmi b/goon/icons/obj/chairs.dmi deleted file mode 100644 index 462370ac37..0000000000 Binary files a/goon/icons/obj/chairs.dmi and /dev/null differ diff --git a/goon/icons/obj/fitness.dmi b/goon/icons/obj/fitness.dmi deleted file mode 100644 index e2675cbda4..0000000000 Binary files a/goon/icons/obj/fitness.dmi and /dev/null differ diff --git a/goon/icons/obj/power.dmi b/goon/icons/obj/power.dmi index bb787c0b3c..d2a623bf6c 100644 Binary files a/goon/icons/obj/power.dmi and b/goon/icons/obj/power.dmi differ diff --git a/goon/sound/effects/spring.ogg b/goon/sound/effects/spring.ogg deleted file mode 100644 index 472a75e304..0000000000 Binary files a/goon/sound/effects/spring.ogg and /dev/null differ diff --git a/html/88x31.png b/html/88x31.png deleted file mode 100644 index 0f2a0f1072..0000000000 Binary files a/html/88x31.png and /dev/null differ diff --git a/html/archivedchangelog.html b/html/archivedchangelog.html deleted file mode 100644 index b586ae9d51..0000000000 --- a/html/archivedchangelog.html +++ /dev/null @@ -1,9051 +0,0 @@ - -

    01 April 2015

    -

    ACCount updated:

    -
      -
    • You can now replace test range firing pins with any other pin.
    • -
    • The plasma cutter is now a gun that comes in the mining vending machine. Use it to mine fast but expensively.
    • -
    • It's also cheaper in RnD, and there's an advanced version of it there too. Yay!
    • -
    • Ripleys and Firefighters have been buffed significantly. Go wild.
    • -
    • Precious mesons are cheaper in RnD.
    • -
    • Now you can mine bluespace crystals. They are extremely rare.
    • -
    • You can make remote bombs out of gibtonite. Figure out how.
    • -
    • Gibtonite is a bit less stable. Do not hit it with anything heavy.
    • -
    -

    Fayrik updated:

    -
      -
    • Added a bowman headset for death squads and ERTs.
    • -
    • Deathsquad radio channel is now called the Centcom radio channel.
    • -
    • Fixed the admin buttons not spawning ERT Medic gear properly.
    • -
    • Expanded Emergency Shuttle dock to allow for more round end griff.
    • -
    • All 7 ERT members now spawn geared, not just the first 4.
    • -
    • Spawning an ERT or Deathsquad no longer stops a second ERT or Deathsquad from being spawned.
    • -
    • Pulse rifles now have 80 shots, not 40.
    • -
    • Deathsquads now use loyalty pinned Pulse rifles.
    • -
    -

    Gun Hog updated:

    -
      -
    • NTSL has been updated! It can now read and modify verbs (says, yells, asks)! You can set your own using $say, $yell, $ask, and $exclaim variables in your scripts.
    • -
    • NTSL can now also modify the font, italics, and bolding of radio messages in four ways! In a script, place $loud, $wacky, $emphasis, and/or $robot in a vector to $filters.
    • -
    -

    Jordie0608 updated:

    -
      -
    • The admin's old player panel has been removed and the new one has taken it's name.
    • -
    -

    NikNakFlak updated:

    -
      -
    • Adds the ability to shave corgis.
    • -
    -

    Sawu updated:

    -
      -
    • Spraycans for Revheads: instant use crayons that can be used on walls.
    • -
    • Spraycans can be used as ghetto pepper spray and leave their target with colored faces that can be removed with space cleaner.
    • -
    -

    Xhuis updated:

    -
      -
    • Area ambience and ship ambience are now separate toggles. If you want one type of ambience but not the other, you only need to switch off the type you don't want.
    • -
    • Added cigar cases. They come in three flavors and can be bought from cigarette machines.
    • -
    - -

    30 March 2015

    -

    AnturK updated:

    -
      -
    • Added new wizard spell : Lightning Bolt
    • -
    -

    Dannno updated:

    -
      -
    • Added a hammer and gavel. Court is now in session.
    • -
    -

    Iamgoofball updated:

    -
      -
    • You can now *flip.
    • -
    • Objects now spin when thrown. Please report any oddities.
    • -
    -

    RemieRichards updated:

    -
      -
    • Monkeys can now wear ANY mask, not just ones they had specific icons for.
    • -
    • Monkeys can now wear HATS, That's right, Monkey Hats!
    • -
    -

    Szunti updated:

    -
      -
    • Mining mobs vision adapted to darkness of the asteroids.
    • -
    -

    phil235 updated:

    -
      -
    • All slimes are now simple animals instead of carbon life forms.
    • -
    • Remove crit status from brain and slimes.
    • -
    • Simple animal aliens can now see in the dark like regular aliens.
    • -
    -

    pudl updated:

    -
      -
    • The detective's forensic scanner has been resprited.
    • -
    • So has the cargo tagger.
    • -
    • And the RPED.
    • -
    -

    tedward1337 updated:

    -
      -
    • Admins now have a button to use Bluespace Artillery at their will.
    • -
    -

    xxalpha updated:

    -
      -
    • You will no longer be slowed down by anything if you use a jetpack in zero gravity.
    • -
    • Engineering hardsuits come with an inbuilt jetpack. Requires an internals tank in suit storage and is slower than a normal jetpack.
    • -
    - -

    25 March 2015

    -

    AnturK updated:

    -
      -
    • Added an arrow graffiti, made arrow and body graffiti face the same way as the user
    • -
    • New changeling ability : Last Resort : Explode and infect corpses if the situation looks grim
    • -
    -

    Fayrik updated:

    -
      -
    • Deleted the toy crossbow that wasn't a gun, but flung projectiles like a gun. Why was that even a thing?
    • -
    • Added an abstract new type of reusable ammo.
    • -
    • Added three new foam force guns and a foam force crossbow, all of which take the new foam dart ammo.
    • -
    • Added foam force dart boxes to the autolathe, and two crates orderable from cargo containing the new guns.
    • -
    • Added two new donksoft guns, the syndicate's own brand of Foam Force. Available in all good uplinks!
    • -
    • New crossbow can be won as an arcade prize.
    • -
    • All kinds of ammo containers can now be used to rapidly collect live ammunition on the ground.
    • -
    • Speedloaders and traditional ammo boxes can now be restocked.
    • -
    • Security bots now react to being shot.
    • -
    -

    MrPerson updated:

    -
      -
    • Added a preference toggle for hearing instruments play as suggested by PKPenguin321.
    • -
    -

    Pennwick updated:

    -
      -
    • Added a buildable Chem Master, board is in Circuit Imprinter.
    • -
    -

    Wjohnston updated:

    -
      -
    • Finally fixed the gulag shuttle missing a redemption console.
    • -
    - -

    24 March 2015

    -

    Cheridan updated:

    -
      -
    • Adds pet collars. Use them to rename pets; Can also be worn if you're a weirdo.
    • -
    • Adds the matyr objective to be dead at the round's end. You can get this objective if you have no others that would need you to survive.
    • -
    -

    Dannno updated:

    -
      -
    • GAR glasses return. Yes, I got permission. Just who the hell do you think I am?
    • -
    -

    Incoming5643 updated:

    -
      -
    • Summon Events has been reworked to be a bit less manic.
    • -
    • Summon Events will turn off if the wizard and all apprentices die. Any lingering effects are not reversed however.
    • -
    • Improving Summon Events will reduce the average time between events, but not the minimum time between events.
    • -
    • Departmental Uprising has been made admin only for being an RP heavy event that creates antags in an enviroment that doesn't really support that.
    • -
    -

    Mandurrrh updated:

    -
      -
    • Added a cyborg upgrade module for the satchel of holding.
    • -
    -

    Miauw updated:

    -
      -
    • Added a fancy white dress and a jester outfit. Sprites by Nienhaus.
    • -
    -

    Steelpoint, RemieRichards, and Gun Hog updated:

    -
      -
    • Nanotrasen Security has authorized modifications to the standard issue helmets for officers. These helmets are now issued with a mounted camera, automatically synced to your assigned station's camera network. In addition, the helmets also include mounting points for the Seclite model of flashlights, found in your station's security vendors.
    • -
    • Nanotrasen Security helmets are designed for easy repairs in the field. Officers may remove their Seclite attachment with any screwdriver, and the camera's assembly may be pried off with a crowbar. The assembly is also compatible with analyzer upgrades for scanning through the station's structure, and EMP shielding is possible by applying a sheet of plasma.
    • -
    - -

    22 March 2015

    -

    Iamgoofball updated:

    -
      -
    • Fixes Morphine not knocking you out.
    • -
    • Hotline no longer exists. Poppies now have Saline-Glucose Solution.
    • -
    • Muriatic Acid, Caustic Soda, and Hydrogen Chloride have been removed, along with the secondary meth recipe. The original recipe still works.
    • -
    • Foam now produces more bang for your buck when mixed. Your foam grenades should be larger now to account for the slowdown.
    • -
    • Adds Stabilizing Agent. This chemical will prevent the effects of certain reactions from taking place in the container it is in, such as Smoke Powder and Flash Powder, allowing you to get the raw forms of the powders for heating up later.
    • -
    • Smoke Powder and Flash Powder can now be mixed along with Stabilizing Agent in order to produce a powder version of the effects. You can then heat these powders to 374K to get the effects.
    • -
    • Mixing them without Stabilizing Agent gives the default effects.
    • -
    • Adds Sonic Powder, a chemical that deafens and stuns within 5 tiles of the reaction. It also follows the reaction rules of the other 2 powders.
    • -
    • Liquid Dark Matter and Sorium also now work like the powders do.
    • -
    • CLF3 now has a higher chance of making plating tiles, and the burn damage caused by it scales based on your fire stacks.
    • -
    • Adds Pyrosium. This reagent heats up mobs by 30 degrees every 3 seconds if it has oxygen to react with. Useful for when you want a delayed mix inside of someone.
    • -
    • Adds Cryostylane. This reagent does the opposite of Pyrosium, but it still requires oxygen to react with.
    • -
    • Adds Phlogiston. This reagent ignites you and gives you a single fire stack every 3 seconds. Burn damage from this chemical scales up with the fire stacks you have. Counter this with literally any chemical that purges other chems.
    • -
    • Smoke now transfers reagents to the mob, and applies touch reactions on them. This means smoke can run out of reagents, no more infinite acid smoke. It also only works on mobs, use the new Reagent Foam(tm) for your hellfoam needs. I suggest a CLF3 Fluoroacid Black Powder mix.
    • -
    • Added a derelict medibot to the code, will place a few on the derelict when this PR is merged as to prevent mapping conflicts.
    • -
    • Adds Initropidril. 33% chance to hit with 5-25 TOX damage every 3 seconds, and a 5-10% chance to either stun, cause lots of oxygen damage, or cause your heart to stop. Get it from the traitor Poison Kit.
    • -
    • Adds Pancuronium. Paralyses you after 30 seconds, with a 7% chance to cause 3-5 loss of breath. Get it from the traitor Poison Kit.
    • -
    • Adds Sodium Thiopental. Knocks you out after 30 seconds, and destroys your stamina. Get it from the traitor Poison Kit.
    • -
    • Adds Sulfonal. +1 TOX per 3 seconds, knocks you out in 66 seconds. Mix it with Acetone, Diethylamine, and Sulfur.
    • -
    • Adds Amantin. On the last second it is in you, it hits you with a stack of TOX damage based on how long it's been in you. Get it from the traitor Poison Kit.
    • -
    • Adds Lipolicide. +1 TOX unless you have nutriment in you. Mix it with Mercury, Diethylamine, and Ephedrine.
    • -
    • Adds Coiine. +2 TOX and +5 loss of breath every 3 seconds. Get it from the traitor Poison Kit.
    • -
    • Adds Curare. +1 TOX, +1 OXY, paralyzes after 33 seconds. Get it from the traitor Poison Kit.
    • -
    • Adds a reagent_deleted() proc to reagents for effects upon the last time it processes in you, like with Amantin.
    • -
    • Neurotoxin required temperature for mixing has been set to 674K, it was 370K for some reason.
    • -
    -

    xxalpha updated:

    -
      -
    • Added Cybernetic Implants: Security HUD, Medical HUD, X-Ray, Thermals, Anti-Drop, Anti-Stun. All implants are researchable and producible by R&D and Robotics.
    • -
    - -

    21 March 2015

    -

    Chocobro updated:

    -
      -
    • Checkered skirts can be adjusted to be worn shorter.
    • -
    -

    Incoming5643 updated:

    -
      -
    • Player controller uplifted mobs will be attacked by gold core mobs of different species.
    • -
    -

    Jordie0608 updated:

    -
      -
    • The backup shuttle will no longer be called if the emergency shuttle is coming.
    • -
    -

    MMMiracles updated:

    -
      -
    • Adds 3 new bear-based foods.
    • -
    • Beary Pie -1 Plain Pie, 1 berry, 1 bear steak
    • -
    • Filet Migrawr - 5u of Manlydorf, 1 bear steak, 1 lighter(not used in crafting)
    • -
    • Bearger - 1 bun, 1 bear steak
    • -
    -

    Phil235 updated:

    -
      -
    • Silicons are no longer blinded by welding.
    • -
    -

    Xhuis updated:

    -
      -
    • A new software update has given the Orion Trail game a cheat code menu. While you can't access this normally (that's for a later software update), maybe an emag could do it...?
    • -
    -

    Zelacks updated:

    -
      -
    • The chemical implant action button should now correctly inject all chemicals when pressed.
    • -
    -

    pudl updated:

    -
      -
    • Adds normal security headsets to security lockers.
    • -
    -

    xxalpha updated:

    -
      -
    • Fixed cables on catwalks being destroyed when creating plating floor.
    • -
    • Portable machines can be mounted on any turf that could hold a cable.
    • -
    - -

    19 March 2015

    -

    Dannno updated:

    -
      -
    • Adds a few cosmetic glasses to the autodrobe and clothing vendors.
    • -
    -

    Gun Hog updated:

    -
      -
    • Explosion relics will now destroy themselves in their own explosion.
    • -
    • The Experimentor can no longer re-roll the function of an already scanned relic.
    • -
    -

    Incoming5643 updated:

    -
      -
    • Ghosts are now asked if they want to become a sentient slime.
    • -
    -

    JJRcop updated:

    -
      -
    • Adds the :rollie: and :ambrosia: emojis.
    • -
    -

    MMMiracles updated:

    -
      -
    • ERT suits now use helmet toggling like hardsuits.
    • -
    -

    Menshin updated:

    -
      -
    • Fixed mechs ballistic guns not firing bullets.
    • -
    -

    Xhuis updated:

    -
      -
    • Allows alt-clicking to adjust breath masks, flip caps, and unlock/lock closets.
    • -
    -

    xxalpha updated:

    -
      -
    • Fixed jetpack trail animation.
    • -
    - -

    17 March 2015

    -

    CandyClownTG updated:

    -
      -
    • Syndicate cigarettes' non-healing Doctor's Delight replaced with Omnizine.
    • -
    -

    Fayrik updated:

    -
      -
    • Expanded the Centcom area for better station-Centcom interaction.
    • -
    -

    Iamgoofball updated:

    -
      -
    • Acid blobs are less likely to melt equipment.
    • -
    -

    MMMiracles updated:

    -
      -
    • Adds the ability to spike bears on a meatspike for their pelt. Yields 5 meat instead of the usual 3 from a knife.
    • -
    -

    Thunder12345 updated:

    -
      -
    • Two new shotgun shells. Ion shell, shotgun version of ion rifle, built with 1 x techshell, 1 x ultra microlaser, 1 x ansible crystal.
    • -
    • Laser slug, regular laser shot in a shotgun shell, build with 1 x techshell, 1 x high power microlaser, 1 x advanced capacitor.
    • -
    • Improvised shotgun shells can now be constructed with 1 x grenade casing, 1 x metal sheet, 1 x cable, 10 units welding fuel. Can be packed with a further 5 units of gunpowder to turn it into a potentially lethal diceroll.
    • -
    • FRAG-12 shotgun shells are no longer duds, now explosive.
    • -
    -

    phil235 updated:

    -
      -
    • Makes the message when you're attacked slightly bigger for better visibility.
    • -
    - -

    15 March 2015

    -

    Ahammer18 updated:

    -
      -
    • Adds ass photocopying for drones
    • -
    -

    Gun Hog updated:

    -
      -
    • Nanotrasen has approved distribution of Loyalty Implant Firing Pin designs. They can be fabricated with sufficient research into weapons technology. If inserted into a firearm, it will only fire upon successful interface with a user's Loyalty Implant.
    • -
    -

    Incoming5643 updated:

    -
      -
    • Utilizing a new magic mirror found in the den, wizards can now customize their appearance to a high degree before descending upon the station.
    • -
    -

    Miauw updated:

    -
      -
    • Firing delay for tasers has been shortened.
    • -
    -

    RemieRichards updated:

    -
      -
    • Beginning major rework and refactor of messy Ninja code.
    • -
    • Roleplay based, kill deathsquad and kill alien queen objectives removed.
    • -
    • Kamikaze mode removed.
    • -
    • AIs and pAIs can no longer be integrated into a ninja suit.
    • -
    • Energy blade power replaced by an energy katana that can be dropped but is more deadly.
    • -
    • Energy katana can emag any object it hits.
    • -
    -

    phil235 updated:

    -
      -
    • Bookbags have a new sprite and can hold bibles.
    • -
    • Adds egg yolk reagent. You can break eggs in open reagent containers or blend them to get egg yolk.
    • -
    • Changes how doughs are made. 10water+15flour chem reaction for dough. 15flour+15eggyolk+5sugar for cake batter (or alternatively soymilk instead of the eggyolk for vegans).
    • -
    • Change customizable snack max volume to 60 and buffs nutriment amount in doughs.
    • -
    • Doors can damage mechs by crushing them now.
    • -
    • The tablecrafting window now also shows partial recipes in grey, if there's some of the things required for the recipe on the table. Recipe requirements are now also shown next to the names of recipes listed in the window.
    • -
    - -

    11 March 2015

    -

    MMMiracles updated:

    -
      -
    • Adds a new vending machine, the Liberation Station. Consult your local patriot for more details.
    • -
    • Adds a patriotic jumpsuit and freedom sheets. Consult your local patriot for more details.
    • -
    -

    Miauw updated:

    -
      -
    • Added a toggle for ghosts that allows them to hear radio chatter without having to hover near intercoms/over people with headsets.
    • -
    - -

    10 March 2015

    -

    Ahammer18 updated:

    -
      -
    • Adds the Slimecake and Slimecake slice.
    • -
    -

    AnturK updated:

    -
      -
    • Non-player Alien Queens/Drones now spread weeds. Can also lay eggs when enabled.
    • -
    -

    Incoming5643 updated:

    -
      -
    • Nanotrasen scientists have recently reported mutations within the pink family line of slimes. Station scientists are encouraged to investigate.
    • -
    -

    Paprika updated:

    -
      -
    • Reworked reskinning and renaming guns, and added the ability to reskin the bartender's shotgun. Click it with an empty active hand to reskin. Warning, you can only do this once! Rename by hitting it with a pen. This also works with miner shotguns now.
    • -
    -

    RemieRichards updated:

    -
      -
    • Embedding from explosions has been tweaked, they will always throw objects fast enough to get embedded if they can.
    • -
    • Damage taken when embedded spears and throwing stars fall out has been increased.
    • -
    • Damage dealt by objects getting embedded has been decreased.
    • -
    -

    Sometinyprick updated:

    -
      -
    • The Horsemask spell has now been altered, instead of just a horse mask it will now choose between three animal masks including the horse mask.
    • -
    -

    Xhuis updated:

    -
      -
    • You can now burn papers using lighters, welders, or matches. Useful for secret messages.
    • -
    -

    phil235 updated:

    -
      -
    • Airlocks with their safety on no longer closes on dense objects (like mechs or tables).
    • -
    • Aliens, slimes, monkeys and ventcrawler mobs can now climb into disposal. Cyborgs and very large mobs can no longer climb into it.
    • -
    • Stuffing another mob in a disposal unit is now only done via grabbing.
    • -
    • Coffee now causes jittering only when you overdose on it.
    • -
    • Turrets now target occupied mechs and don't target drones.
    • -
    - -

    08 March 2015

    -

    Dannno updated:

    -
      -
    • Added more barsigns, sprites by yours truly.
    • -
    -

    Ikarrus updated:

    -
      -
    • Gang mode has been reworked to functionality without some of it's features.
    • -
    • Gang membership visibility, conversion pens and weapons are removed until fixed.
    • -
    • Gang bosses have been given uplinks to use in the meantime.
    • -
    • Chance of deconversion from repeated head trauma has been increased.
    • -
    -

    Incoming5643 updated:

    -
      -
    • The skeleton and zombie hordes have been quelled, at least for the time being.
    • -
    -

    Mandurrrh updated:

    -
      -
    • Added the ability to stop table climbers by clicking the table if present.
    • -
    -

    Paprika updated:

    -
      -
    • Labcoats and uniforms no longer use action buttons and object verbs to adjust their aesthetic style. Alt click them to adjust.
    • -
    • Alt click a PDA with an ID inside to eject the ID.
    • -
    • Renamed 'remove ID' verb to 'eject ID' so it's not immediately next to 'remove pen'.
    • -
    • Rebalanced the flash protection of thermal scanners. Syndicate thermals have the same flash weakness as the meson scanners they come disguised as.
    • -
    -

    Xhuis updated:

    -
      -
    • Adds the Adminbus and Coderbus bar signs.
    • -
    • Added a mining satchel of holding to R&D that can hold an infinite amount of ores. It requires gold and uranium, in addition to a decently high bluespace and materials research.
    • -
    -

    phil235 updated:

    -
      -
    • Harvesting meat from dead simple animals now takes time, has a sound, and can be done with any sharp weapon.
    • -
    -

    pudl updated:

    -
      -
    • Updated the sprite for Fire extinguishers.
    • -
    -

    xxalpha updated:

    -
      -
    • Disposable lighters now come in more colors of the rainbow.
    • -
    - -

    05 March 2015

    -

    Jordie0608 updated:

    -
      -
    • Server hosts can set a config option to make an unseen changelog pop up on connection.
    • -
    -

    MrPerson updated:

    -
      -
    • Expanded the on-screen alerts you get on the top-right of your screen. You can shift-click them to get a description of what's wrong and maybe how to fix it.
    • -
    • Getting buckled to something will show an alert of what you're buckled to. If you're not handcuffed, you can click the alert to unbuckle.
    • -
    -

    RemieRichards updated:

    -
      -
    • Added Necromantic Stones as a buyable item for wizards
    • -
    • Necromantic Stones can cause up to 3 people to rise up as Skeleton Thralls bound to the wielder of the stone
    • -
    • Skeleton Thralls have a 33% Chance to drop all their gear on the floor and autoequip a more fitting thematic uniform
    • -
    • Allows the blob to reroll it's chemical for a cost.
    • -
    -

    phil235 updated:

    -
      -
    • Adds a lot of new plants to botany (red beet, parsnip, snap corn, blumpkin, rice, oat, vanilla, steel cap, mimana, blue cherries, holy melon, geranium, lily, sweet potato) and two new reagents (vanilla, rice).
    • -
    • Fixes taser stun duration being longer due to jitter animation.
    • -
    - -

    03 March 2015

    -

    Delimusca updated:

    -
      -
    • Improvised heating! use lighters or other heat sources to heat beakers, bottles, etc.
    • -
    -

    Gun Hog updated:

    -
      -
    • We have purged the xenomicrobes contamination in the E.X.P.E.R.I-MENTOR using sulfuric acid. Take care not to be exposed should it leak!
    • -
    -

    Iamgoofball updated:

    -
      -
    • Colorful reagent can be washed off with water now.
    • -
    • Oxygen blob deals breath loss damage.
    • -
    • Radioactive blobs irradiate for more.
    • -
    -

    Ikarrus updated:

    -
      -
    • Antagonist roles are now restricted by player client age.
    • -
    -

    Jordie0608 updated:

    -
      -
    • The server's current local time is now displayed in status panel in ISO date format (YYYY-MM-DD hh:mm)
    • -
    -

    Mandurrrh updated:

    -
      -
    • Added the ability to see pda messages as a ghost with GHOSTWHISPER toggled on.
    • -
    • Removed the degrees symbol from Kelvin units on atmos meters because not gramatically correct
    • -
    -

    RemieRichards updated:

    -
      -
    • Drones now see either Static, Black icons or Roguelike style lettering instead of actual mob icons
    • -
    • Icons for the above, from VG's SkowronX
    • -
    • Many icon procs for the above, from VG's ComicIronic
    • -
    • Drones moved into their own folder
    • -
    • Drone.dm replaced with seperate files for each functionality
    • -
    • Drones now have 2 skins to choose from, Maintenance Drone (Current drones) and Repair Drone (A modified VG/Bay sprite)
    • -
    • Much more support for alternate skins on drones
    • -
    -

    Xhuis updated:

    -
      -
    • Added four new emoji: :1997:, :rune:, :blob:, and :onisoma:.
    • -
    -

    xxalpha updated:

    -
      -
    • Added a surgery table and tools to the Nuke Ops ship.
    • -
    • Added Engineering Scanner Goggles to Engivend, Engineering Secure Closets and Research.
    • -
    • Doubled T-ray scanner range.
    • -
    - -

    01 March 2015

    -

    Dannno updated:

    -
      -
    • Resprited all owl items. Wings are now a seperate toggleable suit item.
    • -
    • Added The Griffin costume, arch nemesis of The Owl. Found in the autodrobe.
    • -
    • Added admin-only Owl hardsuit. Only for the most vengeful souls.
    • -
    • Added Owl and Griffin merchandise; The Nest barsign, Owl/Griffin toys and posters.
    • -
    -

    Iamgoofball updated:

    -
      -
    • Fixes the recipe for meth.
    • -
    • Fixes sorium blobs flinging themselves.
    • -
    -

    Incoming5643 updated:

    -
      -
    • On servers where malfunction, wizard, and blob rounds do not end with the death of the primary antagonist, new antagonists from traitor and changeling derivative modes will now sometimes spawn. This depends on the state of the station, the state of the crew, and the server's gamemode probabilities. Server owners should consider revising their configuration choices
    • -
    • If you would like to opt out of this midround chance, a new toggle to disable it can be found in your preferences
    • -
    -

    Mandurrh updated:

    -
      -
    • The barsign can be emagged and EMP'd; EMP'd signs can be repaired with a screwdriver and cables.
    • -
    -

    Menshin updated:

    -
      -
    • Fixed the protolathe not requiring displayed amount of materials to make items.
    • -
    -

    MrStonedOne updated:

    -
      -
    • Adds a Panic Bunker!
    • -
    • This will prevent any player who has never connected before from connecting. (Admins are exempt)
    • -
    • Can be enabled per-round by any admin with +SERVER or for longer periods via the config.
    • -
    • Also adds some other config options relating to new joins, server operators should consult their configuration file for more details.
    • -
    • Fixes toggle darkness vision hiding other ghosts.
    • -
    • Admins fucking around with ghost icon and icon states in VV are going to want to change the icon and icon state of the ghostimage var of the ghost to change the image shown to ghosts who have darkness disabled. doing this via mass edit is not yet supported.
    • -
    • New ghost verb, toggle ghost vision. Switches the ghost's invisibility vision between that of a ghost and that of a human. So ghosts can hide other ghosts and in general get the old behaviour of toggle darkness.
    • -
    -

    Paprika updated:

    -
      -
    • Messages with two exclamation marks will be yelled in bold.
    • -
    -

    Phil235 updated:

    -
      -
    • Cultists can't summon narsie until their sacrifice objective is complete.
    • -
    -

    Razharas updated:

    -
      -
    • Vines now can grow on any tiles that is not dense, including space, shuttles, centcomm tiles and so on.
    • -
    • Added 'Bluespace' mutation to vines, makes them be able to grow through absolutely everything.
    • -
    • Added 'Space Proofing' mutation to vines, after they grow if the tile under them is space it will become special vinetile, which is just resprited regular floor, if the vine on the vinetile dies the vineturf changes back to space.
    • -
    • Made vines spreading speed depend on the seed's production, can be both slower and faster than current.
    • -
    • Made vines mutation chance be 1/10th of the potency of the seed it is spawned from.
    • -
    • Special chemicals added to vine seeds durning their growth can increase/decrease their potency and productivity.
    • -
    • Special chemicals now can remove good, bad or neutral mutations from vine seeds while they are growing, cultivating actually helpful vines is now possible.
    • -
    • Plant analyzers now show the vine seeds mutations.
    • -
    • Buffed numbers in some of the more useless mutations.
    • -
    -

    Steelpoint updated:

    -
      -
    • Reworked and expanded areas of the derelict station. Featuring a repairable gravity generator, turret filled computer core and functional solars.
    • -
    -

    Vekter updated:

    -
      -
    • Chemists, Geneticists, Virologists, Scientists, and Botanists will now spawn with alternative backpacks and satchels in their lockers. Try them out!
    • -
    - -

    25 February 2015

    -

    Cheridan updated:

    -
      -
    • Foam now carries reagents, similarly to smoke. Have fun with that.
    • -
    -

    Dannno updated:

    -
      -
    • Altered the sprite for security hardsuits. The old sprite is now a HoS specific hardsuit.
    • -
    -

    Delimusca updated:

    -
      -
    • Turret's guns replaced by a heavy energy cannon.
    • -
    • Firing a heavy weapon sindlehandedly can make it recoil out of your hands.
    • -
    -

    Gun Hog updated:

    -
      -
    • Nanotrasen has released new design specifications for the prototype combination of standard night-vision equipment and Optical Meson Scanners. We believe that this will address the concerns many Shaft Miners have concerning visiblity in a potentially unsafe environment.
    • -
    • Fixed malf AI's turret upgrade power not working.
    • -
    -

    Iamgoofball updated:

    -
      -
    • You can now go into hyperglycaemic shock from having over 200u of Sugar in your body at once. Treat it with Insulin.
    • -
    • Insulin has been added. Use it to treat hyperglycaemic shock. You can get it from medical vendors and the Cargo medicine supplies crate.
    • -
    • Medvendor contents have been reduced from medical having everything they need at roundstart level, and toxin bottles are now back in the vendor.
    • -
    • Medical Analyzers now have 2 modes, Medical Scan and Chemical Scan. You can swap between modes by clicking on it in hand.
    • -
    • Medical scan is default behavior. Chemical scan shows all the reagents inside the mob at the time, along with any addictions the mob has. It will show if a reagent is overdosing.
    • -
    • Tobacco and Space Tobacco have Nicotine in them now.
    • -
    • Adds Methamphetamine to the game. Mix it with Ephedrine, Iodine, Phosphorous, and Hydrogen at 374K.
    • -
    • Or, look around in Maintenance for Muriatic Acid, Caustic Soda, and Hydrogen Chloride. Recipes are also available for these.
    • -
    • Adds Saltpetre. Mix it with Potassium, Nitrogen, and Oxygen.
    • -
    • Adds Bath Salts, mix it with Bad Food, Saltpetre, Nutriment, Space Cleaner, Universal Enzyme, Tea, and Mercury at 374K.
    • -
    • Adds Aranesp. Mix it with Epinephrine, Atropine, and Morphine.
    • -
    • Adds Hotline. Get it from Poppy plants.
    • -
    • Strange Reagent revival was changed. It now won't gib but won't do anything above a 100 BRUTE or BURN threshold.
    • -
    • Carpet now applies carpet tiles to whatever flooring it hits. Mix it with Space Drugs and Blood.
    • -
    • Colorful Reagent colors have been improved drastically and now are more varied and nicer looking.
    • -
    • Corn Starch has been added. Get it from juicing Corn.
    • -
    • Corn Syrup has been added. Mix it with Corn Starch and S-Acid.
    • -
    • Corgium has been added. Mix it with Nutriment, Colorful Reagent, Strange Reagent, and Blood at 374K.
    • -
    • Adds Quantum Hair Dye. Mix it with Colorful Reagent, Radium, and Space Drugs.
    • -
    • Adds Barber's Aid. Mix it with Carpet, Radium, and Space Drugs.
    • -
    • Adds Concentrated Barber's Aid. Mix it with Barber's Aid and Unstable Mutagen.
    • -
    • Re-adds Chlorine Trifluoride. Mix it with Chlorine and Fluorine at 424K.
    • -
    • Adds Black Powder. Mix it with Saltpetre, Charcoal, and Sulfur. Ignite it for an explosion at 474K
    • -
    • Finally nerfs Salglu Solution. It's no longer tricord 2.0.
    • -
    • Salt recipe is now Water + Sodium + Chlorine due to problems with recipe mixing.
    • -
    -

    Incoming5643 updated:

    -
      -
    • A new event has been added to the wizards summon events spell that gives the game a distictively more roleplaying flair.
    • -
    • Optional population cap functionality has been added to the game. By default all caps are disabled. Server owners should refer to config.txt to see their list of options.
    • -
    • Medical borgs now have access to a deployable onboard roller bed. Should the bed become lost, any roller bed may be used in its place.
    • -
    -

    Mandurrh updated:

    -
      -
    • Added interchangeable bar signs
    • -
    • Added bays fountain machines for the bar. Soda and Beer. Allowing bartenders to have easier access to mix drinks and making more to make their job a little less boring
    • -
    • Added color tiles to the light up floor tiles.
    • -
    • Added metal, glass, and cable to bar back room at round start for bartender to make colored light dance floors.
    • -
    • Fixes clown cuffing both mobs and two pairs of cuffs appearing.
    • -
    • Fixes clown not being able to use his stamp as antag so no meta.
    • -
    • Fixes sleepypen bug. Instead of only dispensing 50u it dispenses the full 55u.
    • -
    • Fixed silicons not being able to pass through holotape.
    • -
    -

    Menshin updated:

    -
      -
    • Getting into regenerative statis now puts the changeling into unconscious state.
    • -
    • Fixed changeling 'Revive' not working.
    • -
    -

    Paprika updated:

    -
      -
    • Added an assistant cap, unlimited by default.
    • -
    • Batons now slowly lose power when left on.
    • -
    • Batons, flashbangs and handcuffs can be seen when stored in a belt.
    • -
    • Computers now emit light when they're on or bluescreened.
    • -
    • Added hotkeys for OOC and custom emotes. Press O and M when in hotkey mode. Remember not to ick in ock!
    • -
    • Added megaphones for the HoS, HoP, and QM.
    • -
    • Goliath tentacles no longer stun you if you cross them. They will only stun you if you don't move away from them in time. They can do up to 15 damage now, in addition to stunning you.
    • -
    • Changed a lot of mining gear and prices. The resonator can now have up to 3 fields active at once, but the fields need to detonate before they crush rocks. Tweak the time before the fields detonate with a screwdriver and upgrade the amount of fields at once with sheets of diamond.
    • -
    • Overhauled straight mining tools. The sonic jackhammer is now the wall-crushing tool, the diamond drill simply mines really fast. Borgs can now get upgraded with the diamond mining tool with only a single sheet of diamond and an upgrade module, they don't need illegal tech modules.
    • -
    • Mining drills and the sonic jackhammer now draw power when they drill down mineral walls. They can be recharged using any type of weapon recharger or by replacing the cell using a screwdriver on them.
    • -
    • Space now emits a dim light to adjacent tiles.
    • -
    • Syndicate shotguns now start with buckshot instead of stunslugs.
    • -
    • Fixed welding tools using fuel when being switched on.
    • -
    • Added a firing delay between shooting electrodes.
    • -
    • Changed the stun revolver from a high-capacity taser to a disabler with extra capacity.
    • -
    • Added a unique stun pistol for the head of security. It is a double capacity taser with no shot delay and a loyalty pin, though it lacks a disable mode.
    • -
    -

    RandomMarine updated:

    -
      -
    • New brute treatment kit crate for cargo.
    • -
    -

    RemieRichards updated:

    -
      -
    • Explosions will now blow (throw) items away from the epicenter
    • -
    • Sharp items can now embedd themselves in a human's limbs
    • -
    • Embedded items have a chance to do some damage (based on w_class) each life() call
    • -
    • Embedded items have a chance to fall out doing some more damage, but removing the object
    • -
    • Adds a surgery to remove Embdedded objects
    • -
    • Adds throwing stars as an uplink item (100% chance to embedd)
    • -
    • Items placed on tables now center to exactly where you clicked.
    • -
    -

    Steelpoint updated:

    -
      -
    • SS13's Head of Security has received a new attempted 1:1 recreation of a Old Earth weapon, the Captain's Antique Laser Gun.
    • -
    • This gun features three firing modes, Tase, Laser and Disable. However this gun lacks the capability to recharge in the field, and is extreamly expensive.
    • -
    • INTERCEPTED TRANSMISSION REPORT: The Syndicate have expressed a interest in this new weapon, and have instructed field agents to do whatever they can to steal this weapon.
    • -
    -

    TheVekter updated:

    -
      -
    • Box's vault nuke has been replaced with immobile Nuclear Self-Destruct Mechanism.
    • -
    • Vault's new green floor tiles turn flashing red when Self-Destruct is activated.
    • -
    -

    Xhuis updated:

    -
      -
    • Syndicate contacts have discovered new ways to manipulate alarms. Malfunctioning AIs, as well as normal emags, can now disable the safeties on air and fire alarms.
    • -
    • When one emags an air alarm, its safeties are disabled, giving it the Flood environmental type, which disables scrubbers as well as vent pressure checks. Burn, pigs, burn!
    • -
    • When one emags a fire alarm, its thermal sesnsors are disabled. This will prevent automatic alerts due to the alarm being unable to recognize high temperatures.
    • -
    • Malf AIs gain two new modules, both of which disable ALL air alarm safeties and thermal sensors. These are separate abilities.
    • -
    • Air and fire alarms have notifications on their interface about the current safety status. One only has to glance at one to see that it's been tampered with.
    • -
    -

    phil235 updated:

    -
      -
    • Fixed arcade machines being usable from inside lockers to dupe rewards.
    • -
    • Silicons can no longer be grabbed by anyone. No more silicon choking
    • -
    • Custom food can now be renamed using a pen.
    • -
    -

    xxalpha updated:

    -
      -
    • Added new graffiti: cyka, prolizard, antilizard
    • -
    - -

    18 February 2015

    -

    Dannno updated:

    -
      -
    • Added proper slurring when drunk.
    • -
    -

    Deantwo updated:

    -
      -
    • Updated the ChemMaster's UI to the station default along with some functionality improvements.
    • -
    • You can now spam the 'Ready' button as much as you want without it setting you 'Not ready' again.
    • -
    -

    Dorsidwarf updated:

    -
      -
    • Added the ability to call Central Command for the nuclear authentication codes. This requires a captain-level ID and admin approval, and warns the crew.
    • -
    -

    Gun Hog updated:

    -
      -
    • E.X.P.E.R.I-MENTOR meteor storm event replaced with a fireball that targets random nearby mob.
    • -
    • EMP event range reduced.
    • -
    • Self-duplicating relics limited to 10 copies.
    • -
    • Nanotrasen has released a firmware patch for the Ore Redemption Machine, which now allows the station AI, cyborgs, and maintenance drones to smelt raw resources without the need of a valid identification card installed.
    • -
    • Nanotrasen scientists have completed their designs for a lightweight, compacted anti-armor ion weapon, without loss of efficiency. In theory, such a weapon could easily fit within standard issue backpacks and satchels. With sufficient research into weapons technology and materials, Nanotrasen believes a working prototype can be fabricated.
    • -
    -

    Iamgoofball updated:

    -
      -
    • Buffs the shit out of Styptic Powder and Silver Sulf, they're now viable to use. Synthflesh is still good for general treatment, but overall Styptic and Silver Sulf deal with their respective damage types way better now.
    • -
    • Improves kinetic accelerator's mining strength.
    • -
    • The kinetic accelerator's cooldown can be decreased by tweaking the thermal exchanger with a screwdriver.
    • -
    • The range can be increased with plasma sheets
    • -
    -

    Incoming5643 updated:

    -
      -
    • Medical borgs have been given full surgery tools which they can't fail a procedure with.
    • -
    • Medical borgs also have rechargeable gauze.
    • -
    • Borg hypo's omnizine replaced with salbutamol, salglu and charcoal.
    • -
    • Slime and Jelly mutant races now actually contain slime jelly. While playing as these races you will naturally produce it internally from your nutrition, so be sure to stay well fed as losing too much is dangerous to your health! Beware of chems that clear toxins, as they can be rapidly fatal to you!
    • -
    -

    Jordie0608 updated:

    -
      -
    • Veil render and rifts changed to spawn with vars, rifts can be closed with a nullrod.
    • -
    -

    Lo6a4evskiy updated:

    -
      -
    • General record now contains a species field and a photo of the crewmember. Security record consoles allow you to update it with a photo taken in-game (with detective's camera, for example, or AI's).
    • -
    • Expanded functionality of security HUDs to display rank and photos.
    • -
    • Medical HUDs allow user to change others' mental and physical status. Currently has no gameplay effect other than changing records.
    • -
    • Medical HUDs can perform an examination at the distance, similrarly to how attacking yourself with help intent works. Has limited ability to detect suffocation and toxin damage.
    • -
    -

    Menshin updated:

    -
      -
    • Solar control computers remade with NanoUI
    • -
    -

    Paprika updated:

    -
      -
    • Added rnd requirements to borg upgrades and tweaked the prices.
    • -
    • Changed some clothing around. Added a turtleneck for the HoS. Removed 'civillian' armor and gave normal armor to the bartender and HoP. Added flash protection to the HoS' eyepatch, it functions like sunglasses now. Additionally, added the ability to store ammo on your shoulder holster as detective.
    • -
    • Removed the defib steal objective. Added a compact defibrillator for the CMO that equips to the belt. Removed defibrillators from RND. Removed the requirement for people to not wear armor to revive them with defibs. Doubled defib timers (10 minutes before permadeath).
    • -
    • Flashlights can be attached to pulse carbines.
    • -
    • Miners spawn with a brute patch.
    • -
    • Mining station's sleeper has been replaced with an IV drip and more medkits.
    • -
    • Added hard-light holotape. This holographic police or engineering hazard tape will block entry if you're running, so you need to walk to pass it. This is to help people not sprint into breaches or crime scenes.
    • -
    • Fixed being able to sling the strapless improvised shotgun on your back.
    • -
    • Reverted the price of the ebow to 12tc and removed the range limit of its bolts.
    • -
    -

    Sometinyprick updated:

    -
      -
    • Novely pig mask prize from arcade machines, can be toggled to make you squeal like a pig.
    • -
    -

    Steelpoint updated:

    -
      -
    • Security Cyborgs Advance Taser have been replaced with a Disabler.
    • -
    -

    TZK13 updated:

    -
      -
    • Adds plaid skirts and new schoolgirl outfits to the autodrobe
    • -
    • Novaflowers apply a firestack for every 20 potency they have.
    • -
    • You can now juice whole watermelons instead of slices.
    • -
    • Advancements in the field of virology by Nanotrasen's finest have uncovered three new disease symptoms for further research:
    • -
    • Ocular Restoration heals any eye trauma experienced by the infected patient.
    • -
    • Revitiligo increases the pigmentation levels of the infected patient's skin.
    • -
    • Spontaneous Combustion ignites the infected patient without warning.
    • -
    -

    Vekter updated:

    -
      -
    • Added shot glasses! Can be obtained from the Booze-o-Mat.
    • -
    • A new premium vodka has been added to the game, hidden in a special spot.
    • -
    • Due to constant attempts to break into the station's safe, the contents have been relocated and have not been replaced. We promise. There is absolutely NO reason to break into the vault's safe anymore.
    • -
    • Each shot glass now holds 15 units, and the drinker takes all 15 in one gulp instead of 5 at a time. This means you can mix certain shots (namely, the B-52 and Toxins Special) in a shot glass. Both drinks have been made exclusive to shot glasses and will no longer show their specific sprite in a normal glass.
    • -
    • Added new sprites for most alcohol in shot glasses. Everything else will show up as 'shot of... what?'.
    • -
    • Fixed shot glasses turning into regular glasses when filled.
    • -
    • Fixed tequila bottle sprites not showing up.
    • -
    • Fixed a typo!
    • -
    • Roboticists will now start with a full toolbelt instead of a toolbox.
    • -
    -

    drovidi updated:

    -
      -
    • Blobs who burst in space will be given a 30 second warning before dying.
    • -
    • If a blob does die from bursting in space, a new crewmember will be infected.
    • -
    • If there are no blobs or infected crew left after bursting, the round will now end properly, rather than becoming endless.
    • -
    -

    phil235 updated:

    -
      -
    • You no longer need to cut the syphon wire to deconstruct air alarms.
    • -
    • Cooking overhaul: microwave recipes are converted to tablecraft recipes.
    • -
    • Added customizable food (burger,sandwich,spaghettis,soup,salad,cake,bread,kebab,pie) with specific color depending on ingredients used.
    • -
    • Added new food ingredients (dough, flat dough, cake batter, pie dough, doughslice, bun, raw pastry base, pastry base, raw cutlet, cutlet, pizzabread). Dough is made by mixing egg and flour, then transformed by using knife, rollingpin, milk and microwave. Meat is now sliceable into rawcutlets (specific color for each meat type).
    • -
    • Changed food recipes a bit (replacing stuff with new food ingredients).
    • -
    • Repurposed the microwave to actually cook certain food items(no reagents required), renamed it microwave oven and added a power setting to it.
    • -
    • Bowl is no longer trash but a beaker-like container that is used in salad&soup recipes. Also, milk and soymilk cartons as well as flour packs are now condiment bottles.
    • -
    • Changed the hunger system a bit, sugar becomes a normal reagent again. Faster nutrition drain is now handled by a variable in junk food. Also added a slight buff to vitamin.
    • -
    -

    xxalpha updated:

    -
      -
    • You now hear the voice of the chosen deity in prayers.
    • -
    - -

    05 February 2015

    -

    Danno updated:

    -
      -
    • Added suicide messages for all gun types and various different items.
    • -
    -

    Paprika updated:

    -
      -
    • Compacted ERT room by removing equipment rooms, filler rooms and pre-spawned mechs.
    • -
    • Rebalanced Pulse weapons to have more shots, faster charge, EMP immunity and modified sprites.
    • -
    • ERT spawns fully equipped with no-slowdown suits.
    • -
    • Added blood and bleeding. If you take enough brute damage on a certain limb, you will start bleeding, and will need to patch your bleeding with gauze from medbay. You can replace lost blood by eating nutritious food and waiting for your heart to reproduce it, or by getting a blood transfusion from an IV drip.
    • -
    -

    Vekter updated:

    -
      -
    • Added a toy red button to the Arcade cabinets.
    • -
    - -

    04 February 2015

    -

    Danno updated:

    -
      -
    • Fixes dufflebag's storage capacity.
    • -
    -

    Deantwo updated:

    -
      -
    • Removes duplicate fluorine from Chemical Dispenser.
    • -
    • Added GoonChems to the Portable Chem Dispenser.
    • -
    • Added cancel buttons to the ChemMaster and CondiMaster when making bottles, pills, etc.
    • -
    -

    Delimusca updated:

    -
      -
    • Added new foam armblade toy to arcade prizes.
    • -
    • Slimes can drag themselves to mobs to start feeding.
    • -
    • Attacking another slime will pull them off their victim if they're feeding or steal some of their mass.
    • -
    -

    GunHog updated:

    -
      -
    • Five new silicon emotes: *buzz2, *chime, *honk, *sad and *warn
    • -
    -

    Incoming5643 updated:

    -
      -
    • New contraband crate containing fifty butterflies.
    • -
    • Shuttle will now always arrive, but won't launch in rounds where it would've been previously auto-recalled.
    • -
    -

    Menshin updated:

    -
      -
    • Fixed being unable to place cables on plating.
    • -
    -

    Paprika updated:

    -
      -
    • Helmets for hardsuits are stored inside the suit and cannot be equipped without the suit on.
    • -
    • EVA space suits are now lighter for faster movement but lack flash or welding protection, don't hide your identity and have less radiation protection.
    • -
    -

    Perakp updated:

    -
      -
    • Tweaked slowdown due to coldness when in in low gravity.
    • -
    -

    Steelpoint updated:

    -
      -
    • ERT base equipment rooms are now access restriction to each role.
    • -
    • ERT commander spawns wearing hardsuit for identification.
    • -
    • Two boxes of metal foam grenades added for ERT engineers.
    • -
    • Deep space sensors recently detected the derelict remains of the NTSS Omen, a outdated Medical Frigate thought lost, within close proximity to Space Station 13.
    • -
    • If any SS13 EVA Personal are able to locate this ship, they will be able to pilot it back to the station for recovery. The ship may also have cordinates for other locations.
    • -
    -

    Xhuis updated:

    -
      -
    • Changelings now have the ability Strained Muscles, which lets them move at inhuman speeds at the cost of rapid stamina damage. It costs one evolution points=.
    • -
    • Changelings now have the ability Augmented Eyesight, which lets them see creatures through walls and see in the dark. It costs two evolution points.
    • -
    • After many failed raids, the Syndicate have finally done something about poor communications between cyborgs and operatives.
    • -
    • Syndicate Cyborgs now come equipped with operative pinpointers, which will automatically point to the nearest nuclear operative.
    • -
    • Handheld crew monitors can now be stored in medical belts.
    • -
    - -

    26 January 2015

    -

    Dannno updated:

    -
      -
    • Added fannypacks of multiple colors, 3 of which are accessible from the clothing vendor.
    • -
    • Added dufflebags to multiple lockers throughout the station and to the syndicate shuttle, more storage slots at the cost of move speed.
    • -
    -

    Deantwo updated:

    -
      -
    • Fixed some bugs in PDA's NTRC Chatroom feature.
    • -
    • You can now use PaperBBCode/PenCode when writing news articles on the newscaster.
    • -
    • PDA's Notekeeper now uses PaperBBCode/PenCode rather than HTML.
    • -
    • Scanning paper with your PDA is now more informative.
    • -
    -

    Firecage updated:

    -
      -
    • We, at NanoTrasen, have recently upgraded the Kitchen Spikes to include the skin of both Monkeys and Aliens when you harvest their flesh!
    • -
    • In other news, a station in a nearby Sector has been making monkey and xeno costumes. We are not sure why.
    • -
    • Added the ability to reform mineral floortiles back into sheets/bars
    • -
    -

    Ikarrus updated:

    -
      -
    • Added a new config option MINIMAL_ACCESS_THRESHOLD that can be used to automatically give players more access during low-population rounds. See game_options.txt for more information.
    • -
    -

    Lo6a4evskiy updated:

    -
      -
    • The kitchen now contains a brand new food cart. It can store foods and liquids, mix them into cocktails and dispense where needed. Food delivery has never been easier!
    • -
    -

    fleure updated:

    -
      -
    • Added briefcase filled with cash to uplink.
    • -
    - -

    21 January 2015

    -

    Iamgoofball updated:

    -
      -
    • Addiction and Overdosing has been added to Chemistry.
    • -
    • Deal with Overdosing by purging the ODing chemical with Calomel or Penetic Acid.
    • -
    • Deal with Addiction by either going cold turkey on it and weathering the effects, eventually causing the addiction to subside, or by taking more of the addictive substance to keep the effects down.
    • -
    • Cryoxadane was heavily buffed. Clonex was removed as it was merged into Cryox.
    • -
    • Fixes a shitton of stuff adding Morphine instead of Ephedrine. Sorry, miners.
    • -
    • Fixes instances of Alkysine not being replaced with Mannitol. Same with Ryetalyn being replaced with Mutadone.
    • -
    • Adds Itching Powder. Welding Fuel and Ammonia.
    • -
    • Adds Antihol. Ethanol and Charcoal.
    • -
    • Adds Triple Citrus. Lemon Juice, Lime Juice, and Orange Juice.
    • -
    • Adds Colorful Reagent. Stable Plasma, Triple Citrus,
    • -
    • Morphine replaces sleep toxin now, not Hyperzine. Hyperzine is replaced by Ephedrine now.
    • -
    • Cryotubes will now autoeject you once you are fully healed.
    • -
    • Synthflesh damage values have been fixed.
    • -
    • Charcoal has been buffed to heal 3 TOX damage a cycle and it purges other chemicals faster.
    • -
    • Saline-Glucose Solution has been buffed. It now has a 50% chance per cycle to heal 3 BRUTE and BURN per tick.
    • -
    • Fixes Strange Reagent revivals dying right after being revived. They'll still need immediate medical treatment, however.
    • -
    • Cryoxadone has had a recipe change. It is now Stable Plasma, Acetone, and Unstable Mutagen.
    • -
    • Adds 9 new Disabilites and 2 new genetic powers.
    • -
    • You can now heat donk pockets once more. Rejoice.
    • -
    - -

    17 January 2015

    -

    Cheridan updated:

    -
      -
    • The lockbox system for R&D has been replaced with a firing pin system. Ask the Warden or HoS for firing pins to allow normal operation of your firearms. Want to test them out at the range? Try printing a test-range pin.
    • -
    • Nuke Ops have used this new technology to lock some of their heavier weapons so that crew cannot use them. These implants replace their explosive implants.
    • -
    • Explosive implants are now purchasable in the uplink, and are much stronger.
    • -
    -

    Firecage updated:

    -
      -
    • NanoTrasen would like to report that our Mechanical Engineers at NTEngiCore has recently upgraded the capacity of the machines known as Biogenerators. They are now have the added ability to create various belts, and also weed/plantkillers and cartons of milk and cream!
    • -
    -

    Iamgoofball (Look Ma, I didn't mispell my name this time!) updated:

    -
      -
    • Replaced Star Trek chemistry with Goon Chemistry.
    • -
    • Emergency Medic's Handbook Tip 1: Styptic Powder = BRUTE, Silver Sulfadiazine = BURN, Charcoal = TOX, Salbutamol = OXY
    • -
    • In recipes that used removed reagents, they have been replaced with their goon chemistry counterpart:
    • -
    • Hyperzine -> Morphine
    • -
    • Inaprovaline -> Epinephrine
    • -
    • Kelotane -> Saline-Glucose Solution
    • -
    • Bicardine -> Saline-Glucose Solution
    • -
    • Dermaline -> Saline-Glucose Solution
    • -
    • Dexalin -> Salbutamol
    • -
    • Dexalin Plus -> Salbutamol
    • -
    • Tricordrazine -> Omnizine
    • -
    • Anti-Toxin -> Charcoal
    • -
    • Hydronalin -> Penetic Acid
    • -
    • Arithrazine -> Penetic Acid
    • -
    • Imidazoline -> Oculine
    • -
    • Mannitol -> Alkysine
    • -
    • Ryetalyn -> Mutadone
    • -
    -

    Steelpoint updated:

    -
      -
    • The Emergency Response Team project has been activated by Nanotrasen. The ERT are a seven man squad that can be deployed by the Central Command (admins) to attempt to rescue the station from a overwhelming threat, or to render assistance in dealing with a significant problem.
    • -
    • The ERT consists of a single Commander, two Security Officers, two Engineering Officers and two Medical Officers. The Commander is preselected when the squad is being spawned in, however the remaining six officers are free to select their role in the squad.
    • -
    • Two new Pulse gun variants have been added to the game. They are the Pulse Carbine and the Pulse Pistol, both have significantly smaller ammunition capacities than the Pulse Rifle, however they both can fit in a backpack and the pistol can fit in a pocket. All ERT Officers have a Pulse Pistol for a sidearm, however the Security Officers get a Pulse Carbine as their primary longarm.
    • -
    -

    phil235 updated:

    -
      -
    • The two library consoles are now real buildable computers. The circuitboard design is available in R&D.
    • -
    -

    sawu-tg updated:

    -
      -
    • Added a new R&D machine, to replace the telescience room. The Machine is based on RND and various interdepartmental creations.
    • -
    - -

    14 January 2015

    -

    Boggart updated:

    -
      -
    • Adds a new spell: Repulse. (Cooldown: 40 seconds, 15 at max upgrade.) Repulse throws objects and creatures within 5 tiles of the caster away and stuns them for a very short time. Distance thrown decreases as the distance from the caster increases. (Max of 5, minimum of 3) Casting it while standing over someone will stun them for longer and cause brute damage but will not throw them.
    • -
    • Fixes the Exosuit Control Console having the unpowered icon state while powered.
    • -
    -

    Iamgootball updated:

    -
      -
    • Added Goonstation Chemistry!
    • -
    • Adds 14 medicines!
    • -
    • Adds 3 pyrotechnics!
    • -
    • Adds 3 drugs with actual gameplay uses!
    • -
    • Adds 7 toxins!
    • -
    • Adds a Chemical Heater for some new recipes!
    • -
    • Adds Chemical Patches for touch based applications!
    • -
    • Adds a Traitor Poison Kit!
    • -
    • Adds Morphine Medipens!
    • -
    • Adds Morphine bottles to Cargo!
    • -
    - -

    13 January 2015

    -

    Dannno updated:

    -
      -
    • Adds a bandanas in basic colors to lockers in the station. Activate in hand to switch between head and mask modes.
    • -
    • Adds more colored jumpsuits to the mixed locker.
    • -
    -

    Incoming5643 updated:

    -
      -
    • Player controlled slimes can now change their face to match AI controlled slimes in kawaiiness. use *help as a slime to find the commands.
    • -
    -

    Studley updated:

    -
      -
    • Fixed NTSL division.
    • -
    • Added new NTSL math functions, including 'sin,' 'cos,' 'asin,' 'acos,' and 'log.'
    • -
    - -

    06 January 2015

    -

    JJRcop, Nienhaus updated:

    -
      -
    • Adds emoji to OOC chat.
    • -
    - -

    27 December 2014

    -

    Dorsidwarf updated:

    -
      -
    • Buffs the RCD from 30 matter units to max capacity 100, and increases the value of matter charges.
    • -
    -

    Paprika updated:

    -
      -
    • Taser electrodes now have a limited range of 7 tiles.
    • -
    • The energy gun's stun mode has been replaced with a disable mode.
    • -
    • Security officers will now spawn with tasers.
    • -
    • Disabler beams now go through windows and grilles.
    • -
    • Disabler beams now do 33 stamina damage instead of 34. This means they will only stun in 3 hits on someone that is NOT 100% healthy.
    • -
    • Most ballistic projectiles now do stamina damage in addition to their regular damage instead of stunning. This includes nuke op c-20r .45, detective's revolver, etc. They are effectively better than disablers at stunning people, as well as do significant damage, but they do not stun instantly like a taser. Expect engagements to be a little longer and plan ahead for this.
    • -
    • Added an advanced taser for RnD, the child of a disabler and a taser.
    • -
    -

    Tkdrg updated:

    -
      -
    • Envoys from the distant Viji sector have brought an exotic contraption to Centcomm. Known as the 'supermatter shard', it is a fragment of an ancient alien artifact, believed to have a dangerous and mysterious power. This precious item has been made available to the Space Station 13 cargo team for the cost of a hundred supply points, as a reward for all your hard work. Good luck, and stay safe.
    • -
    - -

    16 December 2014

    -

    Paprika updated:

    -
      -
    • Reverted security armor and helmets to the old (Grey) style of armor/helmets.
    • -
    • Updated security jumpsuits to be more consistent across officer/warden/HoS ranks.
    • -
    • Added tactical armor and helmets to replace the largely unused bulletproof vest in the armory. This armor has higher bullet and explosive resistance than normal armor, and uses the previous, more military armor/helmet sprites.
    • -
    • Added a new injury doll to go along with the overall health meter. This will show you locational overall limb-based burn/brute damage, so you can tell the difference between being hurt with burn/brute or toxins/stamina damage which does not affect limbs.
    • -
    • Reverted some UI icons back to their older status and changed some around for readability. Thank you for your feedback.
    • -
    -

    Thunder12345 updated:

    -
      -
    • Added a new FRAG-12 explosive shotgun shell, built from the unloaded technological shell, using tablecrafting. Constructed using an unloaded technological tech shell, 5 units sulphuric acid, 5 units polytrinic acid, 5 units glycerol, and requires a screwdriver.
    • -
    -

    phil235 updated:

    -
      -
    • Change to the hunger system. Eating food with sugar temporarily worsens your nutrition drop rate. Eating too much sugar too quickly can make you temporarily unable to eat any sugary food. The nutritional effect of sugar depends on how hungry you are thus it cannot easily raise your nutrition level past well fed and is best used when hungry. Lots of sugar can make you a bit jittery at times. Eating food with vitamin (new reagent) counteracts the sugar effects and can give you temporary buffs when well fed: it lowers your chance to catch or spread viruses,it makes your body's metabolism more efficient that is it keeps healing reagents longer and evacuate toxins faster and reduces damage from radioactive reagents. Your metabolism gets less efficient if starving.
    • -
    • New hunger hud icons: starving, hungry, fed, well fed, full, fat.
    • -
    • Snack vending machine get a chef compartment that can be loaded with non-sugary food by hand or with a tray by anyone with kitchen access (unless you hack the machine with multitool or emag). The food can be unloaded by anyone, like regular snacks
    • -
    • Cargo can get a nutritious pizza crate order for 60 points.
    • -
    • Grown and cooked food gets some vitamin while junk food gets less nutriment and more sugar (only hot donkpocket and ramen don't have sugar)
    • -
    • The number of junk food in snack vending machine is lowered from 6 to 5 of each type.
    • -
    • Fixing not being able to load an omelette du fromage on a tray.
    • -
    - -

    10 December 2014

    -

    GunHog updated:

    -
      -
    • The Nanotrasen firmware update 12.05.14 for station AI units and cyborgs includes a patch to give them more control of their automatic speech systems. They can now chose if the message should be broadcasted with their installed radio system and any frequency available to them.
    • -
    -

    Paprika updated:

    -
      -
    • Added winter coats and winter boots! Bundle up for space xmas! They are available in most wardrobe and job lockers, and come with special features depending on the flavor!
    • -
    -

    Paprka updated:

    -
      -
    • Added a new weapon for syndicate boarding parties, the C-90gl assault rifle. This is a hybrid rifle with a lot of damage and a grenade launcher alt-fire. Purchasable for 18TC.
    • -
    • Suppressors can now be used on the protolathe SMG and the C-20r.
    • -
    -

    RemieRichards updated:

    -
      -
    • Sounds in areas of low pressure (E.g. Space) are now much quieter
    • -
    • To hear someone in space you need to be stood next to them, or use a radio
    • -
    -

    as334 updated:

    -
      -
    • We've discovered that slimes react to the introduction of certain chemicals in their bloodstream. Inaprovaline will decrease the slimes children's chance of mutation, and plasma will increase it.
    • -
    • We've also found that feeding slimes solid plasma bars makes them more friendly to humans.
    • -
    - -

    08 December 2014

    -

    Ergovisavi updated:

    -
      -
    • Allows using replica pods to clone people without bodies.
    • -
    • Speeds up replica pod cloning by adjusting the starting production.
    • -
    • Replica pods will now only create plantmen.
    • -
    • Mixing blood in a beaker or taking it from a suicide victim will render the blood sample useless for replica pod cloning.
    • -
    -

    GunHog updated:

    -
      -
    • Our top Nanotrasen scientists have provided improved specifications for the Rapid Part Exchange Device (RPED)! The RPED can now contain up to 50 machine components, and will display identical items in groups when using its inventory interface.
    • -
    • Note that power cells, being somewhat bulkier, will take up more space inside the device. In addition, the RPED's firmware has also been updated to assist in new machine construction! Simply have the required components inside the RPED, apply it to an unfinished machine with its circuit board installed, and watch as the device does the work!
    • -
    • Nanotrasen has updated station bound Artificial Intelligence unit design specifications to include an integrated subspace radio transmitter. The transmitter is programmed with all standard department channels, along with the inclusion of its private channel. It is accessed using :o in its interface.
    • -
    • {INCOMING CLASSIFIED SYNDICATE TRANSMISSION} Greetings, agents! Today, we are happy to announce that we have successfully reverse engineered the new subspace radio found in Nanotrasen's newest AI build plans. We have included our encryption data into these transmitters.
    • -
    • Should you be deployed with one of our agent AIs, it may be wise of you to purchase a syndicate encryption key in order to contact it securely. Remember, as with other agents, a Syndicate AI is unlikely to be of the same Syndicate corporation as you, and you both may actually have conflicting mission parameters! Your channel, as always, is accessed using :t.
    • -
    -

    Paprika updated:

    -
      -
    • Changed the way flashbang protection works. Currently, only security helmets (and their derivatives like swat and riot), and some hardsuit helmets have flashbang protection. Ear items like earmuffs and 'bowman' headsets (alternative, larger headsets) have flashbang protection as well, so you're able to go hatless as security. The Head of security, warden, and detective's hat do NOT have flashbang protection, but their earpieces do, from the 'noise' part of the flashbang. The flashbang blind still works as before, with only sunglasses/hardsuit helmets protecting you.
    • -
    -

    Tkdrg updated:

    -
      -
    • Security/Medical HUDs are now more responsive and less laggy.
    • -
    - -

    10 November 2014

    -

    Menshin updated:

    -
      -
    • Made meteors more threatening.
    • -
    • Added three levels of danger for meteors waves, randomly selected at spawn.
    • -
    • Rumors speaks of a very rare meteor of unfathomable destructive power in the station sector...
    • -
    • Fixed infinigib/infinisplosion with meteors bumping
    • -
    -

    Paprika updated:

    -
      -
    • Added a defibrillator and an EMT alternative clothing set for medical doctors. These defibrillators will revive the recently deceased as long as their souls are occupying their body and they have no outstanding brute or burn damage.
    • -
    • Yes, they actually work now too!
    • -
    • Added a way for you to unload a round from a chambered projectile weapon. Simply click on the gun when it is in your active hand, and assuming it does not have a magazine, the round should pop out. You can also use this system to unload individual bullets from magazines and ammo boxes, like the detective's speed loaders.
    • -
    • Added glass tables and overhauled how table construction works. Now, you need to build a frame using either metal rods or wood planks, and then place a top on the table.
    • -
    • Table disassembly now works in two stages. Screwdriver the table to remove the top of it and reduce it back to a frame. Frames can be moved around and walked on top of. Wrench the table to deconstruct it entirely back to parts, this is quicker and much more like the old fashion. To deconstruct a frame, use your wrench on it as well.
    • -
    • Fixed traitor med analyzers not fitting in medical belts.
    • -
    • Fixed syringe box bug with medipens.
    • -
    -

    Perakp updated:

    -
      -
    • Added escape-with-identity objective for changelings. Completion requires the changeling to have transformed to their target and be wearing an ID card with the target's name on it when escaping.
    • -
    • Changelings can absorb someone even if they have that DNA in storage already.
    • -
    • Fixes hivemind being lost when readapting evolutions.
    • -
    - -

    04 November 2014

    -

    MrPerson updated:

    -
      -
    • You can use AI Upload modules directly on unslaved cyborgs to change their laws. The panel has to be open to do this.
    • -
    • Newly emagged cyborgs get locked down for a little bit until their new laws get shown. Thank you to whoever bitched about it on singulo and filed an issue report.
    • -
    -

    Paprika updated:

    -
      -
    • Added an advanced mop for the janitor, available at the protolathe. This hi-tech custodian's friend can mop twice as many floor tiles before needing to return to your bucket!
    • -
    • Moved holosign projector to the protolathe and gave the janitor back his old signs. We hope you've enjoyed this free trial run of holo projectors, but our budget is tight!
    • -
    • Added a holosign projector to the janitor module for cyborgs.
    • -
    • Soap now has a delay. Different soap types clean faster than others, but expect to put it some extra arm work if you want to clean that fresh blood!
    • -
    -

    Tkdrg updated:

    -
      -
    • Cutting-edge research in a secret Nanotransen lab has shed light into a revolutionary form of communication technology known as 'chat'. The Personal Data Assistants of Space Station 13 have been deployed with an experimental module implementing this system, dubbed 'Nanotransen Relay Chat'.
    • -
    - -

    30 October 2014

    -

    MrPerson updated:

    -
      -
    • Everything now drifts in space, not just mobs.
    • -
    • Mechs are just as maneuverable in space as you are.
    • -
    • Being weightless now slows movement down by a lot rather than speeding it up. Having your hands full will make movement even slower.
    • -
    • Removed spaceslipping (You slipped! x1000)
    • -
    • Jetpacking after being thrown out a mass driver will cancel out your momentum.
    • -
    • Shooting a gun causes you to drift the other direction like spraying a fire extinguisher.
    • -
    - -

    27 October 2014

    -

    Jordie0608 updated:

    -
      -
    • Adds a new riot shotgun that spawns in the armory with a 6 round beanbag magazine.
    • -
    -

    Paprika updated:

    -
      -
    • Allowed constructs to assist in activating most runes. This includes conversion runes, but does NOT include sacrifice runes.
    • -
    -

    Patchouli Knowledge updated:

    -
      -
    • In light of the recent achievements of the Robotics department, new and upgraded exosuit schematics were delivered to SS13 exosuit fabricators as a reward from CentComm.
    • -
    • The countless hours of research, experimentation, and reverse-engineering of wrecks from the mining asteroid have paid off - the Research team has rediscovered the process of building Phazon exosuits. The parts and circuits have been made available in the exofabs and circuit printers.
    • -
    • The APLU Ripley exosuit has been refitted with asteroid mining purposes in mind. Its armour plating will provide extra protection against the brute attacks of asteroid alien lifeforms, and protect from gibtonite explosions. The leg servos were upgraded to provide faster movement.
    • -
    • There are rumours of some creative shaft miners discovering a way of augmenting APLU Ripley armour with trophy hides from goliath-type asteroid lifeforms...
    • -
    • Durand construction routines now require a phasic scanner module and a super capacitor to match Nanotrasen industry standards.
    • -
    • The exosuit fire extinguisher now boasts a larger watertank, and carries a whole 1000u of water from the old 200u tank.
    • -
    • The exosuit plasma converter's efficiency has been vastly improved upon, and its fuel consumption has been cut to nearly half of old values.
    • -
    • The exosuit sleeper interiors have been refitted to allow the occupants more freedom of movement, and the occupants may now eject at will.
    • -
    • The armour plating on all exosuits was fitted with reactive deflection systems specifically designed to stop the rapid slashes from xenomorph threats.
    • -
    • The Firefighter Ripley chassis were moved from the Exosuit Equipment section to the APLU Ripley section of exofab menus.
    • -
    • Fixed some minor errors in the exosuit construction message syntax.
    • -
    -

    phil235 updated:

    -
      -
    • Closets and its children can no longer contain a near infinite amount of mobs. Large mobs (juggernaut, alien emperess, etc) don't fit, small mobs (mouse, parrot, etc) still fit in the same amounts, human-sized mob (humanoid, slime, etc) fit but maximum two per body bag and three for all the other closets. Adding bluespace body bag to R&D, it can hold even large mobs and in large amounts.
    • -
    • girders and displaced girders now have a chance to let projectiles pass through them.
    • -
    - -

    19 October 2014

    -

    Donkie updated:

    -
      -
    • Major atmos update. Featuring pretty colors.
    • -
    • 4-Way pipes added.
    • -
    • Flip-able trinary devices (mixer & filter).
    • -
    • Pipe-painter added.
    • -
    • Most pipe icons have been tweaked with shading and such, making it look more uniform.
    • -
    -

    JJRcop updated:

    -
      -
    • We have managed to re-discover drones! We improved the formula, and have discovered some cool stuff.
    • -
    • After some fiddling with audio recognition, drones can now understand human speech!
    • -
    • One of our engineers found some screws that were loose on some of our tests, screwing them in made the drone work as if it had just come out of robotics.
    • -
    • We had to sacrifice some of our NT brand EMP protection for the speech recognition, so drones can get damaged if subjected to heavy EMP radiation.
    • -
    • We figured out why drones couldn't remove objects from people, that has been fixed.
    • -
    • The standby light wasn't wired correctly.
    • -
    • Unfortunately one of our assistants tasked with transporting the only copy of the data dropped the flash drive in hot water because he wanted to see what "drone tea" tasted like. You'll have to discover them again.
    • -
    -

    Lo6a4evskiy updated:

    -
      -
    • Station's crayons have been upgraded to the version 2.0 of ColourOS. Don't worry, they are still edible!
    • -
    • Many items now have different stripping delays. Heavier and more armored pieces of clothing are generally more difficult to take off someone else, while smaller items can be very easy to snatch. Pockets always take 4 seconds to search.
    • -
    -

    MrPerson updated:

    -
      -
    • Implants are activated via action buttons on the top-left corner of your screen instead of emotes.
    • -
    -

    Paprika updated:

    -
      -
    • Added zipties for security and nuke operatives. These have a slightly shorter 'breakout time' as normal cuffs but they are destroyed upon removal. Beepsky and sec borgs now use these by default.
    • -
    • Changed the medical HUD in the tactical medkit to a night vision HUD so syndicate medics don't stumble around in the dark. Can be purchased through nuke op uplinks.
    • -
    • Added a second roboticist roundstart job slot.
    • -
    • Added a third cargo tech job slot.
    • -
    -

    Paprka updated:

    -
      -
    • Added undershirts as a companion piece to jumpsuit adjusting. Beat the heat with a comfortable tank top, or warm up with an extra layer tshirt!
    • -
    • Added a holographic sign projector to replace the old wet floor signs to encourage janitors to warn crewmembers about wet floors.
    • -
    -

    optimumtact updated:

    -
      -
    • Medical supplies crate now comes with a boxy full of bodybags
    • -
    - -

    09 October 2014

    -

    Paprika updated:

    -
      -
    • Added inaprovaline MediPens (autoinjectors) that replace inaprovaline syringes in medkits. Like the syringes, these can be used to stabilize patients in critical condition, but require no medical knowledge to use.
    • -
    • Reverted the mining scanner to a manual scanner.
    • -
    • Buffed the rate of the automatic scanner
    • -
    • Added automatic scanner to equipment locker. It is also available by redeeming your voucher.
    • -
    • Reduced the size of the mining jetpack, it now fits in backpacks. The capacity of the jetpack has been reduced as well, however.
    • -
    • Removed resonator from the mining voucher redemption. Replaced it with a mining drill.
    • -
    - -

    08 October 2014

    -

    Cheridan updated:

    -
      -
    • Flash mechanics changed. Instead of a knockdown effect, it will cause a stumbling effect. This includes area-flashing. The five-use-per-minute limit has been removed. "Synthetic" flashes made in the protolathe are now normal flashes.
    • -
    -

    Paprika updated:

    -
      -
    • Added a unique shield to the Head of Security's locker. It can be concealed for storage and activated like an energy shield, but functions like a riot shield. It can also be made at the protolathe.
    • -
    • Marauders: Due to your extremely great performance as of late, we've added a new equipment room on Mother Base. A lot of your equipment has been moved to this room, as well as some new equipment added onto the Mothership. Take some extra time to familiarize yourself with the placement of your equipment.
    • -
    • Oh, and you guys have a space carp now too.
    • -
    -

    Paprka updated:

    -
      -
    • Added jumpsuit adjusting. Adjust your jumpsuit to wear it more casually by rolling it down or roll up those sleeves of that hard-worn suit!
    • -
    • Added a grey alternative to the detective's suit and trenchcoat. Now you can be a noir private investigator!
    • -
    -

    Tkdrg updated:

    -
      -
    • Space Station 13 has been deployed with transit tube dispensers. Central Command encourages the engineering department to repair and improve the station using this equipment.
    • -
    - -

    05 October 2014

    -

    Ikarrus updated:

    -
      -
    • Character Save Files will now remember Species.
    • -
    -

    Miauw updated:

    -
      -
    • Added 5 new maintenance ambience tracks, made by Cuboos.
    • -
    -

    Nobalm updated:

    -
      -
    • Added examine descriptions to twenty eight objects.
    • -
    -

    Paprika updated:

    -
      -
    • Due to some payroll cuts affecting lower-rank crewmembers on Space Station 13, we fear that uprisings and mutinies might be approaching. To help defend themselves, all heads of staff have been given telescopic batons to subdue attackers should they be assaulted during their shifts.
    • -
    • Toolbelts can now hold pocket fire extinguishers. Atmos technicians spawn with them.
    • -
    • Remember those magboots we had our undercover agents steal? Well we've finally reverse engineered them. Not only that, but we gave them a killer paintjob. They will be available in the uplinks of boarding parties we send out to Nanoscum stations.
    • -
    • Listen up, Marauders! The Syndicate has recently cut back funding into boarding parties. What this means is no more hi-tech fancy energy guns. We've had to roll back to using cheaper, mass-produced automatic shotguns. But in retrospect, could this possibly be a downgrade?
    • -
    - -

    01 October 2014

    -

    Cheridan updated:

    -
      -
    • Experienced smugglers have joined the Syndicate, adding their bag of tricks to its arsenal. These tricky pouches can even fit under floor plating!
    • -
    -

    Ikarrus updated:

    -
      -
    • Adds Gang War, a new game mode still in alpha development.
    • -
    -

    Incoming5643 updated:

    -
      -
    • After a public relations nightmare in which a horde of 30 assistants violently dismembered a sole commander the revolution has begin tactically reducing their initial presence in stations with weak command structures. Should stations add to their command staff during the shift additional support will be provided.
    • -
    • Too many instances of crying CMOs hiding in the lockers of supposedly secured revoulutionary stations has lead to a crackdown on revolutionary policy. You must kill or maroon the entire command staff, reguardless of when they reached the station.
    • -
    • Intense study into the underlying structure of the universe has revealed that everything fits into a massive SPACECUBE. This deep and profound understanding has led to a revolution in cross surface movement, and spacemen can look forward to a new era of predictable and safe space-fairing.
    • -
    -

    Jordie0608 updated:

    -
      -
    • Grille damage update, humans now deal less unarmed damage to grilles while projectiles and items deal more.
    • -
    • Replaced all AI turrets with porta-turrets that work on LoS instead of area and can be individually configured
    • -
    -

    Miauw updated:

    -
      -
    • Voice changer masks work again.
    • -
    • You can now turn voice changer masks on/off by activating them in your hand. They start off.
    • -
    • The amount of TC has been increased to 20, but the price of all items has been doubled as well
    • -
    • With this, the prices of stealthy items has been slightly decreased and the prices of offensive items slightly increased (+/- 1 TC)
    • -
    -

    RemieRichards, JJRcop updated:

    -
      -
    • New research in the area of robotics has been published on Maintenance Drones, little robots capable of repairing and improving the station. Unfortunately, all of the research was lost in a catastrophic server fire, but we know they can be made, so it's up to you to re-discover them! Make us proud!
    • -
    -

    phil235 updated:

    -
      -
    • Changed all clone damage descriptions to use the term cellular damage to avoid confusion with genetics mutations.
    • -
    - -

    07 September 2014

    -

    Gun Hog updated:

    -
      -
    • Nanotrasen scientists have released a Heads-Up-Display (HUD) upgrade for all AI and Cyborg units! Cyborgs have had Medical sensors and a Security datacore integrated into their core hardware, replacing the need for a specific module.
    • -
    • AI units are now able to have suit sensor or crew manifest data displayed to them as a visual overlay. When viewing a crewmember with suit sensors set to health monitoring, the health status will be available on the AI's medical HUD. In Security mode, the role as printed on the crewmember's ID card will be displayed to the AI.
    • -
    • Any entity with a Security or Medical HUD active will recieve appropriate messages on that HUD.
    • -
    -

    Ikarrus updated:

    -
      -
    • Server Operators: A new config option added to restrict command and security roles to humans only. Simply add/uncomment the line ENFORCE_HUMAN_AUTHORITY in game_options.txt. -
    • Players: To check if this config option is enabled on your server, type show-server-revision into the game's command line. -
    • -
    - -

    06 September 2014

    -

    Ikarrus updated:

    -
      -
    • Tampered supply ordering consoles can now order dangerous devices directly from the Syndicate for 140 points. -
    • Securitrons line units will no longer arrest individuals without IDs if their faces can still be read. -
    • Enemy Agent ID cards have been reported to be able to interfere with the new securitron threat assessment protocols. -
    • The Syndicate base has been modified to only allow the leading operative to launch the mission. -
    • -
    - -

    04 September 2014

    -

    KyrahAbattoir updated:

    -
      -
    • All the objects found in BoxStation maintenance are now randomized at round start.
    • -
    - -

    03 September 2014

    -

    Ikarrus updated:

    -
      -
    • Cost of Syndicate bombs increased to 6 telecrystals.
    • -
    -

    JStheguy updated:

    -
      -
    • Many new posters have been added.
    • -
    - -

    01 September 2014

    -

    ChuckTheSheep updated:

    -
      -
    • Adds preference toggle for intent selection mode. -
    • Direct selection mode switches intent to the one you click on instead of cycling them. -
    • -
    -

    Ikarrus updated:

    -
      -
    • New more detailed End-Round report. -
    • Removes count of readied players from the lobby. -
    • -
    -

    Jordie0608 updated:

    -
      -
    • Virology has been made the right color.
    • -
    -

    Miauw updated:

    -
      -
    • A major rework of saycode has been completed which fixes numerous issues and improves functionality. -
    • Please report any issues you notice with any form of messaging to Github. -
    • -
    - -

    31 August 2014

    -

    Tokiko1 updated:

    -
      -
    • Adds two new hairstyles.
    • -
    - -

    30 August 2014

    -

    Ikarrus updated:

    -
      -
    • Space Station 13 has been authorized to requisition additional Tank Transfer Valves from Centcom's supply lines for the price of 60 cargo points.
    • -
    - -

    26 August 2014

    -

    Ikarrus updated:

    -
      -
    • Security forces are advised to increase scrutiny on personnel coming into contact with AI systems. Central Intelligence suggests that Syndicate terrorist groups may have begun targeting our AIs for destruction. -
    • For the preservation of corporate assets, Central Command would like to remind all personnel that evacuating during an emergency is mandatory. We suspect that terrorist groups may be attempting to abduct marooned personnel who failed to evacuate. -
    • R&D; teams have released an urgent update to station teleporters. To eliminate the risk of mutation, personnel are advised to calibrate teleporters before attempting each use. -
    • Centcom has approved the Captain's request to rig the display case in his office with a burglar alarm. Any attempts to breach the case will now trigger a lockdown of the room. -
    • **Crew Monitoring Consoles now scan their own Z-level for suit sensors, instead of only scanning Z1. -
    • **Server operators can now set a name for the station in config.txt. Simply add the line "STATIONNAME Space Station 13" anywhere on the text file. Replace Space Station 13 with your station name of choice.
    • - -
    - -

    24 August 2014

    -

    Ikarrus updated:

    -
      -
    • Ore redemption machine can now smelt plasteel.
    • -
    • Mulebot speed has been vastly increased by up to 300%.
    • -
    • Removed exploit where false walls can be used to cheese the AI chamber's defenses
    • -
    - -

    21 August 2014

    -

    Ikarrus updated:

    -
      -
    • The Phase Shift ability will no longer instantly gib players. Instead, they will be knocked out for a few seconds. Mechas will be damaged.
    • -
    • The Phase Slayer ability will no longer instantly gib players. Instead, they will be dealt 190 brute damage. Mechas will be dealt 380 damage.
    • -
    • ADMIN: Most Event buttons have been moved out of the secrets menu and into a Fun verb.
    • -
    - -

    20 August 2014

    -

    Cheridan updated:

    -
      -
    • Three new shotgun shells added. Create them by first researching and printing an unloaded tech shell in R&D.; Afterwards, use table-crafting with the appropriate components with a screwdriver in-hand.
    • -
    • Meteorshot: tech shell + compressed matter cartridge + micro(or better) manipulator.
    • -
    • Pulse Slug: tech shell + advanced capacitor + ultra micro-laser.
    • -
    • Dragonsbreath: tech shell + 5 phosphorus (in container).
    • -
    • Incendiary rounds now leave a blazing trail as they pass. This includes existing incendiary rounds, new dragonsbreath rounds, and the Dark Gygax's carbine.
    • -
    - -

    19 August 2014

    -

    Ikarrus updated:

    -
      -
    • Brig cells and labour shuttle have both been modified to send a message to all security HUDs whenever a prisoner is automatically released.
    • -
    • The labour camp has been outfitted with a points checking console to allow prisoners to check their quota progress easier and better explain the punishment system of forced labour.
    • -
    - -

    18 August 2014

    -

    Iamgoofball updated:

    -
      -
    • 25 new hairstyles have been added.
    • -
    - -

    15 August 2014

    -

    AndroidSFV updated:

    -
      -
    • AI photography has been extended to Cyborgs. While connected to an AI, all images taken by cyborgs will be placed in the AI's album, and viewable by the AI and all linked Cyborgs.
    • -
    • When a Cyborgs AI link wire is pulsed, the images from the Cyborgs image album will be synced with the AI it gets linked to.
    • -
    • Additonally, Cyborgs are able to attach images to newscaster feeds from whichever album is active for them. Cyborgs are also mobile, inefficent, printers of same images.
    • -
    - -

    11 August 2014

    -

    Ikarrus updated:

    -
      -
    • Boxstation map updates:
      - -Singularity engine walled from from outer space
      - -Shutters for exterior Science windows
      - -Teleporter board moved from RD's Office to Tech Storage now that the teleporter can be built again.
      - -Security Deputy Armbands (red) added in HoS's Office



    • -
    - -

    14 July 2014

    -

    Miauw updated:

    -
      -
    • Added a new mutetoxin that can be made with 2 parts uranium, 1 part water and 1 part carbon and makes people mute temporarily
    • -
    • Parapens were renamed to sleepy pens and now contain 30 units of mutetoxin and 30 units of sleeptoxin instead of zombie powder.
    • -
    • C4 can no longer be attached to mobs
    • -
    • Reduced the C4 price to 1 telecrystal
    • -
    - -

    07 July 2014

    -

    Firecage updated:

    -
      -
    • We, of the NanoTrasen Botany Research and Developent(NTBiRD), has some important announcements for the Botany staff aboard our stations.
    • -
    • We have recently released a new strain of Tower Cap. It is now ensured that more planks can be gotten from a single log.
    • -
    • Head Scientist [REDACTED] is thanked for his new strain of Blood Tomatoes. It now not only contains human blood, but also chunks of human flesh!
    • -
    • We have also discovered a way to replant the infamous Cash Trees and 'Eggy' plants. We can now harvest their seeds, and the rare products are inside the fruit shells.
    • -
    • Similar to the new variety of Tower Caps, it is now possible to get various grass flooring depending on the plants potency!
    • -
    • Our sponsors at Knitters United has released a new variation of the botany Aprons and Coveralls which can hold a larger variety of items!
    • -
    • A new version of Plant-B-Gone was produced which are much more lethal to plants, yet at the same time has no extra effect on humans besides the norm.
    • -
    -

    Paprika updated:

    -
      -
    • Tweaked mining turf mineral droprates and reverted mesons to the 'old' style of mesons. This means mesons will be more powerful with the added side effect of not being able to track individual light sources through walls and such. This is a trial run; please provide feedback on the /tg/ codebase section of the forum.
    • -
    - -

    05 July 2014

    -

    Firecage updated:

    -
      -
    • Recently the Space Wizard Federation, with some assistance from the Cult of Nar-Sie, recently created a new strain of Killer Tomato. A sad side effect is this effected all current and future Killer Tomato strains in our galaxy. They are now reported to be extremely violent and deadly, use extreme caution when growing them.
    • -
    - -

    03 July 2014

    -

    Miauw updated:

    -
      -
    • Added slot machines to the game
    • -
    • Slot machines use reels. All prizes except for jackpots can be won on all lines
    • -
    • Simply put a coin into one of the slot machines in the bar to play!
    • -
    • Slot machines can also be emagged.
    • -
    - -

    01 July 2014

    -

    Ikarrus updated:

    -
      -
    • Central Security has approved an upgrade of the Securitron line of bots to a newer model.
      Highlights include:
    • -
    • -An optional setting to arrest personnel without an ID on their uniform (Disabled by default)
    • -
    • -An optional setting to notify security personnel of arrests made by the bots (Enabled by default)
    • -
    • -A new "Weapon Permit" access type that securitrons will use during their weapons checks. Personnel who work with weapons will be granted this access by default. More can be assigned by the station's Head of Security and Personnel.
    • -
    • -A more robust threat assessment algorithm to improve accuracy in identifying perpetrators.
    • -
    -

    Rolan7 updated:

    -
      -
    • Fixed the irrigation system in hydroponics trays. Adding at least 30 units of liquid at once will activate the system, sharing the reagents between all connected trays.
    • -
    • Changelings can communicate while muzzled or monkified, and being monkified doesn't stop them from taking human form.
    • -
    • Mimes cannot break the laws of physics unless their vow is currently active.
    • -
    • Trays are rewritten to make sense and so borgs can actually use them. Service borgs can discretely carry small objects, hint hint. The items are easily knocked out of them.
    • -
    - -

    20 June 2014

    -

    Ikarrus updated:

    -
      -
    • The 'Enter Exosuit' button was removed, and you have to click + drag yourself to enter a mech now; like you would to enter a disposal unit.
    • -
    - -

    12 June 2014

    -

    Cheridan updated:

    -
      -
    • NT Baton Refurbishment Team Notice: 'Released' option in security records has been renamed 'Discharged', and the sechud icon has been changed from a blue R to a blue D. Stop beating your released prisoners, dummies; they're not revheads.
    • -
    • NT Entertainment Department Notice: The prize-dispensing mechanism in Arcade machines has been replaced with a cheaper gas-powered motor. It should still be completely safe, unless an electromagnetic field disrupts it!
    • -
    • Pill code tweaked. In short, you can feed monkeys pills now #whoa
    • -
    • Casings ejected from guns will now spin #wow
    • -
    - -

    11 June 2014

    -

    Ikarrus updated:

    -
      -
    • Having the nuke disk will no longer prevent you from using teleporters or crossing Z-levels. Leaving the Z-level however, will cause you to "suddenly lose" the disk.
    • -
    • Pulled objects will now transition with you when as you transition Z-levels in space.
    • -
    -

    Malkevin updated:

    -
      -
    • IEDs have been removed
    • -
    • Firebombs have been added
    • -
    • They're as reliable and predictable as you would expect from a soda can filled with flammable liquid and set off with an igniter contected to two wires. Use your branes and take proper precautions or leave a charred corpse, your choice.
    • -
    - -

    06 June 2014

    -

    Gun Hog updated:

    -
      -
    • Nanotrasen programmers have discovered a potential exploit involving a station's door control networks. With sufficient computing power, the network can be overloaded and forced to open or bolt closed every airlock at once.
    • -
    • Some reports suggest that the latest firmware update to Artifical Intelligence units installed in our research stations may contain this exploit. Any such reports that state that should a station's AI unit "malfunction", it may gain the ability to use this exploit to initate a full lockdown of the station. Fire locks and blast doors are also said to be affected.
    • -
    • Nanotrasen officially holds no validity to these reports. We recommend that station personnel disregard such rumors.
    • -
    - -

    20 May 2014

    -

    Kelenius updated:

    -
      -
    • After the years of extensive research into xenobiology, and thousands of scientists lost to the slimes, we have finally come to admitting that we don't have a clue how they work. However, we've outlined a few facts, and managed to breed a new kind of slimes. They will be shipped to your station on the next shifts. They are different from the ones they are used to in the following:
    • -
    • Their sight is better than ever, and now they can finally see things that are not directly pressed against them. Beware, they may appear more aggressive!
    • -
    • Their memory has also become better, and they will now remember the people who fed them. As a note, you need to grab the monkey or push it to show to the slime that you're giving it to them, and it's not just walking in.
    • -
    • Apparently, not only we have studied them, but they have also studied us. Slimes are now capable of showing various emotions, mimicking humans. Use it to your advantage.
    • -
    • There are reports of slimes showing signs of sentience. Further research is recommended.
    • -
    • One of the reported signs is their speech capability. Following facts have been gathered: they talk more often to those who feed them; they react to being called by the number, but 'slimes' is also acceptable; they are able to understand being ordered to "follow" someone, or "stop". There is a report of slime releasing the assistant after a scientist shouted at it, and then calmly ordered a slime to stop.
    • -
    • We've made a modification of a health scanner that is intended for the use on slimes. Two are available in the smartfridge.
    • -
    • We've come to a conclusion that 5 units of reagents are not necessary to cause slime core reactions. You actually only need one unit.
    • -
    - -

    16 May 2014

    -

    Menshin updated:

    -
      -
    • Thanks to Nanotrasen's Engineering division, the power wiring of the station has a received a complete overhaul. Here are the highlight features in CentCom report :
    • -
    • Improved way of connecting cables! Finished is the time of "laying and praying" : it's now as simple as matching ends of each cables!
    • -
    • Unified way of connecting machines! Every machine is connected to a powernet through a node cable (it still needs to be anchored to receive power though)!
    • -
    • Lots of improvements in the cable cutting tools! Gone is the odd magic of physically separated yet still connected powernets (contact CentCom Engineering Division if you still witness something weird, we always have a fired form ready for our engineers!)!
    • -
    • Any conscientious (or not!) Station Engineer may check an "updated wiring manual" at http://www.tgstation13.org/wiki/Wiring#Power_Wires
    • -
    - -

    14 May 2014

    -

    Ikarrus updated:

    -
      -
    • A recent breakthrough in Plasma Materials Research has led to the development of a stronger, tougher plasteel alloy that can better resist extreme heat by up to four times. A live demonstration preformed during a press conference earlier today showed a segment of reinforced wall resisting an attack by Thermite. The corporation also announces that upgrades to its existing stations is already underway.
    • -
    - -

    07 May 2014

    -

    /Tg/station Code Management updated:

    -
      -
    • /tg/station code is now under a feature freeze until 7th June 2014. This means that the team will be concentrating on fixing bugs instead of adding features for the month.
    • -
    • You can find more information about the feature freeze here. http://tgstation13.org/phpBB/viewtopic.php?f=5&t;=273
    • -
    • This is the perfect time to report bugs, which you can do so here. https://github.com/tgstation/-tg-station/issues/new
    • -
    - -

    30 April 2014

    -

    Giacom updated:

    -
      -
    • You now have to give a reason when calling the shuttle.
    • -
    • The amount of time it takes for the shuttle to refuel is now a config option, the default is 20 minutes.
    • -
    -

    Gun Hog updated:

    -
      -
    • Certain Enemies of the Corporation have discovered a critical exploit in the firmware of several NanoTrasen robots that could prevent the safe shutdown of units corrupted by illegally modified ID cards, dubbed "cryptographic sequencers".
    • -
    • NanoTrasen requires more research into this exploit, this we have issued a patch for AI and Cyborg software to simulate this malfunction. All NanoTrasen AI units are advised to only allow testing in a safe and contained environment. The robot can safely be reset at any time.
    • -
    • Unfortunately, a robot corrupted by a "cryptographic sequencer" still cannot be reset by any means. NanoTrasen urges regular maintenance and care of all robots to reduce replacement costs.
    • -
    - -

    27 April 2014

    -

    Ikarrus updated:

    -
      -
    • NT Human Resources announces an expansion of the List of Company-Approved Hair Styles, as well as more relaxed gender restrictions on hair styles. Check with your local company-sponsored hairstylist to learn more.
    • -
    - -

    22 April 2014

    -

    Ikarrus updated:

    -
      -
    • ID Computers have been modified to allow Station Heads of Staff to assign and remove access to their departments, as well as stripping the rank of their subordinates. An ID computer on the bridge is available for the use of this function.
    • -
    - -

    20 April 2014

    -

    Gun Hog updated:

    -
      -
    • NanoTrasen Emergency Alerts System 4.20 has been released!
    • -
    • In the unfortunate event of any nuclear device being armed, the station will enter Code Delta Alert.
    • -
    • Should the nuclear explosive be disarmed, the station shall automatically return to its previous alert level.
    • -
    -

    Steelpoint updated:

    -
      -
    • A new AI satellite has been constructed in orbit of Space Station 13!
    • -
    • The satellite exclusivly is used to hold a station's Artifical Intelligence Unit, the satellite contains a miried of turret and motion sensor defences. A transit tube network is used to connect the satellite to the station, with the transit room being located at engineering south of the engi escape pod.
    • -
    • The AI Upload however has been moved north slightly and is connected directly to the bridge.
    • -
    • In addition, the Gravity Generator has been relocated from its prior position in engineering to the location of the old AI Upload, increasing its defence and logical positioning.
    • -
    - -

    11 April 2014

    -

    Jordie0608 updated:

    -
      -
    • Wood planks can be used to make wood walls and airlocks; flammability not included
    • -
    - -

    10 April 2014

    -

    Ikarrus updated:

    -
      -
    • Centcom officials have announced a new initiative to combat misuse of their Emergency Shuttle Service. After the shuttle has been recalled several times over the course of a simple work shift, Centcom will attempt to trace the signal origin and pinpoint its source for station authorities.
    • -
    -

    Steelpoint updated:

    -
      -
    • Thanks to Nanotrasen's Construction division, the brig has recieved a overhaul in its design, to increase ease of movement, including an addition of a "prisioner release room" and a insanity ward. -
    • Furthing concerns among commentators, Nanotrasen has shipped out additional security equipment to station armories, including Riot Shotguns, tear gas grenades, additional securitron units and military grade Ion Guns.
    • -
    • JaniCo have released a new unique product called the JaniBelt. Capable of holding most standard issue janitorial equipment, designed to help relive inventory management among station janitors. In addition the Jani Water Tank has had its reserve of space clenaer increased to 500 units, up from 250. -
    • -
    -

    Validsalad updated:

    -
      -
    • After concerns raised by security personel, new armor has been shipped that covers the lower waist and readjusts the helmet for comfort. -
    • In addition, the aging riot shield has been replaced with a newer, more modern, apperance. -
    • -
    - -

    03 April 2014

    -

    Ikarrus updated:

    -
      -
    • NT AI Firmware version 2554.03.03 includes a function to notify the master AI when a new cyborg is slaved to it.
    • -
    - -

    02 April 2014

    -

    Giacom updated:

    -
      -
    • The syndicate suit is now black and red, because black and red is the new red.
    • -
    • The Ruskie DJ Station now has a classy orange syndicate suit.
    • -
    • Security officers have been equipped with the latest in flashlight technology. You can find a SecLite™ inside your security belt or you can dispense one from the security vending machine.
    • -
    -

    Ikarrus updated:

    -
      -
    • Nanotrasen Construction division is pleased to announce the unveiling of our brand now state-of-the-art Space Station 13 v2.1.3!
    • -
    • -Scaffolding used during construction has been repurposed as an expanded maintenance around the station.
    • -
    • -Our new Emergency Transport Shuttle Mk III will be making its debut in times of crisis. Includes a new cargo area and extra security features.
    • -
    • -A redesigned brig will give security staff more peace of mind with added security features
    • -
    • -The armory is now protected by a motion alarm.
    • -
    • -The armory is now equipped with security hardsuits.
    • -
    • -A new command EVA wing has been added to EVA Storage. Station heads of staff will be able to make use of suits stored here.
    • -
    • -A new garden area will be made publicly available for everyone to enjoy some R&R; during their company-endorsed break periods
    • -
    • -A new Testing Lab has been added to the Science department for any field experiments that need to be run.
    • -
    • -The mining ore redemption machine has been relocated to the Cargo Delivery Office.
    • -
    - -

    01 April 2014

    -

    Aranclanos updated:

    -
      -
    • Made combat more hardcore for hardcore players like myself. This won't be reverted.
    • -
    -

    Malkevin updated:

    -
      -
    • Sacrifice Cult - Cult has received a massive overhaul to how it works, focusing more on cult magics and sacrificing unbelievers. The most important changes are:
    • -
    • Cult starts off with alot more cultists, 6 cultists below 30 players and 9 above. The HoP can no longer be a round start cultist but is still convertible.
    • -
    • Cultists start off with join, blood, self, and hell. These give the runes for the sacrifice and convert.
    • -
    • Conversions now require three cultists and converts no longer reward words, words must be obtained via sacrifice
    • -
    • Sacrificing players traps their soul in a soul stone, which can then be used on construct shells to implant the souls in them
    • -
    • Constructs shells can be summoned via a new rune (travel, hell, technology)
    • -
    • You can no longer convert the sacrifice target, you dozzy sods
    • -
    • Summoning Narsie when she is not an objective leads to !!FUN!!
    • -
    • Wrote a system to allow all mob types to be sacrificable - currently only corgis are in the new system
    • -
    • Holy Water will DECONVERT cultists, takes around 35 units and two minutes to succeed
    • -
    • Hitting a mob that contains holy water with a tome will convert that water to unholy water, conversely hitting any container that contains unholy water with a bible as chaplain will 'cleanse' the taint.
    • -
    • Unholy water works like a combination synaptazine and hyperzine, with a twist of branes dimarge and highly toxic to non-cultists
    • -
    • Cargo can order a religious supplies crate - it contains flasks of holy water, candles, bibles, and robes
    • -
    • Cultists have an innate ability to communicate to the cult hive mind (BE AWARE - THIS DOES A LOT OF DAMAGE), cultists can also communicate via the new Commune option on their tomes (the Read Tome option has been shifted under the Notes option)
    • -
    -

    MrStonedOne updated:

    -
      -
    • Cyborgs can now use AI click shortcuts. (shift click on doors opens them, etc) (including ones added below)
    • -
    • New silicon click shortcut: Control+Shift click on doors toggles access override
    • -
    • New silicon click shortcut: Control click turret controls toggles them on or off
    • -
    • New silicon click shortcut: Alt click turret controls toggles lethal on or off
    • -
    • Cyborg hotkey mode was massively improved. 1-3 selects module slot, q unloads the active module. use hotkeys-help as cyborg for more details
    • -
    - -

    31 March 2014

    -

    Ikarrus updated:

    -
      -
    • Fabricator blueprints for cyborg parts have been updated to allow the debugging of cyborg units prior to boot. To access the debug functions, assemble a cyborg following standard procedure. Before inserting the MMI, use a multitool on the cyborg body. Note that this update also moves designation data into the system files, so pens can no longer be used to name cyborgs.
    • -
    -

    MrPerson updated:

    -
      -
    • Toggling the "Play admin midis" preference will pause any playing songs. Turning midis back on will resume the current song where it was.
    • -
    • If there's a song playing while you have midis off and you then turn midis on, the current song will begin playing for you.
    • -
    - -

    28 March 2014

    -

    Aranclanos updated:

    -
      -
    • Workaround with the click cooldowns. They should feel faster. If you think that anything needs a click cooldown (like grilles, mobs, etc.), report it to me.
    • -
    • Here's the fun part, this is a test for the community and players, I hope I won't be forced to revert this and hear "this is why we can't have nice things". Again, if anything needs a cooldown, report it to me. Have fun with your fast clicks spessmans.
    • -
    - -

    25 March 2014

    -

    Ikarrus updated:

    -
      -
    • A security review committee has approved an update to all Nanotrasen airlocks to better resist cryptographic attacks by the enemy. -

      *New internal wiring will be able to withstand attacks, and panel wires will no longer be left unusable after an attack. -
      *Welding tools will now be able to cut through welded doors that have been damaged. -
      *Damaged electronics are now removable and replaceable following standard procedure. -
      *Airlocks will not be able to operate autonomously until the electronics are replaced.




    • -
    • Hair sprites have been given a visual lift. For best results, set your hair color to be slightly lighter than how you want it to look. For dark hair, do not use a color darker than 80% black.
    • -
    - -

    22 March 2014

    -

    Giacom updated:

    -
      -
    • Gravity is no longer beamed from CentCom! Instead, there is a new gravity generator stored near Engineering that will provide all the gravity for the station and the z level. Please remember that it gives off a lot of radiation when charging or discharging, so wear protection.
    • -
    -

    MrPerson updated:

    -
      -
    • Added a new, somewhat experimental system to delete things. This is basically a port from /vg/, so big thanks to N3X15.
    • -
    • As a result, bombs and the singularity should be much less laggy.
    • -
    • There may be issues with "phantom objects" or other problems with stuff that's suppoed to be deleted or objects interacting with deleted objects. Please report any issues right away!
    • -
    - -

    18 March 2014

    -

    Ikarrus updated:

    -
      -
    • NT R&D; releases AI Patch version 2553.03.18, allowing all Nanotrasen AIs to override the access restrictions on any airlock in case of emergency. Nanotrasen airlocks have been outfitted with new amber warning lights that will flash while the override is active. Should maintenance teams need to restore an airlock's restrictions without using the AI, pulsing the airlock's ID Scanner wire will reset the override.
    • -
    - -

    17 March 2014

    -

    Giacom updated:

    -
      -
    • Machines that had their programming overriden by a Malf AI will no longer attack loyal cyborgs; they will still attack cyborgs that aren't loyal, to the Malf AI that hacked them, though.
    • -
    • You only require a single unit of blood to mutate viruses now, instead of 5.
    • -
    - -

    15 March 2014

    -

    Steelpoint/Validsalad updated:

    -
      -
    • After a review with CentCom, all Security Officers will now begin their shifts with a Stun Baton in their backpack. To avoid inflating costs however all Stun Batons have been removed from Security lockers except from the brig.
    • -
    • After decades of usage CentCom has replaced the Security Uniform, Armor, Belt and Helmet with a newer, more modern design.
    • -
    - -

    14 March 2014

    -

    Ikarrus and Nienhaus updated:

    -
      -
    • Nanotrasen Corporate announced a revised dress codes primarily affecting senior station officers. A new uniform for Heads of Personnel will be shipped out to all NT Research stations.
    • -
    - -

    12 March 2014

    -

    Yota updated:

    -
      -
    • Cameras finally capture the direction you are facing.
    • -
    - -

    10 March 2014

    -

    Giacom updated:

    -
      -
    • Added two new plasma-level disease symptoms, both are very !FUN! and mess with your genetics.
    • -
    • Virologists now only need to use a single unit of virus food, mutagen or plasma to generate symptoms. You can take a single unit by using a dropper, if you change its unit transfer amount in the object tab..
    • -
    • Changed the map to make it harder to escape from the Labor Camp. Please continue using it.
    • -
    -

    Miauw updated:

    -
      -
    • Added changeling space suits. These allow changelings to survive in space, internals are not needed. They do not provide any sort of armor and slow your chemical regeneration.
    • -
    - -

    05 March 2014

    -

    Various Coders updated:

    -
      -
    • Ling rounds are LINGIER, with more lings at a given population.
    • -
    • Many simple animals can ventcrawl, including bats. All ventcrawlers must alt-click to ventcrawl.
    • -
    • An automatic tool to store and replace machine parts has been added to R&D.;
    • -
    • Most stuns have been reduced in from 10+ to 5 ticks in duration.
    • -
    • Shoes no longer speed you up.
    • -
    • Added fancy suits, which can be orderd from cargo.
    • -
    • Added sombrerors and ponches.
    • -
    • Cuff application time reduced 25%.
    • -
    • Fire will cause fuel tanks to explode.
    • -
    • Mutagen has been reduced in lethality. Notably, 15 units are not guaranteed to crit the recipient.
    • -
    - -

    03 March 2014

    -

    ChuckTheSheep updated:

    -
      -
    • Round-end report now shows what items were bought with a traitor's or nuke-op's uplink and how many TCs they used.
    • -
    -

    Drovidi Corv updated:

    -
      -
    • Facehuggers no longer die to zero-force weapons or projectiles like lasertag beams.
    • -
    -

    Incoming5643 updated:

    -
      -
    • Improved blob spores to zombify people adjacent to their tile.
    • -
    • If a hand-teleporter is activated while you're stuck inside a wall, you'll automatically go through it.
    • -
    -

    Miauw updated:

    -
      -
    • Decreased the lethality of Mutagen in small doses.
    • -
    -

    TZK13 updated:

    -
      -
    • Added Incendiary Shotgun Shells made at a hacked autolathe; Xenos be wary.
    • -
    -
    -

    26 February 2014

    -

    Incoming5643 updated:

    -
      -
    • Color blending Kitty Ears have returned.
    • -
    -
    - -
    -

    25 February 2014

    -

    Incoming5643 updated:

    -
      -
    • Colored burgers! Include a crayon in your microwave when cooking a burger and it'll come out just like a Pretty Pattie.
    • -
    • Fixed AI's being able to interact with syndicate bombs.
    • -
    -
    - -
    -

    24 February 2014

    -

    Ergovisavi updated:

    -
      -
    • Added Advanced Mesons and Night Vision Goggles to the protolathe.
    • -
    -

    Giacom updated:

    -
      -
    • Silicons no longer stop statues from moving when in sight.
    • -
    • Increased the health of statues.
    • -
    • Increased the range of statues's blinding spell.
    • -
    -

    HornyGranny updated:

    -
      -
    • Reduced the range of Violin notes.
    • -
    • Low quality violin midi-notes replaced with better .ogg-notes.
    • -
    -

    Incoming5643 updated:

    -
      -
    • Improved the Syndicate Implant bundle to contain freedom, uplink, EMP, adrenalin and explosive implanters.
    • -
    • Added Mineral Storeroom to R&D; containing the Ore Redemption Machine; no more assistants stealing your ore in the open hallway.
    • -
    -

    Miauw updated:

    -
      -
    • No more removing cursed horseheads.
    • -
    -

    Razharas updated:

    -
      -
    • Fixed infinite telecrystal exploit.
    • -
    -
    - -
    -

    19 February 2014

    -

    Aranclanos updated:

    -
      -
    • Removed the chance of your hat falling off when slipping.
    • -
    -

    Perakp updated:

    -
      -
    • Added Iatot's cyborg module selection transformation animations.
    • -
    -
    - -
    -

    17 February 2014

    -

    Ergovisavi updated:

    -
      -
    • Mining has been significantly overhauled. Hostile alien life has infested the western asteroid! Miners are given an equipment voucher to obtain equipment to protect themselves. There is a spare voucher in the HoP's office, should someone want to switch to mining mid-shift.
    • -
    • The Ore Redemption Machine has been added just outside of the Science wing. Ore goes in, Sheets go out, and points are tallied on the machine. Insert your ID to claim points, then spend them on goods at Mining Equipment Lockers. You require specific accesses to tell the Ore Redemption Machine to unload its sheets.
    • -
    • Should you not care for being eaten alive by horrible alien life, it is suggested you stick to the eastern asteroid, where there is no hostile alien life... though the yield on ore is not as good.
    • -
    • Most ore is no longer visible to the naked eye. You must ping it with a Mining Scanner (Available in all mining lockers) to locate nearby ore. Make sure to equip your mesons first, or it won't be visible.
    • -
    • Mesons no longer remove the darkness overlay, you must properly light your environment. Hull breaches to space can still be clearly seen, and it will still protect you from the singulo.
    • -
    • Mineral spawn rates have been significantly tweaked to cut down on unnecessary inflation of mineral economy.
    • -
    • The asteroid no longer has ambient power on the entire asteroid. AI's who go onto asteroid turf will slowly die of power loss. Mining outposts are unaffected.
    • -
    • Fixed an issue where projectiles shot by simple mobs or thrown would hit multiple times.
    • -
    -

    Fleure updated:

    -
      -
    • Reduced chicken crates to contain 1-3 chicks, down from 3-6
    • -
    • Increased fertile chicken egg chance from 10% to 25%
    • -
    -

    Yota updated:

    -
      -
    • Photograph now rendered crisp and clean, so that we may enjoy them in their 0.009 megapixel goodness.
    • -
    • Cameras should now capture more of what they should, and less of what they shouldn't.
    • -
    -
    - -
    -

    09 February 2014

    -

    ADamDirtyApe updated:

    -
      -
    • The lawyer now spawns with a Sec Headset.
    • -
    -

    Demas updated:

    -
      -
    • Banana peel size is based on banana size.
    • -
    • Bigger peels slip for longer than smaller ones. Remember that produce size is based on potency.
    • -
    • The clown now spawns with a decent sized banana.
    • -
    • The banana mortar now shoots 65 potency peels.
    • -
    -

    Giacom updated:

    -
      -
    • A new hostile statue mob, can only move when not being observed, tends to break lights and cause blindness.
    • -
    -

    Incoming5643 updated:

    -
      -
    • Blob Zombies! When a Blob Spore moves over a dead human body it will infect the body and revive it as a more powerful varient of the spore. Has double the health and deals more damage.
    • -
    -

    Neerti updated:

    -
      -
    • Sec Belts can now hold Stun Batons.
    • -
    • Stun Batons now only take 10 seconds to fully recharge.
    • -
    -

    Razharas updated:

    -
      -
    • Tables can now be used as an alternative way to craft makeshift items. Simply click-drag table to yourself bring up a list.
    • -
    -

    adrix89 updated:

    -
      -
    • Spray Bottles can no longer wet up to three tiles with water.
    • -
    • Spray Bottles have a third higher release volume that wets a single tile.
    • -
    • Water slip times are reduced to the same stun times as soap.
    • -
    -
    - -
    -

    08 February 2014

    -

    MrPerson updated:

    -
      -
    • Added a NanoUI for the SMES
    • -
    -

    Razharas updated:

    -
      -
    • Adds more constructible and deconstructable machines!
    • -
    • Added constructible miniature chemical dispensers, upgradable
    • -
    • Sleepers are now constructible and upgradable, open and close like DNA scanners, and don't require a console
    • -
    • Cryogenic tubes are now constructible and upgradable, open and close like DNA scanners, and you can set the cryogenic tube's pipe's direction by opening its panel and wrenching it to connect it to piping
    • -
    • Telescience pads are now constructible and upgradable
    • -
    • Telescience consoles are now constructible
    • -
    • Telescience tweaked (you can save data on GPS units now)
    • -
    • Teleporters are now constructible and upgradable, the console has a new interface and you can lock onto places saved to GPS units in telescience
    • -
    • Teleporters start unconnected. You need to manually reconnect the console, station and hub by opening the panel of the station and applying wire cutters to it.
    • -
    • Biogenerators are now constructible and upgradable
    • -
    • Atmospherics heaters and freezers are now constructible and upgradable and can be rotated with a wrench when their panel is open to connect them to pipes. Screw the board to switch between heater and freezer.
    • -
    • Mech chargers are now constructible and upgradable
    • -
    • Microwaves are now constructible and upgradable
    • -
    • All kitchen machinery can now be wrenched free
    • -
    • SMES are now constructible
    • -
    • Dragging a human's sprite to a cryogenic tube or sleeper will put them inside and activate it if it's cryo
    • -
    • Constructible newscasters, their frames are made with autolathes
    • -
    • Constructible pandemics
    • -
    • Constructible power turbines and their computers
    • -
    • Constructible power compressors
    • -
    • Constructible vending machines. Screw the board to switch vendor type.
    • -
    • Constructible hydroponics trays
    • -
    • Sprites for all this
    • -
    • This update will have unforeseen bugs, please report those you find at https://github.com/tgstation/-tg-station/issues/new if you want them fixed.
    • -
    • As usual, machines are deconstructed by screwing open their panels and crowbarring them. While constructing machines, examining them will tell you what parts you're missing.
    • -
    -
    - -
    -

    05 February 2014

    -

    Yota updated:

    -
      -
    • Handling a couple flashlights will no longer transform you into the sun. Each light source will have deminishing returns.
    • -
    • Inserting lights into containers should no longer dim other lights.
    • -
    -
    - -
    -

    03 February 2014

    -

    Demas updated:

    -
      -
    • Changes windoor and newscaster attack messages to be consistent with windows and grilles. This removes the distracting boldness from windoor attack messages, which is reserved for userdanger, and names the attacker.
    • -
    • Thrown items now play a sound effect on impact. The volume of the sound is based on the item's throwforce and/or weight class.
    • -
    • The fireaxe now has 15 throwforce, when previously it had only 1. But why would you throw it away, anyway?
    • -
    • Projectiles now play a sound upon impact. The volume of the sound depends on the damage done by the projectile. Damageless projectiles such as electrodes have static volumes. Practise laser and laser tag beams have no impact sound.
    • -
    • Added sear.ogg for the impacts of damaging beams such as lasers. It may be replaced if player feedback proves negative.
    • -
    -
    - -
    -

    02 February 2014

    -

    Demas updated:

    -
      -
    • Attack sounds for all melee weapons! No more silent attacks.
    • -
    • The volume of an object's attack sound is based on the weapon's force and/or weight class.
    • -
    • Welders, lighters, matches, cigarettes, energy swords and energy axes have different attack sounds based on whether they're on or off.
    • -
    • Weapons that do no damage play a tap sound. The exceptions are the bike horn, which still honks, and the banhammer, which plays adminhelp.ogg. Surely nothing can go wrong with that last one.
    • -
    • When you tap someone with an object, the message now uses "tapped" or "patted" instead of attacked. The horn still uses HONKED, and the banhammer still uses BANNED.
    • -
    • You won't get the "armour has blocked an attack" message for harmless attacks anymore.
    • -
    • Adds 5 force to the lighter when it's lit. Same as when you accidentally burn yourself lighting it.
    • -
    • Removes boldness from item attack messages on non-human mobs. The attack is bolded for a player controlling a non-human mob. Now your eyes won't jump to the chat when it's Pun Pun who's being brutalised.
    • -
    • Blood will no longer come out of non-human mobs if the attack is harmless.
    • -
    • Adds a period at the end of the catatonic human examine message. That's been bugging me for years.
    • -
    • The activation and deactivation sounds of toy swords, energy swords and energy shields are slightly quieter. Energy swords and shields are now slightly louder than toys.
    • -
    • You can no longer light things with burnt matches.
    • -
    • Match, cigarette and lighter attack verbs, forces and damage types change based on whether the object is lit or not.
    • -
    • Fixes a bug with the energy blade that kept it at weight class 5 after it was deactivated. Who cares, it disappears upon deactivation.
    • -
    • Changes the welder out of fuel message slightly to be less fragmented.
    • -
    • Removes dead air from a lot of weapon sound effects to make them more responsive. In other words, the fire extinguisher attack sound will play a lot sooner after you attack than before.
    • -
    • Equalised the peak volumes of most weapon sounds to be -0.1dB in an attempt to make volumes based on force more consistent across different sounds.
    • -
    -
    - -
    -

    01 February 2014

    -

    Ergovisavi updated:

    -
      -
    • Walking Mushrooms will now attack and eat each other! They're all a little unique from each other, no two shrooms are exactly alike, and a better quality harvest means stronger Walking Shrooms. Pit them against each other for your entertainment.
    • -
    • Each mushroom will have a different colored cap to identify them. When mushrooms eat each other, they get stronger. The resulting mushroom will drop more slices when cut down to harvest, and will have better quality slices.
    • -
    • Don't hurt them yourself, though, or you'll bruise them, and mushrooms won't get stronger from eating a bruised mushroom. If your mushroom faints, feed it a mushroom such as a plump helmet to get it back on its feet. It will slowly regenerate to full health eventually.
    • -
    -
    - -
    -

    30 January 2014

    -

    Balrog updated:

    -
      -
    • Syndicate Playing Cards can now be found on the Syndicate Mothership and purchased from uplinks for 1 telecrystal.
    • -
    • Syndicate Playing Cards are lethal weapons both in melee and when thrown, but make the user's true allegiance to the Syndicate obvious.
    • -
    • Sprites are courtesy of Nienhaus.
    • -
    -

    Demas updated:

    -
      -
    • Adds thud sounds to falling over
    • -
    • Known bug: Thuds play when cloning initialises or someone is put into cryo. This will be fixed.
    • -
    -

    Ergovisavi updated:

    -
      -
    • Gibtonite, the explosive ore, can now be found on the asteroid. It's very hard to tell between it and diamonds, at first glance.
    • -
    • Gibtonite deposits will blow up after a countdown when you attempt to mine it, but you can stop it with an analyzer at any time. It makes for a good mining explosive.
    • -
    • The closer you were to the explosion when you analyze the Gibtonite deposit, the better the Gibtonite you can get from it.
    • -
    • Once extracted, it must be struck with a pickaxe or drill to activate it, where it will go through its countdown again to explode!
    • -
    • Explosives will no longer destroy the ore inside of asteroid walls or lying on the floor.
    • -
    -

    Miauw updated:

    -
      -
    • Adds changeling arm blades that cost 20 chems and do 25 brute damage.
    • -
    • Arm blades can pry open unpowered doors, replace surgical saws in brain removal, slice tables and smash computers.
    • -
    -

    MrPerson updated:

    -
      -
    • Mobs now lie down via turning icons rather than preturned sprites.
    • -
    • You can lie down facing up or down and the turn can be 90 degrees clockwise or counterclockwise.
    • -
    • Resting will always make you lie to the right so you look good on beds.
    • -
    • Please report any bugs you find with this system.
    • -
    -

    Petethegoat updated:

    -
      -
    • Increased the walk speed. Legcuffed speed is unaffected, and is still suffering.
    • -
    • Sped up alien drones, they are now the same speed as sentinels.
    • -
    -
    - -
    -

    28 January 2014

    -

    Demas updated:

    -
      -
    • Adds thud sounds to falling over
    • -
    • Known bug: Thuds play when cloning initialises or someone is put into cryo. This will be fixed.
    • -
    -
    - -
    -

    26 January 2014

    -

    Balrog updated:

    -
      -
    • Syndicate Playing Cards can now be found on the Syndicate Mothership and purchased from uplinks for 1 telecrystal.
    • -
    • Syndicate Playing Cards are lethal weapons both in melee and when thrown, but make the user's true allegiance to the Syndicate obvious.
    • -
    • Sprites are courtesy of Nienhaus.
    • -
    -
    - -
    -

    25 January 2014

    -

    Miauw updated:

    -
      -
    • Adds changeling arm blades that cost 20 chems and do 25 brute damage.
    • -
    • Arm blades can pry open unpowered doors, replace surgical saws in brain removal, slice tables and smash computers.
    • -
    -
    - -
    -

    24 January 2014

    -

    Ergovisavi updated:

    -
      -
    • Gibtonite, the explosive ore, can now be found on the asteroid. It's very hard to tell between it and diamonds, at first glance.
    • -
    • Gibtonite deposits will blow up after a countdown when you attempt to mine it, but you can stop it with an analyzer at any time. It makes for a good mining explosive.
    • -
    • The closer you were to the explosion when you analyze the Gibtonite deposit, the better the Gibtonite you can get from it.
    • -
    • Once extracted, it must be struck with a pickaxe or drill to activate it, where it will go through its countdown again to explode!
    • -
    • Explosives will no longer destroy the ore inside of asteroid walls or lying on the floor.
    • -
    -
    - -
    -

    21 January 2014

    -

    MrPerson updated:

    -
      -
    • Mobs now lie down via turning icons rather than preturned sprites.
    • -
    • You can lie down facing up or down and the turn can be 90 degrees clockwise or counterclockwise.
    • -
    • Resting will always make you lie to the right so you look good on beds.
    • -
    • Please report any bugs you find with this system.
    • -
    -
    - -
    -

    19 January 2014

    -

    KazeEspada updated:

    -
      -
    • The water cooler is now stocked with paper cups. You can refill the cups by putting paper in it.
    • -
    -

    Rolan7 updated:

    -
      -
    • You can now sell mutant seeds, from hydroponics, to Centcom via the supply shuttle.
    • -
    • Fixes powersinks causing APCs to stop automatically recharging.
    • -
    -
    - -
    -

    17 January 2014

    -

    ManeaterMildred updated:

    -
      -
    • Changed the way the Gygax worked. It now has less defense and shot deflection, but is faster and have less battery drain per step.
    • -
    • Nerfed the Carbine's brute damage and renamed it to FNX-99 "Hades" Carbine.
    • -
    • Nerfed the Gygax defense from 300 to 250.
      - Nerfed the Gygax projectile deflection chance from 15 to 5.
      - Buffed the Gygax speed from 3 to 2, making it faster.
      - Reduced the battery use when moving from 5 to 3.
      -
      - The Mech Ion Rifle now has a faster cooldown, from 40 to 20.
      - Nerfed the carbine's Brute Damage from 20 to 5.
      -
      - Please post feedback to these changes on the forums. -







    • -
    -
    - -
    -

    15 January 2014

    -

    Dumpdavidson updated:

    -
      -
    • EMPs affect the equipment of a human again.
    • -
    • EMP flashlight now recharges over time and its description no longer reveals the illegal nature of the device.
    • -
    • EMP implant now has two uses.
      EMP kit now contains two grenades.
    • -
    -
    - -
    -

    14 January 2014

    -

    Fleure updated:

    -
      -
    • Added spider butchery.
    • -
    • Added spider meat, legs, and edible eggs.
    • -
    • Added new spider related meals.
    • -
    -

    Giacom updated:

    -
      -
    • Because of an emagged cyborg's explosion, the MMI will die with it.
    • -
    • The self-respiration symptom will now properly keep you from dying of oxygen loss.
    • -
    • The Stimulant symptom's activation chance was increased so you had a constant flow of hyperzine.
    • -
    -

    Incoming updated:

    -
      -
    • A new training bomb has been added to the armoury, which will allow you to train your wire cutting skills to disarm real syndicate bombs.
    • -
    -

    ManeaterMildred updated:

    -
      -
    • Updated research designs.
    • -
    • The Protolathe can now build a Ion Rifle.
    • -
    • The Exosuit Fabricator can now build a Mech Ion Rifle, a Mech Carbine and a Mech-Mounted Missile Rack.
    • -
    -

    SirBayer updated:

    -
      -
    • Armor now reduces damage by the protection percentage, instead of randomly deciding to half or full block damage by those percentages.
    • -
    • Shotguns, with buckshot shells, will fire a spread of pellets at your target, like a real shotgun blast.
    • -
    -
    - -
    -

    12 January 2014

    -

    VistaPOWA updated:

    -
      -
    • Added Syndicate Cyborgs.
    • -
    • They can be ordered for 25 telecrystals by Nuclear Operatives. A ghost / observer with "Be Operative" ticked in their game options will be chosen to control it.
    • -
    • Their loadout is: Crowbar, Flash, Emag, Esword, Ebow, Laser Rifle. Each weapon costs 100 charge to fire, except the Esword, which has a 500 charge hitcost. Each borg is equipped with a 25k cell by default.
    • -
    • Syndicate borgs can hear the binary channel, but they won't show up on the Robotics Control computer or be visible to the AI. Their lawset is the standard emag one.
    • -
    • Added two cyborg recharging stations to the Syndicate Shuttle.
    • -
    -
    - -
    -

    11 January 2014

    -

    Cheridan updated:

    -
      -
    • You can now upgrade laser pointers with micro laser parts. It will increase the chance of blinding people.
    • -
    -

    Errorage updated:

    -
      -
    • Cyborg modules now use a new UI, which is much quicker than a menu.
    • -
    -

    Giacom updated:

    -
      -
    • The game will now have all background operations disabled, this will result in smoother gameplay but may result in some spike lags, before being set back to normal. The gradually increasing lag should now be gone.
    • -
    • You can now emag the crusher, in disposals, to remove the safety. You can use a screwdriver to reset it to the default factory settings.
    • -
    • The toxin compensation symptom will stop giving you toxin damage while at full health.
    • -
    -

    JJRCop updated:

    -
      -
    • The new nuke toy can now be found in your local arcade machine.
    • -
    -
    - -
    -

    10 January 2014

    -

    ChuckTheSheep updated:

    -
      -
    • Morgue Trays can detect players in their bodies and will now change colour depending on a few things. Red = Dead body with no player inside. Orange = No body but items. Green = A dead body with a player inside.
    • -
    -

    Giacom updated:

    -
      -
    • You can whisper while in critical, but you will immediately die afterwards DRAMATICALLY. The closer you are to death, the less you can say.
    • -
    • The wizard won't spawn so much smoke after they blink.
    • -
    • The detective's forensic scanner was upgraded so that it can now scan from afar.
    • -
    • Made the ghost's follow button less buggy. Please make an issue report if it still bugs out.
    • -
    -

    Rumia29, Nienhaus updated:

    -
      -
    • A new alt RD uniform spawns in his locker.
    • -
    -
    - -
    -

    07 January 2014

    -

    Fleure updated:

    -
      -
    • Janitor now spawns with a service headset.
    • -
    • Backpack watertank slowdown decreased.
    • -
    -
    - -
    -

    04 January 2014

    -

    Razharas updated:

    -
      -
    • Constructable machines now depend on R&D; parts!
    • -
    • DNA scanner: Laser quality lessens irradiation. Manipulator quality drastically improves precision (9x for best part) and scanner quality allows you to scan suicides/ling husks, with the best part enabling the cloner's autoprocess button, making it scan people in the scanner automatically.
    • -
    • Clone pod: Manipulator quality improves the speed of cloning. Scanning module quality affects with how much health people will be ejected, will they get negative mutation/no mutations/clean of all mutations/random good mutation, at best quality will enable clone console's autoprocess button and will try to clone all the dead people in records automatically, together with best DNA scanner parts cloning console will be able to work in full automatic regime autoscanning people and autocloning them.
    • -
    • Borg recharger: Capacitors' quality and powercell max charge affect the speed at which borgs recharge. Manipulator quality allows borg to be slowly repaired while inside the recharges, best manipulator allows even fire damage to be slowly repaired.
    • -
    • Portable power generators: Capacitors' quality produce more power. Better lasers consume less fuel and reduce heat production PACMAN with best parts can keep whole station powered with about sheet of plamsa per minute (approximately, wasn't potent enough to test).
    • -
    • Autolathe: Better manipulator reduces the production time and lowers the cost of things(they will also have less m_amt and g_amt to prevent production of infinity metal), stacks' cant be reduced in cost, because thatll make production of infinity metal/glass easy
    • -
    • Protolathe: Manipulators quality affects the cost of things(they will also have less m_amt and g_amt to prevent production of infinity metal), best manipulators reduces the cost 5 times (!)
    • -
    • Circuit imprinter: Manipulator quality affects the cost, best manipulator reduce cost(acid insluded) 4 times, i.e. 20 boards per 100 units of acid
    • -
    • Destructive analyzer: Better parts allow items with less reliability in. Redone how reliability is handled, you now see item reliability in the deconstruction menu and deconstructing items that has same or one point less research type level will rise the reliability of all known designs that has one or more research type requirements as the deconstructed item. Designs of the same type raise in reliability more. Critically broken things rise reliability of the design drastically. Whole reliability system is not used a lot but now at least on the R&D; part it finally matters.
    • -
    -
    - -
    -

    02 January 2014

    -

    Demas updated:

    -
      -
    • Added different colours to departmental radio frequencies. Now you'll be able to filter out or pay attention to each frequency a lot easier.
    • -
    -

    Fleure updated:

    -
      -
    • Fixed bruisepacks and ointments not working.
    • -
    • Fixed injecting/stabbing mouth or eyes when only thick suit worn.
    • -
    -
    - -
    -

    01 January 2014

    -

    Errorage updated:

    -
      -
    • The damage overlay for humans starts a little later than before. It used to start at 10 points of fire + brute damage, it now starts at 35.
    • -
    -
    - -
    -

    31 December 2013

    -

    Fleure updated:

    -
      -
    • Paper no longer appears with words on it when blank input written or photocopied
    • -
    • Vending machine speaker toggle button now works
    • -
    • Building arcade machines works again
    • -
    -
    - -
    -

    27 December 2013

    -

    Giacom updated:

    -
      -
    • Light explosions will no longer gib dead bodies anymore. C4 will function the same and gib anything attached.
    • -
    • Syringe gun projectiles will now display a message when shots are deflected by space suits, biosuits and etc...
    • -
    • You can now move out of sleepers by moving, again.
    • -
    -

    Miauw updated:

    -
      -
    • Monkeys now have a resist button on their HUD.
    • -
    -
    - -
    -

    21 December 2013

    -

    Bobylein updated:

    -
      -
    • Labcoats can now store bottles, beakers, pills, pill bottles and paper.
    • -
    -

    Giacom updated:

    -
      -
    • The Labor Camp has been changed based on feedback. Ore boxes added, internals added, safety pickaxes/shovels (might revert if unliked).
    • -
    • Labor Camp prisoners, who have earned enough points for freedom, will now have to be alone in the shuttle to move it and to open the middle door; this is in order to prevent free'd prisoners from releasing their comrades.
    • -
    • Monkeys no longer walk away when being pulled or grabbed.
    • -
    • Anti-breach shield generators have a greater range, and will cover more exposed space tiles.
    • -
    -

    Jordie updated:

    -
      -
    • Blowing up borgs from the Robotics Console will now actually make them explode. Emagged Cyborgs will explode even more.
    • -
    -

    Nienhaus updated:

    -
      -
    • Added more poster.
    • -
    -

    Perakp updated:

    -
      -
    • You can no longer slip while laying down.
    • -
    -

    RobRichards, Validsalad updated:

    -
      -
    • Added new sprites for the sec-hailer, SWAT gear and riot armour.
    • -
    -
    - -
    -

    18 December 2013

    -

    Adrinus updated:

    -
      -
    • Playing cards, just like the real thing! Play poker, blackjack, go fish, the limits are limitless! Recommended to use space cash as the poker chips for now
    • -
    -

    Giacom updated:

    -
      -
    • THE REALISM: Injectors such as syringes, parapens and hypos will not penetrate coveralls with thick material, this includes space suits, biosuits, bombsuits, and their head slot equivalent. Injectors now also consider where you aim, if you aim for the head it will try to use it through the head slot, otherwise it will aim for the body. To clarify, if you are wearing a space helmet and a doctor tries to inject you while aiming at your head, it will protect you until they aim for the unprotected body; same story for wearing a space suit and not a helmet.
    • -
    • The syndicate shuttle has been heavily upgraded with a brand new technology which allows the blast doors to the entrance of the shuttle to AUTOMATICALLY close. Whoa. This brand new technology will help keep out those snoopy crew members.
    • -
    • Lowered the cooldown of creating virus cultures to 5 seconds. You now only need to mix one unit of synaptizine, in a blood full of an advance virus, to get it to remove a random symptom.
    • -
    -

    Incoming updated:

    -
      -
    • Rounds will no longer end when the wizard dies and there are still apprentices or traitors/survivors..
    • -
    -

    JJRcop updated:

    -
      -
    • Transit tube tweaks. You can now put someone into a transit tube pod using grabs and you can empty a transit tube pod by clicking on it.
    • -
    -

    Jordie0608 updated:

    -
      -
    • Replaced the digital valves in atmospherics with pumps.
    • -
    -
    - -
    -

    14 December 2013

    -

    Incoming updated:

    -
      -
    • Magic Mania! Powerful new magical tools and skills for wizard and crew alike!
    • -
    • Beware the new Summon Magic spell, which will grant the crew access to magical tools and spells and cause some to misuse it!
    • -
    • One Time Spellbooks that can be spawned during summon magic that can teach a low level magic skill to anyone! Beware the effects of reading pre-owned books, the magical rights management is potent! -
    • Magical Wands that can be spawned during Summon Magic! They come in a variety of effects that mimic both classical wizard spells and all new ones. They come precharged but lack the means to refill them once their magical energy is depleted... Fire efficently!
    • -
    • Be aware of the new Charge spell, which can take normally useless spent wands and give them new life! This mysterious effect has been found to wear down the overall magical potency of wands over time however. Beyond wands the clever magical user can find ways to use this spell on other things that may benefit from a magical charge...
    • -
    • The Staff of Resurrection, which holds intense healing magics able to defeat death itself! Look out for this invaluable magical tool during castings of Summon Magic.
    • -
    • Be on the lookout for a new apprentice! This noble mage is a different beast from most wizards, trained in the arts of defending and healing. Too bad he still works for the wizard!
    • -
    -
    - -
    -

    09 December 2013

    -

    Giacom updated:

    -
      -
    • New colourful ghost sprites for BYOND members. Sprites by anonus.
    • -
    -
    - -
    -

    08 December 2013

    -

    Rolan7 updated:

    -
      -
    • Leather gloves can be used to removes lights.
    • -
    • Plant, ore, and trash bags have a new option to pick up all items of single type
    • -
    • Creating astroturf now works like sandstone, converting all the grass at once.
    • -
    • Uranium and radium can be used instead of mutagen. 10 can mutate species, 5 or 2 mutate traits. Highly toxic.
    • -
    • Plants require a little light to live. Mushroom require even less (2 units vs 4) and take less damage.
    • -
    -
    - -
    -

    05 December 2013

    -

    Razharas updated:

    -
      -
    • Reworked how ling stings are done, now when you click a sting in the changeling tab it becomes current active sting, the icon of that sting appears under the chem counter, alt+clicking anyone will sting them with current sting, clicking the icon of the sting will unset it.
    • -
    • Monkeys have ling chem counter and active sting icons in their UI.
    • -
    • Going monkey -> human will try to equip the human with everything on the ground below it.
    • -
    -
    - -
    -

    02 December 2013

    -

    Giacom updated:

    -
      -
    • A less annoying virology system! From now on, you can only get low level virus symptoms from virus food, medium level virus symptoms from unstable mutagen and high level virus symptoms from liquid plasma. You can find a list of symptoms, and which chemicals are required to get them, here: http://wiki.ss13.eu/index.php/Infections#Symptoms_Table
    • -
    • The virologist starts with a bottle of plasma in his smart fridge.
    • -
    • Made it so you cannot accidentally click in the gaps between chem masters.
    • -
    -
    - -
    -

    01 December 2013

    -

    cookingboy3 updated:

    -
      -
    • Added three new buttons to the sandbox panel.
    • -
    • Removed canister menu, replaced it with buttons.
    • -
    • Players can no longer spawn "dangerous" canisters in sandbox, such as Plasma, N20, CO2, and Nitrogen.
    • -
    -
    - -
    -

    30 November 2013

    -

    Yota updated:

    -
      -
    • The identification console will now require that ID and job names follow the same restrictions as player names.
    • -
    • NTSL scripts and parrots should now handle apostrophes and such properly. It&#39;s about time.
    • -
    • NTSL scripts now have a better sense of time.
    • -
    -
    - -
    -

    28 November 2013

    -

    Malkevin updated:

    -
      -
    • Made the suit storage on the Captain's Tunic more useful than just a place to store your e-o2 tank. You can now store the nuke disk, stamps, medal box, flashes and melee weapons (mainly intended for the Chain of Command), and of course - smoking paraphernalia
    • -
    -
    - -
    -

    27 November 2013

    -

    RobRichards updated:

    -
      -
    • Nanotrasen surgeons are now certified to perform Limb replacements, The robotic parts used in construction of Nanotrasen Cyborgs are the only parts authorized for crew augmentation, these replacement limbs can be repaired with standard welding tools and cables.
    • -
    -
    - -
    -

    17 November 2013

    -

    Laharl Montgommery updated:

    -
      -
    • AI can now anchor and unanchor itself. In short, it means the AI can be dragged, if it wants to.
    • -
    -
    - -
    -

    29 September 2013

    -

    RobRichards updated:

    -
      -
    • Nanotrasen Cyborg Upgrades:
      -Standard issue Engineering cyborgs now come equipped with replacement floor tiles which they can replenish at recharge stations.
    • -
    -
    - - -
    -

    28 September 2013

    -

    Ergovisavi updated:

    -
      -
    • Mobs can now be lit on fire. Wearing a full firesuit (or similar) will protect you. Extinguishers, Showers, Space, Cryo, Resisting, being splashed with water can all extinguish you. Being splashed with fuel/ethanol/plasma makes you more flammable. Water makes you less flammable.
    • -
    -
    - - -
    -

    26 September 2013

    -

    Cheridan updated:

    -
      -
    • Nanotrasen Anomaly Primer:
      - Unstable anomalies have been spotted in your region of space. These anomalies can be hazardous and destructive, though our initial encounters with these space oddities has discovered a method of neutralization. Method follows.
      -

      Step 1. Upon confirmation of an anomaly sighting, report its location. Early detection is key.
      - Step 2. Using an atmospheric analyzer at short range, determine the frequency that the anomaly's core is fluctuating at.
      - Step 3. Send a signal through the frequency using a radio signaller. Note that non-specialized signaller devices may possibly lack the frequency range needed.

      - With the anomaly neutralized and the station brought out of danger, inspect the area for any remnants of the anomaly. Properly researched, we believe these events could provide vast amounts of valuable data.
      - Did you find this report helpful?
    • -
    -
    - - - -
    -

    21 September 2013

    -

    Malkevin updated:

    -
      -
    • Due to complaints about Security not announcing themselves before making arrests NT has now issued it's Sec team with loud hailer integrated gas masks, found in their standard equipment lockers. Users can adjust the mask's level of aggression with a screwdriver.
    • -
    • The sprites could be shaded better. Think you can do better? Post your submissions here.
    • -
    -
    - - -
    -

    19 September 2013

    -

    Malkevin updated:

    -
      -
    • Juggernaut's ablative armor has been adjusted. They have a greater chance to reflect lasers however on reflection they take half damage instead of no damage, basically this adjustment means you should be able to kill a Juggernaut with two laser guns instead of four! Also their reflection spread has been greatly widened, enjoy the lightshow
    • -
    • Cargo can now order exile implants.
    • -
    • Checking a collector's last power output via analyzers has been moved to multitools, because that actually made sense (betcha didn't know this existed, I know I didn't)
    • -
    • Analyzers can now be used to check the gas level of the tank in a loaded radiation collector (yay no more crowbars), you can also use them on pipes to check gas levels (yay no more pipe meters)
    • -
    -
    - -
    - - -

    17 September 2013

    -

    SuperSayu updated:

    -
      -
    • You can no longer strip people through windows and windoors
    • -
    • You can open doors by hand even if there is a firedoor in the way, making firedoor+airlock no longer an unbeatable combination
    • -
    • Ghosts can now click on anything to examine it, or double click to jump to a turf. Double clicking a mob, bot, or (heaven forbid) singularity/Nar-Sie will let you follow it. Double clicking your own corpse re-enters it.
    • -
    • AI can double click a mob to follow it, as well as double clicking turfs to jump.
    • -
    • Ventcrawling mobs can alt-click a vent to start ventcrawling.
    • -
    • Telekinesis is now part of the click system. You can click on buttons, items, etc, without having a telekinetic throw in hand; the throw will appear when you click on something you can move (with your mind).
    • -
    -
    - - -
    -

    13 September 2013

    -

    JJRcop updated:

    -
      -
    • We at Nanotrasen would like to assure you that we know the pain of waiting five minutes for the emergency shuttle to be dispatched in a high-alert situation due to our confirmation-of-distress policy. Therefore, we have amended our confirmation-of-distress policy so that, in the event of a red alert, the distress confirmation period is shortened to three minutes and we will hurry in preparing the shuttle for transit. This totals to 6 minutes, in hope that it will give our very expensive equipment a better chance of recovery.
    • -
    -
    - - -
    -

    3 September 2013

    -

    Cael_Aislinn updated:

    -
      -
    • Terbs Fun Week Day 5: Chef gets a Nanotrasen-issued icecream machine with four pre-approved icecream flavours and two official cone types.
    • -
    -
    - - -
    -

    2 September 2013

    -

    Cael_Aislinn updated:

    -
      -
    • Terbs Fun Week Day 4: Humans, aliens and cyborgs now show speech bubbles when they talk.
    • -
    -
    - - -
    -

    1 September 2013

    -

    Cael_Aislinn updated:

    -
      -
    • Terbs Fun Week Day 3: Detective can reskin his gun to one of five variants: Leopard Spots, Gold Trim, Black Panther, Peacemaker and the Original.
    • -
    -
    - - -
    -

    12 September 2013

    -

    AndroidSFV updated:

    -
      -
    • AI Photography: AIs now have two new verbs, Take Picture and View Picture. The pictures the AI takes are centered on the AI's eyeobj. You can use these pictures on a newscaster, and print them at a photocopier. -
    -
    - - -
    -

    31 August 2013

    -

    Cael_Aislinn updated:

    -
      -
    • Terbs Fun Week Day 2: RD, lawyers and librarians now spawn with a laser pointer. Don't point them in anyone's eyes!
    • -
    -
    - - -
    -

    30 August 2013

    -

    Cael_Aislinn updated:

    -
      -
    • Terbs Fun Week Day 1: Added ghost chilis as a mutation of chili plants. Be careful, they're one of the hottest foods in the galaxy!
    • -
    -
    - - -
    -

    21 August 2013

    -

    Dumpdavidson updated:

    -
      -
    • Replaced the EMP grenades from the uplink with an EMP kit. The kit contains a grenade, an implant and a flashlight with 5 uses that can EMP any object or mob in melee range.
    • -
    -
    - - -
    -

    18 August 2013

    -

    Delicious updated:

    -
      -
    • Made time and date consistent across medical and security records, mecha logs and detective scanner reports
    • -
    • Added date to PDA
    • -
    -
    - - -
    -

    13 August 2013

    -

    Giacom updated:

    -
      -
    • Malf AIs now have a new power which will spawn a "borging machine". This machine will turn living humans into loyal cyborgs which the AI can use to take over the station with. The AI will limit themselves by using this ability, such as no shunting, and the machine will have a long cooldown usage.
    • -
    -
    - - - - - -
    -

    12 August 2013

    -

    Giacom updated:

    -
      -
    • Changed the blob balance to make the blob start strong but grow slower, resulting in rounds where the blob doesn't instantly get killed off if found out and doesn't immediately dominate after being left alone long enough. AIs no longer have to quarantine the station.
    • -
    -
    - - -
    -

    10 August 2013

    -

    Malkevin updated:

    -
      -
    • Cargo Overhaul: Phase 1
    • -
    • Ported Bay's cargo computer categoy system
    • -
    • Crates have been tweaked significantly. Crates have been reduced to single item types where possible, namely with expensive crates such as weapons and armor. A total of 28 new crates have been added, including chemical and tracking implants, and raw materials can also be bought from cargo for a significant number of points (subject to change)
    • -
    • This was a pretty large edit of repetitive data, so no doubt I've made a mistake or two. Please report any bugs to the usual place
    • -
    -
    - - -
    -

    6 August 2013

    -

    Giacom updated:

    -
      -
    • NTSL no longer allows you to use a function within another function parameter. This was changed to help prevent server crashes; if your working script no longer compiles this is why.
    • -
        -
    - - -
    -

    5 August 2013

    -

    Kaze Espada updated:

    -
      -
    • Nanotrasen has recentely had to change its provider of alcoholic beverages to a provider of lower quality. Cases of the old ailment known as alcohol poisoning have returned. Bar goers are to be weary of this new condition.
    • -
    -
    - - -
    -

    4 August 2013

    -

    Giacom updated:

    -
      -
    • Nanotrasen has re-arranged the station blueprint designs to have non-essential APCs moved to the maintenance hallways. Non-essential rooms that aren't connected to a maintenance hallway will have their APC remain. Station Engineers will now have easy access to a room's APC without needing access themselves. Nanotrasen also wishes to remind you that you should not sabotage these easy to access APCs to cause distractions or to lockdown someone in a location. Thank you for reading.
    • -
    -
    - - -
    -

    31 July 2013

    -

    Ricotez updated:

    -
      -
    • Atmospherics now has its own hardsuit. Instead of radiation protection it offers fire protection.
    • -
    -
    - - -
    -

    21 July 2013

    -

    Malkevin updated:

    -
      -
    • Cultists now start with two words each, and the starting talisman no longer damages you when you use it
    • -
    -
    - - - -
    -

    21 July 2013

    -

    Cheridan updated:

    -
      -
    • Instead of a level-up system where it is possible to acquire all the skills, each skill now costs 1 point, and you can pick up to 5.Husking people, instead of giving you more XP to buy skills, now gives you a skill reset, allowing you to pick new ones.
    • -
    • DNA Extract Sting is now free, and is your main mode of acquiring DNA. You can hold up to 5 DNAs, and as you acquire more, the oldest one is removed. If you're currently using the oldest DNA strand, you will be required to transform before gaining more.
    • -
    • New abilities! An UI indicator for chemical storage! Fun!
    • -
    -
    - - -
    -

    16 July 2013

    -

    Malkevin updated:

    -
      -
    • Summary of my recent changes: Added a muzzle and a box of Prisoner ID cards to the perma wing, RnD can make a new combined gas mask with welding visor, added some atmos analyzers to atmospherics, air alarm circuit boards have their own sprites, package wrapped objects will now loop back round to the mail chute instead of auto-rerouting to disposals, and the detective and captain have access to securitrons through their PDA cartridges.
    • -
    -
    - -
    -

    15 July 2013

    -

    Giacom updated:

    -
      -
    • A new item has been added to the syndicate catalog. The AI detector is a device disguised as a multitool; it is not only able to be used as a real multitool but when it detects an AI looking at it, or it's holder, it will turn red to indicate to the holder that he should cease supiscious activities. A great and cheap, to produce, tool for undercover operations involving an AI as the security system.
    • -
    -
    - - -
    -

    7 July 2013

    -

    Giacom updated:

    -
      -
    • Revamped blob mode and the blob random event to spawn a player controlled overmind that can expand the blob and upgrade pieces that perform particular functions. This will use resources which the core can slowly generate or you can place blob pieces that will give you more resources.
    • -
    -
    - -
    -

    27 June 2013

    -

    Ikarrus updated:

    -
      -
    • Nanotrasen R&D released a new firmware patch for their station AIs. Included among the changes is the new ability for AIs to interact with fire doors. R&D officials state they feel giving station AIs more influence could only lead to good things.
    • -
    -
    - -
    -

    16 June 2013

    -

    Khub updated:

    -
      -
    • Job preferences menu now not only allows you to left-click the level (i.e. [Medium]) to raise it, but also to right-click it to lower it. That means you don't have to cycle through all the levels to get rid of a [Low].
    • -
    -
    - - -
    -

    15 June 2013

    -

    Carnie updated:

    -
      -
    • DNA-scanner pods (DNA-modifier + cloning), now open and close in a similar fashion to closets. This means you click on them to open/close them. This change was to fix a number of issues, like items being lost in the scanner-pods.
    • -
    • As a side-effect, borgs can now clone humans. No harm can become a dead human, so they are not necessarily lawbound to clone them, and such tasks are probably best left to qualified genetics staff.
    • -
    -

    Petethegoat updated:

    -
      -
    • Updated chemical grenades. The build process is much the same, except they require an igniter-X assembly instead of a single assembly item. You can also just use a cable coil to get regular grenade behaviour.
    • -
    -
    - -
    -

    9 June 2013

    -

    Ikarrus updated:

    -
      -
    • Server operators may now allow latejoiners to become antagonists. Check game_options.txt for more information.
    • -
    • Server operators may now set how traitors and changelings scale to population. Check game_options.txt for more information.
    • -
    -
    - -
    -

    6 June 2013

    -

    Giacom updated:

    -
      -
    • Emptying someone's pockets won't display a message. In theory you can now pickpocket!
    • -
    -
    - - -
    -

    4 June 2013

    -

    Dumpdavidson updated:

    -
      -
    • Headsets can no longer broadcast into a channel that is disabled.
      Headsets now have a button to turn off the power instead of the speaker. This button disables all communication functions.
      EMPs now force affected radios off for about 20 seconds.
    • -
    -
    - -
    -

    2 June 2013

    -

    Ikarrus updated:

    -
      -
    • To reduce costs of security equipment, mounted flashers have been adjusted to use common handheld flashes as their flashbulbs. Although these flashbulbs are more prone to burnout, they can easily be replaced with wirecutters.
    • -
    -
    - -
    -

    25 May 2013

    -

    Ikarrus updated:

    -
      -
    • CentCom announced some minor restructuring within Space Station 13's command structure. Most notable of these changes is the removal of the Head of Personnel's access to the security radio channel. CentCom officials have stated the intention was to make the HoP's role more specialized and less partial towards security.
    • -
    -
    - -
    -

    14 May 2013

    -

    Ikarrus updated:

    -
      -
    • Nanotrasen seeks to further cut operating costs on experimental cyborg units. -
      -Cyborg chassis will now be made from a cheaper but less durable design. -
      -RCDs found on engineering models have been replaced with a smaller model to make room for a metal rods module. -
      -Cyborg arms will no longer be long enough to allow for self-repairs. -
      NOTE: A cyborg's individual modules have been found to become non-operational should the unit sustain too much structural damage.
    • -
    -
    - -
    -

    11 May 2013

    -

    Malkevin updated:

    -
      -
    • SecHuds now check for valid clearance before allowing you to change someone's arrest status. There is only one way to bypass the ID check, and its not the usual way.
    • -
    - -
    - -
    -

    7 May 2013

    -

    Ikarrus updated:

    -
      -
    • As a part of the most recent round of budget cuts, toolboxes will now be made with a cheaper but heavier alloy. HR reminds employees to avoid being struck with toolboxes, as toolbox-related injuries are not covered under the company's standard health plan.
    • -
    -
    - -
    -

    5 May 2013

    -

    Rolan7 updated:

    -
      -
    • Cargo manifests from CentComm may contain errors. Stamp them DENIED for refunds. Doesn't apply to secure or large crates. Check the orders console for CentComm feedback.
    • -
    -
    - -
    -

    2 May 2013

    -

    Malkevin updated:

    -
      -
    • You can now weld four floor tiles together to make a metal sheet
    • -
    • The All-In-One Grinder can now grind Metal, Plasteel, Glass, Reinforced Glass, and Wood sheets
    • -
    • Made grey backpacks slightly less ugly
    • -
    -
    - -
    -

    30 April 2013

    -

    Ikarrus updated:

    -
      -
    • Researchers have discovered that glass shards are, in fact, dangerous due to their typically sharp nature. Our internal Safety Committee advises that glass shards only be handled while using Nanotrasen-approved hand-protective equipment.
    • -
    -
    - -
    -

    24 April 2013

    -

    Carnie updated:

    -
      -
    • DNA reworked: All SE blocks are randomised. DNA-modifier emitter strength affects the size of the change in the hex-character hit. Emitter duration makes it more likely to hit the character you click on. Almost all DNA-modifier functions are on one screen.
      Balancing -will- be off a bit. Is getting halk to hard/easy? Please report bugs/balancing issues/concerns here: http://forums.nanotrasen.com/viewtopic.php?f=15&t=13083 <3
    • -
    -
    - -
    -

    26 April 2013

    -

    Aranclanos updated:

    -
      -
    • Exosuit fabricators will now need to be manually updated
    • -
    -

    Ikarrus updated:

    -
      -
    • Commanding Officers of Nanotrasen Stations have been issued a box of medals to be awarded to crew members who display exemplary conduct.
    • -
    -
    - - -
    -

    23 April 2013

    -

    Malkevin updated:

    -
      -
    • Replaced the captain's run of the mill armored vest with his very own unique vest. Offers slightly better bullet protection.
    • -
    -
    - - -
    -

    22 April 2013

    -

    Malkevin updated:

    -
      -
    • Overhauled the thermal insulation system
    • -
    • All clothing that protected from one side of the thermal spectrum now protects from the other.
    • -
    • Armor (although most don't have full coverage) protects between 160 to 600 kelvin
    • -
    • Firesuits protect between 60 to 30,000 kelvin (Note: Hotspot damage still exists)
    • -
    • CE's hardsuit got its firesuit level protection back
    • -
    • Bomb suits function as ghetto riot gear
    • -
    -
    - -
    -

    22 April 2013

    -

    Cheridan updated:

    -
      -
    • Stungloves removed 5eva.
    • -
    • Don't rage yet. Makeshift stunprods(similar in function to stungloves) and spears are now craftable. Make them by using a rod on cable restraits, then adding something.
    • -
    • Stun batons/prods now work off power cells, which can be removed and replaced! Use a screwdriver to remove the battery.
    • -
    -
    - - -
    -

    17 April 2013

    -

    Giacom updated:

    -
      -
    • If the configuration option is enabled, AIs and or Cyborgs will not be able to communicate vocally. This means they cannot talk normally and need to use alternative methods to do so
    • -
    -
    - - -
    -

    10 April 2013

    -

    Cheridan updated:

    -
      -
    • You can now condense capsaicin into pepper spray with chemistry.
    • -
    • Pepper spray made slightly more effective.
    • -
    • Teargas grenades can be obtained in Weapons and Riot crates.
    • -
    • Riot crate comes with 2 sets of gear instead of 3, made cheaper. Beanbag crate removed entirely. Just make more at the autolathe instead. Bureaucracy crate cheaper, now has film roll.
    • -
    • NT bluespace engineers have ironed-out that little issue with the teleporter occasionally malfunctioning and dropping users into deep space. Please note, however, that bluespace teleporters are still sensitive experimental technology, and should be Test Fired before use to ensure proper function.
    • -
    -
    - - -
    -

    9 April 2013

    -

    Ikarrus updated:

    -
      -
    • Liquid Plasma have been found to have strange and unexpected results on virion cultures. The executive chief science officer urges virologists to explore the possibilities this new discovery could bring.
    • -
    • After years or research, our scientists have engineered this cutting-edge technology born from the science of shaving. The Electric Space-Razor 5000! It uses moisturizers to refuel your face while you shave with not three, not four, but FIVE lazer-precise inner blades for maximum comfort.
    • -
    -
    - -
    -

    4 April 2013

    -

    Cheridan updated:

    -
      -
    • When an AI shunts into an APC, the pinpointer will begin tracking it. When the AI returns to its core, the pinpointer will go back to locating the nuke disc.
    • -
    • New sechud icons for sec officers/HoS, medical doctors, and loyalty implants.
    • -
    -
    - -
    -

    28 March 2013

    -

    Carnie updated:

    -
      -
    • Empty character slots in your preferences screen will now randomize. So they won't initialise as bald, diaper-clad, white-guys.
    • -
    • Reworked the savefile versioning/updating code. Your preferences data is less likely to be lost.
    • -
    -
    - -
    -

    14 March 2013

    -

    Major_sephiroth updated:

    -
      -
    • You can now light cigarettes with other cigarettes, and candles. And cigars. Light a cigar with a candle! It's possible now!
    • -
    -
    - -
    -

    13 March 2013

    -

    Elo001 updated:

    -
      -
    • You can now open and close job slots for some jobs at any IDcomputer. There is a cooldown when opening or closing a position.
    • -
    -
    - -
    -

    8 March 2013

    -

    Kor updated:

    -
      -
    • You can now construct/destroy bookcases. This is super exciting and game changing.
    • -
    -
    - -
    -

    6 March 2013

    -

    Petethegoat updated:

    -
      -
    • Petethegoat says, "Added a new feature involvi-GLORF"
    • -
    • Overhauled how grabs work. There aren't any interesting mechanical differences yet, but they should be a lot more effective already. You don't have to double click them anymore. Report any bugs with grabbing directly to me, or on the issue tracker.
    • -
    -
    - -
    -

    24 February 2013

    -

    Ikarrus updated:

    -
      -
    • AI has been moved back to the center of the station. Telecoms has been moved to engineering.
    • -
    -

    Faerdan updated:

    -
      -
    • Competely new UI overhaul! Most user interface have been converted.
    • -
    - -
    -

    22 February 2013

    -

    Petethegoat updated:

    -
      -
    • Added cavity implant surgery.
    • -
    • Additionally, surgery must now be performed with help intent. Some procedures have also been updated. - As always, check the wiki for details.
    • -
    -
    - -
    -

    18 February 2013

    -

    Ikarrus updated:

    -
      -
    • The AI has been moved to Research Division, and Telecomms has been moved into the former AI chamber. Affected areas: Telecoms Satellite, Research Division South & Command Sector.
    • -
    -

    Incoming updated:

    -
      -
    • Added three new types of surgery- lipoplasty, plastic surgery, and gender reassignment.
    • -
    -

    Kor updated:

    -
      -
    • The RD has lost access to telecomms, and basic engineers have gained it.
    • -
    -
    - -
    -

    14 February 2013

    -

    Petethegoat updated:

    -
      -
    • Updated surgery: you now initiate surgery with surgical drapes or a bedsheet. Most procedures have changed, check the wiki for details. Currently it's pretty boring, but this paves the way for exciting new stuff- new procedures are very simple to add. Report any bugs directly to me, or on the issue tracker.
    • -
    -
    - -
    -

    13 February 2013

    -

    Giacom updated:

    -
      -
    • There are now hackable wires for the PA computer. To open the interface, click on it while the wires are exposed/panel is open. All but one wire will do something interesting, see if you can figure it out. You can also attach signallers to the wires so have fun remotely releasing the singularity.
    • -
    • New staff of animation icon by Teh Wolf!
    • -
    • You can now hack plastic explosives (C4)!
    • -
    • You can now use NTSL to send signals! With the function signal(frequency, code) you can create some clever ways to trigger a bomb. NTSL also has two new additions; return in the global scope will now stop the remaining code from executing and NTSL now has "elseif"s, huzzah!
    • -
    -

    Kor "I'm quitting I swear" Phaeron updated:

    -
      -
    • You've been asking for it for years, it's finally here. Wizards can spend points to buy apprentices.
    • -
    • A new wizard artefact, the scrying orb.
    • -
    • The spellbook now has descriptions of spells/items visible BEFORE you purchase them.
    • -
    -

    Petethegoat updated:

    -
      -
    • Traitors with the station blueprints steal objective can now use a photo of the blueprints instead!
    • -
    -
    - -
    -

    11 February 2013

    -

    SuperSayu updated:

    -
      -
    • Signallers, prox sensors, mouse traps and infrared beams can now be attacheed to grenades to create a variety of mines.
    • -
    • A slime core can be placed in a large grenade in place of a beaker. When the grenade goes off, the chemicals from the second container will be transfered to the slime core, triggering the usual reaction.
    • -
    -
    - -
    -

    10 Feburary 2012

    -

    Ikarrus updated:

    -
      -
    • Implants can now be surgically removed. Hint: They're inside the skull.
    • -
    -
    - -
    -

    07 February 2012

    -

    Giacom updated:

    -
      -
    • The return of the Nanotrasen Scripting Language! (NTSL) If you haven't heard of NTSL, it is a scripting language within a game for telecomms. Yes, you can create scripts to interact with the radio! For more information, head here: http://wiki.nanotrasen.com/index.php?title=NT_Script But before you do, if you are not an antag, do not create bad scripts which hinders communication.
    • -
    • Cameras, mulebots, APCs, radios and cyborgs can have signallers attached to their wires, like airlocks!
    • -
    • Cameras have non-randomized wires and the power wire when pulsed will now toggle the camera on and off.
    • -
    • Cyborgs have a new wire, the lockdown wire! It will disable/enable the lockdown of a Cyborg when pulsed.
    • -
    • The traffic control computer (or more commonly known as the computer which lets you add NTSL scripts) will now have a user log, which will log all user activity. Other users can then view that log and see who has been uploading naughty scripts!
    • -
    • NTSL has two new functions! time() and timestamp(format) will help you increase the range of types of scripts you can make, especially time(); since you can then make the scripts know the different between each execution by storing the results in memory.
    • -
    • Two new advance disease symptoms! Their names are "Longevity" and "Anti-Bodies Metabolism". Have fun experimenting with them!
    • -
    -
    - - -
    -

    31 January 2013

    -

    Kor "Even in death I still code" Phaeron updated:

    -
      -
    • Four new slime types with their own reactions and two new reactions for old slimes.
    • -
    • Put a suit of reactive teleport armour back in the RD's office.
    • -
    • Chemistry now has two dispensers (with half charge each) so both chemists can actually work at the same time.
    • -
    -
    - - -
    -

    27 January 2013

    -

    Ikarrus updated:

    -
      -
    • Security frequency chatter now appears in cyan (Similar to how command is gold)
    -

    Cheridan updated:

    -
      -
    • The plant bags in Hydroponics lockers have been replaced with upgraded models with seed-extraction tech. Activate with via right-click menu or Objects verb tab.
    • -
    • Obtaining grass tiles works a bit different now: grass is harvested as a normal plant item, clicking on it in-hand produces the tile.
    • -
    -
    - -
    -

    26 January 2013

    -

    Pete updated:

    -
      -
    • Added hugging and kicking. I also updated the text styles for clicking on humans in most intents, but they should be pretty much the same.
    • -
    -
    - -
    -

    25 January 2013

    -

    Errorage updated:

    -
      -
    • All the equipment you spawn with will now contain your fingerprints, giving the detective more ability to tell where items came from and if a crewmember has changed clothing.
    • -
    -
      -
    • Better explosions: Explosion spreading will now be determined by walls, airlocks and poddoors and not just a flat circle.
    • -
    -
    - -
    -

    20 January 2013

    -

    Cheridan updated:

    -
      -
    • Chickens will now lay a certain number of eggs after being fed wheat, rather than just laying them whenever they felt like it. No more chickensplosions.
    • -
    -
    - -
    -

    16 January 2013

    -
      -
    • Department Security can now be runned: -
      Department Security decentralizes security by assigning each officer to a different department. They will be given the radio channel and access to their assigned department along with a security post. The brig has been remapped to be smaller to accomodate this change. -
      To run DeptSec: Before compiling, server operators must
      tick jobs.dm (in WorkInProgress/Sigyn/Department Sec) and use map 2.1.1 instead of 2.1.0.
    • -
    -
    - -
    -

    /tg/station 13 Presents

    -

    Directed by S0ldi3rKr4s0

    -

    & produced by Petethegoat

    -
      -
    • Curse of the Horseman.
    • -
    -
    - -
    -

    12 January 2013

    -

    Cael Aislinn updated:

    -
      -
    • Spiders which will breed and spread through vents. Different classes of vents. AI controlled only at the moment.
    • -
    • Farm animals! Cows, goats and chickens are now available. You can order them at Cargo Bay.
    • -
    -

    Giacom updated:

    -
      -
    • Staff of animation mimics will no longer care whether you are holding the staff or not, they will never attack their creator.
    • -
    • Brainrot will only need alkysine to be cured.
    • -
    • New spider infestation event based on Cael's spiders. The announcement will be the same as alien infestations.
    • -
    -
    - -
    -

    11 January 2013

    -

    Giacom updated:

    -
      -
    • Plasma (Air) will give the breather the plasma reagent, for a toxic effect, instead of just straight damage.
    • -
    • The agent card will now work inside PDAs/Wallets; meaning the AI won't be able to track you.
    • -
    -
    - -
    -

    09 January 2013

    -

    Malkevin updated:

    -
      -
    • The owl mask now functions as a gasmask for increased crimestopping power.
    • -
    -
      -
    • Adds the missing icons for the arrest statuses of Parolled and Released, as well as a little blinking icon for chemical implants.
    • -
    - - -
    -

    08 January 2013

    -

    Cael Aislinn & WJohnston updated:

    -
      -
    • Many new icons for aliens (death, sleeping, unconscious, neurotox, thrown/impregnated facehugger etc)
    • -
    • Alien larva can now be removed by dangerous and unnecessary surgery (and actually chestburst if they aren't).
    • -
    • Alien larva now have sprites to represent their growth: bloody at 0%, pale at 25% and 75% the normal deep red.
    • -
    • New icon overlays for representing alien embryo progression.
    • -
    - -
    -

    07 January 2013

    -

    Kor updated:

    -
      -
    • Four new slime types with their own extract reactions have been added. Sprites this time were created by Reisyn, SuperElement, and LePinkyFace.
    • -
    - -
    -

    02 January 2013

    -

    Kor updated:

    -
      -
    • Slime breeding! There are now 13 varities of slime, each with its own extract reaction (inject five units of plasma). Some of these reactions are reused from the old cores, some are new. As to breeding, each colour of slime has a series of other slimes it may mutate into when it reproduces.
    • -
    -

    Giacom updated:

    -
      -
    • You can now use wallets as IDs and equip them in your ID slot.
    • -
    • Firesuits are once again effective at protecting you from heat. The flames themselves will still hurt you, even with a firesuit. The damage protection is much better with a firesuit though.
    • -
    • Engineering starts with a PACMAN generator for jump starting the singularity if the power runs out of the SMES. 30 plasma spawns in Secure Storage inside the crate, to use as fuel for the generator.
    • -
    - -
    -

    31 December 2012

    -

    Giacom updated:

    -
      -
    • Simple animals (Corgis, Cats, Constructs, Mice, Etc...) can now pull people.
    • -
    • You can quickly stop pulling on someone by pulling them, while they're already being pulled by you. For example, CTRL+Click on something you are pulling to quickly stop pulling it.
    • -
    - -
    -

    30 December 2012

    -

    Giacom updated:

    -
      -
    • Emitters now require to be wired in order to work. When there is not enough power it will stop shooting until there is enough power, meaning you do not have to turn it back on, just get the power flowing.
    • -
    • You can order shield generators from cargo. Teleporter access is required to open the crate.
    • -
    -

    Ikarrus updated:

    -
      -
    • Map: Reorganized the Command Sector. The Captain has his own private quarters in addition to his office.
    • -
    - -
    -

    26 December 2012

    -

    Ikarrus updated:

    -
      -
    • An agent card is now required to use doors and controls on the Syndicate Shuttle (Nuke).
    • -
    • Scanning gas tanks is now a PDA-cart function. Only Atmos and Science PDA carts have this function. Have fun mislabelling gas tanks!
    • -
    - -
    -

    23 December 2012

    -

    Giacom updated:

    -
      -
    • The syndicate Military PDA will not show up on possible PDAs to message anymore, even when the receive/signal is turned on. You can still send messages and people can still reply to you.
    • -
    • You can now sell processed plasma for supply points. The conversion rate is 2 plasma sheets for 1 point. You must put the plasma in a crate for it to count.
    • -
    • The mecha toy prize promotion has officially ended. You can no longer redeem all 11 action mecha figures for a real mech. New toy redeeming promotions in the future will be considered.
    • -
    - -
    -

    21 December 2012

    -

    Ikarrus updated:

    -
      -
    • You can now use . to speak over headset department channels in addition to the : and # characters.
    • -
    - -
    -

    19 December 2012

    -

    Nodrak updated:

    -
      -
    • You can now use # to speak over headset department channels. For example say "#e Hello" will say "Hello" over the engineering channel. say ":e Hello" will still work as it always has.
    • -
    - -
    -

    16 December 2012

    -

    Giacom updated:

    -
      -
    • You can now create your own solar arrays! Order the solar pack crate and you'll receive 21 solar assemblies, 1 electronic which you can put into an assembly to make it a solar tracker and finally the solar computer circuit board. You will get more detailed instructions in the crate, on a piece of paper. Engineering will also start with this crate to help repair destroyed solar arrays.
    • -
    -

    Petethegoat updated:

    -
      -
    • Added a new option to the key authorisation devices. It removes the maintenance access requirement from all doors. It's irreversible, so only use it in an emergency!
    • -
    - -
    -

    15 December 2012

    -

    Ikarrus updated:

    -
      -
    • Swapped the locations of the Library and Chapel. Thanks to killerz104 for the remap.
    • -
    • Partial remap of atmos. Monitoring and Refill stations are now the same room.
    • -
    • Toxins Mixing should be working properly again.
    • -
    - -
    -

    12 December 2012

    -

    Ikarrus updated:

    -
      -
    • Robotics is now a full Science department.
    • -
    • Completely remapped Research Division, Robotics, Medbay, and the Library.
    • -
    • Partially remapped Cargo Bay, Mining Dock, Engineering, and Atmospherics.
    • -
    • Changed the access of the HoS and HoP. For a list, refer to their respective wiki pages.
    • -
    -

    Errorage updated:

    -
      -
    • Miners now have to go through cargo to reach the Mining Dock.
    • -
    -

    Petethegoat updated:

    -
      -
    • The Detective's revolver no longer cares about how cool you look. It now spawns in his locker.
    • -
    • Added new inhands for most energy weapons, by Flashkirby!
    • -
    -

    Giacom updated:

    -
      -
    • Disintegrate (EI NATH) will leave behind the brain of the victim. Possible productive uses include: trophies, looking awesome as you gib someone and only their brain remains, people to talk to when you get an MMI, pocket brains, a way to get back into the game if the wizard didn't grab your brain and stuffed it into his bag.
    • -
    - -
    -

    07 December 2012

    -

    Giacom updated:

    -
      -
    • The detective's scanner was upgraded, it can now scan for reagents in items and living beings. Potential uses include, scanning dead bodies for leftover poison or scanning items to see if they have been spiked.
    • -
    • You can now attach photos to newscaster news feeds and wanted posters.
    • -
    • You can now emag buttons to remove access from them.
    • -
    • The CentComm. Report has been changed so it no longer names potential antagonists. It will just announce the potential round type instead.
    • -
    - -
    -

    05 December 2012

    -

    Cheridan updated:

    -
      -
    • Agent cards have been upgraded with microscanners, allowing operatives in the field to copy access levels off of other ID cards.
    • -
    -

    Ikarrus updated:

    -
      -
    • The Chief Medical Officer, Research Director, Chief Engineer, and Lawyers now have basic Brig access (corridor only)
    • -
    • Merged Mining and Cargo radio channels into the Supply Radio. To use the supply channel, use :u
    • -
    • Mining Dock remapped to be more compact and closer to cargo.
    • -
    -

    Giacom updated:

    -
      -
    • The wizard's fireball spell is once again dumbfire. It will fire in the direction of the wizard instead of having to choose from a list of targets and then home in on them.
    • -
    -
    - -
    -

    02 December 2012

    -

    Giacom updated:

    -
      -
    • Added a new artefact called the "Staff of Animation". You can get it in the Wizard's Spellbook. It will animate objects and items, but not machines, to fight for you. The animated objects will not attack the bearer of the staff which animates them, meaning if you lose your staff, or if it gets stolen, your minions will turn on you.
    • -
    -
    - -
    -

    30 November 2012

    -

    Petethegoat updated:

    -
      -
    • Janitor has recieved a slightly upgrade mop bucket. The old one is still there too.
    • -
    -

    Ikarrus updated:

    -
      -
    • Swapped the locations of the Vault and Tech Storage.
    • -
    • Cargo Techs, Miners, and Roboticists no longer start with gloves. They are still available from their lockers.
    • -
    -
    - -
    -

    28 November 2012

    -

    Kor updated:

    -
      -
    • Slimes have replaced roros (finally)! Right now they are functionally identical, but massive expansion of slimes and xenobio is planned. Sprites are by Cheridan.
    • -
    -
    - -
    -

    25 November 2012

    -

    Giacom updated:

    -
      -
    • Added new very high level symptoms which are only obtainable in the virus crate. Virus crate will also come with mutagen.
    • -
    -

    Petethegoat updated:

    -
      -
    • Removed clown planet! It'll return shortly in away mission form.
    • -
    -

    Ikarrus updated:

    -
      -
    • Added Gateway access. Only the RD, HoP, and Captain start with this.
    • -
    • New access levels in the brig:
      -Brig access now opens the front doors of the brig, as well as other lower-risk security areas.
      -Security access allows you into the break room and equipment lockers.
      -Holding Cells allows you to use brig timers and lets you in the Prison Wing.
      -The Detective no longer has Security Equipment access.
    • -
    • Significantly increased max cloneloss penalty for fresh clones to 40%.
    • -
    -
    - -
    -

    23 November 2012

    -

    Giacom updated:

    -
      -
    • Simplified detective stuff. The high-res scanner is gone and instead the detective's normal scanner will instantly report all fingerprints, dna and cloth fibers in full. This was needed because the system took too long to work with and disencouraged detectives. Not only that, it made detectives less of a threat for antagonists and made possible scenerios, such as framing someone by changing fingerprints with someone else, impratical. To replace the computer, the detective will have a full medical computer with access to it. Not only that, but his useless filing cabinet will be replaced with an empty one for serious investigators. Along with this, are fingerprint cards and built-in PDA scanning, as all of security had access to it which was really the detective's thing. The new scanner will also log every finding and you can print them out as a report by clicking the scanner while it is in your active hand.
    • -
    • You can toggle the pressure of your sprayer by clicking on it while it is in your active hand. With pressure, the sprayer will spray 10 units on the floor, otherwise it sprays 5. You'll need to turn pressure on to spray water on the floor and make it slippery.
    • -
    • AIs in intellicards can no longer move their camera. This will limit them in ability but without making creating and carding an AI to have as a personel door opener impossible.
    • -
    • Telecommunication Busses can now be set to change the frequency of a signal. (Allowing you to say.. set the command channel to broadcast to the common channel).
    • -
    • Telecommunication was changed to be more effecient. Because of this, Relays don't need a broadcaster or a receiver and you can setup a relay on it's own. You can still disable sending and or receiving from the relay's interface.
    • -
    -

    Zelacks updated:

    -
      -
    • Plant Analysers now work on seed bags.
    • -
    -
    - -
    -

    21 November 2012

    -

    Petethegoat updated:

    -
      -
    • The nuke shuttle can now travel at will, and to any location. When travelling from syndicate space to the station, (and vice versa), it will travel through hyperspace.
    • -
    -

    Carn updated:

    -
      -
    • Changed savefile structure. There's a bunch of unused files left lying around so old savefiles will be purged. Sorry for the inconvenience. Many preferences have been moved to the Preferences verb tab. Everything in that tab is persistent between rounds (it updates your savefile, so even DCing won't reset them). Enjoy x
    • -
    -

    Phol updated:

    -
      -
    • Added female sprites for most mutant races.
    • -
    -

    Cheridan updated:

    -
      -
    • SSU manufacturers have issued a product recall! It seems old models shipped with faulty wiring, causing them to short-circuit.
    • -
    -
    - -
    -

    20 November 2012

    -

    Kor updated:

    -
      -
    • Added Exile Implants to the Gateway room. Someone implanted with an Exile Implant will be able to enter the away mission, but unable to return from it. Not only can they be used for getting rid of dangerous criminals, but revs/stationheads count as dead while on the away mission, and traitor/changeling/wizard assassination targets count as dead if they're on the away mission at round end, allowing for those objectives to be completed peacefully.
    • -
    • Added medical hardsuits, sprited by Majorsephiroth. Two of them spawn in EVA. Their most unique/medical oriented feature is being able to hold a medkit in the suit storage slot, allowing you to easily access medicine while keeping your hands free.
    • -
    -
    - -
    -

    19 November 2012

    -

    Giacom updated:

    -
      -
    • Malf AIs can only shunt to APCs from their core. Meaning their core needs to be alive before they can shunt to another APC. Malf AIs can start a takeover inside an APC now.
    • -
    • When taking damage, the next sequence of the overlay will show for a bit before reverting to the overlay you should have. This allows you to know you are taking damage without having to check the text screen.
    • -
    -
    - -
    -

    18 November 2012

    -

    Petethegoat updated:

    -
      -
    • Ported over BS12 style cameras. They now take a photo of a 3x3 area!
    • -
    • Catatonic people (those that have ghosted while alive) now count as dead for assasinate objectives.
    • -
    -
    - -
    -

    17 November 2012

    -

    Donkie updated:

    -
      -
    • You can now deconstruct and construct Air Alarms and Fire Alarms. Read wiki on howto.
    • -
    -

    Giacom updated:

    -
      -
    • Medical Cyborgs no longer lose the reagents in their hypospray when switching modes.
    • -
    • Spaceacillin will now help stop the spread of diseases.
    • -
    • You can once again make floors slippery by spraying water. This was done by increasing the amount the sprayer uses, which is from 5 to 10. You can also empty your sprayer's contents onto the floor with a verb in the Object tab.
    • -
    -
    - -
    -

    16 November 2012

    -

    Kor updated:

    -
      -
    • Fixed the syndicate teleporter door, making teleport assaults possible. It will once again open when you open the outter door.
    • -
    -
    - - -
    -

    15 November 2012

    -

    Giacom updated:

    -
      -
    • You can now name your advance diseases! You can't name already known diseases though.
    • -
    • Chemical implants can now hold 50 units instead of 10 units.
    • -
    -
    - -
    -

    13 November 2012

    -

    Giacom updated:

    -
      -
    • More work to advance diseases. Please report any bugs to the bug tracker, I have tried everything that I can on my own but I'll need lots of people playing to fix the more minor bugs. You can find a guide to making your own diseases here: LINK!
    • -
    • Reduced the cost to use Hive Absorb from 40 to 20. This is to help encourage people to use this power more and to use team work.
    • -
    • New symptom added! See if you can find it.
    • -
    • You can now remove symptoms from a disease using synaptizine.
    • -
    • Kor: You can once again debrain changelings. They won't make anyone half-lings though, and you won't be able to tell if the body of a debrained changeling is a changeling by putting a player brain in there.
    • -
    -

    Nodrak updated:

    -
      -
    • Wizards can no longer cast spells when muzzled. It iss now actually possible to capture a live wizard without constantly injecting them with chloral.
    • -
    • You can no longer take bags of holding or mechs to the clown planet.
    • -
    -
    - -
    -

    11 November 2012

    -

    Carn updated:

    -
      -
    • Admin-ranks changes
      - Lots of changes. This is just a brief summary of the most recent changes; still working on proper documentation.
      - All admins have access to view-vars, player-panel(for individual mobs), game panel and secrets panel. Most of the things on those pages have their own rights requirements. For instance, you can only use event orientated secrets in the secret panel if you have FUN rights. Debug secrets if you have DEBUG rights. etc.
      - Spawn xeno and toggle gravity procs were moved into the secrets panel (fun).
      - This may help with understanding which flags do what. Unfortuanately it's still somewhat vague.
      - If you have any problems, feel free to PM me at irc.rizon.net #coderbus. I go by the username carn or carnie. -
    • -
    -
    - -
    -

    11 November 2012

    -

    Kor updated:

    -
      -
    • New cyborg upgrade available for production that requires illegal and combat tech
    • -
    • Summon Guns has a new gun type created by Ausops. It also lets the user know when its been cast now to prevent people trying to buy it multiple times
    • -
    • Grilles are no longer immortal in regards to solid projectiles, you can now shoot out windows.
    • -
    -
    - -
    -

    09 November 2012

    -

    Giacom updated:

    -
      -
    • Cyborgs can now ping and beep! (Say "*beep" and "*ping") Thanks to Rahlzel for the proposal.
    • -
    • HULKS WILL NOW TALK IN ALL CAPS AND WILL RANDOMLY SAY HULK THINGS. Thanks to Brotemis for the proposal.
    • -
    • Sorry for the inconveniences with advance diseases. They are working much better now!
    • -
    • An improved APC sprite by TankNut!
    • -
    -
    - - -
    -

    05 November 2012

    -

    Giacom updated:

    -
      -
      -
    • AIs can now tweak with a bot's setting like a human who unlocked the bot.
    • -
    -
    - -
    -

    05 November 2012

    -

    Errorage updated:

    -
      -
    • Being in an area with extremely low pressure will now deal some damage, if you're not protected.
    • -
    • Space suits and the captain's armor now protect against pressure damage
    • -
    • Slightly lowered all environment damage intakes (temperature, oxygen deprevation) to make up for low pressure damage.
    • -
    • Pressure protection finally works properly. Items that protect from pressure (firesuits, space suits, fire helmets, ...) will now properly protect. The pressure damage indicator will update properly based on the pressure effects on you. Black (low) and red (high) mean you are taking damage.
    • -
    • Slightly slowed down the speed at which your body temperature changes if you are in a very hot or very cold area. The speed at which you recover from an abnormal body temperature remains the same.
    • -
    -
    - - -
    -

    03 November 2012

    -

    TankNut updated:

    -
      -
    • New APC sprite.
    • -
    • New Wraith sprite and jaunting animation.
    • -
    -
    - -
    -

    03 November 2012

    -

    WJohnston updated:

    -
      -
    • New Ablative Armor sprite.
    • -
    -
    - -
    -

    03 November 2012

    -

    Giacom updated:

    -
      -
      -
    • Airborne diseases will not spread through walls now.
    • -
    • Reduced queen healing rate to 5. The maximum health will be enough.
    • -
    • Aliens can now clear hatched eggs by clicking on them.
    • -
    -
    - -
    -

    02 November 2012

    -

    Errorage updated:

    -
      -
    • You can once again travel to the station, derelict, satellite and mining z-levels through space. You will also never loop into the same level on transition - So if you are exiting the derelict z-level, you will enter one of the other z-levels.
    • -
    -
    - - -
    -

    01 November 2012

    -

    Giacom updated:

    -
      -
    • Aliens now take x2 as much damage from fire based weaponary, instead of x1.5.
    • -
    • Doors are now weaker than walls; so normal weapons can destroy them much more easily.
    • -
    -
    - -
    -

    31 October 2012

    -

    Giacom updated:

    -
      -
    • Advance evolving diseases! Virology can now create, mutate and mix advance diseases together. I replaced the two bottles of blood in Virology with the advance disease. I'll write a wiki article soon enough. Here's a tip: Putting mutagen or virus food (a mixture of milk, water and oxygen) in blood with an existing disease will mutate it to gain symptoms. It can potentially lose old symptoms in the process, so keep backups!
    • -
    -
    - -
    -

    28 October 2012

    -

    Errorage updated:

    -
      -
    • You can now set your character's age up to 85. This used to be 45.
    • -
    -
    - -
    -

    27 October 2012

    -

    Petethegoat updated:

    -
      -
    • Mousetraps are now assemblies.
    • -
    • Added a new crate for cargo to order.
    • - -
    -
    - -
    -

    27 October 2012

    -

    Petethegoat updated:

    -
      -
    • Player Weekend begins!
    • -
    • Added a camera and hand labeler to art storage.
    • -
    • Added a medical records cabinet to the Detective's office.
    • -
    • Added a safe to the vault. Who'll be the first to crack it?
    • -
    -

    Nodrak updated:

    -
      -
    • The CE has a new pet!
    • -
    -
    - -
    -

    25 October 2012

    -

    Flashkirby99 updated:

    -
      -
    • Added 18 new hairstyles!
    • -
    -
    - -
    -

    24 October 2012

    -

    Giacom updated:

    -
      -
    • Throwing eggs will result in the reagents of the egg reacting to the target. (Which can be a turf, object or mob) This creates possibilities like chloral eggs, lube eggs, and many more.
    • -
    • Aliens can now acid walls and floors! Not R-Walls though.
    • -
    • Facehugger throw range reduced to 5, so aim at humans that are 2 tiles apart from the edge of your screen.
    • -
    • Making eggs is a little more expensive but secreting resin is cheaper. (Both cost 75 now)
    • -
    • Aliens no longer have a random duration of stunning humans, it's a constant value now of the lower based value.
    • -
    • Acid is less random and will be more reliable. Don't bother aciding stuff more than once, as it will waste plasma.
    • -
    • You can now target non-dense items (such as facehuggers) with a gun.
    • -
    • You can now shoot canisters, computers and windoors to break them.
    • -
    -
    - -
    -

    18 October 2012

    -

    Giacom updated:

    -
      -
    • As an AI, you can type in the "track with camera" command and get a list of names to show up there. This also works with "list camera" verb. Remember to use space to auto-fill.
    • -
    • Welding goggles have been added. They are like welding helmets but they are for the glasses equipment slot. Science and the assembly line are given a pair.
    • -
    • Thanks to WJohnston for the welding goggle icons.
    • -
    • Small change to the Assembly Line. Instead of six normal flashes, the Assembly Line will instead have two normal flashes and eight synthetic flashes. Synthetic flashes only work once but are designed to be used in construction of Cyborgs.
    • -
    • Nar-Sie put on a few pounds. Thanks HornyGranny.
    • -
    -
    - -
    -

    16 October 2012

    -

    Giacom updated:

    -
      -
    • New changeling powers!
    • -
    • Hive Channel/Hive Absorb. Allows you to share your DNA with other changelings, very expensive chemical wise to absorb (download), not so much to channel (upload)! You cannot achieve your objective by sharing DNA.
    • -
    • Mimic Voice! You can form your voice of a name you enter. You won't look like them but when you talk, people will hear the name of who you selected. While you're mimicing, you can't regenerate chemicals.
    • -
    • Extract DNA! A power that allows you to silently sting someone and take their DNA! Meaning you do not have to absorb someone to become them. Extracting their DNA doesn't count towards completing your objectives.
    • -
    • You can now get flares from red emergency toolboxes. Has a 50% chance of a flash-light or a flare spawning.
    • -
    • Flare icon by Ausops!
    • -
    • Thanks to RavingManiac (Smoke Carter), Roros now lay eggs which can grow into baby roros or be used for cooking recipes. Scientists will need to expose the egg to plasma for it to hatch; while it is orange (grown).
    • -
    • A new icon for the map spawned x-ray cameras. Icon by Krutchen.
    • -
    -
    - -
    -

    13 October 2012

    -

    Giacom updated:

    -
      -
    • Facehuggers have a new animation, thanks to Sly.
    • -
    • Firelocks, glass-less airlocks and walls will stop heat.
    • -
    • Fires are now more deadly, especially the flames.
    • -
    • Fires will now break windows.
    • -
    -
    - -
    -

    10 October 2012

    -

    Giacom updated:

    -
      -
    • Larva grow a little bit faster when on weeds or when breathing in plasma.
    • -
    -
    - -
    -

    8 October 2012

    -

    Giacom updated:

    -
      -
    • Thanks to Skasi. Atmospherics has been changed to be made simpler and spawn with the new atmos features, such as the heaters.
    • -
    • Radio headsets can only be heard by people wearing them on their ear slot. This will let us do more fun stuff with headsets, such as a traitor encryption key which can listen to all the channels, but not talk in them.
    • -
    - -

    Kor updated:

    -
      -
    • A pen no longer spawns in your pocket. Instead, each PDA will spawn with a pen already in it.
    • -
    -
    - -
    -

    5 October 2012

    -

    Giacom updated:

    -
      -
    • Aliens can now be harmed by fire. They now also take double fire damage, meaning flame based weaponry is very effective.
    • -
    • Buffed alien facehuggers and eggs. Facehuggers don't go idle anymore, and they attach to anyone who walks past them. Eggs do the same; fully grown eggs will open to potential hosts. If you are still in the range of them, the facehugger inside will leap out and hug you. Removed "activate facehuggers", since it's useless now. Emote "roar" if you want to roar now.
    • -
    • There can be only one living queen at a time, if the queen dies then a drone can take her place as a princess.
    • -
    • Buffed queen regeneration a bit, so it's not the same as her underlings. It's also more important because there can only be one queen at a time.
    • -
    • Aliens don't slip in space anymore.
    • -
    • Hulks don't paralyze aliens anymore, they instead slow them down to a slow crawl. It is very effective for punching aliens out of weeds, so it can't regenerate it's health.
    • -
    • New egg opening and opened egg icons by WJohnston.
    • -
    -

    Aranclanos updated:

    -
      -
    • A buncha crud nobody cares about lol Added a light to the airlock wiring interface to show the status of the timing.
    • -
    • You can't fill sprays without being next to the dispenser.
    • -
    • Simple animals no longer freeze to death in places with normal temperature.
    • -
    • Mechs no longer freeze on the spot when they are using the Energy Relay on powerless areas.
    • -
    • Improvements to showers, they now clean gear on beltslot, back, ears and eyes. Showers only clean visible gear.
    • -
    • Replica pods works again! But you can't make potato people without a key or clone people who ghosted alive (Catatonic).
    • -
    • Engiborgs can deconstruct airlocks with their RCDs once again.
    • -
    • You can construct airlocks while standing on another airlock with RCDs.
    • -
    -
    - -
    -

    3 October 2012

    -

    Agouri updated:

    - -
    - -
    -

    1 October 2012

    -

    Cheridan updated:

    -
      -
    • Wizards have a new artifact added to their spellbooks.
    • -
    -
    - - -
    -

    30 September 2012

    -

    Numbers updated:

    -
      -
    • Readded Volume Pumps - now they work as intended and are constructable
    • -
    • Readded Passive Gates - now they work as intended and are constructable
    • -
    • Readded Heat Exchangers - now they work as intended and are constructable
    • -
    • Added Heater - to warm up gasses to 300C
    • -
    • Pipe dispensers can produce the readded pieces.
    • -
    • New graphics for all of the above - courtesy by Ausops.
    • -
    -
    - -
    -

    30 September 2012

    -

    Giacom updated:

    -
      -
    • Airlocks now use the Environmental power channel, since they are airlocks after-all. Meaning, when power is low the airlocks will still work until the environmental channel on the APC is turned off. This applies to all the door control buttons too. Pipe meters now use the environmental power channel. If you have any comments have this change, please let me know in the feedback section of the forums.
    • -
    -
    - -
    -

    26 September 2012

    -

    Carnwennan updated:

    -
      -
    • Added new hotkeys. Type hotkeys-help for details or see the drop-down help menu at the top of the game window.
    • -
    -

    Aranclanos updated:

    -
      -
    • Mechs are once again spaceproof!
    • -
    • The YouTool machine is now all access
    • -
    • Cutting tower caps in hand no longer deletes the wood, and planks now auto stack
    • -
    -
    - -
    -

    25 September 2012

    -

    Donkie updated:

    -
      -
    • Reworked the Piano, now really optimized and new interface!
    • -
    -
    - -
    -

    24 September 2012

    -

    Petethegoat updated:

    -
      -
    • Hopefully fixed the stop midis button. It should now stop any midis that are currently playing.
    • -
    -
    - -
    -

    23 September 2012

    -

    Petethegoat updated:

    -
      -
    • Fixed an exploit which would allow the janitor to magically mop floors.
    • -
    • Added lipstick~ It's not available on station, as Nanotrasen has deemed it contraband.
    • -
    • If you encounter any issues with computers, notify an admin, or ask for assistance on #coderbus, on irc.rizon.net.
    • -
    -

    Donkie updated:

    -
      -
    • Updated the Package Tagger with new interface!
    • -
    • You can now dispense, remove and retag sort junctions properly!
    • -
    -
    - -
    -

    17 September 2012

    -

    Cheridan updated:

    -
      -
    • Metroids have been replaced with Rorobeasts. Roros are strange latex-based lifeforms that hate light, fun, and gloves.
    • -
    -
    - -
    -

    17 September 2012

    -

    Carn updated:

    -
      -
    • F5 is now a hotkey for adminghosting. F8 toggles ghost-like invisibility for admins.
    • -
    • Catatonia makes you fall down. Admins appear braindead when admin-ghosting.
    • -
    • "Set-observe"/"Set-play" renamed and merged into "Aghost".
    • -
    • "Lay down/Get up" renamed to "Rest"
    • -
    • Closets can't be sold on the supply shuttle anymore
    • -
    • Fixed all dat light
    • -
    -
    - -
    -

    13 September 2012

    -

    Carn updated:

    -
      -
    • New Hotkeys (Trial period). Details can be found in the help menu or via the hotkeys-help verb. It's all client-side. It shouldn't intefere with regular controls (except ctrl+A, ctrl+S, ctrl+D and ctrl+W).
    • -
    -
    - -
    -

    10 September 2012

    -

    Giacom updated:

    -
      -
    • AIs can double click on mobs to instantly start tracking them.
    • -
    -
    - -
    -

    Important note for server hosts!

    -

    Important note for server hosts!:

    -
      -
    • The file /code/defines/hub.dm was moved into /code/hub.dm. To get your server back on the hub, open /code/hub.dm and set the hub variables again. Sorry for the inconvenience.
    • -
    -
    -
    -

    8 September 2012

    -

    Carn updated:

    -
      -
    • Added an additional check to stop changelings sharing powers/becomming un-absorbable/etc by absorbing eachother and then rejuvinating from death.
    • -
    • Cloaked Aliens are now slightly easier to see, so they should avoid strongly lit areas when possible. They can still lay down to become even stealthier though. Let me know what you think, it's only a minor sprite change.
    • -
    -
    - -
    -

    6 September 2012

    -

    Cheridan updated:

    -
      -
    • -Changes flour from an item to a container-held reagent. All recipes have been updated to use 5 units of reagent flour for every item required previously. This has a few advantages: The 16(!) sacks of flour previously in the kitchen cabinet have been condensed to an equivalent 3 sacks. Beer is now brewable with universal enzyme, and converting lots of wheat into flour should be less tedious. Also, flour grenades, etc. Because of this, flour is now obtained from the all-in-one blender rather than the processor, and spaghetti noodles are made with 5 units of flour in the microwave.
    • -
    -
    - -
    -

    6 September 2012

    -

    Giacom updated:

    -
      -
    • Removed cameras from bots (NOT BORGS). They weren't working well with freelook and I felt that since they weren't used at all, they wouldn't be missed.
    • -
    -
    - -
    -

    3 September 2012

    -

    Giacom updated:

    -
      -
    • Cameras has changed quite a bit. They are no longer created from grenade canisters, instead you make them from an autolathe. The construction and deconstruction for them has also changed, so look it up or experiment it with yourself to see how to setup the cameras now. Cameras also get wires, like airlocks and APCs. There's two duds, a focus wire, a power wire, an alarm wire and a light wire. Protip: You can see which one is the alarm wire by pulsing it.
    • -
    • Added a red phone and placed it in the Cyborg Station. Sprite by Pewtershmitz! You'll also find an AI restorer there, replacing the computer frame.
    • -
    • Cameras aren't all X-ray anymore. The AI won't be able to see what room you are in if there's no normal camera inside that room or if there's no X-ray camera nearby..
    • -
    • Cameras get upgrades! Currently there's X-ray, EMP-Proof and Motion. You'll find the EMP-Proof and Motion cameras in the normal places (Singularity Pen & EVA), the new X-ray cameras can be found in the Dormitory and Bathrooms, plus some extra ones to invade your privacy. See if you can smash them all.
    • -
    • Alien Larva can bite simple animals (see: Ian, Runtime, Mice) to kill them and gain a small amount of growing points.
    • -
    • Space travel was tweaked to be more random when changing Z levels. This will stop people and items from being stuck in an infinite loop, as they will eventually hit something to make them stop.
    • -
    -
    - -
    -

    31 August 2012

    -

    Agouri updated:

    -
      -
    • Overhauled newscasters. No visual additions but the thing is much more robust and everything works as intended. Wanted issues are fixed. Admins, check out Access News Network under Fun.
    • -
    -
    - -
    -

    30 August 2012

    -

    Giacom updated:

    -
      -
    • You can now create an EMP Pulse. Like an explosion, it is the mixing of two reagents that trigger this to happen. I will tell you the first required reagent. Uranium. Have fun!
    • -
    • I have made most chemicals need 3-5 or more chemicals in order to react to a turf. For instance, you need at least 5 units of thermite splashed on a wall for it to burn down."
    • -
    • The EMP kit, that you can buy through the uplink, has two more grenades in them now. Making the box full of EMP grenades!
    • -
    • Changed the EMP grenade's range to be much bigger.
    • -
    -
    - -
    -

    29 August 2012

    -

    Nodrak updated:

    -
      -
    • Mice now work with the admin player panel. Admins can now turn players into mice with the 'Animalize' button in the player panel!
    • -
    • Space bear AI no longer runs when a player is controlling it. Admins can now turn players into space bears with the 'Animalize' button in the player panel!
    • -
    • The holodeck beach program once again has a beach.
    • -
    • The nuke op shuttle floor was pressure-washed a few days ago. We have since re-painted it with nanotrasen blood. Sorry for any confusion.
    • -
    -
    - -
    -

    28 August 2012

    -

    Giacom updated:

    -
      -
    • You can now toggle the bolt light of airlocks. An extra wire, that controls the airlock's bolt light, has been added.
    • -
    • Aliens can now tell who is and who isn't infected. They get a special facehugger icon that appears over mobs that have been impregnated.
    • -
    • Cameras have temporary X-Ray for the time being.
    • -
    -
    - -
    -

    August 26, 2012

    -

    Nodrak updated:

    -
      -
    • Admins now have an 'Animalize' button on a mob's player panel. This button allows admins to turn players into simple animals.
      There are a few exceptions. Mice, Parrots, Bears and Space Worms all have issues that, until fixed, prevent me from allowing players those transformations.
    • -
    -

    August 25, 2012

    -

    Carnwennan updated:

    -
      -
    • New lighting. It should look and feel the same as the old lighting whilst being less taxing on the server. Space has a minimum brightness (IC starlight) and areas that do not use dynamic lighting default to a lighting level of 4, so they aren't dark, but they aren't superbright. Replacing turfs should preserve dynamic lighting. Singulo/bombs should cause a lot less lighting-related lag. There are some minor known issues, see the commit log for details.
    • -
    • Admins can now access most controller datums with the "Debug Controller" verb. Time to break all the things!
    • -
    • Supply shuttle now uses a controller datum. This means admins can see/edit supply orders etc.
    • -
    • Changeling fakedeath can be initiated after death again. Next time you want something reverted, just ask rather than being obnoxious.
    • -
    -

    Giacom updated:

    -
      -
    • AIs can now look around like a ghost with the exception that they cannot see what cameras cannot see. Meaning if you're in maintenance, and there's no cameras near you, the AI will not know what you are doing. This also means there's no X-Ray vision cameras anymore.
    • -
    • AIs can add links to Telecommunication Machines. Added some cameras for areas that should have it but instead relied on cameras nearby for vision.
    • -
    • Choking has been changed. You have to stand still while lethally choking someone. It takes time to get into that lethal choke. When you are lethaling choking someone, they are still concious until the lack of oxygen knocks them out.
    • -
    -

    trubble_bass updated:

    -
      -
    • Nerfed the Neurotoxin drink, it is now less effective than a stunbaton. But more effective than a Beepsky Smash.
    • -
    • Updated descriptions on various cocktails to be more accurate or more relevant to the drink itself.
    • -
    -
    - -
    -

    August 24, 2012

    -

    Sieve updated:

    -
      -
    • Floorbots now actually pull up tiles when emagged
    • -
    • All helper bots (excluding MULEs) have an access panel and maint panel, access being for behavior and maint for internal work
    • -
    • To open the maint panel, the access panel needs to be unlocked, then you use a screwdriver. There you can emag/repair it to your heart's content. (Emagging the access panel will also unlock it permanently)
    • -
    • Helper bots are now repaired by using a welder when their maint panel is open
    • -
    -
    - -
    -

    August 23, 2012

    -

    Nodrak updated:

    -
      -
    • In-hand sprites once again update correctly when equipping items.
    • -
    -
    - - -
    -

    August 16, 2012

    -

    Errorage updated:

    -
      -
    • Changes were made to how heating and cooling of humans works.
    • -
    • You must wear both a space suit and space helmet to be protected from space! Likewise you must wear a firesuit and a fire helmet to be protected from fire! Fire helmets are red and white hardhats, found in all fire closets.
    • -
    • Fire suits now only protect from heat and space suits only protect from cold, so make your choice count.
    • -
    -
    - - -
    -

    August 14, 2012

    -

    Sieve updated:

    -
      -
    • DNA modifiers can be used if there is no occupant, primarily to handle the buffer.
    • -
    • Ion Rifles are only effected by max severity EMPs, so AOE from its own shot won't effect it
    • -
    • Pepper Spray fits on Sec belts again
    • -
    -
    - -
    -

    August 11, 2012

    -

    Sieve updated:

    -
      -
    • Turrets now properly fire at simple_animals.
    • -
    • Borgs, AIs, and brains/MMIs can be sacrificed by cultists.
    • -
    • Grenades now automatically set throw on again.
    • -
    -
    - -
    -

    August 6, 2012

    -

    Dingus updated:

    -
      -
    • Library has been redesigned. It's a whole lot more classy now.
    • -
    • Significant changes to Medbay. CMO's office is more centralized, genetics has a new exit into cryogenics, and a new break room has been installed
    • -
    -
    - -
    -

    August 4, 2012

    -

    Icarus updated:

    -
      -
    • Changes to Med-Sci south and surrounding maintenance areas. Virology is more isolated and Science gets a new Misc. Research Lab.
    • -
    • Atmos techs get construction access now to do their little projects in.
    • -
    • Transformation Stings now work on living humans.
    • -
    -
    - -
    -

    August 2, 2012

    -

    Errorage updated:

    -
      -
    • Gas masks now protect you from reagent smoke clouds
    • -
    • Changed the 'black overlay' you get when paralyzed, blind or in critical condition to include a small circle around you.
    • -
    • Dramatically lowered the amount of damage you get per breath while in critical condition. Critical condition now lasts for about 5 minutes if nothing is causing you any additional harm. This in combination with the new black image overlay is an attempt at making doctors more willing to help.
    • -
    -

    Icarus updated:

    -
      -
    • Borgs now have flashlights to allow them to see in lightless areas
    • -
    • Changes to Medbay: The sleeper and storage rooms have been swapped around. Hopefully this leads to more healing and less looting.
    • -
    -
    - -
    -

    August 1, 2012

    -

    Sieve updated:

    -
      -
    • Borgs can now have an encryption key installed into their internal radios. Simply ID, open the panel, and use the key to insert it (Screwdriver to remove)
    • -
    • Due to that as well, borgs have a 'Toggle Broadcast Mode' button for their radios, which changes the broadcast type between station-bounced (Non-reliant on TComms), and subspace (Required for department channels)
    • -
    • Also changed the binary chat for consistency, now for the prefix is ':b' for everyone, not just one for humans and one for borgs/AIs/pAIs
    • -
    • Based on feedback, Nuke Op pinpointers now automagically change between shuttle and disk mode when the nuke is armed or disarmed.
    • -
    -
    - -
    -

    01-August-2012

    -

    Carn updated:

    -
      -
    • Please update your BYOND clients! Ideally everybody should be running the latest version of byond (v496). People who fail to update to at least version 494 within a month's time may find themself unable to connect. Currently our code has no restrictions at all, which is rather bad. By getting the user-base to keep their clients up-to-date we can make use of newer BYOND features reliably.
    • -
    -

    Giacom updated:

    -
      -
    • I've made some adjustments to the Fireball spell. I've changed it to shoot in the player's facing direction instead of you having to pick a name from a list. It will explode upon contact of a person, if it hits an obstacle or if it shoots for too long. To make up for the fireball not being able to go diagonal I've shortened the cooldown to 10 seconds. It still can hurt you badly and knock you down if you shoot it at a wall. Lastly, it now lights up so it'll show up in dark rooms easily.
    • -
    -
    - -
    -

    31 July 2012

    -

    Giacom updated:

    -
      -
    • Removed passive throwing. You need at least an aggressive hold of the mob before you can throw them.
    • -
    • New map changes by Ikarrus. AI Upload Foyer is now Secure Tech Access, and the outer door only requires Bridge access. Attached to it are two new rooms: The messaging server room and the communications relay. The comms relay room runs off its own SMES unit like the AI, so it won't be affected by powersinks
    • -
    -
    - - -
    -

    29 July 2012

    -

    Giacom updated:

    -
      -
    • All radios now only work in their Z level. This means that the CommSat has a few more additions to work with this change. There is now a new Telecomms Machine called the Relay which allows information to travel across Z levels. It it then linked to a new machine called the Hub, which will receive information from the Relays and send it to the buses. Because every Z level needs these relays, which are linked up with Receivers/Broadcasters, every Z level will get one. There is one in the station, in the RD's office, one in Telecomms as always, one in the Ruskie station which is turned off and hidden from the HUB's linked list. The last one is in Mining but the location for it has not been decided yet.
    • -
    • PDAs now need to be in a Z level with a functioning Relay/Comms Network in order to send messages. It will also send uncompressed (scrambled) messages like you would with the ordinary voice messages.
    • -
    • Added some of WJohnston's sprites. Added a new mining borg sprite, Added a new high tech security airlock, Added the new telecomm sprites for Relays. Hubs were given old Bus sprites.
    • -
    -
    - -
    -

    29 July 2012

    -

    Errorage updated:

    -
      -
    • You can now use crayons to color eggs
    • -
    • Mice have invaded the station!
    • -
    -
    - -
    -

    26 July 2012

    -

    Giacom updated:

    -
      -
    • Added a new mushroom for Hydroponics, the Reishi Mushroom! It is obtained like any other mushroom and it has relaxing properties.
    • -
    -
    - -
    -

    July 25, 2012: The day of updates!

    -

    Nodrak updated:

    -
      -
    • Attacking mobs with items will now give new messages. Instead of "Monkeyman was attacked in the head with a wrench by Nodrak." it will read "Monkeyman was bashed in the head with a wrench by Nodrak." Diffrent items have diffrent verbs and some have multiple verbs.
    • -
    • Cultists can now read what words a rune was made with by examining the rune. Due to an error in the code, this was not possible before.
    • -
    • Clowns no longer have practice lasers or staves of change blow up in their face due to clumsyness.
    • -
    • Engineering cyborgs can now actually repair a cut AI wire in APCs.
    • -
    • I've removed a ton of pointless checks and redundant loops from metroid's which have been causing lag due to how often they get called. If metroids are behaving strangly ping me in #coderbus
    • -
    -

    Sieve updated:

    -
      -
    • Made a 'default' save slot (D), and whenever you connect it automatically selects the default slot to load from, but manually selecting a different slot will allow you to play on that one before it returns to default.
    • -
    • Added the ability to name your save slots with the '*'. Names can be up to 16 characters and contain letters, numbers, and basic symbols
    • -
    • The preview icon on the preference screen now takes into account any job you have set on high, and dresses up the icon accordingly. If assistant is set to 'yes', or AI/Cyborg are on high it will put the icon in a grey suit (So you can still customize).
    • -
    • Nuke Ops get a new pinpointer, changing modes with the verb will switch between pointing to the disk, and pointing to the shuttle. Also provides a notification when you leave the station z-level
    • -
    • Reworked how MMI Life() was done, now they will never lose consciousness, and many less things affect them now(Like deafening/blindness from explosions). However, they are vulnerable to EMPs, but all damage is temporary.
    • -
    • Clowns will no longer be killed trying to use holo eswords
    • -
    • Major tweaking to try and optimize many operations on the game's backend. Hopefully, this will reduce a large amount of lag by steamlining CPU-intensive operations, but at the same time there was so much changed that there is no real way for a small group to test everything. If anyone spots a bug involving being unable to 'find' mobs, characters, whatever, then put it on the issue tracker or at the very least let #coderbus know. We can't fix shit unless we know about it.
    • -
    -

    Icarus updated:

    -
      -
    • Players not buckled in when the emergency shuttle/pod starts moving get will get knocked down.
    • -
    • Added a YouTool vending machine to primary tool storage.
    • -
    -
    - -
    -

    24 July 2012

    -

    Errorage updated:

    -
      -
    • Both the chef and bartender have access to the bar area so both can serve if the other is incompetent or does not exist. Bartender's shotgun and shaker were moved to his back room and the booze-o-mat is now ID restricted to the bartender.
    • -
    • Added powercells into vending machines in engineering
    • -
    • Gave two beartraps to the janitor for pest control purposes................
    • -
    -
    - -
    -

    22 July 2012

    -

    Errorage updated:

    -
      -
    • Mech toys can now be redeemed at the quartermaster's for a great reward! If you collect the full set of 11 toys you should put them in a crate and send them to centcom via the supply shuttle.
    • -
    • Supply shuttle arrival time reduced to 2 minutes
    • -
    • Hopefully fixed the toy haul problem which made it possible to get a million toys from arcade machines.
    • -
    -

    Giacom updated:

    -
      -
    • You can now make newlines with your PDA notes.
    • -
    • You can now research and build the Light Replacer.
    • -
    • You can now store donuts in the donut box. The next donut you pull out will be the last one you put in.
    • -
    • APCs will auto-turn on if there is enough power in the grid, even if the powercell is below 30%. The APC needs to be charged for a long enough time before it starts turning equipment on, to avoid spazzing out. If you have any problems with it, such as equipment turning off and on repeatedly then please make an issue report with a screenshot of the APC.
    • -
    -
    - -
    -

    18 July 2012

    -

    Giacom updated:

    -
      -
    • Added the Light Replacer. This is a device that can auto replace lights that are broken, missing or burnt. Currently it is found in the Janitor's closet and Janitor Borgs can equip it. You can refill it with glass, or if you're a Cyborg, just recharge. It is emaggable and will replace lights with rigged lights. The light's explosion was nerfed to help balance it and it is very noticable when you are holding an emagged Light Replacer.
    • -
    • The Janitor's equipment locator, on their PDA, will now tell you the direction of the equipment.
    • -
    -
    - -
    -

    17 July 2012

    -

    Icarus updated:

    -
      -
    • Added department satchels
    • -
    • Added Captain's Backpack and Satchel
    • -
    • Added three new hairstyles by Sly: Gelled, Flat Top, and Pigtails. Hair list has also been sorted by grouping similar styles.
    • -
    -

    Giacom updated:

    -
      -
    • Added a new wire for Cyborgs. See if you can figure out what it does.
    • -
    • You can now fill any container with a sink. You can change the amount to fill, from sinks, by setting your container's transfer amount.
    • -
    -
    - -
    -

    14 July 2012

    -

    Carn updated:

    -
      -
    • All living mobs can now ghost whenever they want. Essentially making the suicide verb obsolete. If you ghost whilst still alive however, you may not re-enter your body for the rest of the round.
    • -
    • Humans can no longer suicide whilst restrained (this is purely to prevent meta whilst I finish up the new FUN suicides)
    • -
    • Fixed dem evidence bags. Fixed metroids getting at it like rabbits. Fixed stuff like welding masks not hiding your face. Bunch of other things
    • -
    -

    Willox and Messycakes updated:

    -
      -
    • pAI Emoticons! Allows each pAI to set their screen to display an array of faces! Click on 'Screen Display' in the pAI OS for a list.
    • -
    -
    - - -
    -

    Saturday July 14th 2012

    -

    Giacom updated:

    -
      -
    • Added Russian Revolvers. This is a special Revolver that can only hold a single bullet randomly in it's chamber. This will allow you to play Russian Roulette with your fellow crew members! You can use it like a normal gun but you will need to cycle through the chamber slots until you hit the bullet. Only admin spawnable.
    • -
    -
    - -
    -

    Friday July 13th 2012

    -

    Carn updated:

    -
      -
    • Added FLOORLENGTH HAIR. YEESSSSSSSS!!!! :3 If you like it say thanks to Ausops for fixing it up. Credits to Powerfulstation for the original sprite.
    • -
    -

    Giacom updated:

    -
      -
    • Save Slots! You can now have separate save slots for different character setups, with a customizable maximum of 3 slots per account. If you are wondering, you will not lose your old saved setup.
    • -
    • The character setup screen was updated to look nicer and to fit on the screen.
    • -
    -

    Icarus updated:

    -
      -
    • Added new Dwarf and Very Long hairstyles. Dwarf hair and beard by SuperCrayon.
    • -
    -
    - -
    -

    Thursday July 12th 2012

    -

    Giacom updated:

    -
      -
    • pAI gets a better PDA that can actually receive messages from people. They can also instantly reply like everybody else now and they can toggle their receiver/signaller/ringer.
    • -
    • You can show the AI the notes on your PDA by holding it up to a camera. When you show up a paper/pda to the camera the AI can now click on your name to go to you, if you're near a camera. People who are Unknown will not have a link; which would've allowed the AI to track them.
    • -
    • Made the" common server" and the "preset right receiver" listen for frequencies 144.1 to 148.9. This will allow people to use different frequencies to talk to eachother without bothering the common channel. It will also allow Revs and Cultists to work with each other; everything is still logged though so it still has risks.
    • -
    • Increased the maximum frequency limit for handheld radios and intercoms. It will give you the option to just use station bounced radios on a higher frequency so that anyone with a headset can't simply tune in.
    • -
    • Created an All-In-One Grinder that is suppose to replace the blender, juicer and reagent grinder all together. Meaning any department that has a juicer, blender and grinder will instead get this. It will help people be more independent from Chemistry by recycling foods and plants.
    • -
    -
    - -
    -

    Wednesday July 11th 2012

    -

    Nodrak, Cheridan and Icarus updated:

    -
      -
    • Added a couple of Emergency Shield Projectors to Engineering secure storage. -

      Note: Credit goes to Barhardar for the original code and functionality. -

      These devices can be used to quickly create an air-tight seal across a hull breach until repairs can been made. -

      Wrench them in place and activate them near a hull breach. The shield should extend to all space tiles in range. -

      They can be (un)locked by engineering IDs and can also be emagged and otherwise malfunction. As they can not be constructed, you can repair damage and malfunctions by opening the panel with a screwdriver and replacing the wires with a cable coil

    • -
    -

    Giacom updated:

    -
      -
    • Chemistry update: Pills can now be ground up in reagent grinders. You can now put custom amounts of reagent into things using chemmasters. Can now load pill-bottles into chemmasters for mass pill-production.
    • -
    -

    Carn updated:

    -
      -
    • Clicks on inventory slots with items in now act like a click on the thing in that slot. So clicking smaller things (like pens) is easier and you can remove clothing that borks/goes invisible. Please continure to report those kinds of bug though please. Thanks x
    • -
    • Can no longer interact with your inventory with a mech.
    • -
    -

    Errorage updated:

    -
      -
    • You can now only adminhelp once every 2 minutes so please provide all necesary information in one adminhelp instead of 5! Also reply to admins in PM-s and not additional adminhelps.
    • -
    -
    - -
    -

    Saturday July 7th, 2012

    -

    Icarus updated:

    -
      -
    • A basketball simulation is now available at the holodeck. Credit to Sly and Ausops for the sprites.
    • -
    -
    - -
    -

    Friday July 6th, 2012

    -

    Giacom updated:

    -
      -
    • Bottles can now be broken over people's heads! To do this, you must have the harm intent on and you must be targeting the person's head. This change affects alcoholic bottles only. It does not change pill bottles or chemistry bottles. Helmets help protect you from damage and the regents of the bottles will splash over the victim.
    • -
    • AI's now have access to a PDA. Note: It is not PDA-bomb-able
    • -
    • Health analyzers and medical PDAs now give a time of death when used on corpses.
    • -
    -
    - -
    -

    Thursday July 5th, 2012

    -

    Carn updated:

    -
      -
    • Alien larva now chestburst even after their host has died.
    • -
    • Aliens can now slap facehuggers onto faces so they can infect mobs which lay down (or those stuck to nests).
    • -
    • Aliens can now slash security cameras to deactivate them.
    • -
    -
    - -
    -

    Wednesday July 4th, 2012

    -

    39kk9t & Carn updated:

    -
      -
    • Added alien nests. They're basically beds made of thick sticky resin which aliums can 'stick' (buckle) people to for sexytimes
    • -
    • Weed nodes are no longer dense.
    • -
    • Queens can secrete resin for walls/nests/membranes
    • -
    • Various bugfixes
    • -
    -
    - -
    -

    Saturday June 30th, 2012

    -

    Icarus updated:

    -
      -
    • Added Petethegoat's basic mirrors to the map. They allow you to change hairstyles.
    • -
    • Remapped Bar, Theatre, and Hydroponics. Bar and Kitchen are now more integrated with each other.
    • -
    -
    - -
    -

    Thursday, June 28th

    -

    Nodrak updated:

    -
      -
    • I'm currently working on cleaning up and moving around a large portion of the mob code. These changes do not directly affect players; HOWEVER, bugs, oversights or simple mistakes may cause problems for players. While I have tested as much as I can, there may be some lingering bugs I have missed.

      This part of the mob code cleanup mainly focuses on damage variables and procs. So if you suspect something related to taking, dealing or examining damage is not working as intended please fill out an issue report here and be as detailed as possible. This includes what you were doing, steps to reproduce the problem, who you were doing it to, what you were using ect... Thank you.

    • -
    -

    Carn updated:

    -
      -
    • Alien hunters will now cloak when using the 'stalk' movement intent. Whilst cloaked they will use up their plasma reserves. They can however cloak as long as they like. Using the Lay-down verb will allow them to remain cloaked without depleting their plasma reserves, hence allowing them to lay ambushes for unsuspecting prey. Should a hunter attack anybody, or get knocked down in any way, they will become visible. Hopefully this allows for more strategic/stealthy gameplay from aliens. On the other hand, I may have totally screwed the balance so feedback/other-ideas are welcome.
    • -
    • Removed the invisibility verb from the alien hunter caste.
    • -
    -
    - -
    -

    Wednesday, June 27th

    -

    Errorage updated:

    -
      -
    • Fixed the bug which prevented you from editing book's titles and authors with a pen. Also fixed the bug which prevented you from ordering a book by it's SS13ID.
    • -
    • Added the F12 hotkey which hides most of the UI. Currently only works for humans.
    • -
    -

    Donkie updated:

    -
      -
    • Pizza boxes! Fully stackable, tagable (with pen), and everythingelse-able. Fantastic icons by supercrayon!
      Created with a sheet of cardboard.
    • -
    -
    - -
    -

    Tuesday, June 26th

    -

    Errorage updated:

    -
      -
    • Changeling parasting now only weakens for 10 game ticks. It no longer silences your target.
    • -
    -
    - -
    -

    Saturday, June 23rd

    -

    Donkie updated:

    -
      -
    • Reworked job randomizing system. Should be more fair.
    • -
    • List of players are now randomized before given antag, this means that declaring as fast as possible doesn't mean shit anymore!
    • -
    -

    Carn updated:

    -
      -
    • Putting a blindfold on a human with lightly damaged eyes will speed up the healing process. Similar with earmuffs.
    • -
    • More overlay bug fixes. Most of it to do with little robots and construction stuff. Bugs go here if you have 2 minutes http://nanotrasen.com/phpBB3/viewtopic.php?f=15&t=9077
    • -
    • Weakening is instant! That means if you stunbaton somebody they're gonna fall-down immediately.
    • -
    -

    Icarus updated:

    -
      -
    • Medical storage now requires Surgery access (Medical Doctors only)
    • -
    -
    - -
    -

    Wednesday, June 20th

    -

    Nodrak updated:

    -
      -
    • AIs, Borgs are no longer able to be cultists or revolutionaries as their objectives completely contradict their laws. They can still be subverted of course.
    • -
    • pAI's no longer keep cult or rev icons.
    • -

    Cheridan updated:

    -
      -
    • -Both Ambrosia forms have had their reagent contents modified to prevent going over the 50-unit cap at high potencies. Ambrosia Deus now contains space drugs instead of poison.
    • -
    • -Drinking milk removes capsaicin from your body. REALISM!
    • -
    • -Frost oil hurts less upon consumption.
    • -
    • -Liquid plasma can be converted into solid plasma sheets, by mixing 20 plasma, 5 iron, and 5 frost oil.
    • -
    • -Added effects for holy water injection on hydroponics plants.
    • -
    -
    - -
    -

    Monday, June 18th

    -

    Giacom updated:

    -
      -
    • Fix for special characters on paper and from announcements
    • -
    -

    Sieve updated:

    -
      -
    • Various small bugfixes, check the commit log for full details
    • -
    • Fixed falsewalls not working
    • -
    • Made Lasertag ED-209's and turrets much more useful, including making their emag function more fitting
    • -
    • Added Mesons to the EngiVend to make up for how many lockers were removed
    • -
    • New Item: Sheet Snatcher. Right now only borgs have them, but they can hold up to 500 sheets of minerals (Of any combination), and auto-stacks them to boot. Used just like the mining satchels, meaning minerborgs can actually deliver metal
    • -
    • Mech drills can mine sand, and the diamond gets a much larger volume
    • -
    • If a borg has the satchel in its modules (Doesn't have to be the active one), it will auto-magically pick up any ores it walks over.
    • -
    • Bumping an asteroid wall with a pickaxe/drill in your hand makes you auto-magically start drilling the wall, making mining much less tedious (humans and borgs)(Also, gustavg's idea)
    • -
    -

    Icarus updated:

    -
      -
    • New afro hairstyles. Big Afro by Intigracy.
    • -
    -
    - -
    -

    Friday, June 15th

    -

    Carnwennan updated:

    -
      -
    • First update for update_icons stuffs:
      Fixed husking and fatties
      Fixed floor tiles still appearing in hand when laying them
      Fixed runtimes with fatties.
    • -
    • Fixes for pre-existing bugs:
      Fixed being unable to put belts & backpacks on other people
      nodamage (godmode) now prevents all organ damage. It does not stop healing however.
      Nerd stuff...
    • - -
    -

    Errorage updated:

    -
      -
    • Greatly reduced the amount of damage high pressure does.
    • -
    • Fire suits, firefighting helmets (red harhats) and the chief engineer's white hardhat now protect against high pressure.
    • -
    -

    Icarus updated:

    -
      -
    • Ported over ponytail sprites from Baystation
    • -
    -
    - -
    -

    Thursday, June 14th

    -

    Carn updated:

    -
      -
    • FEAR NOT! You can now store a pen in your pda. (aka Best commit all commits)
    • -
    -
    - -
    -

    Wednesday, June 13th

    -

    Carn updated:

    -
      -
    • Massive Mob-Icon Overhaul:
      A large amount of the mob code has been replaced. The systems replaced were causing immense performance issues so the following are very necessary optimisations.
      However, there is a downside: SS13 code is the equivilant of monkeys on typewriters. Despite weeks of constant coding/testing there -will- be things I've missed. The kinds of bugs I'm expecting are overlays not updating and/or in rare cases things not appearing in your hud. Most of these issues can be worked around simply by dropping the item and picking it back up. If all else fails ask an admin to regenerate your icons through view-vars.
      Please report any bugs to me on #coderbus IRC or make an issue on the tracker as a matter of urgency. I will fix them ASAP.
      Also a massive thankyou to Nodrak, Erro, Pete and Willox. :)
    • -
    • Massive rewrite of the overlays system (particularly for humans). Stuff is cached and only updates when necessary. In effect this means faster updates, less overheads/lag, and less reliance on the game-ticker.
    • -
    • Numerous bugfixes and tweaks for damage-procs and damage-overlays for humans. They should now be almost seamless, use very little overhead and update instantly.
    • -
    • TK grab can now be cancelled using the throw hotkey. (so now it toggles on/off like it used to).
    • -
    • Added verbs to the view-var drop-down list: "Regenerate Icons" will fix a mob's hud/overlays. "Set Mutantrace" will change a mob's mutantrace.
    • -
    • Damage icons were split up. They kinda look a bit crap so spriters feel free to replace them. Templates are provided in dam_human.dmi
    • -
    • More to come...
    -

    Cheridan updated:

    -
      -
    • -Added Lezowski's overalls to hydroponic supply closets. 50% chance per closet for them to replace the apron. -Removed some covers tags from things that made no sense to have them.
    • -
    -
    - -
    -

    Monday, June 11th

    -

    Donkie updated:

    -
      -
    • Fixed being able to lock yourself in or out of a locker using the verb.
    • -
    -

    Xerux updated:

    -
      -
    • Added lightfixture creating.
    • -
    -

    Errorage updated:

    -
      -
    • You can now use the resist verb or UI button when welded or locked in a closet. Takes 2 minutes to get out tho (Same as getting out of handcuffs or unbuckling yourself)
    • -
    • Making single-pane windows will now make the window in the direction you're facing. If a window already exists in that direction it will make it 90 degrees to your left and so on.
    • -
    -
    - -
    -

    Sunday, June 10th

    -

    Agouri updated:

    -
      -
    • Cyborgs and AIs can now use the newscaster. It was a mistake on my part, forgetting to finish that part of them.
    • -
    -
    - -
    -

    Saturday, June 9th

    -

    Errorage updated:

    -
      -
    • You can now make restraints from cable. It takes 15 lengths of cable to make a pair of restraints, they are applied the same way as handcuffs and have the same effects. It however only takes 30s to remove them by using the resist verb or button. You can also remove them from someone by using wirecutters on the handcuffed person.
    • -
    • Added four new cable colors: pink, orange, cyan and white. Engineer belts spawn with yellow, red or orange cables while toolboxes and tool closets spawn with all 8 colors.
    • -
    -
    - -
    -

    Thursday, June 7st

    -

    Icarus updated:

    -
      -
    • Added a second ZIS suit to engineering.
    • -
    • Remapped CE office and surrounding areas.
    • -
    -
    - -
    -

    Wednesday, June 6th

    -

    Sieve updated:

    -
      -
    • Radiation now works properly, watch out for that Singularity!
    • -
    • Disposals are no longer the loudest machines in existence.
    • -
    • Building portable turrets with lasertag guns now makes them fire lasertag bolts based on team, and they will automatically target and prioritize people wearing opposing team gear.
    • -
    • The same can be done for ED-209s, simply using a lasertag vest and gun (same color) where you would use a security vest and taser in construction.
    • -
    • Added mineral walls and powered mineral door construction. More information can be found in the commit thread, but basically they are built the same way others are, apply mineral to girder for a mineral wall, mineral to airlock assembly for a powered mineral door.
    • -
    • Commit Thread
    • -
    • Throw hotkey (end) now works with TK.
    • -
    • Swap hands hotkey (page up) now cycles through borg modules.
    • -
    -

    Nodrak updated:

    -
      -
    • Cargo's 'shuttle: station' and 'shuttle: dock' has been changed to 'shuttle: station' and 'shuttle: away' to help avoid confusion.
    • -
    -

    Icarus updated:

    -
      -
    • Maintenance shafts changed around. Renamed, less windows, more turns, and expanded in a few areas.
    • -
    -

    Neek updated:

    -
      -
    • You can now add chemicals into cigarettes by injecting them directly or dipping individual cigarettes into a beaker. You can inject into cigarette packs directly to affect multiple cigarettes at once.
    • -
    -

    Willox updated:

    -
      -
    • You can now click individual blocks/subblocks in the genetics console instead of having to scroll through the blocks with a forward/back button!
    • -
    -
    - -
    -

    Sunday, June 3rd

    -

    Donkie updated:

    -
      -
    • You can now Drag-Drop disposal pipes and machinery into the dispenser, in order to remove them.
    • -
    • You must now use wrench before welding a pipe to the ground
    • -
    • You can no longer remove a trunk untill the machinery ontop is unwelded and unwrenched
    • -
    • You are now forced to eject the disposal bin before unwelding it.
    • -
    -
    - -
    -

    Friday, June 1st

    -

    SkyMarshal updated:

    -
      -
    • Readded fingerprints and detective work, after lots of debugging and optimization.
    • -
    • Any PDA with access to the Security Records can now, by the normal forensic scanner function, store data the same way as the detective's scanner. Scanning the PDA in the detective's computer will copy all scanned data into the database.
    • -
    • If something goes wrong, please contact SkyMarshal on the #bs12 channel on irc.sorcery.net
    • -
    -
    - -
    -

    Friday, June 1st

    -

    Nodrak updated:

    -
      -
    • Windoor's are now constructable! Steps are found here.
    • -
    -
    - -
    -

    Tuesday, May 29th

    -

    Nodrak updated:

    -
      -
    • Glass Doors are now breakable.
    • -
    • Added more treasures to the secret mining room.
    • -
    • Changed mineral lockers from secret mining rooms: Instead of giving you two stacks of everything, you get stacks of ore based on rarity
    • -
    -

    Icarus updated:

    -
      -
    • Moved Engineering and Bridge deliveries.
    • -
    -
    - -
    -

    This 28th day of May, in the year of our Lord, Two Thousand Twelve

    -

    Cheridan updated:

    -
      -
    • -Adjusted balaclavas and added luchador masks. Wearing luchador masks give you latin charisma. They replace the boxing gloves in the fitness room. Boxing gloves are still available in the holodeck. -Fake moustache tweaked and given new sprites.
    • -
    -
    - -
    -

    Monday, May 28th

    -

    Donkie updated:

    -
      -
    • You can now dispense Disposal Bins, Outlets and Chutes from the disposal dispenser. These are movable and you can attach them above open trunks with a wrench, then weld them to attach them completely. You can remove Bins by turning off their pump, then screwdriver, then weld, then wrench. Same with outlet and chute except for the pump part.
    • -
    -
    - -
    -

    Saturday, May 26th

    -

    Icarus updated:

    -
      -
    • Ported over Flashkirby99's RIG suit sprites from Bay12
    • -
    • Department PDA Carts moved out of lockers and into head offices.
    • -
    -
    - -
    -

    Wednesday, May 23rd

    -

    Cheridan updated:

    -
      -
    • -Reverted default UI sprites to Erro's old-style UI. Config options for UI color styles coming soon. -Driest Martinis will no longer be invisible. -Braincakes are now sliceable.
    • -
    • -Medical borg overhaul. Instead of a dozen random pills and syringes, they get a hypospray that can switch between auto-replenishing tricordrazine, inprovaline, and spaceacillin.
    • -
    -

    Errorage updated:

    -
      -
    • Some of the more pressing issues with the new user interface were addressed. These include the health indicator being too far up, the open inventory taking a lot of space, hotkey buttons not being removable and suit storage not being accessible enough.
    • -
    • A toggle-hotkey-buttons verb was added to the OOC tab, which hides the pull, drop and throw buttons for people who prefer to use hotkeys and never use the buttons.
    • -
    • Added a character setup option which allows you to pick between the Midnight, Orange and Old iconsets for the user interface.
    • -
    -
    - -
    -

    Tuesday, May 22nd

    -

    Icarus updated:

    -
      -
    • RIG helmets can now be used as flashlights, just like hardhats. Credit to Sly for the sprites.
    • -
    • HoP's office has been remapped and made into his private office. Conference Room can now be accessed from the main hall.
    • -
    -
    - -
    -

    Sunday, May 20th

    -

    Errorage updated:

    -
      -
    • The new user interface is here. If anything is broken or something should be done differently please post feedback on the forum. Spriters are encouraged to make new sprites for the UI.
    • -
    • When you receive a PDA message, the content is displayed to you if the PDA is located somewhere on your person (so not in your backpack). You will also get a reply button there. This will hopefully make PDA communication easier.
    • -
    • New hotkeys! delete is the now the 'stop dragging' hotkey, insert is the 'cycle intents' hotkey.
    • -
    -
    - -
    -

    Saturday, May 19th

    -

    Doohl updated:

    -
      -
    • You can now swap hands by clicking with your middle mouse button (you have to click on a visible object though, that's the catch).
    • -
    • Tweaked the DNA modifier consoles a little bit so that it's much easier to see individual blocks instead of one jumbled mess of hexadecimal.
    • -
    • You can now properly emag AI turret controls and commsat turret controls.
    • -
    -

    Invisty updated:

    -
      -
    • Brand new ending animations!
    • -
    -
    - -
    -

    Friday, May 18th

    -

    Errorage updated:

    -
      -
    • Removed hat storage, which was useless.
    • -
    • Implanting someone now takes 5 seconds, both people need to remain still. Implanting yourself remains instant.
    • -
    • Wallets once again spawn in the cabinets in the dormitory
    • -
    • Wallets now fit in pockets
    • -
    -
    - -
    -

    Thursday, May 17th

    -

    Icarus updated:

    -
      -
    • Individual dorms now have a button inside that bolts/unbolts the door
    • -
    • New sprites for Cargo, HoP, and Captain's lockers
    • -
    • More department-specific door sprites. Most noticable changes in medsci and supply departments.
    • -
    -
    - -
    -

    Tuesday, May 15th

    -

    Icarus updated:

    -
      -
    • Added WJohnston's scrubs to Medical Doctor lockers. Comes in blue, green, and purple.
    • -
    • Added two new syndicate bundles
    • -
    • Reduced cost of thermals to 3 telecrystals (formerly 4)
    • -
    • Singularity Beacons are now spawned from a smaller, portable device.
    • -
    • CMO and QM jumpsuits made more unique.
    • -
    -
    - -
    -

    Monday, May 14th

    -

    Icarus updated:

    -
      -
    • Reinforced table parts are now made by using four metal rods on regular table parts. No plasteel involved.
    • -
    • Beakers, small and large can now be made/recycled in autolathes.
    • -
    -

    Nodrak updated:

    -
      -
    • Added a 'random item' button to traitor uplinks. You can potentially get ANY item that shows up on the traitor item list, provided you have enough crystals for it.
    • -
    -
    - -
    -

    Friday, May 11th

    -

    Icarus updated:

    -
      -
    • New design for security. This should be the last time it sees major changes for a while.
    • -
    • Added a new construction area. What could it be for?
    • -
    -

    Petethegoat updated:

    -
      -
    • Readded the RD's genetics access.
    • -
    • RD is still without chemistry access, but I'm going to review this decision in a week and see if R&D is useless due to lack of acid.
    • -
    • Added Flashkirby99's SMES sprites!
    • -
    -

    Invisty updated:

    -
      -
    • Sexy new warpspace (or whatever) tiles.
    • -
    -

    Important changes below!

    -
    - -
    -

    Thursday, May 10th

    -

    Sieve updated:

    -
      -
    • Reverted dismemberment, the recent gun changes, and Tarajans. Before you shit up the forums, read this:
    • -
    • Dismemberment was ported from Bay12, but only halfway, and there were several problems with it. I know many people really liked it, but as it stood it did not fit the playstyle here at all. This had to be removed, there is work on a more fitting system, but this had to be taken out first regardless, and the longer people beat around the bush the worse the situation got.
    • -
    • The gun change was made for no real reason and was pretty problematic, so reverting that should mean there are a lot less 'accidental suicides.'
    • -
    • Tarjans were reverted by request as well, and since keeping them working after removing dismemberment would be a stupid amount of work.
    • -
    -
    - -
    -

    Sunday, May 6th

    -

    Cheridan updated:

    -
      -
    • -New booze sprites for the drinks that were removed! Re-enabled the recipes for the removed drinks. Get cracking, bartenders. -You now need 10 sheets of metal instead of 2 to make a gas canister, people can't FILL ENTIRE ROOMS WITH THEM.
    • -
    • -Emergency Toolboxes now contain smaller, lighter fire extinguishers that actually fit inside them! -
    -
    - -
    -

    Saturday, May 5th

    -

    Petethegoat updated:

    -
      -
    • RD get the fuck out of chemistry and genetics
    • -
    • CHEMISTS, DON'T BE DICKS TO RESEARCH, GIVE THEM ACID YOU TIGHT FUCKS
    • -
    -

    Icarus updated:

    -
      -
    • Updates to Sec, including a stationary scrubber for the prison area.
    • -
    • Swapped around cryogenics and the patient rooms in medbay.
    • -
    -
    - -
    -

    Friday, May 4th

    -

    Cheridan updated:

    -
      -
    • -Added fat jumpsuit sprites for orange, pink, yellow, owl, security, and warden jumpsuits.
    • -
    • -Somatoray is hopefully more useful and less buggy when used on trays. -Botanists now have morgue access, because of their ability to clone via replica pods. Try not to get this removed like all your other access, okay hippies?
    • -
    -
    - -
    -

    Thursday, May 3rd

    -

    Ikarrus updated:

    -
      -
    • Updated genetics, medbay and security.
    • -
    -

    Petethegoat updated:

    - -
    - -
    -

    Tuesday, May 1st

    -

    PolymorphBlue updated:

    -
      -
    • Adds BS12 dismemberment!
    • -
    • Adds greater changeling for 30 points
    • -
    -
    - - -
    -

    Monday, April 20th

    -

    Erro updated:

    -
      -
    • Added a verb to the PDA which you can use to remove an ID in it. If your active hand is empy, it puts it there otherwise it puts it on the floor under you.
    • -
    -
    - -
    -

    Wednesday, April 27th

    -

    Cheridan updated:

    -
      -
    • -New sprites for lemons, oranges, and walking mushroom critters. -Added Invisty's new blob sprites.
    • -
    • -Added a new chemical: lipozine, a weight loss drug. Made with sodium chloride, ethanol, and radium.
    • -
    -
    - -
    -

    Wednesday, April 25th

    -

    Ikarrus & Flazeo updated:

    -
      -
    • New layout for Security, including a prison area instead of permacells.
    • -
    • New layout for the library, bar, and botany.
    • -
    • Medbay and R&D now have three-tile halls.
    • -
    -

    Scroll down for more commits! There's a bunch of new shit.

    -
    - -
    -

    Tuesday, April 24th

    -

    PolymorphBlue updated:

    -
      -
    • Fakedeath changelings can no longer have their brains cut out.
    • -
    • Rev checkwin changed to fire every five ticks (from twenty) and actually use the right objective type so revs being off station counts as success.
    • -
    -

    Sieve updated:

    -
      -
    • Powercells now have unique icons for cell types
    • -
    • Implemented mech construction sprite by WJohnston for the Ripley, Firefighter, Gygax, and Durand
    • -
    • Durand construction is reversible
    • -
    • Power Cells can now be made in Mechfabs, provided the proper research level has been achieved
    • -
    • Added a new item, the Synthetic Flash. Works just like a normal flash, except they can only withstand one use, but can be produced in the Mechfab(To replace the need for normal flashes)
    • -
    • Added a new type of gloves, ones that are cheap copies of the coveted Insulated Gloves, but be warned, quality control wasn't too thorough
    • -
    • Added a new Cyborg Upgrade, a jetpack for use by Miner Cyborgs. Can be refilled on any air canister
    • -
    • Miner Cyborgs now have a Diamond Drill equivalent along with an upgraded Ore Satchel
    • -
    • Mechfabs no longer brick if there are parts in the quene on sync
    • -
    • MMIs can be built in the Mechfabs again
    • -
    • Crabs are no longer immortal, and are now especially vulnerable to wirecutters
    • -
    • Bibles printed in the library now retain the religion's deity
    • -
    • Added Construction Sprites for the Ripley, Firefighter, Gygax, and Durand by WJohnston
    • -
    • Added Particle Accelerator sprites by Invisity
    • -
    • Added Power Cell, Synthetic Flash, Robot Upgrades, and made some modifications to the PA sprites
    • -
    -

    Petethegoat updated:

    -
      -
    • Added Invisty's field generator sprites.
    • -
    -
    - -
    -

    April 1-22, 2012

    -

    Cheridan updated:

    -
      -
    • CATCHING UP ON MY CHANGELOG. Some of this has been in for a while: -Added carved pumpkins and corncob pipes. -Added mutations for ambrosia and lemon trees. -Added more wood items for tower cap wood construction. -Added soil to plant seeds in. Make it by crushing up sandstone. Soil does not have indicators like trays do! Watch your plants carefully!
    • -
    • -The biogenerator is now more robust. It can dispense fertilizer in batches, and make simple leather items. -RnD can create a new tool for botanists: The floral somatoray. Has two modes. Use it on your plants to induce mutations or boost yield.
    • -
    • -Added plump helmet biscuits, mushroom soup, pumpkin pie and slices, chawanmushi, and beet soup recipes for the chef to make.
    • -
    • -Added transparency to biohelmets. -Normalized grass harvests. -Changed the name of "Generic Weeds". -Blenders can now be filled directly from plant bags. -Added low chance for a species mutation whenever a plant's stats mutate. -You now get more descriptive messages when applying mutagen to plant trays. -Removed sugarcane seeds from the vending machine. Added the sugarcane seeds to the seeds crate.
    • -
    -
    - -
    -

    Sunday, April 22nd

    -

    Petethegoat updated:

    -
      -
    • New gasmask sprites. Removed emergency gasmasks, so there's only one type now.
    • -
    • New shotgun sprites by Khodoque!
    • -
    • The barman's double-barrel actually works like a double-barrel instead of a pump-action! Rejoice!
    • -
    • Sneaky barmen may be able to illegally modify their shotgun, if they so choose.
    • -
    • Trimmed the changelog, vastly.
    • -
    -
    - -
    -

    Saturday, April 21st

    -

    Errorage updated:

    -
      -
    • Maintenance door outside of tech storage now requires maintenance OR tech storage access instead of maintenance AND robotics accesses.
    • -
    -
    - -
    -

    Thursday, April 19th

    -

    Carn updated:

    -
      -
    • Rewrote the cinematic system to try and simplify and optimise it. Please report any bugs asap to me or coderbus, thanks.
    • -
    -
    - -
    -

    Tuesday, April 17th

    -

    Kor updated:

    -
      -
    • Engineering jobs now have their PDA spawn in their pocket, and their toolbelt on their belt
    • -
    • The nuke going off on station will now gib everyone on the Z level.
    • -
    • Two more core displays are available for the AI
    • -
    • The Artificer can now build cult floors and walls
    • -
    -
    -

    Friday, April 13th

    -

    Sieve updated:

    -
      -
    • Updated the robotics layout.
    • -
    -

    Petethegoat updated:

    -
      -
    • Nerfed the librarian by removing the r-walls from his cubbyhole thing, fuck WGW readers hiding out in there.
    • -
    -
    -
    -

    Thursday, April 12th

    -

    Agouri updated:

    -
      -
    • Fixed the ability to move while lying down/resting.
    • -
    • Sleep has been fixed and works as intended again. Anaesthetic and toxins can now properly put people to sleep, permanently if you keep the administration stable. Sleeplocs are now viable again. The sleep button and *faint emote work again.
    • -
    -
    -
    -

    Wednesday, April 11th

    -

    PolymorphBlue updated:

    -
      -
    • Droppers are now used at the eyes, and thus, access to the eyes is required to have an effect.
    • -
    -
    - - -
    -

    April 10, the year of our lord 2012

    -

    Agouri updated:

    -
      -
    • CONTRABAND-CON UPDATE: Added posters. I'm sorry to add it seperately with the rest of contraband, but there was a lack of sprites for everything else. Hopefully, people will gain interest and get me some damn sprites this way :3 - As I said, this is an ongoing project of mine. So starting of, we've got...
    • -
    • POSTERS! Posters come in rolled packages that can adhere to any wall or r_wall, if it's uncluttered enough. -

      How they get on-board: The quartermaster can now set the receiver frequency of his supplycomp circuit board. A bit simplistic as of now, will work on it later. Building a supplycomp with a properly set up circuitboard will give access to the Contraband crate. -

      How they're used: Unfold the rolled poster on any wall or r_wall to create the poster. There are currently 17 designs, with the possibility of me adding more. -

      How to get rid of them: You can rip them using your hand... To cleanly extract them and not ruin them for future use, however, you can use a pair of wirecutters. -

      How they're classified: They're contraband, so it's perfectly okay for security officers to confiscate them. Punishment for contraband-providers (or end-users, if you want to go full nazi) is up to the situational commanding officers. - -
    -

    Nodrak updated:

    -
      -
    • Merged 'Game' and 'Lobby' tabs during pre-game into one tab
    • -
    • Added the little red x to the late-join job list
    • -
    • Late-joiners are warned if the shuttle is past the point of recall, and if the shuttle has already left the station
    • -
    • Late-joiners now see how long the round has been going on.
    • -
    • Mining shuttle computer no longer spits out both 'Shuttle has been sent' and 'The shuttle is already moving' every time.
    • -
    - -
    - -
    -

    Monday, April 9th

    -

    Petethegoat updated:

    -
      -
    • TORE OUT DETECTIVE WORK! THIS IS A TEMPORARY PATCH TO SEE IF THIS FIXES THE CRASHING.
    • -
    • DETECTIVE SCANNERS AND EVIDENCE BAGS (AND FINGERPRINTS) ARE GONE.
    • -
    -
    - -
    -

    Sunday, April 8th

    -

    PolymorphBlue updated:

    -
      -
    • Secret little rooms now spawn on the mining asteroid, containing various artifacts.
    • -
    • Added the beginnings of a borg upgrade system. Currently, can be used to reset a borg's module.
    • -
    -
    - -
    -

    2 April 2012

    -

    PolymorphBlue updated:

    -
      -
    • ERP is gone. Hope you enjoyed it while it lasted!
    • -
    -
    - -
    -

    April Fools Day! Get hype!

    -

    Doohl updated:

    -
      -
    • Security officers can modify people's criminal status by simply examining them with a security hud on and clicking a link that will show up as part of the character's description.
    • -
    • Less jobs have maintenance access. The only jobs that will have it now are engineers, atmos techs, cargo techs, heads, and the detective.
    • -
    • Changed Runtime's sprite to look more catlike.
    • -
    • View Variables can now better list associative lists.
    • -
    • Miscellaneous bugfixes for the NT Script IDE.
    • -
    -

    PolymorphBlue updated:

    -
      -
    • Minor bugfixes to borg deathsquad, adds borg deathsquad to potential tensioner (set so high it's never going to happen)
    • -
    • Adds consiterable support for ERP! (If enabled.)
    • -
    • Increases cost for changeling unstun to 45
    • -
    -
    - -
    -

    30 March 2012

    -

    Donkie updated:

    -
      -
    • You can now stick papers back in to paperbins, text will persist.
    • -
    • Added a [field] bbcode tag to the pen writing. Lets your start writing from that point.
    • -
    • Changed fonts a bit for papers to make [sign] stand out more.
    • -
    -

    Doohl updated:

    -
      -
    • Gave pill bottles the ability to scoop up pills like ore satchels scoop ore. (There you go, /vg/ Anon.)
    • -
    • Security Officers and Wardens now start with maintenance acceess.
    • -
    -
    - -
    -

    29 March 2012

    -

    PolymorphBlue updated:

    -
      -
    • Exosuits now provide a message when someone is getting in, someone getting in must remain stationary and unstunned, and getting in takes four seconds.
    • -
    -
    - -
    -

    28 March 2012

    -

    Carn updated:

    -
      -
    • Fixed turrets shooting people that leave the area and the telecomm turret controls.
    • -
    -

    Donkie updated:

    -
      -
    • Updated air alarm's GUI.
    • -
    -
    - -
    -

    27 March 2012

    -

    Nodrak updated:

    -
      -
    • Security borgs now have modified tasers.
    • -
    • Security borgs have gone back to having the same movement speed as all other borgs.
    • -
    -
    - -
    -

    23 March 2012

    -

    Doohl updated:

    -
      -
    • Escape shuttles/pods now spend about 2 minutes in high-speed transit before they reach centcom/recon shuttle. This is a warning: regular after-round shuttle grief is NOT OKAY while the shuttle is still in transit! Save it for when the shuttle gets to centcom! The purpose of this is to give potential antagonists and protagonists a chance to have a final showdown in the shuttle. The round does not end until the shutle comes to a stop and docks. Don't step outside while the shuttle is moving!

      For example; if you are a traitor and have an escape-alone objective and a couple of people manage to squeeze in the shuttle, you have two minutes to kill/toss them out to win. Or you can just chill for the duration and reflect on the round.
    • -
    - -

    Donkieyo updated:

    -
      -
    • A bunch new standard-namespace NTSL functions added! Check them out at the NT Script wiki page!
    • -
    -
    - -
    -

    22 March 2012

    -

    Ricotez updated:

    -
      -
    • Medical Lockers, Security Lockers, Research Lockers, Warden Locker, CMO Locker, and RD locker all have new sprites.
    • -
    • Encryption keys now each have their own invidual sprites.
    • -
    - -

    PolymorphBlue updated:

    -
      -
    • Added a prototype holodeck to fitness!
    • -
    • Assorted tensioner fixes
    • -
    - -
    -

    20 March 2012

    -

    Kor updated:

    -
      -
    • Lasertag vests and guns have been added to fitness.
    • -
    • Art storage has replaced the emergency storage near arrivals. Emergency storage has replaced chem storage (has anyone ever used that?)
    • -
    • Wraiths can now see in the dark
    • -
    -
    - - -
    -

    19 March 2012

    -

    PolymorphBlue updated:

    -
      -
    • Added LSD sting to modular changeling by popular demand.
    • -
    • Silence sting no longer provides a message to the victim.
    • -
    • Tensioner will no longer assign dead people as assassination targets.
    • -
    -
    - -
    -

    18 March 2012

    -

    Quarxink updated:

    -
      -
    • The medical record computers can finally search for DNA and not just name and ID.
    • -
    -
    - -
    -

    14 March 2012

    -

    PolymorphBlue updated:

    -
      -
    • Modular changeling added! Changelings now purchase the powers they want. Balancing still underway, but should be playable.
    • -
    -

    Petethegoat updated:

    -
      -
    • Janitor cyborgs have been massively upgraded. Suffice to say they're pretty ballin' now...
    • -
    -

    Nodrak updated:

    -
      -
    • You can now choose whether to spawn with a backpack, satchel, or nothing. Excess items will spawn in your hands if necessary.
    • -
    • You can now choose what kind of underwear you'd like to wear, per a request.
    • -
    -
    - -
    -

    14 March 2012

    -

    Carn updated:

    -
      -
    • Added 6 female hairstyles -- credits go to Erthilo of Baystation. Added a male hairstyle -- credits go to WJohnston of TG. If you can sprite some unique and decent-looking hair sprites, feel free to PM me on the TG forums.
    • -
    -
      -
    • The way objects appear to be splattered with blood has been rewritten in an effort to fix stupid things happening with icons. It should be called far less frequently now. PLEASE, if you experience crashes that could in anyway be related to blood, report them with DETAILED information. Thanks
    • -
    -
    - -
    -

    13 March 2012

    -

    Nodrak & Carn updated:

    -
      -
    • Fixed the way flashes break. Long story short: They'll never break on first use so rev don't get screwed over. They run out of charge temporarily when spammed but recharge. Spamming them also increases the chance of them breaking a little, so use them sparingly.
    • -
    -

    Doohl updated:

    -
      -
    • Ablative Armor now has a high chance of reflecting energy-based projectiles.
    • -
    • Riot shields were buffed; they now block more attacks and they will prevent their wielder from being pushed (most of the time).
    • -
    -
    - -
    -

    12 March 2012

    -

    PolymorphBlue updated:

    -
      -
    • PDA messages now require an active messaging server to be properly sent.
    • -
    -
    - -
    -

    11 March 2012

    -

    PolymorphBlue updated:

    -
      -
    • The AI can now open doors with shift+click, bolt them with ctrl+click, and shock them with alt+click
    • -
    • Tratior borgs who hack themselves cannot be blown by the robotics console, and can override lockdowns.
    • -
    • Adds a new wire to doors that controls the time delay before they close. If pulsed, they close like a sliding glass door. If cut, they do not close by themselves.
    • -
    • Borgs who have died, ghosts, and are then blown up will now have their ghosts properly transfered to their dropped MMIs.
    • -
    -

    Carnwennan updated:

    -
      -
    • You can now request AI presence at a holopad for immediate private communication with the AI anywhere. AIs can click a quick button to zoom to the holopad.
    • -
    -
    - -
    -

    08 March 2012

    -

    Nodrak and Carnwennan updated:

    -
      -
    • Nodrak: Fixed crayon boxes and stuff getting stuck in pockets.
    • -
    • Nodrak: 'Steal item' objectives will report correctly when wrapped up in paper now.
    • -
    • Carn: fixed the vent in the freezer...poor chef kept suffocating.
    • -
    -
    - -
    -

    02 March 2012

    -

    Carn updated:

    -
      -
    • Fixed a number of issues with mob examining. Including: not being able to see burns unless they were bruised; vast amounts of grammar; and icons. Updated them to use stylesheet classes.
    • -
    • Borgs can no-longer drop their module items on conveyor belts.
    • -
    • Names input into the setup screen are now lower-cased and then have their first letters capitalised. This is to fix problems with BYOND's text-parsing system.
    • -
    • Runtime fix for lighting.
    • -
    • Over the next few commits I will be updating a tonne of item names to fix text-parsing. Please inform me if I've typoed anything.
    • -
    -
    - -
    -

    03 March 2012

    -

    Petethegoat updated:

    -
      -
    • Removed cloakers. Removed Security's thermals. Added disguised thermals as a traitor item.
    • -
    -
    - -
    -

    01 March 2012

    -

    SkyMarshal updated:

    -
      -
    • Tweak/Bugfix for Hallucinations. Much more robust.
    • -
    -
    - -
    -

    01 March 2012

    -

    SkyMarshal updated:

    -
      -
    • Ported BS12 Detective Work System
    • -
    -
    - -
    -

    1 March 2012

    -

    Petethegoat updated:

    -
      -
    • Head revolutionaries no longer spawn with traitor uplinks.
    • -
        -
      -
    - -
    -

    29 February 2012

    -

    SkyMarshal updated:

    -
      -
    • BS12 Hallucination and Dreaming port
    • -
        -
      -
    - - -
    -

    29 February 2012

    -

    muskets updated:

    -
      -
    • Integrated BS12's improved uplink code
    • -
    -
    - - -
    -

    26 February 2012

    -

    Doohl updated:

    -
      -
    • The insane crashing has finally been fixed!
    • -
    -
    - -
    -

    25 February 2012

    -

    Doohl updated:

    -
      -
    • Telecommunications has been refined, with many new features and modules implemented.
    • -
    • NTSL (Nanotrasen Scripting Language) is ONLINE! This is a brand new, fully operational scripting language embedded within SS13 itself. The intended purpose is to eventually expand this scripting language to Robotics and possibly other jobs, but for now you may play with the TCS (Traffic Control Systems) implementation of NTSL in the Telecommunications Satellite. Recommended you read the NT Script wiki page for information on how to use the language itself. Other than that, there's not a lot of documentation.
    • -
    • Radio systems have been further optimized, bugfixed, etc. Should be more stable.
    • -
    • Intercoms now require power to work.
    • -
    -
    - - -
    -

    24 February 2012

    -

    PolymorphBlue updated:

    -
      -
    • Headsets are now modular! Use a screwdriver on them to pop out their encrpytion keys, and use a key on one to put it in. A headset can hold two keys. Normal headsets start with 1 key, department headsets with two. The standard chip does nothing, and is not required for listening to the common radio.
    • -
    • Binary translators made into a encrpytion key, and fixed. They now broadcast to AIs properly.
    • -
    -
    - -
    -

    23 February 2012

    -

    PolymorphBlue updated:

    -
      -
    • MMIs/pAIs no longer lip read, and thus can now hear in the dark.
    • -
    • Borg rechargers are no longer Faraday cages, and thus can now receive radio while they're recharging.
    • -
    -

    LastyScratch updated:

    -
      -
    • Glass airlocks now make a different sound than regular airlocks.
    • -
    • in 1997 nanotrasen's first AI malfunctioned
    • -
    • Toggle ambience probably works now! -
    • Runtime is dead. -
    • The Research Director's consoles were moved into the completely empty cage in the back of his office.
    • -
    -
    - - -
    -

    22 February 2012

    -

    PolymorphBlue updated:

    -
      -
    • Changed alt+click to ctrl+click for pulling.
    • -
    -

    Petethegoat updated:

    -
      -
    • New stationary scrubber sprites~
    • -
    • Removed the mint. Coins can still be found and used in vending machines. PACMANs now run off sheets.
    • -
    -

    coolity updated:

    -
      -
    • New sprites for HoS and Captain lockers.
    • -
    • New sprites for the orebox.
    • -
    -
    - -
    -

    21 February 2012

    -

    Petethegoat updated:

    -
      -
    • The jetpacks now display correctly when worn.
    • -
    • Buckling to chairs no longer causes you to drop your weapon
    • -
    -

    Nodrak updated:

    -
      -
    • Ghosts now have a "Jump to Mob" verb.
    • -
    -

    Sieve updated:

    -
      -
    • Mining lanterns work properly once again!.
    • -

      Skaer updated:

      -
        -
      • The armoury now includes a box of spare Sec cartridges.
      • -
      -
    - -
    -

    19 February 2012

    -

    Petethegoat updated:

    -
      -
    • The jetpacks in EVA have been replaced with CO2 ones, painted a classy black.
    • -
    • Additionally, jetpacks will now run on gases other than oxygen, as you would expect.
    • -
    • Chair overhaul! You shouldn't notice anything different, but if you encounter bugs with chairs or beds, please report those asap.
    • -
    • New electric chair sprites, by myself.
    • -
    • Electric chairs will only electrocute people buckled into them.
    • -
    • Karma should be fixed.
    • -
    -

    KorPhaeron updated:

    -
      -
    • A new construct type: Artificer. It is capable of constructing defenses, repairing fellow constructs, and summoning raw materials to construct further constructs
    • -
    • Simple animals (constructs, Ian, etc) can now see their health in the Status tab
    • -
    • Detective's revolver is non-lethal again. Was fun while it lasted
    • -
    -
    - -
    -

    18 February 2012

    -

    Petethegoat updated:

    -
      -
    • Foam has a reduced range to prevent spamming
    • -
    -

    Sieve updated:

    -
      -
    • Stopped the unholy Radium/Uranium/Carbon smoke that crashed the server. And for anyone that did this, you are a horrible person
    • -
    • Cleanbots clean dirt
    • -
    • Cleanbots automatically patrol on construction
    • -
    • Removed silicate because it is not useful enough for how much lag it caused
    • -
    -
    - -
    -

    16 February 2012

    -

    Smoke Carter updated:

    -
      -
    • Newscasters now alert people of new feeds and wanted-alerts simultaneously.
    • -
    -
    - -
    -

    15 February 2012

    -

    Kor updated:

    -
      -
    • Terrorists Win! Desert Eagles and Riot Shields now spawn on the syndicate shuttle, replacing the c20r
    • -
    • The Detectives gun still uses .38, but they're now fully lethal bullets. Go ahead, make his day.
    • -
    • The Veil Render has been nerfed, the Nar-Sie it spawns will not pull anchored objects. This is a temporary measure, more nerfs/reworking to come
    • -
    -
    - -
    -

    14 February 2012

    -

    Carn updated:

    -
      -
    • Spacevines added to the random events.
    • -
    • The bug where doors kept opening when a borg tried to close them at close range is now fixed.
    • -
    -
    - -
    -

    13 February 2012

    -

    Khodoque updated:

    -
      -
    • Security officers, the warden and the HoS have new jumpsuits.
    • -
    -

    Erro updated:

    -
      -
    • Clicking the internals button on your user interface (The one that shows if you have internals on or not) will now toggle internals even if they are in your pockets. (humans only) - It now works if your internals are on your back, suit storage, belt, hands and pockets.
    • -
    • The public autolathe has been removed. If you want some some stuff from a lathe, go to cargo.
    • -
    -

    Kor updated:

    -
      -
    • A new item, the null rod, protects the one bearing it from cult magic. One starts in the chaplains office, and this replaces the job based immunity he had. The null rod also is capable of dispelling runes upon hitting them (the bible can no longer do this)
    • -
    • Shooting fuel tanks with lasers or bullets now causes them to explode
    • -
    • A construct shell is now waiting to be found in space.
    • -
    • Chaplains can no longer self heal with the bible
    • -
    • Simple animals, including constructs, can now attack mechs and critters
    • -
    - -
    - -
    -

    12 February 2012

    -

    Erro updated:

    -
      -
    • You can no longer attach photos to ID cards. This never worked properly and if anything, it was misleading.
    • -
    • Backpacks can now hold 7 normal sized items (box size) as opposed to 6 normal sized items + 1 small item
    • -
    • Added several fire alarms to areas around the station including the brig, engineering and others
    • -
    • The atmospherics department now has a few hazard vests available for atmos techs to wear if they don't like the fire suit
    • -
    • Roboticist now have engineering + science headsets, virologists now have medsci headsets with medical + science channels
    • -
    • Added some headsets to the jobs that didn't have any extras: roboticist, qm, scientist, virologist and geneticist.
    • -
    • Station engineers now have construction site access (vacent office by arrivals)
    • -
    • Replaced a few airlocks with glass airlocks (detective, autolathe, assistant storage, robotics, checkpoint)
    • -
    • Removed the wall that was blocking the entrance to the theater
    • -
    • Made a small redesign for the HoP's office so that people running towards it from the escape hallway don't run right into the queue, annoying everyong
    • -
    • The engineering, command and security airlocks now glow green when closing instead of red to match all the other airlocks
    • -
    • The disposal units now auto trigger every 30 game ticks, if there is something (or someone) in them. So no more hiding in disposal units!
    • -
    • You can no longer control the disposal unit from within it. You will have to wait for it to trigger itself.
    • -
    • You can no longer strip items off of Ian while dead / a ghost
    • -
    -

    Pete updated:

    -
      -
    • Updated fitness, athletic shorts are now available!
    • -
    -
    - - -
    -

    11 February 2012

    -

    Erro updated:

    -
      -
    • You can now take individual crayons out of the crayon box the same way as from boxes
    • -
    • Clicking a grille with a glass or reinforced glass pane in your hand will glaze the grille from the direction you're looking from (don't forget to fasten the window tho)
    • -
    • When you click somewhere with the intent to interact, you will automaticaly face the item you're trying to interact with. This won't slow you down when running and firing guns behind you.
    • -
    -

    Kor updated:

    -
      -
    • A new passive mob ability: Relentless. Relentless mobs cannot be shoved (though may still swap places with help intent)
    • -
    • Alien Queens, Juggernaut constructs, and Medical Borgs are all Relentless. Maybe the medborg can actually drag people to medbay on time now
    • -
    • Two constructs, the Juggernaut and the Wraith are now available for wizards and cultists to use soul stones with
    • -
    • A new highly destructive artefact, Veil Render, is now available for wizards
    • -
    • A new one time use global spell, Summon Guns, is now available for wizards.
    • -
    • DEEPSTRIKING! There is now a partially constructed teleporter on the nuke shuttle, and for a large sum of telecrystals they may purchase the circuitboard needed to complete it.
    • -
    • The Chaplain is immune to cult stun, blind, deafen, and blood boil
    • -
    -
    - -
    -

    10 February 2012

    -

    Quarxink updated:

    -
      -
    • Added a new toy: Water balloons. They can be filled with any reagent and when thrown apply the reagents to the tile and everything on it.
    • -
    -
    - -
    -

    9 February 2012

    -

    Erro updated:

    -
      -
    • Engineering and security lockers now spawn with their respective backpacks in them so job-changers can look as they should. HoS locker now also contains an armored vest, for the convenience of the HoS who wants to play with one.
    • -
    • Slightly changed the spawn order of items in the CE and HoS lockers to make starting up a hint less tedious.
    • -
    -
    - -
    -

    8 February 2012

    -

    ConstantA updated:

    -
      -
    • Added Exosuit Jetpack
    • -
    • Added Exosuit Nuclear Reactor (runs of normal, everyday uranium, maybe I'll switch it to run on enriched) - requires research (level 3 in Materials, Power Manipulation and Engineering)
    • -
    • Added Ripley construction steps sprites (courtesy of WJohnston - man, you're awesome)
    • -
    • Exosuit Sleeper can now inject occupant with reagents taken from Syringe Gun
    • -
    • Exosuit Cable Layer will now auto-dismantle floors
    • -
    • Exosuit Heavy Lazer cooldown increased, Scattershot now fires medium calibre ammo (less damage)
    • -
    • Exosuit wreckage can be pulled
    • -
    • EMP now drains half of current exosuit cell charge, not half of maximum charge.
    • -
    • Fixed several possible exosuit equipment runtimes
    • -
    • Introduced new markup to changelog. Javascript is extremely slow (in byond embedded browser) for some reason.
    • -
    -
    -
    -

    4 February 2012, World Cancer Day

    -

    Erro updated:

    -
      -
    • Examining humans now works a bit differently. Some external suits and helmets can hide certain pieces of clothing so you don't see them when examining. Glasses are also now displayed when examining.
    • -
    • The job selection screen has been changed a little to hopefully make making changes there easier.
    • -
    -
    -31 January 2012 -
      -
    • Carn updated: -
        -
      • Grammar & various bug-fixes
      • -
      • Thank-you to everyone who reported spelling/grammar mistakes. I'm still working on it, so if you spot anymore please leave a comment here. There's still lots to fix.
      • -
      • Mining station areas should no longer lose air.
      • -
      -
    - - -30 January 2012( -
      -
    • Sieve updated: -
        -
      • This stuff is actually already implemented, it just didn't make it to the changelog
      • -
      • Firefighter Mech - A reinforced Ripley that is more resistant to better cope with fires, simply look in the Ripley Contruction manual for instructions.
      • -
      • Mech contruction now has sounds for each step, not just 1/4 of them.
      • -
      • Mech Fabricators are fixed, Manual Sync now works and certain reseach will reduce the time needed to build components.
      • -
      • Added special flaps to the mining station that disallow air-flow, removing the need to shuffle Ore Boxes through the Airlocks.
      • -
      • Each outpost has it's own system for the conveyors so they won't interfere with each other.
      • -
      • Powercell chargers have been buffed so now higher capacity cells are actually useable.
      • -
      • A diamond mech drill has been added. While it isn't any stronger than the standard drill, it is much faster.
      • - -
      -
    - -29 January 2012, got Comp Arch exams on Wednesday :( -
      -
    • Agouri updated: -
        -
      • UPDATE ON THE UPDATE: Newspapers are now fully working, sorry for that. Some minor icon bugs fixed. Now I'm free to work on the contest prizes :3
      • -
      • Newscasters are now LIVE! Bug reports, suggestions for extra uses, tears etc go here.
      • -
      • What ARE newscasters? Fans of the Transmetropolitan series might find them familiar. Basically, they're terminals connected to a station-wide news network. Users are able to submit channels of their own (one per identified user, with channels allowing feed stories by other people or, if you want the channel to be your very own SpaceJournal, being submit-locked to you), while others are able to read the channels, either through the terminals or a printed newspaper which contains every news-story circulating at the time of printing.
      • -
      • About censorship: You can censor channels and feed stories through Security casters, found in the HoS'es office and the Bridge. Alternatively, if you want a channel to stop operating completely, you can mark it with a D-Notice which will freeze it and make all its messages unreadable for the duration it is in effect. If you've got the access, of course.
      • -
      • Basically I think of the newscaster as nothing more as an additional Roleplaying tool. Grab a newspaper along with your donuts and coffee from the machines, read station rumors when you're manning your desk, be a station adventurer or journalist with your very own network journal!
      • -
      • I would ask for a bit of respect when using the machine, though. I removed all and any channel and story restrictions regarding content, so you might end up seeing channels that violate the rules, Report those to the admins.
      • -
      • Finally, due to the removal of the enforced "Channel" string, it's recommended to name your channels properly ("Station Paranormal Activity Channel" instead of "Station Paranormal Activity", for example") - -
      -
    - -28 January 2012 -
      -
    • BubbleWrap updated: -
        -
      • Arresting buff!
      • -
      • A person in handcuffs being pulled cannot be bumped out of the way, nor can the person pulling them. They can still push through a crowd (they get bumped back to behind the person being pulled, or pushed ahead depending on intent).
      • -
      -
    - -27 January 2012 -
      -
    • LastyScratch updated: -
        -
      • Toggle-Ambience now works properly and has been moved from the OOC tab to the Special Verbs tab to be with all the other toggles.
      • -
      -
    • RavingManiac updated: -
        -
      • The bar now has a "stage" area for performances.
      • -
      -
    • Blaank updated: -
        -
      • Added a vending machine to atmopherics reception desk that dispenses large -oxygen tanks, plasma tanks, emergency oxegen tanks, extended capacity emergency -oxygen tanks, and breath masks.
      • -
      -
    • Petethegoat updated (for a bunch of other people): -
        -
      • Lattice is now removed when you create plating or floor (credit Donkieyo).
      • -
      • Monkeys now take damage while in crit (credit Nodrak).
      • -
      • The warden now has his own jacket. (credit Shiftyeyesshady).
      • -
      • Spectacular new dice that will display the proper side when rolled!! (credit TedJustice)
      • -
      • Spectacular new dice that will display the proper side when rolled!! (credit TedJustice)
      • - -
      • Borg RCDs can no longer take down R-walls. (headcoder orders)
      -
    - -19 January 2012 -
      -
    • Petethegoat updated: -
        -
      • Exciting new pen additions! Get the low-down at the wiki.
      • -
      -
    - -17 January 2012 -
      -
    • Doohl updated: -
        -
      • Syndicate shuttle now starts with a All-In-One telecommunication machine, which acts as a mini-network for the syndie channel. It intercepts all station radio activity, too, how cool is that?
      • -
      -
    - -15 January 2012 -
      -
    • Doohl updated: -
        -
      • The radio overhaul 'Telecommunications' is now LIVE. Please submit any opinions/feedback in the forums and check the wiki article on Telecommunications for some more info for the curious.
      • -
      • The AI satellite has been replaced with a communications satellite. You can get there via teleporter or space, just like the AI satellite. I highly recommend not bum-rushing the new satellite, as you may be killed if you don't have access. It's a very secure place.
      • -
      • Once a human's toxicity level reaches a certain point, they begin throwing up. This is a natural, but overall ineffective method of purging toxins from the body.
      • -
      • You can now travel Z-levels in Nuclear Emergency mode (the nuke disk is still bound to the station). This means the nuclear agents can and probably will fly off into space to blow up the comm satellite and shut down communications.
      • -
      -
    - -9 January 2012 -
      -
    • ConstantA updated: -
        -
      • Reworked exosuit internal atmospherics (the situation when exosuit is set to take air from internal tank, otherwise cabin air = location air): -
          -
        • If current cabin presure is lower than &quot;tank output pressure&quot;, the air will be taken from internal tank (if possible), to equalize cabin pressure to &quot;tank output pressure&quot;
        • -
        • If current cabin presure is higher than &quot;tank output pressure&quot;, the air will be siphoned from cabin to location until cabin pressure is equal to &quot;tank output pressure&quot;
        • -
        • Tank air is not altered in any way even if it's overheated or overpressured - connect exosuit to atmos connector port to vent it
        • -
        • &quot;Tank output pressure&quot; can be set through Maintenance window - Initiate maintenance protocol to get the option
        • -
        -
      • -
      • Fixed bug that prevented exosuit tank air updates if exosuit was connected to connector port
      • -
      • Combat exosuits melee won't gib dead mobs anymore
      • -
      • QM exosuit circuit crates cost lowered to 30 points
      • -
      • Exosuit plasma converter effectiveness +50%
      • -
      -
    - - -8 January 2012 -
      -
    • Agouri updated: -
        -
      • I'm back home and resumed work on Newscasters and Contraband.
      • -
      • But I got bored and made cargo softcaps instead. Flippable! Enjoy, now all we need is deliverable pizzas.
      • -
      • Oh, also enjoy some new bodybag functionality and sounds I had ready a while ago, with sprites from Farart. Use a pen to create a visible tag on the bodybag. Wirecutters to cut it off. Also it's no longer weldable because it makes no goddamn sense. -
      -
    - -7 January 2012 -
      -
    • Donkieyo updated: -
        -
      • You must now repair damaged plating with a welder before placing a floor tile.
      • -
      • You can now relabel canisters if they're under 1kPa.
      • -
      -
    • Polymorph updated: -
        -
      • Dragging your PDA onto your person from your inventory will bring up the PDA screen.
      • -
      • You can now send emergancy messages to Centcomm (Or, with some.. tampering, the Syndicate.) via a comms console. (This occurs in much the fashion as a prayer.)
      • -
      -
    -3 January 2012 -
      -
    • Erro updated: -
        -
      • Shift-clicking will now examine whatever you clicked on!
      • -
      -
    • Polymorph updated: -
        -
      • Alt-clicking will now pull whatever you clicked on!
      • -
      -
    - -1 January 2012 (12 more months until doomsday) -
      -
    • Doohl updated: -
        -
      • XENOS ARE NOW IMMUNE TO STUNNING! To compensate, stunning via tasers/batons now slows them down significantly.
      • -
      - -
    • Polymorph updated: -
        -
      • Doors no longer close if they have a mob in the tile. (Generally!) Door safties can now be overriden to close a door with a mob in the tile and injure them severely.
      • -
      - -
    - -29 December 2011 -
      -
    • ConstantA updated: -
        -
      • Added some new Odysseus parts and tweaked old ones.
      • -
      • Added Exosuit Syringe Gun Module
      • -
      • New Odysseus sprites - courtesy of Veyveyr
      • -
      -
    • Polymorph updated: -
        -
      • Air Alarms can now be hacked.
      • -
      • Too much of a good thing is just as bad as too little. Pressures over 3000 kPa will do brute damage.
      • -
      -
    - -28 December 2011 -
      -
    • RavingManiac updated: -
        -
      • Wrapped objects can now be labelled with a pen
      • -
      • Wrapped small packages can be picked up, and are now opened by being used on themselves
      • -
      • Mail office remapped such that packages flushed down disposals end up on a special table
      • -
      • Package wrappers placed in most of the station departments
      • -
      • In short, you can now mail things to other departments by wrapping the object, labelling it with the desired destination using a pen, and flushing it down disposals. At the mail room, the cargo tech will then tag and send the package to the department.
      • -
      -
    - -27 December 2011 -
      -
    • Errorage updated: -
        -
      • Engineering's been remapped
      • -
      -
    • RavingManiac updated: -
        -
      • Refrigerators and freezer crates will now preserve meat
      • -
      -
    - -25 December 2011 -
      -
    • ConstantA updated: -
        -
      • Circuit boards for Odysseus mech can be ordered by QM
      • -
      • Designs for them were added to R&amp;D
      • -
      -
    • -
    • Kor updated: -
        -
      • Soul Stones Added: Like intellicards for dead or dying humans! Full details are too long for the changelog
      • -
      • A belt full of six soul stones is available as an artefact for the wizard
      • -
      • Cultists can buy soulstones with their supply talisman
      • -
      • The chaplain has a single soulstone on his desk
      • -
      • The reactive teleport armour's test run is over. It no longer spawns in the RD's office.
      • -
      -
    • -
    - - - -24 December 2011 -
      -
    • Rockdtben updated: -
        -
      • Added sprites for soda can in left and right hands on mob: sodawater, tonic, purple_can, ice_tea_can, energy_drink, thirteen_loko, space_mountain_wind, dr_gibb, starkist, space-up, and lemon-lime.
      • -
      -
    • - -
    - -23 December 2011 -
      -
    • ConstantA updated: -
        -
      • Mech Fabricators now require robotics ID to operate. Emag removes this restriction.
      • -
      • Added Odysseus Medical Exosuit. Has integrated Medical Hud and ability to mount medical modules.
      • -
      • Added Sleeper Medical module for exosuits. Similar to common sleepers, but no ability to inject reagents.
      • -
      • Added Cable Layer module for exosuits. Load with cable (attack cable with it), activate, walk over dismantled floor.
      • -
      • Added another exosuit internal damage type - short circuit. Short-circuited exosuits will drain powercell charge and power relay won't work.
      • -
      • You should be able to send messages to exosuit operators using Exosuit Control Console
      • -
      • Gygax armour and module capacity nerfed.
      • -
      • Exosuit weapon recharge time raised.
      • -
      • Bugfix: EMP actually drains exosuit cell and damages it
      • -
      -
    • -
    • RavingManiac updated: -
        -
      • Meat will now spoil within three minutes at temperatures between 0C and 100C.
      • -
      • Rotten meat has the same nutritional value as normal meat, and can be used in -the same recipes. However, it is toxic, and ingesting a badly-prepared big bite -burger can kill you.
      • -
      • Because refrigeration serves a purpose now, the kitchen cold room freezing unit -is turned off by default. Chefs should remember to turn the freezer on at the -start of their shift.
      • -
      -
    • -
    - -21 December 2011 -
      -
    • RavingManiac updated: -
        -
      • Kitchen cold room is now cooled by a freezing unit. Temperature is about 240K by default, but can be raised to room temperature or lowered to lethal coldness.
      • -
      -
    - -19 December 2011 -
      -
    • Kor updated: -
        -
      • General/Misc Changes -
          -
        • Escape pods no longer go to the horrific gibbing chambers. Rather, they will be picked up by a salvage ship in deep space. (This basically changes nothing mechanics wise, just fluff)
        • -
        • An ion rifle now spawns on the nuclear operative shuttle. Maybe this will help with them getting destroyed by sec borgs every round?
        • -
        -
      • -
      • Wizard Changes -
          -
        • The wizard can now purchase magic artefacts in addition to spells in a subsection of the spellbook.
        • -
        • The first (and currently only) new artefact is the Staff of Change, which functions as a self recharging energy weapon with some special effects.
        • -
        • The wizard has a new alternative set of robes on his shuttle.
        • - -
        -
      • Cult Changes
          -
        • Cultists now each start with three words (join, blood, self). No more will you suffer at the hands of cultists who refuse to share words.
        • -
        • The starting supply talisman can now be used five times and can now be used to spawn armor and a blade.
        • -
        • Replaced the sprites on the cultist robes/hood.
        • -
      • -
      -
    - -18 December 2011 -
      -
    • Carnwennan updated: -
        -
      • Thanks to the wonders of modern technology and the Nanotrasen steel press Ian's head has been shaped to fit even more silly hats. The taxpayers will be pleased.
      • -
      -
    • -
    • Doohl updated: -
        -
      • Vending machines got yet another overhaul! Good lord, when will they stop assfucking those damned vendors??
      • -
      -
    • -
    - -17 December 2011 -
      -
    • Erro updated: -
        -
      • Your direct supervisors are now displayed when you are assigned a job at round start or late join.
      • -
      -
    • -
    - -14 December 2011 -
      -
    • Erro updated: -
        -
      • Meteor mode is hopefully deadly again!
      • -
      -
    • -
    • Kor updated: -
        -
      • Research director has a new toy: Reactive Teleport Armour. Click it in your hand to activate it and try it out!
      • -
      -
    • -
    - -11 December 2011 -
      -
    • NEO updated: -
        -
      • AIs actually consume power from APCs now
      • -
      • Bigass malf overhaul. tl;dr no more AI sat, instead you have to play whackamole with APCs.
      • -
      -
    • -
    - -10 December 2011 -
      -
    • Doohl updated: -
        -
      • Title music now plays in the pregame lobby. You can toggle this with a verb in "Special Verbs" if you really want to.
      • -
      • User Interface preferences now properly get transferred when you get cloned.
      • -
      -
    • -
    • Erro updated: -
        -
      • Escape pods have been added to test the concept.
      • -
      • Escaping alone in a pod does not count towards the escape alone objective, it counts towards the escape alive objective tho. Escape alone only requires you to escape alone on the emergency shuttle, it doesn't require you to ensure all pods are empty. Cult members that escape on the pods do not ocunt towards the cult escaping acolyte number objective. Escaping on a pod is a valid way to survive meteor.
      • -
      -
    • -
    • Polymorph updated: -
        -
      • Fire is now actually dangerous. Do not touch fire.
      • -
      -
    • - - -
    - -8 December 2011 -
      -
    • Errorage updated: -
        -
      • Fixed the comms console locking up when you tried to change the alert level.
      • -
      • Added a keycard authentication device, which is used for high-security events. The idea behind it is the same as the two-key thing from submarine movies. You select the event you wish to trigger on one of the devices and then swipe your ID, if someone swipes their ID on one of the other devices within 2 seconds, the event is enacted. These devices are in each of the head's offices and all heads have the access level to confirm an event, it can also be added to cards at the HoP's ID computer. The only event that can currently be enacted is Red alert.
      • -
      -
    • -
    • Kor updated: -
        -
      • The chef now has a fancy dinner mint in his kitchen. It is only wafer thin!
      • -
      -
    • -
    - -3 December 2011 -
      -
    • Pete & Erro Christmas update: -
        -
      • Reinforced metal renamed to steel and steel floor tile renamed to metal floor tile to avoid confusion before it even happens.
      • -
      • It is no longer possible to make steel from metal or vice versa or from the autolathe. You can however make metal from the autolathe and still insert steel to increase the metal resource.
      • -
      • To make steel you can now use the mining smelting unit and smelt iron and plasma ore.
      • -
      • The RCD can no longer take down reinforced walls.
      • -
      -
    • -
    • Errorage updated: -
        -
      • Grass plants in hydro now make grass floor tiles instead of the awkward patches.
      • -
      -
    • -
    • Petethegoat updated: -
        -
      • Fixed all known vending machine issues.
      • -
      • Fixed a minor visual bug with emagged lockers.
      • -
      • Clarified some of the APC construction/deconstruction messages.
      • -
      -
    • -
    • Numbers updated: -
        -
      • Potency variations tipped in favour of bigger changes over smaller periods of time.
      • -
      -
    • -
    • PolymorphBlue updated: -
        -
      • Traitors in the escape shuttle's prison cell will now fail their objective.
      • -
      • Lockers are no longer soundproof! (or flashproof, for that matter)
      • -
      • Headrevs can no longer be borged, revs are dereved when borged. -
      -
    • -
    - -30 November 2011 -
      -
    • Vinyl Scratch updated: -
        -
      • New ambient sounds for the station and AI Sat.
      • -
      • He's baaaaaack...
      • -
      -
    • -
    - -27 November 2011 -
      -
    • Kor updated: -
        -
      • Changeling husks are now borgable again (though not clonable) and genome requirements were lowered
      • -
      • De-revved revolutionaries had their message clarified a bit. You remember the person who flashed you, and so can out ONE revhead
      • -
      • Light tubes/bulbs can now be created in the autolathe. Recycle those broken lights!
      • -
      -
    • -
    - -22 November 2011 -
      -
    • Doohl updated: -
        -
      • The firing range now has a purpose. Go check it out; there's a few surprises!
      • -
      -
    • -
    - -19 November 2011 -
      -
    • Doohl updated: -
        -
      • Toggling admin midis will now DISABLE THE CURRENT MIDI OH MY GOSH!
      • -
      -
    • -
    • Tobba updated: -
        -
      • We're looking for feedback on the updated chem dispenser! It no longer dispenses beakers of the reagent, and instead places a variable amount of the reagent into the beaker of your choosing.
      • -
      -
    • -
    • Petethegoat updated: -
        -
      • Diagonal movement is gone on account of them proving to be a bad idea in practice. A grand experiment nonetheless.
      • -
      -
    • -
    • Kor updated: -
        -
      • The PALADIN lawset in the AI upload has been replaced with the corporate lawset
      • -
      -
    • -
    - -16 November 2011 -
      -
    • Tobba updated: -
        -
      • Report any issues with the updated vending machines!
      • -
      -
    • -
    - -16 November 2011 -
      -
    • Petethegoat updated: -
        -
      • Security, Engineer, Medical, and Janitor borgs no longer get a choice of skin. This is for purposes of quick recognition, and is the first part of a series of upcoming cyborg updates.
      • -
      -
    • -
    - -7 November 2011 -
      -
    • Kor updated: -
        -
      • Repair bots (mechs) are now adminspawn only
      • -
      • Extra loyalty implants are now orderable via cargo bay (60 points for 4 implants)
      • -
      • Changeling regen stasis now takes two full minutes to use, but can be used while dead. Burning and gibbing are the only way to keep them dead now.
      • -
      -
    • -
    - -29 October 2011 -
      -
    • ConstantA updated: -
        -
      • Added step and turn sounds for mechs
      • -
      • Added another mecha equipment - plasma converter. Works similar to portable generator. Uses solid plasma as fuel. Can be refueled either by clicking on it with plasma in hand, or directly from mecha - selecting it and clicking on plasma.
      • -
      • Added mecha laser cannon.
      • -
      • Added damage absorption for mechs. Different mechs have different absorption for different types of damage.
      • -
      • Metal foam now blocks air movement.
      • -
      -
    • -
    • Petethegoat updated: -
        -
      • Fixed sticking C4 to containers.
      • -
      • Rearranged the armoury, and changed the medical treatment room in Sec to an interrogation room.
      • -
      • Mr Fixit has been powered off and returned to the armoury. Deploying him every round is still recommended!
      • -
      -
    • -
    - -29 October 2011 -
      -
    • Petethegoat updated: -
        -
      • Stunglove overhaul: part one. Stun gloves are now made by wiring a pair of gloves, and then attaching a battery- this shows up on the object sprite, but not on your character. Stungloves use 2500 charge per stun! This means that some low capacity batteries will make useless stungloves. To get your old inconspicous gloves back, simply cut away the wire and battery. Note that insulated gloves lose their insulation when you wire them up! Yet to come: stungloves taking extra damage from shocked doors.
      • -
      • Removed sleepypens! Paralysis pens have been changed to look like normal pens instead of penlights, and have been slightly nerfed. They will paralyse for about fifteen seconds, and cause minor brain damage and dizziness. -
      • Uplink Implants now have five telecrystals instead of four. -
      -
    • -
    • Doohl updated: -
        -
      • More hairs added and a very long beard.
      • -
      • Finally fixed the request console announcements going AMP AMP AMP all the time when you use punctuation.
      • -
      -
    • -
    - -27 October 2011 -
      -
    • Mport updated: -
        -
      • New WIP TK system added. To activate your TK click the throw button with an empty hand. This will bring up a tkgrab item. Click on a non-anchored (currently) non mob Object to select it as your "focus". Once a focus is selected so long as you are in range of the focus you can now click somewhere to throw the focus at the target. To quit using TK just drop the tkgrab item.
      • -
      -
    • -
    - -21 October 2011, Tuesday: -
      -
    • Errorage updated: -
        -
      • Old keyboard hotkey layout option available again! home, end, page down and page up now once again do what they did before by default. To use diagonal movement you will need to use your numpad with NUM LOCK enabled.
        - The new list of hotkeys is as follows: (Valid as of 21.10.2011) -
          -
        • Numpad with Num Lock enabled = movement in wanted direction.
        • -
        • Numpad with Num Lock disabled = as it was before. movement north-south-east-west and throw, drop, swap hands, use item on itself.
        • -
        • Page up (also numpad 9 with num lock disabled) = swap hands
        • -
        • Page down (also numpad 3 with num lock disabled) = use item in hand on itself
        • -
        • home (also numpad 7 with num lock disabled) = drop
        • -
        • end (also numpad 1 with num lock disabled) = throw
        • -
        • CTRL + A = throw
        • -
        • CTRL + S = swap hands
        • -
        • CTRL + D = drop
        • -
        • CTRL + W = use item in hand on itself
        • -
        • Numpad divide (/) = throw
        • -
        • Numpad multiply (*) = swap hands
        • -
        • Numpad subtract (-) = drop
        • -
        • Numpad add (+) = use item in hand on itself
        • -
        - In short, use Num Lock to swap between the two layouts. -
      • -
      -
    • -
    - -18 October 2011, Tuesday: -
      -
    • Errorage updated: -
        -
      • You can now move diagonally! To do so, use the numpad. The keybaord has been remapped to make this possible: -
          -
        • CTRL + A = throw
        • -
        • CTRL + S = swap hands
        • -
        • CTRL + D = drop
        • -
        • CTRL + W = use item in hand on itself
        • -
        • Numpad divide (/) = throw
        • -
        • Numpad multiply (*) = swap hands
        • -
        • Numpad subtract (-) = drop
        • -
        • Numpad add (+) = use item in hand on itself
        • -
        -
      • -
      -
    • -
    - -15 October 2011, White Cane Safety Day: -
      -
    • Agouri updated: -
        -
      • There has been a tidal wave of bugfixes over the last 5 or so days. If you had previously tried something on the station, saw that it was bugged and never tried it again, chances are it got fixed. I don't want you to neglect using stuff because you think it was bugged, which it was at one point, but no longer is. Thanks, happy new semester to everyone~
      • -
      -
    • -
    • Errorage updated: -
        -
      • When you're unconscious, paralyzed, sleeping, etc. you will still see the same blackness as always, but it will rarely flicker a bit to allow you to see a little of your surroundings.
      • -
      -
    • -
    • Doohl updated: -
        -
      • New hairstyles! YOU never asked for this!
      • -
      -
    • -
    - -11 October 2011: -
      -
    • ConstantA updated: -
        -
      • Added radios to exosuits. Setting can be found in 'Electronics' menu.
      • -
      • Exosuit maintenance can be initiated even if it's occupied. The pilot must permit maintenance through 'Permissions &amp; Logging' - 'Permit maintenance protocols'. For combat exosuits it's disabled by default. While in maintenance mode, exosuit can't move or use equipment.
      • -
      -
    • -
    - -8 October 2011: -
      -
    • Doohl updated: -
        -
      • You can put things on trays and mass-transport them now. To put stuff on trays, simply pick up a tray with items underneath/on top of it and they'll be automatically carried on top of the tray. Be careful not to make a mess~!
      • -
      -
    • -
    • Mport updated: -
        -
      • Telekenesis now only allows you to pick up objects.
      • -
      • Stun gloves ignore intent.
      • -
      • Moved the loyalty implants to the HoS' locker.
      • -
      • Job system redone, remember to setup your prefs.
      • -
      -
    • -
    - -2 October 2011: -
      -
    • Petethegoat updated: -
        -
      • Pandemic recharge speed is affected by the number of different types of antibodies in the blood sample. For maximum efficiency, use blood samples with only a single type of antibody. (Blood samples with two types of antibodies will still let the Pandemic recharge slightly faster than it used to.)
      • -
      -
    • -
    • Errorage updated: -
        -
      • Opening a storage item on your belt will now display the proper number of slots even if the number is different from 7.
      • -
      • Less ponies, gryphons, and Tohou.
      • -
      -
    • -
    - -1 October 2011: -
      -
    • Knognob Lungsparkle updated: -
        -
      • Xenomorphic aliens can now shape resin membranes (organic windows basically).
      • -
      • The AI can no longer see runes. Instead, they will see blood splatters.
      • -
      -
    • -
    - -28 September 2011: -
      -
    • Rolan7 updated: -
        -
      • New method for job assignment. Remember to review your preferences. Send all your hate and bug reports to me.
      • -
      -
    • -
    • Doohl updated: -
        -
      • Putting someone inside a cloning machine's DNA scanner will notify the person that they are about to be cloned. This completely removes the necessity to announce over OOC for someone to get back in their body.
      • -
      -
    • -
    - -22 September 2011, OneWebDay: -
      -
    • Errorage updated: -
        -
      • Added an additional 9 colors, into which you can color bedsheets, jumpsuits, gloves and shoes at the washing machine.
      • -
      • A new click proc will need to be live-tested. The testing will be announced via OOC and you will get a message when it happens. When testing is going on, the new click proc will be used. If testing is going on and you notice a bug, please report it via adminhelp. If you find yourself unable to perform an action, you can double click (By that I mean spam the shit out of clicking) to use the old proc, which is unchanged and will behave like you're used to. Standard roleplay rules apply during tests, they're not an excuse to murder eachother.
      • -
      -
    • -
    - -20 September 2011, 10 year anniversary of the declaration of the "war on terror": -
      -
    • Errorage updated: -
        -
      • You can no longer clone people who suicided. I REPEAT! You can no longer clone people who have suicided! So use suiciding more carefully and only if you ACTUALLY want to get out of a round. You can normally clone people who succumbed tho, so don't worry about that.
      • -
      • Washing your hands in the sink will now only wash your hands and gloves. You can wash items if you have them in your hands. Both of these actions are no longer instant tho.
      • -
      -
    • -
    - -18 September 2011, World Water Monitoring Day: -
      -
    • Errorage updated: -
        -
      • Added the most fun activity in your every-day life. Laundry. Check the dormitory. (Sprites by Hempuli)
      • -
      • You can now change the color of jumpsuits, shoes, gloves and bedsheets using the washing machine.
      • -
      • Some religions (currently Islam, Scientology and Atheism) set your chapel's symbols to the symbols of that religion.
      • -
      • A new old-style cabinet's been added to the detective's office. (Sprite by Hempuli)
      • -
      • Runtime the cat ran away!! And it gets even worse! Mr. Deempisi met a premature end during an excursion to the kitchen's freezer! -- I was ORDERED to do this... don't kill me! :(
      • -
      • Kudzu can now be spawned (Currently admin-only. Will test a bit, balance it properly and add it as a random event) (Original code and sprites donated by I Said No)
      • -
      -
    • -
    • Kor updated: -
        -
      • Added purple goggles to chemistry (you're welcome Lasty)
      • -
      • Added a third MMI to robotics and monkey cubes to xenobio (dont fucking spam them in the halls)
      • -
      -
    • -
    • Mport updated: -
        -
      • Turns out tasers and a few other weapons were slightly bugged when it came to checking the internal powercell. Tasers and such gained an extra shot.
      • -
      • Ion Rifle shots lowered to 5 per charge.
      • -
      -
    • -
    - -17 September 2011, Operation Market Garden remembrance day: -
      -
    • Errorage updated: -
        -
      • You can now insert a coin into vending machines. Some machines (currently only the cigarette vending machine) have special items that you can only get to with a coin. No, hacking will not let you get the items, coin only.
      • -
      -
    • -
    - -14 September 2011: -
      -
    • Lasty updated: -
        -
      • Runtime now actually spawns in medbay because nobody cared whether it is a tiny smugfaced espeon that explodes violently on death or a spacecat that presumably doesn't.
      • -
      • You can no longer put someone into a sleeper and erase them from existence by climbing into the same sleeper.
      • -
      • Players who haven't entered the game will no longer be able to hear administrators in deadchat.
      • -
      -
    • -
    • Pete updated: -
        -
      • Added new sprites for the light tube and glasses boxes.
      • -
      • Fixed the bug where syndicate bundles would have an emergency O2 tank and breath mask.
      • -
      -
    • -
    • Mport, SECOND REMOVER OF SUNS updated: -
        -
      • Singularity absorbtion explosion range lowered and is now dependent on singularity size.
      • -
      • Bag of Holding no longer instakills singularity, and the chance for bombs to destroy a singularity has been changed from 10% to 25%.
      • -
      • Removed THE SUN.
      • -
      • Damage and stun duration from shocked doors has been lowered to account for a larger amount of energy in the powernet.
      • -
      -
    • -
    -13 September 2011: -
      -
    • Errorage updated: -
        -
      • Healing, attacking or 'gently tapping' Ian will now properly display the name of the attacker to all people.
      • -
      -
    • -
    • Vinyl Scratch updated: -
        -
      • Runtime!
      • -
      • Mine ambience now fades out at the end so that not only is it less jarring when it ends, but it also loops properly.
      • -
      • Malfunctioning AI's runtime message now has a voice clip to go with it (courtesy of Rosen Ritter)
      • -
      • Every headset will now display the commands for their respective channels upon examine.
      • -
      -
    • -
    • Miss Phaeron updated: -
        -
      • E-Swords now have a chance to deflect projectiles when active
      • -
      • Taser/Laser shots now drain 40 battery per use from a borg, as opposed to 20
      • -
      • EMPs do 60 damage to borgs now, up from 25. They also stun them momentarily and drain 1k charge
      • -
      • As part of a joint effort between Mport, Falazameer, and myself an Ion Rifle has been added to the armoury
      • -
      • The Mutate spell now gives Laser Vision and Hulk
      • -
      -
    • - -
    - - -11 September 2011: -
      -
    • Errorage updated: -
        -
      • Ian can now be toolboxed.
      • -
      • Ian can now be healed with bruisepacks, unless he's already dead.
      • -
      • You can now walk over Ian when he's killed.
      • -
      • Ian will chase food, if you leave it on the floor. If he notices it and you pick it up, he'll chase you around, if you stay close enough.
      • -
      -
    • -
    - -10 September 2011: -
      -
    • Errorage updated: -
        -
      • A new pet on the bridge.
      • -
      • The pet can now be buckled and will no longer escape from closed containers, such as closets or the cloning pods.
      • -
      • Vending machines and request consoles are the first to use the new in-built browser in the upper-right of the user interface. If feedback is positive on these, more machines will be added to this. Hoping that this will eventually reduce the number of popup micromanagement.
      • -
      -
    • -
    • Lasty updated: -
        -
      • The collectible hats have been removed from the theatre, doomed to rot forever in the hat crates they spawned from. No longer shall you see racks full of "collectible hard hat"!
      • -
      -
    • -
    • TLE updated: -
        -
      • You can now toggle the message for becoming a pAI on and off in your prefs.
      • -
      -
    • -
    • Mport updated: -
        -
      • Synaptizine now once again helps you recover from being stunned, however it is now also slightly toxic and may cause a small amount of toxins damage for every tick that it is in your system.
      • -
      • Assembly updating!
      • -
      • Original blob is back, though it still has lava sprites.
      • -
      • The bug where you would spawn on the wizard shuttle for a second at the start of the round should no longer occur.
      • -
      -
    • -
    - -8 September 2011: -
      -
    • Lasty updated: -
        -
      • Suicide has been changed to biting your tongue off instead of holding your breath, and examining someone who has comitted suicide will give you a message stating that their tongue is missing.
      • -
      • Chemsprayers are now large items instead of small, meaning they can no longer fit in your pocket.
      • -
      -
    • -
    - -6 September 2011 -
      -
    • Greek Rioter updated: -
        -
      • Removed dumb/badly sprited drinks for barman. This is for you, people that love to play barman. Your job is now non-stupid again. EDIT: FIXED DRINK MIXING
      • -
      • More info here: rev2136
      • -
      -
    • -
    • Lasty updated: -
        -
      • Fixed the karma exploit! Uhangi can rest in peace knowing his -87 karma ways were not his own.
      • -
      • Added new ambient sound for space and the mines.
      • -
      • Examining an oxygen tank will now tell you if it is about to run out of air. If it is, you will recieve a beep and a message, and if not, then you'll just get the default "this is an oxygentank!" message.
      • -
      -
    • -
    • Rageroro updated: -
        -
      • Sleeper update! Sleepers can now only inject soporific, dermaline, bicaridine, and dexaline into people with 1% or more health. They can also inject inaprovaline into people with -100% or more health. Nothing can be injected into people who are dead.
      • -
      -
    • -
    • Superxpdude updated: -
        -
      • Virology is now part of medbay, and as such the RD no longer has Virology access and the CMO and Virologist no longer have Research access.
      • -
      -
    • -
    • Uhangi updated: -
        -
      • Electropacks, screwdrivers, headsets, radio signalers, and station bounced radios can now be constructed from the autolathe.
      • -
      • Added a courtroom to Centcom.
      • -
      • Fixed electropack bug regarding using screwdrivers on electropacks.
      • -
      -
    • -
    • Microwave updated: -
        -
      • Nuka Cola re-added.
      • -
      -
    • -
    • Urist McDorf updated: - -
    • -
    • Cheridan updated: -
        -
      • New sprites for beds and air, plasma and nitrogen tanks (The ones found in maintenance shafts).
      • -
      -
    • -
    -5 September 2011. -
      -
    • Rageroro updated: -
        -
      • Updates made to the HoP's ID computer. New interface and removing a card will now put it directly in your hand, if it's empty. Using your card on the computer will place it in the appropriate spot. If it has access to edit cards it will put it as the authentication card, otherwise as the card to be modified. If you have two cards with ID computer access first insert the authentication card, then the one you wish to midify, or do it manually like before.
      • -
      • Placed extra fire suits in maintenance (Near eva and mining) and an extra fire closet to atmos.
      • -
      -
    • -
    - -4 September 2011. -
      -
    • Urist McDorf updated: -
        -
      • People who have been infected by facehuggers can no longer suicide.
      • -
      • Stammering has been reworked.
      • -
      • The chaplain can now no longer discern what ghosts are saying, instead receiving flavour text indicating that ghosts are speaking to him.
      • -
      • Walking Mushroom yield decreased from 4 to 1.
      • -
      • Glowshrooms now only spread on asteroid tiles.
      • -
      • Fixed rev round end message reporting everyone as dead.
      • -
      • Gave the changeling an unfat sting.
      • -
      -
    • Erro updated: -
        -
      • R'n'D and Gas Storage locations have been swapped in order for R&D to be given a hallway-facing table, just like Chemistry.
      • -
      • Buckling someone to a chair now causes them to face in the same direction as the chair.
      • -
      • Conveyor will now move only 10 items per game cycle. This is to prevent miners from overloading the belts with 2000 pieces of ore and slowing down time by turning it on. Does not apply to mobs on belt.
      • -
      -
    • Doohl updated: -
        -
      • New escape shuttle!
      • -
      • Metroids get hungry slower, but gain more nutrients from eating.
      • -
      -
    • Kor updated: -
        -
      • Added Necronomicon bible (credit Joseph Curwen)
      • -
      • Removed Doc Scratch clothing from chaplain? locker and added as a random spawn in the theatre.
      • -
      • Shaft Miners now start with regular oxygen tanks.
      • -
      • Mutate now gives the wizard hulk and OPTIC BLAST instead of hulk and TK.
      • -
      • Spiderman suit is no longer armoured or space worthy.
      • -
      • Crayons
      • -
      -
    • Superxpdude updated: -
        -
      • New, more appropriate arrivals message.
      • -
      • Shuttle escape doors fixed.
      • -
      • New RIG sprite.
      • -
      -
    • Lasty updated: -
        -
      • Switched xenomorph weeds to run in the background, hopefully causing them to destroy the server slightly less.
      • -
      -
    • Microwave updated: -
        -
      • Added sink to hydroponics
      • -
      • Cleaned up autolathe menu
      • -
      • Glasses and cups can now be filled with water from sinks.
      • -
      -
    - -31 August 2011. -
      -
    • Lasty updated: -
        -
      • The costumes that spawn in the theatre are now randomized.
      • -
      • The kitchen now has a Smartfridge which can be directly loaded from the Botanist? plantbags. No more crates! (credit to Rolan7).
      • -
      • Snappops can now be acquired from the arcade machines. Amaze your friends! (credit to Petethegoat)
      • -
      • Bangindonk.ogg added to random end sounds list.
      • -
      -
    • Urist McDorf updated: -
        -
      • Players can no longer be randomly assigned to Librarian, Atmospherics Technician, Chaplain, and Lawyer unless all other non-assisstant job slots are full or they have those jobs in their preferences.
      • -
      • Changeling mode now has multiple changelings.
      • -
      -
    • Superpxdude updated: -
        -
      • The mail system actually works properly now! Probably!
      • -
      • Most hats had their ?eadspace?tag removed, meaning they will no longer substitute for a space helmet in protecting you from the dangers of space.
      • -
      -
    - -28 August 2011. -
      -
    • Doohl updated: -
        -
      • Chaplains can now select different bible icons when they start. The selection is applied globally and the library's bible printer will print the same bibles.
      • -
      • Joy to the world! The Library's bible-printing function now has a one-minute cooldown. One minute may seem a little extreme, but it is necessary to prevent people from spamming the fuck out of everything with 100,000,000,000,000 carbon-copy bibles.
      • -
      • Tweaked Metroids a bit; they are slightly more aggressive and become hungrier faster. To compensate, they now move slightly slower.
      • -
      -
    - -26 August 2011. -
      -
    • Mport updated: -
        -
      • Rev:
      • -
          -
        • Station Heads or Head Revs who leave z1 will count as dead so long as they are off of the z level.
        • -
        • Once a player has been unconverted they may not be reconverted.
        • -
        -
      • Cult:
      • -
          -
        • Heads other than the Captain and HoS are now able to start as or be converted to a cultist.
        • -
        • New Item: Loyalty Implant, which will prevent revving/culting. 4 spawn in the armory.
        • -
        • If a rev (not cultist) is injected with one he will unconvert, if a revhead is injected it will display a resist message.
        • -
        • Loyalty Implants show up on the SecHud
        • -
        • New Machine: Loyalty Implanter - Is on the prison station, shove a guy inside it to implant a loyalty implant. It can implant 5 times before it needs a 10 minute cooldown.
        • -
        -
      -
    - -20 August 2011. -
      -
    • Doohl updated: -
        -
      • The smoke chemistry recipe has been upgraded! You can lace smoke with chemicals that can bathe people or enter their lungs through inhalation. Yes, this means you can make chloral hydrate smoke bombs. No, this doesn't mean you can make napalm smoke or foam smoke.
      • -
      -
    - -16 August 2011. -
      -
    • Superxpdude updated: -
        -
      • Traitor item bundles: Contains a random selection of traitor gear
      • -
      -
    - -
      -
    • Uhangi updated: -
        -
      • .38 Special Ammo can now be made from unhacked autolathes
      • -
      -
    - -15 August 2011. -
      -
    • Superxpdude updated: -
        -
      • NEW MINING STATION, POST YOUR OPINIONS AND BUGS HERE
      • -
      • Added some new awesome mining-related sprites by Petethegoat. All credit for the sprites goes to him.
      • -
      -
    - -9 August 2011. -
      -
    • Mport updated: -
        -
      • Cyborgs once again have open cover/cell icons.
      • -
      • To override a cyborg's laws you must emag it when the cover is open.
      • -
      • Emags can unlock a cyborgs cover.
      • -
      • Xbow radiation damage has been lowered from 100 to 20 a hit
      • -
      -
    - -5 August 2011. -
      -
    • Mport updated: -
        -
      • The various assemblies should be working now.
      • -
      • Old style bombs and suicide vests temporarily removed.
      • -
      -
    - -3 August 2011. -
      -
    • Superxpdude updated: -
        -
      • Virology Airlock changed to no longer cycle air. Should work faster and prevent virologists from suffocating.
      • -
      • Server Room APC is now connected to the power grid.
      • -
      • Stun Batons now start OFF. Make sure to turn them on before hitting people with them.
      • -
      -
    - -2 August 2011. The day the earth stood still. -
      -
    • Agouri updated: -
        -
      • SSUs now correctly cycle and dump the unlucky occupant when designated to supercycle, when the criteria to do so are met.
      • -
      • Fixed bugshit
      • -
      • You can now make normal martinis again, removed a silly recipe conflict (Thanks, muskets.). Good barmen are urged to blend the good ol' recipes since the new ones have sprites that SUCK ASS JESUS CHRIST
      • -
      -
    - -
      -
    • Doohl updated: -
        -
      • Speech bubbles: you can toggle them on in the character setup window. Basically, whenever someone around you talks, you see a speech bubble appear above them.
      • -
      • You can no longer create wizarditis and xenomicrobes with metroid cores.
      • -
      • Tweak: Using an exclamation mark as an AI, pAI, or cyborg will not longer get rid of the last exclamation mark.
      • -
      -
    - -30 July 2011. -
      -
    • Superxpdude Updated: -
        -
      • Engineer and CE space helmets now have built-in lights.
      • -
      -
    • Rockdtben updated: -
        -
      • Bugfix: Fixed a bug where you could dupe diamonds
      • -
      -
    • Doohl updated: -
        -
      • New virus: Retrovirus. It basically screws over your DNA.
      • -
      • You can now do CTRL+MOVEMENT to face any direction you want. See those chairs in Medbay and the Escape Wing? You can do CTRL+EAST to actually RP that you're sitting on them. Is this cool or what?! -
      -
    - -29 July 2011. - Day of Forum revival! -
      -
    • Doohl updated: -
        -
      • Bugfix: Metroids should never "shut down" and just die in a corner when they begin starving. And so, hungry Metroids are a force to be feared.
      • -
      • The Cargo computers now have the ability to cancel pending orders to refund credits. This was put in place so that idiots couldn't waste all the cargo points and run off. However, if the shuttle is en route to the station you won't be able to cancel orders.
      • -
      • Bugfix: the manifest has been fixed! Additionally, the manfiest is now updated realtime; job changes and new arrivals will be automatically updated into the manifest. Joy!
      • -
      • Metroids, when wrestled off of someone's head or beaten off, now get stunned for a few seconds.
      • -
      -
    • Agouri updated: -
        -
      • I was always bothered by how unprofessional it was of Nanotransen (in before >Nanotransen >professionalism) to just lay expensive spacesuits in racks and just let them be. Well, no more. Introducing...
      • -
      • Suit Storage Units. Rumored to actually be repurposed space radiators, these wondrous machines will store any kind of spacesuit in a clean and sterile environment.
      • -
      • The user can interact with the unit in various ways. You can start a UV cauterisation cycle to disinfect its contents, effectively sterilising and cleaning eveyrthing from the suits/helmets stored inside.
      • -
      • A sneaky yordle can also hide in it, if he so desires, or hack it, or lock it or do a plethora of shady stuff with it. Beware, though, there's plenty of dangerous things you can do with it, both to you and your target.
      • -
      • The Unit's control panel can be accessed by screwdriving it. That's all I'm willing to say, I'd like to let the players find out what each hack option does and doesn't. Will add more stuff later.
      • -
      • Added Command Space suit, Chief Engineer space suit and Chief Medical Officer spacesuit (In a new space that you'll probably notice by yourself) to make it easier for you to look like a special snowflake.
      • -
      • EVA and CMO office modified to accomodate the new suits and SSUs. Look, I'm not a competent mapper, okay? Fuck you too. A mapper is strongly recommended to rearrange my half assed shit.
      • -
      • Soda cans, cigarette packets, cigarettes and cigars as well as bullet casings are now considered trash and can be picked up by the trashbag. Now you can annoy the janitor even more!
      • -
      • Sprite credit goes to Alex Jones, his portfolio can be found here: http://bspbox.com. Thanks a lot, bro.
      • -
      • With the recent forum fuss and all that, I've got a thread to specifically contain rants and bug reports about this update. Click me
      • -
      -
    • Uhangi updated: -
        -
      • EVA redesigned
      • -
      • An electropack is now available once again on the prison station
      • -
      -
    • Errorage updated: -
        -
      • Hopefully fixed the derelict 'hotspots'. Derelict medbay has also been fixed.
      • -
      -
    - -4 July - 28 July 2011. -
      - -
    • Trubble Bass updated (committed by Superxpdude): -
        -
      • Hat crates. Hat Station 13.
      • -
      -
    • Matty: -
        -
      • Engineers and miners now start off with the new industrial backpack.
      • -
      -
    • Agouri: -
        -
      • Sleepers are now OP and heal every kind of damage.
      • -
      • Made cloning 30% faster, due to popular demand.
      • -
      -
    • Superxpdude updated: -
        -
      • Added in the Submachine Gun to R&D.
      • -
      • Syndicate agents now have Mini-Uzis.
      • -
      • Added an exosuit recharged to the mining station.
      • -
      • New labcoats for scientists, virologists, chemists, and genetecists.
      • -
      • Moved the vault and added a bridge meeting room next to the HoP's office.
      • -
      • Deathsquad armor now functions like a space suit.
      • -
      • Added in security jackboots.
      • -
      -
    • Uhangi updated: -
        -
      • Traitors can now purchase syndicate balloons, which serve no purpose other than to blow your cover. For a limited time only, you can get them at a bargain price - just 10 telecrystals!
      • -
      • Removed security shotguns from the armory. No fun allowed.
      • -
      • Changed some bullet damage stuff.
      • -
      -
    • Microwave updated: -
        -
      • Monkey boxes:
      • -
      • Contains a score of monkey cubes, which you apply water to create monkies. Nanotrasen provides only the finest technology!
      • -
      • You can order monkey crates from the cargo bay. They contain monkey boxes.
      • -
      • Changed the amount of labels labelers have to 30. 10 was too low and 30 should not be too griefy.
      • -
      • Maximum label text length increased from 10 to 64.
      • -
      • You can no longer label people because they can just peel the labels off. Sorry, clowns!
      • -
      • Jelly dooonnuuuutsss! Happy birthday, officers!
      • -
      • Made xenomeat not give any nutrition.
      • -
      • Added some new reagents.
      • -
      • Made it possible to feed monkies and xenos things, as well as making it possible for them to eat themselves (please don't read that too literally).
      • -
      • Added in synthiflesh.
      • -
      • Plasma is now not used in reactions, instead, is treated as a catalyst that is not used up. This only applies to certain reactions.
      • -
      • Made it possible to grind more things in the chemistry grinder.
      • -
      -
    • Errorage updated: -
        -
      • Increased environmental damage by a factor of 1.5.
      • -
      • Made firesuits a lot more resistant to heat. Previously, they stopped protecting at around 4,500 degrees. They now go up to around 10,000 (which is also the temperature which the floor starts melting)
      • -
      • Edited the quartermaster's office a bit.
      • -
      • Cargo technicians now have access to a cargo ordering console.
      • -
      • Added different-colored hardhats. The CE gets a white hardhat.
      • - -
      -
    • Rastaf.Zero updated: -
        -
      • Botanists get a new toy: Biogenerator. Insert biological items, recieve biological items.
      • -
      • Added roller beds, otherwise known as stretchers, to medbay. You can buckle people onto them and pull them.
      • -
      • Added egg-smashing and tomato-smashing decals.
      • -
      -
    • Muskets updated: -
        -
      • The prepackaged songs (Space Asshole, Cuban Pete, Darkest Honk, etc) have been removed. This doesn't mean admins can't play midis, this just gets rid of a lot of unnecessary download time.
      • -
      -
    • Firecage updated: -
        -
      • A whole bunch of new drinks and food. Seriously, there's alot!
      • -
      • New weapons such as the shock revolver and large energy crossbow.
      • -
      • Hydroponics can now grow a bunch more stuff. A lot of these new crops have some very interesting mutations.
      • -
      • Added a command for AIs to change their icon.
      • -
      • New costumes to the costume room.
      • -
      -
    • Urist McDorf updated: -
        -
      • Adding shading to pills.
      • -
      • Detective's office noir look has been removed. The icon operations required to render everything in monochrome was too heavy on the players.
      • -
      • Added in an uplink implant.
      • -
      -
    • Doohl updated: -
        -
      • A new alien race: Metroids! They are a mostly non-sentient race of jellyfish-like organisms that float in the air and feed on the life energy of other organisms. While most Metroids have never shown signs of self-awareness, they do exhibit signs of basic logic and reasoning skills as well as very sophisticated perception. Nanotrasen has shipped two baby Metroids for the xenobiology department. They should be handled with the utmost care - they are some of the deadliest beings in the known universe!
      • -
      • R&D gets a new toy: the freeze gun. Despite popular belief, this will not literally freeze things!
      • -
      • Every single chemical reagent has been assigned a color.
      • -
      • You can now see beakers fill up with chemicals. You can also observe how the colors mix inside the beakers. Spray bottles also will also show the color of whatever you're spraying.
      • -
      • Added a timestamp to combat logs.
      • -
      • Non-insulated gloves now need to be wrapped in wire in order to be electrified.
      • -
      • You can now shoot at people on the ground by simply clicking on the tile they're on.
      • -
      • Changeling husks are now uncloneable. To clarify: when a changeling sucks out a victim's DNA, the victim is said to become a "husk".
      • -
      -
    - -4 July 2011. -
      -
    • Agouri updated: -
        - Medical stuff overhaul in preparation of Erro's big Medic update: -
      • Sleepers are now able to heal every kind of damage. Drag your ass to medbay and ask a doctor to get you in one.
      • -
      • A lil' bit faster cloning (about 30% faster) due to popular demand.
      • -
      • Sleepers are now all located in the inner part of medbay, except for the examination room one.
      • -
      • Added Dermaline, burn-healing drug that outpowers kelotane (and kelotane is getting a major nerf, so be sure to know how to get this). Recipe is on the wiki if you need to make it.
      • -
      • Drugs no longer heal or metabolise when injected in dead bodies, fuck. Thank god you guys missed this major bug or we'd have cloning-by-injecting-healing-drugs.
      • -
      • Reminder to coders: Goddamn, update the changelog. -
      -
    • - -
    • Matty updated: -
        -
      • New engineering backpacks. Enjoy!
      • -
      -
    • -
    - -18 June 2011. -
      -
    • Agouri updated: -
        -
      • Bugfixes: The reagent grinding now works, allowing the miners to FINALLY bring plasma to the chemistry.
      • -
      • Bugfixes: Pill bottles and clipboards can now be removed from the pockets once placed there.
      • -
      -
    • -
    -
    -7 June 2011. -
      -
    • TLE updated: -
        -
      • Wiped/suicided pAIs should be eligible for being candidates again (5 minute cooldown between prompts.)
      • -
      • pAIs are now affected by EMP bursts. pAIs hit with a burst will be silenced (no speech or PDA messaging) for two minutes and may have their directives or master modified. A sufficiently powerful EMP burst will have a 20% chance of killing a pAI.
      • -
      -
    • -
    • Neo updated: -
        -
      • Nar-sie is now a more vengeful eldritch being. When summoned into our world, he first rewards his loyal cultists by chasing down and eating them first, then turns his attention to any remaining humans.
      • -
      -
    • -
    • Darem updated: -
        -
      • Gun Code Overhaul Phase 1.
      • -
      • Taser guns shoot ONE WHOLE SHOT more then they do now.
      • -
      • Energy Crossbow has a slightly higher shot capacity (still automatically recharges).
      • -
      • Revolvers can either be loaded one shell at a time or all at once with an ammo box.
      • -
      • Shotguns no longer need to be pumped before firing (will change back in phase 2).
      • -
      -
    • -
    • K0000 updated: -
        -
      • Arcane tome now has a "notes" option. Set English translations for runewords which come up when scribing runes. Attack an arcane tome with another arcane tome to copy your notes to the target tome.
      • -
      • Stun rune buffed considerably. Its a 1-use item so it deserved longer stun time.
      • -
      • Tome text: Added missing word description for stun rune.
      • -
      -
    • -
    -
    - -1 June 2011, Canadian Day Against Homophobia -
      -
    • Noise updated: -
        -
      • Changed holopad speaking to :h on request.
      • -
      • Ninja fixes, changes, etc. Refer to the code changelog for more info.
      • -
      -
    • -
    • Neo updated: -
        -
      • Department radio chat now shows with the department name instead of the frequency.
      • -
      -
    • -
    • Veyveyr updated: -
        -
      • Spent casing sprites + SMG sprite.
      • -
      • Sprites for 1x4 and 1x2 pod doors.
      • -
      -
    • -
    • Errorage updated: -
        -
      • Fixed twohanded weapon throwing, which left the 'off-hand' object in your other hand.
      • -
      • Doors now hide items under them when closed, mobs are still always above.
      • -
      • Singularity engine emitter is now much quieter.
      • -
      • Mining station redesigned.
      • -
      • Atmospherics' misc gasses tank now starts with N2O.
      • -
      • Hitting the resist button while handcuffed and buckled to something will make you attempt to free yourself. The process is the same as trying to remove handcuffs. When the 2 minutes pass you will be unbuckled but still handcuffed.
      • -
      -
    • -
    • ConstantA updated: -
        -
      • Added exosuit energy relay equipment. Uses area power (any power channel -available) instead of powercell for movement and actions, recharges powercell.
      • -
      • Exosuits can be renamed. Command is in Permissions & Logging menu.
      • -
      • Lowered construction time for Ripley parts.
      • -
      • Exosuit wreckage can be salvaged for exosuit parts (torso, limbs etc).
      • -
      • Speed-up for mecha.
      • -
      • New malf-AI sprite. (Sprite donated by the D2K5 server)
      • -
      -
    • -
    • Cheridan updated: -
        -
      • Updated mine floor and wall edge sprites.
      • -
      -
    • -
    • Urist McDorf updated: -
        -
      • AIs no longer bleed when they reach 0HP (Critical health).
      • -
      • Added 2 more security HUDs to security.
      • -
      • Security HUDs now show if a person has a tracking implant.
      • -
      -
    • -
    • Microwave updated: -
        -
      • Barman renamed to Bartender.
      • -
      • The amount of drink you get when mixing things in the bar has been rebalanced.
      • -
      • Fixed arrivals maintenance shaft not having air at round start.
      • -
      -
    • -
    • Deuryn updated: -
        -
      • Meteors now do a bit more damage and they're not stopped by grills.
      • -
      -
    • -
    • TLE updated: -
        -
      • Added personal AIs (pAI).
      • -
      -
    • -
    -
    - -19 May 2011 -
      -
    • Errorage updated: -
        -
      • Asteroid floors can be built on by adding tiles
      • -
      • Mining satchels now fit in rig suit storage, on belts and in pockets.
      • -
      • Cables now come in four colors: Red, yellow, green and blue.
      • -
      -
    • - -
    • NEO updated: -
        -
      • Armour overhaul, phase 3. See rev notes for details.
      • -
      • AI cores should now block movement.
      • -
      • MMIs are now properly buildable with the mecha fabricator.
      • -
      -
    • - -
    • Urist updated: -
        -
      • Added sandstone and mineral doors. Mineral boors cannot be opened by the AI or NPCs.
      • -
      • Removed Imperium robes from map.
      • -
      • Added the ability to draw letters and graffiti with crayons.
      • -
      • Removed fire axes except for bridge and atmospherics.
      • -
      -
    • - -
    • Veyveyr updated: -
        -
      • New serviceborg sprite option.
      • -
      • Map changes to robotics; removed borg fabricators and added second exosuit fabricator.
      • -
      • Cyborg parts are now built from exosuit fabricators and benefit from research.
      • -
      • New exosuit fabricator and borg frame sprites.
      • -
      -
    • -
    -
    -14 May 2011, late friday 13 update. -
      -
    • K0000 updated: -
        -
      • Cult updates:
      • -
      • New rune! Stun rune. When used as rune, briefly stuns everyone around (including cultists). When imbued into a talisman, hit someone to stun and briefly mute them. Spawnable with the starter talisman.
      • -
      • Imbue rune doesnt disappear after succesful invocation, only the source rune.
      • -
      • Chaplain's bible now has 20% chance to convert a cultist (was 10%), and gives a message on success.
      • -
      • Also, wrapping paper is back! Find it in the mailroom.
      • -
      -
    • - -
    • NEO updated: -
        -
      • Beginning of armor overhaul. Armor now has slightly better defence against melee, and weaker against shots. More coming soon...someday
      • -
      • Cyborgs finally drop their MMI when gibbed like they were supposed to back when I added MMIs. Round- start cyborgs use whatever name you have selected for your character for the brain that gets spawned for them.
      • -
      -
    • - -
    • Darem updated: -
        -
      • Chemistry update
      • -
      • In containers where there isn't a perfect ratio of reagents, reactions won't consume ALL of the related reagents (so if you mix 10 anti-toxin with 20 inaprovaline, you get 10 tricordrazine and 10 inaprovaline rather then just 10 tricodrazine)
      • -
      • Catalysts: some reactions might need presence of an element, while not directly consuming it.
      • -
      • Reactions changed to use catalysts: all recipes that require Universal Enzyme now require 5 units of the enzyme but the enzyme isn't consumed (So Tofu, Cheese, Moonshine, Wine, Vodka, and Kahlua recipes). -
      -
    • -
    • Errorage updated: -
        -
      • Smooth tables: Tables now automatically determine which direction and sprite they'll use. They will connect to any adjacent table unless there is a window between them (regular, reinforced, tinted, whichever)
      • -
      -
    • -
    -
    -7 May 2011, Mother's day? -
      -
    • Agouri updated: -
        -
      • Fireaxes now work. Derp.
      • -
      -
    • - -
    • Erro updated: -
        -
      • New sprites for thermited walls and girders. Rework of thermited walls. Thermited walls leave a remnant damaged wall, crowbar it to scrap it.
      • -
      • More colors for the lightfloors CANCELLED/POSTPONED
      • -
      -
    • - -
    • Noise updated: -
        -
      • Codephrases for traitors. More details here
      • -
      • New mech sprite
      • -
      -
    • -
    -
    -6 May 2011, AMURRICA FUCK YEAH day -
      -
    • DANGERCON UPDATE:Agouri and Erro updated(I'm in the DangerCon team now, nyoro~n :3): -
        -
      • Backpacks removed from all players. It was unrealistic. You can now had to the living quarters to get one from the personal closets there.
      • -
      • Any firearms now send you to critical in 1-2 shots. Doctors need to get the wounded man to surgery to provide good treatment. Guide for bullet removal is up on the wiki.
      • -
      • Brute packs and kelotane removed altogether to encourage use of surgery for heavy injury.
      • -
      • Just kidding
      • -
      • Fireaxe cabinets and Extinguisher wall-mounted closets now added around the station, thank Nanotransen for that.
      • -
      • Because of Nanotransen being Nanotransen, the fire cabinets are electrically operated. AIs can lock them and you can hack them if you want the precious axe inside and it's locked. The axe itself uses an experimental two-handed system, so while it's FUCKING ROBUST you need to wield it to fully unlock its capabilities. Pick up axe and click it in your hand to wield it, click it again or drop to unwield and carry it.You can also use it as a crowbar for cranking doors and firedoors open when wielded, utilising the lever on the back of the blade. And I didn't lie to you. It's fucking robust.
      • -
      • Fireaxe, when wielded, fully takes up your other hand as well. You can't switch hands and the fireaxe itself is unwieldy and won't fit anywhere. -
      • A fireaxe cabinet can also be smashed if you've got a strong enough object in your hand.
      • -
      • EXTINGUISHER CLOSETS, made by dear Erro, can be found in abundance around the station. Click once to open them, again to retrieve the extinguisher, attack with extinguisher to place it back. Limited uses, but we've got plans for our little friend. -
      • Sprite kudos go to: Cheridan for most of them, Khodoque for the fantastic fireaxe head. I merged those two. Also thanks to matty and Arcalane for giving it a shot.
      • -
      • Has the piano got TOO annoying? Try the fire axe...
      • -
      • Oh, and tou can now construct Light floors! To do it: Use wires on glass, then metal on the produced assembly, then place it on an uncovered floor like you would when replacing broken floor tiles. To deconstruct: Crowbar on light floor, use crowbar on produced assembly to remove metal, wirecutters to seperate the wires from the glass. Sprites by delicious Hempuli.
      • -
      • Got something to bitch about? Got a bug to report? Want to create drama? Did the clown destroy your piano while you were playing an amazing space remix of the moonlight sonata? Give it here - -
      -
    • - -
    • Rastaf.Zero updated: -
        -
      • New uniforms added for captain and chaplain, in their respective lockers. Credits to Farart.
      • -
      -
    • - -
    • Urist McDorf updated: -
        -
      • Mime and Clown now spawn with Crayons. You can eat those crayons. And use them for other nefarious purposes.
      • -
      • Health Scanners (A new type of Goggles) now spawn in medbay. Use them, doctors!
      • -
      • New Arcade toy.
      • -
      • Glowshrooms! What other lifeform will threaten the welfare of the station now?!
      • -
      • Bananas growable in hydroponics. Also soap is now on-board.
      • -
      • Added new "Lights out!" random event.
      • -
      -
    • -
    • ConstantA updated: -
        -
      • Mech pilots are now immune to zapping, thank you very much.
      • -
      -
    • -
    -
    - -17 April 2011, World Hemophilia Day -
      -
    • Microwave updated: -
        -
      • Rabbit ears have a small tail, night vision goggle sprites updated.
      • -
      • Space tea has a nice, calming effect.
      • -
      • Space drugs? Liberty cap... something like that. Microwave, make your changelog entries more understandable!
      • -
      • Brobot merged with Service Borg with a Rapid Service Fabricator.
      • -
      • Arcade machine prizes look and sound realistic once again.
      • -
      • New arcade toy: Syndicate space suit costume, can hold arcade toys in suit storage.
      • -
      • Empty cap gun loaders can be recycled in an autolathe.
      • -
      • Seizure man has laying down sprites now. Update to wizard den.
      • -
      • Mech bay has two more borg chargers.
      • -
      • Beepsky is back!
      • -
      • Detective's office grille has been electrified.
      • -
      • You can now see if someone is wearing an emergency oxygen tank on their belt on the mob itself.
      • -
      • Lexorin - Now deals 3 oxygen damage per tick. Countered with Dexalin or Dexalin Pkus, which remove 2 units of it from your body per tick.
      • -
      • Bilk - Shares the effects of beer and milk. Disgusting!
      • -
      • Sugar - Gives nutrition!
      • -
      • Arithrazine - Now extremely good against radiation damage.
      • -
      • Hyronalin - Stronger radiation removal
      • -
      • Space cleaner spray bottles now contain enough cleaner for 50 uses. Making space cleaner now yields more cleaner.
      • -
      -
    • -
    • Errorage updated: -
        -
      • Shuttle diagonal sprites now work for any kind of floor.
      • -
      • You can now make plaques from gold. Place them on a wall and engrave an epitaph.
      • -
      • Placed a single wall tile in the AI satellite so you don't have a clear LOS of the AI from the door.
      • -
      • Added arrivals lobby. (Map by Superxpdude, updated by Microwave)
      • -
      • Lattice now connects to the solar shields.
      • -
      • Law office maintenance is now connected with Tech storage maintenance. (Some rewiring dont in the area)
      • -
      • Xenobiology now has it's own access level. (Also fixed xeno pen access and blast doors)
      • -
      • You might soon start to see different airlocks and airlock assemblies around the station. (Sprites donated by Baystation 12)
      • -
      • Chemical storage added, discussion on which chemicals it should store is on the forums. You're welcome to contribute.
      • -
      • Hot fires will now melt floors.
      • -
      • Added a pair of market stalls south of the teleporter. LET THERE BE CLOWNMART!
      • -
      • Screwdrivers and wirecutters can now spawn in different colors.
      • -
      • Electrical toolboxes have a 5% chance of spawning a pair of insulated gloves. A set spawns in tech storage.
      • -
      • Oxygen canisters now spawn in emergency storage, near disposal, in the incinerator and the CE's office.
      • -
      • A plasma canister now spawns in toxins, near the maintenance door.
      • -
      • Wooden tables now look nicer.
      • -
      -
    • -
    • Agouri updated: -
        -
      • 2001 space suits added to AI Satellite!
      • -
      • New look for the 2001 space suit.
      • -
      • 2001 space suit jetpack added.
      • -
      • Improved TRAYS!
      • -
      -
    • -
    • Noise updated: -
        -
      • Thermals and mesons no longer give slightly better night vision.
      • -
      • NINJAS! (Too many things to list)
      • -
      • Wizards are no longer trackable by the AI when in their den.
      • -
      • Removed all old notes, except for the last one.
      • -
      • Nuke team now cannot return with their shuttle until the bomb is armed and counting down.
      • -
      • Energy blades can no longer cut through r-walls, walls take 7 seconds to cut through.
      • -
      • Turrets are now destructible. Bash them with stuff when they pop out or (more likely) die trying.
      • -
      • Updated Ripley Mech sprite.
      • -
      -
    • -
    • Neo updated: -
        -
      • You can now aim guns at body parts, armor and helmets properly protect you from projectiles.
      • -
      • Cat ears now match the hair color of the wearer.
      • -
      • Robots can no longer stick their items onto/into things.
      • -
      • Meson, thermal and x-ray vision are now modules for borgs.
      • -
      • Welding now uses less fuel when on and idle but more when welding.
      • -
      • Hopefully fixed the bug when running into airlocks didn't open them and running into objects didn't push them.
      • -
      -
    • -
    • HAL updated: -
        -
      • Added air alarm to security checkpoint, added cameras to aux. arrival docks so the AI can see everything.
      • -
      • Added fire alarm, fire locks and air alarm to delivery office.
      • -
      -
    • -
    • ConstantA updated: -
        -
      • Added mecha DNA-locking. Only the person with matching UE can operate such mechs.
      • -
      • Added two mecha armor booster modules and a repair droid module.
      • -
      • Mech fabricator is now buildable.
      • -
      • Gygax construction is now reversible.
      • -
      -
    • -
    • Rastaf0 and Farart updated: -
        -
      • Ghosts should now always properly hear people.
      • -
      • Monkeyized people (genetics or jungle fever disease) no longer lose their genetic mutations and diseases.
      • -
      • People who get bitten by monkeys get jungle fever.
      • -
      • Most chemicals should now heal and harm humans properly.
      • -
      • Many new (and updated) recipes for the microwave including Pizza, Meatball Soup, Hot Chili and many more.
      • -
      • Items should no longer spawn under vendomats and microwaves.
      • -
      • Runes are now drawn under doors and tables.
      • -
      • Penlights fit in medical belts.
      • -
      • People will scream if they get cremated while still alive.
      • -
      • Diseases should now properly make you loose health.
      • -
      • Monkeys wearing masks now get acid protection too.
      • -
      • You should probably turn off your stun baton before washing it.
      • -
      • latex loves + short piece of wire + some air from tank = balloon!
      • -
      • Kitchen was expanded, also a new look for the kitchen sink.
      • -
      • New dishware vending machine - dispenses knives, forks, trays and drinking glasses.
      • -
      • Water cooler was added to kitchen.
      • -
      • New uniform - Waiter Outfit. Chef can give it to his assistant.
      • -
      -
    • -
    • Deeaych updated: -
        -
      • Updated satchel, bananimum, shovel, jackhammer and pick-in-hand sprites.
      • -
      • Many unneeded r-walls removed, detective's office reinforced.
      • -
      • Captain armor now acts as a space suit, added a unique captain's space helmet to captain's quarters.
      • -
      • Golems cannot speak, but should be perfectly spawnable. Also added golem fat sprite.
      • -
      • Security borgs have side sprites.
      • -
      -
    • -
    • Matty406 updated: -
        -
      • AIs can now feel a little more dorfy.
      • -
      • Many ores, both raw and smelted, look much better.
      • -
      -
    • -
    • Urist_McDorf updated: -
        -
      • You can now light other people's cigarettes by targeting their mouth with a lighter.
      • -
      -
    • -
    • Veyveyr updated: -
        -
      • New tool sprites.
      • -
      • New sprites for smooth-lattice.
      • -
      -
    • -
    • Muskets updated: -
        -
      • Kabobs now return the bar used to make them.
      • -
      -
    • -
    -
    - -2 April 2011, International Children's Book Day -
      -
    • Microwave updated: -
        -
      • New look for the mining cyborg, jackhammer, kitchen sink.
      • -
      • Singularity is now enclosed again (still airless tho).
      • -
      • Wizard has a new starting area.
      • -
      • Chemists and CMOs now have their own jumpsuits.
      • -
      -
    • -
    • ConstantA updated: -
        -
      • You can now put Mind-machine-interface (MMI)'d brains into mecha.
      • -
      -
    • -
    • Errorage updated: -
        -
      • Added smooth lattice.
      • -
      -
    • -
    -
    - -26 March 2011 -
      -
    • Rastaf0 updated: -
        -
      • Food sprites from Farart
      • -
      • New food: popcorn (corn in microwave), tofuburger (tofu+flour in microwave), carpburger (carp meat+floor in microwave)
      • -
      • Medical belts are finally in medbay (credits belong to errorage, I only added it)
      • -
      • Pill bottles now can fit in containers (boxes, medbelts, etc) and in pockets.
      • -
      • Cutting camera now leaves fingerprints.
      • -
      -
    • -
    • Microwave updated: -
        -
      • Armor Can hold revolvers, and so can the detective's coat.
      • -
      • Chef's apron is going live, it can carry a knife, and has a slight heat -resistance (only slight don't run into a fire).
      • -
      • Kitty Ears!
      • -
      • Various food nutriment changes.
      • -
      • Added RIGs to the Mine EVA.
      • -
      • Night vision goggles. They have a range of five tiles.
      • -
      • Added Foods: Very Berry Pie, Tofu Pie, Tofu Kebab.
      • -
      • Modified foods: Custard Pie is now banana cream pie.
      • -
      -
    • -
    • ConstantA updated: -
        -
      • Removed redundand steps from Gygax and HONK construction.
      • -
      • Added some mecha equipment designs to R&D.
      • -
      -
    • -
    -
    - -23 March 2011, World Meteorological Day -
      -
    • Neo updated: -
        -
      • Fixed PacMan (and affiliates) generator construction.
      • -
      • It is now possible to actually eat omelettes with the fork now, instead of just stabbing yourself (or others) in the eye with it.
      • -
      • Welding masks can now be flipped up or down. Note that when they're up they don't hide your identity or protect you from welding.
      • -
      • Reagent based healing should now work properly.
      • -
      • Revolver has been balanced and made cheaper.
      • -
      • Tasers now effect borgs.
      • -
      • Plastic explosives are now bought in single bricks.
      • -
      • Nuke team slightly buffed and their uplink updated with recently added items.
      • -
      • Player verbs have been reorganized into tabs.
      • -
      • Energy swords now come in blue, green, purple and red.
      • -
      • Cameras are now constructable and dismantlable. (Code donated by Powerful Station 13)
      • -
      • Updated the change network verb for AIs. (Code donated by Powerful Station 13)
      • -
      • Added gold, silver and diamond pickaxes to R&D which mine faster.
      • -
      -
    • -
    • Agouri updated: -
        -
      • New look for the Request consoles.
      • -
      -
    • -
    • Rastaf0 updated: -
        -
      • Brig cell timers should now tick closer-to-real seconds.
      • -
      • New look for food, including meat pie, carrot cake, loaded baked potato, omelette, pie, xenopie and others. (some sprites by Farart)
      • -
      • Hearing in lockers now works as intended.
      • -
      • Fixed electronic blink sprite.
      • -
      • Added the 'ghost ears' verb, which allows ghosts to not hear anything but deadcast.
      • -
      -
    • -
    • XSI updated: -
        -
      • New AI core design.
      • -
      • HoP now has a coffee machine!
      • -
      -
    • -
    • Veyveyr updated: -
        -
      • Replaced nuke storage with a vault.
      • -
      • Redesigned the mint, moved the public autolathe and n2o storage.
      • -
      • New look for the coin press. (Sprite by Cheridan)
      • -
      -
    • -
    • Errorage updated: -
        -
      • You can now manually add coins into money bags, also fixed money bag interaction window formatting.
      • -
      • QM no longer has access to the entire mining station to stop him from stealing supplies.
      • -
      • New machine loading sprite for mining machinery. (sprites by Cheridan)
      • -
      • Added a messanging server to the server room. It'll be used for messanging, but ignore it for now.
      • -
      • The delivery office now requires delivery office access. It's also no longer called "Construction Zone"
      • -
      • Almost all the mecha parts now have sprites. (Sprites by Cheridan)
      • -
      • Tinted and frosted glass now look darker.
      • -
      • There are now more money sprites.
      • -
      • Department closets now contain the correct headsets.
      • -
      -
    • -
    • Microwave updated: -
        -
      • Bicaridine now heals a lot better than before.
      • -
      • Added Diethylamine, Dry Ramen, Hot Ramen, Hell Ramen, Ice, Iced Coffee, Iced Tea, Hot Chocolate. Each with it's own effects.
      • -
      • Re-added pest spray to hydroponics.
      • -
      • Carrots now contain a little imidazoline.
      • -
      • HoS, Warden and Security Officer starting equipment changed.
      • -
      • New crate, which contains armored vests and helmets. Requires security access, costs 20.
      • -
      • Miner lockers now contain meson scanners and mining jumpsuits.
      • -
      • Food crate now contains milk, instead of meatballs. Lightbulb crates cost reduced to 5. Riot crates cost reduced to 20. Emergency crate contains 2 med bots instead of floor bots. Hydroponics crate no longer contains weed spray, pest spray. It's latex gloves were replaced with leather ones and an apron.
      • -
      • Added chef's apron (can hold a kitchen knife) and a new service borg sprite.
      • -
      • Autolathe can now construct kitchen knives.
      • -
      • Biosuit and syndicate space suits can now fit into backpacks.
      • -
      • Mime's mask can now be used as a gas mask.
      • -
      • Added welding helmet 'off' sprites.
      • -
      -
    • -
    - -
    - -18 March 2011 -
      -
    • Errorage updated: -
        -
      • You can now use the me command for emotes! It works the same as say "*custom" set to visible.
      • -
      • There is now a wave emote.
      • -
      • Enjoy your tea!
      • -
      -
    • -
    • Deeaych updated: -
        -
      • The exam room has some extra prominence and features.
      • -
      • A new costume for the clown or mime to enjoy.
      • -
      • Service Cyborgs can be picked! Shaker, dropper, tray, pen, paper, and DOSH to show their class off. When emagged, the friendly butler-borg is able to serve up a deadly last meal.
      • -
      • It should now be possible to spawn as a cyborg at round start. Spawned cyborgs have a lower battery life than created cyborgs and begin the round in the AI Foyer.
      • -
      -
    • -
    • Rastaf0 updated: -
        -
      • Fixed an issue with examining several objects in your hands (such as beakers).
      • -
      • Fixed bug with random last name being empty in rare cases.
      • -
      -
    • -
    • hunterluthi updated: -
        -
      • It is now possible to make 3x3 sets of tables.
      • -
      • Fixed some missplaced grilles/lattices on the port solar.
      • -
      • There is now a breakroom for the station and atmos engineers. It has everything an intelligent young engineer needs. Namely, Cheesy Honkers and arcade games.
      • -
      -
    • -
    -
    -15 March 2011, International Day Against Police Brutality -
      -
    • Errorage updated: -
        -
      • Autolathe deconstruction fixed.
      • -
      • Atmos Entrance fixed.
      • -
      • AI no longer gibs themselves if they click on the singularity.
      • -
      • Fixed all the issues I knew of about storage items.
      • -
      • Redesigned Assembly line and surrounding maintenance shafts.
      • -
      • Redesigned Tech storage. (Map by Veyveyr)
      • -
      -
    • -
    • TLE updated: -
        -
      • Forum account activation added. Use the 'Activate Forum Account' verb.
      • -
      -
    • -
    • Neo updated: -
        -
      • New R&D Item: The 'Bag of holding'. (Sprite by Cheridan)
      • -
      • Getting someone out of the cloner now leaves damage, which can only be fixed in the cryo tube.
      • -
      • New reagent: Clonexadone, for use with the cryo tube.
      • -
      • Fixed using syringes on plants.
      • -
      -
    • -
    • Constanta updated: -
        -
      • Added queueing to fabricator.
      • -
      -
    • -
    • Rastaf0 updated: -
        -
      • Air alarms upgraded.
      • -
      • Fixed problem with AI clicking on mulebot.
      • -
      • Airlock controller (as in EVA) now react to commands faster.
      • -
      • Fixed toxins mixing airlocks.
      • -
      -
    • -
    - -6 March 2011 -
      -
    • Neo updated: -
        -
      • Neo deserves a medal for all the bugfixing he's done! --errorage
      • -
      -
    • -
    • Errorage updated: -
        -
      • No. I did not code on my birthday!
      • -
      • Windows can now be rotated clockwise and counter clockwise.
      • -
      • Window creating process slightly changed to make it easier.
      • -
      • Fixed the newly made reinforced windows bug where they weren't properly unfastened and unscrewed.
      • -
      • Examination room has a few windows now.
      • -
      • Can you tell I reinstalled Windows?
      • -
      • Robotics has health analyzers.
      • -
      • Bugfixing.
      • -
      -
    • -
    • Deeyach updated: -
        -
      • Roboticists now spawn with a lab coat and an engineering pda
      • -
      -
    • -
    - -2 March 2011, Wednesday -
      -
    • Errorage updated: -
        -
      • Mapping updates including Atmospherics department map fixes, CE's office and some lights being added here and there.
      • -
      • Mining once again given to the quartermaster and HoP. The CE has no business with mining.
      • -
      • Removed the overstuffed Atmos/Engineering supply room.
      • -
      • Replaced all 'engineering' doors in mining with maintenance doors as they were causing confusion as to which department mining belongs to.
      • -
      • The incinerator is now maintenance access only.
      • -
      -
    • -
    • Neo updated: -
        -
      • New look for the advanced energy gun. (Sprite by Cheridan)
      • -
      • Mech fabricator accepts non-standard materials.
      • -
      • Mules accesses fixed, so they can be unlocked once again.
      • -
      • Atmospherics department mapping overhaul. (Map by Hawk_v3)
      • -
      • Added more name options to arcade machines.
      • -
      -
    • -
    • ConstantA updated: -
        -
      • Added mecha control console and mecha tracking beacons.
      • -
      • Some changes to gygax construction.
      • -
      -
    • -
    • Darem updated: -
        -
      • R&D minor bugfixes.
      • -
      • AI computer can now be deconstructed (right click and select 'accessinternals').
      • -
      • Server room updated, added server equipment to use with R&D.
      • -
      • Wizard and ghost teleport lists are now in alphabetical order, ghosts can now teleport to the mining station.
      • -
      • Rightclicking and examining a constructable frame now tells you what parts still need to be finished.
      • -
      • Large grenades added to R&D.
      • -
      -
    • -
    • Deeyach updated: -
        -
      • Mining given to the CE. (Reverted by Errorage)
      • -
      • Clowns can now pick a new name upon entering the game (like wizards previously).
      • -
      -
    • -
    - -24 February 2011, Thursday -
      -
    • Darem updated: -
        -
      • Lighting code fixed for mining and thermite.
      • -
      • R&D instruction manual added to the R&D lab.
      • -
      • Fixed R&D disk commands not working.
      • -
      • Added portable power generators which run on solid plasma.
      • -
      • You can now set the numer of coins to produce in the mint.
      • -
      • Added two more portable power generators to R&D.
      • -
      -
    • -
    • Deeyach updated: -
        -
      • New uniform for roboticists
      • -
      -
    • -
    • Neo updated: -
        -
      • Game speed increased
      • -
      • Mining stacking machine no longer devours stacks larger than 1 sheet (it was only increasing its stock by 1 when given a stacked stack)
      • -
      • Stackable uranium ore added (a better sprite is needed, contributions are welcome)
      • -
      • Made Meteor gamemode actually do stuff
      • -
      • Made a bigger class of meteor
      • -
      • New R&D item: Advanced Energy Gun
      • -
      • Law priority clarified with regards to ion laws and law 0.
      • -
      -
    • - -
    • Veyveyr updated: -
        -
      • Minor mapping fixes
      • -
      -
    • -
    • Uhangi updated: -
        -
      • New red bomb suit for security.
      • -
      -
    • - -
    • Errorage updated: -
        -
      • Slight mapping change to arrival hallway.
      • -
      -
    • -
    - -23 February 2011, Red Army Day -
      -
    • Uhangi updated: -
        -
      • Antitox and Inaprovaline now mixable via chemistry.
      • -
      • Explosive Ordinance Disosal (EOD) suits added to armory and security.
      • -
      • Large beaker now holds 100 units of chemicals. (code by Slith)
      • -
      -
    • -
    • Rastaf0 updated: -
        -
      • Secbot interface updated.
      • -
      • Syringe auto-toggels mode when full.
      • -
      • Captain's flask volume increased.
      • -
      -
    • -
    • Neo updated: -
        -
      • Fixed the 'be syndicate' choice to actually work on nuke rounds.
      • -
      • Syndicates no longer win if they detonate the nuke on their ship.
      • -
      -
    • - -
    • Errorage updated: -
        -
      • Added cloning manual. (Written by Perapsam)
      • -
      -
    • -
    • K0000 updated: -
        -
      • Cult mode updates.
      • -
      • You can now read the arcane tome. It contains a simple guide for making runes.
      • -
      • Converting people doesnt give them word knowledge.
      • -
      • Sacrifice monkeys or humans to gain new words.
      • -
      • Total number of rune words set to 10
      • -
      • Some minor bugfixes.
      • -
      -
    • -
    - -20 February 2011, Sunday -
      -
    • Errorage updated: -
        -
      • Slight updates to processing unit and stacking machine at the mining outpost.
      • -
      • Digging now yields sand, which can be smelted into glass.
      • -
      • Stacking machine can now stack reinforced metal, regular and reinforced glass too.
      • -
      • Engineers now have two copies of the singularity safety manual.
      • -
      -
    • -
    • Neo updated: -
        -
      • Magboots now have a verb toggle like jumpsuit sensors.
      • -
      • Jumpsuit sensors are now in all jumpsuits, except tactical turtlenecks.
      • -
      • Tweaks to the AI report at round start.
      • -
      • Syndi-cakes now heal traitors/rev heads/etc much more than anyone else.
      • -
      • Containment fields zap once again.
      • -
      • Fire damage meter no longer lies about fire damage.
      • -
      -
    • -
    • Darem updated: -
        -
      • Mass Spectrometer added to R&D. Load it with a syringe of blood and it will tell you the chemicals in it. Low reliability devices may yield false information.
      • -
      • Not all devices have a 100% reliability now.
      • -
      • Miners now have access to mint foyer and loading area. Only captain has access to the vault.
      • -
      • More stuff can be analyzed in the destructive analyzer, protolathe can produce intelicards.
      • -
      -
    • -
    • Rastaf0 updated: -
        -
      • Added blast door button to atmospherics.
      • -
      • Toxins timer-igniter assemblies fixed.
      • -
      • Engineering secure storage expanded.
      • -
      • Added singularity telescreen.
      • -
      -
    • -
    - -18 February 2011, Friday -
      -
    • Errorage updated: -
        -
      • New look for the bio suits. (Biosuit and hood sprites by Cheridan)
      • -
      • New radiation suits added along with radiation hoods and masks. Must wear complete set to get full protection.
      • -
      -
    • -
    • Rastaf0 updated: -
        -
      • Binary translator cost reduced to 1 telecrystal.
      -
    • -
    • AtomicTroop updated: -
        -
      • Mail Sorter job added.
      • -
      • Disposal system redone to allow for package transfers. Packages are routed to mail sorter room and then routed to the rest of the station
      • -
      • Disposal area moved. Old disposal area now just an incinerator and a small disposal into space.
      • -
      • New wrapping paper for sending packages.
      • -
      -
    • -
    • Veyveyr updates: -
        -
      • New machine frame sprite.
      • -
      • Braincase sprites for mechs added. Not actually used, yet.
      • -
      -
    • -
    • Darem updates: -
        -
      • Research and Development system is LIVE. Scientists can now research new advancements in technology. Not much can be made, right now, but the system is there. Technologies are researched by shoving items into the destructive analyzer. Circuit Imprinter, Destructive Analyzer, and Protolathe are controlled from the R&D console.
      • -
      • Autolathe, Protolathe, Destructive Analyzer, and Circuit Imprinter can now be built, taken apart, and upgraded. The basic frame for all of the above requires 5 metal.
      • -
      -
    • -
    - -15 February 2011, Tuesday -
      -
    • Rastaf0 updated: -
        -
      • Added radio channels and headsets for miners (:h or :d ("diggers" lol)) and for cargo techs (:h or :q )
      • -
      • Added a personal headsets to HoP and QM.
      • -
      • Aliens now attack bots instead of opening control window.
      • -
      • All bots can be damaged and repaired.
      • -
      • All bots are effected to EMP now.
      • -
      • Atmos now starts with nitrous oxide in storage tank.
      • -
      -
    • -
    • Veyveyr updated: -
        -
      • New look for the pipe dispenser.
      • -
      -
    • Errorage updated: -
        -
      • Mining station will now charge properly.
      • -
      • Duffle bags (Money bags) can now be emptied.
      • -
      -
    • -
    - -14 February 2011, Valentine's day -
      -
    • Errorage updated: -
        -
      • New Job! - Shaft Miners have finally been added and are available to play.
      • -
      • Mining outpost - A new mining outpost has been built, the mining dock on SS13 has been updated.
      • -
      -
    • -
    • ConstantA updated: -
        -
      • Slight speed up for combat mechs..
      • -
      • Added H.O.N.K construction
      • -
      • Fixed bug with switching intent while in mecha.
      • -
      -
    • -
    - -
    12.02.2011, 01.00 GMT, r1021
    -
      -
    • Added Durand combat exosuit.
    • -
    • Players can modify operation permissions of newly constructed civilian mechs. Click on mech with ID card or PDA with ID inside.
    • -
    • Added robotics access to default mecha maintenance permissions (all mechs) and operation permissions (civilian models only).
    • -
    • Fixed double adminlog message of explosion proc.
    • -
    • Fixed accidental mecha wreckage deletion.
    • -
    • Tweaked mecha internal fire processing.
    • -
    • Added some mecha-related sounds.
    • -
    • Moved GaussRand to helpers.dm and added GaussRandRound helper proc.
    • -
    • Other small changes.
    • -
    - -
    11.02.2011, r1001-1020
    -
      -
    • Headsets upgraded. Shortcuts for channels are: :command :security scie:nce :engineering :medical. Also there is :binary :whisper :traitor and old good :h for your department. -
    • "One Click Queue" added: When you quickly click on two things in a row, it will automatically queue the second click and execute it after the default 'action delay' of 1 second after the first click. Previously you had to spam-click until 1 second had passed. THIS AFFECTS EVERYTHING. NEEDS TESTING. - Skie -
    • EMP effects added for further revisions. - Darem -
    • Goon stuff removed, AI/Bots leave behind hidden fingerprints, firedoors fixed, powersinks eat more, small map changes. - Mport -
    • Big map changes in engineering/robotics/science wing. - errorage -
    • Welder Fixed. Now burns your eyes again. - errorage -
    • 9x9 singularity sprite added. - Skie/Mport -
    • Ghetto surgery added. - Neophyte -
    • Nasty vent pump lag fixed. - Neophyte -
    • Mech gameplay and building updates. - ConstantA -
    - -
    08.02.2011, r999-1000
    -
      -
    • The amount of power the station uses should be lower. -
    • The singularity now changes size based upon how much energy it has -
    • New Machine: Particle Accelerator. -
    • It might need a better name/sprite but when put together properly and turned on it will shoot Accelerated Particles. -
    • The particles irradiate mobs who get in the way and move through solid objects for a short time. -
    • The Particle Accelerator parts are set up by using a Wrench followed by a Cable Coil, then finished with a screwdriver. -
    • When you shoot the Singularity Generator with Accelerated Particles it will spawn a Singularity. -
    • New layout for Engineering, might be changed up slightly in the next few days. -
    - -
    06.02.2011, r979
    -
      -
    • Jesus christ it's a new map what the fuck -
    • Just kidding, it's only minor changes to medbay/mechbay/cybernetics/R&D/toxins/robotics/chapel/theatre -
    • Okay so there's too many changes to list completely, but basically: toxins/R&D/virology/xenobiology are south through medbay; robotics/cybernetics/mechbay are where toxins used to be, the theatre and chapel are above medbay. -
    • Theatre is a new place for the Clown and Mime to play, there are some costumes available, a stage and backstage, and seating for the audience. -
    • R&D and Toxins have been combined together. R&D is still work in progress. You need to head south through medbay to get there. -
    • Medbay has been re-arranged slightly. Honestly, it's nothing, I bet you won't even notice anything different. There's also a new surgery suite, complete with pre-op and post-op rooms. -
    • Virology's been rearranged, but it is mostly in the same place still. -
    • Xenobiology is work in progress. [There's some fun stuff still being coded] -
    • The Chapel is now to the north. You'll probably be thinking something like "Goddamn, this place is fucking huge", but it's actually smaller than the previous chapel. -
    • Robotics and related stuff is also work in progress - however, everything needed for making borgs is there. Note: de-braining will now be done by surgeons in medbay, rather than roboticists in robotics, in case you're wondering where your optable went. -
    • I added color-coded pipes in the areas I was working on. Red pipes run from air siphons and feed into the waste loop; blue pipes run from air vents and pump whatever atmos is set to pump. Yeah, there's TWO pipe networks on the station, who knew? Well, some of you probably did, but I didn't! -
    • Please bring all complaints/ideas/suggestions/bugfixes to: This awesome thread on our forums -
    • This update brought to you by: veyveyr and Rookie, with help from friends! [Now you know who to strangle, please be gentle q_q] -
    - -
    05.02.2011, r968
    -
      -
    • This really needs to be updated more often. -
    • Various map updates have been applied with many more to come. Expect overhauls! -
    • Mining system nearing completion. -
    • Massive overhaul to the electricity systems, the way singularity makes power, and various related functions. -
    • Mime spawns with White Gloves instead of Latex Gloves (apparently there's a difference!) -
    • A new event has been- CLANG! What the fuck was that? -
    • Ion storm laws should be much more interesting. -
    • Security reports should no longer list traitor heads/AIs as possible revs/cultists, nor should nuke operatives ever get named for anything. -
    • Pens are much more versatile and user friendly. -
    • Mech building is rapidly on its way! Ripleys can be built, consult your quartermasters. -
    • Traitors now have several new things they can steal. -
    • Some surgeries coded to accompany the new operating room and surgery tools. -
    • Research and Design is continuing development and should be rolled out shortly. -
    • Various sprites added, tweaked, scrapped and fixed. -
    - -

    Changelog

    -
    05.02.2011, r968
    -
      -
    • This really needs to be updated more often. -
    • Various map updates have been applied with many more to come. Expect overhauls! -
    • Mining system nearing completion. -
    • Massive overhaul to the electricity systems, the way singularity makes power, and various related functions. -
    • Mime spawns with White Gloves instead of Latex Gloves (apparently there's a difference!) -
    • A new event has been- CLANG! What the fuck was that? -
    • Ion storm laws should be much more interesting. -
    • Security reports should no longer list traitor heads/AIs as possible revs/cultists, nor should nuke operatives ever get named for anything. -
    • Pens are much more versatile and user friendly. -
    • Mech building is rapidly on its way! Ripleys can be built, consult your quartermasters. -
    • Traitors now have several new things they can steal. -
    • Some surgeries coded to accompany the new operating room and surgery tools. -
    • Research and Design is continuing development and should be rolled out shortly. -
    • Various sprites added, tweaked, scrapped and fixed. -
    - -
    20.01.2011, r894
    -
      -
    • Pipes can now be removed and re-attached by wrenching them. -
    • Mining system continues to develop. Still unaccessible to players. -
    • Various map changes. Some minor lag causing things were fixed. -
    • Admins have a new tool: They can now give any spell to anyone. Hurray! -
    • Imadolazine now works. Maybe? -
    • Singularity now releases itself if fed too much and will potentially explode. -
    • Magboots now successfully prevent you from getting pulled into the singularity. -
    • Strike teams immune to facehuggers. Why? I dunno. -
    • Many reagent containers are adjustable so you can pour the exact amount you need. -
    • No more emitters working in space, Collectors and collector controllers now ID lockable. -
    • Christmas Contest plaque finally added. It's near the armor/warden's office. -
    • Rocks fall, everyone dies. -
    • All cyborgs and robots can now be named. Just use a pen on the cyborg's frame before the brain is inserted. -
    • Knock spell now unbolts doors as well as opens them. -
    • New cultist runs and other changes. -
    • Added surgery tools for eventual surgery system. -
    • Autolathe and Circuit Printer animations redone. Yay pretty icons. -
    • AI law changes/uploads are now tracked (admin viewable). -
    • Revheads now get a PDA uplink instead of a headset one. -
    • Added a penlight. -
    • Science Research and Development tech tree uploaded. Not really accessible by anyone yet, though. -
    - -
    14.01.2011, r853
    -
      -
    • Changlings Overhauled. Now function kinda like alium (using an internal chemical reserve instead of plasma) with each ability requiring a certain amount of chemicals to activate. Both venoms removed. Several "Dart" abiliites added. They allow the changling to deafen, blind, mute, paralyze, or even transform (dead) targets. -
    • Carp meat now contaminated with Carpotoxin. Anti-toxin negates the poison, however. -
    • New Reagent: Zombie Powder: Puts subjects into a deathlike state (they remain aware, though). Each unit of Zombie Powder requires 5 units of Carpotoxin, Sleeping Toxin, and Copper. -
    • Various alium fixes. -
    • Matches now available from smokes machine. -
    • Megabomb bug fixed. Bombs with timers/signalers won't detonate after the timer/ signaler is removed. -
    • New Disease: Rhumba Beat. Functions like GBS with a few exceptions. Not only available by admindickery. -
    • More mining fixes/changes. -
    • Ghost can now teleport to AI sat, Thunderdome, and Derelict. -
    • New gimmick clothes -
    • Constructing Glass Airlocks now use one sheet of R.Glass. -
    • Windows mow always appear above grills and pipes always above lattices. -
    • Added FireFighter mecha and various mecha fixes. -
    • Deconstructed walls now leave proper floor tiles (that can be pried up like normal) and remember what kind of floor they were before the wall was made. -
    • Carded AIs no longer take damage while in unpowered areas. -
    • Chaplains can now name their religion at round start. -
    • New Recipies: Clown Burger (1 Clown wig, 5 flour), Mime Burger (1 beret, 5 flour), Cuban Carp (1 carp fillet, 1 chili, 5 flour). -
    • Napalm nerfed a bit. Produces ~25% less plasma but it's all concentrated in a single tile (will still spread, though). -
    • Reagent bottles can, once again, be put into grenades. -
    • Various minor map changes. -
    - -
    08.01.2011,8:00PST, r820
    -
      -
    • Holograms (AI controled psudo-mobs) added. Currently only admin spawn. -
    • Pre-spawned pills no longer have randomized image. -
    • Bridge reorganized. -
    • Automated turrets now less dumb. Additionally, turrets won't target people laying down. -
    • Cultists now automatically start known words for add cultist ritual. Also, converted cultists start knowning a word. -
    • Supply ship no longer can transport monkeys. Also, monkeys are no longer orderable from QM. -
    • Meat Crate added to QM. -
    • Corn can now be blended in a blender to produce corn oil which is used to create glycern. -
    • Request Consoles added across the station. Can be used to request things from departments (and slightly easier to notice then the radio). -
    • Centcom reoragnized a fair bit. Not that players care but admins might enjoy it. -
    • There is now a toggable verb that changes whether you'll turn into an alium or not. -
    • Hair sprited modified. -
    • Napalm and Incendiary Grenades both work now. Have fun setting things on fire. -
    • Binary Translater traitor item added. It allows traitors to hear the AI (it functions like a headset). -
    • New Disease: Pierrot's Throat. Enjoy, HONK! -
    • Robotic Transformation (from Robrugers) and Xenomorph Transformation (from xenoburgers) now curable. -
    • Mining added. Only accessible by admins (and those sent by admins). Very much WIP. -
    • Alium Overhaul. Divided into multiple castes with distinct abilities. -
    • New AI Modules: The goody two-shoes P.A.L.A.D.I.N. module and it's evil twin T.Y.R.A.N.T. Only the former actually spawns on the station. -
    • Lizards added. They run away and shit. -
    • PDA overhaul. Doesn't change anything for humans, just makes coders happy. -
    • Firesuits redone to look less like pajamas and instead like firesuits. Fire lockers also added. -
    • New Mecha: H.O.N.K. -
    • Deployable barriers added. Can be locked and unlocked. -
    • Mecha bay (with recharging stations) added. -
    • Bunny Ears, Security Backpacks, Medical Backpacks, Clown Backpacks, and skirt added. -
    • Various wizard changes. New Wizard Spell: Mind Swap. Swap your mind with the targets. Be careful, however: You may lose one of your spells. Wizards are no longer part of the crew and get a random name like the AI does. Wizards can change their known spells with their spellbook but only while on the wizard shuttle. -
    • Circuit Imprinter: Using disks from the various deparments, new circuit boards and AI modules can be produced. -
    • Heat Exchanging pipes added and various pipe/atmos changes. -
    • Ghost/Observer teleport now works 100% of the time. -
    - -
    17.12.2010,11:00GMT
    -
      -
    • You need an agressive grip to table now, as well as being within one tile of the table (to nerf teletabling).
    • -
    • Teleport only runs once at the beginning of the round, hopefully reducing the lag in wizard rounds.
    • -
    • Wizards can't telepot back to their shuttle to afk now.
    • -
    • Someone added it a while ago and forgot to update the changelog - syndies in nuke need to move their shuttle to the station's zlevel first.
    • -
    • Bunch of other stuff.
    • -
    - -
    Sunday, November 21, 3:34 PST
    -
      -
    • Bug fixes, not going into detail. Lots and lots of bug fixes, mostly regarding the new map
    • -
    • CMO has a more obvious lab coat, that looks nicer than the original
    • -
    • CMO also has a stamp now
    • -
    • QM has a denied stamp
    • -
    • Cyborgs got tweaked. Laws only update when checked. Also have wires that can be toyed
    • - with for various effects, including AI sync, and law control -
    • Second construction site similar to the original
    • -
    • Prison station has been tweaked, now includes a lounge, and toilets
    • -
    • Detective's revolver starts with a reasonable number of bullets
    • -
    • Prison teleporter to the courtroom now exists
    • -
    • AI related stuff: More cameras, oh, and bug fixes!
    • -
    • Emergency storage moved
    • -
    • Random AI law changes. New law templates, and variables. Old variables were tweaked and some of the crappy templates were removed
    • -
    • Ghosts can teleport to the derelict now
    • -
    • Respriting of a bunch of stuff as well as graphical fixes
    • -
    • Kitchen is attached to the bar again
    • -
    • General map tweaks and fixes
    • -
    • Wardens fixed for rev rounds
    • -
    • 5-unit pills now work
    • -
    • APCs added and moved
    • -
    • Cola machine added. Contains various flavours of soda. Also added new snacks to the now named snack machine. Water cooler added, just apply an empty glass to it
    • -
    • Salt & Pepper have been added, as part of the food overhaul
    • -
    • More bug fixes. There was a lot
    • -
    - -
    Tuesday, November 16, 00:20 GMT
    -
      -
    • Cruazy Guest's map is now live.
    • -
    • Entire station has been rearranged.
    • -
    • Prison Station added, with Prison Shuttle to transport to and from.
    • -
    • New Job: Warden. Distributes security items.
    • -
    • The new map is still in testing, so please report any bugs or suggestions you have to the forums.
    • -
    • AI Liquid Dispensers, Codename SLIPPER, have been added to the AI core. They dispense cleaning foam twenty times each with a cooldown of ten seconds between uses. Mounted flashes have also been included.
    • -
    • Clown stamp added to clown's backpack.
    • -
    - -
    Sunday, November 14, 18:05
    -
      -
    • Major food/drink code overhaul. Food items heal for more but not instantly. Poison, Drug, and "Heat" effects from food items are also non-instant.
    • -
    • Preperation for one-way containers and condiments.
    • -
    • New Reagents: Nutriment, Ketchup, Soysauce, Salt, Pepper, Capsaicin Oil, Frost Oil, Amatoxin, Psilocybin, Sprinkles
    • -
    • New Food Item: Chaos Donut: 1 Hot Sauce + 1 Cold Sauce + 1 Flour + 1 Egg. Has a variable effect. NOT DEADLY (usually).
    • -
    • New Drug: Ethylredoxrazine: Carbon + Oxygen + Anti-Toxin. Binds strongly with Ethanol.
    • -
    • Tape Recorders added! Now you can actually PROVE someone said something!
    • -
    • Amospherics Overhaul Started: It actually works now. You can also build pipes and create function air and disposal systems!
    • -
    • Walls are now smooth.
    • -
    • Alcohol no longer gets you as wasted or for as long.
    • -
    • QM job split into QM and Cargo Technicians. QM has his own office.
    • -
    • Doors can no longer be disassembled unless powered down and unbolted.
    • -
    • New Job: Chief Medical Officer. Counts as a head of staff and is in charge of medbay. Has his/her own office and coat.
    • -
    • Wizarditis Bottle no longer in virus crate.
    • -
    - -
    Friday, November 5, 19:29
    -
      -
    • The ban appeals URL can now be set in config.txt
    • -
    • Secret mode default probabilities in config.txt made sane
    • -
    • Admin send-to-thunderdome command fixed to no longer send people to the other team's spawn.
    • -
    • Having another disease no longer makes you immune to facehuggers.
    • -
    • Magboots are now available from EVA.
    • -
    • Changeling death timer shortened. Destroying the changeling's body no longer stops the death timer.
    • -
    • Cult mode fixes.
    • -
    • Fixed cyborgs pressing Cancel when choosing AIs.
    • -
    • The play MIDIs setting now carries over when ghosting.
    • -
    • Admins can now see if a cyborg is emagged via the player panel.
    • -
    • PAPERWORK UPDATE v1: Supply crates contain manifest slips, in a later update these will be returnable for supply points. -
    • The Supply Ordering Console (Request computer in the QM lobby) can now print requisition forms for ordering crates. In conjunction with the rubber stamps, these can be used to demonstrate proper authorisation for supply orders.
    • -
    • Rubber stamps now spawn for each head of staff.
    • -
    • The use of DNA Injectors and fueltank detonations are now admin-logged.
    • -
    • Removed old debug code from gib()
    • -
    - -
    Tuesday, November 2, 19:11(GMT)
    -
      -
    • Finished work on the "cult" gamemode. I'll still add features to it later, but it is safe to be put on secret rotation now.
    • -
    • Added an energy cutlass and made a pirate version of the space suit in preparation for a later nuke update.
    • -
    • Changeling now ends 15 minutes after changeling death, unless he's ressurected.
    • -
    • Further fixing of wizarditis teleporting into space.
    • -
    • Fixed the wise beard sprite.
    • -
    • Fixed missing sprite for monkeyburgers.
    • -
    • Fixed Beepsky automatically adding 2 treason points to EVERYONE.
    • - -
    - -
    Thursday, October 28, 19:30(GMT)
    -
      -
    • Sleepers and disposals now require two seconds to climb inside
    • - -
    • Hydroponics crate ordered in QMs doesnt spawn too many items
    • -
    • Replacement lights crate can be ordered in QM.
    • -
    • Added space cleaner and hand labeler to Virology.
    • -
    • Welder fuel tanks now explode when you try to refuel a lit welder.
    • -
    • Made clown's mask work as a gas mask.
    • -
    • 9 new cocktails: Irish Coffee, B-52, Margarita, Long Island Iced Tea, Whiskey Soda, Black Russian, Manhattan, Vodka and Tonic, Gin Fizz. Refer to the wiki for the recipes.
    • -
    • Kitchen update: -
        -
      • -New Microwave Recipies: Carrot Cake (3 Flour, 3 egg, 1 milk, 1 Carrot), Soylen Viridians (3 flour, 1 soybeans), Eggplant Parmigania (2 cheese, 1 eggplant), and Jelly Donuts (1 flour, 1 egg, 1 Berry Jam), Regular Cake (3 flour, 3 egg, 1 milk), Cheese Cake (3 flour, 3 egg, 1 milk), Meat Pies (1 meat of any kind, 2 flour), Wing Fang Chu (1 soysauce, 1 xeno meat), and Human and Monkey Kabob (2 human or monkey meat, metal rods).
      • -
      • - Ingredients from Processor: Soysauce, Coldsauce, Soylent Green, Berry Jam.
      • -
      • - Sink added to kitchen to clean all the inevitable blood stains and as preperation for future cooking changes.
      • -
      • - The food processor can't be abused to make tons of food now.
      • - -
      -
    • Multiple tweaks to virology and diseases: -
        -
      • - Added wizarditis disease.
      • -
      • - Spaceacillin no longer heals all viruses.
      • -
      • - Some diseases must be cured with two or more chemicals simultaneously.
      • -
      • - New Virology design including an airlock and quarantine chambers.
      • -
      • - Made vaccine bottles contain 3 portions of vaccine.
      • -
      • - Lots of minor bug fixes.
      • - -
      - -
    - -
    Monday, October 18, 06:24(GMT)
    -
      -
    • Added virology profession with a cosy lab in northwestern part of medbay.
    • -
    • Virology related things, like taking blood samples, making vaccines, splashing contagious blood all over the station and so on.
    • -
    • Added one pathetic disease.
    • -
    • Virus crates are now available from the quartermasters for 20 points.
    • -
    • The DNA console bug (issue #40) was fixed, but I still made the DNA pod to lock itself while mutating someone.
    • -
    • Added icons for unpowered CheMaster and Pandemic computers
    • -
    • Added some sign decals. The icons were already there, but unused for reasons unknown.
    • -
    • Some map-related changes.
    • -
    - -
    Wednesday, October 13, 14:12(GMT)
    -
      -
    • Crawling through vents (alien) now takes time. The farther destination vent is, the more time it takes.
    • -
    • Cryo cell healing ability depends on wound severity. Grave wounds will heal slower. Use proper chemicals to speed up the process.
    • -
    • Added sink to the medbay.
    • -
    • Bugfixes: -
        -
      • - Some reagents were not metabolized, remaining in mob indefinitely (this includes Space Cola, Cryoxadone and cocktails Kahlua, Irish Cream and The Manly Dorf).
      • -
      • - Fixed placement bug with container contents window. Also, utility belt window now doesn't obscure view.
      • -
      -
    • -
    - -
    Sunday, October 10, 14:25(GMT)
    -
      -
    • Scrubbers in the area can be controlled by air alarms. Air alarm interface must be unlocked with an ID card (minimum access level - atmospheric technician), usable only by humans and AI. Panic syphon drains the air from affected room (simple syphoning does too, but much slower).
    • -
    • Sleeper consoles inject soporific and track the amounts of rejuvination chemicals and sleep toxins in occupants bloodstream.
    • -
    • Flashlights can be used to check if mob is dead, blind or has certain superpower. Aim for the eyes.
    • -
    • Radiation collectors and collector controls can be moved. Secured\unsecured with a wrench.
    • -
    • Air sensors report nitrogen and carbon dioxide in air composition(if set to).
    • -
    • Air Control console in Toxins.
    • -
    • Additional DNA console in genetics
    • -
    • Enough equipment to build another singularity engine can be found in engineering secure storage
    • -
    • Air scrubber, vent and air alarm added to library
    • -
    • Air alarm added to brig
    • -
    • Air scrubbers in Toxins turned on, set to filter toxins
    • -
    • Empty tanks, portable air pumps and similar can be filled with air in Aft Primary Hallway, just connect them to the port. Target pressure is set by Mixed Air Supply console in Atmospherics (defaults to 4000kPa).
    • -
    - -
    Wednesday, October 6, 18:36
    -
      -
    • Fixed the Librarian's suit - its worn iconstate wasn't set.
    • -
    • Fixed some typos.
    • -
    • Monkey crates are now available from the quartermasters for 20 points.
    • -
    • Corpse props removed from zlevel 8 as they were causing issues with admin tools and the communications intercept.
    • -
    • Cleaned up the default config.txt
    • -
    • Added a readme.txt with installation instructions.
    • -
    • Changed the ban appeals link to point to our forums for now - this'll be a config file setting soon.
    • -
    - -
    Tuesday, October 5, 01:41
    -
      -
    • Fixes to various nonworking cocktails.
    • -
    • More map and runtime error fixes.
    • -
    • Nuke operative headsets should be on an unreachable frequency like department headsets.
    • -
    • Another AI Malfunction change: Now once the AI thinks enough APCs have been hacked, it must press a button to start the timer, which alerts the station to its treachery.
    • -
    • Blob reskinned to magma and increased in power.
    • -
    • The HoS now has an armored greatcoat instead of a regular armor vest.
    • -
    • Admin logs now show who killswitched a cyborg.
    • -
    • The roboticist terminal now lets you see which AI a cyborg is linked to.
    • -
    • Malf AIs are no longer treated as inactive for the purpose of law updates and cyborg sync while hacking APCs.
    • -
    • Traitor AIs are now affected by Reset/Purge/Asimov modules, except law 0.
    • -
    • AI core construction sprites updated.
    • -
    • Securitrons removed from the Thunderdome.
    • -
    • An APC now supplies power to the bomb testing area, and has external cabling to supply it in turn.
    • -
    • A new variant freeform module has been added to the AI Upload room.
    • -
    • The changeling's neurotoxic dart has been made more powerful - this will likely be an optional upgrade from a set of choices, akin to wizard spells.
    • -
    • Some gimmick clothes moved to a different object path.
    • -
    • The chameleon jumpsuit should now be more useful - it includes job-specific jumpsuits as well as flat colours.
    • -
    - -
    Wednesday, September 29, 15:40
    -
      -
    • Bartender update! Bartender now has a Booze-O-Mat vending machine dispensing spirits and glasses, which he can use to mix cocktails. Recipes for cocktails are available on the wiki.
    • -
    • The barman also now has a shotgun hidden under a table in the bar. He spawns with beanbag shells and blanks. Lethal ammo is obtainable from hacked autolathes.
    • -
    • Dead AIs can once more be intelicarded, however in order to be restored to functionality they must be repaired using a machine in the RD office.
    • -
    • Silicon-based lifeforms have metal gibs and motor oil instead of blood.
    • -
    • Aliens now have a death message.
    • -
    • Intelicarded AIs can now have their ability to interact with things within their view range reactivated by the person carrying the card.
    • -
    • New AI cores can be constructed from victimsvolunteers.
    • -
    • Verbs tweaked.
    • -
    • Intelicarded AIs can be deleted.
    • -
    • RD office redesigned, and the RD now spawns there.
    • -
    • The AI can now choose to destroy the station on winning a Malf round.
    • -
    • General bugfixes to AIs, constructed AIs and decoy AIs.
    • -
    • Hats no longer prevent choking.
    • -
    • Some extra gimmick costumes are now adminspawnable.
    • -
    • AI health is now displayed on their status tab.
    • -
    • AI upload module now requires you to select which AI to upload laws to in case of multiple AIs.
    • -
    • Cyborgs now choose an AI to sync laws with upon creation.
    • -
    • Law office redesigned.
    • -
    • Roboticists no longer have Engineering access.
    • -
    • More fixes to areas which had infinite power due to having no assosciated APC.
    • -
    • Meatbread slices are no longer infinite.
    • -
    • Malf rounds no longer end if a non-malfunctioning AI is killed.
    • -
    • Cigarettes now have directional sprites.
    • -
    • AI Core circuitboard spawns in the RD office.
    • -
    • AI Satellite now has cameras and properly-wired SMES batteries.
    • -
    • Decoy AIs can no longer be moved.
    • -
    • Several runtime errors have been fixed.
    • -
    • Nuke rounds will now end properly on a station or neutral victory.
    • -
    • Riot shields have been nerfed and are now only available in the armory and in riot crates.
    • -
    • Foam dart crossbows, cap guns and caps can now be won as arcade prizes.
    • -
    • AI Malfunction has been redesigned - the AI must now hack APCs in order to win. More APCs hacked makes the timer tick faster.
    • -
    • Hydroponics now has a MULEbot station.
    • -
    • Changeling mode has been added to the game and is now in testing.
    • -
    • Electrified airlocks should now only zap you once if you bump into them while running.
    • -
    • Chemistry and Toxins access has been removed from Botanists.
    • -
    • General bugfixes and map tweaks.
    • -
    - -
    Sunday, September 26, 17:51
    -
      -
    • Riot shields! One in every security closet, and a few in armory. Also orderable from QM.
    • -
    - -
    Tuesday, September 21, 17:51
    -
      -
    • New experimental UI for humans by Skie. Voice out if it has problems or you don't like it.
    • - ---> YOU CAN CHOOSE UI FROM PREFERENCES <--- -
    • Hydroponics: Now you can inject chemicals into plants with a syringe. Every reagent works differently.
    • -
    • Hydroponics: Added a small hoe for uprooting weeds safely. Botanists now have sissy aprons.
    • -
    • New random station/command names and verbs.
    • -
    • Dead AIs can no longer be intellicarded and the steal AI objective is now working.
    • -
    • Aliens now bleed when you hit them, as well as monkeys.
    • -
    • Hurt people and bodies leave blood behind if dragged around when they are lying. Sprites to be updated soon...
    • -
    • Fixed several run-time errors in the code. Also food doesn't deal damage anylonger in some cases.
    • -
    • Blobs and alien weeds slowed down some. Plant-b-gone buffed some.
    • -
    • Fixed monkeys and aliens not being able to deal damage to humans with items.
    • -
    • Monkeys now slip on wet floor.
    • -
    - -
    Friday, September 17, 23:03
    -
      -
    • The Lawyer now starts in his snazzy new office.
    • -
    • Law Office accesslevel added. Currently, the Lawyer and the HoP begin with this.
    • -
    • Robotics access can now be added or removed from the HoP's computer.
    • -
    • Robotics, the captain's quarters, the cargo lobby and the staff heads office now have APCs and can lose power like the rest of the station.
    • -
    • Toxins mixing room is now a separate area for power and fire alarm purposes, as it already had its own APC.
    • -
    - -
    Thursday, September 16, 20:11
    -
      -
    • Added the Lawyer job.
    • -
    • Doors can now be constructed and deconstructed. This is being playtested, expect the specifics to change.
    • -
    • Fixed certain jobs which were supposed to have stuff spawning in their backpack that just wasn't getting spawned.
    • -
    - -
    Monday, September 13, 13:30
    -
      -
    • Bunch of new announcer sounds added
    • -
    • Minor lag fix implementation in the pipe system
    • -
    • You can now hear ghosts... sometimes
    • -
    • Seed bags and nutrients can now be pocketed
    • -
    - -
    Monday, September 12, 12:48
    -
      -
    • New kitchen stuff: New recipes (Meatbread, Cheese, Omelette Du Fromage, Muffins), new chef's knife and trays (Spawn in the meat locker) and milk (spawns in the fridge). Recipes are as follows: - -Cheese: milk on food processor - -Cheese wedge: Slice the cheese wheel with the chef's knife - -Omelette Du Fromage: 2 eggs 2 cheese wedges - -Muffin: 2 eggs 1 flour 1 carton of milk - -Meatbread: 3 meats (whatever meats) 3 flour 3 cheese. Can be sliced. - Cheese_amount is actually displayed on the microwave.
    • -
    • Profession-special radio channels now have color.
    • -
    • AI card not stupidly lethal anymore, for anyone that didn't notice
    • -
    • HYDROPONICS OVERHAUL, credit goes to Skie and Numbers. Wood doesn't have the entity so the tower caps cannot be harvested. For now.
    • -
    • Bar is now barman-only, access-wise. No more shall the entire station trump inside the bar and choke the monkey.
    • -
    • Prepping ground for Barman update (SPRITE ME SOME GODDAMN BOTTLES)
    • -
    -
    Thursday, September 2, 22:45
    -
      -
    • Ghosts can no longer release the singularity.
    • -
    • Sprites added in preparation for a Hydroponics update
    • -
    • A decoy AI now spawns in the AI core during Malfunction rounds to reduce metagaming.
    • -
    • libmysql.dll added to distribution.
    • -
    • Aircode options restored to default configuration.
    • -
    • AIs properly enter powerloss mode if the APC in their area loses equipment power.
    • -
    • Hydroponics crates added to Hydroponics, containing Weed-B-Gone
    • -
    • Airlock electrification now actually works properly.
    • -
    • Karma database error message updated.
    • -
    • Cyborgs choosing the standard module no longer become invisible except for a pair of glowing red eyes.
    • -
    • Aliens now have a hivemind channel, accessed like departmental radio channels or robot talk with ':a'.
    • -
    • Full donut boxes no longer eat whatever item is used on them and disappear.
    • -
    -
    Monday, August 30, 16:24
    -
      -
    • PDA user interface has been given a graphical overhaul. Please report any problems with it on the issue tracker.
    • -
    • Personal lockers are once again available in the lockerroom
    • -
    • BUGFIX: Xenoburger iconstate was accidentally removed in an earlier revision. This has been fixed.
    • -
    • Some of the default messages have been changed.
    • -
    • Additional sprites added for plants and weeds in preparation for an expansion of Hydroponics.
    • -
    • A schema script is now available for setting up the SQL database.
    • -
    - -
    Sunday, August 29, 05:09
    -
      -
    • The Robotics Crate no longer exists. Quartermasters can now order a MULEbot crate for 20 points, or a Robotics Assembly crate for 10 points. The latter provides 4 flashes, 3 proximity sensors, two 10k charge power cells and an electrical toolbox, and requires a roboticist or a head of staff to open.
    • -
    • Traitor AIs no longer lose their Law 0 in the event of power loss.
    • -
    • Administrators can now toggle the availiabilty of their right-click verbs to prevent accidental usage while playing.
    • -
    • Tool Storage vending machine is now a proper object. (code cleanup)
    • -
    • Buckets are now available from autolathes.
    • -
    • Four generic remote signaller PDA cartridges are now stocked in the Tool Storage vending machine.
    • -
    • AI status display density adjusted.
    • -
    - -
    Thursday, August 26, 21:07
    -
      -
    • Open Source Release Thanks to Mport for releasable singularity code.
    • -
    • Cyborgs redone Thanks again to Mport for this, cyborgs are totally different now.
    • -
    • Engine Monitor PDA app is now Power Monitor PDA app, and actually works.
    • -
    • AI State Laws verb now allows the AI to choose which laws to state, in case of traitor AIs or laws ordering it not to state them. Hopefully this will cut down on 'OMG THE AI IS COPYING AND PASTING' metagaming.
    • -
    • Power Monitor circuitboard isn't mislabeled as Mass Driver Control any more.
    • -
    • Traitor and Rev-head clowns lose the clumsiness gene - this should make trying to flash people in Rev mode less of an exercise in frustration.
    • -
    • A sink has been added to the Fitness room - this lets you wash dirty and bloodstained clothing and equipment.
    • -
    • Blast doors and firedoors no longer open by just bumping into them.
    • -
    • The bar and kitchen now open onto the same seating area. The old cafeteria area is now used as a lockerroom to replace the old one which was displaced by Hydroponics.
    • -
    • The bar now has a space piano with which you can entertain and annoy the crew.
    • -
    • LIBRARY A library has been added to the station in the escape arm in order to educate the crew. The new Librarian job is available to manage it. Crewmembers can request and read books, or write and bind their own books for upload to a persistent database.
    • -
    • The supply of flashbangs available from Security has been reduced to cut down on people constantly flashbanging the escape shuttle.
    • -
    • InteliCards are available in various locations to allow the retrieval of valuable AI personality data in the event of catastrophic station damage.
    • -
    - -
    Friday, August 06, 20:32
    -
      -
    • Hydroponics/Botany Added Credit goes to Skie and the folks over at the independent opensource SS13 branch, this is their code. It's lacking a lot, but it's a great start!
    • -
    • Way more tweaks than I can remember. Shouldn't wait so long between changelog updates.
    • -
    -
    Tuesday, July 13, 22:35
    -
      -
    • Singularity Engine Added Oh God we're all going to die (All credit on this one goes to Mport2004)
    • -
    • 'Purge' AI module added - purges ALL laws (except for law 0). Will probably change this to a Syndicate only item
    • -
    • Cyborgs now spawn with a power cell. Should prevent stupid cyborg deaths (and also pave the way for starting as a cyborg once more bugs are fixed)
    • -
    -
    Saturday, July 10, 15:10
    -
      -
    • Examining a player will now tell you if their client has disconnected.
    • -
    • Examining a brain will now tell you if it's owner is still connected to the game.
    • -
    • Alien Queens can make facehuggers. Facehuggers can make larva. Larva can grow into xenos! Xenos can become queens! The circle of life~
    • -
    • Some powernet bug fixes: Bad list and division by zero.
    • -
    -
    Friday, July 09, 05:16
    -
      -
    • Tweaked crate costs for Quartermaster.
    • -
    • Increased metal available in Robotics.
    • -
    • Added department-specific headsets. Engineering, Medical, Command, and Security all receive special headsets capable of broadcasting on a standard frequency PLUS a secure frequency only available to headsets of the same type. Precede say messages with ":h" to use.
    • -
    - -
    Tuesday, July 06, 19:16
    -
      -
    • Prayer command added.
    • -
    • State Laws command for AI added.
    • -
    • Disabled Lockdown command for AI. Too server heavy.
    • -
    • Crew manifest and various station databases should properly update when late arrivals join the game, now.
    • -
    • Quartermasters will receive 10 points every five minutes. This will probably be nerfed heavily, but we'll give it a shot anyhow.
    • -
    • Fixed a bug with doors/airlocks. (Thanks Mport2004)
    • -
    - -
    Sunday, April 25, 18:53
    - -
  • - New graphics: -
      -
    • - Side Facing Sprites: Player sprites will now face in all directions when moving. Holy shit! -
    • -
    -
  • - -
    Monday 2.0, April 19, 2100
    -
      -
    • - New features: -
        -
      • - Disposal System: The station now has a fully functional disposal system for throwing away nuclear authentication disks and old, dirty clowns. -
      • -
      • - Breakable Windows: Windows are breakable by projectiles and thrown items (including people), shards hurt your feet. -
      • -
      • - Status Display: Station escape shuttle timers now function as status displays modifiable from the bridge. -
      • -
      • - Space Heater: Space heaters for heating up cold spaces, in space. -
      -
    • -
    • - New items: -
        -
      • - Welding Mask: Helps engineers shield their eyes when welding. -
      • -
      • - Utility Belt: Function as toolboxes equippable in the belt slot. -
      • -
      • - Mouse Trap: Hurt your feet, especially if you aren't wearing shoes! -
      • -
      • - Power Sink: Traitor item that rapidly drains power. -
      • -
      -
    • -
    • - New graphics: -
        -
      • - North Facing Sprites: Player sprites will now face north when moving north. -
      • -
      • - Hidden Pipes: Pipes are now hidden underneath floor tiles. -
      • -
      -
    • -
    • - New robot: Medibot -
        -
      • - Automatically attempts to keep crewmembers alive by injecting them with stuff. -
      • -
      -
    • -
    • - New robot: Mulebot -
        -
      • - Allows quartermasters to automatically ship crates to different parts of the station. -
      • -
      -
    • -
    - -
    Funday, December 31, 2099
    -

    "FINALLY, DEV IS OUT"

    -
      -
    • - Changes: -
        -
      • - Atmos system GREATLY OPTIMIZED! -
      • -
      • - Brand new station layout! -
      • -
      • - Robust chemical interaction system! -
      • -
      • - HOLY FUCK PLAYING THIS GAME ISN'T LIKE TRODDING THROUGH MOLASSES ANYMORE -
      • -
      • - Feature: If two players collide with "Help" intent, they swap positions. -
      • -
      -
    • -
    - -
    Tuesday, February 23, 2010
    -
      -
    • - OH NO STRANGLING GOT NERFED: Insta-strangling (hopefully) removed. Victim no longer instantly loses consciousness. -
    • -
    - -
    Sunday, February 21, 2010
    -
      -
    • - Cloning Machine: The Geneticist spilled coffee on the Genetics Machine's revival module and it was too costly to replace! -
        -
      • - Clones may or may not have horrible genetic defects. -
      • -
      -
    • -
    - -
    Thursday, February 18, 2010
    -
      -
    • - New feature: Obesity from overeating in a short period of time. -
    • -
    - -
    Sunday, February 14, 2010
    -
      -
    • - New feature: Station destruction cinematic if the crew loses in AI Malfunction or Nuclear Emergency. -
    • -
    • - New Position: Tourist -
        -
      • - Centcom has entered the lucrative business of space tourism! Enjoy an event-filled vacation on the station, and try not to get killed. -
      • -
      • - Guest accounts are now restricted to selecting Tourist in Character Setup. -
      • -
      -
    • -
    - -
    Friday, February 5, 2010
    -
      -
    • - AI: Added 30 second cooldown to prevent spamming lockdowns. -
    • -
    - -
    Wednesday, February 2, 2010
    -
      -
    • - Feature: Character preview in Character Setup! -
    • -
    - -
    Tuesday, February 2, 2010
    -
      -
    • - New item: Drinking glasses that you can fill with water. -
    • -
    • - Feature: Sounds now pan in stereo depending on your position from the source. -
    • -
    - -
    Saturday, December 5, 2009
    -
      -
    • - Traitor tweak: Agent cards can now be forged into a fake ID. -
    • -
    - -
    Friday, December 4, 2009
    -
      -
    • - Supply Dock 2.0: The Supply Dock has been redesigned and now features conveyer belts! Amazing! -
    • -
    • - New uniforms: The Research Director, Chief Engineer, and the research jobs have new uniforms. The Head of Security has a cool new hat which happens to be his most prized possession. -
    • -
    • - Merged research: The first act of the Research Director is to merge Toxins and Chemistry into a single Chemical Lab. Hooray! -
    • -
    • - Robot tweak: You can now observe robots using the observe command. -
    • -
    • - Stamps: The heads now have stamps to stamp papers with, for whatever reason. -
    • -
    - -
    Monday, November 30, 2009
    -
      -
    • - Supply Shuttle 1.0: Now you can order new supplies using Cargo Bay north of the autolathe. -
    • -
    • - New containers: The game now features a variety of crates to hold all sorts of imaginary space supplies. -
    • -
    • - New position: Quartermaster -
        -
      • - A master of supplies. Manages the cargo bay by taking shipments and distributing them to the crew. -
      • -
      -
    • -
    • - New position: Research Director -
        -
      • - The head of the SS13 research department. He directs research and makes sure that the research crew are working. -
      • -
      -
    • -
    • - New position: Chief Engineer -
        -
      • - Boss of all the engineers. Makes sure the engine is loaded and that the station has the necessary amount of power to run. -
      • -
      -
    • -
    • - New robot: Securibot -
        -
      • - Automatically stuns and handcuffs criminals listed in the security records. It's also really goddamn slow. -
      • -
      -
    • -
    • - New jumpsuits: Engineers and Atmos Techs have new jumpsuits to distinguish between them easier. -
    • -
    - -
    Friday, November 27, 2009
    -
      -
    • - Monkey AI 2.0: Monkeys will now get angry, going after random human targets with the ability to wield weapons, throw random objects, open doors, and break through glass/grilles. They're basically terminators. -
    • -
    • - New gamemode: Monkey Survival -
        -
      • - Survive a horde of angry monkeys busting through the station's airvents and rampaging through the station for 25 minutes. -
      • -
      -
    • -
    • - New robots: Cleanbot and Floorbot -
        -
      • - Cleanbots automatically clean up messes and Floorbots repair floors. -
      • -
      -
    • -
    • - New spell: Mindblast -
        -
      • - Causes brain damage, progressively causing other players to become even more stupid. -
      • -
      -
    • -
    • - Alien Races -
        -
      • - Wizards may randomly spawn as illithids, who gain Mind Blast for free, and nuke agents may randomly spawn as lizardmen. -
      • -
      -
    • -
    • - Station shields: The station now has a toggleable forcefield that can only be destroyed by meteors or bombs. Takes a lot of station power to use. -
    • -
    • - Traitor scaling: Number of traitors/wizards/agents now scales to number of players. -
    • -
    • - New food item: Donk pockets -
        -
      • - Delicious and microwavable, gives a bigger health boost for traitors. -
      • -
      -
    • -
    • - Cigarettes: Now you can fulfill your horrible nicotine cravings. The detective starts with a zippo lighter and pack of cigarettes. Other packs can be be obtained via vending machines. -
    • -
    • - Warning signs: The station is now filled with various warning signs and such. -
    • -
    • - Updated graphics: Many, many objects have had their graphics updated including pipes, windows, tables, and closets. HUD graphics have been updated to be easier to understand. -
    • -
    • - Lighting fixes: New turf is now correctly lit instead of being completely dark. -
    • -
    • - Meteor fixes: The code and graphics for meteors has been fixed so the meteor gametype is more playable, sort of. -
    • -
    • - Escape shuttle fix: The shuttle can now be called in Revolution and Malfunction, but the shuttle will be recalled before it arrives. This way players can no longer call the shuttle to figure out the game mode during secret. -
    • -
    • - Changelog updated: New changelog entry for Thanksgiving thanks to Haruhi who will probably update the changelog from now on after almost a month of neglect. -
    • -
    - -
    Monday, November 3, 2009
    -
      -
    • - Bug fix: Made most pop-up windows respect the close button. -
    • -
    - -
    Sunday, October 25, 2009
    -
      -
    • - Randomized naming: Names for Central Command and Syndicate are now randomized. -
    • -
    - -
    Saturday, October 24, 2009
    -
      -
    • - Bug fix: PDAs had their code cleaned up. Notice any problems? Report them. -
    • -
    • - New syndicate item: Detomatix Cartridge, allows remote detonation of PDAs (rather weak explosion)! -
    • -
    • - Feature: Remotely detonating PDAs has a chance of failure depending on the PDA target, a critical failure will result in the detonation of your own PDA. -
    • -
    - -
    Monday, October 19, 2009
    -
      -
    • - Gibbing update: Gibbing stuff has been rewritten, robots now gib nicer. -
    • -
    • - LIGHTING!!!: The station now has dynamic lighting and associated items. -
    • -
    - -
    Friday, October 16, 2009
    -
      -
    • - Poo v1.0~: This has caused many ragequits. -
    • -
    • - Flushable toilets: You can now use toilets to place your vile, disgusting and irreprehensible excretions (you disgusting children). Just be careful what you flush! -
    • -
    -
    Monday, October 12, 2009
    -
      -
    • - Feature: Emergency oxygen bottles can be clipped to your belt now. -
    • -
    • - Clothing update: Bedsheets are now wearable. -
    • -
    • - Updated HUD: A few minor tweaks to the inventory panel. Things might not be exactly where you're used to them being. -
    • -
    -
    Monday, September 28, 2009
    -
      -
    • - New position: Chef -
        -
      • - Maintains the Cafeteria, has access to Kitchen and Freezer, Food creation will be in shortly. -
      • -
      -
    • -
    • - Food update: Food items now heal Brute/Burn damage. The amount recovered varies between items. -
    • -
    -
    Saturday, August 29, 2009
    -
      -
    • - AI laws update: Nanotrasen has updated its AI laws to better reflect how they wish AIs to - operate their stations. -
    • -
    • - Traitor item change: E-mag renamed to Cryptographic Sequencer. -
    • -
    - -
    Friday, July 31, 2009
    -
      -
    • I&#39;m really sorry everyone I just HAD to add a gib all verb.
    • -
    • Decided to add the creation of bombs to bombers list
    • -
    • Made the new bombing list EVEN BETTER!!!
    • -
    • Fixed a bug with admin jumping AND the traitor death message
    • -
    • Oops, fixed a bug that returned the right click pm thing thinking the admin was - muted.
    • -
    • Made a new improved way of tracking who bombs shit.
    • -
    • More formatting shit.
    • -
    • Fixed up some mute code and made it so that if a player is muted they cannot PM - us.
    • -
    • Adminhelps now logged in the admin file not ooc
    • -
    • Changed the way admin reviving is dealt with. (It was coded kind of weirdly - before)
    • -
    • Added a few areas to the observe teleport. Fixed some adminjump things. Modified - the paths of some areas.
    • -
    • You can now ban people who have logged out and admins can now jump to people - using the player panel.
    • -
    • Added in jump to key coded in a much better way than showtime originally did it.
    • -
    • Fixed magical wind when laying pipes. They start out empty!!
    • -
    • Made blink safer. Fixed the crew-quarters to ai sattelite teleport problem.
    • -
    • Forgot the message again. Added an emp spell. thanks copy&amp;paste.
    • -
    • OH MY GOD I HAVE RUINED ASAY
    • -
    • Added electronic items to the pipe dispenser
    • -
    • fixed a formatting error with the changelog (I didn&#39;t break it, it was showtime)
    • -
    • Fixed a formatting error
    • -
    • Cleaned up sandbox object spawn code
    • -
    • New and improved admin log so we can keep an eye on these fuckers
    • -
    • Fixed adminjump because I realise most people use it for the right click option
    • -
    • Mushed together jump to mob and jump to key
    • -
    • Fixed a compilation error and made my test room more secure!
    • -
    - -
    Wednesday, July 29th, 2009
    - -

    These are a collection of the updates from the last 6 days. I promise to update - the changelog once a week. Note that this does not include all the changes in - the past 6 days.

    - -
      -
    • Multitools can now be used to measure the power in cables.
    • -
    • Fixed a bug where the canister message would repeat and spam the user when - attackby analyzer. Fixed an admin formatting error.
    • -
    • Replaced all range checks with a in_range proc. pretty good chance I broke - something or everything.
    • -
    • Mutations use bitfields
    • -
    • Fixed a bug with my traitor panel.
    • -
    • Fixed the turrets, ruined Pantaloons map (test map). Did some things with - turrets and added a few areas.
    • -
    • Some stuff in here you know the usual shit. Bugfixes, formatting etc.
    • -
    • Stunbaton nerf.
    • -
    • Tempban longer than 1 year -&gt; permaban.
    • -
    • Turfs &gt; spawnable.
    • -
    • Shaking someone now slowly removes paralysis, stuns and the &#39;weakened&#39; stuff.
    • -
    • CTF flags now check if someone has them equipped every 20 seconds, if they are - not then they delete themselves and respawn.
    • -
    • Fixed the r-wall-welder-message-thing.
    • -
    • Change to the CTF code, flag captures can now only happen if your team has their - flag in the starting position.
    • -
    • Pruning my test room.
    • -
    • Instead of the red and green team its now the American and Irish teams!
    • -
    • BACKUP BACKUP TELL ME WHAT YOU GONNA DO NOW Changed the monkey name code. Re-did - my antimatter engine code so it actually puts out power now
    • -
    • dumb as fuck change, whoever did that, it already spawn ()&#39;s inside the proc - code, whoever did that, you are a fool and should read code before you modify - it
    • -
    • Fixed a bug that gave everyone modify ticker variables you silly sausage.
    • -
    • Sorted the AIs track list.
    • -
    • Constructable filter inlets and filter controls.
    • -
    • Added in admin messages for when someone is banned.
    • -
    • Bannana and honk honk.
    • -
    - -
    Saturday, June 27th, 2009
    - -
      -
    • Pipe construction now works completely. //Nannek
    • -
    • Many many other things that never gets recorded in the changelog!!
    • -
    - -
    Saturday, June 27th, 2009
    -
      -
    • The Michael Jackson Memorial Changelog Update
    • -
    • Pipe filters adjusted for more ideal environmentals //Pantaloons
    • -
    • Added in job tracking //Showtime
    • -
    • Crew Manifest and Security Records now automagically update when someone joins //Nannek
    • -
    • Fixed a bug where sometimes you get a screwdriver stuck in your hand //Pantaloons
    • -
    • Flamethrowers can now be disassembled //Pantaloons
    • -
    • OBJECTION! Added suits and briefcases //stuntwaffle
    • -
    • Added automatic brig lockers //Nannek
    • -
    • Added brig door control authorization and redid brig layout //Nannek
    • -
    • Emergency toolboxes now have radios and flashlights, and mechanical toolboxes now have crowbars //Pantaloons
    • -
    • New whisper system //lallander
    • -
    • Some more gay fixes //everybody
    • -
    • Some really cool fixes //everybody
    • -
    • Really boring code cleanup //Pantaloons
    • -
    • ~~In Loving Memory of MJ~~ Sham on!
    • -
    - -
    Friday, June 12th, 2009
    -
      -
    • Looking back through the SVN commit log, I spy...
    • -
    • Keelin doing some more performance enhancements
    • -
    • Fixed one person being all 3 revs at once (hopefully)
    • -
    • Some gay fixes
    • -
    • New admin system installed
    • -
    • Fixed a bug where mass drivers could be used to crash the server
    • -
    • Various pipe changes and fixes
    • -
    - -
    Wednesday, June 3rd, 2009
    -
      -
    • Death commando deathmatch mode added.
    • -
    - -
    Monday, June 1st, 2009
    -
      -
    • Ghosts can no longer wander from space into the dread blackness that lies beyond.
    • -
    • Those other losers probably did a bunch of other stuff since May 6th but they don't comment their revisions so fuck 'em.
    • -
    - - -
    Wednesday, May 6th, 2009
    -
      -
    • Crematorium
    • -
    • Goon? button makes all your dreams come true.
    • -
    • Restructured medbay
    • -
    -
    Monday, May 4th, 2009
    -
      -
    • Does anyone update this anymore?
    • -
    • New atmos computer promises to make atmos easier
    • -
    • Autolathe
    • -
    • Couple of map changes
    • -
    • Some computer code reorganised.
    • -
    • I'm pretty sure theres a couple things
    • -
    -
    Saturday, April 18th, 2009
    -
      -
    • Weld an open closet (only the normal kind), gayes.
    • -
    • Chaplin has a higher chance of hearing the dead.
    • -
    • New traitor objective
    • -
    • Power traitor objective removed
    • -
    • New job system implemented for latecomers.
    • -
    • Head of Research quits forever and ever, is replaced by Head of Security (who gets his own office)
    • -
    - -
    Fri, April 10, 2009
    -
      -
    • Admins are now notified when the traitor is dead.
    • -
    • Unprison verb (again, for admins).
    • -
    - -
    Wed&Thu, April 8&9, 2009
    -
      -
    • Medical redone, doctors do your jobs! (Tell me what you think of this - compared to the old one)
    • -
    • Clickable tracking for the AI
    • -
    • Only the heads can launch the shuttle early now. Or an emag.
    • -
    - -
    Mon&Tue, April 6&7, 2009
    -
      -
    • Sounds. Turn on your speakers & sound downloads.
    • -
    • Scan something with blood on it detective.
    • -
    - -
    Sunday, April 5, 2009
    -
      -
    • A large icon for the headset, no reason it should be so small.
    • -
    - -
    Saturday, April 4, 2009
    -
      -
    • Emergency closets now spawn an 'emergency gas mask' which are just recolored gas masks, no other difference other than making it obvious where the gas mask came from.
    • -
    - -
    Wednesday, April 1, 2009
    -
      -
    • Constructable rocket launchers: 10 rods, 10 metal, 5 thermite and heated plasma from the prototype.
    • -
    • Emergency closets have randomized contents now.
    • -
    • Fixed a bug where someone who was jobbaned from being Captain could still be picked randomly
    • -
    - -
    Friday, March 27, 2009
    -
      -
    • Fixed a bug where monkeys couldn't be stunned.
    • -
    • Change mode votes before game starts delays the game.
    • -
    - -
    Thursday, March 26, 2009
    -
      -
    • The brig is now pimped out with special new gadgets.
    • -
    • Upgraded the admin traitor menu.
    • -
    - -
    Tuesday, March 24, 2009
    -
      -
    • GALOSHES!
    • -
    • A certain item will now protect you from stun batons, tasers and stungloves when worn.
    • -
    - -
    Monday, March 23, 2009 (EXPERIMENTAL)
    -
      -
    • Say / radio / death talk systems recoded, hopefully improving it.
    • -
    • Announcements of late joiners are now done by the AI if it's alive :-)
    • -
    - -
    Monday, March 23, 2009
    -
      -
    • Random station names.
    • -
    • Changes to the message stylesheet.
    • -
    • Admin messages in OOC will now be colored red.
    • -
    - -
    Saturday, March 21, 2009
    -
      -
    • Added a command to list your medals.
    • -
    • ETA no longer shows when it doesn't matter.
    • -
    • Nerfed the ability to spam shuttle restabalization.
    • -
    • Fixed the 'Ow My Balls!' medal to only apply from brute damage rather than both brute and burn damage.
    • -
    - -
    Thursday, March 19, 2009
    -
      -
    • Job banning.
    • -
    • Genetic Researcher renamed to Geneticist.
    • -
    • Toxins Researcher renamed to Scientist.
    • -
    • Help reformatted.
    • -
    • Fixed a bug where combining bruise packs or ointments resulted in an incorrectly combined amount.
    • -
    • Renamed memory and add memory commands to Notes and Add Note.
    • -
    - -
    Tuesday, March 17, 2009
    -
      -
    • Medals! MEDALS!
    • -
    • Trimmed the excessively long changelog.
    • -
    - -
    Saturday, March 14, 2009
    -
      -
    • Janitor job complete! Report any bugs to adminhelp
    • -
    - -
    Saturday, March 7, 2009
    -
      -
    • Wizard now needs his staff for spells
    • -
    • Be careful with APCs now okay?!
    • -
    • Fixed Memory and made it more efficient in the code
    • -
    • Crowbars now open apcs, not screwdrivers. They do something else entirely
    • -
    • Hackable APCs
    • -
    • When APCs are emagged they now stay unlocked
    • -
    • Re-did a shit tonne of admin stuff
    • -
    • New admin system is pretty much finished
    • -
    • FINALLY backpacks can now be looked in while on the ground.
    • -
    - -
    Tuesday, February 24, 2009
    -
      -
    • Ghosts no longer able to open secret doors
    • -
    • Suicide vests now work as armor
    • -
    • Blood no longer comes out of the guy if you pull him due to lag
    • -
    • Admin panel has been touched up to include html tables
    • -
    • Mines now added, only spawnable right now however
    • -
    • Fixed the syndicate nuclear victory bug
    • -
    • Wizard now spawns with wizard outfit which he must wear to cast spells
    • -
    • Blood bug fixes
    • -
    • Fixed a dumb bug that meant I didn't have the power to kick admins
    • -
    • THUNDERDOME!
    • -
    • Several new facial hair options and a bitchin' mohawk
    • -
    • Blood by Culka
    • -
    • Nuke disk now spawns in ALL game modes so that during secret rounds the syndicate now have the element of surprise!
    • -
    - -
    Saturday, February 22, 2009
    -
      -
    • Implemented unstable's "observer" mode
    • -
    • Halerina's wizard mode
    • -
    • Non-interesting stuff
    • -
    • Began addition to the new admin system - right now only available to coders for testing
    • -
    • Admins can now click on the multikeying offenders name to pm them, instead of hunting for them in the pm list
    • -
    • Halerina's chemistry system
    • -
    • You can now deathgasp without being dead, hopefully so people can fake their own deaths.
    • -
    • Redid Medlab
    • -
    • New chemist job
    • -
    - -
    Thursday, February 19, 2009
    -
      -
    • New DNA system. 200th Revision special.
    • -
    • Various bugfixes
    • -
    • Maze
    • -
    - -
    Monday, February 17, 2009
    -
      -
    • Added a new game mode into rotation.
    • -
    • Added an AI satellite
    • -
    • Lockdowns can be disabled with the communications console
    • -
    • Prison shuttle can be called on the comm console, but only if its enabled by admins first
    • -
    • When you slip into space you'll have a 50% chance of going to z=4 instead of z=3
    • -
    - -
    Friday, February 13, 2009
    -
      -
    • Fixed Cakehat
    • -
    • Dead people can now see all turfs, mobs and objs not in their line of sight.
    • -
    • Modified the map slightly
    • -
    • Stungloves can now be "made"
    • -
    • Flashes can now have their bulbs burning out.
    • -
    • Batons can now be turned on and off for different effects. They also now have 10 uses before they need to be recharged.
    • -
    - -
    Tuesday, February 10, 2009
    -
      -
    • Fixed all the autoclose bugs
    • -
    • Due to it being myself and Keelin's 100th revision we have added a super-secret special item. Don't ask because we won't tell! Figure it out!
    • -
    - -
    Sunday, February 8, 2009
    -
      -
    • Modified doors in engineering so that they do not autoclose - Autoclose now handled by a variable
    • -
    • Fixed toxin researcher spawn bug
    • -
    • Changed the "You hear a faint voice" message.
    • -
    • Gave the host new commands to disable admin jumping, admin reviving and admin item spawning
    • -
    • Fixed some airlock autoclose bugs
    • -
    • Changed some doors to not autoclose.
    • -
    • Nerfed the toolbox down.
    • -
    - -
    Friday, February 6, 2009
    -
      -
    • Doors now close after 15 seconds
    • -
    • Fixed some p cool bugs
    • -
    • Cakehat
    • -
    • Added another suit
    • -
    • Walls now take 5 seconds to build
    • -
    • Added sam0rz, thesoldierlljk and kelson's revolution gamemode. Thanks guys!
    • -
    - -
    Thursday, February 5, 2009
    -
      -
    • Fixed a couple of bugs
    • -
    • Improved bar ;)
    • -
    • Beer acts like pills and syringes
    • -
    - -
    Tuesday, February 3, 2009
    -
      -
    • Added 'Make AI' Option for Admins
    • -
    • Added dissolving pills in beer (cyanide and sleeping pills)
    • -
    • Modified engine AGAIN, but personally I love it now
    • -
    - -
    Monday, February 2, 2009
    -
      -
    • Moved bar due to popular demand
    • -
    • Captains room is now a security checkpoint
    • -
    • Assistants now have access to maint tunnels again
    • -
    • Courtroom
    • -
    • Engine has been redone slightly to make it easier to load
    • -
    • Nerfed beer a lot more
    • -
    - -
    Saturday, January 31, 2009
    -
      -
    • Added a bartender job + Bar
    • -
    • Captains panic room
    • -
    • Voice changer traitor item
    • -
    • Bartender suit
    • -
    • Made taking a table apart take longer
    • -
    • Balanced beer a bit more.
    • -
    • Assistants can no longer open external air locks and maint tunnels, sorry guys. Get a job you bums.
    • -
    • Engineers CAN access external air locks and maint tunnels.
    • -
    • Fixed traitor AI bug
    • -
    - -
    Thursday, January 29, 2009
    -
      -
    • Added traitor menu for admins - The ability to turn people into "traitors" as well as keep track of their objectives.
    • -
    • Implemented Keelins revive system - Primary Admins can now revive people.
    • -
    • Moved and redid security to prevent clusterfucks and everyone just crowding around security.
    • -
    • Redid the brig to make it bigger and so that people can break others more easily out since it isn't right in security.
    • -
    • Moved and redid captains quarters/heads quarters. Captains made much smaller and heads is now more of a meeting room.
    • -
    • Added Stungloves and an axe - right now only admin spawnable.
    • -
    • Implemented Persh's adminjump back in - admins can now jump to set locations.
    • -
    • Added a feature that if someone logs off their character moves around and says things - Change what they say from the config/names/loggedsay.txt file.
    • -
    • Added in adminwho verb - tells the user if there are any admins on and who they are.
    • -
    - -
    Saturday, January 10, 2009
    -
      -
    • Freedom implant has been changed so that it will have a random emote associated with it to activate it rather than always chuckle.
    • -
    • There is now a pinpointer tool for use in Nuclear Emergency. It works similar to the existing locator, in that it will detect the presence of nuclear disks and in what direction it is.
    • -
    • The nuke being detonated in Nuclear Emergency should now properly end the game.
    • -
    • Spacesuits now cause you to move slower when not in space.
    • -
    • Syndicate in Nuclear Emergency now have syndicate-themed spacesuits.
    • -
    • Blob mode should properly end now.
    • -
    - -
    Wednesday, January 7, 2009
    -
      -
    • Syndicate Uplink has been changed up, allowing traitor more freedom in his ability to be... traitorus.
    • -
    • Syndicate Uplink can now spawn a ammo-357, syndicate card, energy sword, or timer bomb.
    • -
    • Fixed an issue where Syndicate Uplink looked different than a normal radio.
    • -
    - -
    Monday, January 5, 2009
    -
      -
    • You can choose to be a nudist now.
    • -
    • Facial hair!
    • -
    • Added constructable flamethrowers.
    • -
    • Redid internal naming scheme for human/uniform sprites.
    • -
    • Helmet visors are now translucent.
    • -
    • Held item graphics corrected for basically everything, internally only uses one dmi file instead of two.
    • -
    • Config settings reorganized for.. organization.
    • -
    • Seperated male and female names.
    • -
    • Females have pink underwear.
    • -
    • Guests can no longer save/load profiles, as this just created useless profiles that weren't used again.
    • -
    diff --git a/html/ban.png b/html/ban.png deleted file mode 100644 index 54f68f4770..0000000000 Binary files a/html/ban.png and /dev/null differ diff --git a/html/bug-minus.png b/html/bug-minus.png deleted file mode 100644 index 9934db406b..0000000000 Binary files a/html/bug-minus.png and /dev/null differ diff --git a/html/burn-exclamation.png b/html/burn-exclamation.png deleted file mode 100644 index b2a4f670a8..0000000000 Binary files a/html/burn-exclamation.png and /dev/null differ diff --git a/html/changelog.css b/html/changelog.css deleted file mode 100644 index da32a5a557..0000000000 --- a/html/changelog.css +++ /dev/null @@ -1,41 +0,0 @@ -.top{font-family:Tahoma,sans-serif;font-size:12px;} -h2{font-family:Tahoma,sans-serif;} -a img {border:none;} -.bgimages16 li { - padding:2px 10px 2px 30px; - background-position:6px center; - background-repeat:no-repeat; - border:1px solid #ddd; - border-left:4px solid #999; - margin-bottom:2px; -} -.bugfix {background-image:url(bug-minus.png)} -.wip {background-image:url(hard-hat-exclamation.png)} -.tweak {background-image:url(wrench-screwdriver.png)} -.soundadd {background-image:url(music-plus.png)} -.sounddel {background-image:url(music-minus.png)} -.rscdel {background-image:url(cross-circle.png)} -.rscadd {background-image:url(tick-circle.png)} -.imageadd {background-image:url(image-plus.png)} -.imagedel {background-image:url(image-minus.png)} -.spellcheck {background-image:url(spell-check.png)} -.experiment {background-image:url(burn-exclamation.png)} -.refactor {background-image:url(burn-exclamation.png)} -.code_imp {background-image:url(coding.png)} -.config {background-image:url(chrome-wrench.png)} -.admin {background-image:url(ban.png)} -.server {background-image:url(hard-hat-exclamation.png)} -.balance {background-image:url(scales.png)} -.sansserif {font-family:Tahoma,sans-serif;font-size:12px;} -.commit {margin-bottom:20px;font-size:100%;font-weight:normal;} -.changes {list-style:none;margin:5px 0;padding:0 0 0 25px;font-size:0.8em;} -.date {margin:10px 0;color:blue;border-bottom:2px solid #00f;width:60%;padding:2px 0;font-size:1em;font-weight:bold;} -.author {padding-left:10px;margin:0;font-weight:bold;font-size:0.9em;} -.drop {cursor:pointer;border:1px solid #999;display:inline;font-size:0.9em;padding:1px 20px 1px 5px;line-height:16px;} -.hidden {display:none;} -.indrop {margin:2px 0 0 0;clear:both;background:#fff;border:1px solid #ddd;padding:5px 10px;} -.indrop p {margin:0;font-size:0.8em;line-height:16px;margin:1px 0;} -.indrop img {margin-right:5px;vertical-align:middle;} -.closed {background:url(chevron-expand.png) right center no-repeat;} -.open {background:url(chevron.png) right center no-repeat;} -.lic {font-size:9px;} diff --git a/html/changelog.html b/html/changelog.html deleted file mode 100644 index e2aef333e1..0000000000 --- a/html/changelog.html +++ /dev/null @@ -1,546 +0,0 @@ - - - - Citadel Station 13 Changelog - - - - - - - -
    - - - - -
    -
    Traditional Games Space Station 13
    - -

    -
    - - - - - -
    - Thanks to: /tg/station, Baystation 12, /vg/station, NTstation, CDK Station devs, FacepunchStation, GoonStation devs, the original SpaceStation developers and Invisty for the title image.
    Also a thanks to anybody who has contributed.
    -
    Have a bug to report?
    Visit our Issue Tracker.
    - Please ensure that the bug has not already been reported, use the template provided here!. - Currently Active GitHub contributor list: -Click Here-
    -
    - - -
    - -

    20 August 2021

    -

    EmeraldSundisk updated:

    -
      -
    • Adds a law office/courtroom to OmegaStation
    • -
    • Adds a gateway to OmegaStation
    • -
    • Adds a pool/maintenance bar to OmegaStation
    • -
    • Removes the original maintenance garden in OmegaStation tweak: Relocates the bathrooms to the starboard hall tweak: Modifies port quarter maintenance to include some affected items
    • -
    -

    Putnam3145 updated:

    -
      -
    • Beach now has showers
    • -
    -

    TripleShades updated:

    -
      -
    • At least four or five space heaters spread across Pubby Station Maints
    • -
    • Missing decal in Pubby Station engineering
    • -
    • Moved an atmos alarm in the SM emitter chamber so it wont be destroyed
    • -
    -

    WanderingFox95 updated:

    -
      -
    • Empty bottles and pitchers are available to the bartender now.
    • -
    • They even come with 10 different fillstates!
    • -
    • Better Shark Tails, dodododododo~
    • -
    • The old ones are now listed as carp tails.
    • -
    - -

    18 August 2021

    -

    timothyteakettle updated:

    -
      -
    • lets you select 4 prosthetic limbs instead of only 2
    • -
    - -

    16 August 2021

    -

    BlueWildrose updated:

    -
      -
    • Incapacitated mobs are blacklisted from being human-level intelligence sentience event candidates. This is particularly important due to slimes in BZ stasis on the station.
    • -
    -

    bunny232 updated:

    -
      -
    • Polyvitiligo actually changes your color now
    • -
    - -

    13 August 2021

    -

    Putnam3145 updated:

    -
      -
    • makes certain organs no longer have circular references
    • -
    - -

    12 August 2021

    -

    Arturlang updated:

    -
      -
    • Nonslimes and nonvampires will no longer be able to increase their blood to stupid heights
    • -
    -

    Putnam3145 updated:

    -
      -
    • Supermatter values use auxgm
    • -
    -

    cadyn updated:

    -
      -
    • precompile.sh and build.sh updated, auxmos set to 0.2.3 in dependencies.sh
    • -
    - -

    11 August 2021

    -

    timothyteakettle updated:

    -
      -
    • lets felinids, humans and moths have markings
    • -
    - -

    09 August 2021

    -

    Arturlang updated:

    -
      -
    • Nanite machinery overlays should now work properly
    • -
    • screen objects are now atom/movables instead
    • -
    • Update appearance is used for updating atoms now instead of update_icon and such
    • -
    -

    BlueWildrose updated:

    -
      -
    • Old gateway animation is back. Feedback is given that the gateway is open again.
    • -
    -

    Putnam3145 updated:

    -
      -
    • Rod of asclepius can now be used for revival surgery
    • -
    - -

    07 August 2021

    -

    BlueWildrose updated:

    -
      -
    • The black dress, pink tutu, the bathrobe, the kimonos, and the qipaos no longer have a missing pixel when wearing them with the feminine bodytype. They're also no longer adjustable (they have no sprite for the adjusted variant and therefore it would just make an error if someone did that.)
    • -
    -

    Putnam3145 updated:

    -
      -
    • Supernova rad storms are now half as likely per tick tweak: Supernovae don't announce they're ending if they never announced they're starting tweak: Supernovae say explicitly no rad storms can happen if they can't
    • -
    • Monstermos is back
    • -
    - -

    05 August 2021

    -

    Putnam3145 updated:

    -
      -
    • organs decay again
    • -
    - -

    04 August 2021

    -

    BlueWildrose updated:

    -
      -
    • The debrained overlay actually shows for brainless corpses now instead of showing a blue error.
    • -
    -

    timothyteakettle updated:

    -
      -
    • legs are no longer awful
    • -
    - -

    03 August 2021

    -

    zeroisthebiggay updated:

    -
      -
    • tempgun is a laser
    • -
    • bake mode is useful
    • -
    • tempgun has less shots
    • -
    • tempgun has more sprites
    • -
    - -

    02 August 2021

    -

    TripleShades updated:

    -
      -
    • Decorative (read: Station-safe) water tile in the code
    • -
    • Pubby's new water feature wont kill atmosphere anymore
    • -
    - -

    31 July 2021

    -

    MrJWhit updated:

    -
      -
    • Fixes some minor mistakes around space near boxstation.
    • -
    -

    TripleShades updated:

    -
      -
    • Fountain area to public mining station-side tweak: Moved around the tables and chairs and monitor at public mining station-side
    • -
    -

    WanderingFox95 updated:

    -
      -
    • Added new ruin maps: The Bathhouse, The Library, The Engineering outpost, The Hotsprings(un-cursed), Lust, Wrath and an alternate spawn for the BDM in the form of a mining outpost, based on the same Ruins on the Ice Moon. removed: A lot of the fun items within the ice moon-based ruins that would break mining even more and trading cards.
    • -
    • Yes, this includes that the lavaland version of the hot spring is literally just water and not cursed. tweak: Also "fixed" that only one version of the BDM ruin ever spawns. Not sure it needed fixing but even locally hosted, only blooddrunk2.dmm would spawn. Since I added another spawn for the BDM, I fixed that too.
    • -
    - -

    29 July 2021

    -

    EmeraldSundisk updated:

    -
      -
    • Adds decals between Virology and the general Medbay to provide clarity
    • -
    • Adds an airlock with access to the Engineering Cooling Loop
    • -
    • The Maintenance Theater now has a suitable amount of dust
    • -
    • Removed an errant entertainment monitor left in the morgue
    • -
    • Removed redundant scrubber piping in and around the bar and kitchen tweak: Slightly readjusts an airpipe to take advantage of newfound space tweak: The Toxins Lab has received (predominantly) visual adjustments as to render it more in line with the general science department tweak: Toxins Storage is no longer its own area and as such needn't worry about APCs
    • -
    • Hydroponics now has a proper APC as intended
    • -
    - -

    27 July 2021

    -

    Putnam3145 updated:

    -
      -
    • Generic fires work now
    • -
    • A knock-on effect of the HE pipe change is that space cooling is ~8.4x as powerful
    • -
    - -

    26 July 2021

    -

    SandPoot updated:

    -
      -
    • Removes a sneaky transform button on the vore panel.
    • -
    - -

    24 July 2021

    -

    MrJWhit updated:

    -
      -
    • Replaces the northwest maint room on box with a sadness room
    • -
    • Replaces bar stripper room with an arcade on boxstation
    • -
    • Squished the west bathrooms a bit and made a room to sell things on boxstation.
    • -
    • Southeast maint hallway on box is now ziggy and zaggier.
    • -
    • Fixed pipes being not connected with the recent map PR for boxstation.
    • -
    -

    Putnam3145 updated:

    -
      -
    • hallucination now bottoms out at 0
    • -
    • supermatter now causes only half the hallucinations
    • -
    -

    cadyn updated:

    -
      -
    • auxmos bump for dependencies.sh
    • -
    - -

    23 July 2021

    -

    silicons updated:

    -
      -
    • Batons are slightly more powerful.
    • -
    - -

    19 July 2021

    -

    Arturlang updated:

    -
      -
    • The crafting button should no longer silently make more copies of itself on reconects
    • -
    • There are no longer two copies of the crafting component.
    • -
    • There is no longer a rogue d in tracer.dm tweak: Everything in Misc was moved to Miscelanious in the crafting menu, and Misc was nuked from orbit. Nobody will miss you.
    • -
    -

    MrJWhit updated:

    -
      -
    • Fixes a memory leak, there's a good chance that it's the same one that killed kilo.
    • -
    -

    SandPoot updated:

    -
      -
    • Put back mob vore with a pref.
    • -
    • Taken some stuff from tg for tgui_alert.
    • -
    • Refactored a lot of code on vore panel.
    • -
    -

    WanderingFox95 updated:

    -
      -
    • custom plasteel kegs
    • -
    -

    YakumoChen updated:

    -
      -
    • You can now wear the suffering of others on your head with just a sheet of human skin!
    • -
    • Human skin hats
    • -
    -

    keronshb updated:

    -
      -
    • Stripping/equipping things to a conscious braindead person (AKA a human owned by a disconnected player) will now give them a message with your visible name and roughly how long ago you touched their stuff when they login again. Touching someone's pockets or adjusting their gear other than equipping/unequipping is not logged. After 5 minutes, you'll have forgotten both their name and exactly how long ago past those 5 minutes it happened. (Credit to Ryll-Ryll)
    • -
    • LAZYNULL
    • -
    • Breaking mirrors now gives you a bad omen
    • -
    -

    timothyteakettle updated:

    -
      -
    • anthros can now select the cow tail
    • -
    • new quirk that allows you to eat trash
    • -
    - -

    18 July 2021

    -

    timothyteakettle updated:

    -
      -
    • fixes photosynthesis stopping nutrition going past well fed from non-photosynthesis means
    • -
    - -

    17 July 2021

    -

    cadyn updated:

    -
      -
    • precompile.sh updated
    • -
    - -

    15 July 2021

    -

    Putnam3145 updated:

    -
      -
    • fixes a major source of lag
    • -
    - -

    14 July 2021

    -

    Putnam3145 updated:

    -
      -
    • Acid is now a component
    • -
    - -

    13 July 2021

    -

    MrJWhit updated:

    -
      -
    • Adds a mirror above the sink in the captains bedroom in pubby
    • -
    - -

    12 July 2021

    -

    Putnam3145 updated:

    -
      -
    • causes_dirt_buildup_on_floor is now just a thing humans do instead of a weird var only true for humans
    • -
    - -

    11 July 2021

    -

    shellspeed1 updated:

    -
      -
    • replaces the seed machine with a biogen in the survival pod.
    • -
    • corrected an issue regarding wrong pair of gloves in the pod for DYI wiring .
    • -
    - -

    10 July 2021

    -

    WanderingFox95 updated:

    -
      -
    • Returns the wheelchair sprites to having, you know, wheels?
    • -
    • A motorized wheelchair addsound: Chairwhoosh.
    • -
    - -

    09 July 2021

    -

    MrJWhit updated:

    -
      -
    • Made a light not exist on the same tile as a door on pubby.
    • -
    • Makes the RD APC automatically connect to the powernet with the correct wire on pubby.
    • -
    • Added another wall for the AM engine so it doesn't space the airlock roundstart.
    • -
    - -

    07 July 2021

    -

    DeltaFire15 updated:

    -
      -
    • Golem / Plasmaman species color should work again.
    • -
    - -

    05 July 2021

    -

    Putnam3145 updated:

    -
      -
    • Watchers no longer search 9 tiles away for stuff then throw the result away if it's more than 1 tile away
    • -
    • Auxmos pull now uses a tag instead of pulling straight from the main branch
    • -
    -

    WanderingFox95 updated:

    -
      -
    • Moved a sprite one pixel to the left.
    • -
    -

    zeroisthebiggay updated:

    -
      -
    • tg based tool resprites
    • -
    • wirecutters have proper overlays
    • -
    - -

    04 July 2021

    -

    cadyn updated:

    -
      -
    • Updated server scripts for proper linux support
    • -
    - -

    03 July 2021

    -

    DeltaFire15 updated:

    -
      -
    • Turrets on nonlethal mode now once again shoot till the target is stamcrit as opposed to unable to use items, resolving some issues.
    • -
    -

    Putnam3145 updated:

    -
      -
    • A bunch of sleeping process() calls now either don't sleep or make sure to call a proc with waitfor set to FALSE
    • -
    -

    WanderingFox95 updated:

    -
      -
    • The axolotl ears in the .dmi file actually exist to the game now.
    • -
    - -

    02 July 2021

    -

    silicons updated:

    -
      -
    • spray bottles work again.
    • -
    - -

    30 June 2021

    -

    WanderingFox95 updated:

    -
      -
    • More plushies in the code.
    • -
    • Nabbed some plushie sprites from Cit RP and TG and made some myself. Enjoy!
    • -
    • The Daily Whiplash (Newspaper Baton) is now available! (Using sticky tape to stick a newspaper onto a baton) Bap!
    • -
    • A rolled up newspaper sprite was provided.
    • -
    • Switched Gateway and Vault locations on Boxstation, bringing it more in line with other stations.
    • -
    -

    bunny232 updated:

    -
      -
    • The pubby xenobiology air/scrubber network is now isolated from the rest of the station
    • -
    -

    qweq12yt updated:

    -
      -
    • HoP's cargo access was removed...
    • -
    -

    shellspeed1 updated:

    -
      -
    • NT has lost experimental KA tech to miners who were lost in the field. Make sure to try and recover it.
    • -
    • Adds an extremely expensive survival pod to mining for people to work towards. Get to work cracking rocks today.
    • -
    - -

    28 June 2021

    -

    Putnam3145 updated:

    -
      -
    • APCs aren't infinite power anymore
    • -
    • FDA, LINDA without the bookkeeping.
    • -
    • Putnamos, a simpler replacement for Monstermos. If I can get Monstermos to work, this will be Monstermos instead.
    • -
    • LINDA, the old active-turfs-based atmos subsystem.
    • -
    • Monstermos? I would rather not get rid of this, but I can't get it to work correctly.
    • -
    • Extools has been removed, and loading extools alongside auxtools will cause massive problems. If this is tested or merged, remove extools from the static files.
    • -
    -

    WanderingFox95 updated:

    -
      -
    • Carrots are good for your eyes - but eyes are also good for your carrots. Adds the googly eyes trait to walkingshrooms (Oculary Mimicry)
    • -
    • Googly Eyes - they make everything better.
    • -
    - -

    25 June 2021

    -

    MrJWhit updated:

    -
      -
    • Adds two missing decals to the 5x5 SM.
    • -
    -

    brokenOculus updated:

    -
      -
    • pillbottles and syringesare now printable from the medbay protolathe, shiftstart. Hyposprays are now printable in medbay lathe under advanced biotech.
    • -
    - -

    24 June 2021

    -

    WanderingFox95 updated:

    -
      -
    • An announcement to let players know the Cat Surgeon has come to visit.
    • -
    • Upped the Volume of his spawn noise and lowered the spawn weight slightly.
    • -
    - -

    23 June 2021

    -

    DeltaFire15 updated:

    -
      -
    • A bunch of small nanite things should be less wonky
    • -
    • Slimes are no longer immune to vomiting (undocumented change from a previous PR)
    • -
    • Fruit wine exists again.
    • -
    • Airlock hacking no longer sleeps.
    • -
    • The clockwork gateway deconstruction no longer sleeps.
    • -
    • Teslium reactions and Holywater booms no longer sleep.
    • -
    • Slime timestop no longer sleeps.
    • -
    -

    Putnam3145 updated:

    -
      -
    • inelastic exports no longer uselessly do exponential functions
    • -
    - -

    22 June 2021

    -

    bunny232 updated:

    -
      -
    • Adds a missing win door to meta xenobiology pen 6
    • -
    -

    silicons updated:

    -
      -
    • no more doubleroasting
    • -
    - -

    21 June 2021

    -

    silicons updated:

    -
      -
    • glowshroom scaling
    • -
    -

    timothyteakettle updated:

    -
      -
    • vore is 0.1% less shitcode
    • -
    - -

    20 June 2021

    -

    Arturlang updated:

    -
      -
    • Port's TG's nanite storage modification programs from the bepis
    • -
    • Fixes infective nanite progreams not syncing cloud ID.
    • -
    • Add's off icons for nanite machinery
    • -
    • Fixes antitox nanites runtiming on simplemobs
    • -
    • Updates the nanite dermal button icon set
    • -
    • Adds the ability to select the logic for nanite rules
    • -
    • Nanite programs with triggers won't ignore rules.
    • -
    • Coagluating nanite program research no longer has the wrong name tweak: Nanite program's have better descriptions now tweak: Nanite subdermal ID's now also include pulled ID's for simplemobs
    • -
    • Nanite voice sensors should properly work now.
    • -
    • Fixes nanite comm remote, now they should actually work
    • -
    -

    EmeraldSundisk updated:

    -
      -
    • Adds ColorMates to Snow Taxi tweak: Slight adjustments near the arrival shuttle landing zone
    • -
    • Removes an undesired corporate entity
    • -
    -

    Nanotrasen Structual Engineering Division updated:

    -
      -
    • Added lables to the atmos tanks on Metastation.
    • -
    • Adjusted Pubbystation's emitter room wall layout to prevent light-breakage on startup of emitters.
    • -
    • Removed frestanding sink and showers from Metastation science airlock, and Deltastation Xenobio. Added an emergency shower next to the kill room.
    • -
    • Removed a leftover pipe in Metastation security hallway.
    • -
    -

    bunny232 updated:

    -
      -
    • Pressure tanks other then air tanks start with gas!
    • -
    -

    keronshb updated:

    -
      -
    • Adds the Space Dragon midround event
    • -
    • Space Dragon sounds
    • -
    • Space Dragon + effects
    • -
    • Added Spacewalk trait
    • -
    • Gibs the original owner if they are turned into a Space Dragon with the traitor panel
    • -
    • logging for Space Dragon creation
    • -
    -

    kiwedespars updated:

    -
      -
    • a downside to wheely heelies ((made it actually detrimental))
    • -
    -

    zeroisthebiggay updated:

    -
      -
    • beltslot sprites for various items
    • -
    • resprite for telebaton
    • -
    - -

    19 June 2021

    -

    keronshb updated:

    -
      -
    • Ling Bone Gauntlets work again
    • -
    -
    - -GoonStation 13 Development Team -
    - Coders: Stuntwaffle, Showtime, Pantaloons, Nannek, Keelin, Exadv1, hobnob, Justicefries, 0staf, sniperchance, AngriestIBM, BrianOBlivion
    - Spriters: Supernorn, Haruhi, Stuntwaffle, Pantaloons, Rho, SynthOrange, I Said No
    -
    -
    -

    Creative Commons License
    Except where otherwise noted, Goon Station 13 is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 License.
    Rights are currently extended to SomethingAwful Goons only.

    -

    Some icons by Yusuke Kamiyamane. All rights reserved. Licensed under a Creative Commons Attribution 3.0 License.

    -
    - - diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml deleted file mode 100644 index 580cf51a2f..0000000000 --- a/html/changelogs/.all_changelog.yml +++ /dev/null @@ -1,29840 +0,0 @@ -DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. ---- -2015-04-04: - ACCount: - - rscadd: Emergency welding tool added to emergency toolbox. - - rscadd: Changed industrial welding tool sprite. - - tweak: Replaced welder in syndicate toolbox with industrial one. - - tweak: All tools in syndicate toolbox are red. Corporate style! - - tweak: Red crowbar is a bit more robust. - - bugfix: 'Fixed two bugs: welder icon disappearing and drone toolbox spawning with - invisible cable coil.' - AnturK: - - rscadd: 'Picket signs: table crafted with a rod and two cardboard sheets, write - on them with pen or crayon.' - Cheridan: - - wip: The bar's layout has been changed with a poker table and re-arranged seating. - Dannno: - - rscadd: Added gun lockers for shotguns and energy guns. Click on the lockers with - an item to close them if they're full. - Gun Hog: - - rscadd: Nanotrasen research has finalized improvements for the experimental Reactive - Teleport Armor. The armor is now made of a thinner, lightweight material which - will not hinder movement. In addition, the armor shows an increase in responsiveness, - activating in at least 50% of tests. - Incoming: - - rscadd: The iconic blood-red hardsuits of nuke ops can now be purchased for a - moderate sum of 8 TC by traitors. - Jordie0608: - - tweak: Cyborg mining drills now use up their internal battery before drawing power - from a borg's cell. - - bugfix: Fixes cyborg mining drills not recharging. - RemieRichards: - - rscadd: Burning mobs will ignite others they bump into or when they are stepped - on. - Xhuis: - - tweak: Malfunctioning AIs can no longer leave the station z-level. Upon doing - this, they will fail the round. - - tweak: Phazon exosuits now require an anomaly core as the final step in their - construction. - xxalpha: - - rscadd: Added Nutriment Pump, Nutriment Pump Plus and Reviver implants. - - tweak: Added origin technologies to all implants. - - tweak: 'The following implants are now much harder to obtain: X-ray, Thermals, - Anti-Stun, Nutriment Pump Plus, Reviver.' - - tweak: Cauterizing a surgery wound will now heal some of the damage done by the - bonesaw if it was used as part of the same surgery. - - tweak: Added ability for Medical HUDs to detect cybernetic implants in humans. -2015-04-09: - Iamgoofball: - - rscadd: Quite a lot of cleanables can now be scooped up with a beaker in order - to acquire the contents. - - rscadd: Light a piece of paper on fire with a lighter, and scoop up the ashes! - - rscadd: Scoop up the flour the clown sprayed everywhere as a 'joke'! - - rscadd: Scoop up the oil left behind by exploding robots for re-usage in chemistry! - - rscadd: You can splash the contents of a beaker onto the floor to create a Chemical - Pile! This pile can be heated or blown up and have the reagents take the effects. - Make a string of black powder around a department in maint. and then heat it - with a welder today! - - rscadd: Reagents now can have processing effects when just sitting in a beaker. - - rscadd: Pyrosium and Cryostylane now feed off of oxygen and heat/cool the beaker - without having to be inside of a person! - - rscadd: Reagents can now respond to explosions! - - rscadd: Black Powder now instantly detonates if there is an explosion that effects - it. - - rscadd: Fire now heats up beakers and their contents! - - rscadd: Activate some smoke powder in style by lighting the beaker on fire with - a burning hot plasma fire! - RemieRichards: - - tweak: Ninja stars are summoned to your hand to be thrown rather than automatically - targetting nearby mobs. - - rscadd: 'Added Sword Recall: pulls your katana towards you, hitting mobs in the - way. Free if within sight, cost scales with distance otherwise.' - - rscadd: Enemies can be electrocuted by a ninja as the cost of his energy, stunning - and injuring them. - - rscdel: Removed SpiderOS, functions moved to status panel. - - bugfix: Fixed energy nets not anchoring target, katana emag spam and sound delay. - optimumtact: - - bugfix: Mimes can't use megaphone without breaking their vow anymore. - phil235: - - tweak: Flying animals no longer triggers mouse traps, bear traps or mines. -2015-04-11: - Gun Hog: - - tweak: Nanotrasen has approved an access upgrade for Cargo Technicians! They are - now authorized to release minerals from the ore redemption machine, to allow - proper inventory management and shipping. - Iamgoofball: - - tweak: Blobbernauts no longer deal chemical damage, brute damage increased however. - Ikarrus: - - experiment: Getting converted by a rev or cultist will stun you for a few seconds. - Incoming5643: - - bugfix: Fixes some AI malf powers being usable when dead. - MrPerson: - - tweak: Reduces movement speed penalty from being cold. - Xhuis: - - rscadd: Adds a pizza bomb traitor item for 4 telecrystals. It's a bomb, diguised - as a pizza box. You can also attempt to defuse it by using wirecutters. - kingofkosmos: - - rscadd: Activating internals with an adjusted breath mask will automatically push - it up to normal state. - - tweak: Masks can now be adjusted when buckled to a chair. - optimumtact: - - tweak: Stun batons no longer lose charge over time when on. - phil235: - - tweak: The AI holopads now use a popup window just like computers and other machines. - - rscdel: Nerfs kinetic accelerator and plasma cutters. Plasma cutter is no longer - in the mining vendor. Reduces the drilling cost of all drills. - - rscadd: Adding 40+ new food and drink recipes, mostly using the newest plants. - Notably rice recipes, burritos, nachos, salads, pizzas. - - tweak: Opening the tablecrafting window can now also be done by dragging the mouse - from any food (that's on a table) onto you. - - rscadd: The kitchen cabinet starts with one rice pack. - - tweak: Glasses with unknown reagent will no longer be always brown but will take - the color of their reagents. -2015-04-13: - AnturK: - - rscadd: 'Spacemen have learned the basics of martial arts: Boxing, unleash it''s - power by wearing Boxing Gloves.' - - rscadd: While boxing you can't grab or disarm, but you hit harder with a knockout - chance that scales off stamina damage above 50. - - rscadd: Rumors have been heard of powerful martial styles avaliable only to the - gods themselves. - CosmicScientist: - - rscadd: Added a dehydrated space carp to traitor items, bought with telecrystals. - Use dehydrated space carp in hand to school them on loyalty. Add water to create - a vicious murder machine just for the halibut. - - tweak: The toy carp plushie now has attack verbs for fun, hit your friend with - one today. I put my sole into this mod. - - wip: If you can think of a better fish pun let minnow but I shouldn't leave it - to salmon else. - Ikarrus: - - tweak: Gang bosses can no longer purchase certain potent traitor items but instead - have access to some of a nuke op's arsenal of weapons. - Incoming5643: - - rscadd: 'Three new chemical types of blob can occur: Omnizine, Morphine and Space - Drugs.' - MrPerson: - - experiment: New lighting system! Lighting now smoothly transfers from one lighting - level to the next. - Xhuis: - - rscadd: There have been... odd sighting in Space Station 13's sector. Alien organisms - have appeared on stations 57, 23, and outlying. - - rscadd: Nanotrasen personnel have reason to believe that Space Station 13 is under - attack by shadowlings. We have little intel on these creatures, but be on the - lookout for odd behavior and dark areas. Use plenty of lights. - Zelacks: - - tweak: Defibs no longer have a minimum damage requirement for a successful revive. - Patients will have 150 total damage on a successful revive. - - tweak: Additional feedback is given for several failure states of the defib. - xxalpha: - - wip: Airlock crushing damage increased. -2015-04-16: - AnturK: - - rscadd: Nanotrasen authorities are reporting sightings of unidentified space craft - near space station 13. Report any strange sightings or mental breakdowns to - central command. - - rscadd: 'PS : Abductions are not covered by health insurance.' - - rscadd: Shadowlings and their thralls now have HUD icons. - - rscadd: Thralls learn their master's objectives when enthralled. - - rscadd: Regenerate Chitin ability lets shadowlings re-equip their armor if lost. - - tweak: Loyalty implanted people take 25% longer to enthrall, but lose their implant - and become immune to re-implanting. - - experiment: Shadowlings now have a message in their spawning text which specifies - that cooperation is mandatory. - - bugfix: Veil now works on equipped lights. - - bugfix: Shadowlings now take correct amount of burn damage and in light and heal - clone and brain damage in darkness. - - bugfix: Fixes 'Round end code broke' displaying every round. - - bugfix: Shadowlings who ascend will nore greentext properly. - Gun Hog: - - rscadd: Thinktronic Systems, LTD. has increased the Value of the Value-PAK PDA - cartridge! Standard issue for Captain PDAs, it can now access security bots, - medibots, cleanbots, and floorbots ALL AT ONCE! In addition, it can also connect - to your station's Newscaster network at NO EXTRA CHARGE! As a Thank you for - our contract with them, they have thrown in Newscaster access for the HumanResources9001 - cartridge, Heads of Personnel rejoice! - - tweak: The Newscaster app has also gotten a free upgrade which allows it to display - images and comments inside of posts! - - bugfix: Nanotrasen has concurrently released a patch for bots which will allow - off-station bots to properly patrol. - Incoming5643: - - rscadd: Changeling head slugs have been given player control, ventcrawling, and - a short escape period after egg laying. - MrStonedOne: - - rscadd: Admin ghosts can now drag ghosts to mobs to put that ghost in control - of that mob. - Xhuis: - - rscadd: Nanotrasen scientists have recently observed a strange genome shift in - green slimes. Experiments have shown that injection of radium into an active - green slime extract will create a very unstable mutation toxin. Use with caution. -2015-04-19: - AnturK: - - bugfix: Observers can now see abductor hivemind messages. - - rscadd: 'Adds advanced baton for abductors: Stun, Sleep and Cuff in one tool.' - - rscadd: Abductor agents now have vest cameras. - - imageadd: New sprites for abductors and their gear made by Ausops. - Fayrik: - - rscadd: Added jobban options for Abductors and Deathsquads. - - tweak: Made admin antag spawning buttons more efficient and less prone to failure. - Xhuis: - - rscadd: Recent sightings aboard space stations shows that spirits seem to be manifesting - as malevolent revenants and draining the life of crew. The chaplain may be helpful - in stopping this new threat. - kingofkosmos: - - wip: Girder and machine frame construction protocols has been changed. They can - now be secured/unsecured with a wrench and disassembled with a welder. -2015-04-20: - Fayrik: - - rscadd: Abductors now get advanced camera consoles. - - tweak: Redesigned Centcom again. There's a bar at the thunderdome now. - - rscadd: Headsets can now be locked to a spesific frequency, this only occurs for - nuke ops and deathsquads. - - rscadd: The Centcom channel is now available over all z-levels, regardless of - telecomms status. - - tweak: The Deathsquad space suits have been upgraded to hardsuits. - - rscadd: The Deathsquad now have thermal imaging huds, which can swap which hud - they display on the fly. - phil235: - - tweak: Reagents are now back to being metabolized every tick. Fixes frost oil - and capsaicin not working. - - tweak: Fixes not being able to make sterilizine. - - rscadd: Adding overdose to space drug, causing mild hallucination and toxin and - brain damage. - - tweak: Nerfed healing power of stimulant reagent. Buffed ephedrine a bit. - - rscadd: Nitroglycerin can now be stabilized with stabilizing agent, and explodes - when heated. -2015-04-21: - Ikarrus: - - wip: Gang mode has had some considerable work done on it, including a new objective - and currency dynamic. - - rscadd: New objective: Claim half the station as territory by tagging it - with spray cans supplied to gang bosses, but usable by any member. - - wip: An area can only be tagged by one gang at a time, remove your opponent's - tag or spray over it. - - rscadd: New recruitment: Recruiment pens replace flashes, stab people to - recruit them. - - experiment: Recruitment is silent, but causes brief seizures and has a cooldown - that scales upwards with a gang's size. - - rscadd: New tool: The Gangtool is used by bosses and lieutenants to recall - the shuttle and purchase supplies. - - rscadd: Pistols, ammo, spraycans, recruitment pens and additional gangtools can - all be bought. - - tweak: Gangtools also alert the user of promotions, purchases and territory changes - within the gang. - - rscadd: Lieutenants are promoted from gang members when given their own gangtool; - they're immune to deconversion and able to do anything a boss can except promotion. - - rscadd: New currency: Influence is used to purchase with the gangtool and - is generated every 5 minutes by each territory owned by the gang. - - tweak: Thermite can be cleaned off walls now. -2015-04-22: - Incoming5643: - - rscadd: 'Adds a new fun button for admins: ''Set Round End Sound''. You can use - the set round end sound button to set the round end sound. Glad we cleared that - up!' - Miauw62: - - wip: Very slightly expanded atmos and added an external airlock. - Xhuis: - - bugfix: A few issues have been fixed for revenants. In addition, the Mind Blast/Mind - Spike sound effect has been removed. - - rscadd: Adds the Hypnotize ability to revenants. It will cause a target to fall - asleep after a short time. - xxalpha: - - rscadd: Added an Exosuit Mining Scanner to the robotics fabricator. - - tweak: Buffed Ripley's movement and drilling speed in low pressure environments. -2015-04-25: - Boggart: - - rscadd: Generalizes handheld instrument code and Ports Nienhaus's guitar, sounds - by BartNixon of Tau Ceti. - - rscadd: Fixes being unable to build disposal pipes on walls, makes changing the - RPD's settings not affect pipes that are currently building, makes the RPD use - the datum/browser ui, makes it use categories and makes it show the selected - mode. - Gun Hog: - - rscadd: Nanotrasen has provided designs for fabrication of APC power control modules. - You may print them at any autolathe. - Ikarrus: - - rscadd: Gangs can now purchase switchblades, a relatively cheap and decently robust - melee weapon. - - tweak: Gangs now require at least 66% control of the station to win. - - tweak: Gang spraycan uses reduced to 15. - - tweak: Pistol cost increased to 30 Influence - - tweak: Promotions now start off cheap at 20 influence but get more expensive the - more people you promote. - Xhuis: - - rscadd: Added a Create Antagonist button for revenants. - - rscdel: Removed Mind Blast. - - bugfix: Revenants no longer get killed by explosions. - - tweak: Mind spike cooldown increased to 4 seconds. - - tweak: Harvest now takes 8 seconds and requires you to be adjacent to the target. - - tweak: Hypnotise sleeps targets for longer. - - tweak: Revenant now starts with 3 strikes. - phil235: - - tweak: Telecom machines are now deconstructed the same way as all other constructable - machines. - - tweak: You can no longer overdose on nicotine but you can get addicted (very mild - effects). -2015-04-29: - AndroidSFV: - - tweak: Dehydrated carp now are friendly to both the imprinter of the plushie as - well as any coded-in allies (I.E. Nuke Ops team), and unfriendly to carp of - other origin othan than yourself or your coded-in allies. Dehydrated carp that - are not imprinted will still have the same behavior as regular carp. - AnturK: - - rscadd: Advanced cameras now have all functionality of the abductor consoles. - - tweak: Pinpoint teleportation takes 8 seconds and spawns a flashy silhouette at - the target location. Can be used as distraction since it appears even if teleporter - is empty. - - bugfix: Abductors are now immune to viruses. - - bugfix: Dissection surgery ignores clothes. - - bugfix: Non-abductors can escape the ship by fiddling with consoles enough. - - rscadd: Three new negative glands. - - rscadd: Bloody glands spray blood everywhere and injure the host. - - rscadd: Bodysnatch glands turn the host into a cocoon that hatches doppelgangers. - - rscadd: Plasma glands cause the host to explode into a cloud of plasma. - GoonOnMoon: - - rscadd: Added a new assault rifle to the game for use by Nanotrasen fighting forces - in special events. Also happens to be available in the Liberation Station vending - machine and the summon guns spell usable by the wizard and badminnery. - Iamgoofball: - - rscdel: Acid blob has been removed. - - tweak: Charcoal and Silver Sulf are more powerful now. - - tweak: Styptic power and Silver Sulf metabolize at the default rate. - Ikarrus: - - rscadd: Spraycans and crayons can now draw Poseur Tags, aka Fake Gang Tags, as - grafiti. - - tweak: Influence income changed to provide weaker gangs a bigger boost, while - slowing down stronger gangs to promote opportunity for comebacks. - - tweak: Gangs only earn influence on territories they have held on to since the - previous Status Report (the income calculation every 5 minutes). This places - more significance on defending your existing territory. - - bugfix: You must be in the territory physically to tag it now. So no more tagging - everything from maint. - - tweak: Gang income delay reduced to 3 minutes intervals. - - tweak: Gang Capture goal reduced to 50% - - tweak: Gang spraycan use increased to 20 - - tweak: Gang Boss icon is now a red [G] icon to make it stand out better from regular - gang icons - JJRcop: - - tweak: TED's kill duration has been halved. - - tweak: Escaping from the TED's field no longer kills you. - RemieRichards: - - rscadd: Adds Easels and canvases for custom drawings. - - imageadd: Place a canvas on an easel and draw on it with crayons, clean one pixel - with a rag or soap and activate it in-hand to erase the whole canvas. - - rscadd: Ports VG's Ventcrawling overhaul! - - tweak: Crawling through vents is no longer instant, you now have to move and navigate - manually - - rscadd: While inside pipes and other atmos machinery, you now see pipe vision - phil235: - - bugfix: Podplants are no longer unharvestable. - - tweak: Choosing your clown, mime, cyborg and AI name as well as religion and deity - is now done in the preferences window. As a chaplain , your bible's icon is - now chosen by clicking the bible. -2015-04-30: - Fayrik: - - rscadd: Ported NanoUI to most atmospherics equipment. - TheVekter: - - tweak: Hooch is now made with 2 parts Ethanol, 1 part Welder fuel and 1 part Universal - Enzyme as a catalyst. - - tweak: No-slip shoes are paintable, painting them doesn't remove no-slip properties. -2015-05-01: - Ikarrus: - - rscadd: Gang bosses can now rally their gang to their location with their gangtool. - - rscadd: Gangtools can no longer recall the shuttle if station integrity is lower - than 70% - - rscdel: Removed requirement to be in the territory to tag it. - - tweak: Recruitment Pen cost reduced to 40. - - bugfix: Communications console should now accurately print the (lack of a) location - of the last shuttle call. - Xhuis: - - rscdel: Revenants will no longer spawn without admin intervention. They are pending - a remake. -2015-05-02: - Boggart: - - bugfix: Cryo tubes can no longer be used for ventcrawling. - Ikarrus: - - rscadd: Admins can choose the strength and size of Centcom teams to send, ranging - from officials to deathsquads, with the 'Make Centcom Respone Team' button. - phil235: - - tweak: Space carps can no longer knock down anyone, but they now deal additional - stamina damage to humans. - - tweak: Radiation effects from uranium walls are nerfed to the level of uranium - floor. - - rscadd: You can no longer put an inactive MMI in a cyborg shell. Ghosted brains - now get an alert when someone puts their brain in a MMI. You can now examine - the MMI to see if its brain is active. -2015-05-03: - AnturK: - - rscadd: Abductors can purchase spare gear with experimentation points. - Ikarrus: - - rscadd: Admins can now adjust the pre-game delay time. - MrStonedOne: - - experiment: MasterController and subsystem rejiggering! - - rscadd: The MC can now dynamcially change the rate a subsystem is triggered based - on how laggy it's being. This has been applied to atmos to allow for faster - air processing without lagging the server - - tweak: Pipes and atmos machinery now processes in tune with air, rather than seperately. - - bugfix: Fixed hotspots and fire causing more lag than they needed to - - bugfix: Fixed some objects not getting garbage collected because they didn't properly - clear references in Destory() - - tweak: The qdel subsystem will now limit its processing time to a 5th of a second - each tick to prevent lag when a lot of deletes happen - - bugfix: Fixed the ticker not showing a tip of the round if an admin forces the - round to start immediately -2015-05-04: - Firecage: - - bugfix: Emagged windoors can now be deconstructed. - RemieRichards: - - rscadd: Adds Plasmamen, a species that breathes plasma and bursts into flames - if they don't wear special suits. - - imageadd: New burning icon for all humanoid mobs. - - imageadd: New sprite for Skeletons to match Plasmamen. - oranges: - - tweak: Thanks to recent advances in fork science, you no longer need to aim at - your eyes to eat the food off a fork - xxalpha: - - rscadd: 'Adds a new barsign: ''The Net''.' -2015-05-05: - Firecage: - - bugfix: Golems and skeletons no longer fall over when stepping on shards. - Gun Hog: - - bugfix: Mining borg diamond drill upgrade now functional. - Ikarrus: - - tweak: Doubled the initial charge of SMESs in Engineering. - - tweak: Influence cap for gangs has been increased. - incoming5643: - - bugfix: All modes now select their antagonists before job selection, this means - that a player who prefers roles normally immune to being certain antagonists - (implanted roles/silicons) can still have a fair shot at every antagonist roll - they opt into. If they're selected they simply will not end up with an incompatible - job. - - bugfix: As an example if someone loved to play Head of Security (humor me here) - and had it set to high, and the only other jobs he had set were security officer - at medium and botanist at low but he was selected to be a traitor, he would - spawn as a botanist even if there ended up being no Head of Security. - - experiment: Please give playing security another chance if you'd written it off - because it affected your antag chances. - xxalpha: - - bugfix: Hulks can now break windoors. - - bugfix: Fixed smoking pipe messages. Fixed emptying a smoking pipe with nothing - in it. -2015-05-06: - Jordie0608: - - bugfix: Borgs can now open lockers with the 'Toggle Open' verb. - Thunder12345: - - bugfix: Severed the cryo tube's connection to the spirit world. Ghosts will no - longer be able to eject people from cryo. Please report further instances of - poltergeist activity to your local exorcist. - Xhuis: - - tweak: Many minor technical changes have been made to cult. - - rscadd: Cultist communications now show the name of the person using them. Emergency - communications do not do this. - - rscadd: Emergency communication does less damage. - xxalpha: - - rscadd: Engineering cyborgs can now pick their cable coil color whenever they - want. -2015-05-07: - Xhuis: - - rscadd: Emagged defibrillators will now do burn damage and stop the patient's - heart if used in harm intent. - - tweak: The previous stunning functionality of the emagged defibrillator has been - moved to disarm intent. - phil235: - - tweak: Temperature effects from frost oil and capsaicin reagents and basilisk - have been buffed to be significant again. - xxalpha: - - tweak: Hulks can now break windoors. -2015-05-08: - Firecage: - - tweak: Mobs can now be buckled to operating tables. - Gun Hog: - - rscadd: 'Top scientists at Nanotrasen have made strong progress in Artificial - Intelligence technology, and have completed a design for replicating a human - mind: Positronic Brains. Prototypes produced on your research station should - be compatible with all Man-Machine Interface compliant machines, be it Mechs, - AIs, and even Cyborg bodies. Please note that Cyborgs created from artificial - brains are called Androids.' - - tweak: The pAI role preference and related jobbans have been renamed to properly - reflect that they are not soley for pAI, but include drones and positroinc prains. - astralenigma: - - tweak: Cargo packages are now delivered with their manifests taped to the outside. - Click on them with an open hand to remove them. - optimumtact: - - tweak: Machine frame and girder deconstruction now uses a screwdriver instead - of welding tool. -2015-05-09: - Firecage: - - tweak: Increased the manifestation chance of super powers. - Ikarrus: - - experiment: 'Loyalty implants will no longer survive deconverting a gangster. - Security now needs to use two of them if they want the permanent effects: The - first to deconvert them, and the second to make them loyal.' - KorPhaeron: - - tweak: Slime mutation chance now starts at 30%. - - rscadd: Baby slimes have a -5% to 5% difference of their parent's mutation chance, - allowing you to breed slimes that are more likely to mutate. - - rscdel: Plasma and epinephrine no longer affect mutation chance of slimes. - - rscadd: Red slime extract and plasma makes a potion that can increase mutation - chance, Blue slime extract and plasma potions will decrease it. -2015-05-10: - AnturK: - - bugfix: Fixed borg's cells draining much faster than they're meant to. - Gun Hog: - - tweak: Station bot performance greatly increased. - - rscadd: Captain PDA cartridge now includes nearly all utilities and functions, - including signaller and all bots! HoP now has janitor and quartermaster functions! - The RD and Roboticists now have access to Floor, Clean, and Medibots! - - tweak: Bot access on PDA is now one button across all PDAs. You will only see - what bots you can access, however. - - rscadd: Cartridges that include a signaller have been improved so they will work - on a larger frequency range. - - tweak: All bots now have Robotics access, so they may be set to patrol and released - once constructed. - - tweak: Roboticists now have access to bot navigation beacons. They are found under - the floor tiles as patrol route nodes. -2015-05-11: - Firecage: - - imageadd: New icons for Industrial and Experimental welding tools. - Gun Hog: - - rscdel: The power mechanic for mining drills and the jackhammer has been removed. - They no longer require cells or recharging. - - bugfix: The diamond drill upgrade for mining cyborgs has been fixed. - Xhuis: - - rscadd: Adds the pneumatic cannon, attach an air tank and shoot anything out of - it. - - rscadd: Improvised pneumatic cannons can be tablecrafted with a wrench, 4 metal, - 2 pipes, a pipe manifold, a pipe valve and 8 package wrappers. - spasticVerbalizer: - - bugfix: False walls no longer stackable. -2015-05-13: - Firecage: - - rscadd: Kudzu is now admin-logged in Investigate. - GunHog: - - tweak: Positronic brains are now entered by clicking on an empty one, in the same - manner as drones. - - rscadd: Ghosts are alerted when a new posibrain is made. - Jordie0608: - - rscadd: Borg reagent containers (beakers, spraybottles, shakers etc.) are no longer - emptied when stowed. - - bugfix: Fixes North and West Mining Outposts having empty SMESs. - - bugfix: Aliens and slimes can smash metal foam again. - - rscdel: Deconstructing reinforced walls no longer creates additional rods out - of nowhere. - - imageadd: Pepperspray now has inhand sprites. - Xhuis: - - bugfix: Fixes the recipe for pneumatic cannons; it now only requires a wrench, - 4 metal, 2 pipes and 8 package wrappers . -2015-05-15: - xxalpha: - - bugfix: Fixed emitter beams not being reflectable. -2015-05-16: - MartiUK: - - bugfix: Fixed a typo when cleaning a Microwave. - - bugfix: Fixed a typo when burning someone with a lighter. -2015-05-20: - xxalpha: - - rscadd: Added three drone shells to the derelict. -2015-05-22: - Jordie0608: - - tweak: Smothering someone with a damp rag when in harm intent will apply reagents - onto them, for acid-burning their face; otherwise it will inject them, for drugging - with chloral hydrate. - - imageadd: The healthdoll is now blue when at full health to make it more clear - when a body part is injured. -2015-05-25: - spasticVerbalizer: - - tweak: Glass airlocks can now be made heat-proof by using a sheet of reinforced - glass to create the window, regular glass creates a normal glass airlock. - xxalpha: - - bugfix: You can no longer drop items inside mechas nor machinery (this includes - gas pipes, disposal pipes, cryopods, sleepers, etc.). - - bugfix: Fixed exploit of changelings being able to keep thermal vision after resetting - their powers. - - bugfix: Fixed being able to implant NODROP items with cavity implant surgery. -2015-05-26: - CosmicScientist: - - spellcheck: Corrected wording for the pAI, donksoft riot darts and some tip of - the round tips. - xxalpha: - - bugfix: Fixed changeling revival. -2015-05-30: - duncathan: - - bugfix: Fixes passive gates not auto-coloring. - spasticVerbalizer: - - tweak: Players trying to speak but unable to will now get a message. -2015-05-31: - duncathan: - - tweak: Clarified the ability to retract changeling armblades. -2015-06-04: - Cuboos: - - rscadd: Added casting and firing sounds for wizard spells and staves. - - rscadd: A new title theme has been added. - Gun Hog: - - rscadd: Nanotrasen has approved the designs for destination taggers and hand labelers - in the autolathe. - Palpatine213: - - tweak: Allows sechuds to have their id locks removed via emag as well as EMP -2015-06-05: - CandyClown: - - tweak: Ointments, bruise packs, and gauze are now stacked to 6 instead of 5. - CorruptComputer: - - bugfix: Security lockers no longer spawn in front of each other on Box. - - bugfix: Hooked up the scrubbers in QM's office on Box. - - bugfix: Fixed bar disposals on Box - - bugfix: Fixed the stacked heater+freezer in expirementor maint on Box - - tweak: Made the turbine into Atmos and Engineering access only, and renamed the - doors to Turbine on Box. - Ikarrus: - - rscadd: Gang Bosses will now be able to discreetly send messages to everyone in - their gang for 5 influence a message. - - tweak: Conversion pens now use a flat 60sec cooldown rate. - KorPhaeron: - - rscadd: You can now lay tiles on the asteroid. Go nuts building forts. -2015-06-06: - Incoming5643: - - rscadd: Antagonists with escape alone can now escape with others on the shuttle, - so long as they are also antagonists. - - rscadd: Antagonists with escape alone can also win if non-antagonists are on the - shuttle provided they are locked in the brig. - - rscadd: Escaping to syndicate space on board the nuke op shuttle is now a valid - way to escape the station. - Jordie0608: - - rscadd: Admin-delaying the round now works once it has finished. -2015-06-07: - Aranclanos: - - rscadd: Malfunctioning AIs can preview placement of a Robotic Factory. - Iamgoofball: - - rscadd: Bicardine, Dexalin, Kelotane, Anti-toxin, Inaprovaline and Tricordrazine - have been re-added. - RemieRichards: - - rscadd: Lizards can now wag their tails, emote *wag to start and *stopwag to stop. - kingofkosmos: - - tweak: Mops can now be wet from normal buckets and sinks. -2015-06-08: - AnturK: - - imageadd: Improved the interface of Spellbooks. - Cheridan: - - tweak: Push-force from Atmospherics now depends on an entity's weight, heavier - objects are less prone to being pushed. - - rscadd: Magboots and No-Slip shoes now prevent pushing from spacewind. - Firecage: - - rscadd: Protolathes can now build Experimental Welding Tools. -2015-06-09: - Aranclanos: - - wip: Structures and machines can now be built on shuttles. - Iamgoofball: - - rscadd: 'Adds the Bluespace Rapid Part Exchange Device: holds up to 400 stock - parts and can be used to upgrade machines at range without needing to open their - maintenance panel.' - - rscadd: A new tier of stock parts have been added, they're very expensive to produce - but provide ample improvements. - - experiment: Many machines can now also be upgraded. - - tweak: 'Emitter: Lasers decrease firing delay and Capacitors decrease power consumption.' - - tweak: 'Gibber: Matter Bins increase yield of meat and Manipulators speed up operation - time, at high level can gib creatures with clothes.' - - tweak: 'Seed Extractor: Matter Bins increase storage and Manipulators multiply - seed production.' - - tweak: 'Monkey Recycler: Matter Bins increase the amount of monkey cubes produced - and Manipulators reduce the monkey-to-cubes ratio to a minimum of 1-to-1.' - - tweak: 'Crusher: Matter Bins increase material yield and Manipulators increase - chance to yield materials, at high level there is a chance for rarer materials.' - - tweak: 'Holopad: Capacitors increase an AI''s traversal range from the holopad.' - - tweak: 'Smartfridge: Matter Bins increase storage.' - - tweak: 'Processor: Matter Bins increase yield and Manipulators speed up operation - time.' - - tweak: 'Microwave: Matter Bins increase storage.' - - tweak: 'Ore Redemption Machine: Matter Bins increase yield per ore, Lasers increase - points per ore and Manipulators speed up operation time.' - - tweak: 'Hydroponics Tray: Manipulators improve water and nutrients efficiency.' - - tweak: 'Biogenerator: Matter Bins increase storage.' - bananacreampie: - - rscadd: Added several new options to the ghostform sprites -2015-06-11: - Cheridan: - - rscdel: Removes the powerdrain for individiual active modules on cyborgs. -2015-06-12: - Ikarrus: - - experiment: Gang Updates - - rscadd: 'New objective: To win, Gangs must now buy a Dominator machine (50 influence) - and defend it for a varying time frame.
    * The location of the dominator is - broadcasted to the entire station the moment it is activated
    * The more territories - the gang controls, the less time it will take
    * Gangs no longer win by capturing - territories' - - rscadd: A choice of gang outfits are now purchasable for 1 influence each - - rscadd: Thompson SMGs aka "tommy guns" are now purchasable for 50 influence - - rscadd: Bulletproof armor vests are now purchasable for 10 influence - - tweak: Gang messages are now free to send - - tweak: Prices of pistols and pens reduced to 20 and 30, respectively - - tweak: Gang spraycans have been made a lot less obvious. They look nearly identical - to regular ones, now. - - rscdel: Gangs will no longer be notified how much territory the enemy controls - Incoming5643: - - rscadd: Growing tired of reports of slain members, the Wizard Federation has cautiously - sactioned the dark path of lichdom. Beware of the powerful lich who hides his - phylactery well, for he is immortal! - - rscadd: The trick to defeating liches is to destroy either their body or their - phylactery item before they can ressurect to it. The more a lich is slain the - longer it will take him to make use of his phylactery and the more likely the - crew is to catch him during a vunerable moment. - - rscremove: Due to the addition of proper liching, skeletons as a choosable race - from magic mirrors has been discontinued. My apologies to the powergamers. A - special admin version of the mirror that allows for skeletons has also been - added to the code. - Miauw: - - tweak: 'AIs have received several minor nerfs in order to increase antagonist - counterplay:' - - tweak: AI tracking is no longer instant, it takes an amount of time that increases - with distance from the AI eye, up to 4 seconds. The AI detector item will light - up when an AI begins tracking. - - tweak: A random camera failure event has been added, which will break one or two - random cameras. - - tweak: You can no longer keep tracking people that are outside of your camera - vision. - - tweak: Camera wires have been removed. Screwdriver a camera to open the panel, - then use wirecutters to disable it or a multitool to change the focus. - - tweak: You can now hit cameras with items to break them. To repair a camera, simply - open the panel and use wirecutters on it. - - tweak: Camera alerts now only happen after a camera is reactivated. - RemieRichards: - - rscadd: New optional explosion effect ported from /vg/'s DeityLink, Explosions - that are affected by Walls and Doors -2015-06-14: - Ikarrus: - - rscadd: White suits added to gang outfits - - tweak: Gang outfits are now free, but are now limited in stock (that replenishes - over time) - - tweak: While attempting a Hostile Takeover, gangs do not gain influence. Instead, - the takeover timer will be reduced by how many territories they control. - - tweak: Spraycan cost reduced to 5 influence. - - tweak: Recruitment Pen cooldown increased to 2 minutes, but is reduced if the - enemy gang has more members than yours. - - tweak: Tommy guns no longer deal stamina damage. - - rscdel: Gangtools can no longer recall the shuttle if the game mode is not Gang - War -2015-06-15: - Incoming5643: - - rscadd: Lizards can now choose from a wide varity of physical appearances in character - creation! Sprites made by WJohn. Hiss Responsibly. - Kor: - - rscadd: A terrible new creature stalks the halls of SS13. - - rscadd: The wizard has a new artefact related to said creature. - - rscadd: Added a new sepia slime plasma reaction. Try it out! - spasticVerbalizer: - - bugfix: Drones can now properly quick-equip. -2015-06-18: - AnturK: - - rscadd: Added new photo-over-pda function. Apply the photo to PDA to send it with - your next message! - Ikarrus: - - rscadd: Department Management consoles have been added to Head of Staff offices. - These will enable heads to modify ID's access to their department, as well as - preform demotions. - Miauw: - - tweak: Bullets can now damage cameras. - - tweak: Camera alarms now trigger 90 seconds after the first EMP pulse, instead - of when all EMP pulses run out. - - tweak: Makes the force required to damage cameras greater than or equal to ten - instead of greater than ten. - - tweak: Camera alarms now trigger when cameras are disabled with brute force or - bullets. - Xhuis: - - rscadd: Nanotrasen scientists have determined that a delaminating supermatter - shard combining with a gravitational singularity is an extremely bad idea. They - advise keeping the two as far apart as possible. - phil235: - - rscdel: Nerfed the xray gun. Its range is now 15 tiles. -2015-06-20: - Dorsisdwarf: - - tweak: Syndicate Bulldog Shotguns now use slug ammo instead of buckshot by default - - rscadd: Nuke Ops can now buy team grab-bags of bulldog ammo at a discount. - Ikarrus: - - rscadd: Wearing your gang's outfit now increases influence and shortens takeover - time faster. - - rscadd: Added several more options for gang outfits - - rscadd: Pinpointers will now point at active dominators. - - tweak: Gang outfits are now slightly armored - - tweak: Gang tags are now named 'graffiti' to make them harder to detect - - tweak: Initial takeover timer is now capped at 5 minutes (50% control) - - tweak: 'Server Operators: The default Delta Alert texts have changed. Please check - if your game_options.txt is up to date.' - - rscdel: Loyalty implants now treat gangs as it treats cultists. Implants can no - longer deconvert gangsters, but it can still prevent recruitments. - - tweak: Replaced tommy guns with 9mm 2-burst 32 mag uzis that costs 40 influence. - Unlike tommy guns gangs will be able to purchase ammo for uzis. - Jordie0608: - - tweak: 'For Admins: Jump-to-Mob (JMP) notification command replaced with Follow - (FLW).' - - rscadd: Message and Follow links added to many notifications. - - rscadd: New buttons to toggle nuke and set security level. - - spellcheck: Flamethrowers are logged in attack_log. - Thunder12345: - - rscadd: Combat shotguns are now semi automatic, and will be pumped automatically - after firing. - - tweak: Combat shotgun capacity has been reduced to six shells. - Xhuis: - - rscadd: You will now trip over securitrons if you run over them whilst they are - chasing a target. - - rscadd: An admin-spawnable drone dispenser has been added that will automatically - create drone shells when supplied with materials. - - rscadd: Airlock charges are available to traitors and will cause a lethal explosion - on the next person to open the door. - - rscadd: Nuclear operatives can now buy drum magazines for their Bulldog shotguns - filled with lethal poison-filled darts. - - rscadd: When a malfunctioning AI declares Delta, all blue tiles in its core will - begin flashing red. - - rscadd: Back-worn cloaks have been added for all heads except the HoP. LARPers - rejoice! - - rscadd: More suicide messages have been added for a few items. -2015-06-21: - GunHog: - - tweak: The Hostile Lockdown ability for Malfunctioning AIs has been nerfed. It - now costs 30 CPU, is much more obvious, and automatically resets in 90 seconds. - - tweak: Buffed the Upgrade Turrets Malfunction ability. Turrets will now fire heavy - lasers instead of simply shooting faster. - - rscadd: Nanotrasen has released an Artificial Intelligence firmware upgrade under - the ID 41ST0L3MYB1K3. It contains drivers for interacting with all variants - of exosuit technology, from the Ripley APLU design to even experimental Phazon - units. Simply upload your AI to the exosuit's internal computer via the InteliCard - device. Per safety regulations, the exosuit must have maintenance protocols - enabled in order to remove an AI from it. - - rscadd: Malfunctioning AIs may wirelessly steal mechs via a new power, Mech Domination. - For 30 CPU, a Malf AI may permanently upload itself to a mech, ejecting any - pilots. Malf AIs will still lose if they leave the Z-level, and the Malf will - be gibbed if the mech is destroyed - they cannot be carded out of the mech or - shunt to an APC. - Iamgoofball: - - rscdel: Blobs can no longer have Morphine as their chemical. - duncathan: - - tweak: Heat exchangers now update their color to match that of the pipe connected - to them. - - tweak: Heat exchangers are on longer dense. -2015-06-22: - Iamgoofball: - - rscdel: Removed failure chance and delay when emagging an APC. - KorPhaeron: - - tweak: Rebalanced armor to be less effective, reducing the melee, bullet and/or - laser damage reduction of all armor suits. - LaharlMontogmmery: - - rscadd: You can now click and drag a storage container to empty it's contents - into another container, disposal bin or floor tile. - Xhuis: - - experiment: Revenants have received a considerable overhaul. - - rscadd: Revenants will no longer share spawn points with space carp and will spawn - in locations like the morgue and prisoner transfer center. - - rscadd: Revenants can no longer cross tiles covered in holy water. - - rscadd: Revenants have a new ability called Defile for 30E. It will cause robots - to malfunction, holy water over tiles to evaporate, and a few other effects. - - rscadd: Upon death, revenants will appear and play a sound before rapidly fading - away and leaving behind glimmering residue as evidence of their demise. - - rscadd: This residue lingers with the essence of the revenant. If left unattended, - it may reform into a new revenant. Simply scattering it is enough to stop this, - but it also has high research levels. - - rscadd: Revenants now have fluff objectives as well as a set essence goal. - - tweak: Revenanants will be revealed for longer when using abilities and also receive - feedback on this revealing. - - tweak: Revenants can now only spawn via random event with a specific amount of - dead mobs on the station. The default for this is 10. - - bugfix: Revenants can no longer use abilities from inside walls. - - rscdel: Directly lethal abilities have been removed from revenants. In addition, - they can no longer harvest unconscious people, only the dead. -2015-06-23: - Fayrik: - - rscadd: NanoUI is now Telekenesis aware, but due to other constraints, NanoUI - interfaces are read only at a distance. - - tweak: Refactored all NanoUI interfaces to use a more universal proc. - - tweak: Adjusted the refresh time of the NanoUI SubSystem. All interfaces will - update less, but register mouse clicks faster. - - bugfix: Removed automatic updates on atmospheric pumps, canisters and tanks, making - them respond to button clicks much faster. - - bugfix: Atmos alarm reset buttons work now. Probably. - Iamgoofball: - - rscadd: Adds a progress bar when performing actions. - Ikarrus: - - rscadd: New gang names with tags created by Joan - - rscadd: C4 explosive can be purchased by gangs for 10 influence. - - tweak: Recruitment pen cost increased to 50. - - rscadd: Lieutenants recieve one free recruitment pen. - - tweak: Recruitment pens are now stealthy and no longer give a tiny prick message. - - tweak: Increased chance of deconversion with head trauma - - tweak: Recalling the shuttle now takes about a minute to work, during which you - won't be able to use your gangtool. - - rscadd: Pinpointers no longer point at dominators. Instead, dominators will beep - while active. - - rscadd: Added puffer jackets and vests. - - tweak: Increased gang outfit armor. It is moderately resistant to bullets now. - - rscdel: Removed bulletproof vests from gangtool menu. - Jordie0608: - - rscadd: Admins can now flag ckeys to be alerted when they connect to the server. - MrStonedOne: - - rscadd: Admins can now reject poor adminhelps. This will tell the player how to - construct a useful adminhelp and give them back their adminhelp verb - RemieRichards: - - tweak: Cumulative armour damage resistance is now capped at 90%, you will now - always take at bare minimum, 10% of the incoming damage. - - rscadd: Added a system for Armour Penetration to items, it works by temporarily - (It does NOT damage the armour or anything) reducing the armour values by the - AP value during the attack instance. - - rscadd: 'The formula for AP is Armour-ArmourPenetration = AdjustedArmour and AdjustedArmour - is used for all the remaining calculations instead of Armour (Eg: 80 Melee - - 15 AP = 65 Melee).' - - rscadd: The Ninja's Energy Katana has 15 AP, Xenomorphs have an inbuilt AP of - 10. - - tweak: You can now unwrench pipes who's internal pressures are greater than that - of their environment... - - rscadd: However it will throw you away from the pipe at extreme speed! (You are - warned beforehand if the pipe will do this, allowing you to cancel) - Vekter: - - bugfix: Finally fixed immovable rods! They will now properly bisect the station - (and crit anyone unlucky enough to be in their path). - - tweak: Increased Meteor activity detected in the vicinity of the station. Be advised - that many storms may be more violent than they once were. - - rscadd: Gravitational anomalies will now throw items at mobs in their vicinity. - Take care while scanning them. - - rscadd: Flux anomalies explode much more violently now. Get there and destroy - them, or risk losing half a department. - xxalpha: - - rscadd: 'Added a new Reviver implant: now it revives you from unconsciousness - rather than death.' - - rscadd: Added cybernetic implants and a cybernetic implants bundle to the Nuke - Ops uplink. - - bugfix: Fixed Nutriment pump implant printing. - - tweak: Health Analyzers now have the ability to detect cybernetic implants. - - tweak: X-Ray implants are now much harder to unlock. -2015-06-24: - Ikarrus: - - rscadd: Request Console message sent to major departments will now be broadcasted - on that department's radio. - - rscadd: Request Consoles can be used to quicly declare a security, medical, or - engineering emergency. -2015-06-25: - Iamgoofball: - - rscadd: Changes up how Explosive Implants work. - - rscadd: They have become Microbomb Implants. They cost 1 TC each. Each implant - you inject increases the size of the explosion. You gib on usage, regardless - of explosion size. - - rscadd: A Macrobomb implant was added for 20 TC. It is the equivalent of injecting - 20 microbombs. - - rscadd: Nuke Ops start with microbomb implants again. -2015-06-26: - Ikarrus: - - imageadd: Added a couple of new gang tag resprites by Joan. - Kor: - - tweak: Summon Guns has returned to its former glory. The spell will once again - create antagonists, now with the objective to steal as many guns as possible. - - tweak: Summon Guns once again costs a spell point, rather than granting one. - phil235: - - tweak: Buffs traitor stimpack (and adrenalin implant) to be more efficient against - stuns/knockdowns. - pudl: - - rscadd: You can now play games of mastermind to unlock abandoned crates found - throughout space. -2015-06-27: - Ikarrus: - - rscadd: Some objects can be burned now. - - rscadd: Bombs will shred your clothes, with respect to their layering and armor - values. Exterior clothing will shield clothing underneath. Storage items will - drop their contents when bombed this way. - Laharl Montogmmery: - - rscadd: 'Storage Content Transfer : Bluespace Boogaloo! You can now transfer the - content of the BoH/BRPED into tiles/bins/bags out of your reach. Range is 7 - tiles.' - MrStonedOne: - - tweak: Admins will now receive a notification when one of them starts to reply - to an adminhelp to cut down on multiple responses to adminhelps and let admins - know when an adminhelp isn't getting replied to. - - rscadd: The keyword finder in admin helps (adds a (?) link next to player names - in the text of adminhelps) has been added for all player to admin pms, as well - as admin say. - NullQuery: - - wip: Introduces html_interface, a module to streamline the management of browser - windows. - - rscadd: Adds playing cards that utilize a new HTML window management system. - Vekter: - - rscadd: Added a new military jacket to the Autodrobe and ClothesMate. -2015-06-28: - Ikarrus: - - rscadd: Gang Lieutenants can buy gang tools now, but at a higher cost than the - original boss - - rscadd: Gang leaders can register additional gangtools to themselves for use as - spares. - - tweak: Number of maximum lieutenants lowered to 2 - - tweak: Pistol cost increased to 25 influence - - tweak: Uzi cost increased to 50 influence - - tweak: Uzi Ammo decreased to 20 influence - - rscadd: Overcoats added to items the biogenerator can produce. - - rscdel: Micro and Macro bomb implants are now restricted to the Nuclear game mode. - phil235: - - tweak: Smoke (and foam) no longer distribute more reagents than they have. The - amount of clouds in a smoke now depends on the amount of smoke created. Acid - no longer melts items on a mob at low volume, and the chances to melt them increases - with the amount applied on the mob. Sprays can now contain acid again. -2015-06-29: - Ikarrus: - - rscadd: Clothing has been separated out of equipment lockers into wardrobes to - reduce clutter. - Incoming5643: - - rscadd: The secrets of the rainbow slimes have finally been revealed. To attain - this rare blob you must breed a slime with a 100% mutation chance! - - rscadd: Rainbow slime cores will generate a randomly colored slime when injected - with plasma. It's a good plan B if the slimes aren't cooperating in terms of - colors. You can get any color slime this way, pray to the RNG! - Xhuis: - - rscadd: The Sleeping Carp clan has made its presence known on Space Station 13. - Some gangs will name themselves after this group and practice martial arts rather - than using traditional gang weaponry. These shadowboxers are not to be taken - lightly. - oranges: - - tweak: Thanks to a breakthrough in directed vector thrusting, all nanotrasen brand - jetpacks have been greatly improved in speed and handling -2015-07-01: - Ikarrus: - - rscadd: Multiple gang leaders are spawned at round start, the number which depends - on server population - - rscdel: Gangsters can no longer be promoted mid-game. - - rscadd: Security can once again deconvert gangsters with loyalty implants - - rscadd: Added an Implant Breaker item to the gangtool as a purchasable item for - 10 influence each
    * They are a one-use item that destroys all implants in - the target, including loyalty implants
    * They will also attempt to recruit - the target before destroying itself - - rscdel: Implanters no longer work if the target is wearing headgear. Remove them - first. - NullQuery: - - tweak: The crew monitoring computer, AI crew monitoring popup and the handheld - crew monitor now update automatically. - - tweak: 'Crew monitoring: The health information has been turned into a health - indicator. It goes from green to red. Hovering over the icon shows detailed - information (if available).' - - tweak: 'Crew monitoring: The location coordinates have been hidden. You can see - them by hovering over the ''Location'' column.' - - rscadd: 'Crew monitoring: A minimap has been added so you can easily see where - people are.' - - tweak: 'Crew monitoring: Players who are not in range of a camera are not shown - on the minimap.' - - tweak: 'Crew monitoring: AI players can quickly move to other locations or track - players by clicking the minimap or items in the table.' - - tweak: 'Crew monitoring: For AI players, health information always shows a white - indicator instead of green-to-red. This is a deliberate limitation to prevent - the AI from becoming too omnipresent.' - phil235: - - tweak: Space drug overdose no longer cause brute/brain damage but you hallucinate - more. Space Drug Blob now makes you hallucinate even if you don't overdose on - its space drug. - xxalpha: - - rscadd: 'Added a new traitor objective: steal the station''s self-destruct nuke - plutonium core.' -2015-07-02: - Ikarrus: - - rscadd: Throwing reagent containers such as drinks or beakers may spill their - contents onto whatever they hit - - rscadd: Slipping while carrying items in your hand may cause ~accidents~ - - tweak: Mounted and portable flashers can now only be burned out from overuse, - similar to flashes. - oranges: - - tweak: Thanks to department budget cuts we've had to remove the security cameras - built into officer helmets, Nanotrasen apologies for this inconvenience. -2015-07-03: - Ikarrus: - - experiment: Added support for up to six gangs at a time. Admins may add additional - gangs to any round. - - experiment: Gang mode now has a chance to start with a third gang. - - rscadd: Promotion of lieutenants have been re-added - - rscadd: Every lieutenant promoted will lengthen the gang's recruitment cooldowns - by one minute. - - rscdel: Only gang bosses will be able to recall the shuttle from their gangtool. - - rscadd: A recruitment pen that has not been used for a while will accumilate charges, - so you are no longer punished for waiting to convert people. - - rscadd: Gangs are now fully functional outside of gang mode. - Ricotez: - - rscadd: 'Added two categories of mutant bodyparts for humans with the same system - that lizards use: ears and tails. Right now only admins can edit these.' - - rscadd: Updated the system that checks for which jobs your character qualifies - to be species-dependant. At this moment you won't notice any differences, but - in the future coders can use this to be more specific about which jobs a species - is allowed in under which circumstances. - - imageadd: 'Added one option to both categories, taken from the kitty ears: a cat - tail and cat ears.' - - rscadd: 'Added a new button to the VV menu drop-down list for admins: Toggle Purrbation. - Putting a human on purrbation will give them cat ears and a cat tail, and send - them the message ''You suddenly feel valid.'' Using the button a second time - removes the effects.' - - wip: 'Adding categories for tattoos and scars is in the works. (Read: I need sprites!)' - oranges: - - tweak: Engineers in nanotrasen's safety equipment department announced the release - of a new and improved version of the X25 taser trigger, previous triggers, which - suffered from a long line of misfire problems were recalled enmasse. Nanotrasen - refused to comment on rumours that the previous trigger design was the work - of a saboteur. -2015-07-04: - Gun Hog: - - tweak: The Ore Redemption Machine now allows users to release minerals without - having to insert an ID first. - Ikarrus: - - bugfix: Fixed items that logically shouldn't spill, spilling their contents when - thrown - - bugfix: Fixed Bartender's non-spilling powers - - bugfix: Fixed thrown beakers not applying their contents onto floors - - bugfix: Fixed unable to transfer reagents between beakers you are holding - - bugfix: Fixed bombs shredding clothes that should have been protected by covering - clothes - - bugfix: Fixed gang mode. - MMMiracles: - - rscadd: Added patriotic underwear apparel due to the most god damn american holiday - being just around the corner. - - rscadd: Also adds some other stuff for those inferior countires too, I guess. -2015-07-05: - AlexanderUlanH & Xhuis: - - rscadd: Shadowling Ascendants have a new ability to send messages to the world. - - bugfix: Glare now properly silences targets. - - bugfix: Veil now turns off held lights. - - tweak: Drain Thralls replaced with Drain Life, which targets all nearby humans. - - rscadd: Spatial Relocation replaced with Black Recuperation which lets you revive - a dead thrall every five minutes. - - rscdel: Removed Vortex. - - tweak: Shadowlings can now only enthrall five people before being forced to hatch; - Hatched shadowlings can continue to enthrall however non-hatched ones can't - pass the global limit. - - tweak: Enthralling sends a message to all nearby humans. - - tweak: Removed cooldown on Glacial Freeze. - Ikarrus: - - tweak: Reactive armor may now teleport user to space tiles. Be careful using it - around space. - Razharas: - - tweak: Firing pins can now be removed by tablecrafting a gun with a plasmacutter, - screwdriver and wirecutters. - RemieRichards: - - imageadd: Melee attacks with weapons now display and animation of the weapon over - the target. - - rscadd: Tablecrafting window now shows all recipies and has been split into categorized - tabs. - - rscdel: 30 item limit removed. - Sabbat: - - rscadd: Updated the cult armor rune to let you get additional equipment or abilities - based on what you're wearing or holding. Some nerfed versions of wizard spells - can be used by the cult in exchange for unique clothing, these spells require - the cult robes or armor in order to use. No armor choices are mandatory, you - will always have the option of the default choice. - - rscadd: Zealot - Default armor rune. If none of the required clothing is worn - this will be chosen automatically. Is the same as ever. - - rscadd: Summoner - If you are wearing the wizard robe and hat when using the armor - rune this choice will be available. User will receive magus robes and hat and - nerfed versions of the summon shard and summon shell spells. - - rscadd: Traveler - Available to people wearing EVA suit and helmet. Replaces the - EVA suit and helmet with the cult space suit and space helmet. Gives you a sword. - - rscadd: Marauder - Available to people wearing the captain's space suit and helmet. - Same as Traveler except user is given a spell of summon creature (two creatures). - They can and will attack the user. - - rscadd: Trickster - Available if wearing the RD's reactive teleport armor. Gives - you magus robes, a wand of doors, and a nerfed version of Blink. - - rscadd: Physician - Available if wearing the CMO's labcoat. Gives you a wand of - life. - TheVekter: - - rscadd: Ian now has a dog-bed in the HoP's office. - nukeop: - - rscadd: Uplinks now have a syndicate surgery bag containing surgery tools, a muzzle, - a straightjacket and a syndicate MMI. - - rscadd: Syndicate MMIs can only be placed in cyborgs to create an unlinked cyborg - with syndicate laws. -2015-07-06: - Ikarrus: - - tweak: Increased Uzi SMG cost to 60 influence. - - tweak: Increased Uzi ammo cost to 40 influence. - - tweak: Domination attempt limit is reduced to 1 per gang while the shuttle is - docked with the station. - - tweak: Gang bosses can promote and recall the shuttle using spare gangtools - - bugfix: Fixed Gang bosses getting deconverted with head trauma - - rscadd: Lizard characters can now get random names unique from humans. -2015-07-07: - Ikarrus: - - bugfix: Fixed bug where gang messages would occasionally fail to send. - - bugfix: Fixed bug that prevented implant breakers from recruiting security. - - tweak: Implanters are now only blocked by helmets with THICKMATERIAL - - rscdel: Light severity explosions no longer shred clothes. - MMMiracles: - - rscadd: Adds a new crate to cargo in the security section, for when desperate - times call for desperate measures. - NullQuery: - - bugfix: Crew monitoring computers now sort by department and rank again. - - tweak: 'Crew monitoring computer: Hovering over a dot on the minimap will now - jump to the appropriate entry in the table.' - - bugfix: sNPCs were given ID cards with blank assignments. -2015-07-09: - AlexanderUlanH: - - rscadd: Riot Shotguns now spawn loaded with rubber pellet shells that deal high - stamina damage. - kingofkosmos: - - tweak: Both beakers and drinking glasses can now be be drunk from, fed to mobs - and splashed on mobs, turfs and most objects with harm intent. - nukeop: - - tweak: RCDs have a larger storage and can be loaded with glass, metal and plasteel. - - rscadd: Grilles and Windows can be made with an RCD. - - rscadd: Engi-Vend machine now has three RCDs. - - rscdel: Removed RCD as a steal objective. -2015-07-10: - Ikarrus: - - rscadd: 'New Changeling Ability: False Armblade Sting. It creates an undroppable - armblade on the target temporarily. It will appear exactly like a real one, - except you can''t do anything with it.' - - tweak: Transform stings are no longer stealthy. -2015-07-11: - Dorsidwarf: - - tweak: Due to a new Syndicate budget, uplink implants are now only 14 TC. - - tweak: In order to facilitate inter-agent communication, Syndicate Encryption - Keys have been reduced to 2TC. They retain the ability to intercept all channels - and speak on a private frequency. - Ikarrus: - - tweak: Robotic augmentations have been made a bit more difficult to maintain. -2015-07-13: - Ikarrus: - - imageadd: Loyalty Implant HUD Icon has been updated. - duncathan: - - tweak: Greatly shortened the time it takes to lay pipes with the RPD and to unwrench - pipes in general. - - rscadd: Added Optical T-Ray scanners to R&D and Atmospheric Technician closets. - Optical T-Ray Scanners function identically to a handheld scanner. -2015-07-14: - AnturK: - - rscadd: New species of mimic was spotted in the wilderness of space. Watch out! - Jordie0608: - - rscadd: Added a Local Narrate verb for admins. -2015-07-17: - Ikarrus: - - bugfix: Virology is no longer all-access. - - rscadd: Changelings now have the ability to swap forms with another being. - - tweak: Halved Domination Time. - - tweak: Reinforced windows and windoors are a bit more resistant to fires and blasts. - MrStonedOne: - - tweak: 'Scrubbers now use power: 10w + 10w for every gas its configured to filter. - (60w for siphon)' - - rscadd: Scrubbers can now be configured to operate on a 3x3 range via the air - alarm at a high cost (ranging from 100w to 1000w depending on how many tiles - are near it that aren't blocked and how much power it's using normally) - - tweak: Huge portable scrubbers (like in toxins storage) now use a 3x3 range rather - then a higher volume rate - - bugfix: Fixed issue with atmos not allowing low levels of plasma to spread - - bugfix: Fixed issue with atmos not adding or removing plasma overlays in some - cases - - tweak: Panic siphon now uses a 3x3 area range rather then increasing the scrubbers - intake rate by 8x - - tweak: Replace air uses 3x3 range for the first stage - - rscadd: 'Air alarms now have 3 new environmental modes:' - - rscadd: Siphon - Panic siphon without the panic, operates on a 1 tile range - - rscadd: Contaminated - Activates all gas filters and 3x3 scrubbing mode - - rscadd: Refill Air - 3 times the normal vent output -2015-07-18: - AlexanderUlanH: - - tweak: Reduced stun duration of tabling to be closer to other stuns. - Iamgoofball: - - tweak: The Bioterror Chemical Sprayer is now filled with a more deadly mix of - chemicals. - RemieRichards: - - tweak: Changelings now regenerate chemicals and geneticdamage while dead, but - only up to specific caps (50% of their max chem storage, and 50 geneticdamage) - - tweak: Fakedeath's length has been reduced from 80s dead (1 minute 20) to 40s - dead - - rscadd: Changelings now get to see the last 8 messages the person they absorbed - said, to allow them to better impersonate their victim's speech patterns - Steelpoint: - - tweak: Reduced weight of Sechailer, it now fits in boxes. - phil: - - tweak: Smoke and foam touch reactions gets buffed. - - rscadd: Reagent dispensers (watertank, fueltank) tells you how much reagents they - have left when examined. - - tweak: Liquid dark matter blob spore smoke now cannot throw you. The effects of - sorium, blob sorium, liquid dark matter and blob liquid dark matter are now - scaled by their volume. Sorium/LDM blob's touch now throws the mobs who are - close but simply moves the mobs that are further away. -2015-07-19: - Gun Hog: - - rscadd: Nanotrasen advancements in cyborg technology now allow for integrated - headlamps! As such, the flashlight package normally used as a module is now - seamlessly merged with their systems! - Ikarrus: - - rscadd: Asimov's subject of "human beings" can now be modified by uploaders. - - rscadd: Eaxmining AI modules while adjacent to them will show you what laws it - will upload. - MMMiracles: - - soundadd: Adds a TWANG sound effect when hitting things with a guitar. -2015-07-20: - AnturK: - - tweak: Lightning Bolt now always bounces 5 times and deals 15 to 50 burn damage - to each target depending on the chargeup - KorPaheron: - - rscadd: Added the Multiverse Sword, a new wizard artifact that can summon clones - of yourself from other universes, allowing for dangerous amounts of recursion. - phil235: - - tweak: Mechs no longer use object verbs and the exosuit interface tab. They now - use action buttons. Mechs now have a cycle equipment action button to change - weapon faster than by using the view stats window. Mechs get two special alerts - when their battery or health is low. Mechs now properly consume energy when - moving and having their lights on. Using a mech tool that takes time to act - now shows a progress bar (e.g. mech drill). - - rscadd: Mechs now have a cycle equipment action button to change weapon faster - than by using the view stats window. - - rscadd: Mechs get two special alerts when their battery or health is low. - - tweak: Mechs now properly consume energy when moving and having their lights on. - - rscadd: Using a mech tool that takes time to act now shows a progress bar (e.g. - mech drill). -2015-07-21: - Fayrik: - - tweak: Syndicate Donksoft gear now costs less. - Xhuis: - - rscadd: Firelocks may now be constructed and deconstructed with standard tools. - Circuit boards can be produced at a standard autolathe. - phil235: - - tweak: Thrown things no longer bounces off walls, unless they're in no gravity. - Heavy items and mobs thrown can push the mobs and non anchored objects they - land on. Throwing a mob onto a mob in no gravity will push each one in opposite - direction. Thrown mobs landing on wall, or dense object or mob gets stunned - and a bit injured. The damage when mob hit a wall is nerfed. -2015-07-23: - NullQuery: - - tweak: 'Crew monitoring: The minimap now supports scaling. You can zoom in and - out using the buttons. Hovering over an entry in the table centers the minimap - on that part of the screen.' - - tweak: 'Crew monitoring: If the window is wide enough the health indicator will - expand to show full health data (if available).' - - tweak: 'Crew monitoring: Clicking on the area name will now copy the coordinates - to your clipboard.' - - tweak: 'Crew monitoring: The AI can view health information again, but there is - a 5 second delay between updates for everyone watching.' - freerealestate: - - rscadd: Added resist hotkeys for borgs and humans. With hotkeys mode, use CTRL+C - or C as a human and CTRL+C, C or END as a borg. With hotkeys mode off, use CTRL+C - as a human and END as a borg. - xxalpha: - - bugfix: Changeling augmented eyesight night vision is now working. -2015-07-24: - Incoming5643: - - rscadd: The spells disintegrate and flesh to stone have had their mechanics changed. - Using these spells will spawn a special touch weapon in a free hand (your dominant - hand if possible) that can then be used to inflict the spell on the target of - your choice. Having the touch weapon out is obvious, this is not a stealth based - change. Clicking the spell while the hand is out will let you return the charge - without using it. - - rscdel: The spell won't begin to recharge until the hand attack is either used - or returned. Additionally these changes mean you can no longer use these spells - while stunned or handcuffed. As a suggestion remember that the mutate spell - allows you to break out of cuffs very easily, and warping abilities will keep - you from getting cuffed to begin with! -2015-07-25: - Dorsisdwarf: - - tweak: Due to a fire sale at Syndicate HQ, many of the more interesting traitor - gadgets have been cut in price dramatically. Please take this opportunity to - make full use, as we cannot guarantee that the sale will last! - bgobandit: - - bugfix: Under pressure from the Animal Rights Consortium, Nanotrasen has improved - conditions at its cat and dog breeding facilities. Cats and pugs are now much - more responsive to their owners. - duncathan: - - tweak: Restores RPD delay on disposals machines. - xxalpha: - - tweak: Agent IDs are now rewrittable. -2015-07-26: - Phil235: - - rscadd: Sechailers will now break when used too often. - - imageadd: Mechs now have new action button sprites. - Steelpoint: - - rscadd: Security Officers now spawn with a security breathmask in their internals - box. - - imageadd: Abductor's batons now changes color with modes. - - imageadd: Unique sprites for Abductor hand cuffs and paper. - goosefraba19: - - imageadd: Updated the Power Monitoring Console with better alignment and colorized - readouts. -2015-07-27: - Bgobandit: - - bugfix: Burgers can now be made from corgi meat again. - Ikarrus: - - rscadd: Added shutters to the armory to allow quick access when needed. - - bugfix: Security can now use the Brig external airlocks. - - rscadd: Added a join queue when the server has exceeded the population cap. - - tweak: Decreased the cost of Body Swap and removed it's genetic damage. - kingofkosmos: - - rscadd: Added a link to re-enter corpse to alert when your body is placed in a - cloning scanner. -2015-07-28: - Anonus: - - imageadd: New gang tags for Omni and Prima gangs. - Chiefwaffles: - - rscadd: After realizing how often AIs tend to 'disappear', Central Command has - authorized the shipment of the Automated Announcement System to take over the - AI's responsibility of announcing new arrivals. - - rscadd: In addition, users are able to configure the messages to their liking. - Early testing has shown that this feature may be vulnerable to malicious external - elements! - - rscadd: The station's R&D software has been updated so it can now succesfully - create its own prototype AAS board once the prerequisite levels have been met. - Dorsisdwarf: - - tweak: Increased the cost of Bioterror darts to 6TC. - Incoming5643: - - experiment: Double Agents no longer know they're Double Agents and not just standard - Traitors. - xxalpha: - - rscdel: Removed Anti-Drop and Nutriment Pump implants from Nuclear Operative's - uplink. -2015-07-29: - AnturK: - - rscadd: Aliens can now mine through asteroid rock. - GunHog: - - tweak: Cyborg headlamps have a short cooldown before reactivation when forcibly - deactivated. - - bugfix: Shadowling's Veil now shuts down headlamps for the ability's entire duration. - Kor: - - rscadd: Eating the heart of a Slaughter Demon will grant you dark powers. - freerealestate: - - bugfix: Fixed bug where copying with ctrl+C didn't work due to it being assigned - to resist. - - rscadd: Changed resist to B (hotkeys mode) and ctrl+B (either mode) instead. - - rscdel: Removed End resist from cyborgs. -2015-07-30: - Gun Hog: - - tweak: The Reactivate Camera power for Malfunctining AIs now costs 10 CPU, and - works on the entire camera network, up to 30 cameras fixed. - - tweak: The Upgrade Cameras power now costs 35 CPU, upgrades all cameras in the - network to have EMP proofing, X-ray, and gives the AI night-vision. - Ikarrus: - - rscadd: Door Access buttons can now be emagged to remove access restrictions. - LordPidey: - - rscadd: Added a new medication, Miner's Salve. It heals brute/burn damage over - time, and has the side effect of making the patient think their wounds are fully - healed. It is mixed with water+iron+oil, or grind a twinkie, a sheet of metal, - and a sheet of plasma. - - rscadd: Added a grinder to the mining station. - Midaychi: - - rscadd: Random loot has been added to the derelict as salvage for drones. - Scones: - - rscadd: Adds a Rice Hat to the biogenerator. -2015-08-02: - Incoming5643: - - rscadd: Syndicate toolboxes now come with never before seen red insulated gloves. - Steelpoint: - - bugfix: Fixed multiple mapping errors for Boxstation and the mining base. - - rscadd: A circuit imprinter and exosuit fabrication board have been added to tech - storage. - SvartaSvansen: - - rscadd: Our lizard engineers have worked hard and managed to improve Centcom airlocks - so they no longer disintegrate when the electronics are removed! - - tweak: Put a safety net in place so future airlocks without assemblies produce - the default assembly instead of disintegrating. -2015-08-04: - Kor: - - rscadd: Soulstones will now attempt to pull ghosts from beyond if the targeted - corpse has no soul. - Summoner99: - - rscadd: Added the *roar emote back to Alien Larva - - bugfix: Fixed aliens not being able to do the *hiss and *screech emotes - - tweak: 'Changed how the plural emote system works and now some emotes have plural - versions, example is: *hiss and *hisses.' -2015-08-05: - CoreOverload: - - rscadd: Implants, implant cases and implanters got RnD levels and can be DA'ed - for science. - - rscadd: Surgically removed implant can be placed into an implant case. Remove - implant with empty implant case in inactive hand. - - rscadd: Surgical steps now got progress bars. - - rscadd: You can cancel a surgery by using drape on operable body part again. This - works only before you perform surgery's first step. - - rscadd: Operating computer shows next step for surgeries. No more alt-tabbing - to view next step on wiki while operating. - - tweak: You cannot start two surgeries on one body part at once. You can start - two multiloc surgeries (i.e. two augumentations) on diffirent body parts at - once. - - tweak: Monkey <-> Human transformations now keep your internal organs, cyberimplants - and xeno embryos included. - Ikarrus: - - rscdel: Head beatings no longer deconvert gangsters. - LordPidey: - - rscadd: 'Added a new chemical. Spray tan. It is made by mixing orange juice with - oil or corn oil. Warning: overexposure may result in orange douchebaggery.' - Xhuis: - - rscadd: Shadowling thralls can now be deconverted via surgery or borging. - - rscadd: Thralls can be revealed by examining them. They can hide this by wearing - a mask. - - rscadd: Thralls have a few minor abilities they can use in addition to night vision. - - rscadd: Hatch-exclusive abilities can no longer be used if you are not the shadowling - mutant race. - - rscadd: Ascendants are now immune to bombs and singularities. Honk. - - rscadd: A Centcom report has been added for shadowlings. - - tweak: Ascending no longer kills all shadowling thralls. This allows antagonists - who were enthralled to succeed along with the ascendants. - - tweak: Annihilate now has different sound and a shorter delay before the target - explodes. In addition, it now works on all mobs, instead of just humans. - - bugfix: Glacial Blast now properly has no cooldown if used while phase shifting. - - bugfix: Fixes a runtime if a target with no mind is enthralled. - bgobandit: - - rscadd: Nanotrasen scientists have achieved the tremendous breakthrough of injecting - gold slime extracts with water. Pets ensued. -2015-08-06: - AnturK: - - rscadd: Adds the voodoo doll as a mining treasure, link it with a victim with - an item previously held by them. - - rscadd: Once linked the voodoo doll can be used to injure, confuse and control - the victim. - Core0verlad: - - tweak: Items can now be removed from storage containers inside storage containers. - - imageadd: Beds and bedsheets have new sprites. - - rscdel: MMIs are no longer ID locked. - KorPhaeron: - - tweak: Slaughter Demon's have had their health reduced to 200 and their speed - reduced but they get a speed boost when exiting blood. - MrPerson: - - rscadd: Items stacks now automatically merge unless thrown when moved onto the - same tile. -2015-08-07: - KorPhaeron: - - rscadd: Added a new Guardian Mob that can be summoned to manifest inside a mob. - - rscadd: Guardians can communicate with their host and materialize themselves to - protect their host with magic powers. - - rscadd: Guardians are invincible but cannot live without or too far from their - host, they also relay injuries they suffer to the host. - Phil235: - - bugfix: Fixed being able to run into your own bullet. - RemieRichards: - - rscadd: You no longer need to click on an item in a storage container to remove - it, clicking anywhere around the item works. - bustygoku: - - rscdel: Removed the chance for a disease to make you a carrier on transfer. - phil235: - - tweak: The plasma cutter's fire rate is now a bit lower but its projectile can - pierce multiple asteroid walls and its range isn't lowered in pressurized environment - anymore. -2015-08-09: - RemieRichards: - - rscadd: 'Nanotrasen Mandatory FunCo Subsidiary: CoderbusGames, would like to announce - an update to Orion Trail!' - - rscadd: 'Spaceports: Buy/Sell Crew, Trade Fuel for Food, Trade Food for Fuel, - Buy Spare Electronics, Engine Parts and Hull Plates, or maybe you think you''re - tough enough to attack the spaceport?' - - rscadd: 'Changelings: Changelings can now sneak into your crew, Changelings eat - double the standard food ration and have a chance to Ambush the rest of the - crew!' - - rscadd: 'Kill Crewmembers: Do you suspect changelings? or dont feel you have enough - food rations? Just shoot somebody in the head, at any time!' -2015-08-12: - CosmicScientist: - - rscadd: Added Space Carp costume to the code, get it from an autodrobe near you. - - rscadd: Added Ian costume to the code, take his place under the HoP's hand, get - it from an autodrobe or corgi hide, keep it away from washing machines or it'll - meat its end as clothing. - - rscadd: Added Space Carp spacesuit to the code, I know what I'm praying for. - bgobandit: - - rscadd: After multiple complaints from WaffleCo food activists, Nanotrasen has - added real chocolate, berry juice and blue flavouring to its ice cream products. -2015-08-13: - CoreOverload: - - rscadd: 'Added a new 8TC traitor item: subspace storage implant. It allows you - to store two box-sized items in (almost) undetectable storage. ' - - tweak: Changed the way most of the surgical operations work. See wiki for new - steps. - - tweak: You can cancel step 2+ surgeries with drapes and cautery in inactive hand. - - tweak: Defib no longer works on humans who have no heart. Changeling/thrall/cult/strange - reagent revives are still working, and this is intended. - - rscadd: You can eat all organs raw now, with exception for brains and cyberimplants. - - rscadd: Some xenos abilities are linked to their organs. Play with xenos' guts - for fun and profit! - RemieRichards: - - rscadd: Modifying a string (Text) variable with View Variables or View Variables - Mass Modify now allows you to embed variables like real byond strings, For example - the variable real_name; you could set a text var to [real_name] and it would - be replaced with the actual contents of the var, This allows for Mass fixing - of certain variables but it's also useful for badmin gimmickery -2015-08-15: - Miauw: - - rscadd: Changeling transformations have been upgraded to also include clothing - instead of just DNA. - - tweak: Patches no longer work on dead people. - - rscadd: Added 15-force edaggers that function like pens when off. - MrPerson: - - rscadd: Objects being dragged will no longer get shoved out of your grasp by space - wind. Retrieving dead bodies should be possible. - RemieRichards: - - rscadd: Added Changeling Team Objectives, these are handed out to all lings, with - the chance of a round having one being 20*number_of_lings% (3 lings = 60%) - - rscadd: 'Impersonate Department (Team Objective): As many members of a department - as can reasonably be picked are chosen for the lings to kill, replace and escape - as' - - rscadd: 'Impersonate Heads (Team Objective): 3 to 6 Heads of Staff are chosen - for the lings to kill, replace and escape as' - - tweak: If the Changelings have a Team Objective, their usual Kill, Maroon, Etc. - objectives will not pick other changelings, to discourage backstabbing in teamling - - tweak: Changeling Engorged Glands is now the default storage and regen rate, Engorged - Glands remains for an extra boost - - rscadd: Armblades can now be used to open powered doors, however it takes 10 seconds - of the changeling standing still, Their ability to instantly open unpowered - doors remains unchanged - - rscdel: Debrain objective is no longer handed out to lings, it's as good as broken - these days - - rscadd: Changelings may now purchase a togglable version of the Chameleon Skin - genetics mutation, for 2 DNA -2015-08-16: - Joan: - - rscadd: Revenants will now occasionally spawn as an event. - - tweak: Revenants gain more energy from Harvesting, and can Harvest from people - in crit. - - tweak: Revenant powers are more effective, and no longer freeze you in place, - besides Harvest. - - tweak: Slain Revenants will respawn much faster. - - bugfix: Fixed a whole bunch of revenant bugs, including one that caused the objective - to always fail. - Kor: - - rscadd: The wizard can now stop time. - MMMiracles: - - tweak: Revamps bioterror darts into a less-lethal, syringe form. Removed the coniine - and spore toxins to keep it solely for quiet take-downs. -2015-08-18: - CoreOverload: - - rscadd: Added a new low-tech eye cyberimplant in RnD - welding shield implant. - - rscadd: Implanter and empty implant case added to protolathe. - - rscadd: You can sell tech disks and maxed reliability design disks in cargo for - supply points. - - tweak: DA menu shows current research levels. - - tweak: You can print cyberimplants in updated mech fab. - Supermichael777: - - bugfix: Added an ooc hotkey for borgs = O. They simply didn't have one and it - was a consistency issue - - rscadd: Also added Ctrl+O as an any mode keycombo so you dont have to backspace - and type ooc. Added to hotkey mode to remain consistent with all other Ctrl - combos - bustygoku: - - tweak: Most backpacks now have 21 or more slots, but are still weight restricted. - What this means is that you can have a lot of tiny weight items, but only 7 - medium items just like before. - phil235: - - tweak: Janicart rider no longer slip on wet floor or bananas. Moving on a floor - tile with lube while buckled (chair, roller bed, etc) will make you fall off. -2015-08-19: - Joan: - - rscadd: Added a new revenant ability; Malfunction. It does bad stuff to machines. - - tweak: Defile and Overload Lights now briefly stun the revenant. - - tweak: You can now Harvest a target by clicking on them while next to them. - - bugfix: Harvesting no longer leaves you draining if the target is deleted mid-drain - attempt. - - rscdel: Defile no longer emags bots or disables cyborgs, Malfunction does that - now. - Kor: - - rscadd: The Ranged and Scout guardian types have been merged, and gained a new - surveillance snare ability. - SconesC: - - rscadd: Added Military Belts to traitor uplinks. - bgobandit: - - rscadd: CentComm now offers its cargo department toys, as well as detective gear - so their boss can figure out which tech wasted all the points on them. - phil235: - - rscadd: You can now partially protect yourself from blob attack effects by wearing - impermeable clothes like hardsuits, medical clothes, masks, etc. Max protection - effect is capped at 50%. - - rscdel: Splashing someone with chemicals no longer injects those chemicals in - their body. - - bugfix: Fixes splashing acid on items or floor with items not having any effect. -2015-08-28: - bgobandit: - - bugfix: 'Overheard at CentComm: ''This burn kit said salicyclic acid would heal - my burns! WHO MADE THIS SHIT?'' A muffled honking is heard in the background. - (Burn first-aid kits now contain an appropriate burn pill.)' - - rscadd: Oxandrolone, a new burn healing medication, has been added to burn first-aid - kits and to chemistry. Ingesting 25 units or more causes burn and brute damage. -2015-09-01: - Dorsidwarf: - - tweak: Changelings' Digital Camoflague ability now renders them totally invisible - to the AI - ExcessiveUseOfCobblestone: - - rscadd: Added health analyzer to the autolathe. - - tweak: Moved Cloning board to Medical Machinery section. - - tweak: Moved Telesci stuff to Teleporter section. - Fox P McCloud: - - tweak: Adds the emitter board to to the circuit imprinter for R&D. - Gun Hog: - - tweak: The Disable RCD Malfunction power is now Destroy RCDs! It costs 25 CPU - (down from 50), causes RCDs to explode, can be used multiple times, and no longer - affects cyborgs. - Kor: - - rscadd: Revheads and Gang leaders now spawn with chameleon security HUDs, for - keeping track of loyalty implanted crew. - - rscadd: Syndicate thermals now have a chameleon function as well, allowing you - to disguise the goggles to match your job. - Miauw: - - tweak: Edaggers actually work now and have been buffed to 18 brute and 2 TC. - Oisin100: - - rscadd: Nanotransen discover ancient human knowledge confirming that trees produce - Oxygen From Carbon Dioxide - - tweak: Trees now require Oxygen to live. And will die in extreme temperatures - Xhuis: - - rscadd: The arcade machines have been stocked with a xenomorph action figure that - comes with realistic sounds! - - rscadd: Darksight now has its own icon. - - rscadd: Empowered thralls have been added. While obvious, they are more powerful - and can resist dethralling while conscious. Only 5 can exist at one time. - - rscadd: Shadowlings can now change their night vision radius by using the action - button their eyes (glasses) now provide. - - tweak: Torches are dimmer, being as bright as flashlights, and no longer fit on - belts. - - tweak: Black Recuperation now has a 1 minute cooldown, down from 5. It can also - be used to empower living thralls. - - tweak: Guise can now be used outside of darkness and makes the user more invisible - than before. - - bugfix: Enthrall now functions properly when a shadowling is not hatched, allowing - them to enthrall up to 5 people before hatching. - xxalpha: - - tweak: Blood crawling is now a spell. - - rscadd: Engineering cyborgs now have a constant magpulse. - - tweak: Changed foam spreading to be like gas spreading. -2015-09-05: - Shadowlight213: - - rscadd: The syndicate have taken notice of the camera bug's woeful underuse, and - have managed to combine all of its upgrades into one! -2015-09-06: - Fox P McCloud: - - bugfix: Fixes gold sheets having plasma as their material. - Xhuis: - - bugfix: Nanotrasen inspectors have discovered a fault in the buckles of chairs - and beds. This has been fixed and you are now able to buckle again. -2015-09-07: - xxalpha: - - tweak: Changed xeno weed spread to be like gas spread. -2015-09-09: - Joan: - - rscadd: New blob chemical; Cryogenic Liquid. Cools down targets. - - tweak: Tweaked names, colors, and effects of remaining blob chemicals; - - tweak: Skin Ripper is now Ripping Tendrils and does minor stamina damage, in addition - to the brute damage. - - tweak: Toxic Goop is now Envenomed Filaments and injects targets with spore toxin - and causes hallucinations, in addition to the toxin damage. - - tweak: Lung Destroying Toxin is now Lexorin Jelly and does brute damage instead - of toxin damage. The oxygen loss it causes can also no longer crit you in one - hit. - - tweak: Explosive Gelatin is now Kinetic Gelatin and does random brute damage, - instead of randomly exploding targets. - - rscdel: Skin Melter, Radioactive Liquid, Omnizine, and Space Drugs blob chemicals - are gone. - bgobandit: - - rscadd: Nanotrasen has commissioned two new corporate motivational posters for - your perusal and edification. - - rscadd: Nanotrasen also wishes to remind the crew that non-authorized posters - ARE CONTRABAND. Especially those new ones with Rule 34. Perverts. -2015-09-11: - CosmicScientist: - - tweak: Drone dispenser now has a var for its cooldown, get var editing. -2015-09-13: - Fox P McCloud: - - bugfix: Fixes an exploit and inconsistency issue with a few material amounts on - a few items and designs. - - bugfix: Fixes Bibles/holy books not properly revealing runes. - - bugfix: fixes stimulants not properly applying its speedbuff. - Gun Hog: - - tweak: Nanotrasen scientists have proposed a refined prototype design for the - nuclear powered Advanced Energy guns to include a taser function along with - the disable and kill modes. Addtionally, they have modified the chassis blueprint - to include a hardpoint for attachable seclites. - Iamgoofball: - - tweak: Reduced the cost of changeling armor to 1 and increased it's armor values. - Jordie0608: - - rscadd: You can now view the reason of a jobban from character setup. - xxalpha: - - rscadd: Drying agent splashed on galoshes will turn them into absorbent galoshes - that dry wet floors they walk on. - - rscadd: Drying agent can be made with ethanol, sodium and stable plasma. -2015-09-14: - Fox P McCloud: - - tweak: Adds a mining voucher to the Quartermaster's locker. - Thunder12345: - - rscadd: The captain has been issued with a new jacket for formal occasions. - - tweak: Research has shown that is is possible to build technological shotshells - without the need for silver. The design blueprints supplied to your station - have been updated accordingly. - xxalpha: - - bugfix: Fixed not being able to grab things from storage while inside aliens. - - bugfix: Fixed two progress bars when devouring. - - rscadd: Shields will now block alien hunter pounces. - - tweak: Alien hunters health reduced to 125 from 150. Alien sentinels health increased - to 150 from 125. - - tweak: Alien hunters will no longer be transparent when stalking, this ability - was given to alien sentinels. - - tweak: Alien slashing now deals constant 20 damage but has a chance to miss. - - tweak: Reduced alien disarm stun duration vs cyborgs, from 7 seconds to 2 seconds. - - tweak: Alien sentinels now move as fast as humans. - - tweak: Facehuggers and alien eggs layers increased to be higher than resin walls. -2015-09-16: - Razharas: - - tweak: Replaces the space cube with space torus. Space levels are now each round - randomly placed on the grid with at least one neigbour, any side of the space - level that doesnt have neigbour will loop either onto itself or onto the opposite - side of the furthest straight-connected space level on the same axis. - Supermichael777: - - tweak: The detomax pda cartridge no longer blows its user up. - Xhuis: - - experimental: Cultists will now be able to create all runes without needing to - research or collect words. This is subject to change. - - tweak: Cult code has been significantly improved and will run much faster and - be more responsive. - - tweak: Conversion runes can now be invoked with less than three cultists, but - take a small amount of time to convert the target. - - tweak: Armor runes will only outfit the user with standard armor, rather than - having different loadouts for different worn clothing items. - - tweak: Astral Journey runes will now pull the user back to the rune if they are - moved. The user also has a different color while on the rune. - - tweak: Free Cultist has been removed. Summon Cultist now works even if the target - is restrained. - - tweak: Sacrifice and Raise Dead runes now offer more precise target selection. - - soundadd: Sacrifice runes now have different sounds, and gib rather than dust - (assuming the target is not a silicon). - - tweak: There is no longer a maximum cap on active runes. - - tweak: Runes have been renamed to Rites. For instance, the Teleport rune is now - the Rite of Translocation. The only exception to this is the rune to summon - Nar-Sie, which is a Ritual. - - tweak: Nar-Sie now has a new summon sound. - - tweak: The Nar-Sie summon rune has a new 3x3 sprite. - - tweak: The stun rune no longer stuns cultists. - - rscadd: The Rite of False Truths had been added, that will make all nearby runes - appear as if they were drawn in crayon. - - rscadd: Runes can now be examined by cultists to determine their name, function, - and words. - phil235: - - tweak: Riot and energy shield users now have a chance to block things thrown at - them as well as xeno leaping at them. -2015-09-17: - bgobandit: - - rscadd: Meatspikes can now be constructed and deconstructed with metal and rods, - as well as wrenched and unwrenched! Humans and corgis can be used on them as - well. - xxalpha: - - tweak: 'Reworked nuke deconstruction: Standardized steps, partial reparation (use - metal) to contain radiation.' - - rscadd: New portable nuke, self-destruct terminal, syndie screwdriver sprites - by WJohnston. -2015-09-19: - Xhuis: - - rscadd: Shadowlings are now able to sacrifice a thrall to extend the shuttle timer - by 15 minutes. This will not stack. - - bugfix: Additional abilities granted by Collective Mind will now properly have - icons. - - bugfix: Shadowlings now have their antagonism removed if turned into a silicon. - - tweak: The order of abilities unlocked by Collective Mind has been changed. It - now starts with Sonic Screech. - - tweak: Veil now destroys glowshrooms in a much larger radius than before. -2015-09-20: - Xhuis: - - tweak: Rites have been renamed to their old runes, which reflect their functionality. - - tweak: Examining a talisman no longer opens the paper GUI. - - tweak: Armor talismans have been re-added. - - tweak: EMP talismans now have the same range as their rune counterpart. - - tweak: Some talismans now cost health to use, costing more or less depending on - their effect. - - tweak: Scribing runes now deals 0.1 brute damage instead of 1. - - tweak: Bind Talisman runes no longer deal 5 brute damage when invoking. - - tweak: Rune shapes and colors are now identical to their old versions. - - tweak: Conversion runes can no longer be used by yourself, and require a static - 2 cultists. -2015-09-22: - Kor: - - rscadd: A new admin command, Offer Control to Ghosts, can be found in the view - variables menu. It will randomly select a willing candidate from among dead - players, providing a fair method of replacing antagonists. - Xhuis: - - tweak: When a morph changes form, a message is shown to nearby people. This also - happens upon undisguising. - - tweak: Morphs now have an attack sound and message. - - tweak: The Spawn Morph event now plays a sound to the chosen candidate. - - tweak: Slaughter demons (and other creatures with blood crawl) now take two seconds - to emerge from blood pools. Entering is still instantaneous. - - tweak: The demon heart's sprite has been updated. - - tweak: Eating a demon heart now surgically implants the heart into your chest. - If the heart is removed from you, you lose the ability. Someone else can eat - the heart to gain the ability. - - tweak: Blood Crawl no longer has a 1-second cooldown, instead having none. - - tweak: You can no longer hold items when attempting to Blood Crawl, nor can you - use any items while Blood Crawling. - - tweak: Creatures that can Blood Crawl now take two seconds to emerge from blood - pools. - - tweak: Slaughter demons now store devoured creatures, and will drop them upon - death. - - tweak: Revenants now have the ability to speak to the dead. - - tweak: Revenant abilities now have icons. - - tweak: Malfunction no longer EMPs a specific area - it will instead EMP nearby - machines directly and stun cyborgs. Dominators are immune to this. - - tweak: Revenants now have directional sprites. - - tweak: Overload Lights now has a smaller radius. - - tweak: Defile no longer corrupts tiles. - - tweak: When glimmering residue reforms, the game will attempt to place the old - revenant in control of the new one. If this cannot be done, it will find a random - candidate. - - tweak: Revenants can no longer see ghosts. They can see other revenants, however, - and ghosts can still see revenants. - - tweak: The Spawn Slaughter Demon event now plays a sound to the chosen candidate. - phil235: - - rscdel: Lizards and other non human species can no longer acquire the hulk mutation. - Hulks no longer have red eyes - - bugfix: Monkeys now always have dna and a blood type (compatible with humans). - - bugfix: Monkey transformation no longer deletes the human's clothes. - - bugfix: Space Retrovirus now correctly transfers dna SE to the infected human. - - bugfix: Changeling's Anatomic Panacea removes alien embryo again. - - bugfix: Cloning someone now correctly sets up their dna UE. - - bugfix: Fixes the laser eyes mutation not giving glowing red eyes to the human. - - bugfix: Using changeling readaptation now properly removes all evolutions bought - (arm blade, chameleon skin, organic suit). - xxalpha: - - rscadd: Added a researchable cyborg self-repair module to the robotics fabricator. -2015-09-23: - Xhuis: - - rscadd: Syndicate medical cyborgs have been added. - - rscadd: The Dart Pistol is now available from the uplink for 4 telecrystals. It - functions as a pocket-sized syringe gun with a quieter firing sound. - - tweak: Boxes of riot foam darts now cost 2 telecrystals, down from 10, and are - available to traitors. - - tweak: Foam dart pistols now cost 3 telecrystals, down from 6. - - tweak: Syndicate cyborg teleporters now allow a choice between Assault and Medical - cyborgs. - - tweak: Syndicate cyborgs are now distinguished as Syndicate Assault. - - tweak: Syndicate cyborg energy swords now cost 50 energy per use, down from 500. - - tweak: Airlock charges now cost 2 telecrystals, down from 5. - - tweak: Airlock charges are much more powerful. - - tweak: There is no longer a 25% chance to detonate an airlock charge while removing - it. - - tweak: The description of many uplink items has been changed to better reflect - their use. -2015-09-24: - Jordie0608: - - tweak: Advanced energy guns now only critically fail after successive minor failures. - Cease firing after multiple recent minor failures to avoid critical ones. - Kor: - - rscadd: Guardian Spirit types and powers have been heavily reworked. Full details - of each type are available on the wiki. - - rscadd: Guardian damage transfer to users now deals cloneloss if their user is - in crit. - - rscadd: Guardians are now undergoing a trial run in the traitor uplink, under - the name of Holoparasites. - - rscadd: You can now hang human mobs (dead or alive) from meatspikes. Escaping - the meatspike will further damage the victim. - - rscdel: You can no longer slam humans into the meatspike as an attack. -2015-09-25: - Xhuis: - - rscadd: Changelings have a new ablity, Biodegrade. Costing 30 chemicals and having - an unlock cost of 1, it allows them to dissolve handcuffs and straight jackets - in 3 seconds, and escape from lockers in 7. - - tweak: Fleshmend's effectiveness is now halved each time it is used in a short - time span. - - tweak: Last Resort now blinds and confuses nearby humans and briefly disables - silicons upon use. - - tweak: Headslugs now have 50 health, up from 20. -2015-09-26: - MMMiracles: - - rscadd: Nanotrasen's genetic researchers have rediscovered the inactive dwarfism - genetic defect inside all bipedal humanoids. Suffer not the short to live. - WJohnston: - - tweak: Repiped the entire station. Atmosia and the disposals loop were not touched. - - tweak: Moved mulebot delivery from misc lab to RnD. -2015-09-28: - Feemjmeem: - - bugfix: Rechargers can now be wrenched and unwrenched by cyborgs. - - bugfix: Rechargers no longer stop working forever if you move them from an unpowered - area to a powered area, and now actually look powered off when they are. - - bugfix: Guns and batons can no longer be placed in unwrenched chargers. - Razharas: - - rscadd: Added button to preferences menu that kills all currently playing sounds - when pressed, now you can kill midis and any other sounds for real. - phil235: - - bugfix: Fixed the syndicate cyborg's grenade launcher. - - tweak: You can modify the dna of corpses again. -2015-09-29: - Kor: - - bugfix: The Chaos holoparasite can now actually set people on fire properly. - - tweak: Guardian powers are now used via alt+click rather than shift+click. - - tweak: Added an alert chime for ghosts when someone is summoning a Guardian. -2015-10-04: - Fox P McCloud: - - tweak: Adds a bar of soap to the janitor's locker. - - rscadd: Re-adds the advanced mop as a researchable R&D item. - - rscadd: Adds a bluespace trashbag as a researchable R&D item; can hold large quantities - of garbage. - Jordie0608: - - rscadd: Added Special Verb 'Create Poll', an in-game interface to create server - polls for admins with +permissions. - MrPerson: - - rscdel: Removed NTSL. Sorry. People could write scripts that crashed the server, - and this is the only thing that can be done to prevent them from doing that. - MrStonedOne: - - rscdel: Removed feature where quick consecutive ghost orbits while moving could - be used to fuck with your sprite - - bugfix: Fixed ghosts losing floating animation when returning from an orbit - - bugfix: Fixed logic error that prevented orbit's automatic cancel when the orbiting - thing moved in certain situations. - - rscadd: Ghost Orbit size now changes based on the icon size of the thing they - are orbiting (for that sweet sweet singulo orbiting action) - - tweak: Removed needless checks in ghost orbit, you can now orbit yourself and - restart an orbit around the thing you are already orbiting - Xhuis: - - rscadd: Syndicate Medical cyborgs now have cryptographic sequencers. - - rscdel: Syndicate Medical cyborgs no longer have syringes. - - tweak: Restorative Nanites now heal much more damage per type. - - bugfix: Operative pinpointers now actually point toward the nearest operative. - - bugfix: Syndicate Assault cyborgs no longer start with medical supplies. - - bugfix: Energy saws now have a proper icon. - - bugfix: Non-operatives can now longer use operative pinpointers or Syndicate cyborg - teleporters. - - tweak: Doctor's Delight now requires cryoxadone in its recipe instead of omnizine. - - tweak: Doctor's Delight now restores half a point of brute, burn, toxin, and oxygen - damage per tick. - - tweak: Doctor's Delight now drains nutrition while it's in your system (that is, - unless you're a doctor). - - bugfix: Syndicate roboticists have given Syndicate medical cyborgs sharper hypospray - needles - they are now able to penetrate armor. -2015-10-06: - Gun Hog, for WJohnston: - - rscadd: 'Add new Xenomorph caste: The Praetorian. Drones may become this on their - way to growing into a full queen, and a queen may promote one if there is not - one already.' - - tweak: Xenomorph queens are now GIGANTIC, along with the new Praetorian. Together, - they are considered royals. - - tweak: Queens are now significantly tougher to make up for their huge size. - - bugfix: All forms of dead xenomorph may now be grabbed and placed on a surgery - table for organ harvesting! - Xhuis: - - rscadd: Maintenance drones now have a more descriptive message when examined. - - tweak: A recent Nanotrasen firmware update to drones has increased vulnerability - to foreign influences. Please periodically check drones for abnormal behavior - or status LED malfunction. Note, however, that cryptographic sequencers will - not incur this behavior. - - tweak: In response to complaints about rogue drones, Nanotrasen engineers have - allowed factory resets on all drones by simply using a wrench. - - experiment: Central Command reminds drones to immediately retreat, if possible, - when a law override is begun. Not doing so may anger the gods and incur their - wrath! - - rscadd: Some virus symptoms that had no messages now have them. - - rscadd: 'New virology symptom: Weakness. This will cause stamina damage and fainting - spells.' - - tweak: Many virus symptom messages have been changed to be more threatening. -2015-10-07: - Kor: - - rscadd: The alien queen can now perform a tail sweep attack, throwing back and - stunning all nearby foes. -2015-10-13: - AnturK: - - rscadd: Display cases can now be built using 5 wood planks and 10 glass sheets. - - rscadd: Add airlock electronics to open it with id later, otherwise you'll have - to use crowbar - - tweak: Broken display cases can be fixed with glass sheets or removed using crowbar - - tweak: Added start_showpiece_type variable for mappers to create custom displays - - rscadd: Syndicate Lone Operatives spotted near the nanotrasen stations! Keep the - disk safe! - - tweak: Admin spawned nuclear operatives will now have access to nukeop equipment - Gun Hog: - - rscadd: Nanotrasen's research team has released a new, high tech design for Science - Goggles, which previously did nothing! They new come fitted with a portable - scanning module which will display the potential research data gained from experimenting - with an object. Nanotrasen has also released drivers which shall enable the - prototype hardsuit's built in scan visor. - - rscadd: Supporting this new design, Nanotrasen has seen fit to provide blueprints - for Science Goggles to the station's protolathe. - Kor: - - tweak: Gang implanters now only break implants/deconvert gangsters, meaning you - will have to use a pen to convert them afterwards. - - rscadd: An important function, accessible via alt+click, has been restored to - the detectives hat. - - sounddel: When Nar-Sie is created, they now use the old sound effect. - Steelpoint: - - rscadd: The Chief Medical Officers 'Medical Hardsuit' has been added to the CMO's - office. Boasts the usage of lightweight materials allowing fast movement while - wearing the suit as well as complete biological protection to airborne and similar - pathogens. - - rscadd: The Head of Security's personal 'HoS Hardsuit' has been added to the HoS's - office. This Hardsuit is slightly more armored than the regular Security Hardsuit. - - rscadd: The Research Directors 'Prototype Hardsuit' has been added to the RD's - office. This Hardsuit offers the highest levels of protection against explosive, - as well as biological, attacks, as well as fireproofing. - - rscdel: The Command EVA space suits, due to budget concerns, have been removed - and reloacted to another space station. - Xhuis: - - rscdel: All instances of autorifles have been removed from Security. - - rscadd: The armory has been re-mapped. - - tweak: The spell book has received a rebalancing! There are now ten uses by default, - but most spells cost two uses. Some underused spells, like Blind, Smoke, and - Forcewall, only cost a single use. - - experiment: After searching through the Sleeping Carp's ancient monastery in deep - space, more secrets have been uncovered of their traditional fighting techniques. - - tweak: Members of the Sleeping Carp gang are now able to deflect all ranged projectiles. - - tweak: Members of the Sleeping Carp gang are now uanble to use any type of ranged - weaponry. Doing so would be dishonorable. - - tweak: The Sleeping Carp martial art's effects are more damaging, and many stuns - have been increased in duration. - phil235: - - bugfix: Fixes critical bug causing multiple hits from single projectile. - - bugfix: Fixes not being able to shoot a mob on same tile as the shooter. - - bugfix: Clicking your mob (without targeting your mouth) no longer causes you - to shoot yourself. - - bugfix: Fixes not being able to shoot non human mobs at point blank. - - rscdel: Morphs no longer automatically drop the things they swallowed, you have - to butcher their corpse to retrieve their contents. - - bugfix: butchering a corpse no longer also attacks it. - - rscdel: Dipping cigarette (to asbsorb liquids) in a glass can now only be done - with an unlit cigarette. Lit cigarette now heats up the glass content (like - other heat sources). - - bugfix: Fixes trashbag not being able to pickup drinks and ammo casings. - - tweak: Slimes now attaches themselves to mobs via buckling. -2015-10-16: - MrStonedOne: - - rscadd: Added a reconnect option to the file menu. This will allow you to reconnect - to the game server without closing and re-opening the game window. This should - also prevent another byond ad from playing during reconnections. - Xhuis: - - rscadd: A gamebreaking bug has been fixed with buckets. You can now wear them - on your head. - bgobandit: - - rscadd: The Grape Growers Consortium has complained that Nanotrasen kitchens do - not use their products enough. HQ has come up with a few recipes to pacify them. - Goddamn winos. -2015-10-19: - AnturK: - - rscadd: Handheld T-Ray Scanners now detect critters in pipes. - Kor: - - tweak: Weapons and projectiles that are armour piercing now have an increased - chance to bypass riot shields. - - tweak: Slipping on lube now deals slightly more damage, but is concentrated on - a random body part, rather than spread to your entire body. - - tweak: Slipping on water no longer deals damage - - rscadd: You can now attach grenades and C4 to spears to create explosive lances. - This is done via table crafting. Alt+click the spear to set a war cry. - Shadowlight213: - - rscadd: In response to reports of stranded drones, Nanotrasen has added magnets - to drone legs. They are no longer affected by lack of gravity or spacewind! - - bugfix: Drones can now set Airlock access on RCDs. - bgobandit: - - rscadd: Nanotrasen loves recycling! In the highly unlikely occasion that your - space station accumulates gibs, scoop 'em up and bring them to chemistry to - recycle into soap, candles, or even delicious meat product! - - rscadd: L3 biohazard closets now contain bio-bag satchels for the safe collection - of biowaste products, such as slime extracts. - phil235: - - rscdel: Removing Smile, Swedish, Chav and Elvis mutations from genetics. These - mutation can still be acquired via adminspawned dna injector. - - rscadd: Added a dna injector for laser eyes mutation for admin use. - - bugfix: Fixes winter coat hood sprite appearing as a bucket. - - bugfix: Fixes using razor on non human shaving non existent hair. - - bugfix: Fixes chair deconstruction dropping too much metal. - - bugfix: Fixes snapcorn not giving seeds. - - bugfix: Fixes portable chem dispenser. - - tweak: Changing the transfer amount of all reagent containers (beaker, bucket, - glass) is now done by clicking them, similar to spray. Reagent dispensers (watertank, - fueltank, pepperspray dispenser) no longer have their own transfer amounts and - use the reagent container's transfer amount instead (except for sprays which - get 50u for faster refilling). -2015-10-23: - Incoming5643: - - rscadd: 'Syndicate bomb payloads will now detonate if set on fire long enough. - Note that the casings for the bombs is fireproof, so if you want to set fire - to a bombcore you''ll need to remove it from the case first (cut all wires, - then crowbar it out). A reassurance from our explosives department: it is, and - always has been, impossible to detonate a syndicate bomb that isn''t ticking - with wirecutters alone.' - Xhuis: - - rscadd: Geiger counters have been added and are obtainable from autolathes and - EngiVends. They will measure the severity of radiation pulses while in your - pockets, belt, or hands. One can scan a mob's radiation level by switching to - Help intent and clicking on it. These counters never really discard the radiation - they store, and rumor has it this can be used in nefarious ways... - - tweak: When a mob is impacted by radiation, the radiation is now relayed to all - items on the mob. -2015-10-24: - Kor: - - rscadd: The friendly gold slime reaction now spawns three mobs. - phil235: - - tweak: Changed the effects of alcohol to be more realistic. The effects of alcohol - now appear twice as fast. Drunkenness now scales with how much alcohol is in - you, not how long you've been drinking. This means drinking very little but - continuously no longer makes you very drunk, or confused/slurring for a long - time or give you alcohol poisoning. The dizziness and slurring effects now properly - scale with how drunk you are (and dizziness is generally more pronounced). -2015-10-25: - Incoming5643: - - rscadd: The spell Charge has been added to the spellbook. It can be used to extend - the life of magic and energy weapons and even reset the cooldowns of held wizards! - It cannot reset your own cooldowns. - - rscadd: The Staff of Healing has been added to the spellbook. Heals all damage - and raises the dead! Can't be used on yourself however. - - bugfix: The exploit that allowed you to use the staff of healing on yourself by - suicide has been fixed. - Jordie0608: - - rscadd: You can now selectively mute non-admin players from OOC with the Ignore - verb in the OOC tab. - Tkdrg: - - rscadd: Added chainsaws. They can be tablecrafted using a circular saw, a plasteel - sheet, some cable coil, and a welding tool. Don't forget to turn it on! -2015-10-26: - Fox P McCloud: - - tweak: Standardizes the slowdown of most spacesuits to 1 as opposed to 2. - Incoming5643: - - rscadd: 48x48 pixel mode (x1.5 zoom) has been added to the Icons menu (top left). - While playing in 32x32 or 64x64 will still provide a clearer looking station, - for those of us with resolutions that fall into the gap between the two zooms - this can provide a more consistant looking station than stretch to fit. - - rscadd: 96x96 pixel mode (x3 zoom) has also been added for our players who enjoy - looking at spacemen on their 4k monitors at a crisp and consistent scale. - - tweak: The lich spell has been subjected to some gentle nerfing. When you die - a string of energy will tie your new body to your old body for a short time, - aiding others in determining your location. The duration of this beam scales - with the number of deaths you've avoided. - - tweak: Additionally the post revival stun now also scales in this way. - - tweak: The spell will also fail if the item and the wizard don't share the same - z level, though the nature of space means the odds of the item (or the wizard) - looping around back to the station is pretty high. - - rscadd: The spell is still really good. -2015-10-27: - Joan: - - bugfix: You can now click on things under timestop effects, instead of clicking - the effect and looking like a fool. - Kor: - - rscadd: Added a zombie mob that turns its kills into more zombies. Currently adminspawn - and xenobio only. - - rscadd: Using water with a red slime extract will now yield a speed potion. Using - the speed potion on an item of clothing will paint it red and remove its slowdown. - MrStonedOne: - - rscadd: You may now access the setup character screen when not in the lobby via - the game preferences verb in the preferences tab - - rscadd: The round end restart delay can now be configured by server operators. - New servers will default to 90 seconds while old servers will default to the - old 25 seconds until they import the config option to their server. -2015-10-28: - Tkdrg: - - rscadd: Added a Ghost On-screen HUD. It can be toggled using the "Toggle Ghost - HUD" verb. Thank you Razharas for the sprites! - - rscadd: Ghosts can now use the "Toggle med/sec HUD" verb to see the basic secHUD - (jobs only) or the medHUD of humans. - - rscadd: Ghost will now get clickable icon alerts from events such as being put - in a cloner, drones being created, Nar-sie being summoned, among others. The - older chat messages were kept. These alerts can not be toggled. -2015-10-29: - Kor: - - tweak: Slightly changed what items spawn on the captain vs in his locker, hopefully - saving some annoying inventory shuffle at roundstart. -2015-10-30: - Incoming5643: - - rscadd: Slimepeople can now split if they contain 200 units of slime jelly, and - slimepeople will now slowly generate slime jelly up to 200 units provided they - are very well fed. Split slimepeople are NOT player controlled, but rather the - original slime person can swap between the two mobs at will. If one of the slimepeople - should die under player control, the player won't be able to swap back to their - living body. Splitting only creates a new body, any items you have on you are - not duplicated. - - rscadd: Slimepeople now take half damage from sources of heat, but double damage - from sources of cold. Lasers good, Space bad. -2015-11-01: - Gun Hog: - - rscadd: Nanotrasen listens! After numerous complaints and petitions from Security - personnel regarding energy weapon upkeep, we have authorized the construction - and maintenance of your station's weapon rechargers. As an added bonus, we have - also provided a more modular design for the devices, allowing for greater recharge - rates if fitted with a more efficient capacitor! - - rscadd: Added Diagnostic HUDs! They can be used to view the health and cell status - of borgs and mechs. Silicons have them built in, Roboticists get two in their - locker, and the RD's hardsuit has one built in. - Incoming5643: - - rscadd: The number of roundstart head revolutionaries nows depends on the roundstart - security force as well as the roundstart heads - - rscadd: The maximum number of head revs is 3, the minimum is 1. If there is fewer - than three station heads there will never be more than that number of head revs - at roundstart. For every three vacant security roles (Head of Security/Warden/Security - Officer/Detective) at roundstart the number of starting head revs will be reduced - by 1. - - rscadd: Head revolutionaries can be gained during play if the security/head roles - are filled. They are drawn from existing revolutionaries. - - rscadd: Added dental implant surgery. While targeting the mouth drill a hole in - a tooth then stick a pill in there for hands free later use. - Kor: - - rscadd: Added an experimental control console for Xenobiology. Ask the admins - if you'd like to try it out. It may not work on maps other than Box if they - have renamed the Xenobiology Lab. - - rscadd: Injecting blood into a cerulean slime will yield a special one use set - of blueprints that will allow you to expand the territory your camera can cover. - Kor and Remie: - - rscadd: Added as series of laser reflector structures, the frame of which can - be built with 5 metal sheets. - - rscadd: Completing the frame with 5 glass sheets creates a mirror that will reflect - lasers at a 90 degree angle. - - rscadd: Completing the frame with 10 reinforced glass sheets creates a double - sided mirror that reflects lasers at a 90 degree angle. - - rscadd: Completing the frame with a single diamond sheet creates a box that will - redirect all lasers that hit it from any angle in a single direction. - MMMiracles: - - tweak: Energy Swords can now embed when thrown for a 75% chance. Embedding -2015-11-05: - AnturK: - - rscadd: Added wild shapeshift spell for wizards. -2015-11-08: - Cuboos: - - soundadd: Added a new and better sounding flashbang sound and a ringing sound - for flashbang deaf effect - JJRcop: - - tweak: Chronosuits have had their movement revised, they now take time to teleport - depending on how far you've traveled, and don't teleport automatically anymore - unless you stop moving for a short moment, or press the new ' Teleport Now' - button. - - rscadd: Added new outfit that allows admins to dress people up in the chrono equipment - easier. - Jalleo: - - tweak: Due to a recently discovered report it turns out The Wizard Federation - has devised a way for CEOs to stop having some teas from their Smartfridges - due to this change all smartfridges will temporarily be unable to stack contents. - Joan: - - tweak: Revenant draining now takes about 5 seconds to complete and can be interrupted - by dragging the target away. - - tweak: Revenants can now tell if they are currently visible. - - tweak: Revenant ability costs tweaked; Defile now costs 40 essence to cast, Overload - Lights now costs 45 essence to cast, and Malfunction now costs 50 essence to - cast. - - tweak: Malfunction now affects non-machine objects, even if they're not being - held by a human. - - tweak: Defile does an extremely low amount of toxin damage to humans and confuses, - but does much less stamina damage and stuns the revenant for slightly longer. - - tweak: Overload Lights will no longer shock if the light is broken after a light - is chosen to shock an area. - Kor: - - rscadd: Using water on a dark blue slime extract will now yield a new potion capable - of completely fireproofing clothing items. - - rscadd: You can once again click+drag mobs into disposal units. Xenobiologists - rejoice. - Xhuis: - - tweak: Shadowling abilities now require the user to be human. - - tweak: Enthralling now takes 21 seconds (down from 30). - - tweak: Regenerate Chitin has been renamed to Rapid Re-Hatch. - - tweak: Dethralling surgery's final step now requires a flash, penlight, or flashlight. - - tweak: Dethralling surgery now produces a black tumor, which has a high biological - tech origin but dies quickly in the light. - - rscdel: Shadowlings no longer have Enthrall before hatching. - - rscadd: Shadowling clothing now has icons to better reflect its existence. - - rscdel: Ascendant Broadcast has been removed. - - rscdel: Destroy Engines is now removed from the user after it is used once. -2015-11-11: - AnturK: - - tweak: DNA Injectors now grant temporary powers on every use. Duration dependent - on activated powers and machine upgrades - - rscadd: 'Delayed Transfer added to DNA Scanner - It will activate on the next - closing of scanner door ' - - rscadd: 'UI+UE injectors/buffer transfers added for convinience ' - - tweak: Injector creation timeout cut in half - Firecage: - - rscadd: NanoTrasen specialists has developed a new type of operating table. You - can now make one yourself with only some rods and a sheet of silver! - Kor: - - rscadd: Adds immovable and indestructible reflector structures for badmin use. - - rscadd: The Mjolnir has been added to the wizards spellbook. - - rscadd: The Singularity Hammer has been added to the wizards spellbook. - - rscadd: The Supermatter Sword has been added to the wizards spellbook. - - rscadd: The Veil Render has been added to the wizards spellbook. - - rscadd: Trigger Multiverse War (give the entire crew multiswords) has been added - to the wizards spellbook, at a cost of 8 points. - - rscadd: Converting (to cultist, rev, or gangster) a jobbaned player will now automatically - offer control of their character to ghosts. - - rscadd: Emergency Response Teams and Deathsquads no longer accept non-human members - if the server is configured to bar mutants from being heads of staff. - LordPidey: - - rscadd: Nanotransen doctors have re-approved Saline-Glucose Solution for usage - in IV drips, when blood supplies are low. Simple pills will not suffice. - MMMiracles: - - tweak: Water slips have been nerfed to a more reasonable duration. It is still - a guaranteed way to disarm an opponent and obtain their weapon, but you can - no longer manage to cuff/choke everyone who manages to slip without a problem. - MrStonedOne: - - bugfix: Fixes the smartfridge not stacking items. - Xhuis: - - soundadd: The emergency shuttle now plays unique sounds (thanks to Cuboos for - creating them) when launching from the station and arriving at Central Command. - torger597: - - rscadd: Added a syringe to boxed poison kits. -2015-11-12: - Dunc: - - rscdel: DNA injectors have been restored to their original permanent RNG state - from the impermanent guaranteed state. - Xhuis: - - rscadd: Reagents can no longer be determined by examining a reagent container - without the proper apparatus. Silicons and ghosts can always see reagents. - - rscadd: Science goggles now allow reagents to be seen on examine. In addition, - chemists now start wearing them. The bartender has a pair that looks and functions - like sunglasses. -2015-11-13: - as334: - - rscadd: Nanotrasen has hired a brand new supply of ~~expendable labor~~ *LOYAL - CREW MEMBERS* please welcome them with open arms. - - rscadd: Plasmamen are now a playable race. They require plasma gas to survive - and will ignite in oxygen environments. -2015-11-15: - CosmicScientist: - - tweak: Hopefully made the dehydrated carp's uplink description 100% clear. - - tweak: Made the dehydrated carp cost 1 TC (instead of 3) to help with your traitor - gear combos. - Incoming5643: - - tweak: The supermatter sword was being far too kind in the hands of men. They - should now have the desired effect when swung at people. - Joan: - - tweak: Anomalies move more often, are resistant to explosions and will only be - destroyed if they are in devastation range. You shouldn't bomb them, though. - - tweak: Hyper-energetic flux anomaly will shock mobs that run into it, or if it - runs into them. - - tweak: Bluespace anomaly will occasionally teleport mobs away from it in a small - radius. - - tweak: Vortex anomalies will sometimes throw objects at nearby living mobs. - - tweak: Pyroclastic anomalies will produce bigger, hotter fires, and if not disabled, - it will release an additional burst of flame. In addition, the resulting slime - will be rabid and thus attack much more aggressively. - - bugfix: Gravitational anomalies will now properly throw objects at nearby living - things. - MrStonedOne: - - bugfix: Away mission loading will no longer improperly expand the width of the - game world to two times the size of the away mission map. - - tweak: This should also improve the speed of loading away missions, since the - game doesn't have to resize the world - RemieRichards: - - rscadd: Deities now start off with the ability to place 1 free turret - - tweak: HoG Claymores now do 30 Brute (Down from 40) but now have 15 Armour Penetration - (Up from 0) - - bugfix: Killing the other god objective is fixed - - tweak: Turrets will no longer attack handcuffed people - - rscadd: Followers are now informed of their god's death - - rscadd: Followers are now informed of the location of their god's nexus when it - is placed - - tweak: Gods can no longer place structures near the enemy god's nexus -2015-11-16: - Gun Hog: - - tweak: The Combat tech requirement for Loyalty Firing Pins has been reduced from - 6 to 5. - Joan: - - tweak: Plasmamen can now man the bar. - - tweak: Defile no longer directly affects mobs. Instead, it rips up floors and - opens most machines and lockers. - - rscadd: Blight added. Blight infects humans with a virus that does a set amount - of damage over time and is relatively easily cured. Blight also badly affects - nonhuman mobs and other living things. - - experiment: While the cure to Blight is simple, it's not in this changelog. Use - a medical analyzer to find the cure. - - tweak: Tweaked costs and stuntimes of abilities; - - tweak: Defile now costs 30 essence and stuns for about a second. - - tweak: Overload Lights now costs 40 essence. - - tweak: Malfunction now costs 45 essence. - - rscadd: Blight costs 50 essence and 200 essence to unlock. - - imageadd: Transmit has a new, spookier icon. - - bugfix: Revenant abilities can be given to non-revenants, and will work as normal - spells instead of runtiming. - bgobandit: - - rscadd: Blood packs can now be labeled with a pen. -2015-11-17: - Xhuis: - - tweak: Many medicines have received rebalancing. Expect underused chemicals like - Oxandralone to be much more effective in restoring damage. - - tweak: Many toxins are now more or less efficient. - - tweak: The descriptions of many reagents have been made more accurate. - - rscadd: 'New poison: Heparin. Made from Formaldehyde, Sodium, Chlorine, and Lithium. - Functions as an anticoagulant, inducing uncontrollable bleeding and small amounts - of bruising.' - - rscadd: 'New poison: Teslium. Made from Plasma, Silver, and Black Powder, heated - to 400K. Modifies examine text and induces periodic shocks in the victim as - well as making all shocks against them more damaging.' - - rscadd: Two Chemistry books have been placed in the lab. When used, they will - link to the wiki page for chemistry in the same vein as other wiki books. -2015-11-18: - oranges: - - tweak: Nanotrasen apologies for a recent bad batch of synthflesh that was shipped - to the station, any rumours of death or serious injury are false and should - be reported to your nearest political officer. At most, only light burns would - result. - phil235: - - bugfix: Remotely detonating a planted c4 with a signaler now works again. -2015-11-19: - Joan: - - rscadd: Constructs have action buttons for their spells. - - imageadd: The Juggernaut forcewall now has a new, more cult-appropriate sprite. - - imageadd: Cult floors and walls now have a glow effect when being created. - - bugfix: Nar-Sie and Artificers will properly produce cult flooring. - - spellcheck: Nar-Sie is a she. -2015-11-20: - AnturK: - - tweak: Staff of Doors now creates random types of doors. - Incoming5643: - - bugfix: Setting your species to something other than human (if available) once - again saves properly. Note that if you join a round where your species setting - is no longer valid it will be reset to human. - PKPenguin321: - - tweak: Healing Fountains in Hand of God now give cultists a better and more culty - healing chemical instead of Doctor's Delight. - kingofkosmos: - - rscadd: Added the ability to upgrade your grab by clicking the grabbed mob repeatedly. - octareenroon91: - - rscadd: Add the four-color pen, which writes in black, red, green, and blue. - - rscadd: Adds two such pens to the Bureaucracy supply pack. -2015-11-21: - Joan: - - rscadd: Blobs now have a hud, with jump to node, create storage blob, create resource - blob, create node blob, create factory blob, readapt chemical, relocate core, - and jump to core buttons. - - tweak: Manual blob expansion is now triggered by clicking anything next to a blob - tile, instead of by ctrl-click. - - tweak: 'Rally Spores no longer has a cost. Reminder: You can middle-click anything - you can see to rally spores to it.' - - tweak: Creating a Shield Blob with hotkeys is now ctrl-click instead of alt-click. - - rscadd: Removing a blob now refunds some points based on the blob type, usually - around 40% of initial cost. Hotkey for removal is alt-click. - - rscadd: Blobs now have the *Blob Help* verb which will pull up useful information, - including what your reagent does. - - tweak: Storage Blobs now cost 20, from 40. Storage Blobs also cannot be removed - by blob removal. - - tweak: Readapt Chemical now costs 40, from 50. - octareenroon91: - - rscadd: Add numbers and a star graffiti to crayon/spraycan designs. -2015-11-23: - octareenroon91: - - rscadd: Spilling oxygen or nitrogen will obtain a release of the corresponding - atmospheric gas in the effected tile. - - rscadd: 'Carbon Dioxide has been added as a reagent. Recipe: 2:1 carbon:oxygen, - heated to 777K.' - - rscadd: Spilling CO2 will produce CO2 gas. -2015-11-24: - Kor: - - rscadd: Added a lava turf. Expect to see it in away missions or in admin 'events' -2015-11-25: - Incoming5643: - - experiment: A number of popular stunning spells have undergone balance changes. - Note that for the most part the stuns themselves are untouched. - - experiment: 'Lightning Bolt Changes:' - - rscdel: You can no longer throw the bolt whenever you want, it will fire itself - once it's done charging. - - rscadd: Getting hit by a bolt will do a flat 30 burn now, as opposed to scaling - with how long the wizard spent charging the spell. Unless said wizard made a - habit of charging lightning bolt to near maximum every time this is a buff to - damage. - - rscdel: Every time the bolt jumps the next shock will do five less burn damage. - - rscadd: Lightning bolts can still jump back to the same body, so the maximum number - of bolts you can be hit by in a single casting is three, and the maximum amount - of damage you could take for that is 60 burn. - - experiment: 'Magic Missile Changes:' - - rscdel: Cooldown raised to 20 seconds, up from 15 - - rscadd: Cooldown reduction from taking the spell multiple times raised from 1.5 - seconds to 3.5 seconds. Rank 5 magic missile now has a cooldown of 6 seconds, - down from 9, and is effectively a permastun. - - experiment: 'Time Stop Changes:' - - rscadd: Time Stop field now persists for 10 seconds, up from 9 - - rscdel: Cooldown raised to 50 seconds, up from 40 - - rscadd: Cooldown reduction from taking the spell multiple times raised from 7.75 - seconds to 10 seconds. Rank 5 time stop now has a cooldown of 10 seconds, up - from 9, and is effectively a permastun. - Kor: - - rscadd: Escape pods can now be launched to the asteroid during red and delta level - security alerts. Pods launched in this manner will not travel to Centcomm at - the end of the round. - - rscadd: Each pod is now equipped with a safe that contains two emergency space - suits and mining pickaxes. This safe will only open during red or delta level - security alerts. - MrStonedOne: - - bugfix: fixes interfaces (like the "ready" button) being unresponsive for the - first minute or two after connecting. - - tweak: Burn related code has been changed - - tweak: This will give a small buff to fires by making them burn for longer - - tweak: This will give a massive nerf to plasma related bombs - - tweak: I am actively seeking feedback, if the nerf to bombs is too bad we can - still tweak stuff - PKPenguin321: - - rscadd: Chainsaws (both arm-mounted and not arm-mounted) can now be used in surgeries - as a ghetto sawing tool. Arm-mounted chainsaws are a teeny bit more precise - than regular ol' everyday chainsaws. - YotaXP: - - tweak: Spruced up the preview icons on the Character Setup dialog. - incoming5643: - - rscdel: Citing shenanigan quality concerns the wizard federation has withdrawn - supermatter swords and veil renderers from spellbooks. - neersighted: - - bugfix: Make Airlock Electronics use standard ID checks, allowing Drones to use - them. -2015-11-26: - neersighted: - - tweak: Cyborg Toner is now refilled by recharging stations. - oranges: - - tweak: Removed the 'gloves' from the sailor dress which looked weird since it - was a blouse basically - - tweak: Made the skirt on the blue/red skirts less blocky, - - tweak: Made the striped dress consistent at every direction -2015-11-27: - AnturK: - - rscadd: Turret control panels can now be made through frames available at autolathe. - - rscadd: Unlocked turrets can be linked with built controls with multiool - JJRcop: - - bugfix: Restores golem shock immunity. - Kor and Ausops: - - rscadd: Added four different suits of medieval plate armour. - - rscadd: The Chaplain starts with a suit of Templar armour in his locker. God wills - it! - - rscadd: Rumour has it that Nanotrasen is now training a new elite unit of soldiers - to deal with paranormal threats. Corporate was unable to be reached for comment. - MMMiracles: - - rscadd: Adds a brand new away mission for the gateway called 'Caves'. - - rscadd: The away mission has multiple levels to explore and could be quite dangerous, - running in without proper preparation is unadvised. - YotaXP: - - bugfix: Drones can now use the pick-up verb, and watertanks no longer get jammed - in their internal storage. - bgobandit: - - rscadd: Due to changes in Nanotrasen's mining supply chain, ore redemption machines - now offer a variety of upgraded items! However, certain items are more expensive. - Point values for minerals have been adjusted to reflect their scarcity. - - rscadd: Nanotrasen R&D has discovered how to improve upon the resonator and kinetic - accelerator. - - rscadd: After a colossal tectonic event on Nanotrasen's asteroid, ores are distributed - more randomly. - - rscadd: Bluespace crystals have been discovered to be ore. They will now fit into - satchels and ore boxes. - - rscadd: Mech advanced mining scanners now include meson functionality. - neersighted: - - bugfix: Wooden Barricades now take bullet damage. - - tweak: Rebalance Wooden Barricade damage. -2015-11-28: - TechnoAlchemisto: - - tweak: Cloaks are now worn in your exosuit slot! -2015-11-29: - Firecage: - - rscadd: Hand tools now have variable operating speeds. - GunHog: - - tweak: Nanotrasen has improved the interface for the hand-held teleportation device. - It will now provide the user with the name of the destination tracking beacon. - JJRcop: - - bugfix: Fixes changeling Hive Absorb DNA ability runtime. - Joan: - - imageadd: When sacrificing a target with the sacrifice rune, Nar-Sie herself will - briefly appear to consume them. - - imageadd: When an artificer repairs a construct, there is a visible beam between - it and the target. - - imageadd: When reviving a target with the raise dead rune, there is a visible - beam between the two corpses used. - - imageadd: When draining a target with the blood drain rune, there is a visible - beam between you and the rune. - - imageadd: Construct sprites are now consistent and all bob in the air. - - rscadd: Most cult messages now use the cult span classes, though visible messages - from cult things generally do not. - - bugfix: Examining a cultist talisman as a cultist no longer causes the paper popup - to appear. - - bugfix: You no longer need to press two buttons to read a cultist tome. - - spellcheck: Cult should have a few less typos and grammatical errors. - - spellcheck: The sacrifice rune now uses the proper invocation. - KorPhaeron: - - rscadd: Guardians and holoparasites can now be manually recalled by their master. - - rscadd: The ghost controlling a guardian or holoparasite can be repicked by their - master, only one use which is removed when a new ghost is chosen. - MrStonedOne: - - rscadd: Re-adds 100% chance timed injectors, as it was removed over a misunderstanding. - - bugfix: Fixes bug with injectors having a 100% power chance despite not being - timed - - bugfix: Fixes the excessive amount of time it took the game to initialize. - - bugfix: Fixes some interface bugs. - - rscadd: when an interface window has to send a lot of resources before it can - open, it will now tell you with a "sending resources" line so you know why it's - not opening right away. - PKPenguin321: - - rscadd: Teleprods can now be constructed. Make them via tablecrafting, or by putting - a bluespace crystal onto a stunprod. They warp the target to a random nearby - area (which may include space/the inside of a wall) in addition to giving the - victim a brief stun. Like stunprods, they require a power cell to function. - - rscadd: Teleprods can have their crystal removed and be made back into stunprods - by using them in your hand when they have no cell installed. - - imageadd: Mounted chainsaws now have a unique inhand sprite. - Remie + Kor: - - tweak: Holopads now use AltClick to request the AI - Shadowlight213: - - tweak: Syndie melee mobs have been buffed. - TheNightingale: - - rscadd: Nuclear operatives can now buy the Elite Syndicate Hardsuit for 8 TC that - has better armor and fireproofing. - - tweak: Added throwing stars and Syndicate playing cards to nuclear operative's - uplink. - Yolopanther12: - - rscadd: Added the ability to use a box of lights on a light replacer to more quickly - refill it to capacity. - incoming5643: - - rscadd: OOC will now take steps to try and prevent accidental IC from people who - mistakenly use OOC instead of say. This doesn't catch all mistakes, so please - don't test it. - ktccd: - - bugfix: Blob pieces on some areas no longer count for blob mode victory (Such - as space or asteroid). - - bugfix: Blobcode no longer spawns and destroys blobs uselessly, which fixes other - stuff too. - - bugfix: Asteroid areas are no longer valid gang territory. - neersighted: - - experiment: Nanotrasen would like to announce NanoUI 2.0, now being rolled out - across all our stations. Existing NanoUI devices have been updated, and more - will be added soon. Please report any bugs to Nanotrasen Support. - - tweak: Many NanoUI interfaces have had +/- buttons replaced with input fields. - - tweak: Some NanoUI interfaces have had more information added. - - bugfix: Drones can now interact with NanoUI windows. - swankcookie: - - bugfix: Fixes issue of space-Christians forgetting about the true, humbling values - of space-Christmas. - - rscadd: Adds snowmen outfits -2015-11-30: - neersighted: - - bugfix: Nanotrasen would like to apologize for Chemistry being stuck on NanoUI - 1.0... Please report any further bugs to Nanotrasen Support. - - tweak: NanoUI becomes... difficult to operate with brain damage. Who would have - guessed? - - tweak: Telekinesis enables you to use NanoUI at a distance. - - bugfix: Canisters require physical proximity to actuate... - - bugfix: NanoUI no longer leaks memory on click. -2015-12-01: - Kor: - - rscadd: The away mission Listening Post, originally mapped by Petethegoat, has - removed as a mission. It is now present in normal deep space. - neersighted: - - tweak: Attack animations are now directional! - - rscadd: Nanotrasen brand Airlock Electronics now sport our latest NanoUI interface! - Upgrade your electronics today! - - bugfix: Cryo now knocks you out. - - bugfix: Resisting out of cryo has a delay. - - rscadd: Cryo auto-ejection can now be configured. - - rscdel: Remove Cryo eject verb (resist out). - - bugfix: Cryo works... Love, neersighted - swankcookie: - - tweak: Switches cloak usage to overclothing slot -2015-12-02: - GunHog: - - bugfix: Nanotrasen has discovered a flaw in the weapon recharging station's design - that makes it incompatible with the Rapid Part Exchange Device. This has been - corrected. - neersighted: - - tweak: You can now stop pulling by trying to pull the same object again. - - rscadd: Nanotrasen is proud to announce that even the dead can use our state of - the art NanoUI technology. -2015-12-03: - Joan: - - rscadd: Artificers now have feedback when healing other constructs, showing how - much health the target has. - - tweak: Constructs can move in space. - - imageadd: Fixes cult flooring not lining up with normal floors. - - imageadd: Fixes a juggernaut back spine not glowing where it should. - Spudboy: - - tweak: Realigned the librarian's PDA. - Swankcookie: - - bugfix: Cakehat now creates light - YotaXP: - - rscadd: Rolled out a new line of space heaters around the station. This new model - has the functionality to cool down the environment, as well as heat it. Additionally, - they can be built and upgraded like any other machine. - neersighted: - - bugfix: Dominator now shows the correct area name on non-Box maps. - - bugfix: Unwrenching atmos pipes is less... nuts... - - bugfix: You don't get hopelessly spun when standing on a unwrenched pipe... Don't - try it, though. - - tweak: You can now cancel pulling by Ctrl+Clicking anything else - - tweak: Chemistry Dispensers now have a built-in drain! -2015-12-05: - Joan: - - rscdel: Magic missiles no longer do damage. -2015-12-06: - Gun Hog: - - rscadd: Nanotrasen is proud to announce that it has improved its Diagnostic HUD - firmware to include the station's automated robot population! New features include - integrity tracking, Off/On status, and mode tracking! If your little robot friend - suddenly manages to acquire free will, you will be able to track that as well! - - tweak: Artificial Intelligence units may find that their bot management interface - now shows when a robot gains free will. This is also displayed on the Personal - Data Assistant's bot control interface. - neersighted: - - bugfix: Cryo now properly checks it is on before healing... -2015-12-07: - octareenroon91: - - rscadd: Wallets now use the access of all IDs stored inside them. - - rscadd: As the accesses of all IDs are merged, two IDs in a wallet may grant access - to a door that neither one alone would open. - - bugfix: Wallets used to be useless for access if the first ID card put into it - was taken out, until another ID card was put back in. That should not happen - anymore. -2015-12-08: - Joan: - - experiment: Revenants can no longer move through walls and windows while revealed, - though they can move through tables, plastic flaps, mobs, and other similarly - thin objects. - - tweak: Defile now reveals for 4 seconds, from 8. - - tweak: Overload lights now reveals for 10 seconds, from 8. - - tweak: Blight now reveals for 6 seconds, from 8. - - rscadd: Blight has a higher chance of applying stamina damage to the infected. - Kor: - - rscadd: The blocking system has been completely overhauled. Any held item, exosuit, - or jumpsuit can now have a chance to block, or a custom on hit effect. Different - shields can now have different block chances. - - rscadd: The clowns jumpsuit now honks when you beat the owner. - - rscadd: There is a new (admin only for now) suit of reactive armour that ignites - attackers instead of warping you. - - rscadd: Shields will no longer block hugs. Give peace a chance. - neersighted: - - tweak: MC tab reworked, more items made available. - - rscadd: Admins can now click entries in the MC tab to debug. -2015-12-09: - GunHog: - - tweak: Nanotrasen has discovered new strains of Xenomorph which resist penetration - by known injection devices, including syringes. This seems to only extend to - the large 'Royal' strains, designed 'Queen' and 'Praetorian'. Extreme caution - is advised should these specimens escape containment. - - rscadd: Ghosts may now use Diagnostic HUD. - - tweak: Feedback added for which HUD is active. - Kor: - - rscadd: Security barricades now block gunfire 80% of the time while deployed. - - rscadd: Standing adjacent to barricades will allow you to shoot over them. - MrStonedOne: - - rscadd: noslip floors make you slightly faster - Shadowlight213: - - rscadd: Admins can now interact with mos of the station's machinery as if they - were an AI when ghosting. - incoming5643: - - rscadd: a mutation of glowshrooms, glowcaps, have recently been discovered in - botany. - ktccd: - - bugfix: Blobs now require the correct amount of blobs to win that scales depending - on number of blobs, instead of a set value of 700. -2015-12-12: - Joan: - - tweak: The blob Split Consciousness ability now requires a node under the overmind's - selector, instead of picking the oldest living node to spawn a core on. - - bugfix: Revenant antagonist preference can once again be toggled from the Game - Preferences menu. - Kor: - - rscadd: You now have a chance to flip while attacking with a dualsaber. - - rscadd: Bluespace survival capsules have been added to escape pod safes. - - rscadd: Standing between activating shield generators now has disastrous consequences. - Lo6a4evskiy: - - bugfix: Ninja drains power properly, no more infinite stealth. - RemieRichards: - - rscadd: Adds a Synth Species - - rscadd: Species can now react to being force set by admins, used for Synth species -2015-12-13: - Kor: - - rscadd: Adds reactive stealth armor. Admin spawn only. -2015-12-15: - Incoming5643: - - rscadd: The summon events... event "RPG loot" now allows for items to have bonuses - of up to +15! - - rscadd: The "RPG loot" event now also improves the damage reduction of armor! - - rscadd: Check out the item mall for new item fortification scrolls! - as334: - - rscadd: New research has shown that when when plasma reaches a high enough temperature - in the presence of a carbon catalyst, it undergoes a violent and powerful fusion - reaction. - - rscadd: Adds a new gas reaction, fusion. Heat up plasma and carbon dioxide in - order to produce large amounts of energy and heat. - oranges: - - tweak: hulk no longer stuns - - tweak: John Cena -2015-12-16: - AnturK: - - rscadd: Medical Beam Gun now available for Nuclear Operatives and ERT Medics. - Joan: - - tweak: Revenant Overload Lights reveal time lowered from 10 seconds to 8 seconds, - shock damage increased from 18 to 20. - - tweak: Revenant Blight reveal time lowered from 6 seconds to 5 seconds. - Kor: - - rscadd: Styptic once again works in patches. - - rscadd: Nuke Op team leaders can now activate challenge mode if more than 50 players - are online. - - rscadd: Xenobio mobs will no longer spontaneously murder their friends if you - give them sentience - The-Albinobigfoot: - - bugfix: The Wishgranter now displays its faith in humans with curbed enthusiasm. - Tkdrg: - - experiment: Cult has been overhauled in an attempt to make the gamemode more fun. - - rscdel: Cult onversion and stunpapers have been removed. So have most cult objectives. - - tweak: The cult's single objective is now defend and feed a large construct shell - in order to summon the Geometer. - - tweak: The cult must sacrifice souls in order to acquire summoning orbs, which - must be inserted inside said shell. - - tweak: The large construct shell can be procured by using a summoning orb in hand, - but it is vulnerable to attack. - - tweak: Once enough orbs are inserted, the station will go Delta. After three minutes, - the cult will have won. - - rscadd: Cult communications now no longer damage you when done without a tome. - - rscadd: Cultists now start with a sacrificial dagger, with bleeding effects and - high throwing damage. - - rscadd: Most existing runes were buffed, merged, or removed. A Immolate rune and - a Time Stop rune were added. Experiment! - - experiment: Each cultist now gets a random set of runes in their tomes. Pool together - your knowledge in order to thrive. - neersighted: - - experiment: NanoUI 3.0 - - experiment: Completely rewrite NanoUI frontend; rework backend. - - tweak: Re-design NanoUI interface to be much more attractive. - - tweak: Reduce NanoUI LOC count/resource size. - - tweak: Reduce NanoUI tickrate; make UIs update properly. - - rscadd: Add chromeless NanoUI mode. - - rscadd: NanoUI's chromeless mode can be toggled with the 'Fancy NanoUI' preference. - - bugfix: Allow NanoUI to work on IE8-IE11, and Edge. - - bugfix: Close holes that allow NanoUI href spoofing. -2015-12-17: - Kor: - - rscadd: Security barricades are now deployed via grenade. You can no longer move - them after they've been deployed, you must destroy them. - - rscadd: You can now shoot through wooden barricades while adjacent, while any - other gunfire has a 50% chance of being blocked. - - rscadd: There are no longer restrictions against implanting the nuclear disk in - people. - - rscadd: If the station is destroyed in a nuclear blast, any surviving traitors - will complete their "escape alive" objective regardless of their location. - - rscadd: Hulks now lose hulk when going into crit, rather than at 25 health. - - rscadd: Shuttles will no longer drag random tiles of space with them. This means - you can be thrown out of partially destroyed escape shuttles very easily. - - rscadd: The people and objects on destroyed tiles won't be along for the ride - when the shuttle moves either. - - rscadd: Adds hardsuits with built in energy shielding. CTF and security versions - are admin only. - - rscadd: Nuclear operatives can buy a shielded hardsuit for 30tc. - - rscadd: Traitors can now buy a Mulligan for 4 telecrystals, a syringe that completely - randomizes your name and appearance. - - rscadd: The spy bundle now includes a switchblade and Mulligan. - MMMiracles: - - rscadd: A set of coordinates have recently reappeared on the Nanotrasen gateway - project. Ask your local central official about participation. - MrStonedOne: - - tweak: 'Ghosts can now double click on ANY movable thing (ie: not a turf) to orbit - it' - PKPenguin321: - - rscadd: Dope golden necklaces have been added. They're a jumpsuit attachment like - ties and are completely cosmetic. - - rscadd: Dope necklaces can be bought from the clothesmate with a coin. Three are - in the clothesmate by default, so you can get your posse going. Gangs that aren't - Sleeping Carp can also purchase necklaces for 1 influence each. Dope. - xxalpha: - - tweak: Restores the ability to bolt and unbolt operating airlocks. -2015-12-18: - Incoming5643: - - rscadd: Soon to be blobs in blob mode can now burst at their choosing. However - they will still burst if they wait too long. - - rscadd: Burst responsibly. - Joan: - - rscadd: 'New blob chemicals:' - - rscadd: Pressurized Slime, which is grey, does low brute, oxygen, and stamina - damage, but releases water when damaged or destroyed. - - rscadd: Energized Fibers, which is light yellow, does low burn damage, high stamina - damage, and heals if hit with stamina damage. - - rscadd: Hallucinogenic Nectar, which is pink, does low toxin damage, causes vivid - hallucinations, and does some bonus toxin damage over time. - - tweak: Replaces Kinetic Gelatin with Reactive Gelatin, which does less brute damage, - but if hit with brute damage in melee, damages all nearby objects. - - wip: 'Changes three of the old blob chemicals:' - - tweak: Ripping Tendrils does slightly more stamina damage - - tweak: Envenomed Filaments no longer causes hallucinations, but does some stamina - damage in addition to toxin damage over time. - - tweak: Cryogenic Liquid will freeze targets more effectively. - Kor: - - rscadd: Shooting someone who is holding a grenade has a chance to set the grenade - off. - - rscadd: Shooting someone who is holding a flamethrower has a chance to rupture - the fuel tank. - - tweak: Shields have a bonus against blocking thrown projectiles. - Swankcookie: - - rscadd: lanterns no longer turn into flashlights when you pick them up. - bgobandit: - - rscadd: Lizard tails can now be severed by surgeons with a circular saw and cautery, - and attached the same way augmented limbs are. - - rscadd: The Animal Rights Consortium is horrified by Nanotrasen stations' sudden - rise of illegal lizard tail trade, with such atrocities as lizardskin hats, - lizard whips, lizard clubs and even lizard kebab! - neersighted: - - tweak: NanoUI should now load much faster, as the filesize and file count have - been reduced -2015-12-20: - Joan: - - tweak: Reduces Lexorin Jelly's oxygen damage significantly. - - experiment: Blobbernaut chemical application on attack is back, but much less - absurd this time; blobbernauts with an overmind will do 70% of the normal chem - damage(plus 4) and attack at a much slower rate than the blob itself can. - - wip: As an example, a blobbernaut with the Ripping Tendrils chemical would do - 14.5 brute and 10.5 stamina damage per hit. - Kor: - - rscadd: Adds reactive tesla armour. Adminspawn only. - - rscadd: Adds the legendary spear, Grey Tide. Admin only. - - rscadd: Nuke Ops can now purchase penetrator rounds for their sniper rifles. - - rscadd: Nuke ops can now purchase additional team members for 25 telecrystals. - They don't come with any gear other than a pistol however, so remember to save - some points for them. - - rscadd: Nuke Ops now have an assault pod. A 30tc targeting device will allow you - to select any area on the station as its landing zone. The pod is one way, so - don't forget your nuke. - - rscdel: The teleporter board is no longer available for purchase in the uplink. - - rscdel: After finding absolutely nothing of value, Nanotrasen away teams placed - charges and scuttled the abandoned space hotel. - - rscadd: Metastation now has xenobiology computers. - - rscadd: Metastation now has escape pod computers. - - rscadd: A distress signal has been detected broadcasting in an asteroid field - near Space Station 13. - - rscadd: Clicking the (F) follow link for AI speech will now make you orbit their - camera eye. - MMMiracles: - - tweak: The SAW has been revamped slightly. It now requires a free hand to fire, - but includes 4 new ammo variants along with a TC cost decrease for both the - gun and the ammo boxes. - MrStonedOne: - - bugfix: Fixes ghost orbit breaking ghost floating - - bugfix: Fixes orbiting ever breaking golem spawning - - bugfix: 'Fixes orbiting ever preventing that ghost from showing up in pictures - taken by ghost cameras resdel: Fixes being able to break your ghost sprite by - multiple quick consecutive orbits (FINAL SOLUTION, PROVE ME WRONG YOU CAN''T)' - Remie: - - rscadd: 'Byond members can now choose how their ghost orbits things, their choices - are: Circle, Triangle, Square, Pentagon and Hexagon!' - - tweak: orbit() should be much cheaper for clients now, allowing those of you with - potato PCs to survive mega ghost swirling better. - incoming5643: - - bugfix: the terror of double tailed lizards and featureless clones should now - be over - - rscdel: the emote *stopwag no longer works, just *wag again to stop instead -2015-12-21: - AnturK: - - tweak: Ghost HUD and Ghost Inquisitiveness toggles are now persistent between - rounds. - Kor: - - rscadd: Malfunctioning AIs have been merged with traitor AIs. They no longer appear - in their own mode. - - rscadd: Hacking APCs now gives you points to spend on your modules. Save up enough - points and you can buy a doomsday device on a 450 second timer. - - rscadd: The detectives revolver reskins on alt click now. - - rscadd: You can now dual wield guns. Firing a gun will automatically fire the - gun held in your off hand if you are on harm intent. - LanCartwright: - - tweak: The TC costs for nuke ops have been rebalanced. Guns, viscerators and mechs - are cheaper, ammo and borgs are more expensive. - - rscadd: Most guns can now be bought in bundles, together with some ammo and freebies - for a special discount. - The-Albinobigfoot: - - rscadd: Nuclear Operative families may once again requisition ultra-adhesive footwear. -2015-12-22: - Iamgoofball: - - rscadd: Tesla engine has been added alongside the singularity engine to all maps. - Joan: - - wip: 'Adds three new blob chemicals:' - - rscadd: Replicating Foam, which is brown, does brute damage, has bonus expansion, - and has a chance to expand when damaged. - - rscadd: Sporing Pods, which is light orange, does low toxin damage, and has a - chance to produce weak spores when expanding or killed. - - rscadd: Synchronous Mesh, which is teal, does brute damage and bonus damage for - each blob tile near the target, and splits damage taken between nearby blobs. - - experiment: Synchronous Mesh blobs take 25% more damage, to compensate for the - spread damage. - Kor: - - rscadd: Cayenne will no longer be targeted by the syndicate turrets. - - tweak: Energy shields now only reflect energy projectiles. - - rscadd: Added accelerator sniper rounds to uplink, a weak projectile that ramps - up damage the farther it flies. - MMMiracles: - - bugfix: Saber magazines have been dropped to 21 per magazine. When asked, Nanotrasens - official ballistic department replied "There is indeed such a thing as too much - bullet." - Xhuis: - - tweak: Stun batons can now be blocked by shields, blocked hits don't deduct charge. - xxalpha: - - rscadd: Janitor cyborgs now have a bottle of drying agent. -2015-12-25: - Joan: - - rscdel: The blob Split Consciousness ability has been removed. - - tweak: The blob mode now spawns more roundstart blobs, instead. - Kor: - - rscadd: AI holograms no longer drift in zero gravity - LanCartwright: - - tweak: Shotguns shells now have one extra pellet. - MrStonedOne: - - bugfix: Screen shakes will no longer allow you to see through walls - - tweak: Screen shakes will now move with you when moving rather than lag your client - behind your mob - - tweak: Screen shakes are now less laggy in higher tickrates -2015-12-26: - Buggy123: - - tweak: Salicyclic Acid now rapidly heals severe bruising and slowly heals minor - ones. - Iamgoofball: - - tweak: Telsa energy ball now shoots only a single, powerful beam of lightning - that can arc between mobs. - - soundadd: Energy ball can now be heard when near-by. - Incoming5643: - - tweak: Animated objects now revert if they have no one to attack for a while. - - rscadd: Added Golden revolver, a powerful sounding gun with large recoil. - Kor: - - rscadd: Transform Sting is now actually functional. - MrStonedOne: - - tweak: Movement in no gravity now allows you to push off of things only dense - to some mobs if it is dense to you (such as tables/blob tiles) rather than just - objects that are only dense to all mobs. - - bugfix: Long/timed actions will now cancel properly if you move and quickly move - back to the right location. -2015-12-27: - Joan: - - rscadd: Overmind-created blobbernauts are now player-controlled if possible. - - tweak: Creating a blobbernaut no longer destroys the factory, instead doing heavy - damage to it and preventing it from spawning spores for one minute. - - tweak: You cannot spawn blobbernauts from overly damaged factories. - - rscadd: Procedure 5-6 may be issued for biohazard containment under certain situations. - - tweak: Blobs will now burst slightly later on average, and the nuke report with - the nuke code will arrive slightly earlier. - Kor: - - soundadd: Spacemen now announce when they are changing magazines. - - rscadd: Command headsets now have a toggle to let you have larger radio speech. - LanCartwright: - - rscdel: The Syndicate Ship no longer spawns with Bulldog shotguns, operative have - been given 10 extra telecrystals instead. - MrStonedOne: - - bugfix: Flashes that were emp'ed were incorrectly flashing people in range of - the emper, not in range of the flash. - - tweak: Flashes in a mob's inventory that are emp'ed will only aoe stun if it is - not inside of a container like a backpack/box -2015-12-28: - AnturK: - - rscadd: You can now write an entire word with crayons by setting it as a buffer - and then clicking the target tiles in the right order. - Joan: - - rscdel: Blobbernauts can no longer smash walls of any type. - MrStonedOne: - - tweak: Progress bars now have 20 states instead of 5. - - bugfix: Bump mining should be fixed. - - tweak: Long actions now checks for movement/changed hands/etc more often to prevent - edge cases. - - tweak: Multiple progress bars will now stack properly, rather than fight each - other for focus. - Ressler: - - rscadd: Adds the reagent Haloperidol. - - rscadd: It is an anti-drug reagent, good for stopping assistants hyped up on meth, - bath salts, and equally illegal drugs. - - rscadd: It can be made with Chlorine, Fluorine, Aluminum, Potassium Iodide, and - Oil. - neersighted: - - bugfix: Make NanoUIs transfer upon (un)ghosting. - - bugfix: Fix NanoUIs jumping when resized/dragged. - - bugfix: Lots of other NanoUI bugs. -2015-12-31: - Bawhoppen: - - rscadd: Nanotrasen has opened the availability of tactical SWAT gear to station's - cargo department - - rscadd: Due to a new trade agreement with Chinese space suit manufacturers, Nanotrasen - can now obtain basic space suits much cheaper; This has been reflected in the - cargo prices - - rscadd: Amateur medieval enthusiasts have found a quick way to easily make wooden - bucklers. - Joan: - - imageadd: Replaced every book sprite in the game with new, consistent versions. - - imageadd: Except the one-use wizard spellbooks, which already got new sprites. - PKPenguin321: - - rscadd: Chest implants have been added that allow you to morph your arms into - a gun and back at will. There are two variants, a taser version and a laser - version. Both versions are self-charging. Getting EMPed with one of these implants - results in the implant breaking and loads of fire damage. The implants are currently - admin-only. - - tweak: The telecrystal price for thermal imaging goggles has been lowered from - 6 to 4. - incoming5643: - - rscadd: The wizard federation has finally updated their assortment of guns for - the summon guns event. Look forward to getting shot in the face with a whole - new batch of interesting and rarely seen weaponry! -2016-01-01: - Iamgoofball: - - experiment: Redid how objectives are assigned, they're now a lot more random in - terms of what you can get. - Incoming5643: - - tweak: Removed gender restrictions from socks. - Joan: - - rscdel: Storage Blobs are gone; they were effectively a waste of resources, as - there are more or less no points at which you should need them, unless you were - winning excessively hard. - - rscdel: Blobs can no longer burst early; instead, the button gives some early - help and serves to indicate you're a blob. - - wip: Blobbernauts now poll candidates instead of grabbing a candidate immediately. - The poll is 5 seconds, so that there's no significant pause between making a - blobbernaut and it doing stuff. - - rscadd: Blobbernaut creation replaces Storage Blob creation on the blob HUD. - - tweak: Overmind communication is now much larger and easier to see, and blob mobs, - such as blobbernauts, will hear it. - Kor: - - rscadd: The wizard has a new spell, Lesser Summon Guns. This summons an unending - stream of single shot bolt action rifles into his hands, automatically replacing - themselves as you fire. - - bugfix: Fixes successive generations of grey tide clones not despawning. - - tweak: Using challenge ops now delays shuttle refuel. - - rscadd: Added a new wizard event, Advanced Darkness. - MrStonedOne: - - experiment: GHOST POPUP RE-WORK - - bugfix: Ghost popups will no longer steal focus - - bugfix: Ghost popups will no longer submit on key press (regardless of focus) - unless you tab to a button first - - tweak: Ghost popups will close themselves after the time out has ended - - rscadd: Ghost popups are now themed. - - tweak: Long actions (like resisting out of handcuffs) will no longer count space/nograv - drifting as the user moving. - - tweak: This does not apply to the target of a long action if that target isn't - you. Pulling something while space drifting and working on it intentionally - won't work. -2016-01-02: - Kor: - - rscadd: Guardians/Parasites are now named after constellations, and have new sprites - from Ausops. - Kor and GunHog: - - rscadd: Malfunctioning AIs can now purchase Enhanced Surveillance for 30 points, - which allows them to "hear" with their camera eye. - MMMiracles: - - rscadd: A distress signal was recently discovered with gateway coordinates attached - to a far-off research facility owned by Nanotrasen. The signal was sent out - in hopes of someone competent receiving it, unfortunately, your station was - the only one to respond. Local security forces may not be welcoming your arrival - group with open arms. -2016-01-07: - KorPhaeron: - - tweak: Doubled cost of Lesser Summon Guns to 4 and increased charge time to 75 - seconds. - TrustyGun: - - rscadd: 'Added two new UI styles: black and green Operative and pale green Slimecore.' -2016-01-09: - Wjohnston: - - wip: AI Satellite has been remapped to make it more secure. -2016-01-11: - Joan: - - rscdel: Blob cores and nodes no longer cause normal pulsed blobs to animate. Factories - and resource nodes will still animate. - - imageadd: Holoparasite sprites have been updated again, are now named after silvery - metals and flowers and can also be colored purple, blue or yellow. - xxalpha: - - tweak: Pipes and cables under walls, intact floors, grilles and reinforced windows - will now be shielded from explosions until exposed. -2016-01-13: - Joan: - - imageadd: Alien whisper ability has a new icon - MrStonedOne: - - tweak: Control clicking on the thing you are pulling will no longer unpull, instead - control clicking on anything too far away to be pulled will unpull. (reminder - that the delete key also unpulls) - OneArmedYeti: - - imageadd: To help with colorblindness, gang HUDs have been changed so leaders - have a border and normal gangster icons are smaller. -2016-01-15: - Joan: - - bugfix: Holoparasites can no longer beat their owner to death while inside of - them. - - spellcheck: Updates traitor holoparasite descriptions for accuracy. - - spellcheck: Adds 8 additional silvery metals to the holoparasite name pool. - - imageadd: Adds two new holoparasite colors, light purple and red. - - imageadd: Holoparasite HUD buttons now have new sprites. - - imageadd: Adds glow effects when guardians teleport or recall, including fire - guardian teleporting and support guardian teleporting. - Kor: - - rscadd: Washing machines are activated via alt+click rather than a right click - verb. -2016-01-16: - Joan: - - imageadd: Alien queens and praetorians have suitably large speechbubbles. - - imageadd: Syndicate cyborgs and syndrones have suitably evil robotic speechbubbles. - - imageadd: Blob mobs have suitably uncomfortable-looking speechbubbles. - - imageadd: Holoparasites and guardians have suitably robotic and magical speechbubbles. - - imageadd: Swarmers have suitably holographic speechbubbles. - - imageadd: Slimes have suitably slimy speechbubbles. -2016-01-17: - Joan: - - bugfix: You can once again repair a hacked APC by using an APC frame on it instead - of welding it off the wall, at the same stage as you'd weld it off the wall. - MrStonedOne: - - bugfix: Control clicking on a turf now un-pulls -2016-01-19: - neersighted: - - rscadd: Many many interfaces have been ported to tgui; uplinks and MULEbots being - the most important - - rscadd: You can now tune radios by entering a frequency - - bugfix: Air Alarms now support any gas -2016-01-23: - neersighted: - - experiment: Refactor wires; port wire interface to tgui. - - rscadd: Wire colors are now fully randomized. - - rscdel: Remove pizza bombs, as the code and sprites were terrible. - - rscadd: Add pizza bomb cores, which can be combined with a pizza box to make a - pizza bomb. - octareenroon91: - - bugfix: Chemistry machinery should now all equally accept beakers, drinking glasses, - etc. -2016-01-27: - Joan: - - tweak: Golems have about a 40% chance to stun with punches, from about 60%. - - tweak: Millitary Synths have about a 50% chance to stun with punches, from literally - 100%. - - wip: Blobbernaut creation costs 30 points, and does much more damage to the factory. - - rscdel: Blob factories regenerate at half normal rate. - - tweak: Blob reagents tweaked; - - rscadd: Ripping Tendrils does slightly more brute damage, but less stamina damage. - - rscdel: Lexorin Jelly does less brute damage. - - rscadd: Energized Fibers does slightly more burn damage. - - rscadd: Sporing Pods does slightly more toxin damage. - - rscadd: Replicating Foam will try to replicate when hit more often. - - rscadd: Hallucinogenic Nectar does slightly more toxin damage and causes hallucinations - for longer. - - rscadd: Cryogenic Liquid does more burn damage. - - experiment: Synchronous Mesh does slightly less damage with one blob but massive - damage with more than one nearby blob. - - rscdel: Dark Matter does less brute damage. - - rscdel: Sorium does slightly less brute damage. - - rscdel: Pressurized Slime has a lower chance to emit water when killed and when - attacking targets. - - tweak: Supermatter explosion is no longer capped, and under normal conditions - will produce a 8/16/24 explosion when delaminating. - - imageadd: Blob tiles now do an attack animation when failing to expand into a - turf. - - imageadd: Overmind-directed expansion is more visible than automatic expansion. - Kor: - - rscadd: Capture the flag has been added in space near central command. The spawners - are disabled by default, so be sure to harass admins when you die until they - let you play. The arena was mapped by Ausops. - - rscadd: Nuke ops can purchase mosin nagants for 2 telecrystals. - MrStonedOne: - - bugfix: Fixes the powersink drawing less power than the smeses put out. - - tweak: Made the powersink hold significantly more power before overloading and - going boom. - - tweak: Buffed the explosion of the power sink when it overloads. You are suggested - to think twice about wiring the engine to the grid. - PKPenguin321: - - rscadd: The Autoimplanter, a device that can insert cyberimplants into humans - instantly and without the need of surgery, has been added to the game. It is - currently only obtainable by nuke ops, by way of being included in the Box of - Implants. -2016-01-28: - Joan: - - rscadd: Blobs can communicate before bursting to allow for more coordination. - Kor: - - rscadd: Butchering mobs by attacking them with sharp objects will only happen - on harm intent. This means it is possible to do surgery on aliens again. -2016-01-29: - Joan: - - rscadd: Holoparasites can now see their summoner's health at all times. The health - displayed is a percentage, with 0 being dead. - - imageadd: Holoparasites now have visual flashes on the summoner's location when - recalled due to range limits and when manifesting. - Kor: - - rscadd: Red xenobio potions now work on vehicles (janitor cart, ATV, secway, etc), - causing them to go faster. - - rscadd: Stuffing people in bins uses clickdrag instead of grab. -2016-01-30: - Boredone: - - tweak: Due to an experiment gone wrong, the Research Director's Teleport Armor - now causes some mild radiation poisoning on teleportation to the wearer. - Francinum: - - rscadd: Added two new female underwear styles. - Kor: - - rscadd: You can now use the abandoned white ship as an escape route at round end. - This is possible on Box, Meta, and Dream. - - rscadd: Added support so that mappers can make any shuttle function as an escape - shuttle. - MMMiracles: - - rscadd: Three new bra sets have been added for the ladies out there who want to - show their patriotism. - xxalpha: - - rscadd: Blueprints will now allow the expansion of an existing area by giving - its name to a new adjacent area. - - rscadd: Added a no power warning cyborg verb to Robot Commands. -2016-01-31: - Kor: - - rscadd: Added a special AI upgrade disk that allows normal AIs to use malf modules - and hack APCs. It is admin only. - - rscadd: Added an AI upgrade disk that grants AIs the lipreading power. It is admin - only. -2016-02-01: - Erwgd: - - rscadd: The Kitchen Vending machine now stocks salt shakers and pepper mills! - - rscadd: The NutriMax now stocks spades, cultivators and plant analyzers. - - rscadd: Rice seeds are now stocked in the MegaSeed Servitor, and the seeds supply - crate now contains a pack of rice seeds. - - rscdel: Botanists should be aware that wheat stalks can no longer mutate into - rice. - Fayrik: - - rscadd: pAI cards can now be inserted into simple robots, to allow for more robust - robot personalities. - PKPenguin321: - - rscadd: You can now store knives, pens, switchblades, and energy daggers in certain - types of shoes (such as jackboots, workboots, winter boots, combat boots, or - no-slips). - - rscadd: Horns can now be stored in clown shoes. Honk. - TrustyGun: - - rscadd: Adds gag handcuffs to the prize pool for arcade machines. They act like - regular handcuffs, but you break out of them in a second. - WJohnston: - - rscadd: Adds missing booze & soda dispenser, library console, fixes door access - and a few other minor things to Efficiency Station - - rscadd: Also adds direction tags so people can find their way around better. - bgobandit: - - rscadd: On Valentine's Day, all spacemen will receive candy hearts and valentines - for their special someones! Label valentines with a pen. - - rscadd: Note that today is not Valentine's Day. -2016-02-05: - Joan: - - experiment: Blob expansion is faster near the expanding blob, but slower further - away from it. - - tweak: Blob spores produce a slightly larger smoke cloud when dying. Sporing Pods - spores and blob zombies produce the current small cloud. - - rscdel: Blobbernauts can no longer pull anything at all. - - tweak: Blobbernauts health reduced to 200, but blobbernauts now take half brute - damage. - - tweak: Blobbernauts now take massive damage from fire. - - tweak: Blobbernauts do approximately 3 more damage when attacking. - - wip: Replicating Foam will expand more actively when damaged. - - rscadd: Adds Electromagnetic Web, which is light blue, does burn damage and EMPs - targets, and causes a small EMP when dying. - - rscadd: Electromagnetic Web takes more damage; a normal blob that hasn't been - near a node or the core for 6~ seconds can be oneshotted by a laser. - - rscadd: Anomalies, such as pyroclastic and vortex anomalies, now appear at the - bottom of the ghost orbit and observe menus. - Kor: - - rscadd: Nuke ops can purchase sentience potions for 4tc - MMMiracles: - - tweak: Bulldog now starts with stun-slugs instead of its usual 60-brute slugs. - Slugs now cost 3 TC instead of 2. - - tweak: Most SAW ammo has been slightly buffed in damage so maybe it'll be worth - buying now along with a slight cost decrease for the gun itself. - - tweak: Incen shells for the shotgun now apply extra firestacks on hit so it actually - sets people on fire instead of turning them into a light show. - - tweak: Incen rounds for the SAW now leave a fire trail similar to the bulldog's - dragonsbreath round. - - rscadd: Nuke Ops now have the ability to purchase breaching shells, a weaker variant - of the meteorslugs that can still push back people/airlocks/mechs/corgis. - - bugfix: SAW should now use its in-hand sprites for an open-closed magazine - PKPenguin321: - - rscadd: You can now sharpen carrots into shivs by using a knife or hatchet on - them. - bgobandit: - - rscadd: Seven new emoji have been added to hasten the death of the English language. - octareenroon91: - - rscadd: Player-controlled medibots can examine a patient to know what chems are - in the patient's body. - - bugfix: autolathes have been showing extra copies of the hacked designs, but no - more. -2016-02-06: - LordPidey: - - rscadd: Added suicide command for pipe valves. It's quite messy. - Lzimann: - - tweak: Combat Mechas now have a increased chance of destroying a wall with punches - (40% for walls and 20% for reinforced walls)! - - rscadd: Combat mechas can now destroy tables and racks with a punch! - neersighted: - - rscadd: The Syndicate has stolen the latest tgui improvements from Nanotrasen! - All uplinks now feature filtering/search. - - rscadd: Nanotrasen is proud to announce its next generation sleepers, featuring - tgui! - - rscadd: Portable atmospheric components have been overhauled to use the latest - interface technology. - - rscdel: The Area Atmosphere Computer has been removed. - - rscadd: Huge scrubbers now require power. - - rscdel: Borg jetpacks are now refilled from a recharger and not a canister. - - rscadd: Power monitors now have a state of the art graph. Hopefully they're actually - useful to someone. - - rscadd: Cargo consoles have been redesigned and now feature search and a shopping - cart! -2016-02-08: - Incoming5643: - - rscadd: Poly will now speak a line or emote when pet. - - rscadd: Poly now responds to getting fed crackers by becoming more annoying for - the round. - - experiment: Every day he is growing stronger - Kor: - - rscadd: A certain hygiene obsessed alien is now obtainable via xenobiology gold - cores. - - rscadd: Add laserguns with swappable, rechargeable magazines. They are adminspawn - only. - - rscadd: Operatives now get their pinpointers in their pocket when they spawn, - meaning reinforcements automatically come with them (and hopefully people stop - forgetting them in general). - - rscadd: Capture the flag now features a high speed instagib mode, with guns courtesy - of MMMiracles. - phil235: - - tweak: The vision updates for mobs are now instantaneous (e.g. you don't have - to wait one second to see again when removing your welding helmet) - - tweak: Your vision is now affected when you're inside something or viewing through - a camera. You can no longer see mobs or objects when ventcrawling (unless you - have xray for example), an xray user viewing through a camera do not see through - walls around the camera. On the other hand, cameras with an xray upgrade let - you see through walls. Unfocused camera now give you the same effect as when - you are nearsighted. Being inside closets, morgue container and disposal bins - give you some vision impairments. - - rscadd: The ability to toggle your hud on and off (with f12) is now available - to all mobs not just humans. -2016-02-09: - AnturK: - - rscadd: Syndicate Operatives can now buy bags full of plastic explosives for 9 - TC. - Gun Hog: - - rscadd: '"Nanotrasen has drafted a design for an exosuit version of the medical - nanite projector normally issued to its Emergency Response Personnel. With sufficient - research, a prototype may be fabricated for field testing!"' - incoming5643: - - rscadd: The wizard spell wild shapeshift has been made less terrible. - neersighted: - - rscadd: Internals tanks now provide an action button - - rscadd: Jetpacks now emit the gas consumed for propulsion onto their turf - - rscdel: Jetpacks no longer have object verbs - - rscdel: tgui no longer has internals buttons - - bugfix: Malf AI's flood ability now correctly sets vent pressure bounds -- the - results are devastating... Try it! -2016-02-10: - Joan: - - rscadd: Blob mobs now heal for 2.5% of their maxhealth when blob_act()ed, basically - whenever they're on blobs near a node or the core. - - tweak: Blob expansion no longer has a chance to fail inversely proportional with - the expanding blob's health. Blobs still, however, expand at roughly the same - rate as they do currently. - - experiment: Adds five new blob chemicals. - - rscadd: Adds Penetrating Spines, which is sea green and does brute damage through - armor. The damage can still be reduced by bio protection. - - rscadd: Adds Explosive Lattice, which is dark orange and does brute damage to - all mobs near the target. Explosive Lattice is very resistant to explosions. - - rscadd: Adds Cyclonic Grid, which is a light blueish green and does oxygen damage, - in addition to randomly throwing or pulling nearby objects. - - rscadd: Adds Zombifying Feelers, which is a fleshy zombie color and does toxin - damage, in addition to killing and reviving unconscious humans as blob zombies. - - rscadd: Adds Regenerative Materia, which is light pink and does toxin damage, - in addition to making the attacked mob think it is at full health. - - wip: Tweaks some of the existing blob chemicals slightly. - - rscadd: Sporing Pods can produce spores when killed by damage less than 21, from - less than 20. This means lasers can produce spores. - - rscadd: Reactive Gelatin has a slightly higher maximum damage and will attack - the nearby area when hit with brute damage projectiles, from just when attacked - by brute damage in melee. - - tweak: Sorium, Dark Matter, and the new Cyclonic Grid will not throw mobs with - the 'blob' faction, such as blobbernauts and spores. - Kor: - - rscadd: The chaplain can now transform the null rod into a holy weapon of his - choice by using it in hand. Each one has different strengths and drawbacks. - MrStonedOne: - - tweak: Tesla balance changes - - tweak: Tesla will now require increasingly more energy to trigger new orbiting - balls. First ball comes with 32 energy (down from 300), fourth requires 256 - (down from 1200), and so on and on, doubling with each new ball. Balls after - 7 are increasingly harder to get than before, whereas balls before 6 are easier - to get. - - rscadd: MULTIBOLT IS BACK! - - tweak: Be warned that in multibolt all but 1 primary bolt now have a random shocking - range, meaning they may still target a close human over a far away grounding - rod as the rod may be out of range. - - tweak: Power output of tesla massively dropped, it should no longer put out almost - twice the power of a stage 3 singulo with maxed collectors without any balls, - you'll need at least 3 balls for that now. - - tweak: Tesla can now lose power, causing ball count to drop. Tesla will never - shrink out of existence, just lose its balls. - - tweak: Tesla is now more likely to head in the direction of the thing it last - zapped. - PKPenguin321: - - rscadd: Chameleon Jumpsuits now have slight melee, bullet, and laser protection. - - tweak: The armor values for security helmets, caps, and berets have all been brought - in line. Consequently, helmets and berets are a teeny bit better, and caps now - have the slight bomb protection that the other two had. - - experiment: The time needed to complete most tablecrafting recipes has been cut - in half to make tablecrafting less annoying to use. - Shadowlight213: - - rscadd: pAI controlled mulebots can now run people over. - - tweak: Mulebot health has been greatly decreased. - neersighted: - - rscadd: Horizontal (lying) mobs now fit into crates - - rscadd: Mobs may now be stuffed into crates, as with lockers - - rscadd: Stuffing into a locker deals a mild stun (the same as tabling) - octareenroon91: - - rscadd: New designs can now be added to Autolathes via a design disk. Simply use - a disk containing a suitable design on your autolathe. -2016-02-11: - neersighted: - - rscdel: Remove all cyborg jetpacks... They were awful... - - rscadd: Adds borg ion thrusters, which are available as an upgrade module for - any borg. - - rscdel: Jetpack stabilizers are always on, but now we have... - - rscadd: Jetpack turbo mode, to move at sanic speed in space. -2016-02-12: - Kor: - - rscadd: Malf AIs can now get the objective to have a robot army by the end of - the round. - - rscadd: Malf AIs can now get the objective to ensure only human crew (no mutants) - are on the shuttle at round end. - - rscadd: Malf AIs can now get the objective to prevent a crewmember from escaping - the station, while requiring that crewmember still be alive. - neersighted: - - rscadd: Cybernetic implants purchased from the uplink now include a free autoimplanter! - octareenroon91: - - rscdel: You can no longer kill yourself with the SORD - - rscadd: Suicide attempts with the SORD will inflict 200 stamina damage. You will - only die of shame. - - bugfix: Cleanup to suicide verb code. -2016-02-13: - Buggy123: - - rscadd: You can now build cable coils using the autolathe. - Fox McCloud: - - bugfix: Fixes the sleeping carp martial arts grab not being an instant aggressive - grab - KazeEspada: - - rscadd: 'New backpack options available! New options include: Department Bags, - Leather Satchels, and Dufflebags!' - Kor: - - rscadd: Chainsaw sword, force weapon, and war hammer have all been added as Chaplain - weapon options. - Malkevin: - - tweak: Tracking implants have been upgraded. The old clunky manually adjusted - number system has been replaced with an automated ID scanner, this will show - the implant carrier's name on both the Prisoner Management Console and the hand - tracker. Happy deep striking! - PKPenguin321: - - tweak: 'Traitor EMP kits have had their cost reduced from 5 to 2, and no longer - contain the EMP flashlight. rcsadd: EMP flashlights can now be bought separately - for 2 TCs.' - Zerrien: - - rscadd: Conveyor pieces can be placed as corner pieces when building in non-cardinal - directions. - - rscadd: Using a wrench on a conveyor rotates it while in place. - neersighted: - - tweak: Gibtonite can now be pulled. - - tweak: Slowdown factors are ignored when in zero gravity. - phil235: - - rscadd: Brains can no longer be blinded. - - bugfix: Fixes brain being immortal. They are immune to everything but melee weapon - attacks. Brains not inside a MMI can now be attacked just like MMIs. Damaged - brain can't be put into a robot, they can still be put inside a brainless humanoid - corpse and cloned, but deffibing the corpse always fails (can't revive someone - with a brain beaten to a pulp). -2016-02-14: - Joan: - - rscadd: Blobbernauts can now speak to overminds and other blobbernauts with :b - - rscadd: Blobs can now expand onto lattices and catwalks. - - rscdel: Blob expansion on space tiles with no supports is much slower. - - tweak: Blob Sorium and Dark Matter now have less range on targets with bio protection. - - tweak: Blob Sorium does slightly less damage. -2016-02-17: - Fox McCloud: - - tweak: Laser eyes mutation no longer drains nutrition - Joan: - - rscdel: The sleeping carp gang no longer has special equipment and an inability - to use pneumatic cannons. - PKPenguin321: - - tweak: The traitor surgery bag now costs 3 TC, down from 4. - Zerrien: - - rscadd: adds unique icons for the two medical patch types -2016-02-18: - Kor: - - rscadd: 'Four more chaplain weapon options have been added: hanzo steel, light - energy sword, dark energy sword, and monk''s staff.' -2016-02-19: - AnturK: - - rscadd: Chairs and stools can now be picked up and used as weapons by dragging - them over your character. - PKPenguin321: - - rscadd: The cleanbot uprising has begun. - - rscadd: Emagged cleanbots are much scarier now. Standing on top of one will yield - very devastating results, namely in the form of powerful flesh-eating acid. -2016-02-20: - CPTANT: - - tweak: Due to new crystals Nanotrasen lasers weapons may now set you on FIRE. - Joan: - - imageadd: Blobbernauts and blob spores now have a visual healing effect when being - healed by the blob. - xxalpha: - - rscadd: 'New event: Portal Storm.' - - rscadd: Kinetic accelerators now reload automatically. -2016-02-24: - CPTANT: - - tweak: stamina regeneration is now 50% faster. - Joan: - - rscadd: Revenants now have an essence display on their HUD - - rscadd: Revenants retain the essence cap from the previous revenant when reforming, - minus any perfect souls. - - rscadd: Revenants can now toggle their night vision. - - tweak: Revenant Defile has one tile more of range, but does less damage to windows. - - tweak: Revenant Blight kills space vines and glowshrooms slightly more rapidly. - - tweak: Delays before appearing when harvesting are slightly randomized. - - tweak: Revenant fluff objectives have been changed to be slightly more interesting. - RemieRichards: - - rscadd: Cursed heart item for wizards, allows them to heal themselves in exchange - for having to MANUALLY beat their heart every 6 seconds. Heals 25 brute/burn/oxy - damage per correctly timed pump. - Steelpoint: - - tweak: Syndicate engineers have reinforced the exterior of their stealth attack - ships. Nuclear Operative ship hull walls are now, once again, indestructible. - - tweak: In addition Syndicate engineers had the opportunity to revamp the interior - of stealth attack ships. The inside of Op ships now has a slightly new layout, - including a expanded medbay, as well as additional medical and explosive equipment. - - rscadd: Thanks to covert Syndicate operatives, strike teams can now bring the - stealth attack ship within very close proximity to the station codenamed 'Boxstation'. - A new ship destination labeled 'south maintenance airlock' is now available - to Op strike teams. - phil235: - - rscadd: Holo tape is replaced by holo barriers. - - rscadd: The action button of gas tanks and jetpacks now turn green when you turn - your internals on. -2016-02-26: - Iamgoofball: - - rscadd: Adds the Chameleon Kit to uplinks for 4 telecrystals containing a Chameleon - Jumpsuit/Exosuit/Gloves/Shoes/Glasses/Hat/Mask/Backpack/Radio/Stamp/Gun/PDA. - - rscadd: The chameleon gun fires no-damage lasers regardless of what it looks like. - - rscadd: The Voice Changer has been merged into the Chameleon Mask. - - rscadd: No-slip shoes have been combined into Chameleon Shoes. - - rscdel: Space Ninjas no longer have voice changing capabilities. - - rscdel: The Chameleon Jumpsuit has been replaced by the Chameleon Kit in the uplink - for the same price. - - tweak: All chameleon clothing items have lost EMP vulnerability. - - tweak: Chameleon equipment provides very minor armor. - - experimental: Agent ID Cards can now use chameleon technology to look like any - other ID card. - - bugfix: The Chameleon Kit is actually purchasable now. It doesn't give a single - chameleon jumpsuit anymore. - PKPenguin321: - - rscadd: The kitchen vendor now contains two sharpening blocks. - - rscadd: Only items that are already sharp (such as fire axes, knives, etc) can - be sharpened. Items used on sharpening blocks become sharper and deadlier. The - sharpening blocks themselves can only be used once, and you can only sharpen - items once. - - tweak: The EMP kit has been buffed. It now contains five EMP grenades, up from - two. - - tweak: The EMP implant found in the EMP kit has been buffed. It now has three - uses, up from two. -2016-03-02: - CoreOverload: - - rscadd: A new "breathing tube" mouth implant. It allows you to use internals without - a mask and protects you from being choked. It doesn't protect you from the grab - itself. - - tweak: Arm cannon implants are now actually implanted into the arms, not into - the chest. - - bugfix: Arm cannons have an action button again. - - tweak: Heart removal is no longer instakill. It puts you in condition similar - to heart attack instead. You can fix it by installing a new heart and applying - defibrillator if it wasn't beating. - - rscadd: You can now make a stopped heart beat again by squeezing it. It will stop - beating very soon, so you better be quick if you want to install it without - using defibrillator. - - rscadd: There is now a chance to recover some of the internal organs when butchering - aliens or monkeys. - - rscadd: A new organ - lungs. When removed, it will give you breathing and speaking - troubles. - - rscadd: Human burgers are, once again, named after the generous meat donors that - made them possible. - Fox McCloud: - - rscadd: Gibbing mobs will now throw their internal organs - Gun Hog: - - rscadd: Ghost security HUDs now show arrest status and implants. - - tweak: The Alien queen, upon her death, will now severely weaken the remaining - alien forces. - Joan: - - tweak: Replicating Foam has a lower chance to expand when hit. - - tweak: Penetrating Spines is now purple instead of sea green. - - imageadd: Blobbernauts now have a brief animation when produced. - - experiment: Adds five new blob chemicals. This is a total of 25 blob chemicals. - Will it ever stop? - - rscadd: Draining Spikes, which is reddish pink and does medium brute damage, and - drains blood from targets. - - rscadd: Shifting Fragments, which is tan and does medium brute damage, and shifts - position when attacked. - - rscadd: Flammable Goo, which is reddish orange and does low burn and toxin damage, - and when hit with burn damage, emits a burst of flame. It takes more damage - from burn, though. - - rscadd: Poisonous Strands, which is lavender and does burn, fire, and toxin damage - over a few seconds, instead of instantly. - - rscadd: Adaptive Nexuses, which is dark blue and does medium brute damage, and - reaps 5-10 resources from unconscious humans, killing them in the process. - - wip: Confused about what the chemical you're fighting does? Look at https://tgstation13.org/wiki/Blob#Blob_Chemicals - - rscadd: Adds 'Support and Mechanized Exosuits' and 'Space Suits and Hardsuits' - categories to the syndicate uplink. - - rscadd: Nuke op reinforcements and mechs have been moved to the first category. - Syndicate space suits and hardsuits have been moved to the second category. - - bugfix: Traitors can now properly buy the blood-red hardsuit for 8 TC. - - tweak: Nuke ops can no longer buy the blood-red hardsuit, as the elite hardsuit - costs the same amount while being absolutely better. - Kor: - - rscadd: Added door control remotes. Clicking on doors while holding them will - let you open/bolt/toggle emergency access depending on the mode. They will not - work on doors that have their IDscan disabled (rogue AIs take note!) - - rscadd: The Captain, RD, CE, HoS, CMO, and QM all now have door control remotes - in their lockers. - LanCartwright: - - rscadd: Adds Uranium to Virus reaction. Will create a random symptom between 5 - and 6 when mixed with blood. - - rscadd: Adds Virus rations, which creates a level 1 symptom when mixed with blood. - - rscadd: Adds Mutagenic agar, which creates a level 3 symptom. - - rscadd: Adds Sucrose agar which creates a level 4 symptom. - - rscadd: Adds Weak virus plasma, which creates a level 5 symptom. - - rscadd: Adds Virus plasma, which creates a level 6 symptom. - - rscadd: Adds Virus food and Mutagen reaction, creating Mutagenic agar. - - rscadd: Adds Virus food and Synaptizine reaction, creating Virus rations. - - rscadd: Adds Virus food and Plasma reaction, creating Virus plasma. - - rscadd: Adds Synaptizine and Virus plasma reaction, creating weakened virus plasma. - - rscadd: Adds Sugar and Mutagenic agar reaction, creating sucrose agar. - - rscadd: Adds Saline glucose solution and Mutagenic agar reaction, creating sucrose - agar. - - rscadd: Adds Viral self-adaptation symptom, which boosts stealth and resistance, - but lowers stage speed. - - rscadd: Adds Viral evolutionary acceleration, which bosts stage speed and transmittability, - but lowers stealth and resistance. - - rscadd: Flypeople now vomit when they eat nutriment. - - rscadd: Flypeople can now suck the vomit off the floor to gain it's nutritional - content. - - rscadd: Flypeople now must suck puke chunks and vomit to fill themselves of food - content. - Malkevin: - - tweak: Sec officers have two sets of cuffs again (one on spawn, one in locker) - - tweak: Done some optimisation of sec spawn equipment lists and lockers to remove - some of the repetitive clicking, sec belts are now preloaded with equipment. - - tweak: HoS has a full baton instead of the collapsible one - - tweak: Detective has a classic police baton and pepper spray instead of the collapsible - baton (someone made police batons shit, so don't get overly happy) - - bugfix: pop scaled additional lockers spawned were the wrong type, changed them - to the right type which has batons now (actually belts now that I've changed - them). - MrStonedOne: - - tweak: Suit sensors will now favor higher levels for starting amount with the - exception of the max level, that remains unchanged. - - tweak: 'Old odds: 25% off 25% binary lifesigns 25% full lifesigns 25% coordinates' - - tweak: 'New odds: 12.5% off 25% binary lifesigns 37.5% full lifesigns 25% coordinates' - PKPenguin321: - - rscadd: Bolas are now in the game. They're a simple device fashioned from a cable - and two weights on the end, designed to entangle enemies by wrapping around - their legs upon being thrown at them. The victim can remove them rather quickly, - however. - - rscadd: Bolas can be crafted by applying 6 metal sheets to cablecuffs. They can - also be tablecrafted. - Sestren413: - - rscadd: Botanists have access to a new banana mutation now, bluespace bananas. - These will teleport anyone unfortunate enough to slip on their peel. - Shadowlight213: - - rscadd: A wave of dark energy has been detected in the area. Corgi births may - be affected. - Shadowlight213 and Robustin: - - rscadd: '"Old Cult is back baby!"' - - tweak: '"Cult survival objective disabled"' - - tweak: '"Imbuing talismans now consumes the imbue rune"' - - tweak: '"Invoking the stun talisman now hurts the cultist more"' - - tweak: '"The stun talisman duration is nerfed by 10%, mute is nerfed by 60% but - a stutter and special new slur effect will last much longer"' - - tweak: '"The old cult has retained the rune of time stop, now requiring 3 cultists - to invoke"' - - rscdel: '"New Cult is removed!"' - bgobandit: - - rscadd: CentComm has been informed that cargo is receiving new forms of contraband - in crates. Remember, Nanotrasen has a zero-tolerance contraband policy! - lordpidey: - - rscadd: New virology symptom, projectile vomiting. It is a level four symptom. -2016-03-03: - Joan: - - tweak: Blobbernauts now die slowly when not near a blob. - - rscadd: Blobbernauts can now see their health and the core health of the overmind - that created them. -2016-03-05: - CoreOverload: - - imageadd: Cyborg tools (screwdriver, crowbar, wrench, etc) now have new fancy - sprites. - - tweak: Said cyborg tools have received a buff and are now two times faster than - their non-cyborg counterparts. - Joan: - - tweak: Replicating Foam has lower expand chances when hit and on normal expand. - - bugfix: Shifting Fragments will no longer try and fail to swap with invalid blobs - when hit. - - tweak: Electromagnetic Web no longer always EMPs targets, instead doing it at - a 25% chance. - - tweak: Synchronous Mesh now only takes bonus damage from fire, bombs, and flashbangs. - - tweak: Synchronous Mesh no longer tries to split damage to blob cores or nodes. - Cores and nodes still split damage to nearby blobs, however. - - tweak: Blobbernauts now attack much slower. - - tweak: Blobbernauts are now maximum one per factory, reduce that factory's health - drastically, and die slowly if that factory is destroyed. - - experiment: Factories must still have above 50% health to produce blobbernauts. -2016-03-07: - WJohnston: - - tweak: Queens and praetorians have new sprites! -2016-03-09: - Joan: - - rscadd: Blobs can now attack people that end up on top of blob tiles with Left-Click - or the Expand/Attack Blob verb. - - tweak: The Toxin Filter virology symptom now heals 4-8 toxin damage instead of - 8-14. - - tweak: The Damage Converter virology symptom will now do toxin damage for each - limb healed. - MrStonedOne: - - tweak: Centcom has improved the the tesla generator! The generated tesla energy - balls should now be more stable! Growing quicker and dissipating slower. It - seems to also move around a touch more but that shouldn't be an issue as the - the tesla escaping containment is unheard of! -2016-03-10: - Joan: - - rscadd: The blob can now be shocked by the tesla. - - tweak: Strong blobs are now much more resistant to brute damage. - - wip: Tweaks blob reagents; - - rscdel: Removes Ripping Tendrils. - - rscdel: Removes Draining Spikes. - - tweak: Cryogenic Liquid does less burn damage. - - tweak: Pressurized Slime does less brute damage. - - tweak: Reactive Gelatin now has a lower minimum damage. - - tweak: Poisonous Strands applies its damage over a longer period of time. - - tweak: Sporing Pods now does much less damage, and is less likely to produce spores - when killed. - - tweak: Regenerative Materia, Hallucinogenic Nectar, and Envenomed Filaments do - less toxin damage. - - rscadd: Energized Fibers no longer heals when hit with stamina damage, and is - instead immune to the tesla. - - rscadd: Boiling Oil now takes damage from extinguisher blasts. Boiling Oil blobbernauts, - however, do not. - - tweak: Replicating Foam now takes increased brute damage and when expanding from - damage, will not expand again. - - tweak: Flammable Goo takes 50% increased burn damage, from 30%. - - tweak: Explosive Lattice now takes much higher damage from fire, flashbangs, and - the tesla. - - experiment: Electromagnetic Web takes full brute damage, lasers will now one-hit - normal blobs, and the death EMP is smaller. -2016-03-12: - Joan: - - bugfix: Blobbernauts and blob spores can now move near blob tiles in no gravity. - - tweak: Boiling Oil does slightly more damage and takes slightly less damage when - extinguished. - - rscadd: Flammable Goo now applies firestacks to targets, but does not ignite them. - Jordie0608: - - rscadd: Show Server Revision will now tell you if a PR is test merged currently. - PKPenguin321: - - rscadd: Added reinforced bolas. They do a very short stun in addition to normal - functions, and take twice as long to break out of when compared to regular bolas. - - tweak: The traitor's Throwing Star Box has been made into the Throwing Weapons - Box. It now contains two reinforced bolas in addition to its old contents. It - also costs 5 TCs, down from 6. - tkdrg: - - tweak: The detective's revolver now takes three full seconds to reload. - xxalpha: - - rscadd: Detective can be a Traitor/Double Agent. - - tweak: Removed Detective's access to security lockers and secbots. - - tweak: Removed bowman's headset from Detective's locker. - - tweak: Box Brig Security Office and Locker Room require a higher access level - (Security Officer level). -2016-03-13: - Dorsisdwarf: - - rscadd: 'Adds Robo-Doctor board (The Hippocratic Oath: Now on your beepbot)' - - rscadd: Adds Reporter board (The truth will set ye free (termsandconditionsmayapply)) - - rscadd: Adds Live and Let Live board - - rscadd: Adds Thermodynamics as a dangerous board. - Impisi: - - tweak: Improvised shells now deal more far more damage but are more inaccurate. - - tweak: Overloaded shells now require liquid plasma in addition to black powder. - Shells now fire explosive pellets that are good at hurting you and everything - in front of you. - Joan: - - rscdel: Blob gamemode blobs will no longer burst from people. - - rscadd: Instead, the blob gamemode spawns overminds, which can place their blob - core underneath them in an unobserved area. - - rscadd: The overminds can, until they have placed a blob core, move to any non-space, - non-shuttle tile. - - rscadd: If the overminds fail to place a blob core within a time limit, it will - be automatically placed for them at a random blob spawnpoint. - - tweak: The time before the overmind automatically places the core is slightly - lower than the previous average time it'd take a blob to burst. -2016-03-15: - Cuboos: - - soundadd: Modded the current door sound and added a few new ones, unique sound - for closing, bolting up/down and a nifty denied sound. - Isratosh: - - rscadd: Security flashlights can now be attached to the bulletproof helmets. - Joan: - - tweak: Resource blobs produce resources for their overmind slightly slower for - each resource blob their overmind has. - - rscadd: Blob overminds get one free chemical reroll. - - rscadd: Blob overminds can no longer place resource and factory blobs out of range - of cores and nodes, unless they Toggle Node Requirement off. It is on by default. - - rscadd: Blob UI buttons now have tooltips. - - tweak: Cores and nodes will expand slightly slower. - - tweak: Blob Chemicals no longer trigger effects on dead mobs. - - tweak: Shifting Fragments has a lower chance to move shields with normal expansion - and will no longer shift blobs to the location of a dying blob. - - tweak: Flammable Goo no longer applies fire to tiles with blobs. - - tweak: Electromagnetic Web has a slightly higher EMP range. - Kor: - - rscadd: Hunger was accidentally disabled sometime back in October 2015. We finally - noticed and fixed it. - Kor (And all the lovely maintainers and spriters who helped me along the way): - - rscadd: Adds a new, lava themed planet to mine on,with randomly generated rivers - of lava and islands of volcanic rock. This mine is used on Box and Metastation. - Other mappers may enable it at their discretion. - - rscadd: Added deadly ash storms to mining. - - rscadd: Added slightly deadlier variants of mining mobs to lavaland, with sprites - done by my girlfriend. - - rscadd: Added portable survival capsules to mining equipment lockers. Don't forget - these, or you might get caught out by a storm. You may purchase more at the - venders. - - rscadd: Added randomly loaded ruins to mining. These maps contain new and unique - items not seen elsewhere in thegame. There are around a dozen of them added - with the "release" of lavaland, though I plan for many more. - - rscadd: Some ruins contain sleepers which allow you to spawn as various roles, - such as survivors of a shuttle crash stranded in the wilderness. You can find - these sleepers in the orbit list. - - rscadd: You can now fly the abandoned white ship to lavaland. - LanCartwright: - - tweak: Choking now deals damage based on virus' Stage speed and virus Stealth. - - tweak: Fever heats the body based on Transmittability and Stage speed. - - tweak: Spontaneous Combustion now adjusts firestacks based on stage speed minus - Stealth. - - tweak: Necrotizing Fasciitis now deals damage based on lower Stealth values. - - tweak: Toxic Filter now heals based on Stage speed. - - tweak: Deoxyribonucleic Acid Restoration now heals brain damage based on Stage - speed minus Stealth. - - tweak: Shivering now chills based on Stealth and Resistance. - - rscadd: Proc for the total stage speed of a virus' symptoms. - - rscadd: Proc for the total stealth of a virus' symptoms. - - rscadd: Proc for the total resistance of a virus' symptoms. - - rscadd: Proc for the total transmittance speed of a virus' symptoms. - MrStonedOne: - - rscdel: 'Lag has been removed from the following systems: mob life()/virus process, - machine/object/event processing, atmos, deletion subsystem, lighting, explosions, - singularity''s eat(), timers, wall smoothing, mass var edit, mass proc calls(and - all of sdql2), map loader, and the away mission loader.' - - rscdel: Removed limit on bomb cap of 32,64,128, it can now go to the MOON. - - tweak: Minimap generation is now a config option that defaults to off so coders - don't have to wait for it to generate to test their code, server operators should - note that they need to enable it on production servers that want minimap generation. - - wip: if you find any things that still lag, please report them to MrStonedOne - for lag removal. - - experiment: I'm gonna take this time to shill out that, Lummox JR, byond's only - dev, coded the tool that made this change possible, he lives off of byond membership - donations, if you like the lag removal, become a byond member or at least throw - 5 bucks byond's way for doing this. - - experiment: Feel free to ask for bomb cap removals when solo antag, but remember, - the later in the round it is, the more likely you'll get it. - PKPenguin321: - - rscadd: Scooters and skateboards have been added. - - rscadd: Use rods to make a scooter frame. From there, apply metal to make wheels, - creating a skateboard. Apply a few more rods to make a full scooter. You can - also use tablecrafting to create them, their recipes can be found under the - Misc. category. - - rscadd: Each step of scooter deconstruction is performed with either a wrench - or a screwdriver, depending on the step. - xxalpha: - - rscadd: Scrubber clog event now ejects cockroaches. -2016-03-17: - CoreOverload: - - rscdel: The recent jetpacks nerf is finally reverted. Turbo mode is dead and stabilization - is once again can be toggled on and off. - - rscadd: 'Added a new chest cyberimplant: implantable thrusters set. This implant - is a built-in jetpack that has no stabilization mode at all and can use gas - from environment (if 30+ kPa) or from internals. It can also use plasma from - plasma vessel organ, if you have one.' - Joan: - - tweak: Moved the security hud's icons down slightly to allow it to coexist with - medical and antag huds. - Shadowlight213: - - rscadd: HOG deity can now be heard by all of its followers! - - tweak: The prophet no longer needs to wear his hat to speak with his deity. - - rscadd: The prophet's hat and staff have a new functionality! Use the staff inhand - to reveal hidden structures. - - rscadd: Deities can now hide their structures from view! Pretend to be a book - club when sec bursts in. experiment:Only enemy prophets or your own deity can - reveal these structures and they are disabled when hidden. -2016-03-19: - Joan: - - imageadd: Xray lasers now have unique inhands. - - imageadd: Xray lasers have been recolored to match R&D equipment. - Zombehz: - - rscadd: Adds 'chicken' nuggets* in 4 shapes, including regular, star, corgi, and - lizard. it. They are made with one cutlet of meat. -2016-03-20: - Joan: - - rscadd: Nar-Sie will now corrupt airlocks, tables, windows, and windoors. - - rscadd: Corrupted airlocks have no access restrictions. - - tweak: Nar-Sie no longer causes destruction while moving around in favor of additional - corruption. - - tweak: The surplus crate is less likely to give you eight space suits. - - bugfix: Nukeops can once again buy noslips. The nuke op magboots are still better - than noslips, buy them instead. - Kor: - - rscadd: Runtime now has a chance to spawn with a more classic look. - - rscadd: Killing a necropolis tendril will now drop a chest full of spooky loot. - - rscadd: Killing a necropolis tendril will now cause the ground to collapse around - it after 5 seconds. -2016-03-21: - CoreOverload: - - rscadd: You can now construct and deconstruct wall mounted flashes by using a - wrench on empty wall flash. A crate with four linked "flash frame - flash controller" - pairs is added to cargo. - Joan: - - rscadd: Explosive Holoparasites now have a 33% chance to explosively teleport - attacked targets, doing damage to everyone near the target's appearance point. - - tweak: Explosive Holoparasite bombs can now detonate when living mobs bump them. - - rscadd: Adds lightning holoparasites, which have medium damage resist, a weak - attack, have a lightning chain to their summoner, and apply lightning chains - when attacking targets. - - rscadd: Lightning chains shock everyone nearby, doing low burn damage. This is - excluding the parasite and summoner; chains will shock enemies they're attached - to. - - tweak: Holoparasites can now smash tables and lockers. - PKPenguin321 && !JJRcop: - - rscadd: Milk, which is good for your bones, is now extra beneficial to species - that are mostly comprised of bones. - kingofkosmos: - - rscdel: The backpack close-button has got a visual overhaul. - - rscadd: All storage items can be closed by clicking on them again. -2016-03-23: - Iamgoofball: - - rscadd: Cargo now works off of Credits. - - rscadd: Cargo now plays the Stock Market. - - rscadd: Buy Low, Sell High -2016-03-24: - Iamgoofball: - - rscadd: CLF3 now melts, burns, and destroys floors a lot more often, as it should - be. - - rscadd: CLF3 now makes 3x3 fireballs on tiles it touches now, instead of a single - fireball. - Joan: - - tweak: Lightning Holoparasites will actually shock relatively often instead of - 'sometimes, maybe, if you're really lucky' - PKPenguin321: - - tweak: Sand now fits in your pockets - - rscadd: Sand can now be thrown into people's eyes, doing slight stamina damage, - making their vision slightly blurry, and making them stumble when they walk - for a short time. - RemieRichards: - - rscadd: BEES - - rscadd: Hydroponics can now manage bee colonies, bees produce honeycombs that - can be grinded to obtain honey, a decent nutriment+healing chemical - - rscadd: Hydroponics can inject a queen bee with a syringe of a reagent to alter - her DNA to match that reagent, meaning all honeycombs produced will contain - that reagent in small amounts - - rscadd: Bees with reagents will attack with that reagent - Xhuis: - - experiment: Alcohol has received multiple tweaks. - - tweak: Drunkenness will now be displayed on examine as long as the target's face - is not hidden, ranging from a slight flush to being a completely drunken wreck. - This also helps to measure alcohol poisoning, although the appearance will remain - for thirty seconds after the alcohol leaves the imbiber's bloodstream. - - tweak: Alcohol poisoning now has different effects. It begins with standard things - such as confusion, dizziness, and slurring, but eventually escalates to constant - vomiting, blacking out, and toxin damage. - - tweak: Drinks now have a wide variety of alcoholism. Grog is barely a drink whatsoever, - for instance, but Manly Dorf will completely floor you with too much consumption. - Note that drinks based off of whiskey and vodka are the hardest, whereas beer - and wine are the softest. - - tweak: The speed of alcohol poisoning has been slightly reduced. - - rscadd: Some drinks have received unique effects. Experiment! - - rscadd: A new base alcohol joins the lineup! Absinthe has been added, and is very - strong. - - rscadd: Whiskey Sour, made with Whiskey, Lemon Juice, and Sugar, simply expands - the existing whiskey-based lineup. - - rscadd: Fetching Fizz, made with Nuka-Cola and Iron, will pull all nearby ores - in the direction of the imbiber. - - rscadd: Hearty Punch, made with Brave Bull, Syndicate Bomb, and Absinthe, will - provide extreme healing in critical condition. - - rscadd: Bacchus' Blessing, made with four of the most powerful alcohols on the - station, is over three times stronger than any other alcohol on the station. - Consume in small amounts or risk death. -2016-03-26: - CPTANT: - - tweak: Nanotrasen found a new taser supplier. The new tasers hold 12 shots, down - people with 2 hits and hybrid tasers now have a light laser attached. - CoreOverload: - - tweak: Sorting junctions now support multiple sorting tags. - Fox McCloud: - - bugfix: Fixes Shadowlings not being spaceproof to pressure - - bugfix: Fixes being able to receive multiple spells as a Lesser Shadowling - Joan: - - rscadd: Adds assassin holoparasites, which do low damage and take full damage, - but can go invisible, causing their next attack to do massive damage and ignore - armor. - - rscadd: Assassin holoparasite stealth will be broken by attacking or taking damage, - which will briefly prevent the parasite from recalling. - - rscadd: Traitor holoparasite injectors include this parasite type. - Kor: - - rscadd: There are a couple new lavaland ruins, including one with a new ghost - role. - PKPenguin321: - - tweak: The RD's reactive teleport armor now has a cooldown between teleports. - EMPing it will cause it to shut down and have a longer cooldown applied. - - imageadd: Bolas, both reinforced and regular, now have newer, sexier sprites. -2016-03-29: - Bawhoppen: - - tweak: Bruisepacks, ointment, and gauze now will apply significanty faster. - - rscdel: SWAT crates no longer contain combat knives. - - rscadd: SWAT crates now contain combat gloves. - - rscadd: Combat knives now can be ordered in their own crate. - Iamsaltball: - - rscadd: GRAB SUPER NERFED - - rscadd: IT'S WAY EASIER TO ESCAPE GRABS NOW - - rscadd: IT TAKES WAY LONGER TO UPGRADE GRABS NOW - - rscadd: 'YOU CAN ACTUALLY FUCKING ESCAPE GRABS NOW TOO #WOW #WHOA' - - rscadd: GRAB TEXT IS ALL BIG BOLD AND RED MUCH LIKE YOUR MOM LAST NIGHT - - experiment: GIT GUDDERS GO FUCK YOURSELVES YOU CAN'T GET GOOD AGAINST "LOL INSTANT - PERMASTUN THAT ISN'T OBVIOUS IN CHAT LIKE THE REST OF THE STUNS" - Joan: - - tweak: Ghost revival/body creation alerts now use the ghost's hud style. - - imageadd: Support holoparasites now have a healing effect with their color when - successfully healing a target. - - tweak: Ranged holoparasite projectiles now take on the color of the holoparasite. - - bugfix: Holoparasite communication(holo->summoner) now sends the message to all - holoparasites the summoner has. - - bugfix: If you have multiple holoparasites for some reason, Reset Guardian allows - you to choose which to reset. - - tweak: Resetting a holoparasite also resets its color and name, to make it more - obvious it's a new player. - - rscadd: Holoparasites can now see their summoner's health and various ability - cooldowns from the status panel. - - rscadd: Blobbernauts are now alerted when their factory is destroyed. - KazeEspada: - - bugfix: Blob Mobs no longer swap with other mobs. - RemieRichards: - - rscadd: Added the ability to make Apiaries and Honey frames with wood - - rscadd: Added the ability to make Royal Bee Jelly from 10 Mutagen and 40 Honey - - rscadd: Added the ability to make more Queen Bees from Royal Bee Jelly by using - it on an existing Queen, to split her into two Queens - - tweak: Made homeless bees more obvious - - bugfix: Fixed a typo that made almost all bees homeless, severely reducing the - odds of getting honeycomb - - tweak: Made bee progress reports (50% towards new honeycomb, etc.) always show, - even if it's 0% - - tweak: Made some feedback text more obvious - - bugfix: Fixed being able to duplicate the bee holder object, this was not exploity, - just weird - - bugfix: Fixed being able to put two (or more) queens in the same apiary - - bugfix: Fixed some runtimes from hydro code assuming a plant gene exists - - bugfix: Fixed runtime when you use a honeycomb in your hand - - tweak: It now takes and uses 5u of a reagent to give a bee that reagent - - rscdel: Removed unused icon file - Ricotez: - - imageadd: The default white ghost form now has directional sprites. - - rscadd: The default white ghost form now also has (your) hair! Here's how it works. - - experiment: If you ghost from a body, you'll get the hair from that body. If it - has hair. - - experiment: If you hit Observe, you'll get the hair from the character you had - active in your setup window. If they had hair. - - wip: This only works with the default white ghost form right now (because the - other forms have the wrong shape or lack directional sprites), and with human - bodies since they're the only ones that have hair. Sorry lizards and plasmamen! - You'll get your turn next time. - - rscadd: A new preference called Ghost Accessories. This lets you configure if - you want your ghost sprite to show both hair and directional sprites, only directional - sprites or just use its original default version without directional sprites. - - rscadd: 'A new preference called Ghosts of Others. This preference is clientside - and lets you configure how other ghosts appear to you: as their own setting, - as the form they chose but without any hair or directional sprites, or as the - simple white ghost sprite if you''re sick of those premium users with their - rainbow ghosts.' - - experiment: The layout of the ghost preference buttons has slightly changed. The - old Choose Ghost Form and Choose Ghost Orbit are now a part of Ghost Customization, - which also contains the new Ghost Accessories button. Clicking Ghost Customization - will send you directly to Ghost Accessories if you don't have premium. The Preferences - tab now also contains the Ghost Display button, which lets you configure how - other ghosts appear to you. - - bugfix: Fixed a bug where the toggles for Ghost Accessories and Ghosts of Others - in the Preferences menu wouldn't save your preference update to your save file. - - bugfix: Renamed the "Ghost Display Settings" preference toggle button to "Ghosts - of Others", so it fits with the name the preference has everywhere else. - TehZombehz: - - rscadd: Paper sacks are now craftable by tablecrafting with 5 sheets of paper. - - rscadd: 'Comes in 5 different designs: Use a pen on a paper sack to change the - design.' - - rscadd: Certain paper sack designs can be modified with a sharp object to craft - a (creepy) paper sack hat. - Xhuis: - - bugfix: Portal storm messages now use the station name rather than the world name. - - bugfix: Shadowlings can no longer glare while shadow walking. - - bugfix: Progress bars are now properly shown when reloading revolvers. - - bugfix: Cyborgs and AIs are no longer knocked out when being stuffed into lockers. - - bugfix: Plasmamen can no longer be the patient zero of the space retrovirus. - - bugfix: Cyborgs and AIs now properly display death messages. - - bugfix: Revenants can no longer be closed into lockers. - - bugfix: Airlocks no longer play sounds or flash lights when denying access if - the airlock has no power. - - bugfix: Job spawn icons in mapping have been fixed. - - bugfix: Gibtonite's disarm message no longer include the outside viewer. - - bugfix: Cult walls and girders are now more streamlined and can be built with - runed metal. - - bugfix: Positronic brains and MMIs can no longer see ghosts. - - rscadd: When someone is turned into a statue, the statue now appears as a greyscale - version of them. - - rscadd: Returning from a statue to a human now knocks you down. - - rscdel: Flesh to Stone no longer works on dead mobs. - - bugfix: Wall-mounted flasher crates now have the proper price. - - bugfix: Wall-mounted flasher frames now have icons. - - bugfix: Upgraded resonators now have an inhand sprite. -2016-03-30: - Coiax: - - rscadd: Geiger counters can now be stored in the suit storage of radiation suits - RemieRichards: - - bugfix: fixes shift-clicking action buttons not instantly resetting their location. - (I'm only making a changelog for this because apparently barely noone even knows - you can move the buttons, let alone reset them...) - TehZombehz: - - rscadd: Honey buns and honey nut bars are now craftable using honey. - - tweak: Brewing mead now requires actual honey. -2016-04-01: - Erwgd: - - bugfix: Weed Killer bottles and Pest Killer bottles now contain 50 units. - - rscadd: The biogenerator can now make empty bottles and black pepper. - Isratosh: - - rscadd: Added an admin jump button to explosion logs. - Joan: - - rscadd: Traitors can now buy charger holoparasites. - - rscadd: Charger holoparasites move extremely fast, do medium damage, and can charge - at a location, damaging the first target it hits and forcing them to drop any - items they're holding. - Kor: - - rscadd: Mechas are now storm proof - - rscadd: Kinetic Accelerators now require two hands to fire, but are free standard - gear for miners. - - rscadd: All mining scanners are now automatic, with the advanced version having - longer range. - - rscadd: The QM and HoP no longer have spare vouchers. - - rscadd: You can buy a pack of two survival capsules with your mining voucher. - - rscadd: Mining Bots will no longer cause friendly fire incidents. They'll hold - fire if you are between them and their target - - rscadd: There are now four different mining drone upgrades available in the vendor. - - rscadd: Resonators can now have more fields and deal more melee damage. - - rscadd: Lavaland miners now have explorer's suits instead of hardsuits. Sprites - by Ausops. - - rscadd: You can now butcher Goliath's for their meat. It cooks well in lava. - Shadowlight213: - - rscadd: Clients now have a volume preference for admin-played sounds. - TehZombehz: - - rscadd: The 'Plasteel Chef' program has provided station chefs with complimentary - ingredient packages. There are several package themes, and chefs are provided - a random package on arrival. - coiax: - - rscadd: Free Golems on Lavaland have been naming their newborn siblings with a - wider range of geology terms -2016-04-02: - Eaglendia: - - rscadd: Central Command has released a new, more functional run of their most - stylish fashion line. - - rscadd: Head of Staff cloaks can now hold specific items - the antique laser gun - for the Captain, the replica energy gun for the Head of Security, the hypospray - for the Chief Medical Officer, the Hand Teleporter or RPED for the Research - Director, and the RCD or RPD for the Chief Engineer. -2016-04-03: - Erwgd: - - rscadd: Our valued colleagues in the security department are reminded to search - boots for hidden items (such as knives or syringes) as part of standard search - procedures. Alt-click a pair of boots to remove any hidden items. - Isratosh: - - bugfix: Fixed rudimentary transform not working properly on ghosts with minds. - - rscadd: Admin logs for bluespace capsules not activated on the mining Z level. -2016-04-04: - TechnoAlchemisto: - - rscadd: The recipes for some Trekchems are now back in the game - - rscadd: Bicaridine can be made with carbon, oxygen, and sugar. - - rscadd: Kelotane can be made with silicon and carbon. - - rscadd: Antitoxin can be made with nitrogen, silicon, and potassium - - rscadd: tricordrazine can be made by combining all three. -2016-04-05: - Erwgd: - - rscadd: Utility belts of all kinds can now accept gloves. Most belts, except janitorial - belts, may now also hold station bounced radios. - - rscadd: Hazard vests and most jackets can carry a station bounced radio as well. - Labcoats can be used to store a handheld crew monitor. - - rscadd: The autolathe can now make toolboxes. - Joan: - - rscadd: Adds protector holoparasites to traitor holoparasite injectors. - - rscadd: Protector holoparasites cause the summoner to teleport to them when out - of range, instead of the other way around. - - rscadd: Protector holoparasites have two modes; Combat, where they do and take - medium damage, and Protection, where they do and take almost no damage, but - move slightly slower. - - tweak: Explosive Holoparasites no longer teleport non-mobs when attacking, but - have a higher chance to teleport mobs. - - rscdel: Explosive Holoparasite bombs no longer trigger on their summoner or any - other parasites their summoner has. - - bugfix: Ranged Holoparasites no longer have nightvision active by default. It - can still be toggled on. - - tweak: Ranged Holoparasite snares no longer alert if the crossing mob is their - summoner or one of the parasites their summoner has. - - tweak: Ranged Holoparasites are slightly less visible in scout mode. - - tweak: Standard Holoparasites attack 20% faster than other parasite types. - - rscdel: Support Holoparasite beacons no longer require safe atmospheric conditions, - but the warp channel takes slightly longer, and is preceded with a visible message. - - tweak: Zombies can no longer destroy more than one airlock at a time. - - rscadd: The mining station has been updated. - MrStonedOne: - - bugfix: Centcom is glad to announce the end of sending workers to our control - group for space exposure testing, a fake station in "space" that noticeably - had air in "space". - TechnoAlchemisto: - - tweak: Detective scanners are now smaller. - - tweak: Pickaxes now fit in explorer suit exosuit slots. - bgobandit: - - rscadd: Alt-clicking a fire extinguisher cabinet opens and closes it. That is - all. -2016-04-06: - CoreOverload: - - rscadd: You can now put slimes in stasis by exposing them to room temp CO2. Useful - for both fighting the slimes and safely storing them. - Erwgd: - - rscadd: The autolathe can now make hydroponics tools! Access the design routines - in the Misc. category of the machine. - LanCartwright: - - tweak: Custom viruses with stealth values of 3 or above are now invisible on the - PANDEMIC and no longer visible on health huds. - MrStonedOne: - - bugfix: Centcom is happy to report that our single sided windows and our windoors - should once again create an airtight seal. - bgobandit: - - rscadd: Honk! Nanotrasen's clowning and development department has invented the - clown megaphone, standard in all clowning loadouts! Honk honk! -2016-04-07: - Kor: - - rscadd: The Laser Cannon in RD has been replaced with the Accelerator Laser Cannon. - Try it out! - - rscadd: Mechas now have armour facings. Attacking the front will deal far less - damage, while attacking the back will deal massive bonus damage. - - rscadd: EMPs now deal far less damage/drain to mechas. - Kor and Ausops: - - rscadd: Survival pod interiors have been redone. - - rscadd: Survival pods now contain a stationary GPS computer. - - rscadd: You can now toggle your GPS off with alt+click. - bgobandit: - - rscadd: Due to budget cuts, Nanotrasen is no longer utilizing copy-protected paper - for its classified documents. Fortunately, our world-class security team has - always prevented any thefts or photocopies from being made! - - rscadd: Secret documents can be photocopied. If you have an objective to steal - any set of documents, a photocopy will be accepted. If you must steal red or - blue documents, a photocopy will NOT be accepted. Enterprising traitors can - forge the red/blue seal with a crayon to take advantage of this. -2016-04-09: - GunHog: - - rscadd: Aliens may now force open unbolted, unwelded airlocks. Unpowered airlocks - open faster than powered ones. Has a cool sound provided by @Ultimate-Chimera! - - tweak: Alien Drone health increased to 125 hp. - - tweak: Alien drone is now faster! - - tweak: Alien egg and larva maturation times halved. - - tweak: Resin membrane health increased to 160 hp. - - rscadd: Aliens may now open firelocks. - - rscadd: Aliens may now unweld scrubbers and vents. (From the outside!) - - tweak: Droppers no longer affect aliens. - Joan: - - rscdel: You can no longer drop survival capsules on top of dense objects, such - as the windows in the emergency shuttle. You can still drop them on non-dense - objects and mobs, however. - - tweak: Swarmers can now deconstruct objects simply by clicking. - - rscadd: Swarmers can still teleport mobs away via ctrl-click. - - bugfix: Emps will now properly damage swarmers. - Kor: - - rscadd: Added wisp lanterns to necropolis chests. - - rscadd: Added red/blue cube pairs to necropolis chests. - - rscadd: Added meat hooks to necropolis chests. - - rscadd: Added immortality talismans to necropolis chests. - - rscadd: Added paradox bags to necropolis chests. - - rscadd: Ripley drills work again. Go tear up lavaland. - PKPenguin321: - - tweak: Goofball's grab nerf has been reverted. - TechnoAlchemisto: - - tweak: Pickaxe upgrades are now better. - coiax: - - tweak: Efficiency Station Testing Lab now has a Drone Shell Dispenser - - tweak: Fixed an issue with a door on the Golem Ship - - rscadd: The unfathomable entity Carp'sie has blessed vir followers with mysterious - carp guardians. - - rscadd: Nanotrasen Cyborgs are now able to empty ore boxes without human assistance - - rscadd: Ore boxes are now craftable with 4 planks of wood - - tweak: Ore boxes now drop their contents when destroyed, or dismantled with a - crowbar - coiax, bobdobbington, Core0verload: - - rscadd: An experimental plant DNA manipulator, based on machinery recovered from - ancient seed vaults, has been installed in the Botany department. -2016-04-11: - Joan: - - rscadd: Blob cores will take slight brute damage from explosions. - RandomMarine: - - rscadd: Additional luxuries have been added to golem ships. Including new rewards. - Praise be to The Liberator! - - rscdel: However, jaunters are no longer easily obtained by free golems. - RemieRichards: - - rscadd: The Station Blueprints now display the piping/wiring and some of the machinery - the station started with, to assist in repairs - coiax: - - rscadd: Emagging the cargo console also unlocks regular contraband, in addition - to syndicate gear - - rscadd: A working drone shell dispenser is now on display in MetaStation's museum, - displaying the virtue of the tireless little workers! - - rscadd: Dreamstation now has a drone shell dispenser in the Toxins Launch Room -2016-04-12: - Incoming5643: - - rscadd: Leading scientists have finally proven that humans (and xenos) in fact - have tongues in their mouths. - - rscadd: Swapping out tongues allows the various races to change their speech impediments. - Putting a xeno tongue in someone allows them to make the hissing sound like - a xeno whenever they speak. - - rscdel: There are no erp mechanics tied to this feature. - - experiment: Remember that tongues are stored in the MOUTH, selecting the head - isn't good enough. - Kor: - - rscadd: Ash walker starting gear has been rebalanced. - - rscadd: Ash walkers can no longer use guns. - TrustyGun: - - rscadd: After carefully investing in the market, the Captain had enough money - to replace his silver flask with a golden one! - - rscadd: The Detective is now bringing his personalized flask to work, due to the - grim work he has to do. - - rscadd: The Booze-O-Mat now stocks 3 flasks. -2016-04-16: - Bawhoppen: - - tweak: Cryo is no longer god-awful. - CoreOverload: - - rscadd: A lot of items are now exportable in cargo. - - rscadd: Use Export Scanner to check any item's export value. - Erwgd: - - rscadd: Forks, bowls, drinking glasses, shot glasses and shakers can now be made - and recycled in the autolathe! Access the designs in the new 'Dinnerware' category. - - tweak: Kitchen knives have been moved to the Dinnerware category of the autolathe. - - rscadd: Butcher's cleavers can now be made in a hacked autolathe. - Fox McCloud: - - rscadd: Slime batteries now self-recharge. - - rscadd: Adds transference potion. A potion that allows the user to transfer their - consciousness to a simple mob. - - rscadd: Adds rainbow slime core reaction that generates a consciousness transference - potion when injected with blood. - Iamgoofball, Lati, Geo_Jerkal, Tanquetsunami25: - - rscadd: Lati requested that the Slime Processor will now automatically scoop up - any dead slimes into itself for processing. - - rscadd: Geo_Jerkal requested that you be able to mix Arnold Palmers with Tea and - Lemon Juice. - - rscadd: Tanquetsunami25 requested that cyborg be able to boop. - Incoming5643: - - rscdel: Removed the horrible meme skeletons, please don't sue us. - Kor: - - rscadd: Adrenals, no slips, surplus crates and SUHTANDOS now have minimum population - requirements before they can be purchased. - KorPhaeron: - - rscadd: You now need to butcher goliaths and watchers on lavaland to receive their - loot. Use the combat knives to do so. - Lati: - - rscadd: Custom floor tiles can now be added to floorbots. They will start replacing - other tiles with these tiles if the option is toggled on. - coiax: - - rscadd: Boxstation, not to be outdone by all the other competing station designs, - has installed a drone shell dispenser in the Testing Lab, which makes automated - drones to help fix the station. - - rscadd: Toy fans, rejoyce! The famous skeleton brothers from the beloved game - Belowyarn now have toys that you can win from the arcade machines! - - rscadd: Airlock painters can be printed at your local autolathe - - rscadd: Please do not attempt suicide with the airlock painter or the medical - wrench. - - rscadd: Metastation now has a plant DNA manipulator in Botany. - - rscadd: Using the fire extinguisher on yourself or others while in HELP intent - will spray you or them, rather than beat their probably flaming body with a - metal object. - - tweak: Alt-clicking extinguishers to empty them now wets the floor underneath - them. - lordpidey: - - rscadd: Meth labs can now blow up if you don't purify the ingredients or over-heat - the end product. - nullbear: - - rscadd: Added attack verbs for heart and tongue organs - - tweak: Maximum output of air pumps has been raised. -2016-04-18: - Joan: - - rscdel: Crates are now dense even when open. - - rscadd: You can now climb onto crates in the same way as table and sandbags, though - climbing onto crates is very fast and does not stun you. - - wip: You can walk on crates, provided both are closed/open or the crate you're - on is closed. - - rscdel: You can't close or open a crate if there's a large mob on top of it. - - rscadd: Stuffing items into a closet or crate is now instant and does not close - the closet or crate. Stuffing mobs into a closet or crate still takes time and - closes the closet/crate in question. - - imageadd: Crowbars and wirecutters have new inhand sprites. Crowbars can now be - distinguished from wrenches in-hand. - RandomMarine: - - tweak: Cloth items removed from biogenerator. Instead, it can create stacking - cloth that crafts those items. - - rscadd: In addition, cloth can be used to create grey jumpsuits, backpacks, dufflebags, - bio bags, black shoes, bedsheets, and bandages. - - tweak: Bedsheets now tear into cloth instead of directly into bandages. - Shadowlight213: - - tweak: AI will be notified when one of their cyborgs is detonated. - coiax: - - bugfix: Fixed slime grinders not sucking up more than one slime - - rscadd: Drones now start with a spacious dufflebag full of tools, so they will - stop stealing the captain's - - bugfix: Fixed issues with drones wearing chameleon headgear. - - rscadd: Added admin-only "snowflake drone" (also known as drone camogear) headgear. - nullbear: - - bugfix: Fixes air canisters being silent when bashed. -2016-04-20: - Erwgd: - - rscadd: The autolathe can now make trays. - Fox McCloud: - - bugfix: Fixes abductor vests having no cooldown between uses - Kor: - - rscadd: You can now craft boats and oars out of goliath hides. These boats can - move in lava. - - rscadd: Added a spooky, upgraded boat to necropolis chests. - coiax: - - tweak: Slime grinders now cease suction of new slimes while grinding - coiax, Joan: - - rscadd: Drone dufflebags now have their own sprite. - kevinz000: - - rscadd: 'Admin Detection Multitool: A multitool that shows when administrators - are watching you! Now you can grief in safety!' - - tweak: Syndicate R&D scientists have significantly increased the range of their - "AI detection multitools", making them turn yellow when an AI's tracking is - near, but not on you just yet! -2016-04-21: - Kor: - - rscadd: Mechas can now toggle strafing mode. -2016-04-22: - Bawhoppen: - - rscadd: Security belts can now hold any type of grenade. This includes barrier - grenades. - - rscadd: Janitorial belts are now able to store chem grenades. - - rscadd: Military belts have been given a size upgrade, so they can now hold larger - items. - - rscadd: Bandoliers have been given a buff and now can hold a much larger amount - of ammunition. - nullbear: - - bugfix: xenobio console is deconstructable again. - - tweak: syndibomb recipe calls for any matter bin, scaling effectiveness with tier. -2016-04-23: - Joan: - - bugfix: Aliens can now open crates and lockers. - - bugfix: Aliens and monkeys can now climb climbable objects, such as crates and - sandbags. - - rscadd: Aliens climb very, very fast. - Kor: - - rscadd: Running HE pipes over lava will now heat the gas inside. - - rscadd: Alt+clicking on your mecha (while inside it) will toggle strafing mode. - Mercenaryblue: - - rscadd: Allowed all corgis to wear red wizard hats. - TechnoAlchemisto: - - rscadd: Goliaths now drop bones, and Watchers drop sinews. - - rscadd: You can craft primitive gear from bone and sinew. - coiax: - - bugfix: Non-humans are now able to interact with bee boxes. -2016-04-25: - Joan: - - bugfix: You can once again hit a closet or crate with an item to open it. - Kor Razharas: - - rscadd: Adds support for autoclicking. - - rscadd: The Shock Revolver has been added to RnD. - - rscadd: The Laser Gatling Gun has been added to RnD. The Gatling Gun uses autoclick - to fire as you hold down the mouse. - - rscadd: The Research Director now starts with a box of firing pins. - - rscadd: The SABR and Stun Revolver recipes have been removed from RnD - coiax: - - rscadd: Laughter demons are like slaughter demons, but they tickle people to death - - tweak: Slaughter demons are no longer able to cast spells while phased. - - tweak: Wizards can now speak while ethereal, but still cannot cast spells while - ethereal. - - rscadd: 'Centcom''s "drone expert" reports that drones vision filters have been - upgraded to include the option of making all beings appear as harmless animals. - info: As always, all drone filters are togglable.' - - rscadd: As a sign of friendship between the Free Golems and Centcom, they have - modified Centcom's jaunter to be worn around a user's waist, which will save - them from falling to their death in a chasm. - - experiment: The Golems warn that these modifications have created a risk of accidental - activation when exposed to heavy electromagnetic fields. - - tweak: Renamed hivelord stabilizer to stabilizing serum. - - rscadd: Centcom regret to inform you that new instabilities with nearby gas giants - are causing exospheric bubbles to affect the telecommunications processors. - Please contact your supervisor for further instructions. - - rscadd: The Janitor's Union has mandated additional features to station light - replacer devices. - - rscadd: The light replacer now can be used on the floor to replace the bulbs of - any lights on that tile. - - rscadd: The light replacer now eats replaced bulbs, and after a certain number - of bulb fragments (four) will recycle them into a new bulb. - - tweak: The description of the light replacer is now more informative. - - rscadd: Clown mask appearance toggle now has an action button. -2016-04-26: - Iamgoofball & Super Aggro Crag: - - tweak: Fluorosulfuric Acid now has doubled acid power. - - experiment: Fluorosulfuric Acid now does BONUS burn damage scaling on the time - it's been inside the consumer. - Joan: - - tweak: Blobbernauts now spawn at half health. - - tweak: Blobbernauts regeneration on blob is now 2.5 health per tick, from 5. - - tweak: Blobbernauts now cost 40 resources to produce, from 30. - - rscdel: Factories supporting blobbernauts do not spawn spores. - Lati: - - tweak: Syndicate bomb can be only delayed once by pulsing the delay wire. Time - gained from this is changed from 10 seconds to 30 seconds. - TechnoAlchemisto: - - tweak: Goliath plates can now be stacked. - phil235: - - rscadd: More structures and machines are now breakable and/or destroyable with - melee weapon. Additionally, Some structures and machines that are already breakable/destroyable - are now affected by more attack methods (gun projectiles, thrown items, melee - weapons, xeno/animal attacks, explosions). - - rscadd: Hitting any machine now always makes a sound. - - rscadd: You can hit closed closets/crates and doors by using an item on harm intent - (but it doesn't actually hurt them). - - rscadd: you can now burst filled water balloons with sharp items. - - bugfix: Wooden barricade drops wood when destroyed. - - bugfix: Slot machines with coins inside are deconstructable now. -2016-04-27: - TechnoAlchemisto: - - rscadd: Miners can now select explorer belts from the mining vendor using their - vouchers, or mining points. -2016-04-28: - Bawhoppen: - - tweak: Sandbags are no longer tablecrafted. Now you just put in sand (or ash) - by hand to make them. - - rscadd: Miners and Engis now get boxes of empty sandbags in their lockers. Miners - also get a few premade aswell. - - rscadd: You can now break sandstone down into normal sand. - Joan: - - rscadd: Attacking a blob with an analyzer will tell you what its chemical does, - its health, and a small fact about the blob analyzed. - - rscdel: 'NERFS:' - - tweak: Zombifying Feelers does less toxin damage. - - tweak: Adaptive Nexuses does slightly less brute damage. - - tweak: Replicating Foam does slightly less brute damage. - - tweak: Blob Sorium does slightly less brute damage. - - tweak: Blob Dark Matter does slightly less brute damage. - - tweak: Cyrogenic Liquid injects slightly less frost oil and ice and does slightly - less stamina damage. - - tweak: Pressurized Slime does less brute, oxygen, and stamina damage, and extinguishes - objects and people on turfs it wets. - - rscdel: Blob core strong blobs no longer give points when removed. - - wip: 'PROBABLY BUFFS:' - - tweak: Flammable Goo now does slightly more burn damage and applies more firestacks, - but applies fire to blob tiles that don't share its chemical. - - tweak: Energized Fibers does slightly more burn damage, slightly less stamina - damage, and now takes damage from EMPs. - - rscadd: 'BUFFS:' - - tweak: Boiling Oil does slightly more burn damage and applies more firestacks. - - tweak: Reactive Gelatin does slightly more damage on average. - - tweak: Penetrating Spines now also ignores bio resistance in addition to armor. - - tweak: Hallucinogenic Nectar causes more hallucinations. - - tweak: Normal strong blobs now refund 4 points when removed, from 2. - - rscadd: Charger holoparasites now play a sound when hitting a target, as well - as shaking the target's camera. - PKPenguin321: - - rscadd: The warden's locker now contains krav maga gloves. - TechnoAlchemisto: - - rscadd: You can now craft skull helmets from bones. - - rscadd: Syndicate bombs are now harder to detect -2016-04-29: - Bawhoppen: - - rscadd: Several lesser-used uplink's TC cost have been rebalanced. - - tweak: Steckhin down from 9TC to 7TC. - - tweak: Tactical medkit down from 9TC to 4TC. - - tweak: Syndicate magboots from 3TC to 2TC. - - tweak: Powersinks down from 10TC to 6TC. - - tweak: Stealth rad-laser down from 5TC to 3TC. - - tweak: Bundles have been updated accordingly. - Incoming5643: - - rscadd: The staff/wand of door creation can now also be used to open airlock doors. - - rscadd: Doors spawned by the staff/wand now start open. Keep this in mind the - next time you try to turn every wall on the escape shuttle into a door. - Robustin: - - rscdel: The Teleport Other, Veil, Imbue, Reveal, Disguise, Blood Drain, Timestop, - Stun, Deafen, Blind, Armaments, Construct Shell and Summon Tome runes are gone. - - rscadd: Disguise, Veil/Reveal, Construct Shell and Armaments are now talismans. - The Construction talisman requires 25 sheets of metal. - - rscadd: Cultists will now receive a warning when attempting to use emergency communion - or create the Nar-Sie rune - - rscadd: Cultists can now create talismans with a super-simple Talisman-Creation - rune. It takes about 10 seconds to invoke and will present a menu of all the - talisman choices available. Its as simple as tossing the paper on, clicking - the rune, and selecting your talisman. - - rscadd: Cultists now have a proc, "How to Play" that will give a basic explanation - of how to succeed as a cultist. - - rscadd: The new Talisman of Horror is a stealthy talisman that will cause hallucinations - in the victim. Great for undermining security without having to commit to murder - them in middle of the hall. - - rscadd: Creating the Summon Nar-Sie rune does takes slightly less time, but now - adds a 3x3 square of red barrier shields (60hp each) to prevent the rune-scriber - from being bumped by other idiots. This works in conjunction with the rune's - warning to give crew a chance to stop the summoning. Manifest ghost has a weaker - 1x1 shield to prevent bumps as well. - - rscadd: Talismans are now color-coded by their effect so you can easily organize - and deploy talismans. - - rscadd: You can now make colored paper in the washing machine using crayons or - stamps, honk. - - rscadd: The Electromagnetic Disruption rune will now scale with the number of - cultists invoking the rune. **A full 9-cultist invocation will EMP the entire - station!** - - rscadd: Armaments will now give the recipient a new cult bola. - - rscadd: The new Talisman of Shackling will apply handcuffs directly to the victim. - These cuffs will disappear when removed. - - tweak: Cult slur is a little less potent so victims might be able to squeeze in - a coherent word or two if you let them keep jabbering on the radio, stun talismans - now have less of a health cost and the stun is back to 10 seconds, from 9. - - tweak: Rune and Talisman names now give a much clearer idea of what they do. - - experiment: The following changes are courtesy of ChangelingRain - - rscadd: The Teleport rune now allows cultists to select which rune to teleport - to, and teleports everything on it. - - rscadd: Veil and Reveal are merged into Talisman of Veiling. Veiling has two uses, - the first use will hide and the second use will reveal. - - rscadd: New icons for the cult bola - - tweak: You can now attack fellow cultists with a Talisman of Arming to arm them - with robes and a sword. - - tweak: You can now only place one rune per tile. - - tweak: Ghosts are notified when a new manifest rune is created. - TechnoAlchemisto: - - rscadd: Sinew can now be fashioned into restraints. - coiax: - - tweak: Internals Crate now contains breath masks and small tanks. - - rscadd: Metal foam grenade box crate added for 1000 points - - rscadd: Added two Engineering Mesons to Engineering Gear Crate - - tweak: Engineering Gear now costs 1300 - - rscadd: Breach Shield Generator Crate added for 2500 points - - rscadd: Grounding Rod Crate added for 1700 points - - rscadd: PACMAN Generator Crate added for 2500 - - rscadd: Defibrillator Crate added for 2500 - - rscadd: Added more helmets to the Laser Tag Crate. - - rscadd: Nanotrasen Customs report that some wide band suppliers have been providing - "alternative" firing pins. Nanotrasen reminds all crewmembers that contraband - is contraband. - - rscadd: Contraband crates now appear visually similar to legitimate crates. - - bugfix: The cargo shuttle's normal transit time has been restored. - nullbear: - - rscadd: Adds a preference option, allowing players to toggle whether recipes with - no matching components should be hidden. -2016-04-30: - Joan: - - rscadd: Blobs attempting to attack the supermatter will instead be eaten by it. - - experiment: This doesn't mean throwing a supermatter shard at the blob is a good - idea; blobs attacking it will gradually damage it, eventually resulting in a - massive explosion, and it will not consume blobs if on a space turf. - - tweak: Hitting a locker or crate with an ID, PDA with ID, or wallet with ID will - try to toggle the lock instead of trying to open it. - - imageadd: Cable coils, cablecuffs, and zipties now all have properly colored inhands. - Kor: - - rscadd: Megafauna have been added to lavaland. - - rscadd: Ash Drakes have been spotted roaming the wastes. Use your GPS to track - their fiery signals. - - rscadd: You can now knock on the Necropolis door, but it's probably best that - you don't. - Mercenaryblue: - - rscadd: Adds a basic paper plane to the game. Fold paper with alt-clicking. - - rscadd: Paper planes are now fully compatible with every stamps on station. - bgobandit: - - rscadd: 'Nanotrasen has released Cards Against Spess! Visit your local library - for a copy. Warning: may cause breakage of the fourth wall.' -2016-05-02: - Joan: - - tweak: Blob spores spawn from factories 2 seconds faster, but the factory goes - on cooldown when any of its spores die. - - experiment: You can examine tomes, soulstones, and construct shells to see what - you can do with them. - - rscadd: Releasing a shade from a soulstone now allows you to reuse that soulstone - for capturing shades or souls, instead of preventing the stone's use forever - if the shade dies. - - imageadd: Runes now actually pulse red on failure. - - rscadd: The Summon Cultist rune no longer includes the cultists invoking it in - the selection menu. - - tweak: Imperfect Communication renamed to Emergency Communication. - - rscdel: You can no longer hide the Nar-Sie rune with a Talisman of Veiling/Revealing. - Kor: - - rscadd: Engineering cyborgs now have internal blueprints. - Lzimann: - - tweak: Automatic nexus placing time changed from 2 to 15 minutes. - - tweak: Prophet's gear(hat and staff) prioritizes the backpack instead of automatically - equipping. - - rscadd: Divine telepathy and prophet to god speak now have a follow button for - ghosts. - - rscadd: Divine telepathy and prophet to god speak now has the god's color. - - bugfix: CTF spawn protection trap is no longer constructable - Mercenaryblue: - - tweak: Drastically reduced the chances of eye damage when throwing a paper plane. - RandomMarine: - - tweak: Medical HUDs improved. To better prioritize patients, subjects deep into - critical condition have a blinking red outline around the entire HUD icon, and - will blink more rapidly when very close to death. - TechnoAlchemisto: - - tweak: Security uniforms have been made more professional, and more tactical. - TrustyGun: - - rscadd: By crafting together a legion skull, a goliath steak, ketchup, and capsaicin - oil, you can create Stuffed Legion! Be careful, it's hot. - coiax: - - rscadd: Centcom Department of [REDACTED] have announced a change of supplier of - [EXPLETIVE DELETED]. As such, for security reasons, the absinthe [MOVE ALONG - CITIZEN] will instead be [NOTHING TO SEE HERE]. We hope that this will not affect - the performance of the [INFORMATION ABOVE YOUR SECURITY CLEARANCE]. - nullbear: - - rscadd: A reminder for crew to avoid mopping floors in cold rooms, as the water - will freeze and provide a dangerous slipping hazard known as 'ice'. Running - on it is not recommended. - - rscadd: Frostoil is an effective chemical for rapidly cooling areas in the event - of a fire. - - rscadd: Added X4, a breaching charge more destructive than C4, it can be purchased - from uplinks. - - rscadd: C4 can be used with assemblies. - - bugfix: Fixes chembomb recipe to use any matter bin. Again. - - bugfix: ARG's disappear once finished reacting. -2016-05-03: - coiax, Robustin: - - tweak: Changeling Fleshmend is much less effective when used repeatedly in a short - time. Changeling Panacea is much more effective at purging reagents, reducing - radiation and now reduces braindamage. -2016-05-04: - Fox McCloud: - - tweak: shock revolver projectiles are now energy instead of bullets - Joan: - - rscdel: Cultists no longer communicate via tomes. - - rscadd: Cultists now communicate via the 'Communion' action button. - - rscadd: Examining the blob with an active research scanner or medical hud will - display effects, akin to hitting it with an analyzer. - - rscadd: Improved medical HUDs to work on all living creatures. - - rscadd: Drones and swarmers, being machines, require a diagnostic HUD for analysis - instead. - TechnoAlchemist: - - rscadd: You can now craft cloaks from the scales of fallen ash drakes, look for - the recipe in tablecrafting! - coiax: - - rscadd: The Service and the Standard cyborg module now have a spraycan built in, - for hijinks and passing on important urban messages. The Service cyborg module - also has a cyborg-hand labeler, in case anything needs to be labelled. - - rscadd: 'Centcom Suicide Prevention wishes to remind the station: Please do not - kill yourself with a hand labeler.' - xxalpha: - - bugfix: Fixed the mk-honk prototype shoes. -2016-05-05: - Joan: - - tweak: Revenants are slower while revealed. - - rscdel: Revenants can no longer cast inside dense objects. - - tweak: Lying down will cure Blight much, much faster. - \"Macho Man\" Randy Savage: - - rscadd: OOOHHH YEAAAAHHHH - - rscadd: SNAP INTO A JLIM SIM WITH THE ALL NEW WRESTLING BELT - - rscadd: YOU CAN FREAKOUT YOUR OPPONENTS WITH THE 5 HOT MOVES ON THIS BELT YEAH - - rscadd: PRAY TO THE LOCAL SPACE GODS TO EXCHANGE YOUR TELECRYSTALS TO ENSURE THE - CREAM RISES TO THE TOP -2016-05-07: - Robustin: - - rscadd: A small pantry has been added to SW maintenance. - nullbear: - - rscadd: Makes Shift+Middleclick the hotkey for pointing. - phil235: - - rscadd: DISMEMBERMENT! Humans can now lose their bodyparts. Explosions and being - attacked with a heavy sharp item on a specific bodypart can cause dismemberment. - - rscadd: You can't be handcuffed or legcuffed if you're missing an arm or leg. - You can't use items when you have no legs, your arms are too busy helping you - crawl, unless your are buckled to a chair. You're slower when missing a leg. - - rscadd: You lose organs and items if the bodypart they are inside gets cut off. - You can always retrieve them by cutting the dropped bodypart with a sharp object. - - rscadd: Medbay can replace your missing limbs with robotic parts via surgery, - or amputate you. - - rscadd: Changelings do not die when decapitated! They can regrow all their limbs - with Fleshmend, or just one arm with Arm Blade or Organic Shield. - - rscadd: Your chest cannot be dropped, but it will spill its organs onto the ground - when dismembered. -2016-05-08: - CoreOverload: - - rscadd: You can now de-power inactive swarmers with a screwdriver to prevent them - from activating. - - rscadd: Recycle depowered swarmers in autolathe or sell them in cargo! - Joan: - - rscadd: Cultist constructs, and shades, can now invoke runes by clicking them. - - rscdel: This does not include Manifest Ghost, Blood Boil, or Astral Journey runes. - - rscadd: Medical huds will now show parasites in dead creatures. - KorPhaeron: - - rscadd: Burn weapons can now dismember, and they reduce the limb to ash in the - process - - rscadd: Weapons with high AP values will now dismember limbs much easier. These - values are subject to change depending on how things play out over the next - week or two. - - rscadd: Various weapons with high AP values had them lowered (chaplain scythe, - energy sword, dualsaber) to prevent them taking limbs off in a single hit. - - rscadd: The chaplain has two new weapons (they are mechanically identical to previous - weapons, before anyone gets upset about balance). One is dismemberment themed, - the other is related to a new antagonist. - Mercenaryblue: - - rscadd: Throwing a Banana Cream Pie will now knock down and cream the target's - face. - - rscadd: You can clean off the cream with the usual methods, such as soap, shower, - cleaner spray, etc. - - rscadd: The Clown Federation would like to remind the crew that the HoS is worth - double points! Honk! - Robustin: - - experiment: There are rumors that the Cult's 'Talisman of Construction', which - turns ordinary metal for construct shells, can be used on plasteel to create - structures. If the stories are true, the cult has been producing relics of incredible - power through this transmutation. - coiax: - - rscadd: To save credits, Centcom has subcontracted out emergency shuttle design - to third parties. Rest assured, all of these produced shuttles meet our stringent - quality control. - - tweak: Lavaland ruins spawning chances have been modified. Expect to see more - smaller and less round affecting ruins, and no duplicates of major ruins, like - ash walkers or golems. - lordpidey: - - rscadd: Infernal devils have been seen onboard our spacestations, offering great - boons in exchange for souls. - - rscadd: Employees are reminded that their souls already belong to nanotrasen. If - you have sold your soul in error, a lawyer or head of personnel can help return - your soul to Nanotrasen by hitting you with your employment contract. - - rscadd: Nanotrasen headquarters will be bluespacing employment contracts into - the Lawyer's office filing cabinet when a new arrival reaches the station. It - is recommended that the lawyer create copies of some of these for safe keeping. - - rscadd: Due to the recent infernal incursions, the station library has been equipped - with a Codex Gigas to help research infernal weaknesses. Please note that reading - this book may have unintended side effects. Also note, you must spell the devil's - name exactly, as there are countless demons with similar names. - - rscadd: When a devil dies, if the proper banishment ritual is not performed on - it's remains, the devil will revive itself at the cost of some of it's power. The - banishment ritual is described in the Codex Gigas. - - rscadd: When a demon gains enough souls, It's form will mutate to a more demonic - looking form. The Arch-demon form is known to be on par with an ascended shadowling - in power. -2016-05-09: - Joan: - - tweak: Sporing Pods produces spores when expanding slightly more often. - - tweak: Replicating Foam now only expands when hit with burn damage, from all damage, - but does so at a higher chance. Free expansion from it is, however, more rare. - - tweak: Penetrating Spines does slightly more brute damage, and Poisonous Strands - does its damage 50% faster. - KorPhaeron: - - rscadd: The AI no longer has a tracking delay because artificial lag is the most - miserable thing in the world. - Razharas: - - tweak: crafting can now be done everywhere, little button near the intents with - hammer on it(its not T) opens the crafting menu, if you are in a locker or mech - only things in your hands will be considered for crafting - coiax: - - tweak: Skeletons now have bone "tongues" -2016-05-11: - Joan: - - rscadd: Shades can move in space. - - rscadd: Artificers can now heal shades. - coiax: - - tweak: Added action button to chameleon stamp - - rscadd: Added APPROVED and DENIED stamps to Bureaucracy Crate - - rscadd: Added the cream pie closet to various maps. Added contraband Cream Pie - Crate to Cargo. - pudl: - - rscadd: The armory has been redesigned. -2016-05-12: - Shadowlight and coiax: - - rscdel: Due to numerous reports of teams using human weapons instead of stealth - when carrying out their assignments, future teams have been genetically modified - to only be able to use their assigned blaster and are unable to use human weapons. -2016-05-13: - Joan: - - rscadd: Cultists can now unanchor and reanchor cult structures by hitting them - with a tome. Unanchored cult structures don't do anything. - KorPhaeron: - - rscadd: Drake attacks are now much easier to avoid. - - rscadd: Player controlled drakes can now consume bodies to heal, and alt+click - targets to divebomb them. - TechnoAlchemisto: - - rscadd: More items have been added to the mining vendor, check them out! -2016-05-14: - Cruix: - - bugfix: Fixed foam darts with the safety cap removed being reset when fired. - - rscadd: Added the ability to remove pens from foam darts. - - bugfix: Foam darts with pens inside them are no longer destroyed when fired. - - bugfix: Foam darts no longer drop two darts when fired at a person on a janicart. - Joan: - - rscdel: The Raise Dead rune no longer accepts dead cultists as a sacrifice to - raise the dead. - Metacide: - - rscadd: 'A small update for MetaStation, changes include:' - - rscadd: Added extra grounding rods to the engine area to stop camera destruction. - - rscadd: Added canvases and extra crayons to art storage and some easels to maint. - - rscadd: Added formal security uniform crate for parades to the warden's gear area. - - rscadd: The armory securitron now starts active. - - rscadd: The genetics APC now starts unlocked. - - rscadd: Other minor changes and fixes as detailed on the wiki page. - coiax, Nienhaus: - - rscdel: Unfortunately, the Belowyarn toys have been withdrawn from distribution - due to Assistants choking on the batteries. Centcom has sent their condolences - to the battery manufacturing plant. - - rscadd: We are introducing Oh-cee the original content skeleton figurines. Pull - its string, and hear it say a variety of phrases. Not suitable for infants or - assistants under 36 months. - - tweak: Note that pulling the string of all talking toys is now visible to others. - - rscadd: Talking toys produce a lot more chatter than they did before. So do some - skeleton "tongues". - pudl: - - rscadd: Adds normal security headsets to security lockers - xxalpha: - - bugfix: Fixed drone dispenser multiplying glass or metal. -2016-05-15: - Iamgoofball: - - rscadd: Nanotrasen is short on cash, and are now borrowing escape shuttles from - other stations, and Space Apartments. - Mercenaryblue: - - rscadd: Turns out a bike horn made with Bananium is flipping awesome! Honk! -2016-05-18: - Cruix: - - bugfix: unwrapping an item with telekinesis no longer teleports the item into - your hand. - Metacide: - - rscadd: 'MetaStation: the library and chapel have had windows removed to make - them feel more isolated.' - MrStonedOne: - - tweak: Tesla has been rebalanced. - - tweak: It should now lose balls slower, increase balls faster, and be a bit more - aggressive about finding nearby grounding rods. - - tweak: additional zaps from it's orbiting balls should be a bit more varied, but - a touch less powerful. - Robustin: - - rscadd: Lings have a new default ability, Hivemind Link. This lets you bring a - neck-grabbed victim into hivemind communications after short period of time. - You can talk to victims who are in crit/muted and perhaps persuade them to help - you, give you intel, or even a PDA code. The link will stabilize crit victims - to help ensure they do not die during the link. - Shadowlight213: - - bugfix: Cleanbot and floorbot scanning has greatly improved. they should prioritize - areas next to them, as well as resolve themselves stacking on the same tiles. - coiax: - - rscadd: Kinetic accelerators only require one hand to be fired, as before - - rscdel: Kinetic accelerators recharge time is multiplied by the number of KAs - that person is carrying. - - rscdel: Kinetic accelerators lose their charge quickly if not equipped or being - held - - rscadd: Kinetic accelerator modkits (made at R&D or your local Free Golem ship) - overcome these flaws -2016-05-19: - Razharas: - - rscadd: HE pipes once again work in space and in lava. - - rscadd: Space cools down station air again -2016-05-20: - KorPhaeron: - - rscadd: The HoS now has a pinpointer, the Warden now has his door remote. - bgobandit: - - rscadd: Nanotrasen has begun to research BZ, a hallucinogenic gas. We trust you - will use it responsibly. - - rscadd: BZ causes hallucinations once breathed in and, at high doses, has a chance - of doing brain damage. - - rscadd: BZ is known to cause unusual stasis-like behavior in the slime species. - coiax: - - rscadd: Neurotoxin spit can be used as makeshift space propulsion -2016-05-21: - Iamsaltball: - - rscadd: Heads of Staff now have basic Maint. access. - NicholasM10: - - rscadd: The chef can now make Khinkali and Khachapuri - coiax: - - rscdel: NOBREATH species (golems, skeletons, abductors, ash walkers, zombies) - no longer have or require lungs. They no longer take suffocation/oxyloss damage, - cannot give CPR and cannot benefit from CPR. Instead of suffocation damage, - during crit they take gradual brute damage. - - rscdel: NOBLOOD (golems, skeletons, abductors, slimepeople, plasmamen) species - no longer have or require hearts. - - tweak: NOBREATH species that require hearts still take damage from heart attacks, - as their tissues die and the lack of circulation causes toxins to build up. - - rscdel: NOHUNGER (plasmamen, skeletons) species no longer have appendixes. - coiax, OPDingo: - - tweak: Renamed and reskinned legion's heart to legion's soul to avoid confusion; - it is not a substitute heart, it is a supplemental chest organ. - - rscadd: Legion's souls are now more obviously inert when becoming inert. - nullbear: - - tweak: Wetness updates less often. - - rscadd: Wetness now stacks. Spraying lube over a tile that already has lube, will - make the lube take longer to dry. Likewise, dumping 100 units of lube will take - longer to dry than if only 10 units were dumped. (lube used to last just as - long, regardless of whether it was 1u, or 100u) There is a limit, however, and - you can't stack infinite lube. - - tweak: Hotter temperatures cause water to evaporate more quickly. At 100C, water - will boil away instantly. - - rscadd: About 5 seconds of wetness are removed from a tile for each unit of drying - agent. Absorbant Galoshes remain the most effective method of drying, and dry - tiles instantly regardless of wetness. -2016-05-22: - coiax: - - rscdel: Lavaland monsters now give ruins a wide berth. - - bugfix: Glass tables now break when people are pushed onto them. -2016-05-23: - CoreOverload: - - rscadd: New cyberimplant, "Toolset Arm", is now available in RnD. - coiax, OPDingo: - - rscadd: Crayons and spraycans are now easier to use. - - rscdel: Centcom announce due to budget cuts their supplier of rainbow crayons - has been forced to use more... exotic chemicals. Please do not ingest your standard - issue crayon. - kevinz000: - - rscadd: 'Peacekeeper borgs: Security borgs but without any stuns or restraints! - Modules: Harm Alarm, Cookie Dispenser, Energy Bola Launcher, Peace Injector - that confuses living things, and a weak holobarrier projector! It also comes - with the ability to hug.' - - rscadd: 'Cookie Synthesizer: Self recharging RCD that prints out cookies!' - - tweak: Nanotrasen scientists have added a hugging module to medical and peacekeeper - cyborgs to boost emotions during human-cyborg interaction. -2016-05-24: - Joan: - - rscdel: You can no longer scribe the Summon Nar-Sie rune under non-valid conditions. - Kiazusho: - - rscadd: Added three new advanced syringes to R&D -2016-05-26: - Xhuis: - - rscadd: Purge all untruths and honor Ratvar. - coiax: - - bugfix: Fixes bug where bolt of change to the host would kill an attached guardian. - - bugfix: Fixes bug where bolt of change to laughter demon would not release its - friends. - - bugfix: Fixes bug where bolt of change to morphling would not release its contents. - - bugfix: Fixes bug where bolt of change transforming someone into a drone would - not give them hacked laws and vision. - - bugfix: Blobbernauts created by a staff of change are now "independent" and will - not decay if seperated from a blob or missing a factory. - - rscadd: Independent blobbernauts added to gold slime core spawn pool. - - rscadd: Medical scanners now inform the user if the dead subject is within the - (currently) 120 second defib window. - - rscadd: Ghosts now have the "Restore Character Name" verb, which will set their - ghost appearance and dead chat name to their character preferences. - - bugfix: Mob spawners now give any generated names to the mind of the spawned mob, - meaning ghosts will have the name they had in life. - - bugfix: Fixes interaction with envy's knife and lavaland spawns. - - bugfix: Fixes a bug where swarmers teleporting humans would incorrectly display - a visible message about restraints breaking. - - rscdel: Emagging the emergency shuttle computer with less than ten seconds until - launch no longer gives additional time. - - rscadd: The emergency shuttle computer now reads the ID in your ID slot, rather - than your hand. -2016-05-27: - coiax: - - rscdel: Gatling gun removed from R&D for pressing ceremonial reasons. - phil235: - - tweak: Pull and Grab are merged together. Pulling stays unchanged. Using an empty - hand with grab intent on a mob will pull them. Using an empty hand with grab - intent on a mob that you're already pulling will try to upgrade your grip to - aggressive grab>neck grab>kill grab. Aggressive grabs no longer stun you, but - they act exactly like a handcuff, preventing you from using your hands until - you escape the grip. You can break free from the grip by trying to move or using - the resist button. - - tweak: Someone pulling a restrained mob now swap position with them instead of - getting blocked by the mob, unable to even push them. -2016-05-29: - GunHog: - - rscadd: The CE, RD, and CMO have been issued megaphones. - Paprika, Crystalwarrior, Korphaeron and Bawhoppen: - - rscadd: Pixel projectiles. This is easier to see than explain, so go fire a weapon. - Xhuis: - - rscadd: Ratvar and Nar-Sie now actively seek each other out if they both exist. - - tweak: Celestial gateway animations have been twweaked. - - tweak: Ratvar now has a new sound and message upon spawning. - - tweak: Ratvar now only moves one tile at a time. - - bugfix: The celestial gateway now takes an unreasonably long amount of time. - - bugfix: God clashing is now much more likely to work properly. - - bugfix: Function Call now works as intended. - - bugfix: Break Will now works as intended. - - bugfix: Holy water now properly deconverts servants of Ratvar. - - bugfix: Deconverted servants of Ratvar are no longer considered servants. - pudl: - - rscadd: Chemicals should now have color, instead of just being pink. -2016-05-30: - coiax: - - rscadd: A new Shuttle Manipulator verb has been added for quick access to probably - the best and most mostly bugfree feature on /tg/. - - rscadd: Spectral sword is now a point of interest for ghosts. - - bugfix: Clicking the spectral sword action now orbits the sword, instead of just - teleporting to its location. - - bugfix: Gang tags can again be sprayed over. - - bugfix: Fixes bug where the wisp was unable to be recalled to the lantern. - xxalpha: - - rscdel: Engineering, CE and Atmos hardsuits no longer have in-built jetpacks. -2016-05-31: - CoreOverload: - - rscadd: 'Cleanbot software was updated to version 1.2, improving pathfinding and - adding two new cleaning options: "Clean Trash" and "Exterminate Pests".' - - experiment: New cleaning options are still experimental and disabled by default. - Kiazusho: - - bugfix: Changeling organic suit and chitin armor can be toggled off once again. - Kor: - - rscadd: The Japanese Animes button is back, - - rscadd: 'The chaplain has three new weapons: The possessed blade, the extra-dimensional - blade, and the nautical energy sword. The former has a new power, the latter - two are normal sword reskins.' - - rscadd: The chapel mass driver has been buffed. - coiax: - - rscdel: Zombies can no longer be butchered - - rscadd: If you encounter an infectious zombie, be cautious, its claws will infect - you, and on death you will rise with them. If you manage to kill the beast, - you can remove the corruption from its brain via surgery, or just chop off the - head to stop it coming back. - - rscadd: Adds some stock computers and lavaland to Birdboat Station. - - bugfix: Free Golem scientists have proved that as beings made out of stone, golems - are immune to all electrical discharges, including the tesla. - - rscadd: Nuclear bombs are now points of interest. Never miss a borg steal a nuke - from the syndicate shuttle again! - - rscadd: Alt-clicking a spraycan toggles the cap. -2016-06-01: - coiax: - - rscadd: Added a mirror to the beach biodome. Beach Bums, rejoyce! - pudl: - - rscadd: The brig infirmary has received a redesign. -2016-06-02: - Joan: - - tweak: Closed false walls will block air. - Lati: - - rscadd: R&D required levels and origin tech levels have been rebalanced - - experiment: Overall, items buildable in R&D have lower tech levels and items in - other departments have their tech levels raised. Remember to use science goggles - to see tech levels of items! - - tweak: There are now level gates at high levels. R&D scientists will need help - from others to get past these level gates. - - tweak: Other departments such as hydroponics and genetics will be important to - R&D's progress now and xenobio, mining and cargo are more important than before - - tweak: Efficiency upgrades are back in R&D machines and tweaked to be less powerful - in autolathes - - rscdel: Reliability has been removed from all items - - bugfix: Most bugs in R&D machines should be fixed - PKPenguin321 & Nienhaus: - - rscadd: Letterman jackets are now available from the ClothesMate. - Quiltyquilty: - - rscadd: The bar has seen a redesign. - coiax: - - rscadd: Clone pods now notify the medical channel on a successful clone. They - also notify the medical channel if the clone dies or is horribly mutilated; - but not if it is ejected early by authorised medical personnel. - - rscadd: Cloning pods now are more capable of cloning humanoid species that do - not breathe. - - bugfix: You can only be damaged once by a shuttle's arrival. It is still unpleasant - to be in the path of one though; try to avoid it. - - rscadd: Adds Asteroid emergency shuttle to shuttle templates. It is a very oddly - shaped one though, it might not be compatible with all stations. - - rscdel: The Chaplain soulshard can only turn a body into a shade once. A released - shade can still be reabsorbed by the stone to heal it. - - rscadd: The shuttle manipulator now has a Fast Travel button, for those admins - that really want a shuttle to get to where its going FAST. -2016-06-04: - MrStonedOne: - - bugfix: fixes see_darkness improperly hiding ghosts in certain cases. - Xhuis: - - tweak: Clockwork marauders can now smash walls and tables. - - tweak: Servants are no longer turned into harvesters by Nar-Sie but instead take - heavy brute damage and begin to bleed. Similarly, cultists are no longer converted - by Ratvar but instead take heavy fire damage and are set ablaze. - - rscadd: Added clockwork reclaimers. Ghosts can now click on Ratvar to become clockwork - reclaimers - small constructs capable of forcefully converting those that still - resist Ratvar's reign. Alt-clicking a valid target will allow the reclaimer - to leap onto the head of any non-servant, latching onto their head and converting - the target if they are able. The target will be outfitted with an unremovable, - acid-proof hat version of the reclaimer. The reclaimer will be able to speak - as normal and attack its host and anything nearby. If the reclaimer's host goes - unconscious or dies, it will leap free. - - rscadd: Added pinion airlocks. These airlocks can only be opened by servants and - conventional deconstruction will not work on them. They can be created by proselytizing - a normal airlock or from Ratvar. - - rscadd: Added ratvarian windows. They are created when Ratvar twists the form - of a normal window, and there are both single-direction and full-tile variants. - - bugfix: Non-servants can no longer use clockwork proselytizers or mending motors. - - bugfix: Servants are now deconverted properly. - coiax: - - bugfix: The cloning pod now sounds robotic on the radio. - - rscadd: For extra observer drama, ghosts can now visibly see the countdown of - syndicate bombs, nuclear devices, cloning pods, gang dominators and AI doomsday - devices. -2016-06-05: - Joan: - - rscadd: Clockwork structures can be damaged by projectiles and simple animals, - and will actually drop debris when destroyed. - - rscadd: AIs and Cyborgs that serve Ratvar can control clockwork airlocks and clockwork - windoors. - - rscadd: The clockwork proselytizer can now proselytize windows, doors, grilles, - and windoors. - - rscadd: The clockwork proselytizer can proselytize wall gears and alloy shards - to produce replicant alloy. It can also proselytize replicant alloy to refill, - in addition to refilling by attacking it with alloy. - - rscadd: The clockwork proselytizer can replace clockwork floors with clockwork - walls and vice versa. - - rscadd: Ratvar will convert windoors, tables, and computers in addition to everything - else. - - tweak: Ratvar now moves around much faster. - - rscadd: Ratvar and Nar-Sie will break each other's objects. - - tweak: The blind eye from a broken ocular warden now serves as a belligerent eye - instead of as replicant alloy. The pinion lock from a deconstructed clockwork - airlock now serves as a vanguard cogwheel instead of as replicant alloy. - - rscadd: Clockwork walls drop a wall gear when removed by a welding tool. The wall - gear is dense, but can be climbed over or unwrenched, and drops alloy shards - when broken. Clockwork walls drop alloy shards when broken by other means. - - bugfix: Fixed Nar-Sie wandering while battling Ratvar. - - bugfix: Ratvarian Spears now last for the proper 5 minute duration. - - bugfix: Servant communication now has ghost follow links. - - imageadd: New sigil sprites, courtesy Skowron. - - imageadd: Sigils of Transgression have a visual effect when stunning a target. - - imageadd: Clockwork spears now have a visual effect when breaking. - PKPenguin321: - - rscadd: The CMO's medical HUD implant now comes with a one-use autoimplanter for - ease of use. - RemieRichards: - - rscadd: Slimes may now be ordered to attack! You must be VERY good friends with - the slime(s) to give this command, asking them to attack their friends or other - slimes will result in them liking you less so be careful! - X-TheDark: - - rscadd: Mech battery replacement improved. The inserted battery's charge will - be set to the same percentage of the removed one's (or 10%, if removed one's - was less). - coiax: - - bugfix: Clicking the (F) link when an AI talks in binary chat will follow its - camera eye, the same as when (F) is clicked for its radio chat. - - bugfix: Laughter demons should now always let their friends go when asked correctly. - - rscadd: Cloning pods now grab the clone's mind when the body is ejected, rather - than when it starts cloning. - - rscadd: Wizards have been experimenting with summoning the slightly less lethal - "laughter demon". Please be aware that these demons appear to be nearly as dangerous - as their slaughter cousins. But adorable, nonetheless. - kevinz000: - - rscadd: Gravity Guns! It is a mildly expensive R&D gun that has a 5 second cooldown - between shots, but doesn't need to be recharged. It has two modes, attract and - repulse. For all your gravity-manipulation needs! -2016-06-07: - Bobylein: - - rscadd: Nanotrasen is finally able to source transparent bottles for chemistry. - Iamgoofball: - - experiment: The Greytide Virus got some teeth. - Joan: - - wip: This is a bunch of Clockwork Cult changes. - - rscadd: Added the Clockwork Obelisk, an Application scripture that produces a - clockwork obelisk, which can Hierophant Broadcast a large message to all servants - or open a Spatial Gateway with 5 uses and a 10 second duration to any conscious - servant or clockwork obelisk. - - wip: Spatial Gateways of any source have doubled uses and duration when the target - is a clockwork obelisk. - - rscadd: Added the Mania Motor, an Application scripture that produces a mania - motor, which, while active, causes hallucinations and brain damage in all nearby - humans. - - wip: The Mania Motor will try to convert any non-servant human directly adjacent - to it at an additional power cost and will remove brain damage, hallucinations, - and the druggy effect from servants. - - rscadd: Added the Vitality Matrix, an Application scripture that produces a sigil - that will slowly drain health from non-servants that remain on it. Servants - that remain on the sigil will instead be healed with the vitality drained from - non-servants. - - wip: The Vitality Matrix can revive dead servants for a cost of 25 vitality plus - all non-oxygen damage the servant has. If it cannot immediately revive a servant, - it will still heal their corpse. - - experiment: Most clockwork structures, including the Mending Motor, Interdiction - Lens, and the newly added Clockwork Obelisk and Mania Motor, now require power - to function. - - wip: Mending Motors can still use alloy for power. - - tweak: The Sigil of Transmission has been remade into a power battery and will - power directly adjecent clockwork structures. Sigils of Transmission start off - with 4000 power and can be recharged with Volt Void. - - tweak: Volt Void drains somewhat more power, but will not damage the invoker unless - they drain too much power. Invokers with augmented limbs will instead have those - limbs healed unless they drain especially massive amounts of power. - - wip: Using Volt Void on top of a Sigil of Transmission will transfer most of the - power drained to the Sigil of Transmission, effectively making it far less likely - to damage the invoker. - - rscdel: You can no longer stack most sigils and clockwork objects with themself. - You can still have multiple different objects or sigils on a tile, however. - - tweak: The Break Will Script has been renamed to Dementia Doctrine, is slightly - faster, and causes slightly more brain damage. - - tweak: The Judicial Visor now uses an action button instead of alt-click. Cultists - of Nar-Sie judged by the visor will be stunned for half duration, but will be - set on fire. - - tweak: Multiple scriptures have had their component requirements changed. The - Summon Judicial Visor Script has been reduced from a Script to a Driver. - - rscadd: Recollection will now show both required and consumed components. - - tweak: Clockwork Marauders can now emerge from their host if their host is at - or below 60% total health(for humans, this is 20 health out of crit) - - tweak: Clockwork Marauders will slowly heal if directly adjacent to their host - and have a slightly larger threshold for their no-Fatigue bonus damage. - Quiltyquilty: - - rscadd: Botany, atmospherics and cargo now all have access to high-capacity watertanks. - - rscadd: The bar has now been outfitted with custom bar stools. - Xhuis: - - rscdel: Removed the global message played when Nar-Sie _begins_ to spawn (but - not when it actually spawns). - - tweak: Drunkenness recovery speed now increases with how drunk the imbiber is - and is much quicker when the imbiber is asleep. - - tweak: Suit storage units now take three seconds to enter (up from one) and have - different sounds and messages for UV ray cauterization. - - bugfix: Fixed some bugs with the suit storage unit, inserting mobs, and contents - to seemed to duplicate themselves. - - bugfix: The Summon Nar-Sie rune can now only be drawn on original station tiles - and fails to invoke if scribed on the station then moved elsewhere. - coiax: - - rscdel: Bluespace shelter capsules can no longer be used on shuttles. - - rscadd: Bluespace shelters may have different capsules stored. View what your - capsule has inside by examining it. - - rscdel: The Nar'sie rune cannot be scribed on shuttles or off Z-level. - - rscadd: The Raise Dead rune automatically grabs the ghost of the raised corpse. - - rscadd: Deadchat is now notified when a sentient mob dies. - phil235: - - rscadd: Monkeys and all other animals that should have blood now has it. Beating - them up will make you and your weapon bloody, just like beating a human does. - Dragging them when wounded and lying will leave a blood trail. Their blood is - still mostly cosmetic, they suffer no effects from low blood level, unlike humans. - - rscadd: When a mob leaves a blood trail while dragged, it loses blood. You can - no longer drag a corpse to make an inifinite amount of blood trails, because - once the victim's blood reaches a certain threshold it no longer leaves a blood - trail (and no longer lose any more blood). The threshold depends on how much - damage the mob has taken. You can always avoid hurting the dragged mob by making - them stand up or by buckling them to something or by putting them in a container. - - rscdel: You can no longer empty a mob of its blood entirely with a syringe, once - the mob's blood volume reaches a critically low level you are unable to draw - any more blood from it. - - tweak: A changeling absorbing a human now sucks all their blood. -2016-06-08: - Cruix: - - bugfix: Changelings no longer lose the regenerate ability if they respect while - in regenerative stasis. - Fox McCloud: - - bugfix: Fixes Experimentor critical reactions not working - - bugfix: Fixes Experimentor item cloning not working - - bugfix: Fixes Experimentor producing coffee vending machines instead of coffe - cups - - tweak: Experimentor can only clone critical reaction items instead of anything - with an origin tech - GunHog: - - rscadd: Nanotrasen has approved the Hyper-Kenetic Accelerator upgrade for cyborg - mining modules. - - tweak: Each of the heads' ID computers are now themed for their department! - Joan: - - tweak: Anima Fragments have slightly more health and move faster, but slow down - temporarily when taking damage. Also they can move in space now. - Kor: - - rscadd: The clown will play a sad trombone noise upon death. - - rscadd: Colossi now roam the wastes. - - rscadd: Bubblegum now roams the wastes. - PKPenguin321: - - rscadd: You can now emag chemical dispensers, such as the ones in chemistry or - the bar, to unlock illegal chemicals. - lordpidey: - - tweak: Infernal jaunt has been significantly nerfed with an enter and exit delay. -2016-06-09: - GunHog: - - rscadd: Nanotrasen scientists have completed a design for adapting mining cyborgs - to the Lavaland Wastes in the form of anti-ash storm plating. Research for this - technology must be adapted at your local station. - Joan: - - tweak: Anima Fragments have slightly less health and damage and will slow down - for longer when hit. - Kor: - - rscadd: The captain now spawns with the station charter, which allows him to name - the station. - Papa Bones: - - tweak: Loyalty implants have been refluffed to mindshield implants, they are mechanically - the same. - Xhuis: - - rscadd: You can now remove all plants and weeds from a hydroponics tray by using - a spade on it. - - rscadd: Added meatwheat, a mutated variant of wheat that can be crushed into meat - substitute. - - rscadd: Added ambrosia gaia, a mysterious plant that is rumored to provide nutrients - and water to any soil - hydroponic or otherwise - that it's planted in. - - rscadd: Added cherry bombs, a mutated variant of blue cherries that have an explosively - good taste. Oh, and don't pluck the stems. - coiax: - - tweak: The beacons from support guardians are now structures, rather than replacing - the floor tile. In practice, this will change little, aside from not leaving - empty plating when a beacon is removed because a new one has been placed. - nullbear: - - tweak: Removes the restriction on wormhole jaunters, preventing them from teleporting - you to beacons on other z-levels. - - tweak: No longer able to use beacons to bypass normal shuttle/centcomm anti-bluespace - measures. -2016-06-11: - Joan: - - rscadd: Clockwork Slabs, Clockwork Caches near walls, and Tinkerer's Daemons will - now be more likely to generate components that the clockwork cult has the least - of. - - rscadd: Destroyed Clockwork Caches will drop all Tinkerer's Daemons in them. - - tweak: Clockwork Caches can now only generate a component every 30 seconds(when - near a clockwork wall), Clockwork Slabs can only generate a component every - 40 seconds, and Tinkerer's Daemons can only generate a component every 20 seconds. - This should result in higher component generation for everything except Clockwork - Caches near clockwork walls. - - tweak: Adding a component to a Clockwork Slab instead puts that component in the - global component cache. - - tweak: Clockwork Slabs only generate components if held by a mob or in a mob's - storage, and when generating a component will prevent other Slabs held from - generating a component. - - tweak: The Replicant Driver no longer costs a Replicant Alloy to invoke; basically - you can throw free Slabs at converts. - - rscdel: Clockwork Slabs no longer have Repository as a menu option; instead, you - can examine them to see how many components they have access to. - - rscdel: Clockwork Caches directly on top of clockwork walls won't generate components - from that wall. - Lzimann: - - rscadd: Bar stools are now constructable with metal! - coiax: - - rscadd: Ghosts are notified when someone arrives on the Arrivals Shuttle. This - is independent of the announcement system, and the (F) link will follow the - arrived person. - - tweak: Slimes and aliens with custom names now retain those names when changing - forms. - kevinz000: - - bugfix: Malf AI hacking an APC that is then destroyed will no longer bug the AI - - bugfix: Being turned into a Revolutionary now stuns you for a short while. - - bugfix: Kinetic Accelerators no longer drop their firing pin or cell when destroyed - by lava - phil235: - - rscadd: Firelock assemblies can be reinforced with plasteel to construct heavy - firelocks. -2016-06-12: - Joan: - - rscadd: Attacking a human you are pulling or have grabbed with a ratvarian spear - will impale them, doing massive damage, stunning the target, and breaking the - spear if they remain conscious after being attacked. - - tweak: The Function Call verb is now an action button. - Xhuis: - - rscdel: While experimenting with floral genetic engineering, Nanotrasen botanists - discovered an explosive variety of the cherry plant. Due to gross misuse, the - genes used to produce this strain have been isolated and removed while Central - Command decides how best to modify it. - xxalpha: - - rscadd: 'New wizard spell: Spacetime Distortion.' - - rscadd: 3x1 grafitti -2016-06-13: - Joan: - - tweak: Sigils of Transgression will now only stun for about 5 seconds, from around - 10 seconds. - - tweak: Sigils of Submission take about 5 seconds to convert a target, from around - 3 seconds, and will glow faintly. - - rscadd: Sigils of any type can be attacked with an open hand to destroy them, - instead of requiring harm intent. Servants still require harm intent to do so. - Lati: - - rscadd: Nanotrasen has added one of their rare machine prototypes to cargo's selection. - It might be valuable to research. - Xhuis: - - rscadd: You can now create living cake/cat hybrids through a slightly expensive - crafting recipe. These "caks" are remarkably resilient, quickly regenerating - any brute damage dealt, and can be attacked on harm intent to take a bite to - be fed by a small amount. They serve as mobile sources of food and make great - pets. - - rscadd: If a brain occupied by a player is used in the crafting recipe for caks, - that player then takes control of the cak! -2016-06-14: - Joan: - - tweak: The Gateway to the Celestial Derelict now takes exactly 5 minutes to successfully - summon Ratvar and has 500 health, from 1000. - - rscadd: You can now actually hit people adjacent to the Gateway; only the center - of the Gateway can be attacked. The Gateway is also now dense, allowing you - to more easily shoot at it. - - rscadd: All Scripture in the Clockwork Slab's recital has a simple description. - Razharas: - - rscadd: Wiki now has the method of cultivating kudzu vines that was in game for - over a year. https://tgstation13.org/wiki/Guide_to_hydroponics#Kudzu - kevinz000: - - tweak: Gravity Guns should no longer destroy local reality when set to attract - and shot in an east cardinal direction. Added safety checks has slightly increased - the cost of the gun's fabrication. Nanotrasen apologizes for the inconvenience. - - bugfix: Gravity guns now have an inhand sprite. -2016-06-16: - GunHog: - - rscadd: In response to alarmingly high mining cyborg losses, Nanotrasen has equipped - the units with an internal positioning beacon, as standard within the module. - Joan: - - rscadd: You can now strike a Tinkerer's Cache with a Clockwork Proselytizer to - refill the Proselytizer from the global component cache. - - tweak: The Clockwork Proselytizer requires slightly less alloy to convert windows - and windoors. - - tweak: Several clockwork objects have more useful descriptions, most notably including - structures, which will show a general health level to non-servants and exact - health to servants. - - imageadd: The Clockwork Proselytizer has new, more appropriate inhands. - - tweak: Invoking Inath-Neq, the Resonant Cogwheel, now gives total invulnerability - to all servants in range for 15 seconds instead of buffing maximum health. - - tweak: Impaling a target with a ratvarian spear no longer breaks the spear. - - tweak: Judicial Markers(the things spawned from Ratvar's Flame, in turn spawned - from a Judicial Visor) explode one second faster. - - rscdel: Removed Dementia Doctrine, replacing it with an Application sigil. - - rscadd: Adds the Sigil of Accession, the previously-mentioned Application sigil, - which is much like a Sigil of Submission, except it isn't removed on converting - un-mindshielded targets and will disappear after converting a mindshielded target. - - tweak: Sigil of Submission is now a Script instead of a Driver; It's unlocked - one tier up, so you have to rely on the Drivers you have until you get Scripts, - instead of spamming both Driver sigils for free converts. - - rscadd: To replace Sigil of Submission in the Driver tier; Added Taunting Tirade, - which is a chanted scripture with a very fast invocation, which, on chanting, - confuses, dizzies, and briefly stuns nearby non-servants and allows the invoker - a brief time to relocate before continuing the chant. - - rscadd: Ghosts can now see the Gateway to the Celestial Derelict's remaining time - as a countdown. - - tweak: Anima Fragments are now slightly slower if not at maximum health and no - longer drop a soul vessel when destroyed. - Quiltyquilty: - - rscdel: Patches now hold only 40u. - - rscdel: Patches in first aid kits now only contain 20u of chemicals. - coiax: - - rscadd: Polymorphed mobs now have the same name, and where possible, the same - equipment as their previous form. -2016-06-19: - Joan: - - tweak: Assassin holoparasite attack damage increased from 13 to 15, stealth cooldown - decreased from 20 seconds to 16 seconds. - - tweak: Charger holoparasite charge cooldown decreased from 5 seconds to 4 seconds. - - tweak: Chaos holoparasite attack damage decreased from 10 to 7, range decreased - from 10 to 7. - - tweak: Lightning holoparasite attack damage increased from 5 to 7, chain damage - increased by 33%. - - rscdel: Clock cult scripture unlock now only counts humans and silicons. - - rscadd: Servants of ratvar can now create cogscarab shells with a Script scripture. - Adding a soul vessel to one will produce a small, drone-like being with an inbuilt - proselytizer and tools. - - imageadd: Clockwork mobs have their own speechbubble icons. - - tweak: Invoking Sevtug now causes massive hallucinations, brain damage, confusion, - and dizziness for all non-servant humans on the same zlevel as the invoker. - - rscdel: Invoking Sevtug is no longer mind control. RIP mind control 2016-2016. - - tweak: Clockwork slabs now produce a component every 50 seconds, from 40, Tinkerer's - Caches now produce(if near a clockwork wall) a component every 35 seconds, from - 30. - - experiment: 'Tinkerer''s daemons have a slightly higher cooldown for each component - of the type they chose to produce that''s already in the cache: This is very - slight, but it''ll add up if you have a lot of one component type and are trying - to get more of it with daemons; 5 of a component type will add a second of delay.' - Kor and Iamgoofball: - - rscadd: Miners can now purchase fulton extraction packs. - - rscadd: Miners can now purchase fulton medivac packs. - - rscadd: Two new fulton related bundles are available for purchase with vouchers. - Quiltyquilty: - - rscadd: Beepsky now has his own home in the labor shuttle room. - Wizard's Federation: - - bugfix: We've fired the old Pope, who was actually an apprentice in disguise. - We've a-pope-riately replaced him with a much more experienced magic user. - - rscadd: Some less-then-sane people have been sighted forming mysterious cults - in lieu of recent Pope sightings, lashing out at anyone who speaks ill of him. - - bugfix: We've rejiggered our trans-dimensional rifts, and almost all cases of - clergy members being flung into nothingness should be resolved. - - bugfix: All members of the Space Wizard's Clergy have been appropriately warned - about usage of skin-to-stone spells, and such there should be no more instances - of permanent statueification. - Xhuis: - - tweak: Revenants have been renamed to umbras and have undergone some tweaks. - coiax: - - rscadd: Drones can hear robotic talk, but cannot communicate on it. AIs and cyborgs - are encouraged to share information with station repair drones. - - rscadd: Potted plants can now be ordered from cargo. - - rscdel: AI turrets no longer fire at drones. -2016-06-20: - Kor: - - rscadd: Cult runes can only be scribed on station and on mining. - - rscadd: The comms console now has a new option allowing you to communicate with - the other server. - Quiltyquilty: - - rscadd: The detective has been moved to above the post office. - coiax: - - rscadd: Birdboat's supply loop has been split into two unconnected halves, to - maintain award winning air quality. - incoming5643: - - experiment: New abilities for some races! - - rscadd: Skeletons (liches) and zombies now are much more susceptible to limb loss, - but can also reattach lost limbs manually without surgery. - - rscadd: Slimepeople can now lose their limbs, but also can regenerate them if - they have the jelly for it. Additionally slimepeople will (involuntarily) lose - limbs and convert them to slime jelly if they're extremely low on jelly. - - rscadd: Zombies and slimepeople now have reversed toxic damage, what usually heals - now hurts and what usually hurts now heals. Keep in mind that while you could - for example heal with unstable mutagen, you'd still mutate. Beware of secondary - effects! Drugs like antitoxin are especially dangerous to these races now since - not only do they do toxin damage, but they remove other toxic chems before they - can heal you. Be wary also of wide band healing drugs like omnizine. - - rscadd: For slime people the above mechanic also adds/drains slime jelly. So yes - inhaling plasma is now a valid way to build jelly (but you'll still suffocate - if there's no oxygen). - - rscadd: Pod people now mutate if shot with the mutation setting of the floral - somatoray. -2016-06-22: - Cheridan: - - tweak: Flashes no longer stun cyborgs, instead working almost exactly like a human, - causing them to become confused and unequip their current module. - Joan: - - rscdel: Those who do not serve Ratvar cannot understand His creations. - - rscadd: You can now repair clockwork structures with a clockwork proselytizer. - This is about a third as efficient as a mending motor, costing 2 liquified alloy - to 1 health, and also about a third as fast. - - tweak: Scarab proselytizers are more efficient and will reap more alloy from metal - and plasteel. - - rscadd: They can also directly convert rods to alloy. - - tweak: Nuclear bombs will no longer explode the station if in space. Please be - aware of this. - Kor: - - rscadd: You can now pick up potted plants. - PKPenguin321: - - rscadd: You can now pick up a skateboard and use it as a weapon by dragging it - to yourself. - - imageadd: Skateboards have been given brand new sprites, courtesy of JStheguy - Quiltyquilty: - - rscadd: The AI is back in the center of the station. The gravity generator is - now where the SMES room used to be. The SMESes are in the equipment room. - Supermichael777: - - rscadd: Flaps are no longer space-racist and now accept all bots. - Xhuis: - - tweak: Holy weapons, such as the null rod and possessed blade, now protect from - Ratvar's magic. - coiax: - - rscadd: Certain custom station names may be rejected by Centcom. - - rscadd: Drone shells can be ordered in Emergency supplies at Cargo. -2016-06-23: - Joan: - - tweak: Tinkerer's Caches generate components(when near clockwork walls) every - minute and a half, from every 35 seconds. Clockwork Slabs generate components - once per minute, from once per 50 seconds. - - tweak: Spatial Gateway will last four seconds per invoker, instead of two per - invoker. - - rscdel: Clockwork floors now only heal toxin damage on servants of Ratvar. - - rscdel: You can no longer place ocular wardens very close to other ocular wardens. - - tweak: The Flame produced by a Judicial Visor is no longer an effective melee - weapon and will trigger on all intents, not just harm intent. - Wizard's Federation: - - bugfix: Acolytes of Hades have revealed their true forms. - - rscadd: We've discovered a way to traverse portals left behind by Hades, and have - discovered a great treasure through it. - - bugfix: Hades has undergone Anger Management classes, and should no longer remain - wrathful for the duration of his visit. - coiax: - - rscadd: Changelings now evolve powers via the cellular emporium, which they can - access via an action button. - - rscadd: Due to budget cuts, the shuttle's hyperspace engines now create a visual - distortion at their destination, a few seconds before arrival. Crewmembers are - encouraged to use these "ripples" as an indication of where not to stand. - - bugfix: Shuttles now only run over mobs in turfs they are moving into, rather - than the entire rectangle. - - rscadd: If you are an observer, you can click on transition edges of a Z-level - in order to move as a mob would. - - rscadd: Due to safety concerns, the Hyperfractal Gigashuttle now has some safety - grilles to prevent accidental matter energising. - coiax, incoming: - - rscadd: Due to budget cuts, the builtin anti-orbit engines on the station have - been removed. As such, expect the station to start orbiting the system again, - and encounter an unpredictable stellar environment. - - rscdel: All permanent structures (not on station, Centcom or lavaland) have been - removed. - - rscadd: All removed structures are now space ruins, and can be placed randomly - in space ruin zlevels. - - wip: The White Ship remains at its current location, but has lost any reliable - landmarks near it. Its starting position will be made more random in a coming - update. - - rscadd: The Space Bar has a small atmos system added and a teleporter. Some other - ruins have been cleaned up to not have atmos active turfs. -2016-06-24: - Joan: - - experiment: The Interdiction Lens has been reworked; instead of allowing you to - disable Telecomms, Cameras, or non-Servant Cyborgs, it drains power from all - APCs, SMES units, and non-Servant cyborgs in a relatively large area, funneling - that power into nearby Sigils of Transmission, then disables all cameras and - radios in that same area. - - wip: If it fails to find anything it could disable or drain any power, it turns - off for 2 minutes. - - tweak: You can now target yourself with Sentinel's Compromise, allowing you to - heal yourself with it. - - rscadd: Flashes will once again stun borgs, but for a much shorter time than they - previously did; average stun time is reduced from the previous average of 15 - seconds to about 6 seconds. The confusion remains, but it will no longer unequip - borg modules. - MMMiracles: - - tweak: Metastation xenobiology's lights and cell have been modified so it won't - drain 5 minutes into the round. - SnipeDragon: - - bugfix: Changelings created at round start now correctly receive their Antag HUD. - Xhuis: - - rscadd: Cardboard cutouts have been added. Now you can set up advertisements for - your clown mart. -2016-06-26: - Basilman: - - rscadd: The Donor prompt for becoming an alien queen maid is now an action button - instead, and can be toggled on and off. - Joan: - - rscadd: Fellowship Armory now invokes faster for each nearby servant and provides - clockwork gauntlets, which are shock-resistant and provide armor to the arms. - - tweak: It's not wise to equip clockwork armor if you don't serve Ratvar. - - bugfix: A full set of clockwork armor will now actually cover all limbs. - coiax: - - rscadd: Our administrators, here at /tg/, don't get enough credit for their wealth - of experience and knowledge. Now they get the chance to share that with you - by giving out custom tips! - - tweak: Gang domination now uses the same timing method as shuttles, making their - domination times more accurate. - - rscdel: The default shuttle transit time is now 15 seconds. - - rscadd: Please do not commit suicide with the nuclear authentication disk. - - rscadd: Observers now have a visible countdown for borg factories, silicons can - examine the factory to determine how long it has remaining until it is ready. - - rscadd: Clockwork mobs sound like Ratvar chants if you do not serve Ratvar. - - rscadd: When servants recite, they now talk in a strange voice that is more noticable. -2016-06-28: - CoreOverload: - - rscadd: Kinetic accelerator now supports seclite attachment. - - rscadd: All cyborgs have been outfitted with ash-proof plating. - - rscadd: Mining cyborg module now includes a welder and a fire extinguisher. - - rscadd: 'Mining cyborgs now have a new upgrade: lavaproof tracks.' - Joan: - - rscdel: Clockwork Marauders are no longer totally invincible to damage unless - a holy weapon was involved. - - rscadd: Clockwork Marauders will take damage when attacked, but unless they're - fighting excessive amounts, they'll be forced to return to their host before - they'd normally die. - - experiment: A holy weapon held in either hand in the presence of a marauder will - massively increase the damage they take, making it much more likely the marauder - can be killed. - - tweak: Clockwork Marauders do slightly less damage at low fatigue levels. - - rscadd: Clockwork Marauders now have a chance to block melee attacks, negating - the damage from them, and an additional chance to immediately counter, attacking - whoever tried to attack them. - - wip: If Ratvar has awoken, Marauders have a much higher chance to block and counter, - will block thrown items and projectiles, and gradually regenerate. - - experiment: Clockwork Marauders no longer have a verb to communicate; they instead - use :b to do so. - - rscadd: Faked deaths are now effectively indistinguishable from real deaths. - MMMiracles: - - rscadd: Adds some ruins for space and lavaland. Balance not included. - - rscadd: Adds spooky ghosts. - SnipeDragon: - - bugfix: Cardboard Cutouts now become opaque when their appearance is changed. - Wizard's Federation: - - rscadd: Acolytes of Hades have been scolded for gluing their clothes to themselves, - and their clothes can now be cut off them. - - rscadd: Hades has learned a few new tricks, to ensure the ultimate demise of his - target. - - bugfix: Hades has faced a council of his repeated use of time magic inside chapels, - and as it was deemed unholy, he will no longer do it. - - rscadd: Wizards of the Wizard's Federation have been granted access to Dark Seeds, - ancient relics used to call upon Hades in a time of need. - Xhuis: - - rscdel: You can no longer put paper cups back onto water coolers. In addition, - they're now just called "liquid coolers" instead of changing based on their - contents. - coiax: - - rscadd: Status displays added to a variety of shuttle templates. - - rscdel: Large graffiti now consumes 5 uses from limited use crayons and spraycans, - as well as taking three times the amount of time to draw. - - rscadd: All items inside the supply shuttle will now be sold, regardless of whether - they're inside a container or not. - - bugfix: Fixes issue where the AI core APC on Metastation would not charge. - 'name: Lzimann': - - rscadd: Engineer and atmos wintercoat can hold the RPD now! - optional name here: - - rscdel: Shadowlings have been completely removed. - oranges: - - tweak: You can now hear dice - timkoster1: - - rscadd: adds a hud soul counter for devils. Sprites by PouFrou and special thanks - to lordpidey for about everything. -2016-06-29: - Joan: - - rscadd: Ghosts spawning via Ratvar can now choose to spawn as a Cogscarab with - a usable slab instead of as a Reclaimer. - - bugfix: You can no longer permanently block hostile simple mobs with sandbags - and other barricades. - MrStonedOne: - - rscadd: Ghosts may now jump between the two linked servers using the new Server - Hop verb. Rather than whine in deadchat about dieing, you can just go play a - new round on the other server. - coiax: - - rscadd: Adds a new UI to slimepeople, allowing them to select more easily which - body to swap to - - rscadd: Slimepeople swapping consciousness between bodies is now visible to onlookers - - bugfix: The AI malfunction "Hostile Lockdown" power now restores the station doors - to normal after 90 seconds, rather than keeping everything shut forever. -2016-07-01: - Flavo: - - bugfix: fixed a bug where lights would not update. - Joan: - - rscadd: Clockwork Slabs now use an action button to communicate instead of the - "Report" option in the menu after using a slab. - - tweak: Clockwork Slabs now fit in pockets, the belt slot, or in the suit storage - slot(if wearing clockwork armor), where they can be used as hands-free communication. - - imageadd: Clockwork items with action buttons have a new, clockwork-y background. - - rscadd: Judicial Visors now tell the user how many targets the Judicial Blast - struck. - - soundadd: Judicial Markers now have sounds when appearing and exploding. - - tweak: Wet turfs should remain that way for slightly longer than 5 seconds now. - - rscadd: Drones and Swarmers should now sound more robotic. - - tweak: Ratvarian Spears will stun cyborgs and cultists for twice as long when - thrown; on cyborgs, this should be long enough to use Guvax on them. - - rscdel: Removed the Justicar's Gavel application scripture. - - tweak: Vitality Matrices will drain and heal 50% faster, and the base cost to - revive is 20% lower; 20, from 25. - - rscadd: Vitality Matrices will not revive or heal corpses unless they can grab - the ghost of the corpse, and will immediately grab the ghost when reviving. - - rscadd: Swarmers consuming swarmer shells now refunds the swarmer the entire cost - of the shell instead of 2% of the shell's cost. - - experiment: Application scriptures require at least 75 CV, from 50. - - experiment: Revenant scriptures require at least 4 Caches, from 3, and at least - 150 CV, from 100. - - experiment: Judgement scripture requires at least 12 servants, from 10, 5 Caches, - from 3, and at least 250 CV, from 100. - - experiment: Script and Application scripture have had their component costs and - requirements tweaked to reduce overuse of certain components. - - wip: Invoke times for a few scriptures that were instant are now very short instead. - Kor: - - rscdel: Holoparasites are no longer in the uplink - NikNak: - - tweak: Showcases are now movable and deconstructable. Wrench them to unanchor - and then screwdriver and crowbar to deconstruct. - Papa Bones: - - tweak: Security now has energy bolas available to them in their vending machines, - check them out! - bobdobbington: - - rscadd: Added skub to the AutoDrobe as a premium item. - coiax: - - rscadd: The CTF arena regenerates every round, and the blue team now shoot blue - lasers. - - rscadd: Adds some descriptions to alien surgery tools - - rscadd: The agent vest can be locked and unlocked (toggling the NODROP flag) - - rscadd: An abductor team can spend data points to purchase an agent vest (note - that only abductor agents are trained in their use) - - rscadd: The nuke disk reappears on the station in far more random locations, but - tends to re-materialise in safe pressurised areas that aren't on fire. - 'name: Lzimann': - - tweak: Mulebots with pAI cards no longer stun people -2016-07-02: - Joan: - - rscadd: Clockwork Proselytizers can now reform stored alloy into usable component - alloy when used in-hand. - - rscdel: Mending motors start with 2500W of power in alloy, from 5000. Sigils of - Transmission start with 2500W of power, from 4000. Clockwork Proselytizers start - with 90 alloy, from 100. - - rscdel: Umbras have been removed. - - rscadd: Revenants have been readded, though they are now vulnerable to salt piles. - MMMiracles: - - rscadd: Added the power fist, a gauntlet with a piston-powered ram attached to - the top for traitors to punch people across the station. Punch people into walls - for added fun. - incoming5643: - - rscadd: 'Nuke ops can now harness the power of METAL BOXES: special versions of - cardboard boxes that can take a lot of abuse and can fit the whole team if need - be. They''re not nearly as light as their cardboard brothers though...' - kevinz000: - - rscadd: Some new emojis have been added to OOC for your enjoyment. Try them out. - - rscadd: 'New emojis are : coffee, trophy, tea, gear, supermatter, forceweapon, - gift, kudzu, dosh, chrono, nya, and tophat. Type :nameofemoji: in OOC to use.' -2016-07-03: - Cruix: - - bugfix: Hand labelers can now label storage containers. - - bugfix: You can now properly resist out of wrapped lockers. - - bugfix: You can now resist out of morgues if you are in a bodybag. - - bugfix: Mechs can no longer spam doors they do not have access to. - Joan: - - tweak: Clock Cult can now happen at 24 players, same as cult. - - tweak: Clock Cult player scaling is lower; 3 people, plus one for every 15 players - above 30, from 1 for every 10 players with a player minimum of 30. - - experiment: Guvax now invokes 1 second faster(5 seconds), but is 0.75 seconds - slower for each scripture-valid servant above 5, up to a maximum of 15 seconds. - - experiment: Clockwork Slabs generate components 20 seconds slower for each scripture-valid - servant above 5, up to a maximum of 1 component every 5 minutes. - - tweak: Tinkerer's Daemons that would be useless cannot be made. -2016-07-04: - Gun Hog: - - rscadd: The Space Wizard Federation has finally begun teaching its pupils how - to properly aim the Fireball spell! - - tweak: Fireball spells, including the Devil version, are now aimed via mouse click. - It is recommended to avoid firing at anything too close, as the user can still - blow himself up! - Joan: - - rscdel: Mecha are no longer immune to ocular wardens. - Lzimann: - - rscadd: Throwing active stunbatons now has a chance to stun whoever it hits! - MMMiracles: - - rscadd: Adds space ruins. Balance not included. - - tweak: Simple mob ghosts actually work now. - - rscdel: Puzzle1 ruin removed due to issues with projectiles. - X-TheDark: - - rscadd: Switching mobs/ghosting/etc related actions during the round will now - no longer reset your hotkey settings. - Xhuis: - - bugfix: Ash storms can now occur again. - bgobandit: - - rscadd: Bluespace polycrystals, basically stacks of bluespace crystals, have been - added. The ore redemptor accepts them now. - - tweak: The ore redemptor machine should be less spammy now. - coiax: - - rscadd: The zone of hyperspace that a shuttle travels in is dynamically determined - when a shuttle begins charging its engines. This is signified by the shuttle - mode IGN. All shuttles must now charge engines before launching. This time is - already included in the emergency shuttle timer. - - rscdel: The cargo shuttle can only be loaned to Centcom while at Centcom. - - rscadd: Immovable rods now notify ghosts when created, allowing them to orbit - it and follow their path of destruction through the station. - - bugfix: Fixed bugs where no meteors would come or go from the south. Seriously, - that was a real bug. Meteor showers are now about 33% stronger as a result. -2016-07-06: - Cruix: - - bugfix: Vending machine restocking units now work. - Joan: - - rscadd: Servants should now be more aware of when scripture tiers are locked or - unlocked. - - experiment: Judicial Explosions from a Judicial Visor now mute for about 10 seconds. - MrStonedOne: - - rscadd: Instant Runoff Voting polls are now available. - RemieRichards: - - tweak: Fixes accidental buff to botany, all modifiers should now be at the point - they were at pre-bees (this does not remove, nerf or alter bees) - Xhuis: - - rscadd: The Necropolis gate now looks as regal as it should. Credit goes to KorPhaeron - for turf and wall sprites. - - bugfix: Ash storms are actually damaging now. - coiax: - - bugfix: Gulag prisoners can no longer duplicate their mining efforts through window - breaking on the shuttle. - - bugfix: Fixes pickaxes inside walls on lavaland, along with lava having eaten - one of the storage units. - - rscadd: More fire extinguishers for lavaland mining base. - - bugfix: You can now reload your gun in CTF. - - rscadd: Dying in CTF will spawn a short lived ammo pickup, which you can walk - over to reload all your weapons. - - rscadd: If reduced to critical status in CTF, you will automatically die, so you - no longer have to succumb or be coup de graced. If you are conscious, you will - now heal slowly if some damage got through your shield and didn't crit you. - - bugfix: The tesla now dusts all carbon mobs on the turf that it moves to, grounding - rod or no. - coiax, Niknakflak: - - rscadd: Added fireplaces, fuel with logs or paper and set on fire and enjoy that - warm comforting glow. - - bugfix: Cardboard cutouts are now flammable. - - rscadd: Cigarettes, fireplaces and candles now share a pool of possible igniters. - So you can now esword that candle on, but turn it on first. - - rscadd: Eswords will ignite plasma in the air if turned on. - kevinz000: - - tweak: Kudzu is no longer unstoppable - optional name here: - - bugfix: Suit Storage Units can now disinfect items other than living and dead - creatures. -2016-07-09: - CoreOverload: - - rscadd: You can remove jetpack from a hardsuit by using screwdriver on it. - Crazylemon: - - bugfix: The map loader no longer resets when reading another map mid-load - Goofball Sanders: - - rscadd: Added a new plant to the game to encourage the Chef to be a more relevant - job, alongside a recipe for a food related to it. Throw a cannabis leaf on a - table and check the recipes list to find it. - Gun Hog: - - rscdel: Malf (Traitor) AI's Fireproof Core ability has been removed, as it was - entirely obsolete. - - rscadd: Nanotrasen is proud to announce that conveyor belts can now be fabricated - at your station's autolathes! - Iamgoofball: - - bugfix: Fixes the Atheist's Fedora's throw damage. - Joan: - - rscadd: Tips for Clock Cult may now show up. - - experiment: The global component cache can only be accessed by clockwork slabs - if there is at least one Tinkerer's Cache active. - - rscadd: Ratvarian Spears are now sharp and can be used to cut off limbs or butcher - mobs. - - rscadd: Clock Cult silicons get an action button to communicate with other servants. - - tweak: Clockwork Slabs now produce a component every 1 minute, 30 seconds, from - every 1 minute. - - experiment: The slab production time gain from each servant above 5 has been increased - from 20 seconds to 30 seconds, and the maximum production time has been increased - from 5 minutes to 6 minutes. - - rscadd: You can now transfer components between two clockwork slabs by attacking - one slab, or a person holding a slab, with the other; this will transfer the - attacking slab's components into the target slab. - - tweak: Application scripture now requires 100 CV, from 75, Revenant scripture - now requires 200 CV, from 150, and Judgment scripture now requires 300 CV, from - 250. - - experiment: However, converted windows, windoors, airlocks, and grilles will all - provide some CV. - Lzimann & Keekenox: - - rscadd: You can now craft a baseball bat with 5 sheets of wood! - MrStonedOne: - - experiment: Atmos on planets is now more realistic. There is an unseen upper atmosphere - that gas changes get carried away into, causing planet turfs to revert back - to their original gas mixture. - - tweak: This should massively improve atmos run speed as all of lavaland won't - be processing the moment somebody opens a door anymore - MrStonedOne, coiax: - - rscadd: View Variables can expand on associated lists with type keys. Only 90s - admins will truely understand. - RemieRichards: - - rscadd: Added a Compact mode to the crafting tgui - - tweak: Modified the back end of the crafting tgui so that it has well let's just - say "a lot less" calls to certain functions, should lag a little less but don't - expect miracles (you'd have to wait till we get a new version of ractive for - those!) - coiax: - - rscadd: Podpeople (and venus human traps) are now no longer damaged, poisoned - or obstructed by space vines. Explosive vines still damage them, because there's - an actual explosion. - - rscadd: During a meteor shower, observers can automatically orbit threatening - meteors via an action button and watch them hit the station. - - rscadd: Added Major Space Dust event, which is a meteor shower containing only - space dust. - - bugfix: Fixes bug where meteors wouldn't move when spawned. - - rscadd: Meteor Shower split into three different events, Normal, Threatening and - Catastrophic. They all have the same crew messages, but admins can tell the - difference. - - bugfix: Damage to a shuttle while it is moving will now correctly make transit - space turfs, rather than non-moving space. - - rscadd: AIs get a notification when hacking an APC, which can be clicked to jump - your camera to the APC's location. AIs also get notification sounds when a hack - has completed or failed. - - rscadd: Nuclear bombs now use a more accurate timer system, the same as gang dominators - and shuttles. - - rscadd: Nuclear bombs now have a TGUI interface. - - rscdel: Fleshmend no longer regrows lost limbs. - - rscadd: Added free Regenerate power to changelings, which regrows all external - limbs and internal organs (including the tongue if you lost your head). It costs - 10 chemicals to use. - - rscadd: Fleshmend now costs 20 chemicals, down from 25. - - tweak: Changeling revive power name changed from Regenerate to Revive. - - rscadd: When a player uses a communication console to ask for the codes to the - self destruct, for better or for worse, the admins can set them with a single - click. Whether the admins a) click the button b) actually give the random person - the codes, is another thing entirely. - - rscadd: Servants of Ratvar get an alert if they have no tinkerer's caches constructed. - Because it's important that they should. -2016-07-11: - Iamgoofball: - - bugfix: Fixes Nicotine's stun reduction - Joan: - - tweak: The Function Call action that summons a Ratvarian Spear is no longer one-use; - instead, it can be reused once every five minutes. - - experiment: Clockwork Walls and Floors will appear as normal walls and plating - to mesons, respectively. - coiax: - - tweak: Syndicate bombs now use a more accurate timer. - - bugfix: Fixed a separate bug that caused bomb timers to take twice as long (ie. - 60 seconds took 120 seconds) - - tweak: The AI doomsday device timer is more accurate. - - bugfix: Fixes a bug where the doomsday device would take twice as long as it should. - optional name here: - - bugfix: The search function on security records consoles now works. -2016-07-12: - MMMiracles: - - bugfix: Hotel staff can now actually use their own lockers. - RemieRichards: - - bugfix: fixed Kor's plant disguises - - bugfix: fixed some issues with Alternate Appearances not being added/removed - hornygranny: - - bugfix: Attacks will no longer miss missing limbs -2016-07-14: - Basilman: - - rscadd: Added a new hairstyle "Boddicker" - Bawhoppen: - - rscadd: Added two new materials, Titanium and plastitanium. Titanium is naturally - occuring, and plastitanium is an alloy made of plasma and titanium. - - rscadd: These materials can be used to build shuttle walls and floors, though - this serves no current purpose. - CoreOverload: - - rscadd: Some clothing has pockets now. - Firecage: - - tweak: Mechas can no longer pass through Plastic Flaps - Fox McCloud: - - bugfix: Fixes borg stun arm not having a hitsound, bypassing shields, and not - doing an attack animation - - bugfix: Fixes simple mobs not properly having armor penetration - Joan: - - rscadd: Added dextrous guardians to the code, able to hold and use items and store - a single item within themselves. - - experiment: Dextrous guardians do low damage on punches, have medium damage resist, - and recalling or leashing will force them to drop any items in their hands. - Kor: - - tweak: Shuttle travel time has been shortened from 25 seconds to 6 seconds - Lzimann: - - tweak: Alt clicking a jumpsuit now removes the accessories(if there's any)! - Papa Bones: - - tweak: Security's lethal injections are actually lethal now. - Xhuis: - - rscadd: Nanotrasen electricians have introduced a software update to all licensed - pinpointers. The new pinpointers are more responsive and automatically switch - modes based on the current crisis. - - rscadd: It should be noted that some of these pinpointers have been reported as - missing from their distribution warehouse and are presumed to have been stolen. - This is likely nothing to worry about. - lordpidey: - - tweak: Infernal jaunt now has a cooldown, to prevent trying to jaunt while already - jaunting. This should have no practical changes. - - bugfix: Infernal jaunt no longer occasionally leaves you permanently on fire. - - bugfix: Pitchforks no longer burn devils and soul-sellers, as intended. -2016-07-15: - Cheridan: - - rscadd: Added an aesthetic new space ruin -2016-07-16: - Gun Hog and WJohnston: - - rscadd: Aliens (Xenos) now have the ability to sense the direction and rough distance - of their queen! - Iamgoofball: - - bugfix: Fixed the lag when opening the foodcrafting menu by splitting everything - up into categories. - Joan: - - rscadd: Cogscarabs(and other nonhuman mobs able to hold clockwork slabs) can now - check the stats of the clockwork cult by using a clockwork slab. They remain - unable to use slabs under normal conditions. - MrStonedOne: - - experiment: Added a system to detect when stickybans go rogue and revert all recent - matches. -2016-07-18: - CoreOverload: - - rscadd: Sterilizine now reduces probability of step failure if you apply it after - starting surgery. Useful while operating in less-than-perfect conditions. - - rscadd: Potent alcohol can be used as replacement for sterilizine. - Joan: - - experiment: The Vanguard scripture no longer prevents you from using slabs while - active, but you cannot reactivate it if it is currently active. - - tweak: It now only lasts 20 seconds, instead of 30. - - tweak: When Vanguard deactivates, it now stuns for half the time of all stuns - absorbed, instead of all of them. - - tweak: Invoking Sevtug is less potent at long ranges, and slightly more potent - if extremely close. - - experiment: Invoking Sevtug now requires 3 invokers instead of 1. - - rscadd: The Clockwork Slab now has action buttons for rapidly invoking Guvax and - Vanguard. - - tweak: Belligerent is now chanted more often. - - experiment: Taunting Tirade now weakens nearby nonservants, but is now only invoked - once every 6 seconds(1 second chant, 5 second flee time) and is only chanted - five times. - lordpidey: - - rscadd: Flyswatters are now included in beekeeping crates, they are great at killing - insects and flies of all sizes. -2016-07-19: - Joan: - - tweak: Cogscarabs can no longer pass mobs and have slightly less health. - - experiment: The Gateway to the Celestial Derelict can now take damage from bombs. - RemieRichards: - - rscadd: Added VR Sleepers that allow users to enter a virtual body in a virtual - world (Currently not mapped in ;_;) - Xhuis: - - rscadd: Added communication intercept texts for gamemodes that were missing them. - - tweak: Changed all intercept texts and improved grammar for a lot of key game - code. - - rscdel: The shuttle can now leave while a celestial gateway exists. - - rscadd: If the shuttle docks at Central Command while a celestial gateway exists, - Ratvar's servants will win a minor victory. His arrival will still award a major - victory. - - rscadd: The celestial gateway can now take damage from explosions. -2016-07-22: - Bawhoppen: - - rscadd: Titanium now spawns in mining again. - - rscadd: It has uses in R&D and robotics production. - - rscadd: All shuttle walls are now using a new proper smoothing path. Mappers please - make sure to use this path correctly in the future. (along with tiles) - Cheridan: - - rscadd: Added another space ruin. - Cruix: - - bugfix: Camera bugs can now show camera views. - - bugfix: The chameleon masks in the chameleon kit can once again have their voice - changers toggled. - Incoming5643: - - rscadd: You now have the ability to automatically "back out" of a round if you - miss your chance at all the jobs you have set to low or higher. This is found - on the toggle at the bottom of the jobs window - - rscadd: Due to a quirk of game mode code this option will fail to work if you've - been selected as an antag (what a tragedy!) In this situation, you'll be assigned - a random job. - Joan: - - bugfix: You can now throw items and mobs over chasms without causing them to drop. - - bugfix: You can now throw items over lava without burning them. Mobs will still - burn, however. - - experiment: Tinkerer's Caches now link to a nearby unlinked clockwork wall, and - will not generate components unless linked. As compensation, they will link - to nearby walls(and can generate components) in a larger area. - - wip: Guvax is now slightly slower when above 5 valid servants; 1 additional second - of invoke time for each one above 5, from 0.75 additional seconds, up to a maximum - of 20 seconds of invoke time, from 15 seconds. - - tweak: Sigils of Transgression now stun for about 7 seconds. - - experiment: Sigils of Submission/Accession now take 7 seconds to convert successfully, - and have an obvious message to the person on them that their mind is being invaded. - - tweak: Ocular Wardens do 17% less damage. - - tweak: Mania Motors cause less brain damage and hallucinations. - - rscadd: If you lack the components to recite a scripture, you will be informed - of how many components that scripture requires. - - experiment: Tinkerer's Caches now cost an additional one of each non-alloy component - to construct for every three existing Tinkerer's Caches, up to a maximum of - 5 of each non-alloy component. - - rscadd: Revenant scriptures now announce to all servants and ghosts when used - instead of having a visible message. - Lzimann: - - tweak: Blood packs are now back in surgery room. - MMMiracles: - - rscadd: A giant wad of paper has been seen hurling through the nearby sector of - SS13, officials deny existence of giant paper ball hurling through space because - 'thats really fucking stupid'. - MrStonedOne: - - bugfix: Fixes super darkness from lighting creating two darkness overlays on the - same turf but only changing the darkness of one of the overlays - PKPenguin321: - - rscadd: Added Canned Laughter for the clown. Hehehe - RemieRichards: - - tweak: Auto-generated ratvarian now follows all the rules of hand-written ratvarian, - but you probably won't notice. - Shadowlight213: - - tweak: Angels can now equip satchels - - rscadd: Players will now receive an achievement for killing their first megafauna - after this point. - - rscadd: Additionally, megafauna kills are now tracked on a hub page. Rack up those - kills for first place! - Xhuis: - - rscadd: Clockwork cultists may now have the "Escape" and "Silicon" objectives, - requiring a certain amount of servants to escape on the shuttle and all silicons - to be converted respectively. - - rscadd: Ocular wardens are now forced to target bibles rather than the people - holding them. -2016-07-28: - Cruix: - - bugfix: Fixed a bug where some objects in photos would not be displayed if they - were facing a certain direction. - - bugfix: Photograph descriptions will no longer claim that mobs with low max health - are hurt when they are not. - Incoming5643: - - rscadd: The previously underwhelming viscerator robot has been made a lot more - terrifying by the new ability to proactively target and dismember limbs. - Joan: - - tweak: The Tinkerer's Cache cost increase for having multiple Tinkerer's Caches - now happens every 5 caches, from every 3. - - experiment: If the invoker of Nzcrentr is knocked unconscious or killed, they - will gib instead of producing a lighting blast. - - tweak: Anima Fragments slow down for slightly less time when hit. - - tweak: Clockwork Marauders do 1 more damage on every attack. - - tweak: Wraith Spectacles are now less hard on the eyes, and can be used without - permanent vision impairment for about 50% longer; from 40~ seconds to about - 1 minute. - - tweak: Halves the Interdiction Lens' disrupt cost from 100 per disrupted object - to 50 per disrupted object. - - tweak: Clockwork Sigils will now be destroyed by any level of explosion, except - for Sigils of Transmission, which will gain a small amount of power if hit by - a light explosion instead of breaking. - - bugfix: Clockwork Structures will now properly take damage from explosions instead - of variably not taking damage or instantly being destroyed. - - rscadd: Ghosts can now click Spatial Gateways to teleport to the other gateway. - - bugfix: Spatial Gateways are now properly disrupted by devastating explosions(but - not heavy or light explosions) - - rscadd: Striking a Sigil with any damaging item as a non-servant will remove it. - Servants still need to be on harm intent with an empty hand to remove Sigils. - Kor: - - rscadd: The Staff of Storms, dropped by Legion, can now be used on station. - MMMiracles: - - rscadd: Adds jump boots, a mid/end-tier mining equipment that allows the user - to dash over 4-wide chasms. - ModernViolence: - - bugfix: Hulk now has default cooldown for melee attacks against dominator - MrStonedOne: - - tweak: Space wind (movement from pressure differentials (like a hole to space)) - has been improved. - - tweak: Space wind's rate of movement now scales with pressure differential amount. - - experiment: Actively moving (as in holding down a move key) reduces chance/rate - of getting moved by space wind. - - rscadd: 'Having a wall or dense anchored object to your left or right will lower - the chance/rate of getting moved by space wind for each direction (IE: a wall - on both sides of you will be a double reduction)' - - rscadd: Added Lazy airlock cycling. Bump opening an airlock with this system will - close its partner. This system has been added to most airlocks that go to space - on boxstation, as well as airlocks to secure areas like brig, bridge, engine. - - tweak: This can be overridden by click opening, having a shuttle docked, or setting - emergency mode on one of the doors. - PKPenguin321: - - bugfix: Laughter no longer makes you laugh if you're muted. - - rscadd: Laughter can now be brewed with banana juice and sugar. - Thunder12345: - - rscadd: An old rapier was found rusting in the back of a closet. We cleaned it - up, polished it, and assigned it to your captain as a ceremonial weapon only. - Warranty void if used in combat. - incoming5643: - - tweak: viscerator grenades are now more generous with viscerators spawned -2016-07-30: - astralenigma: - - bugfix: Admins can now turn people into red god. -2016-07-31: - Arctophylax: - - bugfix: Birdboat's atmospheric tanks now function normally again. - - bugfix: Birdboat's TEG is now orientated to match the pipe layout. - Bawhoppen: - - tweak: toolboxes fit in backpacks - Gun Hog: - - rscadd: In an effort to reduce the demoralizing effects that accompany the death - of a crew member, Nanotrasen has provided the prototype designs for the Sad - Trombone implant. It can be fabricated at your station's protolathe, if you - manage to secure the ever elusive Bananium ore. - Joan: - - rscadd: Megafauna will now seek and consume corpses of enemies to heal or otherwise. - - tweak: Toolboxes are slightly more robust. - - tweak: Vanguard now only stuns for 25% of absorbed stuns, from 50%. - Kor: - - rscadd: Hostile mobs will now attack turrets. - Robustin: - - rscdel: Amber ERT Commanders no longer have thermal goggles - lordpidey: - - rscadd: Added Devil agent gamemode, where multiple devils are each trying to buy - more souls than the next in line. - - rscadd: If you've already sold your soul, you can sell it again to a different - devil. You can even go back and forth for INFINITE POWER. -2016-08-01: - Bawhoppen: - - rscadd: Added crowns. Make them from gold. Cap gets a fancy one. - Fox McCloud: - - rscadd: Adds in generic uplink refund system that potentially allows for even - regular traitors to refund uplink items - Joan: - - rscadd: Soul Vessels can now be used on unconscious or dead humans to extract - their consciousness, much like a soulstone. - - tweak: Soul Vessels no longer automatically ping ghosts when created, though they - can still be used in-hand to ping ghosts. - - rscadd: Soul Vessels can now communicate over the Hierophant Network - - experiment: Xenobiology golems enslaved to someone will become convertable if - their enslaver is converted to the enslaving antag type; this applies to gang - and both cult types. - oranges: - - rscdel: Reverted toolboxes fitting in backpacks due to being incorrectly merged -2016-08-02: - CoreOverload: - - rscadd: Pockets in coats! -2016-08-05: - Arctophylax: - - bugfix: The Emergency Medical and Winter Wonderland Holodeck programs work once - again. - Cruix: - - bugfix: RCDs can no longer place multiple grilles on the same tile. - - bugfix: RCDs will no longer use all their ammo if you try to build a wall on the - same turf multiple times. - - tweak: RCDs will now inform their user if they do not have enough ammo to complete - an operation. - Incoming5643: - - rscadd: Parrots have been made more robust. - Joan: - - rscadd: Clockwork Constructs, including anima fragments, marauders, and reclaimers, - can now communicate over the Hierophant Network. - - rscadd: Plasma cutters(normal, advanced, and mech) now have double range in low - pressure areas, but slightly lower range in high pressure areas. - - rscadd: Vitality Matrices will consume dead non-servant mobs to gain a large amount - of Vitality. This doesn't work on mobs that did not have a mind at some point. - Lordpidey and PKPenguin321: - - rscadd: Recent studies have revealed that fly amanita can give you a huge trip. - Lzimann: - - tweak: Holy water no longers makes you confused. - ModernViolence: - - bugfix: 'Photocopier fixes: proper sprites for not empty copies; removing originals - now does not delete them' - PKPenguin321: - - rscadd: Chef, do your station a favor and make a home run baseball burger (TM) - Robustin: - - rscadd: The initial supply talisman can now be used to create runed metal, 5 per - use - - rscadd: The void torch is now available from the altar, use it to transport any - item instantly to any cultist! It appears alongside the veil shifter as part - of the "Veil Walker" set. - - rscadd: Cult floors no longer appear on mesons! - - tweak: Flagellant's Robes now increases damage taken by 50%, down from 100% - - tweak: Veil Shifter has 4 uses, up from 2 - - tweak: Shuttle curse now delays shuttle 3 minutes, up from 2.5 minutes - - tweak: Cult forges, archives, and airlocks have had their cost reduced by 1 runed - metal each - Shadowlight213: - - rscadd: You will now receive an achievement for winning a pulse rifle at the arcade. - TheCarlSaganExpress: - - rscadd: Added lighting effects to the welder. -2016-08-07: - Arctophylax: - - bugfix: You can unbuckle mobs from meat spikes by clicking on the spike once again. - Joan: - - tweak: Barrier runes will now block air while active. - - rscadd: Trying to use sleeping carp against the colossus will now anger it. - frtbngll: - - bugfix: Fixed Paper Wizard summoning only 9 minions in its lifespan by making - the dead stickman decrease it's summoned_minions variable - lordpidey: - - bugfix: Centcom has received reports of cyborgs electrocuting themselves when - working on the power grid, and we have decided to stop storing important electronics - on the wirecutter's blade. -2016-08-08: - Ergovisavi: - - rscadd: Added bonfires to botany. Requires five tower cap logs to create, and - mobs can be buckled to them if an iron rod is added to the bonfire and the mob - is restrained. - Joan: - - rscadd: Added the clockcult "Global Records" alert, which clock cultists can mouse - over to check a variety of information on the clockcult's status, including - living servants, number of caches, CV, tinkerer's daemons, if there's an unconverted - AI, what clockwork generals can be invoked, and what scripture is unlocked. - Shadowlight213: - - rscadd: Ghosts can now see human player's huds when using the OOC -> Observe verb - WJohnston, Gun Hog: - - tweak: Xenos are now considered female. - - tweak: Hunter pounce are now always blocked by shields, and may be blocked more - often by other protective items. - - tweak: Alien Queen is now somewhat faster. - - tweak: Adjusted larva growth sprites. - - tweak: Removed 20% facehugger failure chance for masks. - - tweak: Disarm now always forces a person to drop an item in the active hand, and - if a person's hand is empty/undroppable, Disarm will always result in a tackle. - - tweak: Cyborgs disarmed by a Xeno will first disable their selected module, and - if there is none selected, the cyborg will be pushed back and stunned. - - tweak: Tail Sweep now has a slightly longer stun. -2016-08-10: - Cruix: - - rscadd: Sentient minebots can now toggle meson vision, a flashlight, their mode, - and dump their stored ore. - - bugfix: Sentient minebots can now be repaired if they were made sentient while - the AI was active. - - bugfix: Healing minebots will no longer switch them to attack mode. - - tweak: Sentient minebots can now shoot at humans. - - bugfix: The cooldown on wizard lightning will no longer break if you ethereal - jaunt or RISE! after the initial cast. - Kor: - - rscadd: You can now detonate drones with the RD console - LanCartwright: - - rscadd: Acute respiratory distress syndrom symptom. - - rscadd: Toxic metabolism. - - rscadd: Alkali perspiration - - rscadd: Autophagocytosis Necrosis - - rscadd: Apoptoxin filter - - rscadd: 3 different lategame/Non-roundstart virus reagents - - rscadd: 4 different lategame/Non-roundstart virus recipes - MrStonedOne: - - tweak: Tweaked space wind, it should now only trigger at higher pressure differences, - but be quicker to become aggressive as the pressure difference gets higher. - This should alleviate issues where small differences was still moving a lot - of things. - - tweak: Paper still moves with any pressure difference. - PKPenguin321: - - rscadd: There's now an achievement for managing to examine a meteor as a living - mob! - RemieRichards: - - rscadd: 'Added a new PDA button/app: Drone Phone!' -2016-08-14: - Cheridan: - - tweak: Greatly reduced amount of Hydroponics yield multipliers - - tweak: Somewhat reduced gaia'd tray sustainability. - - tweak: Mutagen will no longer potentially cause plant instadeath based on RNG. - Ergovisavi: - - tweak: Watchers no longer randomly fire beams at you when damaged, and no longer - beam you at point blank. - Gun Hog: - - tweak: The AI's Crew Manifest button now uses the updated styling. - Joan: - - rscadd: Sigils of Transgression now glow brightly when stunning a target. - - rscadd: The Global Records alert now shows the location and countdown time of - the Gateway to the Celestial Derelict. - - tweak: Clockcult tooltips now all have the clockcult tooltip style. - - rscdel: You can no longer become a Reclaimer when clicking on Ratvar. You can - still become a Cogscarab, however. - - bugfix: You can no longer invoke Vanguard while under its effects. - - bugfix: Servants of Ratvar should now always get an announcement when scripture - states change. - - tweak: Function Call can be used to summon a Ratvarian Spear once every 3 minutes, - from 5, but the spear summoned will now only last 3 minutes. - - rscadd: Belligerent now does minor damage to the legs on each invocation, up to - a maximum of 30 damage per recital. - - tweak: Ratvarian Spears will now stun any mob they're thrown at instead of just - enemy cultists and silicons, though the stun is still longer on enemy cultists - and silicons. - Jordie0608: - - rscdel: Removed clicking clown mask to morph it's shape, use action button instead. - Kor: - - rscadd: Added support for projectiles which can dismember - - rscadd: Added a new wizard sword, the spellblade, which fires dismembering projectiles. - Sprites from Lexorion. - - rscadd: Plasmacutter blasts can now take limbs off, but they still do pitiful - damage in a pressurized environment. - - rscadd: Humans and drones now have a UI button that allows them to create new - areas, in the same manner as blueprints. Unlike blueprints, this button does - not allow you to edit existing areas. - - rscadd: You can now use mineral doors (or any other object that blocks atmos) - to complete rooms with blueprints - - rscadd: Players created by sentience potions, mining drone upgrades, or Guardian/Holoparsite - summoners will now automatically join the users antagonist team, if any. - - rscadd: Mobs created in this manner will no longer be convertable/deconvertable - unless their creator is first converted/deconverted. - - rscadd: Cayenne will now officially become an operative when given a sentience - potion. - LanCartwright: - - bugfix: Fixes the recipes not working. - - tweak: Changes Stable uranium virus food recipe from Plasma virus food to just - plasma. - RemieRichards: - - bugfix: You can no longer use the incorrect limb type during augmentation - - bugfix: You can no longer use the incorrect limb type during prosthetic replacement - Shadowlight213: - - rscadd: Security has two new weapons in their arsenal. The security temperature - gun, and the DRAGnet capture and recovery system. - optional name here: - - bugfix: The syndicate uplink ui has been refactored to majorly reduce lag -2016-08-15: - Joan: - - rscadd: The Ark of the Clockwork Justicar can now be constructed even if Ratvar's - rise is not the objective. - - experiment: Accordingly, its behavior is different; instead of summoning Ratvar, - it will convert a massive amount of the station, and should effectively instantly - complete the clockwork cult's objectives. - MrStonedOne: - - tweak: Tweaked the lag stop numbers to hopefully reduce lag during 80+ population - - tweak: Fixed the blackbox not blackboxing. - OSCAR MIKE: - - rscadd: CONTACT ON THE LEFT SIDE! -2016-08-16: - MrStonedOne: - - rscadd: Automated the granting of profiler access to admins - oranges: - - rscadd: Nanotrasen is an all right kind of company -2016-08-17: - Basilman: - - rscadd: Added an admin-spawnable only "Cosmohonk" hardsuit that has the same protection - values of an engineering hardsuit. Comes with built-in lights and requires clown - roundstart role to be equipped. - Ergovisavi: - - rscadd: Adds the "Proto-Kinetic Crusher", a new melee mining weapon. Available - at a mining vendor near you! - Gun Hog: - - tweak: Nanotrasen has improved the coolant system in the stations automated robots. - They will no longer violently explode in hot rooms. - Joan: - - rscadd: Once the blob alert message is sent in the blob game mode, all mobs get - to see how many tiles the blob has until it wins, via the Status tab. - - rscdel: Removed/merged a bunch of blob chems, you probably don't care about the - specifics. - - tweak: The remaining blob chems should, overall, be more powerful. - - tweak: Shield blobs soak brute damage less well. - - tweak: Flashbangs do higher damage to blobs up close, but their damage falls off - faster. - - experiment: Shield blobs now cost 15 resources to make instead of 10. Node blobs - now cost 50 resources to make instead of 60. - - experiment: Expanding/attacking now costs 4 resources instead of 5, and blobs - can now ATTACK DIAGONALLY. Diagonal attacks are weaker than normal attacks, - especially against cyborgs(which may be entirely immune, depending), and they - remain unable to expand diagonally. - - rscadd: Shield blobs no longer block atmos while under half health. Shield blobs - are still immune to fire, even if they can't block atmos. - - tweak: Blobs should block explosions less well. - - rscadd: Blob cores and nodes are no longer immune to fire and no longer block - atmos. - - rscadd: Blobs can only auto-expand one tile at a time per expanding thing, and - should be easier to beat back in general. - - tweak: Blobbernauts now attack faster. - - tweak: Blob Overminds attack mobs slower but can attack non-mobs much faster. - - rscadd: Blob Overminds start with some amount of resources; in the gamemode, it's - 80 divided by the number of overminds, in the event, it's 20 plus the number - of active players, and otherwise, it's 60. - - bugfix: You can no longer move blob cores into space, onto the mining shuttle, - white ship, gulag shuttle, or solars. - - bugfix: Blob rounds might be less laggy, if they were laggy? - - tweak: Blobs don't heal as fast, excluding the core. - - experiment: Blobs are marginally less destructive to their environment. - MrStonedOne: - - rscdel: The server will no longer wait until the next tick to process movement - key presses. Movements should now be ~25-50ms more responsive. - Shadowlight213: - - rscadd: Adds modular computers -2016-08-21: - Ergovisavi: - - tweak: Consolidates the fulton packs into a single item and makes them more user - friendly - Google Play Store: - - spellcheck: Minor Text Fixes. - Incoming5643: - - rscadd: Smuggler satchels left behind hidden on the station can now reappear in - a later round. - - experiment: There's absolutely no way of knowing when exactly it will reappear - however... - - rscadd: Only one item in the satchel will remain when the satchel reappears. - - rscadd: Items are saved in their initial forms, so saving things like chemical - grenades will only disappoint you. - - rscadd: The item pool is map specific and needs to be a certain size before satchels - can start reappearing, so get to hiding that loot! - - rscadd: The staff of change has been expanded to turn you into even more things - that don't have hands. - Jalleo: - - bugfix: Gulag Teleporter of two issues any more please report them. - Jordie0608: - - rscadd: Advanced Energy Guns once again have a chance to irradiate you if EMPed. - Kor: - - rscadd: Kinetic Accelerators are now modular. You can find mod kits in the mining - vendor and in RnD. - - bugfix: Chaplain's dormant spellblade is no longer invisible. - Papa Bones: - - rscadd: A new, scandalous outfit is now available as contraband from the clothesmate - vendor, check it out! Fulfill your deep, dark fantasies. - Shadowlight213: - - tweak: Service and cargo have lost roundstart tablets and engineering has gained - them - - tweak: you can now charge battery modules in cell chargers. Use a screwdriver - on a computer to remove them. As a note, tablets and laptops can be charged - directly by placing them in a security charger. - WJohnston: - - rscadd: Metastation and Boxstation now boast auxillary mining construction rooms - in arrivals. These allow you to build a base and then launch it to wherever - you want on lavaland. - Wjohnston, Gun Hog: - - rscadd: Aliens with Neurotoxic Spit readied will now have drooling animations. - - rscadd: Hunters may now safely leap over lava. - - tweak: Hulk punches no longer stun Xenos. - - tweak: Alien evolve and promotion buttons updated to current Xeno sprites - - bugfix: Handcuff sprites for Xenos now show properly. -2016-08-22: - Bawhoppen: - - rscdel: Stock computers have been temporarily removed due to imbalances. - Ergovisavi: - - bugfix: Bubblegum's charge indicator should be significantly more accurate now. - ExcessiveUseOfCobblestone: - - rscdel: Reverts getting partial credit for discovered seeds. - - tweak: 'Tweaks Money Tree Potency Values [For instance: 1000 Space Cash requires - 98-100 Potency]' - Lzimann & Lexorion: - - rscadd: Adds a bow to the game, currently not craftable - Shadowlight213: - - bugfix: The efficiency AI sat SMES will now charge the APCs instead of itself. - XDTM: - - rscdel: Removed the Longevity symptom. - - rscadd: Added Viral Aggressive Metabolism, which will make viruses act quickly - but decay over time. - - rscadd: Cloning can now give bad mutations if unupgraded! - - rscadd: Cloning can, however, give you good ones if upgraded! -2016-08-24: - Bones: - - rscadd: The detective's closet now contains a seclite, get sleuthing! - Cargo Intelligence Agency: - - rscdel: You don't get to bring traitor items. - Ergovisavi: - - rscadd: Adds "Sacred Flame", a spell that makes everyone around you more flammable, - and lights yourself on fire. Share the wealth. Of fire. - - tweak: Replaces the fireball spellbook as a possible reward from a Drake chest - with a book of sacred flame. - Gun Hog: - - rscadd: The Aux mining base can now call the mining shuttle once landed! The mining - shuttle beacon that comes with the base must be deployed to enable this functionality. - - tweak: Multiple landing zones may now be set for the mining base. - - tweak: The coordinates of each landing zone is shown in the list. - - rscadd: Miners now each get a remote in their starting lockers. tweak The Aux - mining base now requires lighting while on station. - - tweak: The Aux Mining Base now has a GPS signal. - - tweak: The Aux Mining Base now has an alarm for when it is about to drop. - Incoming5643: - - rscadd: 'A slight change to the secret satchel system described below: If a satchel - cannot be spawned due to there not being enough hidden satchels to choose from, - a free empty satchel will spawn hidden SOMEWHERE on the station. Dig - it up and bury it with something interesting!' - Joan: - - rscadd: Using a resonator on an existing resonator field will immediately detonate - that field. Normal resonators will reduce the damage dealt to 80% of normal, - while upgraded resonators will not reduce it at all. - - rscadd: Adds a KA mod that does damage in an AoE, found only in necropolis chests. - - rscadd: You can now install any KA mods into a mining cyborg, though its mod capacity - is slightly lower. - - tweak: Mining cyborgs now have a crowbar to remove mods from their KA. - - tweak: Kinetic Accelerators now have a larger mod capacity, though most mods can - still only be installed the same amount of times as they can currently. - - tweak: You can now hit modkits with Kinetic Accelerators to install that modkit - into the accelerator. Mining cyborgs are unable to do so. - - rscadd: Added white and adjustably-coloured tracer round mods to the mining equipment - vendor, so you can see where your projectile is going(and look cool). - - rscadd: Added the super and hyper chassis mods to the mining equipment vendor, - so you can use excess mod space to have a cool-looking KA. - MrStonedOne: - - rscdel: Removes check on lights preventing you from turning them on while in a - locker - PKPenguin321: - - rscadd: Xeno queens now have an action button that makes them appear to themselves - as the old, small queen sprite. Now they should be able to interact with things - that are above them more easily. - Shadowlight213: - - tweak: Reviver and nutriment implants are far easier to get and have lower tech - origins. - - rscdel: Centcom has cut back on their cat carrier budget and will now only be - able to bring kittens along with runtime. - - rscadd: A new event has been added. The automated grid check. All apcs in non - critical areas will be shut off for some time, but can be manually rebooted - via interaction. - Yackemflam: - - tweak: Boxes are worth >26 tc at LEAST -2016-08-28: - CoreOverload: - - tweak: You can now use sheets from any hand, not just the active one. - Iamgoofball: - - tweak: Station and Character names are now allowed to be longer. - - rscdel: Gender Reassignment surgery has been removed. - Incoming5643: - - experiment: 'Due to a bad case of "being terrible" the save system for secret - satchels has been reworked. All saves are now unified in a single data file: - /data/npc_saves/SecretSatchels' - - rscdel: 'Old savefiles such as: /data/npc_saves/SecretSatchels_Box Station can - now be safely removed.' - - rscadd: A new slime reaction has been found for pink slimes using blood. The potion - produced from this reaction can be used to change the gender of living things. - Decently useful for animal husbandry, but otherwise mostly just for pranks/"""roleplay"""/enforcing - a brutal regime composed entirely of female slime people. - Joan: - - bugfix: Bumping the AI on help intent will no longer cause it and you to swap - positions, even if it is unanchored. If unanchored, it will properly push the - AI around. - - rscadd: The staff of lava can now turn lava back into basalt. - - bugfix: Placing a singularity or energy ball generator directly in front of an - active particle accelerator may be a bad idea. - Kor: - - rscadd: Added Battlemage armour to the spellbook. The armour is heavily shielded, - but will not recharge once the shields are depleted. - - rscadd: Added armour runes to the spellbook, which can grant additional charges - to the Battlemage armour. - MrStonedOne: - - rscadd: The game window will now flash in the taskbar on incoming admin pm, and - to all admins when an admin help comes in. - PKPenguin321: - - rscadd: The tesla is now much more dangerous, and can cause electronics to explode - violently. - - rscadd: It now hurts to get thrown into another person. - Shadowlight213: - - tweak: The radiation storm random event will automatically enable and disable - emergency maint. - - rscadd: The radiation storm random event is now a weather type that affects the - station. - - bugfix: The security temperature gun now has a firing pin making it 0.0000001% - more useful! - - rscadd: Added config option to use byond account creation age for job limits. - WJohnston: - - imageadd: Lavaland lava probably sorta looks better I guess. - Yackemflam: - - rscadd: Sniper kit have been given as a syndicate bundle set. Be warned though, - they are not as equipped as the nuclear agent kits. - kilkun: - - rscadd: Adds a shielded deathsquad hardsuit. it has four charges and recharges - after 15 seconds of not being shot (compared to the syndicate 3 charges and - 20 second recharge rate) - - tweak: All death commandos now spawn with this new hardsuit. The previous hardsuit - was not removed. - pubby: - - rscadd: Mining scanner module to standard borgs - - rscdel: Sheet snatcher module from standard borgs - xxalpha: - - rscadd: Cigarette packs, donut boxes, egg boxes can now be closed and opened with - Ctrl+Click. - - rscadd: Lighters are now represented in cigarette packs with a sprite of their - own. - - rscadd: You can now remove a lighter from a cigarette pack quickly with Alt+Click. - - bugfix: Reduced the amount of cigars that cigar cases can hold to 5 because the - cigar case sprite doesn't support more than that. -2016-08-29: - Cruix: - - rscadd: Space floppy-disk technology has advanced to the point that multiple technologies - or designs can be stored on a single disk. - Joan: - - rscadd: Lava bubbling up from basalt turfs now glows if in sufficient concentration. - - rscadd: Necropolis tendrils now glow. - - rscadd: Lava rivers now have riverbanks, and should overall look much nicer. - Shadowlight213: - - bugfix: The revenant ectoplasm sprite is no longer invisible. - Xhuis: - - rscadd: Highlander has been revamped. Now you can butcher your coworkers in cold - blood like never before! -2016-08-30: - oranges: - - tweak: The ed209 can now only fire as fast as the portaturrets -2016-08-31: - Iamgoofball: - - rscadd: Adds a new experimental gas to the game. Check it out! - Joan: - - rscadd: Vanguard now has a tooltip showing the amount of stuns you've absorbed - and will be affected by. - MMMiracles: - - bugfix: Xenomorphs can now actually damage barricades. - Shadowlight213: - - bugfix: Fixed runtime preventing access locked programs from being downloaded - XDTM: - - rscadd: Metal slimes now spawn a few sheets of glass when injected with water. - xxalpha: - - tweak: Opening and closing of donut boxes, etc. is now done with clicking the - object with itself. - yackemflam: - - rscadd: The standard rounds now blow off limbs. Happy hunting! -2016-09-01: - Cruix: - - bugfix: fortune cookies will now drop their fortunes when they are eaten. - Iamgoofball: - - tweak: NULL Crate in cargo was added again because people are fucking idiots so - if we're going to have this stupid fucking crate might as well make it not fucking - garbo - Kor: - - rscadd: Watertanks will now explode when shot. - Lzimann: - - tweak: You can now open all access doors while restrained. - Shadowlight213: - - tweak: Rad storms are more obvious - - bugfix: Pizza bombs will now delete after exploding. - phil235: - - tweak: Putting packagewrap or hand labeler in a backpack is now done by clicking - and dragging. - - bugfix: You can now wrap backpacks and other storage items with packagewrap. -2016-09-02: - A-t48: - - bugfix: Fixed cyborgs being able to use Power Warning emote when broken. - Iamgoofball: - - experiment: Freon has been reworked completely. - - rscadd: Water Vapor has been added to the Janitor's Closet. - RemieRichards: - - bugfix: Cutting bedsheets with a sharp object/wirecutters no longer puts the resulting - cloth INSIDE OF YOU if you're holding it, what a bug. - bgobandit: - - tweak: You can hide small items in urinals now. Use a screwdriver to screw open - the drain enclosure. - - rscadd: Every space urinal comes complete with space urinal cake. Do not eat. -2016-09-04: - A-t48: - - bugfix: Radiation storms no longer spam "Your armor softened the blow." - - bugfix: Radiation always gives a message that you are being irradiated, regardless - of armor level (only an issue if you stripped off all clothing) - - bugfix: Radiation now displays a message appropriate for all mob types (no longer - references clothes). - Gun Hog: - - rscadd: Ghosts may now read an AI or Cyborg's laws by examining them. - Joan: - - rscadd: The talisman of construction now has 25 uses, each of which can convert - a sheet of plasteel to a sheet of runed metal. It can still convert metal into - construct shells, and requires no specific amount of uses to do so. - - rscadd: Added the 'Drain Life' rune to the runes cultists can make. It will drain - life from all creatures on the rune, healing the invoker. - - imageadd: The 'Astral Communion' rune has a new sprite, made by WJohnston. - - rscdel: You can no longer use telekinesis to hit people with items they're holding, - items inside items they're holding, items embedded in them, items actually implanted - in them, or items they're wearing. - MMMiracles: - - rscadd: A set of combat gear for bears has been added, see your local russian - for more information. - XDTM: - - tweak: Nanotrasen has now stocked the DNA Manipulators with potassium iodide instead - of epinephrine as rejuvenators. -2016-09-07: - A-t48: - - bugfix: you can now scrub freon and water vapor - - bugfix: you can now label canisters as freon and water vapor - AnturK: - - rscadd: Watch out for special instructions from Centcom in the intercept report. - Cheridan: - - tweak: Brain damage no longer causes machines to be inoperable. - Ergovisavi: - - bugfix: Stops ash drakes from swooping across zlevels - Impisi: - - tweak: Increased chances of Modular Receiver drop in Maintenance - Incoming5643: - - rscdel: Wizards can no longer purchase the Cursed Heart from their spellbook. - Joan: - - experiment: The lava staff now has a short delay before creating lava, with a - visible indicator. - - tweak: The lava staff's cooldown is now somewhat shorter, and turning lava back - into basalt has a much shorter cooldown and no delay. - Lzimann: - - tweak: Stunprods no longer fit in your backpack, they go on your back now. - MrStonedOne: - - bugfix: Fixed lava sometimes doing massive amounts of damage. - - tweak: AFK players will no longer default to continue playing during restart votes. - XDTM: - - bugfix: Cloners now preserve your genetic mutations. - pubby: - - tweak: Changed military belt TC cost from 3 -> 1 - - tweak: Update ingredient boxes to have more useful ingredients -2016-09-08: - Jordie0608: - - rscadd: Notes can now be tagged as secret to be hidden from player viewed notes. - Lzimann: - - tweak: Legion implants now have a full heal when implanted instead of passive - heal + spawn tentacles. The healing also goes off when you enter crit. - Yackemflam: - - rscadd: You can now buy a box for a chance to mess with the stations meta for - ops. -2016-09-09: - Ergovisavi: - - rscadd: Adds new loot for the colossus, the "Anomalous Crystal" - - tweak: Enabled colossus spawning again - Joan, Ausops: - - rscadd: Added some very fancy tables, constructed by adding carpet tiles to a - standard table frame. - MrStonedOne: - - experiment: Blessed our beloved code with dark magic. - Shadowlight213: - - tweak: Radiation storm direct tox loss removed - - tweak: Radiation storms now cause a radiation alert to appear for the duration -2016-09-12: - Joan: - - rscadd: Cult structures can once again be constructed with runed metal. - - experiment: Cult structures can now take damage and be destroyed. Artificers can - repair them if they're damaged. - - tweak: The Recollection function of the clockwork slab is much more useful and - easier to parse. - - wip: Tweaked the Recital menus for scripture so the scripture are all in the proper - order. This might fuck you up if you were used to the incorrect order, but you'll - get used to it. - Nanotrasen Anti-Cheese Committee: - - bugfix: A glitch in the hydroponics tray firmware allowed it to retain plant growth - even after the plant was removed, resulting in the next planted seed being grown - instantaneously. This is no longer possible. - PKPenguin321: - - bugfix: Tesla shocks from grilles will no longer do thousands and thousands of - damage. They now properly deal burn damage that is equal to the current power - in the powernet divided by 5000. - Papa Bones: - - tweak: You can now rename the captain's sabre by using a pen on it. - RemieRichards: - - rscadd: Added the functionality for mobs to have multiple hands, this might have - broken some things, so please report any weirdness - Shadowlight213: - - rscdel: The surplus crate and random item will now only contain items allowed - by the gamemode - - rscdel: removes sleeping carp scroll from surplus crates - - experiment: Minimaps will now try to load from a cache or backup file if minimap - generation is disabled. - TheCarlSaganExpress: - - rscadd: Crayons, lipstick, cigarettes, and penlights can now be inserted into - PDAs. - phil235: - - rscadd: Monkeys can be dismembered. - - rscadd: Humans, monkeys and aliens can drop limbs when they are gibbed. - - rscadd: Roboticists can remove flashes, wires and power cells that they inserted - in robot head or torso by using a crowbar on it. - - rscadd: visual wounds appear on a monkey's bodyparts when injured, exactly like - humans. - - rscadd: Using a health analyzer on a monkey or alien shows the injuries to each - bodypart. - - rscadd: Monkeys can become husks. - - bugfix: Human-monkey transformations now respect missing limbs. No more limb regrowth - by becoming a monkey. - - bugfix: Changeling's regenerate ability also work while in monkey form. - - bugfix: Alien larva has its own gib and dust animation. - - bugfix: A bodypart that looks wounded still looks bloody when dismembered. - - bugfix: Amputation surgery now works on robotic limbs, and monkeys. -2016-09-14: - Ergovisavi: - - bugfix: Fixes lockers, bodybags, etc, giving you ash storm / radiation storm protection - Erwgd: - - rscadd: Upgraded sleepers can now inject inacusiate to treat ear damage. - Joan: - - rscadd: Added brass, producible by proselytizing rods, metal, or plasteel, or - by using Replicant Alloy in-hand, and usable to construct a variety of cult-y - brass objects. - - tweak: Objects constructable with brass include; wall gears, pinion airlocks, - brass windoors, brass windows, brass table frames and tables, and brass floor - tiles. - - rscadd: Cogscarabs can convert brass sheets into liquified alloy with their proselytizer. - - tweak: You can use brass sheets on wall gears to produce clockwork walls, or, - if the gear is unanchored, false clockwork walls. - - bugfix: Fixed a bug preventing you from converting grilles into ratvar grilles. - - experiment: Please note that conservation of mass exists. - Sligneris: - - tweak: Captain's space armor has been readapted with modern hardsuit technology. - oranges: - - tweak: Examine code for dismembered humans now has better easter eggs -2016-09-17: - BoxcarRacer41: - - rscadd: Added a new food, bacon. Bacon is made by processing raw meat cutlets. - - rscadd: Added a new burger recipe, the Bacon Burger. It is made with one bun, - one cheese wedge and three pieces of cooked bacon. - Ergovisavi: - - rscadd: Added a nightvision toggle to Shadowpeople - - tweak: Made several anomalous crystal variants more easily identified/easier to - see the effects thereof, and removed the "magic" activation possibility (replaced - with the "bomb" flag) - Gun Hog: - - tweak: Nanotrasen Robotics Division is proud to announce slightly less clunky - leg servo designs relating to the "Ripley" APLU and "Firefighter" exosuits. - Tests show increased mobility in both high and low pressure environments. The - previous designer has been fired for incompetence. - Improves tablets design: - - imageadd: Brings the tablet icons into the holy light of having depth - Joan: - - rscadd: Megafauna will now use ranged attacks even if they don't have direct vision - on their target. - - rscadd: Volt Void and Interdiction Lenses will now drain mech cells of energy. - - tweak: Ocular Wardens do slightly more damage to mechs. - - experiment: Replicant, Soul Vessel, Cogscarab, and Anima Fragment now take an - additional second to recite. - - tweak: Anima Fragments do slightly less damage in melee. - - tweak: Mending Motors and Clockwork Obelisks have slightly less health. - - tweak: Invoking Nezbere now requires 3 invokers. - - rscdel: Clockwork armor no longer has 5% energy resistance. - - bugfix: You can no longer construct clockwork structures on space turfs. - Papa Bones: - - tweak: BZ gas is no longer available on Box and Metastation layouts. - phil235: - - tweak: You no longer have to click a megaphone to use it, you simply keep it in - your active hand and talk normally. - - rscadd: Added new things - - imageadd: added some icons and images -2016-09-20: - Ergovisavi: - - bugfix: fixed "friendly" xenobio mobs and mining drones attacking station drones - Joan: - - rscadd: Miners can now buy KA AoE damage mods from the mining vendor for 2000 - points per mod. - - rscadd: 'Combined the Convert and Sacrifice runes into one rune. It''ll convert - targets that are alive and eligible, and attempt to sacrifice them otherwise. - The only changes to mechanics are that: Converting someone will heal them of - all brute and burn damage they had, and sacrificing anything will always produce - a soulstone(but will still only sometimes fill it)' - - tweak: You can no longer teleport to Teleport runes that have dense objects on - top of them. - - experiment: Wall runes will now activate other nearby wall runes when activated, - but will automatically disable after a minute and a half of continuous activity - and become unusable for 5 seconds. - - experiment: The Blood Boil rune no longer does all of its damage instantly or - stuns, but if you remain in range for the full duration you will be sent deep - into critical. - - experiment: Bubblegum has been seen reaching through blood. Try not to get hit. - - experiment: The Raise Dead rune no longer requires a noncultist corpse to revive - a cultist; instead, it will draw from the pool of all people sacrificed to power - the rune. - Mekhi: - - rscadd: Nanotrasen has been experimenting on cybernetics for a while, and rumors - are they have a few combat prototypes available... - - experiment: 'New arm implants: Energy-blade projector, implanted medical beamgun, - stun-arm implant (Like the borg version), flash implant that is automatically-regenerating - and doubles as a powerful flashlight. There is also one with all four items - in one. Also, a surgery toolkit implant. Adminspawn only for the moment.' - MrStonedOne: - - bugfix: Fixed space/nograv movement not triggering when atoms moved twice quickly - in space/nograv - Nanotrasen Stress Relief Board: - - rscadd: Latecomers to highlander can now join in on the fun. - - rscadd: The crew are encouraged to less pacifistic during highlander. Failing - to shed blood will result in your soul being devoured. Have a nice day. - Nicho1010: - - bugfix: Fixed lattices appearing after exploding lava - Screemonster: - - tweak: Abandoned crates no longer accept impossible guesses. - - tweak: Lets players know that all the digits in the code must be unique. - - tweak: Reads the last guess back on the multitool along with the correct/incorrect - guess readout. - - bugfix: multitool output on crates no longer returns nonsense values. - XDTM: - - rscadd: Positive viruses are now recognized by medical HUDs with a special icon. - - tweak: fully_heal no longer removes nonharmful viruses. This affects legion souls, - staffs of healing, and changeling's revive. - - rscadd: Canisters of any type of gas are now orderable in cargo. Dangerous experimental - gases will require Research Director approval. - Yackemflam: - - rscadd: The syndicate has learned on how to give their agents a true syndicate - ninja experience. - chickenboy10: - - rscadd: Added a Experimental Limb Grower to the medbay department, now medical - stuff can grow synthetic limbs using Synthflesh to help crew that suffer any - work related accidents. There may also be a limb that can be grown with a special - card... - feemjmeem: - - tweak: You can now disassemble meatspike frames with a welding tool. - phil235: - - experiment: 'adds a talk button next to the crafting button. Clicking it makes - a "wheel" appear around you with short predetermined messages that you click - to say them. This lets you say common responses without having to type in the - chat bar. Current messages available are: "Hi", "Bye", "Thanks", "Come", "Help", - "Stop", "Get out", "Yes", and "No". The talk button can be activated with the - hotkey "H" or "CTRL+H"' - - rscadd: Wearing colored glasses colors your vision. This option can be enabled/disabled - by alt-clicking any glasses with such feature. -2016-09-21: - Cyberboss: - - bugfix: The food processor's sprite's maintenance panel is no longer open while - closed and vice/versa - - tweak: Tesla arcs no longer lose power when passing through a coil that isn't - connected to a grid - MrStonedOne: - - bugfix: Fixes minimap generation crashes by making parts of it less precise -2016-09-23: - Cyberboss: - - rscadd: Wire layouts of NanoTransen devices for the round can now be found in - the Station Blueprints - Incoming5643 + WJohnston: - - imageadd: Lizard sprites have received an overhaul, sprites courtesy of WJohnston! - - rscdel: While there are some new bits, a few old bits have gone by the wayside, - if your lizard has been affected by this the specific feature will be randomized - until you pick a new setting. - - rscadd: Lizards can now choose to have digitigrade legs (those weird backwards - bending ones). Keep in mind that they can only be properly seen in rather short - pants. They also preclude the use of shoes. By default no lizard will have these - legs, you have to opt in. - - rscadd: All ash walker lizards however are forced to have these legs. - - experiment: There is absolutely no tactical benefits to using digitigrade legs, - you are only crippling yourself if you use them. - Papa Bones: - - tweak: You can now quick-draw the officer's sabre from its sheath by alt-clicking - it. - XDTM: - - bugfix: Holy Water no longer leaves you stuttering for years. -2016-09-24: - Cheridan: - - tweak: Nerfed Critical Hits - MrStonedOne: - - tweak: Orbits now use a subsystem. - - tweak: Orbits now bind to object's moving to allow for quicker updates, subsystem - fallback for when that doesn't work (for things inside of things or things that - move without announcing it) - XDTM: - - rscdel: Viruses start with 0 in every stat instead of 1. - - bugfix: Atomic Bomb, Pan-Galactic Gargle Blaster, Neurotoxin and Hippie's Delight - are now proper alcoholic drinks, and as such can disinfect, ignite, and be purged - by antihol. - optional name here: - - tweak: Changes cursed heart description to something slightly more clear. - - bugfix: Fixes a capitalization issue -2016-09-26: - Cuboos: - - rscadd: Added E-cigarettes as contraband to cigarettes vending machines. They - take reagents instead of dried plants and also hold more than cigarettes or - pipes. You can modify them to puff out clouds of reagents or emag them to fill - a whole room with reagent vapor. - - rscadd: Added a new shirt to the clothing vendor relating to the newly added vapes. - Joan: - - tweak: Blobs will generally require fewer blobs to win during the blob mode, which - should hopefully make the mode end faster at lower overmind amounts. - Razharas: - - rscadd: '"Kudzu now keeps the mutations it had before and thus can be properly - cultivated to be whatever you want"' - TheCarlSaganExpress: - - rscadd: You may now insert crayons, lipstick, penlights, or cigarettes in your - PDA. - - bugfix: Removing cartridges from the PDA will no longer cause them to automatically - fall to the floor. - oranges: - - rscadd: It looks like a pizza delivery from an un-named station got misplaced -2016-09-27: - Cobby: - - tweak: Nanotrasen has buffed the electronic safety devices found in Secure Briefcases - and Wallsafes, making them... well... more secure. In Particular, we added more - wires that do absolutely nothing but hinder the use of the multitool, along - with removing the ID slot only used by syndicates to emag the safe. - Incoming5643: - - rscadd: The secret satchels system has been updated to hide more smuggler's satchels - hidden randomly under the station - - experiment: In case you forgot about the secret satchel system, basically if you - take a smuggler's satchel (a traitor item also occasionally found under a random - tile in the station [USE T-RAYS]), stow away an item in it, and bury it under - the floor tiles that item can reappear in a random later round! - MrStonedOne: - - tweak: Custom Round end sounds selected by admins will be preloaded to all clients - before actually rebooting the world - Shadowlight213: - - bugfix: Fixes broken icon states when replacing warning floor tile - Supermichael777: - - tweak: Cat men have finally achieved equal discrimination. - TrustyGun+Pubby: - - imageadd: Lawyers now have unique speech bubbles. - XDTM: - - tweak: Using plasma on dark blue slimes will now spawn freon instead of arbitrarily - freezing mobs. - uraniummeltdown: - - tweak: Protolathe stock parts now build 5 times faster -2016-09-28: - Cuboos: - - bugfix: Removed the admin message spam from the smoke_spread proc. You may now - vape in peace without the threat of a Blue Space Artillery - LanCartwright: - - rscdel: Removed Stimulants and Coffee from survival pens. - - tweak: Nanites have been replaced with Mining Nanites which heal more when you - are lower health, and do not have the ridiculous healing Adminorazine had. -2016-10-01: - Incoming5643: - - rscadd: After years of having to live on a mostly blown up hunk of junk the wizard's - ship has finally been repaired - - rscdel: No one paid attention to that lore anyway -2016-10-07: - WJohnston: - - imageadd: Improved/resprited AI card, pAI, easel/canvases, shotgun shells, RCD - cartridge, speedloaders, and certain older buttons. - - imageadd: Improved/resprited a few bar signs, basketball/dodgeball/hoop, blood - bags, and body bags. - - imageadd: Improved/resprited Paper, stamps, folders, small fires, pens, energy - daggers, cabinets, newspaper and other bureaucracy related items. -2016-10-10: - ChemicalRascal: - - bugfix: Previously, improving the incinerator's efficiency made the RPM decay - more quickly, instead of less quickly. No more! - Cyberboss: - - rscadd: More reagent containers can be used for filling your dirty vapor cancer - sticks - - spellcheck: Fixed some vape spelling/grammar - MrStonedOne: - - tweak: Player Preferences window made slightly faster. - Nanotrasen Stress Relief Board: - - rscdel: Claymores created through Highlander no longer thirst for blood or announce - their wielder's location incessantly. - - bugfix: Claymores should now properly absorb fallen foes' corpses. - - bugfix: Losing a limb now properly destroys your claymore. - Supermichael777: - - bugfix: The wizards federation have instituted a strict 1 demon limit on demon - bottles. - XDTM: - - rscadd: Using blood on an Oil Slime will create Corn Oil. - - rscadd: Using blood on Pyrite Slimes will create a random crayon. - - rscadd: Using water on Orange Slimes will create a small smoke cloud. - - rscadd: Using water on Blue Slimes will spawn foam. - - rscadd: You can now retrieve materials inserted in a Drone Shell Dispenser with - a crowbar. - phil235: - - rscadd: A whole bunch of structures and machines can now be broken and destroyed - using conventional attack methods. - - rscadd: The effect of fire on objects is overhauled. When on fire, your external - clothes now take fire damage and can become ashes, unless fire proof. All objects - caught in a fire can now take fire damage, instead of just flammable ones, unless - fire proof. - - rscadd: Acid effect is overhauled. Splashing acid on something puts a green effect - on it and start slowly melting it. Throwing acid on mobs puts acid on their - clothes. Acid can destroy structures and items alike, as long as they're not - acid proof. The more acid put on an object, the faster it melts. Walking on - an acid puddle puts acid on your shoes or burns your bare feet. Picking up an - item with acid without adequate glove protection burns your hand. Acid can be - washed away with any sort of water source (extinguisher, shower, water glass,etc...). - - rscadd: When a mob receives melee attacks, its clothes also get damaged. Clothes - with enough damage get a visual effect. Damaged clothes can be repaired with - cloth (produced with botany's biogenerator). Clothes that receives too much - melee damage become shreds. - - tweak: Clicking a structure/machine with an item on help intent can never result - in an attack. - - tweak: Hostile animals that are environment destroyers no longer destroys tables&closets - in one hit. It now takes several hits depending on the animal. -2016-10-11: - Cyberboss: - - rscadd: The waste line now has a digital valve leading to space (off by default) - along with a port on it's far side - Incoming5643: - - rscadd: Wizards may finally use jaunt and blink on the escape shuttle. Maybe elsewhere - too? - - bugfix: The previously broken radios in the wizards den should work now. You still - have to turn them on though. - Kor: - - rscadd: Added frogs, with sprites by WJ and sounds by Cuboos. - Papa Bones: - - rscadd: Flora now spawns in lavaland tunnels, they can be harvested with a knife. - - rscadd: Flora have a range of effects, be careful what you eat! - - bugfix: You harvest flora on lavaland with your hands, not a knife. My bad. - Shadowlight213: - - rscadd: Cargo can order the antimatter engine -2016-10-12: - Cyberboss: - - bugfix: Fixed motion alarms instantly triggering and de/un/re/triggering - - bugfix: Airlock speed mode now works - Joan: - - rscadd: You can now deconstruct AI cores that contain no actual AI. - WJohnston: - - imageadd: Recolored and resprited candles and ID cards. Folders should have improved - color contrast. - XDTM: - - rscadd: Exhausted slime extracts will now dissolve instead of leaving useless - used slime extracts. - - tweak: Airlocks are now immune to any damage below 20, to prevent pickaxe prison - breaks. - - tweak: High-Security Airlocks, such as the vault or the AI core's airlocks, are - now immune to any damage below 30. -2016-10-13: - Razharas: - - tweak: Makes clicking something in heat of battle a bit easier by making drag&drops - that dont have any effect be counted as clicks - XDTM: - - rscadd: 'Added four new symptoms: Regeneration and Tissue Regrowth heal respectively - brute and burn damage slowly; Flesh Mending and Heat Resistance are the level - 8 version of those symptoms, and heal faster.' - - rscdel: The Toxic Compensation, Toxic Metabolism and Stimulants symptoms have - been removed. - - rscdel: Viruses no longer stack. Viruses can be overridden if the infecting virus - has higher transmittability than the previous virus' resistance. - - tweak: Viruses can now have 8 symptoms, up from 6. - - rscadd: You can now store monkey cubes in bio bags; using bio bags on the consoles - will load them with the monkey cubes inside the bags. - ma44: - - rscadd: Cargo can now order a 2500 supply point crate that requires a QM or above - to unlock. This crates contains a explorer suit, compact pickaxe, mesons, and - a bag to hold ore with. -2016-10-16: - Cuboos: - - rscadd: Added a new unique tool belt to the CE - - rscadd: Added new power tools, a hand drill that can be used as a screw driver - or wrench and jaws of life which can be used as either a crowbar or wire cutters - - rscadd: Power tools can also be made from the protolathe with engineering and - electromagnet 6 - - tweak: slightly revamped how construction/deconstruction handle sound - - soundadd: added new sounds for the power tools - - soundadd: added a new sound for activating and deactivating welding tools, just - because. - Cyberboss: - - bugfix: Plasma fires no longer cause cameras to break. - Joan: - - tweak: Blazing Oil blobs are now outright immune to fire. This does not affect - damage taken from other sources that happen to do burn damage. - - tweak: Normal blob spores now take two welder hits to die, from three. - - tweak: Cyborgs now die much less rapidly to blob attacks. - Lzimann: - - tweak: 'Changed two admin hotkeys: f7 is now stealth-mode and f8 to toggle-build-mode-self.' - Shadowlight213: - - bugfix: Modular consoles have been fixed. - Supermichael777: - - tweak: Changeling Sting is now one part screwdriver cocktail and 2 parts lemon-lime - soda. - - bugfix: Triple citrus now actually displays its sprite. - Yackemflam: - - tweak: extinguishers now spray faster - coiax: - - rscadd: RCDs have a Toggle Window Type verb allowing the rapid construction of - reinforced windows, rather than regular windows. - - rscadd: RCDs can now finish and deconstruct wall girders. - phil235: - - tweak: Clicking a floor with a bodybag or roller bed now deploys them directly - (and the bodybag starts open) - scoopscoop: - - bugfix: The cult shifter will now properly spawn as part of the veil walker set. -2016-10-18: - Basilman: - - rscadd: A third martial art, CQC, has been added and is now available to nuke - ops instead of sleeping carp - Kor: - - rscadd: Added sloths to cargobay on Box and Meta - MrPerson: - - rscadd: New toxin - Rotatium. It doesn't quite do what it does on other servers. - Instead it rocks your game view back and forth while slowly doing toxin damage. - The rocking gets more intense with time. - - rscadd: To make it, mix equal parts mindbreaker, neurotoxin, and teslium. - MrStonedOne: - - experiment: Byond 511 beta users may now choose their own FPS. This will apply - to animations and other client side only effects. Find it in your game preferences. - Shadowlight213: - - bugfix: fixed removing modular computer components - TheCarlSaganExpress: - - tweak: Provided you have access, you may now use your ID to unlock the display - case. - - tweak: The fire axe cabinet and display case may now be repaired with the welder. - XDTM: - - rscadd: You can now grind slime extracts in a reagent grinder. If the slime was - unused it will result in slime jelly, while if used it will only output the - reagents inside the extract. - Yackemflam: - - bugfix: fixed the standard vest being weaker than the slim variant - lordpidey: - - rscadd: There is a new potential obligation for devils to have. Musical duels. Ask - your nearest devil for a musical duel, there's a 14% chance he's obligated to - do it. - - rscdel: Removed the old offering a drink obligation for devils, it overlapped - too much with the food obligation. - - tweak: Trying to clone people who've sold their soul now results in FUN. - - tweak: Devils can no longer spam ghosts with revival contracts. - phil235: - - rscadd: Visual effects appear on the target of an attack, similar to the item - attack effect. - - rscdel: You now only see a message in chat when witnessing someone else getting - attacked or hit by a bullet if you are close enough to the action. -2016-10-19: - Cyberboss: - - bugfix: Physically speaking is no longer delayed by your radio's lag - - bugfix: You can now attack doors with fireaxes and crowbars when using the harm - intent - - tweak: The BSA is no longer ready to fire when constructed - - bugfix: The BSA can no longer be reloaded faster by rebuilding the console - MrStonedOne: - - tweak: tweaked the settings of the space drift subsystem to be less effected by - anti-lag slowdowns - Pubby: - - rscadd: 'A new map: PubbyStation. Set it to your favorite in map preferences!' - XDTM: - - rscadd: PanD.E.M.I.C. now displays the statistics of the viruses inside. - phil235: - - tweak: Made the singularity gen and tesla gen immune to fire. - - tweak: All unique traitor steal objective item are now immune to all damage except - severity=1 explosion. - - tweak: Mobs on fire no longer get damage to their worn backpacks, belts, id, pocket - stuff, and suit storage. - - bugfix: Mob receiving melee attacks now only have its outer layer of clothes damaged, - e.g. no damage to jumpsuit when wearing a suit. - - bugfix: now all hardsuit have 50% more health, as intended. - wrist: - - rscadd: Toxins is different now. -2016-10-21: - Adam E.: - - tweak: Added cargo and engi access to auxillary mine base launching console. - Cyberboss: - - tweak: Your brain is now gibbed upon chestburst - - bugfix: The safe is indestructible again - Joan: - - rscadd: Wraith Spectacles will now slowly repair the eye damage they did to you - as long as you aren't wearing them. - - experiment: You can now see how much eye damage the spectacles have done to you - overall, as well as how close you are to being nearsighted/blinded. - - tweak: Mending Motors heal for more. - - wip: Mania Motors are overall more powerful; they have greater effect, but require - more power to run and less power to convert adjacent targets. - - experiment: Interdiction Lenses no longer require power to disrupt electronics - and will no longer disrupt the radios of servants. - - bugfix: You need to be holding teleport talismans and wizard teleport scrolls - in your hands when you finish the input, and cannot simply open the input and - finish it whenever you get stunned. - - tweak: The range for seeing visible messages in combat is a tile higher. - Screemonster: - - tweak: The anti-tamper mechanism on abandoned crates now resists tampering. - - tweak: Secure, non-abandoned crates can be given a %chance of exploding when tampered - with. Defaults to 0. - Shadowlight213: - - bugfix: The Swap minds wizard event will now function - Swindly: - - rscadd: The action button for a dental implant now includes the name of the pill - - bugfix: The pill activation button now properly displays the pill's icon - uraniummeltdown: - - rscadd: Adds more replacements to the Swedish gene -2016-10-22: - Shadowlight213: - - experiment: Breathing has been moved from species to the lung organ - - rscadd: Lung transplants are now possible! -2016-10-23: - Cyberboss: - - bugfix: Fixed a bug that caused door buttons to open doors one after another rather - than simultaneously like they are suppose to - - bugfix: NOHUNGER species no longer hunger - - bugfix: Appropriate gloves now protect you from getting burned by cheap cigarette - lighters - - rscdel: Labcoats no longer have pockets - Yackemflam: - - tweak: Riot helmets are now more useful in melee situations and the standard helmet - is now slightly weaker - uraniummeltdown: - - rscadd: Atmos grenades are now in the game and uplink -2016-10-24: - Batman: - - tweak: The sniper rifle descriptions are less edgy. - Cobby: - - rscadd: Finally, a way to relate to Bees! - Cyberboss: - - bugfix: Morphs no longer gain the transparency of chameleons - - bugfix: Turrets can no longer shoot when unwrenched - - bugfix: Spray bottle can now be used in the chem dispenser - Joan: - - rscadd: Clockwork marauders now have a HUD, showing block chance, counter chance, - health, fatigue, and host health(if applicable), as well as including a button - to try to emerge/recall. - - experiment: Clockwork marauders can now block bullets and thrown items, even if - Ratvar has not risen. - - rscadd: The Judicial Visor no longer requires an open hand to use. Instead, clicking - the button will give you a target selector to place the Judicial Marker. - - experiment: Tinkerer's Daemons are now a structure instead of a Cache addon. - - wip: Tinkerer's Daemons now consume a small amount of power when producing a component, - but produce components every 12 seconds with no additional delay. - - tweak: Adjusted the costs of the Tinkerer's Daemon and Interdiction Lens. - - imageadd: Floaty component images appear when Tinkerer's Caches and Daemons produce - components. - MrStonedOne: - - bugfix: Spectral sword now tracks orbiting ghosts correctly. - Shadowlight213: - - imageadd: Damaged airlocks now have a sparking effect - Swindly: - - rscadd: Added a button to the ChemMaster that dispenses the entire buffer to bottles. - ma44: - - rscadd: Reminds the user that reading or writing a book is stupid. -2016-10-27: - Chowder McArthor: - - rscadd: Added a neck slot. - - tweak: Modified some of the attachment items (ties, scarves, etc) to be neck slot - items instead. - Cyberboss: - - rscadd: NEW HOTKEYS - - rscadd: The number pad can be used to select the body part you want to target - (Cycle through head -> eyes -> mouth with 8) in hotkey mode. Be sure Numlock - is on! - - rscadd: Holding shift can be used as a modifier to your current run state in both - hotkey and normal mode. - - bugfix: Emag can no longer be spammed on shuttle console - Gun Hog: - - bugfix: Fixed AIs uploaded to mechs having their camera view stuck to their card. - Joan: - - rscadd: Clockwork Floors now have a glow when healing servants of toxin damage. - Only other servants can see it, so don't get any funny ideas. - - bugfix: The Interdiction Lens now properly has a high Belligerent Eye cost instead - of a high Replicant Alloy cost. - Pubby: - - tweak: PubbyStation's bar is now themed like a spooky castle! - Swindly: - - bugfix: Chem implants can now be properly filled and implanted - WJohnston: - - rscadd: Adds an unlocked miner equipment locker on Boxstation and Metastation's - Aux Base Construction area, as well as a telescreen to the camera inside. All - mining outpost computers can also see through that camera. - lordpidey: - - rscadd: The wizard federation has teamed up with various LARP groups to invent - a new type of spell. -2016-10-28: - Erwgd: - - rscadd: You can now use cloth to make black or fingerless gloves. - - tweak: Biogenerators require less biomass to produce botanist's leather gloves. - Tacolizard: - - rscadd: Added a new contraband crate to cargo, the ATV crate. -2016-10-29: - Chowder McArthor: - - bugfix: Added in icons for the neck slot for the other huds. - Cobby: - - rscadd: Adds several Halloween-Themed Emojis. See if you can get them all! [no - code diving cheaters!] - Erwgd: - - rscadd: The NanoMed Plus now stocks premium items. - Joan: - - experiment: Guvax is now targeted; invoking it charges your slab to bind and start - converting the next target attacked in melee within 10 seconds. This makes your - slab visible in-hand. - - tweak: Above 5 Servants, the invocation to charge your slab is not whispered, - and the conversion time is increased for each Servant above 5. - - wip: Using Guvax on an already bound target will stun them. The bound target can - resist out, which will prevent conversion. - - experiment: Sentinel's Compromise is now targeted, like Guvax, but can select - any target in vision range. - - rscadd: Sentinel's Compromise now also removes holy water from the target Servant. - - wip: Clicking your slab will cancel these scriptures. - - imageadd: Both of these will change your cursor, to make it obvious they're active - and you can't do anything else. - - rscadd: Arks of the Clockwork Justicar that do not summon Ratvar will still quick-call - the shuttle. - - bugfix: Clockwork structures that return power can now return power to the APC - of the area they're in if there happens to be one. - - bugfix: Clockwork structures that use power from an APC will cause that APC to - start charging and update the tgUI of anyone looking at the APC. - - bugfix: Converting metal, rods, or plasteel to brass with a clockwork proselytizer - while holding it will no longer leave a remainder inside of you. - - tweak: Plasteel to brass is now a 2:1 ratio, from a 2.5:1 ratio. Accordingly, - you now only need 2 sheets of plasteel to convert it to brass instead of 10 - sheets. - - tweak: Wall gears are now converted to brass sheets instead of directly to alloy. - - rscdel: You can no longer do other proselytizer actions while refueling from a - cache. - - bugfix: Fixed a bug where certain stacks wouldn't merge with other stacks, even - when they should have been. - - bugfix: Clockwork structures constructed from brass sheets now all have appropriate - construction value to replicant alloy ratios. - - bugfix: Tinkerer's Caches no longer need to see a clockwork wall to link to it - and generate components. - MrStonedOne: - - experiment: Shoes do not go on heads. - NikNak: - - rscadd: Action figures are finally winnable at arcade machines. Comes in boxes - of 4. - Pubby: - - rscadd: The holodeck has been upgraded with new programs. Try them out! - Shadowlight213: - - rscdel: The HOS and other heads of staff no longer have a chance to be revheads - TehZombehz: - - tweak: Custom food items can now fit inside of smaller containers, such as paper - sacks. - - rscadd: Small cartons can be crafted using 1 piece of cardboard. Don't be late - for school. - - rscadd: Apples can now be juiced for apple juice. Chocolate milk can now be crafted - using milk and cocoa. - - tweak: Chocolate bar recipe has been modified to compensate for chocolate milk. - The soy milk version of the chocolate bar recipe remains unchanged. - - bugfix: Grapes can now be properly juiced for grape juice using a grinder. - XDTM: - - tweak: Wizards no longer need sandals to cast robed spells. - Xhuis: - - rscadd: Syndicate and malfunctioning AIs may now be transferred onto an intelliCard - if their parent core has been destroyed. This may only be done with the AI's - consent, and the AI may not be re-transferred onto another APC or the APC it - came from. - - rscadd: New additions have been made for this Halloween and all future ones. Happy - Halloween! - ma44: - - rscadd: You can now solidify liquid gold into sheets of gold with frostoil and - a very little amount of iron -2016-10-30: - Joan: - - rscadd: The Recollection option in the Clockwork Slab has been significantly improved, - with a better information to fluff ratio, and the ability to toggle which tiers - of scripture that are visible in Recollection. - Lzimann: - - bugfix: You can once again order books by its ID in the library. - Mysak0CZ: - - bugfix: You no longer need to deconstruct emagged (or AI-hacked) APC to fix them, - replacing board is sufficient - - bugfix: You can no longer unlock AI-hacked APCs - - bugfix: Removing APC's and SMES's terminal no longer ignore current tool's speed - - rscadd: You can repair APC's cover (only if APC is not compleatly broken) by using - APC frame on it - - rscadd: closing APC's cover will lock it - bgobandit: - - rscadd: The creepy clown epidemic has arrived at Space Station 13. - - rscadd: Honk. -2016-10-31: - Joan: - - experiment: Brass windows will now survive two fireaxe hits, and are slightly - more resistant to bullets. - Lzimann: - - rscdel: Changelings no longer have the Swap Forms ability. - Xhuis: - - rscadd: Disposal units, outlets, etc. are now fireproof. - - rscadd: Changelings can now use biodegrade to escape silk cocoons. -2016-11-02: - Iamgoofball: - - rscadd: Added a new lobby menu sound. - Joan: - - rscdel: Brass windows and windoors no longer drop full sheets of brass when destroyed. - - rscadd: Instead, they'll drop gear bits, which can be proselytized for a small - amount of liquified alloy; 80% of the materials used to construct the window. - - tweak: Mending Motors have an increased range and heal for more. - - experiment: Mending Motors will no longer waste massive amounts of power on slightly - damaged objects; instead, they will heal a small amount, use a small amount - of power, and stop if the object is fully healed. - - wip: Mending Motors can now heal all clockwork objects, including pinion airlocks, - brass windows, and anything else you can think of. - - rscadd: Ocular Wardens will no longer attack targets that are handcuffed, buckled - to something AND lying, or in the process of being converted by Guvax. - - tweak: Also, they do very slightly more damage. - - rscdel: Hulks no longer one-shot most clockwork structures and will no longer - four-shot the Gateway to the Celestial Derelict. - - bugfix: Hulks are no longer a blob counter. - XDTM: - - tweak: Ninjas are now slightly visible when stealthing. - phil235: - - rscadd: Spray cleaner and soap can now wash off paint color. -2016-11-03: - Cobby: - - rscadd: Adds a geisha outfit to the clothesmate on hacking. QT space ninja BF - not included - Joan: - - rscadd: 'Proselytizing a window will automatically proselytize any grilles under - it. This is free, so don''t worry about wasting alloy. rcsadd: Trying to proselytize - something that can''t be proselytized will try to proselytize the turf under - it, instead.' - - experiment: Clockcult's "Convert All Silicons" objective now also requires that - Application scripture is unlocked. - - wip: The "Convert All Silicons" objective will also only be given if there is - an AI, instead of only if there is a silicon. -2016-11-05: - Joan: - - rscadd: Proselytizer conversion now accounts for existing materials, and deconstructing - a wall, a girder, or a window for its materials is no longer more efficient - than just converting it. - - imageadd: Heal glows now appear when mending motors repair clockwork mobs and - objects. - Lzimann: - - rscdel: You can no longer walk holding shift. -2016-11-06: - Joan: - - bugfix: Dragging people over a Vitality Matrix will actually cause the Matrix - to start working on them instead of failing to start draining because it's "active" - from when the dragging person crossed it. - phil235: - - rscadd: You can now climb on transit tube, like tables. - - rscadd: You can now use tabs when writing on paper by writing "[tab]" -2016-11-07: - Basilman: - - rscadd: CQC users can now block attacks by having their throw mode on. - - tweak: The CQC kick and Disorient-disarm combos are now much easier to use, CQC - harm intent attacks are stronger aswell. - - bugfix: Fixed being able to CQC restrain someone, let him go, then 10 minutes - later disarm someone else to instantly chokehold them. - - tweak: CQC costs more TC (13) - Cyberboss: - - bugfix: Tesla zaps that don't come from an energy ball can no longer destroy nukes - and gravity generators - El Tacolizard: - - rscadd: A space monastery and chaplain job have been added to PubbyStation. - - rscadd: Improved pubby's maint detailing - Joan: - - tweak: Ratvarian Spears now do 18 damage and ignore a small amount of armor on - normal attacks, but have a slightly lower chance to knowdown/knockout. Impaling - also ignores a larger amount of armor. - - rscadd: Throwing a Ratvarian Spear at a Servant will not damage them and may cause - them to catch the spear. - - rscadd: Standard drones will be converted to Cogscarabs by Ratvar and the Celestial - Gateway proselytization. - - rscdel: Cogscarabs no longer receive station alerts. - - bugfix: Anima Fragments, Clockwork Marauders, and cult constructs are now properly - immune to heat and electricity. - - tweak: Clockwork armor is much stronger against bullets and bombs but much weaker - against lasers. - - wip: Specific numbers; Bullet armor from 50% to 70%, bomb armor from 35% to 60%, - laser armor from -15% to -25%. This means lasers are a 4-hit crit. - - rscadd: You can now Quickbind scripture other than Guvax and Vanguard to the Clockwork - Slab's action buttons, via Recollection. - - rscadd: You can also recite scripture directly from Recollection, if doing so - suits your taste. Of course it suits your taste, it's way easier than menus. - - tweak: You can also toggle compact scripture in Recollection, so that you don't - see description, invocation time, component cost, or tips. - - tweak: Dropping items into Spatial Gateways no longer consumes a use from the - gateway. - - rscadd: If your Spatial Gateway target is unconscious, you can pick a new target - instead. - Kor: - - rscadd: Multiverse teams now have HUD icons. - - rscadd: Multiverse war is back in the spellbook. - phil235: - - rscadd: Altclicking a PDA without id now removes its pen. - - rscadd: The PDA's sprite now shows whether it has an id, a pAI, a pen, or if its - light is on. -2016-11-09: - Changes: - - tweak: Old mining asteroid is more interesting (mining world can be picked in - ministation.dm) - - tweak: Space around ministation is now half(?) the size of normal space - - rscadd: Loot spawners to maintenance - - bugfix: Rad storms frying maintenance - - bugfix: Bad conveyor belts in mining/cargo area of station - - bugfix: Bombs completely destroying toxins test site - - rscadd: Cyborg job available again - - tweak: Mining cyborgs can use steel rods when asteroid mining is enabled - Joan: - - tweak: Repairing clockwork structures with a Clockwork Proselytizer now only costs - 1 alloy per point of damage. - - experiment: Vitality Matrices will no longer heal dead Servants that they cannot - outright revive. - - rscadd: The Celestial Gateway will now prevent the emergency shuttle from leaving. - - tweak: However, Centcom will alert, in general terms, the location of the Celestial - Gateway two minutes after it is summoned. - - rscadd: Reciting scripture while not on the station, centcom, or mining/lavaland - will double recital time and component costs. - Kor: - - rscadd: You can now examine an r-wall to find out which tool is needed to continue - deconstructing it. - - rscadd: The game will now recognize a successful detonation of the nuclear bomb - in the syndicate base. - - rscadd: Cloaks are now cosmetic items that can be worn in the neck slot, allowing - you to wear them over armour. - Shadowlight213: - - rscdel: Removed the restriction on attacking people with a fire extinguisher on - help intent if the safety is on. - uraniummeltdown: - - rscadd: Added Cortical Borers, a brainslug parasite. - - rscadd: Added Cortical Borer Event -2016-11-10: - Kor: - - rscadd: The wizard has a new spell, Rod Form, which allows him to transform into - an immovable rod. - uraniummeltdown: - - bugfix: fixed brains not having ckeys when removed - - bugfix: hopefully fixed multiple ghosts entering a borer ghosting all but one - - tweak: tweaked the formula for hosts needed for borer event to 1+humans/6 - - tweak: borer endround report is a lot nicer -2016-11-11: - Cyberboss: - - bugfix: Promotion of revheads won't occur if they are restrained/incapacitated - - bugfix: Facehuggers can no longer latch onto mobs without a head... How the fuck - did you get a living mob without a head? - - bugfix: Hulks and monkeys can no longer bypass armor - - rscadd: Metastation now has a waste to space line - - bugfix: Objects will no longer get stuck behind the recycler on Boxstation - Joan: - - rscadd: You can now repair reinforced walls by using the tool you'd use to get - to the state they're currently in. Examining will give you a hint as to which - tool to use. - - spellcheck: Renamed Guvax to Geis. This also applies to the component, which has - been similarly renamed. - Kor: - - rscadd: The Captain can now purchase alternate escape shuttles from the communications - console. This drains from the station supply of cargo points, and you can only - do so once per round, so spend wisely. - - rscadd: Some shuttles are less desirable than the default, and will instead grant - the station a credit bonus when purchased. - - rscadd: Explosions are no longer capped on the mining z level. - - rscadd: The forcewall spell now creates a 3x1 wall which the caster can pass through. - - rscadd: Bedsheets are now worn in the neck slot, rather than the back slot. -2016-11-13: - Cyberboss: - - rscadd: Using a screwdriver on a conveyor belt will reverse it's direction - - bugfix: Medibots, by default, can no longer OD you on tricord - - tweak: They will now use charcoal instead of anti-toxin to heal tox damage - - bugfix: Silicons no longer get warm skin when irradiated - Gun Hog: - - tweak: Wizard (and Devil) fireballs now automatically toggle off once fired. - Joan: - - tweak: Judicial Visors now protect from flashes. - - rscadd: Reciting Scripture is now done through an actual interface, and can thus - be done much faster. - - rscdel: The recital and quickbind functions that Recollection had have been moved - to this interface instead. - - rscadd: Servants of Ratvar can now unsecure and move most Clockwork Structures - with a wrench, though doing so will damage the structure by 25% of its maximum - integrity. - - rscadd: Clockwork Structures become less effective as their integrity lowers, - reducing their effect by up to 50% at 25% integrity. - - tweak: You can now deconstruct unsecured wall gears with a screwdriver. - - tweak: Wall gears now have much more health and can be repaired with a proselytizer. - Mysak0CZ: - - rscadd: You can now use wrech to anchor (as long as it is not in space) / unanchor - lockers - - bugfix: Cyborgs can now simply use "hand" to open / close lockers (instead of - using toggle open verb) - - bugfix: You can now properly put unlit welder inside lockers - - bugfix: Lockers using different decostruction tools (like cardboard boxes wirecutters) - can now be deconstructed too - Xhuis: - - rscadd: All computers now have sounds. Try them out! - coiax: - - rscadd: Swarmers can now use :b to talk on Swarm Communication. - - rscadd: Lich phylacteries are now in the "points of interest" for ghosts. - uraniummeltdown: - - bugfix: Cancel Assume Control works as borer now - - rscadd: Added the cueball helmet, scratch suit, joy mask to Autodrobe -2016-11-14: - Joan: - - rscdel: You can no longer pick up cogscarabs. - - rscadd: Servants of Ratvar can now reactivate Cogscarabs with a screwdriver. - - tweak: Cogscarab proselytizers proselytize things twice as fast. - - tweak: Cogscarabs now have 1.6 seconds of delay when firing guns, as much as an - unmodded kinetic accelerator. - - bugfix: Fixed Vitality Matrices and Raise Dead runes not reviving if the target - happened to be in their body already. - Kor: - - rscadd: Extended mode now has a special command report that tells you the round - type. This is to let people know they have time to start on large scale projects - rather than milling about waiting for antagonists to attack. - - rscadd: All station goals are now unlocked during extended. - Mysak0CZ: - - bugfix: MetaStation's xenobiology disposals now work properly - uraniummeltdown: - - tweak: Changed the Command and Security radio colors - - rscadd: Added raw telecrystals to the uplink, can be used with uplinks and uplink - implants. - - rscadd: Added 10mm ammo variants to uplink -2016-11-15: - Cyberboss: - - bugfix: Brains and heads with brains trigger the emergency stop on the recycler - Kor: - - rscadd: The vault is now home to a new machine which can accept cash deposits, - adding to the cargo point total. - - rscadd: You can also use this machine to steal credits from the cargo point total. - Doing so takes time, and will set off an alarm. - - rscadd: You can now buy an asteroid with engines strapped to it to replace the - emergency escape shuttle. - - rscadd: You can now buy a luxury shuttle to replace the emergency escape shuttle. - Each crewmember must bring 500 credits worth of cash or coins to board though. - Lexorion & Lzimann: - - tweak: Wizards have developed a new spell. It's called Arcane Barrage and it has - been reported that it has a similar function to Lesser Summon Guns! - Supermichael777: - - rscdel: The atmos grenades have been removed. if you want to burn down the shuttle - use canisters or something but at least work at it. - coiax: - - rscadd: Mice (the rodent, not the peripheral) now start in random locations. -2016-11-16: - Mysak0CZ: - - rscadd: Door can now have higher security, making them stronger and wires harder - to access - - rscadd: More info can be found on github or wiki (if this passes) - - imageadd: Protected wires now have sprites - Pubby: - - bugfix: cyclelinked airlock pairs now close behind you even when running through - at full speed. - Swindly: - - rscadd: Dice can now be rigged by microwaving them. -2016-11-18: - Cyberboss: - - bugfix: The amount of metal used to construct High Security airlocks with the - RCD is now consistent with the actual cost - Incoming5643: - - bugfix: The charge spell should once again work correctly with guns/wands - Joan: - - rscadd: Clockcult AIs have power as long as they are on a Clockwork Floor or next - to a Sigil of Transmission. This is in addition to having power under normal - conditions. - - rscadd: Clockcult silicons can now activate Clockwork Structures from a distance. - - rscdel: Interdiction Lenses will not disable cameras if there are no living unconverted - AIs. - - rscadd: Clockcult Cyborgs can charge from Sigils of Transmission by crossing them; - after a 5 second delay, the cyborg regains either their missing charge or the - amount of power in the sigil(whichever is lower) over 10 seconds. - - rscadd: You can now cancel out of selecting a robot module! - - imagedel: Robot modules now only have a generic transform animation when selected; - the borg is locked in place for 5 seconds in a small cloud of smoke while the - base borg sprite fades out and the new module fades in. - - tweak: Resetting a borg will do that animation. - - rscadd: Adds Networked Fibers, which gains points instead of automatic expansion - and causes manual expansion near its core to move its core. - - rscadd: Added a new UI style, Clockwork. - NikNak: - - rscadd: Added tator tots, made my putting a potato in the food processor - - tweak: French fries are now made by cutting up a potato into wedges and putting - the wedges (plate and all) into the food processor - coiax: - - bugfix: The observer visible countdown timer for the malfunctioning AI doomsday - device is now formatted and rounded appropriately. - erwgd: - - rscadd: You can now make emergency welding tools in the autolathe. -2016-11-19: - Crushtoe: - - imageadd: Added a shiny new icon for the reaper's scythe in-hand and normal sprite. - It's 25% less gardener. - RandomMarine: - - rscadd: An instruction paper has been added to the morgue on most maps, because - somehow it's needed. - Shadowlight213: - - rscadd: Added the AI integrity restorer as a modular computer program - - rscadd: Added an AI intelliCard slot. Insert an Intellicard into it to be able - to use the restoration program. - - bugfix: Fixes Alarm program detecting ruins - - bugfix: Fixes being unable to toggle the card reader module power - - tweak: The downloader will now tell you if a program is incompatible with your - hardware -2016-11-20: - Basilman: - - rscadd: Added a new beard style, Broken Man. - Cobby: - - tweak: Airlock security is only given to vault doors, centcomm, and Secure Tech - [Secure Tech just requires a welder] - Incoming5643: - - rscadd: The warp whistle has been added to the wizard's repertoire of spells and - artifacts. - - rscadd: The drop table for summon magic has been expanded. - Joan: - - rscdel: Servant cyborgs no longer have emagged modules. - - rscadd: Servant cyborgs now have a limited selection of scripture and tools, which - varies by cyborg type. - Kor: - - bugfix: Station goals will once again function in extended. - Swindly: - - rscadd: Added a nitrous oxide reagent. It can be created by heating 3 parts ammonia, - 1 part nitrogen, and 2 parts oxygen to 525K. The process produces water as a - by-product and will cause an explosion if too much heat is applied. -2016-11-21: - Cobby: - - tweak: mining/labor shuttles are now radiation proof. -2016-11-23: - Crushtoe: - - rscadd: Added more tips. - - bugfix: Fixes some sprites and spelling issues, namely bedsheet capes. - Cyberboss: - - bugfix: Changing an airlock's security level no longer heals it - Gun Hog: - - bugfix: Medibots now heal toxin damage again. - Joan: - - rscadd: Clockcult AIs can now listen to conversations through cameras. - - rscadd: Due to complaints that the new slab interface was too difficult to navigate, - it now starts off in compressed format. The button to toggle this is now also - larger. - Kor: - - rscadd: Rounds ending on one server will send a news report to the other server. - Shadowlight213: - - tweak: Borers now have a 10 second delay before waking up after sugar leaves the - host system - - tweak: There is a chance for borers to lose control, based on brain damage levels - Swindly: - - rscadd: Most small items can now be placed in the microwave. Remember not to microwave - metallic objects. - XDTM: - - rscadd: 'Golems now have special properties based on the mineral they''re made - of:' - - rscadd: Silver golems have a higher chance of stun when punching - - rscadd: Gold golems are faster but less armoured - - rscadd: Diamond golems are more armoured - - rscadd: Uranium golems are radioactive - - rscadd: Plasma golems explode on death - - rscadd: Iron and adamantine golems are unchanged. - jakeramsay007: - - tweak: Borers can no longer take control of people who have a mindshield implant - or are a member of either cult. This however does not stop them from infesting - and controlling them through other means, such as chemicals. -2016-11-24: - Kor: - - rscadd: Shaft miners now have access to the science channel. - Lzimann: - - rscdel: Multiverse sword is no longer buyable by wizards - erwgd: - - rscadd: Plasmamen get their own random names. -2016-11-25: - Joan: - - rscadd: Clockcult AIs with borgs 'slaved' to them will convert them when hacking - via the robotics console. - - experiment: Replaced the "No Cache" alert with an alert that will show what you - need for the next tier of scripture. - Kor: - - rscadd: The captain may now purchase an unfinished shuttle chassis, which will - dock immediately when bought, but will not launch until the end of the regular - shuttle call procedure. The shuttle is empty and devoid of atmosphere however, - so you'll need to do some work on it if you want a safe trip home. - Shadowlight213: - - bugfix: The activation button for the AI integrity restorer modular program actually - works now! - - rscdel: The cortical borer event is now admin only -2016-11-27: - Cyberboss: - - bugfix: False armblades are now removed after one minute. Start feeling the P - A R A N O I A when you see em - Gun Hog: - - rscadd: AIs piloting a mech may now be recovered with an Intellicard from the - wreckage if the mech is destroyed. They will be require repair once recovered. - - tweak: Instructions for piloting mechs as an AI are now more obvious. - - tweak: Traitor and Ratvar AIs may now be carded from mechs, at their discretion. - Joan: - - tweak: Clockwork walls are now about as hard for hulks to break as rwalls. - - rscadd: You can now quickbind up to 5 scriptures from the recital menu, and the - recital menu has less empty space. - - tweak: Clockwork slabs now only start with only Geis pre-bound. - Kor: - - rscadd: Shaft miners can now redeem their starting voucher for a conscription - kit, which contains everything they need to rope their friend into joining them - on lavaland. - - rscadd: You can now see which emergency shuttle is coming in the status panel. - Lzimann: - - rscadd: The robots stole Santa's Elfs jobs. - MMMiracles: - - tweak: Jump boots now have a pocket - - imageadd: Jump boots from mining now have on-character icons. - Mervill: - - imageadd: Disposal units now use a tgui instead of plain html - - rscadd: 'As the AI: Click an AI status display to bring up the prompt for changing - the image' - Swindly: - - rscadd: Wet leather can be dried by putting it on a drying rack. - Xhuis: - - bugfix: Plastic explosives now actually explode when you commit suicide with them. - - bugfix: Resisting out of straight jackets now works properly. - - rscdel: Highlander will no longer announce the last man standing. - - rscadd: Cyborgs can now open morgue trays. This does not include crematoriums! - uraniummeltdown: - - rscdel: Borers no longer randomly lose control based on host brain damage - - tweak: Borer Dominate Victim stun time reduced from 4 -> 2. - - tweak: Borers no longer force unhidden when infesting someone. - - tweak: Borer event is rarer (weight 20->15). - - tweak: Borer reproduction chemicals required increased from 100 to 200. -2016-11-29: - Joan: - - tweak: Interdiction Lenses are more likely to turn off if damaged. - - tweak: Reduced Interdiction Lens and Tinkerer's Daemon CV from 25 to 20. - RemieRichards: - - rscadd: Devils may now spawn with an obligation to accept dance off challanges, - if they have this obligation they also gain a spell to summon/unsummon a 3x3 - dance floor at will. - Swindly: - - rscadd: Microwaves now heat open reagent containers to 1000K. - XDTM: - - rscadd: 'Added new types of golem: glass, sand, wood, plasteel, titanium, plastitanium, - alien alloy, bananium, bluespace, each with their own traits. Experiment!' - - tweak: Golems will be told what their traits are when spawning. - - rscadd: Putting a golem in a gibber will give ores of its mineral type, instead - of meat. - - rscadd: Using Iron on an adamantine slime extract will spawn an incomplete golem - shell, that will be slaved to whoever completes it, much like a normal adamantine - golem. - jughu: - - tweak: Proselytizing airlocks into pinion airlocks takes longer. -2016-11-30: - ANGRY CODER: - - tweak: NT news reports the clandestine criminal organization known as the syndicate - may have upgraded one of their illegally stolen cyborg modules with additional - healing technology. - Cobby [Idea stolen from Shaps]: - - rscadd: For objects that you could previously rename with a pen, you can now edit - their description as well. - Cyberboss: - - rscdel: Due to budget cuts. Firelocks no longer have safety features - - bugfix: Roundstart airlock electronics now properly generate the correct accesses - - bugfix: tgui windows will now close on round end - Gun Hog: - - bugfix: Syndicate Medical Cyborg hyposprays now properly work through Operative - hardsuits and other thick clothing. - Joan: - - tweak: Cogscarabs will once again convert metal, rods, and plasteel directly to - alloy. - - tweak: Tinkerer's caches now increase in cost every 4 caches, from 5. - - rscadd: The Ark of the Clockwork Justicar now converts all silicons once it finishes - proselytizing the station. - Mervill: - - rscadd: AI hologram can move seamlessly between holopads - Thunder12345: - - rscadd: Added anti-armour launcher. A single-use rocket launcher capable of penetrating - all but the heaviest of armour. Deals massively increased damage to cyborgs - and mechs. -2016-12-02: - Cobby: - - bugfix: Removes the exploit that allowed you to bypass grabcooldowns with Ctrl+Click - PeopleAreStrange: - - tweak: Changed F7 to buildmode, F8 to Invismin (again). Removed stealthmin toggle - RemieRichards: - - rscadd: Added a new lavaland "boss" - - tweak: Hostile mobs will now find a new target if they failed to attack their - current one for 30 seconds, this reduces cheese by simply making the mob find - something else to do/someone to kill - - bugfix: Hostile mobs with search_objects will now regain that value after a certain - amount of time (per-mob, base 3 seconds), this is because being attacked causes - mobs with this var to turn it off, so they can run away, however it was literally - never turned on which caused swarmers to get depression and never do anything. -2016-12-03: - Joan: - - rscadd: Trying to move while bound by Geis will cause you to start resisting, - but the time required to resist is up by half a second. - - experiment: Resisting out of Geis now does damage to the binding, and as such - being stunned while bound will no longer totally reset your resist progress. - - rscadd: Using Geis on someone already bound by Geis will interrupt them resisting - out of it and will fully repair the binding. - - tweak: Geis's pre-binding channel now takes longer for each servant above 5. Geis's - conversion channel also takes slightly longer for each servant above 5. - - rscadd: Converted engineering and miner cyborgs can now create Sigils of Transgression. - RandomMarine: - - tweak: Airlocks will keep their original name when their electronics are removed - and replaced. You may still use a pen to rename the assembly if desired. -2016-12-04: - Durkel: - - tweak: Recent enemy reports indicate that changelings have grown bored with attacking - near desolate stations and have shifted focus to more fertile hunting grounds. -2016-12-06: - BASILMAN YOUR MAIN MAN: - - bugfix: fixes people "walking over the glass shard!" when they're on the ground, - changes message when incapacitated - Chnkr: - - rscadd: Nuclear Operatives can now customize the message broadcast to the station - when declaring war. - Cyberboss: - - bugfix: The atmos waste lines for the Metastation Kitchen and Botany departments - is now actually connected - Gun Hog: - - rscadd: Nanotrasen Janitorial Sciences Division is proud to announce a new concept - for the Advanced Mop prototype; It now includes a built-in condenser for self - re-hydration! See your local Scientist today! In the event that janitorial staff - wish to use more expensive solutions, the condenser may be shut off with a handy - handle switch! - Incoming5643: - - bugfix: The timer for shuttle calls/recalls now scales with the security level - of the station (Code Red/Green, etc.). You no longer have to feel dumb if you - forget to call Code Red before you call the shuttle! - - rscadd: Shuttles called in Code Green (the lowest level) now take 20 minutes to - arrive, but may be recalled for up to 10 minutes. They also don't require a - reason to be called. - - experiment: That doesn't mean you should call a code green shuttle every round - the moment it finishes refueling. - - rscadd: Server owners may now customize the population levels required to play - various modes. Keep in mind that this does not preserve the balance of the mode - if you change it drastically. See game_modes.txt for details. - Joan: - - rscadd: You can now proselytize floor tiles at a rate of 20 tiles to 1 brass sheet - or 2 tiles to 1 liquified alloy for cogscarabs. - - rscadd: Proselytizers will automatically pry up floor tiles if those tiles can - be proselytized. - - tweak: Brass floor tiles no longer exist. Instead, you can just apply brass sheets - to a tile. Crowbarring up a clockwork floor will yield that brass sheet. - - rscadd: You can now cancel AI intellicard wiping. - - tweak: Geis now takes 5 seconds to resist. - Mervill: - - bugfix: Examining now lists the neck slot - MisterTikva: - - rscadd: Nanotrasen informs that certain berry and root plants have been infused - with additional genetic traits. - - rscadd: Watermelons now have water in them! - - rscadd: Blumpkin's chlorine production has been reduced for better workplace efficiency. - - rscadd: Squishy plants now obey the laws of physics and will squash all over you - if fall on them. - Shadowlight213: - - bugfix: The lavaland syndicate agents, as well as the ID for all simple_animal - syndicate corpses should have their ID actually have syndicate access on it - now! - Swindly: - - rscadd: 'Adds a new toxin: Anacea. It metabolizes very slowly and quickly purges - medicines in the victim while dealing light toxin damage. Its recipe is 1 part - Haloperidol, 1 part Impedrezene, 1 part Radium.' - WJohn: - - bugfix: AI core turrets can once again hit you if you are standing in front of - the glass panes, or in the viewing area's doorway. - XDTM: - - rscadd: Quantum Pads are now buildable in R&D! - - rscadd: Quantum Pads, once built, can be linked to other Quantum Pads using a - multitool. Using a Pad who has been linked will teleport everything on the sending - pad to the linked pad! - - rscadd: 'Pads do not need to be linked in pairs: Pad A can lead to Pad B which - can lead to pad C.' - - rscadd: Upgrading a Quantum Pad will reduce the cooldown, charge-up time, and - power consumption. - - rscadd: Quantum Pads require a bluespace crystal, a micro manipulator, a capacitor - and a cable piece. - kilkun: - - rscadd: New lore surrounding the various SWAT suits. - - tweak: Captain's hardsuit/SWAT suit got a few buffs. It's now much more robust. - - bugfix: Captain's space suit is now heat proof as well as fireproof. Long overlooked - no longer. -2016-12-07: - Cyberboss: - - bugfix: Atmos canisters now stay connected after relabeling them - Incoming5643: - - rscadd: Server owners that use the panic bunker feature can now optionally redirect - new players to a different server. See config.txt for details. - LOOT DUDE: - - tweak: Swarmers will drop bluespace crystals on death, non-artificial crystals. - MisterTikva: - - rscadd: Nanotrasen Mushroom Studies Division proudly announces that growth serum - producing plants were genetically reassembled. You no longer alternate between - sizes with doses 20u+ and more effects were added to higher doses. - Thunder12345: - - bugfix: You can now only order a replacement shuttle once -2016-12-08: - Fox McCloud: - - rscadd: The ability to harvest a plant, repeatedly, is now a gene-extractable - trait that can be spliced into other plants - - rscadd: can extract the battery capabilities of potatoes and splice them into - other plants - - rscadd: Plants types are now gene traits that can be added/removed from plants - - rscadd: Adds new stinging plant trait that will inject a bit of a plant's reagents - when thrown at someone - Joan: - - rscadd: The clockwork slab's interface is now TGUI. - - imageadd: You can now see what an ocular warden is attacking. - Mervill: - - rscadd: The light replacer can now create bulbs from glass shards - - rscadd: Click a light replacer while holding a glass shard to add the shard to - the replacer - - rscadd: Click a glass shard while holding a light replacer to consume the shard - MrStonedOne: - - tweak: world initialization is now faster. - - bugfix: fixed the modify bodypart admin tool not working - PKPenguin321: - - tweak: Swarmer beacons now have 750 health, down from 3000. - TehZombehz: - - rscadd: Nanotrasen Culinary Division has authorized the production of tacos, both - plain and classic. - XDTM: - - bugfix: Replica Pod cloning now works on people who have been decapitated. - coiax: - - rscadd: Additional mice sometimes appear in the maintenance tunnels. Engineers - beware! -2016-12-10: - Cyberboss: - - bugfix: The slips bug (which made freon laggy) is fixed - Kor: - - imagedel: Deleted all (3000+) left handed inhand icons. They are now automatically - mirrored from the right hand, saving spriters a lot of tedious busywork. - - rscadd: By crafting a wall mounted flasher frame (can be ordered via cargo), a - flash, and a riot shield, you can now construct a strobe shield. The strobe - shield combines the functionality of a riot shield and a flash, and can be reloaded - with flash bulbs. - Supermichael777: - - tweak: Conveyors have been more firmly anchored. No fun allowed - Thunder12345: - - rscadd: Added the Standby Emergency Vessel "Scrapheap Challenge" as a new emergency - shuttle option. You'll even be paid 1000 credits to use it! - coiax: - - rscadd: Due to a combination of radiation and water supply contamination, stations - have been reporting animals gaining self awareness. - optional name here: - - bugfix: fixed ashdrake's flame wall. - - bugfix: fixed walls decon spawning metal in a random location in the same room. -2016-12-11: - Cobby: - - bugfix: Fixes literally everything regarding renaming so far. When adding unique_rename - to objects, make sure the attackby checks for inheritance. - - bugfix: You can pull as other mobs now. Sorry, clickcode is stupid. - Cyberboss: - - bugfix: Frozen things will now unfreeze above 0C - Joan: - - tweak: Invoking Nezbere now increases ocular warden damage slightly more, but - increases ocular warden range slightly less. - Swindly: - - tweak: The recipe for moonshine now calls for 5 units of nutriment and 5 units - of sugar instead of 10 units of nutriment. - Thunder12345: - - bugfix: Scrapheap Challenge shuttle now actually works - coiax: - - rscadd: Cyborgs now have a reset module wire, that when pulsed, triggers the cyborg's - reset module hardware. - - rscadd: Cyborgs now eject all upgrades when reset, rather than the upgrades being - destroyed. - - rscdel: Removed redundant reset module. -2016-12-12: - Dannno: - - rscadd: more chaplain outfits - - rscadd: animal and tribal masks to the theater vendor -2016-12-13: - Fox McCloud: - - rscadd: Adds in random botany seeds; never the same twice. - - rscadd: Adds in new trait that makes a grown release smoke when squashed - - rscadd: Weed rates and chances are now core seed genes - Joan: - - experiment: Clockwork proselytizers suffer doubled cost and proselytization time - when not on the station, mining, or centcom. - - soundadd: Trying to recite scripture offstation is more clearly disapproved of. - XDTM: - - bugfix: The internal rage of the crew has been suppressed, and they will no longer - attack their own backpacks when opening them. -2016-12-14: - Incoming5643: - - rscadd: Recently we've been receiving reports of cheap knock off nuclear authentication - disks circulating among the syndicate network. Don't be fooled by these decoys, - only the real deal can be used to destroy the station! - - experiment: Please don't destroy the station in an attempt to make sure the disk - is real. - Joan: - - rscdel: The Ark of the Clockwork Justicar can no longer be repaired. - - tweak: The Ark now has 20% more health. - - rscadd: The Ark of the Clockwork Justicar will now force objects away from it. - - tweak: Faster-than-normal tools are somewhat slower than before. - - tweak: Mania Motors now require a much larger amount of power to convert people - adjacent, and people converted by it are knocked out. - Mindustry: - - bugfix: Goliath meat can be cooked in lava again - Okand37: - - rscadd: DeltaStation's emergency shuttle - XDTM: - - rscadd: Abductor Agents have now been equipped with extremely advanced construction - and hacking tools. -2016-12-18: - Dannno: - - rscadd: Sec hailers can now be emagged for a more rational, calm message. - Erwgd: - - rscadd: Limb Grower circuit boards can now be made in Research and Development, - requiring level 3 in data theory and level 2 in biological technology. - Firecage: - - rscadd: The NanoTrasen Airlock Builder Federation(NTABF) has recently released - the blueprints involving building and deconstructing Titanium Airlocks! These - airlocks are now being used on all of our shuttles. - Fox McCloud: - - bugfix: Fixes the personal crafting cost of ED-209's being too expensive - Hyena: - - tweak: adds 2 geiger counters to radition protection crates and a gift from the - russians - Joan: - - rscadd: Adds Replicant and Tinkerer's Cache to the default slab quickbind. - - rscadd: Revenants will be revealed by ocular wardens when targeted. - Joan, Dagdammit: - - rscadd: You can now push Wraith Spectacles up to avoid vision damage, but lose - xray vision. - - wip: Do note that flicking them on and off very quickly may cause you to lose - vision rather quickly. - Kor: - - rscadd: Added the treasure hunter's hat, coat, uniform, and whip. These aren't - available on the map yet, but will be available to the librarian soon. - Mervill: - - rscadd: Notice boards can now have photographs pined to them - - tweak: Items removed from the notice board are placed in your hands - - bugfix: Intents can be cycled forward and backwards with hotkeys again - - bugfix: Russian revolver ammo display works correctly - - rscadd: Added a credit deposit to pubbystation's vault - - rscdel: Removed a rather garish golden statue of the HoP from pubbystation's vault - Okand37 & Lexorion: - - rscadd: Added a new hair style, the Sidecut! - Supermichael777: - - rscadd: Clockwork components the chaplain picks up are now destroyed. - Swindly: - - rscadd: Adds eggnog. It can be made by mixing 5 parts rum, 5 parts cream, and - 5 parts egg yolk. - XDTM: - - rscadd: Changelings can now buy Tentacles on the Cellular emporium for 2 evolution - points. - - rscadd: Tentacles, once used, can be fired once against an item or mob to pull - it towards yourself. Items will be automatically grabbed. Costs 10 chemicals - per tentacle. - - rscadd: 'On humanoid mobs tentacles have a varying effect depending on intent: - - Help intent simply pulls the target closer without harming him; - Disarm intent - does not pull the target but instead pulls whatever item he''s holding in his - hands to yours; - Grab intent puts the target into an aggressive grab after - it is pulled, allowing you to throw it or try to consume it; - Harm intent will - briefly stun the target on landing; if you''re holding a sharp weapon you''ll - also impale the target, dealing increased damage and a longer stun.' - - bugfix: Random golems now properly acquire the properties of the golem they pick. - - rscadd: When becoming a random golem the user is informed of the properties of - the picked golem. - coiax: - - rscadd: Chameleon clothing produced by the syndicate has been found to react negatively - to EMPs, randomly switching forms for a time. - - rscadd: Anomalies now have observer-visible countdowns to their detonation. - - rscadd: Adds upgrades for the medical cyborg! - - rscadd: The Hypospray Expanded Synthesiser that adds chemicals to treat blindness, - deafness, brain damage, genetic corruption and drug abuse. - - rscadd: The Hypospray High-Strength Synthesiser, containing stronger versions - of drugs to treat brute, burn, oxyloss and toxic damage. - - rscadd: The Piercing Hypospray (also applicable to the Standard and Peacekeeper - borgs) that allows a hypospray to pierce thick clothing and hardsuits. - - rscadd: The Defibrillator, giving the medical cyborg an onboard defibrillator. - - rscadd: Loose atmospherics pipes are now dangerous to be hit by. - - rscadd: Whenever you automatically pick up ore with an ore satchel, if you are - dragging a wooden ore box, the satchel automatically empties into the box. - dannno: - - rscadd: Adds a villain costume to the autodrobe. - - bugfix: Fixes autodrobe failing to stock items. - jughu: - - tweak: 'sandals are not fireproof or acidproof anymore :add: Magical sandals for - the wizard that are still fireproof/acid proof :tweak: makes the marisa boots - acid and fire proof too' - karlnp: - - bugfix: made facehuggers work again - - bugfix: vendors, airlocks, etc now cannot shock at a distance - uraniummeltdown: - - tweak: Side entrance to Box Medbay, a few layout changes. -2016-12-19: - spudboy: - - bugfix: Fixed items not appearing in the detective's fedora. -2016-12-20: - Kor: - - rscadd: You can put a variety of hats on cyborgs using help intent (the engiborg - can't wear hats though, as it is shaped too oddly. Sorry!) - - rscadd: 'The complete list of currently equippable hats is as follows: Cakehat, - Captains Hat, Centcomm Hat, Witch Hunter Hat, HoS Cap, HoP Cap, Sombrero, Wizard - Hat, Nurse Hat.' - Lzimann: - - bugfix: Mjor the Creative will drop his loot correctly now. - Mekhi Anderson: - - rscdel: Fixes various PAI bugs, various tweaks and bullshit. - MrPerson: - - rscadd: Starlight will have more of a gradient and generally shine a more constant - amount of light regardless of how many tiles are touching space. In dark places - with long borders to space, starlight will be much darker. -2016-12-21: - FTL13, yogstation, Iamgoofball, and MrStonedOne: - - rscadd: Space is pretty. - - tweak: You can configure how pretty space is in preferences, those of you on toasters - should go to low to remove the need to do client side animations. (standard - fanfare as job selection, left click to increase, right click to decrease) (Changes - are applied immediately in most cases, on reconnect otherwise) - Joan: - - rscadd: EMPs will generally fuck up clockwork structures. - - rscdel: Cogscarabs can no longer hold slabs to produce components. - - rscadd: Slabs will now produce components even if in a box in your backpack inside - of a bag of holding on your back; any depth you can hide the slab in will still - produce components. - - bugfix: Non-Servants in possession of clockwork slabs will also no longer produce - components. - Mekhi Anderson: - - bugfix: PAI notifications no longer flood those who do not wish to be flooded. - Shadowlight213: - - imageadd: 2 new performer's outfits have been added to the autodrobe -2016-12-24: - AnturK: - - rscadd: Implants now work on animals. - Cyberboss: - - bugfix: Dead things can no longer be used to open doors - F-OS: - - bugfix: swarmers can no longer destroy airlocks. - MrStonedOne: - - tweak: AI's call bot command has been throttled to prevent edge cases causing - lag. You will not be able to call another bot until the first bot has finished - mapping out it's route. - TehZombehz: - - tweak: Observers can now orbit derelict station drone shells, much like current - lavaland ghost role spawners, to make finding them easier. Regular drone shells - are not affected by this. - XDTM: - - rscadd: Autolathes are now true to their name and can queue 5 or 10 copies of - the same item. - coiax: - - rscadd: Cyborg renaming boards cannot be used if no name has been entered. - - rscdel: Cyborg rename and emergency reboot modules are destroyed upon use, and - not stored inside the cyborg to be ejected if modules are reset. - - rscadd: Emagging the book management console and printing forbidden lore now has - a chance of producing a clockwork slab rather than an arcane tome. - kevinz000: - - experiment: Flightsuits now have their own subsystem! - - bugfix: Flightsuits properly account for power before calculating drifting - - experiment: Flightpack users will automatically fly over anyone buckled without - crashing. - - experiment: Flightpack users automatically slip through mineral doors - - experiment: Flightpack users will crash straight through grills at appropriate - times - - experiment: Flightpack users automatically slip through unbolted airlocks - - experiment: Flightpacks are faster in space, but their space momentum decay has - been upped significantly to compensate - - experiment: Flighthelmets now have a function to allow the wearer to zoom out - to see further. Helps you not crash eh? - spudboy: - - bugfix: Gave cyborgs some hotkeys they should have had. -2016-12-27: - Firecage: - - bugfix: The Nanotrasen Sewing Club has finally fixed the problem which rendered - NT, Ian, and Grey bedsheets invisible when worn! - Hyena: - - tweak: Detective coats can now hold police batons - - bugfix: Fixes disabler in hand sprites - Joan: - - rscadd: You can now put syndicate MMIs and soul vessels into AI cores. - - rscadd: The Hierophant boss will now create an arena if you try to leave its arena. - - imageadd: The Hierophant boss, its arena, and the weapon it drops all have new - sprites. - - soundadd: And new sounds. - - wip: And new text. - - rscadd: Wizards can now buy magic guardians for 2 points. They are not limited - to one guardian, meaning they can have up to 5. If that's wise is an entirely - different question. - - experiment: Wizards cannot buy support guardians, but can buy dexterous guardians, - which can hold items. - Shadowlight213: - - tweak: Shuttle are now safe from radstorms - XDTM: - - bugfix: HUD implants now properly allow you to modify the records of those you - examine, like HUD glasses do. - - bugfix: Organ Manipulation surgery now properly heals on the cautery step. - - bugfix: The maintenance door adjacent to R&D in metastation is now accessible - to scientists, instead of requiring both science and robotics access. -2016-12-28: - Erwgd: - - rscadd: A new access level is available, named "Cloning Room". Medical Doctors, - Geneticists and CMOs start with it. - - tweak: On Box Station and on Meta Station, the cloning lab doors require Cloning - Room access in addition to each door's previous requirements. - - tweak: Cloning pods are now unlocked with Cloning Room access only. - Incoming5643: - - rscadd: There's a new category in uplinks for discounted gear. These special discounts - however can only be taken once, so even if you are lucky enough to see syndibombs - for 75% off you won't be able to nuke the entire station with them. - - bugfix: The charge spell will no longer bilk you on wand charges, and wands that - are dead won't show up as charged. - Joan: - - rscdel: Clockwork Marauders no longer have Fatigue. It was difficult to balance - and made them too easy to force into recalling. This means they just have health; - they aren't forced to recall by anything, but can accordingly die much more - easily. - - rscadd: Accordingly Clockwork Marauders now have more health, do slightly more - damage, block slightly more often, and have to go slightly further from their - host to take damage. - - rscadd: Marauders that are not recovering(from recalling while the host's health - is too high to emerge) and are inside their host, or are within a tile of their - host, will gradually heal their host until their host is above the health threshold - to emerge. - - tweak: Chaos guardians transfer slightly less damage to their summoner. - XDTM: - - tweak: Armblades now go slash slash instead of thwack thwack - - imageadd: Tentacles have some fancier sprites -2016-12-29: - Mervill: - - bugfix: Patched an exploit related to pulling a vehicle as its driver while in - space - - bugfix: Fixed evidence bags not displaying their contents when held - - bugfix: Clothing without a casual variant will no longer say it can be worn differently - when examined - - bugfix: Only standard handcuffs can be used to make chained shoes - - bugfix: Fixed cards against space - - bugfix: Drying rack sprite updates properly when things are removed without drying - XDTM: - - rscadd: Colossi now drop the Voice of God, a mouth organ that, if implanted, allows - you to speak in a HEAVY TONE. This voice can compel hearers to briefly obey - certain codewords, such as "STOP". Using these codewords will severely increase - this ability's cooldown, and only one will be used per sentence. - - rscadd: 'Use .x, :x, or #x as a prefix to use Voice of God or any future vocal - cord organs.' - - rscadd: Chaplains, being closer to the gods, and command staff, being used to - giving orders, gain an increased effect when using the Voice of God. The mime, - not being used to speaking, has a reduced effect. -2016-12-31: - hyena: - - bugfix: fixes caps suit fire immunity - kevinz000: - - bugfix: Machine overloads/overrides aren't as bullshit as you'll actually be able - to dodge it now. -2017-01-01: - A whole bunch of spiders in a SWAT suit: - - bugfix: spiders can't wrap anchored things -2017-01-02: - MrStonedOne: - - tweak: Throwing was refactored to cause less lag and be more precise - - rscadd: Item throwing now imparts the momentum of the user throwing. Throwing - in the direction you are moving throws the item faster, throwing away from the - direction you are moving throws the item slower. This should make hitting yourself - with floor tiles less likely. - XDTM: - - bugfix: Storage bags should now cause less lag when picking up large amounts of - items. - - bugfix: Storage bags now don't send an error message for every single item they - fail to pick up. -2017-01-03: - Cyberboss: - - bugfix: AIs can no longer see cult runes properly - Mervill: - - bugfix: Can't kick racks if weakened, resting or lying -2017-01-06: - Cruix: - - bugfix: Fixed the leftmost and bottommost 15 turfs not having static for AIs and - camera consoles - Joan: - - bugfix: Tesla coils and grounding rods must be anchored with a closed panel to - function, ie; not explode when shocked. - - tweak: Metastation's xenobio has been slightly modified to avoid getting hit by - some standard shuttles. - Mervill: - - bugfix: Regular spraycans aren't silent anymore - MrStonedOne and Ter13: - - rscadd: Added some ping tracking to the game. - - rscadd: Your ping shows in the status tab - - rscadd: Other players ping shows in who to players and admins. - Nabski89: - - bugfix: Re-Vitiligo Levels to match wiki. - XDTM: - - tweak: Voice of God's Sleep lasts less than the other stuns. - - rscadd: You can also use people's jobs to single them out, instead of only names. - - tweak: If multiple people share the same name/job they'll all be included, although - at a reduced bonus. - - tweak: Names and jobs will only be accepted if they're the first part of the command, - and not in the middle, to prevent unintended focusing. - - bugfix: Voice of God now shows speech before the emotes it causes. - - bugfix: Special characters are no longer over-sanitized. - - bugfix: You can now properly apply items to clothing with pockets, such as slime - speed potions on clown shoes. - - bugfix: Mechs are now able to enter wormhole-sized portals. -2017-01-08: - Mervill: - - bugfix: pre-placed posters don't retain their pixel offset when taken down carefully - - bugfix: Dinnerware Vendor will show it's wire panel - Nanotrasen Station Project Advisory Board: - - wip: It is highly recommended that, when constructing the Meteor Shield project, - you are able to see, at minimum, two meteor shields from a stationary location. - The Nanotrasen Station Project Advisory Board is not liable for meteor damage - taken under wider shield arrangements. - Speed of Light Somehow Changed: - - tweak: Dynamic lights are no longer animated, and update instantly - - tweak: Increased maximum radius of mob and mobile lights -2017-01-10: - Arianya: - - bugfix: Doors and vending machines once again make a sound when you screwdriver - them. - Cyberboss: - - bugfix: Explosions can no longer be dodged - - tweak: Airlocks are now destroyed by the same level explosion that destroys walls - - tweak: Diamond/External/Centcomm airlocks and firedoors now block explosions as - walls do - Joan: - - experiment: Clockwork Proselytizers no longer require Replicant Alloy to function; - instead, they gradually charge themselves with power, which is used more or - less the same as alloy. - - tweak: Clockwork Proselytizers now produce brass sheets when used in-hand, instead - of Replicant Alloy. - - rscdel: Tinkerer's Caches can no longer have Replicant Alloy removed from them; - using an empty hand on them will simply check when they'll next produce a component. - - rscdel: Mending Motors can no longer use Replicant Alloy in place of power. - Mervill: - - bugfix: Controlling the station status displays no longer overrides the cargo - supply timer - MrStonedOne: - - experiment: Lighting was made more responsive. - XDTM: - - rscadd: Earmuffs and null rods protect against the Voice of God. - - rscadd: Earmuffs are now buildable in autolathes. - - tweak: Voice of God stuns have a longer cooldown. - coiax: - - rscadd: Girders now offer hints to their deconstruction when examined. -2017-01-13: - Cyberboss: - - bugfix: Walls blow up less stupidly - - bugfix: You no longer drop a beaker after attempting to load it into an already - full cryo cell - Joan: - - bugfix: Instant Summons is no longer greedy with containers. - Mervill: - - bugfix: Hardsuits, amour and other suits that cover the feet now protect against - glass shards - - bugfix: You will now lose the lawyer's speech bubble effect if you unequip the - layer's badge - MrStonedOne: - - tweak: More performance tweaks with the modulated reactive ensured entropy frame - governor system - PKPenguin321: - - tweak: Ash walker tendrils will now restore 5% of their HP when fed. - Shadowlight213: - - bugfix: Borg emotes should now play at the correct pitch - - bugfix: The ID console now properly handles authorization - - bugfix: Clicking on one of the ID cards in the UI will no longer eject both of - them - Thunder12345: - - bugfix: Morphs will no longer retain the colour of the last thing mimicked when - reverting to their true form - XDTM: - - bugfix: Patches' application is now properly delayed instead of instant. - - bugfix: Accelerator laser cannons' projectile now properly grows with distance. - coiax: - - rscadd: The end of round stats include the number of people who escaped on the - main emergency shuttle. -2017-01-14: - Cyberboss: - - bugfix: Explosions now flash people properly - Lzimann: - - bugfix: Fixes TGUI not working for people without IE11 - Thunder12345: - - bugfix: Recoloured mobs and objects will no longer produce coloured fire. - XDTM: - - bugfix: Nanotrasen decided that the "violent osmosis" method for refilling fire - extinguishers was, while cathartic, too expensive, due to the water tank repair - bills. Water tanks now have a tap. - - bugfix: (refilling extinguishers from tanks won't make you hit them) - - bugfix: Golems no longer drop belt, id, and pocket contents in a fit of extreme - clumsiness when drawing a sword from a sheath. - - bugfix: Wrenching portable chem dispensers won't cause you to immediately try - unwrenching them. - coiax: - - bugfix: Blue circuit floors are now restored to their normal colour if an AI doomsday - device is disabled. -2017-01-16: - Cyberboss: - - bugfix: Firedoors no longer have maintenance panels - - tweak: Firedoors must now be welded and screwdrivered prior to be deconstructed - Joan: - - rscadd: Ratvar will now convert lattices and catwalks to clockwork versions. - XDTM: - - tweak: Updating your PDA info with an agent id card inside will also overwrite - the previous name. - - bugfix: Loading a xenobiology console with a bio bag won't cause you to smack - it with it. - - tweak: Chemical splashing is now based on distance rather than affected tiles. - - bugfix: You can now properly wet floors by putting enough water in a grenade. - - bugfix: Floating without gravity won't drain hunger. -2017-01-18: - Mervill: - - bugfix: Using a welder to repair a mining drone now follows standard behaviour - - bugfix: Redeeming the mining voucher for a mining drone now also provides welding - goggles - - bugfix: ntnrc channels are now deleted properly - Tofa01: - - bugfix: Moved all sprites for heat pipe manifold either up or down by one so that - they will line up correctly when connected to adjacent pipes. - uraniummeltdown: - - rscadd: More AI holograms! -2017-01-19: - Cyberboss: - - bugfix: Various abstract entities will no longer be affected by spacewind - - bugfix: Ash will, once again, burn in lava - - rscadd: Active testmerges of PRs will now be shown in the MOTD - - bugfix: You will no longer appear to bleed while bandaged - Joan: - - spellcheck: Clockwork airlocks now have more explicit deconstruction messages, - using the same syntax as rwall deconstruction. - Mervill: - - bugfix: Raw Telecrystals won't appear in the Traitor's purchase log at the end - of the round - MrStonedOne: - - bugfix: Fixed excessive and immersion ruining delay on the smoothing of asteroid/mining - rock after a neighboring rock turf was mined up. - XDTM: - - bugfix: Plasmamen that are set on fire by reacting with oxygen will burn even - if they have protective clothing. It will still protect from external fire sources. - - tweak: Atmos-sealing clothing, like hardsuits, will protect plasmamen from reacting - with the atmosphere. - - tweak: Plasmamen can survive up to 1 mole of oxygen before burning, instead of - burning with any hint of oxygen. - - bugfix: Nanotrasen no longer ships self-glueing posters. You'll have to finish - placing the posters to ensure they don't fall on the ground. - - bugfix: Exosuits can't push anchored mobs, such as megafauna or tendrils, anymore. - coiax: - - bugfix: AIs can no longer activate the Doomsday Device off-station. Previously - it would activate and then immediately turn off, outing the AI as a traitor - without any benefit. -2017-01-20: - CoreOverload: - - tweak: Any sharp item can now be used for "incise" surgery step, with 30% success - probability. - Joan: - - rscadd: Sentinel's Compromise will also convert oxygen damage into half toxin, - in addition to brute and burn. - - tweak: Reduced the Ark of the Clockwork Justicar's health from 600 to 500 - - rscadd: You can now pull objects past the Ark of the Clockwork Justicar without - them being moved and or destroyed by its power. - MrStonedOne: - - tweak: Server side timing of the parallax shuttle launch animation now runs on - client time rather than byond time/server time. This will fix the odd issues - it has during lag. The parallax shuttle slowdown animation will still have issues, - those will be fixed in another more involved update to shuttles. - - rscadd: The window will flash in the taskbar when a new round is ready and about - to start. - Tofa01: - - bugfix: Moved The CentComm station 6 tiles to the left in order to prevent large - shuttles such as "asteroid with engines on it" from clipping off the end of - the right side of the map. - XDTM: - - bugfix: Chameleon PDAs can now morph into assistant PDAs. - - bugfix: A few iconless items have been blacklisted from chameleon clothing. - - tweak: Reviver implants now warn you when they're turning on or off, or when giving - a heart attack due to EMP. -2017-01-22: - ChemicalRascal: - - tweak: Voice analyzers in "inclusive" mode (the default mode) are now case-insensitive. - Cyberboss: - - tweak: You can no longer meatspike bots and silicons - - bugfix: Secbots will now drop the baton type they were constructed with - Dannno: - - rscadd: yeehaw.ogg is now a round end sound - Fox McCloud: - - tweak: drying meat slabs and grapes now yields a healthy non-junkfood snack - Hyena: - - rscadd: Adds paint remover to the janitors closet - Joan: - - rscadd: Clockwork Proselytizers can now convert lattices and catwalks. This has - negative gameplay benefit, but looks cool. - - rscadd: Sigils of Transmission can be accessed by clockwork structures in a larger - range. - - tweak: You can see, when examining a clockwork structure, how many sigils are - in range of it. - - rscadd: Clockwork constructs will toggle clockwork structures instead of attacking - them. - Shadowlight213: - - bugfix: Zombies will now get their claws upon zombification - Thunder12345: - - rscadd: The indestructible walls on CentComm will now smooth. - Tofa01: - - tweak: Changed alert message on early launch Authorization shuttle repeal message. - - bugfix: Makes the repeal message work and push a alert to the crew properly, also - reports every Authorization repeal now. - - bugfix: Auto Capitalisation will now work with all types of MMI chat - Ultimate-Chimera: - - rscadd: Adds a new costume crate to the cargo ordering console. - XDTM: - - rscadd: Xenobiology consoles are now buildable from circuitboards in R&D. They'll - be limited to the area they're built in plus any area with the same name. - - rscadd: Stock Exchange computers are now also buildable this way. - - rscadd: Androids now speak in a more robotic tone of voice. - - imageadd: Armblades now look a bit more bladelike. - coiax: - - rscadd: The Delta emergency shuttle now travels towards the south, rather than - the north. This changes nothing except which direction the stars rushing past - the windows are moving. - - bugfix: Fixed dragging the spawn protection traps on CTF. -2017-01-24: - CoreOverload: - - rscadd: You can now buckle handcuffed people to singularity/tesla generators, - RTGs, tesla coils and grounding rods. - Cyberboss: - - tweak: Firealarms now go off if it's too cold - - bugfix: World start will no longer lag - - bugfix: Dismembered heads will now use a mob's real name - Joan: - - rscadd: Clockwork Slabs can now focus on a specific component type to produce. - - experiment: 'Redesigned: Volt Void now allows you to fire up to 5 energy rays - at targets in view; each ray does 25 laser damage to non-Servants in the target - tile. The ray will consume power to do up to double damage, however.' - - wip: Failing to fire a Volt Void ray will damage you, though you won't die from - it unless you have access to a lot of power and are either low on health or - fail all five rays in a row. - - rscadd: The Ark of the Clockwork Justicar will gradually convert objects near - it with increasing range as it gets closer to activating. - - tweak: 'Brass windows have 20% less health, and are accordingly easier to destroy. - Fun fact: Lasers do more damage to brass windows!' - - tweak: 'Wall gears have 33% less health and are slightly faster to deconstruct. - Fun fact: You can climb over wall gears!' - - tweak: Marauders will heal more of their host's damage, on average, per life tick. - - rscadd: Clockwork Proselytizers can now repair Servant silicons and clockwork - mobs. This works in the same manner as repairing clockwork structures. - - tweak: Cogscarabs work slightly differently, and act as though the proselytizer - is a screwdriver. - Kor: - - rscadd: Megafauna will not heal while on the station. Do not be afraid to throw - your life away to get in a few toolbox hits. - Shadowlight213: - - rscdel: PAIs can no longer ventcrawl - Tofa01: - - rscadd: '[Delta Station] Adds a tracking beacon to AI MiniSat Exterior Hallway' - coiax: - - rscdel: Statues are now just incredibly tough mobs, rather than GODMODE. As a - side effect, they are no longer immune to bolts of change. - - bugfix: Fixed some issues with X (as Y) names on polymorphed mobs. -2017-01-26: - Robustin: - - tweak: Unholy Water can now be thrown or vaporized to deliver a powerful poison - unto the cult's enemies - or healing and stun resistance to its acolytes. - Tofa01: - - tweak: Moved Meta station AI MiniSat tracking beacon to AI MiniSat entrance. Should - prevent being regular teleported into space. - - bugfix: Added missing row of pixels to Flypeople torso so head connects to body - properly. - Tofa01 & XDTM: - - rscadd: Adds radio alert messages going to medical channel to the cryo tube when - a patient is fully restored. - - soundadd: Adds new alert sound for cryo tube. (cryo_warning.ogg) - XDTM: - - rscadd: Voice of God has received a few more commands. - - rscadd: You can now use job abbreviations (ex. hos > head of security) and first - names (ex. Duke > Duke Hayka) to focus targets. - coiax: - - rscadd: The nuclear operative cybernetic implant bundle now actually contains - implants. - - rscdel: The cybernetic implant bundle is no longer eligible for discounts (bundles - are, in general, not eligible). - - rscadd: Telecrystals can be purchased in stacks of five and twenty. - - rscadd: The entire stack of telecrystals are added to the uplink when charging - them. -2017-01-27: - Joan: - - tweak: Buckshot now does a maximum of 75 damage, from 90. - - tweak: The unique cyborg scriptures(Linked Vanguard, Judicial Marker) take 3 seconds - to invoke, from 4. - - tweak: Invoking Inath-neq and Invoking Nzcrentr now both take 10 seconds to invoke, - from 15. - Lzimann: - - rscadd: Now you can choose what department you want to be as security! (This may - not be completly reliable). - RemieRichards: - - rscadd: 'Emagging a sleeper now randomises the buttons, the buttons remain the - same until randomised again so you can "learn" the new button config if you''re - a masochist, Inject omnizine but realise far too late that it''s all morphine, - woops! (Note: Epinephrine can always be injected, regardless of chem levels, - this means if something !!FUN!! ends up on the Epinephrine button, it will always - be injectable!)' - Sweaterkittens: - - tweak: There are now updated names and descriptions for the items that your plasma-based - crewmembers start with and use frequently. -2017-01-28: - Joan: - - tweak: Brass windows no longer start off anchored, but are constructed instantly. - - bugfix: You can no longer stack multiple windows of the same direction on a tile. - - rscadd: Vitality Matrices now share vitality globally, allowing you to use vitality - gained from any Matrix. - - tweak: Geis now mutes human targets if there are less than 6 Servants. - - tweak: Geis no longer produces resist messages below 6 Servants; this isn't a - change, as Geis cannot be successfully resisted below 6 Servants. - - tweak: Applying Geis to an already bound target will also mute them, in addition - to preventing resistance. - RemieRichards: - - rscadd: A New weapon for clown mechs, the Oingo Boingo Punch-face! it's a giant - boxing glove that extends out on a spring and sends atoms flying (including - anchored ones and things that make no sense to move because -clowns-) - Tofa01: - - bugfix: Mop will no longer try and clean tile under janitorial cart when wetting - the mop. - - rscadd: Adds modular computers to Metastation. - - bugfix: Fixes no air in Deltastation maintenance kitchen. - - rscadd: Adds a modular computer to the CE office on Pubbystation. - Xhuis: - - rscadd: Energy-based weapons can now light cigarettes. - coiax: - - rscadd: Communication consoles now share cooldowns on announcements. - - rscadd: Cyborgs can now alter the messages of the announcement system. - - bugfix: Deadchat is now notified of any deaths on the shuttle or on Centcom. The - CTF arena does not generate death messages, due to the high levels of death. - - rscadd: The Human-level Intelligence event now occurs slightly more often, and - produces a classified message. - kevinz000: - - rscadd: Emitters and Tesla Coils now have activation wires! - - rscadd: Emitters will shoot out an emitter bolt when pulsed, regardless of it - is on. - - rscadd: Tesla coils will shoot lightning when pulsed, if it is connected to a - cable that has power. - - bugfix: Bolas no longer restrain your hands for 10 seconds when you try to remove - them and fail. -2017-01-29: - BASILMAN YOUR MAIN MAN: - - rscadd: Added a new sailor outfit to the autodrobe, now you can play sailors vs - pirates. - BlakHoleSun: - - rscadd: Added new reaction with the rainbow slime extract. Injecting a rainbow - slime extract with 5u of holy water and 5u of uranium gives you a flight potion. - Cobby: - - tweak: AI's can now be your banker by manipulating the stock machine. - Cyberboss: - - experiment: Nuclear bombs now detonate - - rscadd: You can now link additional cloning pods in the same powered area to a - single computer using a multitool. - Fox McCloud: - - bugfix: Fixes Kudzu seed gene stats not being properly altered by certain reagents - - bugfix: Fixes Kudzu vine dropped seeds not properly having gene stats set - - bugfix: Fixes glowshrooms having an invalidly high lifespan - - bugfix: Fixes explosive vines not properly chaining - Joan: - - rscadd: Clockwork Marauders now grant their host action buttons to force them - to emerge/recall and communicate with them, instead of requiring the host to - type their name or use a verb, respectively. - - rscdel: Clockwork Marauders no longer see their block and counter chances; this - was mostly useless info, as knowing the chance didn't matter as to what you'd - do. - - rscdel: Clockwork Marauders can no longer change their name. - - tweak: Clockwork Marauders have a slightly lower chance to block, and take slightly - more damage when far from their host. - - bugfix: Fixes a bug where Clockwork Marauders never suffered reduced damage and - speed at low health and never got the damage bonus at high health. - Kor: - - rscdel: Stimpacks are no longer available in the mining vendor. - Lzimann: - - rscadd: You can now change your view range as ghost. To do so, either use the - View Range verb in the ghost tab, the mouse scroll up/down or control + "+"/"-". - The verb also works as a reset if you changed your view. - Sogui: - - tweak: There are now 2 less traitors in the double agent mode - - tweak: All security (and captain) suit sensors are set to max by default - Supermichael777: - - tweak: The wooden chair with wings is now craft-able. -1 non reconstruct-able - map object - - rscadd: Added the Tiki mask, you can make it in wood's crafting menu. - - imageadd: Ported Tiki mask's sprites from Hippie station. It is under the same - Creative Commons 3.0 BY-SA as the rest of our sprites. They are from Nienhaus. - Tofa01: - - rscadd: Adds a camera network onto the Omega Station. - - imageadd: Added new sprite for the AI Slipper. - XDTM: - - tweak: Implanting chainsaws is now a prosthetic replacement instead of its own - surgery. - - rscadd: You can now implant synthetic armblades (from an emagged limb grower) - into people's arms to use it at its full potential. - - rscdel: Chainsaw removal surgery has been removed as well; you'll have to sever - the limb and get a new one. - Xhuis: - - rscadd: AI control beacons are a new item created from the exosuit fabricator. - When installed into a mech, it allows AIs to jump to and from that mech freely. - Note that malfunctioning AIs with the domination power unlocked will instead - be forced to dominate the mech. - - tweak: Some timed actions are no longer interrupted while drifting through space. - - rscadd: Riot foam darts can now be constructed from a hacked autolathe. - bgobandit: - - rscadd: The library computer can now upload scanned books to the newscaster. Remember, - seditious or unsavory news channels should receive a Nanotrasen D-Notice! - - rscadd: The library computer can now print corporate posters as well as Bibles. - - rscdel: Cargo no longer offers a corporate poster crate. Nobody ever bought it - anyway. - coiax: - - rscadd: The Librarian now starts with a chisel/soapstone/chalk/magic marker capable - of engraving messages for subsequent shifts, and permanently erasing messages - that the Librarian is unhappy with. It has limited uses, so order more at Cargo. - - bugfix: The contraband cream pie crate is now locked, and requires Theatre access. - - rscadd: Any silicons created by bolts of change have no laws. - - rscadd: Cyborgs are immune to polymorph while changing module. - - rscadd: Adds Romerol to the traitor uplink for 25 TC. (This means you need a discount, - or to work with another traitor to afford it). Romerol is a highly experimental - bioterror agent which silently create dormant nodules to be etched into the - grey matter of the brain. On death, these nodules take control of the dead body, - causing limited revivification, along with slurred speech, aggression, and the - ability to infect others with this agent. - - rscdel: Zombie infections are no longer visible on MediHUD. - - rscdel: Zombies no longer tear open airlocks, since they can just smash them open - just as fast. - - rscdel: Zombies are no longer TOXINLOVING. - - rscadd: EMPs may cause random wires to be pulsed. Please ensure that sensitive - equipment avoids exposure to heavy electromagnetic pulses. - jughu: - - tweak: Changes some cargo export prices - ma44: - - tweak: Nanotrasen has improved training of the crew, teaching crewmembers like - you to unscrew the top off the bottle and pour it into containers like beakers. - vcordie: - - bugfix: Loads the HADES carbine with the correct bullet. - - tweak: The SRM-8 Rocket Pods have been loaded with new explosives designed to - do maximum damage to terrain. These explosives are less effective on people, - however. -2017-01-30: - BASILMAN YOUR MAIN MAN: - - rscadd: Added BM SPEEDWAGON THE BEST (AND ONLY) SPACE CAR ON THE MARKET. - CoreOverload: - - tweak: Clicking item slot now clicks the item in it. - Cyberboss: - - bugfix: Judicial visors now recharge properly - - bugfix: Gluon grenades now properly freeze turfs - - bugfix: Revs are now properly jobbanned - Fox McCloud: - - tweak: Plant analyzers will now display plant traits - - tweak: Plant analyzers will now display all of a grown's genetic reagents - Joan: - - rscdel: Cutting off legs no longer stuns. - - tweak: Volt Void now only allows you to fire 4 volt rays instead of 5, and the - damage of each ray has been reduced to 20, from 25. - - rscdel: Cyborgs using Volt Void now take damage if they fail to fire. - - experiment: 'Clockwork scripture can no longer require more components than it - consumes: This means that most scriptures ""cost"" one less component.' - MrStonedOne: - - rscadd: Because of abuse, actions on interfaces are throttled. Some bursting is - allowed. You will get a message if an action is ignored. Server operators can - configure this in config.dm - Tofa01: - - bugfix: '[Delta] Fixes area names for Deltastation' - - bugfix: '[Delta] Fixes custodial closet being cold all the time on Deltastation' - bgobandit: - - rscadd: Nanotrasen supports the arts. We now offer picture frames! - coiax: - - rscdel: The Syndicate "Uplink Implant" now has no TC precharged. You can charge - it with the use of physical telecrystals. The price has been reduced from 14TC - to 4TC accordingly. (The uplink implant in the implant bundle still has 10TC). - - rscadd: Syndicate bombs and nuclear devices now have a minimum timer of 90 seconds. - - rscadd: Camoflaged HUDs given to head revolutionaries now function the same as - chameleon glasses in the chameleon kit bundle, giving them an action button - and far more disguise options. - - rscadd: Syndicate thermals are also now more like chameleon glasses as well. - - rscadd: You can regain a use of a soapstone by erasing one of your own messages. - (This means you can remove a message if you don't like the colour and want to - try rephrasing it to get a better colour). Erasing someone else's message still - uses a charge. - - bugfix: Fixes bugs where you'd spend a charge without engraving anything. - - bugfix: Fixes a bug where the wrong ckey was entered in the engraving, you won't - be able to take advantage of the "recharging" on messages made before this change. -2017-01-31: - Cyberboss: - - tweak: The cyborg hugging module can no longer self target - Joan: - - tweak: Changed what scriptures and tools Servant cyborgs get; a full list can - be found on the clockwork cult wiki page. - RemieRichards: - - rscadd: Added the ability to choose where your uplink spawns, choose between the - classic PDA, the "woops you don't actually have a PDA" fallback Radio uplink - and the brand new Pen uplink! -2017-02-01: - Cyberboss: - - bugfix: AI integrity restorer computer now respects power usage - - bugfix: Progress bars will now stack vertically instead of on top of each other - - bugfix: Progress bars will no longer be affected by lighting - Xhuis: - - rscadd: You can now fold up bluespace body bags with creatures or objects inside. - You can't fold them up if too many things are inside, but anything you fold - up in can be carried around in the object and redeployed at any time. -2017-02-03: - Cobby: - - rscadd: Ghosts will now be informed when an event has been triggered by our lovely - RNG system. - Cyberboss: - - tweak: Firedoors will eventually reseal themselves if left open during a fire - alarm - Joan: - - tweak: Clockwork Marauders have 25% less health, 300 health from 400. - - wip: The Vitality Matrix scripture is now a Script, from an Application. Its cost - has been accordingly adjusted. - - tweak: Vitality Matrices will be consumed upon successfully reviving a Servant. - They also drain and heal conscious targets slightly slower. - - wip: The Fellowship Armory scripture is now an Application, from a Script. Its - cost has been accordingly adjusted. - - tweak: Fellowship Armory now affects all Servants in view of the invoker, and - will replace weaker gear and armor with its Ratvarian armor. Also, clockwork - treads now allow you to move in no gravity like magboots. - - rscdel: Mania Motors no longer instantly convert people next to them. - - rscadd: Instead, you have to remain next to them for several seconds, after which - you will be knocked out, then converted if possible. - - tweak: Mania Motors now cost slightly less power to run. - Jordie0608: - - tweak: Admin notes, memos and watchlist entries now use a generalized system, - they can all be accessed from the former notes browser. - - rscadd: Added to this are messages, which allow admins to leave a message for - players that is delivered to them when they next connect. - Lexorion: - - tweak: Laser projectiles have a new sprite! They also have a new effect when they - hit a wall. - Sweaterkittens and Joan: - - rscadd: Ocular Wardens will now provide auditory feedback when they acquire targets - and deal damage. - - soundadd: adds ocularwarden-target.ogg, ocularwarden-dot1.ogg and ocularwarden-dot2.ogg - to the game sound files. - Tofa01: - - bugfix: '[Delta] Allows Station Engineers to access Delta Atmospherics Solar Panel - Array Room.' - - rscadd: '[Omega] Adds a Massdriver room to chapel on Omegastation.' - bgobandit: - - rscadd: All art storage facilities offer construction paper now! - coiax: - - rscadd: A victim of a transformation disease will retain their name. - - tweak: The slime transformation disease can turn you into any colour or age of - slime. - - rscadd: The Abductor event can now happen at any time, rather than thirty (30) - minute plus rounds. -2017-02-04: - Cyberboss: - - bugfix: Modular computers now explode properly - - bugfix: Emagged holograms can no longer be exported for credits - - bugfix: Abstract entities no longer feed the singularity - - tweak: Machine frames will no longer be anchored when created - Joan: - - rscadd: Vanguard now shows you how long you have until it deactivates. - Kor: - - rscadd: 'By combing two flashlights and cable coil, you can create a new eye implant: - flashlight eyes. People with flashlights for eyes can not see, but they will - provide an enormous amount of light to their friends.' - - rscadd: Valentines day will now randomly pair up crew members on dates. The paired - crewmembers will get an objective to protect each other at all costs. - Steelpoint: - - rscadd: Addition of two security DragNETs to Deltastations, Omegastations and - Metastations armouries. - Tofa01: - - rscadd: '[Delta] Removes space money from gold crate replaces with 3 Gold Bars - Gold Wrestling belt is still there.' - - rscadd: '[Delta] Removes space money from silver crate replaces with 5 Silver - Coins.' - - bugfix: Fixes incorrect placement of RD modular computer on Metastation. - WhiteHusky: - - rscadd: Fields are supported when printing with a modular computer - - rscadd: PRINTER_FONT is now a variable - - rscdel: Removed the [logo] tag on Modular computers as the logo no longer exists - - tweak: New lines on paper are parsed properly - - tweak: '[tab] is now four non-breaking spaces on papers' - - tweak: Papers have an additional proc, reload_fields, to allow fields made programmatically - to be used - - tweak: 'stripped_input stripped_multiline_input has a new argument: no_trim' - - bugfix: Modular computers no longer spew HTML when looking at a file, rather it - is unescaped like it should - - bugfix: Modular computers no longer show escaped HTML entities when editing - - bugfix: Modular computers can now propperly read and write from external media - - bugfix: Modular computers' file browser lists files correctly - - spellcheck: NTOS File Manager had a spelling mistake; Manage instead of Manager - coiax: - - bugfix: Engraved messages can no longer be moved by a gravitational singularity. - - tweak: The deadchat notification of randomly triggered events now uses the deadsay - span. - - rscdel: The wizard spell "Rod Form" does not produce a message in deadchat everytime - it is used. -2017-02-05: - Cyberboss: - - bugfix: Shuttle docking/round end shouldn't lag as much - - rscadd: There's a new round end sound! - Hyena: - - bugfix: The bible now contains 1 whiskey - Joan: - - rscadd: Ratvar-converted AIs become brass-colored, speak in Ratvarian, and cannot - be carded. - Kor: - - rscadd: Eyes are now organs. You can remove or implant them into peoples heads - with organ manipulation surgery. A mob without eyes will obviously have trouble - seeing. - - rscadd: All special eye powers are now tied to their respective organs. For example, - this means you can harvest an alien or shadow persons eyes, have them implanted, - and gain toggle-able night vision. - - rscadd: All cybernetic eye implants are now cybernetic eyes, meaning you must - replace the patients organic eyes. HUD implants are still just regular implants. - Lzimann: - - rscadd: Tesla zaps can now generate an energy ball if they zap a tesla generator! - Sweaterkittens: - - rscadd: The station's Plasmamen have been issued a new production of envirosuits. - The most notable change aside from small aesthetic differences is the addition - of an integrated helmet light. - - tweak: Tweaked a few of the Plasma Envirosuit sprites to be more fitting thematically. - Swindly: - - bugfix: Saline-glucose solution can no longer decrease blood volume - - rscadd: Cyborg hyposprays can now dispense saline-glucose solution - - rscadd: Saline-glucose solution now increases blood volume when it heals - coiax: - - bugfix: The mulligan reagent can now be created with 1u stable mutation toxin - + 1u unstable mutagen. - - rscdel: Tesla balls cannot dust people near grounding rods. - - rscadd: Soapstones/chisel/magic markers/chalk can remove messages for free. Removing - one of your own messages still grants a use. - - rscadd: The Janitor starts with a dull soapstone for removing unwanted messages. - xmikey555: - - tweak: The tesla engine no longer destroys energy ball generators. -2017-02-06: - Xhuis: - - rscadd: Traitor janitors can now order EZ-clean grenades for 6 telecrystals per - bundle. They function like normal cleaning grenades with an added "oh god my - face is melting" effect, and can also be found in surplus crates. -2017-02-07: - Cyberboss: - - bugfix: Wire, atmos, and disposal networks no longer work across hyperspace when - on the border of a shuttle - - bugfix: Implants that work on death will now work for simple_animals - - bugfix: The target moving while being implanted will no longer continue the implant - - bugfix: Implanters now show progress bars as they were intended to - - bugfix: Pipe painters are no longer aggressive - - bugfix: Carding the AI will now stop a doomsday device - - rscadd: The job subsystem now loads instantly. No more waiting to set your occupation - prefs! - - bugfix: The rare case of duping your inventory at roundstart has been fixed - - bugfix: Self deleting stackable items are fixed - Dannno: - - tweak: We've switched to a new brand of colored jumpsuit. - JJRcop: - - tweak: Adds 4% chance when assigning a valentines day date to also assign someone - else to the same date, but your date will still have you as their only date. - Poojawa: - - bugfix: '[Delta] Active turfs down from 300+' - - bugfix: '[Delta] Janitor closet isn''t 2.7K anymore' - - bugfix: '[Delta] Various pipe fixes' - RemieRichards: - - rscadd: Added a new checmial, Skewium, it's produced by mixing rotatium, plasma - and sulphuric acid in the ratio 2:2:1, which results in 5 Skewium. - Swindly: - - bugfix: Robotic eyes can no longer be eaten - Tofa01: - - bugfix: Fixes grammar issue when changing someones appearance via plastic surgery. - - tweak: '[OmegaStation] Allows Chaplain job to be selectable.' - - bugfix: '[Omega] Fixes Overpressurization In Mass Driver Room' - Xhuis: - - rscadd: Traitor clowns can now buy a reverse revolver. I'll leave it up to you - to guess what it does. Honk. - iamthedigitalme: - - imageadd: Legion has a new, animated sprite. - kevinz000: - - rscadd: 'ADMINS: SDQL2 has been given some new features!' - - bugfix: SDQL2 now gives you an exception on runtime instead of flooding server - runtime logs. - - rscadd: SDQL2 now supports usr, which makes that variable reference to whatever - mob you are in, src, which targets the object it is being called on itself, - and marked, which targets the datum marked by the admin calling it. Also, it - supports hex references (the hex number at the top of a VV panel) in {}s, so - you can target nearly anything! Also, global procs are supported by global.[procname](args), - for CALL queries. - - bugfix: SDQL2 can no longer edit /datum/admins or /datum/admin_rank, and is protected - from changing x/y/z of a turf and anything that would cause broken movement - for movable atoms. - - rscadd: SDQL2 can now get list input with [arg1, arg2]! - - experiment: Do '""' to put strings inside of SDQL2 or it won't work. -2017-02-09: - Cyberboss: - - bugfix: Certain firedoors that should have closed during an alarm now actually - close - - soundadd: You can now knock on firedoors - - bugfix: Supermatter in a closet/crate will now properly fee the singulo - - bugfix: Paper planes can be unfolded again - - bugfix: Paper planes can be stamped properly - Joan: - - tweak: Impaling someone with a sharp item by pulling them with a changeling Tentacle - now does significantly less damage and stuns for less time. - Jordie0608: - - rscadd: Admins can now filter watchlist entries to only users who are connected. - - tweak: Messages no longer delete themselves when sent. - Kor: - - rscadd: The limb grower has been replaced with a box of surplus limbs. Visit robotics - or harvest limbs from another person if you want quality. - Reeeeimstupid: - - rscadd: Silly Abductee objectives. Try not to go crazy trading life stories with - Lord Singulo. - Tofa01: - - tweak: Removes virology access to jobs including Medical Doctor, Geneticist and - Chemist. - - tweak: '[Delta] Changes NW supermatter filter to filter O2 instead of N2' - - rscadd: '[Delta] Adds wardrobes to Dorms & Arrivals Shuttle' - - rscadd: '[Delta] Adds access buttons to virology doors for extra security' - - rscadd: '[Delta] Adds bolt door button to all dorms' - - rscadd: '[Delta] Adds three pairs of optical meson scanners to supermatter room' - - rscadd: '[Delta] Adds a disk fridge to botany' - - rscadd: '[Delta] Adds a cake hat to the bar' - - bugfix: '[Delta] Fixes misplaced station intercom in Supermatter SMES room' - XDTM: - - rscadd: A Law Removal module can be build in RnD. It can remove a specified core - or freeform law. - - tweak: 'When stating laws, silicons won''t skip a number when hiding laws. (example: - 1. Law 1; 2. Law 2; 3. Law 4 if you choose not to state Law 3)' - Xhuis: - - rscadd: Artistic toolboxes now spawn in maintenance and possess various supplies - for wire art and crayon art. - - rscadd: Traitors can now obtain His Grace. Chaplains can buy it for 20 TC, or - it can be found in a surplus crate. - - rscadd: Soapstone messages can now be rated! Attack the message with your hand - to rate it positive or negative. Anyone can see the rating, and you cannot rate - a message more than once, even across rounds. - - rscdel: Soapstones no longer have a write time. - - tweak: Soapstones now have a fixed vocabulary to write messages with. - chanoc1: - - tweak: The salt and pepper shakers have new sprites. - coiax: - - rscadd: Added metal rods and floor tiles to Standard cyborgs. - - rscadd: Added a remote signaling device to Engineering cyborg. - - rscadd: Adds a 'Guardian of Balance' lawset and AI module, currently admin spawn - only. - uraniummeltdown: - - tweak: Kinetic Accelerator Cosmetic and Tracer Modkits now don't use mod capacity. - Cosmetic kits change the name of the KA. -2017-02-10: - Ausops: - - rscadd: Air tanks and plasma tanks have been resprited. - ChemicalRascal: - - tweak: Pen is able to wind up ruined tapes. - CoreOverload: - - rscadd: You can now emag the escape pods to launch them under any alert code. - - tweak: Shuttle name is no longer displayed on "Status" panel. Instead, you can - now examine a status screen to see it. - Cyberboss: - - bugfix: Simple animals now deathgasp properly again - - bugfix: Testmerged PRs will no longer duplicate in the list - - bugfix: Pods and shuttles now have air again - Joan: - - experiment: Clockwork Cults must always construct and activate the Ark. - - imageadd: Updates air tank inhands to match Ausops' new sprites. - Mekhi Anderson: - - rscadd: All mobs can now *spin! - - rscadd: Cyborgs now have handholds. This means you can ride around on them, but - if you get stunned or hit, you fall off! The cyborg can also throw you off by - spinning. - Tofa01: - - soundadd: Changes fire alarm to make new sound FireAlarm.ogg - Xhuis: - - rscdel: The Syndicate will no longer prank their operatives by including reverse - revolvers in surplus crates. - coiax: - - rscadd: A reverse revolver now comes in a box of hugs. - - rscadd: 'Added a new admin only event: Station-wide Human-level Intelligence. - Like the random animal intelligence event, but affecting as many animals as - there are ghosties.' - - rscadd: The Luxury Shuttle grabs cash in your wallet and backpack, and shares - approval between the entrance gates. - - rscadd: The NES Port shuttle now costs 500 credits. -2017-02-11: - Dannno: - - tweak: hahaha I switched your toolboxes you MORONS - Kor: - - rscadd: Killing bubblegum now unlocks a new shuttle for purchase. - Lzimann: - - tweak: Hardsuit built-in jetpacks no longer have a speed boost. - Pyko: - - bugfix: Fixed legit posters and map editing official/serial number for poster - decals. - Tofa01: - - bugfix: '[Delta] Fixes doors walls and windows being incorrectly placed due to - mapmerge issues.' - - bugfix: '[Box] Fixes access levels for HOP shutters.' -2017-02-12: - AnturK: - - rscadd: Added Poison Pen to uplink. - Drunk Musicians: - - rscadd: Drunk music - Gun Hog: - - rscadd: Nanotrasen Engineering has devised a construction console to assist with - building the Auxiliary Mining Base, usually located near a station's Arrivals - hallway. A breakthrough in bluespace technology, this console employs an advanced - internal Rapid Construction Device linked to a camera-assisted holocrane for - rapid, remote construction! - Lzimann: - - bugfix: MMIs/posibrains works with mechas again - RandomMarine: - - rscadd: The Russians have expanded to the shuttle business. A new escape shuttle - is available for purchase. - Sweaterkittens: - - tweak: Plasmamen burn damage multiplier reduced to 1.5x from 2x - coiax: - - rscdel: Removes the STV5 shuttle from purchase. - - rscadd: Swarmers no longer consume the deep fryer, since they have too much respect - for the potential fried foods it can produce. - - rscadd: The clown's survival/internals box is now a box of hugs. Dawww. -2017-02-13: - ChemicalRascal: - - tweak: Delta station brig cell chairs have been replaced with beds. One bed per - cell, no funny business. - Cyberboss: - - bugfix: Simple animals that are deleted when killed will now deathrattle - - bugfix: Fixed Alt-click stack duplication - Joan: - - imageadd: Updated the back and belt sprites for airtanks to match the new sprites. - Kor: - - rscadd: Mobile pAIs are now slower than humans. - Swindly: - - rscadd: Added Nuka Cola as a premium item in Robust Softdrinks - Tofa01: - - bugfix: '[Delta] Fixes double windoor on chemistry windows.' - - tweak: Lowered volume of fire alarm sound also makes it more quiet. - coiax: - - rscadd: Added an admin only tool, the life candle. Touch the candle, and when - you die, you'll respawn shortly afterwards. Touch it again to stop. Used for - testing, thunderdome brawls and good old fashioned memery. - - bugfix: Fried foods no longer shrink to miniature size. -2017-02-14: - Cyberboss: - - bugfix: Fixed unequipping items while stunned - - bugfix: Fixed various things deleting when unequipped - - bugfix: Fixed tablet ID slots deleting cards - - bugfix: Fixed water mister nozzle getting stuck in hands - - tweak: Title music now starts immediately upon login - - tweak: You can no longer sharpen energy weapons - Joan: - - tweak: Mania Motors are overall less effective and only affect people who can - see the motor. - - tweak: Mania Motors have slightly more health; 100, from 80. - MrStonedOne: - - tweak: Station time is now always visible in the status tab. - - tweak: Both server time and station time now displays seconds so you can actively - see how game time (ByondTime[tm]) is progressing along side real time. - - rscadd: Added a time dilation tracker, this allows you to better understand how - time will progress in game. It shows the time dilation percent for the last - minute as well as some rolling averages. - RandomMarine: - - tweak: Pre-made charcoal pills now contain 10 units instead of 50. The amount - of pills inside of toxin first aid kits and the smartfridge have been increased - to compensate. Keep in mind that each ten unit pill recovers 100 points of toxin - damage and purges 50 units of other reagents. - Steelpoint: - - tweak: All Drones now have a walking animation. - Tofa01: - - bugfix: '[Delta] Fixes space cleaner being empty in brig medbay' - - bugfix: '[Delta] Fixes some areas that are not radiation proof' - - bugfix: '[Meta] Fixes Atmospherics Freezer Spawning As A Heater' - uraniummeltdown: - - rscadd: Window Flashing is now a preference - - rscadd: Your game window will flash when alerted as a ghost. This includes being - revived by defibs/cloning and events such as borers, swarmers, revenant, etc. -2017-02-16: - Cyberboss: - - rscadd: Test merged PRs are now more detailed - Steelpoint: - - rscadd: The Head of Security's Hardsuit is now equipped with a inbuilt Jetpack. - coiax: - - rscadd: The Hyperfractal Gigashuttle is now purchasable for 100,000 credits. Help - Centcom by testing this very safe and efficient shuttle design. (Terms and conditions - apply.) - - rscadd: The changeling power "Anatomic Panacea" now causes the changeling to vomit - out zombie infections, along with headslugs and xeno infections, as before. - - bugfix: The main CTF laser gun disappears when dropped on the floor. -2017-02-17: - Arianya: - - tweak: The Labour Camp rivet wall has been removed! - - spellcheck: Fixed some typos in Prison Ofitser's description. - Cobby: - - experiment: Flashes have been rebalanced to be more powerful - Cyberboss: - - bugfix: Rack construction progress bars will no longer be spammed - - tweak: The round start timer will count down during subsystem initialization - - tweak: Total subsystem initialization time will now be displayed - Joan: - - rscdel: His Grace no longer globally announces when He is awakened or falls to - sleep. - - rscdel: His Grace is not a toolbox, even if He looks like one. - - experiment: His Grace no longer requires organs to awaken. - - tweak: His Grace now gains 4 force for each victim consumed, always provides stun - immunity, and will, generally, take longer to consume His owner. - - experiment: His Grace must be destroyed to free the bodies within Him. - - experiment: Dropping His Grace while He is awake will cause you to suffer His - Wrath until you hold Him again. - - rscadd: His Grace becomes highly aggressive after consuming His owner, and will - hunt His own prey. - - experiment: The Ark of the Clockwork Justicar now only costs 3 of each component - to summon, but must consume an additional 7 of each component before it will - activate and start counting down. - - rscadd: The presence of the Ark will be immediately announced, though the location - will still only be announced after it has been active and counting down for - 2 minutes. - - tweak: The Ark also requires an additional invoker to invoke. - Lobachevskiy: - - bugfix: Fixed glass shards affecting buckled and flying mobs - MrStonedOne: - - experiment: The game will now force hardware rendering on for all clients. - Nienhaus: - - rscadd: Drying racks have new sprites. - Swindly: - - rscadd: Trays can now be used to insert food into food processors - Thunder12345: - - bugfix: It's ACTUALLY possible to pat people on the head now - WJohn: - - imageadd: Improved blueshift sprites, courtesy of Nienhaus. - XDTM: - - rscadd: Bluespace Crystals are now a material that can be inserted in Protolathes - and Circuit Printers. Some items now require Bluespace Mesh. - - rscadd: Bluespace Crystal can now be ground in a reagent grinder to gain bluespace - dust. It has no uses, but it teleports people if splashed on them, and if ingested - it will occasionally cause teleportation. - coiax: - - rscadd: Engraved messages now have a UI, which any player, living or dead can - access. See when the message was engraved, and upvote or downvote accordingly. - - rscadd: Admins have additional options with the UI, seeing the player ckey, original - character name, and the ability to outright delete messages at the press of - a button. - kevinz000: - - bugfix: Flightsuits actually fly over people - - bugfix: Flightsuits don't interrupt pulls when you pass through doors -2017-02-18: - Cyberboss: - - imageadd: New round end animation. Inspired by @Iamgoofball - Gun Hog: - - rscadd: The Aux Base console now controls turrets made by the construction console. - - rscadd: The Aux Base may now be dropped at a random location if miners fail to - use the landing remote. - - rscadd: The mining shuttle may now dock at the Aux Base's spot once the base is - dropped. - - tweak: Removed access levels on the mining shuttle so it can be used at the public - dock. - - tweak: The Aux Base's turrets now fire through glass. Reminder that the turrets - need to be installed outside the base for full damage. - - rscadd: Added a base construction console to Delta Station. - Mysterious Basilman: - - rscadd: More powerful toolboxes are active in this world... - Scoop: - - tweak: Condimasters now correctly drop their items in front of their sprite. - Tofa01: - - bugfix: Re-Arranges And Extends Pubby Escape Hallway To Allow Larger Shuttle To - Dock - - bugfix: '[Meta] Fixes top left grounding rod from being destroyed by the Tesla - engine.' - TrustyGun: - - rscadd: Traitor mimes can now learn two new spells for 15 tc. - - rscadd: The first, Invisible Blockade, creates a 3x1 invisible wall. - - rscadd: The second, Finger Guns, allows them to shoot bullets out of their fingers. - kevinz000: - - rscadd: You can now ride piggyback on other human beings, as a human being! To - do so they must grab you aggressively and you must climb on without outside - assistance without being restrained or incapacitated in any manner. They must - also not be restrained or incapacitated in any manner. - - rscadd: If someone is riding on you and you want them to get off, disarm them - to instantly floor them for a few seconds! It's pretty rude, though. - rock: - - soundadd: you can now harmlessly slap somebody by aiming for the mouth on disarm - intent. - - soundadd: you can only slap somebody who is unarmed on help intent, restrained, - or ready to slap you. -2017-02-19: - Basilman: - - rscadd: some toolboxes, very rarely, have more than one latch - Joan: - - rscadd: You can now put components, and deposit components from slabs, directly - into the Ark of the Clockwork Justicar provided it actually requires components. - - experiment: Taunting Tirade now leaves a confusing and weakening trail instead - of confusing and weakening everyone in view. - - tweak: Invoking Inath-neq/Nzcrentr is now 33% cheaper and has a 33% lower cooldown. - Tofa01: - - rscdel: '[Delta] Removes SSU From Mining Equipment Room' - - tweak: Changes centcomm ferry to require centcomm general access instead of admin - permission. - coiax: - - rscadd: Nuke ops syndicate cyborgs have been split into two seperate uplink items. - Medical cyborgs now cost 35 TC, assault cyborgs now cost 65 TC. - grimreaperx15: - - tweak: Blood Cult Pylons will now rapidly regenerate any nearby cultists blood, - in addition to the normal healing they do. - ma44: - - tweak: Intercepted messages from a lavaland syndicate base reveals they have additional - grenade and other miscellaneous equipment. - uraniummeltdown: - - rscadd: Shuttle engines have new sprites. -2017-02-20: - Cyberboss: - - bugfix: The frequncy fire alarms play at is now consistent - MrStonedOne: - - tweak: bluespace ore cap changed from 100 ores to 500 - Tofa01: - - tweak: '[Meta] Replaces orange jumpsuit in holding cell with prisoner jumpsuits' - XDTM: - - tweak: Repairing someone else's robotic limb is instant. Repairing your own robotic - limbs will still take time. - - tweak: Repairing limbs with cable or welding will now heal more. - Xhuis: - - bugfix: Medipens are no longer reusable. -2017-02-21: - Cyberboss: - - bugfix: You can now unshunt as a malfunctioning AI again - Kor: - - bugfix: You will now retain your facing when getting pushed by another mob. - Tofa01: - - bugfix: '[Z2] Fixed Centcomm shutters to have proper access levels for inspectors - and other Admin given roles' - coiax: - - rscadd: Refactors heart attack code, a cardiac arrest will knock someone unconscious - and kill them very quickly. - - rscadd: Adds corazone, an anti-heart attack drug, made by mixing 2 parts Phenol, - 1 part Lithium. A person with corazone in their system will not suffer any negative - effects from missing a heart. Use it during surgery. - - rscadd: Abductor glands are now hearts, the abductor operation table now automatically - injects corazone to prevent deaths during surgery. The gland will restart if - it stops beating. - - bugfix: Cloning pods always know the name of the person they are cloning. - - rscadd: You can swipe a medical ID card to eject someone from the cloning pod - early. The cloning pod will announce this over the radio. - - rscdel: Fresh clones have no organs or limbs, they gain them during the cloning - process. Ejecting a clone too early is not recommended. Power loss will also - eject a clone as before. - - rscdel: An ejected clone will take damage from being at critical health very quickly - upon ejection, rather than before, where a clone could be stable in critical - for up to two minutes. - - rscadd: Occupants of cloning pods do not interact with the air outside the pod. - uraniummeltdown: - - bugfix: All shuttle engines should now be facing the right way -2017-02-22: - AnonymousNow: - - rscadd: Added Medical HUD Sunglasses. Not currently available on-station, unless - you can convince Centcom to send you a pair. - Cyberboss: - - bugfix: Spawning to the station should now be a less hitchy experience - MrPerson: - - experiment: 'Ion storms have several new additions:' - - rscadd: 25% chance to flatly replace the AI's core lawset with something random - in the config. Suddenly the AI is Corporate, deal w/ it. - - rscadd: 10% chance to delete one of the AI's core or supplied laws. Hope you treated - the AI well without its precious law 1 to protect your sorry ass. - - rscadd: 10% chance that, instead of adding a random law, it will instead replace - one of the AI's existing core or supplied laws with the ion law. Otherwise, - it adds the generated law as normal. There's still a 100% chance of getting - a generated ion law. - - rscadd: 10% chance afterwards to shuffle all the AI's laws. - TalkingCactus: - - bugfix: New characters will now have their backpack preference correctly set to - "Department Backpack". - Tofa01: - - bugfix: '[Delta] Fixes missing R&D shutter near public autolathe' - Xhuis: - - tweak: Highlanders can no longer hide behind chairs and plants. - - tweak: Highlanders no longer bleed and are no longer slowed down by damage. -2017-02-23: - Cyberboss: - - bugfix: Fixed a bug where the fire overlay wasn't getting removed from objects - - bugfix: The graphical delays with characters at roundstart are gone - - bugfix: The crew manifest is working again - - rscadd: Admins can now asay with ":p" and dsay with ":d" - Dannno: - - imageadd: Robust Softdrinks LLC. has sent out new vendies to the stendy. - Joan: - - rscdel: Off-station and carded AIs no longer prevent Judgement scripture from - unlocking. - Nienhaus: - - tweak: Updates ammo sprites to the new perspective. - Tofa01: - - bugfix: Disables sound/frequency variance on cryo tube alert sound - coiax: - - rscadd: Nanotrasen reminds its employees that they have ALWAYS been able to taste. - Anyone claiming that they've recently only just gained the ability to taste - are probably Syndicate agents. -2017-02-24: - MrStonedOne: - - rscdel: Limit on Mining Satchel of Holding Removed - - tweak: Dumping/mass pickup/mass transfer of items is now lag checked - - rscadd: Dumping/mass pickup/mass transfer of items has a progress bar -2017-02-25: - AnonymousNow: - - rscadd: Nerd Co. has sent pairs of thicker prescription glasses out to Nanotrasen - stations, for your local geek to wear. - Basilman: - - rscadd: New box sprites - Robustin: - - tweak: Hulks can no longer use pneumatic cannons or flamethrowers - Tofa01: - - rscadd: '[All Maps] The new and improved Centcom transportation ferry version - 2.0 is out now!' - coiax: - - rscadd: Cargo can now order plastic sheets to make plastic flaps. No doubt other - uses for plastic will be discovered in the future. - - rscadd: To deconstruct plastic flaps, unscrew from the floor, then cut apart with - wirecutters. Plastic flaps have examine tips like reinforced walls. - uraniummeltdown: - - rscadd: Science crates now have new sprites -2017-02-26: - Ausops: - - imageadd: New sprites for water, fuel and hydroponics tanks. - Joan: - - experiment: 'Clockwork objects are overall easier to deconstruct:' - - wip: Clockwork Walls now take 33% less time to slice through, Brass Windows now - work like non-reinforced windows, and Pinion Airlocks now have less health and - only two steps to decon(wrench, then crowbar). - - rscadd: EMPing Pinion Airlocks and Brass Windoors now has a high chance to open - them and will not shock or bolt them. - - rscadd: Anima fragments will very gradually self-repair. - Tofa01: - - bugfix: '[Omega] Fixes ORM input and output directions' - - bugfix: Fixes space bar kitchen freezer access level - - bugfix: Fixes giving IDs proper access for players who spawn on a ruin via a player - sleeper/spawners - - bugfix: '[Delta] Fixes varedited tiles causing tiles to appear as if they have - no texture' - - bugfix: Fixes robotic limb repair grammar issue -2017-02-27: - Kor, Jordie0608 and Tokiko1: - - rscadd: Singularity containment has been replaced on box, meta, and delta with - a supermatter room. The supermatter gives ample warning when melting down, so - hopefully we'll see fewer 15 minute rounds ended by a loose singularity. - - rscadd: Supermatter crystals now collapse into singularities when they fail, rather - than explode. - Tofa01: - - bugfix: Stops AI And Borgs From Interfacing With Ferry Console - TrustyGun: - - imageadd: Box sprites are improved. - WJohnston: - - imageadd: New and improved BRPED beam. The old one was hideous. - coiax: - - rscadd: Drone shells are now points of interest in the orbit list. - - rscadd: Derelict drone shells now spawn with appropriate headgear. -2017-02-28: - Cyberboss: - - tweak: You will no longer be shown empty memories when the game starts - - bugfix: Built APCs now work again - - bugfix: Borg AI cameras now work again - Joan: - - rscadd: Anima Fragments now slam into non-Servants when bumping. This will ONLY - happen if the fragment is not slowed, and slamming into someone will slightly - damage the fragment and slow it severely. - Lzimann: - - tweak: Communications console can also check the ID the user is wearing. - Supermichael777: - - tweak: The button now has a five second delay when detonating bombs - XDTM: - - rscadd: You can now change the input/output directons for Ore Redemption Machines - by using a multitool on them with the panel open. - - rscadd: Diagnostic HUDs can now see if airlocks are shocked. -2017-03-01: - Cyberboss: - - bugfix: Lobby music is no longer delayed -2017-03-02: - Gun Hog: - - tweak: Advanced camera, Slime Management, and Base Construction consoles may now - be operated by drones and cyborgs. - Robustin: - - rscadd: The syndicate power beacon will now announce the distance and direction - of any engines every 10 seconds. - Steelpoint: - - rscadd: Robotics and Mech Bay have seen a mapping overhaul on Boxstation. - - rscadd: A cautery surgical tool has been added to the Robotics surgical area on - Boxstation. - XDTM: - - tweak: Hallucinations have been modified to increase the creepiness factor and - reduce the boring factor. - - rscadd: Added some new hallucinations. - - bugfix: Fixed a bug where the singularity hallucination was stunning for longer - than intended and leaving the fake HUD crit icon permanently. - coiax: - - rscadd: Ghosts are polled if they want to play an alien larva that is about to - chestburst. They are also told who is the (un)lucky victim. - - bugfix: Clones no longer gasp for air while in cloning pods. - - rscadd: Adds a new reagent, "Mime's Bane", that prevents all emoting while it - is in a victim's system. Currently admin only. - - experiment: Mappers now have an easier time adding posters, and specifying whether - they're random, random official, random contraband or a specific poster. - - rscdel: Posters no longer have serial numbers when rolled up; their names are - visible instead. - kevinz000: - - rscadd: You can now craft pressure plates. - - rscadd: Pressure plates are hidden under the floor like smuggler satchels are, - but you can attach a signaller to them to have it signal when a mob passes over - them! - - experiment: Bomb armor is now effective in lessening the chance of being knocked - out by bombs. -2017-03-03: - Cyberboss: - - tweak: You can now repair shuttles in transit space - Incoming5643: - - imageadd: 'Server Owners: There is a new system for title screens accessible from - config/title_screen folder.' - - rscadd: This system allows for multiple rotating title screens as well as map - specific title screens. - - rscadd: It also allows for hosting title screens in formats other than DMI. - - rscadd: 'See the readme.txt in config/title_screen for full details. remove: The - previous method of title screen selection, the define TITLESCREEN, has been - depreciated by this change.' - Sligneris: - - imageadd: Updated sprites for the small xeno queen mode -2017-03-04: - Cyberboss: - - bugfix: You can build lattice in space again - Hyena: - - tweak: Detective revolver/ammo now starts in their shoulder holster - Joan: - - tweak: Weaker cult talismans take less time to imbue. - PJB3005: - - rscadd: Rebased to /vg/station lighting code. - Supermichael777: - - rscadd: Grey security uniforms have unique names and descriptions - Tofa01: - - rscadd: Adds the new Centcomm Raven Battlecruiser to the purchasable shuttle list - buy now get one free! - coiax: - - rscadd: CTF players start with their helmet toggled off, better to see the whites - of their opponents eyes. Very briefly. - - bugfix: Existing CTF barricades are repaired between rounds, and deploy instantly - when replaced. - - tweak: Healing non-critical CTF damage is faster. Remember though, if you drop - into crit, YOU DIE. - - rscadd: Admin ghosts can just click directly on the CTF controller to enable them, - in addition to using the Secrets panel. - - bugfix: Cyborg radios can no longer have their inaccessible wires pulsed by EMPs. -2017-03-06: - Cyberboss: - - experiment: Map rotation has been made smoother - Gun Hog: - - bugfix: The Aux Base Construction Console now directs to the correct Base Management - Console. - - bugfix: The missing Science Department access has been added to the Auxiliary - Base Management Console. - Hyena: - - rscdel: Space bar is out of bussiness - MrStonedOne: - - bugfix: patched a hacky workaround for /vg/lights memory leaking crashing the - server - Penguaro: - - bugfix: Changed DIR of Gas Filter for O2 in Waste Loop from 1 to 4 - Sligneris: - - imageadd: '''xeno queen'' AI hologram now actually uses the xeno queen sprite - as a reference' - Tofa01: - - bugfix: '[Omega] Fixes missing walls and wires new dock to the powergrid' - XDTM: - - rscadd: Changelings can now click their fake clothing to remove it, without needing - to drop the full disguise. - coiax: - - rscadd: The Bardrone and Barmaid are neutral, even in the face of reality altering - elder gods. -2017-03-07: - Supermichael777: - - rscadd: Wannabe ninjas have been found carrying an experimental chameleon belt. - The Spider clan has disavowed any involvement. -2017-03-08: - Cyberboss: - - imageadd: Added roundstart animation - - experiment: Roundstart should now be a smoother experience... again - - bugfix: You can now scan storage items with the forensic scanner - - bugfix: Unfolding paper planes no longer deletes them - - bugfix: Plastic no longer conducts electricity - - tweak: The map rotation message will only show if the map is actually changing - Francinum: - - bugfix: Holopads now require power. - Fun Police: - - tweak: Reject Adminhelp and IC Issue buttons have a cooldown. - Joan: - - rscadd: Circuit tiles now glow faintly. - - rscadd: Glowshrooms now have colored light. - - tweak: Tweaked the potency scaling for glowshroom/glowberry light; high-potency - plantss no longer light up a huge area, but are slightly brighter. - Kor: - - rscadd: People with mutant parts (cat ears) are no longer outright barred from - selecting command roles in their preferences, but will have their mutant parts - removed on spawning if they are selected for that role. - LanCartwright: - - rscadd: Adds scaling damage to buckshot. - Robustin: - - tweak: The DNA Vault has 2 new powers - - tweak: The DNA Vault requires super capacitors instead of quadratic - - tweak: Cargo's Vault Pack now includes DNA probes - Supermichael777: - - rscadd: Robust Soft Drinks LLC is proud to announce Premium canned air for select - markets. There is not an air shortage. Robust Soft Drinks has never engaged - in any form of profiteering. - TalkingCactus: - - rscadd: Energy swords (and other energy melee weapons) now have a colored light - effect when active. - Tofa01: - - bugfix: '[All Maps] Fixes syndicate shuttles spawning too close to stations by - moving their spawn further from the station' - - rscadd: '[Omegastation] This station now has a syndicate shuttle and syndicate - shuttle spawn.' - coiax: - - rscadd: Wizards now have a new spell "The Traps" in their spellbook. Summon an - array of temporary and permanent hazards for your foes, but don't fall into - your own trap(s)! - - rscadd: Permanent wizard traps can be triggered relatively safely by throwing - objects across the trap, or examining it at close range. The trap will then - be on cooldown for a minute. - - rscadd: Toy magic eightballs can now be found around the station in maintenance - and arcade machines. Ask your question aloud, and then shake for guidance. - - rscadd: Adds new Librarian traitor item, the Haunted Magic Eightball. Although - identical in appearance to the harmless toys, this occult device reaches into - the spirit world to find its answers. Be warned, that spirits are often capricious - or just little assholes. - - rscadd: You only have a headache looking at the supermatter if you're a human - without mesons. - - rscadd: The supermatter now speaks in a robotic fashion. - - rscadd: Admins have a "Rename Station Name" option, under Secrets. - - rscadd: A special admin station charter exists, that has unlimited uses and can - be used at any time. - - rscadd: Added glowsticks. Found in maintenance, emergency toolboxes and Party - Crates. - kevinz000: - - rscadd: The Syndicate reports a breakthrough in chameleon laser gun technology - that will disguise its projectiles to be just like the real thing! -2017-03-10: - Cyberboss: - - bugfix: You should no longer be seeing entities with `\improper` in front of their - name - - rscadd: The arrivals shuttle will now ferry new arrivals to the station. It will - not depart if any intelligent living being is on board. It will remain docked - if it is depressurized. - - tweak: You now late-join spawn buckled to arrivals shuttle chairs - - tweak: Ghost spawn points have been moved to the center of the station - - tweak: Departing shuttles will now try and shut their docking airlocks - - bugfix: The arrivals shuttle airlocks are now properly cycle-linked - - bugfix: You can now hear hyperspace sounds outside of shuttles - - experiment: The map loader is faster - - tweak: Lavaland will now load instantly when the game starts - Jordie0608: - - tweak: The Banning Panel now organises search results into pages of 15 each. - XDTM: - - bugfix: Slimes can now properly latch onto humans. - - bugfix: Slimes won't aggro neutral mobs anymore. This includes blood-spawned gold - slime mobs. - - rscadd: Clicking on a tile with another tile and a crowbar in hand directly replaces - the tile. - Xhuis: - - imageadd: Ratvar and Nar-Sie now have fancy colored lighting! - coiax: - - rscadd: Wizards can now use their magic to make ghosts visible to haunt the crew, - and possibly attempt to betray the wizard. - - rscadd: When someone dies, if their body is no longer present, the (F) link will - instead jump to the turf they previously occupied. - - bugfix: Stacks of materials will automatically merge together when created. You - may notice differences when ejecting metal, glass or using the cash machine - in the vault. - - rscadd: You can find green and red glowsticks in YouTool vending machines. - fludd12: - - bugfix: Modifying/deconstructing skateboards while riding them no longer nails - you to the sky. - lordpidey: - - rscadd: Glitter bombs have been added to arcade prizes. -2017-03-11: - AnturK: - - rscadd: Traitors now have access to radio jammers for 10 TC - Hyena: - - bugfix: fixes anti toxin pill naming - Joan: - - tweak: Window construction steps are slightly faster; normal windows now take - 6 seconds with standard tools, from 7 and reinforced windows now take 12 seconds - with standard tools, from 14. - - tweak: Brass windows take 8 seconds with standard tools, from 7. - - rscadd: Added Shadowshrooms as a glowshroom mutation. They do exactly what you'd - expect. - - rscdel: Removed His Grace ascension. - PKPenguin321: - - tweak: Cryoxadone's ability to heal cloneloss has been greatly reduced. - - rscadd: Clonexadone has been readded. It functions exactly like cryoxadone, but - only heals cloneloss, and at a decent rate. Brew it with 1 part cryoxadone, - 1 part sodium, and 5 units of plasma for a catalyst. - Penguaro: - - tweak: Adjusted table locations - - tweak: Moved chair and Cargo Tech start location - - tweak: Moved filing cabinet - - rscdel: Removed Stock Computer - Tofa01: - - bugfix: '[Meta] Fixes Supermatter Shutters Not Working' - coiax: - - rscadd: Swarmer lights are coloured cyan. - kevinz000: - - bugfix: Deadchat no longer has huge amount of F's. -2017-03-12: - JStheguy: - - imageadd: Changed Desert Eagle sprites, changed .50 AE magazine sprites, added - Desert Eagle magazine overlay to icons/obj/guns/projectile.dmi. - - tweak: The empty Desert Eagle sprite now only displays on an empty chamber. The - existence or lack thereof of the magazine is rendered using an overlay instead. - Lzimann: - - tweak: Braindead has a more intuitive message - coiax: - - rscdel: A cloner that is EMP'd will merely eject the clone early, rather than - gibbing it. Emagging the cloner will still gib the clone. -2017-03-13: - Cyberboss: - - tweak: You must now be on any intent EXCEPT help to weld an airlock shut - - rscadd: You can now repair airlocks with welding tools on help intent (broken - airlocks still need their wires mended though) - Cyberboss, Bgobandit, and Yogstation: - - rscadd: The HoP can now prioritze roles for late-joiners - Every coder, player, and admin in Space Station 13: - - rscadd: Adds the Tomb Of The Unknown Employee to Central Command, - - rscadd: Rest in peace, those who died after contributing to Space Station 13. - Hyena: - - bugfix: Surplus leg r/l name fixed - - bugfix: You can now carry honey in plant bags - Lordpidey: - - bugfix: Devils can no longer break into areas with sheer force of disco funk - - rscadd: The pitchfork of an ascended devil can now break down walls. - - rscadd: Hell has decided to at least clothe it's devils when sending them a brand - new body. - - rscadd: Pitchforks glow red now. - Penguaro: - - rscdel: '**Engineering** - Removed Tables, paper bin, and pen' - - rscadd: '**Engineering** - Replaced with Welder and Electrical Lockers' - - rscadd: '**Engineering** - Moved First-Aid Burn kit to Engineering Foyer' - - tweak: '**Chapel** - Replaced one Window with Win-Door for Coffin Storage' - Space Bicycle Consortium: - - bugfix: Bicycles now only cost 10,000 yen, down from 1,000,000 yen. - coiax: - - rscadd: The egg spawner on Metastation will generate a station message and inform - the admins if an egg is spawned. (It's only a two percent chance, but live in - hope.) - - rscadd: Glowsticks can now be found in "Swarmer Cyan" colors. -2017-03-14: - Joan: - - rscadd: Shuttles now have dynamic lighting; you can remove the lights on them - and use your own lights. - - tweak: All maps now use Deltastation's fancy syndicate shuttle. - - tweak: Shadowshrooms of lower potency are much less able to blanket the station - in darkness. - PKPenguin321: - - tweak: Lattices now require wirecutters to deconstruct, rather than welding tools. -2017-03-15: - Cyberboss: - - bugfix: You can no longer depart on the arrivals shuttle by hiding inside things - Joan: - - tweak: Proselytizers converting clockwork floors to walls now always take 10 seconds, - regardless of how fast the proselytizer is. - - tweak: Clockwork grilles no longer provide CV. - Penguaro: - - bugfix: '**Engineering** - Changed Access Level from **24** (_Atmo_) to **10** - (_Engine_) on **Radiation Shutter Control**' - TrustyGun: - - tweak: Traitor Mimes with the finger guns spell now fire 3 bullets at a time, - as opposed to just 1. - octareenroon91: - - rscadd: Allow new reflector frames to be built from metal sheets. - oranges: - - rscdel: Removed patting -2017-03-16: - BASILMAN YOUR MAIN MAN: - - rscadd: The BM Speedwagon has been improved both in terms of aesthetics and performance! - Cyberboss: - - bugfix: The shield generators in Boxstation Xenobiology now have the correct access - Joan: - - rscadd: Cult structures that emitted light now have colored light. - MrPerson: - - rscadd: Humans can see in darkness slightly again. This is only so you can see - where you are when the lights go out. - MrStonedOne: - - bugfix: Fixed lighting not updating when a opaque object was deleted - Penguaro: - - tweak: Increased Synchronization Range on Exosuit Fabricator - Tofa01: - - bugfix: '[Delta] Fixes telecoms temperature and gas mixing / being contaminated.' - - bugfix: '[Delta] Fixes some doubled up turfs causing items and objects to get - stuck to stuff' - - tweak: '[Omega] Makes telecoms room cool down and be cold.' - Tokiko1: - - rscadd: Most gases now have unique effects when surrounding the supermatter crystal. - - tweak: The supermatter crystal can now take damage from too much energy and too - much gas. - - rscadd: Added a dangerous overcharged state to the supermatter crystal. - - rscadd: Readded explosion delaminations, a new tesla delamination and allowed - the singulo delamination to absorb the supermatter. - - tweak: The type of delamination now depends on the state of the supermatter crystal. - - tweak: Various supermatter engine rebalancing and fixes. - kevinz000: - - rscadd: SDQL2 now supports outputting proccalls to variables, and associative - lists - peoplearestrange: - - bugfix: Fixed buildmodes full tile window to be correct path - rock: - - tweak: if we can have glowsticks in toolvends why not flashlights amirite guys -2017-03-17: - BeeSting12: - - bugfix: Moved Metastation's deep fryer so that the chef can walk all the way around - the table. - Cobby: - - tweak: The gulag mineral ratio has been tweaked so there are PLENTY of iron ore, - nice bits of silver/plasma, with the negative of having less really high valued - ores. If you need minerals, it may be a good time to ask the warden now! - Joan: - - rscadd: You can now place lights and most wall objects on shuttles. - Xhuis: - - rscadd: Added the power flow control console, which allows remote manipulation - of most APCs on the z-level. You can find them in the Chief Engineer's office - on all maps. -2017-03-18: - Supermichael777: - - rscadd: Free golems can now buy new ids for 250 points. - XDTM: - - rscadd: You can now complete a golem shell with runed metal, if you somehow manage - to get both. - - rscadd: Runic golems don't have passive bonuses over golems, but they have some - special abilities. - coiax: - - bugfix: The alert level is no longer lowered by a nuke's detonation. -2017-03-19: - BeeSting12: - - rscadd: Nanotrasen has decided to better equip the box-class emergency shuttles - with a recharger on a table in the cockpit. - Cheridan: - - tweak: The slime created by a pyroclastic anomaly detonating is now adult and - player-controlled! Reminder that if you see an anomaly alert, you should grab - an analyzer and head to the announced location to scan it, and then signal the - given frequency on a signaller! - Penguaro: - - bugfix: change access variables for turrets and shield gens - - bugfix: Box Station - Replaces the smiling table grilles with their more serious - counterparts. - coiax: - - tweak: The Syndicate lavaland base now has a single self destruct bomb located - next to the Communications Room. Guaranteed destruction of the base is guaranteed - by payloads embedded in the walls. - octareenroon91: - - bugfix: Fixes infinite vaping bug. - uraniummeltdown: - - rscadd: Plant data disks have new sprites. - - bugfix: Fixed Monkey Recycler board not showing in Circuit Imprinter - - tweak: Kinetic Accelerator Range Mod now takes up 25% space instead of 24% -2017-03-21: - ExcessiveUseOfCobblestone: - - experiment: All core traits [Hydroponics] scale with the parts in the gene machine. - Time to beg Duke's Guide Read.... I mean RND! - - tweak: Data disks with genes on them will have just the name of the gene instead - of the prefix "plant data disk". - - tweak: If you were unaware, you can rename these disks with a pen. Now, you can - also change the description if you felt inclined to. - Joan: - - experiment: Caches produce components every 70 seconds, from every 90, but each - other linked, component-producing cache slows down cache generation by 10 seconds. - Lombardo2: - - rscadd: The tentacle changeling mutation now changes the arm appearance when activated. - MrPerson: - - bugfix: Everyone's eyes aren't white anymore. - Penguaro: - - tweak: Box Station - The Vents and Scrubbers for the Supermatter Air Alarm are - now isolated from the rest of the Air Alarms in Engineering. - Supermichael777: - - bugfix: Chasms now smooth properly. - Tokiko1: - - tweak: Minor supermatter balancing changes. - - tweak: Supermatter now announces its damage half as frequently. - - tweak: Badly unstable supermatter now occasionally zaps nearby engineers and causes - anomalies to appear nearby, similar to overcharged supermatter. - XDTM: - - rscadd: Golem Shells can now be completed with medical gauze or cloth to form - cloth golems, which are weaker and extremely flammable. However, if they die, - they turn into a pile of cloth that will eventually re-animate back into full - health. That is, unless someone lights it on fire. -2017-03-22: - BeeSting12: - - rscadd: Added an autolathe circuit board to deltastation's tech storage. - - rscadd: Added 49 sheets of metal to deltastation's auxiliary tool storage. - Iamgoofball: - - bugfix: Freon no longer bypasses atmos hardsuits. - Penguaro: - - rscadd: Meta - Added Tool Belts to Engineering and Engineering Foyer - - rscdel: Meta - Removed Coffee Machine from Permabrig - - rscadd: Added Cameras for Supermatter Chamber (to view rad collectors and crystal) - - tweak: Adjusted Engine Camera Names for Station Consistency - - bugfix: Adjusted Monitor Names / Networks to view the Engine Cameras - coiax: - - rscadd: APCs now glow faintly with their charging lights. So red is not charging, - blue is charging, green is full. Emagged APCs are also blue. Broken APCs do - not emit light. - - rscadd: Alien glowing resin now glows. -2017-03-23: - Joan: - - tweak: Clock cults always have to summon Ratvar, but that always involves a proselytization - burst. - - rscdel: The proselytization burst will no longer convert heretics, leaving Ratvar - free to chase them down. - - spellcheck: Places that referred to the Ark of the Clockwork Justicar as the "Gateway - to the Celestial Derelict" have been corrected to always refer to the Ark. - Penguaro: - - bugfix: Wizard Ship - Bolts that floating light to the wall. - XDTM: - - rscadd: Medical Gauze now stacks up to 12 - - bugfix: Pressure plates are now craftable. - bgobandit: - - tweak: Alt-clicking a command headset toggles HIGH VOLUME mode. - coiax: - - bugfix: A dead AI no longer counts as an "unconverted AI" for clockcult. -2017-03-24: - BeeSting12: - - bugfix: Auxiliary base maintenance airlock now requires the proper access. Sorry - greyshirts, no loot for you! - Cyberboss: - - tweak: The recycler's base reclaim rate has been buffed from 1% to 50%. Manipulator - upgrades now give +12.5% per level instead of +25% - - bugfix: You can now successfully remove a pen from a PDA while it's in a container - Fox McCloud: - - rscadd: Modular receiver removed from the protolathe to autolathe - - tweak: Modular receiver cost is now 15,000 metal - Joan: - - bugfix: Fixes structures being unable to go through spatial gateways. - - tweak: Blazing Oil blobs take 33% less damage from water. - Penguaro: - - rscadd: '[Meta] Replaced Power Monitoring Console in Engineering with Modular - Engineering Console' - - rscadd: '[Pubby] Replaced Power Monitoring Console in Engineering with Modular - Engineering Console' - - rscadd: '[Omega] Replaced Power Monitoring Console in Engineering with Modular - Engineering Console' - - rscadd: '[Omega] Added RD and Command Modular Consoles to Bridge' - - rscadd: '[Delta] Replaced Power Monitoring Console in Engineering with Modular - Engineering Console' - - rscadd: '[Delta] Replaced duplicate Atmospherics Monitoring Console in Atmo with - Modular Engineering Console' - coiax: - - rscadd: Destroying a lich's body does not destroy the lich permanently, provided - the phylactery is intact. - - rscadd: A lich will respawn three minutes after its death, provided the phylactery - is intact. - - rscadd: The Soul Bind spell is forgotten after cast, respawn is now automatic. - - rscdel: Stationloving objects like the nuke disk are not valid objects for a phylactery. - - rscadd: Explosive implants can always be triggered via action button, even if - unconscious. - rock: - - tweak: lizards are hurt slightly more by cold but less by heat. this does not - mean they are more resistant to being lasered, fortunately. -2017-03-26: - BeeSting12: - - spellcheck: The bar shuttle's buckable bar stools are now buckleable bar stools. - Gun Hog and Shadowlight213: - - rscadd: The AI may now deploy to cyborgs prepared as AI shells. The module to - do this may be research in the exosuit fabricator. Simply slot the module into - a completed cyborg frame as with an MMI, or into a playerless (with no ckey) - cyborg. - - rscadd: AI shells and AIs controlling a shell can be determined through the Diagnostic - HUD. - - rscadd: AIs can deploy to a shell using the new action buttons or by simply clicking - on it. - - experiment: An AI shell will always have the laws of its controlling AI. - Penguaro: - - rscadd: Brig - Added Air Alarm - - rscdel: Engineering - Removed Brig Shutter - - tweak: Omega, Meta, & Delta Stations - The Vents and Scrubbers for the Supermatter - Air Alarm are now isolated from the rest of the Air Alarms in Engineering. - Qbopper: - - spellcheck: Drones are now given OOC guidelines to follow as well as their IC - lawset. - Robustin: - - rscadd: Added the prototype canister with expanded volume, valve pressure, and - access/timer features - TrustyGun: - - bugfix: Deconstructing display cases and coffins now drop the correct amount of - wood. - XDTM: - - tweak: Some golems now spawn with more thematic names. - - tweak: Adamantine Golems are no longer numbered, but receive a random golem name. - - bugfix: Airlocks properly remove the shock overlay when a temporary shock runs - out. - coiax: - - bugfix: Teams playing CTF have their own radio channels, rather than using the - Centcom and Syndicate channels. - - bugfix: Actually actually makes CTF barricades repair between rounds. - - bugfix: Blue CTF lasers have little blue effects when they hit things, rather - than red effects. -2017-03-28: - Supermichael777: - - rscadd: Backup operatives now get the nukes code. - XDTM: - - bugfix: Wooden tiles can now be quick-replaced with a screwdriver instead of a - crowbar, preserving the floor tile. - octareenroon91: - - bugfix: Bonfires that have a metal rod added should buckle instead of runtiming. -2017-03-29: - BeeSting12: - - rscadd: Adds emergency launch console to the backup emergency shuttle. - Joan: - - rscdel: Putting sec armour and a helmet on a corgi no longer makes the corgi immune - to item attacks. - - rscadd: All items with armour will now grant corgis actual armour. - Kevinz000: - - rscadd: High-powered floodlights may be constructed with 5 sheets of metal, a - wrench, a screwdriver, 5 cable coils, and a light tube. They require a powernet - connection via direct wire node. - coiax: - - bugfix: All tophats, rather than just the ones in maintenance, hurt a tiny bit - if you throw them at people. - - bugfix: Supermatter anomalies are more shortlived than regular anomalies, as intended. -2017-03-30: - coiax: - - rscadd: Autoimplanters have been renamed to autosurgeons. Currently only the CMO - and nuclear operatives have access to autosurgeons. What is the CMO hiding? - - bugfix: All upgraded organs for purchase by nuclear operatives now actually come - in an autosurgeon, for speed of surgery. -2017-03-31: - Cobby: - - tweak: Shot glasses are now more ambiguous [EASIER TO MAINTAIN] - Cyberboss: - - bugfix: Temperature changes will now properly cause atmospherics simulation to - activate - - bugfix: The command report for random xeno eggs will now be delivered along with - the rest of the roundstart reports - - bugfix: Drones can no longer be irradiated -2017-04-01: - Cyberboss: - - bugfix: The contents of the shelterpod smart fridge work again - XDTM: - - bugfix: Facehuggers no longer rip masks from people protected by helmets. -2017-04-02: - BeeSting12: - - bugfix: Metastation's northeast radiation collector is now connected to the grid. - Nanotrasen would like to apologize for any inconvenience caused to engineers, - but copper is expensive. - - rscadd: Boxstation's HoP office now has a PDA tech. - Cyberboss: - - tweak: Firedoors no longer operate automatically without power - - bugfix: Blood and other decals will no longer remain on turfs they shouldn't - - bugfix: The splashscreen is working again - - bugfix: False alarms are now guaranteed to actually announce something - Incoming5643: - - rscadd: Lighting visuals have been changed slightly to reduce it's cost to the - client. If you had trouble running the new lighting, it might run a little better - now. - MMMiracles (CereStation): - - rscadd: Added a patrol path for bots, includes 2 round-start securitrons placed - on opposite sites of station. - - wip: Due to map size, mulebots are still somewhat unreliable on longer distances. - Disposals are still advised, but mule bots are now technically an option for - delivery. - - rscadd: Added multiple status displays, extinguishers, and appropriate newscasters - to hallways. - - rscadd: A drone dispenser is now located underneath Engineering in maintenance. - - rscadd: Each security checkpoint now has a disposal chute that directs to a waiting - cell in the Brig for rapid processing of criminals. Why run half-way across - the station with some petty thief when you can just shove him in the criminal - chute and have the warden deal with him? - - tweak: Security's mail chute no longer leads into the armory. This was probably - not the best idea in hindsight. - - tweak: Virology has a bathroom now. - - tweak: Genetics monkey pen is a bit more green now. - - bugfix: Lawyer now has access the brig cells so he can complain more effectively. - - bugfix: Xenobio kill chamber is now in range of a camera. - - bugfix: Removed rogue bits of Vault area. - - bugfix: Medbay escape pod no longer juts out far enough to block the disposal's - path. - - bugfix: Captain's spare ID is now real and not just a gold ID card. - Penguaro: - - tweak: '[Meta] The Chapel Security Hatches were very intimidating. They have been - changed to more inviting glass doors.' - - bugfix: '[Meta] The maintenance tunnels in the Xeno Lab now have radiation shielding. - The Slime Euthanization Chamber will not have radiation shielding at this time - as dead slimes will not mind radiation.' - coiax: - - rscadd: Adds seperate languages to the game. Now Ratvarian, Drone, Machine, Swarmer, - Human (now called Galactic Common), Slime and Monkey are separate languages. - Each languages has its own comma prefix, for example, Galcom has the ,0 prefix, - while Ratvarian has the ,r prefix. If you don't understand a language when it - is spoken to you, you will hear a scrambled version that will vary depending - on the language that you're not understanding. - - experiment: This does not change who can understand what. - - rscdel: Removed the talk wheel feature. - - rscadd: Clicking the speech bubble icon now opens the Language Menu, allowing - you to review which languages you speak, their keys, and letting you set which - language you speak by default. Admins have additional abilities to add and remove - languages from mobs using this menu. - ktccd: - - bugfix: Ninja suits have received a new software update, making them able to **actually - steal tech levels** from R&D consoles and servers, thus avoid being forced to - honourably kill themselves for failing their objective. -2017-04-05: - Cyberboss: - - bugfix: Cardboard boxes and bodybags can no longer be anchored - Penguaro: - - rscadd: '[Box] A fire alarm has been added to the Lawyer''s office.' - - rscadd: '[Box] Adds access for Scientists to Starboard Maintenance Areas outside - of Toxins.' - - tweak: '[Box] Adjusted Science doors to more logical access codes.' - QV: - - bugfix: Fixed taking max suffocation damage whenever oxygen was slightly low - RemieRichards: - - bugfix: Using TK on the supermatter will burn your head off violently, don't do - this. - - rscadd: 'Examining clothing with pockets will now give information about the pockets: - number of slots, how it is interacted with (backpack, etc.), if it has quickdraw - (Alt-Click) support and whether or not it is silent to interact with.' - coiax: - - bugfix: Emergency shuttles will now forget early launch authorizations if they - cannot launch due to a hostile environment. -2017-04-07: - Qbopper: - - bugfix: Secure lockers will no longer have multiple lines about being broken. -2017-04-09: - 4dplanner: - - bugfix: Gas analyzers can now detect more gases in pipes - Joan: - - bugfix: Fixed a bug where getting caught between two shield generators as they - activated wouldn't cause you to gib and die. - QV: - - tweak: Refactored the way limbs that aren't limbs work - octareenroon91: - - bugfix: Hackable wires should work as intended again. -2017-04-11: - BeeSting12: - - spellcheck: '"the herpes of arts and crafts" is now "The herpes of arts and crafts."' - Cyberboss: - - bugfix: Runes no longer make you/themselves/random atoms yuge - JJRcop: - - tweak: Refactors whisper, now all living mobs can use it - - rscadd: 'Prefix any message with # to whisper, for example, "# Man, that guy is - weird.", you can still use the whisper verb if you whish.' - - rscadd: This is compatible with languages, for example "#,r That HoS is a problem, - we should kill him" - - rscdel: 'Removes #a #b #c etc radio codes, as well as :w and .w, which used to - be whisper.' - MrStonedOne: - - tweak: Nightvision was heavily modified. - - rscadd: Nightvision has been given 3 levels of nightvisionness. (some, most, and - full) - - tweak: ghosts, aliens, guardians, night vision eyes, and statues were given all - 3 levels in a cycling toggle - - tweak: thermals, and hud+NV goggles give "some" nightvisionness - - tweak: standalone masons are unchanged. - - tweak: Nightvision goggles (that aren't also sec huds or medhuds or the like) - give "most" nightvisionness. Nightvision masons also give "most" nightvisionness - - tweak: Most simple mobs with the ability to see in the dark were given "most" - nightvisionness, others got full nightvisionness. - - bugfix: Fixed certain ghost only things disappearing when disabling darkness. - - bugfix: Fixed ash storms not being visible when using things that modified your - ability to see darkness - - bugfix: fix a bug with the new github web processor - Shadowlight213: - - bugfix: The anime admin button will no longer cause equipped items to drop. - coiax: - - rscadd: Examining a ghost determines whether it is visible. -2017-04-13: - Cyberboss: - - bugfix: Fixed the incorrectly named Brig APC on Box Station= - - spellcheck: Fixed simple animal attack grammar - - bugfix: Roundstart department head announcements have been fixed - - bugfix: Brig cell doors now properly require the correct access - - bugfix: Fixed a bug preventing chameleon stamps from being picked up - - bugfix: Fixed a bug where honey frames couldn't be picked up - - bugfix: Photocopied papers will now retain their stamps - Davidj361: - - bugfix: Made it so chemsprayers, peppersprays, extinguishers don't spray when - you click your inventory items - - bugfix: Spray guns now actually have their range change when changing modes between - spray and stream - - bugfix: Krav maga now gets its abilities toggled if you click the same ability - twice - - bugfix: Added a link to the bottom right of paper when writing that shows help - for paper writing - - bugfix: Fixed the shift+middle-click pointing shortcut to work for cyborgs as - the functionality wasn't even there - - bugfix: Bodies in body bags get cremated properly now - RemieRichards: - - bugfix: Constructing lattice no longer prevents space transitions. - Robustin: - - rscadd: Ranged RCD added to the game - - rscadd: Rapid Lighting Device (also ranged) has been added. It can create wall, - floor, and temporary lights of any color you desire. - coiax: - - bugfix: Cigarette branding has been fixed. - - rscadd: Uplift Smooth brand cigarettes now taste minty as advertised. - - rscdel: You can no longer inject cigarette packets to inject all cigarettes simultaneously. - powergaming research director: - - bugfix: woops i dropped the emp protection module when i made your cns rebooters - today, guess they're vulnerable again! -2017-04-15: - Cyberboss: - - bugfix: Holopads can no longer be interacted with while unpowered - Davidj361: - - bugfix: Monkeys won't pickup items or rob you while they are in your stomach, - neither walk out of your stomach. - - bugfix: You can't cheat with eyewear/eye-implants when using advanced cameras - - bugfix: Mutant digitigrade legs re-added to the ashwalker species - Robustin: - - rscadd: The Prototype Emitter, will function like an ordinary emitter while also - charging a secondary power supply that will allow a buckled user to manually - fire the emitter. Returning to automatic fire will have the emitter continue - to fire at the last target struck by manual fire. - - rscadd: The Engineering Dance Machine, along with assorted effects/sounds. - coiax: - - bugfix: Plasmamen no longer burn to death while inside a cloning pod. -2017-04-18: - BeeSting12: - - bugfix: Cerestation's shuttle now has a recharger. - - rscdel: Centcomm's thunderdome airlocks have been removed due to contestants breaking - out. - - bugfix: Deltastation's chemistry lab now has a pill bottle closet. - - bugfix: The shield wall generators in xenobiology on Deltastation, Boxstation, - Metastation, and Pubbystation can now be locked and unlocked by scientists. - Davidj361: - - bugfix: Spawned humans no longer spawn eyeless (sprite) - MMMiracles (Cerestation): - - rscadd: Departments have been given head offices for a more secure place to chill - in their departments. - - rscadd: There is now a theatre on the service asteroid. - - tweak: Maintenance visuals and loot have been overhauled to be more visually interesting - and have more scattered bits of loot. - - bugfix: Various fixes with missing APCs, camera coverage, and misc things. - QualityVan: - - rscadd: Some foam guns can now be suppressed - coiax: - - rscadd: Drone, monkey and swarmer language now have distinctive colours when spoken. - - rscadd: Since drones are allowed to interact with pAIs, pAIs in mobile chassis - form are no longer distorted to drone viewpoints. - - bugfix: The shuttle's arrival can no longer be delayed after Nar-Sie's arrival. - The End cannot be delayed. -2017-04-19: - QualityVan: - - bugfix: Improved stethoscopes - Thunder12345: - - bugfix: You can no longer extract negative sheets from the ORM - XDTM: - - bugfix: APCs hacked by a malfunctioning AI are no longer immune to alien attacks. - - bugfix: Fixed bug where flashlight eyes weren't emitting light. -2017-04-20: - Cyberboss: - - bugfix: Fixed mining closets having extra, unrelated items -2017-04-22: - Cyberboss: - - bugfix: Conveyors no longer move things they aren't supposed to - XDTM: - - bugfix: Gold and Light Pink slime extracts no longer disappear before working. - coiax: - - bugfix: Fixed people understanding languages over the radio when they shouldn't. -2017-04-23: - coiax: - - rscadd: Centcom would like to inform all employees that they have ears. - - rscadd: Adds "ear" organs to all carbons. These organs store ear damage and deafness. - A carbon without any ears is deaf. Genetic deafness functions as before. -2017-04-25: - BeeSting12: - - bugfix: Deltastation's secure tech storage is no longer all access. - CoreOverload: - - bugfix: Disposals no longer get broken by shuttles rotation. - - bugfix: Wires no longer get broken by shuttles movement and rotation. - - bugfix: Atmospheric equipment no longer gets broken by shuttles movement and rotation. - Glory to the Flying Fortress of Atmosia! - Jalleo: - - rscdel: WW_maze from lavaland has been removed it wasnt that good really anyhow - QualityVan: - - bugfix: Changeling brains are now more fully vestigial - WJohnston: - - tweak: Skeletons and plasmamen's hitboxes now more closely match that of humans. - They are no longer full of holes and incredibly frustrating to hit, should they - run around naked. - XDTM: - - bugfix: Items will no longer be used on backpacks if they fail to insert when - they're too full. - - bugfix: T-Ray scans are no longer visible to bystanders. - - bugfix: T-Ray scans no longer allow viewers to interact with underfloor objects. - basilman: - - bugfix: fixed species with no skin dropping skin when gibbed. - coiax: - - rscadd: Examining a window now gives hints to the appropriate tool for the next - stage of construction/deconstruction. - - rscadd: You can examine a firedoor for hints on how to construct/deconstruct it. - - rscadd: Add an additional hint during construction where you can add plasteel - to make the firedoor reinforced. - - bugfix: Fixed easter eggs spawning during non-Easter. - - bugfix: Fixes stations not having holiday specific prefixes during the holidays. - - bugfix: Ghosts no longer drift in space. - - bugfix: Swarmers now only speak their own language, rather than swarmer and common. - - bugfix: When you are crushed by a door, it prints a visible message, instead of, - in some cases, silently damaging you. - - bugfix: The vent in the Escape Coridoor on Omega Station has been fixed. - - bugfix: You no longer die when turning into a monkey. - coiax, WJohnston: - - rscadd: Plasmamen lungs, also known as "plasma filters" now look different from - human lungs. - - rscadd: Plasmamen now have their own special type of bone tongue. They still sound - the same, it's just purple. Like them. -2017-04-26: - CoreOverload: - - rscadd: Gas injectors are now buildable! - Joan: - - tweak: Ash Drake swoops no longer teleport the Ash Drake to your position. - - balance: Some other tweaks to Ash Drake attacks and patterns; discover these yourself! - coiax: - - balance: The wizard spell Rod Form now costs 3 points, up from 2. - flashdim: - - bugfix: Omega Station had two APCs not wired properly. (#26526) -2017-04-27: - Gun Hog: - - rscadd: The GPS interface has been converted to tgui. - - experiment: GPS now update automatically or manually, give distance and direction - to a signal, and many other improvements! - MrStonedOne: - - tweak: Tweaked how things were deleted to cut down on lag from consecutive deletes - and provide better logging for things that cause lag when hard-deleted. - - tweak: Server hop verb moved to the OOC tab - - rscadd: Server hop verb can now be used in the lobby as well as while a ghost. - QualityVan: - - bugfix: You can hit emagged cloning pods with a medical ID to empty them - - rscadd: Crayons can be ground - - rscadd: Crayon powder can be used to color stuff - Shadowlight213: - - tweak: Heads of staff may now download the ID card modification program from NTNet. - bgobandit: - - tweak: When jumpsuits take severe damage, their suit sensors break. They can be - fixed by applying a cable coil. - coiax: - - rscadd: Anomalous crystals can be examined by ghosts to determine their function - and activation method. - - rscdel: Lightbringers can understand Slime and Galactic Common, and can only speak - Slime, as before. - - rscadd: The helper anomalous crystal is in the orbit list after it has been activated. -2017-04-28: - Kor: - - rscadd: Librarians can speak any language - coiax, WJohnston: - - rscdel: Languages no longer colour their text. - - rscadd: Languages now have icons to identify them. Galatic Common does not have - an icon if understood. -2017-04-29: - BeeSting12: - - bugfix: The emergency backup shuttle has lighting now. - - bugfix: Plating in deltastation's aux tool storage is no longer checkered. - Cobby: - - rscadd: Syndicate Lavabase now has more explicit instructions when it comes to - outing non-syndicate affiliated enemies of Nanotrasen. - - tweak: The GPS set tag has gone from a limit of 5 characters to 20. - - rscadd: The GPS can now be personalized in both name and description using a pen. - Joan: - - rscdel: Removed Mending Motor. - - rscadd: Added Mending Mantra, which is a script that causes you to repair nearby - constructs and structures as long as you continue chanting it. - - tweak: Mending Mantra will also heal Servants as long as they're wearing clockwork - armor. - Kor: - - rscdel: Removed double agents mode. - - rscadd: Replaced it with Internal Affairs mode. - Swindly: - - rscadd: Added organ storage bags for medical cyborgs. They can hold an organic - body part. Use the bag on a carbon during organ manipulation or prosthetic replacement - to add the held body part. - coiax: - - rscdel: Swarmer traps are no longer summoned by The Traps. - - balance: Wizard traps automatically disappear five minutes after being summoned. - - balance: Wizard traps disappear after firing, whether triggered via person or - something being thrown across it. - - balance: Wizards are immune to their own traps. - - tweak: The Traps are now marked as a Defensive spell, rather than an Offensive - spell. - kevinz000: - - experiment: Songs can now be added to disco machines with add_track(file, name, - length, beat). Only file is required, the other 3 should still be put in, though. - tacolizard forever: - - bugfix: Rechargers no longer flash the 'fully charged' animation before charging - something -2017-04-30: - QualityVan: - - bugfix: Changelings can once again revive with their brain missing - XDTM: - - rscdel: Voice of God's Rest command now no longer makes listeners rest. It instead - activates the sleep command. - coiax: - - rscadd: The Bank Machine in the vault now uses the radio to announce unauthorized - withdrawals, rather than an endless stream of loud announcements. -2017-05-01: - 4dplanner: - - tweak: Syndicate surplus crates now contain fewer implants - Bawhoppen: - - rscadd: Deep storage space ruin has been readded. - - rscadd: Space Cola machines now stock bottles of water. - Cobby: - - balance: The Gang pen is now stealthy. Stab away! - Cyberboss: - - rscadd: You can now make holocalls! Simply stand on a pad, bring up the menu, - and select the holopad you wish to call. Remain still until someone answers. - When they do, you'll be able to act just like an AI hologram until the call - ends - Joan: - - rscadd: Belligerent now prevents you from running for 7 seconds after every chant. - - rscdel: However, you no longer remain walking after Belligerent's effect fades. - - rscadd: Clockcult component generation will automatically focus on components - needed to activate the Ark if it exists. - - rscadd: Gaining Vanguard, such as from the Linked Vanguard scripture, will remove - existing stuns. - - rscadd: Proselytizers can now charge from Sigils of Transmission at a rate of - 1000W per second. - - rscadd: Sigils of Transmission can be charged with brass at a rate of 250W per - sheet. - Moonlighting Mac says: - - bugfix: Due to a clerical error in the chef's cookbooks now being resolved, you - can now make the pristine cookery dish "Stuffed Legion" out of exotic ingredients - from Lavaland. - - experiment: After being found again you will now be able to enjoy its special - blend of flavors with your tastebuds. Mmm. - QualityVan: - - tweak: Saline glucose now acts as temporary blood instead of increasing blood - regeneration - Swindly: - - tweak: Mercury and Lithium make people move when not in space instead of when - in space. - ninjanomnom: - - tweak: TEG displays power in kw or MW now - - tweak: TEG power bar only maxes over 1MW now - - experiment: Moves TEG to SSair - - experiment: Moves SM to SSair -2017-05-02: - 4dplanner: - - bugfix: Squishy plants will now affect walls and other turfs they get squished - on - Kor, Goof and Plizzard: - - rscadd: Adds persistent trophy cases. They are not on any map yet. - Shadowlight213: - - bugfix: The biogenerator will now show its recipes again. - XDTM: - - tweak: Blood Cult's talisman of Horrors now works at range. It will still give - no warning to the victim. - - rscadd: Golems can now click on empty golem shells to transfer into them. - - tweak: Plasma Golems now no longer explode on death. They instead explode if they're - on fire and are hot enough. The explosion size has been increased. - - tweak: Plasma Golems are now always flammable. - coiax: - - rscadd: When talking on the alien hivemind, a person will be identified by their - real name, rather than who they are disguised as. -2017-05-03: - BeeSting12: - - bugfix: Omega shuttle now has lighting. - Joan: - - balance: Clockwork component generation is twice as fast. - - balance: Scriptures cost up to twice as much; Driver scriptures are unaffected, - meaning they cost 50% less, Script scriptures cost 25% less, Application scriptures - cost about 12.5% less, and Revenant scriptures cost about 5% less. - Jordie0608: - - rscadd: Investigate logs are now persistent. - - tweak: Game logs are now stored per-round; use .getserverlog to access previous - rounds. - - rscdel: .giveruntimelog and .getruntimelog removed. - Kor, Profakos, Iamgoofball: - - rscadd: The Librarian has been replaced by the Curator. - - rscadd: Persistent trophy cases have been added to the library on Meta, Delta, - and Box. These are only usable by the Curator. - - rscadd: The Curator now starts with his whip. - - rscadd: The Curator now has access to his treasure hunter outfit, stashed in his - private office. - coiax: - - balance: Plasma vessels, the organs inside aliens that are responsible for their - internal plasma storage, will regenerate small amounts of plasma even if the - owner is not on resin weeds. - - rscadd: Restrictions on Lizardpeople using their native language on the station - have been lifted by Centcom, in order to maximise worker productivity. The language's - key is ",o". - deathride58: - - tweak: Fixed the slimecore HUD's neck slot sprite. -2017-05-04: - 4dplanner: - - bugfix: revenants now properly resurrect from ectoplasm, as opposed to ectoplasm - merely spawning a new grief ghost - - bugfix: Turrets can no longer see invisible things, such as unrevealed revenants - Joan: - - rscadd: Mania Motors now do minor toxin damage over time and will convert those - affected if the toxin damage is high enough. - - balance: The effects of a Mania Motor continue to apply to targets after they - leave its range, though they will fall off extremely quickly. - - rscdel: Mania Motors no longer cause brain damage. - - imageadd: Ratvarian Spears have new inhand icons. - Lzimann: - - rscdel: Gang game mode was removed - Moonlighting Mac says: - - rscadd: Courtesy of the art & crafts division, imitation basalt tiles themed on - the rough volcanic terrain of lavaland are now available to be made out of sandstone. - - experiment: The manufacturer even managed to replicate the way that it lights - up with volcanic energy, it is the perfect accompaniment to other fake (or real) - lava-land tiles or a independent piece. - QualityVan: - - rscadd: Point flashlights at mouths to see what's inside them -2017-05-05: - Incoming: - - tweak: Display cases now require a key to open, which the curator spawns with - Joan: - - balance: Sigil of Accession, Fellowship Armory, Memory Allocation, Anima Fragment, - and Sigil of Transmission are not affected by the previously-mentioned % reduction - to Application scripture costs. - LanCartwright: - - rscadd: Lesser smoke book to Delta and Metastation - - rscdel: Normal smoke book from Delta and Metastation - - tweak: Civilian smoke book now has a 360 max cooldown (from 120) and halved smoke - output. - QualityVan: - - bugfix: Dental implants stay with the head they're in - bgobandit: - - tweak: The Syndicate has added basic functionality to their state-of-the-art equipment. - Nuke ops can now donate all TCs at once. - lordpidey: - - rscadd: There is a new traitor poison, spewium. It will cause uncontrollable - vomiting, which gets worse the longer it's in your system. An overdose can - cause vomiting of organs. - - tweak: Committing suicide with a gas pump can now shoot out random organs. - - bugfix: Toxic vomit now shows up as intended. -2017-05-06: - 4dplanner: - - rscadd: Internal Affairs Agents now obtain the kill objectives of their targets - when they die. - - rscadd: Internal Affairs Agents now have an integrated nanotrasen pinpointer that - tracks their target at distances further than ten squares. - - rscadd: Internal Affairs Agents will now lose any restrictions on collateral damage - and gain a "Die a glorious death" objective upon becoming the last man standing, - and revert if any of their targets are cloned. - BeeSting12: - - bugfix: Pubbystation no longer has two airlocks stacked on top of each other leading - into xenobiology's kill room. - - rscadd: Deltastation's chemistry now has a screwdriver. - - bugfix: Deltastation's morgue no longer has a blue tile. - - bugfix: Deltastation's chemistry smart fridge is no longer blocked by a disposal - unit. - Cyberboss: - - tweak: Teslas now give off light - Joan: - - balance: Sigils of Transgression are slightly more visible and glow very faintly. - LanCartwright: - - rscadd: Reduction to nutrition when consuming Miner's salve. - - rscdel: Stun/weaken that bypasses bugged chemical protection when consuming Miner's - salve. - Lzimann: - - rscdel: Telescience is no more. - PKPenguin321: - - rscadd: Undid the gang gamemode removal. - QualityVan: - - rscadd: Cargo can order restocking units for NanoMed vending machines - - rscadd: NanoMed vending machines can be build and unbuilt - Robustin: - - rscadd: Blood Cultists can now attempt to claim the position of Cult Master with - the approval of a majority of their brethren. - - rscadd: 'The Cult Master has access to unique blood magic that will aid them in - leading the cult to victory:' - - rscadd: The Cult Master can mark targets, allowing the entire cult to track them - down. - - rscadd: The Cult Master has single-use, noisy, and overt channeled spell that - will summon the entire cult to their location. - - rscadd: All cultists gain a HUD alert that will assist them in completing their - objectives. - - rscadd: Constructs created by soul shards will now be able to track their master. - - rscadd: Cultists created outside of cult mode will now get a working sacrifice - and summon objective and the summon rune will no longer fail outside of cult - mode. - - tweak: Gang Dominator max time is now 8 minutes down from 15m - - tweak: Gang Tagging now reduces the timer by 9 seconds per territory, down from - 12 seconds. - coiax: - - rscadd: Adamantine golems have special vocal cords that allow them to send one-way - messages to all golems, due to fragments of resonating adamantine in their heads. - Both of these are organs, and can be removed and put in other species. - - rscadd: You can use adamantine vocal cords by prefixing your message with ":x". - - rscdel: Xenobiology is no longer capable of making golem runes with plasma. Instead, - inject plasma into the adamantine slime core to get bars of adamantine which - you can then craft into an incomplete golem shell. Add 10 sheets of suitable - material to finish the shell. - - experiment: The metal adamantine is also quite valuable when sold via cargo. - - bugfix: If you know more than the usual number of languages, you'll now remember - them after you get cloned. - - rscdel: Humans turning into monkeys will not suddenly be able to speak the monkey - language, and will continue to understand and speak human. - - rscadd: Ghosts can now modify their own understood languages with the language - menu. - - rscadd: Any mob can also open their language menu with the IC->Open Language Menu - verb. - - rscadd: Silicons can now understand Draconic as part of their internal databases. - - bugfix: Golems no longer have underwear, undershorts or socks. - - tweak: The lavaland Seed Vault ruin can spawn only once. - - rscadd: It is now possible to make plastic golems, who are made of a material - flexible enough to crawl through vents (while not carrying equipment). They - also can pass through plastic flaps. - - bugfix: Fixed adamantine vocal cord (F) links not working for observers. -2017-05-07: - Anonmare: - - tweak: Removes organic check from mediborg storage container - Joan: - - rscadd: Cultists of Nar-sie have their own language. The language's key is ",n". - - balance: Sigils of Transgression are slightly brighter. - Moonlighting Mac: - - experiment: Due to budget cuts and oil synthesis replacing expensive processes - of digging up haunted primeval ashwalker burial grounds, Nanotransen has taught - chemists how to make plastic from chemicals in the hopes that new plastic products - can reduce expenditure on metal and glass. - - rscadd: you can now make plastic sheets from chemistry out of heated up crude - oil, ash & sodium chloride - MrStonedOne: - - bugfix: fixed bug that caused an infinite connection loop when connecting on a - new computer or computer with recently changed hardware. - - rscadd: Moved to a new system to make top menu items easier to edit. - - tweak: Moved icon size stuff to a sub menu - - rscadd: Added option to change icon scaling mode. - - bugfix: Byond added fancy shader supported scaling(Point Sampling), this sucks - because it's blurry, the default for /tg/station has changed back to the old - nearest neighbor scaling. - Penguaro: - - bugfix: Adjusted the Examine description of the right-most tiles of the Space - Station 13 sign to be consistent with the rest of the tiles. - - bugfix: Anywhere there was lava below a tile on the station is now space. - Robustin: - - tweak: c4 planting is now 40% faster - coiax: - - bugfix: Smartfridges no longer magically gain medicines if deconstructed and rebuilt. - - rscadd: Ash walkers now know and speak Draconic by default, but still know Galactic - Common. Remember, Galcom's language key is ",0" and you can review your known - languages with the Language Menu. - octareenroon91: - - rscadd: Showers and sinks added to gulag and mining station for hygiene and fire - safety. - - rscadd: Watertanks added to mining station for convenient fire extinguisher refill. -2017-05-08: - Dorsisdwarf: - - bugfix: Fixed being unable to hit museum cases in melee - Joan: - - tweak: The verb to Assert Leadership over the cult has been replaced with an action - button that does the same thing, but is much more visible. - Moonlighting Mac says: - - tweak: After a recent trade fair, employees have took it upon themselves to learn - how to craft leather objects out of finished leather sheets, for novices they - are pretty good at it! Try it yourself! - - rscadd: Muzzles to silence people are now craftable out of leather sheets. - - rscdel: You can no longer print off designs from a bio-generator that can now - be crafted out of leather sheets. - - tweak: Complete sheets of leather can be printed from the bio-generator for 150 - biomass to accommodate for a loss of designs. - - experiment: Specialist objects from the leather & cloth category bio-generator - category were not removed as to encourage interdepartmental interaction & balance. - Penguaro: - - rscadd: The Slime Scanner is available from the Autolathe. - - tweak: The Design Names in the various machines are now capitalized consistently - coiax: - - bugfix: Fixes various mobs speaking languages that they were only supposed to - understand. - - bugfix: Fixes being able to bypass language restrictions by selecting languages - you can't speak as your default language. - ninjanomnom: - - tweak: Highlander no longer breaks your speakers -2017-05-09: - Expletive: - - rscadd: Curator's fedora has a pocket, like all the other fedoras. - - tweak: Treasure hunter suits can now hold large internal tanks, to ease the exploration - of lavaland. - - tweak: The curator can now access the Auxillary Base and open doors on the mining - station. - MrStonedOne: - - tweak: Lighting now defaults to fully bright until the first update tick for that - tile. This makes shuttle movements less immersion breaking. - - experiment: Rather than remove the light source from the system and then re-adding - it on light movements, the system now calculates and applies the difference - to each tile. This should speed up lighting updates. - Penguaro: - - tweak: Adjusts Meteor Shuttle Name - - bugfix: The Central Command Ferry will now dock at one of the ports in Arrivals - - tweak: '[Meta] The Slime Control Console boundaries have been adjusted around - the Kill Room' - XDTM: - - rscadd: Added bluespace launchpads. They can be built with R&D, and can teleport - objects and mobs up to 5 tiles away (8 at max upgrades), from the pad to the - target and viceversa. - - rscadd: To set up a launchpad, a launchpad and a launchpad console must be built. - The pad must be opened with a screwdriver, then linked to the console using - a multitool. A console can support up to 4 pads. - - rscadd: Launchpads require some time to charge up teleports, but don't require - cooldowns unlike quantum pads. Upgrading launchpads increases the range by 1 - per manipulator tier. - - rscadd: A special variant, the Briefcase Launchpad, has also been added to the - traitor uplink for 6 TC. - - rscadd: Briefcase Launchpads look like briefcases until setup (which requires - a few seconds). When setup, the launchpad will be functional, but can still - be dragged on the ground. To pick a pad back up, click and drag it to your character's - sprite. - - rscadd: Unlike stationary launchpads, briefcase pads only have 3 tiles of maximum - range. - - rscadd: Briefcase pads are controlled by a remote (that is sent with the briefcase) - instead of a console. The remote must be linked to the briefcase by simply hitting - it. Each remote can only be linked to one pad, unlike consoles. - coiax: - - rscadd: Visible ghosts emit light. -2017-05-11: - Joan: - - rscadd: You can now buy double eswords from the uplink for 16 telecrystals. They - cannot be bought below 25 players. - - rscdel: You can no longer use two eswords to construct a double esword. - Joan, Robustin: - - rscdel: Harvesters can no longer break walls, construct walls, convert floors, - or emit paralyzing smoke. - - rscadd: Harvesters now remove the limbs of humans when attacking, can heal OTHER - constructs, have thermal vision, and can move through cult walls. - - rscadd: Harvesters can now convert turfs in a small area around them and can create - a wall of force. - - tweak: Harvesters are now cultists. - - rscadd: When Nar-Sie is summoned, she will convert all living non-construct cultists - to harvesters, who will automatically track her. - Kor: - - rscadd: a new mysterious book has been discovered in lavaland chests! - - tweak: weird purple hearts found in lavaland chests have started beating again! - what could this mean? - MrStonedOne: - - bugfix: Fixes t-ray mode on engineering goggles not resetting the lighting override - properly. - QualityVan: - - tweak: Machine names will be capitalized when they talk on radio - Robustin: - - tweak: Dominators now require a significant amount of open (non-walled) space - around them in order to operate. - TehZombehz: - - rscadd: Sticks of butter and liquid mayonnaise can now be produced via a new 'mix' - function on the grinder. Please eat responsibly. - XDTM: - - bugfix: Plasma Golems now have the correct updated tip. - - tweak: Plasma Golems no longer take damage from fire, and take normal instead - of increased burn damage from other sources. They will still explode if on fire - and hot enough. - - rscadd: Plasma Golems can now self-ignite with an action button. - - tweak: Plasma Golems are now warned when they're close to exploding. - - tweak: Plasma Golems now have a constant chance of exploding after 850K instead - of a precise threshold at 900K, making it less predictable. - bandit: - - tweak: Nanotrasen has enhanced personality matchmaking for its personal AIs. pAI - candidates will now see who is requesting a pAI personality. - duncathan: - - tweak: opening a dangerous canister will only alert admins if it contains meaningful - amounts of a dangerous gas. No more being bwoinked because you opened an empty - canister that used to have plasma in it. - lordpidey: - - tweak: Modified chances for returning someone's soul using an employment contract. Now - everyone has a chance, not just lawyers and HoP. - - rscadd: Particularly brain damaged people can no longer sign infernal contracts - properly. - - tweak: Infernal contracts for power no longer give fireball, and instead give - robeless 'lightning bolt' spell. - - rscadd: Devils can now sell you a friend, for the cost of your soul. - - tweak: The codex gigas should now be easier to use, and less finicky. - - rscdel: The codex gigas no longer sintouches readers. - ma44: - - tweak: Doubles the amount of points wooden planks sell for (now 50 points) -2017-05-12: - Joan: - - tweak: Manifest Spirit will no longer continue to cost the user health if the - summoned ghost is put into critical or gibbed. - - rscadd: Ghosts summoned by Manifest Spirit are outfitted with ghostly armor and - a ghostly cult blade that does slightly less damage than a normal cult blade. - - balance: Manifest Spirit now consumes 1 health per second per summoned ghost, - from 0.333~. - - balance: Manifest Spirit can now only summon a maximum of 5 ghosts per rune, and - the summoned ghosts cannot use Manifest Spirit to summon more ghosts. - - rscadd: Wraiths now refund Phase Shift's cooldown by attacking; 1 second on normal - attacks, 5 seconds when putting a target into critical, and a full refund when - killing a target. - - balance: Increased Phase Shift's cooldown from 20 seconds to 25 seconds. - KorPhaeron: - - rscadd: Zombies can now see in the dark. If you steal their eyes you'll be able - to see in the dark as well! - MMMiracles (Cerestation): - - tweak: Hydroponics has been revamped, adding a few things missing before and adding - a bee room in place of the backroom. - - bugfix: Fixed some other stuff. - New Antag Alert sounds: - - soundadd: added sounds that alert players to their antag status - - soundadd: Blood cult has a new alert sound - - soundadd: Clock cult has a new alert sound - - soundadd: changeling has a new alert sound - - soundadd: Malf/traitor AI has a new alert sound - - soundadd: Nuke Ops has a new alert sound - - soundadd: Ragin' Mages has a new alert sound - - soundadd: Traitor has a new alert sound - Swindly: - - tweak: Solid plasma now begins burning at the temperature at which it was ignited. - - balance: Snow walls no longer block explosions, are deconstructed faster, and - no longer leave girders when deconstructed. - coiax: - - balance: Nanotrasen Cloning Divison's three hundred identical scientists have - announced an upgrade to the cloning computer's software. You can now scan brains - or dismembered heads and successfully clone from them. Brains seem to remember - the DNA of the last body they were attached to. -2017-05-13: - QualityVan: - - bugfix: Pizza boxes once again look different when open - 'Tacolizard Forever: It''s hip to fuck bees': - - rscadd: Added a honey jar item. It's not implemented yet. - - balance: Honey is now more robust at healing, but don't eat too much or you'll - turn into a fatty landwhale. - TehZombehz: - - rscadd: Butter noodles, butter biscuits, buttered toast, and pigs in a blanket - can now be crafted using sticks of butter and other ingredients. - coiax: - - rscadd: Servant golems now follow the "Material Golem (123)" naming scheme. - octareenroon91: - - rscadd: Hermit ruin now includes a portable seed extractor. -2017-05-14: - coiax: - - rscadd: Free Golems can purchase Royal Capes of the Liberator at their mining - equipment vendor. -2017-05-15: - Dorsidwarf: - - balance: Nanotrasen Robotics Supply Division has successfully petitioned to replace - the "My First Robot" motors in turret coverings with a standard commercial brand. - As such, they will now open faster. - Expletive: - - rscadd: You can now create water bottles and wet floor signs by using plastic - sheets. - - rscadd: You can create toy swords out of plastic sheets, a piece of cable, and - a light bulb. - Joan: - - tweak: Glowshrooms now have a less saturated glow. - - balance: The summoned ghosts from Manifest Spirit can no longer break airlocks - with their standard blade. - - balance: Manifest Spirit now does a small amount of damage when initially manifesting - a ghost. - McBawbaggings: - - tweak: SMES units will now accept charge from the power network even if the available - load is less than the input rate. Credit to Zaers for the original code. - - bugfix: Wizards are now at least 30 years old. Apprentices will be in-between - ages 17 to 29. - Penguaro: - - bugfix: The Gravity Generator description now mentions a graviton field as opposed - to a gravaton field. What is Gravaty anyway? - - bugfix: Centcom Engineering has reviewed the plans for the Box series station - and has addressed some concerns related to some APCs not affecting their designated - section. APCs for the Detective's Office, Cargobay, and Gateway, now control - those rooms. The Bridge Maintenance APC has been removed from future construction - as it serves no purpose and thus is an unnecessary construction cost. - - bugfix: The pipe from the station to the AI Satellite has been completed. - Profakos: - - rscadd: Centcom has decided to upgrade the Ore Redemption machines with a floppy - drive, intended for design disks. - Qbopper: - - tweak: The supermatter crystal now sends its warning messages to the engineering - channel. (if it's in critical condition the message will be sent to the common - radio channel as before) - Swindly: - - balance: Nitrous oxide now causes anemia. - coiax: - - bugfix: Curator soapstones now successfully leave messages for future shifts. - - rscdel: Soapstones can no longer be purchased in cargo. - - rscdel: The janitor no longer starts with an empty soapstone. - - experiment: Engraved messages can be left anywhere in the world, but be wary that - the terrain of places like lavaland and space can change shift to shift. - - rscadd: Goats on the station have developed a taste for glowshrooms, and will - eat them if they encounter any. - ma44: - - tweak: Seed vault remapped - - tweak: The seed vault random seed spawner can now spawn cherry bombs instead of - regular cherry seeds - - rscadd: BEES to plant vault - octareenroon91: - - rscadd: Ambrosia Deus can now mutate into Gaia, and Gaia into Deus. - - rscdel: A single branch of Ambrosia Gaia will not immediately make a hydroponics - tray self-sufficient. - - balance: A (total) dose of 20u Earthsblood (from Gaia) will make a hydroponics - tray self-sufficient. - uraniummeltdown: - - rscadd: Ambrosia Gaia is back -2017-05-16: - Moonlighting Mac says: - - rscadd: Starthistles now return seeds when they are harvested, amongst having - a overhaul of description, alteration of statistics & a mutational path into - harebells. These seeds have been supplied into the hydroponics seed vendor. - - imageadd: Starthistle tray sprites have been restructured & also fixed from a - issue of them being broken and not appearing in trays. In addition there are - new sprites for its seeds. - Penguaro: - - bugfix: There is now Space under the rocks at the Dragoon's Tomb - - bugfix: Centcom Intelligence reports that the Hidden Syndicate Research Base may - have received a shipment of viruses. - QualityVan: - - bugfix: Fixed fire alarms not being repairable if the board was broken - - bugfix: People without eyes and ears are no longer susceptible to flashbangs they - aren't directly on top of - Robustin: - - rscadd: Summoning Nar'Sie now triggers a different ending. No shuttle is coming! - Survivors must escape on a pod or survive the Red Harvest for 3 minutes. If - Nar'Sie acquires enough souls, the round ends immediately with a **special ending**. - - rscadd: New Harvester Sprite - - rscadd: Harvesters can now track a random survivor on the station, then switch - back to tracking Nar'Sie, via a new action button. - fludd12: - - rscadd: You can now add grills to a bonfire, letting you cook things on top of - them. -2017-05-17: - 4dplanner: - - bugfix: revenant respawning will not spam up deadchat so much, and is less likely - to break. - Expletive: - - rscadd: Syndicate Tomes have been added to traitor uplinks for 9 TC. They let - an agent or an operative provide both weal and woe. - Penguaro: - - bugfix: Centcom Engineering has reviewed the power schematic for the engine room - and added an Area Power Controller. - coiax: - - balance: Magic eightballs are now tiny items, able to fit into a box and pocket. -2017-05-18: - Joan: - - rscadd: Proselytizing alloy shards will now proselytize all the shards in the - tile, instead of requiring you to proselytize each one at a time. - Lordpidey: - - tweak: Space ninjas now use action buttons instead of verbs for a more consistent - user experience. - - rscadd: Toy toolboxes with realistic rumbling action have been added to arcade - prizes. - 'Tacolizard Forever: Plasmaman Powercreep': - - tweak: Plasmaman tanks are the same size as emergency oxygen tanks. - coiax: - - rscadd: Syndicate agents can purchase a "codespeak manual", that teaches them - a language that sounds like a series of codewords. You can also hit other people - with the manual to teach them. One use per manual. - - rscadd: Nuclear operatives have access to a deluxe manual that is more expensive - but has unlimited uses. - - rscadd: Syndicate AIs know Codespeak for free. - - bugfix: Spacevines can no longer spread on space transit turfs. - - balance: Plastic explosives can no longer be detonated by EMPs. - - rscadd: Various vending machines, when shooting their inventory at nearby people, - will "demonstrate their products features". This means that if a cigarette vending - machine throws a lighter at you, it will be on. Vending machines also choose - random products when throwing, rather than the first available one. - kevinz000: - - rscadd: Peacekeeper cyborgs now have projectile dampening fields. -2017-05-19: - 4dplanner: - - balance: the Hierophant club has gained in power -2017-05-20: - Joan: - - balance: Proto-kinetic crushers have been worked over by our highly qualified - techs, will recharge 12% faster, and no longer require very low-pressure atmospheres - to fire! - - balance: In addition, our techs have tweaked the quantum linker module and proto-kinetic - crushers can apply multiple marks to different targets! Marks applied may eventually - expire if not detonated. - Steelpoint: - - rscadd: All Pulse weapons now accurately show, by their sprites, what fire mode - they are in. - - rscadd: ERT, non-red alert, Security Response Officers spawn with a Tactical Energy - Gun. This is a military variant of the Egun that, in addition to laser and disable - rounds, has access to stun rounds. - - tweak: Pulse Pistols can now be recharged. - Swindly: - - rscadd: Added modified syringe guns. They fire DNA injectors. Geneticists and - CMOs can buy them from the traitor uplink for 14 TC. - coiax: - - rscadd: When a shuttle is called, sometimes an on-call admiral, using available - information to them, will recall the shuttle from Centcom. - octareenroon91: - - bugfix: Golems touching a shell can now choose to stay in their own body. -2017-05-21: - Gun Hog: - - bugfix: The Auxiliary Base can no longer land outside the lavaland map's boundaries. - RandomMarine: - - tweak: Drone laws no longer restrict drones to the station. - Steelpoint: - - rscadd: The Warden's Cycler Shotgun has been replaced with a Compact Combat Shotgun. - A unique weapon, it can fit in armour slots but at the sacrifice of a smaller - ammo capacity of four shells. -2017-05-22: - Joan: - - tweak: Resonator fields now visually show how long they have until they burst. - - bugfix: Hitting a legion skull with a resonator will now produce a field. - - balance: Swapped how far plasma cutter blasts go when going through rock and in - open air. This means blasts through air will go 4/5 tiles, but will mine 7/10 - tiles, for normal/advanced plasma cutters, respectively. - - tweak: There is now a buffer zone between the mining base and lavaland where megafauna - will not spawn. - - tweak: Ruins will no longer spawn directly in front of the mining base. - Lzimann: - - rscadd: Pandemic is now tgui! - Robustin: - - rscadd: Gang influence is now decentralized, each gangster has their own influence - that they can increase by spraying (and protecting) their tags and new influence-enhancing - bling. - - rscadd: Gang uniforms are now created based on your gang's color and can be purchased - by any gang member. They will increase the wearer's influence and provide protection, - but will make it fairly obvious which gang you belong to. - - rscadd: Gangs have access to a new surplus rifle; it is a semi-automatic rifle - that is very bulky and has a very low rate of fire. Gang members can buy this - gun for just 8 influence. - - rscadd: Gangs have access to the new machine gun turret; it unleashes a volley - of bullets with an extended view range. It does not run out of ammo, but a significant - delay between volleys and its stationary nature leaves the gunner vulnerable - to flanking and return fire. Holding down the trigger will allow you to aim - the gun while firing. It will cost gangs 50 influence. - - rscadd: The sawn-off improvised shotgun is now available to gangs for 6 influence. - With buckshot shells being easy to produce or purchase, this gun gives the most - "bang for your buck" but its single-shell capacity will leave you vulnerable - during a pitched gunfight. - - rscadd: The Wetwork boots give gangs access to a lightly armored noslip variant. - - tweak: The armored gang outfits are now slightly more resistant to ballistic and - bomb damage - Swindly: - - balance: Monkeys can be weakened by stamina loss - kevinz000: - - bugfix: Nanotrasen decided to remove the integrated jet engines from jetpacks. - They can no longer be used successfully indoors. -2017-05-23: - ClosingBracket: - - spellcheck: Fixed very minor inconsistencies on items & punctuation on items. - Joan: - - rscdel: Nanotrasen has taken a lower bid for their meson suppliers, and meson - scanners will no longer display terrain layouts while on the planet. - - tweak: However, they have discovered that, with some tweaks, mineral scanners - will no longer actually require you to be wearing mesons. - - tweak: The cheaper mesons will not completely remove reliance on light. - - tweak: Ripleys will collect all ore in front of them when they move with a clamp - and stored ore box. - - tweak: Chasms will glow dimly, like lava. - Joan, Repukan: - - rscadd: Traitor miners can now buy up to 2 KA Pressure Mods for 5 TC each. - - balance: KA Pressure Mods now only take up 35 mod capacity each, allowing traitor - miners to use 2 and have space for 1 other mod. - - rscdel: R&D can no longer build KA Pressure Mods. - Robustin: - - rscadd: Added a sexy new icon for the harvester's AOE conversion spell - - bugfix: Fixed construct's forcewall being invisible - - bugfix: Fixed cult constructs "Locate Master" and "Locate Prey" not functioning - - bugfix: Fixed spell action buttons not showing their actual availability status - - tweak: Changed the duration of a few frames for the new Cult ending - Steelpoint: - - rscadd: Auto Rifle alt ammo mags (AP, Incendiary, Uranium Tipped) now have a coloured - stripe to denote them. - That Really Good Soda Flavor: - - bugfix: Martial arts are no longer lost when mind-swapping, cloning, moving your - brain, et cetera. - - bugfix: Fixed a bug where paper bins could swallow up pens into the void. - coiax: - - rscadd: Galactic Common has been added to silicon's internal language database, - meaning even if a cyborg is created from someone who previously did not know - Galactic Common, they will be able to speak it as a silicon. - kevinz000: - - bugfix: Spessmen seems to have stopped suffering from the mental condition that - makes them believe they can't move fast if they have only one leg, even if they're - in space and using a jetpack! - ma44: - - rscadd: Reports of syndicate base on lavaland has been outfitted with a state - of the art donksoft toy weapon dispenser. -2017-05-24: - Joan, WJohnston: - - rscadd: Adds marker beacons to mining as a vendible item. They can be bought in - stacks of 1, 10, and 30 at a rate of 10 points per beacon. - - rscadd: Miners start with a stack of 10 in their backpack, and the Extraction - and Rescue Kit contains a stack of 30. - - rscadd: Marker beacons come in a large selection of colors and simply light up - a small area when placed, but are useful as a path marker or to indicate dangers. - QualityVan: - - rscadd: Hairless hides now become wet when exposed to water - - rscadd: You can microwave wet leather to dry it - - bugfix: Inserted legion cores no longer work if they went inert before implanting - Steelpoint: - - rscadd: Sketchin alternative magazines (Armour Piercing, Hollow Point, Incendiary) - now have unique sprites to better identify them. - - rscadd: ERT Sec Tactical Energy Guns now have a unique sprite. - - tweak: Changes to production of Nanotrasen Auto Rifle armour piercing bullets - have now made AP bullets better able to penetrate armour, but at the cost of - the amount of possible damage the bullet can do to soft targets. - - rscadd: Many Ballistic weapons now have new sounds related to reloading or placing - bullets into magazines. - - rscadd: Boxstation armoury weapon racks now have glass panes to help prevent the - weapons easily flying out of a breached hull. - - bugfix: Fixed Battleship Raven's bridge blast doors not working. - Tacolizard: - - tweak: Station based armour is slightly more descriptive of what it does. - That Really Good Soda Flavor: - - tweak: Changed spray tan overdoses to be more realistic. - - rscadd: People who are high and beach bums can now talk in their own stoner language. - - tweak: Beach bums can only communicate with other beach bums and people who are - high. -2017-05-25: - 4dplanner: - - bugfix: crushers now apply marks properly - - rscadd: 20% of internal affairs agents are actually traitors - 4dplanner, robustin: - - bugfix: c4 has always taken 3 seconds to plant, and you are not allow to believe - otherwise - Crexfu: - - spellcheck: typo fix for origin tech - Cyberboss: - - experiment: Explosions will no longer have a start up delay - - bugfix: Indestructible objects can no longer be destroyed by bombs - Oldman Robustin: - - tweak: Gang mode now calls a 4 minute unrecallable shuttle once 60% of the crew - is dead - ohnopigeons: - - balance: The cost of plasma has been reduced from 500 to 300, but retain their - immunity to saturation -2017-05-26: - Moonlighting Mac says: - - rscadd: You can now craft a strong cloak with a hood made out of goliath and monster - materials from within the primitive crafting screen. - - rscadd: The cloak has a suit slot for all kind of primitive supplies, however - it cannot carry most electronic miner equipment. - - balance: Due to the recipe requiring leather, it is not normally accessible to - all ghost roles without a source of water & electricity. - kevinz000: - - rscadd: You can now add bayonets to kinetic accelerators. However, only combat - knives and survival knives can be added. Harm intent attacking things will cause - you to attack that thing with the bayonet instead! -2017-05-28: - ClosingBracket: - - tweak: Allows explorer webbings to hold marker beacons. - Expletive: - - tweak: E-Cigarettes can now fit in your pocket. - Iamgoofball: - - bugfix: After the Syndicate realized their top chemist was both mixing a stamina - destroying drug with a stimulant to avoid slowdowns entirely in their sleepypens, - they fired him and replaced him with a new chemist. - Joan: - - rscadd: Miner borgs can now place marker beacons from a storage of 30. - - bugfix: Necropolis tendrils will once again emit light. - - rscadd: The kinetic crusher can now gain bonus effects via trophy items gained - by killing bosses with it. - - rscadd: Yes, you do have to kill the boss primarily doing damage via the kinetic - crusher, or you won't get the trophy item and the bonus effect it grants. - Kor: - - bugfix: The chaplains possessed blade, shades, and constructs, can once again - speak galactic common. - QualityVan: - - bugfix: Bayonets can now be used for butchery - - tweak: Cloning pods which are interrupted by a emagging will now produce a slightly - lumpier smoothie - - bugfix: Cloning pods that have stopped cloning early can no longer be broken open - to extract leftover parts - - bugfix: Crew monitoring consoles once again have minimaps while you're on the - station level - Steelpoint: - - rscadd: A New Iron Hawk troop transport ruin has been added to lavaland. Can the - sole surviving Marine somehow survive the horrors of lavaland? Lore fluff included. - - rscadd: Central Command has listened to complaints and, as such, has now stationed - "real" Private Security Officers at centcom docks. - - rscadd: A new Nanotrasen Security Officer NPC variant is available to admins, - this 'peaceful' version will only attack people who attack it first. Great for - keeping order. - Swindly: - - bugfix: fixed not being able to attach heads without brainmobs in them - cacogen: - - rscadd: You can now rename dog beds by buckling a new owner to them - - rscadd: Dogs that spawn in an area with a vacant bed will take possession of and - rename the bed - - rscadd: Adds AI follow links to holopad speech and PDA messages. Note that PDA - messages point to the owner of the PDA and not the PDA's actual location. - - bugfix: Fixes PDA icon not showing up beside received messages for AIs - kevinz000: - - rscadd: Nanotrasen's new titanium wall blueprints are smooth enough that it can - reflect projectiles! -2017-05-29: - Joan: - - spellcheck: Renames hivelord and legion cores to 'regenerative core'. Their descs - have also been updated to be more clear. - Nanotrasen Plasmaman Outreach Division: - - tweak: plasmaman tank volume has been increased from 3 to 6. - XDTM: - - balance: Abductors have learned how to properly delete the memories of their test - subjects. - bandit: - - tweak: The officer's sabre standard in Nanotrasen captain rollouts can be used - to remove the tails of lizard traitors, or lizards in general. - oranges: - - rscadd: AI's can now hang up all holocalls at a station with alt+click -2017-05-30: - Expletive: - - rscadd: Luxury versions of the bluespace shelter capsule are now available! Purchase - them at the mining equipment vendor. - - rscadd: 'Cardboard cutouts have a new option: Xenomorph Maid' - - rscadd: Black Carpet can now be crafted using a stack of carpet and a black crayon. - - rscadd: Black fancy tables can now be crafted using Black Carpet. - - rscadd: Shower curtains can now be recoloured with crayons, unscrewed from the - floor, disassembled with wire cutters, and reassembled using cloth, plastic, - and a metal rod. - kevinz000: - - rscadd: Research and Development have recieved designs for new prototype Beam - Marksman Rifles. These rifles require a short aiming cycle to fire, however, - have extreme velocity over other weapons. - - experiment: Aiming time is 2 seconds, hold down mouse to aim, aiming time increases - if you change your aim based on angle changed, or if you move while aiming. - The weapon can not be fired while unscoped. - - rscdel: However, someone tripped and pulled out the power cord while your servers - were being updated with the latest revision of accelerator laser cannons. All - data have been lost... -2017-06-02: - Cyberboss: - - experiment: New server backend! - - tweak: Test merged PRs now show the commit of the PR at which they were merged - Expletive: - - rscadd: Adds the NT75 Electromagnetic Power Inducer, a tool which can be used - to quickly recharge many devices! They can be found in Electrical Closets, the - CE's locker, ordered by cargo, or created in RnD. - Goodstuff: - - bugfix: Fixes the crafting recipe for black carpet - - bugfix: Removed a random white dot on the black carpet sprite - Joan: - - rscadd: Goliaths, Watchers, and Legions have a small chance of dropping a kinetic - crusher trophy item when killed with a kinetic crusher. Like the boss trophy - items, these give various effects. - - tweak: Kinetic crushers recharge very slightly slower. - - rscadd: Three unique Kinetic Accelerator modules will now appear in necropolis - chests. - MMMiracles (Cerestation): - - rscadd: CereStation's Security department has been overhauled entirely thanks - to the tireless efforts of Nanotrasen's construction division. - Nanotrasen Mining Alert: - - rscadd: Nanotrasen's mining operations have created far more corpses than an entire - galaxy of cooks could hope to deal with. To solve this, we decided to just dump - them all from orbit onto the barren lava planet. Unfortunately, the creatures - called "Legion" have infested a great number of them, and you can now commonly - find the bodies of former Nanotrasen employees left behind. Additionally, there - are reports of natives, other settlers, and even stranger things found among - the corpses. - QualityVan: - - tweak: The tactical rigging in op closets is more tacticool - Shadowlight213: - - balance: The reset wire on borgs must now be cut to reset a borg's module instead - of pulsed. - - tweak: Portable pump max pressure has been lowered. - Steelpoint: - - tweak: Iron Hawk Marine no longer has Centcom all access. My mistake. - - bugfix: Fixes Iron Hawk marine carbine not having a visible sprite. - Swindly: - - balance: Nitrous oxide no longer produces water as a by-product, requires 2 parts - ammonia instead of 3, and produces 5 parts when made instead of 2. - kevinz000: - - experiment: Gang turrets now follow the mouse of the person using them! Yay! - octareenroon91: - - bugfix: Attempts to add items to a storage container beyond its slots limit will - now obtain a failure message again. -2017-06-03: - Expletive: - - tweak: Chem Dispensers now store their power in their batteries. - - tweak: Instead of being based on battery and capacitor ratings, recharge delay - for portable chem dispensers is now based on their capacitor and matter bin - ratings. - - tweak: The Seed Vault's chemical dispenser now has all the chemicals a pod person - could want. - - rscadd: The crafting menu now has subcategories! - - rscadd: Food recipe categories have been combined as subcategories of the Foods - category. - - rscadd: Weaponry and Ammunition have been combined as subcategories of the Weaponry - category. - Improvedname: - - rscadd: Janitors now start with a flyswatter - Mothership Epsilon: - - tweak: All your base are belong to us. - Penguaro: - - bugfix: '[Box] Removes extra/unattached vent from Xeno Lab' - Planned Spaceparenthood: - - bugfix: We would like to apologize for mislabeled cloning pod buttons. - WJohnston: - - bugfix: Deltastation's south nuke op shuttle location should no longer be possible - to teleport into by moving off the map and back on, and moved the rest closer - to the station. - p440: - - bugfix: Fixed duping cable coils with magic APC terminals - - bugfix: Fixed invalid icon state for empty APCs -2017-06-04: - Expletive: - - rscadd: Many stacks now update their sprite based on their amount. - - rscadd: Stacks will now weigh less if they're less than full. - - imageadd: Added new icon states for glass, reinforced glass, metal, plasteel, - plastic, plasma, plastitanium, titanium, gold, silver, adamantine, brass, bruise - packs, ointment, gauze, cloth, leather, wet leather, hairless hide, human hide, - ash drake hide, goliath hide, bones, sandstone blocks, and snow blocks. - - tweak: Some lavaland stacks' max amounts have been reduced. - - bugfix: Bulldog Shotguns should update their sprite properly when you remove the - magazine. - - bugfix: Riot suits no longer hide jumpsuits. - Joan: - - balance: Rod Form now costs 2 points, from 3. - - balance: Rod Form now does 70 damage, from 160, but gains 20 damage, per upgrade, - when upgraded. This means you'll need to spend 6 points on it to instantly crit - people from full health. - Swindly: - - balance: Chemical grenades are no longer permanently disabled after being unlocked - by wirecutters after being primed. -2017-06-05: - Expletive: - - rscadd: The Ore Redemption Machine has been ported to TGUI. New features include - the addition of "Release All" and "Smelt All" buttons. - - rscadd: The Ore Redemption Machine now be loaded with sheets of material. - - rscadd: The Ore Redemption Machine can now 'smelt' Reinforced Glass. - Joan: - - balance: Only human and silicon servants can help recite multi-invoker scriptures. - This means cogscarabs, clockwork marauders, and anima fragments DO NOT COUNT - for scriptures that require multiple invokers. - - balance: Clockcult scripture tiers can no longer be lost by dipping below their - requirements once they are unlocked. - - rscdel: Removes Revenant scriptures entirely. - MMMiracles: - - tweak: Deepstorage ruin has been redone to be more self-sufficient and up to better - mapping standards. -2017-06-06: - Joan: - - rscadd: Added a new unique Kinetic Accelerator module to necropolis chests. - - spellcheck: Renames Clockwork Proselytizers to Replica Fabricators. - - balance: Replica Fabricators can directly consume floor tiles, rods, metal, and - plasteel for power instead of needing to convert to brass first. - - balance: Cogscarabs can no longer use guns. - - tweak: KA modkits in necropolis chests are now design discs with designs for those - modkits, to force miners to bring back minerals. - PKPenguin321: - - bugfix: The fake pits that the arcade machines can vend now vend properly, for - real this time. - Robustin: - - rscadd: The cult master has finally acquired their 3rd spell, Eldritch Pulse. - This ability allows the cult master to quickly teleport any cultist or cult - structure in visual range to another tile in visual range. This spell has an - obvious spell effect that will indicate where the target has gone but without - explicitly revealing who the master is. This spell should assist with moving - obstinate cultists off an important rune, getting wandering cultists back onto - an important rune, save a cultist from an untimely arrest/summary execution, - assist in getting your allies into secure areas, etc. - - bugfix: The void torch now only works on items that have been placed on surfaces, - this prevents the inventory bugs associated with this item. - thefastfoodguy: - - tweak: you can burn your brains out with a flashlight if you're tired of life -2017-06-07: - Expletive: - - rscadd: New plasma medals have been added to the Captain's medal box. Don't get - them too warm. - - imageadd: New sprites for plasma medals. - - imageadd: Icon and worn sprites for all medals and the lawyer's badge have been - improved. Worn medals more closely match their icons. - - tweak: The bone talisman is an accessory again, so it's not useless. - - imageadd: It also has a new worn sprite, based on an arm band. - - imagedel: Ties have been removed from accessories.dmi and vice versa. Same for - the explorer's webbing sprites that were in there. ties.dmi is now neck.dmi, - and has sprites for scarves, ties, sthetoscopes, etc. - - tweak: Examining an accessory now tells you how to use it. - Joan: - - spellcheck: Renamed Volt Void to Volt Blaster. - - tweak: Volt Blaster does not consume power when firing and does not cause backlash - if you don't fire. - - balance: Volt Blaster does 25 damage, from 20-40 depending on power, and has 5 - shots, from 4, over its duration. - QualityVan: - - bugfix: Surplus rifles are no longer invisible while unloaded - Shadowlight213: - - balance: The Changeling Transformation Sting is once again stealthy. However, - it no longer transfers mutations. - - balance: The chemical cost of Transformation Sting has been increased to 50 -2017-06-08: - 4dplanner: - - bugfix: traitors show up on antagHUD - Expletive: - - tweak: The detective's flask has Hearty Punch instead of whiskey. - - bugfix: The Detective's fedora no longer clips with hair. - - imageadd: Adds 91 new sprites to fix clipping issues with the Detective's fedora - and hair. - - imageadd: Change the standard fedora to match the detective and treasure hunter - variants. - - tweak: Detective, Treasure Hunter, and standard fedoras now all benefit from new - sprites. - Joan: - - balance: Tinkerer's Daemons are no longer totally disabled if you drop below the - servant requirement. - - balance: Instead, Tinkerer's Daemons will disable until the number of active daemons - is equal to or less than one-fifth of the living Servants. - - tweak: Tinkerer's Daemons produce components very slightly slower. - - rscadd: Added Prolonging Prism as an application scripture. - - balance: Prolonging Prism will delay the arrival of an emergency shuttle by 2 - minutes at the cost of 2500W of power plus 75W for every 10 CV and 750W for - every previous activation. In addition to the high cost, it very obviously affects - the shuttle dock and leaves an obvious trail to the prism. - - balance: Script scripture now requires 6 Servants to unlock, from 5, and Application - scripture now requires 9 Servants to unlock, from 8. - Lzimann + Cyberboss: - - experiment: Ported goonchat. Much less laggy and crashy than BYOND chat. + Frills! - NanoTrasen Public Relations Department: - - rscadd: A mining accident has released large amounts of space dust, which is starting - to drift near our stations. Don't panic, it's probably safe. - Nanotrasen Plastic Surgery Advert: - - rscadd: Are you a mutant? Were you born hideously deformed? Do you have ears growing - out of the top of your head? Or even a tail? Don't worry, with our patented - surgical techniques, Nanotrasen's highly trained medical staff can make you - normal! Schedule an appointment, and one of our surgeons can see you same day. - - balance: Cat ears now give you double the ear damage. - QualityVan: - - bugfix: Cremators now still work when there's only one thing in them - - bugfix: The ORM now uses the intended amount of resources when making alloys - - rscdel: Cyborgs can no longer alt-click their material stacks to split them - Robustin: - - balance: The blood cult can only attempt to summon Nar-Sie in one of three rooms - that are randomly selected at round-start. - Shadowlight213: - - rscadd: Tracking implants and chem implants have been added to rnd - - rscdel: Adrenaline and freedom implants have been removed from rnd - Xhuis: - - tweak: Defibrillator paddles will no longer stick to your hands, and will snap - back onto the unit if you drop them somehow. - lzimann: - - rscdel: Xeno queens can no longer be maids - oranges: - - rscadd: Added stungloves to the brain damage lines -2017-06-09: - Nanotrasen Shiny Object Appreciation Club: - - rscadd: The RD and HoS now receive medal lockboxes in their lockers, containing - science and security medals, respectively. - Tacolizard and Cyberboss, idea by RandomMarine: - - rscadd: You can now add a commendation message when pinning a medal on someone. - - rscadd: Medal commendations will be displayed when the round ends. - - tweak: Refactored the outfit datum to allow accessories as part of an outfit. - - bugfix: The Captain spawns with the Medal of Captaincy again. - TrustyGun: - - rscadd: Some of the clown's toys have been moved into a crate in the theater. - If you think you are missing something, check in there. - - rscadd: Wooden crates have been added. You can construct them with 6 wooden planks, - and deconstruct them the same way as regular crates - oranges: - - tweak: Security minor and major crime descriptors are now a single line input, - making it easier to add them - - tweak: Medical record descriptions are single inputs now -2017-06-11: - Expletive: - - imageadd: Glass tables are shinier - Nanotrasen Consistency Affairs: - - bugfix: You no longer see yourself in place of the user when examining active - Spirit Sight runes. - Shadowlight213: - - bugfix: Cloning dismembered heads and brains now respects husking and other clone - preventing disabilities. - WJohn: - - bugfix: It is now easier to wire the powernet into box's telecomms SMES cell. - Xhuis: - - rscadd: You can now pin papers and photos to airlocks. Anyone examining the airlock - from up close can see the details. You can cut them down with wirecutters. - lordpidey: - - rscadd: Added F.R.A.M.E. cartridge to uplinks. This PDA cartridge contains 5 - viruses, which when used will unlock the target's PDA into a syndicate uplink, - in addition, you will receive the code needed to unlock the uplink again, if - you so desire. - - rscadd: If you use telecrystals on a F.R.A.M.E. cartridge, the next time it is - used, it will also give those crystals to the target uplink. - octareenroon91: - - bugfix: Mecha tools now respond to MMI control signals as intended. - shizcalev: - - tweak: '"Species immune to radiation are no longer compatible targets of radiation - based DNA injectors."' - - bugfix: '"A gun''s firing pin will no longer malfunction when placed into your - own mouth. Phew!"' - - imageadd: '"Bedsheets capes are now slightly more accurate. Be jealous of the - clown and their sexy cape!"' -2017-06-13: - Expletive: - - tweak: Paper planes are now the same color as the paper used to make them. - - bugfix: Flashdarks can no longer be used to examine head based organs. - Fox McCloud: - - tweak: Tweaked game options animal speed value to match live server - Joan: - - spellcheck: Renamed AI liquid dispensers to foam dispensers. - - tweak: Foam dispensers now activate immediately when clicked, rather than forcing - the user to go through a menu. They also have better visual, message, and examine - feedback on if they can be activated. - MrStonedOne: - - experiment: Added some code to detect the byond bug causing clients to send phantom - actions shortly after connection. It will attempt to fix or work around the - issue. - Nanotrasen Robotics Department: - - rscadd: To aid in general-purpose cleaning and maintaining of station faculties, - all janitor cyborgs are now outfitted with a screwdriver, crowbar, and floor - tile synthesizer. - WJohnston: - - bugfix: Survival bunker ruin's power now works, mostly. - shizcalev: - - tweak: '"Radiation immune species are now incompatible with the radiation based - genetics DNA scanner/modifier."' -2017-06-14: - Expletive: - - rscadd: The medalboxes are now fancy. - - imageadd: New sprites for opened medal boxes. - Joan: - - tweak: Being converted to clockcult will briefly cause your world to turn yellow - and you to hear the machines of Reebe, matching the description in the messages. - - spellcheck: The messages for being converted and for failing conversion to clockcult - have been updated. - Tacolizard: - - bugfix: Flamethrowers no longer say they're being ignited when you extinguish - them -2017-06-17: - Cyberboss: - - tweak: NT now provides education on the proper response for experiencing the excrutiating - pain of varying degree burns (You scream when burning) - Expletive: - - rscadd: The Captain now starts with a deluxe fountain pen in their PDA. - - rscadd: The quartermaster, curator, research director, lawyer, and bartender start - with normal fountain pens in their PDAs. - - rscadd: Cargo can order fountain pens via the Calligraphy Crate. - - rscadd: Nerds on the station will be pleased to know they now have pocket protectors. - - bugfix: Cryo cells work properly on mobs with varying max health values. - Joan: - - rscdel: Cultists must be human to run for Cult Master status. - - tweak: The Hierophant is a little less chaotic and murdery on average. - LanCartwright: - - rscadd: Penguins, penguin chicks, penguin eggs. - - rscadd: Penguin family to Winter Wonderland. - MrStonedOne and Lummox JR: - - bugfix: Fixed icon scaling and size preferences not loading (Technically size - preferences were loading because byond saves that locally, but that's not reliable - because ss13 shares a hub) - QualityVan: - - rscadd: The botany vending machine now has a stock of onion seeds - RandomMarine: - - tweak: RCDs now always use matter consistent with the material needed when building. - - tweak: Floors now cost 3 or 1 matter to build, based on if a lattice exists on - the tile. - - tweak: Reinforced windows cost 12 matter. Normal windows cost 8 matter. (Both - up/down from 10) - - tweak: Glass airlocks cost 20 matter. - - tweak: RCDs are faster at building grilles and plain glass windows. - Steelpoint: - - tweak: Slightly reshuffles the Head of Security's, and Research Directors, locker - to place fluff items below essential items. - Tacolizard: - - rscdel: Flashes no longer have a tech requirement - That Really Good Soda Flavor: - - bugfix: High luminosity eyes will have material science instead of an error research - type - Thunder12345 and Improvedname: - - rscadd: You can now turn severed cat tails and ears into genuine kitty ears - - rscadd: Cat tails can now be used to make a cat o' nine tails, similarly to the - liz o' nine tails. - Xhuis: - - spellcheck: The names of the hand drill, jaws of life, and emitter are now lowercase. - - spellcheck: The descriptions of the hand drill, jaws of life, and emitter have - been changed to be more descriptive and less lengthy. - - rscadd: Tablets with IDs in them now show the ID's name when examining someone - with that tablet in their ID slot, similar to a PDA would. - bandit: - - tweak: Default short/medium/long brig times are now, in order, 2, 3, and 5 minutes. -2017-06-18: - Expletive: - - tweak: Stacks of space cash now tell you their total value and their value per - bill when you examine them. - RandomMarine: - - tweak: Compressed matter cartridge production costs now reflect their material - worth at basic efficiency. - - bugfix: Compressed matter cartridges can now be exported. - Xhuis: - - bugfix: Puny windows will no longer stop the progress of Ratvar. -2017-06-19: - Expletive: - - rscadd: Paper frames can be created using wood and paper, and can be used to create - decorative structures. - - rscadd: Natural paper can now be crafted - - rscadd: KorPhaeron can now start a maid cafe, if they so desire. - - rscadd: Thanks to the invention of "Bill slots", vending machines can now accept - space cash. - - tweak: The Clown and Mime can now find their unique crayons stored inside their - PDAs - LanCartwright: - - rscadd: 1D4 into Lavaland Mining base crate. - RandomMarine: - - tweak: Bonfires now work on lavaland! - Tacolizard: - - rscadd: Repurposed the action button tooltip code to add tooltips with the examine - details of all held and equipped items. Hover your mouse over any item equipped, - held or in your inventory to examine it. - - rscadd: Examine tooltips can be toggled with the 'toggle-examine-tooltips' verb, - which can be typed or accessed from the OOC menu. - - rscadd: You can change the delay before a tooltip appears with the 'set-examine-tooltip-delay' - verb, also accessible via the OOC menu. The default delay is 500ms. -2017-06-20: - Bawhoppen: - - bugfix: Grenade belts and bandoliers will no longer obscure half the screen when - they're completely filled. - LanCartwright: - - rscdel: Removed loot drops from Syndicate Simple mobs. - Tacolizard: - - rscadd: Some items now have custom force strings in their tooltips. - - bugfix: items with no force can still use a custom force string. - Xhuis: - - bugfix: The station's heaters and freezers have been sternly reprimanded and will - now drop the correct circuit boards and cable coils. - - rscadd: The straight jacket now takes five seconds to put on. - - bugfix: The display cases in luxury shelter capsules will no longer spawn unobtainable, - abstract offhand objects. - - bugfix: Disablers now have an in-hand sprite. - nicbn: - - imageadd: Changed cryo sprites to Bay cryopods, which show the person inside of - them. -2017-06-22: - Bawhoppen: - - rscadd: Dressers are now constructable, and unanchorable with a wrench. - ClosingBracket: - - spellcheck: Fixes small typographical errors on flight suits and implanters. - Ergovisavi: - - tweak: Nanofrost setting and metal foam synthesizer on the Atmos watertank backpack - changed to "Resin", which is a solid, but transparent structure similar to metal - foam that scrubs the air of toxins, regulates temperature, etc - - tweak: Atmos holobarrier device swapped out for an Atmos holo-firelock device, - which creates holographic firelocks that prevent atmospheric changes from going - over them - Expletive: - - tweak: Flame thrower plasma tanks can be removed with alt-click. - Lordpidey: - - bugfix: True and arch devils are no longer deaf. - - bugfix: Fixed some edge cases with devils getting two sets of spells. - - bugfix: True/arch devils can now instabreak cuffs. - - rscadd: The codex gigas now indicates if a devil is ascendable or not. - - tweak: Hellfire has been buffed, it now explodes multiple times. - Nanotrasen Robotics Department: - - tweak: Traitor AIs' malfunction modules have received a firmware update and are - more responsive, with HUD buttons and more sensible menus. - - tweak: Overload and Override Machines now function differently; instead of right-clicking - a machine to choose a context menu option, you activate the ability, which lets - you left-click on a machine to overload or override it. This also changes your - cursor. - Xhuis: - - rscadd: Alt-clicking the Show/Hide Actions button will now reset the positions - of all action buttons. - - rscadd: Hints to the two shortcuts for action buttons are now included in the - Show/Hide Actions button's tooltip. - - rscadd: (As a reminder, that's shift-click to reset the clicked button, and alt-clicking - the Show/Hide Actions button to reset it and all the others!) - - spellcheck: The names of several objects, such as the holopad and biogenerator, - have been lowercased. - - spellcheck: Added some descriptions to a few objects that lacked them. - - rscadd: Tablets now have a built-in flashlight! It can even change colors, as - long as they're light enough in hue. - bandit: - - rscadd: Nanotrasen researchers have made the breakthrough discovery that Lavaland's - plants are, in fact, plants, and can be harvested with seed extractors. - ohnopigeons: - - bugfix: After a janitorial audit Nanotrasen has decided to further cut costs by - removing the janicart's secret space propulsion functionality -2017-06-23: - BeeSting12: - - bugfix: The clowndagger now has the correct skin. - MrStonedOne: - - tweak: Makes old chat show while goonchat loads. Should goonchat fail to load, - the old chat will still be operational. -2017-06-25: - Expletive: - - rscadd: Adds the skull codpiece, which can be crafted from parts of lavaland monsters. - - rscadd: Maid Costume aprons can now be detached and reattached to any uniform. - Improvedname: - - rscadd: You can now export cat ears/tails for 1000 credits - JJRcop: - - bugfix: Fixed telekinesis remote item pick up exploit - Kor: - - rscadd: Robotic legs now let you use pockets without a jumpsuit, and a robot chest - now lets you use the belt slot and ID slot without a jumpsuit. - RandomMarine: - - rscadd: Cargo can now export mechs! - Steelpoint: - - rscadd: Station Engineers spawn with a Industrial Welder in their toolbelt. - - tweak: Engineering Welder Locker now only holds three standard Welders. - - rscadd: An old Nanotrasen Space Station has quietly reawoken its surviving crew - one hundred years after they fell to slumber. Can the surviving crew, using - old, broken and out of date equipment, overcome all odds and survive, or will - the cold embrace of the stars become their new home? - - tweak: Nanotrasens Corps of Engineers has refitted and refurbished NTSS Boxstations - Engineering area into, what Centcom believes, a more efficient design. - That Really Good Soda Flavor: - - experiment: Added the ability for a holiday to start on the nth weekday of a month. - - experiment: Allahu ackbar! Added the ability to calculate Ramadan. - - rscadd: Added Thanksgiving, Mother's Day, Father's Day, Ramadan, and Columbus - Day to the possible holidays. - - bugfix: Fixed nuclear bombs being radioactive. - Xhuis: - - rscadd: You can now unfasten intercoms from walls and place them elsewhere on - the station. - - rscadd: Intercom frames can now be created at an autolathe for 75 metal and 25 - glass. - - bugfix: Nearly-full goliath hide stacks now correctly have a sprite. -2017-06-27: - Ergovisavi: - - bugfix: Fixed a few anomalous crystal effects - - bugfix: Fixes stacking atmos resin objects in a single tile - - tweak: Lasers now go through atmos resin objects - Joan: - - tweak: The Necropolis has been rethemed. - Kor: - - rscadd: Added dash weapons, which let you do a short teleport within line of sight. - - rscadd: The ninjas energy katana now lets him dash. He can no longer teleport - with right click. - - rscadd: Glass shards will no longer hurt people with robotic legs. - - rscadd: Mesons work on lavaland again. - Xhuis: - - spellcheck: The names of most glasses, like mesons, t-ray scanners, and night - vision goggles, have been lowercased. - - spellcheck: The thermonocle's description now changes based on the gender of the - person examining it. - - bugfix: Straight jackets can now properly be put onto others. - drline: - - bugfix: Nanotrasen finally sent out IT personnel to plug your modular consoles - back in. You're welcome. -2017-06-28: - Cyberboss: - - rscdel: Cortical borers have been removed - Shadowlight213: - - rscadd: There is now a new monitor program that engineers can use to monitor the - supermatter status - Tacolizard: - - rscadd: NanoTrasen has now outfitted their employees with Extra-Loud(TM) Genetically - Modified Hearts! Now you can hear your heart about to explode when the clown - shoots you full of meth, or hear it slowly coming to a stop as you bleed out - in critical condition after being toolboxed by an unknown gas-mask wearing assistant. -2017-07-07: - Ergovisavi: - - tweak: Added a recovery window after some variable length megafauna attacks - - rscadd: Adds a new mob to the game, the "leaper" - - rscadd: Adds another planetstation mob, the "wanderer/mook" to the backend - - bugfix: Fixes a problem with player controlled leapers where they occasionally - can't fire - Joan: - - tweak: Rethemes the ash walker nest to match the Necropolis. - - balance: Chasms, asteroid turfs, basalt, and lava can no longer be made wet. - - rscadd: A strange new Resonant Signal has appeared on lavaland. - - tweak: Dreams while sleeping are now slightly longer on average and will contain - more possibilities. - - rscadd: Bedsheets may affect what you can dream. - Lexorion: - - imageadd: The portable PACMAN generators now have new icons, including on and - off states. - More Robust Than You: - - rscadd: Nanotrasen has added lids to their soda that POP! when opened. Up to 3 - possible sounds! - - bugfix: brain damage should no longer attempt to emote/say things while unconcious - NanoTrasen Smithy Department: - - soundadd: Tasked by corporate heads to make NanoTrasen's line of captain rapiers - flashier, a few brave smiths have managed to forge their steel in a way that - enhances their swords' acoustic properties. - Shadowlight213: - - rscdel: The majority of the tiny fans on Deltastation have been removed. - - tweak: Airlocks going to space, and secure areas like the bridge and sec on Delta - have been given the cycling system. - - balance: The freedom suit no longer slows you down and can withstand the FIRES - OF LIBERTY! - Steelpoint (Ancient Station): - - rscadd: Major changes to Ancient Station include new sounds for the prototype - RIG hardsuit, the NASA Engineering Voidsuit slowing the user down properly and - new insulated gloves in engineering. - - rscadd: Several minor changes, such as an extra oxygen tank, spawn in equipment - and minor tile changes. - Supermichael777: - - balance: The AI swap menu is now given to the person with the multi-tool rather - than the Borg. Old behavior remains for all non multi-tool sources - - bugfix: Borgs and shells now notify when un-linked due to the wire being cut. - Tacolizard: - - bugfix: Nanotrasen has begun a program to inform the souls of the departed that - their hearts can't beat after death. - - bugfix: heartbeat noises now loop (i can't come up with any dumb fluff for this - one sorry) - That Really Good Soda Flavor: - - bugfix: Martial arts will no longer be transferred in cloning, etc. if they are - temporary (i.e. wrestling, krav maga). - Xhuis: - - tweak: Recollection has been separated into categories and should be easier to - read and more informative. - - bugfix: Ratvar has been reminded that he hates Nar-Sie and will now actively pursue - fighting her. - - bugfix: You can now properly dig out plants from patches of soil. - - bugfix: Reskinnable guns no longer become invisible after firing a single shot. - - bugfix: The kinetic crusher and other forced two-handed objects can now correctly - be stored in a bag of holding. - - bugfix: Positronic brains' icons will now properly change depending on status. - - tweak: Positronic brains will now stop searching as soon as they're occupied. - - tweak: Positronic brains now have error messages if activating them fails for - whatever reason. - - bugfix: Unconscious Servants are now properly informed when they're deconverted. - - bugfix: The Voice of God no longer specifically targets creatures like constructs - and clockwork marauders. - - bugfix: Heartbeat sounds no longer play indefinitely if your body is destroyed. - kevinz000: - - rscadd: Headphones have been provided to the station in Autodrobes, mixed wardrobes, - and fitness wardrobes. Please use them responsibly, and remember to focus on - your job above all else! - - experiment: Headphones fit in head, ears, OR neck slots! - ohnopigeons: - - bugfix: Nanotrasen Electronics have fixed a bug where issued factory-fresh PDAs - did not link to their cartridges, requiring manual reinsertion. - shizcalev: - - balance: Nanotrasen has upgraded the obsolete teleporter consoles on most NT branded - stations with newer ones preloaded with the newest Supermatter monitoring application! - - soundadd: The supermatter base now has a speaker and will provide audio cues as - to it's current status! - somebody: - - rscadd: Strong plasma glass windows -2017-07-09: - Crexfu: - - tweak: 2 plasma sheets have been added to viro break room on box - More Robust Than You: - - bugfix: Plasma and Reinforced plasma glass no longer merge with Normal and Reinforced - Glass - Xhuis: - - bugfix: You can no longer catch objects that require two hands at all times with - only one hand. -2017-07-11: - RandomMarine: - - rscadd: Drones can now switch between help and harm intent. - Tacolizard: - - rscadd: Admins can now set a message/warning when they delay the round end, to - be shown to anyone who tries to reboot the world. - Tacolizard and Cyberboss: - - rscadd: Added two new organs, the liver and stomach. Without them, you won't metabolize - chemicals. - - rscadd: The liver is responsible for processing all chemicals except nutrients. - If your liver is removed, you will be unable to metabolize any drugs and will - slowly die of toxin damage. - - rscadd: Drinking too much alcohol or having too many toxins in you will damage - your liver, if it becomes too damaged, it will undergo liver failure and you - will slowly die of toxin damage. Your liver naturally heals a small amount of - its damage. However, it doesn't heal enough to offset stronger alcohols or large - amounts of toxins, at least until they are metabolized out of your body. - - rscadd: to conduct a liver transplant, inject corazone into the patient. Corazone - will prevent the patient from taking damage due to either not having a liver - or undergoing liver failure. Corazone will metabolize out of the patient quickly, - so at least 50u is recommended. - - rscadd: The stomach is responsible for metabolizing nutrients. Without a stomach, - you will be unable to get fat, but you will also be unable to process any nutrients, - meaning you will eventually starve to death. - Xhuis: - - bugfix: Mobs spawned by Necropolis curses are now immune to chasms. - - tweak: The BoxStation warden's office now has a crew monitoring console. - - imageadd: Clockwork slabs now show icons of the components used in scripture instead - of initials. - factoryman942: - - bugfix: Boxstation Robotics now has 6 flashes, from 2. - - bugfix: Metastation Robotics now has 40 sheets of glass, instead of 20. - shizcalev: - - tweak: The supermatter reporting system has been updated to report remaining integrity, - as opposed to how unstable the SM currently is. -2017-07-18: - BeeSting12: - - tweak: Deltastation's auxiliary storage in arrivals can be accessed by anyone - now. - - bugfix: Deltastation's cargo bay maintenance can now be accessed by cargo techs. - Dannno/Supermichael777/InsaneHyena: - - rscadd: You can now pick from a few different styles when augmenting someone with - robot parts by putting them in the augment manipulator. Alt+click to take parts - out. - Ergovisavi: - - bugfix: Fixed the refresher variant of the anomalous crystal making holodeck items - real - Fox McCloud: - - rscdel: blood and gibs on turfs can no longer infect nearby people - - tweak: Tuberculosis bypasses species virus immunity (it's not a virus!) - - tweak: Disease and appendicitis events no longer infect clientless mobs - - tweak: Disease event will no longer pick virus immune mobs - - tweak: Appendicitis event will no longer pick mobs without an appendix - - bugfix: Fixed changeling panacea curing non-harmful viruses - - bugfix: Fixes IV drips not properly injecting the right amount of blood - Joan: - - rscdel: Removed the Soul Vessel, Cogscarab, and Anima Fragment Scriptures. - - bugfix: The Ark of the Clockwork Justicar will still forcibly take up a 3x3 area - even if it still needs components to activate. - MrStonedOne & Fox-McCloud: - - tweak: Made pathfinding much quicker - NewSta: - - bugfix: Fixes the maid apron being invisible when in-hand or attached to the maid - outfit. - XDTM: - - experiment: Viruses and symptoms have been havily reworked. - - rscadd: Symptoms now have statistic thresholds, that give them new properties - or improve their existing ones if the overall virus statistic is above the threshold. - Check the pull request in github or the wiki (soon) for the full list. - - rscdel: Some symptoms no longer scale linearly with stats, and instead have thresholds. - - tweak: The symptom limit is now 6. - - rscdel: Viruses can no longer be made invisible to the Pandemic - - tweak: Symptoms no longer trigger with a 5% chance every second, but instead have - a minimum and maximum number of seconds between each activation, making them - more consistent. - - rscdel: The symptoms Blood Vomit and Projectile Vomit have been removed, and are - now bonuses for the base Vomit symptom. - - rscdel: The Weakness symptom has been removed as it was completely useless. - - tweak: The Sensory Destruction symptom has been reworked into Narcolepsy, which - causes drowsiness and sleep. - - tweak: Viral Aggressive Metabolism now has a timer before it starts decaying the - virus. It scales with the highest between Resistance or Stage Speed. - - rscadd: You can now neuter symptoms, making them inactive. They will still affect - stats. Adding formaldehyde to a virus will neuter a random symptom. A bottle - of formaldehyde starts in the virus fridge. - Xhuis: - - tweak: The tachyon-doppler array's rotation now has messages, sprites, and examine - text. - - bugfix: Time stop is now fixed, finally! - - soundadd: Time stop's sound now plays in reverse when the effect ends. - - bugfix: Missiles can no longer ricochet off of shuttle walls, etc. - - bugfix: Winter coats now hold all flashlights properly, instead of seclites. - Xhuis & Cyberboss: - - rscadd: New hivebot invasion event - kevinz000: - - rscadd: Personal Cabinets now have piano synthesizers for handheld piano playing. - - experiment: Thank @nicbn for the sprites! - ninjanomnom: - - experiment: Thank you for updating your ShuttlSoft product! Your last update was - -ERROR- years ago. A full changelog can be found at CYG10408.SHSO.b9 along with - the EULA. This update lays a foundation for new things to come and a sample - in the form of new and improved docking procedures. - shizcalev: - - bugfix: Cerestation's emergency shuttle autopilot will no longer fly you in reverse - back to Centcom! -2017-07-27: - Anonmare: - - bugfix: Informs a person about how bomb cores work - BeeSting12: - - rscdel: Water bottles from the sustenance vendor are gone. Wait for the ice in - the ice cups melt, criminal scum. - - rscdel: There is no longer a sink in gulag. Hygiene is for the moral members of - society. - - tweak: Janitor and service cyborgs now get pocket fire extinguishers for fire - suppression and space propulsion. - - rscadd: Pubbystation's dorms now has a dresser. - - bugfix: Crafting satchels from leather now makes a leather satchel rather than - a regular satchel. - Fox McCloud: - - tweak: breathing plasma now causes direct tox damage - - tweak: breathing hot/cold air now warns you when you're doing so, again - - tweak: species heat/cold mod now impacts damage from breathing hot/cold gases - HAL 9000: - - bugfix: I'm sorry Dave, I'm afraid I can't do that - JStheguy: - - imageadd: Resprited the tablet, including completely redone screen sprites. - - rscadd: Tablets can now come spawn in one of 5 colors; red, green, yellow, blue, - and black. - - imageadd: Most alcohol bottles have been resprited, as well as a poster that used - one of the current bottles as part of it's design. - Joan: - - balance: Unwrenching clockwork structures no longer damages them. - - tweak: The Hierophant will now release a burst when melee attacking instead of - actually hitting its target. - - bugfix: The Hierophant Club's blasts will now properly aggro hostile mobs. - - tweak: The blood-drunk miner will fire its KA a bit more often. - PopNotes: - - soundadd: Nar-Sie now sounds like an eldritch abomination that obliterates worlds - instead of a sweet maiden that gently whispers sweet nothings in your ear. - Supermichael777: - - bugfix: delayed chloral hydrate actually works now. - Tacolizard: - - rscadd: Added cybernetic organs to RnD, they can be used to replace organic organs. - Remember to administer corazone during implantation though! - - rscadd: Added the upgraded cybernetic liver. It is exceptionally robust against - toxins and alcohol poisoning. - Xhuis: - - bugfix: Cyborgs now regenerate oxygen damage. - - bugfix: If a cyborg somehow takes toxin damage, it can be healed with cables as - though it was burn damage. - - spellcheck: Picking up ores by walking over them now longer spams messages, instead - showing one message per tile of ore picked up. - - tweak: You can now control-click action buttons to lock them and prevent them - from being moved. Alt-clicking the "Show/Hide Actions" button will unlock all - buttons. - - tweak: There is now a preference for if buttons should be locked by default or - not. - - rscadd: Pizza box stacks can now fall over - - imageadd: Pizza box inhands now stacks depending on how many you're holding. - - bugfix: Mining satchels no longer hold infinite amounts of ore. - - bugfix: Reviving Stasis now consistently regenerates organs. - - bugfix: Medibots now properly render the overlays of the medkits they are made - from. - - bugfix: The latest batch of Syndicate screwdrivers fell into a vat of paint and - were colored randomly. We have rinsed them off and they will no longer come - in random colors. - - bugfix: Supermatter slivers can now be stolen properly. - - tweak: Whenever you're trying to hack off your own limbs, you'll now always hit - those limbs. - Xhuis & MoreRobustThanYou: - - imageadd: Toolbelts now have overlays for crowbars, wirecutters, screwdrivers, - multitools, and wrenches. - Y0SH1_M4S73R: - - bugfix: Romerol zombies count as dead for assassinate and maroon objectives. - bandit: - - rscadd: New Cards against Spess cards are available! - ktccd: - - bugfix: Hijacking should now be possible again! -2017-07-29: - Fox McCloud: - - rscadd: Sound should carry further, but should get quieter and quieter the further - you are from it - Joan: - - tweak: Sigils of Transmission can now drain power in a large area when activated - by a Servant. - - rscdel: Interdiction Lenses have been removed, as they were largely only used - to drain power into Sigils of Transmission. - - balance: Sigils can no longer directly be removed by Servants. - - balance: Prolonging Prisms have a higher cost to delay, but no longer increase - in cost based off of CV. - - balance: Base delay cost changed from 2500W to 3000W, cost increase per activation - changed from 750W to 1250W, cost increase per 10 CV changed from 75W to 0W. - - rscdel: Removed the Volt Blaster scripture. - - rscdel: Ratvarian spears can no longer impale. - - balance: Vitality Matrices now require a flat 150 Vitality to revive Servants, - from 20 + the Servant's non-oxygen damage. Vitality Matrices are also no longer - destroyed when reviving Servants. - - balance: Ratvarian spear damage changed from 18 to 20, Ratvarian spears now generate - 5 Vitality when attacking living targets. Ratvarian spear armour penetration - changed from 0 to 10. - - balance: The Judicial Visor's mark now immediately applies Belligerent and knocks - down for 0.5 seconds. Mark exploding no longer mutes, mark explosion stun changed - from 16 seconds to 1.5 seconds, mark explosion damage changed from 10 to 20. - More Robust Than You: - - rscadd: Nanotrasen has begun production of the Rapid Cable Layer, a tool that - helps you lay down cables faster - - rscadd: You can now craft ghetto RCLs with metal, a screwdriver, welder, and wrench. - They hold less cable, and may fall apart or jam! - Xhuis: - - spellcheck: Player-controlled medibots now receive a notice whenever they try - to heal someone with too high health. - - bugfix: Syringes now properly inject targets wearing thick clothing on different - slots. - - bugfix: Stun baton overlays now appear on security belts when active. - kevinz000: - - rscadd: 'Badmins: Buildmode map generators have names in the list to select them, - instead of paths.' - - rscadd: Also, a new map generator has been added, repair/reload station. Use it - VERY sparingly, it deletes the block of the map and reloads it to roundstart. - THIS CAN CAUSE ISSUES WITH MACHINES AND ATMOSPHERICS, SO DO NOT USE IT UNLESS - YOU ABSOLUTELY HAVE TO! - - experiment: The reload station one tagged DO NOT USE shouldn't be used as it doesn't - delete anything before loading, so if you use it you'll have two copies of things. - That can result in a LOT of issues, so don't use it unless you're a codermin - and know what you're doing/abusing! - ktccd: - - bugfix: Ashstorms no longer pierces the protected people to kill anyone/anything - in them. -2017-08-06: - Anonmare: - - rscadd: Surgical toolarm to protolathe and exofab - - tweak: Toolarm tools are less robust but more efficient at surgery - - tweak: Arm augments are no longer a huge item - AnturK: - - balance: Cyborg remote control range is now limited to 7 tiles. - Ergovisavi: - - rscadd: Adds the "seedling" planetstation mob to the backend - Floyd: - - bugfix: No longer does everyone look like a sick, nauseated weirdo! - Galactic Corgi Breeding Mills, LLC: - - bugfix: Fixed corgis being able to wear spacesuit helmets despite lacking the - proper code and sprites for them. - Joan: - - tweak: Colossus's shotgun is now a static-spread blast of 6 bolts, making it more - predictable. - - balance: Geis now mutes for 12-14 seconds and "stuns" the target, via a binding - effect, for 25 seconds instead of initiating a conversion. - - experiment: Geis's "stun" restrains the target and prevents them from taking actions, - but its duration is halved if the binding is not being pulled by a Servant. - - wip: Using Geis on a target prevents you from taking actions other than attempting - to pull the binding. If you are pulling the binding, you can dispel it at any - time. - - wip: As should be obvious, if the binding is destroyed or dispelled, you can once - again take normal actions. - - tweak: Sigils of Submission are now permanent and have been moved from the Script - tier to the Driver tier, with an according cost adjustment. They still do not - penetrate mindshield implants. - - rscdel: Removed Taunting Tirade. - - rscdel: Removed Sigils of Accession. - Lexorion: - - imageadd: Hearty Punch has a new, fancier sprite. - More Robust Than You: - - bugfix: RCL and Ghetto RCLs are no longer invisible - - bugfix: RCL action button now has a sprite - - bugfix: RCLs can no longer go inside you - XDTM: - - bugfix: Eyes can now be properly damaged. - Xhuis: - - spellcheck: Removed an improper period from the supermatter sliver theft objective's - name. - - bugfix: Alien hunters can no longer pounce through shields. - - bugfix: Observing mobs that have no HUD will no longer cause intense lighting - glare. - - bugfix: Objects on shuttles now rotate in the correct directions. - - soundadd: The speakers in the ceiling have been upgraded, and many sounds are - now less tinny. - Xhuis and oranges: - - bugfix: Banana cream pies no longer splat when they're caught by someone. - - soundadd: Throwing a pie in someone's face now has a splat sound. - kingofkosmos: - - bugfix: Fixed hair sticking through headgear. -2017-08-13: - JStheguy: - - imageadd: Laptops now have actual sprites for using the supermatter monitoring - instead of defaulting to a generic one. - Joan: - - imageadd: Belligerent now has a visible indicator over the caster. - More Robust Than You: - - tweak: Mulligan and non-continuous completion checks will not consider afk/logged - out people to be "living crew". - - tweak: The wiki button now asks what page you want to be taken to - - tweak: His Grace now shows up on the orbit list - Pubby: - - rscadd: The Curator job is now available on PubbyStation - - rscadd: Beekeeping has been added to PubbyStation's monastery - - tweak: PubbyStation's bar has been rearranged - Xhuis: - - bugfix: Swarmer shells now have ghost notifications again. - - bugfix: Minebots no longer lack icons for their action buttons. - kingofkosmos: - - imageadd: Adds icon_states to the unused and used Eldritch whetstones. Sprites - by Fury McFlurry. -2017-08-14: - Joan: - - imageadd: Ported CEV-Eris's APC sprites. - More Robust Than You: - - bugfix: Fixes a typo in the blobbernaut spawn text - WJohnston: - - rscadd: Adds an ore box and shuttle console to aux bases on all stations. - Xhuis: - - bugfix: The Resurrect Cultist rune now works as intended. - - bugfix: Cyborg energy swords now properly have an icon. - kingofkosmos: - - tweak: Canisters don't flash red lights anymore when empty. -2017-08-19: - Anonmare: - - balance: Raised airlock deflection by one point - BeeSting12: - - balance: The meth explosion temperature has been raised. - FrozenGuy5/PraiseRatvar: - - balance: Nerfs L6 SAW Hollow Point Bullets from -10 armour penetration to -60 - armour penetration. - Joan: - - balance: Deathsquads no longer get shielded hardsuits. - More Robust Than You: - - rscadd: Blobs can now sense when they're being cuddled! - - bugfix: Fixes mining hardsuit heat_protection - - bugfix: RCL icons are now better at updating - NewSta: - - bugfix: Fixes the wiki button - - spellcheck: Fixes a typo in the wiki button description - XDTM: - - rscadd: You can now click on symptoms in the Pandemic to see their description - and stats - Xhuis: - - soundadd: The station's explosion now uses a new (or old) sound. - - rscadd: Adds smart metal foam, which conforms to area borders and walls. It can - be made through chemistry by mixing foaming agent, acetone, and iron. - - rscadd: Smart metal foam will create foamed plating on tiles exposed to space. - Foamed plating can be struck with floor tiles to turn it into regular plating! - - spellcheck: The chat message has been removed from *spin. I hope you're happy. - nicbn: - - imageadd: Nanotrasen redesigned the area power controllers! - - imageadd: Thanks Xhuis for the contrast tweak on APCs -2017-08-23: - Cobby: - - balance: Planting kudzu now has a short delay with a visible message to users - around you. Hit-N-Run planting is no longer possible. - - rscdel: kudzu bluespace mutation and spacewalk mutation are removed. - Cruix: - - rscadd: The syndicate shuttle now has a navigation computer that allows it to - fly to any unoccupied location on the station z-level. - Ergovisavi: - - tweak: Slightly increased the radius of the atmos resin launcher, and resin now - makes floors unslippery - Pubby: - - rscadd: Gorillas - - rscadd: Irradiating monkeys can now turn them into hostile gorillas - Shadowlight213: - - experiment: The amount of time spent playing, and jobs played are now tracked - per player. - - experiment: This tracking can be used as a requirement of playtime to unlock jobs. - ShizCalev: - - balance: Morphlings now have to restore to their original form before taking a - new one. - - bugfix: Morphlings will no longer have combined object appearances - Supermichael777: - - bugfix: Boss tiles have been reconstructed out of an unstoppable force. - TehZombehz: - - rscadd: Nanotrasen Culinary Division has authorized the construction of pancakes, - including blueberry and chocolate chip pancakes. Pancakes can be stacked on - top of each other. -2017-08-26: - Cyberboss: - - rscadd: Added the credits roll - Iamgoofball: - - rscadd: Plasmamen now hallucinate with blackpowder in their system - Joan: - - balance: Geis bindings no longer decay faster if not pulled by a Servant, but - last for 20 seconds, from 25. - - tweak: Geis bindings will decay slower when on a Sigil of Submission, and, if - being pulled by a Servant when crossing a Sigil of Submission, will helpfully - remove the pull. - - tweak: Removing Geis bindings is no longer instant and can be done by any Servant - with a slab, not just the initiator. - - wip: Geis no longer prevents you from taking actions, but you remain unable to - recite scripture while the target is bound. In addition, dealing damage to a - bound target will cause the bindings to decay much more rapidly. - - rscadd: You can now remove sigils by hitting them with a clockwork slab for a - small refund. - More Robust Than You: - - balance: Lowers the chance for monkeys to become gorillas - - rscadd: Holoparasite prompts now have a "Never For This Round" option - Naksu: - - spellcheck: fixed inconsistent grammar between machines that derive from /obj/machinery/chem_dispenser - - spellcheck: touched up some chat messages to include references to objects instead - of "that" or "the machine" etc., also removed references to beakers being loaded - in machines that can accept any container -2017-08-30: - CPTANT: - - balance: Hacked AI module cost is reduced to 9TC - Cobby & Cyberboss: - - rscadd: A stealth option for the traitor microlaser has been added. When used, - it adds 30 seconds to the cooldown of the device. - Cyberboss (unwillingly by Kor's hand): - - balance: You no longer take damage/are as heavily blinded in crit while above - -30HP - - balance: Whispering in crit above -30HP will not cause you to succumb - - balance: You can now hear in crit above -30HP - Joan: - - imageadd: Cult blades have updated item and inhand sprites. - Kor: - - rscadd: Added Shadow Walk, a new form of jaunt that lasts for an unlimited amount - of time, but ends if you enter a well lit tile. It is planned for use in a Shadowling - rework, but feel free to hassle admins to test it out in the mean time. - - balance: Slime people can consume meat and dairy again. - Lzimann: - - rscadd: Ghosts now have a way to see all available ghost roles! Check your ghost - tab! - MMMiracles: - - rscdel: Cerestation has been decommissioned. Nanotrasen apologizes for any spikes - of suicidal tendencies, sporadic outbursts of primitive anger, and other issues - that may of been caused during the station's run. - Naksu: - - bugfix: fixed portable chem dispensers charging 50% slower than intended when - initialized. - - bugfix: fixed portable chem dispensers getting faster charging rate every time - refreshparts() is called - Pubby: - - rscadd: Crew-tracking pinpointers to replace laggy crew monitoring console functionality - - rscadd: Crew-tracking pinpointers in medical vendors and the detective's office - RemieRichards: - - rscadd: AltClick listing now updates instantly on AltClick - - bugfix: AltClick listing no longer reveals obscured items - ShizCalev: - - tweak: The singularity now poses a threat towards asteroids as well as stations. - - tweak: All power systems will now report their wattage values in Watts, Kilowatts, - Megawatts, and Gigawatts. Gone are the days of seeing 48760 W total load when - working with an APC! - kingofkosmos: - - tweak: You can now unbuckle out a chair/bed by moving. - ninjanomnom: - - bugfix: Fixed a problem with shuttles being unrepairable under certain circumstances. -2017-09-01: - Fury McFlurry: - - rscadd: Added more halloween costumes. - - rscadd: Among them are a lobster suit, a cold villain costume and some gothic - clothes - More Robust Than You: - - rscdel: Finally fucking removed gangs - MrStonedOne: - - rscadd: Player notes can now be configured to fade out over time to allow admins - to quickly see how recent notes are. Server Operators, check the config for - more info - Pubby: - - rscdel: The multiverse sword is toast - YPOQ: - - bugfix: Pouring radium into a ninja suit restores adrenaline boosts. - - bugfix: Adrenaline boost works while unconscious again. - - bugfix: Energy nets can be used again! -2017-09-02: - Frozenguy5: - - tweak: Added new station prefixes, names and suffixes! - Tortellini Tony: - - tweak: Round-end credits can now be toggled on or off in the server game options. - XDTM: - - tweak: The Disease Outbreak event now can generate random advanced viruses, with - more symptoms and higher level as round time goes on. -2017-09-11: - Anonmare: - - balance: Altered pressure plate crafting recipe - Basilman: - - rscadd: A strange asteroid has drifted nearby... - Firecage: - - rscadd: The NanoTrasen Department for Cybernetics (NDC) would like to announce - the creation of Cybernetic Lungs. Both a stock variety to replace traditional - stock human lungs in emergencies, and a more enhanced variety allowing greater - tolerance of breathing cold air, toxins, and CO2. - JJRcop: - - rscadd: Admins can now play media content from the web to players. - - rscadd: Adds a volume slider for admin midis to the chat options menu. - Jay: - - bugfix: Goliaths can be butchered again - Joan: - - tweak: While below 0 health but above -30 health, you will be able to crawl slowly - if not pulled, whisper, hear speech, and see with worsening vision. - - wip: The previous softcrit got reverted, for changelog context. - - rscdel: Standard attacks, such as swords, hulk punches, mech punches, xeno slashes, - and slime glomps, will no longer damage clothing. - Kor: - - rscadd: People in soft crit will take oxyloss more slowly than people in full - crit if they remain still. - - rscadd: People dragging themselves in critical condition will now leave blood - trails. This will rapidly deal oxyloss to you. - MrStonedOne: - - rscadd: Admins may now show the variables interface to players to help contributors - debug their new additions - Naksu: - - rscadd: Added TGUI interfaces to various smartfridges of different kinds, drying - racks and the disk compartmentalizer - Pubby: - - bugfix: Escape pods and PubbyStation's monastery shuttle are back in commission - Robustin: - - tweak: Golem shells no longer fit in standard crew bags. - Supermichael777: - - bugfix: Stands now check if their user got queue deleted somehow - VexingRaven: - - bugfix: Hearty Punch once again pulls people out of crit. - Xhuis: - - spellcheck: Various grammar in the Orion Trail arcade game has been tweaked. - - rscadd: You can now kill yourself in fun and creative ways with the hierophant - club. - - rscadd: Common lavaland mobs now have rare mutations! Keep an eye out for rare - Poke- err, monsters. - - imageadd: The hand drill and jaws of life now have sprites on the toolbelt. - YPOQ: - - bugfix: Windoors open when emagged again - as334: - - rscadd: Added a mass spectrometer to the detective's closet - basilman: - - rscadd: penguins may now have shamebreros, noot noot -2017-09-13: - BeeSting12: - - balance: The stetchkin APS pistol is smaller. - - rscadd: The 9mm pistol magazines can be purchased from nuke op uplinks at two - telecrystals each. - Kor: - - rscadd: Added Nightmares. They're admin only currently, so as usual, make sure - to beg admins to be one. - - rscadd: The Chaplain may now choose the Unholy Blessing as a null rod skin. - KorPhaeron: - - rscadd: Added Jacob's ladder to the necropolis chest - Lordpidey: - - bugfix: Centcom roundstart threat reports are fixed, and can now be used to narrow - down the types of threats facing the station. - MrROBUST: - - rscadd: Mechs now can be connected to atmos ports - VexingRaven: - - bugfix: Changeling Augmented Eyesight ability now grants flash protection when - toggled off - - bugfix: Changeling Augmented Eyesight ability can now be toggled properly - - bugfix: Changeling Augmented Eyesight ability is properly removed when readapting - - bugfix: The syndicate have once again stocked the toy C20r and L6 Saw with riot - darts. - Xhuis: - - rscadd: You can now use metal rods and departmental jumpsuits to craft departments - for each banner. - - tweak: The lavaland animal hospital ruin has been remapped, including more supplies - as well as light sources. -2017-09-14: - BeeSting12: - - balance: Deltastation's and Metastation's armory now starts with three riot shotguns! - Fun Police: - - rscdel: Removed some of the free lag. - Kor: - - bugfix: It is possible to multitool the cargo computer circuitboard for contraband - again - ShizCalev: - - bugfix: Holding a potted plant will no longer put you above objects on walls. - - bugfix: Replaced leftover references to loyalty implants with mindshield implants. - ninjanomnom: - - bugfix: Shuttle transit parallax should be working again -2017-09-16: - Basilman: - - rscadd: Gondolas are now procedural generated. - Mey-Ha-Zah: - - imageadd: Updated the knife sprite. - Naksu: - - bugfix: Evidence bags will no longer show ghosts of items such as primed flashbangs - after the flashbang inside explodes - - bugfix: Prevents dead monkeys from fleeing their attackers or escaping His Grace - only to be eaten again - - rscdel: Corgis can no longer be targeted by facehuggers - - rscdel: Removed unused vine floors and their sprite. - Robustin: - - rscadd: Due to budget cuts, airlocks that control access to non-functional maint - rooms and other abandoned areas now have a chance to spawn welded, bolted, screwdrivered, - or flat out replaced by a wall at roundstart. - - bugfix: Dice will now roll when thrown - YPOQ: - - rscadd: Ninja adrenaline boost removes stamina damage - - bugfix: Depowered AIs can no longer use abilities or interact with machinery - - bugfix: The doomsday device will again periodically announce the time until its - activation - - bugfix: Crafting stackable items results in the right stack sizes -2017-09-18: - More Robust Than you: - - balance: Blobbernauts are healed quicker by cores and nodes - Naksu: - - bugfix: OOC for dead people is now (re-)enabled at round-end - - bugfix: Fixed chemfridges being unable to display items with dots in their name - Pubby: - - rscadd: Traitorbro gamemode - Supermichael777: - - bugfix: Airlocks now check metal for upgrades using the standard get_amount() - proc instead of checking the amount var, this means it is compatible with cyborgs. - TungstenOxide: - - tweak: Swapped the action of purchasing a pAI software and subtracting the RAM - from available pool. - Xhuis: - - balance: Brave Bull now increases your max HP by 10, up from 5. - - rscadd: Tequila Sunrise now makes you radiate dim light while it's in your body. - - rscadd: Dwarves are now very resistant to the intense alcohol content of the Manly - Dorf and can freely quaff them without too much worry. - - rscadd: Bloody Mary now restores lost blood. -2017-09-20: - PopNotes: - - imageadd: Airlocks animate faster. This doesn't change the time it takes to pass - through an airlock, but it does visually match up much better so you don't just - appear to glide through the airlock while it's half-open. - Pubby: - - bugfix: Atmos pipenets are less glitchy - TehZombehz: - - rscadd: Several new plushie dolls are now available in toy crates. -2017-09-22: - AutomaticFrenzy: - - bugfix: Mice spawning finds the station z level properly - CPTANT: - - balance: Knockdown and unconcious now let you regenerate stamina damage. - - rscadd: Sleeping regenerates more stamina damage. - Naksu: - - bugfix: Admin ghosts can no longer unintentionally make a mess of things. -2017-09-23: - Armhulen: - - rscadd: Rare Spider Variants have arrived! Every spiderling has a rare chance - of growing up to a rare version of their original spider type! - - rscadd: Special thanks to Onule for the sprites, you're the best! - JJRcop: - - rscadd: Suiciding with a ballistic gun now actually blows your brain out. - More Robust Than You: - - tweak: Taking the beaker out of a cryotube now tries to put it into your hand - - code_imp: Removed some spawn()s from secbot code - - bugfix: Using a soulstone on somebody now transfers your languages to the shade - - bugfix: Zombies now stay dead if they suicide - - rscadd: If a zombie suicides, they now rip their head off! - - bugfix: pAIs now transfer their languages to bots - - bugfix: Support Holoparasites must be manifested to heal - Robustin: - - balance: A zombie's automatic self-healing is stopped for 6 seconds after taking - damage. - - bugfix: Deconverted revs will now always get a message, logs will now include - more details. - YPOQ: - - bugfix: Pet persistence works again -2017-09-27: - Arianya: - - balance: Lesser ash drakes no longer drop ash drake hide when butchered. - GLA Coding: - - tweak: Cells must now be installed in mechs when being constructed, this step - is always before the application of internal armor. - - bugfix: Combat mechs now get stats upgrades from their scanning modules and capacitors - Improvedname: - - rscadd: Adds racial equality to color burgers - More Robust Than You: - - rscadd: Implant Chairs now also support organs - Naksu: - - bugfix: Fixed jump boots breaking if used when you can't jump, such as when inside - a sleeper. - - code_imp: Removed meteor-related free lag. - - bugfix: Syndicate MMIs will now properly transfer their laws to newly-constructed - AIs - Pubby: - - rscadd: Bluespace pipes to atmospherics, which create a single pipenet with all - bluespace pipes in existence. -2017-09-28: - RandomMarine: - - imageadd: Air tanks (o2+n2) now have a different appearance from oxygen tanks. - Robustin: - - tweak: Revheads no longer spawn with chameleon glasses or a spraycan, instead - they will start with a cybernetic security HUD implanted into their eyes. - Xhuis: - - rscadd: Ian has recently communed with unspeakable horrors and may now be warped - by their power if Nar-Sie passes near them. - - rscadd: In order to fight back against their ancient foe Ian, Poly has struck - a bargain with Ratvar and will be transformed into a machine by their presence. - Y0SH1_M4S73R: - - bugfix: AFK players count as dead for the assassinate objective. -2017-09-29: - Kor: - - rscadd: Gunfire can now leave bullet holes/dents in walls. Sprites by JStheguy. - RandomMarine: - - rscadd: You can now light your cigs with people that are on fire. The surgeon - general is spinning in their grave. - Robustin: - - tweak: Hacking a secure container with a multitool now takes longer, but no longer - has a chance to fail. - XDTM: - - rscadd: Nurse spiders can now set a directive that will be seen by their spiderlings, - when they get controlled by a player. - - rscadd: Spiders' actions are now action buttons instead of verbs. - - rscadd: Wrapping stuff in a cocoon is now a targeted action! - kevinz000: - - rscadd: The syndicate have recently begun sending agents to extract vital research - information from Nanotrasen. - - bugfix: 'Timestop fields will now stop thrown objects experimental: Timestops - will now be much quicker to react.' - kingofkosmos: - - spellcheck: You can now find out if an item uses alt-clicking by examining it. -2017-10-07: - Antur: - - bugfix: Liches will no longer lose their spells when reviving. - AnturK: - - rscadd: Wigs are now available in AutoDrobe - Cobby: - - admin: Players will now be notified automatically when an admin resolves their - ahelp. - Cyberboss: - - config: The shuttle may now be configured to be automatically called if the amount - of living crew drops below a certain percentage - - bugfix: Fixed a rare case where creating a one tank bomb would result in a broken - object - - bugfix: Fixed many cases where forced item drops could be avoided by not having - an item in your active hand - DaxDupont: - - rscdel: No more roundstart tips about gangs. You can finally start to forget gangs - ever existed. - Incoming5643: - - bugfix: The rarely utilized secret satchel item persistence system has been fixed - and made more lenient. - - rscadd: 'In case you forgot how it works: if you find or buy secret satchels, - put an item in them, and then bury them under tiles on the station you or someone - else can find them again in a future round with the item still there! Free satchels - can often be found hiding around the station, so get to burying!' - JJRcop: - - config: Hosts can now lock config options with the @ prefix. This prevents admins - from editing the option in-game. - - tweak: Admin volume slider moved to its own menu for better visibility. - Joan: - - bugfix: Fixes Vanguard never stunning for more than 2 seconds. - - balance: Ocular Warden base damage per second changed from 12.5 to 15. - - bugfix: Ocular Wardens no longer count themselves when checking for dense objects, - which decreased their overall damage by 15%. - - balance: Ocular Wardens now only reduce their damage by 10% per dense object, - and only do so once per turf. However, dense turfs now reduce their damage with - the same 10% penalty. - Kerbin-Fiber: - - bugfix: Wood is no longer invisible - Kor: - - rscadd: Nightmares now have mutant hearts and brains, with their own special properties - when consumed or implanted in mobs. Experiment! - - bugfix: You can now tell when someone is in soft crit by examining them. - - rscadd: Nightmares now have a chance to spawn via event. - More Robust Than You: - - bugfix: Fixes cogscarab sprites not updating - - balance: Blobs now take damage from particle accelerators - MrDoomBringer: - - rscadd: Nanotrasen, as part of their new Employee Retention program, has encouraged - more station point-makery by adding the "Cargo Tech of the Shift"! The award - is located in a lockbox in the Quartermaster's locker. - MrStonedOne: - - tweak: The MC will now reduce tick rate during high populations to keep it from - fighting with byond for processing time. - - config: Added config options to control MC tick rate - - admin: Admins can no longer manually control the mc's tick rate by editing the - MC's processing value, instead you will have to edit the config datum's values - for high/low pop tick rates. - Naksu: - - bugfix: Removed some of the free lag - - bugfix: Updates to station name are now reflected on Cargo's stock exchange computers. - - bugfix: Gutlunches will now once again look for gibs to eat. - - bugfix: Bees now come with reduced amounts of free lag - - balance: Pyrosium and cryostylane now react at ludicrous speeds. - - tweak: Made atmos tiny bit faster - - bugfix: Tweaks to atmos performance - Qbopper: - - tweak: Moved a locker blocking an airlock in Toxins maintenance. - RandomMarine: - - bugfix: Simple mobs should no longer experience severe hud/lighting glitches when - reconnecting. - Robustin: - - rscadd: Blood cultists can now create a unique bastard sword at their forge - - rscdel: Blood cultists can no longer obtain a hardsuit from the forge - - bugfix: Emotes (e.g. spinning and flipping) will now properly check for consciousness, - restraints, etc. when appropriate. - - bugfix: The Cult's bastard sword should now properly store souls and create constructs. - - bugfix: Neutering a disease symptom now produces a unique ID that will ensure - the PANDEMIC machine copies it properly. - ShizCalev: - - bugfix: You now have to unbuckle a player PRIOR to shaking them up off a bed or - resin nest. - - bugfix: Wizards will now have the correct name when attacked with Envy's knife! - - soundadd: Space ninja energy katanas now make a swish when drawn! - Supermichael777: - - balance: The detectives gun has been restored from a system change that nerfed - knockdown in general. We need to have a serious discussion about anti revolver - hate in this community. - - tweak: The PDA default font has been switched from "eye bleed" to old-style monospace. - Check your preference. - Thefastfoodguy: - - bugfix: Silicons can no longer take brain damage - - bugfix: Antimatter shielding that can't find a control unit won't delete itself - anymore - WJohnston: - - rscadd: Boxstation and Metastation's white ships now have navigation computers, - letting you move them around in the station, deep space, and derelict z levels. - XDTM: - - rscadd: Added the H.E.C.K. suit, a guaranteed loot frop from Bubblegum. - - rscadd: The H.E.C.K. suit is fully fire (and ash) proof, and has very good melee - armor. - - rscadd: H.E.C.K. suits can also be painted with spraycans, to fully customize - your experience. - - rscadd: Despite spending centuries inside a demon king, H.E.C.K. suits are most - definitely safe. - - bugfix: Fixed a bug where Viral Aggressive Metabolism caused viruses to be cured - instantly. - - bugfix: Fixed a bug where viruses' symptoms would all instantly activate on infection. - - rscadd: The CMO now has an advanced health analyzer in his closet! It can give - more precise readings on the non-standard damage types. - Xhuis: - - bugfix: Runed metal and brass are no longer invisible. - Xhuis and Y0SH1_M4S73R: - - bugfix: Servants of Ratvar now spawn in as the actual race set on their preferences, - with plasmamen getting the gear they need to not immediately die. - Y0SH1_M4S73R: - - balance: Gygax overdrive consumes at least 100 power per step - YPOQ: - - bugfix: Jaunters equipped on the belt slot will save you from chasms again. - kevinz000: - - rscadd: Wormhole event wormholes now actually teleport you. - - bugfix: portals now actually teleport on click. - kingofkosmos: - - rscadd: You can now see construction/deconstruction hints when examining airlocks. - - spellcheck: Beds, chairs, closets, grilles, lattices, catwalks, tables, racks, - floors, plating and bookcases now show hints about constructing/deconstructing - them. - nicbn: - - rscadd: Paperwork now uses Markdown instead of BBCode, see the writing help for - changes. - - imageadd: Changed the drop, throw, pull and resist icons. -2017-10-15: - Armhulen: - - bugfix: Clockwork golems no longer slip and slide on glass! - Armie: - - tweak: Holoparasites are once again in the uplink. - Bawhoppen: - - tweak: Smoke machine board has been moved to tech storage. - DaxDupont: - - tweak: After lobbying by Robust Softdrinks and Getmore Chocolate Corp all vendor - firmware has been changed to add sillicons to their target demographic. - - spellcheck: Replaces instances of "permenant" and "permenantly" with the proper - spelling in several areas, - Epoc: - - rscadd: Added a Toggle Underline button to the PDA menu - - code_imp: Cleaned HTML spacing - Frozenguy5: - - bugfix: C20r damage upped from 20 to 30 (used to be 30 before an ammo cleanup - in the code) - GLACoding: - - bugfix: Syndicate turrets and other machines in walls can now be hit by projectiles - Improvedname: - - rscadd: You can now put custom name and lore on your holy weapon by using a pen - on it! - - tweak: Cmo, captain, and the bartender now get pet collars in their lockers. - Jambread/RemieRichards/Incoming5643: - - server: There is a new system for title music accessible from config/title_music - folder. This system allows for multiple rotating lobby music without bloating - Git as well as map specific lobby music. See the readme.txt in config/title_music - for full details. - - config: The previous method of title music selection, strings/round_start_sounds.txt - has been depreciated by this change. - Kor: - - balance: You can now smash the bulbs out of floodlights rather than having to - entirely destroy the object. - Mercenaryblue: - - rscadd: Use the Clown Stamp on some cardboard to begin... the honkbot! - - rscadd: These honkbots are just adorable, and totally not annoying. I swear! Honk! - - rscadd: You can even slot in a pAI! Just don't emag them... oh boy. oh no. oh - geez. - - soundadd: Honkbots now release an evil laugh when emagged. - - imageadd: added some in_hands for banana peels. - - tweak: Golden Bike Horns now permit its victims to perform a full flip before - forcing them to jump again. - More Robust Than You: - - bugfix: Makes the santa event properly poll ghosts - - bugfix: Diseases will now cure if species is changed - - tweak: You can now drag-drop people into open DNA scanners - - bugfix: Medibots will no longer inject people in lockers/sleepers/etc - Naksu: - - bugfix: Fixes to door/airlock deletion routines. - - bugfix: Traitor pen uplinks now preferentially spawn in the PDA pen, and not in - a pocket protector full of pens that no-one checks. - - bugfix: Reusable projectiles such as foam darts no longer get deleted if they're - shot at a shooting range target or a cardboard cutout. - - bugfix: Ghosts no longer inherit the movement delay of their former bodies. - - bugfix: Fixed mobs being able to smash shocked objects without taking damage. - - bugfix: Fixed some mobs not deleting correctly - - code_imp: Fixed dusting code, supermatter-suicides no longer spam the runtime - logs. - - code_imp: Fixed some initialize paths. - Onule: - - tweak: Sunflower sprites were changed, small edits to variants. - - imageadd: Sunflower and variant's inhands sprites. - - imageadd: Tweaked growing sprites to match the new sunflower. - - imageadd: Moonflower and novaflowers now have slightly different growing sprites. - Robustin: - - rscadd: The Chemistry Smoke Machine! Chemist offices will have a board available - should they choose to construct a smoke machine. The smoke machine will regularly - produce smoke from whatever chemicals have been inserted into the machine. Designs - for the circuitboard are also available at RND. - - tweak: Abandoned Airlocks will no longer be deleted when their turf is changed - to a wall. - - tweak: Tesla movement is now completely random. - - bugfix: Clock Cult mode will no longer end if all the cultists die. The round - will not end until the Ark is destroyed or completed. - - bugfix: Chain reactions between explosives will now properly trigger explosives - located in an individual's bag. - - tweak: The wrench-anchoring time of the smoke machine is now doubled to 4 seconds. - - tweak: Smoke Machine smoke is now transparent. - - rscadd: The smoke machine has taken its rightful place in the chemist's office. - - bugfix: Smoke machine will no longer operate while moving/unanchored. - ShizCalev: - - tweak: Nanotrasen brand "Box" model stations have received approval from CentCom - to be retrofitted with the latest in Xenobiology equipment. You will now find - a chemmaster, a chemical dispenser, and a dropper within the Research Division's - Xenobiology lab. - - bugfix: C4 will no longer appear underneath objects on walls. - - bugfix: Plastic explosives will no longer be invisible after being planted. - - imageadd: The security bombsuit's sprite has been updated! - SpaceManiac: - - spellcheck: Grammar when examining objects has been improved. - - bugfix: AI eye camera static is now correctly positioned on Lavaland. - - spellcheck: Fixed many instances of "the the" when interacting with objects. - - bugfix: The tracking implant locator now works on the station again. - WJohn: - - rscadd: An old cruiser class vessel has resiliently stuck around, and may do so - for the foreseeable future. - WJohnston: - - tweak: Due to age, the abandoned ship's engines are now considerably slower when - bringing it place to place. This does however mean that the ship now has a more - gradual takeoff, with no sudden jolt to knock passengers off their feet. - - imageadd: Black carpets no longer have an ugly periodic black line in them. Regular - catwalks are now totally opaque so you won't accidentally click on space when - trying to place wires or tiles on them. - - rscdel: Boxstation's guitar white ship is no more. - - rscadd: Metastation's white ship stands in its place! - - tweak: Metastation's white ship has a couple of weak laser turrets to protect - the cockpit from space carp. - - tweak: Boxstation and metastation now have some plating under the grilles near - the AI sat's transit tube to prevent players from deleting the tube by landing - there. - WJohnston & ninjanomnom: - - rscadd: Plastitanium walls smooth, fancier syndicate shuttles! - - bugfix: Infiltrator shuttles have been moved out of the station maps and made - into a multi-area shuttle. - - balance: Titanium and plastitanium have explosion resistance (requested by Wjohn) - XDTM: - - rscadd: Blood and vomit pools can now spread the diseases of the mob that made - them! Cover your feet properly to avoid infection. - - rscadd: Virus severity now changes the color of the disease HUD icon, scaling - from green to red to flashing black-red. - - tweak: Contact-based diseases no longer spread by simply standing near other people; - it requires interaction like touching or attacking. Bumping against people/swapping - with help intent still counts as touching. - - tweak: Advanced viruses now have another infection type, "Fluids"; it's between - blood and skin contact, and will only be transmitted through fluid contact. - - rscdel: Two "hidden" infection types have been removed. Overall this means that - making a virus airborne is a little bit easier. - - bugfix: Species who cannot breathe can no longer be infected by breathing. - - bugfix: Internals now properly work if set to 0 pressure, and will prevent breathing - gas from the external atmosphere. - - bugfix: Viral Aggressive Metabolism is now properly inactive when neutered. - Xhuis: - - tweak: Cogscarabs can now experiment more freely with base design during non-clockcult - rounds with infinite power and the ability to recite scripture! - - bugfix: The Ark of the Clockwork Justiciar is now registered as a hostile environment. - - refactor: Clockwork scripture now has one progress bar for the entire recital - instead of multiple ones for each sentence in the invocation. - - bugfix: Ocular wardens no longer have a burning hatred for revenants and won't - attack their corpse endlessly anymore. - - balance: Stargazers can no longer be built off-station, even in new areas. - - balance: Integration cogs no longer emit sounds and steam visuals when active. - armie: - - bugfix: mob spawners are no longer possessable - deathride58: - - rscadd: '*slap' - duncathan: - - bugfix: Scrubbers and filters no longer allow for infinite pressure in pipes. - improvedname: - - bugfix: 9mm doesn't longer appear in traitor surplus crates - kevinz000: - - bugfix: 'Flightsuits now allow proper pulling experimental: Moved now has an argument - for if it was a regular Move or a forceMove.' - - rscadd: Instead of dumb sleep()s, follow trails now use SSfastprocess for processing! - - rscadd: Mobs now float while flying automatically! - - rscdel: 'Flightsuits can no longer be safely shut off if you''re still barreling - down the hallway. experimental: Flightsuits should be less shitcode. Hope this - PR doesn''t blow anything important up!' - - bugfix: Fixed trying to clear beaker in pandemic when the beaker is already removed - causing a runtime. - kingofkosmos: - - rscadd: Alt-clicking on a computer now ejects the ID card inside it. - nicbn: - - tweak: You can now clear bullet holes in walls using a welding tool. - ninjanomnom: - - refactor: Radiation has been completely overhauled. - - rscadd: A new radiation subsystem and spreading mechanics. - - rscadd: Walls and other dense objects insulate you from radiation. - - rscadd: Geiger counters now store the last burst of radiation so you can view - it at your leisure or show it to someone. Examine it. - - rscadd: Geiger counters can check mobs for contaminated objects. Scan yourself - before you leave to make sure you aren't carrying dangerous radioactive items. - - soundadd: Geiger counters have realistic sounds and the radiation pulse spam in - chat has been replaced. - - balance: Radiation is more deadly and causes burns at high intensities, WEAR YOUR - RADSUITS. - - balance: However residue radiation is far slower acting and kills you with toxin. - - balance: Engineering holosigns have a light amount of radiation insulation. - - balance: Rad collectors are nerfed. No more supercharging with pressurized plasma. - No more collector spam either. - - balance: Engine output is a lot more stable as a result of collector changes. - - balance: Monkeys need more rads and take more time to turn into gorillas. - - tweak: Over 100% on the DNA computer means your subject is now taking damage. - - tweak: The asteroid escape shuttle has no stabilizers and throws you around when - it moves - - bugfix: Shuttles no longer rotate ghosts of players who prefer directionless sprites - - bugfix: 2 Years later and cameras work on shuttles now, probably. - - bugfix: Buckled mobs when on a rotating shuttle should now rotate correctly - - bugfix: Fixes shuttles gibbing in supposedly safe areas - - bugfix: Mobs that didn't move during shuttle launch would not have their parallax - updated. This is fixed now. - - bugfix: The custom shuttle placement highlight now works for multi area shuttles. - - bugfix: Directional windows shouldn't leak air anymore - - tweak: Windows only block air while anchored - - bugfix: Fixes camera mobs being considered a target by radiation - - bugfix: Cables can no longer be contaminated as well - - balance: Buffs radiation cleansing chems - - balance: Toxin damage per tick from radiation is halved - - admin: Contaminated objects keep track of what contaminated them - - admin: Radiation pulses over 3000 are logged now - spessmenart: - - imageadd: The captains sabre no longer looks like a rapier. -2017-10-17: - DaxDupont: - - bugfix: 'Fancy boxes(ie: donut boxes) now show the proper content amount in the - sprite and no longer go invisible when empty.' - Mercenaryblue: - - bugfix: when decapitated, banana-flavored cream no longer hovers where your head - used to be. - More Robust Than You: - - rscadd: EI NATH! now causes a flash of light - Naksu: - - bugfix: Pinned notes will now show up on vault, abductor, centcom and large glass - airlocks. - - spellcheck: Removed a misleading message when handling full stacks of sheets. - - bugfix: Pre-filled glass bottles (uplink, medbay, botany) will now give visual - feedback about how much stuff is left inside, and the color of contents will - match an empty bottle being filled with the same reagent. - - bugfix: Player-controlled "neutral" mobs such as minebots are now considered valid - targets by clock cult's ocular wardens. - Xhuis: - - bugfix: Cogged APCs can now be correctly unlocked with an ID card. - duncathan: - - tweak: Portable air pumps can output to a maximum of 25 atmospheres. - kevinz000: - - refactor: Legacy projectiles have been removed. Instead, all projectiles are now - PIXEL PROJECTILES! - - rscadd: Reflectors can now be at any angle you want. Alt click them to set angle! - - rscadd: Pipes can now be layered up to 3 layers. -2017-10-18: - DaxDupont: - - bugfix: Fixes automatic fire on guns. - Gun Hog: - - bugfix: The GPS item now correctly changes its name when the GPS tag is changed. - Improvedname: - - tweak: Reverts katana's to its orginal size being huge - Mercenaryblue: - - balance: it should be far easier to clean out your face from multiple cream pies. - More Robust Than You: - - tweak: People that are burning slightly less will appear to be burning... slightly - less. - Robustin: - - bugfix: The smoke machine now properly generates transparent smoke, transmits - chemicals, and displays the proper icons. - ShizCalev: - - tweak: You can no longer build reinforced floors directly on top of dirt, asteroid - sand, ice, or beaches. You'll have to first construct flooring on top of it - instead. - - bugfix: Corrected mapping issues introduced with the latest SM engine/radiation - update across all relevant maps. - - bugfix: The tools on the Caravan Ambush space ruin have had their speeds corrected. - - bugfix: Slappers will no longer appear as a latex balloon in your hand. - - bugfix: Renault now has a comfy new bed on Metastation! - - tweak: Engineering cyborgs now have access to geiger counters. - Xhuis: - - bugfix: You can no longer pick up brass chairs. - Y0SH1_M4S73R: - - bugfix: Disabling leg actuators sets the power drain per step to the correct value. - duncathan: - - bugfix: Filters no longer stop passing any gas through if the filtered output - is full. - ninjanomnom: - - rscadd: You can vomit blood at high enough radiation. - - balance: Radiation knockdown is far far shorter. - - balance: Genetics modification is less harmful but still, upgrade your machines. - - balance: Pentetic acid is useless for low amounts of radiation but indispensable - for high amounts now. - - balance: Singularity radiation has been normalized and Pubby engine has been remapped. - - bugfix: No more hair loss spam - - bugfix: Mob rad contamination has been disabled for now. Regular contamination - is still a thing. - - bugfix: Fixed turfs not rotating - - bugfix: Fixed stealing structures you shouldn't be moving -2017-10-19: - Kor: - - rscadd: Blob is now a side antagonist. - - rscadd: Event and admin blobs will now be able to choose their spawn location. - - rscadd: Blob can now win in any mode by gaining enough tiles to reach Critical - Mass. - - rscadd: Blobs that have Critical Mass have unlimited points, and a minute after - achieving critical mass, they will spread to every tile on station, killing - anyone still on board and ending the round. - - rscadd: Using an analyzer on a blob will now reveal its progress towards Critical - Mass. - - rscadd: The blob event is now more common. - Mercenaryblue: - - tweak: You will no longer trip on inactive honkbots. - - bugfix: Sentient Honkbots are no longer forced to speak when somebody trip on - them. - Naksu: - - bugfix: Manned turrets stop firing when there's no-one in the turret shooting. - - refactor: 'mobs will enter a deep power-saving state when there''s not much to - do except wander around. change: bees are slightly more passive in general' - deathride58: - - tweak: You can now press Ctrl+H to stop pulling, or simply H to stop pulling if - you're in hotkey mode. - ninjanomnom: - - rscadd: Engineering scanner goggles have a radiation mode now - - rscadd: Objects placed under showers are cleansed of radioactive contamination - over a short time. - - soundadd: Showers make sound now. - oranges: - - rscdel: Removed the bluespace pipe -2017-10-20: - Kor: - - rscadd: You can now select your Halloween race, rather than having it assigned - randomly via event. - Robustin: - - bugfix: Fixed a bug where detonating maxcaps, especially multiple maxcaps, on - Reebe guaranteed that everyone would die and thus the Clock Cult would immediately - lose; Reebe maxcap is now 2/5/10. - ShizCalev: - - bugfix: All reflector prisms/mirrors have had their angles corrected. - - tweak: Remains left over by dusting or soul-stoning a mob are now dissoluble with - acid. - - tweak: Changelings using biodegrade to escape restraints will now leave a pile - of goop. - - bugfix: Fixed messages related to changelings using biodegrade not appearing. -2017-10-21: - More Robust Than You: - - bugfix: Heads of staff will now have cat organs removed at roundstart - Robustin: - - balance: Spray tan no longer stuns when ingested. - Thunder12345: - - bugfix: Sentient cats no longer forget to fall over when they die -2017-10-22: - More Robust Than You: - - bugfix: Blood Brother now properly shows up in player panel - Naksu: - - server: Paper bins no longer let server admins know that pens were eaten. - - code_imp: Removed dangling mob references to last attacker/attacked - Robustin: - - balance: Medical biosuits (and hardsuits) now offer heavy, but not complete, radiation - resistance. - ninjanomnom: - - bugfix: Contents of silicon mobs are no longer considered for targets of radiation. - This blocks them from being contaminated. -2017-10-24: - Armhulen: - - rscadd: Wizards may now shapeshift into viper spiders. - Improvedname: - - tweak: Blacklists holoparasite's from surplus crates - Kor: - - rscadd: Added dullahans, which will be available from the character set up menu - during the Halloween event. - - bugfix: Severed heads will no longer appear bald. - More Robust Than You: - - bugfix: Fixes champrojector camera bugs - Naksu: - - bugfix: Grinders will now grind grown items like cocoa pods again - - code_imp: Cameras no longer keep hard references to mobs in their motion tracking - list. - ShizCalev: - - bugfix: Creatures made via gold slime cores will now be given the proper name - of their master. - deathride58: - - tweak: Deltastation's armory now contains reinforced windows surrounding the lethal - weaponry. This makes Delta's armory consistent with Box. - - tweak: There are now decals in places where extra Security lockers can spawn. - - tweak: Cleaned up semicolons in Meta and Boxstation's .dmms -2017-10-25: - Cruix: - - rscadd: Shuttle navigation computers can now place new transit locations over - the shuttle's current position. - JJRcop: - - rscadd: The heart of darkness revives you as a shadowperson if you aren't one - already. - ShizCalev: - - bugfix: Shades will no longer always hear a heartbeat. - - bugfix: Golem abilities will now be start on cooldown when they are made. -2017-10-26: - Kor and JJRcop: - - rscadd: Added vampires. They will be available as a roundstart race during the - Halloween holiday event. - ShizCalev: - - bugfix: Reflectors will no longer drop more materials than they took to make when - deconstructed. - - bugfix: You will no longer be prompted to reenter your body while being defibbed - if you can't actually be revived. - - bugfix: You can no longer teleport past the ticket stands of the Luxury Emergency - Shuttle. - - bugfix: Lightgeists can now -actually- be spawned with gold slime cores. - - tweak: The Staff of Change will now randomly assign a cyborg module when transforming - a mob into a cyborg. - Xhuis: - - balance: Clockwork marauders now move more slowly below 40% health. - - balance: Instead of a 40% chance (or more) chance to block projectiles, clockwork - marauders now have three fixed 100% blocks; after using those three, they cannot - block anymore without avoiding projectiles for ten seconds. This number increases - to four if war is declared. - - balance: Projectiles that deal no damage DO reduce marauders' shield health. Use - disabler shots to open them up, then use lasers to go for the kill! - - bugfix: Cogscarab shells and marauder armor now appear in the spawners menu. - - bugfix: You can no longer stack infinitely many stargazers on one tile. - nicbn: - - imageadd: Chemical heater and smoke machine resprited. - ninjanomnom: - - soundadd: Portable generators have a sound while active. - - soundadd: The supermatter has a sound that scales with stored energy. - ninjanomnom & Wjohn: - - bugfix: Cable cuffs now inherit the color of the cables used to make them. - - bugfix: Split cable stacks keep their color. - - tweak: The blue cable color is now a better blue. -2017-10-27: - Anonmare: - - rscadd: Adds new grindables - JamieH: - - rscadd: Buildmode map generators will now show you a preview of the area you're - changing - - rscadd: Buildmode map generators will now ask before nuking the map - - bugfix: Buildmode map generator corners can now only be set by left clicking - Kor: - - rscadd: Cloth golems will be available as a roundstart race during Halloween. - MrStonedOne: - - code_imp: Created a system to profile code on a line by line basis and return - detailed info about how much time was spent (in milliseconds) on each line(s). - Xhuis: - - balance: Servants can no longer teleport into the gravity generator, EVA, or telecomms. - ninjanomnom: - - bugfix: Hardsuit helmets work like geiger counters for the user. - - code_imp: Radiation should perform a little better in places. - - balance: Various radiation symptom thresholds have been tweaked. - - balance: Contamination strengths at different ranges have been tweaked. - - balance: Contaminated objects have less range for their radiation. - - balance: Hitting something with a contaminated object reduces its strength faster. - - balance: Contaminated objects decay faster. - - balance: Both radiation healing medicines have been buffed a bit. - - balance: Passive radiation loss for mobs is nerfed. - - balance: There is a soft cap for mob radiation now. - - balance: Projectiles, ammo casings, and implants are disallowed from becoming - contaminated. - - rscadd: Suit storage units can completely cleanse contamination from stored objects - - admin: The first time an object is contaminated enough to spread more contamination - admins will be warned. This is also added to stat tracking. - - rscadd: Thermite works on floors and can be ignited by sufficiently hot fires - now - - refactor: Thermite has been made into a component - - bugfix: Thermite no longer removes existing overlays on turfs -2017-10-28: - Mark9013100: - - tweak: The Medical Cloning manual has been updated. -2017-10-29: - Armhulen: - - rscadd: Frost Spiders now use Frost OIL! - Mercenaryblue: - - rscadd: Skeletons can now have their own spectral instruments - - rscadd: \[Dooting Intensifies\] - - admin: the variable "too_spooky" defines if it will spawn new instruments, by - default TRUE. - Naksu: - - bugfix: Removed meteor-related free lag - - bugfix: Cleaned up dangling mob references from alerts - Xhuis: - - bugfix: You can no longer become an enhanced clockwork golem with mutation toxin. - - balance: Normal clockwork golems now have 20% armor, down from 40%. - as334: - - spellcheck: This changelog has been updated and so read it again if you are interested - in doing assmos. - - rscadd: Atmospherics has been massively expanded including new gases. - - rscadd: These new gases include Brown Gas, Pluoxium, Stimulum, Hyper-Noblium and - Tritium. - - rscadd: Brown Gas is acidic to breath, but mildly stimulation. - - rscadd: Stimulum is more stimulating and much safer. - - rscadd: Pluoxium is a non-reactive form of oxygen that delivers more oxygen into - the bloodstream. - - rscadd: Hyper-Noblium is an extremely noble gas, and stops gases from reacting. - - rscadd: Tritium is radioactive and flammable. - - rscadd: New reactions have also been added to create these gases. - - rscadd: 'Tritium formation: Heat large amounts of oxygen with plasma. Make sure - you have a filter ready and setup!' - - rscadd: Fusion has been reintroduced. Plasma will fuse when heated to a high thermal - energy with Tritium as a catalyst. Make sure to manage the waste products. - - rscadd: 'Brown Gas formation: Heat Oxygen and Nitrogen.' - - rscadd: 'BZ fixation: Heat Tritium and Plasma.' - - rscadd: 'Stimulum formation: Heated Tritium, Plasma, BZ and Brown Gas.' - - rscadd: 'Hyper-Noblium condensation: Needs Nitrogen and Tritium at a super high - heat. Cools rapidly.' - - rscadd: Pluoxium is unable to be formed. - - rscdel: Freon has been removed. Use cold nitrogen for your SME problems now. - - rscadd: Water vapor now freezes the tile it is on when it is cooled heavily. - naltronix: - - bugfix: fixes that table that wasnt accessible in Metastation -2017-10-30: - PKPenguin321: - - tweak: You can now use beakers/cups/etc that have welding fuel in them on welders - to refuel them. - bgobandit: - - tweak: 'Due to cuts to Nanotrasen''s Occupational Safety and Health Administration - (NO-SHA) budget, station fixtures no longer undergo as much safety testing. - (Translation for rank and file staff: More objects on the station will hurt - you.)' -2017-11-02: - ACCount: - - tweak: '"Tail removal" and "tail attachment" surgeries are merged with "organ - manipulation".' - - imageadd: New sprites for reflectors. They finally look like something. - - rscadd: You can lock reflector's rotation by using a screwdriver. Use the screwdriver - again to unlock it. - - rscadd: Reflector examine now shows the current angle and rotation lock status. - - rscadd: You can now use a welder to repair damaged reflectors. - - bugfix: Multiple reflector bugs are fixed. - Improvedname: - - rscdel: Removes statues from gold slime pool - Mercenaryblue: - - imageadd: Updated Clown Box sprite to match the others. - More Robust Than You: - - admin: ONLY ADMINS CAN ACTIVATE THE ARK NOW - - tweak: The Ark's time measurements are now a bit more readable - MrStonedOne: - - tweak: Meteor events will not happen before 25 minutes, the worst versions before - 35 and 45 minutes. - - tweak: Meteor events are now player gated to 15, 20, and 25 players respectively - - balance: The more destructive versions of meteor events now have a slightly higher - chance of triggering, to offset the decrease in how often it is that they will - even qualify. - - bugfix: Fixed the changelog generator. - Naksu: - - tweak: Smartfridges and chem/condimasters now output items in a deterministic - 3x3 grid rather than in a huge pile in the middle of the tile. - SpaceManiac: - - bugfix: Admins can once again spawn nuke teams on demand. - Xhuis: - - admin: Admins can now create sound emitters (/obj/effect/sound_emitter) that can - be customized to play sounds to different people, at different volumes, and - at different locations such as by z-level. They're much more versatile for events - than the Play Sound commands! - - rscadd: You can now add grenades to plushies! You'll need to cut out the stuffing - first. - - tweak: Clockwork cult tips of the round have been updated to match the rework. - - tweak: Abscond and Reebe rifts now place servants directly at the Ark instead - of below the "base" area. - nicbn: - - tweak: Brown gas renamed to nitryl. - ninjanomnom: - - bugfix: Fixes decals not rotating correctly with the turf. - - bugfix: Fixes a runtime causing some turfs to be left behind by removed shuttles. - - code_imp: Shuttles should be roughly 40-50% smoother. - - bugfix: Fixes the cargo shuttle occasionally breaking if a mob got on at exactly - the right time. -2017-11-10: - Anonmare: - - bugfix: Adds an organ storage bag to the syndicate medborg. - AnturK: - - balance: Dying in shapeshifted form reverts you to the original one. (You're still - dead) - Floyd / Qustinnus: - - soundadd: Redtexting as a traitor now plays a depressing tune to you - Floyd / Qustinnus (And all the sounds by Kayozz11 from Yogstation): - - soundadd: Adds about 30 new ambience sounds - - refactor: added new defines for ambience lists. - Iamgoofball: - - tweak: Cooldown on the Ripley's mining drills has been halved. - - tweak: The frequency of the Ripley's ore pulse has been doubled. - Jalleo: - - tweak: Removed a variable to state which RCD's can deconstruct reinforced walls - - balance: Made combat (ERT ones) and admin RCDs able to deconstruct r walls alongside - borg ones - Kor: - - bugfix: Cult mode will once again print out names at round end. - Mark9013100: - - rscadd: Deltastation now has a Whiteship. - - tweak: Charcoal bottles have been renamed, and have been given a more informative - description. - Mercenaryblue: - - spellcheck: spellchecked the hotel staff. - - rscadd: Added frog masks. Reeeeeeeeee!! - More Robust Than You: - - bugfix: Blobbernauts and spores are no longer killed by blob victory - - bugfix: New blob overminds off the station Z level are moved to the station - - bugfix: You can now use banhammers as a weapon - - tweak: Monkeys can no longer transmit diseases through hardsuits - - tweak: Xenobio blobbernauts can no longer walk on blob tiles - Naksu: - - tweak: Added deterministic output slots to the slime processor - - bugfix: Fixed some interactions with ghosts and items - - bugfix: Nonhumans such as monkeys can now be scanned for chemicals with the health - analyzer. - Okand37 (DeltaStation Updates): - - rscadd: Tweaked Atmospherics - - bugfix: Fixed the Incinerator air injector - - rscadd: Tweaked Engineering - - rscadd: Added logs to the Chaplain's closet for gimmicks (bonfires) - - rscadd: Tweaked Security - - bugfix: Fixed medical morgue maintenance not providing radiation shielding and - exterior chemistry windoor - - rscadd: Bar now has a door from the backroom to the theatre stage - - rscadd: Tweaked Locker Room/Dormitories - ShizCalev: - - bugfix: You can now -actually- load pie cannons. - - bugfix: The captain's winter coat can now hold a flashlight. - - bugfix: The captain's and security winter coats can now hold internals tanks. - - tweak: All winter coats can now hold toys, lighters, and cigarettes. - - tweak: The captain's hardsuit can now hold pepperspray. - - rscadd: Updated the Test Map debugging verb to report more issues regarding APCs. - DELTASTATION - - bugfix: Reverted Okand37's morgue changes which broke power in the area. - - bugfix: Corrected wrong area on the Southern airlock leading into electrical maintenance. - ALL STATIONS - - bugfix: Corrected numerous duplicate APCs in areas which led to power issues. - SpaceManiac: - - bugfix: Ghosts can no longer create sparks from the hand teleporter's portals. - - bugfix: Digging on Lavaland no longer shows two progress bars. - - bugfix: The holodeck now has an "Offline" option. - - bugfix: Injury and crit overlays are now scaled properly for zoomed-out views. - - bugfix: Already-downloaded software is now hidden from the NTNet software downloader. - - bugfix: The crafting, language, and building buttons are now positioned correctly - in zoomed-out views. - - bugfix: Bluespace shelter walls no longer smooth with non-shelter walls and windows. - Swindly: - - rscadd: Organ storage bags can be used to perform limb augmentation. - - bugfix: You can now cancel a cavity implant during the implanting/removing step - by using drapes while holding the appropriate tool in your inactive hand. Cyborgs - can cancel the surgery by using drapes alone. - - bugfix: Fixed hot items and fire heating reagents to temperatures higher than - their heat source. - - bugfix: Sprays can now be heated with hot items. - - tweak: The heating of reagents by hot items, fire, and microwaves now scales linearly - with the difference between the reagent holder's temperature and the heat source's - temperature instead of constantly. - - tweak: The body temperature of a mob with reagents is affected by the temperature - of the mob's reagents. - - tweak: Reagent containers can now be heated by hot air. - Thefastfoodguy: - - bugfix: Spamming runes / battlecries / etc will no longer trigger spam prevention - WJohnston: - - bugfix: Ancient station lighting fixed on beta side (medical and atmos remains) - XDTM: - - rscadd: Ghosts now have a Toggle Health Scan verb, which allows them to health - scan mobs they click on. - Xhuis: - - rscadd: Ratvar and Nar-Sie plushes now have a unique interaction. - - balance: Clockwork marauders are now on harm intent. - - balance: The Clockwork Marauder scripture now takes five seconds longer to invoke - per marauder summoned in the last 20 seconds, capping at 30 extra seconds. - - balance: Clockwork marauders no longer gain a health bonus when war is declared. - - tweak: Moved the BoxStation deep fryers up one tile. - - rscadd: Microwaves have new sounds! - YPOQ: - - bugfix: EMPs can pulse multiple wires - as334: - - rscadd: Pluoxium can now be formed by irradiating tiles with CO2 in the air. - - rscadd: Rad collectors now steadily form Tritium at a slow pace. - - balance: Nerfs fusion by making it slower, and produce radioactivity. - - balance: Noblium formation now requires significantly more energy input. - - balance: Tanks now melt if their temperature is above 1 Million Kelvin. - deathride58: - - bugfix: Directional character icon previews now function properly. Other things - relying on getflaticon probably work with directional icons again, as well. - nicbn: - - imageadd: Canister sprites for the new gases - ninjanomnom: - - bugfix: Shuttle parallax has been fixed once more - - bugfix: You can no longer set up the auxiliary base's shuttle beacon overlapping - with the edge of the map - uraniummeltdown: - - tweak: Replica fabricatoring airlocks and windoors keeps the old name - - tweak: Narsie and Ratvar converting airlocks and windoors keeps the old name -2017-11-11: - DaxDupont: - - bugfix: Medbots can inject from one tile away again. - SpaceManiac: - - bugfix: The detective and heads of staff are no longer attacked by portable turrets. - deathride58: - - bugfix: You can no longer delete girders, lattices, or catwalks with the RPD - - bugfix: Fixes runtimes that occur when clicking girders, lattices, catwalks, or - disposal pipes with the RPD in paint mode - ninjanomnom: - - bugfix: Fixes ruin cable spawning and probably some other bugs -2017-11-12: - Cyberboss: - - bugfix: Clockwork slabs no longer refer to components -2017-11-13: - Cobby: - - rscadd: The Xray now only hits the first mob it comes into contact with instead - of being outright removed from the game. - Floyd / Qustinnus: - - soundadd: Reebe now has ambience sounds - 'Floyd / Qustinnus:': - - soundadd: Adds a few sound_loop datums to machinery. - Frozenguy5: - - bugfix: Broken cable cuffs no longer has an invisible sprite. - PKPenguin321: - - rscadd: Welders must now be screwdrivered open to reveal their fuel tank. - - rscadd: You can empty welders into open containers (like beakers or glasses) when - they're screwdrivered open. - - rscadd: You can now insert any chemical into a welder, but all most will do is - clog the fuel. Welding fuel will refuel it as usual. Plasma in welders tends - to explode. - Qbopper and JJRcop: - - tweak: The default internet sound volume was changed from 100 to 25. Stop complaining - in OOC about your ears! - SpaceManiac: - - bugfix: Posters may no longer be placed on diagonal wall corners. - WJohnston: - - rscdel: Removes stationary docking ports for syndicate infiltrator ships on all - maps. Use the docking navigator computer instead! This gives the white ship - and syndicate infiltrator more room to navigate and place custom locations that - are otherwise occupied by fixed shuttle landing zones that are rarely used. - Xhuis: - - rscadd: Deep fryers now have sound. - - tweak: Deep fryers now use cooking oil, a specialized reagent that becomes highly - damaging at high temperatures. You can get it from grinding soybeans and meat. - - tweak: Deep fryers now become more efficient with higher-level micro lasers, using - less oil and frying faster. - - tweak: Deep fryers now slowly use oil as it fries objects, instead of all at once. - - bugfix: You can now correctly refill deep fryers with syringes and pills. - nicn: - - balance: Damage from low pressure has been doubled. - ninjanomnom: - - rscadd: You can now select a nearby area to expand when using a blueprint instead - of making a new area. - - rscadd: New shuttle areas can be created using blueprints. This is currently not - useful but will be used later for shuttle construction. - - tweak: Blueprints can modify existing areas on station. - - admin: Blueprint functionality has been added to the debug tab as a verb. -2017-11-14: - ike709: - - imageadd: Added directional computer sprites. Maps haven't been changed yet. - psykzz: - - refactor: AI Airlock UI to use TGUI - - tweak: Allow AI to swap between electrified door states without having to un-electrify - first. - selea/arsserpentarium: - - rscadd: Integrated circuits have been added to Research! - - rscadd: You can use these to create devices with very complex behaviors. - - rscadd: Research the Integrated circuits printer to get started. -2017-11-15: - Fury: - - rscadd: Added new sprites for the Heirophant Relay (clock cultist telecomms equipment). - Naksu: - - bugfix: 'Removed fire-related free lag. change: fire alarms and cameras no longer - work after being ripped off a wall by a singulo' - - tweak: 'Minor speedups to movement processing. change: Fat mobs no longer gain - temperature by running.' - Robustin: - - refactor: Cult population scaling no longer operates on arbitrary breakpoints. - Each additional player between the between the breakpoints will add to the "chance" - that an additional cultist will spawn. - - tweak: On average you will see less roundstart cultists in lowpop and more roundstart - cultists in highpop. - - tweak: Damage examinations now include a "moderate" classification. Before minor - was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 - to <50, and severe is 50+. - - tweak: The tesla will now move toward power beacons at a significantly slower - rate. - SpaceManiac: - - bugfix: The post-round station integrity report is now functional again. - ninjanomnom: - - bugfix: Gas overlays no longer block clicks, on 512 -2017-11-22: - ACCount: - - refactor: Old integrated circuit save file format is ditched in favor of JSON. - Readability, both of save files and save code, is improved greatly. - - tweak: Integrated circuit panels now open with screwdriver instead of crowbar, - to match every single other thing on this server. - - tweak: Integrated circuit printer now stores up to 25 metal sheets. - - bugfix: Fixed integrated circuit rechargers not recharging guns properly and not - updating icons. - - bugfix: Fixed multiple bugs in integrated circuits UIs, improved overall usability. - Anonmare: - - balance: Laserpoitners now incapcitate catpeople - AutomaticFrenzy: - - bugfix: cell chargers weren't animating properly - - bugfix: disable_warning wasn't getting checked and the chat was being spammed - Code by Pyko, Ported by Frozenguy5: - - rscadd: Rat Kebabs and Double Rat Kebabs have been added! - Cyberboss: - - server: Server tools API changed to version 3.2.0.1 - - admin: '"ahelp" chat command can now accept a ticket number as opposed to a ckey' - DaxDupont: - - tweak: CentCom has issued a firmware updated for the operating computers. It is - no longer needed to manually refresh the procedure and patient status. - - bugfix: Proximity sensors no longer beep when unarmed. - - bugfix: Plant trays will now properly process fluorine and adjust toxins and water - contents. - Francinum: - - tweak: The shuttle build plate is now better sized for all stations. - Iamgoofball: - - spellcheck: fixes grammar on logic gate descriptions - - spellcheck: fixes grammar on list circuits - - bugfix: fixes grammar on trig circuits - - spellcheck: fixed grammar on output circuits - JJRcop: - - bugfix: Fixes changeling eggs not putting the changeling in control if the brainslug - is destroyed before hatching. - - tweak: The silicon airlock menu looks a little more like it used to. - Kor: - - bugfix: Blobbernauts will no longer spawn if a player is not selected to control - it, preventing AI blobbernauts from running off the blob and to their deaths. - - rscdel: Following complaints that cargo has been selling all the materials they - receive rather than distributing them, mineral exporting has been removed. - MMMiracles: - - balance: Power regen on the regular tesla relay has been reduced to 50, from 150. - Naksu: - - bugfix: Sped up saycode to remove free lag from highpop - - bugfix: Using a chameleon projector will now dismount you from any vehicles you - are riding, in order to prevent wacky space glitches and being sent to a realm - outside space and time. - Shadowlight213: - - code_imp: Added round id to the status world topic - ShizCalev: - - bugfix: Chameleon goggles will no longer go invisible when selecting Optical Tray - scanners. - - rscadd: Engineering and Atmos scanner goggles will now have correctly colored - inhand sprites. - - tweak: The computers on all maps have have been updated for the latest directional - sprite changes. Please report any computers facing in strange directions to - your nearest mapper. - - bugfix: MetaStation - The consoles in medbay have had their directions corrected. - - imageadd: The Nanotrasen logo on modular computers has been fixed, rejoice! - - bugfix: PubbyStation - Unpowered air injectors in various locations have been - fixed. - - bugfix: MetaStation - Air injector leading out of the incinerator has been fixed - - bugfix: MetaStation - Corrected a couple maintenance airlocks being powered by - the wrong areas. - - bugfix: Computers will no longer rotate incorrectly when being deconstructed. - - bugfix: You can now rotate computer frames during construction. - - bugfix: Chairs, PA parts, infrared emitters, and doppler arrays will now rotate - clockwise. - - bugfix: Throwing drinking glasses and cartons will now consistently cause them - to break! - - bugfix: Humans missing legs or are legcuffed will no longer move slower in areas - without gravity. - - bugfix: The structures external to stations are now properly lit. Make sure you - bring a flashlight. - - bugfix: Computers will no longer delete themselves when being built, whoops! - - bugfix: Space cats will no longer have a smashed helmet when they lay down. - Skylar Lineman, your local R&D moonlighter: - - rscadd: Research has been completely overhauled into the techweb system! No more - levels, the station now unlocks research "nodes" with research points passively - generated when there is atleast one research server properly cooled, powered, - and online. - - rscadd: R&D lab has been replaced by the departmental lathe system on the three - major maps. Each department gets a lathe and possibly a circuit imprinter that - only have designs assigned by that department. - - rscadd: The ore redemption machine has been moved into cargo bay on maps with - decentralized research to prevent the hallways from becoming a free for all. - Honk! - - balance: You shouldn't expect balance as this is the initial merge. Please put - all feedback and concerns on the forum so we can revise the system over the - days, weeks, and months, to make this enjoyable for everyone. Heavily wanted - are ideas of how to add more ways of generating points. - - balance: You can get techweb points by setting off bombs with an active science - doppler array listening. The bombs have to have a theoretical radius far above - maxcap to make a difference. You can only go up, not down, in radius, so you - can't get 6 times the points with 6 TTVs. The algorithm is exponentially/logarithmically - scaled to prevent "world destroyer" bombs from instantly finishing research. - SpaceManiac: - - bugfix: HUDs from mechs and helmets no longer conflict with HUD glasses and no - longer inappropriately remove implanted HUDs. - - code_imp: Chasm code has been refactored to be more sane. - - bugfix: Building lattices over chasms no longer sometimes deletes the chasm. - - code_imp: Ladders have been refactored and should be far less buggy. - - bugfix: Jacob's ladder actually works again. - - bugfix: Pizza box stacking works again. - - bugfix: Fix some permanent-on and permanent-off bugs caused by the HUD stacking - change. - WJohnston: - - imageadd: A bunch of new turf decals for mappers to play with, coming in yellow, - white, and red varieties! - - bugfix: Green banded default airlocks now have extended click area like all other - airlocks. - Y0SH1 M4S73R: - - spellcheck: The R&D Server's name is now improper. - - spellcheck: The R&D Server now has an explanation of what it does. - arsserpentarium: - - bugfix: now lists should work properly - duncathan: - - rscadd: The RPD has a shiny new UI! - - rscadd: The RPD can now paint pipes as it lays them, for quicker piping projects. - - rscadd: Atmos scrubbers (vent and portable) can now filter any and all gases. - ike709: - - imageadd: Added new vent and scrubber sprites by Partheo. - - bugfix: Fixed some computers facing the wrong direction. - jammer312: - - bugfix: fixed conjuration spells forgetting about conjured items - kevinz000: - - rscadd: purple bartender suit and apron added to clothesmates! - - rscadd: long hair 3 added, check it out. both have sprites from okand! - nicbn: - - soundadd: Now rolling beds and office chairs have a sound! - oranges: - - rscdel: Removed the shocker circuit - psykzz: - - imageadd: Grilles have new damaged and default sprites - - rscadd: Added TGUI for Turbine computer - tserpas1289: - - tweak: Any suit that could hold emergency oxygen tanks can now also hold plasma - man internals - - tweak: Hydroponics winter coats now can hold emergency oxygen tanks just like - the other winter coats. - - bugfix: Plasma men jumpsuits can now hold accessories like pocket protectors and - medals. - zennerx: - - bugfix: fixed a bug that made you try and scream while unconscious due to a fire - - tweak: Skateboard crashes now give slight brain damage! - - rscadd: Using a helmet prevents brain damage from the skateboard! -2017-11-23: - GupGup: - - bugfix: Fixes hostile mobs attacking surrounding tiles when trying to attack someone - MrStonedOne and Jordie: - - server: As a late note, serverops be advise that mysql is no longer supported. - existing mysql databases will need to be converted to mariadb - Robustin: - - tweak: RND consoles will no longer display options for machines or disks that - are not connected/inserted. - ShizCalev: - - bugfix: Aliens in soft-crit will now use the correct sprite. - XDTM: - - rscadd: 'Added two new symptoms: one allows viruses to still work while dead, - and allows infection of undead species, and one allows infection of inorganic - species (such as plasmapeople or golems).' -2017-11-24: - ACCount: - - rscdel: Removed "console screen" stock part. Just use glass sheets instead. - More Robust Than You: - - tweak: Spessmen are now smart enough to realize you don't need to turn around - to pull cigarette butts - SpaceManiac: - - bugfix: Fix water misters being inappropriately glued to hands in some cases. - - bugfix: Some misplaced decals in the Hotel brig have been corrected. - ninjanomnom: - - bugfix: Custom shuttle dockers can no longer place docking regions inside other - custom docker regions. -2017-11-25: - CosmicScientist: - - bugfix: bolas are back in tablecrafting! - Dorsisdwarf: - - tweak: Catpeople are now distracted instead of debilitated - - rscadd: Normal cats now go for laser pointers - SpaceManiac: - - bugfix: You can no longer buckle people to roller beds from inside of a locker. - YPOQ: - - bugfix: AIs and cyborgs can interact with unscrewed airlocks and APCs. - ninjanomnom: - - bugfix: Fixes thermite burning hotter than the boiling point of stone - zennerx: - - bugfix: Zombies don't reanimate with no head! -2017-11-27: - ACCount: - - rscadd: 'New integrated circuit components: list constructors/deconstructors. - Useful for building lists and taking them apart.' - - bugfix: Fixed multiple bugs in integrated circuits UIs, improved overall usability. - More Robust Than You: - - bugfix: Fixed cult leaders being de-culted upon election if they had a mindshield - implant - Naksu: - - bugfix: Hopefully fixed mesons granting the ability to hear people through walls. - Okand37: - - rscadd: Re-organized Delta's departmental protolathes for all departments. - - rscadd: Re-organized Delta's ORM placement by connecting it to the mining office, - which now has a desk for over handing materials to the outside. - - rscadd: Added a second Nanomed to Deltastation's medical bay. - - rscadd: Nanotrasen has decided to add proper caution signs to most docking ports - on Deltastation, warning individuals to be cautious around these areas. - - rscadd: Two health sensors are now placed in Deltastation's robotics area for - medibots. - - bugfix: Atmospheric Technicians at Deltastation can now open up their gas storage - in the supermatter power area as intended. - WJohnston: - - bugfix: Fixed a case where items would sometimes be placed underneath racks. - XDTM: - - balance: Viruses' healing symptoms have been reworked! - - rscdel: All existing healing symptoms have been removed in favour of new ones. - - rscdel: Weight Even and Weight Gain have been removed, so hunger can be used for - balancing in symptoms. - - rscadd: Starlight Condensation heals toxin damage if you're in space using starlight - as a catalyst. Being up to two tiles away also works, as long as you can still - see it, but slower. - - rscadd: Toxolysis (level 7) rapidly cleanses all chemicals from the body, with - no exception. - - rscadd: 'Cellular Molding heals brute damage depending on your body temperature: - the higher the temperature, the faster the healing. Requires above-average temperature - to activate, and the speed heavily increases while on fire.' - - rscadd: Regenerative Coma (level 8) causes the virus to send you into a deep coma - when you are heavily damaged (>70 brute+burn damage). While you are unconscious, - either from the virus or from other sources, the virus will heal both brute - and burn damage fairly quickly. Sleeping also works, but at reduced speed. - - rscadd: Tissue Hydration heals burn damage if you are wet (negative fire stacks) - or if you have water in your bloodstream. - - rscadd: Plasma Fixation (level 8) stabilizes temperature and heals burns while - plasma is in your body or while standing in a plasma cloud. Does not protect - from the poisoning effects of plasma. - - rscadd: Radioactive Resonance gives a mild constant brute and burn healing while - irradiated. The healing becomes more intense if you reach higher levels of radiation, - but is still less than the alternatives. - - rscadd: Metabolic Boost (level 7) doubles the rate at which you process chemicals, - good and bad, but also increases hunger tenfold. - kevinz000: - - bugfix: Cryo cells can now be properly rotated with a wrench. - ninjanomnom: - - rscadd: 'You can now make a new tasty traditional treat: butterdogs. Watch out, - they''re slippery.' -2017-11-28: - ACCount: - - rscdel: '"Machine prototype" is removed from the game.' - - rscdel: Mass-spectrometers are removed. Would anyone notice if not for this changelog - entry? - Cruix: - - rscadd: AI and observer diagnostic huds will now show the astar path of all bots, - and Pai bots will be given a visible path to follow when called by the AI. - JJRcop: - - admin: Fixed the Make space ninja verb. - Naksu: - - code_imp: rejiggered botcode a little bit - SpaceManiac: - - spellcheck: Admin-added "download research" objectives are now consistent with - automatic ones. - improvedname: - - tweak: toolbelts can now carry geiger counters - uraniummeltdown: - - rscadd: You can make many different types of office and comfy chairs with metal - - tweak: Stack menus use /datum/browser -2017-11-29: - MrStonedOne: - - tweak: The sloth no longer suspiciously moves fast when gliding between tiles. - - balance: The sloth's movespeed when inhabited by a player has been lowered from - once every 1/5 of a second to once every second. - SpaceManiac: - - spellcheck: The techweb node for mech LMGs no longer claims to be for mech tasers. -2017-11-30: - ninjanomnom: - - tweak: Reduced the max volume of sm by 1/5th and made the upper bounds only play - mid delamination. - psykzz: - - bugfix: Fixing the broken turbine computer -2017-12-02: - BeeSting12: - - spellcheck: Occupand ---> Occupant on opened cryogenic pods. - - spellcheck: Cyrogenic ---> Cryogenic on opened cryogenic pods. - CosmicScientist: - - rscadd: You can make plushies kiss one another! - Frozenguy5: - - tweak: The Particle Accelerator's wires can no longer be EMP'd - Naksu: - - code_imp: Cleans up some loc assignments - Robustin: - - tweak: Damage examinations now include a "moderate" classification. Before minor - was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 - to <50, and severe is 50+. - - balance: Clockwork magicks will now prevent Bags of Holding from being combined - on Reebe. - - bugfix: Flashes will now burn out AFTER flashing when they fail instead of being - a ticking time bomb that waits to screw you over on your next attempt. - SpaceManiac: - - tweak: The R&D Console has been given a much prettier interface. - - tweak: Research scanner goggles now show materials and technology prospects in - a nicer way. - uraniummeltdown: - - imageadd: Construct shells have a new animated sprite -2017-12-03: - ExcessiveUseOfCobblestone: - - bugfix: You can now lay (buckle!) yourself to a bed to avoid being burnt to a - crisp during "the floor is lava" event. - Robustin: - - tweak: Igniting plasma statues no longer ignores ignition temperature and only - creates as much plasma as was used in its creation. - Xhuis: - - rscadd: Light fixtures now turn an ominous, dim red color when they lose power, - and draw from an internal power cell to maintain it until either the cell dies - (usually after 10 minutes) or power is restored. - - rscadd: You can override emergency light functionality from an APC. You can also - click on individual lights as a cyborg or AI to override them individually. - Traitor AIs also have a new ability that disables emergency lights across the - entire station. - zennerx: - - spellcheck: fixed some typos in the weapon firing mechanism description -2017-12-04: - AnturK: - - rscadd: You can now record and replay holopad messages using holodisks. - - rscadd: Holodisks are printable in autolathes. - Xhuis: - - bugfix: You now need fuel in your welder to repair mechs. -2017-12-05: - Cyberboss: - - sounddel: Reduced the volume of showers - Dax Dupont: - - rscadd: Nanotrasen is happy to announce the pinnacle in plasma research! The Disco - Inferno shuttle design is the result of decades of plasma research. Burn, baby, - burn! - MrPerson & ninjanomnom: - - refactor: Completely changed how keyboard input is read. - - rscadd: Holding two directions at the same time will now move you diagonally. - This works with the arrow keys, wasd, and the numpad. - - tweak: Moving diagonally takes twice as long as moving a cardinal direction. - - bugfix: You can use control to turn using wasd and the numpad instead of just - the arrow keys. - - rscdel: 'Some old non-hotkey mode behaviors, especially in relation to chatbox - interaction, can''t be kept with the new system. Of key note: You can''t type - while walking. This is due to limitations of byond and the work necessary to - overcome it is better done as another overhaul allowing custom controls.' - Robustin: - - rscdel: Reverted changes in 3d sound system that tripled the distance that sound - would carry. - SpaceManiac: - - spellcheck: Energy values are now measured in joules. What was previously 1 unit - is now 1 kJ. - - bugfix: Syndicate uplink implants now work again. - Xhuis: - - tweak: Stethoscopes now inform the user if the target can be defibrillated; the - user will hear a "faint, fluttery pulse." - coiax: - - rscadd: Quiet areas of libraries on station have now been equipped with a vending - machine containing suitable recreational activities. -2017-12-06: - Dax Dupont & Alek2ander: - - tweak: Binary chat messages been made more visible. - Revenant Defile ability: - - bugfix: Revenant's Defile now removes salt piles - XDTM: - - rscadd: 'Brain damage has been completely reworked! remove: Brain damage now no - longer simply makes you dumb. Although most of its effects have been shifted - into a brain trauma.' - - rscadd: Every time you take brain damage, there's a chance you'll suffer a brain - trauma. There are many variations of brain traumas, split in mild, severe, and - special. - - rscadd: Mild brain traumas are the easiest to get, can be lightly to moderately - annoying, and can be cured with mannitol and time. - - rscadd: Severe brain traumas are much rarer and require extensive brain damage - before you have a chance to get them; they are usually very debilitating. Unlike - mild traumas, they require surgery to cure. A new surgery procedure has been - added for this, the aptly named Brain Surgery. It can also heal minor traumas. - - rscadd: 'Special brain traumas are rarely gained in place of Severe traumas: they - are either complex or beneficial. However, they are also even easier to cure - than mild traumas, which means that keeping these will usually mean keeping - a mild trauma along with it.' - - rscadd: Mobs can only naturally have one mild trauma and one severe or special - trauma. - - balance: Brain damage will now kill and ruin the brain if it goes above 200. If - it somehow goes above 400, the brain will melt and be destroyed completely. - - balance: Many brain-damaging effects have been given a damage cap, making them - non-lethal. - - rscdel: The Unintelligible mutation has been removed and made into a brain trauma. - - rscdel: Brain damage no longer makes using machines a living hell. - - rscadd: Abductors give minor traumas to people they experiment on. - coiax: - - rscadd: The drone dispenser on Metastation has been moved to the maintenance by - Robotics. -2017-12-07: - ShizCalev: - - bugfix: Games vending machines can now properly be rebuilt. - - bugfix: Games vending machines can now be refilled via supply crates. - - rscadd: Games Supply Crates have been added to the cargo console. - SpaceManiac: - - bugfix: Radio frequency 148.9 is once again serviced by the telecomms system. - Xhuis: - - rscadd: Added the Eminence role to clockcult! Players can elect themselves or - ghosts as the Eminence from the eminence spire structure on Reebe. - - rscadd: The Eminence is incorporeal and invisible, and directs the entire cult. - Anything they say is heard over the Hierophant network, and they can issue commands - by middle-clicking themselves or different turfs. - - rscadd: The Eminence also has a single-use mass recall that warps all servants - to the Ark chamber. - - rscadd: Added traps, triggers, and brass filaments to link them. They can all - be constructed from brass sheets, and do different things and trigger in different - ways. Current traps include the brass skewer and steam vent, and triggers include - the pressure sensor, lever, and repeater. - - rscadd: The Eminence can activate trap triggers by clicking on them! - - rscadd: Servants can deconstruct traps instantly with a wrench. - - rscdel: Mending Mantra has been removed. - - tweak: Clockwork scriptures have been recolored and sorted based on their functions; - yellow scriptures are for construction, red for offense, blue for defense, and - purple for niche. - - balance: Servants now spawn with a PDA and black shoes to make disguise more feasible. - - balance: The Eminence can superheat up to 20 clockwork walls at a time. Superheated - walls are immune to hulk and mech punches, but can still be broken conventionally. - - balance: Clockwork walls are slightly faster to build before the Ark activates, - taking an extra second less. - - bugfix: Poly no longer continually undergoes binary fission when Ratvar is in - range. - - code_imp: The global records alert for servants will no longer display info that - doesn't affect them since the rework. - coiax: - - rscadd: The drone dispenser on Box Station has been moved from the Testing Lab - to the Morgue/Robotics maintenance tunnel. - deathride58: - - config: The default view range can now be defined in the config. The default is - 15x15, which is simplified to 7 by BYOND. For reference, Goonstation's widescreen - range is 21x15. Do note that changing this value will affect the title screen. - The title screen images and the title screen area on the Centcom z-level will - have to be updated if the default view range is changed. -2017-12-08: - Dax Dupont: - - bugfix: Fixed observer chat flavor of silicon chat. - - bugfix: Grilles now no longer revert to a pre-broken icon state when you hit them - after they broke. - Dorsisdwarf: - - tweak: Minor fixes to some techweb nodes - - balance: Made flight suits, combat implants, and combat modules require more nodes - Fox McCloud: - - tweak: Slime blueprints can now make an area compatible with Xenobio consoles, - regardless of the name of the new area - MrDoomBringer: - - imageadd: All stations have been outfitted with brand new Smoke Machines! They - have nicer sprites now! - Shadowlight213: - - rscadd: You now can get a medal for wasting hours talking to the secret debug - tile. - - bugfix: Fixed runtime for the tile when poly's speech file doesn't exist. - Xhuis: - - rscadd: You can now make pet carriers from the autolathe, to carry around chef - meat and other small animals without having to drag them. The HoP, captain, - and CMO also start with carriers in their lockers for their pets. - YPOQ: - - bugfix: Fixed the camera failure, race swap, cursed items, and imposter wizard - random events - - tweak: The cursed items event no longer nullspaces items - jammer312: - - rscadd: Action buttons now remember positions where you locked. - - tweak: Now locking action buttons prevents them from being reset. -2017-12-10: - SpaceManiac: - - bugfix: External airlocks of the mining base and gulag are now cycle-linked. - - tweak: The pAI software interface is now accessible via an action button. - Swindly: - - rscadd: You can kill yourself with a few more items. - XDTM: - - tweak: Instead of activating randomly on speech, Godwoken Syndrome randomly grants - inspiration, causing the next message to be a Voice of God. - Xhuis: - - tweak: Flickering lights will now actually flicker and not go between emergency - lights and normal lighting. - - bugfix: Emergency lights no longer stay on forever in some cases. - kevinz000: - - rscadd: Nanotrasen would like to remind crewmembers and especially medical personnel - to stand clear of cadeavers before applying a defibrillator shock. (You get - shocked if you're pulling/grabbing someone being defibbed.) - - tweak: defib shock/charge sounds upped from 50% to 75%. -2017-12-11: - Anonmare: - - bugfix: Booze-o-mats have beer - Cruix: - - tweak: The white ship navigation computer now takes 10 seconds to designate a - landing spot, and users can no longer see the syndicate shuttle or its custom - landing location. If the white ship landing location would intersect the syndicate - shuttle or its landing location, it will fail after the 10 seconds have elapsed. - Frozenguy5: - - balance: Some hardsuits have had their melee, fire and rad armor ratings tweaked. - Improvedname: - - tweak: cats now drop their ears and tail when butchered. - Robustin: - - bugfix: Modes not in rotation have had their "false report" weights for the Command - Report standardized - SpaceManiac: - - bugfix: The MULEbots that the station starts with now show their ID numbers. - - bugfix: The dependency by Advanced Cybernetic Implants and Experimental Flight - Equipment on Integrated HUDs has been restored. - kevinz000: - - bugfix: flightsuits should no longer disappear when you take them off involuntarily - - bugfix: beam rifles actually fire striaght now - - bugfix: click catchers now actually work - - bugfix: you no longer see space in areas you normally can't see, instead of black. - in reality you can still see space but it's faint enough that you can't tell - so I'll say I fixed it. - uraniummeltdown: - - rscadd: Added MANY new types of airlock assembly that can be built with metal. - Use metal in hand to see the new airlock assembly recipes. - - rscadd: Added new airlock types to the RCD and airlock painter - - rscadd: Vault door assemblies can be built with 8 plasteel, high security assemblies - with 6 plasteel - - rscadd: Glass mineral airlocks are finally constructible. Use glass and mineral - sheets on an airlock assembly in any order to make them. - - tweak: Glass and mineral sheets are now able to be welded out of door assemblies - rather than having to deconstruct the whole thing - - rscdel: Airlock painter no longer works on airlock assemblies (still works on - airlocks) - - bugfix: Titanium airlocks no longer have any missing overlays -2017-12-12: - Mark9013100: - - rscadd: Medical Wardrobes now contain an additional standard and EMT labcoat. - Robustin: - - rscadd: The blood cult revive rune will now replace the souls of braindead or - inactive cultists/constructs when properly invoked. These "revivals" will not - count toward the revive limit. - - rscadd: The clock cult healing rune will now replace the souls of braindead or - inactive cultists/constructs when left atop the rune. These "revivals" will - not drain the rune's energy. - Swindly: - - bugfix: Swarmers can no longer deconstruct objects with living things in them. - kevinz000: - - bugfix: You can now print telecomms equipment again. -2017-12-13: - Naksu: - - bugfix: glass shards and bananium floors no longer make a sound when "walked" - over by a camera or a ghost - SpaceManiac: - - bugfix: Nonstandard power cells found in MULEbots, cyborgs, and elsewhere now - have the correct description. - deathride58: - - bugfix: Genetics will no longer have a random block completely disappear each - round -2017-12-15: - AverageJoe82: - - rscadd: drones now have night vision - - rscdel: drones no longer have lights - Cruix: - - bugfix: Shuttles now place hyperspace ripples where they are about to land again. - Cyberboss: - - config: Added "$include" directives to config files. These are recursive. Only - config.txt will be default loaded if they are specified inside it - - config: Added multi string list entry CROSS_SERVER. e.g. CROSS_SERVER Server+Name - byond://server.net:1337 - - config: CROSS_SERVER_ADDRESS removed - Epoc: - - bugfix: Adds Cybernetic Lungs to the Cyber Organs research node - JStheguy: - - rscadd: Added 10 new assembly designs to the integrated circuit printer, the difference - from current designs is purely aesthetics. - - imageadd: Added the icons for said new assembly designs to electronic_setups.dmi, - changed the current electronic mechanism and electronic machine sprites. - MrStonedOne: - - server: Added new admin flag, AUTOLOGIN, to control if admins start with admin - powers. this defaults to on, and can be removed with -AUTOLOGIN - - admin: Admins with +PERMISSION may now deadmin or readmin other admins via the - permission panel. - Naksu: - - code_imp: Preliminary work on tracking cliented living mobs across Z-levels to - facilitate mob AI changes later - - code_imp: Tidied up some loc assignments - - code_imp: fixes the remaining loc assignments - ShizCalev: - - soundadd: Revamped gun dry-firing sounds. - - tweak: Everyone around you will now hear when your gun goes click. You don't want - to hear click when you want to hear bang! - SpaceManiac: - - code_imp: Remote signaler and other non-telecomms radio code has been cleaned - up. - Xhuis: - - rscadd: Grinding runed metal and brass now produces iron/blood and iron/teslium, - respectively. - - balance: As part of some code-side improvements, the amount of reagents you get - from grinding some objects might be slightly different. - - bugfix: Some grinding recipes that didn't work, like dead mice and glowsticks, - now do. - - bugfix: All-In-One grinders now correctly grind up everything, instead of one - thing at a time. - nicbn: - - imageadd: Closet sprites changed. -2017-12-16: - Armhulen and lagnas2000 (+his team of amazing spriters): - - rscadd: Mi-go have entered your realm! - Robustin: - - balance: Marauder shields now take twice as long to regenerate and only recharge - one charge at a time. - - balance: Marauders now have 120hp down from 150hp. - - bugfix: The wizard event "race swap" should now stick to "safer" species. - - bugfix: Zombies are now properly stunned for a maximum of 2 seconds instead of - 2/10ths of a second. - - tweak: Zombie slowdown adjusted from -2 to -1.6. - SpaceManiac: - - bugfix: The shuttle will no longer be autocalled if the round has already ended. - Xhuis: - - tweak: Vitality matrices don't have visible messages when someone crosses them - anymore. -2017-12-17: - More Robust Than You: - - code_imp: Changed roundend sounds and lobby music to use one proc for choosing - sounds - - server: You can now easily host roundstart sounds without changing the code! - - config: RIP in shit round_start_sounds.txt - XDTM: - - rscadd: A few new traumas have been added. - - balance: Thresholds to get brain traumas have been lowered, as they currently - pretty much only trigger if you intentionally chug impedrezene. - - tweak: Melee head hits deal minor brain damage. Crits still do a significant amount. - - tweak: Nuke Op implants no longer trigger on deathgasp. (They still explode on - death) - - tweak: You'll now receive messages when crossing certain brain damage thresholds. - - tweak: Split Personalities are instructed not to suicide while in control. - - tweak: Godwoken Syndrome now randomly sends Voice of God commands, instead of - being controllable. - Xhuis: - - bugfix: Clockcult power alerts will no longer show outside of the clockcult gamemode - (they could be triggered by scarabs.) - ninjanomnom: - - bugfix: You can use the old non-hotkey mode text input behavior (keyboard input - automatically directed at the text input box) by changing your hotkey mode in - preferences - - rscadd: You can use Shift+E or Shift+B for belt/backpack respectively to quickly - put in your held item or take out the most recently added item. -2017-12-18: - AnturK: - - rscadd: Repeated messages will now be squashed in the chat. - Cyberboss: - - bugfix: Allied station communications are back, now with potentially multiple - stations - Naksu: - - tweak: Hostile mobs on z-levels without living players will now conserve their - efforts and simply not run AI routines at all. Also, idling mob routines should - be significantly cheaper on non-station Z-levels. - ShizCalev: - - soundadd: Added new sounds to guns when reloading. - - bugfix: Cartridges and casings ejected from guns will now make the proper sound! - Xhuis: - - bugfix: Microwave sound loops now correctly stop when it breaks or is otherwise - interrupted mid-cook. - coiax: - - rscadd: A lollipop dispenser in "dispense lollipops" mode can push the lollipop - straight into the targets hand, rather than getting it dirty on the floor first. - - tweak: Aliens (and humans with alien organs) will have a prompt if they try to - create resin structures or lay eggs atop vents or scrubbers. - nicbn: - - bugfix: Now the chem smoke machine uses stock parts for volume and range. - ninjanomnom: - - bugfix: Decals should now rotate the correct way around. - oranges: - - tweak: Dance machine will not play tracks to you if you have instruments turned - off -2017-12-19: - More Robust Than You: - - tweak: Jungle Fever cannot be cured anymore - - bugfix: The Monkey Leaders' virus are now un-detectable by health scanners and - to the PANDEMIC now. - Shadowlight213: - - bugfix: Fixed captain's PDA showing unusable Toggle Remote Door menu option - XDTM: - - rscadd: Abductors can now see if people already have glands! Never worry about - abducting the same guy twice again. - - rscadd: Added the Mind Interface Device to the abductor shop for 2 Credits. Only - scientists can use it. - - rscadd: 'The MID has two modes: Transmit and Control.' - - rscadd: Transmit will allow you to send a message anytime, anywhere to the mind - of a target of your choice, regardless of language barriers. The message will - be anonymous, but abductor-like. - - rscadd: Control allows you to give a temporary directive to a target with an implanted - gland, that they MUST follow. Duration and amount of uses varies by gland type. - When a gland is spent, it will no longer respond to Control signals. The target - forgets ever receiving the objective when the duration ends. - coiax: - - balance: The codespeak manual now has unlimited uses and costs 3 TC. - - bugfix: Nuke ops can now purchase the codespeak manual, as was intended. - - rscadd: Golems can now wear labcoats. - kevinz000: - - rscadd: You can now joust with spears if you are riding on another mob, whether - it's a hapless cyborg or otherwise! Additional damage and stunchance will be - added per tile moved! - ninjanomnom: - - bugfix: Non movement keys pressed while moving no longer stop movement. -2017-12-20: - AnturK: - - rscadd: You can enforce no smoking zones with a disarm aimed at the smokers mouth. - coiax: - - rscadd: A changeling will learn all languages from anyone they absorb. -2017-12-21: - Fox McCloud: - - bugfix: Fixes arm implants being immune to EMPs - SpaceManiac: - - refactor: Telecomms and radio code has been cleaned up. - - tweak: The PDA message server is now a real piece of telecomms machinery. - - tweak: PDA logs now include the job as well as name of the participants. - - bugfix: The Syndicate frequency no longer hears its own messages twice. - - bugfix: Talking directly into a radio which is also hot-miked no longer double-talks. - - bugfix: Passing a space transition no longer interrupts pulls. - Xhuis: - - bugfix: You can no longer elect two Eminences simultaneously. - - bugfix: The Eminence no longer drifts in space. - - tweak: The Eminence's mass recall now works on unconscious servants. - - tweak: The Eminence's messages now have follow links for observers. - - balance: Floors blessed with holy water prevent servants from warping in and the - Eminence from crossing them. - - balance: The Eminence can never enter the Chapel. - coiax: - - rscadd: At the end of the round, all players can see who the antagonists are. - improvedname: - - bugfix: Corrects 357. speedloader in the autolathe - kevinz000: - - rscdel: Integrated circuit smoke circuits now require 10 units of reagents to - fire. - uraniummeltdown: - - rscadd: You can adjust line height in chat settings - - tweak: Default chat line height is slightly shorter, from 1.4 to 1.2 -2017-12-22: - Awesine: - - rscadd: added some things which happen to be mining scanner things to that gulag - thing - Kor: - - rscadd: During Christmas you will be able to click on the tree in the Chapel to - receive one present per round. That present can contain any item in the game. - Naksu: - - bugfix: frying oil actually works - WJohnston: - - tweak: Syndicate nuke op infiltrator shuttle is no longer lopsided. - kevinz000: - - rscadd: 'Clown modules have been added for cyborgs! Modules: Bikehorn, Airhorn, - instrumental bikehorn, clown stamp, multicolor paint, rainbow crayon, soap, - razor, purple lipstick, nonstunning selfcharging creampie cannon, nonslipping - selfcharging water sprayer, lollipop fabricator, metallic picket sign, mini - extinguisher, laughter reagent hypospray, and the ability to hug. experimental: - When emagged they get a fire spray, "super" laughter injector, and shocking - or crushing hugs. Also, the module is adminspawn only at the moment.' - - bugfix: Projectiles that pierce objects will no longer be thrown off course when - doing so! - - code_imp: Projectiles now use /datum/point/vectors for trajectory calculations. - - bugfix: Beam rifle reflections will no longer glitch out. -2017-12-23: - Dax Dupont: - - bugfix: Borgs will no longer have their metal/glass/etc stacks commit sudoku when - it runs out of metal. They will also show the correct amount instead of a constant - of "1" on menu interaction. - Kor: - - rscadd: During Christmas you will be able to click on the tree in the Chapel to - receive one present per round. That present can contain any item in the game. - Robustin: - - tweak: The EMP door shocking effect has a new formula. Heavy EMP's will no longer - shock doors while light EMP's have a 10% chance (down from 13.33%). - coiax: - - balance: The kitchen gibber must be anchored in order to use. - - balance: The gibber requires bodies to have no external items or equipment. -2017-12-24: - Frozenguy5: - - bugfix: Soapstones now give the correct time they were placed down. - More Robust Than You: - - tweak: Vending machines now use TGUI - SpaceManiac: - - bugfix: '"Download N research nodes" objective is now checked correctly again.' -2017-12-25: - SpaceManiac: - - bugfix: The Syndicate radio channel works on the station properly again. - coiax: - - rscadd: Ghosts can now use the *spin and *flip emotes. - uraniummeltdown: - - rscadd: Examine a door assembly to check what custom name is set. -2017-12-26: - Cyberboss: - - tweak: Objects that can have materials inserted into them only will do so on help - intent - PsyKzz: - - rscadd: Jaws of life can now cut handcuffs - SpaceManiac: - - admin: Play Internet Sound now has an option to show the song title to players. - XDTM: - - balance: Rebalanced healing symptoms. - - balance: Cellular Molding was replaced by Nocturnal Regeneration, which only works - in darkness. - - balance: All healing symptoms now heal both brute and burn damage, although the - basic ones will still be more effective on one damage type. - - balance: Plasma Fixation and Radioactive Metabolism heal toxin damage, offsetting - the damage done by their healing sources. - - balance: Changed healing symptoms' stats, generally making them less punishing. - Xhuis: - - balance: Medical supplies on all normal maps (Box, Meta, Delta, Omega, and Pubby) - are now behind ID-locked windoors. These windoors will become all-access during - red alert! - YPOQ: - - bugfix: Emagged cleanbots can acid people again - - bugfix: Headgear worn by monkeys can be affected by acid - ninjanomnom: - - bugfix: The auxiliary mining base can no longer be placed on top of lava, indestructible - turfs, or inside particularly large ruins. - - bugfix: The backup shuttle has it's own area now and you should no longer occasionally - be teleported there by the arena shuttle. - - bugfix: Cycling airlocks on shuttles should work correctly when rotated now. - - bugfix: Things like thermite which burned through walls straight to space now - stop on plating. You'll have to thermite it again to get to space. -2017-12-27: - More Robust Than You: - - code_imp: Changed roundend sounds and lobby music to use one proc for choosing - sounds - - server: You can now easily host roundstart sounds without changing the code! - - config: RIP in shit round_start_sounds.txt - Nero1024: - - soundadd: blast doors and shutters will now play a sound when they open and close. - Robustin: - - bugfix: Hallucinations will no longer show open doors "bolting". - SpaceManiac: - - code_imp: The R&D console has been made more responsive by tweaking how design - icons are loaded. - Xhuis: - - rscadd: Maintenance drones and cogscarabs can now spawn with holiday-related hats - on some holidays! - coiax: - - rscadd: Deltastation now has christmas trees during seasonally appropriate times. - deathride58: - - bugfix: Praise the lord! The shift+scroll hotkey to zoom in/out as a ghost works - properly again! - kevinz000: - - rscadd: you can now pick up corgi's and pAIs, how disgustingly cute - - code_imp: Forensics is now a datum component. - - balance: NPC humans will now start leaving fingerprints on things they touch! -2017-12-28: - Cyberboss: - - bugfix: Ghost lights will follow the ghost while orbiting - Robustin: - - bugfix: Splashing a book with ethanol should no longer produce errant messages. - - balance: Dead cultists can now be moved across the "line" on Reebe. -2017-12-29: - CosmicScientist: - - rscadd: timestop now inverts the colours of those frozen in time! - Dax Dupont: - - bugfix: APCs and other wall mounted objects are no longer blocked by the secure - medbay storage parts. - - bugfix: Removed a duplicate radiation collector on Deltastation. - More Robust Than You: - - bugfix: The Radiance can now enter the chapel - - bugfix: Monkey chat should no longer have .k prefixed - - bugfix: Monkey leaders should actually get jungle fever now - Robustin: - - bugfix: The action button for spells should now accurately reflect when the spell - is on cooldown - - bugfix: You can now reliably use the button for "touch" spells to "recall" the - spell - SpaceManiac: - - code_imp: Explicit z-level checks have been changed to use defines. - XDTM: - - rscadd: 'Added a new reagent: Pax.' - - rscadd: Pax is made with Mindbreaker, Synaptizine and Water, and those affected - by it are forced to be nonviolent against living beings. At least, not directly. - coiax: - - rscadd: Adds an internal radio implant, allowing the use of the radio if you expect - to have your headset removed. Or if you don't have any ears or hands. It can - be purchased for 4 TC from any Syndicate uplink. - - rscadd: Nuke ops now buy special "syndicate intelligence potions" that automatically - insert an internal radio implant when used successfully. Cayenne can now participate - in your high level discussions. -2017-12-30: - Cyberboss: - - tweak: Burial jumpsuits no longer have suit sensors - - tweak: The chemistry job has been removed from Omegastation. Medical doctors still - have full chemistry access - MrDoomBringer: - - imageadd: NanoTrasen has sent the station new spaceheaters! They look nicer now! - Xhuis: - - balance: Vitality matrices now apply Ichorial Stain when reviving a dead servant, - which prevents that servant from being revived again by vitality matrices for - a full minute. - - balance: Vitality matrices can't be placed adjacent to one another. - - balance: Brass skewers now damage and stun cyborgs. - - balance: Vitality matrices no longer drain people impaled on brass skewers. - - balance: Pressure sensors have 5 health again (down from 25.) - ninjanomnom: - - bugfix: Some changes to turfs like shuttles would result in un-initialized space - tiles being created. This has been fixed. -2017-12-31: - Cyberboss: - - rscadd: Explosions now cause camera shake based on intensity and distance - F-OS: - - bugfix: Last resort now requires a confirmation - Naksu: - - code_imp: loot drop spawners now assign their pixel offsets to the items they - spawn, also have a "fanout" setting to distribute items in a neat fashion like - in omega/delta's core and some tech storages. - - tweak: replaced several law boards in uploads with spawners, the net result being - one more board in uploads that may be a duplicate asimov (but hopefully isn't) - SpaceManiac: - - bugfix: Viewing photos sent by PDA message works again. - WJohnston: - - rscadd: Redesigned the entire syndicate lavaland base to be more stylish, have - functioning power and atmos as well as a turbine to play with. - XDTM: - - bugfix: Fixed a hallucination that would say [target.first_name()] instead of - the actual name. -2018-01-01: - Dax Dupont: - - bugfix: PDA messages have been fixed. -2018-01-02: - Dax Dupont: - - bugfix: The bank vault is no longer metagaming. It will now display the IC station - name. - DaxDupont: - - bugfix: Solar control consoles are no longer pointing to the wrong direction, - you can now turn tracking off again and manual positioning of solar panels have - been fixed. - Frozenguy5: - - rscadd: Adds a goon and cult emoji. Improves gear and tophat. (Credits to GoonStation - for creating the goon bee sprite.) - Okand37: - - rscadd: Overhauled aesthetic of some portions of Omegastation - - rscadd: Overhauled Omegastation's departure lounge, fitting it with the rest of - the station's theme - - rscadd: Replaced the personal closets with wardrobes in Omegastation's Lockerroom - - rscadd: Made Omegastation's engine room floortiles reinforced - - rscadd: Replaced the cola and snack machines with their random counterparts on - Omegastation - - bugfix: Fixed Omegastation's self destruct console being a doomsday device - - bugfix: Fixed Omegastation's chemistry shutters not all being synced and rearranged - the chemmaster. - - rscadd: Added a small technology storage in maintenance near departures on Omegastation - - rscadd: Added additional loot and emergency supplies to maintenance on Omegastation - - rscadd: Added the X-01 Multiphase to the Captain's Locker, Blueprints to Vault, - Reactive Teleportation Armor to Server Room and theHypospray to Medical Storage - on Omegastation - XDTM: - - bugfix: Fixed Runic Golem's Abyssal Gaze blinding permanently. - - balance: Ocular Restoration has been removed, its effect transfered on Sensory - Restoration. - - balance: Sensory Restoration now heals both eye and ear damage. - - balance: Mind Restoration now no longer heals ear damage, but now heals brain - damage by default. - - balance: Mind Restoration's thresholds can now let the symptoms cure mild brain - traumas at 6 resistance and severe ones at 9. - ninjanomnom: - - bugfix: Turfs are construct-able again -2018-01-03: - Cyberboss: - - bugfix: Fixed lathe power consumption being too high - - bugfix: You no longer cut yourself with shards when clicking a portal - Dax Dupont: - - bugfix: After 2 years and 2 separate issues the paper mache wizard robe has finally - been fixed. - Naksu: - - rscadd: A damaged core AI module may now spawn in AI uploads. It contains a random - amount of ionic laws with normal law priorities. - - bugfix: splash-fried food is now actually edible - SpaceManiac: - - bugfix: Mimes now laugh silently. - deathride58: - - tweak: Explosions will no longer give everyone and their mothers motion sickness - from a mile away. -2018-01-04: - Cyberboss: - - bugfix: The bloodcult sacrifice objective description won't change when the target - is sacrificed - Dax Dupont: - - rscadd: PDA Interface color is now a preference. - - bugfix: Fixed PDA font style not applying at round start. - - rscadd: 'The following messages have been added to dead chat: Security level change, - (re)calling, Emergency Access, CentComm/Syndicate console messages, outgoing - server messages and announcements,' - MrStonedOne: - - bugfix: The changelog hadn't been updating. This has been fixed. - ShiggyDiggyDo: - - tweak: Syndicate experts were able to create more sophisticated copies of the - nuclear authentication disk. While still unable to detonate the nuclear fission - explosive with them, they're practically identical to the real disk if not examined - closely. -2018-01-05: - Cruix: - - bugfix: Chameleon PDAs now have their chameleon action. - Okand37: - - rscadd: Added a fully functioning A.I. satellite to Omegastation! - - rscadd: Added the CE's magboots to the gravity room on Omegastation! - - rscadd: Added a medical wrench to cryo for Omegastation! - Shadowlight213: - - bugfix: Devils will no longer be permanently stuck if interrupted while trying - to jaunt. - - bugfix: Devils will now properly clear the fake fire if failing to jaunt. - SpaceManiac: - - bugfix: The startup load time of away missions has been drastically reduced. - - bugfix: The admin notification for the pulse rifle prize now shows the correct - coordinates. - deathride58: - - bugfix: Explosions now function properly again! -2018-01-10: - Robustin: - - bugfix: Blood cultists will now properly display a "reverted to their old faith" - message when deconverted. -2018-01-11: - Cyberboss: - - spellcheck: Fixed mechanical arms grammar when failing to activate - - bugfix: You will now no longer hit closets when attempting to anchor them - ExcessiveUseOfCobblestone: - - code_imp: Adds Stat Tracking to Techwebs by node and order. - Selea: - - rscadd: pulling claw.Integrated circuit, which allow assemblies to pull things. - ShizCalev: - - bugfix: 'Meta: The UI for the captain''s cigarette vendor now works again.' - - tweak: 'Meta: Removed the omnizine filled syndicate cigarettes from the captain''s - cigarette vendor.' - - tweak: Medbots are no longer able to inject you if you do not have any exposed - flesh. - Someguynamedpie: - - bugfix: Use world.timeofday instead of world.realtime - SpaceManiac: - - spellcheck: Replaced "CentComm" with "CentCom" in communications console deadchat - announcement. - - refactor: Information about the properties of z-levels is now less hardcoded than - before. - Tortellini Tony: - - rscadd: 'New hotkey for admin say command: F3.' - yorii: - - spellcheck: Renamed the ChemMaster eject button to highlight the fact that the - buffer does not get cleared -2018-01-12: - Cobby: - - tweak: As a human, you will now point with your legs when you have no arms, falling - over each time. - - tweak: As a human, you will bump your head on the ground trying to motion towards - something when you have no arms or legs. - Cyberboss: - - spellcheck: Fixed message grammar when lifting someone off a brass skewer - - bugfix: Fixed the original poker tables not being deleted after Narsie converted - them to a wooden table - Dax Dupont: - - rscadd: Thanks to the extensive disco and plasma research gathered by the Disco - Inferno shuttles, an indestructible mark V disco machine is now available. The - latest edition of the Disco Inferno shuttle now carries it. - JJRcop: - - code_imp: Removes some links intended for admins from game logs. - More Robust Than You: - - balance: Sigils of submission now uncuff upon successful conversion - PKPenguin321: - - tweak: Cyborgs that take enough damage to have a module disabled will now automatically - announce that they've had a module disabled to anybody nearby. Now if you want - to stop a cyborg from interfering with your business but don't want to kill - it, you can simply bash until you see the CRITICAL ERROR message. - - soundadd: Borgs will play an alarm sound in addition to displaying this message - as they have their modules disabled. - ShizCalev: - - bugfix: You can now attach collars to pets again! - - bugfix: Corrected pet collars icon mismatch. - - bugfix: Pets will now drop their collars when gibbed. - - tweak: You will no longer be able to rename unique pets, such as Ian or Runtime. - You can still rename pets without a special name. - - bugfix: Secbot assemblies will no longer lose their weld hole when dragged North - - imageadd: Secbot assemblies now have new North facing sprites! - - imageadd: Cleaned up a rogue pixel on beepsky's sprite. - - bugfix: Defibrillators now have inhands again! - - bugfix: Defibrillators will no longer stay in your hands after you die. - - bugfix: Losing an arm while wielding a two handed weapon will now cause you to - drop the weapon. - - bugfix: Losing an arm while carrying an item that requires two hands to hold will - now cause you to drop the item. - - spellcheck: Improved user feedback from chem dispenser macros. - - bugfix: Fixed Tests Areas debug verb. - - bugfix: Only the chaplain can now purify a bloody bastard sword. - - bugfix: Fully healing a mob as an admin now cures disabilities properly. - - bugfix: Non-cultists hulks can no longer withstand the immense powers of Ratvar's - influence while holding a bloody bastard sword. - - bugfix: The average body temperature has been corrected to 98.6F. - - tweak: Safe dials will now present itself in 1 number increments, instead of 5. - - bugfix: Relabeled canisters will no longer switch to an incorrect sprite when - broken. - SpaceManiac: - - bugfix: Relabelled canisters once again have the correct description. - - bugfix: The interface of airlock consoles has been restored to normalcy. - YPOQ: - - bugfix: Securitrons/ED-209s/Honkbots will only activate their emag functions after - their internals are emagged -2018-01-14: - Dax Dupont: - - bugfix: The NT Violet Lepton shuttle has been retrofitted with lava proof windows - for the lava engine. They will no longer catch fire and violently decompress - the shuttle. - Leshana: - - bugfix: Fix attempt to use `in` on a non-list. Pretty sure bitfields do not work - that way. - - admin: SS_NO_FIRE subsystems will no longer display pointless cost statistics - in MC panel - QualityVan: - - balance: Due to budget cuts, the vault safe is now slightly less resistant to - explosions. - ShizCalev: - - bugfix: Constructed security/honk/ect bots will now drop the correct parts when - destroyed. - - bugfix: "Some areas will no longer present themselves at \"\xC3\xBFUnexplored\ - \ Area\"" - SpaceManiac: - - bugfix: The R&D console design icon for slot machines is no longer mangled. - - bugfix: The Ark's teleportation checks now take mechs and sleepers into account - correctly. - - spellcheck: Activating internals via the right-side button produces better messages - on success. - - bugfix: The RPD will no longer fail to paint and layer pipes in some situations. - - bugfix: Unwrenching canisters from connector ports on non-default layers now resets - their pixel offset. - Thunder12345: - - bugfix: The NES Port emergency shuttle will no longer drain the CentComm emergency - dock of air - XDTM: - - tweak: Dreams are now more immersive and interesting. - deathride58: - - admin: You can now choose an outfit to be equipped while transforming a mob to - human via rudimentary transform. -2018-01-15: - Cruix: - - rscadd: Roundend traitor purchase logs now have tooltips showing the name, cost, - and description of the items. - F-OS: - - rscadd: NT has disabled their automatic APC lock - - tweak: The space heater now has a warning on it about use in the SM. - Half of coderbus ended up working on this somehow: - - rscadd: Goats will now dismember plant people when attacking them. - Iamgoofball: - - bugfix: The Express Console emag effect is now worth using. - JohnGinnane: - - bugfix: Fixed not being able to alt click on a stack - More Robust Than You: - - bugfix: Monkey Leaders should now properly get Jungle Fever - - bugfix: Monkeymode roundend report should now properly show Major/Minor victory - - bugfix: Monkeys should now get the jungle fever objective in monkeymode - - imageadd: Wirecutters can come in even more colors now! - ShizCalev: - - bugfix: RPDs and pipe painters now have more colorssssssssssssssssss - SpaceManiac: - - bugfix: Title screens without multiple dots in their filename will now be chosen - again. - - bugfix: MMIs in mechs or held by humans wearing fireproof suits are no longer - burnt by ash storms. - WJohnston: - - rscadd: Encrypted radio waves have been detected airing around station space. - Watch for possible enemy communications. - - rscadd: The space syndicate listening post has been remade from scratch, and now - has an actual ghost role to help spy on the station and relay info to traitors! - Xhuis: - - tweak: Added some new tips to the list for fighting the clockcult! - - rscadd: Added a new bar sign, The Lightbulb. - YPOQ: - - bugfix: Players are immune to their own slime time stops again - coiax: - - rscadd: A xenomorph maid (or barmaid) cleans the floor as they walk on it. Lie - down, and they'll clean your face. - ninjanomnom: - - admin: There are 3 new helpers in the secrets menu for messing with movement controls - - bugfix: Mining base walls when broken turn into plating which in turn breaks down - to the basalt surface. - theo2003: - - tweak: The autolathes on MetaStation, and DeltaStation next to R&D are now accessible - from R&D via windoor. -2018-01-16: - AnturK: - - bugfix: Photos now properly capture everything again. - DaedalusGame: - - bugfix: fixed duplicate reagent definitions in chem macros - SpaceManiac: - - bugfix: Heat exchange manifold pipes facing east/west now work again. - Thunder12345: - - bugfix: The asteroid with engines strapped to it will no longer vent both the - CentCom docks and its own entrance. - XDTM: - - rscadd: Reworked the species side of xenobiology. - - rscadd: Instead of an universal unstable mutation toxin, green slimes can now - produce slime mutation toxin (plasma), human mutation toxin (blood), and lizard - mutation toxin (radium). - - balance: Slime mutation toxin requires several units and some time before acting, - unless you're already a slimeperson (in which case it will randomize your subspecies) - - rscadd: Two new jellypeople subspecies have been added to make up for the lost - species. - - rscadd: Stargazers have telepathic abilities; they can Send Thoughts, privately - and anonimously, to any target they can see, and they can Link Minds with any - aggressively grabbed mob to form a hivemind with them. Hiveminds have no limit - but expire when the Stargazer dies or changes species. - - rscadd: Luminescents glow faintly and can absorb slime cores to gain special abilities. - Each core has a minor and a major ability, generally based on what they normally - do. Using these abilities does not use up the cores, but it has a cooldown depending - on the ability's power. - - balance: Slimepeople can now switch bodies on death or when unconscious, as long - as they have another one. -2018-01-17: - DaedalusGame: - - balance: you can't get 12 syndi bomb cores from stripping the syndi lava base - for parts anymore - - bugfix: fixed the syndi lava base blowing up from stray colossus shots, goliaths - breaking in or miners throwing gibtonite at it. - F-OS: - - tweak: Air alarms start unlocked - - bugfix: Air alarms no longer think they are fire alarms - - bugfix: Drone dispensers no longer hide drones - - bugfix: Ash storms aren't at ear-rapey volumes inside shielded areas. - ShizCalev: - - bugfix: Gas tanks are now made of metal! Honk - SpaceManiac: - - bugfix: Clicking lattices and girders with the RPD now succeeds instead of appearing - to place a pipe but failing. - - bugfix: The debug verbs "Display Air Status" and "Air Status in Location" now - format their reports the same and actually work more often. - - bugfix: The Camera Failure event no longer crashes the server if the station has - no cameras. - - admin: SDQL "select" outputs now have buttons to jump to the coordinates of the - found objects. - Xhuis: - - balance: You now have to climb through rifts to Reebe by walking into them, instead - of instantly warping away when you bump into one. - - balance: The separation line between the crew spawn and servant spawn in Reebe - now blocks airflow. - - rscadd: Added a new bar sign, The Lightbulb. - - bugfix: The Eminence's mass recall ability should now work properly - coiax: - - rscadd: If enough people vote to start CTF (by clicking on a CTF controller as - a ghost), then CTF will automatically begin. - deathride58: - - rscadd: By using a multitool on a radiation collector, you can use it to generate - research points! This requires a tank filled with a mix of tritium and oxygen. - - tweak: The display of rad collectors' power production rates has been moved from - a multitool interaction to examine text. - - tweak: Radiation collectors now emit a ding when they run out of fuel. - kevinz000: - - bugfix: Flashes can no longer work from inside containers to flash people outside. - - balance: Research export cargo points have been halved - nicbn: - - tweak: The Pirate Code changed its first rule to "BE AN SKELETON YARR". The old - "there are no rules" is now the second rule. -2018-01-18: - Buggy123: - - tweak: full-tile plasmaglass windows have had their integrity increased to the - correct value. -2018-01-19: - AverageJoe82: - - tweak: Reduce clock work mob death sound file's volume to 80% - Buggy123: - - rscadd: Observers can now view the atmospheric contents of the tile they're floating - above. - Cyberboss: - - refactor: Added test run mode which checks for runtimes in startup/shutdown and - runs tests (if they were enabled during compilation). Invoke it with the "test-run" - world parameter - Dax Dupont: - - bugfix: Autolathe now consumes reasonable amounts of power when inserting materials - - bugfix: Fixed conveyor belt power usage. - Frozenguy5: - - code_imp: Travis now builds on BYOND 512.1403 - Joan and More Robust Than You: - - rscadd: Adds moths! They're a new species that is able to fly in pressurized areas - provided gravity is off... and that they still have wings. - More Robust Than You: - - rscadd: Added some useful sec officer tips - OrdoM: - - rscadd: Adds morphine recipe to chemistry. - - rscdel: Removed ability for bartender to steal all morphine on the map - Robustin: - - bugfix: Fixed frost oil (cryosting) sending insulated crewmembers below absolute - zero temperatures. - - bugfix: Fixed damaging cold temps being a death sentence to simple mobs (they - wouldn't heat back up to safe temps at room temperature). - - refactor: Refactored human temperature code, insulating clothing now helps you - stay warm but going unprotected will help you cool off. However, you will now - benefit from colder temps when you're overheating even in full EVA/hardsuit - gear and you will warm up faster at room temperature in insulated gear as well - (i.e. putting on a winter coat will no longer suppress your temperature if your - already cold). - - bugfix: All crew can now purify bloody bastard swords with a bible (available - from cargo religion crates, library, or chapel) once again. - Shadowlight213: - - rscadd: Players can now have a verb in the ooc tab to see their own tracked playtime - - bugfix: fixed admin bypass not using the right proc - - bugfix: Lavaland ghost roles should now show up in the playtime report - ShizCalev: - - bugfix: Floors that look damaged / burned are now ACTUALLY damaged / burned, and - can be repaired! - SpaceManiac: - - bugfix: PDA messages sent by the message monitor console are now included in the - talk logs. - XDTM: - - tweak: Mass Hallucination now will give everyone the same hallucination. - - bugfix: Slimepeople can now properly swap between bodies. - - bugfix: Slimes no longer attack people with their same faction. - Xhuis: - - tweak: Servants can now cancel warps by clicking the button again, instead of - having to manually interrupt it by doing something like picking up an item from - their pocket. - coiax: - - rscdel: The Free Golem Ship no longer has a teleport beacon. - - rscdel: Jaunters no longer have a special effect when teleporting golems. - deathride58: - - rscadd: Mappers can now color individual tiles of floors via turf decals. - - bugfix: Cancelling the "Change equipment" command now works as expected again. - uraniummeltdown: - - bugfix: Jaunting wraiths should now always be facing the correct direction - yorii: - - bugfix: fixed the syringe getting a transfer amount of 0 if the contents of it - are 0, intended feature was probably to check the target and not the syringe - itself for clamp. -2018-01-20: - MrDoomBringer: - - rscadd: All Cargo Techs now come equipped with a standard supply Export Scanner! - Get to selling! - XDTM: - - bugfix: Fixed a bug where slimes wouldn't eat neutral mobs. - uraniummeltdown: - - tweak: Emagged airlocks can now be deconstructed simply by crowbarring when the - panel is open -2018-01-21: - Dax Dupont: - - bugfix: Moth wings will now respect your preferences. - WJohnston: - - rscadd: We've lost contact with one of our trade caravans in your sector, be on - the lookout for possible enemy activity. - - rscadd: Redesigned the syndicate ambush space ruin. It now boasts multiple flyable - shuttles and looks a lot prettier. - - imageadd: Wirecutter greyscaling is now less ugly -2018-01-22: - DaedalusGame: - - balance: foam and smoke now get 4x the reagents as they should according to the - comments - - bugfix: fixes pyrosium and cryostylane not heating or cooling humans at all - - bugfix: fixes cryostylane cooling beakers to negative kelvin, it's now limited - to what the description says - - bugfix: fixes cryostylane cooling people to negative body temperature - - code_imp: removed redundant check in trans_to - - code_imp: fixes a runtime when total_volume is 0 in copy_to - - tweak: Gas reagents (o2, plasma, ...) now dump out gas based on container temperature - instead of room temperature - Dax Dupont: - - rscadd: Fans of clown photography have successfully lobbied Nanotrasen to include - camera and camera accessories designs in the autolathe. - - tweak: Brings material values for the camera in line with other devices. - - tweak: The tapes printed by autolathes now come in random colors. - Dax Dupont & Coiax: - - rscadd: Praise the lord for he has granted thy chaplains, wizards, revenants and - eminences with holy vision. They can now see blessed tiles. - MMMiracles: - - rscadd: Syndicate and pirate mobs now give off light when appropriate - More Robust Than You: - - bugfix: Fixed monkey teams - - tweak: The Lepidopterian language now has less spaces in it - Robustin: - - bugfix: Fixed monkeys slowly freezing to death - ShizCalev: - - bugfix: Clockcultists and revolutionaries can no longer be mindswapped. - SpaceManiac: - - refactor: Weather and certain events have been updated to use Z traits. - - bugfix: The Staff of Storms now correctly starts and ends storms if used from - inside lockers. - - bugfix: Weather telegraph messages are now shown to those inside lockers and mechs. - - bugfix: Radio jammers no longer affect other z-levels. - Tlaltecuhtli: - - tweak: min player req for rev is 30 now - Xhuis: - - bugfix: Emergency lights now function correctly. - deathride58: - - code_imp: Light fixtures no longer use hardcoded values for their power and colour. - ninjanomnom: - - bugfix: Functions that aren't intending on actually moving the shuttle yet don't - send error messages to admins anymore when seeing if a shuttle *can* move. - scrubs2009: - - tweak: Candles last longer - uraniummeltdown: - - bugfix: Bananium shows up on mining scanners again -2018-01-23: - Cruix: - - bugfix: engine goggles set to t-ray mode will no longer show pipes with the wrong - rotation. - - bugfix: cables now show up on t-ray scans. - Dax Dupont: - - bugfix: Fixed missing tile under autolathes - MrDoomBringer: - - rscadd: NanoTrasen's Creative Psychology Initiative has brought new training to - all crewmembers to foster rapid, innovative problem-solving! You can now kill - yourself in so many more ways! - - rscadd: The RnD department can now develop firmware upgrades to the Express Supply - Console, unlocking advanced cargo drop pods! - Naksu: - - code_imp: removed a bunch of unnecessary vars, combining them into a bitfield - SpaceManiac: - - bugfix: Fixed occasional runtimes when ion storms or overflow would replace an - existing law. - WJohnston: - - bugfix: Space syndie listening post now has a real microwave, and a book management - console. Lava listening post comms room intercom now no longer starts with broadcast - on. - - rscadd: the syndicate drop ship and fighter pods from the caravan ambush can now - be flown to the syndicate listening post. The fighter pods also now have xray - cameras because regular ones were super useless. - XDTM: - - rscadd: Added Regenerative Jelly, made with tricordrazine and slime jelly. It - regenerates a bit faster, and won't harm jellypeople. - - rscadd: Added Energized Jelly, made with teslium and jelly. It works as an anti-stun - chemical for slimepeople and speeds up luminescents' power cooldown, but non-jellypeople - will just get shocked. - - rscadd: 'Added Pyroxadone, made with cryoxadone and slime jelly. It''s basically - inverse cryoxadone: it heals faster the hotter your body temperature is.' - - tweak: Cryoxadone no longer deals toxin damage to jellypeople. - - tweak: Purple Slime Extracts no longer have their sugar->slime jelly reaction - (obsolete with extract grinding), and instead have a blood->regen jelly reaction. - - tweak: Purple Extract's major activation by Luminescents now give regenerative - jelly instead of tricordrazine. - coiax: - - rscadd: Fake nuclear disks can only be identified by the captain, observers, nuclear - operatives, seeing where the pinpointer points, or attempting to put it into - a nuclear device. - - rscadd: Fake nuclear disks "respawn" on the station just like the real one. - kevinz000: - - rscdel: pulling claw can now only passively grab - - bugfix: Infrared beams now update instantly. - ninjanomnom: - - bugfix: Changeling clothing can get bloodied again. - the hatchet man (i eat garbage code): - - bugfix: 'you shitlords picked the wrong virtual anime tits to fuck so im takin - away your space bases experimental: lets be fair all you guys did in those was - jack off to hentai, and not real man''s gachimuchi' -2018-01-24: - Dax Dupont: - - bugfix: Fixed missing wheat fridge on omega and removes a duplicate pipe. - - rscadd: Beakers and beaker-like objects now get put in your hand on ejection from - chemistry devices. - Shadowlight213: - - bugfix: Fixed eye damage not being applied if it was exactly 3. - YPOQ: - - bugfix: Emergency lights will give off light again - ninjanomnom: - - bugfix: Pointing at squeaky things doesn't make them squeak anymore. -2018-01-25: - Dax Dupont: - - imageadd: Autolathe now repeats it's animation while printing. - - tweak: You now need to examine engravings to pop open the menu. - - bugfix: People can no longer extract 300 supermatter shard slivers without it - exploding. - - bugfix: Fixed thongs not dusting people on use. - Jittai: - - tweak: All color inputs now use the current color, of the thing being colored, - as default choice. - More Robust Than You: - - rscadd: You can now defib monkeys and aliums - - tweak: Monkeys can also use defibs now, too! - Naksu: - - code_imp: Slightly refactored object armor code - Ordo: - - rscadd: Adds Ketrazine, a powerful but dangerous combat stim which the crew can - synthesize - Robustin: - - balance: Clockwork marauders now take more time (+3s) and power (7x) to create. - - balance: The "recent marauder" time limit is now 60 seconds, up from 20. The limit - now has a significantly smaller effect on summon time but will act as a further - cap on marauder summoning until it has passed. - - tweak: The marauder cap will now only account for living cultists. - - rscadd: 'A new cocktail: The Nar''Sour. Made from blood, demonsblood, and lemon - juice, this cocktail is known to induce a slightly different type of slurring - when imbibed.' - SPACE CONDUCTOR: - - tweak: Shuttles will throw you around if ya don't buckle in - Shadowlight213: - - balance: Moths are now more susceptible to bright lights - Togopal, Armhulenn, Naksu, Jordie & oranges: - - rscadd: Snakes! They hunt vermin on the station! Curators have a natural phobia - to them. - - rscadd: They can be purchased in cargo. - XDTM: - - rscadd: Slimepeople and Jellypeople can now speak the slime language. - - tweak: Slimes now only speak slime language, although they still understand common. - - balance: Slimepeople are no longer virus immune. - - bugfix: The above change fixes a bug that made black slime cure itself. - Xhuis: - - balance: Fleshmend can no longer be stacked several times at once. - - balance: Fleshmend no longer heals changelings who are on fire, and heals burn - damage half as quickly as brute and oxygen damage. - - code_imp: Fleshmend has been refactored into a status effect. - coiax: - - rscadd: Nuclear operatives that wish to fail in style can purchase Centcom Official - and Clown costumes. They can also buy a defective chameleon kit. - - rscadd: The majority of shuttles are now loaded at the start of the round from - template, rather than being premapped. As a side effect, Delta's mining shuttle - now docks facing down at Lavaland. - imsxz: - - rscadd: Traitor clowns are now able to purchase clown bombs from their uplinks. - Honk! - - rscadd: Clown bombs can now be placed via a small beacon, the same way normal - syndicate bombs can be. - - tweak: clown bomb payload now summons 50 clowns instead of 100 - nicbn: - - bugfix: Now if you lose arms you won't be able to see through your uniform. - ninjanomnom: - - bugfix: Loaded templates now get placed on top of existing terrain so as to preserve - baseturfs. This fixes survival pods walls breaking to lava as well as allows - some future fixes. -2018-01-26: - Cruix: - - bugfix: Fixed being able to rotate things in only one direction. - DaedalusGame: - - rscadd: Firefighting Foam reagent, better alternative to water and corn oil for - firefighting purposes - Dax Dupont: - - rscadd: You can now rename and copy holodisks! - - rscadd: Holorecordings now can be looped. - - tweak: Holodisks now have materials and the autolathe cost has been adjusted. - - bugfix: Fixed holodisk speaker name not getting set when on non-prerecorded messages. - Epoc: - - bugfix: Slows Simple Clown mobs - GuppyLaxx: - - bugfix: Fixes the Ketrazine recipe - Iamgoofball: - - balance: Power cells explosions are now logarithmic - Naksu: - - code_imp: Cleaned up some /obj/item vars - - bugfix: Pneumatic cannons no longer misbehave when their contents such as primed - grenades get deleted (explode) - Robustin: - - rscadd: The Peacekeeper Borg's "Peace Hypospray" now includes the "Pax" reagent, - which prevents the subject from carrying out many forms of direct harm. - SpaceManiac: - - spellcheck: Clockwork armaments are no longer named "arnaments". - - bugfix: The Syndicate Listening Post's medicine closet now has the correct access. - coiax: - - rscadd: Syndicate intelligence potions also grant an internal syndicate ID card - to the simple animal granted intelligence. This effectively means that Cayenne - can open the airlocks on the Infiltrator. - uraniummeltdown: - - bugfix: You can no longer weld airlock assemblies for infinite materials -2018-01-27: - Anonmare: - - balance: The Syndicate Chameleon Kit is now available during rounds of lower population. - Because of course you can have an e-sword and revolver without restriction but - disguising and RP is verboten because we deathmatch station now. - Dax Dupont: - - bugfix: Eminence won't get spammed by tile crossing now. - Denton ShizCalev Kor Kevinz000 (original idea): - - balance: Due to budget cuts, the shoes shipped with chameleon kits no longer prevent - slipping. The premium version is unchanged and still sold separately. - - balance: To compensate, the chameleon kit cost was lowered by 2 TC and the minimum - crew limit removed. - Jittai: - - imageadd: New Morgue Tray sprites. - - imageadd: New Crematorium sprites. - Naksu: - - bugfix: Away missions no longer require manually adjusting subsystem mob/client - lists in order to not have the AI break. - WJohnston: - - bugfix: The lavaland syndie base is now packed with considerably fewer explosives, - and should lag far less brutally when exploding. - coiax: - - balance: Mobs will now start with a random nutrition amount, between hungry and - mildly well fed. - - rscadd: Nanotrasen Security Division has reported that syndicate comms agents, - both on lavaland and in space, have had training in "Codespeak", a top secret - language for stealthy communication. - uraniummeltdown: - - imageadd: Ore boxes have a new sprite -2018-01-29: - ACCount: - - rscadd: Having station blueprints in your hands now reveals function of wires - in station objects. - DaedalusGame: - - bugfix: fixed a strange pipenet issue that happens when a singular pipe or manifold - is placed directly between two or more components and wrenched last. - Dax Dupont: - - bugfix: After 3 years of intensive research by Nanotrasen's elite team of chefs, - rice dishes such as rice pudding are no longer considered salads. - Denton: - - spellcheck: Fixed Bubblegum's description. - F-OS: - - tweak: Academy is now part of the random station names. - Mark9013100: - - rscadd: Cloning data disks can now be constructed after researching the Genetic - Engineering technode. - MrStonedOne: - - tweak: 511 Clients can see atmos gases - - rscdel: This reverts the fix that prevents atmos gas overlays from stealing clicks. - Naksu: - - bugfix: Attempting to join into a command role as a nonhuman species no longer - lets you keep your nonhuman species languages if you are transformed into a - human because of a config option - - bugfix: Warp whistle can no longer pick up its user from inside various animation/in-between - states and effects such as transformations, jellypeople split, talisman of immortality - effect period or rod form. - WJohnston: - - bugfix: The centcom ferry shuttle now works again. - XDTM: - - balance: Peacekeeper cyborgs have synth-pax instead of normal pax, which has the - same effect but wears out faster. - - rscadd: Xenobiology consoles can now scan slimes and apply potions remotely. Use - potions on the console to load them. - - rscadd: Abductors now have the chemical, electric and trauma glands. - - rscdel: Removed the bloody, bodysnatch and EMP glands. - - tweak: The abductor viral gland now generates a random advanced virus instead - of a basic one. - - tweak: The abductor heal gland now also heals toxin damage. - - tweak: The abductor mindshock gland can now cause different reactions. - - tweak: The abductor slime gland now gives the slime faction. - - tweak: The abductor species gland now randomizes the victim's appearance and name - on top of the species. - - rscadd: 'Abductors have a new surgery type: violence neutralization. It has the - same steps as brain surgery, but it will instead inflict a Pacifism trauma upon - the victim, making them mostly harmless in the future.' - - rscadd: Bath Salts now give complete stun immunity while they last. - - balance: Ketrazine now gives immuity to sleeping. - improvedname: - - rscadd: Adds bz to cargo - ninjanomnom: - - rscdel: Removed the ability to create new shuttle areas or expand existing ones - with blueprints. - - bugfix: Special areas like rooms which require no power can no longer be expanded. - You can still expand into them however. - - bugfix: Turning to face a direction with control no longer moves you in the faced - direction after releasing control. - uraniummeltdown: - - rscadd: You can alt-click microwaves to turn them on -2018-01-30: - Cyberboss: - - bugfix: Blood contracts now only show living players and real names - DaedalusGame: - - tweak: made fire colored according to blackbody radiation and rule of cool. - - imageadd: some kind of lightning texture - Dax Dupont: - - rscadd: Cyborgs can now be upgraded to be h-u-g-e! Only a cosmetic effect! - ExcessiveUseOfCobblestone: - - bugfix: Turrets now check for borgs. Syndicate turrets are nice to emagged borgs - too! - Iamgoofball: - - bugfix: Minor code cleanup on the wirer - Jalleo: - - balance: nerfs power cells from a insane max possibility - Jittai: - - imageadd: Crematoriums and Morgue Trays now have directional states. - - bugfix: Morgue Trays now checks for cloneable people like the dna-scanner does. - (ghosts can roam now) - - bugfix: Cremated mice no longer leave behind snackable bodies. - - bugfix: Ash does not get instantly deleted in the crematorium upon creation. Ash - also piles up. (aesthetically only) - - tweak: Morgue/Crematorium Trays make a slight rolling sound. - More Robust Than You: - - tweak: Announcing messages while drunk will be slurred - Naksu: - - bugfix: Subjects without hearts now display as unsuitable for abductor experiments - when probed with the advanced baton. - - balance: BZ gas now makes lings lose their chems and hivemind access. The chem - loss is gradual. - - rscdel: 'Removed actual reagent quadrupling added in #34485' - - rscdel: Removed the foam effect combining feature, hopefully to be replaced with - something less completely and utterly broken - PKPenguin321: - - rscadd: Attention, space explorers! Nothing is out of your reach with the ACME - Extendo-Hand (TM)! With it, you can get a WHOLE EXTRA TILE OF REACH! Hug or - punch your friends from a whole 3 feet away! Win one from an arcade machine - or make one in the Misc. tab of your crafting menu today! - Robustin: - - rscadd: Blood magic. The next generation of talismans - you can create 2 spells - without a rune, up to 5 with a rune of empowerment. Preparing spells without - a rune will cost a significant amount of blood. Every talisman has been rebalanced - for its spell form. With a few exceptions, blood magic exists as a "touch" spell - that is very similar in behavior/appearance to the wizard touch spells. - - rscadd: New UI system for cultists. - - rscdel: Removed talismans, Talisman Creation Rune replaced by Rune of Empowerment. - Supply talisman has been replaced by a ritual dagger and 10 runed metal. - - rscadd: Ritual Dagger, replacing the Arcane Tome. This is largely a thematic alteration - but its to reinforce that your primary tool is also a weapon. - - bugfix: Cyborgs and AI are finally unable to see runes again - - tweak: Only the cult master can forge Bastard swords now, regular cultists can - get a mirror shield. - - rscadd: 'The mirror shield, it blocks, it reflects, it creates illusions, and - an incredible throwing weapon! The mirror shield also bears a unique weakness: - Shotgun slugs, .357 rounds, and other high damage projectiles will instantly - shatter it and briefly stun the holder.' - - balance: Nar'sien Bolas will not longer ensnare cultists and non-cultists will - ensnare themselves when attempting to use them. The bolas are now comparable - in effectiveness with reinforced bolas. - - rscadd: Rune of Spirits. This merges the Spirit Sight and Manifest Ghost rune. - The user will now choose which effect when invoking. - - rscadd: The Spirit Sight function has received several major improvements, allowing - the ghost to commune with the cult and mark objects similar how the cult master - can. The user has a unique appearance while ghosted and manifested cult ghosts - can see ghosts as well - allowing their summoner to lead them from the spirit - realm. - - balance: The Form Barrier rune will now last significantly longer and examining - the rune as a cultist will tell you how long it will remain. - - rscadd: The Apocalypse Rune. Replaces the EMP runes. Has a fixed invoker requirement - and added usage limitations. It scales depending on the crew's strength relative - to the cult. Effect includes a massive EMP, unique hallucination for non-cultists, - and if the cult is doing poorly, certain events. The rune can only occur in - the Nar-Sie ritual sites and will prevent Nar-Sie from being summoned there - in the future. - - rscdel: No more EMP rune. - - balance: The conceal/reveal spell now has 10 charges and will conceal far more, - including cult structures and flooring. - - balance: The stun spell will now stun for ~4 less seconds and silence for 2 more - seconds. - - balance: The EMP spell now costs 10 health to use, up from 5, and has had its - heavy/light EMP range nerfed by 1 and 2 respectively (now 3 and 6). - - balance: The shackles spell now has a silence effect similar to the stun talisman. - - balance: The hallucination spell now has multiple charges. - - tweak: The teleport spell can now be used on other adjacent cultists. - - tweak: Summon Tome and Summon Armor have been combined into "Summon Equipment", - which lets you choose between summoning a Ritual Dagger or Combat Gear (same - loadout that Summon Armor used to provide). - - balance: Standard cult robes now have -10 melee and -10 laser armor. - - balance: The "Construction" spell will now convert airlocks into cult airlocks - and cyborgs (after ~10 seconds) into constructs. The airlock is the most fragile - in the game, with reduced integrity, armor, and render it vulnerable to most - attacks. Cyborg "reconstruction" will be accompanied by an obvious effect/sound. - - rscadd: Blood Rites. This spell allows you to absorb blood from your surroundings - or adjacent non-cultists. You can use the blood rites as a convenient heal (self-healing - is significantly more costly though) or you can try to gather large quantities - of blood for unique and powerful relics. - - rscadd: Blood spear, a fragile but robust spear with a special recall ability - - rscadd: Blood bolts, the cultist's version of arcane barrage. The bolts will infuse - cultists with unholy water and damage anything else. - - rscadd: Blood beam, the ultimate blood rite. After a channeling period it will - fire 12 powerful beams across a long distance, piercing almost any surface (except - blessed turf), and damaging all non-cult life caught in the beam. - - tweak: All cult structures now generate significantly less light. - - balance: Pylons will now heal constructs faster and restore slightly more blood - than before. - - balance: Cult floors are now highly resistant to atmospheric changes. - - bugfix: Unholy water will now splash victims properly. - - balance: Unholy Water Vials created at altars now contains 50 units, and is better - at healing brute, and deals slightly more damage to non-cultists, the splash - ratio was reduced to 20% to compensate for the increased volume and damage. - - balance: Holy water will purge any and all blood spells from cultists. - - rscadd: Artificers, Wraiths and Juggernauts can now scribe revive, teleport, and - barrier runes respectively with a 3 minute cooldown. - - balance: Juggernauts' forcewall is now 3x1 but it has a ~30% longer cooldown. - Juggernauts got a modest speed increase (2.5 from 3) but lost a modest amount - of HP (200 from 250). - - rscadd: Juggernauts now get a ranged attack "Gauntlet Echo", a single projectile - that moves about as fast as them and does 30 damage with 5 seconds of stun and - a 35s cooldown. - - balance: The number of ghosts summonable by the manifest spirit rune is 3, down - from 5. - - balance: It now takes ~20% less water (~25 units) and ~30 seconds less to deconvert - cultists via holy water. - - tweak: The emagged library console will now distribute ritual daggers. - - tweak: Using the dagger on a rune will now take a 1-second channel to destroy - it, to avoid incidents where people instantly wipe a critical rune by accident. - - balance: Standard runed airlocks now have a lower damage deflection so they can - be destroyed with most respectable melee weapons (10+). - - balance: Teleporter runes that are used from space or lavaland will result in - the destination rune giving off a unique effect for 60 seconds. This effect - includes a long distance (but not obvious antagonistic) sound, a bright lighting - effect, and a visual cue that will indicate where the cultist arrived from. - Shadowlight213: - - tweak: Pluoxium is no longer considered dangerous for air alarms. - XDTM: - - tweak: Slimepeople can now host multiple minds in their body pool; occupied bodies - will be marked as such in the bodyswap panel. - - tweak: Slimepeople now retain 45% of their slime volume upon splitting instead - of a fixed amount. - Xhuis: - - rscadd: Defibrillator mounts can now be found in the CMO's locker or produced - from a medical protolathe after Biotech is unlocked. They can be attached to - walls, and hold defibrillators for public use. You can swipe an ID to clamp - the defibrillator in place, and it will automatically draw from the powernet - to recharge it. Being one tile away from the mount will force you to drop the - paddles. - - balance: Stargazers have been removed. - - balance: The clockwork cult now has a power cap of 50 kW. - - balance: Script scripture is now unlocked at 25 kW, and Application at 40 kW, - instead of 50 kW and 100 kW. - - tweak: Important scriptures are now displayed with italicized names. - Xhuis & Jigsaw: - - rscadd: Traitor clowns can now purchase the reverse bear trap, a disturbing head-mounted - execution device, for five telecrystals. - kevinz000: - - rscadd: Chameleon laser guns now have a special firing mode, activated by using - them in hand! Only certain gun disguises will allow this to work! - nicbn: - - bugfix: Bloodpacks will have their colors defined by the reagents - - imageadd: MMI dead sprite will now show a red light and no eyes instead of X-crossed - eyes - uraniummeltdown: - - imageadd: Solar panels have new sprites - - imageadd: Coffins have a new sprite -2018-02-01: - CosmicScientist: - - balance: tomatoes and similar ovary laden edibles are fruit, not veg, beware plasmamen - and mothmen - Denton: - - bugfix: Added a missing distress signal to the space ambush ruin. - Jalleo: - - rscdel: Space ghost syndicate comms guy removed. - Jittai: - - bugfix: Cloning doesn't runtime (and indefinitely get stuck) on cloning non-humans. - - tweak: Some of the Morgue Trays and Crematoriums on Box, Delta, and Meta have - been re-positioned to make use of their new directional states. - - imageadd: New Horizontal Coffin Sprites - SpaceManiac: - - tweak: The Whiteship spawn point is now a space ruin rather than being fixed every - round. - Xhuis: - - balance: Servant golems no longer appear in the magic mirror race list. - - bugfix: Cogs now fucking work - cebutris: - - spellcheck: The text you get when you examine a stunbaton to see the battery level - now uses the item's name instead of "baton" -2018-02-02: - Dax Dupont: - - tweak: Hijack objectives will only be given out if there are 30 or more players. - DeityLink: - - rscadd: You can now see the rays from a holopad displaying a hologram! - Epoc: - - bugfix: Soap now has inhand sprites - Xhuis: - - balance: Brass skewers now must be at least one tile apart. - - balance: Steam vents can no longer be placed within cardinal directions of other - steam vents, and will not hide objects they're placed on top of. - - bugfix: Races that have eyes that look different from regular humans' no longer - have white eyespots where human eyes appear. - Xhuis, Cosmic, Fwoosh, and epochayur: - - rscadd: Added pineapples to botany, and a recipe for Hawaiian pizza. - improvedname: - - rscadd: adds yeehaw to the dj's disco soundboard - oranges: - - rscdel: removes ketrazine -2018-02-03: - Dax Dupont: - - tweak: Moved the lathe from box's cargo room to box's cargo office which miners - now can access. - - tweak: Harmonized medbay storage access requirements so all maps allow all medbay - personnel into medbay storage like on Meta and Delta. - - tweak: Moved service lathes into a dedicated service hall/storage area if they - weren't accessible by janitor or bartender. - SpaceManiac: - - code_imp: Removed the now-unused revenant spawn landmark. - Xhuis: - - bugfix: Servant cyborgs with the Standard module now correctly have Abscond. - - bugfix: Securing pipe fittings now transfers fingerprints to the new pipe. - - bugfix: The firelock below the Circuitry Lab airlock on Boxstation will no longer - cover it up when the airlock is open. - uraniummeltdown: - - bugfix: Some airlock animations should no longer be glitchy and restart in the - middle -2018-02-04: - Buggy123: - - rscadd: Morgue trays now detect if a body inside them possesses a consciousness, - and alerts people nearby - Cruix: - - rscadd: The Rapid Piping Device can now dispense transit tubes. - Dax Dupont: - - rscadd: Added logout button to the record screen in the security records console. - - rscadd: Allows you to print photos that are in the security records. - Incoming5643: - - rscadd: The ability to throw drinks without spilling them has been moved from - something bartender's just know how to do to a book that they spawn with, the - ability has also been made into a toggle. - - rscadd: Any number of people can read the book to learn the ability, and it can - also be ordered in the bartending crate in cargo. Bartenders are encouraged - to keep their trade secrets close to their stylish black vests. - Kor: - - bugfix: Fixed mecha grav catapults not being included in techwebs. - MrDoomBringer: - - imageadd: Conveyor Belts now look better when they are crowbar'd off the ground. - - rscadd: Due to complicated quantum-bluespace-entanglement shenanigans, the Bluespace - Drop Pod upgrade for the express supply console is now slightly more difficult - to research. - Robustin: - - bugfix: Vape Pens (e-cigs) will now consume reagents proportional to the vape - size and static smoke production. - - bugfix: Command reports should now properly weight the appearance of modes based - on their existence in our actual game rotation. - - balance: The current mode now has a 35% chance of not appearing in the report. - ShiggyDiggyDo: - - rscadd: You can now win stylish steampunk watches at your local arcade machine! - ShizCalev: - - bugfix: Fixed some broken cultist & wizard antagonist ghost polls. - - rscadd: The Syndicate Comms Officer ghost role has been readded with a minor chance - of actually existing. - Slignerd: - - balance: Following an immense number of complaints filed by security and command - personnel, the Captain's spare ID will from now on be placed inside his locker. - We fail to see how this would help the Captain access the spare in the event - he lost his ID, but the complainants have been VERY insistent. - SpaceManiac: - - bugfix: The pirate ship can now fly again. - Xhuis: - - balance: Integration cog power generation has been increased to 10 W per second - (up from 5 W per second.) Power consumed from the APC remains at 5 W per second. - - balance: Integration cogs will now continue generating power at half-speed when - the APC they are in has no energy. - coiax: - - balance: Romerol is now effective on dead bodies, not just ones that are still - alive. - nicbn: - - rscadd: Destroying windows will now spawn tiny shards -2018-02-05: - Dax Dupont: - - balance: Regular cyborgs now start with a normal high capacity cell instead of - a snowflake cell. Resulting in less confusing and 2.5MJ more electric charge. - - bugfix: Fixed name of the upgraded power cell - - refactor: Removed duplicate cell giving code in transformation proc. - - bugfix: Fixed the crematorium on meta and box. - Denton: - - tweak: Rearranged the mining vendor items by price and item group. - - tweak: In order to promote back-breaking physical labor, Nanotrasen has additionally - made conscription kits available at mining equipment vendors. - Iamgoofball: - - rscdel: Blood cultists can't space base anymore - MMMiracles: - - rscadd: A once-thought abandoned arctic post has recently had its gateway coordinates - re-enabled for access via the Gateway link. Contact your local Exploration Division - for more details. - More Robust Than You: - - bugfix: Holorays are now properly deleted if you switch holopads automatically - Naksu and kevinz000: - - tweak: Ores are no longer completely impervious to explosions, but rather "proper" - ores are destroyed by the strongest explosions and sand is blown away everything - but the weakest ones. This shouldn't affect ore spawns from explosions - - tweak: Lavaland bomb cap reduced to double the station bombcap. - - refactor: Ores are now stackable. Ore stacks now have the appearance of loose - ores and are not called "sheets" by machines that consume them. - - code_imp: Material container component now uses the singular names of stack objects. - - refactor: /obj/item/ore/Crossed() is now removed in favor of the ore satchel utilizing - a redirect component - ShiggyDiggyDo: - - spellcheck: You no longer win double the articles at the arcade - SpaceManiac: - - bugfix: Research investigate logs now actually include the name of the researcher. - XDTM: - - bugfix: Fixes intelligence potions removing previously known mob languages - - tweak: Slime scanning now has a more readable output, especially when scanning - multiple slimes at once - - tweak: Eggs from the abductor egg gland now have a random reagent instead of acid -2018-02-06: - Dax Dupont: - - bugfix: AIs can no longer turn on broken APCs, - SpaceManiac: - - bugfix: Defibrillator mounts no longer spam the error log while empty. - - bugfix: The various ships in the caravan ambush space ruin can now fly again. -2018-02-07: - DaedalusGame: - - bugfix: Fixes Noblium Formation being multiplicative, so having 500 moles of tritium - and 500 moles of nitrogen no longer produces 2500 moles of noblium (it should - correctly produce 10 moles) - - bugfix: Fixes most reactions deleting more gas than exists and making gas out - of nowhere - - bugfix: Fixes Stim Formation invoking a byond bug and not using its intended polynomial - formula - - bugfix: Fixes Cryo Cells not having garbage_collect and clamping - - bugfix: Fixes Rad Collectors not having clamping - - bugfix: Fixes Division by Zero when Fusion has no impurities. - - bugfix: Removes a redundant line in lungs - - bugfix: Fixes rad_act signal not firing from turfs, living mobs, rad collectors - and geiger counters - - bugfix: fixes lava burning into chasm tiles i hate hate hate hate them so much - grrrr - - tweak: NT Scientists have started looking into data from small-scale detonations - and found that there's still potential data to be gathered from explosive yields - lower than 4.184 petajoules - Dax Dupont: - - tweak: Moved the pocket protector to lockers instead of on the uniform. - - rscadd: You can now insert holodisks into cameras and take a static holographic - picture of someone! - - rscadd: Hologram recordings can now be offset slightly. - - rscadd: Posibrains have gotten a small firmware update, they will now play a sound - on successful activation. - - rscadd: Killing a revenant will now result in an unique shuttle to be able to - be bought. You probably won't like it though. - - rscadd: Fake emag now available. - Denton: - - spellcheck: Mining drone upgrades are no longer referred to as "ugprade" - - tweak: Fungal tuberculosis spores can no longer be synthesized by machinery. - Kor: - - rscadd: Spawning as a syndicate comms officer will now activate an encrypted signal - in the Lavaland Syndicate Base, to aid the crew in retaliating. - Ordo: - - rscadd: Mamma-mia! The chef speaks-a so different now! - Robustin: - - balance: The "construct shell" option from the cult archives structure will now - only yield one shell instead of two. - - balance: Sacrificing suicide victims will now only yield an empty shard. - - balance: Synths and Androids are no longer available species at the magic mirror. - ShiggyDiggyDo: - - rscadd: You can now win Toy Daggers at your local arcade! - Skylar Lineman: - - rscadd: Nanotrasen has new intelligence that the newest batch of Syndicate agent - equipment includes sticky explosives disguised as potatoes, designed to incite - terror among whoever is unlucky enough to have one stuck onto their hands. - - rscadd: 'Nanotrasen''s toy suppliers have also started making faux versions of - these, with less-forceful attachment mechanisms and absolutely zero explosive - materials for a child-safe experience. experimental: Explosive Hot Potatoes - are now available for purchase by syndicate-affiliated cooks, botanists, clowns, - and mimes.' - SpaceManiac: - - bugfix: Pressure damage now takes effect in certain situations where it should - have but did not. - Xhuis: - - rscadd: Nanotrasen's anomalous materials division has recently experienced a containment - breach, during which a certain pizza box went missing. Be on the lookout for - any slipups in cargo. - - spellcheck: Pizza margherita is now named "pizza margherita" (the proper way!) - instead of just "margherita." - - tweak: Brass chairs now stop spinning after eight rotations, so you can't crash - the server with them. - coiax: - - rscadd: Eggs now contain 5u of egg yolk. Breaking an egg in a glass container - adds all reagents inside to the container. If you're laying abductor gland eggs, - then you'll get 5u of egg yolk and 10u of random reagent. Egg glands now make - you act like a chicken while laying eggs. Egg laying makes you use the aliennotice - span. - kevinz000: - - balance: Explosive holoparasites must now be adjacent to turn objects into bombs, - instead of being able to do so from any range. -2018-02-09: - Cyberboss: - - balance: Printed power cells must now be charged before use - Dax Dupont: - - bugfix: Supermatter can again blow up again on space tiles. - - bugfix: Fixed borgs applying cuffs on people without the right number of arms. - - refactor: Handcuff code has been rejiggled and snowflake code has been removed. - - rscdel: Removed unused cable cuffs module stuff for borgs. - - bugfix: Telecom equipment now can only be printed by engineers and scientists - as intended. - - bugfix: WT-550 AP can only be printed by sec now. - - tweak: Removed engineering requirement for arcade machines to bring it in line - with others. - - rscadd: Defibs can now be researched and printed. - - balance: Hatches are now small instead of tiny. - Denton: - - code_imp: Changed can_synth values from 0/1 to FALSE/TRUE - - code_imp: Removes grind_results from empty soda cans since they can't be ground. - - spellcheck: For consistency's sake, aluminium is now universally spelled with - two 'i'. - Epoc: - - imageadd: Belt items now have inhand sprites - Evsey9: - - balance: Integrated Circuit Drones are now bulky to improve safety ratings, and - therefore, cannot be stored in normal backpacks or pockets, but now can accept - modules that bulky circuit machinery can. - - balance: Grabbers can now grab items up to the size of the circuit assembly they - are in. - - balance: Grabbers cannot store circuit machinery the same or larger size than - the circuit assembly they are in. - - tweak: Throwers now can throw items up to the size of circuit assembly they are - in. - MMMiracles: - - rscadd: A brand new space-farm, where your family sends all your old/sick catpeople - to live out the rest of their days being free to roam the acres and chase the - field grayshirts. - Naksu: - - bugfix: Cyborg engineering module geiger counters now work properly again - PKPenguin321: - - rscadd: As it would happen, the chef does not actually have Italian genes, but - rather was being influenced by a strange moustache-a. - Robustin: - - bugfix: Fixes the cult master getting two notifications on the cult forge - - rscadd: Blood spells will now "follow" the spell creation button, which is now - unlocked by default. If you want your spell "hotbar" to appear somewhere else, - just move the blood spell button, it will update when you prepare a new spell. - Also, individual spells start off locked but if you unlock them they will no - longer reposition when the spells are updated. - Robustin and More Robust Than You: - - rscadd: A heart disease event has been added. The cure is heart replacement surgery. - Effects of cardiac arrest are halted by the chemical Corazone. Once cardiac - arrest begins at Stage 5, the disease can be cured by a defibrillator or from - a lucky electric shock. - - rscadd: Using gym equipment will now grant a hidden exercise buff that prevents - heart disease for 20 minutes. - SpaceManiac: - - bugfix: Goliath hide plates now properly apply to explorer suits and APLUs again. - oranges: - - rscdel: Removed the saltmine grief shuttle -2018-02-10: - Cruix: - - balance: Changed the chemical recipe for Lexorin from plasma, hydrogen, and nitrogen - to plasma, hydrogen, and oxygen. - - bugfix: These were necessary due to recipe conflicts - Dax Dupont: - - bugfix: Cloner UI now properly updates cloning pod status when autocloning starts - cloning someone. - Ordo: - - tweak: Replaced nitrogen with ethanol in morphine recipe. The recipe now has a - lower yield. - Robustin: - - bugfix: Fixed the limb grower having a max volume of 0. - UI Changes: - - tweak: The Scan with Debugger/Device button now reads Copy Ref and no longer sends - you to the circuit's page when clicked - - tweak: The assembly's menu is now slightly wider - - tweak: The advanced in "integrated advanced medical analyser" is now abbreviated - to adv. - Xhuis: - - bugfix: The preference to lock action buttons in place is now correctly saved - across rounds. -2018-02-11: - DaedalusGame: - - bugfix: Prevents megafauna (and other large things like spiders and mulebots) - from going into machines - Dax Dupont: - - rscadd: You can now win a fake cryptographic sequencer, perfect to go with your - fake space suit! - - tweak: 'To login with an emag on the APC console you will now need to hit it with - the emag. removed: Snowflake emagging implants is no more, Swipe it before install.' - - refactor: everything uses emag_act() now - - balance: Grabbers/throwers no longer can contain/throw things equal to the assembly - size. - - bugfix: Fixes duplicate air alarm on meta. - Kor: - - rscadd: Mining sentience upgrades now grant minebots an ID and radio. - Mokiros: - - rscadd: All-In-One Grinder can now be built with researchable curcuit and micro-manipulator. - More Robust Than You: - - rscadd: You can now squish urinal cakes - More Robust Than You, Basilman, and MMMiracles: - - rscadd: Deep in space, a valuable artifact awaits - Naksu: - - rscdel: Steam engines have been removed from maintenance, engineering, atmos and - teleportation areas. - - rscadd: The chef is now trained for working under siege - Shadowlight213: - - admin: The notify irc/discord bot chat command no longer requires admin privileges. - ShizCalev: - - bugfix: Corrected a number of missing checks when using alt-click actions. Please - report any strange behavior to a coder. - - spellcheck: Corrected typo in NTNet Scanner circuits' name, make sure to update - your blueprints. - uraniummeltdown: - - rscadd: You can now smelt titanium glass and plastitanium glass - - rscadd: Use titanium glass and plastitanium glass to build shuttle windows and - plastitanium windows -2018-02-12: - Dax Dupont: - - bugfix: AI no longers block ark after mass_recall - - bugfix: Placed the dispersal logic AFTER the mass_recall on ark activation instead - of infront(did nothing before basically). - - rscadd: Cell chargers can now be built and upgraded with capacitors! - - bugfix: Fixed empty subtype batteries not updating icons - Denton: - - bugfix: Fixes lye/plastic/charcoal conflicts when mixing. - - bugfix: Lye is now made by combining ash with water and carbon. Plastic sheets - by heating ash, sulphuric acid and oil. - More Robust Than You: - - bugfix: Your hand no longer magically squishes urinal cakes when trying to pick - them up - - bugfix: SCP-294 no longer looks fucked up - Robustin: - - balance: The rift created by teleporting in from space will now include a description - indicating the direction of the "origin" teleport rune - giving the examiner - a fair idea of where the "space base" is located. - - balance: You can no longer manifest spirits or summon cultists while in space - or Lavaland. You may still ascend as a spirit (formerly spirit sight, astral - jaunt, etc.) in either of these locations. - - balance: Juggernauts have lost 20% reflect rate on energy projectiles (now around - 50% for standard lasers). - - balance: Wraiths and Juggernauts have -5 melee damage (20 and 25 now, respectively). - - balance: Construct shells now cost 50 metal through the "twisted construction" - spell. Twisted construction is now a "single use" spell. - - balance: The Concealment spell will now work on cult airlocks (including converted - airlocks). The "concealed" airlock will appear as a generic airlock but will - deny access to any non-cultist. - - balance: The draw blood effect on blood splatters will now draw more blood from - stains with low blood levels. - - tweak: Unanchored (via ritual dagger) cult structures are no longer "dense", meaning - you can move them through teleport runes more efficiently. - - tweak: The button to nominate yourself for cult master now has a confirmation - prompt seeking assurance that the user is prepared to be the cult's master. - - tweak: The reveal aspect of the concealment spell is slightly smaller, albeit - still slightly larger (6 range) than the concealment aspect (5 range). - - imageadd: Juggernauts "gauntlet echo" now has a more cult-themed appearance. - - bugfix: Using a shuttle curse to push the shuttle timer above its default can - no longer be "reset" with a recall. This also adds a block_recall(time_in_deciseconds) - helper-proc to the shuttle subsystem. - - bugfix: Using runed metal on a regular girder is no longer an option, preventing - runtimes and deletions associated with the (unintended) combination. -2018-02-13: - Buggy123: - - tweak: After consulting with their in-house physicists, Nanotrasen has updated - their worst-case disaster training simulation "Space Station 13". The combustion - of hydrogen isotopes now produces water vapor instead of carbon dioxide. - Dax Dupont: - - rscadd: Added hooray emoji! - Iamgoofball: - - bugfix: The Cook now ONLY works under siege. - TehZombehz: - - rscadd: Heart-shaped boxes of chocolates are now included in Valentine's Day event - gifts -2018-02-14: - Dax Dupont: - - bugfix: Integrated circuits no longer start upgraded. - - balance: The IC printers that are available on round start in the IC labs are - no longer upgraded by default. You will need to research these as was intended - Frozenguy5: - - bugfix: You can craft rat kebabs now. - Naksu: - - bugfix: Chasms no longer eat shuttle docking ports, rendering them unusable and - unresponsive - - tweak: The clogged vents event has been removed for pressing ceremonial reasons - coiax: - - rscadd: Transference potions now just rename the mob that you are transferring - into with your name, rather than your name plus the old name of the mob. -2018-02-15: - Kor: - - rscadd: Bluespace slime extracts now have a new chemical reaction with water, - which create slime radio potions. When applied to a simple animal, that mob - gains an internal radio. - MrStonedOne: - - balance: You no longer need an aggressive grab to table someone. - SpaceManiac: - - refactor: Map initialization now supports stations with multiple z-levels. - - bugfix: The map reader no longer sometimes expands the world size inappropriately. - - tweak: Pride's Mirror's destination has become less predictable. -2018-02-16: - AnturK: - - rscdel: Minimap gone from crew monitoring - DaedalusGame: - - code_imp: made powercell rigging no longer set rigged to the plasma reagent datum - what the hell and makes it use TRUE/FALSE defines - Denton: - - tweak: Emagging meteor shield satellites now shows you a message. - - spellcheck: Fixed a typo when emagging RnD servers. - MMMiracles: - - rscadd: You can now produce a cryostatis variant of the shotgun dart after researching - Medical Weaponry. Holds 10u and doesn't have reagents react inside it. - MetroidLover: - - rscadd: Added the ability to gain smoke bomb charges by attacking the initiated - ninja suit with a beaker containing smoke powder - More Robust Than You: - - bugfix: Fixes SCP-294 losing its top sometimes - Naksu: - - code_imp: replaced some item-specific movement hooks with components - Xhuis: - - tweak: Removing and printing integrated circuits will now attempt to place them - into a free hand. - - tweak: You can now hit an integrated circuit printer with an unsecured electronic - assembly to recycle all of the parts in the assembly en masse. - - tweak: You can now recycle empty electronic assemblies in an integrated circuit - printer! - - soundadd: Integrated circuit printers now have sounds for printing circuits and - assemblies. - - bugfix: The RPG loot event will no longer break circuit analyzers. - coiax: - - rscadd: Centcom now reports that thanks to extensive bioengineering, apples and - oranges now taste of apples and oranges, rather than nothing as they did before. -2018-02-17: - DaedalusGame: - - bugfix: fixes lava and fire burning HE-pipes - - rscadd: added a subreaction for rainbow slime cores, injecting 5u of plasma now - makes them explode into random slimecores. - - rscadd: added a slimejelly reaction to rainbow slime cores that does the above - but all the cores that spawn get 5u each of plasma, water and blood injected. - (aka chaos) - - code_imp: improved clusterbuster code with Initialize, addtimer, vars for sounds - and payload spawners, etc - Dax Dupont: - - bugfix: After an incident where a very eager roboticist kept expanding a borg's - size leading to a structural collapse of the entire station proper safety limitations - have been implemented. - - bugfix: You can rotate freezers and cryo again. - - rscadd: Nanotrasen has invested in better reflective materials for it's reflectors. - You can now make complex laser shows again. - Modafinil: - - rscadd: Adds new medicine chem that suppresses sleep and very lightly reduces - stunrates, has a very low metabolic rate which is randomized and a low overdose - treshold. Overdosing is a lethal oxyloss unless treated. (With epipen urgently - and with charcoal/calomel before it puts you to sleep) - TankNut: - - tweak: Corpses spawned in ruins have their suit sensors disabled - coiax: - - admin: Admins can use the Select Equipment verb on observers. Doing so will humanise - them and then apply the equipment. - - bugfix: Species with RESISTHOT (golems, skeletons) can extinguish burning items - as if they were wearing fireproof gloves. - jakeramsay007: - - bugfix: Jellypeople/Slimepeople now are able to speak their Slime language, as - intended when it was added. - yorii: - - bugfix: removes the maintenance panel examination message on poddoors (blast doors) -2018-02-18: - More Robust Than You: - - bugfix: Actually fixes SCP 294 overlay problems - Naksu: - - rscadd: Exosuit fabricators can now build RPED and crew pinpointer upgrades for - engineering and medical borgs respectively. - Ordo: - - rscadd: Adds a few new liquors to the bar, and a few new cocktails to boot! - Xhuis: - - tweak: Crew pinpointers now fit on medical belts! - YPOQ: - - bugfix: Bicycles are rideable again -2018-02-19: - DaedalusGame: - - bugfix: Fixed paper bins not catching fire properly - - bugfix: fixed multiserver mining formula - Improvedname: - - bugfix: Fried eggs don't require boiled eggs anymore and just normal eggs - Kevinz000 and Naksu: - - bugfix: Ore stacks will now initialize with proper visuals and no longer show - a NO SPRITE text when you gather more than 20 ores to a stack. - XDTM: - - rscadd: 'Added three new techweb nodes: Advanced Surgery, Experimental Surgery, - and Alien Surgery(requires abductor tech)' - - rscadd: Added several new surgical procedures, which require these techweb nodes. - To enable an advanced surgery, print its relative disk from a protolathe, and - load it on an Operating Computer. Advanced surgery can only be performed at - operating tables. - - tweak: You can now intentionally fail surgical procedures by initiating them with - disarm intent instead of help intent. - - rscadd: Brain traumas now have a custom resilience system. Some trauma sources - can cause traumas which require more extensive treatment, such as the new Lobotomy - surgery. - - rscadd: Traitors can now purchase a Brainwashing Surgery Disk for 5 TC. - Xhuis: - - bugfix: New blob tiles are no longer invincible after their blob's death. - - bugfix: Blob nodes no longer produce blob tiles even after the blob's death. - coiax: - - rscadd: Mime's Bane, a toxin that prevents people from emoting while it's in their - system, can now be created by mixing 1 part Mute Toxin, 1 part Nothing and 1 - part Radium. -2018-02-20: - Anonmare: - - rscadd: Nanotrasen psychologists have identified new phobias emerging amongst - the workforce. Nanotrasen's surgeon general advises all personnel to just buck - up and deal with it. - AverageJoe82: - - rscadd: Circuits integrity, charge, and overall circuit composition is displayed - on diagnostic huds. If the assembly has dangerous circuits then the status icon - will display exclamation points, if the assembly can communicate with something - far away a wifi icon will appear next to the status icon, and if the circuit - can not operate the status icon will display an 'X'. - - rscadd: AR interface circuit which can modify the status icon if it is not displaying - the exclamation points or the 'X'. - - tweak: Locomotive circuits can no longer be added to assemblies that can't use - them. - - spellcheck: Fixed a typo in the grenade primer description. - - code_imp: Added flags to circuits that help group subsets of circuits and regulate - them. - DaedalusGame: - - bugfix: fixed ghost spawners showing up in the spawner menu when you can't use - them - - bugfix: fixed walls under doors breaking to space - - tweak: changed doors to no longer spawn on top of walls - Dax Dupont: - - rscadd: Adds special tutorial holopads for the hazard course. - Jittai: - - tweak: Ctrl+Clicking progresses through grab cycle on living mobs (not just humans) - Joan: - - tweak: The crusher kit now includes an advanced mining scanner. - - tweak: The resonator kit now includes webbing and a small extinguisher. - - tweak: 'The minebot kit now includes a minebot passthrough kinetic accelerator - module, which will cause kinetic accelerator shots to pass through minebots. - The welding goggles have been replaced with a welding helmet, allowing you to - wear mesons and still be able to repair the minebot without eye damage. feature: - You can now install kinetic accelerator modkits on minebots. Some exceptions - may apply. Crowbar to remove modkits.' - - balance: Minebots now shoot 33% faster by default(3 seconds to 2). The minebot - cooldown upgrade still produces a fire rate of 1 second. - - balance: Minebots are now slightly less likely to sit in melee like idiots, and - are now healed for 15 instead of 10 when welded. - - balance: Sentient minebots are penalized; they cannot have armor and melee upgrades - installed, and making them sentient will override those upgrades if they were - installed. In addition, they move very slightly slower and have their kinetic - accelerator's cooldown increased by 1 second. - NTnet circuit fix: - - bugfix: Now NTnet circuits can recieve sender adress properly.Also, now messages - could be sended to multiple recepiens. - Xhuis: - - rscadd: Admins may now spawn a debug circuit printer that can always print circuits, - and has infinite metal. - - bugfix: Buttons, number pads, and text pads in integrated circuits now correctly - show their labels. - - bugfix: Integrated hypo-injectors can now correctly draw blood. - - tweak: The circuit analyzer output has been slightly tweaked and includes usage - instructions. - - rscadd: The round-end report now shows information about the first person to die - in that round. - - rscadd: Added the dish drive. This machine, the future in plate disposal, can - be researched from techwebs (Biological Processing) and built with a standard - machine frame using two matter bins, a micro manipulator, and a glass sheet. - - rscadd: A circuit board for the dish drive can be found in the chef's and bartender's - wardrobes. - - rscadd: You can hit a dish drive with any dish (like a plate or drinking glass), - and the dish drive will convert it from matter to energy, allowing it to store - an infinite amount of dishes. You can also interact with it to get things back - from it. - - rscadd: Dish drives also have an automatic "suction" function that sucks in all - loose dishes within four tiles. This can be toggled by activating its circuit - board in-hand. - - rscadd: Dish drives automatically beam their stored dishes into any disposal unit - that it can see within seven tiles every minute. You can toggle this by alt-clicking - its circuit board. - - tweak: Plastic surgery now lets you choose from a list of ten random names, so - you can pick the one that you prefer. - - tweak: Abductors performing plastic surgery can now give their target spooky subject - names, with one normal name available for standard plastique. -2018-02-21: - Denton: - - code_imp: Renamed the IDs of various reagents to be more descriptive. - - spellcheck: Fixed the descriptions of changeling adrenaling reagents. - - tweak: Changed Santa event earliest start from 33 minutes & 20 seconds to 30 minutes. - Changed shuttle loan earliest start from 6 minutes & 40 seconds to 7 minutes. - - spellcheck: Tweaked the message you see when emagging meteor shield satellites. - Kevinz000 & Deathride58: - - rscadd: A separate round time has been added to status panel. This will start - at 00:00:00. - - rscadd: Night shift lighting [if enabled in the same configuration] will activate - between station time 7:30 PM and 7:30 AM. This will dim all lights affected, - but they will still have the same range. - - rscadd: APCs now have an option to set night lighting mode on or off, regardless - of time. - Naksu: - - bugfix: Flightsuits should be controllable again -2018-02-22: - Buggy123: - - tweak: Nanotrasen has begun a campaign to inform their employees that you can - alt-click to disable morgue tray beeping. - Jittai / ChuckTheSheep: - - imageadd: NT has stopped buying re-boxed storebrand Donkpockets and now stocks - stations with real, genuine, tasty Donkpockets! - MetroidLover: - - balance: rebalanced Ninja event to allow it to happen earlier. - - bugfix: fixed Ninja welcome text to no longer tell you to right click your suit. - Naksu: - - code_imp: removed unused poisoned apple variant - Repukan: - - bugfix: fixed windoors dropping more cable than what was used to build them. - Robustin: - - bugfix: The clock cult's marauder limit now works properly, temporarily lower - the marauder limit when one has recently been summoned. - Super3222, TheMythicGhost, DaedalusGame: - - rscadd: Adds a barometer function to the standard atmos analyzer. - - imageadd: Adds a new sprite for the atmos analyzer to resemble a barometer. - kevinz000, Denton: - - rscadd: Nanotrasen's RnD division has integrated all stationary tachyon doppler - arrays into the techweb system. Record increasingly large explosions with them - and you will generate research points! - - spellcheck: Fixed a few typos in the RnD doppler array name/description. -2018-02-25: - Astral: - - rscadd: Traitor CMOs and Chemists, for 12 TC, can now get a reagent dartgun, which - is capable of synthesizing it's own syringes, but does so slowly, and can be - easily identified as syndicate by anyone who isn't blind! - Cebutris: - - tweak: Toxin loving species now properly take toxin damage from liver failiure - DaedalusGame: - - bugfix: enables the RPED to construct/replace other parts commonly used in machines - (igniters, beakers, bs crystals) - - bugfix: fixes part ratings of cells so slime cells are correctly more desirable - than bluespace cells and other such nonsense - - bugfix: shivering symptom now works properly instead of only cooling you if you're - already cold - - bugfix: fixed bodytemp going negative in a few cases - - code_imp: removes input/output plates and changes autogibbers to use input dir - - tweak: The last scientists have reported that thermonuclear blasts triggered by - so called 'power gamers' have shorted the doppler array. We've readjusted the - ALU and are confident that this will not happen again. - Denton: - - tweak: The outer airlocks of most space ruin airlocks are now cycle linked. - - tweak: The outer airlocks of various lavaland ruins and ships now cycle lock. - - bugfix: Players can no longer kill themselves by whispering inside clone pods. - - tweak: The 'neurotoxin2' toxin has been renamed to Fentanyl. - Naksu: - - admin: Admins can now start the game as extended revs, a version of revs that - doesn't end when head(rev)s are dead. Admins can also use the speedy mode, which - nukes the station after 20 minutes. - Repukan: - - rscadd: Whiskey to the flask - - rscdel: Hearty Punch from the flask - ShizCalev: - - tweak: Silicons no longer have to be adjacent to morguetrays to disable the alarms - on then. - ThePainkiller: - - tweak: Tweaked the inventory management of the black fedora to be more like the - detective's - Xhuis: - - rscadd: Added Bastion Bourbon, which you can mix with tea, creme de menthe, triple - citrus, and berry juice. When it's in your system, it will very slowly heal - you as long as you're not in critical. When it's first added to your system, - you heal an amount of each damage type equal to the volume taken in, with a - max of 10. This is turned to a max of 20 for anyone in critical. - - rscadd: Added Squirt Cider, which you can mix with water, tomato juice, and nutriment. - It's nutritious and healthy! - - tweak: Reskinning objects now shows their possible appearances in the chat box. - deathride58: - - rscadd: Lights will now actually glow in the dark! -2018-02-26: - DaedalusGame: - - balance: livers don't unfail automatically every second life cycle you have to - get a new one or get some corazone stat - - balance: increased liver damage from alcohol significantly because apparently - your liver regenerates faster than you can chug unless you drink 100 liters - of bacchus blessing - - bugfix: fixed cyber livers thinking they should fail at half durability - MMMiracles: - - rscadd: Added tinfoil hats, headgear that can help protect against government - conspiracies and extra-terrestrials. Found in hacked autolathes. - Robustin: - - bugfix: Twisted Construction will now consume ALL available plasteel in a stack. - - bugfix: Runes will no longer count the original invoker more than once. - XDTM: - - balance: Wizard spells and items can now be resisted/ignored with anti-magic items/clothing - such as null rods! - - balance: Revenant spells can now be resisted with "holy" items like null rods - and bibles. - - balance: Wizard hardsuits are now magic immune, but not holy. - - balance: Immortality Talismans now grant both spell and holy immunity. - - tweak: Inquisitor Hardsuits already granted spell and holy immunity, but now they - do it properly instead of having a null rod embedded inside. - - tweak: Holy Melons now grant holy immunity. - - tweak: Operating computers now display the chemicals required to complete a surgery - step, if there are any. - - tweak: Completing a surgery without the required chems will always result in failure, - instead of a success with no effect. - - balance: You can no longer gain the same trauma more than once. - - balance: 'You can no longer gain more than a certain amount of brain traumas per - resilience tier. (Example: You cannot gain 4 mild traumas, but you can gain - 3 mild and 1 severe)' - - tweak: Abductors' trauma gland now gives traumas of random resilience, instead - of lobotomy every time. - Xhuis: - - balance: Instead of starting unable to clone circuits at all, circuit printers - can now print circuits over time from roundstart. The formula for this is equal - to (metal cost / 150) seconds, with a maximum of 3 minutes. You can see printing - progress by using the printer's interface, and you can print normal components - during this time. - - balance: If circuit printing is disabled in the config, cloning remains unavailable. - - balance: The upgrade disk to allow circuit printers to clone circuits has been - replaced with an upgrade disk to make circuit cloning instant. - - balance: Both circuit printer upgrade disks now cost 5000 metal and glass, down - from 10000. - - code_imp: Butchering has been refactored. - - balance: Some items now take longer to butcher, and have a chance to harvest fewer - items, like spears. Others, however, are faster, like circular saws. - - balance: Certain creatures will always drop certain items on butchering, regardless - of butchering effectiveness or chances. - - balance: Items that are very effective at butchering may yield bonus loot from - butchered creatures! - - rscadd: Plain hamburgers may now spawn as steamed hams with a very low chance. -2018-02-27: - Astral: - - rscadd: blood cultists can now use a nar nar plushie as an extra invoker for runes! - Iamgoofball: - - rscadd: Look sir, free crabs! - Poojawa: - - rscadd: Tesla Corona Analyzers! Study the seemingly magic Edison's Bane for supplemental - research points! - Robustin: - - bugfix: The heart attack event will now actually make the victim acquire the heart - disease - - bugfix: Clicking the chatbox link will let you orbit the victim - - tweak: The event is now significantly more sensitive to junk food. Recent consumption - of multiple junk food items will triple your chances of having a heart attack - (exercise will still block it). - selea: - - bugfix: fixed floorbot - - bugfix: fixed cleanbot - - refactor: improved pathiding in case of given minimal distance;improved sanitation -2018-03-02: - AlexTheSysop: - - bugfix: C4 logging now shows correct location - Astral: - - imageadd: Space is now prettier - DaedalusGame: - - tweak: Machines can now be constructed anchored or unanchored, if the resultant - machine could be unanchored. - Dax Dupont: - - rscadd: Medals now show the commendation text in the description. - Denton: - - tweak: Cargo packs have been grouped and sorted alphabetically. Station goal crates - are now in the Engineering section. - - tweak: The cargo security section has been split into security/armory. - - tweak: Grouped all gas canisters and fuel/water tanks together in one section - with raw materials. - - spellcheck: Fixed a few cargo pack descriptions. - - tweak: Cyclelinked three airlock pairs on Boxstation (port bow solars and the - area that connects RnD with medical). - Improvedname: - - bugfix: chem implants can no longer be self triggered - Jittai / ChuckTheSheep: - - imageadd: New chemdispenser (and minidispenser) sprites. - - imageadd: New soda/beer dispenser sprites, with directional states. - Mey-Ha-Zah: - - imageadd: Heck suit sprites are prettier, with more contrast. - MoreRobustThanYou: - - bugfix: SCP-294 should no longer have overlay problems - Naksu: - - rscdel: SNPCs have been removed. - Poojawa: - - bugfix: Cyborg defib units are now actually functional - XDTM: - - tweak: Bath Salts now induce psychotic rage, but cause much more brain damage. - Xhuis: - - rscadd: Traits! You can now select up to three positive, negative, and neutral - traits in the character setup. You can choose up to six traits based on combinations - varying by the amount of points you earn with negative traits and spend with - positive ones. - - rscadd: You can now splash metal sheets with copper to make bronze sheets, which - you can make "clockwork" things out of. - YPOQ: - - bugfix: The assault pod can be launched again. - uraniummeltdown: - - rscadd: The chatbar now has OOC and Me buttons - - tweak: The chatbar font-size is smaller -2018-03-03: - Cebutris: - - bugfix: Washing a glove with a white crayon will make it look like a white glove, - instead of a latex glove. Instead, mime crayons make gloves look latex - Denton: - - bugfix: Burglar alarms in the Pubbystation library and RD office can now be disabled - properly. - - bugfix: Fixed Pubbystation's RD office shutters. - - rscadd: Added missing engineering and kitchen lockdown shutters on Pubbystation. - - rscadd: 'Pubbystation: Added privacy shutters to the CMO and RD offices. Added - space shutters to the HoS office. Replaced the RD office''s directional windows - with fulltile ones.' - - rscadd: Added a second blast door to the Pubbystation gulag shuttle lockdown. - - tweak: Due to pressure from the space OSHA, Pubbystation has installed missing - fire alarms and firelocks. - - tweak: Split the Pubbystation library into two areas with their own APCs. - Naksu: - - admin: Admins can now easily spawn cargo crates - - admin: Admins can now toggle antag, med, sci, engineering huds and maximum ghost - brightness with just one button. - Robustin: - - balance: Meth now deals 1-4 brain damage while active, up from 0.25 - Selea: - - balance: reduce CD of all non manipulative non list output circuits to 0.1 - - balance: add to locomotion circuit output ref with object, which assembly was - bumped to. - - balance: upgrade disks have multiuse. balance:iducer efficiency= efficiency/number - of inducers on 1 tile. - - balance: unnerf fuel cell.about 3-5 times.Make blood more powerful. - ShizCalev: - - rscadd: You can now hotswap tanks in a canister or gas pump by clicking it with - a new tank! - - rscadd: You can now also close a canister's valve and remove the tank inside it - by alt-clicking it. -2018-03-04: - DaedalusGame: - - balance: changed the formula of liver damage so weak alcohol does barely anything - while strong alcohol is still threatening - Iamgoofball: - - bugfix: RIP Billy, you'll be the boss of heaven's gym now :( - Jalleo: - - admin: Added a cancel button to nuke timer (and others). You no longer have to - make it 0 just a click to cancel. - - admin: You can now easily set how many "INSERT JOB ROLE HERE" you want in the - manage job selection in the admin panel. If you put zero in it will set it to - the current amount of filled positions. - - bugfix: moved a small amount of wording around in a admin browser to make it cleaner - looking. Along with a few updated checks for certain things. - Naksu: - - code_imp: First pass on cleaning up junk defines and unused code - RandomMarine: - - rscdel: The ore redemption machine no longer has 'release all' buttons. Remember - to take just what you need and leave some for the other departments. -2018-03-05: - 81Denton: - - tweak: 'Deltastation: Removed a windoor to make the northern chemistry fridge - more accessible.' - Cruix: - - rscadd: Added a new mini antagonist, the sentient disease. - DaedalusGame: - - bugfix: Fixes the auxbase camera console not placing airlocks on fans but doing - so vice-versa - Dax Dupont: - - balance: Others can now take off your tinfoil hat as seemingly originally intended. - - balance: Due to the nature of tinfoil hats, the delay of putting a tinfoil hat - on unwilling participants has been increased. - Denton: - - bugfix: 'Pubbystation: Added a missing APC to the cargo sorting room, a light - fixture to the RnD security checkpoint and removed an overlooked firelock east - of the bridge.' - - rscadd: 'Pubbystation: Added a spare RPD to the Atmospherics department. Replaced - Engineering''s outdated meson goggles with modern engineering scanners. Added - a GPS device to the secure storage crate.' - - tweak: Moved Pubbystation's drone shell dispenser from the experimentation lab - to Robotics maint. - Jittai / ChuckTheSheep: - - tweak: Adjusted the space parallax's contrast to be less vibrant. - Naksu: - - rscadd: Advanced roasting sticks, a product of applied bluespace research can - now be built from service protolathes. They can be used to cook sausages on - campfires, supermatter engines, tesla balls, singularities and a couple of other - things. - - admin: Admins can now grant spells via implants, using the spell implant. Some - VV is required. - Potato Masher: - - bugfix: The Wizard Federation has finally modified their production method for - pre-packaged magic tarot cards for better compatibility with time-stopping spells. - Guardians Spirits are no longer frozen by their user's time-stops. - SpaceManiac: - - bugfix: Night shift no longer ignores rooms whose APCs are in port or starboard - central maintenance. - - bugfix: Inserting brains into MMIs and then into mechs now works again. -2018-03-06: - MrDoomBringer: - - tweak: Advances in Rapid Delivery Technology have yielded a reduced premium on - express cargo orders! Orders from the express console now have a cost multiplier - of 1, down from 2. - MrStonedOne: - - bugfix: gas overlays once again no longer steal clicks - - rscdel: 511 clients will be unable to see gases once again. the 512 client crashes - are fixed so this shouldn't be that big of a deal. - Naksu: - - admin: Admins can now easily spawn mobs that look like objects. Googly eyes optional! - XDTM: - - rscadd: Revenants now have randomly generated names. - Xhuis: - - code_imp: Traits are now assigned in a way that should cause fewer edge cases - and strangeness. - - bugfix: Night Vision should now work. - - bugfix: Traits no longer tick while dead. - - tweak: RDS now triggers twice as often. - - tweak: You can now modify your trait setup mid-round. Your character is locked - to the traits you had selected when you spawned in, though. - selea: - - bugfix: After several months of natural selection, hostile mobs started to attack - assemblies with combat circuits. -2018-03-08: - ACCount: - - rscadd: Station airlocks now support NTNet remote control. Door remotes now use - NTNet. - - rscadd: Don't worry, any non-public airlock is fully protected from unauthorized - control attempts by NTNet PassKey system! - - rscadd: 'New integrated circuit component: card reader. Use it to read PassKeys - from ID cards.' - - bugfix: Fixes a delay issue when airlocks are being opened/closed by signalers. - Astral: - - bugfix: Lighting fixtures should no longer be visible in camera-less areas by - cameras. - - rscadd: Ghosts can now examine sentient diseases to see info - CameronWoof & MrDoomBringer: - - rscadd: Adds medical sprays, a new application method for touch chems - - rscadd: Pre-loaded medical sprays can be obtained from NanoMeds - - rscadd: Empty medical sprays can be found in boxes in chemistry and from cargo's - medical crate - - tweak: Sterilizer spray has been migrated to be a medspray instead of being a - spray bottle - Cebutris: - - spellcheck: lithenessk -> litheness - Cruix: - - rscadd: Sentient diseases now get two minutes to select an initial host before - being assigned a random one. - Dax Dupont: - - rscadd: Beacons can now be toggled on and off. - - rscadd: Mappers can now have beacons that default to off. Useful for ruins! - - tweak: Renaming replaces the snowflake locator frequency/code - - refactor: Beacons are no longer radios. Why were they radios in the first place? - I don't know. - - bugfix: You can now lay meters again with the RPD. - Denton: - - rscadd: Pubbystation's RnD department has been outfitted with a brand new circuitry - lab! It is found east of the Toxins launch room. - Floyd / Qustinnus (Sprites by Ausops, Some moodlets by Ike709): - - rscadd: Adds mood, which can be found by clicking on the face icon on your screen. - - rscadd: Adds various moodlets which affect your mood. Try eating your favourite - food, playing an arcade game, reading a book, or petting a doggo to increase - your moo. Also be sure to take care of your hunger on a regular basis, like - always. - - rscadd: Adds config option to disable/enable mood. - - rscadd: 'Indoor area''s now have a beauty var defined by the amount of cleanables - in them, (We can later expand this to something like rimworld, where structures - could make rooms more beautiful). These also affect mood. (Janitor now has gameplay - purpose besides slipping and removing useless decals) remove: Removes hunger - slowdown, replacing it with slowdown by being depressed' - - imageadd: Icons for mood states and depression states - MMMiracles: - - tweak: Thirteen Loko now has an overdose threshold of 60u, see your local CMO - for potential side-effects. - MrDoomBringer: - - tweak: Emagging the emergency shuttle now fries the on-board acceleration governor. - Better buckle up! - Naksu: - - balance: The nuclear authentication disk no longer treats the transit space as - a whole as being "in bounds", but instead checks whether it is in an approved - shuttle type (syndicate shuttles, escape shuttles, pubbiestation's monastery - shuttle, escape pods are allowed) - - bugfix: Blueprints can no longer be used to create areas inside shuttles. This - fixes various exploits involving shuttles and areas. - - bugfix: Moving across a space z-level border can no longer place you inside a - shuttle or a dense turf such as an asteroid. - SpaceManiac: - - bugfix: The Shift Duration in the round-end report is no longer blank in rounds - lasting between one and two hours. - kevinz000: - - rscadd: smoke machines can now be printed after researching adv biotech -2018-03-09: - Dax Dupont: - - rscadd: Display cases can now have a list where to randomly spawn items from. - - refactor: Moved plaque code to main type. - - refactor: Statues now use default unwrench and the tool interaction is now completely - non existent when no deconstruct flag is available. - Mark9013100: - - rscadd: Pill bottles can now be produced in the autolathe. - Naksu: - - balance: The white ship and miscellaneous caravan ships lose their advanced place-anywhere - shuttle movement during war ops. - - tweak: The smoke machine can now be deconstructed using a screwdriver and a crowbar - - code_imp: The smoke machine no longer calls update_icon every process() - Robustin: - - balance: Harvesters now have 40hp, from 60. - - tweak: The nuke will now detonate 2 minutes after Nar'sie is summoned, down from - 2.5 minutes - - tweak: The "ARM" ending now requires 75% of the remaining souls aboard to be sacrificed - before the nuke goes off, up from 60%. - - bugfix: Drones can no longer be on the sacrifice list - - bugfix: Bloodsense will now show the true name of the target -2018-03-10: - 81Denton: - - tweak: Added wall safes to Deltastation's HoP and Captain's offices. - Astral: - - bugfix: Constructed turbines will now properly connect to the powernet - Cobby: - - tweak: The Eminence scoffs at your "consecrated" tiles once the Justicar is freed - from his imprisonment. - Denton: - - rscadd: Engi-Vend machines now have welding goggles available. - - tweak: Grouped Nano-Med/Engi-Vend items by category. - Irafas: - - rscadd: Turrets can be set to shoot personnel without loyalty implants - Naksu: - - rscdel: The smoke machine can no longer be found in chemistry departments, instead - it must be constructed manually. The board was added to techwebs earlier. - Singularbyte: - - bugfix: Dead bodies no longer freak out about phobias - 'The Dreamweaver (Sprites: Onule)': - - rscdel: Nanotrasen's Lavaland research team has discovered that the alien brain - has disappeared from necropolis chests. - - rscadd: In it's place they have discovered a new artifact, the Rod of Asclepius, - a strange rod with a magnitude of healing properties, and an even higher magnitude - of responsibility... - XDTM: - - rscadd: You can now place people on tables on Help Intent. Doing so takes a few - seconds and makes the target Rest, instead of stunning them. - Xhuis: - - bugfix: Circuit slow-cloning no longer breaks with some circuits. - - code_imp: Circuit slow-cloning is now cleaner. - kevinz000: - - rscadd: Oh hey guys, RND shows correct material values now, don't hurt me! - ninjanomnom: - - bugfix: Blowing up the wrong part of the shuttle should no longer result in the - shuttle being permanently broken. -2018-03-11: - Buggy123: - - tweak: The Clockwork Justicar has decided to be merciful, and allow nonbelievers - to anchor their petty machines in his city. It's only fair for them to have - a fighting chance, after all. - Irafas: - - bugfix: Fixed pacifists from being able to fire mech weapons - JJRcop: - - bugfix: Sanity checks for Play Internet Sound - MrDoomBringer: - - rscadd: Orderable supplies in cargo now all have descriptions! The station's overall - FLAVORFUL_TEXT stat has gone up by nearly 2% as a result. - Onule: - - tweak: Mining drones have been given a visual makeover! - Poojawa: - - imageadd: Redded borg transformation animations - - imageadd: adjust mining borg animation to new colors. - Xhuis: - - rscadd: The Nanotrasen Meteorology Division has identified the aurora caelus in - your sector. If you are lucky, you may get a chance to witness it with your - own eyes. - ninjanomnom: - - admin: The debug message for generic shuttle errors is improved a little - - bugfix: Custom shuttles being too close to the map edge was causing problems, - you must now be at least 10 tiles away. -2018-03-12: - Naksu: - - balance: The space cleaner spray bottle is now much more efficient and uses much - less space cleaner per spray. The amount of cleaner it can hold has been adjusted - to compensate. - - bugfix: internet sounds can be stopped again - Robustin: - - bugfix: One-man conversions are actually fixed this time - excess chanters var - removed for a more readable and maintainable rune code. - - bugfix: Runes should no longer become GIANT if spammed (credit to Joan for this - fix). - - bugfix: Pylons are no longer a source of infinite rods. - - tweak: Attempting conversion without 2 cultists present will give a more helpful - warning. - - tweak: You can no longer convert braindead individuals. - - balance: Cult doors will no longer lose power but also cannot shock people, brittle - cult doors have 30 less integrity. Therefore ordinary crew can now beat cult - airlocks open without frying themselves. - - balance: Blood magic now costs slightly more blood and takes slightly more time, - the stun spell now stuns for 2 less seconds, twisted construction now costs - 10 health, and the blood rite relics (halberd, bolts, beam) are all 50-100 charges - cheaper. - - balance: The deconversion time for holy water is slightly reduced, 10 units and - 45 seconds (give or take), is all you should need now. Blood cultists can now - have seizures while afflicted with holy water. - - balance: Shades are now slower and have a modest reduction to their damage and - health. -2018-03-13: - Dennok: - - rscadd: Meters can be attached to the floor by screwdriver - Denton: - - bugfix: The disposal bin in Pubbystation's main tool storage now works. - - tweak: Deleted a duplicate r-wall between Pubby's main tool storage and the captain's - office. Added a Metastation-style crate disposals chute and a light switch. - - tweak: Various belts can now hold additional job-specific items. - - tweak: Sepia floor tiles fly really slowly, yet far when thrown. Don't hit yourself! - Naksu: - - admin: ERT creation has been refactored to allow for easier customization and - deployment via templates and settings - Polyphynx: - - tweak: Medical sprays can now be stored in medical belts and smartfridges. - The Dreamweaver: - - rscadd: Both of Nanotrasen brand totally-for-adult-use footwear, Wheely-heels, - the cool and hip new shoes with built in roller-wheels, and Kindle Kicks, the - fun and flashy light up sneakers, are now available as rare prizes at your nearest - arcade machine! - Toriate: - - rscadd: Added ammo counters for RCDs - - rscadd: Added actual flashing yellow light for RCDs - - imageadd: added new RCD sprites including inhands - - imagedel: deleted old RCD iconstate, but not the inhands - checkraisefold: - - bugfix: Nukeops properly checks the required amount of enemies for the gamemode! - This should fix downstream problems. - imsxz: - - rscdel: the viral aggressive metabolism symptom has been removed - ninjanomnom: - - bugfix: You need to actually clear an area for the aux base, remove all walls - (except rock walls). -2018-03-16: - Dax Dupont: - - tweak: 8balls take less time to shake. - Keekenox & Floyd / Qustinnus: - - imageadd: Adds a new Parallax layer that resembles Lavaland (Lava Planet), it - spawns on a random location near the station. You need your parallax on high - to see it. - Shadowlight213: - - tweak: Roundstart or latejoin sec officers will like donuts regardless of race. - cacogen: - - tweak: Transit tubes take half as long to secure/unsecure -2018-03-17: - AnturK: - - rscadd: Traitor AI's can now take manual control of turrets. - Cruix: - - bugfix: Sentient diseases will no longer lose points when a host is uninfected. - Dax Dupont: - - bugfix: Edison's ghost no longer interferes with Tesla Corona Coil research device. - Denton: - - tweak: Syndicate stormtroopers now rapid fire 10g slugs instead of buckshot. This - deals the same damage, but makes getting hit less laggy. - - rscadd: 'Pubbystation: Added protective grilles outside the circuitry lab. The - one with the big glass windows, right next to the bomb test site. Oops.' - - rscadd: 'Pubby: Added electrified grilles to the windows of the CMO/RD/CE offices, - as well as missing privacy shutters to the CE office.' - - rscadd: 'Pubby: There is now a very rare chance for a Xenomorph egg to appear - in the Xeno containment chamber at roundstart.' - - bugfix: 'Pubby: Fixed the name of the HoS space shutter button.' - - tweak: Updated a bunch of roundstart tips and added new ones. - Polyphynx: - - bugfix: Bluespace slime radio potions now work, and are no longer invisible. - RandomMarine: - - bugfix: Did you know that you could buckle guys to grounding rods? Probably not - - not that it mattered before, because people buckled to them didn't get shocked - when they got zapped. That's fixed now. - SpaceManiac: - - bugfix: Cameranet issues in OmegaStation's departures wing, crematorium, and freezer - have been corrected. - The Dreamweaver: - - bugfix: Fixes duplication issue when the Rod of Asclepius is removed while lying - down, as well as fixing a runtime when attempting to use multiple rods. - XDTM: - - rscadd: 'Changed behaviour of mech drills: now they take some time to start drilling, - then they keep drilling until manually stopped or the target is destroyed. Mobs - are still gibbed if they have more than 200 brute damage while being drilled.' - - rscadd: Drilling walls is now consistent; it takes longer, but it will always - work instead of only randomly. - - tweak: Drills no longer stun mobs, but they can dismember limbs. - - bugfix: Mech drills no longer cause explosion-like effects on mobs inside objects. - deathride58: - - bugfix: You can no longer push someone onto a table that's on the other side of - the station. - kevinz000: - - rscadd: Wet floors now get their duration decreased by 0.1 seconds per degree - above 0C the air temperature on it is, and instantly dry above 100C. Below 0C - they will freeze into ice and will not automatically dry. - - rscadd: Floors can now have different types of wet at the same time! Wet strength/type - is now a bitflag. -2018-03-18: - Davidj361: - - tweak: Made AI VOX sound files smaller sized - - bugfix: Fixed improperly pronounced AI VOX lines - - soundadd: Added a ton of new AI VOX sayings - Floyd / Qustinnus: - - rscdel: Removes short-term effects of mood add; Adds long-term effects of mood - by implementing sanity which goes up with good mood, down with bad mood, but - takes time to change. Your sanity can be seen as your average mood in the recent - past. All effects of moods are now covered by this system - - rscadd: Beauty component, currently only attached to cleanables, but you could - attach it to any atom/movable and make them pretty/ugly, affecting mood of anyone - in the room. - - refactor: Removes the original way of adding mood events, uses signals properly - instead. - - bugfix: Cleanables "giving" area's free beauty during initialization - - bugfix: Fixes some events not clearing properly - Naksu: - - bugfix: Chem dispensers now show the correct amount of units they will vend (instead - of 1/10) - - balance: Chem dispensers can now be upgraded. Manipulators increase macro granularity, - matter bins increase power efficiency, cells increase power capacity, capacitors - increase recharge rate. - - balance: Chem dispensers can now be constructed - - rscdel: mini-chemdispensers are removed. -2018-03-19: - Anonmare: - - tweak: Spaceacillin is now useful in disease control - Denton: - - rscadd: It's suicide HoPline prevention week at Omegastation! - - rscadd: Navigation beacons and a brand-new Officer Beepsky unit have been installed. - This means that crewmembers can now use medibots, janibots and other bots as - well. - - rscadd: The atmospherics department has been outfitted with all missing gases - as well as an incinerator and a hardsuit. - - rscadd: The size of the botany and xenobiology departments have been increased - in order to increase productivity. The medbay O2 port has been moved so that - doctors can access the table next to it. - - rscadd: RnD now has circuitry tools; medbay has stethoscopes+wrench+beaker/pill - bottle boxes and primary tool storage has multitools. Enginers no longer have - to share a single pair of insulated gloves either. - - rscadd: Engineers now have access to an Engi-Vend vending machine as well as missing - tools like inducers. Circuitry storage has a smoke machine board and a solars - crate in case the engine blows up. - - tweak: Blueprints have been moved from the vault safe to secure storage in order - to speed up construction projects. - - bugfix: The AI sat transit tube now works! Turret controls can now be accessed - from the outside. The first two turrets now use the proper type of gun. The - telecomms air alarm will no longer report false alarms. - - bugfix: The main hallway's firelocks now no longer all close at once. - - bugfix: 'Pubbystation: The atmos mix tank and N2 filter should now work properly.' - SailorDave: - - bugfix: Crayons and spraycans can no longer draw an unlimited amount of large - graffiti regardless of uses left. -2018-03-20: - Denton: - - bugfix: At last, the Pubbystation auxillary base can be launched again. - - code_imp: Aux base/escape pod/assault pod/elevator docking ports now default to - timid = FALSE. - Garen: - - rscadd: Added 4 new Icons to the diagnostic hud circuit status display that can - be set using the AR interface circuit. - - rscadd: now instead of seeing the yellow warning icon when a weapon is in the - circuit, the current status icon will just turn red. - Irafas: - - rscadd: Pacifists can now drill closets containing living beings - JStheguy: - - rscadd: Electronic assemblies can now have their casings colored using the new - assembly detailer, get yours at your nearest integrated circuit printer! - - rscadd: Added 2 new electronic assemblies, 2 new electronic mechanisms, and 3 - new electronic drones. - - rscadd: Added wall-mounted electronic assemblies in 3 sizes, simply slap it against - a wall to stick it up, and then anchor it in place with a wrench. - - imageadd: Added the new sprites for the new assemblies, and color-able overlays - for every assembly, to allow for the aforementioned coloring feature. - - tweak: Scanners can now scan power cells, circuitry tools, and integrated circuits, - assuming the player isn't able to use them normally. I.E. if the assembly is - closed. - - tweak: Using wrenches to anchor down assemblies now works for all assembly types - except drones, as opposed to just working for electronic machines. - - tweak: Examining an assembly now shows some text telling you what tools to use - to do what, like many other objects currently do. - Kor: - - code_imp: Jobs other than Assistant may now be assigned by admins or events as - the overflow role - - rscadd: April Fools now sets the overflow role as Clown. - Naksu: - - admin: Rhumba beat is now more than renamed GBS - - tweak: Plastic is now a valid material for lathes - - rscadd: Added two new beaker types, 120u and 180u. The 120u beaker can be printed - off the medical protolathe with just glass and plastic, the 180u requires some - mining materials and tech. - - admin: Whether to open the armory doors when spawning an ERT is now controllable - from the ERT creation window. - - tweak: Chaplain inquisitor role now spawns with one holy hand grenade instead - of a box full of them, and the belt now has actually useful stones instead of - unusable cult stones - Polyphynx: - - tweak: The piano now sounds more like a piano! - Shadowlight213: - - bugfix: Malf hacked APCs can be broken with extinguishers and toolboxes again. - TheDreamweaver: - - bugfix: Holodeck mobs that are given sentience via sentience potions are now warned - about the state of their existence. -2018-03-21: - BunnyBot5000: - - rscadd: Fringe Weaver drink - made with ethanol and sugar, it's classy (and slightly - weaker) hooch - - rscadd: Sugar Rush drink - made with sugar, lemon juice, and wine. It's got a - slight nutritional value but decreases your satiety, causing you to be unable - to consume junk food. - - rscadd: Crevice Spike drink - made with lime juice and hot sauce. A 'sobering' - drink, the Crevice Spike will reduce your drunkenness slightly but it kicks - hard going down, dealing 15 points of brute when first ingested. - MrStonedOne: - - bugfix: VOX sounds are now forcefully preloaded on clients to deal with an issue - keeping byond from loading them - cyclowns: - - tweak: Unary devices can now be analyzed using gas scanners. This means stuff - like vents, scrubbers, cryo tubes, or heaters/freezers. -2018-03-22: - Denton: - - tweak: The lavaland Syndicate base has been outfitted with a turret control panel - as well as more chemistry supplies and one (1) bar of Syndicate brand soap. - Floyd / Qustinnus: - - bugfix: Being happy no longer makes you obese. - JohnGinnane: - - refactor: Vending machines now have their own files which includes their refill - cannister. The machines themselves are unchanged - Naksu: - - bugfix: Pulled objects will now follow their puller across space transitions again - Robustin: - - bugfix: Fixed a bug that prevented the advanced blood rites (Halberd, Bolts, Beams) - from appearing when selected. - SpaceManiac: - - bugfix: Ventcrawlers in pipes now breathe from that pipe. - - bugfix: Deconstructing atmos components no longer breaks ventcrawl visuals. -2018-03-23: - Fel: - - add: Slimes can now be crossbred by feeding them a number of slime extracts of - one type. Beware, it only produces one crossbred extract! - - experiment: The number of required extracts has been lowered to 10 since the testmerge, - but this number is up for potential change depending on balance consideration - in the future. - - wip: 'Currently available crossbreeds are accomplished by feeding any slime the - required amount of the following extract colors: Grey, orange, purple, blue, - metal, yellow, dark purple, silver, cerulean, and pyrite. Their relevant effects - will be added to the wiki page for xenobiology soon(TM), and more to come in - a later addition!' - - add: Slimes can be fed extracts one at a time, but if you start mutating it, you - can feed it extracts straight from a biobag! You can also use biobags to feed - a reproductive extract monkey cubes. - - add: Slimes in the process of being crossbred will reveal what modifier they will - gain from their current modification, as well as how many more extracts are - required, to slime scanners. - - tweak: The rainbow slime clusterblorble effect will now only use reagents that - the extract will be activated from, and will try any of these reagents! As a - bonus side effect, this means it has a 1.1% chance of spawning and activating - another clusterblorble effect. - Floyd / Qustinnus: - - bugfix: progression bar now takes the delay after co_efficent in account - - code_imp: removes do_after_speed from mob base, moves it into physiology - - code_imp: makes a do_after coefficiency proc - - balance: Changes rate of sanity drain and caps it depending on mood - Frozenguy5: - - rscdel: Reverted bad airlock sounds. - Naksu: - - tweak: the amount of simultaneous monkey cube-spawned monkeys has been restricted. - - server: the cap is adjustable via the mobs subsystem - SpaceManiac: - - bugfix: The cargo conveyor switches now properly control the belts on the shuttle - again. - - bugfix: Entering a frequency like 145.7 into a radio will now work, where 1457 - was previously required. - TheMythicGhost: - - rscadd: 'New Integrated Circuit Converter Components: hsv2hex and rgb2hex for - smooth color transitions, woo!' - - imageadd: Added icons for the new component chips. - - rscadd: 'New Integrated Circuit Component: AI Vox Sound Circuit' - ninjanomnom: - - bugfix: You can no longer override shuttle areas with new or expanded areas from - elsewhere. -2018-03-24: - Davidj361: - - bugfix: Ranged guardians in scout mode no longer are able to move out of their - master when recalled. - Denton: - - spellcheck: Fixed missing capitalization for craft menu items. - - bugfix: Air alarms no longer trigger atmospherics alarms when stimulum or hyper-noblium - are present. The allowed partial pressure of pluoxium has been increased as - well. - Robustin: - - tweak: The Security Techfab can now produce basic shotgun shell types and .38 - ammo - ShizCalev: - - bugfix: Fixed a large number of missing APCs on Omegastation - - bugfix: Fixed unpowered Incinerator outlet injector on Omegastation. - - bugfix: Replaced glass window at Omegastation's incinerator with a plasma window. - - bugfix: Fixes broken atmos injectors on Omega - - bugfix: Fixes broken air outlet on Meta - - bugfix: Fixed a couple of malfunctioning atmospheric monitors across the rest - of the maps - - rscadd: New test atmos monitoring console debug verb to help alleviate future - issues. - YPOQ: - - bugfix: The imaginary friend trauma now works -2018-03-28: - Davidj361: - - bugfix: Ocular Wardens now target buckled and cuffed players/mobs, unless they - are cuffed by a slab. - - tweak: Cuck cultists can cuff already sec-cuffed targets with their slab cuff - spell. - Dax Dupont: - - bugfix: You no longer hit borgs with hats you want them to wear. - - rscadd: Viva la borg, engieborgs can now wear hats - - rscadd: Borgs can now wear more hats. - - bugfix: After a space OSHA inspection you can now reach the safe and fire extinguisher - in the omega detective office. - - bugfix: Makes it so you don't accidently trigger the fun balloon twice. - Denton: - - tweak: Pubbystation's signs to evac have been made more obvious. - - tweak: Plastic flaps are now airtight. - - spellcheck: Bluespace crystals now show their proper name during machine construction. - EvilJackCarver: - - bugfix: Edited a certain part of the disco machine's dance to only target carbon-based - (mob/living/carbon) lifeforms. pAI units will no longer spam chat with rest - notifications when in range of the disco machine. - Frozenguy5: - - tweak: The monkeycap has been increased to 64. - JohnGinnane: - - rscadd: A guillotine has been added to the game. Can be crafted. If the blade - isn't dull, will cut through human necks like a hot knife through butter. Use - a whetstone to sharpen it if it becomes dull. - MrDoomBringer: - - imageadd: All stations have been outfitted with brand new Chem Masters! They have - nicer sprites now! - - bugfix: Fixed the description of the Cargo Express Console. Cargo Drop Pod orders - aren't double-priced any more! - Naksu: - - bugfix: Chem dispensers no longer take hours to recharge - - tweak: chem dispensers also now use energy from the grid in proportion with the - amount charged - - admin: Admins now get a follow link when a revenant spawns. - - admin: Admin hotkey help is now actually correct - Pipe fixes: - - bugfix: Runtime in components_base.dm,91 what cause atmos machinery connection - problems. - - bugfix: Pipes release air in turf on Destroy(), again. - - bugfix: Pipeline now cant be annihilated by merge(src). Pipes don't lose air on - connecting more than to one pipe. - Robustin: - - code_imp: Monkey AI is now much more efficient and no longer full of terrible, - wasteful processes - - tweak: Monkeys will now move more and will only focus on nearby objects for stealing. - This should result in more natural monkey behavior instead of the monkey staring - furiously at random shit in the room for 5 minutes until it has a 50 item blacklist - of shit it will refuse to touch from then on out. - - tweak: The chance for a monkey to attack you for pulling it will now only happen - when execute the initial grab, instead of a check that happens every tick. - ShizCalev: - - tweak: Cleaned up the preferences panel a bit to be a bit more user friendly. - SpaceManiac: - - bugfix: Unwrenching and re-placing directional signs now keeps their direction, - and backings may be rotated in-hand rather than by pulling. - Tacolizard Forever: - - bugfix: phobias will no longer recognize trigger words inside of other words - XDTM: - - rscadd: Bees (and similar swarming mobs) are now able to occupy the same tile - as other bees! When doing so, their icons are offset to make them seem like - a proper swarm. - - tweak: Bees will now dodge bullets not directly aimed at them. Why are you firing - guns at bees - - bugfix: Sniper rifles will no longer oneshot mechs (although they still deal high - damage). - - bugfix: Sniper rifles no longer knock down walls they hit. - Xhuis: - - rscadd: Added the Family Heirloom trait. This makes you spawn with a special object - on your person; if you don't have it with you, you will gain a mood debuff. - - rscadd: Added the Nyctophobia trait. This makes you walk slowly in complete darkness, - and gain a mood debuff from the fear! - - rscadd: Added the Monochromacy trait, which makes you perceive (almost) the entire - world in black-and-white. - - balance: Social Anxiety's trigger frequency is now correlated to the number of - people near you. - - bugfix: Slimepeople now transfer their roundstart traits when swapping bodies. - YPOQ: - - bugfix: Machine power will now update when moving from powered to unpowered areas - and vice versa. - iskyp: - - bugfix: night vision goggles no longer overwrite thermal eyes. nvg eyes no longer - overwrite thermal goggles. - selea: - - rscadd: a* pathfinder, coordinate pathfinder(accepts not ref to some obj, but - it's abs coordinates) ,turf pointer(can give you ref to turf with given coordinates), - turf scanner(can read letters on floor and contents of turf),material scaner(can - read amounts of materials in machinery),material manipulator(to load/unload - resources) - - tweak: now you can decide, if basic pathfinder should avoid obstacles, or not.Now - demux push only desired output without unnecessary nulls,upgraded claw and local - locator. - - balance: reduced complexity cost of locomotors,abs/rel converters and basic pathfinders.Increased - complexity of throwers, - - bugfix: Fixed bugs with cryptography, obstacle ref in locomotors, release pin - in pullng claw. - - refactor: add material tranfer proc to mat containers.refactored pathfinder SS - to have separated queue for mobs and circuits to avoid spam. - - tweak: Now recycler can butcher mobs and saw tree logs. - yorii: - - tweak: Science goggles can now detect reagents in grenades. -2018-03-30: - Astatineguy12: - - bugfix: Ghosts of servants of Ratvar are no longer confined to Reebe like their - corporal counterparts. - Cruix: - - rscadd: Sentient diseases now have the "Secrete Infection" ability, which causes - anything touching the skin of the host they are currently following to become - infective, spreading their infection to anyone who touches it for the next 30 - seconds. - Davidj361: - - bugfix: Removed health cost for Twisted Construction upon casting on a wrong object - - bugfix: Fixed table crafting not properly checking the surrounding area for tools. - - code_imp: Changed /datum/personal_crafting/proc/get_surroundings(mob/user) to - return 2 lists. - Denton: - - bugfix: 'Omegastation: Added advanced magboots to secure storage so that traitors - can complete the theft objective.' - ShizCalev: - - bugfix: Silicons no longer have to be directly adjacent to a chem master to dispense - pills. - - bugfix: Fixed an exploit involving chem dispensers not actually checking if there - was enough energy to dispense the target chemicals. - - bugfix: Fixed exploit where chem dispensers always worked even if they didn't - have power... - - bugfix: Booze & soda dispensers will no longer turn into chem dispensers when - screwdrivered - - bugfix: Fixed chem dispensers showing as powered on when screwdrivered opened. - - rscadd: Added an examine indication when the maintenance panel to chem/soda/booze - dispensers is open. - neersighted: - - admin: Re-juggled delete verb permissions - robbym: - - bugfix: Fixed an error with integrated circuit tickers where they would sometimes - fail to tick. -2018-03-31: - Naksu: - - rscdel: Chameleon projectors will no longer work from inside transformations, - effects, mechas or machines. Effects that cause movement will no longer leave - sleepers in a bugged state where they can apply chems to you across distances. -2018-04-01: - Davidj361: - - bugfix: Fixed cuffed prison shoes being taken off by dragging them into your hand. - Denton: - - balance: The singularity engine will now output enough energy to power a station - again. - - bugfix: 'Pubbystation: The bomb testing site cameras are now accessible by camera - consoles.' - - spellcheck: Bluespace polycrystals now show their name when inserted into machinery. - Kor: - - rscadd: The disco machine no longer has a fixed list of songs. It will instead - allow players to pick music from a config folder managed by the host and head - admins. - - rscadd: There is now a bartender jukebox variant of the disco machine that plays - music, but has no lights or dancing. This variant will be added the station - maps once the feature freeze is over. - Naksu: - - bugfix: Removed stray defines from maps, making roundstart atmos functional and - runtime-spam free again - robbym: - - bugfix: 'fixed by converting to absolute coordinates #36861' - - spellcheck: changed description from copypasta to correct description -2018-04-02: - Davidj361: - - bugfix: Fixed 'vox_login' for AI VOX - - tweak: Made the AI VOX airhorn quieter to 25% of its original volume - GrayRachnid: - - bugfix: Fixes some crafting tooltips not displaying tool names properly. - MrDoomBringer: - - imageadd: roundend report button now has a lil icon - Naksu: - - bugfix: Removed some edge cases where atmospherics gas lists could continue holding - active gas items that can only transfer 0 gases to neighbors by making the garbage - collection clean them up. - RandomMarine: - - bugfix: The quick equip hotkey (e) now works for drones again. -2018-04-03: - 81Denton: - - spellcheck: Nanotrasen's space entomology department is shocked to discover that - Mothpeople have surnames! - YPOQ: - - bugfix: Mannitol will now properly cure minor brain traumas - robbylm: - - bugfix: Fixes 0 value not being saved in constant memory circuits (#36860) -2018-04-04: - Fludd12: - - rscadd: Burning ores now yields materials at a very reduced ratio! Lavaland roles - will now be able to construct things with enough effort. - JohnGinnane: - - bugfix: Fixed items sometimes being used on fullpacks when trying to insert - - bugfix: Fixed spray containers being used on open lockers and other containers - Naksu: - - bugfix: Fixed (dead) revenants being unable to deadchat or ahelp - - bugfix: Plasmamen that get converted into humans as a part of spawning as a protected - head role no longer retain their plasmaman equipment. - SailorDave: - - bugfix: Fixes virology Asphyxiation symptom activating too early and ignoring - transmission level. - ninjanomnom: - - bugfix: Shuttles have proper baseturfs now. - - bugfix: Mineral walls properly use their baseturfs when destroyed/drilled. - - rscadd: A new engineering goggle mode allows you to see the shuttle area you're - standing in. - - admin: Buildmode works a bit better with baseturfs now and can properly only remove - the top layer of turfs when editing. Note that as a result the order you place - turfs is important and a wall placed on space means when the wall is removed - there will be space underneath. -2018-04-07: - Davidj361: - - tweak: Stacked sheets now have a cancel button when taking an amount from them. - Dax Dupont: - - bugfix: Fixes dead chat announcements not using real name. - Naksu: - - bugfix: Trash bin anchoring/unanchoring now gives you a small text blip about - what happened. - PKPenguin321: - - bugfix: Restored accidentally cut functionality to flashes. You can once again - attach them to a signaller and signal them to trigger an AoE flash remotely. - SailorDave: - - bugfix: Mixed blood samples preserve their cloneability for podpeople if the samples - are the same. - kevinz000: - - rscadd: AIs can now latejoin! - - rscadd: Latejoining AIs will be sent to a special deactivated AI core. This AI - core will spawn in the AI satellite chamber in place of an active AI if none - is there at roundstart. These cores can be deactivated with a multitool, and - moved around per usual, but not deconstructed. They can, however, be destroyed - per usual. - - rscadd: AIs can only latejoin if atleast one of these cores exists and is in a - valid area (Powered, on station, etc etc), and if the AI job slot isn't filled - already by a roundstart or latejoin AI. - - code_imp: A few code internal debugging features have been added to help debug - GC errors. QDEL_HINT_IFFAIL_FINDREFERENCE hint will make the garbage subsystem - find references if the build is in TESTING mode, and qdel_and_then_find_ref_if_fail(datum) - or calling qdel_then_if_fail_find_references will do the same. - robbym: - - bugfix: Fixes examiner circuit failing to pulse 'not scanned' when reference is - null (#36881) -2018-04-08: - AnturK: - - tweak: Slime reflexes restored. - Dax Dupont: - - rscadd: Hugbox version of the VR sleeper you can't emag. - - admin: There's now two categorized vr landmarks for two teams for easy spawning. - You can also now rebuild/refresh all the VR spawnpoints by calling build_spawnpoints(1) - on any sleeper. - Naksu: - - admin: Admins can now access a new control panel for borgs via a new admin verb -2018-04-09: - CosmicScientist: - - rscadd: Top Nanotrasen scientists have diagnosed two new phobias! Birds and chasms! - Good luck Chief Engineers and Miners. - Dax Dupont: - - admin: Removing notes now has an "Are you sure" dialog. - Denton: - - rscadd: Omegastation now has its own arrivals shuttle. - Mickyan: - - imageadd: Stinger, Grasshopper, Quadruple Sec, and Quintuple Sec have new sprites. - Naksu: - - code_imp: Fixed an heirloom trait-related runtime - - code_imp: Fixed an incorrect signature in MakeSlippery causing runtimes - SpironoZeppeli: - - rscadd: You can now wrench the supermatter shard - ninjanomnom: - - bugfix: The arena shuttle should be working again. - - bugfix: The escape pods now reach their proper destination at round end -2018-04-11: - Davidj361: - - bugfix: Fixed paper bins dropping out of your hand or bag when grabbing a pen - or paper. - - bugfix: Paper bins not giving finger prints upon interaction. - - bugfix: Detective can now write notes onto his printed scanner reports. - - tweak: Detective scanner can have its logs erased via alt-click. - - tweak: Detective scanner can display logs via the action button. - Denton: - - bugfix: Added a missing intercom to the Delta arrivals shuttle. - ExcessiveUseOfCobblestone: - - code_imp: Uplink Items now have 2 separate probabilities. One for the syndicate - crate and one for cargo null crates. I encourage you to view uplink_items.dm - and make changes. - Robustin: - - balance: Hostile mobs capable of smashing structures will now smash their way - through dense objects too. - SpaceManiac: - - bugfix: The blindness overlay applied during cloning now properly stretches for - widescreen views. - - code_imp: Various macro consistency problems have been addressed. - YPOQ: - - bugfix: Eminences can hear clock cult chat again - george99g: - - bugfix: Suiciding will now deactivate all your genetics prescans. - iskyp: - - bugfix: makes dragnet non harmful - - tweak: pacifists can now use any disabler or stun setting on any energy gun - - code_imp: removed all of the pacifism check code from code/modules/mob/living/living.dm - - code_imp: gun objects no longer have a harmful variable, instead, ammo_casing - objects now have a harmful variable, which is by default set to TRUE - - code_imp: if a pacifist fires a gun, it checks whether or not the round chambered - is lethal, instead of whether or not the gun itself is lethal. - - code_imp: /obj/item/machinery/power/supermatter_shard is now /obj/item/machinery/power/supermatter_crystal/shard. - the crystal is the parent object. - neersighted: - - code_imp: Reduced lag by speeding up logs 10000% - - code_imp: Logs now include millisecond-level timestamps - pigeonsk: - - tweak: AI now requires silicon playtime instead of crew playtime for roundstart - role - selea: - - bugfix: fixed runtime in logic circuits, which was occured with invalid input - types. -2018-04-12: - Cobby: - - bugfix: Fixes getting "emptystacks" (a stack with an amount of 0) - Dax Dupont: - - bugfix: Briefcase bluespace launch pads no longer work on the centcom Z level. - Dennok: - - rscadd: RPD can automaticaly wrench printed pipes to floor. - Denton: - - rscadd: Cargo can now order tesla coil crates for 2500 credits. - Garen: - - bugfix: Added missing parameter types to circuits. - - bugfix: Fixes two datatypes appearing for some input circuits. - - tweak: Logic circuits now output booleans rather than 1's and 0's, this is purely - cosmetic. - Naksu: - - bugfix: Warp whistle can no longer leave you stuck in an invisible state - The Dreamweaver: - - bugfix: The air around you grows cooler, as if what you once knew about atmospherics - has changed ever so slightly... - Xhuis: - - bugfix: Mood traits cannot be chosen if mood is disabled in the config. - ninjanomnom: - - rscadd: The SM has a guaranteed 30 second final countdown before delamination - now - - balance: The SM will take less damage from low pressure environments - - balance: The SM has a slightly reduced max damage per tick - - bugfix: Tiles placed on lavaland turfs should behave properly again. - pigeonsk: - - bugfix: When you wash your bloody hands they will no longer still look bloody - afterwards -2018-04-13: - Dax Dupont: - - bugfix: SCP 194 now uses it's amount variable instead of a hardcoded number. - Dax Dupont & Naksu: - - bugfix: Toxin loving species won't take liver damage from toxins. - - bugfix: Liver now gets 0.01 damage per unit of toxin subtype reagent every 2 seconds - instead of 0.5. IE 30 units of whatever won't kill you within 10 seconds anymore. - - bugfix: Moved peacekeeper borg reagents to other_reagents so they don't do liver - damage and they aren't really toxins - - refactor: Renamed borg synthpax path to be more inline and put them next to the - other borg reagents. - Denton: - - tweak: Omegastation's supermatter crystal has been replaced with a smaller shard - that doesn't destroy the whole station on explosion. - Naksu: - - bugfix: Fixed KA upgrade applying on the minerborg - Putnam: - - tweak: rounded pi correctly - ninjanomnom: - - bugfix: Some strange baseturfs in lavaland structures and ruins should be fixed. - robbym: - - bugfix: Fixes tile analyzer circuit - - refactor: Cleaned up tile analyzer code -2018-04-14: - JohnGinnane: - - rscadd: PDA messages you send are now displayed in the chat for your confirmation - Naksu: - - bugfix: SCP-294 can no longer be deconstructed. - kevinz000: - - rscadd: After a severe security breach occurred due to lazily configured Nanotrasen - Network DHCP servers where attackers were able to hijack every airlock connected - to the Nanotrasen Intranet, the Central Command engineering team reports that - they have properly configured network address servers to give out (relatively) - secure network IDs again. [NTNet addresses reverted to 16-hex format. they will - now be randomized across a ~billion trillion possibilities instead of being - 1-1000 every round for doors and stuff.] -2018-04-15: - JohnGinnane: - - tweak: Reorganised circuit component controls within an assembly, so they appear - before the name of the component - Naksu: - - bugfix: Bluespace slime cookies can no longer be used to travel to CentCom - - bugfix: Borgs can no longer accidentally end up inside a cryo cell - - bugfix: Shoving someone inside a cryo cell now has a small delay unless they are - knocked down, stunned, sleeping or unconscious - - admin: Station borgs can no longer control the CentCom ferry. - - bugfix: Ghosts can no longer interact with the round via teleporter effects of - any kind - - tweak: His Grace can no longer be deep-fried - - bugfix: Passive gates can be interacted with in unpowered areas -2018-04-16: - Dax Dupont: - - rscadd: Added get current logs button for admins - - refactor: Removed verbs that have been replaced by other things like the combohud - or ticket panel. - Naksu: - - tweak: Mining borgs and mining drones now have mesons and the engineering goggles' - meson mode also works in lavaland again. - SpaceManiac: - - bugfix: The on-body icon for ancient bio suits is no longer broken. - ninjanomnom: - - bugfix: The aux base properly loads in rather than leaving an empty room. - - bugfix: Admin loaded map templates can be designated as shuttles during the upload - process. Make sure to load them on space first. -2018-04-17: - Dax Dupont: - - bugfix: Fixed martial arts/spell granters breaking on interrupt in final stage. - Naksu: - - balance: Welding tools now flash the user as the weld progresses, not just when - the welding is started. - - bugfix: CentCom officials will now properly display the objectives the admin has - assigned them. -2018-04-20: - Astatineguy12: - - bugfix: Gygax construction now actually uses up the capacitor - Dax Dupont: - - bugfix: A cat is fine too. You can select cat parts again! - - bugfix: Default lizard tail was never properly defaulted, now it is. - - bugfix: Fixes an exploit where tendrils/other spawners/anchored mobs in general - could be buckled to things and thus moved around. - Denton: - - rscadd: Due to space OSHA lobbying, the Syndicate's lavaland base now contains - a radsuit and decontamination shower. - - bugfix: Suit storage units' suit/helmet compartments now accept non-spacesuit - clothing (radsuits, EOD suits, firesuits and so on). - Naksu: - - bugfix: Oingo-boingo punch-face and meteor shot can no longer move gateways or - Reebe servant blocker effects - - bugfix: Mechas piloted by servants of Ratvar now teleport to the servant side - of Reebe when entering a rift - - admin: Gravity generators can now be thrown in buildmode - ShizCalev: - - bugfix: Fixed a number of conveyor belts leading to the incorrect direction. - - bugfix: Fixed shuttle conveyor belts being out of sync with cargo's conveyors - on some maps. - SpaceManiac: - - bugfix: Cycle-linking is no longer permanently disabled for airlocks on shuttles. -2018-04-21: - SailorDave: - - rscadd: A new manipulation circuit, the Seed Extractor. Extracts seeds from produce, - and outputs a list of the extracted seeds. - - rscadd: 'A new list circuit, the List Filter. Searches through a list for anything - matching the desired element and outputs two lists: one containing just the - matches, and the other with matches filtered out.' - - rscadd: A new list circuit, the Set circuit. Removes duplicate entries from a - list. - - tweak: The Plant Manipulation circuit can now plant seeds, and outputs a list - of harvested plants. - - tweak: Reagent circuits can now irrigate connected hydroponic trays and inject - blood samples into Replica pods. - - tweak: The Examiner circuit can now output worn items and other examined details - of carbon and silicon mobs into the description pin, as well as the occupied - turf of the scanned object, and can now scan turfs. - - tweak: The locomotion circuit now allows drones to move at base human speed, but - cannot be stacked, and assemblies can now open doors they have access to like - bots by bumping into them. - - bugfix: List Advanced Locator circuit now accepts refs as well as strings. - - bugfix: Fixed the Power Transmitter circuit not properly displaying a message - when activated. - - bugfix: Medical Analyzer circuit can now properly scan non-human mobs. -2018-04-23: - Dax Dupont: - - rscadd: More stations have been outfitted with disk compartmentalizers. - - bugfix: Fixed a lack of feedback when entering too many points for the gulag. - - admin: Fuel tank logging now logs to both game and attack logs so it's more clear - from logs what caused the explosion in game log and added coords to the messages - as well. - - bugfix: Fixes toolbelts being able to hold everything. - Denton: - - tweak: Moved Deltastation's ORM so that all crew can access it. - - code_imp: Added multilayer subtypes for mapping. - Kor: - - rscadd: Changelings can now have an objective to have more genomes than any other - changeling, rather than a set target. - - rscadd: Changelings can now have an objective to absorb another changeling. - - rscadd: Changelings now get bonus genetic points for buying powers when they absorb - another changeling. Their chem storage cap will also be increased. - - rscadd: Changelings absorbed by other changelings will lose all their powers, - chems, and genetic points, making them unable to revive. - Naksu: - - code_imp: Performance tweaks to plant code - - bugfix: Spears, nullrods etc should no longer be invisible - Power Control Support: - - bugfix: What do you mean we accidentally routed the interaction back to the apc - control conso- oh for fleeps sake STEVE WHAT DID YOU DO!! - Rinoka: - - bugfix: phobias now actually make you fear things other than an apostrophe s. - Spoilsport: - - rscdel: Inducers and integrated circuits can no longer charge energised weapons. - iksyp: - - rscadd: the beer and soda dispenser now have their own circuitboards, as well - as design ids. you can unlock them through techwebs under the biotech node. - - bugfix: beer and soda dispensers can no longer be turned into chem dispensers - by deconstructing and reconstructing them. -2018-04-24: - Dax Dupont: - - bugfix: Cargo scanner is no longer invisible. -2018-04-25: - Barhandar: - - bugfix: Pubbystation's field generators have been offset to no longer bisect the - engine on roundstart setup. - Dax Dupont: - - rscadd: You can now research and construct radiation collectors. - - bugfix: Doors don't turn into Mike Pence when the shock wire is pulsed, only why - it's cut. - - admin: Logging and messaging for singularities now include the area and a jump - link to the location where it happened. - - admin: Improved messaging for blood contracts. - - admin: While the onus is on the admin, the ckey has been added to some of the - prompts so mistakes can be caught earlier in the middle of the process. - Denton: - - tweak: 'Nanotrasen''s materials science division reports: Coins and diamonds DO - blend!' - Mickyan: - - tweak: Potato Chips and Beef Jerky from food vendors now contain salt. - deathride58: - - bugfix: Stocks in the stock market no longer have spontaneous exponential spikes. -2018-04-27: - Dax Dupont: - - balance: Experimentor now only outputs one clone. - - bugfix: Above change also fixes **an exploit** with loaded items getting cloned - after changing the loaded item and ejecting. - - bugfix: RPEDs will no longer display machine contents twice. - - bugfix: RPED can no longer hold everything. - - refactor: Moves all the logic for exchanging parts into the RPEDs instead of having - checks in every attack_by. - - rscadd: Clogged vents now scale like meteors. - - balance: Clogged vents got nerfed. - - bugfix: Buildmode toggle now checks for permissions so the hotkey can't bypass - it. - - admin: Press F10 for dsay prompt. - - admin: PDA explosions now have logging. - Denton: - - spellcheck: Fixed object descriptions and added missing ones - mostly to robotics - and RnD. - Fox McCloud: - - tweak: Removed acid requirement from basic network card and basic data disk - - tweak: grinding circuitboards no longer generates acid - Kor: - - rscadd: Added the Bureaucratic Error event, which replaces the overflow role with - a random job. - Mickyan: - - rscadd: 'New negative trait: Acute Blood Deficiency. Keep your slowly decreasing - blood level in check if you want to survive.' - MrDoomBringer: - - rscadd: Analyzers now show temperature in Kelvin as well as Celsuis - Naksu: - - code_imp: Inbounds subsystem, STATIONLOVING_2 and INFORM_ADMINS_ON_RELOCATE_2 - flags are removed. - - code_imp: New stationloving component replaces all of this. - - code_imp: 'Added new signals: COMSIG_MOVABLE_Z_CHANGED is now sent when a movable - changes Z level, COMSIG_PARENT_PREQDELETED is sent before the object''s Destroy() - is called and allows interrupting the deletion, COMSIG_ITEM_IMBUE_SOUL is sent - when a wizard attempts to make a thing their phylactery' - - bugfix: slime pressurization potions are no longer consumed when attempting to - apply them on already-spaceproof clothing - ShizCalev: - - bugfix: Fixed AI units being able to manually fire unpowered/broken turrets. - - bugfix: Fixed traitor AIs being unable to place a robotics factory if they failed - to place it after the prompt. - - bugfix: Fixed mobs having no hands if they had prosthetic limbs - - bugfix: Fixed damage overlays disappearing from prosthetic limbs when a mob is - husked - - bugfix: Fixed ghosts not being able to see into bags - - bugfix: Fixed a number of chapel and morgue doors being high-security CENTCOM - variants. This was also triggering certain phobias. - - bugfix: Fixed the warning message for chameleon projectors when a mob is inside - a closet - - tweak: Improved the formatting of the round-end report for AI and robotic units - - spellcheck: Added a period to the end of point-at messages. - - bugfix: Fixed ghosts getting spammed by sounds when clicking on a jukebox. - - bugfix: Fixed a duplicate docking port on the aux base template which was causing - some errors - - bugfix: Fixed Gr3y.T1d3 virus bolting open the doors to the SM, causing delamination. - - bugfix: Fixed the cat butcher dropping incorrectly colored tails - - bugfix: Fixed being unable to add a cat tail to someone through surgery. - - bugfix: Fixed mass purrbation & the anime event failing to give people ears and - tails in some cases. - - bugfix: Fixed AI units being able to toggle turrets on and off when AI control - is disabled. - - bugfix: While it slight increases the cost of production, vanilla ice cream is - now actually made with real vanilla! - - bugfix: Fixed AI units being able to see lights through static. - - bugfix: Fixed securitron pathfinding icons being broken. - imsxz: - - bugfix: invulnerability exploit involving stable adamantine extract fixed - ninjanomnom: - - admin: You can now use alt click in advanced buildmode to to copy the targeted - object for placement with left click. - - rscadd: You can now see objects and turfs past the map edge borders. - - bugfix: Shuttles getting removed would occasionally causes issues. This has been - fixed. -2018-04-28: - MMMiracles: - - rscadd: A jukebox can now be found in the bar of your respective station. Contact - Central about song suggestions to be added to the curated list! - Naksu: - - code_imp: clothing-specific flags are now defined in /obj/item/clothing.clothing_flags - PKPenguin321: - - balance: The changeling "Spiders" power now requires absorptions gained through - the actual Absorb ability, rather than DNA from DNA sting. To compensate, it - now only requires 3 absorptions, down from 5. - ShizCalev: - - bugfix: Fixed a good number of missing icons. - as334: - - rscadd: Fusion is back - - rscadd: Fusion now happens with large quantities of hot plasma and CO2, consuming - all the plasma rapidly and producing large amounts of energy. Other gases can - also effect the performance of the reaction. - - rscadd: Fusion now produces radiation. Be careful around reactors. - - bugfix: fixes fusion dividing by zero and destroying everything - - code_imp: Gas reactions now have access to where they are occurring - - bugfix: Prevents some other reactions from producing matter from nothing - kevinz000: - - rscadd: Circuit ntnet components buffed. Added a new low level ntnet component - that can send custom data instead of just the two plaintext and one passkey - format, which things will use by default. Ntnet now uses a list for their data - instead of three variables. they also have lowered complexity for the now weakened - normal network component, and has lower cooldowns. - pigeonsk: - - bugfix: The faint echoes of maracas grows louder, as if a past spirit once forgotten - has come back with a vengeance... -2018-04-29: - Naksu: - - bugfix: Wearing a bucket no longer connects your head to the vacuum of space - oranges: - - rscdel: Pet collars can no longer be equipped on humans -2018-04-30: - Dax Dupont: - - balance: Adds a cooldown to PDA send to all messages. - - bugfix: Last sent message cooldown actually works now. - - tweak: More reagents in the clogged vents event. - Denton: - - rscadd: Added more holoprojectors to techwebs (security, engineering and atmos). - Erwgd: - - rscadd: Limb growers can now create limbs for flypeople and mothmen. - Evsey9: - - balance: Integrated Circuit weapon mechanisms now work only when outside of any - containers and hands, due to reports of severe injury caused by activating them - while still holding them. - Garen: - - imageadd: added inhands for teleprods. - JJRcop: - - bugfix: Integrated circuits can no longer throw themselves. - Jalleo: - - bugfix: a certain exploit that can occur in regards to creating certain items - in a particular manner - - tweak: readds emitter field generator and rad collector wrenching times. Someone - override it when adding the wrench_act. - Mickyan: - - tweak: You can now see how well fed you are by self-inspecting. - Naksu: - - code_imp: More flags have been moved to their appropriate places - - code_imp: HEALS_EARS_2 is removed in favor of the earhealing component - - code_imp: wearertargeting component is available to subtype for components that - want to target the wearer of an item rather than the item itself - ShizCalev: - - bugfix: Glass stacks will now properly delete when exploded. - - bugfix: Fixed attacking someone with a bikehorn not triggering the correct mood - event. - YakumoChen: - - tweak: Nanotrasen has once again shipped BZ to its nearby stations. Check your - local Xenobiology lab for your shipment. - - tweak: Nanotrasen would like to remind you that BZ is meant for keeping slimes - from moving or getting hungry. It is not for human use and may lead to hallucinations. - Always practice workplace safety when handling dangerous gasses! - george99g: - - bugfix: Committing suicide will now stop you from being cloned via prescans. - iksyp: - - tweak: pacifists can now use .50BMG Soporific Rounds - ninjanomnom: - - bugfix: Caravan ambush shuttles have been templated to fit the new system and - can fly again. - pigeonsk: - - bugfix: Large stacks of plastitanium now display properly - - rscadd: You can now get traditional sake and get a first-hand taste of a superior - culture. Have I told you about my katana and my trip to- -2018-05-01: - BuffEngineering: - - bugfix: Nanotrasen has graciously connected the port bow solar's SMES to the main - grid. - Denton: - - rscadd: You can now craft and disassemble HUDsunglasses! Check out the clothing - section of the crafting menu. - - tweak: Cargo packs have been reorganized to shrink the big engineering, food&livestock - and misc categories. - NewSta: - - rscadd: 'Added 5 new drinks: Alexander, Between the Sheets, Kamikaze, Mojito and - Sidecar.' - - rscadd: Added Menthol and Sake to the drink dispensers. - Ordonis, Denton: - - rscadd: OH YEAH BROTHER! The H.O.G.A.N. AI module has a chance to spawn at the - AI upload. - SpaceManiac: - - bugfix: The button in the mech interface to terminate maintenace protocol no longer - reads "Initiate maintenace protocol". - - bugfix: Boxes now fit inside storage implants again. - XDTM: - - balance: Small, constant ticks of brain damage are now less likely to cause traumas. - deathride58: - - bugfix: Fixed the intergalactic stock market crash. The speculation/performance - modifier has been removed completely. -2018-05-04: - Cobby (Stolen from GrayRachnid): - - tweak: The processor has now been generalized techweb-wise into the "food/slime - processor". - - rscadd: The processor can now be made by Science. - Dax Dupont: - - balance: After successful lobbying by the Space Ancap Federation ammo is no longer - free. Material redemption cost is now determined by the amount of bullets left. - - balance: .38 ammo is now cheaper to produce. - - balance: Casings now give a little bit of metal. mostly for immersion sake. - Denton: - - bugfix: Runtimestation's RnD machinery is now up to date. - Fox McCloud: - - bugfix: Fixes recycler not recycling bluespace and plastic objects - - bugfix: Fixes objects with material components always showing their materials - on examine - Garen: - - bugfix: Removes unintentional pins from the constant circuit. - Hyacinth: - - rscadd: Grenadine is now available in the bar! - - tweak: Tequila sunrises now require grenadine to make! - Mickyan: - - bugfix: Our suppliers assure us that Midori Tabako cigarettes will actually contain - tobacco from now on. - Naksu: - - code_imp: APC code is slightly less shit. - - tweak: APC cells can be removed with a crowbar - Onule!: - - rscadd: Plasmaman liver and stomach crystals! - Poetic_Iron: - - spellcheck: Fixed 'Tequila Sunrise' naming from 'tequila Sunrise'. - SpaceManiac: - - code_imp: The commit hashes shown in Show Server Revision are now long enough - to autolink when copied into issue reports. - Spellbooks Take 2: - - imageadd: Magical Spellbooks are now animated. - Tlaltecuhtli: - - tweak: medbeams heal tox and oxy slighty - pigeonsk: - - rscdel: After an internal audit and review Nanotrasen has decided that stock financing - at the station-level makes no logistical nor managerial sense. Stations, and - their cargo departments, may no longer play the stock market. -2018-05-06: - Dax Dupont: - - bugfix: Rhumba beat now stops processing while dead. - Denton: - - bugfix: The Donksoft vendor board got lost during the techwebs transition and - has been re-added under the illegal technology node. - Garen: - - tweak: Grilles must take damage to produce tesla shocks. - Naksu: - - bugfix: APCs are closed with crowbars properly again. Screwdrivers can now be - used by borgs to pop out the cell instead of crowbars - SpaceManiac: - - bugfix: The top-left menus (icon scaling, ghost preferences, etc.) now work again. - Xhuis: - - tweak: Character traits are now called character quirks. Functionality remains - unaffected. - deathride58: - - rscadd: If the nuke disk stays still for long enough, the lone operative event - will enter the random event rotation. The longer the nuke disk stays still, - the more likely the lone operative event will trigger. -2018-05-08: - cacogen and nicbn: - - tweak: You can now select RPD modes individually. - - tweak: RPD autowrenching is now a tgui action rather than an Alt Click option. - deathride58: - - rscadd: Added ambient occlusion. You can toggle this on or off in the game preferences - menu. -2018-05-09: - Firecage & Bluespace: - - balance: Replaces the Roman Shield and Roman helmets in the Autodrobe with fake - versions with neither block chance nor armour values. - PKPenguin321: - - rscadd: There are now two new variants of the concatenator integrated circuit. - Small, which only takes 4 inputs, and large, which takes 16. Small uses 50% - less complexity, large uses 50% more. - - rscadd: There's a new string length circuit, which simply returns the length of - a given string. - - rscadd: There's a new indexer circuit, which takes a string and an index and returns - the character found at the index of the given string. - - tweak: The find text integrated circuit now has two new pulse outs, one that runs - when it finds the text and one that runs when it does not. - - tweak: Leaving the delimiter in the explode text circuit null will now return - all of the input string's characters in a list. -2018-05-10: - Dax Dupont: - - bugfix: The singularity spawned by the arcade orion tale meme will disappear as - intended. - Kor: - - rscadd: Science may now research reactive armour shells, which create different - armours when combined with different anomaly cores. They are constructable from - the Research and Engineering lathes. - Ordo: - - rscadd: Adds a french beret to the mime. Steal it from him to learn French! Sort - of. HONH HONH HONH. - SpaceManiac: - - refactor: Large groups of PNG assets are now transmitted in spritesheets, greatly - improving load times. - - tweak: The access denied message when entering a mech now distinguishes between - DNA lock and ID requirements. - - bugfix: Removing an ID card from a wallet now properly removes its visual and - accesses. - Tlaltecuhtli: - - bugfix: the default bulldog shotgun ammo makes sense now - - bugfix: fixes a possible money exploit - YPOQ: - - bugfix: Anomalies can be disabled with signalers again -2018-05-13: - Alexch2: - - bugfix: Large crates no longer behave like lockers. They no longer open into invisible - sprites when damaged, interacted with, when "toggle open" is used, or when non-crowbar - items are used on them. - Ausops and Qbopper: - - rscadd: Added security jumpskirts - snag one from a security wardrobe locker. - Cobby: - - bugfix: Beds will now properly save you from floor is lava, but only if you buckle - to them - Cyberboss: - - tweak: You may now take unlimited neutral and negative quirks - Denton: - - bugfix: Runtimestation's RTGs are now connected to the powernet. - - code_imp: Added chem_dispenser/fullupgrade as well as chem_synthesizer for testing. - - tweak: Replaced runtimestation's two chem dispensers with those subtypes. - - spellcheck: Did you know that you can use a screwdriver on the ChemMaster board? - Now you do. - Frozenguy5: - - tweak: You can now make plasma reinforced glass at the ORM. - - tweak: Titanium glass is now worth 0.5 titanium + 1 glass. Plastitanium glass - is now worth 0.5 titanium + 0.5 plasma + 1 glass. Therefore these glass sheets - are cheaper to make. - Iamgoofball: - - bugfix: Family Heirlooms now properly show you where they are stored if they spawn - in a bag. - Mickyan: - - tweak: Gauze can be deconstructed into cloth using wirecutters. - Naksu: - - rscdel: Fusion has been removed for pressing ceremonial reasons, and also because - it crashes the server - Tlaltecuhtli: - - bugfix: 50% of the corgis bought are now male - XDTM: - - tweak: Teleporters linked to other teleporters now teleport into the other teleporter's - hub, instead of the power station. - - bugfix: Teleporters now no longer consume power if teleportation fails. - YPOQ: - - bugfix: Fixed items stacks sometimes having the wrong amount if created on another - stack - - bugfix: Constructing light tiles no longer uses two sheets of metal - - bugfix: Gorillas have hands slots again - - bugfix: The paddle/nozzles of defibs, backpack water tanks, and gatling lasers - work again - - bugfix: You can honk people with bike horns again -2018-05-14: - Barhandar: - - rscadd: Amount of goliath plates is now shown in examine for explorer suits and - mining hardsuits. - Dax Dupont: - - rscadd: You can now swap disks in the plant manipulator. - JStheguy: - - imageadd: Vending machines now have more complex shading and are rigged with next-gen - flickering technology, a couple have either a partial or complete facelift. - Maintenance panel overlays have been fixed on machines where they were seemingly - left unchanged when the switch to 3/4ths was made. - - imageadd: Burger buns are bigger and more detailed. - - imageadd: Donuts have been totally redrawn. - SpaceManiac: - - admin: Admin-healing someone will now rejuvenate their mood as well. -2018-05-15: - Dax Dupont: - - bugfix: Fixes missing curator hud icon. - Denton: - - tweak: Engi-Vend machines now contain fire alarm and firelock electronics! - - code_imp: Loose tech storage circuit boards have been replaced with spawners. - - rscadd: APC/air alarm/airlock/fire alarm/firelock electronics are now available - once Industrial Engineering is researched.. -2018-05-16: - Dax Dupont: - - balance: Cult items will no longer be a long ride on the vomit coaster if picked - up by a non cultist. -2018-05-17: - Dax Dupont: - - balance: Cult space bases are kill again. - - balance: Cult floors now pass gas. - - bugfix: Fixed a few things deconning into the wrong circuit. - - bugfix: You can no longer do infinite bioware surgery. - - rscadd: Added the MURDERDOME VR player versus player combat arena, filled with - the most powerful weapons Centcom could think of to murder each other peacefully. - Contact your nearest vendors for VR sleepers. - - tweak: VR landmarks now accept outfits. - - tweak: VR Sleepers can now be constructed and researched. - - tweak: VR Sleepers now respond to mouse drops like sleepers! - - bugfix: VR sleepers no longer close or open inappropriately. - Denton: - - code_imp: Added /syndicate subtypes for air alarms and APCs. - - bugfix: Added missing stock parts to the syndicate lavaland base. - - tweak: Added kitchen related circuit boards to the syndie lavaland base. - Dimmadunk: - - rscadd: 'There''s a new type of reagent added to the booze dispenser: Fernet. - With it you can make a couple of new digestif drinks that will help you reduce - excess fat!' - Garen: - - rscadd: Thrower and Gun circuits put messages in chat when they're used. - - tweak: Only the gun assembly can throw/shoot while in hand - - imageadd: Adds inhands for the gun assembly - - bugfix: grabber inventories update when a thrower takes from them - Pubby: - - tweak: PubbyStation has been updated. You can now be the lawyer. - ShizCalev: - - bugfix: Adminorazine will no longer kill ash lizards. - - bugfix: Adminorazine will no longer remove quirks. - iskyp: - - tweak: the walls on the crashed abductor ship ruin in lavaland can now be broken - down -2018-05-18: - GrayRachnid: - - rscadd: The Spider Clan proudly announces that they've taken steps to improve - their hospitality at their capture center! They now hope that captured targets - would not kill them self or fight between each other, dirtying the floor with - blood. - - rscadd: They've also added a VR room for those sick of the real world, taking - them to a reality where they feel like they matter. -2018-05-19: - Alexch2: - - spellcheck: Fixes tons of typos related to integrated circuits. - - tweak: Re-writes the descriptions of a few parts of integrated circuits. - Astatineguy12: - - tweak: The experimentor is less likely to produce food when it transforms an item - - bugfix: The experimentor no longer breaks when the toxic waste malfunction occurs - multiple times and isn't cleaned up - - bugfix: The experimentor irridiate function actually chooses what item to make - properly rather than picking from the start of the list - Dax Dupont: - - bugfix: Mulligan didn't work on lizards and other mutants. Now it does. - - bugfix: Foam no longer gives infinite metal - Denton: - - code_imp: Loose silver/gold/solar panel crates have been replaced with "proper" - crates. - - tweak: There are rumors of the Tiger Cooperative adding a "special little something" - to some of their bioterror kits. - Iamgoofball: - - tweak: Lipolicide now only does damage if you're starving. - Mickyan: - - bugfix: Drinking too much Gargle Blaster, Nuka Cola or Neurotoxin no longer breaks - time and space. - Nichlas0010: - - tweak: Reseach Director Traitors can no longer receive an objective to steal the - Hand Teleporter - ShizCalev: - - bugfix: Fixed mobs immune to radiation being killed by HIGH bursts of radiation. - - bugfix: The book of mindswap will now properly mindswap it's users. - iksyp: - - rscadd: stacking machines and their consoles no longer dissapear into the shadow - realm when broken - - rscadd: you can link the stacking machine and its console by using a multitool -2018-05-20: - Pubby: - - rscadd: 'Cargo bounties from Nanotrasen. Earn cargo points by completing fetch - quests. remove: Several cargo exports have been reduced or merged into cargo - bounties.' - XDTM: - - rscadd: 'Added a new lavaland loot item: Memento Mori. A necklace which has the - power to prevent death, but will turn you into dust if removed.' -2018-05-22: - Cyberboss: - - rscadd: You can now view your last round end report window with the "Your last - round" verb in the OOC tab - Dax Dupont: - - tweak: The BoH dialog now has Abort instead of Proceed as an default option. - - bugfix: Fixes race condition caused by exiting the body while dying in VR. - Denton: - - balance: Skewium is much less likely to appear during the Clogged Vents event. - Firecage: - - rscadd: Replaces wardrobe lockers on Box with Wardrobe Vending Machine. - Kor: - - rscadd: Engineering can now create anomaly neutralizer devices, capable of instantly - neutralizing the short lived anomalies created by the supermatter engine. - - rscadd: The Quartermaster and HoP can now access the vault so they can use the - bank machine. - Mickyan: - - bugfix: Pacifists can now use harm intent for actions that require it (but still - can't harm!) - Naksu: - - code_imp: Added EMP protection component, replaced various bespoke ways things - handled EMP proofness - Nichlas0010: - - spellcheck: you now feel nauseated instead of nauseous - - bugfix: Comms consoles won't update while viewing messages - SpaceManiac: - - bugfix: Pipe icons in the RPD now show properly in older versions of IE. - - bugfix: Family heirlooms which can fit in pockets will now spawn there. - - bugfix: Family heirlooms which only fit in the backpack now show the backpack - at roundstart. - - bugfix: Family heirlooms which do not fit in the backpack are no longer gone forever. - - bugfix: Mindswapping with someone else no longer forces ambient occlusion on. - - code_imp: IRV polls now use the same version of jQuery as everything else. - - bugfix: Hydroponics trays can no longer be deconstructed with their panels closed - or unanchored while irrigated. - - tweak: Frames for machines which do not require being anchored can now be un/anchored - after the circuit has been added. - - bugfix: Removing an ID from a PDA in a backpack no longer hides the ID until something - else updates. - - bugfix: Opening and closing airlocks repeatedly no longer stacks queued autocloses. - - bugfix: Admin AI interaction now works properly on firelocks. - - spellcheck: Fix "Your the wormhole jaunter" when a wormhole jaunter saves you - from a chasm. - Wilchen: - - rscdel: Removed box of firing pins from rd's locker - armhulen: - - rscdel: chameleon guns are disabled for breaking the server - kevinz000: - - bugfix: Field generators are once again operable by adjacent cyborgs. - - bugfix: Digital valves are once again operable by silicons. - - bugfix: Chasms no longer drop mobs buckled to undroppable mobs or objects. - resistor: - - rscadd: Added circuit labels! You can now customize the description of your assemblies. -2018-05-23: - ShizCalev: - - bugfix: Fixed a runtime with the gulag teleporter that could cause the process - to fail if you removed the ID. - - tweak: Not setting the goal of a prisoner's ID when teleporting them will now - set the ID's goal to the default value (200 points at the time of this change.) - SpaceManiac: - - bugfix: Flipping and then rotating trinary pipe fittings no longer causes their - icon to mismatch what they will become when wrenched. - - bugfix: RPD tooltips for flippable trinary components have been corrected. - - bugfix: Entertainment monitors now view the real Thunderdome rather than the template. - cyclowns: - - rscadd: Analyzers can now scan all kinds of atmospheric machinery - unary, binary, - ternary, quaternary, you name it. This means stuff like gas pumps, gas mixers, - vents and so forth can be analyzed. - - tweak: Analyzers now show temperature in kelvin as well as celsius. - - tweak: Analyzers now show total mole count, volume, and mole count of all gases. - - tweak: Analyzers show everything at slightly higher degrees of precision. - imsxz: - - admin: Using mayhem bottles and going under their effects is now logged. - kevinz000: - - rscadd: Any anomaly core can now be deconstructed for a one time boost of 10k - points in the deconstructive analyzer. -2018-05-25: - Astatineguy12: - - bugfix: The mime blockade spell now shows up under the right tab - Cruix: - - rscadd: Added a button to chameleon items to change your entire chameleon outfit - to the standard outfit of a selected job. - Dax Dupont: - - rscadd: Murderdome now has a telecomm system, so you can taunt your enemies better. - - rscadd: Snowdin has come back, as VR! - - rscadd: Nanotrasen Tactical Bureau has discovered a Syndicate VR Training program - on their last raid. It seems to be based on an old CentCom design... - - rscadd: Restricted variant of the uplink. Will allow admins and such to spawn - uplinks in remote arenas or for events that aren't as destructive and can't - communicate with other Zs. - - bugfix: Extends same Z level check to monitor and bugging operations too for camera - bug. - - bugfix: VR sleepers now show the stat of the VR avatar instead of the user as - intended. - - code_imp: Makes it throw a stack trace when you ghostize in VR. - - tweak: It will now delete the body if it's unconscious if you try to reconnect, - to speed up reconnection. - - balance: Emagged sleepers will now display a notification on the UI, and make - you slightly dizzy after a while. - - balance: More chemicals can be found when vents get clogged. - - bugfix: Fixes accidental empty ahelp replies. - Denton: - - rscadd: Departmental wardrobe vendors have been added to all maps. - - spellcheck: Sorted cargo packs (wardrobe refills//alphabetically) and mining vendor - items (by price), again. - - bugfix: 'Navbeacon access requirements have been fixed: Now you need either Engineering - or Robotics access, but not both at the same time.' - Garen: - - rscdel: Removed circuitry save files saving whether or not the assembly is open. - - rscadd: Adds messages for when you successfully use a sensor or scanner circuit. - - bugfix: Fixed circuit printers printing advanced assemblies from save files despite - not being upgraded. - - bugfix: Fixed circuit printers printing circuits into assemblies that wouldn't - normally be able to hold them. - - bugfix: Fixed circuit assemblies taking damage when using objects with the help - intent. - Mickyan: - - spellcheck: fixed typo in bronze girder construction - MrDoomBringer: - - rscadd: Cargo now has access to Supplypod Beacons! Use these to call down supplypods - with frightening accuracy! - - imageadd: the VR sleeper action button has a sprite now - Naksu: - - code_imp: Replaced initialized and admin_spawned vars with flags. - - code_imp: changed the shockedby list on doors to be only initialized when needed. - - tweak: Chameleon projector can no longer scan (often temporary) visual effects - like projectiles, flashes and the masked appearance of another chameleon projector - user - - bugfix: Drones can no longer see a static overlay over invisible revenants - - balance: adjusted default antag rep points to grant every job the same amount - of points per round, except for assistant which gets 30% less - SpaceManiac: - - bugfix: Non-harmfully placing someone who is resting on a table no longer makes - them get up. - - bugfix: The disco machine no longer lags the chat by spamming "You are now resting!" - messages. - - bugfix: The green overlay indicating where a map template will be placed is no - longer invisible on space turfs. - - bugfix: CentCom is no longer self-looping, fixing the ability to see or get into - certain areas after escaping to space. - - bugfix: The destructive analyzer no longer consumes entire stacks to give the - benefit of one sheet. - - bugfix: Xeno weeds and floors under diagonal walls are now on the correct plane, - fixing odd ambient occlusion appearances. - - bugfix: Inserting materials into protolathes with telekinesis is now possible. - - bugfix: Telekinesis no longer teleports items removed from deep fryers, constructed - sandbags, and leftover materials not inserted into lathes. - - bugfix: Telekinetic sparkles now appear in the correct place when clicking on - a turf and when clicking in the fog of war in widescreen. - - bugfix: Telekinetically adjusting power tools no longer causes them to exit the - universe. - - tweak: Examining a telekinetic grab in-hand will now examine the grabbed object. - - bugfix: Frost spiders now correctly inject frost oil on bite. - yorii: - - bugfix: Fixed the smartfridges to be in line with all other machines and puts - the released item in your hand. -2018-05-26: - Dax Dupont: - - bugfix: Experimentor no longer shits out primed TB nades. - Garen: - - rscadd: Added a cell charger to the circuitry lab on all stations. - - rscadd: Added a circuitry lab to the syndicate lavaland base. - - tweak: Modified the meta station circuitry lab. - Iamgoofball: - - rscadd: Humans require ice cream. Eat the ice cream. - Kor: - - rscadd: Bag of Holding detonations have been significantly reworked. - Robustin with cat earrs: - - bugfix: 'Gun overlays should be way less laggy now. remove: Chameleon guns are - completely removed since they crash the server, were already made unavailable, - and are the worst shitcode I''ve ever seen in my life.' - SpaceManiac: - - tweak: Clicking on the viewport to focus it no longer leaves the input bar red. - - admin: Create Object will no longer force objects with special directional logic - to be facing south by default. - - bugfix: Running diagonally into space now properly continues the diagonal movement - in zero-gravity. -2018-05-27: - Armhulen, and Keekenox: - - rscadd: Chaplain now gets custom armor too! Order it from the beacon in your locker. - Cobby: - - tweak: Several of the recent drinks added have now been given effects! - - rscadd: 'Alexander: Conquer the world... or just the station with this drink! - If you have a shield, it will increase the block chance by 10 percent! Careful - not to drop it in battle though....' - - rscadd: 'Between The Sheets: Save the pillow talk for next shift, having this - in your system while you''re asleep will slowly heal you!' - - rscadd: 'Menthol: Prevents coughing. Good for a cold or if the Chaplain gets his - hands on a smoke book!' - - tweak: Descriptions have been edited so that if you view these under a chem master - they will tell you the effect. - - tweak: Decals are the exception to the recent removal of effects in Chameleon - Projectors. - Dax Dupont: - - bugfix: Did you know istype doesn't work on paths even though they are mostly - the same? Yeah I didn't either. Experimentor shouldn't shit out TB nades anymore. - - bugfix: Fixes item reactions for relics as well. - - rscadd: Adds better messaging - - bugfix: Fixes summons happening on away missions. - GuyonBroadway: - - rscadd: Adds gloves of the north star to the traitor uplink. Wearing these gloves - lets you punch people five times faster than normal. - - rscadd: Sprites for the gloves courtesy of Notamaniac - Mickyan: - - rscadd: 'New trait: Drunken Resilience. You may be a drunken wreck but at least - you''re healthy. If alcohol poisoning doesn''t get you, that is!' - Naksu: - - rscadd: Nuclear explosive-shaped beerkegs found on metastation can now be triggered - with the nuclear disk and the syndicate's legacy nuclear code for a foamy surprise - SpaceManiac: - - bugfix: Unwrenching and re-wrenching pre-mapped atmos components no longer turns - them on automatically. - steamport: - - bugfix: Borgs/AIs can now toggle rad collectors -2018-05-28: - CitrusGender: - - bugfix: Kills you if you're under 0% blood and above -9999% blood level (shouldn't - be possible through normal means to be below that.) - - bugfix: Stops bloodloss trait from happening if your race contains the NO_BLOOD - - bugfix: added a check to see if the preferred race is human when the name doesn't - have a space - Dennok: - - bugfix: Fixed a laser reflections from reflectors. - Denton: - - tweak: Deltastation's firing range has been decommisioned and replaced with a - brand new toxins burn chamber. - - bugfix: Delta toxins disposals are now actually connected to the disposals loop. - Toxins storage has a fire alarm too. - - bugfix: The shutter buttons of Pubbystation's mechbay now check for access. - SpaceManiac: - - bugfix: The robustness of the Super Secret Room has been increased. - - bugfix: Observers can no longer move the action button toggle or change the ambient - occlusion setting of their targets. - - bugfix: The emergency space suit safes in escape pods are no longer always unlocked. - Tlaltecuhtli: - - bugfix: apiaries from cargo start unwrenched -2018-05-29: - Dennok: - - rscadd: Collectors show their real produced power and stored power when examined - Naksu: - - code_imp: removed some unneeded typecaches -2018-05-31: - CitrusGender: - - bugfix: Flamethrowers are no longer uncraftable since they have a part that happens - to be a tool. - - bugfix: Fixes cyborgs not being able to use two-handed modules while other modules - are equipped. - CosmicScientist: - - rscdel: Can't make drones anymore - Cruix: - - rscadd: AIs now have an experimental multi-camera mode that allows them to view - up to six map areas at the same time, accessible through two new buttons on - their HUD. - Cyberboss: - - config: The limit of monkey's spawned via monkey cubes is now configurable - Dax Dupont: - - bugfix: Fixes the wrong tiles in Syndicate VR trainer and uses different tiny - fans. - - bugfix: Access didn't append to VR IDs - Firecage: - - rscadd: The mech fabricator can now print two new janiborg upgrades. Advanced - Mop and Trash Bag of holding. These two upgrades uses the advanced robotics - node. - SpaceManiac: - - bugfix: Changing UI Style preference now takes effect immediately rather than - next round. - - bugfix: Mindswapping with someone no longer gives you their UI style. - - bugfix: The destructive analyzer can once again be used to reveal nodes. - - spellcheck: Some references to "deconstructive analyzer" have been updated to - "destructive". - - tweak: Hulks and catpeople now show "Human-derived mutant" under "Species" when - health scanned. - - bugfix: Cyborg inventory slots once again unhighlight when a module is stowed. - deathride58: - - rscadd: Things that are capable of igniting plasma fires will now generate heat - if there's no plasma to ignite. Building a bonfire inside the station without - taking safety precautions is now a bad idea. - kevinz000: - - rscadd: Plasma specific heat is 500J/K*unit, everything else is 200 - zaracka: - - bugfix: The Spirit Realm rune no longer spawns a braindead cult ghost when attempting - to summon one after a player reaches the limit. -2018-06-01: - Big Tobacco: - - rscadd: Cheap lighters now come in four different shapes and Zippos can have one - of four different designs, collect them all and improve our sales! - - imageadd: All existing lighter sprites have been given a face-lift and the flames - are now subtly animated. - - tweak: Cheap lighters now use a fixed list of 16 colors to pick from instead of - using totally randomized colors. - - imageadd: Cigar cases have been tweaked to be a bit smaller and to have a modified - design. - - imageadd: Cohiba Robusto and Havanan cigars now use separate case sprites from - the generic premium cigar cases. - Dax Dupont: - - bugfix: Fixed rpeds throwing stock part rating related runtimes. - Naksu: - - code_imp: NODROP_1, DROPDEL_1, ABSTRACT_1 and NOBLUDGEON_1 have been moved to - item_flags - - tweak: brass handcuffs, meat hook and the chrono gun now conduct electricity. - Nichlas0010: - - bugfix: You can no longer use a soapstone infinitely - SpaceManiac: - - bugfix: Moving diagonally past delivery chutes, transit tube pods, &c. no longer - causes your camera to be stuck on them. - - refactor: The base machinery type is now anchored by default. - - bugfix: Pubby's auxiliary mining base now works again. - - bugfix: Cloning no longer breaks a character's connection to their family heirloom. - - bugfix: The overlay effects of cult flooring are now on the floor plane, fixing - their odd ambient occlusion appearance. - - bugfix: Beam rifle tracers no longer fall into chasms. - - bugfix: Vomiting on the same tile a second time no deletes the vomited reagents. - theo2003: - - bugfix: fixed the clockwork helmet not dropping to ground when used by non-clock - cultists -2018-06-03: - Denton: - - tweak: 'Pubbystation: Added a dual-port vent pump to the toxins burn chamber.' - - code_imp: Removed most airlock_controller/incinerator related varedits and replaced - them with defines/subtypes. - - tweak: The Deltastation toxins lab has its portable scrubber, air pump and intercom - back. - Naksu: - - bugfix: comms consoles now work in transit again, and no longer work in centcom - - code_imp: removed unnecessary getFlatIcons from holocalls - - bugfix: Screwdrivers and other items with overlays now show the proper appearance - of the item when attacking something with them, or when put on a tray. - Nichlas0010: - - bugfix: You now can't get multiple download objectives! - - tweak: RDs, Scientists and Roboticists can no longer get download objectives! - ShizCalev: - - bugfix: Fixed cigar cases & cigarette packets taking two inventory slots - - bugfix: Fixed cigar cases showing the wrong icon for the cigars inside them. - - bugfix: Fixed cigar cases & cigarette packets stating the wrong name of the cigar/cigarette - when removed via altclick. - - bugfix: Fixed items in pockets vanishing when a mob is monkeyized. - - bugfix: Fixed items in pockets vanishing when a mob is gorillized. - - bugfix: Fixed items in pockets vanishing when a mob is infected with a transformation - disease. - - bugfix: Fixed items in pockets not being properly deleted when a mob goes through - a recycler - - bugfix: Fixed items in pockets not being properly deleted when highlander mode - is enabled. - - bugfix: Fixed exploit allowing you to remove unremovable tanks from pockets. - - bugfix: Fixed items in pockets dropping when a mob is equipped with a new outfit. - - bugfix: Fixed items in pockets not being covered in blood when equipping the psycho - outfit. - SpaceManiac: - - bugfix: Switching mobs into/out of a mech (by VR, ghosting, or mindswap) no longer - improperly applies the mech's cursor. - ThatLing: - - bugfix: PDA style now gets loaded correctly. - cyclowns: - - bugfix: Fires no longer flicker back and forth like crazy - iskyp: - - tweak: switched the type of the space suit on the syndicate shuttle - theo2003: - - tweak: roboticists have access to R&D windoors - - bugfix: fixed hydroponics tray weed light staying on when removing weeds with - integrated circuits - yorpan: - - rscadd: Brain damage makes you say one more thing. -2018-06-04: - Beachsprites: - - imageadd: added directional beach sprites - MrDoomBringer: - - admin: Central Command can now smite misbehaving crewmembers with supply pods - (filled with whatever their hearts desire!) - SpaceManiac: - - bugfix: Atom initialization and icon smoothing no longer race, causing late-loading - mineral turfs to have no icon. - - spellcheck: Faceless persons no longer "melt their face off" in energy gun suicides. - - bugfix: The Lightning Bolt spell now works again. - yenwodyah: - - bugfix: A few virus threshold effects should work now -2018-06-06: - Dax Dupont: - - bugfix: Fixes a sentience related exploit by blacklisting it in restricted uplinks. - Denton: - - rscadd: Arcades have been stocked with preloaded tactical snack rigs. - - bugfix: Swarmers can no longer attack field generators and turret covers. - - bugfix: The Pubbystation maint bar Booze-O-Mat now shows its contents correctly. - MrDoomBringer: - - admin: CentCom Supplypods now stun their target before landing, and won't damage - the station as much - Naksu: - - code_imp: moved /datum.isprocessing into datum flags - iksyp: - - bugfix: Ever since the great emotion purge of 2558, people were able to work at - top efficiency, even while starving to death. This is no longer the case, Nanotrasen - Scientists say. - - admin: Hunger slowdown only applies if mood is disabled in the config. -2018-06-07: - Cruix: - - bugfix: Picture-in-picture objects now are no longer overlapped by other certain - objects - SpaceManiac: - - bugfix: It is now possible to access the wires of RND machines in order to repair - them if they have been EMP'd. - Tlaltecuhtli: - - bugfix: rad collectors set to research point gen are somewhat ok now - kevinz000: - - tweak: Vehicle speed changes now happen immediately instead of on the next movement - cycle -2018-06-08: - AnturK: - - code_imp: Gravity can now go above 1g - CitrusGender: - - imageadd: sandstone wall sprite for indestructible object - Denton: - - tweak: Added a warning to the shuttle purchase menu. - - bugfix: Added missing vents to runtimestation. - - tweak: 'Runtimestation: Added /debug EMP flashlight, emag, techfab and tiny fans. - Replaced RCD, healing wand and sleeper with more suitable subtypes.' - MrDoomBringer: - - tweak: Due to DonkCo's recent budget cuts, their line of toy emags are now noticably - less realistic. As such, you can now examine an emag to determine if it is a - toy or not. - Naksu: - - balance: Temperature gun projectiles now respect armor/dodge, and will no longer - freeze you if they don't hit you. - SpaceManiac: - - bugfix: The thermal sight benefits of lantern wisps no longer disappear if you - change glasses. - - bugfix: Paradox bags no longer block the middle of your screen until reconnect, - and also actually work. - - bugfix: A pAI dying while in holoform no longer deletes the card, instead merely - emptying it. - - bugfix: The elevators in the Snowdin away and VR missions work again. - - bugfix: Minor atmos issues in Snowdin and UO45 have been corrected. - Tlaltecuhtli: - - bugfix: all spiders can make webs now - deathride58: - - balance: Sparks, using welding tools, using igniters, etc, will no longer cause - an instant fireless inferno in small rooms. - - tweak: The revert of the original hotspot_expose() PR has been reverted, since - the reason as to why it was reverted was resolved with this change. - - balance: Reverted the increased rad collector tech point gain rate. - fludd12: - - rscadd: Love potions are marginally more interesting! This same effect applies - to if you are a valentine! - - tweak: The names of extracts are now in the proper order, finally! - - rscadd: Self-sustaining extracts are in! Technically, this is a fix, but whatever. - - bugfix: Stabilized Cerulean extracts no longer vaporize items into the Aetherium. - - rscadd: Stabilized Gold extracts are now moderately more fun to use! The randomized - creature persists if it is killed, and can be rerolled at will! Also, if you - give the creature a sentience potion, the mind will transfer over! - oranges: - - rscadd: Sec now has khaki pants for tacticoolness -2018-06-11: - Mickyan: - - rscadd: Added an abandoned kitchen to Metastation maintenance - XDTM: - - bugfix: Fixed anti-magic not working at all. - fludd12: - - bugfix: Stabilized gold extracts now respawn the familiar properly. - - bugfix: Stabilized gold familiars retain the proper languages even after respawning. - - tweak: Stabilized gold familiars can be renamed and have their positions reset - at will. -2018-06-12: - Dax Dupont: - - bugfix: Botany trays don't magically refill anymore with a rped. - SpaceManiac: - - tweak: Fire alarms now redden all the room's lights, and emit light themselves, - rather than applying an area-wide overlay. - - bugfix: Fire alarms no longer visually conflict with radiation storms. - - bugfix: Pulling objects diagonally no longer causes them to flail about when changing - directions. - - bugfix: Riders are no longer left behind if you move while pulling something that - has since been anchored. - - bugfix: Lockboxes are now actually locked again. - - bugfix: Deaf people can no longer hear cyborg system error alarms. - - bugfix: Plasmamen now receive their suit and internals when entering VR. - - bugfix: Legion cores and admin revives now heal confusion. - XDTM: - - bugfix: Diseases now properly lose scan invisibility if their stealth drops below - the required threshold. -2018-06-13: - 'Armhulen code, Keekenox sprites and S_____ as the ideas guy :roll_eyes:': - - rscadd: 'New drinks: Peppermint Patty and the Candyland Extract!!' - CitrusGender: - - bugfix: checks to see if bullets are deleted if they are the ammo type and the - bullet chambered. - Dax Dupont: - - balance: It's now easier to become fat. Don't eat so much. - Mickyan: - - bugfix: Fixed pacifists being able to harm using bottles/screwdrivers - SpaceManiac: - - spellcheck: Capitalization, propriety, and plurality on turfs have been improved. - XDTM: - - tweak: Coldproof mobs can now be cooled down, but are still immune to the negative - effects of cold. - - bugfix: This also fixes some edge cases (freezing beams) where mobs could be cooled - down and damaged despite cold resistance. - - balance: Virus crates now contain several bottles of randomly generated diseases - with symptom levels up to 8. - - rscdel: Removed the single-symptom bottles that were included in the virus crate. - - balance: Androids are now immune to radiation. - cacogen: - - rscadd: You can now see what other people are eating or drinking. - - rscadd: Borg shaker can now synthesise milk, lemon juice, banana juice and coffee - - bugfix: Renamed drinks no longer revert to their original name when their reagents - change - chesse20: - - rscadd: Adds Exotic Corgi Crate to Cargo - - rscadd: Adds Exotic Corgi, a Corgi with a random hue applied to it - - rscadd: Adds Talking Corgi Crate, and talking Corgi -2018-06-15: - CitrusGender: - - bugfix: logs will now show ckeys when admin transformations are done - Cruix: - - bugfix: Item attack animations can no longer be seen over darkness or camera static. - Dax Dupont: - - admin: You can now send messages as CentCom through people's headsets. - - bugfix: Fixes missing cream pies in the cream pie fridge. - Denton: - - bugfix: 'Omegastation: Connected the Engineering Foyer APC to the powernet.' - - bugfix: 'Pubbystation: Connected Chemistry disposals to the pipenet and fixed - Booze-O-Mat related display/access issues.' - - tweak: Syndicate stormtroopers now fire buckshot again. - Naksu: - - bugfix: Pipe dispensers can no longer create pipes containing literally anything - Nichlas0010: - - tweak: The TEG and its circulator can now be deconstructed and rotated! - - tweak: The TEG and its circulator now supports circulators in all directions, - rather than just west/east! - SpaceManiac: - - rscadd: A new OOC verb "Fit Viewport" can be used to adjust the window splitter - to eliminate letterboxing around the map. It can also be set to run automatically - in Preferences. - - bugfix: Refunding nuclear reinforcements while polling ghosts no longer summons - the reinforcements into the error room anyways. - - bugfix: Shift-clicking turfs obscured by fog of war no longer lets you examine - them. - - admin: It is now possible to cancel "Manipulate Organs" midway through. - Tlaltecuhtli: - - rscadd: Added shoes to leather recipes - ninjanomnom: - - bugfix: Gas overlays left over in some turf changes should no longer stick around - where they shouldn't. -2018-06-17: - Dax Dupont: - - refactor: Syndicate and Centcom messages have been squashed together. - - admin: You can now send both Syndicate and Centcom headset messages. Be mindful - that the button was changed to HM in the playerpanel - - bugfix: Fixed missing grilles under brig windows of the pubby shuttle. - - rscadd: For the pubby shuttle, added some food in the fridge, mostly pie slices. - Also added a sleeper to the minimedbay. - - tweak: Reworded pubby shuttle description to be more inline with the new train - shuttle. - - bugfix: Chem synths overlays aren't all kinds of fucked anymore. - - refactor: Unfucked all of the remaining chem synth code. - - refactor: Reagents no longer have an unused var that's always set to true. Who - did this? - - bugfix: You can no longer remove circuits with your mind. - - balance: Makes the xeno nest ruin harder to cheese. - - bugfix: Fixes the bathroom being airless in the Space Ninja anime jail. - Denton: - - tweak: 'Runtimestation: Added shuttle docking ports, a comms console, cargo bay - and syndicate/centcom IDs.' - - balance: Pirates and Syndicate salvage workers have been beefed up around the - caravan ambush ruin. - Pubby: - - bugfix: 'PubbyStation: Fixed disposals issue in security hallway' - SpaceManiac: - - bugfix: Moving large amounts of items with bluespace launchpads no longer creates - a laggy amount of sparks. - - bugfix: Unbreakable ladders are now left behind when shuttles move. - - bugfix: It is no longer possible to pull the mirages images at space transitions, - and some other abstract effects. - - tweak: PDAs and radios with unlocked uplinks no longer open their normal interface - in addition to the uplink when activated. - - tweak: Nuclear operative uplinks are no longer also radios. - - bugfix: The mining shuttle can once again fly to the aux base construction room - after the base has dropped. - - bugfix: The escape pod hallways on MetaStation and DeltaStation now have air again. - - bugfix: Hyperspace ripples now remain visible until the shuttle arrives, even - during extreme lag. - - bugfix: Ripples now correctly take the shape of the shuttle, rather than always - being a rectangle. - - bugfix: Non-secure windoors now properly support the "One Required" access mode - of airlock electronics. - Tlaltecuhtli: - - rscadd: After years of protests NT decided to update the fire security standards - by adding 3 (three) advanced fire extinguishers to all the new stations. - and Fel: - - imageadd: New chairs are on most shuttles! Finally, you can relax in style while - escaping a metal death trap. - cyclowns: - - rscadd: Fusion has been re-enabled! It works similarly to before, but with some - slight modification. - - tweak: Fusion now requires huge amounts of plasma and tritium, as well as a very - high thermal energy and temperature to start. There are several tiers of fusion - that cause different benefits and effects. - - tweak: The fusion power of most gases has been tweaked to allow for more interesting - interactions. - - tweak: BZ now takes N2O and plasma to create, rather than tritium and plasma. - - bugfix: Fusion no longer delivers server-crashingly large amounts of radiation - and stationwide EMPs. - theo2003: - - rscadd: Players who edited a circuit assembly can scan it as a ghost. -2018-06-18: - CitrusGender: - - tweak: The blob core (and only the blob core) now respawns randomly on the station - when the core is taken off z-level - - bugfix: Prevents the round from going into an unending state - - code_imp: Added a variable to the stationloving component for objects that can - be destroyed but not moved off z-level - Denton: - - tweak: NanoTours is proud to announce that the Lavaland beach club has been outfitted - with a dance machine, state of the art bar equipment and more. - SpaceManiac: - - bugfix: It is no longer possible to repair cyborg headlamps even when their panel - is closed. - - bugfix: Item fortification scrolls no longer add multiple prefixes when applied - to the same item. - - bugfix: The gulag shuttle no longer moves instantly when returned via the claim - console. - - admin: It is now possible to use the ".p" (Asay) and ".d" (Dsay) prefixes while - an admin ghost. -2018-06-19: - Cyberboss: - - admin: Speaking in deadchat now shows your rank instead of ADMIN - Dax Dupont: - - balance: Circuit lab no longer starts with super batteries, they have been replaced - with high batteries. - - balance: Circuit labs now start with 20 sheets of metal instead of 50/100. Plenty - of materials on the station you can gather. - - balance: Circuit labs no longer have their own protolathe and autolathe. Science - has their own lathes already. - - tweak: There's no more entire library worth of equipment, they can go publish - the books like the rest of the station, in the library. At least give the librarians - something other to do than screaming about lizard porn on the radio. - Hyacinth-OR: - - rscadd: Added a pink scarf to vendomats - Irafas: - - rscadd: Players can now ctrl-click the PDA to remove the item in its pen slot - JStheguy: - - rscadd: Added the data card reader circuit, a circuit that is able to read data - cards, as well as write to them. - - tweak: Data cards are now longer inexplicably called data disks despite clearly - being cards, and can be printed from the "tools" section of the integrated circuit - printer. - - tweak: Data cards no longer have a special "label card" verb and instead can have - their names and descriptions changed with a pen. - - rscadd: Also, some aesthetically different variants of the data cards, because - why not. - - imageadd: Data cards have new sprites, with support for coloring them via the - assembly detailer. - Naksu: - - code_imp: Sped up atmos very slightly - ninjanomnom: - - rscadd: A plush that knows too much has found its way to the bus ruin. -2018-06-21: - BlueNothing: - - tweak: Grabbers can no longer hold circuit assemblies - CitrusGender: - - bugfix: Ruins air alarms will no longer be reported in the station tablets - - bugfix: added a clamp so you can't set a negative multiplier to create materials - and create more than 50 items. - Cobby: - - rscdel: Removed Advanced Mining Scanner from roundstart voucher kits. - - rscdel: Removed Explorer Webbing from all voucher kits besides the shelter capsule - pack. - Denton: - - bugfix: The public booze-o-mats and autodrobes on Box/Delta/Meta now have no access - requirements, as previously intended. - - rscadd: Regular and advanced health analyzers can now be researched and printed. - McDonald072: - - rscadd: A few new circuits for dealing with atmospherics have been uploaded to - your local printers. - NewSta: - - tweak: made it easier to see from the back whether someone is occupying the shuttle - chair or not. - SpaceManiac: - - tweak: One canister is now suitable to fully stock a vending machine. Relevant - cargo packs have been updated. - - bugfix: Deconstructing and reconstructing a vending machine no longer creates - items from thin air. - - bugfix: Using a part replacer on a vending machine no longer empties its inventory. - - rscadd: Bluespace RPEDs can now be used to refill vending machines. - Tlaltecuhtli: - - bugfix: anomaly cores no longer tend to dust - YPOQ: - - bugfix: Watcher beams will freeze you again -2018-06-23: - Dax Dupont: - - imageadd: CHANGE PLACES, SHUTTLE CHAIRS HAVE BEEN CHANGED AGAIN. - - admin: Create antags now checks for people being on station before applying. - ExcessiveUseOfCobblestone: - - spellcheck: Plant disks with potency genes clarify the percent is for potency - scaling and not relative to max volume on examine. - Kor: - - rscadd: Bubblegum has regained his original (deadlier) move set. - SpaceManiac: - - bugfix: Fire extinguishers on the emergency shuttle are no longer unclickable - once removed from their cabinets. - kevinz000: - - rscadd: Blast cannons have been fixed and are now available for purchase by traitorous - scientists for a low low price of 14TC. - - rscadd: 'Blast cannons take the explosive power of a TTV bomb and ejects a linear - projectile that will apply what the bomb would do to a certain tile at that - distance to that tile. However, this will not cause breaches, or gib mobs, unless - the gods (admins) so will it. experimental: Blast cannons do not respect maxcap. - (Unless the admins so will it.)' -2018-06-24: - CitrusGender: - - bugfix: Fixed cyborgs not getting their names at round start - - bugfix: Fixed cyborgs and A.I.s being able to bypass appearance bans - SpaceManiac: - - bugfix: The "Save Logs" option in the chat now actually works (IE 10+ only). - Time-Green: - - bugfix: Soda is no longer intangible to the laws of physics - cinder1992: - - rscadd: The Captain can now go down with their station in style! Suicide animation - added to the Officer's Sabre. - kevinz000: - - rscadd: Cyborgs now drop keys on deconstruction/detonation -2018-06-27: - Cyberboss: - - server: Logs and admin messages will now appear when you are using deprecated - config settings and advise on upgrades - Dax Dupont: - - admin: Malf AI machine overloads now are logged/admin messaged. - - tweak: The tree of liberty must be refreshed from time to time with the blood - of patriots and tyrants. We've removed access requirements from liberation station - vendors. - - bugfix: Fixes more href exploits in circuits - - refactor: Printing premade assemblies is no longer shitcode, time remaining had - to go for this. - - admin: Filled holes in the logging of circuits - Denton: - - tweak: Camera networks, monitor screens and telescreens have been standardized. - - tweak: Motion-sensitive cameras now show a message when they trigger the alarm. - - bugfix: The Box/Meta auxillary base camera now works. - - bugfix: Bomb test site cameras now emit light, as intended. - - bugfix: 'Meta: Replaced the RD telescreen in the CE office with the correct one.' - - tweak: Did you know that honey has antibiotic properties? - Irafas: - - bugfix: Hardsuit helmets now protect the wearer from pepperspray - - bugfix: Bucket helmets cannot have reagents transferred into them until after - they are removed - MadmanMartian: - - bugfix: Cameras that are EMPed no longer sound an alarm - Mickyan: - - bugfix: Branca Menta won't make you starve and then kill you - - tweak: Fernet has been moved to contraband - Naksu: - - code_imp: Removed unused effect object that could be used to spawn a list of humans - Nichlas0010: - - bugfix: Mothpeople no longer push objects to move in 0-grav, if they can fly - SpaceManiac: - - refactor: AI static now uses visual contents and should perform better in theory. - - bugfix: Pocket protectors now work again. - - bugfix: URLs are no longer auto-linkified in character names and IC messages. - - bugfix: It is once again possible for Cargo to export mechs. - - bugfix: Deaths in the CTF arena are no longer announced to deadchat. - Tlaltecuhtli: - - tweak: tourettes doesnt stack on itself anymore - - bugfix: fixes cult shuttle message repeating - Zxaber: - - rscadd: Cyborgs can wear more hats now. - kevinz000: - - rscadd: R&D deconstructors can now destroy things regardless of if there's a point - value or material - nichlas0010: - - bugfix: You should now receive your destroy AI objectives properly during IAA -2018-06-28: - Anonmare: - - balance: The possessed chainsword no longer makes e-swords look pathetic - Dax Dupont: - - admin: Admins can now scan circuits if they have admin AI interaction enabled. - - admin: some more circuit logging - - rscadd: You can now build clown borgs with a little bit of bananium and research. - Praise be the honkmother. - - rscadd: New upgrade module has been added so making loot/tech web borg modules - has become easier for admins/mappers/coders. - - refactor: Unused and broken OOC metadata code has been killed. - Denton: - - tweak: Added a disk compartmentalizer to Omegastation's hydroponics. - Kraso: - - bugfix: You can no longer use a soulstone shard to tell who's a cultist. - ShizCalev: - - bugfix: The blob will no longer take over space/mining/ect upon victory. -2018-06-29: - BlueNothing: - - balance: Cavity implants can no longer hold normal-sized combat circuits. Grabbers - can now hold up to assembly size. - - bugfix: Grabbers and throwers no longer function inside of storage implants. - Denton: - - tweak: Added all-in-one tcomms machinery and an automated announcement system. - Mickyan: - - imageadd: graffiti letters and numbers have received a makeover - MrDoomBringer: - - imageadd: Disk Fridges now have sprites! Ask cobby if you're wondering why they - look like toasters. -2018-06-30: - Dennok: - - bugfix: Deconstructable TEG now propertly connects to pipes. - - bugfix: Fix of inverted TEG sprite of slow turbine turning. add:Now you can flip - circulator and make TEG of your dream. add:Add TEG and circulator to "Advanced - Power Manipulation" techweb node. - MacHac: - - rscadd: Changelings can now take the Pheromone Receptors ability to hunt down - other changelings. - TerraGS: - - imageadd: New icon for plastic flaps that actually looks airtight. - - code_imp: Update to plastic flaps code to use tool procs rather than attackby - and removed two pointless states. -2018-07-01: - Denton: - - tweak: To comply with space OSHA regulations, all toasters (disk compartmentalizers) - have been put on tables. - - rscadd: Added a disk compartmentalizer to the seed vault Lavaland ruin. - Nichlas0010: - - bugfix: Changelings can now greentext the extract more genomes objective. - Thunder12345: - - rscadd: Added a colour picker component for use with circuits. -2018-07-02: - AnturK: - - bugfix: non-player monkeys won't fight when stunned. - Denton: - - bugfix: 'Pubbystation: Fixed the QM camera console''s direction.' - - code_imp: 'Pubbystation: Used the correct aux bomb camera subtype and replaced - loose tech storage boards with spawners, as is done in the rest of the map.' - - tweak: Tesla balls no longer blow up disposal outlets/delivery chutes and cameras. - Irafas: - - rscadd: Admin spawnable Death Ripley that comes with a version of the Death Clamp - that actually inflicts damage and rips arms off. - Naksu: - - admin: maxHealth is now guarded against invalid values when varediting - SpaceManiac: - - bugfix: A single wired glass tile no longer creates unlimited light floor tiles. - - bugfix: Printing the TEG and circulator boards no longer prints the completed - machinery instead. - XDTM: - - tweak: Nutriment Pump implants no longer require replacing the stomach. -2018-07-03: - Dax Dupont: - - balance: BoH detonations now gib the user. - Denton: - - tweak: Engine heaters no longer let gases pass through them. - - tweak: The Cerestation escape shuttle is now available for purchase! - Frozenguy5: - - bugfix: Fixes nitryl gas not applying its effects. - MrDoomBringer: - - bugfix: SupplyPod smites work properly once again. - Naksu: - - code_imp: Fixed the signatures of several reagent procs, removing useless checks - - tweak: drunkenness is now handled at the carbon level, allowing monkeys to experience - ethanol - - balance: initropidil also works on carbon level, allowing syndicate operatives - using the poison kit to achieve the silent assassin rating against monkeys - - tweak: The ladders in the tear in the fabric of reality no longer spawn their - endpoints when the area is loaded, but only when the tear is made accessible - via a BoH bomb. - - tweak: CentCom is no longer accessible via the space ladder in the tear. - - tweak: The lavaland endpoint can no longer spawn completely surrounded by lava, - unless it spawns on an island - - code_imp: ChangeTurf can now conditionally inherit the air of the turf it is replacing, - via the CHANGETURF_INHERIT_AIR flag. - - bugfix: when ladder endpoints are created, the binary turfs that are created inherit - the air of the turfs they are replacing. This means the lavaland ladder endpoint - will have the lavaland airmix, instead of a vacuum. - - code_imp: navigation beacons are now properly deregistered from their Z-level - list and re-registered on the correct one if moved across Z-levels by an effect - such as teleportation or a BoH-induced chasm. - Nirnael: - - refactor: Removed an unnecessary volume_pump check - SpaceManiac: - - bugfix: Backpack water tanks now work properly when wielded by drones. - - bugfix: Backpack water tank nozzles can no longer be placed inside bags of holding - and chem dispensers. - - bugfix: Moving items between your hands no longer causes them to cross the floor - (squeaking, lava burning). - - bugfix: Scrambled research console icons have been fixed, and will be prevented - in the future. - Zxaber: - - tweak: Empty cyborg shells can now be disassembled with a wrench. - - tweak: Using a screwdriver on an empty shell will now remove the cell, or swap - it if you're holding a cell in your other hand. - ninjanomnom: - - tweak: Shuttle throwing also applies to loose objects on shuttles now. - - tweak: Closets on shuttles start anchored. - - tweak: The throw distance of shuttle throws is marginally random, potentialy 10% - further or shorter - - rscadd: Tables and racks on shuttles have been installed with inertia dampeners. - - bugfix: Some very thin barriers didn't stop mobs from being thrown by the shuttle - under certain circumstances, this has been fixed. -2018-07-05: - Cyberboss: - - bugfix: Setting "default" in maps.txt now will load that map as the first fallback - when a next_map.json is missing - Jared-Fogle: - - bugfix: Fixed the "Remove IV Container" verb on IV drips from showing every nearby - mob - Naksu: - - tweak: shuttles now move the air along with their occupants, instead of magicking - up new air. - deathride58: - - tweak: Lone nuclear operatives now spawn as often as originally intended when - the disk is immobile. Secure that fuckin' disk. -2018-07-06: - Denton: - - spellcheck: Improved supply shuttle messages and firefighting foam descs. - - bugfix: Supply shuttles will no longer spill containers on docking. - Jared-Fogle: - - imageadd: Medical HUDs will now show an icon if the body has died recently enough - to be defibbed - Jegub: - - imageadd: Glowcaps now have their own sprite. - MacHac: - - bugfix: Bedsheets once again properly influence the dreams of those who sleep - under them. -2018-07-07: - Cruix: - - bugfix: Advaced camera consoles now properly show camera static in the area that - the eye starts - Denton: - - bugfix: Cere Station's escape shuttle has had its turbo encabulator replaced and - should no longer fly through hyperspace backwards. - Garen: - - rscadd: sends a signal for afterattack() - - code_imp: modified all calls of afterattack() to call the parent proc - Naksu: - - bugfix: constructed directional windows no longer leak atmos across them - - code_imp: setting the value of anchored for objects should be done via the setAnchored - proc to properly handle things like atmos updates in one place - Spaceinaba: - - tweak: Digitigrade legs no longer revert to normal on compatible outfits. -2018-07-08: - Affurit: - - imageadd: Back Sprites for the Godstaffs and Scythe now exist. - Cruix: - - rscadd: AI detection multitools can now be toggled to provide a HUD that shows - the exact viewports of AI eyes, and the location of nearby camera blind spots. - Floyd: - - rscdel: removed beauty / dirtyness - - balance: Mood no longer gives you hallucinations, instead makes you go into crit - sooner - Gwolfski: - - rscadd: autoname APC - - rscadd: directional autoname APC's - Naksu: - - code_imp: fixed mood component - XDTM: - - bugfix: Corazone now actually stops heart attacks. - cacogen: - - rscadd: Gibs squelch when walked over - subject217: - - bugfix: Five months later, wires will again make noise when pulsed or cut while - hacking. -2018-07-09: - Ausops: - - imageadd: New shuttle chair sprites. - Jared-Fogle: - - bugfix: Fixed russian revolvers acting like normal revolvers. - Nabski: - - imageadd: Crabs have a movement state sprite - TerraGS: - - tweak: Removed tap.ogg from multitool so getting hit by one sounds as painful - as it really is. - ninjanomnom: - - code_imp: The very back-end of movement got some significant reshuffling in preparation - for some future refactors. Bugs are expected. - subject217: - - spellcheck: The Nuke Op uplink no longer lies about how much ammo a C-20r holds. - - tweak: The L6 SAW now has a small amount of spread. It is still accurate within - visual range, but it's not as effective at longer ranges. -2018-07-10: - Astatineguy12: - - bugfix: You can now buy energy shields as a nuke op again - Denton: - - rscadd: 'Box/Delta/Pubbystation: Nuclear explosive-shaped beerkegs have been added - to maintenance areas.' - Naksu: - - rscadd: Added a new ghost verb that lets you change your ignore settings, allowing - previously ignored popups to be un-ignored and notifications without an ignore - button to be ignored - - bugfix: Chaplains are once again unable to acquire the inquisition ERT commander's - sword, as intended. The sword has been restored to its former glory - Supermichael777: - - bugfix: Changelings are no longer prevented from entering stasis by another form - of fake death. - Wjohnston & ninjanomnom: - - imageadd: Engine heaters and engines have had a minor touch up so they don't meld - with the floor quite so much. - - tweak: Engine heaters don't block air anymore. - XDTM: - - bugfix: Romerol tumors no longer zombify you if you're alive when the revive timer - counts down. -2018-07-11: - Denton: - - bugfix: Fixed a bug where golem shells couldn't be completed by certain brass/sandstone/titanium - stacks. - - tweak: The Spider Clan holding facility has completed minor renovations. The dojo - now includes medical and surgical equipment, while the lobby has a fire extinguisher - and plasmaman equipment. - - bugfix: Plasma and wooden golems no longer need to breathe, same as all other - golems. - - spellcheck: Fixed wrong or incomplete golem spawn info texts. - - tweak: Added more random golem names. - Irafas: - - bugfix: non-silicons can no longer use machines without standing next to them. - XDTM: - - bugfix: Automatic emotes no longer spam you saying that you can't perform them - while unconscious. - - rscadd: Added a Rest button to the HUD. It allows the user to lie down or get - back on their feet. - - balance: Getting back up now takes a second, to avoid people matrix-ing bullets. - fludd12: - - rscadd: You can now craft wooden barrels with 30 pieces of wood! They can hold - up to 300u of reagents. - - rscadd: Putting hydroponics-grown plants into the barrel lets you ferment them - for alcohol! Some give bar drinks, while others simply give plain fruit wine. - ninjanomnom: - - bugfix: Porta turret rotation on shuttles visually would not turn, this has been - dealt with. - - bugfix: Decals weren't rotating properly after the recent signal refactor, a couple - new procs for dealing with the signals on the parent object have been added - to deal with this. - subject217: - - balance: L6 SAW AP ammo now costs 9 TC per magazine, up from 6. - - balance: L6 SAW incendiary ammo now deals 20 damage per shot, up from 15. -2018-07-12: - AnturK: - - bugfix: Nuclear rounds will now end properly on nukeop deaths if there are no - other antags present. - Denton: - - rscadd: A new shuttle loan event has been added. Hope you like bees! - - tweak: The pizza delivery shuttle loan event now has some of each flavor and no - longer pays the station for accepting it. - - balance: Syndicate shuttle infiltrators now carry suppressed pistols. - - spellcheck: Added a missing period to spent bullet casing and pizza shutte loan - text. - - bugfix: Zealot's blindfolds now properly prevent non-cultists from using them. - - bugfix: Cultist legion corpses now wear the correct type of zealot's blindfold. - Time-Green: - - rscadd: An overdosing chemist filled the maintenance shafts with unorthodox pills, - be wary - ninjanomnom: - - rscadd: Certain objects which make noise which are thrown in disposals will squeak - when they hit bends in the piping. This includes clowns. - tralezab: - - admin: admins, you can now find martial art granting buttons in your VV dropdown. -2018-07-13: - Arithmetics plus: - - rscadd: Min circuit - - rscadd: Max circuit - Cyberboss: - - rscadd: More interesting recipes to the pizza delivery event - Deepfreeze2k: - - balance: Adds 2 carbon dioxide jetpacks to the pirate ship. Also gives the captain - a renamed bottle of rum in his room. - Denton: - - tweak: 'Most static ingame manuals have been replaced with ones that open relevant - wiki articles. remove: Deleted the "Particle Accelerator User''s Guide" manual, - since it''s included in the Singulo/Tesla one.' - - tweak: Machine frames no longer explode when struck by tesla arcs. - - rscadd: Locators can now be researched and printed at the security protolathe. - Jared-Fogle: - - soundadd: Removed delay from rustle1.ogg - LetterN: - - rscadd: Adds ratvar plushie and narsie plushie on chaplain vendors - Naksu: - - bugfix: deep-frying no longer turns certain objects like limbs invisible - Time-Green: - - bugfix: "Fixes an href exploit that lets you grab ID\u2019s out of PDA right from\ - \ another person" - XDTM: - - balance: (Real) Zombies no longer die from normal means. They will instead go - into crit indefinitely and regenerate until they get back up again. To kill - a zombie permanently you either need to remove the tumor, cut off their head, - gib them, or use more elaborate methods like a wand of death or driving them - to suicide. - - balance: Slowed down zombie regeneration overall, since putting them in crit now - no longer disables them for a full minute in average. - Zxaber: - - bugfix: MMI units inside cyborgs are no longer affected by ash storms. - ninjanomnom: - - bugfix: Objects on tables that are thrown by shuttle movement should no longer - do a silly spin - - balance: The alien pistol and the xray gun have both received a much belated buff - to their radiation damage to be on par with other sources of radiation. -2018-07-14: - Naksu: - - balance: stamina damage is no longer softcapped by the unconsciousness trigger - lowering stamina damage a little bit - ShizCalev: - - tweak: "The SM is now even more deadly to \"certain mobs\"\u2122" -2018-07-15: - AnturK: - - tweak: You can now use numbers in religion and deity names - Denton: - - bugfix: Bounty console circuit boards no longer construct into supply request - terminals. - Naksu: - - bugfix: fixed some missing args in emote procs called with named args, leading - to runtimes - - code_imp: removed unnecessary processing from a few machine types - SpaceManiac: - - bugfix: The Shuttle Manipulator admin verb works once more. -2018-07-16: - kevinz000: - - rscadd: 'Integrated circuit clocks now come in 3 flavors: Nanotrasen time (round - time), Station time (station time), and Bluespace time (server time, therefore - not affected by lag/time dilation)' - - rscadd: Integrated circuit clocks now also output a raw value for deciseconds, - allowing for interesting timer constructions. -2018-07-17: - Cyberboss: - - server: Added BSQL.dll and updated libmariadb.dll for non-blocking SQL support. - See https://github.com/tgstation/BSQL for instructions on building for non-windows - systems - Denton: - - tweak: Sparks now emit less heat. - - tweak: Added a storage room to Metastation engineering that both engineers and - atmos techs can access. - Naksu: - - admin: Plasma decontamination can now be triggered via events - - bugfix: Reebe is no longer airless and completely broken - Shdorsh: - - tweak: added UI to the circuit printer. That's all - XDTM: - - balance: Limbs no longer need to have full damage to be dismemberable, although - more damage means higher dismemberment chance. - - balance: Damaging limbs now only counts as 75% for the mob's total health. Bleeding - still applies normally. - - rscadd: Limbs that reach max damage will now be disabled until they are healed - to half health. - - rscadd: Disabled limbs work similarly to missing limbs, but they can still be - used to wear items or handcuffs. - kevinz000: - - rscadd: Crew pinpointers added to advanced biotechnology, printable from medical - lathes. - - rscadd: AIs can now interact with smartfridges by default, but by default they - will not be able to retrieve items. - ninjanomnom: - - bugfix: Mech equipment can be detached again. This probably also fixes any other - uncaught bugs relating to objects moving out of other objects. -2018-07-18: - Cyberboss: - - bugfix: Deaths now lag the server less - - bugfix: Ban checks cause less lag - Denton: - - tweak: RCDs can now also be loaded with reinforced glass and reinforced plasma - glass sheets. - Irafas: - - bugfix: players can construct while standing on top of a directional window. (machine - frames, computer frames, etc) - MrStonedOne: - - bugfix: synchronizing admin ranks with the database now lags the server less - - bugfix: saving stats now lags the server less - - bugfix: jobexp updating now lags the server less - - bugfix: poll creation now lags the server less. - Tlaltecuhtli: - - tweak: putting a cell and other not intended actions dont open the circuit window - WJohnston: - - tweak: Abandoned box ship space ruin consoles have been turned into something - more obviously broken so people stop complaining the ship doesn't work when - it's not meant to anyway. - - rscdel: Removed the extra syndie headset from the syndicate listening post space - ruin so people stumbling on the ruin won't be able to ruin your channel's security - as often. - XDTM: - - bugfix: Fixed a few bugs with imaginary friends, including them not being able - to hear anyone or surviving past the owner's death. - - rscadd: Imaginary friends can now move into the owner's head. - - rscadd: Imaginary friends can now choose to become invisible to the owner at will. -2018-07-20: - Cobby: - - bugfix: having higher sanity is no longer punished by making you enter crit faster - - balance: you can have 100 mood instead of 99 before it starts slowly decreasing - - bugfix: Paper doesn't give illegal tech anymore - CthulhuOnIce: - - spellcheck: Fixed 'Cybogs' in research nodes. - Denton: - - admin: Added hardsuit outfits for the Captain, HoS, and CMO. Removed old Shaft - Miner (Asteroid) outfits. Gave Chief Engineer (Hardsuit) engineering scanner - goggles. Added debug outfit for testing. - - tweak: Most wardrobe vendor contents have been tweaked. CargoDrobe now has the - vintage shaft miner jumpsuit available as a premium item. - WJohn: - - balance: Caravan ruin overall contains much less firepower, and should be harder - to cheese due to placement changes and less ammunition to work with. - - rscadd: The white ship is no longer stuck to flying around the station z level. - It can now fly around its own spawn's level and the derelict's level too (these - sometimes will be the same level). - kevinz000: - - rscdel: Removed flightsuits - zaracka: - - balance: Visible indications of cultist status during deconversion using holy - water happen more often. -2018-07-21: - Jared-Fogle: - - bugfix: Fixes destroyed non-human bodies cloning as humans. - WJohnston: - - balance: Reduced the 180 rounds (6 boxes) of 9mm ammo in the deep storage bunker - to 45 (3 mags). Removed one of the wt-550s but put a compatible magazine in - its place for the other to use. Turned the syndicate hardsuit into a regular - grey space suit. -2018-07-23: - BeeSting12: - - bugfix: Robotics' circuit printers have been changed to science departmental circuit - printers to allow science to do their job more efficiently. - Cruix: - - bugfix: AI eyes will now see static immediately after jumping between cameras. - Denton: - - rscadd: Shared engineering storage rooms have been added to Deltastation. - - bugfix: Fixed access requirements of lockdown buttons in the CE office. On some - maps, these were set to the wrong department. - - bugfix: Fixed Box and Metastation's CE locker having no access requirements. - - bugfix: 'Deltastation: Fixed engineers having access to atmospheric technicians'' - storage room. Fixed engineers having no access to port bow solars (the ones - at the incinerator by Atmospherics). Also fixed Minisat airlock access requirements.' - - bugfix: 'Pubbystation: Medbay and Cargo now have a techfab instead of protolathe.' - - tweak: Charlie/Delta Station (the "old cryogenics pod" ghost role) has been improved. - Survivors can now finish the singularity engine and will have more minerals - available inside the Hivebot mothership. The local atmos network is connected - to an air tank; fire alarms and a bathroom have been added. Keep an eye out - for a defibrillator too. - - rscadd: Nuclear Operatives can now purchase Buzzkill grenades for 5TC per box - of three. Those release a swarm of angry bees with random toxins. - - spellcheck: Chemical grenades, empty casings and smart metal foam nades now have - more detailed descriptions. - - spellcheck: Added examine descriptions to the organ harvester. - Epoc: - - rscadd: Adds "Toggle Flashlight" to PDA context menu. - Hathkar: - - tweak: Captain's Door Remote now has vault access again. - Mickyan: - - bugfix: 'Deltastation: replaced blood decals in maintenance with their dried counterparts' - SpaceManiac: - - tweak: RCDs can now be loaded partially by compressed matter cartridges rather - than always consuming the entire cartridge. - - bugfix: Fernet Cola's effect has been restored. - - bugfix: Krokodil's addition stage two warning message has been restored. - - admin: The party button is back. - WJohnston: - - bugfix: Fixed corner decals rotating incorrectly in the small caravan freighter. - XDTM: - - bugfix: Limbs disabled by stamina damage no longer appear as broken and mangled. - obscolene: - - soundadd: Curator's whip actually makes a whip sound now -2018-07-25: - Denton: - - tweak: H.O.N.K mechs can now play more sounds from the "Sounds of HONK" panel. - JJRcop: - - tweak: The item pick up animation tweens to the correct spot if you move - MrDoomBringer: - - spellcheck: Changed "cyro" to "cryo" in a few item descriptions and flavortexts. - SpaceManiac: - - rscadd: The vault now contains an ore silo where the station's minerals are stored. - - rscadd: The station's ORM, recycling, and the labor camp send materials to the - silo via bluespace. - - rscadd: Protolathes, techfabs, and circuit imprinters all pull materials from - the silo via bluespace. - - rscadd: Those with vault access can view mineral logs and pause or remove any - machine's access, or add machines with a multitool. - - tweak: The ORM's alloy recipes are now available in engineering and science protolathes. - Telecomms chat logging: - - code_imp: Added logging of telecomms chat - - config: Added LOG_TELECOMMS config flag (enabled by default) - WJohnston: - - rscadd: Redesigned deltastation's abandoned white ship into a luxury NT frigate. - Oh, and there are giant spiders too. - - bugfix: Med and booze dispensers work again on lavaland's syndie base, and the - circuit lab there is slightly less tiny. - subject217: - - rscadd: The M-90gl is back in the Nuke Ops uplink with rebalanced pricing. - - bugfix: The revolver cargo bounty no longer accepts double barrel shotguns and - grenade launchers. -2018-07-26: - Iamgoofball: - - bugfix: The shake now occurs at the same time as the movement, and it now doesn't - trigger on containers or uplinks. - Mickyan: - - balance: Light Step quirk now stops you from leaving footprints - Naksu: - - code_imp: gas reactions no longer copy a list needlessly - SpaceManiac: - - rscadd: 'The following machines can now be tabled: all-in-one grinder, cell charger, - dish drive, disk compartmentalizer, microwave, recharger, soda/booze dispenser.' - - rscadd: Unanchored soda/booze dispensers can now be rotated with alt-click. - - bugfix: Machinery UIs no longer close immediately upon going out of interaction - range. - - rscadd: Washing machines now wiggle slightly while running. - - rscadd: Washing machines can be unanchored if their panel is open for even more - wiggle. - WJohnston: - - rscadd: Return of the boxstation white ship, with a complete makeover! Box and - meta no longer share the same ship. -2018-07-27: - ShizCalev: - - bugfix: Destroying a camera will now clear it's alarm. - ninjanomnom: - - bugfix: The cargo shuttle should move normally again -2018-07-28: - CitrusGender: - - rscdel: Removed slippery component from water turf - Denton: - - balance: The Odysseus mech's movespeed has been increased. - - tweak: 'Metastation: Spruced up the RnD circuitry lab; no gameplay changes.' - - tweak: Due to exemplary performance, NanoTrasen has awarded Shaft Miners with - their very own bathroom, constructed at the mining station dormitories. Construction - costs will be deducted from their salaries. - Mickyan: - - imageadd: insanity static is subtler - - imageadd: neutral mood icon is now light blue - SpaceManiac: - - bugfix: Cyborgs and AIs can now interact with items inside them again. - Tlaltecuhtli: - - rscadd: Mouse traps are craftable from cardboard and a metal rod. - WJohnston: - - balance: Syndicate and pirate simple animals should have stats that more closely - resemble fighting a human in those suits, with appropriate health, sounds, and - space movement limitations. - - imageadd: Pirates in space suits have more modern space suits. -2018-07-30: - Anonmare: - - balance: Upload boards and AI modules, in addition to Weapon Recharger boards, - are now more expensive to manufacture - Basilman: - - bugfix: fixed BM Speedwagon offsets - Cobby (based off Wesoda25's idea): - - rscadd: Adds the PENLITE holobarrier. A holographic barrier which halts individuals - with bad diseases! - Denton: - - tweak: Techweb nodes that are available to exofabs by roundstart have been moved - to basic research technology. - - balance: Ripley APLU circuit boards are now printable by roundstart. - - balance: Odysseus, Gygax, Durand, H.O.N.K. and Phazon mech parts have to be researched - before becoming printable (same as their circuit boards). - - tweak: Arrivals shuttles no longer throw objects/players when docking. - - bugfix: Regular fedoras no longer spawn containing flasks. - - tweak: Increased the range of handheld T-ray scanners. - - balance: Cargo bounties that request irreplaceable items have been removed. - Garen: - - balance: Throwers no longer deal damage - - balance: Flashlight circuits are now the same strength as a normal flashlight - - balance: Grabber circuits are now combat circuits - - rscdel: Removed smoke circuits - - rscdel: Removed all screens larger than small - - tweak: Ntnet circuits can no longer specify the passkey used, it instead always - uses the access - Hate9: - - rscadd: Added pulse multiplexer circuits, to complete the list of data transfers. - Jared-Fogle: - - rscadd: NanoTrasen now officially recognizes Moth Week as a holiday. - - rscdel: Temporarily removes canvases until someone figures out how to fix them. - Mickyan: - - balance: Social anxiety trigger range decreased. Stay out of my personal space! - - bugfix: Social anxiety no longer triggers while nobody is around but you - WJohnston: - - rscadd: Redesigned the metastation white ship as a salvage vessel. - YoYoBatty: - - bugfix: SMES power terminals not actually deleting the terminal reference when - by cutting the terminal itself rather than the SMES. - - bugfix: SMES now reconnect to the grid properly after construction. - - refactor: SMES now uses wirecutter act to handle terminal deconstruction. - ninjanomnom: - - bugfix: Objects picked up from tables blocking throws will no longer be forever - unthrowable -2018-08-01: - Basilman: - - rscadd: Added the stealth manual to the uplink, costs 8 TC. Find it under the - implant section - Cobby: - - spellcheck: Drone's Law 3 has been edited to explicitly state that it's for the - site of activation (aka people do not get banned for going to upgrade station - as derelict drones since it's explicitly clear now). See https://tgstation13.org/phpBB/viewtopic.php?f=33&t=18844&p=429944#p429944 - for why this was PR'd - - bugfix: PENLITEs are now actually spawnable in techwebs. Reminder to make sure - everything is committed before PRing haha! - Denton: - - tweak: New bounties have been added for the Firefighter APLU mech, cat tails and - the Cat/Liz o' Nine Tails weapons. - - bugfix: ExoNuclear mech reactors now noticably irradiate their environment. - - spellcheck: Adjusted suit storage unit descriptions to mention that they can decontaminate - irradiated equipment. - Hate9: - - rscadd: Added tiny-sized circuits (called Devices) - - imageadd: added new icons for the Devices - Iamgoofball: - - balance: 'Buzzkill Grenade Box Cost: 5 -> 15' - Shdorsh: - - rscadd: Text replacer circuit - SpaceManiac: - - bugfix: The bridge of the gulag shuttle now has a stacking machine console for - ejecting sheets. - Time-Green: - - rscadd: You can now mount energy guns into emitters - - bugfix: portal guns no longer runtime when fired by turrets - barbedwireqtip: - - tweak: Adds the security guard outfit from Half-Life to the secdrobe - granpawalton: - - tweak: Removed old piping sections and replaced with Canister storage area in - atmos incinerator - - tweak: scrubber and distro pipes moved in atmos incinerator to make room for added - piping - - balance: added filter at connector on scrubbing pipe in atmos incinerator - - balance: replaced vent in incinerator with scrubber in **Both** incinerators - - balance: mixer placed on pure loop at plasma - - bugfix: delta and pubby atmos incinerator air alarm is no longer locked at round - start - - bugfix: pubby atmos incinerator now starts without atmos in it - kevinz000: - - rscadd: 'Cameras now shoot from 1x1 to 7x7, fully customizable. Alt click on them - to change the size of your photos. experimental: All photos, assuming the server - host turns this feature on, will be logged to disk in round logs, with their - data and path stored in a json. This allows for things like Statbus, and persistence - features among other things to easily grab the data and load the photo.' - - rscadd: Mappers are now able to add in photo albums and wall frames with persistence! - This, obviously, requires photo logging to be turned on. If this is enabled - and used, these albums and frames will save the ID of the photo(s) inside them - and load it the next time they're loaded in! Like secret satchels, but for photos! -2018-08-03: - ArcaneMusic: - - soundadd: Added a new, shoutier RoundEnd Sound. - Basilman: - - bugfix: fixed agent box invisibility - Denton: - - tweak: 'Syndicate lavaland base: Added a grenade parts vendor and smoke machine - board. The testing chamber now has a heatproof door and vents/scrubbers to replace - air after testing gas grenades. Chemical/soda/beer vendors are emagged by default; - the vault contains a set of valuable Syndicate documents.' - - tweak: Added a scrubber pipenet to the Lavaland mining base. - Garen: - - bugfix: mobs now call COMSIG_PARENT_ATTACKBY - JJRcop: - - rscadd: Deadchat can use emoji now, be sure to freak out scrying orb users. - Kmc2000: - - rscadd: You can now attach 4 energy swords to a securiton assembly instead of - a baton to create a 4 esword wielding nightmare-bot - Mickyan: - - imageadd: added sprites for camera when equipped or in hand - - tweak: cameras are now equipped in the neck slot - SpaceManiac: - - bugfix: Traps now have their examine text back. - Supermichael777: - - bugfix: Cigarettes now always transfer a valid amount of reagents. - - bugfix: Reagent order of operations is no longer completely insane - WJohnston: - - tweak: Added a gun recharger to delta's white ship and toned it down from a "luxury" - frigate to just a NT frigate, it's just not made for luxury! - XDTM: - - bugfix: Beheading now works while in hard crit, so it can be used against zombies. - - tweak: You can now have fakedeath without also being unconscious. Existing sources - of fakedeath still cause unconsciousness. - - rscadd: Zombies and skeletons now appear as dead. Don't trust zombies on the ground! - - rscadd: You can now make Ghoul Powder with Zombie Powder and epinephrine, which - causes fakedeath without uncounsciousness. - granpawalton: - - bugfix: pubby round start atmos issues resolved - - bugfix: pubby departures lounge vent is no longer belonging to brig maint - - rscadd: pipe dispenser on pirate ship - ninjanomnom: - - bugfix: The first pod spawned had some issues with shuttle id and wouldn't move - properly. This has been fixed. -2018-08-06: - Basilman: - - balance: Increased agent box cooldown to 10 seconds - Denton: - - bugfix: Omegastation's Atmospherics lockdown button now has the proper access - reqs. - - bugfix: Pubbystation's disposals conveyor belts now face the correct direction. - - bugfix: Pubby's service techfab is no longer stuck inside a wall. - - bugfix: Pubby's disposal loop is no longer broken. - - tweak: The Lavaland seed vault chem dispenser now has upgraded stock parts. - - tweak: 'Metastation: Extended protective grilles to partially cover the Supermatter - cooling loop.' - Epoc: - - rscadd: You can now show off your Attorney's Badge - Garen: - - bugfix: Fixed AddComponent(target) not working when an instance is passed rather - than a path - JJRcop: - - bugfix: Fixed some strange string handling in SDQL - Jared-Fogle: - - rscadd: Moths can now eat clothes. - JohnGinnane: - - rscadd: Users can now see their prayers (similar to PDA sending messages) - Mickyan: - - tweak: Drinking alcohol now improves your mood - Shdorsh: - - bugfix: The previously-added find-replace circuit now actually exists. - Tlaltecuhtli (and then Cobby): - - bugfix: Science Bounties are now available! - WJohnston: - - balance: Rebalanced the simple animal syndies on the metastation ship to be a - bit less destructive of their surroundings, and downgraded the smg guy to a - pistol and upgraded the other guys to knives. - Y0SH1 M4S73R: - - rscadd: windoors now have NTNet support. The "open" command toggles the windoor - open and closed. The "touch" command, not usable by door remotes, functions - identically to walking into the windoor, opening it and then closing it after - some time. - cyclowns: - - tweak: Fusion has been reworked to be a whole lot deadlier! - - tweak: You can now use analyzers on gas mixtures holders (canisters, pipes, turfs, - etc) that have undergone fusion to see the power of the fusion reaction that - occurred. - - balance: Several gases' fusion power and fusion's gas creation has been reworked - to make its tier system more linear and less cheese-able. -2018-08-07: - WJohnston: - - rscadd: Redesigned the pirate event ship to be much prettier and better fitting - what it was meant to do. -2018-08-08: - Denton: - - rscadd: 'Added five new cargo packs: cargo supplies, circuitry starter pack, premium - carpet, surgical supplies and wrapping paper.' - - tweak: Added one bag of L type blood to the blood pack crate. Added a chance for - contraband crates to contain DonkSoft refill packs. - Iamgoofball: - - tweak: The Stealth Implant was mistakenly made nuclear operatives only due to - a misunderstanding of the code. This has been fixed. - Mark9013100: - - rscadd: Pocket fire extinguishers can now be made in the autolathe. - SpaceManiac: - - bugfix: The power flow control console once again allows actually modifying APCs. - - tweak: Gas meters will now prefer to target visible pipes if they share a turf - with hidden pipes. - daklaj: - - bugfix: fixed beepsky and ED-209 cuffing their target successfully even when getting - disabled (EMP'd) in the process - kevinz000: - - rscadd: Catpeople are now a subspecies of human. Switch your character's species - to "Felinid" to be one. - - rscadd: Oh yeah and they show up as felinids on health analyzers. -2018-08-10: - AnturK: - - balance: Portable flashers won't burnout from failed flashes. - Denton, Tlaltecuhtli: - - rscadd: Added cargo bounties that require cooperation with Atmospherics, Engineering - and Mining. - Naksu: - - bugfix: Transformation diseases now properly check for job bans where applicable - - code_imp: Fixed a bunch of runtimes that result from transforming into a nonhuman - from a human, or a noncarbon from a carbon. - SpaceManiac: - - refactor: The map loader has been cleaned up and made more flexible. - nicbn: - - tweak: 'BoxStation science changes: Circuitry lab is closer to RnD now; cannisters, - portable vents, portable scrubbers, filters and mixers have been moved to Toxin - Mixing Lab. There is now a firing range at the testing lab!' -2018-08-11: - Denton: - - tweak: Fixed the Beer Day date and added a few more holidays. - Jordie0608: - - admin: Asay history is once again logged under the admin log secret. - - admin: Notes, messages, memos and watchlists can now have an expiry time. Once - expired they are hidden like as if deleted. - SpaceManiac: - - tweak: Giant spiders can now freely pull their victims through webs. - Time-Green: - - rscadd: Circuit Boards now tell you the components required to build them on examine - WJohn: - - rscadd: Added zombies to boxstation's abandoned ship. - YPOQ: - - bugfix: AIs can take photos and print them at photocopiers again. - - bugfix: Cult floors will not deconstruct to space - - bugfix: Cult floors do not spawn rods when deconstructed - - bugfix: Footprints should no longer spread out of control - zaracka: - - bugfix: blunt trauma causes brain damage while unconscious too - - bugfix: sharp weapons no longer count as blunt trauma in all cases -2018-08-12: - Denton: - - rscadd: Killing gondolas now lets you harvest meat from them. Eating it raw might - be a bad idea. - Mickyan: - - rscadd: Mixed drinks now give mood boosts with varying strength depending on their - quality. - - rscadd: Although powerful, mood boosts from quality drinks are short lived. If - you want to make the most out of them, take a sip every few minutes like a normal - human being instead of downing the entire glass like the alcoholic you are. - Nichlas0010: - - bugfix: Admins with +admin and without +fun are no longer able to smite. - SpaceManiac: - - bugfix: Blood and oil footprints sharing a tile no longer causes footprint decals - to stack. - WJohnston: - - balance: Syndicate (melee) simple animals will now move less predictably and attack - twice as often, hopefully making them quite a bit more dangerous. - XDTM: - - tweak: Operating Computers can now sync to the research database to acquire researched - surgeries, instead of requiring installation by disk. - - rscadd: You can now review the full list of unlocked surgeries from the operating - computer. - actioninja: - - rscadd: Added (unobtainable) Felinid Mutation Toxin. - lyman: - - imageadd: Updated the Chronosuit Helmet sprite. -2018-08-13: - Basilman: - - rscadd: Adds Arnold pizza, dont try putting pineapple on it. - Denton: - - tweak: The briefcase launchpad can now hold items while in briefcase mode (just - like a regular briefcase). Its remote has been disguised as a folder and now - spawns pre-linked inside the briefcase. - - balance: Increased the briefcase launchpad's range from 3 to 8 tiles, which is - roughly half the screen. - - spellcheck: Added more ingame manuals that access wiki pages. - - rscadd: Added botanical and medical bounties as well as a static adamantine bar - bounty. - - tweak: Increased the syndicate document bounty's reward from 10.000 to 15.000 - credits. - - tweak: Removed the gondola hide bounty and in return, increased the export value - to the old level. - - tweak: The briefcase bounty now also accepts secure briefcases. - - bugfix: The action figure bounty now correctly spawns as an assistant type bounty. - Logging refactor and improvement: - - code_imp: All mob-related logs now include the area name and (x,y,z) position. - - code_imp: All logs that included an (x,y,z) position now also include the area - name. - - code_imp: Standardized logging format of mob/player keys. - - code_imp: Telecomms logs are now included in the individual logging panel. - - code_imp: Fixed many other cases of logs being sent to either the individual logging - panel or the saved log files, but not both. - - refactor: The logging system has been refactored to contain less redundant code - and to produce more consistent logs. - SpaceManiac: - - admin: The VV window loads and searches faster. - - admin: Fields in the VV window's header will immediately show your edits. - - admin: Selecting an action from the VV dropdown no longer leaves it selected after - the action is done. - YPOQ: - - bugfix: Uncalibrated teleporters can turn humans into flies again -2018-08-14: - Coolguy3289: - - config: Removed un-needed and un-used RENAME comment from game_options.txt - SpaceManiac: - - bugfix: Escape Pod 1 now reaches the CentCom recovery ship again. - WJohn: - - imageadd: Titanium walls and windows are a bit prettier looking now. - Zxaber: - - rscadd: Airlock electronics can have now have unrestricted access by direction - set. The resulting airlock will allow all traffic from the specified direction(s) - while still requiring normal access otherwise. A small floor light will indicate - this. - - tweak: Medbay Cloning and Main Access doors now have unrestricted access settings - set, and the buttons have been removed. All maps have been updated. - - bugfix: Airlocks now correctly update their overlays (bolts lights, emergency - lights) when their power state changes. -2018-08-15: - barbedwireqtip: - - tweak: added binoculars to the detective's locker -2018-08-17: - Anonmare: - - rscadd: Ore silos circuit boards are now constructable - SpaceManiac: - - admin: The "Map Template - Upload" verb now reports if a map uses nonexistent - paths. - Tlaltecuhtli: - - bugfix: fixes diamond drill bounty having the wrong object path - YPOQ: - - bugfix: Roundstart motion-detecting cameras work again - intrnlerr: - - bugfix: '"Allows image windows sent by PDA to be closed"' -2018-08-18: - Floyd / Qustinnus: - - code_imp: moves nutrition events to the mood component - Jared-Fogle: - - rscadd: Hovering over storage slots with an item in your hand will show you first - if you can put the item in. - XDTM: - - bugfix: Fixed augmentation not working and/or giving you extra limbs - nicbn: - - imageadd: New janitor cart sprites (by Quantum-M) - - imageadd: Dirt is smooth (by AndrewMontagne) - zaracka: - - bugfix: You can now use certain emotes and the suicide verb while buckled, but - not while stunned. -2018-08-20: - Basilman: - - rscadd: Added gondola fur products - Basilman, Sprites by WJohnston: - - rscadd: His Grace ascension is back, feed Him 25 people and you will unlock His - full potential. - Denton: - - tweak: Added new destinations for the parcel tagger! You can now send packages - to the Circuitry Lab, Toxins, Dormitories, Virology, Xenobiology, Law Office - and the Detective's office. Viro/Xeno can only receive parcels. - - bugfix: 'Deltastation: Tagged parcels no longer get routed straight into the crusher. - Untagged parcels also no longer get routed straight into the crusher!' - - tweak: 'Deltastation: Added disposals to Xenobiology that launch contents into - space.' - Epoc: - - tweak: Putting an extinguisher into a cabinet with the safety off will no longer - cause it to spray first - Floyd / Qustinnus: - - code_imp: removes useless mood events subtypes - - bugfix: 'fixes mood event timers not resetting when they get triggered again remove: - removes the depression overlay which makes our fruit happy' - Frosty Fridge: - - rscadd: Added the Surgical Processor upgrade for medical cyborgs. Scan surgery - disks or an operating computer to be able to initiate advanced procedures. - - tweak: Cyborgs can now perform surgery steps that do not require an instrument. - - bugfix: Plastic creation reaction now properly scales with the amount of reagents; - 10u = 1 sheet. - Garen: - - bugfix: fixed using items on a circuit removing all its access(now access gained - from each new item stacks) - - admin: adds logging for gun circuits, grabber circuits, and dragging claw circuits - - rscadd: grabbers can select what they want to drop - MrDoomBringer: - - imageadd: The Nanotrasen Airspace Aesthetics division has shipped out a newer - design of NT-Brand "Ore Silos". No new features have been added, but they certainly - look much nicer! - Naksu: - - balance: Having a high body temperature now increases the damage you take gradually, - whether you're on fire or not. Being on fire also always increases body temperature - damage - NewSta: - - tweak: The names of haircuts, facial hair, undershirts, underwear and socks have - now been sorted and categorized - WJohnston: - - imageadd: Remade titanium and plastitanium floors to be less of an eye strain - and something mappers might actually consider using. - - imageadd: New reinforced floor sprites. - XDTM: - - rscadd: Added programmable nanites to science! - - rscadd: Science now has a nanite chamber, a nanite program hub, a nanite cloud - console and a nanite programmer. - - rscadd: From the program hub you can download nanite programs (unlocked through - techwebs) to disks. - - rscadd: You can then customize their functionality and signal codes through the - Nanite Programmer. - - rscadd: The nanite chamber is necesary to inject nanites into a patient, and it's - also used to install/uninstall programs into a patient's nanites. A second person - is required to man the console. - - rscadd: The nanite cloud console controls remote program storage; it stores program - backups that nanites can be synced to through cloud IDs. - - rscadd: Nanite programs range can be either helpful or harmful; their main potential - is that they can be enabled at will through the use of remotes and sensors. - The potential uses are endless! - - rscadd: More detailed information is available in the wiki. -2018-08-22: - BlueNothing: - - rscadd: Allows video camera circuits to be seen on networks other than the science - cameranet. - - tweak: Alphabetizes camera list for camera bugs, and lets camera bugs see through - borg and circuit cameras. - - tweak: Makes video camera circuits fit in tiny assemblies. - PKPenguin321: - - tweak: The GPS circuit now has a 4th output, placing X,Y,Z all in a string. - - rscadd: '2 new converters: Rel to Abs, and Advanced Rel to Abs.' - - rscadd: Rel to Abs takes a set of relative and a set of absolute coordinates, - and converts the relative one to absolute. 1 complexity. - - rscadd: Advanced Rel to Abs takes a set of relative coordinates and converts it - to absolute without the need for an already known set of absolute coordinates. - 2 complexity. - SpaceManiac: - - bugfix: Freezers and heaters which start on no longer stay visually on when you - turn them off. - - code_imp: Atmospherics now initializes 93% (about 40 seconds) faster. - floyd: - - bugfix: fixes the hunger alert appearing forever - intrnlerr: - - bugfix: Tank temperature is no longer based on pressure - ninjanomnom: - - bugfix: Shuttle templates now handle shuttle registration in the load rather than - the shuttle manipulator. This means admin loaded shuttle templates no longer - need to be manually registered. - oranges: - - tweak: Inventory overlay now uses a traffic light to indicate if the item can - be placed in there -2018-08-23: - Naksu: - - code_imp: Waddling is now available as a component - Nervere: - - rscadd: re-adds the joy emoji. - SpaceManiac: - - rscadd: The body zone selector now indicates which body part you are about to - select when hovered over. - - code_imp: Transit space initializes about five seconds faster. - Tlaltecuhtli: - - balance: Cyborg ion thrusters consume 1/5 of their previous power. -2018-08-25: - Denton: - - rscadd: Added missing export rewards for various lavaland items (tendril/megafauna/ruins) - and engine parts. - - balance: Increased export values for emitters, PA parts, field generators and - radiation collectors to match the rest of engineering exports. Reduced supermatter - shard value by 1000 credits. - - rscdel: Removed export rewards for red/blue warp cubes since they're blacklisted - from the cargo shuttle. - - tweak: Added private intercoms to the confession booths of the Deltastation+Pubbystation - chapels. - - bugfix: Fixed invalid radio frequencies on interrogation chamber/confession booth - intercoms. - - tweak: Anime is even more horrifying than previously discovered! - - rscadd: Added a new shuttle loan event where crew can get paid for having an active - syndicate bomb delivered to cargo bay. - Mickyan: - - bugfix: Blue polo undershirt option has been restored - - tweak: underwear "nude" option moved to the top of the list - SpaceManiac: - - code_imp: The map loader now supports vars to be set to lists containing non-strings. - - bugfix: Overcharging energy guns no longer crashes the server. - - bugfix: Ordering the Build Your Own Shuttle kit no longer crashes the server. - The Dreamweaver: - - code_imp: Refactored gift code to fix a minor inefficiency. - XDTM: - - bugfix: Fixed chest and head augmentation not working properly. -2018-08-26: - CitrusGender: - - admin: Added note severity to [most] bans and the notes associated with them - - admin: 'Banning panel now has a severity option UI: Changed the UI of the note - panel UI: Changed the UI again, added some icons, removed brackets in urls, - fading out notes cannot be selected to expand the browser anymore' - Floyd / Qustinnus (Credits to KMC for the sprites): - - rscadd: The Clown Car, your 18TC clown-only solution to asshole co-workers - - rscadd: Regular car implementation (makes it easier to add more cars if someone - actually feels like adding those) - JJRcop: - - admin: 'Asay logs show "ADMINPRIVATE: ASAY:" again instead of just "ADMINPRIVATE:"' - Naksu: - - code_imp: living and stack typecaches now use a shared instance where it makes - sense, giving small memory savings - PKPenguin321: - - rscadd: Integrated circuit medium screens have been readded. They are now called - large screens. They now only work from your hands or on the ground when you're - standing on top of them (NOT from pockets, lockers, backpacks, etc). - - bugfix: Roundstart cyborgs will now be properly referred to as "it." - SpaceManiac: - - admin: The shuttle manipulator now allows flying any shuttle to any port which - will fit it. - - bugfix: The shuttle manipulator now allows fast-travelling shuttles with 5s remaining, - down from 50s. - - refactor: Status displays have been refactored to be cleaner and more flexible. - - bugfix: The AI dying properly updates its status displays again. - intrnlerr: - - refactor: Refactored nettles to be reagent_containers - nicbn: - - soundadd: Nanotrasen shoes no longer contain Silencium. Now footsteps make noise! - Sounds from Baystation. -2018-08-28: - Denton: - - bugfix: The 10 second anti spam cooldown of night shift lighting now works properly. - - spellcheck: Added an examine message to APCs that mentions Alt-click and Ctrl-click - (silicons only) behavior. - Garen: - - code_imp: adds a signal for screwdriver_act - SpaceManiac: - - code_imp: Multiple copies of a shuttle each get their own area instances (affects - APCs and air alarms). - XDTM: - - rscadd: The forcefield projector is now available ingame in the engineering protolathe. - It can project up to 3 forcefields which act as transparent walls, and share - a pool of health which is recharged over time. The projector must remain within - 7 tiles of the forcefields to keep them active. -2018-08-31: - Anonmare: - - bugfix: AIs can now turn shield generators on and off again - Denton: - - bugfix: Plastic golems can no longer vent crawl with items in their pockets. - Mickyan: - - balance: Skateboards can fit in backpacks - - tweak: Skateboards are slower by default, speed can be adjusted by alt-clicking - - rscadd: 'Show your support for the fine arts with these new quirks:' - - rscadd: 'Tagger: drawing graffiti takes half as many charges off your spraycan/crayon' - - rscadd: 'Photographer: halves the cooldown after taking a picture' - - rscadd: 'Musician: tune instruments to temporarily give your music beneficial - effects such as clearing minor debuffs and improving mood.' - Skoglol: - - bugfix: Dispensers can now add 5u to buckets, plastic beakers and metamaterial - beakers, down from 10u. - - bugfix: You can now pour 5u from buckets, plastic beakers and metamaterial beakers, - down from 10u. - - bugfix: Chem dispenser window width increased slightly, no longer shuffles buttons - when scroll bar appears. - The Dreamweaver: - - bugfix: Sentience Potions no longer require you to have Xenomorph toggled on in - preferences and now relies on its own preference in order to be notified of - open roles. - - code_imp: Split xenomorph, intelligence potions, and mind transfer potions into - separate roles for more precise role management. - - admin: Sentience Potion Spawns and Mind Transfer Potions are now job-bannable - roles. - Time-Green and locker sprites by MrDoomBringer: - - rscadd: Reports have come in that the wizard federation has harnessed some of - the ancient locker force to create a wand - XDTM: - - rscdel: Removed the chance of spouting brain damage lines when over 60 brain damage. - The dumbness trauma still has them. - - bugfix: Fixed Mechanical Repair nanites not working. - ninjanomnom: - - rscadd: Computers are now visible even in the darkest of rooms. Comfy! - - tweak: Because computers are now far easier to find in dark rooms their base light - output has been reduced. - - bugfix: Broken components left over from the signal origin refactor should be - fixed. - - bugfix: Lava isn't a safe place to throw your flammable shit anymore - - bugfix: The computer screen overlay being rotated incorrectly after construction - has been fixed. -2018-09-01: - ElPresidentePoole: - - rscdel: removes curator's fear of snakes - McDonald072: - - bugfix: Defibrillator nanites work properly. - Poojawa: - - bugfix: fixed clothing vendor fedoras having Detective Fedora grade armor - Potato Masher: - - tweak: The color of Wooden golems should be more in line with the color of the - wood used to make it. - WJohnston: - - imageadd: Reinforced floors are now shinier. -2018-09-02: - Denton: - - spellcheck: Fixed species type names that show up on health scanners. -2018-09-03: - Cdey78 (Ported by Floyd / Qustinnus): - - imageadd: AI can now think - - imageadd: 'New OOC emote: :thinking:!' - Naksu: - - admin: a new admin secret has been added to create a customized portal storm - Shdorsh: - - tweak: Makes it possible to create circuits that can get an item loaded into them - while they are in an assembly and the assembly is open. - - code_imp: Optimized electronic assemblies also. - - bugfix: A bug pertaining putting batteries in assemblies - Skoglol: - - bugfix: Eggplant and egg-plant seeds now have different names and plant names. - XDTM: - - bugfix: Fixed nanite cloud storage not allowing uploads. - octareenroon91: - - admin: Supermatter more likely to log fingerprintslast when it consumes any object. -2018-09-04: - Denton: - - spellcheck: Mech construction messages no longer incorrectly mention high-tier - stock parts. - - tweak: Added a nanite lab to Deltastation! It's at the old EXPERIMENTOR lab. - - tweak: 'Delta: Moved the Xenobiology disposals bin to be less obstructive. Added - two sets of insulated gloves to Engineering.' - - bugfix: 'Delta: Fixed scientists not having maintenance access near the circuitry - lab and toxins launch chamber.' - Shdorsh: - - code_imp: Made all the extinguishers use less sleep and spawn procs -2018-09-27: - Alexch2: - - spellcheck: Fixes tons of typos related to integrated circuits. - - tweak: Re-writes the descriptions of a few parts of integrated circuits. - 'Armhulen code, Keekenox sprites and S_____ as the ideas guy :roll_eyes:': - - rscadd: 'New drinks: Peppermint Patty and the Candyland Extract!!' - Astatineguy12: - - tweak: The experimentor is less likely to produce food when it transforms an item - - bugfix: The experimentor no longer breaks when the toxic waste malfunction occurs - multiple times and isn't cleaned up - - bugfix: The experimentor irridiate function actually chooses what item to make - properly rather than picking from the start of the list - - bugfix: The mime blockade spell now shows up under the right tab - Beachsprites: - - imageadd: added directional beach sprites - Big Tobacco: - - rscadd: Cheap lighters now come in four different shapes and Zippos can have one - of four different designs, collect them all and improve our sales! - - imageadd: All existing lighter sprites have been given a face-lift and the flames - are now subtly animated. - - tweak: Cheap lighters now use a fixed list of 16 colors to pick from instead of - using totally randomized colors. - - imageadd: Cigar cases have been tweaked to be a bit smaller and to have a modified - design. - - imageadd: Cohiba Robusto and Havanan cigars now use separate case sprites from - the generic premium cigar cases. - CameronWoof: - - tweak: Quartermaster added to the list of changeling and traitor restricted jobs - CitadelStationBot: - - bugfix: The faint echoes of maracas grows louder, as if a past spirit once forgotten - has come back with a vengeance... - - bugfix: Removing an ID card from a wallet now properly removes its visual and - accesses. - - tweak: You may now take unlimited neutral and negative quirks - - tweak: the walls on the crashed abductor ship ruin in lavaland can now be broken - down - - bugfix: Pipe icons in the RPD now show properly in older versions of IE. - - bugfix: Removing an ID from a PDA in a backpack no longer hides the ID until something - else updates. - - bugfix: Opening and closing airlocks repeatedly no longer stacks queued autocloses. - - bugfix: Mindswapping with someone else no longer forces ambient occlusion on. - - bugfix: Admin AI interaction now works properly on firelocks. - - code_imp: IRV polls now use the same version of jQuery as everything else. - - rscadd: You can now view your last round end report window with the "Your last - round" verb in the OOC tab - - bugfix: Hydroponics trays can no longer be deconstructed with their panels closed - or unanchored while irrigated. - - tweak: Frames for machines which do not require being anchored can now be un/anchored - after the circuit has been added. - - spellcheck: Fix "Your the wormhole jaunter" when a wormhole jaunter saves you - from a chasm. - - rscadd: Analyzers can now scan all kinds of atmospheric machinery - unary, binary, - ternary, quaternary, you name it. This means stuff like gas pumps, gas mixers, - vents and so forth can be analyzed. - - tweak: Analyzers now show temperature in kelvin as well as celsius. - - tweak: Analyzers now show total mole count, volume, and mole count of all gases. - - tweak: Analyzers show everything at slightly higher degrees of precision. - - rscadd: Any anomaly core can now be deconstructed for a one time boost of 10k - points in the deconstructive analyzer. - - bugfix: Chasms no longer drop mobs buckled to undroppable mobs or objects. - - bugfix: Digital valves are once again operable by silicons. - - bugfix: Field generators are once again operable by adjacent cyborgs. - - bugfix: Entertainment monitors now view the real Thunderdome rather than the template. - - bugfix: Flipping and then rotating trinary pipe fittings no longer causes their - icon to mismatch what they will become when wrenched. - - bugfix: RPD tooltips for flippable trinary components have been corrected. - - bugfix: The green overlay indicating where a map template will be placed is no - longer invisible on space turfs. - - bugfix: Frost spiders now correctly inject frost oil on bite. - - bugfix: Inserting materials into protolathes with telekinesis is now possible. - - bugfix: Telekinesis no longer teleports items removed from deep fryers, constructed - sandbags, and leftover materials not inserted into lathes. - - bugfix: Telekinetic sparkles now appear in the correct place when clicking on - a turf and when clicking in the fog of war in widescreen. - - bugfix: Telekinetically adjusting power tools no longer causes them to exit the - universe. - - tweak: Examining a telekinetic grab in-hand will now examine the grabbed object. - - bugfix: Non-harmfully placing someone who is resting on a table no longer makes - them get up. - - bugfix: The disco machine no longer lags the chat by spamming "You are now resting!" - messages. - - tweak: Clicking on the viewport to focus it no longer leaves the input bar red. - - bugfix: Running diagonally into space now properly continues the diagonal movement - in zero-gravity. - - bugfix: Moving diagonally past delivery chutes, transit tube pods, &c. no longer - causes your camera to be stuck on them. - - config: The limit of monkey's spawned via monkey cubes is now configurable - - bugfix: Fixes cyborgs not being able to use two-handed modules while other modules - are equipped. - - bugfix: Pubby's auxiliary mining base now works again. - - bugfix: The overlay effects of cult flooring are now on the floor plane, fixing - their odd ambient occlusion appearance. - - bugfix: Cloning no longer breaks a character's connection to their family heirloom. - - bugfix: Beam rifle tracers no longer fall into chasms. - - bugfix: Vomiting on the same tile a second time no deletes the vomited reagents. - - bugfix: fixed the clockwork helmet not dropping to ground when used by non-clock - cultists - - refactor: The base machinery type is now anchored by default. - - bugfix: PDA style now gets loaded correctly. - - bugfix: Switching mobs into/out of a mech (by VR, ghosting, or mindswap) no longer - improperly applies the mech's cursor. - - tweak: roboticists have access to R&D windoors - - tweak: switched the type of the space suit on the syndicate shuttle - - bugfix: fixed hydroponics tray weed light staying on when removing weeds with - integrated circuits - - bugfix: Atom initialization and icon smoothing no longer race, causing late-loading - mineral turfs to have no icon. - - spellcheck: Faceless persons no longer "melt their face off" in energy gun suicides. - - bugfix: The Lightning Bolt spell now works again. - - tweak: Vehicle speed changes now happen immediately instead of on the next movement - cycle - - bugfix: Picture-in-picture objects now are no longer overlapped by other certain - objects - - bugfix: A pAI dying while in holoform no longer deletes the card, instead merely - emptying it. - - bugfix: The thermal sight benefits of lantern wisps no longer disappear if you - change glasses. - - imageadd: sandstone wall sprite for indestructible object - - bugfix: Stabilized gold extracts now respawn the familiar properly. - - bugfix: Stabilized gold familiars retain the proper languages even after respawning. - - tweak: Stabilized gold familiars can be renamed and have their positions reset - at will. - - bugfix: Pulling objects diagonally no longer causes them to flail about when changing - directions. - - bugfix: Riders are no longer left behind if you move while pulling something that - has since been anchored. - - tweak: Fire alarms now redden all the room's lights, and emit light themselves, - rather than applying an area-wide overlay. - - bugfix: Fire alarms no longer visually conflict with radiation storms. - - bugfix: Plasmamen now receive their suit and internals when entering VR. - - bugfix: Deaf people can no longer hear cyborg system error alarms. - - bugfix: Lockboxes are now actually locked again. - - bugfix: Legion cores and admin revives now heal confusion. - - bugfix: checks to see if bullets are deleted if they are the ammo type and the - bullet chambered. - - spellcheck: Capitalization, propriety, and plurality on turfs have been improved. - - bugfix: Unbreakable ladders are now left behind when shuttles move. - - rscadd: Players who edited a circuit assembly can scan it as a ghost. - - bugfix: It is no longer possible to pull the mirages images at space transitions, - and some other abstract effects. - - bugfix: Moving large amounts of items with bluespace launchpads no longer creates - a laggy amount of sparks. - - bugfix: The escape pod hallways on MetaStation and DeltaStation now have air again. - - bugfix: It is no longer possible to repair cyborg headlamps even when their panel - is closed. - - bugfix: Item fortification scrolls no longer add multiple prefixes when applied - to the same item. - - tweak: The blob core (and only the blob core) now respawns randomly on the station - when the core is taken off z-level - - bugfix: Prevents the round from going into an unending state - - code_imp: Added a variable to the stationloving component for objects that can - be destroyed but not moved off z-level - - rscadd: After years of protests NT decided to update the fire security standards - by adding 3 (three) advanced fire extinguishers to all the new stations. - - bugfix: Hyperspace ripples now remain visible until the shuttle arrives, even - during extreme lag. - - bugfix: Ripples now correctly take the shape of the shuttle, rather than always - being a rectangle. - - bugfix: Non-secure windoors now properly support the "One Required" access mode - of airlock electronics. - - bugfix: The gulag shuttle no longer moves instantly when returned via the claim - console. - - admin: It is now possible to use the ".p" (Asay) and ".d" (Dsay) prefixes while - an admin ghost. - - admin: Speaking in deadchat now shows your rank instead of ADMIN - - rscadd: Added a pink scarf to vendomats - - rscadd: Players can now ctrl-click the PDA to remove the item in its pen slot - - bugfix: added a clamp so you can't set a negative multiplier to create materials - and create more than 50 items. - - bugfix: anomaly cores no longer tend to dust - - spellcheck: Plant disks with potency genes clarify the percent is for potency - scaling and not relative to max volume on examine. - - rscadd: Blast cannons have been fixed and are now available for purchase by traitorous - scientists for a low low price of 14TC. - - rscadd: 'Blast cannons take the explosive power of a TTV bomb and ejects a linear - projectile that will apply what the bomb would do to a certain tile at that - distance to that tile. However, this will not cause breaches, or gib mobs, unless - the gods (admins) so will it. experimental: Blast cannons do not respect maxcap. - (Unless the admins so will it.)' - - rscadd: Cyborgs now drop keys on deconstruction/detonation - - bugfix: The "Save Logs" option in the chat now actually works (IE 10+ only). - - bugfix: Fixed cyborgs not getting their names at round start - - bugfix: Fixed cyborgs and A.I.s being able to bypass appearance bans - - bugfix: fixes cult shuttle message repeating - - bugfix: Hardsuit helmets now protect the wearer from pepperspray - - bugfix: It is once again possible for Cargo to export mechs. - - tweak: tourettes doesnt stack on itself anymore - - refactor: AI static now uses visual contents and should perform better in theory. - - bugfix: Bucket helmets cannot have reagents transferred into them until after - they are removed - - rscadd: R&D deconstructors can now destroy things regardless of if there's a point - value or material - - bugfix: You should now receive your destroy AI objectives properly during IAA - - bugfix: Deconstructable TEG now propertly connects to pipes. - - bugfix: Fix of inverted TEG sprite of slow turbine turning. add:Now you can flip - circulator and make TEG of your dream. add:Add TEG and circulator to "Advanced - Power Manipulation" techweb node. - - imageadd: New icon for plastic flaps that actually looks airtight. - - code_imp: Update to plastic flaps code to use tool procs rather than attackby - and removed two pointless states. - - bugfix: Printing the TEG and circulator boards no longer prints the completed - machinery instead. - - imageadd: Medical HUDs will now show an icon if the body has died recently enough - to be defibbed - Cobby: - - tweak: Decals are the exception to the recent removal of effects in Chameleon - Projectors. - - rscdel: Removed Advanced Mining Scanner from roundstart voucher kits. - - rscdel: Removed Explorer Webbing from all voucher kits besides the shelter capsule - pack. - - bugfix: Paper doesn't give illegal tech anymore - Cruix: - - rscadd: AIs now have an experimental multi-camera mode that allows them to view - up to six map areas at the same time, accessible through two new buttons on - their HUD. - Dax Dupont: - - bugfix: Fixes the wrong tiles in Syndicate VR trainer and uses different tiny - fans. - - bugfix: Access didn't append to VR IDs - - bugfix: Fixes missing curator hud icon. - - balance: Cult items will no longer be a long ride on the vomit coaster if picked - up by a non cultist. - - balance: Cult space bases are kill again. - - balance: Cult floors now pass gas. - - bugfix: Fixed a few things deconning into the wrong circuit. - - bugfix: You can no longer do infinite bioware surgery. - - bugfix: Foam no longer gives infinite metal - - bugfix: Mulligan didn't work on lizards and other mutants. Now it does. - - tweak: The BoH dialog now has Abort instead of Proceed as an default option. - - bugfix: Fixes accidental empty ahelp replies. - - balance: More chemicals can be found when vents get clogged. - - bugfix: Experimentor no longer shits out primed TB nades. - - bugfix: Fixed rpeds throwing stock part rating related runtimes. - - bugfix: Fixes a sentience related exploit by blacklisting it in restricted uplinks. - - bugfix: Botany trays don't magically refill anymore with a rped. - - balance: It's now easier to become fat. Don't eat so much. - - bugfix: Fixed missing grilles under brig windows of the pubby shuttle. - - rscadd: For the pubby shuttle, added some food in the fridge, mostly pie slices. - Also added a sleeper to the minimedbay. - - tweak: Reworded pubby shuttle description to be more inline with the new train - shuttle. - - refactor: Syndicate and Centcom messages have been squashed together. - - admin: You can now send both Syndicate and Centcom headset messages. Be mindful - that the button was changed to HM in the playerpanel - - bugfix: Fixes missing cream pies in the cream pie fridge. - - bugfix: Chem synths overlays aren't all kinds of fucked anymore. - - refactor: Unfucked all of the remaining chem synth code. - - refactor: Reagents no longer have an unused var that's always set to true. Who - did this? - - balance: Makes the xeno nest ruin harder to cheese. - - bugfix: Fixes the bathroom being airless in the Space Ninja anime jail. - - admin: Create antags now checks for people being on station before applying. - - admin: Malf AI machine overloads now are logged/admin messaged. - Denton: - - rscadd: APC/air alarm/airlock/fire alarm/firelock electronics are now available - once Industrial Engineering is researched.. - - tweak: Engi-Vend machines now contain fire alarm and firelock electronics! - - code_imp: Loose tech storage circuit boards have been replaced with spawners. - - code_imp: Added /syndicate subtypes for air alarms and APCs. - - bugfix: Added missing stock parts to the syndicate lavaland base. - - tweak: Added kitchen related circuit boards to the syndie lavaland base. - - tweak: There are rumors of the Tiger Cooperative adding a "special little something" - to some of their bioterror kits. - - code_imp: Loose silver/gold/solar panel crates have been replaced with "proper" - crates. - - balance: Skewium is much less likely to appear during the Clogged Vents event. - - bugfix: 'Navbeacon access requirements have been fixed: Now you need either Engineering - or Robotics access, but not both at the same time.' - - tweak: 'Pubbystation: Added a dual-port vent pump to the toxins burn chamber.' - - code_imp: Removed most airlock_controller/incinerator related varedits and replaced - them with defines/subtypes. - - tweak: The Deltastation toxins lab has its portable scrubber, air pump and intercom - back. - - bugfix: Swarmers can no longer attack field generators and turret covers. - - rscadd: Arcades have been stocked with preloaded tactical snack rigs. - - bugfix: The Pubbystation maint bar Booze-O-Mat now shows its contents correctly. - - tweak: Added a warning to the shuttle purchase menu. - - balance: Pirates and Syndicate salvage workers have been beefed up around the - caravan ambush ruin. - - tweak: NanoTours is proud to announce that the Lavaland beach club has been outfitted - with a dance machine, state of the art bar equipment and more. - - tweak: Did you know that honey has antibiotic properties? - - spellcheck: Improved supply shuttle messages and firefighting foam descs. - - bugfix: Supply shuttles will no longer spill containers on docking. - Dimmadunk: - - rscadd: 'There''s a new type of reagent added to the booze dispenser: Fernet. - With it you can make a couple of new digestif drinks that will help you reduce - excess fat!' - ElPresidentePoole: - - rscadd: SFX for seppuku (on all katanas) - - rscadd: suicide message for energy katanas ("cyber-seppuku") - - rscadd: suicide message for replica katanas ("seppuku") - Flatty: - - tweak: The blurry eye overlay has been replaced with an actual blur. - - tweak: The vending machine UI is now prettier. - Garen: - - rscadd: Thrower and Gun circuits put messages in chat when they're used. - - tweak: Only the gun assembly can throw/shoot while in hand - - imageadd: Adds inhands for the gun assembly - - bugfix: grabber inventories update when a thrower takes from them - GrayRachnid: - - rscadd: Adds private rooms to the ninja holding center - - rscadd: Along with a few things to make it more tolerable, but fear not. There - is now a suicide chamber for those who want the easy way out. - GuyonBroadway: - - rscadd: Adds gloves of the north star to the traitor uplink. Wearing these gloves - lets you punch people five times faster than normal. - - rscadd: Sprites for the gloves courtesy of Notamaniac - Hatterhat: - - tweak: The plasma formerly present in some execution syringes was replaced with - amatoxin. - Hyacinth: - - rscadd: Grenadine is now available in the bar! - - tweak: Tequila sunrises now require grenadine to make! - Iamgoofball: - - tweak: Lipolicide now only does damage if you're starving. - Improvedgay: - - balance: Naming immerions - Improvedname: - - rscadd: Adds rubbershot secrifle shots - JStheguy: - - rscadd: Added the data card reader circuit, a circuit that is able to read data - cards, as well as write to them. - - tweak: Data cards are now longer inexplicably called data disks despite clearly - being cards, and can be printed from the "tools" section of the integrated circuit - printer. - - tweak: Data cards no longer have a special "label card" verb and instead can have - their names and descriptions changed with a pen. - - rscadd: Also, some aesthetically different variants of the data cards, because - why not. - - imageadd: Data cards have new sprites, with support for coloring them via the - assembly detailer. - Jay: - - tweak: Bans CMO, RD, CE, and HoP from antag/ling - Jegub: - - imageadd: Glowcaps now have their own sprite. - Kor: - - rscadd: The Quartermaster and HoP can now access the vault so they can use the - bank machine. - - rscadd: Engineering can now create anomaly neutralizer devices, capable of instantly - neutralizing the short lived anomalies created by the supermatter engine. - - rscadd: Bubblegum has regained his original (deadlier) move set. - LetterN: - - bugfix: Fixes shock collars, they now fit on the neck slot - - bugfix: you can't put them on pockets anymore - MacHac: - - bugfix: Bedsheets once again properly influence the dreams of those who sleep - under them. - Mickyan: - - bugfix: Drinking too much Gargle Blaster, Nuka Cola or Neurotoxin no longer breaks - time and space. - - bugfix: Pacifists can now use harm intent for actions that require it (but still - can't harm!) - - spellcheck: fixed typo in bronze girder construction - - rscadd: 'New trait: Drunken Resilience. You may be a drunken wreck but at least - you''re healthy. If alcohol poisoning doesn''t get you, that is!' - - bugfix: Fixed pacifists being able to harm using bottles/screwdrivers - MrDoomBringer: - - imageadd: the VR sleeper action button has a sprite now - - admin: Central Command can now smite misbehaving crewmembers with supply pods - (filled with whatever their hearts desire!) - - admin: CentCom Supplypods now stun their target before landing, and won't damage - the station as much - Naksu: - - code_imp: clothing-specific flags are now defined in /obj/item/clothing.clothing_flags - - code_imp: More flags have been moved to their appropriate places - - code_imp: HEALS_EARS_2 is removed in favor of the earhealing component - - code_imp: wearertargeting component is available to subtype for components that - want to target the wearer of an item rather than the item itself - - code_imp: changed the shockedby list on doors to be only initialized when needed. - - tweak: Chameleon projector can no longer scan (often temporary) visual effects - like projectiles, flashes and the masked appearance of another chameleon projector - user - - bugfix: Drones can no longer see a static overlay over invisible revenants - - balance: adjusted default antag rep points to grant every job the same amount - of points per round, except for assistant which gets 30% less - - rscadd: Nuclear explosive-shaped beerkegs found on metastation can now be triggered - with the nuclear disk and the syndicate's legacy nuclear code for a foamy surprise - - bugfix: comms consoles now work in transit again, and no longer work in centcom - - code_imp: removed unnecessary getFlatIcons from holocalls - - bugfix: Screwdrivers and other items with overlays now show the proper appearance - of the item when attacking something with them, or when put on a tray. - - code_imp: moved /datum.isprocessing into datum flags - - code_imp: Removed unused effect object that could be used to spawn a list of humans - - tweak: The ladders in the tear in the fabric of reality no longer spawn their - endpoints when the area is loaded, but only when the tear is made accessible - via a BoH bomb. - - tweak: CentCom is no longer accessible via the space ladder in the tear. - - tweak: The lavaland endpoint can no longer spawn completely surrounded by lava, - unless it spawns on an island - - code_imp: ChangeTurf can now conditionally inherit the air of the turf it is replacing, - via the CHANGETURF_INHERIT_AIR flag. - - bugfix: when ladder endpoints are created, the binary turfs that are created inherit - the air of the turfs they are replacing. This means the lavaland ladder endpoint - will have the lavaland airmix, instead of a vacuum. - - code_imp: navigation beacons are now properly deregistered from their Z-level - list and re-registered on the correct one if moved across Z-levels by an effect - such as teleportation or a BoH-induced chasm. - - bugfix: constructed directional windows no longer leak atmos across them - - code_imp: setting the value of anchored for objects should be done via the setAnchored - proc to properly handle things like atmos updates in one place - Nicc: - - rscadd: toxins lab boii - Nichlas0010: - - tweak: Reseach Director Traitors can no longer receive an objective to steal the - Hand Teleporter - - bugfix: Comms consoles won't update while viewing messages - - spellcheck: you now feel nauseated instead of nauseous - - bugfix: You can no longer use a soapstone infinitely - - bugfix: You now can't get multiple download objectives! - - tweak: RDs, Scientists and Roboticists can no longer get download objectives! - Poojawa: - - tweak: Admin IC issue is no longer TG i ded passive aggressive. - - rscadd: Added *insult, for when you just can't think of anything more clever - - bugfix: Makes vore specific prefs call Rust_g else uses normal stuff. - - bugfix: Citadel Toggles should save properly now - - bugfix: fixed clothing vendor fedoras having Detective Fedora grade armor - - bugfix: Fixes missing icons on mag weapons for techmemes - - bugfix: Fixes APCs being replaced in maint from counting Maint as their wall turff - - rscadd: Added Vore based moodlets, primitive and ain't gunna adapt for not belly - things but w/e - Pubby: - - bugfix: 'PubbyStation: Fixed disposals issue in security hallway' - Robustin with cat earrs: - - bugfix: 'Gun overlays should be way less laggy now. remove: Chameleon guns are - completely removed since they crash the server, were already made unavailable, - and are the worst shitcode I''ve ever seen in my life.' - ShizCalev: - - bugfix: Adminorazine will no longer kill ash lizards. - - bugfix: Adminorazine will no longer remove quirks. - - bugfix: Fixed mobs immune to radiation being killed by HIGH bursts of radiation. - - bugfix: The book of mindswap will now properly mindswap it's users. - - bugfix: Fixed a runtime with the gulag teleporter that could cause the process - to fail if you removed the ID. - - tweak: Not setting the goal of a prisoner's ID when teleporting them will now - set the ID's goal to the default value (200 points at the time of this change.) - - bugfix: Fixed cigar cases & cigarette packets taking two inventory slots - - bugfix: Fixed cigar cases showing the wrong icon for the cigars inside them. - - bugfix: Fixed cigar cases & cigarette packets stating the wrong name of the cigar/cigarette - when removed via altclick. - - bugfix: Fixed items in pockets vanishing when a mob is monkeyized. - - bugfix: Fixed items in pockets vanishing when a mob is gorillized. - - bugfix: Fixed items in pockets vanishing when a mob is infected with a transformation - disease. - - bugfix: Fixed items in pockets not being properly deleted when a mob goes through - a recycler - - bugfix: Fixed items in pockets not being properly deleted when highlander mode - is enabled. - - bugfix: Fixed exploit allowing you to remove unremovable tanks from pockets. - - bugfix: Fixed items in pockets dropping when a mob is equipped with a new outfit. - - bugfix: Fixed items in pockets not being covered in blood when equipping the psycho - outfit. - SpaceManiac: - - bugfix: The destructive analyzer can once again be used to reveal nodes. - - spellcheck: Some references to "deconstructive analyzer" have been updated to - "destructive". - TGstation contributors: - - bugfix: Nukeop eshields are now buyable. tgstation/tgstation#39025 - - bugfix: Staff of storms now has admin logging. tgstation/tgstation#39011 - - bugfix: Fixed a couple of inconsistencies in the uplink descriptions of SMGs and - SMG ammo. tgstation/tgstation#38980 - - bugfix: Fixed blob victory. tgstation/tgstation#38988 - - tweak: You can now un-ignore notifications you've clicked "never this round" on, - and more. tgstation/tgstation#38990 - - bugfix: Fixes a weird bug with timers. tgstation/tgstation#38994 - - bugfix: (tgstation/tgstation#40043) - Beam rifles no longer open lockers - - bugfix: (tgstation/tgstation#40061) - Mobs can no longer get stuck at min/max - body temperature - - bugfix: (tgstation/tgstation#40041) - Pictures of asses are now properly sized - - bugfix: (tgstation/tgstation#40084) - The lastattacker var now includes unarmed - attacks - - bugfix: (tgstation/tgstation#39968) - Plastic golems can no longer ventcrawl with - items in their pockets - - bugfix: (tgstation/tgstation#39885) - You can no longer crash the server by overcharging - energy guns. - Thunder12345: - - rscadd: Added a colour picker component for use with circuits. - Time-Green: - - bugfix: Soda is no longer intangible to the laws of physics - Toriate: - - rscadd: It appears that ancient pieces of armor have wound up on the open market! - These armors have degraded beyond usefulness. Grab one now in the loadout! - - imageadd: added flak jacket and M1 Helmet sprites - - rscadd: Gives the flak helmet a tiny storage compartment - - balance: Made the flak helmet even weaker against acid and fire so it crumbles - into dust easier - - rscadd: Added the Corporate Uniform and the Silver Bike Horn - - imageadd: added sprites for the Corporate Uniform and Silver Bike Horn - Tupinambis: - - tweak: 'Removes the tesla coils from engineering secure storage, and places them - within the engine room, functional upon being wrenched down. (Arranged in the - common method of three coils on the left and right sides.) - - Reduces the width of engineering secure storage and its blast door by one tile. - The machinery within has been rearranged in order to make the most commonly - used machinery the most accessible.' - - tweak: Replaces the blood-red hardsuit in Deep Storage with a mining EVA hardsuit, - and an included oxygen jetpack. - - rscadd: 'Adds a replacement to the old lavaland xeno ruins in the form of lavaland_surface_alien_nest.dmm An - image of which is shown below. (The area layer is disabled for visibility.) - ![hive](https://user-images.githubusercontent.com/42078130/44291327-43df0d00-a243-11e8-9e72-ba8f81d31370.PNG) - ![hive2](https://user-images.githubusercontent.com/42078130/44291330-47729400-a243-11e8-998d-660063fa9f41.PNG) - - This replacement is designed to act as a sort of raid, with the queen as the - raid boss. The most notable loot includes the corpse of a drone, security bio - armor, a bone axe, some basic syndicate equipment, and a syringe containing - alien microbes. All references to the old lavaland xeno ruins have been replaced - with references to the new map file.' - - rscadd: New corpse spawners for alien queens and drones. - - rscadd: New syringe containing the alien microbe reagent. - - rscdel: Removed the currently unused lavaland_surface_xeno_nest.dmm map file, - and its references. - - rscadd: Added an experimental hard suit to toxins bomb test room on Box. - - tweak: Increased the size of the toxins bomb test room, moved the telescreen, - and added chairs on Box. - - tweak: Moved some pipes out of the way on Box and Meta. - - rscadd: 'Two air pumps have been added to the toxins lab on Pubby and Meta. - - The following changes apply to Box, Meta, and Pubby:' - - tweak: Unbolts the toxin burn chamber doors on round start. - - tweak: Unlocks the toxins lab air alarm on round start. - - tweak: When spawned as a nuclear operative, you keep your characters race instead - of being changed into a human. Plasmamen are an exception to this change. - - tweak: By popular request, makes the Head of Security spawn with a telebaton instead - of a stun baton. - Werebear: - - rscadd: Seven new holochassis options for pAIs and two new display images for - pAIs. - Wilchen: - - rscdel: Removed box of firing pins from rd's locker - XDTM: - - bugfix: Fixed anti-magic not working at all. - - bugfix: Diseases now properly lose scan invisibility if their stealth drops below - the required threshold. - - tweak: Coldproof mobs can now be cooled down, but are still immune to the negative - effects of cold. - - bugfix: This also fixes some edge cases (freezing beams) where mobs could be cooled - down and damaged despite cold resistance. - - balance: Androids are now immune to radiation. - Xhuis: - - tweak: Character traits are now called character quirks. Functionality remains - unaffected. - Zxaber: - - rscadd: Cyborgs can wear more hats now. - and Fel: - - imageadd: New chairs are on most shuttles! Finally, you can relax in style while - escaping a metal death trap. - armhulen: - - rscdel: chameleon guns are disabled for breaking the server - cacogen: - - rscadd: You can now see what other people are eating or drinking. - - rscadd: Borg shaker can now synthesise milk, lemon juice, banana juice and coffee - - bugfix: Renamed drinks no longer revert to their original name when their reagents - change - cyclowns: - - bugfix: Fires no longer flicker back and forth like crazy - - rscadd: Fusion has been re-enabled! It works similarly to before, but with some - slight modification. - - tweak: Fusion now requires huge amounts of plasma and tritium, as well as a very - high thermal energy and temperature to start. There are several tiers of fusion - that cause different benefits and effects. - - tweak: The fusion power of most gases has been tweaked to allow for more interesting - interactions. - - tweak: BZ now takes N2O and plasma to create, rather than tritium and plasma. - - bugfix: Fusion no longer delivers server-crashingly large amounts of radiation - and stationwide EMPs. - deathride58: - - tweak: (Only visible on 512) Stamina crit will now result in the mob's sprite - subtly darkening around its edges. - - rscadd: Added a tiny reference item to a year-old weeby game. If you're a traitor, - you can find this item in the "badassery" section of the uplink. It's free, - and you can order up to 4 of them! The effects of this item are only visible - on 512. - - code_imp: Added a component signal for toggling combat mode on/off. - - balance: The cleaving saw now deals less staminaloss to its user while inactive. - - rscadd: You can now make use of custom say verbs with the [say verb*message] format - - rscadd: Yelling will now echo and penetrate walls - - tweak: Distant voices now have smaller text - - tweak: You can now see the amount of charges an emag has by examining it - - tweak: Emags now make a quiet noise when they're close to running out of charges. - - tweak: Emags are no longer irreversibly destroyed upon running out of charges. - - rscadd: Traitors can now purchase emag recharge devices for 2 TC. They have five - extra charges each, and can be found in the devices and tools section of the - uplink.. There's no cap on the amount of charges a single emag can have, though - do be aware that upstream spaghetti code makes it easy to waste charges. - - tweak: Small emag flavortext changes here and there - - balance: The warden's particle defender now deals less staminaloss when in stun - mode. - - tweak: '"code [alert level]" has been changed to "[alert level] alert" on the - hub entry.' - - tweak: The hub entry now displays the current map. - - tweak: Lavaland is no longer fullbright. We have memory to spare. - - rscadd: Adds the wheelofsalt command to TGS3. Spin the wheel of salt to find out - what the Citadel Station 13 players are salting about today! - - rscadd: You can now slam or slap your hands onto tables by right clicking them - in combat mode. - - tweak: Non-admins can no longer use LOOC while dead, unconscious, in crit, or - while ghosting. - - tweak: The syndicate mask available in the uplink will now inject you with a chem - that cuts your click delay in half and increases your stamina regeneration, - when you enter combat mode. The mask has a five minute cooldown between adrenaline - injections. - - balance: Dogborgs will now reduce firestacks when they use their tongue to lick - someone's face. - - bugfix: The repo compiles again - - bugfix: The flag cape donor item should render properly now. - - tweak: The default amount of z-levels reserved specifically for space ruin generation - has been reduced from 7 to 1 - - bugfix: Items now spawn on top of, rather than inside, closets and other storage - structures - - rscadd: Jukeboxes now have realtime directional audio, complete with occlusion - when you're far away or behind a wall. - - rscadd: More than one jukebox can play a song at a time now. Have up to 5 jukeboxes - playing at once! - - rscadd: Devs can now control the wet and dry channels of sounds played via playsound_local. - The new envwet and envdry arguments will control the volume of the wet and dry - track, respectively. - - code_imp: Jukeboxes have been turned into a subsystem. Track initialization, audio - playing, etc, are now handled via SSJukeboxes instead of via the jukebox object - procs. - - config: Jukebox tracks now require an additional ID field at the end of their - name. This will make it easier to add jukebox-style objects that are only capable - of playing specific songs, without worrying about copyright issues. - - rscadd: Added Raiq's boombox as a donor item - - rscadd: You can now manipulate tails, ears, body markings, mutant colors, and - taur types via DNA console! - - balance: Reduced the exponent on gas tank ruptures. TTVs and suicide onetanks - that were previously 20dev are now approximately 9.6dev. Let's see the actual - toxins nerds adapt! - - tweak: When a custom say verb message is spoken without any actual words, the - text will render without a `, ""` at the end of it. - - balance: The combat rework's training wheels have been removed. Knockdowns no - longer have any noticeable stun. This indirectly means stunbatons and tasers - will always deal their full stamloss on hit. - - balance: The stamloss required for boxing gloves to throw a knockout punch has - been increased from 50 to 100. - - rscadd: You can now prime the grenade on bombspears by using them in your hand. - The wield hotkey is moved to combat mode rightclick while a spear has a grenade - on it. This is explained in the examine text. - - balance: Bombspears no longer instantly explode on impact when thrown. They now - have to be primed to explode when thrown. - - balance: Bombspears now have 90% embed chance. - - rscadd: If an embedded item is normal sized or larger, you can take it out instantly - by pressing resist. - - balance: Embedded items are now much harder to pull out the smaller they are, - rather than the other way around. It's much easier to rip out a sword from your - chest than it is a shard of glass in your face. - - tweak: The message you get when you get bounced by the PB is now a little more - clear about what you need to do to gain access to the server. - - balance: The jukebox now falls off over a greater distance. You can now actually - hear the jukebox while sitting in a far corner of the bar, or while passing - through the main hallways. - - rscadd: Added antag OOC. This is disabled by default, but you can access it with - the "AOOC" verb as an antagonist when an administrator enables it. - - tweak: LOOC now supports emojis - - tweak: 'Deadchat and asay will now both render emojis! :snya:' - - balance: The disarm attack on EMP'd defibs now has an interruptible 1 second timer - before it actually lands. - - balance: The stamina buffer now only takes 1 second to start regenerating. - - balance: Disablers have had their damage reduced from 36 stamloss to 24 stamloss, - increasing their shots to stamcrit from 4 to 6. - - balance: Tasers have had their damage increased from 55 stamloss total to 61 stamloss - total. Shots required to stamcrit are unaffected. - - rscadd: Introducing the Kitchen Gun (TM)! Say goodbye to daily stains and dirty - surfaces with Kitchen Gun (TM)! Just five shots from Kitchen Gun (TM), and it'll - sparkle like new! Includes two extra ammunition clips for the low, low price - of just 10 TC! Laser sight and night vision accessories sold separately! Magazines - can be purchased individually for 1 TC a pop! - - tweak: Active turf processing is now its own subsystem. - - code_imp: Ports tgstation/tgstation#39287 - You can now configure how fast a mob - fires, and how many shots they fire in a single burst - - rscadd: When you spawn as a miner, you'll get text clarifying your job description. - You might not think it's necessary, but believe me, it is. - - rscadd: mushroom people are now roundstart on live - - rscadd: The geargroupID var of loadout entries can now be a list rather than a - string. GeargroupID changes are additive when multiple are defined in a single - loadout entry. - deathride58 (Original PR by Basilman/Militaires): - - rscadd: Ported TGstation's Agent Stealth Box! You can the implanter in the syndicate - uplink for 8 TC. Credit goes to Basilman/Militaires. This port includes minor - adjustments, see the GitHub for details. - hatterhat after being yelled at by kevinz: - - bugfix: deletes an entire line that might fix flash icons idk blame him if it - gets worse - iksyp: - - rscadd: stacking machines and their consoles no longer dissapear into the shadow - realm when broken - - rscadd: you can link the stacking machine and its console by using a multitool - - bugfix: Ever since the great emotion purge of 2558, people were able to work at - top efficiency, even while starving to death. This is no longer the case, Nanotrasen - Scientists say. - - admin: Hunger slowdown only applies if mood is disabled in the config. - imsxz: - - admin: Using mayhem bottles and going under their effects is now logged. - izzyinbox: - - rscadd: Added an integrated circuit part that interacts with the arousal system - - tweak: changes the admin-pm input box from single line to multi-line - - bugfix: Tennis balls now equip and show up in the correct slots - - rscadd: Adds option in the hide/expose genitals verb to hide genitals even without - clothes - kevinz000: - - rscadd: Cameras now can take pictures up to 7x7. Alt click them to change their - width/height from the default 3x3. - - rscadd: Photos are now logged to disk, assuming the host enabled the configuration - option - - rscadd: If the above is enabled, albums/frames can now have their persistence - IDs set in variables to allow for PHOTO PERSISTENCE - - rscadd: Every head of staff gets a unique album with its own ID in their locker. - Let your successors know about your accomplishments, screwups, and everything - in between! - - rscadd: All of this works or should work with newcasters/pdas/etc etc - - rscadd: Photo taking now clones the area into transit space and then operates - on it, instead of on the spot, in theory making photographing things more accurate? - nicc: - - rscadd: no more dark locker corner woo - - tweak: area alterations - - rscadd: escape pod - - rscadd: see above - - rscadd: adds windoor to the plastic flaps in the atmos lobby - ninjanomnom: - - rscadd: A plush that knows too much has found its way to the bus ruin. - resistor: - - rscadd: Added circuit labels! You can now customize the description of your assemblies. - slate3: - - rscadd: ported a new alternative sprite for engineering borgs, mr. handy - - rscadd: ported a new alternative sprite for security borgs, a spider-like walker - - rscadd: ported a new alternative sprite for medical borgs, an eyebot - steamport: - - bugfix: Borgs/AIs can now toggle rad collectors - ursamedium: - - bugfix: slapping / slamming hands on tables now uses appropriate pronouns - - bugfix: crow pAI is no longer invisible while resting - yenwodyah: - - bugfix: A few virus threshold effects should work now - yorii: - - bugfix: Fixed the smartfridges to be in line with all other machines and puts - the released item in your hand. - yorpan: - - rscadd: Brain damage makes you say one more thing. -2019-11-04: - 4dplanner, MMiracles: - - tweak: Wizard shapeshift now converts damage taken while transformed - - bugfix: transform spell transfers damage correctly instead of healing most of - the time - - bugfix: 0% simplemob health maps to 0 carbon health, 100% simplemob to 100% carbon - - bugfix: transforming to a form with brute resistance no longer heals you - - bugfix: transforming back to a species with brute resistance no longer heals you - AdmiralPancakes1: - - rscadd: 'Cryo cell shortcuts: alt-click toggles the doors, ctrl-click toggles - the power' - Alonefromhell: - - rscadd: Ported Oracle UI, a framework for self-updating and neat UI's - - refactor: Paper now uses OUI - - refactor: Bins now use OUI - - bugfix: fixes tootip offset - AnalWerewolf: - - rscadd: Fritz plushie - - rscadd: Donor item - Anonymous: - - imageadd: 'More crusader armor variants to pick from armament: Teutonic and Hospitaller.' - Arturlang: - - rscadd: You can now use CTRL and ALT click on pumps and filters to toggle them - on and off and max their output respectively - - rscadd: You can now use RPDs on windows and grilles. - - rscadd: The RD can now suplex a immovable rod. Good fucking luck. - - bugfix: Fixes high alert ERT suit sprites. You can see them now! - - rscadd: Traitor codewords are now highlighted for traitors. - - rscadd: You can now examine pumps filters and mixers to see if you can use CTRL - and Alt click on them. - - bugfix: Fixes brain damage/trauma healing nanites so they actually work while - there are only traumas. - - tweak: Advanced toxin filtration nanites now heal slimes - Bhijn: - - rscadd: It's now possible to forcefully eject the occupants of a dogborg's sleeper - by using a crowbar on them. This action is instant. - - tweak: Resist values for dogborg sleepers have been adjusted. The baseline has - been decreased from 30 seconds to 15 seconds. Medihound sleepers have a resist - timer of 3 seconds. Sechound sleepers retain a resist timer of 30 seconds. - - tweak: It now takes 10 full seconds to insert people into your sleeper. This should - hopefully give people some more room to breathe and react to a dogborg attempting - to sleeper someone either for no reason or in a way that violates law 2. - - bugfix: Warp whistles no longer grant permanent invulnerability and invisibility - - bugfix: You can now actually use the resist hotkey to resist out of handcuffs. - Woah, revolutionary - - bugfix: the `!tgs poly` command now actually works - - rscadd: Poly now has a 0.01% chance per squawk to speak through the TGS relay. - - balance: The point production mode of radiation collectors has been reverted to - the original behavior of using all of the stored power every process cycle instead - of just 4% of it - - tweak: Radiation collectors now display the amount of power/research points they're - producing per minute rather than per process cycle, which should hopefully clear - up a lot of confusion. - - tweak: Radiation collectors also display what's happening to the gas within them, - which should make it a lot more obvious as to how you get tritium. - - tweak: Security borgs and K9s are now only available during red alert or higher. - - server: Headmins or other folks with access to the server's config can choose - the minimum alert level for secborgs to be chosen via the MINIMUM_SECBORG_ALERT - config option. See the default game_options.txt for more info. - - bugfix: The server no longer attempts to check if the CID matches the IP of any - bans, or if the IP matches any CIDs of any active bans, during client analyzation - - balance: Vampires can now only ventcrawl in bat form if their blood level is below - the bad blood volume (224 blood total) - - balance: Vampires now only take 5 burn per mob life cycle while within chapel - areas, down from the original 20 burn per life cycle. - - tweak: K9 pounces have received a minor rework. It now has an effective cooldown - of 2.5 seconds, can now only deal up to 120 staminaloss, deals a maximum of - 80 stamloss on hit, has a spoolup of half a second, and now has telegraphing - in the form of a quiet noise. - - balance: K9s now only have 80 health - - balance: Secborgs (but not k9s) now have a hybrid taser. This can be toggled via - server config. - - tweak: The disabler cooler upgrade now applies to all energy-based firearms for - borgs - - rscadd: Dogborg jaws are now capable of incapacitating targets if using help intent. - This deals a hard stun depending on how much staminaloss the target has, and - whether or not they're resting. This behavior can be toggled via server config. - - balance: K9 jaws now have 15 force, up from their nerfed 10 force. - - balance: Borg flashes regained their ability to cause knockdown. This can be toggled - via server config. - - server: The WEAKEN_SECBORG config option will disable the new dogborg jaws mechanic - and make secborgs spawn with a standard disabler. - - server: The DISABLE_BORG_FLASH_KNOCKDOWN will disable the ability for borg flashes - to knockdown. - - tweak: Jukeboxes now have 6 audio channels available to them, up from the previous - accidental 2 and previously intended 5 channels. - - bugfix: Jukeboxes now work again on clients running versions higher than 512.1459. - - bugfix: People will no longer have their ears consumed by an eldritch god if multiple - jukeboxes are active and the first jukebox in the jukebox list stops playing, - then tries to play again - - tweak: Instead of the debug text for invalid jukebox behavior being printed to - world, the debug text is now restricted to the runtime panel. - BurgerB: - - tweak: Tweaked the UI of the loadout to be less cluttered due to an issue with - formatting. - BurgerBB: - - rscadd: Adds the bonermeter; a device that measures arousal based statistics. - - refactor: Added a new input to the electrostimulator that controls the strength - of the shock. It accepts negative inputs which reduce arousal. Added a new output - to the electrostimulator that displays the amount of arousal gained. - - balance: Rebalanced the electro-stimulator to be less spammy by giving it a 2.5 - second enforced cooldown per circuit contraption. Increased the complexity of - electro stimulator from 10 to 15. - - refactor: Reworked the Vent Clog event to spray smoke instead of foam, also made - it shoot smoke over time instead through each vent instead of all at once. - - tweak: Increased the spawn area of the City of Cogs (Reebe). This does not affect - the area in which builders can build. - - balance: Significantly tweaks the Wizard race transformation event to be less - unreasonably troublesome. - - rscadd: Adds a new 0 cost trait that makes you immune* to Crocin and Hexacrocin - - tweak: Tweaks how slurring works so it's more of a gradual change into slurring - instead of immediate. - - balance: Slurring is now directly proportional to your drunkenness, with other - sources of slur being added on top of it. - - tweak: Bras are now separate from underwear, meaning you can mix and match bras - if you're into that. - - tweak: Men can wear female accessory clothing, and females can wear men accessory - clothing. It's not a fetish, mom, it's PROGRESSIVE. - - code_imp: Reorganized accessories into their own files to prevent a massive 1000 - line file. - - server: i'm 10% sure that merging this PR will cause preference corruption sooooooooooo - I just need to hear from @deathride58 or perhaps someone else on how much damage - this could possibly do. - - tweak: Tweaked penis. - - balance: Rebalanced penis. - - rscadd: 'Added the following reagents to the common list of vent clog reagents: - ~~Cooking Oil~~, ~~Frost Oil~~, Sodium Chloride, Corn Oil, Uranium, Carpet, - Firefighting Foam, semen, femcum, tear juice, strange reagent, ~~spraytan~~.' - - balance: Vent Clog smoke emits the same transparent smoke as a smoke machine, - including how much it transfers. Vent Clogs also do not trigger in areas deemed - "Safe" in code, such as in the dorms or trusted areas where dangerous things - shouldn't occur. - - rscadd: Adds additional random brain damage text - - rscadd: Adds penis enlargement pills. - - rscadd: Adds Stun Circuit and Pneumatic Cannon Integrated Circuits - - bugfix: Fixed extinguisher and smoke circuits not accepting any reagents. - - rscadd: Adds a few important clockcult tips. - - rscadd: Added Mech Sensors, a brass-created trap that activates when a mech not - controlled by a cultist crosses it. - - rscadd: Added power nullifiers, an emp trap that emps everything in a 3x3 area, - with the center suffering a heavy EMP. - - tweak: Brass Skewers now deal 50 damage to mechs. - - balance: Ass slapping only works if you're actually behind the target. Ass slapping - now respects disarm blocking. You can no longer face/ass slap someone on an - intent other than help, unless they are also face/ass slapping. - - bugfix: Fixed ass and face slapping grammar. - - rscadd: Adds meh effects for ass and face slapping. - - tweak: '"Unwillingly" eating food now sends a warning message instead of a notice. - Unable to stuff food down your throat sends a danger message instead of a warning - message.' - - rscadd: Adds clockwork reflectors, a fragile anti-laser reflection shield object - that can be constructed for 10 brass sheets. Upon firing on the object in the - direction where it is shielded, it ricochets the bullet off of it relative to - the shooting angle. - - tweak: Renames some windows in the build menu for consistency. - - balance: Clockwork Cult walls can no longer be deconstructed by RCDs when heated. - - rscadd: Adds several new toy loot to the arcade machine. - - balance: Rebalanced the arcade machine loot. Battlemachines now have a 0.5 second - delay instead of a second delay between actions. - - bugfix: Fixed a bug that would not allow the one in a million pulse rifle to spawn. - - rscadd: Adds a new trait "Buns of Steel" that makes you immune to the effects - of ass slapping, and temporarily makes the user's arm useless like a stun baton - hit. It costs 0 points. - - balance: Ass slapping blowback from the Buns of Steel perk now deals 20 stamina - damage instead of 50, and no brute damage. - - rscadd: Gamemode voting results are displayed at the end-round screen. - - balance: Cloning no longer gives you positive mutations, but a chance for a negative - one. Cloning has a chance to "scramble" your visual DNA. - - balance: Chestbursters no longer give and remove your brain. They just disembowel - and kill you now. - - bugfix: Fixes WarOps miscalculating players. - - balance: Activating the nuclear device during war-ops informs the crew of the - nuke's position. - - rscadd: The alert level is displayed at the job selection screen. - - balance: Central Command informs you when a Meteor Storm is about to hit 5 to - 10 minutes before it happens. - BurgerLUA: - - code_imp: Added a new framework for reagents. Reagents can now have a bool that - determines if it can be detected by handheld medical analyzers. Currently only - the changeling sting chemical does this. - - balance: Made changeling transformation string last between 10-15 minutes. Lowered - the dna cost of changeling sting from 3 dna to 2 dna. Lowered the chemical cost - from 50 to 10. Lowered the loudness from 2 to 1. Changeling sting transformation - can be removed via high doses of calomel. - - bugfix: Fixed most reagents having a placeholder color. - - bugfix: Fixed autolathe wires not correctly shocking you when pulsed. - - balance: Rebalanced special jetpacks. - CalamaBanana: - - rscadd: Added Deer taur - - rscadd: Added Elf ears to mammals - CameronWoof: - - rscadd: Medihounds now have rollerbeds for non-vore patient transport - - bugfix: The closed O2 crate now uses the same color scheme as the open one - - tweak: air alarms are green now instead of blue when the atmosphere is ideal - - tweak: Hexacrocin overdose no longer causes climaxes - - tweak: Altered the icons for inventory backplates. Sleek! Stylish! New! - - bugfix: Attaching a beaker that contains water to an IV stand no longer causes - a visual glitch - - tweak: Fluid-producing sexual organs no longer start full - - tweak: Sexual organ fluid capacity decreased from 50 to 15 - - tweak: Sexual organ production rate decreased from 5u to 0.035u per two seconds. - - tweak: Sexual fluid decals no longer contain reagents - - tweak: Sexual fluids cannot by synthesized (e.g., by the Odysseus) - CdrCross: - - rscadd: Adds the ability for cloning consoles to read and write record lists to - the circuit board, and provides a template for giving other machines local circuit - board memory. - Cebutris: - - rscadd: Hugs of the North Star! Get them from the arcades (if you're lucky) and - hug your friends at INCREDIBLE hihg speeds! - - bugfix: Tea Aspera now properly contains tea powder - - tweak: Breasts no longer lactate by default, lactation is now a preference - Chayse: - - tweak: Changed the Warden's compact combat shotgun to instead be a regular combat - shotgun with a foldable stock and penalties for being folded. - - rscadd: Assorted space-worthy helmets can now act as masks for internals. - - refactor: Internals code can now check any item with the ALLOWSINTERNALS flag - through the GET_INTERNAL_SLOTS define. For now this only checks head and mask - slots, since those are the most realistically speaking usable ones. - - tweak: Medbay doors can now be opened by anyone from the inside without having - to press the exit button. - - bugfix: Borgs now have the necessary dexterity to unbuckle people from themselves - and from bucklable objects. - - bugfix: Fixes the Trek Uniform/Suit worn icons - - bugfix: AIs can now once more talk through holopads successfully - Code-Cygnet: - - rscadd: Added new things - Mind trait, alcohol reagent, chemical reagent, drink - sprite and recipe. - - imageadd: added commander_and_chief sprite to drinks.dmi - Coolgat3: - - tweak: Changed player number checks to 20 from 24 for cult and clockcult, also - made nukeops 28 required players instead of 30. - - tweak: Changed enemy minimum age from 14 to 7 - - rscadd: Added the code for the semen donut and made it craftable - - imageadd: Added the donut sprites - - bugfix: Made the sec and warden berret offer as much protection like the helmet - - rscadd: Added berets for all the heads. - - imageadd: Added sprites for the berets. - - code_imp: Coded the berets to spawn in appropiate lockers. - - tweak: Raised the ripley's movement speed and lights range by 1, also lowered - its armor to compensate. - - rscadd: Added combat gloves sprite - - imageadd: Added said sprite - - imageadd: added combat boots sprite - Coolgat3 / Avunia: - - rscadd: Made kindle put the target into stamcrit, which makes it an actually working, - useful stun. - - rscadd: Added a stamina loss modifier to the vanguard spell which makes the user's - stamina drain at a way slower rate. This doesn't make them immune to tasers, - but it takes a few hits to actually get them to fall down. - - tweak: Made it so that clock culties don't start with a chameleon suit. Instead - they start with an engineer suit which is pretty much the same sprite and looks. - If this is not perfect, then I am willing to make a slightly more brass-colored - version of the engineer suit sprite and call it a ratvarian engineer jumpsuit. - - balance: Increased the cost of vanguard, as it is now a spell that works somewhat - like adrenals, minus the move speed, making your stamina drain really slow and - making you unable to get knocked onto the ground by just a single taser shot. - - balance: Lowered the charge time of kindle, reason being that you can usually - have only one active spell on you, or two at max if you decide to run two slabs, - but the fact that kindle silences people for such a small amount of time makes - up for it, in my opinion. - - server: Figured out that the consoles and their warp function actually work with - the current code. The thing that makes them not work is when the gamemode is - ran on debug mode, without the required players to actually support it. It also - breaks the ark timer which is stuck on -1 seconds until activation. Whenever - the gamemode starts properly, like any other gamemode, with player checks and - all, everything seems to work just fine. - CydiaButt13: - - rscadd: Lamp Plushie to loadout - - imageadd: added plushie_lamp to plush icons - - code_imp: added Lamp Plush to loadout and icons and items - EgoSumStultus: - - bugfix: Fixed blood chiller's inhand - - bugfix: FIXED SHIELF - - bugfix: fixed magpistol magazine sprites - - rscadd: Added the Femur Breaker - - rscadd: Adds male AI vox. - EmeraldSundisk: - - rscadd: Adds a gun range to Box Station - - rscadd: Provides some extra power grid connections - - rscdel: Sunglasses and Earmuffs removed from the Warden's Office - they can be - found at the range instead - - tweak: Rearranges a few objects within the prison as to accommodate the new gun - range - - rscadd: Adds a mass driver to Delta Station's chapel - - rscadd: Adds a second means of entry into the chapel - - tweak: Slightly expands the chapel to make room for the driver, slight adjustment - to air systems - - tweak: Clears a path in the station exterior for the mass driver to work properly - - tweak: Nearby maintenance loot has been relocated to accommodate the chapel expansion, - surrounding area has been "cleaned up" somewhat - - tweak: CentCom has noticed the lack of coffins in Delta Station's chapel and provided - some, but in exchange for reducing the chapel morgue's capacity. - - tweak: Fixed a maintenance door the chaplain should have been able to open. - - bugfix: 'Fixes space areas outside the driver removal: CentCom Defense Analysts - have ordered the maintenance hatch to the Mass Driver room be removed citing - "security concerns".' - - rscadd: Increases the number of plots to 9 (from 5) - - rscadd: Additional lighting placed directly outside the garden - - tweak: Cleans up the area to reflect use. Moves the seed extractor to a more central - location - - tweak: 'Relocates the seed packs on botany''s counter to the garden removal: Removes - wooden barricades outside the garden' - - config: Renames "Abandoned Garden" area designation to "Maintenance Garden", but - does not replace the icon in Dream Maker - - rscadd: Expands the chapel mass driver room to make it easier to use - - rscadd: Rearranges the chapel backroom so there are now six coffins and burial - garments roundstart - - tweak: Cleans up the Janitor's office - - tweak: Readjusts the station exterior so mass-driven coffins (hopefully) have - less friction - - bugfix: Adds a fan to the chapel driver - - bugfix: The Janitor missed a few spots around the newly renovated Maintenance - Garden - - bugfix: Readjusts positioning of Delta's QM keycard device - - bugfix: 'Cleaned up a few spots I missed in #9356, particularly around the janitor''s - office' - - rscadd: Adds some potted plants around Box Station - - bugfix: 'The tile mentioned in #9409 should now be radiation-free.' - Fermi: - - bugfix: Fixes tiny runaway decimals in reagents system. - - bugfix: 'SDGF: Fixes infinite clones.' - - bugfix: fixed an angery PR - Fermis: - - rscadd: Added a panda simplemob - - bugfix: fixes empathy exploit. - - rscadd: Added the secbat, a box to hold it and the ability to dispense it from - the SecTech vendor. - - rscadd: Adds 3 new music tracks. - - tweak: tweaked Neurotoxin - - balance: added more depth to Neurotoxin - - bugfix: fixed the inability to create Neurotoxin - - bugfix: fixes fermichem reactions for tiny volumes work - - tweak: makes quantisation level for chemistry finer - - tweak: re-enables femichem explosions in grenades. - - tweak: adds nuance to the SDGF and hatmium explosions. - - bugfix: Fixes analyse function on ChemMasters to correctly display purity. - - bugfix: Fixes the custom transfer for buffer to beaker button. - - rscadd: 'Debug option: Generate Wikichems' - - rscadd: graft synthtissue surgery, new reagent synthtissue - - tweak: 'neurine fixes brain objs merge: combines fermichem''s lung damage with - tg''s' - - rscadd: on_mob_dead(), bitflags and CHECK_MULTIPLE_BITFIELDS - - refactor: refactored fermichem vars, moved impure chems into their own reagents - subtype - - bugfix: Fixes small residues of chems that won't go away! - - tweak: tweaked beaker health and allows use of syringes/droppers on chem_heaters - - soundadd: added a sound for when beakers take temperature damage. - - imageadd: added some icons for melting beakers - - refactor: refactored how beakers take damage - - bugfix: fixes how beakers would only take one instance of damage on pH damage - - bugfix: fixes Janitor grenades. - - bugfix: fixes reaction mechanics at low volumes - - bugfix: stops reactions constantly bubbling on the edge of reaction temperature - - bugfix: stops small amount reactions from occurring, and prevents disappearing - tiny numbers - - tweak: Reduced minimum reaction volume from 1 to 0.01 - - refactor: cleaned up Fermichem - - rscadd: Adds Jacqueline the Pumpqueen and her familiar Bartholomew for the spooky - season - - soundadd: Adds a giggle - - imageadd: 'Adds cauldron, Jacq and Jacq o lanterns, and a costume for halloween! - mapedit: adds a new landmark so Bartholomew can spawn somewhere sensible.' - - bugfix: fixes food reactions and explosion runtimes, - - bugfix: fixes the too much yes problem - - bugfix: Heart, Tongue and stomach regen. - - bugfix: lung damage threshholds. - - bugfix: Graft synthtissue - - bugfix: Skeleton's burning for no reason - - bugfix: Organ freezing handling. - - bugfix: Fixes chemistry books to point to the right wiki, and keeps tg's just - in case - - tweak: Changes top right wiki button location to go to both wikis - - bugfix: fixed Jacq's fondness for the AI - Ghom: - - code_imp: minor clean up on hydroponics reagent containers. - - bugfix: fixes the perpetual lack of moisture that has affected genitalia descriptions - since, like, forever. - - rscadd: implements the arousal state for mammary glands. - Ghommie: - - bugfix: Fixes many possible situations of null icons for cit races' bodyparts. - - imagedel: Removes duplicate slimepeople' sprites. - - code_imp: Purges that draw_citadel_parts(). - - code_imp: Fixes ISINRANGE_EX using the wrong relational operator. - - tweak: The kindle status effect stun duration now properly proportional to the - owner's remaining health. - - tweak: Clockwork cult's kindle now affects silicons. - - tweak: Cyborg mounted disablers/tasers/lasers now slowly self-recharge off the - cyborg user's power cell instead of draining from it directly. - - tweak: Borg rechargers now properly recharge the borg module's energy guns. - - bugfix: Prevents a couple more special/mounted guns from being preserved on cryo - - balance: Halved borg energy guns self-recharge delay and increased their cell - capacity by 3/4 - - bugfix: Fixes chemical patches always checking the suit slot even if the targetted - limb was the head. - - bugfix: Skeleton, nightmare and golem races are once again available to get chemical - patches applied onto. - - rscadd: Adds two cartons of space milk to the space skellie pirates cutter's fridge. - - refactor: Refactored implants to not be located inside mobs codewise, akin to - organs. - - bugfix: Fixed gps tracking implants. - - bugfix: Fixed item not being dumped out of storage implants onto the owner's turf - upon removal. - - bugfix: Fixes cult potentially stalling if the target is erased from existence - without being sacced. - - balance: Nukes the stunprod's 3 seconds delay. - - bugfix: Fixes teleprods. - - bugfix: Stops pulls of resting mobs breaking off whenever you swap turfs with - someone else because of crawling delays. - - bugfix: fixes IAA. - - balance: EMPs now flick off stunbatons, they can be turned back on immediately - by the user anyway. - - balance: Stunbatons now very slowly consume charge whilst kept on, at a rate of - 4/1000th of a standard batoning charge cost per tick. - - balance: Softened up the charge cost checks to stop the above update from practically - reducing the maximum uses of a stun baton by one. Now, should the remaining - charge be lower than the hit cost, the resulting stun will be be proportional - to the remaining charge divided by the hitcost, within a limit under which the - stun batoning just won't happen. - - balance: Buffs condensed capsaicin, a yet another feature previously dunked by - stam combat. - - balance: speeds up pepper spray puffs. - - balance: Buffed krav maga leg sweep stun and stamina damage. On the other hand, - it's now unable to be used on already lying targets. - - bugfix: fixes eyestabbing people with cutlery while being a pacifist. - - bugfix: Reduces goonchat lag from being blasted by pellets and bullets repeatedly - whilst wearing armor by properly removing the armor protection texts this times. - - spellcheck: also reduced the size of armor protection messages in general. they - clog up the chat box. - - bugfix: Fixes stunbatons icon not properly updating on cell removal and insertion. - - tweak: Allows lower charge cells to be used with stun batons, and thus single - use crapshots batons. - - balance: Adds in a 7 seconds delay to the jackhammer dismantling a superheated - clockwork wall. - - tweak: escape pods emergency suits storage can now be busted open by emags or - excessive damage. - - bugfix: Fixes alt click bypassing the escape pods' suits storage lock. - - bugfix: Fixes emags wasting charges on un-emaggable & co stuff. - - code_imp: Ported some radials code updates. - - rscadd: Ported the RCL wiring menu and a comfier RCD interface. - - tweak: A milder combat stance message will show up if the user switch combat mode - on while on help intent. - - spellcheck: Properly rewords the extinguisher's instructions on how to empty it - on the floor since it was changed to be a screwdriver action instead of Alt - Click a while ago. - - rscadd: Reskinnable PDAs. A related game preference. - - refactor: Refactoring the pda, pda painter, obj reskinning and chameleon pda a - bit to support this feature. - - imageadd: more PDA sprites and ported reskins. - - refactor: turned virtual reality into a component datum, which is then applied - to spawned virtual mobs. This fixes mob transformations (such as wabbajack and - monkeyizing) breaking the previously hardcoded behaviour and trapping you in - VR, also enabling a more concrete virtual reality inception experience. - - bugfix: Fixes power cells being unable to be rigged. Also prevents them from starting - processing on init if they don't self recharge. - - bugfix: Fixes many, little or otherwise, issues with the stunbaton status refactor. - - bugfix: The sacrificial target icon will now display onto the cult objective ui - alert once again. - - bugfix: Stopping borgs from sprinting into negative cell charge. - - tweak: The default amount of z-levels reserved specifically for space ruin generation - has been increased from 1 to 2 - - tweak: 'Moving some tablecrafting recipes to the appropriate categories: Kitty - ears and lizard cloche hats to "clothing"; Hot dogs to "Sandwichs"; Cuban carb, - fish and chips and fish fingers to "Fish".' - - bugfix: Fixes the not-a-sandwich recipe being M.I.A. - - rscadd: Adding in peanuts, peanut butter, peanut butter toasts and sandwiches, - and the PB&J sandwich. The peanuts contain a little bit of extractable cooking - oil (similarly to soy beans) and can be microwaved or dried in a drying rack - to make roasted peanuts, which can be mixed in a all-in-one-grinder for peanut - butter, required to make those sandwiches. - - balance: Buffed wizard and artificier's Magic Missile, wizard and xeno queen's - Repulse and juggernaut's Gauntlet Echo. - - bugfix: Fixes flashlights being unable to be used for rudimentary eyes and mouth - exams. - - rscadd: Adds in a grey jumpsuit to the loadout choices, restricted to Assistants. - - bugfix: Fixes CWC construct shells being visible as ghost role to latejoiners. - - imageadd: new sprites for the flechette gun, its magazines and the toy ray gun - - tweak: Merges the end-of-shift and its shuttle autocall announcements into one. - - bugfix: Prevents the end-of-shift shuttle from being recalled (even if to no avail). - - bugfix: Fixes being able to teleport papers to your location with TK. - - bugfix: Fixed some monkey-code shenanigeans making items sometimes disappear from - pickpocketing. - - imageadd: New sprites for the some pda cartridges. - - tweak: The crew monitor's entry for the Quartermaster will now appear bolded, - while HoP's will be of the same color of the service/unknown/other jobs. - - bugfix: emergency pods' storage will now properly work. - - bugfix: The PDA skin preference will now properly save up. - - tweak: Changed the default PDA icon var to match the default PDA skin preference. - - bugfix: Fixing the `(pointless) badassary` category appearing between the `dangerous - and conspicious` and `stealthy and inconspicious` categories. - - bugfix: Combat gloves plus now properly use the combat gloves sprite. - - bugfix: Fixes the space ninja's energy netting. - - rscadd: Adding one pAI to the wizard shuttle and ERT prep room - - bugfix: Fixes the rocket launcher being unreloadable. - - balance: Buffed its accuracy a bit. - - tweak: Replaced the grenade launcher emagged minesweeper loot with the rocket - launcher like it was originally supposed to be. - - imageadd: 'Tweaked the :b: emoji.' - - rscadd: Rubber Toolboxes. - - rscadd: 'Porting in two bar signs: Cyber Sylph''s and Meow Mix.' - - bugfix: Fixing stamina damage melee weaponry being unusable by pacifists, and - still damaging objects and triggering electrified grilles when thrown. - - refactor: refactored underwears to allow custom color preferences, instead of - manually colored sprites. - - rscdel: The aforementioned manually colored pieces. Some of your char preferences - may have been resetted as result. - - rscadd: 'More underwear choices, including: Bowling shirts, long johns, a tank - top, fishnets, more bee socks, bee t-shirt and bee boxers (original PR for the - latter three by nemvar from /tg/station).' - - tweak: random bodies will now have random underwear again. - - bugfix: Dressers will now properly change undergarment again. - - tweak: Toned down many species' female chest sprites to fit the smaller cups. - - bugfix: Fixed some body parts sprites inconsistencies, such as the W/E female - and male chest sprites being the same in some species, and jellypeople's legs - being one tile off on W/E - - bugfix: Fixing baklava pies a bit. - - tweak: Sweaters now cover groins too. - - balance: Improved the zelus flask to be more viable for bottle smashing than the - average barman's selection. - - code_imp: Very slight bottle smashing code clean up, stupid const vars. - - bugfix: Fixes krav maga gloves, wizard spells knockdowns. - - tweak: Added in an alert pop up to the cult convertees, on top of the older "click - here to become a blood cultist" chat message. - - tweak: The convertee's screen will now flash red to fit in the aforementioned - message's fluff. - - spellcheck: Made said message less verbose. - - rscadd: Towels. Crafted with 3 sheets of cloth, they can be worn on head, suit - and belt slots even without uniform, or laid flat on the floor. Sprites from - Baystation and Aurora Station. - - rscadd: You can combat mode right click people while wielding rags and towels - to pat out their flames (to no use for rags) or otherwise drying them out. - - balance: toned down the stamina costs of some of the bulkier weapons. - - code_imp: repathed hypereutactic blades to be a subtype of dual sabers. Way less - copypasta. - - bugfix: Fixing CX Shredder guns not accepting standard flechette mags. - - bugfix: Fixing missing magpistol magazines icon states. - - rscadd: sort of overhauled darkmode/lightmode to /vg/station's, also reincluding - the pre-existing black'n'white theme. - - bugfix: Fixed LOOC color, fixed .userlove and .love span classes being a bit too - blurry on dark mode. - - rscadd: The syndicate base's bathroom is now fitted with a shower, and a special - towel. - - bugfix: Fixed many issues with towels. - - tweak: The dry people off with rags/towels action can only be done if the object - is NOT moist with reagents now. Also cleans banana creaming. - - rscadd: Towels deal more damage while soaked with reagents. - - rscadd: You can now squeeze rags/towels with Alt-Click. - - rscdel: deleted an old and crappier towel sprite that got in the way. - - bugfix: Fixes Pubby's disposal conveyor belts and lack of a second lawyer spawner. - - code_imp: Cleaned up the absolute state of the arousal module. - - refactor: refactored exhibitionism into a quirk. - - tweak: arousal states won't persist after death. - - bugfix: Fixes testicles size adjective thing. - - bugfix: undergarments toggling now works instead of just making underwear disappear - and not come back. - - tweak: The "Always visible" genitals setting will now display them above clothes. - - bugfix: combat pushes will now properly stop targets from using firearms, and - will disarm the firearm if performed a second time, and also slow down people - by 15%, and won't push people on tables blocked by shutters or other dense object - anymore. - - bugfix: Fixes CHECK_BITFIELD macro. - - bugfix: Fixes hypovials being unable to transfer out liquids or be refilled by - large dispensers like water tanks. - - bugfix: Fixes chem-masters machineries not dispensing newly made pills inside - loaded in pill bottles. - - rscadd: Stunswords now fit in the captain's sabre sheat. - - rscadd: reworked ninja's stealth mode. Increased invisibility, but engaging in - combat, attacking or throwing things, bumping people will temporarily lower - it. - - rscadd: Ninja shoes are even stealthier. - - code_imp: cleaned up some 2014 tier processing code horror. - - tweak: the oxyloss fullscreen overlays now also take in consideration 1/5 of the - user stamina loss. - - rscadd: When you're jogging, you will only slip on water if you have more than - 20% staminaloss, for real this time. - - imageadd: Different cuffs now come with different worn overlays instead of a generic - one. - - bugfix: High luminosity eyes can now be properly deactivated and won't illuminate - your surroundings again until turned back on. - - bugfix: Fixes freshly cloned people starting with undershirts. Fixes random characters - possibly rolling with undergarments of the opposite gender (Doesn't affect preferences' - freedom of choice). - - balance: MRE menu 3 has cuban nachos instead of a chili now. - - bugfix: Removed the illustration overlay from MREs, looks pretty weird otherwise. - - rscadd: MRE menu 4, vegetarian. - - bugfix: fixes a few bad touchs on combat mode pushing. - - bugfix: Fixes clock cult Abscond scripture not dragging pulled mobs into Reebe. - Also fixes blood cult tele runes teleporting you from the source turf to the - source turf. - - bugfix: fixes clock cult mass recall. - - bugfix: Fixes underwear colors a bit. - - bugfix: Fixes Blood Cult conversion prompts - - rscdel: Removes an obnoxious temporary overlay var. - - bugfix: colorable socks can be colored again. - - bugfix: Fixed undergarments color preferences resetting each round. - - bugfix: Fixed a few dozen suits' body coverage inconsistencies. These changes - shouldn't affect armor and utility vests for most. - - bugfix: Fixed clown shoes and work boots. - - bugfix: Fixed some overlay bug that happens when legcuffed and then handcuffed. - - balance: Slowed down police baton and tele baton speed by 75%, should be still - be faster than the legacy speed (2 seconds) by 0.6 seconds. Telescopic batons' - stamina cost per swing is now on par with police batons, ergo more expensive. - - bugfix: Fixed undershirts n socks colors prefs. - - bugfix: You can now alt-click to rotate machinery such as the tachyon-droppler - array or emitters again. - - bugfix: Sofas can't be wielded and transformed back into plain chairs anymore. - - rscadd: Enables emojis for PDA messages. - - balance: Removes revenant blight's shabby toxin damage in favor of mood maluses, - and a dangerous necropolis curse if not cured in time. Remember - - tweak: Blood cult altar, forge and archives now use radial menus. - - bugfix: Fixed some machineries' UIs. - - tweak: blood and clock cultists messages from metabolizing - - bugfix: Fixed advanced medical scanners borg upgrades. - - bugfix: Fixes certain borg upgrades being unapplicable on dogborg counterparts - of the target cyborg type. - - bugfix: Fixed people being shovable hrough windows, windoors and the such. - - rscadd: You can now shove people into disposal bins. - - refactor: refactored altdisarm(), ergo the "shoving people around" proc. - - tweak: war ops is now lowpop friendly and doesn't require roughly 54 starting - players anymore. - - rscadd: Singularity beacons now also moderately increases the odds meteor waves, - while lowering their estimeed arrival countdown. - - bugfix: non-alphanumeric graffiti decals will no longer display as "letter". - - balance: Nerfs cyborg disabler and its internal power cell to hold 25 disabler - beam shots rather than 43/44, just like a normal disabler. - - bugfix: Adds some missing species_traits for cloth, clockwork and cult golems. - - rscadd: Added towel linen bins, found in dormitory restrooms. Also enhanced the - bedsheet bins found in some stations' dormitories - - imageadd: Resprited bedsheet bins in 3/4 perspective - - tweak: Made SDGF ghost poll message less verbose, made the experimental cloner's - complaint with the former, and added ghost poll ignore options for both. - - bugfix: fixing some related onmob sprites issues with the above accessory. - - bugfix: Teleprods work on non-carbons mobs now. - - bugfix: Fixed tracking implant teleport issues. - - balance: Increased stunbatons power cell depletion rate when left on by 50%. - - bugfix: Gorlex Marauders are pleased to announce non-slip grooves were given to - their .50 sniper rifles, and thus shouldn't accidentally flop on the floor like - pocket spaghettis whenever taken out of a bag anymore. - - bugfix: Silicons can now operate teleporter, medical and security records console - from a distance again. - - bugfix: Fixed custom say emotes conflict with drunk memes. - - bugfix: Fixes identity transfer (envy knife, changeling transformation, making - a vr avatar) not copying digitigrade legs. - - bugfix: Fixes temporary transformation sting triggering heart attacks on heartless - humans. - - bugfix: Fixed mobs folded inside bluespace bodybags getting their clothing and - items deleted when passing through a recycler. - - bugfix: The alien-bursting-from-your-thorax and the xeno "hud" embryo stage images - will now properly delete them once the embryo egg lifecycle is complete. - - bugfix: Fixed artificier lesser magic missile. - - bugfix: Phantom thief masks will now fancy your combat mode yet again. - - bugfix: Fixed gulag teleporter stripping the user of stuff it really shouldn't - (like storage implant bags). - - bugfix: fixing cydonian armor a bit. - - imageadd: Resprited wooden and critter crates. - - imageadd: Improved the Cyber Sylph' good yet cumbersome bar sign a little. - - bugfix: Cyborgs can now use camera consoles on the edge of their widescreen. These - consoles are also TK friendly now. - - imageadd: Updated gang dominator sprites. - - bugfix: Miner borgs can again have installed PKA mods. - - bugfix: Fixed invisible blackberry n strawberry chocolate cake slices. - - bugfix: Nuke ops / adminbus combat mechs will no longer spawn with tracking beacons. - - imageadd: Arcade machine directional sprites. - - tweak: 'lowered the arcade''s random plush / other prizes ratio from 1 : 2.5 circa - to 1 : 5. Dehydratated carps and the awakened plush can not be achieved this - way anymore.' - - imageadd: Added armrests overlays to sofas and tweaked their sprites a little. - - bugfix: Fixed dogborg sleepers. Just don't tell me what is exactly fixed, cause - I don't want to find out. - - bugfix: Buffed the deep space familiar gorilla against runtimes. - - imageadd: Updated ratvarian computer sprites. - - bugfix: Fixed storage implant transplant. - - bugfix: Refactored how Jacqueen teleportation destination is selected, preventing - them from teleporting on off-station holopads. - Ghommie && Kevinz000: - - balance: Lichdom and necromantic stone skeletons are now of the spaceproof kind - too. - - tweak: skeletons now also like dairy products. - - rscdel: Halloween roundstart skeletons and zombies are no more spaceproof. - - rscadd: You can choose to set your species to zombie or skeleton through the pride - mirror yet again, Alas they are not of the spaceproof kind either. - Ghommie (Credits to Kmc2000 for the original PR): - - rscadd: Porting in MRE boxes from Yogstation. But be careful, eating possibly - expired MREs found in maintenance comes with an unrealistically large (actually - small) chance of food poisoning. Otherwise just bail out and order actually - safe-to-eat MREs from cargo for 2000 credits. - Ghommie (Original PR by Dennok): - - bugfix: Now areas_in_z get areas spawned by templates and blueprints. - Ghommie (Original PR by Dreamweaver): - - rscadd: Nanotrasen has received word of a high-tech research facility that may - contain advancements in bluespace-based research. Any crew members who become - aware of its whereabouts are to report it to CentCom immediately and are restricted - from sharing said info. - - refactor: The turf reservation system now dynamically creates new z levels if - the current reserved levels are full. - Ghommie (Original PR by JJRcop): - - rscadd: 'Ports in more emojis, including : flushed :' - Ghommie (Original PR by LaKiller8): - - bugfix: Goonchat options should now save properly. - Ghommie (Original PR by Vile Beggar): - - rscadd: Warden now has an added drill hat in his locker. You can change the loudness - setting of it by using a screwdriver on it. Use wirecutters on it for a surprise. - Ghommie (Original PR by coiax): - - refactor: atom/var/container_type has been moved into datum/reagents/var/reagents_holder_flags. - There should be no visible changes to effects. - Ghommie (Original PR by nemvar): - - rscadd: Botanists can now get beeplushies (or cultivator and bucket) as an heirloom. - - bugfix: Clowns and mimes will now properly pick either a can of paint or their - brand as heirloom now. - Ghommie (Original PR by tralezab): - - bugfix: Fixes an issue with spontaneous appendicitis picking incompatible mob - biotypes. - Ghommie (Original PRs by Tortellini Tony and BuffEngineering): - - bugfix: E-cigs will continue to display their setting after being emagged. - - bugfix: Vapes now come out of the mouth. fix Fixes an E-cig initialize() runtime. - Ghommie (Original PRs by nemvar and Rowell): - - rscadd: Added beekini bras and panties, thigh-high and knee-high bee socks. - Ghommie (by Arkatos): - - bugfix: Fixed an issue with a Lizardwine drink crafting, where a final product - would contain unwated 100u of Ethanol. - Ghommie (by Floyd / Qustinnus, Arathian): - - rscadd: The robotocist now has robe to show his love for toasters - Ghommie (by nemvar): - - tweak: Dwarfs are now more robust. - Ghommie (original PR by 4dplanner): - - bugfix: thrown objects (but not mobs) no longer hit the thrower - - bugfix: mirror shield rebound no longer depends on the original thrower's momentum - Ghommie (original PR by 81Denton, kriskog and nemvar): - - spellcheck: Sleepers now show a message if players try to unscrew the maintenance - hatch while they're occupied or open. Fixed typos in sleeper/organ harvester - messages. - - tweak: Sleepers and dna scanners can now be pried open with crowbars. - - tweak: You can open and close sleepers and dna scanners by alt-clicking them. - - bugfix: The scanner's hatch now must be closed (on top of being unoccupied), just - like sleepers, before being screwdriverable. This fixes a tricky door stuck - issue with the machine. - Ghommie (original PR by AffectedArc07 and Shazbot): - - imageadd: Added 8 new sock styles - Ghommie (original PR by AffectedArc07): - - tweak: Religion is now a globalvar instead of being a subsystem for some reason - Ghommie (original PR by AnturK): - - bugfix: Supermatter now melt walls if it finds itself in one. - Ghommie (original PR by Anturk): - - rscadd: Recipe for fabled secret sauce can now be found in the deepest reaches - of space. - Ghommie (original PR by Barhandar: - - bugfix: Pumpkin meteors on Halloween now replace catastrophic meteor waves, instead - of ALL OF THEM. - Ghommie (original PR by CrazyClown12): - - tweak: The chloral hydrate inside of the sleepy pen is no longer slower acting - than chloral hydrate made in chemistry. - - tweak: The chloral hydrate inside of cookies synthesised by emagged borgs is no - longer slower acting than chloral hydrate made in chemistry. - - balance: Slight tirizene buff. - - rscdel: Delayed chloral hydrate - Ghommie (original PR by Denton): - - tweak: Nanotrasen has started shipping more types of bedsheets to its stations. - - rscadd: Added in Runtime, Pirate and Gondola bedsheets. The second one can also - be found in some pirate ships, while the last can be crafted from gondola hides. - - balance: You can no longer reveal the 'illegal tech' research node by deconstructing - .357 speedloaders, riot dart boxes, syndicate cigarettes, syndicate playing - cards or syndicate balloons. - Ghommie (original PR by Mickyan): - - bugfix: Fixed being unable to smother people using the damp rag - Ghommie (original PR by MrDoomBringer): - - bugfix: morgues have had their proton packs removed and as such no longer suck - in ghosts on closing. - Ghommie (original PR by MrDoomBringer, AnturK and YPOQ): - - bugfix: Explosions will no longer damage wizards in rod form, the supermatter - monitoring radio and megafauna GPS. - - bugfix: Supplypods no longer detonate their contents. - - bugfix: Fixed silicon items (e.g. cyborg modules) being destroyed by explosion - epicenters. - Ghommie (original PR by Naksu): - - code_imp: get_area() is now a define rather than a proc. - Ghommie (original PR by Nicjh): - - rscadd: Abductor console's select disguise option now uses a radial - Ghommie (original PR by ShizCalev): - - bugfix: Pineapple haters/lovers will get/no longer get pineapple pizzas respectively - from infinite pizza boxes. - - bugfix: As a non-human mob, hovering your cursor over an inventory slot while - holding an object in your active hand shouldn't runtime now. - Ghommie (original PR by Skoglol): - - code_imp: New helper proc for alt-click turf listing, bypasses any interaction - overrides. - - code_imp: Ghosts and revenants now use the new proc. - - bugfix: Ghosts can no longer toggleopen sleepers, adjust skateboard speed or close - laptops - - bugfix: Revenant can now alt-click turf to list contents. - - tweak: Revenant now slightly less nosy, use shift click to examine. - - tweak: Alt-clicking the same turf again no longer closes the turf listing tab. - - bugfix: Reduced ventcrawl lag greatly. - - bugfix: Mining bags will no longer drop ore into backpack. - - bugfix: Mining bags in backpack no longer interferes with other mining bags. - - bugfix: Fixes some storage size circumventions. - - tweak: Moved machine and computer frames below objects, parts are now always on - top. - - tweak: Moved structures (chairs, closets, windows, cult altars etc etc) below - objects. - - tweak: Moves mineral doors to airlock layers - - tweak: morgue/crematorium trays' layers shouldn't overlap bodybags' anymore. - Ghommie (original PR by SpaceManiac): - - bugfix: Disassembling a chem dispenser for the first time will no longer always - yield a fully-charged cell. - Ghommie (original PR by Swindly): - - rscadd: Arm-mounted implants that contain more than one item use a radial menu - instead of a list menu. - Ghommie (original PR by Tlaltecuhtli): - - bugfix: Other people's clothes burning no longer spam you - Ghommie (original PR by XDTM): - - bugfix: Reagents now stop their passive effects (for example, stun immunity) if - the liver stops working while they're active. - Ghommie (original PR by YPOQ): - - bugfix: Fixing roffle waffle, mushroom halluginogen and some invalid reagents. - - bugfix: Fixes clockwork armor not actually having armor. - Ghommie (original PR by cacogen): - - rscadd: The font size of all text in the chat window now scales - - tweak: High volume (megaphone/head of staff headset) is a slightly smaller - - tweak: Admins have slightly larger OOC text - Ghommie (original PR by coiax): - - code_imp: Randomly coloured gloves and randomly coloured glowsticks now have slightly - different typepaths, but otherwise function the same. - - code_imp: The Squeak subsystem has been renamed to Minor Mapping. - Ghommie (original PR by duckay): - - rscadd: Added better names and descriptions for blueshirt officer gear. - - rscadd: Added the above gear to the premium selection of the sectech - Ghommie (original PR by harmonyn): - - balance: Resisting out of bucklecuffs takes more/less time depending on the handcuffs - you used, i.e., fake handcuffs will not bucklecuff someone for ages. - - tweak: fake handcuffs shouldn't no longer demoralize restrained criminals scums. - Ghommie (original PR by monster860): - - bugfix: fixes advanced proccall - Ghommie (original PR by mrhugo13 on tgstation13): - - rscadd: The Syndicate has decided to equip their Syndicate leaders operative (Aswell - as their clown counterparts) with the new Combat Glove Plus! The new Combat - Glove Plus does everything the old boring Combat Gloves does but with the added - extra of learning Krav Maga upon wearing them, any other Syndicate operative - who wants to get in on the action will have to pay 5tc. - Ghommie (original PR by nemvar): - - imageadd: Some drinks have new icons or slightly altered icons. In particular - Wizz Fizz, Bug Spray, Jack Rose, Champagne and Applejack. - Ghommie (original PR by ninjanomnom): - - bugfix: Orbiting is a little more aggressive about staying in orbit. The wisp - as a result now correctly follows you over shuttle moves. - - bugfix: Gaps between sounds in some looping sound effects should no longer happen - as much under heavy server lag. - Ghommie (original PR by variableundefined): - - bugfix: Cancel button to assault pod destination selector. - Ghommie (original PR by wesoda25): - - balance: disembowelment no longer works on mobs that aren't dead or in critical - condition - Ghommie (original PRs by Akrilla, Arkatos and Denton): - - tweak: Sprays cans have a cap on how dark you can make objects. Art is uneffected. - - bugfix: Fixed a bug where you could get cyborg spraycans via pyrite extracts. - - rscadd: Added an infinite spraycan for admins to spawn. - Ghommie (original PRs by Denton and Skoglol): - - tweak: Reorganized the syndicate uplinks. Items are now mostly alphabetical, some - misplaced items moved to more fitting categories. Bundles, random item and TC - have been moved into a new category called "Bundles and Telecrystals". Gloves - of the North Star and Box of Throwing Weapons have been moved to Conspicuous - and Dangerous Weapons. Combat Gloves Plus have been moved to Stealthy and Inconspicuous - Weapons. Moved all implants into the Implants category. - - tweak: 'Added a new category to the uplink: Grenades and Explosives.' - Ghommie (original PRs by Floyd/Qustinnus, optimumtact, Denton and coiax): - - rscadd: You can now select what your pills will look like when making pills from - the Chem Master - - rscadd: Red pills can make you think. - Ghommie (original PRs by Jujumatic and PKPenguin321, respectively): - - rscadd: Minesweeper Arcade machines. The higher the difficulty setting, the better - the prizes will be. - - rscadd: Also keep your eye out for another new (and rare) arcade game! - Ghommie (original PRs by Kmc2000 and actioninja): - - rscadd: Added darkmode! You can opt-in to this by clicking the new toggle darkmode - button just beside the settings one. - - rscadd: Byond members will now have a new setting for their Antag OOC color, instead - of using their OOC one. (Antag OOC still locked under admin discretion though) - - rscdel: Default black'n'white windows style. - Ghommie (original PRs by Mickyan, Anturk, ShizCalev, nemvar and Naksu): - - rscadd: After rigorous mandatory art training for the crew, many new graffiti - styles are now available - - bugfix: Cleaned up some crayon and spraycan code for futureproofing. - - bugfix: Spraypainting blast doors no longer makes them see-through. - - balance: Paint remover now works on blast doors and the like. - - rscadd: Most objects can now be colored using a spray can. - - spellcheck: Added visible message to spraying objects and windows. - - rscadd: Colored lights now shine in different colours. - - rscdel: Removed individual buttons text in crayon/spraycan UI, speeding it up. - - bugfix: Text mode buffer is actually visible in the UI. - - tweak: Last letter of a text mode buffer no longer rotates out to be replaced - with "a", allowing the text mode to be used for individual symbols. - Ghommie (original PRs by Naksu and XDTM): - - bugfix: Transferring quirks now properly removes the roundstart trait from the - person losing the quirk. - - bugfix: Roundstart traits no longer block the removal of other sources of that - trait. - - code_imp: status traits are now a datum var, the accessors are now defines rather - than functions. - Ghommie (original PRs by Naksu and coiax, loser): - - code_imp: Cleaned up saycode - - bugfix: Taking mutadone while having the communication disorder brain trauma will - no longer spam your chat with messages. - - rscadd: IPCs now come with a subtype of robotic tongue without the omnilingual - ability, instead of innately having robotic voice spans. - Ghommie (original PRs by Nichlas0010 and ShizCalev): - - tweak: AI core display screen can now be set in character preferences. - - bugfix: AI core display screen will now be restore when revived. - - spellcheck: Corrected some inconsistent capitalization in the player preferences - screen. - - imageadd: Readded some forgotten AI sprites. - - bugfix: Fixed Hades AI death animation not playing. - - tweak: the AI icon-selection menu now uses a radial. - - imageadd: Added in the death icon_states for the "TechDemon" AI screen. - Ghommie (original PRs by ShizCalev and bobbahbrown): - - rscadd: Headsets now dynamically show in their description how to speak on any - channels they can use when held or worn. - - code_imp: Radio channels names and keys now use defines. - - tweak: The head arrival announcement will now be broadcast to the supply for the - quartermaster. - Ghommie (original PRs by ShizCalev): - - bugfix: Fixed a bug that allowed you to teleport an ID in your possession to a - PDA anywhere ingame. - - bugfix: Fixed an exploit allowing you to steal ID's/pens from PDA's not in your - possession. - - bugfix: Fixed an exploit allowing you unlimited control of a PDA's interface even - if it wasn't near you/in your possession. - - bugfix: Fixed Pride Mirror exploits. - - tweak: Corgi collars can now be removed! - - tweak: Updated the corgi & parrot inventory panels to use the same formatting - as other mobs - - bugfix: Fixed corgi inventory panels not closing properly. - - bugfix: Fixed the parrot inventory panel not closing properly if you're not able - to interact with it. - Ghommie (original PRs by ShizCalev, MrDoombringer, AnturK, bgobandit, 81Denton and actioninja): - - rscadd: Failsafe codes for uplinks are now available for purchase. - - rscadd: Nuke Ops now have the ability to purchase a usable RPG, the PML-9, as - well as a couple different types of rockets for it. you can also suicide rocket - jump with them! - - spellcheck: Improved Uplink item descriptions and formatting. - Ghommie (original PRs by ShizCalev, coiax and Tlaltecuhtli): - - bugfix: Caks will no longer override the bonus reagents provided in a donut when - frosting them. - - bugfix: Caks can no longer create frosted frosted jelly donuts. - - bugfix: Jelly donuts will no longer lose their vitamins when they're frosted. - - bugfix: Fixed chaos donuts potentially doubling the amount of reagents added when - microwaved with something else. - - bugfix: Donuts now always contain 1 sprinkles as was stated on the wiki. Frosted - donuts have a chance at adding an extra sprinkle. - - code_imp: Improved the code for ensuring that security members enjoy donuts and - security-themed alcoholic drinks. - - balance: neurotoxin doesnt insta stun but gives you limb paralysis overtime and - heart attacks if it stays in for too long and it is also alcholic - - balance: beepsky smash now summons imaginary beepskys that deal stamina damage - instead of outright stunning - Ghommie (original PRs by Time-Green and Qustinnus): - - tweak: loot crates can't explode after unlocking anymore - - bugfix: jumping into loot crates no longers causes them to go boom - - bugfix: You can now deconstruct abandoned crates with a welder without making - them go boom. After unlocking them, of course. - Ghommie (original PRs by Tlaltecuhtli and nicbn): - - rscadd: alt click to eject beakers from chem masters + chem dispensers + grinders - + chem heaters - - rscadd: hit chem master + chem dispenser + chem heaters with a beaker and if its - loaded with another it swaps em - - rscadd: All-In-One Blender UI uses a radial menu now. You can see the contents - and reagents by examining. - Ghommie (original PRs by XDTM, 4dplanner, nemvar and, yes, myself): - - code_imp: Merged tinfoil hat kind of protection into the anti_magic component. - - rscadd: Tinfoil hats can also be warped up from excessive dampening of mindray/though - control/psicotronic anomalies, or by simply being microwaved in an oven, and - become useless. - - rscadd: Immortality Talisman and Paranormal Hardsuit helmets now come with tinfoil - protection too (minus the paranoia and limited charges). - - balance: Genetics/Slime/Alien Telepathy and Slime Link are now stopped by tinfoil - protection. - Ghommie (original PRs by XDTM, optimumtact, Nichlas0010 and monster860): - - rscadd: 'Added Quantum Keycards, devices that can link to a quantum pad, and can - be used on any other quantum pad to teleport to its linked pad. spellchecking: - Renamed "Bluespace Teleportation Tech" tech node to "Bluespace Travel".' - - tweak: Moved roasting sticks from the "Bluespace Travel" to "Practical Bluespace". - - rscadd: Spraying holy water on tiles will now prevent cult-based teleportation - from using them as a destination point. - - tweak: Quantum, wormhole and magic teleportation is no longer disrupted by bags - of holding. - - bugfix: You are now also blocked from teleporting IN to no-teleport areas, not - just out of them. - - tweak: Quantum teleportation now makes pretty rainbow sparks instead of the normal - ones. - - bugfix: Non-bluespace teleportation (spells etc.) no longer makes sparks. - - bugfix: Fixed teleportation deleting mob spawners like golem shells and ashwalker - eggs. - ? Ghommie (original PRs by carshalash, GranpaWalton, BebeYoshi & Hexmaniacosanna, - Fire Chance, Ordonis, Krysonism and OnlineGirlfriend) - : - tweak: Reduced booze power of Mead, Red Mead, and Irish Cream. - - tweak: Increased booze power of Grappa. - - rscadd: Added a new premium drink to the soda machine called "Grey Bull" which - gives temporary shock resistance - - rscadd: A new drink called Blank Paper was added to the bar menu, it was made - by a mime and it represents a new start. - - rscadd: 'Adds a variety of fine alcoholic beverages for discerning patrons of - the bar: Wizz Fizz, Bug Spray, Champagne, Applejack, Jack Rose, Turbo, Old - Timer, Rubberneck, Duplex, Trappist Beer, Blazaam and Planet Cracker!' - - rscadd: 'Also more nonalcoholic drinks: Cream Soda, Lemonade and Red Queen.' - - rscadd: Packs of a novel artificial sweetener have been added to the kitchen - vendor. - - rscadd: Bottles of trappist beer and champagne are now available in the premium - seection of the booze-o-mat. - - rscadd: Juicing parsnips now yields parsnip juice. - - rscadd: Maintenance peaches. - - bugfix: Grape soda now cools you down like other sodas. - - tweak: tweaked the Arnold Palmer recipe, it now uses lemonade. - - imageadd: Added new drink, bottle, vomit and peach can sprites. - Ghommie (original PRs by grandpawalton and Mickyan): - - tweak: the contents on the smartfridge icon now change depending on how many items - it contains - - bugfix: opening the maintenance panel of smartfridges now correctly updates the - icon - - bugfix: Screwing a disk compartmentalizer no longer makes it look like a smartfridge. - Ghommie (original PRs by nicbn and coiax): - - rscadd: Microwave UI uses a radial menu now. You can see the contents by examining. - - rscadd: Microwaves have a single wire accessible when open, the activation wire. - When cut, the microwave will no longer function, when pulsed, the microwave - will turn on. - - rscadd: Stabilized dark purple extracts now cook items in your hands, rather than - dropping the cooked item on the floor. - Ghommie (original PRs by ninjanomnom and nemvar): - - bugfix: Trays now scatter their contents when used for attacks, like they are - supposed to. - Ghommie (original PRs by ninjanomnom, coiax, yoyobatty): - - bugfix: Fixed slaughter demons not getting a speed boost when exiting a pool of - blood. Fixed slaughter demon giblets not being visible. - Ghommie (original PRs by subject217, AarontheIdiot, pireamaineach, Gousaid67 and SouDescolado): - - balance: Removed plasmamen species speedmod in favor of a slowdown for envirosuits. - - rscadd: Nanotrasen has began deploying departementalized enviro plasmasuits to - the station! plasmamens can now benefit from some of the bonuses aswell as the - color pattern of their job, while allowing others to easily determine their - profession! - - bugfix: Benevolent Nanotrasen makes gulag available for everyone! (Plasmamen retain - their equipment and don't die.) - - rscdel: Removes code that theoretically limits plasmamen from being clowns and - mimes, but actually doesn't. - Ghommie (original PRs by zeroisthebiggay, AnturK, MrDoomBringer, Cobby, ATHATH, optimumtact, GranpaWalton, Skoglol): - - bugfix: Blob overminds, sentient diseases, etc. can no longer dump out boxes. - Sorry gamers. - - rscadd: Sentient Disease now has almost all symptoms at its disposal. - - code_imp: Adding single-symptom disease abilities is super easy now. - - bugfix: Sentient Disease can now hear (not sure if this was a bug or intentional). - - rscadd: Sentient Disease is a linguist and knows all languages. Still cannot speak. - - tweak: Gives Sentient Diseases a medical hud to observe their victims further - with. - - bugfix: Fixes and moves around some on_stage_change() and Start()-related things - for virus symptoms and (sentient) diseases. - - bugfix: The inorganic biology symptom should work properly now when bought by - a sentient disease. - - bugfix: Oxyloss icon no-longer shows up when someone has the self respiration - symptom - - tweak: The self respiration now makes you not contract diseases through the air - and not breathe in smoke - - bugfix: Sentient diseases can no longer pick two cures that react and disappear - when eaten. - - balance: Sentient disease cures are now consistently harder, will only pick cures - from tier 6 and up. - - bugfix: Disease cures should now stay the same for all infected mobs. - - rscadd: The regenerative coma symptom has a new resistance 4 threshold effect! - Said threshold effect will give hosts of the symptom's virus the TRAIT_STABLECRIT - trait if its threshold is met. - - bugfix: An obscure, probably never reported before bug that may or may not exist - involving sentient diseases and the self-respiration symptom should be fixed - now (if it even existed in the first place). - - balance: The cooldown time between each removal or addition of a symptom for sentient - diseases has been brought down from an agonizingly long 2 minutes to a more - reasonable 1 minute. - Ghommie (original pr by Dennok on tgstation): - - bugfix: Now you don't lose your pulled thing on the z level edge. - GrayRachnid: - - rscadd: Added windoors to all the flaps on delta. - - balance: rebalanced k9dogborgs - Hatterhat: - - rscadd: Magnetic pistols now fit in boot pockets - jackboots, workboots, etc. - - tweak: literally every pistol subtype fits in shoes now. go wild. - Hippie Circuit Port: - - rscadd: Added all Atmospheric Circuits - - rscadd: Added the ability to color data disks - - rscadd: Added Selection and Storage Examiner Circuits - - rscadd: Added Smoke, Extinguisher, and Beaker Connector Circuits - - rscadd: Added Inserter, Renamer, Redescriber, and Repaint Circuits - - rscadd: Added MMI Tank and pAI Connector Circuits (The possibilities are endless!) - Improving and Balancing Cyborgs: - - rscadd: Added Crew Pinpointer to Security Borg - - rscadd: Added Crew Monitor to Medical Borg - - rscadd: Added Crew Pinpointer to MediHound Borg - - tweak: Made the Disabler_Cooler compatible with both Security Borg and K9 Borg - - tweak: Changed the Warning Text upon selecting Security or K9 module - ItzGabby: - - rscadd: Bat Species parts for more leeway for character customization. - - code_imp: Alphabetized decor wing selection window in character creator for simplicity. - JTGSZ: - - tweak: Added one more gang boss slot bringing total to 4 from 3 - - bugfix: Fixed Gang Boss being able to be deconverted - - tweak: Gave Qualifies_for_Rank Check back its checks in job controller. - - rscadd: Optional species based clothing restrictions - - tweak: Gang Dominator excessive wall check tweaked to 25 open turfs - - bugfix: Gang Dominator no longer functions off-station. - - rscadd: Adds more control over species based offsets. - - bugfix: qualifies_for_rank now checks latejoin menu - - rscadd: Added Halloween Dwarves, for Halloween... Yep. - - bugfix: Can flip pipes once more. - - bugfix: barricade girder walls use PlaceOnTop instead of new - Linzolle: - - rscadd: ability to quickly max sensors - - bugfix: atmos helmet visual bug - - bugfix: supply display are now properly on the wall - - tweak: consistency in hop and cap berets - - tweak: slime people now enjoy eating toxic food and it will not disgust them - - bugfix: hos trenchcloak now properly has a sprite on digi characters - - rscdel: duplicate definition of hos and sec skirts - - bugfix: Krav Maga leg sweep now works properly. - - rscadd: shoes can have a different icon used for their item and mob icons - - bugfix: combat gloves plus having no mob icon - - rscadd: inhands sprite for rainbow knife - - tweak: colour of highlight on the regular knife when held in the right hand - - rscadd: mining shuttle console can now be printed after computer consoles have - been researched - - rscadd: can now carry people on your back by aggressive grabbing them while they - are laying down and then dragging their sprite onto yours. - - tweak: dragging people who are prone is now much slower, and carrying them will - allow you to move faster at the cost of taking 5 seconds to lift them up onto - your back. - - tweak: pacifists can now aggressive grab (cannot table slam people though) - - bugfix: blood on your body floating a bit to your right if you're a taur - - bugfix: some suits having no icon on tauric characters - - tweak: front facing CMO hardsuit icon for naga taurs - - tweak: colour of medical cross on CMO hardsuit for taurs - - bugfix: taur body and jumpsuit showing through mining suits - - tweak: all chaplain suits can hold the same items in suit storage - - code_imp: improvement to organisation for chaplain suits - - bugfix: blood halberd not going back to 17 force after unwielding - - spellcheck: unnecessary 's at the end of blood rites healing - - rscadd: QoL to blood rites, examine the ritual aura to view how many blood charges - are left - - code_imp: surgery cleanup - - tweak: dissection available round-start - - rscadd: better dissection surgeries from RnD, gives more points - - rscadd: abductors can now see what glands do - - code_imp: antagonist abductors now have a surgeon trait that teaches them every - surgery rather than having it just check if they're an abductor - - rscadd: muscled veins surgery - - bugfix: having one of your hands used up if you fireman carry but the person being - carried dismounts any way other than you dropping them - - rscadd: Four colour variants of ankle coverings. Select them on the loadout screen. - - imageadd: ankle coverings - - tweak: allows for shoes that don't cover your feet to be taken into account for - footstep sound effects and glass shards - - rscadd: Tend Wounds surgery. Heal in the field, with better healing the more damage - the patient has. - - rscdel: Reconstruction replaced by Tend Wounds - - balance: made Revival more accessible, more viable alternative to cloning. - - bugfix: advanced surgery tools can't perform lobectomy or coronary bypass - - rscadd: Decorative and insect wings can now be coloured individually, similar - to horns. - - bugfix: people getting assigned wings if their savefile is old. - - rscdel: wings that take the hair colour. Unnecessary if you can just set the colour. - - tweak: Cannot make horns pure black. Trying to do so will set it to a default - value. - - bugfix: decorative angel wings being invisible - - bugfix: abductors now actually work - - tweak: abductor scientist has their own greet message now - - bugfix: unable to read paper on airlocks - - tweak: ai can see paper (still just shows stars) - - rscadd: Target head and throw a hat at someone to toss it onto their head, knocking - whatever they're wearing off if they are wearing a hat. Some headgear can't - be knocked off this way. - MediHound: - - rscadd: Made Cyborgs be affected by Ion Storm Law Changes like AIs - MrJWhit: - - balance: rebalance melee stamloss - Multicam Config: - - config: removed whether or not the stuff for multicam was checking the useless - var and instead now checks the CONFIG_GET flag. - - admin: Admins now have a verb in the Server tab to turn AI multicam on and off. - Naksu: - - code_imp: default radiation insulation is now handled by atom vars rather than - a component, components can still be used. - - code_imp: squeezed a little bit more perf out of atmos - Nero1024: - - soundadd: Bare feet will now make the correct footstep sounds. - - soundadd: Other mobs will make the correct footstep sounds. - - soundadd: Crawling/dragging sounds for downed/incapacitated mobs - Onule & Nemvar (ported by Ghommie): - - imageadd: New Revenant icons - Original by Citinited, port by Sishen1542: - - rscadd: You can now use an airlock electronics on a locker to add a lock, and - can screwdriver an unlocked locker to remove its lock. - - rscadd: You can now remove the locks on broken or emagged lockers. - - tweak: Removing the lock from a personal locker now wipes that locker's ID details. - - tweak: Broken lockers have had their appearance changed. - Owai-Seek: - - rscadd: custodial cruiser cargo crate - - tweak: removed light replacer from power designs and moved to misc designs - - tweak: added pimpin ride to custodial locator - - tweak: added additional items to janibelt whitelist - - tweak: made plant DNA manipulator unwrenchable - - balance: reduced janitor premium supply costs - - bugfix: fixed them strawberries - - rscadd: false codpiece - - rscadd: crocin/camphor bottles - - tweak: updated kinkmate item list - PersianXerxes: - - code_imp: Adds the clockwork_warp_allowed flag to the Captain's Office area, set - to FALSE the same way it is for the chapel and armory. - - tweak: Relocates cult catwalks outside the Reebe dressing room. - Poojawa: - - rscadd: Digitigrade legs are now able to wear shoes and look fancy, Uniforms to - come. - - tweak: Xenos are only digitigrade now, mammals and aquatics have the option. - - rscadd: Fire Alarms are visible in low light situations - - bugfix: fixed vore prefs saving inconsistently, new characters might have a previous - slot's prefs tacked on. - - bugfix: fixed mammals not having the option for digilegs. Sprites are fucky until - body-part related sprites are done. - - refactor: improved vore sound responsiveness to preference choices. - - balance: removed morphine from Medihound sleeper chemical list - - bugfix: fixed preference setting being broken - - refactor: Medihound sleepers are Initialized properly, and icons update correctly - now on eject - - tweak: Air alarm All clear color changed from green to blue - - balance: APCs are harder to destroy. - - rscadd: Added Digitigrade versions of everything appliciable in suit.dmi - - imageadd: Snowflake Icons weren't modified, and were given NO_MUTANTRACE_VARIATION - - imageadd: naga and quad Taurs literally don't freeze their ass off in space anymore. - - bugfix: Digitigrade legs will toggle on/off properly on character menue - - bugfix: The misleading "normal" has been removed from species options - - balance: Added sanity checks to emag usage - - bugfix: fixed vtech, but it still doesn't work because of overriding jog/sprint - mechanics from combat reworks. - - bugfix: Puppy jaws properly store if you're emagged, they are also toggle-able - for stealth like the tongue. - - bugfix: 'Digitigrade legs should properly fucking update for the last fucking - time. Fucking snowflake code. refractor: Got rid of snowflake sechound cuffs, - gave them normal zipties like regular secborgs.' - - bugfix: dogborg sleepers actually extinguish people who are on fire, in case you - don't have time to lick them out. - - bugfix: Taur suits should fix themselves properly when worn by other people. - - rscadd: Added the Yogs/Oracle ported latejoin menu - - rscadd: All markings, tails, ears, and snouts for Citadel races are color matrixed! - - imageadd: all markings are on a per-limb basis, including Digitigrade legs! - - imageadd: a bunch of tails were blessed with tail wagging sprites, Fish, Sharks, - Fennecs, Wahs, raccoons, and others. - - imageadd: Tiger markings + tail added, skunk tails improved via sprites from Virgo - - tweak: tweaked some sprites to look better, but they absolutely could use a few - extra passes for quality - - rscadd: HumanScissors in the Tools folder will permit anyone to contribute matrix'd - markings to the sprite sheet, however Mam_markings is very, very full. Be careful. - - tweak: Character preview was both optimized for taurs and bad-touched for better - updating. I don't know if it'll be bad, but hey its better. - - rscadd: Added Dark Medihound and Pup Dozer from Virgo - - tweak: Clone pods no longer announce the name of the clone - - bugfix: fixed flavor text appearing when your face is hidden but you're not an - Unknown - - bugfix: Tauric suits now apply an (placeholder) blood overlay, as well as their - shield overlay. - - balance: Ashwalkers now have lungs. They cannot breath station air without suffocation - effects, but are completely fine on their homeworld. - - balance: Carbon mobs now have a maximum tolerance to oxygen of 50kPa. - - balance: Deluxe synthetic lungs have a very high bonus to O2 tolerance. - - bugfix: Digitigrade legs returned to normal, since digi leg markings overlay them - anyway. - - bugfix: commented out lizard mam_snout entries, because too many abominations - - bugfix: Vore Panel restored to have various interactions available again. Semi-untested - but should work as advertised. - - tweak: Vore Panel has more feedback. - - rscadd: is_wet var to bellies, toggled in the panel, will remove flesh sounding - struggles and the internal loop. JSON version updated. - - rscadd: Feeding var. You will need to enable feeding to recieve any feed vore - actions, but you can now feed yourself to mobs that have this set. TODO, Dogborg - sleeper feeding. - - rscadd: vore mode button now required to be enabled to perform vore actions. It's - the mouth icon! - - bugfix: Ash Drake vore fixed for actual reals this time - - bugfix: Mobs shouldn't spam the released contents announcement anymore on qdel - or death. Only if triggered - - tweak: Hostile mob code now properly ignores targets in bellies - - rscadd: Your belly can quietly growl if you're starving now. - - bugfix: Normal blood splattering isn't offset due to tauric mode - - rscadd: Added plasma man suit icons for taurs - - rscadd: Added bee butt for insects to have stripes - - tweak: adjusted random spawn sprite accessories, humans won't be demi by default - and lizard/mammal spawns will randomly get digitigrade legs - - bugfix: sprite adjustments for tentacles, as well as a misspelling. - - bugfix: Humans once again use ears and tail_human, as intended. This is to prevent - garish randomness - - bugfix: istype for species is actually correct and usable now, it'll be a factor - for monkey form expansions. - - bugfix: Hair functions are de-gendered and more easily selectable now. - - bugfix: Slimes can *wag, select markings and snouts, and yes it works. - - bugfix: Slimepeople extra parts now respect their hair_alpha in terms of being - somewhat see-through. it shouldn't stand out as badly now! - - bugfix: Hunger noises are now toggled per character - - bugfix: Ashwalker den is habitable by ashwalkers again - - rscadd: Medical belts now have overlays! Now you can see if a belt is useful or - just flatout empty. - - bugfix: fixed hypo MK IIs not being able to be put on medical belts - - bugfix: fixed Navy officer uniforms that failed to spawn - - code_imp: Loadout items will be forcefully added to backpacks or at your feet - instead of left behind at title screen - - tweak: hypospray kits hold 12 now, but only vials and sprays themselves - - bugfix: labcoats can carry MK II hyposprays on them now. - - rscadd: Vore Mobs are a thing now, not just ash drakes - - rscdel: 'Removed hunger sound stuff. never taking requests from Coolgat3 ever - again. refractor: Simple Mobs use the same system regular human mobs do, itjustworks.png' - - tweak: Character Window settings unsnowflaked and normalized. I have no fucking - clue how to make them work with taurs still tho, sorry. - - imageadd: added rotating background images for better clarity and contrast than - just SOLID FUCKING BLACK. Images from Virgo/Polaris/Eris - - balance: Defib users automatically stop pulling when they attempt to perform a - defib shock - - imageadd: added muzzled varients of space helmets and full masks - - imageadd: added knight_grey to taur suits, all paranormal ERT now have tauric - versions enabled - - bugfix: Lava knights have digitigrade and tauric versions now - - rscadd: Added a glass version of the gas mask, because it was in the files and - looked nice. does everything regular ones do except make you an unknown - - rscadd: Added custom species names! Examining people will now display their species - name unless they're an Unknown or have their face hidden. like flavor text. - Set it in your character window! - - code_imp: changed how health scanners print messages, wrapping it in msg for one - to_chat instead of printing every line to_chat. - - server: Discord bot will now report when a round ends and give the vague news - ticker that a sister-station would have received for the game mode and result - of the round. - - bugfix: fixed medical hardsuit overlay issue. I thought it was going to work well - but fuck byond. - - bugfix: None body markings shouldn't give rgb hell, but it also should reset properly - anyway. ree. - - bugfix: Sorted some sprites to better sooth my byond icon limit anxiety. - - bugfix: Box Cryopods expanded to 6 public. Permabrig cryo fixed. - - bugfix: Delta Cryopods expanded to 6 public. Permabrig cryo fixed. - - bugfix: MetaStation Crypods expanded to 6 public, relocated above sparring ring. - Permabrig cryo fixed - - bugfix: PubbyStation gained one more cryopod, Permabrig's cryo fixed. - - rscadd: Omega given one more crypod as well. - - rscadd: Gulag was given a cryopod. - - tweak: Box and Meta's cryo rooms are now a new room entirely. - - rscadd: Added erect states for all phallic bodyparts - - bugfix: YOUR DICK ACTUALLY STANDS UP NOW, YOU'RE WELCOME. - - bugfix: skintone locked genitals match the new skintone colorations. - - rscadd: added two new vaginal types and descriptions. - - bugfix: fixed borg defib runtimes - - bugfix: fixed heart attacks being nonlethal - - rscadd: Ported Oracle's cloning set up, you're now visible like cryo when being - cloned, though it's a mystery until you have skin on your meat puppet existance - - balance: Recyclers are unable to destroy the indestructible any longer. - - bugfix: Kiara's toy sabre now actually is the correct item + icon states - - bugfix: Generic armor for taurs fixed, there isn't actually any sprites for 'em, - so. Full sprites overlay over bodies, but I really can't be bothered to do all - the offset fixes otherwise. - - rscadd: Large maps have had a patient room transformed into micro chemistry stations - with nothing else in them. They've been labelled 'Apothecary' rooms and are - accessible by doctors. - - rscadd: females now have female defined sprites - - bugfix: Slime legs have had their excess pixels adjusted - - bugfix: Mammal normal legs are more in line with human legs now - - bugfix: fixed species like abductors and golems getting the fat tiddy or pingas - - bugfix: Atmos and Station alerts should be more alerting. - - rscadd: Added visible and hidden testicles - - rscadd: Added multi-boob support. Now you can have two or three pairs of breasts. - - bugfix: fixed missing vagina and breast sprites - - bugfix: fixed prosthetic hands being invisible - - bugfix: male foxes exist again - - bugfix: female chest markings improved from being too dark in comparison to their - other colors, blending better - - bugfix: Markings behave better on non-organic limbs. - - tweak: tweaked the name of Sublter to distinguish its use - - tweak: Gave a hint for vore posting. - - rscadd: Readded Ninja speech modifications with their mask - - rscadd: Pacifists can eat people for heal belly or noisy. Digestive modes are - auto-swapped to noisy - - rscadd: Added an underwear toggle button under 'Object' tab - - tweak: Genitals now layer under underwear. Hide these if they're too obnoxious. - - rscadd: Added digitigrade socks of all known ones anyway. - - tweak: tweaked the Genital character creation layout to look better - - bugfix: fixed having balls/womb when you don't have the linked organ at character - creation - - bugfix: fixed being able to squeeze semen directly from your balls. Probably. - - rscadd: NT Newscasters have had repeated reports of gang activity and are now - looking into it. - - rscadd: NT Psykers keep mumbling about last words of someone who died. Somehow - they even have a newsletter for this... - - bugfix: Gangster greeting messages are a batch message rather than 5 laggy to_chats - - imageadd: RCL now show what color is currently in use - - rscadd: Added RGB blood effects, know whose blood this is by color! - - rscadd: Added Synthetics blood, and a machine that produces it. A universal donor - for medical to heal people with. Make it via medical protolathe! - - bugfix: With hearts, slimepeople shouldn't die from the effects of not having - a heart. - - bugfix: Plasma vessels from xenomorphs will restore blood if you're on resin. - - server: Poly's speech now echos to the chat bot. - - rscadd: Added new wings to Insects and separated fluff from old ones, they're - Insect's new body markings now without being per-limb (for now). - - rscadd: Horns are now available to mammals, and they have their own color. - - rscadd: Legs are no longer a binary hack code, but actually something that can - be changed. Framework for tauric adaptations. - - rscdel: Purged Modular Citadel's sprite_accessories. - - bugfix: improved the quality of a number of sprites. - - tweak: Moths are now all insects. Avians and Aquatics are all anthromorphics. - Just as planned. - - rscadd: Anthromorphs can choose their preferred gibbing meat. I guess. Snowflakes - are weird. - - bugfix: Additional Gentlemen names. - - rscadd: Medical huds are now calibrated for Radioactive wavelengths. - - balance: Engineering equipment, blue space, and common storage containers are - radiation protected - - bugfix: fixed suit storage not cleaning radiation levels of everything stuffed - into them. - - bugfix: QM is able to hire/fire people to their department now. - - bugfix: cryopod UI isn't complete shit anymore - - bugfix: Cryopods purge silicon gear more efficiently now. Same with ghosts. - - balance: Med Sprays are now more aligned with patch mechanics - - balance: Chemistry is encouraged to be more varied in their healing, as well as - careful in its application - - tweak: Active NPC priority set much higher priority for the MC, with the intent - on making NPC combat more interesting - - bugfix: Clarified access descriptions of some jobs - - bugfix: fixed missing deco wing states - - bugfix: fixed a few things related to vore content - Putnam3145: - - tweak: Bottles in PanD.E.M.I.C 2200 can now be replaced with an inhand bottle - directly - - tweak: Ejecting a bottle from the PanD.E.M.I.C 2200 puts it directly into the - user's hand - - tweak: Alt-clicking the PanD.E.M.I.C 2200 ejects the current bottle - - bugfix: neural nanites only work/drain if you have brain damage or traumas the - nanites can fix - - tweak: Pod people can no longer get fat from standing in the light - - tweak: PanD.E.M.I.C 2200 now ejects onto itself instead of onto user if user's - hands are full - - rscadd: Added configs for a bunch of Dynamic rule parameters. - - config: Added defaults for all the configs (WIP). - - config: Added dynamic midround/latejoin antag injection to the config. - - balance: Made starlight condensation not kill slime people. - - balance: Added not-killing-slime-people to the transmission threshold of plasma - fixation and radioactive resonance. - - tweak: Made the clone scanner lock while it's scanning. - R3dtail: - - rscadd: Added 16 saltprimaryobject items Added 4 saltsecondarysubject items - - rscadd: Added a new carpet. Red! Also added said carpet to the Premium Carpet - crate from the cargo supply console. Trilby said she'd take care of the crafting - recipe. - Raptorizer: - - tweak: Doubled peach spawn rate - - tweak: tweaked numbers/variables - - balance: rebalanced numbers/variables - - spellcheck: removed unneeded code - Seris02: - - rscadd: Abductor Replication Lab ruin and advanced tools - - rscadd: Added looc hotkey - - tweak: made the autoprocess button relevant - - tweak: changes so that spooktober starts earlier - - bugfix: fixed the dark blue lum major effect - Sirich96 and Dennok (ported by Ghommie): - - rscadd: Added new Teleporter Station sprites - - rscadd: Added teleport station calibration animation. - Sishen1542: - - rscadd: Pentetic Jelly, new chemical made through mixing 1:1 slime jelly and pentetic - acid. - - tweak: Anatomic panacea now gives pent jelly instead of pent acid. Medbeams now - have TRUE tox healing to heal TOXINLOVER as well. - - balance: Changed bible heal proc, halving the healed damage and increasing brain - damage 5x in exchange for a much wider array of items to protect you from it. - - tweak: Moved around some chems from emag list into upgrades. - - balance: Added some fun chems to dispensers. - - bugfix: Gave dispensers old tg functionality. - - rscadd: Leather, cardboard, bronze & bone golems! - - rscadd: Bone hurting juice and interactions with plasmamen, skeletons & bone golems! - - rscadd: Ported addition of new CAS cards. - - bugfix: Ported a fix for CAS. - - rscadd: Added the ability to alter your genitalia as a slimeperson more than addition/removal. - - bugfix: fixed genitalia removal proc in alter form. - - balance: Ported the inability for non-station AI to interact with station z-level. - - balance: HoS mains can now peacefully sleep in their office. - - tweak: Podpeople now have customization options. - - bugfix: Removed the human check for cult conversion of captain/chaplain minds. - - balance: Roundstart carbon jetpacks now have full_speed FALSE. - - tweak: Adds plasteel to medical and security techfabs. - - rscadd: Added public autolathes to all maps. - - tweak: density = 0 - - balance: hugboxing mining loot - - balance: ling blade now has 40 armor pen - - rscadd: fun - - rscdel: bad stuff - - balance: mech bad - - balance: rebalances strained muscles - - rscadd: added in the assistant response team - - bugfix: fixed up access on the centcom hangar button - - balance: storage tweaks for belt briefcase - - imageadd: codersprite for belt briefcase - - rscadd: added pharaoh gear to chaplain vendor - - spellcheck: fixed typos in pharaoh items - - rscadd: made laser minigun not shitcode and also craftable - - soundadd: added new fire sounds for the laser minigun - - rscadd: holy lasrifle, hypertool, divine lightblade, and blessed baseball bat. - Four new holy weapons! - - balance: stamina and force tweaks for most holy weapons. - - tweak: prayer beads no longer deconvert after a 10 second timer, now just inject - holy water for delayed effect - - tweak: cultist runes are now destroyed with a bible or a null rod - - tweak: bo-staff now functions as a nerfed sleepy carp staff - - bugfix: fixed kevinz code to add in non-null rod child items as holy weapons - - bugfix: fixing chems for strained muscles - - bugfix: narsie no longer asks for consent - - bugfix: removed reflect from divine lightblade - - bugfix: teleporting a locker is bad - Sishen1542, original by @Tlaltecuhtli: - - bugfix: alt clicking the emitter now rotates it instead of only flipping - Sishen1542, original by @zxaber: - - balance: Utility mechs no longer automatically get beacons. - - balance: Tracking beacons no longer delete themselves when EMPing a mech, and - instead have a ten-second cooldown in-between EMPs. They also now do heavy EMP - damage rather than light. - - balance: Mechs that take EMP damage lose the use of their weapons and equipment - temporarily. Movement and abilities are not effected. - - balance: Mechs taking EMP damage no longer roll for a random malfunction. - Sishen1542, original by Arkatos: - - rscadd: Action buttons can now be dragged onto each other to swap places - Sishen1542, original by NewSta: - - tweak: updated the miasma canister sprites - Sishen1542, original by Skoglol: - - rscadd: Heaters/freezers now support ctrl clicking to turn on and alt clicking - to min/max target temperature. - Sishen1542, original by XDTM: - - rscadd: Using the wrong surgery tool during surgery no longer attacks the patient, - if on help or disarm intent. - - rscadd: Surgery steps are now shown in detail only to the surgeon and anyone standing - adjacent to them; the patient and people watching from further away get a more - vague/ambiguous description. - Skoglol: - - rscadd: You can now alt click storage (bags, boxes, etc) to open it. - Skully): - - rscadd: Nudity Permit, a completely invisible uniform that still has pockets and - such, to loadout options. It is more or less a direct port from the RP server. - SkullyRoberts: - - rscadd: Penis autosurgeon as rare maint loot. - TerraGS / Skoglol: - - rscadd: Adds toggleable light and blinking charge indicator to kinetic crusher - - rscadd: Kinetic crusher can now be one-hand carried. You'll still need two hand - to use it. - Thalpy: - - bugfix: fixes message_admins in SDZF - - tweak: Alkaline buffer recipe so people don't get grumpy and expanded the pH range - - bugfix: fixes buffers - - bugfix: fixes broken compiler because a var changed name - - bugfix: impure travis var anger - - rscadd: Added the ability to dispense smartdarts from the chemmaster. - - tweak: Tweaks medolier amd chembags to allow quickpickups of smartdarts, lets - the latter soak in beakers (on the floor) - - bugfix: fixed rounding errors with smartdart mixes. - - imageadd: added modified smartdartgun icon. - - bugfix: 1. Kev asked that there were no antag datums used, so that's been changed. - 2. Tricks can no longer turn someone into a dullahan, instead you have to spend - candies to get that. I felt it was too mean to turn people into that, I didn't - realise you couldn't revert it. 3. Barth will no longer as for impossible items. - 4. Barth will no longer as for the same item multiple times. 5. Barth will now - accept broader things, rather than asking for something, when meaning something - specific. 6. Jacq will now no longer poof off the z level. 7. Jacq will (hopefully) - stop spooking the AI by teleporting into there 8. Jacq will now try to teleport - to a location with someone nearby. 9. Barth will tell you where Jacq is currently - when you speak to him. 10. You can trade 2 candies for a Jacq Tracq (tm) 11. - Jacq should stop getting mad and cover the station in gas when killed. 12. Fixed - Jacq not singing (the link died). 13. Slightly changed wording so that people - will hopefully get to know her. 14. Jacq no longer disappears when you're getting - to know her. - Toriate: - - imageadd: 'All regular crates are now 3/4ths ToriCrates iamgeadd: Unused plastic - crate sprite added' - - rscadd: Blood freezer crates now have unique sprites. - - rscadd: RPD now has inhands - - imageadd: New sprites for RCDs and RPDs, inhands included - - imageadd: Updated the sprites of all the regular crates - Trilbyspaceclone: - - rscadd: cakes! - - imageadd: Made some sprites! -Love them really came out well - - rscadd: new economics - - tweak: cargo and robotics relationships - - balance: unbalanced something - - bugfix: fixed a maybe oversight - - rscdel: Fun - - tweak: costs of suit voucher - - balance: Unblances miner vender - - bugfix: spare cheaper brute kit - - tweak: harm from hentie - - balance: rebalanced goliaths stun to be less auto death - - rscadd: Armor to blob shields - - tweak: block weaken state to 70% from 75% - - bugfix: restores the deathriplys missing armor - - rscadd: new lockable colalr - - tweak: armor - - bugfix: missing hopes and dreams - - code_imp: orgized the weapon file to be more cat brain friendly - - imageadd: This means sprite right? - - rscdel: Many engi flags on non-engi things - - code_imp: changed some code to be organized at a glance - - balance: '25% < --- 50% For NPC blocking bullshit ided: Yes' - - rscadd: mag gun uses cells - - balance: kev things their to op - - rscadd: syndicate phobia - - tweak: other phobia's - - bugfix: laser carbine - - tweak: makes collars only locked via key - - tweak: charging - - rscadd: Combat inducers for COMBAT! - - code_imp: made it look nice - - rscadd: golden swag boxes - - rscadd: Crafting suitcases - - rscadd: more bountys - - rscdel: Nitryl bounty - - rscadd: better stocks - - rscadd: more evil blood fluff text - - rscadd: Added more mime names - - tweak: replaces a sink with a autolathen - - balance: 2 -> 3 - - rscadd: MASON SUIT! - - rscadd: adds the sec jetpack to sec hardsuit storge - - rscadd: Added a few jet packs to the space queens men - - tweak: volume of jet packs - - rscadd: Bad Idea - - rscadd: bio mass meat - - rscadd: more box options - - bugfix: a lack of replaceable boxes - - bugfix: clothing needing a emag - - tweak: 4 - > 5 - - tweak: 5->6 - - tweak: 4tc - > 2tc - - tweak: mulligan costs 4 - > 3 - - tweak: Tuberculosis 12tc - > 8tc - - tweak: 15 - >10 - - bugfix: both bags have the same name - - tweak: 5 - > 2 - - tweak: 3 -> 1 - - tweak: 2 < - 4 - - tweak: 1->2 and ultra - - rscadd: shield + crafting - - tweak: hierophant movment and melee attack - - rscadd: More plushies - - tweak: attack verbs and descs - - rscadd: bone satchles - - balance: rebalanced stunslugs - - rscadd: colored boxes, and more types - - tweak: harm and such - - balance: item classes - - bugfix: resonators being so shitty - - bugfix: 'Game braking bug critical: bug fix' - - rscadd: items to syndie surgery bags - - rscadd: SNOW CONES - - rscadd: carts buy-able cargo - - tweak: selling/time to craft - - bugfix: crafting problems, and red stamp exsplote - - rscadd: gives paper work sprites that are nicer - - rscadd: origami - - rscadd: gang tower shield - - tweak: costs of boots - - rscadd: organ box - - rscadd: Medical breifcaseses - - rscadd: New cargo crate for tech-slugs! - - rscadd: Ammo to each fitting crate - - bugfix: Cat-code - - spellcheck: fixed a few typos - Again my bad - - bugfix: fixed airless place - - rscadd: baklava - - balance: makes uplink kits more usefull for the risk - - code_imp: Changes some files to be better - - balance: As all things are not - - bugfix: fixing cat code that dosnt work, my bad - - bugfix: Arcades stealing from noodles - - rscadd: rapier - - tweak: speedy quirk - - spellcheck: Ironic - - bugfix: A bunch of minor issues with xenobiology are no more! - - bugfix: I didn't code it right it in the first place - - rscadd: new nodes - - balance: points and node gear - - rscadd: stuff n things - - rscadd: gear harness and a conflict merg - - rscdel: Nudity permits - - bugfix: nothing - - rscadd: Donner item - - rscadd: Luna's Gauntlets - - balance: rebalanced lingy dingy powery gamey - - tweak: melee and block harm - - bugfix: sprites* - - balance: bone satchles - - tweak: holster doing holster things - - rscadd: Donor item - - rscadd: Joy, Happiness, Honk - - bugfix: small mix up in terms - - rscadd: Promiscuous Organs crate, pills to lewd crate and testicles to maints - - bugfix: Made unholy water healtoxinlover - - rscadd: Zelus Oil, brass flasks - - rscadd: Added new chairs - - admin: Bugtesting zone upgrades for easy bug/game testing - - rscadd: more cargo to cargo - - rscadd: More loadout gear - - bugfix: Poojawa power creep - - bugfix: Not my work not my credit - - rscadd: Emitter gun - - bugfix: suit storage nulling anti magic item protection - - balance: rebalanced steal goals restrictions - - spellcheck: fixed a few misleading goals - - bugfix: ports a fix - - bugfix: oversight in benos - - bugfix: QM rooms not getting Key Aunths - - rscadd: new books/cooking - - spellcheck: less bad wording in slime - - rscadd: strawbarries and such - - rscadd: amazing things like tea of catnip, catnip and plant - - tweak: glue uplinks - - rscadd: RPDs to drones - - rscadd: Armor and such - - rscadd: flavor - - bugfix: maybe a runtime - - rscadd: chameloen clothing - - rscadd: tons of peach themed items - - spellcheck: caje - - rscadd: New book - Unused - - code_imp: organized files - - imageadd: redid brass tools to look better* - - bugfix: /cursed from a item path - - rscadd: Almost all clothing and most weaponds can be sold for pocket change - - tweak: Cargo costs of packets and selling - - balance: Lowered mat selling as well as most if not all bountys - - code_imp: Adds more files for easy finding/adding in packs - - bugfix: oops not being blacklisted - - code_imp: removes some cit-modular things - - bugfix: Missing sprites with bad ones - - tweak: emag charge amount - - rscadd: Reebe QoL aka creep in gear - - bugfix: ??? - - server: HEY MADE THE REEBEEE WAY SMALLER - Making it less lagging hopefully - - rscadd: Surgerys and spays in bags - - tweak: earthbloods stam regen - - imageadd: Red to Blue/Black crosses as questioned by Bhijn - - bugfix: clean bot not cleaning basic cleanables - - rscadd: new traitor bundle - - rscadd: trash - - imageadd: 'eye bleed :add: misstakes' - - rscdel: Removed old things! - - bugfix: UI memes - - rscadd: Blue space blood bag - - tweak: blood costs - - rscadd: Beebal and Honeybalm plants - - tweak: Costs of crates and paperwork - - rscadd: Adds 2 more crates hacked only - - rscadd: Added two seed packets of cotten to ash walkers base - Tupinambis: - - tweak: Changes large parts of the nuclear operative base, including the addition - of a new barracks where the ops spawn, a personal bedroom for the leader, the - rearrangement of numerous rooms, some added fluff, a slightly more roomy bar, - a larger hanger, a kitchen, and various other small changes to make the base - feel just a bit more alive. This was achieved by completely redoing the base - from scratch so there was room to work with, as a result potential bugs could - crop, please do report them. - - bugfix: The drop pod chamber was airless. This seems like an oversight, and has - been filled with air. - - rscadd: Cryo Sleepers have been added to Perma on all four maps in rotation. the - bathroom windoor and window have switched places to accommodate this change. - - rscadd: You can now choose the pre-exisiting "loader" sprite as an appearance - for your engineering borg. - - tweak: A vast majority of references to humans within ion laws have been replaced - with crew. AI modules have received similar treatment - - rscadd: 'Adds a syndicate themed emergency shuttle that costs 20000 credits, and - can ONLY be purchased when the communications console is emagged. This shuttle - features a fully stocked medbay with self serve sleepers, plenty of room that - can fit highpop, a fully featured bridge, ballistic auto turrets, and an armory, - EVA prep room, and bar, all of which are only accessible by either an agent - ID or through hacking. - - -EVA prep features 2 syndicate hardsuits and 3 syndicate softsuits. -Armory - features 5 stetchkins with spare ammo, and 2 riot c-20r''s. - - ![image](https://user-images.githubusercontent.com/42078130/48306551-0b786380-e500-11e8-821a-e59ac4eee0ea.png)' - - balance: Lone operatives no longer spawn with a syndicate hardsuit and a bulldog. - They instead spawn with a black and red EVA suit and an extra 15 TC (40 in total) - ![image](https://user-images.githubusercontent.com/42078130/48308065-c44e9a80-e520-11e8-8d60-cec8ff23d61d.png) - - rscadd: The tesla engine has been replaced with a supermatter engine, and pubby - engineering has been redesigned to accommodate this change. - - rscdel: The tesla engine has been completely removed along with any related components - - bugfix: RD and R&D vents are now actually connected to the air distribution. - - rscadd: New engineering hivebot. Has a bit more health but otherwise aesthetic. - - tweak: Oldstation no longer has an excessive amounts of hivebots within it, however - the bots that remain are individually a larger threat. - - balance: Hivebots are now more robust, with a higher melee damage output and health. - - server: Remove this ruin from the blacklist or this PR is pointless. - - bugfix: the air injectors for the SM engine waste and for toxins waste should - now receive power - - tweak: Adds a mixed clothing closet to Deltastation Dorms. - - tweak: Adds a bottle of unstable mutagen to Botany, on account of its distance - from Chemistry. - - bugfix: Omegastation should no longer have any turf with missing textures, as - those spots have been replaced with playing covered in a sandy turf decal. - - tweak: Removed all living eggs from the xeno ruin because people self antag. Honk. - - rscadd: Adds a new security level between Blue and Red (Amber). The shuttle call - time at this level is 8 minutes. - - tweak: Blue security level now has a shuttle call time of 12 minutes. - - tweak: The security level increase/decrease texts have been modified to accommodate - the change. - - imageadd: Adds a code Amber sprite for the fire alarms - - tweak: Removed the plushes from the toy crate, giving them their own. - - tweak: Plushes are now less likely to spawn out of arcades - - imagedel: Removes a moth plush from the game. - - balance: added a small fire delay (3 ticks) to automatic shotguns - - balance: Reduced buckshot brute damage by 20%. (12.5 -> 10 brute per pellet) (75 - -> 60 brute at close range) - - balance: Reduced rubbershot stamina damage by 40% (25 -> 15 stamina per pellet) - (150 -> 90 stamina at close range) - - balance: Reduced beanbag stamina damage by 12.5% (80 -> 70 stamina per shot) - - balance: Engivend RCDs now vend upgraded RCDs - - imageadd: Beautified and stylized the cyborg HUD sprites, animated and cleaned - up some of the old, modernized APC hacking and Doomsday sprites, - - tweak: moved cyborg language select above the radio icon, instead of above the - picture icon. - Twaticus & Poojawa: - - rscadd: Added new carpets from TauCetiStation! - - rscadd: More Liquid carpet chemicals, mix carpet with certain reagents to get - different colors! - - refactor: Tablets have a better means of being assembled codewise. nothing's different - on player end. - UntoldTactics: - - tweak: Rewords the click here prompt given when an attempted conversion is done - on an offer rune (for blood cult) - UristMcAstronaut: - - bugfix: allows a pai to activate its holoform while in a pai connector without - getting derped. - Useroth: - - bugfix: the collars are now aware of their proper overlay sprites - - bugfix: The space hotel dorms are now properly boltable with the buttons inside. - - bugfix: Makes the booze-o-mat hacked by default. Alternative to https://github.com/Citadel-Station-13/Citadel-Station-13/pull/8350. - - bugfix: After the PR which raised the ammo capacity of said magazines, due to - the code, they ended up with an invalid icon state. Fixed through changing the - icon state name in the icon file. - - rscadd: 'Taeclowndo shoes which grant the four following abilities: - Conjuring - a cream pie right into their hand. Every three seconds. - Making a banana peel - appear out of thin air at the tile of the clown''s choice. Every ten seconds. - - Mega HoNk. A touch-ranged, very small AOE ability, with effect equal to being - honked by a Honkerblast on a clown mech, with the effects halved for anyone - who isn''t its direct target. Every ten seconds. - Bluespace Banana Pie. You - don''t throw this one... not right away at least. This baby can fit an entire - body inside. Good for disposal of evidence. 25 second-long action, 45 second - cooldown. Also produces a "[victim''s name] cream pie". The body drops out of - the pie if you splat it somewhere or destroy the pie. If you eat it, it will - chestburst out of you a''la monkey cube. - - It''s a 14 TC item for traitor clowns and a 12 TC item for clown-ops.' - - tweak: The tentacle now directly puts the item in your hands, instead of toggling - your throwing and tossing it at you. Tentacles suffer from ranged inaccuracies - as if they were guns, I think it's enough of an inconvenience. - - tweak: Makes the netting much less clunky. If there's only one target you can - net while you press the button, it will just net that target instead of bringing - up a list of mobs. - - tweak: Energy nets now revive and fully heal capturees (even dead ones, after - calculating points). If someone's got a scan and wants to get cloned, they can - always kill themselves still. - - tweak: Capture points are added on capture, rather than round-end, so it no longer - matters whether your captures kill themselves in the holding facility or not. - - balance: Makes the nets a bit more sturdy. (previously it took mere two welder - hits to break one) - - balance: Makes stungloves actually stun people (currently comparably with stunbatons, - adjustable). Because electrocute_act(25, H) did fuck all, stunwise, and on top - of that, people in insulated gloves were completely unaffected. - - balance: Reduced the stunglove electrocute_act value to 15 due to above. Could - possibly be lowered further. - Weblure: - - rscadd: Added the relevant Beepsky animations from TG's aibots.dmi file to Cit's - aibots.dmi file. - WhiteHusky: - - rscadd: Sleepers now show blood level and type. - - tweak: Changed the styling of arousal messages to use pink-ish colors. - - bugfix: The orgasm moodlet message new-lines properly. - - bugfix: Flavor text with special characters will not get partially unescaped. - - bugfix: Canceling when setting flavor text does not clear it anymore. - - tweak: Checking yourself shouldn't freeze the client anymore. - XDTM: - - rscadd: Added the experimental dissection surgery, which can be performed once - per corpse to gain techweb points. - - rscadd: Rarer specimens are more valuable, so xenos and rare species are more - efficient subjects. - - rscadd: Added two new surgery procedures, under the Experimental Surgery techweb - node. - - rscadd: Ligament Hook makes it so you can attach limbs manually (like skeletons) - but makes dismemberment more likely as well. - - rscadd: Ligament Reinforcement prevents dismemberment, but makes limbs easier - to disable through damage. - - tweak: Golem limbs can now be disabled, although they are still undismemberable. - YPOQ: - - bugfix: Stealth implants work again - Yakumo Chen: - - balance: Made stealth implant boxes flimsier - - balance: Autocloning now requires tier 4 parts - - rscdel: Removes autoscan - - balance: Scanning people now requires someone to operate the cloning computer - regardless of part level. - - balance: removed antimagic component from holymelon - YakumoChen: - - tweak: AEGs brought more in line with current radiation system. Try not to get - EMP'd. - - tweak: Jetpacks no longer last twice as long between air refills. - - rscdel: Reverted laser miniguns. - - rscadd: Adds beanbag slugs to the sec protolathe at round start - - bugfix: Brings shotgun ammo availability back in like between seclathe and autolathe. - Zargserg: - - balance: Lungs maximum toxin threshold is 0.5% of the atmosphere. - - bugfix: Permanently contaminated atmosphere does not murder crew anymore. - ZeroNetAlpha: - - tweak: Cleans up autoylathe code and brings it back in line with the regular autolathe. - - bugfix: Fixes autoylathe interface not updating propperly. - - tweak: Silicons are now consumable by scrub pups. - actioninja: - - bugfix: APC UI autoupdates correctly - bluespace bio bags: - - rscadd: Added bluespace bio bags and put it in the tech web, in the node applied - bluespace - - imageadd: added a crappy icon for bluespace bio bags - chef: - - rscadd: Added main hallway approach to monastery - - rscadd: Added Maintenance hallway approach, with some maint loot - - tweak: moved the docking arm for the white ship - - tweak: changed placement of some grills and windows - coiax: - - admin: When the nuclear disk stays stationary long enough to trigger an increase - for the lone op event chance, admins will be notified every five increments. - dapnee: - - rscadd: Plasmaglass tables, spears, tiny plasmaglass shards - - bugfix: Plasmaglass structures now drop plasmaglass shards instead of nothing - - rscadd: Trim lines! - - bugfix: You can now make plasmaglass tables again. - deathride58: - - admin: When a gamemode fails pre_setup, it will now send a message in admin IRC - and in ingame admin chat, instead of only being viewable in the logs. - - balance: Portal guns now spawn without firing pins. - - balance: Reduced the default/baseline nanite pool amount from 100 nanites to 25 - nanites, and reduced the maximum nanite amount from 500 nanites to 125 nanites. - The safety threshold was reduced from 50 nanites to 12 nanites. - - balance: Most of Lavaland's mobs are now on crack. - - balance: Blood drunk miners now move once every two ticks, rather than once every - three ticks. - - balance: Bubblegum now has a maximum movement speed of once every three ticks. - Buffed from the original value of once per 5 ticks. - - balance: The minimum time for the Colossus to attack again after firing a random - shot is two deciseconds, Sped up from the original value of three seconds. The - minimum time for the Colossus to attack again after performing a blast is now - one second, with the original value being two seconds. The minimum time for - it to attack again after performing its alternating shot pattern is now two - seconds, original value being four seconds. - - balance: Ashdrakes now move once every five ticks, rather than once every ten - ticks. - - balance: Heirophant chasers now move once every two ticks rather than three ticks - by default, and the chaser cooldown has been reduced from 10 seconds to 5 seconds. - The cooldown for the Heirophant's major attacks has also been sped up to 4 seconds - from the original value of 6 seconds. - - balance: The Legion (megafauna) now moves at two ticks per second rather than - three ticks. It additionally now actually moves faster while charging. The cooldown - timer for it's special attacks has been reduced from 2 seconds to 1 second. - Additionally, The Legion's view range has been decreased from 13 tiles to 10 - tiles. - - balance: All megafauna now have a default view range of 4 tiles, decreased from - the original of 5 tiles, and an aggro'd view range of 15 tiles, decreased from - the original of 18 - - balance: Goliaths now move once every ten ticks, sped up from the original value - of 40(!!!) ticks. Additionally, their cooldown for their tentacles has been - reduced from 12 seconds to 6 seconds. To compensate, their cooldown now only - decreases by 5 deciseconds every time they're attacked, rather than 10 deciseconds, - their melee damage has been reduced to 18 per hit from 25 per hit, and their - vision range has been decreased from 5 tiles unaggroed, 9 tiles when aggroed, - to 4 tiles and 7 tiles respectively. Ancient goliaths have a default attack - cooldown of 8 seconds, sped up from the original value of 12 seconds. - - balance: Legion (the common mob) now has a cooldown of 1.5 seconds on their skull - attack, sped up from the original value of 2 seconds. Additionally, their view - range has been decreased from 5 tiles, 9 tiles when aggroed, to 4 tiles, 7 tiles - when aggroed. - - bugfix: Stamina no longer regenerates at hyper speeds. - - tweak: To accommodate for upstream's stamina changes, knockdown() now applies - staminaloss only to the chest. - - tweak: adjuststaminaloss() now has a new argument that allows you to specify a - zone to apply staminaloss to. This defaults to the chest - - tweak: apply_damage() is now capable of healing carbon mobs and human mobs. - - tweak: Since the head has the same exact effects as the chest when disabled, and - doesn't really make much sense to be affected by stamina, the head no longer - has stamina. - - tweak: The chest now has a stamina cap of 200 stamina due to the above. - - tweak: Footsteps now sound mostly the same as they did before the hard sync - - bugfix: Jukeboxes now properly remove themselves from the active jukebox list - when destroyed - - rscadd: Server operators and badmins can now make the server play like TG by toggling - the stamina buffer on/off using the DISABLE_STAMBUFFER config option. - - bugfix: Airlock wires now work as they did prior to the hard sync - - balance: The thing you're currently grabbing is now taken into account when left-click - disarming. Things you have grabbed now roughly have a 45% chance to be disarmed. - - balance: Disarm push rolls are now determined by the target's staminaloss rather - than a flat number. - - balance: When you're in combat mode, pushing someone who isn't in combat mode - is a guaranteed knockdown. Hard counter to stam regen squeezing in melee combat. - - balance: Failed disarm push attempts now deals light staminaloss to the target - so long as both the attacker and target are standing. The total stamloss dealt - to the target is random, clocking in at a very inefficient 1-5 stamloss per - unsuccessful push attempt. - - tweak: Disarm pushes now play the thudswoosh sound regardless if they're successful - or not. Had it not been for copyright, I would've used L4D's melee sound. - - tweak: Disarm push attempts are now logged - - bugfix: Autostand no longer makes you invulnerable to dropping items when being - knocked down with a force greater than 80 - - bugfix: You can no longer abuse an href exploit to return from the labor camp - before obtaining enough points to satisfy your point goal. - - bugfix: Norko's donor item is now listed in the right category - - rscadd: The medihound sleeper now has a non-vore variant. This will be used by - default. The old voracious variant will only appear if both the person being - sleeper'd and the medihound have the voracious hound sleepers pref enabled. - Sprites by Toriate - - tweak: '"Allow medihound sleeper" is now labelled "Voracious medihound sleepers", - and is now off by default' - - bugfix: AOOC no longer prints to players in the lobby - - bugfix: Human tails and human ears now save again. Humans now use mam_tail and - mam_ears for their snowflake bits instead of tg's equivalent, just as they did - prior to human tail and ear saving breaking - - bugfix: Disarm pushes no longer deal staminaloss to resting targets - - bugfix: You can no longer force a hard stamcritted spaceman to stand by clicking - them with help intent. Get more creative if you want to torture someone that's - in hard stamcrit. - - tweak: The revolution gamemode now waits until the 20 minute mark before checking - for win conditions. - - balance: You can no longer resist/move out of grabs while you're resting. Disarming - your way out still works, though. - - rscadd: Stamina damage now has diminishing returns on people who are in hard staminacrit - with the addition of a new multiplier. When you take staminaloss while in hard - staminacrit, you'll be under the effects of the new multiplier, which reduces - the amount of staminaloss you take from all sources of staminaloss. The diminishing - returns multiplier will steadily return to 1 once you're out of staminacrit. - - rscadd: You can now scramble while resting. You can do this by dragging your spaceman - onto an adjacent turf. This works even if you're in staminacrit, but the timer - depends entirely on your staminaloss. - - bugfix: Fully augged cyborg people now heal stamina damage properly. - - bugfix: Job EXP is now tracked properly for all roles. - - balance: Nightmares and shadowpeople have had their light threshold for being - considered in darkness reduced. Nightmares can no longer stand unharmed next - to a light fixture during a nightshift 100% unharmed. The threshold is high - enough so that APC lights on their own won't harm a nightmare, but being on - the edge of a light source will. - - balance: The detective revolver's .38 bullets are now non-lethal again, but now - require 3 shots to hard stamcrit - - rscadd: The current lethal variant of the .38 bullets can still be printed at - sec protolathes. - - rscadd: You can now access ghost roles from the latejoin menu. - - rscadd: Eyeblur now scales depending on how much actual eyeblur you actually have. - - balance: Ebows now induce 50 drowsiness on whatever they hit. - - balance: Telepads have been buffed across the board. T1 parts on a launchpad still - grants you a range of 15 tiles, but T4 parts now grant you a pretty large 60 - tile range (up from their original 18 tile range). Briefcase launchpads were - also buffed, they now have a range of 20 tiles, up from their previous laughable - 8 tiles. - - tweak: The grace period for the revolution win condition check has been reduced - from 20 minutes to 10 minutes. You don't need to wait nearly as long for the - round to end if no heads join in. - - tweak: You can now select plural and neuter as your gender. They're labelled "non-binary" - and "object" in the character customization menu, respectively. - - tweak: A lot more light sources now use the same nonbinary colored lighting philosophies - as flashlights and light fixtures! - - tweak: Flashlights mounted to guns and helmets now retain the same color and power - as their original light. Lavaland's caves will reflect a fluorescent blue as - you shine your KA around, and sec's helmets are now capable of illuminating - maint in that fancy fluorescent blue. - - tweak: Cameras now shine a fluorescent blue when lit up by an AI - - tweak: Glowing goo now actually glows green. - - tweak: Candles had their power reduced from 1 to 0.8. - - tweak: Lighters now shine a little further, and are now properly colored. - - tweak: PDAs now shine an incandescent yellow to match their sprite. - - tweak: Welding tools now shine an appropriate color - - tweak: Hardhats now shine an incandescent yellow. - - tweak: Plasmaman helmets now shine an incandescent yellow. - - tweak: Microwaves no longer overpower literally every single light in the game, - instead having a power of 0.9. - - tweak: Borgs now have incandescent yellow lights to match their sprites - - tweak: Bots now shine a fluorescent blue light - - tweak: Airlock light overlays are now on the above lighting layer. This means - airlock lights can actually be seen in the dark now. - - bugfix: The mob spawners list no longer leaves null entries behind when a spawner - has a job description defined. The latejoin menu will no longer show ghost roles - that are filled, and the spawners menu actually works again. - - rscadd: The voting system now actually tracks who voted for what. This means it's - now possible to change your vote, and it's possible to see what you voted for. - - balance: Using help intent on someone that's in hard stamcrit will now make them - heal 15 stamloss. - - tweak: Auto fit viewport is now enabled by default for new players. One less question - off the FAQ - - rscadd: The Khajiit favorite, Skooma, was added as a chemistry recipe that can - be produced with cooperation between chemistry and either cargo or service. - If you want to spoil the recipe for yourself, take a look at the PR for it! - - rscadd: When the shuttle leaves for centcom, a vote will be started to select - the next map instead of the map being randomly chosen via biased voting methods - - server: If a server operator wishes to re-enable the biased TG preference voting - system, you can do so by toggling the TGSTYLE_MAPROTATION config flag on in - the config.txt. Keep in mind that doing so will bring you great misfortune. - - balance: Cacti in lavaland now have 6u of vitfro instead of just 4u. This lessens - the gap between cacti and first aid kits, the third rarest and second rarest - readily available healing methods for ashwalkers, respectively. - - bugfix: the "genitals use skintone" option now appears in the character appearance - menu when appropriate again. - - rscadd: Clicking your stamina bar will now show your exact stamina along with - info regarding your stamina buffer - - bugfix: The bug where ghost role spawners leave null entries in glob.mob_spawners - has actually been fixed - - bugfix: The Kitchen Gun (TM) is no longer invisible. - - balance: The majority of cult spells no longer have exclamation marks at the end - of their invocations. This means they will no longer be bound to the rules of - shouting. Which means sec officers will no longer be able to hear culties sacrificing - the captain from the complete opposite side of the maintenance tunnel the sacrifice - is happening in. However, things like EMP pulses and runeless teleportation - still have the effect due to their inherent loud nature. - - balance: The stun blood spell now instantly causes hard stamcrit. However, to - offset this, it now also only has one charge and has a higher cost. - - balance: The Gloves of the North Star now restore 2/3 of the stamina used up by - punches when harm intent punching. With aggressive play and good stamina buffer - management, this makes it entirely plausible to roughly double your stamina - regeneration per mob life process tick. - - balance: Revs can no longer remember the name of the person who flashed them when - deconverted. This brings it in-line with the other conversion antag deconversions. - - bugfix: The bug where you can sometimes get permanently stuck in stamcrit should - HOPEFULLY be fixed. I'm unable to reproduce the bug myself, but let's hope. - - balance: The night vision trait now grants you darksight for an entire 1:1 screen, - but the alpha of the lighting plane with the trait has been increased from 245 - to 250 to balance it out - - bugfix: It's now actually possible to click the stamina hud button - - bugfix: The stamina hud button now displays your stamina buffer correctly - - balance: Bone spears now have a reach of 2 tiles. - - bugfix: You can no longer phase through solid objects via scrambling - - bugfix: The syndicate mask now works properly as intended. - - balance: Stamina is no longer affected by health at all. - - rscadd: You can now right-click yourself in help intent in combat mode to instantly - get up from resting. This will cost stamina equal to your entire stamina buffer. - Manage your stamina well, and you'll be able to shrug off a single stray golden - bolt - - rscadd: The new player panel now displays your currently selected character's - name - - balance: Flashes no longer knockdown. Instead, they deal eyeblur and have increased - confusion - - server: The server's tagline is now a config option. People can now stop confusing - us with BR cit - - rscadd: Attack animations will now rotate your character slightly, similar to - Goon. - - rscadd: Throwing items will now perform the attack animation and play a sound - - rscadd: flashlights will now make sounds when toggled on/off - - rscadd: Things in disposals will now emit sounds every single time they hit corners. - This increases immersion. - - bugfix: Air alarms now actually emit the proper light color when their status - is okay. - - rscadd: Backpacks and other storage items will now jiggle and squish when you - interact with them, similar to the animations seen on Goon. - - balance: Mops no longer have a delay on their cleaning, making them an actually - viable alternative to all of the janitor's other cleaning tools - - balance: To balance this, mops now take stamina to clean tiles. Standard mops - take 5 stamina to use, while advanced mops take 2 stamina. - - tweak: Oh and also mops make fancy new sounds and play animations when used now - - balance: Pump-action shotguns now take 2 stamina per pump instead of 5 stamina - per pump. This also applies to bolt-action rifles, as bolt racking counts as - pumping. - - tweak: Pickpocketing items will now place them in your hands if possible - - rscadd: Combat mode is now displayed in examine text - - rscadd: Combat mode now makes a visible message when enabled if you haven't touched - your combat mode button in the last ten seconds. It's done this way to avoid - chat spam from those who know how to pull off stam regen squeezing. - - balance: All knockdown sources will now force people to be dismounted from ridden - vehicles. - - rscadd: When an item is thrown, it will now be rotated and displaced. - - rscadd: Shards of glass will now be rotated when spawned. - - rscadd: Bullet casings will now be rotated when they're ejected from a gun. - - rscadd: Bottles now have random rotations and pixel offsets when smashed via throwing. - - rscadd: Picking up an item will now reset its rotation. - - rscadd: Glasses thrown onto tables by bartenders will now have their rotation - reset. - - balance: Slime speed potions can now only increase the speed of vehicles to be - on par with sprinting speed. They can no longer make a scooter roll around ten - times faster than a speeding blue hedgehog. - - rscdel: Changelings will no longer recieve team objectives - - balance: Changelings no longer start off with hivemind communication as an innate - ability. Hivemind communication now requires 1 dna point, on par with syndicate - encryption keys, which are 2 TC. - - code_imp: Hivemind link now relies on hivemind communication just like the hivemind - download/upload abilities. - - bugfix: It's now only possible to zoom a gun if it's in one of your hands - - bugfix: Mobs without clients no longer cause runtimes when their eyeblur updates - - rscadd: Blood tests have been added. If a changeling has a sufficient number of - loud abilities, you will be able to test their blood by heating up a sample - of it. However, if the changeling has a large amount of loud abilities, attempts - to test their blood will have explosive results. - - rscadd: Changelings now make a very obvious noise when readapting. This is to - prevent the cheese strat of simply readapting when you get caught to avoid detection. - - tweak: The blood splatter effect that happens when you get attacked will now always - make you lose blood depending on the damage you've taken. The effect now also - scales with item damage, meaning tiny little papercuts will no longer be able - to cause a massive blood splatter. - - rscadd: The blood reagent will now cover items and spacemen in blood when applied - to objects and mobs. - - tweak: Helmets, masks, and neck items are all now valid targets to get splattered - when you get covered in blood. Groovy. - - tweak: The temperature notification will now take into consideration both the - ambient temperature and your body temperature, increasing the responsiveness - of the temperature notification and making it much more realistic. - - tweak: Shuttle transit borders are now 10 tiles wide instead of 8 tiles, hopefully - repairing the immersions that get shattered by the ability to see normal space - where the transit areas end. - - rscadd: Instead of transit turfs simply teleporting things to space, transit is - now handled in a somewhat realistic manner. Transit turfs now act like normal - space turfs, though exiting the transit area or being present in the transit - area after the shuttle moves out of transit will teleport you to space and throw - you in the direction the shuttle was moving in. - - tweak: Reservation areas are now able to designate a border turf. - - bugfix: The sprint hotkey will no longer cause you to get permanently stuck sprinting - if the server lags. Just tap shift again if you get stuck - - rscadd: You can now hear sounds in the real world while inside of a VR sleeper. - - rscadd: You can now make nameless characters. Nameless characters will spawn in - with their name set as their job title followed by a unique five digit number. - The "Name" option in the character setup menu will be replaced with a "Default - designation" option for nameless characters, and the default designation will - be used in place of a job title for assistants and other jobs that don't require - dress codes. - - admin: The out-of-game round end notification is now a little more verbose. It'll - now display the round type, end result of the round, and the survival rate. - - bugfix: Xenos can no longer strip items off of people to be capable of using any - item in the game. - - bugfix: also, items from pockets get placed into your hands properly now - - bugfix: A mob's last words are now properly tracked and recorded on death. The - first death of the round will now actually display the victim's last words on - the round end screen. - - bugfix: Divine shenanigans can no longer result in someone becoming immune to - staminaloss - - bugfix: Fixed body_markings in bodyparts being assigned as a list when in reality, - it's a string and literally everything expects it to be a string and uses it - as a string. This should mean that markings no longer have completely fucked - up caches for character preview and other things. - - tweak: Since apparently the game is literally unplayable if items are not in the - exact center of a turf, the maximum pixel variance of thrown objects has been - reduced by four pixels to make things a smidge more clearer for those that dont - know what a turf is. - - bugfix: Bartender glasses should HOPEFULLY no longer be tilted when landing on - a table. Why the fuck is after_throw called via a timer. - - rscadd: Changeling screeches now have their own unique sounds, and are much easier - to recognize. - - rscadd: Most synthetic emotes are now available to humans. *ping - - rscadd: You can now merp - - balance: The TEG will now only produce a meaningful amount of power if the hot - pipe contains gas that's actively combusting - - admin: Added the "add PB bypass" and "revoke PB bypass" verbs, which allow admins - to let a specific ckey to bypass the panic bunker for the rest of the round - - rscadd: Jogging is no longer treated exactly the same as sprinting for water slips. - When you're jogging, you will only slip on water if you have more than 20% staminaloss. - - tweak: The atmospherics turf subsystem now has double the wait time, which should - free up server processing power for other tasks. - - bugfix: The IRC now actually displays the actual survival rate - - rscadd: Bloodcult conversions are now consensual. Convertees are given a ten second - timer to accept or wait out. This should drastically improve the quality of - those that get converted into bloodcult. - - rscadd: All sacrifices now count as a third of a cultist for the end-game narsie - summon. - - bugfix: Nameless captains will no longer proc a "Captain Captain on deck!" message. - Instead, it'll be a much more boring but much more sensical "Captain on deck!" - message. - - bugfix: Transit turfs on the centcom z-level now function properly again at keeping - mobs within the areas defined by their boundaries. - - bugfix: The title screen is also positioned correctly again. - - tweak: Ghost role eligibility for both event and spawner ghost roles is now affected - by DNR status. If you suicide, ghost, or cryo out, you will be unable to qualify - for any ghost roles - - tweak: Cryo now applies DNR status no matter how long the round has been going - on - - tweak: Suicide is now properly admin logged as it is supposed to be. Ghosting - while alive is now also logged. - - bugfix: Sparks and igniters will now actually heat areas rather than cooling them, - as was intended. - - tweak: To alleviate some potential complaints, RPDs now have a cooldown before - they can create sparks, and both RPDs and emitters produce less sparks. - - tweak: Conversion runes will now mute the victim temporarily while they're deciding - whether to convert or be sacrificed. - - bugfix: Conversion runes no longer require a third cultist to sacrifice if the - victim refuses conversion - - bugfix: Staminaloss targeted at the head now properly redirects to the chest. - - tweak: Sprinting no longer takes stam when you're being pulled or when you're - in zero gravity. Other sources of involuntary movement are not affected. - - code_imp: In an attempt to improve performance during highpop, mouse movements - will now only call onmousemove() while a user is in combat mode - - tweak: Ballistic projectiles are now the only projectiles capable of emitting - dinks. - - admin: Panic bunker toggling and bypassing is now logged in admin IRC - - tweak: OOC and LOOC now use separate toggles. You can now use LOOC while OOC is - globally toggled off, and admins now have the option to toggle LOOC off separately - from OOC - - code_imp: also revamped and reorganized relevant looc adminverb code - - bugfix: The endgame narsie summon rune no longer requires 24 total sacrifices, - and will now properly account for cultists that surround it - - tweak: The succumb verb is now available in the IC tab - - tweak: Lighting now uses a linear algorithm to calculate falloff instead of an - inverse-square algorithm. - - code_imp: get_hearers_in_view() now actually caches the results of view() instead - of calling view() twice - - code_imp: Goonchat's JS no longer contains checks related to a completely unused - message filtering function, which should improve clientside performance quite - a bit - - rscadd: The storage hud now properly takes into account the viewer's view size, - meaning storage items with a large amount of storage slots will properly stretch - across the bottom of the screen when running in widescreen. - - rscadd: Action buttons are now able to fill the entire screen in widescreen and - other weird view sizes. - - rscdel: Omegastation's job changes will no longer be included at compile time. - - code_imp: The client update portion of /mob/Login() now double-checks to make - sure client.player_details exists and is of the proper type. This should hopefully - fix the "cannot read null.player_details" runtimes that can spontaneously cause - clients to get kicked out and forced back to the lobby. - - rscadd: You can now quickly use unequipped items on objects by simply click-dragging - the item onto the object with an empty active hand. Doing so will place the - item in your hand, and then use that item on the object. - - code_imp: In an attempt to improve the performance of /mob/Stat(), various time-related - procs now use defines instead of being procs that call procs that call other - procs that call even more procs. - - bugfix: If a living mob has vore initialized but doesnt have voreprefs initialized, - then client login will force voreprefs to load. - - bugfix: 'Hopefully fixed paper crash 2: electric boogaloo' - - refactor: Added unomos, which is basically listmos except gas mixtures only use - one single list for handling their gasses. This is a significant performance - improvement that also offers a mild memory improvement under normal circumstances. - - balance: Locomotion circuits are now restricted to jogging speed - - balance: MMI circuits and pAI circuits both now have 60 complexity, up from their - original 29. - - tweak: Biogenerators now have a sane limit for production - - bugfix: Fixed a fairly huge server crash exploit - - bugfix: Shield blobs no longer become completely invulnerable to all forms of - damage after reaching a """weakened""" state - - tweak: Taken care of what appeared to have been an oversight where shield blobs - don't recover their armor after becoming weakened. - - bugfix: Nerfed concatenators by limiting the amount of characters they're able - to output - - tweak: The timer for stripping an item off of a spaceman is no longer interrupted - by your active held item changing. This means you no longer have to worry about - filling both of your hands when you're stripping items off of someone. - - rscadd: Ported the zulie cloak and blackredgold coat donor items from RP. - - balance: Normal mops now only use 2 stamina to mop a tile, nerfed from their previous - value of 5 stamina per tile mopped. - - balance: Advanced mops now only use 1 stamina to mop turfs, from their former - value of 2 stam. - - tweak: The femur breaker now uses `*scream` instead of forced speech. This means - that the femur breaker will no longer spam deadchat with "AAAAAAAAAHHHHHHHHHH!!" - - tweak: The femur breaker will now guarantee that the victim falls into crit, which - will make it harder to perform torture scenes with it since the victim can just - succumb. - - bugfix: Fixed another runtime in warp whistles. - - bugfix: Spamming forged packets no longer crashes the server. - - bugfix: Things that access job_preferences now explicitly access keys, which means - it no longer attempts to access invalid indices and runtimes as a result. - - balance: The taser's electrode has been reworked. Instead of being a strong knockdown - that deals a heavy amount of stamloss, it now causes a weak knockdown, applies - a debilitating status effect for 5 seconds, and deals 35 stamloss on hit up - to a maximum 50 total stamloss. - - balance: Roundstart turrets now have a nonlethal projectile that gets used when - they're set to stun and the target is resting - - tweak: Hybrid tasers now have disablers set as their default mode. - - rscadd: There is now a 1% chance for the station's announcer to be the medibot - voice instead of the classic TG announcer. - - rscadd: The map config system has been expanded to allow mappers to specify the - map type, announcer voice, ingame year, and how often a given map can be voted - at roundend. - - bugfix: The map vote system now takes into account map playercount limits properly. - - bugfix: Examining a spaceman, and other things that use get_examine_string(), - will now actually properly show when an item is blood-stained. - - bugfix: Plasmaman tongues no longer have a maxHealth of "alien", and no longer - cause the organ's on_life to always runtime. - - bugfix: Shooting a simplemob no longer causes runtimes prior to the blood effect - being created. - - bugfix: Removing a filter from an object that lacks filters no longer causes runtimes. - deathride58 (Original PR by actioninja): - - rscadd: Disarm pushing (combat mode right click in disarm intent) will now actually - push mobs away. Knockdowns from disarm pushing are no longer rng based on the - target's staminaloss. Knockdowns from disarm pushing now only happen when you - push someone into another mob, a table, or a wall. Pushes will now also temporarily - stop targets from using firearms, and will disarm the firearm if performed a - second time. Pushes still deal staminaloss to standing targets, and won't deal - a single ounce of staminaloss to resting targets. - - rscdel: You can no longer displace mobs that are in harm intent by simply walking - into them. Mobs that aren't in help intent have to be disarm pushed to actually - be moved. - dtfe3: - - tweak: Increased music maxlines from 300 to 600 - - tweak: Made it so any oxygen tank can be used instead of only red ones. - - tweak: Watcher wing Trophy's effect lasts 1 second instead of 0.5 - - rscadd: Pink Panties - - rscadd: Twintails - - rscadd: Schoolgirl outfits for the loadout menu! - - tweak: Now the fox ears are located in front of hair meaning they now behave much - like cat ears, that being they are on-top of the hair layer. - izzyinbox: - - rscadd: adds VoG orgasm command using words "orgasm", "cum", "squirt", "climax" - - rscadd: adds VoG dab command using words "dab" and "mood" - - rscadd: Generic dog body marking sprite - - imageadd: colormatrix dog sprites - - tweak: lowered the player age for command jobs to 1/3 of their previous setting - - rscadd: '*bark emote' - jtgsz: - - rscadd: ported gang mode - kappa-sama: - - rscdel: Removed racism - - tweak: Teleporter calibration actually matters to all roundstart players - - balance: Slows down teleportation with the console/hub/teleporter setup if you - care for your species. - - balance: Dedicated non-humans can now get hulk without having to become human. - - bugfix: seed - - tweak: added obj/item/key to wallet whitelist - - tweak: blood cult ritual daggers fit in jack/combat boots - - tweak: voidcells can now unlock alien tech - - balance: rebalanced tech trees (not really) - - rscadd: hugbox (/s) - - tweak: ashwalker spawn text now tells them "i" "c" not to leave lavaland - - bugfix: you can no longer have infinite ebows - - bugfix: kevinz forgot to nerf miasma research and cargo value after making it - produce like 100x as much lmao - kevinz000: - - balance: Hierophant now goes sicko mode, but hey, at least you can't be multi-hit - by melee waves! - - rscadd: Racking shotguns is now more threatening. - - balance: Medibots no longer kill slimes when trying to heal their toxins. - - rscadd: The Syndicate started selling claymores to their agents. - - balance: Nerfed VTEC modules. - - bugfix: Neurotoxin no longer stuns non-carbons. - - rscadd: peacekeeper cyborgs now get a megaphone - - bugfix: Fixes storage bugs regarding reaching into things you shouldn't be able - to reach into. - - code_imp: BYOND 513 preliminary support added. - - balance: 'Trashbags now only allow accessing the first 3 items. 5 for bluespace - ones. experimental: Storage now allows for limiting of random access' - kiwedespars: - - rscadd: regenerative materia to hallucination sting - - rscadd: mindbreaker toxin as an actual chemical to hallucination sting - lolman360: - - rscadd: NT has authorized shipments or Cotton to Megaseed Servitors. It's time - to start picking, liggers. - - imageadd: missing durathread sprites - - rscadd: Added durathread jumpskirt - - imageadd: Duraskirt sprites and rolled down jumpsuit sprites. - - bugfix: Fixes an undocumented change to the naming of Plasmamen. - - tweak: chainsaw kind of weapons and the mecha drill and the CLAMP can now be used - with 100% accuracy for surgery - - refactor: surgery tools now work on defines - - balance: advanced surgerytools can now switch types instead of just being faster - - bugfix: fixes bug with new surgerytools examine - nicc: - - rscadd: Exo-suit - - rscadd: SEVA suit - - rscadd: Flags for Goliath resistance and weakness - - rscadd: suit voucher - - rscadd: temp suit sprites - - rscadd: '*dab' - - balance: teg less gay maybe - ninjanomnom and WhoneedSpacee: - - rscadd: Some rpg affixes now have special effects - - rscadd: 'New RPGLoot modifiers: Vampirism which heals you when you attack, Pyromantic - which sets things you hit on fire. Shrapnel which causes projectiles fired from - a gun to fire projectiles in a radius when they hit something. Finally, Summoning - which summons mobs that sometimes aid you in combat.' - original by @randolfthemeh and @twaticus, port by sishen1542: - - rscadd: jumpskirts - - rscadd: more jumpskirts - - rscadd: jumpskirt/suit prefs - original by Bumtickley00, port by sishen1542: - - tweak: Suit storage units will now also remove radiation from mobs. - original by GuyonBroadway, SkowronX, and Arizon5. port by sishen1542 and kerse: - - rscadd: Clockwork cultists may now summon forth Neovgre, the ratvrarian super - weapon. This powerful mech can be summoned when applications scripture has been - unlocked, boasts superior offensive and defensive capabilities, however once - a pilot enters he cannot leave and is doomed to die with the mech. - - imageadd: Sexy Sprite work courtesy or SkowronX from /tg/ - - imageadd: brass edits by Arizon5 - - soundadd: steamy laser by kerse - original by Skoglol, port by sishen1542: - - balance: Added lots of new virus cures, made cure difficulty scale more consistently. - Cures are now picked from a list of possible cures per resistance level, multiple - diseases at the same level no longer always share a cure. Looking at you table - salt. - - admin: Dynamic gamemode now more auto-deadmin friendly. - original by TheChosenEvilOne, port by sishen1542: - - rscadd: Ported dynamic mode from /vg/, originally made by @DeityLink, @Kurfursten - and @ShiftyRail - original by Tlaltecuhtli, port by sishen1542: - - rscadd: rcd disk that gives rcd computer frame and machine frame designs - - rscadd: upgraded rcd in CE lockers - - tweak: moved deconstruction to the upgrade disk, ashwalker rcd comes upgraded - original by actioninja, port by sishen1542: - - tweak: Medical and Security consoles now check access on worn or inhand ID instead - of requiring an inserted ID - - tweak: mining vendor now reads from ID in hand or on person instead of requiring - an inserted ID - - bugfix: ORM is functional again (for real this time) - - tweak: ORM claim points button transfers points to worn/inhand ID instead of to - an inserted ID, no longer accepts insertions - - tweak: Same for gulag consoles - original by redmoogle, port by sishen1542: - - rscadd: Added support for 3 new gasses; Tritium, Pluoxium, and BZ - 'original by: WJohnston, Antur, Arcane, plapatin, sprites by cogwerks and edited by mrdoombringer. port by sishen1542': - - rscadd: THE GOOSE IS LOOSE - r4d6: - - rscadd: Added decoratives angel wings for Mammalians only - - rscadd: Added blindfolds to the Loadout list - - rscadd: Added Decorative Wings for Humans, Felinids, Slimepersons and Lizardpeoples. - - tweak: Change the SEVA suit & Exo-suit's descriptions - - bugfix: Batteries are now Rad-Proof like the other stock parts - tigercat2000@Paradise: - - bugfix: fixed invalid characters breaking chat output for that message - tinfoil hat wearer: - - rscadd: Added a new alien technology disk to scientist and roboticist uplinks - that allows them to research the heavily-guarded secrets of the Grays. - - tweak: Alientech is now the only Hidden alien research. To compensate for this, - alien_bio and alien_engi have had their research costs doubled and now require - advanced surgery tools and experimental tools respectively to research. Their - export price is also halved. - - balance: roboticists now have brainwashing disks AND alien technology added to - their role-restricted uplink section. alien technology gives them brainwashing - at a much later date, so brainwashing is the much cheaper option for instant - power. makes logical sense because doctors get it as well because they do surgery, - and roboticists can now either choose to brainwash people for less price but - less power or emag borgs for higher prices, limited uses, but higher power. - ursamedium: - - imageadd: Gas icons changed. -2019-12-07: - AffectedArc07: - - code_imp: Fixes a LOT of code edge cases - Anonymous: - - rscadd: Added NEET-- I mean, DAB Suit and Helmet into loadout. Exclusive to Assistants, - for obvious reasons, and don't provide any armor. Goes well with balaclava, - finger-less gloves and jackboots for that true tactic~~f~~ool experience. - - tweak: Renamed loadout name appropriately (ASSU -> DAB) - Arturlang: - - tweak: PDA catridges cant be irradiated anymore. - Bhijn: - - code_imp: Item mousedrop() now provides a return value indicating whether or not - behavior has been overridden somehow. - - bugfix: Defibs now properly check that their loc is the same as the user for mousedrop() - calls, meaning ghosts can no longer make you equip defibs. Plus extra sanity - checks. - - bugfix: Pet carriers no longer attack turfs while trying to unload their contents. - - bugfix: Decks of cards now function as they originally intended when attempting - to use their drag and drop behavior. - - bugfix: Paper bins and papercutters no longer act wonky when you're trying to - pull a piece of paper from them. - - bugfix: Adds clothing drag n drop sanity checks. - - bugfix: Sythetic hats now have extra sanity checks - Coconutwarrior97: - - bugfix: Can only wrench down two transit tubes per turf. - Commandersand: - - rscadd: Added more stuff to loadout,check uniforms mask and backpack - DeltaFire15: - - rscadd: Adds eight new plushies - - imageadd: Adds icons for the new plushies and adds a new icon for the skylar plush - - imagedel: Deleted a old, no-longer used icon for the skylar plush - - spellcheck: Fixed a typo in the trilby plush - Fermis: - - tweak: tweaks botany reagent pHes - - tweak: Purity, Astral, RNG, MK, SMilk, SDGF, furranium, hatmium, eigen, nanite. - - bugfix: Eigen and purity. - - refactor: refactored sleepers! - - rscadd: Organ fridges to all maps near surgery with a random sensible organ, steralizine - and synthtissue. - - tweak: the med hand scanner to be less of a mishmash of random things - - rscadd: a little icon to the HUD if someone's heart has failed. - - tweak: Lets neurine's brain splash attack work via syringe. - - rscadd: a new surgery; Emergency Cardioversion Induction for use on the recently - deceased - - tweak: Synthtissue to be less demanding on growth size for organ regeneration - and improves clarify of it's growth gated effects. - - tweak: Synthtissue now is more useful than synthflesh on the dead - Fox McCloud: - - bugfix: Fixes a very longstanding LINDA bug where turfs adjacent to a hotspot - would be less prone to igniting - Fox McCloud, Ghommie: - - bugfix: Fixes being able to mech-punch other mobs, as a pacifist - - bugfix: Fixes being able to hurt people, as a pacifist, by throwing them into - a wall or other mob, or by using most martial arts (save for the unpredictable - psychotic brawl, and the stamina-damage-only boxing). - - balance: Buffs boxing to outdamage natural stamina regeneration. Made the chance - of outright missing your opponent actually possible. - - tweak: Pacifists can now engage in the (laughably not harmful) sweet sweet art - of boxing now. - Ghommie: - - bugfix: Fixing implant cases being lost inside implant pads when trying to eject - them with your active hand full. - - tweak: Moved the implant pad's case ejection from attack_hand() to AltClick(), - added examination infos about it. - - bugfix: Fixed holodeck sleepers leaving sleeper buffers behind when deleted. - - bugfix: Fixed traitor codewords highlight and some other hear signal hooks spans - highlight (phobias, split personality, hypnosis) or modifiers (mind echo) - - bugfix: Fixed traitor codewords highlight not passing down with the mind datum - and stickying to the first mob. - - spellcheck: Fixed the incongruent bone satchel description. - - bugfix: Fixed sofa overlays doing nothing, because their layer wasn't properly - set. - - tweak: Suicide and cryo now prevents ghost/midround roles for a definite duration - of 30 minutes (and more if that was done before 30 minutes in the game passed), - down from the rest of the round. - - bugfix: fixed several midround roles bypassing and nulling the aforementioned - prevention measures. - - bugfix: Fixed the little issue of PDA skins not updating on job equip. - - tweak: Anomaly Crystals of the clowning type will now rename the victim to their - clown name preference when triggered, instead of giving them a random clown - name. - - balance: Lowered blob event earliest start from 1 hour to 40 minutes (ergo one - third), and the required player population from 40 to 35. - - bugfix: Several fixes and QoL for dullahans. They can see and hear visible and - audible messages now, don't need a space helmet they can't wear anyway to be - space/temperature proof, can examine things through shiftclick, and, most of - all, fixed their head being unpickable. Fixed dullahans gibbing when revived - or had their limbs regenerated. - - bugfix: humans should now drop gibs when gibbed again. - - rscadd: synths (not to be confused with IPCs), android and corporate species, - as well as robotic simple mobs, will now spawn robotic giblets instead of organic - ones. - - bugfix: You can't wear dakimakuras in any other inappropriate slots save for the - back slot anymore, degenerates. - - bugfix: Insert snarky remark about clock welders actually displaying the welder - flame overlay when turned on now here. - - balance: Minor ninja tweaks and stealth nerfs. The stealth penalty for the many - combat-related actions, bumping and now teleporting/dashing or firing guns has - been increased a by a third. There is now a cooldown of 5 seconds on toggling - stealth as well as a slighty slowed stealth in/out animation. - - imageadd: Ported slighty better matchbox sprites from CEV-Eris, also resprited - cigar boxes myself. - - bugfix: Fixed abductors/abductees objectives by porting an objective code. - - bugfix: Riding component fix - - bugfix: fixing a few runtimes on lightgeists, libido trait, rcd, one admin transformation - topic, chem dispensers, glowing robotic eyes... - - imageadd: Porting CEV-eris delivery packages sprites and dunking the old syndie - cybernetics box sprite. - - bugfix: Certain objects shouldn't be able to become radioactive because of a bitflag - that previously was checked nowhere in the code anymore. - - rscadd: Added a new PDA reskin, sprites from CEV-Eris - - rscadd: Clock cult starts with some spare vitality matrix charge scaled of the - number of starter servants. - - balance: Made the vitality matrix sigil slighty more visible, also allowed conversion - runes to heal fresh converts at the cost of some vitality charge. - - bugfix: 'Crawling won''t save you from the wrath of ocular wardens and pressure - sensors anymore, heretics. fix: Pressure sensors are no more triggered by floating/flying - mobs.' - - bugfix: Strawberry milk and tea have sprites now. - - bugfix: Fixed the Aux base camera door settings and toggle window type actions. - Also enabling the user to modify both door access and type. - - imageadd: Improved the two grayscale towel item sprites a little. - - bugfix: Fixed towels onmob suit overlays. Again. - - spellcheck: Fixed some reagents taste descriptions. - - bugfix: Fixed hidden random event reports only priting a paper message without - sending the message to the consoles' message list. - - bugfix: Rosary beads prayer now works on non-carbon mobs too, and won't break - when performed on a monkey or other humanoids. - - tweak: You can flagellate people with rosary beads on harm intent. It's even mediocrer - than the sord though. - - tweak: Moved the `Stealth and Camouflage Items` uplink category next to `Devices - and Tools`. - - bugfix: Deleted a duplicate phatom thief mask entry from the uplink. - - bugfix: Fixed missing delivery packages sprites - - bugfix: fixed a few minor issues with console frames building. - - bugfix: Wizards can use the teleport spell from their den once again. - - tweak: Wizards will now receive feedback messages when attempting to cast teleport - or use the warp whistle while in a no-teleport area. - - rscadd: New clockwork cultist, gondola, monkey and securitron cardboard cutouts. - - bugfix: Fixed aliens gasping randomly once in a while. - - bugfix: fixed superlube waterflower, my bad. - - bugfix: Fixed closing the aux base construction RCD's door access settings window - throwing you out of camera mode when closed. - - rscdel: Removed not functional aux base RCD's door type menu. Use airlock painters, - maybe. - - rscadd: Honkbot oil spills are of the slippery kind now. Honk. - - imageadd: local code scavenger finds forgotten slighty improved apc sprites left - buried in old dusty folders. - - bugfix: Seven old and otherwordly pAI holochassis icons have crawled their way - out of the modular citadel catacombs. - - bugfix: chem dispenser beakers end up in your hand yet again. - - bugfix: Bikehorns squeak yet again, the world is safe. - - bugfix: Cyborgs can now actually use cameras from a distance. - - bugfix: Suicides are yet again painful and instant and won't throw people in deep - crit from full health. - - bugfix: fixed rogue pixels on the energy gu- ahem blaster carbine... and a few - apc lights states being neigh-indistinguishable. - - bugfix: Fixed several "behind" layer tail sprites skipping areas normally covered - by bodyparts. - - bugfix: Morgues' original alert beeping sound has been restored, they no longer - go "ammunition depleted" - - bugfix: Fixed missing hypereutactic left inhand sprites. - - bugfix: Dying, ghosting, having your mind / ckey transferred to another mob, going - softcrit or otherwise unconscious now properly turn off combat mode. - - bugfix: combat mode can't be toggled on while non fully conscious anymore. - - bugfix: Fixed limbs' set_disabled NOT dropping your held items, updating your - hand slot inventory screen image, prompting chat messages and making your character - scream like a sissy. - - bugfix: Lusty xenomoprh maids will now actually clean tiles they travel onto yet - again. - - bugfix: Fixed double whitespace gap in human and AI examine. Fixed single whitespace - in carbon examine. - - rscdel: 'Removed a few useless supply packs: "Siezed" power cells, means of production - and promiscous organs.' - - tweak: Merged the synthetic blood supply pack into the standard blood supply pack, - effectively removing a random type blood pack in favor of two synthetic ones. - - tweak: "Merged together premium carpet pack n\xB01 and n\xB02 to hold one of each\ - \ standard pattern." - - tweak: You can no longer estimate the amount of reagents found inside a damp rag. - - tweak: You can now squeeze a rag's reagents into another open container, as long - as the other one is not full. - - bugfix: Fixed ED-209 being unbuildable past the welding step. - - bugfix: Fixed ai displays status being reset to "Neutral" on login, regardless - of choice. - - bugfix: Fixed tinfoil hats giving random traumas. - Ghommie (original PR by Denton): - - rscadd: Added three new .38 ammo types. TRAC bullets, which embed a tracking implant - inside the target's body. The implant only lasts for five minutes and doesn't - work as a teleport beacon. Hot Shot bullets set targets on fire; Iceblox bullets - drastically lower the target's body temperature. They are available after researching - the Subdermal Implants node (TRAC) or Exotic Ammunition node (Hot Shot/Iceblox). - - tweak: Renamed the Technological Shells research node to Exotic Ammunition. - - code_imp: The "lifespan_postmortem" var now determines how long tracking implants - work after death. - - rscadd: .357 AP speedloaders can now be ordered from syndicate uplinks. - - balance: lowered the cost of uplink's .357 speedloaderd from 4 to 3. - Ghommie (original PR by nicbn and Menshin): - - bugfix: You can click on things that are under flaps or holo barriers. - Ghommie (original PRs by ShizCalev, CRTXBacon and Niknakflak): - - rscadd: Adds the intelliLantern, a big ol' spooky intelliCard skin - - rscadd: crafting recipe for the new intelliCard skin (requires 1 pumpkin, 1 intelliCard, - 5 cables and a wirecutter as a tool) - - tweak: changed the intelliTater crafting recipe to match the intelliLantern recipe - (but with a potato for obvious reasons) add:cute pai gameboy face :3 - Ghommie, porting lot of PRs by MrDoomBringer, AnturK, nemvar and coiax.: - - admin: Admins can now launch supplypods the old, slightly quicker way as well - - bugfix: Centcom-launched supplypods will now properly delimb you (if they are - designated to do so) instead of touching you then literally yeeting all of your - internal organs out of your body. - - admin: Centcom can now specify if they want to yeet all of your organs out of - your body with a supplypod - - soundadd: Supplypods sound a bit nicer as the land now. - - admin: admins can now adjust the animation duration for centcom-launched supplypods - - admin: admins can adjust any sounds that are played as the supplypod lands - - bugfix: Reverse-Supplypods (the admin-launched ones) no longer stay behind after - rising up, and also auto-delete from centcom. - - admin: The centcom podlauncher now has better logging - - tweak: Admins can now allow ghosts to follow the delivery of Centcom-launched - supply pods - - admin: Admins can now use the Centcom Podlauncher to launch things without the - things looking like they're being sent inside a pod. - - admin: sparks will not generate if the quietLanding effect is on, for the centcom - podlauncher - - admin: makes input text clearer for the centcom podlauncher - - admin: New 'Podspawn' verb, which functions like 'Spawn', except any atoms movable - spawned will be dropped in via a no-damage, no-explosion Centcom supply pod. - - bugfix: Removed an oversight that made many obj/effect subtypes accidentally bombproof. - GrayRachnid: - - rscadd: Added saboteur syndicate engiborg - - tweak: changed cyborg tool icons and the secborg taser/laser icons. - - bugfix: Fixes golden toolbox missing inhand sprite - - rscadd: Added traumas - - rscadd: Added science powergame tool - - tweak: a few hearing args - - bugfix: fixed my mistakes - - tweak: tweaked the number of ingredients/pancakes you can stack. - Hatterhat: - - tweak: The Big Red Button now sets bomb timers to 2 seconds, instead of 5. - - tweak: Gloves of the North Star (not Hugs of the North Star) now use all their - intents very, very fast. This does not apply to grabs' click cooldown, nor shoving - people. - - rscadd: The seedvault/alien plant DNA manipulator can now be printed off with - Alien Biotechnology. - Iroquois-Pliskin: - - rscdel: Removed Clockwork Cult Surgical facility from Reebe - Jerry Derpington, baldest of the balds, and nemvar.: - - rscdel: Nanotrasen has lost communication to two away mission sites that contained - a beach for Nanotrasen employees. - - rscadd: Nanotrasen has been able to locate a new away mission site that ALSO has - a beach. Nanotrasen employees will be able to enjoy the beach after all! - - rscadd: Seashells have been added to the game. - KathrinBailey: - - rscadd: Two extra 'luxury' dorms rooms! - - rscadd: Gas miners to atmos. - - rscadd: Posters around the station. - - rscadd: Vacant room added to the Starboard Bow with it's own APC, above electrical - maintenance. - - rscadd: New trendy clothes to the locker room, giving variety and bringing fashion - back onto Nanotrasen stations. - - rscadd: Coloured bedsheet and towel bin. - - rscadd: Maid uniforms for the janitor. - - tweak: Completely reworked bar. Milk kegs added in bar office. The bar has been - changed for a homey restaurant feel just in time for Christmas! You can now - run it as an actual restaurant! Local Bartender Icktsie III loved it so much - he rolled around on the new floor smiling happily. - - tweak: Dorms rework. Fitness room now has lots of costumes and outfits. - - tweak: Junk removed from engineering, welding goggles added. - - tweak: Welding tools in engineering replaced with industrial welding tools. - - tweak: Package wrappers and hand labellers now in major departments. - - tweak: Cell charger moved from engineering lobby to the protolathe room, just - like how it is in all of the other maps and just where the cell charger is actually - needed. - - tweak: Library redesigned to have a private room and a 3x3 private study that - is cleaned up. - - tweak: Paper bins have gone big or gone home, with premium stationery scattered - around. Engineering and security now have a labeller and packaging supplies. - - bugfix: Dark spot top left of Botany fixed. - - bugfix: Huge galactic-sized dark spot in bar fixed. - - bugfix: Light replacers now are less horrifically overpowered and PTSD-inducing - for the server. - - bugfix: 'Fixes issue 9706: https://github.com/Citadel-Station-13/Citadel-Station-13/issues/9706 - Part of maint getting hit by radstorms. - - _Kathrin''s Box Beautification:_' - - rscadd: Ports TG's pews https://github.com/tgstation/tgstation/pull/42712 - - rscadd: The first step of a corporate incursion of Space IKEA into Nanotrasen. - Kevinz000, Cruix, MrStonedOne, Denton, Kmc2000, Anturk, MrDoomBringer, Dennok, TheChosenEvilOne, Ghommie: - - rscadd: Added support for Multi-Z power, atmospherics and disposals - - bugfix: 'massive service department nerf: space can no longer be extra crispy.' - Knouli: - - rscadd: attack_self proc for the legion core which triggers a self-heal al la - the previous 'afterattack' proc, as if clicking on the character's own sprite - to self-heal - - rscadd: admin logging for all three use cases of legion core healing - afterattack, - attack_self, and implanted ui_action_click - Krysonism, Ghommie: - - rscadd: NT has made breakthroughs in ice cream science, ice creams can now be - flavoured with any reagent! - - tweak: The ice cream vat now accepts beakers. - - bugfix: Grape and Peach icecreams have scoop overlays yet again. - Linzolle: - - code_imp: butchering component update - - tweak: hat tossing can no longer knock hats off - - bugfix: strange reagent being unable to revive simplemobs - - rscadd: jitter animation and more clear text to strange reagent revival - Mickyy5: - - rscadd: Nanotrasen are now issuing Plasmamen with plasma in their survival boxes - MrJWhit: - - tweak: tweaked brain damage line - Naksu, ShizCalev: - - refactor: Refactored examine-code - - bugfix: Examining a human with a burned prosthetic limb will no longer tell you - that the limb is blistered. - - tweak: Items will now inform you if they are resistant to frost, fire, acid, and - lava when examined. - Owai-Seek: - - rscadd: '"silly" bounties' - - rscadd: '"gardenchef" bounties' - - rscdel: several bounties that require seriously good RNG to pull off. - - tweak: moved several chef and assistant bounties to silly and gardenchef - - balance: modified several bounty point rewards - - server: added new files "silly.dm" and "gardenchef.dm" - - rscadd: 15+ new crates for cargo - - tweak: organizes crates and moving them to proper categories - - rscdel: some dumb stuff like toner crates re - - rscadd: leg wraps and sweaters to clothesmate - - rscadd: screwdriver and cable coil to janidrobe - - rscadd: screwdriver and cable coil to janibelt whitelist (for fixing/placing light - fixtures) - - rscadd: monkey cube, syringe, enzyme, soy sauce, and cryoxadone to chef's vendor - (contraband and premium) - - rscadd: add cracker, beans, honey bars, lollipops, chocolate coin, and spider - lollipop to snack vendors (contraband and premium) - - rscadd: newspaper to loadout menu for bapping purposes - - rscdel: removed poppy pretzels from snack vendor premium - - rscadd: maid uniform (janimaid alt) to kinkmate. - - tweak: moves gear harness from premium to normal stock in kinkmate - - balance: re-balanced metal shield bounty - - rscadd: cryoxadone bottle (for use in chef vendor) - PersianXerxes: - - tweak: Reduces the grace period for meteors from a minimum of 5 and maximum of - 10 to 3 and 6 minutes respectively. - - rscadd: Adds a pair of VR sleepers to Box Station's permabrig - - rscadd: Adds a pair of VR sleepers to Delta Station's permabrig - - rscadd: Adds a pair of VR sleepers to Pubby Station's permabrig - - rscadd: Adds a pair of VR sleepers to Meta Station's permabrig - Putnam: - - bugfix: From-ghosts dynamic rulesets now actually listen to "required candidates" - - bugfix: Every dynamic-triggered event is now blacklisted from being triggered - by the random events system when dynamic can trigger them. - - rscadd: Dynamic voting now features extended, if recent rounds have been chaotic. - - tweak: Roundstart rulesets now scale on population ready rather than total population. - - bugfix: Threat log now accurately represents what actually used the threat. - - tweak: Verbose threat log (admin-only) now shows ALL threat level changes. - - bugfix: VR mobs can no longer be dynamic midround antags. - - bugfix: Personal closets can use anything that holds an ID card now. - Putnam3145: - - bugfix: traitors work now - - balance: Gas filters now push gas the same way volume pumps do. - - balance: Gas filters now won't clog if only one output is clogged. - - tweak: Glowsticks can no longer be radioactively contaminated (one more supermatter - contam exploit gone) - - bugfix: traitor removal is no longer borked - - rscadd: Dynamic voting - - config: Added DYNAMIC_VOTING to game_options - - tweak: SDGF now copies memories as well as antag data and factions. - - bugfix: Summon events now properly costs threat. - - bugfix: Refunded spells refund threat, too. - - refactor: Made wizard spells inherently have a requirement and cost. - - tweak: Meteor wave is no longer repeatable in dynamic. - - tweak: tweaked nuke ops - - bugfix: Organs can no longer be radioactively contaminated. - Robustin, Subject217: - - balance: The NukeOp Shuttle hull has been dramatically hardened. The walls are - now "R-Walls" with far greater explosion resistance. - - balance: The NukeOp Shuttle guns have been significantly buffed. They now rapidly - fire a new type of penetrator round, at a greater range, and have far greater - explosion resistance. - - balance: The nuclear device on the NukeOp Shuttle is now in an anchored state - by default, the Nuke can only be unanchored by inserting the disk and entering - the proper code. - - balance: Non-Syndicate cyborgs are now unable to access the NukeOp Shuttle Console. - - bugfix: You can now unanchor Nukes even when the floor under them has been destroyed - Seris02: - - rscadd: added sleeping carp hallucination - - rscadd: Centcom + Assistant's formal winter coat + loadout + narsian + ratvarian - winter coats - - rscadd: GPS location on examine - - bugfix: fixed the meteor hallucination - - tweak: tweaked the way the tapered penis looks - - rscadd: Added nine winter coats - - imageadd: added images for the winter coats - - tweak: adds the mining winter coat to mining wardrobes and mining lockers - ShizCalev: - - tweak: Ghosts can now see active AI cameras. - - bugfix: Fixed a couple of laser / energy guns never switching to the empty icon - despite being unable to fire. - Swindly: - - bugfix: Fixed MMIs not being able to use mecha equipment - - bugfix: Fixed MMIs not getting mecha mouse pointers - - bugfix: Fixed MMIs not getting medical HUDs in Odysseuses - - tweak: Brains can now switch to harm intent - Tetr4: - - bugfix: Turning a tile with gas effects into space now gets rid of the effects. - Trilbyspaceclone: - - rscadd: plastic trash cart crafting with plastic - - rscadd: wallets are known for now holding more items - - tweak: shades and clowns HP - - rscadd: six more crates, A barrel, A Loom, 40 cotton sheets, two sets of fruit - crates, raw lumber crate - - rscadd: All fermi chems, Boozes, Medical, food chems now sell - - rscadd: Loads more to sell - Mech gear, Cooking and more! - - tweak: Moved around the vaule of some things and removed elastic of most items - - balance: Rebreather implants will now loss vaule, Do to being just metal and glass - - balance: lowered how many chems are in lewd chem kegs to be around 150-100 as - well as the fancy booze kegs - - bugfix: bad returns and tools used - - rscadd: 8 new cargo crates! - - tweak: tablet cargo crate by -3k - - admin: Closes a bunch of issues - - server: updates changlogs and such - - bugfix: fixed a catnip not having sprites - - balance: Boh cant hold WEIGHT_CLASS_GIGANTIC, just Bulky. Makes katana, chainsaw - and base ball bat into bulky items so they may fit - - server: changes header to be more cit-like - - rscadd: new clothing for the hotel staff and a hat - Ty-the-Smonk: - - bugfix: You can now interact with self sustaining crossbreeds - Useroth: - - rscadd: Colored fairygrass variants. - - bugfix: Added a missing cherrybulb seedpack sprite - - bugfix: numbered storages now are sorted in a consistent way, instead of depending - on ordering of their contents var - - rscadd: strange seeds as a buyable traitor botanist item - - bugfix: resolves the issues revolving around blackpowder exploding where the reaction - happened, instead of where it actually is through making it explode instantly - - tweak: the explosion delay moved from blackpowder directly into bomb cherries, - to keep them functioning as intended - - rscadd: A bunch of newer tg plants - - rscadd: A bunch of newer tg plant traits - - rscadd: A couple of newer tg plant reagents - - bugfix: the new plants now properly get their reagents and reagent genes instead - of being empty with UNKNOWN reagents listed in the DNA machine - - rscadd: extradimensional oranges now contain haloperidol - - bugfix: extradimensional oranges now actually grow properly and give proper seeds. - Weblure: - - rscadd: Button added to slime console that prints out the hotkey commands to the - user. [Includes DMI update] - - rscadd: Shift-click a slime to pick it up, or the floor to drop all held slimes. - (Requires Basic Slime Console upgrade) - - rscadd: Ctrl-click a slime to scan it. - - rscadd: Alt-click a slime to feed it a potion. (Requires Advanced Slime Console - upgrade) - - rscadd: Ctrl-click on a dead monkey to recycle it, or the floor to place a new - monkey. (Requires Monkey Console upgrade) - - rscadd: If the console does not have the required upgrade, an error message will - print to the user. - - rscadd: You can now pick up a single slime from a pile, instead of all of them - at once. - - tweak: When recycling monkeys, the console will now report how many monkeys it - has (will not report decimal increases). - - tweak: Console now alerts you when you're out of monkeys and reports your current - decimal amount. - - tweak: Console messages are now styled consistently. - XDTM, ShizCalev, Naksu, Skoglol, cacogen, Rohesie (ported by Ghommie): - - tweak: Holding an ID in your hands uses it instead of your worn ID for authentication - purposes. - - tweak: If you don't have an ID in your id slot, the belt slot will be checked - as well. - - code_imp: small cleanup to id and bounty console html generation - - tweak: Hop console now hurts your eyes less. Red button text replaced with green. - - tweak: IDs with ID console access now go into the Confirm Identity slot by default - like they used to, similarly IDs without it go into the Target slot by default - again - - rscadd: Can easily swap out IDs by clicking the machine or the UI fields with - another ID - - rscadd: ID console now names which IDs are added/removed in its visible messages - - rscadd: Labels the ID slot fields when logged in so you know which is which - - tweak: Can use Job Management without an ID provided the console is logged in - (matches how the console now stays logged in even without an ID) - - tweak: Can log in without an ID in the Target field (matches how the machine now - stays logged in even after the ID is removed from the Target field) - - tweak: Cleans up UI slightly (had some duplicate/conflicting buttons) - - bugfix: Fixes ID console duping issues. Includes some ID containers, such as PDAs, - tablets and wallets, into the swapping behavior when an ID card is being removed - and the item is being held. - Xantholne: - - rscadd: New Berets for most heads and departments available in their autodrobes - or lockers - YakumoChen: - - imageadd: New AI Holograms and Displays! Ported from /vg/station. - actioninja: - - bugfix: med records no longer can eat id cards for no reason - - bugfix: Chat is properly sent to legacy window if goonchat fails to load again. - dapnee: - - bugfix: fixed closet initialisation being broken - - rscdel: emergency closets no longer have a 1% chance to delete themselves - - bugfix: Communications console window no longer updates, won't steal focus anymore. - - bugfix: Trimline neutral end exists now. - dzahlus: - - soundadd: added a new gun sounds - - sounddel: removed an old gun sounds - him: - - bugfix: hos and aeg guns now conform to le epic taser rework standards - kappa-sama: - - tweak: changed flavor text of alien tech on uplink - - imageadd: added TG's icons for traitor, russian, and golden revolver - kevinz000: - - rscadd: you can now choose never for this round for magical antags - - rscadd: Cargo has passive point generation again at 750 points/minute - - balance: Mindshield crate price increased from 3000 to 4000 - - balance: Miasma sell price reduced from 15/mol to 4/mol - - balance: bluespace wizard apprentice now has blink instead of targeted area teleportation - - balance: Emagged medibots now charcoal toxinlovers. - - balance: disablers buffed 0.7 --> 0.6 speed 24 --> 28 damage - - balance: kinetic crushers no longer drop if you try to use it with one hand - - config: added multi_keyed_list, delimiter defaults to |. - - balance: Light pink extracts no longer speed you up. Instead, they give stamina - regeneration and free sprinting. - kiwedespars: - - rscdel: removed moth fluff coloring you like your wings - - balance: made insect not so bad. - nemvar: - - bugfix: You now get a message if your PDA explodes while you are holding it. - - tweak: The lavaland clown ruin has some new pranks ready. - - rscadd: Added a new loot item to the lavaland clown ruin. - - rscdel: Removed the slime core from said ruin. - - balance: The clown PDA now properly slips people on jogging move intent regardless - of fatigue. Honkmother's will. - nemvar, ShizCalev, Qustinnus/Floyd, Ghommie: - - rscadd: You can now unfasten the loom. - - tweak: it now takes 4 strands to make one piece of durathread cloth - - bugfix: Looms can now be attacked. - - rscadd: Durathread golem weaves his magic - - tweak: Supply ordered looms are unanchored. Bring a wrench. - r4d6: - - rscadd: Added Departements Winter Coats to the loadout list. -2019-12-30: - AnturK: - - bugfix: Fixed ranged syndicate mobs stormtrooper training. - Arturlang: - - rscadd: Adds Bloodsuckers, beware. - BlueWildrose: - - bugfix: Fixed stargazers being unable to link to themselves if mindshielded or - if holding psionic shielding devices (tinfoil hats) when the species is set. - - bugfix: Fixes non-roundstart slimes being unable to wag their tail. - Commandersand: - - tweak: added two words to clown filter - - rscadd: Added new things to loadouts, check em - DeltaFire15: - - balance: Clock cult kindle no longer cares about oxygen damage - - tweak: changed mecha internals access for some special mechs. - - tweak: no more mech maintenance access for engineers. - - tweak: All heads of staff can now message CC - - code_imp: Removes a magicnumber - - balance: Rebalanced cult vs cult stun effects to debuff instead of stun - Detective-Google: - - bugfix: short hair 80's is no longer jank - Fermis: - - tweak: tweaked how super bases/acids work but limiting them - Fikou: - - tweak: the windup toolbox now has some more "realistic" sounds - - bugfix: the windup toolbox now rumbles again - Ghommie: - - bugfix: Fixed hulks, sleeping carp users, pacifists and people with chunky fingers - being able to unrestrictly use gun and pneumatic cannon circuit assemblies. - - bugfix: Fixed gun circuit assemblies being only usable by human mobs. - - balance: Doubled the locomotion circuit external cooldown, thus halving the movable - assemblies' movespeed. - - tweak: Made wooden cabinet/closets... actually made of wood. - - tweak: Wooden cabinets are now deconstructable with a screwdriver. - - tweak: Deconstruction of large crates and other closet subtypes deconstructable - with tools other than the welder is no longer instant. - - tweak: You shouldn't be able to target objects you can't see (excluding darkness) - with the ARCD and RLD - - tweak: The admin RCD is ranged too, just like the ARCD. - - bugfix: Fixed welding, thirteen loko, welding and wraith spectacles not blinding - people as expected. Thank you all whomst reported this issue in the suggestions - box channel instead of the github repository's issues section, very smart! - - bugfix: Fixed on_mob eyes overlays not updating properly in certain cases. - - bugfix: Fixed deconversion from bloodshot eyes blood cult resetting your eyes' - color to pitch black instead of their previous color, more or less. - - balance: 'Spinfusor nerf: Upped the casing and ammo box size by one step, removed - the projectile''s dismemberment value (explosions can still rip a limb or two - off), halved the ammo box capacity, reduced the spinfusor ammo supply pack contents - from 32 to 8, removed the casing''s ability to explode when thrown.' - - bugfix: Fixes bubblegum's death not unlocking the arena shuttle buyment. - - bugfix: Fixed alien tech node not being unlockable with subtypes of the accepted - items. - - bugfix: Fixed reactive armor onmob overlays not updating when toggled and reactive - teleport armor still using forceMove() instead of do_teleport() - - bugfix: Fixed space hermit asteroid rocks unintendedly spawning airless asteroid - turf when mined, save for the perimeter. - - bugfix: Fixes reviver implant having been a crapshot ever since soft-crit was - introduced years ago. - - tweak: Added a "convalescence" time (about 15 seconds) after the user is out of - unconsciousbess/crit to ensure they are properly stabilized. - - tweak: Added a 15 minutes hardcap for accumulated revive cooldown (equivalent - to 150 points of brute or burn healed) above which the implant starts cooling - down regardless of user's conditions. - - bugfix: Fixed AI core displays I may have broken with my coding extravaganza. - - soundadd: Blue, Amber and Red security alert sounds should be half as loud now. - - balance: Buffed clown ops by removing their clumsiness and adding a new trait - to be used in place of several clown role checks. - - tweak: Clown ops too also suffer from not holding or wearing clown shoes now. - - bugfix: Fixed a few holo barriers lacking transparency. - - bugfix: Fixed character setup preview bodyparts not displaying correctly most - of times. - - bugfix: Fixed character appearance preview displaying the mannequin in job attire - instead of undergarments. - - bugfix: Fixed raven's shuttle computer not being of the emergency shuttle type. - - tweak: Blood bank generators can now be anchored and unanchored now. - - admin: Ghost mentors can now orbit around the target instead of setting their - view to theirs'. - - bugfix: Fixes a ghostchat eavesdropping exploit concerning VR. - - bugfix: Fixes VR deaths being broadcasted in deadchat. - - bugfix: Fixed a few pill bottle issues with the ChemMaster. - - bugfix: Fixes a few negative quirks not being properly removed when deleted. - - tweak: Phobia and mute quirks are no longer cheesed by brain surgery grade healing - or medicines. - - bugfix: Fixed double-flavour (and bland custom) ice creams. - - bugfix: Fixed Pubbystation's wall Nanomeds being inconsistent with other stations'. - - bugfix: dextrous simplemobs can now swap action intent with 1, 2, 3, 4 now. Just - like humies, ayys and monkys. - - bugfix: Stops humanoids whose skin_tone variable is set to "albino" from showing - up as pale when examined should their species not use skintones anyway. - - rscdel: Removed the old (almost) unused roboticist encryption key and headset. - - bugfix: Fixed goose meat. - - bugfix: Fixed a little door assembly glass dupe exploit - - bugfix: Fixed AI holopad speech text being small and whispers that in multiple - exclamation marks echo through multiple areas. - - rscdel: Removed literally atrocious polka dotted accessories. They were even more - atrocious than the yellow horrible tie. - Ghommie (also porting PRs by AnturK and Arkatos): - - bugfix: Fixed light eaters not burning out borg lamplights and flashes. fix Fixed - light eater not affecting open turfs emitting lights such as light tiles and - fairy grass. - - bugfix: Fixed an empty reference about light eater armblade disintegration after - Heart of Darkness removal. - Ghommie, Skogol: - - refactor: refactored altclick interaction to allow alt-click interactable objects - to parent call without forcing the turf contents stat menu open. - - tweak: Alt clicking will no longer show turf contents for items inside bags etc. - - tweak: Alt clicking the source of your turf contents stat menu will now close - said menu. - GrayRachnid: - - bugfix: fixes consistency - Hatterhat: - - rscadd: Regenerative nanites, a "chemical" used in the combat stimulant injector. - Actually quite stimulating, and not bad in a pinch for a nuclear operative. - Check the Combat Medic Kit! - - tweak: The Combat Medic Kit now has an advanced health analyzer and medisprays - instead of patches and a chloral syringe. - - balance: The Advanced Syndicate Surgery Duffelbag or whatever it was doesn't get - the better injector, because nobody uses it and so nobody's bothered to update - it. - - rscadd: .357 speedloaders can now be printed with the Advanced Illegal Ballistics - node on the tech tree! - - balance: okay so i may have given the .357 an extra speedloader at the same cost - but it comes in a box now - ItzGabby: - - bugfix: Fixed AltClick on polychromic collars so they actually work now. - KeRSedChaplain: - - soundadd: Extends the file "deltakalaxon.ogg" to a 38 second .ogg. - Linzolle: - - rscadd: neck slice. harm intent someone's head while they are unconscious or in - a neck grab to make them bleed uncontrollably. - - bugfix: officer's sabre now properly makes the unsheating and resheating noise - - bugfix: fireman failure has a different message depending on the circumstance - - rscadd: Abductor chem dispenser, and added it to the abductor console. - - rscadd: '"Superlingual matrix" to the abductor console. It''s the abductor''s - tongue. Can be used to link it to your abductor communication channel and then - implanted into a test subject.' - - rscadd: Shrink ray and added it to the abductor console. - - soundadd: Shrink ray sound effect (its the fucking mega man death sound) - - rscadd: special jumpsuit for abductors - - imageadd: abductor jumpsuit, including digi version if a digitigrade person somehow - manages to get their hands on it. sprites for the shrink ray and chem dispenser. - - rscadd: new glands to play with, including the all-access gland, the quantum gland, - and the blood type randomiser. - - code_imp: split every gland into its own file instead of all being in one file - - tweak: cosmic coat crafting recipe changed to coat + cosmic bedsheet - Mickyan, nemvar, RaveRadbury, AnturK, SpaceManiac: - - bugfix: Certain incompatible quirks can no longer be taken together. - - bugfix: If an admin sends a ghost back to the lobby, they can now choose a different - set of quirks. - - spellcheck: the quirk menu went through some minor formatting changes. - - bugfix: Podcloning now lets you keep your quirks. - - rscadd: Quirks have flavor text in medical records. - - spellcheck: All quirk medical records refer to "Patient", removing a few instances - of "Subject". - - tweak: Quirks no longer apply to off-station roundstart antagonists. - - code_imp: Mood quirks are now only processed by the quirk holders - Narcissisko (ported by Hatterhat): - - rscadd: Luxury Bar Capsule, at 10,000 points. Comes with no medical supplies, - a bar, and a bunch of cigars. Ported from tgstation/tgstation#45547. - Nervere and subject217, Militaires, py01, nemvar: - - balance: The cook's CQC now only works when in the kitchen or the kitchen backroom. - - spellcheck: corrected CQC help instructions - - bugfix: CQC and Sleeping Carp are properly logged. - - tweak: CQC can passively grab targets when not on grab intent. Passive grabs do - not count towards combos for CQC or Sleeping carp. - - code_imp: Martial Art and NOGUN cleanup. - PersianXerxes: - - rscdel: Removed night vision quirk - Putnam: - - bugfix: acute hepatic pharmacokinesis now works if you already have relevant genitals - - balance: Contamination is no longer an infinitely spreading deadly contagion causing - mass panic - - tweak: Dynamic rulesets have lower weight if a round recently featured them (except - traitor). - Putnam3145: - - balance: Buffed HE pipes by making them realistically radiate away heat. - - bugfix: Dynamic has a (totally unused for any relevant purpose) roundstart report - now. - - admin: A whole bunch of dynamic data is now available for statbus - - bugfix: Dynamic from-ghost antags no longer double dip on threat refunds when - the mode fails due to not enough applications. - - bugfix: whoops broke quirks - - bugfix: quirks work - - rscadd: 'New tab in preferences screen: "ERP preferences"' - - rscadd: New opt-outs for individual effects of incubus draught, succubus milk - - rscdel: Acute hepatic pharmacokinesis has been removed, replaced with above - - tweak: Renamed "Toggle Lewdchem" to "Toggle Lewd MKUltra", since that's what it - actually means, and made it toggle the "hypno" setting (rename it again if more - hypno mechanics are added). - - tweak: Made MKUltra's lewd messages require both people involved to have hypno - opted-in. - - config: Buncha dynamic config tweaks - - bugfix: Ghost cafe spawns are actual ghost roles by the game's reckoning now - - bugfix: a runtime in radioactive contamination - - balance: Bomb armor now acts like other armor types. - - balance: Devastation-level explosions on armorless people no longer destroys everything - in their bags. - Seris02: - - rscadd: the clowns headset - - bugfix: distance checks - - bugfix: the sprites - - rscadd: added the runed and brass winter coats (cosmetic ratvarian/narsian) - - tweak: how the narsian/ratvarian coats can be made - - bugfix: fixes some ghost roles from dying of stupid shit - - bugfix: pandoras attacking their owners - - rscadd: Added Rising Bass and the shifting scroll. - - tweak: Changes the martial arts scroll in the uplink to "Sleeping Carp Scroll" - ShizCalev: - - bugfix: Fixed floodlights not turning off properly when they're underpowered. - - bugfix: Fixed emitters not changing icons properly when they're underpowered. - Sishen1542: - - rscadd: Clicking a pack of seeds with a pen allows you to set the plant's name, - description and the pack of seeds' description. Useful for differentiating genetically - modified plants. These changes will persist through different generations of - the plant. - - rscadd: Hydroponics trays update their name and description to reflect the plant - inside them. They revert to default when emptied. - Toriate: - - rscadd: Polychromic shorts now have a digitigrade state - Trilbyspaceclone: - - rscadd: ports all the new donuts, burgars, and chicken stuff from RG - - rscadd: ports new snowcone - - rscadd: ports grill - - rscadd: ports beakfeast tag/mood lit as TG has it - - rscadd: ports all the amazing new sprites - - tweak: ports crafting for many things like snowcones needing water - - balance: ports of many craftings - - soundadd: lowers fryers sound - - imageadd: ported icons for new food/grill - - imagedel: ports the deletion of some icons and images - - spellcheck: ports a spell check for the snowcones - - code_imp: ports fixes for stuff I didnt know were even broken with snowcones - - bugfix: coder cat failers to push the last commit from year(s) ago - - admin: Updates the changlogs - - tweak: meat hook from HUGE to bulky - - tweak: CE hardsuit is now more rad-proof - - bugfix: Wrong icon names, missing dog fashion with telegram hat - - rscadd: New softdrink that comes in its own vender! - - rscadd: Honey now has a reaction with plants - - tweak: Buzz fuzz now only has a 5% to give honey and will now give 1u of sugar - not 2 - - rscadd: Blaster shotguns back into armory - - rscdel: Removed Lighters in thunderdomes - - rscadd: Silicons now know what a slime is saying! - - balance: honey now will not kill slimes. Honey slimepeople can be a thing now, - go sci. - - rscadd: Added insulin into many of the borg hypo's - Useroth: - - rscadd: bamboo which can be used to build punji sticks/ blowguns available as - a sugarcane mutation or in exotic seed crate - - tweak: changed the sugar cane growth stages because fuck if I know why, but it - was in the PR - - rscadd: 'New lavaland ruin: Pulsating tumor' - - rscadd: New class of lavaland mobs, a bit weaker than megafauna but still stronger - than most of what you normally see - - rscadd: Ghost cafe spawner. For letting people spawn as their own character in - the ninja holding facility. It bypasses the usual check, so people who have - suicided/ghosted/cryod may use it. - - rscadd: Dorms in the ninja holding facility. - Xantholne: - - rscadd: Santa Hats to Loadout and Clothesmate - - rscadd: Christmas Wintercoats to Loadout and Clothesmate - - rscadd: Christmas male and female uniforms to loadout and Clothesmate - - rscadd: Red, Green, and Traditional Santa boots to loadout and Clothesmate - - rscadd: Christmas Socks, Red candycane socks, Green candycane socks to sock selection - kappa-sama: - - balance: legion drops more crates now - - balance: .357 speedloaders in autolathes are now individual bullets instead, speedloaders - are now illegal tech, costs less total metal to make 7 bullets than a previous - speedloader. 7.62mm bullets in autolathe when hacked and costs more metal to - make 5 7.62mm bullets than getting a clip from the seclathe. - - tweak: mentions that you can refill speedloaders on .357 uplink description - - bugfix: you can now strip people while aggrograbbing or higher - - rscadd: plasmafist to wizard - - code_imp: modular is gone - - rscadd: martial apprentices for the local Chinese wizard - - bugfix: broodmother baby lag - - balance: you can no longer get 100k credits by spending 4k roundstart - - balance: cooking oil in sunflowers instead of corn oil - - bugfix: throats are no longer slit happy - keronshb: - - rscadd: Adds reflector blobs to shield blob upgrades - kevinz000: - - rscadd: Launchpads can now take number inputs for offsets rather than just buttons. - - balance: nanites no longer spread through air blocking objects - - rscadd: Night vision readded as a darkness dampening effect rather than darksight. - - rscdel: conveyors can only stack items on tiles to 150 now. - - rscadd: added 8 character save slots - - rscadd: Cargo shuttle now silently ignores slaughter demons/revenants instead - of being blocked even while they are jaunted. A drawback is that manifested - ones can't block it either, any more. - - balance: flashbangs process light/sound separately and uses viewers(), so xray - users beware. - - tweak: Stat() slowed down for anti-lag measures. - - bugfix: sprint/stamina huds now work again - - balance: Combat defibs now instant stun on disarm rather than 1 second again - - balance: Defibs are now always emagged when emagged with an emag rather than EMP. - - bugfix: aooc toggling now only broadcasts to antagonists - - code_imp: Antag rep proc is now easier to read and supports returning a list. - - balance: Clockwork marauders are now on a configured summon cooldown if being - summoned on station. They also rapidly bleed health while in or next to space. - And they glow brighter. - lolman360: - - rscadd: Added ability to pick up certain simplemobs. - nemvar: - - bugfix: The brains of roundstart borgs no longer decay. - - code_imp: Refactored the visibility of reagents for mobs. - nicbn, Kevinz000, ShizCalev: - - tweak: Fire alarm is now simpler. Touch it to activate, touch it to deactivate. - When activated, it will blink inconsistently if it is emagged. - - bugfix: You can no longer spam fire alarms. Also, they're logged again. - - bugfix: Fixed fire alarms not updating icons properly after being emagged and - hacked by Malf AI's. - r4d6: - - rscadd: Added a N2O pressure tank - - rscdel: Removed a AM Shielding from the crate - - rscadd: Added Handshakes - - rscadd: Added Nose booping - - rscadd: Added submaps for the SM, Tesla and Singulo - - rscadd: Added a placeholder on Boxstation for the Engines - - bugfix: fixed Nose boops not triggering - shellspeed1: - - rscadd: Adds Insect markings - - rscadd: Adds three new moth wings. -2020-01-27: - 4dplanner, CRITAWAKETS, XDTM, ninjanomnom: - - rscadd: sepia slime extract has a delay before activating - - balance: the user of a sepia slime extract is no longer immune to the time field - - balance: chilling sepia is now the support extract - it always freezes the user, - but not other marked people. give one to your golem! - - rscadd: burning sepia spawns the rewind camera. Take a selfie with someone and - give it to them to make sure they remember the moment forever! You don't actually - need to give them the photo, they'll remember anyway. Keep it as a reminder. - - rscadd: rewinding (deja vu) effect resets your location to the turf you were on - after 10 seconds as well as resetting limbs/mobs/objects damage to the point - it was added. - - rscadd: The deja vu effect cannot resurrect the dead, but will heal their corpse. - New limbs fall off, old ones re-attach - - rscadd: 'Regenerative sepia cores add a deja vu effect before healing instead - of a timestop remove: timefreeze camera is admin spawn only.' - - rscadd: recurring sepia recalls to the hand of the last person to touch it after - activating. Reusable timestop grenades! - - tweak: some special cameras don't prompt for customisation - - bugfix: timefreeze camera actually makes a photo - - bugfix: timestop stops pathing and mechs. - - bugfix: adds a check to make sure simple_animals don't get their AI toggled while - sentient - - bugfix: Adds the timestop overlay to frozen projectiles - - bugfix: Timestopped things have INFINITY move_resist as opposed to being anchored - - bugfix: Timestop will now unfreeze things that somehow leave it - - bugfix: mobs in the middle of a walk_to will have their walk stopped by timestop - - bugfix: mobs that are stunned will be stopped mid walk as well - - bugfix: pulling respects changes in move_force - - bugfix: swapping places respects move_force if the participant is not willing - - bugfix: timestop is properly defeated by antimagic. - - bugfix: timestop only checks antimagic once - - tweak: Time stop now applies its visual effect on floors, walls and static structures - (with no change otherwise) - - tweak: Movable structures are now anchored while time stopped. - - tweak: Timestop effects now prevent speech. - AffectedArc07: - - code_imp: All code files are now in the LF line format, please stick to it - - tweak: Added CI step to check for CRLF files - - code_imp: Line ending CI works now - Arkatos, Zxaber, Ghommie: - - rscadd: Certain AI abilities now dynamically show their remaining uses on the - mouse hover over their respective action buttons. - - bugfix: Malfunctioning AIs can no longer abuse the confirmation popup to create - extra (unstoppable) doomsdays. - - bugfix: Fixed AIs being able to use some of their abilities such as the doomsday - whilst dead, and the doomsday loading phase not halting upon AI death. - Arturlang: - - tweak: Vampires are no longer as tanky - - rscadd: Added modular computers to the loadout - Bhijn: - - rscadd: Limbs now regenerate their stamina faster while disabled - - rscadd: Limbs now have the same incoming stamina damage multiplier mechanics as - spacemen, where the more staminaloss they take while disabled, the less staminaloss - they'll take. - - balance: Limbs have had their base stamina regen rate doubled to match the doubled - stamina regen rate of standard spacemen. - - rscadd: Added a preference to make the sprint hotkey be a toggle instead of a - hold bind - - rscadd: Added a preference to bind the sprint hotkey to space instead of shift. - - bugfix: server_hop can no longer be used to remotely lobotomize a spaceman - Bhijn helped: - - bugfix: Fixes Dragon's Tooth Sword 50% armor penetration by making it 35% - BonniePandora: - - admin: 'Added another SDQL option. Using "UPDATE selectors SET #null=value" will - now resolve value and discard the return. This is useful if you only care about - the side effect of a proc.' - CameronWoof: - - rscadd: Ghost Cafe patrons now spawn with chameleon kits. Dress up! Be fancy! - - rscadd: Robots can now check the crew manifest from anywhere with the "View Crew - Manifest" verb. - - tweak: Lizard tails are now viable options for humans and anthromorphs. - Commandersand: - - bugfix: fixed some clothnig sprites - - balance: lightning bolt,tesla,forcewall,emp spells have lower cooldown - - balance: fireball has a 10 second starting cooldown - DeltaFire15: - - bugfix: Vitality matrixes now correctly succ slimes - Denton, ported by Hatterhat: - - tweak: Most upgradeable machines now show their upgrade status when examined while - standing right next to them. - - tweak: Added examine messages to teleporter stations that hint at their multitool/wirecutter - interactions. - - tweak: Renamed teleporter stations from station to teleporter station. - - code_imp: Changed the teleporter hub accurate var to accuracy; the old name misled - people into thinking that it was a boolean. - Detective-Google: - - tweak: replaced the sprites with new ones requested. - EmeraldSundisk: - - rscadd: Adds a sign outside MetaStation's custodial closet - FantasticFwoosh, ported by Hatterhat: - - rscadd: Both reagent universal enzyme & sacks of flour are now available for their - respective costs from the biogenerator. - - rscadd: New crafting recipies for donut boxes, eggboxes & candle boxes have been - added to cardboard recipes for the collective benefit of service personnel and - the station. - Ghommie: - - tweak: Attached kevlar/soft/plastic padding accessories are now stealthier and - will no longer be displayed on mob examine. - - refactor: Refactored that mess of a code for alternate worn clothing sprites for - digitigrade and taurs. - - bugfix: Fixed some issues with the aforementioned feature you may or may not have - experienced because it was pretty lame. - - bugfix: Fixed missing digi versions fishnet sprites and wrong digitigrade left - dir purple stockings sprite. - - imageadd: Add digitigrade versions for boxers and the long johns. - - bugfix: Fixed the secret sauce recipe being randomized every round. - - bugfix: Fixed singularity pulls duping rods out of engine floors. - - rscdel: Removed an old pair of zipties from the captain closet. - - bugfix: Chestbursters won't delete the host's brain somewhat anymore. - - bugfix: Fixed roundstart mushpeople being unable to MUSH PUUUUUUUUUUUUNCH!! - - bugfix: Lattices can be examined yet again. - - bugfix: Made reagent containers examine text less annoying. - - bugfix: Virus food dispensers dispense virus food again. - - bugfix: Borg hypos inputs do not display typepaths anymore. - - bugfix: Restored chem dispensers alphabetical order. - - bugfix: Sanitized cargo export messages for reagents. - - bugfix: Riot foam dart (not the ammo box) design cost is yet again consistent - with the result's material amount. - - bugfix: Fixed a little exploit with ventcrawlers being capable of escaping closed - turfs by printing scrubbers/vents into them. - - bugfix: deconstructing a rubber toolbox with the destructive analyzer won't "lock" - the machine anymore. - - bugfix: Something about empty hand combat mode right click waving hands defying - common sense and being spammy. - - imageadd: Towels are now "digitigrade-friendly". - - bugfix: The Barefoot drink and mousetraps will now work even if wearing certain - "feet-less shoes". - - rscadd: Refactored code to allow all living mobs to use shields and not only humans. - - tweak: Monkys will now retaliate against aliens attacking them (as if they even - posed a threat to start with). - - tweak: add a click cooldown to the overly spammable table slamming. - Ghommie (original PRs by Kevinz000, ShivCalez, 4dplanner, Barhandar, 81Denton, zxaber, Fox-McCloud): - - rscadd: All atom movables now have move force and move resist, and pull force - An atom can only pull another atom if its pull force is stronger than that atom's - move resist - - rscadd: 'Mobs with a higher move force than an atom''s move resist will automatically - try to force the atom out of its way. This might not always work, depending - on how snowflakey code is. experimental: As of right now, everything has a move - force and resist of 100, and a pull force of 101. Things take (resist - force) - damage when bumped into experimental: Failing to move onto a tile will now still - bump up your last move timer. However, successfully pushing something out of - your way will result in you automatically moving into where it was.' - - bugfix: Bolted AIs can no longer be teleported by launchpads. - - balance: Megafauna cannot teleport - Hatterhat: - - balance: Beakers are generally more useful now, with slight capacity increases. - - tweak: Transfer amounts are different now. Adjust your muscle memory to compensate. - - balance: ore redemption machines actually get affected by lasers again kthx - - tweak: crusher trophy drop chance on mining mobs increased to 1 in 4 (from 1 in - 20) - - bugfix: Blood-drunk buff from blood-drunk eye crusher trophy is less likely to - cripple its user. - - tweak: Forcefield projectors now fit on toolbelts. - - imageadd: New sprites for ATMOS holofan and forcefield projectors! - - tweak: tweaks some values around with beaker transfer amounts, adds a transfer - value verb (altclick) - - rscadd: 'Syndicate sleepers (read: the ones that''re red and have controls in - them) can now be recreated with a sufficient basis in nonstandard (read: illegal) - technologies!' - - bugfix: Explorer hoods on standard explorer suits can be reinforced with goliath - hide plates again. - - rscadd: A shipment of Staff Assistant jumpsuits from the Goon-operated stations - appear to have made their way into your loadout selections - and into the contraband - list from ClothesMates... - - balance: Dropped Exo-suit armor to put it more in line with being an explorer - suit sidegrade and not a straight upgrade for Lavaland usage. - - rscadd: You can now print .357 AP speedloaders from Security techfabs after you - pick up the Advanced Non-Standard Ballistics node. - - rscdel: Forensic scanner removed from Advanced Biotechnology node. - - tweak: Ash Drake armor now has goliath resistance, same as the Exo-suit. - KathrinBailey: - - rscadd: Empty engineering lockers for mappers. - - rscadd: Industrial welding tools to the engineer welding locker. - - rscdel: Removed the multitool, airlock painter, mechanical toolbox, brown sneakers, - hazard vest and airlock painter from the CE's locker. - KeRSedChaplain: - - imageadd: The clockwork cuirass can now support slithering taur bodies. - Kevinz000: - - bugfix: Fixes successful projectile hits also striking another atom on the same - turf should the first one be not the target the projectile was meant for. - - rscdel: Removes infinite reflector loops. - Kraseo: - - bugfix: Jelly donuts and pink jelly donuts will now properly display sprinkled - icon state. - - bugfix: Jelly donuts and its variants will properly spawn with berry juice. - - bugfix: Slime jelly donuts have slime jelly in them now. (thanks ghommie) - - bugfix: Virgo hairstyles no longer have those annoying quotation marks. Rejoice - for you will no longer have to use the scrollbar. - - imagedel: Got rid of some strange-looking hairstyles. (Tbob, fingerweave, etc.) - LetterN: - - rscadd: Doppler logs - - tweak: Shockcolar and electropack uses the new signaler ui - - tweak: Renaming shockcolar requires a pen - - rscadd: Adds banjo - Linzolle: - - bugfix: fixes matchboxes runtiming every time they spawn - MrJWhit: - - tweak: Increases plasma usage in radiation collectors - Naksu: - - code_imp: reagent IDs have been removed in favor using reagent typepaths where - applicable - - bugfix: mechas, borg hyposprays etc no longer display internal reagent ids to - the player - Owai-Seek: - - rscadd: Four New Bounties - - tweak: tweaked several bounties - - tweak: reorganised several bounties - - balance: balanced several bounties - - bugfix: added shady jims to vendor - - rscadd: Towel, Bedsheet, and Colored bedsheet bins to Dojo. Some lockers with - carpets and wood, another bathroom/shower, tons of cleaning supplies, some additional - trash cans, a tiny medical area, and some vendors/vendor resupplies. Also added - some Ambrosia Gaia seeds. - - tweak: Moved some lights around, extended the dojo a bit to make it feel more - spacious. - - rscdel: Cafe Newsfeed Frame - PersianXerxes: - - tweak: Reduces the range of the forcefield projector from 7 tiles to 2 tiles. - Putnam: - - rscadd: Alcohol intolerance trait, which forces vomiting on any alcohol ingestion - - rscdel: Arousal damage is gone, and with it the arousal damage heart on the UI. - - rscdel: As exhibitionist relied on arousal damage, that's gone too. - - rscdel: Bonermeter and electronic stimulation circuit modules are gone. - - rscdel: Masturbation is no longer an option in the climax menu. It was identical - to climax alone in every way but text. Emote it out. - - rscadd: Arousal on genitals can now be displayed manually, on a case-by-case basis. - - rscadd: '"Climax alone" and "climax with partner" now only display to the people - directly involved in the interaction. rework: Catnip tea, catnip, crocin, hexacrocin, - camphor, hexacamphor all had functions or bits of functions reworked.' - - tweak: '"Climax with partner" now requires consent from both parties--it can no - longer be used on mindless mobs, and it asks the mob getting climaxed with if - they consent first.' - - tweak: A lot of MKUltra behaviors have been moved to hypno checks or removed due - to reliance on maso/nympho/exhib. - - rscadd: Cold-blooded quirk - - rscadd: 'Two relief valves for atmospherics, available in your RPD today: a unary - one that opens to air and a binary one that connects two pipenets, like a manual - valve.' - - tweak: The atmos waste outlet injector on box has been replaced with an atmos - waste relief valve. - Putnam3145: - - rscadd: Dynamic storytellers, a new voting paradigm for dynamic - - rscadd: Support for approval voting and condorcet (ranked choice) voting in server - votes - - rscadd: Ghost cafe mobs can now ghostize - - rscadd: Ghost cafe now has a cremator - - rscadd: Ghost cafe mobs are now eligible for ghost roles - - refactor: Ghost roles now use an element for eligibility purposes - - bugfix: You can toggle some prefs properly now. - - bugfix: no ass slap is no longer the same thing as no aphro - - balance: Devastating bombs kills bomb armor'd mobs again - - rscadd: Added a sort of "game mode ban" by way of having people rank their game - modes favorite to least favorite after the secret/extended vote. - - bugfix: Turns out the schulze scoring was written wrong and it was setting things - to 0 that shouldn't have been, so that's fixed. - - config: Random engines are now weighted. - - rscadd: Ghost dojo now has an autoylathe. - - rscdel: Ghost dojo no longer has VR or modular computer access. - - tweak: Ghost dojo mobs are pacifists. - - tweak: Ghost dojo booze-o-mat is now all access. - - bugfix: Ghost dojo crematorium now has a button. - - bugfix: Traitor objectives don't take a dump when they try to add an assassinate - anymore - - admin: Objective removal with antag panel no longer commented out silently while - still being an option that gives useful feedback on stuff it's not doing in - any respect - - rscadd: Second, temporary flavor text! - - bugfix: Limb damage works now - - tweak: Score instead of ranked choice for mode tiers - - bugfix: Chemistry not :b:roke - - tweak: Ghost dojo spawns will dust if their owner suicides or uses the "ghost" - verb. - - admin: Crafting is logged in a file now - - bugfix: temporary flavor text now pops up properly - - code_imp: demodularized player panel code, mostly - - admin: added ghost role eligibility delay removal to player panel - - balance: Metabolic synthesis disables if user isn't well-fed rather than if user - is starving - - bugfix: Gibtonite no longer instantly explodes upon being pickaxe'd. - - balance: Cold-blooded costs -2 quirk points now - - config: Added suicide to the config. - - tweak: Ghost cafe mobs are super duper attached to the ghost cafe. - - bugfix: Meow Mix bar sign works - - bugfix: Fixed a few relief valve behaviors - Ryll/Shaps, ported by Hatterhat: - - rscadd: Point-blanking people with shotguns actually throws them backwards! - Savotta: - - rscadd: snout - - imageadd: snout - Seris02: - - tweak: made it so trait blacklisting removes random positives instead of removing - everything - - rscadd: added atmos holofirelocks and temperature blocking - - tweak: tweaked how atmos holofan looks - - rscadd: stunglasses - - rscadd: disabler sechuds - - rscadd: adds coconut - - rscadd: adds a coconut bong - - rscadd: Auto ooc - - admin: changed "assume direct control" from m.ckey = src.ckey to adminmob.transfer_ckey(M) - so it works with auto ooc - - rscadd: marshmallow - - rscadd: telescopic IV drip - - bugfix: cardboard box speed - - tweak: makes gorilla shuttle emag only - - tweak: changed where the observe verb is. - - tweak: the way chameleon clothes update on change - - bugfix: chameleon cloak icon - - balance: Explosions now cause knockdown instead of KOs, with the amount of time - scaling off bomb armor. Heavy explosions still cause a ~2 second KO for follow - up attacks. - - balance: Devastating explosions now no longer gib players with more than 50 bomb - armor. This used to be more or less random depending on the amount of bomb armor. - - code_imp: Removed reagent explosion code that would trigger for <1 amount reactions. - - rscadd: traitor tool for bowmanizing headsets + bowmanizing headsets - - rscadd: durathread winter coats from hyper station - - tweak: conveyor belt now are stacks instead of single item - - tweak: conveyor crate has 30 belts - - tweak: printing a conveyor costs 3000 metal - - rscadd: you can press the conveyor switch in hand to link any not deployed belts - to it - - tweak: sniffing sneezing etc doing anything if they don't breathe - - bugfix: probably fixes the make mentor button - - tweak: the sprites for the conveyor belts to look more directional - Skoglol: - - bugfix: Falsewalls now properly hide pipes and wires. - SpaceManiac, bobbahbrown, ShizCalev, SpaceManiac (ported by Ghommie): - - code_imp: It is now possible to set a different most-base-turf per z-level. - - spellcheck: Removed unlawful reference to Disney's Star Wars franchise in map - logging. - - tweak: Moved mapping related errors to their own log file. - - bugfix: Destruction on Lavaland will no longer reveal space in rare situations. - Tlaltecuhtli, Nemvar, Trilby, Hatterhat: - - rscadd: russian surplus crate, sec ammo crate, meat/veggie/fruit crate, rped crate, - bomb suit crate, bio suit crate, parrot crate, chem crate, db crate - - tweak: lowered price of some crates which are overpriced for no reason aka the - tablet crate and the mech circuits crates, track implant crate has also track - .38 ammo - - bugfix: sectech vendor has a refill pack - Trilbyspaceclone: - - bugfix: Fermi plushie can be made once again - - tweak: range on Engi Tray scanners and Rad-Scanners - - bugfix: issues with mapping done my Trilby - - rscadd: Grass now makes light beer when distilled - - tweak: allows bandoliers to hold any ammo type as long as it has a casing - - server: Cleans out the last years of changlogs - - bugfix: 'rouge cases of #$39; in bottle/pill/patch/condiments' - - tweak: Adds missing but needed flags to MASON RIG - - bugfix: missing sprites with crushed cans - - tweak: Halfs the nutriments in sugar - - rscadd: Glitter is now makeable with ground plastic and some crayons - - code_imp: Makes more folders and files for uplink. - - rscadd: Seed packs now have RnD points inside them - - rscadd: New tips that reflect the now use seed packs have for Rnd / Chems affect - on plants - - code_imp: Made the research file look nice rather then an eye harming list - - bugfix: Fixed fragile space suits breaking from weak and non-damaging "weapons" - (such as the Sord, toys and foam darts). - - rscadd: 'tip of the round: Cleanbot can withstand lava and burning hot ash. Its - a god' - - rscadd: more glassware - - rscadd: Few new packs and glassmaker kit! - - tweak: prices/chems of crates/autobottler - - bugfix: some crates ungettable as well as some broken crates - Trilbyspaceclone, Ghommie: - - rscadd: More types of glass can now be used to make a solar panel, with different - sturdiness and efficiency depending the type. - Tupinambis: - - tweak: Replaces new fire alarms with a slightly updated version of the old ones. - - bugfix: Fixed bug where Amber alert had no proper alert lights, and red alert - had amber lights. - - balance: RLDs now cost more to use, have reduced matter capacity, and sheets are - worth less when refilling them. - Unit2E & JMoldy, ported by Hatterhat: - - balance: the powerfist now punches people away at high velocity depending on setting. - - rscadd: the powerfist now leaks the gas it uses onto the tile you're on. - - tweak: Adds weak punch variations for empty and near-empty punching. - Xantholne: - - bugfix: Christmas clothes that where missing stuff should work again - - tweak: Christmas clothes moved from clothesmate and loadout to premium autodrobe, - hoodies and boots remain. - - rscadd: Botany bee pet, Bumbles - - rscadd: New bee models that aren't 1 tile big of 0 opacity pixels - - rscadd: Cheongsam and Qipao clothing added to loadout and clothesmates - dapnee: - - imageadd: new toxin's uniform and accessories - - imagedel: old toxin's uniform and accessories - deathride58: - - balance: The stamina buffer no longer uses stamina while recharging. - jakeramsay007: - - rscadd: The assorted .357 revolvers (except russian revolver) can now also load - .38, like real life. - kappa-sama: - - rscadd: loot crates in cargo contraband - - code_imp: modular_citadel file movement - - code_imp: modular citadel loses some files - - balance: dragnet snares can now be removed in 5 seconds - keronshb: - - rscadd: Adds new features for nanites - - bugfix: fixed the missing icons from Dermal Button nanites - - rscadd: Ports the special nanite remote, mood programs, and research generating - nanites - - balance: rebalances some nanites - - bugfix: fixed my messup - kevinz000: - - rscadd: throwing things no longer makes them randomly turned as long as you aren't - on harm intent - - rscadd: Custom holoforms have been added for pAIs and AIs. oh and cyborg holograms - of specific modules too. - - balance: pais are no longer indestructible-flagged while in card form. pai radios - now short out if they are forcefully collapsed from damage. - - bugfix: telescopic iv drips now have the proper sanity checks for deployment. - - bugfix: megafauna can hear again - - balance: Cargo passive gen is now 500 down from 750. - - config: Added a few more nightshift config entries - - rscadd: nightshift_public_area variable in areas to determine how public an area - is. - - rscadd: NIGHT_SHIFT_PUBLIC_AREAS_ONLY config entry allows the server to be configured - to only nightshift areas of that level and below (so areas that are more public) - - rscadd: Config entries added for requiring authorizations to toggle nightshift. - Defaults to only requiring on public areas as determined by above - - balance: nuclear fist buffed. - - balance: cogscarabs are now fulltile-hitbox. - - balance: emitters are now hitscan - - balance: monkies gorrilize easier now - - rscadd: Ghosting no longer stops abductors from using you. - - rscadd: guests can now looc - - tweak: tableslamming has 0.4 second cooldown instead of 0.8 - - bugfix: health analyzers now work - - code_imp: Mapping helpers added for power cables and atmos pipes. - - rscdel: Blood duplication is gone, but viruses now react up to 5 times, 1 time - per unit, for virus mix. - - rscadd: you can now block people on your PDA - - bugfix: Grenades can now have their timers adjusted. - - balance: Cloning has been nerfed. - - bugfix: hilbert hotel is now less of an exploity mess - - balance: Doorcrushes are once again instant. - nik707: - - tweak: engraving light_power from 1 to 0.3 - r4d6: - - rscadd: Added a Radiation Hardsuit - - rscadd: Added a Radiation Hardsuit crate - - rscadd: Added 3 SM Engine variations. - - rscadd: 'Added a way to make opaque plastic flaps change: Change the already existing - flap recipe to show that they are see-through' - - rscadd: Animations for the RCD - - bugfix: Said animations being pulled by the Singulo - - balance: Prevent Reinforced Doors from being RCD'ed - - bugfix: Deconstructing Floors now cost MUs like everything else - - tweak: changed the RCD's upgrades into flags - - rscadd: Allow RCDs to print APC, Firelocks and Fire Alarms with the right upgrade - - balance: Allow Engineers to print RCDs and RPDs from their protolathe without - needing to hack one. - - rscadd: Added a playback device - - bugfix: Made the Voice Analyzer actually care about languages - - bugfix: fixed SM's piping - - rscadd: Added a message when pulsing the open wire. - - bugfix: fixed being able to use a playback device and a voice analyzer to activate - each others - - rscadd: added passive vent to the arsenal of atmospheric devices. - - rscadd: Mining base now has a common area accessible via a new shuttle on the - medium-highpop maps, and a security office connecting the gulag and the mining - base. Gulag also has functional atmos. - - rscadd: Added more Cyborg Landmarks - - refactor: better code for passive vents - - bugfix: fixed a hole in Meta - - rscadd: Added the ability to easily add variations of the mining base - - bugfix: fixed a sprite - timothyteakettle: - - bugfix: fixed not being able to remove trait genes without a disk being inserted - into the dna manipulator -2020-02-26: - AnturK ported by kevinz000: - - rscadd: Dueling pistols have been added. - Arturlang: - - rscadd: Replaces a lot of ingame UIs with TGUI next, increasing performance drastically. - - rscadd: Each night for bloodsuckers will last longer due to the sun dimming. - - tweak: You cant level up for free, now you have to pay blood for power. - - balance: Bloodsuckers are no longer as resistant to hard stuns and regenerate - less stamina. and a lot of their cooldowns are a lot higher. - - rscdel: Removed text macros from the chem dispenser. - - rscadd: Replaced with dispenser input recording macros. - - bugfix: Fancifying makeshift switchblades now works - - balance: Shields will no longer block lasers, and will break if they take too - much damage. - - rscadd: Added a TGUI Next interface for crafting - - rscdel: Removed the old TGUI slow crafting interface - - tweak: The MK2 hypospray now - - admin: The debug outfit is now kitted out for whatever debbuging needs. - - bugfix: Fixed the pandemic naming and the radiation healing symptom UI crashing - - tweak: Hyposprays now switch modes on CTRL click, instead of alt, as it was already - reserved for dispension amount. - - rscadd: Nanite interfaces have gotten a rework to TGUI Next, and can now support - sub-programs. add:Adds the nanite sting program, which will allow you to manually - sting people to give them nanites, changeling style. - - balance: The pandemic can no longer make vaccines or synthblood as quickly. - - rscadd: The syndicate uplinks interface has been redone in TGUI Next - - tweak: Valentines can now be converted by bloodsuckers - Bhijn: - - tweak: Click-dragging will now only perform the quick item usage behavior if you're - in combat mode. - BlueWildrose: - - bugfix: podpeople tail wagging - - tweak: lifebringer ghost role fixes - BuffEngineering, nemvar.: - - bugfix: Addicts can now feel like they're getting their fix or kicking it. - - bugfix: Aheals now remove addictions and restore your mood to default. - CameronWoof: - - tweak: Lighting looks better now. I can say that because the PR wouldn't be merged - and you wouldn't be reading this if it wasn't true. - - rscadd: Ammonia and saltpetre can now be made at the biogenerator. - Commandersand: - - tweak: uplink centcomm suit doesn't have sensors - DeltaFire15: - - balance: Nar'Sie runes no longer benefit from runed floors. - Detective-Google: - - rscadd: 'the POOL. remove: boxstation dorms 7' - - bugfix: valentines candy no longer prefbreaks - - rscadd: Loudness Booster pAI program - - rscadd: Encryption Key pAI program - EmeraldSundisk: - - bugfix: Connects mining's disposal unit on Delta. - - tweak: Slight visual adjustments to the immediate affected area. - Feasel: - - balance: Buffed dissection success chances. - Ghommie: - - tweak: The anomalous honking crystal should now properly clown your mind. - - bugfix: Stopped the ellipsis question mark from being displayed twice in the examine - message for masked/unknown human mobs. - - tweak: Made the aforementioned ellipsis question mark display on flavor-text-less - masked/unknown human mobs too for consistency. - - bugfix: Stopped an APTFT exploit with spray bottles. - - bugfix: Fixed the detective revolver being quite risky to use. - - bugfix: Hair styles and undergarments are yet again free from gender restrictions. - - tweak: Clown ops will find bombananas and clown bomb beacons instead of minibombs - and bomb beacons in their infiltrator ship now. - - tweak: For safety, the syndicate shuttle minibombs and bombananas come shipped - in a box. Please don't instinctively eat any of those nanas, thank you. - - tweak: Uplink items excluded (such as mulligan, chameleon, ebow) from or exclusive - (such as cyber implants) to normal nuke ops will now be properly unavailable/available - to clown ops. - - bugfix: Fixed bananium energy sword/shield slips. - - balance: Buffed said slips to ignore no-grav/crawling/flying as well as adding - some deadly force to the e-sword. - - bugfix: Fixed the 'stache grenade anti-non-clumsy user check. - - balance: Doubled the timer for the sticky mustaches effect from the above grenade - (from 1 to 2 minutes) - - bugfix: Fixed an edge case with the chaplain armaments beacon spawning the box - in nullspace. - - tweak: The playback device's cooldown now proportionally increases with messages - longer than 60 characters (3 seconds is the default assembly cooldown). - - bugfix: Fixed space ninjas "Nothing" objective. Now you gotta steal some dandy - stuff such as corgi meat and pinpointers as a ninja too. - - bugfix: Fixed maploaded APC terminals direction. - - balance: Nerfed magnetic rifles/pistols by re(?)adding power cell requirements - for it. These firearms must be recharged after firing 2 magazines worth of projectiles - and are slightly more susceptible to EMPs. - - bugfix: Fixed the tearstache nade not properly working. - - balance: Buffed it against space helmet internals. - - tweak: Holographic fans won't display above mobs and other objects anymore. - - bugfix: Fixed paraplegics appearing as shoeless. - - bugfix: Fixed the petting element. - - bugfix: Fixed slipping. - - refactor: Refactored mob holders into an element. - - bugfix: Fixed a few minor issues with that feature. such as mismatching sprites - for certain held mobs and a slight lack of safety checks. - - rscdel: holdable mobs can't force themselves into people's hands anymore. - - bugfix: Milkies fix. - - bugfix: Fixed some mounted defibrillator issue with the altclicking functionality. - - bugfix: Fixed no-grav lavaland labor/mining shuttle areas. - - bugfix: Fixed a little issue with sleeper UI and blood types. - - bugfix: Fixing accidental nerfs to the magpistol magazine. - - bugfix: The Lavaland's Herald speech sound should only play if they are actually - speaking. - - bugfix: Nerfed cargo passive points generation from 500 to 125 creds per minute. - - bugfix: Fixed whitelisted/donor loadouts - - bugfix: Childproofs double-esword and hypereuplastic blade toys. - - balance: Some reagent holders (such as cigarettes, food) are not suitable for - reagents export anymore, while unprocessed botany crops will only net 1/3 of - the standard reagents values. - - bugfix: Export scanners now include the reagents value in the price report. - - bugfix: Fixed a little inconvenience with the character setup preview dummy having - extra unwarranted bits. - - bugfix: Stopped role restricted uplink items from being discounted despite not - being purchasable most times. - - bugfix: Missing words replacement file for the gondola mask. - - bugfix: Fixed an issue with the nearsighted prescription glasses taking over worn - eyewear. - - bugfix: Fixed AI unanchoring not properly removing the no teleport trait. My bad. - - bugfix: Fixed another issue with hering comsig. - - imageadd: Fixed dozen missing privates sprites. - - bugfix: A little fix concerning some R&D and reagents. - - bugfix: Further mob holder fixes. - - bugfix: Fixed being unable to dump a trash bag's contents directly into disposal - bins. - - bugfix: Doubled the halved flavor text maximum length. - - bugfix: Reduced tongue organ damage and tasting pH message spam. - - bugfix: Fixed agent IDs not registering the inputted name. Thanks MrPerson. - - bugfix: Fixed solar panels/trackers (de)construction being a bit wonky. - - bugfix: Fixed something about slime blood and the law of conservation of mass. - - bugfix: Fixed flypeople being emetic machine guns. - - bugfix: Fixed virology being unable to be done with synthetic blood. - - rscdel: Renamed "blaster carbine" and "blaster rifles" back to "energy gun" and - "laser gun" respectively - - bugfix: Fixed magnetic rifles & co being inconsistent with printed energy guns - and start with an empty power cell. - - imagedel: Reverted practice laser gun sprites back to their former glory. Mostly. - - bugfix: Fixed sprint buffer cost and regen being rounded down. - - balance: Nerfed the fermenting barrel export industry. - - tweak: Reagent dispensers selling price no longer takes in account the reagents - volume. It's already handled by reagents export. - - bugfix: pAIs are yet again unable to perform certain silicon interactions with - machineries yet again. - - bugfix: Fixed pAI radios inability to be toggled on/off. - ? Ghommie (original PRs by Floyd/Qustinnus, 4Dplanner, Willox, ninjanomnom, mrdoombringer, - Fikou, Fox McCloud, TheChosenEvilOne, nemvar, bobbahbrown, Time-Green, Stonebaykyle, - MrPerson, ArcaneMusic and zxaber) - : - rscadd: You can now make toolboxes out of almost any solid material in an autolathe - - rscadd: adds Knight's Armour made out of any materials - - rscadd: new ruin found in lavaland protected by dark wizards, I wonder what - they're guarding - - rscadd: You can now put a bunch more mats in the coin mint and autolathe - - rscadd: Adamantine and Mythril are now materials (Adamantine still only from - xenobio, Mythril still only from badminnery). Adamantine boosts an item's - force by 1.5, Mythril gives an item RPG statistics. - - rscdel: most custom sprites for coins have been lost - - rscadd: You can now give your ass acute radiation poisoning - - rscadd: floydmats now apply to all objs / items - - rscadd: you can now make tables and chairs out of any material - - bugfix: Fixes being able to exploit fully upgraded destructive analyzers to - multiply materials - - rscadd: An old monastery from a previously abandoned sector of space has recently - resurfaced in some regions surrounding the station. - - rscadd: Latent scans of the surrounding systems have picked up trace signs of - new, smaller cult constructs, however these signatures quickly vanished. - - rscadd: In other news, scavengers in your sector have been seen occasionally - with classically recreated maces, so autolathe firmware has been upgraded - to accommodate this. - Hatterhat: - - balance: Zombie powder is now instant when ingested, but delayed when injected - or applied through touch. - - tweak: The H.E.C.K. suit is now goliath tentacle resistant and probably better - for acid resistance. - - rscadd: The Engineering techfab can now print standard and large RCD compressed - matter cartridges. - - rscadd: The Experimental Tools node now has the Combifan projector, blocking both - temperature and atmospheric changes. - - tweak: fiddles with the seed extractor upgrade examine to make it not shit - - rscadd: Formaldehyde prevents organ decay and corpses' miasma production at 1u - in the body. - - rscadd: Epinephrine pens now contain 3u formaldehyde. This should not kill you. - - rscadd: The ships often crashed by Free Golems on Lavaland now have GPSes. They're - off, by default, but an awakening Golem could easily turn one on. - - tweak: Standard RCD ammo can now be printed from Engineering-keyed techfabs once - you hit Industrial Engineering. - - tweak: Consoleless interfaces are now default - this means unrestricted protolathes - and circuit imprinters can now be interfaced with by interacting with the machine - itself. - - bugfix: Multitools can now actually be printed from Engineering and Science protolathes/techfabs - once you unlock Basic Tools. - - rscadd: Husking (from being burned to shit) can now be reverted! 5u rezadone or - 100u synthflesh, at below 50 burn. - - balance: Turning a body into a burnt husk now takes more effort. 300 burn's worth - of effort. - - balance: Buckshot individual pellet damage up from 10 to 12.5. Still firing 6 - pellets. - - rscadd: Preservahyde! Made with water, bromine, and formaldehyde, it doesn't decay - into histamine. Instead, it just prevents your organs from rotting into nothing. - - balance: You can now purify eldritch longswords with a bible. This creates purified - longswords, which do not have anti-magic properties, but are still good for - swinging at cultists. - - rscadd: Extend votes! Ported from Hyper, ported from AUstation. - - bugfix: mechs with stock parts now have icons - - balance: Pie reagent transfer now requires an uncovered mouth. - - bugfix: Biogenerators can now actually generate universal enzyme. - - bugfix: The Basic Tools node now unlocks the multitool for printing on Engineering - and Science fabricators. - - rscadd: The Ash Walkers' nest on Lavaland now starts with three bowyery slabs. - - rscadd: You can now welder-harden arrows. It might take longer. - - balance: Silkstring's costs adjusted for bows and whatnot. - - spellcheck: Grammar adjusted on a lot of things relating to bows. - - bugfix: Pipe bows' bowstring doesn't look like it replicated itself upon draw. - IHOPMommyLich: - - tweak: Changed the multiplicative_slowdown of Stimulants from -1 to -0.5 - IronEleven: - - balance: Minor stat changes to Choking, Spontaneous Combustion, Autophagocytosis - Necrosis, Hallucigen, Narcolepsy, Shivering, and Vomiting symptoms. - KathrinBailey: - - bugfix: Missing turf_decals in Cargo Office. - - bugfix: Turns on the docking beacons on Box. - - bugfix: Fixes Starboard Quarter maint room being spaced. It was never intended - to be like how it was. - - bugfix: The aforementioned maint room not having stuff in it. - - bugfix: varedited photocopier sometimes not opening any UI. - - bugfix: Atmos differences in Starboard Quarter maint. - - bugfix: Atmos differences in destroyed shuttle/EVA bridge. Plating replaced with - airless plating. - - bugfix: Rotates AI satellite computers. These have probably been like this since - computers had the old sprites and no directional ones. You shouldn't sit at - a chair to operate a sideways computer. - KrabSpider: - - imageadd: The Van Dyke is no longer Fu Manchu. - - imagedel: Gets rid of a Fu Manchu imitation. - Kraseo: - - bugfix: You can no longer pull before wearing boxing gloves to bypass the grab - check. - - bugfix: Nightmares no longer delete entire guns from existence for merely having - a light on them. - Linzolle: - - bugfix: Bows now will not delete an arrow if it cant fire it. - - bugfix: bows now like and respect sprite changes - MalricB: - - rscadd: '"Shaggy" sprite from virgo' - - rscadd: '"shaggy" option in the character customization' - MrJWhit: - - rscdel: Removed meteor defense tech node - - tweak: TEG - Naksu: - - bugfix: Odysseus chem synthesizing now works again. - Owai-Seek: - - rscadd: Burger, Cargo Packaging, Dirty Magazine, Air Pump, and Scrubber crates. - - rscdel: Duplicate Crate, Festive Wrapping Paper Crate, Contraband Monkey Meat - Crate - - tweak: Gave Seed Crate Ambrosia Seed, gave Biker Gang Crate Spraypaint. - - tweak: Organised some crates with sub-categories. Also, moved all vendor refills - to a new tab. - - tweak: Moved Grill to Service Tab - - bugfix: Engineering Hardsuit Access - - tweak: Blood Crate now has all of the current blood types. - - tweak: Birthday Cake Recipe is now the same as TG. - - tweak: Added Soy Sauce and BBQ Packets to Dinnerware Vendor. - - tweak: Added nurse outfit, nurse cap, and mailman hat to loadout. - - tweak: Changed the name of scrubs to blue, green, and purple scrubs. - - rscadd: Bacon and Eggs food item. Delicious! Added a Lemony Poppy Seed Muffin. - - tweak: Snack Vendor has Chocolates, Tortilla Chips, and a Marshmallow Box - - balance: Mops can now be printed at service lathe once tools are researched. - - balance: Biobags can hold most organic limbs/organs, but not brains, implants, - or cybernetics. - - balance: Trash Bag can now hold limbs (but not heads.) - - balance: Most snack vendor items reduced by 1. - - bugfix: Trash Cans are now actually craftable, and only require metal instead - of plastic. - - imageadd: Bacon and Eggs, Drying Agent Bottle. - - imageadd: Mugs now show reagent colors of contained reagents. Thanks Seris! - - tweak: Reorganized all food recipes, (hopefully) making things easier to find. - - balance: Trays now have a whitelist, allowing them to pick up normal sized foods, - bowls, glassware, booze, ect. - - bugfix: Easter foods are no longer their own Misc Food Category on the top of - the menu. - - spellcheck: fixed a few typos/capitalization consistency. - - tweak: Mexican Foods are their own Subcategory. - - tweak: Donuts are their own Subcategory - - tweak: Moved Sweets from Misc Food in with Pies. Renamed to Pies & Sweets - - rscadd: BROOM - - tweak: Janitor Vendor now has gear for two Janitors. - PersianXerxes: - - rscadd: 'SMES and PACMAN attached to gulag Security to power electrified windows - remove: Removed Sec vendor from gulag Security' - - tweak: Separation of gulag and public mining - - rscadd: Better clarified the comment explaining the contraband tag. - - tweak: Cargo nuclear defusal kits now require an emag'd drop pod console to be - purchased. - - rscadd: Added Kilo Station - - tweak: Adjusts Kilo Station to be more in line with Citadel standards - - imageadd: Added area icons required to make Kilo Station editable on Citadel code - - code_imp: Fixed a reagent container on Kilo pointing to a nonexistent reagent - - config: Adds Kilo Station to the maps config file, does not fix Meta Station's - population requirement - Psody-Mordheim: - - rscadd: You can now make synth-flesh with synthetic blood. - - rscadd: You can now make synthetic blood via mixing saline glucose, iron, stable - plasma and heating it to 350 temp. - - rscadd: You can mix synthetic blood and cryoxadone to create synth-meat in addition - to normal blood. - - rscadd: Disfiguration Symptom. - - rscadd: Deoxyribonucleic Acid Saboteur Symptom. - - rscadd: Polyvitiligo Symptom. - - rscdel: Revitiligo Symptom. - - rscdel: Vitiligo Symptom. - Putnam3145: - - admin: Added logging to various consent things. - - rscadd: Lots of new traitor objectives - - bugfix: gender change potion now respects prefs - - bugfix: Hypno prefs work better. - - admin: Panic bunker is now round-to-round persistent - - tweak: Relief valve now has a TGUI-next UI - - bugfix: Atmos reaction priority works now. - - rscadd: map voting doesn't suck anymore - - bugfix: Dynamic now defaults to "classic" storyteller instead of just failing - if the vote didn't choose a storyteller. - - bugfix: antag quirk blacklisting works now - - tweak: default should be... default - - balance: all supermatter damage is now hardcapped - - tweak: Supermatter sabotage objective no longer shows up with no supermatter - - bugfix: Mining vendors no longer fail and eat your points iff you have precisely - enough points to pay for an item - - tweak: Licking pref - - bugfix: Fixed IRV. - - bugfix: Runtime if nobody has a chaos pref set - - bugfix: IRV fixed... again - - bugfix: temporary flavor text can now be of reasonable length - - balance: Shooting the supermatter now adds to the supermatter's power. CO2 setups - beware! - - rscadd: Logging for renaming - Raiq & Linzolle: - - rscadd: Bone bow - Ash walkers crafting , bone arrows - Ash walkers crafting, - silk string used in bow crafting, harden arrows - Ash walkers crafting, ash - walker only crafting book, basic pipe bow, and bow & arrow selling. Quivers - for ash walkers as well, just to hold some arrows well out on the hunt! - Seris02: - - tweak: tweaked the way the SM works - - rscadd: custom reagent pie smite - - rscadd: hijack implant - - code_imp: changed mentions of the issilion proc to hasSiliconAccessInArea based - on what the proc is used for - - rscadd: recipe for mammal mutation toxin - - rscadd: polychromic winter coat - - rscadd: thief's gloves - - rscadd: crushing magboots - - bugfix: golden plastitanium toolbox being actually plastitanuium - - bugfix: character slot amount - - balance: rebalanced rising bass - - bugfix: string highlighting whitespace - - bugfix: glitch with PKA - - bugfix: meteor hallucinations (again) - - rscadd: Added naked hallucination - - rscadd: crowbarring manifests off crates - - balance: makes RCDs cost a better amount - - bugfix: apc icons - - rscadd: rest hotkey - - rscadd: hsl instead of sum of rgb for spraycan lum check - - balance: bloodcrawl's cooldown - ShadeAware: - - rscadd: Craftable Switchblades, a weaker subtype of normal switchblades that can - be crafted using a Kitchen Knife, Modular Receiver, Rifle Stock and some Cable - Coil. Requires a welder to complete. - - bugfix: You can now actually craft Switchblades. - - bugfix: Switchblades no longer regain their old Makeshift sprite after retracting - if you've made them fancy with Silver. - - rscadd: 'The Captain''s Wardrobe, a special one-of-a-kind and ID-locked wardrobe - for the Captain that holds all of their snowflakey gear. Remove: Snowflake gear - from the Captain''s locker, since now it has its own vendor.' - Tlaltecuhtli, ported by Hatterhat: - - balance: Ripley, Firefighter, Odysseus and H.O.N.K. mechs now also use scanning - modules and capacitors on construction. This means that they also gain reduced - power consumption and EMP protection from higher-tier stock parts. - Trilbyspaceclone: - - bugfix: Vault hallway door being all access - - server: Updates change logs - - rscadd: Crafts are now made of plasteel and can be made with 5 sheets - - rscadd: Takes away NT's connections to the Aliens that run the Syndicats - - rscadd: Carps have evolved to take more damage - - rscadd: restock crates for each vender - - rscadd: restock units for all station venders - - bugfix: Sec-vender missing icon - - bugfix: 'Box station captain office issues maping: Gulag on box can now be accessed' - - rscadd: Alien stools and chairs - - tweak: Bone armor/Dagger are now crafting from bones rather then crafting menu - - rscadd: Firing pins that only works when not on station - - rscadd: Medical locked crates - - balance: Russian gear crates have less gear in some cases but all will cost more - - bugfix: Medical locked crates that were not locked - - spellcheck: Crates that were out of date are corrected - - balance: Heads of staff have been better screened by NT before being promoted - - balance: The suit full of spiders also known as a ninja now is a tactical turtleneck - - balance: The Wiznerds now dont have suits set to max - - tweak: Meat wheat no longer has blood - - bugfix: Flat guns can no longer be suppressed - - tweak: replaced stickmans .45 caliber with 10mm, for consistency. - - tweak: Meatwheat and Oats now have rarity - - balance: Oats now have at lest 50% more flour in them - - balance: BDM now uses a PKA rather then a normal KA - - tweak: Gang tower shield is no longer transparent - - tweak: Cosmic winter coat now glows like the bedsheet, and holds normal winter - coat gear - - server: Express console is now logging what it buys, like the normal console should - - bugfix: Crabs are now made of crab meat. - - bugfix: AIs now understand the old ways of drunken dwarfs - - balance: Removes some armored Russian hats from box station round start - - bugfix: Doner items spawning - - balance: Engi/Sec Trek suit no longer has 10% melee protection - - bugfix: IPC hearts are now made of robomeat and roboblood thats emp proof. Heals - and is all and all just like an normal heart - - imageadd: All robotic organs now have an animation. - - imageadd: IPC's now organs now look like robotic ones, even tho thats not the - case game wise - - imageadd: Added a new bee themed bar sign - - imageadd: Makes plywood chair not look as bad. - - bugfix: corndog sprite being miss-spelled - - bugfix: Ash from land of lava now is useable for sandstone - - bugfix: Peach cake slices are no long made by mimes - Tupinambis: - - tweak: the portion of laws that require harm prevention by silicons has been removed. - - server: silicon_laws.txt config file is required to be modified for full implementation. - - bugfix: masks no longer improperly stick out of helmets when they should be hidden. - - bugfix: Status Displays should now update correctly. - - balance: stunbatons now take 4 hits to inflict hard crit, up from 3. - - balance: stunbatons no longer disarm targets. - Yakumo Chen: - - rscadd: Rings for your fingers! - - rscadd: New cargo crates and loadout options to bling your rings! - YakumoChen: - - tweak: Observe is back in the OOC tab - - imageadd: Rings look nicer. Sprites used from RP. - - imageadd: Ring on-hands. Diamond rings sparkle! - - tweak: You can now propose using a diamond ring in your hand. - - tweak: Legion skulls behave like bees!!!! - Zellular: - - imageadd: Movement state for pupdozer and its decals - - tweak: Tweaked the movement state for the pupdozer's eyes - ancientpower: - - bugfix: Fixes an error in pH strips' feedback message. - - rscadd: Ported drink sliding from /vg/station. - - bugfix: Fixes color mismatching with the "genitals use skintone" preference. - - imageadd: Bunny ear style for humanoid species. - - tweak: Ghosts are now literate. - bunny232: - - tweak: Changes the simple animal sentience event from the xenomorph preference - to sentience potion preference. - coiax: - - rscadd: Admin and event only pair pinpointers! They come in a box of two, and - each pinpointer will always point at its corresponding pair. Aww. - deathride58: - - bugfix: Spacemen no longer run at lightspeed on local servers. - kappa-sama: - - bugfix: the plant dudes can actually make plant disks now - keronshb: - - rscadd: Added repairable turrets - - rscadd: Adds Tiny Fans to the pirate ship - - tweak: changes some reinforced windows to plastinanium pirate windows - - tweak: made the pirate shuttle + turrets bomb resistant - - tweak: made most pirate machines + consoles indestructible - - tweak: increased pirate turret health - - rscadd: Adds the CogChamp drink and Sprite - - rscadd: Added burn and knockback to stunhand during HALOS on cult. - - balance: Added burn and knockback to stunhand during HALOS on cult. - - bugfix: fixed accelerated regeneration nanites - - bugfix: fixed mechanical repair nanites - - bugfix: fixed bio reconstruction nanites - kevinz000: - - refactor: Custom snowflake plushies are now in config rather than code. - - balance: Abductor mindsnapping (aka abductee objectives) can now be "cured" with - brain surgery. - - rscadd: Shuttle hijacking has been completely reworked. Alt-click the shuttle - as a hijack-capable mind (so traitors, and especially traitors with hijack) - to begin or continue a hacking process. - - refactor: 'A good amount of the blood RGB rework was cleaned up/reverted, with - some notable gameplay changes including: Gibs and blood not having max blood - by default (no more easy rampages, cultists), infinite gib streaking, etc etc.' - - balance: meteor waves are now directional and announces the direction on the command - report. - - rscadd: CTF CLAYMORES - - balance: shoves buffed, now shoving into a wall twice rapidly will also disarm - their weapon. - - balance: traitor+bro gamemode minimum population set to 25 until there can be - more in depth configuration systems for gamemodes. - - bugfix: no more bluespace skittish locker diving, - - rscadd: moths now have unique laughs and can *chitter. - - tweak: nuke explosion is now full dev radius for anti lag purposes - - balance: Gangs can now only tag with a gang uplink bought spraycan. - - tweak: dueling pistol accesses have been changed to be more accessible. - - bugfix: mechs no longer have admin logs flooding into IC control console log viewing - - refactor: Guncode and energy guns have been refactored a bit. - - rscadd: You can now combat mode ight click on an energy gun to attempt to switch - firing modes. This only works on guns without right click functions overridden. - - balance: shoes can now fit magpistols again. - - balance: Projectiles now always hit chest if targeting chest, snipers have 100% - targeting zone accuracy. All other cases are unchanged. - - tweak: The lawyer's PDA cartridge has been rebranded to something more accurate - to its true nature. - - refactor: Refactored ghostreading/etc - - balance: Cyborgization will now de-gang people, even gangheads. - - bugfix: reactive repulse armor now has an item limit - - bugfix: beam rifle runtime fix during aiming_beam - - bugfix: 'fail2topic runtime fix: taking out an ip while incrementing index resulted - in accessing the next-next entry instead of the next and results in out of bound - errors.' - - rscadd: gravity gun repulse and chaos now work in all angles, rather than just - basic cardinals and diagonals. fun. - - balance: Public autolathes can no longer be hacked. - - bugfix: Energy weapons now once again have their lens in contents. - - bugfix: pais are no longer muted for literally a whole hour on emp. - - rscadd: auto profiler subsystem from tg - - bugfix: Brig cells now are more accurate by using timeofday instead of realtime - - bugfix: Cryo now actually transfers reagents at tier 4 on enter rather than every - 80 machine fire()-process()s regardless of if it was "reset" by open/close. - - rscadd: cmo now gets advanced surgery drapes that techweb-sync for advanced surgeries - without an operating console. - - bugfix: ctf claymores now actually spawn (and fit). - - bugfix: STOP_PROCESSING now removes from currentrun to prevent another process - cycle from happening where it shouldn't. - - balance: hand teleporters now require 30 deciseconds of still movement by the - user to dispel portals. there's a beam effect too. - - balance: Sort of a bugfix but cult blood magic and all guns now respect stamina - softcrit. - - balance: Organ healing rate doubled. Organ decay rate halved to match its define - (15 minutes for full decay, so at around 8-10 minutes it'll be really fucked). - - tweak: Storage now caches max screen size and only stores when being opened by - a non ghost, meaning ghosts will no longer distort living player screens when - viewing storage. - - balance: Stunbatons changed yet again. - - tweak: the game's built in autoclicker aka CanMobAutoclick no longer triggers - client/Click()'s anti clickspam guard. - - balance: pais can no longer bodyblock bullets - - balance: pai radio short changed to 3 minutes down from 5 - - balance: pais are no longer fulltile click opacity. - - refactor: vampire "immortal haste" has been reworked to be more reliable and consistent. - - tweak: hand teles use a less atrocious beam - necromanceranne: - - rscadd: Ebows now disarm people hit by them. - - rscadd: Ebows now do 60 stamina damage on hit. - - rscdel: Ebows no longer inflict drowsiness - - balance: Miniature ebows do 15 toxin damage, up from 8. - - balance: Ebows have considerably shorter knockdowns. - - balance: Ebows now make you slur rather than stutter. - - balance: Large ebows are now heavy and bulky. - - rscdel: You can no longer order spinfusors or their ammo from cargo. - - rscdel: Removed the formal security officer jacket from the secdrobe - - tweak: formal security jackets are now armor vests - - rscdel: Bullets causing bleed rates equal to unmitigated damage through all forms - of defense. - - balance: 'Reverted #9092, crew mecha no longer spawn with tracking beacons.' - - balance: '[Port] Mecha ballistics weapons now require ammo created from an Exosuit - Fabricator or the Security Protolathe, though they will start with a full magazine - and in most cases enough for one full reload. Reloading these weapons no longer - chunks your power cell. Clown (and mime) mecha equipment have not changed.' - - balance: '[Port] The SRM-8 Missile Launcher has been replaced with the BRM-6 Breaching - Missile Launcher in techwebs (Nukie Mauler remains equipped with the SRM-8).' - - balance: '[Port] Both Missile Launchers and the Clusterbang Launcher do not have - an ammo cache, and cannot be reloaded by the pilot. Once the initial loaded - ammo has been spent, you can use the appropriate ammo box to load the weapon - directly.' - - rscadd: '[Port] Utility mechs that have a clamp equipped can load ammo from their - own cargo hold into other mechs.' - - rscadd: '[Port] Nuke Ops can purchase spare ammo duffel bags for their mecha weapons, - should they run low.' - - bugfix: Literally unclickability with a cham projector - nemvar: - - code_imp: Slight changes the self-repair borg module. It no longer references - the borg that owns it. - - bugfix: Trash from food now gets generated at the location of the food item, instead - of in the hands of the eater. - - code_imp: Changed mob biotypes from lists to flags. - r4d6: - - rscadd: Added a dwarf language - - rscadd: Added more engines - - tweak: RPD subcategories and preview icons reorganized. - - rscadd: RPD now starts with painting turned off, hitting pipes with build and - no paint will target the turf underneath instead. Bye bye turf pixelhunting. - - config: Made dwarves into a roundstart races - - tweak: Meteor Timer back to 3-5 minutes - - bugfix: Mining no longer lead to spess - - rscadd: Added Plasteel Pickaxe - - rscadd: Added Titanium Pickaxe - - bugfix: fixed a missing tile - tralezab, bandit, Skoglol: - - rscadd: The mime's PDA messages are silent now! - - rscadd: 30 new emoji have been added. Mime buff, mime now OP. -2020-03-28: - Arreksuru and Detective Google: - - rscadd: new HUDpatches for medical, diagnostic, and mesons. - - rscadd: crafting and de-crafting recipes for new HUDpatches. - - bugfix: silly typo with "singlasses" in one of the crafting recipes for HUDglasses. - Arturlang: - - balance: Bloodsuckers can no longer get usable blood from blood tomatoes. - - bugfix: Fixed reagent container transfer amount cycling. - Bhijn: - - tweak: Clicking an open closet with harm intent no longer attempts to place your - currently held item inside, but rather attacks it. - Bhijn (original PR by Azarak, sprites by Discord user Smug Asshole Muhreen#5522): - - rscadd: Synths, the open source and free-as-in-freedom species by FA user vader-san, - have been ported from Skyrat. - - rscadd: Ported VOREStation's synthetic taursprites - - rscadd: Markings that don't match very well with your selected species are now - hidden from the markings list by default. You can still use these mismatched - markings to create horrendous sparkledog abominations by using the "Show mismatched - markings" button ingame. - - bugfix: Body markings who's iconstates don't match their name will now actually - render properly. - - code_imp: Limb base icons are no longer hardcoded, should_draw_citadel and should_draw_grayscale - have been removed in favor of the species-level `icon_limbs` var and the bodypart-level - `base_bp_icon` and `color_src` vars. Downstreams should no longer have to touch - bodypart rendering code a whole lot if they want to add custom species. Downstreams - that have already added species with digitigrade leg support will have to append - species IDs to the digitigrade leg sprites, but aside from that, the migration - process to this more modularity-friendly system should be fairly smooth. - BlackMajor: - - tweak: Adjusted the ash walker camp's storm proofing. - - rscadd: Added a tip about creating areas to the ash walker spawn text. - Bumtickley00: - - tweak: Iron sheets build the normal metal table again - Crystal9156: - - bugfix: Fixes Chocolate Jelly Donut icon - Dennok, ported by Hatterhat: - - bugfix: Lava rivers no longer burn into basalt. - - code_imp: The river generator can now specify baseturfs. - Detective-Google: - - bugfix: absurd dong sizes. - - bugfix: my dumb stupid paramedics - - balance: Medical no longer spawns with syringe guns, Medical now spawns with medidart - guns. - EmeraldSundisk: - - rscadd: Adds CogStation's shuttles to-be. - - rscadd: Adds the "NES Classic" escape shuttle. - - refactor: Accounts for the new shuttles. - Ghommie: - - tweak: Added a few cooldowns to chill nuclear bomb and communications console - security level change spam, as well as the emergency shuttle's authorization - announcements. - - bugfix: Fixed viruses not working on anthros and some others species. - - sounddel: Made the cogchamp mixing sound less annoying. - - rscdel: Removed makeshift switchblades. - - bugfix: pAIs, drones, monkys and lizards can be worn over the head again. - - bugfix: Fixed cargo passive point generation to not go into decimals. - - bugfix: Syndicate ninjas are slightly less friendly now. - - balance: Allowed blobbernauts to drag objects (but not mobs) again. - - bugfix: The examiner circuit now works better for mobs. - - tweak: Chances are monkeys won't end up gorillizing as quickly after being exposed - to a rad storm for a minute or so. - - bugfix: Vampire mesmerize doesn't permanently disable combat mode. - - bugfix: The flying speed slowdown while hurt now actually affects flying mobs - and not floating ones. - - bugfix: Joining in as a positronic brain won't break the spawner menu anymore. - - bugfix: Fixed dynamic voting. - - bugfix: The autotransfer subsystem is slightly more modulable now. - - imageadd: Resprited some sprite_accessory icon states. - Ghommie (plus a fix originally done by Skogol): - - bugfix: Drinks dispensers now only show the container they are holding. - - bugfix: Ghost cafe patrons are warded against a few more events now. - - bugfix: Fixed RnD machineries UI displaying designs' required reagents' typepaths - instead of names. - Hatterhat: - - bugfix: Red and blue boxes are now actually red or blue. - - rscadd: Beegions! Like Legions, but with actual bees. As in, the bees from the - holodeck sim with the randomly-generated toxic bees. - - rscdel: Mining cyborgs are no longer physically capable of claiming points nor - wielding a premium accelerator. - - tweak: Arrow crafting has been finagled with, preventing fire-hardened arrows - from being fire-hardened repeatedly. Or something. - - bugfix: Space hermits (those quirky fellas stuck in a rock with carp surrounding - them) now have gravity! But they lost their perpetual generators. - - balance: Space hermits now have to mine for their research tech (golem vendor - board, ORM board). They have slightly less bad parts, though. And better(?) - rocks. - InnocentFire made the sprites all thanks to them!: - - imageadd: All bows now have inhand sprites once again - KathrinBailey: - - rscadd: Nine new posters! - - rscadd: Shower curtains can be crafted. - - rscadd: New sofas! - - rscadd: Green and purple comfy chairs to the crafting menu to fit green and purple - carpets. - - bugfix: Shower curtains now let you see through them once open, and don't once - closed. - Kraseo: - - balance: If you have the powersink objective, you will now receive a free beacon. - - rscadd: Lavaland flora have more traits now, to encourage harvesting and sending - these off to the botanists. - - bugfix: Napalm will now properly remove weeds from a tray if the plant in it has - the fireproof gene. - - balance: Gangs no longer get soporific rounds for their sniper rifles. - - rscadd: Syndicate Contracts. Use the new contract uplink to select a contract, - and bring the assigned target dead or alive to the designated drop off. Call - for the extraction pod and send them off for your TC payment, with much higher - rewards for keeping them alive. A high risk, high reward choice for a traitor - who wants a real challenge. - - rscadd: New 20 TC contract kit - supplies you with your contractor loadout and - uplink. - - rscadd: Targets successfully extracted will be held for ransom by the Syndicate - after their use to them is fulfilled. Central command covers the cost, but they'll - be taking a cut out of station funds to offset their loss... - - rscadd: Adds a third random item, as well as a small guide on using the contract - kit. Also added new possible items that can appear. - - tweak: Supplied space suit in the contract kit is now an improved variant on the - normal Syndicate version. - - balance: TC payouts adjusted to be a bit more fair to the contractor. Total payout - can never be below a certain threshold. - - bugfix: Broken dropoff locations work again, and general bugfixes. - - rscadd: Contract kit comes with a contractor baton - a unique, lightly electrified - weapon to help complete your contracts. - - tweak: Finalized payment system for contracts; much more balanced for contractors. - No more extremely low paying contract sets. - - tweak: Generated contracts will all have unique targets, no more duplicates. - - tweak: Extraction droppod explosion has been removed, it'll only damage the tile - it lands on. - - bugfix: Extraction pods get sent to the jail immediately again. - - refactor: Refactored classic_baton code. - - rscadd: Contractor Hub. A unique store for contractors to buy items with Contractor - Rep, with two Rep being given when completing a contract. - - rscadd: Contractor pinpointer, available through the Hub. A very inaccurate pinpointer - that ignores suit sensors. - - rscadd: Call reinforcements, available through the Hub. Limited to a one-time - buy for a contractor, you can purchase an agent to be sent down to help in your - mission. Role is polled to ghosts. - - rscadd: Blackout, available through the Hub. Disable station power for a small - duration - an expensive, but powerful option of getting into secure areas. - - rscadd: Fulton extraction, available through the Hub. Purchase a fulton extraction - kit to help move your targets across the station for those difficult dropoffs. - - tweak: Assigning yourself to another tablet will give you another contract set. - - rscadd: Contractors can now reroll their contracts a small number of times. - - rscadd: Brand new sprites! A redesign of the specialist space suit, and the kit's - own unique tablet. Done by Mey Ha Zah. - - tweak: Displays contract target jobs under their name. - - tweak: New locations, such as maintenance, are now possible dropoff locations. - - balance: Contractor kit pop cap reduced from 20 to 15. - - balance: You can no longer get haunted 8balls from contractor kits. - - bugfix: Pods and shuttles should no longer be valid dropoff locations. - - bugfix: Contract tablets will no longer break when one of your contracts is deleted - from the world. - - bugfix: Baton inhands for the right hand now shows the right direction. - - bugfix: Mice don't chew on wires anymore while they're on your person. - - bugfix: Bloodsucker heart theft objective now completes successfully. - - tweak: Blacklists turret protected areas, the toxins test range, asteroid ruins, - and solars from being valid dropoff locations for contracts. - Linzolle: - - tweak: pacifists can no longer meatspike living things - - bugfix: flypeople being unable to gain nutrition from eating vomit - - bugfix: targetting mouth on help intent now properly nose boops - - tweak: cmo hypokit now holds the same amount of items as normal kits - Moonlit Protector: - - rscadd: Introducing the 'Heroic Beacon', standing vigil over service the curator - can assume one three different historic heroes, each determining their equipment - and emergent playstyle to suit the player; a beacon can be found in the curator's - backpack upon spawning - - rscadd: Become the Braveheart, a fierce scottish warrior armed with a ceremonial - claymore, spraycan, kilt and a disregard for underwear with the scottish themed - hero pack. - - rscadd: A unique mention is the "First man on the Moon" heroic pack, with a two - piece space worthy suit, air tank & a GPS for recreating a key spessfaring moment - in history. - - tweak: The Curadrobe has been stripped & refilled full of helpful library supplies, - including varieties of pens and glasses including the jamjar's. - - tweak: The curator's explorer equipment & whip has been moved into the 'Courageous - Tomb Raider' heroic pack; removed from the backpack & the Curavend respectively. - MrJWhit: - - tweak: Added minor station things - - balance: re balanced r-walls - - tweak: Evens both sides of the gas containers TEG with reinforced windows - - tweak: Removed egun in every head locker, replaces RPD with air pump in science, - fixes a computer in sec, moves hand teleporter, and removes decals under lockers. - MrPerson: - - rscadd: Solar panels will visually rotate a lot more smoothly instead of being - locked to only 8 directions. - - rscadd: Timed solar tracking is in degrees per minute. You're still not gonna - use it though. - Naksu: - - rscadd: Time based free rerolls - - refactor: Refactored Blobs - - balance: Blob rerolls now give the blob 4 different options to choose from, rather - than forcing a single random one. - NecromancerAnne and goldnharl: - - imageadd: Sprite cleanups and animations for energy guns. - NecromancerAnne and zawo and zeroisthebiggay and carlarctg: - - rscadd: The Infiltrator Bundle, an armor kit for 3TC. Murder people in style! - - rscadd: Some pajamas for nukies to get plenty of bed rest. - - rscadd: halved firefight carry delay with latex or nitrile gloves - - tweak: headset upgrade is cheaper - Owai-Seek: - - rscadd: Butter Bear - - rscadd: Crab Burger, Bisque, Crab Rangoon, French Onion Soup, Empowered Burger, - Chicken Nugget box. - - tweak: +++ Spider Eggs to Exotic Meat crate. --- Bacon from Exotic Meat crate. - - tweak: Tweaked Crab Recipes - - imageadd: Butter Bear aka Terrygold - - balance: Food Crafting is now 5 deciseconds instead of 30. - Putnam: - - tweak: Swarmers, portal storm, wormholes are now controlled by dynamic. - - tweak: Dynamic-controlled events can now have a minimum start time. - - balance: Threatening meteors are more common (though still have pretty strict - requirements) - - balance: Different storytellers now balance around different expected players-per-antag; - default was 5, now intrigue/story/random have 7 and calm has 10. - - rscadd: Clown ops is now available as a roundstart antag in dynamic. - - balance: Sentient disease and revenant are now in the event pool rather than the - antag pool (with the logic that they're both completely useless and unfun to - play if people are actually playing against them). - - rscadd: A new formulation of extended was added to the storytellers; no antags, - but still spending threat on events. - - bugfix: Fixed a runtime in dynamic due to my misunderstanding pickweightAllowZero - - rscdel: Made conversion storyteller 0-weight-by-default. - Putnam3145: - - tweak: Salbutamol causes jittering now. - - bugfix: Made lickable pref save - - rscadd: 'Traitor classes for traitors: a new way for traitors to have objectives - assigned.' - - bugfix: Actually made things work as intended. - - code_imp: Removed a redundant turf melting check from the supermatter. - - rscdel: Removed "realistic tcomms lag" - - rscdel: Removed some particularly bad flavor objectives. - - balance: Power sink objective is 10x as easy to get - - bugfix: Processing objectives now properly stop once won - - rscdel: MKUltra no longer explodes into lovegas when it fermi explodes, instead - causing a regular ol' fireball. - - tweak: Eigenstasium OD flavor text less restrictive - - bugfix: Dynamic voting should work absent of a config. - - tweak: Autotransfer vote now requires actual transfer votes to transfer. - - bugfix: More dynamic fixes - - bugfix: Server-run votes aren't subject to vote cooldown - - rscadd: Mass hallucination can better be admemed - - tweak: Waffle co objective rewritten to make more clear it's not a murderbone - objective - - rscadd: CTF spawns, random animals and possessed blades can now be pinged for - ghost roles. - - bugfix: A bunch of polls now work with ghost role eligible non-observers. - - bugfix: Removes superfluous line in supermatter processing. - - code_imp: Power sink objective processing now makes sense. - Qustinnus/floyd, Ghommie: - - bugfix: To save costs, Nanotrasen has removed the emergency battery ejection systems - in modular computers. We realized saving the batteries isn't really important. - - bugfix: You can squash spiderlings with your bare hands now. - - bugfix: Being deafened properly stops jukebox music from playing. - - bugfix: admin multicam toggles no longer tells everyone but only admins and AIs - Ragolution: - - rscadd: All winter coats and hoods might be different if slightly from one a other. - - tweak: Adjusted Bartender's Drink Flinging print message to not include name of - target turf and save immersion. - Seris02: - - rscadd: tg genetics - - balance: illegal technology - - balance: rebalanced rising bass's buttom actions from repulse to side kick - - bugfix: projectiles and rising bass and items and rising bass - - bugfix: a very specific fix with tails and wagging - - rscadd: duffel bags of holding - - bugfix: quirk blacklist fixing - - bugfix: robotics console button swapping - - bugfix: fixed thieving gloves not pickpocketing fast - - rscadd: mentor de/rementor button - - bugfix: mentor !msg - - balance: bloodsuckers being unable to accept genes - - balance: removes xray from the gene pool - Skoglol: - - bugfix: Fixed gibber exploit. - Timberpoes: - - bugfix: 'Shuttle countdowns once again read like "01:05" instead of "01: 5".' - Trilbyspaceclone: - - rscadd: Three new arm implants, shield for sec, janitor and service - - rscadd: Two new legion drop. Assistant and Bee-Activist - - rscadd: Three new posters have been issued to the printing press - - rscadd: Well contruction, grubs to ash walker home, more seeds for ash walkers. - - rscadd: Wooden buckets can be made from 2 planks of wood, Tower caps also can - be used on a fire to make coal - - tweak: Makes all ashwalker round start seeds 5 yield and 50 harvest so that they - can get good crops in rather then failing after 1 harvest - - bugfix: arrow crafting has been fixed - - balance: Blobs now can store 250 points. - - spellcheck: Alien bar stool is no longer bronze - - server: 28 days log changlogs have been added well 56+ day old changlogs have - been removed - - balance: Added sunglasses that are able to be huds AND prescription - - rscadd: Prescription sunglasses and crafting of each new type for - Diagnostic, - Med and Sec - - rscadd: Diagnostic Sunglasses - - bugfix: Blackists Prescription HUDs from sunglasses crafting - - tweak: Cotton/Durathread now stack to 80 bundles - - rscadd: Medical hardsuits now have a Medi-Hud built into its helm - - rscdel: Removed old unused Techweb Node selling - - imageadd: Corrects snowcones names and a pixle. Corrects Space Wind snowcone as - well - - bugfix: Arrow crafting has been fixed... Again... - - rscadd: Soidifaction of and uranium can be done as well as making new bluespace - shards - - balance: Xeno and Fountain Hall will no longer spawn more then once - - tweak: Makes the game want to spawn in more then one tumor maybe - - tweak: Number of paper work in the crate "freelance paperwork" is half - - code_imp: A few cases were something their is unneeded copy past replaced with - many 1 in spawns - - rscadd: Potass Iodide has been fitted into standered borgs as well as medical - ones. Upgraded hypos now have Prussian Blue as well. - - tweak: Syndi borgs Potass Iodide has been swapped for Prussian Blue - - bugfix: No longer can you get the The End and Russian Flask without being the - donator - - balance: Pipes are small now - - bugfix: Edaggers now enbed as intended - - rscadd: The sleeper agents can be outfitted with some larger then normal sunglasses - for 1TC in Badass category - - rscadd: The Syndi Medical borg has been outfitted with the newest and latest ~~Stolen~~ - MediCo Gear on the market - - rscadd: Ninjas may be asked to steal the CMO's smart drapes - - tweak: Hyper Cell steal goal is upgraded to a bluespace cell, as well as the BoH - goal now wants a type of BoH rather then the normal default one. - - rscadd: Gutlunches have gotten teeth now and will eat legs, arms, and organs! - - Tho are picky and will not eat the brain just laying about! - Useroth: - - bugfix: contractor tablets spawned with invalid icon_state - Xantholne: - - rscadd: Bumbles is now actually in every station's hydroponics. - - bugfix: Bumbles will now actually rest, sit up, and buzz - YakumoChen: - - imageadd: Nekomata (double cat) tails. - - imageadd: 2CAT LMAO - - bugfix: Mining base looks more natural where it's spawned. - - server: Templates Headers will now correctly use the Citadel Official Wiki Link - Yenwodyah: - - bugfix: Bear traps and bolas apply slowdown correctly again - - bugfix: Recycler doesn't delete people in mechs, cardboard boxes, spells, etc. - anymore. - actioninja, ninjanomnom: - - tweak: Being fat is no longer lessened by flying. - - bugfix: The slowdown from grabbing someone no longer applies when you're floating. - bunny232: - - rscadd: Box bar now has a lightswitch. - - bugfix: fixes several piping issues around box station - - bugfix: moved a scrubber and vent down 5 pixels - - rscadd: Box station captain office now has a standard issue renault - - bugfix: Box bridge now actually has the air distro connected - dapnee: - - rscadd: Lambdastation and it's accompanying files - - rscadd: Robotic's APC, a few missing buttons (bridge shutters and crematorium), - paramedic has spawn locations now, two rapid cable deployers to engineering - - tweak: Renamed some doors and edited engineering to be a bit more open in one - spot - - bugfix: a few APCs with bad area tags, access on maintenance doors fixed, engine - APC is now connected to the grid instead of power created by the engine - - rscdel: the two syringe guns in medical were removed - - rscadd: couple gas masks around atmos - - bugfix: direction on turbine plasma pressure tank, cloning actually has a cloning - console now - floyd: - - bugfix: Everything made from glass in the game has a little more tegridy and doesnt - break from a single punch. - kappa-sama: - - rscdel: removed laptops giving slowdown when open - - balance: removed (mostly aesthetic) requirement to become hulk - - bugfix: changed add to remove on crit - - rscadd: a super combat shotgun that loads and fires 2 shells at a time - - balance: replaces bubblegum's blood contract drop with the super shotgun - - balance: 60 seconds instead of 120 for firebreath - keronshb: - - balance: blobs now receive a 50% cost refund on attacks that don't spread - - balance: reflector blobs are considerably tougher - - bugfix: fixed an integrity - - bugfix: attempting to turn a damaged strong blob into a reflector blob now refunds - points - - bugfix: also fixes blob node camera jump (from another PR) - kevinz000: - - code_imp: Mobility flags are here. Fixed some edge cases with xeno hardstuns and - similar stuff like warden's shotgun hardstuns and yeah. - - rscadd: Security now has riot quarterstaves in their lethal shotgun locker. - - tweak: Pushing is no longer free space movement. - - tweak: You can now right click to point the tip of some sharp tipped weapons at - people. - - bugfix: compact defibs have 10k cells again - - tweak: music max characters per line is now 150 instead of 50. - - bugfix: storage no longer closes while being dragged - - balance: disabler taser alt fire shots are faster and have a 14 tile range now - - balance: HoS taser now only applies tased effect for 1 second and warden's pump - action stun blaster no longer applies it at all. - - balance: Nanite adrenals have been nerfed. - - balance: Ninja stungloves nerfed 49 stamina to 25 (so they're basically just better - than stunbatons). - - tweak: Batons now also trigger disarm behavior in disarm intent and not just on - right click. - - refactor: combat mode/sprint/resisting lying down/attempting to crawl under all - refactored, added combat/sprint mode lockouts, being locked out of combat mode - no longer disables it and allows right click interactions etc etc - - bugfix: hands free actions no longer check mobility and only consciousness. - - rscadd: Minimaps, accessible via a button on OOC. - - bugfix: unnecessary blindness post-unconsciouss has been fixed with a hack that's - almost as garbage as the code that caused it in the first place. - - bugfix: synthflesh and rezadone now take total amounts of both applied and existing - reagents rather than only existing and only applied respectively. - - balance: reverts bubblegum bloodling swarming. - - balance: Beam rifles shot count 10 --> 5 and can no longer pierce. Also renders - properly for reflections against blobs and some other things. - - bugfix: being stunned no longer stops an ai from undeploying from a shell. - - bugfix: beam rifles are less terrible code - - code_imp: slowdown on items should now be set by set_slowdown(). - - bugfix: hypereutactic blades properly slow down their wielders when being used - and vv-editing an item's slowdown will once again properly update someone's - slowdown to take the new value into account. - - balance: stunprods knockdown again. - monster860: - - tweak: You can now moan in soft crit - - rscadd: Use Ctrl-Shift-direction key to shift your characters position. Use for - ERP. - necromanceranne: - - rscadd: Ports New Sleeping Carp - - refactor: Ports the martial arts refactors, which includes things like moving - martial into the martial subfolder and renaming it _martial, and cleans up human_defense - rising bass/sleeping carp exclusive code. - - balance: Particle Defender is now a much more sane weapon. - - balance: Tasers are no longer ignoring stimulants. - - bugfix: Blood beam can't create harvesters out of mech pilots. - - code_imp: Some minor fixes to fakedeath and a tg fix port. - - bugfix: Bleeding out all your blood from getting love tapped by a toolbox. - - bugfix: Diagnostic HUDSunglasses are better than ever! - - bugfix: Sprite fixes I hope - - balance: You can no longer acquire stun bullets in the .45 calibre. You can get - the 30 damage version out of the autolathe instead. - - balance: KITCHEN GUN (TM) is a lot stronger. Cleaning bullets are a whole 40 damage! - - bugfix: Fixed turrets not allowing their guns to be recovered. - - balance: Altered the plastitanium rapier from a perfect AP but weaker esword equivalent - to a more unique sleep inducing melee weapon. - - rscadd: Touched up all the relevant sprites. - - balance: Nightvision goggles are nerfed all-round. Flashes have actual use against - people using nightvision, as do flashbangs. - - balance: Syndicate nuclear agents get to live peacefully knowing their eyes are - well protected by their special night vision goggles. Spider clan also get these - goggles. - raspyosu: - - rscadd: some flavor text for lunge, cloak - - tweak: mesmerize, cloak functionality/requirements - - balance: mesmerize, lunge, cloak - - soundadd: lunge telegraph sound - - spellcheck: mesmerized status icon flavor text - - bugfix: cloak sometimes not restoring initial move intent - - tweak: mesmerize (line of sight checking system and remove progress bar) - - balance: 'nerf: lunge, mesmerize' - spookydonut: - - code_imp: adds selective duplicate component mode - wesoda25: - - code_imp: You no longer hit fermenting barrels when taking reagents from them - zeroisthebiggay: - - rscadd: kilo shuttle less bad - - rscadd: tauric contractor space suits - - tweak: ghost hud and nv defaults on - - bugfix: syndicate elite hardsuit helmet doesnt hide masks anymore - - balance: syndicate contractor helmets are no longer secretly lead - - rscadd: Space Fashion has discovered a new way to wear bandannas. With some simple - minor adjustments and ties, bandannas can be made into fashionable neckerchiefs! - - rscadd: Box Station has gotten a brand new brig. Go and check it out and discover - all the quirky little soulbits. - - bugfix: box brig miscellaneous issues - - bugfix: box station hos office -2020-04-15: - Arturlang: - - rscadd: Adds garlic, a mutation of onions - - rscadd: You can now make garlic necklaces. - - tweak: Tweaked hunger to be more the same as blood level for bloodsuckers - - tweak: Bloodsuckers no longer get zero healing from regenerative cores, the core - now heals their wounds but not their blood. - - balance: Bloodsucker heal is now based a lot more on blood level. - - bugfix: You can no longer be effectively immortal when fully auged as a bloodsucker. - - bugfix: Regenerative cores will regain their old names when they are renewed, - no more working decayed cores. - - code_imp: Removes a lot of unnecesiry clutter of comments and tries to make the - vars more consistent for bloodsucker code. - - code_imp: Made the regenerative core use one proc instead of copypasta - Auris456852: - - rscadd: Added printer sound for admins that plays when someone messages Centcomm - or the Syndicate. Just like RP! - Bhijn: - - admin: The traitor panel now actually shows a list of contractor targets. - - server: Fail2Topic now supports Linux. Do beware that this requires some sysop - experience to properly set up! - - config: Fail2Topic is now disabled by default, and the out-of-the-box config files - have been updated to be a little more detailed. - - rscadd: Added a lfwb-inspired orbiting pixel + flashing outline animation to the - sprint and combat mode buttons. This can be toggled via the preferences menu, - and is completely independent from all HUD themes. - BuffEngineering: - - bugfix: You may no longer summon plasteel from the door dimension. - - tweak: High security airlocks are now 33% more materially efficient! - DeltaFire15: - - balance: clockie vanguard now quickly regenerates stam while active (as its description - always told you,) - Detective-Google: - - balance: Shotguns are now slower and require two hands to fire. - Ghommie: - - bugfix: mobs with antag statuses such as wizard, ert and nuke ops get their flavor - text removed now. - - bugfix: Fixed megafauna mobs, goliaths and "anchored" AIs being stuffable into - closets. - - bugfix: After years of visual agony, the Curse of The Floating Disembodied Phallus - has come to an end. - - rscadd: Underwear now fulfills its purpose. - - rscadd: Privates visibility preferences. - - refactor: refactored polychromic clothing into an element. - - tweak: Blacklists unsynthetizable reagents from botany bees honey production. - - bugfix: Fixed toilet cistern loot spawning on the floor. - - tweak: The megafauna's hitbox doesn't include 0 alpha sections anymore. - - bugfix: Wizard robes & co work again now. - - bugfix: Fixed some spell casting message spam. - - rscadd: Added M/F body preferences. - - bugfix: fixed yet another few airless issues with the space hermit ruin. - - bugfix: Intellectual property infringment is not cool. - - bugfix: Near-station nuclear explosions now display the on-station nuke explosion - cinematic, consistently with its clearance of the station level and its nuclear - victory / total annihilation ending status. - - balance: Nuclear bombs can't be anchored in space areas (not just turfs) anymore, - as a quick effortless way to discourage players from anchoring the device on - the edge of the map. - - bugfix: Fixed a whacky miniature cell duping issue. - - bugfix: Liver failure is back! - - tweak: standarized a few (prefs off) side effects from enlargment chems on livers - to do organ damage instead without the blood volume whackiness. - - tweak: High liver damage now slows mobs down. - - bugfix: Fixing an issue with the split personality removing the original owner - from the round if the body died while the stranger was in control. - - bugfix: fixed a few floaty sprite accessories. - - bugfix: Fixed a few mutations not working correctly. - - bugfix: Fixed the phantom thief component, again. - - refactor: Made votes obfuscation settings more robust. - - admin: Also included them in custom votes. - - tweak: The map rotation vote will only hide ongoing votes now, not the results. - - balance: The crusher's vortex talisman trophy now has a cooldown between each - spawned wall. - - refactor: Backend body size preferences. - - bugfix: Infiltrator's boots don't stop slips and "space wind" through the power - of runtime errors anymore, and properly silence the user's footsteps now. - - tweak: Chaplains are now inelegible for bloodsuckers. - - bugfix: Fixed crafting hud icon overlapping the second pocket on 1:1 screen mode. - - code_imp: Removed some dead flightsuit code leftovers. - - rscadd: Reenabled the swarmers event. Also blacklisted another dozen other machineries - and structures that may be critical to the shift or station integrity from swarmers' - HUNGER for materials. - - bugfix: Fixed find_safe_turfs() searching for turfs with concentration of oxygen - lower than 16 rather higher. - KathrinBailey: - - rscadd: Radiation shuttesr to all supermatters. - - rscadd: Windowed shutters to armouries where relevant. - - rscadd: New posters are now on the map in relevant locations. - - bugfix: Windowed shutter now has glass, the door closing proc sees this and no - longer changes opacity. - - bugfix: Accidental HoochMaster removal in the bar. - - bugfix: Spawning looking at the supermatter with no mesons on Meta. - - bugfix: Missing disposal pipe outside HoP office. - - bugfix: Sofas were never adjusted when the pool was added. - - rscadd: New shutter sprites - - rscadd: Reinforced Shutter - - rscadd: Radiation Shutter - - rscadd: Window Shutter - - tweak: Shutters not being blast doors functionally. - - balance: Shutter armour block and health. - Kraseo: - - balance: Sneaksuit now costs 5 TC rather than 3. - - bugfix: You can break out of neckgrabs once more. - Owai-Seek: - - rscadd: Port Pina Colada, Painkiller, Moscow Mule, Hivemind Eraser, Moana Lou - Drinks - - rscadd: Gunfire, Hellfire, Sins Delight, Strawberry Daiquiri, Miami Vice, Malibu - Sunset, Lizz Fizz, Hotline Miami - - rscadd: Strawberry and Pineapple Juice - - rscadd: Salami Slices - - tweak: Soda Dispenser Juices - - tweak: Reorganize Vendor Objects (Bowls, Glasses, Shot Glasses) - - tweak: Strawberry Milk and Tea actually use strawberry Juice. - - tweak: Lizards can eat egg wraps. Moved Egg Wraps to Misc - PersianXerxes: - - rscadd: 'TGUI Next UIs for: chem heaters, chem masters, chem dispensers, and sleepers' - - code_imp: Reworked Chem Master code - Putnam3145: - - rscdel: No more station integrity goal - - tweak: Upload-hacked-law goal only picksif there's an AI to upload to - - rscadd: A new, much more barebones holding facility for contractors. - - rscdel: Energy nets are gone. - - tweak: Various ghost roles are now easier to ghost as. - - tweak: The candles in the dojo no longer make the place hotter and hotter over - time. - - rscdel: Nymphomania removed - - code_imp: Exhibitionism ignored by preferences now, since it was also removed - - code_imp: Quirk migration now does an admin log instead of a stack trace - - bugfix: Roundstart rulesets now roll properly. - - config: Added configs for various antag threat levels. - - bugfix: Fixed a runtime in threat calculation. - - tweak: Fixed up some misleading texts. - - tweak: 'Dynamic reworked to be more "storyteller-like": threat is now how threatened - the station is right now and threat level is how much the mode wants the station - to be threatened.' - - tweak: Random storyteller is now truly random. - - tweak: Story storyteller now gives a nice rising-action-climax-falling action - curve for threat level. - - tweak: '"Chaotic" storyteller now simply ramps up threat level as round goes on.' - - rscadd: '"Classic" storyteller, basically doing what "random" did before.' - - rscadd: Latejoin changelings for dynamic - - bugfix: Average threat calculation works now - - bugfix: Contamination is back. - Seris02: - - balance: stops hijackers from being able to remotely blow up borgs - - rscadd: wall walking boots - - bugfix: made color picking for character appearance show the colors when you pick - them - - tweak: the sergal markings - Trilbyspaceclone: - - rscadd: Cooks aided by Clowns have came out with and new healthy Salad - Caesar - Salad. Just dont eat the knife... - - rscadd: Ports over TG's Mortars and Pestles. - - balance: Water, Holywater and Unholywater will now now quickly purge itself if - you have 151u in your system - - rscadd: Most crate types can now be made, some costing more do to function over - fashion - - rscadd: Medical Mechs syringe gun now knows many more life saving chems, like - Insulin, Dexalin, Prussian Blue, Kelotane and Bicaridine - - balance: torches take less staminda to use. - - balance: Glowsticks dont last as long - - balance: Penlights are better at being lights - - balance: Torches are brighter then before - Indian Johns want to be on lava land - rejoy! - - balance: Eye lights have 30% less light coming out of them. - - spellcheck: Spec Ops crate no longer talks about a "Null Crate" what ever that - is - - server: Changlogs are updateded once again as of the 28th of March on year 2020 - - balance: White Ships, Telerelays and a defunk mining post are now always going - to spawn. - - spellcheck: Corrects a few desc on station side ruins - Xantholne: - - bugfix: bumbles will stop sleeping so much - actioninja: - - rscadd: Washing machines now support arbitrary dye color - - rscadd: Washing machines now dye nearly every item. - - refactor: lots of backend changes to clothing overlays, report any issues - - rscadd: Better glowing lights - actioninja (ported by Ghommie): - - refactor: repathed all under clothing, keep an eye out for errors. - bunny232: - - bugfix: Box secmos now is now longer connected to the scrubber loop - dapnee: - - rscadd: plant disk sorter in botany, bounty console for the rest of cargo, a missing - air alarm in the incinerator - - tweak: fixed a decal in front of security, moved an AIR alarm so it doesn't look - awful to ghosts/AI, asteroids don't delete air anymore, fixed more active turfs, - the buttons in the bridge "should" work now, HoP and cargo desks should be secure - now - - rscdel: quarters that found their way out of the quartermaster's back room - kappa-sama: - - rscdel: normies can no longer steal circuit codes - - balance: doubles the Stam damage of nonlethal krav stompers - - bugfix: no longer Krav Maga stomp people that are standing - - balance: no more 20pop requirement for noslips - keronshb: - - tweak: Reverts Mining Base RNG Placement - kevinz000: - - rscadd: Melee attacks now stagger people, preventing them from sprinting until - the (relatively short lived) effect runs out. Duration equation is [(1.5 + (w_class/7.5)) - * force]. - - balance: Fireman carrying now makes the person being carried unable to use items. - Piggybacking now slows down the person being ridden. In both cases, the person - riding will be dazed when forcefully dismounted, and dazed for a second if dismounting - from piggybacking - - bugfix: turfs properly initialize atom colors if they're colored. - - tweak: cloners now stabilize mutations while someone's cloning, meaning active - genes will not life tick. - - code_imp: datum/pipeline return_air stack trace now gives a reference so it's - actually marginally useful if caught in round. - - rscadd: Volumetric storage is here. - - rscadd: Traitor chaplains can now become neutered versions of cults. - - bugfix: beams should no longer go across the map and mess everything up if their - source or target isn't on a turf. - kiwedespars: - - rscadd: Added paper masks. - necromanceranne: - - bugfix: Fixed limb damage calc - - tweak: Stunslugs are now a mixed damage taser-like slug that will allow you to - apply a variety of damage while still being countered by tasers usual counters. - - balance: Mech scattershot guns are no longer oneshotting people into stamina crit. - - rscdel: 'Removed an number of cargo crate packs: Riot shotguns/standard shotguns, - double barreled shotguns, techshell crate, swat tasers, WT550 types (not rubber - or standard), traitor theft objective kits.' - - balance: HEALTH AND STAMINA DON'T STACK FOR PUTTING YOU INTO STAMINA CRIT. - - balance: YOUR FISTS ARE HELLA GODDAMN STRONG. - - balance: 'ACCEPT THE FELINIDS WARES, FOR SKOOMA HAS INCREDIBLE LETHAL PROPERTIES: - YOUR HANDS BECOME LIKE SWORDS.' - - balance: BOXERS CAN ONLY KNOCK OUT OTHER BOXERS BECAUSE THEY HAVE HONOR OR SOME - SHIT - - balance: INCREASED STAMINA DAMAGE TO LIMBS FROM 50% TO 75%. - - balance: Double-barreled shotguns and any child of such now can be used with off-hand - equipment. - - rscadd: Readds bioterror darts to the nuclear operative uplink for the legacy - price of 6tc! Has all new horrid reagents! - - balance: Scatterlaser is now in-line with buckshot. Nukies can't purchase scatterlaser - shot. - - rscdel: Null crates are no longer available in cargo! - - bugfix: Sleeping Carp and Rising Bass now dodge. Again. - - bugfix: Russian Revolver can no longer be exploited for a free 357. - - balance: Several guns now shoot exactly where you click regardless of movement - or turning. - timothyteakettle: - - rscadd: added beacon for cooks to choose an ingredient box, which replaces the - random box they used to receive - - rscadd: added a new sushi ingredients box - - rscadd: added more items to the wildcard box's possible contents - - rscadd: add new holodeck wrestling belt which lets you use moves only on those - also wearing it - - rscadd: add new holodeck map featuring the holodeck wrestling belt - - rscadd: new reagent 'Condensed Cooking Oil' - - tweak: list of chems that can go into fried non-food items was changed - zeroisthebiggay: - - rscadd: sneaksuit to contractor items - - tweak: sneaksuit is a bundle - - rscdel: intel potion and radio implant from contractor items - - rscadd: ghosts can now DNR - - balance: sneaksuit is not fireproof - - bugfix: insidious balaclava muzzlepsprite works - - rscadd: You can now choose your name and color as a holoparasite/guardian/holocarp! - - bugfix: fixes lings being able to get mechanical holoparasites -2020-04-16: - ForrestWick: - - tweak: changed a certain item to be called meatball, ended racism, thank you obama - Linzolle: - - tweak: remove any slurs, etc. to comply with GitHub's ToS -2020-04-19: - Anonymous: - - rscadd: Xenohybrids will now scream like xeno. - Arturlang: - - bugfix: You can no longer spam craft things using the crafting menu - Detective-Google: - - bugfix: uncorks some of Lambda's rooms. - Ghommie: - - rscadd: Custom skin tone preferences. - - tweak: Normalized box dorm lockers. Also removed a straight jacket found in the - same area. - Jake Park: - - bugfix: fixed path name for youtool vending - Putnam3145: - - bugfix: Objectives now clean theirselves up instead of leaving null entries in - lists everywhere. - Seris02: - - bugfix: stops magboots from not updating slowdowns - Trilbyspaceclone: - - rscadd: Maints have seen an uptick in left over types of welders, and tools. As - well as different types of masks - - rscadd: New type of 02 locker - Rng! It can have almost any type of gas/breath - mask and almost any type of o2 tank as well as even plasma men internals - Fancy! - - tweak: Tool lockers have 70% odds to have a spare random tool inside! - - rscadd: 12 new more drinks for most races! - - rscadd: New animations for mauna loa, and colour swap from red to blue for a Paramedic - Hardsuit helm - - tweak: Lowers cog champ ((the drink)) flare rate - - rscadd: Six more Sci based bounties have been posted at your local Cargo Bounty - Request console - - bugfix: Mimes have made catnip plants not become invisible. How helpful. - - rscadd: Honey Palm now distills into mead rather then wine - UristMcAstronaut: - - rscadd: Adds circuit analyzers to maps and to integrated circuit printer and circuitry - starter crate. - kappa-sama: - - balance: aranesp heals 10 instead of 18 stamina per tick - - rscdel: removed roundstart hyper earrape screams from xenohybrids - kevinz000: - - bugfix: you can no longer stun xenos - - balance: Contractor kits are now poplocked to 30 players. - - rscadd: Shield bashing has been added - necromanceranne: - - rscadd: You can now craft armwraps! - - balance: Pugilists disarm you more easily and are harder to disarm. They also - get a discount on disarm. - - balance: Pugilists only suffer a flat 10% chance to miss you. It's just like old - punches! Kinda. - - balance: Chaplain's armbands are a +2, up from a +1! - - balance: Martial artists spend stamina when they disarm. - - balance: Rising Bass had several moves shortened and made stronger. Has a disarm - override attack which does stamina damage and trips people on a disarm stun - punch. - - balance: CQC had it's disarm move altered to be a stronger version of Krav Maga's. - Dizzies and disarms on a disarm stun punch or just does some stamina damage - and brute damage. - - balance: Sleeping Carp can punch you to the floor on a harm stun punch. - - bugfix: Hugs of the Northstar are no longer nodrop. - - bugfix: Adding in some overrides and proper flag checks for martial arts. - - bugfix: Stun thresholding stops disarm spams at extremely high stamina loss. - - tweak: Ashen Arrows are actually called Ashen Arrows in the crafting menu. -2020-06-08: - DeltaFire15: - - bugfix: Delinging now properly removes their special role - - balance: Keycard auth devices now require two seperate IDs with sufficient access - to auth. - Linzolle: - - bugfix: shotguns no longer delete chambered shells while firing - kevinz000: - - rscadd: test - - rscdel: test - shellspeed1: - - rscadd: Internal tanks are now printable at the engineering lathe. - timothyteakettle: - - bugfix: newly created areas using blueprints now maintain the previous areas noteleport - value - - bugfix: kudzu seeds now actually spawn vines -2020-06-09: - Anonymous: - - rscadd: Added Orville-inspired clothing as a worthy alternative to Trek stuff. - - tweak: Adds chaplain role allowance to the TMP Service Uniform loadout. - - tweak: Adds paramedic in every medsci mentioned uniform loadout. - DeltaFire15: - - bugfix: Offstation AIs can once again only interact with their z-level - Ghommie: - - bugfix: Fixing IC material containers interaction with stacks, for real. - Trilbyspaceclone: - - tweak: Gasses like BZ and Masiam seem to just sell for less in cargo, markets - seem to change it seems - kevinz000: - - balance: plantpeople should stop dying in the halls now - - rscadd: Modifier-independent hotkey bindings have been added. -2020-06-10: - DeltaFire15: - - bugfix: Golems / simillar now inherit the neutered antag datum if the creator - is neutered. - Ghommie: - - bugfix: Fixing missing pill type buttons from the chem master UI. - Naksu: - - code_imp: Lighting corner updates are ever so slightly faster. - Putnam for helping me code the contamination clearing on people: - - rscadd: Lab made Zeolites have been remade anew and more affective now that they - refined the best possable way to mix and make a supper Zeolite capable of clearing - contamination form not only people but items! - Trilbyspaceclone: - - tweak: Tank Dispender has been moved into toxin storage from toxins - kevinz000: - - rscadd: traitor classes can now be poplocked. hijack/glorious death are now locked - to 25/20 respectively. - timothyteakettle: - - rscadd: adds a new fermichem, used for creating sentient plushies! - - rscadd: Mice can now breed using cheese wedges - - rscadd: Royal cheese can be crafted to convert a mouse into king rat -2020-06-11: - Ghommie: - - balance: Balanced vending machine prices to be generally more affordable, a minority - has been priced up though. -2020-06-12: - EmeraldSundisk: - - tweak: The Detective's Office has been commandeered in order to serve a Head of - Security. Detectives will find their new office within starboard maintenance. - - rscadd: Adds the Head of Security's standard equipment to their new office. - - tweak: Slight adjustment/expansion to the main security department - - rscadd: Additional maintenance work - timothyteakettle: - - rscadd: Crabs, cockroaches, slimes and crabs are now small enough to fit in pet - carriers -2020-06-14: - Bhijn: - - bugfix: raw HTML can no longer be used in flavortext - - rscadd: Added Lesbian Visibility Day (April 26th) - - rscadd: Added Bisexual Visibility Day (September 23rd) - - rscadd: Added Coming Out Day! (October 11th) - - rscadd: Added Intersex Awareness Day (October 26th) - - rscadd: Added Transgender Awareness Week (November 13th - 19th) - - rscadd: Added the Transgender Day of Remembrance (November 20th) - - rscadd: Added Asexual Awareness Week (Last full week of October, this year it'll - be Oct. 25-31) - - rscadd: Added the Stonewall Riot Anniversary (June 28) - - bugfix: Moth week is now *actually* the last full week of July, instead of the - 4th of every weekday + the 5th Sunday. - Floof Ball / Kathrin Morrison / Floof Ball#0798: - - rscadd: Improvised Pistol + 32 ACP ammo. - - rscadd: Improvised Energy Gun. Fires 5 shots of 10 burn damage each. Can be upgraded - with a lens made from glassworking and T4 parts for a minor buff. - - rscadd: Ammo + gun part loot spawners for mappers. - - rscadd: New sprites for Improvised Rifle, the ability to sling the rifle and a - sprite for that. - - rscadd: New sprites for the Improvised Shotgun and its sling sprite. - - balance: Improvised shotguns are now two-handed only. - - balance: Improvised shotguns now only have a much less harsh 0.9* modifier, keeping - them two hits to crit with slugs and buckshot. It can no longer be dual-wielded - but can still be sawn off for w_class medium (can fit in backpacks). - - bugfix: Missing handsaw icons added in. - - tweak: Crafting table cleaned up into sections. - Ghommie: - - tweak: changed the weak attack message prefix from "inefficiently" to "limply", - "feebly" and "saplessly" and lowered the threshold. - - bugfix: Fixing old beserker hardsuits having the wrong helmet type. - The0bserver and Stewydeadmike: - - rscadd: Hey, there's a bit of dust in this recipe book! Recipes using peas? How - many recipes does this book even have? - - rscadd: Adds 6 new food items, and 1 new consumable reagent using all forms of - the recently discovered peas. Ask your local botanist and chef for them today! - YakumoChen: - - tweak: Adds polychrome options to loadout - - tweak: Adds risque polychrome options to Kinkmate vendors - kevinz000: - - bugfix: emissive blockers can no longer be radioactive. - - rscadd: Ghosts can now scan air inside most objects that contain air by clicking - on them. - - rscadd: Directional blocking has been added, keybound to G. This will reduce a - portion of incoming damage if done with eligible items at the cost of stamina - damage incurred to the user based on damage blocked as well as while active, - as well as in most cases preventing the user from doing any attacks while this - is active. - - rscadd: Parrying has been added, keybound to F. Timing-based counterattacks, effect - heavily dependent on the item, WIP. - - balance: Disks are now smaller. -2020-06-15: - Anturk, kevinz000: - - bugfix: VV now properly allows access to datums in associative lists - - rscadd: SDQL2 printout has been upgraded for the 5th time. - kevinz000: - - bugfix: plushies now work. credits to timothytea. - - rscadd: You can now tape knives to cleanbots - kevinz000 (port from VOREStation): - - imageadd: Ported zoomba skins for cyborgs. -2020-06-16: - Ghommie: - - bugfix: You can't blink nor use LOOC/AOOC as a petrified statue anymore. - Trilbyspaceclone: - - tweak: BEPIS decal painter has been moved to venders, replacing it being the flashdark - kevinz000: - - refactor: projectile ricochets now use a less hilariously terrible way of being - handled and should be easier to w - - bugfix: projectile runtime/ricocheting - - balance: Lobotomy no longer has a 50% chance of giving you a nigh-unremovable - trauma, but does 50 brain damage even on success. On failure, it will give you - a lobotomy-class trauma. - - balance: spinesnapping from tackling now only gives a lobotomy class trauma instead - of magic. - timothyteakettle: - - bugfix: Food carts now function as intended, allowing the pouring and mixing of - drinks. - - rscadd: slimes can now change their color using alter form -2020-06-17: - SmArtKar: - - rscadd: New ID icons - - rscadd: Sutures and Meshes - Trilbyspaceclone: - - bugfix: Gin export takes gin now -2020-06-18: - Detective-Google: - - tweak: cog is now less the suck - - bugfix: couple little derpy bits - - balance: malf disk and illegal tech disk moved from ashwalker base (guaranteed) - to tendrils (chance based) - SmArtKar: - - rscadd: Ported shuttles from beestation - timothyteakettle: - - rscadd: embeds got reworked, sticky tape was added, more bullets that ricochet - also added - - rscadd: medbots can now be tipped over - - soundadd: added more medbot sounds -2020-06-19: - Bhijn: - - bugfix: Atmos can no longer become completely bricked - Funce: - - bugfix: Square root circuit should now actually work. - SmArtKar: - - bugfix: Fixed my runtimes - TheSpaghetti: - - rscadd: more insectoid insects - kevinz000: - - rscadd: bay/polaris style say_emphasis has been added. You can now |italicize| - _underline_ and +bold+ your messages. - timothyteakettle: - - rscadd: Adds the brain trauma event, where one player gets a random brain trauma! - - rscadd: Adds the wisdom cow event, where the wisdom cow appears on the station! - - rscadd: Adds the fake virus event, where people get fake virus symptoms. - - rscadd: Adds the stray cargo pod event, where a cargo pod crashes into the station. - - rscadd: Adds the fugitives event, where fugitives are loose on the station, and - it's the hunters jobs to capture them. -2020-06-20: - LetterN: - - rscadd: Asset cache from tg - - tweak: Made the map viewer not look bad - - bugfix: Admin matrix right-bracket - bunny232: - - rscdel: Removed unsavory things from the vent clog event -2020-06-21: - kevinz000: - - balance: calculations for punch hit chance has been drastically buffed in favor - of the attacker. -2020-06-22: - Ghommie (porting PRs by zxaber, Ryll-Ryll, AnturK): - - tweak: Certain small items purchased through cargo now get grouped into a single - box. They also are immune to the 10% private account fee. - - rscadd: Added single-order options for several existing products in the Cargo - Catalog. - - tweak: Medkit listings are now single-pack items, and considered small items that - get grouped into single boxes. Price for medkits is as close to unchanged as - is reasonable. - - rscadd: You can now beat on vending machines to try and knock loose free stuff! - You can also almost kill yourself doing it, so it's your call if your life is - worth ten bucks. - - rscadd: Cigarette packets now have coupons on the back for small cargo items! - Smoking DOES pay! - - tweak: Some single/small items in cargo have been rebranded as goodies, come in - lockboxes rather than crates, and can only be purchased with private accounts. - kevinz000: - - refactor: Life() is split into BiologicalLife() and PhysicalLife. A component - signal has been added that can prevent either from ticking. - shellspeed1: - - rscadd: Adds IV bags. -2020-06-24: - DeltaFire15: - - balance: Choosing a random item in your uplink will no longer sometimes reroll - your contract. - - rscdel: Syndicate crate event cannot fire as a random event anymore. - Detective-Google: - - bugfix: singulos no longer succ infinite rods out of the ice - - bugfix: one of the directions for the diag hudpatch was blu instead of orang - timothyteakettle: - - bugfix: bonfires/grills no longer produce infinite quantities of food - - bugfix: slime's alter form ability now updates their hair colour when changing - their body colour -2020-06-25: - Anonymous: - - rscadd: Added kepi and orvilike kepi. Available through loadout. - Detective Google: - - rscadd: Medigygax - Detective-Google: - - bugfix: malf AIs can no longer yeet the station while shunted - - bugfix: SMESes can now properly use self charging cells - - rscadd: ghosts now show up when the round ends - - balance: away missions - Funce: - - bugfix: Mentor SQL queries are now deleted properly. - Linzolle: - - bugfix: analyze function on chem master is no longer broken - - bugfix: organs now decay inside dead bodies again - dapnee: - - rscadd: wataur bottle item - - imageadd: wataur bottle and overlay -2020-06-26: - Ghommie: - - bugfix: Snore spam. - - bugfix: Hostile mobs shouldn't hit their original spawner structures or thoses - of the same faction. - silicons: - - bugfix: soap cleans blood again -2020-06-27: - Detective-Google: - - tweak: Lying down is better - timothyteakettle: - - rscadd: felinids now nya when tabled -2020-06-28: - Detective-Google: - - bugfix: cog is less the suck - - tweak: piggybacking is no longer absolutely inferior - Ghommie: - - bugfix: Fixing windows interaction with spraycans. - - bugfix: Fixing kinetic accelerator guns not working well with gun circuitries. - - bugfix: Fixing Zoomba borgs lights overlays. - - bugfix: Fixing the "absorb another ling" and "absorb the most dna" objectives - rolling when no other changeling is around. - - spellcheck: Clarified a pet peeve about the spread infestation ability. - - bugfix: BEPIS nodes won't show up anymore in the expert mode ui of the r&d console - anymore (good thing they weren't researchable). - - bugfix: Hopefully fixing sound loop edge cases. - - bugfix: Fixing pAI radios being permanently disabled by EMPs at times. - - rscadd: Windoors can now be obscured with spraycans just like windows. - Ghommie porting PRs by Qustinnus/Floyd, Willow, cacogen, nemvar, Ghilker and EOBGames (Inept): - - bugfix: Fixes a material duplication bug. - - code_imp: unique combinations of custom_materials lists are now shared between - objects - - rscadd: meat material. yes. - - rscadd: materials can now be used to build walls/floors. meat house - - bugfix: edible component now does not try to attack if you eat something with - it - - rscadd: Texture support for mat datums with thanks to 4DPlanner! - - bugfix: you no longer hit yourself with organs when eating - - rscadd: A whole bunch of materials are now datumised! Check out bronze, runed - metal, sand, sandstone, snow, paper, cardboard, bone and bamboo. Oh, and pizza. - Yes, pizza. - - balance: Buffs material floor tiles' throwforces from 1 to 10 (same as iron) to - better showcase the effect of different materials (e.g. meat vs. titanium) - - bugfix: Radioactive items no longer output a single . when examined at a distance - MrJWhit: - - rscdel: Removed air alarm in Snow Snaxi in Tcomms Sat - - rscdel: Removed trash bins in genetics and mining - - tweak: Gives cargo techs a cargolathe - Putnam3145: - - bugfix: lost my mind just a couple of times - b1tt3r1n0: - - rscadd: pouches, again, and and material pouches. - timothyteakettle: - - rscadd: support for custom blood colours implemented, slimes blood colour now - equivalent to their body colour -2020-06-29: - b1tt3r1n0: - - balance: Made teratomas from sdgf less powergame - timothyteakettle: - - bugfix: slimes no longer have white blood by default -2020-06-30: - Fikou: - - rscadd: spray cans, airlock painters, and decal painters added to engineering/service/autolathe - (where applicable) - Ghommie: - - bugfix: Fixed a gap on the male insect anthro torso sprite when facing south. - - bugfix: Fixed mecha ID access not being removable. - - bugfix: Fixed a peeve with the hypno trance status effect not sanitizing some - heard hypnosis inputs (i.e. custom say messages like say"honks*clownem ipsum - dolor") - - bugfix: fixed an issue about using stacks with only 1 amount left. - - bugfix: Fixed a peeve on attack messages against carbons/humans. - - bugfix: Fixed missing hypnochair board. - - bugfix: Fixed material walls and tiles. My bad on that port. - Ghommie (inspired by MrDoomBringer's work on tgstation): - - rscadd: New check skills UI. - Ghommie (porting PRs by XTDM, coiax, MrDoomBringer): - - tweak: Random Events now have a follow link for ghosts! - - rscadd: Adds the Spontaneous Brain Trauma to the event pool. Sometimes your brain - just goes a little wrong. - - rscadd: Sometimes a low level cloning pod will make errors in replicating your - brain, leaving you with a mild brain trauma. - - rscadd: When a person is cloned, any mental traumas are cloned as well. - - rscadd: The wizard federation announces that the Curse of Madness is out of beta - and is now available for purchase for 4 points. It causes long-lasting brain - traumas to all inhabitants of a target space station. - - rscadd: The wizard federation declines responsibility for any self-harm caused - by curses cast while inside the targeted station. - - rscadd: Due to the extensive testing of the Curse of Madness some unique new trauma - types have appeared across Nanotrasen-controlled space. - - rscadd: Curse of Madness can now be triggered by a wizard's Summon Events, at - the same chance as Summon Guns or Summon Magic. - - admin: When an admin triggers Curse of Madness manually, they can specify their - own dark truth to horrify the station with. - nightred: - - code_imp: Created two_handed component - - refactor: Updated all existing two handed items to use the new component - silicons: - - bugfix: typing indicators no longer generates duplicate message boxes. - - rscadd: config errors now have line numbers. - - tweak: outgoing mentorpms are now blue instead of green for the sender. - - soundadd: '*squish' - timothyteakettle: - - rscadd: you can now select your tongue and speech verb in the character customization - menu! - - rscadd: skeleton is now split into two more types, greater and lesser - - bugfix: non-carbon blood is now not white - - spellcheck: fixed a bunch of grammar/spelling mistakes -2020-07-02: - Ghommie: - - bugfix: Fixing a few issues with twohanded items. - - bugfix: Unum decks now work correctly. - - bugfix: Abductor walls are once again buildable with alien alloy. - Trilbyspaceclone: - - tweak: Makes pride and envy ruin a bit smaller! - - rscadd: Pride now has rings, lipstick wigs and silver walls/door making a nice - and polished look then cyan blue walls. - - rscadd: more trash and better dagger placement on food ruin - - rscadd: Snowboim now has snowballs and toy gifts for the two skeles daw! - - tweak: Beach boim now has carp light branding beer, as well as soap! - - tweak: Greed ruin now uses nice slick walls and carpet! - - tweak: Founten ruin looks a lot better with its carpets and well maintained fluff - things, but walls suffered and no longer can salvage ruined metal... - - rscadd: Alien nest has a bit more glowy floors of resin looking a bit more lived - in by the drones. As well as the "door" now being see through resin rather then - the thicker stuff that you cant see through - - rscadd: Pizza party has a few more gifts, some candy and snap pops yay! - - balance: Sloth ruin is about 15~ tiles shorter, has and has more fruit for a bowl. - How lazy! - silicons: - - bugfix: bohbombing is a thing now -2020-07-03: - Arturlang: - - rscadd: You can now toggle hardsuit helmets from the strip menu - Ghommie: - - bugfix: fixed custom speech/tongue stuff. - - balance: Lowered shaft miners' paycheck, they have other ways to make cash. - - rscadd: You can't (un)equip garments on/from obscured inventory slots anymore. - - balance: The stamina cost multiplier for swinging melee weapons against mobs has - been brought back to 1 from 0.8 - - balance: The stamina cost for throwing mobs now scales with their mob size variable. - LetterN: - - tweak: Ported some tags from tgui-3.0 to Vending.js - - bugfix: vending icons - - bugfix: r&d icons - - bugfix: chem master icons - Onule: - - tweak: titanium wall man good - Sonic121x: - - bugfix: Bringback the ChemMaster pill type button. - - bugfix: Fix Technode icon. - bunny232: - - tweak: Witchhunter hat no longer obscures mask ears ,eyes, face and mouth - timothyteakettle: - - bugfix: bloodpacks initialise correctly now -2020-07-04: - Sonic121x: - - rscadd: crushed Soldry sodacan - - rscadd: digitigrade version of chief medical officer's turtleneck and captain's - female formal outfit. - silicons: - - refactor: blood_DNA["color"] is now a single variable instead of a list -2020-07-05: - Ghommie: - - bugfix: You can now actually gain wiring experience from using cable coils. - - bugfix: Opening the View Skill Panel shouldn't trigger messages about insufficient - admin privileges anymore. - Yakumo Chen, kappa-sama: - - rscdel: Removes improvised handguns - - rscdel: removed handsaws, improvised gun barrels (you can use atmos pipes again) - - balance: Guncrafting is less time and resource intensive - - tweak: Item names in guncrafting are user-friendly. - kappa-sama: - - rscadd: cloth string to replace durathread string - - rscdel: durathread string - - balance: All bows and arrows have had crafting times significantly reduced, coming - out at up to 6 times faster crafting speeds. Improvised bows no longer require - durathread; instead, they use cloth materials. - silicons: - - tweak: active blocking now has a toggle keybind - - rscadd: auto bunker override verb has been added - - balance: shields take 2.5 stam instead of 3.5 stam per second to maintain block - - rscadd: Cybernetic implant shields will auto-extend and be used to block if the - user has no item to block with - timothyteakettle: - - tweak: cooking oil is now far less lethal, requiring a higher volume of the reagent - to deal more damage -2020-07-07: - KasparoVy: - - tweak: Fixes misaligned south-facing silver legwraps sprite. - Owai-Seek: - - bugfix: Bee Balm is now visible. - Weblure: - - bugfix: Fixed the slowdown formula for small character sprites; you guys don't - use custom sprite sizes so just ignore these changes. - - bugfix: Fixed the "Move it to the threshold" button; it now does what it says. - - tweak: Reworded some text to be clearer. -2020-07-08: - DeltaFire15: - - bugfix: The kill-once objective now works properly. - EmeraldSundisk: - - rscadd: CogStation now has an apothecary - - rscdel: Removes an outdated note on sleepers - - tweak: Readjusts CogStation's chemistry lab - - tweak: Slight area designation adjustments for Robotics - - bugfix: The arrivals plaque should be readable now - Owai-Seek: - - rscadd: Margarine, Chili Cheese Fries. - - tweak: Egg Wraps are now categorized under egg foods. - - bugfix: Tuna Sandwich crafting/sprite is now visible. - - imageadd: Icons for chicken, cooked chicken, steak, grilled carp, corndogs - - imageadd: Icons for chili cheese fries, margarine, BLT sandwich - - imageadd: (Unused) icons for raw meatballs, and lard -2020-07-09: - timothyteakettle: - - rscadd: bluespace tray added, allowing twice as many items as the regular tray, - printable at the service lathe, researched through science - - rscadd: bluespace jar added, a kind of pet carrier that allows human sized mobs - inside, and smashes when thrown, researched and printed through science -2020-07-10: - Chiirno: - - code_imp: Gave jellypeople a unique brain object /obj/item/organ/brain/jelly - - imageadd: added an icon for jellypeople brains. - EmeraldSundisk: - - rscadd: Adds a pool to PubbyStation - - tweak: Slight adjustments to the surrounding area as to fit said pool - Sneakyrat6: - - bugfix: Fixes hair falling out of hoodies. - TheObserver-sys: - - bugfix: Actually adds the juice reagent to make laugh peas donuts. -2020-07-11: - Putnam3145: - - refactor: Gas mixtures now live entirely in a DLL. -2020-07-12: - DeltaFire15: - - balance: Sentinels compromise now heals augmented bodyparts. - EmeraldSundisk: - - rscadd: Adds turnstiles to CogStation's security wing - - rscadd: Readds robotics to the Corpse Disposal Network - - rscadd: Readds chemistry's ability to send items directly to the experimentation - lab - - tweak: Visual renovation and slight adjustments to CogStation's robotics lab - - tweak: Slight visual adjustments elsewhere (the library) - - bugfix: CogStation's mail and disposal pipes are once again complete - - bugfix: CogStation's robotics lab now has spawners, lights, and other room essentials - HeroWithYay: - - rscadd: Added Telecrystal Dust - - tweak: Telecrystals can be sold at cargo - LetterN: - - rscadd: Added d[thing] emojis - - bugfix: bye xss - MrJWhit: - - rscdel: Removes northern tunnel to the monastery on Pubby - Yakumo Chen: - - rscadd: Adds a wedding crate to cargo full of wedding attire. - kappa-sama: - - tweak: wisdom cow is half as common and is wise enough to lag the server 66% less - silicons: - - config: 'policy configuration added, plus support hooks for assisting enforcement - of clone memory disorder. logging: added logging of revival by defib, cloning, - strangereagent, and revival surgery' - - rscadd: You can now "audibly emote" by having ! at the start of a sentence. - timothyteakettle: - - rscadd: due to recent biological advancements, you can now make eye contact with - people. - zeroisthebiggay: - - bugfix: a singular stray pixel -2020-07-13: - Linzolle: - - bugfix: you can no longer vore and digest people regardless of vore preferences - Owai-Seek: - - tweak: Trashbags can now hold most shoes, and organs. - - balance: You can no longer nest nuke disks or hold brains in the trash. -2020-07-14: - silicons: - - rscadd: chemical reactions now are sorted by priority first and temperature second. - - rscadd: sec and medical records have been added to character setup. - - bugfix: circuit reagent heaters are now sanitized for temperature from 2.7 to - 1000. - timothyteakettle: - - bugfix: ports a money bag exploit -2020-07-15: - Sonic121x: - - bugfix: Paramedic jumpsuit -2020-07-16: - DeltaFire15: - - bugfix: Fixes a zeolite runtime caused by a missing check. - Sneakyrat6: - - bugfix: Fixes being able to meta people real name with OOC Notes - timothyteakettle: - - rscadd: travelling traders from another dimension can now visit the station in - search of something specific, and reward you for giving it to them - - bugfix: small error with pet carrier logic fixed and also making sure simple mobs - are catered for properly inside bluespace jars - - bugfix: fixes coin related issue -2020-07-17: - ShizCalev, Fikou: - - bugfix: Added some sanity checking for varedit values. - - bugfix: Fixed an exploit involving coins and mints that could crash the server. - - bugfix: Fixed an exploit that would allow you to destroy round-critical / indestructible - items with folders. - - bugfix: Swarmers can no longer cut power lines by deconstructing catwalks underneath - them. - - bugfix: Fixed a scenario that allowed infinite resource generation via ore machines. - - bugfix: you can no longer inject html in ahelps - - admin: you cant either, jannies - timothyteakettle: - - bugfix: fixes a small pickle related issue - - rscadd: recent culinary and scientific advancements have brought forth new pickle - related technologies -2020-07-19: - Arturlang: - - rscadd: TGUI 3.0 and enables all the UIs, plus the smart asset cache, and all - the things required for them - EmeraldSundisk: - - rscadd: Adds a pool to Delta Station - - rscadd: Adds light fixtures to specified areas - - tweak: Relocates objects in impacted areas of Delta's starboard maintenance - MrJWhit: - - rscadd: Adds a small light next to the kitchen counter - Putnam3145: - - bugfix: Pen uplinks no longer broken - TheObserver-sys: - - rscadd: 'Adds a new reaction: Slime Extractification. Take 30u Slime Jelly, 5u - Frost Oil, and 5u plasma to generate a fresh grey slime extract.' - Yakumo Chen: - - tweak: Hierophant club now checks for friendly fire by default. - b1tt3r1n0: - - rscadd: Added the updated circle game - silicons: - - rscadd: Unarmed parry is now a thing. - timothyteakettle: - - rscadd: plushies in the loadout have been replaced with a box that lets you choose - one instead - - bugfix: wrestling should no longer have the ability to permanently rotate people - - rscadd: you can now select to wear a snail shell as your backpack in the customization - menu - zeroisthebiggay: - - tweak: martial arts twenty minpop - - bugfix: records -2020-07-20: - lolman360: - - tweak: Service borgs now have synthesizers instead of a violin and guitar. - - bugfix: borg RSF -2020-07-21: - Arturlang: - - bugfix: Decal painter ui now works, yay? - CameronWoof: - - rscadd: Adds aloe, a new growable plant - - rscadd: Adds medicated sutures and advanced regenerative meshes - - bugfix: Polypyrylium oligomers and liquid electricity now correctly populate - Chiirno: - - rscadd: Alt-click pill bottles places top-most pill into active hand. - - tweak: Moved dice bags from pill_bottle/dice to box/dice to avoid dice bags being - affected from medical specific pill bottle changes. - DeltaFire15: - - bugfix: Swarmers can once again eat items as long as there's nothing living in - them. - Funce: - - bugfix: Genetics spiderwebs are no longer impassable walls - Kraseo: - - balance: Damp rags no longer instantly apply their chemicals onto someone. - SiliconMain: - - tweak: Geigers can no longer be contaminated - TheSpaghetti: - - rscadd: new snowflake trait - kappa-sama: - - balance: advanced surgery duffel bag no longer comes with a nukie medkit. it costs - 4 less telecrystals to make up for this colossal nerf. - - tweak: quartered the weight of the stray cargo pod event from 2x normal to 1/2 - normal - silicons: - - tweak: survivalists (from summon guns/magic) are proper objective'd pseudoantagonists - again - - tweak: summon guns/magic can only be used once each - - tweak: summon guns/magic now only cost one point each - - imageadd: ':dsmile: :dfrown: :dhsmile: :dpog: :dneutral:' - - bugfix: gravity should update for mobs a fair bit faster - - rscadd: voting can now be done from the stat panel if the system is plurality - and approval - timothyteakettle: - - rscadd: new fried component used for frying objects - - bugfix: various frying bugs fixed such as being able to unfry items and frying - turfs with cold cooking oil -2020-07-22: - Ludox: - - rscdel: You can no longer be brainwashed into giving birth to a fake baby - kappa-sama: - - balance: brainwashing disk has lost its cost buffs (3->5) and is role restricted - once more (medical doctor/roboticist) -2020-07-23: - DeltaFire15: - - bugfix: Traits are no longer fucked - Putnam3145: - - tweak: Slight optimization in chat code. - kappa-sama: - - bugfix: tendril chests being empty - zeroisthebiggay: - - rscadd: fetish content -2020-07-24: - EmeraldSundisk: - - rscadd: Adds a CMO office, along with Virology and Genetics labs to Omega Station - - rscadd: Adds a second chemistry station to the chemistry lab - - tweak: Adjusts the locations of some objects in medical to accommodate these new - additions - - tweak: Relocates the morgue - - tweak: Relocates items in impacted areas of maintenance as well as the library - - bugfix: Fixes an air line Bartholomew somehow knocked out - Linzolle: - - bugfix: wounds now have a description on examine - Owai-Seek: - - rscadd: Meatball Sub, Meatloaf + Meatloaf Slices, Bear Chili, Mashed Potatoes - - rscadd: Buttered Potatoes, Fancy Cracker Pack, Spiral Soup, Sweet and Sour Chicken - - tweak: Organised the Food DMI a bit. - - tweak: Deleted some stray pixels on some sprites. - - tweak: Nuggie boxes are now centered correctly. - - imageadd: Icons for the the food items in this PR. - Sneakyrat6: - - bugfix: Fixes dressers not giving you undies - - bugfix: Fixes Snaxi not loading properly because of typos - - rscadd: You can now burn photos - Zandario: - - spellcheck: Murdered **tipes** and gave birth to **is**. - silicons: - - tweak: sanitization now doesn't cut off 15.7 or something million possible colors - from character preferences (instead of only allowing 16 values for R G and B, - it now allows 256 each) - - balance: projectiles are by default 17.5 tiles per second instead of 12.5 - timothyteakettle: - - rscadd: due to recent innovative research in the medical field, you now have bones - - tweak: zombie claws are now sharp and do less damage, but can destroy non-lifeforms - far faster - - tweak: zombies now take less stamina damage - - rscadd: beepsky can now wear hats - zeroisthebiggay: - - imageadd: rad and kravglove sprites -2020-07-25: - CameronWoof: - - bugfix: Aloe now has an icon. - timothyteakettle: - - bugfix: beepsky replaces the word THREAT_LEVEL with the actual threat level -2020-07-26: - DeltaFire15: - - bugfix: Organs now decay again. - Iatots: - - tweak: Licking wounds now may cause you to spit out a hairball once in a while! - - rscadd: You can now craft a catgirl plushie with 3 of a new ingredient occasionally - found in medbay! - dapnee: - - tweak: removed legacy public mining shuttle area and remade lounge -2020-07-27: - Hatterhat: - - rscadd: Training bokkens! Make 'em from wood, use 'em in-hand to toggle between - harmful and not-so-harmful, practice your parrying with them! - - bugfix: Marker beacons should have a sprite again. - silicons: - - rscadd: clownops and clown mobs now share the same faction. HONK! - timothyteakettle: - - bugfix: modern pickle technology now allows people who have been turned into pickles, - to be retrieved through the medical course of dying -2020-07-28: - Cacogen: - - rscadd: OSHA has more pull than anyone could have expected. All armor provided - by Nanotrasen and the syndicate now have tags that accurately lists defenses - and resistances of a piece of clothing. - CameronWoof: - - tweak: Exotic seed crates now contain a spaceman's trumpet seed packet. - EmeraldSundisk: - - rscadd: Renovates Snow Taxi's northeast bathroom to have multiple non-urinal toilets - and showers - - rscadd: Adds signage/labeling to improve map readability - - rscadd: Adds a bathroom to the northwest station - - rscadd: Adds a filing cabinet to the cargo department - - tweak: Area designation adjustments to account for the above changes - - bugfix: Adds a missing airlock cyclelink near medical - Ludox235: - - tweak: Makes the flavour text that appears when you become a zombie tell you to - act like one. - MrJWhit: - - tweak: Decluttered toxins and hid the yellow mix line in atmos, for metastation - SiliconMain: - - tweak: Paramedic heirloom is now a zippo - - tweak: Durathread belts now protect their contents from radiation, and can hold - full sized extinguishers - Sishen1542: - - rscdel: removed zoomba - dapnee: - - tweak: added a fan to the listening outpost - - bugfix: added two missing r-walls near the SM, removed random light and wire node - below the engine, and fixed the missing cable in the courtroom on Kilo - kappa-sama: - - balance: Stimpaks cost 5tc once more, up from 3tc. - silicons: - - rscadd: polychromatic cloaks to loadout - - rscdel: no more self healing with medibeam guns - - balance: oh no, taser buff. alt fire delay dropped to 0.4 seconds. - - rscadd: you can now shoot yourself by disarm-intenting yourself with a gun. - timothyteakettle: - - tweak: species code is now slightly less messy - - bugfix: slight tweak to how material crafting works - - bugfix: changed up pet carriers / bluespace jars a bit so you can't fit certain - things inside them and also the text shown for resist times is accurate - zeroisthebiggay: - - rscadd: Black Box theft objective -2020-07-29: - DeltaFire15: - - bugfix: The 'Naked' outfit is no longer broken. - Ghommie: - - bugfix: fixed cremator trays, paleness examination strings, chat message for stamping - paper, looping sounds, load away missions/VR admin verb, access requirements - for using the sechuds. - - tweak: Alt-Clicking a cigarette packet should pull the lighter out first if present, - then cigarettes. - Hatterhat: - - bugfix: Directional windows can now be rotated counterclockwise properly again. - NecromancerAnne, Sirich96: - - rscadd: Stunbaton sprites by Sirich96. - - rscadd: New sprites for the stunsword. - necromanceranne: - - rscadd: Adds some in-hands for the rapier sheath. - timothyteakettle: - - bugfix: tail wagging should work in all cases now - - bugfix: bluespace jars work as intended now - - bugfix: aliens can remove embeds now - - bugfix: bloodsuckers are not affected by bloodloss - zeroisthebiggay: - - rscadd: Flannel jackets and bartender winter coat -2020-07-30: - Adelphon: - - rscadd: Created a Cosmetic version of the camo. - Arturlang: - - code_imp: Bloodsucker LifeTick runs from BiologicalLife now - Ryll-Ryll ported by silicons: - - rscadd: Shoelaces are now a thing. You can untie them by laying down next to someone. - - tweak: shoes now have lace delays and some can't be laced at all - - refactor: do after now tracks who's interacting with who, meaning some actions - now break when the target moves away. - SiliconMain: - - rscadd: Ported the long range atmos analyzer from sk*rat, credit to NotRanged - silicons: - - rscadd: energy sword perfect parries now reflect projectiles back at their shooters. - - balance: any mob can now parry if they have the right item - - rscadd: beam rifles now go into emitters properly - - refactor: clickdelay has been refactored into an experimental hybrid system. Check - code/modules/mob/clickdelay.dm for more information. - - balance: Resisting no longer checks clickdelay, but is standardized to a 2 second - per resist system for most forms of resisting. It still sets clickdelay, though. - - rscadd: 'Meters have been added for estimating time until next attack/resist. - Won''t be that useful due to our clickdelay currently being very short, though. - They''re visible from your hand and resist HUD elements. experimental: Most - attacks and forms of attacking (minus unarmed because it''s too much of a pain - to refactor how hugs/gloves of the north star works) now check for time-since-last-attack - rather than making it so you can''t attack for said time. This means you can - very quickly switch to a gun from a melee weapon, whereas in the old system - a melee weapon would put you on lockout for 0.8 seconds, in the new system all - the gun cares about is that you did not attack for at least 0.4 seconds.' - - code_imp: All clickdelay setting/reading are now procs, so it should be trivial - to implement another system where drawing/switching to a weapon requires you - to have it out for x seconds before using it. I am not personally doing it at - this point in time though because it will likely just annoy everyone with no - real gain unless we do something like putting a 0.8 second switch-to cooldown - for guns (which I did not, yet) - - refactor: 'attack_hand has been refactored to on_attack_hand remove: sexchems - no longer impact click delay' - - rscadd: turrets now automatically stagger their shots. Happy parrying/blocking. - - bugfix: turrets now speed_process, they were shooting slower than they should - be - - balance: anything can now block with the right items - timothyteakettle: - - bugfix: some crafted crates won't contain items now, and thus have stopped breaking - the laws of physics - - tweak: beepskys hats now follow the laws of gravity and move up/down when he bobs - up and down -2020-08-01: - dapnee: - - tweak: added cake hat to bar, adds another atmostech spawn - - bugfix: sinks point in the right direction, APC won't spawn off the wall in circuits - - bugfix: changes commissary APC so it actually powers the room, adds a missing - AIR alarm, arrivals no longer has active atmos tiles. - silicons: - - tweak: toy shotguns no longer need 2 hands to fire - - bugfix: being on fire works again. - timothyteakettle: - - bugfix: monkeys no longer continuously bleed everywhere -2020-08-02: - Auris456852: - - rscadd: Added B.O.O.P. Remote Control cartridges to the PTech. - Hatterhat: - - rscadd: Durathread reinforcement kits! Sprites by Toriate, sets jumpsuit armor - to durathread levels, craft in the crafting menu. - KeRSedChaplain: - - rscadd: The belligerent scripture and a brass multitool, and a new marauder variant - which act similar to holoparasites/guardian spirits. - - rscdel: Removed the abductor teleport consoles they get, removes abscond for the - time being as I've not seen much use for it other than just spamming it and - hoping you end up in the armory. - - tweak: moved around scriptures to make the cult work better as being based around - the station, makes the Ark scream more often and work as a summonable object, - clockwork armor now has a flat 0 defense up to 10 instead of negatives against - laser damage. Makes the Ark work better in a station based setting, as well - as the Heralds beacon in case It works for the mode. - - soundadd: added powerloaderstep.ogg for Neovgre - - tweak: changes 'Dread_Ipad.dmi' to 'clockwork_slab.dmi' - MrJWhit: - - tweak: Adjusts abductor spawntext - Seris02: - - bugfix: fixed replica pods - dapnee: - - bugfix: fixed active turfs on wizard ruin and space hermit, fixed missing APC's - and added a light on Delta - ike709 and bobbahbrown: - - rscadd: Admins can now see your bans on (some) other servers. - kappa-sama: - - bugfix: chaplain cultists being able to convert people to full clockwork cult - status - timothyteakettle: - - tweak: combat mode now has weaker buffs in terms of damage dealt and took for - being or not being in the mode - - tweak: damage debuff for laying down has been decreased from 0.5x to 0.7x -2020-08-03: - KeRSedChaplain: - - bugfix: fixed clockwork guardians being able to reflect ranged weapons - Linzolle: - - bugfix: uv penlight no longer invisible - dapnee: - - bugfix: active turfs on box and xenohive, maintenance bar APC not being stringed - correctly, turned a monitor to face a direction that makes sense, changed tag - of camera in gravgen being misnamed - silicons: - - rscadd: shoves have been buffed to apply a status effect rather than a 0.85 movespeed - modifier, meaning repeatedly shoving someone now renews the debuff - - balance: shoves now stagger for 3.5 seconds. - - tweak: war operatives now actually time 20 minutes since roundstart to depart - instead of 15. - - balance: explosive stand bombs can now be examined from any distance - - code_imp: explosive stand bombs are now a component. -2020-08-04: - Seris02: - - bugfix: lizard spines - timothyteakettle: - - rscadd: due to further advancements in medical technology, you can now have holes - poked into your body for fun and enjoyment - zeroisthebiggay: - - rscadd: prefs for headpat wagging -2020-08-06: - Auris456852: - - rscadd: Added B.O.O.P. Remote Control cartridges to the PTech. - Hatterhat: - - rscadd: Proto-kinetic glaives! Essentially a proto-kinetic crusher with a different - blade, handguard, and goliath hide grip. Expensive, but elegant. - - balance: Door charges no longer knock people out. - Ludox235: - - rscadd: You can now buy damaged AI upload modules in the traitor's uplink. - Seris02: - - bugfix: fixed ghost chilis - Trilbyspaceclone: - - rscadd: 4 New blends of tea have been shipped to the station, and how to make - them has been leaked! - b1tt3r1n0: - - rscadd: Added the warp implant - dapnee: - - tweak: added a hallway to telecoms for engineers to get there on meta - kappa-sama: - - rscdel: dildo circuit assemblies - lolman360: - - bugfix: The Tendril-Mother on Lavaland has remembered how to make ashwalkers who - know how to speak Draconic again. - timothyteakettle: - - tweak: nanotrasen has decided to fire all disabled members of the security division - and confiscate certain sentimental items from doctors - - tweak: the custom tongue preference now passes through cloning so you spawn with - your selected tongue - - tweak: several changes to travelling traders so they look better and spawn slightly - less often - zeroisthebiggay: - - rscadd: nukies can buy holoparasites -2020-08-07: - dapnee: - - bugfix: fixed active tufs on some space ruins, murderdome VR, and a few on pubby, - changed cargo autolathe to techfab, messed with pipe room leading to monastery. - lolman360: - - bugfix: vendors are now unanchored when tipped. it just fell over it's not bolted - to the ground anymore. - - bugfix: podpeople no fat when sunbathing. - silicons: - - balance: explosions only recurse one level into storage before dropping 1 level - per storage layer. - - tweak: volumetric storage is now minimum 16 pixels per item because 8 was ridiculous - - spellcheck: shieldbash balanace --> balance - - rscadd: attempting to send too long of an emote will now reflect it back to you - instead of cutting it off and discarding the overflow. - - rscadd: holoparasites can now play music - - balance: lethal blood now causes damaging bleeding instead of outright gibbing -2020-08-08: - DeltaFire15: - - balance: Roundstart cultists now start with a replica fabricator - no brass though, - make your own. - - balance: 'Kindle cast time: 10 > 15, mute after stun end: 2 > 5, slur after mute - end: 3 > 5' - - bugfix: The ratvarian spear no longer adds negative vitality under very specific - circumstances. - - balance: The Ratvarian Spear can parry now! Short parries with low leeway, but - low cooldown. - - rscadd: The brass claw, a implant-based weapon which gains combo on consecutive - hits against the same target. - - rscadd: The sigil of rites, a sigil used to perform various rites with a cost - of power and materials - - rscadd: 'The Rite of Advancement: Used to add a organ or cyberimplant to a clockie - without need for surgery.' - - rscadd: 'The Rite of Woundmending: Used to heal all wounds on another cultist, - causing toxins damage in return.' - - rscadd: 'The Rite of the Claw: Used to summon a brass claw implant. Maximum of - 4 uses per round.' - Hatterhat: - - rscadd: You can now buy a toolbox's worth of Mosin-Nagant ammo for a fairly discounted - price. - - rscadd: Revolvers from the dedicated kit now have reskinning capabilities. - - bugfix: You can now actually buy the riflery primer, which lets you pump shotguns - and work the Mosin's bolt faster. - - imageadd: Bulldog slug magazines now have a unique sprite. - Ludox235: - - rscdel: Removed an abductee objective that told you to remove all oxygen. - - rscadd: Added a new abductee objective to replace the removed one. - Sishen1542: - - tweak: "\U0001F171\uFE0Foneless" - - rscadd: squishy slime emotes - timothyteakettle: - - tweak: heparin makes you bleed half as much now - - tweak: cuts make you bleed 25% less now - - rscadd: more items in the loadout and loadout has subcategories now for easier - searching -2020-08-09: - Hatterhat: - - rscadd: Proto-kinetic glaives (not crushers) can parry now. - MrJWhit: - - rscadd: Adds a second shutter on the top of the hop line - silicons: - - bugfix: immovable rods no longer drop down chasms - - rscdel: 'fun removal: squeaking objects now have an 1 second cooldown between - squeaks, and will have a 33% chance of interrupting any other squeaking object - when Cross()ing, meaning no more ear-fuck conveyor belts.' -2020-08-10: - Hatterhat: - - bugfix: Parry counterattack text now shows up. - - balance: Sterilized gauze is now better at stopping bleeding, and applies slightly - faster. Very slightly faster. - - balance: Ointment and sutures now hold more in a stack (12 and 15, respectively). - - tweak: Sterilized gauze can now be made by just pouring 10u sterilizine onto standard - medical gauze, instead of having to craft it. Why you had to craft it, I will - honestly never know. - - balance: Proto-kinetic glaives are more expensive, stagger/cooldown on failed - parries increased slightly, perfect parries required for counterattack. - - rscadd: 'New item: Temporal Katana. 2 points for wizards, timestops upon successful - parry, bokken quickparry stats (100 force on melee counter!).' - - rscadd: Also you can *smirk. This has no mechanical effect, other than being smug. - KeRSedChaplain: - - rscadd: Added a guide for romerol usage - - balance: made infectious zombies not enter softcrit and take no stamina damage - LetterN: - - tweak: clocktheme color - - code_imp: Ports TGUI-4 - Lynxless: - - rscadd: 'Ports TG #51879' - Owai-Seek: - - tweak: Meatballs now spawn raw from food processors. - Putnam3145: - - rscadd: Ethereals - - rscdel: (Hexa)crocin - - rscdel: (Hexa)camphor - - tweak: Tweaked wording for marking tickets IC issue. - - tweak: Rerolling your traitor goals will ONLY give you "proper" objectives. - Seris02: - - bugfix: borgs being able to select and use a module when it's too damaged - Sishen1542: - - balance: gave chairs active block/parry in exchange for removal of block_chance - - tweak: replaces box whiteship tbaton with truncheon - kappa-sama: - - balance: made the Dirty Magazines crate cost 4000 instead of 12000 credits - - rscadd: MODS I SPILLED MU JUICE HEJPPHRLP HELPJ JLEP HELP - silicons: - - balance: player made areas are no longer valid for malf hacking - - tweak: default space levels is 4 again. - - tweak: rats now swarm instead of stacking on one spot. - - balance: getting hit by an explosion will now barely hard knockdown, but will - leave you somewhat winded. - timothyteakettle: - - tweak: speech verbs copy through dna copying now -2020-08-11: - Hatterhat: - - bugfix: PDA uplinks can now steal from pens. Properly. Just make sure to have - a pen in your PDA, first. - kappa-sama: - - tweak: tracer no longer gives you full stamheals per use - zeroisthebiggay: - - rscadd: volaju two -2020-08-12: - DeltaFire15: - - balance: 'hellgun single-pack classification: goodies -> armory' - Detective-Google: - - bugfix: hallway table hallway table - Hatterhat: - - balance: The temporal katana is now slightly more worthy of the 2 spell point - cost, with a smaller, antimagic respecting timestop, less force, and no random - blockchance. Society has progressed past the need for blockchance. - LetterN: - - rscadd: Mafia Component - - bugfix: Fixed missing icons and handtele - Putnam3145: - - bugfix: a whole lot of jank regarding funny part sprite display. - Toriate: - - rscadd: Opossums have migrated into the maintenance tunnels! Seek them out at - your own peril! - ancientpower: - - tweak: Doors added to the west side of box medbay to make things a bit more manageable. - kappa-sama: - - tweak: smuggler satchel cost 2->1 - - tweak: radio jammer cost 5->2 - - bugfix: smuggler satchel uplink description now implies that persistence is disabled - lolman360: - - rscadd: renameable necklace (accessory, attaches to suit) and ring (glove slot.) - - tweak: custom rename is now 2048 characters? i think it's characters. - silicons: - - rscadd: You can now use anything as an emoji by doing :/obj/item/path/to/item:. - This works for any /atom or subtype. - timothyteakettle: - - rscadd: syndicate agents now have access to mechanical aim enhancers which allow - them to aim bullets to bounce off walls - - bugfix: ricochets work properly now for the bullets that support them - zeroisthebiggay: - - imageadd: hair and some sechuds - - balance: ce hardsuit radproofing -2020-08-13: - LetterN: - - rscdel: Removes fermisleepers and reverts them to tg ones -2020-08-14: - silicons: - - bugfix: abductors can buy things -2020-08-15: - LetterN: - - bugfix: missing anomaly core icons - - bugfix: wrong state. blame the tg vertion i copied - silicons: - - tweak: the 8 rotation limit from clockwork chairs has been removed. please don't - abuse this. - - tweak: ethereals can now wear underwear -2020-08-16: - kiwedespars: - - balance: nerfed hypereut chaplain weapon. - - balance: 50% rng blockchance -> 0% - - balance: parry made much worse because it's an actual weapon and a roundstart - one at that. - zeroisthebiggay: - - rscadd: tips - - rscdel: tips -2020-08-17: - DeltaFire15: - - bugfix: Cogscarabs are no longer always Pogscarabs - Strazyplus: - - rscadd: Added drakeborgs - - rscadd: Added drakeplushies - - imageadd: added drakeborg sprites - - imageadd: added drakeplushie sprites - - code_imp: changed some code - added drakeplushies to backpack loadout Removed - duplicate voresleeper belly sprites from engdrake & jantidrake. [CC BY-NC-SA - 3.0](https://creativecommons.org/licenses/by-nc-sa/3.0/) - - rscadd: Added CC BY-NC-SA 3.0 license details to icon/mob/cyborg moved drakeborg.dmi - to icon/mob/cyborg -2020-08-18: - DeltaFire15: - - balance: 'kindle cast time: 15ds -> 25ds' - - tweak: Moved the Belligerent Scripture to where it should be in the code - Detective-Google: - - rscadd: glass floors - - rscadd: uncrowbarrable plasma floors tweak:disco inferno's plasma floors can no - longer be crowbarred. - - rscadd: ghost cafe has funky fresh art - - bugfix: you can actually remove glass floors now - - code_imp: get_equipped_items is hopefully less gross - - balance: plasma cutters are no longer gay - Hatterhat: - - balance: Slaughter demons (and laughter demons, being a subtype) are MOB_SIZE_LARGE, - with one of the more immediate effects being able to mark them with a crusher - and backstab them. - - balance: The funny blyat men have stumbled upon another surplus of Mosin-Nagants - and are starting to pack them into crates again. - - balance: Vehicle riders can now, by default, get shot in the face and/or chest. - - rscadd: Adminspawn only .357 DumDum rounds! Because sometimes the other guy just - really needs to hurt. - - rscadd: Bluespace beakers now have a chemical window through the side that shows - chemical overlays. - - rscadd: Plant DNA manipulators now let you chuck things over them. Or they WOULD, - if LETPASSTHROW worked half a damn. - LetterN: - - bugfix: uplink implant states - - tweak: tweaks how role assigning works - MrJWhit: - - rscadd: Gives ashwalkers nightvision - - balance: Makes tesla blast people, not the environment, to save the server. - TheObserver-sys: - - bugfix: moves Garlic sprites from growing.dmi to growing_vegetable.dmi - - rscdel: Removes the unused Electric Lime mutation, it just takes up space with - no actual function nor sprites. - - imageadd: Gives Catnip growing sprites - - imagedel: Removes redundant images in growing.dmi - kiwedespars: - - rscadd: 10 force to a fucking rubber cock. - lolman360: - - balance: shotgun stripper clip nerf. ammoboxes can now accept a load_delay that - happens when they attack a magazine, internal or external. - ported from tg: - - rscadd: bronze airlocks and windows can now be built - - balance: i also tweaked bronze flooring to be cheaper. - silicons: - - tweak: stamina draining projectiles without stamina for their primary damage type - now has their stamina damage taken into account for shield blocking, rather - than the block being done for free for that. - timothyteakettle: - - refactor: snowflake code tidyup - - refactor: snowflake code for mutant bodypart selection has been rewritten to be - ~14x shorter - - tweak: meat type and horns can now be selected by any species -2020-08-20: - DeltaFire15: - - bugfix: The cooking oil damage formula is no longer scuffed. - - tweak: Changed the clockie help-link to lead to our own wiki. - Fikou: - - admin: admins can now do html in ahelps properly - Hatterhat: - - balance: Pirate threats are now announced as "business propositions", and their - arrivals are now also announced properly. - tiramisuapimancer: - - bugfix: Ethereal hair is now their body color instead of accidentally white -2020-08-21: - LetterN: - - rscadd: Updates and adds some of the tips - Putnam3145: - - admin: added reftracking as a compile flag - SmArtKar: - - tweak: RSD limitation is now 500 tiles - - bugfix: Fixed broken RSD sprites - - config: Removed that shuttle limit - timothyteakettle: - - bugfix: two snouts can once again be chosen in customization - - bugfix: lizard snouts work again -2020-08-22: - Time-Green (copypasta'd by lolman360): - - rscadd: plumbing - - rscadd: automatic hydro trays -2020-08-23: - DeltaFire15: - - bugfix: silicons and clockies can now access APCs properly - EmeraldSundisk: - - rscadd: Medbay now has a smartfridge for organ storage - - rscadd: Slight enhancements to the station's electrical wiring layout - - rscadd: Very small library renovation - - bugfix: Exterior airlocks have been given proper air systems for safety's sake - Ghommie: - - bugfix: Stops shielded hardsuits from slowly turning the wearer into a big glowing - ball of stacked energy shield overlays. - - tweak: the shielding overlay is merely visual as result. Aim your clicks. - Ludox235: - - tweak: no more 10 pop xenos (25pop now) - MrJWhit: - - tweak: Increases the majority of airlocks by 1 tile. - - tweak: Minor adjustments to the TEG engine. - Putnam3145: - - balance: Simplemobs no longer count in dynamic. - - balance: '"Story" storyteller no longer starts at a ludicrously low threat, always.' - - balance: Blob threat now scales with coverage. - - tweak: One person with their pref on no longer overpowers 40 people who might - not even know there is one. - - bugfix: Negative-weight rulesets are no longer put into the list. - kiwedespars: - - tweak: removed durathread from armwraps recipe. - lolman360: - - rscadd: breath mask balaclava - timothyteakettle: - - bugfix: lizards are now a recommended species for mam snouts - zeroisthebiggay: - - rscadd: new sprites for the temporal katana - - rscadd: suiciding with the temporal katana omae wa mou shinderius you into the - shadow realm - - soundadd: twilight isnt earrape -2020-08-24: - MrJWhit: - - bugfix: Fixes areas on expanded airlocks - silicons: - - bugfix: wormhole jaunters work - - tweak: wormhole jaunters no longer get interference from bags of holding - - bugfix: airlocks now only shock on pulse/wirecutters instead of on tgui panel - open. - timothyteakettle: - - rscadd: three new items are in the loadout for all donators - zeroisthebiggay: - - rscadd: contraband black evening gloves in kinkvend -2020-08-25: - Hatterhat: - - rscadd: Insidious combat gloves have been replaced by insidious guerilla gloves. - They're generally the same, except now you can tackle with them. - Literallynotpickles: - - tweak: You can now equip handheld crew monitors on all medical-related winter - coats. - Putnam3145: - - tweak: vore now ejects occupants on death - raspy-on-osu: - - tweak: Thermoelectric Generator power output - timothyteakettle: - - tweak: I.P.Cs now short their circuits when expressing emotion, causing sparks - to appear around them. -2020-08-26: - ancientpower: - - tweak: Ghosts can read newscasters by clicking on them. - silicons: - - balance: hierophant vortex blasts now have 50% armor penetration vs mecha - - balance: ventcrawling now kicks off every attached/buckled mob, even for non humans. -2020-08-27: - silicons: - - tweak: eyebeam lighting can only have 128 maximum HSV saturation now. - - balance: no more shotgun stripper clips in boxes. - - balance: goliath tentacles now do 20 damage to mechs at 25% ap - timothyteakettle: - - tweak: changing your character's gender won't randomize its hairstyle and facial - hairstyle now -2020-08-28: - EmeraldSundisk: - - rscadd: Adds more paper to the library - - rscadd: The law office now has a desk window - - tweak: Expands most of CogStation's exterior airlocks. Slightly adjusts surrounding - areas to accommodate this. - - tweak: Updates some of CogStation's paperwork - - tweak: The rat in the morgue turned themselves into a possum. Funniest shit I've - ever seen. - - bugfix: Adjusts some area designations so cameras should receive power properly - - bugfix: Cleans up an errant decal - Hatterhat: - - tweak: Traitor holoparasites can now only be bought once, because apparently you - can only have one active holopara. - - balance: PDA bombs can now only be bought once per uplink. - lolman360: - - rscadd: atmos = radiation = chemistry. - shellspeed1: - - rscadd: Adds slow mode for iv drips - timothyteakettle: - - rscadd: an ancient game over a thousand years old has re-emerged among crewmembers - - rock paper scissors - - tweak: customization features appear in alphabetical order where necessary - - tweak: bokken do two more stamina damage now - - rscadd: you can now choose a body sprite as an anthromorph or anthromorphic insect, - and can choose from aquatic/avian and apid respectively (and obviously back - to the defaults too) -2020-08-30: - raspy-on-osu: - - rscadd: new explosion echoes - - tweak: explosion echo range - - soundadd: 5 new explosion related sounds -2020-08-31: - Arturlang: - - tweak: Slimes can now damage structures, don't leave them unfed! - Chiirno: - - bugfix: Moves pill_bottles/dice to box/dice on CogStation. - Couls, ported by NecromancerAnne: - - code_imp: cleans up mech backstabbing code - DeltaFire15: - - rscdel: teleport-to-ark ability of the eminence, commented out - - rscadd: teleport-to-obelisk ability for the eminence - Detective-Google: - - tweak: plasmamen have no more slowdown - - rscadd: object reskins now use very nice and cool radials - EmeraldSundisk: - - rscadd: Adds a pool to MetaStation - - tweak: Slight readjustments to the surrounding area - - bugfix: Fixes a handful of external airlocks - ForrestWick: - - balance: removes wall walking boots from nukie uplink - - tweak: removes wall walking boots from nukie uplink - Ghommie: - - bugfix: e-gun overlays and some floor decals should have been fixed. - LetterN: - - rscadd: tgchat - Lynxless: - - tweak: Changed anatomic panacea into a direct buff, instead of a chem injection - - balance: Changed the values of anatomic panacea - - imageadd: Added a new icon for panacea's buff alert - Putnam3145: - - tweak: Pref for genital/vore examine text - - bugfix: Fixed a couple events having ghost roles eligible. - - balance: 'Buffed slaughter demon: gets stronger as it eats people' - - balance: 'Nerfed slaughter demon: no longer permanently round-removes all who - are eaten by it, instead releasing their now-heartless bodies' - - bugfix: Dynamic storytellers now calculate property weights properly. - Sonic121x: - - bugfix: Fix the four type of new tea that will stuck inside your vein. - - rscadd: drinking glass sprite for those tea. - kappa-sama: - - balance: miners can no longer acquire funny antag item - lolman360: - - bugfix: shuttle engine/heater sprites now face the right way - raspy-on-osu: - - tweak: TEG power output - - tweak: tesla movement priorities - - rscadd: tesla counterplay - - rscadd: tesla containment check (containment variable now usable) - silicons: - - bugfix: brooms now sweep objects on MOVABLE_PRE_MOVE rather than MOVABLE_MOVED - - balance: firedoors no longer automatically open on touch when there's no pressure - differences. - timothyteakettle: - - tweak: buzz, buzz2 and ping are now all unrestricted emotes and can be used by - anyone - - imagedel: the drake credit and pickle credit sprites have been removed - - refactor: tongue speech handling is now done by accent datums - zeroisthebiggay: - - rscdel: waffleco -2020-09-01: - BlueWildrose: - - bugfix: fixed slimes starting off hungry -2020-09-02: - Putnam3145: - - code_imp: Added a unit test for character saving. - - balance: Plastitanium rapier no longer silently sleeps with no chance at counterplay - when used by pacifists. - - bugfix: Fusion scan is now actually useful. - Tupinambis: - - tweak: moved the dakis, genital growth pills, and genital autosurgeons out of - the maintenance loot table and into kinkmates. - raspy-on-osu: - - bugfix: pyroclastic anomaly client spam - timothyteakettle: - - rscadd: you can hide your ckey now from the roundend report -2020-09-03: - Ghommie: - - bugfix: Jaunters should now work with magic mirror chasming. - - bugfix: The photocopier can now print more than one copy at a time. - - bugfix: Alkali perspiration infos don't crash the Pandemic UI anymore. - - bugfix: Windoors can be actually tinted now. -2020-09-04: - timothyteakettle: - - bugfix: ipcs can speak -2020-09-05: - Bhijn: - - rscadd: Readded the old method of temperature notifications in the form of a new - pair of shivering/sweating notifications. - Putnam3145: - - tweak: Hilbert hotel flavor text for one particular snowflake hotel changed. - - admin: admins can now actually reduce threat level in dynamic - - tweak: Made owo.ogg smaller. - - tweak: Character saving unit test is now more verbose on failure. - - refactor: Added an extools proc hook alternative to rust_g logging. - raspy-on-osu: - - tweak: supermatter shard examine text - - tweak: protolathe item categories -2020-09-06: - Putnam3145: - - rscdel: Dynamic no longer pushes events. - - balance: Made spontaneous brain trauma a good deal less annoying. - lolman360, NecromancerAnne: - - rscadd: The ancient art of blacksmithing, now in pixels. - - imageadd: cool swords and shit (thanks anne) - raspy-on-osu: - - tweak: thermomachine examine text -2020-09-07: - DeltaFire15: - - spellcheck: fixed a typo causing a span not to show. - Putnam for debugging ammo loading! Thx!!: - - rscdel: Removed spell blade, diamond picaxe, and fire wand from lava land loot - tables - - tweak: Each mini boss now has its own type of crate. - - tweak: Each spike has its own type of crate that it pulls its now smaller loot - table from - - balance: Moved god eye from spike loot table to hard spawn collosses fight - - balance: Moved holoparasight from spike loot table to bubble gum - - balance: Moved magic meat hook from spike loot table to drake - - rscadd: 2 more crates to Arena Shuttle as well as 4-4-4 of each new type of chest - - balance: Replaced the diamond pick loot with a better one - - tweak: Replaced the cursted katana with a non cursted verson that deals half the - damage and has less block! - - rscadd: Three new potions, blue heals the mind like a mama potion, Green heals - the soul aka the organs! Lastly Red heals the body, by 100 damage of each main - types. Best not to waste them! - - rscadd: Four more "wands" Spellbooks! These fun little guys shoot out its own - pages to do the affect, one will set the target on fire like a bullet, one will - harm them a bit, one will heal the target a small bit - How nice! Last one will - give them a few statis affects like a taser bolt but without as much power or - tasing affect -2020-09-08: - Ghommie: - - spellcheck: fixed names of the Electrical Toolbox goodie pack and green croptop - christmas suit. - - bugfix: Fixed turf visuals for real. Original PR by AnturK on tgstation. - KeRSedChaplain: - - soundadd: added borg_deathsound.ogg and android_scream.ogg - silicons: - - balance: meteor waves now have a static 5 minute timer. -2020-09-09: - Putnam3145: - - bugfix: Made superconductivity work for the first time literally ever. - timothyteakettle: - - bugfix: accents work better -2020-09-11: - Putnam3145: - - balance: Superconducting turfs now can't go below 0 celsius. -2020-09-12: - BlueWildrose: - - bugfix: The Polychromic winter coat's hoodie will now polychrome, alongside any - other new polychromic items with toggleable headwear. - - bugfix: Minesweeper will no longer blow up the player's ears when they select - "Play on the same board" - - rscadd: Slimepeople will find warm donk pockets among other toxin healing items - even more repulsive, as they are anti-toxic. - - tweak: Slimepeople are now neutral to gross foods. - DeltaFire15: - - balance: AIs can no longer qdel() the gravity generator - Putnam3145: - - code_imp: Added some unit tests for reactions. - - refactor: replaced handle_changeling and handle_bloodsucker with signal registration - Sonic121x: - - bugfix: Fixed pill button on chemical press - TheObserver-sys: - - rscadd: Brass now has a proper datum. Aspiring Forgetenders rejoice! - Trilbyspaceclone: - - bugfix: Race based drinks will no longer stay inside your blood for ever. - Tupinambis: - - tweak: Redid Cogstation atmos pipes to make it less cluttered. - - tweak: Removed a few doors from the main hallway to mitigate chokepoint issues - - bugfix: All belt hell conveyers are now on by default, so that belt hell actually - works. - - bugfix: IDs for poddoors and belts and the like. Everything is now properly hooked - and should work as expected (except for the pressure triggered mass drivers) - - bugfix: addresses most if not all roundstart active turfs. - - bugfix: Issue where wires were connected to the SMES improperly, and SMES were - not properly precharged, resulting in power failure earlier than intended. - - bugfix: various rogue turfs and wirings. - - bugfix: security office APC being hooked to maintenance for some reason. - - bugfix: TEG is now directly wired to the SMES. - - code_imp: 'adds a subtype of mass drivers that is triggered by things being on - it. TODO: Make these mass drivers trigger poddoors, to make belt hell fully - functional.' - lolman360: - - bugfix: glaives now work again - zeroisthebiggay: - - balance: Revolver is now poplocked down to fifteen people. -2020-09-16: - timothyteakettle: - - tweak: fixed an icon path -2020-09-17: - DeltaFire15: - - rscadd: Failing the plushmium reaction can now create peculiar plushies, depending - on reaction volume. - - bugfix: The mood-buff from petting a plushie now works properly again. - - bugfix: Fixed wacky necropolis loot chest behavior - EmeraldSundisk: - - rscadd: Adds the Research Director's office to Omega Station - - rscadd: Adds 2 new solar arrays (and control rooms) - - rscadd: Adds some action figures that weren't there previously - - rscadd: The CMO's office now has a light switch - - tweak: Slight readjustments to impacted areas - - tweak: Readjusts the toxins air supply line to (ideally) be easier to service - - bugfix: Department camera consoles should now be able to actually check appropriate - cameras - - bugfix: Xenobiology can now be locked down (by the Research Director) - MrJWhit: - - rscadd: Adds a brain damage line - Putnam3145: - - bugfix: Your balls finally feel full, again. - timothyteakettle: - - rscadd: due to changes in policy, and several lawsuits, Nanotrasen has been forced - to allow disabled people to sign up -2020-09-20: - DeltaFire15: - - bugfix: Sutures work on simplemobs again. - - bugfix: Attacking dismembered bodyparts now targets the chest instead, for weapons - aswell as unarmed attacks. - MrJWhit: - - rscadd: New sprites for chess pieces! You can craft them in-game with metal sheets. - silicons: - - balance: hulks can smash again (walls no longer break their hands) - - rscdel: acid no longer degrades armor -2020-09-22: - Arturlang: - - rscadd: TGUI Statpanel - YakumoChen: - - imageadd: Mechsuits, robotics jumpsuits added to RoboDrobe - timothyteakettle: - - tweak: character previews should be more consistent now -2020-09-24: - Putnam3145: - - refactor: Atmos is free. -2020-09-25: - Putnam3145: - - bugfix: Removed a non-working proc that already had its functionality implemented - in another proc in the same file. -2020-09-26: - CoreFlare: - - rscadd: IPC's can have hair. Why wasn't this added earlier. Use the bald hairstyle - for no hair. -2020-09-27: - SiliconMain: - - tweak: Holograms made from projectors (atmos, engi, sec, medical, ect...) can - no longer be contaminated by radiation -2020-09-28: - ArchieBeepBoop: - - rscadd: Craftable Micro Powered Fans - Degirin2120: - - rscadd: Added engineering hazard jumpsuits, can be found in the engidrobe, comes - in 3 varieties. - Putnam3145: - - tweak: Added a brute-force check-every-single-tile step to SSair when it has enough - time to run. - - balance: G fuid production is now much lower. - - rscdel: Supermatter sabotage objective's gone. - - balance: Subterfuge objectives are now all equally likely. - - spellcheck: Replaced a "(hopefully) 1" with a "2" - - tweak: Cryoing no longer unwins already-won objectives. - SiliconMain: - - tweak: Minor adjustment to material cost of long range atmos analyzer - Trilbyspaceclone: - - tweak: Most drinks now have some animation in them, from basic soda bubbles fizzing - around to ice cubes bobbing just a bit. - Tupinambis: - - bugfix: Ghost poly's color value is now a hex value instead of an oct value. This - has been a thing for OVER FIVE YEARS - - imageadd: Updates TEG, Antimatter, Jetpack sprites (CO2 and Oxy from Eris). - - imageadd: Replaced old chair sprites with new ones ported and modified from eris. - - tweak: Beds can now be placed both right and left. - - tweak: Subtle changes to stool legs to give them more of a shine. - raspy-on-osu: - - tweak: TEG power generation - thakyZ: - - rscadd: Added the ability to print the Light Replacer at the Engineering Protolathe - timothyteakettle: - - bugfix: turrets can once again be broken - - rscadd: you can now have heterochromia and select individual eye colours -2020-09-29: - timothyteakettle: - - bugfix: fixed a typo causing your right eye colour to save as the left eye colour -2020-10-01: - BlueWildrose: - - soundadd: Slimepeople are given unique laughs and screams. - - tweak: Adds "warbles", "chimpers", and "puffs" to the customizable speech verbs - for character. -2020-10-02: - ArcaneMusic, with minor tweaks by TheObserver-sys: - - rscadd: Adds and modifies fertilizers, as well as a new stat, Instability. - - rscdel: Removes the rather disused functionality of irrigation hoses, temporarily - disables circuit use on hydroponics trays. - - tweak: Plant Analyzer have been upgraded. Using one in hand will now switch between - a stat view of your plant, and a chemical view of your plant. tweak:Trays now - accept and store reagents, as well as coming with an autogrow mode. However, - these upgrades came at the cost of old self sufficiency, meaning you must attend - to your plants a bit more often. - - tweak: Earthsblood, while not being able to gild trays anymore, has been found - to still be quite powerful as a fertilizer. - CoreFlare: - - rscadd: Altcloaks! Available in loadout. - Detective-Google: - - rscadd: a smattering of clothes from the RP server - - rscadd: detective wardrobe - EmeraldSundisk: - - rscadd: Adds the "Skelter" space ruin - - code_imp: Creates a few new area designations for the Skelter - - rscadd: Cargo techs now have access to a "long pants" variant of their standard - work uniform - - rscadd: Adds said uniform to CargoDrobes and the loadout menu - ItzGabby: - - rscadd: Three new turf tiles. - - imageadd: Turf icons with multiple damage icons, with in-hand icons for each tile. - - spellcheck: Edited the name and description to wooden. - LetterN: - - rscadd: craftable railings - - code_imp: ports robust savefiles - MrJWhit: - - tweak: tweaked heavy suit dmi - - bugfix: Fixes drones not being able to quickslot items - Putnam3145: - - rscadd: New policy config for pyroclastic slimes. - - tweak: SDGF clones now naked. - - balance: SDGF is now way more likely to make a clone that will align with the - creator's goals, with purity, making it a better antagging tool. - - bugfix: SDGF clones now have the same traits as the original. - - bugfix: transfer_ckey now resets view, preventing things like SDGF clones with - much larger view range. - - config: 'Policy configs have been added for SDGF, currently unused: SDGF, SDGF_ALIGNED, - SDGF_UNALIGNED.' - - bugfix: Shivering now has thresholds and fever's thresholds now work. - - bugfix: Made allturfs setup actually set up all turfs. - - balance: Dynamic is now more aggressive with adding antags. - - bugfix: Fixes vore pref saving. - SandPoot: - - bugfix: Fixes headslugs being unable to recover their human form. - Tupinambis: - - rscadd: Adds methane and methyl bromide gases. - - tweak: Minor gas name/desc changes to improve consistency - - imageadd: Ports the methyl bromide tank from bay. Adds two new canister sprites - for the new gases and CH4 screen alerts. - - bugfix: fixed a mispelling in the wound armor value for the bounty hunter suit - dapnee: - - rscadd: atrium, clinic, an extra office, a pseudo public mining area, two more - deluxe dorms, micro beach, aux bathroom, two construction areas, mass driver, - more intercoms - - tweak: moved all of service, chapel, dorms, garden, holodeck to a different z-level, - RnD is more open, maintenance is a bit more random, more firelocks, added more - mine-able rock - - bugfix: fixed the buttons in xenobio, gave shutters to cargo's storage area, fixed - holodeck so it works now, fixed some techfabs being lathes, added sensors to - atmos tanks, more decals, couple more signs, little floral areas and sitting - areas added to break up hallway monotony, mech chargers are no longer missing - their consoles, whiteship won't crash into arrivals anymore while the area it - takes up is more telegraphed, APC placement on AI sat entrance, missing wire - node for the outer portion of the AI sat, civilian level now has a telecom relay - lolman360: - - bugfix: smonk machine runtimes - - bugfix: automatic hydro tray has a unique sprite now (fancy robot arm) - timothyteakettle: - - rscadd: added luminescent and stargazer sprites as selectable body sprites for - slimes - - tweak: wound exponent lowered slightly from 1.225 to 1.2 - - config: wound exponent and limb damage multiplier are now config values - - rscadd: ipcs and synthlizards are now treated as actual robots, with robotic limbs, - an extra organ, and better emp acts - - rscadd: surgeries for healing robotic limbs, and brain surgery for robotic heads - - bugfix: androids limbs now show up as intended - - refactor: emps now work from 1-100 severity instead of 1/2 and the severity reduces - as you move from the epicentre - zeroisthebiggay: - - rscadd: ratvar gf is complete -2020-10-04: - DeltaFire15: - - bugfix: Synths / IPCs are no longer wound immune. - - bugfix: Husked IPCs / Synths should now be rendered correctly. - - bugfix: Falling vendors now squish synths / IPCs' limbs again. - - bugfix: Synths and IPCs now do not have some fun roundstart oversights anymore. - - bugfix: Regenerate_limbs now works for carbons with the ROBOTIC_LIMBS trait. - - bugfix: Pacifists no longer counterattack on parries if that attack would be harmful. - - tweak: Heretic sacrifices now husk with the reason of burn, and deal some additional - damage. - - bugfix: Neovgre can no longer become invincible on clock tiles. - - bugfix: Plushlings no longer break when absorbing snowflake plushies. - Detective-Google: - - bugfix: the snow cabin doors actually bolt now - Putnam3145: - - bugfix: Ghosts are no longer incapable of going away. - monster860: - - tweak: The slimeperson swap-body UI stays open when you switch bodies - timothyteakettle: - - bugfix: limb id entry in mutant bodyparts now supports switching to/from species - with gendered body parts - - tweak: the minimum brightness of mutant parts is now a define -2021-01-21: - Acer202: - - bugfix: Main mining shuttle should no longer look at the public mining shuttle - and attempt to dock ontop of it. Monastery shuttle should now function again. - Acer202, with minor help from The0bserver: - - rscadd: After internal deliberation, CentCom has decided to run a limited reinstatement - of public mining shuttles for use in more tried and true station classes. CentCom - would like to remind you that this privilege is easily revoked, and that abuse - may result in immediate detonation. - - rscadd: Restores the mining shuttle on Pubby, Box, Delta, Meta, and Lambda Station. - ArcaneMusic, The0bserver-sys: - - rscadd: 'New from Hydrowear LLC: The Botanical Belt! This handy yellow belt lets - you hold most of your botany gear, and a few beakers for reduced bag and floor - clutter!' - - tweak: Gives Hydrotrays plumbing pipes automatically, allowing you to make a self - sustaining tray via plumbing. - - tweak: Gives Service access to Bluespace Beakers, at last, gives Cargo, Science, - and Medical the ability to construct reinforced plungers for use on lavaland. - ArchieBeepBoop: - - rscadd: Upgraded Advanced RTG Machine Preset - - bugfix: Outlet Injector Mapping Asset Layer Fix - - bugfix: Jacqueen and the Christmas tree should no longer spawn abstract things - that can cause shittons of runtimes. - Arturlang: - - bugfix: You can't tackle in nograv anymore - - tweak: You cannot spam drink from blood bags anymore - - bugfix: Blood bag drinking inefficiency is now the right way, so you loose some - of the blood drinking it straight - - bugfix: Handles more edge cases with construct soul returning - - tweak: Being sacrificed by the cult no longer removes all hope of rescue. - - bugfix: Makes construct mind returning more robust - - tweak: Prayers to admins now do a wee ding sound for all prayers, instead of just - chaplains - - bugfix: Fixes the mint machine's UI - - bugfix: Hopefully fixes whitescreen issues for TGUI UI's by giving assets more - time to get to the client - - bugfix: Fixes hijack implant APC UI, again - - code_imp: Comments out spaceman dmm do not sleeps for mob/proc/CommonClickOn, - atom/proc/attack_hand, datum/proc/keyLoop and mob/living/proc/Life - - bugfix: Bloodsuckers tresspass ability can no longer work while they are not awake. - - tweak: The cursed heart now only takes away half as much blood every loop, and - can be used as long as you are alive, instead if only you are awake/able to - use your hands - Bhijn: - - tweak: Changeling loudness is now determined as an average of all their abilities, - rather than the sum - - tweak: To compensate for this, blood tests now require a loudness value of 1 or - higher to detect ling blood. Additionally, blood test explosions are now triggered - only when the loudness value is higher than 2. - BlackMajor: - - tweak: Cyborg hypospray no longer injects if it means OD'ing while on help intent. - BlueWildrose: - - tweak: Nyctophobia quirk now has some light lag compensation. - - bugfix: Fixes cloning computer UI not updating when pressing certain buttons - - also adds extra check for names to update a message - - rscdel: Removes oversized genitalia analysis from medical scanners, since huge - dick and titty are no longer a problem anymore thanks to advancements in that - kind of technology when it comes to chemical fun times growth. - - bugfix: Fixed species-specific drinks not giving a mood boost if you are that - species. - - tweak: You will now only unbuckle fireman-carried/piggybacked people on disarm - or harm intent. - - balance: The traitor AI can no longer activate the doomsday device while carded. - - bugfix: Fixes noodle size appearance for 12+ inch members. - - bugfix: Fixed the subtle hotkey being weird with its input prompts. - - rscadd: Adds a subtler anti-ghost hotkey. Default key is 6. - - tweak: No more straining when your cock or breasts are growing via incubus draft - or succubus milk. - - rscadd: PubbyStation now has two Christmas Tree spawners. - - tweak: You can now have a max-roundstart-dicksize-config inch long johnson before - you start suffering blood loss and slowdowns instead of a 20 inch one. - - rscadd: Color Mates have been added to all stations (except Snaxi). Enjoy coloring - your attire without having to bug science! - - bugfix: Polychromic hoodies that were obtained from the loadout have functional - colorable hoods now. - - rscadd: Adds in timid woman/man costumes. Available at your autodrobe! Also adds - in garters as some new socks. - - spellcheck: Corrected the capitalization in gasmask concealment examine text - Chiirno: - - rscadd: Added the paramedics EVA suit as a purchase from the cargo console. - - rscadd: Paramedics office and Surgery Storage Room - - tweak: Remodeled the surgery room, as well as shrunk Morgue and Starboard Emergency - Storage. Fiddled with some areas for better map edit clarity and fixed one runtime - in Vacant Office A. - - imageadd: Added the paramedic closet sprite, a paramedic colored medical3 closet. - - code_imp: Added a paramedic closet, which is the standard medical3 closet with - their suit, a pinpointer, and a crew monitor added. - - tweak: Nightmare now deals additional damage to most light sources. - - bugfix: Nightmare now one-shots miners beacons and glowshrooms - - bugfix: Portable Chem Mixer now researchable from biotech node. - - tweak: Chem masters can now dispense 20 instances of its outputs instead of 10. - Delams-The-SM: - - rscadd: Added 3 new emotes *hiss *purr *meow - - soundadd: ported sounds from Citadel RP for *purr and *meow - - bugfix: fixed randomization of colors for things like mulligan and Stabilized - green slime extract for matrixed body parts - DeltaFire15: - - balance: Biomechanical (hybrid) bodyparts now have access to wound-fixing surgeries. - - tweak: A wound being fixed no longer just qdel()s surgeries connected to it. - - tweak: Some robotic surgery steps are now a bit more clear. - - bugfix: Organs no longer get fed to people after successfully being inserted into - them. - - tweak: Not completing the do_after of a surgery no longer causes you to attack - the target with whatever you were holding. - - rscadd: IPC cells & power cords are now printable after they are researched. - - rscadd: A new surgery, allowing revival of synths without a defib at hand. - - balance: 'Semi-permanent damage of Synth limbs caused by passing the damage threshold: - 10 <- 15.' - - tweak: The embed removal surgery now has a version for Synths. - - balance: EMPs no longer hardstun Synths. - - bugfix: Portals no longer runtime because of incorrect args. - - tweak: Abductors now can use experimental organ replacement surgery on robots - / synthetics. - - bugfix: Fixes a minor incorrectness in ratvarian borg slabs (ratvar_act -> ui_act) - - bugfix: Changelings no longer double-deathgasp when activating the regen stasis - ability while not dead. - - bugfix: People installing KA modkits in miner borgs is no longer broken. - - bugfix: Fixes the tail entwine messages displaying incorrectly. - - bugfix: Antagging / Deantagging Heretics now properly sets their special role. - - bugfix: The borg VTEC ability now actually gets removed when the upgrade is removed. - - bugfix: Supplypods shouldn't cause runtimes anymore, and shrapnel (pelletclouds) - should work for them. - - rscadd: Robots (anyone with the robotic_organism trait) have toxins damage replaced - with system corruption. See the PR for details. - - code_imp: Clockwork rites now support hiding specific rites from neutered servants. - - tweak: AIs now only have to kill people once instead of permanently. - - bugfix: Scripture no longer sometimes eats part of its invocation. - - balance: APCs and silicons are now more susceptible to powerdrains (by the power_drain() - proc, which is rare) - - balance: Void Volt has been modified from a chant to a singular pulse. - - balance: Robotpeople are now fully immune to the effects of alcohol (drunkness - etc.) - - tweak: Renames the alcohol intolerance trait in the code to make what it does - more clear. - - bugfix: Self-fueling weldingtools recharge fuel properly again. - - bugfix: Brass welders now actually recharge faster than experimental ones. - - bugfix: Repeatable surgery steps can no longer cause an infinite loop if not completing - the do_after - - bugfix: The Revenant self-revive ability is no longer broken. - - bugfix: Loot items mobs drop are no longer always failing to initialize. - - tweak: Instant summons can no longer do wacky stuff with disposals (and nukes). - - bugfix: Objectives are no longer very broken. - - bugfix: Bloodcult stunhands now work against clockies like they were supposed - to instead of hardstunning. - - balance: zeolites are now actual fermichems instead of being incredibly easy to - make. - - bugfix: Using syringes / droppers on chem heaters with beakers in them works again. - - bugfix: Some edge cases causing issues with system corruption shouldn't be able - to occur anymore. - - bugfix: Cyborg B.o.r.i.s. installation now checks for if the chest has a cell, - just like how it does with MMIs. - - bugfix: The 'Your body is in a cloner' notification works again - - bugfix: Hijack implants should work properly again (or, at least better) - - bugfix: Liches are now good skeletons again instead of weak ones - - bugfix: The piratepad control cannot be destroyed again. - - bugfix: Pirates have received new supplies of jetpacks instead of useless oxygen - tanks - - bugfix: Ratvarian AIs are once again able to show their linked borgs Ratvar's - light - - bugfix: Hijackers are once again unable to detonate borgs without being adjacent - to the console - - bugfix: Automated annoucement systems and gulag ore consoles no longer waste emag - charges - - bugfix: Automated announcement systems once again can be remote controlled by - non-AIs with silicon access - - bugfix: APCs being hijacked multiple times at once is no longer possible, preventing - some issues - - bugfix: Recharging APCs no longer use 0.2% of the power they should be using. - - bugfix: APCs no longer always use as much power as they can for their cell, even - if it is full. - - bugfix: Vampire shapeshifting should now behave as intended - - balance: Some synth damage stuff has been a bit rebalanced, see the PR for details. - - rscadd: Nanogel, available at medical and robotics, which fixes internal damage - in sufficiently repaired robotic limbs. - - balance: Robotic Limbs now each have their own damage threshhold values - - balance: Robotic Limb damage threshholds are now seperated into threshhold itself - and mindamage when passed balance; Hybrid limbs can now be injected with hypos, - but not sprayed (Still not healed by chems) - - tweak: Brain surgery has been tweaked back to allowing robotic limbs, blacklisting - IPC brains instead. - - tweak: Robot brain surgery can now be used on organic heads, if there is a IPC - brain in them somehow. - - tweak: The robot limb heal surgery can now be used even if the target's torso - is not robotic, as long as they have robotic limbs - - refactor: BODYPART_ROBOTIC / BODYPART_ORGANIC checks replaced with helper-procs - whereever possible. - - code_imp: Added a BODYPART_HYBRID define for robotic bodyparts that behave organic - in some regards. - - bugfix: The transmission sigil power drain works now - - bugfix: A certain lizard (totally not me) being stupid is no longer going to break - regenerate_bodyparts - - bugfix: Combat mode now will not stay permanently disabled due to status effects - not working as intended. - - bugfix: Attacking some certain objects no longer has no clickdelay. - - bugfix: the blacksmithing skill now works properly - - tweak: Anvils cannot be interacted with with hammers whilst they are already being - used - - tweak: If someone has no gloves when interacting with heated ingots, they no longer - ignore their effects. - - bugfix: A runtime caused by hallucinations is gone. - - bugfix: Cargo packs marked as 'no private buying' now actually register as such. - - balance: Fleshmend, Anatomic Panacea and bloodsucker healing now work for Synths - / IPCs. - - tweak: Medibots now ignore people they cannot help due to their biology. - - bugfix: get_damaged_bodyparts() is no longer broken. - - bugfix: Your target cryoing will no longer give you a free greentext. - - bugfix: Sleeper UI interactiveness now behaves correctly. - Detective-Google: - - rscadd: arcade carpet - - rscadd: explosions now get broadcasted to deadchat. - - rscadd: Lick radial - - bugfix: Hilbert's jukebox works - - bugfix: arcade carpets now actually work - - tweak: the snow taxi is no longer the slow taxi - ERP mains: - - rscadd: Subtler Around Table is now a verb - EdgeLordExe, MoonFalcon: - - balance: Ported a bunch of heretic-related tweaks and changes from tg - EmeraldSundisk: - - rscadd: Adds a few new area designations primarily for CogStation, incorporates - them into said map - - tweak: Reorganizes some area designations for ease of use, along with renaming - the central "Router" to "Routing Depot" - - bugfix: Fixes an incorrectly designated area in CogStation - - bugfix: Changes the area designations to be not varedited since the code didn't - like that anymore - - bugfix: The cargo bay conveyor belts not only work with the shuttle now but go - in the right direction to boot - - tweak: Slight visual adjustments to cargo in light of this - - rscadd: The arcade's got RAD carpet now - - bugfix: Fixes the conveyor belt issues in Delta Station's cargo wing - - rscdel: Removes some of the dirt around the affected area (presumably they would - have cleaned it up while working on it) - - rscadd: Adds a floor light to fix the "dark spot" cargo had - - rscadd: Adds a new "Computer Core" area designation for CogStation - - bugfix: Fixes some missing area strings - - tweak: Replaces some firelocks with directional ones as to ensure desks/counters - can still be accessed - - balance: The "Skelter ruin" now has stechkins as opposed to M1911s - - tweak: Skelter's decorative bullet casings replaced to factor in the change in - caliber - - rscadd: Skelter now has a combat knife and fluff note - Ghommie: - - bugfix: You can access the mime / clown mask skins radial menu once again. - - bugfix: Dice bags no longer act like cardboard boxes. - - bugfix: Abductors should be no longer mute. - - bugfix: Item action buttons should now properly show the item current overlays, - most times. - - bugfix: The blackbox should now go into your hand slot when pried out, rather - than tumbling on the ground everytime. - - tweak: The Quick Equip hotkey is now usable by all living mobs (so long they have - hands and equipment slots) - Ghommie, porting PRs by MMMiracles and pireamaineach, credits to BlueWildrose too.: - - rscadd: You can now draw on plasmaman helmets with a crayon to turn their frown - upside-down. - - balance: Plasmaman helmets no longer hide your identity when worn by themselves. - - balance: Plasmaman helmets now have welding visors, which can't stack with their - torches in the helmet and are visible. - Hatterhat: - - rscadd: Energy sabre reskin for the energy sword - access via alt-click. - - bugfix: Alt-click reskins are fixed. - - tweak: Defibrillators and their many, many overlays were moved to another .dmi. - - tweak: You can now change the color of an energy sword via multitool. Not deswords. - Yet. - - imageadd: The Syndicate appear to be issuing new revolver variants. - - rscadd: Basic sticky technology is now a roundstart tech. Advanced sticky technology - is BEPIS-locked, though. Theoretically. - - tweak: Non-smithed katanas (including the temporal katana) can now fit in the - twin sheath. - - tweak: Cotton and durathread processing by hand now acts like grass. Stand on - a pile of cotton (or durathread) and use a single bundle from it. - - spellcheck: Utility uniforms now comply with the "nonproper equipment names" thing. - - bugfix: The CapDrobe now allows the captain to get his own clothes for free. Probably. - - tweak: All captains' clothes now offer 15 woundarmor, up from the 5. Because apparently - only the suit and tie and its suitskirt subtype have this wound armor, which - is dumb. - - rscadd: The nature interaction shuttle with the monkeys now has tiny fans on the - airlocks in, because that's apparently a feature that was missing. - - rscadd: More bags have been added to department vendors. - - balance: Every roundstart species (and also ash walkers) now has flesh and bone - that can be wounded. - - balance: Recipes for sutures, regen mesh, and sterilized gauze have been adjusted - to be easier, mostly. - - balance: Sterilized gauze is better at absorbing blood and being a splint. - - bugfix: Energy sabres now have an off inhand. - - balance: The bone gauntlets should be slightly less murderously punchy on the - fast punches mode. - - tweak: RPEDs now drop their lowest part tier first when quick-emptied (used inhand). - - tweak: Improvised gauzes can now be crafted in stacks up to 10, like their maximum - stacksize implies they should be capable of doing. - - bugfix: Pouring sterilizine on gauze now takes the proper 5u per sterilized gauze - instead of 10u. - - bugfix: Cryogenics now screams on common again when your fuckbuddy heads out. - - rscadd: Survival daggers! A slightly more expensive survival knife that comes - with a brighter flashlight. On the blade. - - tweak: Luxury pod capsules look different from normal capsules. - - rscadd: The wastes of Lavaland and the icy caverns of Snow Taxi rumble in unison. - - tweak: Exosuits sold on the Supply shuttle no longer leave wreckages. - - rscdel: Apparently, shrink rays were buyable again, despite a PR having been made - a while ago specifically for removing shrink rays. They're gone again. - - rscadd: Changeling bone gauntlets! They punch the shit out of people really good. - - tweak: Guerilla gloves and gorilla gloves inherit the strip modifiers of their - predecessors, because apparently they had those. - - balance: Pugilists now always hit the targeted limb and never miss. - - rscadd: The dock-silver standard set by Box and Meta has been enforced across - maps in rotation (Delta, Pubby, Lambda). - - bugfix: The Box whiteship now has its missing tiny fan back. - - bugfix: The survival dagger light on the sprite now actually turns on and off. - - balance: The survival dagger in the glaive kit that can also be bought by itself - is now better at butchering things. - HeroWithYay: - - bugfix: Changed description of Necrotizing Fasciitis symptom. - - tweak: Wormhole Projector and Gravity Gun now require anomaly cores to function - instead of firing pins. - KeRSedChaplain: - - imageadd: Resprited the brass claw - LetterN: - - rscadd: 2 more ways to get up from z1 - - tweak: tweaked the z2 garden to be less blank - - bugfix: fixed telecomms pda log - - rscadd: Coin & Holochip support for slot machine - - admin: Stickybans are now saved in the DB too - - soundadd: Immersive ™ audio reverbs. (also adds multiz audio) - - code_imp: Semi-hardsync from TG - - code_imp: Updates rust-g - - code_imp: Uses git CI instead of travis/appveyor now - - code_imp: Updates git and build tests. - - bugfix: minimap text - - code_imp: ports cinematic upgrades - Linzolle: - - bugfix: entertainment monitors no longer invisible - - rscadd: entertainment monitors now light up and display text when motion is detected - in thunderdome - - bugfix: lizard snouts are no longer *slightly* lighter than they are supposed - to be. - MrJWhit: - - rscadd: Expanded space hermit base - - tweak: Replaced engineering fuel tank with a large fuel tank - - tweak: Changed access to sec suit storage from armory access in every map to other - security access - - rscadd: Adds a space loop to every map in toxins - - rscadd: '' - - tweak: Added the ability for cargo to buy a large welding tank - - imageadd: Tweaked large tank reagent sprites to /tg/'s - - tweak: Gives metastation toxins storage a scrubber and a vent - - tweak: Updates suit storage info on Tip Of the Round. - - tweak: Increased christmas event from 22th to 27th to 10th to 27th - - tweak: Removes an opposum from the wall - - tweak: Donut boxes show what's inside of them now - - tweak: Updated meat icons - - admin: Canceling events gives more time to stop from 10 to 30 - - tweak: Fixes two chairs on one table - - tweak: Removed the wires connecting the AI from the rest of the station on cogstation. - - tweak: Fixes experimenter on cogstation. - - tweak: Less pipes in the overall area in toxins on cogstation - - tweak: Small fixes on security on boxstation - - tweak: Updated jukebox sprite. - - tweak: Fixes maint area in boxstation - - tweak: Christmas starts on the 18th now - - rscadd: Adds a goose bar sign - - bugfix: Effects can no longer trigger landmines - - rscdel: Removes the screen flashing on climax. - - rscadd: Makes gas sensors fireproof. - - tweak: A small bucket of random fixes, - - tweak: Minor fixes to kilo - - tweak: Porting garbage collection tweak from /tg/ - - tweak: Updates our dark gygax sprites to /tg/'s - - tweak: Bugfix of a morph becoming an AI eye - - tweak: Mining station oxygen locker on the cycling airlock starts out wrenched. - - balance: Nerf combat knife damage - - bugfix: Code improvement on ventcrawling - NT Cleaning Crews On Break: - - rscadd: Most kinds of dirt, grime, and debris are now persistent. Get to work, - jannies. - - rscadd: Dirt can now be removed by tile replacements. Other cleanable decals can't, - though. - Putnam3145: - - tweak: Replaces majority judgement with usual judgement. - - bugfix: Toilet loot spawners don't lag the server on server start with forced - hard dels. - - bugfix: vore prefs save now - - tweak: gear harness no longer magically covers up the body mechanically despite - covering up nothing visually - - balance: Regen coma now puts into a coma even from crit or while unconscious. - - bugfix: Regen coma now properly weakens while asleep. - - bugfix: Multi-surgery unit test no longer fails at random. - - refactor: Dwarf speech is no longer absolutely paranoid about word replacement. - - balance: Spontaneous brain trauma now requires minimum 5 players - - tweak: Grab bag works as advertised. - - balance: Xeno threat in dynamic tripled. - - code_imp: 'Vote system #defines are now strings' - - rscadd: Stat panel UI for ranked choice votes - - rscadd: A fallback for dynamic antag rolling that allows for it to just try between - traitor, blood brothers, heretics, changeling, bloodsucker and devil until there - are enough roundstart antags. This can also happen randomly anyway. Blood brothers - and devil are disabled for now, but the code is there to enable them. - - rscadd: A new storyteller, "Grab Bag", that forces the above round type. - - bugfix: atmos subsystem no longer dies if there's too many gases - - bugfix: Emotes can properly be filtered for in TGUI. - - bugfix: Holofirelocks work now. - - bugfix: adminhelping no longer removes entire admin tab - - bugfix: end of round no longer removes entire admin tab - - bugfix: Fixed a runtime in every healing nanite program. - - bugfix: removed a unit test causing master to fail - - tweak: Planetary atmos no longer does superconduction. - - bugfix: Dynamic vote no longer shows the none-storyteller. - - tweak: You can now exit polycircuit input - - bugfix: Polycircuits now check for range - - bugfix: gear harness alt-click is now sane - - code_imp: rolldown() and toggle_jumpsuit_adjust() now no longer mix behavior-that-should-be-overridden - and behavior-that-shouldn't-be-overridden in ways that make no sense. - - tweak: Gear harness now covers nothing. - - bugfix: Chemical stuff now displays fermichem stuff properly - - balance: Rad collectors now get 1.25x as much energy from radiation - - balance: Rad collectors now put out 1.25x as much stored energy per tick - - balance: Above two rad collector changes give a total 56.25% power output increase - - balance: Zeolites now only generate 1/5 the heat when reacting and don't require - a catalyst. - Ryll/Shaps: - - admin: Fixed an issue with player logs becoming confused when someone triggers - multiple events within one second (like being attacked by two people at the - same time) that would cause holes in the logs - SandPoot: - - tweak: You can attack a pile of money on the floor with your id to put it all - in quickly. - - refactor: Changes the limb grower a lot. - - bugfix: '"Limb" costs on limbgrower are actually displayed like it was meant to - all along.' - - code_imp: Swaps the gift static blacklist with a global list one. - SiliconMain: - - tweak: Engi department has gas masks in loadout - - tweak: hololocks (which haven't worked for god knows how long) commented out until - auxmos is merged - Sonic121x: - - rscadd: alarm ert hardsuit sprite for naga and canine - - tweak: adjust the naga ert hardsuit to cover the hand - - bugfix: cydonia hardsuit helmet - - rscadd: digi sprite uniform - - bugfix: digi leg suit - SpaceManiac: - - bugfix: Fixed the maphook - Thalpy: - - bugfix: fixes some bugs in jacqs code from edits to the codebase - The Grinch: - - rscdel: infinite presents from hilbert hotel - TheObserver: - - rscadd: Re-adds the rifle stock, and sets the improv shotgun to be as it was. - - rscdel: The maintenance rifle has been shelved - for now. Watch this space. - TheObserver-sys: - - bugfix: Drake? Where's the dead fairygrass sprite? - TheSpaghetti: - - bugfix: no more tumor bread double punctuation - Trilbyspaceclone: - - tweak: Zeolites now use gold rather then uranium for catalyst - - tweak: Zeolites are not as hard to make ph wise - - tweak: Making Zeolites heats up the beaker less allowing for better control - - tweak: ASP 9mm and M1911 can now have suppressers added - - balance: Brass welders are 50% faster at refueling - - code_imp: redoes self fueling welders in the code to be less speggie - - rscadd: the corporate unifoms can now be gotton in the clothing mate vender - TripleShades: - - rscadd: 'Firelock to Surgery Bay drapes change: Swapped Nanomed and Fire Alarm - button locations in both Surgery Bays change: Removes the double mirror in both - Surgery Bays to be a singular mirror change: Moved an intercom to not be doorstuck - below Paramedical Office remove: One Surgery Observation Fire Alarm button' - - rscadd: 'New Paramedic Office next to Genetics where the old Genetics Reception - used to be change: Surgery, Surgery Observation, and Recovery Hall layout revamped - drastically change: Maints below Surgery lowered by one tile to recover lost - tile space from Surgery expansion' - Tupinambis: - - rscadd: Arachnids (spider people) with limited night vision, flash vulnerability, - and webbing. - Vynzill: - - rscadd: 'new gateway mission mapadd: jungleresort map' - - bugfix: fixes high luminosity eyes - Xantholne: - - bugfix: Fixed new birds changing back to basic parrot when sitting - - rscadd: New parrots from the RP server, can be found in Bird Crate in Cargo - - rscadd: You can now tuck disky into bed - - rscadd: You can now make beds by applying a bed sheet to them - - rscadd: You can now tuck in pai cards into bed - - rscadd: Added bed tucking element, can be added to any held object to allow tucking - into beds - - bugfix: Twin Sword Sheaths have an equipment icon and icon when worn now and make - a sound when sheathed/unsheathed - Yakumo Chen: - - balance: Slime Jelly is no longer obtainable from slimepeople. Go ask Xenobio - YakumoChen: - - balance: "To lower production costs, Buzz Fuzz is now manufactured with Real\u2122\ - \uFE0F Synthetic honey." - Zandario: - - code_imp: Added some framework for future species expansions, including clothing - refitting. - - refactor: Made majority of the relevant Species IDs and Categories pre-defined, - also for easier expansion and use. - - bugfix: lum slime sprites work again - - code_imp: Slapped the Species Defines where relevant - corin9090: - - tweak: The chaplain's prayer beads can now be worn on your belt slot - kappa-sama: - - bugfix: super saiyan - - tweak: ishotgun crafting recipe no longer requires plasteel and is slightly more - convenient - - balance: ishotgun does 45 damage now instead of 40.5 - - rscadd: s - - tweak: s - - balance: s - - bugfix: s - - rscadd: A new spell for the wizard and his martial apprentices, the Inner Mantra - technique. It makes you punch people really good and makes you durable, but - drains your energy while it's active. - - rscadd: A self-buffing spell for valiant bubblegum slayers that is ultimately - useless on lavaland and probably overpowered for miner antagonists. Go figure. - At least all it does is let you punch hard while draining your health every - second. - - balance: bubblegum now drops a book that makes you into an abusive father instead - of a shotgun that plays like pre-nerf shotguns - - soundadd: a powerup and powerdown sound effect - - imageadd: two icons for two buff spells - keronshb: - - bugfix: Allows Energy Bola to be caught - - balance: This also allows them to be dropped/picked up. - - rscadd: Adds a reduced stamina buffer for SCarp users - - rscadd: Gives SCarp users a better parry - - rscadd: Adds the SCarp bundle which includes a bo staff - - rscadd: Lets Carp costumes carry Bo Staffs - - balance: reduces the stamina damage of scarp slightly - - balance: reduced the blockchance of the bo staff - - rscadd: Adds more room to northwest maint - - rscadd: Adds a bridge between Atmos and the Turbine. - - balance: Blob Resource Tower to 2 points per instead of 1 point per. - - balance: Blob Factory Towers can be placed 5 tiles apart instead of 7. - - bugfix: Fixes Blobbernaut Factories consuming Factories if no naut is chosen. - - bugfix: Fixes Reflective Blobs - - rscadd: Re-adds the Clown Car to the clown uplink - - balance: 15 >16 TC cost - - balance: bonks on external airlocks - - bugfix: Fixes the parry data for scarp - kittycat2002: - - rscadd: set the name of /datum/reagent/consumable/ethanol/species_drink to Species - Drink - kiwedespars: - - balance: balanced bone gauntlets. - - rscadd: the robust dildo weapon now has sound. - necromanceranne: - - bugfix: Fixes various sprites for bokken, as well as being unable to craft certain - parts and duplicate entries. - - rscadd: 'Bokken now come in two lengths; full and wakizashi, and two varieties: - wood and ironwood. They have different stats for all four.' - - rscadd: Bokken require menu crafting and part construction, as well as more complicated - materials. - - tweak: Bokken (long and short) require wood, cloth and leather to craft with a - hatchet and screwdriver. - - tweak: Ironwood bokken (long and short) require ironcap logs, cloth and leather - to craft with a hatchet, screwdriver and welder. - - balance: Twin sheathes can only fit a pair of blades (longsword + shortsword) - or they can fit two shortswords. - - bugfix: Fixed a twin sheath runtime. - - imageadd: A lot of bokken related sprites received an overhaul. Added overlay - sprites for weapons sheathed in the twin sheathes. - - imageadd: The extradimensional blade received improved sprites for inhands/back - sprites. - - bugfix: You can now make all the variants of the bokken. - - bugfix: Removes a duplicate sprite. - - tweak: Renames all instances of 'ironwood' to 'steelwood'. - - rscadd: Adds new roboticist labcoat sprites! - qwertyquerty: - - bugfix: Flash the screen on climax - raspy-on-osu: - - spellcheck: salicylic acid - - tweak: space heater heating range and power - - tweak: windoor open length - shellspeed1: - - rscadd: Wings from Cit RP have been ported over - - rscadd: Moth wings from cit have been ported over - - bugfix: Cleaned up some pixels on existing moth wings. - - tweak: Organized the lists for wings by if they are for moths or not and than - by alphabetical. - - balance: Lings now have infinite space for DNA. - - rscadd: All xenomorph types have been added as corpses for mapping purposes - - balance: The dead xenomorphs in the lavaland xenomorph hive now have more variety. - - tweak: Floor bots are now buildable with all toolboxes. - - rscadd: 'Xenomorph hybrids can now select wings ~~add: Xenomorph hybrids can now - speak xenomorph~~' - - rscadd: Xenomorph tongues are available for customization. - - rscadd: Mining borgs can claim points again - - rscadd: Construction bags have been added, use them to carry all sorts of construction - bits. - - rscadd: A recipe has been added to cloth stacks to make material and construction - bags. - - balance: Material bags and construction bags are now available in engineering - lockers. - - rscadd: Adds the disposable sentry gun from tg for 11tc each. - - rscadd: The exofab can now print prosthetic limbs - - bugfix: The exofab was missing access to multiple cybernetic organs. This has - now been rectified. - - rscadd: A new recipe for a spicy has been given to us by a strange business man. - - rscadd: The bluespace navigation gigabeacon design has been added to shuttle research - for those wanting to take their ships around space more. - - tweak: Xenomorph powers now list plasma cost in their description. - silicons: - - tweak: nanite resistances tweaked - - rscadd: new nanite programs added for locking the user out from being modified - by consoles or antivirals. - - rscdel: anomalies no longer spawn in walls - - rscadd: 'Twitch Plays: Clown Car' - - rscadd: pugilists can now parry - - balance: c4 can no longer gib mobs - - tweak: medium screens are better now - - tweak: text formatting now uses one character instead of two around the text to - emphasize. - - rscadd: colormates - - balance: shoving yourself up now costs 50% more - - bugfix: dullahans enabled - - rscadd: tailed individuals can now target groin to intertwine tails on grab intent. - - rscadd: Clowns now have unpredictable effects on supermatter crystals when dusting - from contact. - - tweak: anyone new to the server is lucky enough to have their sprint default to - toggle instead of hold - - balance: stamina crit is only removed when at or under 100 stamina, rather than - 140. stamina crit threshold is still at 140. - - tweak: luxury shuttle no longer has noteleport - - rscdel: now only poly gets a headset on spawn, not all birds. - - tweak: the warp implant now actually warps you back 10 seconds. leaves a trail, - though. now unlimited us. - - bugfix: things in DEATHCOMA do not deathgasp on death - - tweak: Meth and changeling adrenals no longer ignore all slowdowns, rather damage - slowdowns. - - rscadd: you can now be an angel using a magic mirror again - - tweak: command headsets are 120% instead of 160% - - bugfix: no more emote italics - - rscadd: players can now respawn/return to lobby as a ghost after a 15 minute (default) - delay and rejoin on another character with some/many restrictions - - rscadd: cryo now preserves everything - - bugfix: Magrifle ammo no longer glows. - - tweak: temperature slowdown divisor nerfed to 35 from 20. - - balance: dna melt drops all items being destroying you - - bugfix: keybinds generate anti-collision bindings where necessary automatically - now - - balance: changeling combat mutations rebalanced. most of them take chemicals to - upkeep now. - - rscadd: set-pose has been added - - tweak: temporary flavor text renamed to set pose, fully visible in examine - - bugfix: ninja gloves no longer hardstun - - balance: ninja gloves now cost half as much to use to compensate - - bugfix: simple mobs are now immune to radioactive contamination - timothyteakettle: - - bugfix: time for memory loss message to show up when being revived is now correctly - 300 seconds, instead of 30 - - bugfix: the load away mission verb won't crash the server now - - rscadd: roundstart slimes can turn into puddles now - - rscadd: all gas masks (but welding + glass) can be alt clicked to show/hide identity - - tweak: autosurgeons from travelling trader rewards now only have one use - - bugfix: fixes held items proccing crossed when passing someone - - tweak: you can now get a family heirlooms based off your species instead of job - - tweak: changeling stings retract upon turning into a slime puddle - - tweak: you cannot transform into a slime puddle with a no drop item in your hands - - tweak: slime puddles are now transparent and their colour looks more natural in - comparison to the user - - tweak: slime puddles are now even slower - - tweak: slime puddles now get no protection from worn clothing - - rscdel: removes two debug messages left in from my prior eye customization pr - - rscadd: adds unlockable loadout items, corresponding category in loadouts, etc - - rscadd: added in-game age verification as an alternative to access requests - - bugfix: disabling adminhelp noises no longer disables looc - - bugfix: apids render now - - bugfix: you can now only entwine tails with people who have a tail - - bugfix: custom eyes and tongues now properly carry across cloning - - rscadd: re-adds the holoform verb for people who want to use it over going through - the char list - - bugfix: eye sprites should look normal once more - - rscadd: licking people washes pie off their face - - rscadd: you can now pick your eye sprites from customization - - tweak: looking at loadout equips loadout items on your preview image instead of - job items - - tweak: custom holoforms are now accessible through an action instead of through - verbs - - tweak: AI holoforms can now emote - - tweak: cloning now correctly copies your blood colour, body sprite type and eye - type - - bugfix: species with NOTRANSSTING cannot have envy's knife used on them - - rscadd: avian/digitigrade legs have been added for slimes - - rscadd: you can teleport bread - - tweak: slime puddles are no longer layered down one layer - - tweak: you cannot tackle with two paralysed arms - - tweak: tackling with a single paralysed arm lowers your tackle roll by 2 - - bugfix: circuits get pin data proc is sanitized when text is returned as data - - rscadd: loadout now has save slot support and colour choosing/saving for polychromic - items - - rscadd: polychromic maid outfit - - rscadd: you can rebind communication hotkeys and they're the default now - - rscadd: you can now customize your size from 90% to 130%, going below 100% makes - you have 10 less max health - - rscadd: '*squeak' - - rscadd: anthromorphic synth species - - rscadd: improvements to the automatic age gate - - tweak: antag items are now of critical importance and wont fail to be placed on - the character - - bugfix: a tonne of fixes to colourisation of parts, too many to name, including - some sprite fixes - - rscadd: things now have their own individual primary/(secondary)/(tertiary) colours - as required, and these can be modified by you - uomo91: - - bugfix: Fixed "Show All" tab in player panel logs being broken. - - bugfix: Whispers, OOC, and various other things display differently in logs, visually - distinguishing them from say logs. - - refactor: Player panel logs will now show all logs chronologically, so you'll - see commingled say and attack logs if you're on the "Show All" tab, etc... - yorii: - - bugfix: fixed botany rounding error that caused grass and other plants to misbehave - zeroisthebiggay: - - bugfix: legion now drops chests - - rscadd: Traitor assistants can now purchase the patented POGBox! Put TC into it - for even higher damage! - - balance: MEGAFAUNA DROPS ARE LAVAPROOF - - imageadd: cool codex cicatrix inhands - - rscadd: gravitokinetic stands from tg - - balance: buffs stands overall - - bugfix: protector stands no longer become tposing invisible apes sometimes - - bugfix: jacqueline spawns on boxstation - - rscadd: secsheath for your cool stunsword at your local security vendor. you gotta - hack it first though. - - imageadd: fuck the r*d cr*ss - - rscadd: The legion megafauna has been reworked. The fight should now be both slightly - harder and faster. - - balance: You can no longer cheese the colossus by being a sand golem and simply - being immune. -2021-01-22: - Arturlang: - - rscadd: Adds a way to give items to people, you can combat mode rightclick to - offer it to one person, right click on people without mode and click the give - verb, or use the hotkey CTRL G to offer it to everyone around you -2021-01-25: - MrJWhit: - - bugfix: Alien radio code - - rscadd: Microwave can now be cleaned by a damp rag as well as soap. - - bugfix: Removes some unused code, and improves some other code. - - rscadd: The AI has a verb to look up and down z-levels - - bugfix: Making a monkey into a human doesn't unanchor random things on the tile - - bugfix: Makes a few slight improvements to drinking code - - tweak: Makes encryption keys be put in the hands of the user when able instead - of being dropped on the floor when removed from headsets - raspy-on-osu: - - refactor: ventcrawling - silicons: - - tweak: you can now shove yourself up in any intent, not just help. -2021-01-27: - ArcaneMusic, ported by Hatterhat: - - rscadd: Strike a hydroponics tray with a fully-charged floral somatoray to lock - in a mutation. - - rscadd: Floral somatorays now have the ability to force a mutation in a plant. - This should drain the cell in a single shot, but we'll see. - - balance: Somatorays now take uranium to craft instead of radium. - Arturlang: - - rscadd: Actually adds a right click give option - - rscadd: Revenants can now clickdrag to throw stuff at people, with some items - doing various things at the same time. - DeltaFire15: - - bugfix: The woundmending rite no longer causes runtimes. - - bugfix: Ratvarian borgs can now use their tier-0 spells. - - balance: Ratvarian borgs can always use their assigned spells, if there is enough - power. - - admin: The heretic antag panel now shows their sacrifices & current sacrifice - targets. - - tweak: The heretic roundend report now shows their sacrifices and nonsacrificed - targets. - - bugfix: Living hearts can no longer select the same target as another living heart, - removing a certain problem. - Hatterhat: - - tweak: Department budget cards have been readded. TO THE CODE. NOT LOCKERS. - - tweak: Also budget cards now look more like every other ID - see tgstation#55001. - - balance: One of the contractor tablet's payouts has been raised from a small payout - to a medium payout. - - balance: The free golem ship's GPSes no longer start on. They were never meant - to, but they did. - - rscdel: Headsets can't be found on most legion corpses now. - - rscdel: The flash on the assistant corpse is gone, too. - MrJWhit: - - tweak: Remaps some air alarms for sanity. - SandPoot: - - bugfix: The drop circuit can no longer drop things that are not inside it. - raspy-on-osu: - - bugfix: bespoke ventcrawling element not detaching due to malformed call - shellspeed1: - - bugfix: Floorbots had had a software update, preventing them from dogpiling on - their target as easily as they did before. - - soundadd: Floorbots will now play a small chime when stacked on top of each other - to indicate that they're moving apart. - timothyteakettle: - - rscadd: blobs can use the 'me' verb - - admin: adminhelps and pms only sanitize once instead of twice -2021-01-28: - silicons: - - rscadd: colormates can now paint some mobs. - - bugfix: 1 dev explosions shouldn't delete brains anymore -2021-01-29: - MrJWhit: - - tweak: Ported the QM, Captain, CMO, and HoS cloaks from beestation. - - rscdel: Removes excess air alarms from boxstation - TripleShades: - - bugfix: fixes engineering secure storage being the wrong area because I fucked - that up previously my bad - - bugfix: removes funny extra light switch under right surgery table in surgery - oops - - rscadd: Added chairs to the corpse launch viewing area - - rscadd: Small garden plot for flowers for parity with other station Chapels - - rscadd: Plain Bible to glass tables in Chapel - - rscadd: Candles and Matchbox to glass tables in Chapel - - rscadd: More glass tables, with a chaplain figure and another spare bible. - - rscadd: Bookcase to Box Chapel for parity with other station Chapels - - rscadd: Minimoog to Box Chapel as substitute for a church organ - - rscadd: 'Holy department sign just below Chapel change: Expanded the corpse launching - area to feel less congested change: Added windows to the corpse launch so you - can look inside I guess? change: Moved flowers and burial garments to the corner - next to the corpse launcher change: Box Chaplain''s office door is moved over - one change: Confessional is now connected to Chaplain''s office for parity with - other station Chapels change: Moved coffins over to old confessional location - change: Box Chapel now has pews instead of stools change: Box Chapel Confessional - is now lit instead of being nearly pitch black remove: Two coffins from Chapel' - timothyteakettle: - - bugfix: the miner bedsheet will now increment its progress when you redeem points - from the ORM - - rscadd: you can add custom names and descriptions to item's on the loadout now - zeroisthebiggay: - - rscadd: roundstart aesthetic sterile masks and roundstart paper masks - - rscadd: more accessory slot items - - rscadd: cowbell necklace happy 2021 - - rscadd: shibari ropes & torn pantyhose -2021-01-30: - timothyteakettle: - - rscadd: adds 'clucks', 'caws' and 'gekkers' to the speech verb list - zeroisthebiggay: - - rscadd: some more FUCKING hairs - - imageadd: uncodersprites the advanced extinguisher -2021-01-31: - Putnam3145: - - balance: fermichem explosion EMPs don't cover the entire station -2021-02-02: - silicons: - - rscadd: pais can now be carried around piggybacking/fireman - - balance: Meth and Nuka Cola once again, speed you up. -2021-02-03: - Hatterhat: - - bugfix: The green energy sabre's sprite now respects proper handedness. -2021-02-05: - SmArtKar: - - rscadd: The orbit menu now has an Auto-Observe button! No more sifting through - the lame observe menu to snoop in people's backpacks! Also, orbit menu now refreshes. - - bugfix: KAs are no longer getting broken when fired by a circuit - keronshb: - - balance: Force and damage > 15 from 18/25 - - balance: Knockdown put down to 5 from 30 - - balance: Armor pen down to 10 from 100. - - balance: Makes cell chargers, charge faster. - raspy-on-osu: - - bugfix: alien royals can no longer ventcrawl - shellspeed1: - - balance: There actually needs to be people for zombies to happen now. - timothyteakettle: - - rscadd: dwarf facial hair is no longer randomised -2021-02-07: - Thalpy: - - refactor: 'Dispenser: Adds the ability to store a small amount of reagents in - the machine itself for dispensing. Reacting recipies cannot be stored. Size - of storage increases with bin size.' - - refactor: 'Dispenser: Allows reagents to be color coded by pH' - - refactor: 'Dispenser: Each reagent displays it''s pH on hover' - - refactor: 'Dispenser: Allows the user to toggle between buttons and a radial dial' - - refactor: 'Dispenser: When the dispencer is upgraded it can dispense 5/3/2/1 volumes - based on rating refactor: Dispenser: as it was before. This does not break recorded - recipes.' - - tweak: Adds a round function to some numbers so they're not huge - - tweak: The Chem master can now get purity for all reagents when analysed - - bugfix: Synthissue fixes - - tweak: buffers now have a strong and weak variant. Weak can be dispensed, and - strong can be created. Strong buffers are 6x more effective. - - bugfix: Some buffer pH edge calculation fixes - TyrianTyrell: - - rscadd: added a signed language, that can't be used over the radio but can be - used if you're mute. also added the multilingual trait. - - imageadd: hopefully added an icon for the signed language. - - code_imp: changed how some traits function slightly. - dzahlus: - - tweak: tweaked a few sounds - - soundadd: added a new weapon sounds - - sounddel: removed old weapon sounds - - code_imp: changed some sound related code - silicons: - - rscadd: syndicate ablative armwraps have been added. -2021-02-09: - Chiirno: - - rscadd: Adds clown waddle to clown shoes. Enhanced Clown Waddle Dampeners can - be engaged in-hand with ctrl+click, _but why would you?_ - MrJWhit: - - rscadd: Re-adds theater disposal outlet, and makes dorms disposal able to have - things sent to it on boxstation. - TyrianTyrell: - - bugfix: made default tongue able to speak signed language. - timothyteakettle: - - balance: sentient viruses can now infect synths and ipcs -2021-02-11: - Adelphon: - - rscadd: Charismatic Suit - - rscadd: Urban Jacket - DeltaFire15: - - tweak: Added nanogel to the robodrobe. - Putnam3145: - - rscadd: Config to keep unreadied players from mode voting - dzahlus: - - bugfix: fixes grenadelaunch.ogg being used where it shouldn't and makes mech weapons - use correct sound - keronshb: - - balance: 10 > 30 second for Warp Implant cooldown - - rscdel: Comments out power sink objective. - timothyteakettle: - - bugfix: persistent blood should stop being invisible and alt clicking it shouldn't - return the entire spritesheet - - admin: pickpocketing is now logged using log_combat - zeroisthebiggay: - - tweak: the aesthetic sterile mask no longer hides faces so you can cosplay egirls - and keep flavortexts -2021-02-12: - Hatterhat: - - balance: The ATVs on SnowCabin.dmm have been replaced with snowmobiles. - MrJWhit: - - tweak: Random deltastation fixes. - - tweak: Gives boxstation vault door actual vault door access - silicons: - - balance: Voice of God - sleep removed, stun staggers instead, knockdown is faster - but does not do stamina damage, vomit is faster but doesn't stun -2021-02-13: - Hatterhat: - - balance: Energy bolas now take 2.5 seconds to remove and dissipate on removal. - timothyteakettle: - - admin: migration error to version 39+ of savefiles is now logged instead of messaging - all online admins in the chat -2021-02-14: - DeltaFire15: - - admin: The antag panel now correctly shows the names of cultist / clockcult datum - subtypes. - - bugfix: Adding clock cultists via the admin panel now works correctly. - - bugfix: Xeno larvae should now be able to ventcrawl again. - Hatterhat: - - tweak: Repairing sensors on jumpsuits now requires a fully-intact jumpsuit. Find - some cloth. - - tweak: Durathread armor kits now require you to have a fully-repaired jumpsuit, - first, with no attachments. - - bugfix: Durathread armor kits now no longer weave the entirety of the jumpsuit - armor universe into having armor. - TyrianTyrell: - - code_imp: added a define for multilingual granted languages, and changed the multilingual - trait to use it. -2021-02-15: - Adelphon: - - rscadd: polychromatic shoes - - rscadd: polychromatic windbreaker - - rscadd: polychromatic canvas cloak - - bugfix: digitigrade charismatic suit texture - DeltaFire15: - - balance: Kneecapped pugilist parries somewhat. - - balance: Slightly nerfed default unarmed parries. - - balance: Slightly nerfed traitor armwrap parries. - - bugfix: Pugilist parries now cannot perfectly defend against projectiles, as they - were supposed to. - - bugfix: Some parrying numbers that one would think were in seconds didn't have - the SECONDS. I added those. - - balance: Clock cultists now yell alot less when invoking scripture. - dzahlus: - - rscadd: Added new emote - - soundadd: added a new emote sound - silicons: - - balance: people on the ground hit less hard in unarmed combat. rng miss remove - from punches. - - bugfix: chat highlighting no longer drops half your entered words. -2021-02-16: - silicons: - - config: sprint removal entry added, UI will revert to old UI while this is active. -2021-02-18: - BlueWildrose: - - admin: Admins now receive messages regarding certain holodeck actions. - Hatterhat: - - bugfix: Free Golem Ship GPSes now start as disabled. Like they were supposed to. - LetterN: - - tweak: No more liver damage when you opt out of "hornychems" - SmArtKar: - - rscadd: Added a new TCG card game - dzahlus: - - rscdel: Removed maroon objective due to toxic gameplay behaviour - shellspeed1: - - bugfix: floor bots place plating before tiles now. - - bugfix: gets rid of another tile duplication issue. - silicons: - - spellcheck: priviledge --> privilege -2021-02-19: - Putnam3145: - - bugfix: Buzz Fuzz's addiction threshold is now a can and a sip as intended. - timothyteakettle: - - admin: staring into pierced realities is now logged -2021-02-20: - Adelphon: - - rscadd: polychromic pants - - tweak: urban coat made polychromic - Chiirno: - - tweak: Synthflesh now unhusks with 100u instead of requiring 101u. - SmArtKar: - - tweak: Added some QoL changes to TCG - - bugfix: Fixed TCG cards not saving - TyrianTyrell: - - bugfix: fixed the signed language so that you can actually use it, and that it's - unusable when it's meant to be. - timothyteakettle: - - bugfix: stops people using Message All on PDAs when their cartridge doesn't allow - it -2021-02-21: - Hatterhat: - - balance: Anomaly announcements and brand intelligence now always announce instead - of having some ham-fisted chance of being a command report. - IronEleven: - - balance: Raises Space Vine Population Requirement from 10 to 20 - MrJWhit: - - tweak: Removes an unnecessary % on the seed extractor. - timothyteakettle: - - bugfix: the query for checking mentors now gets properly deleted - - rscadd: vampires no longer burn in the chapel if they signed up as the chaplain -2021-02-22: - Putnam3145: - - rscadd: (Hexa)crocin - - rscadd: (Hexa)camphor - - rscadd: Nymphomaniac quirk - - admin: All climaxes and arousals are now logged, as well as genital exposure. - SandPoot: - - rscadd: Cyborg tablets and it's special app for self-management. - - bugfix: In the case of a doomsday device being created outside of an AI it will - delete itself. - - imageadd: Some sprites for it have been added and the borg's hud light toggles - been changed to only on-off (made by yours truly) - - refactor: A lot of borg code was changed - - refactor: Tools no longer use istype checks and actually check for their behavior. - Vynzill: - - rscadd: cursed rice hat that's hard to find and obtain, along with a couple other - hats - - rscadd: a replacement toy gun for donksoft lmg - - rscadd: gorillas to the jungle gateway, friendly, even when attacked. - - bugfix: couple mapping errors I noticed, most importantly a missing window in - the chapel. - - balance: shotgun and donksoft lmg removed, captain coat nerfed armor values. - - balance: leaper healthpool from 450 to 550 hopefully making it more of a struggle, - and gives it a name. - - tweak: leaper pit is more wider. The hidden room south is now more obvious to - find - dzahlus: - - rscadd: Added pain emote to getting wounded - - soundadd: added a new pain emote sounds -2021-02-23: - keronshb: - - rscadd: Hyperblade to uplink with poplock - - balance: Removes combination of two Dragon Tooth Swords while keeping it for regular - eutactics. - timothyteakettle: - - bugfix: banning panel prioritises mobs with clients now when trying to find them - if they're in the game -2021-02-24: - SandPoot: - - bugfix: Regular crowbars no longer open powered airlocks. - silicons: - - balance: xeno cube makes hostile xenos now, and drops a sentinel instead of a - drone. -2021-02-25: - DeltaFire15: - - bugfix: Traitor / Ling objective amount should now be correct again. -2021-02-26: - DeltaFire15: - - code_imp: All machine-frame based tool-use actions now have state-checking callbacks. -2021-02-27: - Hatterhat: - - balance: Lingfists (trait_mauler) now deal no stam damage and lost their 15(!!!) - armor penetration. - Putnam3145: - - tweak: Tablets now protect their contents from rads. - TheObserver-sys: - - rscadd: Chems that should have been usable are now usable, try some cryoxadone - on a plant today!!! - kappa-sama: - - tweak: cards and card binders are now small-class items - keronshb: - - balance: 16 > 10 unlock cost for stronger abilities - - balance: Made nearly all other abilities for free. - kiwedespars: - - balance: reverted the pr that absolutely gutted pugilism and made it worse than - base unarmed, also gives it a second long stagger - - balance: removed the ability to parry while horizontal, because that's dumb and - makes it easy to just time the parries right. - silicons: - - bugfix: chaplain arrythmic knives can no longer be abused for infinite speed. -2021-02-28: - Putnam3145: - - bugfix: Polychromic windbreaker's alt-click message is now coherent - - code_imp: Toggleable suits now have an on_toggle proc to be overridden. - R3dtail: - - tweak: doubled max belly name length and quadrupled belly description length - SandPoot: - - tweak: Body rejuvenation surgery will loop until the patient is completely healed. - dzahlus: - - bugfix: fixes toxinlovers dying from heretic stuff that should heal them instead -2021-03-01: - SmArtKar: - - bugfix: Fixes decks breaking your screen - - bugfix: Fixes binders not saving cards - - bugfix: Fixes binders not saving multiple cards of the same type - Vynzill: - - bugfix: cursed rice hat right in front of the jungle gateway's entrance is now - removed from this dimensional plane -2021-03-02: - LetterN: - - bugfix: 'colorpainter: let''s not dispense null' - SandPoot: - - bugfix: Changelings will actually become the person they want to be when using - "human form" ability(after having used last resort). -2021-03-03: - MarinaGryphon: - - bugfix: The AOOC mute pref is now properly respected. - - bugfix: Muting adminhelp sounds no longer mutes AOOC. - Putnam3145: - - config: pAIs now have a policy config - - rscadd: '"Supermatter surge" event, which might cause problems if the supermatter - is not sufficiently cooled (i.e. the setup is messed up in some way)' - - rscdel: Fusion can no longer be done in open air. - - rscdel: Valentine's day event no longer gives everyone a valentine's antag. - SandPoot: - - bugfix: Legions should now pass their type to the person they infect (if valid). - dzahlus: - - rscadd: Added new subtype to lesser ash drake balanced around player control - - balance: rebalanced dragon transformation to a 1 minute cooldown as well as using - the new subtype of megafauna - qweq12yt: - - bugfix: fixed infectious zombies not being able to attack if host was pacifist - - rscadd: adds a way for species to have blacklisted quirks, the removal, and restoration - of said quirks upon species changes - - bugfix: Now pacifists won't be able to use flamethrowers - - bugfix: Kinetic Accelerator now properly reloads a charge to it's chamber instead - of nulling the variable forever - - bugfix: Now pacifists won't be able to use Kinetic Accelerators if a non-pacifist - shoots it first -2021-03-04: - LetterN: - - code_imp: removes bsql -2021-03-05: - Putnam3145: - - tweak: Lowered ash storm volume - - tweak: Minesweeper can no longer be made to lag the server on purpose - keronshb: - - tweak: Prevents heat from going through reinforced plasma glass. -2021-03-07: - Hatterhat: - - rscadd: You can now reskin your improvised shotguns. - - rscadd: The spontaneous brain trauma event now announces to ghosts whoever got - funnied upon. - - imageadd: Ports EikoBiko's cat tail sprite. - Putnam3145: - - bugfix: nitryl now consumes oxygen/nitrogen instead of generating them - - balance: Hyper-nob and nitryl are easier to make. - dzahlus: - - rscadd: Added taser microbattery for MWS-01 - - tweak: tweaked MWS-01 beacondrop to have more batteries - - balance: rebalanced MWS-01 disabler battery to fire 10 shots - - soundadd: added unique sound to the MWS-01 - - spellcheck: fixed Modula Weapons System to "Modular Weapon System" - timothyteakettle: - - balance: exiting a bluespace jar through any means, hardstuns you for 5 seconds -2021-03-09: - LetterN: - - refactor: tg hardsync, mostly contains tgui -2021-03-10: - Hatterhat: - - rscadd: The femur breaker now actually breaks legs by applying a compound fracture. - Putnam3145: - - balance: uncapped TEG power, buffing high-temp TEGs -2021-03-12: - R3dtail: - - spellcheck: Adds Periods and moves some words around. -2021-03-14: - Adelphon: - - rscadd: messy2 - - bugfix: papermask - Hatterhat: - - rscadd: Robotic limb repair surgery now has tiers. - - rscadd: 'Pubby and Delta now have roundstart limb-growers relatively close to, - if not in, the operating theaters. tweak: Box QM''s console now can announce - things.' - Putnam3145: - - bugfix: chaos loads now - kiwedespars: - - rscadd: adds a cute new plushie - necromanceranne: - - bugfix: Fixes cosmetic augments missing their foot sprites. -2021-03-16: - GrayRachnid: - - balance: removed red toolbox, agent id, and guerilla gloves from unlocking illegal - tech. - HeroWithYay: - - bugfix: fixed spelling error - LetterN: - - bugfix: Borg light icons not turning off - - bugfix: Double ai icon select + Fixes ai core not having icons - - bugfix: Missing air tank icon - - bugfix: Computer boards being dumb and nullspacing/qdeling itself - Putnam3145: - - balance: Supernova now much lower chance to be inconsequential - - balance: Made hyper-nob's point values way lower (25/20 for science/cargo instead - of 1000/1000) - - balance: Made nitryl's cargo sell value less (10 instead of 30) - SandPoot: - - bugfix: Fixed interacting with telecomms. -2021-03-17: - KeRSedChaplain: - - rscadd: Added three new rites, and makes soul vessels obtainable - - bugfix: fixes clockwork guardians inheriting marauders blocking - - soundadd: added sounds for the ratvar end sequence, voiced by @dzahlus - timothyteakettle: - - rscadd: speech panel added to main menu customization -2021-03-18: - Arturlang: - - bugfix: Combat mode right click and right click verb give's are now actualyl targeted - Hatterhat: - - rscadd: Hypospray vials are now printable from the medical techshift start. - - rscadd: 'Empty hypospray kits are now printable behind biological technology. - tweak: Quantum electromag (T4 lasers) are now behind Advanced Bluespace like - the rest of T4.' -2021-03-19: - DeltaFire15: - - rscdel: 'Bluespace jars can no longer be printed / acquired from lathes / techwebs. - tweak: The travelling animal trader now gives you your reward in a one-use bluespace - jar.' - Putnam3145: - - rscadd: '"Antag" role that can be toggled to disable all antags' - SandPoot: - - rscadd: Tactitool Skirtleneck. - - rscadd: Adds the tactitool skirtleneck to the loadout. - kiwedespars: - - rscadd: 'New heretic path - Path of Void- it specializes in being extremely stealthy. - tweak : Removed curse of blindness replaced with mask of madness. hey it even - rhymes.' - - bugfix: fixes heretic mass deletion during transmutation bug. - - bugfix: Fixes heretic brews being permanent. - - bugfix: 'Fixes void storm breaking after resurrecting. tweak: Heretic has received - a minor textual facelift. tweak: Heretics who finish the Void Path and become - an Aristocrat of the Void can now survive in the Void (space).' - - bugfix: Heretics who research Aristocrats Way on the Void Path will no longer - suffocate in their own storm when they ascend (no longer breathes). - - bugfix: Mark of Void and Seeking Blade are once again exclusive only to Void. - - balance: 'Carving knife now deals more damage on throw and can embed in your enemies. - tweak: Grasp of Rust only rusts floors and machines on harm intent. tweak: when - u choose a sac target as heretic it ll also tell the job of the sac' - - rscadd: 2 new void spells, one a placeholder. - - rscadd: flesh mansus grasp buffed, now gives you 5u eldritch fluid when hitting - someone. - zeroisthebiggay: - - bugfix: fixes spriteless heretic book -2021-03-20: - Hatterhat: - - bugfix: Bluespace beaker filling icons for that narrow band between 90 and 80% - full now actually exist. -2021-03-21: - Arturlang: - - bugfix: Vampire statpanel no longer shows spans unnecesary - GrayRachnid: - - bugfix: fixed the holopad autocall bug - - bugfix: properly incorporated the secure holopad that was commented out in the - code. - - config: the in_character_filter.txt is now usable - - admin: headmins should edit the in_character_filter.txt - - server: someone with box access should delete racism with the in_character_filter.txt - - balance: buffed particle defender disabler shots from 13->15 stamina (15*6=90) - - balance: buffed particle defender laser ammo to 4 shots - Hatterhat: - - rscdel: removes pacifism from ghost cafe. have fun beating up your coworkers - LetterN: - - rscadd: Art gallery (meta) - - rscadd: Laptop vendor (meta, delta, box) - Putnam3145: - - balance: Buffed supermatter surge massively. - The-Sun-In-Splendour: - - bugfix: You cannot revive yourself (as a changeling) if you've been absorbed anymore - dzahlus: - - balance: rebalanced hierophant STAFF to do 15 damage on all attacks - timothyteakettle: - - bugfix: using the puddle ability when stunned wont break it -2021-03-23: - LetterN: - - bugfix: NIRM departamental purchases now work. Have fun spending the entire R&D - Budget! -2021-03-24: - BlueWildrose: - - bugfix: The nightmare's light eater can now destroy messes that emit light, like - glowing goo or ectoplasmic puddles. - Hatterhat: - - bugfix: The NOGUNS trait now takes precedence over the triggerguard checks. - - balance: Medicated sutures and advanced regenerative mesh are now easier to make. - Reagent-quantity wise, anyway. - ItzGabby: - - rscadd: Fluff Items with polychromic support - - rscadd: A new vendor called Bark box - - rscadd: A new form of snack with it's own box - - rscadd: Two harness, one of them being lewd - - rscadd: One new collar, with a ribbon. Classy. - - rscadd: More locked forms of collars - - rscdel: Purged old balls - - balance: Removed the funny buffs each colored tennis ball had, down with the powergame! - - imageadd: Added polychromic fluff icons, vendor icons, suit icons, snack icons, - fancy box icons, and a polychromic version of Izzy's ball. - - imagedel: Deleted old balls, Izzy's Ball, except the rainbow one since it's special - and as I did not go out of my way to get permission to touch. - - spellcheck: Walked into vending.dm and glared for a moment at hydroponics' grammar. - LetterN: - - bugfix: fixed laptops pickability - - bugfix: fixed closets being unweldable - YakumoChen: - - balance: Genetics - Thermal vision is a recipe instead of a natural gene now. - Nearsighted+Stimmed. Other minor nerfs, Thermal is 40 instability. - - balance: Research - X-ray eyes are now an illegal tech. - qweq12yt: - - rscadd: added the black market uplink - - imageadd: added blackmarket.dmi - - bugfix: increased the black market interface's width, now the delivery options - will show properly when the LTSRBT is built - zeroisthebiggay: - - rscadd: biodegrade works on legcuffs -2021-03-25: - zeroisthebiggay: - - balance: strained muscles isn't free -2021-03-26: - BlueWildrose: - - balance: Clothing no longer drops when shredded. It just becomes useless. - - balance: Suit sensors are guaranteed to short out when the clothes become shredded, - not damaged now. - - balance: Uniform limb integrity increased from 30 to 120. - - balance: 'Suit sensor damage has been added. The more damaged your suit sensors - get, the less features that will be available from these suit sensors. It takes - two e-sword hits to ruin your tracking beacon for instance. tweak: Examine text - on uniforms is now more clear about needing cable coil to repair your suit sensors.' - - bugfix: Fixed prisoner uniform sprite paths - CuteMoff: - - balance: Diamond's forcemod was changed from 1.1x to 1.2x - Hatterhat: - - rscadd: Lever-action rifles, chambered in .38, are now sitting in the code. They - might be buyable from Cargo or the Black Market soon. Watch this space. - - rscadd: Sawed-off shotguns now look like shotguns, but short, when inhand, instead - of "generic gun". - timothyteakettle: - - bugfix: slimes can be delimbed - - bugfix: the loadout now colours pet collars correctly -2021-03-28: - CuteMoff: - - balance: Changed Strength Modifier from the default (1.0) too .7 - Hatterhat: - - bugfix: As a heretic, shattering your blade no longer interferes with bluespace. - Putnam3145: - - rscadd: Threat tracking is now universal, rather than dynamic-only - - rscadd: Slaughter demon event now increases weight based on how much blood there - is. - R3dtail: - - rscdel: Removed ichor creates - - balance: Removed ichor crates and adjusted crate rolling appropriately - - balance: Removed the bonespear from the blackmarket uplink, and made EMP grenades - harder to get from the same item. - - rscadd: Added a description to the black market uplink - Shadow-Quill: - - imageadd: Added small versions of the walk icon for all hud styles, except Retro. - dzahlus: - - rscadd: Added radial menu to joy mask for alt reskins - - imageadd: added pensive, angry and flushed sprites to joy mask - keronshb: - - balance: Radioactive microlasers can no longer knock out creatures who are immune - to the effects of radiation. - - bugfix: The radioactive microlaser now calculates the strength of its delay effect - using the intensity setting it had when you initially used it on your victim, - not the intensity setting it currently has. This prevents people from "cheating - out" its intensity 20 effect with only a 2 second delay and a 1 second cooldown. - - balance: Radioactive microlasers no longer contain twice as much metal as normal - health analyzers do. - necromanceranne: - - rscadd: Replaces the useless bullet and laser shields with new Kinetic and Ablative - shields, which do as they advertise. - - rscadd: Replaces the shield implants shield with a hardlight shield that can take - large amounts of brute damage, but disintegrates when shot with disablers. - - bugfix: Fixes Fake Roman Shields being able to be used as normal riot shields. - - bugfix: Fixes nonlethal/non-physical damage types destroying shields. (stamina, - toxins, oxygen, clone, brain) - - bugfix: Fixes tower shields not doing anything, while also giving them intergrity - to match their advertised durability. - - bugfix: Uses additional flags to determine what kind effects work well and what - works poorly against various shields. - timothyteakettle: - - rscadd: ghost cafe residents can now disguise themselves as any mob or object - - bugfix: fixes character preview not updating when selecting the loadout tab - zeroisthebiggay: - - rscadd: triple kitsune tail -2021-03-29: - BlueWildrose: - - bugfix: Fixed being unable to fix suit sensors if damaged at all unless destroyed - completely - YakumoChen: - - rscadd: A less-than-new Syndicate bundle that reminds you of the good old days - when we didn't need all those newfangled traitor items the young-uns get. We - had 6 items in the uplink and we had Monkey in rotation and by god we made do. - qweq12yt: - - rscadd: Added Earmuffs - - rscadd: Added Random Drink - - rscadd: Added Clear PDA - - rscadd: Added Internals Box - - rscadd: Added Meson Goggles - - rscadd: Added Smoke Grenade - silicons: - - bugfix: automated hydroponics system design now works properly -2021-04-02: - LetterN: - - bugfix: piratepayment -2021-04-03: - BlueWildrose: - - bugfix: The hydroponics pet bee, Bumbles no longer has a number besides their - name. - Putnam3145: - - rscdel: '"Destroy all nanotrasen cloning machines" objective is gone' - - code_imp: Removed all the commented-out sabotage objectives (we can just get them - from history) - - rscadd: Observe verb logging -2021-04-04: - Hatterhat: - - balance: After a sudden crash in the tower-cap log slash wooden plank economy, - NanoTrasen has decided to stop selling tower-cap logs to Cargo. -2021-04-06: - ArcaneMusic: - - bugfix: Prevents people from lagging the server by growing HUMANS FROM CABBAGE! - BlueWildrose: - - admin: Admins get to hear the prayer ding again unless they have prayer sounds - turned off. - DeltaFire15: - - bugfix: The wood plank cargo pack no longer is named incorrectly. - Putnam3145: - - bugfix: forced climax doesn't do a climax-with - SandPoot: - - bugfix: Reverts locker/crate behavior for attacking it with an item while closed - (use any intent other than help to bash it). - - bugfix: 'Laptop interactions are no longer weird and now you can drag it to yourself - to pick it up. tweak: Ctrl+Shift-Click to toggle laptops open/closed. tweak: - More examine info for laptops.' - - bugfix: Lockers/Crates can now be deconstructed the right way respecting the cutting_tool - (even if it's not one of the default interactions). - - rscdel: Dragging the laptop into itself shouldn't do anything anymore (kind of - pointless and hard to do). -2021-04-07: - LetterN: - - rscadd: Perln generation & biomes from lavaland - - code_imp: Cleans up the area, update it's icon and updates the openspace to use - the modules. -2021-04-09: - BlueWildrose: - - balance: The genetics mutation Autotomy has been buffed to be 20 instability instead - of 30, and harmless in delimbing. - - rscadd: 'There are now three more pills in each breast or penis enlargement pill - bottle. tweak: There are now 10 pill bottles of breast and penis enlargement - pill bottles in a Kinkmate instead of 5.' - - balance: Because of such changes that increases their amount in the kinkmate, - succubus milk and incubus draft values are reduced to RARE from VERY_RARE. - - spellcheck: Grammar correction on titty pill bottle. - - rscadd: The pandemic machine can now let you swap containers. - - bugfix: Slime puddles will now show mutation visual indicators & cult indicators - after exiting slime puddle form - - bugfix: Slime puddle transformation animations are now resized to fit the slimeperson's - current size, making it visually more consistent - - spellcheck: Typo correction in some mutation descriptions and other things - - code_imp: Cult/clockcult layers moved from LAYER_MUTATION to LAYER_ANTAG, new - update section for them specifically now - - rscadd: Sylvan and Mushroom languages are now tongueless, and Encoded Audio Language - is now learnable. - SandPoot: - - bugfix: The dragons_blood "lizard with the appearance of a drake" no longer wipes - important stuff. - - bugfix: Fixes Ashlizard legs not being digitigrade and makes them have the "Sharp" - snout. - - bugfix: Machines that open no longer drop their stock parts. - brokenOculus: - - rscadd: Added Telescopic Baseball Bat - - rscadd: Added Telescopic Baseball Bat to Stealthy uplink items - - rscadd: Added sprites for Telescopic Baseball Bat - - rscadd: Added Telescopic Baseball Bat to Baseball kit under uplink bundles -2021-04-12: - BlueWildrose: - - bugfix: Fixed female slime-subspecies left/right sprites being flipped - - bugfix: Fixed drones nullspacing things they try to place on tables and in closets - - bugfix: Fixed phantom mob-holder items. You can now grab Ian from your backpack - without any issues. - silicons: - - balance: gold cores can spawn simplemob xenos again. - timothyteakettle: - - config: makes AGE_VERIFICATION option off by default -2021-04-13: - rossark: - - bugfix: wrong word -2021-04-14: - Hatterhat: - - balance: Space pirates are now slightly more aware of how much money the station - has, and will demand payment accordingly. (No more 20k minimum payouts and basically-confirmed - three midround skeletons.) -2021-04-15: - BlueWildrose: - - bugfix: Fixed escape pods not docking at Centcom - skodai: - - imageadd: Resprited the icons for the sushi, onigiri, tuna can and sea weed. -2021-04-16: - BlueWildrose: - - bugfix: (TGport-Timberpoes) You can once again pay off the pirate event from the - communications console without it silently failing for no obvious reason. - - bugfix: Fixed being unable to delete messages from the communication consoles - message list save for the one on the bottom. - - bugfix: The data siphon that the space pirates have will no longer go invisible - when it begins siphoning. - - bugfix: If the space pirate's "offer" has been rejected, there is now announcement - feedback for if this does happen. - DeltaFire15: - - bugfix: Borgs can now use tank dispensers (again?) -2021-04-18: - BlueWildrose: - - balance: '(TGport-Kriskog) Reduced blight cost to 75, more in line with its underwhelming - nature. tweak: (TGport-Kriskog) Revenants now only use stolen essence to unlock - new spells. No more counting corpses or waiting for regen before draining. tweak: - (TGport-Kriskog) Spell unlock costs adjusted accordingly, defile upped from - 0 to a cost of 10. tweak: (TGport-Kriskog) Drain targets in soft-crit will be - stunned, to prevent them crawling away.' - - bugfix: (TGport-ShizCalev) Fixed revenant's light overload ability not blowing - lights in a square if there was another broken/burnt out/empty light in it. - DeltaFire15: - - bugfix: Mechs now do not get drained an absurd amount of energy when EMPd. - - bugfix: Organic healing surgeries no longer show up for people without any organic - bodyparts. - SandPoot: - - rscadd: Adds a fancy TGUI interface for the cloning computer. - - rscdel: 'Destroys the old cloning interface. tweak: Alt-Click now removes disks - from the cloning computer.' - - refactor: Replaced way too much code for the cloning computer. - - refactor: Cloning scan's implant now outputs a list if desired. -2021-04-20: - BlueWildrose: - - rscadd: New slimeperson organs that aren't really that different from humans for - now. - - imageadd: Some blue organs for slimepeople. - - rscadd: Space pirate sleepers can now be crowbared to be destroyed. - DrPainis: - - rscadd: ash drake meat - Hatterhat: - - bugfix: Plastitanium glass now properly applies the *2 bonus for integrity and - efficiency when used as a solar panel. - HeroWithYay: - - imageadd: replaced some icons - Putnam3145: - - rscadd: Bluespace pipes, which can teleport gas over long distances - - rscadd: Donk co traitor class (assassin-heavy) - - rscadd: Waffle co traitor class (freeform) - - rscadd: 'Admin-only activity tracking system only attached to antags for now tweak: - Objective rerolling can now be done twice' - - bugfix: Sabotage objectives won't give "free objective" anymore - The0bserver, TripleZeta, and AsciiSquid: - - rscadd: New, easily concealable weapons, chambered in .38, .357, and .45-70 Govt. - Fun for the whole family! - - rscadd: Some smugglers seem to have acquired a high amount of .38 derringers, - and are looking to offload them to those of gray morality, with no questions - asked! - - rscadd: An enigmatic gun collector has seen fit to do special acquisition work - for the Gorlex Marauders, selling the fruits of his labor for a premium price. - If you have the right electomagnetic sequence, you might be able to contact - him to acquire a piece of his armory. - coiax: - - rscadd: Nuke ops can now purchase a box of "deathrattle implants". When an implanted - person dies, all the other users of the implant will get a message, saying who - died and where they died. - keronshb: - - balance: Weight per blood is .03 now instead of .05 - - balance: Dragnet Snare breakout timer is now 2.5 seconds down from 5 seconds. - qweq12yt: - - bugfix: Fixed a bug where some cargo crates would never arrive and still charge - users - zeroisthebiggay: - - rscdel: the box ghost burger -2021-04-21: - necromanceranne: - - balance: Stun batons (not police batons/telebatons) no longer knockdown on leftclick. - - balance: Stun batons apply a knockdown and tase effect on right click, but once - every few seconds (they still don't disarm). They are vulnerable to a shove - disarm briefly, however. Standard batons have a cooldown of 5 seconds. Stun - prods have a cooldown of 7 seconds. - - balance: Taser resistance prevents the knockdown, so any chem that grants this - (like adrenals) protects you from this knockdown. - - balance: Stun batons apply a stagger when they hit someone, preventing sprinting - for a few seconds. - - balance: Stun batons respect melee armor for their stamina damage, but their cells, - based on max charge, grant armor penetration. For every 1000 charge, they gain - 1 armor pen. (Roundstart batons have 15 pen, just fyi) - - balance: Shoves can disarm you of any item, not just guns. - - bugfix: Removes a duplicate trait definition for TRAIT_NICE_SHOT. -2021-04-22: - Whoneedspacee: - - rscadd: new arena attack where ash drake summons lava around you - - rscdel: removed old swooping above you, instead flies above you instantly - - balance: ash drake now spawns temporary lava pools instead of meteors falling - down - - balance: ash drake takes twice as long to swoop down now that he instantly goes - above you - - balance: ash drake now moves twice as fast - - balance: increases the odds of lava spawns in the lava pool attack - - balance: 'increases fire line damage and decreases lava attacks direct damage - tweak: ash drake fire now shoots in the direction of the target tweak: changes - times of certain animations tweak: changes sounds of meteor falling to lava - creation' - - bugfix: a bug where ash drakes attacks did not damage mechs - - imageadd: changes meteor icon to lava creation animation from lava staff - - rscadd: Mass fire attack, sends fire out from the ash drake in all directions - - rscadd: Adds an enraged attack for ash drake, heals him as well as making him - glow and go faster, spawning massive amounts of fire in all directions - - rscdel: 'Removes the old triple swoop with lava pools attack tweak: Lava pools - can now spawn with the normal fire breath attack sometimes tweak: Lava pools - now have changed delays for lesser amounts so they don''t all just place around - one area tweak: Increases default swoop delay' - - balance: Teleporting out of the lava arena now has some actual consequences by - enraging the ash drake - - bugfix: Makes lava arena a bit less laggy by not recalculating range_turfs every - time - - bugfix: Fixes the arena attack selecting inaccessible tiles as the safe tile though - this will not change the turfs to basalt temporarily to prevent moving through - indestructible walls - - bugfix: Fire lines would not spawn if their range would place their final turf - location outside of the map - - bugfix: The arena attack will no longer destroy indestructible open turfs - - balance: ash drake fire does less damage now - - balance: ash drake takes longer to swoop down now - - balance: tiles take longer to fully convert into lava now, slowing down the arena - attack as well - - balance: fire breath now moves slower - - balance: triple fire breath for the lava swoop only happens below half health - now - - bugfix: The arena attack not making safespots when you fight it in a mech -2021-04-25: - DrPainis: - - spellcheck: Bubblegum is now capitalized. -2021-04-26: - Trigg, stylemistake and SandPoot: - - admin: 'Admins just got a new TGUI Select Equipment menu tweak: Prevents the window - from creating sprites for any animated version there might be. (this guarantees - consistant sprite size/amount)' -2021-04-29: - Putnam3145: - - bugfix: Fixed a couple runtimes in activity (threat) tracking - keronshb: - - balance: Removes the Reinforcement Chromosome from Genetics. -2021-04-30: - DrPainis: - - spellcheck: Bubblegum's hallucinations are capitalized. - Melbert, SandPoot: - - refactor: TGUI Limbgrower - - refactor: Refactored the limbgrower to modernize the code and allow for more types - of designs. - - rscadd: The limbgrower now supports plumbing ducts. - - bugfix: Fixes genitals not actually getting data from disks. - - code_imp: Adds two special helpers. - SandPoot: - - rscadd: The decal painter now has visible previews for your tile painting funs. - - bugfix: Fixes decal painter painting in the opposite direction. - TheObserver-sys: - - bugfix: Restores the access lock on crates that should have them, given the goods - inside. - - bugfix: Makes the 10MM Surplus Rifle a less awful thing to use. - - bugfix: replaces unarmored things with their armored versions. - - balance: Illegal Tech Ammo actually is fucking reasonable, now. - - balance: Expensive Illegal Tech Ammo Boxes are now constructible, with actually - justifiable prices. - WanderingFox95: - - balance: There's finally a reason for the reagent dart gun to exist and be used! - akada: - - imageadd: Changes the space adaptation sprite to something less intrusive and - more subtle. - necromanceranne: - - rscadd: 'Basic cybernetic organs: they''re worse than organic! Basic stomachs, - hearts, lungs and livers! For when you hate someone enough to not bother harvesting - organs from a monkeyhuman!' - - rscadd: 'Cybernetic organs have been adjusted into three tiers: 1 (basic), 2 (standard, - better than organic) and 3 (absolutely better than organic but expensive to - print)' - - rscadd: Cybernetic organs that are emp'd instead suffer different effects based - on the severity of the emp. The bigger the emp, the worse the effect is. - - rscadd: Rather than outright bricking, severely emp'd cyberorgans degrade over - time very quickly, requiring replacement in the near future. - - rscadd: Fake blindfolds in the loadout. They don't obscure vision, for better - or worse. -2021-05-01: - qweq12yt: - - bugfix: Restores the sprite for the Riot Suit. -2021-05-03: - TripleShades: - - rscadd: Added two air alarms to Pubby Security, one in the evidence locker room - and one in the main equipment back room - - rscadd: pAI Card back to outside Research in Meta Station - - bugfix: Pubby Disposals now shunts to space - - bugfix: Maintinence Areas being not applied to certain airlocks as well as stealing - minor walls - - bugfix: Box Surgery Storage camera is now renamed to be on the network - - bugfix: 'Box Paramedic Station camera is now renamed to be on the network, and - no longer steals the Morgue''s cam tweak: Box Surgery Storage is now it''s own - proper room' -2021-05-05: - The0bserver, with a great amount of advice from TripleZeta/TetraZeta: - - rscadd: Adds a new crate type, for use with any manner of cheeky breeki shenanigans, - as well as with existing Russian contraband. - bunny232: - - rscadd: There's some new vents and scrubbers in the meta station xenobiology department. - Welders and wrenches not included* - keronshb: - - balance: Nightmare Shadow Jaunt threshold up to 0.4 - - balance: Vendor and Engraved message light down to 0.3 -2021-05-08: - Arturlang: - - bugfix: Synthblood bottles now have the proper color and probably won't poison - you anymore - timothyteakettle: - - rscadd: lets humans have digi legs (and avian legs) -2021-05-09: - Putnam3145: - - rscadd: Priority announcement admeme verb - SandPoot: - - bugfix: Fixed Cyborg examines adding an extra weird line. - - code_imp: Everything can be set to have tooltips, and even coded to have neat - tooltips. - - rscadd: Makes it so humans and borgs already have tooltips. - TheObserver-sys: - - bugfix: Fixes most of the weird handling bugs and improves cigarette case handling - in general. - - rscadd: The Gorlex Marauders have seen fit to allow you to purchase the .45-70 - GOVT rare ammo, at a premium cost. Don't waste it. - WanderingFox95: - - rscadd: added the unrolling pin, an innovative solution to dough-based mishaps. - - imageadd: added visuals for the unrolling pin - dzahlus: - - soundadd: added new malf AI spawn and doomsday sound - - sounddel: removed old malf AI spawn and doomsday sound - zeroisthebiggay: - - balance: pirates now have a medbay and several other things qualifying as a buff - - balance: pirates lost their toilet -2021-05-11: - LetterN: - - bugfix: fixes emagging console shuttle purchases - - balance: syndie melee simplemobs has no more bullshit shield - bunny232: - - rscadd: Delta station xenobiology department has received enhanced scrubbing and - ventilation capabilities similar to box and meta -2021-05-12: - DeltaFire15: - - bugfix: find_safe_turf no longer always fails on safe oxygen levels(??) - - bugfix: 'Heretic bladeshatters now actually take the heretic''s z into account - as intended, instead of always being station z tweak: Message for failing the - bladeshatter despite succeeding the do_after tweak: Improves bladeshatter a - bit by making it safer codewise' -2021-05-13: - Linzolle: - - spellcheck: anthromorphic -> anthropomorphic - WanderingFox95: - - rscadd: Pinot Mort (Necropolis Wine), a new, (totally healthy) mixed drink! - qweq12yt: - - bugfix: Fixed sleeping disky spam (it still sleeps soundly, but every minute instead - of every two seconds) - - bugfix: Fixed Hulks not breaking cuffs, zipties, restraints. - silicons: - - code_imp: A deterministic wave explosion system has been added. Use it with wave_explosion(). - zeroisthebiggay: - - rscadd: vegas style bunny ears -2021-05-14: - keronshb: - - balance: Removes VOG sleep command since it was an undocumented readd. - zeroisthebiggay: - - spellcheck: consealed -2021-05-15: - bunny232: - - bugfix: Corrects the bot pathing by engineering on meta station - timothyteakettle: - - balance: borg spraycans have a five second delay before being able to knock someone - down again -2021-05-19: - WanderingFox95: - - rscadd: The E-Fink, a mending tool for food. - - soundadd: A backwards bladeslice. (Yes, for the E-fink) - - imageadd: And Icons for the E-fink, of course. - shellspeed1: - - rscadd: Survival pods can now be designated as requiring power. Survival pods - with this feature should include an APC when created and will run out of power - rather quickly if no source is added. Perfect for true emergencies. - - rscadd: An empty survival pod has been added to the mining vendor. This is an - extremely barebones pod featuring only a gps, table, apc, and the standard fridge - for some donk pockets. - zeroisthebiggay: - - rscadd: New Alcohol Amaretto and various cocktails - - rscadd: more drink mixture flavortext - - soundadd: you're going to Baystation -2021-05-20: - qweq12yt: - - bugfix: Fixed void cloak voiding itself into oblivion. - - bugfix: You can now order emag shuttles again. - timothyteakettle: - - rscadd: ports rp's marking system -2021-05-21: - Putnam3145: - - bugfix: Fixed activity being attached to minds instead of mobs on antag attach. -2021-05-23: - Putnam3145: - - bugfix: Antag and species no longer remove all traits if one has a blacklisted - trait - WanderingFox95: - - imageadd: Replaced the antlers showing up when you select deer ears with actual - deer ears. Literally why was that even a thing before? - - imageadd: Straight rabbit ears are now a thing. - keronshb: - - balance: 30 > 25 pop req for contractor kit - - code_imp: adds a special hud for simple mobs. - - imageadd: a lot of >32x32 mobs now have icons for their health dolls -2021-05-24: - zeroisthebiggay: - - rscadd: 'New traitor item: the Mauler Gauntlets! Punch hard, punch good! Eight - telecrystals, buy today!' - - rscadd: hairs from Airborne Snitch -2021-05-26: - bunny232: - - bugfix: Removed two random 'captain's office' tiles from space on meta station -2021-05-29: - Kraseo: - - bugfix: No more slamming into people while bloodcrawled. - Linzolle: - - bugfix: brand intelligence event works again - keronshb: - - rscadd: swag outfit available in clothesmate - - rscadd: 'swag shoes availble in clothesmate resprite: changed swag shoes icon - to the one twaticus made.' - - rscadd: Adds the clown mob spawner for admins - zeroisthebiggay: - - balance: puglism damage can no longer stack with scarp -2021-06-03: - MrJWhit: - - balance: Removed some debug tiles on the xenoruin. - TripleShades: - - rscadd: Added a camera to both solar entryways - - rscadd: Added an intercom to toxin's launch for the doppler - - rscdel: The fake nuke auth disk in the library -2021-06-04: - MrJWhit: - - rscadd: Adds a missing pipe - Putnam3145: - - bugfix: sniper rifle doesn't ruin your round instantly now -2021-06-05: - Arturlang: - - code_imp: float sanity now makes it not actually run if it's actively being thrown - coderbus13: - - bugfix: Pubby's toxins injector now starts at 200L, like it does on other maps - zeroisthebiggay: - - rscadd: light floppy dog ears -2021-06-06: - bunny232: - - rscadd: Pools are capable of mist at lower temperatures -2021-06-10: - Arturlang: - - balance: Holoparasites for traitors now cost 12 crystals, for operatives 8, the - ricochet eyepath traitor item now 4. - DrPainis: - - rscadd: goliath calamari - - rscadd: cat meteors - Linzolle: - - bugfix: cults can build in maintenance (and other small areas) again. - - bugfix: centcom can no longer be selected as the target area for narsie to be - summoned?????? - MrJWhit: - - balance: Moves medical holodeck to the restricted category - SandPoot: - - code_imp: Uses some of the existing images for the typing indicators. - - bugfix: Fixes soulstone shard not working for non-cultists. - WanderingFox95: - - rscadd: A random event for the cat surgeon to invade the station. Listen for scary - noises! - - soundadd: Screaming Cat SFX, you know, for the mood. - bunny232: - - bugfix: Atmos resin now properly prevents all atmos from moving - - bugfix: Air tanks now properly have a 21/79 o2/n2 mix - - rscadd: Hydroponics can now make 5u of slimejelly by injecting 3 oil, 2 radium - and 1 tinea luxor into a glowshroom - keronshb: - - balance: Made it so Off Balance only disarms if they're shoved into a wall or - person. - - balance: Reduced Off Balance time to 2 seconds. - - balance: Pierced Realities despawn after 3 minutes and 15 seconds, new unresearched - realities spawn in after that time elsewhere to help other heretics get back - into the game. - - balance: A required sacrifice amount for heretic's second to last and last powers - are added to discourage only rushing for holes. - - balance: An announcement automatically plays to everyone that there's a heretic - gunning for ascension upon learning the 2nd to last power - - balance: 'Blade Shatters are now used in hand other than with a HUD icon tweak: - Adjusted some TGUI menus for the book to reflect how many sacrifices a heretic - has and how many are required for certain powers' - - bugfix: Fixes sprite issue for Void Cloak for people who have digigrade legs. - - bugfix: Fixes the Raw Prophet recipe to match the description - - balance: Lets the Cargo Shuttle use Disposal Pipes again - - rscadd: Adds motivation and adds it to the uplink - - rscadd: Adds Judgement Cut projectiles - - rscadd: Adds Judgement Cut hit effects and firing effects. - - soundadd: added sounds for the firing and hit sounds of Judgement Cuts, created - by @dzahlus - - rscadd: Adds Floor Cluwnes and event for midround - - rscadd: Adds Cluwne mutation - - rscadd: Adds Cluwne spell - - rscadd: Adds Cluwnes - - imageadd: Adds Cluwne Mask + shoes - - admin: Adds Floor Cluwne spawn button - - admin: Adds Cluwne smite button - zeroisthebiggay: - - bugfix: Fixed an exploit allowing you to grab people from anywhere with a clowncar. - - balance: revenant essence objective reduced -2021-06-12: - silicons: - - bugfix: xenos are now truly immune to stamina damage. -2021-06-14: - EmeraldSundisk: - - rscadd: 'Adds a brand new, wholly unique mining base to Snaxi tweak: A thorough - redesign of Snaxi (see PR #14818 for more info)' - - bugfix: Increases the number of electrical connections between substations - MrJWhit: - - balance: Removes cat meteors. - SandPoot: - - rscadd: Tablet computers now have a pen slot, they can almost replace your pda! - - spellcheck: Removed a bracket from printer's examine. - - bugfix: The cosmetic turtleneck and skirtleneck no longer start with broken sensors. - TripleShades: - - rscadd: Lights to AI Sat Walkways - - rscadd: Lights to Atmospherics - - rscadd: Floor labels to Atmospherics Gas Miner containment units - - rscdel: Gas canisters from Gas Miner containment units - - rscdel: Excessive wiring in Security and Detective's Office - qweq12yt: - - bugfix: Locker orders now properly bundle together in a single locker (still separated - by buyer). - - bugfix: Changed some package names to be more accurate. - timothyteakettle: - - rscadd: bees can go in containers and are released upon opening the container - - rscadd: 7 more round tips have been added - zeroisthebiggay: - - imageadd: new singularity hammer sprite - - imageadd: various slight sprite additions - - imageadd: distinctive combat defib sprite - - imageadd: a onesleeved croptop accessory sprited by trojan coyote - - imageadd: new bank machine sprite - - imagedel: unused goon coffin sprite - - imageadd: new water cooler sprite -2021-06-15: - EmeraldSundisk: - - rscadd: Xenobiology now has proper lighting - - bugfix: The Corporate Showroom now has a proper front door - - bugfix: Mining snowmobiles now have keys - - bugfix: Adjusts area designations so GENTURF icons should no longer be visible - in-game -2021-06-16: - silicons: - - bugfix: on_found works again -2021-06-17: - Vynzill: - - rscadd: ability to change crafted armwrap sprite to alternate one. - - imageadd: extended armwrap icon and sprite - timothyteakettle: - - bugfix: fixes an oversight causing embed jostling to do 2x as much damage as it - should -2021-06-19: - keronshb: - - bugfix: Ling Bone Gauntlets work again -2021-06-20: - Arturlang: - - rscadd: Port's TG's nanite storage modification programs from the bepis - - bugfix: Fixes infective nanite progreams not syncing cloud ID. - - rscadd: Add's off icons for nanite machinery - - bugfix: Fixes antitox nanites runtiming on simplemobs - - rscadd: Updates the nanite dermal button icon set - - rscadd: Adds the ability to select the logic for nanite rules - - bugfix: Nanite programs with triggers won't ignore rules. - - bugfix: 'Coagluating nanite program research no longer has the wrong name tweak: - Nanite program''s have better descriptions now tweak: Nanite subdermal ID''s - now also include pulled ID''s for simplemobs' - - bugfix: Nanite voice sensors should properly work now. - - bugfix: Fixes nanite comm remote, now they should actually work - EmeraldSundisk: - - rscadd: 'Adds ColorMates to Snow Taxi tweak: Slight adjustments near the arrival - shuttle landing zone' - - rscdel: Removes an undesired corporate entity - Nanotrasen Structual Engineering Division: - - rscadd: Added lables to the atmos tanks on Metastation. - - rscadd: Adjusted Pubbystation's emitter room wall layout to prevent light-breakage - on startup of emitters. - - rscdel: Removed frestanding sink and showers from Metastation science airlock, - and Deltastation Xenobio. Added an emergency shower next to the kill room. - - bugfix: Removed a leftover pipe in Metastation security hallway. - bunny232: - - bugfix: Pressure tanks other then air tanks start with gas! - keronshb: - - rscadd: Adds the Space Dragon midround event - - soundadd: Space Dragon sounds - - imageadd: Space Dragon + effects - - code_imp: Added Spacewalk trait - - code_imp: Gibs the original owner if they are turned into a Space Dragon with - the traitor panel - - admin: logging for Space Dragon creation - kiwedespars: - - rscadd: a downside to wheely heelies ((made it actually detrimental)) - zeroisthebiggay: - - imageadd: beltslot sprites for various items - - imageadd: resprite for telebaton -2021-06-21: - silicons: - - bugfix: glowshroom scaling - timothyteakettle: - - bugfix: vore is 0.1% less shitcode -2021-06-22: - bunny232: - - bugfix: Adds a missing win door to meta xenobiology pen 6 - silicons: - - bugfix: no more doubleroasting -2021-06-23: - DeltaFire15: - - bugfix: A bunch of small nanite things should be less wonky - - bugfix: Slimes are no longer immune to vomiting (undocumented change from a previous - PR) - - bugfix: Fruit wine exists again. - - code_imp: Airlock hacking no longer sleeps. - - code_imp: The clockwork gateway deconstruction no longer sleeps. - - code_imp: Teslium reactions and Holywater booms no longer sleep. - - code_imp: Slime timestop no longer sleeps. - Putnam3145: - - bugfix: inelastic exports no longer uselessly do exponential functions -2021-06-24: - WanderingFox95: - - rscadd: An announcement to let players know the Cat Surgeon has come to visit. - - balance: Upped the Volume of his spawn noise and lowered the spawn weight slightly. -2021-06-25: - MrJWhit: - - rscadd: Adds two missing decals to the 5x5 SM. - brokenOculus: - - rscadd: pillbottles and syringesare now printable from the medbay protolathe, - shiftstart. Hyposprays are now printable in medbay lathe under advanced biotech. -2021-06-28: - Putnam3145: - - bugfix: APCs aren't infinite power anymore - - rscadd: FDA, LINDA without the bookkeeping. - - rscadd: Putnamos, a simpler replacement for Monstermos. If I can get Monstermos - to work, this will be Monstermos instead. - - rscdel: LINDA, the old active-turfs-based atmos subsystem. - - rscdel: Monstermos? I would rather not get rid of this, but I can't get it to - work correctly. - - server: Extools has been removed, and loading extools alongside auxtools will - cause massive problems. If this is tested or merged, remove extools from the - static files. - WanderingFox95: - - rscadd: Carrots are good for your eyes - but eyes are also good for your carrots. - Adds the googly eyes trait to walkingshrooms (Oculary Mimicry) - - imageadd: Googly Eyes - they make everything better. -2021-06-30: - WanderingFox95: - - rscadd: More plushies in the code. - - imageadd: Nabbed some plushie sprites from Cit RP and TG and made some myself. - Enjoy! - - rscadd: The Daily Whiplash (Newspaper Baton) is now available! (Using sticky tape - to stick a newspaper onto a baton) Bap! - - imageadd: A rolled up newspaper sprite was provided. - - balance: Switched Gateway and Vault locations on Boxstation, bringing it more - in line with other stations. - bunny232: - - rscadd: The pubby xenobiology air/scrubber network is now isolated from the rest - of the station - qweq12yt: - - rscdel: HoP's cargo access was removed... - shellspeed1: - - balance: NT has lost experimental KA tech to miners who were lost in the field. - Make sure to try and recover it. - - rscadd: Adds an extremely expensive survival pod to mining for people to work - towards. Get to work cracking rocks today. -2021-07-02: - silicons: - - bugfix: spray bottles work again. -2021-07-03: - DeltaFire15: - - bugfix: Turrets on nonlethal mode now once again shoot till the target is stamcrit - as opposed to unable to use items, resolving some issues. - Putnam3145: - - bugfix: A bunch of sleeping process() calls now either don't sleep or make sure - to call a proc with waitfor set to FALSE - WanderingFox95: - - bugfix: The axolotl ears in the .dmi file actually exist to the game now. -2021-07-04: - cadyn: - - server: Updated server scripts for proper linux support -2021-07-05: - Putnam3145: - - bugfix: Watchers no longer search 9 tiles away for stuff then throw the result - away if it's more than 1 tile away - - server: Auxmos pull now uses a tag instead of pulling straight from the main branch - WanderingFox95: - - bugfix: Moved a sprite one pixel to the left. - zeroisthebiggay: - - imageadd: tg based tool resprites - - bugfix: wirecutters have proper overlays -2021-07-07: - DeltaFire15: - - bugfix: Golem / Plasmaman species color should work again. -2021-07-09: - MrJWhit: - - bugfix: Made a light not exist on the same tile as a door on pubby. - - bugfix: Makes the RD APC automatically connect to the powernet with the correct - wire on pubby. - - rscadd: Added another wall for the AM engine so it doesn't space the airlock roundstart. -2021-07-10: - WanderingFox95: - - imageadd: Returns the wheelchair sprites to having, you know, wheels? - - rscadd: 'A motorized wheelchair addsound: Chairwhoosh.' -2021-07-11: - shellspeed1: - - balance: replaces the seed machine with a biogen in the survival pod. - - bugfix: corrected an issue regarding wrong pair of gloves in the pod for DYI wiring - . -2021-07-12: - Putnam3145: - - refactor: causes_dirt_buildup_on_floor is now just a thing humans do instead of - a weird var only true for humans -2021-07-13: - MrJWhit: - - rscadd: Adds a mirror above the sink in the captains bedroom in pubby -2021-07-14: - Putnam3145: - - refactor: Acid is now a component -2021-07-15: - Putnam3145: - - bugfix: fixes a major source of lag -2021-07-17: - cadyn: - - server: precompile.sh updated -2021-07-18: - timothyteakettle: - - bugfix: fixes photosynthesis stopping nutrition going past well fed from non-photosynthesis - means -2021-07-19: - Arturlang: - - bugfix: The crafting button should no longer silently make more copies of itself - on reconects - - code_imp: There are no longer two copies of the crafting component. - - code_imp: 'There is no longer a rogue d in tracer.dm tweak: Everything in Misc - was moved to Miscelanious in the crafting menu, and Misc was nuked from orbit. - Nobody will miss you.' - MrJWhit: - - bugfix: Fixes a memory leak, there's a good chance that it's the same one that - killed kilo. - SandPoot: - - rscadd: Put back mob vore with a pref. - - code_imp: Taken some stuff from tg for tgui_alert. - - refactor: Refactored a lot of code on vore panel. - WanderingFox95: - - rscadd: custom plasteel kegs - YakumoChen: - - rscadd: You can now wear the suffering of others on your head with just a sheet - of human skin! - - imageadd: Human skin hats - keronshb: - - rscadd: Stripping/equipping things to a conscious braindead person (AKA a human - owned by a disconnected player) will now give them a message with your visible - name and roughly how long ago you touched their stuff when they login again. - Touching someone's pockets or adjusting their gear other than equipping/unequipping - is not logged. After 5 minutes, you'll have forgotten both their name and exactly - how long ago past those 5 minutes it happened. (Credit to Ryll-Ryll) - - rscadd: LAZYNULL - - rscadd: Breaking mirrors now gives you a bad omen - timothyteakettle: - - bugfix: anthros can now select the cow tail - - rscadd: new quirk that allows you to eat trash -2021-07-23: - silicons: - - balance: Batons are slightly more powerful. -2021-07-24: - MrJWhit: - - rscadd: Replaces the northwest maint room on box with a sadness room - - rscadd: Replaces bar stripper room with an arcade on boxstation - - rscadd: Squished the west bathrooms a bit and made a room to sell things on boxstation. - - balance: Southeast maint hallway on box is now ziggy and zaggier. - - bugfix: Fixed pipes being not connected with the recent map PR for boxstation. - Putnam3145: - - bugfix: hallucination now bottoms out at 0 - - balance: supermatter now causes only half the hallucinations - cadyn: - - server: auxmos bump for dependencies.sh -2021-07-26: - SandPoot: - - rscdel: Removes a sneaky transform button on the vore panel. -2021-07-27: - Putnam3145: - - bugfix: Generic fires work now - - balance: A knock-on effect of the HE pipe change is that space cooling is ~8.4x - as powerful -2021-07-29: - EmeraldSundisk: - - rscadd: Adds decals between Virology and the general Medbay to provide clarity - - rscadd: Adds an airlock with access to the Engineering Cooling Loop - - rscadd: The Maintenance Theater now has a suitable amount of dust - - rscdel: Removed an errant entertainment monitor left in the morgue - - rscdel: 'Removed redundant scrubber piping in and around the bar and kitchen tweak: - Slightly readjusts an airpipe to take advantage of newfound space tweak: The - Toxins Lab has received (predominantly) visual adjustments as to render it more - in line with the general science department tweak: Toxins Storage is no longer - its own area and as such needn''t worry about APCs' - - bugfix: Hydroponics now has a proper APC as intended -2021-07-31: - MrJWhit: - - bugfix: Fixes some minor mistakes around space near boxstation. - TripleShades: - - rscadd: 'Fountain area to public mining station-side tweak: Moved around the tables - and chairs and monitor at public mining station-side' - WanderingFox95: - - rscadd: 'Added new ruin maps: The Bathhouse, The Library, The Engineering outpost, - The Hotsprings(un-cursed), Lust, Wrath and an alternate spawn for the BDM in - the form of a mining outpost, based on the same Ruins on the Ice Moon. removed: - A lot of the fun items within the ice moon-based ruins that would break mining - even more and trading cards.' - - balance: 'Yes, this includes that the lavaland version of the hot spring is literally - just water and not cursed. tweak: Also "fixed" that only one version of the - BDM ruin ever spawns. Not sure it needed fixing but even locally hosted, only - blooddrunk2.dmm would spawn. Since I added another spawn for the BDM, I fixed - that too.' -2021-08-02: - TripleShades: - - rscadd: 'Decorative (read: Station-safe) water tile in the code' - - bugfix: Pubby's new water feature wont kill atmosphere anymore -2021-08-03: - zeroisthebiggay: - - balance: tempgun is a laser - - balance: bake mode is useful - - balance: tempgun has less shots - - imageadd: tempgun has more sprites -2021-08-04: - BlueWildrose: - - bugfix: The debrained overlay actually shows for brainless corpses now instead - of showing a blue error. - timothyteakettle: - - bugfix: legs are no longer awful -2021-08-05: - Putnam3145: - - bugfix: organs decay again -2021-08-07: - BlueWildrose: - - bugfix: The black dress, pink tutu, the bathrobe, the kimonos, and the qipaos - no longer have a missing pixel when wearing them with the feminine bodytype. - They're also no longer adjustable (they have no sprite for the adjusted variant - and therefore it would just make an error if someone did that.) - Putnam3145: - - balance: 'Supernova rad storms are now half as likely per tick tweak: Supernovae - don''t announce they''re ending if they never announced they''re starting tweak: - Supernovae say explicitly no rad storms can happen if they can''t' - - rscadd: Monstermos is back -2021-08-09: - Arturlang: - - bugfix: Nanite machinery overlays should now work properly - - code_imp: screen objects are now atom/movables instead - - code_imp: Update appearance is used for updating atoms now instead of update_icon - and such - BlueWildrose: - - bugfix: Old gateway animation is back. Feedback is given that the gateway is open - again. - Putnam3145: - - balance: Rod of asclepius can now be used for revival surgery -2021-08-11: - timothyteakettle: - - rscadd: lets felinids, humans and moths have markings -2021-08-12: - Arturlang: - - rscdel: Nonslimes and nonvampires will no longer be able to increase their blood - to stupid heights - Putnam3145: - - refactor: Supermatter values use auxgm - cadyn: - - server: precompile.sh and build.sh updated, auxmos set to 0.2.3 in dependencies.sh -2021-08-13: - Putnam3145: - - bugfix: makes certain organs no longer have circular references -2021-08-16: - BlueWildrose: - - bugfix: Incapacitated mobs are blacklisted from being human-level intelligence - sentience event candidates. This is particularly important due to slimes in - BZ stasis on the station. - bunny232: - - bugfix: Polyvitiligo actually changes your color now -2021-08-18: - timothyteakettle: - - rscadd: lets you select 4 prosthetic limbs instead of only 2 -2021-08-20: - EmeraldSundisk: - - rscadd: Adds a law office/courtroom to OmegaStation - - rscadd: Adds a gateway to OmegaStation - - rscadd: Adds a pool/maintenance bar to OmegaStation - - rscdel: 'Removes the original maintenance garden in OmegaStation tweak: Relocates - the bathrooms to the starboard hall tweak: Modifies port quarter maintenance - to include some affected items' - Putnam3145: - - rscadd: Beach now has showers - TripleShades: - - rscadd: At least four or five space heaters spread across Pubby Station Maints - - rscadd: Missing decal in Pubby Station engineering - - bugfix: Moved an atmos alarm in the SM emitter chamber so it wont be destroyed - WanderingFox95: - - rscadd: Empty bottles and pitchers are available to the bartender now. - - imageadd: They even come with 10 different fillstates! - - imageadd: Better Shark Tails, dodododododo~ - - rscadd: The old ones are now listed as carp tails. diff --git a/html/changelogs/archive/2015-04.yml b/html/changelogs/archive/2015-04.yml new file mode 100644 index 0000000000..ca148891fc --- /dev/null +++ b/html/changelogs/archive/2015-04.yml @@ -0,0 +1,357 @@ +2015-04-04: + ACCount: + - rscadd: Emergency welding tool added to emergency toolbox. + - rscadd: Changed industrial welding tool sprite. + - tweak: Replaced welder in syndicate toolbox with industrial one. + - tweak: All tools in syndicate toolbox are red. Corporate style! + - tweak: Red crowbar is a bit more robust. + - bugfix: 'Fixed two bugs: welder icon disappearing and drone toolbox spawning with + invisible cable coil.' + AnturK: + - rscadd: 'Picket signs: table crafted with a rod and two cardboard sheets, write + on them with pen or crayon.' + Cheridan: + - wip: The bar's layout has been changed with a poker table and re-arranged seating. + Dannno: + - rscadd: Added gun lockers for shotguns and energy guns. Click on the lockers with + an item to close them if they're full. + Gun Hog: + - rscadd: Nanotrasen research has finalized improvements for the experimental Reactive + Teleport Armor. The armor is now made of a thinner, lightweight material which + will not hinder movement. In addition, the armor shows an increase in responsiveness, + activating in at least 50% of tests. + Incoming: + - rscadd: The iconic blood-red hardsuits of nuke ops can now be purchased for a + moderate sum of 8 TC by traitors. + Jordie0608: + - tweak: Cyborg mining drills now use up their internal battery before drawing power + from a borg's cell. + - bugfix: Fixes cyborg mining drills not recharging. + RemieRichards: + - rscadd: Burning mobs will ignite others they bump into or when they are stepped + on. + Xhuis: + - tweak: Malfunctioning AIs can no longer leave the station z-level. Upon doing + this, they will fail the round. + - tweak: Phazon exosuits now require an anomaly core as the final step in their + construction. + xxalpha: + - rscadd: Added Nutriment Pump, Nutriment Pump Plus and Reviver implants. + - tweak: Added origin technologies to all implants. + - tweak: 'The following implants are now much harder to obtain: X-ray, Thermals, + Anti-Stun, Nutriment Pump Plus, Reviver.' + - tweak: Cauterizing a surgery wound will now heal some of the damage done by the + bonesaw if it was used as part of the same surgery. + - tweak: Added ability for Medical HUDs to detect cybernetic implants in humans. +2015-04-09: + Iamgoofball: + - rscadd: Quite a lot of cleanables can now be scooped up with a beaker in order + to acquire the contents. + - rscadd: Light a piece of paper on fire with a lighter, and scoop up the ashes! + - rscadd: Scoop up the flour the clown sprayed everywhere as a 'joke'! + - rscadd: Scoop up the oil left behind by exploding robots for re-usage in chemistry! + - rscadd: You can splash the contents of a beaker onto the floor to create a Chemical + Pile! This pile can be heated or blown up and have the reagents take the effects. + Make a string of black powder around a department in maint. and then heat it + with a welder today! + - rscadd: Reagents now can have processing effects when just sitting in a beaker. + - rscadd: Pyrosium and Cryostylane now feed off of oxygen and heat/cool the beaker + without having to be inside of a person! + - rscadd: Reagents can now respond to explosions! + - rscadd: Black Powder now instantly detonates if there is an explosion that effects + it. + - rscadd: Fire now heats up beakers and their contents! + - rscadd: Activate some smoke powder in style by lighting the beaker on fire with + a burning hot plasma fire! + RemieRichards: + - tweak: Ninja stars are summoned to your hand to be thrown rather than automatically + targetting nearby mobs. + - rscadd: 'Added Sword Recall: pulls your katana towards you, hitting mobs in the + way. Free if within sight, cost scales with distance otherwise.' + - rscadd: Enemies can be electrocuted by a ninja as the cost of his energy, stunning + and injuring them. + - rscdel: Removed SpiderOS, functions moved to status panel. + - bugfix: Fixed energy nets not anchoring target, katana emag spam and sound delay. + optimumtact: + - bugfix: Mimes can't use megaphone without breaking their vow anymore. + phil235: + - tweak: Flying animals no longer triggers mouse traps, bear traps or mines. +2015-04-11: + Gun Hog: + - tweak: Nanotrasen has approved an access upgrade for Cargo Technicians! They are + now authorized to release minerals from the ore redemption machine, to allow + proper inventory management and shipping. + Iamgoofball: + - tweak: Blobbernauts no longer deal chemical damage, brute damage increased however. + Ikarrus: + - experiment: Getting converted by a rev or cultist will stun you for a few seconds. + Incoming5643: + - bugfix: Fixes some AI malf powers being usable when dead. + MrPerson: + - tweak: Reduces movement speed penalty from being cold. + Xhuis: + - rscadd: Adds a pizza bomb traitor item for 4 telecrystals. It's a bomb, diguised + as a pizza box. You can also attempt to defuse it by using wirecutters. + kingofkosmos: + - rscadd: Activating internals with an adjusted breath mask will automatically push + it up to normal state. + - tweak: Masks can now be adjusted when buckled to a chair. + optimumtact: + - tweak: Stun batons no longer lose charge over time when on. + phil235: + - tweak: The AI holopads now use a popup window just like computers and other machines. + - rscdel: Nerfs kinetic accelerator and plasma cutters. Plasma cutter is no longer + in the mining vendor. Reduces the drilling cost of all drills. + - rscadd: Adding 40+ new food and drink recipes, mostly using the newest plants. + Notably rice recipes, burritos, nachos, salads, pizzas. + - tweak: Opening the tablecrafting window can now also be done by dragging the mouse + from any food (that's on a table) onto you. + - rscadd: The kitchen cabinet starts with one rice pack. + - tweak: Glasses with unknown reagent will no longer be always brown but will take + the color of their reagents. +2015-04-13: + AnturK: + - rscadd: 'Spacemen have learned the basics of martial arts: Boxing, unleash it''s + power by wearing Boxing Gloves.' + - rscadd: While boxing you can't grab or disarm, but you hit harder with a knockout + chance that scales off stamina damage above 50. + - rscadd: Rumors have been heard of powerful martial styles avaliable only to the + gods themselves. + CosmicScientist: + - rscadd: Added a dehydrated space carp to traitor items, bought with telecrystals. + Use dehydrated space carp in hand to school them on loyalty. Add water to create + a vicious murder machine just for the halibut. + - tweak: The toy carp plushie now has attack verbs for fun, hit your friend with + one today. I put my sole into this mod. + - wip: If you can think of a better fish pun let minnow but I shouldn't leave it + to salmon else. + Ikarrus: + - tweak: Gang bosses can no longer purchase certain potent traitor items but instead + have access to some of a nuke op's arsenal of weapons. + Incoming5643: + - rscadd: 'Three new chemical types of blob can occur: Omnizine, Morphine and Space + Drugs.' + MrPerson: + - experiment: New lighting system! Lighting now smoothly transfers from one lighting + level to the next. + Xhuis: + - rscadd: There have been... odd sighting in Space Station 13's sector. Alien organisms + have appeared on stations 57, 23, and outlying. + - rscadd: Nanotrasen personnel have reason to believe that Space Station 13 is under + attack by shadowlings. We have little intel on these creatures, but be on the + lookout for odd behavior and dark areas. Use plenty of lights. + Zelacks: + - tweak: Defibs no longer have a minimum damage requirement for a successful revive. + Patients will have 150 total damage on a successful revive. + - tweak: Additional feedback is given for several failure states of the defib. + xxalpha: + - wip: Airlock crushing damage increased. +2015-04-16: + AnturK: + - rscadd: Nanotrasen authorities are reporting sightings of unidentified space craft + near space station 13. Report any strange sightings or mental breakdowns to + central command. + - rscadd: 'PS : Abductions are not covered by health insurance.' + - rscadd: Shadowlings and their thralls now have HUD icons. + - rscadd: Thralls learn their master's objectives when enthralled. + - rscadd: Regenerate Chitin ability lets shadowlings re-equip their armor if lost. + - tweak: Loyalty implanted people take 25% longer to enthrall, but lose their implant + and become immune to re-implanting. + - experiment: Shadowlings now have a message in their spawning text which specifies + that cooperation is mandatory. + - bugfix: Veil now works on equipped lights. + - bugfix: Shadowlings now take correct amount of burn damage and in light and heal + clone and brain damage in darkness. + - bugfix: Fixes 'Round end code broke' displaying every round. + - bugfix: Shadowlings who ascend will nore greentext properly. + Gun Hog: + - rscadd: Thinktronic Systems, LTD. has increased the Value of the Value-PAK PDA + cartridge! Standard issue for Captain PDAs, it can now access security bots, + medibots, cleanbots, and floorbots ALL AT ONCE! In addition, it can also connect + to your station's Newscaster network at NO EXTRA CHARGE! As a Thank you for + our contract with them, they have thrown in Newscaster access for the HumanResources9001 + cartridge, Heads of Personnel rejoice! + - tweak: The Newscaster app has also gotten a free upgrade which allows it to display + images and comments inside of posts! + - bugfix: Nanotrasen has concurrently released a patch for bots which will allow + off-station bots to properly patrol. + Incoming5643: + - rscadd: Changeling head slugs have been given player control, ventcrawling, and + a short escape period after egg laying. + MrStonedOne: + - rscadd: Admin ghosts can now drag ghosts to mobs to put that ghost in control + of that mob. + Xhuis: + - rscadd: Nanotrasen scientists have recently observed a strange genome shift in + green slimes. Experiments have shown that injection of radium into an active + green slime extract will create a very unstable mutation toxin. Use with caution. +2015-04-19: + AnturK: + - bugfix: Observers can now see abductor hivemind messages. + - rscadd: 'Adds advanced baton for abductors: Stun, Sleep and Cuff in one tool.' + - rscadd: Abductor agents now have vest cameras. + - imageadd: New sprites for abductors and their gear made by Ausops. + Fayrik: + - rscadd: Added jobban options for Abductors and Deathsquads. + - tweak: Made admin antag spawning buttons more efficient and less prone to failure. + Xhuis: + - rscadd: Recent sightings aboard space stations shows that spirits seem to be manifesting + as malevolent revenants and draining the life of crew. The chaplain may be helpful + in stopping this new threat. + kingofkosmos: + - wip: Girder and machine frame construction protocols has been changed. They can + now be secured/unsecured with a wrench and disassembled with a welder. +2015-04-20: + Fayrik: + - rscadd: Abductors now get advanced camera consoles. + - tweak: Redesigned Centcom again. There's a bar at the thunderdome now. + - rscadd: Headsets can now be locked to a spesific frequency, this only occurs for + nuke ops and deathsquads. + - rscadd: The Centcom channel is now available over all z-levels, regardless of + telecomms status. + - tweak: The Deathsquad space suits have been upgraded to hardsuits. + - rscadd: The Deathsquad now have thermal imaging huds, which can swap which hud + they display on the fly. + phil235: + - tweak: Reagents are now back to being metabolized every tick. Fixes frost oil + and capsaicin not working. + - tweak: Fixes not being able to make sterilizine. + - rscadd: Adding overdose to space drug, causing mild hallucination and toxin and + brain damage. + - tweak: Nerfed healing power of stimulant reagent. Buffed ephedrine a bit. + - rscadd: Nitroglycerin can now be stabilized with stabilizing agent, and explodes + when heated. +2015-04-21: + Ikarrus: + - wip: Gang mode has had some considerable work done on it, including a new objective + and currency dynamic. + - rscadd: New objective: Claim half the station as territory by tagging it + with spray cans supplied to gang bosses, but usable by any member. + - wip: An area can only be tagged by one gang at a time, remove your opponent's + tag or spray over it. + - rscadd: New recruitment: Recruiment pens replace flashes, stab people to + recruit them. + - experiment: Recruitment is silent, but causes brief seizures and has a cooldown + that scales upwards with a gang's size. + - rscadd: New tool: The Gangtool is used by bosses and lieutenants to recall + the shuttle and purchase supplies. + - rscadd: Pistols, ammo, spraycans, recruitment pens and additional gangtools can + all be bought. + - tweak: Gangtools also alert the user of promotions, purchases and territory changes + within the gang. + - rscadd: Lieutenants are promoted from gang members when given their own gangtool; + they're immune to deconversion and able to do anything a boss can except promotion. + - rscadd: New currency: Influence is used to purchase with the gangtool and + is generated every 5 minutes by each territory owned by the gang. + - tweak: Thermite can be cleaned off walls now. +2015-04-22: + Incoming5643: + - rscadd: 'Adds a new fun button for admins: ''Set Round End Sound''. You can use + the set round end sound button to set the round end sound. Glad we cleared that + up!' + Miauw62: + - wip: Very slightly expanded atmos and added an external airlock. + Xhuis: + - bugfix: A few issues have been fixed for revenants. In addition, the Mind Blast/Mind + Spike sound effect has been removed. + - rscadd: Adds the Hypnotize ability to revenants. It will cause a target to fall + asleep after a short time. + xxalpha: + - rscadd: Added an Exosuit Mining Scanner to the robotics fabricator. + - tweak: Buffed Ripley's movement and drilling speed in low pressure environments. +2015-04-25: + Boggart: + - rscadd: Generalizes handheld instrument code and Ports Nienhaus's guitar, sounds + by BartNixon of Tau Ceti. + - rscadd: Fixes being unable to build disposal pipes on walls, makes changing the + RPD's settings not affect pipes that are currently building, makes the RPD use + the datum/browser ui, makes it use categories and makes it show the selected + mode. + Gun Hog: + - rscadd: Nanotrasen has provided designs for fabrication of APC power control modules. + You may print them at any autolathe. + Ikarrus: + - rscadd: Gangs can now purchase switchblades, a relatively cheap and decently robust + melee weapon. + - tweak: Gangs now require at least 66% control of the station to win. + - tweak: Gang spraycan uses reduced to 15. + - tweak: Pistol cost increased to 30 Influence + - tweak: Promotions now start off cheap at 20 influence but get more expensive the + more people you promote. + Xhuis: + - rscadd: Added a Create Antagonist button for revenants. + - rscdel: Removed Mind Blast. + - bugfix: Revenants no longer get killed by explosions. + - tweak: Mind spike cooldown increased to 4 seconds. + - tweak: Harvest now takes 8 seconds and requires you to be adjacent to the target. + - tweak: Hypnotise sleeps targets for longer. + - tweak: Revenant now starts with 3 strikes. + phil235: + - tweak: Telecom machines are now deconstructed the same way as all other constructable + machines. + - tweak: You can no longer overdose on nicotine but you can get addicted (very mild + effects). +2015-04-29: + AndroidSFV: + - tweak: Dehydrated carp now are friendly to both the imprinter of the plushie as + well as any coded-in allies (I.E. Nuke Ops team), and unfriendly to carp of + other origin othan than yourself or your coded-in allies. Dehydrated carp that + are not imprinted will still have the same behavior as regular carp. + AnturK: + - rscadd: Advanced cameras now have all functionality of the abductor consoles. + - tweak: Pinpoint teleportation takes 8 seconds and spawns a flashy silhouette at + the target location. Can be used as distraction since it appears even if teleporter + is empty. + - bugfix: Abductors are now immune to viruses. + - bugfix: Dissection surgery ignores clothes. + - bugfix: Non-abductors can escape the ship by fiddling with consoles enough. + - rscadd: Three new negative glands. + - rscadd: Bloody glands spray blood everywhere and injure the host. + - rscadd: Bodysnatch glands turn the host into a cocoon that hatches doppelgangers. + - rscadd: Plasma glands cause the host to explode into a cloud of plasma. + GoonOnMoon: + - rscadd: Added a new assault rifle to the game for use by Nanotrasen fighting forces + in special events. Also happens to be available in the Liberation Station vending + machine and the summon guns spell usable by the wizard and badminnery. + Iamgoofball: + - rscdel: Acid blob has been removed. + - tweak: Charcoal and Silver Sulf are more powerful now. + - tweak: Styptic power and Silver Sulf metabolize at the default rate. + Ikarrus: + - rscadd: Spraycans and crayons can now draw Poseur Tags, aka Fake Gang Tags, as + grafiti. + - tweak: Influence income changed to provide weaker gangs a bigger boost, while + slowing down stronger gangs to promote opportunity for comebacks. + - tweak: Gangs only earn influence on territories they have held on to since the + previous Status Report (the income calculation every 5 minutes). This places + more significance on defending your existing territory. + - bugfix: You must be in the territory physically to tag it now. So no more tagging + everything from maint. + - tweak: Gang income delay reduced to 3 minutes intervals. + - tweak: Gang Capture goal reduced to 50% + - tweak: Gang spraycan use increased to 20 + - tweak: Gang Boss icon is now a red [G] icon to make it stand out better from regular + gang icons + JJRcop: + - tweak: TED's kill duration has been halved. + - tweak: Escaping from the TED's field no longer kills you. + RemieRichards: + - rscadd: Adds Easels and canvases for custom drawings. + - imageadd: Place a canvas on an easel and draw on it with crayons, clean one pixel + with a rag or soap and activate it in-hand to erase the whole canvas. + - rscadd: Ports VG's Ventcrawling overhaul! + - tweak: Crawling through vents is no longer instant, you now have to move and navigate + manually + - rscadd: While inside pipes and other atmos machinery, you now see pipe vision + phil235: + - bugfix: Podplants are no longer unharvestable. + - tweak: Choosing your clown, mime, cyborg and AI name as well as religion and deity + is now done in the preferences window. As a chaplain , your bible's icon is + now chosen by clicking the bible. +2015-04-30: + Fayrik: + - rscadd: Ported NanoUI to most atmospherics equipment. + TheVekter: + - tweak: Hooch is now made with 2 parts Ethanol, 1 part Welder fuel and 1 part Universal + Enzyme as a catalyst. + - tweak: No-slip shoes are paintable, painting them doesn't remove no-slip properties. diff --git a/html/changelogs/archive/2015-05.yml b/html/changelogs/archive/2015-05.yml new file mode 100644 index 0000000000..107d2e8572 --- /dev/null +++ b/html/changelogs/archive/2015-05.yml @@ -0,0 +1,228 @@ +2015-05-01: + Ikarrus: + - rscadd: Gang bosses can now rally their gang to their location with their gangtool. + - rscadd: Gangtools can no longer recall the shuttle if station integrity is lower + than 70% + - rscdel: Removed requirement to be in the territory to tag it. + - tweak: Recruitment Pen cost reduced to 40. + - bugfix: Communications console should now accurately print the (lack of a) location + of the last shuttle call. + Xhuis: + - rscdel: Revenants will no longer spawn without admin intervention. They are pending + a remake. +2015-05-02: + Boggart: + - bugfix: Cryo tubes can no longer be used for ventcrawling. + Ikarrus: + - rscadd: Admins can choose the strength and size of Centcom teams to send, ranging + from officials to deathsquads, with the 'Make Centcom Respone Team' button. + phil235: + - tweak: Space carps can no longer knock down anyone, but they now deal additional + stamina damage to humans. + - tweak: Radiation effects from uranium walls are nerfed to the level of uranium + floor. + - rscadd: You can no longer put an inactive MMI in a cyborg shell. Ghosted brains + now get an alert when someone puts their brain in a MMI. You can now examine + the MMI to see if its brain is active. +2015-05-03: + AnturK: + - rscadd: Abductors can purchase spare gear with experimentation points. + Ikarrus: + - rscadd: Admins can now adjust the pre-game delay time. + MrStonedOne: + - experiment: MasterController and subsystem rejiggering! + - rscadd: The MC can now dynamcially change the rate a subsystem is triggered based + on how laggy it's being. This has been applied to atmos to allow for faster + air processing without lagging the server + - tweak: Pipes and atmos machinery now processes in tune with air, rather than seperately. + - bugfix: Fixed hotspots and fire causing more lag than they needed to + - bugfix: Fixed some objects not getting garbage collected because they didn't properly + clear references in Destory() + - tweak: The qdel subsystem will now limit its processing time to a 5th of a second + each tick to prevent lag when a lot of deletes happen + - bugfix: Fixed the ticker not showing a tip of the round if an admin forces the + round to start immediately +2015-05-04: + Firecage: + - bugfix: Emagged windoors can now be deconstructed. + RemieRichards: + - rscadd: Adds Plasmamen, a species that breathes plasma and bursts into flames + if they don't wear special suits. + - imageadd: New burning icon for all humanoid mobs. + - imageadd: New sprite for Skeletons to match Plasmamen. + oranges: + - tweak: Thanks to recent advances in fork science, you no longer need to aim at + your eyes to eat the food off a fork + xxalpha: + - rscadd: 'Adds a new barsign: ''The Net''.' +2015-05-05: + Firecage: + - bugfix: Golems and skeletons no longer fall over when stepping on shards. + Gun Hog: + - bugfix: Mining borg diamond drill upgrade now functional. + Ikarrus: + - tweak: Doubled the initial charge of SMESs in Engineering. + - tweak: Influence cap for gangs has been increased. + incoming5643: + - bugfix: All modes now select their antagonists before job selection, this means + that a player who prefers roles normally immune to being certain antagonists + (implanted roles/silicons) can still have a fair shot at every antagonist roll + they opt into. If they're selected they simply will not end up with an incompatible + job. + - bugfix: As an example if someone loved to play Head of Security (humor me here) + and had it set to high, and the only other jobs he had set were security officer + at medium and botanist at low but he was selected to be a traitor, he would + spawn as a botanist even if there ended up being no Head of Security. + - experiment: Please give playing security another chance if you'd written it off + because it affected your antag chances. + xxalpha: + - bugfix: Hulks can now break windoors. + - bugfix: Fixed smoking pipe messages. Fixed emptying a smoking pipe with nothing + in it. +2015-05-06: + Jordie0608: + - bugfix: Borgs can now open lockers with the 'Toggle Open' verb. + Thunder12345: + - bugfix: Severed the cryo tube's connection to the spirit world. Ghosts will no + longer be able to eject people from cryo. Please report further instances of + poltergeist activity to your local exorcist. + Xhuis: + - tweak: Many minor technical changes have been made to cult. + - rscadd: Cultist communications now show the name of the person using them. Emergency + communications do not do this. + - rscadd: Emergency communication does less damage. + xxalpha: + - rscadd: Engineering cyborgs can now pick their cable coil color whenever they + want. +2015-05-07: + Xhuis: + - rscadd: Emagged defibrillators will now do burn damage and stop the patient's + heart if used in harm intent. + - tweak: The previous stunning functionality of the emagged defibrillator has been + moved to disarm intent. + phil235: + - tweak: Temperature effects from frost oil and capsaicin reagents and basilisk + have been buffed to be significant again. + xxalpha: + - tweak: Hulks can now break windoors. +2015-05-08: + Firecage: + - tweak: Mobs can now be buckled to operating tables. + Gun Hog: + - rscadd: 'Top scientists at Nanotrasen have made strong progress in Artificial + Intelligence technology, and have completed a design for replicating a human + mind: Positronic Brains. Prototypes produced on your research station should + be compatible with all Man-Machine Interface compliant machines, be it Mechs, + AIs, and even Cyborg bodies. Please note that Cyborgs created from artificial + brains are called Androids.' + - tweak: The pAI role preference and related jobbans have been renamed to properly + reflect that they are not soley for pAI, but include drones and positroinc prains. + astralenigma: + - tweak: Cargo packages are now delivered with their manifests taped to the outside. + Click on them with an open hand to remove them. + optimumtact: + - tweak: Machine frame and girder deconstruction now uses a screwdriver instead + of welding tool. +2015-05-09: + Firecage: + - tweak: Increased the manifestation chance of super powers. + Ikarrus: + - experiment: 'Loyalty implants will no longer survive deconverting a gangster. + Security now needs to use two of them if they want the permanent effects: The + first to deconvert them, and the second to make them loyal.' + KorPhaeron: + - tweak: Slime mutation chance now starts at 30%. + - rscadd: Baby slimes have a -5% to 5% difference of their parent's mutation chance, + allowing you to breed slimes that are more likely to mutate. + - rscdel: Plasma and epinephrine no longer affect mutation chance of slimes. + - rscadd: Red slime extract and plasma makes a potion that can increase mutation + chance, Blue slime extract and plasma potions will decrease it. +2015-05-10: + AnturK: + - bugfix: Fixed borg's cells draining much faster than they're meant to. + Gun Hog: + - tweak: Station bot performance greatly increased. + - rscadd: Captain PDA cartridge now includes nearly all utilities and functions, + including signaller and all bots! HoP now has janitor and quartermaster functions! + The RD and Roboticists now have access to Floor, Clean, and Medibots! + - tweak: Bot access on PDA is now one button across all PDAs. You will only see + what bots you can access, however. + - rscadd: Cartridges that include a signaller have been improved so they will work + on a larger frequency range. + - tweak: All bots now have Robotics access, so they may be set to patrol and released + once constructed. + - tweak: Roboticists now have access to bot navigation beacons. They are found under + the floor tiles as patrol route nodes. +2015-05-11: + Firecage: + - imageadd: New icons for Industrial and Experimental welding tools. + Gun Hog: + - rscdel: The power mechanic for mining drills and the jackhammer has been removed. + They no longer require cells or recharging. + - bugfix: The diamond drill upgrade for mining cyborgs has been fixed. + Xhuis: + - rscadd: Adds the pneumatic cannon, attach an air tank and shoot anything out of + it. + - rscadd: Improvised pneumatic cannons can be tablecrafted with a wrench, 4 metal, + 2 pipes, a pipe manifold, a pipe valve and 8 package wrappers. + spasticVerbalizer: + - bugfix: False walls no longer stackable. +2015-05-13: + Firecage: + - rscadd: Kudzu is now admin-logged in Investigate. + GunHog: + - tweak: Positronic brains are now entered by clicking on an empty one, in the same + manner as drones. + - rscadd: Ghosts are alerted when a new posibrain is made. + Jordie0608: + - rscadd: Borg reagent containers (beakers, spraybottles, shakers etc.) are no longer + emptied when stowed. + - bugfix: Fixes North and West Mining Outposts having empty SMESs. + - bugfix: Aliens and slimes can smash metal foam again. + - rscdel: Deconstructing reinforced walls no longer creates additional rods out + of nowhere. + - imageadd: Pepperspray now has inhand sprites. + Xhuis: + - bugfix: Fixes the recipe for pneumatic cannons; it now only requires a wrench, + 4 metal, 2 pipes and 8 package wrappers . +2015-05-15: + xxalpha: + - bugfix: Fixed emitter beams not being reflectable. +2015-05-16: + MartiUK: + - bugfix: Fixed a typo when cleaning a Microwave. + - bugfix: Fixed a typo when burning someone with a lighter. +2015-05-20: + xxalpha: + - rscadd: Added three drone shells to the derelict. +2015-05-22: + Jordie0608: + - tweak: Smothering someone with a damp rag when in harm intent will apply reagents + onto them, for acid-burning their face; otherwise it will inject them, for drugging + with chloral hydrate. + - imageadd: The healthdoll is now blue when at full health to make it more clear + when a body part is injured. +2015-05-25: + spasticVerbalizer: + - tweak: Glass airlocks can now be made heat-proof by using a sheet of reinforced + glass to create the window, regular glass creates a normal glass airlock. + xxalpha: + - bugfix: You can no longer drop items inside mechas nor machinery (this includes + gas pipes, disposal pipes, cryopods, sleepers, etc.). + - bugfix: Fixed exploit of changelings being able to keep thermal vision after resetting + their powers. + - bugfix: Fixed being able to implant NODROP items with cavity implant surgery. +2015-05-26: + CosmicScientist: + - spellcheck: Corrected wording for the pAI, donksoft riot darts and some tip of + the round tips. + xxalpha: + - bugfix: Fixed changeling revival. +2015-05-30: + duncathan: + - bugfix: Fixes passive gates not auto-coloring. + spasticVerbalizer: + - tweak: Players trying to speak but unable to will now get a message. +2015-05-31: + duncathan: + - tweak: Clarified the ability to retract changeling armblades. diff --git a/html/changelogs/archive/2015-06.yml b/html/changelogs/archive/2015-06.yml new file mode 100644 index 0000000000..703b141606 --- /dev/null +++ b/html/changelogs/archive/2015-06.yml @@ -0,0 +1,421 @@ +2015-06-04: + Cuboos: + - rscadd: Added casting and firing sounds for wizard spells and staves. + - rscadd: A new title theme has been added. + Gun Hog: + - rscadd: Nanotrasen has approved the designs for destination taggers and hand labelers + in the autolathe. + Palpatine213: + - tweak: Allows sechuds to have their id locks removed via emag as well as EMP +2015-06-05: + CandyClown: + - tweak: Ointments, bruise packs, and gauze are now stacked to 6 instead of 5. + CorruptComputer: + - bugfix: Security lockers no longer spawn in front of each other on Box. + - bugfix: Hooked up the scrubbers in QM's office on Box. + - bugfix: Fixed bar disposals on Box + - bugfix: Fixed the stacked heater+freezer in expirementor maint on Box + - tweak: Made the turbine into Atmos and Engineering access only, and renamed the + doors to Turbine on Box. + Ikarrus: + - rscadd: Gang Bosses will now be able to discreetly send messages to everyone in + their gang for 5 influence a message. + - tweak: Conversion pens now use a flat 60sec cooldown rate. + KorPhaeron: + - rscadd: You can now lay tiles on the asteroid. Go nuts building forts. +2015-06-06: + Incoming5643: + - rscadd: Antagonists with escape alone can now escape with others on the shuttle, + so long as they are also antagonists. + - rscadd: Antagonists with escape alone can also win if non-antagonists are on the + shuttle provided they are locked in the brig. + - rscadd: Escaping to syndicate space on board the nuke op shuttle is now a valid + way to escape the station. + Jordie0608: + - rscadd: Admin-delaying the round now works once it has finished. +2015-06-07: + Aranclanos: + - rscadd: Malfunctioning AIs can preview placement of a Robotic Factory. + Iamgoofball: + - rscadd: Bicardine, Dexalin, Kelotane, Anti-toxin, Inaprovaline and Tricordrazine + have been re-added. + RemieRichards: + - rscadd: Lizards can now wag their tails, emote *wag to start and *stopwag to stop. + kingofkosmos: + - tweak: Mops can now be wet from normal buckets and sinks. +2015-06-08: + AnturK: + - imageadd: Improved the interface of Spellbooks. + Cheridan: + - tweak: Push-force from Atmospherics now depends on an entity's weight, heavier + objects are less prone to being pushed. + - rscadd: Magboots and No-Slip shoes now prevent pushing from spacewind. + Firecage: + - rscadd: Protolathes can now build Experimental Welding Tools. +2015-06-09: + Aranclanos: + - wip: Structures and machines can now be built on shuttles. + Iamgoofball: + - rscadd: 'Adds the Bluespace Rapid Part Exchange Device: holds up to 400 stock + parts and can be used to upgrade machines at range without needing to open their + maintenance panel.' + - rscadd: A new tier of stock parts have been added, they're very expensive to produce + but provide ample improvements. + - experiment: Many machines can now also be upgraded. + - tweak: 'Emitter: Lasers decrease firing delay and Capacitors decrease power consumption.' + - tweak: 'Gibber: Matter Bins increase yield of meat and Manipulators speed up operation + time, at high level can gib creatures with clothes.' + - tweak: 'Seed Extractor: Matter Bins increase storage and Manipulators multiply + seed production.' + - tweak: 'Monkey Recycler: Matter Bins increase the amount of monkey cubes produced + and Manipulators reduce the monkey-to-cubes ratio to a minimum of 1-to-1.' + - tweak: 'Crusher: Matter Bins increase material yield and Manipulators increase + chance to yield materials, at high level there is a chance for rarer materials.' + - tweak: 'Holopad: Capacitors increase an AI''s traversal range from the holopad.' + - tweak: 'Smartfridge: Matter Bins increase storage.' + - tweak: 'Processor: Matter Bins increase yield and Manipulators speed up operation + time.' + - tweak: 'Microwave: Matter Bins increase storage.' + - tweak: 'Ore Redemption Machine: Matter Bins increase yield per ore, Lasers increase + points per ore and Manipulators speed up operation time.' + - tweak: 'Hydroponics Tray: Manipulators improve water and nutrients efficiency.' + - tweak: 'Biogenerator: Matter Bins increase storage.' + bananacreampie: + - rscadd: Added several new options to the ghostform sprites +2015-06-11: + Cheridan: + - rscdel: Removes the powerdrain for individiual active modules on cyborgs. +2015-06-12: + Ikarrus: + - experiment: Gang Updates + - rscadd: 'New objective: To win, Gangs must now buy a Dominator machine (50 influence) + and defend it for a varying time frame.
    * The location of the dominator is + broadcasted to the entire station the moment it is activated
    * The more territories + the gang controls, the less time it will take
    * Gangs no longer win by capturing + territories' + - rscadd: A choice of gang outfits are now purchasable for 1 influence each + - rscadd: Thompson SMGs aka "tommy guns" are now purchasable for 50 influence + - rscadd: Bulletproof armor vests are now purchasable for 10 influence + - tweak: Gang messages are now free to send + - tweak: Prices of pistols and pens reduced to 20 and 30, respectively + - tweak: Gang spraycans have been made a lot less obvious. They look nearly identical + to regular ones, now. + - rscdel: Gangs will no longer be notified how much territory the enemy controls + Incoming5643: + - rscadd: Growing tired of reports of slain members, the Wizard Federation has cautiously + sactioned the dark path of lichdom. Beware of the powerful lich who hides his + phylactery well, for he is immortal! + - rscadd: The trick to defeating liches is to destroy either their body or their + phylactery item before they can ressurect to it. The more a lich is slain the + longer it will take him to make use of his phylactery and the more likely the + crew is to catch him during a vunerable moment. + - rscremove: Due to the addition of proper liching, skeletons as a choosable race + from magic mirrors has been discontinued. My apologies to the powergamers. A + special admin version of the mirror that allows for skeletons has also been + added to the code. + Miauw: + - tweak: 'AIs have received several minor nerfs in order to increase antagonist + counterplay:' + - tweak: AI tracking is no longer instant, it takes an amount of time that increases + with distance from the AI eye, up to 4 seconds. The AI detector item will light + up when an AI begins tracking. + - tweak: A random camera failure event has been added, which will break one or two + random cameras. + - tweak: You can no longer keep tracking people that are outside of your camera + vision. + - tweak: Camera wires have been removed. Screwdriver a camera to open the panel, + then use wirecutters to disable it or a multitool to change the focus. + - tweak: You can now hit cameras with items to break them. To repair a camera, simply + open the panel and use wirecutters on it. + - tweak: Camera alerts now only happen after a camera is reactivated. + RemieRichards: + - rscadd: New optional explosion effect ported from /vg/'s DeityLink, Explosions + that are affected by Walls and Doors +2015-06-14: + Ikarrus: + - rscadd: White suits added to gang outfits + - tweak: Gang outfits are now free, but are now limited in stock (that replenishes + over time) + - tweak: While attempting a Hostile Takeover, gangs do not gain influence. Instead, + the takeover timer will be reduced by how many territories they control. + - tweak: Spraycan cost reduced to 5 influence. + - tweak: Recruitment Pen cooldown increased to 2 minutes, but is reduced if the + enemy gang has more members than yours. + - tweak: Tommy guns no longer deal stamina damage. + - rscdel: Gangtools can no longer recall the shuttle if the game mode is not Gang + War +2015-06-15: + Incoming5643: + - rscadd: Lizards can now choose from a wide varity of physical appearances in character + creation! Sprites made by WJohn. Hiss Responsibly. + Kor: + - rscadd: A terrible new creature stalks the halls of SS13. + - rscadd: The wizard has a new artefact related to said creature. + - rscadd: Added a new sepia slime plasma reaction. Try it out! + spasticVerbalizer: + - bugfix: Drones can now properly quick-equip. +2015-06-18: + AnturK: + - rscadd: Added new photo-over-pda function. Apply the photo to PDA to send it with + your next message! + Ikarrus: + - rscadd: Department Management consoles have been added to Head of Staff offices. + These will enable heads to modify ID's access to their department, as well as + preform demotions. + Miauw: + - tweak: Bullets can now damage cameras. + - tweak: Camera alarms now trigger 90 seconds after the first EMP pulse, instead + of when all EMP pulses run out. + - tweak: Makes the force required to damage cameras greater than or equal to ten + instead of greater than ten. + - tweak: Camera alarms now trigger when cameras are disabled with brute force or + bullets. + Xhuis: + - rscadd: Nanotrasen scientists have determined that a delaminating supermatter + shard combining with a gravitational singularity is an extremely bad idea. They + advise keeping the two as far apart as possible. + phil235: + - rscdel: Nerfed the xray gun. Its range is now 15 tiles. +2015-06-20: + Dorsisdwarf: + - tweak: Syndicate Bulldog Shotguns now use slug ammo instead of buckshot by default + - rscadd: Nuke Ops can now buy team grab-bags of bulldog ammo at a discount. + Ikarrus: + - rscadd: Wearing your gang's outfit now increases influence and shortens takeover + time faster. + - rscadd: Added several more options for gang outfits + - rscadd: Pinpointers will now point at active dominators. + - tweak: Gang outfits are now slightly armored + - tweak: Gang tags are now named 'graffiti' to make them harder to detect + - tweak: Initial takeover timer is now capped at 5 minutes (50% control) + - tweak: 'Server Operators: The default Delta Alert texts have changed. Please check + if your game_options.txt is up to date.' + - rscdel: Loyalty implants now treat gangs as it treats cultists. Implants can no + longer deconvert gangsters, but it can still prevent recruitments. + - tweak: Replaced tommy guns with 9mm 2-burst 32 mag uzis that costs 40 influence. + Unlike tommy guns gangs will be able to purchase ammo for uzis. + Jordie0608: + - tweak: 'For Admins: Jump-to-Mob (JMP) notification command replaced with Follow + (FLW).' + - rscadd: Message and Follow links added to many notifications. + - rscadd: New buttons to toggle nuke and set security level. + - spellcheck: Flamethrowers are logged in attack_log. + Thunder12345: + - rscadd: Combat shotguns are now semi automatic, and will be pumped automatically + after firing. + - tweak: Combat shotgun capacity has been reduced to six shells. + Xhuis: + - rscadd: You will now trip over securitrons if you run over them whilst they are + chasing a target. + - rscadd: An admin-spawnable drone dispenser has been added that will automatically + create drone shells when supplied with materials. + - rscadd: Airlock charges are available to traitors and will cause a lethal explosion + on the next person to open the door. + - rscadd: Nuclear operatives can now buy drum magazines for their Bulldog shotguns + filled with lethal poison-filled darts. + - rscadd: When a malfunctioning AI declares Delta, all blue tiles in its core will + begin flashing red. + - rscadd: Back-worn cloaks have been added for all heads except the HoP. LARPers + rejoice! + - rscadd: More suicide messages have been added for a few items. +2015-06-21: + GunHog: + - tweak: The Hostile Lockdown ability for Malfunctioning AIs has been nerfed. It + now costs 30 CPU, is much more obvious, and automatically resets in 90 seconds. + - tweak: Buffed the Upgrade Turrets Malfunction ability. Turrets will now fire heavy + lasers instead of simply shooting faster. + - rscadd: Nanotrasen has released an Artificial Intelligence firmware upgrade under + the ID 41ST0L3MYB1K3. It contains drivers for interacting with all variants + of exosuit technology, from the Ripley APLU design to even experimental Phazon + units. Simply upload your AI to the exosuit's internal computer via the InteliCard + device. Per safety regulations, the exosuit must have maintenance protocols + enabled in order to remove an AI from it. + - rscadd: Malfunctioning AIs may wirelessly steal mechs via a new power, Mech Domination. + For 30 CPU, a Malf AI may permanently upload itself to a mech, ejecting any + pilots. Malf AIs will still lose if they leave the Z-level, and the Malf will + be gibbed if the mech is destroyed - they cannot be carded out of the mech or + shunt to an APC. + Iamgoofball: + - rscdel: Blobs can no longer have Morphine as their chemical. + duncathan: + - tweak: Heat exchangers now update their color to match that of the pipe connected + to them. + - tweak: Heat exchangers are on longer dense. +2015-06-22: + Iamgoofball: + - rscdel: Removed failure chance and delay when emagging an APC. + KorPhaeron: + - tweak: Rebalanced armor to be less effective, reducing the melee, bullet and/or + laser damage reduction of all armor suits. + LaharlMontogmmery: + - rscadd: You can now click and drag a storage container to empty it's contents + into another container, disposal bin or floor tile. + Xhuis: + - experiment: Revenants have received a considerable overhaul. + - rscadd: Revenants will no longer share spawn points with space carp and will spawn + in locations like the morgue and prisoner transfer center. + - rscadd: Revenants can no longer cross tiles covered in holy water. + - rscadd: Revenants have a new ability called Defile for 30E. It will cause robots + to malfunction, holy water over tiles to evaporate, and a few other effects. + - rscadd: Upon death, revenants will appear and play a sound before rapidly fading + away and leaving behind glimmering residue as evidence of their demise. + - rscadd: This residue lingers with the essence of the revenant. If left unattended, + it may reform into a new revenant. Simply scattering it is enough to stop this, + but it also has high research levels. + - rscadd: Revenants now have fluff objectives as well as a set essence goal. + - tweak: Revenanants will be revealed for longer when using abilities and also receive + feedback on this revealing. + - tweak: Revenants can now only spawn via random event with a specific amount of + dead mobs on the station. The default for this is 10. + - bugfix: Revenants can no longer use abilities from inside walls. + - rscdel: Directly lethal abilities have been removed from revenants. In addition, + they can no longer harvest unconscious people, only the dead. +2015-06-23: + Fayrik: + - rscadd: NanoUI is now Telekenesis aware, but due to other constraints, NanoUI + interfaces are read only at a distance. + - tweak: Refactored all NanoUI interfaces to use a more universal proc. + - tweak: Adjusted the refresh time of the NanoUI SubSystem. All interfaces will + update less, but register mouse clicks faster. + - bugfix: Removed automatic updates on atmospheric pumps, canisters and tanks, making + them respond to button clicks much faster. + - bugfix: Atmos alarm reset buttons work now. Probably. + Iamgoofball: + - rscadd: Adds a progress bar when performing actions. + Ikarrus: + - rscadd: New gang names with tags created by Joan + - rscadd: C4 explosive can be purchased by gangs for 10 influence. + - tweak: Recruitment pen cost increased to 50. + - rscadd: Lieutenants recieve one free recruitment pen. + - tweak: Recruitment pens are now stealthy and no longer give a tiny prick message. + - tweak: Increased chance of deconversion with head trauma + - tweak: Recalling the shuttle now takes about a minute to work, during which you + won't be able to use your gangtool. + - rscadd: Pinpointers no longer point at dominators. Instead, dominators will beep + while active. + - rscadd: Added puffer jackets and vests. + - tweak: Increased gang outfit armor. It is moderately resistant to bullets now. + - rscdel: Removed bulletproof vests from gangtool menu. + Jordie0608: + - rscadd: Admins can now flag ckeys to be alerted when they connect to the server. + MrStonedOne: + - rscadd: Admins can now reject poor adminhelps. This will tell the player how to + construct a useful adminhelp and give them back their adminhelp verb + RemieRichards: + - tweak: Cumulative armour damage resistance is now capped at 90%, you will now + always take at bare minimum, 10% of the incoming damage. + - rscadd: Added a system for Armour Penetration to items, it works by temporarily + (It does NOT damage the armour or anything) reducing the armour values by the + AP value during the attack instance. + - rscadd: 'The formula for AP is Armour-ArmourPenetration = AdjustedArmour and AdjustedArmour + is used for all the remaining calculations instead of Armour (Eg: 80 Melee - + 15 AP = 65 Melee).' + - rscadd: The Ninja's Energy Katana has 15 AP, Xenomorphs have an inbuilt AP of + 10. + - tweak: You can now unwrench pipes who's internal pressures are greater than that + of their environment... + - rscadd: However it will throw you away from the pipe at extreme speed! (You are + warned beforehand if the pipe will do this, allowing you to cancel) + Vekter: + - bugfix: Finally fixed immovable rods! They will now properly bisect the station + (and crit anyone unlucky enough to be in their path). + - tweak: Increased Meteor activity detected in the vicinity of the station. Be advised + that many storms may be more violent than they once were. + - rscadd: Gravitational anomalies will now throw items at mobs in their vicinity. + Take care while scanning them. + - rscadd: Flux anomalies explode much more violently now. Get there and destroy + them, or risk losing half a department. + xxalpha: + - rscadd: 'Added a new Reviver implant: now it revives you from unconsciousness + rather than death.' + - rscadd: Added cybernetic implants and a cybernetic implants bundle to the Nuke + Ops uplink. + - bugfix: Fixed Nutriment pump implant printing. + - tweak: Health Analyzers now have the ability to detect cybernetic implants. + - tweak: X-Ray implants are now much harder to unlock. +2015-06-24: + Ikarrus: + - rscadd: Request Console message sent to major departments will now be broadcasted + on that department's radio. + - rscadd: Request Consoles can be used to quicly declare a security, medical, or + engineering emergency. +2015-06-25: + Iamgoofball: + - rscadd: Changes up how Explosive Implants work. + - rscadd: They have become Microbomb Implants. They cost 1 TC each. Each implant + you inject increases the size of the explosion. You gib on usage, regardless + of explosion size. + - rscadd: A Macrobomb implant was added for 20 TC. It is the equivalent of injecting + 20 microbombs. + - rscadd: Nuke Ops start with microbomb implants again. +2015-06-26: + Ikarrus: + - imageadd: Added a couple of new gang tag resprites by Joan. + Kor: + - tweak: Summon Guns has returned to its former glory. The spell will once again + create antagonists, now with the objective to steal as many guns as possible. + - tweak: Summon Guns once again costs a spell point, rather than granting one. + phil235: + - tweak: Buffs traitor stimpack (and adrenalin implant) to be more efficient against + stuns/knockdowns. + pudl: + - rscadd: You can now play games of mastermind to unlock abandoned crates found + throughout space. +2015-06-27: + Ikarrus: + - rscadd: Some objects can be burned now. + - rscadd: Bombs will shred your clothes, with respect to their layering and armor + values. Exterior clothing will shield clothing underneath. Storage items will + drop their contents when bombed this way. + Laharl Montogmmery: + - rscadd: 'Storage Content Transfer : Bluespace Boogaloo! You can now transfer the + content of the BoH/BRPED into tiles/bins/bags out of your reach. Range is 7 + tiles.' + MrStonedOne: + - tweak: Admins will now receive a notification when one of them starts to reply + to an adminhelp to cut down on multiple responses to adminhelps and let admins + know when an adminhelp isn't getting replied to. + - rscadd: The keyword finder in admin helps (adds a (?) link next to player names + in the text of adminhelps) has been added for all player to admin pms, as well + as admin say. + NullQuery: + - wip: Introduces html_interface, a module to streamline the management of browser + windows. + - rscadd: Adds playing cards that utilize a new HTML window management system. + Vekter: + - rscadd: Added a new military jacket to the Autodrobe and ClothesMate. +2015-06-28: + Ikarrus: + - rscadd: Gang Lieutenants can buy gang tools now, but at a higher cost than the + original boss + - rscadd: Gang leaders can register additional gangtools to themselves for use as + spares. + - tweak: Number of maximum lieutenants lowered to 2 + - tweak: Pistol cost increased to 25 influence + - tweak: Uzi cost increased to 50 influence + - tweak: Uzi Ammo decreased to 20 influence + - rscadd: Overcoats added to items the biogenerator can produce. + - rscdel: Micro and Macro bomb implants are now restricted to the Nuclear game mode. + phil235: + - tweak: Smoke (and foam) no longer distribute more reagents than they have. The + amount of clouds in a smoke now depends on the amount of smoke created. Acid + no longer melts items on a mob at low volume, and the chances to melt them increases + with the amount applied on the mob. Sprays can now contain acid again. +2015-06-29: + Ikarrus: + - rscadd: Clothing has been separated out of equipment lockers into wardrobes to + reduce clutter. + Incoming5643: + - rscadd: The secrets of the rainbow slimes have finally been revealed. To attain + this rare blob you must breed a slime with a 100% mutation chance! + - rscadd: Rainbow slime cores will generate a randomly colored slime when injected + with plasma. It's a good plan B if the slimes aren't cooperating in terms of + colors. You can get any color slime this way, pray to the RNG! + Xhuis: + - rscadd: The Sleeping Carp clan has made its presence known on Space Station 13. + Some gangs will name themselves after this group and practice martial arts rather + than using traditional gang weaponry. These shadowboxers are not to be taken + lightly. + oranges: + - tweak: Thanks to a breakthrough in directed vector thrusting, all nanotrasen brand + jetpacks have been greatly improved in speed and handling diff --git a/html/changelogs/archive/2015-07.yml b/html/changelogs/archive/2015-07.yml new file mode 100644 index 0000000000..55e0ac120d --- /dev/null +++ b/html/changelogs/archive/2015-07.yml @@ -0,0 +1,418 @@ +2015-07-01: + Ikarrus: + - rscadd: Multiple gang leaders are spawned at round start, the number which depends + on server population + - rscdel: Gangsters can no longer be promoted mid-game. + - rscadd: Security can once again deconvert gangsters with loyalty implants + - rscadd: Added an Implant Breaker item to the gangtool as a purchasable item for + 10 influence each
    * They are a one-use item that destroys all implants in + the target, including loyalty implants
    * They will also attempt to recruit + the target before destroying itself + - rscdel: Implanters no longer work if the target is wearing headgear. Remove them + first. + NullQuery: + - tweak: The crew monitoring computer, AI crew monitoring popup and the handheld + crew monitor now update automatically. + - tweak: 'Crew monitoring: The health information has been turned into a health + indicator. It goes from green to red. Hovering over the icon shows detailed + information (if available).' + - tweak: 'Crew monitoring: The location coordinates have been hidden. You can see + them by hovering over the ''Location'' column.' + - rscadd: 'Crew monitoring: A minimap has been added so you can easily see where + people are.' + - tweak: 'Crew monitoring: Players who are not in range of a camera are not shown + on the minimap.' + - tweak: 'Crew monitoring: AI players can quickly move to other locations or track + players by clicking the minimap or items in the table.' + - tweak: 'Crew monitoring: For AI players, health information always shows a white + indicator instead of green-to-red. This is a deliberate limitation to prevent + the AI from becoming too omnipresent.' + phil235: + - tweak: Space drug overdose no longer cause brute/brain damage but you hallucinate + more. Space Drug Blob now makes you hallucinate even if you don't overdose on + its space drug. + xxalpha: + - rscadd: 'Added a new traitor objective: steal the station''s self-destruct nuke + plutonium core.' +2015-07-02: + Ikarrus: + - rscadd: Throwing reagent containers such as drinks or beakers may spill their + contents onto whatever they hit + - rscadd: Slipping while carrying items in your hand may cause ~accidents~ + - tweak: Mounted and portable flashers can now only be burned out from overuse, + similar to flashes. + oranges: + - tweak: Thanks to department budget cuts we've had to remove the security cameras + built into officer helmets, Nanotrasen apologies for this inconvenience. +2015-07-03: + Ikarrus: + - experiment: Added support for up to six gangs at a time. Admins may add additional + gangs to any round. + - experiment: Gang mode now has a chance to start with a third gang. + - rscadd: Promotion of lieutenants have been re-added + - rscadd: Every lieutenant promoted will lengthen the gang's recruitment cooldowns + by one minute. + - rscdel: Only gang bosses will be able to recall the shuttle from their gangtool. + - rscadd: A recruitment pen that has not been used for a while will accumilate charges, + so you are no longer punished for waiting to convert people. + - rscadd: Gangs are now fully functional outside of gang mode. + Ricotez: + - rscadd: 'Added two categories of mutant bodyparts for humans with the same system + that lizards use: ears and tails. Right now only admins can edit these.' + - rscadd: Updated the system that checks for which jobs your character qualifies + to be species-dependant. At this moment you won't notice any differences, but + in the future coders can use this to be more specific about which jobs a species + is allowed in under which circumstances. + - imageadd: 'Added one option to both categories, taken from the kitty ears: a cat + tail and cat ears.' + - rscadd: 'Added a new button to the VV menu drop-down list for admins: Toggle Purrbation. + Putting a human on purrbation will give them cat ears and a cat tail, and send + them the message ''You suddenly feel valid.'' Using the button a second time + removes the effects.' + - wip: 'Adding categories for tattoos and scars is in the works. (Read: I need sprites!)' + oranges: + - tweak: Engineers in nanotrasen's safety equipment department announced the release + of a new and improved version of the X25 taser trigger, previous triggers, which + suffered from a long line of misfire problems were recalled enmasse. Nanotrasen + refused to comment on rumours that the previous trigger design was the work + of a saboteur. +2015-07-04: + Gun Hog: + - tweak: The Ore Redemption Machine now allows users to release minerals without + having to insert an ID first. + Ikarrus: + - bugfix: Fixed items that logically shouldn't spill, spilling their contents when + thrown + - bugfix: Fixed Bartender's non-spilling powers + - bugfix: Fixed thrown beakers not applying their contents onto floors + - bugfix: Fixed unable to transfer reagents between beakers you are holding + - bugfix: Fixed bombs shredding clothes that should have been protected by covering + clothes + - bugfix: Fixed gang mode. + MMMiracles: + - rscadd: Added patriotic underwear apparel due to the most god damn american holiday + being just around the corner. + - rscadd: Also adds some other stuff for those inferior countires too, I guess. +2015-07-05: + AlexanderUlanH & Xhuis: + - rscadd: Shadowling Ascendants have a new ability to send messages to the world. + - bugfix: Glare now properly silences targets. + - bugfix: Veil now turns off held lights. + - tweak: Drain Thralls replaced with Drain Life, which targets all nearby humans. + - rscadd: Spatial Relocation replaced with Black Recuperation which lets you revive + a dead thrall every five minutes. + - rscdel: Removed Vortex. + - tweak: Shadowlings can now only enthrall five people before being forced to hatch; + Hatched shadowlings can continue to enthrall however non-hatched ones can't + pass the global limit. + - tweak: Enthralling sends a message to all nearby humans. + - tweak: Removed cooldown on Glacial Freeze. + Ikarrus: + - tweak: Reactive armor may now teleport user to space tiles. Be careful using it + around space. + Razharas: + - tweak: Firing pins can now be removed by tablecrafting a gun with a plasmacutter, + screwdriver and wirecutters. + RemieRichards: + - imageadd: Melee attacks with weapons now display and animation of the weapon over + the target. + - rscadd: Tablecrafting window now shows all recipies and has been split into categorized + tabs. + - rscdel: 30 item limit removed. + Sabbat: + - rscadd: Updated the cult armor rune to let you get additional equipment or abilities + based on what you're wearing or holding. Some nerfed versions of wizard spells + can be used by the cult in exchange for unique clothing, these spells require + the cult robes or armor in order to use. No armor choices are mandatory, you + will always have the option of the default choice. + - rscadd: Zealot - Default armor rune. If none of the required clothing is worn + this will be chosen automatically. Is the same as ever. + - rscadd: Summoner - If you are wearing the wizard robe and hat when using the armor + rune this choice will be available. User will receive magus robes and hat and + nerfed versions of the summon shard and summon shell spells. + - rscadd: Traveler - Available to people wearing EVA suit and helmet. Replaces the + EVA suit and helmet with the cult space suit and space helmet. Gives you a sword. + - rscadd: Marauder - Available to people wearing the captain's space suit and helmet. + Same as Traveler except user is given a spell of summon creature (two creatures). + They can and will attack the user. + - rscadd: Trickster - Available if wearing the RD's reactive teleport armor. Gives + you magus robes, a wand of doors, and a nerfed version of Blink. + - rscadd: Physician - Available if wearing the CMO's labcoat. Gives you a wand of + life. + TheVekter: + - rscadd: Ian now has a dog-bed in the HoP's office. + nukeop: + - rscadd: Uplinks now have a syndicate surgery bag containing surgery tools, a muzzle, + a straightjacket and a syndicate MMI. + - rscadd: Syndicate MMIs can only be placed in cyborgs to create an unlinked cyborg + with syndicate laws. +2015-07-06: + Ikarrus: + - tweak: Increased Uzi SMG cost to 60 influence. + - tweak: Increased Uzi ammo cost to 40 influence. + - tweak: Domination attempt limit is reduced to 1 per gang while the shuttle is + docked with the station. + - tweak: Gang bosses can promote and recall the shuttle using spare gangtools + - bugfix: Fixed Gang bosses getting deconverted with head trauma + - rscadd: Lizard characters can now get random names unique from humans. +2015-07-07: + Ikarrus: + - bugfix: Fixed bug where gang messages would occasionally fail to send. + - bugfix: Fixed bug that prevented implant breakers from recruiting security. + - tweak: Implanters are now only blocked by helmets with THICKMATERIAL + - rscdel: Light severity explosions no longer shred clothes. + MMMiracles: + - rscadd: Adds a new crate to cargo in the security section, for when desperate + times call for desperate measures. + NullQuery: + - bugfix: Crew monitoring computers now sort by department and rank again. + - tweak: 'Crew monitoring computer: Hovering over a dot on the minimap will now + jump to the appropriate entry in the table.' + - bugfix: sNPCs were given ID cards with blank assignments. +2015-07-09: + AlexanderUlanH: + - rscadd: Riot Shotguns now spawn loaded with rubber pellet shells that deal high + stamina damage. + kingofkosmos: + - tweak: Both beakers and drinking glasses can now be be drunk from, fed to mobs + and splashed on mobs, turfs and most objects with harm intent. + nukeop: + - tweak: RCDs have a larger storage and can be loaded with glass, metal and plasteel. + - rscadd: Grilles and Windows can be made with an RCD. + - rscadd: Engi-Vend machine now has three RCDs. + - rscdel: Removed RCD as a steal objective. +2015-07-10: + Ikarrus: + - rscadd: 'New Changeling Ability: False Armblade Sting. It creates an undroppable + armblade on the target temporarily. It will appear exactly like a real one, + except you can''t do anything with it.' + - tweak: Transform stings are no longer stealthy. +2015-07-11: + Dorsidwarf: + - tweak: Due to a new Syndicate budget, uplink implants are now only 14 TC. + - tweak: In order to facilitate inter-agent communication, Syndicate Encryption + Keys have been reduced to 2TC. They retain the ability to intercept all channels + and speak on a private frequency. + Ikarrus: + - tweak: Robotic augmentations have been made a bit more difficult to maintain. +2015-07-13: + Ikarrus: + - imageadd: Loyalty Implant HUD Icon has been updated. + duncathan: + - tweak: Greatly shortened the time it takes to lay pipes with the RPD and to unwrench + pipes in general. + - rscadd: Added Optical T-Ray scanners to R&D and Atmospheric Technician closets. + Optical T-Ray Scanners function identically to a handheld scanner. +2015-07-14: + AnturK: + - rscadd: New species of mimic was spotted in the wilderness of space. Watch out! + Jordie0608: + - rscadd: Added a Local Narrate verb for admins. +2015-07-17: + Ikarrus: + - bugfix: Virology is no longer all-access. + - rscadd: Changelings now have the ability to swap forms with another being. + - tweak: Halved Domination Time. + - tweak: Reinforced windows and windoors are a bit more resistant to fires and blasts. + MrStonedOne: + - tweak: 'Scrubbers now use power: 10w + 10w for every gas its configured to filter. + (60w for siphon)' + - rscadd: Scrubbers can now be configured to operate on a 3x3 range via the air + alarm at a high cost (ranging from 100w to 1000w depending on how many tiles + are near it that aren't blocked and how much power it's using normally) + - tweak: Huge portable scrubbers (like in toxins storage) now use a 3x3 range rather + then a higher volume rate + - bugfix: Fixed issue with atmos not allowing low levels of plasma to spread + - bugfix: Fixed issue with atmos not adding or removing plasma overlays in some + cases + - tweak: Panic siphon now uses a 3x3 area range rather then increasing the scrubbers + intake rate by 8x + - tweak: Replace air uses 3x3 range for the first stage + - rscadd: 'Air alarms now have 3 new environmental modes:' + - rscadd: Siphon - Panic siphon without the panic, operates on a 1 tile range + - rscadd: Contaminated - Activates all gas filters and 3x3 scrubbing mode + - rscadd: Refill Air - 3 times the normal vent output +2015-07-18: + AlexanderUlanH: + - tweak: Reduced stun duration of tabling to be closer to other stuns. + Iamgoofball: + - tweak: The Bioterror Chemical Sprayer is now filled with a more deadly mix of + chemicals. + RemieRichards: + - tweak: Changelings now regenerate chemicals and geneticdamage while dead, but + only up to specific caps (50% of their max chem storage, and 50 geneticdamage) + - tweak: Fakedeath's length has been reduced from 80s dead (1 minute 20) to 40s + dead + - rscadd: Changelings now get to see the last 8 messages the person they absorbed + said, to allow them to better impersonate their victim's speech patterns + Steelpoint: + - tweak: Reduced weight of Sechailer, it now fits in boxes. + phil: + - tweak: Smoke and foam touch reactions gets buffed. + - rscadd: Reagent dispensers (watertank, fueltank) tells you how much reagents they + have left when examined. + - tweak: Liquid dark matter blob spore smoke now cannot throw you. The effects of + sorium, blob sorium, liquid dark matter and blob liquid dark matter are now + scaled by their volume. Sorium/LDM blob's touch now throws the mobs who are + close but simply moves the mobs that are further away. +2015-07-19: + Gun Hog: + - rscadd: Nanotrasen advancements in cyborg technology now allow for integrated + headlamps! As such, the flashlight package normally used as a module is now + seamlessly merged with their systems! + Ikarrus: + - rscadd: Asimov's subject of "human beings" can now be modified by uploaders. + - rscadd: Eaxmining AI modules while adjacent to them will show you what laws it + will upload. + MMMiracles: + - soundadd: Adds a TWANG sound effect when hitting things with a guitar. +2015-07-20: + AnturK: + - tweak: Lightning Bolt now always bounces 5 times and deals 15 to 50 burn damage + to each target depending on the chargeup + KorPaheron: + - rscadd: Added the Multiverse Sword, a new wizard artifact that can summon clones + of yourself from other universes, allowing for dangerous amounts of recursion. + phil235: + - tweak: Mechs no longer use object verbs and the exosuit interface tab. They now + use action buttons. Mechs now have a cycle equipment action button to change + weapon faster than by using the view stats window. Mechs get two special alerts + when their battery or health is low. Mechs now properly consume energy when + moving and having their lights on. Using a mech tool that takes time to act + now shows a progress bar (e.g. mech drill). + - rscadd: Mechs now have a cycle equipment action button to change weapon faster + than by using the view stats window. + - rscadd: Mechs get two special alerts when their battery or health is low. + - tweak: Mechs now properly consume energy when moving and having their lights on. + - rscadd: Using a mech tool that takes time to act now shows a progress bar (e.g. + mech drill). +2015-07-21: + Fayrik: + - tweak: Syndicate Donksoft gear now costs less. + Xhuis: + - rscadd: Firelocks may now be constructed and deconstructed with standard tools. + Circuit boards can be produced at a standard autolathe. + phil235: + - tweak: Thrown things no longer bounces off walls, unless they're in no gravity. + Heavy items and mobs thrown can push the mobs and non anchored objects they + land on. Throwing a mob onto a mob in no gravity will push each one in opposite + direction. Thrown mobs landing on wall, or dense object or mob gets stunned + and a bit injured. The damage when mob hit a wall is nerfed. +2015-07-23: + NullQuery: + - tweak: 'Crew monitoring: The minimap now supports scaling. You can zoom in and + out using the buttons. Hovering over an entry in the table centers the minimap + on that part of the screen.' + - tweak: 'Crew monitoring: If the window is wide enough the health indicator will + expand to show full health data (if available).' + - tweak: 'Crew monitoring: Clicking on the area name will now copy the coordinates + to your clipboard.' + - tweak: 'Crew monitoring: The AI can view health information again, but there is + a 5 second delay between updates for everyone watching.' + freerealestate: + - rscadd: Added resist hotkeys for borgs and humans. With hotkeys mode, use CTRL+C + or C as a human and CTRL+C, C or END as a borg. With hotkeys mode off, use CTRL+C + as a human and END as a borg. + xxalpha: + - bugfix: Changeling augmented eyesight night vision is now working. +2015-07-24: + Incoming5643: + - rscadd: The spells disintegrate and flesh to stone have had their mechanics changed. + Using these spells will spawn a special touch weapon in a free hand (your dominant + hand if possible) that can then be used to inflict the spell on the target of + your choice. Having the touch weapon out is obvious, this is not a stealth based + change. Clicking the spell while the hand is out will let you return the charge + without using it. + - rscdel: The spell won't begin to recharge until the hand attack is either used + or returned. Additionally these changes mean you can no longer use these spells + while stunned or handcuffed. As a suggestion remember that the mutate spell + allows you to break out of cuffs very easily, and warping abilities will keep + you from getting cuffed to begin with! +2015-07-25: + Dorsisdwarf: + - tweak: Due to a fire sale at Syndicate HQ, many of the more interesting traitor + gadgets have been cut in price dramatically. Please take this opportunity to + make full use, as we cannot guarantee that the sale will last! + bgobandit: + - bugfix: Under pressure from the Animal Rights Consortium, Nanotrasen has improved + conditions at its cat and dog breeding facilities. Cats and pugs are now much + more responsive to their owners. + duncathan: + - tweak: Restores RPD delay on disposals machines. + xxalpha: + - tweak: Agent IDs are now rewrittable. +2015-07-26: + Phil235: + - rscadd: Sechailers will now break when used too often. + - imageadd: Mechs now have new action button sprites. + Steelpoint: + - rscadd: Security Officers now spawn with a security breathmask in their internals + box. + - imageadd: Abductor's batons now changes color with modes. + - imageadd: Unique sprites for Abductor hand cuffs and paper. + goosefraba19: + - imageadd: Updated the Power Monitoring Console with better alignment and colorized + readouts. +2015-07-27: + Bgobandit: + - bugfix: Burgers can now be made from corgi meat again. + Ikarrus: + - rscadd: Added shutters to the armory to allow quick access when needed. + - bugfix: Security can now use the Brig external airlocks. + - rscadd: Added a join queue when the server has exceeded the population cap. + - tweak: Decreased the cost of Body Swap and removed it's genetic damage. + kingofkosmos: + - rscadd: Added a link to re-enter corpse to alert when your body is placed in a + cloning scanner. +2015-07-28: + Anonus: + - imageadd: New gang tags for Omni and Prima gangs. + Chiefwaffles: + - rscadd: After realizing how often AIs tend to 'disappear', Central Command has + authorized the shipment of the Automated Announcement System to take over the + AI's responsibility of announcing new arrivals. + - rscadd: In addition, users are able to configure the messages to their liking. + Early testing has shown that this feature may be vulnerable to malicious external + elements! + - rscadd: The station's R&D software has been updated so it can now succesfully + create its own prototype AAS board once the prerequisite levels have been met. + Dorsisdwarf: + - tweak: Increased the cost of Bioterror darts to 6TC. + Incoming5643: + - experiment: Double Agents no longer know they're Double Agents and not just standard + Traitors. + xxalpha: + - rscdel: Removed Anti-Drop and Nutriment Pump implants from Nuclear Operative's + uplink. +2015-07-29: + AnturK: + - rscadd: Aliens can now mine through asteroid rock. + GunHog: + - tweak: Cyborg headlamps have a short cooldown before reactivation when forcibly + deactivated. + - bugfix: Shadowling's Veil now shuts down headlamps for the ability's entire duration. + Kor: + - rscadd: Eating the heart of a Slaughter Demon will grant you dark powers. + freerealestate: + - bugfix: Fixed bug where copying with ctrl+C didn't work due to it being assigned + to resist. + - rscadd: Changed resist to B (hotkeys mode) and ctrl+B (either mode) instead. + - rscdel: Removed End resist from cyborgs. +2015-07-30: + Gun Hog: + - tweak: The Reactivate Camera power for Malfunctining AIs now costs 10 CPU, and + works on the entire camera network, up to 30 cameras fixed. + - tweak: The Upgrade Cameras power now costs 35 CPU, upgrades all cameras in the + network to have EMP proofing, X-ray, and gives the AI night-vision. + Ikarrus: + - rscadd: Door Access buttons can now be emagged to remove access restrictions. + LordPidey: + - rscadd: Added a new medication, Miner's Salve. It heals brute/burn damage over + time, and has the side effect of making the patient think their wounds are fully + healed. It is mixed with water+iron+oil, or grind a twinkie, a sheet of metal, + and a sheet of plasma. + - rscadd: Added a grinder to the mining station. + Midaychi: + - rscadd: Random loot has been added to the derelict as salvage for drones. + Scones: + - rscadd: Adds a Rice Hat to the biogenerator. diff --git a/html/changelogs/archive/2015-08.yml b/html/changelogs/archive/2015-08.yml new file mode 100644 index 0000000000..b82da17768 --- /dev/null +++ b/html/changelogs/archive/2015-08.yml @@ -0,0 +1,229 @@ +2015-08-02: + Incoming5643: + - rscadd: Syndicate toolboxes now come with never before seen red insulated gloves. + Steelpoint: + - bugfix: Fixed multiple mapping errors for Boxstation and the mining base. + - rscadd: A circuit imprinter and exosuit fabrication board have been added to tech + storage. + SvartaSvansen: + - rscadd: Our lizard engineers have worked hard and managed to improve Centcom airlocks + so they no longer disintegrate when the electronics are removed! + - tweak: Put a safety net in place so future airlocks without assemblies produce + the default assembly instead of disintegrating. +2015-08-04: + Kor: + - rscadd: Soulstones will now attempt to pull ghosts from beyond if the targeted + corpse has no soul. + Summoner99: + - rscadd: Added the *roar emote back to Alien Larva + - bugfix: Fixed aliens not being able to do the *hiss and *screech emotes + - tweak: 'Changed how the plural emote system works and now some emotes have plural + versions, example is: *hiss and *hisses.' +2015-08-05: + CoreOverload: + - rscadd: Implants, implant cases and implanters got RnD levels and can be DA'ed + for science. + - rscadd: Surgically removed implant can be placed into an implant case. Remove + implant with empty implant case in inactive hand. + - rscadd: Surgical steps now got progress bars. + - rscadd: You can cancel a surgery by using drape on operable body part again. This + works only before you perform surgery's first step. + - rscadd: Operating computer shows next step for surgeries. No more alt-tabbing + to view next step on wiki while operating. + - tweak: You cannot start two surgeries on one body part at once. You can start + two multiloc surgeries (i.e. two augumentations) on diffirent body parts at + once. + - tweak: Monkey <-> Human transformations now keep your internal organs, cyberimplants + and xeno embryos included. + Ikarrus: + - rscdel: Head beatings no longer deconvert gangsters. + LordPidey: + - rscadd: 'Added a new chemical. Spray tan. It is made by mixing orange juice with + oil or corn oil. Warning: overexposure may result in orange douchebaggery.' + Xhuis: + - rscadd: Shadowling thralls can now be deconverted via surgery or borging. + - rscadd: Thralls can be revealed by examining them. They can hide this by wearing + a mask. + - rscadd: Thralls have a few minor abilities they can use in addition to night vision. + - rscadd: Hatch-exclusive abilities can no longer be used if you are not the shadowling + mutant race. + - rscadd: Ascendants are now immune to bombs and singularities. Honk. + - rscadd: A Centcom report has been added for shadowlings. + - tweak: Ascending no longer kills all shadowling thralls. This allows antagonists + who were enthralled to succeed along with the ascendants. + - tweak: Annihilate now has different sound and a shorter delay before the target + explodes. In addition, it now works on all mobs, instead of just humans. + - bugfix: Glacial Blast now properly has no cooldown if used while phase shifting. + - bugfix: Fixes a runtime if a target with no mind is enthralled. + bgobandit: + - rscadd: Nanotrasen scientists have achieved the tremendous breakthrough of injecting + gold slime extracts with water. Pets ensued. +2015-08-06: + AnturK: + - rscadd: Adds the voodoo doll as a mining treasure, link it with a victim with + an item previously held by them. + - rscadd: Once linked the voodoo doll can be used to injure, confuse and control + the victim. + Core0verlad: + - tweak: Items can now be removed from storage containers inside storage containers. + - imageadd: Beds and bedsheets have new sprites. + - rscdel: MMIs are no longer ID locked. + KorPhaeron: + - tweak: Slaughter Demon's have had their health reduced to 200 and their speed + reduced but they get a speed boost when exiting blood. + MrPerson: + - rscadd: Items stacks now automatically merge unless thrown when moved onto the + same tile. +2015-08-07: + KorPhaeron: + - rscadd: Added a new Guardian Mob that can be summoned to manifest inside a mob. + - rscadd: Guardians can communicate with their host and materialize themselves to + protect their host with magic powers. + - rscadd: Guardians are invincible but cannot live without or too far from their + host, they also relay injuries they suffer to the host. + Phil235: + - bugfix: Fixed being able to run into your own bullet. + RemieRichards: + - rscadd: You no longer need to click on an item in a storage container to remove + it, clicking anywhere around the item works. + bustygoku: + - rscdel: Removed the chance for a disease to make you a carrier on transfer. + phil235: + - tweak: The plasma cutter's fire rate is now a bit lower but its projectile can + pierce multiple asteroid walls and its range isn't lowered in pressurized environment + anymore. +2015-08-09: + RemieRichards: + - rscadd: 'Nanotrasen Mandatory FunCo Subsidiary: CoderbusGames, would like to announce + an update to Orion Trail!' + - rscadd: 'Spaceports: Buy/Sell Crew, Trade Fuel for Food, Trade Food for Fuel, + Buy Spare Electronics, Engine Parts and Hull Plates, or maybe you think you''re + tough enough to attack the spaceport?' + - rscadd: 'Changelings: Changelings can now sneak into your crew, Changelings eat + double the standard food ration and have a chance to Ambush the rest of the + crew!' + - rscadd: 'Kill Crewmembers: Do you suspect changelings? or dont feel you have enough + food rations? Just shoot somebody in the head, at any time!' +2015-08-12: + CosmicScientist: + - rscadd: Added Space Carp costume to the code, get it from an autodrobe near you. + - rscadd: Added Ian costume to the code, take his place under the HoP's hand, get + it from an autodrobe or corgi hide, keep it away from washing machines or it'll + meat its end as clothing. + - rscadd: Added Space Carp spacesuit to the code, I know what I'm praying for. + bgobandit: + - rscadd: After multiple complaints from WaffleCo food activists, Nanotrasen has + added real chocolate, berry juice and blue flavouring to its ice cream products. +2015-08-13: + CoreOverload: + - rscadd: 'Added a new 8TC traitor item: subspace storage implant. It allows you + to store two box-sized items in (almost) undetectable storage. ' + - tweak: Changed the way most of the surgical operations work. See wiki for new + steps. + - tweak: You can cancel step 2+ surgeries with drapes and cautery in inactive hand. + - tweak: Defib no longer works on humans who have no heart. Changeling/thrall/cult/strange + reagent revives are still working, and this is intended. + - rscadd: You can eat all organs raw now, with exception for brains and cyberimplants. + - rscadd: Some xenos abilities are linked to their organs. Play with xenos' guts + for fun and profit! + RemieRichards: + - rscadd: Modifying a string (Text) variable with View Variables or View Variables + Mass Modify now allows you to embed variables like real byond strings, For example + the variable real_name; you could set a text var to [real_name] and it would + be replaced with the actual contents of the var, This allows for Mass fixing + of certain variables but it's also useful for badmin gimmickery +2015-08-15: + Miauw: + - rscadd: Changeling transformations have been upgraded to also include clothing + instead of just DNA. + - tweak: Patches no longer work on dead people. + - rscadd: Added 15-force edaggers that function like pens when off. + MrPerson: + - rscadd: Objects being dragged will no longer get shoved out of your grasp by space + wind. Retrieving dead bodies should be possible. + RemieRichards: + - rscadd: Added Changeling Team Objectives, these are handed out to all lings, with + the chance of a round having one being 20*number_of_lings% (3 lings = 60%) + - rscadd: 'Impersonate Department (Team Objective): As many members of a department + as can reasonably be picked are chosen for the lings to kill, replace and escape + as' + - rscadd: 'Impersonate Heads (Team Objective): 3 to 6 Heads of Staff are chosen + for the lings to kill, replace and escape as' + - tweak: If the Changelings have a Team Objective, their usual Kill, Maroon, Etc. + objectives will not pick other changelings, to discourage backstabbing in teamling + - tweak: Changeling Engorged Glands is now the default storage and regen rate, Engorged + Glands remains for an extra boost + - rscadd: Armblades can now be used to open powered doors, however it takes 10 seconds + of the changeling standing still, Their ability to instantly open unpowered + doors remains unchanged + - rscdel: Debrain objective is no longer handed out to lings, it's as good as broken + these days + - rscadd: Changelings may now purchase a togglable version of the Chameleon Skin + genetics mutation, for 2 DNA +2015-08-16: + Joan: + - rscadd: Revenants will now occasionally spawn as an event. + - tweak: Revenants gain more energy from Harvesting, and can Harvest from people + in crit. + - tweak: Revenant powers are more effective, and no longer freeze you in place, + besides Harvest. + - tweak: Slain Revenants will respawn much faster. + - bugfix: Fixed a whole bunch of revenant bugs, including one that caused the objective + to always fail. + Kor: + - rscadd: The wizard can now stop time. + MMMiracles: + - tweak: Revamps bioterror darts into a less-lethal, syringe form. Removed the coniine + and spore toxins to keep it solely for quiet take-downs. +2015-08-18: + CoreOverload: + - rscadd: Added a new low-tech eye cyberimplant in RnD - welding shield implant. + - rscadd: Implanter and empty implant case added to protolathe. + - rscadd: You can sell tech disks and maxed reliability design disks in cargo for + supply points. + - tweak: DA menu shows current research levels. + - tweak: You can print cyberimplants in updated mech fab. + Supermichael777: + - bugfix: Added an ooc hotkey for borgs = O. They simply didn't have one and it + was a consistency issue + - rscadd: Also added Ctrl+O as an any mode keycombo so you dont have to backspace + and type ooc. Added to hotkey mode to remain consistent with all other Ctrl + combos + bustygoku: + - tweak: Most backpacks now have 21 or more slots, but are still weight restricted. + What this means is that you can have a lot of tiny weight items, but only 7 + medium items just like before. + phil235: + - tweak: Janicart rider no longer slip on wet floor or bananas. Moving on a floor + tile with lube while buckled (chair, roller bed, etc) will make you fall off. +2015-08-19: + Joan: + - rscadd: Added a new revenant ability; Malfunction. It does bad stuff to machines. + - tweak: Defile and Overload Lights now briefly stun the revenant. + - tweak: You can now Harvest a target by clicking on them while next to them. + - bugfix: Harvesting no longer leaves you draining if the target is deleted mid-drain + attempt. + - rscdel: Defile no longer emags bots or disables cyborgs, Malfunction does that + now. + Kor: + - rscadd: The Ranged and Scout guardian types have been merged, and gained a new + surveillance snare ability. + SconesC: + - rscadd: Added Military Belts to traitor uplinks. + bgobandit: + - rscadd: CentComm now offers its cargo department toys, as well as detective gear + so their boss can figure out which tech wasted all the points on them. + phil235: + - rscadd: You can now partially protect yourself from blob attack effects by wearing + impermeable clothes like hardsuits, medical clothes, masks, etc. Max protection + effect is capped at 50%. + - rscdel: Splashing someone with chemicals no longer injects those chemicals in + their body. + - bugfix: Fixes splashing acid on items or floor with items not having any effect. +2015-08-28: + bgobandit: + - bugfix: 'Overheard at CentComm: ''This burn kit said salicyclic acid would heal + my burns! WHO MADE THIS SHIT?'' A muffled honking is heard in the background. + (Burn first-aid kits now contain an appropriate burn pill.)' + - rscadd: Oxandrolone, a new burn healing medication, has been added to burn first-aid + kits and to chemistry. Ingesting 25 units or more causes burn and brute damage. diff --git a/html/changelogs/archive/2015-09.yml b/html/changelogs/archive/2015-09.yml new file mode 100644 index 0000000000..57532365e3 --- /dev/null +++ b/html/changelogs/archive/2015-09.yml @@ -0,0 +1,306 @@ +2015-09-01: + Dorsidwarf: + - tweak: Changelings' Digital Camoflague ability now renders them totally invisible + to the AI + ExcessiveUseOfCobblestone: + - rscadd: Added health analyzer to the autolathe. + - tweak: Moved Cloning board to Medical Machinery section. + - tweak: Moved Telesci stuff to Teleporter section. + Fox P McCloud: + - tweak: Adds the emitter board to to the circuit imprinter for R&D. + Gun Hog: + - tweak: The Disable RCD Malfunction power is now Destroy RCDs! It costs 25 CPU + (down from 50), causes RCDs to explode, can be used multiple times, and no longer + affects cyborgs. + Kor: + - rscadd: Revheads and Gang leaders now spawn with chameleon security HUDs, for + keeping track of loyalty implanted crew. + - rscadd: Syndicate thermals now have a chameleon function as well, allowing you + to disguise the goggles to match your job. + Miauw: + - tweak: Edaggers actually work now and have been buffed to 18 brute and 2 TC. + Oisin100: + - rscadd: Nanotransen discover ancient human knowledge confirming that trees produce + Oxygen From Carbon Dioxide + - tweak: Trees now require Oxygen to live. And will die in extreme temperatures + Xhuis: + - rscadd: The arcade machines have been stocked with a xenomorph action figure that + comes with realistic sounds! + - rscadd: Darksight now has its own icon. + - rscadd: Empowered thralls have been added. While obvious, they are more powerful + and can resist dethralling while conscious. Only 5 can exist at one time. + - rscadd: Shadowlings can now change their night vision radius by using the action + button their eyes (glasses) now provide. + - tweak: Torches are dimmer, being as bright as flashlights, and no longer fit on + belts. + - tweak: Black Recuperation now has a 1 minute cooldown, down from 5. It can also + be used to empower living thralls. + - tweak: Guise can now be used outside of darkness and makes the user more invisible + than before. + - bugfix: Enthrall now functions properly when a shadowling is not hatched, allowing + them to enthrall up to 5 people before hatching. + xxalpha: + - tweak: Blood crawling is now a spell. + - rscadd: Engineering cyborgs now have a constant magpulse. + - tweak: Changed foam spreading to be like gas spreading. +2015-09-05: + Shadowlight213: + - rscadd: The syndicate have taken notice of the camera bug's woeful underuse, and + have managed to combine all of its upgrades into one! +2015-09-06: + Fox P McCloud: + - bugfix: Fixes gold sheets having plasma as their material. + Xhuis: + - bugfix: Nanotrasen inspectors have discovered a fault in the buckles of chairs + and beds. This has been fixed and you are now able to buckle again. +2015-09-07: + xxalpha: + - tweak: Changed xeno weed spread to be like gas spread. +2015-09-09: + Joan: + - rscadd: New blob chemical; Cryogenic Liquid. Cools down targets. + - tweak: Tweaked names, colors, and effects of remaining blob chemicals; + - tweak: Skin Ripper is now Ripping Tendrils and does minor stamina damage, in addition + to the brute damage. + - tweak: Toxic Goop is now Envenomed Filaments and injects targets with spore toxin + and causes hallucinations, in addition to the toxin damage. + - tweak: Lung Destroying Toxin is now Lexorin Jelly and does brute damage instead + of toxin damage. The oxygen loss it causes can also no longer crit you in one + hit. + - tweak: Explosive Gelatin is now Kinetic Gelatin and does random brute damage, + instead of randomly exploding targets. + - rscdel: Skin Melter, Radioactive Liquid, Omnizine, and Space Drugs blob chemicals + are gone. + bgobandit: + - rscadd: Nanotrasen has commissioned two new corporate motivational posters for + your perusal and edification. + - rscadd: Nanotrasen also wishes to remind the crew that non-authorized posters + ARE CONTRABAND. Especially those new ones with Rule 34. Perverts. +2015-09-11: + CosmicScientist: + - tweak: Drone dispenser now has a var for its cooldown, get var editing. +2015-09-13: + Fox P McCloud: + - bugfix: Fixes an exploit and inconsistency issue with a few material amounts on + a few items and designs. + - bugfix: Fixes Bibles/holy books not properly revealing runes. + - bugfix: fixes stimulants not properly applying its speedbuff. + Gun Hog: + - tweak: Nanotrasen scientists have proposed a refined prototype design for the + nuclear powered Advanced Energy guns to include a taser function along with + the disable and kill modes. Addtionally, they have modified the chassis blueprint + to include a hardpoint for attachable seclites. + Iamgoofball: + - tweak: Reduced the cost of changeling armor to 1 and increased it's armor values. + Jordie0608: + - rscadd: You can now view the reason of a jobban from character setup. + xxalpha: + - rscadd: Drying agent splashed on galoshes will turn them into absorbent galoshes + that dry wet floors they walk on. + - rscadd: Drying agent can be made with ethanol, sodium and stable plasma. +2015-09-14: + Fox P McCloud: + - tweak: Adds a mining voucher to the Quartermaster's locker. + Thunder12345: + - rscadd: The captain has been issued with a new jacket for formal occasions. + - tweak: Research has shown that is is possible to build technological shotshells + without the need for silver. The design blueprints supplied to your station + have been updated accordingly. + xxalpha: + - bugfix: Fixed not being able to grab things from storage while inside aliens. + - bugfix: Fixed two progress bars when devouring. + - rscadd: Shields will now block alien hunter pounces. + - tweak: Alien hunters health reduced to 125 from 150. Alien sentinels health increased + to 150 from 125. + - tweak: Alien hunters will no longer be transparent when stalking, this ability + was given to alien sentinels. + - tweak: Alien slashing now deals constant 20 damage but has a chance to miss. + - tweak: Reduced alien disarm stun duration vs cyborgs, from 7 seconds to 2 seconds. + - tweak: Alien sentinels now move as fast as humans. + - tweak: Facehuggers and alien eggs layers increased to be higher than resin walls. +2015-09-16: + Razharas: + - tweak: Replaces the space cube with space torus. Space levels are now each round + randomly placed on the grid with at least one neigbour, any side of the space + level that doesnt have neigbour will loop either onto itself or onto the opposite + side of the furthest straight-connected space level on the same axis. + Supermichael777: + - tweak: The detomax pda cartridge no longer blows its user up. + Xhuis: + - experimental: Cultists will now be able to create all runes without needing to + research or collect words. This is subject to change. + - tweak: Cult code has been significantly improved and will run much faster and + be more responsive. + - tweak: Conversion runes can now be invoked with less than three cultists, but + take a small amount of time to convert the target. + - tweak: Armor runes will only outfit the user with standard armor, rather than + having different loadouts for different worn clothing items. + - tweak: Astral Journey runes will now pull the user back to the rune if they are + moved. The user also has a different color while on the rune. + - tweak: Free Cultist has been removed. Summon Cultist now works even if the target + is restrained. + - tweak: Sacrifice and Raise Dead runes now offer more precise target selection. + - soundadd: Sacrifice runes now have different sounds, and gib rather than dust + (assuming the target is not a silicon). + - tweak: There is no longer a maximum cap on active runes. + - tweak: Runes have been renamed to Rites. For instance, the Teleport rune is now + the Rite of Translocation. The only exception to this is the rune to summon + Nar-Sie, which is a Ritual. + - tweak: Nar-Sie now has a new summon sound. + - tweak: The Nar-Sie summon rune has a new 3x3 sprite. + - tweak: The stun rune no longer stuns cultists. + - rscadd: The Rite of False Truths had been added, that will make all nearby runes + appear as if they were drawn in crayon. + - rscadd: Runes can now be examined by cultists to determine their name, function, + and words. + phil235: + - tweak: Riot and energy shield users now have a chance to block things thrown at + them as well as xeno leaping at them. +2015-09-17: + bgobandit: + - rscadd: Meatspikes can now be constructed and deconstructed with metal and rods, + as well as wrenched and unwrenched! Humans and corgis can be used on them as + well. + xxalpha: + - tweak: 'Reworked nuke deconstruction: Standardized steps, partial reparation (use + metal) to contain radiation.' + - rscadd: New portable nuke, self-destruct terminal, syndie screwdriver sprites + by WJohnston. +2015-09-19: + Xhuis: + - rscadd: Shadowlings are now able to sacrifice a thrall to extend the shuttle timer + by 15 minutes. This will not stack. + - bugfix: Additional abilities granted by Collective Mind will now properly have + icons. + - bugfix: Shadowlings now have their antagonism removed if turned into a silicon. + - tweak: The order of abilities unlocked by Collective Mind has been changed. It + now starts with Sonic Screech. + - tweak: Veil now destroys glowshrooms in a much larger radius than before. +2015-09-20: + Xhuis: + - tweak: Rites have been renamed to their old runes, which reflect their functionality. + - tweak: Examining a talisman no longer opens the paper GUI. + - tweak: Armor talismans have been re-added. + - tweak: EMP talismans now have the same range as their rune counterpart. + - tweak: Some talismans now cost health to use, costing more or less depending on + their effect. + - tweak: Scribing runes now deals 0.1 brute damage instead of 1. + - tweak: Bind Talisman runes no longer deal 5 brute damage when invoking. + - tweak: Rune shapes and colors are now identical to their old versions. + - tweak: Conversion runes can no longer be used by yourself, and require a static + 2 cultists. +2015-09-22: + Kor: + - rscadd: A new admin command, Offer Control to Ghosts, can be found in the view + variables menu. It will randomly select a willing candidate from among dead + players, providing a fair method of replacing antagonists. + Xhuis: + - tweak: When a morph changes form, a message is shown to nearby people. This also + happens upon undisguising. + - tweak: Morphs now have an attack sound and message. + - tweak: The Spawn Morph event now plays a sound to the chosen candidate. + - tweak: Slaughter demons (and other creatures with blood crawl) now take two seconds + to emerge from blood pools. Entering is still instantaneous. + - tweak: The demon heart's sprite has been updated. + - tweak: Eating a demon heart now surgically implants the heart into your chest. + If the heart is removed from you, you lose the ability. Someone else can eat + the heart to gain the ability. + - tweak: Blood Crawl no longer has a 1-second cooldown, instead having none. + - tweak: You can no longer hold items when attempting to Blood Crawl, nor can you + use any items while Blood Crawling. + - tweak: Creatures that can Blood Crawl now take two seconds to emerge from blood + pools. + - tweak: Slaughter demons now store devoured creatures, and will drop them upon + death. + - tweak: Revenants now have the ability to speak to the dead. + - tweak: Revenant abilities now have icons. + - tweak: Malfunction no longer EMPs a specific area - it will instead EMP nearby + machines directly and stun cyborgs. Dominators are immune to this. + - tweak: Revenants now have directional sprites. + - tweak: Overload Lights now has a smaller radius. + - tweak: Defile no longer corrupts tiles. + - tweak: When glimmering residue reforms, the game will attempt to place the old + revenant in control of the new one. If this cannot be done, it will find a random + candidate. + - tweak: Revenants can no longer see ghosts. They can see other revenants, however, + and ghosts can still see revenants. + - tweak: The Spawn Slaughter Demon event now plays a sound to the chosen candidate. + phil235: + - rscdel: Lizards and other non human species can no longer acquire the hulk mutation. + Hulks no longer have red eyes + - bugfix: Monkeys now always have dna and a blood type (compatible with humans). + - bugfix: Monkey transformation no longer deletes the human's clothes. + - bugfix: Space Retrovirus now correctly transfers dna SE to the infected human. + - bugfix: Changeling's Anatomic Panacea removes alien embryo again. + - bugfix: Cloning someone now correctly sets up their dna UE. + - bugfix: Fixes the laser eyes mutation not giving glowing red eyes to the human. + - bugfix: Using changeling readaptation now properly removes all evolutions bought + (arm blade, chameleon skin, organic suit). + xxalpha: + - rscadd: Added a researchable cyborg self-repair module to the robotics fabricator. +2015-09-23: + Xhuis: + - rscadd: Syndicate medical cyborgs have been added. + - rscadd: The Dart Pistol is now available from the uplink for 4 telecrystals. It + functions as a pocket-sized syringe gun with a quieter firing sound. + - tweak: Boxes of riot foam darts now cost 2 telecrystals, down from 10, and are + available to traitors. + - tweak: Foam dart pistols now cost 3 telecrystals, down from 6. + - tweak: Syndicate cyborg teleporters now allow a choice between Assault and Medical + cyborgs. + - tweak: Syndicate cyborgs are now distinguished as Syndicate Assault. + - tweak: Syndicate cyborg energy swords now cost 50 energy per use, down from 500. + - tweak: Airlock charges now cost 2 telecrystals, down from 5. + - tweak: Airlock charges are much more powerful. + - tweak: There is no longer a 25% chance to detonate an airlock charge while removing + it. + - tweak: The description of many uplink items has been changed to better reflect + their use. +2015-09-24: + Jordie0608: + - tweak: Advanced energy guns now only critically fail after successive minor failures. + Cease firing after multiple recent minor failures to avoid critical ones. + Kor: + - rscadd: Guardian Spirit types and powers have been heavily reworked. Full details + of each type are available on the wiki. + - rscadd: Guardian damage transfer to users now deals cloneloss if their user is + in crit. + - rscadd: Guardians are now undergoing a trial run in the traitor uplink, under + the name of Holoparasites. + - rscadd: You can now hang human mobs (dead or alive) from meatspikes. Escaping + the meatspike will further damage the victim. + - rscdel: You can no longer slam humans into the meatspike as an attack. +2015-09-25: + Xhuis: + - rscadd: Changelings have a new ablity, Biodegrade. Costing 30 chemicals and having + an unlock cost of 1, it allows them to dissolve handcuffs and straight jackets + in 3 seconds, and escape from lockers in 7. + - tweak: Fleshmend's effectiveness is now halved each time it is used in a short + time span. + - tweak: Last Resort now blinds and confuses nearby humans and briefly disables + silicons upon use. + - tweak: Headslugs now have 50 health, up from 20. +2015-09-26: + MMMiracles: + - rscadd: Nanotrasen's genetic researchers have rediscovered the inactive dwarfism + genetic defect inside all bipedal humanoids. Suffer not the short to live. + WJohnston: + - tweak: Repiped the entire station. Atmosia and the disposals loop were not touched. + - tweak: Moved mulebot delivery from misc lab to RnD. +2015-09-28: + Feemjmeem: + - bugfix: Rechargers can now be wrenched and unwrenched by cyborgs. + - bugfix: Rechargers no longer stop working forever if you move them from an unpowered + area to a powered area, and now actually look powered off when they are. + - bugfix: Guns and batons can no longer be placed in unwrenched chargers. + Razharas: + - rscadd: Added button to preferences menu that kills all currently playing sounds + when pressed, now you can kill midis and any other sounds for real. + phil235: + - bugfix: Fixed the syndicate cyborg's grenade launcher. + - tweak: You can modify the dna of corpses again. +2015-09-29: + Kor: + - bugfix: The Chaos holoparasite can now actually set people on fire properly. + - tweak: Guardian powers are now used via alt+click rather than shift+click. + - tweak: Added an alert chime for ghosts when someone is summoning a Guardian. diff --git a/html/changelogs/archive/2015-10.yml b/html/changelogs/archive/2015-10.yml new file mode 100644 index 0000000000..9c733e85c8 --- /dev/null +++ b/html/changelogs/archive/2015-10.yml @@ -0,0 +1,276 @@ +2015-10-04: + Fox P McCloud: + - tweak: Adds a bar of soap to the janitor's locker. + - rscadd: Re-adds the advanced mop as a researchable R&D item. + - rscadd: Adds a bluespace trashbag as a researchable R&D item; can hold large quantities + of garbage. + Jordie0608: + - rscadd: Added Special Verb 'Create Poll', an in-game interface to create server + polls for admins with +permissions. + MrPerson: + - rscdel: Removed NTSL. Sorry. People could write scripts that crashed the server, + and this is the only thing that can be done to prevent them from doing that. + MrStonedOne: + - rscdel: Removed feature where quick consecutive ghost orbits while moving could + be used to fuck with your sprite + - bugfix: Fixed ghosts losing floating animation when returning from an orbit + - bugfix: Fixed logic error that prevented orbit's automatic cancel when the orbiting + thing moved in certain situations. + - rscadd: Ghost Orbit size now changes based on the icon size of the thing they + are orbiting (for that sweet sweet singulo orbiting action) + - tweak: Removed needless checks in ghost orbit, you can now orbit yourself and + restart an orbit around the thing you are already orbiting + Xhuis: + - rscadd: Syndicate Medical cyborgs now have cryptographic sequencers. + - rscdel: Syndicate Medical cyborgs no longer have syringes. + - tweak: Restorative Nanites now heal much more damage per type. + - bugfix: Operative pinpointers now actually point toward the nearest operative. + - bugfix: Syndicate Assault cyborgs no longer start with medical supplies. + - bugfix: Energy saws now have a proper icon. + - bugfix: Non-operatives can now longer use operative pinpointers or Syndicate cyborg + teleporters. + - tweak: Doctor's Delight now requires cryoxadone in its recipe instead of omnizine. + - tweak: Doctor's Delight now restores half a point of brute, burn, toxin, and oxygen + damage per tick. + - tweak: Doctor's Delight now drains nutrition while it's in your system (that is, + unless you're a doctor). + - bugfix: Syndicate roboticists have given Syndicate medical cyborgs sharper hypospray + needles - they are now able to penetrate armor. +2015-10-06: + Gun Hog, for WJohnston: + - rscadd: 'Add new Xenomorph caste: The Praetorian. Drones may become this on their + way to growing into a full queen, and a queen may promote one if there is not + one already.' + - tweak: Xenomorph queens are now GIGANTIC, along with the new Praetorian. Together, + they are considered royals. + - tweak: Queens are now significantly tougher to make up for their huge size. + - bugfix: All forms of dead xenomorph may now be grabbed and placed on a surgery + table for organ harvesting! + Xhuis: + - rscadd: Maintenance drones now have a more descriptive message when examined. + - tweak: A recent Nanotrasen firmware update to drones has increased vulnerability + to foreign influences. Please periodically check drones for abnormal behavior + or status LED malfunction. Note, however, that cryptographic sequencers will + not incur this behavior. + - tweak: In response to complaints about rogue drones, Nanotrasen engineers have + allowed factory resets on all drones by simply using a wrench. + - experiment: Central Command reminds drones to immediately retreat, if possible, + when a law override is begun. Not doing so may anger the gods and incur their + wrath! + - rscadd: Some virus symptoms that had no messages now have them. + - rscadd: 'New virology symptom: Weakness. This will cause stamina damage and fainting + spells.' + - tweak: Many virus symptom messages have been changed to be more threatening. +2015-10-07: + Kor: + - rscadd: The alien queen can now perform a tail sweep attack, throwing back and + stunning all nearby foes. +2015-10-13: + AnturK: + - rscadd: Display cases can now be built using 5 wood planks and 10 glass sheets. + - rscadd: Add airlock electronics to open it with id later, otherwise you'll have + to use crowbar + - tweak: Broken display cases can be fixed with glass sheets or removed using crowbar + - tweak: Added start_showpiece_type variable for mappers to create custom displays + - rscadd: Syndicate Lone Operatives spotted near the nanotrasen stations! Keep the + disk safe! + - tweak: Admin spawned nuclear operatives will now have access to nukeop equipment + Gun Hog: + - rscadd: Nanotrasen's research team has released a new, high tech design for Science + Goggles, which previously did nothing! They new come fitted with a portable + scanning module which will display the potential research data gained from experimenting + with an object. Nanotrasen has also released drivers which shall enable the + prototype hardsuit's built in scan visor. + - rscadd: Supporting this new design, Nanotrasen has seen fit to provide blueprints + for Science Goggles to the station's protolathe. + Kor: + - tweak: Gang implanters now only break implants/deconvert gangsters, meaning you + will have to use a pen to convert them afterwards. + - rscadd: An important function, accessible via alt+click, has been restored to + the detectives hat. + - sounddel: When Nar-Sie is created, they now use the old sound effect. + Steelpoint: + - rscadd: The Chief Medical Officers 'Medical Hardsuit' has been added to the CMO's + office. Boasts the usage of lightweight materials allowing fast movement while + wearing the suit as well as complete biological protection to airborne and similar + pathogens. + - rscadd: The Head of Security's personal 'HoS Hardsuit' has been added to the HoS's + office. This Hardsuit is slightly more armored than the regular Security Hardsuit. + - rscadd: The Research Directors 'Prototype Hardsuit' has been added to the RD's + office. This Hardsuit offers the highest levels of protection against explosive, + as well as biological, attacks, as well as fireproofing. + - rscdel: The Command EVA space suits, due to budget concerns, have been removed + and reloacted to another space station. + Xhuis: + - rscdel: All instances of autorifles have been removed from Security. + - rscadd: The armory has been re-mapped. + - tweak: The spell book has received a rebalancing! There are now ten uses by default, + but most spells cost two uses. Some underused spells, like Blind, Smoke, and + Forcewall, only cost a single use. + - experiment: After searching through the Sleeping Carp's ancient monastery in deep + space, more secrets have been uncovered of their traditional fighting techniques. + - tweak: Members of the Sleeping Carp gang are now able to deflect all ranged projectiles. + - tweak: Members of the Sleeping Carp gang are now uanble to use any type of ranged + weaponry. Doing so would be dishonorable. + - tweak: The Sleeping Carp martial art's effects are more damaging, and many stuns + have been increased in duration. + phil235: + - bugfix: Fixes critical bug causing multiple hits from single projectile. + - bugfix: Fixes not being able to shoot a mob on same tile as the shooter. + - bugfix: Clicking your mob (without targeting your mouth) no longer causes you + to shoot yourself. + - bugfix: Fixes not being able to shoot non human mobs at point blank. + - rscdel: Morphs no longer automatically drop the things they swallowed, you have + to butcher their corpse to retrieve their contents. + - bugfix: butchering a corpse no longer also attacks it. + - rscdel: Dipping cigarette (to asbsorb liquids) in a glass can now only be done + with an unlit cigarette. Lit cigarette now heats up the glass content (like + other heat sources). + - bugfix: Fixes trashbag not being able to pickup drinks and ammo casings. + - tweak: Slimes now attaches themselves to mobs via buckling. +2015-10-16: + MrStonedOne: + - rscadd: Added a reconnect option to the file menu. This will allow you to reconnect + to the game server without closing and re-opening the game window. This should + also prevent another byond ad from playing during reconnections. + Xhuis: + - rscadd: A gamebreaking bug has been fixed with buckets. You can now wear them + on your head. + bgobandit: + - rscadd: The Grape Growers Consortium has complained that Nanotrasen kitchens do + not use their products enough. HQ has come up with a few recipes to pacify them. + Goddamn winos. +2015-10-19: + AnturK: + - rscadd: Handheld T-Ray Scanners now detect critters in pipes. + Kor: + - tweak: Weapons and projectiles that are armour piercing now have an increased + chance to bypass riot shields. + - tweak: Slipping on lube now deals slightly more damage, but is concentrated on + a random body part, rather than spread to your entire body. + - tweak: Slipping on water no longer deals damage + - rscadd: You can now attach grenades and C4 to spears to create explosive lances. + This is done via table crafting. Alt+click the spear to set a war cry. + Shadowlight213: + - rscadd: In response to reports of stranded drones, Nanotrasen has added magnets + to drone legs. They are no longer affected by lack of gravity or spacewind! + - bugfix: Drones can now set Airlock access on RCDs. + bgobandit: + - rscadd: Nanotrasen loves recycling! In the highly unlikely occasion that your + space station accumulates gibs, scoop 'em up and bring them to chemistry to + recycle into soap, candles, or even delicious meat product! + - rscadd: L3 biohazard closets now contain bio-bag satchels for the safe collection + of biowaste products, such as slime extracts. + phil235: + - rscdel: Removing Smile, Swedish, Chav and Elvis mutations from genetics. These + mutation can still be acquired via adminspawned dna injector. + - rscadd: Added a dna injector for laser eyes mutation for admin use. + - bugfix: Fixes winter coat hood sprite appearing as a bucket. + - bugfix: Fixes using razor on non human shaving non existent hair. + - bugfix: Fixes chair deconstruction dropping too much metal. + - bugfix: Fixes snapcorn not giving seeds. + - bugfix: Fixes portable chem dispenser. + - tweak: Changing the transfer amount of all reagent containers (beaker, bucket, + glass) is now done by clicking them, similar to spray. Reagent dispensers (watertank, + fueltank, pepperspray dispenser) no longer have their own transfer amounts and + use the reagent container's transfer amount instead (except for sprays which + get 50u for faster refilling). +2015-10-23: + Incoming5643: + - rscadd: 'Syndicate bomb payloads will now detonate if set on fire long enough. + Note that the casings for the bombs is fireproof, so if you want to set fire + to a bombcore you''ll need to remove it from the case first (cut all wires, + then crowbar it out). A reassurance from our explosives department: it is, and + always has been, impossible to detonate a syndicate bomb that isn''t ticking + with wirecutters alone.' + Xhuis: + - rscadd: Geiger counters have been added and are obtainable from autolathes and + EngiVends. They will measure the severity of radiation pulses while in your + pockets, belt, or hands. One can scan a mob's radiation level by switching to + Help intent and clicking on it. These counters never really discard the radiation + they store, and rumor has it this can be used in nefarious ways... + - tweak: When a mob is impacted by radiation, the radiation is now relayed to all + items on the mob. +2015-10-24: + Kor: + - rscadd: The friendly gold slime reaction now spawns three mobs. + phil235: + - tweak: Changed the effects of alcohol to be more realistic. The effects of alcohol + now appear twice as fast. Drunkenness now scales with how much alcohol is in + you, not how long you've been drinking. This means drinking very little but + continuously no longer makes you very drunk, or confused/slurring for a long + time or give you alcohol poisoning. The dizziness and slurring effects now properly + scale with how drunk you are (and dizziness is generally more pronounced). +2015-10-25: + Incoming5643: + - rscadd: The spell Charge has been added to the spellbook. It can be used to extend + the life of magic and energy weapons and even reset the cooldowns of held wizards! + It cannot reset your own cooldowns. + - rscadd: The Staff of Healing has been added to the spellbook. Heals all damage + and raises the dead! Can't be used on yourself however. + - bugfix: The exploit that allowed you to use the staff of healing on yourself by + suicide has been fixed. + Jordie0608: + - rscadd: You can now selectively mute non-admin players from OOC with the Ignore + verb in the OOC tab. + Tkdrg: + - rscadd: Added chainsaws. They can be tablecrafted using a circular saw, a plasteel + sheet, some cable coil, and a welding tool. Don't forget to turn it on! +2015-10-26: + Fox P McCloud: + - tweak: Standardizes the slowdown of most spacesuits to 1 as opposed to 2. + Incoming5643: + - rscadd: 48x48 pixel mode (x1.5 zoom) has been added to the Icons menu (top left). + While playing in 32x32 or 64x64 will still provide a clearer looking station, + for those of us with resolutions that fall into the gap between the two zooms + this can provide a more consistant looking station than stretch to fit. + - rscadd: 96x96 pixel mode (x3 zoom) has also been added for our players who enjoy + looking at spacemen on their 4k monitors at a crisp and consistent scale. + - tweak: The lich spell has been subjected to some gentle nerfing. When you die + a string of energy will tie your new body to your old body for a short time, + aiding others in determining your location. The duration of this beam scales + with the number of deaths you've avoided. + - tweak: Additionally the post revival stun now also scales in this way. + - tweak: The spell will also fail if the item and the wizard don't share the same + z level, though the nature of space means the odds of the item (or the wizard) + looping around back to the station is pretty high. + - rscadd: The spell is still really good. +2015-10-27: + Joan: + - bugfix: You can now click on things under timestop effects, instead of clicking + the effect and looking like a fool. + Kor: + - rscadd: Added a zombie mob that turns its kills into more zombies. Currently adminspawn + and xenobio only. + - rscadd: Using water with a red slime extract will now yield a speed potion. Using + the speed potion on an item of clothing will paint it red and remove its slowdown. + MrStonedOne: + - rscadd: You may now access the setup character screen when not in the lobby via + the game preferences verb in the preferences tab + - rscadd: The round end restart delay can now be configured by server operators. + New servers will default to 90 seconds while old servers will default to the + old 25 seconds until they import the config option to their server. +2015-10-28: + Tkdrg: + - rscadd: Added a Ghost On-screen HUD. It can be toggled using the "Toggle Ghost + HUD" verb. Thank you Razharas for the sprites! + - rscadd: Ghosts can now use the "Toggle med/sec HUD" verb to see the basic secHUD + (jobs only) or the medHUD of humans. + - rscadd: Ghost will now get clickable icon alerts from events such as being put + in a cloner, drones being created, Nar-sie being summoned, among others. The + older chat messages were kept. These alerts can not be toggled. +2015-10-29: + Kor: + - tweak: Slightly changed what items spawn on the captain vs in his locker, hopefully + saving some annoying inventory shuffle at roundstart. +2015-10-30: + Incoming5643: + - rscadd: Slimepeople can now split if they contain 200 units of slime jelly, and + slimepeople will now slowly generate slime jelly up to 200 units provided they + are very well fed. Split slimepeople are NOT player controlled, but rather the + original slime person can swap between the two mobs at will. If one of the slimepeople + should die under player control, the player won't be able to swap back to their + living body. Splitting only creates a new body, any items you have on you are + not duplicated. + - rscadd: Slimepeople now take half damage from sources of heat, but double damage + from sources of cold. Lasers good, Space bad. diff --git a/html/changelogs/archive/2015-11.yml b/html/changelogs/archive/2015-11.yml new file mode 100644 index 0000000000..c0223b35f8 --- /dev/null +++ b/html/changelogs/archive/2015-11.yml @@ -0,0 +1,456 @@ +2015-11-01: + Gun Hog: + - rscadd: Nanotrasen listens! After numerous complaints and petitions from Security + personnel regarding energy weapon upkeep, we have authorized the construction + and maintenance of your station's weapon rechargers. As an added bonus, we have + also provided a more modular design for the devices, allowing for greater recharge + rates if fitted with a more efficient capacitor! + - rscadd: Added Diagnostic HUDs! They can be used to view the health and cell status + of borgs and mechs. Silicons have them built in, Roboticists get two in their + locker, and the RD's hardsuit has one built in. + Incoming5643: + - rscadd: The number of roundstart head revolutionaries nows depends on the roundstart + security force as well as the roundstart heads + - rscadd: The maximum number of head revs is 3, the minimum is 1. If there is fewer + than three station heads there will never be more than that number of head revs + at roundstart. For every three vacant security roles (Head of Security/Warden/Security + Officer/Detective) at roundstart the number of starting head revs will be reduced + by 1. + - rscadd: Head revolutionaries can be gained during play if the security/head roles + are filled. They are drawn from existing revolutionaries. + - rscadd: Added dental implant surgery. While targeting the mouth drill a hole in + a tooth then stick a pill in there for hands free later use. + Kor: + - rscadd: Added an experimental control console for Xenobiology. Ask the admins + if you'd like to try it out. It may not work on maps other than Box if they + have renamed the Xenobiology Lab. + - rscadd: Injecting blood into a cerulean slime will yield a special one use set + of blueprints that will allow you to expand the territory your camera can cover. + Kor and Remie: + - rscadd: Added as series of laser reflector structures, the frame of which can + be built with 5 metal sheets. + - rscadd: Completing the frame with 5 glass sheets creates a mirror that will reflect + lasers at a 90 degree angle. + - rscadd: Completing the frame with 10 reinforced glass sheets creates a double + sided mirror that reflects lasers at a 90 degree angle. + - rscadd: Completing the frame with a single diamond sheet creates a box that will + redirect all lasers that hit it from any angle in a single direction. + MMMiracles: + - tweak: Energy Swords can now embed when thrown for a 75% chance. Embedding +2015-11-05: + AnturK: + - rscadd: Added wild shapeshift spell for wizards. +2015-11-08: + Cuboos: + - soundadd: Added a new and better sounding flashbang sound and a ringing sound + for flashbang deaf effect + JJRcop: + - tweak: Chronosuits have had their movement revised, they now take time to teleport + depending on how far you've traveled, and don't teleport automatically anymore + unless you stop moving for a short moment, or press the new ' Teleport Now' + button. + - rscadd: Added new outfit that allows admins to dress people up in the chrono equipment + easier. + Jalleo: + - tweak: Due to a recently discovered report it turns out The Wizard Federation + has devised a way for CEOs to stop having some teas from their Smartfridges + due to this change all smartfridges will temporarily be unable to stack contents. + Joan: + - tweak: Revenant draining now takes about 5 seconds to complete and can be interrupted + by dragging the target away. + - tweak: Revenants can now tell if they are currently visible. + - tweak: Revenant ability costs tweaked; Defile now costs 40 essence to cast, Overload + Lights now costs 45 essence to cast, and Malfunction now costs 50 essence to + cast. + - tweak: Malfunction now affects non-machine objects, even if they're not being + held by a human. + - tweak: Defile does an extremely low amount of toxin damage to humans and confuses, + but does much less stamina damage and stuns the revenant for slightly longer. + - tweak: Overload Lights will no longer shock if the light is broken after a light + is chosen to shock an area. + Kor: + - rscadd: Using water on a dark blue slime extract will now yield a new potion capable + of completely fireproofing clothing items. + - rscadd: You can once again click+drag mobs into disposal units. Xenobiologists + rejoice. + Xhuis: + - tweak: Shadowling abilities now require the user to be human. + - tweak: Enthralling now takes 21 seconds (down from 30). + - tweak: Regenerate Chitin has been renamed to Rapid Re-Hatch. + - tweak: Dethralling surgery's final step now requires a flash, penlight, or flashlight. + - tweak: Dethralling surgery now produces a black tumor, which has a high biological + tech origin but dies quickly in the light. + - rscdel: Shadowlings no longer have Enthrall before hatching. + - rscadd: Shadowling clothing now has icons to better reflect its existence. + - rscdel: Ascendant Broadcast has been removed. + - rscdel: Destroy Engines is now removed from the user after it is used once. +2015-11-11: + AnturK: + - tweak: DNA Injectors now grant temporary powers on every use. Duration dependent + on activated powers and machine upgrades + - rscadd: 'Delayed Transfer added to DNA Scanner - It will activate on the next + closing of scanner door ' + - rscadd: 'UI+UE injectors/buffer transfers added for convinience ' + - tweak: Injector creation timeout cut in half + Firecage: + - rscadd: NanoTrasen specialists has developed a new type of operating table. You + can now make one yourself with only some rods and a sheet of silver! + Kor: + - rscadd: Adds immovable and indestructible reflector structures for badmin use. + - rscadd: The Mjolnir has been added to the wizards spellbook. + - rscadd: The Singularity Hammer has been added to the wizards spellbook. + - rscadd: The Supermatter Sword has been added to the wizards spellbook. + - rscadd: The Veil Render has been added to the wizards spellbook. + - rscadd: Trigger Multiverse War (give the entire crew multiswords) has been added + to the wizards spellbook, at a cost of 8 points. + - rscadd: Converting (to cultist, rev, or gangster) a jobbaned player will now automatically + offer control of their character to ghosts. + - rscadd: Emergency Response Teams and Deathsquads no longer accept non-human members + if the server is configured to bar mutants from being heads of staff. + LordPidey: + - rscadd: Nanotransen doctors have re-approved Saline-Glucose Solution for usage + in IV drips, when blood supplies are low. Simple pills will not suffice. + MMMiracles: + - tweak: Water slips have been nerfed to a more reasonable duration. It is still + a guaranteed way to disarm an opponent and obtain their weapon, but you can + no longer manage to cuff/choke everyone who manages to slip without a problem. + MrStonedOne: + - bugfix: Fixes the smartfridge not stacking items. + Xhuis: + - soundadd: The emergency shuttle now plays unique sounds (thanks to Cuboos for + creating them) when launching from the station and arriving at Central Command. + torger597: + - rscadd: Added a syringe to boxed poison kits. +2015-11-12: + Dunc: + - rscdel: DNA injectors have been restored to their original permanent RNG state + from the impermanent guaranteed state. + Xhuis: + - rscadd: Reagents can no longer be determined by examining a reagent container + without the proper apparatus. Silicons and ghosts can always see reagents. + - rscadd: Science goggles now allow reagents to be seen on examine. In addition, + chemists now start wearing them. The bartender has a pair that looks and functions + like sunglasses. +2015-11-13: + as334: + - rscadd: Nanotrasen has hired a brand new supply of ~~expendable labor~~ *LOYAL + CREW MEMBERS* please welcome them with open arms. + - rscadd: Plasmamen are now a playable race. They require plasma gas to survive + and will ignite in oxygen environments. +2015-11-15: + CosmicScientist: + - tweak: Hopefully made the dehydrated carp's uplink description 100% clear. + - tweak: Made the dehydrated carp cost 1 TC (instead of 3) to help with your traitor + gear combos. + Incoming5643: + - tweak: The supermatter sword was being far too kind in the hands of men. They + should now have the desired effect when swung at people. + Joan: + - tweak: Anomalies move more often, are resistant to explosions and will only be + destroyed if they are in devastation range. You shouldn't bomb them, though. + - tweak: Hyper-energetic flux anomaly will shock mobs that run into it, or if it + runs into them. + - tweak: Bluespace anomaly will occasionally teleport mobs away from it in a small + radius. + - tweak: Vortex anomalies will sometimes throw objects at nearby living mobs. + - tweak: Pyroclastic anomalies will produce bigger, hotter fires, and if not disabled, + it will release an additional burst of flame. In addition, the resulting slime + will be rabid and thus attack much more aggressively. + - bugfix: Gravitational anomalies will now properly throw objects at nearby living + things. + MrStonedOne: + - bugfix: Away mission loading will no longer improperly expand the width of the + game world to two times the size of the away mission map. + - tweak: This should also improve the speed of loading away missions, since the + game doesn't have to resize the world + RemieRichards: + - rscadd: Deities now start off with the ability to place 1 free turret + - tweak: HoG Claymores now do 30 Brute (Down from 40) but now have 15 Armour Penetration + (Up from 0) + - bugfix: Killing the other god objective is fixed + - tweak: Turrets will no longer attack handcuffed people + - rscadd: Followers are now informed of their god's death + - rscadd: Followers are now informed of the location of their god's nexus when it + is placed + - tweak: Gods can no longer place structures near the enemy god's nexus +2015-11-16: + Gun Hog: + - tweak: The Combat tech requirement for Loyalty Firing Pins has been reduced from + 6 to 5. + Joan: + - tweak: Plasmamen can now man the bar. + - tweak: Defile no longer directly affects mobs. Instead, it rips up floors and + opens most machines and lockers. + - rscadd: Blight added. Blight infects humans with a virus that does a set amount + of damage over time and is relatively easily cured. Blight also badly affects + nonhuman mobs and other living things. + - experiment: While the cure to Blight is simple, it's not in this changelog. Use + a medical analyzer to find the cure. + - tweak: Tweaked costs and stuntimes of abilities; + - tweak: Defile now costs 30 essence and stuns for about a second. + - tweak: Overload Lights now costs 40 essence. + - tweak: Malfunction now costs 45 essence. + - rscadd: Blight costs 50 essence and 200 essence to unlock. + - imageadd: Transmit has a new, spookier icon. + - bugfix: Revenant abilities can be given to non-revenants, and will work as normal + spells instead of runtiming. + bgobandit: + - rscadd: Blood packs can now be labeled with a pen. +2015-11-17: + Xhuis: + - tweak: Many medicines have received rebalancing. Expect underused chemicals like + Oxandralone to be much more effective in restoring damage. + - tweak: Many toxins are now more or less efficient. + - tweak: The descriptions of many reagents have been made more accurate. + - rscadd: 'New poison: Heparin. Made from Formaldehyde, Sodium, Chlorine, and Lithium. + Functions as an anticoagulant, inducing uncontrollable bleeding and small amounts + of bruising.' + - rscadd: 'New poison: Teslium. Made from Plasma, Silver, and Black Powder, heated + to 400K. Modifies examine text and induces periodic shocks in the victim as + well as making all shocks against them more damaging.' + - rscadd: Two Chemistry books have been placed in the lab. When used, they will + link to the wiki page for chemistry in the same vein as other wiki books. +2015-11-18: + oranges: + - tweak: Nanotrasen apologies for a recent bad batch of synthflesh that was shipped + to the station, any rumours of death or serious injury are false and should + be reported to your nearest political officer. At most, only light burns would + result. + phil235: + - bugfix: Remotely detonating a planted c4 with a signaler now works again. +2015-11-19: + Joan: + - rscadd: Constructs have action buttons for their spells. + - imageadd: The Juggernaut forcewall now has a new, more cult-appropriate sprite. + - imageadd: Cult floors and walls now have a glow effect when being created. + - bugfix: Nar-Sie and Artificers will properly produce cult flooring. + - spellcheck: Nar-Sie is a she. +2015-11-20: + AnturK: + - tweak: Staff of Doors now creates random types of doors. + Incoming5643: + - bugfix: Setting your species to something other than human (if available) once + again saves properly. Note that if you join a round where your species setting + is no longer valid it will be reset to human. + PKPenguin321: + - tweak: Healing Fountains in Hand of God now give cultists a better and more culty + healing chemical instead of Doctor's Delight. + kingofkosmos: + - rscadd: Added the ability to upgrade your grab by clicking the grabbed mob repeatedly. + octareenroon91: + - rscadd: Add the four-color pen, which writes in black, red, green, and blue. + - rscadd: Adds two such pens to the Bureaucracy supply pack. +2015-11-21: + Joan: + - rscadd: Blobs now have a hud, with jump to node, create storage blob, create resource + blob, create node blob, create factory blob, readapt chemical, relocate core, + and jump to core buttons. + - tweak: Manual blob expansion is now triggered by clicking anything next to a blob + tile, instead of by ctrl-click. + - tweak: 'Rally Spores no longer has a cost. Reminder: You can middle-click anything + you can see to rally spores to it.' + - tweak: Creating a Shield Blob with hotkeys is now ctrl-click instead of alt-click. + - rscadd: Removing a blob now refunds some points based on the blob type, usually + around 40% of initial cost. Hotkey for removal is alt-click. + - rscadd: Blobs now have the *Blob Help* verb which will pull up useful information, + including what your reagent does. + - tweak: Storage Blobs now cost 20, from 40. Storage Blobs also cannot be removed + by blob removal. + - tweak: Readapt Chemical now costs 40, from 50. + octareenroon91: + - rscadd: Add numbers and a star graffiti to crayon/spraycan designs. +2015-11-23: + octareenroon91: + - rscadd: Spilling oxygen or nitrogen will obtain a release of the corresponding + atmospheric gas in the effected tile. + - rscadd: 'Carbon Dioxide has been added as a reagent. Recipe: 2:1 carbon:oxygen, + heated to 777K.' + - rscadd: Spilling CO2 will produce CO2 gas. +2015-11-24: + Kor: + - rscadd: Added a lava turf. Expect to see it in away missions or in admin 'events' +2015-11-25: + Incoming5643: + - experiment: A number of popular stunning spells have undergone balance changes. + Note that for the most part the stuns themselves are untouched. + - experiment: 'Lightning Bolt Changes:' + - rscdel: You can no longer throw the bolt whenever you want, it will fire itself + once it's done charging. + - rscadd: Getting hit by a bolt will do a flat 30 burn now, as opposed to scaling + with how long the wizard spent charging the spell. Unless said wizard made a + habit of charging lightning bolt to near maximum every time this is a buff to + damage. + - rscdel: Every time the bolt jumps the next shock will do five less burn damage. + - rscadd: Lightning bolts can still jump back to the same body, so the maximum number + of bolts you can be hit by in a single casting is three, and the maximum amount + of damage you could take for that is 60 burn. + - experiment: 'Magic Missile Changes:' + - rscdel: Cooldown raised to 20 seconds, up from 15 + - rscadd: Cooldown reduction from taking the spell multiple times raised from 1.5 + seconds to 3.5 seconds. Rank 5 magic missile now has a cooldown of 6 seconds, + down from 9, and is effectively a permastun. + - experiment: 'Time Stop Changes:' + - rscadd: Time Stop field now persists for 10 seconds, up from 9 + - rscdel: Cooldown raised to 50 seconds, up from 40 + - rscadd: Cooldown reduction from taking the spell multiple times raised from 7.75 + seconds to 10 seconds. Rank 5 time stop now has a cooldown of 10 seconds, up + from 9, and is effectively a permastun. + Kor: + - rscadd: Escape pods can now be launched to the asteroid during red and delta level + security alerts. Pods launched in this manner will not travel to Centcomm at + the end of the round. + - rscadd: Each pod is now equipped with a safe that contains two emergency space + suits and mining pickaxes. This safe will only open during red or delta level + security alerts. + MrStonedOne: + - bugfix: fixes interfaces (like the "ready" button) being unresponsive for the + first minute or two after connecting. + - tweak: Burn related code has been changed + - tweak: This will give a small buff to fires by making them burn for longer + - tweak: This will give a massive nerf to plasma related bombs + - tweak: I am actively seeking feedback, if the nerf to bombs is too bad we can + still tweak stuff + PKPenguin321: + - rscadd: Chainsaws (both arm-mounted and not arm-mounted) can now be used in surgeries + as a ghetto sawing tool. Arm-mounted chainsaws are a teeny bit more precise + than regular ol' everyday chainsaws. + YotaXP: + - tweak: Spruced up the preview icons on the Character Setup dialog. + incoming5643: + - rscdel: Citing shenanigan quality concerns the wizard federation has withdrawn + supermatter swords and veil renderers from spellbooks. + neersighted: + - bugfix: Make Airlock Electronics use standard ID checks, allowing Drones to use + them. +2015-11-26: + neersighted: + - tweak: Cyborg Toner is now refilled by recharging stations. + oranges: + - tweak: Removed the 'gloves' from the sailor dress which looked weird since it + was a blouse basically + - tweak: Made the skirt on the blue/red skirts less blocky, + - tweak: Made the striped dress consistent at every direction +2015-11-27: + AnturK: + - rscadd: Turret control panels can now be made through frames available at autolathe. + - rscadd: Unlocked turrets can be linked with built controls with multiool + JJRcop: + - bugfix: Restores golem shock immunity. + Kor and Ausops: + - rscadd: Added four different suits of medieval plate armour. + - rscadd: The Chaplain starts with a suit of Templar armour in his locker. God wills + it! + - rscadd: Rumour has it that Nanotrasen is now training a new elite unit of soldiers + to deal with paranormal threats. Corporate was unable to be reached for comment. + MMMiracles: + - rscadd: Adds a brand new away mission for the gateway called 'Caves'. + - rscadd: The away mission has multiple levels to explore and could be quite dangerous, + running in without proper preparation is unadvised. + YotaXP: + - bugfix: Drones can now use the pick-up verb, and watertanks no longer get jammed + in their internal storage. + bgobandit: + - rscadd: Due to changes in Nanotrasen's mining supply chain, ore redemption machines + now offer a variety of upgraded items! However, certain items are more expensive. + Point values for minerals have been adjusted to reflect their scarcity. + - rscadd: Nanotrasen R&D has discovered how to improve upon the resonator and kinetic + accelerator. + - rscadd: After a colossal tectonic event on Nanotrasen's asteroid, ores are distributed + more randomly. + - rscadd: Bluespace crystals have been discovered to be ore. They will now fit into + satchels and ore boxes. + - rscadd: Mech advanced mining scanners now include meson functionality. + neersighted: + - bugfix: Wooden Barricades now take bullet damage. + - tweak: Rebalance Wooden Barricade damage. +2015-11-28: + TechnoAlchemisto: + - tweak: Cloaks are now worn in your exosuit slot! +2015-11-29: + Firecage: + - rscadd: Hand tools now have variable operating speeds. + GunHog: + - tweak: Nanotrasen has improved the interface for the hand-held teleportation device. + It will now provide the user with the name of the destination tracking beacon. + JJRcop: + - bugfix: Fixes changeling Hive Absorb DNA ability runtime. + Joan: + - imageadd: When sacrificing a target with the sacrifice rune, Nar-Sie herself will + briefly appear to consume them. + - imageadd: When an artificer repairs a construct, there is a visible beam between + it and the target. + - imageadd: When reviving a target with the raise dead rune, there is a visible + beam between the two corpses used. + - imageadd: When draining a target with the blood drain rune, there is a visible + beam between you and the rune. + - imageadd: Construct sprites are now consistent and all bob in the air. + - rscadd: Most cult messages now use the cult span classes, though visible messages + from cult things generally do not. + - bugfix: Examining a cultist talisman as a cultist no longer causes the paper popup + to appear. + - bugfix: You no longer need to press two buttons to read a cultist tome. + - spellcheck: Cult should have a few less typos and grammatical errors. + - spellcheck: The sacrifice rune now uses the proper invocation. + KorPhaeron: + - rscadd: Guardians and holoparasites can now be manually recalled by their master. + - rscadd: The ghost controlling a guardian or holoparasite can be repicked by their + master, only one use which is removed when a new ghost is chosen. + MrStonedOne: + - rscadd: Re-adds 100% chance timed injectors, as it was removed over a misunderstanding. + - bugfix: Fixes bug with injectors having a 100% power chance despite not being + timed + - bugfix: Fixes the excessive amount of time it took the game to initialize. + - bugfix: Fixes some interface bugs. + - rscadd: when an interface window has to send a lot of resources before it can + open, it will now tell you with a "sending resources" line so you know why it's + not opening right away. + PKPenguin321: + - rscadd: Teleprods can now be constructed. Make them via tablecrafting, or by putting + a bluespace crystal onto a stunprod. They warp the target to a random nearby + area (which may include space/the inside of a wall) in addition to giving the + victim a brief stun. Like stunprods, they require a power cell to function. + - rscadd: Teleprods can have their crystal removed and be made back into stunprods + by using them in your hand when they have no cell installed. + - imageadd: Mounted chainsaws now have a unique inhand sprite. + Remie + Kor: + - tweak: Holopads now use AltClick to request the AI + Shadowlight213: + - tweak: Syndie melee mobs have been buffed. + TheNightingale: + - rscadd: Nuclear operatives can now buy the Elite Syndicate Hardsuit for 8 TC that + has better armor and fireproofing. + - tweak: Added throwing stars and Syndicate playing cards to nuclear operative's + uplink. + Yolopanther12: + - rscadd: Added the ability to use a box of lights on a light replacer to more quickly + refill it to capacity. + incoming5643: + - rscadd: OOC will now take steps to try and prevent accidental IC from people who + mistakenly use OOC instead of say. This doesn't catch all mistakes, so please + don't test it. + ktccd: + - bugfix: Blob pieces on some areas no longer count for blob mode victory (Such + as space or asteroid). + - bugfix: Blobcode no longer spawns and destroys blobs uselessly, which fixes other + stuff too. + - bugfix: Asteroid areas are no longer valid gang territory. + neersighted: + - experiment: Nanotrasen would like to announce NanoUI 2.0, now being rolled out + across all our stations. Existing NanoUI devices have been updated, and more + will be added soon. Please report any bugs to Nanotrasen Support. + - tweak: Many NanoUI interfaces have had +/- buttons replaced with input fields. + - tweak: Some NanoUI interfaces have had more information added. + - bugfix: Drones can now interact with NanoUI windows. + swankcookie: + - bugfix: Fixes issue of space-Christians forgetting about the true, humbling values + of space-Christmas. + - rscadd: Adds snowmen outfits +2015-11-30: + neersighted: + - bugfix: Nanotrasen would like to apologize for Chemistry being stuck on NanoUI + 1.0... Please report any further bugs to Nanotrasen Support. + - tweak: NanoUI becomes... difficult to operate with brain damage. Who would have + guessed? + - tweak: Telekinesis enables you to use NanoUI at a distance. + - bugfix: Canisters require physical proximity to actuate... + - bugfix: NanoUI no longer leaks memory on click. diff --git a/html/changelogs/archive/2015-12.yml b/html/changelogs/archive/2015-12.yml new file mode 100644 index 0000000000..81dde90a37 --- /dev/null +++ b/html/changelogs/archive/2015-12.yml @@ -0,0 +1,448 @@ +2015-12-01: + Kor: + - rscadd: The away mission Listening Post, originally mapped by Petethegoat, has + removed as a mission. It is now present in normal deep space. + neersighted: + - tweak: Attack animations are now directional! + - rscadd: Nanotrasen brand Airlock Electronics now sport our latest NanoUI interface! + Upgrade your electronics today! + - bugfix: Cryo now knocks you out. + - bugfix: Resisting out of cryo has a delay. + - rscadd: Cryo auto-ejection can now be configured. + - rscdel: Remove Cryo eject verb (resist out). + - bugfix: Cryo works... Love, neersighted + swankcookie: + - tweak: Switches cloak usage to overclothing slot +2015-12-02: + GunHog: + - bugfix: Nanotrasen has discovered a flaw in the weapon recharging station's design + that makes it incompatible with the Rapid Part Exchange Device. This has been + corrected. + neersighted: + - tweak: You can now stop pulling by trying to pull the same object again. + - rscadd: Nanotrasen is proud to announce that even the dead can use our state of + the art NanoUI technology. +2015-12-03: + Joan: + - rscadd: Artificers now have feedback when healing other constructs, showing how + much health the target has. + - tweak: Constructs can move in space. + - imageadd: Fixes cult flooring not lining up with normal floors. + - imageadd: Fixes a juggernaut back spine not glowing where it should. + Spudboy: + - tweak: Realigned the librarian's PDA. + Swankcookie: + - bugfix: Cakehat now creates light + YotaXP: + - rscadd: Rolled out a new line of space heaters around the station. This new model + has the functionality to cool down the environment, as well as heat it. Additionally, + they can be built and upgraded like any other machine. + neersighted: + - bugfix: Dominator now shows the correct area name on non-Box maps. + - bugfix: Unwrenching atmos pipes is less... nuts... + - bugfix: You don't get hopelessly spun when standing on a unwrenched pipe... Don't + try it, though. + - tweak: You can now cancel pulling by Ctrl+Clicking anything else + - tweak: Chemistry Dispensers now have a built-in drain! +2015-12-05: + Joan: + - rscdel: Magic missiles no longer do damage. +2015-12-06: + Gun Hog: + - rscadd: Nanotrasen is proud to announce that it has improved its Diagnostic HUD + firmware to include the station's automated robot population! New features include + integrity tracking, Off/On status, and mode tracking! If your little robot friend + suddenly manages to acquire free will, you will be able to track that as well! + - tweak: Artificial Intelligence units may find that their bot management interface + now shows when a robot gains free will. This is also displayed on the Personal + Data Assistant's bot control interface. + neersighted: + - bugfix: Cryo now properly checks it is on before healing... +2015-12-07: + octareenroon91: + - rscadd: Wallets now use the access of all IDs stored inside them. + - rscadd: As the accesses of all IDs are merged, two IDs in a wallet may grant access + to a door that neither one alone would open. + - bugfix: Wallets used to be useless for access if the first ID card put into it + was taken out, until another ID card was put back in. That should not happen + anymore. +2015-12-08: + Joan: + - experiment: Revenants can no longer move through walls and windows while revealed, + though they can move through tables, plastic flaps, mobs, and other similarly + thin objects. + - tweak: Defile now reveals for 4 seconds, from 8. + - tweak: Overload lights now reveals for 10 seconds, from 8. + - tweak: Blight now reveals for 6 seconds, from 8. + - rscadd: Blight has a higher chance of applying stamina damage to the infected. + Kor: + - rscadd: The blocking system has been completely overhauled. Any held item, exosuit, + or jumpsuit can now have a chance to block, or a custom on hit effect. Different + shields can now have different block chances. + - rscadd: The clowns jumpsuit now honks when you beat the owner. + - rscadd: There is a new (admin only for now) suit of reactive armour that ignites + attackers instead of warping you. + - rscadd: Shields will no longer block hugs. Give peace a chance. + neersighted: + - tweak: MC tab reworked, more items made available. + - rscadd: Admins can now click entries in the MC tab to debug. +2015-12-09: + GunHog: + - tweak: Nanotrasen has discovered new strains of Xenomorph which resist penetration + by known injection devices, including syringes. This seems to only extend to + the large 'Royal' strains, designed 'Queen' and 'Praetorian'. Extreme caution + is advised should these specimens escape containment. + - rscadd: Ghosts may now use Diagnostic HUD. + - tweak: Feedback added for which HUD is active. + Kor: + - rscadd: Security barricades now block gunfire 80% of the time while deployed. + - rscadd: Standing adjacent to barricades will allow you to shoot over them. + MrStonedOne: + - rscadd: noslip floors make you slightly faster + Shadowlight213: + - rscadd: Admins can now interact with mos of the station's machinery as if they + were an AI when ghosting. + incoming5643: + - rscadd: a mutation of glowshrooms, glowcaps, have recently been discovered in + botany. + ktccd: + - bugfix: Blobs now require the correct amount of blobs to win that scales depending + on number of blobs, instead of a set value of 700. +2015-12-12: + Joan: + - tweak: The blob Split Consciousness ability now requires a node under the overmind's + selector, instead of picking the oldest living node to spawn a core on. + - bugfix: Revenant antagonist preference can once again be toggled from the Game + Preferences menu. + Kor: + - rscadd: You now have a chance to flip while attacking with a dualsaber. + - rscadd: Bluespace survival capsules have been added to escape pod safes. + - rscadd: Standing between activating shield generators now has disastrous consequences. + Lo6a4evskiy: + - bugfix: Ninja drains power properly, no more infinite stealth. + RemieRichards: + - rscadd: Adds a Synth Species + - rscadd: Species can now react to being force set by admins, used for Synth species +2015-12-13: + Kor: + - rscadd: Adds reactive stealth armor. Admin spawn only. +2015-12-15: + Incoming5643: + - rscadd: The summon events... event "RPG loot" now allows for items to have bonuses + of up to +15! + - rscadd: The "RPG loot" event now also improves the damage reduction of armor! + - rscadd: Check out the item mall for new item fortification scrolls! + as334: + - rscadd: New research has shown that when when plasma reaches a high enough temperature + in the presence of a carbon catalyst, it undergoes a violent and powerful fusion + reaction. + - rscadd: Adds a new gas reaction, fusion. Heat up plasma and carbon dioxide in + order to produce large amounts of energy and heat. + oranges: + - tweak: hulk no longer stuns + - tweak: John Cena +2015-12-16: + AnturK: + - rscadd: Medical Beam Gun now available for Nuclear Operatives and ERT Medics. + Joan: + - tweak: Revenant Overload Lights reveal time lowered from 10 seconds to 8 seconds, + shock damage increased from 18 to 20. + - tweak: Revenant Blight reveal time lowered from 6 seconds to 5 seconds. + Kor: + - rscadd: Styptic once again works in patches. + - rscadd: Nuke Op team leaders can now activate challenge mode if more than 50 players + are online. + - rscadd: Xenobio mobs will no longer spontaneously murder their friends if you + give them sentience + The-Albinobigfoot: + - bugfix: The Wishgranter now displays its faith in humans with curbed enthusiasm. + Tkdrg: + - experiment: Cult has been overhauled in an attempt to make the gamemode more fun. + - rscdel: Cult onversion and stunpapers have been removed. So have most cult objectives. + - tweak: The cult's single objective is now defend and feed a large construct shell + in order to summon the Geometer. + - tweak: The cult must sacrifice souls in order to acquire summoning orbs, which + must be inserted inside said shell. + - tweak: The large construct shell can be procured by using a summoning orb in hand, + but it is vulnerable to attack. + - tweak: Once enough orbs are inserted, the station will go Delta. After three minutes, + the cult will have won. + - rscadd: Cult communications now no longer damage you when done without a tome. + - rscadd: Cultists now start with a sacrificial dagger, with bleeding effects and + high throwing damage. + - rscadd: Most existing runes were buffed, merged, or removed. A Immolate rune and + a Time Stop rune were added. Experiment! + - experiment: Each cultist now gets a random set of runes in their tomes. Pool together + your knowledge in order to thrive. + neersighted: + - experiment: NanoUI 3.0 + - experiment: Completely rewrite NanoUI frontend; rework backend. + - tweak: Re-design NanoUI interface to be much more attractive. + - tweak: Reduce NanoUI LOC count/resource size. + - tweak: Reduce NanoUI tickrate; make UIs update properly. + - rscadd: Add chromeless NanoUI mode. + - rscadd: NanoUI's chromeless mode can be toggled with the 'Fancy NanoUI' preference. + - bugfix: Allow NanoUI to work on IE8-IE11, and Edge. + - bugfix: Close holes that allow NanoUI href spoofing. +2015-12-17: + Kor: + - rscadd: Security barricades are now deployed via grenade. You can no longer move + them after they've been deployed, you must destroy them. + - rscadd: You can now shoot through wooden barricades while adjacent, while any + other gunfire has a 50% chance of being blocked. + - rscadd: There are no longer restrictions against implanting the nuclear disk in + people. + - rscadd: If the station is destroyed in a nuclear blast, any surviving traitors + will complete their "escape alive" objective regardless of their location. + - rscadd: Hulks now lose hulk when going into crit, rather than at 25 health. + - rscadd: Shuttles will no longer drag random tiles of space with them. This means + you can be thrown out of partially destroyed escape shuttles very easily. + - rscadd: The people and objects on destroyed tiles won't be along for the ride + when the shuttle moves either. + - rscadd: Adds hardsuits with built in energy shielding. CTF and security versions + are admin only. + - rscadd: Nuclear operatives can buy a shielded hardsuit for 30tc. + - rscadd: Traitors can now buy a Mulligan for 4 telecrystals, a syringe that completely + randomizes your name and appearance. + - rscadd: The spy bundle now includes a switchblade and Mulligan. + MMMiracles: + - rscadd: A set of coordinates have recently reappeared on the Nanotrasen gateway + project. Ask your local central official about participation. + MrStonedOne: + - tweak: 'Ghosts can now double click on ANY movable thing (ie: not a turf) to orbit + it' + PKPenguin321: + - rscadd: Dope golden necklaces have been added. They're a jumpsuit attachment like + ties and are completely cosmetic. + - rscadd: Dope necklaces can be bought from the clothesmate with a coin. Three are + in the clothesmate by default, so you can get your posse going. Gangs that aren't + Sleeping Carp can also purchase necklaces for 1 influence each. Dope. + xxalpha: + - tweak: Restores the ability to bolt and unbolt operating airlocks. +2015-12-18: + Incoming5643: + - rscadd: Soon to be blobs in blob mode can now burst at their choosing. However + they will still burst if they wait too long. + - rscadd: Burst responsibly. + Joan: + - rscadd: 'New blob chemicals:' + - rscadd: Pressurized Slime, which is grey, does low brute, oxygen, and stamina + damage, but releases water when damaged or destroyed. + - rscadd: Energized Fibers, which is light yellow, does low burn damage, high stamina + damage, and heals if hit with stamina damage. + - rscadd: Hallucinogenic Nectar, which is pink, does low toxin damage, causes vivid + hallucinations, and does some bonus toxin damage over time. + - tweak: Replaces Kinetic Gelatin with Reactive Gelatin, which does less brute damage, + but if hit with brute damage in melee, damages all nearby objects. + - wip: 'Changes three of the old blob chemicals:' + - tweak: Ripping Tendrils does slightly more stamina damage + - tweak: Envenomed Filaments no longer causes hallucinations, but does some stamina + damage in addition to toxin damage over time. + - tweak: Cryogenic Liquid will freeze targets more effectively. + Kor: + - rscadd: Shooting someone who is holding a grenade has a chance to set the grenade + off. + - rscadd: Shooting someone who is holding a flamethrower has a chance to rupture + the fuel tank. + - tweak: Shields have a bonus against blocking thrown projectiles. + Swankcookie: + - rscadd: lanterns no longer turn into flashlights when you pick them up. + bgobandit: + - rscadd: Lizard tails can now be severed by surgeons with a circular saw and cautery, + and attached the same way augmented limbs are. + - rscadd: The Animal Rights Consortium is horrified by Nanotrasen stations' sudden + rise of illegal lizard tail trade, with such atrocities as lizardskin hats, + lizard whips, lizard clubs and even lizard kebab! + neersighted: + - tweak: NanoUI should now load much faster, as the filesize and file count have + been reduced +2015-12-20: + Joan: + - tweak: Reduces Lexorin Jelly's oxygen damage significantly. + - experiment: Blobbernaut chemical application on attack is back, but much less + absurd this time; blobbernauts with an overmind will do 70% of the normal chem + damage(plus 4) and attack at a much slower rate than the blob itself can. + - wip: As an example, a blobbernaut with the Ripping Tendrils chemical would do + 14.5 brute and 10.5 stamina damage per hit. + Kor: + - rscadd: Adds reactive tesla armour. Adminspawn only. + - rscadd: Adds the legendary spear, Grey Tide. Admin only. + - rscadd: Nuke Ops can now purchase penetrator rounds for their sniper rifles. + - rscadd: Nuke ops can now purchase additional team members for 25 telecrystals. + They don't come with any gear other than a pistol however, so remember to save + some points for them. + - rscadd: Nuke Ops now have an assault pod. A 30tc targeting device will allow you + to select any area on the station as its landing zone. The pod is one way, so + don't forget your nuke. + - rscdel: The teleporter board is no longer available for purchase in the uplink. + - rscdel: After finding absolutely nothing of value, Nanotrasen away teams placed + charges and scuttled the abandoned space hotel. + - rscadd: Metastation now has xenobiology computers. + - rscadd: Metastation now has escape pod computers. + - rscadd: A distress signal has been detected broadcasting in an asteroid field + near Space Station 13. + - rscadd: Clicking the (F) follow link for AI speech will now make you orbit their + camera eye. + MMMiracles: + - tweak: The SAW has been revamped slightly. It now requires a free hand to fire, + but includes 4 new ammo variants along with a TC cost decrease for both the + gun and the ammo boxes. + MrStonedOne: + - bugfix: Fixes ghost orbit breaking ghost floating + - bugfix: Fixes orbiting ever breaking golem spawning + - bugfix: 'Fixes orbiting ever preventing that ghost from showing up in pictures + taken by ghost cameras resdel: Fixes being able to break your ghost sprite by + multiple quick consecutive orbits (FINAL SOLUTION, PROVE ME WRONG YOU CAN''T)' + Remie: + - rscadd: 'Byond members can now choose how their ghost orbits things, their choices + are: Circle, Triangle, Square, Pentagon and Hexagon!' + - tweak: orbit() should be much cheaper for clients now, allowing those of you with + potato PCs to survive mega ghost swirling better. + incoming5643: + - bugfix: the terror of double tailed lizards and featureless clones should now + be over + - rscdel: the emote *stopwag no longer works, just *wag again to stop instead +2015-12-21: + AnturK: + - tweak: Ghost HUD and Ghost Inquisitiveness toggles are now persistent between + rounds. + Kor: + - rscadd: Malfunctioning AIs have been merged with traitor AIs. They no longer appear + in their own mode. + - rscadd: Hacking APCs now gives you points to spend on your modules. Save up enough + points and you can buy a doomsday device on a 450 second timer. + - rscadd: The detectives revolver reskins on alt click now. + - rscadd: You can now dual wield guns. Firing a gun will automatically fire the + gun held in your off hand if you are on harm intent. + LanCartwright: + - tweak: The TC costs for nuke ops have been rebalanced. Guns, viscerators and mechs + are cheaper, ammo and borgs are more expensive. + - rscadd: Most guns can now be bought in bundles, together with some ammo and freebies + for a special discount. + The-Albinobigfoot: + - rscadd: Nuclear Operative families may once again requisition ultra-adhesive footwear. +2015-12-22: + Iamgoofball: + - rscadd: Tesla engine has been added alongside the singularity engine to all maps. + Joan: + - wip: 'Adds three new blob chemicals:' + - rscadd: Replicating Foam, which is brown, does brute damage, has bonus expansion, + and has a chance to expand when damaged. + - rscadd: Sporing Pods, which is light orange, does low toxin damage, and has a + chance to produce weak spores when expanding or killed. + - rscadd: Synchronous Mesh, which is teal, does brute damage and bonus damage for + each blob tile near the target, and splits damage taken between nearby blobs. + - experiment: Synchronous Mesh blobs take 25% more damage, to compensate for the + spread damage. + Kor: + - rscadd: Cayenne will no longer be targeted by the syndicate turrets. + - tweak: Energy shields now only reflect energy projectiles. + - rscadd: Added accelerator sniper rounds to uplink, a weak projectile that ramps + up damage the farther it flies. + MMMiracles: + - bugfix: Saber magazines have been dropped to 21 per magazine. When asked, Nanotrasens + official ballistic department replied "There is indeed such a thing as too much + bullet." + Xhuis: + - tweak: Stun batons can now be blocked by shields, blocked hits don't deduct charge. + xxalpha: + - rscadd: Janitor cyborgs now have a bottle of drying agent. +2015-12-25: + Joan: + - rscdel: The blob Split Consciousness ability has been removed. + - tweak: The blob mode now spawns more roundstart blobs, instead. + Kor: + - rscadd: AI holograms no longer drift in zero gravity + LanCartwright: + - tweak: Shotguns shells now have one extra pellet. + MrStonedOne: + - bugfix: Screen shakes will no longer allow you to see through walls + - tweak: Screen shakes will now move with you when moving rather than lag your client + behind your mob + - tweak: Screen shakes are now less laggy in higher tickrates +2015-12-26: + Buggy123: + - tweak: Salicyclic Acid now rapidly heals severe bruising and slowly heals minor + ones. + Iamgoofball: + - tweak: Telsa energy ball now shoots only a single, powerful beam of lightning + that can arc between mobs. + - soundadd: Energy ball can now be heard when near-by. + Incoming5643: + - tweak: Animated objects now revert if they have no one to attack for a while. + - rscadd: Added Golden revolver, a powerful sounding gun with large recoil. + Kor: + - rscadd: Transform Sting is now actually functional. + MrStonedOne: + - tweak: Movement in no gravity now allows you to push off of things only dense + to some mobs if it is dense to you (such as tables/blob tiles) rather than just + objects that are only dense to all mobs. + - bugfix: Long/timed actions will now cancel properly if you move and quickly move + back to the right location. +2015-12-27: + Joan: + - rscadd: Overmind-created blobbernauts are now player-controlled if possible. + - tweak: Creating a blobbernaut no longer destroys the factory, instead doing heavy + damage to it and preventing it from spawning spores for one minute. + - tweak: You cannot spawn blobbernauts from overly damaged factories. + - rscadd: Procedure 5-6 may be issued for biohazard containment under certain situations. + - tweak: Blobs will now burst slightly later on average, and the nuke report with + the nuke code will arrive slightly earlier. + Kor: + - soundadd: Spacemen now announce when they are changing magazines. + - rscadd: Command headsets now have a toggle to let you have larger radio speech. + LanCartwright: + - rscdel: The Syndicate Ship no longer spawns with Bulldog shotguns, operative have + been given 10 extra telecrystals instead. + MrStonedOne: + - bugfix: Flashes that were emp'ed were incorrectly flashing people in range of + the emper, not in range of the flash. + - tweak: Flashes in a mob's inventory that are emp'ed will only aoe stun if it is + not inside of a container like a backpack/box +2015-12-28: + AnturK: + - rscadd: You can now write an entire word with crayons by setting it as a buffer + and then clicking the target tiles in the right order. + Joan: + - rscdel: Blobbernauts can no longer smash walls of any type. + MrStonedOne: + - tweak: Progress bars now have 20 states instead of 5. + - bugfix: Bump mining should be fixed. + - tweak: Long actions now checks for movement/changed hands/etc more often to prevent + edge cases. + - tweak: Multiple progress bars will now stack properly, rather than fight each + other for focus. + Ressler: + - rscadd: Adds the reagent Haloperidol. + - rscadd: It is an anti-drug reagent, good for stopping assistants hyped up on meth, + bath salts, and equally illegal drugs. + - rscadd: It can be made with Chlorine, Fluorine, Aluminum, Potassium Iodide, and + Oil. + neersighted: + - bugfix: Make NanoUIs transfer upon (un)ghosting. + - bugfix: Fix NanoUIs jumping when resized/dragged. + - bugfix: Lots of other NanoUI bugs. +2015-12-31: + Bawhoppen: + - rscadd: Nanotrasen has opened the availability of tactical SWAT gear to station's + cargo department + - rscadd: Due to a new trade agreement with Chinese space suit manufacturers, Nanotrasen + can now obtain basic space suits much cheaper; This has been reflected in the + cargo prices + - rscadd: Amateur medieval enthusiasts have found a quick way to easily make wooden + bucklers. + Joan: + - imageadd: Replaced every book sprite in the game with new, consistent versions. + - imageadd: Except the one-use wizard spellbooks, which already got new sprites. + PKPenguin321: + - rscadd: Chest implants have been added that allow you to morph your arms into + a gun and back at will. There are two variants, a taser version and a laser + version. Both versions are self-charging. Getting EMPed with one of these implants + results in the implant breaking and loads of fire damage. The implants are currently + admin-only. + - tweak: The telecrystal price for thermal imaging goggles has been lowered from + 6 to 4. + incoming5643: + - rscadd: The wizard federation has finally updated their assortment of guns for + the summon guns event. Look forward to getting shot in the face with a whole + new batch of interesting and rarely seen weaponry! diff --git a/html/changelogs/archive/2016-01.yml b/html/changelogs/archive/2016-01.yml new file mode 100644 index 0000000000..9725d48765 --- /dev/null +++ b/html/changelogs/archive/2016-01.yml @@ -0,0 +1,204 @@ +2016-01-01: + Iamgoofball: + - experiment: Redid how objectives are assigned, they're now a lot more random in + terms of what you can get. + Incoming5643: + - tweak: Removed gender restrictions from socks. + Joan: + - rscdel: Storage Blobs are gone; they were effectively a waste of resources, as + there are more or less no points at which you should need them, unless you were + winning excessively hard. + - rscdel: Blobs can no longer burst early; instead, the button gives some early + help and serves to indicate you're a blob. + - wip: Blobbernauts now poll candidates instead of grabbing a candidate immediately. + The poll is 5 seconds, so that there's no significant pause between making a + blobbernaut and it doing stuff. + - rscadd: Blobbernaut creation replaces Storage Blob creation on the blob HUD. + - tweak: Overmind communication is now much larger and easier to see, and blob mobs, + such as blobbernauts, will hear it. + Kor: + - rscadd: The wizard has a new spell, Lesser Summon Guns. This summons an unending + stream of single shot bolt action rifles into his hands, automatically replacing + themselves as you fire. + - bugfix: Fixes successive generations of grey tide clones not despawning. + - tweak: Using challenge ops now delays shuttle refuel. + - rscadd: Added a new wizard event, Advanced Darkness. + MrStonedOne: + - experiment: GHOST POPUP RE-WORK + - bugfix: Ghost popups will no longer steal focus + - bugfix: Ghost popups will no longer submit on key press (regardless of focus) + unless you tab to a button first + - tweak: Ghost popups will close themselves after the time out has ended + - rscadd: Ghost popups are now themed. + - tweak: Long actions (like resisting out of handcuffs) will no longer count space/nograv + drifting as the user moving. + - tweak: This does not apply to the target of a long action if that target isn't + you. Pulling something while space drifting and working on it intentionally + won't work. +2016-01-02: + Kor: + - rscadd: Guardians/Parasites are now named after constellations, and have new sprites + from Ausops. + Kor and GunHog: + - rscadd: Malfunctioning AIs can now purchase Enhanced Surveillance for 30 points, + which allows them to "hear" with their camera eye. + MMMiracles: + - rscadd: A distress signal was recently discovered with gateway coordinates attached + to a far-off research facility owned by Nanotrasen. The signal was sent out + in hopes of someone competent receiving it, unfortunately, your station was + the only one to respond. Local security forces may not be welcoming your arrival + group with open arms. +2016-01-07: + KorPhaeron: + - tweak: Doubled cost of Lesser Summon Guns to 4 and increased charge time to 75 + seconds. + TrustyGun: + - rscadd: 'Added two new UI styles: black and green Operative and pale green Slimecore.' +2016-01-09: + Wjohnston: + - wip: AI Satellite has been remapped to make it more secure. +2016-01-11: + Joan: + - rscdel: Blob cores and nodes no longer cause normal pulsed blobs to animate. Factories + and resource nodes will still animate. + - imageadd: Holoparasite sprites have been updated again, are now named after silvery + metals and flowers and can also be colored purple, blue or yellow. + xxalpha: + - tweak: Pipes and cables under walls, intact floors, grilles and reinforced windows + will now be shielded from explosions until exposed. +2016-01-13: + Joan: + - imageadd: Alien whisper ability has a new icon + MrStonedOne: + - tweak: Control clicking on the thing you are pulling will no longer unpull, instead + control clicking on anything too far away to be pulled will unpull. (reminder + that the delete key also unpulls) + OneArmedYeti: + - imageadd: To help with colorblindness, gang HUDs have been changed so leaders + have a border and normal gangster icons are smaller. +2016-01-15: + Joan: + - bugfix: Holoparasites can no longer beat their owner to death while inside of + them. + - spellcheck: Updates traitor holoparasite descriptions for accuracy. + - spellcheck: Adds 8 additional silvery metals to the holoparasite name pool. + - imageadd: Adds two new holoparasite colors, light purple and red. + - imageadd: Holoparasite HUD buttons now have new sprites. + - imageadd: Adds glow effects when guardians teleport or recall, including fire + guardian teleporting and support guardian teleporting. + Kor: + - rscadd: Washing machines are activated via alt+click rather than a right click + verb. +2016-01-16: + Joan: + - imageadd: Alien queens and praetorians have suitably large speechbubbles. + - imageadd: Syndicate cyborgs and syndrones have suitably evil robotic speechbubbles. + - imageadd: Blob mobs have suitably uncomfortable-looking speechbubbles. + - imageadd: Holoparasites and guardians have suitably robotic and magical speechbubbles. + - imageadd: Swarmers have suitably holographic speechbubbles. + - imageadd: Slimes have suitably slimy speechbubbles. +2016-01-17: + Joan: + - bugfix: You can once again repair a hacked APC by using an APC frame on it instead + of welding it off the wall, at the same stage as you'd weld it off the wall. + MrStonedOne: + - bugfix: Control clicking on a turf now un-pulls +2016-01-19: + neersighted: + - rscadd: Many many interfaces have been ported to tgui; uplinks and MULEbots being + the most important + - rscadd: You can now tune radios by entering a frequency + - bugfix: Air Alarms now support any gas +2016-01-23: + neersighted: + - experiment: Refactor wires; port wire interface to tgui. + - rscadd: Wire colors are now fully randomized. + - rscdel: Remove pizza bombs, as the code and sprites were terrible. + - rscadd: Add pizza bomb cores, which can be combined with a pizza box to make a + pizza bomb. + octareenroon91: + - bugfix: Chemistry machinery should now all equally accept beakers, drinking glasses, + etc. +2016-01-27: + Joan: + - tweak: Golems have about a 40% chance to stun with punches, from about 60%. + - tweak: Millitary Synths have about a 50% chance to stun with punches, from literally + 100%. + - wip: Blobbernaut creation costs 30 points, and does much more damage to the factory. + - rscdel: Blob factories regenerate at half normal rate. + - tweak: Blob reagents tweaked; + - rscadd: Ripping Tendrils does slightly more brute damage, but less stamina damage. + - rscdel: Lexorin Jelly does less brute damage. + - rscadd: Energized Fibers does slightly more burn damage. + - rscadd: Sporing Pods does slightly more toxin damage. + - rscadd: Replicating Foam will try to replicate when hit more often. + - rscadd: Hallucinogenic Nectar does slightly more toxin damage and causes hallucinations + for longer. + - rscadd: Cryogenic Liquid does more burn damage. + - experiment: Synchronous Mesh does slightly less damage with one blob but massive + damage with more than one nearby blob. + - rscdel: Dark Matter does less brute damage. + - rscdel: Sorium does slightly less brute damage. + - rscdel: Pressurized Slime has a lower chance to emit water when killed and when + attacking targets. + - tweak: Supermatter explosion is no longer capped, and under normal conditions + will produce a 8/16/24 explosion when delaminating. + - imageadd: Blob tiles now do an attack animation when failing to expand into a + turf. + - imageadd: Overmind-directed expansion is more visible than automatic expansion. + Kor: + - rscadd: Capture the flag has been added in space near central command. The spawners + are disabled by default, so be sure to harass admins when you die until they + let you play. The arena was mapped by Ausops. + - rscadd: Nuke ops can purchase mosin nagants for 2 telecrystals. + MrStonedOne: + - bugfix: Fixes the powersink drawing less power than the smeses put out. + - tweak: Made the powersink hold significantly more power before overloading and + going boom. + - tweak: Buffed the explosion of the power sink when it overloads. You are suggested + to think twice about wiring the engine to the grid. + PKPenguin321: + - rscadd: The Autoimplanter, a device that can insert cyberimplants into humans + instantly and without the need of surgery, has been added to the game. It is + currently only obtainable by nuke ops, by way of being included in the Box of + Implants. +2016-01-28: + Joan: + - rscadd: Blobs can communicate before bursting to allow for more coordination. + Kor: + - rscadd: Butchering mobs by attacking them with sharp objects will only happen + on harm intent. This means it is possible to do surgery on aliens again. +2016-01-29: + Joan: + - rscadd: Holoparasites can now see their summoner's health at all times. The health + displayed is a percentage, with 0 being dead. + - imageadd: Holoparasites now have visual flashes on the summoner's location when + recalled due to range limits and when manifesting. + Kor: + - rscadd: Red xenobio potions now work on vehicles (janitor cart, ATV, secway, etc), + causing them to go faster. + - rscadd: Stuffing people in bins uses clickdrag instead of grab. +2016-01-30: + Boredone: + - tweak: Due to an experiment gone wrong, the Research Director's Teleport Armor + now causes some mild radiation poisoning on teleportation to the wearer. + Francinum: + - rscadd: Added two new female underwear styles. + Kor: + - rscadd: You can now use the abandoned white ship as an escape route at round end. + This is possible on Box, Meta, and Dream. + - rscadd: Added support so that mappers can make any shuttle function as an escape + shuttle. + MMMiracles: + - rscadd: Three new bra sets have been added for the ladies out there who want to + show their patriotism. + xxalpha: + - rscadd: Blueprints will now allow the expansion of an existing area by giving + its name to a new adjacent area. + - rscadd: Added a no power warning cyborg verb to Robot Commands. +2016-01-31: + Kor: + - rscadd: Added a special AI upgrade disk that allows normal AIs to use malf modules + and hack APCs. It is admin only. + - rscadd: Added an AI upgrade disk that grants AIs the lipreading power. It is admin + only. diff --git a/html/changelogs/archive/2016-02.yml b/html/changelogs/archive/2016-02.yml new file mode 100644 index 0000000000..db6bf9b284 --- /dev/null +++ b/html/changelogs/archive/2016-02.yml @@ -0,0 +1,350 @@ +2016-02-01: + Erwgd: + - rscadd: The Kitchen Vending machine now stocks salt shakers and pepper mills! + - rscadd: The NutriMax now stocks spades, cultivators and plant analyzers. + - rscadd: Rice seeds are now stocked in the MegaSeed Servitor, and the seeds supply + crate now contains a pack of rice seeds. + - rscdel: Botanists should be aware that wheat stalks can no longer mutate into + rice. + Fayrik: + - rscadd: pAI cards can now be inserted into simple robots, to allow for more robust + robot personalities. + PKPenguin321: + - rscadd: You can now store knives, pens, switchblades, and energy daggers in certain + types of shoes (such as jackboots, workboots, winter boots, combat boots, or + no-slips). + - rscadd: Horns can now be stored in clown shoes. Honk. + TrustyGun: + - rscadd: Adds gag handcuffs to the prize pool for arcade machines. They act like + regular handcuffs, but you break out of them in a second. + WJohnston: + - rscadd: Adds missing booze & soda dispenser, library console, fixes door access + and a few other minor things to Efficiency Station + - rscadd: Also adds direction tags so people can find their way around better. + bgobandit: + - rscadd: On Valentine's Day, all spacemen will receive candy hearts and valentines + for their special someones! Label valentines with a pen. + - rscadd: Note that today is not Valentine's Day. +2016-02-05: + Joan: + - experiment: Blob expansion is faster near the expanding blob, but slower further + away from it. + - tweak: Blob spores produce a slightly larger smoke cloud when dying. Sporing Pods + spores and blob zombies produce the current small cloud. + - rscdel: Blobbernauts can no longer pull anything at all. + - tweak: Blobbernauts health reduced to 200, but blobbernauts now take half brute + damage. + - tweak: Blobbernauts now take massive damage from fire. + - tweak: Blobbernauts do approximately 3 more damage when attacking. + - wip: Replicating Foam will expand more actively when damaged. + - rscadd: Adds Electromagnetic Web, which is light blue, does burn damage and EMPs + targets, and causes a small EMP when dying. + - rscadd: Electromagnetic Web takes more damage; a normal blob that hasn't been + near a node or the core for 6~ seconds can be oneshotted by a laser. + - rscadd: Anomalies, such as pyroclastic and vortex anomalies, now appear at the + bottom of the ghost orbit and observe menus. + Kor: + - rscadd: Nuke ops can purchase sentience potions for 4tc + MMMiracles: + - tweak: Bulldog now starts with stun-slugs instead of its usual 60-brute slugs. + Slugs now cost 3 TC instead of 2. + - tweak: Most SAW ammo has been slightly buffed in damage so maybe it'll be worth + buying now along with a slight cost decrease for the gun itself. + - tweak: Incen shells for the shotgun now apply extra firestacks on hit so it actually + sets people on fire instead of turning them into a light show. + - tweak: Incen rounds for the SAW now leave a fire trail similar to the bulldog's + dragonsbreath round. + - rscadd: Nuke Ops now have the ability to purchase breaching shells, a weaker variant + of the meteorslugs that can still push back people/airlocks/mechs/corgis. + - bugfix: SAW should now use its in-hand sprites for an open-closed magazine + PKPenguin321: + - rscadd: You can now sharpen carrots into shivs by using a knife or hatchet on + them. + bgobandit: + - rscadd: Seven new emoji have been added to hasten the death of the English language. + octareenroon91: + - rscadd: Player-controlled medibots can examine a patient to know what chems are + in the patient's body. + - bugfix: autolathes have been showing extra copies of the hacked designs, but no + more. +2016-02-06: + LordPidey: + - rscadd: Added suicide command for pipe valves. It's quite messy. + Lzimann: + - tweak: Combat Mechas now have a increased chance of destroying a wall with punches + (40% for walls and 20% for reinforced walls)! + - rscadd: Combat mechas can now destroy tables and racks with a punch! + neersighted: + - rscadd: The Syndicate has stolen the latest tgui improvements from Nanotrasen! + All uplinks now feature filtering/search. + - rscadd: Nanotrasen is proud to announce its next generation sleepers, featuring + tgui! + - rscadd: Portable atmospheric components have been overhauled to use the latest + interface technology. + - rscdel: The Area Atmosphere Computer has been removed. + - rscadd: Huge scrubbers now require power. + - rscdel: Borg jetpacks are now refilled from a recharger and not a canister. + - rscadd: Power monitors now have a state of the art graph. Hopefully they're actually + useful to someone. + - rscadd: Cargo consoles have been redesigned and now feature search and a shopping + cart! +2016-02-08: + Incoming5643: + - rscadd: Poly will now speak a line or emote when pet. + - rscadd: Poly now responds to getting fed crackers by becoming more annoying for + the round. + - experiment: Every day he is growing stronger + Kor: + - rscadd: A certain hygiene obsessed alien is now obtainable via xenobiology gold + cores. + - rscadd: Add laserguns with swappable, rechargeable magazines. They are adminspawn + only. + - rscadd: Operatives now get their pinpointers in their pocket when they spawn, + meaning reinforcements automatically come with them (and hopefully people stop + forgetting them in general). + - rscadd: Capture the flag now features a high speed instagib mode, with guns courtesy + of MMMiracles. + phil235: + - tweak: The vision updates for mobs are now instantaneous (e.g. you don't have + to wait one second to see again when removing your welding helmet) + - tweak: Your vision is now affected when you're inside something or viewing through + a camera. You can no longer see mobs or objects when ventcrawling (unless you + have xray for example), an xray user viewing through a camera do not see through + walls around the camera. On the other hand, cameras with an xray upgrade let + you see through walls. Unfocused camera now give you the same effect as when + you are nearsighted. Being inside closets, morgue container and disposal bins + give you some vision impairments. + - rscadd: The ability to toggle your hud on and off (with f12) is now available + to all mobs not just humans. +2016-02-09: + AnturK: + - rscadd: Syndicate Operatives can now buy bags full of plastic explosives for 9 + TC. + Gun Hog: + - rscadd: '"Nanotrasen has drafted a design for an exosuit version of the medical + nanite projector normally issued to its Emergency Response Personnel. With sufficient + research, a prototype may be fabricated for field testing!"' + incoming5643: + - rscadd: The wizard spell wild shapeshift has been made less terrible. + neersighted: + - rscadd: Internals tanks now provide an action button + - rscadd: Jetpacks now emit the gas consumed for propulsion onto their turf + - rscdel: Jetpacks no longer have object verbs + - rscdel: tgui no longer has internals buttons + - bugfix: Malf AI's flood ability now correctly sets vent pressure bounds -- the + results are devastating... Try it! +2016-02-10: + Joan: + - rscadd: Blob mobs now heal for 2.5% of their maxhealth when blob_act()ed, basically + whenever they're on blobs near a node or the core. + - tweak: Blob expansion no longer has a chance to fail inversely proportional with + the expanding blob's health. Blobs still, however, expand at roughly the same + rate as they do currently. + - experiment: Adds five new blob chemicals. + - rscadd: Adds Penetrating Spines, which is sea green and does brute damage through + armor. The damage can still be reduced by bio protection. + - rscadd: Adds Explosive Lattice, which is dark orange and does brute damage to + all mobs near the target. Explosive Lattice is very resistant to explosions. + - rscadd: Adds Cyclonic Grid, which is a light blueish green and does oxygen damage, + in addition to randomly throwing or pulling nearby objects. + - rscadd: Adds Zombifying Feelers, which is a fleshy zombie color and does toxin + damage, in addition to killing and reviving unconscious humans as blob zombies. + - rscadd: Adds Regenerative Materia, which is light pink and does toxin damage, + in addition to making the attacked mob think it is at full health. + - wip: Tweaks some of the existing blob chemicals slightly. + - rscadd: Sporing Pods can produce spores when killed by damage less than 21, from + less than 20. This means lasers can produce spores. + - rscadd: Reactive Gelatin has a slightly higher maximum damage and will attack + the nearby area when hit with brute damage projectiles, from just when attacked + by brute damage in melee. + - tweak: Sorium, Dark Matter, and the new Cyclonic Grid will not throw mobs with + the 'blob' faction, such as blobbernauts and spores. + Kor: + - rscadd: The chaplain can now transform the null rod into a holy weapon of his + choice by using it in hand. Each one has different strengths and drawbacks. + MrStonedOne: + - tweak: Tesla balance changes + - tweak: Tesla will now require increasingly more energy to trigger new orbiting + balls. First ball comes with 32 energy (down from 300), fourth requires 256 + (down from 1200), and so on and on, doubling with each new ball. Balls after + 7 are increasingly harder to get than before, whereas balls before 6 are easier + to get. + - rscadd: MULTIBOLT IS BACK! + - tweak: Be warned that in multibolt all but 1 primary bolt now have a random shocking + range, meaning they may still target a close human over a far away grounding + rod as the rod may be out of range. + - tweak: Power output of tesla massively dropped, it should no longer put out almost + twice the power of a stage 3 singulo with maxed collectors without any balls, + you'll need at least 3 balls for that now. + - tweak: Tesla can now lose power, causing ball count to drop. Tesla will never + shrink out of existence, just lose its balls. + - tweak: Tesla is now more likely to head in the direction of the thing it last + zapped. + PKPenguin321: + - rscadd: Chameleon Jumpsuits now have slight melee, bullet, and laser protection. + - tweak: The armor values for security helmets, caps, and berets have all been brought + in line. Consequently, helmets and berets are a teeny bit better, and caps now + have the slight bomb protection that the other two had. + - experiment: The time needed to complete most tablecrafting recipes has been cut + in half to make tablecrafting less annoying to use. + Shadowlight213: + - rscadd: pAI controlled mulebots can now run people over. + - tweak: Mulebot health has been greatly decreased. + neersighted: + - rscadd: Horizontal (lying) mobs now fit into crates + - rscadd: Mobs may now be stuffed into crates, as with lockers + - rscadd: Stuffing into a locker deals a mild stun (the same as tabling) + octareenroon91: + - rscadd: New designs can now be added to Autolathes via a design disk. Simply use + a disk containing a suitable design on your autolathe. +2016-02-11: + neersighted: + - rscdel: Remove all cyborg jetpacks... They were awful... + - rscadd: Adds borg ion thrusters, which are available as an upgrade module for + any borg. + - rscdel: Jetpack stabilizers are always on, but now we have... + - rscadd: Jetpack turbo mode, to move at sanic speed in space. +2016-02-12: + Kor: + - rscadd: Malf AIs can now get the objective to have a robot army by the end of + the round. + - rscadd: Malf AIs can now get the objective to ensure only human crew (no mutants) + are on the shuttle at round end. + - rscadd: Malf AIs can now get the objective to prevent a crewmember from escaping + the station, while requiring that crewmember still be alive. + neersighted: + - rscadd: Cybernetic implants purchased from the uplink now include a free autoimplanter! + octareenroon91: + - rscdel: You can no longer kill yourself with the SORD + - rscadd: Suicide attempts with the SORD will inflict 200 stamina damage. You will + only die of shame. + - bugfix: Cleanup to suicide verb code. +2016-02-13: + Buggy123: + - rscadd: You can now build cable coils using the autolathe. + Fox McCloud: + - bugfix: Fixes the sleeping carp martial arts grab not being an instant aggressive + grab + KazeEspada: + - rscadd: 'New backpack options available! New options include: Department Bags, + Leather Satchels, and Dufflebags!' + Kor: + - rscadd: Chainsaw sword, force weapon, and war hammer have all been added as Chaplain + weapon options. + Malkevin: + - tweak: Tracking implants have been upgraded. The old clunky manually adjusted + number system has been replaced with an automated ID scanner, this will show + the implant carrier's name on both the Prisoner Management Console and the hand + tracker. Happy deep striking! + PKPenguin321: + - tweak: 'Traitor EMP kits have had their cost reduced from 5 to 2, and no longer + contain the EMP flashlight. rcsadd: EMP flashlights can now be bought separately + for 2 TCs.' + Zerrien: + - rscadd: Conveyor pieces can be placed as corner pieces when building in non-cardinal + directions. + - rscadd: Using a wrench on a conveyor rotates it while in place. + neersighted: + - tweak: Gibtonite can now be pulled. + - tweak: Slowdown factors are ignored when in zero gravity. + phil235: + - rscadd: Brains can no longer be blinded. + - bugfix: Fixes brain being immortal. They are immune to everything but melee weapon + attacks. Brains not inside a MMI can now be attacked just like MMIs. Damaged + brain can't be put into a robot, they can still be put inside a brainless humanoid + corpse and cloned, but deffibing the corpse always fails (can't revive someone + with a brain beaten to a pulp). +2016-02-14: + Joan: + - rscadd: Blobbernauts can now speak to overminds and other blobbernauts with :b + - rscadd: Blobs can now expand onto lattices and catwalks. + - rscdel: Blob expansion on space tiles with no supports is much slower. + - tweak: Blob Sorium and Dark Matter now have less range on targets with bio protection. + - tweak: Blob Sorium does slightly less damage. +2016-02-17: + Fox McCloud: + - tweak: Laser eyes mutation no longer drains nutrition + Joan: + - rscdel: The sleeping carp gang no longer has special equipment and an inability + to use pneumatic cannons. + PKPenguin321: + - tweak: The traitor surgery bag now costs 3 TC, down from 4. + Zerrien: + - rscadd: adds unique icons for the two medical patch types +2016-02-18: + Kor: + - rscadd: 'Four more chaplain weapon options have been added: hanzo steel, light + energy sword, dark energy sword, and monk''s staff.' +2016-02-19: + AnturK: + - rscadd: Chairs and stools can now be picked up and used as weapons by dragging + them over your character. + PKPenguin321: + - rscadd: The cleanbot uprising has begun. + - rscadd: Emagged cleanbots are much scarier now. Standing on top of one will yield + very devastating results, namely in the form of powerful flesh-eating acid. +2016-02-20: + CPTANT: + - tweak: Due to new crystals Nanotrasen lasers weapons may now set you on FIRE. + Joan: + - imageadd: Blobbernauts and blob spores now have a visual healing effect when being + healed by the blob. + xxalpha: + - rscadd: 'New event: Portal Storm.' + - rscadd: Kinetic accelerators now reload automatically. +2016-02-24: + CPTANT: + - tweak: stamina regeneration is now 50% faster. + Joan: + - rscadd: Revenants now have an essence display on their HUD + - rscadd: Revenants retain the essence cap from the previous revenant when reforming, + minus any perfect souls. + - rscadd: Revenants can now toggle their night vision. + - tweak: Revenant Defile has one tile more of range, but does less damage to windows. + - tweak: Revenant Blight kills space vines and glowshrooms slightly more rapidly. + - tweak: Delays before appearing when harvesting are slightly randomized. + - tweak: Revenant fluff objectives have been changed to be slightly more interesting. + RemieRichards: + - rscadd: Cursed heart item for wizards, allows them to heal themselves in exchange + for having to MANUALLY beat their heart every 6 seconds. Heals 25 brute/burn/oxy + damage per correctly timed pump. + Steelpoint: + - tweak: Syndicate engineers have reinforced the exterior of their stealth attack + ships. Nuclear Operative ship hull walls are now, once again, indestructible. + - tweak: In addition Syndicate engineers had the opportunity to revamp the interior + of stealth attack ships. The inside of Op ships now has a slightly new layout, + including a expanded medbay, as well as additional medical and explosive equipment. + - rscadd: Thanks to covert Syndicate operatives, strike teams can now bring the + stealth attack ship within very close proximity to the station codenamed 'Boxstation'. + A new ship destination labeled 'south maintenance airlock' is now available + to Op strike teams. + phil235: + - rscadd: Holo tape is replaced by holo barriers. + - rscadd: The action button of gas tanks and jetpacks now turn green when you turn + your internals on. +2016-02-26: + Iamgoofball: + - rscadd: Adds the Chameleon Kit to uplinks for 4 telecrystals containing a Chameleon + Jumpsuit/Exosuit/Gloves/Shoes/Glasses/Hat/Mask/Backpack/Radio/Stamp/Gun/PDA. + - rscadd: The chameleon gun fires no-damage lasers regardless of what it looks like. + - rscadd: The Voice Changer has been merged into the Chameleon Mask. + - rscadd: No-slip shoes have been combined into Chameleon Shoes. + - rscdel: Space Ninjas no longer have voice changing capabilities. + - rscdel: The Chameleon Jumpsuit has been replaced by the Chameleon Kit in the uplink + for the same price. + - tweak: All chameleon clothing items have lost EMP vulnerability. + - tweak: Chameleon equipment provides very minor armor. + - experimental: Agent ID Cards can now use chameleon technology to look like any + other ID card. + - bugfix: The Chameleon Kit is actually purchasable now. It doesn't give a single + chameleon jumpsuit anymore. + PKPenguin321: + - rscadd: The kitchen vendor now contains two sharpening blocks. + - rscadd: Only items that are already sharp (such as fire axes, knives, etc) can + be sharpened. Items used on sharpening blocks become sharper and deadlier. The + sharpening blocks themselves can only be used once, and you can only sharpen + items once. + - tweak: The EMP kit has been buffed. It now contains five EMP grenades, up from + two. + - tweak: The EMP implant found in the EMP kit has been buffed. It now has three + uses, up from two. diff --git a/html/changelogs/archive/2016-03.yml b/html/changelogs/archive/2016-03.yml new file mode 100644 index 0000000000..f5d766b79a --- /dev/null +++ b/html/changelogs/archive/2016-03.yml @@ -0,0 +1,566 @@ +2016-03-02: + CoreOverload: + - rscadd: A new "breathing tube" mouth implant. It allows you to use internals without + a mask and protects you from being choked. It doesn't protect you from the grab + itself. + - tweak: Arm cannon implants are now actually implanted into the arms, not into + the chest. + - bugfix: Arm cannons have an action button again. + - tweak: Heart removal is no longer instakill. It puts you in condition similar + to heart attack instead. You can fix it by installing a new heart and applying + defibrillator if it wasn't beating. + - rscadd: You can now make a stopped heart beat again by squeezing it. It will stop + beating very soon, so you better be quick if you want to install it without + using defibrillator. + - rscadd: There is now a chance to recover some of the internal organs when butchering + aliens or monkeys. + - rscadd: A new organ - lungs. When removed, it will give you breathing and speaking + troubles. + - rscadd: Human burgers are, once again, named after the generous meat donors that + made them possible. + Fox McCloud: + - rscadd: Gibbing mobs will now throw their internal organs + Gun Hog: + - rscadd: Ghost security HUDs now show arrest status and implants. + - tweak: The Alien queen, upon her death, will now severely weaken the remaining + alien forces. + Joan: + - tweak: Replicating Foam has a lower chance to expand when hit. + - tweak: Penetrating Spines is now purple instead of sea green. + - imageadd: Blobbernauts now have a brief animation when produced. + - experiment: Adds five new blob chemicals. This is a total of 25 blob chemicals. + Will it ever stop? + - rscadd: Draining Spikes, which is reddish pink and does medium brute damage, and + drains blood from targets. + - rscadd: Shifting Fragments, which is tan and does medium brute damage, and shifts + position when attacked. + - rscadd: Flammable Goo, which is reddish orange and does low burn and toxin damage, + and when hit with burn damage, emits a burst of flame. It takes more damage + from burn, though. + - rscadd: Poisonous Strands, which is lavender and does burn, fire, and toxin damage + over a few seconds, instead of instantly. + - rscadd: Adaptive Nexuses, which is dark blue and does medium brute damage, and + reaps 5-10 resources from unconscious humans, killing them in the process. + - wip: Confused about what the chemical you're fighting does? Look at https://tgstation13.org/wiki/Blob#Blob_Chemicals + - rscadd: Adds 'Support and Mechanized Exosuits' and 'Space Suits and Hardsuits' + categories to the syndicate uplink. + - rscadd: Nuke op reinforcements and mechs have been moved to the first category. + Syndicate space suits and hardsuits have been moved to the second category. + - bugfix: Traitors can now properly buy the blood-red hardsuit for 8 TC. + - tweak: Nuke ops can no longer buy the blood-red hardsuit, as the elite hardsuit + costs the same amount while being absolutely better. + Kor: + - rscadd: Added door control remotes. Clicking on doors while holding them will + let you open/bolt/toggle emergency access depending on the mode. They will not + work on doors that have their IDscan disabled (rogue AIs take note!) + - rscadd: The Captain, RD, CE, HoS, CMO, and QM all now have door control remotes + in their lockers. + LanCartwright: + - rscadd: Adds Uranium to Virus reaction. Will create a random symptom between 5 + and 6 when mixed with blood. + - rscadd: Adds Virus rations, which creates a level 1 symptom when mixed with blood. + - rscadd: Adds Mutagenic agar, which creates a level 3 symptom. + - rscadd: Adds Sucrose agar which creates a level 4 symptom. + - rscadd: Adds Weak virus plasma, which creates a level 5 symptom. + - rscadd: Adds Virus plasma, which creates a level 6 symptom. + - rscadd: Adds Virus food and Mutagen reaction, creating Mutagenic agar. + - rscadd: Adds Virus food and Synaptizine reaction, creating Virus rations. + - rscadd: Adds Virus food and Plasma reaction, creating Virus plasma. + - rscadd: Adds Synaptizine and Virus plasma reaction, creating weakened virus plasma. + - rscadd: Adds Sugar and Mutagenic agar reaction, creating sucrose agar. + - rscadd: Adds Saline glucose solution and Mutagenic agar reaction, creating sucrose + agar. + - rscadd: Adds Viral self-adaptation symptom, which boosts stealth and resistance, + but lowers stage speed. + - rscadd: Adds Viral evolutionary acceleration, which bosts stage speed and transmittability, + but lowers stealth and resistance. + - rscadd: Flypeople now vomit when they eat nutriment. + - rscadd: Flypeople can now suck the vomit off the floor to gain it's nutritional + content. + - rscadd: Flypeople now must suck puke chunks and vomit to fill themselves of food + content. + Malkevin: + - tweak: Sec officers have two sets of cuffs again (one on spawn, one in locker) + - tweak: Done some optimisation of sec spawn equipment lists and lockers to remove + some of the repetitive clicking, sec belts are now preloaded with equipment. + - tweak: HoS has a full baton instead of the collapsible one + - tweak: Detective has a classic police baton and pepper spray instead of the collapsible + baton (someone made police batons shit, so don't get overly happy) + - bugfix: pop scaled additional lockers spawned were the wrong type, changed them + to the right type which has batons now (actually belts now that I've changed + them). + MrStonedOne: + - tweak: Suit sensors will now favor higher levels for starting amount with the + exception of the max level, that remains unchanged. + - tweak: 'Old odds: 25% off 25% binary lifesigns 25% full lifesigns 25% coordinates' + - tweak: 'New odds: 12.5% off 25% binary lifesigns 37.5% full lifesigns 25% coordinates' + PKPenguin321: + - rscadd: Bolas are now in the game. They're a simple device fashioned from a cable + and two weights on the end, designed to entangle enemies by wrapping around + their legs upon being thrown at them. The victim can remove them rather quickly, + however. + - rscadd: Bolas can be crafted by applying 6 metal sheets to cablecuffs. They can + also be tablecrafted. + Sestren413: + - rscadd: Botanists have access to a new banana mutation now, bluespace bananas. + These will teleport anyone unfortunate enough to slip on their peel. + Shadowlight213: + - rscadd: A wave of dark energy has been detected in the area. Corgi births may + be affected. + Shadowlight213 and Robustin: + - rscadd: '"Old Cult is back baby!"' + - tweak: '"Cult survival objective disabled"' + - tweak: '"Imbuing talismans now consumes the imbue rune"' + - tweak: '"Invoking the stun talisman now hurts the cultist more"' + - tweak: '"The stun talisman duration is nerfed by 10%, mute is nerfed by 60% but + a stutter and special new slur effect will last much longer"' + - tweak: '"The old cult has retained the rune of time stop, now requiring 3 cultists + to invoke"' + - rscdel: '"New Cult is removed!"' + bgobandit: + - rscadd: CentComm has been informed that cargo is receiving new forms of contraband + in crates. Remember, Nanotrasen has a zero-tolerance contraband policy! + lordpidey: + - rscadd: New virology symptom, projectile vomiting. It is a level four symptom. +2016-03-03: + Joan: + - tweak: Blobbernauts now die slowly when not near a blob. + - rscadd: Blobbernauts can now see their health and the core health of the overmind + that created them. +2016-03-05: + CoreOverload: + - imageadd: Cyborg tools (screwdriver, crowbar, wrench, etc) now have new fancy + sprites. + - tweak: Said cyborg tools have received a buff and are now two times faster than + their non-cyborg counterparts. + Joan: + - tweak: Replicating Foam has lower expand chances when hit and on normal expand. + - bugfix: Shifting Fragments will no longer try and fail to swap with invalid blobs + when hit. + - tweak: Electromagnetic Web no longer always EMPs targets, instead doing it at + a 25% chance. + - tweak: Synchronous Mesh now only takes bonus damage from fire, bombs, and flashbangs. + - tweak: Synchronous Mesh no longer tries to split damage to blob cores or nodes. + Cores and nodes still split damage to nearby blobs, however. + - tweak: Blobbernauts now attack much slower. + - tweak: Blobbernauts are now maximum one per factory, reduce that factory's health + drastically, and die slowly if that factory is destroyed. + - experiment: Factories must still have above 50% health to produce blobbernauts. +2016-03-07: + WJohnston: + - tweak: Queens and praetorians have new sprites! +2016-03-09: + Joan: + - rscadd: Blobs can now attack people that end up on top of blob tiles with Left-Click + or the Expand/Attack Blob verb. + - tweak: The Toxin Filter virology symptom now heals 4-8 toxin damage instead of + 8-14. + - tweak: The Damage Converter virology symptom will now do toxin damage for each + limb healed. + MrStonedOne: + - tweak: Centcom has improved the the tesla generator! The generated tesla energy + balls should now be more stable! Growing quicker and dissipating slower. It + seems to also move around a touch more but that shouldn't be an issue as the + the tesla escaping containment is unheard of! +2016-03-10: + Joan: + - rscadd: The blob can now be shocked by the tesla. + - tweak: Strong blobs are now much more resistant to brute damage. + - wip: Tweaks blob reagents; + - rscdel: Removes Ripping Tendrils. + - rscdel: Removes Draining Spikes. + - tweak: Cryogenic Liquid does less burn damage. + - tweak: Pressurized Slime does less brute damage. + - tweak: Reactive Gelatin now has a lower minimum damage. + - tweak: Poisonous Strands applies its damage over a longer period of time. + - tweak: Sporing Pods now does much less damage, and is less likely to produce spores + when killed. + - tweak: Regenerative Materia, Hallucinogenic Nectar, and Envenomed Filaments do + less toxin damage. + - rscadd: Energized Fibers no longer heals when hit with stamina damage, and is + instead immune to the tesla. + - rscadd: Boiling Oil now takes damage from extinguisher blasts. Boiling Oil blobbernauts, + however, do not. + - tweak: Replicating Foam now takes increased brute damage and when expanding from + damage, will not expand again. + - tweak: Flammable Goo takes 50% increased burn damage, from 30%. + - tweak: Explosive Lattice now takes much higher damage from fire, flashbangs, and + the tesla. + - experiment: Electromagnetic Web takes full brute damage, lasers will now one-hit + normal blobs, and the death EMP is smaller. +2016-03-12: + Joan: + - bugfix: Blobbernauts and blob spores can now move near blob tiles in no gravity. + - tweak: Boiling Oil does slightly more damage and takes slightly less damage when + extinguished. + - rscadd: Flammable Goo now applies firestacks to targets, but does not ignite them. + Jordie0608: + - rscadd: Show Server Revision will now tell you if a PR is test merged currently. + PKPenguin321: + - rscadd: Added reinforced bolas. They do a very short stun in addition to normal + functions, and take twice as long to break out of when compared to regular bolas. + - tweak: The traitor's Throwing Star Box has been made into the Throwing Weapons + Box. It now contains two reinforced bolas in addition to its old contents. It + also costs 5 TCs, down from 6. + tkdrg: + - tweak: The detective's revolver now takes three full seconds to reload. + xxalpha: + - rscadd: Detective can be a Traitor/Double Agent. + - tweak: Removed Detective's access to security lockers and secbots. + - tweak: Removed bowman's headset from Detective's locker. + - tweak: Box Brig Security Office and Locker Room require a higher access level + (Security Officer level). +2016-03-13: + Dorsisdwarf: + - rscadd: 'Adds Robo-Doctor board (The Hippocratic Oath: Now on your beepbot)' + - rscadd: Adds Reporter board (The truth will set ye free (termsandconditionsmayapply)) + - rscadd: Adds Live and Let Live board + - rscadd: Adds Thermodynamics as a dangerous board. + Impisi: + - tweak: Improvised shells now deal more far more damage but are more inaccurate. + - tweak: Overloaded shells now require liquid plasma in addition to black powder. + Shells now fire explosive pellets that are good at hurting you and everything + in front of you. + Joan: + - rscdel: Blob gamemode blobs will no longer burst from people. + - rscadd: Instead, the blob gamemode spawns overminds, which can place their blob + core underneath them in an unobserved area. + - rscadd: The overminds can, until they have placed a blob core, move to any non-space, + non-shuttle tile. + - rscadd: If the overminds fail to place a blob core within a time limit, it will + be automatically placed for them at a random blob spawnpoint. + - tweak: The time before the overmind automatically places the core is slightly + lower than the previous average time it'd take a blob to burst. +2016-03-15: + Cuboos: + - soundadd: Modded the current door sound and added a few new ones, unique sound + for closing, bolting up/down and a nifty denied sound. + Isratosh: + - rscadd: Security flashlights can now be attached to the bulletproof helmets. + Joan: + - tweak: Resource blobs produce resources for their overmind slightly slower for + each resource blob their overmind has. + - rscadd: Blob overminds get one free chemical reroll. + - rscadd: Blob overminds can no longer place resource and factory blobs out of range + of cores and nodes, unless they Toggle Node Requirement off. It is on by default. + - rscadd: Blob UI buttons now have tooltips. + - tweak: Cores and nodes will expand slightly slower. + - tweak: Blob Chemicals no longer trigger effects on dead mobs. + - tweak: Shifting Fragments has a lower chance to move shields with normal expansion + and will no longer shift blobs to the location of a dying blob. + - tweak: Flammable Goo no longer applies fire to tiles with blobs. + - tweak: Electromagnetic Web has a slightly higher EMP range. + Kor: + - rscadd: Hunger was accidentally disabled sometime back in October 2015. We finally + noticed and fixed it. + Kor (And all the lovely maintainers and spriters who helped me along the way): + - rscadd: Adds a new, lava themed planet to mine on,with randomly generated rivers + of lava and islands of volcanic rock. This mine is used on Box and Metastation. + Other mappers may enable it at their discretion. + - rscadd: Added deadly ash storms to mining. + - rscadd: Added slightly deadlier variants of mining mobs to lavaland, with sprites + done by my girlfriend. + - rscadd: Added portable survival capsules to mining equipment lockers. Don't forget + these, or you might get caught out by a storm. You may purchase more at the + venders. + - rscadd: Added randomly loaded ruins to mining. These maps contain new and unique + items not seen elsewhere in thegame. There are around a dozen of them added + with the "release" of lavaland, though I plan for many more. + - rscadd: Some ruins contain sleepers which allow you to spawn as various roles, + such as survivors of a shuttle crash stranded in the wilderness. You can find + these sleepers in the orbit list. + - rscadd: You can now fly the abandoned white ship to lavaland. + LanCartwright: + - tweak: Choking now deals damage based on virus' Stage speed and virus Stealth. + - tweak: Fever heats the body based on Transmittability and Stage speed. + - tweak: Spontaneous Combustion now adjusts firestacks based on stage speed minus + Stealth. + - tweak: Necrotizing Fasciitis now deals damage based on lower Stealth values. + - tweak: Toxic Filter now heals based on Stage speed. + - tweak: Deoxyribonucleic Acid Restoration now heals brain damage based on Stage + speed minus Stealth. + - tweak: Shivering now chills based on Stealth and Resistance. + - rscadd: Proc for the total stage speed of a virus' symptoms. + - rscadd: Proc for the total stealth of a virus' symptoms. + - rscadd: Proc for the total resistance of a virus' symptoms. + - rscadd: Proc for the total transmittance speed of a virus' symptoms. + MrStonedOne: + - rscdel: 'Lag has been removed from the following systems: mob life()/virus process, + machine/object/event processing, atmos, deletion subsystem, lighting, explosions, + singularity''s eat(), timers, wall smoothing, mass var edit, mass proc calls(and + all of sdql2), map loader, and the away mission loader.' + - rscdel: Removed limit on bomb cap of 32,64,128, it can now go to the MOON. + - tweak: Minimap generation is now a config option that defaults to off so coders + don't have to wait for it to generate to test their code, server operators should + note that they need to enable it on production servers that want minimap generation. + - wip: if you find any things that still lag, please report them to MrStonedOne + for lag removal. + - experiment: I'm gonna take this time to shill out that, Lummox JR, byond's only + dev, coded the tool that made this change possible, he lives off of byond membership + donations, if you like the lag removal, become a byond member or at least throw + 5 bucks byond's way for doing this. + - experiment: Feel free to ask for bomb cap removals when solo antag, but remember, + the later in the round it is, the more likely you'll get it. + PKPenguin321: + - rscadd: Scooters and skateboards have been added. + - rscadd: Use rods to make a scooter frame. From there, apply metal to make wheels, + creating a skateboard. Apply a few more rods to make a full scooter. You can + also use tablecrafting to create them, their recipes can be found under the + Misc. category. + - rscadd: Each step of scooter deconstruction is performed with either a wrench + or a screwdriver, depending on the step. + xxalpha: + - rscadd: Scrubber clog event now ejects cockroaches. +2016-03-17: + CoreOverload: + - rscdel: The recent jetpacks nerf is finally reverted. Turbo mode is dead and stabilization + is once again can be toggled on and off. + - rscadd: 'Added a new chest cyberimplant: implantable thrusters set. This implant + is a built-in jetpack that has no stabilization mode at all and can use gas + from environment (if 30+ kPa) or from internals. It can also use plasma from + plasma vessel organ, if you have one.' + Joan: + - tweak: Moved the security hud's icons down slightly to allow it to coexist with + medical and antag huds. + Shadowlight213: + - rscadd: HOG deity can now be heard by all of its followers! + - tweak: The prophet no longer needs to wear his hat to speak with his deity. + - rscadd: The prophet's hat and staff have a new functionality! Use the staff inhand + to reveal hidden structures. + - rscadd: Deities can now hide their structures from view! Pretend to be a book + club when sec bursts in. experiment:Only enemy prophets or your own deity can + reveal these structures and they are disabled when hidden. +2016-03-19: + Joan: + - imageadd: Xray lasers now have unique inhands. + - imageadd: Xray lasers have been recolored to match R&D equipment. + Zombehz: + - rscadd: Adds 'chicken' nuggets* in 4 shapes, including regular, star, corgi, and + lizard. it. They are made with one cutlet of meat. +2016-03-20: + Joan: + - rscadd: Nar-Sie will now corrupt airlocks, tables, windows, and windoors. + - rscadd: Corrupted airlocks have no access restrictions. + - tweak: Nar-Sie no longer causes destruction while moving around in favor of additional + corruption. + - tweak: The surplus crate is less likely to give you eight space suits. + - bugfix: Nukeops can once again buy noslips. The nuke op magboots are still better + than noslips, buy them instead. + Kor: + - rscadd: Runtime now has a chance to spawn with a more classic look. + - rscadd: Killing a necropolis tendril will now drop a chest full of spooky loot. + - rscadd: Killing a necropolis tendril will now cause the ground to collapse around + it after 5 seconds. +2016-03-21: + CoreOverload: + - rscadd: You can now construct and deconstruct wall mounted flashes by using a + wrench on empty wall flash. A crate with four linked "flash frame - flash controller" + pairs is added to cargo. + Joan: + - rscadd: Explosive Holoparasites now have a 33% chance to explosively teleport + attacked targets, doing damage to everyone near the target's appearance point. + - tweak: Explosive Holoparasite bombs can now detonate when living mobs bump them. + - rscadd: Adds lightning holoparasites, which have medium damage resist, a weak + attack, have a lightning chain to their summoner, and apply lightning chains + when attacking targets. + - rscadd: Lightning chains shock everyone nearby, doing low burn damage. This is + excluding the parasite and summoner; chains will shock enemies they're attached + to. + - tweak: Holoparasites can now smash tables and lockers. + PKPenguin321 && !JJRcop: + - rscadd: Milk, which is good for your bones, is now extra beneficial to species + that are mostly comprised of bones. + kingofkosmos: + - rscdel: The backpack close-button has got a visual overhaul. + - rscadd: All storage items can be closed by clicking on them again. +2016-03-23: + Iamgoofball: + - rscadd: Cargo now works off of Credits. + - rscadd: Cargo now plays the Stock Market. + - rscadd: Buy Low, Sell High +2016-03-24: + Iamgoofball: + - rscadd: CLF3 now melts, burns, and destroys floors a lot more often, as it should + be. + - rscadd: CLF3 now makes 3x3 fireballs on tiles it touches now, instead of a single + fireball. + Joan: + - tweak: Lightning Holoparasites will actually shock relatively often instead of + 'sometimes, maybe, if you're really lucky' + PKPenguin321: + - tweak: Sand now fits in your pockets + - rscadd: Sand can now be thrown into people's eyes, doing slight stamina damage, + making their vision slightly blurry, and making them stumble when they walk + for a short time. + RemieRichards: + - rscadd: BEES + - rscadd: Hydroponics can now manage bee colonies, bees produce honeycombs that + can be grinded to obtain honey, a decent nutriment+healing chemical + - rscadd: Hydroponics can inject a queen bee with a syringe of a reagent to alter + her DNA to match that reagent, meaning all honeycombs produced will contain + that reagent in small amounts + - rscadd: Bees with reagents will attack with that reagent + Xhuis: + - experiment: Alcohol has received multiple tweaks. + - tweak: Drunkenness will now be displayed on examine as long as the target's face + is not hidden, ranging from a slight flush to being a completely drunken wreck. + This also helps to measure alcohol poisoning, although the appearance will remain + for thirty seconds after the alcohol leaves the imbiber's bloodstream. + - tweak: Alcohol poisoning now has different effects. It begins with standard things + such as confusion, dizziness, and slurring, but eventually escalates to constant + vomiting, blacking out, and toxin damage. + - tweak: Drinks now have a wide variety of alcoholism. Grog is barely a drink whatsoever, + for instance, but Manly Dorf will completely floor you with too much consumption. + Note that drinks based off of whiskey and vodka are the hardest, whereas beer + and wine are the softest. + - tweak: The speed of alcohol poisoning has been slightly reduced. + - rscadd: Some drinks have received unique effects. Experiment! + - rscadd: A new base alcohol joins the lineup! Absinthe has been added, and is very + strong. + - rscadd: Whiskey Sour, made with Whiskey, Lemon Juice, and Sugar, simply expands + the existing whiskey-based lineup. + - rscadd: Fetching Fizz, made with Nuka-Cola and Iron, will pull all nearby ores + in the direction of the imbiber. + - rscadd: Hearty Punch, made with Brave Bull, Syndicate Bomb, and Absinthe, will + provide extreme healing in critical condition. + - rscadd: Bacchus' Blessing, made with four of the most powerful alcohols on the + station, is over three times stronger than any other alcohol on the station. + Consume in small amounts or risk death. +2016-03-26: + CPTANT: + - tweak: Nanotrasen found a new taser supplier. The new tasers hold 12 shots, down + people with 2 hits and hybrid tasers now have a light laser attached. + CoreOverload: + - tweak: Sorting junctions now support multiple sorting tags. + Fox McCloud: + - bugfix: Fixes Shadowlings not being spaceproof to pressure + - bugfix: Fixes being able to receive multiple spells as a Lesser Shadowling + Joan: + - rscadd: Adds assassin holoparasites, which do low damage and take full damage, + but can go invisible, causing their next attack to do massive damage and ignore + armor. + - rscadd: Assassin holoparasite stealth will be broken by attacking or taking damage, + which will briefly prevent the parasite from recalling. + - rscadd: Traitor holoparasite injectors include this parasite type. + Kor: + - rscadd: There are a couple new lavaland ruins, including one with a new ghost + role. + PKPenguin321: + - tweak: The RD's reactive teleport armor now has a cooldown between teleports. + EMPing it will cause it to shut down and have a longer cooldown applied. + - imageadd: Bolas, both reinforced and regular, now have newer, sexier sprites. +2016-03-29: + Bawhoppen: + - tweak: Bruisepacks, ointment, and gauze now will apply significanty faster. + - rscdel: SWAT crates no longer contain combat knives. + - rscadd: SWAT crates now contain combat gloves. + - rscadd: Combat knives now can be ordered in their own crate. + Iamsaltball: + - rscadd: GRAB SUPER NERFED + - rscadd: IT'S WAY EASIER TO ESCAPE GRABS NOW + - rscadd: IT TAKES WAY LONGER TO UPGRADE GRABS NOW + - rscadd: 'YOU CAN ACTUALLY FUCKING ESCAPE GRABS NOW TOO #WOW #WHOA' + - rscadd: GRAB TEXT IS ALL BIG BOLD AND RED MUCH LIKE YOUR MOM LAST NIGHT + - experiment: GIT GUDDERS GO FUCK YOURSELVES YOU CAN'T GET GOOD AGAINST "LOL INSTANT + PERMASTUN THAT ISN'T OBVIOUS IN CHAT LIKE THE REST OF THE STUNS" + Joan: + - tweak: Ghost revival/body creation alerts now use the ghost's hud style. + - imageadd: Support holoparasites now have a healing effect with their color when + successfully healing a target. + - tweak: Ranged holoparasite projectiles now take on the color of the holoparasite. + - bugfix: Holoparasite communication(holo->summoner) now sends the message to all + holoparasites the summoner has. + - bugfix: If you have multiple holoparasites for some reason, Reset Guardian allows + you to choose which to reset. + - tweak: Resetting a holoparasite also resets its color and name, to make it more + obvious it's a new player. + - rscadd: Holoparasites can now see their summoner's health and various ability + cooldowns from the status panel. + - rscadd: Blobbernauts are now alerted when their factory is destroyed. + KazeEspada: + - bugfix: Blob Mobs no longer swap with other mobs. + RemieRichards: + - rscadd: Added the ability to make Apiaries and Honey frames with wood + - rscadd: Added the ability to make Royal Bee Jelly from 10 Mutagen and 40 Honey + - rscadd: Added the ability to make more Queen Bees from Royal Bee Jelly by using + it on an existing Queen, to split her into two Queens + - tweak: Made homeless bees more obvious + - bugfix: Fixed a typo that made almost all bees homeless, severely reducing the + odds of getting honeycomb + - tweak: Made bee progress reports (50% towards new honeycomb, etc.) always show, + even if it's 0% + - tweak: Made some feedback text more obvious + - bugfix: Fixed being able to duplicate the bee holder object, this was not exploity, + just weird + - bugfix: Fixed being able to put two (or more) queens in the same apiary + - bugfix: Fixed some runtimes from hydro code assuming a plant gene exists + - bugfix: Fixed runtime when you use a honeycomb in your hand + - tweak: It now takes and uses 5u of a reagent to give a bee that reagent + - rscdel: Removed unused icon file + Ricotez: + - imageadd: The default white ghost form now has directional sprites. + - rscadd: The default white ghost form now also has (your) hair! Here's how it works. + - experiment: If you ghost from a body, you'll get the hair from that body. If it + has hair. + - experiment: If you hit Observe, you'll get the hair from the character you had + active in your setup window. If they had hair. + - wip: This only works with the default white ghost form right now (because the + other forms have the wrong shape or lack directional sprites), and with human + bodies since they're the only ones that have hair. Sorry lizards and plasmamen! + You'll get your turn next time. + - rscadd: A new preference called Ghost Accessories. This lets you configure if + you want your ghost sprite to show both hair and directional sprites, only directional + sprites or just use its original default version without directional sprites. + - rscadd: 'A new preference called Ghosts of Others. This preference is clientside + and lets you configure how other ghosts appear to you: as their own setting, + as the form they chose but without any hair or directional sprites, or as the + simple white ghost sprite if you''re sick of those premium users with their + rainbow ghosts.' + - experiment: The layout of the ghost preference buttons has slightly changed. The + old Choose Ghost Form and Choose Ghost Orbit are now a part of Ghost Customization, + which also contains the new Ghost Accessories button. Clicking Ghost Customization + will send you directly to Ghost Accessories if you don't have premium. The Preferences + tab now also contains the Ghost Display button, which lets you configure how + other ghosts appear to you. + - bugfix: Fixed a bug where the toggles for Ghost Accessories and Ghosts of Others + in the Preferences menu wouldn't save your preference update to your save file. + - bugfix: Renamed the "Ghost Display Settings" preference toggle button to "Ghosts + of Others", so it fits with the name the preference has everywhere else. + TehZombehz: + - rscadd: Paper sacks are now craftable by tablecrafting with 5 sheets of paper. + - rscadd: 'Comes in 5 different designs: Use a pen on a paper sack to change the + design.' + - rscadd: Certain paper sack designs can be modified with a sharp object to craft + a (creepy) paper sack hat. + Xhuis: + - bugfix: Portal storm messages now use the station name rather than the world name. + - bugfix: Shadowlings can no longer glare while shadow walking. + - bugfix: Progress bars are now properly shown when reloading revolvers. + - bugfix: Cyborgs and AIs are no longer knocked out when being stuffed into lockers. + - bugfix: Plasmamen can no longer be the patient zero of the space retrovirus. + - bugfix: Cyborgs and AIs now properly display death messages. + - bugfix: Revenants can no longer be closed into lockers. + - bugfix: Airlocks no longer play sounds or flash lights when denying access if + the airlock has no power. + - bugfix: Job spawn icons in mapping have been fixed. + - bugfix: Gibtonite's disarm message no longer include the outside viewer. + - bugfix: Cult walls and girders are now more streamlined and can be built with + runed metal. + - bugfix: Positronic brains and MMIs can no longer see ghosts. + - rscadd: When someone is turned into a statue, the statue now appears as a greyscale + version of them. + - rscadd: Returning from a statue to a human now knocks you down. + - rscdel: Flesh to Stone no longer works on dead mobs. + - bugfix: Wall-mounted flasher crates now have the proper price. + - bugfix: Wall-mounted flasher frames now have icons. + - bugfix: Upgraded resonators now have an inhand sprite. +2016-03-30: + Coiax: + - rscadd: Geiger counters can now be stored in the suit storage of radiation suits + RemieRichards: + - bugfix: fixes shift-clicking action buttons not instantly resetting their location. + (I'm only making a changelog for this because apparently barely noone even knows + you can move the buttons, let alone reset them...) + TehZombehz: + - rscadd: Honey buns and honey nut bars are now craftable using honey. + - tweak: Brewing mead now requires actual honey. diff --git a/html/changelogs/archive/2016-04.yml b/html/changelogs/archive/2016-04.yml new file mode 100644 index 0000000000..59793944eb --- /dev/null +++ b/html/changelogs/archive/2016-04.yml @@ -0,0 +1,544 @@ +2016-04-01: + Erwgd: + - bugfix: Weed Killer bottles and Pest Killer bottles now contain 50 units. + - rscadd: The biogenerator can now make empty bottles and black pepper. + Isratosh: + - rscadd: Added an admin jump button to explosion logs. + Joan: + - rscadd: Traitors can now buy charger holoparasites. + - rscadd: Charger holoparasites move extremely fast, do medium damage, and can charge + at a location, damaging the first target it hits and forcing them to drop any + items they're holding. + Kor: + - rscadd: Mechas are now storm proof + - rscadd: Kinetic Accelerators now require two hands to fire, but are free standard + gear for miners. + - rscadd: All mining scanners are now automatic, with the advanced version having + longer range. + - rscadd: The QM and HoP no longer have spare vouchers. + - rscadd: You can buy a pack of two survival capsules with your mining voucher. + - rscadd: Mining Bots will no longer cause friendly fire incidents. They'll hold + fire if you are between them and their target + - rscadd: There are now four different mining drone upgrades available in the vendor. + - rscadd: Resonators can now have more fields and deal more melee damage. + - rscadd: Lavaland miners now have explorer's suits instead of hardsuits. Sprites + by Ausops. + - rscadd: You can now butcher Goliath's for their meat. It cooks well in lava. + Shadowlight213: + - rscadd: Clients now have a volume preference for admin-played sounds. + TehZombehz: + - rscadd: The 'Plasteel Chef' program has provided station chefs with complimentary + ingredient packages. There are several package themes, and chefs are provided + a random package on arrival. + coiax: + - rscadd: Free Golems on Lavaland have been naming their newborn siblings with a + wider range of geology terms +2016-04-02: + Eaglendia: + - rscadd: Central Command has released a new, more functional run of their most + stylish fashion line. + - rscadd: Head of Staff cloaks can now hold specific items - the antique laser gun + for the Captain, the replica energy gun for the Head of Security, the hypospray + for the Chief Medical Officer, the Hand Teleporter or RPED for the Research + Director, and the RCD or RPD for the Chief Engineer. +2016-04-03: + Erwgd: + - rscadd: Our valued colleagues in the security department are reminded to search + boots for hidden items (such as knives or syringes) as part of standard search + procedures. Alt-click a pair of boots to remove any hidden items. + Isratosh: + - bugfix: Fixed rudimentary transform not working properly on ghosts with minds. + - rscadd: Admin logs for bluespace capsules not activated on the mining Z level. +2016-04-04: + TechnoAlchemisto: + - rscadd: The recipes for some Trekchems are now back in the game + - rscadd: Bicaridine can be made with carbon, oxygen, and sugar. + - rscadd: Kelotane can be made with silicon and carbon. + - rscadd: Antitoxin can be made with nitrogen, silicon, and potassium + - rscadd: tricordrazine can be made by combining all three. +2016-04-05: + Erwgd: + - rscadd: Utility belts of all kinds can now accept gloves. Most belts, except janitorial + belts, may now also hold station bounced radios. + - rscadd: Hazard vests and most jackets can carry a station bounced radio as well. + Labcoats can be used to store a handheld crew monitor. + - rscadd: The autolathe can now make toolboxes. + Joan: + - rscadd: Adds protector holoparasites to traitor holoparasite injectors. + - rscadd: Protector holoparasites cause the summoner to teleport to them when out + of range, instead of the other way around. + - rscadd: Protector holoparasites have two modes; Combat, where they do and take + medium damage, and Protection, where they do and take almost no damage, but + move slightly slower. + - tweak: Explosive Holoparasites no longer teleport non-mobs when attacking, but + have a higher chance to teleport mobs. + - rscdel: Explosive Holoparasite bombs no longer trigger on their summoner or any + other parasites their summoner has. + - bugfix: Ranged Holoparasites no longer have nightvision active by default. It + can still be toggled on. + - tweak: Ranged Holoparasite snares no longer alert if the crossing mob is their + summoner or one of the parasites their summoner has. + - tweak: Ranged Holoparasites are slightly less visible in scout mode. + - tweak: Standard Holoparasites attack 20% faster than other parasite types. + - rscdel: Support Holoparasite beacons no longer require safe atmospheric conditions, + but the warp channel takes slightly longer, and is preceded with a visible message. + - tweak: Zombies can no longer destroy more than one airlock at a time. + - rscadd: The mining station has been updated. + MrStonedOne: + - bugfix: Centcom is glad to announce the end of sending workers to our control + group for space exposure testing, a fake station in "space" that noticeably + had air in "space". + TechnoAlchemisto: + - tweak: Detective scanners are now smaller. + - tweak: Pickaxes now fit in explorer suit exosuit slots. + bgobandit: + - rscadd: Alt-clicking a fire extinguisher cabinet opens and closes it. That is + all. +2016-04-06: + CoreOverload: + - rscadd: You can now put slimes in stasis by exposing them to room temp CO2. Useful + for both fighting the slimes and safely storing them. + Erwgd: + - rscadd: The autolathe can now make hydroponics tools! Access the design routines + in the Misc. category of the machine. + LanCartwright: + - tweak: Custom viruses with stealth values of 3 or above are now invisible on the + PANDEMIC and no longer visible on health huds. + MrStonedOne: + - bugfix: Centcom is happy to report that our single sided windows and our windoors + should once again create an airtight seal. + bgobandit: + - rscadd: Honk! Nanotrasen's clowning and development department has invented the + clown megaphone, standard in all clowning loadouts! Honk honk! +2016-04-07: + Kor: + - rscadd: The Laser Cannon in RD has been replaced with the Accelerator Laser Cannon. + Try it out! + - rscadd: Mechas now have armour facings. Attacking the front will deal far less + damage, while attacking the back will deal massive bonus damage. + - rscadd: EMPs now deal far less damage/drain to mechas. + Kor and Ausops: + - rscadd: Survival pod interiors have been redone. + - rscadd: Survival pods now contain a stationary GPS computer. + - rscadd: You can now toggle your GPS off with alt+click. + bgobandit: + - rscadd: Due to budget cuts, Nanotrasen is no longer utilizing copy-protected paper + for its classified documents. Fortunately, our world-class security team has + always prevented any thefts or photocopies from being made! + - rscadd: Secret documents can be photocopied. If you have an objective to steal + any set of documents, a photocopy will be accepted. If you must steal red or + blue documents, a photocopy will NOT be accepted. Enterprising traitors can + forge the red/blue seal with a crayon to take advantage of this. +2016-04-09: + GunHog: + - rscadd: Aliens may now force open unbolted, unwelded airlocks. Unpowered airlocks + open faster than powered ones. Has a cool sound provided by @Ultimate-Chimera! + - tweak: Alien Drone health increased to 125 hp. + - tweak: Alien drone is now faster! + - tweak: Alien egg and larva maturation times halved. + - tweak: Resin membrane health increased to 160 hp. + - rscadd: Aliens may now open firelocks. + - rscadd: Aliens may now unweld scrubbers and vents. (From the outside!) + - tweak: Droppers no longer affect aliens. + Joan: + - rscdel: You can no longer drop survival capsules on top of dense objects, such + as the windows in the emergency shuttle. You can still drop them on non-dense + objects and mobs, however. + - tweak: Swarmers can now deconstruct objects simply by clicking. + - rscadd: Swarmers can still teleport mobs away via ctrl-click. + - bugfix: Emps will now properly damage swarmers. + Kor: + - rscadd: Added wisp lanterns to necropolis chests. + - rscadd: Added red/blue cube pairs to necropolis chests. + - rscadd: Added meat hooks to necropolis chests. + - rscadd: Added immortality talismans to necropolis chests. + - rscadd: Added paradox bags to necropolis chests. + - rscadd: Ripley drills work again. Go tear up lavaland. + PKPenguin321: + - tweak: Goofball's grab nerf has been reverted. + TechnoAlchemisto: + - tweak: Pickaxe upgrades are now better. + coiax: + - tweak: Efficiency Station Testing Lab now has a Drone Shell Dispenser + - tweak: Fixed an issue with a door on the Golem Ship + - rscadd: The unfathomable entity Carp'sie has blessed vir followers with mysterious + carp guardians. + - rscadd: Nanotrasen Cyborgs are now able to empty ore boxes without human assistance + - rscadd: Ore boxes are now craftable with 4 planks of wood + - tweak: Ore boxes now drop their contents when destroyed, or dismantled with a + crowbar + coiax, bobdobbington, Core0verload: + - rscadd: An experimental plant DNA manipulator, based on machinery recovered from + ancient seed vaults, has been installed in the Botany department. +2016-04-11: + Joan: + - rscadd: Blob cores will take slight brute damage from explosions. + RandomMarine: + - rscadd: Additional luxuries have been added to golem ships. Including new rewards. + Praise be to The Liberator! + - rscdel: However, jaunters are no longer easily obtained by free golems. + RemieRichards: + - rscadd: The Station Blueprints now display the piping/wiring and some of the machinery + the station started with, to assist in repairs + coiax: + - rscadd: Emagging the cargo console also unlocks regular contraband, in addition + to syndicate gear + - rscadd: A working drone shell dispenser is now on display in MetaStation's museum, + displaying the virtue of the tireless little workers! + - rscadd: Dreamstation now has a drone shell dispenser in the Toxins Launch Room +2016-04-12: + Incoming5643: + - rscadd: Leading scientists have finally proven that humans (and xenos) in fact + have tongues in their mouths. + - rscadd: Swapping out tongues allows the various races to change their speech impediments. + Putting a xeno tongue in someone allows them to make the hissing sound like + a xeno whenever they speak. + - rscdel: There are no erp mechanics tied to this feature. + - experiment: Remember that tongues are stored in the MOUTH, selecting the head + isn't good enough. + Kor: + - rscadd: Ash walker starting gear has been rebalanced. + - rscadd: Ash walkers can no longer use guns. + TrustyGun: + - rscadd: After carefully investing in the market, the Captain had enough money + to replace his silver flask with a golden one! + - rscadd: The Detective is now bringing his personalized flask to work, due to the + grim work he has to do. + - rscadd: The Booze-O-Mat now stocks 3 flasks. +2016-04-16: + Bawhoppen: + - tweak: Cryo is no longer god-awful. + CoreOverload: + - rscadd: A lot of items are now exportable in cargo. + - rscadd: Use Export Scanner to check any item's export value. + Erwgd: + - rscadd: Forks, bowls, drinking glasses, shot glasses and shakers can now be made + and recycled in the autolathe! Access the designs in the new 'Dinnerware' category. + - tweak: Kitchen knives have been moved to the Dinnerware category of the autolathe. + - rscadd: Butcher's cleavers can now be made in a hacked autolathe. + Fox McCloud: + - rscadd: Slime batteries now self-recharge. + - rscadd: Adds transference potion. A potion that allows the user to transfer their + consciousness to a simple mob. + - rscadd: Adds rainbow slime core reaction that generates a consciousness transference + potion when injected with blood. + Iamgoofball, Lati, Geo_Jerkal, Tanquetsunami25: + - rscadd: Lati requested that the Slime Processor will now automatically scoop up + any dead slimes into itself for processing. + - rscadd: Geo_Jerkal requested that you be able to mix Arnold Palmers with Tea and + Lemon Juice. + - rscadd: Tanquetsunami25 requested that cyborg be able to boop. + Incoming5643: + - rscdel: Removed the horrible meme skeletons, please don't sue us. + Kor: + - rscadd: Adrenals, no slips, surplus crates and SUHTANDOS now have minimum population + requirements before they can be purchased. + KorPhaeron: + - rscadd: You now need to butcher goliaths and watchers on lavaland to receive their + loot. Use the combat knives to do so. + Lati: + - rscadd: Custom floor tiles can now be added to floorbots. They will start replacing + other tiles with these tiles if the option is toggled on. + coiax: + - rscadd: Boxstation, not to be outdone by all the other competing station designs, + has installed a drone shell dispenser in the Testing Lab, which makes automated + drones to help fix the station. + - rscadd: Toy fans, rejoyce! The famous skeleton brothers from the beloved game + Belowyarn now have toys that you can win from the arcade machines! + - rscadd: Airlock painters can be printed at your local autolathe + - rscadd: Please do not attempt suicide with the airlock painter or the medical + wrench. + - rscadd: Metastation now has a plant DNA manipulator in Botany. + - rscadd: Using the fire extinguisher on yourself or others while in HELP intent + will spray you or them, rather than beat their probably flaming body with a + metal object. + - tweak: Alt-clicking extinguishers to empty them now wets the floor underneath + them. + lordpidey: + - rscadd: Meth labs can now blow up if you don't purify the ingredients or over-heat + the end product. + nullbear: + - rscadd: Added attack verbs for heart and tongue organs + - tweak: Maximum output of air pumps has been raised. +2016-04-18: + Joan: + - rscdel: Crates are now dense even when open. + - rscadd: You can now climb onto crates in the same way as table and sandbags, though + climbing onto crates is very fast and does not stun you. + - wip: You can walk on crates, provided both are closed/open or the crate you're + on is closed. + - rscdel: You can't close or open a crate if there's a large mob on top of it. + - rscadd: Stuffing items into a closet or crate is now instant and does not close + the closet or crate. Stuffing mobs into a closet or crate still takes time and + closes the closet/crate in question. + - imageadd: Crowbars and wirecutters have new inhand sprites. Crowbars can now be + distinguished from wrenches in-hand. + RandomMarine: + - tweak: Cloth items removed from biogenerator. Instead, it can create stacking + cloth that crafts those items. + - rscadd: In addition, cloth can be used to create grey jumpsuits, backpacks, dufflebags, + bio bags, black shoes, bedsheets, and bandages. + - tweak: Bedsheets now tear into cloth instead of directly into bandages. + Shadowlight213: + - tweak: AI will be notified when one of their cyborgs is detonated. + coiax: + - bugfix: Fixed slime grinders not sucking up more than one slime + - rscadd: Drones now start with a spacious dufflebag full of tools, so they will + stop stealing the captain's + - bugfix: Fixed issues with drones wearing chameleon headgear. + - rscadd: Added admin-only "snowflake drone" (also known as drone camogear) headgear. + nullbear: + - bugfix: Fixes air canisters being silent when bashed. +2016-04-20: + Erwgd: + - rscadd: The autolathe can now make trays. + Fox McCloud: + - bugfix: Fixes abductor vests having no cooldown between uses + Kor: + - rscadd: You can now craft boats and oars out of goliath hides. These boats can + move in lava. + - rscadd: Added a spooky, upgraded boat to necropolis chests. + coiax: + - tweak: Slime grinders now cease suction of new slimes while grinding + coiax, Joan: + - rscadd: Drone dufflebags now have their own sprite. + kevinz000: + - rscadd: 'Admin Detection Multitool: A multitool that shows when administrators + are watching you! Now you can grief in safety!' + - tweak: Syndicate R&D scientists have significantly increased the range of their + "AI detection multitools", making them turn yellow when an AI's tracking is + near, but not on you just yet! +2016-04-21: + Kor: + - rscadd: Mechas can now toggle strafing mode. +2016-04-22: + Bawhoppen: + - rscadd: Security belts can now hold any type of grenade. This includes barrier + grenades. + - rscadd: Janitorial belts are now able to store chem grenades. + - rscadd: Military belts have been given a size upgrade, so they can now hold larger + items. + - rscadd: Bandoliers have been given a buff and now can hold a much larger amount + of ammunition. + nullbear: + - bugfix: xenobio console is deconstructable again. + - tweak: syndibomb recipe calls for any matter bin, scaling effectiveness with tier. +2016-04-23: + Joan: + - bugfix: Aliens can now open crates and lockers. + - bugfix: Aliens and monkeys can now climb climbable objects, such as crates and + sandbags. + - rscadd: Aliens climb very, very fast. + Kor: + - rscadd: Running HE pipes over lava will now heat the gas inside. + - rscadd: Alt+clicking on your mecha (while inside it) will toggle strafing mode. + Mercenaryblue: + - rscadd: Allowed all corgis to wear red wizard hats. + TechnoAlchemisto: + - rscadd: Goliaths now drop bones, and Watchers drop sinews. + - rscadd: You can craft primitive gear from bone and sinew. + coiax: + - bugfix: Non-humans are now able to interact with bee boxes. +2016-04-25: + Joan: + - bugfix: You can once again hit a closet or crate with an item to open it. + Kor Razharas: + - rscadd: Adds support for autoclicking. + - rscadd: The Shock Revolver has been added to RnD. + - rscadd: The Laser Gatling Gun has been added to RnD. The Gatling Gun uses autoclick + to fire as you hold down the mouse. + - rscadd: The Research Director now starts with a box of firing pins. + - rscadd: The SABR and Stun Revolver recipes have been removed from RnD + coiax: + - rscadd: Laughter demons are like slaughter demons, but they tickle people to death + - tweak: Slaughter demons are no longer able to cast spells while phased. + - tweak: Wizards can now speak while ethereal, but still cannot cast spells while + ethereal. + - rscadd: 'Centcom''s "drone expert" reports that drones vision filters have been + upgraded to include the option of making all beings appear as harmless animals. + info: As always, all drone filters are togglable.' + - rscadd: As a sign of friendship between the Free Golems and Centcom, they have + modified Centcom's jaunter to be worn around a user's waist, which will save + them from falling to their death in a chasm. + - experiment: The Golems warn that these modifications have created a risk of accidental + activation when exposed to heavy electromagnetic fields. + - tweak: Renamed hivelord stabilizer to stabilizing serum. + - rscadd: Centcom regret to inform you that new instabilities with nearby gas giants + are causing exospheric bubbles to affect the telecommunications processors. + Please contact your supervisor for further instructions. + - rscadd: The Janitor's Union has mandated additional features to station light + replacer devices. + - rscadd: The light replacer now can be used on the floor to replace the bulbs of + any lights on that tile. + - rscadd: The light replacer now eats replaced bulbs, and after a certain number + of bulb fragments (four) will recycle them into a new bulb. + - tweak: The description of the light replacer is now more informative. + - rscadd: Clown mask appearance toggle now has an action button. +2016-04-26: + Iamgoofball & Super Aggro Crag: + - tweak: Fluorosulfuric Acid now has doubled acid power. + - experiment: Fluorosulfuric Acid now does BONUS burn damage scaling on the time + it's been inside the consumer. + Joan: + - tweak: Blobbernauts now spawn at half health. + - tweak: Blobbernauts regeneration on blob is now 2.5 health per tick, from 5. + - tweak: Blobbernauts now cost 40 resources to produce, from 30. + - rscdel: Factories supporting blobbernauts do not spawn spores. + Lati: + - tweak: Syndicate bomb can be only delayed once by pulsing the delay wire. Time + gained from this is changed from 10 seconds to 30 seconds. + TechnoAlchemisto: + - tweak: Goliath plates can now be stacked. + phil235: + - rscadd: More structures and machines are now breakable and/or destroyable with + melee weapon. Additionally, Some structures and machines that are already breakable/destroyable + are now affected by more attack methods (gun projectiles, thrown items, melee + weapons, xeno/animal attacks, explosions). + - rscadd: Hitting any machine now always makes a sound. + - rscadd: You can hit closed closets/crates and doors by using an item on harm intent + (but it doesn't actually hurt them). + - rscadd: you can now burst filled water balloons with sharp items. + - bugfix: Wooden barricade drops wood when destroyed. + - bugfix: Slot machines with coins inside are deconstructable now. +2016-04-27: + TechnoAlchemisto: + - rscadd: Miners can now select explorer belts from the mining vendor using their + vouchers, or mining points. +2016-04-28: + Bawhoppen: + - tweak: Sandbags are no longer tablecrafted. Now you just put in sand (or ash) + by hand to make them. + - rscadd: Miners and Engis now get boxes of empty sandbags in their lockers. Miners + also get a few premade aswell. + - rscadd: You can now break sandstone down into normal sand. + Joan: + - rscadd: Attacking a blob with an analyzer will tell you what its chemical does, + its health, and a small fact about the blob analyzed. + - rscdel: 'NERFS:' + - tweak: Zombifying Feelers does less toxin damage. + - tweak: Adaptive Nexuses does slightly less brute damage. + - tweak: Replicating Foam does slightly less brute damage. + - tweak: Blob Sorium does slightly less brute damage. + - tweak: Blob Dark Matter does slightly less brute damage. + - tweak: Cyrogenic Liquid injects slightly less frost oil and ice and does slightly + less stamina damage. + - tweak: Pressurized Slime does less brute, oxygen, and stamina damage, and extinguishes + objects and people on turfs it wets. + - rscdel: Blob core strong blobs no longer give points when removed. + - wip: 'PROBABLY BUFFS:' + - tweak: Flammable Goo now does slightly more burn damage and applies more firestacks, + but applies fire to blob tiles that don't share its chemical. + - tweak: Energized Fibers does slightly more burn damage, slightly less stamina + damage, and now takes damage from EMPs. + - rscadd: 'BUFFS:' + - tweak: Boiling Oil does slightly more burn damage and applies more firestacks. + - tweak: Reactive Gelatin does slightly more damage on average. + - tweak: Penetrating Spines now also ignores bio resistance in addition to armor. + - tweak: Hallucinogenic Nectar causes more hallucinations. + - tweak: Normal strong blobs now refund 4 points when removed, from 2. + - rscadd: Charger holoparasites now play a sound when hitting a target, as well + as shaking the target's camera. + PKPenguin321: + - rscadd: The warden's locker now contains krav maga gloves. + TechnoAlchemisto: + - rscadd: You can now craft skull helmets from bones. + - rscadd: Syndicate bombs are now harder to detect +2016-04-29: + Bawhoppen: + - rscadd: Several lesser-used uplink's TC cost have been rebalanced. + - tweak: Steckhin down from 9TC to 7TC. + - tweak: Tactical medkit down from 9TC to 4TC. + - tweak: Syndicate magboots from 3TC to 2TC. + - tweak: Powersinks down from 10TC to 6TC. + - tweak: Stealth rad-laser down from 5TC to 3TC. + - tweak: Bundles have been updated accordingly. + Incoming5643: + - rscadd: The staff/wand of door creation can now also be used to open airlock doors. + - rscadd: Doors spawned by the staff/wand now start open. Keep this in mind the + next time you try to turn every wall on the escape shuttle into a door. + Robustin: + - rscdel: The Teleport Other, Veil, Imbue, Reveal, Disguise, Blood Drain, Timestop, + Stun, Deafen, Blind, Armaments, Construct Shell and Summon Tome runes are gone. + - rscadd: Disguise, Veil/Reveal, Construct Shell and Armaments are now talismans. + The Construction talisman requires 25 sheets of metal. + - rscadd: Cultists will now receive a warning when attempting to use emergency communion + or create the Nar-Sie rune + - rscadd: Cultists can now create talismans with a super-simple Talisman-Creation + rune. It takes about 10 seconds to invoke and will present a menu of all the + talisman choices available. Its as simple as tossing the paper on, clicking + the rune, and selecting your talisman. + - rscadd: Cultists now have a proc, "How to Play" that will give a basic explanation + of how to succeed as a cultist. + - rscadd: The new Talisman of Horror is a stealthy talisman that will cause hallucinations + in the victim. Great for undermining security without having to commit to murder + them in middle of the hall. + - rscadd: Creating the Summon Nar-Sie rune does takes slightly less time, but now + adds a 3x3 square of red barrier shields (60hp each) to prevent the rune-scriber + from being bumped by other idiots. This works in conjunction with the rune's + warning to give crew a chance to stop the summoning. Manifest ghost has a weaker + 1x1 shield to prevent bumps as well. + - rscadd: Talismans are now color-coded by their effect so you can easily organize + and deploy talismans. + - rscadd: You can now make colored paper in the washing machine using crayons or + stamps, honk. + - rscadd: The Electromagnetic Disruption rune will now scale with the number of + cultists invoking the rune. **A full 9-cultist invocation will EMP the entire + station!** + - rscadd: Armaments will now give the recipient a new cult bola. + - rscadd: The new Talisman of Shackling will apply handcuffs directly to the victim. + These cuffs will disappear when removed. + - tweak: Cult slur is a little less potent so victims might be able to squeeze in + a coherent word or two if you let them keep jabbering on the radio, stun talismans + now have less of a health cost and the stun is back to 10 seconds, from 9. + - tweak: Rune and Talisman names now give a much clearer idea of what they do. + - experiment: The following changes are courtesy of ChangelingRain + - rscadd: The Teleport rune now allows cultists to select which rune to teleport + to, and teleports everything on it. + - rscadd: Veil and Reveal are merged into Talisman of Veiling. Veiling has two uses, + the first use will hide and the second use will reveal. + - rscadd: New icons for the cult bola + - tweak: You can now attack fellow cultists with a Talisman of Arming to arm them + with robes and a sword. + - tweak: You can now only place one rune per tile. + - tweak: Ghosts are notified when a new manifest rune is created. + TechnoAlchemisto: + - rscadd: Sinew can now be fashioned into restraints. + coiax: + - tweak: Internals Crate now contains breath masks and small tanks. + - rscadd: Metal foam grenade box crate added for 1000 points + - rscadd: Added two Engineering Mesons to Engineering Gear Crate + - tweak: Engineering Gear now costs 1300 + - rscadd: Breach Shield Generator Crate added for 2500 points + - rscadd: Grounding Rod Crate added for 1700 points + - rscadd: PACMAN Generator Crate added for 2500 + - rscadd: Defibrillator Crate added for 2500 + - rscadd: Added more helmets to the Laser Tag Crate. + - rscadd: Nanotrasen Customs report that some wide band suppliers have been providing + "alternative" firing pins. Nanotrasen reminds all crewmembers that contraband + is contraband. + - rscadd: Contraband crates now appear visually similar to legitimate crates. + - bugfix: The cargo shuttle's normal transit time has been restored. + nullbear: + - rscadd: Adds a preference option, allowing players to toggle whether recipes with + no matching components should be hidden. +2016-04-30: + Joan: + - rscadd: Blobs attempting to attack the supermatter will instead be eaten by it. + - experiment: This doesn't mean throwing a supermatter shard at the blob is a good + idea; blobs attacking it will gradually damage it, eventually resulting in a + massive explosion, and it will not consume blobs if on a space turf. + - tweak: Hitting a locker or crate with an ID, PDA with ID, or wallet with ID will + try to toggle the lock instead of trying to open it. + - imageadd: Cable coils, cablecuffs, and zipties now all have properly colored inhands. + Kor: + - rscadd: Megafauna have been added to lavaland. + - rscadd: Ash Drakes have been spotted roaming the wastes. Use your GPS to track + their fiery signals. + - rscadd: You can now knock on the Necropolis door, but it's probably best that + you don't. + Mercenaryblue: + - rscadd: Adds a basic paper plane to the game. Fold paper with alt-clicking. + - rscadd: Paper planes are now fully compatible with every stamps on station. + bgobandit: + - rscadd: 'Nanotrasen has released Cards Against Spess! Visit your local library + for a copy. Warning: may cause breakage of the fourth wall.' diff --git a/html/changelogs/archive/2016-05.yml b/html/changelogs/archive/2016-05.yml new file mode 100644 index 0000000000..e9ecdad30b --- /dev/null +++ b/html/changelogs/archive/2016-05.yml @@ -0,0 +1,439 @@ +2016-05-02: + Joan: + - tweak: Blob spores spawn from factories 2 seconds faster, but the factory goes + on cooldown when any of its spores die. + - experiment: You can examine tomes, soulstones, and construct shells to see what + you can do with them. + - rscadd: Releasing a shade from a soulstone now allows you to reuse that soulstone + for capturing shades or souls, instead of preventing the stone's use forever + if the shade dies. + - imageadd: Runes now actually pulse red on failure. + - rscadd: The Summon Cultist rune no longer includes the cultists invoking it in + the selection menu. + - tweak: Imperfect Communication renamed to Emergency Communication. + - rscdel: You can no longer hide the Nar-Sie rune with a Talisman of Veiling/Revealing. + Kor: + - rscadd: Engineering cyborgs now have internal blueprints. + Lzimann: + - tweak: Automatic nexus placing time changed from 2 to 15 minutes. + - tweak: Prophet's gear(hat and staff) prioritizes the backpack instead of automatically + equipping. + - rscadd: Divine telepathy and prophet to god speak now have a follow button for + ghosts. + - rscadd: Divine telepathy and prophet to god speak now has the god's color. + - bugfix: CTF spawn protection trap is no longer constructable + Mercenaryblue: + - tweak: Drastically reduced the chances of eye damage when throwing a paper plane. + RandomMarine: + - tweak: Medical HUDs improved. To better prioritize patients, subjects deep into + critical condition have a blinking red outline around the entire HUD icon, and + will blink more rapidly when very close to death. + TechnoAlchemisto: + - tweak: Security uniforms have been made more professional, and more tactical. + TrustyGun: + - rscadd: By crafting together a legion skull, a goliath steak, ketchup, and capsaicin + oil, you can create Stuffed Legion! Be careful, it's hot. + coiax: + - rscadd: Centcom Department of [REDACTED] have announced a change of supplier of + [EXPLETIVE DELETED]. As such, for security reasons, the absinthe [MOVE ALONG + CITIZEN] will instead be [NOTHING TO SEE HERE]. We hope that this will not affect + the performance of the [INFORMATION ABOVE YOUR SECURITY CLEARANCE]. + nullbear: + - rscadd: A reminder for crew to avoid mopping floors in cold rooms, as the water + will freeze and provide a dangerous slipping hazard known as 'ice'. Running + on it is not recommended. + - rscadd: Frostoil is an effective chemical for rapidly cooling areas in the event + of a fire. + - rscadd: Added X4, a breaching charge more destructive than C4, it can be purchased + from uplinks. + - rscadd: C4 can be used with assemblies. + - bugfix: Fixes chembomb recipe to use any matter bin. Again. + - bugfix: ARG's disappear once finished reacting. +2016-05-03: + coiax, Robustin: + - tweak: Changeling Fleshmend is much less effective when used repeatedly in a short + time. Changeling Panacea is much more effective at purging reagents, reducing + radiation and now reduces braindamage. +2016-05-04: + Fox McCloud: + - tweak: shock revolver projectiles are now energy instead of bullets + Joan: + - rscdel: Cultists no longer communicate via tomes. + - rscadd: Cultists now communicate via the 'Communion' action button. + - rscadd: Examining the blob with an active research scanner or medical hud will + display effects, akin to hitting it with an analyzer. + - rscadd: Improved medical HUDs to work on all living creatures. + - rscadd: Drones and swarmers, being machines, require a diagnostic HUD for analysis + instead. + TechnoAlchemist: + - rscadd: You can now craft cloaks from the scales of fallen ash drakes, look for + the recipe in tablecrafting! + coiax: + - rscadd: The Service and the Standard cyborg module now have a spraycan built in, + for hijinks and passing on important urban messages. The Service cyborg module + also has a cyborg-hand labeler, in case anything needs to be labelled. + - rscadd: 'Centcom Suicide Prevention wishes to remind the station: Please do not + kill yourself with a hand labeler.' + xxalpha: + - bugfix: Fixed the mk-honk prototype shoes. +2016-05-05: + Joan: + - tweak: Revenants are slower while revealed. + - rscdel: Revenants can no longer cast inside dense objects. + - tweak: Lying down will cure Blight much, much faster. + \"Macho Man\" Randy Savage: + - rscadd: OOOHHH YEAAAAHHHH + - rscadd: SNAP INTO A JLIM SIM WITH THE ALL NEW WRESTLING BELT + - rscadd: YOU CAN FREAKOUT YOUR OPPONENTS WITH THE 5 HOT MOVES ON THIS BELT YEAH + - rscadd: PRAY TO THE LOCAL SPACE GODS TO EXCHANGE YOUR TELECRYSTALS TO ENSURE THE + CREAM RISES TO THE TOP +2016-05-07: + Robustin: + - rscadd: A small pantry has been added to SW maintenance. + nullbear: + - rscadd: Makes Shift+Middleclick the hotkey for pointing. + phil235: + - rscadd: DISMEMBERMENT! Humans can now lose their bodyparts. Explosions and being + attacked with a heavy sharp item on a specific bodypart can cause dismemberment. + - rscadd: You can't be handcuffed or legcuffed if you're missing an arm or leg. + You can't use items when you have no legs, your arms are too busy helping you + crawl, unless your are buckled to a chair. You're slower when missing a leg. + - rscadd: You lose organs and items if the bodypart they are inside gets cut off. + You can always retrieve them by cutting the dropped bodypart with a sharp object. + - rscadd: Medbay can replace your missing limbs with robotic parts via surgery, + or amputate you. + - rscadd: Changelings do not die when decapitated! They can regrow all their limbs + with Fleshmend, or just one arm with Arm Blade or Organic Shield. + - rscadd: Your chest cannot be dropped, but it will spill its organs onto the ground + when dismembered. +2016-05-08: + CoreOverload: + - rscadd: You can now de-power inactive swarmers with a screwdriver to prevent them + from activating. + - rscadd: Recycle depowered swarmers in autolathe or sell them in cargo! + Joan: + - rscadd: Cultist constructs, and shades, can now invoke runes by clicking them. + - rscdel: This does not include Manifest Ghost, Blood Boil, or Astral Journey runes. + - rscadd: Medical huds will now show parasites in dead creatures. + KorPhaeron: + - rscadd: Burn weapons can now dismember, and they reduce the limb to ash in the + process + - rscadd: Weapons with high AP values will now dismember limbs much easier. These + values are subject to change depending on how things play out over the next + week or two. + - rscadd: Various weapons with high AP values had them lowered (chaplain scythe, + energy sword, dualsaber) to prevent them taking limbs off in a single hit. + - rscadd: The chaplain has two new weapons (they are mechanically identical to previous + weapons, before anyone gets upset about balance). One is dismemberment themed, + the other is related to a new antagonist. + Mercenaryblue: + - rscadd: Throwing a Banana Cream Pie will now knock down and cream the target's + face. + - rscadd: You can clean off the cream with the usual methods, such as soap, shower, + cleaner spray, etc. + - rscadd: The Clown Federation would like to remind the crew that the HoS is worth + double points! Honk! + Robustin: + - experiment: There are rumors that the Cult's 'Talisman of Construction', which + turns ordinary metal for construct shells, can be used on plasteel to create + structures. If the stories are true, the cult has been producing relics of incredible + power through this transmutation. + coiax: + - rscadd: To save credits, Centcom has subcontracted out emergency shuttle design + to third parties. Rest assured, all of these produced shuttles meet our stringent + quality control. + - tweak: Lavaland ruins spawning chances have been modified. Expect to see more + smaller and less round affecting ruins, and no duplicates of major ruins, like + ash walkers or golems. + lordpidey: + - rscadd: Infernal devils have been seen onboard our spacestations, offering great + boons in exchange for souls. + - rscadd: Employees are reminded that their souls already belong to nanotrasen. If + you have sold your soul in error, a lawyer or head of personnel can help return + your soul to Nanotrasen by hitting you with your employment contract. + - rscadd: Nanotrasen headquarters will be bluespacing employment contracts into + the Lawyer's office filing cabinet when a new arrival reaches the station. It + is recommended that the lawyer create copies of some of these for safe keeping. + - rscadd: Due to the recent infernal incursions, the station library has been equipped + with a Codex Gigas to help research infernal weaknesses. Please note that reading + this book may have unintended side effects. Also note, you must spell the devil's + name exactly, as there are countless demons with similar names. + - rscadd: When a devil dies, if the proper banishment ritual is not performed on + it's remains, the devil will revive itself at the cost of some of it's power. The + banishment ritual is described in the Codex Gigas. + - rscadd: When a demon gains enough souls, It's form will mutate to a more demonic + looking form. The Arch-demon form is known to be on par with an ascended shadowling + in power. +2016-05-09: + Joan: + - tweak: Sporing Pods produces spores when expanding slightly more often. + - tweak: Replicating Foam now only expands when hit with burn damage, from all damage, + but does so at a higher chance. Free expansion from it is, however, more rare. + - tweak: Penetrating Spines does slightly more brute damage, and Poisonous Strands + does its damage 50% faster. + KorPhaeron: + - rscadd: The AI no longer has a tracking delay because artificial lag is the most + miserable thing in the world. + Razharas: + - tweak: crafting can now be done everywhere, little button near the intents with + hammer on it(its not T) opens the crafting menu, if you are in a locker or mech + only things in your hands will be considered for crafting + coiax: + - tweak: Skeletons now have bone "tongues" +2016-05-11: + Joan: + - rscadd: Shades can move in space. + - rscadd: Artificers can now heal shades. + coiax: + - tweak: Added action button to chameleon stamp + - rscadd: Added APPROVED and DENIED stamps to Bureaucracy Crate + - rscadd: Added the cream pie closet to various maps. Added contraband Cream Pie + Crate to Cargo. + pudl: + - rscadd: The armory has been redesigned. +2016-05-12: + Shadowlight and coiax: + - rscdel: Due to numerous reports of teams using human weapons instead of stealth + when carrying out their assignments, future teams have been genetically modified + to only be able to use their assigned blaster and are unable to use human weapons. +2016-05-13: + Joan: + - rscadd: Cultists can now unanchor and reanchor cult structures by hitting them + with a tome. Unanchored cult structures don't do anything. + KorPhaeron: + - rscadd: Drake attacks are now much easier to avoid. + - rscadd: Player controlled drakes can now consume bodies to heal, and alt+click + targets to divebomb them. + TechnoAlchemisto: + - rscadd: More items have been added to the mining vendor, check them out! +2016-05-14: + Cruix: + - bugfix: Fixed foam darts with the safety cap removed being reset when fired. + - rscadd: Added the ability to remove pens from foam darts. + - bugfix: Foam darts with pens inside them are no longer destroyed when fired. + - bugfix: Foam darts no longer drop two darts when fired at a person on a janicart. + Joan: + - rscdel: The Raise Dead rune no longer accepts dead cultists as a sacrifice to + raise the dead. + Metacide: + - rscadd: 'A small update for MetaStation, changes include:' + - rscadd: Added extra grounding rods to the engine area to stop camera destruction. + - rscadd: Added canvases and extra crayons to art storage and some easels to maint. + - rscadd: Added formal security uniform crate for parades to the warden's gear area. + - rscadd: The armory securitron now starts active. + - rscadd: The genetics APC now starts unlocked. + - rscadd: Other minor changes and fixes as detailed on the wiki page. + coiax, Nienhaus: + - rscdel: Unfortunately, the Belowyarn toys have been withdrawn from distribution + due to Assistants choking on the batteries. Centcom has sent their condolences + to the battery manufacturing plant. + - rscadd: We are introducing Oh-cee the original content skeleton figurines. Pull + its string, and hear it say a variety of phrases. Not suitable for infants or + assistants under 36 months. + - tweak: Note that pulling the string of all talking toys is now visible to others. + - rscadd: Talking toys produce a lot more chatter than they did before. So do some + skeleton "tongues". + pudl: + - rscadd: Adds normal security headsets to security lockers + xxalpha: + - bugfix: Fixed drone dispenser multiplying glass or metal. +2016-05-15: + Iamgoofball: + - rscadd: Nanotrasen is short on cash, and are now borrowing escape shuttles from + other stations, and Space Apartments. + Mercenaryblue: + - rscadd: Turns out a bike horn made with Bananium is flipping awesome! Honk! +2016-05-18: + Cruix: + - bugfix: unwrapping an item with telekinesis no longer teleports the item into + your hand. + Metacide: + - rscadd: 'MetaStation: the library and chapel have had windows removed to make + them feel more isolated.' + MrStonedOne: + - tweak: Tesla has been rebalanced. + - tweak: It should now lose balls slower, increase balls faster, and be a bit more + aggressive about finding nearby grounding rods. + - tweak: additional zaps from it's orbiting balls should be a bit more varied, but + a touch less powerful. + Robustin: + - rscadd: Lings have a new default ability, Hivemind Link. This lets you bring a + neck-grabbed victim into hivemind communications after short period of time. + You can talk to victims who are in crit/muted and perhaps persuade them to help + you, give you intel, or even a PDA code. The link will stabilize crit victims + to help ensure they do not die during the link. + Shadowlight213: + - bugfix: Cleanbot and floorbot scanning has greatly improved. they should prioritize + areas next to them, as well as resolve themselves stacking on the same tiles. + coiax: + - rscadd: Kinetic accelerators only require one hand to be fired, as before + - rscdel: Kinetic accelerators recharge time is multiplied by the number of KAs + that person is carrying. + - rscdel: Kinetic accelerators lose their charge quickly if not equipped or being + held + - rscadd: Kinetic accelerator modkits (made at R&D or your local Free Golem ship) + overcome these flaws +2016-05-19: + Razharas: + - rscadd: HE pipes once again work in space and in lava. + - rscadd: Space cools down station air again +2016-05-20: + KorPhaeron: + - rscadd: The HoS now has a pinpointer, the Warden now has his door remote. + bgobandit: + - rscadd: Nanotrasen has begun to research BZ, a hallucinogenic gas. We trust you + will use it responsibly. + - rscadd: BZ causes hallucinations once breathed in and, at high doses, has a chance + of doing brain damage. + - rscadd: BZ is known to cause unusual stasis-like behavior in the slime species. + coiax: + - rscadd: Neurotoxin spit can be used as makeshift space propulsion +2016-05-21: + Iamsaltball: + - rscadd: Heads of Staff now have basic Maint. access. + NicholasM10: + - rscadd: The chef can now make Khinkali and Khachapuri + coiax: + - rscdel: NOBREATH species (golems, skeletons, abductors, ash walkers, zombies) + no longer have or require lungs. They no longer take suffocation/oxyloss damage, + cannot give CPR and cannot benefit from CPR. Instead of suffocation damage, + during crit they take gradual brute damage. + - rscdel: NOBLOOD (golems, skeletons, abductors, slimepeople, plasmamen) species + no longer have or require hearts. + - tweak: NOBREATH species that require hearts still take damage from heart attacks, + as their tissues die and the lack of circulation causes toxins to build up. + - rscdel: NOHUNGER (plasmamen, skeletons) species no longer have appendixes. + coiax, OPDingo: + - tweak: Renamed and reskinned legion's heart to legion's soul to avoid confusion; + it is not a substitute heart, it is a supplemental chest organ. + - rscadd: Legion's souls are now more obviously inert when becoming inert. + nullbear: + - tweak: Wetness updates less often. + - rscadd: Wetness now stacks. Spraying lube over a tile that already has lube, will + make the lube take longer to dry. Likewise, dumping 100 units of lube will take + longer to dry than if only 10 units were dumped. (lube used to last just as + long, regardless of whether it was 1u, or 100u) There is a limit, however, and + you can't stack infinite lube. + - tweak: Hotter temperatures cause water to evaporate more quickly. At 100C, water + will boil away instantly. + - rscadd: About 5 seconds of wetness are removed from a tile for each unit of drying + agent. Absorbant Galoshes remain the most effective method of drying, and dry + tiles instantly regardless of wetness. +2016-05-22: + coiax: + - rscdel: Lavaland monsters now give ruins a wide berth. + - bugfix: Glass tables now break when people are pushed onto them. +2016-05-23: + CoreOverload: + - rscadd: New cyberimplant, "Toolset Arm", is now available in RnD. + coiax, OPDingo: + - rscadd: Crayons and spraycans are now easier to use. + - rscdel: Centcom announce due to budget cuts their supplier of rainbow crayons + has been forced to use more... exotic chemicals. Please do not ingest your standard + issue crayon. + kevinz000: + - rscadd: 'Peacekeeper borgs: Security borgs but without any stuns or restraints! + Modules: Harm Alarm, Cookie Dispenser, Energy Bola Launcher, Peace Injector + that confuses living things, and a weak holobarrier projector! It also comes + with the ability to hug.' + - rscadd: 'Cookie Synthesizer: Self recharging RCD that prints out cookies!' + - tweak: Nanotrasen scientists have added a hugging module to medical and peacekeeper + cyborgs to boost emotions during human-cyborg interaction. +2016-05-24: + Joan: + - rscdel: You can no longer scribe the Summon Nar-Sie rune under non-valid conditions. + Kiazusho: + - rscadd: Added three new advanced syringes to R&D +2016-05-26: + Xhuis: + - rscadd: Purge all untruths and honor Ratvar. + coiax: + - bugfix: Fixes bug where bolt of change to the host would kill an attached guardian. + - bugfix: Fixes bug where bolt of change to laughter demon would not release its + friends. + - bugfix: Fixes bug where bolt of change to morphling would not release its contents. + - bugfix: Fixes bug where bolt of change transforming someone into a drone would + not give them hacked laws and vision. + - bugfix: Blobbernauts created by a staff of change are now "independent" and will + not decay if seperated from a blob or missing a factory. + - rscadd: Independent blobbernauts added to gold slime core spawn pool. + - rscadd: Medical scanners now inform the user if the dead subject is within the + (currently) 120 second defib window. + - rscadd: Ghosts now have the "Restore Character Name" verb, which will set their + ghost appearance and dead chat name to their character preferences. + - bugfix: Mob spawners now give any generated names to the mind of the spawned mob, + meaning ghosts will have the name they had in life. + - bugfix: Fixes interaction with envy's knife and lavaland spawns. + - bugfix: Fixes a bug where swarmers teleporting humans would incorrectly display + a visible message about restraints breaking. + - rscdel: Emagging the emergency shuttle computer with less than ten seconds until + launch no longer gives additional time. + - rscadd: The emergency shuttle computer now reads the ID in your ID slot, rather + than your hand. +2016-05-27: + coiax: + - rscdel: Gatling gun removed from R&D for pressing ceremonial reasons. + phil235: + - tweak: Pull and Grab are merged together. Pulling stays unchanged. Using an empty + hand with grab intent on a mob will pull them. Using an empty hand with grab + intent on a mob that you're already pulling will try to upgrade your grip to + aggressive grab>neck grab>kill grab. Aggressive grabs no longer stun you, but + they act exactly like a handcuff, preventing you from using your hands until + you escape the grip. You can break free from the grip by trying to move or using + the resist button. + - tweak: Someone pulling a restrained mob now swap position with them instead of + getting blocked by the mob, unable to even push them. +2016-05-29: + GunHog: + - rscadd: The CE, RD, and CMO have been issued megaphones. + Paprika, Crystalwarrior, Korphaeron and Bawhoppen: + - rscadd: Pixel projectiles. This is easier to see than explain, so go fire a weapon. + Xhuis: + - rscadd: Ratvar and Nar-Sie now actively seek each other out if they both exist. + - tweak: Celestial gateway animations have been twweaked. + - tweak: Ratvar now has a new sound and message upon spawning. + - tweak: Ratvar now only moves one tile at a time. + - bugfix: The celestial gateway now takes an unreasonably long amount of time. + - bugfix: God clashing is now much more likely to work properly. + - bugfix: Function Call now works as intended. + - bugfix: Break Will now works as intended. + - bugfix: Holy water now properly deconverts servants of Ratvar. + - bugfix: Deconverted servants of Ratvar are no longer considered servants. + pudl: + - rscadd: Chemicals should now have color, instead of just being pink. +2016-05-30: + coiax: + - rscadd: A new Shuttle Manipulator verb has been added for quick access to probably + the best and most mostly bugfree feature on /tg/. + - rscadd: Spectral sword is now a point of interest for ghosts. + - bugfix: Clicking the spectral sword action now orbits the sword, instead of just + teleporting to its location. + - bugfix: Gang tags can again be sprayed over. + - bugfix: Fixes bug where the wisp was unable to be recalled to the lantern. + xxalpha: + - rscdel: Engineering, CE and Atmos hardsuits no longer have in-built jetpacks. +2016-05-31: + CoreOverload: + - rscadd: 'Cleanbot software was updated to version 1.2, improving pathfinding and + adding two new cleaning options: "Clean Trash" and "Exterminate Pests".' + - experiment: New cleaning options are still experimental and disabled by default. + Kiazusho: + - bugfix: Changeling organic suit and chitin armor can be toggled off once again. + Kor: + - rscadd: The Japanese Animes button is back, + - rscadd: 'The chaplain has three new weapons: The possessed blade, the extra-dimensional + blade, and the nautical energy sword. The former has a new power, the latter + two are normal sword reskins.' + - rscadd: The chapel mass driver has been buffed. + coiax: + - rscdel: Zombies can no longer be butchered + - rscadd: If you encounter an infectious zombie, be cautious, its claws will infect + you, and on death you will rise with them. If you manage to kill the beast, + you can remove the corruption from its brain via surgery, or just chop off the + head to stop it coming back. + - rscadd: Adds some stock computers and lavaland to Birdboat Station. + - bugfix: Free Golem scientists have proved that as beings made out of stone, golems + are immune to all electrical discharges, including the tesla. + - rscadd: Nuclear bombs are now points of interest. Never miss a borg steal a nuke + from the syndicate shuttle again! + - rscadd: Alt-clicking a spraycan toggles the cap. diff --git a/html/changelogs/archive/2016-06.yml b/html/changelogs/archive/2016-06.yml new file mode 100644 index 0000000000..8f27f80b0b --- /dev/null +++ b/html/changelogs/archive/2016-06.yml @@ -0,0 +1,660 @@ +2016-06-01: + coiax: + - rscadd: Added a mirror to the beach biodome. Beach Bums, rejoyce! + pudl: + - rscadd: The brig infirmary has received a redesign. +2016-06-02: + Joan: + - tweak: Closed false walls will block air. + Lati: + - rscadd: R&D required levels and origin tech levels have been rebalanced + - experiment: Overall, items buildable in R&D have lower tech levels and items in + other departments have their tech levels raised. Remember to use science goggles + to see tech levels of items! + - tweak: There are now level gates at high levels. R&D scientists will need help + from others to get past these level gates. + - tweak: Other departments such as hydroponics and genetics will be important to + R&D's progress now and xenobio, mining and cargo are more important than before + - tweak: Efficiency upgrades are back in R&D machines and tweaked to be less powerful + in autolathes + - rscdel: Reliability has been removed from all items + - bugfix: Most bugs in R&D machines should be fixed + PKPenguin321 & Nienhaus: + - rscadd: Letterman jackets are now available from the ClothesMate. + Quiltyquilty: + - rscadd: The bar has seen a redesign. + coiax: + - rscadd: Clone pods now notify the medical channel on a successful clone. They + also notify the medical channel if the clone dies or is horribly mutilated; + but not if it is ejected early by authorised medical personnel. + - rscadd: Cloning pods now are more capable of cloning humanoid species that do + not breathe. + - bugfix: You can only be damaged once by a shuttle's arrival. It is still unpleasant + to be in the path of one though; try to avoid it. + - rscadd: Adds Asteroid emergency shuttle to shuttle templates. It is a very oddly + shaped one though, it might not be compatible with all stations. + - rscdel: The Chaplain soulshard can only turn a body into a shade once. A released + shade can still be reabsorbed by the stone to heal it. + - rscadd: The shuttle manipulator now has a Fast Travel button, for those admins + that really want a shuttle to get to where its going FAST. +2016-06-04: + MrStonedOne: + - bugfix: fixes see_darkness improperly hiding ghosts in certain cases. + Xhuis: + - tweak: Clockwork marauders can now smash walls and tables. + - tweak: Servants are no longer turned into harvesters by Nar-Sie but instead take + heavy brute damage and begin to bleed. Similarly, cultists are no longer converted + by Ratvar but instead take heavy fire damage and are set ablaze. + - rscadd: Added clockwork reclaimers. Ghosts can now click on Ratvar to become clockwork + reclaimers - small constructs capable of forcefully converting those that still + resist Ratvar's reign. Alt-clicking a valid target will allow the reclaimer + to leap onto the head of any non-servant, latching onto their head and converting + the target if they are able. The target will be outfitted with an unremovable, + acid-proof hat version of the reclaimer. The reclaimer will be able to speak + as normal and attack its host and anything nearby. If the reclaimer's host goes + unconscious or dies, it will leap free. + - rscadd: Added pinion airlocks. These airlocks can only be opened by servants and + conventional deconstruction will not work on them. They can be created by proselytizing + a normal airlock or from Ratvar. + - rscadd: Added ratvarian windows. They are created when Ratvar twists the form + of a normal window, and there are both single-direction and full-tile variants. + - bugfix: Non-servants can no longer use clockwork proselytizers or mending motors. + - bugfix: Servants are now deconverted properly. + coiax: + - bugfix: The cloning pod now sounds robotic on the radio. + - rscadd: For extra observer drama, ghosts can now visibly see the countdown of + syndicate bombs, nuclear devices, cloning pods, gang dominators and AI doomsday + devices. +2016-06-05: + Joan: + - rscadd: Clockwork structures can be damaged by projectiles and simple animals, + and will actually drop debris when destroyed. + - rscadd: AIs and Cyborgs that serve Ratvar can control clockwork airlocks and clockwork + windoors. + - rscadd: The clockwork proselytizer can now proselytize windows, doors, grilles, + and windoors. + - rscadd: The clockwork proselytizer can proselytize wall gears and alloy shards + to produce replicant alloy. It can also proselytize replicant alloy to refill, + in addition to refilling by attacking it with alloy. + - rscadd: The clockwork proselytizer can replace clockwork floors with clockwork + walls and vice versa. + - rscadd: Ratvar will convert windoors, tables, and computers in addition to everything + else. + - tweak: Ratvar now moves around much faster. + - rscadd: Ratvar and Nar-Sie will break each other's objects. + - tweak: The blind eye from a broken ocular warden now serves as a belligerent eye + instead of as replicant alloy. The pinion lock from a deconstructed clockwork + airlock now serves as a vanguard cogwheel instead of as replicant alloy. + - rscadd: Clockwork walls drop a wall gear when removed by a welding tool. The wall + gear is dense, but can be climbed over or unwrenched, and drops alloy shards + when broken. Clockwork walls drop alloy shards when broken by other means. + - bugfix: Fixed Nar-Sie wandering while battling Ratvar. + - bugfix: Ratvarian Spears now last for the proper 5 minute duration. + - bugfix: Servant communication now has ghost follow links. + - imageadd: New sigil sprites, courtesy Skowron. + - imageadd: Sigils of Transgression have a visual effect when stunning a target. + - imageadd: Clockwork spears now have a visual effect when breaking. + PKPenguin321: + - rscadd: The CMO's medical HUD implant now comes with a one-use autoimplanter for + ease of use. + RemieRichards: + - rscadd: Slimes may now be ordered to attack! You must be VERY good friends with + the slime(s) to give this command, asking them to attack their friends or other + slimes will result in them liking you less so be careful! + X-TheDark: + - rscadd: Mech battery replacement improved. The inserted battery's charge will + be set to the same percentage of the removed one's (or 10%, if removed one's + was less). + coiax: + - bugfix: Clicking the (F) link when an AI talks in binary chat will follow its + camera eye, the same as when (F) is clicked for its radio chat. + - bugfix: Laughter demons should now always let their friends go when asked correctly. + - rscadd: Cloning pods now grab the clone's mind when the body is ejected, rather + than when it starts cloning. + - rscadd: Wizards have been experimenting with summoning the slightly less lethal + "laughter demon". Please be aware that these demons appear to be nearly as dangerous + as their slaughter cousins. But adorable, nonetheless. + kevinz000: + - rscadd: Gravity Guns! It is a mildly expensive R&D gun that has a 5 second cooldown + between shots, but doesn't need to be recharged. It has two modes, attract and + repulse. For all your gravity-manipulation needs! +2016-06-07: + Bobylein: + - rscadd: Nanotrasen is finally able to source transparent bottles for chemistry. + Iamgoofball: + - experiment: The Greytide Virus got some teeth. + Joan: + - wip: This is a bunch of Clockwork Cult changes. + - rscadd: Added the Clockwork Obelisk, an Application scripture that produces a + clockwork obelisk, which can Hierophant Broadcast a large message to all servants + or open a Spatial Gateway with 5 uses and a 10 second duration to any conscious + servant or clockwork obelisk. + - wip: Spatial Gateways of any source have doubled uses and duration when the target + is a clockwork obelisk. + - rscadd: Added the Mania Motor, an Application scripture that produces a mania + motor, which, while active, causes hallucinations and brain damage in all nearby + humans. + - wip: The Mania Motor will try to convert any non-servant human directly adjacent + to it at an additional power cost and will remove brain damage, hallucinations, + and the druggy effect from servants. + - rscadd: Added the Vitality Matrix, an Application scripture that produces a sigil + that will slowly drain health from non-servants that remain on it. Servants + that remain on the sigil will instead be healed with the vitality drained from + non-servants. + - wip: The Vitality Matrix can revive dead servants for a cost of 25 vitality plus + all non-oxygen damage the servant has. If it cannot immediately revive a servant, + it will still heal their corpse. + - experiment: Most clockwork structures, including the Mending Motor, Interdiction + Lens, and the newly added Clockwork Obelisk and Mania Motor, now require power + to function. + - wip: Mending Motors can still use alloy for power. + - tweak: The Sigil of Transmission has been remade into a power battery and will + power directly adjecent clockwork structures. Sigils of Transmission start off + with 4000 power and can be recharged with Volt Void. + - tweak: Volt Void drains somewhat more power, but will not damage the invoker unless + they drain too much power. Invokers with augmented limbs will instead have those + limbs healed unless they drain especially massive amounts of power. + - wip: Using Volt Void on top of a Sigil of Transmission will transfer most of the + power drained to the Sigil of Transmission, effectively making it far less likely + to damage the invoker. + - rscdel: You can no longer stack most sigils and clockwork objects with themself. + You can still have multiple different objects or sigils on a tile, however. + - tweak: The Break Will Script has been renamed to Dementia Doctrine, is slightly + faster, and causes slightly more brain damage. + - tweak: The Judicial Visor now uses an action button instead of alt-click. Cultists + of Nar-Sie judged by the visor will be stunned for half duration, but will be + set on fire. + - tweak: Multiple scriptures have had their component requirements changed. The + Summon Judicial Visor Script has been reduced from a Script to a Driver. + - rscadd: Recollection will now show both required and consumed components. + - tweak: Clockwork Marauders can now emerge from their host if their host is at + or below 60% total health(for humans, this is 20 health out of crit) + - tweak: Clockwork Marauders will slowly heal if directly adjacent to their host + and have a slightly larger threshold for their no-Fatigue bonus damage. + Quiltyquilty: + - rscadd: Botany, atmospherics and cargo now all have access to high-capacity watertanks. + - rscadd: The bar has now been outfitted with custom bar stools. + Xhuis: + - rscdel: Removed the global message played when Nar-Sie _begins_ to spawn (but + not when it actually spawns). + - tweak: Drunkenness recovery speed now increases with how drunk the imbiber is + and is much quicker when the imbiber is asleep. + - tweak: Suit storage units now take three seconds to enter (up from one) and have + different sounds and messages for UV ray cauterization. + - bugfix: Fixed some bugs with the suit storage unit, inserting mobs, and contents + to seemed to duplicate themselves. + - bugfix: The Summon Nar-Sie rune can now only be drawn on original station tiles + and fails to invoke if scribed on the station then moved elsewhere. + coiax: + - rscdel: Bluespace shelter capsules can no longer be used on shuttles. + - rscadd: Bluespace shelters may have different capsules stored. View what your + capsule has inside by examining it. + - rscdel: The Nar'sie rune cannot be scribed on shuttles or off Z-level. + - rscadd: The Raise Dead rune automatically grabs the ghost of the raised corpse. + - rscadd: Deadchat is now notified when a sentient mob dies. + phil235: + - rscadd: Monkeys and all other animals that should have blood now has it. Beating + them up will make you and your weapon bloody, just like beating a human does. + Dragging them when wounded and lying will leave a blood trail. Their blood is + still mostly cosmetic, they suffer no effects from low blood level, unlike humans. + - rscadd: When a mob leaves a blood trail while dragged, it loses blood. You can + no longer drag a corpse to make an inifinite amount of blood trails, because + once the victim's blood reaches a certain threshold it no longer leaves a blood + trail (and no longer lose any more blood). The threshold depends on how much + damage the mob has taken. You can always avoid hurting the dragged mob by making + them stand up or by buckling them to something or by putting them in a container. + - rscdel: You can no longer empty a mob of its blood entirely with a syringe, once + the mob's blood volume reaches a critically low level you are unable to draw + any more blood from it. + - tweak: A changeling absorbing a human now sucks all their blood. +2016-06-08: + Cruix: + - bugfix: Changelings no longer lose the regenerate ability if they respect while + in regenerative stasis. + Fox McCloud: + - bugfix: Fixes Experimentor critical reactions not working + - bugfix: Fixes Experimentor item cloning not working + - bugfix: Fixes Experimentor producing coffee vending machines instead of coffe + cups + - tweak: Experimentor can only clone critical reaction items instead of anything + with an origin tech + GunHog: + - rscadd: Nanotrasen has approved the Hyper-Kenetic Accelerator upgrade for cyborg + mining modules. + - tweak: Each of the heads' ID computers are now themed for their department! + Joan: + - tweak: Anima Fragments have slightly more health and move faster, but slow down + temporarily when taking damage. Also they can move in space now. + Kor: + - rscadd: The clown will play a sad trombone noise upon death. + - rscadd: Colossi now roam the wastes. + - rscadd: Bubblegum now roams the wastes. + PKPenguin321: + - rscadd: You can now emag chemical dispensers, such as the ones in chemistry or + the bar, to unlock illegal chemicals. + lordpidey: + - tweak: Infernal jaunt has been significantly nerfed with an enter and exit delay. +2016-06-09: + GunHog: + - rscadd: Nanotrasen scientists have completed a design for adapting mining cyborgs + to the Lavaland Wastes in the form of anti-ash storm plating. Research for this + technology must be adapted at your local station. + Joan: + - tweak: Anima Fragments have slightly less health and damage and will slow down + for longer when hit. + Kor: + - rscadd: The captain now spawns with the station charter, which allows him to name + the station. + Papa Bones: + - tweak: Loyalty implants have been refluffed to mindshield implants, they are mechanically + the same. + Xhuis: + - rscadd: You can now remove all plants and weeds from a hydroponics tray by using + a spade on it. + - rscadd: Added meatwheat, a mutated variant of wheat that can be crushed into meat + substitute. + - rscadd: Added ambrosia gaia, a mysterious plant that is rumored to provide nutrients + and water to any soil - hydroponic or otherwise - that it's planted in. + - rscadd: Added cherry bombs, a mutated variant of blue cherries that have an explosively + good taste. Oh, and don't pluck the stems. + coiax: + - tweak: The beacons from support guardians are now structures, rather than replacing + the floor tile. In practice, this will change little, aside from not leaving + empty plating when a beacon is removed because a new one has been placed. + nullbear: + - tweak: Removes the restriction on wormhole jaunters, preventing them from teleporting + you to beacons on other z-levels. + - tweak: No longer able to use beacons to bypass normal shuttle/centcomm anti-bluespace + measures. +2016-06-11: + Joan: + - rscadd: Clockwork Slabs, Clockwork Caches near walls, and Tinkerer's Daemons will + now be more likely to generate components that the clockwork cult has the least + of. + - rscadd: Destroyed Clockwork Caches will drop all Tinkerer's Daemons in them. + - tweak: Clockwork Caches can now only generate a component every 30 seconds(when + near a clockwork wall), Clockwork Slabs can only generate a component every + 40 seconds, and Tinkerer's Daemons can only generate a component every 20 seconds. + This should result in higher component generation for everything except Clockwork + Caches near clockwork walls. + - tweak: Adding a component to a Clockwork Slab instead puts that component in the + global component cache. + - tweak: Clockwork Slabs only generate components if held by a mob or in a mob's + storage, and when generating a component will prevent other Slabs held from + generating a component. + - tweak: The Replicant Driver no longer costs a Replicant Alloy to invoke; basically + you can throw free Slabs at converts. + - rscdel: Clockwork Slabs no longer have Repository as a menu option; instead, you + can examine them to see how many components they have access to. + - rscdel: Clockwork Caches directly on top of clockwork walls won't generate components + from that wall. + Lzimann: + - rscadd: Bar stools are now constructable with metal! + coiax: + - rscadd: Ghosts are notified when someone arrives on the Arrivals Shuttle. This + is independent of the announcement system, and the (F) link will follow the + arrived person. + - tweak: Slimes and aliens with custom names now retain those names when changing + forms. + kevinz000: + - bugfix: Malf AI hacking an APC that is then destroyed will no longer bug the AI + - bugfix: Being turned into a Revolutionary now stuns you for a short while. + - bugfix: Kinetic Accelerators no longer drop their firing pin or cell when destroyed + by lava + phil235: + - rscadd: Firelock assemblies can be reinforced with plasteel to construct heavy + firelocks. +2016-06-12: + Joan: + - rscadd: Attacking a human you are pulling or have grabbed with a ratvarian spear + will impale them, doing massive damage, stunning the target, and breaking the + spear if they remain conscious after being attacked. + - tweak: The Function Call verb is now an action button. + Xhuis: + - rscdel: While experimenting with floral genetic engineering, Nanotrasen botanists + discovered an explosive variety of the cherry plant. Due to gross misuse, the + genes used to produce this strain have been isolated and removed while Central + Command decides how best to modify it. + xxalpha: + - rscadd: 'New wizard spell: Spacetime Distortion.' + - rscadd: 3x1 grafitti +2016-06-13: + Joan: + - tweak: Sigils of Transgression will now only stun for about 5 seconds, from around + 10 seconds. + - tweak: Sigils of Submission take about 5 seconds to convert a target, from around + 3 seconds, and will glow faintly. + - rscadd: Sigils of any type can be attacked with an open hand to destroy them, + instead of requiring harm intent. Servants still require harm intent to do so. + Lati: + - rscadd: Nanotrasen has added one of their rare machine prototypes to cargo's selection. + It might be valuable to research. + Xhuis: + - rscadd: You can now create living cake/cat hybrids through a slightly expensive + crafting recipe. These "caks" are remarkably resilient, quickly regenerating + any brute damage dealt, and can be attacked on harm intent to take a bite to + be fed by a small amount. They serve as mobile sources of food and make great + pets. + - rscadd: If a brain occupied by a player is used in the crafting recipe for caks, + that player then takes control of the cak! +2016-06-14: + Joan: + - tweak: The Gateway to the Celestial Derelict now takes exactly 5 minutes to successfully + summon Ratvar and has 500 health, from 1000. + - rscadd: You can now actually hit people adjacent to the Gateway; only the center + of the Gateway can be attacked. The Gateway is also now dense, allowing you + to more easily shoot at it. + - rscadd: All Scripture in the Clockwork Slab's recital has a simple description. + Razharas: + - rscadd: Wiki now has the method of cultivating kudzu vines that was in game for + over a year. https://tgstation13.org/wiki/Guide_to_hydroponics#Kudzu + kevinz000: + - tweak: Gravity Guns should no longer destroy local reality when set to attract + and shot in an east cardinal direction. Added safety checks has slightly increased + the cost of the gun's fabrication. Nanotrasen apologizes for the inconvenience. + - bugfix: Gravity guns now have an inhand sprite. +2016-06-16: + GunHog: + - rscadd: In response to alarmingly high mining cyborg losses, Nanotrasen has equipped + the units with an internal positioning beacon, as standard within the module. + Joan: + - rscadd: You can now strike a Tinkerer's Cache with a Clockwork Proselytizer to + refill the Proselytizer from the global component cache. + - tweak: The Clockwork Proselytizer requires slightly less alloy to convert windows + and windoors. + - tweak: Several clockwork objects have more useful descriptions, most notably including + structures, which will show a general health level to non-servants and exact + health to servants. + - imageadd: The Clockwork Proselytizer has new, more appropriate inhands. + - tweak: Invoking Inath-Neq, the Resonant Cogwheel, now gives total invulnerability + to all servants in range for 15 seconds instead of buffing maximum health. + - tweak: Impaling a target with a ratvarian spear no longer breaks the spear. + - tweak: Judicial Markers(the things spawned from Ratvar's Flame, in turn spawned + from a Judicial Visor) explode one second faster. + - rscdel: Removed Dementia Doctrine, replacing it with an Application sigil. + - rscadd: Adds the Sigil of Accession, the previously-mentioned Application sigil, + which is much like a Sigil of Submission, except it isn't removed on converting + un-mindshielded targets and will disappear after converting a mindshielded target. + - tweak: Sigil of Submission is now a Script instead of a Driver; It's unlocked + one tier up, so you have to rely on the Drivers you have until you get Scripts, + instead of spamming both Driver sigils for free converts. + - rscadd: To replace Sigil of Submission in the Driver tier; Added Taunting Tirade, + which is a chanted scripture with a very fast invocation, which, on chanting, + confuses, dizzies, and briefly stuns nearby non-servants and allows the invoker + a brief time to relocate before continuing the chant. + - rscadd: Ghosts can now see the Gateway to the Celestial Derelict's remaining time + as a countdown. + - tweak: Anima Fragments are now slightly slower if not at maximum health and no + longer drop a soul vessel when destroyed. + Quiltyquilty: + - rscdel: Patches now hold only 40u. + - rscdel: Patches in first aid kits now only contain 20u of chemicals. + coiax: + - rscadd: Polymorphed mobs now have the same name, and where possible, the same + equipment as their previous form. +2016-06-19: + Joan: + - tweak: Assassin holoparasite attack damage increased from 13 to 15, stealth cooldown + decreased from 20 seconds to 16 seconds. + - tweak: Charger holoparasite charge cooldown decreased from 5 seconds to 4 seconds. + - tweak: Chaos holoparasite attack damage decreased from 10 to 7, range decreased + from 10 to 7. + - tweak: Lightning holoparasite attack damage increased from 5 to 7, chain damage + increased by 33%. + - rscdel: Clock cult scripture unlock now only counts humans and silicons. + - rscadd: Servants of ratvar can now create cogscarab shells with a Script scripture. + Adding a soul vessel to one will produce a small, drone-like being with an inbuilt + proselytizer and tools. + - imageadd: Clockwork mobs have their own speechbubble icons. + - tweak: Invoking Sevtug now causes massive hallucinations, brain damage, confusion, + and dizziness for all non-servant humans on the same zlevel as the invoker. + - rscdel: Invoking Sevtug is no longer mind control. RIP mind control 2016-2016. + - tweak: Clockwork slabs now produce a component every 50 seconds, from 40, Tinkerer's + Caches now produce(if near a clockwork wall) a component every 35 seconds, from + 30. + - experiment: 'Tinkerer''s daemons have a slightly higher cooldown for each component + of the type they chose to produce that''s already in the cache: This is very + slight, but it''ll add up if you have a lot of one component type and are trying + to get more of it with daemons; 5 of a component type will add a second of delay.' + Kor and Iamgoofball: + - rscadd: Miners can now purchase fulton extraction packs. + - rscadd: Miners can now purchase fulton medivac packs. + - rscadd: Two new fulton related bundles are available for purchase with vouchers. + Quiltyquilty: + - rscadd: Beepsky now has his own home in the labor shuttle room. + Wizard's Federation: + - bugfix: We've fired the old Pope, who was actually an apprentice in disguise. + We've a-pope-riately replaced him with a much more experienced magic user. + - rscadd: Some less-then-sane people have been sighted forming mysterious cults + in lieu of recent Pope sightings, lashing out at anyone who speaks ill of him. + - bugfix: We've rejiggered our trans-dimensional rifts, and almost all cases of + clergy members being flung into nothingness should be resolved. + - bugfix: All members of the Space Wizard's Clergy have been appropriately warned + about usage of skin-to-stone spells, and such there should be no more instances + of permanent statueification. + Xhuis: + - tweak: Revenants have been renamed to umbras and have undergone some tweaks. + coiax: + - rscadd: Drones can hear robotic talk, but cannot communicate on it. AIs and cyborgs + are encouraged to share information with station repair drones. + - rscadd: Potted plants can now be ordered from cargo. + - rscdel: AI turrets no longer fire at drones. +2016-06-20: + Kor: + - rscadd: Cult runes can only be scribed on station and on mining. + - rscadd: The comms console now has a new option allowing you to communicate with + the other server. + Quiltyquilty: + - rscadd: The detective has been moved to above the post office. + coiax: + - rscadd: Birdboat's supply loop has been split into two unconnected halves, to + maintain award winning air quality. + incoming5643: + - experiment: New abilities for some races! + - rscadd: Skeletons (liches) and zombies now are much more susceptible to limb loss, + but can also reattach lost limbs manually without surgery. + - rscadd: Slimepeople can now lose their limbs, but also can regenerate them if + they have the jelly for it. Additionally slimepeople will (involuntarily) lose + limbs and convert them to slime jelly if they're extremely low on jelly. + - rscadd: Zombies and slimepeople now have reversed toxic damage, what usually heals + now hurts and what usually hurts now heals. Keep in mind that while you could + for example heal with unstable mutagen, you'd still mutate. Beware of secondary + effects! Drugs like antitoxin are especially dangerous to these races now since + not only do they do toxin damage, but they remove other toxic chems before they + can heal you. Be wary also of wide band healing drugs like omnizine. + - rscadd: For slime people the above mechanic also adds/drains slime jelly. So yes + inhaling plasma is now a valid way to build jelly (but you'll still suffocate + if there's no oxygen). + - rscadd: Pod people now mutate if shot with the mutation setting of the floral + somatoray. +2016-06-22: + Cheridan: + - tweak: Flashes no longer stun cyborgs, instead working almost exactly like a human, + causing them to become confused and unequip their current module. + Joan: + - rscdel: Those who do not serve Ratvar cannot understand His creations. + - rscadd: You can now repair clockwork structures with a clockwork proselytizer. + This is about a third as efficient as a mending motor, costing 2 liquified alloy + to 1 health, and also about a third as fast. + - tweak: Scarab proselytizers are more efficient and will reap more alloy from metal + and plasteel. + - rscadd: They can also directly convert rods to alloy. + - tweak: Nuclear bombs will no longer explode the station if in space. Please be + aware of this. + Kor: + - rscadd: You can now pick up potted plants. + PKPenguin321: + - rscadd: You can now pick up a skateboard and use it as a weapon by dragging it + to yourself. + - imageadd: Skateboards have been given brand new sprites, courtesy of JStheguy + Quiltyquilty: + - rscadd: The AI is back in the center of the station. The gravity generator is + now where the SMES room used to be. The SMESes are in the equipment room. + Supermichael777: + - rscadd: Flaps are no longer space-racist and now accept all bots. + Xhuis: + - tweak: Holy weapons, such as the null rod and possessed blade, now protect from + Ratvar's magic. + coiax: + - rscadd: Certain custom station names may be rejected by Centcom. + - rscadd: Drone shells can be ordered in Emergency supplies at Cargo. +2016-06-23: + Joan: + - tweak: Tinkerer's Caches generate components(when near clockwork walls) every + minute and a half, from every 35 seconds. Clockwork Slabs generate components + once per minute, from once per 50 seconds. + - tweak: Spatial Gateway will last four seconds per invoker, instead of two per + invoker. + - rscdel: Clockwork floors now only heal toxin damage on servants of Ratvar. + - rscdel: You can no longer place ocular wardens very close to other ocular wardens. + - tweak: The Flame produced by a Judicial Visor is no longer an effective melee + weapon and will trigger on all intents, not just harm intent. + Wizard's Federation: + - bugfix: Acolytes of Hades have revealed their true forms. + - rscadd: We've discovered a way to traverse portals left behind by Hades, and have + discovered a great treasure through it. + - bugfix: Hades has undergone Anger Management classes, and should no longer remain + wrathful for the duration of his visit. + coiax: + - rscadd: Changelings now evolve powers via the cellular emporium, which they can + access via an action button. + - rscadd: Due to budget cuts, the shuttle's hyperspace engines now create a visual + distortion at their destination, a few seconds before arrival. Crewmembers are + encouraged to use these "ripples" as an indication of where not to stand. + - bugfix: Shuttles now only run over mobs in turfs they are moving into, rather + than the entire rectangle. + - rscadd: If you are an observer, you can click on transition edges of a Z-level + in order to move as a mob would. + - rscadd: Due to safety concerns, the Hyperfractal Gigashuttle now has some safety + grilles to prevent accidental matter energising. + coiax, incoming: + - rscadd: Due to budget cuts, the builtin anti-orbit engines on the station have + been removed. As such, expect the station to start orbiting the system again, + and encounter an unpredictable stellar environment. + - rscdel: All permanent structures (not on station, Centcom or lavaland) have been + removed. + - rscadd: All removed structures are now space ruins, and can be placed randomly + in space ruin zlevels. + - wip: The White Ship remains at its current location, but has lost any reliable + landmarks near it. Its starting position will be made more random in a coming + update. + - rscadd: The Space Bar has a small atmos system added and a teleporter. Some other + ruins have been cleaned up to not have atmos active turfs. +2016-06-24: + Joan: + - experiment: The Interdiction Lens has been reworked; instead of allowing you to + disable Telecomms, Cameras, or non-Servant Cyborgs, it drains power from all + APCs, SMES units, and non-Servant cyborgs in a relatively large area, funneling + that power into nearby Sigils of Transmission, then disables all cameras and + radios in that same area. + - wip: If it fails to find anything it could disable or drain any power, it turns + off for 2 minutes. + - tweak: You can now target yourself with Sentinel's Compromise, allowing you to + heal yourself with it. + - rscadd: Flashes will once again stun borgs, but for a much shorter time than they + previously did; average stun time is reduced from the previous average of 15 + seconds to about 6 seconds. The confusion remains, but it will no longer unequip + borg modules. + MMMiracles: + - tweak: Metastation xenobiology's lights and cell have been modified so it won't + drain 5 minutes into the round. + SnipeDragon: + - bugfix: Changelings created at round start now correctly receive their Antag HUD. + Xhuis: + - rscadd: Cardboard cutouts have been added. Now you can set up advertisements for + your clown mart. +2016-06-26: + Basilman: + - rscadd: The Donor prompt for becoming an alien queen maid is now an action button + instead, and can be toggled on and off. + Joan: + - rscadd: Fellowship Armory now invokes faster for each nearby servant and provides + clockwork gauntlets, which are shock-resistant and provide armor to the arms. + - tweak: It's not wise to equip clockwork armor if you don't serve Ratvar. + - bugfix: A full set of clockwork armor will now actually cover all limbs. + coiax: + - rscadd: Our administrators, here at /tg/, don't get enough credit for their wealth + of experience and knowledge. Now they get the chance to share that with you + by giving out custom tips! + - tweak: Gang domination now uses the same timing method as shuttles, making their + domination times more accurate. + - rscdel: The default shuttle transit time is now 15 seconds. + - rscadd: Please do not commit suicide with the nuclear authentication disk. + - rscadd: Observers now have a visible countdown for borg factories, silicons can + examine the factory to determine how long it has remaining until it is ready. + - rscadd: Clockwork mobs sound like Ratvar chants if you do not serve Ratvar. + - rscadd: When servants recite, they now talk in a strange voice that is more noticable. +2016-06-28: + CoreOverload: + - rscadd: Kinetic accelerator now supports seclite attachment. + - rscadd: All cyborgs have been outfitted with ash-proof plating. + - rscadd: Mining cyborg module now includes a welder and a fire extinguisher. + - rscadd: 'Mining cyborgs now have a new upgrade: lavaproof tracks.' + Joan: + - rscdel: Clockwork Marauders are no longer totally invincible to damage unless + a holy weapon was involved. + - rscadd: Clockwork Marauders will take damage when attacked, but unless they're + fighting excessive amounts, they'll be forced to return to their host before + they'd normally die. + - experiment: A holy weapon held in either hand in the presence of a marauder will + massively increase the damage they take, making it much more likely the marauder + can be killed. + - tweak: Clockwork Marauders do slightly less damage at low fatigue levels. + - rscadd: Clockwork Marauders now have a chance to block melee attacks, negating + the damage from them, and an additional chance to immediately counter, attacking + whoever tried to attack them. + - wip: If Ratvar has awoken, Marauders have a much higher chance to block and counter, + will block thrown items and projectiles, and gradually regenerate. + - experiment: Clockwork Marauders no longer have a verb to communicate; they instead + use :b to do so. + - rscadd: Faked deaths are now effectively indistinguishable from real deaths. + MMMiracles: + - rscadd: Adds some ruins for space and lavaland. Balance not included. + - rscadd: Adds spooky ghosts. + SnipeDragon: + - bugfix: Cardboard Cutouts now become opaque when their appearance is changed. + Wizard's Federation: + - rscadd: Acolytes of Hades have been scolded for gluing their clothes to themselves, + and their clothes can now be cut off them. + - rscadd: Hades has learned a few new tricks, to ensure the ultimate demise of his + target. + - bugfix: Hades has faced a council of his repeated use of time magic inside chapels, + and as it was deemed unholy, he will no longer do it. + - rscadd: Wizards of the Wizard's Federation have been granted access to Dark Seeds, + ancient relics used to call upon Hades in a time of need. + Xhuis: + - rscdel: You can no longer put paper cups back onto water coolers. In addition, + they're now just called "liquid coolers" instead of changing based on their + contents. + coiax: + - rscadd: Status displays added to a variety of shuttle templates. + - rscdel: Large graffiti now consumes 5 uses from limited use crayons and spraycans, + as well as taking three times the amount of time to draw. + - rscadd: All items inside the supply shuttle will now be sold, regardless of whether + they're inside a container or not. + - bugfix: Fixes issue where the AI core APC on Metastation would not charge. + 'name: Lzimann': + - rscadd: Engineer and atmos wintercoat can hold the RPD now! + optional name here: + - rscdel: Shadowlings have been completely removed. + oranges: + - tweak: You can now hear dice + timkoster1: + - rscadd: adds a hud soul counter for devils. Sprites by PouFrou and special thanks + to lordpidey for about everything. +2016-06-29: + Joan: + - rscadd: Ghosts spawning via Ratvar can now choose to spawn as a Cogscarab with + a usable slab instead of as a Reclaimer. + - bugfix: You can no longer permanently block hostile simple mobs with sandbags + and other barricades. + MrStonedOne: + - rscadd: Ghosts may now jump between the two linked servers using the new Server + Hop verb. Rather than whine in deadchat about dieing, you can just go play a + new round on the other server. + coiax: + - rscadd: Adds a new UI to slimepeople, allowing them to select more easily which + body to swap to + - rscadd: Slimepeople swapping consciousness between bodies is now visible to onlookers + - bugfix: The AI malfunction "Hostile Lockdown" power now restores the station doors + to normal after 90 seconds, rather than keeping everything shut forever. diff --git a/html/changelogs/archive/2016-07.yml b/html/changelogs/archive/2016-07.yml new file mode 100644 index 0000000000..e240a6b065 --- /dev/null +++ b/html/changelogs/archive/2016-07.yml @@ -0,0 +1,523 @@ +2016-07-01: + Flavo: + - bugfix: fixed a bug where lights would not update. + Joan: + - rscadd: Clockwork Slabs now use an action button to communicate instead of the + "Report" option in the menu after using a slab. + - tweak: Clockwork Slabs now fit in pockets, the belt slot, or in the suit storage + slot(if wearing clockwork armor), where they can be used as hands-free communication. + - imageadd: Clockwork items with action buttons have a new, clockwork-y background. + - rscadd: Judicial Visors now tell the user how many targets the Judicial Blast + struck. + - soundadd: Judicial Markers now have sounds when appearing and exploding. + - tweak: Wet turfs should remain that way for slightly longer than 5 seconds now. + - rscadd: Drones and Swarmers should now sound more robotic. + - tweak: Ratvarian Spears will stun cyborgs and cultists for twice as long when + thrown; on cyborgs, this should be long enough to use Guvax on them. + - rscdel: Removed the Justicar's Gavel application scripture. + - tweak: Vitality Matrices will drain and heal 50% faster, and the base cost to + revive is 20% lower; 20, from 25. + - rscadd: Vitality Matrices will not revive or heal corpses unless they can grab + the ghost of the corpse, and will immediately grab the ghost when reviving. + - rscadd: Swarmers consuming swarmer shells now refunds the swarmer the entire cost + of the shell instead of 2% of the shell's cost. + - experiment: Application scriptures require at least 75 CV, from 50. + - experiment: Revenant scriptures require at least 4 Caches, from 3, and at least + 150 CV, from 100. + - experiment: Judgement scripture requires at least 12 servants, from 10, 5 Caches, + from 3, and at least 250 CV, from 100. + - experiment: Script and Application scripture have had their component costs and + requirements tweaked to reduce overuse of certain components. + - wip: Invoke times for a few scriptures that were instant are now very short instead. + Kor: + - rscdel: Holoparasites are no longer in the uplink + NikNak: + - tweak: Showcases are now movable and deconstructable. Wrench them to unanchor + and then screwdriver and crowbar to deconstruct. + Papa Bones: + - tweak: Security now has energy bolas available to them in their vending machines, + check them out! + bobdobbington: + - rscadd: Added skub to the AutoDrobe as a premium item. + coiax: + - rscadd: The CTF arena regenerates every round, and the blue team now shoot blue + lasers. + - rscadd: Adds some descriptions to alien surgery tools + - rscadd: The agent vest can be locked and unlocked (toggling the NODROP flag) + - rscadd: An abductor team can spend data points to purchase an agent vest (note + that only abductor agents are trained in their use) + - rscadd: The nuke disk reappears on the station in far more random locations, but + tends to re-materialise in safe pressurised areas that aren't on fire. + 'name: Lzimann': + - tweak: Mulebots with pAI cards no longer stun people +2016-07-02: + Joan: + - rscadd: Clockwork Proselytizers can now reform stored alloy into usable component + alloy when used in-hand. + - rscdel: Mending motors start with 2500W of power in alloy, from 5000. Sigils of + Transmission start with 2500W of power, from 4000. Clockwork Proselytizers start + with 90 alloy, from 100. + - rscdel: Umbras have been removed. + - rscadd: Revenants have been readded, though they are now vulnerable to salt piles. + MMMiracles: + - rscadd: Added the power fist, a gauntlet with a piston-powered ram attached to + the top for traitors to punch people across the station. Punch people into walls + for added fun. + incoming5643: + - rscadd: 'Nuke ops can now harness the power of METAL BOXES: special versions of + cardboard boxes that can take a lot of abuse and can fit the whole team if need + be. They''re not nearly as light as their cardboard brothers though...' + kevinz000: + - rscadd: Some new emojis have been added to OOC for your enjoyment. Try them out. + - rscadd: 'New emojis are : coffee, trophy, tea, gear, supermatter, forceweapon, + gift, kudzu, dosh, chrono, nya, and tophat. Type :nameofemoji: in OOC to use.' +2016-07-03: + Cruix: + - bugfix: Hand labelers can now label storage containers. + - bugfix: You can now properly resist out of wrapped lockers. + - bugfix: You can now resist out of morgues if you are in a bodybag. + - bugfix: Mechs can no longer spam doors they do not have access to. + Joan: + - tweak: Clock Cult can now happen at 24 players, same as cult. + - tweak: Clock Cult player scaling is lower; 3 people, plus one for every 15 players + above 30, from 1 for every 10 players with a player minimum of 30. + - experiment: Guvax now invokes 1 second faster(5 seconds), but is 0.75 seconds + slower for each scripture-valid servant above 5, up to a maximum of 15 seconds. + - experiment: Clockwork Slabs generate components 20 seconds slower for each scripture-valid + servant above 5, up to a maximum of 1 component every 5 minutes. + - tweak: Tinkerer's Daemons that would be useless cannot be made. +2016-07-04: + Gun Hog: + - rscadd: The Space Wizard Federation has finally begun teaching its pupils how + to properly aim the Fireball spell! + - tweak: Fireball spells, including the Devil version, are now aimed via mouse click. + It is recommended to avoid firing at anything too close, as the user can still + blow himself up! + Joan: + - rscdel: Mecha are no longer immune to ocular wardens. + Lzimann: + - rscadd: Throwing active stunbatons now has a chance to stun whoever it hits! + MMMiracles: + - rscadd: Adds space ruins. Balance not included. + - tweak: Simple mob ghosts actually work now. + - rscdel: Puzzle1 ruin removed due to issues with projectiles. + X-TheDark: + - rscadd: Switching mobs/ghosting/etc related actions during the round will now + no longer reset your hotkey settings. + Xhuis: + - bugfix: Ash storms can now occur again. + bgobandit: + - rscadd: Bluespace polycrystals, basically stacks of bluespace crystals, have been + added. The ore redemptor accepts them now. + - tweak: The ore redemptor machine should be less spammy now. + coiax: + - rscadd: The zone of hyperspace that a shuttle travels in is dynamically determined + when a shuttle begins charging its engines. This is signified by the shuttle + mode IGN. All shuttles must now charge engines before launching. This time is + already included in the emergency shuttle timer. + - rscdel: The cargo shuttle can only be loaned to Centcom while at Centcom. + - rscadd: Immovable rods now notify ghosts when created, allowing them to orbit + it and follow their path of destruction through the station. + - bugfix: Fixed bugs where no meteors would come or go from the south. Seriously, + that was a real bug. Meteor showers are now about 33% stronger as a result. +2016-07-06: + Cruix: + - bugfix: Vending machine restocking units now work. + Joan: + - rscadd: Servants should now be more aware of when scripture tiers are locked or + unlocked. + - experiment: Judicial Explosions from a Judicial Visor now mute for about 10 seconds. + MrStonedOne: + - rscadd: Instant Runoff Voting polls are now available. + RemieRichards: + - tweak: Fixes accidental buff to botany, all modifiers should now be at the point + they were at pre-bees (this does not remove, nerf or alter bees) + Xhuis: + - rscadd: The Necropolis gate now looks as regal as it should. Credit goes to KorPhaeron + for turf and wall sprites. + - bugfix: Ash storms are actually damaging now. + coiax: + - bugfix: Gulag prisoners can no longer duplicate their mining efforts through window + breaking on the shuttle. + - bugfix: Fixes pickaxes inside walls on lavaland, along with lava having eaten + one of the storage units. + - rscadd: More fire extinguishers for lavaland mining base. + - bugfix: You can now reload your gun in CTF. + - rscadd: Dying in CTF will spawn a short lived ammo pickup, which you can walk + over to reload all your weapons. + - rscadd: If reduced to critical status in CTF, you will automatically die, so you + no longer have to succumb or be coup de graced. If you are conscious, you will + now heal slowly if some damage got through your shield and didn't crit you. + - bugfix: The tesla now dusts all carbon mobs on the turf that it moves to, grounding + rod or no. + coiax, Niknakflak: + - rscadd: Added fireplaces, fuel with logs or paper and set on fire and enjoy that + warm comforting glow. + - bugfix: Cardboard cutouts are now flammable. + - rscadd: Cigarettes, fireplaces and candles now share a pool of possible igniters. + So you can now esword that candle on, but turn it on first. + - rscadd: Eswords will ignite plasma in the air if turned on. + kevinz000: + - tweak: Kudzu is no longer unstoppable + optional name here: + - bugfix: Suit Storage Units can now disinfect items other than living and dead + creatures. +2016-07-09: + CoreOverload: + - rscadd: You can remove jetpack from a hardsuit by using screwdriver on it. + Crazylemon: + - bugfix: The map loader no longer resets when reading another map mid-load + Goofball Sanders: + - rscadd: Added a new plant to the game to encourage the Chef to be a more relevant + job, alongside a recipe for a food related to it. Throw a cannabis leaf on a + table and check the recipes list to find it. + Gun Hog: + - rscdel: Malf (Traitor) AI's Fireproof Core ability has been removed, as it was + entirely obsolete. + - rscadd: Nanotrasen is proud to announce that conveyor belts can now be fabricated + at your station's autolathes! + Iamgoofball: + - bugfix: Fixes the Atheist's Fedora's throw damage. + Joan: + - rscadd: Tips for Clock Cult may now show up. + - experiment: The global component cache can only be accessed by clockwork slabs + if there is at least one Tinkerer's Cache active. + - rscadd: Ratvarian Spears are now sharp and can be used to cut off limbs or butcher + mobs. + - rscadd: Clock Cult silicons get an action button to communicate with other servants. + - tweak: Clockwork Slabs now produce a component every 1 minute, 30 seconds, from + every 1 minute. + - experiment: The slab production time gain from each servant above 5 has been increased + from 20 seconds to 30 seconds, and the maximum production time has been increased + from 5 minutes to 6 minutes. + - rscadd: You can now transfer components between two clockwork slabs by attacking + one slab, or a person holding a slab, with the other; this will transfer the + attacking slab's components into the target slab. + - tweak: Application scripture now requires 100 CV, from 75, Revenant scripture + now requires 200 CV, from 150, and Judgment scripture now requires 300 CV, from + 250. + - experiment: However, converted windows, windoors, airlocks, and grilles will all + provide some CV. + Lzimann & Keekenox: + - rscadd: You can now craft a baseball bat with 5 sheets of wood! + MrStonedOne: + - experiment: Atmos on planets is now more realistic. There is an unseen upper atmosphere + that gas changes get carried away into, causing planet turfs to revert back + to their original gas mixture. + - tweak: This should massively improve atmos run speed as all of lavaland won't + be processing the moment somebody opens a door anymore + MrStonedOne, coiax: + - rscadd: View Variables can expand on associated lists with type keys. Only 90s + admins will truely understand. + RemieRichards: + - rscadd: Added a Compact mode to the crafting tgui + - tweak: Modified the back end of the crafting tgui so that it has well let's just + say "a lot less" calls to certain functions, should lag a little less but don't + expect miracles (you'd have to wait till we get a new version of ractive for + those!) + coiax: + - rscadd: Podpeople (and venus human traps) are now no longer damaged, poisoned + or obstructed by space vines. Explosive vines still damage them, because there's + an actual explosion. + - rscadd: During a meteor shower, observers can automatically orbit threatening + meteors via an action button and watch them hit the station. + - rscadd: Added Major Space Dust event, which is a meteor shower containing only + space dust. + - bugfix: Fixes bug where meteors wouldn't move when spawned. + - rscadd: Meteor Shower split into three different events, Normal, Threatening and + Catastrophic. They all have the same crew messages, but admins can tell the + difference. + - bugfix: Damage to a shuttle while it is moving will now correctly make transit + space turfs, rather than non-moving space. + - rscadd: AIs get a notification when hacking an APC, which can be clicked to jump + your camera to the APC's location. AIs also get notification sounds when a hack + has completed or failed. + - rscadd: Nuclear bombs now use a more accurate timer system, the same as gang dominators + and shuttles. + - rscadd: Nuclear bombs now have a TGUI interface. + - rscdel: Fleshmend no longer regrows lost limbs. + - rscadd: Added free Regenerate power to changelings, which regrows all external + limbs and internal organs (including the tongue if you lost your head). It costs + 10 chemicals to use. + - rscadd: Fleshmend now costs 20 chemicals, down from 25. + - tweak: Changeling revive power name changed from Regenerate to Revive. + - rscadd: When a player uses a communication console to ask for the codes to the + self destruct, for better or for worse, the admins can set them with a single + click. Whether the admins a) click the button b) actually give the random person + the codes, is another thing entirely. + - rscadd: Servants of Ratvar get an alert if they have no tinkerer's caches constructed. + Because it's important that they should. +2016-07-11: + Iamgoofball: + - bugfix: Fixes Nicotine's stun reduction + Joan: + - tweak: The Function Call action that summons a Ratvarian Spear is no longer one-use; + instead, it can be reused once every five minutes. + - experiment: Clockwork Walls and Floors will appear as normal walls and plating + to mesons, respectively. + coiax: + - tweak: Syndicate bombs now use a more accurate timer. + - bugfix: Fixed a separate bug that caused bomb timers to take twice as long (ie. + 60 seconds took 120 seconds) + - tweak: The AI doomsday device timer is more accurate. + - bugfix: Fixes a bug where the doomsday device would take twice as long as it should. + optional name here: + - bugfix: The search function on security records consoles now works. +2016-07-12: + MMMiracles: + - bugfix: Hotel staff can now actually use their own lockers. + RemieRichards: + - bugfix: fixed Kor's plant disguises + - bugfix: fixed some issues with Alternate Appearances not being added/removed + hornygranny: + - bugfix: Attacks will no longer miss missing limbs +2016-07-14: + Basilman: + - rscadd: Added a new hairstyle "Boddicker" + Bawhoppen: + - rscadd: Added two new materials, Titanium and plastitanium. Titanium is naturally + occuring, and plastitanium is an alloy made of plasma and titanium. + - rscadd: These materials can be used to build shuttle walls and floors, though + this serves no current purpose. + CoreOverload: + - rscadd: Some clothing has pockets now. + Firecage: + - tweak: Mechas can no longer pass through Plastic Flaps + Fox McCloud: + - bugfix: Fixes borg stun arm not having a hitsound, bypassing shields, and not + doing an attack animation + - bugfix: Fixes simple mobs not properly having armor penetration + Joan: + - rscadd: Added dextrous guardians to the code, able to hold and use items and store + a single item within themselves. + - experiment: Dextrous guardians do low damage on punches, have medium damage resist, + and recalling or leashing will force them to drop any items in their hands. + Kor: + - tweak: Shuttle travel time has been shortened from 25 seconds to 6 seconds + Lzimann: + - tweak: Alt clicking a jumpsuit now removes the accessories(if there's any)! + Papa Bones: + - tweak: Security's lethal injections are actually lethal now. + Xhuis: + - rscadd: Nanotrasen electricians have introduced a software update to all licensed + pinpointers. The new pinpointers are more responsive and automatically switch + modes based on the current crisis. + - rscadd: It should be noted that some of these pinpointers have been reported as + missing from their distribution warehouse and are presumed to have been stolen. + This is likely nothing to worry about. + lordpidey: + - tweak: Infernal jaunt now has a cooldown, to prevent trying to jaunt while already + jaunting. This should have no practical changes. + - bugfix: Infernal jaunt no longer occasionally leaves you permanently on fire. + - bugfix: Pitchforks no longer burn devils and soul-sellers, as intended. +2016-07-15: + Cheridan: + - rscadd: Added an aesthetic new space ruin +2016-07-16: + Gun Hog and WJohnston: + - rscadd: Aliens (Xenos) now have the ability to sense the direction and rough distance + of their queen! + Iamgoofball: + - bugfix: Fixed the lag when opening the foodcrafting menu by splitting everything + up into categories. + Joan: + - rscadd: Cogscarabs(and other nonhuman mobs able to hold clockwork slabs) can now + check the stats of the clockwork cult by using a clockwork slab. They remain + unable to use slabs under normal conditions. + MrStonedOne: + - experiment: Added a system to detect when stickybans go rogue and revert all recent + matches. +2016-07-18: + CoreOverload: + - rscadd: Sterilizine now reduces probability of step failure if you apply it after + starting surgery. Useful while operating in less-than-perfect conditions. + - rscadd: Potent alcohol can be used as replacement for sterilizine. + Joan: + - experiment: The Vanguard scripture no longer prevents you from using slabs while + active, but you cannot reactivate it if it is currently active. + - tweak: It now only lasts 20 seconds, instead of 30. + - tweak: When Vanguard deactivates, it now stuns for half the time of all stuns + absorbed, instead of all of them. + - tweak: Invoking Sevtug is less potent at long ranges, and slightly more potent + if extremely close. + - experiment: Invoking Sevtug now requires 3 invokers instead of 1. + - rscadd: The Clockwork Slab now has action buttons for rapidly invoking Guvax and + Vanguard. + - tweak: Belligerent is now chanted more often. + - experiment: Taunting Tirade now weakens nearby nonservants, but is now only invoked + once every 6 seconds(1 second chant, 5 second flee time) and is only chanted + five times. + lordpidey: + - rscadd: Flyswatters are now included in beekeeping crates, they are great at killing + insects and flies of all sizes. +2016-07-19: + Joan: + - tweak: Cogscarabs can no longer pass mobs and have slightly less health. + - experiment: The Gateway to the Celestial Derelict can now take damage from bombs. + RemieRichards: + - rscadd: Added VR Sleepers that allow users to enter a virtual body in a virtual + world (Currently not mapped in ;_;) + Xhuis: + - rscadd: Added communication intercept texts for gamemodes that were missing them. + - tweak: Changed all intercept texts and improved grammar for a lot of key game + code. + - rscdel: The shuttle can now leave while a celestial gateway exists. + - rscadd: If the shuttle docks at Central Command while a celestial gateway exists, + Ratvar's servants will win a minor victory. His arrival will still award a major + victory. + - rscadd: The celestial gateway can now take damage from explosions. +2016-07-22: + Bawhoppen: + - rscadd: Titanium now spawns in mining again. + - rscadd: It has uses in R&D and robotics production. + - rscadd: All shuttle walls are now using a new proper smoothing path. Mappers please + make sure to use this path correctly in the future. (along with tiles) + Cheridan: + - rscadd: Added another space ruin. + Cruix: + - bugfix: Camera bugs can now show camera views. + - bugfix: The chameleon masks in the chameleon kit can once again have their voice + changers toggled. + Incoming5643: + - rscadd: You now have the ability to automatically "back out" of a round if you + miss your chance at all the jobs you have set to low or higher. This is found + on the toggle at the bottom of the jobs window + - rscadd: Due to a quirk of game mode code this option will fail to work if you've + been selected as an antag (what a tragedy!) In this situation, you'll be assigned + a random job. + Joan: + - bugfix: You can now throw items and mobs over chasms without causing them to drop. + - bugfix: You can now throw items over lava without burning them. Mobs will still + burn, however. + - experiment: Tinkerer's Caches now link to a nearby unlinked clockwork wall, and + will not generate components unless linked. As compensation, they will link + to nearby walls(and can generate components) in a larger area. + - wip: Guvax is now slightly slower when above 5 valid servants; 1 additional second + of invoke time for each one above 5, from 0.75 additional seconds, up to a maximum + of 20 seconds of invoke time, from 15 seconds. + - tweak: Sigils of Transgression now stun for about 7 seconds. + - experiment: Sigils of Submission/Accession now take 7 seconds to convert successfully, + and have an obvious message to the person on them that their mind is being invaded. + - tweak: Ocular Wardens do 17% less damage. + - tweak: Mania Motors cause less brain damage and hallucinations. + - rscadd: If you lack the components to recite a scripture, you will be informed + of how many components that scripture requires. + - experiment: Tinkerer's Caches now cost an additional one of each non-alloy component + to construct for every three existing Tinkerer's Caches, up to a maximum of + 5 of each non-alloy component. + - rscadd: Revenant scriptures now announce to all servants and ghosts when used + instead of having a visible message. + Lzimann: + - tweak: Blood packs are now back in surgery room. + MMMiracles: + - rscadd: A giant wad of paper has been seen hurling through the nearby sector of + SS13, officials deny existence of giant paper ball hurling through space because + 'thats really fucking stupid'. + MrStonedOne: + - bugfix: Fixes super darkness from lighting creating two darkness overlays on the + same turf but only changing the darkness of one of the overlays + PKPenguin321: + - rscadd: Added Canned Laughter for the clown. Hehehe + RemieRichards: + - tweak: Auto-generated ratvarian now follows all the rules of hand-written ratvarian, + but you probably won't notice. + Shadowlight213: + - tweak: Angels can now equip satchels + - rscadd: Players will now receive an achievement for killing their first megafauna + after this point. + - rscadd: Additionally, megafauna kills are now tracked on a hub page. Rack up those + kills for first place! + Xhuis: + - rscadd: Clockwork cultists may now have the "Escape" and "Silicon" objectives, + requiring a certain amount of servants to escape on the shuttle and all silicons + to be converted respectively. + - rscadd: Ocular wardens are now forced to target bibles rather than the people + holding them. +2016-07-28: + Cruix: + - bugfix: Fixed a bug where some objects in photos would not be displayed if they + were facing a certain direction. + - bugfix: Photograph descriptions will no longer claim that mobs with low max health + are hurt when they are not. + Incoming5643: + - rscadd: The previously underwhelming viscerator robot has been made a lot more + terrifying by the new ability to proactively target and dismember limbs. + Joan: + - tweak: The Tinkerer's Cache cost increase for having multiple Tinkerer's Caches + now happens every 5 caches, from every 3. + - experiment: If the invoker of Nzcrentr is knocked unconscious or killed, they + will gib instead of producing a lighting blast. + - tweak: Anima Fragments slow down for slightly less time when hit. + - tweak: Clockwork Marauders do 1 more damage on every attack. + - tweak: Wraith Spectacles are now less hard on the eyes, and can be used without + permanent vision impairment for about 50% longer; from 40~ seconds to about + 1 minute. + - tweak: Halves the Interdiction Lens' disrupt cost from 100 per disrupted object + to 50 per disrupted object. + - tweak: Clockwork Sigils will now be destroyed by any level of explosion, except + for Sigils of Transmission, which will gain a small amount of power if hit by + a light explosion instead of breaking. + - bugfix: Clockwork Structures will now properly take damage from explosions instead + of variably not taking damage or instantly being destroyed. + - rscadd: Ghosts can now click Spatial Gateways to teleport to the other gateway. + - bugfix: Spatial Gateways are now properly disrupted by devastating explosions(but + not heavy or light explosions) + - rscadd: Striking a Sigil with any damaging item as a non-servant will remove it. + Servants still need to be on harm intent with an empty hand to remove Sigils. + Kor: + - rscadd: The Staff of Storms, dropped by Legion, can now be used on station. + MMMiracles: + - rscadd: Adds jump boots, a mid/end-tier mining equipment that allows the user + to dash over 4-wide chasms. + ModernViolence: + - bugfix: Hulk now has default cooldown for melee attacks against dominator + MrStonedOne: + - tweak: Space wind (movement from pressure differentials (like a hole to space)) + has been improved. + - tweak: Space wind's rate of movement now scales with pressure differential amount. + - experiment: Actively moving (as in holding down a move key) reduces chance/rate + of getting moved by space wind. + - rscadd: 'Having a wall or dense anchored object to your left or right will lower + the chance/rate of getting moved by space wind for each direction (IE: a wall + on both sides of you will be a double reduction)' + - rscadd: Added Lazy airlock cycling. Bump opening an airlock with this system will + close its partner. This system has been added to most airlocks that go to space + on boxstation, as well as airlocks to secure areas like brig, bridge, engine. + - tweak: This can be overridden by click opening, having a shuttle docked, or setting + emergency mode on one of the doors. + PKPenguin321: + - bugfix: Laughter no longer makes you laugh if you're muted. + - rscadd: Laughter can now be brewed with banana juice and sugar. + Thunder12345: + - rscadd: An old rapier was found rusting in the back of a closet. We cleaned it + up, polished it, and assigned it to your captain as a ceremonial weapon only. + Warranty void if used in combat. + incoming5643: + - tweak: viscerator grenades are now more generous with viscerators spawned +2016-07-30: + astralenigma: + - bugfix: Admins can now turn people into red god. +2016-07-31: + Arctophylax: + - bugfix: Birdboat's atmospheric tanks now function normally again. + - bugfix: Birdboat's TEG is now orientated to match the pipe layout. + Bawhoppen: + - tweak: toolboxes fit in backpacks + Gun Hog: + - rscadd: In an effort to reduce the demoralizing effects that accompany the death + of a crew member, Nanotrasen has provided the prototype designs for the Sad + Trombone implant. It can be fabricated at your station's protolathe, if you + manage to secure the ever elusive Bananium ore. + Joan: + - rscadd: Megafauna will now seek and consume corpses of enemies to heal or otherwise. + - tweak: Toolboxes are slightly more robust. + - tweak: Vanguard now only stuns for 25% of absorbed stuns, from 50%. + Kor: + - rscadd: Hostile mobs will now attack turrets. + Robustin: + - rscdel: Amber ERT Commanders no longer have thermal goggles + lordpidey: + - rscadd: Added Devil agent gamemode, where multiple devils are each trying to buy + more souls than the next in line. + - rscadd: If you've already sold your soul, you can sell it again to a different + devil. You can even go back and forth for INFINITE POWER. diff --git a/html/changelogs/archive/2016-08.yml b/html/changelogs/archive/2016-08.yml new file mode 100644 index 0000000000..a76d4a9137 --- /dev/null +++ b/html/changelogs/archive/2016-08.yml @@ -0,0 +1,474 @@ +2016-08-01: + Bawhoppen: + - rscadd: Added crowns. Make them from gold. Cap gets a fancy one. + Fox McCloud: + - rscadd: Adds in generic uplink refund system that potentially allows for even + regular traitors to refund uplink items + Joan: + - rscadd: Soul Vessels can now be used on unconscious or dead humans to extract + their consciousness, much like a soulstone. + - tweak: Soul Vessels no longer automatically ping ghosts when created, though they + can still be used in-hand to ping ghosts. + - rscadd: Soul Vessels can now communicate over the Hierophant Network + - experiment: Xenobiology golems enslaved to someone will become convertable if + their enslaver is converted to the enslaving antag type; this applies to gang + and both cult types. + oranges: + - rscdel: Reverted toolboxes fitting in backpacks due to being incorrectly merged +2016-08-02: + CoreOverload: + - rscadd: Pockets in coats! +2016-08-05: + Arctophylax: + - bugfix: The Emergency Medical and Winter Wonderland Holodeck programs work once + again. + Cruix: + - bugfix: RCDs can no longer place multiple grilles on the same tile. + - bugfix: RCDs will no longer use all their ammo if you try to build a wall on the + same turf multiple times. + - tweak: RCDs will now inform their user if they do not have enough ammo to complete + an operation. + Incoming5643: + - rscadd: Parrots have been made more robust. + Joan: + - rscadd: Clockwork Constructs, including anima fragments, marauders, and reclaimers, + can now communicate over the Hierophant Network. + - rscadd: Plasma cutters(normal, advanced, and mech) now have double range in low + pressure areas, but slightly lower range in high pressure areas. + - rscadd: Vitality Matrices will consume dead non-servant mobs to gain a large amount + of Vitality. This doesn't work on mobs that did not have a mind at some point. + Lordpidey and PKPenguin321: + - rscadd: Recent studies have revealed that fly amanita can give you a huge trip. + Lzimann: + - tweak: Holy water no longers makes you confused. + ModernViolence: + - bugfix: 'Photocopier fixes: proper sprites for not empty copies; removing originals + now does not delete them' + PKPenguin321: + - rscadd: Chef, do your station a favor and make a home run baseball burger (TM) + Robustin: + - rscadd: The initial supply talisman can now be used to create runed metal, 5 per + use + - rscadd: The void torch is now available from the altar, use it to transport any + item instantly to any cultist! It appears alongside the veil shifter as part + of the "Veil Walker" set. + - rscadd: Cult floors no longer appear on mesons! + - tweak: Flagellant's Robes now increases damage taken by 50%, down from 100% + - tweak: Veil Shifter has 4 uses, up from 2 + - tweak: Shuttle curse now delays shuttle 3 minutes, up from 2.5 minutes + - tweak: Cult forges, archives, and airlocks have had their cost reduced by 1 runed + metal each + Shadowlight213: + - rscadd: You will now receive an achievement for winning a pulse rifle at the arcade. + TheCarlSaganExpress: + - rscadd: Added lighting effects to the welder. +2016-08-07: + Arctophylax: + - bugfix: You can unbuckle mobs from meat spikes by clicking on the spike once again. + Joan: + - tweak: Barrier runes will now block air while active. + - rscadd: Trying to use sleeping carp against the colossus will now anger it. + frtbngll: + - bugfix: Fixed Paper Wizard summoning only 9 minions in its lifespan by making + the dead stickman decrease it's summoned_minions variable + lordpidey: + - bugfix: Centcom has received reports of cyborgs electrocuting themselves when + working on the power grid, and we have decided to stop storing important electronics + on the wirecutter's blade. +2016-08-08: + Ergovisavi: + - rscadd: Added bonfires to botany. Requires five tower cap logs to create, and + mobs can be buckled to them if an iron rod is added to the bonfire and the mob + is restrained. + Joan: + - rscadd: Added the clockcult "Global Records" alert, which clock cultists can mouse + over to check a variety of information on the clockcult's status, including + living servants, number of caches, CV, tinkerer's daemons, if there's an unconverted + AI, what clockwork generals can be invoked, and what scripture is unlocked. + Shadowlight213: + - rscadd: Ghosts can now see human player's huds when using the OOC -> Observe verb + WJohnston, Gun Hog: + - tweak: Xenos are now considered female. + - tweak: Hunter pounce are now always blocked by shields, and may be blocked more + often by other protective items. + - tweak: Alien Queen is now somewhat faster. + - tweak: Adjusted larva growth sprites. + - tweak: Removed 20% facehugger failure chance for masks. + - tweak: Disarm now always forces a person to drop an item in the active hand, and + if a person's hand is empty/undroppable, Disarm will always result in a tackle. + - tweak: Cyborgs disarmed by a Xeno will first disable their selected module, and + if there is none selected, the cyborg will be pushed back and stunned. + - tweak: Tail Sweep now has a slightly longer stun. +2016-08-10: + Cruix: + - rscadd: Sentient minebots can now toggle meson vision, a flashlight, their mode, + and dump their stored ore. + - bugfix: Sentient minebots can now be repaired if they were made sentient while + the AI was active. + - bugfix: Healing minebots will no longer switch them to attack mode. + - tweak: Sentient minebots can now shoot at humans. + - bugfix: The cooldown on wizard lightning will no longer break if you ethereal + jaunt or RISE! after the initial cast. + Kor: + - rscadd: You can now detonate drones with the RD console + LanCartwright: + - rscadd: Acute respiratory distress syndrom symptom. + - rscadd: Toxic metabolism. + - rscadd: Alkali perspiration + - rscadd: Autophagocytosis Necrosis + - rscadd: Apoptoxin filter + - rscadd: 3 different lategame/Non-roundstart virus reagents + - rscadd: 4 different lategame/Non-roundstart virus recipes + MrStonedOne: + - tweak: Tweaked space wind, it should now only trigger at higher pressure differences, + but be quicker to become aggressive as the pressure difference gets higher. + This should alleviate issues where small differences was still moving a lot + of things. + - tweak: Paper still moves with any pressure difference. + PKPenguin321: + - rscadd: There's now an achievement for managing to examine a meteor as a living + mob! + RemieRichards: + - rscadd: 'Added a new PDA button/app: Drone Phone!' +2016-08-14: + Cheridan: + - tweak: Greatly reduced amount of Hydroponics yield multipliers + - tweak: Somewhat reduced gaia'd tray sustainability. + - tweak: Mutagen will no longer potentially cause plant instadeath based on RNG. + Ergovisavi: + - tweak: Watchers no longer randomly fire beams at you when damaged, and no longer + beam you at point blank. + Gun Hog: + - tweak: The AI's Crew Manifest button now uses the updated styling. + Joan: + - rscadd: Sigils of Transgression now glow brightly when stunning a target. + - rscadd: The Global Records alert now shows the location and countdown time of + the Gateway to the Celestial Derelict. + - tweak: Clockcult tooltips now all have the clockcult tooltip style. + - rscdel: You can no longer become a Reclaimer when clicking on Ratvar. You can + still become a Cogscarab, however. + - bugfix: You can no longer invoke Vanguard while under its effects. + - bugfix: Servants of Ratvar should now always get an announcement when scripture + states change. + - tweak: Function Call can be used to summon a Ratvarian Spear once every 3 minutes, + from 5, but the spear summoned will now only last 3 minutes. + - rscadd: Belligerent now does minor damage to the legs on each invocation, up to + a maximum of 30 damage per recital. + - tweak: Ratvarian Spears will now stun any mob they're thrown at instead of just + enemy cultists and silicons, though the stun is still longer on enemy cultists + and silicons. + Jordie0608: + - rscdel: Removed clicking clown mask to morph it's shape, use action button instead. + Kor: + - rscadd: Added support for projectiles which can dismember + - rscadd: Added a new wizard sword, the spellblade, which fires dismembering projectiles. + Sprites from Lexorion. + - rscadd: Plasmacutter blasts can now take limbs off, but they still do pitiful + damage in a pressurized environment. + - rscadd: Humans and drones now have a UI button that allows them to create new + areas, in the same manner as blueprints. Unlike blueprints, this button does + not allow you to edit existing areas. + - rscadd: You can now use mineral doors (or any other object that blocks atmos) + to complete rooms with blueprints + - rscadd: Players created by sentience potions, mining drone upgrades, or Guardian/Holoparsite + summoners will now automatically join the users antagonist team, if any. + - rscadd: Mobs created in this manner will no longer be convertable/deconvertable + unless their creator is first converted/deconverted. + - rscadd: Cayenne will now officially become an operative when given a sentience + potion. + LanCartwright: + - bugfix: Fixes the recipes not working. + - tweak: Changes Stable uranium virus food recipe from Plasma virus food to just + plasma. + RemieRichards: + - bugfix: You can no longer use the incorrect limb type during augmentation + - bugfix: You can no longer use the incorrect limb type during prosthetic replacement + Shadowlight213: + - rscadd: Security has two new weapons in their arsenal. The security temperature + gun, and the DRAGnet capture and recovery system. + optional name here: + - bugfix: The syndicate uplink ui has been refactored to majorly reduce lag +2016-08-15: + Joan: + - rscadd: The Ark of the Clockwork Justicar can now be constructed even if Ratvar's + rise is not the objective. + - experiment: Accordingly, its behavior is different; instead of summoning Ratvar, + it will convert a massive amount of the station, and should effectively instantly + complete the clockwork cult's objectives. + MrStonedOne: + - tweak: Tweaked the lag stop numbers to hopefully reduce lag during 80+ population + - tweak: Fixed the blackbox not blackboxing. + OSCAR MIKE: + - rscadd: CONTACT ON THE LEFT SIDE! +2016-08-16: + MrStonedOne: + - rscadd: Automated the granting of profiler access to admins + oranges: + - rscadd: Nanotrasen is an all right kind of company +2016-08-17: + Basilman: + - rscadd: Added an admin-spawnable only "Cosmohonk" hardsuit that has the same protection + values of an engineering hardsuit. Comes with built-in lights and requires clown + roundstart role to be equipped. + Ergovisavi: + - rscadd: Adds the "Proto-Kinetic Crusher", a new melee mining weapon. Available + at a mining vendor near you! + Gun Hog: + - tweak: Nanotrasen has improved the coolant system in the stations automated robots. + They will no longer violently explode in hot rooms. + Joan: + - rscadd: Once the blob alert message is sent in the blob game mode, all mobs get + to see how many tiles the blob has until it wins, via the Status tab. + - rscdel: Removed/merged a bunch of blob chems, you probably don't care about the + specifics. + - tweak: The remaining blob chems should, overall, be more powerful. + - tweak: Shield blobs soak brute damage less well. + - tweak: Flashbangs do higher damage to blobs up close, but their damage falls off + faster. + - experiment: Shield blobs now cost 15 resources to make instead of 10. Node blobs + now cost 50 resources to make instead of 60. + - experiment: Expanding/attacking now costs 4 resources instead of 5, and blobs + can now ATTACK DIAGONALLY. Diagonal attacks are weaker than normal attacks, + especially against cyborgs(which may be entirely immune, depending), and they + remain unable to expand diagonally. + - rscadd: Shield blobs no longer block atmos while under half health. Shield blobs + are still immune to fire, even if they can't block atmos. + - tweak: Blobs should block explosions less well. + - rscadd: Blob cores and nodes are no longer immune to fire and no longer block + atmos. + - rscadd: Blobs can only auto-expand one tile at a time per expanding thing, and + should be easier to beat back in general. + - tweak: Blobbernauts now attack faster. + - tweak: Blob Overminds attack mobs slower but can attack non-mobs much faster. + - rscadd: Blob Overminds start with some amount of resources; in the gamemode, it's + 80 divided by the number of overminds, in the event, it's 20 plus the number + of active players, and otherwise, it's 60. + - bugfix: You can no longer move blob cores into space, onto the mining shuttle, + white ship, gulag shuttle, or solars. + - bugfix: Blob rounds might be less laggy, if they were laggy? + - tweak: Blobs don't heal as fast, excluding the core. + - experiment: Blobs are marginally less destructive to their environment. + MrStonedOne: + - rscdel: The server will no longer wait until the next tick to process movement + key presses. Movements should now be ~25-50ms more responsive. + Shadowlight213: + - rscadd: Adds modular computers +2016-08-21: + Ergovisavi: + - tweak: Consolidates the fulton packs into a single item and makes them more user + friendly + Google Play Store: + - spellcheck: Minor Text Fixes. + Incoming5643: + - rscadd: Smuggler satchels left behind hidden on the station can now reappear in + a later round. + - experiment: There's absolutely no way of knowing when exactly it will reappear + however... + - rscadd: Only one item in the satchel will remain when the satchel reappears. + - rscadd: Items are saved in their initial forms, so saving things like chemical + grenades will only disappoint you. + - rscadd: The item pool is map specific and needs to be a certain size before satchels + can start reappearing, so get to hiding that loot! + - rscadd: The staff of change has been expanded to turn you into even more things + that don't have hands. + Jalleo: + - bugfix: Gulag Teleporter of two issues any more please report them. + Jordie0608: + - rscadd: Advanced Energy Guns once again have a chance to irradiate you if EMPed. + Kor: + - rscadd: Kinetic Accelerators are now modular. You can find mod kits in the mining + vendor and in RnD. + - bugfix: Chaplain's dormant spellblade is no longer invisible. + Papa Bones: + - rscadd: A new, scandalous outfit is now available as contraband from the clothesmate + vendor, check it out! Fulfill your deep, dark fantasies. + Shadowlight213: + - tweak: Service and cargo have lost roundstart tablets and engineering has gained + them + - tweak: you can now charge battery modules in cell chargers. Use a screwdriver + on a computer to remove them. As a note, tablets and laptops can be charged + directly by placing them in a security charger. + WJohnston: + - rscadd: Metastation and Boxstation now boast auxillary mining construction rooms + in arrivals. These allow you to build a base and then launch it to wherever + you want on lavaland. + Wjohnston, Gun Hog: + - rscadd: Aliens with Neurotoxic Spit readied will now have drooling animations. + - rscadd: Hunters may now safely leap over lava. + - tweak: Hulk punches no longer stun Xenos. + - tweak: Alien evolve and promotion buttons updated to current Xeno sprites + - bugfix: Handcuff sprites for Xenos now show properly. +2016-08-22: + Bawhoppen: + - rscdel: Stock computers have been temporarily removed due to imbalances. + Ergovisavi: + - bugfix: Bubblegum's charge indicator should be significantly more accurate now. + ExcessiveUseOfCobblestone: + - rscdel: Reverts getting partial credit for discovered seeds. + - tweak: 'Tweaks Money Tree Potency Values [For instance: 1000 Space Cash requires + 98-100 Potency]' + Lzimann & Lexorion: + - rscadd: Adds a bow to the game, currently not craftable + Shadowlight213: + - bugfix: The efficiency AI sat SMES will now charge the APCs instead of itself. + XDTM: + - rscdel: Removed the Longevity symptom. + - rscadd: Added Viral Aggressive Metabolism, which will make viruses act quickly + but decay over time. + - rscadd: Cloning can now give bad mutations if unupgraded! + - rscadd: Cloning can, however, give you good ones if upgraded! +2016-08-24: + Bones: + - rscadd: The detective's closet now contains a seclite, get sleuthing! + Cargo Intelligence Agency: + - rscdel: You don't get to bring traitor items. + Ergovisavi: + - rscadd: Adds "Sacred Flame", a spell that makes everyone around you more flammable, + and lights yourself on fire. Share the wealth. Of fire. + - tweak: Replaces the fireball spellbook as a possible reward from a Drake chest + with a book of sacred flame. + Gun Hog: + - rscadd: The Aux mining base can now call the mining shuttle once landed! The mining + shuttle beacon that comes with the base must be deployed to enable this functionality. + - tweak: Multiple landing zones may now be set for the mining base. + - tweak: The coordinates of each landing zone is shown in the list. + - rscadd: Miners now each get a remote in their starting lockers. tweak The Aux + mining base now requires lighting while on station. + - tweak: The Aux Mining Base now has a GPS signal. + - tweak: The Aux Mining Base now has an alarm for when it is about to drop. + Incoming5643: + - rscadd: 'A slight change to the secret satchel system described below: If a satchel + cannot be spawned due to there not being enough hidden satchels to choose from, + a free empty satchel will spawn hidden SOMEWHERE on the station. Dig + it up and bury it with something interesting!' + Joan: + - rscadd: Using a resonator on an existing resonator field will immediately detonate + that field. Normal resonators will reduce the damage dealt to 80% of normal, + while upgraded resonators will not reduce it at all. + - rscadd: Adds a KA mod that does damage in an AoE, found only in necropolis chests. + - rscadd: You can now install any KA mods into a mining cyborg, though its mod capacity + is slightly lower. + - tweak: Mining cyborgs now have a crowbar to remove mods from their KA. + - tweak: Kinetic Accelerators now have a larger mod capacity, though most mods can + still only be installed the same amount of times as they can currently. + - tweak: You can now hit modkits with Kinetic Accelerators to install that modkit + into the accelerator. Mining cyborgs are unable to do so. + - rscadd: Added white and adjustably-coloured tracer round mods to the mining equipment + vendor, so you can see where your projectile is going(and look cool). + - rscadd: Added the super and hyper chassis mods to the mining equipment vendor, + so you can use excess mod space to have a cool-looking KA. + MrStonedOne: + - rscdel: Removes check on lights preventing you from turning them on while in a + locker + PKPenguin321: + - rscadd: Xeno queens now have an action button that makes them appear to themselves + as the old, small queen sprite. Now they should be able to interact with things + that are above them more easily. + Shadowlight213: + - tweak: Reviver and nutriment implants are far easier to get and have lower tech + origins. + - rscdel: Centcom has cut back on their cat carrier budget and will now only be + able to bring kittens along with runtime. + - rscadd: A new event has been added. The automated grid check. All apcs in non + critical areas will be shut off for some time, but can be manually rebooted + via interaction. + Yackemflam: + - tweak: Boxes are worth >26 tc at LEAST +2016-08-28: + CoreOverload: + - tweak: You can now use sheets from any hand, not just the active one. + Iamgoofball: + - tweak: Station and Character names are now allowed to be longer. + - rscdel: Gender Reassignment surgery has been removed. + Incoming5643: + - experiment: 'Due to a bad case of "being terrible" the save system for secret + satchels has been reworked. All saves are now unified in a single data file: + /data/npc_saves/SecretSatchels' + - rscdel: 'Old savefiles such as: /data/npc_saves/SecretSatchels_Box Station can + now be safely removed.' + - rscadd: A new slime reaction has been found for pink slimes using blood. The potion + produced from this reaction can be used to change the gender of living things. + Decently useful for animal husbandry, but otherwise mostly just for pranks/"""roleplay"""/enforcing + a brutal regime composed entirely of female slime people. + Joan: + - bugfix: Bumping the AI on help intent will no longer cause it and you to swap + positions, even if it is unanchored. If unanchored, it will properly push the + AI around. + - rscadd: The staff of lava can now turn lava back into basalt. + - bugfix: Placing a singularity or energy ball generator directly in front of an + active particle accelerator may be a bad idea. + Kor: + - rscadd: Added Battlemage armour to the spellbook. The armour is heavily shielded, + but will not recharge once the shields are depleted. + - rscadd: Added armour runes to the spellbook, which can grant additional charges + to the Battlemage armour. + MrStonedOne: + - rscadd: The game window will now flash in the taskbar on incoming admin pm, and + to all admins when an admin help comes in. + PKPenguin321: + - rscadd: The tesla is now much more dangerous, and can cause electronics to explode + violently. + - rscadd: It now hurts to get thrown into another person. + Shadowlight213: + - tweak: The radiation storm random event will automatically enable and disable + emergency maint. + - rscadd: The radiation storm random event is now a weather type that affects the + station. + - bugfix: The security temperature gun now has a firing pin making it 0.0000001% + more useful! + - rscadd: Added config option to use byond account creation age for job limits. + WJohnston: + - imageadd: Lavaland lava probably sorta looks better I guess. + Yackemflam: + - rscadd: Sniper kit have been given as a syndicate bundle set. Be warned though, + they are not as equipped as the nuclear agent kits. + kilkun: + - rscadd: Adds a shielded deathsquad hardsuit. it has four charges and recharges + after 15 seconds of not being shot (compared to the syndicate 3 charges and + 20 second recharge rate) + - tweak: All death commandos now spawn with this new hardsuit. The previous hardsuit + was not removed. + pubby: + - rscadd: Mining scanner module to standard borgs + - rscdel: Sheet snatcher module from standard borgs + xxalpha: + - rscadd: Cigarette packs, donut boxes, egg boxes can now be closed and opened with + Ctrl+Click. + - rscadd: Lighters are now represented in cigarette packs with a sprite of their + own. + - rscadd: You can now remove a lighter from a cigarette pack quickly with Alt+Click. + - bugfix: Reduced the amount of cigars that cigar cases can hold to 5 because the + cigar case sprite doesn't support more than that. +2016-08-29: + Cruix: + - rscadd: Space floppy-disk technology has advanced to the point that multiple technologies + or designs can be stored on a single disk. + Joan: + - rscadd: Lava bubbling up from basalt turfs now glows if in sufficient concentration. + - rscadd: Necropolis tendrils now glow. + - rscadd: Lava rivers now have riverbanks, and should overall look much nicer. + Shadowlight213: + - bugfix: The revenant ectoplasm sprite is no longer invisible. + Xhuis: + - rscadd: Highlander has been revamped. Now you can butcher your coworkers in cold + blood like never before! +2016-08-30: + oranges: + - tweak: The ed209 can now only fire as fast as the portaturrets +2016-08-31: + Iamgoofball: + - rscadd: Adds a new experimental gas to the game. Check it out! + Joan: + - rscadd: Vanguard now has a tooltip showing the amount of stuns you've absorbed + and will be affected by. + MMMiracles: + - bugfix: Xenomorphs can now actually damage barricades. + Shadowlight213: + - bugfix: Fixed runtime preventing access locked programs from being downloaded + XDTM: + - rscadd: Metal slimes now spawn a few sheets of glass when injected with water. + xxalpha: + - tweak: Opening and closing of donut boxes, etc. is now done with clicking the + object with itself. + yackemflam: + - rscadd: The standard rounds now blow off limbs. Happy hunting! diff --git a/html/changelogs/archive/2016-09.yml b/html/changelogs/archive/2016-09.yml new file mode 100644 index 0000000000..3c1124d666 --- /dev/null +++ b/html/changelogs/archive/2016-09.yml @@ -0,0 +1,381 @@ +2016-09-01: + Cruix: + - bugfix: fortune cookies will now drop their fortunes when they are eaten. + Iamgoofball: + - tweak: NULL Crate in cargo was added again because people are fucking idiots so + if we're going to have this stupid fucking crate might as well make it not fucking + garbo + Kor: + - rscadd: Watertanks will now explode when shot. + Lzimann: + - tweak: You can now open all access doors while restrained. + Shadowlight213: + - tweak: Rad storms are more obvious + - bugfix: Pizza bombs will now delete after exploding. + phil235: + - tweak: Putting packagewrap or hand labeler in a backpack is now done by clicking + and dragging. + - bugfix: You can now wrap backpacks and other storage items with packagewrap. +2016-09-02: + A-t48: + - bugfix: Fixed cyborgs being able to use Power Warning emote when broken. + Iamgoofball: + - experiment: Freon has been reworked completely. + - rscadd: Water Vapor has been added to the Janitor's Closet. + RemieRichards: + - bugfix: Cutting bedsheets with a sharp object/wirecutters no longer puts the resulting + cloth INSIDE OF YOU if you're holding it, what a bug. + bgobandit: + - tweak: You can hide small items in urinals now. Use a screwdriver to screw open + the drain enclosure. + - rscadd: Every space urinal comes complete with space urinal cake. Do not eat. +2016-09-04: + A-t48: + - bugfix: Radiation storms no longer spam "Your armor softened the blow." + - bugfix: Radiation always gives a message that you are being irradiated, regardless + of armor level (only an issue if you stripped off all clothing) + - bugfix: Radiation now displays a message appropriate for all mob types (no longer + references clothes). + Gun Hog: + - rscadd: Ghosts may now read an AI or Cyborg's laws by examining them. + Joan: + - rscadd: The talisman of construction now has 25 uses, each of which can convert + a sheet of plasteel to a sheet of runed metal. It can still convert metal into + construct shells, and requires no specific amount of uses to do so. + - rscadd: Added the 'Drain Life' rune to the runes cultists can make. It will drain + life from all creatures on the rune, healing the invoker. + - imageadd: The 'Astral Communion' rune has a new sprite, made by WJohnston. + - rscdel: You can no longer use telekinesis to hit people with items they're holding, + items inside items they're holding, items embedded in them, items actually implanted + in them, or items they're wearing. + MMMiracles: + - rscadd: A set of combat gear for bears has been added, see your local russian + for more information. + XDTM: + - tweak: Nanotrasen has now stocked the DNA Manipulators with potassium iodide instead + of epinephrine as rejuvenators. +2016-09-07: + A-t48: + - bugfix: you can now scrub freon and water vapor + - bugfix: you can now label canisters as freon and water vapor + AnturK: + - rscadd: Watch out for special instructions from Centcom in the intercept report. + Cheridan: + - tweak: Brain damage no longer causes machines to be inoperable. + Ergovisavi: + - bugfix: Stops ash drakes from swooping across zlevels + Impisi: + - tweak: Increased chances of Modular Receiver drop in Maintenance + Incoming5643: + - rscdel: Wizards can no longer purchase the Cursed Heart from their spellbook. + Joan: + - experiment: The lava staff now has a short delay before creating lava, with a + visible indicator. + - tweak: The lava staff's cooldown is now somewhat shorter, and turning lava back + into basalt has a much shorter cooldown and no delay. + Lzimann: + - tweak: Stunprods no longer fit in your backpack, they go on your back now. + MrStonedOne: + - bugfix: Fixed lava sometimes doing massive amounts of damage. + - tweak: AFK players will no longer default to continue playing during restart votes. + XDTM: + - bugfix: Cloners now preserve your genetic mutations. + pubby: + - tweak: Changed military belt TC cost from 3 -> 1 + - tweak: Update ingredient boxes to have more useful ingredients +2016-09-08: + Jordie0608: + - rscadd: Notes can now be tagged as secret to be hidden from player viewed notes. + Lzimann: + - tweak: Legion implants now have a full heal when implanted instead of passive + heal + spawn tentacles. The healing also goes off when you enter crit. + Yackemflam: + - rscadd: You can now buy a box for a chance to mess with the stations meta for + ops. +2016-09-09: + Ergovisavi: + - rscadd: Adds new loot for the colossus, the "Anomalous Crystal" + - tweak: Enabled colossus spawning again + Joan, Ausops: + - rscadd: Added some very fancy tables, constructed by adding carpet tiles to a + standard table frame. + MrStonedOne: + - experiment: Blessed our beloved code with dark magic. + Shadowlight213: + - tweak: Radiation storm direct tox loss removed + - tweak: Radiation storms now cause a radiation alert to appear for the duration +2016-09-12: + Joan: + - rscadd: Cult structures can once again be constructed with runed metal. + - experiment: Cult structures can now take damage and be destroyed. Artificers can + repair them if they're damaged. + - tweak: The Recollection function of the clockwork slab is much more useful and + easier to parse. + - wip: Tweaked the Recital menus for scripture so the scripture are all in the proper + order. This might fuck you up if you were used to the incorrect order, but you'll + get used to it. + Nanotrasen Anti-Cheese Committee: + - bugfix: A glitch in the hydroponics tray firmware allowed it to retain plant growth + even after the plant was removed, resulting in the next planted seed being grown + instantaneously. This is no longer possible. + PKPenguin321: + - bugfix: Tesla shocks from grilles will no longer do thousands and thousands of + damage. They now properly deal burn damage that is equal to the current power + in the powernet divided by 5000. + Papa Bones: + - tweak: You can now rename the captain's sabre by using a pen on it. + RemieRichards: + - rscadd: Added the functionality for mobs to have multiple hands, this might have + broken some things, so please report any weirdness + Shadowlight213: + - rscdel: The surplus crate and random item will now only contain items allowed + by the gamemode + - rscdel: removes sleeping carp scroll from surplus crates + - experiment: Minimaps will now try to load from a cache or backup file if minimap + generation is disabled. + TheCarlSaganExpress: + - rscadd: Crayons, lipstick, cigarettes, and penlights can now be inserted into + PDAs. + phil235: + - rscadd: Monkeys can be dismembered. + - rscadd: Humans, monkeys and aliens can drop limbs when they are gibbed. + - rscadd: Roboticists can remove flashes, wires and power cells that they inserted + in robot head or torso by using a crowbar on it. + - rscadd: visual wounds appear on a monkey's bodyparts when injured, exactly like + humans. + - rscadd: Using a health analyzer on a monkey or alien shows the injuries to each + bodypart. + - rscadd: Monkeys can become husks. + - bugfix: Human-monkey transformations now respect missing limbs. No more limb regrowth + by becoming a monkey. + - bugfix: Changeling's regenerate ability also work while in monkey form. + - bugfix: Alien larva has its own gib and dust animation. + - bugfix: A bodypart that looks wounded still looks bloody when dismembered. + - bugfix: Amputation surgery now works on robotic limbs, and monkeys. +2016-09-14: + Ergovisavi: + - bugfix: Fixes lockers, bodybags, etc, giving you ash storm / radiation storm protection + Erwgd: + - rscadd: Upgraded sleepers can now inject inacusiate to treat ear damage. + Joan: + - rscadd: Added brass, producible by proselytizing rods, metal, or plasteel, or + by using Replicant Alloy in-hand, and usable to construct a variety of cult-y + brass objects. + - tweak: Objects constructable with brass include; wall gears, pinion airlocks, + brass windoors, brass windows, brass table frames and tables, and brass floor + tiles. + - rscadd: Cogscarabs can convert brass sheets into liquified alloy with their proselytizer. + - tweak: You can use brass sheets on wall gears to produce clockwork walls, or, + if the gear is unanchored, false clockwork walls. + - bugfix: Fixed a bug preventing you from converting grilles into ratvar grilles. + - experiment: Please note that conservation of mass exists. + Sligneris: + - tweak: Captain's space armor has been readapted with modern hardsuit technology. + oranges: + - tweak: Examine code for dismembered humans now has better easter eggs +2016-09-17: + BoxcarRacer41: + - rscadd: Added a new food, bacon. Bacon is made by processing raw meat cutlets. + - rscadd: Added a new burger recipe, the Bacon Burger. It is made with one bun, + one cheese wedge and three pieces of cooked bacon. + Ergovisavi: + - rscadd: Added a nightvision toggle to Shadowpeople + - tweak: Made several anomalous crystal variants more easily identified/easier to + see the effects thereof, and removed the "magic" activation possibility (replaced + with the "bomb" flag) + Gun Hog: + - tweak: Nanotrasen Robotics Division is proud to announce slightly less clunky + leg servo designs relating to the "Ripley" APLU and "Firefighter" exosuits. + Tests show increased mobility in both high and low pressure environments. The + previous designer has been fired for incompetence. + Improves tablets design: + - imageadd: Brings the tablet icons into the holy light of having depth + Joan: + - rscadd: Megafauna will now use ranged attacks even if they don't have direct vision + on their target. + - rscadd: Volt Void and Interdiction Lenses will now drain mech cells of energy. + - tweak: Ocular Wardens do slightly more damage to mechs. + - experiment: Replicant, Soul Vessel, Cogscarab, and Anima Fragment now take an + additional second to recite. + - tweak: Anima Fragments do slightly less damage in melee. + - tweak: Mending Motors and Clockwork Obelisks have slightly less health. + - tweak: Invoking Nezbere now requires 3 invokers. + - rscdel: Clockwork armor no longer has 5% energy resistance. + - bugfix: You can no longer construct clockwork structures on space turfs. + Papa Bones: + - tweak: BZ gas is no longer available on Box and Metastation layouts. + phil235: + - tweak: You no longer have to click a megaphone to use it, you simply keep it in + your active hand and talk normally. + - rscadd: Added new things + - imageadd: added some icons and images +2016-09-20: + Ergovisavi: + - bugfix: fixed "friendly" xenobio mobs and mining drones attacking station drones + Joan: + - rscadd: Miners can now buy KA AoE damage mods from the mining vendor for 2000 + points per mod. + - rscadd: 'Combined the Convert and Sacrifice runes into one rune. It''ll convert + targets that are alive and eligible, and attempt to sacrifice them otherwise. + The only changes to mechanics are that: Converting someone will heal them of + all brute and burn damage they had, and sacrificing anything will always produce + a soulstone(but will still only sometimes fill it)' + - tweak: You can no longer teleport to Teleport runes that have dense objects on + top of them. + - experiment: Wall runes will now activate other nearby wall runes when activated, + but will automatically disable after a minute and a half of continuous activity + and become unusable for 5 seconds. + - experiment: The Blood Boil rune no longer does all of its damage instantly or + stuns, but if you remain in range for the full duration you will be sent deep + into critical. + - experiment: Bubblegum has been seen reaching through blood. Try not to get hit. + - experiment: The Raise Dead rune no longer requires a noncultist corpse to revive + a cultist; instead, it will draw from the pool of all people sacrificed to power + the rune. + Mekhi: + - rscadd: Nanotrasen has been experimenting on cybernetics for a while, and rumors + are they have a few combat prototypes available... + - experiment: 'New arm implants: Energy-blade projector, implanted medical beamgun, + stun-arm implant (Like the borg version), flash implant that is automatically-regenerating + and doubles as a powerful flashlight. There is also one with all four items + in one. Also, a surgery toolkit implant. Adminspawn only for the moment.' + MrStonedOne: + - bugfix: Fixed space/nograv movement not triggering when atoms moved twice quickly + in space/nograv + Nanotrasen Stress Relief Board: + - rscadd: Latecomers to highlander can now join in on the fun. + - rscadd: The crew are encouraged to less pacifistic during highlander. Failing + to shed blood will result in your soul being devoured. Have a nice day. + Nicho1010: + - bugfix: Fixed lattices appearing after exploding lava + Screemonster: + - tweak: Abandoned crates no longer accept impossible guesses. + - tweak: Lets players know that all the digits in the code must be unique. + - tweak: Reads the last guess back on the multitool along with the correct/incorrect + guess readout. + - bugfix: multitool output on crates no longer returns nonsense values. + XDTM: + - rscadd: Positive viruses are now recognized by medical HUDs with a special icon. + - tweak: fully_heal no longer removes nonharmful viruses. This affects legion souls, + staffs of healing, and changeling's revive. + - rscadd: Canisters of any type of gas are now orderable in cargo. Dangerous experimental + gases will require Research Director approval. + Yackemflam: + - rscadd: The syndicate has learned on how to give their agents a true syndicate + ninja experience. + chickenboy10: + - rscadd: Added a Experimental Limb Grower to the medbay department, now medical + stuff can grow synthetic limbs using Synthflesh to help crew that suffer any + work related accidents. There may also be a limb that can be grown with a special + card... + feemjmeem: + - tweak: You can now disassemble meatspike frames with a welding tool. + phil235: + - experiment: 'adds a talk button next to the crafting button. Clicking it makes + a "wheel" appear around you with short predetermined messages that you click + to say them. This lets you say common responses without having to type in the + chat bar. Current messages available are: "Hi", "Bye", "Thanks", "Come", "Help", + "Stop", "Get out", "Yes", and "No". The talk button can be activated with the + hotkey "H" or "CTRL+H"' + - rscadd: Wearing colored glasses colors your vision. This option can be enabled/disabled + by alt-clicking any glasses with such feature. +2016-09-21: + Cyberboss: + - bugfix: The food processor's sprite's maintenance panel is no longer open while + closed and vice/versa + - tweak: Tesla arcs no longer lose power when passing through a coil that isn't + connected to a grid + MrStonedOne: + - bugfix: Fixes minimap generation crashes by making parts of it less precise +2016-09-23: + Cyberboss: + - rscadd: Wire layouts of NanoTransen devices for the round can now be found in + the Station Blueprints + Incoming5643 + WJohnston: + - imageadd: Lizard sprites have received an overhaul, sprites courtesy of WJohnston! + - rscdel: While there are some new bits, a few old bits have gone by the wayside, + if your lizard has been affected by this the specific feature will be randomized + until you pick a new setting. + - rscadd: Lizards can now choose to have digitigrade legs (those weird backwards + bending ones). Keep in mind that they can only be properly seen in rather short + pants. They also preclude the use of shoes. By default no lizard will have these + legs, you have to opt in. + - rscadd: All ash walker lizards however are forced to have these legs. + - experiment: There is absolutely no tactical benefits to using digitigrade legs, + you are only crippling yourself if you use them. + Papa Bones: + - tweak: You can now quick-draw the officer's sabre from its sheath by alt-clicking + it. + XDTM: + - bugfix: Holy Water no longer leaves you stuttering for years. +2016-09-24: + Cheridan: + - tweak: Nerfed Critical Hits + MrStonedOne: + - tweak: Orbits now use a subsystem. + - tweak: Orbits now bind to object's moving to allow for quicker updates, subsystem + fallback for when that doesn't work (for things inside of things or things that + move without announcing it) + XDTM: + - rscdel: Viruses start with 0 in every stat instead of 1. + - bugfix: Atomic Bomb, Pan-Galactic Gargle Blaster, Neurotoxin and Hippie's Delight + are now proper alcoholic drinks, and as such can disinfect, ignite, and be purged + by antihol. + optional name here: + - tweak: Changes cursed heart description to something slightly more clear. + - bugfix: Fixes a capitalization issue +2016-09-26: + Cuboos: + - rscadd: Added E-cigarettes as contraband to cigarettes vending machines. They + take reagents instead of dried plants and also hold more than cigarettes or + pipes. You can modify them to puff out clouds of reagents or emag them to fill + a whole room with reagent vapor. + - rscadd: Added a new shirt to the clothing vendor relating to the newly added vapes. + Joan: + - tweak: Blobs will generally require fewer blobs to win during the blob mode, which + should hopefully make the mode end faster at lower overmind amounts. + Razharas: + - rscadd: '"Kudzu now keeps the mutations it had before and thus can be properly + cultivated to be whatever you want"' + TheCarlSaganExpress: + - rscadd: You may now insert crayons, lipstick, penlights, or cigarettes in your + PDA. + - bugfix: Removing cartridges from the PDA will no longer cause them to automatically + fall to the floor. + oranges: + - rscadd: It looks like a pizza delivery from an un-named station got misplaced +2016-09-27: + Cobby: + - tweak: Nanotrasen has buffed the electronic safety devices found in Secure Briefcases + and Wallsafes, making them... well... more secure. In Particular, we added more + wires that do absolutely nothing but hinder the use of the multitool, along + with removing the ID slot only used by syndicates to emag the safe. + Incoming5643: + - rscadd: The secret satchels system has been updated to hide more smuggler's satchels + hidden randomly under the station + - experiment: In case you forgot about the secret satchel system, basically if you + take a smuggler's satchel (a traitor item also occasionally found under a random + tile in the station [USE T-RAYS]), stow away an item in it, and bury it under + the floor tiles that item can reappear in a random later round! + MrStonedOne: + - tweak: Custom Round end sounds selected by admins will be preloaded to all clients + before actually rebooting the world + Shadowlight213: + - bugfix: Fixes broken icon states when replacing warning floor tile + Supermichael777: + - tweak: Cat men have finally achieved equal discrimination. + TrustyGun+Pubby: + - imageadd: Lawyers now have unique speech bubbles. + XDTM: + - tweak: Using plasma on dark blue slimes will now spawn freon instead of arbitrarily + freezing mobs. + uraniummeltdown: + - tweak: Protolathe stock parts now build 5 times faster +2016-09-28: + Cuboos: + - bugfix: Removed the admin message spam from the smoke_spread proc. You may now + vape in peace without the threat of a Blue Space Artillery + LanCartwright: + - rscdel: Removed Stimulants and Coffee from survival pens. + - tweak: Nanites have been replaced with Mining Nanites which heal more when you + are lower health, and do not have the ridiculous healing Adminorazine had. diff --git a/html/changelogs/archive/2016-10.yml b/html/changelogs/archive/2016-10.yml new file mode 100644 index 0000000000..4662fcff3f --- /dev/null +++ b/html/changelogs/archive/2016-10.yml @@ -0,0 +1,429 @@ +2016-10-01: + Incoming5643: + - rscadd: After years of having to live on a mostly blown up hunk of junk the wizard's + ship has finally been repaired + - rscdel: No one paid attention to that lore anyway +2016-10-07: + WJohnston: + - imageadd: Improved/resprited AI card, pAI, easel/canvases, shotgun shells, RCD + cartridge, speedloaders, and certain older buttons. + - imageadd: Improved/resprited a few bar signs, basketball/dodgeball/hoop, blood + bags, and body bags. + - imageadd: Improved/resprited Paper, stamps, folders, small fires, pens, energy + daggers, cabinets, newspaper and other bureaucracy related items. +2016-10-10: + ChemicalRascal: + - bugfix: Previously, improving the incinerator's efficiency made the RPM decay + more quickly, instead of less quickly. No more! + Cyberboss: + - rscadd: More reagent containers can be used for filling your dirty vapor cancer + sticks + - spellcheck: Fixed some vape spelling/grammar + MrStonedOne: + - tweak: Player Preferences window made slightly faster. + Nanotrasen Stress Relief Board: + - rscdel: Claymores created through Highlander no longer thirst for blood or announce + their wielder's location incessantly. + - bugfix: Claymores should now properly absorb fallen foes' corpses. + - bugfix: Losing a limb now properly destroys your claymore. + Supermichael777: + - bugfix: The wizards federation have instituted a strict 1 demon limit on demon + bottles. + XDTM: + - rscadd: Using blood on an Oil Slime will create Corn Oil. + - rscadd: Using blood on Pyrite Slimes will create a random crayon. + - rscadd: Using water on Orange Slimes will create a small smoke cloud. + - rscadd: Using water on Blue Slimes will spawn foam. + - rscadd: You can now retrieve materials inserted in a Drone Shell Dispenser with + a crowbar. + phil235: + - rscadd: A whole bunch of structures and machines can now be broken and destroyed + using conventional attack methods. + - rscadd: The effect of fire on objects is overhauled. When on fire, your external + clothes now take fire damage and can become ashes, unless fire proof. All objects + caught in a fire can now take fire damage, instead of just flammable ones, unless + fire proof. + - rscadd: Acid effect is overhauled. Splashing acid on something puts a green effect + on it and start slowly melting it. Throwing acid on mobs puts acid on their + clothes. Acid can destroy structures and items alike, as long as they're not + acid proof. The more acid put on an object, the faster it melts. Walking on + an acid puddle puts acid on your shoes or burns your bare feet. Picking up an + item with acid without adequate glove protection burns your hand. Acid can be + washed away with any sort of water source (extinguisher, shower, water glass,etc...). + - rscadd: When a mob receives melee attacks, its clothes also get damaged. Clothes + with enough damage get a visual effect. Damaged clothes can be repaired with + cloth (produced with botany's biogenerator). Clothes that receives too much + melee damage become shreds. + - tweak: Clicking a structure/machine with an item on help intent can never result + in an attack. + - tweak: Hostile animals that are environment destroyers no longer destroys tables&closets + in one hit. It now takes several hits depending on the animal. +2016-10-11: + Cyberboss: + - rscadd: The waste line now has a digital valve leading to space (off by default) + along with a port on it's far side + Incoming5643: + - rscadd: Wizards may finally use jaunt and blink on the escape shuttle. Maybe elsewhere + too? + - bugfix: The previously broken radios in the wizards den should work now. You still + have to turn them on though. + Kor: + - rscadd: Added frogs, with sprites by WJ and sounds by Cuboos. + Papa Bones: + - rscadd: Flora now spawns in lavaland tunnels, they can be harvested with a knife. + - rscadd: Flora have a range of effects, be careful what you eat! + - bugfix: You harvest flora on lavaland with your hands, not a knife. My bad. + Shadowlight213: + - rscadd: Cargo can order the antimatter engine +2016-10-12: + Cyberboss: + - bugfix: Fixed motion alarms instantly triggering and de/un/re/triggering + - bugfix: Airlock speed mode now works + Joan: + - rscadd: You can now deconstruct AI cores that contain no actual AI. + WJohnston: + - imageadd: Recolored and resprited candles and ID cards. Folders should have improved + color contrast. + XDTM: + - rscadd: Exhausted slime extracts will now dissolve instead of leaving useless + used slime extracts. + - tweak: Airlocks are now immune to any damage below 20, to prevent pickaxe prison + breaks. + - tweak: High-Security Airlocks, such as the vault or the AI core's airlocks, are + now immune to any damage below 30. +2016-10-13: + Razharas: + - tweak: Makes clicking something in heat of battle a bit easier by making drag&drops + that dont have any effect be counted as clicks + XDTM: + - rscadd: 'Added four new symptoms: Regeneration and Tissue Regrowth heal respectively + brute and burn damage slowly; Flesh Mending and Heat Resistance are the level + 8 version of those symptoms, and heal faster.' + - rscdel: The Toxic Compensation, Toxic Metabolism and Stimulants symptoms have + been removed. + - rscdel: Viruses no longer stack. Viruses can be overridden if the infecting virus + has higher transmittability than the previous virus' resistance. + - tweak: Viruses can now have 8 symptoms, up from 6. + - rscadd: You can now store monkey cubes in bio bags; using bio bags on the consoles + will load them with the monkey cubes inside the bags. + ma44: + - rscadd: Cargo can now order a 2500 supply point crate that requires a QM or above + to unlock. This crates contains a explorer suit, compact pickaxe, mesons, and + a bag to hold ore with. +2016-10-16: + Cuboos: + - rscadd: Added a new unique tool belt to the CE + - rscadd: Added new power tools, a hand drill that can be used as a screw driver + or wrench and jaws of life which can be used as either a crowbar or wire cutters + - rscadd: Power tools can also be made from the protolathe with engineering and + electromagnet 6 + - tweak: slightly revamped how construction/deconstruction handle sound + - soundadd: added new sounds for the power tools + - soundadd: added a new sound for activating and deactivating welding tools, just + because. + Cyberboss: + - bugfix: Plasma fires no longer cause cameras to break. + Joan: + - tweak: Blazing Oil blobs are now outright immune to fire. This does not affect + damage taken from other sources that happen to do burn damage. + - tweak: Normal blob spores now take two welder hits to die, from three. + - tweak: Cyborgs now die much less rapidly to blob attacks. + Lzimann: + - tweak: 'Changed two admin hotkeys: f7 is now stealth-mode and f8 to toggle-build-mode-self.' + Shadowlight213: + - bugfix: Modular consoles have been fixed. + Supermichael777: + - tweak: Changeling Sting is now one part screwdriver cocktail and 2 parts lemon-lime + soda. + - bugfix: Triple citrus now actually displays its sprite. + Yackemflam: + - tweak: extinguishers now spray faster + coiax: + - rscadd: RCDs have a Toggle Window Type verb allowing the rapid construction of + reinforced windows, rather than regular windows. + - rscadd: RCDs can now finish and deconstruct wall girders. + phil235: + - tweak: Clicking a floor with a bodybag or roller bed now deploys them directly + (and the bodybag starts open) + scoopscoop: + - bugfix: The cult shifter will now properly spawn as part of the veil walker set. +2016-10-18: + Basilman: + - rscadd: A third martial art, CQC, has been added and is now available to nuke + ops instead of sleeping carp + Kor: + - rscadd: Added sloths to cargobay on Box and Meta + MrPerson: + - rscadd: New toxin - Rotatium. It doesn't quite do what it does on other servers. + Instead it rocks your game view back and forth while slowly doing toxin damage. + The rocking gets more intense with time. + - rscadd: To make it, mix equal parts mindbreaker, neurotoxin, and teslium. + MrStonedOne: + - experiment: Byond 511 beta users may now choose their own FPS. This will apply + to animations and other client side only effects. Find it in your game preferences. + Shadowlight213: + - bugfix: fixed removing modular computer components + TheCarlSaganExpress: + - tweak: Provided you have access, you may now use your ID to unlock the display + case. + - tweak: The fire axe cabinet and display case may now be repaired with the welder. + XDTM: + - rscadd: You can now grind slime extracts in a reagent grinder. If the slime was + unused it will result in slime jelly, while if used it will only output the + reagents inside the extract. + Yackemflam: + - bugfix: fixed the standard vest being weaker than the slim variant + lordpidey: + - rscadd: There is a new potential obligation for devils to have. Musical duels. Ask + your nearest devil for a musical duel, there's a 14% chance he's obligated to + do it. + - rscdel: Removed the old offering a drink obligation for devils, it overlapped + too much with the food obligation. + - tweak: Trying to clone people who've sold their soul now results in FUN. + - tweak: Devils can no longer spam ghosts with revival contracts. + phil235: + - rscadd: Visual effects appear on the target of an attack, similar to the item + attack effect. + - rscdel: You now only see a message in chat when witnessing someone else getting + attacked or hit by a bullet if you are close enough to the action. +2016-10-19: + Cyberboss: + - bugfix: Physically speaking is no longer delayed by your radio's lag + - bugfix: You can now attack doors with fireaxes and crowbars when using the harm + intent + - tweak: The BSA is no longer ready to fire when constructed + - bugfix: The BSA can no longer be reloaded faster by rebuilding the console + MrStonedOne: + - tweak: tweaked the settings of the space drift subsystem to be less effected by + anti-lag slowdowns + Pubby: + - rscadd: 'A new map: PubbyStation. Set it to your favorite in map preferences!' + XDTM: + - rscadd: PanD.E.M.I.C. now displays the statistics of the viruses inside. + phil235: + - tweak: Made the singularity gen and tesla gen immune to fire. + - tweak: All unique traitor steal objective item are now immune to all damage except + severity=1 explosion. + - tweak: Mobs on fire no longer get damage to their worn backpacks, belts, id, pocket + stuff, and suit storage. + - bugfix: Mob receiving melee attacks now only have its outer layer of clothes damaged, + e.g. no damage to jumpsuit when wearing a suit. + - bugfix: now all hardsuit have 50% more health, as intended. + wrist: + - rscadd: Toxins is different now. +2016-10-21: + Adam E.: + - tweak: Added cargo and engi access to auxillary mine base launching console. + Cyberboss: + - tweak: Your brain is now gibbed upon chestburst + - bugfix: The safe is indestructible again + Joan: + - rscadd: Wraith Spectacles will now slowly repair the eye damage they did to you + as long as you aren't wearing them. + - experiment: You can now see how much eye damage the spectacles have done to you + overall, as well as how close you are to being nearsighted/blinded. + - tweak: Mending Motors heal for more. + - wip: Mania Motors are overall more powerful; they have greater effect, but require + more power to run and less power to convert adjacent targets. + - experiment: Interdiction Lenses no longer require power to disrupt electronics + and will no longer disrupt the radios of servants. + - bugfix: You need to be holding teleport talismans and wizard teleport scrolls + in your hands when you finish the input, and cannot simply open the input and + finish it whenever you get stunned. + - tweak: The range for seeing visible messages in combat is a tile higher. + Screemonster: + - tweak: The anti-tamper mechanism on abandoned crates now resists tampering. + - tweak: Secure, non-abandoned crates can be given a %chance of exploding when tampered + with. Defaults to 0. + Shadowlight213: + - bugfix: The Swap minds wizard event will now function + Swindly: + - rscadd: The action button for a dental implant now includes the name of the pill + - bugfix: The pill activation button now properly displays the pill's icon + uraniummeltdown: + - rscadd: Adds more replacements to the Swedish gene +2016-10-22: + Shadowlight213: + - experiment: Breathing has been moved from species to the lung organ + - rscadd: Lung transplants are now possible! +2016-10-23: + Cyberboss: + - bugfix: Fixed a bug that caused door buttons to open doors one after another rather + than simultaneously like they are suppose to + - bugfix: NOHUNGER species no longer hunger + - bugfix: Appropriate gloves now protect you from getting burned by cheap cigarette + lighters + - rscdel: Labcoats no longer have pockets + Yackemflam: + - tweak: Riot helmets are now more useful in melee situations and the standard helmet + is now slightly weaker + uraniummeltdown: + - rscadd: Atmos grenades are now in the game and uplink +2016-10-24: + Batman: + - tweak: The sniper rifle descriptions are less edgy. + Cobby: + - rscadd: Finally, a way to relate to Bees! + Cyberboss: + - bugfix: Morphs no longer gain the transparency of chameleons + - bugfix: Turrets can no longer shoot when unwrenched + - bugfix: Spray bottle can now be used in the chem dispenser + Joan: + - rscadd: Clockwork marauders now have a HUD, showing block chance, counter chance, + health, fatigue, and host health(if applicable), as well as including a button + to try to emerge/recall. + - experiment: Clockwork marauders can now block bullets and thrown items, even if + Ratvar has not risen. + - rscadd: The Judicial Visor no longer requires an open hand to use. Instead, clicking + the button will give you a target selector to place the Judicial Marker. + - experiment: Tinkerer's Daemons are now a structure instead of a Cache addon. + - wip: Tinkerer's Daemons now consume a small amount of power when producing a component, + but produce components every 12 seconds with no additional delay. + - tweak: Adjusted the costs of the Tinkerer's Daemon and Interdiction Lens. + - imageadd: Floaty component images appear when Tinkerer's Caches and Daemons produce + components. + MrStonedOne: + - bugfix: Spectral sword now tracks orbiting ghosts correctly. + Shadowlight213: + - imageadd: Damaged airlocks now have a sparking effect + Swindly: + - rscadd: Added a button to the ChemMaster that dispenses the entire buffer to bottles. + ma44: + - rscadd: Reminds the user that reading or writing a book is stupid. +2016-10-27: + Chowder McArthor: + - rscadd: Added a neck slot. + - tweak: Modified some of the attachment items (ties, scarves, etc) to be neck slot + items instead. + Cyberboss: + - rscadd: NEW HOTKEYS + - rscadd: The number pad can be used to select the body part you want to target + (Cycle through head -> eyes -> mouth with 8) in hotkey mode. Be sure Numlock + is on! + - rscadd: Holding shift can be used as a modifier to your current run state in both + hotkey and normal mode. + - bugfix: Emag can no longer be spammed on shuttle console + Gun Hog: + - bugfix: Fixed AIs uploaded to mechs having their camera view stuck to their card. + Joan: + - rscadd: Clockwork Floors now have a glow when healing servants of toxin damage. + Only other servants can see it, so don't get any funny ideas. + - bugfix: The Interdiction Lens now properly has a high Belligerent Eye cost instead + of a high Replicant Alloy cost. + Pubby: + - tweak: PubbyStation's bar is now themed like a spooky castle! + Swindly: + - bugfix: Chem implants can now be properly filled and implanted + WJohnston: + - rscadd: Adds an unlocked miner equipment locker on Boxstation and Metastation's + Aux Base Construction area, as well as a telescreen to the camera inside. All + mining outpost computers can also see through that camera. + lordpidey: + - rscadd: The wizard federation has teamed up with various LARP groups to invent + a new type of spell. +2016-10-28: + Erwgd: + - rscadd: You can now use cloth to make black or fingerless gloves. + - tweak: Biogenerators require less biomass to produce botanist's leather gloves. + Tacolizard: + - rscadd: Added a new contraband crate to cargo, the ATV crate. +2016-10-29: + Chowder McArthor: + - bugfix: Added in icons for the neck slot for the other huds. + Cobby: + - rscadd: Adds several Halloween-Themed Emojis. See if you can get them all! [no + code diving cheaters!] + Erwgd: + - rscadd: The NanoMed Plus now stocks premium items. + Joan: + - experiment: Guvax is now targeted; invoking it charges your slab to bind and start + converting the next target attacked in melee within 10 seconds. This makes your + slab visible in-hand. + - tweak: Above 5 Servants, the invocation to charge your slab is not whispered, + and the conversion time is increased for each Servant above 5. + - wip: Using Guvax on an already bound target will stun them. The bound target can + resist out, which will prevent conversion. + - experiment: Sentinel's Compromise is now targeted, like Guvax, but can select + any target in vision range. + - rscadd: Sentinel's Compromise now also removes holy water from the target Servant. + - wip: Clicking your slab will cancel these scriptures. + - imageadd: Both of these will change your cursor, to make it obvious they're active + and you can't do anything else. + - rscadd: Arks of the Clockwork Justicar that do not summon Ratvar will still quick-call + the shuttle. + - bugfix: Clockwork structures that return power can now return power to the APC + of the area they're in if there happens to be one. + - bugfix: Clockwork structures that use power from an APC will cause that APC to + start charging and update the tgUI of anyone looking at the APC. + - bugfix: Converting metal, rods, or plasteel to brass with a clockwork proselytizer + while holding it will no longer leave a remainder inside of you. + - tweak: Plasteel to brass is now a 2:1 ratio, from a 2.5:1 ratio. Accordingly, + you now only need 2 sheets of plasteel to convert it to brass instead of 10 + sheets. + - tweak: Wall gears are now converted to brass sheets instead of directly to alloy. + - rscdel: You can no longer do other proselytizer actions while refueling from a + cache. + - bugfix: Fixed a bug where certain stacks wouldn't merge with other stacks, even + when they should have been. + - bugfix: Clockwork structures constructed from brass sheets now all have appropriate + construction value to replicant alloy ratios. + - bugfix: Tinkerer's Caches no longer need to see a clockwork wall to link to it + and generate components. + MrStonedOne: + - experiment: Shoes do not go on heads. + NikNak: + - rscadd: Action figures are finally winnable at arcade machines. Comes in boxes + of 4. + Pubby: + - rscadd: The holodeck has been upgraded with new programs. Try them out! + Shadowlight213: + - rscdel: The HOS and other heads of staff no longer have a chance to be revheads + TehZombehz: + - tweak: Custom food items can now fit inside of smaller containers, such as paper + sacks. + - rscadd: Small cartons can be crafted using 1 piece of cardboard. Don't be late + for school. + - rscadd: Apples can now be juiced for apple juice. Chocolate milk can now be crafted + using milk and cocoa. + - tweak: Chocolate bar recipe has been modified to compensate for chocolate milk. + The soy milk version of the chocolate bar recipe remains unchanged. + - bugfix: Grapes can now be properly juiced for grape juice using a grinder. + XDTM: + - tweak: Wizards no longer need sandals to cast robed spells. + Xhuis: + - rscadd: Syndicate and malfunctioning AIs may now be transferred onto an intelliCard + if their parent core has been destroyed. This may only be done with the AI's + consent, and the AI may not be re-transferred onto another APC or the APC it + came from. + - rscadd: New additions have been made for this Halloween and all future ones. Happy + Halloween! + ma44: + - rscadd: You can now solidify liquid gold into sheets of gold with frostoil and + a very little amount of iron +2016-10-30: + Joan: + - rscadd: The Recollection option in the Clockwork Slab has been significantly improved, + with a better information to fluff ratio, and the ability to toggle which tiers + of scripture that are visible in Recollection. + Lzimann: + - bugfix: You can once again order books by its ID in the library. + Mysak0CZ: + - bugfix: You no longer need to deconstruct emagged (or AI-hacked) APC to fix them, + replacing board is sufficient + - bugfix: You can no longer unlock AI-hacked APCs + - bugfix: Removing APC's and SMES's terminal no longer ignore current tool's speed + - rscadd: You can repair APC's cover (only if APC is not compleatly broken) by using + APC frame on it + - rscadd: closing APC's cover will lock it + bgobandit: + - rscadd: The creepy clown epidemic has arrived at Space Station 13. + - rscadd: Honk. +2016-10-31: + Joan: + - experiment: Brass windows will now survive two fireaxe hits, and are slightly + more resistant to bullets. + Lzimann: + - rscdel: Changelings no longer have the Swap Forms ability. + Xhuis: + - rscadd: Disposal units, outlets, etc. are now fireproof. + - rscadd: Changelings can now use biodegrade to escape silk cocoons. diff --git a/html/changelogs/archive/2016-11.yml b/html/changelogs/archive/2016-11.yml new file mode 100644 index 0000000000..c656d00965 --- /dev/null +++ b/html/changelogs/archive/2016-11.yml @@ -0,0 +1,471 @@ +2016-11-02: + Iamgoofball: + - rscadd: Added a new lobby menu sound. + Joan: + - rscdel: Brass windows and windoors no longer drop full sheets of brass when destroyed. + - rscadd: Instead, they'll drop gear bits, which can be proselytized for a small + amount of liquified alloy; 80% of the materials used to construct the window. + - tweak: Mending Motors have an increased range and heal for more. + - experiment: Mending Motors will no longer waste massive amounts of power on slightly + damaged objects; instead, they will heal a small amount, use a small amount + of power, and stop if the object is fully healed. + - wip: Mending Motors can now heal all clockwork objects, including pinion airlocks, + brass windows, and anything else you can think of. + - rscadd: Ocular Wardens will no longer attack targets that are handcuffed, buckled + to something AND lying, or in the process of being converted by Guvax. + - tweak: Also, they do very slightly more damage. + - rscdel: Hulks no longer one-shot most clockwork structures and will no longer + four-shot the Gateway to the Celestial Derelict. + - bugfix: Hulks are no longer a blob counter. + XDTM: + - tweak: Ninjas are now slightly visible when stealthing. + phil235: + - rscadd: Spray cleaner and soap can now wash off paint color. +2016-11-03: + Cobby: + - rscadd: Adds a geisha outfit to the clothesmate on hacking. QT space ninja BF + not included + Joan: + - rscadd: 'Proselytizing a window will automatically proselytize any grilles under + it. This is free, so don''t worry about wasting alloy. rcsadd: Trying to proselytize + something that can''t be proselytized will try to proselytize the turf under + it, instead.' + - experiment: Clockcult's "Convert All Silicons" objective now also requires that + Application scripture is unlocked. + - wip: The "Convert All Silicons" objective will also only be given if there is + an AI, instead of only if there is a silicon. +2016-11-05: + Joan: + - rscadd: Proselytizer conversion now accounts for existing materials, and deconstructing + a wall, a girder, or a window for its materials is no longer more efficient + than just converting it. + - imageadd: Heal glows now appear when mending motors repair clockwork mobs and + objects. + Lzimann: + - rscdel: You can no longer walk holding shift. +2016-11-06: + Joan: + - bugfix: Dragging people over a Vitality Matrix will actually cause the Matrix + to start working on them instead of failing to start draining because it's "active" + from when the dragging person crossed it. + phil235: + - rscadd: You can now climb on transit tube, like tables. + - rscadd: You can now use tabs when writing on paper by writing "[tab]" +2016-11-07: + Basilman: + - rscadd: CQC users can now block attacks by having their throw mode on. + - tweak: The CQC kick and Disorient-disarm combos are now much easier to use, CQC + harm intent attacks are stronger aswell. + - bugfix: Fixed being able to CQC restrain someone, let him go, then 10 minutes + later disarm someone else to instantly chokehold them. + - tweak: CQC costs more TC (13) + Cyberboss: + - bugfix: Tesla zaps that don't come from an energy ball can no longer destroy nukes + and gravity generators + El Tacolizard: + - rscadd: A space monastery and chaplain job have been added to PubbyStation. + - rscadd: Improved pubby's maint detailing + Joan: + - tweak: Ratvarian Spears now do 18 damage and ignore a small amount of armor on + normal attacks, but have a slightly lower chance to knowdown/knockout. Impaling + also ignores a larger amount of armor. + - rscadd: Throwing a Ratvarian Spear at a Servant will not damage them and may cause + them to catch the spear. + - rscadd: Standard drones will be converted to Cogscarabs by Ratvar and the Celestial + Gateway proselytization. + - rscdel: Cogscarabs no longer receive station alerts. + - bugfix: Anima Fragments, Clockwork Marauders, and cult constructs are now properly + immune to heat and electricity. + - tweak: Clockwork armor is much stronger against bullets and bombs but much weaker + against lasers. + - wip: Specific numbers; Bullet armor from 50% to 70%, bomb armor from 35% to 60%, + laser armor from -15% to -25%. This means lasers are a 4-hit crit. + - rscadd: You can now Quickbind scripture other than Guvax and Vanguard to the Clockwork + Slab's action buttons, via Recollection. + - rscadd: You can also recite scripture directly from Recollection, if doing so + suits your taste. Of course it suits your taste, it's way easier than menus. + - tweak: You can also toggle compact scripture in Recollection, so that you don't + see description, invocation time, component cost, or tips. + - tweak: Dropping items into Spatial Gateways no longer consumes a use from the + gateway. + - rscadd: If your Spatial Gateway target is unconscious, you can pick a new target + instead. + Kor: + - rscadd: Multiverse teams now have HUD icons. + - rscadd: Multiverse war is back in the spellbook. + phil235: + - rscadd: Altclicking a PDA without id now removes its pen. + - rscadd: The PDA's sprite now shows whether it has an id, a pAI, a pen, or if its + light is on. +2016-11-09: + Changes: + - tweak: Old mining asteroid is more interesting (mining world can be picked in + ministation.dm) + - tweak: Space around ministation is now half(?) the size of normal space + - rscadd: Loot spawners to maintenance + - bugfix: Rad storms frying maintenance + - bugfix: Bad conveyor belts in mining/cargo area of station + - bugfix: Bombs completely destroying toxins test site + - rscadd: Cyborg job available again + - tweak: Mining cyborgs can use steel rods when asteroid mining is enabled + Joan: + - tweak: Repairing clockwork structures with a Clockwork Proselytizer now only costs + 1 alloy per point of damage. + - experiment: Vitality Matrices will no longer heal dead Servants that they cannot + outright revive. + - rscadd: The Celestial Gateway will now prevent the emergency shuttle from leaving. + - tweak: However, Centcom will alert, in general terms, the location of the Celestial + Gateway two minutes after it is summoned. + - rscadd: Reciting scripture while not on the station, centcom, or mining/lavaland + will double recital time and component costs. + Kor: + - rscadd: You can now examine an r-wall to find out which tool is needed to continue + deconstructing it. + - rscadd: The game will now recognize a successful detonation of the nuclear bomb + in the syndicate base. + - rscadd: Cloaks are now cosmetic items that can be worn in the neck slot, allowing + you to wear them over armour. + Shadowlight213: + - rscdel: Removed the restriction on attacking people with a fire extinguisher on + help intent if the safety is on. + uraniummeltdown: + - rscadd: Added Cortical Borers, a brainslug parasite. + - rscadd: Added Cortical Borer Event +2016-11-10: + Kor: + - rscadd: The wizard has a new spell, Rod Form, which allows him to transform into + an immovable rod. + uraniummeltdown: + - bugfix: fixed brains not having ckeys when removed + - bugfix: hopefully fixed multiple ghosts entering a borer ghosting all but one + - tweak: tweaked the formula for hosts needed for borer event to 1+humans/6 + - tweak: borer endround report is a lot nicer +2016-11-11: + Cyberboss: + - bugfix: Promotion of revheads won't occur if they are restrained/incapacitated + - bugfix: Facehuggers can no longer latch onto mobs without a head... How the fuck + did you get a living mob without a head? + - bugfix: Hulks and monkeys can no longer bypass armor + - rscadd: Metastation now has a waste to space line + - bugfix: Objects will no longer get stuck behind the recycler on Boxstation + Joan: + - rscadd: You can now repair reinforced walls by using the tool you'd use to get + to the state they're currently in. Examining will give you a hint as to which + tool to use. + - spellcheck: Renamed Guvax to Geis. This also applies to the component, which has + been similarly renamed. + Kor: + - rscadd: The Captain can now purchase alternate escape shuttles from the communications + console. This drains from the station supply of cargo points, and you can only + do so once per round, so spend wisely. + - rscadd: Some shuttles are less desirable than the default, and will instead grant + the station a credit bonus when purchased. + - rscadd: Explosions are no longer capped on the mining z level. + - rscadd: The forcewall spell now creates a 3x1 wall which the caster can pass through. + - rscadd: Bedsheets are now worn in the neck slot, rather than the back slot. +2016-11-13: + Cyberboss: + - rscadd: Using a screwdriver on a conveyor belt will reverse it's direction + - bugfix: Medibots, by default, can no longer OD you on tricord + - tweak: They will now use charcoal instead of anti-toxin to heal tox damage + - bugfix: Silicons no longer get warm skin when irradiated + Gun Hog: + - tweak: Wizard (and Devil) fireballs now automatically toggle off once fired. + Joan: + - tweak: Judicial Visors now protect from flashes. + - rscadd: Reciting Scripture is now done through an actual interface, and can thus + be done much faster. + - rscdel: The recital and quickbind functions that Recollection had have been moved + to this interface instead. + - rscadd: Servants of Ratvar can now unsecure and move most Clockwork Structures + with a wrench, though doing so will damage the structure by 25% of its maximum + integrity. + - rscadd: Clockwork Structures become less effective as their integrity lowers, + reducing their effect by up to 50% at 25% integrity. + - tweak: You can now deconstruct unsecured wall gears with a screwdriver. + - tweak: Wall gears now have much more health and can be repaired with a proselytizer. + Mysak0CZ: + - rscadd: You can now use wrech to anchor (as long as it is not in space) / unanchor + lockers + - bugfix: Cyborgs can now simply use "hand" to open / close lockers (instead of + using toggle open verb) + - bugfix: You can now properly put unlit welder inside lockers + - bugfix: Lockers using different decostruction tools (like cardboard boxes wirecutters) + can now be deconstructed too + Xhuis: + - rscadd: All computers now have sounds. Try them out! + coiax: + - rscadd: Swarmers can now use :b to talk on Swarm Communication. + - rscadd: Lich phylacteries are now in the "points of interest" for ghosts. + uraniummeltdown: + - bugfix: Cancel Assume Control works as borer now + - rscadd: Added the cueball helmet, scratch suit, joy mask to Autodrobe +2016-11-14: + Joan: + - rscdel: You can no longer pick up cogscarabs. + - rscadd: Servants of Ratvar can now reactivate Cogscarabs with a screwdriver. + - tweak: Cogscarab proselytizers proselytize things twice as fast. + - tweak: Cogscarabs now have 1.6 seconds of delay when firing guns, as much as an + unmodded kinetic accelerator. + - bugfix: Fixed Vitality Matrices and Raise Dead runes not reviving if the target + happened to be in their body already. + Kor: + - rscadd: Extended mode now has a special command report that tells you the round + type. This is to let people know they have time to start on large scale projects + rather than milling about waiting for antagonists to attack. + - rscadd: All station goals are now unlocked during extended. + Mysak0CZ: + - bugfix: MetaStation's xenobiology disposals now work properly + uraniummeltdown: + - tweak: Changed the Command and Security radio colors + - rscadd: Added raw telecrystals to the uplink, can be used with uplinks and uplink + implants. + - rscadd: Added 10mm ammo variants to uplink +2016-11-15: + Cyberboss: + - bugfix: Brains and heads with brains trigger the emergency stop on the recycler + Kor: + - rscadd: The vault is now home to a new machine which can accept cash deposits, + adding to the cargo point total. + - rscadd: You can also use this machine to steal credits from the cargo point total. + Doing so takes time, and will set off an alarm. + - rscadd: You can now buy an asteroid with engines strapped to it to replace the + emergency escape shuttle. + - rscadd: You can now buy a luxury shuttle to replace the emergency escape shuttle. + Each crewmember must bring 500 credits worth of cash or coins to board though. + Lexorion & Lzimann: + - tweak: Wizards have developed a new spell. It's called Arcane Barrage and it has + been reported that it has a similar function to Lesser Summon Guns! + Supermichael777: + - rscdel: The atmos grenades have been removed. if you want to burn down the shuttle + use canisters or something but at least work at it. + coiax: + - rscadd: Mice (the rodent, not the peripheral) now start in random locations. +2016-11-16: + Mysak0CZ: + - rscadd: Door can now have higher security, making them stronger and wires harder + to access + - rscadd: More info can be found on github or wiki (if this passes) + - imageadd: Protected wires now have sprites + Pubby: + - bugfix: cyclelinked airlock pairs now close behind you even when running through + at full speed. + Swindly: + - rscadd: Dice can now be rigged by microwaving them. +2016-11-18: + Cyberboss: + - bugfix: The amount of metal used to construct High Security airlocks with the + RCD is now consistent with the actual cost + Incoming5643: + - bugfix: The charge spell should once again work correctly with guns/wands + Joan: + - rscadd: Clockcult AIs have power as long as they are on a Clockwork Floor or next + to a Sigil of Transmission. This is in addition to having power under normal + conditions. + - rscadd: Clockcult silicons can now activate Clockwork Structures from a distance. + - rscdel: Interdiction Lenses will not disable cameras if there are no living unconverted + AIs. + - rscadd: Clockcult Cyborgs can charge from Sigils of Transmission by crossing them; + after a 5 second delay, the cyborg regains either their missing charge or the + amount of power in the sigil(whichever is lower) over 10 seconds. + - rscadd: You can now cancel out of selecting a robot module! + - imagedel: Robot modules now only have a generic transform animation when selected; + the borg is locked in place for 5 seconds in a small cloud of smoke while the + base borg sprite fades out and the new module fades in. + - tweak: Resetting a borg will do that animation. + - rscadd: Adds Networked Fibers, which gains points instead of automatic expansion + and causes manual expansion near its core to move its core. + - rscadd: Added a new UI style, Clockwork. + NikNak: + - rscadd: Added tator tots, made my putting a potato in the food processor + - tweak: French fries are now made by cutting up a potato into wedges and putting + the wedges (plate and all) into the food processor + coiax: + - bugfix: The observer visible countdown timer for the malfunctioning AI doomsday + device is now formatted and rounded appropriately. + erwgd: + - rscadd: You can now make emergency welding tools in the autolathe. +2016-11-19: + Crushtoe: + - imageadd: Added a shiny new icon for the reaper's scythe in-hand and normal sprite. + It's 25% less gardener. + RandomMarine: + - rscadd: An instruction paper has been added to the morgue on most maps, because + somehow it's needed. + Shadowlight213: + - rscadd: Added the AI integrity restorer as a modular computer program + - rscadd: Added an AI intelliCard slot. Insert an Intellicard into it to be able + to use the restoration program. + - bugfix: Fixes Alarm program detecting ruins + - bugfix: Fixes being unable to toggle the card reader module power + - tweak: The downloader will now tell you if a program is incompatible with your + hardware +2016-11-20: + Basilman: + - rscadd: Added a new beard style, Broken Man. + Cobby: + - tweak: Airlock security is only given to vault doors, centcomm, and Secure Tech + [Secure Tech just requires a welder] + Incoming5643: + - rscadd: The warp whistle has been added to the wizard's repertoire of spells and + artifacts. + - rscadd: The drop table for summon magic has been expanded. + Joan: + - rscdel: Servant cyborgs no longer have emagged modules. + - rscadd: Servant cyborgs now have a limited selection of scripture and tools, which + varies by cyborg type. + Kor: + - bugfix: Station goals will once again function in extended. + Swindly: + - rscadd: Added a nitrous oxide reagent. It can be created by heating 3 parts ammonia, + 1 part nitrogen, and 2 parts oxygen to 525K. The process produces water as a + by-product and will cause an explosion if too much heat is applied. +2016-11-21: + Cobby: + - tweak: mining/labor shuttles are now radiation proof. +2016-11-23: + Crushtoe: + - rscadd: Added more tips. + - bugfix: Fixes some sprites and spelling issues, namely bedsheet capes. + Cyberboss: + - bugfix: Changing an airlock's security level no longer heals it + Gun Hog: + - bugfix: Medibots now heal toxin damage again. + Joan: + - rscadd: Clockcult AIs can now listen to conversations through cameras. + - rscadd: Due to complaints that the new slab interface was too difficult to navigate, + it now starts off in compressed format. The button to toggle this is now also + larger. + Kor: + - rscadd: Rounds ending on one server will send a news report to the other server. + Shadowlight213: + - tweak: Borers now have a 10 second delay before waking up after sugar leaves the + host system + - tweak: There is a chance for borers to lose control, based on brain damage levels + Swindly: + - rscadd: Most small items can now be placed in the microwave. Remember not to microwave + metallic objects. + XDTM: + - rscadd: 'Golems now have special properties based on the mineral they''re made + of:' + - rscadd: Silver golems have a higher chance of stun when punching + - rscadd: Gold golems are faster but less armoured + - rscadd: Diamond golems are more armoured + - rscadd: Uranium golems are radioactive + - rscadd: Plasma golems explode on death + - rscadd: Iron and adamantine golems are unchanged. + jakeramsay007: + - tweak: Borers can no longer take control of people who have a mindshield implant + or are a member of either cult. This however does not stop them from infesting + and controlling them through other means, such as chemicals. +2016-11-24: + Kor: + - rscadd: Shaft miners now have access to the science channel. + Lzimann: + - rscdel: Multiverse sword is no longer buyable by wizards + erwgd: + - rscadd: Plasmamen get their own random names. +2016-11-25: + Joan: + - rscadd: Clockcult AIs with borgs 'slaved' to them will convert them when hacking + via the robotics console. + - experiment: Replaced the "No Cache" alert with an alert that will show what you + need for the next tier of scripture. + Kor: + - rscadd: The captain may now purchase an unfinished shuttle chassis, which will + dock immediately when bought, but will not launch until the end of the regular + shuttle call procedure. The shuttle is empty and devoid of atmosphere however, + so you'll need to do some work on it if you want a safe trip home. + Shadowlight213: + - bugfix: The activation button for the AI integrity restorer modular program actually + works now! + - rscdel: The cortical borer event is now admin only +2016-11-27: + Cyberboss: + - bugfix: False armblades are now removed after one minute. Start feeling the P + A R A N O I A when you see em + Gun Hog: + - rscadd: AIs piloting a mech may now be recovered with an Intellicard from the + wreckage if the mech is destroyed. They will be require repair once recovered. + - tweak: Instructions for piloting mechs as an AI are now more obvious. + - tweak: Traitor and Ratvar AIs may now be carded from mechs, at their discretion. + Joan: + - tweak: Clockwork walls are now about as hard for hulks to break as rwalls. + - rscadd: You can now quickbind up to 5 scriptures from the recital menu, and the + recital menu has less empty space. + - tweak: Clockwork slabs now only start with only Geis pre-bound. + Kor: + - rscadd: Shaft miners can now redeem their starting voucher for a conscription + kit, which contains everything they need to rope their friend into joining them + on lavaland. + - rscadd: You can now see which emergency shuttle is coming in the status panel. + Lzimann: + - rscadd: The robots stole Santa's Elfs jobs. + MMMiracles: + - tweak: Jump boots now have a pocket + - imageadd: Jump boots from mining now have on-character icons. + Mervill: + - imageadd: Disposal units now use a tgui instead of plain html + - rscadd: 'As the AI: Click an AI status display to bring up the prompt for changing + the image' + Swindly: + - rscadd: Wet leather can be dried by putting it on a drying rack. + Xhuis: + - bugfix: Plastic explosives now actually explode when you commit suicide with them. + - bugfix: Resisting out of straight jackets now works properly. + - rscdel: Highlander will no longer announce the last man standing. + - rscadd: Cyborgs can now open morgue trays. This does not include crematoriums! + uraniummeltdown: + - rscdel: Borers no longer randomly lose control based on host brain damage + - tweak: Borer Dominate Victim stun time reduced from 4 -> 2. + - tweak: Borers no longer force unhidden when infesting someone. + - tweak: Borer event is rarer (weight 20->15). + - tweak: Borer reproduction chemicals required increased from 100 to 200. +2016-11-29: + Joan: + - tweak: Interdiction Lenses are more likely to turn off if damaged. + - tweak: Reduced Interdiction Lens and Tinkerer's Daemon CV from 25 to 20. + RemieRichards: + - rscadd: Devils may now spawn with an obligation to accept dance off challanges, + if they have this obligation they also gain a spell to summon/unsummon a 3x3 + dance floor at will. + Swindly: + - rscadd: Microwaves now heat open reagent containers to 1000K. + XDTM: + - rscadd: 'Added new types of golem: glass, sand, wood, plasteel, titanium, plastitanium, + alien alloy, bananium, bluespace, each with their own traits. Experiment!' + - tweak: Golems will be told what their traits are when spawning. + - rscadd: Putting a golem in a gibber will give ores of its mineral type, instead + of meat. + - rscadd: Using Iron on an adamantine slime extract will spawn an incomplete golem + shell, that will be slaved to whoever completes it, much like a normal adamantine + golem. + jughu: + - tweak: Proselytizing airlocks into pinion airlocks takes longer. +2016-11-30: + ANGRY CODER: + - tweak: NT news reports the clandestine criminal organization known as the syndicate + may have upgraded one of their illegally stolen cyborg modules with additional + healing technology. + Cobby [Idea stolen from Shaps]: + - rscadd: For objects that you could previously rename with a pen, you can now edit + their description as well. + Cyberboss: + - rscdel: Due to budget cuts. Firelocks no longer have safety features + - bugfix: Roundstart airlock electronics now properly generate the correct accesses + - bugfix: tgui windows will now close on round end + Gun Hog: + - bugfix: Syndicate Medical Cyborg hyposprays now properly work through Operative + hardsuits and other thick clothing. + Joan: + - tweak: Cogscarabs will once again convert metal, rods, and plasteel directly to + alloy. + - tweak: Tinkerer's caches now increase in cost every 4 caches, from 5. + - rscadd: The Ark of the Clockwork Justicar now converts all silicons once it finishes + proselytizing the station. + Mervill: + - rscadd: AI hologram can move seamlessly between holopads + Thunder12345: + - rscadd: Added anti-armour launcher. A single-use rocket launcher capable of penetrating + all but the heaviest of armour. Deals massively increased damage to cyborgs + and mechs. diff --git a/html/changelogs/archive/2016-12.yml b/html/changelogs/archive/2016-12.yml new file mode 100644 index 0000000000..debb0dbbf9 --- /dev/null +++ b/html/changelogs/archive/2016-12.yml @@ -0,0 +1,469 @@ +2016-12-02: + Cobby: + - bugfix: Removes the exploit that allowed you to bypass grabcooldowns with Ctrl+Click + PeopleAreStrange: + - tweak: Changed F7 to buildmode, F8 to Invismin (again). Removed stealthmin toggle + RemieRichards: + - rscadd: Added a new lavaland "boss" + - tweak: Hostile mobs will now find a new target if they failed to attack their + current one for 30 seconds, this reduces cheese by simply making the mob find + something else to do/someone to kill + - bugfix: Hostile mobs with search_objects will now regain that value after a certain + amount of time (per-mob, base 3 seconds), this is because being attacked causes + mobs with this var to turn it off, so they can run away, however it was literally + never turned on which caused swarmers to get depression and never do anything. +2016-12-03: + Joan: + - rscadd: Trying to move while bound by Geis will cause you to start resisting, + but the time required to resist is up by half a second. + - experiment: Resisting out of Geis now does damage to the binding, and as such + being stunned while bound will no longer totally reset your resist progress. + - rscadd: Using Geis on someone already bound by Geis will interrupt them resisting + out of it and will fully repair the binding. + - tweak: Geis's pre-binding channel now takes longer for each servant above 5. Geis's + conversion channel also takes slightly longer for each servant above 5. + - rscadd: Converted engineering and miner cyborgs can now create Sigils of Transgression. + RandomMarine: + - tweak: Airlocks will keep their original name when their electronics are removed + and replaced. You may still use a pen to rename the assembly if desired. +2016-12-04: + Durkel: + - tweak: Recent enemy reports indicate that changelings have grown bored with attacking + near desolate stations and have shifted focus to more fertile hunting grounds. +2016-12-06: + BASILMAN YOUR MAIN MAN: + - bugfix: fixes people "walking over the glass shard!" when they're on the ground, + changes message when incapacitated + Chnkr: + - rscadd: Nuclear Operatives can now customize the message broadcast to the station + when declaring war. + Cyberboss: + - bugfix: The atmos waste lines for the Metastation Kitchen and Botany departments + is now actually connected + Gun Hog: + - rscadd: Nanotrasen Janitorial Sciences Division is proud to announce a new concept + for the Advanced Mop prototype; It now includes a built-in condenser for self + re-hydration! See your local Scientist today! In the event that janitorial staff + wish to use more expensive solutions, the condenser may be shut off with a handy + handle switch! + Incoming5643: + - bugfix: The timer for shuttle calls/recalls now scales with the security level + of the station (Code Red/Green, etc.). You no longer have to feel dumb if you + forget to call Code Red before you call the shuttle! + - rscadd: Shuttles called in Code Green (the lowest level) now take 20 minutes to + arrive, but may be recalled for up to 10 minutes. They also don't require a + reason to be called. + - experiment: That doesn't mean you should call a code green shuttle every round + the moment it finishes refueling. + - rscadd: Server owners may now customize the population levels required to play + various modes. Keep in mind that this does not preserve the balance of the mode + if you change it drastically. See game_modes.txt for details. + Joan: + - rscadd: You can now proselytize floor tiles at a rate of 20 tiles to 1 brass sheet + or 2 tiles to 1 liquified alloy for cogscarabs. + - rscadd: Proselytizers will automatically pry up floor tiles if those tiles can + be proselytized. + - tweak: Brass floor tiles no longer exist. Instead, you can just apply brass sheets + to a tile. Crowbarring up a clockwork floor will yield that brass sheet. + - rscadd: You can now cancel AI intellicard wiping. + - tweak: Geis now takes 5 seconds to resist. + Mervill: + - bugfix: Examining now lists the neck slot + MisterTikva: + - rscadd: Nanotrasen informs that certain berry and root plants have been infused + with additional genetic traits. + - rscadd: Watermelons now have water in them! + - rscadd: Blumpkin's chlorine production has been reduced for better workplace efficiency. + - rscadd: Squishy plants now obey the laws of physics and will squash all over you + if fall on them. + Shadowlight213: + - bugfix: The lavaland syndicate agents, as well as the ID for all simple_animal + syndicate corpses should have their ID actually have syndicate access on it + now! + Swindly: + - rscadd: 'Adds a new toxin: Anacea. It metabolizes very slowly and quickly purges + medicines in the victim while dealing light toxin damage. Its recipe is 1 part + Haloperidol, 1 part Impedrezene, 1 part Radium.' + WJohn: + - bugfix: AI core turrets can once again hit you if you are standing in front of + the glass panes, or in the viewing area's doorway. + XDTM: + - rscadd: Quantum Pads are now buildable in R&D! + - rscadd: Quantum Pads, once built, can be linked to other Quantum Pads using a + multitool. Using a Pad who has been linked will teleport everything on the sending + pad to the linked pad! + - rscadd: 'Pads do not need to be linked in pairs: Pad A can lead to Pad B which + can lead to pad C.' + - rscadd: Upgrading a Quantum Pad will reduce the cooldown, charge-up time, and + power consumption. + - rscadd: Quantum Pads require a bluespace crystal, a micro manipulator, a capacitor + and a cable piece. + kilkun: + - rscadd: New lore surrounding the various SWAT suits. + - tweak: Captain's hardsuit/SWAT suit got a few buffs. It's now much more robust. + - bugfix: Captain's space suit is now heat proof as well as fireproof. Long overlooked + no longer. +2016-12-07: + Cyberboss: + - bugfix: Atmos canisters now stay connected after relabeling them + Incoming5643: + - rscadd: Server owners that use the panic bunker feature can now optionally redirect + new players to a different server. See config.txt for details. + LOOT DUDE: + - tweak: Swarmers will drop bluespace crystals on death, non-artificial crystals. + MisterTikva: + - rscadd: Nanotrasen Mushroom Studies Division proudly announces that growth serum + producing plants were genetically reassembled. You no longer alternate between + sizes with doses 20u+ and more effects were added to higher doses. + Thunder12345: + - bugfix: You can now only order a replacement shuttle once +2016-12-08: + Fox McCloud: + - rscadd: The ability to harvest a plant, repeatedly, is now a gene-extractable + trait that can be spliced into other plants + - rscadd: can extract the battery capabilities of potatoes and splice them into + other plants + - rscadd: Plants types are now gene traits that can be added/removed from plants + - rscadd: Adds new stinging plant trait that will inject a bit of a plant's reagents + when thrown at someone + Joan: + - rscadd: The clockwork slab's interface is now TGUI. + - imageadd: You can now see what an ocular warden is attacking. + Mervill: + - rscadd: The light replacer can now create bulbs from glass shards + - rscadd: Click a light replacer while holding a glass shard to add the shard to + the replacer + - rscadd: Click a glass shard while holding a light replacer to consume the shard + MrStonedOne: + - tweak: world initialization is now faster. + - bugfix: fixed the modify bodypart admin tool not working + PKPenguin321: + - tweak: Swarmer beacons now have 750 health, down from 3000. + TehZombehz: + - rscadd: Nanotrasen Culinary Division has authorized the production of tacos, both + plain and classic. + XDTM: + - bugfix: Replica Pod cloning now works on people who have been decapitated. + coiax: + - rscadd: Additional mice sometimes appear in the maintenance tunnels. Engineers + beware! +2016-12-10: + Cyberboss: + - bugfix: The slips bug (which made freon laggy) is fixed + Kor: + - imagedel: Deleted all (3000+) left handed inhand icons. They are now automatically + mirrored from the right hand, saving spriters a lot of tedious busywork. + - rscadd: By crafting a wall mounted flasher frame (can be ordered via cargo), a + flash, and a riot shield, you can now construct a strobe shield. The strobe + shield combines the functionality of a riot shield and a flash, and can be reloaded + with flash bulbs. + Supermichael777: + - tweak: Conveyors have been more firmly anchored. No fun allowed + Thunder12345: + - rscadd: Added the Standby Emergency Vessel "Scrapheap Challenge" as a new emergency + shuttle option. You'll even be paid 1000 credits to use it! + coiax: + - rscadd: Due to a combination of radiation and water supply contamination, stations + have been reporting animals gaining self awareness. + optional name here: + - bugfix: fixed ashdrake's flame wall. + - bugfix: fixed walls decon spawning metal in a random location in the same room. +2016-12-11: + Cobby: + - bugfix: Fixes literally everything regarding renaming so far. When adding unique_rename + to objects, make sure the attackby checks for inheritance. + - bugfix: You can pull as other mobs now. Sorry, clickcode is stupid. + Cyberboss: + - bugfix: Frozen things will now unfreeze above 0C + Joan: + - tweak: Invoking Nezbere now increases ocular warden damage slightly more, but + increases ocular warden range slightly less. + Swindly: + - tweak: The recipe for moonshine now calls for 5 units of nutriment and 5 units + of sugar instead of 10 units of nutriment. + Thunder12345: + - bugfix: Scrapheap Challenge shuttle now actually works + coiax: + - rscadd: Cyborgs now have a reset module wire, that when pulsed, triggers the cyborg's + reset module hardware. + - rscadd: Cyborgs now eject all upgrades when reset, rather than the upgrades being + destroyed. + - rscdel: Removed redundant reset module. +2016-12-12: + Dannno: + - rscadd: more chaplain outfits + - rscadd: animal and tribal masks to the theater vendor +2016-12-13: + Fox McCloud: + - rscadd: Adds in random botany seeds; never the same twice. + - rscadd: Adds in new trait that makes a grown release smoke when squashed + - rscadd: Weed rates and chances are now core seed genes + Joan: + - experiment: Clockwork proselytizers suffer doubled cost and proselytization time + when not on the station, mining, or centcom. + - soundadd: Trying to recite scripture offstation is more clearly disapproved of. + XDTM: + - bugfix: The internal rage of the crew has been suppressed, and they will no longer + attack their own backpacks when opening them. +2016-12-14: + Incoming5643: + - rscadd: Recently we've been receiving reports of cheap knock off nuclear authentication + disks circulating among the syndicate network. Don't be fooled by these decoys, + only the real deal can be used to destroy the station! + - experiment: Please don't destroy the station in an attempt to make sure the disk + is real. + Joan: + - rscdel: The Ark of the Clockwork Justicar can no longer be repaired. + - tweak: The Ark now has 20% more health. + - rscadd: The Ark of the Clockwork Justicar will now force objects away from it. + - tweak: Faster-than-normal tools are somewhat slower than before. + - tweak: Mania Motors now require a much larger amount of power to convert people + adjacent, and people converted by it are knocked out. + Mindustry: + - bugfix: Goliath meat can be cooked in lava again + Okand37: + - rscadd: DeltaStation's emergency shuttle + XDTM: + - rscadd: Abductor Agents have now been equipped with extremely advanced construction + and hacking tools. +2016-12-18: + Dannno: + - rscadd: Sec hailers can now be emagged for a more rational, calm message. + Erwgd: + - rscadd: Limb Grower circuit boards can now be made in Research and Development, + requiring level 3 in data theory and level 2 in biological technology. + Firecage: + - rscadd: The NanoTrasen Airlock Builder Federation(NTABF) has recently released + the blueprints involving building and deconstructing Titanium Airlocks! These + airlocks are now being used on all of our shuttles. + Fox McCloud: + - bugfix: Fixes the personal crafting cost of ED-209's being too expensive + Hyena: + - tweak: adds 2 geiger counters to radition protection crates and a gift from the + russians + Joan: + - rscadd: Adds Replicant and Tinkerer's Cache to the default slab quickbind. + - rscadd: Revenants will be revealed by ocular wardens when targeted. + Joan, Dagdammit: + - rscadd: You can now push Wraith Spectacles up to avoid vision damage, but lose + xray vision. + - wip: Do note that flicking them on and off very quickly may cause you to lose + vision rather quickly. + Kor: + - rscadd: Added the treasure hunter's hat, coat, uniform, and whip. These aren't + available on the map yet, but will be available to the librarian soon. + Mervill: + - rscadd: Notice boards can now have photographs pined to them + - tweak: Items removed from the notice board are placed in your hands + - bugfix: Intents can be cycled forward and backwards with hotkeys again + - bugfix: Russian revolver ammo display works correctly + - rscadd: Added a credit deposit to pubbystation's vault + - rscdel: Removed a rather garish golden statue of the HoP from pubbystation's vault + Okand37 & Lexorion: + - rscadd: Added a new hair style, the Sidecut! + Supermichael777: + - rscadd: Clockwork components the chaplain picks up are now destroyed. + Swindly: + - rscadd: Adds eggnog. It can be made by mixing 5 parts rum, 5 parts cream, and + 5 parts egg yolk. + XDTM: + - rscadd: Changelings can now buy Tentacles on the Cellular emporium for 2 evolution + points. + - rscadd: Tentacles, once used, can be fired once against an item or mob to pull + it towards yourself. Items will be automatically grabbed. Costs 10 chemicals + per tentacle. + - rscadd: 'On humanoid mobs tentacles have a varying effect depending on intent: + - Help intent simply pulls the target closer without harming him; - Disarm intent + does not pull the target but instead pulls whatever item he''s holding in his + hands to yours; - Grab intent puts the target into an aggressive grab after + it is pulled, allowing you to throw it or try to consume it; - Harm intent will + briefly stun the target on landing; if you''re holding a sharp weapon you''ll + also impale the target, dealing increased damage and a longer stun.' + - bugfix: Random golems now properly acquire the properties of the golem they pick. + - rscadd: When becoming a random golem the user is informed of the properties of + the picked golem. + coiax: + - rscadd: Chameleon clothing produced by the syndicate has been found to react negatively + to EMPs, randomly switching forms for a time. + - rscadd: Anomalies now have observer-visible countdowns to their detonation. + - rscadd: Adds upgrades for the medical cyborg! + - rscadd: The Hypospray Expanded Synthesiser that adds chemicals to treat blindness, + deafness, brain damage, genetic corruption and drug abuse. + - rscadd: The Hypospray High-Strength Synthesiser, containing stronger versions + of drugs to treat brute, burn, oxyloss and toxic damage. + - rscadd: The Piercing Hypospray (also applicable to the Standard and Peacekeeper + borgs) that allows a hypospray to pierce thick clothing and hardsuits. + - rscadd: The Defibrillator, giving the medical cyborg an onboard defibrillator. + - rscadd: Loose atmospherics pipes are now dangerous to be hit by. + - rscadd: Whenever you automatically pick up ore with an ore satchel, if you are + dragging a wooden ore box, the satchel automatically empties into the box. + dannno: + - rscadd: Adds a villain costume to the autodrobe. + - bugfix: Fixes autodrobe failing to stock items. + jughu: + - tweak: 'sandals are not fireproof or acidproof anymore :add: Magical sandals for + the wizard that are still fireproof/acid proof :tweak: makes the marisa boots + acid and fire proof too' + karlnp: + - bugfix: made facehuggers work again + - bugfix: vendors, airlocks, etc now cannot shock at a distance + uraniummeltdown: + - tweak: Side entrance to Box Medbay, a few layout changes. +2016-12-19: + spudboy: + - bugfix: Fixed items not appearing in the detective's fedora. +2016-12-20: + Kor: + - rscadd: You can put a variety of hats on cyborgs using help intent (the engiborg + can't wear hats though, as it is shaped too oddly. Sorry!) + - rscadd: 'The complete list of currently equippable hats is as follows: Cakehat, + Captains Hat, Centcomm Hat, Witch Hunter Hat, HoS Cap, HoP Cap, Sombrero, Wizard + Hat, Nurse Hat.' + Lzimann: + - bugfix: Mjor the Creative will drop his loot correctly now. + Mekhi Anderson: + - rscdel: Fixes various PAI bugs, various tweaks and bullshit. + MrPerson: + - rscadd: Starlight will have more of a gradient and generally shine a more constant + amount of light regardless of how many tiles are touching space. In dark places + with long borders to space, starlight will be much darker. +2016-12-21: + FTL13, yogstation, Iamgoofball, and MrStonedOne: + - rscadd: Space is pretty. + - tweak: You can configure how pretty space is in preferences, those of you on toasters + should go to low to remove the need to do client side animations. (standard + fanfare as job selection, left click to increase, right click to decrease) (Changes + are applied immediately in most cases, on reconnect otherwise) + Joan: + - rscadd: EMPs will generally fuck up clockwork structures. + - rscdel: Cogscarabs can no longer hold slabs to produce components. + - rscadd: Slabs will now produce components even if in a box in your backpack inside + of a bag of holding on your back; any depth you can hide the slab in will still + produce components. + - bugfix: Non-Servants in possession of clockwork slabs will also no longer produce + components. + Mekhi Anderson: + - bugfix: PAI notifications no longer flood those who do not wish to be flooded. + Shadowlight213: + - imageadd: 2 new performer's outfits have been added to the autodrobe +2016-12-24: + AnturK: + - rscadd: Implants now work on animals. + Cyberboss: + - bugfix: Dead things can no longer be used to open doors + F-OS: + - bugfix: swarmers can no longer destroy airlocks. + MrStonedOne: + - tweak: AI's call bot command has been throttled to prevent edge cases causing + lag. You will not be able to call another bot until the first bot has finished + mapping out it's route. + TehZombehz: + - tweak: Observers can now orbit derelict station drone shells, much like current + lavaland ghost role spawners, to make finding them easier. Regular drone shells + are not affected by this. + XDTM: + - rscadd: Autolathes are now true to their name and can queue 5 or 10 copies of + the same item. + coiax: + - rscadd: Cyborg renaming boards cannot be used if no name has been entered. + - rscdel: Cyborg rename and emergency reboot modules are destroyed upon use, and + not stored inside the cyborg to be ejected if modules are reset. + - rscadd: Emagging the book management console and printing forbidden lore now has + a chance of producing a clockwork slab rather than an arcane tome. + kevinz000: + - experiment: Flightsuits now have their own subsystem! + - bugfix: Flightsuits properly account for power before calculating drifting + - experiment: Flightpack users will automatically fly over anyone buckled without + crashing. + - experiment: Flightpack users automatically slip through mineral doors + - experiment: Flightpack users will crash straight through grills at appropriate + times + - experiment: Flightpack users automatically slip through unbolted airlocks + - experiment: Flightpacks are faster in space, but their space momentum decay has + been upped significantly to compensate + - experiment: Flighthelmets now have a function to allow the wearer to zoom out + to see further. Helps you not crash eh? + spudboy: + - bugfix: Gave cyborgs some hotkeys they should have had. +2016-12-27: + Firecage: + - bugfix: The Nanotrasen Sewing Club has finally fixed the problem which rendered + NT, Ian, and Grey bedsheets invisible when worn! + Hyena: + - tweak: Detective coats can now hold police batons + - bugfix: Fixes disabler in hand sprites + Joan: + - rscadd: You can now put syndicate MMIs and soul vessels into AI cores. + - rscadd: The Hierophant boss will now create an arena if you try to leave its arena. + - imageadd: The Hierophant boss, its arena, and the weapon it drops all have new + sprites. + - soundadd: And new sounds. + - wip: And new text. + - rscadd: Wizards can now buy magic guardians for 2 points. They are not limited + to one guardian, meaning they can have up to 5. If that's wise is an entirely + different question. + - experiment: Wizards cannot buy support guardians, but can buy dexterous guardians, + which can hold items. + Shadowlight213: + - tweak: Shuttle are now safe from radstorms + XDTM: + - bugfix: HUD implants now properly allow you to modify the records of those you + examine, like HUD glasses do. + - bugfix: Organ Manipulation surgery now properly heals on the cautery step. + - bugfix: The maintenance door adjacent to R&D in metastation is now accessible + to scientists, instead of requiring both science and robotics access. +2016-12-28: + Erwgd: + - rscadd: A new access level is available, named "Cloning Room". Medical Doctors, + Geneticists and CMOs start with it. + - tweak: On Box Station and on Meta Station, the cloning lab doors require Cloning + Room access in addition to each door's previous requirements. + - tweak: Cloning pods are now unlocked with Cloning Room access only. + Incoming5643: + - rscadd: There's a new category in uplinks for discounted gear. These special discounts + however can only be taken once, so even if you are lucky enough to see syndibombs + for 75% off you won't be able to nuke the entire station with them. + - bugfix: The charge spell will no longer bilk you on wand charges, and wands that + are dead won't show up as charged. + Joan: + - rscdel: Clockwork Marauders no longer have Fatigue. It was difficult to balance + and made them too easy to force into recalling. This means they just have health; + they aren't forced to recall by anything, but can accordingly die much more + easily. + - rscadd: Accordingly Clockwork Marauders now have more health, do slightly more + damage, block slightly more often, and have to go slightly further from their + host to take damage. + - rscadd: Marauders that are not recovering(from recalling while the host's health + is too high to emerge) and are inside their host, or are within a tile of their + host, will gradually heal their host until their host is above the health threshold + to emerge. + - tweak: Chaos guardians transfer slightly less damage to their summoner. + XDTM: + - tweak: Armblades now go slash slash instead of thwack thwack + - imageadd: Tentacles have some fancier sprites +2016-12-29: + Mervill: + - bugfix: Patched an exploit related to pulling a vehicle as its driver while in + space + - bugfix: Fixed evidence bags not displaying their contents when held + - bugfix: Clothing without a casual variant will no longer say it can be worn differently + when examined + - bugfix: Only standard handcuffs can be used to make chained shoes + - bugfix: Fixed cards against space + - bugfix: Drying rack sprite updates properly when things are removed without drying + XDTM: + - rscadd: Colossi now drop the Voice of God, a mouth organ that, if implanted, allows + you to speak in a HEAVY TONE. This voice can compel hearers to briefly obey + certain codewords, such as "STOP". Using these codewords will severely increase + this ability's cooldown, and only one will be used per sentence. + - rscadd: 'Use .x, :x, or #x as a prefix to use Voice of God or any future vocal + cord organs.' + - rscadd: Chaplains, being closer to the gods, and command staff, being used to + giving orders, gain an increased effect when using the Voice of God. The mime, + not being used to speaking, has a reduced effect. +2016-12-31: + hyena: + - bugfix: fixes caps suit fire immunity + kevinz000: + - bugfix: Machine overloads/overrides aren't as bullshit as you'll actually be able + to dodge it now. diff --git a/html/changelogs/archive/2017-01.yml b/html/changelogs/archive/2017-01.yml new file mode 100644 index 0000000000..224976189b --- /dev/null +++ b/html/changelogs/archive/2017-01.yml @@ -0,0 +1,535 @@ +2017-01-01: + A whole bunch of spiders in a SWAT suit: + - bugfix: spiders can't wrap anchored things +2017-01-02: + MrStonedOne: + - tweak: Throwing was refactored to cause less lag and be more precise + - rscadd: Item throwing now imparts the momentum of the user throwing. Throwing + in the direction you are moving throws the item faster, throwing away from the + direction you are moving throws the item slower. This should make hitting yourself + with floor tiles less likely. + XDTM: + - bugfix: Storage bags should now cause less lag when picking up large amounts of + items. + - bugfix: Storage bags now don't send an error message for every single item they + fail to pick up. +2017-01-03: + Cyberboss: + - bugfix: AIs can no longer see cult runes properly + Mervill: + - bugfix: Can't kick racks if weakened, resting or lying +2017-01-06: + Cruix: + - bugfix: Fixed the leftmost and bottommost 15 turfs not having static for AIs and + camera consoles + Joan: + - bugfix: Tesla coils and grounding rods must be anchored with a closed panel to + function, ie; not explode when shocked. + - tweak: Metastation's xenobio has been slightly modified to avoid getting hit by + some standard shuttles. + Mervill: + - bugfix: Regular spraycans aren't silent anymore + MrStonedOne and Ter13: + - rscadd: Added some ping tracking to the game. + - rscadd: Your ping shows in the status tab + - rscadd: Other players ping shows in who to players and admins. + Nabski89: + - bugfix: Re-Vitiligo Levels to match wiki. + XDTM: + - tweak: Voice of God's Sleep lasts less than the other stuns. + - rscadd: You can also use people's jobs to single them out, instead of only names. + - tweak: If multiple people share the same name/job they'll all be included, although + at a reduced bonus. + - tweak: Names and jobs will only be accepted if they're the first part of the command, + and not in the middle, to prevent unintended focusing. + - bugfix: Voice of God now shows speech before the emotes it causes. + - bugfix: Special characters are no longer over-sanitized. + - bugfix: You can now properly apply items to clothing with pockets, such as slime + speed potions on clown shoes. + - bugfix: Mechs are now able to enter wormhole-sized portals. +2017-01-08: + Mervill: + - bugfix: pre-placed posters don't retain their pixel offset when taken down carefully + - bugfix: Dinnerware Vendor will show it's wire panel + Nanotrasen Station Project Advisory Board: + - wip: It is highly recommended that, when constructing the Meteor Shield project, + you are able to see, at minimum, two meteor shields from a stationary location. + The Nanotrasen Station Project Advisory Board is not liable for meteor damage + taken under wider shield arrangements. + Speed of Light Somehow Changed: + - tweak: Dynamic lights are no longer animated, and update instantly + - tweak: Increased maximum radius of mob and mobile lights +2017-01-10: + Arianya: + - bugfix: Doors and vending machines once again make a sound when you screwdriver + them. + Cyberboss: + - bugfix: Explosions can no longer be dodged + - tweak: Airlocks are now destroyed by the same level explosion that destroys walls + - tweak: Diamond/External/Centcomm airlocks and firedoors now block explosions as + walls do + Joan: + - experiment: Clockwork Proselytizers no longer require Replicant Alloy to function; + instead, they gradually charge themselves with power, which is used more or + less the same as alloy. + - tweak: Clockwork Proselytizers now produce brass sheets when used in-hand, instead + of Replicant Alloy. + - rscdel: Tinkerer's Caches can no longer have Replicant Alloy removed from them; + using an empty hand on them will simply check when they'll next produce a component. + - rscdel: Mending Motors can no longer use Replicant Alloy in place of power. + Mervill: + - bugfix: Controlling the station status displays no longer overrides the cargo + supply timer + MrStonedOne: + - experiment: Lighting was made more responsive. + XDTM: + - rscadd: Earmuffs and null rods protect against the Voice of God. + - rscadd: Earmuffs are now buildable in autolathes. + - tweak: Voice of God stuns have a longer cooldown. + coiax: + - rscadd: Girders now offer hints to their deconstruction when examined. +2017-01-13: + Cyberboss: + - bugfix: Walls blow up less stupidly + - bugfix: You no longer drop a beaker after attempting to load it into an already + full cryo cell + Joan: + - bugfix: Instant Summons is no longer greedy with containers. + Mervill: + - bugfix: Hardsuits, amour and other suits that cover the feet now protect against + glass shards + - bugfix: You will now lose the lawyer's speech bubble effect if you unequip the + layer's badge + MrStonedOne: + - tweak: More performance tweaks with the modulated reactive ensured entropy frame + governor system + PKPenguin321: + - tweak: Ash walker tendrils will now restore 5% of their HP when fed. + Shadowlight213: + - bugfix: Borg emotes should now play at the correct pitch + - bugfix: The ID console now properly handles authorization + - bugfix: Clicking on one of the ID cards in the UI will no longer eject both of + them + Thunder12345: + - bugfix: Morphs will no longer retain the colour of the last thing mimicked when + reverting to their true form + XDTM: + - bugfix: Patches' application is now properly delayed instead of instant. + - bugfix: Accelerator laser cannons' projectile now properly grows with distance. + coiax: + - rscadd: The end of round stats include the number of people who escaped on the + main emergency shuttle. +2017-01-14: + Cyberboss: + - bugfix: Explosions now flash people properly + Lzimann: + - bugfix: Fixes TGUI not working for people without IE11 + Thunder12345: + - bugfix: Recoloured mobs and objects will no longer produce coloured fire. + XDTM: + - bugfix: Nanotrasen decided that the "violent osmosis" method for refilling fire + extinguishers was, while cathartic, too expensive, due to the water tank repair + bills. Water tanks now have a tap. + - bugfix: (refilling extinguishers from tanks won't make you hit them) + - bugfix: Golems no longer drop belt, id, and pocket contents in a fit of extreme + clumsiness when drawing a sword from a sheath. + - bugfix: Wrenching portable chem dispensers won't cause you to immediately try + unwrenching them. + coiax: + - bugfix: Blue circuit floors are now restored to their normal colour if an AI doomsday + device is disabled. +2017-01-16: + Cyberboss: + - bugfix: Firedoors no longer have maintenance panels + - tweak: Firedoors must now be welded and screwdrivered prior to be deconstructed + Joan: + - rscadd: Ratvar will now convert lattices and catwalks to clockwork versions. + XDTM: + - tweak: Updating your PDA info with an agent id card inside will also overwrite + the previous name. + - bugfix: Loading a xenobiology console with a bio bag won't cause you to smack + it with it. + - tweak: Chemical splashing is now based on distance rather than affected tiles. + - bugfix: You can now properly wet floors by putting enough water in a grenade. + - bugfix: Floating without gravity won't drain hunger. +2017-01-18: + Mervill: + - bugfix: Using a welder to repair a mining drone now follows standard behaviour + - bugfix: Redeeming the mining voucher for a mining drone now also provides welding + goggles + - bugfix: ntnrc channels are now deleted properly + Tofa01: + - bugfix: Moved all sprites for heat pipe manifold either up or down by one so that + they will line up correctly when connected to adjacent pipes. + uraniummeltdown: + - rscadd: More AI holograms! +2017-01-19: + Cyberboss: + - bugfix: Various abstract entities will no longer be affected by spacewind + - bugfix: Ash will, once again, burn in lava + - rscadd: Active testmerges of PRs will now be shown in the MOTD + - bugfix: You will no longer appear to bleed while bandaged + Joan: + - spellcheck: Clockwork airlocks now have more explicit deconstruction messages, + using the same syntax as rwall deconstruction. + Mervill: + - bugfix: Raw Telecrystals won't appear in the Traitor's purchase log at the end + of the round + MrStonedOne: + - bugfix: Fixed excessive and immersion ruining delay on the smoothing of asteroid/mining + rock after a neighboring rock turf was mined up. + XDTM: + - bugfix: Plasmamen that are set on fire by reacting with oxygen will burn even + if they have protective clothing. It will still protect from external fire sources. + - tweak: Atmos-sealing clothing, like hardsuits, will protect plasmamen from reacting + with the atmosphere. + - tweak: Plasmamen can survive up to 1 mole of oxygen before burning, instead of + burning with any hint of oxygen. + - bugfix: Nanotrasen no longer ships self-glueing posters. You'll have to finish + placing the posters to ensure they don't fall on the ground. + - bugfix: Exosuits can't push anchored mobs, such as megafauna or tendrils, anymore. + coiax: + - bugfix: AIs can no longer activate the Doomsday Device off-station. Previously + it would activate and then immediately turn off, outing the AI as a traitor + without any benefit. +2017-01-20: + CoreOverload: + - tweak: Any sharp item can now be used for "incise" surgery step, with 30% success + probability. + Joan: + - rscadd: Sentinel's Compromise will also convert oxygen damage into half toxin, + in addition to brute and burn. + - tweak: Reduced the Ark of the Clockwork Justicar's health from 600 to 500 + - rscadd: You can now pull objects past the Ark of the Clockwork Justicar without + them being moved and or destroyed by its power. + MrStonedOne: + - tweak: Server side timing of the parallax shuttle launch animation now runs on + client time rather than byond time/server time. This will fix the odd issues + it has during lag. The parallax shuttle slowdown animation will still have issues, + those will be fixed in another more involved update to shuttles. + - rscadd: The window will flash in the taskbar when a new round is ready and about + to start. + Tofa01: + - bugfix: Moved The CentComm station 6 tiles to the left in order to prevent large + shuttles such as "asteroid with engines on it" from clipping off the end of + the right side of the map. + XDTM: + - bugfix: Chameleon PDAs can now morph into assistant PDAs. + - bugfix: A few iconless items have been blacklisted from chameleon clothing. + - tweak: Reviver implants now warn you when they're turning on or off, or when giving + a heart attack due to EMP. +2017-01-22: + ChemicalRascal: + - tweak: Voice analyzers in "inclusive" mode (the default mode) are now case-insensitive. + Cyberboss: + - tweak: You can no longer meatspike bots and silicons + - bugfix: Secbots will now drop the baton type they were constructed with + Dannno: + - rscadd: yeehaw.ogg is now a round end sound + Fox McCloud: + - tweak: drying meat slabs and grapes now yields a healthy non-junkfood snack + Hyena: + - rscadd: Adds paint remover to the janitors closet + Joan: + - rscadd: Clockwork Proselytizers can now convert lattices and catwalks. This has + negative gameplay benefit, but looks cool. + - rscadd: Sigils of Transmission can be accessed by clockwork structures in a larger + range. + - tweak: You can see, when examining a clockwork structure, how many sigils are + in range of it. + - rscadd: Clockwork constructs will toggle clockwork structures instead of attacking + them. + Shadowlight213: + - bugfix: Zombies will now get their claws upon zombification + Thunder12345: + - rscadd: The indestructible walls on CentComm will now smooth. + Tofa01: + - tweak: Changed alert message on early launch Authorization shuttle repeal message. + - bugfix: Makes the repeal message work and push a alert to the crew properly, also + reports every Authorization repeal now. + - bugfix: Auto Capitalisation will now work with all types of MMI chat + Ultimate-Chimera: + - rscadd: Adds a new costume crate to the cargo ordering console. + XDTM: + - rscadd: Xenobiology consoles are now buildable from circuitboards in R&D. They'll + be limited to the area they're built in plus any area with the same name. + - rscadd: Stock Exchange computers are now also buildable this way. + - rscadd: Androids now speak in a more robotic tone of voice. + - imageadd: Armblades now look a bit more bladelike. + coiax: + - rscadd: The Delta emergency shuttle now travels towards the south, rather than + the north. This changes nothing except which direction the stars rushing past + the windows are moving. + - bugfix: Fixed dragging the spawn protection traps on CTF. +2017-01-24: + CoreOverload: + - rscadd: You can now buckle handcuffed people to singularity/tesla generators, + RTGs, tesla coils and grounding rods. + Cyberboss: + - tweak: Firealarms now go off if it's too cold + - bugfix: World start will no longer lag + - bugfix: Dismembered heads will now use a mob's real name + Joan: + - rscadd: Clockwork Slabs can now focus on a specific component type to produce. + - experiment: 'Redesigned: Volt Void now allows you to fire up to 5 energy rays + at targets in view; each ray does 25 laser damage to non-Servants in the target + tile. The ray will consume power to do up to double damage, however.' + - wip: Failing to fire a Volt Void ray will damage you, though you won't die from + it unless you have access to a lot of power and are either low on health or + fail all five rays in a row. + - rscadd: The Ark of the Clockwork Justicar will gradually convert objects near + it with increasing range as it gets closer to activating. + - tweak: 'Brass windows have 20% less health, and are accordingly easier to destroy. + Fun fact: Lasers do more damage to brass windows!' + - tweak: 'Wall gears have 33% less health and are slightly faster to deconstruct. + Fun fact: You can climb over wall gears!' + - tweak: Marauders will heal more of their host's damage, on average, per life tick. + - rscadd: Clockwork Proselytizers can now repair Servant silicons and clockwork + mobs. This works in the same manner as repairing clockwork structures. + - tweak: Cogscarabs work slightly differently, and act as though the proselytizer + is a screwdriver. + Kor: + - rscadd: Megafauna will not heal while on the station. Do not be afraid to throw + your life away to get in a few toolbox hits. + Shadowlight213: + - rscdel: PAIs can no longer ventcrawl + Tofa01: + - rscadd: '[Delta Station] Adds a tracking beacon to AI MiniSat Exterior Hallway' + coiax: + - rscdel: Statues are now just incredibly tough mobs, rather than GODMODE. As a + side effect, they are no longer immune to bolts of change. + - bugfix: Fixed some issues with X (as Y) names on polymorphed mobs. +2017-01-26: + Robustin: + - tweak: Unholy Water can now be thrown or vaporized to deliver a powerful poison + unto the cult's enemies - or healing and stun resistance to its acolytes. + Tofa01: + - tweak: Moved Meta station AI MiniSat tracking beacon to AI MiniSat entrance. Should + prevent being regular teleported into space. + - bugfix: Added missing row of pixels to Flypeople torso so head connects to body + properly. + Tofa01 & XDTM: + - rscadd: Adds radio alert messages going to medical channel to the cryo tube when + a patient is fully restored. + - soundadd: Adds new alert sound for cryo tube. (cryo_warning.ogg) + XDTM: + - rscadd: Voice of God has received a few more commands. + - rscadd: You can now use job abbreviations (ex. hos > head of security) and first + names (ex. Duke > Duke Hayka) to focus targets. + coiax: + - rscadd: The nuclear operative cybernetic implant bundle now actually contains + implants. + - rscdel: The cybernetic implant bundle is no longer eligible for discounts (bundles + are, in general, not eligible). + - rscadd: Telecrystals can be purchased in stacks of five and twenty. + - rscadd: The entire stack of telecrystals are added to the uplink when charging + them. +2017-01-27: + Joan: + - tweak: Buckshot now does a maximum of 75 damage, from 90. + - tweak: The unique cyborg scriptures(Linked Vanguard, Judicial Marker) take 3 seconds + to invoke, from 4. + - tweak: Invoking Inath-neq and Invoking Nzcrentr now both take 10 seconds to invoke, + from 15. + Lzimann: + - rscadd: Now you can choose what department you want to be as security! (This may + not be completly reliable). + RemieRichards: + - rscadd: 'Emagging a sleeper now randomises the buttons, the buttons remain the + same until randomised again so you can "learn" the new button config if you''re + a masochist, Inject omnizine but realise far too late that it''s all morphine, + woops! (Note: Epinephrine can always be injected, regardless of chem levels, + this means if something !!FUN!! ends up on the Epinephrine button, it will always + be injectable!)' + Sweaterkittens: + - tweak: There are now updated names and descriptions for the items that your plasma-based + crewmembers start with and use frequently. +2017-01-28: + Joan: + - tweak: Brass windows no longer start off anchored, but are constructed instantly. + - bugfix: You can no longer stack multiple windows of the same direction on a tile. + - rscadd: Vitality Matrices now share vitality globally, allowing you to use vitality + gained from any Matrix. + - tweak: Geis now mutes human targets if there are less than 6 Servants. + - tweak: Geis no longer produces resist messages below 6 Servants; this isn't a + change, as Geis cannot be successfully resisted below 6 Servants. + - tweak: Applying Geis to an already bound target will also mute them, in addition + to preventing resistance. + RemieRichards: + - rscadd: A New weapon for clown mechs, the Oingo Boingo Punch-face! it's a giant + boxing glove that extends out on a spring and sends atoms flying (including + anchored ones and things that make no sense to move because -clowns-) + Tofa01: + - bugfix: Mop will no longer try and clean tile under janitorial cart when wetting + the mop. + - rscadd: Adds modular computers to Metastation. + - bugfix: Fixes no air in Deltastation maintenance kitchen. + - rscadd: Adds a modular computer to the CE office on Pubbystation. + Xhuis: + - rscadd: Energy-based weapons can now light cigarettes. + coiax: + - rscadd: Communication consoles now share cooldowns on announcements. + - rscadd: Cyborgs can now alter the messages of the announcement system. + - bugfix: Deadchat is now notified of any deaths on the shuttle or on Centcom. The + CTF arena does not generate death messages, due to the high levels of death. + - rscadd: The Human-level Intelligence event now occurs slightly more often, and + produces a classified message. + kevinz000: + - rscadd: Emitters and Tesla Coils now have activation wires! + - rscadd: Emitters will shoot out an emitter bolt when pulsed, regardless of it + is on. + - rscadd: Tesla coils will shoot lightning when pulsed, if it is connected to a + cable that has power. + - bugfix: Bolas no longer restrain your hands for 10 seconds when you try to remove + them and fail. +2017-01-29: + BASILMAN YOUR MAIN MAN: + - rscadd: Added a new sailor outfit to the autodrobe, now you can play sailors vs + pirates. + BlakHoleSun: + - rscadd: Added new reaction with the rainbow slime extract. Injecting a rainbow + slime extract with 5u of holy water and 5u of uranium gives you a flight potion. + Cobby: + - tweak: AI's can now be your banker by manipulating the stock machine. + Cyberboss: + - experiment: Nuclear bombs now detonate + - rscadd: You can now link additional cloning pods in the same powered area to a + single computer using a multitool. + Fox McCloud: + - bugfix: Fixes Kudzu seed gene stats not being properly altered by certain reagents + - bugfix: Fixes Kudzu vine dropped seeds not properly having gene stats set + - bugfix: Fixes glowshrooms having an invalidly high lifespan + - bugfix: Fixes explosive vines not properly chaining + Joan: + - rscadd: Clockwork Marauders now grant their host action buttons to force them + to emerge/recall and communicate with them, instead of requiring the host to + type their name or use a verb, respectively. + - rscdel: Clockwork Marauders no longer see their block and counter chances; this + was mostly useless info, as knowing the chance didn't matter as to what you'd + do. + - rscdel: Clockwork Marauders can no longer change their name. + - tweak: Clockwork Marauders have a slightly lower chance to block, and take slightly + more damage when far from their host. + - bugfix: Fixes a bug where Clockwork Marauders never suffered reduced damage and + speed at low health and never got the damage bonus at high health. + Kor: + - rscdel: Stimpacks are no longer available in the mining vendor. + Lzimann: + - rscadd: You can now change your view range as ghost. To do so, either use the + View Range verb in the ghost tab, the mouse scroll up/down or control + "+"/"-". + The verb also works as a reset if you changed your view. + Sogui: + - tweak: There are now 2 less traitors in the double agent mode + - tweak: All security (and captain) suit sensors are set to max by default + Supermichael777: + - tweak: The wooden chair with wings is now craft-able. -1 non reconstruct-able + map object + - rscadd: Added the Tiki mask, you can make it in wood's crafting menu. + - imageadd: Ported Tiki mask's sprites from Hippie station. It is under the same + Creative Commons 3.0 BY-SA as the rest of our sprites. They are from Nienhaus. + Tofa01: + - rscadd: Adds a camera network onto the Omega Station. + - imageadd: Added new sprite for the AI Slipper. + XDTM: + - tweak: Implanting chainsaws is now a prosthetic replacement instead of its own + surgery. + - rscadd: You can now implant synthetic armblades (from an emagged limb grower) + into people's arms to use it at its full potential. + - rscdel: Chainsaw removal surgery has been removed as well; you'll have to sever + the limb and get a new one. + Xhuis: + - rscadd: AI control beacons are a new item created from the exosuit fabricator. + When installed into a mech, it allows AIs to jump to and from that mech freely. + Note that malfunctioning AIs with the domination power unlocked will instead + be forced to dominate the mech. + - tweak: Some timed actions are no longer interrupted while drifting through space. + - rscadd: Riot foam darts can now be constructed from a hacked autolathe. + bgobandit: + - rscadd: The library computer can now upload scanned books to the newscaster. Remember, + seditious or unsavory news channels should receive a Nanotrasen D-Notice! + - rscadd: The library computer can now print corporate posters as well as Bibles. + - rscdel: Cargo no longer offers a corporate poster crate. Nobody ever bought it + anyway. + coiax: + - rscadd: The Librarian now starts with a chisel/soapstone/chalk/magic marker capable + of engraving messages for subsequent shifts, and permanently erasing messages + that the Librarian is unhappy with. It has limited uses, so order more at Cargo. + - bugfix: The contraband cream pie crate is now locked, and requires Theatre access. + - rscadd: Any silicons created by bolts of change have no laws. + - rscadd: Cyborgs are immune to polymorph while changing module. + - rscadd: Adds Romerol to the traitor uplink for 25 TC. (This means you need a discount, + or to work with another traitor to afford it). Romerol is a highly experimental + bioterror agent which silently create dormant nodules to be etched into the + grey matter of the brain. On death, these nodules take control of the dead body, + causing limited revivification, along with slurred speech, aggression, and the + ability to infect others with this agent. + - rscdel: Zombie infections are no longer visible on MediHUD. + - rscdel: Zombies no longer tear open airlocks, since they can just smash them open + just as fast. + - rscdel: Zombies are no longer TOXINLOVING. + - rscadd: EMPs may cause random wires to be pulsed. Please ensure that sensitive + equipment avoids exposure to heavy electromagnetic pulses. + jughu: + - tweak: Changes some cargo export prices + ma44: + - tweak: Nanotrasen has improved training of the crew, teaching crewmembers like + you to unscrew the top off the bottle and pour it into containers like beakers. + vcordie: + - bugfix: Loads the HADES carbine with the correct bullet. + - tweak: The SRM-8 Rocket Pods have been loaded with new explosives designed to + do maximum damage to terrain. These explosives are less effective on people, + however. +2017-01-30: + BASILMAN YOUR MAIN MAN: + - rscadd: Added BM SPEEDWAGON THE BEST (AND ONLY) SPACE CAR ON THE MARKET. + CoreOverload: + - tweak: Clicking item slot now clicks the item in it. + Cyberboss: + - bugfix: Judicial visors now recharge properly + - bugfix: Gluon grenades now properly freeze turfs + - bugfix: Revs are now properly jobbanned + Fox McCloud: + - tweak: Plant analyzers will now display plant traits + - tweak: Plant analyzers will now display all of a grown's genetic reagents + Joan: + - rscdel: Cutting off legs no longer stuns. + - tweak: Volt Void now only allows you to fire 4 volt rays instead of 5, and the + damage of each ray has been reduced to 20, from 25. + - rscdel: Cyborgs using Volt Void now take damage if they fail to fire. + - experiment: 'Clockwork scripture can no longer require more components than it + consumes: This means that most scriptures ""cost"" one less component.' + MrStonedOne: + - rscadd: Because of abuse, actions on interfaces are throttled. Some bursting is + allowed. You will get a message if an action is ignored. Server operators can + configure this in config.dm + Tofa01: + - bugfix: '[Delta] Fixes area names for Deltastation' + - bugfix: '[Delta] Fixes custodial closet being cold all the time on Deltastation' + bgobandit: + - rscadd: Nanotrasen supports the arts. We now offer picture frames! + coiax: + - rscdel: The Syndicate "Uplink Implant" now has no TC precharged. You can charge + it with the use of physical telecrystals. The price has been reduced from 14TC + to 4TC accordingly. (The uplink implant in the implant bundle still has 10TC). + - rscadd: Syndicate bombs and nuclear devices now have a minimum timer of 90 seconds. + - rscadd: Camoflaged HUDs given to head revolutionaries now function the same as + chameleon glasses in the chameleon kit bundle, giving them an action button + and far more disguise options. + - rscadd: Syndicate thermals are also now more like chameleon glasses as well. + - rscadd: You can regain a use of a soapstone by erasing one of your own messages. + (This means you can remove a message if you don't like the colour and want to + try rephrasing it to get a better colour). Erasing someone else's message still + uses a charge. + - bugfix: Fixes bugs where you'd spend a charge without engraving anything. + - bugfix: Fixes a bug where the wrong ckey was entered in the engraving, you won't + be able to take advantage of the "recharging" on messages made before this change. +2017-01-31: + Cyberboss: + - tweak: The cyborg hugging module can no longer self target + Joan: + - tweak: Changed what scriptures and tools Servant cyborgs get; a full list can + be found on the clockwork cult wiki page. + RemieRichards: + - rscadd: Added the ability to choose where your uplink spawns, choose between the + classic PDA, the "woops you don't actually have a PDA" fallback Radio uplink + and the brand new Pen uplink! diff --git a/html/changelogs/archive/2017-02.yml b/html/changelogs/archive/2017-02.yml new file mode 100644 index 0000000000..0834dac09b --- /dev/null +++ b/html/changelogs/archive/2017-02.yml @@ -0,0 +1,668 @@ +2017-02-01: + Cyberboss: + - bugfix: AI integrity restorer computer now respects power usage + - bugfix: Progress bars will now stack vertically instead of on top of each other + - bugfix: Progress bars will no longer be affected by lighting + Xhuis: + - rscadd: You can now fold up bluespace body bags with creatures or objects inside. + You can't fold them up if too many things are inside, but anything you fold + up in can be carried around in the object and redeployed at any time. +2017-02-03: + Cobby: + - rscadd: Ghosts will now be informed when an event has been triggered by our lovely + RNG system. + Cyberboss: + - tweak: Firedoors will eventually reseal themselves if left open during a fire + alarm + Joan: + - tweak: Clockwork Marauders have 25% less health, 300 health from 400. + - wip: The Vitality Matrix scripture is now a Script, from an Application. Its cost + has been accordingly adjusted. + - tweak: Vitality Matrices will be consumed upon successfully reviving a Servant. + They also drain and heal conscious targets slightly slower. + - wip: The Fellowship Armory scripture is now an Application, from a Script. Its + cost has been accordingly adjusted. + - tweak: Fellowship Armory now affects all Servants in view of the invoker, and + will replace weaker gear and armor with its Ratvarian armor. Also, clockwork + treads now allow you to move in no gravity like magboots. + - rscdel: Mania Motors no longer instantly convert people next to them. + - rscadd: Instead, you have to remain next to them for several seconds, after which + you will be knocked out, then converted if possible. + - tweak: Mania Motors now cost slightly less power to run. + Jordie0608: + - tweak: Admin notes, memos and watchlist entries now use a generalized system, + they can all be accessed from the former notes browser. + - rscadd: Added to this are messages, which allow admins to leave a message for + players that is delivered to them when they next connect. + Lexorion: + - tweak: Laser projectiles have a new sprite! They also have a new effect when they + hit a wall. + Sweaterkittens and Joan: + - rscadd: Ocular Wardens will now provide auditory feedback when they acquire targets + and deal damage. + - soundadd: adds ocularwarden-target.ogg, ocularwarden-dot1.ogg and ocularwarden-dot2.ogg + to the game sound files. + Tofa01: + - bugfix: '[Delta] Allows Station Engineers to access Delta Atmospherics Solar Panel + Array Room.' + - rscadd: '[Omega] Adds a Massdriver room to chapel on Omegastation.' + bgobandit: + - rscadd: All art storage facilities offer construction paper now! + coiax: + - rscadd: A victim of a transformation disease will retain their name. + - tweak: The slime transformation disease can turn you into any colour or age of + slime. + - rscadd: The Abductor event can now happen at any time, rather than thirty (30) + minute plus rounds. +2017-02-04: + Cyberboss: + - bugfix: Modular computers now explode properly + - bugfix: Emagged holograms can no longer be exported for credits + - bugfix: Abstract entities no longer feed the singularity + - tweak: Machine frames will no longer be anchored when created + Joan: + - rscadd: Vanguard now shows you how long you have until it deactivates. + Kor: + - rscadd: 'By combing two flashlights and cable coil, you can create a new eye implant: + flashlight eyes. People with flashlights for eyes can not see, but they will + provide an enormous amount of light to their friends.' + - rscadd: Valentines day will now randomly pair up crew members on dates. The paired + crewmembers will get an objective to protect each other at all costs. + Steelpoint: + - rscadd: Addition of two security DragNETs to Deltastations, Omegastations and + Metastations armouries. + Tofa01: + - rscadd: '[Delta] Removes space money from gold crate replaces with 3 Gold Bars + Gold Wrestling belt is still there.' + - rscadd: '[Delta] Removes space money from silver crate replaces with 5 Silver + Coins.' + - bugfix: Fixes incorrect placement of RD modular computer on Metastation. + WhiteHusky: + - rscadd: Fields are supported when printing with a modular computer + - rscadd: PRINTER_FONT is now a variable + - rscdel: Removed the [logo] tag on Modular computers as the logo no longer exists + - tweak: New lines on paper are parsed properly + - tweak: '[tab] is now four non-breaking spaces on papers' + - tweak: Papers have an additional proc, reload_fields, to allow fields made programmatically + to be used + - tweak: 'stripped_input stripped_multiline_input has a new argument: no_trim' + - bugfix: Modular computers no longer spew HTML when looking at a file, rather it + is unescaped like it should + - bugfix: Modular computers no longer show escaped HTML entities when editing + - bugfix: Modular computers can now propperly read and write from external media + - bugfix: Modular computers' file browser lists files correctly + - spellcheck: NTOS File Manager had a spelling mistake; Manage instead of Manager + coiax: + - bugfix: Engraved messages can no longer be moved by a gravitational singularity. + - tweak: The deadchat notification of randomly triggered events now uses the deadsay + span. + - rscdel: The wizard spell "Rod Form" does not produce a message in deadchat everytime + it is used. +2017-02-05: + Cyberboss: + - bugfix: Shuttle docking/round end shouldn't lag as much + - rscadd: There's a new round end sound! + Hyena: + - bugfix: The bible now contains 1 whiskey + Joan: + - rscadd: Ratvar-converted AIs become brass-colored, speak in Ratvarian, and cannot + be carded. + Kor: + - rscadd: Eyes are now organs. You can remove or implant them into peoples heads + with organ manipulation surgery. A mob without eyes will obviously have trouble + seeing. + - rscadd: All special eye powers are now tied to their respective organs. For example, + this means you can harvest an alien or shadow persons eyes, have them implanted, + and gain toggle-able night vision. + - rscadd: All cybernetic eye implants are now cybernetic eyes, meaning you must + replace the patients organic eyes. HUD implants are still just regular implants. + Lzimann: + - rscadd: Tesla zaps can now generate an energy ball if they zap a tesla generator! + Sweaterkittens: + - rscadd: The station's Plasmamen have been issued a new production of envirosuits. + The most notable change aside from small aesthetic differences is the addition + of an integrated helmet light. + - tweak: Tweaked a few of the Plasma Envirosuit sprites to be more fitting thematically. + Swindly: + - bugfix: Saline-glucose solution can no longer decrease blood volume + - rscadd: Cyborg hyposprays can now dispense saline-glucose solution + - rscadd: Saline-glucose solution now increases blood volume when it heals + coiax: + - bugfix: The mulligan reagent can now be created with 1u stable mutation toxin + + 1u unstable mutagen. + - rscdel: Tesla balls cannot dust people near grounding rods. + - rscadd: Soapstones/chisel/magic markers/chalk can remove messages for free. Removing + one of your own messages still grants a use. + - rscadd: The Janitor starts with a dull soapstone for removing unwanted messages. + xmikey555: + - tweak: The tesla engine no longer destroys energy ball generators. +2017-02-06: + Xhuis: + - rscadd: Traitor janitors can now order EZ-clean grenades for 6 telecrystals per + bundle. They function like normal cleaning grenades with an added "oh god my + face is melting" effect, and can also be found in surplus crates. +2017-02-07: + Cyberboss: + - bugfix: Wire, atmos, and disposal networks no longer work across hyperspace when + on the border of a shuttle + - bugfix: Implants that work on death will now work for simple_animals + - bugfix: The target moving while being implanted will no longer continue the implant + - bugfix: Implanters now show progress bars as they were intended to + - bugfix: Pipe painters are no longer aggressive + - bugfix: Carding the AI will now stop a doomsday device + - rscadd: The job subsystem now loads instantly. No more waiting to set your occupation + prefs! + - bugfix: The rare case of duping your inventory at roundstart has been fixed + - bugfix: Self deleting stackable items are fixed + Dannno: + - tweak: We've switched to a new brand of colored jumpsuit. + JJRcop: + - tweak: Adds 4% chance when assigning a valentines day date to also assign someone + else to the same date, but your date will still have you as their only date. + Poojawa: + - bugfix: '[Delta] Active turfs down from 300+' + - bugfix: '[Delta] Janitor closet isn''t 2.7K anymore' + - bugfix: '[Delta] Various pipe fixes' + RemieRichards: + - rscadd: Added a new checmial, Skewium, it's produced by mixing rotatium, plasma + and sulphuric acid in the ratio 2:2:1, which results in 5 Skewium. + Swindly: + - bugfix: Robotic eyes can no longer be eaten + Tofa01: + - bugfix: Fixes grammar issue when changing someones appearance via plastic surgery. + - tweak: '[OmegaStation] Allows Chaplain job to be selectable.' + - bugfix: '[Omega] Fixes Overpressurization In Mass Driver Room' + Xhuis: + - rscadd: Traitor clowns can now buy a reverse revolver. I'll leave it up to you + to guess what it does. Honk. + iamthedigitalme: + - imageadd: Legion has a new, animated sprite. + kevinz000: + - rscadd: 'ADMINS: SDQL2 has been given some new features!' + - bugfix: SDQL2 now gives you an exception on runtime instead of flooding server + runtime logs. + - rscadd: SDQL2 now supports usr, which makes that variable reference to whatever + mob you are in, src, which targets the object it is being called on itself, + and marked, which targets the datum marked by the admin calling it. Also, it + supports hex references (the hex number at the top of a VV panel) in {}s, so + you can target nearly anything! Also, global procs are supported by global.[procname](args), + for CALL queries. + - bugfix: SDQL2 can no longer edit /datum/admins or /datum/admin_rank, and is protected + from changing x/y/z of a turf and anything that would cause broken movement + for movable atoms. + - rscadd: SDQL2 can now get list input with [arg1, arg2]! + - experiment: Do '""' to put strings inside of SDQL2 or it won't work. +2017-02-09: + Cyberboss: + - bugfix: Certain firedoors that should have closed during an alarm now actually + close + - soundadd: You can now knock on firedoors + - bugfix: Supermatter in a closet/crate will now properly fee the singulo + - bugfix: Paper planes can be unfolded again + - bugfix: Paper planes can be stamped properly + Joan: + - tweak: Impaling someone with a sharp item by pulling them with a changeling Tentacle + now does significantly less damage and stuns for less time. + Jordie0608: + - rscadd: Admins can now filter watchlist entries to only users who are connected. + - tweak: Messages no longer delete themselves when sent. + Kor: + - rscadd: The limb grower has been replaced with a box of surplus limbs. Visit robotics + or harvest limbs from another person if you want quality. + Reeeeimstupid: + - rscadd: Silly Abductee objectives. Try not to go crazy trading life stories with + Lord Singulo. + Tofa01: + - tweak: Removes virology access to jobs including Medical Doctor, Geneticist and + Chemist. + - tweak: '[Delta] Changes NW supermatter filter to filter O2 instead of N2' + - rscadd: '[Delta] Adds wardrobes to Dorms & Arrivals Shuttle' + - rscadd: '[Delta] Adds access buttons to virology doors for extra security' + - rscadd: '[Delta] Adds bolt door button to all dorms' + - rscadd: '[Delta] Adds three pairs of optical meson scanners to supermatter room' + - rscadd: '[Delta] Adds a disk fridge to botany' + - rscadd: '[Delta] Adds a cake hat to the bar' + - bugfix: '[Delta] Fixes misplaced station intercom in Supermatter SMES room' + XDTM: + - rscadd: A Law Removal module can be build in RnD. It can remove a specified core + or freeform law. + - tweak: 'When stating laws, silicons won''t skip a number when hiding laws. (example: + 1. Law 1; 2. Law 2; 3. Law 4 if you choose not to state Law 3)' + Xhuis: + - rscadd: Artistic toolboxes now spawn in maintenance and possess various supplies + for wire art and crayon art. + - rscadd: Traitors can now obtain His Grace. Chaplains can buy it for 20 TC, or + it can be found in a surplus crate. + - rscadd: Soapstone messages can now be rated! Attack the message with your hand + to rate it positive or negative. Anyone can see the rating, and you cannot rate + a message more than once, even across rounds. + - rscdel: Soapstones no longer have a write time. + - tweak: Soapstones now have a fixed vocabulary to write messages with. + chanoc1: + - tweak: The salt and pepper shakers have new sprites. + coiax: + - rscadd: Added metal rods and floor tiles to Standard cyborgs. + - rscadd: Added a remote signaling device to Engineering cyborg. + - rscadd: Adds a 'Guardian of Balance' lawset and AI module, currently admin spawn + only. + uraniummeltdown: + - tweak: Kinetic Accelerator Cosmetic and Tracer Modkits now don't use mod capacity. + Cosmetic kits change the name of the KA. +2017-02-10: + Ausops: + - rscadd: Air tanks and plasma tanks have been resprited. + ChemicalRascal: + - tweak: Pen is able to wind up ruined tapes. + CoreOverload: + - rscadd: You can now emag the escape pods to launch them under any alert code. + - tweak: Shuttle name is no longer displayed on "Status" panel. Instead, you can + now examine a status screen to see it. + Cyberboss: + - bugfix: Simple animals now deathgasp properly again + - bugfix: Testmerged PRs will no longer duplicate in the list + - bugfix: Pods and shuttles now have air again + Joan: + - experiment: Clockwork Cults must always construct and activate the Ark. + - imageadd: Updates air tank inhands to match Ausops' new sprites. + Mekhi Anderson: + - rscadd: All mobs can now *spin! + - rscadd: Cyborgs now have handholds. This means you can ride around on them, but + if you get stunned or hit, you fall off! The cyborg can also throw you off by + spinning. + Tofa01: + - soundadd: Changes fire alarm to make new sound FireAlarm.ogg + Xhuis: + - rscdel: The Syndicate will no longer prank their operatives by including reverse + revolvers in surplus crates. + coiax: + - rscadd: A reverse revolver now comes in a box of hugs. + - rscadd: 'Added a new admin only event: Station-wide Human-level Intelligence. + Like the random animal intelligence event, but affecting as many animals as + there are ghosties.' + - rscadd: The Luxury Shuttle grabs cash in your wallet and backpack, and shares + approval between the entrance gates. + - rscadd: The NES Port shuttle now costs 500 credits. +2017-02-11: + Dannno: + - tweak: hahaha I switched your toolboxes you MORONS + Kor: + - rscadd: Killing bubblegum now unlocks a new shuttle for purchase. + Lzimann: + - tweak: Hardsuit built-in jetpacks no longer have a speed boost. + Pyko: + - bugfix: Fixed legit posters and map editing official/serial number for poster + decals. + Tofa01: + - bugfix: '[Delta] Fixes doors walls and windows being incorrectly placed due to + mapmerge issues.' + - bugfix: '[Box] Fixes access levels for HOP shutters.' +2017-02-12: + AnturK: + - rscadd: Added Poison Pen to uplink. + Drunk Musicians: + - rscadd: Drunk music + Gun Hog: + - rscadd: Nanotrasen Engineering has devised a construction console to assist with + building the Auxiliary Mining Base, usually located near a station's Arrivals + hallway. A breakthrough in bluespace technology, this console employs an advanced + internal Rapid Construction Device linked to a camera-assisted holocrane for + rapid, remote construction! + Lzimann: + - bugfix: MMIs/posibrains works with mechas again + RandomMarine: + - rscadd: The Russians have expanded to the shuttle business. A new escape shuttle + is available for purchase. + Sweaterkittens: + - tweak: Plasmamen burn damage multiplier reduced to 1.5x from 2x + coiax: + - rscdel: Removes the STV5 shuttle from purchase. + - rscadd: Swarmers no longer consume the deep fryer, since they have too much respect + for the potential fried foods it can produce. + - rscadd: The clown's survival/internals box is now a box of hugs. Dawww. +2017-02-13: + ChemicalRascal: + - tweak: Delta station brig cell chairs have been replaced with beds. One bed per + cell, no funny business. + Cyberboss: + - bugfix: Simple animals that are deleted when killed will now deathrattle + - bugfix: Fixed Alt-click stack duplication + Joan: + - imageadd: Updated the back and belt sprites for airtanks to match the new sprites. + Kor: + - rscadd: Mobile pAIs are now slower than humans. + Swindly: + - rscadd: Added Nuka Cola as a premium item in Robust Softdrinks + Tofa01: + - bugfix: '[Delta] Fixes double windoor on chemistry windows.' + - tweak: Lowered volume of fire alarm sound also makes it more quiet. + coiax: + - rscadd: Added an admin only tool, the life candle. Touch the candle, and when + you die, you'll respawn shortly afterwards. Touch it again to stop. Used for + testing, thunderdome brawls and good old fashioned memery. + - bugfix: Fried foods no longer shrink to miniature size. +2017-02-14: + Cyberboss: + - bugfix: Fixed unequipping items while stunned + - bugfix: Fixed various things deleting when unequipped + - bugfix: Fixed tablet ID slots deleting cards + - bugfix: Fixed water mister nozzle getting stuck in hands + - tweak: Title music now starts immediately upon login + - tweak: You can no longer sharpen energy weapons + Joan: + - tweak: Mania Motors are overall less effective and only affect people who can + see the motor. + - tweak: Mania Motors have slightly more health; 100, from 80. + MrStonedOne: + - tweak: Station time is now always visible in the status tab. + - tweak: Both server time and station time now displays seconds so you can actively + see how game time (ByondTime[tm]) is progressing along side real time. + - rscadd: Added a time dilation tracker, this allows you to better understand how + time will progress in game. It shows the time dilation percent for the last + minute as well as some rolling averages. + RandomMarine: + - tweak: Pre-made charcoal pills now contain 10 units instead of 50. The amount + of pills inside of toxin first aid kits and the smartfridge have been increased + to compensate. Keep in mind that each ten unit pill recovers 100 points of toxin + damage and purges 50 units of other reagents. + Steelpoint: + - tweak: All Drones now have a walking animation. + Tofa01: + - bugfix: '[Delta] Fixes space cleaner being empty in brig medbay' + - bugfix: '[Delta] Fixes some areas that are not radiation proof' + - bugfix: '[Meta] Fixes Atmospherics Freezer Spawning As A Heater' + uraniummeltdown: + - rscadd: Window Flashing is now a preference + - rscadd: Your game window will flash when alerted as a ghost. This includes being + revived by defibs/cloning and events such as borers, swarmers, revenant, etc. +2017-02-16: + Cyberboss: + - rscadd: Test merged PRs are now more detailed + Steelpoint: + - rscadd: The Head of Security's Hardsuit is now equipped with a inbuilt Jetpack. + coiax: + - rscadd: The Hyperfractal Gigashuttle is now purchasable for 100,000 credits. Help + Centcom by testing this very safe and efficient shuttle design. (Terms and conditions + apply.) + - rscadd: The changeling power "Anatomic Panacea" now causes the changeling to vomit + out zombie infections, along with headslugs and xeno infections, as before. + - bugfix: The main CTF laser gun disappears when dropped on the floor. +2017-02-17: + Arianya: + - tweak: The Labour Camp rivet wall has been removed! + - spellcheck: Fixed some typos in Prison Ofitser's description. + Cobby: + - experiment: Flashes have been rebalanced to be more powerful + Cyberboss: + - bugfix: Rack construction progress bars will no longer be spammed + - tweak: The round start timer will count down during subsystem initialization + - tweak: Total subsystem initialization time will now be displayed + Joan: + - rscdel: His Grace no longer globally announces when He is awakened or falls to + sleep. + - rscdel: His Grace is not a toolbox, even if He looks like one. + - experiment: His Grace no longer requires organs to awaken. + - tweak: His Grace now gains 4 force for each victim consumed, always provides stun + immunity, and will, generally, take longer to consume His owner. + - experiment: His Grace must be destroyed to free the bodies within Him. + - experiment: Dropping His Grace while He is awake will cause you to suffer His + Wrath until you hold Him again. + - rscadd: His Grace becomes highly aggressive after consuming His owner, and will + hunt His own prey. + - experiment: The Ark of the Clockwork Justicar now only costs 3 of each component + to summon, but must consume an additional 7 of each component before it will + activate and start counting down. + - rscadd: The presence of the Ark will be immediately announced, though the location + will still only be announced after it has been active and counting down for + 2 minutes. + - tweak: The Ark also requires an additional invoker to invoke. + Lobachevskiy: + - bugfix: Fixed glass shards affecting buckled and flying mobs + MrStonedOne: + - experiment: The game will now force hardware rendering on for all clients. + Nienhaus: + - rscadd: Drying racks have new sprites. + Swindly: + - rscadd: Trays can now be used to insert food into food processors + Thunder12345: + - bugfix: It's ACTUALLY possible to pat people on the head now + WJohn: + - imageadd: Improved blueshift sprites, courtesy of Nienhaus. + XDTM: + - rscadd: Bluespace Crystals are now a material that can be inserted in Protolathes + and Circuit Printers. Some items now require Bluespace Mesh. + - rscadd: Bluespace Crystal can now be ground in a reagent grinder to gain bluespace + dust. It has no uses, but it teleports people if splashed on them, and if ingested + it will occasionally cause teleportation. + coiax: + - rscadd: Engraved messages now have a UI, which any player, living or dead can + access. See when the message was engraved, and upvote or downvote accordingly. + - rscadd: Admins have additional options with the UI, seeing the player ckey, original + character name, and the ability to outright delete messages at the press of + a button. + kevinz000: + - bugfix: Flightsuits actually fly over people + - bugfix: Flightsuits don't interrupt pulls when you pass through doors +2017-02-18: + Cyberboss: + - imageadd: New round end animation. Inspired by @Iamgoofball + Gun Hog: + - rscadd: The Aux Base console now controls turrets made by the construction console. + - rscadd: The Aux Base may now be dropped at a random location if miners fail to + use the landing remote. + - rscadd: The mining shuttle may now dock at the Aux Base's spot once the base is + dropped. + - tweak: Removed access levels on the mining shuttle so it can be used at the public + dock. + - tweak: The Aux Base's turrets now fire through glass. Reminder that the turrets + need to be installed outside the base for full damage. + - rscadd: Added a base construction console to Delta Station. + Mysterious Basilman: + - rscadd: More powerful toolboxes are active in this world... + Scoop: + - tweak: Condimasters now correctly drop their items in front of their sprite. + Tofa01: + - bugfix: Re-Arranges And Extends Pubby Escape Hallway To Allow Larger Shuttle To + Dock + - bugfix: '[Meta] Fixes top left grounding rod from being destroyed by the Tesla + engine.' + TrustyGun: + - rscadd: Traitor mimes can now learn two new spells for 15 tc. + - rscadd: The first, Invisible Blockade, creates a 3x1 invisible wall. + - rscadd: The second, Finger Guns, allows them to shoot bullets out of their fingers. + kevinz000: + - rscadd: You can now ride piggyback on other human beings, as a human being! To + do so they must grab you aggressively and you must climb on without outside + assistance without being restrained or incapacitated in any manner. They must + also not be restrained or incapacitated in any manner. + - rscadd: If someone is riding on you and you want them to get off, disarm them + to instantly floor them for a few seconds! It's pretty rude, though. + rock: + - soundadd: you can now harmlessly slap somebody by aiming for the mouth on disarm + intent. + - soundadd: you can only slap somebody who is unarmed on help intent, restrained, + or ready to slap you. +2017-02-19: + Basilman: + - rscadd: some toolboxes, very rarely, have more than one latch + Joan: + - rscadd: You can now put components, and deposit components from slabs, directly + into the Ark of the Clockwork Justicar provided it actually requires components. + - experiment: Taunting Tirade now leaves a confusing and weakening trail instead + of confusing and weakening everyone in view. + - tweak: Invoking Inath-neq/Nzcrentr is now 33% cheaper and has a 33% lower cooldown. + Tofa01: + - rscdel: '[Delta] Removes SSU From Mining Equipment Room' + - tweak: Changes centcomm ferry to require centcomm general access instead of admin + permission. + coiax: + - rscadd: Nuke ops syndicate cyborgs have been split into two seperate uplink items. + Medical cyborgs now cost 35 TC, assault cyborgs now cost 65 TC. + grimreaperx15: + - tweak: Blood Cult Pylons will now rapidly regenerate any nearby cultists blood, + in addition to the normal healing they do. + ma44: + - tweak: Intercepted messages from a lavaland syndicate base reveals they have additional + grenade and other miscellaneous equipment. + uraniummeltdown: + - rscadd: Shuttle engines have new sprites. +2017-02-20: + Cyberboss: + - bugfix: The frequncy fire alarms play at is now consistent + MrStonedOne: + - tweak: bluespace ore cap changed from 100 ores to 500 + Tofa01: + - tweak: '[Meta] Replaces orange jumpsuit in holding cell with prisoner jumpsuits' + XDTM: + - tweak: Repairing someone else's robotic limb is instant. Repairing your own robotic + limbs will still take time. + - tweak: Repairing limbs with cable or welding will now heal more. + Xhuis: + - bugfix: Medipens are no longer reusable. +2017-02-21: + Cyberboss: + - bugfix: You can now unshunt as a malfunctioning AI again + Kor: + - bugfix: You will now retain your facing when getting pushed by another mob. + Tofa01: + - bugfix: '[Z2] Fixed Centcomm shutters to have proper access levels for inspectors + and other Admin given roles' + coiax: + - rscadd: Refactors heart attack code, a cardiac arrest will knock someone unconscious + and kill them very quickly. + - rscadd: Adds corazone, an anti-heart attack drug, made by mixing 2 parts Phenol, + 1 part Lithium. A person with corazone in their system will not suffer any negative + effects from missing a heart. Use it during surgery. + - rscadd: Abductor glands are now hearts, the abductor operation table now automatically + injects corazone to prevent deaths during surgery. The gland will restart if + it stops beating. + - bugfix: Cloning pods always know the name of the person they are cloning. + - rscadd: You can swipe a medical ID card to eject someone from the cloning pod + early. The cloning pod will announce this over the radio. + - rscdel: Fresh clones have no organs or limbs, they gain them during the cloning + process. Ejecting a clone too early is not recommended. Power loss will also + eject a clone as before. + - rscdel: An ejected clone will take damage from being at critical health very quickly + upon ejection, rather than before, where a clone could be stable in critical + for up to two minutes. + - rscadd: Occupants of cloning pods do not interact with the air outside the pod. + uraniummeltdown: + - bugfix: All shuttle engines should now be facing the right way +2017-02-22: + AnonymousNow: + - rscadd: Added Medical HUD Sunglasses. Not currently available on-station, unless + you can convince Centcom to send you a pair. + Cyberboss: + - bugfix: Spawning to the station should now be a less hitchy experience + MrPerson: + - experiment: 'Ion storms have several new additions:' + - rscadd: 25% chance to flatly replace the AI's core lawset with something random + in the config. Suddenly the AI is Corporate, deal w/ it. + - rscadd: 10% chance to delete one of the AI's core or supplied laws. Hope you treated + the AI well without its precious law 1 to protect your sorry ass. + - rscadd: 10% chance that, instead of adding a random law, it will instead replace + one of the AI's existing core or supplied laws with the ion law. Otherwise, + it adds the generated law as normal. There's still a 100% chance of getting + a generated ion law. + - rscadd: 10% chance afterwards to shuffle all the AI's laws. + TalkingCactus: + - bugfix: New characters will now have their backpack preference correctly set to + "Department Backpack". + Tofa01: + - bugfix: '[Delta] Fixes missing R&D shutter near public autolathe' + Xhuis: + - tweak: Highlanders can no longer hide behind chairs and plants. + - tweak: Highlanders no longer bleed and are no longer slowed down by damage. +2017-02-23: + Cyberboss: + - bugfix: Fixed a bug where the fire overlay wasn't getting removed from objects + - bugfix: The graphical delays with characters at roundstart are gone + - bugfix: The crew manifest is working again + - rscadd: Admins can now asay with ":p" and dsay with ":d" + Dannno: + - imageadd: Robust Softdrinks LLC. has sent out new vendies to the stendy. + Joan: + - rscdel: Off-station and carded AIs no longer prevent Judgement scripture from + unlocking. + Nienhaus: + - tweak: Updates ammo sprites to the new perspective. + Tofa01: + - bugfix: Disables sound/frequency variance on cryo tube alert sound + coiax: + - rscadd: Nanotrasen reminds its employees that they have ALWAYS been able to taste. + Anyone claiming that they've recently only just gained the ability to taste + are probably Syndicate agents. +2017-02-24: + MrStonedOne: + - rscdel: Limit on Mining Satchel of Holding Removed + - tweak: Dumping/mass pickup/mass transfer of items is now lag checked + - rscadd: Dumping/mass pickup/mass transfer of items has a progress bar +2017-02-25: + AnonymousNow: + - rscadd: Nerd Co. has sent pairs of thicker prescription glasses out to Nanotrasen + stations, for your local geek to wear. + Basilman: + - rscadd: New box sprites + Robustin: + - tweak: Hulks can no longer use pneumatic cannons or flamethrowers + Tofa01: + - rscadd: '[All Maps] The new and improved Centcom transportation ferry version + 2.0 is out now!' + coiax: + - rscadd: Cargo can now order plastic sheets to make plastic flaps. No doubt other + uses for plastic will be discovered in the future. + - rscadd: To deconstruct plastic flaps, unscrew from the floor, then cut apart with + wirecutters. Plastic flaps have examine tips like reinforced walls. + uraniummeltdown: + - rscadd: Science crates now have new sprites +2017-02-26: + Ausops: + - imageadd: New sprites for water, fuel and hydroponics tanks. + Joan: + - experiment: 'Clockwork objects are overall easier to deconstruct:' + - wip: Clockwork Walls now take 33% less time to slice through, Brass Windows now + work like non-reinforced windows, and Pinion Airlocks now have less health and + only two steps to decon(wrench, then crowbar). + - rscadd: EMPing Pinion Airlocks and Brass Windoors now has a high chance to open + them and will not shock or bolt them. + - rscadd: Anima fragments will very gradually self-repair. + Tofa01: + - bugfix: '[Omega] Fixes ORM input and output directions' + - bugfix: Fixes space bar kitchen freezer access level + - bugfix: Fixes giving IDs proper access for players who spawn on a ruin via a player + sleeper/spawners + - bugfix: '[Delta] Fixes varedited tiles causing tiles to appear as if they have + no texture' + - bugfix: Fixes robotic limb repair grammar issue +2017-02-27: + Kor, Jordie0608 and Tokiko1: + - rscadd: Singularity containment has been replaced on box, meta, and delta with + a supermatter room. The supermatter gives ample warning when melting down, so + hopefully we'll see fewer 15 minute rounds ended by a loose singularity. + - rscadd: Supermatter crystals now collapse into singularities when they fail, rather + than explode. + Tofa01: + - bugfix: Stops AI And Borgs From Interfacing With Ferry Console + TrustyGun: + - imageadd: Box sprites are improved. + WJohnston: + - imageadd: New and improved BRPED beam. The old one was hideous. + coiax: + - rscadd: Drone shells are now points of interest in the orbit list. + - rscadd: Derelict drone shells now spawn with appropriate headgear. +2017-02-28: + Cyberboss: + - tweak: You will no longer be shown empty memories when the game starts + - bugfix: Built APCs now work again + - bugfix: Borg AI cameras now work again + Joan: + - rscadd: Anima Fragments now slam into non-Servants when bumping. This will ONLY + happen if the fragment is not slowed, and slamming into someone will slightly + damage the fragment and slow it severely. + Lzimann: + - tweak: Communications console can also check the ID the user is wearing. + Supermichael777: + - tweak: The button now has a five second delay when detonating bombs + XDTM: + - rscadd: You can now change the input/output directons for Ore Redemption Machines + by using a multitool on them with the panel open. + - rscadd: Diagnostic HUDs can now see if airlocks are shocked. diff --git a/html/changelogs/archive/2017-03.yml b/html/changelogs/archive/2017-03.yml new file mode 100644 index 0000000000..cacd069bab --- /dev/null +++ b/html/changelogs/archive/2017-03.yml @@ -0,0 +1,563 @@ +2017-03-01: + Cyberboss: + - bugfix: Lobby music is no longer delayed +2017-03-02: + Gun Hog: + - tweak: Advanced camera, Slime Management, and Base Construction consoles may now + be operated by drones and cyborgs. + Robustin: + - rscadd: The syndicate power beacon will now announce the distance and direction + of any engines every 10 seconds. + Steelpoint: + - rscadd: Robotics and Mech Bay have seen a mapping overhaul on Boxstation. + - rscadd: A cautery surgical tool has been added to the Robotics surgical area on + Boxstation. + XDTM: + - tweak: Hallucinations have been modified to increase the creepiness factor and + reduce the boring factor. + - rscadd: Added some new hallucinations. + - bugfix: Fixed a bug where the singularity hallucination was stunning for longer + than intended and leaving the fake HUD crit icon permanently. + coiax: + - rscadd: Ghosts are polled if they want to play an alien larva that is about to + chestburst. They are also told who is the (un)lucky victim. + - bugfix: Clones no longer gasp for air while in cloning pods. + - rscadd: Adds a new reagent, "Mime's Bane", that prevents all emoting while it + is in a victim's system. Currently admin only. + - experiment: Mappers now have an easier time adding posters, and specifying whether + they're random, random official, random contraband or a specific poster. + - rscdel: Posters no longer have serial numbers when rolled up; their names are + visible instead. + kevinz000: + - rscadd: You can now craft pressure plates. + - rscadd: Pressure plates are hidden under the floor like smuggler satchels are, + but you can attach a signaller to them to have it signal when a mob passes over + them! + - experiment: Bomb armor is now effective in lessening the chance of being knocked + out by bombs. +2017-03-03: + Cyberboss: + - tweak: You can now repair shuttles in transit space + Incoming5643: + - imageadd: 'Server Owners: There is a new system for title screens accessible from + config/title_screen folder.' + - rscadd: This system allows for multiple rotating title screens as well as map + specific title screens. + - rscadd: It also allows for hosting title screens in formats other than DMI. + - rscadd: 'See the readme.txt in config/title_screen for full details. remove: The + previous method of title screen selection, the define TITLESCREEN, has been + depreciated by this change.' + Sligneris: + - imageadd: Updated sprites for the small xeno queen mode +2017-03-04: + Cyberboss: + - bugfix: You can build lattice in space again + Hyena: + - tweak: Detective revolver/ammo now starts in their shoulder holster + Joan: + - tweak: Weaker cult talismans take less time to imbue. + PJB3005: + - rscadd: Rebased to /vg/station lighting code. + Supermichael777: + - rscadd: Grey security uniforms have unique names and descriptions + Tofa01: + - rscadd: Adds the new Centcomm Raven Battlecruiser to the purchasable shuttle list + buy now get one free! + coiax: + - rscadd: CTF players start with their helmet toggled off, better to see the whites + of their opponents eyes. Very briefly. + - bugfix: Existing CTF barricades are repaired between rounds, and deploy instantly + when replaced. + - tweak: Healing non-critical CTF damage is faster. Remember though, if you drop + into crit, YOU DIE. + - rscadd: Admin ghosts can just click directly on the CTF controller to enable them, + in addition to using the Secrets panel. + - bugfix: Cyborg radios can no longer have their inaccessible wires pulsed by EMPs. +2017-03-06: + Cyberboss: + - experiment: Map rotation has been made smoother + Gun Hog: + - bugfix: The Aux Base Construction Console now directs to the correct Base Management + Console. + - bugfix: The missing Science Department access has been added to the Auxiliary + Base Management Console. + Hyena: + - rscdel: Space bar is out of bussiness + MrStonedOne: + - bugfix: patched a hacky workaround for /vg/lights memory leaking crashing the + server + Penguaro: + - bugfix: Changed DIR of Gas Filter for O2 in Waste Loop from 1 to 4 + Sligneris: + - imageadd: '''xeno queen'' AI hologram now actually uses the xeno queen sprite + as a reference' + Tofa01: + - bugfix: '[Omega] Fixes missing walls and wires new dock to the powergrid' + XDTM: + - rscadd: Changelings can now click their fake clothing to remove it, without needing + to drop the full disguise. + coiax: + - rscadd: The Bardrone and Barmaid are neutral, even in the face of reality altering + elder gods. +2017-03-07: + Supermichael777: + - rscadd: Wannabe ninjas have been found carrying an experimental chameleon belt. + The Spider clan has disavowed any involvement. +2017-03-08: + Cyberboss: + - imageadd: Added roundstart animation + - experiment: Roundstart should now be a smoother experience... again + - bugfix: You can now scan storage items with the forensic scanner + - bugfix: Unfolding paper planes no longer deletes them + - bugfix: Plastic no longer conducts electricity + - tweak: The map rotation message will only show if the map is actually changing + Francinum: + - bugfix: Holopads now require power. + Fun Police: + - tweak: Reject Adminhelp and IC Issue buttons have a cooldown. + Joan: + - rscadd: Circuit tiles now glow faintly. + - rscadd: Glowshrooms now have colored light. + - tweak: Tweaked the potency scaling for glowshroom/glowberry light; high-potency + plantss no longer light up a huge area, but are slightly brighter. + Kor: + - rscadd: People with mutant parts (cat ears) are no longer outright barred from + selecting command roles in their preferences, but will have their mutant parts + removed on spawning if they are selected for that role. + LanCartwright: + - rscadd: Adds scaling damage to buckshot. + Robustin: + - tweak: The DNA Vault has 2 new powers + - tweak: The DNA Vault requires super capacitors instead of quadratic + - tweak: Cargo's Vault Pack now includes DNA probes + Supermichael777: + - rscadd: Robust Soft Drinks LLC is proud to announce Premium canned air for select + markets. There is not an air shortage. Robust Soft Drinks has never engaged + in any form of profiteering. + TalkingCactus: + - rscadd: Energy swords (and other energy melee weapons) now have a colored light + effect when active. + Tofa01: + - bugfix: '[All Maps] Fixes syndicate shuttles spawning too close to stations by + moving their spawn further from the station' + - rscadd: '[Omegastation] This station now has a syndicate shuttle and syndicate + shuttle spawn.' + coiax: + - rscadd: Wizards now have a new spell "The Traps" in their spellbook. Summon an + array of temporary and permanent hazards for your foes, but don't fall into + your own trap(s)! + - rscadd: Permanent wizard traps can be triggered relatively safely by throwing + objects across the trap, or examining it at close range. The trap will then + be on cooldown for a minute. + - rscadd: Toy magic eightballs can now be found around the station in maintenance + and arcade machines. Ask your question aloud, and then shake for guidance. + - rscadd: Adds new Librarian traitor item, the Haunted Magic Eightball. Although + identical in appearance to the harmless toys, this occult device reaches into + the spirit world to find its answers. Be warned, that spirits are often capricious + or just little assholes. + - rscadd: You only have a headache looking at the supermatter if you're a human + without mesons. + - rscadd: The supermatter now speaks in a robotic fashion. + - rscadd: Admins have a "Rename Station Name" option, under Secrets. + - rscadd: A special admin station charter exists, that has unlimited uses and can + be used at any time. + - rscadd: Added glowsticks. Found in maintenance, emergency toolboxes and Party + Crates. + kevinz000: + - rscadd: The Syndicate reports a breakthrough in chameleon laser gun technology + that will disguise its projectiles to be just like the real thing! +2017-03-10: + Cyberboss: + - bugfix: You should no longer be seeing entities with `\improper` in front of their + name + - rscadd: The arrivals shuttle will now ferry new arrivals to the station. It will + not depart if any intelligent living being is on board. It will remain docked + if it is depressurized. + - tweak: You now late-join spawn buckled to arrivals shuttle chairs + - tweak: Ghost spawn points have been moved to the center of the station + - tweak: Departing shuttles will now try and shut their docking airlocks + - bugfix: The arrivals shuttle airlocks are now properly cycle-linked + - bugfix: You can now hear hyperspace sounds outside of shuttles + - experiment: The map loader is faster + - tweak: Lavaland will now load instantly when the game starts + Jordie0608: + - tweak: The Banning Panel now organises search results into pages of 15 each. + XDTM: + - bugfix: Slimes can now properly latch onto humans. + - bugfix: Slimes won't aggro neutral mobs anymore. This includes blood-spawned gold + slime mobs. + - rscadd: Clicking on a tile with another tile and a crowbar in hand directly replaces + the tile. + Xhuis: + - imageadd: Ratvar and Nar-Sie now have fancy colored lighting! + coiax: + - rscadd: Wizards can now use their magic to make ghosts visible to haunt the crew, + and possibly attempt to betray the wizard. + - rscadd: When someone dies, if their body is no longer present, the (F) link will + instead jump to the turf they previously occupied. + - bugfix: Stacks of materials will automatically merge together when created. You + may notice differences when ejecting metal, glass or using the cash machine + in the vault. + - rscadd: You can find green and red glowsticks in YouTool vending machines. + fludd12: + - bugfix: Modifying/deconstructing skateboards while riding them no longer nails + you to the sky. + lordpidey: + - rscadd: Glitter bombs have been added to arcade prizes. +2017-03-11: + AnturK: + - rscadd: Traitors now have access to radio jammers for 10 TC + Hyena: + - bugfix: fixes anti toxin pill naming + Joan: + - tweak: Window construction steps are slightly faster; normal windows now take + 6 seconds with standard tools, from 7 and reinforced windows now take 12 seconds + with standard tools, from 14. + - tweak: Brass windows take 8 seconds with standard tools, from 7. + - rscadd: Added Shadowshrooms as a glowshroom mutation. They do exactly what you'd + expect. + - rscdel: Removed His Grace ascension. + PKPenguin321: + - tweak: Cryoxadone's ability to heal cloneloss has been greatly reduced. + - rscadd: Clonexadone has been readded. It functions exactly like cryoxadone, but + only heals cloneloss, and at a decent rate. Brew it with 1 part cryoxadone, + 1 part sodium, and 5 units of plasma for a catalyst. + Penguaro: + - tweak: Adjusted table locations + - tweak: Moved chair and Cargo Tech start location + - tweak: Moved filing cabinet + - rscdel: Removed Stock Computer + Tofa01: + - bugfix: '[Meta] Fixes Supermatter Shutters Not Working' + coiax: + - rscadd: Swarmer lights are coloured cyan. + kevinz000: + - bugfix: Deadchat no longer has huge amount of F's. +2017-03-12: + JStheguy: + - imageadd: Changed Desert Eagle sprites, changed .50 AE magazine sprites, added + Desert Eagle magazine overlay to icons/obj/guns/projectile.dmi. + - tweak: The empty Desert Eagle sprite now only displays on an empty chamber. The + existence or lack thereof of the magazine is rendered using an overlay instead. + Lzimann: + - tweak: Braindead has a more intuitive message + coiax: + - rscdel: A cloner that is EMP'd will merely eject the clone early, rather than + gibbing it. Emagging the cloner will still gib the clone. +2017-03-13: + Cyberboss: + - tweak: You must now be on any intent EXCEPT help to weld an airlock shut + - rscadd: You can now repair airlocks with welding tools on help intent (broken + airlocks still need their wires mended though) + Cyberboss, Bgobandit, and Yogstation: + - rscadd: The HoP can now prioritze roles for late-joiners + Every coder, player, and admin in Space Station 13: + - rscadd: Adds the Tomb Of The Unknown Employee to Central Command, + - rscadd: Rest in peace, those who died after contributing to Space Station 13. + Hyena: + - bugfix: Surplus leg r/l name fixed + - bugfix: You can now carry honey in plant bags + Lordpidey: + - bugfix: Devils can no longer break into areas with sheer force of disco funk + - rscadd: The pitchfork of an ascended devil can now break down walls. + - rscadd: Hell has decided to at least clothe it's devils when sending them a brand + new body. + - rscadd: Pitchforks glow red now. + Penguaro: + - rscdel: '**Engineering** - Removed Tables, paper bin, and pen' + - rscadd: '**Engineering** - Replaced with Welder and Electrical Lockers' + - rscadd: '**Engineering** - Moved First-Aid Burn kit to Engineering Foyer' + - tweak: '**Chapel** - Replaced one Window with Win-Door for Coffin Storage' + Space Bicycle Consortium: + - bugfix: Bicycles now only cost 10,000 yen, down from 1,000,000 yen. + coiax: + - rscadd: The egg spawner on Metastation will generate a station message and inform + the admins if an egg is spawned. (It's only a two percent chance, but live in + hope.) + - rscadd: Glowsticks can now be found in "Swarmer Cyan" colors. +2017-03-14: + Joan: + - rscadd: Shuttles now have dynamic lighting; you can remove the lights on them + and use your own lights. + - tweak: All maps now use Deltastation's fancy syndicate shuttle. + - tweak: Shadowshrooms of lower potency are much less able to blanket the station + in darkness. + PKPenguin321: + - tweak: Lattices now require wirecutters to deconstruct, rather than welding tools. +2017-03-15: + Cyberboss: + - bugfix: You can no longer depart on the arrivals shuttle by hiding inside things + Joan: + - tweak: Proselytizers converting clockwork floors to walls now always take 10 seconds, + regardless of how fast the proselytizer is. + - tweak: Clockwork grilles no longer provide CV. + Penguaro: + - bugfix: '**Engineering** - Changed Access Level from **24** (_Atmo_) to **10** + (_Engine_) on **Radiation Shutter Control**' + TrustyGun: + - tweak: Traitor Mimes with the finger guns spell now fire 3 bullets at a time, + as opposed to just 1. + octareenroon91: + - rscadd: Allow new reflector frames to be built from metal sheets. + oranges: + - rscdel: Removed patting +2017-03-16: + BASILMAN YOUR MAIN MAN: + - rscadd: The BM Speedwagon has been improved both in terms of aesthetics and performance! + Cyberboss: + - bugfix: The shield generators in Boxstation Xenobiology now have the correct access + Joan: + - rscadd: Cult structures that emitted light now have colored light. + MrPerson: + - rscadd: Humans can see in darkness slightly again. This is only so you can see + where you are when the lights go out. + MrStonedOne: + - bugfix: Fixed lighting not updating when a opaque object was deleted + Penguaro: + - tweak: Increased Synchronization Range on Exosuit Fabricator + Tofa01: + - bugfix: '[Delta] Fixes telecoms temperature and gas mixing / being contaminated.' + - bugfix: '[Delta] Fixes some doubled up turfs causing items and objects to get + stuck to stuff' + - tweak: '[Omega] Makes telecoms room cool down and be cold.' + Tokiko1: + - rscadd: Most gases now have unique effects when surrounding the supermatter crystal. + - tweak: The supermatter crystal can now take damage from too much energy and too + much gas. + - rscadd: Added a dangerous overcharged state to the supermatter crystal. + - rscadd: Readded explosion delaminations, a new tesla delamination and allowed + the singulo delamination to absorb the supermatter. + - tweak: The type of delamination now depends on the state of the supermatter crystal. + - tweak: Various supermatter engine rebalancing and fixes. + kevinz000: + - rscadd: SDQL2 now supports outputting proccalls to variables, and associative + lists + peoplearestrange: + - bugfix: Fixed buildmodes full tile window to be correct path + rock: + - tweak: if we can have glowsticks in toolvends why not flashlights amirite guys +2017-03-17: + BeeSting12: + - bugfix: Moved Metastation's deep fryer so that the chef can walk all the way around + the table. + Cobby: + - tweak: The gulag mineral ratio has been tweaked so there are PLENTY of iron ore, + nice bits of silver/plasma, with the negative of having less really high valued + ores. If you need minerals, it may be a good time to ask the warden now! + Joan: + - rscadd: You can now place lights and most wall objects on shuttles. + Xhuis: + - rscadd: Added the power flow control console, which allows remote manipulation + of most APCs on the z-level. You can find them in the Chief Engineer's office + on all maps. +2017-03-18: + Supermichael777: + - rscadd: Free golems can now buy new ids for 250 points. + XDTM: + - rscadd: You can now complete a golem shell with runed metal, if you somehow manage + to get both. + - rscadd: Runic golems don't have passive bonuses over golems, but they have some + special abilities. + coiax: + - bugfix: The alert level is no longer lowered by a nuke's detonation. +2017-03-19: + BeeSting12: + - rscadd: Nanotrasen has decided to better equip the box-class emergency shuttles + with a recharger on a table in the cockpit. + Cheridan: + - tweak: The slime created by a pyroclastic anomaly detonating is now adult and + player-controlled! Reminder that if you see an anomaly alert, you should grab + an analyzer and head to the announced location to scan it, and then signal the + given frequency on a signaller! + Penguaro: + - bugfix: change access variables for turrets and shield gens + - bugfix: Box Station - Replaces the smiling table grilles with their more serious + counterparts. + coiax: + - tweak: The Syndicate lavaland base now has a single self destruct bomb located + next to the Communications Room. Guaranteed destruction of the base is guaranteed + by payloads embedded in the walls. + octareenroon91: + - bugfix: Fixes infinite vaping bug. + uraniummeltdown: + - rscadd: Plant data disks have new sprites. + - bugfix: Fixed Monkey Recycler board not showing in Circuit Imprinter + - tweak: Kinetic Accelerator Range Mod now takes up 25% space instead of 24% +2017-03-21: + ExcessiveUseOfCobblestone: + - experiment: All core traits [Hydroponics] scale with the parts in the gene machine. + Time to beg Duke's Guide Read.... I mean RND! + - tweak: Data disks with genes on them will have just the name of the gene instead + of the prefix "plant data disk". + - tweak: If you were unaware, you can rename these disks with a pen. Now, you can + also change the description if you felt inclined to. + Joan: + - experiment: Caches produce components every 70 seconds, from every 90, but each + other linked, component-producing cache slows down cache generation by 10 seconds. + Lombardo2: + - rscadd: The tentacle changeling mutation now changes the arm appearance when activated. + MrPerson: + - bugfix: Everyone's eyes aren't white anymore. + Penguaro: + - tweak: Box Station - The Vents and Scrubbers for the Supermatter Air Alarm are + now isolated from the rest of the Air Alarms in Engineering. + Supermichael777: + - bugfix: Chasms now smooth properly. + Tokiko1: + - tweak: Minor supermatter balancing changes. + - tweak: Supermatter now announces its damage half as frequently. + - tweak: Badly unstable supermatter now occasionally zaps nearby engineers and causes + anomalies to appear nearby, similar to overcharged supermatter. + XDTM: + - rscadd: Golem Shells can now be completed with medical gauze or cloth to form + cloth golems, which are weaker and extremely flammable. However, if they die, + they turn into a pile of cloth that will eventually re-animate back into full + health. That is, unless someone lights it on fire. +2017-03-22: + BeeSting12: + - rscadd: Added an autolathe circuit board to deltastation's tech storage. + - rscadd: Added 49 sheets of metal to deltastation's auxiliary tool storage. + Iamgoofball: + - bugfix: Freon no longer bypasses atmos hardsuits. + Penguaro: + - rscadd: Meta - Added Tool Belts to Engineering and Engineering Foyer + - rscdel: Meta - Removed Coffee Machine from Permabrig + - rscadd: Added Cameras for Supermatter Chamber (to view rad collectors and crystal) + - tweak: Adjusted Engine Camera Names for Station Consistency + - bugfix: Adjusted Monitor Names / Networks to view the Engine Cameras + coiax: + - rscadd: APCs now glow faintly with their charging lights. So red is not charging, + blue is charging, green is full. Emagged APCs are also blue. Broken APCs do + not emit light. + - rscadd: Alien glowing resin now glows. +2017-03-23: + Joan: + - tweak: Clock cults always have to summon Ratvar, but that always involves a proselytization + burst. + - rscdel: The proselytization burst will no longer convert heretics, leaving Ratvar + free to chase them down. + - spellcheck: Places that referred to the Ark of the Clockwork Justicar as the "Gateway + to the Celestial Derelict" have been corrected to always refer to the Ark. + Penguaro: + - bugfix: Wizard Ship - Bolts that floating light to the wall. + XDTM: + - rscadd: Medical Gauze now stacks up to 12 + - bugfix: Pressure plates are now craftable. + bgobandit: + - tweak: Alt-clicking a command headset toggles HIGH VOLUME mode. + coiax: + - bugfix: A dead AI no longer counts as an "unconverted AI" for clockcult. +2017-03-24: + BeeSting12: + - bugfix: Auxiliary base maintenance airlock now requires the proper access. Sorry + greyshirts, no loot for you! + Cyberboss: + - tweak: The recycler's base reclaim rate has been buffed from 1% to 50%. Manipulator + upgrades now give +12.5% per level instead of +25% + - bugfix: You can now successfully remove a pen from a PDA while it's in a container + Fox McCloud: + - rscadd: Modular receiver removed from the protolathe to autolathe + - tweak: Modular receiver cost is now 15,000 metal + Joan: + - bugfix: Fixes structures being unable to go through spatial gateways. + - tweak: Blazing Oil blobs take 33% less damage from water. + Penguaro: + - rscadd: '[Meta] Replaced Power Monitoring Console in Engineering with Modular + Engineering Console' + - rscadd: '[Pubby] Replaced Power Monitoring Console in Engineering with Modular + Engineering Console' + - rscadd: '[Omega] Replaced Power Monitoring Console in Engineering with Modular + Engineering Console' + - rscadd: '[Omega] Added RD and Command Modular Consoles to Bridge' + - rscadd: '[Delta] Replaced Power Monitoring Console in Engineering with Modular + Engineering Console' + - rscadd: '[Delta] Replaced duplicate Atmospherics Monitoring Console in Atmo with + Modular Engineering Console' + coiax: + - rscadd: Destroying a lich's body does not destroy the lich permanently, provided + the phylactery is intact. + - rscadd: A lich will respawn three minutes after its death, provided the phylactery + is intact. + - rscadd: The Soul Bind spell is forgotten after cast, respawn is now automatic. + - rscdel: Stationloving objects like the nuke disk are not valid objects for a phylactery. + - rscadd: Explosive implants can always be triggered via action button, even if + unconscious. + rock: + - tweak: lizards are hurt slightly more by cold but less by heat. this does not + mean they are more resistant to being lasered, fortunately. +2017-03-26: + BeeSting12: + - spellcheck: The bar shuttle's buckable bar stools are now buckleable bar stools. + Gun Hog and Shadowlight213: + - rscadd: The AI may now deploy to cyborgs prepared as AI shells. The module to + do this may be research in the exosuit fabricator. Simply slot the module into + a completed cyborg frame as with an MMI, or into a playerless (with no ckey) + cyborg. + - rscadd: AI shells and AIs controlling a shell can be determined through the Diagnostic + HUD. + - rscadd: AIs can deploy to a shell using the new action buttons or by simply clicking + on it. + - experiment: An AI shell will always have the laws of its controlling AI. + Penguaro: + - rscadd: Brig - Added Air Alarm + - rscdel: Engineering - Removed Brig Shutter + - tweak: Omega, Meta, & Delta Stations - The Vents and Scrubbers for the Supermatter + Air Alarm are now isolated from the rest of the Air Alarms in Engineering. + Qbopper: + - spellcheck: Drones are now given OOC guidelines to follow as well as their IC + lawset. + Robustin: + - rscadd: Added the prototype canister with expanded volume, valve pressure, and + access/timer features + TrustyGun: + - bugfix: Deconstructing display cases and coffins now drop the correct amount of + wood. + XDTM: + - tweak: Some golems now spawn with more thematic names. + - tweak: Adamantine Golems are no longer numbered, but receive a random golem name. + - bugfix: Airlocks properly remove the shock overlay when a temporary shock runs + out. + coiax: + - bugfix: Teams playing CTF have their own radio channels, rather than using the + Centcom and Syndicate channels. + - bugfix: Actually actually makes CTF barricades repair between rounds. + - bugfix: Blue CTF lasers have little blue effects when they hit things, rather + than red effects. +2017-03-28: + Supermichael777: + - rscadd: Backup operatives now get the nukes code. + XDTM: + - bugfix: Wooden tiles can now be quick-replaced with a screwdriver instead of a + crowbar, preserving the floor tile. + octareenroon91: + - bugfix: Bonfires that have a metal rod added should buckle instead of runtiming. +2017-03-29: + BeeSting12: + - rscadd: Adds emergency launch console to the backup emergency shuttle. + Joan: + - rscdel: Putting sec armour and a helmet on a corgi no longer makes the corgi immune + to item attacks. + - rscadd: All items with armour will now grant corgis actual armour. + Kevinz000: + - rscadd: High-powered floodlights may be constructed with 5 sheets of metal, a + wrench, a screwdriver, 5 cable coils, and a light tube. They require a powernet + connection via direct wire node. + coiax: + - bugfix: All tophats, rather than just the ones in maintenance, hurt a tiny bit + if you throw them at people. + - bugfix: Supermatter anomalies are more shortlived than regular anomalies, as intended. +2017-03-30: + coiax: + - rscadd: Autoimplanters have been renamed to autosurgeons. Currently only the CMO + and nuclear operatives have access to autosurgeons. What is the CMO hiding? + - bugfix: All upgraded organs for purchase by nuclear operatives now actually come + in an autosurgeon, for speed of surgery. +2017-03-31: + Cobby: + - tweak: Shot glasses are now more ambiguous [EASIER TO MAINTAIN] + Cyberboss: + - bugfix: Temperature changes will now properly cause atmospherics simulation to + activate + - bugfix: The command report for random xeno eggs will now be delivered along with + the rest of the roundstart reports + - bugfix: Drones can no longer be irradiated diff --git a/html/changelogs/archive/2017-04.yml b/html/changelogs/archive/2017-04.yml new file mode 100644 index 0000000000..ddcbede564 --- /dev/null +++ b/html/changelogs/archive/2017-04.yml @@ -0,0 +1,358 @@ +2017-04-01: + Cyberboss: + - bugfix: The contents of the shelterpod smart fridge work again + XDTM: + - bugfix: Facehuggers no longer rip masks from people protected by helmets. +2017-04-02: + BeeSting12: + - bugfix: Metastation's northeast radiation collector is now connected to the grid. + Nanotrasen would like to apologize for any inconvenience caused to engineers, + but copper is expensive. + - rscadd: Boxstation's HoP office now has a PDA tech. + Cyberboss: + - tweak: Firedoors no longer operate automatically without power + - bugfix: Blood and other decals will no longer remain on turfs they shouldn't + - bugfix: The splashscreen is working again + - bugfix: False alarms are now guaranteed to actually announce something + Incoming5643: + - rscadd: Lighting visuals have been changed slightly to reduce it's cost to the + client. If you had trouble running the new lighting, it might run a little better + now. + MMMiracles (CereStation): + - rscadd: Added a patrol path for bots, includes 2 round-start securitrons placed + on opposite sites of station. + - wip: Due to map size, mulebots are still somewhat unreliable on longer distances. + Disposals are still advised, but mule bots are now technically an option for + delivery. + - rscadd: Added multiple status displays, extinguishers, and appropriate newscasters + to hallways. + - rscadd: A drone dispenser is now located underneath Engineering in maintenance. + - rscadd: Each security checkpoint now has a disposal chute that directs to a waiting + cell in the Brig for rapid processing of criminals. Why run half-way across + the station with some petty thief when you can just shove him in the criminal + chute and have the warden deal with him? + - tweak: Security's mail chute no longer leads into the armory. This was probably + not the best idea in hindsight. + - tweak: Virology has a bathroom now. + - tweak: Genetics monkey pen is a bit more green now. + - bugfix: Lawyer now has access the brig cells so he can complain more effectively. + - bugfix: Xenobio kill chamber is now in range of a camera. + - bugfix: Removed rogue bits of Vault area. + - bugfix: Medbay escape pod no longer juts out far enough to block the disposal's + path. + - bugfix: Captain's spare ID is now real and not just a gold ID card. + Penguaro: + - tweak: '[Meta] The Chapel Security Hatches were very intimidating. They have been + changed to more inviting glass doors.' + - bugfix: '[Meta] The maintenance tunnels in the Xeno Lab now have radiation shielding. + The Slime Euthanization Chamber will not have radiation shielding at this time + as dead slimes will not mind radiation.' + coiax: + - rscadd: Adds seperate languages to the game. Now Ratvarian, Drone, Machine, Swarmer, + Human (now called Galactic Common), Slime and Monkey are separate languages. + Each languages has its own comma prefix, for example, Galcom has the ,0 prefix, + while Ratvarian has the ,r prefix. If you don't understand a language when it + is spoken to you, you will hear a scrambled version that will vary depending + on the language that you're not understanding. + - experiment: This does not change who can understand what. + - rscdel: Removed the talk wheel feature. + - rscadd: Clicking the speech bubble icon now opens the Language Menu, allowing + you to review which languages you speak, their keys, and letting you set which + language you speak by default. Admins have additional abilities to add and remove + languages from mobs using this menu. + ktccd: + - bugfix: Ninja suits have received a new software update, making them able to **actually + steal tech levels** from R&D consoles and servers, thus avoid being forced to + honourably kill themselves for failing their objective. +2017-04-05: + Cyberboss: + - bugfix: Cardboard boxes and bodybags can no longer be anchored + Penguaro: + - rscadd: '[Box] A fire alarm has been added to the Lawyer''s office.' + - rscadd: '[Box] Adds access for Scientists to Starboard Maintenance Areas outside + of Toxins.' + - tweak: '[Box] Adjusted Science doors to more logical access codes.' + QV: + - bugfix: Fixed taking max suffocation damage whenever oxygen was slightly low + RemieRichards: + - bugfix: Using TK on the supermatter will burn your head off violently, don't do + this. + - rscadd: 'Examining clothing with pockets will now give information about the pockets: + number of slots, how it is interacted with (backpack, etc.), if it has quickdraw + (Alt-Click) support and whether or not it is silent to interact with.' + coiax: + - bugfix: Emergency shuttles will now forget early launch authorizations if they + cannot launch due to a hostile environment. +2017-04-07: + Qbopper: + - bugfix: Secure lockers will no longer have multiple lines about being broken. +2017-04-09: + 4dplanner: + - bugfix: Gas analyzers can now detect more gases in pipes + Joan: + - bugfix: Fixed a bug where getting caught between two shield generators as they + activated wouldn't cause you to gib and die. + QV: + - tweak: Refactored the way limbs that aren't limbs work + octareenroon91: + - bugfix: Hackable wires should work as intended again. +2017-04-11: + BeeSting12: + - spellcheck: '"the herpes of arts and crafts" is now "The herpes of arts and crafts."' + Cyberboss: + - bugfix: Runes no longer make you/themselves/random atoms yuge + JJRcop: + - tweak: Refactors whisper, now all living mobs can use it + - rscadd: 'Prefix any message with # to whisper, for example, "# Man, that guy is + weird.", you can still use the whisper verb if you whish.' + - rscadd: This is compatible with languages, for example "#,r That HoS is a problem, + we should kill him" + - rscdel: 'Removes #a #b #c etc radio codes, as well as :w and .w, which used to + be whisper.' + MrStonedOne: + - tweak: Nightvision was heavily modified. + - rscadd: Nightvision has been given 3 levels of nightvisionness. (some, most, and + full) + - tweak: ghosts, aliens, guardians, night vision eyes, and statues were given all + 3 levels in a cycling toggle + - tweak: thermals, and hud+NV goggles give "some" nightvisionness + - tweak: standalone masons are unchanged. + - tweak: Nightvision goggles (that aren't also sec huds or medhuds or the like) + give "most" nightvisionness. Nightvision masons also give "most" nightvisionness + - tweak: Most simple mobs with the ability to see in the dark were given "most" + nightvisionness, others got full nightvisionness. + - bugfix: Fixed certain ghost only things disappearing when disabling darkness. + - bugfix: Fixed ash storms not being visible when using things that modified your + ability to see darkness + - bugfix: fix a bug with the new github web processor + Shadowlight213: + - bugfix: The anime admin button will no longer cause equipped items to drop. + coiax: + - rscadd: Examining a ghost determines whether it is visible. +2017-04-13: + Cyberboss: + - bugfix: Fixed the incorrectly named Brig APC on Box Station= + - spellcheck: Fixed simple animal attack grammar + - bugfix: Roundstart department head announcements have been fixed + - bugfix: Brig cell doors now properly require the correct access + - bugfix: Fixed a bug preventing chameleon stamps from being picked up + - bugfix: Fixed a bug where honey frames couldn't be picked up + - bugfix: Photocopied papers will now retain their stamps + Davidj361: + - bugfix: Made it so chemsprayers, peppersprays, extinguishers don't spray when + you click your inventory items + - bugfix: Spray guns now actually have their range change when changing modes between + spray and stream + - bugfix: Krav maga now gets its abilities toggled if you click the same ability + twice + - bugfix: Added a link to the bottom right of paper when writing that shows help + for paper writing + - bugfix: Fixed the shift+middle-click pointing shortcut to work for cyborgs as + the functionality wasn't even there + - bugfix: Bodies in body bags get cremated properly now + RemieRichards: + - bugfix: Constructing lattice no longer prevents space transitions. + Robustin: + - rscadd: Ranged RCD added to the game + - rscadd: Rapid Lighting Device (also ranged) has been added. It can create wall, + floor, and temporary lights of any color you desire. + coiax: + - bugfix: Cigarette branding has been fixed. + - rscadd: Uplift Smooth brand cigarettes now taste minty as advertised. + - rscdel: You can no longer inject cigarette packets to inject all cigarettes simultaneously. + powergaming research director: + - bugfix: woops i dropped the emp protection module when i made your cns rebooters + today, guess they're vulnerable again! +2017-04-15: + Cyberboss: + - bugfix: Holopads can no longer be interacted with while unpowered + Davidj361: + - bugfix: Monkeys won't pickup items or rob you while they are in your stomach, + neither walk out of your stomach. + - bugfix: You can't cheat with eyewear/eye-implants when using advanced cameras + - bugfix: Mutant digitigrade legs re-added to the ashwalker species + Robustin: + - rscadd: The Prototype Emitter, will function like an ordinary emitter while also + charging a secondary power supply that will allow a buckled user to manually + fire the emitter. Returning to automatic fire will have the emitter continue + to fire at the last target struck by manual fire. + - rscadd: The Engineering Dance Machine, along with assorted effects/sounds. + coiax: + - bugfix: Plasmamen no longer burn to death while inside a cloning pod. +2017-04-18: + BeeSting12: + - bugfix: Cerestation's shuttle now has a recharger. + - rscdel: Centcomm's thunderdome airlocks have been removed due to contestants breaking + out. + - bugfix: Deltastation's chemistry lab now has a pill bottle closet. + - bugfix: The shield wall generators in xenobiology on Deltastation, Boxstation, + Metastation, and Pubbystation can now be locked and unlocked by scientists. + Davidj361: + - bugfix: Spawned humans no longer spawn eyeless (sprite) + MMMiracles (Cerestation): + - rscadd: Departments have been given head offices for a more secure place to chill + in their departments. + - rscadd: There is now a theatre on the service asteroid. + - tweak: Maintenance visuals and loot have been overhauled to be more visually interesting + and have more scattered bits of loot. + - bugfix: Various fixes with missing APCs, camera coverage, and misc things. + QualityVan: + - rscadd: Some foam guns can now be suppressed + coiax: + - rscadd: Drone, monkey and swarmer language now have distinctive colours when spoken. + - rscadd: Since drones are allowed to interact with pAIs, pAIs in mobile chassis + form are no longer distorted to drone viewpoints. + - bugfix: The shuttle's arrival can no longer be delayed after Nar-Sie's arrival. + The End cannot be delayed. +2017-04-19: + QualityVan: + - bugfix: Improved stethoscopes + Thunder12345: + - bugfix: You can no longer extract negative sheets from the ORM + XDTM: + - bugfix: APCs hacked by a malfunctioning AI are no longer immune to alien attacks. + - bugfix: Fixed bug where flashlight eyes weren't emitting light. +2017-04-20: + Cyberboss: + - bugfix: Fixed mining closets having extra, unrelated items +2017-04-22: + Cyberboss: + - bugfix: Conveyors no longer move things they aren't supposed to + XDTM: + - bugfix: Gold and Light Pink slime extracts no longer disappear before working. + coiax: + - bugfix: Fixed people understanding languages over the radio when they shouldn't. +2017-04-23: + coiax: + - rscadd: Centcom would like to inform all employees that they have ears. + - rscadd: Adds "ear" organs to all carbons. These organs store ear damage and deafness. + A carbon without any ears is deaf. Genetic deafness functions as before. +2017-04-25: + BeeSting12: + - bugfix: Deltastation's secure tech storage is no longer all access. + CoreOverload: + - bugfix: Disposals no longer get broken by shuttles rotation. + - bugfix: Wires no longer get broken by shuttles movement and rotation. + - bugfix: Atmospheric equipment no longer gets broken by shuttles movement and rotation. + Glory to the Flying Fortress of Atmosia! + Jalleo: + - rscdel: WW_maze from lavaland has been removed it wasnt that good really anyhow + QualityVan: + - bugfix: Changeling brains are now more fully vestigial + WJohnston: + - tweak: Skeletons and plasmamen's hitboxes now more closely match that of humans. + They are no longer full of holes and incredibly frustrating to hit, should they + run around naked. + XDTM: + - bugfix: Items will no longer be used on backpacks if they fail to insert when + they're too full. + - bugfix: T-Ray scans are no longer visible to bystanders. + - bugfix: T-Ray scans no longer allow viewers to interact with underfloor objects. + basilman: + - bugfix: fixed species with no skin dropping skin when gibbed. + coiax: + - rscadd: Examining a window now gives hints to the appropriate tool for the next + stage of construction/deconstruction. + - rscadd: You can examine a firedoor for hints on how to construct/deconstruct it. + - rscadd: Add an additional hint during construction where you can add plasteel + to make the firedoor reinforced. + - bugfix: Fixed easter eggs spawning during non-Easter. + - bugfix: Fixes stations not having holiday specific prefixes during the holidays. + - bugfix: Ghosts no longer drift in space. + - bugfix: Swarmers now only speak their own language, rather than swarmer and common. + - bugfix: When you are crushed by a door, it prints a visible message, instead of, + in some cases, silently damaging you. + - bugfix: The vent in the Escape Coridoor on Omega Station has been fixed. + - bugfix: You no longer die when turning into a monkey. + coiax, WJohnston: + - rscadd: Plasmamen lungs, also known as "plasma filters" now look different from + human lungs. + - rscadd: Plasmamen now have their own special type of bone tongue. They still sound + the same, it's just purple. Like them. +2017-04-26: + CoreOverload: + - rscadd: Gas injectors are now buildable! + Joan: + - tweak: Ash Drake swoops no longer teleport the Ash Drake to your position. + - balance: Some other tweaks to Ash Drake attacks and patterns; discover these yourself! + coiax: + - balance: The wizard spell Rod Form now costs 3 points, up from 2. + flashdim: + - bugfix: Omega Station had two APCs not wired properly. (#26526) +2017-04-27: + Gun Hog: + - rscadd: The GPS interface has been converted to tgui. + - experiment: GPS now update automatically or manually, give distance and direction + to a signal, and many other improvements! + MrStonedOne: + - tweak: Tweaked how things were deleted to cut down on lag from consecutive deletes + and provide better logging for things that cause lag when hard-deleted. + - tweak: Server hop verb moved to the OOC tab + - rscadd: Server hop verb can now be used in the lobby as well as while a ghost. + QualityVan: + - bugfix: You can hit emagged cloning pods with a medical ID to empty them + - rscadd: Crayons can be ground + - rscadd: Crayon powder can be used to color stuff + Shadowlight213: + - tweak: Heads of staff may now download the ID card modification program from NTNet. + bgobandit: + - tweak: When jumpsuits take severe damage, their suit sensors break. They can be + fixed by applying a cable coil. + coiax: + - rscadd: Anomalous crystals can be examined by ghosts to determine their function + and activation method. + - rscdel: Lightbringers can understand Slime and Galactic Common, and can only speak + Slime, as before. + - rscadd: The helper anomalous crystal is in the orbit list after it has been activated. +2017-04-28: + Kor: + - rscadd: Librarians can speak any language + coiax, WJohnston: + - rscdel: Languages no longer colour their text. + - rscadd: Languages now have icons to identify them. Galatic Common does not have + an icon if understood. +2017-04-29: + BeeSting12: + - bugfix: The emergency backup shuttle has lighting now. + - bugfix: Plating in deltastation's aux tool storage is no longer checkered. + Cobby: + - rscadd: Syndicate Lavabase now has more explicit instructions when it comes to + outing non-syndicate affiliated enemies of Nanotrasen. + - tweak: The GPS set tag has gone from a limit of 5 characters to 20. + - rscadd: The GPS can now be personalized in both name and description using a pen. + Joan: + - rscdel: Removed Mending Motor. + - rscadd: Added Mending Mantra, which is a script that causes you to repair nearby + constructs and structures as long as you continue chanting it. + - tweak: Mending Mantra will also heal Servants as long as they're wearing clockwork + armor. + Kor: + - rscdel: Removed double agents mode. + - rscadd: Replaced it with Internal Affairs mode. + Swindly: + - rscadd: Added organ storage bags for medical cyborgs. They can hold an organic + body part. Use the bag on a carbon during organ manipulation or prosthetic replacement + to add the held body part. + coiax: + - rscdel: Swarmer traps are no longer summoned by The Traps. + - balance: Wizard traps automatically disappear five minutes after being summoned. + - balance: Wizard traps disappear after firing, whether triggered via person or + something being thrown across it. + - balance: Wizards are immune to their own traps. + - tweak: The Traps are now marked as a Defensive spell, rather than an Offensive + spell. + kevinz000: + - experiment: Songs can now be added to disco machines with add_track(file, name, + length, beat). Only file is required, the other 3 should still be put in, though. + tacolizard forever: + - bugfix: Rechargers no longer flash the 'fully charged' animation before charging + something +2017-04-30: + QualityVan: + - bugfix: Changelings can once again revive with their brain missing + XDTM: + - rscdel: Voice of God's Rest command now no longer makes listeners rest. It instead + activates the sleep command. + coiax: + - rscadd: The Bank Machine in the vault now uses the radio to announce unauthorized + withdrawals, rather than an endless stream of loud announcements. diff --git a/html/changelogs/archive/2017-05.yml b/html/changelogs/archive/2017-05.yml new file mode 100644 index 0000000000..699a8cadb4 --- /dev/null +++ b/html/changelogs/archive/2017-05.yml @@ -0,0 +1,808 @@ +2017-05-01: + 4dplanner: + - tweak: Syndicate surplus crates now contain fewer implants + Bawhoppen: + - rscadd: Deep storage space ruin has been readded. + - rscadd: Space Cola machines now stock bottles of water. + Cobby: + - balance: The Gang pen is now stealthy. Stab away! + Cyberboss: + - rscadd: You can now make holocalls! Simply stand on a pad, bring up the menu, + and select the holopad you wish to call. Remain still until someone answers. + When they do, you'll be able to act just like an AI hologram until the call + ends + Joan: + - rscadd: Belligerent now prevents you from running for 7 seconds after every chant. + - rscdel: However, you no longer remain walking after Belligerent's effect fades. + - rscadd: Clockcult component generation will automatically focus on components + needed to activate the Ark if it exists. + - rscadd: Gaining Vanguard, such as from the Linked Vanguard scripture, will remove + existing stuns. + - rscadd: Proselytizers can now charge from Sigils of Transmission at a rate of + 1000W per second. + - rscadd: Sigils of Transmission can be charged with brass at a rate of 250W per + sheet. + Moonlighting Mac says: + - bugfix: Due to a clerical error in the chef's cookbooks now being resolved, you + can now make the pristine cookery dish "Stuffed Legion" out of exotic ingredients + from Lavaland. + - experiment: After being found again you will now be able to enjoy its special + blend of flavors with your tastebuds. Mmm. + QualityVan: + - tweak: Saline glucose now acts as temporary blood instead of increasing blood + regeneration + Swindly: + - tweak: Mercury and Lithium make people move when not in space instead of when + in space. + ninjanomnom: + - tweak: TEG displays power in kw or MW now + - tweak: TEG power bar only maxes over 1MW now + - experiment: Moves TEG to SSair + - experiment: Moves SM to SSair +2017-05-02: + 4dplanner: + - bugfix: Squishy plants will now affect walls and other turfs they get squished + on + Kor, Goof and Plizzard: + - rscadd: Adds persistent trophy cases. They are not on any map yet. + Shadowlight213: + - bugfix: The biogenerator will now show its recipes again. + XDTM: + - tweak: Blood Cult's talisman of Horrors now works at range. It will still give + no warning to the victim. + - rscadd: Golems can now click on empty golem shells to transfer into them. + - tweak: Plasma Golems now no longer explode on death. They instead explode if they're + on fire and are hot enough. The explosion size has been increased. + - tweak: Plasma Golems are now always flammable. + coiax: + - rscadd: When talking on the alien hivemind, a person will be identified by their + real name, rather than who they are disguised as. +2017-05-03: + BeeSting12: + - bugfix: Omega shuttle now has lighting. + Joan: + - balance: Clockwork component generation is twice as fast. + - balance: Scriptures cost up to twice as much; Driver scriptures are unaffected, + meaning they cost 50% less, Script scriptures cost 25% less, Application scriptures + cost about 12.5% less, and Revenant scriptures cost about 5% less. + Jordie0608: + - rscadd: Investigate logs are now persistent. + - tweak: Game logs are now stored per-round; use .getserverlog to access previous + rounds. + - rscdel: .giveruntimelog and .getruntimelog removed. + Kor, Profakos, Iamgoofball: + - rscadd: The Librarian has been replaced by the Curator. + - rscadd: Persistent trophy cases have been added to the library on Meta, Delta, + and Box. These are only usable by the Curator. + - rscadd: The Curator now starts with his whip. + - rscadd: The Curator now has access to his treasure hunter outfit, stashed in his + private office. + coiax: + - balance: Plasma vessels, the organs inside aliens that are responsible for their + internal plasma storage, will regenerate small amounts of plasma even if the + owner is not on resin weeds. + - rscadd: Restrictions on Lizardpeople using their native language on the station + have been lifted by Centcom, in order to maximise worker productivity. The language's + key is ",o". + deathride58: + - tweak: Fixed the slimecore HUD's neck slot sprite. +2017-05-04: + 4dplanner: + - bugfix: revenants now properly resurrect from ectoplasm, as opposed to ectoplasm + merely spawning a new grief ghost + - bugfix: Turrets can no longer see invisible things, such as unrevealed revenants + Joan: + - rscadd: Mania Motors now do minor toxin damage over time and will convert those + affected if the toxin damage is high enough. + - balance: The effects of a Mania Motor continue to apply to targets after they + leave its range, though they will fall off extremely quickly. + - rscdel: Mania Motors no longer cause brain damage. + - imageadd: Ratvarian Spears have new inhand icons. + Lzimann: + - rscdel: Gang game mode was removed + Moonlighting Mac says: + - rscadd: Courtesy of the art & crafts division, imitation basalt tiles themed on + the rough volcanic terrain of lavaland are now available to be made out of sandstone. + - experiment: The manufacturer even managed to replicate the way that it lights + up with volcanic energy, it is the perfect accompaniment to other fake (or real) + lava-land tiles or a independent piece. + QualityVan: + - rscadd: Point flashlights at mouths to see what's inside them +2017-05-05: + Incoming: + - tweak: Display cases now require a key to open, which the curator spawns with + Joan: + - balance: Sigil of Accession, Fellowship Armory, Memory Allocation, Anima Fragment, + and Sigil of Transmission are not affected by the previously-mentioned % reduction + to Application scripture costs. + LanCartwright: + - rscadd: Lesser smoke book to Delta and Metastation + - rscdel: Normal smoke book from Delta and Metastation + - tweak: Civilian smoke book now has a 360 max cooldown (from 120) and halved smoke + output. + QualityVan: + - bugfix: Dental implants stay with the head they're in + bgobandit: + - tweak: The Syndicate has added basic functionality to their state-of-the-art equipment. + Nuke ops can now donate all TCs at once. + lordpidey: + - rscadd: There is a new traitor poison, spewium. It will cause uncontrollable + vomiting, which gets worse the longer it's in your system. An overdose can + cause vomiting of organs. + - tweak: Committing suicide with a gas pump can now shoot out random organs. + - bugfix: Toxic vomit now shows up as intended. +2017-05-06: + 4dplanner: + - rscadd: Internal Affairs Agents now obtain the kill objectives of their targets + when they die. + - rscadd: Internal Affairs Agents now have an integrated nanotrasen pinpointer that + tracks their target at distances further than ten squares. + - rscadd: Internal Affairs Agents will now lose any restrictions on collateral damage + and gain a "Die a glorious death" objective upon becoming the last man standing, + and revert if any of their targets are cloned. + BeeSting12: + - bugfix: Pubbystation no longer has two airlocks stacked on top of each other leading + into xenobiology's kill room. + - rscadd: Deltastation's chemistry now has a screwdriver. + - bugfix: Deltastation's morgue no longer has a blue tile. + - bugfix: Deltastation's chemistry smart fridge is no longer blocked by a disposal + unit. + Cyberboss: + - tweak: Teslas now give off light + Joan: + - balance: Sigils of Transgression are slightly more visible and glow very faintly. + LanCartwright: + - rscadd: Reduction to nutrition when consuming Miner's salve. + - rscdel: Stun/weaken that bypasses bugged chemical protection when consuming Miner's + salve. + Lzimann: + - rscdel: Telescience is no more. + PKPenguin321: + - rscadd: Undid the gang gamemode removal. + QualityVan: + - rscadd: Cargo can order restocking units for NanoMed vending machines + - rscadd: NanoMed vending machines can be build and unbuilt + Robustin: + - rscadd: Blood Cultists can now attempt to claim the position of Cult Master with + the approval of a majority of their brethren. + - rscadd: 'The Cult Master has access to unique blood magic that will aid them in + leading the cult to victory:' + - rscadd: The Cult Master can mark targets, allowing the entire cult to track them + down. + - rscadd: The Cult Master has single-use, noisy, and overt channeled spell that + will summon the entire cult to their location. + - rscadd: All cultists gain a HUD alert that will assist them in completing their + objectives. + - rscadd: Constructs created by soul shards will now be able to track their master. + - rscadd: Cultists created outside of cult mode will now get a working sacrifice + and summon objective and the summon rune will no longer fail outside of cult + mode. + - tweak: Gang Dominator max time is now 8 minutes down from 15m + - tweak: Gang Tagging now reduces the timer by 9 seconds per territory, down from + 12 seconds. + coiax: + - rscadd: Adamantine golems have special vocal cords that allow them to send one-way + messages to all golems, due to fragments of resonating adamantine in their heads. + Both of these are organs, and can be removed and put in other species. + - rscadd: You can use adamantine vocal cords by prefixing your message with ":x". + - rscdel: Xenobiology is no longer capable of making golem runes with plasma. Instead, + inject plasma into the adamantine slime core to get bars of adamantine which + you can then craft into an incomplete golem shell. Add 10 sheets of suitable + material to finish the shell. + - experiment: The metal adamantine is also quite valuable when sold via cargo. + - bugfix: If you know more than the usual number of languages, you'll now remember + them after you get cloned. + - rscdel: Humans turning into monkeys will not suddenly be able to speak the monkey + language, and will continue to understand and speak human. + - rscadd: Ghosts can now modify their own understood languages with the language + menu. + - rscadd: Any mob can also open their language menu with the IC->Open Language Menu + verb. + - rscadd: Silicons can now understand Draconic as part of their internal databases. + - bugfix: Golems no longer have underwear, undershorts or socks. + - tweak: The lavaland Seed Vault ruin can spawn only once. + - rscadd: It is now possible to make plastic golems, who are made of a material + flexible enough to crawl through vents (while not carrying equipment). They + also can pass through plastic flaps. + - bugfix: Fixed adamantine vocal cord (F) links not working for observers. +2017-05-07: + Anonmare: + - tweak: Removes organic check from mediborg storage container + Joan: + - rscadd: Cultists of Nar-sie have their own language. The language's key is ",n". + - balance: Sigils of Transgression are slightly brighter. + Moonlighting Mac: + - experiment: Due to budget cuts and oil synthesis replacing expensive processes + of digging up haunted primeval ashwalker burial grounds, Nanotransen has taught + chemists how to make plastic from chemicals in the hopes that new plastic products + can reduce expenditure on metal and glass. + - rscadd: you can now make plastic sheets from chemistry out of heated up crude + oil, ash & sodium chloride + MrStonedOne: + - bugfix: fixed bug that caused an infinite connection loop when connecting on a + new computer or computer with recently changed hardware. + - rscadd: Moved to a new system to make top menu items easier to edit. + - tweak: Moved icon size stuff to a sub menu + - rscadd: Added option to change icon scaling mode. + - bugfix: Byond added fancy shader supported scaling(Point Sampling), this sucks + because it's blurry, the default for /tg/station has changed back to the old + nearest neighbor scaling. + Penguaro: + - bugfix: Adjusted the Examine description of the right-most tiles of the Space + Station 13 sign to be consistent with the rest of the tiles. + - bugfix: Anywhere there was lava below a tile on the station is now space. + Robustin: + - tweak: c4 planting is now 40% faster + coiax: + - bugfix: Smartfridges no longer magically gain medicines if deconstructed and rebuilt. + - rscadd: Ash walkers now know and speak Draconic by default, but still know Galactic + Common. Remember, Galcom's language key is ",0" and you can review your known + languages with the Language Menu. + octareenroon91: + - rscadd: Showers and sinks added to gulag and mining station for hygiene and fire + safety. + - rscadd: Watertanks added to mining station for convenient fire extinguisher refill. +2017-05-08: + Dorsisdwarf: + - bugfix: Fixed being unable to hit museum cases in melee + Joan: + - tweak: The verb to Assert Leadership over the cult has been replaced with an action + button that does the same thing, but is much more visible. + Moonlighting Mac says: + - tweak: After a recent trade fair, employees have took it upon themselves to learn + how to craft leather objects out of finished leather sheets, for novices they + are pretty good at it! Try it yourself! + - rscadd: Muzzles to silence people are now craftable out of leather sheets. + - rscdel: You can no longer print off designs from a bio-generator that can now + be crafted out of leather sheets. + - tweak: Complete sheets of leather can be printed from the bio-generator for 150 + biomass to accommodate for a loss of designs. + - experiment: Specialist objects from the leather & cloth category bio-generator + category were not removed as to encourage interdepartmental interaction & balance. + Penguaro: + - rscadd: The Slime Scanner is available from the Autolathe. + - tweak: The Design Names in the various machines are now capitalized consistently + coiax: + - bugfix: Fixes various mobs speaking languages that they were only supposed to + understand. + - bugfix: Fixes being able to bypass language restrictions by selecting languages + you can't speak as your default language. + ninjanomnom: + - tweak: Highlander no longer breaks your speakers +2017-05-09: + Expletive: + - rscadd: Curator's fedora has a pocket, like all the other fedoras. + - tweak: Treasure hunter suits can now hold large internal tanks, to ease the exploration + of lavaland. + - tweak: The curator can now access the Auxillary Base and open doors on the mining + station. + MrStonedOne: + - tweak: Lighting now defaults to fully bright until the first update tick for that + tile. This makes shuttle movements less immersion breaking. + - experiment: Rather than remove the light source from the system and then re-adding + it on light movements, the system now calculates and applies the difference + to each tile. This should speed up lighting updates. + Penguaro: + - tweak: Adjusts Meteor Shuttle Name + - bugfix: The Central Command Ferry will now dock at one of the ports in Arrivals + - tweak: '[Meta] The Slime Control Console boundaries have been adjusted around + the Kill Room' + XDTM: + - rscadd: Added bluespace launchpads. They can be built with R&D, and can teleport + objects and mobs up to 5 tiles away (8 at max upgrades), from the pad to the + target and viceversa. + - rscadd: To set up a launchpad, a launchpad and a launchpad console must be built. + The pad must be opened with a screwdriver, then linked to the console using + a multitool. A console can support up to 4 pads. + - rscadd: Launchpads require some time to charge up teleports, but don't require + cooldowns unlike quantum pads. Upgrading launchpads increases the range by 1 + per manipulator tier. + - rscadd: A special variant, the Briefcase Launchpad, has also been added to the + traitor uplink for 6 TC. + - rscadd: Briefcase Launchpads look like briefcases until setup (which requires + a few seconds). When setup, the launchpad will be functional, but can still + be dragged on the ground. To pick a pad back up, click and drag it to your character's + sprite. + - rscadd: Unlike stationary launchpads, briefcase pads only have 3 tiles of maximum + range. + - rscadd: Briefcase pads are controlled by a remote (that is sent with the briefcase) + instead of a console. The remote must be linked to the briefcase by simply hitting + it. Each remote can only be linked to one pad, unlike consoles. + coiax: + - rscadd: Visible ghosts emit light. +2017-05-11: + Joan: + - rscadd: You can now buy double eswords from the uplink for 16 telecrystals. They + cannot be bought below 25 players. + - rscdel: You can no longer use two eswords to construct a double esword. + Joan, Robustin: + - rscdel: Harvesters can no longer break walls, construct walls, convert floors, + or emit paralyzing smoke. + - rscadd: Harvesters now remove the limbs of humans when attacking, can heal OTHER + constructs, have thermal vision, and can move through cult walls. + - rscadd: Harvesters can now convert turfs in a small area around them and can create + a wall of force. + - tweak: Harvesters are now cultists. + - rscadd: When Nar-Sie is summoned, she will convert all living non-construct cultists + to harvesters, who will automatically track her. + Kor: + - rscadd: a new mysterious book has been discovered in lavaland chests! + - tweak: weird purple hearts found in lavaland chests have started beating again! + what could this mean? + MrStonedOne: + - bugfix: Fixes t-ray mode on engineering goggles not resetting the lighting override + properly. + QualityVan: + - tweak: Machine names will be capitalized when they talk on radio + Robustin: + - tweak: Dominators now require a significant amount of open (non-walled) space + around them in order to operate. + TehZombehz: + - rscadd: Sticks of butter and liquid mayonnaise can now be produced via a new 'mix' + function on the grinder. Please eat responsibly. + XDTM: + - bugfix: Plasma Golems now have the correct updated tip. + - tweak: Plasma Golems no longer take damage from fire, and take normal instead + of increased burn damage from other sources. They will still explode if on fire + and hot enough. + - rscadd: Plasma Golems can now self-ignite with an action button. + - tweak: Plasma Golems are now warned when they're close to exploding. + - tweak: Plasma Golems now have a constant chance of exploding after 850K instead + of a precise threshold at 900K, making it less predictable. + bandit: + - tweak: Nanotrasen has enhanced personality matchmaking for its personal AIs. pAI + candidates will now see who is requesting a pAI personality. + duncathan: + - tweak: opening a dangerous canister will only alert admins if it contains meaningful + amounts of a dangerous gas. No more being bwoinked because you opened an empty + canister that used to have plasma in it. + lordpidey: + - tweak: Modified chances for returning someone's soul using an employment contract. Now + everyone has a chance, not just lawyers and HoP. + - rscadd: Particularly brain damaged people can no longer sign infernal contracts + properly. + - tweak: Infernal contracts for power no longer give fireball, and instead give + robeless 'lightning bolt' spell. + - rscadd: Devils can now sell you a friend, for the cost of your soul. + - tweak: The codex gigas should now be easier to use, and less finicky. + - rscdel: The codex gigas no longer sintouches readers. + ma44: + - tweak: Doubles the amount of points wooden planks sell for (now 50 points) +2017-05-12: + Joan: + - tweak: Manifest Spirit will no longer continue to cost the user health if the + summoned ghost is put into critical or gibbed. + - rscadd: Ghosts summoned by Manifest Spirit are outfitted with ghostly armor and + a ghostly cult blade that does slightly less damage than a normal cult blade. + - balance: Manifest Spirit now consumes 1 health per second per summoned ghost, + from 0.333~. + - balance: Manifest Spirit can now only summon a maximum of 5 ghosts per rune, and + the summoned ghosts cannot use Manifest Spirit to summon more ghosts. + - rscadd: Wraiths now refund Phase Shift's cooldown by attacking; 1 second on normal + attacks, 5 seconds when putting a target into critical, and a full refund when + killing a target. + - balance: Increased Phase Shift's cooldown from 20 seconds to 25 seconds. + KorPhaeron: + - rscadd: Zombies can now see in the dark. If you steal their eyes you'll be able + to see in the dark as well! + MMMiracles (Cerestation): + - tweak: Hydroponics has been revamped, adding a few things missing before and adding + a bee room in place of the backroom. + - bugfix: Fixed some other stuff. + New Antag Alert sounds: + - soundadd: added sounds that alert players to their antag status + - soundadd: Blood cult has a new alert sound + - soundadd: Clock cult has a new alert sound + - soundadd: changeling has a new alert sound + - soundadd: Malf/traitor AI has a new alert sound + - soundadd: Nuke Ops has a new alert sound + - soundadd: Ragin' Mages has a new alert sound + - soundadd: Traitor has a new alert sound + Swindly: + - tweak: Solid plasma now begins burning at the temperature at which it was ignited. + - balance: Snow walls no longer block explosions, are deconstructed faster, and + no longer leave girders when deconstructed. + coiax: + - balance: Nanotrasen Cloning Divison's three hundred identical scientists have + announced an upgrade to the cloning computer's software. You can now scan brains + or dismembered heads and successfully clone from them. Brains seem to remember + the DNA of the last body they were attached to. +2017-05-13: + QualityVan: + - bugfix: Pizza boxes once again look different when open + 'Tacolizard Forever: It''s hip to fuck bees': + - rscadd: Added a honey jar item. It's not implemented yet. + - balance: Honey is now more robust at healing, but don't eat too much or you'll + turn into a fatty landwhale. + TehZombehz: + - rscadd: Butter noodles, butter biscuits, buttered toast, and pigs in a blanket + can now be crafted using sticks of butter and other ingredients. + coiax: + - rscadd: Servant golems now follow the "Material Golem (123)" naming scheme. + octareenroon91: + - rscadd: Hermit ruin now includes a portable seed extractor. +2017-05-14: + coiax: + - rscadd: Free Golems can purchase Royal Capes of the Liberator at their mining + equipment vendor. +2017-05-15: + Dorsidwarf: + - balance: Nanotrasen Robotics Supply Division has successfully petitioned to replace + the "My First Robot" motors in turret coverings with a standard commercial brand. + As such, they will now open faster. + Expletive: + - rscadd: You can now create water bottles and wet floor signs by using plastic + sheets. + - rscadd: You can create toy swords out of plastic sheets, a piece of cable, and + a light bulb. + Joan: + - tweak: Glowshrooms now have a less saturated glow. + - balance: The summoned ghosts from Manifest Spirit can no longer break airlocks + with their standard blade. + - balance: Manifest Spirit now does a small amount of damage when initially manifesting + a ghost. + McBawbaggings: + - tweak: SMES units will now accept charge from the power network even if the available + load is less than the input rate. Credit to Zaers for the original code. + - bugfix: Wizards are now at least 30 years old. Apprentices will be in-between + ages 17 to 29. + Penguaro: + - bugfix: The Gravity Generator description now mentions a graviton field as opposed + to a gravaton field. What is Gravaty anyway? + - bugfix: Centcom Engineering has reviewed the plans for the Box series station + and has addressed some concerns related to some APCs not affecting their designated + section. APCs for the Detective's Office, Cargobay, and Gateway, now control + those rooms. The Bridge Maintenance APC has been removed from future construction + as it serves no purpose and thus is an unnecessary construction cost. + - bugfix: The pipe from the station to the AI Satellite has been completed. + Profakos: + - rscadd: Centcom has decided to upgrade the Ore Redemption machines with a floppy + drive, intended for design disks. + Qbopper: + - tweak: The supermatter crystal now sends its warning messages to the engineering + channel. (if it's in critical condition the message will be sent to the common + radio channel as before) + Swindly: + - balance: Nitrous oxide now causes anemia. + coiax: + - bugfix: Curator soapstones now successfully leave messages for future shifts. + - rscdel: Soapstones can no longer be purchased in cargo. + - rscdel: The janitor no longer starts with an empty soapstone. + - experiment: Engraved messages can be left anywhere in the world, but be wary that + the terrain of places like lavaland and space can change shift to shift. + - rscadd: Goats on the station have developed a taste for glowshrooms, and will + eat them if they encounter any. + ma44: + - tweak: Seed vault remapped + - tweak: The seed vault random seed spawner can now spawn cherry bombs instead of + regular cherry seeds + - rscadd: BEES to plant vault + octareenroon91: + - rscadd: Ambrosia Deus can now mutate into Gaia, and Gaia into Deus. + - rscdel: A single branch of Ambrosia Gaia will not immediately make a hydroponics + tray self-sufficient. + - balance: A (total) dose of 20u Earthsblood (from Gaia) will make a hydroponics + tray self-sufficient. + uraniummeltdown: + - rscadd: Ambrosia Gaia is back +2017-05-16: + Moonlighting Mac says: + - rscadd: Starthistles now return seeds when they are harvested, amongst having + a overhaul of description, alteration of statistics & a mutational path into + harebells. These seeds have been supplied into the hydroponics seed vendor. + - imageadd: Starthistle tray sprites have been restructured & also fixed from a + issue of them being broken and not appearing in trays. In addition there are + new sprites for its seeds. + Penguaro: + - bugfix: There is now Space under the rocks at the Dragoon's Tomb + - bugfix: Centcom Intelligence reports that the Hidden Syndicate Research Base may + have received a shipment of viruses. + QualityVan: + - bugfix: Fixed fire alarms not being repairable if the board was broken + - bugfix: People without eyes and ears are no longer susceptible to flashbangs they + aren't directly on top of + Robustin: + - rscadd: Summoning Nar'Sie now triggers a different ending. No shuttle is coming! + Survivors must escape on a pod or survive the Red Harvest for 3 minutes. If + Nar'Sie acquires enough souls, the round ends immediately with a **special ending**. + - rscadd: New Harvester Sprite + - rscadd: Harvesters can now track a random survivor on the station, then switch + back to tracking Nar'Sie, via a new action button. + fludd12: + - rscadd: You can now add grills to a bonfire, letting you cook things on top of + them. +2017-05-17: + 4dplanner: + - bugfix: revenant respawning will not spam up deadchat so much, and is less likely + to break. + Expletive: + - rscadd: Syndicate Tomes have been added to traitor uplinks for 9 TC. They let + an agent or an operative provide both weal and woe. + Penguaro: + - bugfix: Centcom Engineering has reviewed the power schematic for the engine room + and added an Area Power Controller. + coiax: + - balance: Magic eightballs are now tiny items, able to fit into a box and pocket. +2017-05-18: + Joan: + - rscadd: Proselytizing alloy shards will now proselytize all the shards in the + tile, instead of requiring you to proselytize each one at a time. + Lordpidey: + - tweak: Space ninjas now use action buttons instead of verbs for a more consistent + user experience. + - rscadd: Toy toolboxes with realistic rumbling action have been added to arcade + prizes. + 'Tacolizard Forever: Plasmaman Powercreep': + - tweak: Plasmaman tanks are the same size as emergency oxygen tanks. + coiax: + - rscadd: Syndicate agents can purchase a "codespeak manual", that teaches them + a language that sounds like a series of codewords. You can also hit other people + with the manual to teach them. One use per manual. + - rscadd: Nuclear operatives have access to a deluxe manual that is more expensive + but has unlimited uses. + - rscadd: Syndicate AIs know Codespeak for free. + - bugfix: Spacevines can no longer spread on space transit turfs. + - balance: Plastic explosives can no longer be detonated by EMPs. + - rscadd: Various vending machines, when shooting their inventory at nearby people, + will "demonstrate their products features". This means that if a cigarette vending + machine throws a lighter at you, it will be on. Vending machines also choose + random products when throwing, rather than the first available one. + kevinz000: + - rscadd: Peacekeeper cyborgs now have projectile dampening fields. +2017-05-19: + 4dplanner: + - balance: the Hierophant club has gained in power +2017-05-20: + Joan: + - balance: Proto-kinetic crushers have been worked over by our highly qualified + techs, will recharge 12% faster, and no longer require very low-pressure atmospheres + to fire! + - balance: In addition, our techs have tweaked the quantum linker module and proto-kinetic + crushers can apply multiple marks to different targets! Marks applied may eventually + expire if not detonated. + Steelpoint: + - rscadd: All Pulse weapons now accurately show, by their sprites, what fire mode + they are in. + - rscadd: ERT, non-red alert, Security Response Officers spawn with a Tactical Energy + Gun. This is a military variant of the Egun that, in addition to laser and disable + rounds, has access to stun rounds. + - tweak: Pulse Pistols can now be recharged. + Swindly: + - rscadd: Added modified syringe guns. They fire DNA injectors. Geneticists and + CMOs can buy them from the traitor uplink for 14 TC. + coiax: + - rscadd: When a shuttle is called, sometimes an on-call admiral, using available + information to them, will recall the shuttle from Centcom. + octareenroon91: + - bugfix: Golems touching a shell can now choose to stay in their own body. +2017-05-21: + Gun Hog: + - bugfix: The Auxiliary Base can no longer land outside the lavaland map's boundaries. + RandomMarine: + - tweak: Drone laws no longer restrict drones to the station. + Steelpoint: + - rscadd: The Warden's Cycler Shotgun has been replaced with a Compact Combat Shotgun. + A unique weapon, it can fit in armour slots but at the sacrifice of a smaller + ammo capacity of four shells. +2017-05-22: + Joan: + - tweak: Resonator fields now visually show how long they have until they burst. + - bugfix: Hitting a legion skull with a resonator will now produce a field. + - balance: Swapped how far plasma cutter blasts go when going through rock and in + open air. This means blasts through air will go 4/5 tiles, but will mine 7/10 + tiles, for normal/advanced plasma cutters, respectively. + - tweak: There is now a buffer zone between the mining base and lavaland where megafauna + will not spawn. + - tweak: Ruins will no longer spawn directly in front of the mining base. + Lzimann: + - rscadd: Pandemic is now tgui! + Robustin: + - rscadd: Gang influence is now decentralized, each gangster has their own influence + that they can increase by spraying (and protecting) their tags and new influence-enhancing + bling. + - rscadd: Gang uniforms are now created based on your gang's color and can be purchased + by any gang member. They will increase the wearer's influence and provide protection, + but will make it fairly obvious which gang you belong to. + - rscadd: Gangs have access to a new surplus rifle; it is a semi-automatic rifle + that is very bulky and has a very low rate of fire. Gang members can buy this + gun for just 8 influence. + - rscadd: Gangs have access to the new machine gun turret; it unleashes a volley + of bullets with an extended view range. It does not run out of ammo, but a significant + delay between volleys and its stationary nature leaves the gunner vulnerable + to flanking and return fire. Holding down the trigger will allow you to aim + the gun while firing. It will cost gangs 50 influence. + - rscadd: The sawn-off improvised shotgun is now available to gangs for 6 influence. + With buckshot shells being easy to produce or purchase, this gun gives the most + "bang for your buck" but its single-shell capacity will leave you vulnerable + during a pitched gunfight. + - rscadd: The Wetwork boots give gangs access to a lightly armored noslip variant. + - tweak: The armored gang outfits are now slightly more resistant to ballistic and + bomb damage + Swindly: + - balance: Monkeys can be weakened by stamina loss + kevinz000: + - bugfix: Nanotrasen decided to remove the integrated jet engines from jetpacks. + They can no longer be used successfully indoors. +2017-05-23: + ClosingBracket: + - spellcheck: Fixed very minor inconsistencies on items & punctuation on items. + Joan: + - rscdel: Nanotrasen has taken a lower bid for their meson suppliers, and meson + scanners will no longer display terrain layouts while on the planet. + - tweak: However, they have discovered that, with some tweaks, mineral scanners + will no longer actually require you to be wearing mesons. + - tweak: The cheaper mesons will not completely remove reliance on light. + - tweak: Ripleys will collect all ore in front of them when they move with a clamp + and stored ore box. + - tweak: Chasms will glow dimly, like lava. + Joan, Repukan: + - rscadd: Traitor miners can now buy up to 2 KA Pressure Mods for 5 TC each. + - balance: KA Pressure Mods now only take up 35 mod capacity each, allowing traitor + miners to use 2 and have space for 1 other mod. + - rscdel: R&D can no longer build KA Pressure Mods. + Robustin: + - rscadd: Added a sexy new icon for the harvester's AOE conversion spell + - bugfix: Fixed construct's forcewall being invisible + - bugfix: Fixed cult constructs "Locate Master" and "Locate Prey" not functioning + - bugfix: Fixed spell action buttons not showing their actual availability status + - tweak: Changed the duration of a few frames for the new Cult ending + Steelpoint: + - rscadd: Auto Rifle alt ammo mags (AP, Incendiary, Uranium Tipped) now have a coloured + stripe to denote them. + That Really Good Soda Flavor: + - bugfix: Martial arts are no longer lost when mind-swapping, cloning, moving your + brain, et cetera. + - bugfix: Fixed a bug where paper bins could swallow up pens into the void. + coiax: + - rscadd: Galactic Common has been added to silicon's internal language database, + meaning even if a cyborg is created from someone who previously did not know + Galactic Common, they will be able to speak it as a silicon. + kevinz000: + - bugfix: Spessmen seems to have stopped suffering from the mental condition that + makes them believe they can't move fast if they have only one leg, even if they're + in space and using a jetpack! + ma44: + - rscadd: Reports of syndicate base on lavaland has been outfitted with a state + of the art donksoft toy weapon dispenser. +2017-05-24: + Joan, WJohnston: + - rscadd: Adds marker beacons to mining as a vendible item. They can be bought in + stacks of 1, 10, and 30 at a rate of 10 points per beacon. + - rscadd: Miners start with a stack of 10 in their backpack, and the Extraction + and Rescue Kit contains a stack of 30. + - rscadd: Marker beacons come in a large selection of colors and simply light up + a small area when placed, but are useful as a path marker or to indicate dangers. + QualityVan: + - rscadd: Hairless hides now become wet when exposed to water + - rscadd: You can microwave wet leather to dry it + - bugfix: Inserted legion cores no longer work if they went inert before implanting + Steelpoint: + - rscadd: Sketchin alternative magazines (Armour Piercing, Hollow Point, Incendiary) + now have unique sprites to better identify them. + - rscadd: ERT Sec Tactical Energy Guns now have a unique sprite. + - tweak: Changes to production of Nanotrasen Auto Rifle armour piercing bullets + have now made AP bullets better able to penetrate armour, but at the cost of + the amount of possible damage the bullet can do to soft targets. + - rscadd: Many Ballistic weapons now have new sounds related to reloading or placing + bullets into magazines. + - rscadd: Boxstation armoury weapon racks now have glass panes to help prevent the + weapons easily flying out of a breached hull. + - bugfix: Fixed Battleship Raven's bridge blast doors not working. + Tacolizard: + - tweak: Station based armour is slightly more descriptive of what it does. + That Really Good Soda Flavor: + - tweak: Changed spray tan overdoses to be more realistic. + - rscadd: People who are high and beach bums can now talk in their own stoner language. + - tweak: Beach bums can only communicate with other beach bums and people who are + high. +2017-05-25: + 4dplanner: + - bugfix: crushers now apply marks properly + - rscadd: 20% of internal affairs agents are actually traitors + 4dplanner, robustin: + - bugfix: c4 has always taken 3 seconds to plant, and you are not allow to believe + otherwise + Crexfu: + - spellcheck: typo fix for origin tech + Cyberboss: + - experiment: Explosions will no longer have a start up delay + - bugfix: Indestructible objects can no longer be destroyed by bombs + Oldman Robustin: + - tweak: Gang mode now calls a 4 minute unrecallable shuttle once 60% of the crew + is dead + ohnopigeons: + - balance: The cost of plasma has been reduced from 500 to 300, but retain their + immunity to saturation +2017-05-26: + Moonlighting Mac says: + - rscadd: You can now craft a strong cloak with a hood made out of goliath and monster + materials from within the primitive crafting screen. + - rscadd: The cloak has a suit slot for all kind of primitive supplies, however + it cannot carry most electronic miner equipment. + - balance: Due to the recipe requiring leather, it is not normally accessible to + all ghost roles without a source of water & electricity. + kevinz000: + - rscadd: You can now add bayonets to kinetic accelerators. However, only combat + knives and survival knives can be added. Harm intent attacking things will cause + you to attack that thing with the bayonet instead! +2017-05-28: + ClosingBracket: + - tweak: Allows explorer webbings to hold marker beacons. + Expletive: + - tweak: E-Cigarettes can now fit in your pocket. + Iamgoofball: + - bugfix: After the Syndicate realized their top chemist was both mixing a stamina + destroying drug with a stimulant to avoid slowdowns entirely in their sleepypens, + they fired him and replaced him with a new chemist. + Joan: + - rscadd: Miner borgs can now place marker beacons from a storage of 30. + - bugfix: Necropolis tendrils will once again emit light. + - rscadd: The kinetic crusher can now gain bonus effects via trophy items gained + by killing bosses with it. + - rscadd: Yes, you do have to kill the boss primarily doing damage via the kinetic + crusher, or you won't get the trophy item and the bonus effect it grants. + Kor: + - bugfix: The chaplains possessed blade, shades, and constructs, can once again + speak galactic common. + QualityVan: + - bugfix: Bayonets can now be used for butchery + - tweak: Cloning pods which are interrupted by a emagging will now produce a slightly + lumpier smoothie + - bugfix: Cloning pods that have stopped cloning early can no longer be broken open + to extract leftover parts + - bugfix: Crew monitoring consoles once again have minimaps while you're on the + station level + Steelpoint: + - rscadd: A New Iron Hawk troop transport ruin has been added to lavaland. Can the + sole surviving Marine somehow survive the horrors of lavaland? Lore fluff included. + - rscadd: Central Command has listened to complaints and, as such, has now stationed + "real" Private Security Officers at centcom docks. + - rscadd: A new Nanotrasen Security Officer NPC variant is available to admins, + this 'peaceful' version will only attack people who attack it first. Great for + keeping order. + Swindly: + - bugfix: fixed not being able to attach heads without brainmobs in them + cacogen: + - rscadd: You can now rename dog beds by buckling a new owner to them + - rscadd: Dogs that spawn in an area with a vacant bed will take possession of and + rename the bed + - rscadd: Adds AI follow links to holopad speech and PDA messages. Note that PDA + messages point to the owner of the PDA and not the PDA's actual location. + - bugfix: Fixes PDA icon not showing up beside received messages for AIs + kevinz000: + - rscadd: Nanotrasen's new titanium wall blueprints are smooth enough that it can + reflect projectiles! +2017-05-29: + Joan: + - spellcheck: Renames hivelord and legion cores to 'regenerative core'. Their descs + have also been updated to be more clear. + Nanotrasen Plasmaman Outreach Division: + - tweak: plasmaman tank volume has been increased from 3 to 6. + XDTM: + - balance: Abductors have learned how to properly delete the memories of their test + subjects. + bandit: + - tweak: The officer's sabre standard in Nanotrasen captain rollouts can be used + to remove the tails of lizard traitors, or lizards in general. + oranges: + - rscadd: AI's can now hang up all holocalls at a station with alt+click +2017-05-30: + Expletive: + - rscadd: Luxury versions of the bluespace shelter capsule are now available! Purchase + them at the mining equipment vendor. + - rscadd: 'Cardboard cutouts have a new option: Xenomorph Maid' + - rscadd: Black Carpet can now be crafted using a stack of carpet and a black crayon. + - rscadd: Black fancy tables can now be crafted using Black Carpet. + - rscadd: Shower curtains can now be recoloured with crayons, unscrewed from the + floor, disassembled with wire cutters, and reassembled using cloth, plastic, + and a metal rod. + kevinz000: + - rscadd: Research and Development have recieved designs for new prototype Beam + Marksman Rifles. These rifles require a short aiming cycle to fire, however, + have extreme velocity over other weapons. + - experiment: Aiming time is 2 seconds, hold down mouse to aim, aiming time increases + if you change your aim based on angle changed, or if you move while aiming. + The weapon can not be fired while unscoped. + - rscdel: However, someone tripped and pulled out the power cord while your servers + were being updated with the latest revision of accelerator laser cannons. All + data have been lost... diff --git a/html/changelogs/archive/2017-06.yml b/html/changelogs/archive/2017-06.yml new file mode 100644 index 0000000000..2c3d4ee85c --- /dev/null +++ b/html/changelogs/archive/2017-06.yml @@ -0,0 +1,517 @@ +2017-06-02: + Cyberboss: + - experiment: New server backend! + - tweak: Test merged PRs now show the commit of the PR at which they were merged + Expletive: + - rscadd: Adds the NT75 Electromagnetic Power Inducer, a tool which can be used + to quickly recharge many devices! They can be found in Electrical Closets, the + CE's locker, ordered by cargo, or created in RnD. + Goodstuff: + - bugfix: Fixes the crafting recipe for black carpet + - bugfix: Removed a random white dot on the black carpet sprite + Joan: + - rscadd: Goliaths, Watchers, and Legions have a small chance of dropping a kinetic + crusher trophy item when killed with a kinetic crusher. Like the boss trophy + items, these give various effects. + - tweak: Kinetic crushers recharge very slightly slower. + - rscadd: Three unique Kinetic Accelerator modules will now appear in necropolis + chests. + MMMiracles (Cerestation): + - rscadd: CereStation's Security department has been overhauled entirely thanks + to the tireless efforts of Nanotrasen's construction division. + Nanotrasen Mining Alert: + - rscadd: Nanotrasen's mining operations have created far more corpses than an entire + galaxy of cooks could hope to deal with. To solve this, we decided to just dump + them all from orbit onto the barren lava planet. Unfortunately, the creatures + called "Legion" have infested a great number of them, and you can now commonly + find the bodies of former Nanotrasen employees left behind. Additionally, there + are reports of natives, other settlers, and even stranger things found among + the corpses. + QualityVan: + - tweak: The tactical rigging in op closets is more tacticool + Shadowlight213: + - balance: The reset wire on borgs must now be cut to reset a borg's module instead + of pulsed. + - tweak: Portable pump max pressure has been lowered. + Steelpoint: + - tweak: Iron Hawk Marine no longer has Centcom all access. My mistake. + - bugfix: Fixes Iron Hawk marine carbine not having a visible sprite. + Swindly: + - balance: Nitrous oxide no longer produces water as a by-product, requires 2 parts + ammonia instead of 3, and produces 5 parts when made instead of 2. + kevinz000: + - experiment: Gang turrets now follow the mouse of the person using them! Yay! + octareenroon91: + - bugfix: Attempts to add items to a storage container beyond its slots limit will + now obtain a failure message again. +2017-06-03: + Expletive: + - tweak: Chem Dispensers now store their power in their batteries. + - tweak: Instead of being based on battery and capacitor ratings, recharge delay + for portable chem dispensers is now based on their capacitor and matter bin + ratings. + - tweak: The Seed Vault's chemical dispenser now has all the chemicals a pod person + could want. + - rscadd: The crafting menu now has subcategories! + - rscadd: Food recipe categories have been combined as subcategories of the Foods + category. + - rscadd: Weaponry and Ammunition have been combined as subcategories of the Weaponry + category. + Improvedname: + - rscadd: Janitors now start with a flyswatter + Mothership Epsilon: + - tweak: All your base are belong to us. + Penguaro: + - bugfix: '[Box] Removes extra/unattached vent from Xeno Lab' + Planned Spaceparenthood: + - bugfix: We would like to apologize for mislabeled cloning pod buttons. + WJohnston: + - bugfix: Deltastation's south nuke op shuttle location should no longer be possible + to teleport into by moving off the map and back on, and moved the rest closer + to the station. + p440: + - bugfix: Fixed duping cable coils with magic APC terminals + - bugfix: Fixed invalid icon state for empty APCs +2017-06-04: + Expletive: + - rscadd: Many stacks now update their sprite based on their amount. + - rscadd: Stacks will now weigh less if they're less than full. + - imageadd: Added new icon states for glass, reinforced glass, metal, plasteel, + plastic, plasma, plastitanium, titanium, gold, silver, adamantine, brass, bruise + packs, ointment, gauze, cloth, leather, wet leather, hairless hide, human hide, + ash drake hide, goliath hide, bones, sandstone blocks, and snow blocks. + - tweak: Some lavaland stacks' max amounts have been reduced. + - bugfix: Bulldog Shotguns should update their sprite properly when you remove the + magazine. + - bugfix: Riot suits no longer hide jumpsuits. + Joan: + - balance: Rod Form now costs 2 points, from 3. + - balance: Rod Form now does 70 damage, from 160, but gains 20 damage, per upgrade, + when upgraded. This means you'll need to spend 6 points on it to instantly crit + people from full health. + Swindly: + - balance: Chemical grenades are no longer permanently disabled after being unlocked + by wirecutters after being primed. +2017-06-05: + Expletive: + - rscadd: The Ore Redemption Machine has been ported to TGUI. New features include + the addition of "Release All" and "Smelt All" buttons. + - rscadd: The Ore Redemption Machine now be loaded with sheets of material. + - rscadd: The Ore Redemption Machine can now 'smelt' Reinforced Glass. + Joan: + - balance: Only human and silicon servants can help recite multi-invoker scriptures. + This means cogscarabs, clockwork marauders, and anima fragments DO NOT COUNT + for scriptures that require multiple invokers. + - balance: Clockcult scripture tiers can no longer be lost by dipping below their + requirements once they are unlocked. + - rscdel: Removes Revenant scriptures entirely. + MMMiracles: + - tweak: Deepstorage ruin has been redone to be more self-sufficient and up to better + mapping standards. +2017-06-06: + Joan: + - rscadd: Added a new unique Kinetic Accelerator module to necropolis chests. + - spellcheck: Renames Clockwork Proselytizers to Replica Fabricators. + - balance: Replica Fabricators can directly consume floor tiles, rods, metal, and + plasteel for power instead of needing to convert to brass first. + - balance: Cogscarabs can no longer use guns. + - tweak: KA modkits in necropolis chests are now design discs with designs for those + modkits, to force miners to bring back minerals. + PKPenguin321: + - bugfix: The fake pits that the arcade machines can vend now vend properly, for + real this time. + Robustin: + - rscadd: The cult master has finally acquired their 3rd spell, Eldritch Pulse. + This ability allows the cult master to quickly teleport any cultist or cult + structure in visual range to another tile in visual range. This spell has an + obvious spell effect that will indicate where the target has gone but without + explicitly revealing who the master is. This spell should assist with moving + obstinate cultists off an important rune, getting wandering cultists back onto + an important rune, save a cultist from an untimely arrest/summary execution, + assist in getting your allies into secure areas, etc. + - bugfix: The void torch now only works on items that have been placed on surfaces, + this prevents the inventory bugs associated with this item. + thefastfoodguy: + - tweak: you can burn your brains out with a flashlight if you're tired of life +2017-06-07: + Expletive: + - rscadd: New plasma medals have been added to the Captain's medal box. Don't get + them too warm. + - imageadd: New sprites for plasma medals. + - imageadd: Icon and worn sprites for all medals and the lawyer's badge have been + improved. Worn medals more closely match their icons. + - tweak: The bone talisman is an accessory again, so it's not useless. + - imageadd: It also has a new worn sprite, based on an arm band. + - imagedel: Ties have been removed from accessories.dmi and vice versa. Same for + the explorer's webbing sprites that were in there. ties.dmi is now neck.dmi, + and has sprites for scarves, ties, sthetoscopes, etc. + - tweak: Examining an accessory now tells you how to use it. + Joan: + - spellcheck: Renamed Volt Void to Volt Blaster. + - tweak: Volt Blaster does not consume power when firing and does not cause backlash + if you don't fire. + - balance: Volt Blaster does 25 damage, from 20-40 depending on power, and has 5 + shots, from 4, over its duration. + QualityVan: + - bugfix: Surplus rifles are no longer invisible while unloaded + Shadowlight213: + - balance: The Changeling Transformation Sting is once again stealthy. However, + it no longer transfers mutations. + - balance: The chemical cost of Transformation Sting has been increased to 50 +2017-06-08: + 4dplanner: + - bugfix: traitors show up on antagHUD + Expletive: + - tweak: The detective's flask has Hearty Punch instead of whiskey. + - bugfix: The Detective's fedora no longer clips with hair. + - imageadd: Adds 91 new sprites to fix clipping issues with the Detective's fedora + and hair. + - imageadd: Change the standard fedora to match the detective and treasure hunter + variants. + - tweak: Detective, Treasure Hunter, and standard fedoras now all benefit from new + sprites. + Joan: + - balance: Tinkerer's Daemons are no longer totally disabled if you drop below the + servant requirement. + - balance: Instead, Tinkerer's Daemons will disable until the number of active daemons + is equal to or less than one-fifth of the living Servants. + - tweak: Tinkerer's Daemons produce components very slightly slower. + - rscadd: Added Prolonging Prism as an application scripture. + - balance: Prolonging Prism will delay the arrival of an emergency shuttle by 2 + minutes at the cost of 2500W of power plus 75W for every 10 CV and 750W for + every previous activation. In addition to the high cost, it very obviously affects + the shuttle dock and leaves an obvious trail to the prism. + - balance: Script scripture now requires 6 Servants to unlock, from 5, and Application + scripture now requires 9 Servants to unlock, from 8. + Lzimann + Cyberboss: + - experiment: Ported goonchat. Much less laggy and crashy than BYOND chat. + Frills! + NanoTrasen Public Relations Department: + - rscadd: A mining accident has released large amounts of space dust, which is starting + to drift near our stations. Don't panic, it's probably safe. + Nanotrasen Plastic Surgery Advert: + - rscadd: Are you a mutant? Were you born hideously deformed? Do you have ears growing + out of the top of your head? Or even a tail? Don't worry, with our patented + surgical techniques, Nanotrasen's highly trained medical staff can make you + normal! Schedule an appointment, and one of our surgeons can see you same day. + - balance: Cat ears now give you double the ear damage. + QualityVan: + - bugfix: Cremators now still work when there's only one thing in them + - bugfix: The ORM now uses the intended amount of resources when making alloys + - rscdel: Cyborgs can no longer alt-click their material stacks to split them + Robustin: + - balance: The blood cult can only attempt to summon Nar-Sie in one of three rooms + that are randomly selected at round-start. + Shadowlight213: + - rscadd: Tracking implants and chem implants have been added to rnd + - rscdel: Adrenaline and freedom implants have been removed from rnd + Xhuis: + - tweak: Defibrillator paddles will no longer stick to your hands, and will snap + back onto the unit if you drop them somehow. + lzimann: + - rscdel: Xeno queens can no longer be maids + oranges: + - rscadd: Added stungloves to the brain damage lines +2017-06-09: + Nanotrasen Shiny Object Appreciation Club: + - rscadd: The RD and HoS now receive medal lockboxes in their lockers, containing + science and security medals, respectively. + Tacolizard and Cyberboss, idea by RandomMarine: + - rscadd: You can now add a commendation message when pinning a medal on someone. + - rscadd: Medal commendations will be displayed when the round ends. + - tweak: Refactored the outfit datum to allow accessories as part of an outfit. + - bugfix: The Captain spawns with the Medal of Captaincy again. + TrustyGun: + - rscadd: Some of the clown's toys have been moved into a crate in the theater. + If you think you are missing something, check in there. + - rscadd: Wooden crates have been added. You can construct them with 6 wooden planks, + and deconstruct them the same way as regular crates + oranges: + - tweak: Security minor and major crime descriptors are now a single line input, + making it easier to add them + - tweak: Medical record descriptions are single inputs now +2017-06-11: + Expletive: + - imageadd: Glass tables are shinier + Nanotrasen Consistency Affairs: + - bugfix: You no longer see yourself in place of the user when examining active + Spirit Sight runes. + Shadowlight213: + - bugfix: Cloning dismembered heads and brains now respects husking and other clone + preventing disabilities. + WJohn: + - bugfix: It is now easier to wire the powernet into box's telecomms SMES cell. + Xhuis: + - rscadd: You can now pin papers and photos to airlocks. Anyone examining the airlock + from up close can see the details. You can cut them down with wirecutters. + lordpidey: + - rscadd: Added F.R.A.M.E. cartridge to uplinks. This PDA cartridge contains 5 + viruses, which when used will unlock the target's PDA into a syndicate uplink, + in addition, you will receive the code needed to unlock the uplink again, if + you so desire. + - rscadd: If you use telecrystals on a F.R.A.M.E. cartridge, the next time it is + used, it will also give those crystals to the target uplink. + octareenroon91: + - bugfix: Mecha tools now respond to MMI control signals as intended. + shizcalev: + - tweak: '"Species immune to radiation are no longer compatible targets of radiation + based DNA injectors."' + - bugfix: '"A gun''s firing pin will no longer malfunction when placed into your + own mouth. Phew!"' + - imageadd: '"Bedsheets capes are now slightly more accurate. Be jealous of the + clown and their sexy cape!"' +2017-06-13: + Expletive: + - tweak: Paper planes are now the same color as the paper used to make them. + - bugfix: Flashdarks can no longer be used to examine head based organs. + Fox McCloud: + - tweak: Tweaked game options animal speed value to match live server + Joan: + - spellcheck: Renamed AI liquid dispensers to foam dispensers. + - tweak: Foam dispensers now activate immediately when clicked, rather than forcing + the user to go through a menu. They also have better visual, message, and examine + feedback on if they can be activated. + MrStonedOne: + - experiment: Added some code to detect the byond bug causing clients to send phantom + actions shortly after connection. It will attempt to fix or work around the + issue. + Nanotrasen Robotics Department: + - rscadd: To aid in general-purpose cleaning and maintaining of station faculties, + all janitor cyborgs are now outfitted with a screwdriver, crowbar, and floor + tile synthesizer. + WJohnston: + - bugfix: Survival bunker ruin's power now works, mostly. + shizcalev: + - tweak: '"Radiation immune species are now incompatible with the radiation based + genetics DNA scanner/modifier."' +2017-06-14: + Expletive: + - rscadd: The medalboxes are now fancy. + - imageadd: New sprites for opened medal boxes. + Joan: + - tweak: Being converted to clockcult will briefly cause your world to turn yellow + and you to hear the machines of Reebe, matching the description in the messages. + - spellcheck: The messages for being converted and for failing conversion to clockcult + have been updated. + Tacolizard: + - bugfix: Flamethrowers no longer say they're being ignited when you extinguish + them +2017-06-17: + Cyberboss: + - tweak: NT now provides education on the proper response for experiencing the excrutiating + pain of varying degree burns (You scream when burning) + Expletive: + - rscadd: The Captain now starts with a deluxe fountain pen in their PDA. + - rscadd: The quartermaster, curator, research director, lawyer, and bartender start + with normal fountain pens in their PDAs. + - rscadd: Cargo can order fountain pens via the Calligraphy Crate. + - rscadd: Nerds on the station will be pleased to know they now have pocket protectors. + - bugfix: Cryo cells work properly on mobs with varying max health values. + Joan: + - rscdel: Cultists must be human to run for Cult Master status. + - tweak: The Hierophant is a little less chaotic and murdery on average. + LanCartwright: + - rscadd: Penguins, penguin chicks, penguin eggs. + - rscadd: Penguin family to Winter Wonderland. + MrStonedOne and Lummox JR: + - bugfix: Fixed icon scaling and size preferences not loading (Technically size + preferences were loading because byond saves that locally, but that's not reliable + because ss13 shares a hub) + QualityVan: + - rscadd: The botany vending machine now has a stock of onion seeds + RandomMarine: + - tweak: RCDs now always use matter consistent with the material needed when building. + - tweak: Floors now cost 3 or 1 matter to build, based on if a lattice exists on + the tile. + - tweak: Reinforced windows cost 12 matter. Normal windows cost 8 matter. (Both + up/down from 10) + - tweak: Glass airlocks cost 20 matter. + - tweak: RCDs are faster at building grilles and plain glass windows. + Steelpoint: + - tweak: Slightly reshuffles the Head of Security's, and Research Directors, locker + to place fluff items below essential items. + Tacolizard: + - rscdel: Flashes no longer have a tech requirement + That Really Good Soda Flavor: + - bugfix: High luminosity eyes will have material science instead of an error research + type + Thunder12345 and Improvedname: + - rscadd: You can now turn severed cat tails and ears into genuine kitty ears + - rscadd: Cat tails can now be used to make a cat o' nine tails, similarly to the + liz o' nine tails. + Xhuis: + - spellcheck: The names of the hand drill, jaws of life, and emitter are now lowercase. + - spellcheck: The descriptions of the hand drill, jaws of life, and emitter have + been changed to be more descriptive and less lengthy. + - rscadd: Tablets with IDs in them now show the ID's name when examining someone + with that tablet in their ID slot, similar to a PDA would. + bandit: + - tweak: Default short/medium/long brig times are now, in order, 2, 3, and 5 minutes. +2017-06-18: + Expletive: + - tweak: Stacks of space cash now tell you their total value and their value per + bill when you examine them. + RandomMarine: + - tweak: Compressed matter cartridge production costs now reflect their material + worth at basic efficiency. + - bugfix: Compressed matter cartridges can now be exported. + Xhuis: + - bugfix: Puny windows will no longer stop the progress of Ratvar. +2017-06-19: + Expletive: + - rscadd: Paper frames can be created using wood and paper, and can be used to create + decorative structures. + - rscadd: Natural paper can now be crafted + - rscadd: KorPhaeron can now start a maid cafe, if they so desire. + - rscadd: Thanks to the invention of "Bill slots", vending machines can now accept + space cash. + - tweak: The Clown and Mime can now find their unique crayons stored inside their + PDAs + LanCartwright: + - rscadd: 1D4 into Lavaland Mining base crate. + RandomMarine: + - tweak: Bonfires now work on lavaland! + Tacolizard: + - rscadd: Repurposed the action button tooltip code to add tooltips with the examine + details of all held and equipped items. Hover your mouse over any item equipped, + held or in your inventory to examine it. + - rscadd: Examine tooltips can be toggled with the 'toggle-examine-tooltips' verb, + which can be typed or accessed from the OOC menu. + - rscadd: You can change the delay before a tooltip appears with the 'set-examine-tooltip-delay' + verb, also accessible via the OOC menu. The default delay is 500ms. +2017-06-20: + Bawhoppen: + - bugfix: Grenade belts and bandoliers will no longer obscure half the screen when + they're completely filled. + LanCartwright: + - rscdel: Removed loot drops from Syndicate Simple mobs. + Tacolizard: + - rscadd: Some items now have custom force strings in their tooltips. + - bugfix: items with no force can still use a custom force string. + Xhuis: + - bugfix: The station's heaters and freezers have been sternly reprimanded and will + now drop the correct circuit boards and cable coils. + - rscadd: The straight jacket now takes five seconds to put on. + - bugfix: The display cases in luxury shelter capsules will no longer spawn unobtainable, + abstract offhand objects. + - bugfix: Disablers now have an in-hand sprite. + nicbn: + - imageadd: Changed cryo sprites to Bay cryopods, which show the person inside of + them. +2017-06-22: + Bawhoppen: + - rscadd: Dressers are now constructable, and unanchorable with a wrench. + ClosingBracket: + - spellcheck: Fixes small typographical errors on flight suits and implanters. + Ergovisavi: + - tweak: Nanofrost setting and metal foam synthesizer on the Atmos watertank backpack + changed to "Resin", which is a solid, but transparent structure similar to metal + foam that scrubs the air of toxins, regulates temperature, etc + - tweak: Atmos holobarrier device swapped out for an Atmos holo-firelock device, + which creates holographic firelocks that prevent atmospheric changes from going + over them + Expletive: + - tweak: Flame thrower plasma tanks can be removed with alt-click. + Lordpidey: + - bugfix: True and arch devils are no longer deaf. + - bugfix: Fixed some edge cases with devils getting two sets of spells. + - bugfix: True/arch devils can now instabreak cuffs. + - rscadd: The codex gigas now indicates if a devil is ascendable or not. + - tweak: Hellfire has been buffed, it now explodes multiple times. + Nanotrasen Robotics Department: + - tweak: Traitor AIs' malfunction modules have received a firmware update and are + more responsive, with HUD buttons and more sensible menus. + - tweak: Overload and Override Machines now function differently; instead of right-clicking + a machine to choose a context menu option, you activate the ability, which lets + you left-click on a machine to overload or override it. This also changes your + cursor. + Xhuis: + - rscadd: Alt-clicking the Show/Hide Actions button will now reset the positions + of all action buttons. + - rscadd: Hints to the two shortcuts for action buttons are now included in the + Show/Hide Actions button's tooltip. + - rscadd: (As a reminder, that's shift-click to reset the clicked button, and alt-clicking + the Show/Hide Actions button to reset it and all the others!) + - spellcheck: The names of several objects, such as the holopad and biogenerator, + have been lowercased. + - spellcheck: Added some descriptions to a few objects that lacked them. + - rscadd: Tablets now have a built-in flashlight! It can even change colors, as + long as they're light enough in hue. + bandit: + - rscadd: Nanotrasen researchers have made the breakthrough discovery that Lavaland's + plants are, in fact, plants, and can be harvested with seed extractors. + ohnopigeons: + - bugfix: After a janitorial audit Nanotrasen has decided to further cut costs by + removing the janicart's secret space propulsion functionality +2017-06-23: + BeeSting12: + - bugfix: The clowndagger now has the correct skin. + MrStonedOne: + - tweak: Makes old chat show while goonchat loads. Should goonchat fail to load, + the old chat will still be operational. +2017-06-25: + Expletive: + - rscadd: Adds the skull codpiece, which can be crafted from parts of lavaland monsters. + - rscadd: Maid Costume aprons can now be detached and reattached to any uniform. + Improvedname: + - rscadd: You can now export cat ears/tails for 1000 credits + JJRcop: + - bugfix: Fixed telekinesis remote item pick up exploit + Kor: + - rscadd: Robotic legs now let you use pockets without a jumpsuit, and a robot chest + now lets you use the belt slot and ID slot without a jumpsuit. + RandomMarine: + - rscadd: Cargo can now export mechs! + Steelpoint: + - rscadd: Station Engineers spawn with a Industrial Welder in their toolbelt. + - tweak: Engineering Welder Locker now only holds three standard Welders. + - rscadd: An old Nanotrasen Space Station has quietly reawoken its surviving crew + one hundred years after they fell to slumber. Can the surviving crew, using + old, broken and out of date equipment, overcome all odds and survive, or will + the cold embrace of the stars become their new home? + - tweak: Nanotrasens Corps of Engineers has refitted and refurbished NTSS Boxstations + Engineering area into, what Centcom believes, a more efficient design. + That Really Good Soda Flavor: + - experiment: Added the ability for a holiday to start on the nth weekday of a month. + - experiment: Allahu ackbar! Added the ability to calculate Ramadan. + - rscadd: Added Thanksgiving, Mother's Day, Father's Day, Ramadan, and Columbus + Day to the possible holidays. + - bugfix: Fixed nuclear bombs being radioactive. + Xhuis: + - rscadd: You can now unfasten intercoms from walls and place them elsewhere on + the station. + - rscadd: Intercom frames can now be created at an autolathe for 75 metal and 25 + glass. + - bugfix: Nearly-full goliath hide stacks now correctly have a sprite. +2017-06-27: + Ergovisavi: + - bugfix: Fixed a few anomalous crystal effects + - bugfix: Fixes stacking atmos resin objects in a single tile + - tweak: Lasers now go through atmos resin objects + Joan: + - tweak: The Necropolis has been rethemed. + Kor: + - rscadd: Added dash weapons, which let you do a short teleport within line of sight. + - rscadd: The ninjas energy katana now lets him dash. He can no longer teleport + with right click. + - rscadd: Glass shards will no longer hurt people with robotic legs. + - rscadd: Mesons work on lavaland again. + Xhuis: + - spellcheck: The names of most glasses, like mesons, t-ray scanners, and night + vision goggles, have been lowercased. + - spellcheck: The thermonocle's description now changes based on the gender of the + person examining it. + - bugfix: Straight jackets can now properly be put onto others. + drline: + - bugfix: Nanotrasen finally sent out IT personnel to plug your modular consoles + back in. You're welcome. +2017-06-28: + Cyberboss: + - rscdel: Cortical borers have been removed + Shadowlight213: + - rscadd: There is now a new monitor program that engineers can use to monitor the + supermatter status + Tacolizard: + - rscadd: NanoTrasen has now outfitted their employees with Extra-Loud(TM) Genetically + Modified Hearts! Now you can hear your heart about to explode when the clown + shoots you full of meth, or hear it slowly coming to a stop as you bleed out + in critical condition after being toolboxed by an unknown gas-mask wearing assistant. diff --git a/html/changelogs/archive/2017-07.yml b/html/changelogs/archive/2017-07.yml new file mode 100644 index 0000000000..df6eab55f4 --- /dev/null +++ b/html/changelogs/archive/2017-07.yml @@ -0,0 +1,318 @@ +2017-07-07: + Ergovisavi: + - tweak: Added a recovery window after some variable length megafauna attacks + - rscadd: Adds a new mob to the game, the "leaper" + - rscadd: Adds another planetstation mob, the "wanderer/mook" to the backend + - bugfix: Fixes a problem with player controlled leapers where they occasionally + can't fire + Joan: + - tweak: Rethemes the ash walker nest to match the Necropolis. + - balance: Chasms, asteroid turfs, basalt, and lava can no longer be made wet. + - rscadd: A strange new Resonant Signal has appeared on lavaland. + - tweak: Dreams while sleeping are now slightly longer on average and will contain + more possibilities. + - rscadd: Bedsheets may affect what you can dream. + Lexorion: + - imageadd: The portable PACMAN generators now have new icons, including on and + off states. + More Robust Than You: + - rscadd: Nanotrasen has added lids to their soda that POP! when opened. Up to 3 + possible sounds! + - bugfix: brain damage should no longer attempt to emote/say things while unconcious + NanoTrasen Smithy Department: + - soundadd: Tasked by corporate heads to make NanoTrasen's line of captain rapiers + flashier, a few brave smiths have managed to forge their steel in a way that + enhances their swords' acoustic properties. + Shadowlight213: + - rscdel: The majority of the tiny fans on Deltastation have been removed. + - tweak: Airlocks going to space, and secure areas like the bridge and sec on Delta + have been given the cycling system. + - balance: The freedom suit no longer slows you down and can withstand the FIRES + OF LIBERTY! + Steelpoint (Ancient Station): + - rscadd: Major changes to Ancient Station include new sounds for the prototype + RIG hardsuit, the NASA Engineering Voidsuit slowing the user down properly and + new insulated gloves in engineering. + - rscadd: Several minor changes, such as an extra oxygen tank, spawn in equipment + and minor tile changes. + Supermichael777: + - balance: The AI swap menu is now given to the person with the multi-tool rather + than the Borg. Old behavior remains for all non multi-tool sources + - bugfix: Borgs and shells now notify when un-linked due to the wire being cut. + Tacolizard: + - bugfix: Nanotrasen has begun a program to inform the souls of the departed that + their hearts can't beat after death. + - bugfix: heartbeat noises now loop (i can't come up with any dumb fluff for this + one sorry) + That Really Good Soda Flavor: + - bugfix: Martial arts will no longer be transferred in cloning, etc. if they are + temporary (i.e. wrestling, krav maga). + Xhuis: + - tweak: Recollection has been separated into categories and should be easier to + read and more informative. + - bugfix: Ratvar has been reminded that he hates Nar-Sie and will now actively pursue + fighting her. + - bugfix: You can now properly dig out plants from patches of soil. + - bugfix: Reskinnable guns no longer become invisible after firing a single shot. + - bugfix: The kinetic crusher and other forced two-handed objects can now correctly + be stored in a bag of holding. + - bugfix: Positronic brains' icons will now properly change depending on status. + - tweak: Positronic brains will now stop searching as soon as they're occupied. + - tweak: Positronic brains now have error messages if activating them fails for + whatever reason. + - bugfix: Unconscious Servants are now properly informed when they're deconverted. + - bugfix: The Voice of God no longer specifically targets creatures like constructs + and clockwork marauders. + - bugfix: Heartbeat sounds no longer play indefinitely if your body is destroyed. + kevinz000: + - rscadd: Headphones have been provided to the station in Autodrobes, mixed wardrobes, + and fitness wardrobes. Please use them responsibly, and remember to focus on + your job above all else! + - experiment: Headphones fit in head, ears, OR neck slots! + ohnopigeons: + - bugfix: Nanotrasen Electronics have fixed a bug where issued factory-fresh PDAs + did not link to their cartridges, requiring manual reinsertion. + shizcalev: + - balance: Nanotrasen has upgraded the obsolete teleporter consoles on most NT branded + stations with newer ones preloaded with the newest Supermatter monitoring application! + - soundadd: The supermatter base now has a speaker and will provide audio cues as + to it's current status! + somebody: + - rscadd: Strong plasma glass windows +2017-07-09: + Crexfu: + - tweak: 2 plasma sheets have been added to viro break room on box + More Robust Than You: + - bugfix: Plasma and Reinforced plasma glass no longer merge with Normal and Reinforced + Glass + Xhuis: + - bugfix: You can no longer catch objects that require two hands at all times with + only one hand. +2017-07-11: + RandomMarine: + - rscadd: Drones can now switch between help and harm intent. + Tacolizard: + - rscadd: Admins can now set a message/warning when they delay the round end, to + be shown to anyone who tries to reboot the world. + Tacolizard and Cyberboss: + - rscadd: Added two new organs, the liver and stomach. Without them, you won't metabolize + chemicals. + - rscadd: The liver is responsible for processing all chemicals except nutrients. + If your liver is removed, you will be unable to metabolize any drugs and will + slowly die of toxin damage. + - rscadd: Drinking too much alcohol or having too many toxins in you will damage + your liver, if it becomes too damaged, it will undergo liver failure and you + will slowly die of toxin damage. Your liver naturally heals a small amount of + its damage. However, it doesn't heal enough to offset stronger alcohols or large + amounts of toxins, at least until they are metabolized out of your body. + - rscadd: to conduct a liver transplant, inject corazone into the patient. Corazone + will prevent the patient from taking damage due to either not having a liver + or undergoing liver failure. Corazone will metabolize out of the patient quickly, + so at least 50u is recommended. + - rscadd: The stomach is responsible for metabolizing nutrients. Without a stomach, + you will be unable to get fat, but you will also be unable to process any nutrients, + meaning you will eventually starve to death. + Xhuis: + - bugfix: Mobs spawned by Necropolis curses are now immune to chasms. + - tweak: The BoxStation warden's office now has a crew monitoring console. + - imageadd: Clockwork slabs now show icons of the components used in scripture instead + of initials. + factoryman942: + - bugfix: Boxstation Robotics now has 6 flashes, from 2. + - bugfix: Metastation Robotics now has 40 sheets of glass, instead of 20. + shizcalev: + - tweak: The supermatter reporting system has been updated to report remaining integrity, + as opposed to how unstable the SM currently is. +2017-07-18: + BeeSting12: + - tweak: Deltastation's auxiliary storage in arrivals can be accessed by anyone + now. + - bugfix: Deltastation's cargo bay maintenance can now be accessed by cargo techs. + Dannno/Supermichael777/InsaneHyena: + - rscadd: You can now pick from a few different styles when augmenting someone with + robot parts by putting them in the augment manipulator. Alt+click to take parts + out. + Ergovisavi: + - bugfix: Fixed the refresher variant of the anomalous crystal making holodeck items + real + Fox McCloud: + - rscdel: blood and gibs on turfs can no longer infect nearby people + - tweak: Tuberculosis bypasses species virus immunity (it's not a virus!) + - tweak: Disease and appendicitis events no longer infect clientless mobs + - tweak: Disease event will no longer pick virus immune mobs + - tweak: Appendicitis event will no longer pick mobs without an appendix + - bugfix: Fixed changeling panacea curing non-harmful viruses + - bugfix: Fixes IV drips not properly injecting the right amount of blood + Joan: + - rscdel: Removed the Soul Vessel, Cogscarab, and Anima Fragment Scriptures. + - bugfix: The Ark of the Clockwork Justicar will still forcibly take up a 3x3 area + even if it still needs components to activate. + MrStonedOne & Fox-McCloud: + - tweak: Made pathfinding much quicker + NewSta: + - bugfix: Fixes the maid apron being invisible when in-hand or attached to the maid + outfit. + XDTM: + - experiment: Viruses and symptoms have been havily reworked. + - rscadd: Symptoms now have statistic thresholds, that give them new properties + or improve their existing ones if the overall virus statistic is above the threshold. + Check the pull request in github or the wiki (soon) for the full list. + - rscdel: Some symptoms no longer scale linearly with stats, and instead have thresholds. + - tweak: The symptom limit is now 6. + - rscdel: Viruses can no longer be made invisible to the Pandemic + - tweak: Symptoms no longer trigger with a 5% chance every second, but instead have + a minimum and maximum number of seconds between each activation, making them + more consistent. + - rscdel: The symptoms Blood Vomit and Projectile Vomit have been removed, and are + now bonuses for the base Vomit symptom. + - rscdel: The Weakness symptom has been removed as it was completely useless. + - tweak: The Sensory Destruction symptom has been reworked into Narcolepsy, which + causes drowsiness and sleep. + - tweak: Viral Aggressive Metabolism now has a timer before it starts decaying the + virus. It scales with the highest between Resistance or Stage Speed. + - rscadd: You can now neuter symptoms, making them inactive. They will still affect + stats. Adding formaldehyde to a virus will neuter a random symptom. A bottle + of formaldehyde starts in the virus fridge. + Xhuis: + - tweak: The tachyon-doppler array's rotation now has messages, sprites, and examine + text. + - bugfix: Time stop is now fixed, finally! + - soundadd: Time stop's sound now plays in reverse when the effect ends. + - bugfix: Missiles can no longer ricochet off of shuttle walls, etc. + - bugfix: Winter coats now hold all flashlights properly, instead of seclites. + Xhuis & Cyberboss: + - rscadd: New hivebot invasion event + kevinz000: + - rscadd: Personal Cabinets now have piano synthesizers for handheld piano playing. + - experiment: Thank @nicbn for the sprites! + ninjanomnom: + - experiment: Thank you for updating your ShuttlSoft product! Your last update was + -ERROR- years ago. A full changelog can be found at CYG10408.SHSO.b9 along with + the EULA. This update lays a foundation for new things to come and a sample + in the form of new and improved docking procedures. + shizcalev: + - bugfix: Cerestation's emergency shuttle autopilot will no longer fly you in reverse + back to Centcom! +2017-07-27: + Anonmare: + - bugfix: Informs a person about how bomb cores work + BeeSting12: + - rscdel: Water bottles from the sustenance vendor are gone. Wait for the ice in + the ice cups melt, criminal scum. + - rscdel: There is no longer a sink in gulag. Hygiene is for the moral members of + society. + - tweak: Janitor and service cyborgs now get pocket fire extinguishers for fire + suppression and space propulsion. + - rscadd: Pubbystation's dorms now has a dresser. + - bugfix: Crafting satchels from leather now makes a leather satchel rather than + a regular satchel. + Fox McCloud: + - tweak: breathing plasma now causes direct tox damage + - tweak: breathing hot/cold air now warns you when you're doing so, again + - tweak: species heat/cold mod now impacts damage from breathing hot/cold gases + HAL 9000: + - bugfix: I'm sorry Dave, I'm afraid I can't do that + JStheguy: + - imageadd: Resprited the tablet, including completely redone screen sprites. + - rscadd: Tablets can now come spawn in one of 5 colors; red, green, yellow, blue, + and black. + - imageadd: Most alcohol bottles have been resprited, as well as a poster that used + one of the current bottles as part of it's design. + Joan: + - balance: Unwrenching clockwork structures no longer damages them. + - tweak: The Hierophant will now release a burst when melee attacking instead of + actually hitting its target. + - bugfix: The Hierophant Club's blasts will now properly aggro hostile mobs. + - tweak: The blood-drunk miner will fire its KA a bit more often. + PopNotes: + - soundadd: Nar-Sie now sounds like an eldritch abomination that obliterates worlds + instead of a sweet maiden that gently whispers sweet nothings in your ear. + Supermichael777: + - bugfix: delayed chloral hydrate actually works now. + Tacolizard: + - rscadd: Added cybernetic organs to RnD, they can be used to replace organic organs. + Remember to administer corazone during implantation though! + - rscadd: Added the upgraded cybernetic liver. It is exceptionally robust against + toxins and alcohol poisoning. + Xhuis: + - bugfix: Cyborgs now regenerate oxygen damage. + - bugfix: If a cyborg somehow takes toxin damage, it can be healed with cables as + though it was burn damage. + - spellcheck: Picking up ores by walking over them now longer spams messages, instead + showing one message per tile of ore picked up. + - tweak: You can now control-click action buttons to lock them and prevent them + from being moved. Alt-clicking the "Show/Hide Actions" button will unlock all + buttons. + - tweak: There is now a preference for if buttons should be locked by default or + not. + - rscadd: Pizza box stacks can now fall over + - imageadd: Pizza box inhands now stacks depending on how many you're holding. + - bugfix: Mining satchels no longer hold infinite amounts of ore. + - bugfix: Reviving Stasis now consistently regenerates organs. + - bugfix: Medibots now properly render the overlays of the medkits they are made + from. + - bugfix: The latest batch of Syndicate screwdrivers fell into a vat of paint and + were colored randomly. We have rinsed them off and they will no longer come + in random colors. + - bugfix: Supermatter slivers can now be stolen properly. + - tweak: Whenever you're trying to hack off your own limbs, you'll now always hit + those limbs. + Xhuis & MoreRobustThanYou: + - imageadd: Toolbelts now have overlays for crowbars, wirecutters, screwdrivers, + multitools, and wrenches. + Y0SH1_M4S73R: + - bugfix: Romerol zombies count as dead for assassinate and maroon objectives. + bandit: + - rscadd: New Cards against Spess cards are available! + ktccd: + - bugfix: Hijacking should now be possible again! +2017-07-29: + Fox McCloud: + - rscadd: Sound should carry further, but should get quieter and quieter the further + you are from it + Joan: + - tweak: Sigils of Transmission can now drain power in a large area when activated + by a Servant. + - rscdel: Interdiction Lenses have been removed, as they were largely only used + to drain power into Sigils of Transmission. + - balance: Sigils can no longer directly be removed by Servants. + - balance: Prolonging Prisms have a higher cost to delay, but no longer increase + in cost based off of CV. + - balance: Base delay cost changed from 2500W to 3000W, cost increase per activation + changed from 750W to 1250W, cost increase per 10 CV changed from 75W to 0W. + - rscdel: Removed the Volt Blaster scripture. + - rscdel: Ratvarian spears can no longer impale. + - balance: Vitality Matrices now require a flat 150 Vitality to revive Servants, + from 20 + the Servant's non-oxygen damage. Vitality Matrices are also no longer + destroyed when reviving Servants. + - balance: Ratvarian spear damage changed from 18 to 20, Ratvarian spears now generate + 5 Vitality when attacking living targets. Ratvarian spear armour penetration + changed from 0 to 10. + - balance: The Judicial Visor's mark now immediately applies Belligerent and knocks + down for 0.5 seconds. Mark exploding no longer mutes, mark explosion stun changed + from 16 seconds to 1.5 seconds, mark explosion damage changed from 10 to 20. + More Robust Than You: + - rscadd: Nanotrasen has begun production of the Rapid Cable Layer, a tool that + helps you lay down cables faster + - rscadd: You can now craft ghetto RCLs with metal, a screwdriver, welder, and wrench. + They hold less cable, and may fall apart or jam! + Xhuis: + - spellcheck: Player-controlled medibots now receive a notice whenever they try + to heal someone with too high health. + - bugfix: Syringes now properly inject targets wearing thick clothing on different + slots. + - bugfix: Stun baton overlays now appear on security belts when active. + kevinz000: + - rscadd: 'Badmins: Buildmode map generators have names in the list to select them, + instead of paths.' + - rscadd: Also, a new map generator has been added, repair/reload station. Use it + VERY sparingly, it deletes the block of the map and reloads it to roundstart. + THIS CAN CAUSE ISSUES WITH MACHINES AND ATMOSPHERICS, SO DO NOT USE IT UNLESS + YOU ABSOLUTELY HAVE TO! + - experiment: The reload station one tagged DO NOT USE shouldn't be used as it doesn't + delete anything before loading, so if you use it you'll have two copies of things. + That can result in a LOT of issues, so don't use it unless you're a codermin + and know what you're doing/abusing! + ktccd: + - bugfix: Ashstorms no longer pierces the protected people to kill anyone/anything + in them. diff --git a/html/changelogs/archive/2017-08.yml b/html/changelogs/archive/2017-08.yml new file mode 100644 index 0000000000..91ad6f0a4b --- /dev/null +++ b/html/changelogs/archive/2017-08.yml @@ -0,0 +1,215 @@ +2017-08-06: + Anonmare: + - rscadd: Surgical toolarm to protolathe and exofab + - tweak: Toolarm tools are less robust but more efficient at surgery + - tweak: Arm augments are no longer a huge item + AnturK: + - balance: Cyborg remote control range is now limited to 7 tiles. + Ergovisavi: + - rscadd: Adds the "seedling" planetstation mob to the backend + Floyd: + - bugfix: No longer does everyone look like a sick, nauseated weirdo! + Galactic Corgi Breeding Mills, LLC: + - bugfix: Fixed corgis being able to wear spacesuit helmets despite lacking the + proper code and sprites for them. + Joan: + - tweak: Colossus's shotgun is now a static-spread blast of 6 bolts, making it more + predictable. + - balance: Geis now mutes for 12-14 seconds and "stuns" the target, via a binding + effect, for 25 seconds instead of initiating a conversion. + - experiment: Geis's "stun" restrains the target and prevents them from taking actions, + but its duration is halved if the binding is not being pulled by a Servant. + - wip: Using Geis on a target prevents you from taking actions other than attempting + to pull the binding. If you are pulling the binding, you can dispel it at any + time. + - wip: As should be obvious, if the binding is destroyed or dispelled, you can once + again take normal actions. + - tweak: Sigils of Submission are now permanent and have been moved from the Script + tier to the Driver tier, with an according cost adjustment. They still do not + penetrate mindshield implants. + - rscdel: Removed Taunting Tirade. + - rscdel: Removed Sigils of Accession. + Lexorion: + - imageadd: Hearty Punch has a new, fancier sprite. + More Robust Than You: + - bugfix: RCL and Ghetto RCLs are no longer invisible + - bugfix: RCL action button now has a sprite + - bugfix: RCLs can no longer go inside you + XDTM: + - bugfix: Eyes can now be properly damaged. + Xhuis: + - spellcheck: Removed an improper period from the supermatter sliver theft objective's + name. + - bugfix: Alien hunters can no longer pounce through shields. + - bugfix: Observing mobs that have no HUD will no longer cause intense lighting + glare. + - bugfix: Objects on shuttles now rotate in the correct directions. + - soundadd: The speakers in the ceiling have been upgraded, and many sounds are + now less tinny. + Xhuis and oranges: + - bugfix: Banana cream pies no longer splat when they're caught by someone. + - soundadd: Throwing a pie in someone's face now has a splat sound. + kingofkosmos: + - bugfix: Fixed hair sticking through headgear. +2017-08-13: + JStheguy: + - imageadd: Laptops now have actual sprites for using the supermatter monitoring + instead of defaulting to a generic one. + Joan: + - imageadd: Belligerent now has a visible indicator over the caster. + More Robust Than You: + - tweak: Mulligan and non-continuous completion checks will not consider afk/logged + out people to be "living crew". + - tweak: The wiki button now asks what page you want to be taken to + - tweak: His Grace now shows up on the orbit list + Pubby: + - rscadd: The Curator job is now available on PubbyStation + - rscadd: Beekeeping has been added to PubbyStation's monastery + - tweak: PubbyStation's bar has been rearranged + Xhuis: + - bugfix: Swarmer shells now have ghost notifications again. + - bugfix: Minebots no longer lack icons for their action buttons. + kingofkosmos: + - imageadd: Adds icon_states to the unused and used Eldritch whetstones. Sprites + by Fury McFlurry. +2017-08-14: + Joan: + - imageadd: Ported CEV-Eris's APC sprites. + More Robust Than You: + - bugfix: Fixes a typo in the blobbernaut spawn text + WJohnston: + - rscadd: Adds an ore box and shuttle console to aux bases on all stations. + Xhuis: + - bugfix: The Resurrect Cultist rune now works as intended. + - bugfix: Cyborg energy swords now properly have an icon. + kingofkosmos: + - tweak: Canisters don't flash red lights anymore when empty. +2017-08-19: + Anonmare: + - balance: Raised airlock deflection by one point + BeeSting12: + - balance: The meth explosion temperature has been raised. + FrozenGuy5/PraiseRatvar: + - balance: Nerfs L6 SAW Hollow Point Bullets from -10 armour penetration to -60 + armour penetration. + Joan: + - balance: Deathsquads no longer get shielded hardsuits. + More Robust Than You: + - rscadd: Blobs can now sense when they're being cuddled! + - bugfix: Fixes mining hardsuit heat_protection + - bugfix: RCL icons are now better at updating + NewSta: + - bugfix: Fixes the wiki button + - spellcheck: Fixes a typo in the wiki button description + XDTM: + - rscadd: You can now click on symptoms in the Pandemic to see their description + and stats + Xhuis: + - soundadd: The station's explosion now uses a new (or old) sound. + - rscadd: Adds smart metal foam, which conforms to area borders and walls. It can + be made through chemistry by mixing foaming agent, acetone, and iron. + - rscadd: Smart metal foam will create foamed plating on tiles exposed to space. + Foamed plating can be struck with floor tiles to turn it into regular plating! + - spellcheck: The chat message has been removed from *spin. I hope you're happy. + nicbn: + - imageadd: Nanotrasen redesigned the area power controllers! + - imageadd: Thanks Xhuis for the contrast tweak on APCs +2017-08-23: + Cobby: + - balance: Planting kudzu now has a short delay with a visible message to users + around you. Hit-N-Run planting is no longer possible. + - rscdel: kudzu bluespace mutation and spacewalk mutation are removed. + Cruix: + - rscadd: The syndicate shuttle now has a navigation computer that allows it to + fly to any unoccupied location on the station z-level. + Ergovisavi: + - tweak: Slightly increased the radius of the atmos resin launcher, and resin now + makes floors unslippery + Pubby: + - rscadd: Gorillas + - rscadd: Irradiating monkeys can now turn them into hostile gorillas + Shadowlight213: + - experiment: The amount of time spent playing, and jobs played are now tracked + per player. + - experiment: This tracking can be used as a requirement of playtime to unlock jobs. + ShizCalev: + - balance: Morphlings now have to restore to their original form before taking a + new one. + - bugfix: Morphlings will no longer have combined object appearances + Supermichael777: + - bugfix: Boss tiles have been reconstructed out of an unstoppable force. + TehZombehz: + - rscadd: Nanotrasen Culinary Division has authorized the construction of pancakes, + including blueberry and chocolate chip pancakes. Pancakes can be stacked on + top of each other. +2017-08-26: + Cyberboss: + - rscadd: Added the credits roll + Iamgoofball: + - rscadd: Plasmamen now hallucinate with blackpowder in their system + Joan: + - balance: Geis bindings no longer decay faster if not pulled by a Servant, but + last for 20 seconds, from 25. + - tweak: Geis bindings will decay slower when on a Sigil of Submission, and, if + being pulled by a Servant when crossing a Sigil of Submission, will helpfully + remove the pull. + - tweak: Removing Geis bindings is no longer instant and can be done by any Servant + with a slab, not just the initiator. + - wip: Geis no longer prevents you from taking actions, but you remain unable to + recite scripture while the target is bound. In addition, dealing damage to a + bound target will cause the bindings to decay much more rapidly. + - rscadd: You can now remove sigils by hitting them with a clockwork slab for a + small refund. + More Robust Than You: + - balance: Lowers the chance for monkeys to become gorillas + - rscadd: Holoparasite prompts now have a "Never For This Round" option + Naksu: + - spellcheck: fixed inconsistent grammar between machines that derive from /obj/machinery/chem_dispenser + - spellcheck: touched up some chat messages to include references to objects instead + of "that" or "the machine" etc., also removed references to beakers being loaded + in machines that can accept any container +2017-08-30: + CPTANT: + - balance: Hacked AI module cost is reduced to 9TC + Cobby & Cyberboss: + - rscadd: A stealth option for the traitor microlaser has been added. When used, + it adds 30 seconds to the cooldown of the device. + Cyberboss (unwillingly by Kor's hand): + - balance: You no longer take damage/are as heavily blinded in crit while above + -30HP + - balance: Whispering in crit above -30HP will not cause you to succumb + - balance: You can now hear in crit above -30HP + Joan: + - imageadd: Cult blades have updated item and inhand sprites. + Kor: + - rscadd: Added Shadow Walk, a new form of jaunt that lasts for an unlimited amount + of time, but ends if you enter a well lit tile. It is planned for use in a Shadowling + rework, but feel free to hassle admins to test it out in the mean time. + - balance: Slime people can consume meat and dairy again. + Lzimann: + - rscadd: Ghosts now have a way to see all available ghost roles! Check your ghost + tab! + MMMiracles: + - rscdel: Cerestation has been decommissioned. Nanotrasen apologizes for any spikes + of suicidal tendencies, sporadic outbursts of primitive anger, and other issues + that may of been caused during the station's run. + Naksu: + - bugfix: fixed portable chem dispensers charging 50% slower than intended when + initialized. + - bugfix: fixed portable chem dispensers getting faster charging rate every time + refreshparts() is called + Pubby: + - rscadd: Crew-tracking pinpointers to replace laggy crew monitoring console functionality + - rscadd: Crew-tracking pinpointers in medical vendors and the detective's office + RemieRichards: + - rscadd: AltClick listing now updates instantly on AltClick + - bugfix: AltClick listing no longer reveals obscured items + ShizCalev: + - tweak: The singularity now poses a threat towards asteroids as well as stations. + - tweak: All power systems will now report their wattage values in Watts, Kilowatts, + Megawatts, and Gigawatts. Gone are the days of seeing 48760 W total load when + working with an APC! + kingofkosmos: + - tweak: You can now unbuckle out a chair/bed by moving. + ninjanomnom: + - bugfix: Fixed a problem with shuttles being unrepairable under certain circumstances. diff --git a/html/changelogs/archive/2017-09.yml b/html/changelogs/archive/2017-09.yml new file mode 100644 index 0000000000..46b95edc69 --- /dev/null +++ b/html/changelogs/archive/2017-09.yml @@ -0,0 +1,255 @@ +2017-09-01: + Fury McFlurry: + - rscadd: Added more halloween costumes. + - rscadd: Among them are a lobster suit, a cold villain costume and some gothic + clothes + More Robust Than You: + - rscdel: Finally fucking removed gangs + MrStonedOne: + - rscadd: Player notes can now be configured to fade out over time to allow admins + to quickly see how recent notes are. Server Operators, check the config for + more info + Pubby: + - rscdel: The multiverse sword is toast + YPOQ: + - bugfix: Pouring radium into a ninja suit restores adrenaline boosts. + - bugfix: Adrenaline boost works while unconscious again. + - bugfix: Energy nets can be used again! +2017-09-02: + Frozenguy5: + - tweak: Added new station prefixes, names and suffixes! + Tortellini Tony: + - tweak: Round-end credits can now be toggled on or off in the server game options. + XDTM: + - tweak: The Disease Outbreak event now can generate random advanced viruses, with + more symptoms and higher level as round time goes on. +2017-09-11: + Anonmare: + - balance: Altered pressure plate crafting recipe + Basilman: + - rscadd: A strange asteroid has drifted nearby... + Firecage: + - rscadd: The NanoTrasen Department for Cybernetics (NDC) would like to announce + the creation of Cybernetic Lungs. Both a stock variety to replace traditional + stock human lungs in emergencies, and a more enhanced variety allowing greater + tolerance of breathing cold air, toxins, and CO2. + JJRcop: + - rscadd: Admins can now play media content from the web to players. + - rscadd: Adds a volume slider for admin midis to the chat options menu. + Jay: + - bugfix: Goliaths can be butchered again + Joan: + - tweak: While below 0 health but above -30 health, you will be able to crawl slowly + if not pulled, whisper, hear speech, and see with worsening vision. + - wip: The previous softcrit got reverted, for changelog context. + - rscdel: Standard attacks, such as swords, hulk punches, mech punches, xeno slashes, + and slime glomps, will no longer damage clothing. + Kor: + - rscadd: People in soft crit will take oxyloss more slowly than people in full + crit if they remain still. + - rscadd: People dragging themselves in critical condition will now leave blood + trails. This will rapidly deal oxyloss to you. + MrStonedOne: + - rscadd: Admins may now show the variables interface to players to help contributors + debug their new additions + Naksu: + - rscadd: Added TGUI interfaces to various smartfridges of different kinds, drying + racks and the disk compartmentalizer + Pubby: + - bugfix: Escape pods and PubbyStation's monastery shuttle are back in commission + Robustin: + - tweak: Golem shells no longer fit in standard crew bags. + Supermichael777: + - bugfix: Stands now check if their user got queue deleted somehow + VexingRaven: + - bugfix: Hearty Punch once again pulls people out of crit. + Xhuis: + - spellcheck: Various grammar in the Orion Trail arcade game has been tweaked. + - rscadd: You can now kill yourself in fun and creative ways with the hierophant + club. + - rscadd: Common lavaland mobs now have rare mutations! Keep an eye out for rare + Poke- err, monsters. + - imageadd: The hand drill and jaws of life now have sprites on the toolbelt. + YPOQ: + - bugfix: Windoors open when emagged again + as334: + - rscadd: Added a mass spectrometer to the detective's closet + basilman: + - rscadd: penguins may now have shamebreros, noot noot +2017-09-13: + BeeSting12: + - balance: The stetchkin APS pistol is smaller. + - rscadd: The 9mm pistol magazines can be purchased from nuke op uplinks at two + telecrystals each. + Kor: + - rscadd: Added Nightmares. They're admin only currently, so as usual, make sure + to beg admins to be one. + - rscadd: The Chaplain may now choose the Unholy Blessing as a null rod skin. + KorPhaeron: + - rscadd: Added Jacob's ladder to the necropolis chest + Lordpidey: + - bugfix: Centcom roundstart threat reports are fixed, and can now be used to narrow + down the types of threats facing the station. + MrROBUST: + - rscadd: Mechs now can be connected to atmos ports + VexingRaven: + - bugfix: Changeling Augmented Eyesight ability now grants flash protection when + toggled off + - bugfix: Changeling Augmented Eyesight ability can now be toggled properly + - bugfix: Changeling Augmented Eyesight ability is properly removed when readapting + - bugfix: The syndicate have once again stocked the toy C20r and L6 Saw with riot + darts. + Xhuis: + - rscadd: You can now use metal rods and departmental jumpsuits to craft departments + for each banner. + - tweak: The lavaland animal hospital ruin has been remapped, including more supplies + as well as light sources. +2017-09-14: + BeeSting12: + - balance: Deltastation's and Metastation's armory now starts with three riot shotguns! + Fun Police: + - rscdel: Removed some of the free lag. + Kor: + - bugfix: It is possible to multitool the cargo computer circuitboard for contraband + again + ShizCalev: + - bugfix: Holding a potted plant will no longer put you above objects on walls. + - bugfix: Replaced leftover references to loyalty implants with mindshield implants. + ninjanomnom: + - bugfix: Shuttle transit parallax should be working again +2017-09-16: + Basilman: + - rscadd: Gondolas are now procedural generated. + Mey-Ha-Zah: + - imageadd: Updated the knife sprite. + Naksu: + - bugfix: Evidence bags will no longer show ghosts of items such as primed flashbangs + after the flashbang inside explodes + - bugfix: Prevents dead monkeys from fleeing their attackers or escaping His Grace + only to be eaten again + - rscdel: Corgis can no longer be targeted by facehuggers + - rscdel: Removed unused vine floors and their sprite. + Robustin: + - rscadd: Due to budget cuts, airlocks that control access to non-functional maint + rooms and other abandoned areas now have a chance to spawn welded, bolted, screwdrivered, + or flat out replaced by a wall at roundstart. + - bugfix: Dice will now roll when thrown + YPOQ: + - rscadd: Ninja adrenaline boost removes stamina damage + - bugfix: Depowered AIs can no longer use abilities or interact with machinery + - bugfix: The doomsday device will again periodically announce the time until its + activation + - bugfix: Crafting stackable items results in the right stack sizes +2017-09-18: + More Robust Than you: + - balance: Blobbernauts are healed quicker by cores and nodes + Naksu: + - bugfix: OOC for dead people is now (re-)enabled at round-end + - bugfix: Fixed chemfridges being unable to display items with dots in their name + Pubby: + - rscadd: Traitorbro gamemode + Supermichael777: + - bugfix: Airlocks now check metal for upgrades using the standard get_amount() + proc instead of checking the amount var, this means it is compatible with cyborgs. + TungstenOxide: + - tweak: Swapped the action of purchasing a pAI software and subtracting the RAM + from available pool. + Xhuis: + - balance: Brave Bull now increases your max HP by 10, up from 5. + - rscadd: Tequila Sunrise now makes you radiate dim light while it's in your body. + - rscadd: Dwarves are now very resistant to the intense alcohol content of the Manly + Dorf and can freely quaff them without too much worry. + - rscadd: Bloody Mary now restores lost blood. +2017-09-20: + PopNotes: + - imageadd: Airlocks animate faster. This doesn't change the time it takes to pass + through an airlock, but it does visually match up much better so you don't just + appear to glide through the airlock while it's half-open. + Pubby: + - bugfix: Atmos pipenets are less glitchy + TehZombehz: + - rscadd: Several new plushie dolls are now available in toy crates. +2017-09-22: + AutomaticFrenzy: + - bugfix: Mice spawning finds the station z level properly + CPTANT: + - balance: Knockdown and unconcious now let you regenerate stamina damage. + - rscadd: Sleeping regenerates more stamina damage. + Naksu: + - bugfix: Admin ghosts can no longer unintentionally make a mess of things. +2017-09-23: + Armhulen: + - rscadd: Rare Spider Variants have arrived! Every spiderling has a rare chance + of growing up to a rare version of their original spider type! + - rscadd: Special thanks to Onule for the sprites, you're the best! + JJRcop: + - rscadd: Suiciding with a ballistic gun now actually blows your brain out. + More Robust Than You: + - tweak: Taking the beaker out of a cryotube now tries to put it into your hand + - code_imp: Removed some spawn()s from secbot code + - bugfix: Using a soulstone on somebody now transfers your languages to the shade + - bugfix: Zombies now stay dead if they suicide + - rscadd: If a zombie suicides, they now rip their head off! + - bugfix: pAIs now transfer their languages to bots + - bugfix: Support Holoparasites must be manifested to heal + Robustin: + - balance: A zombie's automatic self-healing is stopped for 6 seconds after taking + damage. + - bugfix: Deconverted revs will now always get a message, logs will now include + more details. + YPOQ: + - bugfix: Pet persistence works again +2017-09-27: + Arianya: + - balance: Lesser ash drakes no longer drop ash drake hide when butchered. + GLA Coding: + - tweak: Cells must now be installed in mechs when being constructed, this step + is always before the application of internal armor. + - bugfix: Combat mechs now get stats upgrades from their scanning modules and capacitors + Improvedname: + - rscadd: Adds racial equality to color burgers + More Robust Than You: + - rscadd: Implant Chairs now also support organs + Naksu: + - bugfix: Fixed jump boots breaking if used when you can't jump, such as when inside + a sleeper. + - code_imp: Removed meteor-related free lag. + - bugfix: Syndicate MMIs will now properly transfer their laws to newly-constructed + AIs + Pubby: + - rscadd: Bluespace pipes to atmospherics, which create a single pipenet with all + bluespace pipes in existence. +2017-09-28: + RandomMarine: + - imageadd: Air tanks (o2+n2) now have a different appearance from oxygen tanks. + Robustin: + - tweak: Revheads no longer spawn with chameleon glasses or a spraycan, instead + they will start with a cybernetic security HUD implanted into their eyes. + Xhuis: + - rscadd: Ian has recently communed with unspeakable horrors and may now be warped + by their power if Nar-Sie passes near them. + - rscadd: In order to fight back against their ancient foe Ian, Poly has struck + a bargain with Ratvar and will be transformed into a machine by their presence. + Y0SH1_M4S73R: + - bugfix: AFK players count as dead for the assassinate objective. +2017-09-29: + Kor: + - rscadd: Gunfire can now leave bullet holes/dents in walls. Sprites by JStheguy. + RandomMarine: + - rscadd: You can now light your cigs with people that are on fire. The surgeon + general is spinning in their grave. + Robustin: + - tweak: Hacking a secure container with a multitool now takes longer, but no longer + has a chance to fail. + XDTM: + - rscadd: Nurse spiders can now set a directive that will be seen by their spiderlings, + when they get controlled by a player. + - rscadd: Spiders' actions are now action buttons instead of verbs. + - rscadd: Wrapping stuff in a cocoon is now a targeted action! + kevinz000: + - rscadd: The syndicate have recently begun sending agents to extract vital research + information from Nanotrasen. + - bugfix: 'Timestop fields will now stop thrown objects experimental: Timestops + will now be much quicker to react.' + kingofkosmos: + - spellcheck: You can now find out if an item uses alt-clicking by examining it. diff --git a/html/changelogs/archive/2017-10.yml b/html/changelogs/archive/2017-10.yml new file mode 100644 index 0000000000..591a208961 --- /dev/null +++ b/html/changelogs/archive/2017-10.yml @@ -0,0 +1,622 @@ +2017-10-07: + Antur: + - bugfix: Liches will no longer lose their spells when reviving. + AnturK: + - rscadd: Wigs are now available in AutoDrobe + Cobby: + - admin: Players will now be notified automatically when an admin resolves their + ahelp. + Cyberboss: + - config: The shuttle may now be configured to be automatically called if the amount + of living crew drops below a certain percentage + - bugfix: Fixed a rare case where creating a one tank bomb would result in a broken + object + - bugfix: Fixed many cases where forced item drops could be avoided by not having + an item in your active hand + DaxDupont: + - rscdel: No more roundstart tips about gangs. You can finally start to forget gangs + ever existed. + Incoming5643: + - bugfix: The rarely utilized secret satchel item persistence system has been fixed + and made more lenient. + - rscadd: 'In case you forgot how it works: if you find or buy secret satchels, + put an item in them, and then bury them under tiles on the station you or someone + else can find them again in a future round with the item still there! Free satchels + can often be found hiding around the station, so get to burying!' + JJRcop: + - config: Hosts can now lock config options with the @ prefix. This prevents admins + from editing the option in-game. + - tweak: Admin volume slider moved to its own menu for better visibility. + Joan: + - bugfix: Fixes Vanguard never stunning for more than 2 seconds. + - balance: Ocular Warden base damage per second changed from 12.5 to 15. + - bugfix: Ocular Wardens no longer count themselves when checking for dense objects, + which decreased their overall damage by 15%. + - balance: Ocular Wardens now only reduce their damage by 10% per dense object, + and only do so once per turf. However, dense turfs now reduce their damage with + the same 10% penalty. + Kerbin-Fiber: + - bugfix: Wood is no longer invisible + Kor: + - rscadd: Nightmares now have mutant hearts and brains, with their own special properties + when consumed or implanted in mobs. Experiment! + - bugfix: You can now tell when someone is in soft crit by examining them. + - rscadd: Nightmares now have a chance to spawn via event. + More Robust Than You: + - bugfix: Fixes cogscarab sprites not updating + - balance: Blobs now take damage from particle accelerators + MrDoomBringer: + - rscadd: Nanotrasen, as part of their new Employee Retention program, has encouraged + more station point-makery by adding the "Cargo Tech of the Shift"! The award + is located in a lockbox in the Quartermaster's locker. + MrStonedOne: + - tweak: The MC will now reduce tick rate during high populations to keep it from + fighting with byond for processing time. + - config: Added config options to control MC tick rate + - admin: Admins can no longer manually control the mc's tick rate by editing the + MC's processing value, instead you will have to edit the config datum's values + for high/low pop tick rates. + Naksu: + - bugfix: Removed some of the free lag + - bugfix: Updates to station name are now reflected on Cargo's stock exchange computers. + - bugfix: Gutlunches will now once again look for gibs to eat. + - bugfix: Bees now come with reduced amounts of free lag + - balance: Pyrosium and cryostylane now react at ludicrous speeds. + - tweak: Made atmos tiny bit faster + - bugfix: Tweaks to atmos performance + Qbopper: + - tweak: Moved a locker blocking an airlock in Toxins maintenance. + RandomMarine: + - bugfix: Simple mobs should no longer experience severe hud/lighting glitches when + reconnecting. + Robustin: + - rscadd: Blood cultists can now create a unique bastard sword at their forge + - rscdel: Blood cultists can no longer obtain a hardsuit from the forge + - bugfix: Emotes (e.g. spinning and flipping) will now properly check for consciousness, + restraints, etc. when appropriate. + - bugfix: The Cult's bastard sword should now properly store souls and create constructs. + - bugfix: Neutering a disease symptom now produces a unique ID that will ensure + the PANDEMIC machine copies it properly. + ShizCalev: + - bugfix: You now have to unbuckle a player PRIOR to shaking them up off a bed or + resin nest. + - bugfix: Wizards will now have the correct name when attacked with Envy's knife! + - soundadd: Space ninja energy katanas now make a swish when drawn! + Supermichael777: + - balance: The detectives gun has been restored from a system change that nerfed + knockdown in general. We need to have a serious discussion about anti revolver + hate in this community. + - tweak: The PDA default font has been switched from "eye bleed" to old-style monospace. + Check your preference. + Thefastfoodguy: + - bugfix: Silicons can no longer take brain damage + - bugfix: Antimatter shielding that can't find a control unit won't delete itself + anymore + WJohnston: + - rscadd: Boxstation and Metastation's white ships now have navigation computers, + letting you move them around in the station, deep space, and derelict z levels. + XDTM: + - rscadd: Added the H.E.C.K. suit, a guaranteed loot frop from Bubblegum. + - rscadd: The H.E.C.K. suit is fully fire (and ash) proof, and has very good melee + armor. + - rscadd: H.E.C.K. suits can also be painted with spraycans, to fully customize + your experience. + - rscadd: Despite spending centuries inside a demon king, H.E.C.K. suits are most + definitely safe. + - bugfix: Fixed a bug where Viral Aggressive Metabolism caused viruses to be cured + instantly. + - bugfix: Fixed a bug where viruses' symptoms would all instantly activate on infection. + - rscadd: The CMO now has an advanced health analyzer in his closet! It can give + more precise readings on the non-standard damage types. + Xhuis: + - bugfix: Runed metal and brass are no longer invisible. + Xhuis and Y0SH1_M4S73R: + - bugfix: Servants of Ratvar now spawn in as the actual race set on their preferences, + with plasmamen getting the gear they need to not immediately die. + Y0SH1_M4S73R: + - balance: Gygax overdrive consumes at least 100 power per step + YPOQ: + - bugfix: Jaunters equipped on the belt slot will save you from chasms again. + kevinz000: + - rscadd: Wormhole event wormholes now actually teleport you. + - bugfix: portals now actually teleport on click. + kingofkosmos: + - rscadd: You can now see construction/deconstruction hints when examining airlocks. + - spellcheck: Beds, chairs, closets, grilles, lattices, catwalks, tables, racks, + floors, plating and bookcases now show hints about constructing/deconstructing + them. + nicbn: + - rscadd: Paperwork now uses Markdown instead of BBCode, see the writing help for + changes. + - imageadd: Changed the drop, throw, pull and resist icons. +2017-10-15: + Armhulen: + - bugfix: Clockwork golems no longer slip and slide on glass! + Armie: + - tweak: Holoparasites are once again in the uplink. + Bawhoppen: + - tweak: Smoke machine board has been moved to tech storage. + DaxDupont: + - tweak: After lobbying by Robust Softdrinks and Getmore Chocolate Corp all vendor + firmware has been changed to add sillicons to their target demographic. + - spellcheck: Replaces instances of "permenant" and "permenantly" with the proper + spelling in several areas, + Epoc: + - rscadd: Added a Toggle Underline button to the PDA menu + - code_imp: Cleaned HTML spacing + Frozenguy5: + - bugfix: C20r damage upped from 20 to 30 (used to be 30 before an ammo cleanup + in the code) + GLACoding: + - bugfix: Syndicate turrets and other machines in walls can now be hit by projectiles + Improvedname: + - rscadd: You can now put custom name and lore on your holy weapon by using a pen + on it! + - tweak: Cmo, captain, and the bartender now get pet collars in their lockers. + Jambread/RemieRichards/Incoming5643: + - server: There is a new system for title music accessible from config/title_music + folder. This system allows for multiple rotating lobby music without bloating + Git as well as map specific lobby music. See the readme.txt in config/title_music + for full details. + - config: The previous method of title music selection, strings/round_start_sounds.txt + has been depreciated by this change. + Kor: + - balance: You can now smash the bulbs out of floodlights rather than having to + entirely destroy the object. + Mercenaryblue: + - rscadd: Use the Clown Stamp on some cardboard to begin... the honkbot! + - rscadd: These honkbots are just adorable, and totally not annoying. I swear! Honk! + - rscadd: You can even slot in a pAI! Just don't emag them... oh boy. oh no. oh + geez. + - soundadd: Honkbots now release an evil laugh when emagged. + - imageadd: added some in_hands for banana peels. + - tweak: Golden Bike Horns now permit its victims to perform a full flip before + forcing them to jump again. + More Robust Than You: + - bugfix: Makes the santa event properly poll ghosts + - bugfix: Diseases will now cure if species is changed + - tweak: You can now drag-drop people into open DNA scanners + - bugfix: Medibots will no longer inject people in lockers/sleepers/etc + Naksu: + - bugfix: Fixes to door/airlock deletion routines. + - bugfix: Traitor pen uplinks now preferentially spawn in the PDA pen, and not in + a pocket protector full of pens that no-one checks. + - bugfix: Reusable projectiles such as foam darts no longer get deleted if they're + shot at a shooting range target or a cardboard cutout. + - bugfix: Ghosts no longer inherit the movement delay of their former bodies. + - bugfix: Fixed mobs being able to smash shocked objects without taking damage. + - bugfix: Fixed some mobs not deleting correctly + - code_imp: Fixed dusting code, supermatter-suicides no longer spam the runtime + logs. + - code_imp: Fixed some initialize paths. + Onule: + - tweak: Sunflower sprites were changed, small edits to variants. + - imageadd: Sunflower and variant's inhands sprites. + - imageadd: Tweaked growing sprites to match the new sunflower. + - imageadd: Moonflower and novaflowers now have slightly different growing sprites. + Robustin: + - rscadd: The Chemistry Smoke Machine! Chemist offices will have a board available + should they choose to construct a smoke machine. The smoke machine will regularly + produce smoke from whatever chemicals have been inserted into the machine. Designs + for the circuitboard are also available at RND. + - tweak: Abandoned Airlocks will no longer be deleted when their turf is changed + to a wall. + - tweak: Tesla movement is now completely random. + - bugfix: Clock Cult mode will no longer end if all the cultists die. The round + will not end until the Ark is destroyed or completed. + - bugfix: Chain reactions between explosives will now properly trigger explosives + located in an individual's bag. + - tweak: The wrench-anchoring time of the smoke machine is now doubled to 4 seconds. + - tweak: Smoke Machine smoke is now transparent. + - rscadd: The smoke machine has taken its rightful place in the chemist's office. + - bugfix: Smoke machine will no longer operate while moving/unanchored. + ShizCalev: + - tweak: Nanotrasen brand "Box" model stations have received approval from CentCom + to be retrofitted with the latest in Xenobiology equipment. You will now find + a chemmaster, a chemical dispenser, and a dropper within the Research Division's + Xenobiology lab. + - bugfix: C4 will no longer appear underneath objects on walls. + - bugfix: Plastic explosives will no longer be invisible after being planted. + - imageadd: The security bombsuit's sprite has been updated! + SpaceManiac: + - spellcheck: Grammar when examining objects has been improved. + - bugfix: AI eye camera static is now correctly positioned on Lavaland. + - spellcheck: Fixed many instances of "the the" when interacting with objects. + - bugfix: The tracking implant locator now works on the station again. + WJohn: + - rscadd: An old cruiser class vessel has resiliently stuck around, and may do so + for the foreseeable future. + WJohnston: + - tweak: Due to age, the abandoned ship's engines are now considerably slower when + bringing it place to place. This does however mean that the ship now has a more + gradual takeoff, with no sudden jolt to knock passengers off their feet. + - imageadd: Black carpets no longer have an ugly periodic black line in them. Regular + catwalks are now totally opaque so you won't accidentally click on space when + trying to place wires or tiles on them. + - rscdel: Boxstation's guitar white ship is no more. + - rscadd: Metastation's white ship stands in its place! + - tweak: Metastation's white ship has a couple of weak laser turrets to protect + the cockpit from space carp. + - tweak: Boxstation and metastation now have some plating under the grilles near + the AI sat's transit tube to prevent players from deleting the tube by landing + there. + WJohnston & ninjanomnom: + - rscadd: Plastitanium walls smooth, fancier syndicate shuttles! + - bugfix: Infiltrator shuttles have been moved out of the station maps and made + into a multi-area shuttle. + - balance: Titanium and plastitanium have explosion resistance (requested by Wjohn) + XDTM: + - rscadd: Blood and vomit pools can now spread the diseases of the mob that made + them! Cover your feet properly to avoid infection. + - rscadd: Virus severity now changes the color of the disease HUD icon, scaling + from green to red to flashing black-red. + - tweak: Contact-based diseases no longer spread by simply standing near other people; + it requires interaction like touching or attacking. Bumping against people/swapping + with help intent still counts as touching. + - tweak: Advanced viruses now have another infection type, "Fluids"; it's between + blood and skin contact, and will only be transmitted through fluid contact. + - rscdel: Two "hidden" infection types have been removed. Overall this means that + making a virus airborne is a little bit easier. + - bugfix: Species who cannot breathe can no longer be infected by breathing. + - bugfix: Internals now properly work if set to 0 pressure, and will prevent breathing + gas from the external atmosphere. + - bugfix: Viral Aggressive Metabolism is now properly inactive when neutered. + Xhuis: + - tweak: Cogscarabs can now experiment more freely with base design during non-clockcult + rounds with infinite power and the ability to recite scripture! + - bugfix: The Ark of the Clockwork Justiciar is now registered as a hostile environment. + - refactor: Clockwork scripture now has one progress bar for the entire recital + instead of multiple ones for each sentence in the invocation. + - bugfix: Ocular wardens no longer have a burning hatred for revenants and won't + attack their corpse endlessly anymore. + - balance: Stargazers can no longer be built off-station, even in new areas. + - balance: Integration cogs no longer emit sounds and steam visuals when active. + armie: + - bugfix: mob spawners are no longer possessable + deathride58: + - rscadd: '*slap' + duncathan: + - bugfix: Scrubbers and filters no longer allow for infinite pressure in pipes. + improvedname: + - bugfix: 9mm doesn't longer appear in traitor surplus crates + kevinz000: + - bugfix: 'Flightsuits now allow proper pulling experimental: Moved now has an argument + for if it was a regular Move or a forceMove.' + - rscadd: Instead of dumb sleep()s, follow trails now use SSfastprocess for processing! + - rscadd: Mobs now float while flying automatically! + - rscdel: 'Flightsuits can no longer be safely shut off if you''re still barreling + down the hallway. experimental: Flightsuits should be less shitcode. Hope this + PR doesn''t blow anything important up!' + - bugfix: Fixed trying to clear beaker in pandemic when the beaker is already removed + causing a runtime. + kingofkosmos: + - rscadd: Alt-clicking on a computer now ejects the ID card inside it. + nicbn: + - tweak: You can now clear bullet holes in walls using a welding tool. + ninjanomnom: + - refactor: Radiation has been completely overhauled. + - rscadd: A new radiation subsystem and spreading mechanics. + - rscadd: Walls and other dense objects insulate you from radiation. + - rscadd: Geiger counters now store the last burst of radiation so you can view + it at your leisure or show it to someone. Examine it. + - rscadd: Geiger counters can check mobs for contaminated objects. Scan yourself + before you leave to make sure you aren't carrying dangerous radioactive items. + - soundadd: Geiger counters have realistic sounds and the radiation pulse spam in + chat has been replaced. + - balance: Radiation is more deadly and causes burns at high intensities, WEAR YOUR + RADSUITS. + - balance: However residue radiation is far slower acting and kills you with toxin. + - balance: Engineering holosigns have a light amount of radiation insulation. + - balance: Rad collectors are nerfed. No more supercharging with pressurized plasma. + No more collector spam either. + - balance: Engine output is a lot more stable as a result of collector changes. + - balance: Monkeys need more rads and take more time to turn into gorillas. + - tweak: Over 100% on the DNA computer means your subject is now taking damage. + - tweak: The asteroid escape shuttle has no stabilizers and throws you around when + it moves + - bugfix: Shuttles no longer rotate ghosts of players who prefer directionless sprites + - bugfix: 2 Years later and cameras work on shuttles now, probably. + - bugfix: Buckled mobs when on a rotating shuttle should now rotate correctly + - bugfix: Fixes shuttles gibbing in supposedly safe areas + - bugfix: Mobs that didn't move during shuttle launch would not have their parallax + updated. This is fixed now. + - bugfix: The custom shuttle placement highlight now works for multi area shuttles. + - bugfix: Directional windows shouldn't leak air anymore + - tweak: Windows only block air while anchored + - bugfix: Fixes camera mobs being considered a target by radiation + - bugfix: Cables can no longer be contaminated as well + - balance: Buffs radiation cleansing chems + - balance: Toxin damage per tick from radiation is halved + - admin: Contaminated objects keep track of what contaminated them + - admin: Radiation pulses over 3000 are logged now + spessmenart: + - imageadd: The captains sabre no longer looks like a rapier. +2017-10-17: + DaxDupont: + - bugfix: 'Fancy boxes(ie: donut boxes) now show the proper content amount in the + sprite and no longer go invisible when empty.' + Mercenaryblue: + - bugfix: when decapitated, banana-flavored cream no longer hovers where your head + used to be. + More Robust Than You: + - rscadd: EI NATH! now causes a flash of light + Naksu: + - bugfix: Pinned notes will now show up on vault, abductor, centcom and large glass + airlocks. + - spellcheck: Removed a misleading message when handling full stacks of sheets. + - bugfix: Pre-filled glass bottles (uplink, medbay, botany) will now give visual + feedback about how much stuff is left inside, and the color of contents will + match an empty bottle being filled with the same reagent. + - bugfix: Player-controlled "neutral" mobs such as minebots are now considered valid + targets by clock cult's ocular wardens. + Xhuis: + - bugfix: Cogged APCs can now be correctly unlocked with an ID card. + duncathan: + - tweak: Portable air pumps can output to a maximum of 25 atmospheres. + kevinz000: + - refactor: Legacy projectiles have been removed. Instead, all projectiles are now + PIXEL PROJECTILES! + - rscadd: Reflectors can now be at any angle you want. Alt click them to set angle! + - rscadd: Pipes can now be layered up to 3 layers. +2017-10-18: + DaxDupont: + - bugfix: Fixes automatic fire on guns. + Gun Hog: + - bugfix: The GPS item now correctly changes its name when the GPS tag is changed. + Improvedname: + - tweak: Reverts katana's to its orginal size being huge + Mercenaryblue: + - balance: it should be far easier to clean out your face from multiple cream pies. + More Robust Than You: + - tweak: People that are burning slightly less will appear to be burning... slightly + less. + Robustin: + - bugfix: The smoke machine now properly generates transparent smoke, transmits + chemicals, and displays the proper icons. + ShizCalev: + - tweak: You can no longer build reinforced floors directly on top of dirt, asteroid + sand, ice, or beaches. You'll have to first construct flooring on top of it + instead. + - bugfix: Corrected mapping issues introduced with the latest SM engine/radiation + update across all relevant maps. + - bugfix: The tools on the Caravan Ambush space ruin have had their speeds corrected. + - bugfix: Slappers will no longer appear as a latex balloon in your hand. + - bugfix: Renault now has a comfy new bed on Metastation! + - tweak: Engineering cyborgs now have access to geiger counters. + Xhuis: + - bugfix: You can no longer pick up brass chairs. + Y0SH1_M4S73R: + - bugfix: Disabling leg actuators sets the power drain per step to the correct value. + duncathan: + - bugfix: Filters no longer stop passing any gas through if the filtered output + is full. + ninjanomnom: + - rscadd: You can vomit blood at high enough radiation. + - balance: Radiation knockdown is far far shorter. + - balance: Genetics modification is less harmful but still, upgrade your machines. + - balance: Pentetic acid is useless for low amounts of radiation but indispensable + for high amounts now. + - balance: Singularity radiation has been normalized and Pubby engine has been remapped. + - bugfix: No more hair loss spam + - bugfix: Mob rad contamination has been disabled for now. Regular contamination + is still a thing. + - bugfix: Fixed turfs not rotating + - bugfix: Fixed stealing structures you shouldn't be moving +2017-10-19: + Kor: + - rscadd: Blob is now a side antagonist. + - rscadd: Event and admin blobs will now be able to choose their spawn location. + - rscadd: Blob can now win in any mode by gaining enough tiles to reach Critical + Mass. + - rscadd: Blobs that have Critical Mass have unlimited points, and a minute after + achieving critical mass, they will spread to every tile on station, killing + anyone still on board and ending the round. + - rscadd: Using an analyzer on a blob will now reveal its progress towards Critical + Mass. + - rscadd: The blob event is now more common. + Mercenaryblue: + - tweak: You will no longer trip on inactive honkbots. + - bugfix: Sentient Honkbots are no longer forced to speak when somebody trip on + them. + Naksu: + - bugfix: Manned turrets stop firing when there's no-one in the turret shooting. + - refactor: 'mobs will enter a deep power-saving state when there''s not much to + do except wander around. change: bees are slightly more passive in general' + deathride58: + - tweak: You can now press Ctrl+H to stop pulling, or simply H to stop pulling if + you're in hotkey mode. + ninjanomnom: + - rscadd: Engineering scanner goggles have a radiation mode now + - rscadd: Objects placed under showers are cleansed of radioactive contamination + over a short time. + - soundadd: Showers make sound now. + oranges: + - rscdel: Removed the bluespace pipe +2017-10-20: + Kor: + - rscadd: You can now select your Halloween race, rather than having it assigned + randomly via event. + Robustin: + - bugfix: Fixed a bug where detonating maxcaps, especially multiple maxcaps, on + Reebe guaranteed that everyone would die and thus the Clock Cult would immediately + lose; Reebe maxcap is now 2/5/10. + ShizCalev: + - bugfix: All reflector prisms/mirrors have had their angles corrected. + - tweak: Remains left over by dusting or soul-stoning a mob are now dissoluble with + acid. + - tweak: Changelings using biodegrade to escape restraints will now leave a pile + of goop. + - bugfix: Fixed messages related to changelings using biodegrade not appearing. +2017-10-21: + More Robust Than You: + - bugfix: Heads of staff will now have cat organs removed at roundstart + Robustin: + - balance: Spray tan no longer stuns when ingested. + Thunder12345: + - bugfix: Sentient cats no longer forget to fall over when they die +2017-10-22: + More Robust Than You: + - bugfix: Blood Brother now properly shows up in player panel + Naksu: + - server: Paper bins no longer let server admins know that pens were eaten. + - code_imp: Removed dangling mob references to last attacker/attacked + Robustin: + - balance: Medical biosuits (and hardsuits) now offer heavy, but not complete, radiation + resistance. + ninjanomnom: + - bugfix: Contents of silicon mobs are no longer considered for targets of radiation. + This blocks them from being contaminated. +2017-10-24: + Armhulen: + - rscadd: Wizards may now shapeshift into viper spiders. + Improvedname: + - tweak: Blacklists holoparasite's from surplus crates + Kor: + - rscadd: Added dullahans, which will be available from the character set up menu + during the Halloween event. + - bugfix: Severed heads will no longer appear bald. + More Robust Than You: + - bugfix: Fixes champrojector camera bugs + Naksu: + - bugfix: Grinders will now grind grown items like cocoa pods again + - code_imp: Cameras no longer keep hard references to mobs in their motion tracking + list. + ShizCalev: + - bugfix: Creatures made via gold slime cores will now be given the proper name + of their master. + deathride58: + - tweak: Deltastation's armory now contains reinforced windows surrounding the lethal + weaponry. This makes Delta's armory consistent with Box. + - tweak: There are now decals in places where extra Security lockers can spawn. + - tweak: Cleaned up semicolons in Meta and Boxstation's .dmms +2017-10-25: + Cruix: + - rscadd: Shuttle navigation computers can now place new transit locations over + the shuttle's current position. + JJRcop: + - rscadd: The heart of darkness revives you as a shadowperson if you aren't one + already. + ShizCalev: + - bugfix: Shades will no longer always hear a heartbeat. + - bugfix: Golem abilities will now be start on cooldown when they are made. +2017-10-26: + Kor and JJRcop: + - rscadd: Added vampires. They will be available as a roundstart race during the + Halloween holiday event. + ShizCalev: + - bugfix: Reflectors will no longer drop more materials than they took to make when + deconstructed. + - bugfix: You will no longer be prompted to reenter your body while being defibbed + if you can't actually be revived. + - bugfix: You can no longer teleport past the ticket stands of the Luxury Emergency + Shuttle. + - bugfix: Lightgeists can now -actually- be spawned with gold slime cores. + - tweak: The Staff of Change will now randomly assign a cyborg module when transforming + a mob into a cyborg. + Xhuis: + - balance: Clockwork marauders now move more slowly below 40% health. + - balance: Instead of a 40% chance (or more) chance to block projectiles, clockwork + marauders now have three fixed 100% blocks; after using those three, they cannot + block anymore without avoiding projectiles for ten seconds. This number increases + to four if war is declared. + - balance: Projectiles that deal no damage DO reduce marauders' shield health. Use + disabler shots to open them up, then use lasers to go for the kill! + - bugfix: Cogscarab shells and marauder armor now appear in the spawners menu. + - bugfix: You can no longer stack infinitely many stargazers on one tile. + nicbn: + - imageadd: Chemical heater and smoke machine resprited. + ninjanomnom: + - soundadd: Portable generators have a sound while active. + - soundadd: The supermatter has a sound that scales with stored energy. + ninjanomnom & Wjohn: + - bugfix: Cable cuffs now inherit the color of the cables used to make them. + - bugfix: Split cable stacks keep their color. + - tweak: The blue cable color is now a better blue. +2017-10-27: + Anonmare: + - rscadd: Adds new grindables + JamieH: + - rscadd: Buildmode map generators will now show you a preview of the area you're + changing + - rscadd: Buildmode map generators will now ask before nuking the map + - bugfix: Buildmode map generator corners can now only be set by left clicking + Kor: + - rscadd: Cloth golems will be available as a roundstart race during Halloween. + MrStonedOne: + - code_imp: Created a system to profile code on a line by line basis and return + detailed info about how much time was spent (in milliseconds) on each line(s). + Xhuis: + - balance: Servants can no longer teleport into the gravity generator, EVA, or telecomms. + ninjanomnom: + - bugfix: Hardsuit helmets work like geiger counters for the user. + - code_imp: Radiation should perform a little better in places. + - balance: Various radiation symptom thresholds have been tweaked. + - balance: Contamination strengths at different ranges have been tweaked. + - balance: Contaminated objects have less range for their radiation. + - balance: Hitting something with a contaminated object reduces its strength faster. + - balance: Contaminated objects decay faster. + - balance: Both radiation healing medicines have been buffed a bit. + - balance: Passive radiation loss for mobs is nerfed. + - balance: There is a soft cap for mob radiation now. + - balance: Projectiles, ammo casings, and implants are disallowed from becoming + contaminated. + - rscadd: Suit storage units can completely cleanse contamination from stored objects + - admin: The first time an object is contaminated enough to spread more contamination + admins will be warned. This is also added to stat tracking. + - rscadd: Thermite works on floors and can be ignited by sufficiently hot fires + now + - refactor: Thermite has been made into a component + - bugfix: Thermite no longer removes existing overlays on turfs +2017-10-28: + Mark9013100: + - tweak: The Medical Cloning manual has been updated. +2017-10-29: + Armhulen: + - rscadd: Frost Spiders now use Frost OIL! + Mercenaryblue: + - rscadd: Skeletons can now have their own spectral instruments + - rscadd: \[Dooting Intensifies\] + - admin: the variable "too_spooky" defines if it will spawn new instruments, by + default TRUE. + Naksu: + - bugfix: Removed meteor-related free lag + - bugfix: Cleaned up dangling mob references from alerts + Xhuis: + - bugfix: You can no longer become an enhanced clockwork golem with mutation toxin. + - balance: Normal clockwork golems now have 20% armor, down from 40%. + as334: + - spellcheck: This changelog has been updated and so read it again if you are interested + in doing assmos. + - rscadd: Atmospherics has been massively expanded including new gases. + - rscadd: These new gases include Brown Gas, Pluoxium, Stimulum, Hyper-Noblium and + Tritium. + - rscadd: Brown Gas is acidic to breath, but mildly stimulation. + - rscadd: Stimulum is more stimulating and much safer. + - rscadd: Pluoxium is a non-reactive form of oxygen that delivers more oxygen into + the bloodstream. + - rscadd: Hyper-Noblium is an extremely noble gas, and stops gases from reacting. + - rscadd: Tritium is radioactive and flammable. + - rscadd: New reactions have also been added to create these gases. + - rscadd: 'Tritium formation: Heat large amounts of oxygen with plasma. Make sure + you have a filter ready and setup!' + - rscadd: Fusion has been reintroduced. Plasma will fuse when heated to a high thermal + energy with Tritium as a catalyst. Make sure to manage the waste products. + - rscadd: 'Brown Gas formation: Heat Oxygen and Nitrogen.' + - rscadd: 'BZ fixation: Heat Tritium and Plasma.' + - rscadd: 'Stimulum formation: Heated Tritium, Plasma, BZ and Brown Gas.' + - rscadd: 'Hyper-Noblium condensation: Needs Nitrogen and Tritium at a super high + heat. Cools rapidly.' + - rscadd: Pluoxium is unable to be formed. + - rscdel: Freon has been removed. Use cold nitrogen for your SME problems now. + - rscadd: Water vapor now freezes the tile it is on when it is cooled heavily. + naltronix: + - bugfix: fixes that table that wasnt accessible in Metastation +2017-10-30: + PKPenguin321: + - tweak: You can now use beakers/cups/etc that have welding fuel in them on welders + to refuel them. + bgobandit: + - tweak: 'Due to cuts to Nanotrasen''s Occupational Safety and Health Administration + (NO-SHA) budget, station fixtures no longer undergo as much safety testing. + (Translation for rank and file staff: More objects on the station will hurt + you.)' diff --git a/html/changelogs/archive/2017-11.yml b/html/changelogs/archive/2017-11.yml new file mode 100644 index 0000000000..19691b29ee --- /dev/null +++ b/html/changelogs/archive/2017-11.yml @@ -0,0 +1,535 @@ +2017-11-02: + ACCount: + - tweak: '"Tail removal" and "tail attachment" surgeries are merged with "organ + manipulation".' + - imageadd: New sprites for reflectors. They finally look like something. + - rscadd: You can lock reflector's rotation by using a screwdriver. Use the screwdriver + again to unlock it. + - rscadd: Reflector examine now shows the current angle and rotation lock status. + - rscadd: You can now use a welder to repair damaged reflectors. + - bugfix: Multiple reflector bugs are fixed. + Improvedname: + - rscdel: Removes statues from gold slime pool + Mercenaryblue: + - imageadd: Updated Clown Box sprite to match the others. + More Robust Than You: + - admin: ONLY ADMINS CAN ACTIVATE THE ARK NOW + - tweak: The Ark's time measurements are now a bit more readable + MrStonedOne: + - tweak: Meteor events will not happen before 25 minutes, the worst versions before + 35 and 45 minutes. + - tweak: Meteor events are now player gated to 15, 20, and 25 players respectively + - balance: The more destructive versions of meteor events now have a slightly higher + chance of triggering, to offset the decrease in how often it is that they will + even qualify. + - bugfix: Fixed the changelog generator. + Naksu: + - tweak: Smartfridges and chem/condimasters now output items in a deterministic + 3x3 grid rather than in a huge pile in the middle of the tile. + SpaceManiac: + - bugfix: Admins can once again spawn nuke teams on demand. + Xhuis: + - admin: Admins can now create sound emitters (/obj/effect/sound_emitter) that can + be customized to play sounds to different people, at different volumes, and + at different locations such as by z-level. They're much more versatile for events + than the Play Sound commands! + - rscadd: You can now add grenades to plushies! You'll need to cut out the stuffing + first. + - tweak: Clockwork cult tips of the round have been updated to match the rework. + - tweak: Abscond and Reebe rifts now place servants directly at the Ark instead + of below the "base" area. + nicbn: + - tweak: Brown gas renamed to nitryl. + ninjanomnom: + - bugfix: Fixes decals not rotating correctly with the turf. + - bugfix: Fixes a runtime causing some turfs to be left behind by removed shuttles. + - code_imp: Shuttles should be roughly 40-50% smoother. + - bugfix: Fixes the cargo shuttle occasionally breaking if a mob got on at exactly + the right time. +2017-11-10: + Anonmare: + - bugfix: Adds an organ storage bag to the syndicate medborg. + AnturK: + - balance: Dying in shapeshifted form reverts you to the original one. (You're still + dead) + Floyd / Qustinnus: + - soundadd: Redtexting as a traitor now plays a depressing tune to you + Floyd / Qustinnus (And all the sounds by Kayozz11 from Yogstation): + - soundadd: Adds about 30 new ambience sounds + - refactor: added new defines for ambience lists. + Iamgoofball: + - tweak: Cooldown on the Ripley's mining drills has been halved. + - tweak: The frequency of the Ripley's ore pulse has been doubled. + Jalleo: + - tweak: Removed a variable to state which RCD's can deconstruct reinforced walls + - balance: Made combat (ERT ones) and admin RCDs able to deconstruct r walls alongside + borg ones + Kor: + - bugfix: Cult mode will once again print out names at round end. + Mark9013100: + - rscadd: Deltastation now has a Whiteship. + - tweak: Charcoal bottles have been renamed, and have been given a more informative + description. + Mercenaryblue: + - spellcheck: spellchecked the hotel staff. + - rscadd: Added frog masks. Reeeeeeeeee!! + More Robust Than You: + - bugfix: Blobbernauts and spores are no longer killed by blob victory + - bugfix: New blob overminds off the station Z level are moved to the station + - bugfix: You can now use banhammers as a weapon + - tweak: Monkeys can no longer transmit diseases through hardsuits + - tweak: Xenobio blobbernauts can no longer walk on blob tiles + Naksu: + - tweak: Added deterministic output slots to the slime processor + - bugfix: Fixed some interactions with ghosts and items + - bugfix: Nonhumans such as monkeys can now be scanned for chemicals with the health + analyzer. + Okand37 (DeltaStation Updates): + - rscadd: Tweaked Atmospherics + - bugfix: Fixed the Incinerator air injector + - rscadd: Tweaked Engineering + - rscadd: Added logs to the Chaplain's closet for gimmicks (bonfires) + - rscadd: Tweaked Security + - bugfix: Fixed medical morgue maintenance not providing radiation shielding and + exterior chemistry windoor + - rscadd: Bar now has a door from the backroom to the theatre stage + - rscadd: Tweaked Locker Room/Dormitories + ShizCalev: + - bugfix: You can now -actually- load pie cannons. + - bugfix: The captain's winter coat can now hold a flashlight. + - bugfix: The captain's and security winter coats can now hold internals tanks. + - tweak: All winter coats can now hold toys, lighters, and cigarettes. + - tweak: The captain's hardsuit can now hold pepperspray. + - rscadd: Updated the Test Map debugging verb to report more issues regarding APCs. + DELTASTATION + - bugfix: Reverted Okand37's morgue changes which broke power in the area. + - bugfix: Corrected wrong area on the Southern airlock leading into electrical maintenance. + ALL STATIONS + - bugfix: Corrected numerous duplicate APCs in areas which led to power issues. + SpaceManiac: + - bugfix: Ghosts can no longer create sparks from the hand teleporter's portals. + - bugfix: Digging on Lavaland no longer shows two progress bars. + - bugfix: The holodeck now has an "Offline" option. + - bugfix: Injury and crit overlays are now scaled properly for zoomed-out views. + - bugfix: Already-downloaded software is now hidden from the NTNet software downloader. + - bugfix: The crafting, language, and building buttons are now positioned correctly + in zoomed-out views. + - bugfix: Bluespace shelter walls no longer smooth with non-shelter walls and windows. + Swindly: + - rscadd: Organ storage bags can be used to perform limb augmentation. + - bugfix: You can now cancel a cavity implant during the implanting/removing step + by using drapes while holding the appropriate tool in your inactive hand. Cyborgs + can cancel the surgery by using drapes alone. + - bugfix: Fixed hot items and fire heating reagents to temperatures higher than + their heat source. + - bugfix: Sprays can now be heated with hot items. + - tweak: The heating of reagents by hot items, fire, and microwaves now scales linearly + with the difference between the reagent holder's temperature and the heat source's + temperature instead of constantly. + - tweak: The body temperature of a mob with reagents is affected by the temperature + of the mob's reagents. + - tweak: Reagent containers can now be heated by hot air. + Thefastfoodguy: + - bugfix: Spamming runes / battlecries / etc will no longer trigger spam prevention + WJohnston: + - bugfix: Ancient station lighting fixed on beta side (medical and atmos remains) + XDTM: + - rscadd: Ghosts now have a Toggle Health Scan verb, which allows them to health + scan mobs they click on. + Xhuis: + - rscadd: Ratvar and Nar-Sie plushes now have a unique interaction. + - balance: Clockwork marauders are now on harm intent. + - balance: The Clockwork Marauder scripture now takes five seconds longer to invoke + per marauder summoned in the last 20 seconds, capping at 30 extra seconds. + - balance: Clockwork marauders no longer gain a health bonus when war is declared. + - tweak: Moved the BoxStation deep fryers up one tile. + - rscadd: Microwaves have new sounds! + YPOQ: + - bugfix: EMPs can pulse multiple wires + as334: + - rscadd: Pluoxium can now be formed by irradiating tiles with CO2 in the air. + - rscadd: Rad collectors now steadily form Tritium at a slow pace. + - balance: Nerfs fusion by making it slower, and produce radioactivity. + - balance: Noblium formation now requires significantly more energy input. + - balance: Tanks now melt if their temperature is above 1 Million Kelvin. + deathride58: + - bugfix: Directional character icon previews now function properly. Other things + relying on getflaticon probably work with directional icons again, as well. + nicbn: + - imageadd: Canister sprites for the new gases + ninjanomnom: + - bugfix: Shuttle parallax has been fixed once more + - bugfix: You can no longer set up the auxiliary base's shuttle beacon overlapping + with the edge of the map + uraniummeltdown: + - tweak: Replica fabricatoring airlocks and windoors keeps the old name + - tweak: Narsie and Ratvar converting airlocks and windoors keeps the old name +2017-11-11: + DaxDupont: + - bugfix: Medbots can inject from one tile away again. + SpaceManiac: + - bugfix: The detective and heads of staff are no longer attacked by portable turrets. + deathride58: + - bugfix: You can no longer delete girders, lattices, or catwalks with the RPD + - bugfix: Fixes runtimes that occur when clicking girders, lattices, catwalks, or + disposal pipes with the RPD in paint mode + ninjanomnom: + - bugfix: Fixes ruin cable spawning and probably some other bugs +2017-11-12: + Cyberboss: + - bugfix: Clockwork slabs no longer refer to components +2017-11-13: + Cobby: + - rscadd: The Xray now only hits the first mob it comes into contact with instead + of being outright removed from the game. + Floyd / Qustinnus: + - soundadd: Reebe now has ambience sounds + 'Floyd / Qustinnus:': + - soundadd: Adds a few sound_loop datums to machinery. + Frozenguy5: + - bugfix: Broken cable cuffs no longer has an invisible sprite. + PKPenguin321: + - rscadd: Welders must now be screwdrivered open to reveal their fuel tank. + - rscadd: You can empty welders into open containers (like beakers or glasses) when + they're screwdrivered open. + - rscadd: You can now insert any chemical into a welder, but all most will do is + clog the fuel. Welding fuel will refuel it as usual. Plasma in welders tends + to explode. + Qbopper and JJRcop: + - tweak: The default internet sound volume was changed from 100 to 25. Stop complaining + in OOC about your ears! + SpaceManiac: + - bugfix: Posters may no longer be placed on diagonal wall corners. + WJohnston: + - rscdel: Removes stationary docking ports for syndicate infiltrator ships on all + maps. Use the docking navigator computer instead! This gives the white ship + and syndicate infiltrator more room to navigate and place custom locations that + are otherwise occupied by fixed shuttle landing zones that are rarely used. + Xhuis: + - rscadd: Deep fryers now have sound. + - tweak: Deep fryers now use cooking oil, a specialized reagent that becomes highly + damaging at high temperatures. You can get it from grinding soybeans and meat. + - tweak: Deep fryers now become more efficient with higher-level micro lasers, using + less oil and frying faster. + - tweak: Deep fryers now slowly use oil as it fries objects, instead of all at once. + - bugfix: You can now correctly refill deep fryers with syringes and pills. + nicn: + - balance: Damage from low pressure has been doubled. + ninjanomnom: + - rscadd: You can now select a nearby area to expand when using a blueprint instead + of making a new area. + - rscadd: New shuttle areas can be created using blueprints. This is currently not + useful but will be used later for shuttle construction. + - tweak: Blueprints can modify existing areas on station. + - admin: Blueprint functionality has been added to the debug tab as a verb. +2017-11-14: + ike709: + - imageadd: Added directional computer sprites. Maps haven't been changed yet. + psykzz: + - refactor: AI Airlock UI to use TGUI + - tweak: Allow AI to swap between electrified door states without having to un-electrify + first. + selea/arsserpentarium: + - rscadd: Integrated circuits have been added to Research! + - rscadd: You can use these to create devices with very complex behaviors. + - rscadd: Research the Integrated circuits printer to get started. +2017-11-15: + Fury: + - rscadd: Added new sprites for the Heirophant Relay (clock cultist telecomms equipment). + Naksu: + - bugfix: 'Removed fire-related free lag. change: fire alarms and cameras no longer + work after being ripped off a wall by a singulo' + - tweak: 'Minor speedups to movement processing. change: Fat mobs no longer gain + temperature by running.' + Robustin: + - refactor: Cult population scaling no longer operates on arbitrary breakpoints. + Each additional player between the between the breakpoints will add to the "chance" + that an additional cultist will spawn. + - tweak: On average you will see less roundstart cultists in lowpop and more roundstart + cultists in highpop. + - tweak: Damage examinations now include a "moderate" classification. Before minor + was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 + to <50, and severe is 50+. + - tweak: The tesla will now move toward power beacons at a significantly slower + rate. + SpaceManiac: + - bugfix: The post-round station integrity report is now functional again. + ninjanomnom: + - bugfix: Gas overlays no longer block clicks, on 512 +2017-11-22: + ACCount: + - refactor: Old integrated circuit save file format is ditched in favor of JSON. + Readability, both of save files and save code, is improved greatly. + - tweak: Integrated circuit panels now open with screwdriver instead of crowbar, + to match every single other thing on this server. + - tweak: Integrated circuit printer now stores up to 25 metal sheets. + - bugfix: Fixed integrated circuit rechargers not recharging guns properly and not + updating icons. + - bugfix: Fixed multiple bugs in integrated circuits UIs, improved overall usability. + Anonmare: + - balance: Laserpoitners now incapcitate catpeople + AutomaticFrenzy: + - bugfix: cell chargers weren't animating properly + - bugfix: disable_warning wasn't getting checked and the chat was being spammed + Code by Pyko, Ported by Frozenguy5: + - rscadd: Rat Kebabs and Double Rat Kebabs have been added! + Cyberboss: + - server: Server tools API changed to version 3.2.0.1 + - admin: '"ahelp" chat command can now accept a ticket number as opposed to a ckey' + DaxDupont: + - tweak: CentCom has issued a firmware updated for the operating computers. It is + no longer needed to manually refresh the procedure and patient status. + - bugfix: Proximity sensors no longer beep when unarmed. + - bugfix: Plant trays will now properly process fluorine and adjust toxins and water + contents. + Francinum: + - tweak: The shuttle build plate is now better sized for all stations. + Iamgoofball: + - spellcheck: fixes grammar on logic gate descriptions + - spellcheck: fixes grammar on list circuits + - bugfix: fixes grammar on trig circuits + - spellcheck: fixed grammar on output circuits + JJRcop: + - bugfix: Fixes changeling eggs not putting the changeling in control if the brainslug + is destroyed before hatching. + - tweak: The silicon airlock menu looks a little more like it used to. + Kor: + - bugfix: Blobbernauts will no longer spawn if a player is not selected to control + it, preventing AI blobbernauts from running off the blob and to their deaths. + - rscdel: Following complaints that cargo has been selling all the materials they + receive rather than distributing them, mineral exporting has been removed. + MMMiracles: + - balance: Power regen on the regular tesla relay has been reduced to 50, from 150. + Naksu: + - bugfix: Sped up saycode to remove free lag from highpop + - bugfix: Using a chameleon projector will now dismount you from any vehicles you + are riding, in order to prevent wacky space glitches and being sent to a realm + outside space and time. + Shadowlight213: + - code_imp: Added round id to the status world topic + ShizCalev: + - bugfix: Chameleon goggles will no longer go invisible when selecting Optical Tray + scanners. + - rscadd: Engineering and Atmos scanner goggles will now have correctly colored + inhand sprites. + - tweak: The computers on all maps have have been updated for the latest directional + sprite changes. Please report any computers facing in strange directions to + your nearest mapper. + - bugfix: MetaStation - The consoles in medbay have had their directions corrected. + - imageadd: The Nanotrasen logo on modular computers has been fixed, rejoice! + - bugfix: PubbyStation - Unpowered air injectors in various locations have been + fixed. + - bugfix: MetaStation - Air injector leading out of the incinerator has been fixed + - bugfix: MetaStation - Corrected a couple maintenance airlocks being powered by + the wrong areas. + - bugfix: Computers will no longer rotate incorrectly when being deconstructed. + - bugfix: You can now rotate computer frames during construction. + - bugfix: Chairs, PA parts, infrared emitters, and doppler arrays will now rotate + clockwise. + - bugfix: Throwing drinking glasses and cartons will now consistently cause them + to break! + - bugfix: Humans missing legs or are legcuffed will no longer move slower in areas + without gravity. + - bugfix: The structures external to stations are now properly lit. Make sure you + bring a flashlight. + - bugfix: Computers will no longer delete themselves when being built, whoops! + - bugfix: Space cats will no longer have a smashed helmet when they lay down. + Skylar Lineman, your local R&D moonlighter: + - rscadd: Research has been completely overhauled into the techweb system! No more + levels, the station now unlocks research "nodes" with research points passively + generated when there is atleast one research server properly cooled, powered, + and online. + - rscadd: R&D lab has been replaced by the departmental lathe system on the three + major maps. Each department gets a lathe and possibly a circuit imprinter that + only have designs assigned by that department. + - rscadd: The ore redemption machine has been moved into cargo bay on maps with + decentralized research to prevent the hallways from becoming a free for all. + Honk! + - balance: You shouldn't expect balance as this is the initial merge. Please put + all feedback and concerns on the forum so we can revise the system over the + days, weeks, and months, to make this enjoyable for everyone. Heavily wanted + are ideas of how to add more ways of generating points. + - balance: You can get techweb points by setting off bombs with an active science + doppler array listening. The bombs have to have a theoretical radius far above + maxcap to make a difference. You can only go up, not down, in radius, so you + can't get 6 times the points with 6 TTVs. The algorithm is exponentially/logarithmically + scaled to prevent "world destroyer" bombs from instantly finishing research. + SpaceManiac: + - bugfix: HUDs from mechs and helmets no longer conflict with HUD glasses and no + longer inappropriately remove implanted HUDs. + - code_imp: Chasm code has been refactored to be more sane. + - bugfix: Building lattices over chasms no longer sometimes deletes the chasm. + - code_imp: Ladders have been refactored and should be far less buggy. + - bugfix: Jacob's ladder actually works again. + - bugfix: Pizza box stacking works again. + - bugfix: Fix some permanent-on and permanent-off bugs caused by the HUD stacking + change. + WJohnston: + - imageadd: A bunch of new turf decals for mappers to play with, coming in yellow, + white, and red varieties! + - bugfix: Green banded default airlocks now have extended click area like all other + airlocks. + Y0SH1 M4S73R: + - spellcheck: The R&D Server's name is now improper. + - spellcheck: The R&D Server now has an explanation of what it does. + arsserpentarium: + - bugfix: now lists should work properly + duncathan: + - rscadd: The RPD has a shiny new UI! + - rscadd: The RPD can now paint pipes as it lays them, for quicker piping projects. + - rscadd: Atmos scrubbers (vent and portable) can now filter any and all gases. + ike709: + - imageadd: Added new vent and scrubber sprites by Partheo. + - bugfix: Fixed some computers facing the wrong direction. + jammer312: + - bugfix: fixed conjuration spells forgetting about conjured items + kevinz000: + - rscadd: purple bartender suit and apron added to clothesmates! + - rscadd: long hair 3 added, check it out. both have sprites from okand! + nicbn: + - soundadd: Now rolling beds and office chairs have a sound! + oranges: + - rscdel: Removed the shocker circuit + psykzz: + - imageadd: Grilles have new damaged and default sprites + - rscadd: Added TGUI for Turbine computer + tserpas1289: + - tweak: Any suit that could hold emergency oxygen tanks can now also hold plasma + man internals + - tweak: Hydroponics winter coats now can hold emergency oxygen tanks just like + the other winter coats. + - bugfix: Plasma men jumpsuits can now hold accessories like pocket protectors and + medals. + zennerx: + - bugfix: fixed a bug that made you try and scream while unconscious due to a fire + - tweak: Skateboard crashes now give slight brain damage! + - rscadd: Using a helmet prevents brain damage from the skateboard! +2017-11-23: + GupGup: + - bugfix: Fixes hostile mobs attacking surrounding tiles when trying to attack someone + MrStonedOne and Jordie: + - server: As a late note, serverops be advise that mysql is no longer supported. + existing mysql databases will need to be converted to mariadb + Robustin: + - tweak: RND consoles will no longer display options for machines or disks that + are not connected/inserted. + ShizCalev: + - bugfix: Aliens in soft-crit will now use the correct sprite. + XDTM: + - rscadd: 'Added two new symptoms: one allows viruses to still work while dead, + and allows infection of undead species, and one allows infection of inorganic + species (such as plasmapeople or golems).' +2017-11-24: + ACCount: + - rscdel: Removed "console screen" stock part. Just use glass sheets instead. + More Robust Than You: + - tweak: Spessmen are now smart enough to realize you don't need to turn around + to pull cigarette butts + SpaceManiac: + - bugfix: Fix water misters being inappropriately glued to hands in some cases. + - bugfix: Some misplaced decals in the Hotel brig have been corrected. + ninjanomnom: + - bugfix: Custom shuttle dockers can no longer place docking regions inside other + custom docker regions. +2017-11-25: + CosmicScientist: + - bugfix: bolas are back in tablecrafting! + Dorsisdwarf: + - tweak: Catpeople are now distracted instead of debilitated + - rscadd: Normal cats now go for laser pointers + SpaceManiac: + - bugfix: You can no longer buckle people to roller beds from inside of a locker. + YPOQ: + - bugfix: AIs and cyborgs can interact with unscrewed airlocks and APCs. + ninjanomnom: + - bugfix: Fixes thermite burning hotter than the boiling point of stone + zennerx: + - bugfix: Zombies don't reanimate with no head! +2017-11-27: + ACCount: + - rscadd: 'New integrated circuit components: list constructors/deconstructors. + Useful for building lists and taking them apart.' + - bugfix: Fixed multiple bugs in integrated circuits UIs, improved overall usability. + More Robust Than You: + - bugfix: Fixed cult leaders being de-culted upon election if they had a mindshield + implant + Naksu: + - bugfix: Hopefully fixed mesons granting the ability to hear people through walls. + Okand37: + - rscadd: Re-organized Delta's departmental protolathes for all departments. + - rscadd: Re-organized Delta's ORM placement by connecting it to the mining office, + which now has a desk for over handing materials to the outside. + - rscadd: Added a second Nanomed to Deltastation's medical bay. + - rscadd: Nanotrasen has decided to add proper caution signs to most docking ports + on Deltastation, warning individuals to be cautious around these areas. + - rscadd: Two health sensors are now placed in Deltastation's robotics area for + medibots. + - bugfix: Atmospheric Technicians at Deltastation can now open up their gas storage + in the supermatter power area as intended. + WJohnston: + - bugfix: Fixed a case where items would sometimes be placed underneath racks. + XDTM: + - balance: Viruses' healing symptoms have been reworked! + - rscdel: All existing healing symptoms have been removed in favour of new ones. + - rscdel: Weight Even and Weight Gain have been removed, so hunger can be used for + balancing in symptoms. + - rscadd: Starlight Condensation heals toxin damage if you're in space using starlight + as a catalyst. Being up to two tiles away also works, as long as you can still + see it, but slower. + - rscadd: Toxolysis (level 7) rapidly cleanses all chemicals from the body, with + no exception. + - rscadd: 'Cellular Molding heals brute damage depending on your body temperature: + the higher the temperature, the faster the healing. Requires above-average temperature + to activate, and the speed heavily increases while on fire.' + - rscadd: Regenerative Coma (level 8) causes the virus to send you into a deep coma + when you are heavily damaged (>70 brute+burn damage). While you are unconscious, + either from the virus or from other sources, the virus will heal both brute + and burn damage fairly quickly. Sleeping also works, but at reduced speed. + - rscadd: Tissue Hydration heals burn damage if you are wet (negative fire stacks) + or if you have water in your bloodstream. + - rscadd: Plasma Fixation (level 8) stabilizes temperature and heals burns while + plasma is in your body or while standing in a plasma cloud. Does not protect + from the poisoning effects of plasma. + - rscadd: Radioactive Resonance gives a mild constant brute and burn healing while + irradiated. The healing becomes more intense if you reach higher levels of radiation, + but is still less than the alternatives. + - rscadd: Metabolic Boost (level 7) doubles the rate at which you process chemicals, + good and bad, but also increases hunger tenfold. + kevinz000: + - bugfix: Cryo cells can now be properly rotated with a wrench. + ninjanomnom: + - rscadd: 'You can now make a new tasty traditional treat: butterdogs. Watch out, + they''re slippery.' +2017-11-28: + ACCount: + - rscdel: '"Machine prototype" is removed from the game.' + - rscdel: Mass-spectrometers are removed. Would anyone notice if not for this changelog + entry? + Cruix: + - rscadd: AI and observer diagnostic huds will now show the astar path of all bots, + and Pai bots will be given a visible path to follow when called by the AI. + JJRcop: + - admin: Fixed the Make space ninja verb. + Naksu: + - code_imp: rejiggered botcode a little bit + SpaceManiac: + - spellcheck: Admin-added "download research" objectives are now consistent with + automatic ones. + improvedname: + - tweak: toolbelts can now carry geiger counters + uraniummeltdown: + - rscadd: You can make many different types of office and comfy chairs with metal + - tweak: Stack menus use /datum/browser +2017-11-29: + MrStonedOne: + - tweak: The sloth no longer suspiciously moves fast when gliding between tiles. + - balance: The sloth's movespeed when inhabited by a player has been lowered from + once every 1/5 of a second to once every second. + SpaceManiac: + - spellcheck: The techweb node for mech LMGs no longer claims to be for mech tasers. +2017-11-30: + ninjanomnom: + - tweak: Reduced the max volume of sm by 1/5th and made the upper bounds only play + mid delamination. + psykzz: + - bugfix: Fixing the broken turbine computer diff --git a/html/changelogs/archive/2017-12.yml b/html/changelogs/archive/2017-12.yml new file mode 100644 index 0000000000..cab229dd57 --- /dev/null +++ b/html/changelogs/archive/2017-12.yml @@ -0,0 +1,625 @@ +2017-12-02: + BeeSting12: + - spellcheck: Occupand ---> Occupant on opened cryogenic pods. + - spellcheck: Cyrogenic ---> Cryogenic on opened cryogenic pods. + CosmicScientist: + - rscadd: You can make plushies kiss one another! + Frozenguy5: + - tweak: The Particle Accelerator's wires can no longer be EMP'd + Naksu: + - code_imp: Cleans up some loc assignments + Robustin: + - tweak: Damage examinations now include a "moderate" classification. Before minor + was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 + to <50, and severe is 50+. + - balance: Clockwork magicks will now prevent Bags of Holding from being combined + on Reebe. + - bugfix: Flashes will now burn out AFTER flashing when they fail instead of being + a ticking time bomb that waits to screw you over on your next attempt. + SpaceManiac: + - tweak: The R&D Console has been given a much prettier interface. + - tweak: Research scanner goggles now show materials and technology prospects in + a nicer way. + uraniummeltdown: + - imageadd: Construct shells have a new animated sprite +2017-12-03: + ExcessiveUseOfCobblestone: + - bugfix: You can now lay (buckle!) yourself to a bed to avoid being burnt to a + crisp during "the floor is lava" event. + Robustin: + - tweak: Igniting plasma statues no longer ignores ignition temperature and only + creates as much plasma as was used in its creation. + Xhuis: + - rscadd: Light fixtures now turn an ominous, dim red color when they lose power, + and draw from an internal power cell to maintain it until either the cell dies + (usually after 10 minutes) or power is restored. + - rscadd: You can override emergency light functionality from an APC. You can also + click on individual lights as a cyborg or AI to override them individually. + Traitor AIs also have a new ability that disables emergency lights across the + entire station. + zennerx: + - spellcheck: fixed some typos in the weapon firing mechanism description +2017-12-04: + AnturK: + - rscadd: You can now record and replay holopad messages using holodisks. + - rscadd: Holodisks are printable in autolathes. + Xhuis: + - bugfix: You now need fuel in your welder to repair mechs. +2017-12-05: + Cyberboss: + - sounddel: Reduced the volume of showers + Dax Dupont: + - rscadd: Nanotrasen is happy to announce the pinnacle in plasma research! The Disco + Inferno shuttle design is the result of decades of plasma research. Burn, baby, + burn! + MrPerson & ninjanomnom: + - refactor: Completely changed how keyboard input is read. + - rscadd: Holding two directions at the same time will now move you diagonally. + This works with the arrow keys, wasd, and the numpad. + - tweak: Moving diagonally takes twice as long as moving a cardinal direction. + - bugfix: You can use control to turn using wasd and the numpad instead of just + the arrow keys. + - rscdel: 'Some old non-hotkey mode behaviors, especially in relation to chatbox + interaction, can''t be kept with the new system. Of key note: You can''t type + while walking. This is due to limitations of byond and the work necessary to + overcome it is better done as another overhaul allowing custom controls.' + Robustin: + - rscdel: Reverted changes in 3d sound system that tripled the distance that sound + would carry. + SpaceManiac: + - spellcheck: Energy values are now measured in joules. What was previously 1 unit + is now 1 kJ. + - bugfix: Syndicate uplink implants now work again. + Xhuis: + - tweak: Stethoscopes now inform the user if the target can be defibrillated; the + user will hear a "faint, fluttery pulse." + coiax: + - rscadd: Quiet areas of libraries on station have now been equipped with a vending + machine containing suitable recreational activities. +2017-12-06: + Dax Dupont & Alek2ander: + - tweak: Binary chat messages been made more visible. + Revenant Defile ability: + - bugfix: Revenant's Defile now removes salt piles + XDTM: + - rscadd: 'Brain damage has been completely reworked! remove: Brain damage now no + longer simply makes you dumb. Although most of its effects have been shifted + into a brain trauma.' + - rscadd: Every time you take brain damage, there's a chance you'll suffer a brain + trauma. There are many variations of brain traumas, split in mild, severe, and + special. + - rscadd: Mild brain traumas are the easiest to get, can be lightly to moderately + annoying, and can be cured with mannitol and time. + - rscadd: Severe brain traumas are much rarer and require extensive brain damage + before you have a chance to get them; they are usually very debilitating. Unlike + mild traumas, they require surgery to cure. A new surgery procedure has been + added for this, the aptly named Brain Surgery. It can also heal minor traumas. + - rscadd: 'Special brain traumas are rarely gained in place of Severe traumas: they + are either complex or beneficial. However, they are also even easier to cure + than mild traumas, which means that keeping these will usually mean keeping + a mild trauma along with it.' + - rscadd: Mobs can only naturally have one mild trauma and one severe or special + trauma. + - balance: Brain damage will now kill and ruin the brain if it goes above 200. If + it somehow goes above 400, the brain will melt and be destroyed completely. + - balance: Many brain-damaging effects have been given a damage cap, making them + non-lethal. + - rscdel: The Unintelligible mutation has been removed and made into a brain trauma. + - rscdel: Brain damage no longer makes using machines a living hell. + - rscadd: Abductors give minor traumas to people they experiment on. + coiax: + - rscadd: The drone dispenser on Metastation has been moved to the maintenance by + Robotics. +2017-12-07: + ShizCalev: + - bugfix: Games vending machines can now properly be rebuilt. + - bugfix: Games vending machines can now be refilled via supply crates. + - rscadd: Games Supply Crates have been added to the cargo console. + SpaceManiac: + - bugfix: Radio frequency 148.9 is once again serviced by the telecomms system. + Xhuis: + - rscadd: Added the Eminence role to clockcult! Players can elect themselves or + ghosts as the Eminence from the eminence spire structure on Reebe. + - rscadd: The Eminence is incorporeal and invisible, and directs the entire cult. + Anything they say is heard over the Hierophant network, and they can issue commands + by middle-clicking themselves or different turfs. + - rscadd: The Eminence also has a single-use mass recall that warps all servants + to the Ark chamber. + - rscadd: Added traps, triggers, and brass filaments to link them. They can all + be constructed from brass sheets, and do different things and trigger in different + ways. Current traps include the brass skewer and steam vent, and triggers include + the pressure sensor, lever, and repeater. + - rscadd: The Eminence can activate trap triggers by clicking on them! + - rscadd: Servants can deconstruct traps instantly with a wrench. + - rscdel: Mending Mantra has been removed. + - tweak: Clockwork scriptures have been recolored and sorted based on their functions; + yellow scriptures are for construction, red for offense, blue for defense, and + purple for niche. + - balance: Servants now spawn with a PDA and black shoes to make disguise more feasible. + - balance: The Eminence can superheat up to 20 clockwork walls at a time. Superheated + walls are immune to hulk and mech punches, but can still be broken conventionally. + - balance: Clockwork walls are slightly faster to build before the Ark activates, + taking an extra second less. + - bugfix: Poly no longer continually undergoes binary fission when Ratvar is in + range. + - code_imp: The global records alert for servants will no longer display info that + doesn't affect them since the rework. + coiax: + - rscadd: The drone dispenser on Box Station has been moved from the Testing Lab + to the Morgue/Robotics maintenance tunnel. + deathride58: + - config: The default view range can now be defined in the config. The default is + 15x15, which is simplified to 7 by BYOND. For reference, Goonstation's widescreen + range is 21x15. Do note that changing this value will affect the title screen. + The title screen images and the title screen area on the Centcom z-level will + have to be updated if the default view range is changed. +2017-12-08: + Dax Dupont: + - bugfix: Fixed observer chat flavor of silicon chat. + - bugfix: Grilles now no longer revert to a pre-broken icon state when you hit them + after they broke. + Dorsisdwarf: + - tweak: Minor fixes to some techweb nodes + - balance: Made flight suits, combat implants, and combat modules require more nodes + Fox McCloud: + - tweak: Slime blueprints can now make an area compatible with Xenobio consoles, + regardless of the name of the new area + MrDoomBringer: + - imageadd: All stations have been outfitted with brand new Smoke Machines! They + have nicer sprites now! + Shadowlight213: + - rscadd: You now can get a medal for wasting hours talking to the secret debug + tile. + - bugfix: Fixed runtime for the tile when poly's speech file doesn't exist. + Xhuis: + - rscadd: You can now make pet carriers from the autolathe, to carry around chef + meat and other small animals without having to drag them. The HoP, captain, + and CMO also start with carriers in their lockers for their pets. + YPOQ: + - bugfix: Fixed the camera failure, race swap, cursed items, and imposter wizard + random events + - tweak: The cursed items event no longer nullspaces items + jammer312: + - rscadd: Action buttons now remember positions where you locked. + - tweak: Now locking action buttons prevents them from being reset. +2017-12-10: + SpaceManiac: + - bugfix: External airlocks of the mining base and gulag are now cycle-linked. + - tweak: The pAI software interface is now accessible via an action button. + Swindly: + - rscadd: You can kill yourself with a few more items. + XDTM: + - tweak: Instead of activating randomly on speech, Godwoken Syndrome randomly grants + inspiration, causing the next message to be a Voice of God. + Xhuis: + - tweak: Flickering lights will now actually flicker and not go between emergency + lights and normal lighting. + - bugfix: Emergency lights no longer stay on forever in some cases. + kevinz000: + - rscadd: Nanotrasen would like to remind crewmembers and especially medical personnel + to stand clear of cadeavers before applying a defibrillator shock. (You get + shocked if you're pulling/grabbing someone being defibbed.) + - tweak: defib shock/charge sounds upped from 50% to 75%. +2017-12-11: + Anonmare: + - bugfix: Booze-o-mats have beer + Cruix: + - tweak: The white ship navigation computer now takes 10 seconds to designate a + landing spot, and users can no longer see the syndicate shuttle or its custom + landing location. If the white ship landing location would intersect the syndicate + shuttle or its landing location, it will fail after the 10 seconds have elapsed. + Frozenguy5: + - balance: Some hardsuits have had their melee, fire and rad armor ratings tweaked. + Improvedname: + - tweak: cats now drop their ears and tail when butchered. + Robustin: + - bugfix: Modes not in rotation have had their "false report" weights for the Command + Report standardized + SpaceManiac: + - bugfix: The MULEbots that the station starts with now show their ID numbers. + - bugfix: The dependency by Advanced Cybernetic Implants and Experimental Flight + Equipment on Integrated HUDs has been restored. + kevinz000: + - bugfix: flightsuits should no longer disappear when you take them off involuntarily + - bugfix: beam rifles actually fire striaght now + - bugfix: click catchers now actually work + - bugfix: you no longer see space in areas you normally can't see, instead of black. + in reality you can still see space but it's faint enough that you can't tell + so I'll say I fixed it. + uraniummeltdown: + - rscadd: Added MANY new types of airlock assembly that can be built with metal. + Use metal in hand to see the new airlock assembly recipes. + - rscadd: Added new airlock types to the RCD and airlock painter + - rscadd: Vault door assemblies can be built with 8 plasteel, high security assemblies + with 6 plasteel + - rscadd: Glass mineral airlocks are finally constructible. Use glass and mineral + sheets on an airlock assembly in any order to make them. + - tweak: Glass and mineral sheets are now able to be welded out of door assemblies + rather than having to deconstruct the whole thing + - rscdel: Airlock painter no longer works on airlock assemblies (still works on + airlocks) + - bugfix: Titanium airlocks no longer have any missing overlays +2017-12-12: + Mark9013100: + - rscadd: Medical Wardrobes now contain an additional standard and EMT labcoat. + Robustin: + - rscadd: The blood cult revive rune will now replace the souls of braindead or + inactive cultists/constructs when properly invoked. These "revivals" will not + count toward the revive limit. + - rscadd: The clock cult healing rune will now replace the souls of braindead or + inactive cultists/constructs when left atop the rune. These "revivals" will + not drain the rune's energy. + Swindly: + - bugfix: Swarmers can no longer deconstruct objects with living things in them. + kevinz000: + - bugfix: You can now print telecomms equipment again. +2017-12-13: + Naksu: + - bugfix: glass shards and bananium floors no longer make a sound when "walked" + over by a camera or a ghost + SpaceManiac: + - bugfix: Nonstandard power cells found in MULEbots, cyborgs, and elsewhere now + have the correct description. + deathride58: + - bugfix: Genetics will no longer have a random block completely disappear each + round +2017-12-15: + AverageJoe82: + - rscadd: drones now have night vision + - rscdel: drones no longer have lights + Cruix: + - bugfix: Shuttles now place hyperspace ripples where they are about to land again. + Cyberboss: + - config: Added "$include" directives to config files. These are recursive. Only + config.txt will be default loaded if they are specified inside it + - config: Added multi string list entry CROSS_SERVER. e.g. CROSS_SERVER Server+Name + byond://server.net:1337 + - config: CROSS_SERVER_ADDRESS removed + Epoc: + - bugfix: Adds Cybernetic Lungs to the Cyber Organs research node + JStheguy: + - rscadd: Added 10 new assembly designs to the integrated circuit printer, the difference + from current designs is purely aesthetics. + - imageadd: Added the icons for said new assembly designs to electronic_setups.dmi, + changed the current electronic mechanism and electronic machine sprites. + MrStonedOne: + - server: Added new admin flag, AUTOLOGIN, to control if admins start with admin + powers. this defaults to on, and can be removed with -AUTOLOGIN + - admin: Admins with +PERMISSION may now deadmin or readmin other admins via the + permission panel. + Naksu: + - code_imp: Preliminary work on tracking cliented living mobs across Z-levels to + facilitate mob AI changes later + - code_imp: Tidied up some loc assignments + - code_imp: fixes the remaining loc assignments + ShizCalev: + - soundadd: Revamped gun dry-firing sounds. + - tweak: Everyone around you will now hear when your gun goes click. You don't want + to hear click when you want to hear bang! + SpaceManiac: + - code_imp: Remote signaler and other non-telecomms radio code has been cleaned + up. + Xhuis: + - rscadd: Grinding runed metal and brass now produces iron/blood and iron/teslium, + respectively. + - balance: As part of some code-side improvements, the amount of reagents you get + from grinding some objects might be slightly different. + - bugfix: Some grinding recipes that didn't work, like dead mice and glowsticks, + now do. + - bugfix: All-In-One grinders now correctly grind up everything, instead of one + thing at a time. + nicbn: + - imageadd: Closet sprites changed. +2017-12-16: + Armhulen and lagnas2000 (+his team of amazing spriters): + - rscadd: Mi-go have entered your realm! + Robustin: + - balance: Marauder shields now take twice as long to regenerate and only recharge + one charge at a time. + - balance: Marauders now have 120hp down from 150hp. + - bugfix: The wizard event "race swap" should now stick to "safer" species. + - bugfix: Zombies are now properly stunned for a maximum of 2 seconds instead of + 2/10ths of a second. + - tweak: Zombie slowdown adjusted from -2 to -1.6. + SpaceManiac: + - bugfix: The shuttle will no longer be autocalled if the round has already ended. + Xhuis: + - tweak: Vitality matrices don't have visible messages when someone crosses them + anymore. +2017-12-17: + More Robust Than You: + - code_imp: Changed roundend sounds and lobby music to use one proc for choosing + sounds + - server: You can now easily host roundstart sounds without changing the code! + - config: RIP in shit round_start_sounds.txt + XDTM: + - rscadd: A few new traumas have been added. + - balance: Thresholds to get brain traumas have been lowered, as they currently + pretty much only trigger if you intentionally chug impedrezene. + - tweak: Melee head hits deal minor brain damage. Crits still do a significant amount. + - tweak: Nuke Op implants no longer trigger on deathgasp. (They still explode on + death) + - tweak: You'll now receive messages when crossing certain brain damage thresholds. + - tweak: Split Personalities are instructed not to suicide while in control. + - tweak: Godwoken Syndrome now randomly sends Voice of God commands, instead of + being controllable. + Xhuis: + - bugfix: Clockcult power alerts will no longer show outside of the clockcult gamemode + (they could be triggered by scarabs.) + ninjanomnom: + - bugfix: You can use the old non-hotkey mode text input behavior (keyboard input + automatically directed at the text input box) by changing your hotkey mode in + preferences + - rscadd: You can use Shift+E or Shift+B for belt/backpack respectively to quickly + put in your held item or take out the most recently added item. +2017-12-18: + AnturK: + - rscadd: Repeated messages will now be squashed in the chat. + Cyberboss: + - bugfix: Allied station communications are back, now with potentially multiple + stations + Naksu: + - tweak: Hostile mobs on z-levels without living players will now conserve their + efforts and simply not run AI routines at all. Also, idling mob routines should + be significantly cheaper on non-station Z-levels. + ShizCalev: + - soundadd: Added new sounds to guns when reloading. + - bugfix: Cartridges and casings ejected from guns will now make the proper sound! + Xhuis: + - bugfix: Microwave sound loops now correctly stop when it breaks or is otherwise + interrupted mid-cook. + coiax: + - rscadd: A lollipop dispenser in "dispense lollipops" mode can push the lollipop + straight into the targets hand, rather than getting it dirty on the floor first. + - tweak: Aliens (and humans with alien organs) will have a prompt if they try to + create resin structures or lay eggs atop vents or scrubbers. + nicbn: + - bugfix: Now the chem smoke machine uses stock parts for volume and range. + ninjanomnom: + - bugfix: Decals should now rotate the correct way around. + oranges: + - tweak: Dance machine will not play tracks to you if you have instruments turned + off +2017-12-19: + More Robust Than You: + - tweak: Jungle Fever cannot be cured anymore + - bugfix: The Monkey Leaders' virus are now un-detectable by health scanners and + to the PANDEMIC now. + Shadowlight213: + - bugfix: Fixed captain's PDA showing unusable Toggle Remote Door menu option + XDTM: + - rscadd: Abductors can now see if people already have glands! Never worry about + abducting the same guy twice again. + - rscadd: Added the Mind Interface Device to the abductor shop for 2 Credits. Only + scientists can use it. + - rscadd: 'The MID has two modes: Transmit and Control.' + - rscadd: Transmit will allow you to send a message anytime, anywhere to the mind + of a target of your choice, regardless of language barriers. The message will + be anonymous, but abductor-like. + - rscadd: Control allows you to give a temporary directive to a target with an implanted + gland, that they MUST follow. Duration and amount of uses varies by gland type. + When a gland is spent, it will no longer respond to Control signals. The target + forgets ever receiving the objective when the duration ends. + coiax: + - balance: The codespeak manual now has unlimited uses and costs 3 TC. + - bugfix: Nuke ops can now purchase the codespeak manual, as was intended. + - rscadd: Golems can now wear labcoats. + kevinz000: + - rscadd: You can now joust with spears if you are riding on another mob, whether + it's a hapless cyborg or otherwise! Additional damage and stunchance will be + added per tile moved! + ninjanomnom: + - bugfix: Non movement keys pressed while moving no longer stop movement. +2017-12-20: + AnturK: + - rscadd: You can enforce no smoking zones with a disarm aimed at the smokers mouth. + coiax: + - rscadd: A changeling will learn all languages from anyone they absorb. +2017-12-21: + Fox McCloud: + - bugfix: Fixes arm implants being immune to EMPs + SpaceManiac: + - refactor: Telecomms and radio code has been cleaned up. + - tweak: The PDA message server is now a real piece of telecomms machinery. + - tweak: PDA logs now include the job as well as name of the participants. + - bugfix: The Syndicate frequency no longer hears its own messages twice. + - bugfix: Talking directly into a radio which is also hot-miked no longer double-talks. + - bugfix: Passing a space transition no longer interrupts pulls. + Xhuis: + - bugfix: You can no longer elect two Eminences simultaneously. + - bugfix: The Eminence no longer drifts in space. + - tweak: The Eminence's mass recall now works on unconscious servants. + - tweak: The Eminence's messages now have follow links for observers. + - balance: Floors blessed with holy water prevent servants from warping in and the + Eminence from crossing them. + - balance: The Eminence can never enter the Chapel. + coiax: + - rscadd: At the end of the round, all players can see who the antagonists are. + improvedname: + - bugfix: Corrects 357. speedloader in the autolathe + kevinz000: + - rscdel: Integrated circuit smoke circuits now require 10 units of reagents to + fire. + uraniummeltdown: + - rscadd: You can adjust line height in chat settings + - tweak: Default chat line height is slightly shorter, from 1.4 to 1.2 +2017-12-22: + Awesine: + - rscadd: added some things which happen to be mining scanner things to that gulag + thing + Kor: + - rscadd: During Christmas you will be able to click on the tree in the Chapel to + receive one present per round. That present can contain any item in the game. + Naksu: + - bugfix: frying oil actually works + WJohnston: + - tweak: Syndicate nuke op infiltrator shuttle is no longer lopsided. + kevinz000: + - rscadd: 'Clown modules have been added for cyborgs! Modules: Bikehorn, Airhorn, + instrumental bikehorn, clown stamp, multicolor paint, rainbow crayon, soap, + razor, purple lipstick, nonstunning selfcharging creampie cannon, nonslipping + selfcharging water sprayer, lollipop fabricator, metallic picket sign, mini + extinguisher, laughter reagent hypospray, and the ability to hug. experimental: + When emagged they get a fire spray, "super" laughter injector, and shocking + or crushing hugs. Also, the module is adminspawn only at the moment.' + - bugfix: Projectiles that pierce objects will no longer be thrown off course when + doing so! + - code_imp: Projectiles now use /datum/point/vectors for trajectory calculations. + - bugfix: Beam rifle reflections will no longer glitch out. +2017-12-23: + Dax Dupont: + - bugfix: Borgs will no longer have their metal/glass/etc stacks commit sudoku when + it runs out of metal. They will also show the correct amount instead of a constant + of "1" on menu interaction. + Kor: + - rscadd: During Christmas you will be able to click on the tree in the Chapel to + receive one present per round. That present can contain any item in the game. + Robustin: + - tweak: The EMP door shocking effect has a new formula. Heavy EMP's will no longer + shock doors while light EMP's have a 10% chance (down from 13.33%). + coiax: + - balance: The kitchen gibber must be anchored in order to use. + - balance: The gibber requires bodies to have no external items or equipment. +2017-12-24: + Frozenguy5: + - bugfix: Soapstones now give the correct time they were placed down. + More Robust Than You: + - tweak: Vending machines now use TGUI + SpaceManiac: + - bugfix: '"Download N research nodes" objective is now checked correctly again.' +2017-12-25: + SpaceManiac: + - bugfix: The Syndicate radio channel works on the station properly again. + coiax: + - rscadd: Ghosts can now use the *spin and *flip emotes. + uraniummeltdown: + - rscadd: Examine a door assembly to check what custom name is set. +2017-12-26: + Cyberboss: + - tweak: Objects that can have materials inserted into them only will do so on help + intent + PsyKzz: + - rscadd: Jaws of life can now cut handcuffs + SpaceManiac: + - admin: Play Internet Sound now has an option to show the song title to players. + XDTM: + - balance: Rebalanced healing symptoms. + - balance: Cellular Molding was replaced by Nocturnal Regeneration, which only works + in darkness. + - balance: All healing symptoms now heal both brute and burn damage, although the + basic ones will still be more effective on one damage type. + - balance: Plasma Fixation and Radioactive Metabolism heal toxin damage, offsetting + the damage done by their healing sources. + - balance: Changed healing symptoms' stats, generally making them less punishing. + Xhuis: + - balance: Medical supplies on all normal maps (Box, Meta, Delta, Omega, and Pubby) + are now behind ID-locked windoors. These windoors will become all-access during + red alert! + YPOQ: + - bugfix: Emagged cleanbots can acid people again + - bugfix: Headgear worn by monkeys can be affected by acid + ninjanomnom: + - bugfix: The auxiliary mining base can no longer be placed on top of lava, indestructible + turfs, or inside particularly large ruins. + - bugfix: The backup shuttle has it's own area now and you should no longer occasionally + be teleported there by the arena shuttle. + - bugfix: Cycling airlocks on shuttles should work correctly when rotated now. + - bugfix: Things like thermite which burned through walls straight to space now + stop on plating. You'll have to thermite it again to get to space. +2017-12-27: + More Robust Than You: + - code_imp: Changed roundend sounds and lobby music to use one proc for choosing + sounds + - server: You can now easily host roundstart sounds without changing the code! + - config: RIP in shit round_start_sounds.txt + Nero1024: + - soundadd: blast doors and shutters will now play a sound when they open and close. + Robustin: + - bugfix: Hallucinations will no longer show open doors "bolting". + SpaceManiac: + - code_imp: The R&D console has been made more responsive by tweaking how design + icons are loaded. + Xhuis: + - rscadd: Maintenance drones and cogscarabs can now spawn with holiday-related hats + on some holidays! + coiax: + - rscadd: Deltastation now has christmas trees during seasonally appropriate times. + deathride58: + - bugfix: Praise the lord! The shift+scroll hotkey to zoom in/out as a ghost works + properly again! + kevinz000: + - rscadd: you can now pick up corgi's and pAIs, how disgustingly cute + - code_imp: Forensics is now a datum component. + - balance: NPC humans will now start leaving fingerprints on things they touch! +2017-12-28: + Cyberboss: + - bugfix: Ghost lights will follow the ghost while orbiting + Robustin: + - bugfix: Splashing a book with ethanol should no longer produce errant messages. + - balance: Dead cultists can now be moved across the "line" on Reebe. +2017-12-29: + CosmicScientist: + - rscadd: timestop now inverts the colours of those frozen in time! + Dax Dupont: + - bugfix: APCs and other wall mounted objects are no longer blocked by the secure + medbay storage parts. + - bugfix: Removed a duplicate radiation collector on Deltastation. + More Robust Than You: + - bugfix: The Radiance can now enter the chapel + - bugfix: Monkey chat should no longer have .k prefixed + - bugfix: Monkey leaders should actually get jungle fever now + Robustin: + - bugfix: The action button for spells should now accurately reflect when the spell + is on cooldown + - bugfix: You can now reliably use the button for "touch" spells to "recall" the + spell + SpaceManiac: + - code_imp: Explicit z-level checks have been changed to use defines. + XDTM: + - rscadd: 'Added a new reagent: Pax.' + - rscadd: Pax is made with Mindbreaker, Synaptizine and Water, and those affected + by it are forced to be nonviolent against living beings. At least, not directly. + coiax: + - rscadd: Adds an internal radio implant, allowing the use of the radio if you expect + to have your headset removed. Or if you don't have any ears or hands. It can + be purchased for 4 TC from any Syndicate uplink. + - rscadd: Nuke ops now buy special "syndicate intelligence potions" that automatically + insert an internal radio implant when used successfully. Cayenne can now participate + in your high level discussions. +2017-12-30: + Cyberboss: + - tweak: Burial jumpsuits no longer have suit sensors + - tweak: The chemistry job has been removed from Omegastation. Medical doctors still + have full chemistry access + MrDoomBringer: + - imageadd: NanoTrasen has sent the station new spaceheaters! They look nicer now! + Xhuis: + - balance: Vitality matrices now apply Ichorial Stain when reviving a dead servant, + which prevents that servant from being revived again by vitality matrices for + a full minute. + - balance: Vitality matrices can't be placed adjacent to one another. + - balance: Brass skewers now damage and stun cyborgs. + - balance: Vitality matrices no longer drain people impaled on brass skewers. + - balance: Pressure sensors have 5 health again (down from 25.) + ninjanomnom: + - bugfix: Some changes to turfs like shuttles would result in un-initialized space + tiles being created. This has been fixed. +2017-12-31: + Cyberboss: + - rscadd: Explosions now cause camera shake based on intensity and distance + F-OS: + - bugfix: Last resort now requires a confirmation + Naksu: + - code_imp: loot drop spawners now assign their pixel offsets to the items they + spawn, also have a "fanout" setting to distribute items in a neat fashion like + in omega/delta's core and some tech storages. + - tweak: replaced several law boards in uploads with spawners, the net result being + one more board in uploads that may be a duplicate asimov (but hopefully isn't) + SpaceManiac: + - bugfix: Viewing photos sent by PDA message works again. + WJohnston: + - rscadd: Redesigned the entire syndicate lavaland base to be more stylish, have + functioning power and atmos as well as a turbine to play with. + XDTM: + - bugfix: Fixed a hallucination that would say [target.first_name()] instead of + the actual name. diff --git a/html/changelogs/archive/2018-01.yml b/html/changelogs/archive/2018-01.yml new file mode 100644 index 0000000000..fbe2522f92 --- /dev/null +++ b/html/changelogs/archive/2018-01.yml @@ -0,0 +1,877 @@ +2018-01-01: + Dax Dupont: + - bugfix: PDA messages have been fixed. +2018-01-02: + Dax Dupont: + - bugfix: The bank vault is no longer metagaming. It will now display the IC station + name. + DaxDupont: + - bugfix: Solar control consoles are no longer pointing to the wrong direction, + you can now turn tracking off again and manual positioning of solar panels have + been fixed. + Frozenguy5: + - rscadd: Adds a goon and cult emoji. Improves gear and tophat. (Credits to GoonStation + for creating the goon bee sprite.) + Okand37: + - rscadd: Overhauled aesthetic of some portions of Omegastation + - rscadd: Overhauled Omegastation's departure lounge, fitting it with the rest of + the station's theme + - rscadd: Replaced the personal closets with wardrobes in Omegastation's Lockerroom + - rscadd: Made Omegastation's engine room floortiles reinforced + - rscadd: Replaced the cola and snack machines with their random counterparts on + Omegastation + - bugfix: Fixed Omegastation's self destruct console being a doomsday device + - bugfix: Fixed Omegastation's chemistry shutters not all being synced and rearranged + the chemmaster. + - rscadd: Added a small technology storage in maintenance near departures on Omegastation + - rscadd: Added additional loot and emergency supplies to maintenance on Omegastation + - rscadd: Added the X-01 Multiphase to the Captain's Locker, Blueprints to Vault, + Reactive Teleportation Armor to Server Room and theHypospray to Medical Storage + on Omegastation + XDTM: + - bugfix: Fixed Runic Golem's Abyssal Gaze blinding permanently. + - balance: Ocular Restoration has been removed, its effect transfered on Sensory + Restoration. + - balance: Sensory Restoration now heals both eye and ear damage. + - balance: Mind Restoration now no longer heals ear damage, but now heals brain + damage by default. + - balance: Mind Restoration's thresholds can now let the symptoms cure mild brain + traumas at 6 resistance and severe ones at 9. + ninjanomnom: + - bugfix: Turfs are construct-able again +2018-01-03: + Cyberboss: + - bugfix: Fixed lathe power consumption being too high + - bugfix: You no longer cut yourself with shards when clicking a portal + Dax Dupont: + - bugfix: After 2 years and 2 separate issues the paper mache wizard robe has finally + been fixed. + Naksu: + - rscadd: A damaged core AI module may now spawn in AI uploads. It contains a random + amount of ionic laws with normal law priorities. + - bugfix: splash-fried food is now actually edible + SpaceManiac: + - bugfix: Mimes now laugh silently. + deathride58: + - tweak: Explosions will no longer give everyone and their mothers motion sickness + from a mile away. +2018-01-04: + Cyberboss: + - bugfix: The bloodcult sacrifice objective description won't change when the target + is sacrificed + Dax Dupont: + - rscadd: PDA Interface color is now a preference. + - bugfix: Fixed PDA font style not applying at round start. + - rscadd: 'The following messages have been added to dead chat: Security level change, + (re)calling, Emergency Access, CentComm/Syndicate console messages, outgoing + server messages and announcements,' + MrStonedOne: + - bugfix: The changelog hadn't been updating. This has been fixed. + ShiggyDiggyDo: + - tweak: Syndicate experts were able to create more sophisticated copies of the + nuclear authentication disk. While still unable to detonate the nuclear fission + explosive with them, they're practically identical to the real disk if not examined + closely. +2018-01-05: + Cruix: + - bugfix: Chameleon PDAs now have their chameleon action. + Okand37: + - rscadd: Added a fully functioning A.I. satellite to Omegastation! + - rscadd: Added the CE's magboots to the gravity room on Omegastation! + - rscadd: Added a medical wrench to cryo for Omegastation! + Shadowlight213: + - bugfix: Devils will no longer be permanently stuck if interrupted while trying + to jaunt. + - bugfix: Devils will now properly clear the fake fire if failing to jaunt. + SpaceManiac: + - bugfix: The startup load time of away missions has been drastically reduced. + - bugfix: The admin notification for the pulse rifle prize now shows the correct + coordinates. + deathride58: + - bugfix: Explosions now function properly again! +2018-01-10: + Robustin: + - bugfix: Blood cultists will now properly display a "reverted to their old faith" + message when deconverted. +2018-01-11: + Cyberboss: + - spellcheck: Fixed mechanical arms grammar when failing to activate + - bugfix: You will now no longer hit closets when attempting to anchor them + ExcessiveUseOfCobblestone: + - code_imp: Adds Stat Tracking to Techwebs by node and order. + Selea: + - rscadd: pulling claw.Integrated circuit, which allow assemblies to pull things. + ShizCalev: + - bugfix: 'Meta: The UI for the captain''s cigarette vendor now works again.' + - tweak: 'Meta: Removed the omnizine filled syndicate cigarettes from the captain''s + cigarette vendor.' + - tweak: Medbots are no longer able to inject you if you do not have any exposed + flesh. + Someguynamedpie: + - bugfix: Use world.timeofday instead of world.realtime + SpaceManiac: + - spellcheck: Replaced "CentComm" with "CentCom" in communications console deadchat + announcement. + - refactor: Information about the properties of z-levels is now less hardcoded than + before. + Tortellini Tony: + - rscadd: 'New hotkey for admin say command: F3.' + yorii: + - spellcheck: Renamed the ChemMaster eject button to highlight the fact that the + buffer does not get cleared +2018-01-12: + Cobby: + - tweak: As a human, you will now point with your legs when you have no arms, falling + over each time. + - tweak: As a human, you will bump your head on the ground trying to motion towards + something when you have no arms or legs. + Cyberboss: + - spellcheck: Fixed message grammar when lifting someone off a brass skewer + - bugfix: Fixed the original poker tables not being deleted after Narsie converted + them to a wooden table + Dax Dupont: + - rscadd: Thanks to the extensive disco and plasma research gathered by the Disco + Inferno shuttles, an indestructible mark V disco machine is now available. The + latest edition of the Disco Inferno shuttle now carries it. + JJRcop: + - code_imp: Removes some links intended for admins from game logs. + More Robust Than You: + - balance: Sigils of submission now uncuff upon successful conversion + PKPenguin321: + - tweak: Cyborgs that take enough damage to have a module disabled will now automatically + announce that they've had a module disabled to anybody nearby. Now if you want + to stop a cyborg from interfering with your business but don't want to kill + it, you can simply bash until you see the CRITICAL ERROR message. + - soundadd: Borgs will play an alarm sound in addition to displaying this message + as they have their modules disabled. + ShizCalev: + - bugfix: You can now attach collars to pets again! + - bugfix: Corrected pet collars icon mismatch. + - bugfix: Pets will now drop their collars when gibbed. + - tweak: You will no longer be able to rename unique pets, such as Ian or Runtime. + You can still rename pets without a special name. + - bugfix: Secbot assemblies will no longer lose their weld hole when dragged North + - imageadd: Secbot assemblies now have new North facing sprites! + - imageadd: Cleaned up a rogue pixel on beepsky's sprite. + - bugfix: Defibrillators now have inhands again! + - bugfix: Defibrillators will no longer stay in your hands after you die. + - bugfix: Losing an arm while wielding a two handed weapon will now cause you to + drop the weapon. + - bugfix: Losing an arm while carrying an item that requires two hands to hold will + now cause you to drop the item. + - spellcheck: Improved user feedback from chem dispenser macros. + - bugfix: Fixed Tests Areas debug verb. + - bugfix: Only the chaplain can now purify a bloody bastard sword. + - bugfix: Fully healing a mob as an admin now cures disabilities properly. + - bugfix: Non-cultists hulks can no longer withstand the immense powers of Ratvar's + influence while holding a bloody bastard sword. + - bugfix: The average body temperature has been corrected to 98.6F. + - tweak: Safe dials will now present itself in 1 number increments, instead of 5. + - bugfix: Relabeled canisters will no longer switch to an incorrect sprite when + broken. + SpaceManiac: + - bugfix: Relabelled canisters once again have the correct description. + - bugfix: The interface of airlock consoles has been restored to normalcy. + YPOQ: + - bugfix: Securitrons/ED-209s/Honkbots will only activate their emag functions after + their internals are emagged +2018-01-14: + Dax Dupont: + - bugfix: The NT Violet Lepton shuttle has been retrofitted with lava proof windows + for the lava engine. They will no longer catch fire and violently decompress + the shuttle. + Leshana: + - bugfix: Fix attempt to use `in` on a non-list. Pretty sure bitfields do not work + that way. + - admin: SS_NO_FIRE subsystems will no longer display pointless cost statistics + in MC panel + QualityVan: + - balance: Due to budget cuts, the vault safe is now slightly less resistant to + explosions. + ShizCalev: + - bugfix: Constructed security/honk/ect bots will now drop the correct parts when + destroyed. + - bugfix: "Some areas will no longer present themselves at \"\xC3\xBFUnexplored\ + \ Area\"" + SpaceManiac: + - bugfix: The R&D console design icon for slot machines is no longer mangled. + - bugfix: The Ark's teleportation checks now take mechs and sleepers into account + correctly. + - spellcheck: Activating internals via the right-side button produces better messages + on success. + - bugfix: The RPD will no longer fail to paint and layer pipes in some situations. + - bugfix: Unwrenching canisters from connector ports on non-default layers now resets + their pixel offset. + Thunder12345: + - bugfix: The NES Port emergency shuttle will no longer drain the CentComm emergency + dock of air + XDTM: + - tweak: Dreams are now more immersive and interesting. + deathride58: + - admin: You can now choose an outfit to be equipped while transforming a mob to + human via rudimentary transform. +2018-01-15: + Cruix: + - rscadd: Roundend traitor purchase logs now have tooltips showing the name, cost, + and description of the items. + F-OS: + - rscadd: NT has disabled their automatic APC lock + - tweak: The space heater now has a warning on it about use in the SM. + Half of coderbus ended up working on this somehow: + - rscadd: Goats will now dismember plant people when attacking them. + Iamgoofball: + - bugfix: The Express Console emag effect is now worth using. + JohnGinnane: + - bugfix: Fixed not being able to alt click on a stack + More Robust Than You: + - bugfix: Monkey Leaders should now properly get Jungle Fever + - bugfix: Monkeymode roundend report should now properly show Major/Minor victory + - bugfix: Monkeys should now get the jungle fever objective in monkeymode + - imageadd: Wirecutters can come in even more colors now! + ShizCalev: + - bugfix: RPDs and pipe painters now have more colorssssssssssssssssss + SpaceManiac: + - bugfix: Title screens without multiple dots in their filename will now be chosen + again. + - bugfix: MMIs in mechs or held by humans wearing fireproof suits are no longer + burnt by ash storms. + WJohnston: + - rscadd: Encrypted radio waves have been detected airing around station space. + Watch for possible enemy communications. + - rscadd: The space syndicate listening post has been remade from scratch, and now + has an actual ghost role to help spy on the station and relay info to traitors! + Xhuis: + - tweak: Added some new tips to the list for fighting the clockcult! + - rscadd: Added a new bar sign, The Lightbulb. + YPOQ: + - bugfix: Players are immune to their own slime time stops again + coiax: + - rscadd: A xenomorph maid (or barmaid) cleans the floor as they walk on it. Lie + down, and they'll clean your face. + ninjanomnom: + - admin: There are 3 new helpers in the secrets menu for messing with movement controls + - bugfix: Mining base walls when broken turn into plating which in turn breaks down + to the basalt surface. + theo2003: + - tweak: The autolathes on MetaStation, and DeltaStation next to R&D are now accessible + from R&D via windoor. +2018-01-16: + AnturK: + - bugfix: Photos now properly capture everything again. + DaedalusGame: + - bugfix: fixed duplicate reagent definitions in chem macros + SpaceManiac: + - bugfix: Heat exchange manifold pipes facing east/west now work again. + Thunder12345: + - bugfix: The asteroid with engines strapped to it will no longer vent both the + CentCom docks and its own entrance. + XDTM: + - rscadd: Reworked the species side of xenobiology. + - rscadd: Instead of an universal unstable mutation toxin, green slimes can now + produce slime mutation toxin (plasma), human mutation toxin (blood), and lizard + mutation toxin (radium). + - balance: Slime mutation toxin requires several units and some time before acting, + unless you're already a slimeperson (in which case it will randomize your subspecies) + - rscadd: Two new jellypeople subspecies have been added to make up for the lost + species. + - rscadd: Stargazers have telepathic abilities; they can Send Thoughts, privately + and anonimously, to any target they can see, and they can Link Minds with any + aggressively grabbed mob to form a hivemind with them. Hiveminds have no limit + but expire when the Stargazer dies or changes species. + - rscadd: Luminescents glow faintly and can absorb slime cores to gain special abilities. + Each core has a minor and a major ability, generally based on what they normally + do. Using these abilities does not use up the cores, but it has a cooldown depending + on the ability's power. + - balance: Slimepeople can now switch bodies on death or when unconscious, as long + as they have another one. +2018-01-17: + DaedalusGame: + - balance: you can't get 12 syndi bomb cores from stripping the syndi lava base + for parts anymore + - bugfix: fixed the syndi lava base blowing up from stray colossus shots, goliaths + breaking in or miners throwing gibtonite at it. + F-OS: + - tweak: Air alarms start unlocked + - bugfix: Air alarms no longer think they are fire alarms + - bugfix: Drone dispensers no longer hide drones + - bugfix: Ash storms aren't at ear-rapey volumes inside shielded areas. + ShizCalev: + - bugfix: Gas tanks are now made of metal! Honk + SpaceManiac: + - bugfix: Clicking lattices and girders with the RPD now succeeds instead of appearing + to place a pipe but failing. + - bugfix: The debug verbs "Display Air Status" and "Air Status in Location" now + format their reports the same and actually work more often. + - bugfix: The Camera Failure event no longer crashes the server if the station has + no cameras. + - admin: SDQL "select" outputs now have buttons to jump to the coordinates of the + found objects. + Xhuis: + - balance: You now have to climb through rifts to Reebe by walking into them, instead + of instantly warping away when you bump into one. + - balance: The separation line between the crew spawn and servant spawn in Reebe + now blocks airflow. + - rscadd: Added a new bar sign, The Lightbulb. + - bugfix: The Eminence's mass recall ability should now work properly + coiax: + - rscadd: If enough people vote to start CTF (by clicking on a CTF controller as + a ghost), then CTF will automatically begin. + deathride58: + - rscadd: By using a multitool on a radiation collector, you can use it to generate + research points! This requires a tank filled with a mix of tritium and oxygen. + - tweak: The display of rad collectors' power production rates has been moved from + a multitool interaction to examine text. + - tweak: Radiation collectors now emit a ding when they run out of fuel. + kevinz000: + - bugfix: Flashes can no longer work from inside containers to flash people outside. + - balance: Research export cargo points have been halved + nicbn: + - tweak: The Pirate Code changed its first rule to "BE AN SKELETON YARR". The old + "there are no rules" is now the second rule. +2018-01-18: + Buggy123: + - tweak: full-tile plasmaglass windows have had their integrity increased to the + correct value. +2018-01-19: + AverageJoe82: + - tweak: Reduce clock work mob death sound file's volume to 80% + Buggy123: + - rscadd: Observers can now view the atmospheric contents of the tile they're floating + above. + Cyberboss: + - refactor: Added test run mode which checks for runtimes in startup/shutdown and + runs tests (if they were enabled during compilation). Invoke it with the "test-run" + world parameter + Dax Dupont: + - bugfix: Autolathe now consumes reasonable amounts of power when inserting materials + - bugfix: Fixed conveyor belt power usage. + Frozenguy5: + - code_imp: Travis now builds on BYOND 512.1403 + Joan and More Robust Than You: + - rscadd: Adds moths! They're a new species that is able to fly in pressurized areas + provided gravity is off... and that they still have wings. + More Robust Than You: + - rscadd: Added some useful sec officer tips + OrdoM: + - rscadd: Adds morphine recipe to chemistry. + - rscdel: Removed ability for bartender to steal all morphine on the map + Robustin: + - bugfix: Fixed frost oil (cryosting) sending insulated crewmembers below absolute + zero temperatures. + - bugfix: Fixed damaging cold temps being a death sentence to simple mobs (they + wouldn't heat back up to safe temps at room temperature). + - refactor: Refactored human temperature code, insulating clothing now helps you + stay warm but going unprotected will help you cool off. However, you will now + benefit from colder temps when you're overheating even in full EVA/hardsuit + gear and you will warm up faster at room temperature in insulated gear as well + (i.e. putting on a winter coat will no longer suppress your temperature if your + already cold). + - bugfix: All crew can now purify bloody bastard swords with a bible (available + from cargo religion crates, library, or chapel) once again. + Shadowlight213: + - rscadd: Players can now have a verb in the ooc tab to see their own tracked playtime + - bugfix: fixed admin bypass not using the right proc + - bugfix: Lavaland ghost roles should now show up in the playtime report + ShizCalev: + - bugfix: Floors that look damaged / burned are now ACTUALLY damaged / burned, and + can be repaired! + SpaceManiac: + - bugfix: PDA messages sent by the message monitor console are now included in the + talk logs. + XDTM: + - tweak: Mass Hallucination now will give everyone the same hallucination. + - bugfix: Slimepeople can now properly swap between bodies. + - bugfix: Slimes no longer attack people with their same faction. + Xhuis: + - tweak: Servants can now cancel warps by clicking the button again, instead of + having to manually interrupt it by doing something like picking up an item from + their pocket. + coiax: + - rscdel: The Free Golem Ship no longer has a teleport beacon. + - rscdel: Jaunters no longer have a special effect when teleporting golems. + deathride58: + - rscadd: Mappers can now color individual tiles of floors via turf decals. + - bugfix: Cancelling the "Change equipment" command now works as expected again. + uraniummeltdown: + - bugfix: Jaunting wraiths should now always be facing the correct direction + yorii: + - bugfix: fixed the syringe getting a transfer amount of 0 if the contents of it + are 0, intended feature was probably to check the target and not the syringe + itself for clamp. +2018-01-20: + MrDoomBringer: + - rscadd: All Cargo Techs now come equipped with a standard supply Export Scanner! + Get to selling! + XDTM: + - bugfix: Fixed a bug where slimes wouldn't eat neutral mobs. + uraniummeltdown: + - tweak: Emagged airlocks can now be deconstructed simply by crowbarring when the + panel is open +2018-01-21: + Dax Dupont: + - bugfix: Moth wings will now respect your preferences. + WJohnston: + - rscadd: We've lost contact with one of our trade caravans in your sector, be on + the lookout for possible enemy activity. + - rscadd: Redesigned the syndicate ambush space ruin. It now boasts multiple flyable + shuttles and looks a lot prettier. + - imageadd: Wirecutter greyscaling is now less ugly +2018-01-22: + DaedalusGame: + - balance: foam and smoke now get 4x the reagents as they should according to the + comments + - bugfix: fixes pyrosium and cryostylane not heating or cooling humans at all + - bugfix: fixes cryostylane cooling beakers to negative kelvin, it's now limited + to what the description says + - bugfix: fixes cryostylane cooling people to negative body temperature + - code_imp: removed redundant check in trans_to + - code_imp: fixes a runtime when total_volume is 0 in copy_to + - tweak: Gas reagents (o2, plasma, ...) now dump out gas based on container temperature + instead of room temperature + Dax Dupont: + - rscadd: Fans of clown photography have successfully lobbied Nanotrasen to include + camera and camera accessories designs in the autolathe. + - tweak: Brings material values for the camera in line with other devices. + - tweak: The tapes printed by autolathes now come in random colors. + Dax Dupont & Coiax: + - rscadd: Praise the lord for he has granted thy chaplains, wizards, revenants and + eminences with holy vision. They can now see blessed tiles. + MMMiracles: + - rscadd: Syndicate and pirate mobs now give off light when appropriate + More Robust Than You: + - bugfix: Fixed monkey teams + - tweak: The Lepidopterian language now has less spaces in it + Robustin: + - bugfix: Fixed monkeys slowly freezing to death + ShizCalev: + - bugfix: Clockcultists and revolutionaries can no longer be mindswapped. + SpaceManiac: + - refactor: Weather and certain events have been updated to use Z traits. + - bugfix: The Staff of Storms now correctly starts and ends storms if used from + inside lockers. + - bugfix: Weather telegraph messages are now shown to those inside lockers and mechs. + - bugfix: Radio jammers no longer affect other z-levels. + Tlaltecuhtli: + - tweak: min player req for rev is 30 now + Xhuis: + - bugfix: Emergency lights now function correctly. + deathride58: + - code_imp: Light fixtures no longer use hardcoded values for their power and colour. + ninjanomnom: + - bugfix: Functions that aren't intending on actually moving the shuttle yet don't + send error messages to admins anymore when seeing if a shuttle *can* move. + scrubs2009: + - tweak: Candles last longer + uraniummeltdown: + - bugfix: Bananium shows up on mining scanners again +2018-01-23: + Cruix: + - bugfix: engine goggles set to t-ray mode will no longer show pipes with the wrong + rotation. + - bugfix: cables now show up on t-ray scans. + Dax Dupont: + - bugfix: Fixed missing tile under autolathes + MrDoomBringer: + - rscadd: NanoTrasen's Creative Psychology Initiative has brought new training to + all crewmembers to foster rapid, innovative problem-solving! You can now kill + yourself in so many more ways! + - rscadd: The RnD department can now develop firmware upgrades to the Express Supply + Console, unlocking advanced cargo drop pods! + Naksu: + - code_imp: removed a bunch of unnecessary vars, combining them into a bitfield + SpaceManiac: + - bugfix: Fixed occasional runtimes when ion storms or overflow would replace an + existing law. + WJohnston: + - bugfix: Space syndie listening post now has a real microwave, and a book management + console. Lava listening post comms room intercom now no longer starts with broadcast + on. + - rscadd: the syndicate drop ship and fighter pods from the caravan ambush can now + be flown to the syndicate listening post. The fighter pods also now have xray + cameras because regular ones were super useless. + XDTM: + - rscadd: Added Regenerative Jelly, made with tricordrazine and slime jelly. It + regenerates a bit faster, and won't harm jellypeople. + - rscadd: Added Energized Jelly, made with teslium and jelly. It works as an anti-stun + chemical for slimepeople and speeds up luminescents' power cooldown, but non-jellypeople + will just get shocked. + - rscadd: 'Added Pyroxadone, made with cryoxadone and slime jelly. It''s basically + inverse cryoxadone: it heals faster the hotter your body temperature is.' + - tweak: Cryoxadone no longer deals toxin damage to jellypeople. + - tweak: Purple Slime Extracts no longer have their sugar->slime jelly reaction + (obsolete with extract grinding), and instead have a blood->regen jelly reaction. + - tweak: Purple Extract's major activation by Luminescents now give regenerative + jelly instead of tricordrazine. + coiax: + - rscadd: Fake nuclear disks can only be identified by the captain, observers, nuclear + operatives, seeing where the pinpointer points, or attempting to put it into + a nuclear device. + - rscadd: Fake nuclear disks "respawn" on the station just like the real one. + kevinz000: + - rscdel: pulling claw can now only passively grab + - bugfix: Infrared beams now update instantly. + ninjanomnom: + - bugfix: Changeling clothing can get bloodied again. + the hatchet man (i eat garbage code): + - bugfix: 'you shitlords picked the wrong virtual anime tits to fuck so im takin + away your space bases experimental: lets be fair all you guys did in those was + jack off to hentai, and not real man''s gachimuchi' +2018-01-24: + Dax Dupont: + - bugfix: Fixed missing wheat fridge on omega and removes a duplicate pipe. + - rscadd: Beakers and beaker-like objects now get put in your hand on ejection from + chemistry devices. + Shadowlight213: + - bugfix: Fixed eye damage not being applied if it was exactly 3. + YPOQ: + - bugfix: Emergency lights will give off light again + ninjanomnom: + - bugfix: Pointing at squeaky things doesn't make them squeak anymore. +2018-01-25: + Dax Dupont: + - imageadd: Autolathe now repeats it's animation while printing. + - tweak: You now need to examine engravings to pop open the menu. + - bugfix: People can no longer extract 300 supermatter shard slivers without it + exploding. + - bugfix: Fixed thongs not dusting people on use. + Jittai: + - tweak: All color inputs now use the current color, of the thing being colored, + as default choice. + More Robust Than You: + - rscadd: You can now defib monkeys and aliums + - tweak: Monkeys can also use defibs now, too! + Naksu: + - code_imp: Slightly refactored object armor code + Ordo: + - rscadd: Adds Ketrazine, a powerful but dangerous combat stim which the crew can + synthesize + Robustin: + - balance: Clockwork marauders now take more time (+3s) and power (7x) to create. + - balance: The "recent marauder" time limit is now 60 seconds, up from 20. The limit + now has a significantly smaller effect on summon time but will act as a further + cap on marauder summoning until it has passed. + - tweak: The marauder cap will now only account for living cultists. + - rscadd: 'A new cocktail: The Nar''Sour. Made from blood, demonsblood, and lemon + juice, this cocktail is known to induce a slightly different type of slurring + when imbibed.' + SPACE CONDUCTOR: + - tweak: Shuttles will throw you around if ya don't buckle in + Shadowlight213: + - balance: Moths are now more susceptible to bright lights + Togopal, Armhulenn, Naksu, Jordie & oranges: + - rscadd: Snakes! They hunt vermin on the station! Curators have a natural phobia + to them. + - rscadd: They can be purchased in cargo. + XDTM: + - rscadd: Slimepeople and Jellypeople can now speak the slime language. + - tweak: Slimes now only speak slime language, although they still understand common. + - balance: Slimepeople are no longer virus immune. + - bugfix: The above change fixes a bug that made black slime cure itself. + Xhuis: + - balance: Fleshmend can no longer be stacked several times at once. + - balance: Fleshmend no longer heals changelings who are on fire, and heals burn + damage half as quickly as brute and oxygen damage. + - code_imp: Fleshmend has been refactored into a status effect. + coiax: + - rscadd: Nuclear operatives that wish to fail in style can purchase Centcom Official + and Clown costumes. They can also buy a defective chameleon kit. + - rscadd: The majority of shuttles are now loaded at the start of the round from + template, rather than being premapped. As a side effect, Delta's mining shuttle + now docks facing down at Lavaland. + imsxz: + - rscadd: Traitor clowns are now able to purchase clown bombs from their uplinks. + Honk! + - rscadd: Clown bombs can now be placed via a small beacon, the same way normal + syndicate bombs can be. + - tweak: clown bomb payload now summons 50 clowns instead of 100 + nicbn: + - bugfix: Now if you lose arms you won't be able to see through your uniform. + ninjanomnom: + - bugfix: Loaded templates now get placed on top of existing terrain so as to preserve + baseturfs. This fixes survival pods walls breaking to lava as well as allows + some future fixes. +2018-01-26: + Cruix: + - bugfix: Fixed being able to rotate things in only one direction. + DaedalusGame: + - rscadd: Firefighting Foam reagent, better alternative to water and corn oil for + firefighting purposes + Dax Dupont: + - rscadd: You can now rename and copy holodisks! + - rscadd: Holorecordings now can be looped. + - tweak: Holodisks now have materials and the autolathe cost has been adjusted. + - bugfix: Fixed holodisk speaker name not getting set when on non-prerecorded messages. + Epoc: + - bugfix: Slows Simple Clown mobs + GuppyLaxx: + - bugfix: Fixes the Ketrazine recipe + Iamgoofball: + - balance: Power cells explosions are now logarithmic + Naksu: + - code_imp: Cleaned up some /obj/item vars + - bugfix: Pneumatic cannons no longer misbehave when their contents such as primed + grenades get deleted (explode) + Robustin: + - rscadd: The Peacekeeper Borg's "Peace Hypospray" now includes the "Pax" reagent, + which prevents the subject from carrying out many forms of direct harm. + SpaceManiac: + - spellcheck: Clockwork armaments are no longer named "arnaments". + - bugfix: The Syndicate Listening Post's medicine closet now has the correct access. + coiax: + - rscadd: Syndicate intelligence potions also grant an internal syndicate ID card + to the simple animal granted intelligence. This effectively means that Cayenne + can open the airlocks on the Infiltrator. + uraniummeltdown: + - bugfix: You can no longer weld airlock assemblies for infinite materials +2018-01-27: + Anonmare: + - balance: The Syndicate Chameleon Kit is now available during rounds of lower population. + Because of course you can have an e-sword and revolver without restriction but + disguising and RP is verboten because we deathmatch station now. + Dax Dupont: + - bugfix: Eminence won't get spammed by tile crossing now. + Denton ShizCalev Kor Kevinz000 (original idea): + - balance: Due to budget cuts, the shoes shipped with chameleon kits no longer prevent + slipping. The premium version is unchanged and still sold separately. + - balance: To compensate, the chameleon kit cost was lowered by 2 TC and the minimum + crew limit removed. + Jittai: + - imageadd: New Morgue Tray sprites. + - imageadd: New Crematorium sprites. + Naksu: + - bugfix: Away missions no longer require manually adjusting subsystem mob/client + lists in order to not have the AI break. + WJohnston: + - bugfix: The lavaland syndie base is now packed with considerably fewer explosives, + and should lag far less brutally when exploding. + coiax: + - balance: Mobs will now start with a random nutrition amount, between hungry and + mildly well fed. + - rscadd: Nanotrasen Security Division has reported that syndicate comms agents, + both on lavaland and in space, have had training in "Codespeak", a top secret + language for stealthy communication. + uraniummeltdown: + - imageadd: Ore boxes have a new sprite +2018-01-29: + ACCount: + - rscadd: Having station blueprints in your hands now reveals function of wires + in station objects. + DaedalusGame: + - bugfix: fixed a strange pipenet issue that happens when a singular pipe or manifold + is placed directly between two or more components and wrenched last. + Dax Dupont: + - bugfix: After 3 years of intensive research by Nanotrasen's elite team of chefs, + rice dishes such as rice pudding are no longer considered salads. + Denton: + - spellcheck: Fixed Bubblegum's description. + F-OS: + - tweak: Academy is now part of the random station names. + Mark9013100: + - rscadd: Cloning data disks can now be constructed after researching the Genetic + Engineering technode. + MrStonedOne: + - tweak: 511 Clients can see atmos gases + - rscdel: This reverts the fix that prevents atmos gas overlays from stealing clicks. + Naksu: + - bugfix: Attempting to join into a command role as a nonhuman species no longer + lets you keep your nonhuman species languages if you are transformed into a + human because of a config option + - bugfix: Warp whistle can no longer pick up its user from inside various animation/in-between + states and effects such as transformations, jellypeople split, talisman of immortality + effect period or rod form. + WJohnston: + - bugfix: The centcom ferry shuttle now works again. + XDTM: + - balance: Peacekeeper cyborgs have synth-pax instead of normal pax, which has the + same effect but wears out faster. + - rscadd: Xenobiology consoles can now scan slimes and apply potions remotely. Use + potions on the console to load them. + - rscadd: Abductors now have the chemical, electric and trauma glands. + - rscdel: Removed the bloody, bodysnatch and EMP glands. + - tweak: The abductor viral gland now generates a random advanced virus instead + of a basic one. + - tweak: The abductor heal gland now also heals toxin damage. + - tweak: The abductor mindshock gland can now cause different reactions. + - tweak: The abductor slime gland now gives the slime faction. + - tweak: The abductor species gland now randomizes the victim's appearance and name + on top of the species. + - rscadd: 'Abductors have a new surgery type: violence neutralization. It has the + same steps as brain surgery, but it will instead inflict a Pacifism trauma upon + the victim, making them mostly harmless in the future.' + - rscadd: Bath Salts now give complete stun immunity while they last. + - balance: Ketrazine now gives immuity to sleeping. + improvedname: + - rscadd: Adds bz to cargo + ninjanomnom: + - rscdel: Removed the ability to create new shuttle areas or expand existing ones + with blueprints. + - bugfix: Special areas like rooms which require no power can no longer be expanded. + You can still expand into them however. + - bugfix: Turning to face a direction with control no longer moves you in the faced + direction after releasing control. + uraniummeltdown: + - rscadd: You can alt-click microwaves to turn them on +2018-01-30: + Cyberboss: + - bugfix: Blood contracts now only show living players and real names + DaedalusGame: + - tweak: made fire colored according to blackbody radiation and rule of cool. + - imageadd: some kind of lightning texture + Dax Dupont: + - rscadd: Cyborgs can now be upgraded to be h-u-g-e! Only a cosmetic effect! + ExcessiveUseOfCobblestone: + - bugfix: Turrets now check for borgs. Syndicate turrets are nice to emagged borgs + too! + Iamgoofball: + - bugfix: Minor code cleanup on the wirer + Jalleo: + - balance: nerfs power cells from a insane max possibility + Jittai: + - imageadd: Crematoriums and Morgue Trays now have directional states. + - bugfix: Morgue Trays now checks for cloneable people like the dna-scanner does. + (ghosts can roam now) + - bugfix: Cremated mice no longer leave behind snackable bodies. + - bugfix: Ash does not get instantly deleted in the crematorium upon creation. Ash + also piles up. (aesthetically only) + - tweak: Morgue/Crematorium Trays make a slight rolling sound. + More Robust Than You: + - tweak: Announcing messages while drunk will be slurred + Naksu: + - bugfix: Subjects without hearts now display as unsuitable for abductor experiments + when probed with the advanced baton. + - balance: BZ gas now makes lings lose their chems and hivemind access. The chem + loss is gradual. + - rscdel: 'Removed actual reagent quadrupling added in #34485' + - rscdel: Removed the foam effect combining feature, hopefully to be replaced with + something less completely and utterly broken + PKPenguin321: + - rscadd: Attention, space explorers! Nothing is out of your reach with the ACME + Extendo-Hand (TM)! With it, you can get a WHOLE EXTRA TILE OF REACH! Hug or + punch your friends from a whole 3 feet away! Win one from an arcade machine + or make one in the Misc. tab of your crafting menu today! + Robustin: + - rscadd: Blood magic. The next generation of talismans - you can create 2 spells + without a rune, up to 5 with a rune of empowerment. Preparing spells without + a rune will cost a significant amount of blood. Every talisman has been rebalanced + for its spell form. With a few exceptions, blood magic exists as a "touch" spell + that is very similar in behavior/appearance to the wizard touch spells. + - rscadd: New UI system for cultists. + - rscdel: Removed talismans, Talisman Creation Rune replaced by Rune of Empowerment. + Supply talisman has been replaced by a ritual dagger and 10 runed metal. + - rscadd: Ritual Dagger, replacing the Arcane Tome. This is largely a thematic alteration + but its to reinforce that your primary tool is also a weapon. + - bugfix: Cyborgs and AI are finally unable to see runes again + - tweak: Only the cult master can forge Bastard swords now, regular cultists can + get a mirror shield. + - rscadd: 'The mirror shield, it blocks, it reflects, it creates illusions, and + an incredible throwing weapon! The mirror shield also bears a unique weakness: + Shotgun slugs, .357 rounds, and other high damage projectiles will instantly + shatter it and briefly stun the holder.' + - balance: Nar'sien Bolas will not longer ensnare cultists and non-cultists will + ensnare themselves when attempting to use them. The bolas are now comparable + in effectiveness with reinforced bolas. + - rscadd: Rune of Spirits. This merges the Spirit Sight and Manifest Ghost rune. + The user will now choose which effect when invoking. + - rscadd: The Spirit Sight function has received several major improvements, allowing + the ghost to commune with the cult and mark objects similar how the cult master + can. The user has a unique appearance while ghosted and manifested cult ghosts + can see ghosts as well - allowing their summoner to lead them from the spirit + realm. + - balance: The Form Barrier rune will now last significantly longer and examining + the rune as a cultist will tell you how long it will remain. + - rscadd: The Apocalypse Rune. Replaces the EMP runes. Has a fixed invoker requirement + and added usage limitations. It scales depending on the crew's strength relative + to the cult. Effect includes a massive EMP, unique hallucination for non-cultists, + and if the cult is doing poorly, certain events. The rune can only occur in + the Nar-Sie ritual sites and will prevent Nar-Sie from being summoned there + in the future. + - rscdel: No more EMP rune. + - balance: The conceal/reveal spell now has 10 charges and will conceal far more, + including cult structures and flooring. + - balance: The stun spell will now stun for ~4 less seconds and silence for 2 more + seconds. + - balance: The EMP spell now costs 10 health to use, up from 5, and has had its + heavy/light EMP range nerfed by 1 and 2 respectively (now 3 and 6). + - balance: The shackles spell now has a silence effect similar to the stun talisman. + - balance: The hallucination spell now has multiple charges. + - tweak: The teleport spell can now be used on other adjacent cultists. + - tweak: Summon Tome and Summon Armor have been combined into "Summon Equipment", + which lets you choose between summoning a Ritual Dagger or Combat Gear (same + loadout that Summon Armor used to provide). + - balance: Standard cult robes now have -10 melee and -10 laser armor. + - balance: The "Construction" spell will now convert airlocks into cult airlocks + and cyborgs (after ~10 seconds) into constructs. The airlock is the most fragile + in the game, with reduced integrity, armor, and render it vulnerable to most + attacks. Cyborg "reconstruction" will be accompanied by an obvious effect/sound. + - rscadd: Blood Rites. This spell allows you to absorb blood from your surroundings + or adjacent non-cultists. You can use the blood rites as a convenient heal (self-healing + is significantly more costly though) or you can try to gather large quantities + of blood for unique and powerful relics. + - rscadd: Blood spear, a fragile but robust spear with a special recall ability + - rscadd: Blood bolts, the cultist's version of arcane barrage. The bolts will infuse + cultists with unholy water and damage anything else. + - rscadd: Blood beam, the ultimate blood rite. After a channeling period it will + fire 12 powerful beams across a long distance, piercing almost any surface (except + blessed turf), and damaging all non-cult life caught in the beam. + - tweak: All cult structures now generate significantly less light. + - balance: Pylons will now heal constructs faster and restore slightly more blood + than before. + - balance: Cult floors are now highly resistant to atmospheric changes. + - bugfix: Unholy water will now splash victims properly. + - balance: Unholy Water Vials created at altars now contains 50 units, and is better + at healing brute, and deals slightly more damage to non-cultists, the splash + ratio was reduced to 20% to compensate for the increased volume and damage. + - balance: Holy water will purge any and all blood spells from cultists. + - rscadd: Artificers, Wraiths and Juggernauts can now scribe revive, teleport, and + barrier runes respectively with a 3 minute cooldown. + - balance: Juggernauts' forcewall is now 3x1 but it has a ~30% longer cooldown. + Juggernauts got a modest speed increase (2.5 from 3) but lost a modest amount + of HP (200 from 250). + - rscadd: Juggernauts now get a ranged attack "Gauntlet Echo", a single projectile + that moves about as fast as them and does 30 damage with 5 seconds of stun and + a 35s cooldown. + - balance: The number of ghosts summonable by the manifest spirit rune is 3, down + from 5. + - balance: It now takes ~20% less water (~25 units) and ~30 seconds less to deconvert + cultists via holy water. + - tweak: The emagged library console will now distribute ritual daggers. + - tweak: Using the dagger on a rune will now take a 1-second channel to destroy + it, to avoid incidents where people instantly wipe a critical rune by accident. + - balance: Standard runed airlocks now have a lower damage deflection so they can + be destroyed with most respectable melee weapons (10+). + - balance: Teleporter runes that are used from space or lavaland will result in + the destination rune giving off a unique effect for 60 seconds. This effect + includes a long distance (but not obvious antagonistic) sound, a bright lighting + effect, and a visual cue that will indicate where the cultist arrived from. + Shadowlight213: + - tweak: Pluoxium is no longer considered dangerous for air alarms. + XDTM: + - tweak: Slimepeople can now host multiple minds in their body pool; occupied bodies + will be marked as such in the bodyswap panel. + - tweak: Slimepeople now retain 45% of their slime volume upon splitting instead + of a fixed amount. + Xhuis: + - rscadd: Defibrillator mounts can now be found in the CMO's locker or produced + from a medical protolathe after Biotech is unlocked. They can be attached to + walls, and hold defibrillators for public use. You can swipe an ID to clamp + the defibrillator in place, and it will automatically draw from the powernet + to recharge it. Being one tile away from the mount will force you to drop the + paddles. + - balance: Stargazers have been removed. + - balance: The clockwork cult now has a power cap of 50 kW. + - balance: Script scripture is now unlocked at 25 kW, and Application at 40 kW, + instead of 50 kW and 100 kW. + - tweak: Important scriptures are now displayed with italicized names. + Xhuis & Jigsaw: + - rscadd: Traitor clowns can now purchase the reverse bear trap, a disturbing head-mounted + execution device, for five telecrystals. + kevinz000: + - rscadd: Chameleon laser guns now have a special firing mode, activated by using + them in hand! Only certain gun disguises will allow this to work! + nicbn: + - bugfix: Bloodpacks will have their colors defined by the reagents + - imageadd: MMI dead sprite will now show a red light and no eyes instead of X-crossed + eyes + uraniummeltdown: + - imageadd: Solar panels have new sprites + - imageadd: Coffins have a new sprite diff --git a/html/changelogs/archive/2018-02.yml b/html/changelogs/archive/2018-02.yml new file mode 100644 index 0000000000..e6d600824e --- /dev/null +++ b/html/changelogs/archive/2018-02.yml @@ -0,0 +1,772 @@ +2018-02-01: + CosmicScientist: + - balance: tomatoes and similar ovary laden edibles are fruit, not veg, beware plasmamen + and mothmen + Denton: + - bugfix: Added a missing distress signal to the space ambush ruin. + Jalleo: + - rscdel: Space ghost syndicate comms guy removed. + Jittai: + - bugfix: Cloning doesn't runtime (and indefinitely get stuck) on cloning non-humans. + - tweak: Some of the Morgue Trays and Crematoriums on Box, Delta, and Meta have + been re-positioned to make use of their new directional states. + - imageadd: New Horizontal Coffin Sprites + SpaceManiac: + - tweak: The Whiteship spawn point is now a space ruin rather than being fixed every + round. + Xhuis: + - balance: Servant golems no longer appear in the magic mirror race list. + - bugfix: Cogs now fucking work + cebutris: + - spellcheck: The text you get when you examine a stunbaton to see the battery level + now uses the item's name instead of "baton" +2018-02-02: + Dax Dupont: + - tweak: Hijack objectives will only be given out if there are 30 or more players. + DeityLink: + - rscadd: You can now see the rays from a holopad displaying a hologram! + Epoc: + - bugfix: Soap now has inhand sprites + Xhuis: + - balance: Brass skewers now must be at least one tile apart. + - balance: Steam vents can no longer be placed within cardinal directions of other + steam vents, and will not hide objects they're placed on top of. + - bugfix: Races that have eyes that look different from regular humans' no longer + have white eyespots where human eyes appear. + Xhuis, Cosmic, Fwoosh, and epochayur: + - rscadd: Added pineapples to botany, and a recipe for Hawaiian pizza. + improvedname: + - rscadd: adds yeehaw to the dj's disco soundboard + oranges: + - rscdel: removes ketrazine +2018-02-03: + Dax Dupont: + - tweak: Moved the lathe from box's cargo room to box's cargo office which miners + now can access. + - tweak: Harmonized medbay storage access requirements so all maps allow all medbay + personnel into medbay storage like on Meta and Delta. + - tweak: Moved service lathes into a dedicated service hall/storage area if they + weren't accessible by janitor or bartender. + SpaceManiac: + - code_imp: Removed the now-unused revenant spawn landmark. + Xhuis: + - bugfix: Servant cyborgs with the Standard module now correctly have Abscond. + - bugfix: Securing pipe fittings now transfers fingerprints to the new pipe. + - bugfix: The firelock below the Circuitry Lab airlock on Boxstation will no longer + cover it up when the airlock is open. + uraniummeltdown: + - bugfix: Some airlock animations should no longer be glitchy and restart in the + middle +2018-02-04: + Buggy123: + - rscadd: Morgue trays now detect if a body inside them possesses a consciousness, + and alerts people nearby + Cruix: + - rscadd: The Rapid Piping Device can now dispense transit tubes. + Dax Dupont: + - rscadd: Added logout button to the record screen in the security records console. + - rscadd: Allows you to print photos that are in the security records. + Incoming5643: + - rscadd: The ability to throw drinks without spilling them has been moved from + something bartender's just know how to do to a book that they spawn with, the + ability has also been made into a toggle. + - rscadd: Any number of people can read the book to learn the ability, and it can + also be ordered in the bartending crate in cargo. Bartenders are encouraged + to keep their trade secrets close to their stylish black vests. + Kor: + - bugfix: Fixed mecha grav catapults not being included in techwebs. + MrDoomBringer: + - imageadd: Conveyor Belts now look better when they are crowbar'd off the ground. + - rscadd: Due to complicated quantum-bluespace-entanglement shenanigans, the Bluespace + Drop Pod upgrade for the express supply console is now slightly more difficult + to research. + Robustin: + - bugfix: Vape Pens (e-cigs) will now consume reagents proportional to the vape + size and static smoke production. + - bugfix: Command reports should now properly weight the appearance of modes based + on their existence in our actual game rotation. + - balance: The current mode now has a 35% chance of not appearing in the report. + ShiggyDiggyDo: + - rscadd: You can now win stylish steampunk watches at your local arcade machine! + ShizCalev: + - bugfix: Fixed some broken cultist & wizard antagonist ghost polls. + - rscadd: The Syndicate Comms Officer ghost role has been readded with a minor chance + of actually existing. + Slignerd: + - balance: Following an immense number of complaints filed by security and command + personnel, the Captain's spare ID will from now on be placed inside his locker. + We fail to see how this would help the Captain access the spare in the event + he lost his ID, but the complainants have been VERY insistent. + SpaceManiac: + - bugfix: The pirate ship can now fly again. + Xhuis: + - balance: Integration cog power generation has been increased to 10 W per second + (up from 5 W per second.) Power consumed from the APC remains at 5 W per second. + - balance: Integration cogs will now continue generating power at half-speed when + the APC they are in has no energy. + coiax: + - balance: Romerol is now effective on dead bodies, not just ones that are still + alive. + nicbn: + - rscadd: Destroying windows will now spawn tiny shards +2018-02-05: + Dax Dupont: + - balance: Regular cyborgs now start with a normal high capacity cell instead of + a snowflake cell. Resulting in less confusing and 2.5MJ more electric charge. + - bugfix: Fixed name of the upgraded power cell + - refactor: Removed duplicate cell giving code in transformation proc. + - bugfix: Fixed the crematorium on meta and box. + Denton: + - tweak: Rearranged the mining vendor items by price and item group. + - tweak: In order to promote back-breaking physical labor, Nanotrasen has additionally + made conscription kits available at mining equipment vendors. + Iamgoofball: + - rscdel: Blood cultists can't space base anymore + MMMiracles: + - rscadd: A once-thought abandoned arctic post has recently had its gateway coordinates + re-enabled for access via the Gateway link. Contact your local Exploration Division + for more details. + More Robust Than You: + - bugfix: Holorays are now properly deleted if you switch holopads automatically + Naksu and kevinz000: + - tweak: Ores are no longer completely impervious to explosions, but rather "proper" + ores are destroyed by the strongest explosions and sand is blown away everything + but the weakest ones. This shouldn't affect ore spawns from explosions + - tweak: Lavaland bomb cap reduced to double the station bombcap. + - refactor: Ores are now stackable. Ore stacks now have the appearance of loose + ores and are not called "sheets" by machines that consume them. + - code_imp: Material container component now uses the singular names of stack objects. + - refactor: /obj/item/ore/Crossed() is now removed in favor of the ore satchel utilizing + a redirect component + ShiggyDiggyDo: + - spellcheck: You no longer win double the articles at the arcade + SpaceManiac: + - bugfix: Research investigate logs now actually include the name of the researcher. + XDTM: + - bugfix: Fixes intelligence potions removing previously known mob languages + - tweak: Slime scanning now has a more readable output, especially when scanning + multiple slimes at once + - tweak: Eggs from the abductor egg gland now have a random reagent instead of acid +2018-02-06: + Dax Dupont: + - bugfix: AIs can no longer turn on broken APCs, + SpaceManiac: + - bugfix: Defibrillator mounts no longer spam the error log while empty. + - bugfix: The various ships in the caravan ambush space ruin can now fly again. +2018-02-07: + DaedalusGame: + - bugfix: Fixes Noblium Formation being multiplicative, so having 500 moles of tritium + and 500 moles of nitrogen no longer produces 2500 moles of noblium (it should + correctly produce 10 moles) + - bugfix: Fixes most reactions deleting more gas than exists and making gas out + of nowhere + - bugfix: Fixes Stim Formation invoking a byond bug and not using its intended polynomial + formula + - bugfix: Fixes Cryo Cells not having garbage_collect and clamping + - bugfix: Fixes Rad Collectors not having clamping + - bugfix: Fixes Division by Zero when Fusion has no impurities. + - bugfix: Removes a redundant line in lungs + - bugfix: Fixes rad_act signal not firing from turfs, living mobs, rad collectors + and geiger counters + - bugfix: fixes lava burning into chasm tiles i hate hate hate hate them so much + grrrr + - tweak: NT Scientists have started looking into data from small-scale detonations + and found that there's still potential data to be gathered from explosive yields + lower than 4.184 petajoules + Dax Dupont: + - tweak: Moved the pocket protector to lockers instead of on the uniform. + - rscadd: You can now insert holodisks into cameras and take a static holographic + picture of someone! + - rscadd: Hologram recordings can now be offset slightly. + - rscadd: Posibrains have gotten a small firmware update, they will now play a sound + on successful activation. + - rscadd: Killing a revenant will now result in an unique shuttle to be able to + be bought. You probably won't like it though. + - rscadd: Fake emag now available. + Denton: + - spellcheck: Mining drone upgrades are no longer referred to as "ugprade" + - tweak: Fungal tuberculosis spores can no longer be synthesized by machinery. + Kor: + - rscadd: Spawning as a syndicate comms officer will now activate an encrypted signal + in the Lavaland Syndicate Base, to aid the crew in retaliating. + Ordo: + - rscadd: Mamma-mia! The chef speaks-a so different now! + Robustin: + - balance: The "construct shell" option from the cult archives structure will now + only yield one shell instead of two. + - balance: Sacrificing suicide victims will now only yield an empty shard. + - balance: Synths and Androids are no longer available species at the magic mirror. + ShiggyDiggyDo: + - rscadd: You can now win Toy Daggers at your local arcade! + Skylar Lineman: + - rscadd: Nanotrasen has new intelligence that the newest batch of Syndicate agent + equipment includes sticky explosives disguised as potatoes, designed to incite + terror among whoever is unlucky enough to have one stuck onto their hands. + - rscadd: 'Nanotrasen''s toy suppliers have also started making faux versions of + these, with less-forceful attachment mechanisms and absolutely zero explosive + materials for a child-safe experience. experimental: Explosive Hot Potatoes + are now available for purchase by syndicate-affiliated cooks, botanists, clowns, + and mimes.' + SpaceManiac: + - bugfix: Pressure damage now takes effect in certain situations where it should + have but did not. + Xhuis: + - rscadd: Nanotrasen's anomalous materials division has recently experienced a containment + breach, during which a certain pizza box went missing. Be on the lookout for + any slipups in cargo. + - spellcheck: Pizza margherita is now named "pizza margherita" (the proper way!) + instead of just "margherita." + - tweak: Brass chairs now stop spinning after eight rotations, so you can't crash + the server with them. + coiax: + - rscadd: Eggs now contain 5u of egg yolk. Breaking an egg in a glass container + adds all reagents inside to the container. If you're laying abductor gland eggs, + then you'll get 5u of egg yolk and 10u of random reagent. Egg glands now make + you act like a chicken while laying eggs. Egg laying makes you use the aliennotice + span. + kevinz000: + - balance: Explosive holoparasites must now be adjacent to turn objects into bombs, + instead of being able to do so from any range. +2018-02-09: + Cyberboss: + - balance: Printed power cells must now be charged before use + Dax Dupont: + - bugfix: Supermatter can again blow up again on space tiles. + - bugfix: Fixed borgs applying cuffs on people without the right number of arms. + - refactor: Handcuff code has been rejiggled and snowflake code has been removed. + - rscdel: Removed unused cable cuffs module stuff for borgs. + - bugfix: Telecom equipment now can only be printed by engineers and scientists + as intended. + - bugfix: WT-550 AP can only be printed by sec now. + - tweak: Removed engineering requirement for arcade machines to bring it in line + with others. + - rscadd: Defibs can now be researched and printed. + - balance: Hatches are now small instead of tiny. + Denton: + - code_imp: Changed can_synth values from 0/1 to FALSE/TRUE + - code_imp: Removes grind_results from empty soda cans since they can't be ground. + - spellcheck: For consistency's sake, aluminium is now universally spelled with + two 'i'. + Epoc: + - imageadd: Belt items now have inhand sprites + Evsey9: + - balance: Integrated Circuit Drones are now bulky to improve safety ratings, and + therefore, cannot be stored in normal backpacks or pockets, but now can accept + modules that bulky circuit machinery can. + - balance: Grabbers can now grab items up to the size of the circuit assembly they + are in. + - balance: Grabbers cannot store circuit machinery the same or larger size than + the circuit assembly they are in. + - tweak: Throwers now can throw items up to the size of circuit assembly they are + in. + MMMiracles: + - rscadd: A brand new space-farm, where your family sends all your old/sick catpeople + to live out the rest of their days being free to roam the acres and chase the + field grayshirts. + Naksu: + - bugfix: Cyborg engineering module geiger counters now work properly again + PKPenguin321: + - rscadd: As it would happen, the chef does not actually have Italian genes, but + rather was being influenced by a strange moustache-a. + Robustin: + - bugfix: Fixes the cult master getting two notifications on the cult forge + - rscadd: Blood spells will now "follow" the spell creation button, which is now + unlocked by default. If you want your spell "hotbar" to appear somewhere else, + just move the blood spell button, it will update when you prepare a new spell. + Also, individual spells start off locked but if you unlock them they will no + longer reposition when the spells are updated. + Robustin and More Robust Than You: + - rscadd: A heart disease event has been added. The cure is heart replacement surgery. + Effects of cardiac arrest are halted by the chemical Corazone. Once cardiac + arrest begins at Stage 5, the disease can be cured by a defibrillator or from + a lucky electric shock. + - rscadd: Using gym equipment will now grant a hidden exercise buff that prevents + heart disease for 20 minutes. + SpaceManiac: + - bugfix: Goliath hide plates now properly apply to explorer suits and APLUs again. + oranges: + - rscdel: Removed the saltmine grief shuttle +2018-02-10: + Cruix: + - balance: Changed the chemical recipe for Lexorin from plasma, hydrogen, and nitrogen + to plasma, hydrogen, and oxygen. + - bugfix: These were necessary due to recipe conflicts + Dax Dupont: + - bugfix: Cloner UI now properly updates cloning pod status when autocloning starts + cloning someone. + Ordo: + - tweak: Replaced nitrogen with ethanol in morphine recipe. The recipe now has a + lower yield. + Robustin: + - bugfix: Fixed the limb grower having a max volume of 0. + UI Changes: + - tweak: The Scan with Debugger/Device button now reads Copy Ref and no longer sends + you to the circuit's page when clicked + - tweak: The assembly's menu is now slightly wider + - tweak: The advanced in "integrated advanced medical analyser" is now abbreviated + to adv. + Xhuis: + - bugfix: The preference to lock action buttons in place is now correctly saved + across rounds. +2018-02-11: + DaedalusGame: + - bugfix: Prevents megafauna (and other large things like spiders and mulebots) + from going into machines + Dax Dupont: + - rscadd: You can now win a fake cryptographic sequencer, perfect to go with your + fake space suit! + - tweak: 'To login with an emag on the APC console you will now need to hit it with + the emag. removed: Snowflake emagging implants is no more, Swipe it before install.' + - refactor: everything uses emag_act() now + - balance: Grabbers/throwers no longer can contain/throw things equal to the assembly + size. + - bugfix: Fixes duplicate air alarm on meta. + Kor: + - rscadd: Mining sentience upgrades now grant minebots an ID and radio. + Mokiros: + - rscadd: All-In-One Grinder can now be built with researchable curcuit and micro-manipulator. + More Robust Than You: + - rscadd: You can now squish urinal cakes + More Robust Than You, Basilman, and MMMiracles: + - rscadd: Deep in space, a valuable artifact awaits + Naksu: + - rscdel: Steam engines have been removed from maintenance, engineering, atmos and + teleportation areas. + - rscadd: The chef is now trained for working under siege + Shadowlight213: + - admin: The notify irc/discord bot chat command no longer requires admin privileges. + ShizCalev: + - bugfix: Corrected a number of missing checks when using alt-click actions. Please + report any strange behavior to a coder. + - spellcheck: Corrected typo in NTNet Scanner circuits' name, make sure to update + your blueprints. + uraniummeltdown: + - rscadd: You can now smelt titanium glass and plastitanium glass + - rscadd: Use titanium glass and plastitanium glass to build shuttle windows and + plastitanium windows +2018-02-12: + Dax Dupont: + - bugfix: AI no longers block ark after mass_recall + - bugfix: Placed the dispersal logic AFTER the mass_recall on ark activation instead + of infront(did nothing before basically). + - rscadd: Cell chargers can now be built and upgraded with capacitors! + - bugfix: Fixed empty subtype batteries not updating icons + Denton: + - bugfix: Fixes lye/plastic/charcoal conflicts when mixing. + - bugfix: Lye is now made by combining ash with water and carbon. Plastic sheets + by heating ash, sulphuric acid and oil. + More Robust Than You: + - bugfix: Your hand no longer magically squishes urinal cakes when trying to pick + them up + - bugfix: SCP-294 no longer looks fucked up + Robustin: + - balance: The rift created by teleporting in from space will now include a description + indicating the direction of the "origin" teleport rune - giving the examiner + a fair idea of where the "space base" is located. + - balance: You can no longer manifest spirits or summon cultists while in space + or Lavaland. You may still ascend as a spirit (formerly spirit sight, astral + jaunt, etc.) in either of these locations. + - balance: Juggernauts have lost 20% reflect rate on energy projectiles (now around + 50% for standard lasers). + - balance: Wraiths and Juggernauts have -5 melee damage (20 and 25 now, respectively). + - balance: Construct shells now cost 50 metal through the "twisted construction" + spell. Twisted construction is now a "single use" spell. + - balance: The Concealment spell will now work on cult airlocks (including converted + airlocks). The "concealed" airlock will appear as a generic airlock but will + deny access to any non-cultist. + - balance: The draw blood effect on blood splatters will now draw more blood from + stains with low blood levels. + - tweak: Unanchored (via ritual dagger) cult structures are no longer "dense", meaning + you can move them through teleport runes more efficiently. + - tweak: The button to nominate yourself for cult master now has a confirmation + prompt seeking assurance that the user is prepared to be the cult's master. + - tweak: The reveal aspect of the concealment spell is slightly smaller, albeit + still slightly larger (6 range) than the concealment aspect (5 range). + - imageadd: Juggernauts "gauntlet echo" now has a more cult-themed appearance. + - bugfix: Using a shuttle curse to push the shuttle timer above its default can + no longer be "reset" with a recall. This also adds a block_recall(time_in_deciseconds) + helper-proc to the shuttle subsystem. + - bugfix: Using runed metal on a regular girder is no longer an option, preventing + runtimes and deletions associated with the (unintended) combination. +2018-02-13: + Buggy123: + - tweak: After consulting with their in-house physicists, Nanotrasen has updated + their worst-case disaster training simulation "Space Station 13". The combustion + of hydrogen isotopes now produces water vapor instead of carbon dioxide. + Dax Dupont: + - rscadd: Added hooray emoji! + Iamgoofball: + - bugfix: The Cook now ONLY works under siege. + TehZombehz: + - rscadd: Heart-shaped boxes of chocolates are now included in Valentine's Day event + gifts +2018-02-14: + Dax Dupont: + - bugfix: Integrated circuits no longer start upgraded. + - balance: The IC printers that are available on round start in the IC labs are + no longer upgraded by default. You will need to research these as was intended + Frozenguy5: + - bugfix: You can craft rat kebabs now. + Naksu: + - bugfix: Chasms no longer eat shuttle docking ports, rendering them unusable and + unresponsive + - tweak: The clogged vents event has been removed for pressing ceremonial reasons + coiax: + - rscadd: Transference potions now just rename the mob that you are transferring + into with your name, rather than your name plus the old name of the mob. +2018-02-15: + Kor: + - rscadd: Bluespace slime extracts now have a new chemical reaction with water, + which create slime radio potions. When applied to a simple animal, that mob + gains an internal radio. + MrStonedOne: + - balance: You no longer need an aggressive grab to table someone. + SpaceManiac: + - refactor: Map initialization now supports stations with multiple z-levels. + - bugfix: The map reader no longer sometimes expands the world size inappropriately. + - tweak: Pride's Mirror's destination has become less predictable. +2018-02-16: + AnturK: + - rscdel: Minimap gone from crew monitoring + DaedalusGame: + - code_imp: made powercell rigging no longer set rigged to the plasma reagent datum + what the hell and makes it use TRUE/FALSE defines + Denton: + - tweak: Emagging meteor shield satellites now shows you a message. + - spellcheck: Fixed a typo when emagging RnD servers. + MMMiracles: + - rscadd: You can now produce a cryostatis variant of the shotgun dart after researching + Medical Weaponry. Holds 10u and doesn't have reagents react inside it. + MetroidLover: + - rscadd: Added the ability to gain smoke bomb charges by attacking the initiated + ninja suit with a beaker containing smoke powder + More Robust Than You: + - bugfix: Fixes SCP-294 losing its top sometimes + Naksu: + - code_imp: replaced some item-specific movement hooks with components + Xhuis: + - tweak: Removing and printing integrated circuits will now attempt to place them + into a free hand. + - tweak: You can now hit an integrated circuit printer with an unsecured electronic + assembly to recycle all of the parts in the assembly en masse. + - tweak: You can now recycle empty electronic assemblies in an integrated circuit + printer! + - soundadd: Integrated circuit printers now have sounds for printing circuits and + assemblies. + - bugfix: The RPG loot event will no longer break circuit analyzers. + coiax: + - rscadd: Centcom now reports that thanks to extensive bioengineering, apples and + oranges now taste of apples and oranges, rather than nothing as they did before. +2018-02-17: + DaedalusGame: + - bugfix: fixes lava and fire burning HE-pipes + - rscadd: added a subreaction for rainbow slime cores, injecting 5u of plasma now + makes them explode into random slimecores. + - rscadd: added a slimejelly reaction to rainbow slime cores that does the above + but all the cores that spawn get 5u each of plasma, water and blood injected. + (aka chaos) + - code_imp: improved clusterbuster code with Initialize, addtimer, vars for sounds + and payload spawners, etc + Dax Dupont: + - bugfix: After an incident where a very eager roboticist kept expanding a borg's + size leading to a structural collapse of the entire station proper safety limitations + have been implemented. + - bugfix: You can rotate freezers and cryo again. + - rscadd: Nanotrasen has invested in better reflective materials for it's reflectors. + You can now make complex laser shows again. + Modafinil: + - rscadd: Adds new medicine chem that suppresses sleep and very lightly reduces + stunrates, has a very low metabolic rate which is randomized and a low overdose + treshold. Overdosing is a lethal oxyloss unless treated. (With epipen urgently + and with charcoal/calomel before it puts you to sleep) + TankNut: + - tweak: Corpses spawned in ruins have their suit sensors disabled + coiax: + - admin: Admins can use the Select Equipment verb on observers. Doing so will humanise + them and then apply the equipment. + - bugfix: Species with RESISTHOT (golems, skeletons) can extinguish burning items + as if they were wearing fireproof gloves. + jakeramsay007: + - bugfix: Jellypeople/Slimepeople now are able to speak their Slime language, as + intended when it was added. + yorii: + - bugfix: removes the maintenance panel examination message on poddoors (blast doors) +2018-02-18: + More Robust Than You: + - bugfix: Actually fixes SCP 294 overlay problems + Naksu: + - rscadd: Exosuit fabricators can now build RPED and crew pinpointer upgrades for + engineering and medical borgs respectively. + Ordo: + - rscadd: Adds a few new liquors to the bar, and a few new cocktails to boot! + Xhuis: + - tweak: Crew pinpointers now fit on medical belts! + YPOQ: + - bugfix: Bicycles are rideable again +2018-02-19: + DaedalusGame: + - bugfix: Fixed paper bins not catching fire properly + - bugfix: fixed multiserver mining formula + Improvedname: + - bugfix: Fried eggs don't require boiled eggs anymore and just normal eggs + Kevinz000 and Naksu: + - bugfix: Ore stacks will now initialize with proper visuals and no longer show + a NO SPRITE text when you gather more than 20 ores to a stack. + XDTM: + - rscadd: 'Added three new techweb nodes: Advanced Surgery, Experimental Surgery, + and Alien Surgery(requires abductor tech)' + - rscadd: Added several new surgical procedures, which require these techweb nodes. + To enable an advanced surgery, print its relative disk from a protolathe, and + load it on an Operating Computer. Advanced surgery can only be performed at + operating tables. + - tweak: You can now intentionally fail surgical procedures by initiating them with + disarm intent instead of help intent. + - rscadd: Brain traumas now have a custom resilience system. Some trauma sources + can cause traumas which require more extensive treatment, such as the new Lobotomy + surgery. + - rscadd: Traitors can now purchase a Brainwashing Surgery Disk for 5 TC. + Xhuis: + - bugfix: New blob tiles are no longer invincible after their blob's death. + - bugfix: Blob nodes no longer produce blob tiles even after the blob's death. + coiax: + - rscadd: Mime's Bane, a toxin that prevents people from emoting while it's in their + system, can now be created by mixing 1 part Mute Toxin, 1 part Nothing and 1 + part Radium. +2018-02-20: + Anonmare: + - rscadd: Nanotrasen psychologists have identified new phobias emerging amongst + the workforce. Nanotrasen's surgeon general advises all personnel to just buck + up and deal with it. + AverageJoe82: + - rscadd: Circuits integrity, charge, and overall circuit composition is displayed + on diagnostic huds. If the assembly has dangerous circuits then the status icon + will display exclamation points, if the assembly can communicate with something + far away a wifi icon will appear next to the status icon, and if the circuit + can not operate the status icon will display an 'X'. + - rscadd: AR interface circuit which can modify the status icon if it is not displaying + the exclamation points or the 'X'. + - tweak: Locomotive circuits can no longer be added to assemblies that can't use + them. + - spellcheck: Fixed a typo in the grenade primer description. + - code_imp: Added flags to circuits that help group subsets of circuits and regulate + them. + DaedalusGame: + - bugfix: fixed ghost spawners showing up in the spawner menu when you can't use + them + - bugfix: fixed walls under doors breaking to space + - tweak: changed doors to no longer spawn on top of walls + Dax Dupont: + - rscadd: Adds special tutorial holopads for the hazard course. + Jittai: + - tweak: Ctrl+Clicking progresses through grab cycle on living mobs (not just humans) + Joan: + - tweak: The crusher kit now includes an advanced mining scanner. + - tweak: The resonator kit now includes webbing and a small extinguisher. + - tweak: 'The minebot kit now includes a minebot passthrough kinetic accelerator + module, which will cause kinetic accelerator shots to pass through minebots. + The welding goggles have been replaced with a welding helmet, allowing you to + wear mesons and still be able to repair the minebot without eye damage. feature: + You can now install kinetic accelerator modkits on minebots. Some exceptions + may apply. Crowbar to remove modkits.' + - balance: Minebots now shoot 33% faster by default(3 seconds to 2). The minebot + cooldown upgrade still produces a fire rate of 1 second. + - balance: Minebots are now slightly less likely to sit in melee like idiots, and + are now healed for 15 instead of 10 when welded. + - balance: Sentient minebots are penalized; they cannot have armor and melee upgrades + installed, and making them sentient will override those upgrades if they were + installed. In addition, they move very slightly slower and have their kinetic + accelerator's cooldown increased by 1 second. + NTnet circuit fix: + - bugfix: Now NTnet circuits can recieve sender adress properly.Also, now messages + could be sended to multiple recepiens. + Xhuis: + - rscadd: Admins may now spawn a debug circuit printer that can always print circuits, + and has infinite metal. + - bugfix: Buttons, number pads, and text pads in integrated circuits now correctly + show their labels. + - bugfix: Integrated hypo-injectors can now correctly draw blood. + - tweak: The circuit analyzer output has been slightly tweaked and includes usage + instructions. + - rscadd: The round-end report now shows information about the first person to die + in that round. + - rscadd: Added the dish drive. This machine, the future in plate disposal, can + be researched from techwebs (Biological Processing) and built with a standard + machine frame using two matter bins, a micro manipulator, and a glass sheet. + - rscadd: A circuit board for the dish drive can be found in the chef's and bartender's + wardrobes. + - rscadd: You can hit a dish drive with any dish (like a plate or drinking glass), + and the dish drive will convert it from matter to energy, allowing it to store + an infinite amount of dishes. You can also interact with it to get things back + from it. + - rscadd: Dish drives also have an automatic "suction" function that sucks in all + loose dishes within four tiles. This can be toggled by activating its circuit + board in-hand. + - rscadd: Dish drives automatically beam their stored dishes into any disposal unit + that it can see within seven tiles every minute. You can toggle this by alt-clicking + its circuit board. + - tweak: Plastic surgery now lets you choose from a list of ten random names, so + you can pick the one that you prefer. + - tweak: Abductors performing plastic surgery can now give their target spooky subject + names, with one normal name available for standard plastique. +2018-02-21: + Denton: + - code_imp: Renamed the IDs of various reagents to be more descriptive. + - spellcheck: Fixed the descriptions of changeling adrenaling reagents. + - tweak: Changed Santa event earliest start from 33 minutes & 20 seconds to 30 minutes. + Changed shuttle loan earliest start from 6 minutes & 40 seconds to 7 minutes. + - spellcheck: Tweaked the message you see when emagging meteor shield satellites. + Kevinz000 & Deathride58: + - rscadd: A separate round time has been added to status panel. This will start + at 00:00:00. + - rscadd: Night shift lighting [if enabled in the same configuration] will activate + between station time 7:30 PM and 7:30 AM. This will dim all lights affected, + but they will still have the same range. + - rscadd: APCs now have an option to set night lighting mode on or off, regardless + of time. + Naksu: + - bugfix: Flightsuits should be controllable again +2018-02-22: + Buggy123: + - tweak: Nanotrasen has begun a campaign to inform their employees that you can + alt-click to disable morgue tray beeping. + Jittai / ChuckTheSheep: + - imageadd: NT has stopped buying re-boxed storebrand Donkpockets and now stocks + stations with real, genuine, tasty Donkpockets! + MetroidLover: + - balance: rebalanced Ninja event to allow it to happen earlier. + - bugfix: fixed Ninja welcome text to no longer tell you to right click your suit. + Naksu: + - code_imp: removed unused poisoned apple variant + Repukan: + - bugfix: fixed windoors dropping more cable than what was used to build them. + Robustin: + - bugfix: The clock cult's marauder limit now works properly, temporarily lower + the marauder limit when one has recently been summoned. + Super3222, TheMythicGhost, DaedalusGame: + - rscadd: Adds a barometer function to the standard atmos analyzer. + - imageadd: Adds a new sprite for the atmos analyzer to resemble a barometer. + kevinz000, Denton: + - rscadd: Nanotrasen's RnD division has integrated all stationary tachyon doppler + arrays into the techweb system. Record increasingly large explosions with them + and you will generate research points! + - spellcheck: Fixed a few typos in the RnD doppler array name/description. +2018-02-25: + Astral: + - rscadd: Traitor CMOs and Chemists, for 12 TC, can now get a reagent dartgun, which + is capable of synthesizing it's own syringes, but does so slowly, and can be + easily identified as syndicate by anyone who isn't blind! + Cebutris: + - tweak: Toxin loving species now properly take toxin damage from liver failiure + DaedalusGame: + - bugfix: enables the RPED to construct/replace other parts commonly used in machines + (igniters, beakers, bs crystals) + - bugfix: fixes part ratings of cells so slime cells are correctly more desirable + than bluespace cells and other such nonsense + - bugfix: shivering symptom now works properly instead of only cooling you if you're + already cold + - bugfix: fixed bodytemp going negative in a few cases + - code_imp: removes input/output plates and changes autogibbers to use input dir + - tweak: The last scientists have reported that thermonuclear blasts triggered by + so called 'power gamers' have shorted the doppler array. We've readjusted the + ALU and are confident that this will not happen again. + Denton: + - tweak: The outer airlocks of most space ruin airlocks are now cycle linked. + - tweak: The outer airlocks of various lavaland ruins and ships now cycle lock. + - bugfix: Players can no longer kill themselves by whispering inside clone pods. + - tweak: The 'neurotoxin2' toxin has been renamed to Fentanyl. + Naksu: + - admin: Admins can now start the game as extended revs, a version of revs that + doesn't end when head(rev)s are dead. Admins can also use the speedy mode, which + nukes the station after 20 minutes. + Repukan: + - rscadd: Whiskey to the flask + - rscdel: Hearty Punch from the flask + ShizCalev: + - tweak: Silicons no longer have to be adjacent to morguetrays to disable the alarms + on then. + ThePainkiller: + - tweak: Tweaked the inventory management of the black fedora to be more like the + detective's + Xhuis: + - rscadd: Added Bastion Bourbon, which you can mix with tea, creme de menthe, triple + citrus, and berry juice. When it's in your system, it will very slowly heal + you as long as you're not in critical. When it's first added to your system, + you heal an amount of each damage type equal to the volume taken in, with a + max of 10. This is turned to a max of 20 for anyone in critical. + - rscadd: Added Squirt Cider, which you can mix with water, tomato juice, and nutriment. + It's nutritious and healthy! + - tweak: Reskinning objects now shows their possible appearances in the chat box. + deathride58: + - rscadd: Lights will now actually glow in the dark! +2018-02-26: + DaedalusGame: + - balance: livers don't unfail automatically every second life cycle you have to + get a new one or get some corazone stat + - balance: increased liver damage from alcohol significantly because apparently + your liver regenerates faster than you can chug unless you drink 100 liters + of bacchus blessing + - bugfix: fixed cyber livers thinking they should fail at half durability + MMMiracles: + - rscadd: Added tinfoil hats, headgear that can help protect against government + conspiracies and extra-terrestrials. Found in hacked autolathes. + Robustin: + - bugfix: Twisted Construction will now consume ALL available plasteel in a stack. + - bugfix: Runes will no longer count the original invoker more than once. + XDTM: + - balance: Wizard spells and items can now be resisted/ignored with anti-magic items/clothing + such as null rods! + - balance: Revenant spells can now be resisted with "holy" items like null rods + and bibles. + - balance: Wizard hardsuits are now magic immune, but not holy. + - balance: Immortality Talismans now grant both spell and holy immunity. + - tweak: Inquisitor Hardsuits already granted spell and holy immunity, but now they + do it properly instead of having a null rod embedded inside. + - tweak: Holy Melons now grant holy immunity. + - tweak: Operating computers now display the chemicals required to complete a surgery + step, if there are any. + - tweak: Completing a surgery without the required chems will always result in failure, + instead of a success with no effect. + - balance: You can no longer gain the same trauma more than once. + - balance: 'You can no longer gain more than a certain amount of brain traumas per + resilience tier. (Example: You cannot gain 4 mild traumas, but you can gain + 3 mild and 1 severe)' + - tweak: Abductors' trauma gland now gives traumas of random resilience, instead + of lobotomy every time. + Xhuis: + - balance: Instead of starting unable to clone circuits at all, circuit printers + can now print circuits over time from roundstart. The formula for this is equal + to (metal cost / 150) seconds, with a maximum of 3 minutes. You can see printing + progress by using the printer's interface, and you can print normal components + during this time. + - balance: If circuit printing is disabled in the config, cloning remains unavailable. + - balance: The upgrade disk to allow circuit printers to clone circuits has been + replaced with an upgrade disk to make circuit cloning instant. + - balance: Both circuit printer upgrade disks now cost 5000 metal and glass, down + from 10000. + - code_imp: Butchering has been refactored. + - balance: Some items now take longer to butcher, and have a chance to harvest fewer + items, like spears. Others, however, are faster, like circular saws. + - balance: Certain creatures will always drop certain items on butchering, regardless + of butchering effectiveness or chances. + - balance: Items that are very effective at butchering may yield bonus loot from + butchered creatures! + - rscadd: Plain hamburgers may now spawn as steamed hams with a very low chance. +2018-02-27: + Astral: + - rscadd: blood cultists can now use a nar nar plushie as an extra invoker for runes! + Iamgoofball: + - rscadd: Look sir, free crabs! + Poojawa: + - rscadd: Tesla Corona Analyzers! Study the seemingly magic Edison's Bane for supplemental + research points! + Robustin: + - bugfix: The heart attack event will now actually make the victim acquire the heart + disease + - bugfix: Clicking the chatbox link will let you orbit the victim + - tweak: The event is now significantly more sensitive to junk food. Recent consumption + of multiple junk food items will triple your chances of having a heart attack + (exercise will still block it). + selea: + - bugfix: fixed floorbot + - bugfix: fixed cleanbot + - refactor: improved pathiding in case of given minimal distance;improved sanitation diff --git a/html/changelogs/archive/2018-03.yml b/html/changelogs/archive/2018-03.yml new file mode 100644 index 0000000000..35d3f12f20 --- /dev/null +++ b/html/changelogs/archive/2018-03.yml @@ -0,0 +1,776 @@ +2018-03-02: + AlexTheSysop: + - bugfix: C4 logging now shows correct location + Astral: + - imageadd: Space is now prettier + DaedalusGame: + - tweak: Machines can now be constructed anchored or unanchored, if the resultant + machine could be unanchored. + Dax Dupont: + - rscadd: Medals now show the commendation text in the description. + Denton: + - tweak: Cargo packs have been grouped and sorted alphabetically. Station goal crates + are now in the Engineering section. + - tweak: The cargo security section has been split into security/armory. + - tweak: Grouped all gas canisters and fuel/water tanks together in one section + with raw materials. + - spellcheck: Fixed a few cargo pack descriptions. + - tweak: Cyclelinked three airlock pairs on Boxstation (port bow solars and the + area that connects RnD with medical). + Improvedname: + - bugfix: chem implants can no longer be self triggered + Jittai / ChuckTheSheep: + - imageadd: New chemdispenser (and minidispenser) sprites. + - imageadd: New soda/beer dispenser sprites, with directional states. + Mey-Ha-Zah: + - imageadd: Heck suit sprites are prettier, with more contrast. + MoreRobustThanYou: + - bugfix: SCP-294 should no longer have overlay problems + Naksu: + - rscdel: SNPCs have been removed. + Poojawa: + - bugfix: Cyborg defib units are now actually functional + XDTM: + - tweak: Bath Salts now induce psychotic rage, but cause much more brain damage. + Xhuis: + - rscadd: Traits! You can now select up to three positive, negative, and neutral + traits in the character setup. You can choose up to six traits based on combinations + varying by the amount of points you earn with negative traits and spend with + positive ones. + - rscadd: You can now splash metal sheets with copper to make bronze sheets, which + you can make "clockwork" things out of. + YPOQ: + - bugfix: The assault pod can be launched again. + uraniummeltdown: + - rscadd: The chatbar now has OOC and Me buttons + - tweak: The chatbar font-size is smaller +2018-03-03: + Cebutris: + - bugfix: Washing a glove with a white crayon will make it look like a white glove, + instead of a latex glove. Instead, mime crayons make gloves look latex + Denton: + - bugfix: Burglar alarms in the Pubbystation library and RD office can now be disabled + properly. + - bugfix: Fixed Pubbystation's RD office shutters. + - rscadd: Added missing engineering and kitchen lockdown shutters on Pubbystation. + - rscadd: 'Pubbystation: Added privacy shutters to the CMO and RD offices. Added + space shutters to the HoS office. Replaced the RD office''s directional windows + with fulltile ones.' + - rscadd: Added a second blast door to the Pubbystation gulag shuttle lockdown. + - tweak: Due to pressure from the space OSHA, Pubbystation has installed missing + fire alarms and firelocks. + - tweak: Split the Pubbystation library into two areas with their own APCs. + Naksu: + - admin: Admins can now easily spawn cargo crates + - admin: Admins can now toggle antag, med, sci, engineering huds and maximum ghost + brightness with just one button. + Robustin: + - balance: Meth now deals 1-4 brain damage while active, up from 0.25 + Selea: + - balance: reduce CD of all non manipulative non list output circuits to 0.1 + - balance: add to locomotion circuit output ref with object, which assembly was + bumped to. + - balance: upgrade disks have multiuse. balance:iducer efficiency= efficiency/number + of inducers on 1 tile. + - balance: unnerf fuel cell.about 3-5 times.Make blood more powerful. + ShizCalev: + - rscadd: You can now hotswap tanks in a canister or gas pump by clicking it with + a new tank! + - rscadd: You can now also close a canister's valve and remove the tank inside it + by alt-clicking it. +2018-03-04: + DaedalusGame: + - balance: changed the formula of liver damage so weak alcohol does barely anything + while strong alcohol is still threatening + Iamgoofball: + - bugfix: RIP Billy, you'll be the boss of heaven's gym now :( + Jalleo: + - admin: Added a cancel button to nuke timer (and others). You no longer have to + make it 0 just a click to cancel. + - admin: You can now easily set how many "INSERT JOB ROLE HERE" you want in the + manage job selection in the admin panel. If you put zero in it will set it to + the current amount of filled positions. + - bugfix: moved a small amount of wording around in a admin browser to make it cleaner + looking. Along with a few updated checks for certain things. + Naksu: + - code_imp: First pass on cleaning up junk defines and unused code + RandomMarine: + - rscdel: The ore redemption machine no longer has 'release all' buttons. Remember + to take just what you need and leave some for the other departments. +2018-03-05: + 81Denton: + - tweak: 'Deltastation: Removed a windoor to make the northern chemistry fridge + more accessible.' + Cruix: + - rscadd: Added a new mini antagonist, the sentient disease. + DaedalusGame: + - bugfix: Fixes the auxbase camera console not placing airlocks on fans but doing + so vice-versa + Dax Dupont: + - balance: Others can now take off your tinfoil hat as seemingly originally intended. + - balance: Due to the nature of tinfoil hats, the delay of putting a tinfoil hat + on unwilling participants has been increased. + Denton: + - bugfix: 'Pubbystation: Added a missing APC to the cargo sorting room, a light + fixture to the RnD security checkpoint and removed an overlooked firelock east + of the bridge.' + - rscadd: 'Pubbystation: Added a spare RPD to the Atmospherics department. Replaced + Engineering''s outdated meson goggles with modern engineering scanners. Added + a GPS device to the secure storage crate.' + - tweak: Moved Pubbystation's drone shell dispenser from the experimentation lab + to Robotics maint. + Jittai / ChuckTheSheep: + - tweak: Adjusted the space parallax's contrast to be less vibrant. + Naksu: + - rscadd: Advanced roasting sticks, a product of applied bluespace research can + now be built from service protolathes. They can be used to cook sausages on + campfires, supermatter engines, tesla balls, singularities and a couple of other + things. + - admin: Admins can now grant spells via implants, using the spell implant. Some + VV is required. + Potato Masher: + - bugfix: The Wizard Federation has finally modified their production method for + pre-packaged magic tarot cards for better compatibility with time-stopping spells. + Guardians Spirits are no longer frozen by their user's time-stops. + SpaceManiac: + - bugfix: Night shift no longer ignores rooms whose APCs are in port or starboard + central maintenance. + - bugfix: Inserting brains into MMIs and then into mechs now works again. +2018-03-06: + MrDoomBringer: + - tweak: Advances in Rapid Delivery Technology have yielded a reduced premium on + express cargo orders! Orders from the express console now have a cost multiplier + of 1, down from 2. + MrStonedOne: + - bugfix: gas overlays once again no longer steal clicks + - rscdel: 511 clients will be unable to see gases once again. the 512 client crashes + are fixed so this shouldn't be that big of a deal. + Naksu: + - admin: Admins can now easily spawn mobs that look like objects. Googly eyes optional! + XDTM: + - rscadd: Revenants now have randomly generated names. + Xhuis: + - code_imp: Traits are now assigned in a way that should cause fewer edge cases + and strangeness. + - bugfix: Night Vision should now work. + - bugfix: Traits no longer tick while dead. + - tweak: RDS now triggers twice as often. + - tweak: You can now modify your trait setup mid-round. Your character is locked + to the traits you had selected when you spawned in, though. + selea: + - bugfix: After several months of natural selection, hostile mobs started to attack + assemblies with combat circuits. +2018-03-08: + ACCount: + - rscadd: Station airlocks now support NTNet remote control. Door remotes now use + NTNet. + - rscadd: Don't worry, any non-public airlock is fully protected from unauthorized + control attempts by NTNet PassKey system! + - rscadd: 'New integrated circuit component: card reader. Use it to read PassKeys + from ID cards.' + - bugfix: Fixes a delay issue when airlocks are being opened/closed by signalers. + Astral: + - bugfix: Lighting fixtures should no longer be visible in camera-less areas by + cameras. + - rscadd: Ghosts can now examine sentient diseases to see info + CameronWoof & MrDoomBringer: + - rscadd: Adds medical sprays, a new application method for touch chems + - rscadd: Pre-loaded medical sprays can be obtained from NanoMeds + - rscadd: Empty medical sprays can be found in boxes in chemistry and from cargo's + medical crate + - tweak: Sterilizer spray has been migrated to be a medspray instead of being a + spray bottle + Cebutris: + - spellcheck: lithenessk -> litheness + Cruix: + - rscadd: Sentient diseases now get two minutes to select an initial host before + being assigned a random one. + Dax Dupont: + - rscadd: Beacons can now be toggled on and off. + - rscadd: Mappers can now have beacons that default to off. Useful for ruins! + - tweak: Renaming replaces the snowflake locator frequency/code + - refactor: Beacons are no longer radios. Why were they radios in the first place? + I don't know. + - bugfix: You can now lay meters again with the RPD. + Denton: + - rscadd: Pubbystation's RnD department has been outfitted with a brand new circuitry + lab! It is found east of the Toxins launch room. + Floyd / Qustinnus (Sprites by Ausops, Some moodlets by Ike709): + - rscadd: Adds mood, which can be found by clicking on the face icon on your screen. + - rscadd: Adds various moodlets which affect your mood. Try eating your favourite + food, playing an arcade game, reading a book, or petting a doggo to increase + your moo. Also be sure to take care of your hunger on a regular basis, like + always. + - rscadd: Adds config option to disable/enable mood. + - rscadd: 'Indoor area''s now have a beauty var defined by the amount of cleanables + in them, (We can later expand this to something like rimworld, where structures + could make rooms more beautiful). These also affect mood. (Janitor now has gameplay + purpose besides slipping and removing useless decals) remove: Removes hunger + slowdown, replacing it with slowdown by being depressed' + - imageadd: Icons for mood states and depression states + MMMiracles: + - tweak: Thirteen Loko now has an overdose threshold of 60u, see your local CMO + for potential side-effects. + MrDoomBringer: + - tweak: Emagging the emergency shuttle now fries the on-board acceleration governor. + Better buckle up! + Naksu: + - balance: The nuclear authentication disk no longer treats the transit space as + a whole as being "in bounds", but instead checks whether it is in an approved + shuttle type (syndicate shuttles, escape shuttles, pubbiestation's monastery + shuttle, escape pods are allowed) + - bugfix: Blueprints can no longer be used to create areas inside shuttles. This + fixes various exploits involving shuttles and areas. + - bugfix: Moving across a space z-level border can no longer place you inside a + shuttle or a dense turf such as an asteroid. + SpaceManiac: + - bugfix: The Shift Duration in the round-end report is no longer blank in rounds + lasting between one and two hours. + kevinz000: + - rscadd: smoke machines can now be printed after researching adv biotech +2018-03-09: + Dax Dupont: + - rscadd: Display cases can now have a list where to randomly spawn items from. + - refactor: Moved plaque code to main type. + - refactor: Statues now use default unwrench and the tool interaction is now completely + non existent when no deconstruct flag is available. + Mark9013100: + - rscadd: Pill bottles can now be produced in the autolathe. + Naksu: + - balance: The white ship and miscellaneous caravan ships lose their advanced place-anywhere + shuttle movement during war ops. + - tweak: The smoke machine can now be deconstructed using a screwdriver and a crowbar + - code_imp: The smoke machine no longer calls update_icon every process() + Robustin: + - balance: Harvesters now have 40hp, from 60. + - tweak: The nuke will now detonate 2 minutes after Nar'sie is summoned, down from + 2.5 minutes + - tweak: The "ARM" ending now requires 75% of the remaining souls aboard to be sacrificed + before the nuke goes off, up from 60%. + - bugfix: Drones can no longer be on the sacrifice list + - bugfix: Bloodsense will now show the true name of the target +2018-03-10: + 81Denton: + - tweak: Added wall safes to Deltastation's HoP and Captain's offices. + Astral: + - bugfix: Constructed turbines will now properly connect to the powernet + Cobby: + - tweak: The Eminence scoffs at your "consecrated" tiles once the Justicar is freed + from his imprisonment. + Denton: + - rscadd: Engi-Vend machines now have welding goggles available. + - tweak: Grouped Nano-Med/Engi-Vend items by category. + Irafas: + - rscadd: Turrets can be set to shoot personnel without loyalty implants + Naksu: + - rscdel: The smoke machine can no longer be found in chemistry departments, instead + it must be constructed manually. The board was added to techwebs earlier. + Singularbyte: + - bugfix: Dead bodies no longer freak out about phobias + 'The Dreamweaver (Sprites: Onule)': + - rscdel: Nanotrasen's Lavaland research team has discovered that the alien brain + has disappeared from necropolis chests. + - rscadd: In it's place they have discovered a new artifact, the Rod of Asclepius, + a strange rod with a magnitude of healing properties, and an even higher magnitude + of responsibility... + XDTM: + - rscadd: You can now place people on tables on Help Intent. Doing so takes a few + seconds and makes the target Rest, instead of stunning them. + Xhuis: + - bugfix: Circuit slow-cloning no longer breaks with some circuits. + - code_imp: Circuit slow-cloning is now cleaner. + kevinz000: + - rscadd: Oh hey guys, RND shows correct material values now, don't hurt me! + ninjanomnom: + - bugfix: Blowing up the wrong part of the shuttle should no longer result in the + shuttle being permanently broken. +2018-03-11: + Buggy123: + - tweak: The Clockwork Justicar has decided to be merciful, and allow nonbelievers + to anchor their petty machines in his city. It's only fair for them to have + a fighting chance, after all. + Irafas: + - bugfix: Fixed pacifists from being able to fire mech weapons + JJRcop: + - bugfix: Sanity checks for Play Internet Sound + MrDoomBringer: + - rscadd: Orderable supplies in cargo now all have descriptions! The station's overall + FLAVORFUL_TEXT stat has gone up by nearly 2% as a result. + Onule: + - tweak: Mining drones have been given a visual makeover! + Poojawa: + - imageadd: Redded borg transformation animations + - imageadd: adjust mining borg animation to new colors. + Xhuis: + - rscadd: The Nanotrasen Meteorology Division has identified the aurora caelus in + your sector. If you are lucky, you may get a chance to witness it with your + own eyes. + ninjanomnom: + - admin: The debug message for generic shuttle errors is improved a little + - bugfix: Custom shuttles being too close to the map edge was causing problems, + you must now be at least 10 tiles away. +2018-03-12: + Naksu: + - balance: The space cleaner spray bottle is now much more efficient and uses much + less space cleaner per spray. The amount of cleaner it can hold has been adjusted + to compensate. + - bugfix: internet sounds can be stopped again + Robustin: + - bugfix: One-man conversions are actually fixed this time - excess chanters var + removed for a more readable and maintainable rune code. + - bugfix: Runes should no longer become GIANT if spammed (credit to Joan for this + fix). + - bugfix: Pylons are no longer a source of infinite rods. + - tweak: Attempting conversion without 2 cultists present will give a more helpful + warning. + - tweak: You can no longer convert braindead individuals. + - balance: Cult doors will no longer lose power but also cannot shock people, brittle + cult doors have 30 less integrity. Therefore ordinary crew can now beat cult + airlocks open without frying themselves. + - balance: Blood magic now costs slightly more blood and takes slightly more time, + the stun spell now stuns for 2 less seconds, twisted construction now costs + 10 health, and the blood rite relics (halberd, bolts, beam) are all 50-100 charges + cheaper. + - balance: The deconversion time for holy water is slightly reduced, 10 units and + 45 seconds (give or take), is all you should need now. Blood cultists can now + have seizures while afflicted with holy water. + - balance: Shades are now slower and have a modest reduction to their damage and + health. +2018-03-13: + Dennok: + - rscadd: Meters can be attached to the floor by screwdriver + Denton: + - bugfix: The disposal bin in Pubbystation's main tool storage now works. + - tweak: Deleted a duplicate r-wall between Pubby's main tool storage and the captain's + office. Added a Metastation-style crate disposals chute and a light switch. + - tweak: Various belts can now hold additional job-specific items. + - tweak: Sepia floor tiles fly really slowly, yet far when thrown. Don't hit yourself! + Naksu: + - admin: ERT creation has been refactored to allow for easier customization and + deployment via templates and settings + Polyphynx: + - tweak: Medical sprays can now be stored in medical belts and smartfridges. + The Dreamweaver: + - rscadd: Both of Nanotrasen brand totally-for-adult-use footwear, Wheely-heels, + the cool and hip new shoes with built in roller-wheels, and Kindle Kicks, the + fun and flashy light up sneakers, are now available as rare prizes at your nearest + arcade machine! + Toriate: + - rscadd: Added ammo counters for RCDs + - rscadd: Added actual flashing yellow light for RCDs + - imageadd: added new RCD sprites including inhands + - imagedel: deleted old RCD iconstate, but not the inhands + checkraisefold: + - bugfix: Nukeops properly checks the required amount of enemies for the gamemode! + This should fix downstream problems. + imsxz: + - rscdel: the viral aggressive metabolism symptom has been removed + ninjanomnom: + - bugfix: You need to actually clear an area for the aux base, remove all walls + (except rock walls). +2018-03-16: + Dax Dupont: + - tweak: 8balls take less time to shake. + Keekenox & Floyd / Qustinnus: + - imageadd: Adds a new Parallax layer that resembles Lavaland (Lava Planet), it + spawns on a random location near the station. You need your parallax on high + to see it. + Shadowlight213: + - tweak: Roundstart or latejoin sec officers will like donuts regardless of race. + cacogen: + - tweak: Transit tubes take half as long to secure/unsecure +2018-03-17: + AnturK: + - rscadd: Traitor AI's can now take manual control of turrets. + Cruix: + - bugfix: Sentient diseases will no longer lose points when a host is uninfected. + Dax Dupont: + - bugfix: Edison's ghost no longer interferes with Tesla Corona Coil research device. + Denton: + - tweak: Syndicate stormtroopers now rapid fire 10g slugs instead of buckshot. This + deals the same damage, but makes getting hit less laggy. + - rscadd: 'Pubbystation: Added protective grilles outside the circuitry lab. The + one with the big glass windows, right next to the bomb test site. Oops.' + - rscadd: 'Pubby: Added electrified grilles to the windows of the CMO/RD/CE offices, + as well as missing privacy shutters to the CE office.' + - rscadd: 'Pubby: There is now a very rare chance for a Xenomorph egg to appear + in the Xeno containment chamber at roundstart.' + - bugfix: 'Pubby: Fixed the name of the HoS space shutter button.' + - tweak: Updated a bunch of roundstart tips and added new ones. + Polyphynx: + - bugfix: Bluespace slime radio potions now work, and are no longer invisible. + RandomMarine: + - bugfix: Did you know that you could buckle guys to grounding rods? Probably not + - not that it mattered before, because people buckled to them didn't get shocked + when they got zapped. That's fixed now. + SpaceManiac: + - bugfix: Cameranet issues in OmegaStation's departures wing, crematorium, and freezer + have been corrected. + The Dreamweaver: + - bugfix: Fixes duplication issue when the Rod of Asclepius is removed while lying + down, as well as fixing a runtime when attempting to use multiple rods. + XDTM: + - rscadd: 'Changed behaviour of mech drills: now they take some time to start drilling, + then they keep drilling until manually stopped or the target is destroyed. Mobs + are still gibbed if they have more than 200 brute damage while being drilled.' + - rscadd: Drilling walls is now consistent; it takes longer, but it will always + work instead of only randomly. + - tweak: Drills no longer stun mobs, but they can dismember limbs. + - bugfix: Mech drills no longer cause explosion-like effects on mobs inside objects. + deathride58: + - bugfix: You can no longer push someone onto a table that's on the other side of + the station. + kevinz000: + - rscadd: Wet floors now get their duration decreased by 0.1 seconds per degree + above 0C the air temperature on it is, and instantly dry above 100C. Below 0C + they will freeze into ice and will not automatically dry. + - rscadd: Floors can now have different types of wet at the same time! Wet strength/type + is now a bitflag. +2018-03-18: + Davidj361: + - tweak: Made AI VOX sound files smaller sized + - bugfix: Fixed improperly pronounced AI VOX lines + - soundadd: Added a ton of new AI VOX sayings + Floyd / Qustinnus: + - rscdel: Removes short-term effects of mood add; Adds long-term effects of mood + by implementing sanity which goes up with good mood, down with bad mood, but + takes time to change. Your sanity can be seen as your average mood in the recent + past. All effects of moods are now covered by this system + - rscadd: Beauty component, currently only attached to cleanables, but you could + attach it to any atom/movable and make them pretty/ugly, affecting mood of anyone + in the room. + - refactor: Removes the original way of adding mood events, uses signals properly + instead. + - bugfix: Cleanables "giving" area's free beauty during initialization + - bugfix: Fixes some events not clearing properly + Naksu: + - bugfix: Chem dispensers now show the correct amount of units they will vend (instead + of 1/10) + - balance: Chem dispensers can now be upgraded. Manipulators increase macro granularity, + matter bins increase power efficiency, cells increase power capacity, capacitors + increase recharge rate. + - balance: Chem dispensers can now be constructed + - rscdel: mini-chemdispensers are removed. +2018-03-19: + Anonmare: + - tweak: Spaceacillin is now useful in disease control + Denton: + - rscadd: It's suicide HoPline prevention week at Omegastation! + - rscadd: Navigation beacons and a brand-new Officer Beepsky unit have been installed. + This means that crewmembers can now use medibots, janibots and other bots as + well. + - rscadd: The atmospherics department has been outfitted with all missing gases + as well as an incinerator and a hardsuit. + - rscadd: The size of the botany and xenobiology departments have been increased + in order to increase productivity. The medbay O2 port has been moved so that + doctors can access the table next to it. + - rscadd: RnD now has circuitry tools; medbay has stethoscopes+wrench+beaker/pill + bottle boxes and primary tool storage has multitools. Enginers no longer have + to share a single pair of insulated gloves either. + - rscadd: Engineers now have access to an Engi-Vend vending machine as well as missing + tools like inducers. Circuitry storage has a smoke machine board and a solars + crate in case the engine blows up. + - tweak: Blueprints have been moved from the vault safe to secure storage in order + to speed up construction projects. + - bugfix: The AI sat transit tube now works! Turret controls can now be accessed + from the outside. The first two turrets now use the proper type of gun. The + telecomms air alarm will no longer report false alarms. + - bugfix: The main hallway's firelocks now no longer all close at once. + - bugfix: 'Pubbystation: The atmos mix tank and N2 filter should now work properly.' + SailorDave: + - bugfix: Crayons and spraycans can no longer draw an unlimited amount of large + graffiti regardless of uses left. +2018-03-20: + Denton: + - bugfix: At last, the Pubbystation auxillary base can be launched again. + - code_imp: Aux base/escape pod/assault pod/elevator docking ports now default to + timid = FALSE. + Garen: + - rscadd: Added 4 new Icons to the diagnostic hud circuit status display that can + be set using the AR interface circuit. + - rscadd: now instead of seeing the yellow warning icon when a weapon is in the + circuit, the current status icon will just turn red. + Irafas: + - rscadd: Pacifists can now drill closets containing living beings + JStheguy: + - rscadd: Electronic assemblies can now have their casings colored using the new + assembly detailer, get yours at your nearest integrated circuit printer! + - rscadd: Added 2 new electronic assemblies, 2 new electronic mechanisms, and 3 + new electronic drones. + - rscadd: Added wall-mounted electronic assemblies in 3 sizes, simply slap it against + a wall to stick it up, and then anchor it in place with a wrench. + - imageadd: Added the new sprites for the new assemblies, and color-able overlays + for every assembly, to allow for the aforementioned coloring feature. + - tweak: Scanners can now scan power cells, circuitry tools, and integrated circuits, + assuming the player isn't able to use them normally. I.E. if the assembly is + closed. + - tweak: Using wrenches to anchor down assemblies now works for all assembly types + except drones, as opposed to just working for electronic machines. + - tweak: Examining an assembly now shows some text telling you what tools to use + to do what, like many other objects currently do. + Kor: + - code_imp: Jobs other than Assistant may now be assigned by admins or events as + the overflow role + - rscadd: April Fools now sets the overflow role as Clown. + Naksu: + - admin: Rhumba beat is now more than renamed GBS + - tweak: Plastic is now a valid material for lathes + - rscadd: Added two new beaker types, 120u and 180u. The 120u beaker can be printed + off the medical protolathe with just glass and plastic, the 180u requires some + mining materials and tech. + - admin: Whether to open the armory doors when spawning an ERT is now controllable + from the ERT creation window. + - tweak: Chaplain inquisitor role now spawns with one holy hand grenade instead + of a box full of them, and the belt now has actually useful stones instead of + unusable cult stones + Polyphynx: + - tweak: The piano now sounds more like a piano! + Shadowlight213: + - bugfix: Malf hacked APCs can be broken with extinguishers and toolboxes again. + TheDreamweaver: + - bugfix: Holodeck mobs that are given sentience via sentience potions are now warned + about the state of their existence. +2018-03-21: + BunnyBot5000: + - rscadd: Fringe Weaver drink - made with ethanol and sugar, it's classy (and slightly + weaker) hooch + - rscadd: Sugar Rush drink - made with sugar, lemon juice, and wine. It's got a + slight nutritional value but decreases your satiety, causing you to be unable + to consume junk food. + - rscadd: Crevice Spike drink - made with lime juice and hot sauce. A 'sobering' + drink, the Crevice Spike will reduce your drunkenness slightly but it kicks + hard going down, dealing 15 points of brute when first ingested. + MrStonedOne: + - bugfix: VOX sounds are now forcefully preloaded on clients to deal with an issue + keeping byond from loading them + cyclowns: + - tweak: Unary devices can now be analyzed using gas scanners. This means stuff + like vents, scrubbers, cryo tubes, or heaters/freezers. +2018-03-22: + Denton: + - tweak: The lavaland Syndicate base has been outfitted with a turret control panel + as well as more chemistry supplies and one (1) bar of Syndicate brand soap. + Floyd / Qustinnus: + - bugfix: Being happy no longer makes you obese. + JohnGinnane: + - refactor: Vending machines now have their own files which includes their refill + cannister. The machines themselves are unchanged + Naksu: + - bugfix: Pulled objects will now follow their puller across space transitions again + Robustin: + - bugfix: Fixed a bug that prevented the advanced blood rites (Halberd, Bolts, Beams) + from appearing when selected. + SpaceManiac: + - bugfix: Ventcrawlers in pipes now breathe from that pipe. + - bugfix: Deconstructing atmos components no longer breaks ventcrawl visuals. +2018-03-23: + Fel: + - add: Slimes can now be crossbred by feeding them a number of slime extracts of + one type. Beware, it only produces one crossbred extract! + - experiment: The number of required extracts has been lowered to 10 since the testmerge, + but this number is up for potential change depending on balance consideration + in the future. + - wip: 'Currently available crossbreeds are accomplished by feeding any slime the + required amount of the following extract colors: Grey, orange, purple, blue, + metal, yellow, dark purple, silver, cerulean, and pyrite. Their relevant effects + will be added to the wiki page for xenobiology soon(TM), and more to come in + a later addition!' + - add: Slimes can be fed extracts one at a time, but if you start mutating it, you + can feed it extracts straight from a biobag! You can also use biobags to feed + a reproductive extract monkey cubes. + - add: Slimes in the process of being crossbred will reveal what modifier they will + gain from their current modification, as well as how many more extracts are + required, to slime scanners. + - tweak: The rainbow slime clusterblorble effect will now only use reagents that + the extract will be activated from, and will try any of these reagents! As a + bonus side effect, this means it has a 1.1% chance of spawning and activating + another clusterblorble effect. + Floyd / Qustinnus: + - bugfix: progression bar now takes the delay after co_efficent in account + - code_imp: removes do_after_speed from mob base, moves it into physiology + - code_imp: makes a do_after coefficiency proc + - balance: Changes rate of sanity drain and caps it depending on mood + Frozenguy5: + - rscdel: Reverted bad airlock sounds. + Naksu: + - tweak: the amount of simultaneous monkey cube-spawned monkeys has been restricted. + - server: the cap is adjustable via the mobs subsystem + SpaceManiac: + - bugfix: The cargo conveyor switches now properly control the belts on the shuttle + again. + - bugfix: Entering a frequency like 145.7 into a radio will now work, where 1457 + was previously required. + TheMythicGhost: + - rscadd: 'New Integrated Circuit Converter Components: hsv2hex and rgb2hex for + smooth color transitions, woo!' + - imageadd: Added icons for the new component chips. + - rscadd: 'New Integrated Circuit Component: AI Vox Sound Circuit' + ninjanomnom: + - bugfix: You can no longer override shuttle areas with new or expanded areas from + elsewhere. +2018-03-24: + Davidj361: + - bugfix: Ranged guardians in scout mode no longer are able to move out of their + master when recalled. + Denton: + - spellcheck: Fixed missing capitalization for craft menu items. + - bugfix: Air alarms no longer trigger atmospherics alarms when stimulum or hyper-noblium + are present. The allowed partial pressure of pluoxium has been increased as + well. + Robustin: + - tweak: The Security Techfab can now produce basic shotgun shell types and .38 + ammo + ShizCalev: + - bugfix: Fixed a large number of missing APCs on Omegastation + - bugfix: Fixed unpowered Incinerator outlet injector on Omegastation. + - bugfix: Replaced glass window at Omegastation's incinerator with a plasma window. + - bugfix: Fixes broken atmos injectors on Omega + - bugfix: Fixes broken air outlet on Meta + - bugfix: Fixed a couple of malfunctioning atmospheric monitors across the rest + of the maps + - rscadd: New test atmos monitoring console debug verb to help alleviate future + issues. + YPOQ: + - bugfix: The imaginary friend trauma now works +2018-03-28: + Davidj361: + - bugfix: Ocular Wardens now target buckled and cuffed players/mobs, unless they + are cuffed by a slab. + - tweak: Cuck cultists can cuff already sec-cuffed targets with their slab cuff + spell. + Dax Dupont: + - bugfix: You no longer hit borgs with hats you want them to wear. + - rscadd: Viva la borg, engieborgs can now wear hats + - rscadd: Borgs can now wear more hats. + - bugfix: After a space OSHA inspection you can now reach the safe and fire extinguisher + in the omega detective office. + - bugfix: Makes it so you don't accidently trigger the fun balloon twice. + Denton: + - tweak: Pubbystation's signs to evac have been made more obvious. + - tweak: Plastic flaps are now airtight. + - spellcheck: Bluespace crystals now show their proper name during machine construction. + EvilJackCarver: + - bugfix: Edited a certain part of the disco machine's dance to only target carbon-based + (mob/living/carbon) lifeforms. pAI units will no longer spam chat with rest + notifications when in range of the disco machine. + Frozenguy5: + - tweak: The monkeycap has been increased to 64. + JohnGinnane: + - rscadd: A guillotine has been added to the game. Can be crafted. If the blade + isn't dull, will cut through human necks like a hot knife through butter. Use + a whetstone to sharpen it if it becomes dull. + MrDoomBringer: + - imageadd: All stations have been outfitted with brand new Chem Masters! They have + nicer sprites now! + - bugfix: Fixed the description of the Cargo Express Console. Cargo Drop Pod orders + aren't double-priced any more! + Naksu: + - bugfix: Chem dispensers no longer take hours to recharge + - tweak: chem dispensers also now use energy from the grid in proportion with the + amount charged + - admin: Admins now get a follow link when a revenant spawns. + - admin: Admin hotkey help is now actually correct + Pipe fixes: + - bugfix: Runtime in components_base.dm,91 what cause atmos machinery connection + problems. + - bugfix: Pipes release air in turf on Destroy(), again. + - bugfix: Pipeline now cant be annihilated by merge(src). Pipes don't lose air on + connecting more than to one pipe. + Robustin: + - code_imp: Monkey AI is now much more efficient and no longer full of terrible, + wasteful processes + - tweak: Monkeys will now move more and will only focus on nearby objects for stealing. + This should result in more natural monkey behavior instead of the monkey staring + furiously at random shit in the room for 5 minutes until it has a 50 item blacklist + of shit it will refuse to touch from then on out. + - tweak: The chance for a monkey to attack you for pulling it will now only happen + when execute the initial grab, instead of a check that happens every tick. + ShizCalev: + - tweak: Cleaned up the preferences panel a bit to be a bit more user friendly. + SpaceManiac: + - bugfix: Unwrenching and re-placing directional signs now keeps their direction, + and backings may be rotated in-hand rather than by pulling. + Tacolizard Forever: + - bugfix: phobias will no longer recognize trigger words inside of other words + XDTM: + - rscadd: Bees (and similar swarming mobs) are now able to occupy the same tile + as other bees! When doing so, their icons are offset to make them seem like + a proper swarm. + - tweak: Bees will now dodge bullets not directly aimed at them. Why are you firing + guns at bees + - bugfix: Sniper rifles will no longer oneshot mechs (although they still deal high + damage). + - bugfix: Sniper rifles no longer knock down walls they hit. + Xhuis: + - rscadd: Added the Family Heirloom trait. This makes you spawn with a special object + on your person; if you don't have it with you, you will gain a mood debuff. + - rscadd: Added the Nyctophobia trait. This makes you walk slowly in complete darkness, + and gain a mood debuff from the fear! + - rscadd: Added the Monochromacy trait, which makes you perceive (almost) the entire + world in black-and-white. + - balance: Social Anxiety's trigger frequency is now correlated to the number of + people near you. + - bugfix: Slimepeople now transfer their roundstart traits when swapping bodies. + YPOQ: + - bugfix: Machine power will now update when moving from powered to unpowered areas + and vice versa. + iskyp: + - bugfix: night vision goggles no longer overwrite thermal eyes. nvg eyes no longer + overwrite thermal goggles. + selea: + - rscadd: a* pathfinder, coordinate pathfinder(accepts not ref to some obj, but + it's abs coordinates) ,turf pointer(can give you ref to turf with given coordinates), + turf scanner(can read letters on floor and contents of turf),material scaner(can + read amounts of materials in machinery),material manipulator(to load/unload + resources) + - tweak: now you can decide, if basic pathfinder should avoid obstacles, or not.Now + demux push only desired output without unnecessary nulls,upgraded claw and local + locator. + - balance: reduced complexity cost of locomotors,abs/rel converters and basic pathfinders.Increased + complexity of throwers, + - bugfix: Fixed bugs with cryptography, obstacle ref in locomotors, release pin + in pullng claw. + - refactor: add material tranfer proc to mat containers.refactored pathfinder SS + to have separated queue for mobs and circuits to avoid spam. + - tweak: Now recycler can butcher mobs and saw tree logs. + yorii: + - tweak: Science goggles can now detect reagents in grenades. +2018-03-30: + Astatineguy12: + - bugfix: Ghosts of servants of Ratvar are no longer confined to Reebe like their + corporal counterparts. + Cruix: + - rscadd: Sentient diseases now have the "Secrete Infection" ability, which causes + anything touching the skin of the host they are currently following to become + infective, spreading their infection to anyone who touches it for the next 30 + seconds. + Davidj361: + - bugfix: Removed health cost for Twisted Construction upon casting on a wrong object + - bugfix: Fixed table crafting not properly checking the surrounding area for tools. + - code_imp: Changed /datum/personal_crafting/proc/get_surroundings(mob/user) to + return 2 lists. + Denton: + - bugfix: 'Omegastation: Added advanced magboots to secure storage so that traitors + can complete the theft objective.' + ShizCalev: + - bugfix: Silicons no longer have to be directly adjacent to a chem master to dispense + pills. + - bugfix: Fixed an exploit involving chem dispensers not actually checking if there + was enough energy to dispense the target chemicals. + - bugfix: Fixed exploit where chem dispensers always worked even if they didn't + have power... + - bugfix: Booze & soda dispensers will no longer turn into chem dispensers when + screwdrivered + - bugfix: Fixed chem dispensers showing as powered on when screwdrivered opened. + - rscadd: Added an examine indication when the maintenance panel to chem/soda/booze + dispensers is open. + neersighted: + - admin: Re-juggled delete verb permissions + robbym: + - bugfix: Fixed an error with integrated circuit tickers where they would sometimes + fail to tick. +2018-03-31: + Naksu: + - rscdel: Chameleon projectors will no longer work from inside transformations, + effects, mechas or machines. Effects that cause movement will no longer leave + sleepers in a bugged state where they can apply chems to you across distances. diff --git a/html/changelogs/archive/2018-04.yml b/html/changelogs/archive/2018-04.yml new file mode 100644 index 0000000000..c75868fd21 --- /dev/null +++ b/html/changelogs/archive/2018-04.yml @@ -0,0 +1,537 @@ +2018-04-01: + Davidj361: + - bugfix: Fixed cuffed prison shoes being taken off by dragging them into your hand. + Denton: + - balance: The singularity engine will now output enough energy to power a station + again. + - bugfix: 'Pubbystation: The bomb testing site cameras are now accessible by camera + consoles.' + - spellcheck: Bluespace polycrystals now show their name when inserted into machinery. + Kor: + - rscadd: The disco machine no longer has a fixed list of songs. It will instead + allow players to pick music from a config folder managed by the host and head + admins. + - rscadd: There is now a bartender jukebox variant of the disco machine that plays + music, but has no lights or dancing. This variant will be added the station + maps once the feature freeze is over. + Naksu: + - bugfix: Removed stray defines from maps, making roundstart atmos functional and + runtime-spam free again + robbym: + - bugfix: 'fixed by converting to absolute coordinates #36861' + - spellcheck: changed description from copypasta to correct description +2018-04-02: + Davidj361: + - bugfix: Fixed 'vox_login' for AI VOX + - tweak: Made the AI VOX airhorn quieter to 25% of its original volume + GrayRachnid: + - bugfix: Fixes some crafting tooltips not displaying tool names properly. + MrDoomBringer: + - imageadd: roundend report button now has a lil icon + Naksu: + - bugfix: Removed some edge cases where atmospherics gas lists could continue holding + active gas items that can only transfer 0 gases to neighbors by making the garbage + collection clean them up. + RandomMarine: + - bugfix: The quick equip hotkey (e) now works for drones again. +2018-04-03: + 81Denton: + - spellcheck: Nanotrasen's space entomology department is shocked to discover that + Mothpeople have surnames! + YPOQ: + - bugfix: Mannitol will now properly cure minor brain traumas + robbylm: + - bugfix: Fixes 0 value not being saved in constant memory circuits (#36860) +2018-04-04: + Fludd12: + - rscadd: Burning ores now yields materials at a very reduced ratio! Lavaland roles + will now be able to construct things with enough effort. + JohnGinnane: + - bugfix: Fixed items sometimes being used on fullpacks when trying to insert + - bugfix: Fixed spray containers being used on open lockers and other containers + Naksu: + - bugfix: Fixed (dead) revenants being unable to deadchat or ahelp + - bugfix: Plasmamen that get converted into humans as a part of spawning as a protected + head role no longer retain their plasmaman equipment. + SailorDave: + - bugfix: Fixes virology Asphyxiation symptom activating too early and ignoring + transmission level. + ninjanomnom: + - bugfix: Shuttles have proper baseturfs now. + - bugfix: Mineral walls properly use their baseturfs when destroyed/drilled. + - rscadd: A new engineering goggle mode allows you to see the shuttle area you're + standing in. + - admin: Buildmode works a bit better with baseturfs now and can properly only remove + the top layer of turfs when editing. Note that as a result the order you place + turfs is important and a wall placed on space means when the wall is removed + there will be space underneath. +2018-04-07: + Davidj361: + - tweak: Stacked sheets now have a cancel button when taking an amount from them. + Dax Dupont: + - bugfix: Fixes dead chat announcements not using real name. + Naksu: + - bugfix: Trash bin anchoring/unanchoring now gives you a small text blip about + what happened. + PKPenguin321: + - bugfix: Restored accidentally cut functionality to flashes. You can once again + attach them to a signaller and signal them to trigger an AoE flash remotely. + SailorDave: + - bugfix: Mixed blood samples preserve their cloneability for podpeople if the samples + are the same. + kevinz000: + - rscadd: AIs can now latejoin! + - rscadd: Latejoining AIs will be sent to a special deactivated AI core. This AI + core will spawn in the AI satellite chamber in place of an active AI if none + is there at roundstart. These cores can be deactivated with a multitool, and + moved around per usual, but not deconstructed. They can, however, be destroyed + per usual. + - rscadd: AIs can only latejoin if atleast one of these cores exists and is in a + valid area (Powered, on station, etc etc), and if the AI job slot isn't filled + already by a roundstart or latejoin AI. + - code_imp: A few code internal debugging features have been added to help debug + GC errors. QDEL_HINT_IFFAIL_FINDREFERENCE hint will make the garbage subsystem + find references if the build is in TESTING mode, and qdel_and_then_find_ref_if_fail(datum) + or calling qdel_then_if_fail_find_references will do the same. + robbym: + - bugfix: Fixes examiner circuit failing to pulse 'not scanned' when reference is + null (#36881) +2018-04-08: + AnturK: + - tweak: Slime reflexes restored. + Dax Dupont: + - rscadd: Hugbox version of the VR sleeper you can't emag. + - admin: There's now two categorized vr landmarks for two teams for easy spawning. + You can also now rebuild/refresh all the VR spawnpoints by calling build_spawnpoints(1) + on any sleeper. + Naksu: + - admin: Admins can now access a new control panel for borgs via a new admin verb +2018-04-09: + CosmicScientist: + - rscadd: Top Nanotrasen scientists have diagnosed two new phobias! Birds and chasms! + Good luck Chief Engineers and Miners. + Dax Dupont: + - admin: Removing notes now has an "Are you sure" dialog. + Denton: + - rscadd: Omegastation now has its own arrivals shuttle. + Mickyan: + - imageadd: Stinger, Grasshopper, Quadruple Sec, and Quintuple Sec have new sprites. + Naksu: + - code_imp: Fixed an heirloom trait-related runtime + - code_imp: Fixed an incorrect signature in MakeSlippery causing runtimes + SpironoZeppeli: + - rscadd: You can now wrench the supermatter shard + ninjanomnom: + - bugfix: The arena shuttle should be working again. + - bugfix: The escape pods now reach their proper destination at round end +2018-04-11: + Davidj361: + - bugfix: Fixed paper bins dropping out of your hand or bag when grabbing a pen + or paper. + - bugfix: Paper bins not giving finger prints upon interaction. + - bugfix: Detective can now write notes onto his printed scanner reports. + - tweak: Detective scanner can have its logs erased via alt-click. + - tweak: Detective scanner can display logs via the action button. + Denton: + - bugfix: Added a missing intercom to the Delta arrivals shuttle. + ExcessiveUseOfCobblestone: + - code_imp: Uplink Items now have 2 separate probabilities. One for the syndicate + crate and one for cargo null crates. I encourage you to view uplink_items.dm + and make changes. + Robustin: + - balance: Hostile mobs capable of smashing structures will now smash their way + through dense objects too. + SpaceManiac: + - bugfix: The blindness overlay applied during cloning now properly stretches for + widescreen views. + - code_imp: Various macro consistency problems have been addressed. + YPOQ: + - bugfix: Eminences can hear clock cult chat again + george99g: + - bugfix: Suiciding will now deactivate all your genetics prescans. + iskyp: + - bugfix: makes dragnet non harmful + - tweak: pacifists can now use any disabler or stun setting on any energy gun + - code_imp: removed all of the pacifism check code from code/modules/mob/living/living.dm + - code_imp: gun objects no longer have a harmful variable, instead, ammo_casing + objects now have a harmful variable, which is by default set to TRUE + - code_imp: if a pacifist fires a gun, it checks whether or not the round chambered + is lethal, instead of whether or not the gun itself is lethal. + - code_imp: /obj/item/machinery/power/supermatter_shard is now /obj/item/machinery/power/supermatter_crystal/shard. + the crystal is the parent object. + neersighted: + - code_imp: Reduced lag by speeding up logs 10000% + - code_imp: Logs now include millisecond-level timestamps + pigeonsk: + - tweak: AI now requires silicon playtime instead of crew playtime for roundstart + role + selea: + - bugfix: fixed runtime in logic circuits, which was occured with invalid input + types. +2018-04-12: + Cobby: + - bugfix: Fixes getting "emptystacks" (a stack with an amount of 0) + Dax Dupont: + - bugfix: Briefcase bluespace launch pads no longer work on the centcom Z level. + Dennok: + - rscadd: RPD can automaticaly wrench printed pipes to floor. + Denton: + - rscadd: Cargo can now order tesla coil crates for 2500 credits. + Garen: + - bugfix: Added missing parameter types to circuits. + - bugfix: Fixes two datatypes appearing for some input circuits. + - tweak: Logic circuits now output booleans rather than 1's and 0's, this is purely + cosmetic. + Naksu: + - bugfix: Warp whistle can no longer leave you stuck in an invisible state + The Dreamweaver: + - bugfix: The air around you grows cooler, as if what you once knew about atmospherics + has changed ever so slightly... + Xhuis: + - bugfix: Mood traits cannot be chosen if mood is disabled in the config. + ninjanomnom: + - rscadd: The SM has a guaranteed 30 second final countdown before delamination + now + - balance: The SM will take less damage from low pressure environments + - balance: The SM has a slightly reduced max damage per tick + - bugfix: Tiles placed on lavaland turfs should behave properly again. + pigeonsk: + - bugfix: When you wash your bloody hands they will no longer still look bloody + afterwards +2018-04-13: + Dax Dupont: + - bugfix: SCP 194 now uses it's amount variable instead of a hardcoded number. + Dax Dupont & Naksu: + - bugfix: Toxin loving species won't take liver damage from toxins. + - bugfix: Liver now gets 0.01 damage per unit of toxin subtype reagent every 2 seconds + instead of 0.5. IE 30 units of whatever won't kill you within 10 seconds anymore. + - bugfix: Moved peacekeeper borg reagents to other_reagents so they don't do liver + damage and they aren't really toxins + - refactor: Renamed borg synthpax path to be more inline and put them next to the + other borg reagents. + Denton: + - tweak: Omegastation's supermatter crystal has been replaced with a smaller shard + that doesn't destroy the whole station on explosion. + Naksu: + - bugfix: Fixed KA upgrade applying on the minerborg + Putnam: + - tweak: rounded pi correctly + ninjanomnom: + - bugfix: Some strange baseturfs in lavaland structures and ruins should be fixed. + robbym: + - bugfix: Fixes tile analyzer circuit + - refactor: Cleaned up tile analyzer code +2018-04-14: + JohnGinnane: + - rscadd: PDA messages you send are now displayed in the chat for your confirmation + Naksu: + - bugfix: SCP-294 can no longer be deconstructed. + kevinz000: + - rscadd: After a severe security breach occurred due to lazily configured Nanotrasen + Network DHCP servers where attackers were able to hijack every airlock connected + to the Nanotrasen Intranet, the Central Command engineering team reports that + they have properly configured network address servers to give out (relatively) + secure network IDs again. [NTNet addresses reverted to 16-hex format. they will + now be randomized across a ~billion trillion possibilities instead of being + 1-1000 every round for doors and stuff.] +2018-04-15: + JohnGinnane: + - tweak: Reorganised circuit component controls within an assembly, so they appear + before the name of the component + Naksu: + - bugfix: Bluespace slime cookies can no longer be used to travel to CentCom + - bugfix: Borgs can no longer accidentally end up inside a cryo cell + - bugfix: Shoving someone inside a cryo cell now has a small delay unless they are + knocked down, stunned, sleeping or unconscious + - admin: Station borgs can no longer control the CentCom ferry. + - bugfix: Ghosts can no longer interact with the round via teleporter effects of + any kind + - tweak: His Grace can no longer be deep-fried + - bugfix: Passive gates can be interacted with in unpowered areas +2018-04-16: + Dax Dupont: + - rscadd: Added get current logs button for admins + - refactor: Removed verbs that have been replaced by other things like the combohud + or ticket panel. + Naksu: + - tweak: Mining borgs and mining drones now have mesons and the engineering goggles' + meson mode also works in lavaland again. + SpaceManiac: + - bugfix: The on-body icon for ancient bio suits is no longer broken. + ninjanomnom: + - bugfix: The aux base properly loads in rather than leaving an empty room. + - bugfix: Admin loaded map templates can be designated as shuttles during the upload + process. Make sure to load them on space first. +2018-04-17: + Dax Dupont: + - bugfix: Fixed martial arts/spell granters breaking on interrupt in final stage. + Naksu: + - balance: Welding tools now flash the user as the weld progresses, not just when + the welding is started. + - bugfix: CentCom officials will now properly display the objectives the admin has + assigned them. +2018-04-20: + Astatineguy12: + - bugfix: Gygax construction now actually uses up the capacitor + Dax Dupont: + - bugfix: A cat is fine too. You can select cat parts again! + - bugfix: Default lizard tail was never properly defaulted, now it is. + - bugfix: Fixes an exploit where tendrils/other spawners/anchored mobs in general + could be buckled to things and thus moved around. + Denton: + - rscadd: Due to space OSHA lobbying, the Syndicate's lavaland base now contains + a radsuit and decontamination shower. + - bugfix: Suit storage units' suit/helmet compartments now accept non-spacesuit + clothing (radsuits, EOD suits, firesuits and so on). + Naksu: + - bugfix: Oingo-boingo punch-face and meteor shot can no longer move gateways or + Reebe servant blocker effects + - bugfix: Mechas piloted by servants of Ratvar now teleport to the servant side + of Reebe when entering a rift + - admin: Gravity generators can now be thrown in buildmode + ShizCalev: + - bugfix: Fixed a number of conveyor belts leading to the incorrect direction. + - bugfix: Fixed shuttle conveyor belts being out of sync with cargo's conveyors + on some maps. + SpaceManiac: + - bugfix: Cycle-linking is no longer permanently disabled for airlocks on shuttles. +2018-04-21: + SailorDave: + - rscadd: A new manipulation circuit, the Seed Extractor. Extracts seeds from produce, + and outputs a list of the extracted seeds. + - rscadd: 'A new list circuit, the List Filter. Searches through a list for anything + matching the desired element and outputs two lists: one containing just the + matches, and the other with matches filtered out.' + - rscadd: A new list circuit, the Set circuit. Removes duplicate entries from a + list. + - tweak: The Plant Manipulation circuit can now plant seeds, and outputs a list + of harvested plants. + - tweak: Reagent circuits can now irrigate connected hydroponic trays and inject + blood samples into Replica pods. + - tweak: The Examiner circuit can now output worn items and other examined details + of carbon and silicon mobs into the description pin, as well as the occupied + turf of the scanned object, and can now scan turfs. + - tweak: The locomotion circuit now allows drones to move at base human speed, but + cannot be stacked, and assemblies can now open doors they have access to like + bots by bumping into them. + - bugfix: List Advanced Locator circuit now accepts refs as well as strings. + - bugfix: Fixed the Power Transmitter circuit not properly displaying a message + when activated. + - bugfix: Medical Analyzer circuit can now properly scan non-human mobs. +2018-04-23: + Dax Dupont: + - rscadd: More stations have been outfitted with disk compartmentalizers. + - bugfix: Fixed a lack of feedback when entering too many points for the gulag. + - admin: Fuel tank logging now logs to both game and attack logs so it's more clear + from logs what caused the explosion in game log and added coords to the messages + as well. + - bugfix: Fixes toolbelts being able to hold everything. + Denton: + - tweak: Moved Deltastation's ORM so that all crew can access it. + - code_imp: Added multilayer subtypes for mapping. + Kor: + - rscadd: Changelings can now have an objective to have more genomes than any other + changeling, rather than a set target. + - rscadd: Changelings can now have an objective to absorb another changeling. + - rscadd: Changelings now get bonus genetic points for buying powers when they absorb + another changeling. Their chem storage cap will also be increased. + - rscadd: Changelings absorbed by other changelings will lose all their powers, + chems, and genetic points, making them unable to revive. + Naksu: + - code_imp: Performance tweaks to plant code + - bugfix: Spears, nullrods etc should no longer be invisible + Power Control Support: + - bugfix: What do you mean we accidentally routed the interaction back to the apc + control conso- oh for fleeps sake STEVE WHAT DID YOU DO!! + Rinoka: + - bugfix: phobias now actually make you fear things other than an apostrophe s. + Spoilsport: + - rscdel: Inducers and integrated circuits can no longer charge energised weapons. + iksyp: + - rscadd: the beer and soda dispenser now have their own circuitboards, as well + as design ids. you can unlock them through techwebs under the biotech node. + - bugfix: beer and soda dispensers can no longer be turned into chem dispensers + by deconstructing and reconstructing them. +2018-04-24: + Dax Dupont: + - bugfix: Cargo scanner is no longer invisible. +2018-04-25: + Barhandar: + - bugfix: Pubbystation's field generators have been offset to no longer bisect the + engine on roundstart setup. + Dax Dupont: + - rscadd: You can now research and construct radiation collectors. + - bugfix: Doors don't turn into Mike Pence when the shock wire is pulsed, only why + it's cut. + - admin: Logging and messaging for singularities now include the area and a jump + link to the location where it happened. + - admin: Improved messaging for blood contracts. + - admin: While the onus is on the admin, the ckey has been added to some of the + prompts so mistakes can be caught earlier in the middle of the process. + Denton: + - tweak: 'Nanotrasen''s materials science division reports: Coins and diamonds DO + blend!' + Mickyan: + - tweak: Potato Chips and Beef Jerky from food vendors now contain salt. + deathride58: + - bugfix: Stocks in the stock market no longer have spontaneous exponential spikes. +2018-04-27: + Dax Dupont: + - balance: Experimentor now only outputs one clone. + - bugfix: Above change also fixes **an exploit** with loaded items getting cloned + after changing the loaded item and ejecting. + - bugfix: RPEDs will no longer display machine contents twice. + - bugfix: RPED can no longer hold everything. + - refactor: Moves all the logic for exchanging parts into the RPEDs instead of having + checks in every attack_by. + - rscadd: Clogged vents now scale like meteors. + - balance: Clogged vents got nerfed. + - bugfix: Buildmode toggle now checks for permissions so the hotkey can't bypass + it. + - admin: Press F10 for dsay prompt. + - admin: PDA explosions now have logging. + Denton: + - spellcheck: Fixed object descriptions and added missing ones - mostly to robotics + and RnD. + Fox McCloud: + - tweak: Removed acid requirement from basic network card and basic data disk + - tweak: grinding circuitboards no longer generates acid + Kor: + - rscadd: Added the Bureaucratic Error event, which replaces the overflow role with + a random job. + Mickyan: + - rscadd: 'New negative trait: Acute Blood Deficiency. Keep your slowly decreasing + blood level in check if you want to survive.' + MrDoomBringer: + - rscadd: Analyzers now show temperature in Kelvin as well as Celsuis + Naksu: + - code_imp: Inbounds subsystem, STATIONLOVING_2 and INFORM_ADMINS_ON_RELOCATE_2 + flags are removed. + - code_imp: New stationloving component replaces all of this. + - code_imp: 'Added new signals: COMSIG_MOVABLE_Z_CHANGED is now sent when a movable + changes Z level, COMSIG_PARENT_PREQDELETED is sent before the object''s Destroy() + is called and allows interrupting the deletion, COMSIG_ITEM_IMBUE_SOUL is sent + when a wizard attempts to make a thing their phylactery' + - bugfix: slime pressurization potions are no longer consumed when attempting to + apply them on already-spaceproof clothing + ShizCalev: + - bugfix: Fixed AI units being able to manually fire unpowered/broken turrets. + - bugfix: Fixed traitor AIs being unable to place a robotics factory if they failed + to place it after the prompt. + - bugfix: Fixed mobs having no hands if they had prosthetic limbs + - bugfix: Fixed damage overlays disappearing from prosthetic limbs when a mob is + husked + - bugfix: Fixed ghosts not being able to see into bags + - bugfix: Fixed a number of chapel and morgue doors being high-security CENTCOM + variants. This was also triggering certain phobias. + - bugfix: Fixed the warning message for chameleon projectors when a mob is inside + a closet + - tweak: Improved the formatting of the round-end report for AI and robotic units + - spellcheck: Added a period to the end of point-at messages. + - bugfix: Fixed ghosts getting spammed by sounds when clicking on a jukebox. + - bugfix: Fixed a duplicate docking port on the aux base template which was causing + some errors + - bugfix: Fixed Gr3y.T1d3 virus bolting open the doors to the SM, causing delamination. + - bugfix: Fixed the cat butcher dropping incorrectly colored tails + - bugfix: Fixed being unable to add a cat tail to someone through surgery. + - bugfix: Fixed mass purrbation & the anime event failing to give people ears and + tails in some cases. + - bugfix: Fixed AI units being able to toggle turrets on and off when AI control + is disabled. + - bugfix: While it slight increases the cost of production, vanilla ice cream is + now actually made with real vanilla! + - bugfix: Fixed AI units being able to see lights through static. + - bugfix: Fixed securitron pathfinding icons being broken. + imsxz: + - bugfix: invulnerability exploit involving stable adamantine extract fixed + ninjanomnom: + - admin: You can now use alt click in advanced buildmode to to copy the targeted + object for placement with left click. + - rscadd: You can now see objects and turfs past the map edge borders. + - bugfix: Shuttles getting removed would occasionally causes issues. This has been + fixed. +2018-04-28: + MMMiracles: + - rscadd: A jukebox can now be found in the bar of your respective station. Contact + Central about song suggestions to be added to the curated list! + Naksu: + - code_imp: clothing-specific flags are now defined in /obj/item/clothing.clothing_flags + PKPenguin321: + - balance: The changeling "Spiders" power now requires absorptions gained through + the actual Absorb ability, rather than DNA from DNA sting. To compensate, it + now only requires 3 absorptions, down from 5. + ShizCalev: + - bugfix: Fixed a good number of missing icons. + as334: + - rscadd: Fusion is back + - rscadd: Fusion now happens with large quantities of hot plasma and CO2, consuming + all the plasma rapidly and producing large amounts of energy. Other gases can + also effect the performance of the reaction. + - rscadd: Fusion now produces radiation. Be careful around reactors. + - bugfix: fixes fusion dividing by zero and destroying everything + - code_imp: Gas reactions now have access to where they are occurring + - bugfix: Prevents some other reactions from producing matter from nothing + kevinz000: + - rscadd: Circuit ntnet components buffed. Added a new low level ntnet component + that can send custom data instead of just the two plaintext and one passkey + format, which things will use by default. Ntnet now uses a list for their data + instead of three variables. they also have lowered complexity for the now weakened + normal network component, and has lower cooldowns. + pigeonsk: + - bugfix: The faint echoes of maracas grows louder, as if a past spirit once forgotten + has come back with a vengeance... +2018-04-29: + Naksu: + - bugfix: Wearing a bucket no longer connects your head to the vacuum of space + oranges: + - rscdel: Pet collars can no longer be equipped on humans +2018-04-30: + Dax Dupont: + - balance: Adds a cooldown to PDA send to all messages. + - bugfix: Last sent message cooldown actually works now. + - tweak: More reagents in the clogged vents event. + Denton: + - rscadd: Added more holoprojectors to techwebs (security, engineering and atmos). + Erwgd: + - rscadd: Limb growers can now create limbs for flypeople and mothmen. + Evsey9: + - balance: Integrated Circuit weapon mechanisms now work only when outside of any + containers and hands, due to reports of severe injury caused by activating them + while still holding them. + Garen: + - imageadd: added inhands for teleprods. + JJRcop: + - bugfix: Integrated circuits can no longer throw themselves. + Jalleo: + - bugfix: a certain exploit that can occur in regards to creating certain items + in a particular manner + - tweak: readds emitter field generator and rad collector wrenching times. Someone + override it when adding the wrench_act. + Mickyan: + - tweak: You can now see how well fed you are by self-inspecting. + Naksu: + - code_imp: More flags have been moved to their appropriate places + - code_imp: HEALS_EARS_2 is removed in favor of the earhealing component + - code_imp: wearertargeting component is available to subtype for components that + want to target the wearer of an item rather than the item itself + ShizCalev: + - bugfix: Glass stacks will now properly delete when exploded. + - bugfix: Fixed attacking someone with a bikehorn not triggering the correct mood + event. + YakumoChen: + - tweak: Nanotrasen has once again shipped BZ to its nearby stations. Check your + local Xenobiology lab for your shipment. + - tweak: Nanotrasen would like to remind you that BZ is meant for keeping slimes + from moving or getting hungry. It is not for human use and may lead to hallucinations. + Always practice workplace safety when handling dangerous gasses! + george99g: + - bugfix: Committing suicide will now stop you from being cloned via prescans. + iksyp: + - tweak: pacifists can now use .50BMG Soporific Rounds + ninjanomnom: + - bugfix: Caravan ambush shuttles have been templated to fit the new system and + can fly again. + pigeonsk: + - bugfix: Large stacks of plastitanium now display properly + - rscadd: You can now get traditional sake and get a first-hand taste of a superior + culture. Have I told you about my katana and my trip to- diff --git a/html/changelogs/archive/2018-05.yml b/html/changelogs/archive/2018-05.yml new file mode 100644 index 0000000000..a3f5729b9d --- /dev/null +++ b/html/changelogs/archive/2018-05.yml @@ -0,0 +1,570 @@ +2018-05-01: + BuffEngineering: + - bugfix: Nanotrasen has graciously connected the port bow solar's SMES to the main + grid. + Denton: + - rscadd: You can now craft and disassemble HUDsunglasses! Check out the clothing + section of the crafting menu. + - tweak: Cargo packs have been reorganized to shrink the big engineering, food&livestock + and misc categories. + NewSta: + - rscadd: 'Added 5 new drinks: Alexander, Between the Sheets, Kamikaze, Mojito and + Sidecar.' + - rscadd: Added Menthol and Sake to the drink dispensers. + Ordonis, Denton: + - rscadd: OH YEAH BROTHER! The H.O.G.A.N. AI module has a chance to spawn at the + AI upload. + SpaceManiac: + - bugfix: The button in the mech interface to terminate maintenace protocol no longer + reads "Initiate maintenace protocol". + - bugfix: Boxes now fit inside storage implants again. + XDTM: + - balance: Small, constant ticks of brain damage are now less likely to cause traumas. + deathride58: + - bugfix: Fixed the intergalactic stock market crash. The speculation/performance + modifier has been removed completely. +2018-05-04: + Cobby (Stolen from GrayRachnid): + - tweak: The processor has now been generalized techweb-wise into the "food/slime + processor". + - rscadd: The processor can now be made by Science. + Dax Dupont: + - balance: After successful lobbying by the Space Ancap Federation ammo is no longer + free. Material redemption cost is now determined by the amount of bullets left. + - balance: .38 ammo is now cheaper to produce. + - balance: Casings now give a little bit of metal. mostly for immersion sake. + Denton: + - bugfix: Runtimestation's RnD machinery is now up to date. + Fox McCloud: + - bugfix: Fixes recycler not recycling bluespace and plastic objects + - bugfix: Fixes objects with material components always showing their materials + on examine + Garen: + - bugfix: Removes unintentional pins from the constant circuit. + Hyacinth: + - rscadd: Grenadine is now available in the bar! + - tweak: Tequila sunrises now require grenadine to make! + Mickyan: + - bugfix: Our suppliers assure us that Midori Tabako cigarettes will actually contain + tobacco from now on. + Naksu: + - code_imp: APC code is slightly less shit. + - tweak: APC cells can be removed with a crowbar + Onule!: + - rscadd: Plasmaman liver and stomach crystals! + Poetic_Iron: + - spellcheck: Fixed 'Tequila Sunrise' naming from 'tequila Sunrise'. + SpaceManiac: + - code_imp: The commit hashes shown in Show Server Revision are now long enough + to autolink when copied into issue reports. + Spellbooks Take 2: + - imageadd: Magical Spellbooks are now animated. + Tlaltecuhtli: + - tweak: medbeams heal tox and oxy slighty + pigeonsk: + - rscdel: After an internal audit and review Nanotrasen has decided that stock financing + at the station-level makes no logistical nor managerial sense. Stations, and + their cargo departments, may no longer play the stock market. +2018-05-06: + Dax Dupont: + - bugfix: Rhumba beat now stops processing while dead. + Denton: + - bugfix: The Donksoft vendor board got lost during the techwebs transition and + has been re-added under the illegal technology node. + Garen: + - tweak: Grilles must take damage to produce tesla shocks. + Naksu: + - bugfix: APCs are closed with crowbars properly again. Screwdrivers can now be + used by borgs to pop out the cell instead of crowbars + SpaceManiac: + - bugfix: The top-left menus (icon scaling, ghost preferences, etc.) now work again. + Xhuis: + - tweak: Character traits are now called character quirks. Functionality remains + unaffected. + deathride58: + - rscadd: If the nuke disk stays still for long enough, the lone operative event + will enter the random event rotation. The longer the nuke disk stays still, + the more likely the lone operative event will trigger. +2018-05-08: + cacogen and nicbn: + - tweak: You can now select RPD modes individually. + - tweak: RPD autowrenching is now a tgui action rather than an Alt Click option. + deathride58: + - rscadd: Added ambient occlusion. You can toggle this on or off in the game preferences + menu. +2018-05-09: + Firecage & Bluespace: + - balance: Replaces the Roman Shield and Roman helmets in the Autodrobe with fake + versions with neither block chance nor armour values. + PKPenguin321: + - rscadd: There are now two new variants of the concatenator integrated circuit. + Small, which only takes 4 inputs, and large, which takes 16. Small uses 50% + less complexity, large uses 50% more. + - rscadd: There's a new string length circuit, which simply returns the length of + a given string. + - rscadd: There's a new indexer circuit, which takes a string and an index and returns + the character found at the index of the given string. + - tweak: The find text integrated circuit now has two new pulse outs, one that runs + when it finds the text and one that runs when it does not. + - tweak: Leaving the delimiter in the explode text circuit null will now return + all of the input string's characters in a list. +2018-05-10: + Dax Dupont: + - bugfix: The singularity spawned by the arcade orion tale meme will disappear as + intended. + Kor: + - rscadd: Science may now research reactive armour shells, which create different + armours when combined with different anomaly cores. They are constructable from + the Research and Engineering lathes. + Ordo: + - rscadd: Adds a french beret to the mime. Steal it from him to learn French! Sort + of. HONH HONH HONH. + SpaceManiac: + - refactor: Large groups of PNG assets are now transmitted in spritesheets, greatly + improving load times. + - tweak: The access denied message when entering a mech now distinguishes between + DNA lock and ID requirements. + - bugfix: Removing an ID card from a wallet now properly removes its visual and + accesses. + Tlaltecuhtli: + - bugfix: the default bulldog shotgun ammo makes sense now + - bugfix: fixes a possible money exploit + YPOQ: + - bugfix: Anomalies can be disabled with signalers again +2018-05-13: + Alexch2: + - bugfix: Large crates no longer behave like lockers. They no longer open into invisible + sprites when damaged, interacted with, when "toggle open" is used, or when non-crowbar + items are used on them. + Ausops and Qbopper: + - rscadd: Added security jumpskirts - snag one from a security wardrobe locker. + Cobby: + - bugfix: Beds will now properly save you from floor is lava, but only if you buckle + to them + Cyberboss: + - tweak: You may now take unlimited neutral and negative quirks + Denton: + - bugfix: Runtimestation's RTGs are now connected to the powernet. + - code_imp: Added chem_dispenser/fullupgrade as well as chem_synthesizer for testing. + - tweak: Replaced runtimestation's two chem dispensers with those subtypes. + - spellcheck: Did you know that you can use a screwdriver on the ChemMaster board? + Now you do. + Frozenguy5: + - tweak: You can now make plasma reinforced glass at the ORM. + - tweak: Titanium glass is now worth 0.5 titanium + 1 glass. Plastitanium glass + is now worth 0.5 titanium + 0.5 plasma + 1 glass. Therefore these glass sheets + are cheaper to make. + Iamgoofball: + - bugfix: Family Heirlooms now properly show you where they are stored if they spawn + in a bag. + Mickyan: + - tweak: Gauze can be deconstructed into cloth using wirecutters. + Naksu: + - rscdel: Fusion has been removed for pressing ceremonial reasons, and also because + it crashes the server + Tlaltecuhtli: + - bugfix: 50% of the corgis bought are now male + XDTM: + - tweak: Teleporters linked to other teleporters now teleport into the other teleporter's + hub, instead of the power station. + - bugfix: Teleporters now no longer consume power if teleportation fails. + YPOQ: + - bugfix: Fixed items stacks sometimes having the wrong amount if created on another + stack + - bugfix: Constructing light tiles no longer uses two sheets of metal + - bugfix: Gorillas have hands slots again + - bugfix: The paddle/nozzles of defibs, backpack water tanks, and gatling lasers + work again + - bugfix: You can honk people with bike horns again +2018-05-14: + Barhandar: + - rscadd: Amount of goliath plates is now shown in examine for explorer suits and + mining hardsuits. + Dax Dupont: + - rscadd: You can now swap disks in the plant manipulator. + JStheguy: + - imageadd: Vending machines now have more complex shading and are rigged with next-gen + flickering technology, a couple have either a partial or complete facelift. + Maintenance panel overlays have been fixed on machines where they were seemingly + left unchanged when the switch to 3/4ths was made. + - imageadd: Burger buns are bigger and more detailed. + - imageadd: Donuts have been totally redrawn. + SpaceManiac: + - admin: Admin-healing someone will now rejuvenate their mood as well. +2018-05-15: + Dax Dupont: + - bugfix: Fixes missing curator hud icon. + Denton: + - tweak: Engi-Vend machines now contain fire alarm and firelock electronics! + - code_imp: Loose tech storage circuit boards have been replaced with spawners. + - rscadd: APC/air alarm/airlock/fire alarm/firelock electronics are now available + once Industrial Engineering is researched.. +2018-05-16: + Dax Dupont: + - balance: Cult items will no longer be a long ride on the vomit coaster if picked + up by a non cultist. +2018-05-17: + Dax Dupont: + - balance: Cult space bases are kill again. + - balance: Cult floors now pass gas. + - bugfix: Fixed a few things deconning into the wrong circuit. + - bugfix: You can no longer do infinite bioware surgery. + - rscadd: Added the MURDERDOME VR player versus player combat arena, filled with + the most powerful weapons Centcom could think of to murder each other peacefully. + Contact your nearest vendors for VR sleepers. + - tweak: VR landmarks now accept outfits. + - tweak: VR Sleepers can now be constructed and researched. + - tweak: VR Sleepers now respond to mouse drops like sleepers! + - bugfix: VR sleepers no longer close or open inappropriately. + Denton: + - code_imp: Added /syndicate subtypes for air alarms and APCs. + - bugfix: Added missing stock parts to the syndicate lavaland base. + - tweak: Added kitchen related circuit boards to the syndie lavaland base. + Dimmadunk: + - rscadd: 'There''s a new type of reagent added to the booze dispenser: Fernet. + With it you can make a couple of new digestif drinks that will help you reduce + excess fat!' + Garen: + - rscadd: Thrower and Gun circuits put messages in chat when they're used. + - tweak: Only the gun assembly can throw/shoot while in hand + - imageadd: Adds inhands for the gun assembly + - bugfix: grabber inventories update when a thrower takes from them + Pubby: + - tweak: PubbyStation has been updated. You can now be the lawyer. + ShizCalev: + - bugfix: Adminorazine will no longer kill ash lizards. + - bugfix: Adminorazine will no longer remove quirks. + iskyp: + - tweak: the walls on the crashed abductor ship ruin in lavaland can now be broken + down +2018-05-18: + GrayRachnid: + - rscadd: The Spider Clan proudly announces that they've taken steps to improve + their hospitality at their capture center! They now hope that captured targets + would not kill them self or fight between each other, dirtying the floor with + blood. + - rscadd: They've also added a VR room for those sick of the real world, taking + them to a reality where they feel like they matter. +2018-05-19: + Alexch2: + - spellcheck: Fixes tons of typos related to integrated circuits. + - tweak: Re-writes the descriptions of a few parts of integrated circuits. + Astatineguy12: + - tweak: The experimentor is less likely to produce food when it transforms an item + - bugfix: The experimentor no longer breaks when the toxic waste malfunction occurs + multiple times and isn't cleaned up + - bugfix: The experimentor irridiate function actually chooses what item to make + properly rather than picking from the start of the list + Dax Dupont: + - bugfix: Mulligan didn't work on lizards and other mutants. Now it does. + - bugfix: Foam no longer gives infinite metal + Denton: + - code_imp: Loose silver/gold/solar panel crates have been replaced with "proper" + crates. + - tweak: There are rumors of the Tiger Cooperative adding a "special little something" + to some of their bioterror kits. + Iamgoofball: + - tweak: Lipolicide now only does damage if you're starving. + Mickyan: + - bugfix: Drinking too much Gargle Blaster, Nuka Cola or Neurotoxin no longer breaks + time and space. + Nichlas0010: + - tweak: Reseach Director Traitors can no longer receive an objective to steal the + Hand Teleporter + ShizCalev: + - bugfix: Fixed mobs immune to radiation being killed by HIGH bursts of radiation. + - bugfix: The book of mindswap will now properly mindswap it's users. + iksyp: + - rscadd: stacking machines and their consoles no longer dissapear into the shadow + realm when broken + - rscadd: you can link the stacking machine and its console by using a multitool +2018-05-20: + Pubby: + - rscadd: 'Cargo bounties from Nanotrasen. Earn cargo points by completing fetch + quests. remove: Several cargo exports have been reduced or merged into cargo + bounties.' + XDTM: + - rscadd: 'Added a new lavaland loot item: Memento Mori. A necklace which has the + power to prevent death, but will turn you into dust if removed.' +2018-05-22: + Cyberboss: + - rscadd: You can now view your last round end report window with the "Your last + round" verb in the OOC tab + Dax Dupont: + - tweak: The BoH dialog now has Abort instead of Proceed as an default option. + - bugfix: Fixes race condition caused by exiting the body while dying in VR. + Denton: + - balance: Skewium is much less likely to appear during the Clogged Vents event. + Firecage: + - rscadd: Replaces wardrobe lockers on Box with Wardrobe Vending Machine. + Kor: + - rscadd: Engineering can now create anomaly neutralizer devices, capable of instantly + neutralizing the short lived anomalies created by the supermatter engine. + - rscadd: The Quartermaster and HoP can now access the vault so they can use the + bank machine. + Mickyan: + - bugfix: Pacifists can now use harm intent for actions that require it (but still + can't harm!) + Naksu: + - code_imp: Added EMP protection component, replaced various bespoke ways things + handled EMP proofness + Nichlas0010: + - spellcheck: you now feel nauseated instead of nauseous + - bugfix: Comms consoles won't update while viewing messages + SpaceManiac: + - bugfix: Pipe icons in the RPD now show properly in older versions of IE. + - bugfix: Family heirlooms which can fit in pockets will now spawn there. + - bugfix: Family heirlooms which only fit in the backpack now show the backpack + at roundstart. + - bugfix: Family heirlooms which do not fit in the backpack are no longer gone forever. + - bugfix: Mindswapping with someone else no longer forces ambient occlusion on. + - code_imp: IRV polls now use the same version of jQuery as everything else. + - bugfix: Hydroponics trays can no longer be deconstructed with their panels closed + or unanchored while irrigated. + - tweak: Frames for machines which do not require being anchored can now be un/anchored + after the circuit has been added. + - bugfix: Removing an ID from a PDA in a backpack no longer hides the ID until something + else updates. + - bugfix: Opening and closing airlocks repeatedly no longer stacks queued autocloses. + - bugfix: Admin AI interaction now works properly on firelocks. + - spellcheck: Fix "Your the wormhole jaunter" when a wormhole jaunter saves you + from a chasm. + Wilchen: + - rscdel: Removed box of firing pins from rd's locker + armhulen: + - rscdel: chameleon guns are disabled for breaking the server + kevinz000: + - bugfix: Field generators are once again operable by adjacent cyborgs. + - bugfix: Digital valves are once again operable by silicons. + - bugfix: Chasms no longer drop mobs buckled to undroppable mobs or objects. + resistor: + - rscadd: Added circuit labels! You can now customize the description of your assemblies. +2018-05-23: + ShizCalev: + - bugfix: Fixed a runtime with the gulag teleporter that could cause the process + to fail if you removed the ID. + - tweak: Not setting the goal of a prisoner's ID when teleporting them will now + set the ID's goal to the default value (200 points at the time of this change.) + SpaceManiac: + - bugfix: Flipping and then rotating trinary pipe fittings no longer causes their + icon to mismatch what they will become when wrenched. + - bugfix: RPD tooltips for flippable trinary components have been corrected. + - bugfix: Entertainment monitors now view the real Thunderdome rather than the template. + cyclowns: + - rscadd: Analyzers can now scan all kinds of atmospheric machinery - unary, binary, + ternary, quaternary, you name it. This means stuff like gas pumps, gas mixers, + vents and so forth can be analyzed. + - tweak: Analyzers now show temperature in kelvin as well as celsius. + - tweak: Analyzers now show total mole count, volume, and mole count of all gases. + - tweak: Analyzers show everything at slightly higher degrees of precision. + imsxz: + - admin: Using mayhem bottles and going under their effects is now logged. + kevinz000: + - rscadd: Any anomaly core can now be deconstructed for a one time boost of 10k + points in the deconstructive analyzer. +2018-05-25: + Astatineguy12: + - bugfix: The mime blockade spell now shows up under the right tab + Cruix: + - rscadd: Added a button to chameleon items to change your entire chameleon outfit + to the standard outfit of a selected job. + Dax Dupont: + - rscadd: Murderdome now has a telecomm system, so you can taunt your enemies better. + - rscadd: Snowdin has come back, as VR! + - rscadd: Nanotrasen Tactical Bureau has discovered a Syndicate VR Training program + on their last raid. It seems to be based on an old CentCom design... + - rscadd: Restricted variant of the uplink. Will allow admins and such to spawn + uplinks in remote arenas or for events that aren't as destructive and can't + communicate with other Zs. + - bugfix: Extends same Z level check to monitor and bugging operations too for camera + bug. + - bugfix: VR sleepers now show the stat of the VR avatar instead of the user as + intended. + - code_imp: Makes it throw a stack trace when you ghostize in VR. + - tweak: It will now delete the body if it's unconscious if you try to reconnect, + to speed up reconnection. + - balance: Emagged sleepers will now display a notification on the UI, and make + you slightly dizzy after a while. + - balance: More chemicals can be found when vents get clogged. + - bugfix: Fixes accidental empty ahelp replies. + Denton: + - rscadd: Departmental wardrobe vendors have been added to all maps. + - spellcheck: Sorted cargo packs (wardrobe refills//alphabetically) and mining vendor + items (by price), again. + - bugfix: 'Navbeacon access requirements have been fixed: Now you need either Engineering + or Robotics access, but not both at the same time.' + Garen: + - rscdel: Removed circuitry save files saving whether or not the assembly is open. + - rscadd: Adds messages for when you successfully use a sensor or scanner circuit. + - bugfix: Fixed circuit printers printing advanced assemblies from save files despite + not being upgraded. + - bugfix: Fixed circuit printers printing circuits into assemblies that wouldn't + normally be able to hold them. + - bugfix: Fixed circuit assemblies taking damage when using objects with the help + intent. + Mickyan: + - spellcheck: fixed typo in bronze girder construction + MrDoomBringer: + - rscadd: Cargo now has access to Supplypod Beacons! Use these to call down supplypods + with frightening accuracy! + - imageadd: the VR sleeper action button has a sprite now + Naksu: + - code_imp: Replaced initialized and admin_spawned vars with flags. + - code_imp: changed the shockedby list on doors to be only initialized when needed. + - tweak: Chameleon projector can no longer scan (often temporary) visual effects + like projectiles, flashes and the masked appearance of another chameleon projector + user + - bugfix: Drones can no longer see a static overlay over invisible revenants + - balance: adjusted default antag rep points to grant every job the same amount + of points per round, except for assistant which gets 30% less + SpaceManiac: + - bugfix: Non-harmfully placing someone who is resting on a table no longer makes + them get up. + - bugfix: The disco machine no longer lags the chat by spamming "You are now resting!" + messages. + - bugfix: The green overlay indicating where a map template will be placed is no + longer invisible on space turfs. + - bugfix: CentCom is no longer self-looping, fixing the ability to see or get into + certain areas after escaping to space. + - bugfix: The destructive analyzer no longer consumes entire stacks to give the + benefit of one sheet. + - bugfix: Xeno weeds and floors under diagonal walls are now on the correct plane, + fixing odd ambient occlusion appearances. + - bugfix: Inserting materials into protolathes with telekinesis is now possible. + - bugfix: Telekinesis no longer teleports items removed from deep fryers, constructed + sandbags, and leftover materials not inserted into lathes. + - bugfix: Telekinetic sparkles now appear in the correct place when clicking on + a turf and when clicking in the fog of war in widescreen. + - bugfix: Telekinetically adjusting power tools no longer causes them to exit the + universe. + - tweak: Examining a telekinetic grab in-hand will now examine the grabbed object. + - bugfix: Frost spiders now correctly inject frost oil on bite. + yorii: + - bugfix: Fixed the smartfridges to be in line with all other machines and puts + the released item in your hand. +2018-05-26: + Dax Dupont: + - bugfix: Experimentor no longer shits out primed TB nades. + Garen: + - rscadd: Added a cell charger to the circuitry lab on all stations. + - rscadd: Added a circuitry lab to the syndicate lavaland base. + - tweak: Modified the meta station circuitry lab. + Iamgoofball: + - rscadd: Humans require ice cream. Eat the ice cream. + Kor: + - rscadd: Bag of Holding detonations have been significantly reworked. + Robustin with cat earrs: + - bugfix: 'Gun overlays should be way less laggy now. remove: Chameleon guns are + completely removed since they crash the server, were already made unavailable, + and are the worst shitcode I''ve ever seen in my life.' + SpaceManiac: + - tweak: Clicking on the viewport to focus it no longer leaves the input bar red. + - admin: Create Object will no longer force objects with special directional logic + to be facing south by default. + - bugfix: Running diagonally into space now properly continues the diagonal movement + in zero-gravity. +2018-05-27: + Armhulen, and Keekenox: + - rscadd: Chaplain now gets custom armor too! Order it from the beacon in your locker. + Cobby: + - tweak: Several of the recent drinks added have now been given effects! + - rscadd: 'Alexander: Conquer the world... or just the station with this drink! + If you have a shield, it will increase the block chance by 10 percent! Careful + not to drop it in battle though....' + - rscadd: 'Between The Sheets: Save the pillow talk for next shift, having this + in your system while you''re asleep will slowly heal you!' + - rscadd: 'Menthol: Prevents coughing. Good for a cold or if the Chaplain gets his + hands on a smoke book!' + - tweak: Descriptions have been edited so that if you view these under a chem master + they will tell you the effect. + - tweak: Decals are the exception to the recent removal of effects in Chameleon + Projectors. + Dax Dupont: + - bugfix: Did you know istype doesn't work on paths even though they are mostly + the same? Yeah I didn't either. Experimentor shouldn't shit out TB nades anymore. + - bugfix: Fixes item reactions for relics as well. + - rscadd: Adds better messaging + - bugfix: Fixes summons happening on away missions. + GuyonBroadway: + - rscadd: Adds gloves of the north star to the traitor uplink. Wearing these gloves + lets you punch people five times faster than normal. + - rscadd: Sprites for the gloves courtesy of Notamaniac + Mickyan: + - rscadd: 'New trait: Drunken Resilience. You may be a drunken wreck but at least + you''re healthy. If alcohol poisoning doesn''t get you, that is!' + Naksu: + - rscadd: Nuclear explosive-shaped beerkegs found on metastation can now be triggered + with the nuclear disk and the syndicate's legacy nuclear code for a foamy surprise + SpaceManiac: + - bugfix: Unwrenching and re-wrenching pre-mapped atmos components no longer turns + them on automatically. + steamport: + - bugfix: Borgs/AIs can now toggle rad collectors +2018-05-28: + CitrusGender: + - bugfix: Kills you if you're under 0% blood and above -9999% blood level (shouldn't + be possible through normal means to be below that.) + - bugfix: Stops bloodloss trait from happening if your race contains the NO_BLOOD + - bugfix: added a check to see if the preferred race is human when the name doesn't + have a space + Dennok: + - bugfix: Fixed a laser reflections from reflectors. + Denton: + - tweak: Deltastation's firing range has been decommisioned and replaced with a + brand new toxins burn chamber. + - bugfix: Delta toxins disposals are now actually connected to the disposals loop. + Toxins storage has a fire alarm too. + - bugfix: The shutter buttons of Pubbystation's mechbay now check for access. + SpaceManiac: + - bugfix: The robustness of the Super Secret Room has been increased. + - bugfix: Observers can no longer move the action button toggle or change the ambient + occlusion setting of their targets. + - bugfix: The emergency space suit safes in escape pods are no longer always unlocked. + Tlaltecuhtli: + - bugfix: apiaries from cargo start unwrenched +2018-05-29: + Dennok: + - rscadd: Collectors show their real produced power and stored power when examined + Naksu: + - code_imp: removed some unneeded typecaches +2018-05-31: + CitrusGender: + - bugfix: Flamethrowers are no longer uncraftable since they have a part that happens + to be a tool. + - bugfix: Fixes cyborgs not being able to use two-handed modules while other modules + are equipped. + CosmicScientist: + - rscdel: Can't make drones anymore + Cruix: + - rscadd: AIs now have an experimental multi-camera mode that allows them to view + up to six map areas at the same time, accessible through two new buttons on + their HUD. + Cyberboss: + - config: The limit of monkey's spawned via monkey cubes is now configurable + Dax Dupont: + - bugfix: Fixes the wrong tiles in Syndicate VR trainer and uses different tiny + fans. + - bugfix: Access didn't append to VR IDs + Firecage: + - rscadd: The mech fabricator can now print two new janiborg upgrades. Advanced + Mop and Trash Bag of holding. These two upgrades uses the advanced robotics + node. + SpaceManiac: + - bugfix: Changing UI Style preference now takes effect immediately rather than + next round. + - bugfix: Mindswapping with someone no longer gives you their UI style. + - bugfix: The destructive analyzer can once again be used to reveal nodes. + - spellcheck: Some references to "deconstructive analyzer" have been updated to + "destructive". + - tweak: Hulks and catpeople now show "Human-derived mutant" under "Species" when + health scanned. + - bugfix: Cyborg inventory slots once again unhighlight when a module is stowed. + deathride58: + - rscadd: Things that are capable of igniting plasma fires will now generate heat + if there's no plasma to ignite. Building a bonfire inside the station without + taking safety precautions is now a bad idea. + kevinz000: + - rscadd: Plasma specific heat is 500J/K*unit, everything else is 200 + zaracka: + - bugfix: The Spirit Realm rune no longer spawns a braindead cult ghost when attempting + to summon one after a player reaches the limit. diff --git a/html/changelogs/archive/2018-06.yml b/html/changelogs/archive/2018-06.yml new file mode 100644 index 0000000000..8a182b32f4 --- /dev/null +++ b/html/changelogs/archive/2018-06.yml @@ -0,0 +1,527 @@ +2018-06-01: + Big Tobacco: + - rscadd: Cheap lighters now come in four different shapes and Zippos can have one + of four different designs, collect them all and improve our sales! + - imageadd: All existing lighter sprites have been given a face-lift and the flames + are now subtly animated. + - tweak: Cheap lighters now use a fixed list of 16 colors to pick from instead of + using totally randomized colors. + - imageadd: Cigar cases have been tweaked to be a bit smaller and to have a modified + design. + - imageadd: Cohiba Robusto and Havanan cigars now use separate case sprites from + the generic premium cigar cases. + Dax Dupont: + - bugfix: Fixed rpeds throwing stock part rating related runtimes. + Naksu: + - code_imp: NODROP_1, DROPDEL_1, ABSTRACT_1 and NOBLUDGEON_1 have been moved to + item_flags + - tweak: brass handcuffs, meat hook and the chrono gun now conduct electricity. + Nichlas0010: + - bugfix: You can no longer use a soapstone infinitely + SpaceManiac: + - bugfix: Moving diagonally past delivery chutes, transit tube pods, &c. no longer + causes your camera to be stuck on them. + - refactor: The base machinery type is now anchored by default. + - bugfix: Pubby's auxiliary mining base now works again. + - bugfix: Cloning no longer breaks a character's connection to their family heirloom. + - bugfix: The overlay effects of cult flooring are now on the floor plane, fixing + their odd ambient occlusion appearance. + - bugfix: Beam rifle tracers no longer fall into chasms. + - bugfix: Vomiting on the same tile a second time no deletes the vomited reagents. + theo2003: + - bugfix: fixed the clockwork helmet not dropping to ground when used by non-clock + cultists +2018-06-03: + Denton: + - tweak: 'Pubbystation: Added a dual-port vent pump to the toxins burn chamber.' + - code_imp: Removed most airlock_controller/incinerator related varedits and replaced + them with defines/subtypes. + - tweak: The Deltastation toxins lab has its portable scrubber, air pump and intercom + back. + Naksu: + - bugfix: comms consoles now work in transit again, and no longer work in centcom + - code_imp: removed unnecessary getFlatIcons from holocalls + - bugfix: Screwdrivers and other items with overlays now show the proper appearance + of the item when attacking something with them, or when put on a tray. + Nichlas0010: + - bugfix: You now can't get multiple download objectives! + - tweak: RDs, Scientists and Roboticists can no longer get download objectives! + ShizCalev: + - bugfix: Fixed cigar cases & cigarette packets taking two inventory slots + - bugfix: Fixed cigar cases showing the wrong icon for the cigars inside them. + - bugfix: Fixed cigar cases & cigarette packets stating the wrong name of the cigar/cigarette + when removed via altclick. + - bugfix: Fixed items in pockets vanishing when a mob is monkeyized. + - bugfix: Fixed items in pockets vanishing when a mob is gorillized. + - bugfix: Fixed items in pockets vanishing when a mob is infected with a transformation + disease. + - bugfix: Fixed items in pockets not being properly deleted when a mob goes through + a recycler + - bugfix: Fixed items in pockets not being properly deleted when highlander mode + is enabled. + - bugfix: Fixed exploit allowing you to remove unremovable tanks from pockets. + - bugfix: Fixed items in pockets dropping when a mob is equipped with a new outfit. + - bugfix: Fixed items in pockets not being covered in blood when equipping the psycho + outfit. + SpaceManiac: + - bugfix: Switching mobs into/out of a mech (by VR, ghosting, or mindswap) no longer + improperly applies the mech's cursor. + ThatLing: + - bugfix: PDA style now gets loaded correctly. + cyclowns: + - bugfix: Fires no longer flicker back and forth like crazy + iskyp: + - tweak: switched the type of the space suit on the syndicate shuttle + theo2003: + - tweak: roboticists have access to R&D windoors + - bugfix: fixed hydroponics tray weed light staying on when removing weeds with + integrated circuits + yorpan: + - rscadd: Brain damage makes you say one more thing. +2018-06-04: + Beachsprites: + - imageadd: added directional beach sprites + MrDoomBringer: + - admin: Central Command can now smite misbehaving crewmembers with supply pods + (filled with whatever their hearts desire!) + SpaceManiac: + - bugfix: Atom initialization and icon smoothing no longer race, causing late-loading + mineral turfs to have no icon. + - spellcheck: Faceless persons no longer "melt their face off" in energy gun suicides. + - bugfix: The Lightning Bolt spell now works again. + yenwodyah: + - bugfix: A few virus threshold effects should work now +2018-06-06: + Dax Dupont: + - bugfix: Fixes a sentience related exploit by blacklisting it in restricted uplinks. + Denton: + - rscadd: Arcades have been stocked with preloaded tactical snack rigs. + - bugfix: Swarmers can no longer attack field generators and turret covers. + - bugfix: The Pubbystation maint bar Booze-O-Mat now shows its contents correctly. + MrDoomBringer: + - admin: CentCom Supplypods now stun their target before landing, and won't damage + the station as much + Naksu: + - code_imp: moved /datum.isprocessing into datum flags + iksyp: + - bugfix: Ever since the great emotion purge of 2558, people were able to work at + top efficiency, even while starving to death. This is no longer the case, Nanotrasen + Scientists say. + - admin: Hunger slowdown only applies if mood is disabled in the config. +2018-06-07: + Cruix: + - bugfix: Picture-in-picture objects now are no longer overlapped by other certain + objects + SpaceManiac: + - bugfix: It is now possible to access the wires of RND machines in order to repair + them if they have been EMP'd. + Tlaltecuhtli: + - bugfix: rad collectors set to research point gen are somewhat ok now + kevinz000: + - tweak: Vehicle speed changes now happen immediately instead of on the next movement + cycle +2018-06-08: + AnturK: + - code_imp: Gravity can now go above 1g + CitrusGender: + - imageadd: sandstone wall sprite for indestructible object + Denton: + - tweak: Added a warning to the shuttle purchase menu. + - bugfix: Added missing vents to runtimestation. + - tweak: 'Runtimestation: Added /debug EMP flashlight, emag, techfab and tiny fans. + Replaced RCD, healing wand and sleeper with more suitable subtypes.' + MrDoomBringer: + - tweak: Due to DonkCo's recent budget cuts, their line of toy emags are now noticably + less realistic. As such, you can now examine an emag to determine if it is a + toy or not. + Naksu: + - balance: Temperature gun projectiles now respect armor/dodge, and will no longer + freeze you if they don't hit you. + SpaceManiac: + - bugfix: The thermal sight benefits of lantern wisps no longer disappear if you + change glasses. + - bugfix: Paradox bags no longer block the middle of your screen until reconnect, + and also actually work. + - bugfix: A pAI dying while in holoform no longer deletes the card, instead merely + emptying it. + - bugfix: The elevators in the Snowdin away and VR missions work again. + - bugfix: Minor atmos issues in Snowdin and UO45 have been corrected. + Tlaltecuhtli: + - bugfix: all spiders can make webs now + deathride58: + - balance: Sparks, using welding tools, using igniters, etc, will no longer cause + an instant fireless inferno in small rooms. + - tweak: The revert of the original hotspot_expose() PR has been reverted, since + the reason as to why it was reverted was resolved with this change. + - balance: Reverted the increased rad collector tech point gain rate. + fludd12: + - rscadd: Love potions are marginally more interesting! This same effect applies + to if you are a valentine! + - tweak: The names of extracts are now in the proper order, finally! + - rscadd: Self-sustaining extracts are in! Technically, this is a fix, but whatever. + - bugfix: Stabilized Cerulean extracts no longer vaporize items into the Aetherium. + - rscadd: Stabilized Gold extracts are now moderately more fun to use! The randomized + creature persists if it is killed, and can be rerolled at will! Also, if you + give the creature a sentience potion, the mind will transfer over! + oranges: + - rscadd: Sec now has khaki pants for tacticoolness +2018-06-11: + Mickyan: + - rscadd: Added an abandoned kitchen to Metastation maintenance + XDTM: + - bugfix: Fixed anti-magic not working at all. + fludd12: + - bugfix: Stabilized gold extracts now respawn the familiar properly. + - bugfix: Stabilized gold familiars retain the proper languages even after respawning. + - tweak: Stabilized gold familiars can be renamed and have their positions reset + at will. +2018-06-12: + Dax Dupont: + - bugfix: Botany trays don't magically refill anymore with a rped. + SpaceManiac: + - tweak: Fire alarms now redden all the room's lights, and emit light themselves, + rather than applying an area-wide overlay. + - bugfix: Fire alarms no longer visually conflict with radiation storms. + - bugfix: Pulling objects diagonally no longer causes them to flail about when changing + directions. + - bugfix: Riders are no longer left behind if you move while pulling something that + has since been anchored. + - bugfix: Lockboxes are now actually locked again. + - bugfix: Deaf people can no longer hear cyborg system error alarms. + - bugfix: Plasmamen now receive their suit and internals when entering VR. + - bugfix: Legion cores and admin revives now heal confusion. + XDTM: + - bugfix: Diseases now properly lose scan invisibility if their stealth drops below + the required threshold. +2018-06-13: + 'Armhulen code, Keekenox sprites and S_____ as the ideas guy :roll_eyes:': + - rscadd: 'New drinks: Peppermint Patty and the Candyland Extract!!' + CitrusGender: + - bugfix: checks to see if bullets are deleted if they are the ammo type and the + bullet chambered. + Dax Dupont: + - balance: It's now easier to become fat. Don't eat so much. + Mickyan: + - bugfix: Fixed pacifists being able to harm using bottles/screwdrivers + SpaceManiac: + - spellcheck: Capitalization, propriety, and plurality on turfs have been improved. + XDTM: + - tweak: Coldproof mobs can now be cooled down, but are still immune to the negative + effects of cold. + - bugfix: This also fixes some edge cases (freezing beams) where mobs could be cooled + down and damaged despite cold resistance. + - balance: Virus crates now contain several bottles of randomly generated diseases + with symptom levels up to 8. + - rscdel: Removed the single-symptom bottles that were included in the virus crate. + - balance: Androids are now immune to radiation. + cacogen: + - rscadd: You can now see what other people are eating or drinking. + - rscadd: Borg shaker can now synthesise milk, lemon juice, banana juice and coffee + - bugfix: Renamed drinks no longer revert to their original name when their reagents + change + chesse20: + - rscadd: Adds Exotic Corgi Crate to Cargo + - rscadd: Adds Exotic Corgi, a Corgi with a random hue applied to it + - rscadd: Adds Talking Corgi Crate, and talking Corgi +2018-06-15: + CitrusGender: + - bugfix: logs will now show ckeys when admin transformations are done + Cruix: + - bugfix: Item attack animations can no longer be seen over darkness or camera static. + Dax Dupont: + - admin: You can now send messages as CentCom through people's headsets. + - bugfix: Fixes missing cream pies in the cream pie fridge. + Denton: + - bugfix: 'Omegastation: Connected the Engineering Foyer APC to the powernet.' + - bugfix: 'Pubbystation: Connected Chemistry disposals to the pipenet and fixed + Booze-O-Mat related display/access issues.' + - tweak: Syndicate stormtroopers now fire buckshot again. + Naksu: + - bugfix: Pipe dispensers can no longer create pipes containing literally anything + Nichlas0010: + - tweak: The TEG and its circulator can now be deconstructed and rotated! + - tweak: The TEG and its circulator now supports circulators in all directions, + rather than just west/east! + SpaceManiac: + - rscadd: A new OOC verb "Fit Viewport" can be used to adjust the window splitter + to eliminate letterboxing around the map. It can also be set to run automatically + in Preferences. + - bugfix: Refunding nuclear reinforcements while polling ghosts no longer summons + the reinforcements into the error room anyways. + - bugfix: Shift-clicking turfs obscured by fog of war no longer lets you examine + them. + - admin: It is now possible to cancel "Manipulate Organs" midway through. + Tlaltecuhtli: + - rscadd: Added shoes to leather recipes + ninjanomnom: + - bugfix: Gas overlays left over in some turf changes should no longer stick around + where they shouldn't. +2018-06-17: + Dax Dupont: + - refactor: Syndicate and Centcom messages have been squashed together. + - admin: You can now send both Syndicate and Centcom headset messages. Be mindful + that the button was changed to HM in the playerpanel + - bugfix: Fixed missing grilles under brig windows of the pubby shuttle. + - rscadd: For the pubby shuttle, added some food in the fridge, mostly pie slices. + Also added a sleeper to the minimedbay. + - tweak: Reworded pubby shuttle description to be more inline with the new train + shuttle. + - bugfix: Chem synths overlays aren't all kinds of fucked anymore. + - refactor: Unfucked all of the remaining chem synth code. + - refactor: Reagents no longer have an unused var that's always set to true. Who + did this? + - bugfix: You can no longer remove circuits with your mind. + - balance: Makes the xeno nest ruin harder to cheese. + - bugfix: Fixes the bathroom being airless in the Space Ninja anime jail. + Denton: + - tweak: 'Runtimestation: Added shuttle docking ports, a comms console, cargo bay + and syndicate/centcom IDs.' + - balance: Pirates and Syndicate salvage workers have been beefed up around the + caravan ambush ruin. + Pubby: + - bugfix: 'PubbyStation: Fixed disposals issue in security hallway' + SpaceManiac: + - bugfix: Moving large amounts of items with bluespace launchpads no longer creates + a laggy amount of sparks. + - bugfix: Unbreakable ladders are now left behind when shuttles move. + - bugfix: It is no longer possible to pull the mirages images at space transitions, + and some other abstract effects. + - tweak: PDAs and radios with unlocked uplinks no longer open their normal interface + in addition to the uplink when activated. + - tweak: Nuclear operative uplinks are no longer also radios. + - bugfix: The mining shuttle can once again fly to the aux base construction room + after the base has dropped. + - bugfix: The escape pod hallways on MetaStation and DeltaStation now have air again. + - bugfix: Hyperspace ripples now remain visible until the shuttle arrives, even + during extreme lag. + - bugfix: Ripples now correctly take the shape of the shuttle, rather than always + being a rectangle. + - bugfix: Non-secure windoors now properly support the "One Required" access mode + of airlock electronics. + Tlaltecuhtli: + - rscadd: After years of protests NT decided to update the fire security standards + by adding 3 (three) advanced fire extinguishers to all the new stations. + and Fel: + - imageadd: New chairs are on most shuttles! Finally, you can relax in style while + escaping a metal death trap. + cyclowns: + - rscadd: Fusion has been re-enabled! It works similarly to before, but with some + slight modification. + - tweak: Fusion now requires huge amounts of plasma and tritium, as well as a very + high thermal energy and temperature to start. There are several tiers of fusion + that cause different benefits and effects. + - tweak: The fusion power of most gases has been tweaked to allow for more interesting + interactions. + - tweak: BZ now takes N2O and plasma to create, rather than tritium and plasma. + - bugfix: Fusion no longer delivers server-crashingly large amounts of radiation + and stationwide EMPs. + theo2003: + - rscadd: Players who edited a circuit assembly can scan it as a ghost. +2018-06-18: + CitrusGender: + - tweak: The blob core (and only the blob core) now respawns randomly on the station + when the core is taken off z-level + - bugfix: Prevents the round from going into an unending state + - code_imp: Added a variable to the stationloving component for objects that can + be destroyed but not moved off z-level + Denton: + - tweak: NanoTours is proud to announce that the Lavaland beach club has been outfitted + with a dance machine, state of the art bar equipment and more. + SpaceManiac: + - bugfix: It is no longer possible to repair cyborg headlamps even when their panel + is closed. + - bugfix: Item fortification scrolls no longer add multiple prefixes when applied + to the same item. + - bugfix: The gulag shuttle no longer moves instantly when returned via the claim + console. + - admin: It is now possible to use the ".p" (Asay) and ".d" (Dsay) prefixes while + an admin ghost. +2018-06-19: + Cyberboss: + - admin: Speaking in deadchat now shows your rank instead of ADMIN + Dax Dupont: + - balance: Circuit lab no longer starts with super batteries, they have been replaced + with high batteries. + - balance: Circuit labs now start with 20 sheets of metal instead of 50/100. Plenty + of materials on the station you can gather. + - balance: Circuit labs no longer have their own protolathe and autolathe. Science + has their own lathes already. + - tweak: There's no more entire library worth of equipment, they can go publish + the books like the rest of the station, in the library. At least give the librarians + something other to do than screaming about lizard porn on the radio. + Hyacinth-OR: + - rscadd: Added a pink scarf to vendomats + Irafas: + - rscadd: Players can now ctrl-click the PDA to remove the item in its pen slot + JStheguy: + - rscadd: Added the data card reader circuit, a circuit that is able to read data + cards, as well as write to them. + - tweak: Data cards are now longer inexplicably called data disks despite clearly + being cards, and can be printed from the "tools" section of the integrated circuit + printer. + - tweak: Data cards no longer have a special "label card" verb and instead can have + their names and descriptions changed with a pen. + - rscadd: Also, some aesthetically different variants of the data cards, because + why not. + - imageadd: Data cards have new sprites, with support for coloring them via the + assembly detailer. + Naksu: + - code_imp: Sped up atmos very slightly + ninjanomnom: + - rscadd: A plush that knows too much has found its way to the bus ruin. +2018-06-21: + BlueNothing: + - tweak: Grabbers can no longer hold circuit assemblies + CitrusGender: + - bugfix: Ruins air alarms will no longer be reported in the station tablets + - bugfix: added a clamp so you can't set a negative multiplier to create materials + and create more than 50 items. + Cobby: + - rscdel: Removed Advanced Mining Scanner from roundstart voucher kits. + - rscdel: Removed Explorer Webbing from all voucher kits besides the shelter capsule + pack. + Denton: + - bugfix: The public booze-o-mats and autodrobes on Box/Delta/Meta now have no access + requirements, as previously intended. + - rscadd: Regular and advanced health analyzers can now be researched and printed. + McDonald072: + - rscadd: A few new circuits for dealing with atmospherics have been uploaded to + your local printers. + NewSta: + - tweak: made it easier to see from the back whether someone is occupying the shuttle + chair or not. + SpaceManiac: + - tweak: One canister is now suitable to fully stock a vending machine. Relevant + cargo packs have been updated. + - bugfix: Deconstructing and reconstructing a vending machine no longer creates + items from thin air. + - bugfix: Using a part replacer on a vending machine no longer empties its inventory. + - rscadd: Bluespace RPEDs can now be used to refill vending machines. + Tlaltecuhtli: + - bugfix: anomaly cores no longer tend to dust + YPOQ: + - bugfix: Watcher beams will freeze you again +2018-06-23: + Dax Dupont: + - imageadd: CHANGE PLACES, SHUTTLE CHAIRS HAVE BEEN CHANGED AGAIN. + - admin: Create antags now checks for people being on station before applying. + ExcessiveUseOfCobblestone: + - spellcheck: Plant disks with potency genes clarify the percent is for potency + scaling and not relative to max volume on examine. + Kor: + - rscadd: Bubblegum has regained his original (deadlier) move set. + SpaceManiac: + - bugfix: Fire extinguishers on the emergency shuttle are no longer unclickable + once removed from their cabinets. + kevinz000: + - rscadd: Blast cannons have been fixed and are now available for purchase by traitorous + scientists for a low low price of 14TC. + - rscadd: 'Blast cannons take the explosive power of a TTV bomb and ejects a linear + projectile that will apply what the bomb would do to a certain tile at that + distance to that tile. However, this will not cause breaches, or gib mobs, unless + the gods (admins) so will it. experimental: Blast cannons do not respect maxcap. + (Unless the admins so will it.)' +2018-06-24: + CitrusGender: + - bugfix: Fixed cyborgs not getting their names at round start + - bugfix: Fixed cyborgs and A.I.s being able to bypass appearance bans + SpaceManiac: + - bugfix: The "Save Logs" option in the chat now actually works (IE 10+ only). + Time-Green: + - bugfix: Soda is no longer intangible to the laws of physics + cinder1992: + - rscadd: The Captain can now go down with their station in style! Suicide animation + added to the Officer's Sabre. + kevinz000: + - rscadd: Cyborgs now drop keys on deconstruction/detonation +2018-06-27: + Cyberboss: + - server: Logs and admin messages will now appear when you are using deprecated + config settings and advise on upgrades + Dax Dupont: + - admin: Malf AI machine overloads now are logged/admin messaged. + - tweak: The tree of liberty must be refreshed from time to time with the blood + of patriots and tyrants. We've removed access requirements from liberation station + vendors. + - bugfix: Fixes more href exploits in circuits + - refactor: Printing premade assemblies is no longer shitcode, time remaining had + to go for this. + - admin: Filled holes in the logging of circuits + Denton: + - tweak: Camera networks, monitor screens and telescreens have been standardized. + - tweak: Motion-sensitive cameras now show a message when they trigger the alarm. + - bugfix: The Box/Meta auxillary base camera now works. + - bugfix: Bomb test site cameras now emit light, as intended. + - bugfix: 'Meta: Replaced the RD telescreen in the CE office with the correct one.' + - tweak: Did you know that honey has antibiotic properties? + Irafas: + - bugfix: Hardsuit helmets now protect the wearer from pepperspray + - bugfix: Bucket helmets cannot have reagents transferred into them until after + they are removed + MadmanMartian: + - bugfix: Cameras that are EMPed no longer sound an alarm + Mickyan: + - bugfix: Branca Menta won't make you starve and then kill you + - tweak: Fernet has been moved to contraband + Naksu: + - code_imp: Removed unused effect object that could be used to spawn a list of humans + Nichlas0010: + - bugfix: Mothpeople no longer push objects to move in 0-grav, if they can fly + SpaceManiac: + - refactor: AI static now uses visual contents and should perform better in theory. + - bugfix: Pocket protectors now work again. + - bugfix: URLs are no longer auto-linkified in character names and IC messages. + - bugfix: It is once again possible for Cargo to export mechs. + - bugfix: Deaths in the CTF arena are no longer announced to deadchat. + Tlaltecuhtli: + - tweak: tourettes doesnt stack on itself anymore + - bugfix: fixes cult shuttle message repeating + Zxaber: + - rscadd: Cyborgs can wear more hats now. + kevinz000: + - rscadd: R&D deconstructors can now destroy things regardless of if there's a point + value or material + nichlas0010: + - bugfix: You should now receive your destroy AI objectives properly during IAA +2018-06-28: + Anonmare: + - balance: The possessed chainsword no longer makes e-swords look pathetic + Dax Dupont: + - admin: Admins can now scan circuits if they have admin AI interaction enabled. + - admin: some more circuit logging + - rscadd: You can now build clown borgs with a little bit of bananium and research. + Praise be the honkmother. + - rscadd: New upgrade module has been added so making loot/tech web borg modules + has become easier for admins/mappers/coders. + - refactor: Unused and broken OOC metadata code has been killed. + Denton: + - tweak: Added a disk compartmentalizer to Omegastation's hydroponics. + Kraso: + - bugfix: You can no longer use a soulstone shard to tell who's a cultist. + ShizCalev: + - bugfix: The blob will no longer take over space/mining/ect upon victory. +2018-06-29: + BlueNothing: + - balance: Cavity implants can no longer hold normal-sized combat circuits. Grabbers + can now hold up to assembly size. + - bugfix: Grabbers and throwers no longer function inside of storage implants. + Denton: + - tweak: Added all-in-one tcomms machinery and an automated announcement system. + Mickyan: + - imageadd: graffiti letters and numbers have received a makeover + MrDoomBringer: + - imageadd: Disk Fridges now have sprites! Ask cobby if you're wondering why they + look like toasters. +2018-06-30: + Dennok: + - bugfix: Deconstructable TEG now propertly connects to pipes. + - bugfix: Fix of inverted TEG sprite of slow turbine turning. add:Now you can flip + circulator and make TEG of your dream. add:Add TEG and circulator to "Advanced + Power Manipulation" techweb node. + MacHac: + - rscadd: Changelings can now take the Pheromone Receptors ability to hunt down + other changelings. + TerraGS: + - imageadd: New icon for plastic flaps that actually looks airtight. + - code_imp: Update to plastic flaps code to use tool procs rather than attackby + and removed two pointless states. diff --git a/html/changelogs/archive/2018-07.yml b/html/changelogs/archive/2018-07.yml new file mode 100644 index 0000000000..e213137c73 --- /dev/null +++ b/html/changelogs/archive/2018-07.yml @@ -0,0 +1,554 @@ +2018-07-01: + Denton: + - tweak: To comply with space OSHA regulations, all toasters (disk compartmentalizers) + have been put on tables. + - rscadd: Added a disk compartmentalizer to the seed vault Lavaland ruin. + Nichlas0010: + - bugfix: Changelings can now greentext the extract more genomes objective. + Thunder12345: + - rscadd: Added a colour picker component for use with circuits. +2018-07-02: + AnturK: + - bugfix: non-player monkeys won't fight when stunned. + Denton: + - bugfix: 'Pubbystation: Fixed the QM camera console''s direction.' + - code_imp: 'Pubbystation: Used the correct aux bomb camera subtype and replaced + loose tech storage boards with spawners, as is done in the rest of the map.' + - tweak: Tesla balls no longer blow up disposal outlets/delivery chutes and cameras. + Irafas: + - rscadd: Admin spawnable Death Ripley that comes with a version of the Death Clamp + that actually inflicts damage and rips arms off. + Naksu: + - admin: maxHealth is now guarded against invalid values when varediting + SpaceManiac: + - bugfix: A single wired glass tile no longer creates unlimited light floor tiles. + - bugfix: Printing the TEG and circulator boards no longer prints the completed + machinery instead. + XDTM: + - tweak: Nutriment Pump implants no longer require replacing the stomach. +2018-07-03: + Dax Dupont: + - balance: BoH detonations now gib the user. + Denton: + - tweak: Engine heaters no longer let gases pass through them. + - tweak: The Cerestation escape shuttle is now available for purchase! + Frozenguy5: + - bugfix: Fixes nitryl gas not applying its effects. + MrDoomBringer: + - bugfix: SupplyPod smites work properly once again. + Naksu: + - code_imp: Fixed the signatures of several reagent procs, removing useless checks + - tweak: drunkenness is now handled at the carbon level, allowing monkeys to experience + ethanol + - balance: initropidil also works on carbon level, allowing syndicate operatives + using the poison kit to achieve the silent assassin rating against monkeys + - tweak: The ladders in the tear in the fabric of reality no longer spawn their + endpoints when the area is loaded, but only when the tear is made accessible + via a BoH bomb. + - tweak: CentCom is no longer accessible via the space ladder in the tear. + - tweak: The lavaland endpoint can no longer spawn completely surrounded by lava, + unless it spawns on an island + - code_imp: ChangeTurf can now conditionally inherit the air of the turf it is replacing, + via the CHANGETURF_INHERIT_AIR flag. + - bugfix: when ladder endpoints are created, the binary turfs that are created inherit + the air of the turfs they are replacing. This means the lavaland ladder endpoint + will have the lavaland airmix, instead of a vacuum. + - code_imp: navigation beacons are now properly deregistered from their Z-level + list and re-registered on the correct one if moved across Z-levels by an effect + such as teleportation or a BoH-induced chasm. + Nirnael: + - refactor: Removed an unnecessary volume_pump check + SpaceManiac: + - bugfix: Backpack water tanks now work properly when wielded by drones. + - bugfix: Backpack water tank nozzles can no longer be placed inside bags of holding + and chem dispensers. + - bugfix: Moving items between your hands no longer causes them to cross the floor + (squeaking, lava burning). + - bugfix: Scrambled research console icons have been fixed, and will be prevented + in the future. + Zxaber: + - tweak: Empty cyborg shells can now be disassembled with a wrench. + - tweak: Using a screwdriver on an empty shell will now remove the cell, or swap + it if you're holding a cell in your other hand. + ninjanomnom: + - tweak: Shuttle throwing also applies to loose objects on shuttles now. + - tweak: Closets on shuttles start anchored. + - tweak: The throw distance of shuttle throws is marginally random, potentialy 10% + further or shorter + - rscadd: Tables and racks on shuttles have been installed with inertia dampeners. + - bugfix: Some very thin barriers didn't stop mobs from being thrown by the shuttle + under certain circumstances, this has been fixed. +2018-07-05: + Cyberboss: + - bugfix: Setting "default" in maps.txt now will load that map as the first fallback + when a next_map.json is missing + Jared-Fogle: + - bugfix: Fixed the "Remove IV Container" verb on IV drips from showing every nearby + mob + Naksu: + - tweak: shuttles now move the air along with their occupants, instead of magicking + up new air. + deathride58: + - tweak: Lone nuclear operatives now spawn as often as originally intended when + the disk is immobile. Secure that fuckin' disk. +2018-07-06: + Denton: + - spellcheck: Improved supply shuttle messages and firefighting foam descs. + - bugfix: Supply shuttles will no longer spill containers on docking. + Jared-Fogle: + - imageadd: Medical HUDs will now show an icon if the body has died recently enough + to be defibbed + Jegub: + - imageadd: Glowcaps now have their own sprite. + MacHac: + - bugfix: Bedsheets once again properly influence the dreams of those who sleep + under them. +2018-07-07: + Cruix: + - bugfix: Advaced camera consoles now properly show camera static in the area that + the eye starts + Denton: + - bugfix: Cere Station's escape shuttle has had its turbo encabulator replaced and + should no longer fly through hyperspace backwards. + Garen: + - rscadd: sends a signal for afterattack() + - code_imp: modified all calls of afterattack() to call the parent proc + Naksu: + - bugfix: constructed directional windows no longer leak atmos across them + - code_imp: setting the value of anchored for objects should be done via the setAnchored + proc to properly handle things like atmos updates in one place + Spaceinaba: + - tweak: Digitigrade legs no longer revert to normal on compatible outfits. +2018-07-08: + Affurit: + - imageadd: Back Sprites for the Godstaffs and Scythe now exist. + Cruix: + - rscadd: AI detection multitools can now be toggled to provide a HUD that shows + the exact viewports of AI eyes, and the location of nearby camera blind spots. + Floyd: + - rscdel: removed beauty / dirtyness + - balance: Mood no longer gives you hallucinations, instead makes you go into crit + sooner + Gwolfski: + - rscadd: autoname APC + - rscadd: directional autoname APC's + Naksu: + - code_imp: fixed mood component + XDTM: + - bugfix: Corazone now actually stops heart attacks. + cacogen: + - rscadd: Gibs squelch when walked over + subject217: + - bugfix: Five months later, wires will again make noise when pulsed or cut while + hacking. +2018-07-09: + Ausops: + - imageadd: New shuttle chair sprites. + Jared-Fogle: + - bugfix: Fixed russian revolvers acting like normal revolvers. + Nabski: + - imageadd: Crabs have a movement state sprite + TerraGS: + - tweak: Removed tap.ogg from multitool so getting hit by one sounds as painful + as it really is. + ninjanomnom: + - code_imp: The very back-end of movement got some significant reshuffling in preparation + for some future refactors. Bugs are expected. + subject217: + - spellcheck: The Nuke Op uplink no longer lies about how much ammo a C-20r holds. + - tweak: The L6 SAW now has a small amount of spread. It is still accurate within + visual range, but it's not as effective at longer ranges. +2018-07-10: + Astatineguy12: + - bugfix: You can now buy energy shields as a nuke op again + Denton: + - rscadd: 'Box/Delta/Pubbystation: Nuclear explosive-shaped beerkegs have been added + to maintenance areas.' + Naksu: + - rscadd: Added a new ghost verb that lets you change your ignore settings, allowing + previously ignored popups to be un-ignored and notifications without an ignore + button to be ignored + - bugfix: Chaplains are once again unable to acquire the inquisition ERT commander's + sword, as intended. The sword has been restored to its former glory + Supermichael777: + - bugfix: Changelings are no longer prevented from entering stasis by another form + of fake death. + Wjohnston & ninjanomnom: + - imageadd: Engine heaters and engines have had a minor touch up so they don't meld + with the floor quite so much. + - tweak: Engine heaters don't block air anymore. + XDTM: + - bugfix: Romerol tumors no longer zombify you if you're alive when the revive timer + counts down. +2018-07-11: + Denton: + - bugfix: Fixed a bug where golem shells couldn't be completed by certain brass/sandstone/titanium + stacks. + - tweak: The Spider Clan holding facility has completed minor renovations. The dojo + now includes medical and surgical equipment, while the lobby has a fire extinguisher + and plasmaman equipment. + - bugfix: Plasma and wooden golems no longer need to breathe, same as all other + golems. + - spellcheck: Fixed wrong or incomplete golem spawn info texts. + - tweak: Added more random golem names. + Irafas: + - bugfix: non-silicons can no longer use machines without standing next to them. + XDTM: + - bugfix: Automatic emotes no longer spam you saying that you can't perform them + while unconscious. + - rscadd: Added a Rest button to the HUD. It allows the user to lie down or get + back on their feet. + - balance: Getting back up now takes a second, to avoid people matrix-ing bullets. + fludd12: + - rscadd: You can now craft wooden barrels with 30 pieces of wood! They can hold + up to 300u of reagents. + - rscadd: Putting hydroponics-grown plants into the barrel lets you ferment them + for alcohol! Some give bar drinks, while others simply give plain fruit wine. + ninjanomnom: + - bugfix: Porta turret rotation on shuttles visually would not turn, this has been + dealt with. + - bugfix: Decals weren't rotating properly after the recent signal refactor, a couple + new procs for dealing with the signals on the parent object have been added + to deal with this. + subject217: + - balance: L6 SAW AP ammo now costs 9 TC per magazine, up from 6. + - balance: L6 SAW incendiary ammo now deals 20 damage per shot, up from 15. +2018-07-12: + AnturK: + - bugfix: Nuclear rounds will now end properly on nukeop deaths if there are no + other antags present. + Denton: + - rscadd: A new shuttle loan event has been added. Hope you like bees! + - tweak: The pizza delivery shuttle loan event now has some of each flavor and no + longer pays the station for accepting it. + - balance: Syndicate shuttle infiltrators now carry suppressed pistols. + - spellcheck: Added a missing period to spent bullet casing and pizza shutte loan + text. + - bugfix: Zealot's blindfolds now properly prevent non-cultists from using them. + - bugfix: Cultist legion corpses now wear the correct type of zealot's blindfold. + Time-Green: + - rscadd: An overdosing chemist filled the maintenance shafts with unorthodox pills, + be wary + ninjanomnom: + - rscadd: Certain objects which make noise which are thrown in disposals will squeak + when they hit bends in the piping. This includes clowns. + tralezab: + - admin: admins, you can now find martial art granting buttons in your VV dropdown. +2018-07-13: + Arithmetics plus: + - rscadd: Min circuit + - rscadd: Max circuit + Cyberboss: + - rscadd: More interesting recipes to the pizza delivery event + Deepfreeze2k: + - balance: Adds 2 carbon dioxide jetpacks to the pirate ship. Also gives the captain + a renamed bottle of rum in his room. + Denton: + - tweak: 'Most static ingame manuals have been replaced with ones that open relevant + wiki articles. remove: Deleted the "Particle Accelerator User''s Guide" manual, + since it''s included in the Singulo/Tesla one.' + - tweak: Machine frames no longer explode when struck by tesla arcs. + - rscadd: Locators can now be researched and printed at the security protolathe. + Jared-Fogle: + - soundadd: Removed delay from rustle1.ogg + LetterN: + - rscadd: Adds ratvar plushie and narsie plushie on chaplain vendors + Naksu: + - bugfix: deep-frying no longer turns certain objects like limbs invisible + Time-Green: + - bugfix: "Fixes an href exploit that lets you grab ID\u2019s out of PDA right from\ + \ another person" + XDTM: + - balance: (Real) Zombies no longer die from normal means. They will instead go + into crit indefinitely and regenerate until they get back up again. To kill + a zombie permanently you either need to remove the tumor, cut off their head, + gib them, or use more elaborate methods like a wand of death or driving them + to suicide. + - balance: Slowed down zombie regeneration overall, since putting them in crit now + no longer disables them for a full minute in average. + Zxaber: + - bugfix: MMI units inside cyborgs are no longer affected by ash storms. + ninjanomnom: + - bugfix: Objects on tables that are thrown by shuttle movement should no longer + do a silly spin + - balance: The alien pistol and the xray gun have both received a much belated buff + to their radiation damage to be on par with other sources of radiation. +2018-07-14: + Naksu: + - balance: stamina damage is no longer softcapped by the unconsciousness trigger + lowering stamina damage a little bit + ShizCalev: + - tweak: "The SM is now even more deadly to \"certain mobs\"\u2122" +2018-07-15: + AnturK: + - tweak: You can now use numbers in religion and deity names + Denton: + - bugfix: Bounty console circuit boards no longer construct into supply request + terminals. + Naksu: + - bugfix: fixed some missing args in emote procs called with named args, leading + to runtimes + - code_imp: removed unnecessary processing from a few machine types + SpaceManiac: + - bugfix: The Shuttle Manipulator admin verb works once more. +2018-07-16: + kevinz000: + - rscadd: 'Integrated circuit clocks now come in 3 flavors: Nanotrasen time (round + time), Station time (station time), and Bluespace time (server time, therefore + not affected by lag/time dilation)' + - rscadd: Integrated circuit clocks now also output a raw value for deciseconds, + allowing for interesting timer constructions. +2018-07-17: + Cyberboss: + - server: Added BSQL.dll and updated libmariadb.dll for non-blocking SQL support. + See https://github.com/tgstation/BSQL for instructions on building for non-windows + systems + Denton: + - tweak: Sparks now emit less heat. + - tweak: Added a storage room to Metastation engineering that both engineers and + atmos techs can access. + Naksu: + - admin: Plasma decontamination can now be triggered via events + - bugfix: Reebe is no longer airless and completely broken + Shdorsh: + - tweak: added UI to the circuit printer. That's all + XDTM: + - balance: Limbs no longer need to have full damage to be dismemberable, although + more damage means higher dismemberment chance. + - balance: Damaging limbs now only counts as 75% for the mob's total health. Bleeding + still applies normally. + - rscadd: Limbs that reach max damage will now be disabled until they are healed + to half health. + - rscadd: Disabled limbs work similarly to missing limbs, but they can still be + used to wear items or handcuffs. + kevinz000: + - rscadd: Crew pinpointers added to advanced biotechnology, printable from medical + lathes. + - rscadd: AIs can now interact with smartfridges by default, but by default they + will not be able to retrieve items. + ninjanomnom: + - bugfix: Mech equipment can be detached again. This probably also fixes any other + uncaught bugs relating to objects moving out of other objects. +2018-07-18: + Cyberboss: + - bugfix: Deaths now lag the server less + - bugfix: Ban checks cause less lag + Denton: + - tweak: RCDs can now also be loaded with reinforced glass and reinforced plasma + glass sheets. + Irafas: + - bugfix: players can construct while standing on top of a directional window. (machine + frames, computer frames, etc) + MrStonedOne: + - bugfix: synchronizing admin ranks with the database now lags the server less + - bugfix: saving stats now lags the server less + - bugfix: jobexp updating now lags the server less + - bugfix: poll creation now lags the server less. + Tlaltecuhtli: + - tweak: putting a cell and other not intended actions dont open the circuit window + WJohnston: + - tweak: Abandoned box ship space ruin consoles have been turned into something + more obviously broken so people stop complaining the ship doesn't work when + it's not meant to anyway. + - rscdel: Removed the extra syndie headset from the syndicate listening post space + ruin so people stumbling on the ruin won't be able to ruin your channel's security + as often. + XDTM: + - bugfix: Fixed a few bugs with imaginary friends, including them not being able + to hear anyone or surviving past the owner's death. + - rscadd: Imaginary friends can now move into the owner's head. + - rscadd: Imaginary friends can now choose to become invisible to the owner at will. +2018-07-20: + Cobby: + - bugfix: having higher sanity is no longer punished by making you enter crit faster + - balance: you can have 100 mood instead of 99 before it starts slowly decreasing + - bugfix: Paper doesn't give illegal tech anymore + CthulhuOnIce: + - spellcheck: Fixed 'Cybogs' in research nodes. + Denton: + - admin: Added hardsuit outfits for the Captain, HoS, and CMO. Removed old Shaft + Miner (Asteroid) outfits. Gave Chief Engineer (Hardsuit) engineering scanner + goggles. Added debug outfit for testing. + - tweak: Most wardrobe vendor contents have been tweaked. CargoDrobe now has the + vintage shaft miner jumpsuit available as a premium item. + WJohn: + - balance: Caravan ruin overall contains much less firepower, and should be harder + to cheese due to placement changes and less ammunition to work with. + - rscadd: The white ship is no longer stuck to flying around the station z level. + It can now fly around its own spawn's level and the derelict's level too (these + sometimes will be the same level). + kevinz000: + - rscdel: Removed flightsuits + zaracka: + - balance: Visible indications of cultist status during deconversion using holy + water happen more often. +2018-07-21: + Jared-Fogle: + - bugfix: Fixes destroyed non-human bodies cloning as humans. + WJohnston: + - balance: Reduced the 180 rounds (6 boxes) of 9mm ammo in the deep storage bunker + to 45 (3 mags). Removed one of the wt-550s but put a compatible magazine in + its place for the other to use. Turned the syndicate hardsuit into a regular + grey space suit. +2018-07-23: + BeeSting12: + - bugfix: Robotics' circuit printers have been changed to science departmental circuit + printers to allow science to do their job more efficiently. + Cruix: + - bugfix: AI eyes will now see static immediately after jumping between cameras. + Denton: + - rscadd: Shared engineering storage rooms have been added to Deltastation. + - bugfix: Fixed access requirements of lockdown buttons in the CE office. On some + maps, these were set to the wrong department. + - bugfix: Fixed Box and Metastation's CE locker having no access requirements. + - bugfix: 'Deltastation: Fixed engineers having access to atmospheric technicians'' + storage room. Fixed engineers having no access to port bow solars (the ones + at the incinerator by Atmospherics). Also fixed Minisat airlock access requirements.' + - bugfix: 'Pubbystation: Medbay and Cargo now have a techfab instead of protolathe.' + - tweak: Charlie/Delta Station (the "old cryogenics pod" ghost role) has been improved. + Survivors can now finish the singularity engine and will have more minerals + available inside the Hivebot mothership. The local atmos network is connected + to an air tank; fire alarms and a bathroom have been added. Keep an eye out + for a defibrillator too. + - rscadd: Nuclear Operatives can now purchase Buzzkill grenades for 5TC per box + of three. Those release a swarm of angry bees with random toxins. + - spellcheck: Chemical grenades, empty casings and smart metal foam nades now have + more detailed descriptions. + - spellcheck: Added examine descriptions to the organ harvester. + Epoc: + - rscadd: Adds "Toggle Flashlight" to PDA context menu. + Hathkar: + - tweak: Captain's Door Remote now has vault access again. + Mickyan: + - bugfix: 'Deltastation: replaced blood decals in maintenance with their dried counterparts' + SpaceManiac: + - tweak: RCDs can now be loaded partially by compressed matter cartridges rather + than always consuming the entire cartridge. + - bugfix: Fernet Cola's effect has been restored. + - bugfix: Krokodil's addition stage two warning message has been restored. + - admin: The party button is back. + WJohnston: + - bugfix: Fixed corner decals rotating incorrectly in the small caravan freighter. + XDTM: + - bugfix: Limbs disabled by stamina damage no longer appear as broken and mangled. + obscolene: + - soundadd: Curator's whip actually makes a whip sound now +2018-07-25: + Denton: + - tweak: H.O.N.K mechs can now play more sounds from the "Sounds of HONK" panel. + JJRcop: + - tweak: The item pick up animation tweens to the correct spot if you move + MrDoomBringer: + - spellcheck: Changed "cyro" to "cryo" in a few item descriptions and flavortexts. + SpaceManiac: + - rscadd: The vault now contains an ore silo where the station's minerals are stored. + - rscadd: The station's ORM, recycling, and the labor camp send materials to the + silo via bluespace. + - rscadd: Protolathes, techfabs, and circuit imprinters all pull materials from + the silo via bluespace. + - rscadd: Those with vault access can view mineral logs and pause or remove any + machine's access, or add machines with a multitool. + - tweak: The ORM's alloy recipes are now available in engineering and science protolathes. + Telecomms chat logging: + - code_imp: Added logging of telecomms chat + - config: Added LOG_TELECOMMS config flag (enabled by default) + WJohnston: + - rscadd: Redesigned deltastation's abandoned white ship into a luxury NT frigate. + Oh, and there are giant spiders too. + - bugfix: Med and booze dispensers work again on lavaland's syndie base, and the + circuit lab there is slightly less tiny. + subject217: + - rscadd: The M-90gl is back in the Nuke Ops uplink with rebalanced pricing. + - bugfix: The revolver cargo bounty no longer accepts double barrel shotguns and + grenade launchers. +2018-07-26: + Iamgoofball: + - bugfix: The shake now occurs at the same time as the movement, and it now doesn't + trigger on containers or uplinks. + Mickyan: + - balance: Light Step quirk now stops you from leaving footprints + Naksu: + - code_imp: gas reactions no longer copy a list needlessly + SpaceManiac: + - rscadd: 'The following machines can now be tabled: all-in-one grinder, cell charger, + dish drive, disk compartmentalizer, microwave, recharger, soda/booze dispenser.' + - rscadd: Unanchored soda/booze dispensers can now be rotated with alt-click. + - bugfix: Machinery UIs no longer close immediately upon going out of interaction + range. + - rscadd: Washing machines now wiggle slightly while running. + - rscadd: Washing machines can be unanchored if their panel is open for even more + wiggle. + WJohnston: + - rscadd: Return of the boxstation white ship, with a complete makeover! Box and + meta no longer share the same ship. +2018-07-27: + ShizCalev: + - bugfix: Destroying a camera will now clear it's alarm. + ninjanomnom: + - bugfix: The cargo shuttle should move normally again +2018-07-28: + CitrusGender: + - rscdel: Removed slippery component from water turf + Denton: + - balance: The Odysseus mech's movespeed has been increased. + - tweak: 'Metastation: Spruced up the RnD circuitry lab; no gameplay changes.' + - tweak: Due to exemplary performance, NanoTrasen has awarded Shaft Miners with + their very own bathroom, constructed at the mining station dormitories. Construction + costs will be deducted from their salaries. + Mickyan: + - imageadd: insanity static is subtler + - imageadd: neutral mood icon is now light blue + SpaceManiac: + - bugfix: Cyborgs and AIs can now interact with items inside them again. + Tlaltecuhtli: + - rscadd: Mouse traps are craftable from cardboard and a metal rod. + WJohnston: + - balance: Syndicate and pirate simple animals should have stats that more closely + resemble fighting a human in those suits, with appropriate health, sounds, and + space movement limitations. + - imageadd: Pirates in space suits have more modern space suits. +2018-07-30: + Anonmare: + - balance: Upload boards and AI modules, in addition to Weapon Recharger boards, + are now more expensive to manufacture + Basilman: + - bugfix: fixed BM Speedwagon offsets + Cobby (based off Wesoda25's idea): + - rscadd: Adds the PENLITE holobarrier. A holographic barrier which halts individuals + with bad diseases! + Denton: + - tweak: Techweb nodes that are available to exofabs by roundstart have been moved + to basic research technology. + - balance: Ripley APLU circuit boards are now printable by roundstart. + - balance: Odysseus, Gygax, Durand, H.O.N.K. and Phazon mech parts have to be researched + before becoming printable (same as their circuit boards). + - tweak: Arrivals shuttles no longer throw objects/players when docking. + - bugfix: Regular fedoras no longer spawn containing flasks. + - tweak: Increased the range of handheld T-ray scanners. + - balance: Cargo bounties that request irreplaceable items have been removed. + Garen: + - balance: Throwers no longer deal damage + - balance: Flashlight circuits are now the same strength as a normal flashlight + - balance: Grabber circuits are now combat circuits + - rscdel: Removed smoke circuits + - rscdel: Removed all screens larger than small + - tweak: Ntnet circuits can no longer specify the passkey used, it instead always + uses the access + Hate9: + - rscadd: Added pulse multiplexer circuits, to complete the list of data transfers. + Jared-Fogle: + - rscadd: NanoTrasen now officially recognizes Moth Week as a holiday. + - rscdel: Temporarily removes canvases until someone figures out how to fix them. + Mickyan: + - balance: Social anxiety trigger range decreased. Stay out of my personal space! + - bugfix: Social anxiety no longer triggers while nobody is around but you + WJohnston: + - rscadd: Redesigned the metastation white ship as a salvage vessel. + YoYoBatty: + - bugfix: SMES power terminals not actually deleting the terminal reference when + by cutting the terminal itself rather than the SMES. + - bugfix: SMES now reconnect to the grid properly after construction. + - refactor: SMES now uses wirecutter act to handle terminal deconstruction. + ninjanomnom: + - bugfix: Objects picked up from tables blocking throws will no longer be forever + unthrowable diff --git a/html/changelogs/archive/2018-08.yml b/html/changelogs/archive/2018-08.yml new file mode 100644 index 0000000000..3ee21a1a6f --- /dev/null +++ b/html/changelogs/archive/2018-08.yml @@ -0,0 +1,534 @@ +2018-08-01: + Basilman: + - rscadd: Added the stealth manual to the uplink, costs 8 TC. Find it under the + implant section + Cobby: + - spellcheck: Drone's Law 3 has been edited to explicitly state that it's for the + site of activation (aka people do not get banned for going to upgrade station + as derelict drones since it's explicitly clear now). See https://tgstation13.org/phpBB/viewtopic.php?f=33&t=18844&p=429944#p429944 + for why this was PR'd + - bugfix: PENLITEs are now actually spawnable in techwebs. Reminder to make sure + everything is committed before PRing haha! + Denton: + - tweak: New bounties have been added for the Firefighter APLU mech, cat tails and + the Cat/Liz o' Nine Tails weapons. + - bugfix: ExoNuclear mech reactors now noticably irradiate their environment. + - spellcheck: Adjusted suit storage unit descriptions to mention that they can decontaminate + irradiated equipment. + Hate9: + - rscadd: Added tiny-sized circuits (called Devices) + - imageadd: added new icons for the Devices + Iamgoofball: + - balance: 'Buzzkill Grenade Box Cost: 5 -> 15' + Shdorsh: + - rscadd: Text replacer circuit + SpaceManiac: + - bugfix: The bridge of the gulag shuttle now has a stacking machine console for + ejecting sheets. + Time-Green: + - rscadd: You can now mount energy guns into emitters + - bugfix: portal guns no longer runtime when fired by turrets + barbedwireqtip: + - tweak: Adds the security guard outfit from Half-Life to the secdrobe + granpawalton: + - tweak: Removed old piping sections and replaced with Canister storage area in + atmos incinerator + - tweak: scrubber and distro pipes moved in atmos incinerator to make room for added + piping + - balance: added filter at connector on scrubbing pipe in atmos incinerator + - balance: replaced vent in incinerator with scrubber in **Both** incinerators + - balance: mixer placed on pure loop at plasma + - bugfix: delta and pubby atmos incinerator air alarm is no longer locked at round + start + - bugfix: pubby atmos incinerator now starts without atmos in it + kevinz000: + - rscadd: 'Cameras now shoot from 1x1 to 7x7, fully customizable. Alt click on them + to change the size of your photos. experimental: All photos, assuming the server + host turns this feature on, will be logged to disk in round logs, with their + data and path stored in a json. This allows for things like Statbus, and persistence + features among other things to easily grab the data and load the photo.' + - rscadd: Mappers are now able to add in photo albums and wall frames with persistence! + This, obviously, requires photo logging to be turned on. If this is enabled + and used, these albums and frames will save the ID of the photo(s) inside them + and load it the next time they're loaded in! Like secret satchels, but for photos! +2018-08-03: + ArcaneMusic: + - soundadd: Added a new, shoutier RoundEnd Sound. + Basilman: + - bugfix: fixed agent box invisibility + Denton: + - tweak: 'Syndicate lavaland base: Added a grenade parts vendor and smoke machine + board. The testing chamber now has a heatproof door and vents/scrubbers to replace + air after testing gas grenades. Chemical/soda/beer vendors are emagged by default; + the vault contains a set of valuable Syndicate documents.' + - tweak: Added a scrubber pipenet to the Lavaland mining base. + Garen: + - bugfix: mobs now call COMSIG_PARENT_ATTACKBY + JJRcop: + - rscadd: Deadchat can use emoji now, be sure to freak out scrying orb users. + Kmc2000: + - rscadd: You can now attach 4 energy swords to a securiton assembly instead of + a baton to create a 4 esword wielding nightmare-bot + Mickyan: + - imageadd: added sprites for camera when equipped or in hand + - tweak: cameras are now equipped in the neck slot + SpaceManiac: + - bugfix: Traps now have their examine text back. + Supermichael777: + - bugfix: Cigarettes now always transfer a valid amount of reagents. + - bugfix: Reagent order of operations is no longer completely insane + WJohnston: + - tweak: Added a gun recharger to delta's white ship and toned it down from a "luxury" + frigate to just a NT frigate, it's just not made for luxury! + XDTM: + - bugfix: Beheading now works while in hard crit, so it can be used against zombies. + - tweak: You can now have fakedeath without also being unconscious. Existing sources + of fakedeath still cause unconsciousness. + - rscadd: Zombies and skeletons now appear as dead. Don't trust zombies on the ground! + - rscadd: You can now make Ghoul Powder with Zombie Powder and epinephrine, which + causes fakedeath without uncounsciousness. + granpawalton: + - bugfix: pubby round start atmos issues resolved + - bugfix: pubby departures lounge vent is no longer belonging to brig maint + - rscadd: pipe dispenser on pirate ship + ninjanomnom: + - bugfix: The first pod spawned had some issues with shuttle id and wouldn't move + properly. This has been fixed. +2018-08-06: + Basilman: + - balance: Increased agent box cooldown to 10 seconds + Denton: + - bugfix: Omegastation's Atmospherics lockdown button now has the proper access + reqs. + - bugfix: Pubbystation's disposals conveyor belts now face the correct direction. + - bugfix: Pubby's service techfab is no longer stuck inside a wall. + - bugfix: Pubby's disposal loop is no longer broken. + - tweak: The Lavaland seed vault chem dispenser now has upgraded stock parts. + - tweak: 'Metastation: Extended protective grilles to partially cover the Supermatter + cooling loop.' + Epoc: + - rscadd: You can now show off your Attorney's Badge + Garen: + - bugfix: Fixed AddComponent(target) not working when an instance is passed rather + than a path + JJRcop: + - bugfix: Fixed some strange string handling in SDQL + Jared-Fogle: + - rscadd: Moths can now eat clothes. + JohnGinnane: + - rscadd: Users can now see their prayers (similar to PDA sending messages) + Mickyan: + - tweak: Drinking alcohol now improves your mood + Shdorsh: + - bugfix: The previously-added find-replace circuit now actually exists. + Tlaltecuhtli (and then Cobby): + - bugfix: Science Bounties are now available! + WJohnston: + - balance: Rebalanced the simple animal syndies on the metastation ship to be a + bit less destructive of their surroundings, and downgraded the smg guy to a + pistol and upgraded the other guys to knives. + Y0SH1 M4S73R: + - rscadd: windoors now have NTNet support. The "open" command toggles the windoor + open and closed. The "touch" command, not usable by door remotes, functions + identically to walking into the windoor, opening it and then closing it after + some time. + cyclowns: + - tweak: Fusion has been reworked to be a whole lot deadlier! + - tweak: You can now use analyzers on gas mixtures holders (canisters, pipes, turfs, + etc) that have undergone fusion to see the power of the fusion reaction that + occurred. + - balance: Several gases' fusion power and fusion's gas creation has been reworked + to make its tier system more linear and less cheese-able. +2018-08-07: + WJohnston: + - rscadd: Redesigned the pirate event ship to be much prettier and better fitting + what it was meant to do. +2018-08-08: + Denton: + - rscadd: 'Added five new cargo packs: cargo supplies, circuitry starter pack, premium + carpet, surgical supplies and wrapping paper.' + - tweak: Added one bag of L type blood to the blood pack crate. Added a chance for + contraband crates to contain DonkSoft refill packs. + Iamgoofball: + - tweak: The Stealth Implant was mistakenly made nuclear operatives only due to + a misunderstanding of the code. This has been fixed. + Mark9013100: + - rscadd: Pocket fire extinguishers can now be made in the autolathe. + SpaceManiac: + - bugfix: The power flow control console once again allows actually modifying APCs. + - tweak: Gas meters will now prefer to target visible pipes if they share a turf + with hidden pipes. + daklaj: + - bugfix: fixed beepsky and ED-209 cuffing their target successfully even when getting + disabled (EMP'd) in the process + kevinz000: + - rscadd: Catpeople are now a subspecies of human. Switch your character's species + to "Felinid" to be one. + - rscadd: Oh yeah and they show up as felinids on health analyzers. +2018-08-10: + AnturK: + - balance: Portable flashers won't burnout from failed flashes. + Denton, Tlaltecuhtli: + - rscadd: Added cargo bounties that require cooperation with Atmospherics, Engineering + and Mining. + Naksu: + - bugfix: Transformation diseases now properly check for job bans where applicable + - code_imp: Fixed a bunch of runtimes that result from transforming into a nonhuman + from a human, or a noncarbon from a carbon. + SpaceManiac: + - refactor: The map loader has been cleaned up and made more flexible. + nicbn: + - tweak: 'BoxStation science changes: Circuitry lab is closer to RnD now; cannisters, + portable vents, portable scrubbers, filters and mixers have been moved to Toxin + Mixing Lab. There is now a firing range at the testing lab!' +2018-08-11: + Denton: + - tweak: Fixed the Beer Day date and added a few more holidays. + Jordie0608: + - admin: Asay history is once again logged under the admin log secret. + - admin: Notes, messages, memos and watchlists can now have an expiry time. Once + expired they are hidden like as if deleted. + SpaceManiac: + - tweak: Giant spiders can now freely pull their victims through webs. + Time-Green: + - rscadd: Circuit Boards now tell you the components required to build them on examine + WJohn: + - rscadd: Added zombies to boxstation's abandoned ship. + YPOQ: + - bugfix: AIs can take photos and print them at photocopiers again. + - bugfix: Cult floors will not deconstruct to space + - bugfix: Cult floors do not spawn rods when deconstructed + - bugfix: Footprints should no longer spread out of control + zaracka: + - bugfix: blunt trauma causes brain damage while unconscious too + - bugfix: sharp weapons no longer count as blunt trauma in all cases +2018-08-12: + Denton: + - rscadd: Killing gondolas now lets you harvest meat from them. Eating it raw might + be a bad idea. + Mickyan: + - rscadd: Mixed drinks now give mood boosts with varying strength depending on their + quality. + - rscadd: Although powerful, mood boosts from quality drinks are short lived. If + you want to make the most out of them, take a sip every few minutes like a normal + human being instead of downing the entire glass like the alcoholic you are. + Nichlas0010: + - bugfix: Admins with +admin and without +fun are no longer able to smite. + SpaceManiac: + - bugfix: Blood and oil footprints sharing a tile no longer causes footprint decals + to stack. + WJohnston: + - balance: Syndicate (melee) simple animals will now move less predictably and attack + twice as often, hopefully making them quite a bit more dangerous. + XDTM: + - tweak: Operating Computers can now sync to the research database to acquire researched + surgeries, instead of requiring installation by disk. + - rscadd: You can now review the full list of unlocked surgeries from the operating + computer. + actioninja: + - rscadd: Added (unobtainable) Felinid Mutation Toxin. + lyman: + - imageadd: Updated the Chronosuit Helmet sprite. +2018-08-13: + Basilman: + - rscadd: Adds Arnold pizza, dont try putting pineapple on it. + Denton: + - tweak: The briefcase launchpad can now hold items while in briefcase mode (just + like a regular briefcase). Its remote has been disguised as a folder and now + spawns pre-linked inside the briefcase. + - balance: Increased the briefcase launchpad's range from 3 to 8 tiles, which is + roughly half the screen. + - spellcheck: Added more ingame manuals that access wiki pages. + - rscadd: Added botanical and medical bounties as well as a static adamantine bar + bounty. + - tweak: Increased the syndicate document bounty's reward from 10.000 to 15.000 + credits. + - tweak: Removed the gondola hide bounty and in return, increased the export value + to the old level. + - tweak: The briefcase bounty now also accepts secure briefcases. + - bugfix: The action figure bounty now correctly spawns as an assistant type bounty. + Logging refactor and improvement: + - code_imp: All mob-related logs now include the area name and (x,y,z) position. + - code_imp: All logs that included an (x,y,z) position now also include the area + name. + - code_imp: Standardized logging format of mob/player keys. + - code_imp: Telecomms logs are now included in the individual logging panel. + - code_imp: Fixed many other cases of logs being sent to either the individual logging + panel or the saved log files, but not both. + - refactor: The logging system has been refactored to contain less redundant code + and to produce more consistent logs. + SpaceManiac: + - admin: The VV window loads and searches faster. + - admin: Fields in the VV window's header will immediately show your edits. + - admin: Selecting an action from the VV dropdown no longer leaves it selected after + the action is done. + YPOQ: + - bugfix: Uncalibrated teleporters can turn humans into flies again +2018-08-14: + Coolguy3289: + - config: Removed un-needed and un-used RENAME comment from game_options.txt + SpaceManiac: + - bugfix: Escape Pod 1 now reaches the CentCom recovery ship again. + WJohn: + - imageadd: Titanium walls and windows are a bit prettier looking now. + Zxaber: + - rscadd: Airlock electronics can have now have unrestricted access by direction + set. The resulting airlock will allow all traffic from the specified direction(s) + while still requiring normal access otherwise. A small floor light will indicate + this. + - tweak: Medbay Cloning and Main Access doors now have unrestricted access settings + set, and the buttons have been removed. All maps have been updated. + - bugfix: Airlocks now correctly update their overlays (bolts lights, emergency + lights) when their power state changes. +2018-08-15: + barbedwireqtip: + - tweak: added binoculars to the detective's locker +2018-08-17: + Anonmare: + - rscadd: Ore silos circuit boards are now constructable + SpaceManiac: + - admin: The "Map Template - Upload" verb now reports if a map uses nonexistent + paths. + Tlaltecuhtli: + - bugfix: fixes diamond drill bounty having the wrong object path + YPOQ: + - bugfix: Roundstart motion-detecting cameras work again + intrnlerr: + - bugfix: '"Allows image windows sent by PDA to be closed"' +2018-08-18: + Floyd / Qustinnus: + - code_imp: moves nutrition events to the mood component + Jared-Fogle: + - rscadd: Hovering over storage slots with an item in your hand will show you first + if you can put the item in. + XDTM: + - bugfix: Fixed augmentation not working and/or giving you extra limbs + nicbn: + - imageadd: New janitor cart sprites (by Quantum-M) + - imageadd: Dirt is smooth (by AndrewMontagne) + zaracka: + - bugfix: You can now use certain emotes and the suicide verb while buckled, but + not while stunned. +2018-08-20: + Basilman: + - rscadd: Added gondola fur products + Basilman, Sprites by WJohnston: + - rscadd: His Grace ascension is back, feed Him 25 people and you will unlock His + full potential. + Denton: + - tweak: Added new destinations for the parcel tagger! You can now send packages + to the Circuitry Lab, Toxins, Dormitories, Virology, Xenobiology, Law Office + and the Detective's office. Viro/Xeno can only receive parcels. + - bugfix: 'Deltastation: Tagged parcels no longer get routed straight into the crusher. + Untagged parcels also no longer get routed straight into the crusher!' + - tweak: 'Deltastation: Added disposals to Xenobiology that launch contents into + space.' + Epoc: + - tweak: Putting an extinguisher into a cabinet with the safety off will no longer + cause it to spray first + Floyd / Qustinnus: + - code_imp: removes useless mood events subtypes + - bugfix: 'fixes mood event timers not resetting when they get triggered again remove: + removes the depression overlay which makes our fruit happy' + Frosty Fridge: + - rscadd: Added the Surgical Processor upgrade for medical cyborgs. Scan surgery + disks or an operating computer to be able to initiate advanced procedures. + - tweak: Cyborgs can now perform surgery steps that do not require an instrument. + - bugfix: Plastic creation reaction now properly scales with the amount of reagents; + 10u = 1 sheet. + Garen: + - bugfix: fixed using items on a circuit removing all its access(now access gained + from each new item stacks) + - admin: adds logging for gun circuits, grabber circuits, and dragging claw circuits + - rscadd: grabbers can select what they want to drop + MrDoomBringer: + - imageadd: The Nanotrasen Airspace Aesthetics division has shipped out a newer + design of NT-Brand "Ore Silos". No new features have been added, but they certainly + look much nicer! + Naksu: + - balance: Having a high body temperature now increases the damage you take gradually, + whether you're on fire or not. Being on fire also always increases body temperature + damage + NewSta: + - tweak: The names of haircuts, facial hair, undershirts, underwear and socks have + now been sorted and categorized + WJohnston: + - imageadd: Remade titanium and plastitanium floors to be less of an eye strain + and something mappers might actually consider using. + - imageadd: New reinforced floor sprites. + XDTM: + - rscadd: Added programmable nanites to science! + - rscadd: Science now has a nanite chamber, a nanite program hub, a nanite cloud + console and a nanite programmer. + - rscadd: From the program hub you can download nanite programs (unlocked through + techwebs) to disks. + - rscadd: You can then customize their functionality and signal codes through the + Nanite Programmer. + - rscadd: The nanite chamber is necesary to inject nanites into a patient, and it's + also used to install/uninstall programs into a patient's nanites. A second person + is required to man the console. + - rscadd: The nanite cloud console controls remote program storage; it stores program + backups that nanites can be synced to through cloud IDs. + - rscadd: Nanite programs range can be either helpful or harmful; their main potential + is that they can be enabled at will through the use of remotes and sensors. + The potential uses are endless! + - rscadd: More detailed information is available in the wiki. +2018-08-22: + BlueNothing: + - rscadd: Allows video camera circuits to be seen on networks other than the science + cameranet. + - tweak: Alphabetizes camera list for camera bugs, and lets camera bugs see through + borg and circuit cameras. + - tweak: Makes video camera circuits fit in tiny assemblies. + PKPenguin321: + - tweak: The GPS circuit now has a 4th output, placing X,Y,Z all in a string. + - rscadd: '2 new converters: Rel to Abs, and Advanced Rel to Abs.' + - rscadd: Rel to Abs takes a set of relative and a set of absolute coordinates, + and converts the relative one to absolute. 1 complexity. + - rscadd: Advanced Rel to Abs takes a set of relative coordinates and converts it + to absolute without the need for an already known set of absolute coordinates. + 2 complexity. + SpaceManiac: + - bugfix: Freezers and heaters which start on no longer stay visually on when you + turn them off. + - code_imp: Atmospherics now initializes 93% (about 40 seconds) faster. + floyd: + - bugfix: fixes the hunger alert appearing forever + intrnlerr: + - bugfix: Tank temperature is no longer based on pressure + ninjanomnom: + - bugfix: Shuttle templates now handle shuttle registration in the load rather than + the shuttle manipulator. This means admin loaded shuttle templates no longer + need to be manually registered. + oranges: + - tweak: Inventory overlay now uses a traffic light to indicate if the item can + be placed in there +2018-08-23: + Naksu: + - code_imp: Waddling is now available as a component + Nervere: + - rscadd: re-adds the joy emoji. + SpaceManiac: + - rscadd: The body zone selector now indicates which body part you are about to + select when hovered over. + - code_imp: Transit space initializes about five seconds faster. + Tlaltecuhtli: + - balance: Cyborg ion thrusters consume 1/5 of their previous power. +2018-08-25: + Denton: + - rscadd: Added missing export rewards for various lavaland items (tendril/megafauna/ruins) + and engine parts. + - balance: Increased export values for emitters, PA parts, field generators and + radiation collectors to match the rest of engineering exports. Reduced supermatter + shard value by 1000 credits. + - rscdel: Removed export rewards for red/blue warp cubes since they're blacklisted + from the cargo shuttle. + - tweak: Added private intercoms to the confession booths of the Deltastation+Pubbystation + chapels. + - bugfix: Fixed invalid radio frequencies on interrogation chamber/confession booth + intercoms. + - tweak: Anime is even more horrifying than previously discovered! + - rscadd: Added a new shuttle loan event where crew can get paid for having an active + syndicate bomb delivered to cargo bay. + Mickyan: + - bugfix: Blue polo undershirt option has been restored + - tweak: underwear "nude" option moved to the top of the list + SpaceManiac: + - code_imp: The map loader now supports vars to be set to lists containing non-strings. + - bugfix: Overcharging energy guns no longer crashes the server. + - bugfix: Ordering the Build Your Own Shuttle kit no longer crashes the server. + The Dreamweaver: + - code_imp: Refactored gift code to fix a minor inefficiency. + XDTM: + - bugfix: Fixed chest and head augmentation not working properly. +2018-08-26: + CitrusGender: + - admin: Added note severity to [most] bans and the notes associated with them + - admin: 'Banning panel now has a severity option UI: Changed the UI of the note + panel UI: Changed the UI again, added some icons, removed brackets in urls, + fading out notes cannot be selected to expand the browser anymore' + Floyd / Qustinnus (Credits to KMC for the sprites): + - rscadd: The Clown Car, your 18TC clown-only solution to asshole co-workers + - rscadd: Regular car implementation (makes it easier to add more cars if someone + actually feels like adding those) + JJRcop: + - admin: 'Asay logs show "ADMINPRIVATE: ASAY:" again instead of just "ADMINPRIVATE:"' + Naksu: + - code_imp: living and stack typecaches now use a shared instance where it makes + sense, giving small memory savings + PKPenguin321: + - rscadd: Integrated circuit medium screens have been readded. They are now called + large screens. They now only work from your hands or on the ground when you're + standing on top of them (NOT from pockets, lockers, backpacks, etc). + - bugfix: Roundstart cyborgs will now be properly referred to as "it." + SpaceManiac: + - admin: The shuttle manipulator now allows flying any shuttle to any port which + will fit it. + - bugfix: The shuttle manipulator now allows fast-travelling shuttles with 5s remaining, + down from 50s. + - refactor: Status displays have been refactored to be cleaner and more flexible. + - bugfix: The AI dying properly updates its status displays again. + intrnlerr: + - refactor: Refactored nettles to be reagent_containers + nicbn: + - soundadd: Nanotrasen shoes no longer contain Silencium. Now footsteps make noise! + Sounds from Baystation. +2018-08-28: + Denton: + - bugfix: The 10 second anti spam cooldown of night shift lighting now works properly. + - spellcheck: Added an examine message to APCs that mentions Alt-click and Ctrl-click + (silicons only) behavior. + Garen: + - code_imp: adds a signal for screwdriver_act + SpaceManiac: + - code_imp: Multiple copies of a shuttle each get their own area instances (affects + APCs and air alarms). + XDTM: + - rscadd: The forcefield projector is now available ingame in the engineering protolathe. + It can project up to 3 forcefields which act as transparent walls, and share + a pool of health which is recharged over time. The projector must remain within + 7 tiles of the forcefields to keep them active. +2018-08-31: + Anonmare: + - bugfix: AIs can now turn shield generators on and off again + Denton: + - bugfix: Plastic golems can no longer vent crawl with items in their pockets. + Mickyan: + - balance: Skateboards can fit in backpacks + - tweak: Skateboards are slower by default, speed can be adjusted by alt-clicking + - rscadd: 'Show your support for the fine arts with these new quirks:' + - rscadd: 'Tagger: drawing graffiti takes half as many charges off your spraycan/crayon' + - rscadd: 'Photographer: halves the cooldown after taking a picture' + - rscadd: 'Musician: tune instruments to temporarily give your music beneficial + effects such as clearing minor debuffs and improving mood.' + Skoglol: + - bugfix: Dispensers can now add 5u to buckets, plastic beakers and metamaterial + beakers, down from 10u. + - bugfix: You can now pour 5u from buckets, plastic beakers and metamaterial beakers, + down from 10u. + - bugfix: Chem dispenser window width increased slightly, no longer shuffles buttons + when scroll bar appears. + The Dreamweaver: + - bugfix: Sentience Potions no longer require you to have Xenomorph toggled on in + preferences and now relies on its own preference in order to be notified of + open roles. + - code_imp: Split xenomorph, intelligence potions, and mind transfer potions into + separate roles for more precise role management. + - admin: Sentience Potion Spawns and Mind Transfer Potions are now job-bannable + roles. + Time-Green and locker sprites by MrDoomBringer: + - rscadd: Reports have come in that the wizard federation has harnessed some of + the ancient locker force to create a wand + XDTM: + - rscdel: Removed the chance of spouting brain damage lines when over 60 brain damage. + The dumbness trauma still has them. + - bugfix: Fixed Mechanical Repair nanites not working. + ninjanomnom: + - rscadd: Computers are now visible even in the darkest of rooms. Comfy! + - tweak: Because computers are now far easier to find in dark rooms their base light + output has been reduced. + - bugfix: Broken components left over from the signal origin refactor should be + fixed. + - bugfix: Lava isn't a safe place to throw your flammable shit anymore + - bugfix: The computer screen overlay being rotated incorrectly after construction + has been fixed. diff --git a/html/changelogs/archive/2018-09.yml b/html/changelogs/archive/2018-09.yml new file mode 100644 index 0000000000..8c438a3b7f --- /dev/null +++ b/html/changelogs/archive/2018-09.yml @@ -0,0 +1,782 @@ +2018-09-01: + ElPresidentePoole: + - rscdel: removes curator's fear of snakes + McDonald072: + - bugfix: Defibrillator nanites work properly. + Poojawa: + - bugfix: fixed clothing vendor fedoras having Detective Fedora grade armor + Potato Masher: + - tweak: The color of Wooden golems should be more in line with the color of the + wood used to make it. + WJohnston: + - imageadd: Reinforced floors are now shinier. +2018-09-02: + Denton: + - spellcheck: Fixed species type names that show up on health scanners. +2018-09-03: + Cdey78 (Ported by Floyd / Qustinnus): + - imageadd: AI can now think + - imageadd: 'New OOC emote: :thinking:!' + Naksu: + - admin: a new admin secret has been added to create a customized portal storm + Shdorsh: + - tweak: Makes it possible to create circuits that can get an item loaded into them + while they are in an assembly and the assembly is open. + - code_imp: Optimized electronic assemblies also. + - bugfix: A bug pertaining putting batteries in assemblies + Skoglol: + - bugfix: Eggplant and egg-plant seeds now have different names and plant names. + XDTM: + - bugfix: Fixed nanite cloud storage not allowing uploads. + octareenroon91: + - admin: Supermatter more likely to log fingerprintslast when it consumes any object. +2018-09-04: + Denton: + - spellcheck: Mech construction messages no longer incorrectly mention high-tier + stock parts. + - tweak: Added a nanite lab to Deltastation! It's at the old EXPERIMENTOR lab. + - tweak: 'Delta: Moved the Xenobiology disposals bin to be less obstructive. Added + two sets of insulated gloves to Engineering.' + - bugfix: 'Delta: Fixed scientists not having maintenance access near the circuitry + lab and toxins launch chamber.' + Shdorsh: + - code_imp: Made all the extinguishers use less sleep and spawn procs +2018-09-27: + Alexch2: + - spellcheck: Fixes tons of typos related to integrated circuits. + - tweak: Re-writes the descriptions of a few parts of integrated circuits. + 'Armhulen code, Keekenox sprites and S_____ as the ideas guy :roll_eyes:': + - rscadd: 'New drinks: Peppermint Patty and the Candyland Extract!!' + Astatineguy12: + - tweak: The experimentor is less likely to produce food when it transforms an item + - bugfix: The experimentor no longer breaks when the toxic waste malfunction occurs + multiple times and isn't cleaned up + - bugfix: The experimentor irridiate function actually chooses what item to make + properly rather than picking from the start of the list + - bugfix: The mime blockade spell now shows up under the right tab + Beachsprites: + - imageadd: added directional beach sprites + Big Tobacco: + - rscadd: Cheap lighters now come in four different shapes and Zippos can have one + of four different designs, collect them all and improve our sales! + - imageadd: All existing lighter sprites have been given a face-lift and the flames + are now subtly animated. + - tweak: Cheap lighters now use a fixed list of 16 colors to pick from instead of + using totally randomized colors. + - imageadd: Cigar cases have been tweaked to be a bit smaller and to have a modified + design. + - imageadd: Cohiba Robusto and Havanan cigars now use separate case sprites from + the generic premium cigar cases. + CameronWoof: + - tweak: Quartermaster added to the list of changeling and traitor restricted jobs + CitadelStationBot: + - bugfix: The faint echoes of maracas grows louder, as if a past spirit once forgotten + has come back with a vengeance... + - bugfix: Removing an ID card from a wallet now properly removes its visual and + accesses. + - tweak: You may now take unlimited neutral and negative quirks + - tweak: the walls on the crashed abductor ship ruin in lavaland can now be broken + down + - bugfix: Pipe icons in the RPD now show properly in older versions of IE. + - bugfix: Removing an ID from a PDA in a backpack no longer hides the ID until something + else updates. + - bugfix: Opening and closing airlocks repeatedly no longer stacks queued autocloses. + - bugfix: Mindswapping with someone else no longer forces ambient occlusion on. + - bugfix: Admin AI interaction now works properly on firelocks. + - code_imp: IRV polls now use the same version of jQuery as everything else. + - rscadd: You can now view your last round end report window with the "Your last + round" verb in the OOC tab + - bugfix: Hydroponics trays can no longer be deconstructed with their panels closed + or unanchored while irrigated. + - tweak: Frames for machines which do not require being anchored can now be un/anchored + after the circuit has been added. + - spellcheck: Fix "Your the wormhole jaunter" when a wormhole jaunter saves you + from a chasm. + - rscadd: Analyzers can now scan all kinds of atmospheric machinery - unary, binary, + ternary, quaternary, you name it. This means stuff like gas pumps, gas mixers, + vents and so forth can be analyzed. + - tweak: Analyzers now show temperature in kelvin as well as celsius. + - tweak: Analyzers now show total mole count, volume, and mole count of all gases. + - tweak: Analyzers show everything at slightly higher degrees of precision. + - rscadd: Any anomaly core can now be deconstructed for a one time boost of 10k + points in the deconstructive analyzer. + - bugfix: Chasms no longer drop mobs buckled to undroppable mobs or objects. + - bugfix: Digital valves are once again operable by silicons. + - bugfix: Field generators are once again operable by adjacent cyborgs. + - bugfix: Entertainment monitors now view the real Thunderdome rather than the template. + - bugfix: Flipping and then rotating trinary pipe fittings no longer causes their + icon to mismatch what they will become when wrenched. + - bugfix: RPD tooltips for flippable trinary components have been corrected. + - bugfix: The green overlay indicating where a map template will be placed is no + longer invisible on space turfs. + - bugfix: Frost spiders now correctly inject frost oil on bite. + - bugfix: Inserting materials into protolathes with telekinesis is now possible. + - bugfix: Telekinesis no longer teleports items removed from deep fryers, constructed + sandbags, and leftover materials not inserted into lathes. + - bugfix: Telekinetic sparkles now appear in the correct place when clicking on + a turf and when clicking in the fog of war in widescreen. + - bugfix: Telekinetically adjusting power tools no longer causes them to exit the + universe. + - tweak: Examining a telekinetic grab in-hand will now examine the grabbed object. + - bugfix: Non-harmfully placing someone who is resting on a table no longer makes + them get up. + - bugfix: The disco machine no longer lags the chat by spamming "You are now resting!" + messages. + - tweak: Clicking on the viewport to focus it no longer leaves the input bar red. + - bugfix: Running diagonally into space now properly continues the diagonal movement + in zero-gravity. + - bugfix: Moving diagonally past delivery chutes, transit tube pods, &c. no longer + causes your camera to be stuck on them. + - config: The limit of monkey's spawned via monkey cubes is now configurable + - bugfix: Fixes cyborgs not being able to use two-handed modules while other modules + are equipped. + - bugfix: Pubby's auxiliary mining base now works again. + - bugfix: The overlay effects of cult flooring are now on the floor plane, fixing + their odd ambient occlusion appearance. + - bugfix: Cloning no longer breaks a character's connection to their family heirloom. + - bugfix: Beam rifle tracers no longer fall into chasms. + - bugfix: Vomiting on the same tile a second time no deletes the vomited reagents. + - bugfix: fixed the clockwork helmet not dropping to ground when used by non-clock + cultists + - refactor: The base machinery type is now anchored by default. + - bugfix: PDA style now gets loaded correctly. + - bugfix: Switching mobs into/out of a mech (by VR, ghosting, or mindswap) no longer + improperly applies the mech's cursor. + - tweak: roboticists have access to R&D windoors + - tweak: switched the type of the space suit on the syndicate shuttle + - bugfix: fixed hydroponics tray weed light staying on when removing weeds with + integrated circuits + - bugfix: Atom initialization and icon smoothing no longer race, causing late-loading + mineral turfs to have no icon. + - spellcheck: Faceless persons no longer "melt their face off" in energy gun suicides. + - bugfix: The Lightning Bolt spell now works again. + - tweak: Vehicle speed changes now happen immediately instead of on the next movement + cycle + - bugfix: Picture-in-picture objects now are no longer overlapped by other certain + objects + - bugfix: A pAI dying while in holoform no longer deletes the card, instead merely + emptying it. + - bugfix: The thermal sight benefits of lantern wisps no longer disappear if you + change glasses. + - imageadd: sandstone wall sprite for indestructible object + - bugfix: Stabilized gold extracts now respawn the familiar properly. + - bugfix: Stabilized gold familiars retain the proper languages even after respawning. + - tweak: Stabilized gold familiars can be renamed and have their positions reset + at will. + - bugfix: Pulling objects diagonally no longer causes them to flail about when changing + directions. + - bugfix: Riders are no longer left behind if you move while pulling something that + has since been anchored. + - tweak: Fire alarms now redden all the room's lights, and emit light themselves, + rather than applying an area-wide overlay. + - bugfix: Fire alarms no longer visually conflict with radiation storms. + - bugfix: Plasmamen now receive their suit and internals when entering VR. + - bugfix: Deaf people can no longer hear cyborg system error alarms. + - bugfix: Lockboxes are now actually locked again. + - bugfix: Legion cores and admin revives now heal confusion. + - bugfix: checks to see if bullets are deleted if they are the ammo type and the + bullet chambered. + - spellcheck: Capitalization, propriety, and plurality on turfs have been improved. + - bugfix: Unbreakable ladders are now left behind when shuttles move. + - rscadd: Players who edited a circuit assembly can scan it as a ghost. + - bugfix: It is no longer possible to pull the mirages images at space transitions, + and some other abstract effects. + - bugfix: Moving large amounts of items with bluespace launchpads no longer creates + a laggy amount of sparks. + - bugfix: The escape pod hallways on MetaStation and DeltaStation now have air again. + - bugfix: It is no longer possible to repair cyborg headlamps even when their panel + is closed. + - bugfix: Item fortification scrolls no longer add multiple prefixes when applied + to the same item. + - tweak: The blob core (and only the blob core) now respawns randomly on the station + when the core is taken off z-level + - bugfix: Prevents the round from going into an unending state + - code_imp: Added a variable to the stationloving component for objects that can + be destroyed but not moved off z-level + - rscadd: After years of protests NT decided to update the fire security standards + by adding 3 (three) advanced fire extinguishers to all the new stations. + - bugfix: Hyperspace ripples now remain visible until the shuttle arrives, even + during extreme lag. + - bugfix: Ripples now correctly take the shape of the shuttle, rather than always + being a rectangle. + - bugfix: Non-secure windoors now properly support the "One Required" access mode + of airlock electronics. + - bugfix: The gulag shuttle no longer moves instantly when returned via the claim + console. + - admin: It is now possible to use the ".p" (Asay) and ".d" (Dsay) prefixes while + an admin ghost. + - admin: Speaking in deadchat now shows your rank instead of ADMIN + - rscadd: Added a pink scarf to vendomats + - rscadd: Players can now ctrl-click the PDA to remove the item in its pen slot + - bugfix: added a clamp so you can't set a negative multiplier to create materials + and create more than 50 items. + - bugfix: anomaly cores no longer tend to dust + - spellcheck: Plant disks with potency genes clarify the percent is for potency + scaling and not relative to max volume on examine. + - rscadd: Blast cannons have been fixed and are now available for purchase by traitorous + scientists for a low low price of 14TC. + - rscadd: 'Blast cannons take the explosive power of a TTV bomb and ejects a linear + projectile that will apply what the bomb would do to a certain tile at that + distance to that tile. However, this will not cause breaches, or gib mobs, unless + the gods (admins) so will it. experimental: Blast cannons do not respect maxcap. + (Unless the admins so will it.)' + - rscadd: Cyborgs now drop keys on deconstruction/detonation + - bugfix: The "Save Logs" option in the chat now actually works (IE 10+ only). + - bugfix: Fixed cyborgs not getting their names at round start + - bugfix: Fixed cyborgs and A.I.s being able to bypass appearance bans + - bugfix: fixes cult shuttle message repeating + - bugfix: Hardsuit helmets now protect the wearer from pepperspray + - bugfix: It is once again possible for Cargo to export mechs. + - tweak: tourettes doesnt stack on itself anymore + - refactor: AI static now uses visual contents and should perform better in theory. + - bugfix: Bucket helmets cannot have reagents transferred into them until after + they are removed + - rscadd: R&D deconstructors can now destroy things regardless of if there's a point + value or material + - bugfix: You should now receive your destroy AI objectives properly during IAA + - bugfix: Deconstructable TEG now propertly connects to pipes. + - bugfix: Fix of inverted TEG sprite of slow turbine turning. add:Now you can flip + circulator and make TEG of your dream. add:Add TEG and circulator to "Advanced + Power Manipulation" techweb node. + - imageadd: New icon for plastic flaps that actually looks airtight. + - code_imp: Update to plastic flaps code to use tool procs rather than attackby + and removed two pointless states. + - bugfix: Printing the TEG and circulator boards no longer prints the completed + machinery instead. + - imageadd: Medical HUDs will now show an icon if the body has died recently enough + to be defibbed + Cobby: + - tweak: Decals are the exception to the recent removal of effects in Chameleon + Projectors. + - rscdel: Removed Advanced Mining Scanner from roundstart voucher kits. + - rscdel: Removed Explorer Webbing from all voucher kits besides the shelter capsule + pack. + - bugfix: Paper doesn't give illegal tech anymore + Cruix: + - rscadd: AIs now have an experimental multi-camera mode that allows them to view + up to six map areas at the same time, accessible through two new buttons on + their HUD. + Dax Dupont: + - bugfix: Fixes the wrong tiles in Syndicate VR trainer and uses different tiny + fans. + - bugfix: Access didn't append to VR IDs + - bugfix: Fixes missing curator hud icon. + - balance: Cult items will no longer be a long ride on the vomit coaster if picked + up by a non cultist. + - balance: Cult space bases are kill again. + - balance: Cult floors now pass gas. + - bugfix: Fixed a few things deconning into the wrong circuit. + - bugfix: You can no longer do infinite bioware surgery. + - bugfix: Foam no longer gives infinite metal + - bugfix: Mulligan didn't work on lizards and other mutants. Now it does. + - tweak: The BoH dialog now has Abort instead of Proceed as an default option. + - bugfix: Fixes accidental empty ahelp replies. + - balance: More chemicals can be found when vents get clogged. + - bugfix: Experimentor no longer shits out primed TB nades. + - bugfix: Fixed rpeds throwing stock part rating related runtimes. + - bugfix: Fixes a sentience related exploit by blacklisting it in restricted uplinks. + - bugfix: Botany trays don't magically refill anymore with a rped. + - balance: It's now easier to become fat. Don't eat so much. + - bugfix: Fixed missing grilles under brig windows of the pubby shuttle. + - rscadd: For the pubby shuttle, added some food in the fridge, mostly pie slices. + Also added a sleeper to the minimedbay. + - tweak: Reworded pubby shuttle description to be more inline with the new train + shuttle. + - refactor: Syndicate and Centcom messages have been squashed together. + - admin: You can now send both Syndicate and Centcom headset messages. Be mindful + that the button was changed to HM in the playerpanel + - bugfix: Fixes missing cream pies in the cream pie fridge. + - bugfix: Chem synths overlays aren't all kinds of fucked anymore. + - refactor: Unfucked all of the remaining chem synth code. + - refactor: Reagents no longer have an unused var that's always set to true. Who + did this? + - balance: Makes the xeno nest ruin harder to cheese. + - bugfix: Fixes the bathroom being airless in the Space Ninja anime jail. + - admin: Create antags now checks for people being on station before applying. + - admin: Malf AI machine overloads now are logged/admin messaged. + Denton: + - rscadd: APC/air alarm/airlock/fire alarm/firelock electronics are now available + once Industrial Engineering is researched.. + - tweak: Engi-Vend machines now contain fire alarm and firelock electronics! + - code_imp: Loose tech storage circuit boards have been replaced with spawners. + - code_imp: Added /syndicate subtypes for air alarms and APCs. + - bugfix: Added missing stock parts to the syndicate lavaland base. + - tweak: Added kitchen related circuit boards to the syndie lavaland base. + - tweak: There are rumors of the Tiger Cooperative adding a "special little something" + to some of their bioterror kits. + - code_imp: Loose silver/gold/solar panel crates have been replaced with "proper" + crates. + - balance: Skewium is much less likely to appear during the Clogged Vents event. + - bugfix: 'Navbeacon access requirements have been fixed: Now you need either Engineering + or Robotics access, but not both at the same time.' + - tweak: 'Pubbystation: Added a dual-port vent pump to the toxins burn chamber.' + - code_imp: Removed most airlock_controller/incinerator related varedits and replaced + them with defines/subtypes. + - tweak: The Deltastation toxins lab has its portable scrubber, air pump and intercom + back. + - bugfix: Swarmers can no longer attack field generators and turret covers. + - rscadd: Arcades have been stocked with preloaded tactical snack rigs. + - bugfix: The Pubbystation maint bar Booze-O-Mat now shows its contents correctly. + - tweak: Added a warning to the shuttle purchase menu. + - balance: Pirates and Syndicate salvage workers have been beefed up around the + caravan ambush ruin. + - tweak: NanoTours is proud to announce that the Lavaland beach club has been outfitted + with a dance machine, state of the art bar equipment and more. + - tweak: Did you know that honey has antibiotic properties? + - spellcheck: Improved supply shuttle messages and firefighting foam descs. + - bugfix: Supply shuttles will no longer spill containers on docking. + Dimmadunk: + - rscadd: 'There''s a new type of reagent added to the booze dispenser: Fernet. + With it you can make a couple of new digestif drinks that will help you reduce + excess fat!' + ElPresidentePoole: + - rscadd: SFX for seppuku (on all katanas) + - rscadd: suicide message for energy katanas ("cyber-seppuku") + - rscadd: suicide message for replica katanas ("seppuku") + Flatty: + - tweak: The blurry eye overlay has been replaced with an actual blur. + - tweak: The vending machine UI is now prettier. + Garen: + - rscadd: Thrower and Gun circuits put messages in chat when they're used. + - tweak: Only the gun assembly can throw/shoot while in hand + - imageadd: Adds inhands for the gun assembly + - bugfix: grabber inventories update when a thrower takes from them + GrayRachnid: + - rscadd: Adds private rooms to the ninja holding center + - rscadd: Along with a few things to make it more tolerable, but fear not. There + is now a suicide chamber for those who want the easy way out. + GuyonBroadway: + - rscadd: Adds gloves of the north star to the traitor uplink. Wearing these gloves + lets you punch people five times faster than normal. + - rscadd: Sprites for the gloves courtesy of Notamaniac + Hatterhat: + - tweak: The plasma formerly present in some execution syringes was replaced with + amatoxin. + Hyacinth: + - rscadd: Grenadine is now available in the bar! + - tweak: Tequila sunrises now require grenadine to make! + Iamgoofball: + - tweak: Lipolicide now only does damage if you're starving. + Improvedgay: + - balance: Naming immerions + Improvedname: + - rscadd: Adds rubbershot secrifle shots + JStheguy: + - rscadd: Added the data card reader circuit, a circuit that is able to read data + cards, as well as write to them. + - tweak: Data cards are now longer inexplicably called data disks despite clearly + being cards, and can be printed from the "tools" section of the integrated circuit + printer. + - tweak: Data cards no longer have a special "label card" verb and instead can have + their names and descriptions changed with a pen. + - rscadd: Also, some aesthetically different variants of the data cards, because + why not. + - imageadd: Data cards have new sprites, with support for coloring them via the + assembly detailer. + Jay: + - tweak: Bans CMO, RD, CE, and HoP from antag/ling + Jegub: + - imageadd: Glowcaps now have their own sprite. + Kor: + - rscadd: The Quartermaster and HoP can now access the vault so they can use the + bank machine. + - rscadd: Engineering can now create anomaly neutralizer devices, capable of instantly + neutralizing the short lived anomalies created by the supermatter engine. + - rscadd: Bubblegum has regained his original (deadlier) move set. + LetterN: + - bugfix: Fixes shock collars, they now fit on the neck slot + - bugfix: you can't put them on pockets anymore + MacHac: + - bugfix: Bedsheets once again properly influence the dreams of those who sleep + under them. + Mickyan: + - bugfix: Drinking too much Gargle Blaster, Nuka Cola or Neurotoxin no longer breaks + time and space. + - bugfix: Pacifists can now use harm intent for actions that require it (but still + can't harm!) + - spellcheck: fixed typo in bronze girder construction + - rscadd: 'New trait: Drunken Resilience. You may be a drunken wreck but at least + you''re healthy. If alcohol poisoning doesn''t get you, that is!' + - bugfix: Fixed pacifists being able to harm using bottles/screwdrivers + MrDoomBringer: + - imageadd: the VR sleeper action button has a sprite now + - admin: Central Command can now smite misbehaving crewmembers with supply pods + (filled with whatever their hearts desire!) + - admin: CentCom Supplypods now stun their target before landing, and won't damage + the station as much + Naksu: + - code_imp: clothing-specific flags are now defined in /obj/item/clothing.clothing_flags + - code_imp: More flags have been moved to their appropriate places + - code_imp: HEALS_EARS_2 is removed in favor of the earhealing component + - code_imp: wearertargeting component is available to subtype for components that + want to target the wearer of an item rather than the item itself + - code_imp: changed the shockedby list on doors to be only initialized when needed. + - tweak: Chameleon projector can no longer scan (often temporary) visual effects + like projectiles, flashes and the masked appearance of another chameleon projector + user + - bugfix: Drones can no longer see a static overlay over invisible revenants + - balance: adjusted default antag rep points to grant every job the same amount + of points per round, except for assistant which gets 30% less + - rscadd: Nuclear explosive-shaped beerkegs found on metastation can now be triggered + with the nuclear disk and the syndicate's legacy nuclear code for a foamy surprise + - bugfix: comms consoles now work in transit again, and no longer work in centcom + - code_imp: removed unnecessary getFlatIcons from holocalls + - bugfix: Screwdrivers and other items with overlays now show the proper appearance + of the item when attacking something with them, or when put on a tray. + - code_imp: moved /datum.isprocessing into datum flags + - code_imp: Removed unused effect object that could be used to spawn a list of humans + - tweak: The ladders in the tear in the fabric of reality no longer spawn their + endpoints when the area is loaded, but only when the tear is made accessible + via a BoH bomb. + - tweak: CentCom is no longer accessible via the space ladder in the tear. + - tweak: The lavaland endpoint can no longer spawn completely surrounded by lava, + unless it spawns on an island + - code_imp: ChangeTurf can now conditionally inherit the air of the turf it is replacing, + via the CHANGETURF_INHERIT_AIR flag. + - bugfix: when ladder endpoints are created, the binary turfs that are created inherit + the air of the turfs they are replacing. This means the lavaland ladder endpoint + will have the lavaland airmix, instead of a vacuum. + - code_imp: navigation beacons are now properly deregistered from their Z-level + list and re-registered on the correct one if moved across Z-levels by an effect + such as teleportation or a BoH-induced chasm. + - bugfix: constructed directional windows no longer leak atmos across them + - code_imp: setting the value of anchored for objects should be done via the setAnchored + proc to properly handle things like atmos updates in one place + Nicc: + - rscadd: toxins lab boii + Nichlas0010: + - tweak: Reseach Director Traitors can no longer receive an objective to steal the + Hand Teleporter + - bugfix: Comms consoles won't update while viewing messages + - spellcheck: you now feel nauseated instead of nauseous + - bugfix: You can no longer use a soapstone infinitely + - bugfix: You now can't get multiple download objectives! + - tweak: RDs, Scientists and Roboticists can no longer get download objectives! + Poojawa: + - tweak: Admin IC issue is no longer TG i ded passive aggressive. + - rscadd: Added *insult, for when you just can't think of anything more clever + - bugfix: Makes vore specific prefs call Rust_g else uses normal stuff. + - bugfix: Citadel Toggles should save properly now + - bugfix: fixed clothing vendor fedoras having Detective Fedora grade armor + - bugfix: Fixes missing icons on mag weapons for techmemes + - bugfix: Fixes APCs being replaced in maint from counting Maint as their wall turff + - rscadd: Added Vore based moodlets, primitive and ain't gunna adapt for not belly + things but w/e + Pubby: + - bugfix: 'PubbyStation: Fixed disposals issue in security hallway' + Robustin with cat earrs: + - bugfix: 'Gun overlays should be way less laggy now. remove: Chameleon guns are + completely removed since they crash the server, were already made unavailable, + and are the worst shitcode I''ve ever seen in my life.' + ShizCalev: + - bugfix: Adminorazine will no longer kill ash lizards. + - bugfix: Adminorazine will no longer remove quirks. + - bugfix: Fixed mobs immune to radiation being killed by HIGH bursts of radiation. + - bugfix: The book of mindswap will now properly mindswap it's users. + - bugfix: Fixed a runtime with the gulag teleporter that could cause the process + to fail if you removed the ID. + - tweak: Not setting the goal of a prisoner's ID when teleporting them will now + set the ID's goal to the default value (200 points at the time of this change.) + - bugfix: Fixed cigar cases & cigarette packets taking two inventory slots + - bugfix: Fixed cigar cases showing the wrong icon for the cigars inside them. + - bugfix: Fixed cigar cases & cigarette packets stating the wrong name of the cigar/cigarette + when removed via altclick. + - bugfix: Fixed items in pockets vanishing when a mob is monkeyized. + - bugfix: Fixed items in pockets vanishing when a mob is gorillized. + - bugfix: Fixed items in pockets vanishing when a mob is infected with a transformation + disease. + - bugfix: Fixed items in pockets not being properly deleted when a mob goes through + a recycler + - bugfix: Fixed items in pockets not being properly deleted when highlander mode + is enabled. + - bugfix: Fixed exploit allowing you to remove unremovable tanks from pockets. + - bugfix: Fixed items in pockets dropping when a mob is equipped with a new outfit. + - bugfix: Fixed items in pockets not being covered in blood when equipping the psycho + outfit. + SpaceManiac: + - bugfix: The destructive analyzer can once again be used to reveal nodes. + - spellcheck: Some references to "deconstructive analyzer" have been updated to + "destructive". + TGstation contributors: + - bugfix: Nukeop eshields are now buyable. tgstation/tgstation#39025 + - bugfix: Staff of storms now has admin logging. tgstation/tgstation#39011 + - bugfix: Fixed a couple of inconsistencies in the uplink descriptions of SMGs and + SMG ammo. tgstation/tgstation#38980 + - bugfix: Fixed blob victory. tgstation/tgstation#38988 + - tweak: You can now un-ignore notifications you've clicked "never this round" on, + and more. tgstation/tgstation#38990 + - bugfix: Fixes a weird bug with timers. tgstation/tgstation#38994 + - bugfix: (tgstation/tgstation#40043) - Beam rifles no longer open lockers + - bugfix: (tgstation/tgstation#40061) - Mobs can no longer get stuck at min/max + body temperature + - bugfix: (tgstation/tgstation#40041) - Pictures of asses are now properly sized + - bugfix: (tgstation/tgstation#40084) - The lastattacker var now includes unarmed + attacks + - bugfix: (tgstation/tgstation#39968) - Plastic golems can no longer ventcrawl with + items in their pockets + - bugfix: (tgstation/tgstation#39885) - You can no longer crash the server by overcharging + energy guns. + Thunder12345: + - rscadd: Added a colour picker component for use with circuits. + Time-Green: + - bugfix: Soda is no longer intangible to the laws of physics + Toriate: + - rscadd: It appears that ancient pieces of armor have wound up on the open market! + These armors have degraded beyond usefulness. Grab one now in the loadout! + - imageadd: added flak jacket and M1 Helmet sprites + - rscadd: Gives the flak helmet a tiny storage compartment + - balance: Made the flak helmet even weaker against acid and fire so it crumbles + into dust easier + - rscadd: Added the Corporate Uniform and the Silver Bike Horn + - imageadd: added sprites for the Corporate Uniform and Silver Bike Horn + Tupinambis: + - tweak: 'Removes the tesla coils from engineering secure storage, and places them + within the engine room, functional upon being wrenched down. (Arranged in the + common method of three coils on the left and right sides.) + + Reduces the width of engineering secure storage and its blast door by one tile. + The machinery within has been rearranged in order to make the most commonly + used machinery the most accessible.' + - tweak: Replaces the blood-red hardsuit in Deep Storage with a mining EVA hardsuit, + and an included oxygen jetpack. + - rscadd: 'Adds a replacement to the old lavaland xeno ruins in the form of lavaland_surface_alien_nest.dmm An + image of which is shown below. (The area layer is disabled for visibility.) + ![hive](https://user-images.githubusercontent.com/42078130/44291327-43df0d00-a243-11e8-9e72-ba8f81d31370.PNG) + ![hive2](https://user-images.githubusercontent.com/42078130/44291330-47729400-a243-11e8-998d-660063fa9f41.PNG) + + This replacement is designed to act as a sort of raid, with the queen as the + raid boss. The most notable loot includes the corpse of a drone, security bio + armor, a bone axe, some basic syndicate equipment, and a syringe containing + alien microbes. All references to the old lavaland xeno ruins have been replaced + with references to the new map file.' + - rscadd: New corpse spawners for alien queens and drones. + - rscadd: New syringe containing the alien microbe reagent. + - rscdel: Removed the currently unused lavaland_surface_xeno_nest.dmm map file, + and its references. + - rscadd: Added an experimental hard suit to toxins bomb test room on Box. + - tweak: Increased the size of the toxins bomb test room, moved the telescreen, + and added chairs on Box. + - tweak: Moved some pipes out of the way on Box and Meta. + - rscadd: 'Two air pumps have been added to the toxins lab on Pubby and Meta. + + The following changes apply to Box, Meta, and Pubby:' + - tweak: Unbolts the toxin burn chamber doors on round start. + - tweak: Unlocks the toxins lab air alarm on round start. + - tweak: When spawned as a nuclear operative, you keep your characters race instead + of being changed into a human. Plasmamen are an exception to this change. + - tweak: By popular request, makes the Head of Security spawn with a telebaton instead + of a stun baton. + Werebear: + - rscadd: Seven new holochassis options for pAIs and two new display images for + pAIs. + Wilchen: + - rscdel: Removed box of firing pins from rd's locker + XDTM: + - bugfix: Fixed anti-magic not working at all. + - bugfix: Diseases now properly lose scan invisibility if their stealth drops below + the required threshold. + - tweak: Coldproof mobs can now be cooled down, but are still immune to the negative + effects of cold. + - bugfix: This also fixes some edge cases (freezing beams) where mobs could be cooled + down and damaged despite cold resistance. + - balance: Androids are now immune to radiation. + Xhuis: + - tweak: Character traits are now called character quirks. Functionality remains + unaffected. + Zxaber: + - rscadd: Cyborgs can wear more hats now. + and Fel: + - imageadd: New chairs are on most shuttles! Finally, you can relax in style while + escaping a metal death trap. + armhulen: + - rscdel: chameleon guns are disabled for breaking the server + cacogen: + - rscadd: You can now see what other people are eating or drinking. + - rscadd: Borg shaker can now synthesise milk, lemon juice, banana juice and coffee + - bugfix: Renamed drinks no longer revert to their original name when their reagents + change + cyclowns: + - bugfix: Fires no longer flicker back and forth like crazy + - rscadd: Fusion has been re-enabled! It works similarly to before, but with some + slight modification. + - tweak: Fusion now requires huge amounts of plasma and tritium, as well as a very + high thermal energy and temperature to start. There are several tiers of fusion + that cause different benefits and effects. + - tweak: The fusion power of most gases has been tweaked to allow for more interesting + interactions. + - tweak: BZ now takes N2O and plasma to create, rather than tritium and plasma. + - bugfix: Fusion no longer delivers server-crashingly large amounts of radiation + and stationwide EMPs. + deathride58: + - tweak: (Only visible on 512) Stamina crit will now result in the mob's sprite + subtly darkening around its edges. + - rscadd: Added a tiny reference item to a year-old weeby game. If you're a traitor, + you can find this item in the "badassery" section of the uplink. It's free, + and you can order up to 4 of them! The effects of this item are only visible + on 512. + - code_imp: Added a component signal for toggling combat mode on/off. + - balance: The cleaving saw now deals less staminaloss to its user while inactive. + - rscadd: You can now make use of custom say verbs with the [say verb*message] format + - rscadd: Yelling will now echo and penetrate walls + - tweak: Distant voices now have smaller text + - tweak: You can now see the amount of charges an emag has by examining it + - tweak: Emags now make a quiet noise when they're close to running out of charges. + - tweak: Emags are no longer irreversibly destroyed upon running out of charges. + - rscadd: Traitors can now purchase emag recharge devices for 2 TC. They have five + extra charges each, and can be found in the devices and tools section of the + uplink.. There's no cap on the amount of charges a single emag can have, though + do be aware that upstream spaghetti code makes it easy to waste charges. + - tweak: Small emag flavortext changes here and there + - balance: The warden's particle defender now deals less staminaloss when in stun + mode. + - tweak: '"code [alert level]" has been changed to "[alert level] alert" on the + hub entry.' + - tweak: The hub entry now displays the current map. + - tweak: Lavaland is no longer fullbright. We have memory to spare. + - rscadd: Adds the wheelofsalt command to TGS3. Spin the wheel of salt to find out + what the Citadel Station 13 players are salting about today! + - rscadd: You can now slam or slap your hands onto tables by right clicking them + in combat mode. + - tweak: Non-admins can no longer use LOOC while dead, unconscious, in crit, or + while ghosting. + - tweak: The syndicate mask available in the uplink will now inject you with a chem + that cuts your click delay in half and increases your stamina regeneration, + when you enter combat mode. The mask has a five minute cooldown between adrenaline + injections. + - balance: Dogborgs will now reduce firestacks when they use their tongue to lick + someone's face. + - bugfix: The repo compiles again + - bugfix: The flag cape donor item should render properly now. + - tweak: The default amount of z-levels reserved specifically for space ruin generation + has been reduced from 7 to 1 + - bugfix: Items now spawn on top of, rather than inside, closets and other storage + structures + - rscadd: Jukeboxes now have realtime directional audio, complete with occlusion + when you're far away or behind a wall. + - rscadd: More than one jukebox can play a song at a time now. Have up to 5 jukeboxes + playing at once! + - rscadd: Devs can now control the wet and dry channels of sounds played via playsound_local. + The new envwet and envdry arguments will control the volume of the wet and dry + track, respectively. + - code_imp: Jukeboxes have been turned into a subsystem. Track initialization, audio + playing, etc, are now handled via SSJukeboxes instead of via the jukebox object + procs. + - config: Jukebox tracks now require an additional ID field at the end of their + name. This will make it easier to add jukebox-style objects that are only capable + of playing specific songs, without worrying about copyright issues. + - rscadd: Added Raiq's boombox as a donor item + - rscadd: You can now manipulate tails, ears, body markings, mutant colors, and + taur types via DNA console! + - balance: Reduced the exponent on gas tank ruptures. TTVs and suicide onetanks + that were previously 20dev are now approximately 9.6dev. Let's see the actual + toxins nerds adapt! + - tweak: When a custom say verb message is spoken without any actual words, the + text will render without a `, ""` at the end of it. + - balance: The combat rework's training wheels have been removed. Knockdowns no + longer have any noticeable stun. This indirectly means stunbatons and tasers + will always deal their full stamloss on hit. + - balance: The stamloss required for boxing gloves to throw a knockout punch has + been increased from 50 to 100. + - rscadd: You can now prime the grenade on bombspears by using them in your hand. + The wield hotkey is moved to combat mode rightclick while a spear has a grenade + on it. This is explained in the examine text. + - balance: Bombspears no longer instantly explode on impact when thrown. They now + have to be primed to explode when thrown. + - balance: Bombspears now have 90% embed chance. + - rscadd: If an embedded item is normal sized or larger, you can take it out instantly + by pressing resist. + - balance: Embedded items are now much harder to pull out the smaller they are, + rather than the other way around. It's much easier to rip out a sword from your + chest than it is a shard of glass in your face. + - tweak: The message you get when you get bounced by the PB is now a little more + clear about what you need to do to gain access to the server. + - balance: The jukebox now falls off over a greater distance. You can now actually + hear the jukebox while sitting in a far corner of the bar, or while passing + through the main hallways. + - rscadd: Added antag OOC. This is disabled by default, but you can access it with + the "AOOC" verb as an antagonist when an administrator enables it. + - tweak: LOOC now supports emojis + - tweak: 'Deadchat and asay will now both render emojis! :snya:' + - balance: The disarm attack on EMP'd defibs now has an interruptible 1 second timer + before it actually lands. + - balance: The stamina buffer now only takes 1 second to start regenerating. + - balance: Disablers have had their damage reduced from 36 stamloss to 24 stamloss, + increasing their shots to stamcrit from 4 to 6. + - balance: Tasers have had their damage increased from 55 stamloss total to 61 stamloss + total. Shots required to stamcrit are unaffected. + - rscadd: Introducing the Kitchen Gun (TM)! Say goodbye to daily stains and dirty + surfaces with Kitchen Gun (TM)! Just five shots from Kitchen Gun (TM), and it'll + sparkle like new! Includes two extra ammunition clips for the low, low price + of just 10 TC! Laser sight and night vision accessories sold separately! Magazines + can be purchased individually for 1 TC a pop! + - tweak: Active turf processing is now its own subsystem. + - code_imp: Ports tgstation/tgstation#39287 - You can now configure how fast a mob + fires, and how many shots they fire in a single burst + - rscadd: When you spawn as a miner, you'll get text clarifying your job description. + You might not think it's necessary, but believe me, it is. + - rscadd: mushroom people are now roundstart on live + - rscadd: The geargroupID var of loadout entries can now be a list rather than a + string. GeargroupID changes are additive when multiple are defined in a single + loadout entry. + deathride58 (Original PR by Basilman/Militaires): + - rscadd: Ported TGstation's Agent Stealth Box! You can the implanter in the syndicate + uplink for 8 TC. Credit goes to Basilman/Militaires. This port includes minor + adjustments, see the GitHub for details. + hatterhat after being yelled at by kevinz: + - bugfix: deletes an entire line that might fix flash icons idk blame him if it + gets worse + iksyp: + - rscadd: stacking machines and their consoles no longer dissapear into the shadow + realm when broken + - rscadd: you can link the stacking machine and its console by using a multitool + - bugfix: Ever since the great emotion purge of 2558, people were able to work at + top efficiency, even while starving to death. This is no longer the case, Nanotrasen + Scientists say. + - admin: Hunger slowdown only applies if mood is disabled in the config. + imsxz: + - admin: Using mayhem bottles and going under their effects is now logged. + izzyinbox: + - rscadd: Added an integrated circuit part that interacts with the arousal system + - tweak: changes the admin-pm input box from single line to multi-line + - bugfix: Tennis balls now equip and show up in the correct slots + - rscadd: Adds option in the hide/expose genitals verb to hide genitals even without + clothes + kevinz000: + - rscadd: Cameras now can take pictures up to 7x7. Alt click them to change their + width/height from the default 3x3. + - rscadd: Photos are now logged to disk, assuming the host enabled the configuration + option + - rscadd: If the above is enabled, albums/frames can now have their persistence + IDs set in variables to allow for PHOTO PERSISTENCE + - rscadd: Every head of staff gets a unique album with its own ID in their locker. + Let your successors know about your accomplishments, screwups, and everything + in between! + - rscadd: All of this works or should work with newcasters/pdas/etc etc + - rscadd: Photo taking now clones the area into transit space and then operates + on it, instead of on the spot, in theory making photographing things more accurate? + nicc: + - rscadd: no more dark locker corner woo + - tweak: area alterations + - rscadd: escape pod + - rscadd: see above + - rscadd: adds windoor to the plastic flaps in the atmos lobby + ninjanomnom: + - rscadd: A plush that knows too much has found its way to the bus ruin. + resistor: + - rscadd: Added circuit labels! You can now customize the description of your assemblies. + slate3: + - rscadd: ported a new alternative sprite for engineering borgs, mr. handy + - rscadd: ported a new alternative sprite for security borgs, a spider-like walker + - rscadd: ported a new alternative sprite for medical borgs, an eyebot + steamport: + - bugfix: Borgs/AIs can now toggle rad collectors + ursamedium: + - bugfix: slapping / slamming hands on tables now uses appropriate pronouns + - bugfix: crow pAI is no longer invisible while resting + yenwodyah: + - bugfix: A few virus threshold effects should work now + yorii: + - bugfix: Fixed the smartfridges to be in line with all other machines and puts + the released item in your hand. + yorpan: + - rscadd: Brain damage makes you say one more thing. diff --git a/html/changelogs/archive/2019-11.yml b/html/changelogs/archive/2019-11.yml new file mode 100644 index 0000000000..ad93f04d99 --- /dev/null +++ b/html/changelogs/archive/2019-11.yml @@ -0,0 +1,2522 @@ +2019-11-04: + 4dplanner, MMiracles: + - tweak: Wizard shapeshift now converts damage taken while transformed + - bugfix: transform spell transfers damage correctly instead of healing most of + the time + - bugfix: 0% simplemob health maps to 0 carbon health, 100% simplemob to 100% carbon + - bugfix: transforming to a form with brute resistance no longer heals you + - bugfix: transforming back to a species with brute resistance no longer heals you + AdmiralPancakes1: + - rscadd: 'Cryo cell shortcuts: alt-click toggles the doors, ctrl-click toggles + the power' + Alonefromhell: + - rscadd: Ported Oracle UI, a framework for self-updating and neat UI's + - refactor: Paper now uses OUI + - refactor: Bins now use OUI + - bugfix: fixes tootip offset + AnalWerewolf: + - rscadd: Fritz plushie + - rscadd: Donor item + Anonymous: + - imageadd: 'More crusader armor variants to pick from armament: Teutonic and Hospitaller.' + Arturlang: + - rscadd: You can now use CTRL and ALT click on pumps and filters to toggle them + on and off and max their output respectively + - rscadd: You can now use RPDs on windows and grilles. + - rscadd: The RD can now suplex a immovable rod. Good fucking luck. + - bugfix: Fixes high alert ERT suit sprites. You can see them now! + - rscadd: Traitor codewords are now highlighted for traitors. + - rscadd: You can now examine pumps filters and mixers to see if you can use CTRL + and Alt click on them. + - bugfix: Fixes brain damage/trauma healing nanites so they actually work while + there are only traumas. + - tweak: Advanced toxin filtration nanites now heal slimes + Bhijn: + - rscadd: It's now possible to forcefully eject the occupants of a dogborg's sleeper + by using a crowbar on them. This action is instant. + - tweak: Resist values for dogborg sleepers have been adjusted. The baseline has + been decreased from 30 seconds to 15 seconds. Medihound sleepers have a resist + timer of 3 seconds. Sechound sleepers retain a resist timer of 30 seconds. + - tweak: It now takes 10 full seconds to insert people into your sleeper. This should + hopefully give people some more room to breathe and react to a dogborg attempting + to sleeper someone either for no reason or in a way that violates law 2. + - bugfix: Warp whistles no longer grant permanent invulnerability and invisibility + - bugfix: You can now actually use the resist hotkey to resist out of handcuffs. + Woah, revolutionary + - bugfix: the `!tgs poly` command now actually works + - rscadd: Poly now has a 0.01% chance per squawk to speak through the TGS relay. + - balance: The point production mode of radiation collectors has been reverted to + the original behavior of using all of the stored power every process cycle instead + of just 4% of it + - tweak: Radiation collectors now display the amount of power/research points they're + producing per minute rather than per process cycle, which should hopefully clear + up a lot of confusion. + - tweak: Radiation collectors also display what's happening to the gas within them, + which should make it a lot more obvious as to how you get tritium. + - tweak: Security borgs and K9s are now only available during red alert or higher. + - server: Headmins or other folks with access to the server's config can choose + the minimum alert level for secborgs to be chosen via the MINIMUM_SECBORG_ALERT + config option. See the default game_options.txt for more info. + - bugfix: The server no longer attempts to check if the CID matches the IP of any + bans, or if the IP matches any CIDs of any active bans, during client analyzation + - balance: Vampires can now only ventcrawl in bat form if their blood level is below + the bad blood volume (224 blood total) + - balance: Vampires now only take 5 burn per mob life cycle while within chapel + areas, down from the original 20 burn per life cycle. + - tweak: K9 pounces have received a minor rework. It now has an effective cooldown + of 2.5 seconds, can now only deal up to 120 staminaloss, deals a maximum of + 80 stamloss on hit, has a spoolup of half a second, and now has telegraphing + in the form of a quiet noise. + - balance: K9s now only have 80 health + - balance: Secborgs (but not k9s) now have a hybrid taser. This can be toggled via + server config. + - tweak: The disabler cooler upgrade now applies to all energy-based firearms for + borgs + - rscadd: Dogborg jaws are now capable of incapacitating targets if using help intent. + This deals a hard stun depending on how much staminaloss the target has, and + whether or not they're resting. This behavior can be toggled via server config. + - balance: K9 jaws now have 15 force, up from their nerfed 10 force. + - balance: Borg flashes regained their ability to cause knockdown. This can be toggled + via server config. + - server: The WEAKEN_SECBORG config option will disable the new dogborg jaws mechanic + and make secborgs spawn with a standard disabler. + - server: The DISABLE_BORG_FLASH_KNOCKDOWN will disable the ability for borg flashes + to knockdown. + - tweak: Jukeboxes now have 6 audio channels available to them, up from the previous + accidental 2 and previously intended 5 channels. + - bugfix: Jukeboxes now work again on clients running versions higher than 512.1459. + - bugfix: People will no longer have their ears consumed by an eldritch god if multiple + jukeboxes are active and the first jukebox in the jukebox list stops playing, + then tries to play again + - tweak: Instead of the debug text for invalid jukebox behavior being printed to + world, the debug text is now restricted to the runtime panel. + BurgerB: + - tweak: Tweaked the UI of the loadout to be less cluttered due to an issue with + formatting. + BurgerBB: + - rscadd: Adds the bonermeter; a device that measures arousal based statistics. + - refactor: Added a new input to the electrostimulator that controls the strength + of the shock. It accepts negative inputs which reduce arousal. Added a new output + to the electrostimulator that displays the amount of arousal gained. + - balance: Rebalanced the electro-stimulator to be less spammy by giving it a 2.5 + second enforced cooldown per circuit contraption. Increased the complexity of + electro stimulator from 10 to 15. + - refactor: Reworked the Vent Clog event to spray smoke instead of foam, also made + it shoot smoke over time instead through each vent instead of all at once. + - tweak: Increased the spawn area of the City of Cogs (Reebe). This does not affect + the area in which builders can build. + - balance: Significantly tweaks the Wizard race transformation event to be less + unreasonably troublesome. + - rscadd: Adds a new 0 cost trait that makes you immune* to Crocin and Hexacrocin + - tweak: Tweaks how slurring works so it's more of a gradual change into slurring + instead of immediate. + - balance: Slurring is now directly proportional to your drunkenness, with other + sources of slur being added on top of it. + - tweak: Bras are now separate from underwear, meaning you can mix and match bras + if you're into that. + - tweak: Men can wear female accessory clothing, and females can wear men accessory + clothing. It's not a fetish, mom, it's PROGRESSIVE. + - code_imp: Reorganized accessories into their own files to prevent a massive 1000 + line file. + - server: i'm 10% sure that merging this PR will cause preference corruption sooooooooooo + I just need to hear from @deathride58 or perhaps someone else on how much damage + this could possibly do. + - tweak: Tweaked penis. + - balance: Rebalanced penis. + - rscadd: 'Added the following reagents to the common list of vent clog reagents: + ~~Cooking Oil~~, ~~Frost Oil~~, Sodium Chloride, Corn Oil, Uranium, Carpet, + Firefighting Foam, semen, femcum, tear juice, strange reagent, ~~spraytan~~.' + - balance: Vent Clog smoke emits the same transparent smoke as a smoke machine, + including how much it transfers. Vent Clogs also do not trigger in areas deemed + "Safe" in code, such as in the dorms or trusted areas where dangerous things + shouldn't occur. + - rscadd: Adds additional random brain damage text + - rscadd: Adds penis enlargement pills. + - rscadd: Adds Stun Circuit and Pneumatic Cannon Integrated Circuits + - bugfix: Fixed extinguisher and smoke circuits not accepting any reagents. + - rscadd: Adds a few important clockcult tips. + - rscadd: Added Mech Sensors, a brass-created trap that activates when a mech not + controlled by a cultist crosses it. + - rscadd: Added power nullifiers, an emp trap that emps everything in a 3x3 area, + with the center suffering a heavy EMP. + - tweak: Brass Skewers now deal 50 damage to mechs. + - balance: Ass slapping only works if you're actually behind the target. Ass slapping + now respects disarm blocking. You can no longer face/ass slap someone on an + intent other than help, unless they are also face/ass slapping. + - bugfix: Fixed ass and face slapping grammar. + - rscadd: Adds meh effects for ass and face slapping. + - tweak: '"Unwillingly" eating food now sends a warning message instead of a notice. + Unable to stuff food down your throat sends a danger message instead of a warning + message.' + - rscadd: Adds clockwork reflectors, a fragile anti-laser reflection shield object + that can be constructed for 10 brass sheets. Upon firing on the object in the + direction where it is shielded, it ricochets the bullet off of it relative to + the shooting angle. + - tweak: Renames some windows in the build menu for consistency. + - balance: Clockwork Cult walls can no longer be deconstructed by RCDs when heated. + - rscadd: Adds several new toy loot to the arcade machine. + - balance: Rebalanced the arcade machine loot. Battlemachines now have a 0.5 second + delay instead of a second delay between actions. + - bugfix: Fixed a bug that would not allow the one in a million pulse rifle to spawn. + - rscadd: Adds a new trait "Buns of Steel" that makes you immune to the effects + of ass slapping, and temporarily makes the user's arm useless like a stun baton + hit. It costs 0 points. + - balance: Ass slapping blowback from the Buns of Steel perk now deals 20 stamina + damage instead of 50, and no brute damage. + - rscadd: Gamemode voting results are displayed at the end-round screen. + - balance: Cloning no longer gives you positive mutations, but a chance for a negative + one. Cloning has a chance to "scramble" your visual DNA. + - balance: Chestbursters no longer give and remove your brain. They just disembowel + and kill you now. + - bugfix: Fixes WarOps miscalculating players. + - balance: Activating the nuclear device during war-ops informs the crew of the + nuke's position. + - rscadd: The alert level is displayed at the job selection screen. + - balance: Central Command informs you when a Meteor Storm is about to hit 5 to + 10 minutes before it happens. + BurgerLUA: + - code_imp: Added a new framework for reagents. Reagents can now have a bool that + determines if it can be detected by handheld medical analyzers. Currently only + the changeling sting chemical does this. + - balance: Made changeling transformation string last between 10-15 minutes. Lowered + the dna cost of changeling sting from 3 dna to 2 dna. Lowered the chemical cost + from 50 to 10. Lowered the loudness from 2 to 1. Changeling sting transformation + can be removed via high doses of calomel. + - bugfix: Fixed most reagents having a placeholder color. + - bugfix: Fixed autolathe wires not correctly shocking you when pulsed. + - balance: Rebalanced special jetpacks. + CalamaBanana: + - rscadd: Added Deer taur + - rscadd: Added Elf ears to mammals + CameronWoof: + - rscadd: Medihounds now have rollerbeds for non-vore patient transport + - bugfix: The closed O2 crate now uses the same color scheme as the open one + - tweak: air alarms are green now instead of blue when the atmosphere is ideal + - tweak: Hexacrocin overdose no longer causes climaxes + - tweak: Altered the icons for inventory backplates. Sleek! Stylish! New! + - bugfix: Attaching a beaker that contains water to an IV stand no longer causes + a visual glitch + - tweak: Fluid-producing sexual organs no longer start full + - tweak: Sexual organ fluid capacity decreased from 50 to 15 + - tweak: Sexual organ production rate decreased from 5u to 0.035u per two seconds. + - tweak: Sexual fluid decals no longer contain reagents + - tweak: Sexual fluids cannot by synthesized (e.g., by the Odysseus) + CdrCross: + - rscadd: Adds the ability for cloning consoles to read and write record lists to + the circuit board, and provides a template for giving other machines local circuit + board memory. + Cebutris: + - rscadd: Hugs of the North Star! Get them from the arcades (if you're lucky) and + hug your friends at INCREDIBLE hihg speeds! + - bugfix: Tea Aspera now properly contains tea powder + - tweak: Breasts no longer lactate by default, lactation is now a preference + Chayse: + - tweak: Changed the Warden's compact combat shotgun to instead be a regular combat + shotgun with a foldable stock and penalties for being folded. + - rscadd: Assorted space-worthy helmets can now act as masks for internals. + - refactor: Internals code can now check any item with the ALLOWSINTERNALS flag + through the GET_INTERNAL_SLOTS define. For now this only checks head and mask + slots, since those are the most realistically speaking usable ones. + - tweak: Medbay doors can now be opened by anyone from the inside without having + to press the exit button. + - bugfix: Borgs now have the necessary dexterity to unbuckle people from themselves + and from bucklable objects. + - bugfix: Fixes the Trek Uniform/Suit worn icons + - bugfix: AIs can now once more talk through holopads successfully + Code-Cygnet: + - rscadd: Added new things - Mind trait, alcohol reagent, chemical reagent, drink + sprite and recipe. + - imageadd: added commander_and_chief sprite to drinks.dmi + Coolgat3: + - tweak: Changed player number checks to 20 from 24 for cult and clockcult, also + made nukeops 28 required players instead of 30. + - tweak: Changed enemy minimum age from 14 to 7 + - rscadd: Added the code for the semen donut and made it craftable + - imageadd: Added the donut sprites + - bugfix: Made the sec and warden berret offer as much protection like the helmet + - rscadd: Added berets for all the heads. + - imageadd: Added sprites for the berets. + - code_imp: Coded the berets to spawn in appropiate lockers. + - tweak: Raised the ripley's movement speed and lights range by 1, also lowered + its armor to compensate. + - rscadd: Added combat gloves sprite + - imageadd: Added said sprite + - imageadd: added combat boots sprite + Coolgat3 / Avunia: + - rscadd: Made kindle put the target into stamcrit, which makes it an actually working, + useful stun. + - rscadd: Added a stamina loss modifier to the vanguard spell which makes the user's + stamina drain at a way slower rate. This doesn't make them immune to tasers, + but it takes a few hits to actually get them to fall down. + - tweak: Made it so that clock culties don't start with a chameleon suit. Instead + they start with an engineer suit which is pretty much the same sprite and looks. + If this is not perfect, then I am willing to make a slightly more brass-colored + version of the engineer suit sprite and call it a ratvarian engineer jumpsuit. + - balance: Increased the cost of vanguard, as it is now a spell that works somewhat + like adrenals, minus the move speed, making your stamina drain really slow and + making you unable to get knocked onto the ground by just a single taser shot. + - balance: Lowered the charge time of kindle, reason being that you can usually + have only one active spell on you, or two at max if you decide to run two slabs, + but the fact that kindle silences people for such a small amount of time makes + up for it, in my opinion. + - server: Figured out that the consoles and their warp function actually work with + the current code. The thing that makes them not work is when the gamemode is + ran on debug mode, without the required players to actually support it. It also + breaks the ark timer which is stuck on -1 seconds until activation. Whenever + the gamemode starts properly, like any other gamemode, with player checks and + all, everything seems to work just fine. + CydiaButt13: + - rscadd: Lamp Plushie to loadout + - imageadd: added plushie_lamp to plush icons + - code_imp: added Lamp Plush to loadout and icons and items + EgoSumStultus: + - bugfix: Fixed blood chiller's inhand + - bugfix: FIXED SHIELF + - bugfix: fixed magpistol magazine sprites + - rscadd: Added the Femur Breaker + - rscadd: Adds male AI vox. + EmeraldSundisk: + - rscadd: Adds a gun range to Box Station + - rscadd: Provides some extra power grid connections + - rscdel: Sunglasses and Earmuffs removed from the Warden's Office - they can be + found at the range instead + - tweak: Rearranges a few objects within the prison as to accommodate the new gun + range + - rscadd: Adds a mass driver to Delta Station's chapel + - rscadd: Adds a second means of entry into the chapel + - tweak: Slightly expands the chapel to make room for the driver, slight adjustment + to air systems + - tweak: Clears a path in the station exterior for the mass driver to work properly + - tweak: Nearby maintenance loot has been relocated to accommodate the chapel expansion, + surrounding area has been "cleaned up" somewhat + - tweak: CentCom has noticed the lack of coffins in Delta Station's chapel and provided + some, but in exchange for reducing the chapel morgue's capacity. + - tweak: Fixed a maintenance door the chaplain should have been able to open. + - bugfix: 'Fixes space areas outside the driver removal: CentCom Defense Analysts + have ordered the maintenance hatch to the Mass Driver room be removed citing + "security concerns".' + - rscadd: Increases the number of plots to 9 (from 5) + - rscadd: Additional lighting placed directly outside the garden + - tweak: Cleans up the area to reflect use. Moves the seed extractor to a more central + location + - tweak: 'Relocates the seed packs on botany''s counter to the garden removal: Removes + wooden barricades outside the garden' + - config: Renames "Abandoned Garden" area designation to "Maintenance Garden", but + does not replace the icon in Dream Maker + - rscadd: Expands the chapel mass driver room to make it easier to use + - rscadd: Rearranges the chapel backroom so there are now six coffins and burial + garments roundstart + - tweak: Cleans up the Janitor's office + - tweak: Readjusts the station exterior so mass-driven coffins (hopefully) have + less friction + - bugfix: Adds a fan to the chapel driver + - bugfix: The Janitor missed a few spots around the newly renovated Maintenance + Garden + - bugfix: Readjusts positioning of Delta's QM keycard device + - bugfix: 'Cleaned up a few spots I missed in #9356, particularly around the janitor''s + office' + - rscadd: Adds some potted plants around Box Station + - bugfix: 'The tile mentioned in #9409 should now be radiation-free.' + Fermi: + - bugfix: Fixes tiny runaway decimals in reagents system. + - bugfix: 'SDGF: Fixes infinite clones.' + - bugfix: fixed an angery PR + Fermis: + - rscadd: Added a panda simplemob + - bugfix: fixes empathy exploit. + - rscadd: Added the secbat, a box to hold it and the ability to dispense it from + the SecTech vendor. + - rscadd: Adds 3 new music tracks. + - tweak: tweaked Neurotoxin + - balance: added more depth to Neurotoxin + - bugfix: fixed the inability to create Neurotoxin + - bugfix: fixes fermichem reactions for tiny volumes work + - tweak: makes quantisation level for chemistry finer + - tweak: re-enables femichem explosions in grenades. + - tweak: adds nuance to the SDGF and hatmium explosions. + - bugfix: Fixes analyse function on ChemMasters to correctly display purity. + - bugfix: Fixes the custom transfer for buffer to beaker button. + - rscadd: 'Debug option: Generate Wikichems' + - rscadd: graft synthtissue surgery, new reagent synthtissue + - tweak: 'neurine fixes brain objs merge: combines fermichem''s lung damage with + tg''s' + - rscadd: on_mob_dead(), bitflags and CHECK_MULTIPLE_BITFIELDS + - refactor: refactored fermichem vars, moved impure chems into their own reagents + subtype + - bugfix: Fixes small residues of chems that won't go away! + - tweak: tweaked beaker health and allows use of syringes/droppers on chem_heaters + - soundadd: added a sound for when beakers take temperature damage. + - imageadd: added some icons for melting beakers + - refactor: refactored how beakers take damage + - bugfix: fixes how beakers would only take one instance of damage on pH damage + - bugfix: fixes Janitor grenades. + - bugfix: fixes reaction mechanics at low volumes + - bugfix: stops reactions constantly bubbling on the edge of reaction temperature + - bugfix: stops small amount reactions from occurring, and prevents disappearing + tiny numbers + - tweak: Reduced minimum reaction volume from 1 to 0.01 + - refactor: cleaned up Fermichem + - rscadd: Adds Jacqueline the Pumpqueen and her familiar Bartholomew for the spooky + season + - soundadd: Adds a giggle + - imageadd: 'Adds cauldron, Jacq and Jacq o lanterns, and a costume for halloween! + mapedit: adds a new landmark so Bartholomew can spawn somewhere sensible.' + - bugfix: fixes food reactions and explosion runtimes, + - bugfix: fixes the too much yes problem + - bugfix: Heart, Tongue and stomach regen. + - bugfix: lung damage threshholds. + - bugfix: Graft synthtissue + - bugfix: Skeleton's burning for no reason + - bugfix: Organ freezing handling. + - bugfix: Fixes chemistry books to point to the right wiki, and keeps tg's just + in case + - tweak: Changes top right wiki button location to go to both wikis + - bugfix: fixed Jacq's fondness for the AI + Ghom: + - code_imp: minor clean up on hydroponics reagent containers. + - bugfix: fixes the perpetual lack of moisture that has affected genitalia descriptions + since, like, forever. + - rscadd: implements the arousal state for mammary glands. + Ghommie: + - bugfix: Fixes many possible situations of null icons for cit races' bodyparts. + - imagedel: Removes duplicate slimepeople' sprites. + - code_imp: Purges that draw_citadel_parts(). + - code_imp: Fixes ISINRANGE_EX using the wrong relational operator. + - tweak: The kindle status effect stun duration now properly proportional to the + owner's remaining health. + - tweak: Clockwork cult's kindle now affects silicons. + - tweak: Cyborg mounted disablers/tasers/lasers now slowly self-recharge off the + cyborg user's power cell instead of draining from it directly. + - tweak: Borg rechargers now properly recharge the borg module's energy guns. + - bugfix: Prevents a couple more special/mounted guns from being preserved on cryo + - balance: Halved borg energy guns self-recharge delay and increased their cell + capacity by 3/4 + - bugfix: Fixes chemical patches always checking the suit slot even if the targetted + limb was the head. + - bugfix: Skeleton, nightmare and golem races are once again available to get chemical + patches applied onto. + - rscadd: Adds two cartons of space milk to the space skellie pirates cutter's fridge. + - refactor: Refactored implants to not be located inside mobs codewise, akin to + organs. + - bugfix: Fixed gps tracking implants. + - bugfix: Fixed item not being dumped out of storage implants onto the owner's turf + upon removal. + - bugfix: Fixes cult potentially stalling if the target is erased from existence + without being sacced. + - balance: Nukes the stunprod's 3 seconds delay. + - bugfix: Fixes teleprods. + - bugfix: Stops pulls of resting mobs breaking off whenever you swap turfs with + someone else because of crawling delays. + - bugfix: fixes IAA. + - balance: EMPs now flick off stunbatons, they can be turned back on immediately + by the user anyway. + - balance: Stunbatons now very slowly consume charge whilst kept on, at a rate of + 4/1000th of a standard batoning charge cost per tick. + - balance: Softened up the charge cost checks to stop the above update from practically + reducing the maximum uses of a stun baton by one. Now, should the remaining + charge be lower than the hit cost, the resulting stun will be be proportional + to the remaining charge divided by the hitcost, within a limit under which the + stun batoning just won't happen. + - balance: Buffs condensed capsaicin, a yet another feature previously dunked by + stam combat. + - balance: speeds up pepper spray puffs. + - balance: Buffed krav maga leg sweep stun and stamina damage. On the other hand, + it's now unable to be used on already lying targets. + - bugfix: fixes eyestabbing people with cutlery while being a pacifist. + - bugfix: Reduces goonchat lag from being blasted by pellets and bullets repeatedly + whilst wearing armor by properly removing the armor protection texts this times. + - spellcheck: also reduced the size of armor protection messages in general. they + clog up the chat box. + - bugfix: Fixes stunbatons icon not properly updating on cell removal and insertion. + - tweak: Allows lower charge cells to be used with stun batons, and thus single + use crapshots batons. + - balance: Adds in a 7 seconds delay to the jackhammer dismantling a superheated + clockwork wall. + - tweak: escape pods emergency suits storage can now be busted open by emags or + excessive damage. + - bugfix: Fixes alt click bypassing the escape pods' suits storage lock. + - bugfix: Fixes emags wasting charges on un-emaggable & co stuff. + - code_imp: Ported some radials code updates. + - rscadd: Ported the RCL wiring menu and a comfier RCD interface. + - tweak: A milder combat stance message will show up if the user switch combat mode + on while on help intent. + - spellcheck: Properly rewords the extinguisher's instructions on how to empty it + on the floor since it was changed to be a screwdriver action instead of Alt + Click a while ago. + - rscadd: Reskinnable PDAs. A related game preference. + - refactor: Refactoring the pda, pda painter, obj reskinning and chameleon pda a + bit to support this feature. + - imageadd: more PDA sprites and ported reskins. + - refactor: turned virtual reality into a component datum, which is then applied + to spawned virtual mobs. This fixes mob transformations (such as wabbajack and + monkeyizing) breaking the previously hardcoded behaviour and trapping you in + VR, also enabling a more concrete virtual reality inception experience. + - bugfix: Fixes power cells being unable to be rigged. Also prevents them from starting + processing on init if they don't self recharge. + - bugfix: Fixes many, little or otherwise, issues with the stunbaton status refactor. + - bugfix: The sacrificial target icon will now display onto the cult objective ui + alert once again. + - bugfix: Stopping borgs from sprinting into negative cell charge. + - tweak: The default amount of z-levels reserved specifically for space ruin generation + has been increased from 1 to 2 + - tweak: 'Moving some tablecrafting recipes to the appropriate categories: Kitty + ears and lizard cloche hats to "clothing"; Hot dogs to "Sandwichs"; Cuban carb, + fish and chips and fish fingers to "Fish".' + - bugfix: Fixes the not-a-sandwich recipe being M.I.A. + - rscadd: Adding in peanuts, peanut butter, peanut butter toasts and sandwiches, + and the PB&J sandwich. The peanuts contain a little bit of extractable cooking + oil (similarly to soy beans) and can be microwaved or dried in a drying rack + to make roasted peanuts, which can be mixed in a all-in-one-grinder for peanut + butter, required to make those sandwiches. + - balance: Buffed wizard and artificier's Magic Missile, wizard and xeno queen's + Repulse and juggernaut's Gauntlet Echo. + - bugfix: Fixes flashlights being unable to be used for rudimentary eyes and mouth + exams. + - rscadd: Adds in a grey jumpsuit to the loadout choices, restricted to Assistants. + - bugfix: Fixes CWC construct shells being visible as ghost role to latejoiners. + - imageadd: new sprites for the flechette gun, its magazines and the toy ray gun + - tweak: Merges the end-of-shift and its shuttle autocall announcements into one. + - bugfix: Prevents the end-of-shift shuttle from being recalled (even if to no avail). + - bugfix: Fixes being able to teleport papers to your location with TK. + - bugfix: Fixed some monkey-code shenanigeans making items sometimes disappear from + pickpocketing. + - imageadd: New sprites for the some pda cartridges. + - tweak: The crew monitor's entry for the Quartermaster will now appear bolded, + while HoP's will be of the same color of the service/unknown/other jobs. + - bugfix: emergency pods' storage will now properly work. + - bugfix: The PDA skin preference will now properly save up. + - tweak: Changed the default PDA icon var to match the default PDA skin preference. + - bugfix: Fixing the `(pointless) badassary` category appearing between the `dangerous + and conspicious` and `stealthy and inconspicious` categories. + - bugfix: Combat gloves plus now properly use the combat gloves sprite. + - bugfix: Fixes the space ninja's energy netting. + - rscadd: Adding one pAI to the wizard shuttle and ERT prep room + - bugfix: Fixes the rocket launcher being unreloadable. + - balance: Buffed its accuracy a bit. + - tweak: Replaced the grenade launcher emagged minesweeper loot with the rocket + launcher like it was originally supposed to be. + - imageadd: 'Tweaked the :b: emoji.' + - rscadd: Rubber Toolboxes. + - rscadd: 'Porting in two bar signs: Cyber Sylph''s and Meow Mix.' + - bugfix: Fixing stamina damage melee weaponry being unusable by pacifists, and + still damaging objects and triggering electrified grilles when thrown. + - refactor: refactored underwears to allow custom color preferences, instead of + manually colored sprites. + - rscdel: The aforementioned manually colored pieces. Some of your char preferences + may have been resetted as result. + - rscadd: 'More underwear choices, including: Bowling shirts, long johns, a tank + top, fishnets, more bee socks, bee t-shirt and bee boxers (original PR for the + latter three by nemvar from /tg/station).' + - tweak: random bodies will now have random underwear again. + - bugfix: Dressers will now properly change undergarment again. + - tweak: Toned down many species' female chest sprites to fit the smaller cups. + - bugfix: Fixed some body parts sprites inconsistencies, such as the W/E female + and male chest sprites being the same in some species, and jellypeople's legs + being one tile off on W/E + - bugfix: Fixing baklava pies a bit. + - tweak: Sweaters now cover groins too. + - balance: Improved the zelus flask to be more viable for bottle smashing than the + average barman's selection. + - code_imp: Very slight bottle smashing code clean up, stupid const vars. + - bugfix: Fixes krav maga gloves, wizard spells knockdowns. + - tweak: Added in an alert pop up to the cult convertees, on top of the older "click + here to become a blood cultist" chat message. + - tweak: The convertee's screen will now flash red to fit in the aforementioned + message's fluff. + - spellcheck: Made said message less verbose. + - rscadd: Towels. Crafted with 3 sheets of cloth, they can be worn on head, suit + and belt slots even without uniform, or laid flat on the floor. Sprites from + Baystation and Aurora Station. + - rscadd: You can combat mode right click people while wielding rags and towels + to pat out their flames (to no use for rags) or otherwise drying them out. + - balance: toned down the stamina costs of some of the bulkier weapons. + - code_imp: repathed hypereutactic blades to be a subtype of dual sabers. Way less + copypasta. + - bugfix: Fixing CX Shredder guns not accepting standard flechette mags. + - bugfix: Fixing missing magpistol magazines icon states. + - rscadd: sort of overhauled darkmode/lightmode to /vg/station's, also reincluding + the pre-existing black'n'white theme. + - bugfix: Fixed LOOC color, fixed .userlove and .love span classes being a bit too + blurry on dark mode. + - rscadd: The syndicate base's bathroom is now fitted with a shower, and a special + towel. + - bugfix: Fixed many issues with towels. + - tweak: The dry people off with rags/towels action can only be done if the object + is NOT moist with reagents now. Also cleans banana creaming. + - rscadd: Towels deal more damage while soaked with reagents. + - rscadd: You can now squeeze rags/towels with Alt-Click. + - rscdel: deleted an old and crappier towel sprite that got in the way. + - bugfix: Fixes Pubby's disposal conveyor belts and lack of a second lawyer spawner. + - code_imp: Cleaned up the absolute state of the arousal module. + - refactor: refactored exhibitionism into a quirk. + - tweak: arousal states won't persist after death. + - bugfix: Fixes testicles size adjective thing. + - bugfix: undergarments toggling now works instead of just making underwear disappear + and not come back. + - tweak: The "Always visible" genitals setting will now display them above clothes. + - bugfix: combat pushes will now properly stop targets from using firearms, and + will disarm the firearm if performed a second time, and also slow down people + by 15%, and won't push people on tables blocked by shutters or other dense object + anymore. + - bugfix: Fixes CHECK_BITFIELD macro. + - bugfix: Fixes hypovials being unable to transfer out liquids or be refilled by + large dispensers like water tanks. + - bugfix: Fixes chem-masters machineries not dispensing newly made pills inside + loaded in pill bottles. + - rscadd: Stunswords now fit in the captain's sabre sheat. + - rscadd: reworked ninja's stealth mode. Increased invisibility, but engaging in + combat, attacking or throwing things, bumping people will temporarily lower + it. + - rscadd: Ninja shoes are even stealthier. + - code_imp: cleaned up some 2014 tier processing code horror. + - tweak: the oxyloss fullscreen overlays now also take in consideration 1/5 of the + user stamina loss. + - rscadd: When you're jogging, you will only slip on water if you have more than + 20% staminaloss, for real this time. + - imageadd: Different cuffs now come with different worn overlays instead of a generic + one. + - bugfix: High luminosity eyes can now be properly deactivated and won't illuminate + your surroundings again until turned back on. + - bugfix: Fixes freshly cloned people starting with undershirts. Fixes random characters + possibly rolling with undergarments of the opposite gender (Doesn't affect preferences' + freedom of choice). + - balance: MRE menu 3 has cuban nachos instead of a chili now. + - bugfix: Removed the illustration overlay from MREs, looks pretty weird otherwise. + - rscadd: MRE menu 4, vegetarian. + - bugfix: fixes a few bad touchs on combat mode pushing. + - bugfix: Fixes clock cult Abscond scripture not dragging pulled mobs into Reebe. + Also fixes blood cult tele runes teleporting you from the source turf to the + source turf. + - bugfix: fixes clock cult mass recall. + - bugfix: Fixes underwear colors a bit. + - bugfix: Fixes Blood Cult conversion prompts + - rscdel: Removes an obnoxious temporary overlay var. + - bugfix: colorable socks can be colored again. + - bugfix: Fixed undergarments color preferences resetting each round. + - bugfix: Fixed a few dozen suits' body coverage inconsistencies. These changes + shouldn't affect armor and utility vests for most. + - bugfix: Fixed clown shoes and work boots. + - bugfix: Fixed some overlay bug that happens when legcuffed and then handcuffed. + - balance: Slowed down police baton and tele baton speed by 75%, should be still + be faster than the legacy speed (2 seconds) by 0.6 seconds. Telescopic batons' + stamina cost per swing is now on par with police batons, ergo more expensive. + - bugfix: Fixed undershirts n socks colors prefs. + - bugfix: You can now alt-click to rotate machinery such as the tachyon-droppler + array or emitters again. + - bugfix: Sofas can't be wielded and transformed back into plain chairs anymore. + - rscadd: Enables emojis for PDA messages. + - balance: Removes revenant blight's shabby toxin damage in favor of mood maluses, + and a dangerous necropolis curse if not cured in time. Remember + - tweak: Blood cult altar, forge and archives now use radial menus. + - bugfix: Fixed some machineries' UIs. + - tweak: blood and clock cultists messages from metabolizing + - bugfix: Fixed advanced medical scanners borg upgrades. + - bugfix: Fixes certain borg upgrades being unapplicable on dogborg counterparts + of the target cyborg type. + - bugfix: Fixed people being shovable hrough windows, windoors and the such. + - rscadd: You can now shove people into disposal bins. + - refactor: refactored altdisarm(), ergo the "shoving people around" proc. + - tweak: war ops is now lowpop friendly and doesn't require roughly 54 starting + players anymore. + - rscadd: Singularity beacons now also moderately increases the odds meteor waves, + while lowering their estimeed arrival countdown. + - bugfix: non-alphanumeric graffiti decals will no longer display as "letter". + - balance: Nerfs cyborg disabler and its internal power cell to hold 25 disabler + beam shots rather than 43/44, just like a normal disabler. + - bugfix: Adds some missing species_traits for cloth, clockwork and cult golems. + - rscadd: Added towel linen bins, found in dormitory restrooms. Also enhanced the + bedsheet bins found in some stations' dormitories + - imageadd: Resprited bedsheet bins in 3/4 perspective + - tweak: Made SDGF ghost poll message less verbose, made the experimental cloner's + complaint with the former, and added ghost poll ignore options for both. + - bugfix: fixing some related onmob sprites issues with the above accessory. + - bugfix: Teleprods work on non-carbons mobs now. + - bugfix: Fixed tracking implant teleport issues. + - balance: Increased stunbatons power cell depletion rate when left on by 50%. + - bugfix: Gorlex Marauders are pleased to announce non-slip grooves were given to + their .50 sniper rifles, and thus shouldn't accidentally flop on the floor like + pocket spaghettis whenever taken out of a bag anymore. + - bugfix: Silicons can now operate teleporter, medical and security records console + from a distance again. + - bugfix: Fixed custom say emotes conflict with drunk memes. + - bugfix: Fixes identity transfer (envy knife, changeling transformation, making + a vr avatar) not copying digitigrade legs. + - bugfix: Fixes temporary transformation sting triggering heart attacks on heartless + humans. + - bugfix: Fixed mobs folded inside bluespace bodybags getting their clothing and + items deleted when passing through a recycler. + - bugfix: The alien-bursting-from-your-thorax and the xeno "hud" embryo stage images + will now properly delete them once the embryo egg lifecycle is complete. + - bugfix: Fixed artificier lesser magic missile. + - bugfix: Phantom thief masks will now fancy your combat mode yet again. + - bugfix: Fixed gulag teleporter stripping the user of stuff it really shouldn't + (like storage implant bags). + - bugfix: fixing cydonian armor a bit. + - imageadd: Resprited wooden and critter crates. + - imageadd: Improved the Cyber Sylph' good yet cumbersome bar sign a little. + - bugfix: Cyborgs can now use camera consoles on the edge of their widescreen. These + consoles are also TK friendly now. + - imageadd: Updated gang dominator sprites. + - bugfix: Miner borgs can again have installed PKA mods. + - bugfix: Fixed invisible blackberry n strawberry chocolate cake slices. + - bugfix: Nuke ops / adminbus combat mechs will no longer spawn with tracking beacons. + - imageadd: Arcade machine directional sprites. + - tweak: 'lowered the arcade''s random plush / other prizes ratio from 1 : 2.5 circa + to 1 : 5. Dehydratated carps and the awakened plush can not be achieved this + way anymore.' + - imageadd: Added armrests overlays to sofas and tweaked their sprites a little. + - bugfix: Fixed dogborg sleepers. Just don't tell me what is exactly fixed, cause + I don't want to find out. + - bugfix: Buffed the deep space familiar gorilla against runtimes. + - imageadd: Updated ratvarian computer sprites. + - bugfix: Fixed storage implant transplant. + - bugfix: Refactored how Jacqueen teleportation destination is selected, preventing + them from teleporting on off-station holopads. + Ghommie && Kevinz000: + - balance: Lichdom and necromantic stone skeletons are now of the spaceproof kind + too. + - tweak: skeletons now also like dairy products. + - rscdel: Halloween roundstart skeletons and zombies are no more spaceproof. + - rscadd: You can choose to set your species to zombie or skeleton through the pride + mirror yet again, Alas they are not of the spaceproof kind either. + Ghommie (Credits to Kmc2000 for the original PR): + - rscadd: Porting in MRE boxes from Yogstation. But be careful, eating possibly + expired MREs found in maintenance comes with an unrealistically large (actually + small) chance of food poisoning. Otherwise just bail out and order actually + safe-to-eat MREs from cargo for 2000 credits. + Ghommie (Original PR by Dennok): + - bugfix: Now areas_in_z get areas spawned by templates and blueprints. + Ghommie (Original PR by Dreamweaver): + - rscadd: Nanotrasen has received word of a high-tech research facility that may + contain advancements in bluespace-based research. Any crew members who become + aware of its whereabouts are to report it to CentCom immediately and are restricted + from sharing said info. + - refactor: The turf reservation system now dynamically creates new z levels if + the current reserved levels are full. + Ghommie (Original PR by JJRcop): + - rscadd: 'Ports in more emojis, including : flushed :' + Ghommie (Original PR by LaKiller8): + - bugfix: Goonchat options should now save properly. + Ghommie (Original PR by Vile Beggar): + - rscadd: Warden now has an added drill hat in his locker. You can change the loudness + setting of it by using a screwdriver on it. Use wirecutters on it for a surprise. + Ghommie (Original PR by coiax): + - refactor: atom/var/container_type has been moved into datum/reagents/var/reagents_holder_flags. + There should be no visible changes to effects. + Ghommie (Original PR by nemvar): + - rscadd: Botanists can now get beeplushies (or cultivator and bucket) as an heirloom. + - bugfix: Clowns and mimes will now properly pick either a can of paint or their + brand as heirloom now. + Ghommie (Original PR by tralezab): + - bugfix: Fixes an issue with spontaneous appendicitis picking incompatible mob + biotypes. + Ghommie (Original PRs by Tortellini Tony and BuffEngineering): + - bugfix: E-cigs will continue to display their setting after being emagged. + - bugfix: Vapes now come out of the mouth. fix Fixes an E-cig initialize() runtime. + Ghommie (Original PRs by nemvar and Rowell): + - rscadd: Added beekini bras and panties, thigh-high and knee-high bee socks. + Ghommie (by Arkatos): + - bugfix: Fixed an issue with a Lizardwine drink crafting, where a final product + would contain unwated 100u of Ethanol. + Ghommie (by Floyd / Qustinnus, Arathian): + - rscadd: The robotocist now has robe to show his love for toasters + Ghommie (by nemvar): + - tweak: Dwarfs are now more robust. + Ghommie (original PR by 4dplanner): + - bugfix: thrown objects (but not mobs) no longer hit the thrower + - bugfix: mirror shield rebound no longer depends on the original thrower's momentum + Ghommie (original PR by 81Denton, kriskog and nemvar): + - spellcheck: Sleepers now show a message if players try to unscrew the maintenance + hatch while they're occupied or open. Fixed typos in sleeper/organ harvester + messages. + - tweak: Sleepers and dna scanners can now be pried open with crowbars. + - tweak: You can open and close sleepers and dna scanners by alt-clicking them. + - bugfix: The scanner's hatch now must be closed (on top of being unoccupied), just + like sleepers, before being screwdriverable. This fixes a tricky door stuck + issue with the machine. + Ghommie (original PR by AffectedArc07 and Shazbot): + - imageadd: Added 8 new sock styles + Ghommie (original PR by AffectedArc07): + - tweak: Religion is now a globalvar instead of being a subsystem for some reason + Ghommie (original PR by AnturK): + - bugfix: Supermatter now melt walls if it finds itself in one. + Ghommie (original PR by Anturk): + - rscadd: Recipe for fabled secret sauce can now be found in the deepest reaches + of space. + Ghommie (original PR by Barhandar: + - bugfix: Pumpkin meteors on Halloween now replace catastrophic meteor waves, instead + of ALL OF THEM. + Ghommie (original PR by CrazyClown12): + - tweak: The chloral hydrate inside of the sleepy pen is no longer slower acting + than chloral hydrate made in chemistry. + - tweak: The chloral hydrate inside of cookies synthesised by emagged borgs is no + longer slower acting than chloral hydrate made in chemistry. + - balance: Slight tirizene buff. + - rscdel: Delayed chloral hydrate + Ghommie (original PR by Denton): + - tweak: Nanotrasen has started shipping more types of bedsheets to its stations. + - rscadd: Added in Runtime, Pirate and Gondola bedsheets. The second one can also + be found in some pirate ships, while the last can be crafted from gondola hides. + - balance: You can no longer reveal the 'illegal tech' research node by deconstructing + .357 speedloaders, riot dart boxes, syndicate cigarettes, syndicate playing + cards or syndicate balloons. + Ghommie (original PR by Mickyan): + - bugfix: Fixed being unable to smother people using the damp rag + Ghommie (original PR by MrDoomBringer): + - bugfix: morgues have had their proton packs removed and as such no longer suck + in ghosts on closing. + Ghommie (original PR by MrDoomBringer, AnturK and YPOQ): + - bugfix: Explosions will no longer damage wizards in rod form, the supermatter + monitoring radio and megafauna GPS. + - bugfix: Supplypods no longer detonate their contents. + - bugfix: Fixed silicon items (e.g. cyborg modules) being destroyed by explosion + epicenters. + Ghommie (original PR by Naksu): + - code_imp: get_area() is now a define rather than a proc. + Ghommie (original PR by Nicjh): + - rscadd: Abductor console's select disguise option now uses a radial + Ghommie (original PR by ShizCalev): + - bugfix: Pineapple haters/lovers will get/no longer get pineapple pizzas respectively + from infinite pizza boxes. + - bugfix: As a non-human mob, hovering your cursor over an inventory slot while + holding an object in your active hand shouldn't runtime now. + Ghommie (original PR by Skoglol): + - code_imp: New helper proc for alt-click turf listing, bypasses any interaction + overrides. + - code_imp: Ghosts and revenants now use the new proc. + - bugfix: Ghosts can no longer toggleopen sleepers, adjust skateboard speed or close + laptops + - bugfix: Revenant can now alt-click turf to list contents. + - tweak: Revenant now slightly less nosy, use shift click to examine. + - tweak: Alt-clicking the same turf again no longer closes the turf listing tab. + - bugfix: Reduced ventcrawl lag greatly. + - bugfix: Mining bags will no longer drop ore into backpack. + - bugfix: Mining bags in backpack no longer interferes with other mining bags. + - bugfix: Fixes some storage size circumventions. + - tweak: Moved machine and computer frames below objects, parts are now always on + top. + - tweak: Moved structures (chairs, closets, windows, cult altars etc etc) below + objects. + - tweak: Moves mineral doors to airlock layers + - tweak: morgue/crematorium trays' layers shouldn't overlap bodybags' anymore. + Ghommie (original PR by SpaceManiac): + - bugfix: Disassembling a chem dispenser for the first time will no longer always + yield a fully-charged cell. + Ghommie (original PR by Swindly): + - rscadd: Arm-mounted implants that contain more than one item use a radial menu + instead of a list menu. + Ghommie (original PR by Tlaltecuhtli): + - bugfix: Other people's clothes burning no longer spam you + Ghommie (original PR by XDTM): + - bugfix: Reagents now stop their passive effects (for example, stun immunity) if + the liver stops working while they're active. + Ghommie (original PR by YPOQ): + - bugfix: Fixing roffle waffle, mushroom halluginogen and some invalid reagents. + - bugfix: Fixes clockwork armor not actually having armor. + Ghommie (original PR by cacogen): + - rscadd: The font size of all text in the chat window now scales + - tweak: High volume (megaphone/head of staff headset) is a slightly smaller + - tweak: Admins have slightly larger OOC text + Ghommie (original PR by coiax): + - code_imp: Randomly coloured gloves and randomly coloured glowsticks now have slightly + different typepaths, but otherwise function the same. + - code_imp: The Squeak subsystem has been renamed to Minor Mapping. + Ghommie (original PR by duckay): + - rscadd: Added better names and descriptions for blueshirt officer gear. + - rscadd: Added the above gear to the premium selection of the sectech + Ghommie (original PR by harmonyn): + - balance: Resisting out of bucklecuffs takes more/less time depending on the handcuffs + you used, i.e., fake handcuffs will not bucklecuff someone for ages. + - tweak: fake handcuffs shouldn't no longer demoralize restrained criminals scums. + Ghommie (original PR by monster860): + - bugfix: fixes advanced proccall + Ghommie (original PR by mrhugo13 on tgstation13): + - rscadd: The Syndicate has decided to equip their Syndicate leaders operative (Aswell + as their clown counterparts) with the new Combat Glove Plus! The new Combat + Glove Plus does everything the old boring Combat Gloves does but with the added + extra of learning Krav Maga upon wearing them, any other Syndicate operative + who wants to get in on the action will have to pay 5tc. + Ghommie (original PR by nemvar): + - imageadd: Some drinks have new icons or slightly altered icons. In particular + Wizz Fizz, Bug Spray, Jack Rose, Champagne and Applejack. + Ghommie (original PR by ninjanomnom): + - bugfix: Orbiting is a little more aggressive about staying in orbit. The wisp + as a result now correctly follows you over shuttle moves. + - bugfix: Gaps between sounds in some looping sound effects should no longer happen + as much under heavy server lag. + Ghommie (original PR by variableundefined): + - bugfix: Cancel button to assault pod destination selector. + Ghommie (original PR by wesoda25): + - balance: disembowelment no longer works on mobs that aren't dead or in critical + condition + Ghommie (original PRs by Akrilla, Arkatos and Denton): + - tweak: Sprays cans have a cap on how dark you can make objects. Art is uneffected. + - bugfix: Fixed a bug where you could get cyborg spraycans via pyrite extracts. + - rscadd: Added an infinite spraycan for admins to spawn. + Ghommie (original PRs by Denton and Skoglol): + - tweak: Reorganized the syndicate uplinks. Items are now mostly alphabetical, some + misplaced items moved to more fitting categories. Bundles, random item and TC + have been moved into a new category called "Bundles and Telecrystals". Gloves + of the North Star and Box of Throwing Weapons have been moved to Conspicuous + and Dangerous Weapons. Combat Gloves Plus have been moved to Stealthy and Inconspicuous + Weapons. Moved all implants into the Implants category. + - tweak: 'Added a new category to the uplink: Grenades and Explosives.' + Ghommie (original PRs by Floyd/Qustinnus, optimumtact, Denton and coiax): + - rscadd: You can now select what your pills will look like when making pills from + the Chem Master + - rscadd: Red pills can make you think. + Ghommie (original PRs by Jujumatic and PKPenguin321, respectively): + - rscadd: Minesweeper Arcade machines. The higher the difficulty setting, the better + the prizes will be. + - rscadd: Also keep your eye out for another new (and rare) arcade game! + Ghommie (original PRs by Kmc2000 and actioninja): + - rscadd: Added darkmode! You can opt-in to this by clicking the new toggle darkmode + button just beside the settings one. + - rscadd: Byond members will now have a new setting for their Antag OOC color, instead + of using their OOC one. (Antag OOC still locked under admin discretion though) + - rscdel: Default black'n'white windows style. + Ghommie (original PRs by Mickyan, Anturk, ShizCalev, nemvar and Naksu): + - rscadd: After rigorous mandatory art training for the crew, many new graffiti + styles are now available + - bugfix: Cleaned up some crayon and spraycan code for futureproofing. + - bugfix: Spraypainting blast doors no longer makes them see-through. + - balance: Paint remover now works on blast doors and the like. + - rscadd: Most objects can now be colored using a spray can. + - spellcheck: Added visible message to spraying objects and windows. + - rscadd: Colored lights now shine in different colours. + - rscdel: Removed individual buttons text in crayon/spraycan UI, speeding it up. + - bugfix: Text mode buffer is actually visible in the UI. + - tweak: Last letter of a text mode buffer no longer rotates out to be replaced + with "a", allowing the text mode to be used for individual symbols. + Ghommie (original PRs by Naksu and XDTM): + - bugfix: Transferring quirks now properly removes the roundstart trait from the + person losing the quirk. + - bugfix: Roundstart traits no longer block the removal of other sources of that + trait. + - code_imp: status traits are now a datum var, the accessors are now defines rather + than functions. + Ghommie (original PRs by Naksu and coiax, loser): + - code_imp: Cleaned up saycode + - bugfix: Taking mutadone while having the communication disorder brain trauma will + no longer spam your chat with messages. + - rscadd: IPCs now come with a subtype of robotic tongue without the omnilingual + ability, instead of innately having robotic voice spans. + Ghommie (original PRs by Nichlas0010 and ShizCalev): + - tweak: AI core display screen can now be set in character preferences. + - bugfix: AI core display screen will now be restore when revived. + - spellcheck: Corrected some inconsistent capitalization in the player preferences + screen. + - imageadd: Readded some forgotten AI sprites. + - bugfix: Fixed Hades AI death animation not playing. + - tweak: the AI icon-selection menu now uses a radial. + - imageadd: Added in the death icon_states for the "TechDemon" AI screen. + Ghommie (original PRs by ShizCalev and bobbahbrown): + - rscadd: Headsets now dynamically show in their description how to speak on any + channels they can use when held or worn. + - code_imp: Radio channels names and keys now use defines. + - tweak: The head arrival announcement will now be broadcast to the supply for the + quartermaster. + Ghommie (original PRs by ShizCalev): + - bugfix: Fixed a bug that allowed you to teleport an ID in your possession to a + PDA anywhere ingame. + - bugfix: Fixed an exploit allowing you to steal ID's/pens from PDA's not in your + possession. + - bugfix: Fixed an exploit allowing you unlimited control of a PDA's interface even + if it wasn't near you/in your possession. + - bugfix: Fixed Pride Mirror exploits. + - tweak: Corgi collars can now be removed! + - tweak: Updated the corgi & parrot inventory panels to use the same formatting + as other mobs + - bugfix: Fixed corgi inventory panels not closing properly. + - bugfix: Fixed the parrot inventory panel not closing properly if you're not able + to interact with it. + Ghommie (original PRs by ShizCalev, MrDoombringer, AnturK, bgobandit, 81Denton and actioninja): + - rscadd: Failsafe codes for uplinks are now available for purchase. + - rscadd: Nuke Ops now have the ability to purchase a usable RPG, the PML-9, as + well as a couple different types of rockets for it. you can also suicide rocket + jump with them! + - spellcheck: Improved Uplink item descriptions and formatting. + Ghommie (original PRs by ShizCalev, coiax and Tlaltecuhtli): + - bugfix: Caks will no longer override the bonus reagents provided in a donut when + frosting them. + - bugfix: Caks can no longer create frosted frosted jelly donuts. + - bugfix: Jelly donuts will no longer lose their vitamins when they're frosted. + - bugfix: Fixed chaos donuts potentially doubling the amount of reagents added when + microwaved with something else. + - bugfix: Donuts now always contain 1 sprinkles as was stated on the wiki. Frosted + donuts have a chance at adding an extra sprinkle. + - code_imp: Improved the code for ensuring that security members enjoy donuts and + security-themed alcoholic drinks. + - balance: neurotoxin doesnt insta stun but gives you limb paralysis overtime and + heart attacks if it stays in for too long and it is also alcholic + - balance: beepsky smash now summons imaginary beepskys that deal stamina damage + instead of outright stunning + Ghommie (original PRs by Time-Green and Qustinnus): + - tweak: loot crates can't explode after unlocking anymore + - bugfix: jumping into loot crates no longers causes them to go boom + - bugfix: You can now deconstruct abandoned crates with a welder without making + them go boom. After unlocking them, of course. + Ghommie (original PRs by Tlaltecuhtli and nicbn): + - rscadd: alt click to eject beakers from chem masters + chem dispensers + grinders + + chem heaters + - rscadd: hit chem master + chem dispenser + chem heaters with a beaker and if its + loaded with another it swaps em + - rscadd: All-In-One Blender UI uses a radial menu now. You can see the contents + and reagents by examining. + Ghommie (original PRs by XDTM, 4dplanner, nemvar and, yes, myself): + - code_imp: Merged tinfoil hat kind of protection into the anti_magic component. + - rscadd: Tinfoil hats can also be warped up from excessive dampening of mindray/though + control/psicotronic anomalies, or by simply being microwaved in an oven, and + become useless. + - rscadd: Immortality Talisman and Paranormal Hardsuit helmets now come with tinfoil + protection too (minus the paranoia and limited charges). + - balance: Genetics/Slime/Alien Telepathy and Slime Link are now stopped by tinfoil + protection. + Ghommie (original PRs by XDTM, optimumtact, Nichlas0010 and monster860): + - rscadd: 'Added Quantum Keycards, devices that can link to a quantum pad, and can + be used on any other quantum pad to teleport to its linked pad. spellchecking: + Renamed "Bluespace Teleportation Tech" tech node to "Bluespace Travel".' + - tweak: Moved roasting sticks from the "Bluespace Travel" to "Practical Bluespace". + - rscadd: Spraying holy water on tiles will now prevent cult-based teleportation + from using them as a destination point. + - tweak: Quantum, wormhole and magic teleportation is no longer disrupted by bags + of holding. + - bugfix: You are now also blocked from teleporting IN to no-teleport areas, not + just out of them. + - tweak: Quantum teleportation now makes pretty rainbow sparks instead of the normal + ones. + - bugfix: Non-bluespace teleportation (spells etc.) no longer makes sparks. + - bugfix: Fixed teleportation deleting mob spawners like golem shells and ashwalker + eggs. + ? Ghommie (original PRs by carshalash, GranpaWalton, BebeYoshi & Hexmaniacosanna, + Fire Chance, Ordonis, Krysonism and OnlineGirlfriend) + : - tweak: Reduced booze power of Mead, Red Mead, and Irish Cream. + - tweak: Increased booze power of Grappa. + - rscadd: Added a new premium drink to the soda machine called "Grey Bull" which + gives temporary shock resistance + - rscadd: A new drink called Blank Paper was added to the bar menu, it was made + by a mime and it represents a new start. + - rscadd: 'Adds a variety of fine alcoholic beverages for discerning patrons of + the bar: Wizz Fizz, Bug Spray, Champagne, Applejack, Jack Rose, Turbo, Old + Timer, Rubberneck, Duplex, Trappist Beer, Blazaam and Planet Cracker!' + - rscadd: 'Also more nonalcoholic drinks: Cream Soda, Lemonade and Red Queen.' + - rscadd: Packs of a novel artificial sweetener have been added to the kitchen + vendor. + - rscadd: Bottles of trappist beer and champagne are now available in the premium + seection of the booze-o-mat. + - rscadd: Juicing parsnips now yields parsnip juice. + - rscadd: Maintenance peaches. + - bugfix: Grape soda now cools you down like other sodas. + - tweak: tweaked the Arnold Palmer recipe, it now uses lemonade. + - imageadd: Added new drink, bottle, vomit and peach can sprites. + Ghommie (original PRs by grandpawalton and Mickyan): + - tweak: the contents on the smartfridge icon now change depending on how many items + it contains + - bugfix: opening the maintenance panel of smartfridges now correctly updates the + icon + - bugfix: Screwing a disk compartmentalizer no longer makes it look like a smartfridge. + Ghommie (original PRs by nicbn and coiax): + - rscadd: Microwave UI uses a radial menu now. You can see the contents by examining. + - rscadd: Microwaves have a single wire accessible when open, the activation wire. + When cut, the microwave will no longer function, when pulsed, the microwave + will turn on. + - rscadd: Stabilized dark purple extracts now cook items in your hands, rather than + dropping the cooked item on the floor. + Ghommie (original PRs by ninjanomnom and nemvar): + - bugfix: Trays now scatter their contents when used for attacks, like they are + supposed to. + Ghommie (original PRs by ninjanomnom, coiax, yoyobatty): + - bugfix: Fixed slaughter demons not getting a speed boost when exiting a pool of + blood. Fixed slaughter demon giblets not being visible. + Ghommie (original PRs by subject217, AarontheIdiot, pireamaineach, Gousaid67 and SouDescolado): + - balance: Removed plasmamen species speedmod in favor of a slowdown for envirosuits. + - rscadd: Nanotrasen has began deploying departementalized enviro plasmasuits to + the station! plasmamens can now benefit from some of the bonuses aswell as the + color pattern of their job, while allowing others to easily determine their + profession! + - bugfix: Benevolent Nanotrasen makes gulag available for everyone! (Plasmamen retain + their equipment and don't die.) + - rscdel: Removes code that theoretically limits plasmamen from being clowns and + mimes, but actually doesn't. + Ghommie (original PRs by zeroisthebiggay, AnturK, MrDoomBringer, Cobby, ATHATH, optimumtact, GranpaWalton, Skoglol): + - bugfix: Blob overminds, sentient diseases, etc. can no longer dump out boxes. + Sorry gamers. + - rscadd: Sentient Disease now has almost all symptoms at its disposal. + - code_imp: Adding single-symptom disease abilities is super easy now. + - bugfix: Sentient Disease can now hear (not sure if this was a bug or intentional). + - rscadd: Sentient Disease is a linguist and knows all languages. Still cannot speak. + - tweak: Gives Sentient Diseases a medical hud to observe their victims further + with. + - bugfix: Fixes and moves around some on_stage_change() and Start()-related things + for virus symptoms and (sentient) diseases. + - bugfix: The inorganic biology symptom should work properly now when bought by + a sentient disease. + - bugfix: Oxyloss icon no-longer shows up when someone has the self respiration + symptom + - tweak: The self respiration now makes you not contract diseases through the air + and not breathe in smoke + - bugfix: Sentient diseases can no longer pick two cures that react and disappear + when eaten. + - balance: Sentient disease cures are now consistently harder, will only pick cures + from tier 6 and up. + - bugfix: Disease cures should now stay the same for all infected mobs. + - rscadd: The regenerative coma symptom has a new resistance 4 threshold effect! + Said threshold effect will give hosts of the symptom's virus the TRAIT_STABLECRIT + trait if its threshold is met. + - bugfix: An obscure, probably never reported before bug that may or may not exist + involving sentient diseases and the self-respiration symptom should be fixed + now (if it even existed in the first place). + - balance: The cooldown time between each removal or addition of a symptom for sentient + diseases has been brought down from an agonizingly long 2 minutes to a more + reasonable 1 minute. + Ghommie (original pr by Dennok on tgstation): + - bugfix: Now you don't lose your pulled thing on the z level edge. + GrayRachnid: + - rscadd: Added windoors to all the flaps on delta. + - balance: rebalanced k9dogborgs + Hatterhat: + - rscadd: Magnetic pistols now fit in boot pockets - jackboots, workboots, etc. + - tweak: literally every pistol subtype fits in shoes now. go wild. + Hippie Circuit Port: + - rscadd: Added all Atmospheric Circuits + - rscadd: Added the ability to color data disks + - rscadd: Added Selection and Storage Examiner Circuits + - rscadd: Added Smoke, Extinguisher, and Beaker Connector Circuits + - rscadd: Added Inserter, Renamer, Redescriber, and Repaint Circuits + - rscadd: Added MMI Tank and pAI Connector Circuits (The possibilities are endless!) + Improving and Balancing Cyborgs: + - rscadd: Added Crew Pinpointer to Security Borg + - rscadd: Added Crew Monitor to Medical Borg + - rscadd: Added Crew Pinpointer to MediHound Borg + - tweak: Made the Disabler_Cooler compatible with both Security Borg and K9 Borg + - tweak: Changed the Warning Text upon selecting Security or K9 module + ItzGabby: + - rscadd: Bat Species parts for more leeway for character customization. + - code_imp: Alphabetized decor wing selection window in character creator for simplicity. + JTGSZ: + - tweak: Added one more gang boss slot bringing total to 4 from 3 + - bugfix: Fixed Gang Boss being able to be deconverted + - tweak: Gave Qualifies_for_Rank Check back its checks in job controller. + - rscadd: Optional species based clothing restrictions + - tweak: Gang Dominator excessive wall check tweaked to 25 open turfs + - bugfix: Gang Dominator no longer functions off-station. + - rscadd: Adds more control over species based offsets. + - bugfix: qualifies_for_rank now checks latejoin menu + - rscadd: Added Halloween Dwarves, for Halloween... Yep. + - bugfix: Can flip pipes once more. + - bugfix: barricade girder walls use PlaceOnTop instead of new + Linzolle: + - rscadd: ability to quickly max sensors + - bugfix: atmos helmet visual bug + - bugfix: supply display are now properly on the wall + - tweak: consistency in hop and cap berets + - tweak: slime people now enjoy eating toxic food and it will not disgust them + - bugfix: hos trenchcloak now properly has a sprite on digi characters + - rscdel: duplicate definition of hos and sec skirts + - bugfix: Krav Maga leg sweep now works properly. + - rscadd: shoes can have a different icon used for their item and mob icons + - bugfix: combat gloves plus having no mob icon + - rscadd: inhands sprite for rainbow knife + - tweak: colour of highlight on the regular knife when held in the right hand + - rscadd: mining shuttle console can now be printed after computer consoles have + been researched + - rscadd: can now carry people on your back by aggressive grabbing them while they + are laying down and then dragging their sprite onto yours. + - tweak: dragging people who are prone is now much slower, and carrying them will + allow you to move faster at the cost of taking 5 seconds to lift them up onto + your back. + - tweak: pacifists can now aggressive grab (cannot table slam people though) + - bugfix: blood on your body floating a bit to your right if you're a taur + - bugfix: some suits having no icon on tauric characters + - tweak: front facing CMO hardsuit icon for naga taurs + - tweak: colour of medical cross on CMO hardsuit for taurs + - bugfix: taur body and jumpsuit showing through mining suits + - tweak: all chaplain suits can hold the same items in suit storage + - code_imp: improvement to organisation for chaplain suits + - bugfix: blood halberd not going back to 17 force after unwielding + - spellcheck: unnecessary 's at the end of blood rites healing + - rscadd: QoL to blood rites, examine the ritual aura to view how many blood charges + are left + - code_imp: surgery cleanup + - tweak: dissection available round-start + - rscadd: better dissection surgeries from RnD, gives more points + - rscadd: abductors can now see what glands do + - code_imp: antagonist abductors now have a surgeon trait that teaches them every + surgery rather than having it just check if they're an abductor + - rscadd: muscled veins surgery + - bugfix: having one of your hands used up if you fireman carry but the person being + carried dismounts any way other than you dropping them + - rscadd: Four colour variants of ankle coverings. Select them on the loadout screen. + - imageadd: ankle coverings + - tweak: allows for shoes that don't cover your feet to be taken into account for + footstep sound effects and glass shards + - rscadd: Tend Wounds surgery. Heal in the field, with better healing the more damage + the patient has. + - rscdel: Reconstruction replaced by Tend Wounds + - balance: made Revival more accessible, more viable alternative to cloning. + - bugfix: advanced surgery tools can't perform lobectomy or coronary bypass + - rscadd: Decorative and insect wings can now be coloured individually, similar + to horns. + - bugfix: people getting assigned wings if their savefile is old. + - rscdel: wings that take the hair colour. Unnecessary if you can just set the colour. + - tweak: Cannot make horns pure black. Trying to do so will set it to a default + value. + - bugfix: decorative angel wings being invisible + - bugfix: abductors now actually work + - tweak: abductor scientist has their own greet message now + - bugfix: unable to read paper on airlocks + - tweak: ai can see paper (still just shows stars) + - rscadd: Target head and throw a hat at someone to toss it onto their head, knocking + whatever they're wearing off if they are wearing a hat. Some headgear can't + be knocked off this way. + MediHound: + - rscadd: Made Cyborgs be affected by Ion Storm Law Changes like AIs + MrJWhit: + - balance: rebalance melee stamloss + Multicam Config: + - config: removed whether or not the stuff for multicam was checking the useless + var and instead now checks the CONFIG_GET flag. + - admin: Admins now have a verb in the Server tab to turn AI multicam on and off. + Naksu: + - code_imp: default radiation insulation is now handled by atom vars rather than + a component, components can still be used. + - code_imp: squeezed a little bit more perf out of atmos + Nero1024: + - soundadd: Bare feet will now make the correct footstep sounds. + - soundadd: Other mobs will make the correct footstep sounds. + - soundadd: Crawling/dragging sounds for downed/incapacitated mobs + Onule & Nemvar (ported by Ghommie): + - imageadd: New Revenant icons + Original by Citinited, port by Sishen1542: + - rscadd: You can now use an airlock electronics on a locker to add a lock, and + can screwdriver an unlocked locker to remove its lock. + - rscadd: You can now remove the locks on broken or emagged lockers. + - tweak: Removing the lock from a personal locker now wipes that locker's ID details. + - tweak: Broken lockers have had their appearance changed. + Owai-Seek: + - rscadd: custodial cruiser cargo crate + - tweak: removed light replacer from power designs and moved to misc designs + - tweak: added pimpin ride to custodial locator + - tweak: added additional items to janibelt whitelist + - tweak: made plant DNA manipulator unwrenchable + - balance: reduced janitor premium supply costs + - bugfix: fixed them strawberries + - rscadd: false codpiece + - rscadd: crocin/camphor bottles + - tweak: updated kinkmate item list + PersianXerxes: + - code_imp: Adds the clockwork_warp_allowed flag to the Captain's Office area, set + to FALSE the same way it is for the chapel and armory. + - tweak: Relocates cult catwalks outside the Reebe dressing room. + Poojawa: + - rscadd: Digitigrade legs are now able to wear shoes and look fancy, Uniforms to + come. + - tweak: Xenos are only digitigrade now, mammals and aquatics have the option. + - rscadd: Fire Alarms are visible in low light situations + - bugfix: fixed vore prefs saving inconsistently, new characters might have a previous + slot's prefs tacked on. + - bugfix: fixed mammals not having the option for digilegs. Sprites are fucky until + body-part related sprites are done. + - refactor: improved vore sound responsiveness to preference choices. + - balance: removed morphine from Medihound sleeper chemical list + - bugfix: fixed preference setting being broken + - refactor: Medihound sleepers are Initialized properly, and icons update correctly + now on eject + - tweak: Air alarm All clear color changed from green to blue + - balance: APCs are harder to destroy. + - rscadd: Added Digitigrade versions of everything appliciable in suit.dmi + - imageadd: Snowflake Icons weren't modified, and were given NO_MUTANTRACE_VARIATION + - imageadd: naga and quad Taurs literally don't freeze their ass off in space anymore. + - bugfix: Digitigrade legs will toggle on/off properly on character menue + - bugfix: The misleading "normal" has been removed from species options + - balance: Added sanity checks to emag usage + - bugfix: fixed vtech, but it still doesn't work because of overriding jog/sprint + mechanics from combat reworks. + - bugfix: Puppy jaws properly store if you're emagged, they are also toggle-able + for stealth like the tongue. + - bugfix: 'Digitigrade legs should properly fucking update for the last fucking + time. Fucking snowflake code. refractor: Got rid of snowflake sechound cuffs, + gave them normal zipties like regular secborgs.' + - bugfix: dogborg sleepers actually extinguish people who are on fire, in case you + don't have time to lick them out. + - bugfix: Taur suits should fix themselves properly when worn by other people. + - rscadd: Added the Yogs/Oracle ported latejoin menu + - rscadd: All markings, tails, ears, and snouts for Citadel races are color matrixed! + - imageadd: all markings are on a per-limb basis, including Digitigrade legs! + - imageadd: a bunch of tails were blessed with tail wagging sprites, Fish, Sharks, + Fennecs, Wahs, raccoons, and others. + - imageadd: Tiger markings + tail added, skunk tails improved via sprites from Virgo + - tweak: tweaked some sprites to look better, but they absolutely could use a few + extra passes for quality + - rscadd: HumanScissors in the Tools folder will permit anyone to contribute matrix'd + markings to the sprite sheet, however Mam_markings is very, very full. Be careful. + - tweak: Character preview was both optimized for taurs and bad-touched for better + updating. I don't know if it'll be bad, but hey its better. + - rscadd: Added Dark Medihound and Pup Dozer from Virgo + - tweak: Clone pods no longer announce the name of the clone + - bugfix: fixed flavor text appearing when your face is hidden but you're not an + Unknown + - bugfix: Tauric suits now apply an (placeholder) blood overlay, as well as their + shield overlay. + - balance: Ashwalkers now have lungs. They cannot breath station air without suffocation + effects, but are completely fine on their homeworld. + - balance: Carbon mobs now have a maximum tolerance to oxygen of 50kPa. + - balance: Deluxe synthetic lungs have a very high bonus to O2 tolerance. + - bugfix: Digitigrade legs returned to normal, since digi leg markings overlay them + anyway. + - bugfix: commented out lizard mam_snout entries, because too many abominations + - bugfix: Vore Panel restored to have various interactions available again. Semi-untested + but should work as advertised. + - tweak: Vore Panel has more feedback. + - rscadd: is_wet var to bellies, toggled in the panel, will remove flesh sounding + struggles and the internal loop. JSON version updated. + - rscadd: Feeding var. You will need to enable feeding to recieve any feed vore + actions, but you can now feed yourself to mobs that have this set. TODO, Dogborg + sleeper feeding. + - rscadd: vore mode button now required to be enabled to perform vore actions. It's + the mouth icon! + - bugfix: Ash Drake vore fixed for actual reals this time + - bugfix: Mobs shouldn't spam the released contents announcement anymore on qdel + or death. Only if triggered + - tweak: Hostile mob code now properly ignores targets in bellies + - rscadd: Your belly can quietly growl if you're starving now. + - bugfix: Normal blood splattering isn't offset due to tauric mode + - rscadd: Added plasma man suit icons for taurs + - rscadd: Added bee butt for insects to have stripes + - tweak: adjusted random spawn sprite accessories, humans won't be demi by default + and lizard/mammal spawns will randomly get digitigrade legs + - bugfix: sprite adjustments for tentacles, as well as a misspelling. + - bugfix: Humans once again use ears and tail_human, as intended. This is to prevent + garish randomness + - bugfix: istype for species is actually correct and usable now, it'll be a factor + for monkey form expansions. + - bugfix: Hair functions are de-gendered and more easily selectable now. + - bugfix: Slimes can *wag, select markings and snouts, and yes it works. + - bugfix: Slimepeople extra parts now respect their hair_alpha in terms of being + somewhat see-through. it shouldn't stand out as badly now! + - bugfix: Hunger noises are now toggled per character + - bugfix: Ashwalker den is habitable by ashwalkers again + - rscadd: Medical belts now have overlays! Now you can see if a belt is useful or + just flatout empty. + - bugfix: fixed hypo MK IIs not being able to be put on medical belts + - bugfix: fixed Navy officer uniforms that failed to spawn + - code_imp: Loadout items will be forcefully added to backpacks or at your feet + instead of left behind at title screen + - tweak: hypospray kits hold 12 now, but only vials and sprays themselves + - bugfix: labcoats can carry MK II hyposprays on them now. + - rscadd: Vore Mobs are a thing now, not just ash drakes + - rscdel: 'Removed hunger sound stuff. never taking requests from Coolgat3 ever + again. refractor: Simple Mobs use the same system regular human mobs do, itjustworks.png' + - tweak: Character Window settings unsnowflaked and normalized. I have no fucking + clue how to make them work with taurs still tho, sorry. + - imageadd: added rotating background images for better clarity and contrast than + just SOLID FUCKING BLACK. Images from Virgo/Polaris/Eris + - balance: Defib users automatically stop pulling when they attempt to perform a + defib shock + - imageadd: added muzzled varients of space helmets and full masks + - imageadd: added knight_grey to taur suits, all paranormal ERT now have tauric + versions enabled + - bugfix: Lava knights have digitigrade and tauric versions now + - rscadd: Added a glass version of the gas mask, because it was in the files and + looked nice. does everything regular ones do except make you an unknown + - rscadd: Added custom species names! Examining people will now display their species + name unless they're an Unknown or have their face hidden. like flavor text. + Set it in your character window! + - code_imp: changed how health scanners print messages, wrapping it in msg for one + to_chat instead of printing every line to_chat. + - server: Discord bot will now report when a round ends and give the vague news + ticker that a sister-station would have received for the game mode and result + of the round. + - bugfix: fixed medical hardsuit overlay issue. I thought it was going to work well + but fuck byond. + - bugfix: None body markings shouldn't give rgb hell, but it also should reset properly + anyway. ree. + - bugfix: Sorted some sprites to better sooth my byond icon limit anxiety. + - bugfix: Box Cryopods expanded to 6 public. Permabrig cryo fixed. + - bugfix: Delta Cryopods expanded to 6 public. Permabrig cryo fixed. + - bugfix: MetaStation Crypods expanded to 6 public, relocated above sparring ring. + Permabrig cryo fixed + - bugfix: PubbyStation gained one more cryopod, Permabrig's cryo fixed. + - rscadd: Omega given one more crypod as well. + - rscadd: Gulag was given a cryopod. + - tweak: Box and Meta's cryo rooms are now a new room entirely. + - rscadd: Added erect states for all phallic bodyparts + - bugfix: YOUR DICK ACTUALLY STANDS UP NOW, YOU'RE WELCOME. + - bugfix: skintone locked genitals match the new skintone colorations. + - rscadd: added two new vaginal types and descriptions. + - bugfix: fixed borg defib runtimes + - bugfix: fixed heart attacks being nonlethal + - rscadd: Ported Oracle's cloning set up, you're now visible like cryo when being + cloned, though it's a mystery until you have skin on your meat puppet existance + - balance: Recyclers are unable to destroy the indestructible any longer. + - bugfix: Kiara's toy sabre now actually is the correct item + icon states + - bugfix: Generic armor for taurs fixed, there isn't actually any sprites for 'em, + so. Full sprites overlay over bodies, but I really can't be bothered to do all + the offset fixes otherwise. + - rscadd: Large maps have had a patient room transformed into micro chemistry stations + with nothing else in them. They've been labelled 'Apothecary' rooms and are + accessible by doctors. + - rscadd: females now have female defined sprites + - bugfix: Slime legs have had their excess pixels adjusted + - bugfix: Mammal normal legs are more in line with human legs now + - bugfix: fixed species like abductors and golems getting the fat tiddy or pingas + - bugfix: Atmos and Station alerts should be more alerting. + - rscadd: Added visible and hidden testicles + - rscadd: Added multi-boob support. Now you can have two or three pairs of breasts. + - bugfix: fixed missing vagina and breast sprites + - bugfix: fixed prosthetic hands being invisible + - bugfix: male foxes exist again + - bugfix: female chest markings improved from being too dark in comparison to their + other colors, blending better + - bugfix: Markings behave better on non-organic limbs. + - tweak: tweaked the name of Sublter to distinguish its use + - tweak: Gave a hint for vore posting. + - rscadd: Readded Ninja speech modifications with their mask + - rscadd: Pacifists can eat people for heal belly or noisy. Digestive modes are + auto-swapped to noisy + - rscadd: Added an underwear toggle button under 'Object' tab + - tweak: Genitals now layer under underwear. Hide these if they're too obnoxious. + - rscadd: Added digitigrade socks of all known ones anyway. + - tweak: tweaked the Genital character creation layout to look better + - bugfix: fixed having balls/womb when you don't have the linked organ at character + creation + - bugfix: fixed being able to squeeze semen directly from your balls. Probably. + - rscadd: NT Newscasters have had repeated reports of gang activity and are now + looking into it. + - rscadd: NT Psykers keep mumbling about last words of someone who died. Somehow + they even have a newsletter for this... + - bugfix: Gangster greeting messages are a batch message rather than 5 laggy to_chats + - imageadd: RCL now show what color is currently in use + - rscadd: Added RGB blood effects, know whose blood this is by color! + - rscadd: Added Synthetics blood, and a machine that produces it. A universal donor + for medical to heal people with. Make it via medical protolathe! + - bugfix: With hearts, slimepeople shouldn't die from the effects of not having + a heart. + - bugfix: Plasma vessels from xenomorphs will restore blood if you're on resin. + - server: Poly's speech now echos to the chat bot. + - rscadd: Added new wings to Insects and separated fluff from old ones, they're + Insect's new body markings now without being per-limb (for now). + - rscadd: Horns are now available to mammals, and they have their own color. + - rscadd: Legs are no longer a binary hack code, but actually something that can + be changed. Framework for tauric adaptations. + - rscdel: Purged Modular Citadel's sprite_accessories. + - bugfix: improved the quality of a number of sprites. + - tweak: Moths are now all insects. Avians and Aquatics are all anthromorphics. + Just as planned. + - rscadd: Anthromorphs can choose their preferred gibbing meat. I guess. Snowflakes + are weird. + - bugfix: Additional Gentlemen names. + - rscadd: Medical huds are now calibrated for Radioactive wavelengths. + - balance: Engineering equipment, blue space, and common storage containers are + radiation protected + - bugfix: fixed suit storage not cleaning radiation levels of everything stuffed + into them. + - bugfix: QM is able to hire/fire people to their department now. + - bugfix: cryopod UI isn't complete shit anymore + - bugfix: Cryopods purge silicon gear more efficiently now. Same with ghosts. + - balance: Med Sprays are now more aligned with patch mechanics + - balance: Chemistry is encouraged to be more varied in their healing, as well as + careful in its application + - tweak: Active NPC priority set much higher priority for the MC, with the intent + on making NPC combat more interesting + - bugfix: Clarified access descriptions of some jobs + - bugfix: fixed missing deco wing states + - bugfix: fixed a few things related to vore content + Putnam3145: + - tweak: Bottles in PanD.E.M.I.C 2200 can now be replaced with an inhand bottle + directly + - tweak: Ejecting a bottle from the PanD.E.M.I.C 2200 puts it directly into the + user's hand + - tweak: Alt-clicking the PanD.E.M.I.C 2200 ejects the current bottle + - bugfix: neural nanites only work/drain if you have brain damage or traumas the + nanites can fix + - tweak: Pod people can no longer get fat from standing in the light + - tweak: PanD.E.M.I.C 2200 now ejects onto itself instead of onto user if user's + hands are full + - rscadd: Added configs for a bunch of Dynamic rule parameters. + - config: Added defaults for all the configs (WIP). + - config: Added dynamic midround/latejoin antag injection to the config. + - balance: Made starlight condensation not kill slime people. + - balance: Added not-killing-slime-people to the transmission threshold of plasma + fixation and radioactive resonance. + - tweak: Made the clone scanner lock while it's scanning. + R3dtail: + - rscadd: Added 16 saltprimaryobject items Added 4 saltsecondarysubject items + - rscadd: Added a new carpet. Red! Also added said carpet to the Premium Carpet + crate from the cargo supply console. Trilby said she'd take care of the crafting + recipe. + Raptorizer: + - tweak: Doubled peach spawn rate + - tweak: tweaked numbers/variables + - balance: rebalanced numbers/variables + - spellcheck: removed unneeded code + Seris02: + - rscadd: Abductor Replication Lab ruin and advanced tools + - rscadd: Added looc hotkey + - tweak: made the autoprocess button relevant + - tweak: changes so that spooktober starts earlier + - bugfix: fixed the dark blue lum major effect + Sirich96 and Dennok (ported by Ghommie): + - rscadd: Added new Teleporter Station sprites + - rscadd: Added teleport station calibration animation. + Sishen1542: + - rscadd: Pentetic Jelly, new chemical made through mixing 1:1 slime jelly and pentetic + acid. + - tweak: Anatomic panacea now gives pent jelly instead of pent acid. Medbeams now + have TRUE tox healing to heal TOXINLOVER as well. + - balance: Changed bible heal proc, halving the healed damage and increasing brain + damage 5x in exchange for a much wider array of items to protect you from it. + - tweak: Moved around some chems from emag list into upgrades. + - balance: Added some fun chems to dispensers. + - bugfix: Gave dispensers old tg functionality. + - rscadd: Leather, cardboard, bronze & bone golems! + - rscadd: Bone hurting juice and interactions with plasmamen, skeletons & bone golems! + - rscadd: Ported addition of new CAS cards. + - bugfix: Ported a fix for CAS. + - rscadd: Added the ability to alter your genitalia as a slimeperson more than addition/removal. + - bugfix: fixed genitalia removal proc in alter form. + - balance: Ported the inability for non-station AI to interact with station z-level. + - balance: HoS mains can now peacefully sleep in their office. + - tweak: Podpeople now have customization options. + - bugfix: Removed the human check for cult conversion of captain/chaplain minds. + - balance: Roundstart carbon jetpacks now have full_speed FALSE. + - tweak: Adds plasteel to medical and security techfabs. + - rscadd: Added public autolathes to all maps. + - tweak: density = 0 + - balance: hugboxing mining loot + - balance: ling blade now has 40 armor pen + - rscadd: fun + - rscdel: bad stuff + - balance: mech bad + - balance: rebalances strained muscles + - rscadd: added in the assistant response team + - bugfix: fixed up access on the centcom hangar button + - balance: storage tweaks for belt briefcase + - imageadd: codersprite for belt briefcase + - rscadd: added pharaoh gear to chaplain vendor + - spellcheck: fixed typos in pharaoh items + - rscadd: made laser minigun not shitcode and also craftable + - soundadd: added new fire sounds for the laser minigun + - rscadd: holy lasrifle, hypertool, divine lightblade, and blessed baseball bat. + Four new holy weapons! + - balance: stamina and force tweaks for most holy weapons. + - tweak: prayer beads no longer deconvert after a 10 second timer, now just inject + holy water for delayed effect + - tweak: cultist runes are now destroyed with a bible or a null rod + - tweak: bo-staff now functions as a nerfed sleepy carp staff + - bugfix: fixed kevinz code to add in non-null rod child items as holy weapons + - bugfix: fixing chems for strained muscles + - bugfix: narsie no longer asks for consent + - bugfix: removed reflect from divine lightblade + - bugfix: teleporting a locker is bad + Sishen1542, original by @Tlaltecuhtli: + - bugfix: alt clicking the emitter now rotates it instead of only flipping + Sishen1542, original by @zxaber: + - balance: Utility mechs no longer automatically get beacons. + - balance: Tracking beacons no longer delete themselves when EMPing a mech, and + instead have a ten-second cooldown in-between EMPs. They also now do heavy EMP + damage rather than light. + - balance: Mechs that take EMP damage lose the use of their weapons and equipment + temporarily. Movement and abilities are not effected. + - balance: Mechs taking EMP damage no longer roll for a random malfunction. + Sishen1542, original by Arkatos: + - rscadd: Action buttons can now be dragged onto each other to swap places + Sishen1542, original by NewSta: + - tweak: updated the miasma canister sprites + Sishen1542, original by Skoglol: + - rscadd: Heaters/freezers now support ctrl clicking to turn on and alt clicking + to min/max target temperature. + Sishen1542, original by XDTM: + - rscadd: Using the wrong surgery tool during surgery no longer attacks the patient, + if on help or disarm intent. + - rscadd: Surgery steps are now shown in detail only to the surgeon and anyone standing + adjacent to them; the patient and people watching from further away get a more + vague/ambiguous description. + Skoglol: + - rscadd: You can now alt click storage (bags, boxes, etc) to open it. + Skully): + - rscadd: Nudity Permit, a completely invisible uniform that still has pockets and + such, to loadout options. It is more or less a direct port from the RP server. + SkullyRoberts: + - rscadd: Penis autosurgeon as rare maint loot. + TerraGS / Skoglol: + - rscadd: Adds toggleable light and blinking charge indicator to kinetic crusher + - rscadd: Kinetic crusher can now be one-hand carried. You'll still need two hand + to use it. + Thalpy: + - bugfix: fixes message_admins in SDZF + - tweak: Alkaline buffer recipe so people don't get grumpy and expanded the pH range + - bugfix: fixes buffers + - bugfix: fixes broken compiler because a var changed name + - bugfix: impure travis var anger + - rscadd: Added the ability to dispense smartdarts from the chemmaster. + - tweak: Tweaks medolier amd chembags to allow quickpickups of smartdarts, lets + the latter soak in beakers (on the floor) + - bugfix: fixed rounding errors with smartdart mixes. + - imageadd: added modified smartdartgun icon. + - bugfix: 1. Kev asked that there were no antag datums used, so that's been changed. + 2. Tricks can no longer turn someone into a dullahan, instead you have to spend + candies to get that. I felt it was too mean to turn people into that, I didn't + realise you couldn't revert it. 3. Barth will no longer as for impossible items. + 4. Barth will no longer as for the same item multiple times. 5. Barth will now + accept broader things, rather than asking for something, when meaning something + specific. 6. Jacq will now no longer poof off the z level. 7. Jacq will (hopefully) + stop spooking the AI by teleporting into there 8. Jacq will now try to teleport + to a location with someone nearby. 9. Barth will tell you where Jacq is currently + when you speak to him. 10. You can trade 2 candies for a Jacq Tracq (tm) 11. + Jacq should stop getting mad and cover the station in gas when killed. 12. Fixed + Jacq not singing (the link died). 13. Slightly changed wording so that people + will hopefully get to know her. 14. Jacq no longer disappears when you're getting + to know her. + Toriate: + - imageadd: 'All regular crates are now 3/4ths ToriCrates iamgeadd: Unused plastic + crate sprite added' + - rscadd: Blood freezer crates now have unique sprites. + - rscadd: RPD now has inhands + - imageadd: New sprites for RCDs and RPDs, inhands included + - imageadd: Updated the sprites of all the regular crates + Trilbyspaceclone: + - rscadd: cakes! + - imageadd: Made some sprites! -Love them really came out well + - rscadd: new economics + - tweak: cargo and robotics relationships + - balance: unbalanced something + - bugfix: fixed a maybe oversight + - rscdel: Fun + - tweak: costs of suit voucher + - balance: Unblances miner vender + - bugfix: spare cheaper brute kit + - tweak: harm from hentie + - balance: rebalanced goliaths stun to be less auto death + - rscadd: Armor to blob shields + - tweak: block weaken state to 70% from 75% + - bugfix: restores the deathriplys missing armor + - rscadd: new lockable colalr + - tweak: armor + - bugfix: missing hopes and dreams + - code_imp: orgized the weapon file to be more cat brain friendly + - imageadd: This means sprite right? + - rscdel: Many engi flags on non-engi things + - code_imp: changed some code to be organized at a glance + - balance: '25% < --- 50% For NPC blocking bullshit ided: Yes' + - rscadd: mag gun uses cells + - balance: kev things their to op + - rscadd: syndicate phobia + - tweak: other phobia's + - bugfix: laser carbine + - tweak: makes collars only locked via key + - tweak: charging + - rscadd: Combat inducers for COMBAT! + - code_imp: made it look nice + - rscadd: golden swag boxes + - rscadd: Crafting suitcases + - rscadd: more bountys + - rscdel: Nitryl bounty + - rscadd: better stocks + - rscadd: more evil blood fluff text + - rscadd: Added more mime names + - tweak: replaces a sink with a autolathen + - balance: 2 -> 3 + - rscadd: MASON SUIT! + - rscadd: adds the sec jetpack to sec hardsuit storge + - rscadd: Added a few jet packs to the space queens men + - tweak: volume of jet packs + - rscadd: Bad Idea + - rscadd: bio mass meat + - rscadd: more box options + - bugfix: a lack of replaceable boxes + - bugfix: clothing needing a emag + - tweak: 4 - > 5 + - tweak: 5->6 + - tweak: 4tc - > 2tc + - tweak: mulligan costs 4 - > 3 + - tweak: Tuberculosis 12tc - > 8tc + - tweak: 15 - >10 + - bugfix: both bags have the same name + - tweak: 5 - > 2 + - tweak: 3 -> 1 + - tweak: 2 < - 4 + - tweak: 1->2 and ultra + - rscadd: shield + crafting + - tweak: hierophant movment and melee attack + - rscadd: More plushies + - tweak: attack verbs and descs + - rscadd: bone satchles + - balance: rebalanced stunslugs + - rscadd: colored boxes, and more types + - tweak: harm and such + - balance: item classes + - bugfix: resonators being so shitty + - bugfix: 'Game braking bug critical: bug fix' + - rscadd: items to syndie surgery bags + - rscadd: SNOW CONES + - rscadd: carts buy-able cargo + - tweak: selling/time to craft + - bugfix: crafting problems, and red stamp exsplote + - rscadd: gives paper work sprites that are nicer + - rscadd: origami + - rscadd: gang tower shield + - tweak: costs of boots + - rscadd: organ box + - rscadd: Medical breifcaseses + - rscadd: New cargo crate for tech-slugs! + - rscadd: Ammo to each fitting crate + - bugfix: Cat-code + - spellcheck: fixed a few typos - Again my bad + - bugfix: fixed airless place + - rscadd: baklava + - balance: makes uplink kits more usefull for the risk + - code_imp: Changes some files to be better + - balance: As all things are not + - bugfix: fixing cat code that dosnt work, my bad + - bugfix: Arcades stealing from noodles + - rscadd: rapier + - tweak: speedy quirk + - spellcheck: Ironic + - bugfix: A bunch of minor issues with xenobiology are no more! + - bugfix: I didn't code it right it in the first place + - rscadd: new nodes + - balance: points and node gear + - rscadd: stuff n things + - rscadd: gear harness and a conflict merg + - rscdel: Nudity permits + - bugfix: nothing + - rscadd: Donner item + - rscadd: Luna's Gauntlets + - balance: rebalanced lingy dingy powery gamey + - tweak: melee and block harm + - bugfix: sprites* + - balance: bone satchles + - tweak: holster doing holster things + - rscadd: Donor item + - rscadd: Joy, Happiness, Honk + - bugfix: small mix up in terms + - rscadd: Promiscuous Organs crate, pills to lewd crate and testicles to maints + - bugfix: Made unholy water healtoxinlover + - rscadd: Zelus Oil, brass flasks + - rscadd: Added new chairs + - admin: Bugtesting zone upgrades for easy bug/game testing + - rscadd: more cargo to cargo + - rscadd: More loadout gear + - bugfix: Poojawa power creep + - bugfix: Not my work not my credit + - rscadd: Emitter gun + - bugfix: suit storage nulling anti magic item protection + - balance: rebalanced steal goals restrictions + - spellcheck: fixed a few misleading goals + - bugfix: ports a fix + - bugfix: oversight in benos + - bugfix: QM rooms not getting Key Aunths + - rscadd: new books/cooking + - spellcheck: less bad wording in slime + - rscadd: strawbarries and such + - rscadd: amazing things like tea of catnip, catnip and plant + - tweak: glue uplinks + - rscadd: RPDs to drones + - rscadd: Armor and such + - rscadd: flavor + - bugfix: maybe a runtime + - rscadd: chameloen clothing + - rscadd: tons of peach themed items + - spellcheck: caje + - rscadd: New book - Unused + - code_imp: organized files + - imageadd: redid brass tools to look better* + - bugfix: /cursed from a item path + - rscadd: Almost all clothing and most weaponds can be sold for pocket change + - tweak: Cargo costs of packets and selling + - balance: Lowered mat selling as well as most if not all bountys + - code_imp: Adds more files for easy finding/adding in packs + - bugfix: oops not being blacklisted + - code_imp: removes some cit-modular things + - bugfix: Missing sprites with bad ones + - tweak: emag charge amount + - rscadd: Reebe QoL aka creep in gear + - bugfix: ??? + - server: HEY MADE THE REEBEEE WAY SMALLER - Making it less lagging hopefully + - rscadd: Surgerys and spays in bags + - tweak: earthbloods stam regen + - imageadd: Red to Blue/Black crosses as questioned by Bhijn + - bugfix: clean bot not cleaning basic cleanables + - rscadd: new traitor bundle + - rscadd: trash + - imageadd: 'eye bleed :add: misstakes' + - rscdel: Removed old things! + - bugfix: UI memes + - rscadd: Blue space blood bag + - tweak: blood costs + - rscadd: Beebal and Honeybalm plants + - tweak: Costs of crates and paperwork + - rscadd: Adds 2 more crates hacked only + - rscadd: Added two seed packets of cotten to ash walkers base + Tupinambis: + - tweak: Changes large parts of the nuclear operative base, including the addition + of a new barracks where the ops spawn, a personal bedroom for the leader, the + rearrangement of numerous rooms, some added fluff, a slightly more roomy bar, + a larger hanger, a kitchen, and various other small changes to make the base + feel just a bit more alive. This was achieved by completely redoing the base + from scratch so there was room to work with, as a result potential bugs could + crop, please do report them. + - bugfix: The drop pod chamber was airless. This seems like an oversight, and has + been filled with air. + - rscadd: Cryo Sleepers have been added to Perma on all four maps in rotation. the + bathroom windoor and window have switched places to accommodate this change. + - rscadd: You can now choose the pre-exisiting "loader" sprite as an appearance + for your engineering borg. + - tweak: A vast majority of references to humans within ion laws have been replaced + with crew. AI modules have received similar treatment + - rscadd: 'Adds a syndicate themed emergency shuttle that costs 20000 credits, and + can ONLY be purchased when the communications console is emagged. This shuttle + features a fully stocked medbay with self serve sleepers, plenty of room that + can fit highpop, a fully featured bridge, ballistic auto turrets, and an armory, + EVA prep room, and bar, all of which are only accessible by either an agent + ID or through hacking. + + -EVA prep features 2 syndicate hardsuits and 3 syndicate softsuits. -Armory + features 5 stetchkins with spare ammo, and 2 riot c-20r''s. + + ![image](https://user-images.githubusercontent.com/42078130/48306551-0b786380-e500-11e8-821a-e59ac4eee0ea.png)' + - balance: Lone operatives no longer spawn with a syndicate hardsuit and a bulldog. + They instead spawn with a black and red EVA suit and an extra 15 TC (40 in total) + ![image](https://user-images.githubusercontent.com/42078130/48308065-c44e9a80-e520-11e8-8d60-cec8ff23d61d.png) + - rscadd: The tesla engine has been replaced with a supermatter engine, and pubby + engineering has been redesigned to accommodate this change. + - rscdel: The tesla engine has been completely removed along with any related components + - bugfix: RD and R&D vents are now actually connected to the air distribution. + - rscadd: New engineering hivebot. Has a bit more health but otherwise aesthetic. + - tweak: Oldstation no longer has an excessive amounts of hivebots within it, however + the bots that remain are individually a larger threat. + - balance: Hivebots are now more robust, with a higher melee damage output and health. + - server: Remove this ruin from the blacklist or this PR is pointless. + - bugfix: the air injectors for the SM engine waste and for toxins waste should + now receive power + - tweak: Adds a mixed clothing closet to Deltastation Dorms. + - tweak: Adds a bottle of unstable mutagen to Botany, on account of its distance + from Chemistry. + - bugfix: Omegastation should no longer have any turf with missing textures, as + those spots have been replaced with playing covered in a sandy turf decal. + - tweak: Removed all living eggs from the xeno ruin because people self antag. Honk. + - rscadd: Adds a new security level between Blue and Red (Amber). The shuttle call + time at this level is 8 minutes. + - tweak: Blue security level now has a shuttle call time of 12 minutes. + - tweak: The security level increase/decrease texts have been modified to accommodate + the change. + - imageadd: Adds a code Amber sprite for the fire alarms + - tweak: Removed the plushes from the toy crate, giving them their own. + - tweak: Plushes are now less likely to spawn out of arcades + - imagedel: Removes a moth plush from the game. + - balance: added a small fire delay (3 ticks) to automatic shotguns + - balance: Reduced buckshot brute damage by 20%. (12.5 -> 10 brute per pellet) (75 + -> 60 brute at close range) + - balance: Reduced rubbershot stamina damage by 40% (25 -> 15 stamina per pellet) + (150 -> 90 stamina at close range) + - balance: Reduced beanbag stamina damage by 12.5% (80 -> 70 stamina per shot) + - balance: Engivend RCDs now vend upgraded RCDs + - imageadd: Beautified and stylized the cyborg HUD sprites, animated and cleaned + up some of the old, modernized APC hacking and Doomsday sprites, + - tweak: moved cyborg language select above the radio icon, instead of above the + picture icon. + Twaticus & Poojawa: + - rscadd: Added new carpets from TauCetiStation! + - rscadd: More Liquid carpet chemicals, mix carpet with certain reagents to get + different colors! + - refactor: Tablets have a better means of being assembled codewise. nothing's different + on player end. + UntoldTactics: + - tweak: Rewords the click here prompt given when an attempted conversion is done + on an offer rune (for blood cult) + UristMcAstronaut: + - bugfix: allows a pai to activate its holoform while in a pai connector without + getting derped. + Useroth: + - bugfix: the collars are now aware of their proper overlay sprites + - bugfix: The space hotel dorms are now properly boltable with the buttons inside. + - bugfix: Makes the booze-o-mat hacked by default. Alternative to https://github.com/Citadel-Station-13/Citadel-Station-13/pull/8350. + - bugfix: After the PR which raised the ammo capacity of said magazines, due to + the code, they ended up with an invalid icon state. Fixed through changing the + icon state name in the icon file. + - rscadd: 'Taeclowndo shoes which grant the four following abilities: - Conjuring + a cream pie right into their hand. Every three seconds. - Making a banana peel + appear out of thin air at the tile of the clown''s choice. Every ten seconds. + - Mega HoNk. A touch-ranged, very small AOE ability, with effect equal to being + honked by a Honkerblast on a clown mech, with the effects halved for anyone + who isn''t its direct target. Every ten seconds. - Bluespace Banana Pie. You + don''t throw this one... not right away at least. This baby can fit an entire + body inside. Good for disposal of evidence. 25 second-long action, 45 second + cooldown. Also produces a "[victim''s name] cream pie". The body drops out of + the pie if you splat it somewhere or destroy the pie. If you eat it, it will + chestburst out of you a''la monkey cube. + + It''s a 14 TC item for traitor clowns and a 12 TC item for clown-ops.' + - tweak: The tentacle now directly puts the item in your hands, instead of toggling + your throwing and tossing it at you. Tentacles suffer from ranged inaccuracies + as if they were guns, I think it's enough of an inconvenience. + - tweak: Makes the netting much less clunky. If there's only one target you can + net while you press the button, it will just net that target instead of bringing + up a list of mobs. + - tweak: Energy nets now revive and fully heal capturees (even dead ones, after + calculating points). If someone's got a scan and wants to get cloned, they can + always kill themselves still. + - tweak: Capture points are added on capture, rather than round-end, so it no longer + matters whether your captures kill themselves in the holding facility or not. + - balance: Makes the nets a bit more sturdy. (previously it took mere two welder + hits to break one) + - balance: Makes stungloves actually stun people (currently comparably with stunbatons, + adjustable). Because electrocute_act(25, H) did fuck all, stunwise, and on top + of that, people in insulated gloves were completely unaffected. + - balance: Reduced the stunglove electrocute_act value to 15 due to above. Could + possibly be lowered further. + Weblure: + - rscadd: Added the relevant Beepsky animations from TG's aibots.dmi file to Cit's + aibots.dmi file. + WhiteHusky: + - rscadd: Sleepers now show blood level and type. + - tweak: Changed the styling of arousal messages to use pink-ish colors. + - bugfix: The orgasm moodlet message new-lines properly. + - bugfix: Flavor text with special characters will not get partially unescaped. + - bugfix: Canceling when setting flavor text does not clear it anymore. + - tweak: Checking yourself shouldn't freeze the client anymore. + XDTM: + - rscadd: Added the experimental dissection surgery, which can be performed once + per corpse to gain techweb points. + - rscadd: Rarer specimens are more valuable, so xenos and rare species are more + efficient subjects. + - rscadd: Added two new surgery procedures, under the Experimental Surgery techweb + node. + - rscadd: Ligament Hook makes it so you can attach limbs manually (like skeletons) + but makes dismemberment more likely as well. + - rscadd: Ligament Reinforcement prevents dismemberment, but makes limbs easier + to disable through damage. + - tweak: Golem limbs can now be disabled, although they are still undismemberable. + YPOQ: + - bugfix: Stealth implants work again + Yakumo Chen: + - balance: Made stealth implant boxes flimsier + - balance: Autocloning now requires tier 4 parts + - rscdel: Removes autoscan + - balance: Scanning people now requires someone to operate the cloning computer + regardless of part level. + - balance: removed antimagic component from holymelon + YakumoChen: + - tweak: AEGs brought more in line with current radiation system. Try not to get + EMP'd. + - tweak: Jetpacks no longer last twice as long between air refills. + - rscdel: Reverted laser miniguns. + - rscadd: Adds beanbag slugs to the sec protolathe at round start + - bugfix: Brings shotgun ammo availability back in like between seclathe and autolathe. + Zargserg: + - balance: Lungs maximum toxin threshold is 0.5% of the atmosphere. + - bugfix: Permanently contaminated atmosphere does not murder crew anymore. + ZeroNetAlpha: + - tweak: Cleans up autoylathe code and brings it back in line with the regular autolathe. + - bugfix: Fixes autoylathe interface not updating propperly. + - tweak: Silicons are now consumable by scrub pups. + actioninja: + - bugfix: APC UI autoupdates correctly + bluespace bio bags: + - rscadd: Added bluespace bio bags and put it in the tech web, in the node applied + bluespace + - imageadd: added a crappy icon for bluespace bio bags + chef: + - rscadd: Added main hallway approach to monastery + - rscadd: Added Maintenance hallway approach, with some maint loot + - tweak: moved the docking arm for the white ship + - tweak: changed placement of some grills and windows + coiax: + - admin: When the nuclear disk stays stationary long enough to trigger an increase + for the lone op event chance, admins will be notified every five increments. + dapnee: + - rscadd: Plasmaglass tables, spears, tiny plasmaglass shards + - bugfix: Plasmaglass structures now drop plasmaglass shards instead of nothing + - rscadd: Trim lines! + - bugfix: You can now make plasmaglass tables again. + deathride58: + - admin: When a gamemode fails pre_setup, it will now send a message in admin IRC + and in ingame admin chat, instead of only being viewable in the logs. + - balance: Portal guns now spawn without firing pins. + - balance: Reduced the default/baseline nanite pool amount from 100 nanites to 25 + nanites, and reduced the maximum nanite amount from 500 nanites to 125 nanites. + The safety threshold was reduced from 50 nanites to 12 nanites. + - balance: Most of Lavaland's mobs are now on crack. + - balance: Blood drunk miners now move once every two ticks, rather than once every + three ticks. + - balance: Bubblegum now has a maximum movement speed of once every three ticks. + Buffed from the original value of once per 5 ticks. + - balance: The minimum time for the Colossus to attack again after firing a random + shot is two deciseconds, Sped up from the original value of three seconds. The + minimum time for the Colossus to attack again after performing a blast is now + one second, with the original value being two seconds. The minimum time for + it to attack again after performing its alternating shot pattern is now two + seconds, original value being four seconds. + - balance: Ashdrakes now move once every five ticks, rather than once every ten + ticks. + - balance: Heirophant chasers now move once every two ticks rather than three ticks + by default, and the chaser cooldown has been reduced from 10 seconds to 5 seconds. + The cooldown for the Heirophant's major attacks has also been sped up to 4 seconds + from the original value of 6 seconds. + - balance: The Legion (megafauna) now moves at two ticks per second rather than + three ticks. It additionally now actually moves faster while charging. The cooldown + timer for it's special attacks has been reduced from 2 seconds to 1 second. + Additionally, The Legion's view range has been decreased from 13 tiles to 10 + tiles. + - balance: All megafauna now have a default view range of 4 tiles, decreased from + the original of 5 tiles, and an aggro'd view range of 15 tiles, decreased from + the original of 18 + - balance: Goliaths now move once every ten ticks, sped up from the original value + of 40(!!!) ticks. Additionally, their cooldown for their tentacles has been + reduced from 12 seconds to 6 seconds. To compensate, their cooldown now only + decreases by 5 deciseconds every time they're attacked, rather than 10 deciseconds, + their melee damage has been reduced to 18 per hit from 25 per hit, and their + vision range has been decreased from 5 tiles unaggroed, 9 tiles when aggroed, + to 4 tiles and 7 tiles respectively. Ancient goliaths have a default attack + cooldown of 8 seconds, sped up from the original value of 12 seconds. + - balance: Legion (the common mob) now has a cooldown of 1.5 seconds on their skull + attack, sped up from the original value of 2 seconds. Additionally, their view + range has been decreased from 5 tiles, 9 tiles when aggroed, to 4 tiles, 7 tiles + when aggroed. + - bugfix: Stamina no longer regenerates at hyper speeds. + - tweak: To accommodate for upstream's stamina changes, knockdown() now applies + staminaloss only to the chest. + - tweak: adjuststaminaloss() now has a new argument that allows you to specify a + zone to apply staminaloss to. This defaults to the chest + - tweak: apply_damage() is now capable of healing carbon mobs and human mobs. + - tweak: Since the head has the same exact effects as the chest when disabled, and + doesn't really make much sense to be affected by stamina, the head no longer + has stamina. + - tweak: The chest now has a stamina cap of 200 stamina due to the above. + - tweak: Footsteps now sound mostly the same as they did before the hard sync + - bugfix: Jukeboxes now properly remove themselves from the active jukebox list + when destroyed + - rscadd: Server operators and badmins can now make the server play like TG by toggling + the stamina buffer on/off using the DISABLE_STAMBUFFER config option. + - bugfix: Airlock wires now work as they did prior to the hard sync + - balance: The thing you're currently grabbing is now taken into account when left-click + disarming. Things you have grabbed now roughly have a 45% chance to be disarmed. + - balance: Disarm push rolls are now determined by the target's staminaloss rather + than a flat number. + - balance: When you're in combat mode, pushing someone who isn't in combat mode + is a guaranteed knockdown. Hard counter to stam regen squeezing in melee combat. + - balance: Failed disarm push attempts now deals light staminaloss to the target + so long as both the attacker and target are standing. The total stamloss dealt + to the target is random, clocking in at a very inefficient 1-5 stamloss per + unsuccessful push attempt. + - tweak: Disarm pushes now play the thudswoosh sound regardless if they're successful + or not. Had it not been for copyright, I would've used L4D's melee sound. + - tweak: Disarm push attempts are now logged + - bugfix: Autostand no longer makes you invulnerable to dropping items when being + knocked down with a force greater than 80 + - bugfix: You can no longer abuse an href exploit to return from the labor camp + before obtaining enough points to satisfy your point goal. + - bugfix: Norko's donor item is now listed in the right category + - rscadd: The medihound sleeper now has a non-vore variant. This will be used by + default. The old voracious variant will only appear if both the person being + sleeper'd and the medihound have the voracious hound sleepers pref enabled. + Sprites by Toriate + - tweak: '"Allow medihound sleeper" is now labelled "Voracious medihound sleepers", + and is now off by default' + - bugfix: AOOC no longer prints to players in the lobby + - bugfix: Human tails and human ears now save again. Humans now use mam_tail and + mam_ears for their snowflake bits instead of tg's equivalent, just as they did + prior to human tail and ear saving breaking + - bugfix: Disarm pushes no longer deal staminaloss to resting targets + - bugfix: You can no longer force a hard stamcritted spaceman to stand by clicking + them with help intent. Get more creative if you want to torture someone that's + in hard stamcrit. + - tweak: The revolution gamemode now waits until the 20 minute mark before checking + for win conditions. + - balance: You can no longer resist/move out of grabs while you're resting. Disarming + your way out still works, though. + - rscadd: Stamina damage now has diminishing returns on people who are in hard staminacrit + with the addition of a new multiplier. When you take staminaloss while in hard + staminacrit, you'll be under the effects of the new multiplier, which reduces + the amount of staminaloss you take from all sources of staminaloss. The diminishing + returns multiplier will steadily return to 1 once you're out of staminacrit. + - rscadd: You can now scramble while resting. You can do this by dragging your spaceman + onto an adjacent turf. This works even if you're in staminacrit, but the timer + depends entirely on your staminaloss. + - bugfix: Fully augged cyborg people now heal stamina damage properly. + - bugfix: Job EXP is now tracked properly for all roles. + - balance: Nightmares and shadowpeople have had their light threshold for being + considered in darkness reduced. Nightmares can no longer stand unharmed next + to a light fixture during a nightshift 100% unharmed. The threshold is high + enough so that APC lights on their own won't harm a nightmare, but being on + the edge of a light source will. + - balance: The detective revolver's .38 bullets are now non-lethal again, but now + require 3 shots to hard stamcrit + - rscadd: The current lethal variant of the .38 bullets can still be printed at + sec protolathes. + - rscadd: You can now access ghost roles from the latejoin menu. + - rscadd: Eyeblur now scales depending on how much actual eyeblur you actually have. + - balance: Ebows now induce 50 drowsiness on whatever they hit. + - balance: Telepads have been buffed across the board. T1 parts on a launchpad still + grants you a range of 15 tiles, but T4 parts now grant you a pretty large 60 + tile range (up from their original 18 tile range). Briefcase launchpads were + also buffed, they now have a range of 20 tiles, up from their previous laughable + 8 tiles. + - tweak: The grace period for the revolution win condition check has been reduced + from 20 minutes to 10 minutes. You don't need to wait nearly as long for the + round to end if no heads join in. + - tweak: You can now select plural and neuter as your gender. They're labelled "non-binary" + and "object" in the character customization menu, respectively. + - tweak: A lot more light sources now use the same nonbinary colored lighting philosophies + as flashlights and light fixtures! + - tweak: Flashlights mounted to guns and helmets now retain the same color and power + as their original light. Lavaland's caves will reflect a fluorescent blue as + you shine your KA around, and sec's helmets are now capable of illuminating + maint in that fancy fluorescent blue. + - tweak: Cameras now shine a fluorescent blue when lit up by an AI + - tweak: Glowing goo now actually glows green. + - tweak: Candles had their power reduced from 1 to 0.8. + - tweak: Lighters now shine a little further, and are now properly colored. + - tweak: PDAs now shine an incandescent yellow to match their sprite. + - tweak: Welding tools now shine an appropriate color + - tweak: Hardhats now shine an incandescent yellow. + - tweak: Plasmaman helmets now shine an incandescent yellow. + - tweak: Microwaves no longer overpower literally every single light in the game, + instead having a power of 0.9. + - tweak: Borgs now have incandescent yellow lights to match their sprites + - tweak: Bots now shine a fluorescent blue light + - tweak: Airlock light overlays are now on the above lighting layer. This means + airlock lights can actually be seen in the dark now. + - bugfix: The mob spawners list no longer leaves null entries behind when a spawner + has a job description defined. The latejoin menu will no longer show ghost roles + that are filled, and the spawners menu actually works again. + - rscadd: The voting system now actually tracks who voted for what. This means it's + now possible to change your vote, and it's possible to see what you voted for. + - balance: Using help intent on someone that's in hard stamcrit will now make them + heal 15 stamloss. + - tweak: Auto fit viewport is now enabled by default for new players. One less question + off the FAQ + - rscadd: The Khajiit favorite, Skooma, was added as a chemistry recipe that can + be produced with cooperation between chemistry and either cargo or service. + If you want to spoil the recipe for yourself, take a look at the PR for it! + - rscadd: When the shuttle leaves for centcom, a vote will be started to select + the next map instead of the map being randomly chosen via biased voting methods + - server: If a server operator wishes to re-enable the biased TG preference voting + system, you can do so by toggling the TGSTYLE_MAPROTATION config flag on in + the config.txt. Keep in mind that doing so will bring you great misfortune. + - balance: Cacti in lavaland now have 6u of vitfro instead of just 4u. This lessens + the gap between cacti and first aid kits, the third rarest and second rarest + readily available healing methods for ashwalkers, respectively. + - bugfix: the "genitals use skintone" option now appears in the character appearance + menu when appropriate again. + - rscadd: Clicking your stamina bar will now show your exact stamina along with + info regarding your stamina buffer + - bugfix: The bug where ghost role spawners leave null entries in glob.mob_spawners + has actually been fixed + - bugfix: The Kitchen Gun (TM) is no longer invisible. + - balance: The majority of cult spells no longer have exclamation marks at the end + of their invocations. This means they will no longer be bound to the rules of + shouting. Which means sec officers will no longer be able to hear culties sacrificing + the captain from the complete opposite side of the maintenance tunnel the sacrifice + is happening in. However, things like EMP pulses and runeless teleportation + still have the effect due to their inherent loud nature. + - balance: The stun blood spell now instantly causes hard stamcrit. However, to + offset this, it now also only has one charge and has a higher cost. + - balance: The Gloves of the North Star now restore 2/3 of the stamina used up by + punches when harm intent punching. With aggressive play and good stamina buffer + management, this makes it entirely plausible to roughly double your stamina + regeneration per mob life process tick. + - balance: Revs can no longer remember the name of the person who flashed them when + deconverted. This brings it in-line with the other conversion antag deconversions. + - bugfix: The bug where you can sometimes get permanently stuck in stamcrit should + HOPEFULLY be fixed. I'm unable to reproduce the bug myself, but let's hope. + - balance: The night vision trait now grants you darksight for an entire 1:1 screen, + but the alpha of the lighting plane with the trait has been increased from 245 + to 250 to balance it out + - bugfix: It's now actually possible to click the stamina hud button + - bugfix: The stamina hud button now displays your stamina buffer correctly + - balance: Bone spears now have a reach of 2 tiles. + - bugfix: You can no longer phase through solid objects via scrambling + - bugfix: The syndicate mask now works properly as intended. + - balance: Stamina is no longer affected by health at all. + - rscadd: You can now right-click yourself in help intent in combat mode to instantly + get up from resting. This will cost stamina equal to your entire stamina buffer. + Manage your stamina well, and you'll be able to shrug off a single stray golden + bolt + - rscadd: The new player panel now displays your currently selected character's + name + - balance: Flashes no longer knockdown. Instead, they deal eyeblur and have increased + confusion + - server: The server's tagline is now a config option. People can now stop confusing + us with BR cit + - rscadd: Attack animations will now rotate your character slightly, similar to + Goon. + - rscadd: Throwing items will now perform the attack animation and play a sound + - rscadd: flashlights will now make sounds when toggled on/off + - rscadd: Things in disposals will now emit sounds every single time they hit corners. + This increases immersion. + - bugfix: Air alarms now actually emit the proper light color when their status + is okay. + - rscadd: Backpacks and other storage items will now jiggle and squish when you + interact with them, similar to the animations seen on Goon. + - balance: Mops no longer have a delay on their cleaning, making them an actually + viable alternative to all of the janitor's other cleaning tools + - balance: To balance this, mops now take stamina to clean tiles. Standard mops + take 5 stamina to use, while advanced mops take 2 stamina. + - tweak: Oh and also mops make fancy new sounds and play animations when used now + - balance: Pump-action shotguns now take 2 stamina per pump instead of 5 stamina + per pump. This also applies to bolt-action rifles, as bolt racking counts as + pumping. + - tweak: Pickpocketing items will now place them in your hands if possible + - rscadd: Combat mode is now displayed in examine text + - rscadd: Combat mode now makes a visible message when enabled if you haven't touched + your combat mode button in the last ten seconds. It's done this way to avoid + chat spam from those who know how to pull off stam regen squeezing. + - balance: All knockdown sources will now force people to be dismounted from ridden + vehicles. + - rscadd: When an item is thrown, it will now be rotated and displaced. + - rscadd: Shards of glass will now be rotated when spawned. + - rscadd: Bullet casings will now be rotated when they're ejected from a gun. + - rscadd: Bottles now have random rotations and pixel offsets when smashed via throwing. + - rscadd: Picking up an item will now reset its rotation. + - rscadd: Glasses thrown onto tables by bartenders will now have their rotation + reset. + - balance: Slime speed potions can now only increase the speed of vehicles to be + on par with sprinting speed. They can no longer make a scooter roll around ten + times faster than a speeding blue hedgehog. + - rscdel: Changelings will no longer recieve team objectives + - balance: Changelings no longer start off with hivemind communication as an innate + ability. Hivemind communication now requires 1 dna point, on par with syndicate + encryption keys, which are 2 TC. + - code_imp: Hivemind link now relies on hivemind communication just like the hivemind + download/upload abilities. + - bugfix: It's now only possible to zoom a gun if it's in one of your hands + - bugfix: Mobs without clients no longer cause runtimes when their eyeblur updates + - rscadd: Blood tests have been added. If a changeling has a sufficient number of + loud abilities, you will be able to test their blood by heating up a sample + of it. However, if the changeling has a large amount of loud abilities, attempts + to test their blood will have explosive results. + - rscadd: Changelings now make a very obvious noise when readapting. This is to + prevent the cheese strat of simply readapting when you get caught to avoid detection. + - tweak: The blood splatter effect that happens when you get attacked will now always + make you lose blood depending on the damage you've taken. The effect now also + scales with item damage, meaning tiny little papercuts will no longer be able + to cause a massive blood splatter. + - rscadd: The blood reagent will now cover items and spacemen in blood when applied + to objects and mobs. + - tweak: Helmets, masks, and neck items are all now valid targets to get splattered + when you get covered in blood. Groovy. + - tweak: The temperature notification will now take into consideration both the + ambient temperature and your body temperature, increasing the responsiveness + of the temperature notification and making it much more realistic. + - tweak: Shuttle transit borders are now 10 tiles wide instead of 8 tiles, hopefully + repairing the immersions that get shattered by the ability to see normal space + where the transit areas end. + - rscadd: Instead of transit turfs simply teleporting things to space, transit is + now handled in a somewhat realistic manner. Transit turfs now act like normal + space turfs, though exiting the transit area or being present in the transit + area after the shuttle moves out of transit will teleport you to space and throw + you in the direction the shuttle was moving in. + - tweak: Reservation areas are now able to designate a border turf. + - bugfix: The sprint hotkey will no longer cause you to get permanently stuck sprinting + if the server lags. Just tap shift again if you get stuck + - rscadd: You can now hear sounds in the real world while inside of a VR sleeper. + - rscadd: You can now make nameless characters. Nameless characters will spawn in + with their name set as their job title followed by a unique five digit number. + The "Name" option in the character setup menu will be replaced with a "Default + designation" option for nameless characters, and the default designation will + be used in place of a job title for assistants and other jobs that don't require + dress codes. + - admin: The out-of-game round end notification is now a little more verbose. It'll + now display the round type, end result of the round, and the survival rate. + - bugfix: Xenos can no longer strip items off of people to be capable of using any + item in the game. + - bugfix: also, items from pockets get placed into your hands properly now + - bugfix: A mob's last words are now properly tracked and recorded on death. The + first death of the round will now actually display the victim's last words on + the round end screen. + - bugfix: Divine shenanigans can no longer result in someone becoming immune to + staminaloss + - bugfix: Fixed body_markings in bodyparts being assigned as a list when in reality, + it's a string and literally everything expects it to be a string and uses it + as a string. This should mean that markings no longer have completely fucked + up caches for character preview and other things. + - tweak: Since apparently the game is literally unplayable if items are not in the + exact center of a turf, the maximum pixel variance of thrown objects has been + reduced by four pixels to make things a smidge more clearer for those that dont + know what a turf is. + - bugfix: Bartender glasses should HOPEFULLY no longer be tilted when landing on + a table. Why the fuck is after_throw called via a timer. + - rscadd: Changeling screeches now have their own unique sounds, and are much easier + to recognize. + - rscadd: Most synthetic emotes are now available to humans. *ping + - rscadd: You can now merp + - balance: The TEG will now only produce a meaningful amount of power if the hot + pipe contains gas that's actively combusting + - admin: Added the "add PB bypass" and "revoke PB bypass" verbs, which allow admins + to let a specific ckey to bypass the panic bunker for the rest of the round + - rscadd: Jogging is no longer treated exactly the same as sprinting for water slips. + When you're jogging, you will only slip on water if you have more than 20% staminaloss. + - tweak: The atmospherics turf subsystem now has double the wait time, which should + free up server processing power for other tasks. + - bugfix: The IRC now actually displays the actual survival rate + - rscadd: Bloodcult conversions are now consensual. Convertees are given a ten second + timer to accept or wait out. This should drastically improve the quality of + those that get converted into bloodcult. + - rscadd: All sacrifices now count as a third of a cultist for the end-game narsie + summon. + - bugfix: Nameless captains will no longer proc a "Captain Captain on deck!" message. + Instead, it'll be a much more boring but much more sensical "Captain on deck!" + message. + - bugfix: Transit turfs on the centcom z-level now function properly again at keeping + mobs within the areas defined by their boundaries. + - bugfix: The title screen is also positioned correctly again. + - tweak: Ghost role eligibility for both event and spawner ghost roles is now affected + by DNR status. If you suicide, ghost, or cryo out, you will be unable to qualify + for any ghost roles + - tweak: Cryo now applies DNR status no matter how long the round has been going + on + - tweak: Suicide is now properly admin logged as it is supposed to be. Ghosting + while alive is now also logged. + - bugfix: Sparks and igniters will now actually heat areas rather than cooling them, + as was intended. + - tweak: To alleviate some potential complaints, RPDs now have a cooldown before + they can create sparks, and both RPDs and emitters produce less sparks. + - tweak: Conversion runes will now mute the victim temporarily while they're deciding + whether to convert or be sacrificed. + - bugfix: Conversion runes no longer require a third cultist to sacrifice if the + victim refuses conversion + - bugfix: Staminaloss targeted at the head now properly redirects to the chest. + - tweak: Sprinting no longer takes stam when you're being pulled or when you're + in zero gravity. Other sources of involuntary movement are not affected. + - code_imp: In an attempt to improve performance during highpop, mouse movements + will now only call onmousemove() while a user is in combat mode + - tweak: Ballistic projectiles are now the only projectiles capable of emitting + dinks. + - admin: Panic bunker toggling and bypassing is now logged in admin IRC + - tweak: OOC and LOOC now use separate toggles. You can now use LOOC while OOC is + globally toggled off, and admins now have the option to toggle LOOC off separately + from OOC + - code_imp: also revamped and reorganized relevant looc adminverb code + - bugfix: The endgame narsie summon rune no longer requires 24 total sacrifices, + and will now properly account for cultists that surround it + - tweak: The succumb verb is now available in the IC tab + - tweak: Lighting now uses a linear algorithm to calculate falloff instead of an + inverse-square algorithm. + - code_imp: get_hearers_in_view() now actually caches the results of view() instead + of calling view() twice + - code_imp: Goonchat's JS no longer contains checks related to a completely unused + message filtering function, which should improve clientside performance quite + a bit + - rscadd: The storage hud now properly takes into account the viewer's view size, + meaning storage items with a large amount of storage slots will properly stretch + across the bottom of the screen when running in widescreen. + - rscadd: Action buttons are now able to fill the entire screen in widescreen and + other weird view sizes. + - rscdel: Omegastation's job changes will no longer be included at compile time. + - code_imp: The client update portion of /mob/Login() now double-checks to make + sure client.player_details exists and is of the proper type. This should hopefully + fix the "cannot read null.player_details" runtimes that can spontaneously cause + clients to get kicked out and forced back to the lobby. + - rscadd: You can now quickly use unequipped items on objects by simply click-dragging + the item onto the object with an empty active hand. Doing so will place the + item in your hand, and then use that item on the object. + - code_imp: In an attempt to improve the performance of /mob/Stat(), various time-related + procs now use defines instead of being procs that call procs that call other + procs that call even more procs. + - bugfix: If a living mob has vore initialized but doesnt have voreprefs initialized, + then client login will force voreprefs to load. + - bugfix: 'Hopefully fixed paper crash 2: electric boogaloo' + - refactor: Added unomos, which is basically listmos except gas mixtures only use + one single list for handling their gasses. This is a significant performance + improvement that also offers a mild memory improvement under normal circumstances. + - balance: Locomotion circuits are now restricted to jogging speed + - balance: MMI circuits and pAI circuits both now have 60 complexity, up from their + original 29. + - tweak: Biogenerators now have a sane limit for production + - bugfix: Fixed a fairly huge server crash exploit + - bugfix: Shield blobs no longer become completely invulnerable to all forms of + damage after reaching a """weakened""" state + - tweak: Taken care of what appeared to have been an oversight where shield blobs + don't recover their armor after becoming weakened. + - bugfix: Nerfed concatenators by limiting the amount of characters they're able + to output + - tweak: The timer for stripping an item off of a spaceman is no longer interrupted + by your active held item changing. This means you no longer have to worry about + filling both of your hands when you're stripping items off of someone. + - rscadd: Ported the zulie cloak and blackredgold coat donor items from RP. + - balance: Normal mops now only use 2 stamina to mop a tile, nerfed from their previous + value of 5 stamina per tile mopped. + - balance: Advanced mops now only use 1 stamina to mop turfs, from their former + value of 2 stam. + - tweak: The femur breaker now uses `*scream` instead of forced speech. This means + that the femur breaker will no longer spam deadchat with "AAAAAAAAAHHHHHHHHHH!!" + - tweak: The femur breaker will now guarantee that the victim falls into crit, which + will make it harder to perform torture scenes with it since the victim can just + succumb. + - bugfix: Fixed another runtime in warp whistles. + - bugfix: Spamming forged packets no longer crashes the server. + - bugfix: Things that access job_preferences now explicitly access keys, which means + it no longer attempts to access invalid indices and runtimes as a result. + - balance: The taser's electrode has been reworked. Instead of being a strong knockdown + that deals a heavy amount of stamloss, it now causes a weak knockdown, applies + a debilitating status effect for 5 seconds, and deals 35 stamloss on hit up + to a maximum 50 total stamloss. + - balance: Roundstart turrets now have a nonlethal projectile that gets used when + they're set to stun and the target is resting + - tweak: Hybrid tasers now have disablers set as their default mode. + - rscadd: There is now a 1% chance for the station's announcer to be the medibot + voice instead of the classic TG announcer. + - rscadd: The map config system has been expanded to allow mappers to specify the + map type, announcer voice, ingame year, and how often a given map can be voted + at roundend. + - bugfix: The map vote system now takes into account map playercount limits properly. + - bugfix: Examining a spaceman, and other things that use get_examine_string(), + will now actually properly show when an item is blood-stained. + - bugfix: Plasmaman tongues no longer have a maxHealth of "alien", and no longer + cause the organ's on_life to always runtime. + - bugfix: Shooting a simplemob no longer causes runtimes prior to the blood effect + being created. + - bugfix: Removing a filter from an object that lacks filters no longer causes runtimes. + deathride58 (Original PR by actioninja): + - rscadd: Disarm pushing (combat mode right click in disarm intent) will now actually + push mobs away. Knockdowns from disarm pushing are no longer rng based on the + target's staminaloss. Knockdowns from disarm pushing now only happen when you + push someone into another mob, a table, or a wall. Pushes will now also temporarily + stop targets from using firearms, and will disarm the firearm if performed a + second time. Pushes still deal staminaloss to standing targets, and won't deal + a single ounce of staminaloss to resting targets. + - rscdel: You can no longer displace mobs that are in harm intent by simply walking + into them. Mobs that aren't in help intent have to be disarm pushed to actually + be moved. + dtfe3: + - tweak: Increased music maxlines from 300 to 600 + - tweak: Made it so any oxygen tank can be used instead of only red ones. + - tweak: Watcher wing Trophy's effect lasts 1 second instead of 0.5 + - rscadd: Pink Panties + - rscadd: Twintails + - rscadd: Schoolgirl outfits for the loadout menu! + - tweak: Now the fox ears are located in front of hair meaning they now behave much + like cat ears, that being they are on-top of the hair layer. + izzyinbox: + - rscadd: adds VoG orgasm command using words "orgasm", "cum", "squirt", "climax" + - rscadd: adds VoG dab command using words "dab" and "mood" + - rscadd: Generic dog body marking sprite + - imageadd: colormatrix dog sprites + - tweak: lowered the player age for command jobs to 1/3 of their previous setting + - rscadd: '*bark emote' + jtgsz: + - rscadd: ported gang mode + kappa-sama: + - rscdel: Removed racism + - tweak: Teleporter calibration actually matters to all roundstart players + - balance: Slows down teleportation with the console/hub/teleporter setup if you + care for your species. + - balance: Dedicated non-humans can now get hulk without having to become human. + - bugfix: seed + - tweak: added obj/item/key to wallet whitelist + - tweak: blood cult ritual daggers fit in jack/combat boots + - tweak: voidcells can now unlock alien tech + - balance: rebalanced tech trees (not really) + - rscadd: hugbox (/s) + - tweak: ashwalker spawn text now tells them "i" "c" not to leave lavaland + - bugfix: you can no longer have infinite ebows + - bugfix: kevinz forgot to nerf miasma research and cargo value after making it + produce like 100x as much lmao + kevinz000: + - balance: Hierophant now goes sicko mode, but hey, at least you can't be multi-hit + by melee waves! + - rscadd: Racking shotguns is now more threatening. + - balance: Medibots no longer kill slimes when trying to heal their toxins. + - rscadd: The Syndicate started selling claymores to their agents. + - balance: Nerfed VTEC modules. + - bugfix: Neurotoxin no longer stuns non-carbons. + - rscadd: peacekeeper cyborgs now get a megaphone + - bugfix: Fixes storage bugs regarding reaching into things you shouldn't be able + to reach into. + - code_imp: BYOND 513 preliminary support added. + - balance: 'Trashbags now only allow accessing the first 3 items. 5 for bluespace + ones. experimental: Storage now allows for limiting of random access' + kiwedespars: + - rscadd: regenerative materia to hallucination sting + - rscadd: mindbreaker toxin as an actual chemical to hallucination sting + lolman360: + - rscadd: NT has authorized shipments or Cotton to Megaseed Servitors. It's time + to start picking, liggers. + - imageadd: missing durathread sprites + - rscadd: Added durathread jumpskirt + - imageadd: Duraskirt sprites and rolled down jumpsuit sprites. + - bugfix: Fixes an undocumented change to the naming of Plasmamen. + - tweak: chainsaw kind of weapons and the mecha drill and the CLAMP can now be used + with 100% accuracy for surgery + - refactor: surgery tools now work on defines + - balance: advanced surgerytools can now switch types instead of just being faster + - bugfix: fixes bug with new surgerytools examine + nicc: + - rscadd: Exo-suit + - rscadd: SEVA suit + - rscadd: Flags for Goliath resistance and weakness + - rscadd: suit voucher + - rscadd: temp suit sprites + - rscadd: '*dab' + - balance: teg less gay maybe + ninjanomnom and WhoneedSpacee: + - rscadd: Some rpg affixes now have special effects + - rscadd: 'New RPGLoot modifiers: Vampirism which heals you when you attack, Pyromantic + which sets things you hit on fire. Shrapnel which causes projectiles fired from + a gun to fire projectiles in a radius when they hit something. Finally, Summoning + which summons mobs that sometimes aid you in combat.' + original by @randolfthemeh and @twaticus, port by sishen1542: + - rscadd: jumpskirts + - rscadd: more jumpskirts + - rscadd: jumpskirt/suit prefs + original by Bumtickley00, port by sishen1542: + - tweak: Suit storage units will now also remove radiation from mobs. + original by GuyonBroadway, SkowronX, and Arizon5. port by sishen1542 and kerse: + - rscadd: Clockwork cultists may now summon forth Neovgre, the ratvrarian super + weapon. This powerful mech can be summoned when applications scripture has been + unlocked, boasts superior offensive and defensive capabilities, however once + a pilot enters he cannot leave and is doomed to die with the mech. + - imageadd: Sexy Sprite work courtesy or SkowronX from /tg/ + - imageadd: brass edits by Arizon5 + - soundadd: steamy laser by kerse + original by Skoglol, port by sishen1542: + - balance: Added lots of new virus cures, made cure difficulty scale more consistently. + Cures are now picked from a list of possible cures per resistance level, multiple + diseases at the same level no longer always share a cure. Looking at you table + salt. + - admin: Dynamic gamemode now more auto-deadmin friendly. + original by TheChosenEvilOne, port by sishen1542: + - rscadd: Ported dynamic mode from /vg/, originally made by @DeityLink, @Kurfursten + and @ShiftyRail + original by Tlaltecuhtli, port by sishen1542: + - rscadd: rcd disk that gives rcd computer frame and machine frame designs + - rscadd: upgraded rcd in CE lockers + - tweak: moved deconstruction to the upgrade disk, ashwalker rcd comes upgraded + original by actioninja, port by sishen1542: + - tweak: Medical and Security consoles now check access on worn or inhand ID instead + of requiring an inserted ID + - tweak: mining vendor now reads from ID in hand or on person instead of requiring + an inserted ID + - bugfix: ORM is functional again (for real this time) + - tweak: ORM claim points button transfers points to worn/inhand ID instead of to + an inserted ID, no longer accepts insertions + - tweak: Same for gulag consoles + original by redmoogle, port by sishen1542: + - rscadd: Added support for 3 new gasses; Tritium, Pluoxium, and BZ + 'original by: WJohnston, Antur, Arcane, plapatin, sprites by cogwerks and edited by mrdoombringer. port by sishen1542': + - rscadd: THE GOOSE IS LOOSE + r4d6: + - rscadd: Added decoratives angel wings for Mammalians only + - rscadd: Added blindfolds to the Loadout list + - rscadd: Added Decorative Wings for Humans, Felinids, Slimepersons and Lizardpeoples. + - tweak: Change the SEVA suit & Exo-suit's descriptions + - bugfix: Batteries are now Rad-Proof like the other stock parts + tigercat2000@Paradise: + - bugfix: fixed invalid characters breaking chat output for that message + tinfoil hat wearer: + - rscadd: Added a new alien technology disk to scientist and roboticist uplinks + that allows them to research the heavily-guarded secrets of the Grays. + - tweak: Alientech is now the only Hidden alien research. To compensate for this, + alien_bio and alien_engi have had their research costs doubled and now require + advanced surgery tools and experimental tools respectively to research. Their + export price is also halved. + - balance: roboticists now have brainwashing disks AND alien technology added to + their role-restricted uplink section. alien technology gives them brainwashing + at a much later date, so brainwashing is the much cheaper option for instant + power. makes logical sense because doctors get it as well because they do surgery, + and roboticists can now either choose to brainwash people for less price but + less power or emag borgs for higher prices, limited uses, but higher power. + ursamedium: + - imageadd: Gas icons changed. diff --git a/html/changelogs/archive/2019-12.yml b/html/changelogs/archive/2019-12.yml new file mode 100644 index 0000000000..37bfe399e4 --- /dev/null +++ b/html/changelogs/archive/2019-12.yml @@ -0,0 +1,861 @@ +2019-12-07: + AffectedArc07: + - code_imp: Fixes a LOT of code edge cases + Anonymous: + - rscadd: Added NEET-- I mean, DAB Suit and Helmet into loadout. Exclusive to Assistants, + for obvious reasons, and don't provide any armor. Goes well with balaclava, + finger-less gloves and jackboots for that true tactic~~f~~ool experience. + - tweak: Renamed loadout name appropriately (ASSU -> DAB) + Arturlang: + - tweak: PDA catridges cant be irradiated anymore. + Bhijn: + - code_imp: Item mousedrop() now provides a return value indicating whether or not + behavior has been overridden somehow. + - bugfix: Defibs now properly check that their loc is the same as the user for mousedrop() + calls, meaning ghosts can no longer make you equip defibs. Plus extra sanity + checks. + - bugfix: Pet carriers no longer attack turfs while trying to unload their contents. + - bugfix: Decks of cards now function as they originally intended when attempting + to use their drag and drop behavior. + - bugfix: Paper bins and papercutters no longer act wonky when you're trying to + pull a piece of paper from them. + - bugfix: Adds clothing drag n drop sanity checks. + - bugfix: Sythetic hats now have extra sanity checks + Coconutwarrior97: + - bugfix: Can only wrench down two transit tubes per turf. + Commandersand: + - rscadd: Added more stuff to loadout,check uniforms mask and backpack + DeltaFire15: + - rscadd: Adds eight new plushies + - imageadd: Adds icons for the new plushies and adds a new icon for the skylar plush + - imagedel: Deleted a old, no-longer used icon for the skylar plush + - spellcheck: Fixed a typo in the trilby plush + Fermis: + - tweak: tweaks botany reagent pHes + - tweak: Purity, Astral, RNG, MK, SMilk, SDGF, furranium, hatmium, eigen, nanite. + - bugfix: Eigen and purity. + - refactor: refactored sleepers! + - rscadd: Organ fridges to all maps near surgery with a random sensible organ, steralizine + and synthtissue. + - tweak: the med hand scanner to be less of a mishmash of random things + - rscadd: a little icon to the HUD if someone's heart has failed. + - tweak: Lets neurine's brain splash attack work via syringe. + - rscadd: a new surgery; Emergency Cardioversion Induction for use on the recently + deceased + - tweak: Synthtissue to be less demanding on growth size for organ regeneration + and improves clarify of it's growth gated effects. + - tweak: Synthtissue now is more useful than synthflesh on the dead + Fox McCloud: + - bugfix: Fixes a very longstanding LINDA bug where turfs adjacent to a hotspot + would be less prone to igniting + Fox McCloud, Ghommie: + - bugfix: Fixes being able to mech-punch other mobs, as a pacifist + - bugfix: Fixes being able to hurt people, as a pacifist, by throwing them into + a wall or other mob, or by using most martial arts (save for the unpredictable + psychotic brawl, and the stamina-damage-only boxing). + - balance: Buffs boxing to outdamage natural stamina regeneration. Made the chance + of outright missing your opponent actually possible. + - tweak: Pacifists can now engage in the (laughably not harmful) sweet sweet art + of boxing now. + Ghommie: + - bugfix: Fixing implant cases being lost inside implant pads when trying to eject + them with your active hand full. + - tweak: Moved the implant pad's case ejection from attack_hand() to AltClick(), + added examination infos about it. + - bugfix: Fixed holodeck sleepers leaving sleeper buffers behind when deleted. + - bugfix: Fixed traitor codewords highlight and some other hear signal hooks spans + highlight (phobias, split personality, hypnosis) or modifiers (mind echo) + - bugfix: Fixed traitor codewords highlight not passing down with the mind datum + and stickying to the first mob. + - spellcheck: Fixed the incongruent bone satchel description. + - bugfix: Fixed sofa overlays doing nothing, because their layer wasn't properly + set. + - tweak: Suicide and cryo now prevents ghost/midround roles for a definite duration + of 30 minutes (and more if that was done before 30 minutes in the game passed), + down from the rest of the round. + - bugfix: fixed several midround roles bypassing and nulling the aforementioned + prevention measures. + - bugfix: Fixed the little issue of PDA skins not updating on job equip. + - tweak: Anomaly Crystals of the clowning type will now rename the victim to their + clown name preference when triggered, instead of giving them a random clown + name. + - balance: Lowered blob event earliest start from 1 hour to 40 minutes (ergo one + third), and the required player population from 40 to 35. + - bugfix: Several fixes and QoL for dullahans. They can see and hear visible and + audible messages now, don't need a space helmet they can't wear anyway to be + space/temperature proof, can examine things through shiftclick, and, most of + all, fixed their head being unpickable. Fixed dullahans gibbing when revived + or had their limbs regenerated. + - bugfix: humans should now drop gibs when gibbed again. + - rscadd: synths (not to be confused with IPCs), android and corporate species, + as well as robotic simple mobs, will now spawn robotic giblets instead of organic + ones. + - bugfix: You can't wear dakimakuras in any other inappropriate slots save for the + back slot anymore, degenerates. + - bugfix: Insert snarky remark about clock welders actually displaying the welder + flame overlay when turned on now here. + - balance: Minor ninja tweaks and stealth nerfs. The stealth penalty for the many + combat-related actions, bumping and now teleporting/dashing or firing guns has + been increased a by a third. There is now a cooldown of 5 seconds on toggling + stealth as well as a slighty slowed stealth in/out animation. + - imageadd: Ported slighty better matchbox sprites from CEV-Eris, also resprited + cigar boxes myself. + - bugfix: Fixed abductors/abductees objectives by porting an objective code. + - bugfix: Riding component fix + - bugfix: fixing a few runtimes on lightgeists, libido trait, rcd, one admin transformation + topic, chem dispensers, glowing robotic eyes... + - imageadd: Porting CEV-eris delivery packages sprites and dunking the old syndie + cybernetics box sprite. + - bugfix: Certain objects shouldn't be able to become radioactive because of a bitflag + that previously was checked nowhere in the code anymore. + - rscadd: Added a new PDA reskin, sprites from CEV-Eris + - rscadd: Clock cult starts with some spare vitality matrix charge scaled of the + number of starter servants. + - balance: Made the vitality matrix sigil slighty more visible, also allowed conversion + runes to heal fresh converts at the cost of some vitality charge. + - bugfix: 'Crawling won''t save you from the wrath of ocular wardens and pressure + sensors anymore, heretics. fix: Pressure sensors are no more triggered by floating/flying + mobs.' + - bugfix: Strawberry milk and tea have sprites now. + - bugfix: Fixed the Aux base camera door settings and toggle window type actions. + Also enabling the user to modify both door access and type. + - imageadd: Improved the two grayscale towel item sprites a little. + - bugfix: Fixed towels onmob suit overlays. Again. + - spellcheck: Fixed some reagents taste descriptions. + - bugfix: Fixed hidden random event reports only priting a paper message without + sending the message to the consoles' message list. + - bugfix: Rosary beads prayer now works on non-carbon mobs too, and won't break + when performed on a monkey or other humanoids. + - tweak: You can flagellate people with rosary beads on harm intent. It's even mediocrer + than the sord though. + - tweak: Moved the `Stealth and Camouflage Items` uplink category next to `Devices + and Tools`. + - bugfix: Deleted a duplicate phatom thief mask entry from the uplink. + - bugfix: Fixed missing delivery packages sprites + - bugfix: fixed a few minor issues with console frames building. + - bugfix: Wizards can use the teleport spell from their den once again. + - tweak: Wizards will now receive feedback messages when attempting to cast teleport + or use the warp whistle while in a no-teleport area. + - rscadd: New clockwork cultist, gondola, monkey and securitron cardboard cutouts. + - bugfix: Fixed aliens gasping randomly once in a while. + - bugfix: fixed superlube waterflower, my bad. + - bugfix: Fixed closing the aux base construction RCD's door access settings window + throwing you out of camera mode when closed. + - rscdel: Removed not functional aux base RCD's door type menu. Use airlock painters, + maybe. + - rscadd: Honkbot oil spills are of the slippery kind now. Honk. + - imageadd: local code scavenger finds forgotten slighty improved apc sprites left + buried in old dusty folders. + - bugfix: Seven old and otherwordly pAI holochassis icons have crawled their way + out of the modular citadel catacombs. + - bugfix: chem dispenser beakers end up in your hand yet again. + - bugfix: Bikehorns squeak yet again, the world is safe. + - bugfix: Cyborgs can now actually use cameras from a distance. + - bugfix: Suicides are yet again painful and instant and won't throw people in deep + crit from full health. + - bugfix: fixed rogue pixels on the energy gu- ahem blaster carbine... and a few + apc lights states being neigh-indistinguishable. + - bugfix: Fixed several "behind" layer tail sprites skipping areas normally covered + by bodyparts. + - bugfix: Morgues' original alert beeping sound has been restored, they no longer + go "ammunition depleted" + - bugfix: Fixed missing hypereutactic left inhand sprites. + - bugfix: Dying, ghosting, having your mind / ckey transferred to another mob, going + softcrit or otherwise unconscious now properly turn off combat mode. + - bugfix: combat mode can't be toggled on while non fully conscious anymore. + - bugfix: Fixed limbs' set_disabled NOT dropping your held items, updating your + hand slot inventory screen image, prompting chat messages and making your character + scream like a sissy. + - bugfix: Lusty xenomoprh maids will now actually clean tiles they travel onto yet + again. + - bugfix: Fixed double whitespace gap in human and AI examine. Fixed single whitespace + in carbon examine. + - rscdel: 'Removed a few useless supply packs: "Siezed" power cells, means of production + and promiscous organs.' + - tweak: Merged the synthetic blood supply pack into the standard blood supply pack, + effectively removing a random type blood pack in favor of two synthetic ones. + - tweak: "Merged together premium carpet pack n\xB01 and n\xB02 to hold one of each\ + \ standard pattern." + - tweak: You can no longer estimate the amount of reagents found inside a damp rag. + - tweak: You can now squeeze a rag's reagents into another open container, as long + as the other one is not full. + - bugfix: Fixed ED-209 being unbuildable past the welding step. + - bugfix: Fixed ai displays status being reset to "Neutral" on login, regardless + of choice. + - bugfix: Fixed tinfoil hats giving random traumas. + Ghommie (original PR by Denton): + - rscadd: Added three new .38 ammo types. TRAC bullets, which embed a tracking implant + inside the target's body. The implant only lasts for five minutes and doesn't + work as a teleport beacon. Hot Shot bullets set targets on fire; Iceblox bullets + drastically lower the target's body temperature. They are available after researching + the Subdermal Implants node (TRAC) or Exotic Ammunition node (Hot Shot/Iceblox). + - tweak: Renamed the Technological Shells research node to Exotic Ammunition. + - code_imp: The "lifespan_postmortem" var now determines how long tracking implants + work after death. + - rscadd: .357 AP speedloaders can now be ordered from syndicate uplinks. + - balance: lowered the cost of uplink's .357 speedloaderd from 4 to 3. + Ghommie (original PR by nicbn and Menshin): + - bugfix: You can click on things that are under flaps or holo barriers. + Ghommie (original PRs by ShizCalev, CRTXBacon and Niknakflak): + - rscadd: Adds the intelliLantern, a big ol' spooky intelliCard skin + - rscadd: crafting recipe for the new intelliCard skin (requires 1 pumpkin, 1 intelliCard, + 5 cables and a wirecutter as a tool) + - tweak: changed the intelliTater crafting recipe to match the intelliLantern recipe + (but with a potato for obvious reasons) add:cute pai gameboy face :3 + Ghommie, porting lot of PRs by MrDoomBringer, AnturK, nemvar and coiax.: + - admin: Admins can now launch supplypods the old, slightly quicker way as well + - bugfix: Centcom-launched supplypods will now properly delimb you (if they are + designated to do so) instead of touching you then literally yeeting all of your + internal organs out of your body. + - admin: Centcom can now specify if they want to yeet all of your organs out of + your body with a supplypod + - soundadd: Supplypods sound a bit nicer as the land now. + - admin: admins can now adjust the animation duration for centcom-launched supplypods + - admin: admins can adjust any sounds that are played as the supplypod lands + - bugfix: Reverse-Supplypods (the admin-launched ones) no longer stay behind after + rising up, and also auto-delete from centcom. + - admin: The centcom podlauncher now has better logging + - tweak: Admins can now allow ghosts to follow the delivery of Centcom-launched + supply pods + - admin: Admins can now use the Centcom Podlauncher to launch things without the + things looking like they're being sent inside a pod. + - admin: sparks will not generate if the quietLanding effect is on, for the centcom + podlauncher + - admin: makes input text clearer for the centcom podlauncher + - admin: New 'Podspawn' verb, which functions like 'Spawn', except any atoms movable + spawned will be dropped in via a no-damage, no-explosion Centcom supply pod. + - bugfix: Removed an oversight that made many obj/effect subtypes accidentally bombproof. + GrayRachnid: + - rscadd: Added saboteur syndicate engiborg + - tweak: changed cyborg tool icons and the secborg taser/laser icons. + - bugfix: Fixes golden toolbox missing inhand sprite + - rscadd: Added traumas + - rscadd: Added science powergame tool + - tweak: a few hearing args + - bugfix: fixed my mistakes + - tweak: tweaked the number of ingredients/pancakes you can stack. + Hatterhat: + - tweak: The Big Red Button now sets bomb timers to 2 seconds, instead of 5. + - tweak: Gloves of the North Star (not Hugs of the North Star) now use all their + intents very, very fast. This does not apply to grabs' click cooldown, nor shoving + people. + - rscadd: The seedvault/alien plant DNA manipulator can now be printed off with + Alien Biotechnology. + Iroquois-Pliskin: + - rscdel: Removed Clockwork Cult Surgical facility from Reebe + Jerry Derpington, baldest of the balds, and nemvar.: + - rscdel: Nanotrasen has lost communication to two away mission sites that contained + a beach for Nanotrasen employees. + - rscadd: Nanotrasen has been able to locate a new away mission site that ALSO has + a beach. Nanotrasen employees will be able to enjoy the beach after all! + - rscadd: Seashells have been added to the game. + KathrinBailey: + - rscadd: Two extra 'luxury' dorms rooms! + - rscadd: Gas miners to atmos. + - rscadd: Posters around the station. + - rscadd: Vacant room added to the Starboard Bow with it's own APC, above electrical + maintenance. + - rscadd: New trendy clothes to the locker room, giving variety and bringing fashion + back onto Nanotrasen stations. + - rscadd: Coloured bedsheet and towel bin. + - rscadd: Maid uniforms for the janitor. + - tweak: Completely reworked bar. Milk kegs added in bar office. The bar has been + changed for a homey restaurant feel just in time for Christmas! You can now + run it as an actual restaurant! Local Bartender Icktsie III loved it so much + he rolled around on the new floor smiling happily. + - tweak: Dorms rework. Fitness room now has lots of costumes and outfits. + - tweak: Junk removed from engineering, welding goggles added. + - tweak: Welding tools in engineering replaced with industrial welding tools. + - tweak: Package wrappers and hand labellers now in major departments. + - tweak: Cell charger moved from engineering lobby to the protolathe room, just + like how it is in all of the other maps and just where the cell charger is actually + needed. + - tweak: Library redesigned to have a private room and a 3x3 private study that + is cleaned up. + - tweak: Paper bins have gone big or gone home, with premium stationery scattered + around. Engineering and security now have a labeller and packaging supplies. + - bugfix: Dark spot top left of Botany fixed. + - bugfix: Huge galactic-sized dark spot in bar fixed. + - bugfix: Light replacers now are less horrifically overpowered and PTSD-inducing + for the server. + - bugfix: 'Fixes issue 9706: https://github.com/Citadel-Station-13/Citadel-Station-13/issues/9706 + Part of maint getting hit by radstorms. + + _Kathrin''s Box Beautification:_' + - rscadd: Ports TG's pews https://github.com/tgstation/tgstation/pull/42712 + - rscadd: The first step of a corporate incursion of Space IKEA into Nanotrasen. + Kevinz000, Cruix, MrStonedOne, Denton, Kmc2000, Anturk, MrDoomBringer, Dennok, TheChosenEvilOne, Ghommie: + - rscadd: Added support for Multi-Z power, atmospherics and disposals + - bugfix: 'massive service department nerf: space can no longer be extra crispy.' + Knouli: + - rscadd: attack_self proc for the legion core which triggers a self-heal al la + the previous 'afterattack' proc, as if clicking on the character's own sprite + to self-heal + - rscadd: admin logging for all three use cases of legion core healing - afterattack, + attack_self, and implanted ui_action_click + Krysonism, Ghommie: + - rscadd: NT has made breakthroughs in ice cream science, ice creams can now be + flavoured with any reagent! + - tweak: The ice cream vat now accepts beakers. + - bugfix: Grape and Peach icecreams have scoop overlays yet again. + Linzolle: + - code_imp: butchering component update + - tweak: hat tossing can no longer knock hats off + - bugfix: strange reagent being unable to revive simplemobs + - rscadd: jitter animation and more clear text to strange reagent revival + Mickyy5: + - rscadd: Nanotrasen are now issuing Plasmamen with plasma in their survival boxes + MrJWhit: + - tweak: tweaked brain damage line + Naksu, ShizCalev: + - refactor: Refactored examine-code + - bugfix: Examining a human with a burned prosthetic limb will no longer tell you + that the limb is blistered. + - tweak: Items will now inform you if they are resistant to frost, fire, acid, and + lava when examined. + Owai-Seek: + - rscadd: '"silly" bounties' + - rscadd: '"gardenchef" bounties' + - rscdel: several bounties that require seriously good RNG to pull off. + - tweak: moved several chef and assistant bounties to silly and gardenchef + - balance: modified several bounty point rewards + - server: added new files "silly.dm" and "gardenchef.dm" + - rscadd: 15+ new crates for cargo + - tweak: organizes crates and moving them to proper categories + - rscdel: some dumb stuff like toner crates re + - rscadd: leg wraps and sweaters to clothesmate + - rscadd: screwdriver and cable coil to janidrobe + - rscadd: screwdriver and cable coil to janibelt whitelist (for fixing/placing light + fixtures) + - rscadd: monkey cube, syringe, enzyme, soy sauce, and cryoxadone to chef's vendor + (contraband and premium) + - rscadd: add cracker, beans, honey bars, lollipops, chocolate coin, and spider + lollipop to snack vendors (contraband and premium) + - rscadd: newspaper to loadout menu for bapping purposes + - rscdel: removed poppy pretzels from snack vendor premium + - rscadd: maid uniform (janimaid alt) to kinkmate. + - tweak: moves gear harness from premium to normal stock in kinkmate + - balance: re-balanced metal shield bounty + - rscadd: cryoxadone bottle (for use in chef vendor) + PersianXerxes: + - tweak: Reduces the grace period for meteors from a minimum of 5 and maximum of + 10 to 3 and 6 minutes respectively. + - rscadd: Adds a pair of VR sleepers to Box Station's permabrig + - rscadd: Adds a pair of VR sleepers to Delta Station's permabrig + - rscadd: Adds a pair of VR sleepers to Pubby Station's permabrig + - rscadd: Adds a pair of VR sleepers to Meta Station's permabrig + Putnam: + - bugfix: From-ghosts dynamic rulesets now actually listen to "required candidates" + - bugfix: Every dynamic-triggered event is now blacklisted from being triggered + by the random events system when dynamic can trigger them. + - rscadd: Dynamic voting now features extended, if recent rounds have been chaotic. + - tweak: Roundstart rulesets now scale on population ready rather than total population. + - bugfix: Threat log now accurately represents what actually used the threat. + - tweak: Verbose threat log (admin-only) now shows ALL threat level changes. + - bugfix: VR mobs can no longer be dynamic midround antags. + - bugfix: Personal closets can use anything that holds an ID card now. + Putnam3145: + - bugfix: traitors work now + - balance: Gas filters now push gas the same way volume pumps do. + - balance: Gas filters now won't clog if only one output is clogged. + - tweak: Glowsticks can no longer be radioactively contaminated (one more supermatter + contam exploit gone) + - bugfix: traitor removal is no longer borked + - rscadd: Dynamic voting + - config: Added DYNAMIC_VOTING to game_options + - tweak: SDGF now copies memories as well as antag data and factions. + - bugfix: Summon events now properly costs threat. + - bugfix: Refunded spells refund threat, too. + - refactor: Made wizard spells inherently have a requirement and cost. + - tweak: Meteor wave is no longer repeatable in dynamic. + - tweak: tweaked nuke ops + - bugfix: Organs can no longer be radioactively contaminated. + Robustin, Subject217: + - balance: The NukeOp Shuttle hull has been dramatically hardened. The walls are + now "R-Walls" with far greater explosion resistance. + - balance: The NukeOp Shuttle guns have been significantly buffed. They now rapidly + fire a new type of penetrator round, at a greater range, and have far greater + explosion resistance. + - balance: The nuclear device on the NukeOp Shuttle is now in an anchored state + by default, the Nuke can only be unanchored by inserting the disk and entering + the proper code. + - balance: Non-Syndicate cyborgs are now unable to access the NukeOp Shuttle Console. + - bugfix: You can now unanchor Nukes even when the floor under them has been destroyed + Seris02: + - rscadd: added sleeping carp hallucination + - rscadd: Centcom + Assistant's formal winter coat + loadout + narsian + ratvarian + winter coats + - rscadd: GPS location on examine + - bugfix: fixed the meteor hallucination + - tweak: tweaked the way the tapered penis looks + - rscadd: Added nine winter coats + - imageadd: added images for the winter coats + - tweak: adds the mining winter coat to mining wardrobes and mining lockers + ShizCalev: + - tweak: Ghosts can now see active AI cameras. + - bugfix: Fixed a couple of laser / energy guns never switching to the empty icon + despite being unable to fire. + Swindly: + - bugfix: Fixed MMIs not being able to use mecha equipment + - bugfix: Fixed MMIs not getting mecha mouse pointers + - bugfix: Fixed MMIs not getting medical HUDs in Odysseuses + - tweak: Brains can now switch to harm intent + Tetr4: + - bugfix: Turning a tile with gas effects into space now gets rid of the effects. + Trilbyspaceclone: + - rscadd: plastic trash cart crafting with plastic + - rscadd: wallets are known for now holding more items + - tweak: shades and clowns HP + - rscadd: six more crates, A barrel, A Loom, 40 cotton sheets, two sets of fruit + crates, raw lumber crate + - rscadd: All fermi chems, Boozes, Medical, food chems now sell + - rscadd: Loads more to sell - Mech gear, Cooking and more! + - tweak: Moved around the vaule of some things and removed elastic of most items + - balance: Rebreather implants will now loss vaule, Do to being just metal and glass + - balance: lowered how many chems are in lewd chem kegs to be around 150-100 as + well as the fancy booze kegs + - bugfix: bad returns and tools used + - rscadd: 8 new cargo crates! + - tweak: tablet cargo crate by -3k + - admin: Closes a bunch of issues + - server: updates changlogs and such + - bugfix: fixed a catnip not having sprites + - balance: Boh cant hold WEIGHT_CLASS_GIGANTIC, just Bulky. Makes katana, chainsaw + and base ball bat into bulky items so they may fit + - server: changes header to be more cit-like + - rscadd: new clothing for the hotel staff and a hat + Ty-the-Smonk: + - bugfix: You can now interact with self sustaining crossbreeds + Useroth: + - rscadd: Colored fairygrass variants. + - bugfix: Added a missing cherrybulb seedpack sprite + - bugfix: numbered storages now are sorted in a consistent way, instead of depending + on ordering of their contents var + - rscadd: strange seeds as a buyable traitor botanist item + - bugfix: resolves the issues revolving around blackpowder exploding where the reaction + happened, instead of where it actually is through making it explode instantly + - tweak: the explosion delay moved from blackpowder directly into bomb cherries, + to keep them functioning as intended + - rscadd: A bunch of newer tg plants + - rscadd: A bunch of newer tg plant traits + - rscadd: A couple of newer tg plant reagents + - bugfix: the new plants now properly get their reagents and reagent genes instead + of being empty with UNKNOWN reagents listed in the DNA machine + - rscadd: extradimensional oranges now contain haloperidol + - bugfix: extradimensional oranges now actually grow properly and give proper seeds. + Weblure: + - rscadd: Button added to slime console that prints out the hotkey commands to the + user. [Includes DMI update] + - rscadd: Shift-click a slime to pick it up, or the floor to drop all held slimes. + (Requires Basic Slime Console upgrade) + - rscadd: Ctrl-click a slime to scan it. + - rscadd: Alt-click a slime to feed it a potion. (Requires Advanced Slime Console + upgrade) + - rscadd: Ctrl-click on a dead monkey to recycle it, or the floor to place a new + monkey. (Requires Monkey Console upgrade) + - rscadd: If the console does not have the required upgrade, an error message will + print to the user. + - rscadd: You can now pick up a single slime from a pile, instead of all of them + at once. + - tweak: When recycling monkeys, the console will now report how many monkeys it + has (will not report decimal increases). + - tweak: Console now alerts you when you're out of monkeys and reports your current + decimal amount. + - tweak: Console messages are now styled consistently. + XDTM, ShizCalev, Naksu, Skoglol, cacogen, Rohesie (ported by Ghommie): + - tweak: Holding an ID in your hands uses it instead of your worn ID for authentication + purposes. + - tweak: If you don't have an ID in your id slot, the belt slot will be checked + as well. + - code_imp: small cleanup to id and bounty console html generation + - tweak: Hop console now hurts your eyes less. Red button text replaced with green. + - tweak: IDs with ID console access now go into the Confirm Identity slot by default + like they used to, similarly IDs without it go into the Target slot by default + again + - rscadd: Can easily swap out IDs by clicking the machine or the UI fields with + another ID + - rscadd: ID console now names which IDs are added/removed in its visible messages + - rscadd: Labels the ID slot fields when logged in so you know which is which + - tweak: Can use Job Management without an ID provided the console is logged in + (matches how the console now stays logged in even without an ID) + - tweak: Can log in without an ID in the Target field (matches how the machine now + stays logged in even after the ID is removed from the Target field) + - tweak: Cleans up UI slightly (had some duplicate/conflicting buttons) + - bugfix: Fixes ID console duping issues. Includes some ID containers, such as PDAs, + tablets and wallets, into the swapping behavior when an ID card is being removed + and the item is being held. + Xantholne: + - rscadd: New Berets for most heads and departments available in their autodrobes + or lockers + YakumoChen: + - imageadd: New AI Holograms and Displays! Ported from /vg/station. + actioninja: + - bugfix: med records no longer can eat id cards for no reason + - bugfix: Chat is properly sent to legacy window if goonchat fails to load again. + dapnee: + - bugfix: fixed closet initialisation being broken + - rscdel: emergency closets no longer have a 1% chance to delete themselves + - bugfix: Communications console window no longer updates, won't steal focus anymore. + - bugfix: Trimline neutral end exists now. + dzahlus: + - soundadd: added a new gun sounds + - sounddel: removed an old gun sounds + him: + - bugfix: hos and aeg guns now conform to le epic taser rework standards + kappa-sama: + - tweak: changed flavor text of alien tech on uplink + - imageadd: added TG's icons for traitor, russian, and golden revolver + kevinz000: + - rscadd: you can now choose never for this round for magical antags + - rscadd: Cargo has passive point generation again at 750 points/minute + - balance: Mindshield crate price increased from 3000 to 4000 + - balance: Miasma sell price reduced from 15/mol to 4/mol + - balance: bluespace wizard apprentice now has blink instead of targeted area teleportation + - balance: Emagged medibots now charcoal toxinlovers. + - balance: disablers buffed 0.7 --> 0.6 speed 24 --> 28 damage + - balance: kinetic crushers no longer drop if you try to use it with one hand + - config: added multi_keyed_list, delimiter defaults to |. + - balance: Light pink extracts no longer speed you up. Instead, they give stamina + regeneration and free sprinting. + kiwedespars: + - rscdel: removed moth fluff coloring you like your wings + - balance: made insect not so bad. + nemvar: + - bugfix: You now get a message if your PDA explodes while you are holding it. + - tweak: The lavaland clown ruin has some new pranks ready. + - rscadd: Added a new loot item to the lavaland clown ruin. + - rscdel: Removed the slime core from said ruin. + - balance: The clown PDA now properly slips people on jogging move intent regardless + of fatigue. Honkmother's will. + nemvar, ShizCalev, Qustinnus/Floyd, Ghommie: + - rscadd: You can now unfasten the loom. + - tweak: it now takes 4 strands to make one piece of durathread cloth + - bugfix: Looms can now be attacked. + - rscadd: Durathread golem weaves his magic + - tweak: Supply ordered looms are unanchored. Bring a wrench. + r4d6: + - rscadd: Added Departements Winter Coats to the loadout list. +2019-12-30: + AnturK: + - bugfix: Fixed ranged syndicate mobs stormtrooper training. + Arturlang: + - rscadd: Adds Bloodsuckers, beware. + BlueWildrose: + - bugfix: Fixed stargazers being unable to link to themselves if mindshielded or + if holding psionic shielding devices (tinfoil hats) when the species is set. + - bugfix: Fixes non-roundstart slimes being unable to wag their tail. + Commandersand: + - tweak: added two words to clown filter + - rscadd: Added new things to loadouts, check em + DeltaFire15: + - balance: Clock cult kindle no longer cares about oxygen damage + - tweak: changed mecha internals access for some special mechs. + - tweak: no more mech maintenance access for engineers. + - tweak: All heads of staff can now message CC + - code_imp: Removes a magicnumber + - balance: Rebalanced cult vs cult stun effects to debuff instead of stun + Detective-Google: + - bugfix: short hair 80's is no longer jank + Fermis: + - tweak: tweaked how super bases/acids work but limiting them + Fikou: + - tweak: the windup toolbox now has some more "realistic" sounds + - bugfix: the windup toolbox now rumbles again + Ghommie: + - bugfix: Fixed hulks, sleeping carp users, pacifists and people with chunky fingers + being able to unrestrictly use gun and pneumatic cannon circuit assemblies. + - bugfix: Fixed gun circuit assemblies being only usable by human mobs. + - balance: Doubled the locomotion circuit external cooldown, thus halving the movable + assemblies' movespeed. + - tweak: Made wooden cabinet/closets... actually made of wood. + - tweak: Wooden cabinets are now deconstructable with a screwdriver. + - tweak: Deconstruction of large crates and other closet subtypes deconstructable + with tools other than the welder is no longer instant. + - tweak: You shouldn't be able to target objects you can't see (excluding darkness) + with the ARCD and RLD + - tweak: The admin RCD is ranged too, just like the ARCD. + - bugfix: Fixed welding, thirteen loko, welding and wraith spectacles not blinding + people as expected. Thank you all whomst reported this issue in the suggestions + box channel instead of the github repository's issues section, very smart! + - bugfix: Fixed on_mob eyes overlays not updating properly in certain cases. + - bugfix: Fixed deconversion from bloodshot eyes blood cult resetting your eyes' + color to pitch black instead of their previous color, more or less. + - balance: 'Spinfusor nerf: Upped the casing and ammo box size by one step, removed + the projectile''s dismemberment value (explosions can still rip a limb or two + off), halved the ammo box capacity, reduced the spinfusor ammo supply pack contents + from 32 to 8, removed the casing''s ability to explode when thrown.' + - bugfix: Fixes bubblegum's death not unlocking the arena shuttle buyment. + - bugfix: Fixed alien tech node not being unlockable with subtypes of the accepted + items. + - bugfix: Fixed reactive armor onmob overlays not updating when toggled and reactive + teleport armor still using forceMove() instead of do_teleport() + - bugfix: Fixed space hermit asteroid rocks unintendedly spawning airless asteroid + turf when mined, save for the perimeter. + - bugfix: Fixes reviver implant having been a crapshot ever since soft-crit was + introduced years ago. + - tweak: Added a "convalescence" time (about 15 seconds) after the user is out of + unconsciousbess/crit to ensure they are properly stabilized. + - tweak: Added a 15 minutes hardcap for accumulated revive cooldown (equivalent + to 150 points of brute or burn healed) above which the implant starts cooling + down regardless of user's conditions. + - bugfix: Fixed AI core displays I may have broken with my coding extravaganza. + - soundadd: Blue, Amber and Red security alert sounds should be half as loud now. + - balance: Buffed clown ops by removing their clumsiness and adding a new trait + to be used in place of several clown role checks. + - tweak: Clown ops too also suffer from not holding or wearing clown shoes now. + - bugfix: Fixed a few holo barriers lacking transparency. + - bugfix: Fixed character setup preview bodyparts not displaying correctly most + of times. + - bugfix: Fixed character appearance preview displaying the mannequin in job attire + instead of undergarments. + - bugfix: Fixed raven's shuttle computer not being of the emergency shuttle type. + - tweak: Blood bank generators can now be anchored and unanchored now. + - admin: Ghost mentors can now orbit around the target instead of setting their + view to theirs'. + - bugfix: Fixes a ghostchat eavesdropping exploit concerning VR. + - bugfix: Fixes VR deaths being broadcasted in deadchat. + - bugfix: Fixed a few pill bottle issues with the ChemMaster. + - bugfix: Fixes a few negative quirks not being properly removed when deleted. + - tweak: Phobia and mute quirks are no longer cheesed by brain surgery grade healing + or medicines. + - bugfix: Fixed double-flavour (and bland custom) ice creams. + - bugfix: Fixed Pubbystation's wall Nanomeds being inconsistent with other stations'. + - bugfix: dextrous simplemobs can now swap action intent with 1, 2, 3, 4 now. Just + like humies, ayys and monkys. + - bugfix: Stops humanoids whose skin_tone variable is set to "albino" from showing + up as pale when examined should their species not use skintones anyway. + - rscdel: Removed the old (almost) unused roboticist encryption key and headset. + - bugfix: Fixed goose meat. + - bugfix: Fixed a little door assembly glass dupe exploit + - bugfix: Fixed AI holopad speech text being small and whispers that in multiple + exclamation marks echo through multiple areas. + - rscdel: Removed literally atrocious polka dotted accessories. They were even more + atrocious than the yellow horrible tie. + Ghommie (also porting PRs by AnturK and Arkatos): + - bugfix: Fixed light eaters not burning out borg lamplights and flashes. fix Fixed + light eater not affecting open turfs emitting lights such as light tiles and + fairy grass. + - bugfix: Fixed an empty reference about light eater armblade disintegration after + Heart of Darkness removal. + Ghommie, Skogol: + - refactor: refactored altclick interaction to allow alt-click interactable objects + to parent call without forcing the turf contents stat menu open. + - tweak: Alt clicking will no longer show turf contents for items inside bags etc. + - tweak: Alt clicking the source of your turf contents stat menu will now close + said menu. + GrayRachnid: + - bugfix: fixes consistency + Hatterhat: + - rscadd: Regenerative nanites, a "chemical" used in the combat stimulant injector. + Actually quite stimulating, and not bad in a pinch for a nuclear operative. + Check the Combat Medic Kit! + - tweak: The Combat Medic Kit now has an advanced health analyzer and medisprays + instead of patches and a chloral syringe. + - balance: The Advanced Syndicate Surgery Duffelbag or whatever it was doesn't get + the better injector, because nobody uses it and so nobody's bothered to update + it. + - rscadd: .357 speedloaders can now be printed with the Advanced Illegal Ballistics + node on the tech tree! + - balance: okay so i may have given the .357 an extra speedloader at the same cost + but it comes in a box now + ItzGabby: + - bugfix: Fixed AltClick on polychromic collars so they actually work now. + KeRSedChaplain: + - soundadd: Extends the file "deltakalaxon.ogg" to a 38 second .ogg. + Linzolle: + - rscadd: neck slice. harm intent someone's head while they are unconscious or in + a neck grab to make them bleed uncontrollably. + - bugfix: officer's sabre now properly makes the unsheating and resheating noise + - bugfix: fireman failure has a different message depending on the circumstance + - rscadd: Abductor chem dispenser, and added it to the abductor console. + - rscadd: '"Superlingual matrix" to the abductor console. It''s the abductor''s + tongue. Can be used to link it to your abductor communication channel and then + implanted into a test subject.' + - rscadd: Shrink ray and added it to the abductor console. + - soundadd: Shrink ray sound effect (its the fucking mega man death sound) + - rscadd: special jumpsuit for abductors + - imageadd: abductor jumpsuit, including digi version if a digitigrade person somehow + manages to get their hands on it. sprites for the shrink ray and chem dispenser. + - rscadd: new glands to play with, including the all-access gland, the quantum gland, + and the blood type randomiser. + - code_imp: split every gland into its own file instead of all being in one file + - tweak: cosmic coat crafting recipe changed to coat + cosmic bedsheet + Mickyan, nemvar, RaveRadbury, AnturK, SpaceManiac: + - bugfix: Certain incompatible quirks can no longer be taken together. + - bugfix: If an admin sends a ghost back to the lobby, they can now choose a different + set of quirks. + - spellcheck: the quirk menu went through some minor formatting changes. + - bugfix: Podcloning now lets you keep your quirks. + - rscadd: Quirks have flavor text in medical records. + - spellcheck: All quirk medical records refer to "Patient", removing a few instances + of "Subject". + - tweak: Quirks no longer apply to off-station roundstart antagonists. + - code_imp: Mood quirks are now only processed by the quirk holders + Narcissisko (ported by Hatterhat): + - rscadd: Luxury Bar Capsule, at 10,000 points. Comes with no medical supplies, + a bar, and a bunch of cigars. Ported from tgstation/tgstation#45547. + Nervere and subject217, Militaires, py01, nemvar: + - balance: The cook's CQC now only works when in the kitchen or the kitchen backroom. + - spellcheck: corrected CQC help instructions + - bugfix: CQC and Sleeping Carp are properly logged. + - tweak: CQC can passively grab targets when not on grab intent. Passive grabs do + not count towards combos for CQC or Sleeping carp. + - code_imp: Martial Art and NOGUN cleanup. + PersianXerxes: + - rscdel: Removed night vision quirk + Putnam: + - bugfix: acute hepatic pharmacokinesis now works if you already have relevant genitals + - balance: Contamination is no longer an infinitely spreading deadly contagion causing + mass panic + - tweak: Dynamic rulesets have lower weight if a round recently featured them (except + traitor). + Putnam3145: + - balance: Buffed HE pipes by making them realistically radiate away heat. + - bugfix: Dynamic has a (totally unused for any relevant purpose) roundstart report + now. + - admin: A whole bunch of dynamic data is now available for statbus + - bugfix: Dynamic from-ghost antags no longer double dip on threat refunds when + the mode fails due to not enough applications. + - bugfix: whoops broke quirks + - bugfix: quirks work + - rscadd: 'New tab in preferences screen: "ERP preferences"' + - rscadd: New opt-outs for individual effects of incubus draught, succubus milk + - rscdel: Acute hepatic pharmacokinesis has been removed, replaced with above + - tweak: Renamed "Toggle Lewdchem" to "Toggle Lewd MKUltra", since that's what it + actually means, and made it toggle the "hypno" setting (rename it again if more + hypno mechanics are added). + - tweak: Made MKUltra's lewd messages require both people involved to have hypno + opted-in. + - config: Buncha dynamic config tweaks + - bugfix: Ghost cafe spawns are actual ghost roles by the game's reckoning now + - bugfix: a runtime in radioactive contamination + - balance: Bomb armor now acts like other armor types. + - balance: Devastation-level explosions on armorless people no longer destroys everything + in their bags. + Seris02: + - rscadd: the clowns headset + - bugfix: distance checks + - bugfix: the sprites + - rscadd: added the runed and brass winter coats (cosmetic ratvarian/narsian) + - tweak: how the narsian/ratvarian coats can be made + - bugfix: fixes some ghost roles from dying of stupid shit + - bugfix: pandoras attacking their owners + - rscadd: Added Rising Bass and the shifting scroll. + - tweak: Changes the martial arts scroll in the uplink to "Sleeping Carp Scroll" + ShizCalev: + - bugfix: Fixed floodlights not turning off properly when they're underpowered. + - bugfix: Fixed emitters not changing icons properly when they're underpowered. + Sishen1542: + - rscadd: Clicking a pack of seeds with a pen allows you to set the plant's name, + description and the pack of seeds' description. Useful for differentiating genetically + modified plants. These changes will persist through different generations of + the plant. + - rscadd: Hydroponics trays update their name and description to reflect the plant + inside them. They revert to default when emptied. + Toriate: + - rscadd: Polychromic shorts now have a digitigrade state + Trilbyspaceclone: + - rscadd: ports all the new donuts, burgars, and chicken stuff from RG + - rscadd: ports new snowcone + - rscadd: ports grill + - rscadd: ports beakfeast tag/mood lit as TG has it + - rscadd: ports all the amazing new sprites + - tweak: ports crafting for many things like snowcones needing water + - balance: ports of many craftings + - soundadd: lowers fryers sound + - imageadd: ported icons for new food/grill + - imagedel: ports the deletion of some icons and images + - spellcheck: ports a spell check for the snowcones + - code_imp: ports fixes for stuff I didnt know were even broken with snowcones + - bugfix: coder cat failers to push the last commit from year(s) ago + - admin: Updates the changlogs + - tweak: meat hook from HUGE to bulky + - tweak: CE hardsuit is now more rad-proof + - bugfix: Wrong icon names, missing dog fashion with telegram hat + - rscadd: New softdrink that comes in its own vender! + - rscadd: Honey now has a reaction with plants + - tweak: Buzz fuzz now only has a 5% to give honey and will now give 1u of sugar + not 2 + - rscadd: Blaster shotguns back into armory + - rscdel: Removed Lighters in thunderdomes + - rscadd: Silicons now know what a slime is saying! + - balance: honey now will not kill slimes. Honey slimepeople can be a thing now, + go sci. + - rscadd: Added insulin into many of the borg hypo's + Useroth: + - rscadd: bamboo which can be used to build punji sticks/ blowguns available as + a sugarcane mutation or in exotic seed crate + - tweak: changed the sugar cane growth stages because fuck if I know why, but it + was in the PR + - rscadd: 'New lavaland ruin: Pulsating tumor' + - rscadd: New class of lavaland mobs, a bit weaker than megafauna but still stronger + than most of what you normally see + - rscadd: Ghost cafe spawner. For letting people spawn as their own character in + the ninja holding facility. It bypasses the usual check, so people who have + suicided/ghosted/cryod may use it. + - rscadd: Dorms in the ninja holding facility. + Xantholne: + - rscadd: Santa Hats to Loadout and Clothesmate + - rscadd: Christmas Wintercoats to Loadout and Clothesmate + - rscadd: Christmas male and female uniforms to loadout and Clothesmate + - rscadd: Red, Green, and Traditional Santa boots to loadout and Clothesmate + - rscadd: Christmas Socks, Red candycane socks, Green candycane socks to sock selection + kappa-sama: + - balance: legion drops more crates now + - balance: .357 speedloaders in autolathes are now individual bullets instead, speedloaders + are now illegal tech, costs less total metal to make 7 bullets than a previous + speedloader. 7.62mm bullets in autolathe when hacked and costs more metal to + make 5 7.62mm bullets than getting a clip from the seclathe. + - tweak: mentions that you can refill speedloaders on .357 uplink description + - bugfix: you can now strip people while aggrograbbing or higher + - rscadd: plasmafist to wizard + - code_imp: modular is gone + - rscadd: martial apprentices for the local Chinese wizard + - bugfix: broodmother baby lag + - balance: you can no longer get 100k credits by spending 4k roundstart + - balance: cooking oil in sunflowers instead of corn oil + - bugfix: throats are no longer slit happy + keronshb: + - rscadd: Adds reflector blobs to shield blob upgrades + kevinz000: + - rscadd: Launchpads can now take number inputs for offsets rather than just buttons. + - balance: nanites no longer spread through air blocking objects + - rscadd: Night vision readded as a darkness dampening effect rather than darksight. + - rscdel: conveyors can only stack items on tiles to 150 now. + - rscadd: added 8 character save slots + - rscadd: Cargo shuttle now silently ignores slaughter demons/revenants instead + of being blocked even while they are jaunted. A drawback is that manifested + ones can't block it either, any more. + - balance: flashbangs process light/sound separately and uses viewers(), so xray + users beware. + - tweak: Stat() slowed down for anti-lag measures. + - bugfix: sprint/stamina huds now work again + - balance: Combat defibs now instant stun on disarm rather than 1 second again + - balance: Defibs are now always emagged when emagged with an emag rather than EMP. + - bugfix: aooc toggling now only broadcasts to antagonists + - code_imp: Antag rep proc is now easier to read and supports returning a list. + - balance: Clockwork marauders are now on a configured summon cooldown if being + summoned on station. They also rapidly bleed health while in or next to space. + And they glow brighter. + lolman360: + - rscadd: Added ability to pick up certain simplemobs. + nemvar: + - bugfix: The brains of roundstart borgs no longer decay. + - code_imp: Refactored the visibility of reagents for mobs. + nicbn, Kevinz000, ShizCalev: + - tweak: Fire alarm is now simpler. Touch it to activate, touch it to deactivate. + When activated, it will blink inconsistently if it is emagged. + - bugfix: You can no longer spam fire alarms. Also, they're logged again. + - bugfix: Fixed fire alarms not updating icons properly after being emagged and + hacked by Malf AI's. + r4d6: + - rscadd: Added a N2O pressure tank + - rscdel: Removed a AM Shielding from the crate + - rscadd: Added Handshakes + - rscadd: Added Nose booping + - rscadd: Added submaps for the SM, Tesla and Singulo + - rscadd: Added a placeholder on Boxstation for the Engines + - bugfix: fixed Nose boops not triggering + shellspeed1: + - rscadd: Adds Insect markings + - rscadd: Adds three new moth wings. diff --git a/html/changelogs/archive/2020-01.yml b/html/changelogs/archive/2020-01.yml new file mode 100644 index 0000000000..c145d9c62b --- /dev/null +++ b/html/changelogs/archive/2020-01.yml @@ -0,0 +1,472 @@ +2020-01-27: + 4dplanner, CRITAWAKETS, XDTM, ninjanomnom: + - rscadd: sepia slime extract has a delay before activating + - balance: the user of a sepia slime extract is no longer immune to the time field + - balance: chilling sepia is now the support extract - it always freezes the user, + but not other marked people. give one to your golem! + - rscadd: burning sepia spawns the rewind camera. Take a selfie with someone and + give it to them to make sure they remember the moment forever! You don't actually + need to give them the photo, they'll remember anyway. Keep it as a reminder. + - rscadd: rewinding (deja vu) effect resets your location to the turf you were on + after 10 seconds as well as resetting limbs/mobs/objects damage to the point + it was added. + - rscadd: The deja vu effect cannot resurrect the dead, but will heal their corpse. + New limbs fall off, old ones re-attach + - rscadd: 'Regenerative sepia cores add a deja vu effect before healing instead + of a timestop remove: timefreeze camera is admin spawn only.' + - rscadd: recurring sepia recalls to the hand of the last person to touch it after + activating. Reusable timestop grenades! + - tweak: some special cameras don't prompt for customisation + - bugfix: timefreeze camera actually makes a photo + - bugfix: timestop stops pathing and mechs. + - bugfix: adds a check to make sure simple_animals don't get their AI toggled while + sentient + - bugfix: Adds the timestop overlay to frozen projectiles + - bugfix: Timestopped things have INFINITY move_resist as opposed to being anchored + - bugfix: Timestop will now unfreeze things that somehow leave it + - bugfix: mobs in the middle of a walk_to will have their walk stopped by timestop + - bugfix: mobs that are stunned will be stopped mid walk as well + - bugfix: pulling respects changes in move_force + - bugfix: swapping places respects move_force if the participant is not willing + - bugfix: timestop is properly defeated by antimagic. + - bugfix: timestop only checks antimagic once + - tweak: Time stop now applies its visual effect on floors, walls and static structures + (with no change otherwise) + - tweak: Movable structures are now anchored while time stopped. + - tweak: Timestop effects now prevent speech. + AffectedArc07: + - code_imp: All code files are now in the LF line format, please stick to it + - tweak: Added CI step to check for CRLF files + - code_imp: Line ending CI works now + Arkatos, Zxaber, Ghommie: + - rscadd: Certain AI abilities now dynamically show their remaining uses on the + mouse hover over their respective action buttons. + - bugfix: Malfunctioning AIs can no longer abuse the confirmation popup to create + extra (unstoppable) doomsdays. + - bugfix: Fixed AIs being able to use some of their abilities such as the doomsday + whilst dead, and the doomsday loading phase not halting upon AI death. + Arturlang: + - tweak: Vampires are no longer as tanky + - rscadd: Added modular computers to the loadout + Bhijn: + - rscadd: Limbs now regenerate their stamina faster while disabled + - rscadd: Limbs now have the same incoming stamina damage multiplier mechanics as + spacemen, where the more staminaloss they take while disabled, the less staminaloss + they'll take. + - balance: Limbs have had their base stamina regen rate doubled to match the doubled + stamina regen rate of standard spacemen. + - rscadd: Added a preference to make the sprint hotkey be a toggle instead of a + hold bind + - rscadd: Added a preference to bind the sprint hotkey to space instead of shift. + - bugfix: server_hop can no longer be used to remotely lobotomize a spaceman + Bhijn helped: + - bugfix: Fixes Dragon's Tooth Sword 50% armor penetration by making it 35% + BonniePandora: + - admin: 'Added another SDQL option. Using "UPDATE selectors SET #null=value" will + now resolve value and discard the return. This is useful if you only care about + the side effect of a proc.' + CameronWoof: + - rscadd: Ghost Cafe patrons now spawn with chameleon kits. Dress up! Be fancy! + - rscadd: Robots can now check the crew manifest from anywhere with the "View Crew + Manifest" verb. + - tweak: Lizard tails are now viable options for humans and anthromorphs. + Commandersand: + - bugfix: fixed some clothnig sprites + - balance: lightning bolt,tesla,forcewall,emp spells have lower cooldown + - balance: fireball has a 10 second starting cooldown + DeltaFire15: + - bugfix: Vitality matrixes now correctly succ slimes + Denton, ported by Hatterhat: + - tweak: Most upgradeable machines now show their upgrade status when examined while + standing right next to them. + - tweak: Added examine messages to teleporter stations that hint at their multitool/wirecutter + interactions. + - tweak: Renamed teleporter stations from station to teleporter station. + - code_imp: Changed the teleporter hub accurate var to accuracy; the old name misled + people into thinking that it was a boolean. + Detective-Google: + - tweak: replaced the sprites with new ones requested. + EmeraldSundisk: + - rscadd: Adds a sign outside MetaStation's custodial closet + FantasticFwoosh, ported by Hatterhat: + - rscadd: Both reagent universal enzyme & sacks of flour are now available for their + respective costs from the biogenerator. + - rscadd: New crafting recipies for donut boxes, eggboxes & candle boxes have been + added to cardboard recipes for the collective benefit of service personnel and + the station. + Ghommie: + - tweak: Attached kevlar/soft/plastic padding accessories are now stealthier and + will no longer be displayed on mob examine. + - refactor: Refactored that mess of a code for alternate worn clothing sprites for + digitigrade and taurs. + - bugfix: Fixed some issues with the aforementioned feature you may or may not have + experienced because it was pretty lame. + - bugfix: Fixed missing digi versions fishnet sprites and wrong digitigrade left + dir purple stockings sprite. + - imageadd: Add digitigrade versions for boxers and the long johns. + - bugfix: Fixed the secret sauce recipe being randomized every round. + - bugfix: Fixed singularity pulls duping rods out of engine floors. + - rscdel: Removed an old pair of zipties from the captain closet. + - bugfix: Chestbursters won't delete the host's brain somewhat anymore. + - bugfix: Fixed roundstart mushpeople being unable to MUSH PUUUUUUUUUUUUNCH!! + - bugfix: Lattices can be examined yet again. + - bugfix: Made reagent containers examine text less annoying. + - bugfix: Virus food dispensers dispense virus food again. + - bugfix: Borg hypos inputs do not display typepaths anymore. + - bugfix: Restored chem dispensers alphabetical order. + - bugfix: Sanitized cargo export messages for reagents. + - bugfix: Riot foam dart (not the ammo box) design cost is yet again consistent + with the result's material amount. + - bugfix: Fixed a little exploit with ventcrawlers being capable of escaping closed + turfs by printing scrubbers/vents into them. + - bugfix: deconstructing a rubber toolbox with the destructive analyzer won't "lock" + the machine anymore. + - bugfix: Something about empty hand combat mode right click waving hands defying + common sense and being spammy. + - imageadd: Towels are now "digitigrade-friendly". + - bugfix: The Barefoot drink and mousetraps will now work even if wearing certain + "feet-less shoes". + - rscadd: Refactored code to allow all living mobs to use shields and not only humans. + - tweak: Monkys will now retaliate against aliens attacking them (as if they even + posed a threat to start with). + - tweak: add a click cooldown to the overly spammable table slamming. + Ghommie (original PRs by Kevinz000, ShivCalez, 4dplanner, Barhandar, 81Denton, zxaber, Fox-McCloud): + - rscadd: All atom movables now have move force and move resist, and pull force + An atom can only pull another atom if its pull force is stronger than that atom's + move resist + - rscadd: 'Mobs with a higher move force than an atom''s move resist will automatically + try to force the atom out of its way. This might not always work, depending + on how snowflakey code is. experimental: As of right now, everything has a move + force and resist of 100, and a pull force of 101. Things take (resist - force) + damage when bumped into experimental: Failing to move onto a tile will now still + bump up your last move timer. However, successfully pushing something out of + your way will result in you automatically moving into where it was.' + - bugfix: Bolted AIs can no longer be teleported by launchpads. + - balance: Megafauna cannot teleport + Hatterhat: + - balance: Beakers are generally more useful now, with slight capacity increases. + - tweak: Transfer amounts are different now. Adjust your muscle memory to compensate. + - balance: ore redemption machines actually get affected by lasers again kthx + - tweak: crusher trophy drop chance on mining mobs increased to 1 in 4 (from 1 in + 20) + - bugfix: Blood-drunk buff from blood-drunk eye crusher trophy is less likely to + cripple its user. + - tweak: Forcefield projectors now fit on toolbelts. + - imageadd: New sprites for ATMOS holofan and forcefield projectors! + - tweak: tweaks some values around with beaker transfer amounts, adds a transfer + value verb (altclick) + - rscadd: 'Syndicate sleepers (read: the ones that''re red and have controls in + them) can now be recreated with a sufficient basis in nonstandard (read: illegal) + technologies!' + - bugfix: Explorer hoods on standard explorer suits can be reinforced with goliath + hide plates again. + - rscadd: A shipment of Staff Assistant jumpsuits from the Goon-operated stations + appear to have made their way into your loadout selections - and into the contraband + list from ClothesMates... + - balance: Dropped Exo-suit armor to put it more in line with being an explorer + suit sidegrade and not a straight upgrade for Lavaland usage. + - rscadd: You can now print .357 AP speedloaders from Security techfabs after you + pick up the Advanced Non-Standard Ballistics node. + - rscdel: Forensic scanner removed from Advanced Biotechnology node. + - tweak: Ash Drake armor now has goliath resistance, same as the Exo-suit. + KathrinBailey: + - rscadd: Empty engineering lockers for mappers. + - rscadd: Industrial welding tools to the engineer welding locker. + - rscdel: Removed the multitool, airlock painter, mechanical toolbox, brown sneakers, + hazard vest and airlock painter from the CE's locker. + KeRSedChaplain: + - imageadd: The clockwork cuirass can now support slithering taur bodies. + Kevinz000: + - bugfix: Fixes successful projectile hits also striking another atom on the same + turf should the first one be not the target the projectile was meant for. + - rscdel: Removes infinite reflector loops. + Kraseo: + - bugfix: Jelly donuts and pink jelly donuts will now properly display sprinkled + icon state. + - bugfix: Jelly donuts and its variants will properly spawn with berry juice. + - bugfix: Slime jelly donuts have slime jelly in them now. (thanks ghommie) + - bugfix: Virgo hairstyles no longer have those annoying quotation marks. Rejoice + for you will no longer have to use the scrollbar. + - imagedel: Got rid of some strange-looking hairstyles. (Tbob, fingerweave, etc.) + LetterN: + - rscadd: Doppler logs + - tweak: Shockcolar and electropack uses the new signaler ui + - tweak: Renaming shockcolar requires a pen + - rscadd: Adds banjo + Linzolle: + - bugfix: fixes matchboxes runtiming every time they spawn + MrJWhit: + - tweak: Increases plasma usage in radiation collectors + Naksu: + - code_imp: reagent IDs have been removed in favor using reagent typepaths where + applicable + - bugfix: mechas, borg hyposprays etc no longer display internal reagent ids to + the player + Owai-Seek: + - rscadd: Four New Bounties + - tweak: tweaked several bounties + - tweak: reorganised several bounties + - balance: balanced several bounties + - bugfix: added shady jims to vendor + - rscadd: Towel, Bedsheet, and Colored bedsheet bins to Dojo. Some lockers with + carpets and wood, another bathroom/shower, tons of cleaning supplies, some additional + trash cans, a tiny medical area, and some vendors/vendor resupplies. Also added + some Ambrosia Gaia seeds. + - tweak: Moved some lights around, extended the dojo a bit to make it feel more + spacious. + - rscdel: Cafe Newsfeed Frame + PersianXerxes: + - tweak: Reduces the range of the forcefield projector from 7 tiles to 2 tiles. + Putnam: + - rscadd: Alcohol intolerance trait, which forces vomiting on any alcohol ingestion + - rscdel: Arousal damage is gone, and with it the arousal damage heart on the UI. + - rscdel: As exhibitionist relied on arousal damage, that's gone too. + - rscdel: Bonermeter and electronic stimulation circuit modules are gone. + - rscdel: Masturbation is no longer an option in the climax menu. It was identical + to climax alone in every way but text. Emote it out. + - rscadd: Arousal on genitals can now be displayed manually, on a case-by-case basis. + - rscadd: '"Climax alone" and "climax with partner" now only display to the people + directly involved in the interaction. rework: Catnip tea, catnip, crocin, hexacrocin, + camphor, hexacamphor all had functions or bits of functions reworked.' + - tweak: '"Climax with partner" now requires consent from both parties--it can no + longer be used on mindless mobs, and it asks the mob getting climaxed with if + they consent first.' + - tweak: A lot of MKUltra behaviors have been moved to hypno checks or removed due + to reliance on maso/nympho/exhib. + - rscadd: Cold-blooded quirk + - rscadd: 'Two relief valves for atmospherics, available in your RPD today: a unary + one that opens to air and a binary one that connects two pipenets, like a manual + valve.' + - tweak: The atmos waste outlet injector on box has been replaced with an atmos + waste relief valve. + Putnam3145: + - rscadd: Dynamic storytellers, a new voting paradigm for dynamic + - rscadd: Support for approval voting and condorcet (ranked choice) voting in server + votes + - rscadd: Ghost cafe mobs can now ghostize + - rscadd: Ghost cafe now has a cremator + - rscadd: Ghost cafe mobs are now eligible for ghost roles + - refactor: Ghost roles now use an element for eligibility purposes + - bugfix: You can toggle some prefs properly now. + - bugfix: no ass slap is no longer the same thing as no aphro + - balance: Devastating bombs kills bomb armor'd mobs again + - rscadd: Added a sort of "game mode ban" by way of having people rank their game + modes favorite to least favorite after the secret/extended vote. + - bugfix: Turns out the schulze scoring was written wrong and it was setting things + to 0 that shouldn't have been, so that's fixed. + - config: Random engines are now weighted. + - rscadd: Ghost dojo now has an autoylathe. + - rscdel: Ghost dojo no longer has VR or modular computer access. + - tweak: Ghost dojo mobs are pacifists. + - tweak: Ghost dojo booze-o-mat is now all access. + - bugfix: Ghost dojo crematorium now has a button. + - bugfix: Traitor objectives don't take a dump when they try to add an assassinate + anymore + - admin: Objective removal with antag panel no longer commented out silently while + still being an option that gives useful feedback on stuff it's not doing in + any respect + - rscadd: Second, temporary flavor text! + - bugfix: Limb damage works now + - tweak: Score instead of ranked choice for mode tiers + - bugfix: Chemistry not :b:roke + - tweak: Ghost dojo spawns will dust if their owner suicides or uses the "ghost" + verb. + - admin: Crafting is logged in a file now + - bugfix: temporary flavor text now pops up properly + - code_imp: demodularized player panel code, mostly + - admin: added ghost role eligibility delay removal to player panel + - balance: Metabolic synthesis disables if user isn't well-fed rather than if user + is starving + - bugfix: Gibtonite no longer instantly explodes upon being pickaxe'd. + - balance: Cold-blooded costs -2 quirk points now + - config: Added suicide to the config. + - tweak: Ghost cafe mobs are super duper attached to the ghost cafe. + - bugfix: Meow Mix bar sign works + - bugfix: Fixed a few relief valve behaviors + Ryll/Shaps, ported by Hatterhat: + - rscadd: Point-blanking people with shotguns actually throws them backwards! + Savotta: + - rscadd: snout + - imageadd: snout + Seris02: + - tweak: made it so trait blacklisting removes random positives instead of removing + everything + - rscadd: added atmos holofirelocks and temperature blocking + - tweak: tweaked how atmos holofan looks + - rscadd: stunglasses + - rscadd: disabler sechuds + - rscadd: adds coconut + - rscadd: adds a coconut bong + - rscadd: Auto ooc + - admin: changed "assume direct control" from m.ckey = src.ckey to adminmob.transfer_ckey(M) + so it works with auto ooc + - rscadd: marshmallow + - rscadd: telescopic IV drip + - bugfix: cardboard box speed + - tweak: makes gorilla shuttle emag only + - tweak: changed where the observe verb is. + - tweak: the way chameleon clothes update on change + - bugfix: chameleon cloak icon + - balance: Explosions now cause knockdown instead of KOs, with the amount of time + scaling off bomb armor. Heavy explosions still cause a ~2 second KO for follow + up attacks. + - balance: Devastating explosions now no longer gib players with more than 50 bomb + armor. This used to be more or less random depending on the amount of bomb armor. + - code_imp: Removed reagent explosion code that would trigger for <1 amount reactions. + - rscadd: traitor tool for bowmanizing headsets + bowmanizing headsets + - rscadd: durathread winter coats from hyper station + - tweak: conveyor belt now are stacks instead of single item + - tweak: conveyor crate has 30 belts + - tweak: printing a conveyor costs 3000 metal + - rscadd: you can press the conveyor switch in hand to link any not deployed belts + to it + - tweak: sniffing sneezing etc doing anything if they don't breathe + - bugfix: probably fixes the make mentor button + - tweak: the sprites for the conveyor belts to look more directional + Skoglol: + - bugfix: Falsewalls now properly hide pipes and wires. + SpaceManiac, bobbahbrown, ShizCalev, SpaceManiac (ported by Ghommie): + - code_imp: It is now possible to set a different most-base-turf per z-level. + - spellcheck: Removed unlawful reference to Disney's Star Wars franchise in map + logging. + - tweak: Moved mapping related errors to their own log file. + - bugfix: Destruction on Lavaland will no longer reveal space in rare situations. + Tlaltecuhtli, Nemvar, Trilby, Hatterhat: + - rscadd: russian surplus crate, sec ammo crate, meat/veggie/fruit crate, rped crate, + bomb suit crate, bio suit crate, parrot crate, chem crate, db crate + - tweak: lowered price of some crates which are overpriced for no reason aka the + tablet crate and the mech circuits crates, track implant crate has also track + .38 ammo + - bugfix: sectech vendor has a refill pack + Trilbyspaceclone: + - bugfix: Fermi plushie can be made once again + - tweak: range on Engi Tray scanners and Rad-Scanners + - bugfix: issues with mapping done my Trilby + - rscadd: Grass now makes light beer when distilled + - tweak: allows bandoliers to hold any ammo type as long as it has a casing + - server: Cleans out the last years of changlogs + - bugfix: 'rouge cases of #$39; in bottle/pill/patch/condiments' + - tweak: Adds missing but needed flags to MASON RIG + - bugfix: missing sprites with crushed cans + - tweak: Halfs the nutriments in sugar + - rscadd: Glitter is now makeable with ground plastic and some crayons + - code_imp: Makes more folders and files for uplink. + - rscadd: Seed packs now have RnD points inside them + - rscadd: New tips that reflect the now use seed packs have for Rnd / Chems affect + on plants + - code_imp: Made the research file look nice rather then an eye harming list + - bugfix: Fixed fragile space suits breaking from weak and non-damaging "weapons" + (such as the Sord, toys and foam darts). + - rscadd: 'tip of the round: Cleanbot can withstand lava and burning hot ash. Its + a god' + - rscadd: more glassware + - rscadd: Few new packs and glassmaker kit! + - tweak: prices/chems of crates/autobottler + - bugfix: some crates ungettable as well as some broken crates + Trilbyspaceclone, Ghommie: + - rscadd: More types of glass can now be used to make a solar panel, with different + sturdiness and efficiency depending the type. + Tupinambis: + - tweak: Replaces new fire alarms with a slightly updated version of the old ones. + - bugfix: Fixed bug where Amber alert had no proper alert lights, and red alert + had amber lights. + - balance: RLDs now cost more to use, have reduced matter capacity, and sheets are + worth less when refilling them. + Unit2E & JMoldy, ported by Hatterhat: + - balance: the powerfist now punches people away at high velocity depending on setting. + - rscadd: the powerfist now leaks the gas it uses onto the tile you're on. + - tweak: Adds weak punch variations for empty and near-empty punching. + Xantholne: + - bugfix: Christmas clothes that where missing stuff should work again + - tweak: Christmas clothes moved from clothesmate and loadout to premium autodrobe, + hoodies and boots remain. + - rscadd: Botany bee pet, Bumbles + - rscadd: New bee models that aren't 1 tile big of 0 opacity pixels + - rscadd: Cheongsam and Qipao clothing added to loadout and clothesmates + dapnee: + - imageadd: new toxin's uniform and accessories + - imagedel: old toxin's uniform and accessories + deathride58: + - balance: The stamina buffer no longer uses stamina while recharging. + jakeramsay007: + - rscadd: The assorted .357 revolvers (except russian revolver) can now also load + .38, like real life. + kappa-sama: + - rscadd: loot crates in cargo contraband + - code_imp: modular_citadel file movement + - code_imp: modular citadel loses some files + - balance: dragnet snares can now be removed in 5 seconds + keronshb: + - rscadd: Adds new features for nanites + - bugfix: fixed the missing icons from Dermal Button nanites + - rscadd: Ports the special nanite remote, mood programs, and research generating + nanites + - balance: rebalances some nanites + - bugfix: fixed my messup + kevinz000: + - rscadd: throwing things no longer makes them randomly turned as long as you aren't + on harm intent + - rscadd: Custom holoforms have been added for pAIs and AIs. oh and cyborg holograms + of specific modules too. + - balance: pais are no longer indestructible-flagged while in card form. pai radios + now short out if they are forcefully collapsed from damage. + - bugfix: telescopic iv drips now have the proper sanity checks for deployment. + - bugfix: megafauna can hear again + - balance: Cargo passive gen is now 500 down from 750. + - config: Added a few more nightshift config entries + - rscadd: nightshift_public_area variable in areas to determine how public an area + is. + - rscadd: NIGHT_SHIFT_PUBLIC_AREAS_ONLY config entry allows the server to be configured + to only nightshift areas of that level and below (so areas that are more public) + - rscadd: Config entries added for requiring authorizations to toggle nightshift. + Defaults to only requiring on public areas as determined by above + - balance: nuclear fist buffed. + - balance: cogscarabs are now fulltile-hitbox. + - balance: emitters are now hitscan + - balance: monkies gorrilize easier now + - rscadd: Ghosting no longer stops abductors from using you. + - rscadd: guests can now looc + - tweak: tableslamming has 0.4 second cooldown instead of 0.8 + - bugfix: health analyzers now work + - code_imp: Mapping helpers added for power cables and atmos pipes. + - rscdel: Blood duplication is gone, but viruses now react up to 5 times, 1 time + per unit, for virus mix. + - rscadd: you can now block people on your PDA + - bugfix: Grenades can now have their timers adjusted. + - balance: Cloning has been nerfed. + - bugfix: hilbert hotel is now less of an exploity mess + - balance: Doorcrushes are once again instant. + nik707: + - tweak: engraving light_power from 1 to 0.3 + r4d6: + - rscadd: Added a Radiation Hardsuit + - rscadd: Added a Radiation Hardsuit crate + - rscadd: Added 3 SM Engine variations. + - rscadd: 'Added a way to make opaque plastic flaps change: Change the already existing + flap recipe to show that they are see-through' + - rscadd: Animations for the RCD + - bugfix: Said animations being pulled by the Singulo + - balance: Prevent Reinforced Doors from being RCD'ed + - bugfix: Deconstructing Floors now cost MUs like everything else + - tweak: changed the RCD's upgrades into flags + - rscadd: Allow RCDs to print APC, Firelocks and Fire Alarms with the right upgrade + - balance: Allow Engineers to print RCDs and RPDs from their protolathe without + needing to hack one. + - rscadd: Added a playback device + - bugfix: Made the Voice Analyzer actually care about languages + - bugfix: fixed SM's piping + - rscadd: Added a message when pulsing the open wire. + - bugfix: fixed being able to use a playback device and a voice analyzer to activate + each others + - rscadd: added passive vent to the arsenal of atmospheric devices. + - rscadd: Mining base now has a common area accessible via a new shuttle on the + medium-highpop maps, and a security office connecting the gulag and the mining + base. Gulag also has functional atmos. + - rscadd: Added more Cyborg Landmarks + - refactor: better code for passive vents + - bugfix: fixed a hole in Meta + - rscadd: Added the ability to easily add variations of the mining base + - bugfix: fixed a sprite + timothyteakettle: + - bugfix: fixed not being able to remove trait genes without a disk being inserted + into the dna manipulator diff --git a/html/changelogs/archive/2020-02.yml b/html/changelogs/archive/2020-02.yml new file mode 100644 index 0000000000..11389c24ae --- /dev/null +++ b/html/changelogs/archive/2020-02.yml @@ -0,0 +1,587 @@ +2020-02-26: + AnturK ported by kevinz000: + - rscadd: Dueling pistols have been added. + Arturlang: + - rscadd: Replaces a lot of ingame UIs with TGUI next, increasing performance drastically. + - rscadd: Each night for bloodsuckers will last longer due to the sun dimming. + - tweak: You cant level up for free, now you have to pay blood for power. + - balance: Bloodsuckers are no longer as resistant to hard stuns and regenerate + less stamina. and a lot of their cooldowns are a lot higher. + - rscdel: Removed text macros from the chem dispenser. + - rscadd: Replaced with dispenser input recording macros. + - bugfix: Fancifying makeshift switchblades now works + - balance: Shields will no longer block lasers, and will break if they take too + much damage. + - rscadd: Added a TGUI Next interface for crafting + - rscdel: Removed the old TGUI slow crafting interface + - tweak: The MK2 hypospray now + - admin: The debug outfit is now kitted out for whatever debbuging needs. + - bugfix: Fixed the pandemic naming and the radiation healing symptom UI crashing + - tweak: Hyposprays now switch modes on CTRL click, instead of alt, as it was already + reserved for dispension amount. + - rscadd: Nanite interfaces have gotten a rework to TGUI Next, and can now support + sub-programs. add:Adds the nanite sting program, which will allow you to manually + sting people to give them nanites, changeling style. + - balance: The pandemic can no longer make vaccines or synthblood as quickly. + - rscadd: The syndicate uplinks interface has been redone in TGUI Next + - tweak: Valentines can now be converted by bloodsuckers + Bhijn: + - tweak: Click-dragging will now only perform the quick item usage behavior if you're + in combat mode. + BlueWildrose: + - bugfix: podpeople tail wagging + - tweak: lifebringer ghost role fixes + BuffEngineering, nemvar.: + - bugfix: Addicts can now feel like they're getting their fix or kicking it. + - bugfix: Aheals now remove addictions and restore your mood to default. + CameronWoof: + - tweak: Lighting looks better now. I can say that because the PR wouldn't be merged + and you wouldn't be reading this if it wasn't true. + - rscadd: Ammonia and saltpetre can now be made at the biogenerator. + Commandersand: + - tweak: uplink centcomm suit doesn't have sensors + DeltaFire15: + - balance: Nar'Sie runes no longer benefit from runed floors. + Detective-Google: + - rscadd: 'the POOL. remove: boxstation dorms 7' + - bugfix: valentines candy no longer prefbreaks + - rscadd: Loudness Booster pAI program + - rscadd: Encryption Key pAI program + EmeraldSundisk: + - bugfix: Connects mining's disposal unit on Delta. + - tweak: Slight visual adjustments to the immediate affected area. + Feasel: + - balance: Buffed dissection success chances. + Ghommie: + - tweak: The anomalous honking crystal should now properly clown your mind. + - bugfix: Stopped the ellipsis question mark from being displayed twice in the examine + message for masked/unknown human mobs. + - tweak: Made the aforementioned ellipsis question mark display on flavor-text-less + masked/unknown human mobs too for consistency. + - bugfix: Stopped an APTFT exploit with spray bottles. + - bugfix: Fixed the detective revolver being quite risky to use. + - bugfix: Hair styles and undergarments are yet again free from gender restrictions. + - tweak: Clown ops will find bombananas and clown bomb beacons instead of minibombs + and bomb beacons in their infiltrator ship now. + - tweak: For safety, the syndicate shuttle minibombs and bombananas come shipped + in a box. Please don't instinctively eat any of those nanas, thank you. + - tweak: Uplink items excluded (such as mulligan, chameleon, ebow) from or exclusive + (such as cyber implants) to normal nuke ops will now be properly unavailable/available + to clown ops. + - bugfix: Fixed bananium energy sword/shield slips. + - balance: Buffed said slips to ignore no-grav/crawling/flying as well as adding + some deadly force to the e-sword. + - bugfix: Fixed the 'stache grenade anti-non-clumsy user check. + - balance: Doubled the timer for the sticky mustaches effect from the above grenade + (from 1 to 2 minutes) + - bugfix: Fixed an edge case with the chaplain armaments beacon spawning the box + in nullspace. + - tweak: The playback device's cooldown now proportionally increases with messages + longer than 60 characters (3 seconds is the default assembly cooldown). + - bugfix: Fixed space ninjas "Nothing" objective. Now you gotta steal some dandy + stuff such as corgi meat and pinpointers as a ninja too. + - bugfix: Fixed maploaded APC terminals direction. + - balance: Nerfed magnetic rifles/pistols by re(?)adding power cell requirements + for it. These firearms must be recharged after firing 2 magazines worth of projectiles + and are slightly more susceptible to EMPs. + - bugfix: Fixed the tearstache nade not properly working. + - balance: Buffed it against space helmet internals. + - tweak: Holographic fans won't display above mobs and other objects anymore. + - bugfix: Fixed paraplegics appearing as shoeless. + - bugfix: Fixed the petting element. + - bugfix: Fixed slipping. + - refactor: Refactored mob holders into an element. + - bugfix: Fixed a few minor issues with that feature. such as mismatching sprites + for certain held mobs and a slight lack of safety checks. + - rscdel: holdable mobs can't force themselves into people's hands anymore. + - bugfix: Milkies fix. + - bugfix: Fixed some mounted defibrillator issue with the altclicking functionality. + - bugfix: Fixed no-grav lavaland labor/mining shuttle areas. + - bugfix: Fixed a little issue with sleeper UI and blood types. + - bugfix: Fixing accidental nerfs to the magpistol magazine. + - bugfix: The Lavaland's Herald speech sound should only play if they are actually + speaking. + - bugfix: Nerfed cargo passive points generation from 500 to 125 creds per minute. + - bugfix: Fixed whitelisted/donor loadouts + - bugfix: Childproofs double-esword and hypereuplastic blade toys. + - balance: Some reagent holders (such as cigarettes, food) are not suitable for + reagents export anymore, while unprocessed botany crops will only net 1/3 of + the standard reagents values. + - bugfix: Export scanners now include the reagents value in the price report. + - bugfix: Fixed a little inconvenience with the character setup preview dummy having + extra unwarranted bits. + - bugfix: Stopped role restricted uplink items from being discounted despite not + being purchasable most times. + - bugfix: Missing words replacement file for the gondola mask. + - bugfix: Fixed an issue with the nearsighted prescription glasses taking over worn + eyewear. + - bugfix: Fixed AI unanchoring not properly removing the no teleport trait. My bad. + - bugfix: Fixed another issue with hering comsig. + - imageadd: Fixed dozen missing privates sprites. + - bugfix: A little fix concerning some R&D and reagents. + - bugfix: Further mob holder fixes. + - bugfix: Fixed being unable to dump a trash bag's contents directly into disposal + bins. + - bugfix: Doubled the halved flavor text maximum length. + - bugfix: Reduced tongue organ damage and tasting pH message spam. + - bugfix: Fixed agent IDs not registering the inputted name. Thanks MrPerson. + - bugfix: Fixed solar panels/trackers (de)construction being a bit wonky. + - bugfix: Fixed something about slime blood and the law of conservation of mass. + - bugfix: Fixed flypeople being emetic machine guns. + - bugfix: Fixed virology being unable to be done with synthetic blood. + - rscdel: Renamed "blaster carbine" and "blaster rifles" back to "energy gun" and + "laser gun" respectively + - bugfix: Fixed magnetic rifles & co being inconsistent with printed energy guns + and start with an empty power cell. + - imagedel: Reverted practice laser gun sprites back to their former glory. Mostly. + - bugfix: Fixed sprint buffer cost and regen being rounded down. + - balance: Nerfed the fermenting barrel export industry. + - tweak: Reagent dispensers selling price no longer takes in account the reagents + volume. It's already handled by reagents export. + - bugfix: pAIs are yet again unable to perform certain silicon interactions with + machineries yet again. + - bugfix: Fixed pAI radios inability to be toggled on/off. + ? Ghommie (original PRs by Floyd/Qustinnus, 4Dplanner, Willox, ninjanomnom, mrdoombringer, + Fikou, Fox McCloud, TheChosenEvilOne, nemvar, bobbahbrown, Time-Green, Stonebaykyle, + MrPerson, ArcaneMusic and zxaber) + : - rscadd: You can now make toolboxes out of almost any solid material in an autolathe + - rscadd: adds Knight's Armour made out of any materials + - rscadd: new ruin found in lavaland protected by dark wizards, I wonder what + they're guarding + - rscadd: You can now put a bunch more mats in the coin mint and autolathe + - rscadd: Adamantine and Mythril are now materials (Adamantine still only from + xenobio, Mythril still only from badminnery). Adamantine boosts an item's + force by 1.5, Mythril gives an item RPG statistics. + - rscdel: most custom sprites for coins have been lost + - rscadd: You can now give your ass acute radiation poisoning + - rscadd: floydmats now apply to all objs / items + - rscadd: you can now make tables and chairs out of any material + - bugfix: Fixes being able to exploit fully upgraded destructive analyzers to + multiply materials + - rscadd: An old monastery from a previously abandoned sector of space has recently + resurfaced in some regions surrounding the station. + - rscadd: Latent scans of the surrounding systems have picked up trace signs of + new, smaller cult constructs, however these signatures quickly vanished. + - rscadd: In other news, scavengers in your sector have been seen occasionally + with classically recreated maces, so autolathe firmware has been upgraded + to accommodate this. + Hatterhat: + - balance: Zombie powder is now instant when ingested, but delayed when injected + or applied through touch. + - tweak: The H.E.C.K. suit is now goliath tentacle resistant and probably better + for acid resistance. + - rscadd: The Engineering techfab can now print standard and large RCD compressed + matter cartridges. + - rscadd: The Experimental Tools node now has the Combifan projector, blocking both + temperature and atmospheric changes. + - tweak: fiddles with the seed extractor upgrade examine to make it not shit + - rscadd: Formaldehyde prevents organ decay and corpses' miasma production at 1u + in the body. + - rscadd: Epinephrine pens now contain 3u formaldehyde. This should not kill you. + - rscadd: The ships often crashed by Free Golems on Lavaland now have GPSes. They're + off, by default, but an awakening Golem could easily turn one on. + - tweak: Standard RCD ammo can now be printed from Engineering-keyed techfabs once + you hit Industrial Engineering. + - tweak: Consoleless interfaces are now default - this means unrestricted protolathes + and circuit imprinters can now be interfaced with by interacting with the machine + itself. + - bugfix: Multitools can now actually be printed from Engineering and Science protolathes/techfabs + once you unlock Basic Tools. + - rscadd: Husking (from being burned to shit) can now be reverted! 5u rezadone or + 100u synthflesh, at below 50 burn. + - balance: Turning a body into a burnt husk now takes more effort. 300 burn's worth + of effort. + - balance: Buckshot individual pellet damage up from 10 to 12.5. Still firing 6 + pellets. + - rscadd: Preservahyde! Made with water, bromine, and formaldehyde, it doesn't decay + into histamine. Instead, it just prevents your organs from rotting into nothing. + - balance: You can now purify eldritch longswords with a bible. This creates purified + longswords, which do not have anti-magic properties, but are still good for + swinging at cultists. + - rscadd: Extend votes! Ported from Hyper, ported from AUstation. + - bugfix: mechs with stock parts now have icons + - balance: Pie reagent transfer now requires an uncovered mouth. + - bugfix: Biogenerators can now actually generate universal enzyme. + - bugfix: The Basic Tools node now unlocks the multitool for printing on Engineering + and Science fabricators. + - rscadd: The Ash Walkers' nest on Lavaland now starts with three bowyery slabs. + - rscadd: You can now welder-harden arrows. It might take longer. + - balance: Silkstring's costs adjusted for bows and whatnot. + - spellcheck: Grammar adjusted on a lot of things relating to bows. + - bugfix: Pipe bows' bowstring doesn't look like it replicated itself upon draw. + IHOPMommyLich: + - tweak: Changed the multiplicative_slowdown of Stimulants from -1 to -0.5 + IronEleven: + - balance: Minor stat changes to Choking, Spontaneous Combustion, Autophagocytosis + Necrosis, Hallucigen, Narcolepsy, Shivering, and Vomiting symptoms. + KathrinBailey: + - bugfix: Missing turf_decals in Cargo Office. + - bugfix: Turns on the docking beacons on Box. + - bugfix: Fixes Starboard Quarter maint room being spaced. It was never intended + to be like how it was. + - bugfix: The aforementioned maint room not having stuff in it. + - bugfix: varedited photocopier sometimes not opening any UI. + - bugfix: Atmos differences in Starboard Quarter maint. + - bugfix: Atmos differences in destroyed shuttle/EVA bridge. Plating replaced with + airless plating. + - bugfix: Rotates AI satellite computers. These have probably been like this since + computers had the old sprites and no directional ones. You shouldn't sit at + a chair to operate a sideways computer. + KrabSpider: + - imageadd: The Van Dyke is no longer Fu Manchu. + - imagedel: Gets rid of a Fu Manchu imitation. + Kraseo: + - bugfix: You can no longer pull before wearing boxing gloves to bypass the grab + check. + - bugfix: Nightmares no longer delete entire guns from existence for merely having + a light on them. + Linzolle: + - bugfix: Bows now will not delete an arrow if it cant fire it. + - bugfix: bows now like and respect sprite changes + MalricB: + - rscadd: '"Shaggy" sprite from virgo' + - rscadd: '"shaggy" option in the character customization' + MrJWhit: + - rscdel: Removed meteor defense tech node + - tweak: TEG + Naksu: + - bugfix: Odysseus chem synthesizing now works again. + Owai-Seek: + - rscadd: Burger, Cargo Packaging, Dirty Magazine, Air Pump, and Scrubber crates. + - rscdel: Duplicate Crate, Festive Wrapping Paper Crate, Contraband Monkey Meat + Crate + - tweak: Gave Seed Crate Ambrosia Seed, gave Biker Gang Crate Spraypaint. + - tweak: Organised some crates with sub-categories. Also, moved all vendor refills + to a new tab. + - tweak: Moved Grill to Service Tab + - bugfix: Engineering Hardsuit Access + - tweak: Blood Crate now has all of the current blood types. + - tweak: Birthday Cake Recipe is now the same as TG. + - tweak: Added Soy Sauce and BBQ Packets to Dinnerware Vendor. + - tweak: Added nurse outfit, nurse cap, and mailman hat to loadout. + - tweak: Changed the name of scrubs to blue, green, and purple scrubs. + - rscadd: Bacon and Eggs food item. Delicious! Added a Lemony Poppy Seed Muffin. + - tweak: Snack Vendor has Chocolates, Tortilla Chips, and a Marshmallow Box + - balance: Mops can now be printed at service lathe once tools are researched. + - balance: Biobags can hold most organic limbs/organs, but not brains, implants, + or cybernetics. + - balance: Trash Bag can now hold limbs (but not heads.) + - balance: Most snack vendor items reduced by 1. + - bugfix: Trash Cans are now actually craftable, and only require metal instead + of plastic. + - imageadd: Bacon and Eggs, Drying Agent Bottle. + - imageadd: Mugs now show reagent colors of contained reagents. Thanks Seris! + - tweak: Reorganized all food recipes, (hopefully) making things easier to find. + - balance: Trays now have a whitelist, allowing them to pick up normal sized foods, + bowls, glassware, booze, ect. + - bugfix: Easter foods are no longer their own Misc Food Category on the top of + the menu. + - spellcheck: fixed a few typos/capitalization consistency. + - tweak: Mexican Foods are their own Subcategory. + - tweak: Donuts are their own Subcategory + - tweak: Moved Sweets from Misc Food in with Pies. Renamed to Pies & Sweets + - rscadd: BROOM + - tweak: Janitor Vendor now has gear for two Janitors. + PersianXerxes: + - rscadd: 'SMES and PACMAN attached to gulag Security to power electrified windows + remove: Removed Sec vendor from gulag Security' + - tweak: Separation of gulag and public mining + - rscadd: Better clarified the comment explaining the contraband tag. + - tweak: Cargo nuclear defusal kits now require an emag'd drop pod console to be + purchased. + - rscadd: Added Kilo Station + - tweak: Adjusts Kilo Station to be more in line with Citadel standards + - imageadd: Added area icons required to make Kilo Station editable on Citadel code + - code_imp: Fixed a reagent container on Kilo pointing to a nonexistent reagent + - config: Adds Kilo Station to the maps config file, does not fix Meta Station's + population requirement + Psody-Mordheim: + - rscadd: You can now make synth-flesh with synthetic blood. + - rscadd: You can now make synthetic blood via mixing saline glucose, iron, stable + plasma and heating it to 350 temp. + - rscadd: You can mix synthetic blood and cryoxadone to create synth-meat in addition + to normal blood. + - rscadd: Disfiguration Symptom. + - rscadd: Deoxyribonucleic Acid Saboteur Symptom. + - rscadd: Polyvitiligo Symptom. + - rscdel: Revitiligo Symptom. + - rscdel: Vitiligo Symptom. + Putnam3145: + - admin: Added logging to various consent things. + - rscadd: Lots of new traitor objectives + - bugfix: gender change potion now respects prefs + - bugfix: Hypno prefs work better. + - admin: Panic bunker is now round-to-round persistent + - tweak: Relief valve now has a TGUI-next UI + - bugfix: Atmos reaction priority works now. + - rscadd: map voting doesn't suck anymore + - bugfix: Dynamic now defaults to "classic" storyteller instead of just failing + if the vote didn't choose a storyteller. + - bugfix: antag quirk blacklisting works now + - tweak: default should be... default + - balance: all supermatter damage is now hardcapped + - tweak: Supermatter sabotage objective no longer shows up with no supermatter + - bugfix: Mining vendors no longer fail and eat your points iff you have precisely + enough points to pay for an item + - tweak: Licking pref + - bugfix: Fixed IRV. + - bugfix: Runtime if nobody has a chaos pref set + - bugfix: IRV fixed... again + - bugfix: temporary flavor text can now be of reasonable length + - balance: Shooting the supermatter now adds to the supermatter's power. CO2 setups + beware! + - rscadd: Logging for renaming + Raiq & Linzolle: + - rscadd: Bone bow - Ash walkers crafting , bone arrows - Ash walkers crafting, + silk string used in bow crafting, harden arrows - Ash walkers crafting, ash + walker only crafting book, basic pipe bow, and bow & arrow selling. Quivers + for ash walkers as well, just to hold some arrows well out on the hunt! + Seris02: + - tweak: tweaked the way the SM works + - rscadd: custom reagent pie smite + - rscadd: hijack implant + - code_imp: changed mentions of the issilion proc to hasSiliconAccessInArea based + on what the proc is used for + - rscadd: recipe for mammal mutation toxin + - rscadd: polychromic winter coat + - rscadd: thief's gloves + - rscadd: crushing magboots + - bugfix: golden plastitanium toolbox being actually plastitanuium + - bugfix: character slot amount + - balance: rebalanced rising bass + - bugfix: string highlighting whitespace + - bugfix: glitch with PKA + - bugfix: meteor hallucinations (again) + - rscadd: Added naked hallucination + - rscadd: crowbarring manifests off crates + - balance: makes RCDs cost a better amount + - bugfix: apc icons + - rscadd: rest hotkey + - rscadd: hsl instead of sum of rgb for spraycan lum check + - balance: bloodcrawl's cooldown + ShadeAware: + - rscadd: Craftable Switchblades, a weaker subtype of normal switchblades that can + be crafted using a Kitchen Knife, Modular Receiver, Rifle Stock and some Cable + Coil. Requires a welder to complete. + - bugfix: You can now actually craft Switchblades. + - bugfix: Switchblades no longer regain their old Makeshift sprite after retracting + if you've made them fancy with Silver. + - rscadd: 'The Captain''s Wardrobe, a special one-of-a-kind and ID-locked wardrobe + for the Captain that holds all of their snowflakey gear. Remove: Snowflake gear + from the Captain''s locker, since now it has its own vendor.' + Tlaltecuhtli, ported by Hatterhat: + - balance: Ripley, Firefighter, Odysseus and H.O.N.K. mechs now also use scanning + modules and capacitors on construction. This means that they also gain reduced + power consumption and EMP protection from higher-tier stock parts. + Trilbyspaceclone: + - bugfix: Vault hallway door being all access + - server: Updates change logs + - rscadd: Crafts are now made of plasteel and can be made with 5 sheets + - rscadd: Takes away NT's connections to the Aliens that run the Syndicats + - rscadd: Carps have evolved to take more damage + - rscadd: restock crates for each vender + - rscadd: restock units for all station venders + - bugfix: Sec-vender missing icon + - bugfix: 'Box station captain office issues maping: Gulag on box can now be accessed' + - rscadd: Alien stools and chairs + - tweak: Bone armor/Dagger are now crafting from bones rather then crafting menu + - rscadd: Firing pins that only works when not on station + - rscadd: Medical locked crates + - balance: Russian gear crates have less gear in some cases but all will cost more + - bugfix: Medical locked crates that were not locked + - spellcheck: Crates that were out of date are corrected + - balance: Heads of staff have been better screened by NT before being promoted + - balance: The suit full of spiders also known as a ninja now is a tactical turtleneck + - balance: The Wiznerds now dont have suits set to max + - tweak: Meat wheat no longer has blood + - bugfix: Flat guns can no longer be suppressed + - tweak: replaced stickmans .45 caliber with 10mm, for consistency. + - tweak: Meatwheat and Oats now have rarity + - balance: Oats now have at lest 50% more flour in them + - balance: BDM now uses a PKA rather then a normal KA + - tweak: Gang tower shield is no longer transparent + - tweak: Cosmic winter coat now glows like the bedsheet, and holds normal winter + coat gear + - server: Express console is now logging what it buys, like the normal console should + - bugfix: Crabs are now made of crab meat. + - bugfix: AIs now understand the old ways of drunken dwarfs + - balance: Removes some armored Russian hats from box station round start + - bugfix: Doner items spawning + - balance: Engi/Sec Trek suit no longer has 10% melee protection + - bugfix: IPC hearts are now made of robomeat and roboblood thats emp proof. Heals + and is all and all just like an normal heart + - imageadd: All robotic organs now have an animation. + - imageadd: IPC's now organs now look like robotic ones, even tho thats not the + case game wise + - imageadd: Added a new bee themed bar sign + - imageadd: Makes plywood chair not look as bad. + - bugfix: corndog sprite being miss-spelled + - bugfix: Ash from land of lava now is useable for sandstone + - bugfix: Peach cake slices are no long made by mimes + Tupinambis: + - tweak: the portion of laws that require harm prevention by silicons has been removed. + - server: silicon_laws.txt config file is required to be modified for full implementation. + - bugfix: masks no longer improperly stick out of helmets when they should be hidden. + - bugfix: Status Displays should now update correctly. + - balance: stunbatons now take 4 hits to inflict hard crit, up from 3. + - balance: stunbatons no longer disarm targets. + Yakumo Chen: + - rscadd: Rings for your fingers! + - rscadd: New cargo crates and loadout options to bling your rings! + YakumoChen: + - tweak: Observe is back in the OOC tab + - imageadd: Rings look nicer. Sprites used from RP. + - imageadd: Ring on-hands. Diamond rings sparkle! + - tweak: You can now propose using a diamond ring in your hand. + - tweak: Legion skulls behave like bees!!!! + Zellular: + - imageadd: Movement state for pupdozer and its decals + - tweak: Tweaked the movement state for the pupdozer's eyes + ancientpower: + - bugfix: Fixes an error in pH strips' feedback message. + - rscadd: Ported drink sliding from /vg/station. + - bugfix: Fixes color mismatching with the "genitals use skintone" preference. + - imageadd: Bunny ear style for humanoid species. + - tweak: Ghosts are now literate. + bunny232: + - tweak: Changes the simple animal sentience event from the xenomorph preference + to sentience potion preference. + coiax: + - rscadd: Admin and event only pair pinpointers! They come in a box of two, and + each pinpointer will always point at its corresponding pair. Aww. + deathride58: + - bugfix: Spacemen no longer run at lightspeed on local servers. + kappa-sama: + - bugfix: the plant dudes can actually make plant disks now + keronshb: + - rscadd: Added repairable turrets + - rscadd: Adds Tiny Fans to the pirate ship + - tweak: changes some reinforced windows to plastinanium pirate windows + - tweak: made the pirate shuttle + turrets bomb resistant + - tweak: made most pirate machines + consoles indestructible + - tweak: increased pirate turret health + - rscadd: Adds the CogChamp drink and Sprite + - rscadd: Added burn and knockback to stunhand during HALOS on cult. + - balance: Added burn and knockback to stunhand during HALOS on cult. + - bugfix: fixed accelerated regeneration nanites + - bugfix: fixed mechanical repair nanites + - bugfix: fixed bio reconstruction nanites + kevinz000: + - refactor: Custom snowflake plushies are now in config rather than code. + - balance: Abductor mindsnapping (aka abductee objectives) can now be "cured" with + brain surgery. + - rscadd: Shuttle hijacking has been completely reworked. Alt-click the shuttle + as a hijack-capable mind (so traitors, and especially traitors with hijack) + to begin or continue a hacking process. + - refactor: 'A good amount of the blood RGB rework was cleaned up/reverted, with + some notable gameplay changes including: Gibs and blood not having max blood + by default (no more easy rampages, cultists), infinite gib streaking, etc etc.' + - balance: meteor waves are now directional and announces the direction on the command + report. + - rscadd: CTF CLAYMORES + - balance: shoves buffed, now shoving into a wall twice rapidly will also disarm + their weapon. + - balance: traitor+bro gamemode minimum population set to 25 until there can be + more in depth configuration systems for gamemodes. + - bugfix: no more bluespace skittish locker diving, + - rscadd: moths now have unique laughs and can *chitter. + - tweak: nuke explosion is now full dev radius for anti lag purposes + - balance: Gangs can now only tag with a gang uplink bought spraycan. + - tweak: dueling pistol accesses have been changed to be more accessible. + - bugfix: mechs no longer have admin logs flooding into IC control console log viewing + - refactor: Guncode and energy guns have been refactored a bit. + - rscadd: You can now combat mode ight click on an energy gun to attempt to switch + firing modes. This only works on guns without right click functions overridden. + - balance: shoes can now fit magpistols again. + - balance: Projectiles now always hit chest if targeting chest, snipers have 100% + targeting zone accuracy. All other cases are unchanged. + - tweak: The lawyer's PDA cartridge has been rebranded to something more accurate + to its true nature. + - refactor: Refactored ghostreading/etc + - balance: Cyborgization will now de-gang people, even gangheads. + - bugfix: reactive repulse armor now has an item limit + - bugfix: beam rifle runtime fix during aiming_beam + - bugfix: 'fail2topic runtime fix: taking out an ip while incrementing index resulted + in accessing the next-next entry instead of the next and results in out of bound + errors.' + - rscadd: gravity gun repulse and chaos now work in all angles, rather than just + basic cardinals and diagonals. fun. + - balance: Public autolathes can no longer be hacked. + - bugfix: Energy weapons now once again have their lens in contents. + - bugfix: pais are no longer muted for literally a whole hour on emp. + - rscadd: auto profiler subsystem from tg + - bugfix: Brig cells now are more accurate by using timeofday instead of realtime + - bugfix: Cryo now actually transfers reagents at tier 4 on enter rather than every + 80 machine fire()-process()s regardless of if it was "reset" by open/close. + - rscadd: cmo now gets advanced surgery drapes that techweb-sync for advanced surgeries + without an operating console. + - bugfix: ctf claymores now actually spawn (and fit). + - bugfix: STOP_PROCESSING now removes from currentrun to prevent another process + cycle from happening where it shouldn't. + - balance: hand teleporters now require 30 deciseconds of still movement by the + user to dispel portals. there's a beam effect too. + - balance: Sort of a bugfix but cult blood magic and all guns now respect stamina + softcrit. + - balance: Organ healing rate doubled. Organ decay rate halved to match its define + (15 minutes for full decay, so at around 8-10 minutes it'll be really fucked). + - tweak: Storage now caches max screen size and only stores when being opened by + a non ghost, meaning ghosts will no longer distort living player screens when + viewing storage. + - balance: Stunbatons changed yet again. + - tweak: the game's built in autoclicker aka CanMobAutoclick no longer triggers + client/Click()'s anti clickspam guard. + - balance: pais can no longer bodyblock bullets + - balance: pai radio short changed to 3 minutes down from 5 + - balance: pais are no longer fulltile click opacity. + - refactor: vampire "immortal haste" has been reworked to be more reliable and consistent. + - tweak: hand teles use a less atrocious beam + necromanceranne: + - rscadd: Ebows now disarm people hit by them. + - rscadd: Ebows now do 60 stamina damage on hit. + - rscdel: Ebows no longer inflict drowsiness + - balance: Miniature ebows do 15 toxin damage, up from 8. + - balance: Ebows have considerably shorter knockdowns. + - balance: Ebows now make you slur rather than stutter. + - balance: Large ebows are now heavy and bulky. + - rscdel: You can no longer order spinfusors or their ammo from cargo. + - rscdel: Removed the formal security officer jacket from the secdrobe + - tweak: formal security jackets are now armor vests + - rscdel: Bullets causing bleed rates equal to unmitigated damage through all forms + of defense. + - balance: 'Reverted #9092, crew mecha no longer spawn with tracking beacons.' + - balance: '[Port] Mecha ballistics weapons now require ammo created from an Exosuit + Fabricator or the Security Protolathe, though they will start with a full magazine + and in most cases enough for one full reload. Reloading these weapons no longer + chunks your power cell. Clown (and mime) mecha equipment have not changed.' + - balance: '[Port] The SRM-8 Missile Launcher has been replaced with the BRM-6 Breaching + Missile Launcher in techwebs (Nukie Mauler remains equipped with the SRM-8).' + - balance: '[Port] Both Missile Launchers and the Clusterbang Launcher do not have + an ammo cache, and cannot be reloaded by the pilot. Once the initial loaded + ammo has been spent, you can use the appropriate ammo box to load the weapon + directly.' + - rscadd: '[Port] Utility mechs that have a clamp equipped can load ammo from their + own cargo hold into other mechs.' + - rscadd: '[Port] Nuke Ops can purchase spare ammo duffel bags for their mecha weapons, + should they run low.' + - bugfix: Literally unclickability with a cham projector + nemvar: + - code_imp: Slight changes the self-repair borg module. It no longer references + the borg that owns it. + - bugfix: Trash from food now gets generated at the location of the food item, instead + of in the hands of the eater. + - code_imp: Changed mob biotypes from lists to flags. + r4d6: + - rscadd: Added a dwarf language + - rscadd: Added more engines + - tweak: RPD subcategories and preview icons reorganized. + - rscadd: RPD now starts with painting turned off, hitting pipes with build and + no paint will target the turf underneath instead. Bye bye turf pixelhunting. + - config: Made dwarves into a roundstart races + - tweak: Meteor Timer back to 3-5 minutes + - bugfix: Mining no longer lead to spess + - rscadd: Added Plasteel Pickaxe + - rscadd: Added Titanium Pickaxe + - bugfix: fixed a missing tile + tralezab, bandit, Skoglol: + - rscadd: The mime's PDA messages are silent now! + - rscadd: 30 new emoji have been added. Mime buff, mime now OP. diff --git a/html/changelogs/archive/2020-03.yml b/html/changelogs/archive/2020-03.yml new file mode 100644 index 0000000000..6b9b3c92f5 --- /dev/null +++ b/html/changelogs/archive/2020-03.yml @@ -0,0 +1,466 @@ +2020-03-28: + Arreksuru and Detective Google: + - rscadd: new HUDpatches for medical, diagnostic, and mesons. + - rscadd: crafting and de-crafting recipes for new HUDpatches. + - bugfix: silly typo with "singlasses" in one of the crafting recipes for HUDglasses. + Arturlang: + - balance: Bloodsuckers can no longer get usable blood from blood tomatoes. + - bugfix: Fixed reagent container transfer amount cycling. + Bhijn: + - tweak: Clicking an open closet with harm intent no longer attempts to place your + currently held item inside, but rather attacks it. + Bhijn (original PR by Azarak, sprites by Discord user Smug Asshole Muhreen#5522): + - rscadd: Synths, the open source and free-as-in-freedom species by FA user vader-san, + have been ported from Skyrat. + - rscadd: Ported VOREStation's synthetic taursprites + - rscadd: Markings that don't match very well with your selected species are now + hidden from the markings list by default. You can still use these mismatched + markings to create horrendous sparkledog abominations by using the "Show mismatched + markings" button ingame. + - bugfix: Body markings who's iconstates don't match their name will now actually + render properly. + - code_imp: Limb base icons are no longer hardcoded, should_draw_citadel and should_draw_grayscale + have been removed in favor of the species-level `icon_limbs` var and the bodypart-level + `base_bp_icon` and `color_src` vars. Downstreams should no longer have to touch + bodypart rendering code a whole lot if they want to add custom species. Downstreams + that have already added species with digitigrade leg support will have to append + species IDs to the digitigrade leg sprites, but aside from that, the migration + process to this more modularity-friendly system should be fairly smooth. + BlackMajor: + - tweak: Adjusted the ash walker camp's storm proofing. + - rscadd: Added a tip about creating areas to the ash walker spawn text. + Bumtickley00: + - tweak: Iron sheets build the normal metal table again + Crystal9156: + - bugfix: Fixes Chocolate Jelly Donut icon + Dennok, ported by Hatterhat: + - bugfix: Lava rivers no longer burn into basalt. + - code_imp: The river generator can now specify baseturfs. + Detective-Google: + - bugfix: absurd dong sizes. + - bugfix: my dumb stupid paramedics + - balance: Medical no longer spawns with syringe guns, Medical now spawns with medidart + guns. + EmeraldSundisk: + - rscadd: Adds CogStation's shuttles to-be. + - rscadd: Adds the "NES Classic" escape shuttle. + - refactor: Accounts for the new shuttles. + Ghommie: + - tweak: Added a few cooldowns to chill nuclear bomb and communications console + security level change spam, as well as the emergency shuttle's authorization + announcements. + - bugfix: Fixed viruses not working on anthros and some others species. + - sounddel: Made the cogchamp mixing sound less annoying. + - rscdel: Removed makeshift switchblades. + - bugfix: pAIs, drones, monkys and lizards can be worn over the head again. + - bugfix: Fixed cargo passive point generation to not go into decimals. + - bugfix: Syndicate ninjas are slightly less friendly now. + - balance: Allowed blobbernauts to drag objects (but not mobs) again. + - bugfix: The examiner circuit now works better for mobs. + - tweak: Chances are monkeys won't end up gorillizing as quickly after being exposed + to a rad storm for a minute or so. + - bugfix: Vampire mesmerize doesn't permanently disable combat mode. + - bugfix: The flying speed slowdown while hurt now actually affects flying mobs + and not floating ones. + - bugfix: Joining in as a positronic brain won't break the spawner menu anymore. + - bugfix: Fixed dynamic voting. + - bugfix: The autotransfer subsystem is slightly more modulable now. + - imageadd: Resprited some sprite_accessory icon states. + Ghommie (plus a fix originally done by Skogol): + - bugfix: Drinks dispensers now only show the container they are holding. + - bugfix: Ghost cafe patrons are warded against a few more events now. + - bugfix: Fixed RnD machineries UI displaying designs' required reagents' typepaths + instead of names. + Hatterhat: + - bugfix: Red and blue boxes are now actually red or blue. + - rscadd: Beegions! Like Legions, but with actual bees. As in, the bees from the + holodeck sim with the randomly-generated toxic bees. + - rscdel: Mining cyborgs are no longer physically capable of claiming points nor + wielding a premium accelerator. + - tweak: Arrow crafting has been finagled with, preventing fire-hardened arrows + from being fire-hardened repeatedly. Or something. + - bugfix: Space hermits (those quirky fellas stuck in a rock with carp surrounding + them) now have gravity! But they lost their perpetual generators. + - balance: Space hermits now have to mine for their research tech (golem vendor + board, ORM board). They have slightly less bad parts, though. And better(?) + rocks. + InnocentFire made the sprites all thanks to them!: + - imageadd: All bows now have inhand sprites once again + KathrinBailey: + - rscadd: Nine new posters! + - rscadd: Shower curtains can be crafted. + - rscadd: New sofas! + - rscadd: Green and purple comfy chairs to the crafting menu to fit green and purple + carpets. + - bugfix: Shower curtains now let you see through them once open, and don't once + closed. + Kraseo: + - balance: If you have the powersink objective, you will now receive a free beacon. + - rscadd: Lavaland flora have more traits now, to encourage harvesting and sending + these off to the botanists. + - bugfix: Napalm will now properly remove weeds from a tray if the plant in it has + the fireproof gene. + - balance: Gangs no longer get soporific rounds for their sniper rifles. + - rscadd: Syndicate Contracts. Use the new contract uplink to select a contract, + and bring the assigned target dead or alive to the designated drop off. Call + for the extraction pod and send them off for your TC payment, with much higher + rewards for keeping them alive. A high risk, high reward choice for a traitor + who wants a real challenge. + - rscadd: New 20 TC contract kit - supplies you with your contractor loadout and + uplink. + - rscadd: Targets successfully extracted will be held for ransom by the Syndicate + after their use to them is fulfilled. Central command covers the cost, but they'll + be taking a cut out of station funds to offset their loss... + - rscadd: Adds a third random item, as well as a small guide on using the contract + kit. Also added new possible items that can appear. + - tweak: Supplied space suit in the contract kit is now an improved variant on the + normal Syndicate version. + - balance: TC payouts adjusted to be a bit more fair to the contractor. Total payout + can never be below a certain threshold. + - bugfix: Broken dropoff locations work again, and general bugfixes. + - rscadd: Contract kit comes with a contractor baton - a unique, lightly electrified + weapon to help complete your contracts. + - tweak: Finalized payment system for contracts; much more balanced for contractors. + No more extremely low paying contract sets. + - tweak: Generated contracts will all have unique targets, no more duplicates. + - tweak: Extraction droppod explosion has been removed, it'll only damage the tile + it lands on. + - bugfix: Extraction pods get sent to the jail immediately again. + - refactor: Refactored classic_baton code. + - rscadd: Contractor Hub. A unique store for contractors to buy items with Contractor + Rep, with two Rep being given when completing a contract. + - rscadd: Contractor pinpointer, available through the Hub. A very inaccurate pinpointer + that ignores suit sensors. + - rscadd: Call reinforcements, available through the Hub. Limited to a one-time + buy for a contractor, you can purchase an agent to be sent down to help in your + mission. Role is polled to ghosts. + - rscadd: Blackout, available through the Hub. Disable station power for a small + duration - an expensive, but powerful option of getting into secure areas. + - rscadd: Fulton extraction, available through the Hub. Purchase a fulton extraction + kit to help move your targets across the station for those difficult dropoffs. + - tweak: Assigning yourself to another tablet will give you another contract set. + - rscadd: Contractors can now reroll their contracts a small number of times. + - rscadd: Brand new sprites! A redesign of the specialist space suit, and the kit's + own unique tablet. Done by Mey Ha Zah. + - tweak: Displays contract target jobs under their name. + - tweak: New locations, such as maintenance, are now possible dropoff locations. + - balance: Contractor kit pop cap reduced from 20 to 15. + - balance: You can no longer get haunted 8balls from contractor kits. + - bugfix: Pods and shuttles should no longer be valid dropoff locations. + - bugfix: Contract tablets will no longer break when one of your contracts is deleted + from the world. + - bugfix: Baton inhands for the right hand now shows the right direction. + - bugfix: Mice don't chew on wires anymore while they're on your person. + - bugfix: Bloodsucker heart theft objective now completes successfully. + - tweak: Blacklists turret protected areas, the toxins test range, asteroid ruins, + and solars from being valid dropoff locations for contracts. + Linzolle: + - tweak: pacifists can no longer meatspike living things + - bugfix: flypeople being unable to gain nutrition from eating vomit + - bugfix: targetting mouth on help intent now properly nose boops + - tweak: cmo hypokit now holds the same amount of items as normal kits + Moonlit Protector: + - rscadd: Introducing the 'Heroic Beacon', standing vigil over service the curator + can assume one three different historic heroes, each determining their equipment + and emergent playstyle to suit the player; a beacon can be found in the curator's + backpack upon spawning + - rscadd: Become the Braveheart, a fierce scottish warrior armed with a ceremonial + claymore, spraycan, kilt and a disregard for underwear with the scottish themed + hero pack. + - rscadd: A unique mention is the "First man on the Moon" heroic pack, with a two + piece space worthy suit, air tank & a GPS for recreating a key spessfaring moment + in history. + - tweak: The Curadrobe has been stripped & refilled full of helpful library supplies, + including varieties of pens and glasses including the jamjar's. + - tweak: The curator's explorer equipment & whip has been moved into the 'Courageous + Tomb Raider' heroic pack; removed from the backpack & the Curavend respectively. + MrJWhit: + - tweak: Added minor station things + - balance: re balanced r-walls + - tweak: Evens both sides of the gas containers TEG with reinforced windows + - tweak: Removed egun in every head locker, replaces RPD with air pump in science, + fixes a computer in sec, moves hand teleporter, and removes decals under lockers. + MrPerson: + - rscadd: Solar panels will visually rotate a lot more smoothly instead of being + locked to only 8 directions. + - rscadd: Timed solar tracking is in degrees per minute. You're still not gonna + use it though. + Naksu: + - rscadd: Time based free rerolls + - refactor: Refactored Blobs + - balance: Blob rerolls now give the blob 4 different options to choose from, rather + than forcing a single random one. + NecromancerAnne and goldnharl: + - imageadd: Sprite cleanups and animations for energy guns. + NecromancerAnne and zawo and zeroisthebiggay and carlarctg: + - rscadd: The Infiltrator Bundle, an armor kit for 3TC. Murder people in style! + - rscadd: Some pajamas for nukies to get plenty of bed rest. + - rscadd: halved firefight carry delay with latex or nitrile gloves + - tweak: headset upgrade is cheaper + Owai-Seek: + - rscadd: Butter Bear + - rscadd: Crab Burger, Bisque, Crab Rangoon, French Onion Soup, Empowered Burger, + Chicken Nugget box. + - tweak: +++ Spider Eggs to Exotic Meat crate. --- Bacon from Exotic Meat crate. + - tweak: Tweaked Crab Recipes + - imageadd: Butter Bear aka Terrygold + - balance: Food Crafting is now 5 deciseconds instead of 30. + Putnam: + - tweak: Swarmers, portal storm, wormholes are now controlled by dynamic. + - tweak: Dynamic-controlled events can now have a minimum start time. + - balance: Threatening meteors are more common (though still have pretty strict + requirements) + - balance: Different storytellers now balance around different expected players-per-antag; + default was 5, now intrigue/story/random have 7 and calm has 10. + - rscadd: Clown ops is now available as a roundstart antag in dynamic. + - balance: Sentient disease and revenant are now in the event pool rather than the + antag pool (with the logic that they're both completely useless and unfun to + play if people are actually playing against them). + - rscadd: A new formulation of extended was added to the storytellers; no antags, + but still spending threat on events. + - bugfix: Fixed a runtime in dynamic due to my misunderstanding pickweightAllowZero + - rscdel: Made conversion storyteller 0-weight-by-default. + Putnam3145: + - tweak: Salbutamol causes jittering now. + - bugfix: Made lickable pref save + - rscadd: 'Traitor classes for traitors: a new way for traitors to have objectives + assigned.' + - bugfix: Actually made things work as intended. + - code_imp: Removed a redundant turf melting check from the supermatter. + - rscdel: Removed "realistic tcomms lag" + - rscdel: Removed some particularly bad flavor objectives. + - balance: Power sink objective is 10x as easy to get + - bugfix: Processing objectives now properly stop once won + - rscdel: MKUltra no longer explodes into lovegas when it fermi explodes, instead + causing a regular ol' fireball. + - tweak: Eigenstasium OD flavor text less restrictive + - bugfix: Dynamic voting should work absent of a config. + - tweak: Autotransfer vote now requires actual transfer votes to transfer. + - bugfix: More dynamic fixes + - bugfix: Server-run votes aren't subject to vote cooldown + - rscadd: Mass hallucination can better be admemed + - tweak: Waffle co objective rewritten to make more clear it's not a murderbone + objective + - rscadd: CTF spawns, random animals and possessed blades can now be pinged for + ghost roles. + - bugfix: A bunch of polls now work with ghost role eligible non-observers. + - bugfix: Removes superfluous line in supermatter processing. + - code_imp: Power sink objective processing now makes sense. + Qustinnus/floyd, Ghommie: + - bugfix: To save costs, Nanotrasen has removed the emergency battery ejection systems + in modular computers. We realized saving the batteries isn't really important. + - bugfix: You can squash spiderlings with your bare hands now. + - bugfix: Being deafened properly stops jukebox music from playing. + - bugfix: admin multicam toggles no longer tells everyone but only admins and AIs + Ragolution: + - rscadd: All winter coats and hoods might be different if slightly from one a other. + - tweak: Adjusted Bartender's Drink Flinging print message to not include name of + target turf and save immersion. + Seris02: + - rscadd: tg genetics + - balance: illegal technology + - balance: rebalanced rising bass's buttom actions from repulse to side kick + - bugfix: projectiles and rising bass and items and rising bass + - bugfix: a very specific fix with tails and wagging + - rscadd: duffel bags of holding + - bugfix: quirk blacklist fixing + - bugfix: robotics console button swapping + - bugfix: fixed thieving gloves not pickpocketing fast + - rscadd: mentor de/rementor button + - bugfix: mentor !msg + - balance: bloodsuckers being unable to accept genes + - balance: removes xray from the gene pool + Skoglol: + - bugfix: Fixed gibber exploit. + Timberpoes: + - bugfix: 'Shuttle countdowns once again read like "01:05" instead of "01: 5".' + Trilbyspaceclone: + - rscadd: Three new arm implants, shield for sec, janitor and service + - rscadd: Two new legion drop. Assistant and Bee-Activist + - rscadd: Three new posters have been issued to the printing press + - rscadd: Well contruction, grubs to ash walker home, more seeds for ash walkers. + - rscadd: Wooden buckets can be made from 2 planks of wood, Tower caps also can + be used on a fire to make coal + - tweak: Makes all ashwalker round start seeds 5 yield and 50 harvest so that they + can get good crops in rather then failing after 1 harvest + - bugfix: arrow crafting has been fixed + - balance: Blobs now can store 250 points. + - spellcheck: Alien bar stool is no longer bronze + - server: 28 days log changlogs have been added well 56+ day old changlogs have + been removed + - balance: Added sunglasses that are able to be huds AND prescription + - rscadd: Prescription sunglasses and crafting of each new type for - Diagnostic, + Med and Sec + - rscadd: Diagnostic Sunglasses + - bugfix: Blackists Prescription HUDs from sunglasses crafting + - tweak: Cotton/Durathread now stack to 80 bundles + - rscadd: Medical hardsuits now have a Medi-Hud built into its helm + - rscdel: Removed old unused Techweb Node selling + - imageadd: Corrects snowcones names and a pixle. Corrects Space Wind snowcone as + well + - bugfix: Arrow crafting has been fixed... Again... + - rscadd: Soidifaction of and uranium can be done as well as making new bluespace + shards + - balance: Xeno and Fountain Hall will no longer spawn more then once + - tweak: Makes the game want to spawn in more then one tumor maybe + - tweak: Number of paper work in the crate "freelance paperwork" is half + - code_imp: A few cases were something their is unneeded copy past replaced with + many 1 in spawns + - rscadd: Potass Iodide has been fitted into standered borgs as well as medical + ones. Upgraded hypos now have Prussian Blue as well. + - tweak: Syndi borgs Potass Iodide has been swapped for Prussian Blue + - bugfix: No longer can you get the The End and Russian Flask without being the + donator + - balance: Pipes are small now + - bugfix: Edaggers now enbed as intended + - rscadd: The sleeper agents can be outfitted with some larger then normal sunglasses + for 1TC in Badass category + - rscadd: The Syndi Medical borg has been outfitted with the newest and latest ~~Stolen~~ + MediCo Gear on the market + - rscadd: Ninjas may be asked to steal the CMO's smart drapes + - tweak: Hyper Cell steal goal is upgraded to a bluespace cell, as well as the BoH + goal now wants a type of BoH rather then the normal default one. + - rscadd: Gutlunches have gotten teeth now and will eat legs, arms, and organs! + - Tho are picky and will not eat the brain just laying about! + Useroth: + - bugfix: contractor tablets spawned with invalid icon_state + Xantholne: + - rscadd: Bumbles is now actually in every station's hydroponics. + - bugfix: Bumbles will now actually rest, sit up, and buzz + YakumoChen: + - imageadd: Nekomata (double cat) tails. + - imageadd: 2CAT LMAO + - bugfix: Mining base looks more natural where it's spawned. + - server: Templates Headers will now correctly use the Citadel Official Wiki Link + Yenwodyah: + - bugfix: Bear traps and bolas apply slowdown correctly again + - bugfix: Recycler doesn't delete people in mechs, cardboard boxes, spells, etc. + anymore. + actioninja, ninjanomnom: + - tweak: Being fat is no longer lessened by flying. + - bugfix: The slowdown from grabbing someone no longer applies when you're floating. + bunny232: + - rscadd: Box bar now has a lightswitch. + - bugfix: fixes several piping issues around box station + - bugfix: moved a scrubber and vent down 5 pixels + - rscadd: Box station captain office now has a standard issue renault + - bugfix: Box bridge now actually has the air distro connected + dapnee: + - rscadd: Lambdastation and it's accompanying files + - rscadd: Robotic's APC, a few missing buttons (bridge shutters and crematorium), + paramedic has spawn locations now, two rapid cable deployers to engineering + - tweak: Renamed some doors and edited engineering to be a bit more open in one + spot + - bugfix: a few APCs with bad area tags, access on maintenance doors fixed, engine + APC is now connected to the grid instead of power created by the engine + - rscdel: the two syringe guns in medical were removed + - rscadd: couple gas masks around atmos + - bugfix: direction on turbine plasma pressure tank, cloning actually has a cloning + console now + floyd: + - bugfix: Everything made from glass in the game has a little more tegridy and doesnt + break from a single punch. + kappa-sama: + - rscdel: removed laptops giving slowdown when open + - balance: removed (mostly aesthetic) requirement to become hulk + - bugfix: changed add to remove on crit + - rscadd: a super combat shotgun that loads and fires 2 shells at a time + - balance: replaces bubblegum's blood contract drop with the super shotgun + - balance: 60 seconds instead of 120 for firebreath + keronshb: + - balance: blobs now receive a 50% cost refund on attacks that don't spread + - balance: reflector blobs are considerably tougher + - bugfix: fixed an integrity + - bugfix: attempting to turn a damaged strong blob into a reflector blob now refunds + points + - bugfix: also fixes blob node camera jump (from another PR) + kevinz000: + - code_imp: Mobility flags are here. Fixed some edge cases with xeno hardstuns and + similar stuff like warden's shotgun hardstuns and yeah. + - rscadd: Security now has riot quarterstaves in their lethal shotgun locker. + - tweak: Pushing is no longer free space movement. + - tweak: You can now right click to point the tip of some sharp tipped weapons at + people. + - bugfix: compact defibs have 10k cells again + - tweak: music max characters per line is now 150 instead of 50. + - bugfix: storage no longer closes while being dragged + - balance: disabler taser alt fire shots are faster and have a 14 tile range now + - balance: HoS taser now only applies tased effect for 1 second and warden's pump + action stun blaster no longer applies it at all. + - balance: Nanite adrenals have been nerfed. + - balance: Ninja stungloves nerfed 49 stamina to 25 (so they're basically just better + than stunbatons). + - tweak: Batons now also trigger disarm behavior in disarm intent and not just on + right click. + - refactor: combat mode/sprint/resisting lying down/attempting to crawl under all + refactored, added combat/sprint mode lockouts, being locked out of combat mode + no longer disables it and allows right click interactions etc etc + - bugfix: hands free actions no longer check mobility and only consciousness. + - rscadd: Minimaps, accessible via a button on OOC. + - bugfix: unnecessary blindness post-unconsciouss has been fixed with a hack that's + almost as garbage as the code that caused it in the first place. + - bugfix: synthflesh and rezadone now take total amounts of both applied and existing + reagents rather than only existing and only applied respectively. + - balance: reverts bubblegum bloodling swarming. + - balance: Beam rifles shot count 10 --> 5 and can no longer pierce. Also renders + properly for reflections against blobs and some other things. + - bugfix: being stunned no longer stops an ai from undeploying from a shell. + - bugfix: beam rifles are less terrible code + - code_imp: slowdown on items should now be set by set_slowdown(). + - bugfix: hypereutactic blades properly slow down their wielders when being used + and vv-editing an item's slowdown will once again properly update someone's + slowdown to take the new value into account. + - balance: stunprods knockdown again. + monster860: + - tweak: You can now moan in soft crit + - rscadd: Use Ctrl-Shift-direction key to shift your characters position. Use for + ERP. + necromanceranne: + - rscadd: Ports New Sleeping Carp + - refactor: Ports the martial arts refactors, which includes things like moving + martial into the martial subfolder and renaming it _martial, and cleans up human_defense + rising bass/sleeping carp exclusive code. + - balance: Particle Defender is now a much more sane weapon. + - balance: Tasers are no longer ignoring stimulants. + - bugfix: Blood beam can't create harvesters out of mech pilots. + - code_imp: Some minor fixes to fakedeath and a tg fix port. + - bugfix: Bleeding out all your blood from getting love tapped by a toolbox. + - bugfix: Diagnostic HUDSunglasses are better than ever! + - bugfix: Sprite fixes I hope + - balance: You can no longer acquire stun bullets in the .45 calibre. You can get + the 30 damage version out of the autolathe instead. + - balance: KITCHEN GUN (TM) is a lot stronger. Cleaning bullets are a whole 40 damage! + - bugfix: Fixed turrets not allowing their guns to be recovered. + - balance: Altered the plastitanium rapier from a perfect AP but weaker esword equivalent + to a more unique sleep inducing melee weapon. + - rscadd: Touched up all the relevant sprites. + - balance: Nightvision goggles are nerfed all-round. Flashes have actual use against + people using nightvision, as do flashbangs. + - balance: Syndicate nuclear agents get to live peacefully knowing their eyes are + well protected by their special night vision goggles. Spider clan also get these + goggles. + raspyosu: + - rscadd: some flavor text for lunge, cloak + - tweak: mesmerize, cloak functionality/requirements + - balance: mesmerize, lunge, cloak + - soundadd: lunge telegraph sound + - spellcheck: mesmerized status icon flavor text + - bugfix: cloak sometimes not restoring initial move intent + - tweak: mesmerize (line of sight checking system and remove progress bar) + - balance: 'nerf: lunge, mesmerize' + spookydonut: + - code_imp: adds selective duplicate component mode + wesoda25: + - code_imp: You no longer hit fermenting barrels when taking reagents from them + zeroisthebiggay: + - rscadd: kilo shuttle less bad + - rscadd: tauric contractor space suits + - tweak: ghost hud and nv defaults on + - bugfix: syndicate elite hardsuit helmet doesnt hide masks anymore + - balance: syndicate contractor helmets are no longer secretly lead + - rscadd: Space Fashion has discovered a new way to wear bandannas. With some simple + minor adjustments and ties, bandannas can be made into fashionable neckerchiefs! + - rscadd: Box Station has gotten a brand new brig. Go and check it out and discover + all the quirky little soulbits. + - bugfix: box brig miscellaneous issues + - bugfix: box station hos office diff --git a/html/changelogs/archive/2020-04.yml b/html/changelogs/archive/2020-04.yml new file mode 100644 index 0000000000..10525cd200 --- /dev/null +++ b/html/changelogs/archive/2020-04.yml @@ -0,0 +1,327 @@ +2020-04-15: + Arturlang: + - rscadd: Adds garlic, a mutation of onions + - rscadd: You can now make garlic necklaces. + - tweak: Tweaked hunger to be more the same as blood level for bloodsuckers + - tweak: Bloodsuckers no longer get zero healing from regenerative cores, the core + now heals their wounds but not their blood. + - balance: Bloodsucker heal is now based a lot more on blood level. + - bugfix: You can no longer be effectively immortal when fully auged as a bloodsucker. + - bugfix: Regenerative cores will regain their old names when they are renewed, + no more working decayed cores. + - code_imp: Removes a lot of unnecesiry clutter of comments and tries to make the + vars more consistent for bloodsucker code. + - code_imp: Made the regenerative core use one proc instead of copypasta + Auris456852: + - rscadd: Added printer sound for admins that plays when someone messages Centcomm + or the Syndicate. Just like RP! + Bhijn: + - admin: The traitor panel now actually shows a list of contractor targets. + - server: Fail2Topic now supports Linux. Do beware that this requires some sysop + experience to properly set up! + - config: Fail2Topic is now disabled by default, and the out-of-the-box config files + have been updated to be a little more detailed. + - rscadd: Added a lfwb-inspired orbiting pixel + flashing outline animation to the + sprint and combat mode buttons. This can be toggled via the preferences menu, + and is completely independent from all HUD themes. + BuffEngineering: + - bugfix: You may no longer summon plasteel from the door dimension. + - tweak: High security airlocks are now 33% more materially efficient! + DeltaFire15: + - balance: clockie vanguard now quickly regenerates stam while active (as its description + always told you,) + Detective-Google: + - balance: Shotguns are now slower and require two hands to fire. + Ghommie: + - bugfix: mobs with antag statuses such as wizard, ert and nuke ops get their flavor + text removed now. + - bugfix: Fixed megafauna mobs, goliaths and "anchored" AIs being stuffable into + closets. + - bugfix: After years of visual agony, the Curse of The Floating Disembodied Phallus + has come to an end. + - rscadd: Underwear now fulfills its purpose. + - rscadd: Privates visibility preferences. + - refactor: refactored polychromic clothing into an element. + - tweak: Blacklists unsynthetizable reagents from botany bees honey production. + - bugfix: Fixed toilet cistern loot spawning on the floor. + - tweak: The megafauna's hitbox doesn't include 0 alpha sections anymore. + - bugfix: Wizard robes & co work again now. + - bugfix: Fixed some spell casting message spam. + - rscadd: Added M/F body preferences. + - bugfix: fixed yet another few airless issues with the space hermit ruin. + - bugfix: Intellectual property infringment is not cool. + - bugfix: Near-station nuclear explosions now display the on-station nuke explosion + cinematic, consistently with its clearance of the station level and its nuclear + victory / total annihilation ending status. + - balance: Nuclear bombs can't be anchored in space areas (not just turfs) anymore, + as a quick effortless way to discourage players from anchoring the device on + the edge of the map. + - bugfix: Fixed a whacky miniature cell duping issue. + - bugfix: Liver failure is back! + - tweak: standarized a few (prefs off) side effects from enlargment chems on livers + to do organ damage instead without the blood volume whackiness. + - tweak: High liver damage now slows mobs down. + - bugfix: Fixing an issue with the split personality removing the original owner + from the round if the body died while the stranger was in control. + - bugfix: fixed a few floaty sprite accessories. + - bugfix: Fixed a few mutations not working correctly. + - bugfix: Fixed the phantom thief component, again. + - refactor: Made votes obfuscation settings more robust. + - admin: Also included them in custom votes. + - tweak: The map rotation vote will only hide ongoing votes now, not the results. + - balance: The crusher's vortex talisman trophy now has a cooldown between each + spawned wall. + - refactor: Backend body size preferences. + - bugfix: Infiltrator's boots don't stop slips and "space wind" through the power + of runtime errors anymore, and properly silence the user's footsteps now. + - tweak: Chaplains are now inelegible for bloodsuckers. + - bugfix: Fixed crafting hud icon overlapping the second pocket on 1:1 screen mode. + - code_imp: Removed some dead flightsuit code leftovers. + - rscadd: Reenabled the swarmers event. Also blacklisted another dozen other machineries + and structures that may be critical to the shift or station integrity from swarmers' + HUNGER for materials. + - bugfix: Fixed find_safe_turfs() searching for turfs with concentration of oxygen + lower than 16 rather higher. + KathrinBailey: + - rscadd: Radiation shuttesr to all supermatters. + - rscadd: Windowed shutters to armouries where relevant. + - rscadd: New posters are now on the map in relevant locations. + - bugfix: Windowed shutter now has glass, the door closing proc sees this and no + longer changes opacity. + - bugfix: Accidental HoochMaster removal in the bar. + - bugfix: Spawning looking at the supermatter with no mesons on Meta. + - bugfix: Missing disposal pipe outside HoP office. + - bugfix: Sofas were never adjusted when the pool was added. + - rscadd: New shutter sprites + - rscadd: Reinforced Shutter + - rscadd: Radiation Shutter + - rscadd: Window Shutter + - tweak: Shutters not being blast doors functionally. + - balance: Shutter armour block and health. + Kraseo: + - balance: Sneaksuit now costs 5 TC rather than 3. + - bugfix: You can break out of neckgrabs once more. + Owai-Seek: + - rscadd: Port Pina Colada, Painkiller, Moscow Mule, Hivemind Eraser, Moana Lou + Drinks + - rscadd: Gunfire, Hellfire, Sins Delight, Strawberry Daiquiri, Miami Vice, Malibu + Sunset, Lizz Fizz, Hotline Miami + - rscadd: Strawberry and Pineapple Juice + - rscadd: Salami Slices + - tweak: Soda Dispenser Juices + - tweak: Reorganize Vendor Objects (Bowls, Glasses, Shot Glasses) + - tweak: Strawberry Milk and Tea actually use strawberry Juice. + - tweak: Lizards can eat egg wraps. Moved Egg Wraps to Misc + PersianXerxes: + - rscadd: 'TGUI Next UIs for: chem heaters, chem masters, chem dispensers, and sleepers' + - code_imp: Reworked Chem Master code + Putnam3145: + - rscdel: No more station integrity goal + - tweak: Upload-hacked-law goal only picksif there's an AI to upload to + - rscadd: A new, much more barebones holding facility for contractors. + - rscdel: Energy nets are gone. + - tweak: Various ghost roles are now easier to ghost as. + - tweak: The candles in the dojo no longer make the place hotter and hotter over + time. + - rscdel: Nymphomania removed + - code_imp: Exhibitionism ignored by preferences now, since it was also removed + - code_imp: Quirk migration now does an admin log instead of a stack trace + - bugfix: Roundstart rulesets now roll properly. + - config: Added configs for various antag threat levels. + - bugfix: Fixed a runtime in threat calculation. + - tweak: Fixed up some misleading texts. + - tweak: 'Dynamic reworked to be more "storyteller-like": threat is now how threatened + the station is right now and threat level is how much the mode wants the station + to be threatened.' + - tweak: Random storyteller is now truly random. + - tweak: Story storyteller now gives a nice rising-action-climax-falling action + curve for threat level. + - tweak: '"Chaotic" storyteller now simply ramps up threat level as round goes on.' + - rscadd: '"Classic" storyteller, basically doing what "random" did before.' + - rscadd: Latejoin changelings for dynamic + - bugfix: Average threat calculation works now + - bugfix: Contamination is back. + Seris02: + - balance: stops hijackers from being able to remotely blow up borgs + - rscadd: wall walking boots + - bugfix: made color picking for character appearance show the colors when you pick + them + - tweak: the sergal markings + Trilbyspaceclone: + - rscadd: Cooks aided by Clowns have came out with and new healthy Salad - Caesar + Salad. Just dont eat the knife... + - rscadd: Ports over TG's Mortars and Pestles. + - balance: Water, Holywater and Unholywater will now now quickly purge itself if + you have 151u in your system + - rscadd: Most crate types can now be made, some costing more do to function over + fashion + - rscadd: Medical Mechs syringe gun now knows many more life saving chems, like + Insulin, Dexalin, Prussian Blue, Kelotane and Bicaridine + - balance: torches take less staminda to use. + - balance: Glowsticks dont last as long + - balance: Penlights are better at being lights + - balance: Torches are brighter then before - Indian Johns want to be on lava land + rejoy! + - balance: Eye lights have 30% less light coming out of them. + - spellcheck: Spec Ops crate no longer talks about a "Null Crate" what ever that + is + - server: Changlogs are updateded once again as of the 28th of March on year 2020 + - balance: White Ships, Telerelays and a defunk mining post are now always going + to spawn. + - spellcheck: Corrects a few desc on station side ruins + Xantholne: + - bugfix: bumbles will stop sleeping so much + actioninja: + - rscadd: Washing machines now support arbitrary dye color + - rscadd: Washing machines now dye nearly every item. + - refactor: lots of backend changes to clothing overlays, report any issues + - rscadd: Better glowing lights + actioninja (ported by Ghommie): + - refactor: repathed all under clothing, keep an eye out for errors. + bunny232: + - bugfix: Box secmos now is now longer connected to the scrubber loop + dapnee: + - rscadd: plant disk sorter in botany, bounty console for the rest of cargo, a missing + air alarm in the incinerator + - tweak: fixed a decal in front of security, moved an AIR alarm so it doesn't look + awful to ghosts/AI, asteroids don't delete air anymore, fixed more active turfs, + the buttons in the bridge "should" work now, HoP and cargo desks should be secure + now + - rscdel: quarters that found their way out of the quartermaster's back room + kappa-sama: + - rscdel: normies can no longer steal circuit codes + - balance: doubles the Stam damage of nonlethal krav stompers + - bugfix: no longer Krav Maga stomp people that are standing + - balance: no more 20pop requirement for noslips + keronshb: + - tweak: Reverts Mining Base RNG Placement + kevinz000: + - rscadd: Melee attacks now stagger people, preventing them from sprinting until + the (relatively short lived) effect runs out. Duration equation is [(1.5 + (w_class/7.5)) + * force]. + - balance: Fireman carrying now makes the person being carried unable to use items. + Piggybacking now slows down the person being ridden. In both cases, the person + riding will be dazed when forcefully dismounted, and dazed for a second if dismounting + from piggybacking + - bugfix: turfs properly initialize atom colors if they're colored. + - tweak: cloners now stabilize mutations while someone's cloning, meaning active + genes will not life tick. + - code_imp: datum/pipeline return_air stack trace now gives a reference so it's + actually marginally useful if caught in round. + - rscadd: Volumetric storage is here. + - rscadd: Traitor chaplains can now become neutered versions of cults. + - bugfix: beams should no longer go across the map and mess everything up if their + source or target isn't on a turf. + kiwedespars: + - rscadd: Added paper masks. + necromanceranne: + - bugfix: Fixed limb damage calc + - tweak: Stunslugs are now a mixed damage taser-like slug that will allow you to + apply a variety of damage while still being countered by tasers usual counters. + - balance: Mech scattershot guns are no longer oneshotting people into stamina crit. + - rscdel: 'Removed an number of cargo crate packs: Riot shotguns/standard shotguns, + double barreled shotguns, techshell crate, swat tasers, WT550 types (not rubber + or standard), traitor theft objective kits.' + - balance: HEALTH AND STAMINA DON'T STACK FOR PUTTING YOU INTO STAMINA CRIT. + - balance: YOUR FISTS ARE HELLA GODDAMN STRONG. + - balance: 'ACCEPT THE FELINIDS WARES, FOR SKOOMA HAS INCREDIBLE LETHAL PROPERTIES: + YOUR HANDS BECOME LIKE SWORDS.' + - balance: BOXERS CAN ONLY KNOCK OUT OTHER BOXERS BECAUSE THEY HAVE HONOR OR SOME + SHIT + - balance: INCREASED STAMINA DAMAGE TO LIMBS FROM 50% TO 75%. + - balance: Double-barreled shotguns and any child of such now can be used with off-hand + equipment. + - rscadd: Readds bioterror darts to the nuclear operative uplink for the legacy + price of 6tc! Has all new horrid reagents! + - balance: Scatterlaser is now in-line with buckshot. Nukies can't purchase scatterlaser + shot. + - rscdel: Null crates are no longer available in cargo! + - bugfix: Sleeping Carp and Rising Bass now dodge. Again. + - bugfix: Russian Revolver can no longer be exploited for a free 357. + - balance: Several guns now shoot exactly where you click regardless of movement + or turning. + timothyteakettle: + - rscadd: added beacon for cooks to choose an ingredient box, which replaces the + random box they used to receive + - rscadd: added a new sushi ingredients box + - rscadd: added more items to the wildcard box's possible contents + - rscadd: add new holodeck wrestling belt which lets you use moves only on those + also wearing it + - rscadd: add new holodeck map featuring the holodeck wrestling belt + - rscadd: new reagent 'Condensed Cooking Oil' + - tweak: list of chems that can go into fried non-food items was changed + zeroisthebiggay: + - rscadd: sneaksuit to contractor items + - tweak: sneaksuit is a bundle + - rscdel: intel potion and radio implant from contractor items + - rscadd: ghosts can now DNR + - balance: sneaksuit is not fireproof + - bugfix: insidious balaclava muzzlepsprite works + - rscadd: You can now choose your name and color as a holoparasite/guardian/holocarp! + - bugfix: fixes lings being able to get mechanical holoparasites +2020-04-16: + ForrestWick: + - tweak: changed a certain item to be called meatball, ended racism, thank you obama + Linzolle: + - tweak: remove any slurs, etc. to comply with GitHub's ToS +2020-04-19: + Anonymous: + - rscadd: Xenohybrids will now scream like xeno. + Arturlang: + - bugfix: You can no longer spam craft things using the crafting menu + Detective-Google: + - bugfix: uncorks some of Lambda's rooms. + Ghommie: + - rscadd: Custom skin tone preferences. + - tweak: Normalized box dorm lockers. Also removed a straight jacket found in the + same area. + Jake Park: + - bugfix: fixed path name for youtool vending + Putnam3145: + - bugfix: Objectives now clean theirselves up instead of leaving null entries in + lists everywhere. + Seris02: + - bugfix: stops magboots from not updating slowdowns + Trilbyspaceclone: + - rscadd: Maints have seen an uptick in left over types of welders, and tools. As + well as different types of masks + - rscadd: New type of 02 locker - Rng! It can have almost any type of gas/breath + mask and almost any type of o2 tank as well as even plasma men internals - Fancy! + - tweak: Tool lockers have 70% odds to have a spare random tool inside! + - rscadd: 12 new more drinks for most races! + - rscadd: New animations for mauna loa, and colour swap from red to blue for a Paramedic + Hardsuit helm + - tweak: Lowers cog champ ((the drink)) flare rate + - rscadd: Six more Sci based bounties have been posted at your local Cargo Bounty + Request console + - bugfix: Mimes have made catnip plants not become invisible. How helpful. + - rscadd: Honey Palm now distills into mead rather then wine + UristMcAstronaut: + - rscadd: Adds circuit analyzers to maps and to integrated circuit printer and circuitry + starter crate. + kappa-sama: + - balance: aranesp heals 10 instead of 18 stamina per tick + - rscdel: removed roundstart hyper earrape screams from xenohybrids + kevinz000: + - bugfix: you can no longer stun xenos + - balance: Contractor kits are now poplocked to 30 players. + - rscadd: Shield bashing has been added + necromanceranne: + - rscadd: You can now craft armwraps! + - balance: Pugilists disarm you more easily and are harder to disarm. They also + get a discount on disarm. + - balance: Pugilists only suffer a flat 10% chance to miss you. It's just like old + punches! Kinda. + - balance: Chaplain's armbands are a +2, up from a +1! + - balance: Martial artists spend stamina when they disarm. + - balance: Rising Bass had several moves shortened and made stronger. Has a disarm + override attack which does stamina damage and trips people on a disarm stun + punch. + - balance: CQC had it's disarm move altered to be a stronger version of Krav Maga's. + Dizzies and disarms on a disarm stun punch or just does some stamina damage + and brute damage. + - balance: Sleeping Carp can punch you to the floor on a harm stun punch. + - bugfix: Hugs of the Northstar are no longer nodrop. + - bugfix: Adding in some overrides and proper flag checks for martial arts. + - bugfix: Stun thresholding stops disarm spams at extremely high stamina loss. + - tweak: Ashen Arrows are actually called Ashen Arrows in the crafting menu. diff --git a/html/changelogs/archive/2020-06.yml b/html/changelogs/archive/2020-06.yml new file mode 100644 index 0000000000..e269906a84 --- /dev/null +++ b/html/changelogs/archive/2020-06.yml @@ -0,0 +1,353 @@ +2020-06-08: + DeltaFire15: + - bugfix: Delinging now properly removes their special role + - balance: Keycard auth devices now require two seperate IDs with sufficient access + to auth. + Linzolle: + - bugfix: shotguns no longer delete chambered shells while firing + kevinz000: + - rscadd: test + - rscdel: test + shellspeed1: + - rscadd: Internal tanks are now printable at the engineering lathe. + timothyteakettle: + - bugfix: newly created areas using blueprints now maintain the previous areas noteleport + value + - bugfix: kudzu seeds now actually spawn vines +2020-06-09: + Anonymous: + - rscadd: Added Orville-inspired clothing as a worthy alternative to Trek stuff. + - tweak: Adds chaplain role allowance to the TMP Service Uniform loadout. + - tweak: Adds paramedic in every medsci mentioned uniform loadout. + DeltaFire15: + - bugfix: Offstation AIs can once again only interact with their z-level + Ghommie: + - bugfix: Fixing IC material containers interaction with stacks, for real. + Trilbyspaceclone: + - tweak: Gasses like BZ and Masiam seem to just sell for less in cargo, markets + seem to change it seems + kevinz000: + - balance: plantpeople should stop dying in the halls now + - rscadd: Modifier-independent hotkey bindings have been added. +2020-06-10: + DeltaFire15: + - bugfix: Golems / simillar now inherit the neutered antag datum if the creator + is neutered. + Ghommie: + - bugfix: Fixing missing pill type buttons from the chem master UI. + Naksu: + - code_imp: Lighting corner updates are ever so slightly faster. + Putnam for helping me code the contamination clearing on people: + - rscadd: Lab made Zeolites have been remade anew and more affective now that they + refined the best possable way to mix and make a supper Zeolite capable of clearing + contamination form not only people but items! + Trilbyspaceclone: + - tweak: Tank Dispender has been moved into toxin storage from toxins + kevinz000: + - rscadd: traitor classes can now be poplocked. hijack/glorious death are now locked + to 25/20 respectively. + timothyteakettle: + - rscadd: adds a new fermichem, used for creating sentient plushies! + - rscadd: Mice can now breed using cheese wedges + - rscadd: Royal cheese can be crafted to convert a mouse into king rat +2020-06-11: + Ghommie: + - balance: Balanced vending machine prices to be generally more affordable, a minority + has been priced up though. +2020-06-12: + EmeraldSundisk: + - tweak: The Detective's Office has been commandeered in order to serve a Head of + Security. Detectives will find their new office within starboard maintenance. + - rscadd: Adds the Head of Security's standard equipment to their new office. + - tweak: Slight adjustment/expansion to the main security department + - rscadd: Additional maintenance work + timothyteakettle: + - rscadd: Crabs, cockroaches, slimes and crabs are now small enough to fit in pet + carriers +2020-06-14: + Bhijn: + - bugfix: raw HTML can no longer be used in flavortext + - rscadd: Added Lesbian Visibility Day (April 26th) + - rscadd: Added Bisexual Visibility Day (September 23rd) + - rscadd: Added Coming Out Day! (October 11th) + - rscadd: Added Intersex Awareness Day (October 26th) + - rscadd: Added Transgender Awareness Week (November 13th - 19th) + - rscadd: Added the Transgender Day of Remembrance (November 20th) + - rscadd: Added Asexual Awareness Week (Last full week of October, this year it'll + be Oct. 25-31) + - rscadd: Added the Stonewall Riot Anniversary (June 28) + - bugfix: Moth week is now *actually* the last full week of July, instead of the + 4th of every weekday + the 5th Sunday. + Floof Ball / Kathrin Morrison / Floof Ball#0798: + - rscadd: Improvised Pistol + 32 ACP ammo. + - rscadd: Improvised Energy Gun. Fires 5 shots of 10 burn damage each. Can be upgraded + with a lens made from glassworking and T4 parts for a minor buff. + - rscadd: Ammo + gun part loot spawners for mappers. + - rscadd: New sprites for Improvised Rifle, the ability to sling the rifle and a + sprite for that. + - rscadd: New sprites for the Improvised Shotgun and its sling sprite. + - balance: Improvised shotguns are now two-handed only. + - balance: Improvised shotguns now only have a much less harsh 0.9* modifier, keeping + them two hits to crit with slugs and buckshot. It can no longer be dual-wielded + but can still be sawn off for w_class medium (can fit in backpacks). + - bugfix: Missing handsaw icons added in. + - tweak: Crafting table cleaned up into sections. + Ghommie: + - tweak: changed the weak attack message prefix from "inefficiently" to "limply", + "feebly" and "saplessly" and lowered the threshold. + - bugfix: Fixing old beserker hardsuits having the wrong helmet type. + The0bserver and Stewydeadmike: + - rscadd: Hey, there's a bit of dust in this recipe book! Recipes using peas? How + many recipes does this book even have? + - rscadd: Adds 6 new food items, and 1 new consumable reagent using all forms of + the recently discovered peas. Ask your local botanist and chef for them today! + YakumoChen: + - tweak: Adds polychrome options to loadout + - tweak: Adds risque polychrome options to Kinkmate vendors + kevinz000: + - bugfix: emissive blockers can no longer be radioactive. + - rscadd: Ghosts can now scan air inside most objects that contain air by clicking + on them. + - rscadd: Directional blocking has been added, keybound to G. This will reduce a + portion of incoming damage if done with eligible items at the cost of stamina + damage incurred to the user based on damage blocked as well as while active, + as well as in most cases preventing the user from doing any attacks while this + is active. + - rscadd: Parrying has been added, keybound to F. Timing-based counterattacks, effect + heavily dependent on the item, WIP. + - balance: Disks are now smaller. +2020-06-15: + Anturk, kevinz000: + - bugfix: VV now properly allows access to datums in associative lists + - rscadd: SDQL2 printout has been upgraded for the 5th time. + kevinz000: + - bugfix: plushies now work. credits to timothytea. + - rscadd: You can now tape knives to cleanbots + kevinz000 (port from VOREStation): + - imageadd: Ported zoomba skins for cyborgs. +2020-06-16: + Ghommie: + - bugfix: You can't blink nor use LOOC/AOOC as a petrified statue anymore. + Trilbyspaceclone: + - tweak: BEPIS decal painter has been moved to venders, replacing it being the flashdark + kevinz000: + - refactor: projectile ricochets now use a less hilariously terrible way of being + handled and should be easier to w + - bugfix: projectile runtime/ricocheting + - balance: Lobotomy no longer has a 50% chance of giving you a nigh-unremovable + trauma, but does 50 brain damage even on success. On failure, it will give you + a lobotomy-class trauma. + - balance: spinesnapping from tackling now only gives a lobotomy class trauma instead + of magic. + timothyteakettle: + - bugfix: Food carts now function as intended, allowing the pouring and mixing of + drinks. + - rscadd: slimes can now change their color using alter form +2020-06-17: + SmArtKar: + - rscadd: New ID icons + - rscadd: Sutures and Meshes + Trilbyspaceclone: + - bugfix: Gin export takes gin now +2020-06-18: + Detective-Google: + - tweak: cog is now less the suck + - bugfix: couple little derpy bits + - balance: malf disk and illegal tech disk moved from ashwalker base (guaranteed) + to tendrils (chance based) + SmArtKar: + - rscadd: Ported shuttles from beestation + timothyteakettle: + - rscadd: embeds got reworked, sticky tape was added, more bullets that ricochet + also added + - rscadd: medbots can now be tipped over + - soundadd: added more medbot sounds +2020-06-19: + Bhijn: + - bugfix: Atmos can no longer become completely bricked + Funce: + - bugfix: Square root circuit should now actually work. + SmArtKar: + - bugfix: Fixed my runtimes + TheSpaghetti: + - rscadd: more insectoid insects + kevinz000: + - rscadd: bay/polaris style say_emphasis has been added. You can now |italicize| + _underline_ and +bold+ your messages. + timothyteakettle: + - rscadd: Adds the brain trauma event, where one player gets a random brain trauma! + - rscadd: Adds the wisdom cow event, where the wisdom cow appears on the station! + - rscadd: Adds the fake virus event, where people get fake virus symptoms. + - rscadd: Adds the stray cargo pod event, where a cargo pod crashes into the station. + - rscadd: Adds the fugitives event, where fugitives are loose on the station, and + it's the hunters jobs to capture them. +2020-06-20: + LetterN: + - rscadd: Asset cache from tg + - tweak: Made the map viewer not look bad + - bugfix: Admin matrix right-bracket + bunny232: + - rscdel: Removed unsavory things from the vent clog event +2020-06-21: + kevinz000: + - balance: calculations for punch hit chance has been drastically buffed in favor + of the attacker. +2020-06-22: + Ghommie (porting PRs by zxaber, Ryll-Ryll, AnturK): + - tweak: Certain small items purchased through cargo now get grouped into a single + box. They also are immune to the 10% private account fee. + - rscadd: Added single-order options for several existing products in the Cargo + Catalog. + - tweak: Medkit listings are now single-pack items, and considered small items that + get grouped into single boxes. Price for medkits is as close to unchanged as + is reasonable. + - rscadd: You can now beat on vending machines to try and knock loose free stuff! + You can also almost kill yourself doing it, so it's your call if your life is + worth ten bucks. + - rscadd: Cigarette packets now have coupons on the back for small cargo items! + Smoking DOES pay! + - tweak: Some single/small items in cargo have been rebranded as goodies, come in + lockboxes rather than crates, and can only be purchased with private accounts. + kevinz000: + - refactor: Life() is split into BiologicalLife() and PhysicalLife. A component + signal has been added that can prevent either from ticking. + shellspeed1: + - rscadd: Adds IV bags. +2020-06-24: + DeltaFire15: + - balance: Choosing a random item in your uplink will no longer sometimes reroll + your contract. + - rscdel: Syndicate crate event cannot fire as a random event anymore. + Detective-Google: + - bugfix: singulos no longer succ infinite rods out of the ice + - bugfix: one of the directions for the diag hudpatch was blu instead of orang + timothyteakettle: + - bugfix: bonfires/grills no longer produce infinite quantities of food + - bugfix: slime's alter form ability now updates their hair colour when changing + their body colour +2020-06-25: + Anonymous: + - rscadd: Added kepi and orvilike kepi. Available through loadout. + Detective Google: + - rscadd: Medigygax + Detective-Google: + - bugfix: malf AIs can no longer yeet the station while shunted + - bugfix: SMESes can now properly use self charging cells + - rscadd: ghosts now show up when the round ends + - balance: away missions + Funce: + - bugfix: Mentor SQL queries are now deleted properly. + Linzolle: + - bugfix: analyze function on chem master is no longer broken + - bugfix: organs now decay inside dead bodies again + dapnee: + - rscadd: wataur bottle item + - imageadd: wataur bottle and overlay +2020-06-26: + Ghommie: + - bugfix: Snore spam. + - bugfix: Hostile mobs shouldn't hit their original spawner structures or thoses + of the same faction. + silicons: + - bugfix: soap cleans blood again +2020-06-27: + Detective-Google: + - tweak: Lying down is better + timothyteakettle: + - rscadd: felinids now nya when tabled +2020-06-28: + Detective-Google: + - bugfix: cog is less the suck + - tweak: piggybacking is no longer absolutely inferior + Ghommie: + - bugfix: Fixing windows interaction with spraycans. + - bugfix: Fixing kinetic accelerator guns not working well with gun circuitries. + - bugfix: Fixing Zoomba borgs lights overlays. + - bugfix: Fixing the "absorb another ling" and "absorb the most dna" objectives + rolling when no other changeling is around. + - spellcheck: Clarified a pet peeve about the spread infestation ability. + - bugfix: BEPIS nodes won't show up anymore in the expert mode ui of the r&d console + anymore (good thing they weren't researchable). + - bugfix: Hopefully fixing sound loop edge cases. + - bugfix: Fixing pAI radios being permanently disabled by EMPs at times. + - rscadd: Windoors can now be obscured with spraycans just like windows. + Ghommie porting PRs by Qustinnus/Floyd, Willow, cacogen, nemvar, Ghilker and EOBGames (Inept): + - bugfix: Fixes a material duplication bug. + - code_imp: unique combinations of custom_materials lists are now shared between + objects + - rscadd: meat material. yes. + - rscadd: materials can now be used to build walls/floors. meat house + - bugfix: edible component now does not try to attack if you eat something with + it + - rscadd: Texture support for mat datums with thanks to 4DPlanner! + - bugfix: you no longer hit yourself with organs when eating + - rscadd: A whole bunch of materials are now datumised! Check out bronze, runed + metal, sand, sandstone, snow, paper, cardboard, bone and bamboo. Oh, and pizza. + Yes, pizza. + - balance: Buffs material floor tiles' throwforces from 1 to 10 (same as iron) to + better showcase the effect of different materials (e.g. meat vs. titanium) + - bugfix: Radioactive items no longer output a single . when examined at a distance + MrJWhit: + - rscdel: Removed air alarm in Snow Snaxi in Tcomms Sat + - rscdel: Removed trash bins in genetics and mining + - tweak: Gives cargo techs a cargolathe + Putnam3145: + - bugfix: lost my mind just a couple of times + b1tt3r1n0: + - rscadd: pouches, again, and and material pouches. + timothyteakettle: + - rscadd: support for custom blood colours implemented, slimes blood colour now + equivalent to their body colour +2020-06-29: + b1tt3r1n0: + - balance: Made teratomas from sdgf less powergame + timothyteakettle: + - bugfix: slimes no longer have white blood by default +2020-06-30: + Fikou: + - rscadd: spray cans, airlock painters, and decal painters added to engineering/service/autolathe + (where applicable) + Ghommie: + - bugfix: Fixed a gap on the male insect anthro torso sprite when facing south. + - bugfix: Fixed mecha ID access not being removable. + - bugfix: Fixed a peeve with the hypno trance status effect not sanitizing some + heard hypnosis inputs (i.e. custom say messages like say"honks*clownem ipsum + dolor") + - bugfix: fixed an issue about using stacks with only 1 amount left. + - bugfix: Fixed a peeve on attack messages against carbons/humans. + - bugfix: Fixed missing hypnochair board. + - bugfix: Fixed material walls and tiles. My bad on that port. + Ghommie (inspired by MrDoomBringer's work on tgstation): + - rscadd: New check skills UI. + Ghommie (porting PRs by XTDM, coiax, MrDoomBringer): + - tweak: Random Events now have a follow link for ghosts! + - rscadd: Adds the Spontaneous Brain Trauma to the event pool. Sometimes your brain + just goes a little wrong. + - rscadd: Sometimes a low level cloning pod will make errors in replicating your + brain, leaving you with a mild brain trauma. + - rscadd: When a person is cloned, any mental traumas are cloned as well. + - rscadd: The wizard federation announces that the Curse of Madness is out of beta + and is now available for purchase for 4 points. It causes long-lasting brain + traumas to all inhabitants of a target space station. + - rscadd: The wizard federation declines responsibility for any self-harm caused + by curses cast while inside the targeted station. + - rscadd: Due to the extensive testing of the Curse of Madness some unique new trauma + types have appeared across Nanotrasen-controlled space. + - rscadd: Curse of Madness can now be triggered by a wizard's Summon Events, at + the same chance as Summon Guns or Summon Magic. + - admin: When an admin triggers Curse of Madness manually, they can specify their + own dark truth to horrify the station with. + nightred: + - code_imp: Created two_handed component + - refactor: Updated all existing two handed items to use the new component + silicons: + - bugfix: typing indicators no longer generates duplicate message boxes. + - rscadd: config errors now have line numbers. + - tweak: outgoing mentorpms are now blue instead of green for the sender. + - soundadd: '*squish' + timothyteakettle: + - rscadd: you can now select your tongue and speech verb in the character customization + menu! + - rscadd: skeleton is now split into two more types, greater and lesser + - bugfix: non-carbon blood is now not white + - spellcheck: fixed a bunch of grammar/spelling mistakes diff --git a/html/changelogs/archive/2020-07.yml b/html/changelogs/archive/2020-07.yml new file mode 100644 index 0000000000..55d279e810 --- /dev/null +++ b/html/changelogs/archive/2020-07.yml @@ -0,0 +1,465 @@ +2020-07-02: + Ghommie: + - bugfix: Fixing a few issues with twohanded items. + - bugfix: Unum decks now work correctly. + - bugfix: Abductor walls are once again buildable with alien alloy. + Trilbyspaceclone: + - tweak: Makes pride and envy ruin a bit smaller! + - rscadd: Pride now has rings, lipstick wigs and silver walls/door making a nice + and polished look then cyan blue walls. + - rscadd: more trash and better dagger placement on food ruin + - rscadd: Snowboim now has snowballs and toy gifts for the two skeles daw! + - tweak: Beach boim now has carp light branding beer, as well as soap! + - tweak: Greed ruin now uses nice slick walls and carpet! + - tweak: Founten ruin looks a lot better with its carpets and well maintained fluff + things, but walls suffered and no longer can salvage ruined metal... + - rscadd: Alien nest has a bit more glowy floors of resin looking a bit more lived + in by the drones. As well as the "door" now being see through resin rather then + the thicker stuff that you cant see through + - rscadd: Pizza party has a few more gifts, some candy and snap pops yay! + - balance: Sloth ruin is about 15~ tiles shorter, has and has more fruit for a bowl. + How lazy! + silicons: + - bugfix: bohbombing is a thing now +2020-07-03: + Arturlang: + - rscadd: You can now toggle hardsuit helmets from the strip menu + Ghommie: + - bugfix: fixed custom speech/tongue stuff. + - balance: Lowered shaft miners' paycheck, they have other ways to make cash. + - rscadd: You can't (un)equip garments on/from obscured inventory slots anymore. + - balance: The stamina cost multiplier for swinging melee weapons against mobs has + been brought back to 1 from 0.8 + - balance: The stamina cost for throwing mobs now scales with their mob size variable. + LetterN: + - tweak: Ported some tags from tgui-3.0 to Vending.js + - bugfix: vending icons + - bugfix: r&d icons + - bugfix: chem master icons + Onule: + - tweak: titanium wall man good + Sonic121x: + - bugfix: Bringback the ChemMaster pill type button. + - bugfix: Fix Technode icon. + bunny232: + - tweak: Witchhunter hat no longer obscures mask ears ,eyes, face and mouth + timothyteakettle: + - bugfix: bloodpacks initialise correctly now +2020-07-04: + Sonic121x: + - rscadd: crushed Soldry sodacan + - rscadd: digitigrade version of chief medical officer's turtleneck and captain's + female formal outfit. + silicons: + - refactor: blood_DNA["color"] is now a single variable instead of a list +2020-07-05: + Ghommie: + - bugfix: You can now actually gain wiring experience from using cable coils. + - bugfix: Opening the View Skill Panel shouldn't trigger messages about insufficient + admin privileges anymore. + Yakumo Chen, kappa-sama: + - rscdel: Removes improvised handguns + - rscdel: removed handsaws, improvised gun barrels (you can use atmos pipes again) + - balance: Guncrafting is less time and resource intensive + - tweak: Item names in guncrafting are user-friendly. + kappa-sama: + - rscadd: cloth string to replace durathread string + - rscdel: durathread string + - balance: All bows and arrows have had crafting times significantly reduced, coming + out at up to 6 times faster crafting speeds. Improvised bows no longer require + durathread; instead, they use cloth materials. + silicons: + - tweak: active blocking now has a toggle keybind + - rscadd: auto bunker override verb has been added + - balance: shields take 2.5 stam instead of 3.5 stam per second to maintain block + - rscadd: Cybernetic implant shields will auto-extend and be used to block if the + user has no item to block with + timothyteakettle: + - tweak: cooking oil is now far less lethal, requiring a higher volume of the reagent + to deal more damage +2020-07-07: + KasparoVy: + - tweak: Fixes misaligned south-facing silver legwraps sprite. + Owai-Seek: + - bugfix: Bee Balm is now visible. + Weblure: + - bugfix: Fixed the slowdown formula for small character sprites; you guys don't + use custom sprite sizes so just ignore these changes. + - bugfix: Fixed the "Move it to the threshold" button; it now does what it says. + - tweak: Reworded some text to be clearer. +2020-07-08: + DeltaFire15: + - bugfix: The kill-once objective now works properly. + EmeraldSundisk: + - rscadd: CogStation now has an apothecary + - rscdel: Removes an outdated note on sleepers + - tweak: Readjusts CogStation's chemistry lab + - tweak: Slight area designation adjustments for Robotics + - bugfix: The arrivals plaque should be readable now + Owai-Seek: + - rscadd: Margarine, Chili Cheese Fries. + - tweak: Egg Wraps are now categorized under egg foods. + - bugfix: Tuna Sandwich crafting/sprite is now visible. + - imageadd: Icons for chicken, cooked chicken, steak, grilled carp, corndogs + - imageadd: Icons for chili cheese fries, margarine, BLT sandwich + - imageadd: (Unused) icons for raw meatballs, and lard +2020-07-09: + timothyteakettle: + - rscadd: bluespace tray added, allowing twice as many items as the regular tray, + printable at the service lathe, researched through science + - rscadd: bluespace jar added, a kind of pet carrier that allows human sized mobs + inside, and smashes when thrown, researched and printed through science +2020-07-10: + Chiirno: + - code_imp: Gave jellypeople a unique brain object /obj/item/organ/brain/jelly + - imageadd: added an icon for jellypeople brains. + EmeraldSundisk: + - rscadd: Adds a pool to PubbyStation + - tweak: Slight adjustments to the surrounding area as to fit said pool + Sneakyrat6: + - bugfix: Fixes hair falling out of hoodies. + TheObserver-sys: + - bugfix: Actually adds the juice reagent to make laugh peas donuts. +2020-07-11: + Putnam3145: + - refactor: Gas mixtures now live entirely in a DLL. +2020-07-12: + DeltaFire15: + - balance: Sentinels compromise now heals augmented bodyparts. + EmeraldSundisk: + - rscadd: Adds turnstiles to CogStation's security wing + - rscadd: Readds robotics to the Corpse Disposal Network + - rscadd: Readds chemistry's ability to send items directly to the experimentation + lab + - tweak: Visual renovation and slight adjustments to CogStation's robotics lab + - tweak: Slight visual adjustments elsewhere (the library) + - bugfix: CogStation's mail and disposal pipes are once again complete + - bugfix: CogStation's robotics lab now has spawners, lights, and other room essentials + HeroWithYay: + - rscadd: Added Telecrystal Dust + - tweak: Telecrystals can be sold at cargo + LetterN: + - rscadd: Added d[thing] emojis + - bugfix: bye xss + MrJWhit: + - rscdel: Removes northern tunnel to the monastery on Pubby + Yakumo Chen: + - rscadd: Adds a wedding crate to cargo full of wedding attire. + kappa-sama: + - tweak: wisdom cow is half as common and is wise enough to lag the server 66% less + silicons: + - config: 'policy configuration added, plus support hooks for assisting enforcement + of clone memory disorder. logging: added logging of revival by defib, cloning, + strangereagent, and revival surgery' + - rscadd: You can now "audibly emote" by having ! at the start of a sentence. + timothyteakettle: + - rscadd: due to recent biological advancements, you can now make eye contact with + people. + zeroisthebiggay: + - bugfix: a singular stray pixel +2020-07-13: + Linzolle: + - bugfix: you can no longer vore and digest people regardless of vore preferences + Owai-Seek: + - tweak: Trashbags can now hold most shoes, and organs. + - balance: You can no longer nest nuke disks or hold brains in the trash. +2020-07-14: + silicons: + - rscadd: chemical reactions now are sorted by priority first and temperature second. + - rscadd: sec and medical records have been added to character setup. + - bugfix: circuit reagent heaters are now sanitized for temperature from 2.7 to + 1000. + timothyteakettle: + - bugfix: ports a money bag exploit +2020-07-15: + Sonic121x: + - bugfix: Paramedic jumpsuit +2020-07-16: + DeltaFire15: + - bugfix: Fixes a zeolite runtime caused by a missing check. + Sneakyrat6: + - bugfix: Fixes being able to meta people real name with OOC Notes + timothyteakettle: + - rscadd: travelling traders from another dimension can now visit the station in + search of something specific, and reward you for giving it to them + - bugfix: small error with pet carrier logic fixed and also making sure simple mobs + are catered for properly inside bluespace jars + - bugfix: fixes coin related issue +2020-07-17: + ShizCalev, Fikou: + - bugfix: Added some sanity checking for varedit values. + - bugfix: Fixed an exploit involving coins and mints that could crash the server. + - bugfix: Fixed an exploit that would allow you to destroy round-critical / indestructible + items with folders. + - bugfix: Swarmers can no longer cut power lines by deconstructing catwalks underneath + them. + - bugfix: Fixed a scenario that allowed infinite resource generation via ore machines. + - bugfix: you can no longer inject html in ahelps + - admin: you cant either, jannies + timothyteakettle: + - bugfix: fixes a small pickle related issue + - rscadd: recent culinary and scientific advancements have brought forth new pickle + related technologies +2020-07-19: + Arturlang: + - rscadd: TGUI 3.0 and enables all the UIs, plus the smart asset cache, and all + the things required for them + EmeraldSundisk: + - rscadd: Adds a pool to Delta Station + - rscadd: Adds light fixtures to specified areas + - tweak: Relocates objects in impacted areas of Delta's starboard maintenance + MrJWhit: + - rscadd: Adds a small light next to the kitchen counter + Putnam3145: + - bugfix: Pen uplinks no longer broken + TheObserver-sys: + - rscadd: 'Adds a new reaction: Slime Extractification. Take 30u Slime Jelly, 5u + Frost Oil, and 5u plasma to generate a fresh grey slime extract.' + Yakumo Chen: + - tweak: Hierophant club now checks for friendly fire by default. + b1tt3r1n0: + - rscadd: Added the updated circle game + silicons: + - rscadd: Unarmed parry is now a thing. + timothyteakettle: + - rscadd: plushies in the loadout have been replaced with a box that lets you choose + one instead + - bugfix: wrestling should no longer have the ability to permanently rotate people + - rscadd: you can now select to wear a snail shell as your backpack in the customization + menu + zeroisthebiggay: + - tweak: martial arts twenty minpop + - bugfix: records +2020-07-20: + lolman360: + - tweak: Service borgs now have synthesizers instead of a violin and guitar. + - bugfix: borg RSF +2020-07-21: + Arturlang: + - bugfix: Decal painter ui now works, yay? + CameronWoof: + - rscadd: Adds aloe, a new growable plant + - rscadd: Adds medicated sutures and advanced regenerative meshes + - bugfix: Polypyrylium oligomers and liquid electricity now correctly populate + Chiirno: + - rscadd: Alt-click pill bottles places top-most pill into active hand. + - tweak: Moved dice bags from pill_bottle/dice to box/dice to avoid dice bags being + affected from medical specific pill bottle changes. + DeltaFire15: + - bugfix: Swarmers can once again eat items as long as there's nothing living in + them. + Funce: + - bugfix: Genetics spiderwebs are no longer impassable walls + Kraseo: + - balance: Damp rags no longer instantly apply their chemicals onto someone. + SiliconMain: + - tweak: Geigers can no longer be contaminated + TheSpaghetti: + - rscadd: new snowflake trait + kappa-sama: + - balance: advanced surgery duffel bag no longer comes with a nukie medkit. it costs + 4 less telecrystals to make up for this colossal nerf. + - tweak: quartered the weight of the stray cargo pod event from 2x normal to 1/2 + normal + silicons: + - tweak: survivalists (from summon guns/magic) are proper objective'd pseudoantagonists + again + - tweak: summon guns/magic can only be used once each + - tweak: summon guns/magic now only cost one point each + - imageadd: ':dsmile: :dfrown: :dhsmile: :dpog: :dneutral:' + - bugfix: gravity should update for mobs a fair bit faster + - rscadd: voting can now be done from the stat panel if the system is plurality + and approval + timothyteakettle: + - rscadd: new fried component used for frying objects + - bugfix: various frying bugs fixed such as being able to unfry items and frying + turfs with cold cooking oil +2020-07-22: + Ludox: + - rscdel: You can no longer be brainwashed into giving birth to a fake baby + kappa-sama: + - balance: brainwashing disk has lost its cost buffs (3->5) and is role restricted + once more (medical doctor/roboticist) +2020-07-23: + DeltaFire15: + - bugfix: Traits are no longer fucked + Putnam3145: + - tweak: Slight optimization in chat code. + kappa-sama: + - bugfix: tendril chests being empty + zeroisthebiggay: + - rscadd: fetish content +2020-07-24: + EmeraldSundisk: + - rscadd: Adds a CMO office, along with Virology and Genetics labs to Omega Station + - rscadd: Adds a second chemistry station to the chemistry lab + - tweak: Adjusts the locations of some objects in medical to accommodate these new + additions + - tweak: Relocates the morgue + - tweak: Relocates items in impacted areas of maintenance as well as the library + - bugfix: Fixes an air line Bartholomew somehow knocked out + Linzolle: + - bugfix: wounds now have a description on examine + Owai-Seek: + - rscadd: Meatball Sub, Meatloaf + Meatloaf Slices, Bear Chili, Mashed Potatoes + - rscadd: Buttered Potatoes, Fancy Cracker Pack, Spiral Soup, Sweet and Sour Chicken + - tweak: Organised the Food DMI a bit. + - tweak: Deleted some stray pixels on some sprites. + - tweak: Nuggie boxes are now centered correctly. + - imageadd: Icons for the the food items in this PR. + Sneakyrat6: + - bugfix: Fixes dressers not giving you undies + - bugfix: Fixes Snaxi not loading properly because of typos + - rscadd: You can now burn photos + Zandario: + - spellcheck: Murdered **tipes** and gave birth to **is**. + silicons: + - tweak: sanitization now doesn't cut off 15.7 or something million possible colors + from character preferences (instead of only allowing 16 values for R G and B, + it now allows 256 each) + - balance: projectiles are by default 17.5 tiles per second instead of 12.5 + timothyteakettle: + - rscadd: due to recent innovative research in the medical field, you now have bones + - tweak: zombie claws are now sharp and do less damage, but can destroy non-lifeforms + far faster + - tweak: zombies now take less stamina damage + - rscadd: beepsky can now wear hats + zeroisthebiggay: + - imageadd: rad and kravglove sprites +2020-07-25: + CameronWoof: + - bugfix: Aloe now has an icon. + timothyteakettle: + - bugfix: beepsky replaces the word THREAT_LEVEL with the actual threat level +2020-07-26: + DeltaFire15: + - bugfix: Organs now decay again. + Iatots: + - tweak: Licking wounds now may cause you to spit out a hairball once in a while! + - rscadd: You can now craft a catgirl plushie with 3 of a new ingredient occasionally + found in medbay! + dapnee: + - tweak: removed legacy public mining shuttle area and remade lounge +2020-07-27: + Hatterhat: + - rscadd: Training bokkens! Make 'em from wood, use 'em in-hand to toggle between + harmful and not-so-harmful, practice your parrying with them! + - bugfix: Marker beacons should have a sprite again. + silicons: + - rscadd: clownops and clown mobs now share the same faction. HONK! + timothyteakettle: + - bugfix: modern pickle technology now allows people who have been turned into pickles, + to be retrieved through the medical course of dying +2020-07-28: + Cacogen: + - rscadd: OSHA has more pull than anyone could have expected. All armor provided + by Nanotrasen and the syndicate now have tags that accurately lists defenses + and resistances of a piece of clothing. + CameronWoof: + - tweak: Exotic seed crates now contain a spaceman's trumpet seed packet. + EmeraldSundisk: + - rscadd: Renovates Snow Taxi's northeast bathroom to have multiple non-urinal toilets + and showers + - rscadd: Adds signage/labeling to improve map readability + - rscadd: Adds a bathroom to the northwest station + - rscadd: Adds a filing cabinet to the cargo department + - tweak: Area designation adjustments to account for the above changes + - bugfix: Adds a missing airlock cyclelink near medical + Ludox235: + - tweak: Makes the flavour text that appears when you become a zombie tell you to + act like one. + MrJWhit: + - tweak: Decluttered toxins and hid the yellow mix line in atmos, for metastation + SiliconMain: + - tweak: Paramedic heirloom is now a zippo + - tweak: Durathread belts now protect their contents from radiation, and can hold + full sized extinguishers + Sishen1542: + - rscdel: removed zoomba + dapnee: + - tweak: added a fan to the listening outpost + - bugfix: added two missing r-walls near the SM, removed random light and wire node + below the engine, and fixed the missing cable in the courtroom on Kilo + kappa-sama: + - balance: Stimpaks cost 5tc once more, up from 3tc. + silicons: + - rscadd: polychromatic cloaks to loadout + - rscdel: no more self healing with medibeam guns + - balance: oh no, taser buff. alt fire delay dropped to 0.4 seconds. + - rscadd: you can now shoot yourself by disarm-intenting yourself with a gun. + timothyteakettle: + - tweak: species code is now slightly less messy + - bugfix: slight tweak to how material crafting works + - bugfix: changed up pet carriers / bluespace jars a bit so you can't fit certain + things inside them and also the text shown for resist times is accurate + zeroisthebiggay: + - rscadd: Black Box theft objective +2020-07-29: + DeltaFire15: + - bugfix: The 'Naked' outfit is no longer broken. + Ghommie: + - bugfix: fixed cremator trays, paleness examination strings, chat message for stamping + paper, looping sounds, load away missions/VR admin verb, access requirements + for using the sechuds. + - tweak: Alt-Clicking a cigarette packet should pull the lighter out first if present, + then cigarettes. + Hatterhat: + - bugfix: Directional windows can now be rotated counterclockwise properly again. + NecromancerAnne, Sirich96: + - rscadd: Stunbaton sprites by Sirich96. + - rscadd: New sprites for the stunsword. + necromanceranne: + - rscadd: Adds some in-hands for the rapier sheath. + timothyteakettle: + - bugfix: tail wagging should work in all cases now + - bugfix: bluespace jars work as intended now + - bugfix: aliens can remove embeds now + - bugfix: bloodsuckers are not affected by bloodloss + zeroisthebiggay: + - rscadd: Flannel jackets and bartender winter coat +2020-07-30: + Adelphon: + - rscadd: Created a Cosmetic version of the camo. + Arturlang: + - code_imp: Bloodsucker LifeTick runs from BiologicalLife now + Ryll-Ryll ported by silicons: + - rscadd: Shoelaces are now a thing. You can untie them by laying down next to someone. + - tweak: shoes now have lace delays and some can't be laced at all + - refactor: do after now tracks who's interacting with who, meaning some actions + now break when the target moves away. + SiliconMain: + - rscadd: Ported the long range atmos analyzer from sk*rat, credit to NotRanged + silicons: + - rscadd: energy sword perfect parries now reflect projectiles back at their shooters. + - balance: any mob can now parry if they have the right item + - rscadd: beam rifles now go into emitters properly + - refactor: clickdelay has been refactored into an experimental hybrid system. Check + code/modules/mob/clickdelay.dm for more information. + - balance: Resisting no longer checks clickdelay, but is standardized to a 2 second + per resist system for most forms of resisting. It still sets clickdelay, though. + - rscadd: 'Meters have been added for estimating time until next attack/resist. + Won''t be that useful due to our clickdelay currently being very short, though. + They''re visible from your hand and resist HUD elements. experimental: Most + attacks and forms of attacking (minus unarmed because it''s too much of a pain + to refactor how hugs/gloves of the north star works) now check for time-since-last-attack + rather than making it so you can''t attack for said time. This means you can + very quickly switch to a gun from a melee weapon, whereas in the old system + a melee weapon would put you on lockout for 0.8 seconds, in the new system all + the gun cares about is that you did not attack for at least 0.4 seconds.' + - code_imp: All clickdelay setting/reading are now procs, so it should be trivial + to implement another system where drawing/switching to a weapon requires you + to have it out for x seconds before using it. I am not personally doing it at + this point in time though because it will likely just annoy everyone with no + real gain unless we do something like putting a 0.8 second switch-to cooldown + for guns (which I did not, yet) + - refactor: 'attack_hand has been refactored to on_attack_hand remove: sexchems + no longer impact click delay' + - rscadd: turrets now automatically stagger their shots. Happy parrying/blocking. + - bugfix: turrets now speed_process, they were shooting slower than they should + be + - balance: anything can now block with the right items + timothyteakettle: + - bugfix: some crafted crates won't contain items now, and thus have stopped breaking + the laws of physics + - tweak: beepskys hats now follow the laws of gravity and move up/down when he bobs + up and down diff --git a/html/changelogs/archive/2020-08.yml b/html/changelogs/archive/2020-08.yml new file mode 100644 index 0000000000..9bb5e371f1 --- /dev/null +++ b/html/changelogs/archive/2020-08.yml @@ -0,0 +1,540 @@ +2020-08-01: + dapnee: + - tweak: added cake hat to bar, adds another atmostech spawn + - bugfix: sinks point in the right direction, APC won't spawn off the wall in circuits + - bugfix: changes commissary APC so it actually powers the room, adds a missing + AIR alarm, arrivals no longer has active atmos tiles. + silicons: + - tweak: toy shotguns no longer need 2 hands to fire + - bugfix: being on fire works again. + timothyteakettle: + - bugfix: monkeys no longer continuously bleed everywhere +2020-08-02: + Auris456852: + - rscadd: Added B.O.O.P. Remote Control cartridges to the PTech. + Hatterhat: + - rscadd: Durathread reinforcement kits! Sprites by Toriate, sets jumpsuit armor + to durathread levels, craft in the crafting menu. + KeRSedChaplain: + - rscadd: The belligerent scripture and a brass multitool, and a new marauder variant + which act similar to holoparasites/guardian spirits. + - rscdel: Removed the abductor teleport consoles they get, removes abscond for the + time being as I've not seen much use for it other than just spamming it and + hoping you end up in the armory. + - tweak: moved around scriptures to make the cult work better as being based around + the station, makes the Ark scream more often and work as a summonable object, + clockwork armor now has a flat 0 defense up to 10 instead of negatives against + laser damage. Makes the Ark work better in a station based setting, as well + as the Heralds beacon in case It works for the mode. + - soundadd: added powerloaderstep.ogg for Neovgre + - tweak: changes 'Dread_Ipad.dmi' to 'clockwork_slab.dmi' + MrJWhit: + - tweak: Adjusts abductor spawntext + Seris02: + - bugfix: fixed replica pods + dapnee: + - bugfix: fixed active turfs on wizard ruin and space hermit, fixed missing APC's + and added a light on Delta + ike709 and bobbahbrown: + - rscadd: Admins can now see your bans on (some) other servers. + kappa-sama: + - bugfix: chaplain cultists being able to convert people to full clockwork cult + status + timothyteakettle: + - tweak: combat mode now has weaker buffs in terms of damage dealt and took for + being or not being in the mode + - tweak: damage debuff for laying down has been decreased from 0.5x to 0.7x +2020-08-03: + KeRSedChaplain: + - bugfix: fixed clockwork guardians being able to reflect ranged weapons + Linzolle: + - bugfix: uv penlight no longer invisible + dapnee: + - bugfix: active turfs on box and xenohive, maintenance bar APC not being stringed + correctly, turned a monitor to face a direction that makes sense, changed tag + of camera in gravgen being misnamed + silicons: + - rscadd: shoves have been buffed to apply a status effect rather than a 0.85 movespeed + modifier, meaning repeatedly shoving someone now renews the debuff + - balance: shoves now stagger for 3.5 seconds. + - tweak: war operatives now actually time 20 minutes since roundstart to depart + instead of 15. + - balance: explosive stand bombs can now be examined from any distance + - code_imp: explosive stand bombs are now a component. +2020-08-04: + Seris02: + - bugfix: lizard spines + timothyteakettle: + - rscadd: due to further advancements in medical technology, you can now have holes + poked into your body for fun and enjoyment + zeroisthebiggay: + - rscadd: prefs for headpat wagging +2020-08-06: + Auris456852: + - rscadd: Added B.O.O.P. Remote Control cartridges to the PTech. + Hatterhat: + - rscadd: Proto-kinetic glaives! Essentially a proto-kinetic crusher with a different + blade, handguard, and goliath hide grip. Expensive, but elegant. + - balance: Door charges no longer knock people out. + Ludox235: + - rscadd: You can now buy damaged AI upload modules in the traitor's uplink. + Seris02: + - bugfix: fixed ghost chilis + Trilbyspaceclone: + - rscadd: 4 New blends of tea have been shipped to the station, and how to make + them has been leaked! + b1tt3r1n0: + - rscadd: Added the warp implant + dapnee: + - tweak: added a hallway to telecoms for engineers to get there on meta + kappa-sama: + - rscdel: dildo circuit assemblies + lolman360: + - bugfix: The Tendril-Mother on Lavaland has remembered how to make ashwalkers who + know how to speak Draconic again. + timothyteakettle: + - tweak: nanotrasen has decided to fire all disabled members of the security division + and confiscate certain sentimental items from doctors + - tweak: the custom tongue preference now passes through cloning so you spawn with + your selected tongue + - tweak: several changes to travelling traders so they look better and spawn slightly + less often + zeroisthebiggay: + - rscadd: nukies can buy holoparasites +2020-08-07: + dapnee: + - bugfix: fixed active tufs on some space ruins, murderdome VR, and a few on pubby, + changed cargo autolathe to techfab, messed with pipe room leading to monastery. + lolman360: + - bugfix: vendors are now unanchored when tipped. it just fell over it's not bolted + to the ground anymore. + - bugfix: podpeople no fat when sunbathing. + silicons: + - balance: explosions only recurse one level into storage before dropping 1 level + per storage layer. + - tweak: volumetric storage is now minimum 16 pixels per item because 8 was ridiculous + - spellcheck: shieldbash balanace --> balance + - rscadd: attempting to send too long of an emote will now reflect it back to you + instead of cutting it off and discarding the overflow. + - rscadd: holoparasites can now play music + - balance: lethal blood now causes damaging bleeding instead of outright gibbing +2020-08-08: + DeltaFire15: + - balance: Roundstart cultists now start with a replica fabricator - no brass though, + make your own. + - balance: 'Kindle cast time: 10 > 15, mute after stun end: 2 > 5, slur after mute + end: 3 > 5' + - bugfix: The ratvarian spear no longer adds negative vitality under very specific + circumstances. + - balance: The Ratvarian Spear can parry now! Short parries with low leeway, but + low cooldown. + - rscadd: The brass claw, a implant-based weapon which gains combo on consecutive + hits against the same target. + - rscadd: The sigil of rites, a sigil used to perform various rites with a cost + of power and materials + - rscadd: 'The Rite of Advancement: Used to add a organ or cyberimplant to a clockie + without need for surgery.' + - rscadd: 'The Rite of Woundmending: Used to heal all wounds on another cultist, + causing toxins damage in return.' + - rscadd: 'The Rite of the Claw: Used to summon a brass claw implant. Maximum of + 4 uses per round.' + Hatterhat: + - rscadd: You can now buy a toolbox's worth of Mosin-Nagant ammo for a fairly discounted + price. + - rscadd: Revolvers from the dedicated kit now have reskinning capabilities. + - bugfix: You can now actually buy the riflery primer, which lets you pump shotguns + and work the Mosin's bolt faster. + - imageadd: Bulldog slug magazines now have a unique sprite. + Ludox235: + - rscdel: Removed an abductee objective that told you to remove all oxygen. + - rscadd: Added a new abductee objective to replace the removed one. + Sishen1542: + - tweak: "\U0001F171\uFE0Foneless" + - rscadd: squishy slime emotes + timothyteakettle: + - tweak: heparin makes you bleed half as much now + - tweak: cuts make you bleed 25% less now + - rscadd: more items in the loadout and loadout has subcategories now for easier + searching +2020-08-09: + Hatterhat: + - rscadd: Proto-kinetic glaives (not crushers) can parry now. + MrJWhit: + - rscadd: Adds a second shutter on the top of the hop line + silicons: + - bugfix: immovable rods no longer drop down chasms + - rscdel: 'fun removal: squeaking objects now have an 1 second cooldown between + squeaks, and will have a 33% chance of interrupting any other squeaking object + when Cross()ing, meaning no more ear-fuck conveyor belts.' +2020-08-10: + Hatterhat: + - bugfix: Parry counterattack text now shows up. + - balance: Sterilized gauze is now better at stopping bleeding, and applies slightly + faster. Very slightly faster. + - balance: Ointment and sutures now hold more in a stack (12 and 15, respectively). + - tweak: Sterilized gauze can now be made by just pouring 10u sterilizine onto standard + medical gauze, instead of having to craft it. Why you had to craft it, I will + honestly never know. + - balance: Proto-kinetic glaives are more expensive, stagger/cooldown on failed + parries increased slightly, perfect parries required for counterattack. + - rscadd: 'New item: Temporal Katana. 2 points for wizards, timestops upon successful + parry, bokken quickparry stats (100 force on melee counter!).' + - rscadd: Also you can *smirk. This has no mechanical effect, other than being smug. + KeRSedChaplain: + - rscadd: Added a guide for romerol usage + - balance: made infectious zombies not enter softcrit and take no stamina damage + LetterN: + - tweak: clocktheme color + - code_imp: Ports TGUI-4 + Lynxless: + - rscadd: 'Ports TG #51879' + Owai-Seek: + - tweak: Meatballs now spawn raw from food processors. + Putnam3145: + - rscadd: Ethereals + - rscdel: (Hexa)crocin + - rscdel: (Hexa)camphor + - tweak: Tweaked wording for marking tickets IC issue. + - tweak: Rerolling your traitor goals will ONLY give you "proper" objectives. + Seris02: + - bugfix: borgs being able to select and use a module when it's too damaged + Sishen1542: + - balance: gave chairs active block/parry in exchange for removal of block_chance + - tweak: replaces box whiteship tbaton with truncheon + kappa-sama: + - balance: made the Dirty Magazines crate cost 4000 instead of 12000 credits + - rscadd: MODS I SPILLED MU JUICE HEJPPHRLP HELPJ JLEP HELP + silicons: + - balance: player made areas are no longer valid for malf hacking + - tweak: default space levels is 4 again. + - tweak: rats now swarm instead of stacking on one spot. + - balance: getting hit by an explosion will now barely hard knockdown, but will + leave you somewhat winded. + timothyteakettle: + - tweak: speech verbs copy through dna copying now +2020-08-11: + Hatterhat: + - bugfix: PDA uplinks can now steal from pens. Properly. Just make sure to have + a pen in your PDA, first. + kappa-sama: + - tweak: tracer no longer gives you full stamheals per use + zeroisthebiggay: + - rscadd: volaju two +2020-08-12: + DeltaFire15: + - balance: 'hellgun single-pack classification: goodies -> armory' + Detective-Google: + - bugfix: hallway table hallway table + Hatterhat: + - balance: The temporal katana is now slightly more worthy of the 2 spell point + cost, with a smaller, antimagic respecting timestop, less force, and no random + blockchance. Society has progressed past the need for blockchance. + LetterN: + - rscadd: Mafia Component + - bugfix: Fixed missing icons and handtele + Putnam3145: + - bugfix: a whole lot of jank regarding funny part sprite display. + Toriate: + - rscadd: Opossums have migrated into the maintenance tunnels! Seek them out at + your own peril! + ancientpower: + - tweak: Doors added to the west side of box medbay to make things a bit more manageable. + kappa-sama: + - tweak: smuggler satchel cost 2->1 + - tweak: radio jammer cost 5->2 + - bugfix: smuggler satchel uplink description now implies that persistence is disabled + lolman360: + - rscadd: renameable necklace (accessory, attaches to suit) and ring (glove slot.) + - tweak: custom rename is now 2048 characters? i think it's characters. + silicons: + - rscadd: You can now use anything as an emoji by doing :/obj/item/path/to/item:. + This works for any /atom or subtype. + timothyteakettle: + - rscadd: syndicate agents now have access to mechanical aim enhancers which allow + them to aim bullets to bounce off walls + - bugfix: ricochets work properly now for the bullets that support them + zeroisthebiggay: + - imageadd: hair and some sechuds + - balance: ce hardsuit radproofing +2020-08-13: + LetterN: + - rscdel: Removes fermisleepers and reverts them to tg ones +2020-08-14: + silicons: + - bugfix: abductors can buy things +2020-08-15: + LetterN: + - bugfix: missing anomaly core icons + - bugfix: wrong state. blame the tg vertion i copied + silicons: + - tweak: the 8 rotation limit from clockwork chairs has been removed. please don't + abuse this. + - tweak: ethereals can now wear underwear +2020-08-16: + kiwedespars: + - balance: nerfed hypereut chaplain weapon. + - balance: 50% rng blockchance -> 0% + - balance: parry made much worse because it's an actual weapon and a roundstart + one at that. + zeroisthebiggay: + - rscadd: tips + - rscdel: tips +2020-08-17: + DeltaFire15: + - bugfix: Cogscarabs are no longer always Pogscarabs + Strazyplus: + - rscadd: Added drakeborgs + - rscadd: Added drakeplushies + - imageadd: added drakeborg sprites + - imageadd: added drakeplushie sprites + - code_imp: changed some code - added drakeplushies to backpack loadout Removed + duplicate voresleeper belly sprites from engdrake & jantidrake. [CC BY-NC-SA + 3.0](https://creativecommons.org/licenses/by-nc-sa/3.0/) + - rscadd: Added CC BY-NC-SA 3.0 license details to icon/mob/cyborg moved drakeborg.dmi + to icon/mob/cyborg +2020-08-18: + DeltaFire15: + - balance: 'kindle cast time: 15ds -> 25ds' + - tweak: Moved the Belligerent Scripture to where it should be in the code + Detective-Google: + - rscadd: glass floors + - rscadd: uncrowbarrable plasma floors tweak:disco inferno's plasma floors can no + longer be crowbarred. + - rscadd: ghost cafe has funky fresh art + - bugfix: you can actually remove glass floors now + - code_imp: get_equipped_items is hopefully less gross + - balance: plasma cutters are no longer gay + Hatterhat: + - balance: Slaughter demons (and laughter demons, being a subtype) are MOB_SIZE_LARGE, + with one of the more immediate effects being able to mark them with a crusher + and backstab them. + - balance: The funny blyat men have stumbled upon another surplus of Mosin-Nagants + and are starting to pack them into crates again. + - balance: Vehicle riders can now, by default, get shot in the face and/or chest. + - rscadd: Adminspawn only .357 DumDum rounds! Because sometimes the other guy just + really needs to hurt. + - rscadd: Bluespace beakers now have a chemical window through the side that shows + chemical overlays. + - rscadd: Plant DNA manipulators now let you chuck things over them. Or they WOULD, + if LETPASSTHROW worked half a damn. + LetterN: + - bugfix: uplink implant states + - tweak: tweaks how role assigning works + MrJWhit: + - rscadd: Gives ashwalkers nightvision + - balance: Makes tesla blast people, not the environment, to save the server. + TheObserver-sys: + - bugfix: moves Garlic sprites from growing.dmi to growing_vegetable.dmi + - rscdel: Removes the unused Electric Lime mutation, it just takes up space with + no actual function nor sprites. + - imageadd: Gives Catnip growing sprites + - imagedel: Removes redundant images in growing.dmi + kiwedespars: + - rscadd: 10 force to a fucking rubber cock. + lolman360: + - balance: shotgun stripper clip nerf. ammoboxes can now accept a load_delay that + happens when they attack a magazine, internal or external. + ported from tg: + - rscadd: bronze airlocks and windows can now be built + - balance: i also tweaked bronze flooring to be cheaper. + silicons: + - tweak: stamina draining projectiles without stamina for their primary damage type + now has their stamina damage taken into account for shield blocking, rather + than the block being done for free for that. + timothyteakettle: + - refactor: snowflake code tidyup + - refactor: snowflake code for mutant bodypart selection has been rewritten to be + ~14x shorter + - tweak: meat type and horns can now be selected by any species +2020-08-20: + DeltaFire15: + - bugfix: The cooking oil damage formula is no longer scuffed. + - tweak: Changed the clockie help-link to lead to our own wiki. + Fikou: + - admin: admins can now do html in ahelps properly + Hatterhat: + - balance: Pirate threats are now announced as "business propositions", and their + arrivals are now also announced properly. + tiramisuapimancer: + - bugfix: Ethereal hair is now their body color instead of accidentally white +2020-08-21: + LetterN: + - rscadd: Updates and adds some of the tips + Putnam3145: + - admin: added reftracking as a compile flag + SmArtKar: + - tweak: RSD limitation is now 500 tiles + - bugfix: Fixed broken RSD sprites + - config: Removed that shuttle limit + timothyteakettle: + - bugfix: two snouts can once again be chosen in customization + - bugfix: lizard snouts work again +2020-08-22: + Time-Green (copypasta'd by lolman360): + - rscadd: plumbing + - rscadd: automatic hydro trays +2020-08-23: + DeltaFire15: + - bugfix: silicons and clockies can now access APCs properly + EmeraldSundisk: + - rscadd: Medbay now has a smartfridge for organ storage + - rscadd: Slight enhancements to the station's electrical wiring layout + - rscadd: Very small library renovation + - bugfix: Exterior airlocks have been given proper air systems for safety's sake + Ghommie: + - bugfix: Stops shielded hardsuits from slowly turning the wearer into a big glowing + ball of stacked energy shield overlays. + - tweak: the shielding overlay is merely visual as result. Aim your clicks. + Ludox235: + - tweak: no more 10 pop xenos (25pop now) + MrJWhit: + - tweak: Increases the majority of airlocks by 1 tile. + - tweak: Minor adjustments to the TEG engine. + Putnam3145: + - balance: Simplemobs no longer count in dynamic. + - balance: '"Story" storyteller no longer starts at a ludicrously low threat, always.' + - balance: Blob threat now scales with coverage. + - tweak: One person with their pref on no longer overpowers 40 people who might + not even know there is one. + - bugfix: Negative-weight rulesets are no longer put into the list. + kiwedespars: + - tweak: removed durathread from armwraps recipe. + lolman360: + - rscadd: breath mask balaclava + timothyteakettle: + - bugfix: lizards are now a recommended species for mam snouts + zeroisthebiggay: + - rscadd: new sprites for the temporal katana + - rscadd: suiciding with the temporal katana omae wa mou shinderius you into the + shadow realm + - soundadd: twilight isnt earrape +2020-08-24: + MrJWhit: + - bugfix: Fixes areas on expanded airlocks + silicons: + - bugfix: wormhole jaunters work + - tweak: wormhole jaunters no longer get interference from bags of holding + - bugfix: airlocks now only shock on pulse/wirecutters instead of on tgui panel + open. + timothyteakettle: + - rscadd: three new items are in the loadout for all donators + zeroisthebiggay: + - rscadd: contraband black evening gloves in kinkvend +2020-08-25: + Hatterhat: + - rscadd: Insidious combat gloves have been replaced by insidious guerilla gloves. + They're generally the same, except now you can tackle with them. + Literallynotpickles: + - tweak: You can now equip handheld crew monitors on all medical-related winter + coats. + Putnam3145: + - tweak: vore now ejects occupants on death + raspy-on-osu: + - tweak: Thermoelectric Generator power output + timothyteakettle: + - tweak: I.P.Cs now short their circuits when expressing emotion, causing sparks + to appear around them. +2020-08-26: + ancientpower: + - tweak: Ghosts can read newscasters by clicking on them. + silicons: + - balance: hierophant vortex blasts now have 50% armor penetration vs mecha + - balance: ventcrawling now kicks off every attached/buckled mob, even for non humans. +2020-08-27: + silicons: + - tweak: eyebeam lighting can only have 128 maximum HSV saturation now. + - balance: no more shotgun stripper clips in boxes. + - balance: goliath tentacles now do 20 damage to mechs at 25% ap + timothyteakettle: + - tweak: changing your character's gender won't randomize its hairstyle and facial + hairstyle now +2020-08-28: + EmeraldSundisk: + - rscadd: Adds more paper to the library + - rscadd: The law office now has a desk window + - tweak: Expands most of CogStation's exterior airlocks. Slightly adjusts surrounding + areas to accommodate this. + - tweak: Updates some of CogStation's paperwork + - tweak: The rat in the morgue turned themselves into a possum. Funniest shit I've + ever seen. + - bugfix: Adjusts some area designations so cameras should receive power properly + - bugfix: Cleans up an errant decal + Hatterhat: + - tweak: Traitor holoparasites can now only be bought once, because apparently you + can only have one active holopara. + - balance: PDA bombs can now only be bought once per uplink. + lolman360: + - rscadd: atmos = radiation = chemistry. + shellspeed1: + - rscadd: Adds slow mode for iv drips + timothyteakettle: + - rscadd: an ancient game over a thousand years old has re-emerged among crewmembers + - rock paper scissors + - tweak: customization features appear in alphabetical order where necessary + - tweak: bokken do two more stamina damage now + - rscadd: you can now choose a body sprite as an anthromorph or anthromorphic insect, + and can choose from aquatic/avian and apid respectively (and obviously back + to the defaults too) +2020-08-30: + raspy-on-osu: + - rscadd: new explosion echoes + - tweak: explosion echo range + - soundadd: 5 new explosion related sounds +2020-08-31: + Arturlang: + - tweak: Slimes can now damage structures, don't leave them unfed! + Chiirno: + - bugfix: Moves pill_bottles/dice to box/dice on CogStation. + Couls, ported by NecromancerAnne: + - code_imp: cleans up mech backstabbing code + DeltaFire15: + - rscdel: teleport-to-ark ability of the eminence, commented out + - rscadd: teleport-to-obelisk ability for the eminence + Detective-Google: + - tweak: plasmamen have no more slowdown + - rscadd: object reskins now use very nice and cool radials + EmeraldSundisk: + - rscadd: Adds a pool to MetaStation + - tweak: Slight readjustments to the surrounding area + - bugfix: Fixes a handful of external airlocks + ForrestWick: + - balance: removes wall walking boots from nukie uplink + - tweak: removes wall walking boots from nukie uplink + Ghommie: + - bugfix: e-gun overlays and some floor decals should have been fixed. + LetterN: + - rscadd: tgchat + Lynxless: + - tweak: Changed anatomic panacea into a direct buff, instead of a chem injection + - balance: Changed the values of anatomic panacea + - imageadd: Added a new icon for panacea's buff alert + Putnam3145: + - tweak: Pref for genital/vore examine text + - bugfix: Fixed a couple events having ghost roles eligible. + - balance: 'Buffed slaughter demon: gets stronger as it eats people' + - balance: 'Nerfed slaughter demon: no longer permanently round-removes all who + are eaten by it, instead releasing their now-heartless bodies' + - bugfix: Dynamic storytellers now calculate property weights properly. + Sonic121x: + - bugfix: Fix the four type of new tea that will stuck inside your vein. + - rscadd: drinking glass sprite for those tea. + kappa-sama: + - balance: miners can no longer acquire funny antag item + lolman360: + - bugfix: shuttle engine/heater sprites now face the right way + raspy-on-osu: + - tweak: TEG power output + - tweak: tesla movement priorities + - rscadd: tesla counterplay + - rscadd: tesla containment check (containment variable now usable) + silicons: + - bugfix: brooms now sweep objects on MOVABLE_PRE_MOVE rather than MOVABLE_MOVED + - balance: firedoors no longer automatically open on touch when there's no pressure + differences. + timothyteakettle: + - tweak: buzz, buzz2 and ping are now all unrestricted emotes and can be used by + anyone + - imagedel: the drake credit and pickle credit sprites have been removed + - refactor: tongue speech handling is now done by accent datums + zeroisthebiggay: + - rscdel: waffleco diff --git a/html/changelogs/archive/2020-09.yml b/html/changelogs/archive/2020-09.yml new file mode 100644 index 0000000000..35996bde59 --- /dev/null +++ b/html/changelogs/archive/2020-09.yml @@ -0,0 +1,222 @@ +2020-09-01: + BlueWildrose: + - bugfix: fixed slimes starting off hungry +2020-09-02: + Putnam3145: + - code_imp: Added a unit test for character saving. + - balance: Plastitanium rapier no longer silently sleeps with no chance at counterplay + when used by pacifists. + - bugfix: Fusion scan is now actually useful. + Tupinambis: + - tweak: moved the dakis, genital growth pills, and genital autosurgeons out of + the maintenance loot table and into kinkmates. + raspy-on-osu: + - bugfix: pyroclastic anomaly client spam + timothyteakettle: + - rscadd: you can hide your ckey now from the roundend report +2020-09-03: + Ghommie: + - bugfix: Jaunters should now work with magic mirror chasming. + - bugfix: The photocopier can now print more than one copy at a time. + - bugfix: Alkali perspiration infos don't crash the Pandemic UI anymore. + - bugfix: Windoors can be actually tinted now. +2020-09-04: + timothyteakettle: + - bugfix: ipcs can speak +2020-09-05: + Bhijn: + - rscadd: Readded the old method of temperature notifications in the form of a new + pair of shivering/sweating notifications. + Putnam3145: + - tweak: Hilbert hotel flavor text for one particular snowflake hotel changed. + - admin: admins can now actually reduce threat level in dynamic + - tweak: Made owo.ogg smaller. + - tweak: Character saving unit test is now more verbose on failure. + - refactor: Added an extools proc hook alternative to rust_g logging. + raspy-on-osu: + - tweak: supermatter shard examine text + - tweak: protolathe item categories +2020-09-06: + Putnam3145: + - rscdel: Dynamic no longer pushes events. + - balance: Made spontaneous brain trauma a good deal less annoying. + lolman360, NecromancerAnne: + - rscadd: The ancient art of blacksmithing, now in pixels. + - imageadd: cool swords and shit (thanks anne) + raspy-on-osu: + - tweak: thermomachine examine text +2020-09-07: + DeltaFire15: + - spellcheck: fixed a typo causing a span not to show. + Putnam for debugging ammo loading! Thx!!: + - rscdel: Removed spell blade, diamond picaxe, and fire wand from lava land loot + tables + - tweak: Each mini boss now has its own type of crate. + - tweak: Each spike has its own type of crate that it pulls its now smaller loot + table from + - balance: Moved god eye from spike loot table to hard spawn collosses fight + - balance: Moved holoparasight from spike loot table to bubble gum + - balance: Moved magic meat hook from spike loot table to drake + - rscadd: 2 more crates to Arena Shuttle as well as 4-4-4 of each new type of chest + - balance: Replaced the diamond pick loot with a better one + - tweak: Replaced the cursted katana with a non cursted verson that deals half the + damage and has less block! + - rscadd: Three new potions, blue heals the mind like a mama potion, Green heals + the soul aka the organs! Lastly Red heals the body, by 100 damage of each main + types. Best not to waste them! + - rscadd: Four more "wands" Spellbooks! These fun little guys shoot out its own + pages to do the affect, one will set the target on fire like a bullet, one will + harm them a bit, one will heal the target a small bit - How nice! Last one will + give them a few statis affects like a taser bolt but without as much power or + tasing affect +2020-09-08: + Ghommie: + - spellcheck: fixed names of the Electrical Toolbox goodie pack and green croptop + christmas suit. + - bugfix: Fixed turf visuals for real. Original PR by AnturK on tgstation. + KeRSedChaplain: + - soundadd: added borg_deathsound.ogg and android_scream.ogg + silicons: + - balance: meteor waves now have a static 5 minute timer. +2020-09-09: + Putnam3145: + - bugfix: Made superconductivity work for the first time literally ever. + timothyteakettle: + - bugfix: accents work better +2020-09-11: + Putnam3145: + - balance: Superconducting turfs now can't go below 0 celsius. +2020-09-12: + BlueWildrose: + - bugfix: The Polychromic winter coat's hoodie will now polychrome, alongside any + other new polychromic items with toggleable headwear. + - bugfix: Minesweeper will no longer blow up the player's ears when they select + "Play on the same board" + - rscadd: Slimepeople will find warm donk pockets among other toxin healing items + even more repulsive, as they are anti-toxic. + - tweak: Slimepeople are now neutral to gross foods. + DeltaFire15: + - balance: AIs can no longer qdel() the gravity generator + Putnam3145: + - code_imp: Added some unit tests for reactions. + - refactor: replaced handle_changeling and handle_bloodsucker with signal registration + Sonic121x: + - bugfix: Fixed pill button on chemical press + TheObserver-sys: + - rscadd: Brass now has a proper datum. Aspiring Forgetenders rejoice! + Trilbyspaceclone: + - bugfix: Race based drinks will no longer stay inside your blood for ever. + Tupinambis: + - tweak: Redid Cogstation atmos pipes to make it less cluttered. + - tweak: Removed a few doors from the main hallway to mitigate chokepoint issues + - bugfix: All belt hell conveyers are now on by default, so that belt hell actually + works. + - bugfix: IDs for poddoors and belts and the like. Everything is now properly hooked + and should work as expected (except for the pressure triggered mass drivers) + - bugfix: addresses most if not all roundstart active turfs. + - bugfix: Issue where wires were connected to the SMES improperly, and SMES were + not properly precharged, resulting in power failure earlier than intended. + - bugfix: various rogue turfs and wirings. + - bugfix: security office APC being hooked to maintenance for some reason. + - bugfix: TEG is now directly wired to the SMES. + - code_imp: 'adds a subtype of mass drivers that is triggered by things being on + it. TODO: Make these mass drivers trigger poddoors, to make belt hell fully + functional.' + lolman360: + - bugfix: glaives now work again + zeroisthebiggay: + - balance: Revolver is now poplocked down to fifteen people. +2020-09-16: + timothyteakettle: + - tweak: fixed an icon path +2020-09-17: + DeltaFire15: + - rscadd: Failing the plushmium reaction can now create peculiar plushies, depending + on reaction volume. + - bugfix: The mood-buff from petting a plushie now works properly again. + - bugfix: Fixed wacky necropolis loot chest behavior + EmeraldSundisk: + - rscadd: Adds the Research Director's office to Omega Station + - rscadd: Adds 2 new solar arrays (and control rooms) + - rscadd: Adds some action figures that weren't there previously + - rscadd: The CMO's office now has a light switch + - tweak: Slight readjustments to impacted areas + - tweak: Readjusts the toxins air supply line to (ideally) be easier to service + - bugfix: Department camera consoles should now be able to actually check appropriate + cameras + - bugfix: Xenobiology can now be locked down (by the Research Director) + MrJWhit: + - rscadd: Adds a brain damage line + Putnam3145: + - bugfix: Your balls finally feel full, again. + timothyteakettle: + - rscadd: due to changes in policy, and several lawsuits, Nanotrasen has been forced + to allow disabled people to sign up +2020-09-20: + DeltaFire15: + - bugfix: Sutures work on simplemobs again. + - bugfix: Attacking dismembered bodyparts now targets the chest instead, for weapons + aswell as unarmed attacks. + MrJWhit: + - rscadd: New sprites for chess pieces! You can craft them in-game with metal sheets. + silicons: + - balance: hulks can smash again (walls no longer break their hands) + - rscdel: acid no longer degrades armor +2020-09-22: + Arturlang: + - rscadd: TGUI Statpanel + YakumoChen: + - imageadd: Mechsuits, robotics jumpsuits added to RoboDrobe + timothyteakettle: + - tweak: character previews should be more consistent now +2020-09-24: + Putnam3145: + - refactor: Atmos is free. +2020-09-25: + Putnam3145: + - bugfix: Removed a non-working proc that already had its functionality implemented + in another proc in the same file. +2020-09-26: + CoreFlare: + - rscadd: IPC's can have hair. Why wasn't this added earlier. Use the bald hairstyle + for no hair. +2020-09-27: + SiliconMain: + - tweak: Holograms made from projectors (atmos, engi, sec, medical, ect...) can + no longer be contaminated by radiation +2020-09-28: + ArchieBeepBoop: + - rscadd: Craftable Micro Powered Fans + Degirin2120: + - rscadd: Added engineering hazard jumpsuits, can be found in the engidrobe, comes + in 3 varieties. + Putnam3145: + - tweak: Added a brute-force check-every-single-tile step to SSair when it has enough + time to run. + - balance: G fuid production is now much lower. + - rscdel: Supermatter sabotage objective's gone. + - balance: Subterfuge objectives are now all equally likely. + - spellcheck: Replaced a "(hopefully) 1" with a "2" + - tweak: Cryoing no longer unwins already-won objectives. + SiliconMain: + - tweak: Minor adjustment to material cost of long range atmos analyzer + Trilbyspaceclone: + - tweak: Most drinks now have some animation in them, from basic soda bubbles fizzing + around to ice cubes bobbing just a bit. + Tupinambis: + - bugfix: Ghost poly's color value is now a hex value instead of an oct value. This + has been a thing for OVER FIVE YEARS + - imageadd: Updates TEG, Antimatter, Jetpack sprites (CO2 and Oxy from Eris). + - imageadd: Replaced old chair sprites with new ones ported and modified from eris. + - tweak: Beds can now be placed both right and left. + - tweak: Subtle changes to stool legs to give them more of a shine. + raspy-on-osu: + - tweak: TEG power generation + thakyZ: + - rscadd: Added the ability to print the Light Replacer at the Engineering Protolathe + timothyteakettle: + - bugfix: turrets can once again be broken + - rscadd: you can now have heterochromia and select individual eye colours +2020-09-29: + timothyteakettle: + - bugfix: fixed a typo causing your right eye colour to save as the left eye colour diff --git a/html/changelogs/archive/2020-10.yml b/html/changelogs/archive/2020-10.yml new file mode 100644 index 0000000000..647724c0d5 --- /dev/null +++ b/html/changelogs/archive/2020-10.yml @@ -0,0 +1,112 @@ +2020-10-01: + BlueWildrose: + - soundadd: Slimepeople are given unique laughs and screams. + - tweak: Adds "warbles", "chimpers", and "puffs" to the customizable speech verbs + for character. +2020-10-02: + ArcaneMusic, with minor tweaks by TheObserver-sys: + - rscadd: Adds and modifies fertilizers, as well as a new stat, Instability. + - rscdel: Removes the rather disused functionality of irrigation hoses, temporarily + disables circuit use on hydroponics trays. + - tweak: Plant Analyzer have been upgraded. Using one in hand will now switch between + a stat view of your plant, and a chemical view of your plant. tweak:Trays now + accept and store reagents, as well as coming with an autogrow mode. However, + these upgrades came at the cost of old self sufficiency, meaning you must attend + to your plants a bit more often. + - tweak: Earthsblood, while not being able to gild trays anymore, has been found + to still be quite powerful as a fertilizer. + CoreFlare: + - rscadd: Altcloaks! Available in loadout. + Detective-Google: + - rscadd: a smattering of clothes from the RP server + - rscadd: detective wardrobe + EmeraldSundisk: + - rscadd: Adds the "Skelter" space ruin + - code_imp: Creates a few new area designations for the Skelter + - rscadd: Cargo techs now have access to a "long pants" variant of their standard + work uniform + - rscadd: Adds said uniform to CargoDrobes and the loadout menu + ItzGabby: + - rscadd: Three new turf tiles. + - imageadd: Turf icons with multiple damage icons, with in-hand icons for each tile. + - spellcheck: Edited the name and description to wooden. + LetterN: + - rscadd: craftable railings + - code_imp: ports robust savefiles + MrJWhit: + - tweak: tweaked heavy suit dmi + - bugfix: Fixes drones not being able to quickslot items + Putnam3145: + - rscadd: New policy config for pyroclastic slimes. + - tweak: SDGF clones now naked. + - balance: SDGF is now way more likely to make a clone that will align with the + creator's goals, with purity, making it a better antagging tool. + - bugfix: SDGF clones now have the same traits as the original. + - bugfix: transfer_ckey now resets view, preventing things like SDGF clones with + much larger view range. + - config: 'Policy configs have been added for SDGF, currently unused: SDGF, SDGF_ALIGNED, + SDGF_UNALIGNED.' + - bugfix: Shivering now has thresholds and fever's thresholds now work. + - bugfix: Made allturfs setup actually set up all turfs. + - balance: Dynamic is now more aggressive with adding antags. + - bugfix: Fixes vore pref saving. + SandPoot: + - bugfix: Fixes headslugs being unable to recover their human form. + Tupinambis: + - rscadd: Adds methane and methyl bromide gases. + - tweak: Minor gas name/desc changes to improve consistency + - imageadd: Ports the methyl bromide tank from bay. Adds two new canister sprites + for the new gases and CH4 screen alerts. + - bugfix: fixed a mispelling in the wound armor value for the bounty hunter suit + dapnee: + - rscadd: atrium, clinic, an extra office, a pseudo public mining area, two more + deluxe dorms, micro beach, aux bathroom, two construction areas, mass driver, + more intercoms + - tweak: moved all of service, chapel, dorms, garden, holodeck to a different z-level, + RnD is more open, maintenance is a bit more random, more firelocks, added more + mine-able rock + - bugfix: fixed the buttons in xenobio, gave shutters to cargo's storage area, fixed + holodeck so it works now, fixed some techfabs being lathes, added sensors to + atmos tanks, more decals, couple more signs, little floral areas and sitting + areas added to break up hallway monotony, mech chargers are no longer missing + their consoles, whiteship won't crash into arrivals anymore while the area it + takes up is more telegraphed, APC placement on AI sat entrance, missing wire + node for the outer portion of the AI sat, civilian level now has a telecom relay + lolman360: + - bugfix: smonk machine runtimes + - bugfix: automatic hydro tray has a unique sprite now (fancy robot arm) + timothyteakettle: + - rscadd: added luminescent and stargazer sprites as selectable body sprites for + slimes + - tweak: wound exponent lowered slightly from 1.225 to 1.2 + - config: wound exponent and limb damage multiplier are now config values + - rscadd: ipcs and synthlizards are now treated as actual robots, with robotic limbs, + an extra organ, and better emp acts + - rscadd: surgeries for healing robotic limbs, and brain surgery for robotic heads + - bugfix: androids limbs now show up as intended + - refactor: emps now work from 1-100 severity instead of 1/2 and the severity reduces + as you move from the epicentre + zeroisthebiggay: + - rscadd: ratvar gf is complete +2020-10-04: + DeltaFire15: + - bugfix: Synths / IPCs are no longer wound immune. + - bugfix: Husked IPCs / Synths should now be rendered correctly. + - bugfix: Falling vendors now squish synths / IPCs' limbs again. + - bugfix: Synths and IPCs now do not have some fun roundstart oversights anymore. + - bugfix: Regenerate_limbs now works for carbons with the ROBOTIC_LIMBS trait. + - bugfix: Pacifists no longer counterattack on parries if that attack would be harmful. + - tweak: Heretic sacrifices now husk with the reason of burn, and deal some additional + damage. + - bugfix: Neovgre can no longer become invincible on clock tiles. + - bugfix: Plushlings no longer break when absorbing snowflake plushies. + Detective-Google: + - bugfix: the snow cabin doors actually bolt now + Putnam3145: + - bugfix: Ghosts are no longer incapable of going away. + monster860: + - tweak: The slimeperson swap-body UI stays open when you switch bodies + timothyteakettle: + - bugfix: limb id entry in mutant bodyparts now supports switching to/from species + with gendered body parts + - tweak: the minimum brightness of mutant parts is now a define diff --git a/html/changelogs/archive/2021-01.yml b/html/changelogs/archive/2021-01.yml new file mode 100644 index 0000000000..2a82c3ebbf --- /dev/null +++ b/html/changelogs/archive/2021-01.yml @@ -0,0 +1,837 @@ +2021-01-21: + Acer202: + - bugfix: Main mining shuttle should no longer look at the public mining shuttle + and attempt to dock ontop of it. Monastery shuttle should now function again. + Acer202, with minor help from The0bserver: + - rscadd: After internal deliberation, CentCom has decided to run a limited reinstatement + of public mining shuttles for use in more tried and true station classes. CentCom + would like to remind you that this privilege is easily revoked, and that abuse + may result in immediate detonation. + - rscadd: Restores the mining shuttle on Pubby, Box, Delta, Meta, and Lambda Station. + ArcaneMusic, The0bserver-sys: + - rscadd: 'New from Hydrowear LLC: The Botanical Belt! This handy yellow belt lets + you hold most of your botany gear, and a few beakers for reduced bag and floor + clutter!' + - tweak: Gives Hydrotrays plumbing pipes automatically, allowing you to make a self + sustaining tray via plumbing. + - tweak: Gives Service access to Bluespace Beakers, at last, gives Cargo, Science, + and Medical the ability to construct reinforced plungers for use on lavaland. + ArchieBeepBoop: + - rscadd: Upgraded Advanced RTG Machine Preset + - bugfix: Outlet Injector Mapping Asset Layer Fix + - bugfix: Jacqueen and the Christmas tree should no longer spawn abstract things + that can cause shittons of runtimes. + Arturlang: + - bugfix: You can't tackle in nograv anymore + - tweak: You cannot spam drink from blood bags anymore + - bugfix: Blood bag drinking inefficiency is now the right way, so you loose some + of the blood drinking it straight + - bugfix: Handles more edge cases with construct soul returning + - tweak: Being sacrificed by the cult no longer removes all hope of rescue. + - bugfix: Makes construct mind returning more robust + - tweak: Prayers to admins now do a wee ding sound for all prayers, instead of just + chaplains + - bugfix: Fixes the mint machine's UI + - bugfix: Hopefully fixes whitescreen issues for TGUI UI's by giving assets more + time to get to the client + - bugfix: Fixes hijack implant APC UI, again + - code_imp: Comments out spaceman dmm do not sleeps for mob/proc/CommonClickOn, + atom/proc/attack_hand, datum/proc/keyLoop and mob/living/proc/Life + - bugfix: Bloodsuckers tresspass ability can no longer work while they are not awake. + - tweak: The cursed heart now only takes away half as much blood every loop, and + can be used as long as you are alive, instead if only you are awake/able to + use your hands + Bhijn: + - tweak: Changeling loudness is now determined as an average of all their abilities, + rather than the sum + - tweak: To compensate for this, blood tests now require a loudness value of 1 or + higher to detect ling blood. Additionally, blood test explosions are now triggered + only when the loudness value is higher than 2. + BlackMajor: + - tweak: Cyborg hypospray no longer injects if it means OD'ing while on help intent. + BlueWildrose: + - tweak: Nyctophobia quirk now has some light lag compensation. + - bugfix: Fixes cloning computer UI not updating when pressing certain buttons - + also adds extra check for names to update a message + - rscdel: Removes oversized genitalia analysis from medical scanners, since huge + dick and titty are no longer a problem anymore thanks to advancements in that + kind of technology when it comes to chemical fun times growth. + - bugfix: Fixed species-specific drinks not giving a mood boost if you are that + species. + - tweak: You will now only unbuckle fireman-carried/piggybacked people on disarm + or harm intent. + - balance: The traitor AI can no longer activate the doomsday device while carded. + - bugfix: Fixes noodle size appearance for 12+ inch members. + - bugfix: Fixed the subtle hotkey being weird with its input prompts. + - rscadd: Adds a subtler anti-ghost hotkey. Default key is 6. + - tweak: No more straining when your cock or breasts are growing via incubus draft + or succubus milk. + - rscadd: PubbyStation now has two Christmas Tree spawners. + - tweak: You can now have a max-roundstart-dicksize-config inch long johnson before + you start suffering blood loss and slowdowns instead of a 20 inch one. + - rscadd: Color Mates have been added to all stations (except Snaxi). Enjoy coloring + your attire without having to bug science! + - bugfix: Polychromic hoodies that were obtained from the loadout have functional + colorable hoods now. + - rscadd: Adds in timid woman/man costumes. Available at your autodrobe! Also adds + in garters as some new socks. + - spellcheck: Corrected the capitalization in gasmask concealment examine text + Chiirno: + - rscadd: Added the paramedics EVA suit as a purchase from the cargo console. + - rscadd: Paramedics office and Surgery Storage Room + - tweak: Remodeled the surgery room, as well as shrunk Morgue and Starboard Emergency + Storage. Fiddled with some areas for better map edit clarity and fixed one runtime + in Vacant Office A. + - imageadd: Added the paramedic closet sprite, a paramedic colored medical3 closet. + - code_imp: Added a paramedic closet, which is the standard medical3 closet with + their suit, a pinpointer, and a crew monitor added. + - tweak: Nightmare now deals additional damage to most light sources. + - bugfix: Nightmare now one-shots miners beacons and glowshrooms + - bugfix: Portable Chem Mixer now researchable from biotech node. + - tweak: Chem masters can now dispense 20 instances of its outputs instead of 10. + Delams-The-SM: + - rscadd: Added 3 new emotes *hiss *purr *meow + - soundadd: ported sounds from Citadel RP for *purr and *meow + - bugfix: fixed randomization of colors for things like mulligan and Stabilized + green slime extract for matrixed body parts + DeltaFire15: + - balance: Biomechanical (hybrid) bodyparts now have access to wound-fixing surgeries. + - tweak: A wound being fixed no longer just qdel()s surgeries connected to it. + - tweak: Some robotic surgery steps are now a bit more clear. + - bugfix: Organs no longer get fed to people after successfully being inserted into + them. + - tweak: Not completing the do_after of a surgery no longer causes you to attack + the target with whatever you were holding. + - rscadd: IPC cells & power cords are now printable after they are researched. + - rscadd: A new surgery, allowing revival of synths without a defib at hand. + - balance: 'Semi-permanent damage of Synth limbs caused by passing the damage threshold: + 10 <- 15.' + - tweak: The embed removal surgery now has a version for Synths. + - balance: EMPs no longer hardstun Synths. + - bugfix: Portals no longer runtime because of incorrect args. + - tweak: Abductors now can use experimental organ replacement surgery on robots + / synthetics. + - bugfix: Fixes a minor incorrectness in ratvarian borg slabs (ratvar_act -> ui_act) + - bugfix: Changelings no longer double-deathgasp when activating the regen stasis + ability while not dead. + - bugfix: People installing KA modkits in miner borgs is no longer broken. + - bugfix: Fixes the tail entwine messages displaying incorrectly. + - bugfix: Antagging / Deantagging Heretics now properly sets their special role. + - bugfix: The borg VTEC ability now actually gets removed when the upgrade is removed. + - bugfix: Supplypods shouldn't cause runtimes anymore, and shrapnel (pelletclouds) + should work for them. + - rscadd: Robots (anyone with the robotic_organism trait) have toxins damage replaced + with system corruption. See the PR for details. + - code_imp: Clockwork rites now support hiding specific rites from neutered servants. + - tweak: AIs now only have to kill people once instead of permanently. + - bugfix: Scripture no longer sometimes eats part of its invocation. + - balance: APCs and silicons are now more susceptible to powerdrains (by the power_drain() + proc, which is rare) + - balance: Void Volt has been modified from a chant to a singular pulse. + - balance: Robotpeople are now fully immune to the effects of alcohol (drunkness + etc.) + - tweak: Renames the alcohol intolerance trait in the code to make what it does + more clear. + - bugfix: Self-fueling weldingtools recharge fuel properly again. + - bugfix: Brass welders now actually recharge faster than experimental ones. + - bugfix: Repeatable surgery steps can no longer cause an infinite loop if not completing + the do_after + - bugfix: The Revenant self-revive ability is no longer broken. + - bugfix: Loot items mobs drop are no longer always failing to initialize. + - tweak: Instant summons can no longer do wacky stuff with disposals (and nukes). + - bugfix: Objectives are no longer very broken. + - bugfix: Bloodcult stunhands now work against clockies like they were supposed + to instead of hardstunning. + - balance: zeolites are now actual fermichems instead of being incredibly easy to + make. + - bugfix: Using syringes / droppers on chem heaters with beakers in them works again. + - bugfix: Some edge cases causing issues with system corruption shouldn't be able + to occur anymore. + - bugfix: Cyborg B.o.r.i.s. installation now checks for if the chest has a cell, + just like how it does with MMIs. + - bugfix: The 'Your body is in a cloner' notification works again + - bugfix: Hijack implants should work properly again (or, at least better) + - bugfix: Liches are now good skeletons again instead of weak ones + - bugfix: The piratepad control cannot be destroyed again. + - bugfix: Pirates have received new supplies of jetpacks instead of useless oxygen + tanks + - bugfix: Ratvarian AIs are once again able to show their linked borgs Ratvar's + light + - bugfix: Hijackers are once again unable to detonate borgs without being adjacent + to the console + - bugfix: Automated annoucement systems and gulag ore consoles no longer waste emag + charges + - bugfix: Automated announcement systems once again can be remote controlled by + non-AIs with silicon access + - bugfix: APCs being hijacked multiple times at once is no longer possible, preventing + some issues + - bugfix: Recharging APCs no longer use 0.2% of the power they should be using. + - bugfix: APCs no longer always use as much power as they can for their cell, even + if it is full. + - bugfix: Vampire shapeshifting should now behave as intended + - balance: Some synth damage stuff has been a bit rebalanced, see the PR for details. + - rscadd: Nanogel, available at medical and robotics, which fixes internal damage + in sufficiently repaired robotic limbs. + - balance: Robotic Limbs now each have their own damage threshhold values + - balance: Robotic Limb damage threshholds are now seperated into threshhold itself + and mindamage when passed balance; Hybrid limbs can now be injected with hypos, + but not sprayed (Still not healed by chems) + - tweak: Brain surgery has been tweaked back to allowing robotic limbs, blacklisting + IPC brains instead. + - tweak: Robot brain surgery can now be used on organic heads, if there is a IPC + brain in them somehow. + - tweak: The robot limb heal surgery can now be used even if the target's torso + is not robotic, as long as they have robotic limbs + - refactor: BODYPART_ROBOTIC / BODYPART_ORGANIC checks replaced with helper-procs + whereever possible. + - code_imp: Added a BODYPART_HYBRID define for robotic bodyparts that behave organic + in some regards. + - bugfix: The transmission sigil power drain works now + - bugfix: A certain lizard (totally not me) being stupid is no longer going to break + regenerate_bodyparts + - bugfix: Combat mode now will not stay permanently disabled due to status effects + not working as intended. + - bugfix: Attacking some certain objects no longer has no clickdelay. + - bugfix: the blacksmithing skill now works properly + - tweak: Anvils cannot be interacted with with hammers whilst they are already being + used + - tweak: If someone has no gloves when interacting with heated ingots, they no longer + ignore their effects. + - bugfix: A runtime caused by hallucinations is gone. + - bugfix: Cargo packs marked as 'no private buying' now actually register as such. + - balance: Fleshmend, Anatomic Panacea and bloodsucker healing now work for Synths + / IPCs. + - tweak: Medibots now ignore people they cannot help due to their biology. + - bugfix: get_damaged_bodyparts() is no longer broken. + - bugfix: Your target cryoing will no longer give you a free greentext. + - bugfix: Sleeper UI interactiveness now behaves correctly. + Detective-Google: + - rscadd: arcade carpet + - rscadd: explosions now get broadcasted to deadchat. + - rscadd: Lick radial + - bugfix: Hilbert's jukebox works + - bugfix: arcade carpets now actually work + - tweak: the snow taxi is no longer the slow taxi + ERP mains: + - rscadd: Subtler Around Table is now a verb + EdgeLordExe, MoonFalcon: + - balance: Ported a bunch of heretic-related tweaks and changes from tg + EmeraldSundisk: + - rscadd: Adds a few new area designations primarily for CogStation, incorporates + them into said map + - tweak: Reorganizes some area designations for ease of use, along with renaming + the central "Router" to "Routing Depot" + - bugfix: Fixes an incorrectly designated area in CogStation + - bugfix: Changes the area designations to be not varedited since the code didn't + like that anymore + - bugfix: The cargo bay conveyor belts not only work with the shuttle now but go + in the right direction to boot + - tweak: Slight visual adjustments to cargo in light of this + - rscadd: The arcade's got RAD carpet now + - bugfix: Fixes the conveyor belt issues in Delta Station's cargo wing + - rscdel: Removes some of the dirt around the affected area (presumably they would + have cleaned it up while working on it) + - rscadd: Adds a floor light to fix the "dark spot" cargo had + - rscadd: Adds a new "Computer Core" area designation for CogStation + - bugfix: Fixes some missing area strings + - tweak: Replaces some firelocks with directional ones as to ensure desks/counters + can still be accessed + - balance: The "Skelter ruin" now has stechkins as opposed to M1911s + - tweak: Skelter's decorative bullet casings replaced to factor in the change in + caliber + - rscadd: Skelter now has a combat knife and fluff note + Ghommie: + - bugfix: You can access the mime / clown mask skins radial menu once again. + - bugfix: Dice bags no longer act like cardboard boxes. + - bugfix: Abductors should be no longer mute. + - bugfix: Item action buttons should now properly show the item current overlays, + most times. + - bugfix: The blackbox should now go into your hand slot when pried out, rather + than tumbling on the ground everytime. + - tweak: The Quick Equip hotkey is now usable by all living mobs (so long they have + hands and equipment slots) + Ghommie, porting PRs by MMMiracles and pireamaineach, credits to BlueWildrose too.: + - rscadd: You can now draw on plasmaman helmets with a crayon to turn their frown + upside-down. + - balance: Plasmaman helmets no longer hide your identity when worn by themselves. + - balance: Plasmaman helmets now have welding visors, which can't stack with their + torches in the helmet and are visible. + Hatterhat: + - rscadd: Energy sabre reskin for the energy sword - access via alt-click. + - bugfix: Alt-click reskins are fixed. + - tweak: Defibrillators and their many, many overlays were moved to another .dmi. + - tweak: You can now change the color of an energy sword via multitool. Not deswords. + Yet. + - imageadd: The Syndicate appear to be issuing new revolver variants. + - rscadd: Basic sticky technology is now a roundstart tech. Advanced sticky technology + is BEPIS-locked, though. Theoretically. + - tweak: Non-smithed katanas (including the temporal katana) can now fit in the + twin sheath. + - tweak: Cotton and durathread processing by hand now acts like grass. Stand on + a pile of cotton (or durathread) and use a single bundle from it. + - spellcheck: Utility uniforms now comply with the "nonproper equipment names" thing. + - bugfix: The CapDrobe now allows the captain to get his own clothes for free. Probably. + - tweak: All captains' clothes now offer 15 woundarmor, up from the 5. Because apparently + only the suit and tie and its suitskirt subtype have this wound armor, which + is dumb. + - rscadd: The nature interaction shuttle with the monkeys now has tiny fans on the + airlocks in, because that's apparently a feature that was missing. + - rscadd: More bags have been added to department vendors. + - balance: Every roundstart species (and also ash walkers) now has flesh and bone + that can be wounded. + - balance: Recipes for sutures, regen mesh, and sterilized gauze have been adjusted + to be easier, mostly. + - balance: Sterilized gauze is better at absorbing blood and being a splint. + - bugfix: Energy sabres now have an off inhand. + - balance: The bone gauntlets should be slightly less murderously punchy on the + fast punches mode. + - tweak: RPEDs now drop their lowest part tier first when quick-emptied (used inhand). + - tweak: Improvised gauzes can now be crafted in stacks up to 10, like their maximum + stacksize implies they should be capable of doing. + - bugfix: Pouring sterilizine on gauze now takes the proper 5u per sterilized gauze + instead of 10u. + - bugfix: Cryogenics now screams on common again when your fuckbuddy heads out. + - rscadd: Survival daggers! A slightly more expensive survival knife that comes + with a brighter flashlight. On the blade. + - tweak: Luxury pod capsules look different from normal capsules. + - rscadd: The wastes of Lavaland and the icy caverns of Snow Taxi rumble in unison. + - tweak: Exosuits sold on the Supply shuttle no longer leave wreckages. + - rscdel: Apparently, shrink rays were buyable again, despite a PR having been made + a while ago specifically for removing shrink rays. They're gone again. + - rscadd: Changeling bone gauntlets! They punch the shit out of people really good. + - tweak: Guerilla gloves and gorilla gloves inherit the strip modifiers of their + predecessors, because apparently they had those. + - balance: Pugilists now always hit the targeted limb and never miss. + - rscadd: The dock-silver standard set by Box and Meta has been enforced across + maps in rotation (Delta, Pubby, Lambda). + - bugfix: The Box whiteship now has its missing tiny fan back. + - bugfix: The survival dagger light on the sprite now actually turns on and off. + - balance: The survival dagger in the glaive kit that can also be bought by itself + is now better at butchering things. + HeroWithYay: + - bugfix: Changed description of Necrotizing Fasciitis symptom. + - tweak: Wormhole Projector and Gravity Gun now require anomaly cores to function + instead of firing pins. + KeRSedChaplain: + - imageadd: Resprited the brass claw + LetterN: + - rscadd: 2 more ways to get up from z1 + - tweak: tweaked the z2 garden to be less blank + - bugfix: fixed telecomms pda log + - rscadd: Coin & Holochip support for slot machine + - admin: Stickybans are now saved in the DB too + - soundadd: Immersive ™ audio reverbs. (also adds multiz audio) + - code_imp: Semi-hardsync from TG + - code_imp: Updates rust-g + - code_imp: Uses git CI instead of travis/appveyor now + - code_imp: Updates git and build tests. + - bugfix: minimap text + - code_imp: ports cinematic upgrades + Linzolle: + - bugfix: entertainment monitors no longer invisible + - rscadd: entertainment monitors now light up and display text when motion is detected + in thunderdome + - bugfix: lizard snouts are no longer *slightly* lighter than they are supposed + to be. + MrJWhit: + - rscadd: Expanded space hermit base + - tweak: Replaced engineering fuel tank with a large fuel tank + - tweak: Changed access to sec suit storage from armory access in every map to other + security access + - rscadd: Adds a space loop to every map in toxins + - rscadd: '' + - tweak: Added the ability for cargo to buy a large welding tank + - imageadd: Tweaked large tank reagent sprites to /tg/'s + - tweak: Gives metastation toxins storage a scrubber and a vent + - tweak: Updates suit storage info on Tip Of the Round. + - tweak: Increased christmas event from 22th to 27th to 10th to 27th + - tweak: Removes an opposum from the wall + - tweak: Donut boxes show what's inside of them now + - tweak: Updated meat icons + - admin: Canceling events gives more time to stop from 10 to 30 + - tweak: Fixes two chairs on one table + - tweak: Removed the wires connecting the AI from the rest of the station on cogstation. + - tweak: Fixes experimenter on cogstation. + - tweak: Less pipes in the overall area in toxins on cogstation + - tweak: Small fixes on security on boxstation + - tweak: Updated jukebox sprite. + - tweak: Fixes maint area in boxstation + - tweak: Christmas starts on the 18th now + - rscadd: Adds a goose bar sign + - bugfix: Effects can no longer trigger landmines + - rscdel: Removes the screen flashing on climax. + - rscadd: Makes gas sensors fireproof. + - tweak: A small bucket of random fixes, + - tweak: Minor fixes to kilo + - tweak: Porting garbage collection tweak from /tg/ + - tweak: Updates our dark gygax sprites to /tg/'s + - tweak: Bugfix of a morph becoming an AI eye + - tweak: Mining station oxygen locker on the cycling airlock starts out wrenched. + - balance: Nerf combat knife damage + - bugfix: Code improvement on ventcrawling + NT Cleaning Crews On Break: + - rscadd: Most kinds of dirt, grime, and debris are now persistent. Get to work, + jannies. + - rscadd: Dirt can now be removed by tile replacements. Other cleanable decals can't, + though. + Putnam3145: + - tweak: Replaces majority judgement with usual judgement. + - bugfix: Toilet loot spawners don't lag the server on server start with forced + hard dels. + - bugfix: vore prefs save now + - tweak: gear harness no longer magically covers up the body mechanically despite + covering up nothing visually + - balance: Regen coma now puts into a coma even from crit or while unconscious. + - bugfix: Regen coma now properly weakens while asleep. + - bugfix: Multi-surgery unit test no longer fails at random. + - refactor: Dwarf speech is no longer absolutely paranoid about word replacement. + - balance: Spontaneous brain trauma now requires minimum 5 players + - tweak: Grab bag works as advertised. + - balance: Xeno threat in dynamic tripled. + - code_imp: 'Vote system #defines are now strings' + - rscadd: Stat panel UI for ranked choice votes + - rscadd: A fallback for dynamic antag rolling that allows for it to just try between + traitor, blood brothers, heretics, changeling, bloodsucker and devil until there + are enough roundstart antags. This can also happen randomly anyway. Blood brothers + and devil are disabled for now, but the code is there to enable them. + - rscadd: A new storyteller, "Grab Bag", that forces the above round type. + - bugfix: atmos subsystem no longer dies if there's too many gases + - bugfix: Emotes can properly be filtered for in TGUI. + - bugfix: Holofirelocks work now. + - bugfix: adminhelping no longer removes entire admin tab + - bugfix: end of round no longer removes entire admin tab + - bugfix: Fixed a runtime in every healing nanite program. + - bugfix: removed a unit test causing master to fail + - tweak: Planetary atmos no longer does superconduction. + - bugfix: Dynamic vote no longer shows the none-storyteller. + - tweak: You can now exit polycircuit input + - bugfix: Polycircuits now check for range + - bugfix: gear harness alt-click is now sane + - code_imp: rolldown() and toggle_jumpsuit_adjust() now no longer mix behavior-that-should-be-overridden + and behavior-that-shouldn't-be-overridden in ways that make no sense. + - tweak: Gear harness now covers nothing. + - bugfix: Chemical stuff now displays fermichem stuff properly + - balance: Rad collectors now get 1.25x as much energy from radiation + - balance: Rad collectors now put out 1.25x as much stored energy per tick + - balance: Above two rad collector changes give a total 56.25% power output increase + - balance: Zeolites now only generate 1/5 the heat when reacting and don't require + a catalyst. + Ryll/Shaps: + - admin: Fixed an issue with player logs becoming confused when someone triggers + multiple events within one second (like being attacked by two people at the + same time) that would cause holes in the logs + SandPoot: + - tweak: You can attack a pile of money on the floor with your id to put it all + in quickly. + - refactor: Changes the limb grower a lot. + - bugfix: '"Limb" costs on limbgrower are actually displayed like it was meant to + all along.' + - code_imp: Swaps the gift static blacklist with a global list one. + SiliconMain: + - tweak: Engi department has gas masks in loadout + - tweak: hololocks (which haven't worked for god knows how long) commented out until + auxmos is merged + Sonic121x: + - rscadd: alarm ert hardsuit sprite for naga and canine + - tweak: adjust the naga ert hardsuit to cover the hand + - bugfix: cydonia hardsuit helmet + - rscadd: digi sprite uniform + - bugfix: digi leg suit + SpaceManiac: + - bugfix: Fixed the maphook + Thalpy: + - bugfix: fixes some bugs in jacqs code from edits to the codebase + The Grinch: + - rscdel: infinite presents from hilbert hotel + TheObserver: + - rscadd: Re-adds the rifle stock, and sets the improv shotgun to be as it was. + - rscdel: The maintenance rifle has been shelved - for now. Watch this space. + TheObserver-sys: + - bugfix: Drake? Where's the dead fairygrass sprite? + TheSpaghetti: + - bugfix: no more tumor bread double punctuation + Trilbyspaceclone: + - tweak: Zeolites now use gold rather then uranium for catalyst + - tweak: Zeolites are not as hard to make ph wise + - tweak: Making Zeolites heats up the beaker less allowing for better control + - tweak: ASP 9mm and M1911 can now have suppressers added + - balance: Brass welders are 50% faster at refueling + - code_imp: redoes self fueling welders in the code to be less speggie + - rscadd: the corporate unifoms can now be gotton in the clothing mate vender + TripleShades: + - rscadd: 'Firelock to Surgery Bay drapes change: Swapped Nanomed and Fire Alarm + button locations in both Surgery Bays change: Removes the double mirror in both + Surgery Bays to be a singular mirror change: Moved an intercom to not be doorstuck + below Paramedical Office remove: One Surgery Observation Fire Alarm button' + - rscadd: 'New Paramedic Office next to Genetics where the old Genetics Reception + used to be change: Surgery, Surgery Observation, and Recovery Hall layout revamped + drastically change: Maints below Surgery lowered by one tile to recover lost + tile space from Surgery expansion' + Tupinambis: + - rscadd: Arachnids (spider people) with limited night vision, flash vulnerability, + and webbing. + Vynzill: + - rscadd: 'new gateway mission mapadd: jungleresort map' + - bugfix: fixes high luminosity eyes + Xantholne: + - bugfix: Fixed new birds changing back to basic parrot when sitting + - rscadd: New parrots from the RP server, can be found in Bird Crate in Cargo + - rscadd: You can now tuck disky into bed + - rscadd: You can now make beds by applying a bed sheet to them + - rscadd: You can now tuck in pai cards into bed + - rscadd: Added bed tucking element, can be added to any held object to allow tucking + into beds + - bugfix: Twin Sword Sheaths have an equipment icon and icon when worn now and make + a sound when sheathed/unsheathed + Yakumo Chen: + - balance: Slime Jelly is no longer obtainable from slimepeople. Go ask Xenobio + YakumoChen: + - balance: "To lower production costs, Buzz Fuzz is now manufactured with Real\u2122\ + \uFE0F Synthetic honey." + Zandario: + - code_imp: Added some framework for future species expansions, including clothing + refitting. + - refactor: Made majority of the relevant Species IDs and Categories pre-defined, + also for easier expansion and use. + - bugfix: lum slime sprites work again + - code_imp: Slapped the Species Defines where relevant + corin9090: + - tweak: The chaplain's prayer beads can now be worn on your belt slot + kappa-sama: + - bugfix: super saiyan + - tweak: ishotgun crafting recipe no longer requires plasteel and is slightly more + convenient + - balance: ishotgun does 45 damage now instead of 40.5 + - rscadd: s + - tweak: s + - balance: s + - bugfix: s + - rscadd: A new spell for the wizard and his martial apprentices, the Inner Mantra + technique. It makes you punch people really good and makes you durable, but + drains your energy while it's active. + - rscadd: A self-buffing spell for valiant bubblegum slayers that is ultimately + useless on lavaland and probably overpowered for miner antagonists. Go figure. + At least all it does is let you punch hard while draining your health every + second. + - balance: bubblegum now drops a book that makes you into an abusive father instead + of a shotgun that plays like pre-nerf shotguns + - soundadd: a powerup and powerdown sound effect + - imageadd: two icons for two buff spells + keronshb: + - bugfix: Allows Energy Bola to be caught + - balance: This also allows them to be dropped/picked up. + - rscadd: Adds a reduced stamina buffer for SCarp users + - rscadd: Gives SCarp users a better parry + - rscadd: Adds the SCarp bundle which includes a bo staff + - rscadd: Lets Carp costumes carry Bo Staffs + - balance: reduces the stamina damage of scarp slightly + - balance: reduced the blockchance of the bo staff + - rscadd: Adds more room to northwest maint + - rscadd: Adds a bridge between Atmos and the Turbine. + - balance: Blob Resource Tower to 2 points per instead of 1 point per. + - balance: Blob Factory Towers can be placed 5 tiles apart instead of 7. + - bugfix: Fixes Blobbernaut Factories consuming Factories if no naut is chosen. + - bugfix: Fixes Reflective Blobs + - rscadd: Re-adds the Clown Car to the clown uplink + - balance: 15 >16 TC cost + - balance: bonks on external airlocks + - bugfix: Fixes the parry data for scarp + kittycat2002: + - rscadd: set the name of /datum/reagent/consumable/ethanol/species_drink to Species + Drink + kiwedespars: + - balance: balanced bone gauntlets. + - rscadd: the robust dildo weapon now has sound. + necromanceranne: + - bugfix: Fixes various sprites for bokken, as well as being unable to craft certain + parts and duplicate entries. + - rscadd: 'Bokken now come in two lengths; full and wakizashi, and two varieties: + wood and ironwood. They have different stats for all four.' + - rscadd: Bokken require menu crafting and part construction, as well as more complicated + materials. + - tweak: Bokken (long and short) require wood, cloth and leather to craft with a + hatchet and screwdriver. + - tweak: Ironwood bokken (long and short) require ironcap logs, cloth and leather + to craft with a hatchet, screwdriver and welder. + - balance: Twin sheathes can only fit a pair of blades (longsword + shortsword) + or they can fit two shortswords. + - bugfix: Fixed a twin sheath runtime. + - imageadd: A lot of bokken related sprites received an overhaul. Added overlay + sprites for weapons sheathed in the twin sheathes. + - imageadd: The extradimensional blade received improved sprites for inhands/back + sprites. + - bugfix: You can now make all the variants of the bokken. + - bugfix: Removes a duplicate sprite. + - tweak: Renames all instances of 'ironwood' to 'steelwood'. + - rscadd: Adds new roboticist labcoat sprites! + qwertyquerty: + - bugfix: Flash the screen on climax + raspy-on-osu: + - spellcheck: salicylic acid + - tweak: space heater heating range and power + - tweak: windoor open length + shellspeed1: + - rscadd: Wings from Cit RP have been ported over + - rscadd: Moth wings from cit have been ported over + - bugfix: Cleaned up some pixels on existing moth wings. + - tweak: Organized the lists for wings by if they are for moths or not and than + by alphabetical. + - balance: Lings now have infinite space for DNA. + - rscadd: All xenomorph types have been added as corpses for mapping purposes + - balance: The dead xenomorphs in the lavaland xenomorph hive now have more variety. + - tweak: Floor bots are now buildable with all toolboxes. + - rscadd: 'Xenomorph hybrids can now select wings ~~add: Xenomorph hybrids can now + speak xenomorph~~' + - rscadd: Xenomorph tongues are available for customization. + - rscadd: Mining borgs can claim points again + - rscadd: Construction bags have been added, use them to carry all sorts of construction + bits. + - rscadd: A recipe has been added to cloth stacks to make material and construction + bags. + - balance: Material bags and construction bags are now available in engineering + lockers. + - rscadd: Adds the disposable sentry gun from tg for 11tc each. + - rscadd: The exofab can now print prosthetic limbs + - bugfix: The exofab was missing access to multiple cybernetic organs. This has + now been rectified. + - rscadd: A new recipe for a spicy has been given to us by a strange business man. + - rscadd: The bluespace navigation gigabeacon design has been added to shuttle research + for those wanting to take their ships around space more. + - tweak: Xenomorph powers now list plasma cost in their description. + silicons: + - tweak: nanite resistances tweaked + - rscadd: new nanite programs added for locking the user out from being modified + by consoles or antivirals. + - rscdel: anomalies no longer spawn in walls + - rscadd: 'Twitch Plays: Clown Car' + - rscadd: pugilists can now parry + - balance: c4 can no longer gib mobs + - tweak: medium screens are better now + - tweak: text formatting now uses one character instead of two around the text to + emphasize. + - rscadd: colormates + - balance: shoving yourself up now costs 50% more + - bugfix: dullahans enabled + - rscadd: tailed individuals can now target groin to intertwine tails on grab intent. + - rscadd: Clowns now have unpredictable effects on supermatter crystals when dusting + from contact. + - tweak: anyone new to the server is lucky enough to have their sprint default to + toggle instead of hold + - balance: stamina crit is only removed when at or under 100 stamina, rather than + 140. stamina crit threshold is still at 140. + - tweak: luxury shuttle no longer has noteleport + - rscdel: now only poly gets a headset on spawn, not all birds. + - tweak: the warp implant now actually warps you back 10 seconds. leaves a trail, + though. now unlimited us. + - bugfix: things in DEATHCOMA do not deathgasp on death + - tweak: Meth and changeling adrenals no longer ignore all slowdowns, rather damage + slowdowns. + - rscadd: you can now be an angel using a magic mirror again + - tweak: command headsets are 120% instead of 160% + - bugfix: no more emote italics + - rscadd: players can now respawn/return to lobby as a ghost after a 15 minute (default) + delay and rejoin on another character with some/many restrictions + - rscadd: cryo now preserves everything + - bugfix: Magrifle ammo no longer glows. + - tweak: temperature slowdown divisor nerfed to 35 from 20. + - balance: dna melt drops all items being destroying you + - bugfix: keybinds generate anti-collision bindings where necessary automatically + now + - balance: changeling combat mutations rebalanced. most of them take chemicals to + upkeep now. + - rscadd: set-pose has been added + - tweak: temporary flavor text renamed to set pose, fully visible in examine + - bugfix: ninja gloves no longer hardstun + - balance: ninja gloves now cost half as much to use to compensate + - bugfix: simple mobs are now immune to radioactive contamination + timothyteakettle: + - bugfix: time for memory loss message to show up when being revived is now correctly + 300 seconds, instead of 30 + - bugfix: the load away mission verb won't crash the server now + - rscadd: roundstart slimes can turn into puddles now + - rscadd: all gas masks (but welding + glass) can be alt clicked to show/hide identity + - tweak: autosurgeons from travelling trader rewards now only have one use + - bugfix: fixes held items proccing crossed when passing someone + - tweak: you can now get a family heirlooms based off your species instead of job + - tweak: changeling stings retract upon turning into a slime puddle + - tweak: you cannot transform into a slime puddle with a no drop item in your hands + - tweak: slime puddles are now transparent and their colour looks more natural in + comparison to the user + - tweak: slime puddles are now even slower + - tweak: slime puddles now get no protection from worn clothing + - rscdel: removes two debug messages left in from my prior eye customization pr + - rscadd: adds unlockable loadout items, corresponding category in loadouts, etc + - rscadd: added in-game age verification as an alternative to access requests + - bugfix: disabling adminhelp noises no longer disables looc + - bugfix: apids render now + - bugfix: you can now only entwine tails with people who have a tail + - bugfix: custom eyes and tongues now properly carry across cloning + - rscadd: re-adds the holoform verb for people who want to use it over going through + the char list + - bugfix: eye sprites should look normal once more + - rscadd: licking people washes pie off their face + - rscadd: you can now pick your eye sprites from customization + - tweak: looking at loadout equips loadout items on your preview image instead of + job items + - tweak: custom holoforms are now accessible through an action instead of through + verbs + - tweak: AI holoforms can now emote + - tweak: cloning now correctly copies your blood colour, body sprite type and eye + type + - bugfix: species with NOTRANSSTING cannot have envy's knife used on them + - rscadd: avian/digitigrade legs have been added for slimes + - rscadd: you can teleport bread + - tweak: slime puddles are no longer layered down one layer + - tweak: you cannot tackle with two paralysed arms + - tweak: tackling with a single paralysed arm lowers your tackle roll by 2 + - bugfix: circuits get pin data proc is sanitized when text is returned as data + - rscadd: loadout now has save slot support and colour choosing/saving for polychromic + items + - rscadd: polychromic maid outfit + - rscadd: you can rebind communication hotkeys and they're the default now + - rscadd: you can now customize your size from 90% to 130%, going below 100% makes + you have 10 less max health + - rscadd: '*squeak' + - rscadd: anthromorphic synth species + - rscadd: improvements to the automatic age gate + - tweak: antag items are now of critical importance and wont fail to be placed on + the character + - bugfix: a tonne of fixes to colourisation of parts, too many to name, including + some sprite fixes + - rscadd: things now have their own individual primary/(secondary)/(tertiary) colours + as required, and these can be modified by you + uomo91: + - bugfix: Fixed "Show All" tab in player panel logs being broken. + - bugfix: Whispers, OOC, and various other things display differently in logs, visually + distinguishing them from say logs. + - refactor: Player panel logs will now show all logs chronologically, so you'll + see commingled say and attack logs if you're on the "Show All" tab, etc... + yorii: + - bugfix: fixed botany rounding error that caused grass and other plants to misbehave + zeroisthebiggay: + - bugfix: legion now drops chests + - rscadd: Traitor assistants can now purchase the patented POGBox! Put TC into it + for even higher damage! + - balance: MEGAFAUNA DROPS ARE LAVAPROOF + - imageadd: cool codex cicatrix inhands + - rscadd: gravitokinetic stands from tg + - balance: buffs stands overall + - bugfix: protector stands no longer become tposing invisible apes sometimes + - bugfix: jacqueline spawns on boxstation + - rscadd: secsheath for your cool stunsword at your local security vendor. you gotta + hack it first though. + - imageadd: fuck the r*d cr*ss + - rscadd: The legion megafauna has been reworked. The fight should now be both slightly + harder and faster. + - balance: You can no longer cheese the colossus by being a sand golem and simply + being immune. +2021-01-22: + Arturlang: + - rscadd: Adds a way to give items to people, you can combat mode rightclick to + offer it to one person, right click on people without mode and click the give + verb, or use the hotkey CTRL G to offer it to everyone around you +2021-01-25: + MrJWhit: + - bugfix: Alien radio code + - rscadd: Microwave can now be cleaned by a damp rag as well as soap. + - bugfix: Removes some unused code, and improves some other code. + - rscadd: The AI has a verb to look up and down z-levels + - bugfix: Making a monkey into a human doesn't unanchor random things on the tile + - bugfix: Makes a few slight improvements to drinking code + - tweak: Makes encryption keys be put in the hands of the user when able instead + of being dropped on the floor when removed from headsets + raspy-on-osu: + - refactor: ventcrawling + silicons: + - tweak: you can now shove yourself up in any intent, not just help. +2021-01-27: + ArcaneMusic, ported by Hatterhat: + - rscadd: Strike a hydroponics tray with a fully-charged floral somatoray to lock + in a mutation. + - rscadd: Floral somatorays now have the ability to force a mutation in a plant. + This should drain the cell in a single shot, but we'll see. + - balance: Somatorays now take uranium to craft instead of radium. + Arturlang: + - rscadd: Actually adds a right click give option + - rscadd: Revenants can now clickdrag to throw stuff at people, with some items + doing various things at the same time. + DeltaFire15: + - bugfix: The woundmending rite no longer causes runtimes. + - bugfix: Ratvarian borgs can now use their tier-0 spells. + - balance: Ratvarian borgs can always use their assigned spells, if there is enough + power. + - admin: The heretic antag panel now shows their sacrifices & current sacrifice + targets. + - tweak: The heretic roundend report now shows their sacrifices and nonsacrificed + targets. + - bugfix: Living hearts can no longer select the same target as another living heart, + removing a certain problem. + Hatterhat: + - tweak: Department budget cards have been readded. TO THE CODE. NOT LOCKERS. + - tweak: Also budget cards now look more like every other ID - see tgstation#55001. + - balance: One of the contractor tablet's payouts has been raised from a small payout + to a medium payout. + - balance: The free golem ship's GPSes no longer start on. They were never meant + to, but they did. + - rscdel: Headsets can't be found on most legion corpses now. + - rscdel: The flash on the assistant corpse is gone, too. + MrJWhit: + - tweak: Remaps some air alarms for sanity. + SandPoot: + - bugfix: The drop circuit can no longer drop things that are not inside it. + raspy-on-osu: + - bugfix: bespoke ventcrawling element not detaching due to malformed call + shellspeed1: + - bugfix: Floorbots had had a software update, preventing them from dogpiling on + their target as easily as they did before. + - soundadd: Floorbots will now play a small chime when stacked on top of each other + to indicate that they're moving apart. + timothyteakettle: + - rscadd: blobs can use the 'me' verb + - admin: adminhelps and pms only sanitize once instead of twice +2021-01-28: + silicons: + - rscadd: colormates can now paint some mobs. + - bugfix: 1 dev explosions shouldn't delete brains anymore +2021-01-29: + MrJWhit: + - tweak: Ported the QM, Captain, CMO, and HoS cloaks from beestation. + - rscdel: Removes excess air alarms from boxstation + TripleShades: + - bugfix: fixes engineering secure storage being the wrong area because I fucked + that up previously my bad + - bugfix: removes funny extra light switch under right surgery table in surgery + oops + - rscadd: Added chairs to the corpse launch viewing area + - rscadd: Small garden plot for flowers for parity with other station Chapels + - rscadd: Plain Bible to glass tables in Chapel + - rscadd: Candles and Matchbox to glass tables in Chapel + - rscadd: More glass tables, with a chaplain figure and another spare bible. + - rscadd: Bookcase to Box Chapel for parity with other station Chapels + - rscadd: Minimoog to Box Chapel as substitute for a church organ + - rscadd: 'Holy department sign just below Chapel change: Expanded the corpse launching + area to feel less congested change: Added windows to the corpse launch so you + can look inside I guess? change: Moved flowers and burial garments to the corner + next to the corpse launcher change: Box Chaplain''s office door is moved over + one change: Confessional is now connected to Chaplain''s office for parity with + other station Chapels change: Moved coffins over to old confessional location + change: Box Chapel now has pews instead of stools change: Box Chapel Confessional + is now lit instead of being nearly pitch black remove: Two coffins from Chapel' + timothyteakettle: + - bugfix: the miner bedsheet will now increment its progress when you redeem points + from the ORM + - rscadd: you can add custom names and descriptions to item's on the loadout now + zeroisthebiggay: + - rscadd: roundstart aesthetic sterile masks and roundstart paper masks + - rscadd: more accessory slot items + - rscadd: cowbell necklace happy 2021 + - rscadd: shibari ropes & torn pantyhose +2021-01-30: + timothyteakettle: + - rscadd: adds 'clucks', 'caws' and 'gekkers' to the speech verb list + zeroisthebiggay: + - rscadd: some more FUCKING hairs + - imageadd: uncodersprites the advanced extinguisher +2021-01-31: + Putnam3145: + - balance: fermichem explosion EMPs don't cover the entire station diff --git a/html/changelogs/archive/2021-02.yml b/html/changelogs/archive/2021-02.yml new file mode 100644 index 0000000000..7b4448849e --- /dev/null +++ b/html/changelogs/archive/2021-02.yml @@ -0,0 +1,267 @@ +2021-02-02: + silicons: + - rscadd: pais can now be carried around piggybacking/fireman + - balance: Meth and Nuka Cola once again, speed you up. +2021-02-03: + Hatterhat: + - bugfix: The green energy sabre's sprite now respects proper handedness. +2021-02-05: + SmArtKar: + - rscadd: The orbit menu now has an Auto-Observe button! No more sifting through + the lame observe menu to snoop in people's backpacks! Also, orbit menu now refreshes. + - bugfix: KAs are no longer getting broken when fired by a circuit + keronshb: + - balance: Force and damage > 15 from 18/25 + - balance: Knockdown put down to 5 from 30 + - balance: Armor pen down to 10 from 100. + - balance: Makes cell chargers, charge faster. + raspy-on-osu: + - bugfix: alien royals can no longer ventcrawl + shellspeed1: + - balance: There actually needs to be people for zombies to happen now. + timothyteakettle: + - rscadd: dwarf facial hair is no longer randomised +2021-02-07: + Thalpy: + - refactor: 'Dispenser: Adds the ability to store a small amount of reagents in + the machine itself for dispensing. Reacting recipies cannot be stored. Size + of storage increases with bin size.' + - refactor: 'Dispenser: Allows reagents to be color coded by pH' + - refactor: 'Dispenser: Each reagent displays it''s pH on hover' + - refactor: 'Dispenser: Allows the user to toggle between buttons and a radial dial' + - refactor: 'Dispenser: When the dispencer is upgraded it can dispense 5/3/2/1 volumes + based on rating refactor: Dispenser: as it was before. This does not break recorded + recipes.' + - tweak: Adds a round function to some numbers so they're not huge + - tweak: The Chem master can now get purity for all reagents when analysed + - bugfix: Synthissue fixes + - tweak: buffers now have a strong and weak variant. Weak can be dispensed, and + strong can be created. Strong buffers are 6x more effective. + - bugfix: Some buffer pH edge calculation fixes + TyrianTyrell: + - rscadd: added a signed language, that can't be used over the radio but can be + used if you're mute. also added the multilingual trait. + - imageadd: hopefully added an icon for the signed language. + - code_imp: changed how some traits function slightly. + dzahlus: + - tweak: tweaked a few sounds + - soundadd: added a new weapon sounds + - sounddel: removed old weapon sounds + - code_imp: changed some sound related code + silicons: + - rscadd: syndicate ablative armwraps have been added. +2021-02-09: + Chiirno: + - rscadd: Adds clown waddle to clown shoes. Enhanced Clown Waddle Dampeners can + be engaged in-hand with ctrl+click, _but why would you?_ + MrJWhit: + - rscadd: Re-adds theater disposal outlet, and makes dorms disposal able to have + things sent to it on boxstation. + TyrianTyrell: + - bugfix: made default tongue able to speak signed language. + timothyteakettle: + - balance: sentient viruses can now infect synths and ipcs +2021-02-11: + Adelphon: + - rscadd: Charismatic Suit + - rscadd: Urban Jacket + DeltaFire15: + - tweak: Added nanogel to the robodrobe. + Putnam3145: + - rscadd: Config to keep unreadied players from mode voting + dzahlus: + - bugfix: fixes grenadelaunch.ogg being used where it shouldn't and makes mech weapons + use correct sound + keronshb: + - balance: 10 > 30 second for Warp Implant cooldown + - rscdel: Comments out power sink objective. + timothyteakettle: + - bugfix: persistent blood should stop being invisible and alt clicking it shouldn't + return the entire spritesheet + - admin: pickpocketing is now logged using log_combat + zeroisthebiggay: + - tweak: the aesthetic sterile mask no longer hides faces so you can cosplay egirls + and keep flavortexts +2021-02-12: + Hatterhat: + - balance: The ATVs on SnowCabin.dmm have been replaced with snowmobiles. + MrJWhit: + - tweak: Random deltastation fixes. + - tweak: Gives boxstation vault door actual vault door access + silicons: + - balance: Voice of God - sleep removed, stun staggers instead, knockdown is faster + but does not do stamina damage, vomit is faster but doesn't stun +2021-02-13: + Hatterhat: + - balance: Energy bolas now take 2.5 seconds to remove and dissipate on removal. + timothyteakettle: + - admin: migration error to version 39+ of savefiles is now logged instead of messaging + all online admins in the chat +2021-02-14: + DeltaFire15: + - admin: The antag panel now correctly shows the names of cultist / clockcult datum + subtypes. + - bugfix: Adding clock cultists via the admin panel now works correctly. + - bugfix: Xeno larvae should now be able to ventcrawl again. + Hatterhat: + - tweak: Repairing sensors on jumpsuits now requires a fully-intact jumpsuit. Find + some cloth. + - tweak: Durathread armor kits now require you to have a fully-repaired jumpsuit, + first, with no attachments. + - bugfix: Durathread armor kits now no longer weave the entirety of the jumpsuit + armor universe into having armor. + TyrianTyrell: + - code_imp: added a define for multilingual granted languages, and changed the multilingual + trait to use it. +2021-02-15: + Adelphon: + - rscadd: polychromatic shoes + - rscadd: polychromatic windbreaker + - rscadd: polychromatic canvas cloak + - bugfix: digitigrade charismatic suit texture + DeltaFire15: + - balance: Kneecapped pugilist parries somewhat. + - balance: Slightly nerfed default unarmed parries. + - balance: Slightly nerfed traitor armwrap parries. + - bugfix: Pugilist parries now cannot perfectly defend against projectiles, as they + were supposed to. + - bugfix: Some parrying numbers that one would think were in seconds didn't have + the SECONDS. I added those. + - balance: Clock cultists now yell alot less when invoking scripture. + dzahlus: + - rscadd: Added new emote + - soundadd: added a new emote sound + silicons: + - balance: people on the ground hit less hard in unarmed combat. rng miss remove + from punches. + - bugfix: chat highlighting no longer drops half your entered words. +2021-02-16: + silicons: + - config: sprint removal entry added, UI will revert to old UI while this is active. +2021-02-18: + BlueWildrose: + - admin: Admins now receive messages regarding certain holodeck actions. + Hatterhat: + - bugfix: Free Golem Ship GPSes now start as disabled. Like they were supposed to. + LetterN: + - tweak: No more liver damage when you opt out of "hornychems" + SmArtKar: + - rscadd: Added a new TCG card game + dzahlus: + - rscdel: Removed maroon objective due to toxic gameplay behaviour + shellspeed1: + - bugfix: floor bots place plating before tiles now. + - bugfix: gets rid of another tile duplication issue. + silicons: + - spellcheck: priviledge --> privilege +2021-02-19: + Putnam3145: + - bugfix: Buzz Fuzz's addiction threshold is now a can and a sip as intended. + timothyteakettle: + - admin: staring into pierced realities is now logged +2021-02-20: + Adelphon: + - rscadd: polychromic pants + - tweak: urban coat made polychromic + Chiirno: + - tweak: Synthflesh now unhusks with 100u instead of requiring 101u. + SmArtKar: + - tweak: Added some QoL changes to TCG + - bugfix: Fixed TCG cards not saving + TyrianTyrell: + - bugfix: fixed the signed language so that you can actually use it, and that it's + unusable when it's meant to be. + timothyteakettle: + - bugfix: stops people using Message All on PDAs when their cartridge doesn't allow + it +2021-02-21: + Hatterhat: + - balance: Anomaly announcements and brand intelligence now always announce instead + of having some ham-fisted chance of being a command report. + IronEleven: + - balance: Raises Space Vine Population Requirement from 10 to 20 + MrJWhit: + - tweak: Removes an unnecessary % on the seed extractor. + timothyteakettle: + - bugfix: the query for checking mentors now gets properly deleted + - rscadd: vampires no longer burn in the chapel if they signed up as the chaplain +2021-02-22: + Putnam3145: + - rscadd: (Hexa)crocin + - rscadd: (Hexa)camphor + - rscadd: Nymphomaniac quirk + - admin: All climaxes and arousals are now logged, as well as genital exposure. + SandPoot: + - rscadd: Cyborg tablets and it's special app for self-management. + - bugfix: In the case of a doomsday device being created outside of an AI it will + delete itself. + - imageadd: Some sprites for it have been added and the borg's hud light toggles + been changed to only on-off (made by yours truly) + - refactor: A lot of borg code was changed + - refactor: Tools no longer use istype checks and actually check for their behavior. + Vynzill: + - rscadd: cursed rice hat that's hard to find and obtain, along with a couple other + hats + - rscadd: a replacement toy gun for donksoft lmg + - rscadd: gorillas to the jungle gateway, friendly, even when attacked. + - bugfix: couple mapping errors I noticed, most importantly a missing window in + the chapel. + - balance: shotgun and donksoft lmg removed, captain coat nerfed armor values. + - balance: leaper healthpool from 450 to 550 hopefully making it more of a struggle, + and gives it a name. + - tweak: leaper pit is more wider. The hidden room south is now more obvious to + find + dzahlus: + - rscadd: Added pain emote to getting wounded + - soundadd: added a new pain emote sounds +2021-02-23: + keronshb: + - rscadd: Hyperblade to uplink with poplock + - balance: Removes combination of two Dragon Tooth Swords while keeping it for regular + eutactics. + timothyteakettle: + - bugfix: banning panel prioritises mobs with clients now when trying to find them + if they're in the game +2021-02-24: + SandPoot: + - bugfix: Regular crowbars no longer open powered airlocks. + silicons: + - balance: xeno cube makes hostile xenos now, and drops a sentinel instead of a + drone. +2021-02-25: + DeltaFire15: + - bugfix: Traitor / Ling objective amount should now be correct again. +2021-02-26: + DeltaFire15: + - code_imp: All machine-frame based tool-use actions now have state-checking callbacks. +2021-02-27: + Hatterhat: + - balance: Lingfists (trait_mauler) now deal no stam damage and lost their 15(!!!) + armor penetration. + Putnam3145: + - tweak: Tablets now protect their contents from rads. + TheObserver-sys: + - rscadd: Chems that should have been usable are now usable, try some cryoxadone + on a plant today!!! + kappa-sama: + - tweak: cards and card binders are now small-class items + keronshb: + - balance: 16 > 10 unlock cost for stronger abilities + - balance: Made nearly all other abilities for free. + kiwedespars: + - balance: reverted the pr that absolutely gutted pugilism and made it worse than + base unarmed, also gives it a second long stagger + - balance: removed the ability to parry while horizontal, because that's dumb and + makes it easy to just time the parries right. + silicons: + - bugfix: chaplain arrythmic knives can no longer be abused for infinite speed. +2021-02-28: + Putnam3145: + - bugfix: Polychromic windbreaker's alt-click message is now coherent + - code_imp: Toggleable suits now have an on_toggle proc to be overridden. + R3dtail: + - tweak: doubled max belly name length and quadrupled belly description length + SandPoot: + - tweak: Body rejuvenation surgery will loop until the patient is completely healed. + dzahlus: + - bugfix: fixes toxinlovers dying from heretic stuff that should heal them instead diff --git a/html/changelogs/archive/2021-03.yml b/html/changelogs/archive/2021-03.yml new file mode 100644 index 0000000000..e36008a175 --- /dev/null +++ b/html/changelogs/archive/2021-03.yml @@ -0,0 +1,310 @@ +2021-03-01: + SmArtKar: + - bugfix: Fixes decks breaking your screen + - bugfix: Fixes binders not saving cards + - bugfix: Fixes binders not saving multiple cards of the same type + Vynzill: + - bugfix: cursed rice hat right in front of the jungle gateway's entrance is now + removed from this dimensional plane +2021-03-02: + LetterN: + - bugfix: 'colorpainter: let''s not dispense null' + SandPoot: + - bugfix: Changelings will actually become the person they want to be when using + "human form" ability(after having used last resort). +2021-03-03: + MarinaGryphon: + - bugfix: The AOOC mute pref is now properly respected. + - bugfix: Muting adminhelp sounds no longer mutes AOOC. + Putnam3145: + - config: pAIs now have a policy config + - rscadd: '"Supermatter surge" event, which might cause problems if the supermatter + is not sufficiently cooled (i.e. the setup is messed up in some way)' + - rscdel: Fusion can no longer be done in open air. + - rscdel: Valentine's day event no longer gives everyone a valentine's antag. + SandPoot: + - bugfix: Legions should now pass their type to the person they infect (if valid). + dzahlus: + - rscadd: Added new subtype to lesser ash drake balanced around player control + - balance: rebalanced dragon transformation to a 1 minute cooldown as well as using + the new subtype of megafauna + qweq12yt: + - bugfix: fixed infectious zombies not being able to attack if host was pacifist + - rscadd: adds a way for species to have blacklisted quirks, the removal, and restoration + of said quirks upon species changes + - bugfix: Now pacifists won't be able to use flamethrowers + - bugfix: Kinetic Accelerator now properly reloads a charge to it's chamber instead + of nulling the variable forever + - bugfix: Now pacifists won't be able to use Kinetic Accelerators if a non-pacifist + shoots it first +2021-03-04: + LetterN: + - code_imp: removes bsql +2021-03-05: + Putnam3145: + - tweak: Lowered ash storm volume + - tweak: Minesweeper can no longer be made to lag the server on purpose + keronshb: + - tweak: Prevents heat from going through reinforced plasma glass. +2021-03-07: + Hatterhat: + - rscadd: You can now reskin your improvised shotguns. + - rscadd: The spontaneous brain trauma event now announces to ghosts whoever got + funnied upon. + - imageadd: Ports EikoBiko's cat tail sprite. + Putnam3145: + - bugfix: nitryl now consumes oxygen/nitrogen instead of generating them + - balance: Hyper-nob and nitryl are easier to make. + dzahlus: + - rscadd: Added taser microbattery for MWS-01 + - tweak: tweaked MWS-01 beacondrop to have more batteries + - balance: rebalanced MWS-01 disabler battery to fire 10 shots + - soundadd: added unique sound to the MWS-01 + - spellcheck: fixed Modula Weapons System to "Modular Weapon System" + timothyteakettle: + - balance: exiting a bluespace jar through any means, hardstuns you for 5 seconds +2021-03-09: + LetterN: + - refactor: tg hardsync, mostly contains tgui +2021-03-10: + Hatterhat: + - rscadd: The femur breaker now actually breaks legs by applying a compound fracture. + Putnam3145: + - balance: uncapped TEG power, buffing high-temp TEGs +2021-03-12: + R3dtail: + - spellcheck: Adds Periods and moves some words around. +2021-03-14: + Adelphon: + - rscadd: messy2 + - bugfix: papermask + Hatterhat: + - rscadd: Robotic limb repair surgery now has tiers. + - rscadd: 'Pubby and Delta now have roundstart limb-growers relatively close to, + if not in, the operating theaters. tweak: Box QM''s console now can announce + things.' + Putnam3145: + - bugfix: chaos loads now + kiwedespars: + - rscadd: adds a cute new plushie + necromanceranne: + - bugfix: Fixes cosmetic augments missing their foot sprites. +2021-03-16: + GrayRachnid: + - balance: removed red toolbox, agent id, and guerilla gloves from unlocking illegal + tech. + HeroWithYay: + - bugfix: fixed spelling error + LetterN: + - bugfix: Borg light icons not turning off + - bugfix: Double ai icon select + Fixes ai core not having icons + - bugfix: Missing air tank icon + - bugfix: Computer boards being dumb and nullspacing/qdeling itself + Putnam3145: + - balance: Supernova now much lower chance to be inconsequential + - balance: Made hyper-nob's point values way lower (25/20 for science/cargo instead + of 1000/1000) + - balance: Made nitryl's cargo sell value less (10 instead of 30) + SandPoot: + - bugfix: Fixed interacting with telecomms. +2021-03-17: + KeRSedChaplain: + - rscadd: Added three new rites, and makes soul vessels obtainable + - bugfix: fixes clockwork guardians inheriting marauders blocking + - soundadd: added sounds for the ratvar end sequence, voiced by @dzahlus + timothyteakettle: + - rscadd: speech panel added to main menu customization +2021-03-18: + Arturlang: + - bugfix: Combat mode right click and right click verb give's are now actualyl targeted + Hatterhat: + - rscadd: Hypospray vials are now printable from the medical techshift start. + - rscadd: 'Empty hypospray kits are now printable behind biological technology. + tweak: Quantum electromag (T4 lasers) are now behind Advanced Bluespace like + the rest of T4.' +2021-03-19: + DeltaFire15: + - rscdel: 'Bluespace jars can no longer be printed / acquired from lathes / techwebs. + tweak: The travelling animal trader now gives you your reward in a one-use bluespace + jar.' + Putnam3145: + - rscadd: '"Antag" role that can be toggled to disable all antags' + SandPoot: + - rscadd: Tactitool Skirtleneck. + - rscadd: Adds the tactitool skirtleneck to the loadout. + kiwedespars: + - rscadd: 'New heretic path - Path of Void- it specializes in being extremely stealthy. + tweak : Removed curse of blindness replaced with mask of madness. hey it even + rhymes.' + - bugfix: fixes heretic mass deletion during transmutation bug. + - bugfix: Fixes heretic brews being permanent. + - bugfix: 'Fixes void storm breaking after resurrecting. tweak: Heretic has received + a minor textual facelift. tweak: Heretics who finish the Void Path and become + an Aristocrat of the Void can now survive in the Void (space).' + - bugfix: Heretics who research Aristocrats Way on the Void Path will no longer + suffocate in their own storm when they ascend (no longer breathes). + - bugfix: Mark of Void and Seeking Blade are once again exclusive only to Void. + - balance: 'Carving knife now deals more damage on throw and can embed in your enemies. + tweak: Grasp of Rust only rusts floors and machines on harm intent. tweak: when + u choose a sac target as heretic it ll also tell the job of the sac' + - rscadd: 2 new void spells, one a placeholder. + - rscadd: flesh mansus grasp buffed, now gives you 5u eldritch fluid when hitting + someone. + zeroisthebiggay: + - bugfix: fixes spriteless heretic book +2021-03-20: + Hatterhat: + - bugfix: Bluespace beaker filling icons for that narrow band between 90 and 80% + full now actually exist. +2021-03-21: + Arturlang: + - bugfix: Vampire statpanel no longer shows spans unnecesary + GrayRachnid: + - bugfix: fixed the holopad autocall bug + - bugfix: properly incorporated the secure holopad that was commented out in the + code. + - config: the in_character_filter.txt is now usable + - admin: headmins should edit the in_character_filter.txt + - server: someone with box access should delete racism with the in_character_filter.txt + - balance: buffed particle defender disabler shots from 13->15 stamina (15*6=90) + - balance: buffed particle defender laser ammo to 4 shots + Hatterhat: + - rscdel: removes pacifism from ghost cafe. have fun beating up your coworkers + LetterN: + - rscadd: Art gallery (meta) + - rscadd: Laptop vendor (meta, delta, box) + Putnam3145: + - balance: Buffed supermatter surge massively. + The-Sun-In-Splendour: + - bugfix: You cannot revive yourself (as a changeling) if you've been absorbed anymore + dzahlus: + - balance: rebalanced hierophant STAFF to do 15 damage on all attacks + timothyteakettle: + - bugfix: using the puddle ability when stunned wont break it +2021-03-23: + LetterN: + - bugfix: NIRM departamental purchases now work. Have fun spending the entire R&D + Budget! +2021-03-24: + BlueWildrose: + - bugfix: The nightmare's light eater can now destroy messes that emit light, like + glowing goo or ectoplasmic puddles. + Hatterhat: + - bugfix: The NOGUNS trait now takes precedence over the triggerguard checks. + - balance: Medicated sutures and advanced regenerative mesh are now easier to make. + Reagent-quantity wise, anyway. + ItzGabby: + - rscadd: Fluff Items with polychromic support + - rscadd: A new vendor called Bark box + - rscadd: A new form of snack with it's own box + - rscadd: Two harness, one of them being lewd + - rscadd: One new collar, with a ribbon. Classy. + - rscadd: More locked forms of collars + - rscdel: Purged old balls + - balance: Removed the funny buffs each colored tennis ball had, down with the powergame! + - imageadd: Added polychromic fluff icons, vendor icons, suit icons, snack icons, + fancy box icons, and a polychromic version of Izzy's ball. + - imagedel: Deleted old balls, Izzy's Ball, except the rainbow one since it's special + and as I did not go out of my way to get permission to touch. + - spellcheck: Walked into vending.dm and glared for a moment at hydroponics' grammar. + LetterN: + - bugfix: fixed laptops pickability + - bugfix: fixed closets being unweldable + YakumoChen: + - balance: Genetics - Thermal vision is a recipe instead of a natural gene now. + Nearsighted+Stimmed. Other minor nerfs, Thermal is 40 instability. + - balance: Research - X-ray eyes are now an illegal tech. + qweq12yt: + - rscadd: added the black market uplink + - imageadd: added blackmarket.dmi + - bugfix: increased the black market interface's width, now the delivery options + will show properly when the LTSRBT is built + zeroisthebiggay: + - rscadd: biodegrade works on legcuffs +2021-03-25: + zeroisthebiggay: + - balance: strained muscles isn't free +2021-03-26: + BlueWildrose: + - balance: Clothing no longer drops when shredded. It just becomes useless. + - balance: Suit sensors are guaranteed to short out when the clothes become shredded, + not damaged now. + - balance: Uniform limb integrity increased from 30 to 120. + - balance: 'Suit sensor damage has been added. The more damaged your suit sensors + get, the less features that will be available from these suit sensors. It takes + two e-sword hits to ruin your tracking beacon for instance. tweak: Examine text + on uniforms is now more clear about needing cable coil to repair your suit sensors.' + - bugfix: Fixed prisoner uniform sprite paths + CuteMoff: + - balance: Diamond's forcemod was changed from 1.1x to 1.2x + Hatterhat: + - rscadd: Lever-action rifles, chambered in .38, are now sitting in the code. They + might be buyable from Cargo or the Black Market soon. Watch this space. + - rscadd: Sawed-off shotguns now look like shotguns, but short, when inhand, instead + of "generic gun". + timothyteakettle: + - bugfix: slimes can be delimbed + - bugfix: the loadout now colours pet collars correctly +2021-03-28: + CuteMoff: + - balance: Changed Strength Modifier from the default (1.0) too .7 + Hatterhat: + - bugfix: As a heretic, shattering your blade no longer interferes with bluespace. + Putnam3145: + - rscadd: Threat tracking is now universal, rather than dynamic-only + - rscadd: Slaughter demon event now increases weight based on how much blood there + is. + R3dtail: + - rscdel: Removed ichor creates + - balance: Removed ichor crates and adjusted crate rolling appropriately + - balance: Removed the bonespear from the blackmarket uplink, and made EMP grenades + harder to get from the same item. + - rscadd: Added a description to the black market uplink + Shadow-Quill: + - imageadd: Added small versions of the walk icon for all hud styles, except Retro. + dzahlus: + - rscadd: Added radial menu to joy mask for alt reskins + - imageadd: added pensive, angry and flushed sprites to joy mask + keronshb: + - balance: Radioactive microlasers can no longer knock out creatures who are immune + to the effects of radiation. + - bugfix: The radioactive microlaser now calculates the strength of its delay effect + using the intensity setting it had when you initially used it on your victim, + not the intensity setting it currently has. This prevents people from "cheating + out" its intensity 20 effect with only a 2 second delay and a 1 second cooldown. + - balance: Radioactive microlasers no longer contain twice as much metal as normal + health analyzers do. + necromanceranne: + - rscadd: Replaces the useless bullet and laser shields with new Kinetic and Ablative + shields, which do as they advertise. + - rscadd: Replaces the shield implants shield with a hardlight shield that can take + large amounts of brute damage, but disintegrates when shot with disablers. + - bugfix: Fixes Fake Roman Shields being able to be used as normal riot shields. + - bugfix: Fixes nonlethal/non-physical damage types destroying shields. (stamina, + toxins, oxygen, clone, brain) + - bugfix: Fixes tower shields not doing anything, while also giving them intergrity + to match their advertised durability. + - bugfix: Uses additional flags to determine what kind effects work well and what + works poorly against various shields. + timothyteakettle: + - rscadd: ghost cafe residents can now disguise themselves as any mob or object + - bugfix: fixes character preview not updating when selecting the loadout tab + zeroisthebiggay: + - rscadd: triple kitsune tail +2021-03-29: + BlueWildrose: + - bugfix: Fixed being unable to fix suit sensors if damaged at all unless destroyed + completely + YakumoChen: + - rscadd: A less-than-new Syndicate bundle that reminds you of the good old days + when we didn't need all those newfangled traitor items the young-uns get. We + had 6 items in the uplink and we had Monkey in rotation and by god we made do. + qweq12yt: + - rscadd: Added Earmuffs + - rscadd: Added Random Drink + - rscadd: Added Clear PDA + - rscadd: Added Internals Box + - rscadd: Added Meson Goggles + - rscadd: Added Smoke Grenade + silicons: + - bugfix: automated hydroponics system design now works properly diff --git a/html/changelogs/archive/2021-04.yml b/html/changelogs/archive/2021-04.yml new file mode 100644 index 0000000000..a42fecb451 --- /dev/null +++ b/html/changelogs/archive/2021-04.yml @@ -0,0 +1,278 @@ +2021-04-02: + LetterN: + - bugfix: piratepayment +2021-04-03: + BlueWildrose: + - bugfix: The hydroponics pet bee, Bumbles no longer has a number besides their + name. + Putnam3145: + - rscdel: '"Destroy all nanotrasen cloning machines" objective is gone' + - code_imp: Removed all the commented-out sabotage objectives (we can just get them + from history) + - rscadd: Observe verb logging +2021-04-04: + Hatterhat: + - balance: After a sudden crash in the tower-cap log slash wooden plank economy, + NanoTrasen has decided to stop selling tower-cap logs to Cargo. +2021-04-06: + ArcaneMusic: + - bugfix: Prevents people from lagging the server by growing HUMANS FROM CABBAGE! + BlueWildrose: + - admin: Admins get to hear the prayer ding again unless they have prayer sounds + turned off. + DeltaFire15: + - bugfix: The wood plank cargo pack no longer is named incorrectly. + Putnam3145: + - bugfix: forced climax doesn't do a climax-with + SandPoot: + - bugfix: Reverts locker/crate behavior for attacking it with an item while closed + (use any intent other than help to bash it). + - bugfix: 'Laptop interactions are no longer weird and now you can drag it to yourself + to pick it up. tweak: Ctrl+Shift-Click to toggle laptops open/closed. tweak: + More examine info for laptops.' + - bugfix: Lockers/Crates can now be deconstructed the right way respecting the cutting_tool + (even if it's not one of the default interactions). + - rscdel: Dragging the laptop into itself shouldn't do anything anymore (kind of + pointless and hard to do). +2021-04-07: + LetterN: + - rscadd: Perln generation & biomes from lavaland + - code_imp: Cleans up the area, update it's icon and updates the openspace to use + the modules. +2021-04-09: + BlueWildrose: + - balance: The genetics mutation Autotomy has been buffed to be 20 instability instead + of 30, and harmless in delimbing. + - rscadd: 'There are now three more pills in each breast or penis enlargement pill + bottle. tweak: There are now 10 pill bottles of breast and penis enlargement + pill bottles in a Kinkmate instead of 5.' + - balance: Because of such changes that increases their amount in the kinkmate, + succubus milk and incubus draft values are reduced to RARE from VERY_RARE. + - spellcheck: Grammar correction on titty pill bottle. + - rscadd: The pandemic machine can now let you swap containers. + - bugfix: Slime puddles will now show mutation visual indicators & cult indicators + after exiting slime puddle form + - bugfix: Slime puddle transformation animations are now resized to fit the slimeperson's + current size, making it visually more consistent + - spellcheck: Typo correction in some mutation descriptions and other things + - code_imp: Cult/clockcult layers moved from LAYER_MUTATION to LAYER_ANTAG, new + update section for them specifically now + - rscadd: Sylvan and Mushroom languages are now tongueless, and Encoded Audio Language + is now learnable. + SandPoot: + - bugfix: The dragons_blood "lizard with the appearance of a drake" no longer wipes + important stuff. + - bugfix: Fixes Ashlizard legs not being digitigrade and makes them have the "Sharp" + snout. + - bugfix: Machines that open no longer drop their stock parts. + brokenOculus: + - rscadd: Added Telescopic Baseball Bat + - rscadd: Added Telescopic Baseball Bat to Stealthy uplink items + - rscadd: Added sprites for Telescopic Baseball Bat + - rscadd: Added Telescopic Baseball Bat to Baseball kit under uplink bundles +2021-04-12: + BlueWildrose: + - bugfix: Fixed female slime-subspecies left/right sprites being flipped + - bugfix: Fixed drones nullspacing things they try to place on tables and in closets + - bugfix: Fixed phantom mob-holder items. You can now grab Ian from your backpack + without any issues. + silicons: + - balance: gold cores can spawn simplemob xenos again. + timothyteakettle: + - config: makes AGE_VERIFICATION option off by default +2021-04-13: + rossark: + - bugfix: wrong word +2021-04-14: + Hatterhat: + - balance: Space pirates are now slightly more aware of how much money the station + has, and will demand payment accordingly. (No more 20k minimum payouts and basically-confirmed + three midround skeletons.) +2021-04-15: + BlueWildrose: + - bugfix: Fixed escape pods not docking at Centcom + skodai: + - imageadd: Resprited the icons for the sushi, onigiri, tuna can and sea weed. +2021-04-16: + BlueWildrose: + - bugfix: (TGport-Timberpoes) You can once again pay off the pirate event from the + communications console without it silently failing for no obvious reason. + - bugfix: Fixed being unable to delete messages from the communication consoles + message list save for the one on the bottom. + - bugfix: The data siphon that the space pirates have will no longer go invisible + when it begins siphoning. + - bugfix: If the space pirate's "offer" has been rejected, there is now announcement + feedback for if this does happen. + DeltaFire15: + - bugfix: Borgs can now use tank dispensers (again?) +2021-04-18: + BlueWildrose: + - balance: '(TGport-Kriskog) Reduced blight cost to 75, more in line with its underwhelming + nature. tweak: (TGport-Kriskog) Revenants now only use stolen essence to unlock + new spells. No more counting corpses or waiting for regen before draining. tweak: + (TGport-Kriskog) Spell unlock costs adjusted accordingly, defile upped from + 0 to a cost of 10. tweak: (TGport-Kriskog) Drain targets in soft-crit will be + stunned, to prevent them crawling away.' + - bugfix: (TGport-ShizCalev) Fixed revenant's light overload ability not blowing + lights in a square if there was another broken/burnt out/empty light in it. + DeltaFire15: + - bugfix: Mechs now do not get drained an absurd amount of energy when EMPd. + - bugfix: Organic healing surgeries no longer show up for people without any organic + bodyparts. + SandPoot: + - rscadd: Adds a fancy TGUI interface for the cloning computer. + - rscdel: 'Destroys the old cloning interface. tweak: Alt-Click now removes disks + from the cloning computer.' + - refactor: Replaced way too much code for the cloning computer. + - refactor: Cloning scan's implant now outputs a list if desired. +2021-04-20: + BlueWildrose: + - rscadd: New slimeperson organs that aren't really that different from humans for + now. + - imageadd: Some blue organs for slimepeople. + - rscadd: Space pirate sleepers can now be crowbared to be destroyed. + DrPainis: + - rscadd: ash drake meat + Hatterhat: + - bugfix: Plastitanium glass now properly applies the *2 bonus for integrity and + efficiency when used as a solar panel. + HeroWithYay: + - imageadd: replaced some icons + Putnam3145: + - rscadd: Bluespace pipes, which can teleport gas over long distances + - rscadd: Donk co traitor class (assassin-heavy) + - rscadd: Waffle co traitor class (freeform) + - rscadd: 'Admin-only activity tracking system only attached to antags for now tweak: + Objective rerolling can now be done twice' + - bugfix: Sabotage objectives won't give "free objective" anymore + The0bserver, TripleZeta, and AsciiSquid: + - rscadd: New, easily concealable weapons, chambered in .38, .357, and .45-70 Govt. + Fun for the whole family! + - rscadd: Some smugglers seem to have acquired a high amount of .38 derringers, + and are looking to offload them to those of gray morality, with no questions + asked! + - rscadd: An enigmatic gun collector has seen fit to do special acquisition work + for the Gorlex Marauders, selling the fruits of his labor for a premium price. + If you have the right electomagnetic sequence, you might be able to contact + him to acquire a piece of his armory. + coiax: + - rscadd: Nuke ops can now purchase a box of "deathrattle implants". When an implanted + person dies, all the other users of the implant will get a message, saying who + died and where they died. + keronshb: + - balance: Weight per blood is .03 now instead of .05 + - balance: Dragnet Snare breakout timer is now 2.5 seconds down from 5 seconds. + qweq12yt: + - bugfix: Fixed a bug where some cargo crates would never arrive and still charge + users + zeroisthebiggay: + - rscdel: the box ghost burger +2021-04-21: + necromanceranne: + - balance: Stun batons (not police batons/telebatons) no longer knockdown on leftclick. + - balance: Stun batons apply a knockdown and tase effect on right click, but once + every few seconds (they still don't disarm). They are vulnerable to a shove + disarm briefly, however. Standard batons have a cooldown of 5 seconds. Stun + prods have a cooldown of 7 seconds. + - balance: Taser resistance prevents the knockdown, so any chem that grants this + (like adrenals) protects you from this knockdown. + - balance: Stun batons apply a stagger when they hit someone, preventing sprinting + for a few seconds. + - balance: Stun batons respect melee armor for their stamina damage, but their cells, + based on max charge, grant armor penetration. For every 1000 charge, they gain + 1 armor pen. (Roundstart batons have 15 pen, just fyi) + - balance: Shoves can disarm you of any item, not just guns. + - bugfix: Removes a duplicate trait definition for TRAIT_NICE_SHOT. +2021-04-22: + Whoneedspacee: + - rscadd: new arena attack where ash drake summons lava around you + - rscdel: removed old swooping above you, instead flies above you instantly + - balance: ash drake now spawns temporary lava pools instead of meteors falling + down + - balance: ash drake takes twice as long to swoop down now that he instantly goes + above you + - balance: ash drake now moves twice as fast + - balance: increases the odds of lava spawns in the lava pool attack + - balance: 'increases fire line damage and decreases lava attacks direct damage + tweak: ash drake fire now shoots in the direction of the target tweak: changes + times of certain animations tweak: changes sounds of meteor falling to lava + creation' + - bugfix: a bug where ash drakes attacks did not damage mechs + - imageadd: changes meteor icon to lava creation animation from lava staff + - rscadd: Mass fire attack, sends fire out from the ash drake in all directions + - rscadd: Adds an enraged attack for ash drake, heals him as well as making him + glow and go faster, spawning massive amounts of fire in all directions + - rscdel: 'Removes the old triple swoop with lava pools attack tweak: Lava pools + can now spawn with the normal fire breath attack sometimes tweak: Lava pools + now have changed delays for lesser amounts so they don''t all just place around + one area tweak: Increases default swoop delay' + - balance: Teleporting out of the lava arena now has some actual consequences by + enraging the ash drake + - bugfix: Makes lava arena a bit less laggy by not recalculating range_turfs every + time + - bugfix: Fixes the arena attack selecting inaccessible tiles as the safe tile though + this will not change the turfs to basalt temporarily to prevent moving through + indestructible walls + - bugfix: Fire lines would not spawn if their range would place their final turf + location outside of the map + - bugfix: The arena attack will no longer destroy indestructible open turfs + - balance: ash drake fire does less damage now + - balance: ash drake takes longer to swoop down now + - balance: tiles take longer to fully convert into lava now, slowing down the arena + attack as well + - balance: fire breath now moves slower + - balance: triple fire breath for the lava swoop only happens below half health + now + - bugfix: The arena attack not making safespots when you fight it in a mech +2021-04-25: + DrPainis: + - spellcheck: Bubblegum is now capitalized. +2021-04-26: + Trigg, stylemistake and SandPoot: + - admin: 'Admins just got a new TGUI Select Equipment menu tweak: Prevents the window + from creating sprites for any animated version there might be. (this guarantees + consistant sprite size/amount)' +2021-04-29: + Putnam3145: + - bugfix: Fixed a couple runtimes in activity (threat) tracking + keronshb: + - balance: Removes the Reinforcement Chromosome from Genetics. +2021-04-30: + DrPainis: + - spellcheck: Bubblegum's hallucinations are capitalized. + Melbert, SandPoot: + - refactor: TGUI Limbgrower + - refactor: Refactored the limbgrower to modernize the code and allow for more types + of designs. + - rscadd: The limbgrower now supports plumbing ducts. + - bugfix: Fixes genitals not actually getting data from disks. + - code_imp: Adds two special helpers. + SandPoot: + - rscadd: The decal painter now has visible previews for your tile painting funs. + - bugfix: Fixes decal painter painting in the opposite direction. + TheObserver-sys: + - bugfix: Restores the access lock on crates that should have them, given the goods + inside. + - bugfix: Makes the 10MM Surplus Rifle a less awful thing to use. + - bugfix: replaces unarmored things with their armored versions. + - balance: Illegal Tech Ammo actually is fucking reasonable, now. + - balance: Expensive Illegal Tech Ammo Boxes are now constructible, with actually + justifiable prices. + WanderingFox95: + - balance: There's finally a reason for the reagent dart gun to exist and be used! + akada: + - imageadd: Changes the space adaptation sprite to something less intrusive and + more subtle. + necromanceranne: + - rscadd: 'Basic cybernetic organs: they''re worse than organic! Basic stomachs, + hearts, lungs and livers! For when you hate someone enough to not bother harvesting + organs from a monkeyhuman!' + - rscadd: 'Cybernetic organs have been adjusted into three tiers: 1 (basic), 2 (standard, + better than organic) and 3 (absolutely better than organic but expensive to + print)' + - rscadd: Cybernetic organs that are emp'd instead suffer different effects based + on the severity of the emp. The bigger the emp, the worse the effect is. + - rscadd: Rather than outright bricking, severely emp'd cyberorgans degrade over + time very quickly, requiring replacement in the near future. + - rscadd: Fake blindfolds in the loadout. They don't obscure vision, for better + or worse. diff --git a/html/changelogs/archive/2021-05.yml b/html/changelogs/archive/2021-05.yml new file mode 100644 index 0000000000..8508fbb2ec --- /dev/null +++ b/html/changelogs/archive/2021-05.yml @@ -0,0 +1,148 @@ +2021-05-01: + qweq12yt: + - bugfix: Restores the sprite for the Riot Suit. +2021-05-03: + TripleShades: + - rscadd: Added two air alarms to Pubby Security, one in the evidence locker room + and one in the main equipment back room + - rscadd: pAI Card back to outside Research in Meta Station + - bugfix: Pubby Disposals now shunts to space + - bugfix: Maintinence Areas being not applied to certain airlocks as well as stealing + minor walls + - bugfix: Box Surgery Storage camera is now renamed to be on the network + - bugfix: 'Box Paramedic Station camera is now renamed to be on the network, and + no longer steals the Morgue''s cam tweak: Box Surgery Storage is now it''s own + proper room' +2021-05-05: + The0bserver, with a great amount of advice from TripleZeta/TetraZeta: + - rscadd: Adds a new crate type, for use with any manner of cheeky breeki shenanigans, + as well as with existing Russian contraband. + bunny232: + - rscadd: There's some new vents and scrubbers in the meta station xenobiology department. + Welders and wrenches not included* + keronshb: + - balance: Nightmare Shadow Jaunt threshold up to 0.4 + - balance: Vendor and Engraved message light down to 0.3 +2021-05-08: + Arturlang: + - bugfix: Synthblood bottles now have the proper color and probably won't poison + you anymore + timothyteakettle: + - rscadd: lets humans have digi legs (and avian legs) +2021-05-09: + Putnam3145: + - rscadd: Priority announcement admeme verb + SandPoot: + - bugfix: Fixed Cyborg examines adding an extra weird line. + - code_imp: Everything can be set to have tooltips, and even coded to have neat + tooltips. + - rscadd: Makes it so humans and borgs already have tooltips. + TheObserver-sys: + - bugfix: Fixes most of the weird handling bugs and improves cigarette case handling + in general. + - rscadd: The Gorlex Marauders have seen fit to allow you to purchase the .45-70 + GOVT rare ammo, at a premium cost. Don't waste it. + WanderingFox95: + - rscadd: added the unrolling pin, an innovative solution to dough-based mishaps. + - imageadd: added visuals for the unrolling pin + dzahlus: + - soundadd: added new malf AI spawn and doomsday sound + - sounddel: removed old malf AI spawn and doomsday sound + zeroisthebiggay: + - balance: pirates now have a medbay and several other things qualifying as a buff + - balance: pirates lost their toilet +2021-05-11: + LetterN: + - bugfix: fixes emagging console shuttle purchases + - balance: syndie melee simplemobs has no more bullshit shield + bunny232: + - rscadd: Delta station xenobiology department has received enhanced scrubbing and + ventilation capabilities similar to box and meta +2021-05-12: + DeltaFire15: + - bugfix: find_safe_turf no longer always fails on safe oxygen levels(??) + - bugfix: 'Heretic bladeshatters now actually take the heretic''s z into account + as intended, instead of always being station z tweak: Message for failing the + bladeshatter despite succeeding the do_after tweak: Improves bladeshatter a + bit by making it safer codewise' +2021-05-13: + Linzolle: + - spellcheck: anthromorphic -> anthropomorphic + WanderingFox95: + - rscadd: Pinot Mort (Necropolis Wine), a new, (totally healthy) mixed drink! + qweq12yt: + - bugfix: Fixed sleeping disky spam (it still sleeps soundly, but every minute instead + of every two seconds) + - bugfix: Fixed Hulks not breaking cuffs, zipties, restraints. + silicons: + - code_imp: A deterministic wave explosion system has been added. Use it with wave_explosion(). + zeroisthebiggay: + - rscadd: vegas style bunny ears +2021-05-14: + keronshb: + - balance: Removes VOG sleep command since it was an undocumented readd. + zeroisthebiggay: + - spellcheck: consealed +2021-05-15: + bunny232: + - bugfix: Corrects the bot pathing by engineering on meta station + timothyteakettle: + - balance: borg spraycans have a five second delay before being able to knock someone + down again +2021-05-19: + WanderingFox95: + - rscadd: The E-Fink, a mending tool for food. + - soundadd: A backwards bladeslice. (Yes, for the E-fink) + - imageadd: And Icons for the E-fink, of course. + shellspeed1: + - rscadd: Survival pods can now be designated as requiring power. Survival pods + with this feature should include an APC when created and will run out of power + rather quickly if no source is added. Perfect for true emergencies. + - rscadd: An empty survival pod has been added to the mining vendor. This is an + extremely barebones pod featuring only a gps, table, apc, and the standard fridge + for some donk pockets. + zeroisthebiggay: + - rscadd: New Alcohol Amaretto and various cocktails + - rscadd: more drink mixture flavortext + - soundadd: you're going to Baystation +2021-05-20: + qweq12yt: + - bugfix: Fixed void cloak voiding itself into oblivion. + - bugfix: You can now order emag shuttles again. + timothyteakettle: + - rscadd: ports rp's marking system +2021-05-21: + Putnam3145: + - bugfix: Fixed activity being attached to minds instead of mobs on antag attach. +2021-05-23: + Putnam3145: + - bugfix: Antag and species no longer remove all traits if one has a blacklisted + trait + WanderingFox95: + - imageadd: Replaced the antlers showing up when you select deer ears with actual + deer ears. Literally why was that even a thing before? + - imageadd: Straight rabbit ears are now a thing. + keronshb: + - balance: 30 > 25 pop req for contractor kit + - code_imp: adds a special hud for simple mobs. + - imageadd: a lot of >32x32 mobs now have icons for their health dolls +2021-05-24: + zeroisthebiggay: + - rscadd: 'New traitor item: the Mauler Gauntlets! Punch hard, punch good! Eight + telecrystals, buy today!' + - rscadd: hairs from Airborne Snitch +2021-05-26: + bunny232: + - bugfix: Removed two random 'captain's office' tiles from space on meta station +2021-05-29: + Kraseo: + - bugfix: No more slamming into people while bloodcrawled. + Linzolle: + - bugfix: brand intelligence event works again + keronshb: + - rscadd: swag outfit available in clothesmate + - rscadd: 'swag shoes availble in clothesmate resprite: changed swag shoes icon + to the one twaticus made.' + - rscadd: Adds the clown mob spawner for admins + zeroisthebiggay: + - balance: puglism damage can no longer stack with scarp diff --git a/html/changelogs/archive/2021-06.yml b/html/changelogs/archive/2021-06.yml new file mode 100644 index 0000000000..8aca39ea54 --- /dev/null +++ b/html/changelogs/archive/2021-06.yml @@ -0,0 +1,242 @@ +2021-06-03: + MrJWhit: + - balance: Removed some debug tiles on the xenoruin. + TripleShades: + - rscadd: Added a camera to both solar entryways + - rscadd: Added an intercom to toxin's launch for the doppler + - rscdel: The fake nuke auth disk in the library +2021-06-04: + MrJWhit: + - rscadd: Adds a missing pipe + Putnam3145: + - bugfix: sniper rifle doesn't ruin your round instantly now +2021-06-05: + Arturlang: + - code_imp: float sanity now makes it not actually run if it's actively being thrown + coderbus13: + - bugfix: Pubby's toxins injector now starts at 200L, like it does on other maps + zeroisthebiggay: + - rscadd: light floppy dog ears +2021-06-06: + bunny232: + - rscadd: Pools are capable of mist at lower temperatures +2021-06-10: + Arturlang: + - balance: Holoparasites for traitors now cost 12 crystals, for operatives 8, the + ricochet eyepath traitor item now 4. + DrPainis: + - rscadd: goliath calamari + - rscadd: cat meteors + Linzolle: + - bugfix: cults can build in maintenance (and other small areas) again. + - bugfix: centcom can no longer be selected as the target area for narsie to be + summoned?????? + MrJWhit: + - balance: Moves medical holodeck to the restricted category + SandPoot: + - code_imp: Uses some of the existing images for the typing indicators. + - bugfix: Fixes soulstone shard not working for non-cultists. + WanderingFox95: + - rscadd: A random event for the cat surgeon to invade the station. Listen for scary + noises! + - soundadd: Screaming Cat SFX, you know, for the mood. + bunny232: + - bugfix: Atmos resin now properly prevents all atmos from moving + - bugfix: Air tanks now properly have a 21/79 o2/n2 mix + - rscadd: Hydroponics can now make 5u of slimejelly by injecting 3 oil, 2 radium + and 1 tinea luxor into a glowshroom + keronshb: + - balance: Made it so Off Balance only disarms if they're shoved into a wall or + person. + - balance: Reduced Off Balance time to 2 seconds. + - balance: Pierced Realities despawn after 3 minutes and 15 seconds, new unresearched + realities spawn in after that time elsewhere to help other heretics get back + into the game. + - balance: A required sacrifice amount for heretic's second to last and last powers + are added to discourage only rushing for holes. + - balance: An announcement automatically plays to everyone that there's a heretic + gunning for ascension upon learning the 2nd to last power + - balance: 'Blade Shatters are now used in hand other than with a HUD icon tweak: + Adjusted some TGUI menus for the book to reflect how many sacrifices a heretic + has and how many are required for certain powers' + - bugfix: Fixes sprite issue for Void Cloak for people who have digigrade legs. + - bugfix: Fixes the Raw Prophet recipe to match the description + - balance: Lets the Cargo Shuttle use Disposal Pipes again + - rscadd: Adds motivation and adds it to the uplink + - rscadd: Adds Judgement Cut projectiles + - rscadd: Adds Judgement Cut hit effects and firing effects. + - soundadd: added sounds for the firing and hit sounds of Judgement Cuts, created + by @dzahlus + - rscadd: Adds Floor Cluwnes and event for midround + - rscadd: Adds Cluwne mutation + - rscadd: Adds Cluwne spell + - rscadd: Adds Cluwnes + - imageadd: Adds Cluwne Mask + shoes + - admin: Adds Floor Cluwne spawn button + - admin: Adds Cluwne smite button + zeroisthebiggay: + - bugfix: Fixed an exploit allowing you to grab people from anywhere with a clowncar. + - balance: revenant essence objective reduced +2021-06-12: + silicons: + - bugfix: xenos are now truly immune to stamina damage. +2021-06-14: + EmeraldSundisk: + - rscadd: 'Adds a brand new, wholly unique mining base to Snaxi tweak: A thorough + redesign of Snaxi (see PR #14818 for more info)' + - bugfix: Increases the number of electrical connections between substations + MrJWhit: + - balance: Removes cat meteors. + SandPoot: + - rscadd: Tablet computers now have a pen slot, they can almost replace your pda! + - spellcheck: Removed a bracket from printer's examine. + - bugfix: The cosmetic turtleneck and skirtleneck no longer start with broken sensors. + TripleShades: + - rscadd: Lights to AI Sat Walkways + - rscadd: Lights to Atmospherics + - rscadd: Floor labels to Atmospherics Gas Miner containment units + - rscdel: Gas canisters from Gas Miner containment units + - rscdel: Excessive wiring in Security and Detective's Office + qweq12yt: + - bugfix: Locker orders now properly bundle together in a single locker (still separated + by buyer). + - bugfix: Changed some package names to be more accurate. + timothyteakettle: + - rscadd: bees can go in containers and are released upon opening the container + - rscadd: 7 more round tips have been added + zeroisthebiggay: + - imageadd: new singularity hammer sprite + - imageadd: various slight sprite additions + - imageadd: distinctive combat defib sprite + - imageadd: a onesleeved croptop accessory sprited by trojan coyote + - imageadd: new bank machine sprite + - imagedel: unused goon coffin sprite + - imageadd: new water cooler sprite +2021-06-15: + EmeraldSundisk: + - rscadd: Xenobiology now has proper lighting + - bugfix: The Corporate Showroom now has a proper front door + - bugfix: Mining snowmobiles now have keys + - bugfix: Adjusts area designations so GENTURF icons should no longer be visible + in-game +2021-06-16: + silicons: + - bugfix: on_found works again +2021-06-17: + Vynzill: + - rscadd: ability to change crafted armwrap sprite to alternate one. + - imageadd: extended armwrap icon and sprite + timothyteakettle: + - bugfix: fixes an oversight causing embed jostling to do 2x as much damage as it + should +2021-06-19: + keronshb: + - bugfix: Ling Bone Gauntlets work again +2021-06-20: + Arturlang: + - rscadd: Port's TG's nanite storage modification programs from the bepis + - bugfix: Fixes infective nanite progreams not syncing cloud ID. + - rscadd: Add's off icons for nanite machinery + - bugfix: Fixes antitox nanites runtiming on simplemobs + - rscadd: Updates the nanite dermal button icon set + - rscadd: Adds the ability to select the logic for nanite rules + - bugfix: Nanite programs with triggers won't ignore rules. + - bugfix: 'Coagluating nanite program research no longer has the wrong name tweak: + Nanite program''s have better descriptions now tweak: Nanite subdermal ID''s + now also include pulled ID''s for simplemobs' + - bugfix: Nanite voice sensors should properly work now. + - bugfix: Fixes nanite comm remote, now they should actually work + EmeraldSundisk: + - rscadd: 'Adds ColorMates to Snow Taxi tweak: Slight adjustments near the arrival + shuttle landing zone' + - rscdel: Removes an undesired corporate entity + Nanotrasen Structual Engineering Division: + - rscadd: Added lables to the atmos tanks on Metastation. + - rscadd: Adjusted Pubbystation's emitter room wall layout to prevent light-breakage + on startup of emitters. + - rscdel: Removed frestanding sink and showers from Metastation science airlock, + and Deltastation Xenobio. Added an emergency shower next to the kill room. + - bugfix: Removed a leftover pipe in Metastation security hallway. + bunny232: + - bugfix: Pressure tanks other then air tanks start with gas! + keronshb: + - rscadd: Adds the Space Dragon midround event + - soundadd: Space Dragon sounds + - imageadd: Space Dragon + effects + - code_imp: Added Spacewalk trait + - code_imp: Gibs the original owner if they are turned into a Space Dragon with + the traitor panel + - admin: logging for Space Dragon creation + kiwedespars: + - rscadd: a downside to wheely heelies ((made it actually detrimental)) + zeroisthebiggay: + - imageadd: beltslot sprites for various items + - imageadd: resprite for telebaton +2021-06-21: + silicons: + - bugfix: glowshroom scaling + timothyteakettle: + - bugfix: vore is 0.1% less shitcode +2021-06-22: + bunny232: + - bugfix: Adds a missing win door to meta xenobiology pen 6 + silicons: + - bugfix: no more doubleroasting +2021-06-23: + DeltaFire15: + - bugfix: A bunch of small nanite things should be less wonky + - bugfix: Slimes are no longer immune to vomiting (undocumented change from a previous + PR) + - bugfix: Fruit wine exists again. + - code_imp: Airlock hacking no longer sleeps. + - code_imp: The clockwork gateway deconstruction no longer sleeps. + - code_imp: Teslium reactions and Holywater booms no longer sleep. + - code_imp: Slime timestop no longer sleeps. + Putnam3145: + - bugfix: inelastic exports no longer uselessly do exponential functions +2021-06-24: + WanderingFox95: + - rscadd: An announcement to let players know the Cat Surgeon has come to visit. + - balance: Upped the Volume of his spawn noise and lowered the spawn weight slightly. +2021-06-25: + MrJWhit: + - rscadd: Adds two missing decals to the 5x5 SM. + brokenOculus: + - rscadd: pillbottles and syringesare now printable from the medbay protolathe, + shiftstart. Hyposprays are now printable in medbay lathe under advanced biotech. +2021-06-28: + Putnam3145: + - bugfix: APCs aren't infinite power anymore + - rscadd: FDA, LINDA without the bookkeeping. + - rscadd: Putnamos, a simpler replacement for Monstermos. If I can get Monstermos + to work, this will be Monstermos instead. + - rscdel: LINDA, the old active-turfs-based atmos subsystem. + - rscdel: Monstermos? I would rather not get rid of this, but I can't get it to + work correctly. + - server: Extools has been removed, and loading extools alongside auxtools will + cause massive problems. If this is tested or merged, remove extools from the + static files. + WanderingFox95: + - rscadd: Carrots are good for your eyes - but eyes are also good for your carrots. + Adds the googly eyes trait to walkingshrooms (Oculary Mimicry) + - imageadd: Googly Eyes - they make everything better. +2021-06-30: + WanderingFox95: + - rscadd: More plushies in the code. + - imageadd: Nabbed some plushie sprites from Cit RP and TG and made some myself. + Enjoy! + - rscadd: The Daily Whiplash (Newspaper Baton) is now available! (Using sticky tape + to stick a newspaper onto a baton) Bap! + - imageadd: A rolled up newspaper sprite was provided. + - balance: Switched Gateway and Vault locations on Boxstation, bringing it more + in line with other stations. + bunny232: + - rscadd: The pubby xenobiology air/scrubber network is now isolated from the rest + of the station + qweq12yt: + - rscdel: HoP's cargo access was removed... + shellspeed1: + - balance: NT has lost experimental KA tech to miners who were lost in the field. + Make sure to try and recover it. + - rscadd: Adds an extremely expensive survival pod to mining for people to work + towards. Get to work cracking rocks today. diff --git a/html/changelogs/archive/2021-07.yml b/html/changelogs/archive/2021-07.yml new file mode 100644 index 0000000000..433e461bdf --- /dev/null +++ b/html/changelogs/archive/2021-07.yml @@ -0,0 +1,148 @@ +2021-07-02: + silicons: + - bugfix: spray bottles work again. +2021-07-03: + DeltaFire15: + - bugfix: Turrets on nonlethal mode now once again shoot till the target is stamcrit + as opposed to unable to use items, resolving some issues. + Putnam3145: + - bugfix: A bunch of sleeping process() calls now either don't sleep or make sure + to call a proc with waitfor set to FALSE + WanderingFox95: + - bugfix: The axolotl ears in the .dmi file actually exist to the game now. +2021-07-04: + cadyn: + - server: Updated server scripts for proper linux support +2021-07-05: + Putnam3145: + - bugfix: Watchers no longer search 9 tiles away for stuff then throw the result + away if it's more than 1 tile away + - server: Auxmos pull now uses a tag instead of pulling straight from the main branch + WanderingFox95: + - bugfix: Moved a sprite one pixel to the left. + zeroisthebiggay: + - imageadd: tg based tool resprites + - bugfix: wirecutters have proper overlays +2021-07-07: + DeltaFire15: + - bugfix: Golem / Plasmaman species color should work again. +2021-07-09: + MrJWhit: + - bugfix: Made a light not exist on the same tile as a door on pubby. + - bugfix: Makes the RD APC automatically connect to the powernet with the correct + wire on pubby. + - rscadd: Added another wall for the AM engine so it doesn't space the airlock roundstart. +2021-07-10: + WanderingFox95: + - imageadd: Returns the wheelchair sprites to having, you know, wheels? + - rscadd: 'A motorized wheelchair addsound: Chairwhoosh.' +2021-07-11: + shellspeed1: + - balance: replaces the seed machine with a biogen in the survival pod. + - bugfix: corrected an issue regarding wrong pair of gloves in the pod for DYI wiring + . +2021-07-12: + Putnam3145: + - refactor: causes_dirt_buildup_on_floor is now just a thing humans do instead of + a weird var only true for humans +2021-07-13: + MrJWhit: + - rscadd: Adds a mirror above the sink in the captains bedroom in pubby +2021-07-14: + Putnam3145: + - refactor: Acid is now a component +2021-07-15: + Putnam3145: + - bugfix: fixes a major source of lag +2021-07-17: + cadyn: + - server: precompile.sh updated +2021-07-18: + timothyteakettle: + - bugfix: fixes photosynthesis stopping nutrition going past well fed from non-photosynthesis + means +2021-07-19: + Arturlang: + - bugfix: The crafting button should no longer silently make more copies of itself + on reconects + - code_imp: There are no longer two copies of the crafting component. + - code_imp: 'There is no longer a rogue d in tracer.dm tweak: Everything in Misc + was moved to Miscelanious in the crafting menu, and Misc was nuked from orbit. + Nobody will miss you.' + MrJWhit: + - bugfix: Fixes a memory leak, there's a good chance that it's the same one that + killed kilo. + SandPoot: + - rscadd: Put back mob vore with a pref. + - code_imp: Taken some stuff from tg for tgui_alert. + - refactor: Refactored a lot of code on vore panel. + WanderingFox95: + - rscadd: custom plasteel kegs + YakumoChen: + - rscadd: You can now wear the suffering of others on your head with just a sheet + of human skin! + - imageadd: Human skin hats + keronshb: + - rscadd: Stripping/equipping things to a conscious braindead person (AKA a human + owned by a disconnected player) will now give them a message with your visible + name and roughly how long ago you touched their stuff when they login again. + Touching someone's pockets or adjusting their gear other than equipping/unequipping + is not logged. After 5 minutes, you'll have forgotten both their name and exactly + how long ago past those 5 minutes it happened. (Credit to Ryll-Ryll) + - rscadd: LAZYNULL + - rscadd: Breaking mirrors now gives you a bad omen + timothyteakettle: + - bugfix: anthros can now select the cow tail + - rscadd: new quirk that allows you to eat trash +2021-07-23: + silicons: + - balance: Batons are slightly more powerful. +2021-07-24: + MrJWhit: + - rscadd: Replaces the northwest maint room on box with a sadness room + - rscadd: Replaces bar stripper room with an arcade on boxstation + - rscadd: Squished the west bathrooms a bit and made a room to sell things on boxstation. + - balance: Southeast maint hallway on box is now ziggy and zaggier. + - bugfix: Fixed pipes being not connected with the recent map PR for boxstation. + Putnam3145: + - bugfix: hallucination now bottoms out at 0 + - balance: supermatter now causes only half the hallucinations + cadyn: + - server: auxmos bump for dependencies.sh +2021-07-26: + SandPoot: + - rscdel: Removes a sneaky transform button on the vore panel. +2021-07-27: + Putnam3145: + - bugfix: Generic fires work now + - balance: A knock-on effect of the HE pipe change is that space cooling is ~8.4x + as powerful +2021-07-29: + EmeraldSundisk: + - rscadd: Adds decals between Virology and the general Medbay to provide clarity + - rscadd: Adds an airlock with access to the Engineering Cooling Loop + - rscadd: The Maintenance Theater now has a suitable amount of dust + - rscdel: Removed an errant entertainment monitor left in the morgue + - rscdel: 'Removed redundant scrubber piping in and around the bar and kitchen tweak: + Slightly readjusts an airpipe to take advantage of newfound space tweak: The + Toxins Lab has received (predominantly) visual adjustments as to render it more + in line with the general science department tweak: Toxins Storage is no longer + its own area and as such needn''t worry about APCs' + - bugfix: Hydroponics now has a proper APC as intended +2021-07-31: + MrJWhit: + - bugfix: Fixes some minor mistakes around space near boxstation. + TripleShades: + - rscadd: 'Fountain area to public mining station-side tweak: Moved around the tables + and chairs and monitor at public mining station-side' + WanderingFox95: + - rscadd: 'Added new ruin maps: The Bathhouse, The Library, The Engineering outpost, + The Hotsprings(un-cursed), Lust, Wrath and an alternate spawn for the BDM in + the form of a mining outpost, based on the same Ruins on the Ice Moon. removed: + A lot of the fun items within the ice moon-based ruins that would break mining + even more and trading cards.' + - balance: 'Yes, this includes that the lavaland version of the hot spring is literally + just water and not cursed. tweak: Also "fixed" that only one version of the + BDM ruin ever spawns. Not sure it needed fixing but even locally hosted, only + blooddrunk2.dmm would spawn. Since I added another spawn for the BDM, I fixed + that too.' diff --git a/html/changelogs/archive/2021-08.yml b/html/changelogs/archive/2021-08.yml new file mode 100644 index 0000000000..f2ad5124a1 --- /dev/null +++ b/html/changelogs/archive/2021-08.yml @@ -0,0 +1,119 @@ +2021-08-02: + TripleShades: + - rscadd: 'Decorative (read: Station-safe) water tile in the code' + - bugfix: Pubby's new water feature wont kill atmosphere anymore +2021-08-03: + zeroisthebiggay: + - balance: tempgun is a laser + - balance: bake mode is useful + - balance: tempgun has less shots + - imageadd: tempgun has more sprites +2021-08-04: + BlueWildrose: + - bugfix: The debrained overlay actually shows for brainless corpses now instead + of showing a blue error. + timothyteakettle: + - bugfix: legs are no longer awful +2021-08-05: + Putnam3145: + - bugfix: organs decay again +2021-08-07: + BlueWildrose: + - bugfix: The black dress, pink tutu, the bathrobe, the kimonos, and the qipaos + no longer have a missing pixel when wearing them with the feminine bodytype. + They're also no longer adjustable (they have no sprite for the adjusted variant + and therefore it would just make an error if someone did that.) + Putnam3145: + - balance: 'Supernova rad storms are now half as likely per tick tweak: Supernovae + don''t announce they''re ending if they never announced they''re starting tweak: + Supernovae say explicitly no rad storms can happen if they can''t' + - rscadd: Monstermos is back +2021-08-09: + Arturlang: + - bugfix: Nanite machinery overlays should now work properly + - code_imp: screen objects are now atom/movables instead + - code_imp: Update appearance is used for updating atoms now instead of update_icon + and such + BlueWildrose: + - bugfix: Old gateway animation is back. Feedback is given that the gateway is open + again. + Putnam3145: + - balance: Rod of asclepius can now be used for revival surgery +2021-08-11: + timothyteakettle: + - rscadd: lets felinids, humans and moths have markings +2021-08-12: + Arturlang: + - rscdel: Nonslimes and nonvampires will no longer be able to increase their blood + to stupid heights + Putnam3145: + - refactor: Supermatter values use auxgm + cadyn: + - server: precompile.sh and build.sh updated, auxmos set to 0.2.3 in dependencies.sh +2021-08-13: + Putnam3145: + - bugfix: makes certain organs no longer have circular references +2021-08-16: + BlueWildrose: + - bugfix: Incapacitated mobs are blacklisted from being human-level intelligence + sentience event candidates. This is particularly important due to slimes in + BZ stasis on the station. + bunny232: + - bugfix: Polyvitiligo actually changes your color now +2021-08-18: + timothyteakettle: + - rscadd: lets you select 4 prosthetic limbs instead of only 2 +2021-08-20: + EmeraldSundisk: + - rscadd: Adds a law office/courtroom to OmegaStation + - rscadd: Adds a gateway to OmegaStation + - rscadd: Adds a pool/maintenance bar to OmegaStation + - rscdel: 'Removes the original maintenance garden in OmegaStation tweak: Relocates + the bathrooms to the starboard hall tweak: Modifies port quarter maintenance + to include some affected items' + Putnam3145: + - rscadd: Beach now has showers + TripleShades: + - rscadd: At least four or five space heaters spread across Pubby Station Maints + - rscadd: Missing decal in Pubby Station engineering + - bugfix: Moved an atmos alarm in the SM emitter chamber so it wont be destroyed + WanderingFox95: + - rscadd: Empty bottles and pitchers are available to the bartender now. + - imageadd: They even come with 10 different fillstates! + - imageadd: Better Shark Tails, dodododododo~ + - rscadd: The old ones are now listed as carp tails. +2021-08-22: + zeroisthebiggay: + - spellcheck: trillby can't spell pair +2021-08-23: + zeroisthebiggay: + - spellcheck: i hate the grammarchrist +2021-08-24: + BlueWildrose: + - balance: MK ultra explosions (failures at making MKultra) are gone, and replaced + with a gas that just causes a bunch of status effects to you. +2021-08-26: + keronshb: + - rscadd: Adds catwalk floors +2021-08-28: + DeltaFire15: + - bugfix: 'Demons now drop bodies on their own tile instead of scattering them across + the station. tweak: Space dragon content ejection is now slightly safer.' + - bugfix: Space dragons no longer delete their contents if they die due to timeout, + ejecting them instead. + - bugfix: Carp rifts created by space dragons now have their armor work correctly. + Putnam3145: + - config: Planetary monstermos can now be disabled with varedit + - rscadd: Lavaland/ice planet atmos is no longer a preset gas mixture and varies + per round + keronshb: + - rscadd: Ports Inventory Outlines + - imageadd: Re-adds the old glue sprite + - rscadd: Adds Plague Rats + - rscadd: Gives Plague Rat spawn conditions for regular mice + - imageadd: Plague Rat sprite + - rscadd: Gremlin + - imageadd: Gremlin sprites + zeroisthebiggay: + - rscdel: grilles as maintenance loot + - rscadd: sevensune tail from hyperstation diff --git a/html/changelogs/archive/2021-09.yml b/html/changelogs/archive/2021-09.yml new file mode 100644 index 0000000000..831eb56899 --- /dev/null +++ b/html/changelogs/archive/2021-09.yml @@ -0,0 +1,247 @@ +2021-09-01: + BlueWildrose: + - bugfix: The waddle component now takes size into account when running rotating + animations, thus not reverting character sizes to default size. + ma44: + - bugfix: Weapon rechargers now have their recharger indicators again. + - bugfix: Energy guns now update when switching modes again. + - bugfix: Stabilized yellow slime extracts will now update cells and guns it recharges. + - rscadd: Weapon rechargers will now be more noticeable when it has finished recharging + something. + zeroisthebiggay: + - bugfix: the fucking chainsaw sprite +2021-09-03: + timothyteakettle: + - bugfix: fixes losing your additional language upon changing species +2021-09-04: + Putnam3145: + - bugfix: Might've fixed some ghost sprite oddities nobody even knew about + WanderingFox95: + - bugfix: Lavaland architects don't screw up so badly anymore and do in fact not + somehow leave holes through the planet surface all the way into space under + their bookshelves. + - bugfix: Snow was removed from Lavaland Ruins. + keronshb: + - bugfix: Fixes entering an occupied VR sleeper bug + timothyteakettle: + - bugfix: makes the arm/leg markings for synthetic lizards appear as an option again +2021-09-05: + DeltaFire15: + - bugfix: Unreadied player gamemode votes now actually get ignored (if the config + for this is enabled). +2021-09-07: + bunny232: + - bugfix: fixed some jank in pubby's xenobiological secure pen + keronshb: + - bugfix: Gremlins no longer have AA when dead + zeroisthebiggay: + - spellcheck: you can just about +2021-09-08: + keronshb: + - imageadd: Adds the parade outfit for the HoS and Centcomm + - imageadd: Recolors the parade outfit for the Captain + - imageadd: Adds a toggle option for the parade outfits + - bugfix: Observers can no longer highlight your items +2021-09-10: + BlueWildrose: + - rscadd: CTRL + (combat mode) Right Click - positional dropping and item rotation. + keronshb: + - rscadd: Readds Reebe + - rscadd: Added the ability to dye your hair with gradients by using a hair dye + spray. + - rscadd: The new Colorist quirk, allowing you to spawn with a hair dye spray. + - rscadd: Adds Hair gradients to preferences + - imageadd: Three new hair gradients, a pair of shorter fades and a spiky wave. + - bugfix: Adds viewers for mask of madness so it doesn't wallhack + zeroisthebiggay: + - bugfix: Replaced the DNA probe's old sprite (Hypospray) with a unique sprite + - imageadd: added some icons and images for hyposprays and medipens so they stand + out + - imageadd: added inhands for the cautery, retractor, drapes and hemostat. + - imageadd: New icon and sprites for the DNA probe + - imageadd: Emergency survival boxes now have an unique blue sprite and description + to tell them apart from regular boxes. + - imageadd: Added craftable normal/extended emergency oxygen tank boxes to put your + emergency oxygen tank collection inside. + - imageadd: Emergency first aid kits now look visually consistent with full first + aid kits. + - imageadd: Ports new Hypospray, Combat Autoinjector, Pestle, Mortar and Dropper + sprites from Shiptest! + - imageadd: Adds a new sprite for pill bottles! + - imageadd: new surgical tool sprites + - imageadd: The cyborg toolset is now all new and improved, with a new coat of paint! + - imageadd: Updates pride hammer sprites! + - imageadd: Replaced old Mjolnir sprites with new Mjolnir sprites. +2021-09-11: + LetterN: + - code_imp: Tickers, GC, MC, FS updates + - code_imp: rust_g update. It is default that we use their urlencode/unencode now. + - code_imp: updates CBT to juke + - bugfix: CI Cache works properly now + Putnam3145: + - bugfix: Removed some crashes + SandPoot: + - rscadd: 'Cyborg grippers now have a preview of the item you are holding. tweak: + Cyborg grippers no longer drop using alt-click, instead, you try to drop the + gripper to drop the item, and then you can drop the gripper. tweak: You can + now use the "Pick up" verb on the right click menu to take items with a cyborg + gripper.' + - bugfix: You should be able to access the interface of airlock electronics once + again as a borg. + - refactor: Reworks a lot of stuff that was being used on the grippers. + timothyteakettle: + - bugfix: arachnid legs now show up properly + zeroisthebiggay: + - imageadd: reinforcing the mining hardsuit with goliath hide now makes the sprite + cooler + - imageadd: The SWAT helmet is now consistent between its front, side and back sprites + for coloration. + - imageadd: new riot armor sprites +2021-09-12: + LetterN: + - bugfix: lowers the audio volume of ark sfx + - bugfix: readded cwc theme in the index.js once more + timothyteakettle: + - rscadd: allows custom taste text and color on the custom ice cream setting in + the ice cream vat +2021-09-14: + Hatterhat: + - balance: The Syndicate zero-day'd the NT IRN program on modular computers through + cryptographic sequencing technology. NanoTrasen's cybersecurity divisions are + seething. + LetterN: + - code_imp: sync mafia code + Putnam3145: + - balance: Nerfed bad toxins bombs and buffed good toxins bombs. There's no longer + an arbitrary hard research points cap. + keronshb: + - balance: Removes zap obj damage and machinery explosion from the SM arcs + - bugfix: Fixes hitby runtime. + zeroisthebiggay: + - rscadd: the permabrig erp role + - balance: changeling adrenals buff + - bugfix: speedups + - bugfix: bread goes in mouth and not on head +2021-09-17: + DeltaFire15: + - bugfix: Techweb hidden nodes should now show less weird behavior. +2021-09-18: + kiwedespars: + - balance: blacklisted morphine and haloperidol from dart guns +2021-09-20: + BlueWildrose: + - balance: Slime regenerative extracts now require five seconds of wait before they + are used. They add 25 disgust when used. + DeltaFire15: + - bugfix: Catsurgeons should now spawn at more reasonable locations if possible. + - balance: carded AIs can now be converted by conversion sigils (clockcult) + - bugfix: There is now a way to acquire nanite storage protocols (bepis, like the + other protocols), as opposed to them existing with no way to acquire them. + - bugfix: Plastic golems are back to ventcrawler_nude instead of ventcrawler_always + Putnam3145: + - config: monstermos config added, disabled + buffyuwu: + - bugfix: fixed medihound sleeper ui display + - rscadd: Adds 4 redesigned jackets and 2 redesigned shirts to loadout + - bugfix: Holoparasites no long rename and recolor on relog + dapnee: + - bugfix: attaches an air vent that was just there on the AI sat, changes some areas + to what they'd logically be + keronshb: + - bugfix: Plague Rats will no longer spawn thousands of dirt decals + - bugfix: Plague Rats will no longer spawn thousands of corpses + - bugfix: Plague Rats can't spawn or transform off station z anymore + - bugfix: Plague Rats shouldn't explosively grow instantly + - bugfix: Plague Rats won't spawn infinite miasma anymore. + - balance: Plague Rats health is now 100. + - balance: Plague Rats can now ventcrawl through everything to prevent farming. + - bugfix: Slaughter Demons Slam will now wound again on hit. + - balance: Damage for demons back up to 30 + - balance: 'Wound Bonus for demons now at 0. image_add: Adds a sprite for the action + bar' + - refactor: Changed the CTRL+SHIFT Click to an action button. People can see the + cooldown now too. + - rscadd: PAIs can be emagged to reset master + qweq12yt: + - bugfix: Fixed space heaters not being able to be interacted/turned on in non powered + areas + timothyteakettle: + - bugfix: removes passkey from access circuits as its not used anymore + - rscadd: a new mild trauma, **[REDACTED]** + zeroisthebiggay: + - balance: glass has do_after + - bugfix: box perma has power + - bugfix: missing madness mask sprites + - balance: The Spider Clan has recently taken up the Space Ninja project again along + with the Syndicate. Space Ninjas have been drastically changed as a result, + becoming much weaker and more stealth oriented. As a result of cutting costs + per ninja, more ninjas were able to be hired. Expect to see them around more + often. + - bugfix: prisoners cannot latejoin anymore + - bugfix: bone satchel onmob sprites + - rscadd: new tips + - rscdel: old tips + - imageadd: all medipens get inhands + - rscadd: some more brainhurt lines +2021-09-22: + silicons: + - bugfix: dice bags can only hold dice + - rscdel: limb damage changes reverted + - bugfix: crawling can't be adrenals'd +2021-09-23: + KrabSpider: + - code_imp: cryogenics ain't a candidate for anomaly spawns anymore. + buffyuwu: + - rscadd: canvas and spray can are now sold in the fun vendor +2021-09-24: + zeroisthebiggay: + - balance: gremlins become shock immune +2021-09-25: + buffyuwu: + - bugfix: fixes accordions +2021-09-27: + zeroisthebiggay: + - bugfix: helter skelter actually spawns + - bugfix: 'code\modules\mob\living\simple_animal\hostile\plaguerat.dm:139:warning: + newmouse: variable defined but not used' +2021-09-28: + zeroisthebiggay: + - balance: helter skelter loot insanity + - bugfix: helter skelter comms insanity +2021-09-29: + Ghommie: + - rscdel: Animals are no loner n(e)igh-immune to stuttering. + - bugfix: Silicons and animals won't keep stuttering or slurring forever after being + struck by something that made them like that in the first place (such as a Blue + Space Artillery). + Hatterhat: + - balance: Reports from other stations' Wardens blasting themselves in sensitive + places due to mishandled firearms has led to the introduction of a folding-stock + safety for their shotgun, rendering it inoperable while the stock is folded. + - balance: Compact combat shotguns now stay compact when stored, by virtue of being + unable to be extended while in a bag. + - balance: Reloading a shotgun with a shell clip now inflicts melee click delay. + LetterN: + - rscadd: clowncar railgun- i mean gun + - rscadd: more achivements + - rscadd: syndie carp can pick up the disky (and is smart now) + - code_imp: hooks most of the achivements, all of the heretics work now + Putnam3145: + - bugfix: Lavaland can no longer be too cold for its natives to surivive + buffyuwu: + - bugfix: flannels can now be toggled in style from buttoned to unbuttoned + - rscadd: ports more rp and existing tg assets with minor edits into loadout selection + keronshb: + - refactor: Ninja status back in the status menu + zeroisthebiggay: + - bugfix: the monkey shuttle brig + - rscadd: meta gets a prison + - bugfix: the floating fire extinguisher + - balance: fucks the motivation's cost. + - soundadd: a new maintenance ambience +2021-09-30: + Hatterhat: + - rscdel: The xenomorph infestation on Moon Outpost 19 is significantly less prone + to outbreaks, theoretically. + Putnam3145: + - rscdel: Minesweeper's "play on same board" diff --git a/html/changelogs/archive/2021-10.yml b/html/changelogs/archive/2021-10.yml new file mode 100644 index 0000000000..af24aa50fd --- /dev/null +++ b/html/changelogs/archive/2021-10.yml @@ -0,0 +1,76 @@ +2021-10-13: + Hatterhat: + - rscadd: Contraband dealers are now embracing their inner Old Space Westerner. + Look for the Old West Surplus Crate on your mildly-hacked cargo console today. + MrJWhit: + - rscadd: Adds more fire-saftey closets and trashpiles to boxstation + - rscadd: Adds trashpiles to delta. +2021-10-16: + Ryll/Shaps: + - rscadd: Asay now supports pings (via using @[adminckey]) + SandPoot: + - bugfix: If a gamemode fails to load too many times, a safe gamemode will be loaded + instead. + - code_imp: Dynamic is no longer hardcoded, and you can now set a gamemode to be + forced in the configs. + - bugfix: Equip delays are a bit less weird now, only relevant for coders/people + who use straight jackets... on themself, since that's the only thing that uses + it right now. + - bugfix: Toggling arousal will properly update your sprite. + - bugfix: That also means no spam when moving it in your hands. + WanderingFox95: + - bugfix: Removes the quick attack loop (like TG did it) + dapnee: + - rscadd: 'BEPIS to science tweak: moved the courtroom' + keronshb: + - rscadd: Adds the fat dart cigarette and to vendors + - imageadd: Adds the sprites for the fat dart +2021-10-20: + Putnam3145: + - bugfix: Removed a panic from auxmos + - bugfix: Properly implemented hysteresis on heat exchanger processing +2021-10-22: + Putnam3145: + - bugfix: Ashwalker lungs more aggressively attempt to be safe on lavaland + WanderingFox95: + - bugfix: fixed the wielded sprites not showing up properly. + - bugfix: fixed a runtime in the bark box vendor + - imageadd: added a missing tennis ball sprite +2021-10-25: + Putnam3145: + - rscadd: Vent pumps can now be set to siphoning via the air alarm UI + keronshb: + - balance: 10k pirate spending money +2021-10-26: + WanderingFox95: + - rscadd: bone anvils and bone ingots + - imageadd: bone anvil sprites +2021-10-28: + Hatterhat: + - rscadd: 'Proto-kinetic gauntlets! Less straight damage, extra damage on backstabs, + slows Lavaland fauna on counterhit. tweak: The glaive kit has been renamed to + the premium kinetic melee kit, and now has a voucher for either a glaive or + gauntlets.' + - rscadd: NanoTrasen is rolling out a prototype Autoloom, hidden behind Botanical + Engineering. It only processes cotton and logs. Despite its visual similarity + to the recycler, it is entirely tamperproof. + Linzolle: + - bugfix: plasmamen now spawn in their proper outfit in the ghostcafe + Putnam3145: + - rscdel: Removed minesweeper + keronshb: + - balance: -40 wound bonus for DSword + - balance: -20 Wound bonus for Hyper Eu + - bugfix: Fixes hyper eu's slowdown when it's not wielded +2021-10-30: + keronshb: + - balance: Jacq can't burn in the cremator anymore + - balance: Jacq also can't be cheesed off station + - balance: Barth also cannot be destroyed +2021-10-31: + DeltaFire15: + - bugfix: You can now drag things over prone people again. + DrPainis: + - bugfix: Walking no longer makes you fat. + keronshb: + - balance: Christmas trees are now indestructible diff --git a/html/changelogs/archive/2021-11.yml b/html/changelogs/archive/2021-11.yml new file mode 100644 index 0000000000..e8dfabd4b0 --- /dev/null +++ b/html/changelogs/archive/2021-11.yml @@ -0,0 +1,152 @@ +2021-11-05: + keronshb: + - balance: removes required enemies + - balance: Lowers assassination threat threshold +2021-11-06: + Putnam3145: + - bugfix: Ashwalkers should no longer suffocate on lavaland (and hypothetical other + future problems) + - bugfix: A gas mix with 0 oxygen should now properly suffocate you (or 0 plasma, + for ashwalkers) +2021-11-08: + timothyteakettle: + - bugfix: fixes party pod sprite + - bugfix: fixes red panda head marking +2021-11-10: + Ethan4303: + - rscadd: Added two wire nodes under the engineering PA room Apc and under the HOS + office APC + - rscadd: Added cables to connect the second floor relay to the power grid + - rscdel: Removed the generic broken computer from Hos Office + - bugfix: Fixed Hos office not having the Security records console + Putnam3145: + - bugfix: Power alerts now work + - bugfix: No longer have too much O2 from too much CO2 + SandPoot: + - rscadd: Crayon precision mode. +2021-11-11: + DrPainis: + - bugfix: The universe has realized that not every species uses hemoglobin again. + Putnam3145: + - refactor: '"REM" removed, replaced with "REAGENTS_EFFECT_MULTIPLIER", which "REM" + is short for' +2021-11-13: + Putnam3145: + - balance: Chonker cubans pete now no longer have a reasonable chance to be unbeatable +2021-11-14: + TripleShades: + - rscadd: (Pubby) Surgery table to Brig Medical + - rscadd: (Pubby) Dirt decals added to Command maint + - rscadd: (Pubby) Decals and gavel block to Courtroom + - rscadd: (Pubby) Training bomb to Birg + - rscdel: (Pubby) Chapel stripper pole room + - rscdel: '(Pubby) Command maint storage shed room tweak: (Pubby) Makes Arrivals + atmos room into a main atmos grid room akin to what Meta has' + - bugfix: (Pubby) Gulag shuttle spawning in a tile off from the airlocks + - bugfix: (Pubby) Air Injector in Medical maints having no power + - bugfix: (Pubby) Incorrect area on one side at AI Sat where the turrets are + - bugfix: (Pubby) Arrivals atmos is now linked to the main atmos grid + - bugfix: (Pubby) Medbay front airlocks access + keronshb: + - admin: Admins get messaged if dynamic midrounds fail to hijack +2021-11-16: + Putnam3145: + - bugfix: Lavaland can no longer go below 281 kelvins + TripleShades: + - bugfix: (Pubby) Engineering security checkpoint no longer has a duplicate records + console +2021-11-18: + DeltaFire15: + - bugfix: Devastation level explosions no longer delete your organs after gibbing + you. + - code_imp: Adjusted all overrides of ex_act() and contents_explosion() to take + account of current args for them. + - code_imp: 'Reebe can now be loaded via a proc. tweak: The clockwork relay in reebe + is now indestructible and not deconstrutible to avoid some issues.' + Putnam3145: + - bugfix: Regal rat can no longer keep spawning stuff while dead + SandPoot: + - rscadd: When your statpanel doesn't load, you'll get a message with a button to + fix it. + - bugfix: The fix chat message button now works. + keronshb: + - rscadd: Ball + - rscadd: Spookystation Map + - rscadd: Tree chopping/Grass cutting + - rscadd: Vectorcars +2021-11-19: + shellspeed1: + - rscadd: 'An experimental smart dart repeater rifle has been added by NT. It accepts + both a large and small hypovials and uses it to fill the smart darts it synthesizes. + It can hold 6 smart darts and makes a new one every 20 seconds. To research + it, grab the medical weaponry node. tweak: Reagent gun renamed to reagent repeater' + - balance: reagent repeater now holds 6 syringes. + - balance: Reagent repeater and smart dart repeater rifle start with 4 syringes + instead of a full clip. + - balance: 'reagent repeater synthesizes a new syringe every 20 seconds. tweak: + smart dart guns now use the syringe gun as an inhands sprite.' +2021-11-20: + SandPoot: + - bugfix: Acid will disappear when not existant. + - code_imp: Updates component Destroy code, might result in less component related + runtimes. +2021-11-21: + DeltaFire15: + - rscadd: Power cord implants can now also be connected to cells to recharge. + - rscdel: Synthetics can no longer bite power cells. + LetterN: + - rscadd: Search option on the cwc slab + MrJWhit: + - balance: Reduces the HP from loot piles to 100, from 300. + TripleShades: + - rscadd: '(Pubby) Loot piles to maint halls remove: (Pubby) CMO''s sex dungeon + tweak: (Pubby) Surgery layout is now more open' + keronshb: + - rscadd: 'Adds Cogscarab spell tweak: Cogscarabs gib now because I have no idea + how to fix the issue of dead pogscarabs eating up the limit.' +2021-11-23: + TripleShades: + - rscadd: '(Pubby) Paramedic Office tweak: (Pubby) Moved Medbay delivery to the + south hall entrance' + - bugfix: (Pubby) Morgue wall being labeled as Bar +2021-11-24: + timothyteakettle: + - bugfix: oil drum now recognises synthetic anthormorphs as synths +2021-11-25: + Arturlang: + - rscadd: Buldmode mapgen save tool + SandPoot: + - rscadd: Double Bed Type. Miners can also make Double Pod Beds to really feel like + an Alaskan King. + - rscadd: Bedsheets to match! Try to share those big blankets with a lizard if you + see that they're shivering! + - code_imp: Stuff that lets you interact with the benches and beds in-game, so that + you too can enjoy being a king. + - imageadd: Ports the Double Bed sprites from Skyrat. + - bugfix: Dealt with some weirdness when buckling to beds. +2021-11-28: + SandPoot: + - imageadd: Legless sprite for it + TripleShades: + - rscadd: (Meta) Adds meters to the refill/scrubber station outside Engineering + - rscadd: (Meta) Adds a small light fixture to southeast solar access + - rscadd: (Meta) Places an intercom to southeast solar access + - rscadd: (Meta) Gives a cautery to Robotics + - rscadd: (Meta) Camera to Incinerator + - rscadd: (Meta) Linen bin to dorms + - rscadd: (Box) Camera to Incinerator + - rscadd: (Box) Painting mounts to Library + - rscadd: (Pubby) Painting mounts to Library + - rscdel: '(Meta) Removes the example tanks from the Atmospherics gas chambers tweak: + (Box) Moves the Bar camera from out behind the soda dispenser tweak: (Box) Gives + dorm room 6 a double bed to start tweak: (Pubby) Moves linen bin in washroom + to a table tweak: (Delta) Moves the plant in Medbay''s Storage to not be in + front of a vendor tweak: (Delta) Moves the gas miners and labels inside the + Atmoshperics gas chambers to the centers' + - bugfix: (Box) Made the upper Execution Chamber airlock unable to be used by the + AI + - bugfix: (Box) Moves prison cell 4 and 6's shutter button to the wall + keronshb: + - rscadd: FestiveMap + - rscadd: Specific Truck and Ambulance vector cars + - rscadd: Radials for those cars diff --git a/html/changelogs/archive/2021-12.yml b/html/changelogs/archive/2021-12.yml new file mode 100644 index 0000000000..cc359c8a99 --- /dev/null +++ b/html/changelogs/archive/2021-12.yml @@ -0,0 +1,82 @@ +2021-12-01: + DeltaFire15: + - balance: Pellets now care about block woundwise + - balance: Pellet wound-bonus no longer stacks for the final calculation + - balance: Embeds no longer bypass full blocking. + - bugfix: Shields now work properly against unarmed / mob attacks. +2021-12-02: + DeltaFire15: + - balance: Synthetics gained quasi-immunity to most chemicals, excluding some core + medical chems and a few specific disruptive ones. + - rscadd: Health analyzer, ChemMaster and chemical analyzer interactions with the + chemical processing flag system. + - bugfix: System Cleaner should now always update health as opposed to before. + - balance: system cleaner is now twice as effective. +2021-12-03: + TripleShades: + - rscadd: (Pubby) Holopad to surgery viewing area +2021-12-05: + Arturlang: + - rscadd: You can now put in LaTeX equations in TGUI paper if you insert them between + two $ dollar signs + DeltaFire15: + - bugfix: Fireman carry no longer drops the carried person if passing over a prone + individual. +2021-12-09: + DeltaFire15: + - bugfix: Linters should no longer scream. + Linzolle: + - bugfix: it now only snows on festivestation instead of every map + - bugfix: rain now triggers properly on spookystation + TripleShades: + - rscadd: (Pubby) Gives Robotic's Lab Surgery a cautery + keronshb: + - rscadd: Lets dynamic pick clock cultists midround + timothyteakettle: + - bugfix: being fat no longer makes you slower when floating +2021-12-11: + SandPoot: + - bugfix: Borg speech is now centralized even inside lockers or something like that. + bunny232: + - bugfix: Cold blooded critters won't worry too much about the air around them being + too hot even though their body temperature is the same as it. + - balance: The warm pool is no longer nearly boiling and the cool pool no longer + goes below 0C. +2021-12-12: + DeltaFire15: + - bugfix: Linters should no longer complain about afterattack sleeps. +2021-12-13: + Putnam3145: + - bugfix: Per-minute science output fixed +2021-12-17: + DeltaFire15: + - bugfix: The time for admins to cancel events is 30 seconds again. + SandPoot: + - bugfix: Fixes assembly holders. +2021-12-21: + ShizCalev: + - bugfix: Fixed an issue where you were able to remove flashlights/bayonets that + were supposed to be permanently attached to a gun. + - bugfix: Fixed an issue where you were unable to remove flashlights & bayonets + from certain weapons. + - bugfix: Fixed a potential issue where adding a flashlight to your helmet would've + caused you to lose other action buttons. + - bugfix: 'Fixed a issue where guns with multiple action buttons would break all + but one of those action buttons. tweak: If you have both a bayonet and a flashlight + attached to your gun, you''ll now be given a prompt on which you''d like to + remove when using a screwdriver on it. tweak: Hacking a firing pin out of a + gun is no longer done via a crafting menu - you can now do it by simply holding + the gun in your hand and clicking it with a welder/screwdriver/wirecutters.' +2021-12-23: + Putnam3145: + - bugfix: Atmos group processing heuristic no longer does opposite of intent +2021-12-29: + TripleShades: + - rscadd: (Festive Station) Fixes + - rscadd: 'Readds the cold to Festive Station tweak: (Festive Station) Fixes' + - rscadd: (Pubby) Cautery??? I think this is leftover but nobody has touched Pubby + since me so it's fine probably +2021-12-31: + SandPoot: + - bugfix: You also no longer get every animation sprite and direction sprite of + items on the menus. diff --git a/html/changelogs/archive/2022-01.yml b/html/changelogs/archive/2022-01.yml new file mode 100644 index 0000000000..babd85cd96 --- /dev/null +++ b/html/changelogs/archive/2022-01.yml @@ -0,0 +1,95 @@ +2022-01-02: + DeltaFire15: + - admin: Station names now require admin approval instead of autoaccepting. + Putnam3145: + - bugfix: Bluespace pipes +2022-01-03: + TripleShades: + - rscadd: '(Meta) Floodlight to Atmospherics tweak: (Meta) Atmospherics Entryway + layout change tweak: (Meta) Atmospherics Monitoring room layout tweak tweak: + (Meta) Atmospherics Supply Line room airlock location change' + - bugfix: (Meta) Incinerator Access airlock now has the correct access +2022-01-04: + Hatterhat: + - imageadd: Jumpboots now have a mining sprite. Alt-click, as usual, to change 'em. + MrJWhit: + - rscadd: Adds pipes to the SM to make omega better + - bugfix: Various omega fixes + Putnam3145: + - rscadd: Hydrogen gas (no way to get yet) + - rscadd: Gas groups, such as... + - rscadd: Chemical gases, starting with ethanol, bromine, diethylamine, ammonia, + phlogiston + - rscadd: Bromine gas (can make it by tossing hot bromine on the ground OR by burning + methyl bromide) + - rscadd: Ammonia gas (toss hot ammonia on the ground OR burn diethylamine) + - rscdel: 'Snowflake trit/plasma fires fires tweak: Generic fires are now more accurate + energy-wise tweak: Water vapor condensation no longer happens below 40 C tweak: + Methyl bromide now burns properly' + - balance: Massive fusion nerf + - balance: Due to the removal of snowflake trit fires, trit fires are much, much + less hot + - balance: 'Due to the previous, bombs are now easier to reach 50,000 points on + (2 : 1 plasma : oxy at 160 kelvins cold side should be fine)' +2022-01-07: + MrJWhit: + - rscadd: Adds an airlock between atmos and engineering on omega. +2022-01-10: + Linzolle: + - bugfix: bloodsplatter effects no longer white in certain cases + - bugfix: the blood in the BDM ruin is no longer white + Putnam3145: + - bugfix: Alcohol works again +2022-01-14: + Putnam3145: + - admin: More logging for bad ERP reagent mechanics + - balance: Made supernova rad storms less strong, slightly more common (but less + spammy) +2022-01-23: + DeltaFire15: + - balance: Synths no longer take direct damage from low blood. They will however + suffer from lower cooling efficiency and be in danger of overheating. + - balance: The temperature system of synths is now simillar to the coldblooded trait, + though depending on environment and coolant level, with access to short bursts + of direct control via active cooling. + - balance: Synths no longer breathe. If in crit, they meltdown and suffer burn damage + over time. + - balance: Synths are now immune to low pressure, resistant to low temp, and vulnerable + to high temp. + - balance: Synths no longer process oxyloss and temperature adjustment chemicals. + - balance: 'Nanogel is now printable at med- / scilathes and mechfabs after researching + the Advanced Robotics node. It does need a bit of diamond though. tweak: All + Synthetics now use blood type S' + Putnam3145: + - rscadd: Atmospheric Flux event + - balance: A lot more fluids can be used for replica pods + Trilbyspaceclone: + - rscadd: New type of flora to lava land, an Ash Tree, can be harvested for coal + or if lucky used to gather honey. Just use a container! +2022-01-25: + Putnam3145: + - bugfix: Artificial zeolite now has a taste + - spellcheck: '"Zeolites" has been renamed to "zeolite" ("a beaker of zeolites" + is like "a beaker of woods")' + - spellcheck: Various taste descriptors have had their end punctuation removed +2022-01-26: + LetterN: + - rscadd: Antag info panel using tgui for selected antags + - code_imp: TGUI hardsync + - code_imp: TIMER_DELETE_ME flag for timers + - code_imp: 'wiremod backend (DO NOT ENABLE, FOLLOWUP PR WILL ADD WIREMOD) tweak: + Cryo DOES NOT store the items, instead only drops it as soon as the person "fully + cryo" tweak: Changes on how uplink works. Purchases are now only based on if + said uplink has the right flag to purchase an item, rather than using a list + to whitelist/blacklist specific gamemodes for it. Also, the purchase items handles + poplocking by themselves now.' +2022-01-28: + DeltaFire15: + - rscdel: genital fluids are once again not valid for pod cloning, nor do the decals + have dna (I hate the fact I had to PR this because the original got merged with + this still present) + SpiWat: + - spellcheck: fixed a typo, I hope +2022-01-29: + Arturlang: + - bugfix: Fixes Papers not working due to a dependency updated. diff --git a/html/changelogs/archive/2022-02.yml b/html/changelogs/archive/2022-02.yml new file mode 100644 index 0000000000..12ad63274c --- /dev/null +++ b/html/changelogs/archive/2022-02.yml @@ -0,0 +1,176 @@ +2022-02-01: + SpiWat: + - spellcheck: tweenty --> twenty +2022-02-02: + BlueWildrose: + - bugfix: Sylvan should actually be speakable for those who have taken that language + as roundstart now, and for plantpeople who naturally start with it. + - bugfix: The langauge Neo-kanji's shortcut was overlapping with the slime language, + and has been relocated from k to j. + - bugfix: The langauge Dwarvish's shortcut was potentially overlapping with drones, + and has been relocated from D to w. + - bugfix: The language Rachnidian's shortcut was getting in the way of the Ratvarian + language, so it's been moved from r to c. +2022-02-08: + CoreFlare: + - rscadd: Humanity is... Ok. Blood is fuel. IPCs have wings. + DeltaFire15: + - balance: Stabilized orange extracts can only cool by -5 degrees per tick base + instead of by as much as the difference is. + - balance: "Stabilized orange extracts only have halved cooling effects on Synthetics\ + \ (2.5 per status tick / 5 per life), but also cool them towards ~-100\xB0C\ + \ instead of base bodytemp." + - balance: The Space Adaptation mutation when applied to Synthetics now nullifies + the penalty for passive cooling if in low-pressure environments. + LiteralMushroom: + - rscadd: Slimes can have wings now. + SakuraOran: + - rscadd: Ashwalkers can now heal, even from death, by being incapacitated (asleep/dead) + near the tendril + - rscadd: Added the ability for antags to have the "protect object" objective, which + the ashwalkers now have to protect the tendril. This is determined by if the + object is broken or not, and can be set to any object or structure that can + reasonably be destroyed + - balance: Ashwalkers get one life, and have a 40% chance to earn an additional + life when they sacrifice to the tendril. + - bugfix: fixed mobs not dropping guaranteed_butcher_results when gibbed + SandPoot: + - qol: Changing a reagent container's transfer amount will now give you feedback + in the form of text on the container itself. + - rscadd: 'TGUI autolathe tweak: You can now input a custom amount to print(hard + limit at 50 or maximum stack size) tweak: Can now search and change categories + while the autolathe is busy, line up those designs!' + - bugfix: You can once again see your previews for picking target bodyparts on your + hud. + - refactor: Converted the changelog popup to TGUI + - rscadd: Adds a keybinding where you can cancel actions. + - rscadd: Made a cool UI for the custom shuttles. + - bugfix: Removes "Convert Lineendings" git action. + - rscadd: All of your favorite simple bot friends aboard the station now have a + much better interface in TGUI + - qol: You can now lock and unlock bots, including their maintenance hatches, via + the UI. + silicons: + - refactor: clickcatchers, parallax +2022-02-14: + keronshb: + - rscadd: Adds the new MRP version of Families + - rscadd: Adds the new Antag UI panel for Families, disables it for other antags + (for now) + - rscadd: Adds High Fives (needed for the Handshake) + - rscdel: Removed old Gang War + - bugfix: Fixed Observer Alerts and general alerts for give/take/restraints. + - soundadd: Adds related sounds for Families + - imageadd: Adds related icons for Families + - code_imp: Changed the petehat/gang to just petehat on the jungle away mission + - code_imp: Adds HAND_ITEM + - code_imp: A bunch of UI code for Antags/Families + - code_imp: Adds IS_DEAD_OR_INCAP + - code_imp: Adds GLOBAL_LIST_EMPTY(pre_setup_antags) + - code_imp: Adds Queued Deletions + - code_imp: Sanity check for attached_effect + - code_imp: Adds Suicide cries for antags + - code_imp: Adds preview_outfits for antags + - refactor: Refactors give/take > offer/receive + - config: Added Families to the dynamic config + - admin: Adds admin tp Family stuff +2022-02-17: + '[Timberpoes](https://github.com/Timberpoes)': + - admin: Re-added the button to the player playtime panel that lets admins toggle + a player's job playtime exemption status. +2022-02-19: + timothyteakettle: + - rscadd: polychromic clown outfit and mask +2022-02-20: + jupyterkat: + - refactor: switched equalization method to katmos +2022-02-21: + BlueWildrose and tralezab, Wjohnston, Mey Ha Zah, ArcaneDefense, Jack7D1, Papaporo, Sheits & Mqiib from TG and Yog: + - rscadd: TG wing port - All species can now use flight potions and grow wings. + Your wing sprite will be based off of what wings you have on your character, + or otherwise what species you are if you have no wings. + - bugfix: Jellypeople did not call the species parent proc on spec_life. Fixed. + Putnam3145: + - bugfix: Default features on linux auxmos compile now formatted correctly + - bugfix: reinforced plasma glass windows are buildable + TripleShades: + - rscadd: '[Omega] Gateway shutter button' + - rscadd: '[Omega] Signs to the airlocks that lead to space that say SPACE' + - rscadd: '[Omega] Air Alarm for the Turbine itself' + - rscadd: '[Omega] SMES Unit for the Turbine itself' + - rscadd: '[Omega] Firelock to Robotics airlock' + - rscadd: '[Omega] Captain''s Office now has a hand teleporter and medal box' + - rscadd: '[Omega] Screwdriver to Chemistry' + - rscadd: '[Omega] Space Cleaner bottle to Medbay' + - rscadd: '[Omega] Limb Grower and Spare Limb Crate to Surgery' + - rscadd: '[Omega] Kinkmate in Dorms' + - rscadd: '[Omega] Lightbulb fixture to Secure Tech Storage' + - rscadd: '[Omega] Armsky is now in the Armoury' + - rscdel: '[Omega] Extra automated announcement machine' + - rscdel: '[Omega] Wall inside of southwest Solar Array window' + - rscdel: '[Omega] Wall inside library maint airlock' + - rscdel: '[Omega] Duplicate Robotics airlock tweak: [Omega] HoS gun now spawns + in HoS locker instead of Captain''s locker tweak: [Omega] Both Solar Arrays + now have more windows tweak: [Omega] PACMAN moved out from behind a Command + airlock in Engineering tweak: [Omega] A few cameras so that they''re not sitting + improperly on windows tweak: [Omega] Medbay Surgery now has a surgical duffel + instead of strewn about tools tweak: [Omega] Security Cell 1 is now properly + named and has a bed instead of a chair tweak: [Omega] Toxins scrubber piping + now goes through a wall tweak: [Omega] Robotics trash can is now moved to the + small hallway between Robotics and Toxins tweak: [Omega] Maint Pool drain moved + down a tile so it''s easier to retrieve lost items' + - bugfix: '[Omega] Lawyer Office access' + - bugfix: '[Omega] Both Solar Arrays are now wired up to power the station properly' + - bugfix: '[Omega] Wire leading to the single Supermatter Emitter should now be + properly connected and not diagonal' + - bugfix: '[Omega] Gateway Maint airlock access' + - bugfix: '[Omega] Toxins Launch not being connected to the main air supply' + - bugfix: '[Omega] Toxins Mix Chamber no longer starts bolted' + - bugfix: '[Omega] Missing pipe above Security leading into Perma' + - bugfix: '[Omega] Secure Tech Storage now properly has an area' +2022-02-23: + SandPoot: + - bugfix: You know the training targets? You can grab them again now with your own + hands, instead of using telekinesis. + TripleShades: + - rscadd: '[Omega] Trash chute to space in Virology' + - rscadd: '[Omega] Trash chute to space in Xenobiology' + - rscadd: '[Omega] Airlock leading out to Supermatter cooling pipeline' + - rscadd: '[Omega] Two more air pumps to Toxins' + - rscadd: '[Omega] Robotics circuitry printer' + - rscadd: '[Omega] Windoor to Cargo delivery flaps' + - rscdel: '[Omega] Backdoor to Gravity Generator' + - rscdel: '[Omega] Bunched up cameras tweak: [Omega] Pipes leading to the Incinerator + burn chamber are now black tweak: [Omega] Gravity Generator airlocks are now + accessible by engineers tweak: [Omega] Chapel mass driver and mass driver bulkhead + are now controlled by one button instead of two' + - bugfix: '[Omega] Lawyer''s carpet is no longer airless' +2022-02-25: + TripleShades: + - rscadd: '[Omega] Additional Solar Panels to both existing arrays' + - rscadd: '[Omega] Floor tile underneath library maint airlock' + - rscadd: '[Omega] Contraband locker to Armoury' + - bugfix: '[Omega] Solar Array SMES Units actually connect to the grid properly + now' + timothyteakettle: + - rscadd: adds snake coiling +2022-02-26: + Putnam3145: + - balance: Now slightly easier to get 50,000 points with toxins (50,000 point baseline + changed from 200 light range to 175) +2022-02-28: + Arturlang: + - rscadd: The limbgrower can make human chest parts that you can build onto into + a person. + Putnam3145: + - rscadd: Configurable weekly high-chaos days + SandPoot: + - refactor: Kills off SLOT_ in favor of ITEM_SLOT_ + SandPoot and Crowbar764: + - rscadd: TGUI for the player playtimes menu. + bunny232: + - rscadd: Cold weather gear can now provide insulation against temperatures of up + to 57C (330K) + timothyteakettle: + - rscadd: adds a cartridge for the bartender's PDA that lets them search drink recipes + - rscadd: updates chemist cartridge to be able to search all chemical recipes diff --git a/html/changelogs/archive/2022-04.yml b/html/changelogs/archive/2022-04.yml new file mode 100644 index 0000000000..64f12efa8f --- /dev/null +++ b/html/changelogs/archive/2022-04.yml @@ -0,0 +1,54 @@ +2022-04-08: + SandPoot: + - bugfix: Make changelogs actually get added! +2022-04-09: + AnthurK: + - bugfix: Fixes bots trying to path through dense corners. + Arturlang: + - rscadd: Adds stasis beds and related mechanics + - rscdel: Removed mapped in sleepers from station maps. Shuttles have it but centcomm + doesn't. +2022-04-10: + SandPoot: + - bugfix: The action button for leaving mechs actually works! + - bugfix: The medigax no longer uses gygax armor plates to be built! + - bugfix: The firefighter ripley is now visible during construction. + - bugfix: Medigaxes can actually be built now. + Solaris-Shade: + - bugfix: fixed a few projectile lines + - code_imp: changed a large block of the projectile code + - refactor: refactored most of the projectile code + tiviplus, lolman360, SandPoot: + - refactor: /obj/mecha > /obj/vehicle/sealed/mecha +2022-04-15: + BlueWildrose: + - rscadd: Added carcinisoprojection jelly, a limb regrowth chemical made from xenobiology's + slime mutation toxin & blood. Don't overdose! +2022-04-16: + SandPoot: + - bugfix: Progressbars no longer stay after completing/failing their task. +2022-04-17: + Putnam3145: + - bugfix: 'Fires are back on Linux tweak: Linux-only: plasma and trit fires work + as before' + SandPoot: + - bugfix: Fixes testicle shape saving. + - code_imp: Initialize(mapload) + - rscadd: Added deadminning preferences (only affects admins). + maxspells: + - expansion: Surgery steps play sound effects appropriate to the step +2022-04-28: + Putnam3145: + - rscadd: 'Methane-based planetary atmospheres tweak: Advanced fire extinguishers + can now remove non-plasma flammable gases' + - rscadd: Nitric oxide (NO), with reactions associated + - rscadd: A maximum temperature above which all gases break down into quark matter, + which will break down into gases again if it goes below that temperature. + SandPoot: + - rscadd: The stasis beds can now be researched alongside being built. + - balance: Maps are now half stasis beds and half sleepers... only in medbay. + - bugfix: The stasis bed's examine now works. + - refactor: Generally updates stasis bed's code and adds cooldown defines (i learnt + how to use them) + timothyteakettle: + - spellcheck: trashcan quirk now uses correct grammar diff --git a/html/changelogs/archive/2022-05.yml b/html/changelogs/archive/2022-05.yml new file mode 100644 index 0000000000..e55d2a3bca --- /dev/null +++ b/html/changelogs/archive/2022-05.yml @@ -0,0 +1,49 @@ +2022-05-03: + Putnam3145: + - bugfix: Round times are accurate now + SandPoot: + - bugfix: Actually fixes dragging storage items into themself. + timothyteakettle: + - rscadd: sodium sensitivity quirk +2022-05-13: + Bhijn & Myr: + - rscadd: The server's hub tagline now has the option to pull random strings from + strings/server_taglines.txt! + LiteralMushroom: + - rscadd: alter form affects wings + - rscadd: Synths get to spark too. + SandPoot: + - rscadd: Status displays can now be built. + - rscadd: AIs can now quickly modify their status displays using an emote (*bsod)! + - rscadd: AIs can also modify their status displays by just clicking on the devices + (opens a radial wheel)! + - refactor: Status displays simply look a lot better now. + TomGarou: + - rscadd: Added Reprogramming to surgeries via Techweb under Alien surgery and Brainwashing + disk + - balance: Synths and non Synths can now be brainwashed equally + - bugfix: Brainwash surgery not working with synths due to metal heads +2022-05-14: + Putnam3145: + - rscadd: Smelly gases (Bromine, methane, ammonia, nitric oxide and stimulum in + particular) + - rscadd: Easier-to-make-visible gases; gases made visible with this system are + bromine and hydrogen (plus nitryl, but that was already visible in the same + way) + - bugfix: 'Scrubbers scrub chems properly tweak: Air alarms now show all gases, + not just ones they''re hardcoded to show tweak: Contaminated now only removes + "dangerous" gases (this is actually a consequence of the hardcode reduction) + tweak: Water vapor is now counted as DANGEROUS (this makes it included in "contaminated" + and adds admin logging when people open water vapor cans)' +2022-05-17: + timothyteakettle: + - rscadd: poly alt cloak can now be renamed/dedescriptioned in loadout +2022-05-19: + timothyteakettle: + - rscadd: quirks are now organised into three tabs for positive, neutral and negative +2022-05-21: + Bhijn & Myr: + - bugfix: Blood trails no longer have a duplicate directionless iconstate as their + base sprite, fixing the Wonkiness of blood trails going west/east. + SandPoot: + - bugfix: Silicon flavor texts are no longer broken... maybe? diff --git a/html/changelogs/archive/2022-06.yml b/html/changelogs/archive/2022-06.yml new file mode 100644 index 0000000000..9365a633b1 --- /dev/null +++ b/html/changelogs/archive/2022-06.yml @@ -0,0 +1,171 @@ +2022-06-01: + DeltaFire15: + - bugfix: Mechs now use power when moving. + - bugfix: The check for mining-only mechs is no longer inverted to only allow non-mining + z levels. + - bugfix: Reverted an accidental buff from the /tg/ mech code port and its adjustment + to citadel's mech state. + - bugfix: 'Mechs with different base movement power cost now actually have it apply + instead of immediately being overwritten. tweak: Adjusted part impact on movement + power use to make more sense.' + timothyteakettle: + - rscadd: 'optimises quirks somewhat tweak: nyctophobia will now stop run intent + when you try to move in darkness with it on, compared to the old behaviour of + automatically turning it off in darkness when it is on and you have been in + darkness for >= 0.2 seconds tweak: nyctophobia and lightless will both not update + your mood until you move now, as part of the optimisations made by changing + them to tg code' +2022-06-02: + Bhijn & Myr: + - bugfix: You can no longer attach multiple tracking beacons to a single mech, fixing + an exploit where mechs can be nuked with minimal effort. + - bugfix: Omegastation's airmix filter is no longer inverted! The oxygen:nitrogen + levels of Omega later in the round should now be normal again. + - rscadd: 'The TGS bot is now capable of pinging the reboot role! Rejoice! tweak: + The TGS bot''s automated output can now be configured to define which channels + certain messages are output to.' + - rscadd: Jukeboxes now have a queue! You can pay 40 credits to have any song of + your choosing queued up for playback on the jukebox! + - rscadd: Jukeboxes can now be emagged, allowing you to boost their volume up to + 210%, along with removing all of its access restrictions. Additionally, a sufficiently + loud jukebox is fully capable of causing potentially permanent damage to your + ears. + - rscadd: 'Jukeboxes now support multi-z! This is self-explanatory. tweak: Volume + knobs now work on jukeboxes! tweak: Muffled jukeboxes have been given a buff. + tweak: Sounds now factor in the distance multiplier for their baseline z offset. + tweak: SOUND_UPDATE now bypasses the can_hear() check in playsound_local() (thanks + Azarak for helping figure this out!)' + - bugfix: 'Jukebox audio no longer uses playsound_local(), allowing falloff to properly + apply to jukeboxes (this fixes the bug where they were significantly quieter + than intended) tweak: When deaf, jukeboxes no longer mute the playing track + permanently.' + - bugfix: Ears are capable of taking damage again. + - rscadd: Jukeboxes have been added to Boxstation, Lambdastation, Metastation, and + Omegastation + - bugfix: Boxstation's incinerator sensor now properly reports to atmos's machinery + again + Putnam3145: + - balance: Nitryl is higher risk, can't be sold for as much + - refactor: Gas prices are now part of the gas data structure + TrojanCoyote: + - rscadd: sprites for muzzled and non muzzled mobs for the masks, along with the + adjusted versions, icons for the masks as well. + bunny232: + - rscadd: Universal blood type now accepts bug blood. +2022-06-03: + Bhijn & Myr: + - bugfix: Solar panels now actually face the proper direction. This is achieved + by reducing the iconstate to only 1 dir. +2022-06-06: + SandPoot: + - refactor: Completely replaces the new player panel *not the admin one* with TG's. + timothyteakettle: + - rscadd: adds paper skin and glass bones quirks +2022-06-08: + Bhijn & Myr: + - bugfix: Audiovisual redirection now works exactly as it used to. In laymen's terms, + this means folks in VR sleepers are aware of the world around them again! + - rscadd: During pride month, station nukes are significantly more efficient at + revealing genders. + - rscadd: Station pets now retain their color between shifts! + - bugfix: The shake animation, jiggle animation, squish animation, jitter animation, + and float animation, have all been fixed. + - bugfix: This also means that storage animations are fully working again. It's + been a few years! + - bugfix: 'The pull animation no longer interrupts ongoing animations. tweak: The + pull animation now supports diagonal directions (currently only applies to the + initial grab! pull code is spaghetti)' + - bugfix: All screenshake sources now fully support the screenshake pref + - code_imp: cit_screenshake.dm has been fully merged into the base files. + - bugfix: You can no longer remotely apply fingerprints to storage objects by clicking + and dragging it around. Additionally, storage objects now rustle again when + clicking and dragging (only took like,, a year to fix) + - bugfix: 'The pickup animation now properly slides into your spaceman again, instead + of just kinda disappearing. tweak: When pulling a resting mob, they''ll now + skip the laying animation entirely, fixing a visual oddity where they shrink + and grow to flip. tweak: Alerts are now a little snappier and bouncier, as they''ve + been swapped from sine easing, to back easing. tweak: Radial menus now use sine + easing, rather than linear easing. This just looks a little prettier. tweak: + Runechat now properly respects an object''s X offset. Previously, it relied + on a hardcoded check for dogborgs. tweak: The float animation now uses pixel_z + instead of pixel_y, fixing issues where the Y offset gets wiped due to the float + animation. This also makes floating fully compatible with ctrl+WASD.' + - bugfix: Admin vote deobfuscation now properly displays votes as 0 if they were + simply never voted for. + SandPoot: + - refactor: Does some extremely minor touches on pulling/pushing code. + timothyteakettle: + - rscadd: updates existing poly maid outfit with tg sprite but polychromatic + - rscadd: adds polychromic maid apron, gloves, collar, headband + - rscadd: adds support for polychromic accessories +2022-06-12: + Bhijn & Myr: + - rscadd: The station minimap now features higher detail! Instead of just windows + and grilles being outlined, all dense+anchored structures and machinery are + shown on the minimap. + - rscadd: The station minimap now supports obfuscating entire areas, via the minimap_show_walls + var. + - rscadd: 'The station minimap now supports defining two area colors, allowing for + a checkerboard pattern! tweak: Hallways and maint have been given white and + gray colors, respectively, for ease of readability. tweak: Ruins are now obfuscated + on the minimap, and have been given a subtle, yet distinct, color pattern!' + - bugfix: The station minimap no longer errors when you mouse over it + - rscadd: 'The station minimap now supports multiz! (However, due to bugginess, + multiz minimaps won''t display area tooltips.) tweak: The station minimap now + features pixel-perfect scaling.' + - code_imp: The station minimap can now support managing data for up to 16,581,374 + areas without any conflicts at all! Before, BYOND's psuedorandom RNG meant that + it was somewhat common for areas to collide with each others' data. + - rscadd: Talking is now accompanied with fully-customizable sounds! You can modify + your character's speech under the speech tab in chargen, and you can toggle + these sounds via the "Hear/Silence Vocal Barks" verb under the preferences tab! + This also fully supports genetics. + - bugfix: Admittedly an unatomized change, but Cit's DNA blocks can now properly + be updated through genetics. Before, these required a complete genetics reset + to apply. + - rscadd: 'The chat now supports blockquotes! tweak: Examining, medical scanners, + self-checking, and mood checkups, have all been converted to make use of blockquotes.' + Bhijn & Myr (+ UI work and cleanup by Sandpoot!): + - rscadd: 'Colormates now have HSV coloration! tweak: Colormates have had their + "please use white clothing" message removed, as that recommendation''s now mostly + pointless tweak: The default mode for colormates is now HSV coloration tweak: + The temp messages in colormates have been tweaked slightly to be more user-friendly, + as they''re user-facing. tweak: The description for constants in the colormate + matrix mode has been fixed; the constant variables have nothing to do with contrast, + they simply add color tweak: Matrix mode has been made a lot more usable; it''s + now clamped between -10 and 10, and features a step of 0.01, making it much + easier to simply click and drag to adjust the values, rather than having to + punch them in manually' + Putnam3145: + - balance: QCD matter is now worth 10x as much and makes 2 research pointer per + mole + SandPoot: + - rscadd: Added a search box to all vending machine uis. + - qol: Vending machines have candystripes for better clarity. + - bugfix: Fixed items that use strip_mod and strip_silence (stripping people faster + or without giving them a message) + keronshb: + - bugfix: Families fixed from crashing +2022-06-13: + Bhijn & Myr: + - bugfix: Jukebox audio is now audible within closets, crates, etc! +2022-06-19: + IHOPMommyLich: + - rscdel: Removed the forced dynamic, allowing the standard game mode vote. + TripleShades: + - bugfix: Cannabis mutation variants now use the proper growth state icons + - bugfix: Picking to make tea cups will now give the right starting glasswork base + - bugfix: Picking to make tea plates will now give the right starting glasswork + base + - spellcheck: Fixed a state typo in tea cup glassworking + - spellcheck: Fixed an incorrect step displayed on spout glassworking + - code_imp: Enables the make priority announcement admin verb for admin use +2022-06-21: + Bhijn & Myr: + - balance: Ling abilities now have a default loudness of 0.5. This change applies + to every single ability that used to have 0 loudness. + TrojanCoyote: + - rscadd: Adds a plate carrier to HoS loadout, sprites for such +2022-06-29: + Putnam3145: + - bugfix: GAS_OXYGEN -> GAS_O2 diff --git a/html/changelogs/archive/2022-07.yml b/html/changelogs/archive/2022-07.yml new file mode 100644 index 0000000000..99a1e1103e --- /dev/null +++ b/html/changelogs/archive/2022-07.yml @@ -0,0 +1,103 @@ +2022-07-05: + Putnam3145: + - bugfix: Miasma is brown again +2022-07-09: + Bhijn & Myr: + - code_imp: Barks can now be intercepted via component signals. Both bark queuing + and individual barks can be intercepted via signals! + - rscadd: The "Brassy" bark has been added, using the cog installation sound as + a sample! This works surprisingly well as a bark + - rscadd: 'Genetics can now give people goose1.ogg tweak: If new barks are queued + before the current barks are finished, this will interrupt all ongoing barks + tweak: Yelling no longer cuts the minimum bark time variance down to half, as + this proved to sound pretty awful with most barks. tweak: Chitter now uses a + completely unique audio sample, which is based on the original ratchet.ogg it + used to be. This new sample is shorter, and has significantly less harsh noise + on the higher frequencies, making it much easier on the ears. Additionally, + the minimum speed for chitter has been reduced from 6 to 4. tweak: Setting vocal_bark + to a file should now automatically turn it into a sound datum (in theory, at + least! as of writing i haven''t tested this at all)' + - bugfix: Barks and other DNA features after the first mob color now work exactly + as you'd expect. This was the cause for horrid eldritch bark sounds when the + wrong part of DNA gets hit. The first mob color has lost some genetics resolution + as an indirect result of this (the higher resolution is what caused this bug) + UDaV73rus, Tokoriso, dragomagol: + - rscadd: welding now has an animation! + timothyteakettle: + - rscadd: slimes no longer die from having no blood, properly consume limbs when + at low blood, and suffer brute damage and oxygen loss for having no blood and + no limbs left to consume respectably, they cannot go past BLOOD_VOLUME_MAXIMUM + from consuming toxin +2022-07-16: + MediHound: + - rscdel: Removed old Alina sprites + - rscadd: Added new Alina sprites + SandPoot: + - bugfix: The tweak tag for changelogs should now work. +2022-07-20: + Putnam3145: + - balance: quark matter is now worth 5% as much and gives 10% the research points + timothyteakettle: + - bugfix: makes brain trauma event respect canSpawnEvent conditions such as min + players +2022-07-21: + SandPoot: + - bugfix: If you have a dark purple stabilized extract and are holding nothing in + your hand, no longer attempts to heat nothing, which caused immense amounts + of runtimes. + - bugfix: The syndicate has fixed the radiation health analyzer allowing you to + check on the ui again. +2022-07-23: + TripleShades: + - rscdel: Snow Cabin turbine + - tweak: Snow Cabin, Jungle Resort, and Plasma Outpost gateways now use RTGs for + power generation + - balance: Snow Cabin SMES unit is now non-magical + - bugfix: Snow Cabin gateway wiring now connected properly +2022-07-24: + Bhijn & Myr: + - tweak: The typo in Polly's name has been fixed, severing the decade-old reference + to a 2012-era TGstation coder. If you know, you know. + BlueWildrose: + - qol: Two new Kinkmates have been added to Deltastation in the dorms and arrivals + area. + - bugfix: Cleanbots will no longer go invisible when they get turned on or off. + - qol: Public library paintings have been added to Omegastation. You can now submit + paintings that will appear in later rounds on that station. +2022-07-25: + BlueWildrose: + - bugfix: Fixes hierophant walls letting non-casters pass through them. + - qol: Player-controlled cleanbots can now clean messes that ordinarily wouldn't + be clickable as long as they are clicking the tile it's on. + - bugfix: The shocked autolathe will no longer infinitely zap you with the menu + open. + - bugfix: Using wirecutters on an autolathe with an open panel will now have appropriate + behavior of opening the wire menu. + - bugfix: Harvested grown inedibles now take their seed stats into account instead + of acting like they got adminspawned. + - bugfix: Tea now dispenses from dispensers again. + - bugfix: Pink tea and Pink milk are pathed correctly. + SandPoot: + - bugfix: Put arguments into handle_blood (it needs them). +2022-07-27: + timothyteakettle: + - bugfix: slime limb regeneration ability fix +2022-07-31: + Putnam3145: + - rscadd: Atmospheric flux event (properly) + - rscadd: Sandstorm event (was in files, just disabled; 10 space dusts all at once) + - tweak: Random brain trauma can now trigger if there's an AI, chemist, virologist, + captain, HoP or roboticist + - balance: Flux anomaly min player count 10->0 + - balance: Pyroclastic anomaly min player count 0->5 + - balance: Cat surgeon weight 8->5 + - balance: Disease outbreak min player count 10->3, now requires medbay + - balance: Heart attack min player count 40->10, now requires medbay + - balance: Mass hallucination max occurrences 2->5 + - balance: Supermatter surge max occurrences 2->5, now half as strong on CO2less + setups (lerping up to old value for 100% CO2) + - balance: Supernova max occurrences 2->1, weight 10->5 + - balance: 'Vent Clog: Normal min players 25->0, random chem prob 1%->0%' + - balance: 'Vent Clog: Threatening min players 35->15' + - balance: 'Vent Clog: Catastrophic min players 45->25' + - rscadd: Random shoe untying diff --git a/html/changelogs/archive/2022-08.yml b/html/changelogs/archive/2022-08.yml new file mode 100644 index 0000000000..6890cbb6b9 --- /dev/null +++ b/html/changelogs/archive/2022-08.yml @@ -0,0 +1,184 @@ +2022-08-01: + Putnam3145: + - bugfix: rad collectors display the right units now + - balance: Stasis beds are now 90% as good as surgery tables for surgery +2022-08-02: + SandPoot: + - admin: Alphabetically ordered bitfields for admin editing. + - admin: It is now easier to change the flags of turrets. + - refactor: Allows for defining bitfields in other files. +2022-08-03: + Putnam3145: + - balance: Research bomb "midpoint" at which it's worth exactly 50000 points from + 240->300 + - code_imp: doesn't snowflake the bomb cap for linux anymore, servers that need + to tweak it can do it themselves (I didn't even put it down right, should be + 5000 instead of 50000, yikes) +2022-08-04: + MrJWhit: + - rscadd: Adds more AI screens on box + TripleShades: + - qol: Three gateways will no longer lose power via Magical SMES Units + timothyteakettle: + - rscadd: lets AIs control status displays (vtuber mode) +2022-08-05: + Hatterhat: + - tweak: The L6 Squad Automatic Weapon, as used by Syndicate nuclear operatives, + now fires 7.12x82mm, with no change in ballistic performance. This has the side + effect of making it now capable of utilizing match-grade ammunition, which some + would think are mutually incompatible concepts. + Putnam3145: + - tweak: Untied shoelaces probabilities rework + - balance: Miner boots are slightly harder to tie/untie now +2022-08-08: + Hatterhat: + - tweak: Proto-kinetic crushers and variants can now be renamed via pen. + - tweak: Custom descriptions on items tagged with UNIQUE_RENAME can now go to 350 + characters, up from 140. + - tweak: Recoil now pushes your screen in the opposite direction of where you're + shooting. It makes sense in context, I swear. Adjust the setting for this in + your client prefs, because it defaults to on. + Linzolle: + - bugfix: catwalk overlays behave properly, appearing on top of cables and such + Putnam3145: + - tweak: Various gases now have shortened names for filters + - balance: Nitric oxide now removes from the power mix like nitrogen/pluoxium do + - balance: Nitric oxide now becomes, at most, 20% nitrogen dioxide instead of 50% + SandPoot: + - bugfix: Fixed the lack of eyes making ERROR appear on people. + - qol: Set up for the dmi editor extension, very helpful as you can see the existant + states and their names opposed to only images in a huge spritesheet. +2022-08-09: + Putnam3145: + - rscadd: 'Adds station traits: Small modifiers that can randomly be chosen each + round. They are usually logged in the intercept the station receives early in + the round' + - refactor: Announcement audio is now stored in a datum to make it easy to add different + announcers +2022-08-17: + Putnam3145: + - bugfix: added a missing signal call to SSticker + TripleShades: + - rscadd: '[Omega] Cleanbot named "Rustbucket" to the Bridge' + - rscadd: '[Omega] Securitron "Pingsky" to AI Sat' + - rscadd: '[Omega] External AI Sat cams around the south' + - rscadd: '[Omega] Unfinished cleanbot to Robotics' + - rscadd: '[Omega] More status displays and AI displays' + - rscadd: '[Omega] Captain''s Wardrobe vendor' + - rscadd: '[Omega] Engineering Supermatter Room now has a YouTool' + - rscadd: '[Omega] Hydroponics front desk now has windoors' + - rscadd: '[Omega] Bar monkey Punpun placed at the Bar' + - rscadd: '[Omega] Paramedical room' + - rscadd: '[Omega] Scrubbers to Xenobiology slime pens' + - rscadd: '[Omega] Xenobiology now has one canister of BZ' + - rscdel: '[Omega] Tiny Medbay reception desk' + - rscdel: '[Omega] Overlapping cams and window-sitting cams' + - rscdel: '[Omega] Defibrillator outside of Medbay Surgery' + - rscdel: '[Omega] Rogue isolated power wire under East Maintenence Airlock' + - tweak: '[Omega] Virology now has a cycling airlock' + - tweak: '[Omega] Xenobiology slime pen floors and kill room floor now match other + stations' + - tweak: '[Omega] Xenobiology main scrubber and vent shifted around' + - tweak: '[Omega] Medbay intercoms are now largely on the unique frequency other + stations use' + - tweak: '[Omega] Certain floors under airlocks now properly match their surroundings' + - tweak: '[Omega] Atmospherics now has layer adaptors' + - tweak: '[Omega] Cargo''s starting crates are shifted around to better show which + belt goes to the shuttle' + - tweak: '[Omega] Engineering Secure Storage button is now in Chief Engineer''s + office' +2022-08-19: + BlueWildrose: + - balance: Removes persistence from the cleanable glowing goo. It'll no longer last + between rounds. + TripleShades: + - rscadd: '[Omega] One decal to better indicate Turbine area' + - rscdel: '[Omega] Duplicate leftover intercom' + - bugfix: '[Omega] Virology Airlock access buttons should actually work' +2022-08-20: + Putnam3145: + - bugfix: Stake (maybe) + - bugfix: Caches the auxmos file if found + - balance: Sandstorm now happens less often, tends to be less powerful and is announced. + zeroisthebiggay: + - tweak: cauteries searing tools and energy scalpels now have heat and can be used + to light cigarettes +2022-08-21: + Hatterhat: + - tweak: Chief engineers now have expert wiring skills, as befitting a crew member + of their assumed caliber. Atmos techs also get more wire skill. + - tweak: Research directors now have trained wiring skills, and scientists have + basic wiring expertise. + - rscadd: 'Cleaving saws now have a Certified FromSoft Classic mechanic: dodge-rolling. + Combat mode RMB with it inhand to use.' + Linzolle: + - rscadd: radial menu to organ manipulation surgery + Onule, PositiveEntropy, TetraZeta, Axietheaxolotl, Thgvr, AdipemDragon: + - imageadd: Completely resprites all medkits! + - imageadd: Completely resprites all medical tools! + - imageadd: Removes the clamp sprite and instead creates separate hemostat and retractor + inhand sprites! + - imageadd: Adds missing inhands for the bonesetter, advanced med tools, tactical + medkit, surgical drill and bone gel! + Putnam3145: + - bugfix: update air ref more aggressively + - bugfix: Binary translator key now has a proper description + - rscadd: Space lube, drying agent, salbutamol, colorful reagent, drying agent chem + gases + - bugfix: Signal commander works now + - tweak: Infinite blood trails are no longer possible + Rohesie: + - tweak: Admins and byond users can now set their OOC color to light values and + it will save in the preferences. + zeroisthebiggay: + - imageadd: crushers + - imageadd: glaives + - imageadd: drills + - imageadd: mining scammers + - imageadd: my mom + - imageadd: new ninja sprites + - imageadd: makes the long gloves look more like their normal counterparts + - imageadd: mauler gauntlets have lost a grand total of three pixels in order to + make them slimmer +2022-08-22: + zeroisthebiggay: + - rscadd: Added polychromatic workout shorts to the loadout and to the clothesmate + vendors for various workout procedures. +2022-08-23: + Linzolle: + - bugfix: suiciding with a stamina projectile now actually works instead of doing + literally nothing + Putnam3145: + - bugfix: security levels work now + TrojanCoyote: + - tweak: slight change to sprite +2022-08-24: + zeroisthebiggay: + - rscadd: hyper slutskirt and secukini +2022-08-25: + Putnam3145: + - code_imp: New Find() lint +2022-08-27: + PositiveEntropy: + - imageadd: Resprites the IPC/pAI recharge cable! + shellspeed1: + - rscadd: new garden survival pod added. . It can be bought from the mining vendor + for 7500 points. + - balance: To reflect the drop in usefulness of the penthouse pod, its price has + been halved. + - tweak: Penthouse survival pod redone, instead of a kitchen and garden it now features + an office area for when a miner feels like writing a book, or shitposting in + the station's modular computer chatroom. + - bugfix: Stacked windows in survival pods fixed. + - tweak: rtgs in survival pods now come prewired, I figured out a new trick woo. +2022-08-30: + Putnam3145: + - balance: Untied shoes are slightly less common + - admin: Better admin logging on potential prefbreak arousal stuff + zeroisthebiggay: + - bugfix: harpy wings layering + - rscadd: and steals the harpy wings from rp so that there is some variety +2022-08-31: + Putnam3145: + - bugfix: has_important_message = TRUE added to a bunch of events so you still know + where that pyro anomaly is with an intern diff --git a/html/changelogs/archive/2022-09.yml b/html/changelogs/archive/2022-09.yml new file mode 100644 index 0000000000..b237689a4f --- /dev/null +++ b/html/changelogs/archive/2022-09.yml @@ -0,0 +1,74 @@ +2022-09-01: + Putnam3145: + - bugfix: Job code is no longer fricked (oh well) + - rscadd: Antag roles can be set to "low" rather than just "enabled" or "disabled", + which will prevent spending antag rep on that antag but make you a low priority + pick + - code_imp: Changed no antags from a special role to a toggle (why did i make it + a special role) + - code_imp: All direct references to ROLE_NO_ANTAGONISTS have been swapped to the + HAS_ANTAG_PREF macro or removed +2022-09-02: + Putnam3145: + - tweak: comfy disky no longer wants the station to blow up + - balance: Field generators now yell if they fail (singuloose nerf) + ? zeroisthebiggay and Tastyfish (https://github.com/Tastyfish) and Fikou (https://github.com/Fikou) + and san7890 (https://github.com/san7890) + : - bugfix: The 2 types of weight machines now have unique in-game names. + - imageadd: New sprites for the weight machines. + - imageadd: new punching bag sprites!!!!!!!!!!!!!!!! + - soundadd: The next time you work out at the gym, please appreciate the new crispness + of the sound when that machine starts to squeak as a result of your effort. + So refreshing. +2022-09-03: + Putnam3145: + - bugfix: Destructive analyzer now does not multiply your stack by 50 +2022-09-14: + timothyteakettle: + - rscadd: lets ghosts click a pAI device to download into it without a master +2022-09-18: + Putnam3145: + - code_imp: Spurious for loop squashed + That REALLY Good Soda Flavor, jacklecroy on GitHub, ported by Hatterhat: + - rscadd: Using certain martial arts will create a combo meter when you attack. + - imageadd: Added combo meter icons. + shellspeed1: + - rscadd: The Quantum Spin design has been brought over from TG for testing in the + Citadel Station facilities. + - balance: Launchpads now have a targeting icon. + - balance: Massive gamebreaking balance. Xenohybrids can now eat DOUGHNUTS. Security + officers everywhere are afraid. + - bugfix: makes it some people can speak the encoded langauge. + - bugfix: makes the xenotongue a xenohybrid tongue so that people with it can speak + other langauges. + - rscadd: Adds the RBMK reactor from NSV. Credit to Kmc2000 for originally making + it. https://github.com/BeeStation/NSV13/pull/828 +2022-09-19: + Putnam3145: + - code_imp: Auxmos updated to 2.0.0 +2022-09-23: + shellspeed1: + - rscadd: Massively buffs talking by adding 3 new speech verbs improving the ability + of everyone to scream at each other. +2022-09-24: + Putnam3145: + - bugfix: Added a check to from-ghosts midrounds making them not able to roll if + there are no ghosts + shellspeed1: + - rscadd: full auto is now available for some weapons. + - rscadd: All automatic weapons now come with a firemode selector switch. + - rscadd: You can now take people hostage with a gun by using it on someone with + the grab intent on. + - bugfix: cyborg mining point card now works again. + - rscadd: Added the posialert console, now ghosts can complain at the roboticist + for not making posibrains. + - rscadd: Borgs now receive access to the comms associated with their department + by default! + zeroisthebiggay, retlaw34 (https://github.com/retlaw34), any%, tetrazeta, zxaber(https://github.com/zxaber): + - imageadd: Restyles the hud + - imageadd: The Airlock Shock Indicator seen when using a Diagnostics Hud has a + new sprite. +2022-09-27: + Putnam3145: + - bugfix: Your custom AI name is no longer stomped if someone decides to name a + station pet "Friend" or whatever diff --git a/html/changelogs/archive/2022-10.yml b/html/changelogs/archive/2022-10.yml new file mode 100644 index 0000000000..b996f9250c --- /dev/null +++ b/html/changelogs/archive/2022-10.yml @@ -0,0 +1,25 @@ +2022-10-09: + KeRSedChaplain: + - balance: lets engineering/service borgs use structure summoning scripture without + having to have another servant + - balance: gives clockwork armor 50 (65 with the buffed version) laser/energy protection, + none from -25 was still a dumb choice + - balance: made Neovgre tankier and cheaper, but slower. No more dying due to an + internal fire that you can't fix yourself! + shellspeed1: + - balance: The borg premium KA has returned as an 8000 point reward in the mining + vendor. +2022-10-10: + Hatterhat: + - rscadd: Proto-kinetic gauntlets now support movesets and weird combo strings! + Examine them twice to take your first steps into field-testing some fighting + game bullshit. +2022-10-13: + Hatterhat: + - bugfix: Shoving organ-containing bodyparts e.g. heads into smart organ storages + now freezes the organs in the head, too. + shellspeed1: + - rscadd: The Public Bounty Console has been added replacing both the coin mint + and the standard cargo bounties. + - rscadd: The Sales Tagger has been added to enable a little bit of entrepreneurship + by the crew. diff --git a/html/changelogs/example.yml b/html/changelogs/example.yml index c44f796755..f37fc68f54 100644 --- a/html/changelogs/example.yml +++ b/html/changelogs/example.yml @@ -6,7 +6,7 @@ # Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) # When it is, any changes listed below will disappear. # -# Valid Prefixes: +# Valid Prefixes: # bugfix # - (fixes bugs) # wip @@ -18,9 +18,9 @@ # sounddel # - (removes a sound) # rscdel -# - (adds a feature) -# rscadd # - (removes a feature) +# rscadd +# - (adds a feature) # imageadd # - (adds an image or sprite) # imagedel @@ -30,7 +30,7 @@ # experiment # - (experimental change) # tgs -# - (TGS change) +# - (messing around with tgs) # balance # - (balance changes) # code_imp @@ -43,9 +43,13 @@ # - (makes changes to administrator tools) # server # - (miscellaneous changes to server) +# expansion +# - (expands something) +# qol +# - (quality of life) ################################# -# Your name. +# Your name. author: " # Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. @@ -56,6 +60,6 @@ delete-after: True # SCREW THIS UP AND IT WON'T WORK. # Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. # Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. -changes: +changes: - rscadd: "Added a changelog editing system that should cause fewer conflicts and more accurate timestamps." - rscdel: "Killed innocent kittens." diff --git a/html/chrome-wrench.png b/html/chrome-wrench.png deleted file mode 100644 index a64f202074..0000000000 Binary files a/html/chrome-wrench.png and /dev/null differ diff --git a/html/coding.png b/html/coding.png deleted file mode 100644 index 887d6b5068..0000000000 Binary files a/html/coding.png and /dev/null differ diff --git a/html/cross-circle.png b/html/cross-circle.png deleted file mode 100644 index e6f2d3228b..0000000000 Binary files a/html/cross-circle.png and /dev/null differ diff --git a/html/hard-hat-exclamation.png b/html/hard-hat-exclamation.png deleted file mode 100644 index e22eb61b8f..0000000000 Binary files a/html/hard-hat-exclamation.png and /dev/null differ diff --git a/html/image-minus.png b/html/image-minus.png deleted file mode 100644 index b2bac2c45a..0000000000 Binary files a/html/image-minus.png and /dev/null differ diff --git a/html/image-plus.png b/html/image-plus.png deleted file mode 100644 index 308c1ae0a2..0000000000 Binary files a/html/image-plus.png and /dev/null differ diff --git a/html/IRV/jquery-ui.custom-core-widgit-mouse-sortable-min.js b/html/jquery/jquery-ui.custom-core-widgit-mouse-sortable.min.js similarity index 100% rename from html/IRV/jquery-ui.custom-core-widgit-mouse-sortable-min.js rename to html/jquery/jquery-ui.custom-core-widgit-mouse-sortable.min.js diff --git a/html/jquery.min.js b/html/jquery/jquery.min.js similarity index 100% rename from html/jquery.min.js rename to html/jquery/jquery.min.js diff --git a/html/music-minus.png b/html/music-minus.png deleted file mode 100644 index 1b9478f43e..0000000000 Binary files a/html/music-minus.png and /dev/null differ diff --git a/html/music-plus.png b/html/music-plus.png deleted file mode 100644 index ea7f36c6ba..0000000000 Binary files a/html/music-plus.png and /dev/null differ diff --git a/html/scales.png b/html/scales.png deleted file mode 100644 index bb28dc9b59..0000000000 Binary files a/html/scales.png and /dev/null differ diff --git a/html/spell-check.png b/html/spell-check.png deleted file mode 100644 index 70b066d12a..0000000000 Binary files a/html/spell-check.png and /dev/null differ diff --git a/html/statbrowser.html b/html/statbrowser.html index 1cb089a189..ecb47c419c 100644 --- a/html/statbrowser.html +++ b/html/statbrowser.html @@ -12,16 +12,27 @@ font-size: 12px !important; margin: 0 !important; padding: 0 !important; + overflow-x: hidden; + overflow-y: scroll; } + body.dark { background-color: #131313; - color: #abc6ec; + color: #b2c4dd; + scrollbar-base-color: #1c1c1c; + scrollbar-face-color: #3b3b3b; + scrollbar-3dlight-color: #252525; + scrollbar-highlight-color: #252525; + scrollbar-track-color: #1c1c1c; + scrollbar-arrow-color: #929292; + scrollbar-shadow-color: #3b3b3b; } #menu { background-color: #F0F0F0; position: fixed; width: 100%; + z-index: 100; } .dark #menu { @@ -38,7 +49,7 @@ } .dark a { - color: #abc6ec; + color: #b2c4dd; } a:hover, .dark a:hover { @@ -80,73 +91,115 @@ .button { background-color: #dfdfdf; - border-color: #cecece; - border-width: 1px; - border-style: solid; + border: 1px solid #cecece; + border-bottom-width: 2px; color: rgba(0, 0, 0, 0.7); - padding: 6px 4px; + padding: 6px 4px 4px; text-align: center; text-decoration: none; font-size: 12px; margin: 0; cursor: pointer; - transition-duration: 0.25s; + transition-duration: 100ms; order: 3; min-width: 40px; } .dark button { - background-color: #444444; + background-color: #222222; border-color: #343434; - color: rgba(255, 255, 255, 0.7); + color: rgba(255, 255, 255, 0.5); } .button:hover { background-color: #ececec; + transition-duration: 0; } .dark button:hover { - background-color: #4d4d4d; + background-color: #2e2e2e; } .button:active, .button.active { background-color: #ffffff; color: black; - border-top: 1px solid #cecece; - border-left: 1px solid #cecece; - border-right: 1px solid #cecece; - border-bottom: 1px solid #ffffff; + border-top-color: #cecece; + border-left-color: #cecece; + border-right-color: #cecece; + border-bottom-color: #ffffff; } .dark .button:active, .dark .button.active { - background-color: #131313; + background-color: #444444; color: white; - border-top: 1px solid #343434; - border-left: 1px solid #343434; - border-right: 1px solid #343434; - border-bottom: 1px solid #131313; + border-top-color: #343434; + border-left-color: #343434; + border-right-color: #343434; + border-bottom-color: #ffffff; } .grid-container { - display: inline-flex; - flex-wrap: wrap; - justify-content: flex-start; - align-items: flex-start; - min-width: 0; - min-height: 0; - white-space: pre-wrap; + margin: -2px; + margin-right: -15px; } .grid-item { - color: black; - width: 150px; - font-size: 11px; - line-height: 24px; - text-align: left; - min-width: 0; - min-height: 0; - white-space: pre-wrap; - padding-right: 12px; /* A little more than two spaces, to look good in IE8 where flex-justify does nothing */ + position: relative; + display: inline-block; + width: 100%; + box-sizing: border-box; + overflow: visible; + padding: 3px 2px; + text-decoration: none; + } + + @media only screen and (min-width: 300px) { + .grid-item { + width: 50%; + } + } + + @media only screen and (min-width: 430px) { + .grid-item { + width: 33%; + } + } + + @media only screen and (min-width: 560px) { + .grid-item { + width: 25%; + } + } + + @media only screen and (min-width: 770px) { + .grid-item { + width: 20%; + } + } + + .grid-item:hover { + z-index: 1; + } + + .grid-item:hover .grid-item-text { + width: auto; + text-decoration: underline; + } + + .grid-item-text { + display: inline-block; + width: 100%; + background-color: #ffffff; + margin: 0 -6px; + padding: 0 6px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + pointer-events: none; + } + + .dark .grid-item-text { + background-color: #131313; } .link { @@ -173,6 +226,10 @@ -ms-interpolation-mode: nearest-neighbor; image-rendering: pixelated; } + + .interview_panel_controls, .interview_panel_stats { + margin-bottom: 10px; + } @@ -242,53 +299,6 @@ if (!String.prototype.trim) { }, 0, 'test'); }()) -// Browser passthrough code --------------------------------------------------- -if (window.location) { - var anti_spam = []; // wow I wish I could use e.repeat but IE is dumb and doesn't have it. - document[addEventListenerKey]("keydown", function(e) { - if(e.target && (e.target.localName == "input" || e.target.localName == "textarea")) - return; - if(e.defaultPrevented) - return; // do e.preventDefault() to prevent this behavior. - if(e.which) { - if(!anti_spam[e.which]) { - anti_spam[e.which] = true; - var key = String.fromCharCode(e.which); - var x = event.x || event.clientX; - var y = event.y || event.clientY; - if(x || y ) // if either of these exist this is happening after a click - return; - window.location.href = "byond://winset?command=keyDown " + e.key; - } - } - }); - document[addEventListenerKey]("keyup", function(e) { - if(e.target && (e.target.localName == "input" || e.target.localName == "textarea")) - return; - if(e.defaultPrevented) - return; - if(e.which) { - anti_spam[e.which] = false; - var key = String.fromCharCode(e.which); - var x = event.x || event.clientX; - var y = event.y || event.clientY; - if( x || y ) // if either of these exist this is happening after a click - return; - - window.location.href = "byond://winset?command=keyUp " + e.key; - } - }); -} -/* document.addEventListener("mousedown", function(e){ - var shiftPressed=0; - var evt = e?e:window.event; - shiftPressed=evt.shiftKey; - if (shiftPressed) { - return false; - } - return true; -}); */ - // Status panel implementation ------------------------------------------------ var status_tab_parts = ["Loading..."]; var current_tab = null; @@ -300,20 +310,80 @@ var spell_tabs = []; var verb_tabs = []; var verbs = [["", ""]]; // list with a list inside var tickets = []; +var interviewManager = {status: "", interviews: []}; var sdql2 = []; var permanent_tabs = []; // tabs that won't be cleared by wipes var turfcontents = []; var turfname = ""; var imageRetryDelay = 500; var imageRetryLimit = 50; -var menu = document.querySelector('#menu'); -var under_menu = document.querySelector('#under_menu'); -var statcontentdiv = document.querySelector('#statcontent'); +var menu = document.getElementById('menu'); +var under_menu = document.getElementById('under_menu'); +var statcontentdiv = document.getElementById('statcontent'); var storedimages = []; +var split_admin_tabs = false; + +var connected = false; +var commandQueue = []; + +// Any BYOND verb call must go through this, as if a verb is sent during reconnect then +// it will cause the reconnect to fail. +// This function will either call immediately, or queue until +// BYOND confirms we are connected. +function send_byond_command(command) { + var href = "byond://winset?command=" + command; + + if (connected) { + window.location.href = href; + } else { + commandQueue.push(href); + } +} + +// Any BYOND commands that could result in the client's focus changing go through this +// to ensure that when we relinquish our focus, we don't do it after the result of +// a command has already taken focus for itself. +function run_after_focus(callback) { + setTimeout(callback, 0); +} + +function connected_to_server() { + if (connected) { + return; + } + + connected = true; + + for (var index = 0; index < commandQueue.length; index++) { + // This is just setting it a lot, is this not going to cancel? + window.location.href = commandQueue[index]; + } + + commandQueue = []; +} + +function update_split_admin_tabs(status) { + status = (status == true); + + if (split_admin_tabs !== status) { + if (split_admin_tabs === true) { + removeStatusTab("Events"); + removeStatusTab("Fun"); + removeStatusTab("Game"); + } + update_verbs(); + } + split_admin_tabs = status; +} function createStatusTab(name) { - if (name.indexOf(".") != -1) - name = name.split(".")[0]; + if (name.indexOf(".") != -1) { + var splitName = name.split("."); + if (split_admin_tabs && splitName[0] === "Admin") + name = splitName[1]; + else + name = splitName[0]; + } if(document.getElementById(name) || name.trim() == "") return; if(!verb_tabs.includes(name) && !permanent_tabs.includes(name)) @@ -386,6 +456,7 @@ function checkStatusTab() { if(!verb_tabs.includes(menu.children[i].id) && !permanent_tabs.includes(menu.children[i].id)) menu.removeChild(menu.children[i]); } + function remove_verb(v) { var verb_to_remove = v; // to_remove = [verb:category, verb:name] for(var i = verbs.length - 1; i >= 0; i--){ @@ -403,7 +474,14 @@ function check_verbs() { } function verbs_cat_check(cat) { - var tabCat = cat.indexOf(".") != -1 ? cat.split(".")[0] : cat; + var tabCat = cat; + if (cat.indexOf(".") != -1) { + var splitName = cat.split("."); + if (split_admin_tabs && splitName[0] === "Admin") + tabCat = splitName[1]; + else + tabCat = splitName[0]; + } var verbs_in_cat = 0; var verbcat = ""; if(!verb_tabs.includes(tabCat)){ @@ -412,7 +490,14 @@ function verbs_cat_check(cat) { } for(var v = 0; v < verbs.length; v++){ var part = verbs[v]; - verbcat = part[0].indexOf(".") != -1 ? part[0].split(".")[0] : part[0]; + verbcat = part[0]; + if (verbcat.indexOf(".") != -1) { + var splitName = verbcat.split("."); + if (split_admin_tabs && splitName[0] === "Admin") + verbcat = splitName[1]; + else + verbcat = splitName[0]; + } if(verbcat != tabCat || verbcat.trim() == ""){ continue; } @@ -441,6 +526,11 @@ function wipe_verbs() { checkStatusTab(); // remove all empty verb tabs } +function update_verbs() { + wipe_verbs(); + send_byond_command("Update-Verbs"); +} + function add_verb_list(v) { var to_add = JSON.parse(v); // list of a list with category and verb inside it to_add.sort(); // sort what we're adding @@ -448,7 +538,14 @@ function add_verb_list(v) { var part = to_add[i]; if(!part[0]) continue; - var category = part[0].indexOf(".") == -1 ? part[0] : part[0].split(".")[0]; + var category = part[0]; + if (category.indexOf(".") != -1) { + var splitName = category.split("."); + if (split_admin_tabs && splitName[0] === "Admin") + category = splitName[1]; + else + category = splitName[0]; + } if(findVerbindex(part[1], verbs)) continue; if(verb_tabs.includes(category)){ @@ -478,6 +575,7 @@ function remove_verb_list(v) { // passes a 2D list of (verbcategory, verbname) creates tabs and adds verbs to respective list // example (IC, Say) function init_verbs(c, v) { + connected_to_server(); wipe_verbs(); // remove all verb categories so we can replace them checkStatusTab(); // remove all status tabs verb_tabs = JSON.parse(c); @@ -510,12 +608,12 @@ function SendTabsToByond(){ } function SendTabToByond(tab) { - window.location.href = "byond://winset?command=Send-Tabs " + tab; + send_byond_command("Send-Tabs " + tab); } //Byond can't have this tab anymore since we're removing it function TakeTabFromByond(tab) { - window.location.href = "byond://winset?command=Remove-Tabs " + tab; + send_byond_command("Remove-Tabs " + tab); } function update(global_data, ping_entry, other_entries) { @@ -625,6 +723,7 @@ function tab_change(tab) { draw_debug(); } else if(tab == "Tickets") { draw_tickets(); +// draw_interviews(); } else if(tab == "SDQL2") { draw_sdql2(); }else if(tab == turfname) { @@ -636,8 +735,9 @@ function tab_change(tab) { } function set_byond_tab(tab){ - window.location.href = "byond://winset?command=Set-Tab " + tab; + send_byond_command("Set-Tab " + tab); } + function draw_debug() { statcontentdiv[textContentKey] = ""; var wipeverbstabs = document.createElement("div"); @@ -646,12 +746,26 @@ function draw_debug() { link[textContentKey] = "Wipe All Verbs"; wipeverbstabs.appendChild(link); document.getElementById("statcontent").appendChild(wipeverbstabs); + var wipeUpdateVerbsTabs = document.createElement("div"); + var updateLink = document.createElement("a"); + updateLink.onclick = function() {update_verbs()}; + updateLink[textContentKey] = "Wipe and Update All Verbs"; + wipeUpdateVerbsTabs.appendChild(updateLink); + document.getElementById("statcontent").appendChild(wipeUpdateVerbsTabs); var text = document.createElement("div"); text[textContentKey] = "Verb Tabs:"; document.getElementById("statcontent").appendChild(text); var table1 = document.createElement("table"); for(var i=0; i < verb_tabs.length ; i++) { var part = verb_tabs[i]; + // Hide subgroups except admin subgroups if they are split + if (verb_tabs[i].lastIndexOf(".") != -1) { + var splitName = verb_tabs[i].split("."); + if (split_admin_tabs && splitName[0] === "Admin") + part = splitName[1]; + else + continue; + } var tr = document.createElement("tr"); var td1 = document.createElement("td"); td1[textContentKey] = part; @@ -740,7 +854,7 @@ function draw_status() { } if(verb_tabs.length == 0 || !verbs) { - window.location.href = "byond://winset?command=Fix-Stat-Panel"; + send_byond_command("Fix-Stat-Panel"); } } @@ -776,6 +890,11 @@ function update_tickets(T){ if(current_tab == "Tickets") draw_tickets(); } +function update_interviews(I){ + interviewManager = JSON.parse(I); + if(current_tab == "Tickets") + draw_interviews(); +} function update_sdql2(S) { sdql2 = JSON.parse(S); if(sdql2.length > 0 && !verb_tabs.includes("SDQL2")) { @@ -805,12 +924,21 @@ function remove_tickets() { } checkStatusTab(); } + +function remove_interviews() { + if(tickets) { + tickets = []; + } + checkStatusTab(); +} + // removes MC, Tickets and MC tabs. function remove_admin_tabs() { href_token = null; remove_mc(); remove_tickets(); remove_sdql2(); +// remove_interviews(); } function add_admin_tabs(ht) { @@ -875,7 +1003,17 @@ function draw_listedturf() { // rather than every onmousedown getting the "part" of the last entry. return function(e) { e.preventDefault(); - clickcatcher = "?src=_statpanel_;statpanel_item_target=" + part[1] + ";statpanel_item_click=1"; + clickcatcher = "?src=_statpanel_;statpanel_item_target=" + part[1]; + switch(e.button){ + case 1: + clickcatcher += ";statpanel_item_click=middle" + break; + case 2: + clickcatcher += ";statpanel_item_click=right" + break; + default: + clickcatcher += ";statpanel_item_click=left" + } if(e.shiftKey){ clickcatcher += ";statpanel_item_shiftclick=1"; } @@ -912,7 +1050,7 @@ function draw_sdql2(){ var td2 = document.createElement("td"); if(part[2]) { var a = document.createElement("a"); - a.href = "?src=" + "_statpanel_" + ";statpanel_item_target=" + part[2] + ";statpanel_item_click=1"; + a.href = "?src=" + "_statpanel_" + ";statpanel_item_target=" + part[2] + ";statpanel_item_click=left"; a[textContentKey] = part[1]; td2.appendChild(a); } else { @@ -938,12 +1076,12 @@ function draw_tickets() { var td2 = document.createElement("td"); if(part[2]) { var a = document.createElement("a"); - a.href = "?_src_=holder;admin_token=" + href_token + ";ahelp=" + part[2] + ";ahelp_action=ticket;statpanel_item_click=1;action=ticket" ; + a.href = "?_src_=holder;admin_token=" + href_token + ";ahelp=" + part[2] + ";ahelp_action=ticket;statpanel_item_click=left;action=ticket" ; a[textContentKey] = part[1]; td2.appendChild(a); } else if(part[3]){ var a = document.createElement("a"); - a.href = "?src=_statpanel_" + ";statpanel_item_target=" + part[3] + ";statpanel_item_click=1"; + a.href = "?src=_statpanel_" + ";statpanel_item_target=" + part[3] + ";statpanel_item_click=left"; a[textContentKey] = part[1]; td2.appendChild(a); } else { @@ -956,6 +1094,55 @@ function draw_tickets() { document.getElementById("statcontent").appendChild(table); } +function draw_interviews() { + var body = document.createElement("div"); + var header = document.createElement("h3"); + header[textContentKey] = "Interviews"; + body.appendChild(header); + var manDiv = document.createElement("div"); + manDiv.className = "interview_panel_controls" + var manLink = document.createElement("a"); + manLink[textContentKey] = "Open Interview Manager Panel"; + manLink.href = "?_src_=holder;admin_token=" + href_token + ";interview_man=1;statpanel_item_click=left"; + manDiv.appendChild(manLink); + body.appendChild(manDiv); + + // List interview stats + var statsDiv = document.createElement("table"); + statsDiv.className="interview_panel_stats"; + for (var key in interviewManager.status) { + var d = document.createElement("div"); + var tr = document.createElement("tr"); + var stat_name = document.createElement("td"); + var stat_text = document.createElement("td"); + stat_name[textContentKey] = key; + stat_text[textContentKey] = interviewManager.status[key]; + tr.appendChild(stat_name); + tr.appendChild(stat_text); + statsDiv.appendChild(tr); + } + body.appendChild(statsDiv); + document.getElementById("statcontent").appendChild(body); + + // List interviews if any are open + var table = document.createElement("table"); + table.className = "interview_panel_table"; + if(!interviewManager) + return; + for(var i = 0; i < interviewManager.interviews.length; i++) { + var part = interviewManager.interviews[i]; + var tr = document.createElement("tr"); + var td = document.createElement("td"); + var a = document.createElement("a"); + a[textContentKey] = part["status"]; + a.href = "?_src_=holder;admin_token=" + href_token + ";interview=" + part["ref"] + ";statpanel_item_click=left"; + td.appendChild(a); + tr.appendChild(td); + table.appendChild(tr); + } + document.getElementById("statcontent").appendChild(table); +} + function draw_spells(cat) { statcontentdiv[textContentKey] = ""; var table = document.createElement("table"); @@ -968,7 +1155,7 @@ function draw_spells(cat) { var td2 = document.createElement("td"); if(part[3]) { var a = document.createElement("a"); - a.href = "?src=" + part[3] + ";statpanel_item_click=1"; + a.href = "?src=" + part[3] + ";statpanel_item_click=left"; a[textContentKey] = part[2]; td2.appendChild(a); } else { @@ -981,16 +1168,34 @@ function draw_spells(cat) { document.getElementById("statcontent").appendChild(table); } +function make_verb_onclick(command) { + return function() { + run_after_focus(function() { + send_byond_command(command); + }); + }; +} + function draw_verbs(cat){ statcontentdiv[textContentKey] = ""; var table = document.createElement("div"); var additions = {}; // additional sub-categories to be rendered table.className = "grid-container"; sortVerbs(); + if (split_admin_tabs && cat.lastIndexOf(".") != -1) { + var splitName = cat.split("."); + if (splitName[0] === "Admin") + cat = splitName[1]; + } verbs.reverse(); // sort verbs backwards before we draw for (var i = 0; i < verbs.length; ++i) { var part = verbs[i]; var name = part[0]; + if (split_admin_tabs && name.lastIndexOf(".") != -1) { + var splitName = name.split("."); + if (splitName[0] === "Admin") + name = splitName[1]; + } var command = part[1]; if (command && name.lastIndexOf(cat, 0) != -1 && (name.length == cat.length || name.charAt(cat.length) == ".")) { @@ -1002,9 +1207,13 @@ function draw_verbs(cat){ } var a = document.createElement("a"); - a.href = "byond://winset?command=" + command.replace(/\s/g, "-"); - a[textContentKey] = command; + a.href = "#" + a.onclick = make_verb_onclick(command.replace(/\s/g, "-")); a.className = "grid-item"; + var t = document.createElement("span"); + t[textContentKey] = command; + t.className = "grid-item-text"; + a.appendChild(t); (subCat ? additions[subCat] : table).appendChild(a); } } @@ -1029,7 +1238,7 @@ function set_theme(which) { if (which == "light") { document.body.className = ""; set_style_sheet("browserOutput_white"); - } else if (which == "dark" || which == "default") { + } else if (which == "dark") { document.body.className = "dark"; set_style_sheet("browserOutput"); } @@ -1040,7 +1249,7 @@ function set_style_sheet(sheet) { var currentSheet = document.getElementById("goonStyle"); currentSheet.parentElement.removeChild(currentSheet); } - var head = document.getElementsByTagName('head')[0]; + var head = document.getElementsByTagName('head')[0]; var sheetElement = document.createElement("link"); sheetElement.id = "goonStyle"; sheetElement.rel = "stylesheet"; @@ -1050,9 +1259,14 @@ function set_style_sheet(sheet) { head.appendChild(sheetElement); } -document[addEventListenerKey]("click", function(e) { - window.location.href = "byond://winset?map.focus=true"; -}); +function restoreFocus() { + run_after_focus(function() { + window.location.href = "byond://winset?map.focus=true"; + }); +} + +document[addEventListenerKey]("mouseup", restoreFocus); +document[addEventListenerKey]("keyup", restoreFocus); if(!current_tab) { addPermanentTab("Status"); @@ -1061,7 +1275,7 @@ if(!current_tab) { window.onload = function() { NotifyByondOnload(); - }; +}; function NotifyByondOnload() { window.location.href = "byond://winset?command=Panel-Ready"; diff --git a/html/templates/footer.html b/html/templates/footer.html deleted file mode 100644 index 5d98f73b15..0000000000 --- a/html/templates/footer.html +++ /dev/null @@ -1,13 +0,0 @@ -
    - -GoonStation 13 Development Team -
    - Coders: Stuntwaffle, Showtime, Pantaloons, Nannek, Keelin, Exadv1, hobnob, Justicefries, 0staf, sniperchance, AngriestIBM, BrianOBlivion
    - Spriters: Supernorn, Haruhi, Stuntwaffle, Pantaloons, Rho, SynthOrange, I Said No
    -
    -
    -

    Creative Commons License
    Except where otherwise noted, Goon Station 13 is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 License.
    Rights are currently extended to SomethingAwful Goons only.

    -

    Some icons by Yusuke Kamiyamane. All rights reserved. Licensed under a Creative Commons Attribution 3.0 License.

    - - - diff --git a/html/templates/header.html b/html/templates/header.html deleted file mode 100644 index 29759234e2..0000000000 --- a/html/templates/header.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - Citadel Station 13 Changelog - - - - - - - -
    - - - - -
    -
    Traditional Games Space Station 13
    - -

    -
    - - - - - -
    - Thanks to: /tg/station, Baystation 12, /vg/station, NTstation, CDK Station devs, FacepunchStation, GoonStation devs, the original SpaceStation developers and Invisty for the title image.
    Also a thanks to anybody who has contributed.
    -
    Have a bug to report?
    Visit our Issue Tracker.
    - Please ensure that the bug has not already been reported, use the template provided here!. - Currently Active GitHub contributor list: -Click Here-
    -
    - - -
    diff --git a/html/tick-circle.png b/html/tick-circle.png deleted file mode 100644 index bcc4dc24b2..0000000000 Binary files a/html/tick-circle.png and /dev/null differ diff --git a/icons/UI_Icons/adventure/default.png b/icons/UI_Icons/adventure/default.png new file mode 100644 index 0000000000..953dd8f2b0 Binary files /dev/null and b/icons/UI_Icons/adventure/default.png differ diff --git a/icons/UI_Icons/adventure/grue.png b/icons/UI_Icons/adventure/grue.png new file mode 100644 index 0000000000..fe60784b61 Binary files /dev/null and b/icons/UI_Icons/adventure/grue.png differ diff --git a/icons/UI_Icons/adventure/signal_lost.png b/icons/UI_Icons/adventure/signal_lost.png new file mode 100644 index 0000000000..94315a6823 Binary files /dev/null and b/icons/UI_Icons/adventure/signal_lost.png differ diff --git a/icons/UI_Icons/adventure/trade.png b/icons/UI_Icons/adventure/trade.png new file mode 100644 index 0000000000..4463120f97 Binary files /dev/null and b/icons/UI_Icons/adventure/trade.png differ diff --git a/icons/UI_Icons/inventory/back.png b/icons/UI_Icons/inventory/back.png new file mode 100644 index 0000000000..210045c1c6 Binary files /dev/null and b/icons/UI_Icons/inventory/back.png differ diff --git a/icons/UI_Icons/inventory/belt.png b/icons/UI_Icons/inventory/belt.png new file mode 100644 index 0000000000..9bec60c7bb Binary files /dev/null and b/icons/UI_Icons/inventory/belt.png differ diff --git a/icons/UI_Icons/inventory/collar.png b/icons/UI_Icons/inventory/collar.png new file mode 100644 index 0000000000..a7d1b52784 Binary files /dev/null and b/icons/UI_Icons/inventory/collar.png differ diff --git a/icons/UI_Icons/inventory/ears.png b/icons/UI_Icons/inventory/ears.png new file mode 100644 index 0000000000..3c3ba34929 Binary files /dev/null and b/icons/UI_Icons/inventory/ears.png differ diff --git a/icons/UI_Icons/inventory/glasses.png b/icons/UI_Icons/inventory/glasses.png new file mode 100644 index 0000000000..3dff0cd599 Binary files /dev/null and b/icons/UI_Icons/inventory/glasses.png differ diff --git a/icons/UI_Icons/inventory/gloves.png b/icons/UI_Icons/inventory/gloves.png new file mode 100644 index 0000000000..87c829eb62 Binary files /dev/null and b/icons/UI_Icons/inventory/gloves.png differ diff --git a/icons/UI_Icons/inventory/hand_l.png b/icons/UI_Icons/inventory/hand_l.png new file mode 100644 index 0000000000..ab9535180d Binary files /dev/null and b/icons/UI_Icons/inventory/hand_l.png differ diff --git a/icons/UI_Icons/inventory/hand_r.png b/icons/UI_Icons/inventory/hand_r.png new file mode 100644 index 0000000000..e6b0d3cb9d Binary files /dev/null and b/icons/UI_Icons/inventory/hand_r.png differ diff --git a/icons/UI_Icons/inventory/head.png b/icons/UI_Icons/inventory/head.png new file mode 100644 index 0000000000..2d1b65159b Binary files /dev/null and b/icons/UI_Icons/inventory/head.png differ diff --git a/icons/UI_Icons/inventory/id.png b/icons/UI_Icons/inventory/id.png new file mode 100644 index 0000000000..397b30ca42 Binary files /dev/null and b/icons/UI_Icons/inventory/id.png differ diff --git a/icons/UI_Icons/inventory/mask.png b/icons/UI_Icons/inventory/mask.png new file mode 100644 index 0000000000..dbaa80ec1a Binary files /dev/null and b/icons/UI_Icons/inventory/mask.png differ diff --git a/icons/UI_Icons/inventory/neck.png b/icons/UI_Icons/inventory/neck.png new file mode 100644 index 0000000000..74cf1e33ea Binary files /dev/null and b/icons/UI_Icons/inventory/neck.png differ diff --git a/icons/UI_Icons/inventory/pocket.png b/icons/UI_Icons/inventory/pocket.png new file mode 100644 index 0000000000..2e08ed41b0 Binary files /dev/null and b/icons/UI_Icons/inventory/pocket.png differ diff --git a/icons/UI_Icons/inventory/shoes.png b/icons/UI_Icons/inventory/shoes.png new file mode 100644 index 0000000000..b1b19c6339 Binary files /dev/null and b/icons/UI_Icons/inventory/shoes.png differ diff --git a/icons/UI_Icons/inventory/suit.png b/icons/UI_Icons/inventory/suit.png new file mode 100644 index 0000000000..71b877677f Binary files /dev/null and b/icons/UI_Icons/inventory/suit.png differ diff --git a/icons/UI_Icons/inventory/suit_storage.png b/icons/UI_Icons/inventory/suit_storage.png new file mode 100644 index 0000000000..0dd12ed4f8 Binary files /dev/null and b/icons/UI_Icons/inventory/suit_storage.png differ diff --git a/icons/UI_Icons/inventory/uniform.png b/icons/UI_Icons/inventory/uniform.png new file mode 100644 index 0000000000..56576429e8 Binary files /dev/null and b/icons/UI_Icons/inventory/uniform.png differ diff --git a/icons/UI_Icons/screentips/cursor_hints.dmi b/icons/UI_Icons/screentips/cursor_hints.dmi new file mode 100644 index 0000000000..f314166d43 Binary files /dev/null and b/icons/UI_Icons/screentips/cursor_hints.dmi differ diff --git a/icons/UI_Icons/screentips/full_mouse.dmi b/icons/UI_Icons/screentips/full_mouse.dmi new file mode 100644 index 0000000000..a055b4ae3f Binary files /dev/null and b/icons/UI_Icons/screentips/full_mouse.dmi differ diff --git a/icons/UI_Icons/tgui/grid_background.png b/icons/UI_Icons/tgui/grid_background.png new file mode 100644 index 0000000000..228d373456 Binary files /dev/null and b/icons/UI_Icons/tgui/grid_background.png differ diff --git a/icons/UI_Icons/tgui/jobs.dmi b/icons/UI_Icons/tgui/jobs.dmi new file mode 100644 index 0000000000..207f11afed Binary files /dev/null and b/icons/UI_Icons/tgui/jobs.dmi differ diff --git a/icons/UI_Icons/tgui/ntosradar_background.png b/icons/UI_Icons/tgui/ntosradar_background.png index bac7647e3a..94b9c8ea69 100644 Binary files a/icons/UI_Icons/tgui/ntosradar_background.png and b/icons/UI_Icons/tgui/ntosradar_background.png differ diff --git a/icons/UI_Icons/tgui/ntosradar_pointer.png b/icons/UI_Icons/tgui/ntosradar_pointer.png index e71823f391..efa2026ef7 100644 Binary files a/icons/UI_Icons/tgui/ntosradar_pointer.png and b/icons/UI_Icons/tgui/ntosradar_pointer.png differ diff --git a/icons/UI_Icons/tgui/ntosradar_pointer_S.png b/icons/UI_Icons/tgui/ntosradar_pointer_S.png index 51a0dd49d9..7d394826d2 100644 Binary files a/icons/UI_Icons/tgui/ntosradar_pointer_S.png and b/icons/UI_Icons/tgui/ntosradar_pointer_S.png differ diff --git a/icons/blanks/32x32.dmi b/icons/blanks/32x32.dmi new file mode 100644 index 0000000000..6c4f2b33e0 Binary files /dev/null and b/icons/blanks/32x32.dmi differ diff --git a/icons/blanks/96x96.dmi b/icons/blanks/96x96.dmi new file mode 100644 index 0000000000..d79e60c111 Binary files /dev/null and b/icons/blanks/96x96.dmi differ diff --git a/icons/blanks/blank_title.png b/icons/blanks/blank_title.png new file mode 100644 index 0000000000..387a21f03a Binary files /dev/null and b/icons/blanks/blank_title.png differ diff --git a/icons/default_title.dmi b/icons/default_title.dmi deleted file mode 100644 index 633bd434b8..0000000000 Binary files a/icons/default_title.dmi and /dev/null differ diff --git a/icons/effects/96x32.dmi b/icons/effects/96x32.dmi index 937b2e8d42..a78d11530b 100644 Binary files a/icons/effects/96x32.dmi and b/icons/effects/96x32.dmi differ diff --git a/icons/effects/atmospherics.dmi b/icons/effects/atmospherics.dmi index acf48a0bd0..6c2412c04b 100644 Binary files a/icons/effects/atmospherics.dmi and b/icons/effects/atmospherics.dmi differ diff --git a/icons/effects/blood.dmi b/icons/effects/blood.dmi index bee16d4d90..c5a3756907 100644 Binary files a/icons/effects/blood.dmi and b/icons/effects/blood.dmi differ diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 2614e35211..be99d57a3d 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/effects/mouse_pointers/weapon_pointer.dmi b/icons/effects/mouse_pointers/weapon_pointer.dmi new file mode 100644 index 0000000000..b5070062c0 Binary files /dev/null and b/icons/effects/mouse_pointers/weapon_pointer.dmi differ diff --git a/icons/effects/random_spawners.dmi b/icons/effects/random_spawners.dmi new file mode 100644 index 0000000000..144287ced0 Binary files /dev/null and b/icons/effects/random_spawners.dmi differ diff --git a/icons/effects/summon.dmi b/icons/effects/summon.dmi new file mode 100644 index 0000000000..fefd79d845 Binary files /dev/null and b/icons/effects/summon.dmi differ diff --git a/icons/effects/weather_effects.dmi b/icons/effects/weather_effects.dmi index 4ae2387692..f8a4872848 100644 Binary files a/icons/effects/weather_effects.dmi and b/icons/effects/weather_effects.dmi differ diff --git a/icons/effects/welding_effect.dmi b/icons/effects/welding_effect.dmi new file mode 100644 index 0000000000..8b8db2dcae Binary files /dev/null and b/icons/effects/welding_effect.dmi differ diff --git a/icons/hud/lobby/background.dmi b/icons/hud/lobby/background.dmi new file mode 100644 index 0000000000..554543ecf3 Binary files /dev/null and b/icons/hud/lobby/background.dmi differ diff --git a/icons/hud/lobby/bottom_buttons.dmi b/icons/hud/lobby/bottom_buttons.dmi new file mode 100644 index 0000000000..6cbebb6e68 Binary files /dev/null and b/icons/hud/lobby/bottom_buttons.dmi differ diff --git a/icons/hud/lobby/character_setup.dmi b/icons/hud/lobby/character_setup.dmi new file mode 100644 index 0000000000..d3b94fb43e Binary files /dev/null and b/icons/hud/lobby/character_setup.dmi differ diff --git a/icons/hud/lobby/collapse_expand.dmi b/icons/hud/lobby/collapse_expand.dmi new file mode 100644 index 0000000000..03f9f02f3d Binary files /dev/null and b/icons/hud/lobby/collapse_expand.dmi differ diff --git a/icons/hud/lobby/join.dmi b/icons/hud/lobby/join.dmi new file mode 100644 index 0000000000..416f315770 Binary files /dev/null and b/icons/hud/lobby/join.dmi differ diff --git a/icons/hud/lobby/observe.dmi b/icons/hud/lobby/observe.dmi new file mode 100644 index 0000000000..f59252b3ea Binary files /dev/null and b/icons/hud/lobby/observe.dmi differ diff --git a/icons/hud/lobby/poll_overlay.dmi b/icons/hud/lobby/poll_overlay.dmi new file mode 100644 index 0000000000..2fc9716260 Binary files /dev/null and b/icons/hud/lobby/poll_overlay.dmi differ diff --git a/icons/hud/lobby/ready.dmi b/icons/hud/lobby/ready.dmi new file mode 100644 index 0000000000..d2a45a883f Binary files /dev/null and b/icons/hud/lobby/ready.dmi differ diff --git a/icons/hud/lobby/shutter.dmi b/icons/hud/lobby/shutter.dmi new file mode 100644 index 0000000000..baecaca421 Binary files /dev/null and b/icons/hud/lobby/shutter.dmi differ diff --git a/icons/mecha/durand_shield.dmi b/icons/mecha/durand_shield.dmi new file mode 100644 index 0000000000..0600e352b3 Binary files /dev/null and b/icons/mecha/durand_shield.dmi differ diff --git a/icons/mecha/mecha.dmi b/icons/mecha/mecha.dmi index d75ae09c97..17e62c2d9e 100644 Binary files a/icons/mecha/mecha.dmi and b/icons/mecha/mecha.dmi differ diff --git a/icons/mecha/mecha_96x96.dmi b/icons/mecha/mecha_96x96.dmi new file mode 100644 index 0000000000..dbcd513359 Binary files /dev/null and b/icons/mecha/mecha_96x96.dmi differ diff --git a/icons/misc/language.dmi b/icons/misc/language.dmi index a33f914885..b24e9871c3 100644 Binary files a/icons/misc/language.dmi and b/icons/misc/language.dmi differ diff --git a/icons/mob/32x64_mutant_bodyparts.dmi b/icons/mob/32x64_mutant_bodyparts.dmi new file mode 100644 index 0000000000..3d94f23538 Binary files /dev/null and b/icons/mob/32x64_mutant_bodyparts.dmi differ diff --git a/icons/mob/OnFire.dmi b/icons/mob/OnFire.dmi index 7768bf0269..e82442f4d0 100644 Binary files a/icons/mob/OnFire.dmi and b/icons/mob/OnFire.dmi differ diff --git a/icons/mob/actions/actions_changeling.dmi b/icons/mob/actions/actions_changeling.dmi index 2f384c6119..f394ef8a82 100644 Binary files a/icons/mob/actions/actions_changeling.dmi and b/icons/mob/actions/actions_changeling.dmi differ diff --git a/icons/mob/actions/actions_items.dmi b/icons/mob/actions/actions_items.dmi index 10627cf66d..2eb92f4a45 100644 Binary files a/icons/mob/actions/actions_items.dmi and b/icons/mob/actions/actions_items.dmi differ diff --git a/icons/mob/actions/actions_mecha.dmi b/icons/mob/actions/actions_mecha.dmi index 81c706b22c..071305150e 100644 Binary files a/icons/mob/actions/actions_mecha.dmi and b/icons/mob/actions/actions_mecha.dmi differ diff --git a/icons/mob/actions/actions_minor_antag.dmi b/icons/mob/actions/actions_minor_antag.dmi index 3b9fe54577..6936e9e4bf 100644 Binary files a/icons/mob/actions/actions_minor_antag.dmi and b/icons/mob/actions/actions_minor_antag.dmi differ diff --git a/icons/mob/actions/actions_mod.dmi b/icons/mob/actions/actions_mod.dmi new file mode 100644 index 0000000000..84fcbc00db Binary files /dev/null and b/icons/mob/actions/actions_mod.dmi differ diff --git a/icons/mob/actions/actions_snake.dmi b/icons/mob/actions/actions_snake.dmi new file mode 100644 index 0000000000..6856171b0d Binary files /dev/null and b/icons/mob/actions/actions_snake.dmi differ diff --git a/icons/mob/actions/backgrounds.dmi b/icons/mob/actions/backgrounds.dmi index 6b983df95a..a55e09bcfa 100644 Binary files a/icons/mob/actions/backgrounds.dmi and b/icons/mob/actions/backgrounds.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index 68e6170969..34bd587146 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/arachnid_parts.dmi b/icons/mob/arachnid_parts.dmi index 1b70935450..196e2037b5 100644 Binary files a/icons/mob/arachnid_parts.dmi and b/icons/mob/arachnid_parts.dmi differ diff --git a/icons/mob/clothing/accessories.dmi b/icons/mob/clothing/accessories.dmi index 03849efa5a..5c212f3f45 100644 Binary files a/icons/mob/clothing/accessories.dmi and b/icons/mob/clothing/accessories.dmi differ diff --git a/icons/mob/clothing/back.dmi b/icons/mob/clothing/back.dmi index ff787bc3fc..5d27cf95d8 100644 Binary files a/icons/mob/clothing/back.dmi and b/icons/mob/clothing/back.dmi differ diff --git a/icons/mob/clothing/belt.dmi b/icons/mob/clothing/belt.dmi index a40a8a72dd..f7062b9f4e 100644 Binary files a/icons/mob/clothing/belt.dmi and b/icons/mob/clothing/belt.dmi differ diff --git a/icons/mob/clothing/custom_w.dmi b/icons/mob/clothing/custom_w.dmi index 199232d73b..7859015998 100644 Binary files a/icons/mob/clothing/custom_w.dmi and b/icons/mob/clothing/custom_w.dmi differ diff --git a/icons/mob/clothing/eyes.dmi b/icons/mob/clothing/eyes.dmi index 876159c258..1525ba9a93 100644 Binary files a/icons/mob/clothing/eyes.dmi and b/icons/mob/clothing/eyes.dmi differ diff --git a/icons/mob/clothing/feet.dmi b/icons/mob/clothing/feet.dmi index df40636049..88b63f46b8 100644 Binary files a/icons/mob/clothing/feet.dmi and b/icons/mob/clothing/feet.dmi differ diff --git a/icons/mob/clothing/feet_digi.dmi b/icons/mob/clothing/feet_digi.dmi index 7215875f2c..41b75ec240 100644 Binary files a/icons/mob/clothing/feet_digi.dmi and b/icons/mob/clothing/feet_digi.dmi differ diff --git a/icons/mob/clothing/hands.dmi b/icons/mob/clothing/hands.dmi index 556bc4fd9d..3060ae8f2a 100644 Binary files a/icons/mob/clothing/hands.dmi and b/icons/mob/clothing/hands.dmi differ diff --git a/icons/mob/clothing/head.dmi b/icons/mob/clothing/head.dmi index 51675c8d7d..3216b816ed 100644 Binary files a/icons/mob/clothing/head.dmi and b/icons/mob/clothing/head.dmi differ diff --git a/icons/mob/clothing/head_muzzled.dmi b/icons/mob/clothing/head_muzzled.dmi index e99f1ff6d4..3a7506d96c 100644 Binary files a/icons/mob/clothing/head_muzzled.dmi and b/icons/mob/clothing/head_muzzled.dmi differ diff --git a/icons/mob/clothing/mask.dmi b/icons/mob/clothing/mask.dmi index 60c2e34b39..be578ae1e4 100644 Binary files a/icons/mob/clothing/mask.dmi and b/icons/mob/clothing/mask.dmi differ diff --git a/icons/mob/clothing/mask_muzzled.dmi b/icons/mob/clothing/mask_muzzled.dmi index 9da3545c65..d755bd2818 100644 Binary files a/icons/mob/clothing/mask_muzzled.dmi and b/icons/mob/clothing/mask_muzzled.dmi differ diff --git a/icons/mob/clothing/modsuit/mod_clothing.dmi b/icons/mob/clothing/modsuit/mod_clothing.dmi new file mode 100644 index 0000000000..f8dba0a006 Binary files /dev/null and b/icons/mob/clothing/modsuit/mod_clothing.dmi differ diff --git a/icons/mob/clothing/modsuit/mod_clothing_anthro.dmi b/icons/mob/clothing/modsuit/mod_clothing_anthro.dmi new file mode 100644 index 0000000000..a18800875c Binary files /dev/null and b/icons/mob/clothing/modsuit/mod_clothing_anthro.dmi differ diff --git a/icons/mob/clothing/modsuit/mod_modules.dmi b/icons/mob/clothing/modsuit/mod_modules.dmi new file mode 100644 index 0000000000..1001ae77d2 Binary files /dev/null and b/icons/mob/clothing/modsuit/mod_modules.dmi differ diff --git a/icons/mob/clothing/neck.dmi b/icons/mob/clothing/neck.dmi index 20b8576277..2b317737d7 100644 Binary files a/icons/mob/clothing/neck.dmi and b/icons/mob/clothing/neck.dmi differ diff --git a/icons/mob/clothing/suit.dmi b/icons/mob/clothing/suit.dmi index 39ad5337a7..db15a5ea40 100644 Binary files a/icons/mob/clothing/suit.dmi and b/icons/mob/clothing/suit.dmi differ diff --git a/icons/mob/clothing/suit_digi.dmi b/icons/mob/clothing/suit_digi.dmi index f80cb4a426..200aabc390 100644 Binary files a/icons/mob/clothing/suit_digi.dmi and b/icons/mob/clothing/suit_digi.dmi differ diff --git a/icons/mob/clothing/taur_canine.dmi b/icons/mob/clothing/taur_canine.dmi index 6155a274f2..db88043fb2 100644 Binary files a/icons/mob/clothing/taur_canine.dmi and b/icons/mob/clothing/taur_canine.dmi differ diff --git a/icons/mob/clothing/taur_hooved.dmi b/icons/mob/clothing/taur_hooved.dmi index 03fd8c8a30..a0af305d4c 100644 Binary files a/icons/mob/clothing/taur_hooved.dmi and b/icons/mob/clothing/taur_hooved.dmi differ diff --git a/icons/mob/clothing/taur_naga.dmi b/icons/mob/clothing/taur_naga.dmi index 3525333fb3..3df8625bec 100644 Binary files a/icons/mob/clothing/taur_naga.dmi and b/icons/mob/clothing/taur_naga.dmi differ diff --git a/icons/mob/clothing/under/costume.dmi b/icons/mob/clothing/under/costume.dmi new file mode 100644 index 0000000000..1f55b13314 Binary files /dev/null and b/icons/mob/clothing/under/costume.dmi differ diff --git a/icons/mob/clothing/uniform.dmi b/icons/mob/clothing/uniform.dmi index fd4ded6ad8..753ed9a4a2 100644 Binary files a/icons/mob/clothing/uniform.dmi and b/icons/mob/clothing/uniform.dmi differ diff --git a/icons/mob/clothing/uniform_digi.dmi b/icons/mob/clothing/uniform_digi.dmi index cbda1ab616..b274dd090e 100644 Binary files a/icons/mob/clothing/uniform_digi.dmi and b/icons/mob/clothing/uniform_digi.dmi differ diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi index 4b8dba160a..c4927ea06b 100644 Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ diff --git a/icons/mob/hair_gradients.dmi b/icons/mob/hair_gradients.dmi new file mode 100644 index 0000000000..ceb3b52eab Binary files /dev/null and b/icons/mob/hair_gradients.dmi differ diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 1d2007fd63..fa71351bec 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/mob/icemoon/64x64megafauna.dmi b/icons/mob/icemoon/64x64megafauna.dmi index 5a622dc7bc..e466b62556 100644 Binary files a/icons/mob/icemoon/64x64megafauna.dmi and b/icons/mob/icemoon/64x64megafauna.dmi differ diff --git a/icons/mob/inhands/equipment/belt_lefthand.dmi b/icons/mob/inhands/equipment/belt_lefthand.dmi index 81b12c60f9..944022713b 100644 Binary files a/icons/mob/inhands/equipment/belt_lefthand.dmi and b/icons/mob/inhands/equipment/belt_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/belt_righthand.dmi b/icons/mob/inhands/equipment/belt_righthand.dmi index 42ed3a30c6..78c5fc47b5 100644 Binary files a/icons/mob/inhands/equipment/belt_righthand.dmi and b/icons/mob/inhands/equipment/belt_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/custodial_righthand.dmi b/icons/mob/inhands/equipment/custodial_righthand.dmi index 26d8e61163..c986155b10 100644 Binary files a/icons/mob/inhands/equipment/custodial_righthand.dmi and b/icons/mob/inhands/equipment/custodial_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/medical_lefthand.dmi b/icons/mob/inhands/equipment/medical_lefthand.dmi index 232f3f9e65..38f2a00525 100644 Binary files a/icons/mob/inhands/equipment/medical_lefthand.dmi and b/icons/mob/inhands/equipment/medical_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/medical_righthand.dmi b/icons/mob/inhands/equipment/medical_righthand.dmi index 8133cca9bd..829735f11f 100644 Binary files a/icons/mob/inhands/equipment/medical_righthand.dmi and b/icons/mob/inhands/equipment/medical_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/mining_lefthand.dmi b/icons/mob/inhands/equipment/mining_lefthand.dmi index 7496aba625..c3519482a7 100644 Binary files a/icons/mob/inhands/equipment/mining_lefthand.dmi and b/icons/mob/inhands/equipment/mining_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/mining_righthand.dmi b/icons/mob/inhands/equipment/mining_righthand.dmi index de3d11978a..dc605cd2a0 100644 Binary files a/icons/mob/inhands/equipment/mining_righthand.dmi and b/icons/mob/inhands/equipment/mining_righthand.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 384159b299..b694d0ba35 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index 3d22f8d4b1..3836f4c713 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/inhands/misc/plushes_lefthand.dmi b/icons/mob/inhands/misc/plushes_lefthand.dmi new file mode 100644 index 0000000000..1a12cece7d Binary files /dev/null and b/icons/mob/inhands/misc/plushes_lefthand.dmi differ diff --git a/icons/mob/inhands/misc/plushes_righthand.dmi b/icons/mob/inhands/misc/plushes_righthand.dmi new file mode 100644 index 0000000000..fab9101eb6 Binary files /dev/null and b/icons/mob/inhands/misc/plushes_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/axes_lefthand.dmi b/icons/mob/inhands/weapons/axes_lefthand.dmi index 6b4041e477..021c005fc3 100644 Binary files a/icons/mob/inhands/weapons/axes_lefthand.dmi and b/icons/mob/inhands/weapons/axes_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/axes_righthand.dmi b/icons/mob/inhands/weapons/axes_righthand.dmi index 30553d6320..c19440b531 100644 Binary files a/icons/mob/inhands/weapons/axes_righthand.dmi and b/icons/mob/inhands/weapons/axes_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/bombs_lefthand.dmi b/icons/mob/inhands/weapons/bombs_lefthand.dmi index 4772c01a22..123f4f3a7d 100644 Binary files a/icons/mob/inhands/weapons/bombs_lefthand.dmi and b/icons/mob/inhands/weapons/bombs_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/bombs_righthand.dmi b/icons/mob/inhands/weapons/bombs_righthand.dmi index 9046e788d2..b4e3d17ada 100644 Binary files a/icons/mob/inhands/weapons/bombs_righthand.dmi and b/icons/mob/inhands/weapons/bombs_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/chainsaw_lefthand.dmi b/icons/mob/inhands/weapons/chainsaw_lefthand.dmi index 3e0aea0e6b..3053fea723 100644 Binary files a/icons/mob/inhands/weapons/chainsaw_lefthand.dmi and b/icons/mob/inhands/weapons/chainsaw_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/chainsaw_righthand.dmi b/icons/mob/inhands/weapons/chainsaw_righthand.dmi index 0800a52731..4e76c19b7a 100644 Binary files a/icons/mob/inhands/weapons/chainsaw_righthand.dmi and b/icons/mob/inhands/weapons/chainsaw_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/guns_lefthand.dmi b/icons/mob/inhands/weapons/guns_lefthand.dmi index ca742c9c7f..a8ca244865 100644 Binary files a/icons/mob/inhands/weapons/guns_lefthand.dmi and b/icons/mob/inhands/weapons/guns_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/guns_righthand.dmi b/icons/mob/inhands/weapons/guns_righthand.dmi index a277b29993..d1019fa3d1 100644 Binary files a/icons/mob/inhands/weapons/guns_righthand.dmi and b/icons/mob/inhands/weapons/guns_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/hammers_lefthand.dmi b/icons/mob/inhands/weapons/hammers_lefthand.dmi index 612066728a..d32402e371 100644 Binary files a/icons/mob/inhands/weapons/hammers_lefthand.dmi and b/icons/mob/inhands/weapons/hammers_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/hammers_righthand.dmi b/icons/mob/inhands/weapons/hammers_righthand.dmi index 9341cc8e4c..402ac32126 100644 Binary files a/icons/mob/inhands/weapons/hammers_righthand.dmi and b/icons/mob/inhands/weapons/hammers_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/melee_lefthand.dmi b/icons/mob/inhands/weapons/melee_lefthand.dmi index bb6de0432e..0477b1b0f9 100644 Binary files a/icons/mob/inhands/weapons/melee_lefthand.dmi and b/icons/mob/inhands/weapons/melee_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/melee_righthand.dmi b/icons/mob/inhands/weapons/melee_righthand.dmi index 346f6d5977..cf2cf50ad9 100644 Binary files a/icons/mob/inhands/weapons/melee_righthand.dmi and b/icons/mob/inhands/weapons/melee_righthand.dmi differ diff --git a/icons/mob/inhands/weapons/swords_lefthand.dmi b/icons/mob/inhands/weapons/swords_lefthand.dmi index 4be0df2300..860bc5a3de 100644 Binary files a/icons/mob/inhands/weapons/swords_lefthand.dmi and b/icons/mob/inhands/weapons/swords_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/swords_righthand.dmi b/icons/mob/inhands/weapons/swords_righthand.dmi index 57308ffb76..326821dc8b 100644 Binary files a/icons/mob/inhands/weapons/swords_righthand.dmi and b/icons/mob/inhands/weapons/swords_righthand.dmi differ diff --git a/icons/mob/landmarks.dmi b/icons/mob/landmarks.dmi index 284809da70..0e2ae605f6 100644 Binary files a/icons/mob/landmarks.dmi and b/icons/mob/landmarks.dmi differ diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi index 3137e8ac26..65efde8697 100644 Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ diff --git a/icons/mob/radial.dmi b/icons/mob/radial.dmi index 27b268eea0..9afc0e7df0 100644 Binary files a/icons/mob/radial.dmi and b/icons/mob/radial.dmi differ diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi index 082bfb3c3e..21af40ff8f 100644 Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ diff --git a/icons/mob/screen_full.dmi b/icons/mob/screen_full.dmi index 502e9ad3f9..975cbf3fe4 100644 Binary files a/icons/mob/screen_full.dmi and b/icons/mob/screen_full.dmi differ diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi index 4377a0d7c6..39e8eb4b45 100644 Binary files a/icons/mob/screen_gen.dmi and b/icons/mob/screen_gen.dmi differ diff --git a/icons/mob/screen_synth.dmi b/icons/mob/screen_synth.dmi new file mode 100644 index 0000000000..95ecc5e2bb Binary files /dev/null and b/icons/mob/screen_synth.dmi differ diff --git a/icons/mob/talk.dmi b/icons/mob/talk.dmi index 0a56321037..beb38f01cc 100644 Binary files a/icons/mob/talk.dmi and b/icons/mob/talk.dmi differ diff --git a/icons/mob/wings.dmi b/icons/mob/wings.dmi index 92de5c150c..8b74384e29 100644 Binary files a/icons/mob/wings.dmi and b/icons/mob/wings.dmi differ diff --git a/icons/mob/wings_functional.dmi b/icons/mob/wings_functional.dmi new file mode 100644 index 0000000000..5d1a82a245 Binary files /dev/null and b/icons/mob/wings_functional.dmi differ diff --git a/icons/obj/abductor.dmi b/icons/obj/abductor.dmi index 75f84347b6..83d71c1093 100644 Binary files a/icons/obj/abductor.dmi and b/icons/obj/abductor.dmi differ diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index e1caad8279..eb642648af 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/barkbox_fluff.dmi b/icons/obj/barkbox_fluff.dmi index e420e864e7..f209ad7c31 100644 Binary files a/icons/obj/barkbox_fluff.dmi and b/icons/obj/barkbox_fluff.dmi differ diff --git a/icons/obj/bedsheets.dmi b/icons/obj/bedsheets.dmi index f62dd34c66..17837b0bc5 100644 Binary files a/icons/obj/bedsheets.dmi and b/icons/obj/bedsheets.dmi differ diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index 3916fcb694..36db68b7bb 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/icons/obj/cigarettes.dmi b/icons/obj/cigarettes.dmi index 5c55efd67f..e4aa1917f4 100644 Binary files a/icons/obj/cigarettes.dmi and b/icons/obj/cigarettes.dmi differ diff --git a/icons/obj/clothing/accessories.dmi b/icons/obj/clothing/accessories.dmi index 79cb2bff77..b92d65092e 100644 Binary files a/icons/obj/clothing/accessories.dmi and b/icons/obj/clothing/accessories.dmi differ diff --git a/icons/obj/clothing/belt_overlays.dmi b/icons/obj/clothing/belt_overlays.dmi index 0799920a6c..5d9bad32ac 100644 Binary files a/icons/obj/clothing/belt_overlays.dmi and b/icons/obj/clothing/belt_overlays.dmi differ diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi index 48aaa3a418..70548c5719 100644 Binary files a/icons/obj/clothing/belts.dmi and b/icons/obj/clothing/belts.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index 4fce479a9d..c98c984c7d 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi index 9df096d19b..855936dfb4 100644 Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 854928f2ca..a981bc456d 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 532d4f5df7..315594cfb2 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/modsuit/mod_clothing.dmi b/icons/obj/clothing/modsuit/mod_clothing.dmi new file mode 100644 index 0000000000..41ebc1a2ba Binary files /dev/null and b/icons/obj/clothing/modsuit/mod_clothing.dmi differ diff --git a/icons/obj/clothing/modsuit/mod_construction.dmi b/icons/obj/clothing/modsuit/mod_construction.dmi new file mode 100644 index 0000000000..5140af8cb6 Binary files /dev/null and b/icons/obj/clothing/modsuit/mod_construction.dmi differ diff --git a/icons/obj/clothing/modsuit/mod_modules.dmi b/icons/obj/clothing/modsuit/mod_modules.dmi new file mode 100644 index 0000000000..037e7fe696 Binary files /dev/null and b/icons/obj/clothing/modsuit/mod_modules.dmi differ diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi index 8540b2f392..c9491af6b2 100644 Binary files a/icons/obj/clothing/neck.dmi and b/icons/obj/clothing/neck.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index bde07bd54d..2406e61190 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index f689ee5068..d9b8f39988 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/under/costume.dmi b/icons/obj/clothing/under/costume.dmi new file mode 100644 index 0000000000..33d0aad418 Binary files /dev/null and b/icons/obj/clothing/under/costume.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 2bbe93a410..bb44a20647 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/computer.dmi b/icons/obj/computer.dmi index 33cd46d15f..36402ad2d5 100644 Binary files a/icons/obj/computer.dmi and b/icons/obj/computer.dmi differ diff --git a/icons/obj/contraband.dmi b/icons/obj/contraband.dmi index a6c554f7da..eadf4a1591 100644 Binary files a/icons/obj/contraband.dmi and b/icons/obj/contraband.dmi differ diff --git a/icons/obj/control_rod.dmi b/icons/obj/control_rod.dmi new file mode 100644 index 0000000000..bef59ebf2e Binary files /dev/null and b/icons/obj/control_rod.dmi differ diff --git a/icons/obj/crates.dmi b/icons/obj/crates.dmi index 1fda3933bd..c6574ca86b 100644 Binary files a/icons/obj/crates.dmi and b/icons/obj/crates.dmi differ diff --git a/icons/obj/custom.dmi b/icons/obj/custom.dmi index 89da4b43a0..43018f4b8c 100644 Binary files a/icons/obj/custom.dmi and b/icons/obj/custom.dmi differ diff --git a/icons/obj/defibrillators.dmi b/icons/obj/defibrillators.dmi index a4dc9e65e3..8871d5b049 100644 Binary files a/icons/obj/defibrillators.dmi and b/icons/obj/defibrillators.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index b507b3bcdd..01bb25535f 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi index 0f49bc6d5f..e873aef87d 100644 Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ diff --git a/icons/obj/dyespray.dmi b/icons/obj/dyespray.dmi new file mode 100644 index 0000000000..eb05603679 Binary files /dev/null and b/icons/obj/dyespray.dmi differ diff --git a/icons/obj/economy.dmi b/icons/obj/economy.dmi index a73f50ef7f..c8ac3c142c 100644 Binary files a/icons/obj/economy.dmi and b/icons/obj/economy.dmi differ diff --git a/icons/obj/fitness.dmi b/icons/obj/fitness.dmi new file mode 100644 index 0000000000..c48e2450fb Binary files /dev/null and b/icons/obj/fitness.dmi differ diff --git a/icons/obj/food/containers.dmi b/icons/obj/food/containers.dmi index 40e00b431e..78ee67c45a 100644 Binary files a/icons/obj/food/containers.dmi and b/icons/obj/food/containers.dmi differ diff --git a/icons/obj/gang/actions.dmi b/icons/obj/gang/actions.dmi new file mode 100644 index 0000000000..c8996ccd6f Binary files /dev/null and b/icons/obj/gang/actions.dmi differ diff --git a/icons/obj/gang/cell_phone.dmi b/icons/obj/gang/cell_phone.dmi new file mode 100644 index 0000000000..40a5c33cbe Binary files /dev/null and b/icons/obj/gang/cell_phone.dmi differ diff --git a/icons/obj/gang/signup_points.dmi b/icons/obj/gang/signup_points.dmi new file mode 100644 index 0000000000..2bda4b8ce1 Binary files /dev/null and b/icons/obj/gang/signup_points.dmi differ diff --git a/icons/obj/gang/tags.dmi b/icons/obj/gang/tags.dmi new file mode 100644 index 0000000000..61059c47e4 Binary files /dev/null and b/icons/obj/gang/tags.dmi differ diff --git a/icons/obj/gang/wanted_160x32.dmi b/icons/obj/gang/wanted_160x32.dmi new file mode 100644 index 0000000000..c25f5758d4 Binary files /dev/null and b/icons/obj/gang/wanted_160x32.dmi differ diff --git a/icons/obj/gang/wanted_stars.dmi b/icons/obj/gang/wanted_stars.dmi new file mode 100644 index 0000000000..8fd9205b56 Binary files /dev/null and b/icons/obj/gang/wanted_stars.dmi differ diff --git a/icons/obj/genitals/breasts_onmob.dmi b/icons/obj/genitals/breasts_onmob.dmi index 3f3bcf5bd7..aa717be8f0 100644 Binary files a/icons/obj/genitals/breasts_onmob.dmi and b/icons/obj/genitals/breasts_onmob.dmi differ diff --git a/icons/obj/genitals/butt.dmi b/icons/obj/genitals/butt.dmi new file mode 100644 index 0000000000..304a8424bb Binary files /dev/null and b/icons/obj/genitals/butt.dmi differ diff --git a/icons/obj/genitals/butt_onmob.dmi b/icons/obj/genitals/butt_onmob.dmi new file mode 100644 index 0000000000..95a75fa745 Binary files /dev/null and b/icons/obj/genitals/butt_onmob.dmi differ diff --git a/icons/obj/genitals/testicles_onmob.dmi b/icons/obj/genitals/testicles_onmob.dmi index 65eb24268f..febbd5b362 100644 Binary files a/icons/obj/genitals/testicles_onmob.dmi and b/icons/obj/genitals/testicles_onmob.dmi differ diff --git a/icons/obj/grenade.dmi b/icons/obj/grenade.dmi index d6dd4c1b00..27301fa272 100644 Binary files a/icons/obj/grenade.dmi and b/icons/obj/grenade.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index 9d9279f148..5bbcca9791 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/halloween_items.dmi b/icons/obj/halloween_items.dmi index b4f11165dc..a69550c6eb 100644 Binary files a/icons/obj/halloween_items.dmi and b/icons/obj/halloween_items.dmi differ diff --git a/icons/obj/inflatable.dmi b/icons/obj/inflatable.dmi new file mode 100644 index 0000000000..65888be4ad Binary files /dev/null and b/icons/obj/inflatable.dmi differ diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index b468d0d4c9..b958ca201c 100644 Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ diff --git a/icons/obj/items_cyborg.dmi b/icons/obj/items_cyborg.dmi index 769d5492c6..5d87bee320 100644 Binary files a/icons/obj/items_cyborg.dmi and b/icons/obj/items_cyborg.dmi differ diff --git a/icons/obj/janitor.dmi b/icons/obj/janitor.dmi index 50975dc828..74ec511768 100644 Binary files a/icons/obj/janitor.dmi and b/icons/obj/janitor.dmi differ diff --git a/icons/obj/kitchen.dmi b/icons/obj/kitchen.dmi index 36efd97189..84b4f47e1a 100644 Binary files a/icons/obj/kitchen.dmi and b/icons/obj/kitchen.dmi differ diff --git a/icons/obj/lavaland/ash_tree.dmi b/icons/obj/lavaland/ash_tree.dmi new file mode 100644 index 0000000000..7a8addafe5 Binary files /dev/null and b/icons/obj/lavaland/ash_tree.dmi differ diff --git a/icons/obj/lavaland/survival_pod.dmi b/icons/obj/lavaland/survival_pod.dmi index 84ea0e1e83..149c2aa888 100644 Binary files a/icons/obj/lavaland/survival_pod.dmi and b/icons/obj/lavaland/survival_pod.dmi differ diff --git a/icons/obj/machines/gateway.dmi b/icons/obj/machines/gateway.dmi index 99a74a68bc..5ba943bb89 100644 Binary files a/icons/obj/machines/gateway.dmi and b/icons/obj/machines/gateway.dmi differ diff --git a/icons/obj/machines/prison.dmi b/icons/obj/machines/prison.dmi new file mode 100644 index 0000000000..7ce58e93a2 Binary files /dev/null and b/icons/obj/machines/prison.dmi differ diff --git a/icons/obj/machines/rbmk.dmi b/icons/obj/machines/rbmk.dmi new file mode 100644 index 0000000000..1c52ddac12 Binary files /dev/null and b/icons/obj/machines/rbmk.dmi differ diff --git a/icons/obj/machines/rbmk_computer.dmi b/icons/obj/machines/rbmk_computer.dmi new file mode 100644 index 0000000000..66bbcb40ac Binary files /dev/null and b/icons/obj/machines/rbmk_computer.dmi differ diff --git a/icons/obj/machines/reactor_parts.dmi b/icons/obj/machines/reactor_parts.dmi new file mode 100644 index 0000000000..7fd5cfccb0 Binary files /dev/null and b/icons/obj/machines/reactor_parts.dmi differ diff --git a/icons/obj/machines/sleeper.dmi b/icons/obj/machines/sleeper.dmi index ff9e2b197a..134448fc4e 100644 Binary files a/icons/obj/machines/sleeper.dmi and b/icons/obj/machines/sleeper.dmi differ diff --git a/icons/obj/machines/stasis.dmi b/icons/obj/machines/stasis.dmi new file mode 100644 index 0000000000..21844b0f8d Binary files /dev/null and b/icons/obj/machines/stasis.dmi differ diff --git a/icons/obj/machines/terminals.dmi b/icons/obj/machines/terminals.dmi new file mode 100644 index 0000000000..e504b35abb Binary files /dev/null and b/icons/obj/machines/terminals.dmi differ diff --git a/icons/obj/mining.dmi b/icons/obj/mining.dmi index ad0b74829f..9ad3c2578e 100644 Binary files a/icons/obj/mining.dmi and b/icons/obj/mining.dmi differ diff --git a/icons/obj/modular_laptop.dmi b/icons/obj/modular_laptop.dmi index 4c7f838db4..92536f9ca6 100644 Binary files a/icons/obj/modular_laptop.dmi and b/icons/obj/modular_laptop.dmi differ diff --git a/icons/obj/modular_tablet.dmi b/icons/obj/modular_tablet.dmi index 9ccbef928b..60d47a7240 100644 Binary files a/icons/obj/modular_tablet.dmi and b/icons/obj/modular_tablet.dmi differ diff --git a/icons/obj/nuke_tools.dmi b/icons/obj/nuke_tools.dmi index 7f5c730fe5..eb724e29be 100644 Binary files a/icons/obj/nuke_tools.dmi and b/icons/obj/nuke_tools.dmi differ diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi index 6d29b8df8e..cc28f4e346 100644 Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ diff --git a/icons/obj/pda.dmi b/icons/obj/pda.dmi index 8992f4a4a1..f968d15860 100644 Binary files a/icons/obj/pda.dmi and b/icons/obj/pda.dmi differ diff --git a/icons/obj/plushes.dmi b/icons/obj/plushes.dmi index 69cec1a6fd..aea6a40e86 100644 Binary files a/icons/obj/plushes.dmi and b/icons/obj/plushes.dmi differ diff --git a/icons/obj/power.dmi b/icons/obj/power.dmi index 9544ea77c0..13aaba8f94 100644 Binary files a/icons/obj/power.dmi and b/icons/obj/power.dmi differ diff --git a/icons/obj/radio.dmi b/icons/obj/radio.dmi index dbfc7b1f93..7e9a976624 100644 Binary files a/icons/obj/radio.dmi and b/icons/obj/radio.dmi differ diff --git a/icons/obj/rbmk_computer.dmi b/icons/obj/rbmk_computer.dmi new file mode 100644 index 0000000000..66bbcb40ac Binary files /dev/null and b/icons/obj/rbmk_computer.dmi differ diff --git a/icons/obj/reagentfillings.dmi b/icons/obj/reagentfillings.dmi index 7926ead12d..077a3b43db 100644 Binary files a/icons/obj/reagentfillings.dmi and b/icons/obj/reagentfillings.dmi differ diff --git a/icons/obj/recycling.dmi b/icons/obj/recycling.dmi index 9604d6b97e..621b9e4241 100644 Binary files a/icons/obj/recycling.dmi and b/icons/obj/recycling.dmi differ diff --git a/icons/obj/shards.dmi b/icons/obj/shards.dmi index e7875efa26..6e5f5821ce 100644 Binary files a/icons/obj/shards.dmi and b/icons/obj/shards.dmi differ diff --git a/icons/obj/smith.dmi b/icons/obj/smith.dmi index 19e12dec86..87be22c5a8 100644 Binary files a/icons/obj/smith.dmi and b/icons/obj/smith.dmi differ diff --git a/icons/obj/sofaclean.dmi b/icons/obj/sofaclean.dmi new file mode 100644 index 0000000000..861499c032 Binary files /dev/null and b/icons/obj/sofaclean.dmi differ diff --git a/icons/obj/stack_objects.dmi b/icons/obj/stack_objects.dmi index 3136cf34b2..026612b144 100644 Binary files a/icons/obj/stack_objects.dmi and b/icons/obj/stack_objects.dmi differ diff --git a/icons/obj/stationobjs.dmi b/icons/obj/stationobjs.dmi index a4fbe53dba..7e04fa0d2a 100644 Binary files a/icons/obj/stationobjs.dmi and b/icons/obj/stationobjs.dmi differ diff --git a/icons/obj/statue.dmi b/icons/obj/statue.dmi index 0fe4f7f539..48368dda28 100644 Binary files a/icons/obj/statue.dmi and b/icons/obj/statue.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index b4f223e57d..3204b36cc5 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index 52172bbe29..fbd6cecc56 100755 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/icons/obj/syringe.dmi b/icons/obj/syringe.dmi index b474dc68ba..cea955ac64 100644 Binary files a/icons/obj/syringe.dmi and b/icons/obj/syringe.dmi differ diff --git a/icons/obj/telescience.dmi b/icons/obj/telescience.dmi index 1e60c01131..b342d2db71 100644 Binary files a/icons/obj/telescience.dmi and b/icons/obj/telescience.dmi differ diff --git a/icons/obj/tiles.dmi b/icons/obj/tiles.dmi index 088b6c2c7b..757208cd9b 100644 Binary files a/icons/obj/tiles.dmi and b/icons/obj/tiles.dmi differ diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index a720aff62c..95a887a733 100644 Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ diff --git a/icons/obj/vehicles.dmi b/icons/obj/vehicles.dmi index 14b19caef8..2520e98bba 100644 Binary files a/icons/obj/vehicles.dmi and b/icons/obj/vehicles.dmi differ diff --git a/icons/obj/vending.dmi b/icons/obj/vending.dmi index 5f45b9b168..f99b061d55 100644 Binary files a/icons/obj/vending.dmi and b/icons/obj/vending.dmi differ diff --git a/icons/obj/vending_restock.dmi b/icons/obj/vending_restock.dmi index a48107546f..276abe6cc1 100644 Binary files a/icons/obj/vending_restock.dmi and b/icons/obj/vending_restock.dmi differ diff --git a/icons/obj/wallframe.dmi b/icons/obj/wallframe.dmi index 70149901e3..c447263db5 100644 Binary files a/icons/obj/wallframe.dmi and b/icons/obj/wallframe.dmi differ diff --git a/icons/runtime/README.md b/icons/runtime/README.md new file mode 100644 index 0000000000..804cb2f285 --- /dev/null +++ b/icons/runtime/README.md @@ -0,0 +1,5 @@ +# Runtime Loaded Icons + +These icons are not compiled into the .rsc or are otherwise loaded at runtime. + +Please keep all (non-config) icons that do this in this folder as it is needed by the [deploy.sh](../../tools/deploy.sh) script to minimize build output. diff --git a/icons/runtime/default_title.dmi b/icons/runtime/default_title.dmi new file mode 100644 index 0000000000..17f4787f84 Binary files /dev/null and b/icons/runtime/default_title.dmi differ diff --git a/icons/runtime/tcg/default.dmi b/icons/runtime/tcg/default.dmi new file mode 100644 index 0000000000..f42113f30e Binary files /dev/null and b/icons/runtime/tcg/default.dmi differ diff --git a/icons/runtime/tcg/xenos.dmi b/icons/runtime/tcg/xenos.dmi new file mode 100644 index 0000000000..682b0a6966 Binary files /dev/null and b/icons/runtime/tcg/xenos.dmi differ diff --git a/icons/screen/clickcatcher.dmi b/icons/screen/clickcatcher.dmi new file mode 100644 index 0000000000..50a3616991 Binary files /dev/null and b/icons/screen/clickcatcher.dmi differ diff --git a/icons/screen/fullscreen_15x15.dmi b/icons/screen/fullscreen_15x15.dmi new file mode 100644 index 0000000000..502e9ad3f9 Binary files /dev/null and b/icons/screen/fullscreen_15x15.dmi differ diff --git a/icons/screen/fullscreen_tiled.dmi b/icons/screen/fullscreen_tiled.dmi new file mode 100644 index 0000000000..11b70842ec Binary files /dev/null and b/icons/screen/fullscreen_tiled.dmi differ diff --git a/icons/screen/parallax.dmi b/icons/screen/parallax.dmi new file mode 100644 index 0000000000..36dd36ee7a Binary files /dev/null and b/icons/screen/parallax.dmi differ diff --git a/icons/turf/areas.dmi b/icons/turf/areas.dmi index a1a6180068..9c2357edd7 100644 Binary files a/icons/turf/areas.dmi and b/icons/turf/areas.dmi differ diff --git a/icons/turf/decals.dmi b/icons/turf/decals.dmi index 4ed8c8db9a..6b42ad12c7 100644 Binary files a/icons/turf/decals.dmi and b/icons/turf/decals.dmi differ diff --git a/icons/turf/floors/catwalk_plating.dmi b/icons/turf/floors/catwalk_plating.dmi new file mode 100644 index 0000000000..c9ad36653b Binary files /dev/null and b/icons/turf/floors/catwalk_plating.dmi differ diff --git a/interface/fonts/Grand9K_Pixel.ttf b/interface/fonts/Grand9K_Pixel.ttf new file mode 100644 index 0000000000..cf6fdf44e2 Binary files /dev/null and b/interface/fonts/Grand9K_Pixel.ttf differ diff --git a/interface/fonts/Pixellari.ttf b/interface/fonts/Pixellari.ttf new file mode 100644 index 0000000000..5a3a3c2b11 Binary files /dev/null and b/interface/fonts/Pixellari.ttf differ diff --git a/interface/fonts/SpessFont.ttf b/interface/fonts/SpessFont.ttf new file mode 100644 index 0000000000..8f7c7e08d0 Binary files /dev/null and b/interface/fonts/SpessFont.ttf differ diff --git a/interface/fonts/TinyUnicode.ttf b/interface/fonts/TinyUnicode.ttf new file mode 100644 index 0000000000..74d0d3e386 Binary files /dev/null and b/interface/fonts/TinyUnicode.ttf differ diff --git a/interface/fonts/VCR_OSD_Mono.ttf b/interface/fonts/VCR_OSD_Mono.ttf new file mode 100644 index 0000000000..dcca687a43 Binary files /dev/null and b/interface/fonts/VCR_OSD_Mono.ttf differ diff --git a/interface/fonts/fonts_datum.dm b/interface/fonts/fonts_datum.dm new file mode 100644 index 0000000000..a346706d7f --- /dev/null +++ b/interface/fonts/fonts_datum.dm @@ -0,0 +1,78 @@ +/// A font datum, it exists to define a custom font to use in a span style later. +/datum/font + /// Font name, just so people know what to put in their span style. + var/name + /// The font file we link to. + var/font_family + + /// Font features and metrics + /// Generated by Lummox's dmifontsplus (https://www.byond.com/developer/LummoxJR/DmiFontsPlus) + /// Note: these variable names have been changed, so you can't straight copy/paste from dmifontsplus.exe + + /// list of font size/spacing metrics + var/list/metrics + /// total height of a line + var/height + /// distance above baseline (including whitespace) + var/ascent + /// distance below baseline + var/descent + /// average character width + var/average_width + /// maximum character width + var/max_width + /// extra width, such as from italics, for a line + var/overhang + /// internal leading vertical space, for accent marks + var/in_leading + /// external leading vertical space, just plain blank + var/ex_leading + /// default character (for undefined chars) + var/default_character + /// first character in metrics + var/start + /// last character in metrics + var/end + +/// Get font metrics +/// From Lummox's dmifontsplus (https://www.byond.com/developer/LummoxJR/DmiFontsPlus) +/datum/font/proc/get_metrics(text, flags, first_line) + . = 0 + var/longest = 0 + if(!length(text)) + return + + var/i = 1 + var/idx + while(i <= length(text)) + var/character = text2ascii(text, i++) + if(character <= 10) + if(character <= 7) + . += character // spacers for justification + + if(character <= 9) + continue // soft-break chars + + if(. && idx && !(flags & INCLUDE_AC)) + . -= max(metrics[idx + 3], 0) + + longest = max(longest, . + first_line) + . = 0 + first_line = 0 + idx = 0 + continue + + idx = (character - start) * 3 + if(idx <= 0 || idx >= metrics.len) + idx = (default_character - start) * 3 + + if(!. && !(flags & INCLUDE_AC)) + . -= metrics[idx + 1] + . += metrics[idx + 1] + metrics[idx + 2] + metrics[idx +3] + + if(. && idx && !(flags & INCLUDE_AC)) + . -= max(metrics[idx + 3], 0) + + . = max(. + first_line, longest) + if(. > 0) + . += overhang diff --git a/interface/fonts/grand_9k.dm b/interface/fonts/grand_9k.dm new file mode 100644 index 0000000000..7993d307bc --- /dev/null +++ b/interface/fonts/grand_9k.dm @@ -0,0 +1,253 @@ +/// For clean results on map, use only sizing pt, multiples of 6: 6pt 12pt 18pt 24pt etc. - Not for use with px sizing +/// Can be used in TGUI etc, px sizing is pt / 0.75. 6pt = 8px, 12pt = 16px etc. + +/// Base font +/datum/font/grand9k + name = "Grand9K Pixel" + font_family = 'interface/fonts/Grand9K_Pixel.ttf' + +/// For icon overlays +/// Grand9K 6pt metrics generated using Lummox's dmifontsplus (https://www.byond.com/developer/LummoxJR/DmiFontsPlus) +/// Note: these variable names have been changed, so you can't straight copy/paste from dmifontsplus.exe +/datum/font/grand9k/size_6pt + name = "Grand9K Pixel 6pt" + height = 12 + ascent = 10 + descent = 2 + average_width = 4 + max_width = 9 + overhang = 0 + in_leading = 4 + ex_leading = 1 + default_character = 31 + start = 30 + end = 255 + metrics = list( + 0, 5, 1, // char 30 + 0, 5, 1, // char 31 + 0, 1, 1, // char 32 + 0, 1, 1, // char 33 + 0, 3, 1, // char 34 + 0, 6, 1, // char 35 + 0, 5, 1, // char 36 + 0, 7, 1, // char 37 + 0, 5, 1, // char 38 + 0, 1, 1, // char 39 + 0, 3, 1, // char 40 + 0, 3, 1, // char 41 + 0, 5, 1, // char 42 + 0, 5, 1, // char 43 + 0, 1, 1, // char 44 + 0, 4, 1, // char 45 + 0, 1, 1, // char 46 + 0, 3, 1, // char 47 + 0, 5, 1, // char 48 + 0, 2, 1, // char 49 + 0, 5, 1, // char 50 + 0, 4, 1, // char 51 + 0, 5, 1, // char 52 + 0, 5, 1, // char 53 + 0, 5, 1, // char 54 + 0, 5, 1, // char 55 + 0, 5, 1, // char 56 + 0, 5, 1, // char 57 + 0, 1, 1, // char 58 + 0, 1, 1, // char 59 + 0, 4, 1, // char 60 + 0, 4, 1, // char 61 + 0, 4, 1, // char 62 + 0, 4, 1, // char 63 + 0, 7, 1, // char 64 + 0, 5, 1, // char 65 + 0, 5, 1, // char 66 + 0, 4, 1, // char 67 + 0, 5, 1, // char 68 + 0, 4, 1, // char 69 + 0, 4, 1, // char 70 + 0, 5, 1, // char 71 + 0, 5, 1, // char 72 + 0, 1, 1, // char 73 + 0, 5, 1, // char 74 + 0, 5, 1, // char 75 + 0, 5, 1, // char 76 + 0, 5, 1, // char 77 + 0, 5, 1, // char 78 + 0, 5, 1, // char 79 + 0, 5, 1, // char 80 + 0, 6, 1, // char 81 + 0, 5, 1, // char 82 + 0, 5, 1, // char 83 + 0, 5, 1, // char 84 + 0, 5, 1, // char 85 + 0, 5, 1, // char 86 + 0, 5, 1, // char 87 + 0, 5, 1, // char 88 + 0, 5, 1, // char 89 + 0, 5, 1, // char 90 + 0, 3, 1, // char 91 + 0, 3, 1, // char 92 + 0, 3, 1, // char 93 + 0, 5, 1, // char 94 + 0, 4, 0, // char 95 + 0, 2, 1, // char 96 + 0, 4, 1, // char 97 + 0, 4, 1, // char 98 + 0, 3, 1, // char 99 + 0, 4, 1, // char 100 + 0, 4, 1, // char 101 + 0, 4, 1, // char 102 + 0, 4, 1, // char 103 + 0, 4, 1, // char 104 + 0, 1, 1, // char 105 + 0, 3, 1, // char 106 + 0, 4, 1, // char 107 + 0, 1, 1, // char 108 + 0, 5, 1, // char 109 + 0, 4, 1, // char 110 + 0, 4, 1, // char 111 + 0, 4, 1, // char 112 + 0, 4, 1, // char 113 + 0, 4, 1, // char 114 + 0, 4, 1, // char 115 + 0, 4, 1, // char 116 + 0, 4, 1, // char 117 + 0, 5, 1, // char 118 + 0, 5, 1, // char 119 + 0, 5, 1, // char 120 + 0, 4, 1, // char 121 + 0, 5, 1, // char 122 + 0, 4, 1, // char 123 + 0, 1, 1, // char 124 + 0, 4, 1, // char 125 + 0, 6, 1, // char 126 + 0, 5, 1, // char 127 + 0, 5, 1, // char 128 + 0, 5, 1, // char 129 + 0, 1, 1, // char 130 + 0, 5, 1, // char 131 + 0, 3, 1, // char 132 + 0, 5, 1, // char 133 + 0, 5, 1, // char 134 + 0, 5, 1, // char 135 + 0, 5, 1, // char 136 + 0, 5, 1, // char 137 + 0, 5, 1, // char 138 + 0, 3, 1, // char 139 + 0, 6, 1, // char 140 + 0, 5, 1, // char 141 + 0, 5, 1, // char 142 + 0, 5, 1, // char 143 + 0, 5, 1, // char 144 + 0, 1, 1, // char 145 + 0, 1, 1, // char 146 + 0, 3, 1, // char 147 + 0, 3, 1, // char 148 + 0, 1, 1, // char 149 + 0, 5, 1, // char 150 + 0, 5, 1, // char 151 + 0, 5, 1, // char 152 + 0, 8, 1, // char 153 + 0, 4, 1, // char 154 + 0, 3, 1, // char 155 + 0, 5, 1, // char 156 + 0, 5, 1, // char 157 + 0, 5, 1, // char 158 + 0, 5, 1, // char 159 + 0, 1, 1, // char 160 + 0, 1, 1, // char 161 + 0, 4, 1, // char 162 + 0, 5, 1, // char 163 + 0, 5, 1, // char 164 + 0, 5, 1, // char 165 + 0, 1, 1, // char 166 + 0, 5, 1, // char 167 + 0, 3, 1, // char 168 + 0, 8, 1, // char 169 + 0, 5, 1, // char 170 + 0, 6, 1, // char 171 + 0, 4, 1, // char 172 + 0, 5, 1, // char 173 + 0, 8, 1, // char 174 + 0, 5, 1, // char 175 + 0, 3, 1, // char 176 + 0, 5, 1, // char 177 + 0, 5, 1, // char 178 + 0, 5, 1, // char 179 + 0, 2, 1, // char 180 + 0, 4, 1, // char 181 + 0, 5, 1, // char 182 + 0, 1, 1, // char 183 + 0, 2, 1, // char 184 + 0, 5, 1, // char 185 + 0, 5, 1, // char 186 + 0, 6, 1, // char 187 + 0, 5, 1, // char 188 + 0, 5, 1, // char 189 + 0, 5, 1, // char 190 + 0, 4, 1, // char 191 + 0, 5, 1, // char 192 + 0, 5, 1, // char 193 + 0, 5, 1, // char 194 + 0, 6, 0, // char 195 + 0, 5, 1, // char 196 + 0, 5, 1, // char 197 + 0, 6, 1, // char 198 + 0, 4, 1, // char 199 + 0, 4, 1, // char 200 + 0, 4, 1, // char 201 + 0, 4, 1, // char 202 + 0, 4, 1, // char 203 + 1, 2, 0, // char 204 + 0, 2, 1, // char 205 + 0, 3, 0, // char 206 + 0, 3, 0, // char 207 + 0, 6, 1, // char 208 + 0, 6, 0, // char 209 + 0, 5, 1, // char 210 + 0, 5, 1, // char 211 + 0, 5, 1, // char 212 + 0, 6, 1, // char 213 + 0, 5, 1, // char 214 + 0, 5, 1, // char 215 + 0, 5, 1, // char 216 + 0, 5, 1, // char 217 + 0, 5, 1, // char 218 + 0, 5, 1, // char 219 + 0, 5, 1, // char 220 + 0, 5, 1, // char 221 + 0, 5, 1, // char 222 + 0, 5, 1, // char 223 + 0, 4, 1, // char 224 + 0, 4, 1, // char 225 + 0, 4, 1, // char 226 + 0, 4, 1, // char 227 + 0, 4, 1, // char 228 + 0, 4, 1, // char 229 + 0, 5, 1, // char 230 + 0, 3, 1, // char 231 + 0, 4, 1, // char 232 + 0, 4, 1, // char 233 + 0, 4, 1, // char 234 + 0, 4, 1, // char 235 + 0, 2, 1, // char 236 + 1, 2, 0, // char 237 + 0, 3, 0, // char 238 + 0, 3, 0, // char 239 + 0, 5, 0, // char 240 + 0, 4, 1, // char 241 + 0, 4, 1, // char 242 + 0, 4, 1, // char 243 + 0, 4, 1, // char 244 + 0, 4, 1, // char 245 + 0, 4, 1, // char 246 + 0, 5, 1, // char 247 + 0, 4, 1, // char 248 + 0, 4, 1, // char 249 + 0, 4, 1, // char 250 + 0, 4, 1, // char 251 + 0, 4, 1, // char 252 + 0, 4, 1, // char 253 + 0, 4, 1, // char 254 + 0, 4, 1, // char 255 + 226 + ) diff --git a/interface/fonts/license.txt b/interface/fonts/license.txt new file mode 100644 index 0000000000..9aa70fbac2 --- /dev/null +++ b/interface/fonts/license.txt @@ -0,0 +1,13 @@ +Grand9K Pixel created by Jayvee Enaguas. Licensed under Creative Commons Attribution 4.0 International (CC BY 4.0) +(https://creativecommons.org/licenses/by/4.0/) (https://www.dafont.com/grand9k-pixel.font) + +Pixellari created by Zacchary Dempsey-Plante. Website indicates free for commercial use. +(https://www.dafont.com/pixellari.font?fpp=200) + +Spess Font created by MTandi (discord) for /tg/station. + +Tiny Unicode created by Jakob Riedle/DuffsDevice. Website indicates free for commercial use. +(https://fontmeme.com/fonts/tiny-unicode-font/) + +VCR OSD Mono created by Riciery Leal/mrmanet. Website indicates 100% free, author confirms it's free for all to use. +(https://www.dafont.com/font-comment.php?file=vcr_osd_mono) diff --git a/interface/fonts/pixellari.dm b/interface/fonts/pixellari.dm new file mode 100644 index 0000000000..24fcd1961f --- /dev/null +++ b/interface/fonts/pixellari.dm @@ -0,0 +1,252 @@ +/// For clean results on map, use only sizing pt, multiples of 12: 12pt 24pt 48pt etc. - Not for use with px sizing +/// Can be used in TGUI etc, px sizing is pt / 0.75. 12pt = 16px, 24pt = 32px etc. + +/// Base font +/datum/font/pixellari + name = "Pixellari" + font_family = 'interface/fonts/Pixellari.ttf' + +/// For icon overlays +/// Pixellari 12pt metrics generated using Lummox's dmifontsplus (https://www.byond.com/developer/LummoxJR/DmiFontsPlus) +/// Note: these variable names have been changed, so you can't straight copy/paste from dmifontsplus.exe +/datum/font/pixellari/size_12pt + name = "Pixellari 12pt" + height = 16 + ascent = 12 + descent = 4 + average_width = 7 + max_width = 15 + overhang = 0 + in_leading = 0 + ex_leading = 1 + default_character = 31 + start = 30 + end = 255 + metrics = list(\ + 1, 5, 0, /* char 30 */ \ + 1, 5, 0, /* char 31 */ \ + 0, 1, 4, /* char 32 */ \ + 1, 2, 1, /* char 33 */ \ + 1, 5, 1, /* char 34 */ \ + 0, 8, 1, /* char 35 */ \ + 2, 6, 1, /* char 36 */ \ + 0, 13, 1, /* char 37 */ \ + 1, 8, 1, /* char 38 */ \ + 1, 2, 1, /* char 39 */ \ + 1, 3, 1, /* char 40 */ \ + 2, 3, 1, /* char 41 */ \ + 0, 6, 1, /* char 42 */ \ + 1, 6, 1, /* char 43 */ \ + 1, 2, 1, /* char 44 */ \ + 1, 6, 1, /* char 45 */ \ + 1, 2, 1, /* char 46 */ \ + 0, 6, 1, /* char 47 */ \ + 1, 7, 1, /* char 48 */ \ + 2, 6, 1, /* char 49 */ \ + 1, 6, 1, /* char 50 */ \ + 1, 6, 1, /* char 51 */ \ + 1, 7, 1, /* char 52 */ \ + 1, 6, 1, /* char 53 */ \ + 1, 6, 1, /* char 54 */ \ + 1, 7, 1, /* char 55 */ \ + 1, 6, 1, /* char 56 */ \ + 1, 6, 1, /* char 57 */ \ + 1, 2, 1, /* char 58 */ \ + 1, 2, 1, /* char 59 */ \ + 0, 10, 1, /* char 60 */ \ + 1, 6, 1, /* char 61 */ \ + 0, 10, 1, /* char 62 */ \ + 1, 6, 1, /* char 63 */ \ + 1, 12, 1, /* char 64 */ \ + 1, 8, 1, /* char 65 */ \ + 1, 8, 1, /* char 66 */ \ + 2, 7, 1, /* char 67 */ \ + 2, 8, 1, /* char 68 */ \ + 2, 6, 1, /* char 69 */ \ + 2, 6, 1, /* char 70 */ \ + 2, 7, 1, /* char 71 */ \ + 1, 8, 1, /* char 72 */ \ + 1, 4, 1, /* char 73 */ \ + 0, 7, 1, /* char 74 */ \ + 1, 8, 1, /* char 75 */ \ + 1, 6, 1, /* char 76 */ \ + 1, 10, 1, /* char 77 */ \ + 1, 9, 1, /* char 78 */ \ + 2, 8, 1, /* char 79 */ \ + 1, 7, 1, /* char 80 */ \ + 2, 9, 1, /* char 81 */ \ + 1, 8, 1, /* char 82 */ \ + 1, 8, 1, /* char 83 */ \ + 1, 8, 1, /* char 84 */ \ + 2, 8, 1, /* char 85 */ \ + 2, 8, 1, /* char 86 */ \ + 1, 10, 1, /* char 87 */ \ + 1, 8, 1, /* char 88 */ \ + 1, 8, 1, /* char 89 */ \ + 0, 10, 1, /* char 90 */ \ + 1, 3, 1, /* char 91 */ \ + 0, 6, 1, /* char 92 */ \ + 2, 3, 1, /* char 93 */ \ + 0, 7, 1, /* char 94 */ \ + 0, 8, 1, /* char 95 */ \ + 1, 3, 1, /* char 96 */ \ + 1, 6, 1, /* char 97 */ \ + 1, 7, 1, /* char 98 */ \ + 1, 6, 1, /* char 99 */ \ + 1, 7, 1, /* char 100 */ \ + 1, 6, 1, /* char 101 */ \ + 1, 4, 1, /* char 102 */ \ + 1, 7, 1, /* char 103 */ \ + 1, 7, 1, /* char 104 */ \ + 1, 2, 1, /* char 105 */ \ + -1, 4, 1, /* char 106 */ \ + 0, 7, 1, /* char 107 */ \ + 1, 2, 1, /* char 108 */ \ + 1, 10, 1, /* char 109 */ \ + 1, 6, 1, /* char 110 */ \ + 1, 6, 1, /* char 111 */ \ + 1, 7, 1, /* char 112 */ \ + 1, 7, 1, /* char 113 */ \ + 1, 6, 1, /* char 114 */ \ + 1, 6, 1, /* char 115 */ \ + 0, 4, 1, /* char 116 */ \ + 1, 6, 1, /* char 117 */ \ + 1, 6, 1, /* char 118 */ \ + 1, 10, 1, /* char 119 */ \ + 1, 6, 1, /* char 120 */ \ + 1, 6, 1, /* char 121 */ \ + 1, 6, 1, /* char 122 */ \ + 0, 5, 1, /* char 123 */ \ + 1, 2, 1, /* char 124 */ \ + 0, 5, 1, /* char 125 */ \ + 1, 8, 1, /* char 126 */ \ + 1, 5, 0, /* char 127 */ \ + 1, 8, 1, /* char 128 */ \ + 1, 5, 0, /* char 129 */ \ + 1, 5, 0, /* char 130 */ \ + 1, 5, 0, /* char 131 */ \ + 1, 5, 0, /* char 132 */ \ + 1, 5, 0, /* char 133 */ \ + 1, 5, 0, /* char 134 */ \ + 1, 5, 0, /* char 135 */ \ + 1, 5, 0, /* char 136 */ \ + 1, 5, 0, /* char 137 */ \ + 1, 8, 1, /* char 138 */ \ + 1, 5, 0, /* char 139 */ \ + 0, 14, 1, /* char 140 */ \ + 1, 5, 0, /* char 141 */ \ + 0, 10, 1, /* char 142 */ \ + 1, 5, 0, /* char 143 */ \ + 1, 5, 0, /* char 144 */ \ + 1, 5, 0, /* char 145 */ \ + 1, 5, 0, /* char 146 */ \ + 1, 5, 0, /* char 147 */ \ + 1, 5, 0, /* char 148 */ \ + 1, 5, 0, /* char 149 */ \ + 1, 5, 0, /* char 150 */ \ + 1, 5, 0, /* char 151 */ \ + 1, 5, 0, /* char 152 */ \ + 1, 5, 0, /* char 153 */ \ + 1, 6, 1, /* char 154 */ \ + 1, 5, 0, /* char 155 */ \ + 1, 11, 1, /* char 156 */ \ + 1, 5, 0, /* char 157 */ \ + 1, 6, 1, /* char 158 */ \ + 1, 8, 1, /* char 159 */ \ + 0, 1, 4, /* char 160 */ \ + 1, 2, 1, /* char 161 */ \ + 1, 6, 1, /* char 162 */ \ + 0, 8, 1, /* char 163 */ \ + 0, 9, 1, /* char 164 */ \ + 1, 8, 1, /* char 165 */ \ + 1, 2, 1, /* char 166 */ \ + 1, 7, 1, /* char 167 */ \ + 0, 5, 1, /* char 168 */ \ + -1, 12, 1, /* char 169 */ \ + 0, 6, 1, /* char 170 */ \ + 0, 8, 1, /* char 171 */ \ + 1, 8, 1, /* char 172 */ \ + 1, 5, 0, /* char 173 */ \ + -1, 12, 1, /* char 174 */ \ + 2, 4, 1, /* char 175 */ \ + 0, 6, 1, /* char 176 */ \ + 1, 6, 1, /* char 177 */ \ + 0, 5, 1, /* char 178 */ \ + 0, 5, 1, /* char 179 */ \ + 1, 3, 1, /* char 180 */ \ + 1, 6, 1, /* char 181 */ \ + 1, 7, 1, /* char 182 */ \ + 1, 2, 1, /* char 183 */ \ + 1, 3, 1, /* char 184 */ \ + 1, 4, 1, /* char 185 */ \ + 0, 6, 1, /* char 186 */ \ + 0, 8, 1, /* char 187 */ \ + 1, 13, 1, /* char 188 */ \ + 1, 12, 1, /* char 189 */ \ + 0, 13, 1, /* char 190 */ \ + 1, 6, 1, /* char 191 */ \ + 1, 8, 1, /* char 192 */ \ + 1, 8, 1, /* char 193 */ \ + 1, 8, 1, /* char 194 */ \ + 1, 8, 1, /* char 195 */ \ + 1, 8, 1, /* char 196 */ \ + 1, 8, 1, /* char 197 */ \ + 0, 13, 1, /* char 198 */ \ + 2, 7, 1, /* char 199 */ \ + 2, 6, 1, /* char 200 */ \ + 2, 6, 1, /* char 201 */ \ + 2, 6, 1, /* char 202 */ \ + 2, 6, 1, /* char 203 */ \ + 1, 4, 1, /* char 204 */ \ + 1, 4, 1, /* char 205 */ \ + 1, 4, 1, /* char 206 */ \ + 1, 4, 1, /* char 207 */ \ + 0, 10, 1, /* char 208 */ \ + 1, 9, 1, /* char 209 */ \ + 2, 8, 1, /* char 210 */ \ + 2, 8, 1, /* char 211 */ \ + 2, 8, 1, /* char 212 */ \ + 2, 8, 1, /* char 213 */ \ + 2, 8, 1, /* char 214 */ \ + 1, 6, 1, /* char 215 */ \ + -2, 14, 1, /* char 216 */ \ + 2, 8, 1, /* char 217 */ \ + 2, 8, 1, /* char 218 */ \ + 2, 8, 1, /* char 219 */ \ + 2, 8, 1, /* char 220 */ \ + 1, 8, 1, /* char 221 */ \ + 1, 8, 1, /* char 222 */ \ + 1, 8, 1, /* char 223 */ \ + 1, 6, 1, /* char 224 */ \ + 1, 6, 1, /* char 225 */ \ + 1, 6, 1, /* char 226 */ \ + 1, 6, 1, /* char 227 */ \ + 1, 6, 1, /* char 228 */ \ + 1, 6, 1, /* char 229 */ \ + 1, 11, 1, /* char 230 */ \ + 1, 6, 1, /* char 231 */ \ + 1, 6, 1, /* char 232 */ \ + 1, 6, 1, /* char 233 */ \ + 1, 6, 1, /* char 234 */ \ + 1, 6, 1, /* char 235 */ \ + 1, 2, 1, /* char 236 */ \ + 1, 2, 1, /* char 237 */ \ + 0, 4, 1, /* char 238 */ \ + 0, 4, 1, /* char 239 */ \ + 1, 7, 1, /* char 240 */ \ + 1, 6, 1, /* char 241 */ \ + 1, 6, 1, /* char 242 */ \ + 1, 6, 1, /* char 243 */ \ + 1, 6, 1, /* char 244 */ \ + 1, 6, 1, /* char 245 */ \ + 1, 6, 1, /* char 246 */ \ + 1, 6, 1, /* char 247 */ \ + 0, 10, 1, /* char 248 */ \ + 1, 6, 1, /* char 249 */ \ + 1, 6, 1, /* char 250 */ \ + 1, 6, 1, /* char 251 */ \ + 1, 6, 1, /* char 252 */ \ + 1, 6, 1, /* char 253 */ \ + 1, 8, 1, /* char 254 */ \ + 1, 6, 1, /* char 255 */ \ + 226) diff --git a/interface/fonts/spess_font.dm b/interface/fonts/spess_font.dm new file mode 100644 index 0000000000..07e8ea5b3b --- /dev/null +++ b/interface/fonts/spess_font.dm @@ -0,0 +1,252 @@ +/// For clean results on map, use only sizing pt, multiples of 6: 6t 12pt 18pt etc. - Not for use with px sizing +/// Can be used in TGUI etc, px sizing is pt / 0.75. 12pt = 16px, 24pt = 32px etc. + +/// Base font +/datum/font/spessfont + name = "Spess Font" + font_family = 'interface/fonts/SpessFont.ttf' + +/// For icon overlays +/// Spess Font 6pt metrics generated using Lummox's dmifontsplus (https://www.byond.com/developer/LummoxJR/DmiFontsPlus) +/// Note: these variable names have been changed, so you can't straight copy/paste from dmifontsplus.exe +/datum/font/spessfont/size_6pt + name = "Spess Font 6pt" + height = 8 + ascent = 6 + descent = 2 + average_width = 4 + max_width = 6 + overhang = 0 + in_leading = 0 + ex_leading = 0 + default_character = 31 + start = 30 + end = 255 + metrics = list(\ + 0, 1, 0, /* char 30 */ \ + 0, 1, 0, /* char 31 */ \ + 0, 1, 1, /* char 32 */ \ + 0, 1, 1, /* char 33 */ \ + 0, 3, 1, /* char 34 */ \ + 0, 5, 1, /* char 35 */ \ + 0, 3, 1, /* char 36 */ \ + 0, 5, 1, /* char 37 */ \ + 0, 5, 1, /* char 38 */ \ + 0, 1, 1, /* char 39 */ \ + 0, 2, 1, /* char 40 */ \ + 0, 2, 1, /* char 41 */ \ + 0, 3, 1, /* char 42 */ \ + 0, 3, 1, /* char 43 */ \ + 0, 1, 1, /* char 44 */ \ + 0, 3, 1, /* char 45 */ \ + 0, 1, 1, /* char 46 */ \ + 0, 3, 1, /* char 47 */ \ + 0, 4, 1, /* char 48 */ \ + 0, 2, 1, /* char 49 */ \ + 0, 4, 1, /* char 50 */ \ + 0, 4, 1, /* char 51 */ \ + 0, 4, 1, /* char 52 */ \ + 0, 4, 1, /* char 53 */ \ + 0, 4, 1, /* char 54 */ \ + 0, 4, 1, /* char 55 */ \ + 0, 4, 1, /* char 56 */ \ + 0, 4, 1, /* char 57 */ \ + 0, 1, 1, /* char 58 */ \ + 0, 1, 1, /* char 59 */ \ + 0, 3, 1, /* char 60 */ \ + 0, 3, 1, /* char 61 */ \ + 0, 3, 1, /* char 62 */ \ + 0, 3, 1, /* char 63 */ \ + 0, 4, 1, /* char 64 */ \ + 0, 4, 1, /* char 65 */ \ + 0, 4, 1, /* char 66 */ \ + 0, 4, 1, /* char 67 */ \ + 0, 4, 1, /* char 68 */ \ + 0, 4, 1, /* char 69 */ \ + 0, 4, 1, /* char 70 */ \ + 0, 4, 1, /* char 71 */ \ + 0, 4, 1, /* char 72 */ \ + 0, 3, 1, /* char 73 */ \ + 0, 4, 1, /* char 74 */ \ + 0, 4, 1, /* char 75 */ \ + 0, 4, 1, /* char 76 */ \ + 0, 5, 1, /* char 77 */ \ + 0, 4, 1, /* char 78 */ \ + 0, 4, 1, /* char 79 */ \ + 0, 4, 1, /* char 80 */ \ + 0, 4, 1, /* char 81 */ \ + 0, 4, 1, /* char 82 */ \ + 0, 4, 1, /* char 83 */ \ + 0, 5, 1, /* char 84 */ \ + 0, 4, 1, /* char 85 */ \ + 0, 4, 1, /* char 86 */ \ + 0, 5, 1, /* char 87 */ \ + 0, 5, 1, /* char 88 */ \ + 0, 4, 1, /* char 89 */ \ + 0, 4, 1, /* char 90 */ \ + 0, 2, 1, /* char 91 */ \ + 0, 3, 1, /* char 92 */ \ + 0, 2, 1, /* char 93 */ \ + 0, 3, 1, /* char 94 */ \ + 0, 4, 1, /* char 95 */ \ + 0, 2, 1, /* char 96 */ \ + 0, 3, 1, /* char 97 */ \ + 0, 4, 1, /* char 98 */ \ + 0, 3, 1, /* char 99 */ \ + 0, 4, 1, /* char 100 */ \ + 0, 3, 1, /* char 101 */ \ + 0, 2, 1, /* char 102 */ \ + 0, 4, 1, /* char 103 */ \ + 0, 3, 1, /* char 104 */ \ + 0, 1, 1, /* char 105 */ \ + 0, 1, 1, /* char 106 */ \ + 0, 3, 1, /* char 107 */ \ + 0, 1, 1, /* char 108 */ \ + 0, 5, 1, /* char 109 */ \ + 0, 3, 1, /* char 110 */ \ + 0, 4, 1, /* char 111 */ \ + 0, 4, 1, /* char 112 */ \ + 0, 4, 1, /* char 113 */ \ + 0, 2, 1, /* char 114 */ \ + 0, 3, 1, /* char 115 */ \ + 0, 2, 1, /* char 116 */ \ + 0, 3, 1, /* char 117 */ \ + 0, 3, 1, /* char 118 */ \ + 0, 5, 1, /* char 119 */ \ + 0, 3, 1, /* char 120 */ \ + 0, 3, 1, /* char 121 */ \ + 0, 3, 1, /* char 122 */ \ + 0, 3, 1, /* char 123 */ \ + 0, 1, 1, /* char 124 */ \ + 0, 3, 1, /* char 125 */ \ + 0, 4, 1, /* char 126 */ \ + 0, 1, 0, /* char 127 */ \ + 0, 1, 0, /* char 128 */ \ + 0, 1, 0, /* char 129 */ \ + 0, 1, 0, /* char 130 */ \ + 0, 1, 0, /* char 131 */ \ + 0, 1, 0, /* char 132 */ \ + 0, 1, 0, /* char 133 */ \ + 0, 1, 0, /* char 134 */ \ + 0, 1, 0, /* char 135 */ \ + 0, 1, 0, /* char 136 */ \ + 0, 1, 0, /* char 137 */ \ + 0, 1, 0, /* char 138 */ \ + 0, 1, 0, /* char 139 */ \ + 0, 1, 0, /* char 140 */ \ + 0, 1, 0, /* char 141 */ \ + 0, 1, 0, /* char 142 */ \ + 0, 1, 0, /* char 143 */ \ + 0, 1, 0, /* char 144 */ \ + 0, 1, 0, /* char 145 */ \ + 0, 1, 0, /* char 146 */ \ + 0, 1, 0, /* char 147 */ \ + 0, 1, 0, /* char 148 */ \ + 0, 1, 0, /* char 149 */ \ + 0, 1, 0, /* char 150 */ \ + 0, 1, 0, /* char 151 */ \ + 0, 1, 0, /* char 152 */ \ + 0, 1, 0, /* char 153 */ \ + 0, 1, 0, /* char 154 */ \ + 0, 1, 0, /* char 155 */ \ + 0, 1, 0, /* char 156 */ \ + 0, 1, 0, /* char 157 */ \ + 0, 1, 0, /* char 158 */ \ + 0, 1, 0, /* char 159 */ \ + 0, 1, 0, /* char 160 */ \ + 0, 1, 0, /* char 161 */ \ + 0, 1, 0, /* char 162 */ \ + 0, 1, 0, /* char 163 */ \ + 0, 1, 0, /* char 164 */ \ + 0, 1, 0, /* char 165 */ \ + 0, 1, 0, /* char 166 */ \ + 0, 1, 0, /* char 167 */ \ + 0, 1, 0, /* char 168 */ \ + 0, 1, 0, /* char 169 */ \ + 0, 1, 0, /* char 170 */ \ + 0, 1, 0, /* char 171 */ \ + 0, 1, 0, /* char 172 */ \ + 0, 1, 0, /* char 173 */ \ + 0, 1, 0, /* char 174 */ \ + 0, 1, 0, /* char 175 */ \ + 0, 1, 0, /* char 176 */ \ + 0, 1, 0, /* char 177 */ \ + 0, 1, 0, /* char 178 */ \ + 0, 1, 0, /* char 179 */ \ + 0, 1, 0, /* char 180 */ \ + 0, 1, 0, /* char 181 */ \ + 0, 1, 0, /* char 182 */ \ + 0, 1, 0, /* char 183 */ \ + 0, 1, 0, /* char 184 */ \ + 0, 1, 0, /* char 185 */ \ + 0, 1, 0, /* char 186 */ \ + 0, 1, 0, /* char 187 */ \ + 0, 1, 0, /* char 188 */ \ + 0, 1, 0, /* char 189 */ \ + 0, 1, 0, /* char 190 */ \ + 0, 1, 0, /* char 191 */ \ + 0, 1, 0, /* char 192 */ \ + 0, 1, 0, /* char 193 */ \ + 0, 1, 0, /* char 194 */ \ + 0, 1, 0, /* char 195 */ \ + 0, 1, 0, /* char 196 */ \ + 0, 1, 0, /* char 197 */ \ + 0, 1, 0, /* char 198 */ \ + 0, 1, 0, /* char 199 */ \ + 0, 1, 0, /* char 200 */ \ + 0, 1, 0, /* char 201 */ \ + 0, 1, 0, /* char 202 */ \ + 0, 1, 0, /* char 203 */ \ + 0, 1, 0, /* char 204 */ \ + 0, 1, 0, /* char 205 */ \ + 0, 1, 0, /* char 206 */ \ + 0, 1, 0, /* char 207 */ \ + 0, 1, 0, /* char 208 */ \ + 0, 1, 0, /* char 209 */ \ + 0, 1, 0, /* char 210 */ \ + 0, 1, 0, /* char 211 */ \ + 0, 1, 0, /* char 212 */ \ + 0, 1, 0, /* char 213 */ \ + 0, 1, 0, /* char 214 */ \ + 0, 1, 0, /* char 215 */ \ + 0, 1, 0, /* char 216 */ \ + 0, 1, 0, /* char 217 */ \ + 0, 1, 0, /* char 218 */ \ + 0, 1, 0, /* char 219 */ \ + 0, 1, 0, /* char 220 */ \ + 0, 1, 0, /* char 221 */ \ + 0, 1, 0, /* char 222 */ \ + 0, 1, 0, /* char 223 */ \ + 0, 1, 0, /* char 224 */ \ + 0, 1, 0, /* char 225 */ \ + 0, 1, 0, /* char 226 */ \ + 0, 1, 0, /* char 227 */ \ + 0, 1, 0, /* char 228 */ \ + 0, 1, 0, /* char 229 */ \ + 0, 1, 0, /* char 230 */ \ + 0, 1, 0, /* char 231 */ \ + 0, 1, 0, /* char 232 */ \ + 0, 1, 0, /* char 233 */ \ + 0, 1, 0, /* char 234 */ \ + 0, 1, 0, /* char 235 */ \ + 0, 1, 0, /* char 236 */ \ + 0, 1, 0, /* char 237 */ \ + 0, 1, 0, /* char 238 */ \ + 0, 1, 0, /* char 239 */ \ + 0, 1, 0, /* char 240 */ \ + 0, 1, 0, /* char 241 */ \ + 0, 1, 0, /* char 242 */ \ + 0, 1, 0, /* char 243 */ \ + 0, 1, 0, /* char 244 */ \ + 0, 1, 0, /* char 245 */ \ + 0, 1, 0, /* char 246 */ \ + 0, 1, 0, /* char 247 */ \ + 0, 1, 0, /* char 248 */ \ + 0, 1, 0, /* char 249 */ \ + 0, 1, 0, /* char 250 */ \ + 0, 1, 0, /* char 251 */ \ + 0, 1, 0, /* char 252 */ \ + 0, 1, 0, /* char 253 */ \ + 0, 1, 0, /* char 254 */ \ + 0, 1, 0, /* char 255 */ \ + 226) diff --git a/interface/fonts/tiny_unicode.dm b/interface/fonts/tiny_unicode.dm new file mode 100644 index 0000000000..d6af265d51 --- /dev/null +++ b/interface/fonts/tiny_unicode.dm @@ -0,0 +1,253 @@ +/// For clean results on map, use only sizing pt, multiples of 12: 12pt 24pt 48pt etc. - Not for use with px sizing +/// Can be used in TGUI etc, px sizing is pt / 0.75. 12pt = 16px, 24pt = 32px etc. + +/// Base font +/datum/font/tiny_unicode + name = "TinyUnicode" + font_family = 'interface/fonts/TinyUnicode.ttf' + +/// For icon overlays +/// TinyUnicode 12pt metrics generated using Lummox's dmifontsplus (https://www.byond.com/developer/LummoxJR/DmiFontsPlus) +/// Note: these variable names have been changed, so you can't straight copy/paste from dmifontsplus.exe +/datum/font/tiny_unicode/size_12pt + name = "TinyUnicode 12pt" + height = 13 + ascent = 11 + descent = 2 + average_width = 5 + max_width = 11 + overhang = 0 + in_leading = -3 + ex_leading = 1 + default_character = 31 + start = 30 + end = 255 + metrics = list( + 1, 5, 0, // char 30 + 1, 5, 0, // char 31 + 0, 1, 4, // char 32 + 0, 1, 1, // char 33 + 0, 3, 1, // char 34 + 0, 5, 1, // char 35 + 0, 4, 1, // char 36 + 0, 3, 1, // char 37 + 0, 5, 1, // char 38 + 0, 1, 1, // char 39 + 0, 2, 1, // char 40 + 0, 2, 1, // char 41 + 0, 3, 1, // char 42 + 0, 3, 1, // char 43 + 0, 2, 1, // char 44 + 0, 3, 1, // char 45 + 0, 1, 1, // char 46 + 0, 3, 1, // char 47 + 0, 4, 1, // char 48 + 0, 2, 1, // char 49 + 0, 4, 1, // char 50 + 0, 4, 1, // char 51 + 0, 4, 1, // char 52 + 0, 4, 1, // char 53 + 0, 4, 1, // char 54 + 0, 4, 1, // char 55 + 0, 4, 1, // char 56 + 0, 4, 1, // char 57 + 0, 1, 1, // char 58 + 0, 2, 1, // char 59 + 0, 2, 1, // char 60 + 0, 4, 1, // char 61 + 0, 2, 1, // char 62 + 0, 4, 1, // char 63 + 0, 7, 1, // char 64 + 0, 4, 1, // char 65 + 0, 4, 1, // char 66 + 0, 3, 1, // char 67 + 0, 4, 1, // char 68 + 0, 3, 1, // char 69 + 0, 3, 1, // char 70 + 0, 4, 1, // char 71 + 0, 4, 1, // char 72 + 0, 3, 1, // char 73 + 0, 4, 1, // char 74 + 0, 4, 1, // char 75 + 0, 3, 1, // char 76 + 0, 5, 1, // char 77 + 0, 4, 1, // char 78 + 0, 4, 1, // char 79 + 0, 4, 1, // char 80 + 0, 4, 1, // char 81 + 0, 4, 1, // char 82 + 0, 4, 1, // char 83 + 0, 3, 1, // char 84 + 0, 4, 1, // char 85 + 0, 4, 1, // char 86 + 0, 5, 1, // char 87 + 0, 4, 1, // char 88 + 0, 4, 1, // char 89 + 0, 3, 1, // char 90 + 0, 2, 1, // char 91 + 0, 3, 1, // char 92 + 0, 2, 1, // char 93 + 0, 3, 1, // char 94 + 0, 5, 1, // char 95 + 0, 2, 1, // char 96 + 0, 4, 1, // char 97 + 0, 4, 1, // char 98 + 0, 3, 1, // char 99 + 0, 4, 1, // char 100 + 0, 4, 1, // char 101 + 0, 3, 1, // char 102 + 0, 4, 1, // char 103 + 0, 4, 1, // char 104 + 0, 1, 1, // char 105 + 0, 2, 1, // char 106 + 0, 4, 1, // char 107 + 0, 1, 1, // char 108 + 0, 5, 1, // char 109 + 0, 4, 1, // char 110 + 0, 4, 1, // char 111 + 0, 4, 1, // char 112 + 0, 4, 1, // char 113 + 0, 3, 1, // char 114 + 0, 4, 1, // char 115 + 0, 3, 1, // char 116 + 0, 4, 1, // char 117 + 0, 4, 1, // char 118 + 0, 5, 1, // char 119 + 0, 3, 1, // char 120 + 0, 4, 1, // char 121 + 0, 4, 1, // char 122 + 0, 3, 1, // char 123 + 0, 1, 1, // char 124 + 0, 3, 1, // char 125 + 0, 5, 1, // char 126 + 1, 5, 0, // char 127 + 0, 4, 1, // char 128 + 1, 5, 0, // char 129 + 1, 5, 0, // char 130 + 1, 5, 0, // char 131 + 1, 5, 0, // char 132 + 1, 5, 0, // char 133 + 1, 5, 0, // char 134 + 1, 5, 0, // char 135 + 1, 5, 0, // char 136 + 0, 5, 1, // char 137 + 1, 5, 0, // char 138 + 1, 5, 0, // char 139 + 0, 6, 1, // char 140 + 1, 5, 0, // char 141 + 1, 5, 0, // char 142 + 1, 5, 0, // char 143 + 1, 5, 0, // char 144 + 1, 5, 0, // char 145 + 1, 5, 0, // char 146 + 1, 5, 0, // char 147 + 1, 5, 0, // char 148 + 0, 2, 1, // char 149 + 1, 5, 0, // char 150 + 1, 5, 0, // char 151 + 1, 5, 0, // char 152 + 0, 4, 1, // char 153 + 1, 5, 0, // char 154 + 1, 5, 0, // char 155 + 1, 5, 0, // char 156 + 1, 5, 0, // char 157 + 1, 5, 0, // char 158 + 0, 4, 1, // char 159 + 1, 5, 0, // char 160 + 0, 1, 1, // char 161 + 0, 4, 1, // char 162 + 0, 4, 1, // char 163 + 0, 5, 1, // char 164 + 0, 3, 1, // char 165 + 0, 1, 1, // char 166 + 0, 4, 1, // char 167 + 0, 3, 1, // char 168 + 0, 2, 1, // char 169 + 0, 8, 1, // char 170 + 0, 4, 1, // char 171 + 0, 4, 1, // char 172 + 1, 5, 0, // char 173 + 0, 2, 1, // char 174 + 0, 4, 1, // char 175 + 0, 3, 1, // char 176 + 0, 3, 1, // char 177 + 0, 2, 1, // char 178 + 0, 2, 1, // char 179 + 0, 2, 1, // char 180 + 0, 4, 1, // char 181 + 0, 5, 1, // char 182 + 1, 1, 1, // char 183 + 0, 8, 1, // char 184 + 0, 2, 1, // char 185 + 0, 2, 1, // char 186 + 0, 4, 1, // char 187 + 0, 7, 1, // char 188 + 0, 8, 1, // char 189 + 0, 8, 1, // char 190 + 0, 4, 1, // char 191 + 0, 4, 1, // char 192 + 0, 4, 1, // char 193 + 0, 4, 1, // char 194 + 0, 4, 1, // char 195 + 0, 4, 1, // char 196 + 0, 4, 1, // char 197 + 0, 6, 1, // char 198 + 0, 3, 1, // char 199 + 0, 3, 1, // char 200 + 0, 3, 1, // char 201 + 0, 3, 1, // char 202 + 0, 3, 1, // char 203 + 0, 3, 1, // char 204 + 0, 3, 1, // char 205 + 0, 3, 1, // char 206 + 0, 3, 1, // char 207 + 0, 10, 1, // char 208 + 0, 4, 1, // char 209 + 0, 4, 1, // char 210 + 0, 4, 1, // char 211 + 0, 4, 1, // char 212 + 0, 4, 1, // char 213 + 0, 4, 1, // char 214 + 0, 3, 1, // char 215 + 0, 5, 1, // char 216 + 0, 4, 1, // char 217 + 0, 4, 1, // char 218 + 0, 4, 1, // char 219 + 0, 4, 1, // char 220 + 0, 4, 1, // char 221 + 0, 3, 1, // char 222 + 0, 3, 1, // char 223 + 0, 4, 1, // char 224 + 0, 4, 1, // char 225 + 0, 4, 1, // char 226 + 0, 4, 1, // char 227 + 0, 4, 1, // char 228 + 0, 4, 1, // char 229 + 0, 7, 1, // char 230 + 0, 3, 1, // char 231 + 0, 4, 1, // char 232 + 0, 4, 1, // char 233 + 0, 4, 1, // char 234 + 0, 4, 1, // char 235 + 0, 2, 1, // char 236 + 0, 2, 1, // char 237 + 0, 3, 1, // char 238 + 0, 3, 1, // char 239 + 0, 5, 1, // char 240 + 0, 4, 1, // char 241 + 0, 4, 1, // char 242 + 0, 4, 1, // char 243 + 0, 4, 1, // char 244 + 0, 4, 1, // char 245 + 0, 4, 1, // char 246 + 0, 5, 1, // char 247 + 0, 4, 1, // char 248 + 0, 4, 1, // char 249 + 0, 4, 1, // char 250 + 0, 4, 1, // char 251 + 0, 4, 1, // char 252 + 0, 4, 1, // char 253 + 0, 10, 1, // char 254 + 0, 4, 1, // char 255 + 226 + ) diff --git a/interface/fonts/vcr_osd_mono.dm b/interface/fonts/vcr_osd_mono.dm new file mode 100644 index 0000000000..301d90d2f7 --- /dev/null +++ b/interface/fonts/vcr_osd_mono.dm @@ -0,0 +1,3 @@ +/datum/font/vcr_osd_mono + name = "VCR OSD Mono" + font_family = 'interface/fonts/VCR_OSD_Mono.ttf' diff --git a/interface/interface.dm b/interface/interface.dm index 2aece7cb6c..78da9b9ebf 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -82,9 +82,10 @@ /client/verb/changelog() set name = "Changelog" set category = "OOC" - var/datum/asset/simple/namespaced/changelog = get_asset_datum(/datum/asset/simple/namespaced/changelog) - changelog.send(src) - src << browse(changelog.get_htmlloader("changelog.html"), "window=changes;size=675x650") + if(!GLOB.changelog_tgui) + GLOB.changelog_tgui = new /datum/changelog() + + GLOB.changelog_tgui.ui_interact(usr) if(prefs.lastchangelog != GLOB.changelog_hash) prefs.lastchangelog = GLOB.changelog_hash prefs.save_preferences() diff --git a/interface/skin.dmf b/interface/skin.dmf index ccfcd76571..d80b5dcd22 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -2,21 +2,21 @@ macro "default" menu "menu" - elem + elem name = "&File" command = "" saved-params = "is-checked" - elem + elem name = "&Quick screenshot\tF2" command = ".screenshot auto" category = "&File" saved-params = "is-checked" - elem + elem name = "&Save screenshot as...\tShift+F2" command = ".screenshot" category = "&File" saved-params = "is-checked" - elem + elem name = "" command = "" category = "&File" @@ -26,21 +26,21 @@ menu "menu" command = ".reconnect" category = "&File" saved-params = "is-checked" - elem + elem name = "&Quit\tAlt-F4" command = ".quit" category = "&File" saved-params = "is-checked" - elem + elem name = "&Help" command = "" saved-params = "is-checked" - elem + elem name = "&Admin Help\tF1" command = "adminhelp" category = "&Help" saved-params = "is-checked" - elem + elem name = "&Hotkeys" command = "hotkeys-help" category = "&Help" @@ -56,6 +56,7 @@ window "mainwindow" anchor2 = none is-default = true saved-params = "pos;size;is-minimized;is-maximized" + statusbar = false icon = 'icons\\ss13_64.png' macro = "default" menu = "menu" @@ -95,6 +96,7 @@ window "mapwindow" anchor2 = none saved-params = "pos;size;is-minimized;is-maximized" is-pane = true + on-status = ".winset \"status_bar.text=[[*]]\" " elem "map" type = MAP pos = 0,0 @@ -106,7 +108,17 @@ window "mapwindow" text-color = none is-default = true saved-params = "zoom;letterbox;zoom-mode" - style = ".center { text-align: center; } .maptext { font-family: 'Small Fonts'; font-size: 7px; -dm-text-outline: 1px black; color: white; line-height: 1.1; } .command_headset { font-weight: bold;\tfont-size: 8px; } .small { font-size: 6px; } .big { font-size: 8px; } .reallybig { font-size: 8px; } .extremelybig { font-size: 8px; } .greentext { color: #00FF00; font-size: 7px; } .redtext { color: #FF0000; font-size: 7px; } .clown { color: #FF69Bf; font-size: 7px; font-weight: bold; } .his_grace { color: #15D512; } .hypnophrase { color: #0d0d0d; font-weight: bold; } .yell { font-weight: bold; } .italics { font-size: 6px; }" + style = ".center { text-align: center; } .maptext { font-family: 'Small Fonts'; font-size: 7px; -dm-text-outline: 1px black; color: white; line-height: 1.1; } .command_headset { font-weight: bold;\tfont-size: 8px; } .context { font-family: 'Pixellari'; font-size: 12pt; -dm-text-outline: 1px black; } .subcontext { font-family: 'TinyUnicode'; font-size: 12pt; line-height: 0.75; } .small { font-size: 6px; } .big { font-size: 8px; } .reallybig { font-size: 8px; } .extremelybig { font-size: 8px; } .greentext { color: #00FF00; font-size: 7px; } .redtext { color: #FF0000; font-size: 7px; } .clown { color: #FF69Bf; font-size: 7px; font-weight: bold; } .his_grace { color: #15D512; } .hypnophrase { color: #0d0d0d; font-weight: bold; } .yell { font-weight: bold; } .italics { font-size: 6px; }" + elem "status_bar" + type = LABEL + pos = 0,1008 + size = 280x16 + anchor1 = 0,100 + text = "" + align = left + background-color = #222222 + text-color = #ffffff + border = line window "infowindow" elem "infowindow" diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index dea6da4254..292f2fc4d9 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -58,6 +58,9 @@ em {font-style: normal; font-weight: bold;} .aiprivradio {color: #ff00ff;} .redteamradio {color: #ff0000;} .blueteamradio {color: #0000ff;} +.greenteamradio {color: #00ff00;} +.yellowteamradio {color: #d1ba22;} +.gangradio {color: #ac2ea1;} .yell { font-weight: bold;} diff --git a/modular_citadel/code/datums/components/souldeath.dm b/modular_citadel/code/datums/components/souldeath.dm index ab45210a46..01e6acb795 100644 --- a/modular_citadel/code/datums/components/souldeath.dm +++ b/modular_citadel/code/datums/components/souldeath.dm @@ -32,4 +32,4 @@ playsound(wearer, 'sound/misc/souldeath.ogg', 100, FALSE) /datum/component/souldeath/neck - equip_slot = SLOT_NECK + equip_slot = ITEM_SLOT_NECK diff --git a/modular_citadel/code/game/objects/cit_screenshake.dm b/modular_citadel/code/game/objects/cit_screenshake.dm deleted file mode 100644 index 222de37f82..0000000000 --- a/modular_citadel/code/game/objects/cit_screenshake.dm +++ /dev/null @@ -1,51 +0,0 @@ -//we vlambeer now - -/obj/proc/shake_camera(mob/M, duration, strength=1)//byond's wonky with this shit - set waitfor = FALSE - if(!M || !M.client || duration <= 0) - return - var/client/C = M.client - if (C.prefs.screenshake==0) - return - var/oldx = C.pixel_x - var/oldy = C.pixel_y - var/clientscreenshake = (C.prefs.screenshake * 0.01) - var/max = (strength*clientscreenshake) * world.icon_size - var/min = -((strength*clientscreenshake) * world.icon_size) - - for(var/i in 0 to duration-1) - if (i == 0) - animate(C, pixel_x=rand(min,max), pixel_y=rand(min,max), time=1) - else - animate(pixel_x=rand(min,max), pixel_y=rand(min,max), time=1) - animate(pixel_x=oldx, pixel_y=oldy, time=1) - -/obj/item/gun/energy - recoil = 0.1 - -/obj/item/gun/energy/kinetic_accelerator - recoil = 0.5 - -/obj/item/gun/ballistic - recoil = 0.25 - -/obj/item/gun/ballistic/shotgun - recoil = 1 - -/obj/item/gun/ballistic/revolver - recoil = 0.5 - -/obj/item/gun/ballistic/revolver/doublebarrel - recoil = 1 - -/obj/item/gun/syringe - recoil = 0.1 - -/obj/item/pneumatic_cannon/fire_items(turf/target, mob/user) - . = ..() - shake_camera(user, (pressureSetting * 0.75 + 1), (pressureSetting * 0.75)) - -/obj/item/attack_obj(obj/O, mob/living/user) - . = ..() - if(force >= 20) - shake_camera(user, ((force - 15) * 0.01 + 1), ((force - 15) * 0.01)) diff --git a/modular_citadel/code/modules/client/loadout/__donator.dm b/modular_citadel/code/modules/client/loadout/__donator.dm index c1489da94a..9e07329151 100644 --- a/modular_citadel/code/modules/client/loadout/__donator.dm +++ b/modular_citadel/code/modules/client/loadout/__donator.dm @@ -2,561 +2,7 @@ /datum/gear/donator name = "IF YOU SEE THIS, PING A CODER RIGHT NOW!" - slot = SLOT_IN_BACKPACK + slot = ITEM_SLOT_BACKPACK path = /obj/item/bikehorn/golden category = LOADOUT_CATEGORY_DONATOR ckeywhitelist = list("This entry should never appear with this variable set.") //If it does, then that means somebody fucked up the whitelist system pretty hard - -/datum/gear/donator/pet - name = "Pet Beacon" - slot = SLOT_IN_BACKPACK - path = /obj/item/choice_beacon/pet - ckeywhitelist = list() - donator_group_id = DONATOR_GROUP_TIER_1 // can be accessed by all donators - -/datum/gear/donator/carpet - name = "Carpet Beacon" - slot = SLOT_IN_BACKPACK - path = /obj/item/choice_beacon/box/carpet - ckeywhitelist = list() - donator_group_id = DONATOR_GROUP_TIER_1 - -/datum/gear/donator/chameleon_bedsheet - name = "Chameleon Bedsheet" - slot = SLOT_NECK - path = /obj/item/bedsheet/chameleon - ckeywhitelist = list() - donator_group_id = DONATOR_GROUP_TIER_1 - -/datum/gear/donator/donortestingbikehorn - name = "Donor item testing bikehorn" - slot = SLOT_IN_BACKPACK - path = /obj/item/bikehorn - geargroupID = list("DONORTEST") //This is a list mainly for the sake of testing, but geargroupID works just fine with ordinary strings - -/datum/gear/donator/kevhorn - name = "Airhorn" - slot = SLOT_IN_BACKPACK - path = /obj/item/bikehorn/airhorn - ckeywhitelist = list("kevinz000") - -/datum/gear/donator/kiaracloak - name = "Kiara's cloak" - slot = SLOT_NECK - path = /obj/item/clothing/neck/cloak/inferno - ckeywhitelist = list("inferno707") - -/datum/gear/donator/kiaracollar - name = "Kiara's collar" - slot = SLOT_NECK - path = /obj/item/clothing/neck/petcollar/inferno - ckeywhitelist = list("inferno707") - -/datum/gear/donator/kiaramedal - name = "Insignia of Steele" - slot = SLOT_IN_BACKPACK - path = /obj/item/clothing/accessory/medal/steele - ckeywhitelist = list("inferno707") - -/datum/gear/donator/hheart - name = "The Hollow Heart" - slot = SLOT_WEAR_MASK - path = /obj/item/clothing/mask/hheart - ckeywhitelist = list("inferno707") - -/datum/gear/donator/engravedzippo - name = "Engraved zippo" - slot = SLOT_HANDS - path = /obj/item/lighter/gold - ckeywhitelist = list("dirtyoldharry") - -/datum/gear/donator/geisha - name = "Geisha suit" - slot = SLOT_W_UNIFORM - path = /obj/item/clothing/under/costume/geisha - ckeywhitelist = list("atiefling") - -/datum/gear/donator/specialscarf - name = "Special scarf" - slot = SLOT_NECK - path = /obj/item/clothing/neck/scarf/zomb - ckeywhitelist = list("zombierobin") - -/datum/gear/donator/redmadcoat - name = "The Mad's labcoat" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/suit/toggle/labcoat/mad/red - ckeywhitelist = list("zombierobin") - -/datum/gear/donator/santahat - name = "Santa hat" - slot = SLOT_HEAD - path = /obj/item/clothing/head/santa/fluff - ckeywhitelist = list("illotafv") - -/datum/gear/donator/reindeerhat - name = "Reindeer hat" - slot = SLOT_HEAD - path = /obj/item/clothing/head/hardhat/reindeer/fluff - ckeywhitelist = list("illotafv") - -/datum/gear/donator/treeplushie - name = "Christmas tree plushie" - slot = SLOT_IN_BACKPACK - path = /obj/item/toy/plush/tree - ckeywhitelist = list("illotafv") - -/datum/gear/donator/santaoutfit - name = "Santa costume" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/suit/space/santa/fluff - ckeywhitelist = list("illotafv") - -/datum/gear/donator/treecloak - name = "Christmas tree cloak" - slot = SLOT_NECK - path = /obj/item/clothing/neck/cloak/festive - ckeywhitelist = list("illotafv") - -/datum/gear/donator/carrotplush - name = "Carrot plushie" - slot = SLOT_IN_BACKPACK - path = /obj/item/toy/plush/carrot - ckeywhitelist = list("improvedname") - -/datum/gear/donator/carrotcloak - name = "Carrot cloak" - slot = SLOT_NECK - path = /obj/item/clothing/neck/cloak/carrot - ckeywhitelist = list("improvedname") - -/datum/gear/donator/albortorosamask - name = "Alborto Rosa mask" - slot = SLOT_WEAR_MASK - path = /obj/item/clothing/mask/luchador/zigfie - ckeywhitelist = list("zigfie") - -/datum/gear/donator/mankini - name = "Mankini" - slot = SLOT_W_UNIFORM - path = /obj/item/clothing/under/misc/stripper/mankini - ckeywhitelist = list("zigfie") - -/datum/gear/donator/pinkshoes - name = "Pink shoes" - slot = SLOT_SHOES - path = /obj/item/clothing/shoes/sneakers/pink - ckeywhitelist = list("zigfie") - -/datum/gear/donator/reecesgreatcoat - name = "Reece's Great Coat" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/suit/trenchcoat/green - ckeywhitelist = list("geemiesif") - -/datum/gear/donator/russianflask - name = "Russian flask" - slot = SLOT_IN_BACKPACK - path = /obj/item/reagent_containers/food/drinks/flask/russian - cost = 2 - ckeywhitelist = list("slomka") - -/datum/gear/donator/stalkermask - name = "S.T.A.L.K.E.R. mask" - slot = SLOT_WEAR_MASK - path = /obj/item/clothing/mask/gas/stalker - ckeywhitelist = list("slomka") - -/datum/gear/donator/stripedcollar - name = "Striped collar" - slot = SLOT_NECK - path = /obj/item/clothing/neck/petcollar/stripe - ckeywhitelist = list("jademanique") - -/datum/gear/donator/performersoutfit - name = "Bluish performer's outfit" - slot = SLOT_W_UNIFORM - path = /obj/item/clothing/under/costume/singer/yellow/custom - ckeywhitelist = list("killer402402") - -/datum/gear/donator/vermillion - name = "Vermillion clothing" - slot = SLOT_W_UNIFORM - path = /obj/item/clothing/suit/vermillion - ckeywhitelist = list("fractious") - -/datum/gear/donator/AM4B - name = "Foam Force AM4-B" - slot = SLOT_IN_BACKPACK - path = /obj/item/gun/ballistic/automatic/AM4B - ckeywhitelist = list("zeronetalpha") - -/datum/gear/donator/carrotsatchel - name = "Carrot Satchel" - slot = SLOT_HANDS - path = /obj/item/storage/backpack/satchel/carrot - ckeywhitelist = list("improvedname") - -/datum/gear/donator/naomisweater - name = "worn black sweater" - slot = SLOT_W_UNIFORM - path = /obj/item/clothing/under/sweater/black/naomi - ckeywhitelist = list("technicalmagi") - -/datum/gear/donator/naomicollar - name = "worn pet collar" - slot = SLOT_NECK - path = /obj/item/clothing/neck/petcollar/naomi - ckeywhitelist = list("technicalmagi") - -/datum/gear/donator/gladiator - name = "Gladiator Armor" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/under/costume/gladiator - ckeywhitelist = list("aroche") - -/datum/gear/donator/bloodredtie - name = "Blood Red Tie" - slot = SLOT_NECK - path = /obj/item/clothing/neck/tie/bloodred - ckeywhitelist = list("kyutness") - -/datum/gear/donator/puffydress - name = "Puffy Dress" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/suit/puffydress - ckeywhitelist = list("stallingratt") - -/datum/gear/donator/labredblack - name = "Black and Red Coat" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/suit/toggle/labcoat/labredblack - ckeywhitelist = list("blakeryan", "durandalphor") - -/datum/gear/donator/torisword - name = "Rainbow Zweihander" - slot = SLOT_IN_BACKPACK - path = /obj/item/dualsaber/hypereutactic/toy/rainbow - ckeywhitelist = list("annoymous35") - -/datum/gear/donator/darksabre - name = "Dark Sabre" - slot = SLOT_IN_BACKPACK - path = /obj/item/toy/darksabre - ckeywhitelist = list("inferno707") - -/datum/gear/donator/darksabresheath - name = "Dark Sabre Sheath" - slot = SLOT_IN_BACKPACK - path = /obj/item/storage/belt/sabre/darksabre - ckeywhitelist = list("inferno707") - -/datum/gear/donator/toriball - name = "Rainbow Tennis Ball" - slot = SLOT_IN_BACKPACK - path = /obj/item/toy/fluff/tennis_poly/tri/squeak/rainbow - ckeywhitelist = list("annoymous35") - -/datum/gear/donator/izzyball - name = "Katlin's Ball" - slot = SLOT_IN_BACKPACK - path = /obj/item/toy/fluff/tennis_poly/tri/squeak/izzy - ckeywhitelist = list("izzyinbox") - -/datum/gear/donator/cloak - name = "Green Cloak" - slot = SLOT_NECK - path = /obj/item/clothing/neck/cloak/green - ckeywhitelist = list("killer402402") - -/datum/gear/donator/steelflask - name = "Steel Flask" - slot = SLOT_IN_BACKPACK - path = /obj/item/reagent_containers/food/drinks/flask/steel - cost = 2 - ckeywhitelist = list("nik707") - -/datum/gear/donator/paperhat - name = "Paper Hat" - slot = SLOT_HEAD - path = /obj/item/clothing/head/paperhat - ckeywhitelist = list("kered2") - -/datum/gear/donator/cloakce - name = "Polychromic CE Cloak" - slot = SLOT_IN_BACKPACK - path = /obj/item/clothing/neck/cloak/polychromic/polyce - ckeywhitelist = list("worksbythesea", "blakeryan") - loadout_flags = LOADOUT_CAN_COLOR_POLYCHROMIC - loadout_initial_colors = list("#808080", "#8CC6FF", "#FF3535") - -/datum/gear/donator/ssk - name = "Stun Sword Kit" - slot = SLOT_IN_BACKPACK - path = /obj/item/ssword_kit - ckeywhitelist = list("phillip458") - -/datum/gear/donator/techcoat - name = "Techomancers Labcoat" - slot = SLOT_IN_BACKPACK - path = /obj/item/clothing/suit/toggle/labcoat/mad/techcoat - ckeywhitelist = list("wilchen") - -/datum/gear/donator/leechjar - name = "Jar of Leeches" - slot = SLOT_IN_BACKPACK - path = /obj/item/custom/leechjar - ckeywhitelist = list("sgtryder") - -/datum/gear/donator/darkarmor - name = "Dark Armor" - slot = SLOT_IN_BACKPACK - path = /obj/item/clothing/suit/armor/vest/darkcarapace - ckeywhitelist = list("inferno707") - -/datum/gear/donator/devilwings - name = "Strange Wings" - slot = SLOT_NECK - path = /obj/item/clothing/neck/devilwings - ckeywhitelist = list("kitsun") - -/datum/gear/donator/flagcape - name = "US Flag Cape" - slot = SLOT_IN_BACKPACK - path = /obj/item/clothing/neck/flagcape - ckeywhitelist = list("darnchacha") - -/datum/gear/donator/luckyjack - name = "Lucky Jackboots" - slot = SLOT_IN_BACKPACK - path = /obj/item/clothing/shoes/lucky - ckeywhitelist = list("donaldtrumpthecommunist") - -/datum/gear/donator/raiqbawks - name = "Miami Boombox" - slot = SLOT_HANDS - cost = 2 - path = /obj/item/boombox/raiq - ckeywhitelist = list("chefferz") - -/datum/gear/donator/m41 - name = "Toy M41" - slot = SLOT_IN_BACKPACK - path = /obj/item/toy/gun/m41 - ckeywhitelist = list("thalverscholen") - -/datum/gear/donator/Divine_robes - name = "Divine robes" - slot = SLOT_W_UNIFORM - path = /obj/item/clothing/under/custom/lunasune - ckeywhitelist = list("invader4352") - -/datum/gear/donator/gothcoat - name = "Goth Coat" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/suit/gothcoat - ckeywhitelist = list("norko") - -/datum/gear/donator/corgisuit - name = "Corgi Suit" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/suit/hooded/ian_costume - ckeywhitelist = list("cathodetherobot") - -/datum/gear/donator/sharkcloth - name = "Leon's Skimpy Outfit" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/under/custom/leoskimpy - ckeywhitelist = list("spectrosis") - -/datum/gear/donator/mimemask - name = "Mime Mask" - slot = SLOT_WEAR_MASK - path = /obj/item/clothing/mask/gas/mime - ckeywhitelist = list("pireamaineach") - -/datum/gear/donator/mimeoveralls - name = "Mime's Overalls" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/under/custom/mimeoveralls - ckeywhitelist = list("pireamaineach") - -/datum/gear/donator/soulneck - name = "Soul Necklace" - slot = SLOT_NECK - path = /obj/item/clothing/neck/undertale - ckeywhitelist = list("twilightic") - -/datum/gear/donator/frenchberet - name = "French Beret" - slot = SLOT_HEAD - path = /obj/item/clothing/head/frenchberet - ckeywhitelist = list("notazoltan") - -/datum/gear/donator/zuliecloak - name = "Project: Zul-E" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/suit/hooded/cloak/zuliecloak - ckeywhitelist = list("asky") - -/datum/gear/donator/blackredgold - name = "Black, Red, and Gold Coat" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/suit/blackredgold - ckeywhitelist = list("ttbnc") - -/datum/gear/donator/fritzplush - name = "Fritz Plushie" - slot = SLOT_IN_BACKPACK - path = /obj/item/toy/plush/mammal/dog/fritz - ckeywhitelist = list("analwerewolf") - -/datum/gear/donator/kimono - name = "Kimono" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/suit/kimono - ckeywhitelist = list("sfox63") - -/datum/gear/donator/commjacket - name = "Dusty Commisar's Cloak" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/suit/commjacket - ckeywhitelist = list("sadisticbatter") - -/datum/gear/donator/mw2_russian_para - name = "Russian Paratrooper Jumper" - slot = SLOT_W_UNIFORM - path = /obj/item/clothing/under/custom/mw2_russian_para - ckeywhitelist = list("investigator77") - -/datum/gear/donator/longblackgloves - name = "Luna's Gauntlets" - slot = SLOT_GLOVES - path = /obj/item/clothing/gloves/longblackgloves - ckeywhitelist = list("bigmanclancy") - -/datum/gear/donator/trendy_fit - name = "Trendy Fit" - slot = SLOT_W_UNIFORM - path = /obj/item/clothing/under/custom/trendy_fit - ckeywhitelist = list("midgetdragon") - -/datum/gear/donator/singery - name = "Yellow Performer Outfit" - slot = SLOT_W_UNIFORM - path = /obj/item/clothing/under/costume/singer/yellow - ckeywhitelist = list("maxlynchy") - -/datum/gear/donator/csheet - name = "NT Bedsheet" - slot = SLOT_NECK - path = /obj/item/bedsheet/captain - ckeywhitelist = list("tikibomb") - -/datum/gear/donator/borgplush - name = "Robot Plush" - slot = SLOT_IN_BACKPACK - path = /obj/item/toy/plush/borgplushie - ckeywhitelist = list("nicholaiavenicci") - -/datum/gear/donator/donorberet - name = "Atmos Beret" - slot = SLOT_HEAD - path = /obj/item/clothing/head/blueberet - ckeywhitelist = list("foxystalin") - -/datum/gear/donator/donorgoggles - name = "Flight Goggles" - slot = SLOT_HEAD - path = /obj/item/clothing/head/flight - ckeywhitelist = list("maxlynchy") - -/datum/gear/donator/onionneck - name = "Onion Necklace" - slot = SLOT_NECK - path = /obj/item/clothing/neck/necklace/onion - ckeywhitelist = list("cdrcross") - -/datum/gear/donator/mikubikini - name = "starlight singer bikini" - slot = SLOT_W_UNIFORM - path = /obj/item/clothing/under/custom/mikubikini - ckeywhitelist = list("grandvegeta") - -/datum/gear/donator/mikujacket - name = "starlight singer jacket" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/suit/mikujacket - ckeywhitelist = list("grandvegeta") - -/datum/gear/donator/mikuhair - name = "starlight singer hair" - slot = SLOT_W_UNIFORM - path = /obj/item/clothing/head/mikuhair - ckeywhitelist = list("grandvegeta") - -/datum/gear/donator/mikugloves - name = "starlight singer gloves" - slot = SLOT_GLOVES - path = /obj/item/clothing/gloves/mikugloves - ckeywhitelist = list("grandvegeta") - -/datum/gear/donator/mikuleggings - name = "starlight singer leggings" - slot = SLOT_SHOES - path = /obj/item/clothing/shoes/sneakers/mikuleggings - ckeywhitelist = list("grandvegeta") - -/datum/gear/donator/cosmos - name = "cosmic space bedsheet" - slot = SLOT_IN_BACKPACK - path = /obj/item/bedsheet/cosmos - ckeywhitelist = list("grunnyyy") - -/datum/gear/donator/customskirt - name = "custom atmos skirt" - slot = SLOT_IN_BACKPACK - path = /obj/item/clothing/under/custom/customskirt - ckeywhitelist = list("thakyz") - -/datum/gear/donator/hisakaki - name = "halo" - slot = SLOT_HEAD - path = /obj/item/clothing/head/halo - ckeywhitelist = list("hisakaki") - -/datum/gear/donator/vest - name = "vest and shirt" - slot = SLOT_W_UNIFORM - path = /obj/item/clothing/under/custom/vest - ckeywhitelist = list("maylowfox") - -/datum/gear/donator/exo - name = "exo frame" - slot = SLOT_WEAR_SUIT - path = /obj/item/clothing/suit/custom/exo - ckeywhitelist = list("jesterz7") - -/datum/gear/donator/choker - name = "NT Choker" - slot = SLOT_NECK - path = /obj/item/clothing/neck/petcollar/donorchoker - ckeywhitelist = list("trigillass") - -/datum/gear/donator/strangemask - name = "Strange Metal Mask" - slot = SLOT_IN_BACKPACK - path = /obj/item/clothing/mask/breath/mmask - ckeywhitelist = list("sneka") - -/datum/gear/donator/smaiden - name = "shrine maiden outfit" - slot = SLOT_W_UNIFORM - path = /obj/item/clothing/under/smaiden - ckeywhitelist = list("ultimarifox") - -/datum/gear/donator/mgasmask - name = "Military Gas Mask" - slot = SLOT_IN_BACKPACK - path = /obj/item/clothing/mask/gas/military - ckeywhitelist = list("unclebourbon") diff --git a/modular_citadel/code/modules/client/loadout/_loadout.dm b/modular_citadel/code/modules/client/loadout/_loadout.dm index 5f895c4805..0f58b4c48f 100644 --- a/modular_citadel/code/modules/client/loadout/_loadout.dm +++ b/modular_citadel/code/modules/client/loadout/_loadout.dm @@ -55,9 +55,10 @@ GLOBAL_LIST_EMPTY(loadout_whitelist_ids) var/geargroupID //defines the ID that the gear inherits from the config var/loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION var/list/loadout_initial_colors = list() + var/handle_post_equip = FALSE //NEW DONATOR SYTSEM STUFF - var/donoritem //autoset on new if null + var/donoritem //autoset on new if null var/donator_group_id //New donator group ID system. //END diff --git a/modular_citadel/code/modules/client/loadout/accessory.dm b/modular_citadel/code/modules/client/loadout/accessory.dm new file mode 100644 index 0000000000..55cce181a5 --- /dev/null +++ b/modular_citadel/code/modules/client/loadout/accessory.dm @@ -0,0 +1,20 @@ +/datum/gear/accessory + category = LOADOUT_CATEGORY_ACCESSORY + slot = ITEM_SLOT_ACCESSORY + handle_post_equip = TRUE + +/datum/gear/accessory/necklace + name = "A renameable necklace" + path = /obj/item/clothing/accessory/necklace + +/datum/gear/accessory/polymaidapron + name = "Polychromic maid apron" + path = /obj/item/clothing/accessory/maidapron/polychromic + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#333333", "#FFFFFF") + +/datum/gear/accessory/pridepin + name = "Pride pin" + path = /obj/item/clothing/accessory/pride + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION + cost = 0 diff --git a/modular_citadel/code/modules/client/loadout/backpack.dm b/modular_citadel/code/modules/client/loadout/backpack.dm index 466ee50474..24545e7b4c 100644 --- a/modular_citadel/code/modules/client/loadout/backpack.dm +++ b/modular_citadel/code/modules/client/loadout/backpack.dm @@ -1,7 +1,8 @@ /datum/gear/backpack category = LOADOUT_CATEGORY_BACKPACK subcategory = LOADOUT_SUBCATEGORY_BACKPACK_GENERAL - slot = SLOT_IN_BACKPACK + slot = ITEM_SLOT_BACKPACK + handle_post_equip = TRUE /datum/gear/backpack/plushbox name = "Plushie Choice Box" @@ -172,6 +173,7 @@ path = /obj/item/storage/fancy/ringbox/diamond cost = 5 -/datum/gear/backpack/necklace//this is here because loadout doesn't support proper accessories - name = "A renameable necklace" - path = /obj/item/clothing/accessory/necklace +// Moved here from quirks +/datum/gear/backpack/dyespray + name = "Hair dye spray" + path = /obj/item/dyespray diff --git a/modular_citadel/code/modules/client/loadout/donator/accessory.dm b/modular_citadel/code/modules/client/loadout/donator/accessory.dm new file mode 100644 index 0000000000..40569d024f --- /dev/null +++ b/modular_citadel/code/modules/client/loadout/donator/accessory.dm @@ -0,0 +1,8 @@ +/datum/gear/donator/accessory + slot = ITEM_SLOT_ACCESSORY + handle_post_equip = TRUE + +/datum/gear/donator/accessory/kiaramedal + name = "Insignia of Steele" + path = /obj/item/clothing/accessory/medal/steele + ckeywhitelist = list("inferno707") diff --git a/modular_citadel/code/modules/client/loadout/donator/backpack.dm b/modular_citadel/code/modules/client/loadout/donator/backpack.dm new file mode 100644 index 0000000000..71acdab122 --- /dev/null +++ b/modular_citadel/code/modules/client/loadout/donator/backpack.dm @@ -0,0 +1,153 @@ +/datum/gear/donator/backpack + handle_post_equip = TRUE + +/datum/gear/donator/backpack/pet + name = "Pet Beacon" + path = /obj/item/choice_beacon/pet + ckeywhitelist = list() + donator_group_id = DONATOR_GROUP_TIER_1 // can be accessed by all donators + +/datum/gear/donator/backpack/carpet + name = "Carpet Beacon" + path = /obj/item/choice_beacon/box/carpet + ckeywhitelist = list() + donator_group_id = DONATOR_GROUP_TIER_1 + +/datum/gear/donator/backpack/donortestingbikehorn + name = "Donor item testing bikehorn" + path = /obj/item/bikehorn + geargroupID = list("DONORTEST") //This is a list mainly for the sake of testing, but geargroupID works just fine with ordinary strings + +/datum/gear/donator/backpack/kevhorn + name = "Airhorn" + path = /obj/item/bikehorn/airhorn + ckeywhitelist = list("kevinz000") + +/datum/gear/donator/backpack/treeplushie + name = "Christmas tree plushie" + path = /obj/item/toy/plush/tree + ckeywhitelist = list("illotafv") + +/datum/gear/donator/backpack/carrotplush + name = "Carrot plushie" + path = /obj/item/toy/plush/carrot + ckeywhitelist = list("improvedname") + +/datum/gear/donator/backpack/russianflask + name = "Russian flask" + path = /obj/item/reagent_containers/food/drinks/flask/russian + cost = 2 + ckeywhitelist = list("slomka") + +/datum/gear/donator/backpack/AM4B + name = "Foam Force AM4-B" + path = /obj/item/gun/ballistic/automatic/AM4B + ckeywhitelist = list("zeronetalpha") + +/datum/gear/donator/backpack/torisword + name = "Rainbow Zweihander" + path = /obj/item/dualsaber/hypereutactic/toy/rainbow + ckeywhitelist = list("annoymous35") + +/datum/gear/donator/backpack/darksabre + name = "Dark Sabre" + path = /obj/item/toy/darksabre + ckeywhitelist = list("inferno707") + +/datum/gear/donator/backpack/darksabresheath + name = "Dark Sabre Sheath" + path = /obj/item/storage/belt/sabre/darksabre + ckeywhitelist = list("inferno707") + +/datum/gear/donator/backpack/toriball + name = "Rainbow Tennis Ball" + path = /obj/item/toy/fluff/tennis_poly/tri/squeak/rainbow + ckeywhitelist = list("annoymous35") + +/datum/gear/donator/backpack/izzyball + name = "Katlin's Ball" + path = /obj/item/toy/fluff/tennis_poly/tri/squeak/izzy + ckeywhitelist = list("izzyinbox") + +/datum/gear/donator/backpack/steelflask + name = "Steel Flask" + path = /obj/item/reagent_containers/food/drinks/flask/steel + cost = 2 + ckeywhitelist = list("nik707") + +/datum/gear/donator/backpack/cloakce + name = "Polychromic CE Cloak" + path = /obj/item/clothing/neck/cloak/polychromic/polyce + ckeywhitelist = list("worksbythesea", "blakeryan") + loadout_flags = LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#808080", "#8CC6FF", "#FF3535") + +/datum/gear/donator/backpack/ssk + name = "Stun Sword Kit" + path = /obj/item/ssword_kit + ckeywhitelist = list("phillip458") + +/datum/gear/donator/backpack/techcoat + name = "Techomancers Labcoat" + path = /obj/item/clothing/suit/toggle/labcoat/mad/techcoat + ckeywhitelist = list("wilchen") + +/datum/gear/donator/backpack/leechjar + name = "Jar of Leeches" + path = /obj/item/custom/leechjar + ckeywhitelist = list("sgtryder") + +/datum/gear/donator/backpack/darkarmor + name = "Dark Armor" + path = /obj/item/clothing/suit/armor/vest/darkcarapace + ckeywhitelist = list("inferno707") + +/datum/gear/donator/backpack/flagcape + name = "US Flag Cape" + path = /obj/item/clothing/neck/flagcape + ckeywhitelist = list("darnchacha") + +/datum/gear/donator/backpack/luckyjack + name = "Lucky Jackboots" + path = /obj/item/clothing/shoes/lucky + ckeywhitelist = list("spiralwithin") + +/datum/gear/donator/backpack/m41 + name = "Toy M41" + path = /obj/item/toy/gun/m41 + ckeywhitelist = list("thalverscholen") + +/datum/gear/donator/backpack/fritzplush + name = "Fritz Plushie" + path = /obj/item/toy/plush/mammal/dog/fritz + ckeywhitelist = list("analwerewolf") + +/datum/gear/donator/backpack/borgplush + name = "Robot Plush" + path = /obj/item/toy/plush/borgplushie + ckeywhitelist = list("nicholaiavenicci") + +/datum/gear/donator/backpack/cosmos + name = "cosmic space bedsheet" + path = /obj/item/bedsheet/cosmos + ckeywhitelist = list("grunnyyy") + +/datum/gear/donator/backpack/customskirt + name = "custom atmos skirt" + path = /obj/item/clothing/under/custom/customskirt + ckeywhitelist = list("thakyz") + +/datum/gear/donator/backpack/strangemask + name = "Strange Metal Mask" + path = /obj/item/clothing/mask/breath/mmask + ckeywhitelist = list("sneka") + +/datum/gear/donator/backpack/mgasmask + name = "Military Gas Mask" + path = /obj/item/clothing/mask/gas/military + ckeywhitelist = list("unclebourbon") + +/datum/gear/donator/backpack/pokerchips + name = "pokerchip set" + path = /obj/item/storage/box/pockerchips + ckeywhitelist = list("greed2323") diff --git a/modular_citadel/code/modules/client/loadout/donator/gloves.dm b/modular_citadel/code/modules/client/loadout/donator/gloves.dm new file mode 100644 index 0000000000..6d020b7068 --- /dev/null +++ b/modular_citadel/code/modules/client/loadout/donator/gloves.dm @@ -0,0 +1,12 @@ +/datum/gear/donator/gloves + slot = ITEM_SLOT_GLOVES + +/datum/gear/donator/gloves/longblackgloves + name = "Luna's Gauntlets" + path = /obj/item/clothing/gloves/longblackgloves + ckeywhitelist = list("bigmanclancy") + +/datum/gear/donator/gloves/mikugloves + name = "starlight singer gloves" + path = /obj/item/clothing/gloves/mikugloves + ckeywhitelist = list("grandvegeta") diff --git a/modular_citadel/code/modules/client/loadout/donator/hands.dm b/modular_citadel/code/modules/client/loadout/donator/hands.dm new file mode 100644 index 0000000000..c4c9ec7643 --- /dev/null +++ b/modular_citadel/code/modules/client/loadout/donator/hands.dm @@ -0,0 +1,19 @@ +/datum/gear/donator/hands + slot = ITEM_SLOT_HANDS + +/datum/gear/donator/hands/engravedzippo + name = "Engraved zippo" + path = /obj/item/lighter/gold + ckeywhitelist = list("dirtyoldharry") + +/datum/gear/donator/hands/carrotsatchel + name = "Carrot Satchel" + path = /obj/item/storage/backpack/satchel/carrot + ckeywhitelist = list("improvedname") + +/datum/gear/donator/hands/raiqbawks + name = "Miami Boombox" + cost = 2 + path = /obj/item/boombox/raiq + ckeywhitelist = list("chefferz") + diff --git a/modular_citadel/code/modules/client/loadout/donator/head.dm b/modular_citadel/code/modules/client/loadout/donator/head.dm new file mode 100644 index 0000000000..623619a3f3 --- /dev/null +++ b/modular_citadel/code/modules/client/loadout/donator/head.dm @@ -0,0 +1,42 @@ +/datum/gear/donator/head + slot = ITEM_SLOT_HEAD + +/datum/gear/donator/head/santahat + name = "Santa hat" + path = /obj/item/clothing/head/santa/fluff + ckeywhitelist = list("illotafv") + +/datum/gear/donator/head/reindeerhat + name = "Reindeer hat" + path = /obj/item/clothing/head/hardhat/reindeer/fluff + ckeywhitelist = list("illotafv") + +/datum/gear/donator/head/paperhat + name = "Paper Hat" + path = /obj/item/clothing/head/paperhat + ckeywhitelist = list("kered2") + +/datum/gear/donator/head/frenchberet + name = "French Beret" + path = /obj/item/clothing/head/frenchberet + ckeywhitelist = list("notazoltan") + +/datum/gear/donator/head/donorberet + name = "Atmos Beret" + path = /obj/item/clothing/head/blueberet + ckeywhitelist = list("foxystalin") + +/datum/gear/donator/head/donorgoggles + name = "Flight Goggles" + path = /obj/item/clothing/head/flight + ckeywhitelist = list("maxlynchy") + +/datum/gear/donator/head/mikuhair + name = "starlight singer hair" + path = /obj/item/clothing/head/mikuhair + ckeywhitelist = list("grandvegeta") + +/datum/gear/donator/head/hisakaki + name = "halo" + path = /obj/item/clothing/head/halo + ckeywhitelist = list("hisakaki") diff --git a/modular_citadel/code/modules/client/loadout/donator/mask.dm b/modular_citadel/code/modules/client/loadout/donator/mask.dm new file mode 100644 index 0000000000..8540c82e3d --- /dev/null +++ b/modular_citadel/code/modules/client/loadout/donator/mask.dm @@ -0,0 +1,27 @@ +/datum/gear/donator/mask + slot = ITEM_SLOT_MASK + +/datum/gear/donator/mask/hheart + name = "The Hollow Heart" + path = /obj/item/clothing/mask/hheart + ckeywhitelist = list("inferno707") + +/datum/gear/donator/mask/albortorosamask + name = "Alborto Rosa mask" + path = /obj/item/clothing/mask/luchador/zigfie + ckeywhitelist = list("zigfie") + +/datum/gear/donator/mask/stalkermask + name = "S.T.A.L.K.E.R. mask" + path = /obj/item/clothing/mask/gas/stalker + ckeywhitelist = list("slomka") + +/datum/gear/donator/mask/mimemask + name = "Mime Mask" + path = /obj/item/clothing/mask/gas/mime + ckeywhitelist = list("pireamaineach") + +/datum/gear/donator/mask/clownmask + name = "Clown Mask" + path = /obj/item/clothing/mask/gas/clown_hat + ckeywhitelist = list("djkouta") diff --git a/modular_citadel/code/modules/client/loadout/donator/neck.dm b/modular_citadel/code/modules/client/loadout/donator/neck.dm new file mode 100644 index 0000000000..cb5359ea08 --- /dev/null +++ b/modular_citadel/code/modules/client/loadout/donator/neck.dm @@ -0,0 +1,78 @@ +/datum/gear/donator/neck + slot = ITEM_SLOT_NECK + +/datum/gear/donator/neck/chameleon_bedsheet + name = "Chameleon Bedsheet" + path = /obj/item/bedsheet/chameleon + ckeywhitelist = list() + donator_group_id = DONATOR_GROUP_TIER_1 + +/datum/gear/donator/neck/kiaracloak + name = "Kiara's cloak" + path = /obj/item/clothing/neck/cloak/inferno + ckeywhitelist = list("inferno707") + +/datum/gear/donator/neck/kiaracollar + name = "Kiara's collar" + path = /obj/item/clothing/neck/petcollar/inferno + ckeywhitelist = list("inferno707") + +/datum/gear/donator/neck/specialscarf + name = "Special scarf" + path = /obj/item/clothing/neck/scarf/zomb + ckeywhitelist = list("zombierobin") + +/datum/gear/donator/neck/treecloak + name = "Christmas tree cloak" + path = /obj/item/clothing/neck/cloak/festive + ckeywhitelist = list("illotafv") + +/datum/gear/donator/neck/carrotcloak + name = "Carrot cloak" + path = /obj/item/clothing/neck/cloak/carrot + ckeywhitelist = list("improvedname") + +/datum/gear/donator/neck/stripedcollar + name = "Striped collar" + path = /obj/item/clothing/neck/petcollar/stripe + ckeywhitelist = list("jademanique") + +/datum/gear/donator/neck/naomicollar + name = "worn pet collar" + path = /obj/item/clothing/neck/petcollar/naomi + ckeywhitelist = list("technicalmagi") + +/datum/gear/donator/neck/bloodredtie + name = "Blood Red Tie" + path = /obj/item/clothing/neck/tie/bloodred + ckeywhitelist = list("kyutness") + +/datum/gear/donator/neck/cloak + name = "Green Cloak" + path = /obj/item/clothing/neck/cloak/green + ckeywhitelist = list("killer402402") + +/datum/gear/donator/neck/devilwings + name = "Strange Wings" + path = /obj/item/clothing/neck/devilwings + ckeywhitelist = list("kitsun") + +/datum/gear/donator/neck/soulneck + name = "Soul Necklace" + path = /obj/item/clothing/neck/undertale + ckeywhitelist = list("twilightic") + +/datum/gear/donator/neck/csheet + name = "NT Bedsheet" + path = /obj/item/bedsheet/captain + ckeywhitelist = list("tikibomb") + +/datum/gear/donator/neck/onionneck + name = "Onion Necklace" + path = /obj/item/clothing/neck/necklace/onion + ckeywhitelist = list("cdrcross") + +/datum/gear/donator/neck/choker + name = "NT Choker" + path = /obj/item/clothing/neck/petcollar/donorchoker + ckeywhitelist = list("trigillass") diff --git a/modular_citadel/code/modules/client/loadout/donator/shoes.dm b/modular_citadel/code/modules/client/loadout/donator/shoes.dm new file mode 100644 index 0000000000..003599572d --- /dev/null +++ b/modular_citadel/code/modules/client/loadout/donator/shoes.dm @@ -0,0 +1,12 @@ +/datum/gear/donator/shoes + slot = ITEM_SLOT_FEET + +/datum/gear/donator/shoes/pinkshoes + name = "Pink shoes" + path = /obj/item/clothing/shoes/sneakers/pink + ckeywhitelist = list("zigfie") + +/datum/gear/donator/shoes/mikuleggings + name = "starlight singer leggings" + path = /obj/item/clothing/shoes/sneakers/mikuleggings + ckeywhitelist = list("grandvegeta") diff --git a/modular_citadel/code/modules/client/loadout/donator/suit.dm b/modular_citadel/code/modules/client/loadout/donator/suit.dm new file mode 100644 index 0000000000..d0ffd6ba6c --- /dev/null +++ b/modular_citadel/code/modules/client/loadout/donator/suit.dm @@ -0,0 +1,87 @@ +/datum/gear/donator/suit + slot = ITEM_SLOT_OCLOTHING + +/datum/gear/donator/suit/redmadcoat + name = "The Mad's labcoat" + path = /obj/item/clothing/suit/toggle/labcoat/mad/red + ckeywhitelist = list("zombierobin") + +/datum/gear/donator/suit/santaoutfit + name = "Santa costume" + path = /obj/item/clothing/suit/space/santa/fluff + ckeywhitelist = list("illotafv") + +/datum/gear/donator/suit/reecesgreatcoat + name = "Reece's Great Coat" + path = /obj/item/clothing/suit/trenchcoat/green + ckeywhitelist = list("geemiesif") + +/datum/gear/donator/suit/gladiator + name = "Gladiator Armor" + path = /obj/item/clothing/under/costume/gladiator + ckeywhitelist = list("aroche") + +/datum/gear/donator/suit/puffydress + name = "Puffy Dress" + path = /obj/item/clothing/suit/puffydress + ckeywhitelist = list("stallingratt") + +/datum/gear/donator/suit/labredblack + name = "Black and Red Coat" + path = /obj/item/clothing/suit/toggle/labcoat/labredblack + ckeywhitelist = list("blakeryan", "durandalphor") + +/datum/gear/donator/suit/gothcoat + name = "Goth Coat" + path = /obj/item/clothing/suit/gothcoat + ckeywhitelist = list("norko") + +/datum/gear/donator/suit/corgisuit + name = "Corgi Suit" + path = /obj/item/clothing/suit/hooded/ian_costume + ckeywhitelist = list("cathodetherobot") + +/datum/gear/donator/suit/sharkcloth + name = "Leon's Skimpy Outfit" + path = /obj/item/clothing/under/custom/leoskimpy + ckeywhitelist = list("spectrosis") + +/datum/gear/donator/suit/mimeoveralls + name = "Mime's Overalls" + path = /obj/item/clothing/under/custom/mimeoveralls + ckeywhitelist = list("pireamaineach") + +/datum/gear/donator/suit/zuliecloak + name = "Project: Zul-E" + path = /obj/item/clothing/suit/hooded/cloak/zuliecloak + ckeywhitelist = list("asky") + +/datum/gear/donator/suit/blackredgold + name = "Black, Red, and Gold Coat" + path = /obj/item/clothing/suit/blackredgold + ckeywhitelist = list("ttbnc") + +/datum/gear/donator/suit/kimono + name = "Kimono" + path = /obj/item/clothing/suit/kimono + ckeywhitelist = list("sfox63") + +/datum/gear/donator/suit/commjacket + name = "Dusty Commisar's Cloak" + path = /obj/item/clothing/suit/commjacket + ckeywhitelist = list("sadisticbatter") + +/datum/gear/donator/suit/mikujacket + name = "starlight singer jacket" + path = /obj/item/clothing/suit/mikujacket + ckeywhitelist = list("grandvegeta") + +/datum/gear/donator/suit/exo + name = "exo frame" + path = /obj/item/clothing/suit/custom/exo + ckeywhitelist = list("jesterz7") + +/datum/gear/donator/suit/spacehoodie + name = "Space Hoodie" + path = /obj/item/clothing/suit/spacehoodie + ckeywhitelist = list("bidlink2") diff --git a/modular_citadel/code/modules/client/loadout/donator/uniform.dm b/modular_citadel/code/modules/client/loadout/donator/uniform.dm new file mode 100644 index 0000000000..11f6ee517e --- /dev/null +++ b/modular_citadel/code/modules/client/loadout/donator/uniform.dm @@ -0,0 +1,68 @@ +/datum/gear/donator/uniform + slot = ITEM_SLOT_ICLOTHING + +/datum/gear/donator/uniform/geisha + name = "Geisha suit" + path = /obj/item/clothing/under/costume/geisha + ckeywhitelist = list("atiefling") + +/datum/gear/donator/uniform/mankini + name = "Mankini" + path = /obj/item/clothing/under/misc/stripper/mankini + ckeywhitelist = list("zigfie") + +/datum/gear/donator/uniform/performersoutfit + name = "Bluish performer's outfit" + path = /obj/item/clothing/under/costume/singer/yellow/custom + ckeywhitelist = list("killer402402") + +/datum/gear/donator/uniform/vermillion + name = "Vermillion clothing" + path = /obj/item/clothing/suit/vermillion + ckeywhitelist = list("fractious") + +/datum/gear/donator/uniform/naomisweater + name = "worn black sweater" + path = /obj/item/clothing/under/sweater/black/naomi + ckeywhitelist = list("technicalmagi") + +/datum/gear/donator/uniform/Divine_robes + name = "Divine robes" + path = /obj/item/clothing/under/custom/lunasune + ckeywhitelist = list("invader4352") + +/datum/gear/donator/uniform/mw2_russian_para + name = "Russian Paratrooper Jumper" + path = /obj/item/clothing/under/custom/mw2_russian_para + ckeywhitelist = list("investigator77") + +/datum/gear/donator/uniform/trendy_fit + name = "Trendy Fit" + path = /obj/item/clothing/under/custom/trendy_fit + ckeywhitelist = list("midgetdragon") + +/datum/gear/donator/uniform/singery + name = "Yellow Performer Outfit" + path = /obj/item/clothing/under/costume/singer/yellow + ckeywhitelist = list("maxlynchy") + +/datum/gear/donator/uniform/mikubikini + name = "starlight singer bikini" + path = /obj/item/clothing/under/custom/mikubikini + ckeywhitelist = list("grandvegeta") + +/datum/gear/donator/uniform/vest + name = "vest and shirt" + path = /obj/item/clothing/under/custom/vest + ckeywhitelist = list("maylowfox") + +/datum/gear/donator/uniform/smaiden + name = "shrine maiden outfit" + path = /obj/item/clothing/under/smaiden + ckeywhitelist = list("ultimarifox") + +/datum/gear/donator/uniform/psychedelicjumpsuit + name = "psychedelic jumpsuit" + path = /obj/item/clothing/under/misc/psyche + ckeywhitelist = list("commandnotrecognized") + diff --git a/modular_citadel/code/modules/client/loadout/glasses.dm b/modular_citadel/code/modules/client/loadout/glasses.dm index f3b07657f4..0ca9aa0e05 100644 --- a/modular_citadel/code/modules/client/loadout/glasses.dm +++ b/modular_citadel/code/modules/client/loadout/glasses.dm @@ -1,6 +1,6 @@ /datum/gear/glasses category = LOADOUT_CATEGORY_GLASSES - slot = SLOT_GLASSES + slot = ITEM_SLOT_EYES /datum/gear/glasses/blindfold name = "Blindfold" @@ -45,3 +45,7 @@ /datum/gear/glasses/prescription name = "Prescription glasses" path = /obj/item/clothing/glasses/regular + +/datum/gear/glasses/modern + name = "Modern prescription glasses" + path = /obj/item/clothing/glasses/regular/modern diff --git a/modular_citadel/code/modules/client/loadout/gloves.dm b/modular_citadel/code/modules/client/loadout/gloves.dm index 09694ddec7..960be356e2 100644 --- a/modular_citadel/code/modules/client/loadout/gloves.dm +++ b/modular_citadel/code/modules/client/loadout/gloves.dm @@ -1,6 +1,6 @@ /datum/gear/gloves category = LOADOUT_CATEGORY_GLOVES - slot = SLOT_GLOVES + slot = ITEM_SLOT_GLOVES /datum/gear/gloves/fingerless name = "Fingerless Gloves" @@ -9,11 +9,17 @@ /datum/gear/gloves/evening name = "Evening gloves" path = /obj/item/clothing/gloves/evening - + /datum/gear/gloves/midnight name = "Midnight gloves" path = /obj/item/clothing/gloves/evening/black +/datum/gear/gloves/maidpoly // WHAT DO YOU EVEN CALL THEM + name = "Polychromic maid gloves" + path = /obj/item/clothing/gloves/polymaid + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#333333", "#FFFFFF") + /datum/gear/gloves/goldring name = "A gold ring" path = /obj/item/clothing/gloves/ring diff --git a/modular_citadel/code/modules/client/loadout/hands.dm b/modular_citadel/code/modules/client/loadout/hands.dm index eb496ed78c..5dbe8b33dd 100644 --- a/modular_citadel/code/modules/client/loadout/hands.dm +++ b/modular_citadel/code/modules/client/loadout/hands.dm @@ -1,6 +1,6 @@ /datum/gear/hands category = LOADOUT_CATEGORY_HANDS - slot = SLOT_HANDS + slot = ITEM_SLOT_HANDS /datum/gear/hands/cane name = "Cane" diff --git a/modular_citadel/code/modules/client/loadout/head.dm b/modular_citadel/code/modules/client/loadout/head.dm index 6d6c803ef1..58dd6e9fc3 100644 --- a/modular_citadel/code/modules/client/loadout/head.dm +++ b/modular_citadel/code/modules/client/loadout/head.dm @@ -1,7 +1,7 @@ /datum/gear/head category = LOADOUT_CATEGORY_HEAD subcategory = LOADOUT_SUBCATEGORY_HEAD_GENERAL - slot = SLOT_HEAD + slot = ITEM_SLOT_HEAD /datum/gear/head/baseball name = "Ballcap" @@ -58,6 +58,12 @@ name = "Maid headband" path= /obj/item/clothing/head/maid +/datum/gear/head/maidband/poly + name = "Polychromic maid headband" + path= /obj/item/clothing/head/maid/polychromic + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#333333", "#FFFFFF") + /datum/gear/head/flakhelm name = "Flak Helmet" path = /obj/item/clothing/head/flakhelm @@ -156,12 +162,12 @@ /*Commenting out Until next Christmas or made automatic /datum/gear/santahatr name = "Red Santa Hat" - category = SLOT_HEAD + category = ITEM_SLOT_HEAD path = /obj/item/clothing/head/christmashat /datum/gear/santahatg name = "Green Santa Hat" - category = SLOT_HEAD + category = ITEM_SLOT_HEAD path = /obj/item/clothing/head/christmashatg */ @@ -189,6 +195,12 @@ restricted_desc = "Security" restricted_roles = list("Warden","Detective","Security Officer","Head of Security") +/datum/gear/head/cowboyhat/polychromic + name = "Cowboy Hat, Polychromic" + path = /obj/item/clothing/head/cowboyhat/polychromic + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#5F5F5F", "#DDDDDD") + /datum/gear/head/wkepi name = "white kepi" path = /obj/item/clothing/head/kepi diff --git a/modular_citadel/code/modules/client/loadout/mask.dm b/modular_citadel/code/modules/client/loadout/mask.dm index 576b29cddc..f1cf2a5d9f 100644 --- a/modular_citadel/code/modules/client/loadout/mask.dm +++ b/modular_citadel/code/modules/client/loadout/mask.dm @@ -1,6 +1,6 @@ /datum/gear/mask category = LOADOUT_CATEGORY_MASK - slot = SLOT_WEAR_MASK + slot = ITEM_SLOT_MASK /datum/gear/mask/balaclava name = "Balaclava" @@ -15,6 +15,16 @@ path = /obj/item/clothing/mask/joy cost = 3 +/datum/gear/mask/kitsune + name = "White Kitsune Mask" + path = /obj/item/clothing/mask/kitsunewhi + cost = 2 + +/datum/gear/mask/black_kitsune + name = "Black Kitsune Mask" + path = /obj/item/clothing/mask/kitsuneblk + cost = 2 + /datum/gear/mask/gas name = "Gas Mask" path = /obj/item/clothing/mask/gas @@ -30,4 +40,8 @@ name = "Paper mask" path = /obj/item/clothing/mask/paper cost = 2 - + +/datum/gear/mask/polychromic_clown + name = "polychromic clown wig and mask" + path = /obj/item/clothing/mask/gas/clown_hat_polychromic + restricted_roles = list("Clown") diff --git a/modular_citadel/code/modules/client/loadout/neck.dm b/modular_citadel/code/modules/client/loadout/neck.dm index 128285628a..64d1fcdc1f 100644 --- a/modular_citadel/code/modules/client/loadout/neck.dm +++ b/modular_citadel/code/modules/client/loadout/neck.dm @@ -1,7 +1,7 @@ /datum/gear/neck category = LOADOUT_CATEGORY_NECK subcategory = LOADOUT_SUBCATEGORY_NECK_GENERAL - slot = SLOT_NECK + slot = ITEM_SLOT_NECK /datum/gear/neck/bluetie name = "Blue tie" @@ -98,7 +98,7 @@ /datum/gear/neck/altpolycloak name = "Alternate Cloak" path = /obj/item/clothing/neck/cloak/alt/polychromic - loadout_flags = LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#FFFFFF", "#676767", "#4C4C4C") /datum/gear/neck/cancloak @@ -106,3 +106,9 @@ path = /obj/item/clothing/neck/cloak/cancloak/polychromic loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#585858", "#373737", "#BEBEBE") + +/datum/gear/neck/maid + name = "Polychromatic Maid Collar" + path = /obj/item/clothing/neck/maid + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#333333", "#FFFFFF") diff --git a/modular_citadel/code/modules/client/loadout/shoes.dm b/modular_citadel/code/modules/client/loadout/shoes.dm index e2b3916ae0..394c957f36 100644 --- a/modular_citadel/code/modules/client/loadout/shoes.dm +++ b/modular_citadel/code/modules/client/loadout/shoes.dm @@ -1,6 +1,6 @@ /datum/gear/shoes category = LOADOUT_CATEGORY_SHOES - slot = SLOT_SHOES + slot = ITEM_SLOT_FEET /datum/gear/shoes/laceup name = "Laceup shoes" diff --git a/modular_citadel/code/modules/client/loadout/suit.dm b/modular_citadel/code/modules/client/loadout/suit.dm index 108bcafc19..2685812232 100644 --- a/modular_citadel/code/modules/client/loadout/suit.dm +++ b/modular_citadel/code/modules/client/loadout/suit.dm @@ -1,7 +1,7 @@ /datum/gear/suit category = LOADOUT_CATEGORY_SUIT subcategory = LOADOUT_SUBCATEGORY_SUIT_GENERAL - slot = SLOT_WEAR_SUIT + slot = ITEM_SLOT_OCLOTHING /datum/gear/suit/poncho name = "Poncho" @@ -18,7 +18,6 @@ /datum/gear/suit/redhood name = "Red cloak" path = /obj/item/clothing/suit/hooded/cloak/david - cost = 3 /datum/gear/suit/jacketbomber name = "Bomber jacket" @@ -27,22 +26,22 @@ /datum/gear/suit/jacketflannelblack // all of these are reskins of bomber jackets but with the vibe to make you look like a true lumberjack name = "Black flannel jacket" - path = /obj/item/clothing/suit/jacket/flannel + path = /obj/item/clothing/suit/toggle/jacket/flannel subcategory = LOADOUT_SUBCATEGORY_SUIT_JACKETS /datum/gear/suit/jacketflannelred name = "Red flannel jacket" - path = /obj/item/clothing/suit/jacket/flannel/red + path = /obj/item/clothing/suit/toggle/jacket/flannel/red subcategory = LOADOUT_SUBCATEGORY_SUIT_JACKETS /datum/gear/suit/jacketflannelaqua name = "Aqua flannel jacket" - path = /obj/item/clothing/suit/jacket/flannel/aqua + path = /obj/item/clothing/suit/toggle/jacket/flannel/aqua subcategory = LOADOUT_SUBCATEGORY_SUIT_JACKETS /datum/gear/suit/jacketflannelbrown name = "Brown flannel jacket" - path = /obj/item/clothing/suit/jacket/flannel/brown + path = /obj/item/clothing/suit/toggle/jacket/flannel/brown subcategory = LOADOUT_SUBCATEGORY_SUIT_JACKETS /datum/gear/suit/jacketleather @@ -97,17 +96,77 @@ name = "Brass winter coat" path = /obj/item/clothing/suit/hooded/wintercoat/ratvar/fake +/datum/gear/suit/whitehoodie + name = "Soft hoodie" + path = /obj/item/clothing/suit/toggle/jacket/whitehoodie + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION + subcategory = LOADOUT_SUBCATEGORY_SUIT_JACKETS + +/datum/gear/suit/jacketbluehoodie + name = "Blue hoodie" + path = /obj/item/clothing/suit/jacket/bluehoodie + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION + subcategory = LOADOUT_SUBCATEGORY_SUIT_JACKETS +/datum/gear/suit/jacketpurplehoodie + name = "Purple hoodie" + path = /obj/item/clothing/suit/jacket/purplehoodie + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION + subcategory = LOADOUT_SUBCATEGORY_SUIT_JACKETS + +/datum/gear/suit/jacketheartcoat + name = "Heart coat" + path = /obj/item/clothing/suit/jacket/heartcoat + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION + subcategory = LOADOUT_SUBCATEGORY_SUIT_JACKETS + +/datum/gear/suit/jacketgothiccoat + name = "Long black coat with cuffs" + path = /obj/item/clothing/suit/jacket/gothiccoat + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION + subcategory = LOADOUT_SUBCATEGORY_SUIT_JACKETS + +/datum/gear/suit/jacketgothshirt + name = "Black shirt with cuffs" + path = /obj/item/clothing/suit/jacket/gothicshirt + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION + subcategory = LOADOUT_SUBCATEGORY_SUIT_GENERAL + +/datum/gear/suit/jacketgothshirtcross + name = "Black shirt with cross" + path = /obj/item/clothing/suit/jacket/gothicshirtcross + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION + subcategory = LOADOUT_SUBCATEGORY_SUIT_GENERAL + +/datum/gear/suit/gentlecoat + name = "Grey coat" + path = /obj/item/clothing/suit/jacket/gentlecoat + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION + subcategory = LOADOUT_SUBCATEGORY_SUIT_COATS + +/datum/gear/suit/greenjacket + name = "Green outdoorsman jacket" + path = /obj/item/clothing/suit/toggle/jacket/greenjacket + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION + subcategory = LOADOUT_SUBCATEGORY_SUIT_JACKETS + +/datum/gear/suit/fancytrench + name = "Grey trenchcoat" + path = /obj/item/clothing/suit/toggle/jacket/fancytrench + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION + subcategory = LOADOUT_SUBCATEGORY_SUIT_COATS + + /datum/gear/suit/coat/polycoat name = "Polychromic winter coat" path = /obj/item/clothing/suit/hooded/wintercoat/polychromic - cost = 4 //too many people with neon green coats is hard on the eyes + cost = 2 //too many people with neon green coats is hard on the eyes // it's probably fine now loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#6A6964", "#C4B8A6", "#0000FF") /datum/gear/suit/coat/wbreakpoly name = "Polychromic windbreaker" path = /obj/item/clothing/suit/toggle/wbreakpoly/polychromic - cost = 4 + cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#464F65", "#916035", "#474747") diff --git a/modular_citadel/code/modules/client/loadout/uniform.dm b/modular_citadel/code/modules/client/loadout/uniform.dm index 86fcc867a3..4ff90fb7fe 100644 --- a/modular_citadel/code/modules/client/loadout/uniform.dm +++ b/modular_citadel/code/modules/client/loadout/uniform.dm @@ -1,7 +1,7 @@ /datum/gear/uniform category = LOADOUT_CATEGORY_UNIFORM subcategory = LOADOUT_SUBCATEGORY_UNIFORM_GENERAL - slot = SLOT_W_UNIFORM + slot = ITEM_SLOT_ICLOTHING /datum/gear/uniform/suit name = "Black suit" @@ -52,7 +52,7 @@ name = "Polychromic maid costume" path = /obj/item/clothing/under/rank/civilian/janitor/maid/polychromic loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC - loadout_initial_colors = list("#FFFFFF", "#000000") + loadout_initial_colors = list("#333333", "#FFFFFF") /datum/gear/uniform/mailmanuniform name = "Mailman's jumpsuit" @@ -172,11 +172,18 @@ /datum/gear/uniform/pants/polypants name = "Polychromic Pants" - path = /obj/item/clothing/under/pants/polypants/polychromic + path = /obj/item/clothing/under/pants/polypants cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#75634F", "#3D3D3D", "#575757") +/datum/gear/uniform/pants/workout + name = "Polychromatic Workout Shorts" + path = /obj/item/clothing/under/shorts/polychromic/polyworkout + cost = 2 + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#323232", "#FFFFFF") + /datum/gear/uniform/pants/track name = "Track Pants" path = /obj/item/clothing/under/pants/track @@ -273,36 +280,34 @@ /datum/gear/uniform/suit/poly name = "Polychromic Button-up Shirt" path = /obj/item/clothing/under/misc/poly_shirt - cost = 3 + cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#FFFFFF", "#353535", "#353535") /datum/gear/uniform/skirt/poly/pleated name = "Polychromic Pleated Sweaterskirt" path = /obj/item/clothing/under/dress/skirt/polychromic/pleated - cost = 3 + cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#8CC6FF", "#808080", "#FF3535") /datum/gear/uniform/polykilt name = "Polychromic Kilt" path = /obj/item/clothing/under/costume/kilt/polychromic - cost = 3 + cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#FFFFFF", "#F08080") /datum/gear/uniform/shorts/poly name = "Polychromic Shorts" path = /obj/item/clothing/under/misc/polyshorts - cost = 3 + cost = 2 loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#353535", "#808080", "#808080") /datum/gear/uniform/shorts/poly/athletic name = "Polychromic Athletic Shorts" path = /obj/item/clothing/under/shorts/polychromic - cost = 2 - loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#FFFFFF", "#F08080") /datum/gear/uniform/hopcasual @@ -636,27 +641,27 @@ /*Commenting out Until next Christmas or made automatic /datum/gear/uniform/christmasmaler name = "Red Masculine Christmas Suit" - category = SLOT_W_UNIFORM + category = ITEM_SLOT_ICLOTHING path = /obj/item/clothing/under/costume/christmas /datum/gear/uniform/christmasmaleg name = "Green Masculine Christmas Suit" - category = SLOT_W_UNIFORM + category = ITEM_SLOT_ICLOTHING path = /obj/item/clothing/under/costume/christmas/green /datum/gear/uniform/christmasfemaler name = "Red Feminine Christmas Suit" - category = SLOT_W_UNIFORM + category = ITEM_SLOT_ICLOTHING path = /obj/item/clothing/under/costume/christmas/croptop /datum/gear/uniform/christmasfemaleg name = "Green Feminine Christmas Suit" - category = SLOT_W_UNIFORM + category = ITEM_SLOT_ICLOTHING path = /obj/item/clothing/under/costume/christmas/croptop/green /datum/gear/uniform/pinkstripper name = "Pink stripper outfit" - category = SLOT_W_UNIFORM + category = ITEM_SLOT_ICLOTHING path = /obj/item/clothing/under/misc/stripper cost = 3 */ @@ -739,3 +744,9 @@ path = /obj/item/clothing/under/rank/cargo/tech/long subcategory = LOADOUT_SUBCATEGORY_UNIFORM_JOBS restricted_roles = list("Cargo Technician") + +/datum/gear/uniform/clown_polychromic + name = "polychromic clown suit" + path = /obj/item/clothing/under/rank/civilian/polychromic_clown + subcategory = LOADOUT_SUBCATEGORY_UNIFORM_JOBS + restricted_roles = list("Clown") diff --git a/modular_citadel/code/modules/client/loadout/unlockable.dm b/modular_citadel/code/modules/client/loadout/unlockable.dm index 67e0c06d8c..9db05a66e9 100644 --- a/modular_citadel/code/modules/client/loadout/unlockable.dm +++ b/modular_citadel/code/modules/client/loadout/unlockable.dm @@ -1,6 +1,6 @@ /datum/gear/unlockable category = LOADOUT_CATEGORY_UNLOCKABLE - slot = SLOT_NECK + slot = ITEM_SLOT_NECK var/progress_required //what does our progress need to be to unlock it var/progress_key //what is the key used to retrieve existing progress for this unlockable diff --git a/modular_citadel/code/modules/client/preferences_savefile.dm b/modular_citadel/code/modules/client/preferences_savefile.dm index 102ae41921..4942a1041f 100644 --- a/modular_citadel/code/modules/client/preferences_savefile.dm +++ b/modular_citadel/code/modules/client/preferences_savefile.dm @@ -35,5 +35,4 @@ WRITE_FILE(S["feature_xeno_head"], features["xenohead"]) //flavor text WRITE_FILE(S["feature_flavor_text"], features["flavor_text"]) - WRITE_FILE(S["silicon_feature_flavor_text"], features["silicon_flavor_text"]) - + WRITE_FILE(S["feature_silicon_flavor_text"], features["silicon_flavor_text"]) diff --git a/modular_citadel/code/modules/clothing/neck.dm b/modular_citadel/code/modules/clothing/neck.dm index f57e2ae530..9507e65e0e 100644 --- a/modular_citadel/code/modules/clothing/neck.dm +++ b/modular_citadel/code/modules/clothing/neck.dm @@ -18,6 +18,6 @@ playsound(owner, 'sound/misc/souldeath.ogg', 100, FALSE) -/obj/item/clothing/neck/undertale/Initialize() +/obj/item/clothing/neck/undertale/Initialize(mapload) ..() AddComponent(/datum/component/souldeath/neck) diff --git a/modular_citadel/code/modules/clothing/trek.dm b/modular_citadel/code/modules/clothing/trek.dm index cf422053c7..7272ea6c1a 100644 --- a/modular_citadel/code/modules/clothing/trek.dm +++ b/modular_citadel/code/modules/clothing/trek.dm @@ -27,7 +27,7 @@ /obj/item/reagent_containers/glass/bottle/vial,/obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill,/obj/item/storage/pill_bottle, /obj/item/restraints/handcuffs,/obj/item/hypospray ) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/suit/storage/trek/ds9/admiral // Only for adminuz name = "Admiral Overcoat" @@ -35,7 +35,7 @@ icon_state = "trek_ds9_coat_adm" item_state = "trek_ds9_coat_adm" permeability_coefficient = 0.01 - armor = list("melee" = 50, "bullet" = 50, "laser" = 50,"energy" = 50, "bomb" = 50, "bio" = 50, "rad" = 50, "fire" = 50, "acid" = 50) + armor = list(MELEE = 50, BULLET = 50, LASER = 50,ENERGY = 50, BOMB = 50, BIO = 50, RAD = 50, FIRE = 50, ACID = 50) //MODERN ish Joan sqrl sprites. I think @@ -66,7 +66,7 @@ /obj/item/reagent_containers/glass/beaker, /obj/item/storage/pill_bottle, /obj/item/taperecorder) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) var/unbuttoned = FALSE /obj/item/clothing/suit/storage/fluff/fedcoat/verb/toggle() @@ -122,7 +122,7 @@ /obj/item/reagent_containers/glass/bottle/vial,/obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill,/obj/item/storage/pill_bottle, /obj/item/restraints/handcuffs,/obj/item/hypospray ) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) //Variants /obj/item/clothing/suit/storage/fluff/modernfedcoat/medsci @@ -139,7 +139,7 @@ /obj/item/clothing/head/caphat/formal/fedcover name = "Federation Officer's Cap" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) desc = "An officer's cap that demands discipline from the one who wears it." icon = 'modular_citadel/icons/obj/clothing/trek_item_icon.dmi' icon_state = "fedcapofficer" diff --git a/modular_citadel/code/modules/custom_loadout/custom_items.dm b/modular_citadel/code/modules/custom_loadout/custom_items.dm index 14114c513b..906da43448 100644 --- a/modular_citadel/code/modules/custom_loadout/custom_items.dm +++ b/modular_citadel/code/modules/custom_loadout/custom_items.dm @@ -66,7 +66,7 @@ blood_overlay_type = "armor" dog_fashion = /datum/dog_fashion/back mutantrace_variation = NONE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/lighter/gold @@ -77,7 +77,7 @@ item_state = "gold_zippo" w_class = WEIGHT_CLASS_TINY flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT + slot_flags = ITEM_SLOT_BELT heat = 1500 resistance_flags = FIRE_PROOF light_color = LIGHT_COLOR_FIRE @@ -113,7 +113,6 @@ desc = "While a normal carrot would be good for your eyes, this one seems a bit more for hugging then eating." icon = 'icons/obj/hydroponics/harvest.dmi' icon_state = "carrot" - item_state = "carrot" w_class = WEIGHT_CLASS_SMALL attack_verb = list("slapped") resistance_flags = FLAMMABLE @@ -137,7 +136,7 @@ item_state = "satchel_carrot" mob_overlay_icon = 'icons/mob/clothing/custom_w.dmi' -/obj/item/storage/backpack/satchel/carrot/Initialize() +/obj/item/storage/backpack/satchel/carrot/Initialize(mapload) . = ..() AddComponent(/datum/component/squeak, list('sound/items/toysqueak1.ogg'=1), 50) @@ -146,7 +145,6 @@ desc = "A festive plush that squeeks when you squeeze it!" icon = 'icons/obj/custom.dmi' icon_state = "pine_c" - item_state = "pine_c" w_class = WEIGHT_CLASS_SMALL attack_verb = list("slapped") resistance_flags = FLAMMABLE @@ -404,7 +402,7 @@ mob_overlay_icon = 'icons/mob/clothing/custom_w.dmi' hoodtype = /obj/item/clothing/head/hooded/cloakhood/zuliecloak body_parts_covered = CHEST|GROIN|ARMS - slot_flags = SLOT_WEAR_SUIT | ITEM_SLOT_NECK //it's a cloak. it's cosmetic. so why the hell not? what could possibly go wrong? + slot_flags = ITEM_SLOT_OCLOTHING | ITEM_SLOT_NECK //it's a cloak. it's cosmetic. so why the hell not? what could possibly go wrong? mutantrace_variation = NONE /obj/item/clothing/head/hooded/cloakhood/zuliecloak @@ -547,10 +545,12 @@ /obj/item/toy/plush/mammal/dog/fritz icon = 'icons/obj/custom.dmi' icon_state = "fritz" - item_state = "fritz" attack_verb = list("barked", "boofed", "shotgun'd") obj_flags = UNIQUE_RENAME - unique_reskin = list("Goodboye" = "fritz", "Badboye" = "fritz_bad") + unique_reskin = list( + "Goodboye" = list("icon_state" = "fritz"), + "Badboye" = list("icon_state" = "fritz_bad") + ) mutantrace_variation = NONE /obj/item/clothing/neck/cloak/polychromic/polyce @@ -618,3 +618,58 @@ icon = 'icons/obj/custom.dmi' mob_overlay_icon = 'icons/mob/clothing/custom_w.dmi' mutantrace_variation = NONE + +/obj/item/clothing/suit/spacehoodie + name = "space hoodie" + desc = "You are not sure why this hoodie exists... but it does and it is comfortable." + icon_state = "starhoodie" + item_state = "starhoodie" + icon = 'icons/obj/custom.dmi' + mob_overlay_icon = 'icons/mob/clothing/custom_w.dmi' + mutantrace_variation = NONE + +/obj/item/coin/red + name = "red pokerchip" + desc = "A red pokerchip." + icon_state = "c_red" + item_state = "c_red" + icon = 'icons/obj/custom.dmi' + +/obj/item/coin/blue + name = "blue pokerchip" + desc = "A blue pokerchip." + icon_state = "c_nlue" + item_state = "c_blue" + icon = 'icons/obj/custom.dmi' + +/obj/item/coin/green + name = "green pokerchip" + desc = "A green pokerchip." + icon_state = "c_green" + item_state = "c_green" + icon = 'icons/obj/custom.dmi' + +/obj/item/coin/black + name = "black pokerchip" + desc = "A black pokerchip." + icon_state = "c_black" + item_state = "c_black" + icon = 'icons/obj/custom.dmi' + +/obj/item/storage/box/pockerchips + name = "tray of pocker chips" + desc = "A tray of green, red, blue, and black pocker chips." + icon_state = "c_holder" + icon = 'icons/obj/custom.dmi' + illustration=null + +/obj/item/storage/box/pokerchips/PopulateContents() + for(var/i in 1 to 5) + new /obj/item/coin/red(src) + for(var/i in 1 to 10) + new /obj/item/coin/blue(src) + for(var/i in 1 to 15) + new /obj/item/coin/black(src) + for(var/i in 1 to 20) + new /obj/item/coin/green(src) + diff --git a/modular_citadel/code/modules/custom_loadout/load_to_mob.dm b/modular_citadel/code/modules/custom_loadout/load_to_mob.dm index 79f17afc74..1d28c7320c 100644 --- a/modular_citadel/code/modules/custom_loadout/load_to_mob.dm +++ b/modular_citadel/code/modules/custom_loadout/load_to_mob.dm @@ -52,7 +52,7 @@ loaded_atom.forceMove(T) continue var/obj/item/loaded = loaded_atom - var/obj/item/storage/S = H.get_item_by_slot(SLOT_BACK) + var/obj/item/storage/S = H.get_item_by_slot(ITEM_SLOT_BACK) if(istype(S)) SEND_SIGNAL(S, COMSIG_TRY_STORAGE_INSERT,loaded, TRUE, H) //Force it into their backpack continue diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/JTGSZwork.dm b/modular_citadel/code/modules/eventmaps/Spookystation/JTGSZwork.dm new file mode 100644 index 0000000000..a2ccc319d0 --- /dev/null +++ b/modular_citadel/code/modules/eventmaps/Spookystation/JTGSZwork.dm @@ -0,0 +1,1134 @@ +/* +⢀⡴⠑⡄⠀⠀⠀⠀⠀⠀⠀⣀⣀⣤⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠸⡇⠀⠿⡀⠀⠀⠀⣀⡴⢿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠑⢄⣠⠾⠁⣀⣄⡈⠙⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⢀⡀⠁⠀⠀⠈⠙⠛⠂⠈⣿⣿⣿⣿⣿⠿⡿⢿⣆⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⢀⡾⣁⣀⠀⠴⠂⠙⣗⡀⠀⢻⣿⣿⠭⢤⣴⣦⣤⣹⠀⠀⠀⢀⢴⣶⣆ +⠀⠀⢀⣾⣿⣿⣿⣷⣮⣽⣾⣿⣥⣴⣿⣿⡿⢂⠔⢚⡿⢿⣿⣦⣴⣾⠁⠸⣼⡿ +⠀⢀⡞⠁⠙⠻⠿⠟⠉⠀⠛⢹⣿⣿⣿⣿⣿⣌⢤⣼⣿⣾⣿⡟⠉⠀⠀⠀⠀⠀ +⠀⣾⣷⣶⠇⠀⠀⣤⣄⣀⡀⠈⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀ WARNING: THE SHITCODE BELOW HAS BEEN HASTILY +⠀⠉⠈⠉⠀⠀⢦⡈⢻⣿⣿⣿⣶⣶⣶⣶⣤⣽⡹⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀ COPY AND PASTED, PORTED FROM AWKWARD PLACES, AND PROBABLY MADE WORSE. +⠀⠀⠀⠀⠀⠀⠀⠉⠲⣽⡻⢿⣿⣿⣿⣿⣿⣿⣷⣜⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣷⣶⣮⣭⣽⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⣀⣀⣈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀ WELCOME TO JT's TG-CODE HALLOWEEN BALL CODEFILE. +⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀ ALL OF IT WILL HOPEFULLY BE BELOW. +⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠻⠿⠿⠿⠿⠛⠉ +*/ +//Also Shrek will crash your dmlang server repeatedly if you edit him. +//JT is weird, considering my handle is a acronym. +//Considering I can't grab defines from everywhere, I hope you enjoy strings and numbers plebs. +//Update - Moved to modular citadel so we are after everything has loaded...probably we gucci - jtgsz + +/* + AREAS + */ +//This is generally how you handle planet areas, gen 1 large outside area is good for outside effects. +//PS: Mountain has a soundloop, outside has a soundloop, inside has a soundloop, mountaininside is silent +//This is for the rain weather my man. +/area/eventmap + name = "Dont use this" //Its the parent to any dunces out there. + has_gravity = STANDARD_GRAVITY //We have gravity + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/areas.dmi' //It unsets the icon. don't make a err icon. + requires_power = 0 // We don't need power anywhere. + flags_1 = NONE + dynamic_lighting = DYNAMIC_LIGHTING_FORCED + +/area/eventmap/outside //We are outside + name = "Outside" + icon_state = "outside" + outdoors = 0 //I set outdoors to false. So areas can be edited. + +/area/eventmap/inside //We are inside, all things are pretty normal. + name = "Inside" + icon_state = "inside" + +/area/eventmap/mountain //Mostly so I can see the area lines of the mountain area in the minimap. + name = "Mountain" + icon_state = "mountain" + var/mountain = 1 + +/area/eventmap/mountaininside + name = "Silent Mountain Inside" + icon_state = "mountain_inside" + outdoors = 0 + +/* + OUTSIDE WALLS I WANT NOT NEED + */ +//These exist mostly to limit the amount of space we use organically really. +//Decided to just use the denserock within the regular code. + +/turf/closed/indestructible/spookytime/matrixblocker //Two times the reference power. + name = "matrix" + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + icon_state = "matrix" + desc = "You suddenly realize the truth - there is no spoon.
    Digital simulation ends here ONCE AGAIN.
    " + +/* + OUTSIDE TURFS WITH NO GEN JUS MIDNIGHT LIGHT BABY + */ + +//In a ideal world, we would have split the turfs onto a single parent. +//Then we would tree from INSIDE and OUTSIDE, with outside having the lighting set, for the day/night subsystem to change. +//Outside would also have the planetary atmos and config on it. +//Inside would be a case to case basis depending on if you want it to scrub or not.. and not have the lighting. +//Along with what needs to be constructed on etc. +//This is not a ideal world so enjoy the overload. + +//Parent of all our outside turfs. Both the inside and outside should be on a parent like this. +/turf/open/floor/spooktime //But for now, we just handle what is outside, for light control etc. + name = "You fucked up pal" + desc = "Don't use this turf its a parent and just a holder." + planetary_atmos = 1 //REVERT TO INITIAL AIR GASMIX OVER TIME WITH LINDA. AKA SUPERSCRUBBER + light_range = 3 //MIDNIGHT BLUE + light_power = 0.15 //NOT PITCH BLACK, JUST REALLY DARK + light_color = "#00111a" //The light can technically cycle on a timer worldwide, but no daynight cycle. + baseturfs = /turf/open/floor/plating/spookbase/dirtattachmentpoint //If we explode or die somehow, we just become grass + gender = PLURAL //THE GENDER IS PLURAL + tiled_dirt = 0 //NO TILESMOOTHING DIRT/DIRT SPAWNS OR SOME SHIT + +/turf/open/floor/spooktime/break_tile() + return +/turf/open/floor/spooktime/burn_tile() + return + +/turf/open/floor/spooktime/pry_tile(obj/item/I, mob/user, silent = FALSE) + return //No prying these tiles, you instead shovel it if avail. + +/* + Baseturf, when we call scrapeaway() after a shoveling. So people can attach tiles + */ + +//WARNING VERY IMPORTANT AND HACKJOBBISH - Basically this handles construction on everything. +/turf/open/floor/plating/spookbase/dirtattachmentpoint //Lighted variant + name = "the ground" + desc = "Looks like its been dugged out and prepped for construction" + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + icon_state = "dugdirt" + footstep = FOOTSTEP_GRASS + barefootstep = FOOTSTEP_GRASS + clawfootstep = FOOTSTEP_GRASS + heavyfootstep = FOOTSTEP_GENERIC_HEAVY + attachment_holes = TRUE + planetary_atmos = 1 + light_range = 3 //We reset this + light_power = 0.15 //The lighting will unset when people place their tiles/etc on it. + light_color = "#00111a" //It should be fine + + baseturfs = /turf/open/floor/plating/spookbase/dirtattachmentpoint //No going lower than this. + +/turf/open/floor/plating/spookbase/dirtattachmentpoint/mountain + name = "the ground" + desc = "It has been dug out and prepared for construction." + light_range = 0 + light_power = 0 + + baseturfs = /turf/open/floor/plating/spookbase/dirtattachmentpoint/mountain + +/turf/open/floor/plating/spookbase/sandattachmentpoint + name = "the sand" + desc = "Looks like its been dugged out and prepped for construction" + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + icon_state = "dugsand" + footstep = FOOTSTEP_GRASS + barefootstep = FOOTSTEP_GRASS + clawfootstep = FOOTSTEP_GRASS + heavyfootstep = FOOTSTEP_GENERIC_HEAVY + attachment_holes = TRUE + planetary_atmos = 1 + light_range = 3 + light_power = 0.15 + light_color = "#00111a" + + baseturfs = /turf/open/floor/plating/spookbase/sandattachmentpoint // The sand version. + +/* + FLOOR TILES + */ +/obj/item/stack/tile/nonspooktimegrass + name = "clumps of grass" + singular_name = "clump of grass" + desc = "This is a clump of grass." + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + icon_state = "grass_clump" + turf_type = /turf/open/floor/spooktime/nonspooktimegrass + resistance_flags = FLAMMABLE + +/obj/item/stack/tile/normalasssand + name = "piles of sand" + singular_name = "pile of sand" + desc = "This is a pile of sand" + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + icon_state = "sand_clump" + turf_type = /turf/open/floor/spooktime/beach + +/* + IMPORTANT TURFS */ + +//Grass with no flora generation on it. +/turf/open/floor/spooktime/nonspooktimegrass + name = "grass patch" + desc = "You can't tell if this is real grass... Ah, who are you kidding, it totally is real grass." + icon_state = "grass_1" //Grass of the varied variety. + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + baseturfs = /turf/open/floor/plating/spookbase/dirtattachmentpoint + footstep = FOOTSTEP_GRASS + barefootstep = FOOTSTEP_GRASS + clawfootstep = FOOTSTEP_GRASS + heavyfootstep = FOOTSTEP_GENERIC_HEAVY + var/turfverb = "dig out" + +/turf/open/floor/spooktime/nonspooktimegrass/Initialize(mapload) //Init rng icon. + . = ..() + icon_state = "grass_[rand(1,3)]" + +/turf/open/floor/spooktime/nonspooktimegrass/attackby(obj/item/C, mob/user, params) //We dig it out with a shovel. + if((C.tool_behaviour == TOOL_SHOVEL) && params) //And beneath it we reveal dirt + new /obj/item/stack/tile/nonspooktimegrass(src) + user.visible_message("[user] digs up [src].", "You [turfverb] [src].") + playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) + make_plating() + if(..()) + return + + +//Dirt patches with no lighting. +/turf/open/floor/spooktime/dirtpatch + name = "clearly dirt" + desc = "Its dirt alright" + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + icon_state = "smoothdarkdirt" + light_range = 0 //We set the lights to nothing on the CLEARLY DIRT + light_power = 0 //ayep + footstep = FOOTSTEP_SAND + barefootstep = FOOTSTEP_SAND + clawfootstep = FOOTSTEP_SAND + heavyfootstep = FOOTSTEP_GENERIC_HEAVY + baseturfs = /turf/open/floor/plating/spookbase/dirtattachmentpoint/mountain //no light variant + var/turfverb = "dig out" + +/turf/open/floor/spooktime/dirtpatch/attackby(obj/item/C, mob/user, params) //We dig it out with a shovel. + if((C.tool_behaviour == TOOL_SHOVEL) && params) //And beneath it we reveal dirt + user.visible_message("[user] digs up [src].", "You [turfverb] [src].") + playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) + make_plating() + if(..()) + return + +//Snow with no planetary atmos, so the map doesn't atmos crash. +/turf/open/floor/spooktime/snow + gender = PLURAL + name = "snow" + icon = 'icons/turf/snow.dmi' + desc = "Looks cold." + icon_state = "snow" + slowdown = 2 + light_range = 0 + light_power = 0 + bullet_sizzle = 1 + footstep = FOOTSTEP_SAND + barefootstep = FOOTSTEP_SAND + clawfootstep = FOOTSTEP_SAND + heavyfootstep = FOOTSTEP_GENERIC_HEAVY + +/turf/open/floor/spooktime/snow/try_replace_tile(obj/item/stack/tile/T, mob/user, params) + return + +/turf/open/floor/spooktime/snow/crowbar_act(mob/living/user, obj/item/I) + return + +/* + Basic Grass turf w Flora gen + */ +/turf/open/floor/spooktime/spooktimegrass + name = "the ground" + desc = "It clearly looks like grass and dirt, clearly." + icon_state = "grass_1" + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' //32x32 iconfile, sry we had different sizes. + broken_states = list("sand") + footstep = FOOTSTEP_GRASS //Finally I can have my footstep noises + barefootstep = FOOTSTEP_GRASS + clawfootstep = FOOTSTEP_GRASS + heavyfootstep = FOOTSTEP_GENERIC_HEAVY + var/turfverb = "dig out" + + + baseturfs = /turf/open/floor/plating/spookbase/dirtattachmentpoint //beneath the grass there is dirt. + + //Holders for what can occur on the turf. + var/obj/structure/flora/turfGrass = null + var/obj/structure/flora/turfTree = null + var/obj/structure/flora/turfAusflora = null + var/obj/structure/flora/turfRocks = null + var/obj/structure/flora/turfDebris = null + + +/turf/open/floor/spooktime/spooktimegrass/Initialize(mapload) //Considering adding dirtgen here too. + . = ..() + if(prob(1)) + icon_state = "smoothdarkdirt" //Sometimes we can be dirt. + else + icon_state = "grass_[rand(1,3)]" //Icon state variation for how many states of grass I got... 3 lul + //If no fences, machines (soil patches are machines), etc. try to plant grass + if(!(\ + (locate(/obj/structure) in src) || \ + (locate(/obj/machinery) in src) )) + floraGen() //And off we go riding into hell. + update_icon() + +/turf/open/floor/spooktime/spooktimegrass/attackby(obj/item/C, mob/user, params) //We dig it out with a shovel. + if((C.tool_behaviour == TOOL_SHOVEL) && params) //And beneath it we reveal dirt) + new /obj/item/stack/tile/nonspooktimegrass(src) + user.visible_message("[user] digs up [src].", "You [turfverb] [src].") + playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) + make_plating() + if(..()) + return + +/turf/open/floor/spooktime/spooktimegrass/try_replace_tile(obj/item/stack/tile/T, mob/user, params) + return //No replacing it + +/turf/open/floor/spooktime/spooktimegrass/burn_tile() + return //No burning it + +/turf/open/floor/spooktime/spooktimegrass/MakeSlippery(wet_setting, min_wet_time, wet_time_to_add, max_wet_time, permanent) + return //No slippery + +/turf/open/floor/spooktime/spooktimegrass/MakeDry() + return //No making it dry. + +/* + FLORA GEN PROCEDURE + */ + +//This is mostly for flora/doodads. I don't feel like there needs to be lake/cave and animals generation.. +//For the halloween map at least, so I used the f13 flora gen and appended to it instead of usin cellular automata. +//Soooo, its just tied to the turf initialize on init right now. +//Right now each segment generates independantly, but it wouldn't be hard to do it in a chain +//And check for what else is there before a list of objects has the option to appear. +//Or even change weighting based on the weight of other things that the turf has checked in its range. +//But at the same time, the stacked flora/rocks etc look pretty okay together honestly. +//On the other side of the coin, you could even adjust their pixel x and y for better thickets. +//Since after-all things in nature don't just occupy one spot each a lot of the time. + +//That being said you have somewhere around 50 seconds of init, and 160 seconds of pre-game time. +//To finish generation if you need to split it up by chunks and add more checks. +//Its more time than you could ever want considering how fast it finishes like this without hiccups really. +//Ironically, not very resource intensive or slow to do this much of it. + +//I have turned what used to be simple into hell. +//We can keep appending stuff here as we go, it basically just spawns it all on turf spooktimegrass on init. + +//============> Current Set value // JTGSZ Tuned Reference Value <============== +#define GRASS_SPONTANEOUS 2//2 //chance it appears on the tile on its own +#define GRASS_WEIGHT 4//4 //multiplier increase if theres some nearby +#define TREE_SPONTANEOUS 4//4 +#define TREE_WEIGHT 4//4 +#define AUSFLORA_SPONTANEOUS 2//2 +#define AUSFLORA_WEIGHT 3//3 +#define ROCKS_SPONTANEOUS 2//2 //Technically this can be moved to the desolate spawn list tied to grass. +#define ROCKS_WEIGHT 1//1 //Lower weight cause rock clusters were too common...But cool honestly. +#define DEBRIS_SPONTANEOUS 2//2 +#define DEBRIS_WEIGHT 2//2 + +//These are basically what can spawn in the lists, the number is the weight. +//The weight dictates how likely it is to spawn over other things in the lists. If you were to use pickweight. +#define LUSH_GRASS_SPAWN_LIST list(/obj/structure/flora/grass/spookytime = 4,\ + /obj/structure/flora/ausbushes/lavendergrass = 3,\ + /obj/structure/flora/ausbushes/sparsegrass = 6,\ + /obj/structure/flora/ausbushes/fullgrass = 1\ + ) + +#define TREE_SPAWN_LIST list(/obj/structure/flora/tree/spookytime = 9,\ + /obj/structure/flora/tree/spookytimexl = 2,\ + /obj/structure/flora/tree/jungle = 1,\ + /obj/structure/flora/tree/jungle/small = 1\ + ) + +#define AUSFLORA_SPAWN_LIST list(/obj/structure/flora/ausbushes = 3,\ + /obj/structure/flora/ausbushes/grassybush = 3,\ + /obj/structure/flora/ausbushes/fernybush = 1,\ + /obj/structure/flora/ausbushes/sunnybush = 1,\ + /obj/structure/flora/ausbushes/reedbush = 1,\ + /obj/structure/flora/ausbushes/palebush = 1,\ + /obj/structure/flora/ausbushes/stalkybush = 1\ + ) + +#define ROCKS_SPAWN_LIST list(/obj/structure/flora/spookyrock = 1\ + ) + +#define DEBRIS_SPAWN_LIST list(/obj/structure/flora/tree/spookybranch = 5, \ + /obj/structure/flora/tree/spookylog = 1\ + ) + +//Lists that occur when the cluster doesn't happen but probability dictates it tries. +#define DESOLATE_SPAWN_LIST list(/obj/structure/flora/grass/spookytime = 1,\ + /obj/structure/flora/ausbushes/sparsegrass = 1\ + ) + +//I just kinda made it worse... Like a lot worse. Ngl man. +/turf/open/floor/spooktime/spooktimegrass/proc/floraGen() + var/grassWeight = 0 //grassWeight holders for each individual layer + var/treeWeight = 0 + var/ausfloraWeight = 0 + var/rocksWeight = 0 + var/debrisWeight = 0 + + var/randGrass = null //The random plant picked + var/randTree = null //The random deadtree picked + var/randAusflora = null //The random Ausflora picked + var/randRocks = null //The random rock picked + var/randDebris = null //The random wood debris picked + + //spontaneously spawn the objects based on probability from the define. + //Ngl, a lot of this is going to be have to generate in certain orders later in this proc. + if(prob(GRASS_SPONTANEOUS)) //If probability THE DEFINE NUMBER + randGrass = pickweight(LUSH_GRASS_SPAWN_LIST) //randgrass is assigned a obj from the weighted list + turfGrass = new randGrass(src) //The var on the turf now has a new randgrass from the list. + + if(prob(TREE_SPONTANEOUS)) + randTree = pickweight(TREE_SPAWN_LIST) + turfTree = new randTree(src) + + if(prob(AUSFLORA_SPONTANEOUS)) + randAusflora = pickweight(AUSFLORA_SPAWN_LIST) + turfAusflora = new randAusflora(src) + + if(prob(ROCKS_SPONTANEOUS)) + randRocks = pickweight(ROCKS_SPAWN_LIST) + turfRocks = new randRocks(src) + + if(prob(DEBRIS_SPONTANEOUS)) + randDebris = pickweight(DEBRIS_SPAWN_LIST) + turfDebris = new randDebris(src) + + + //loop through neighbouring turfs, if they have grass, then increase weight, cluster prep. + for(var/turf/open/floor/spooktime/spooktimegrass/T in RANGE_TURFS(3, src)) + if(T.turfGrass) //We check what is around our turf + grassWeight += GRASS_WEIGHT //The weight is increased by grass weight per every grass we find + if(T.turfTree) + treeWeight += TREE_WEIGHT + if(T.turfAusflora) + ausfloraWeight += AUSFLORA_WEIGHT + if(T.turfRocks) + rocksWeight += ROCKS_WEIGHT + if(T.turfDebris) + debrisWeight += DEBRIS_WEIGHT + + + //Below is where we handle clusters really. + //use weight to try to spawn grass + if(prob(grassWeight)) //Basically the probability goes by the DEFINE WEIGHT the more of it is around. + //If surrounded on 5+ sides, pick from lush + if(grassWeight == (5 * GRASS_WEIGHT)) //If we are five times the define value, aka 5 detected. + randGrass = pickweight(LUSH_GRASS_SPAWN_LIST) //We weighted pick from the lush list, aka boys that can be together. + else //Else. + randGrass = pickweight(DESOLATE_SPAWN_LIST) //We weighted pick from boys that are fine being alone. + turfGrass = new randGrass(src) //And at the end we set the turfgrass to this object. + + if(prob(treeWeight)) //We can technically redirect individuals down here too, but lets just focus on clumps. + randTree = pickweight(TREE_SPAWN_LIST) + turfTree = new randTree(src) + + if(prob(ausfloraWeight)) + randAusflora = pickweight(AUSFLORA_SPAWN_LIST) + turfAusflora = new randAusflora(src) + + if(prob(rocksWeight)) + randRocks = pickweight(ROCKS_SPAWN_LIST) + turfRocks = new randRocks(src) + + if(prob(debrisWeight)) + randDebris = pickweight(DEBRIS_SPAWN_LIST) + turfDebris = new randDebris(src) + +//Make sure we delete the objects if we ever change turfs +/turf/open/floor/spooktime/spooktimegrass/ChangeTurf(flags = CHANGETURF_INHERIT_AIR) + if(turfGrass) + qdel(turfGrass) + //if(turfTree) + // qdel(turfTree) + if(turfAusflora) + qdel(turfAusflora) + if(turfRocks) + qdel(turfRocks) + if(turfDebris) + qdel(turfDebris) + . = ..() + +//Grass baseturf helper, more than likely completely unneeded since its set on the original turf too. +/obj/effect/baseturf_helper/spooktimegrass + name = "grass baseturf helper" //Basically just changes the baseturf into grass + baseturf = /turf/open/floor/spooktime/spooktimegrass //Wherever it is at. + +//A reference to this list is passed into area sound managers, and it's modified in a manner that preserves that reference in ash_storm.dm +GLOBAL_LIST_EMPTY(rain_sounds) + +// HEY!! IF THIS DOES NOT WORK CHECK LOGIN.DM !!!!! + +/* + HERE COMES THE MOTHERFUCKING RAIN + */ +/datum/weather/long_rain + name = "Long rain at midnight" + desc = "The planet sometimes rains, nothing special about it really." + + telegraph_duration = 130 + telegraph_message = "Water droplets begin falling from the sky." + telegraph_overlay = "regular_rain" //Ya my apologies for not making a new rain icon + + weather_message = "The droplets become a downpour, rain now falls all around you from the night sky." + weather_overlay = "regular_rain" //But I need to work on my mouse on the day of 10/24/2019, so lets call it here. + weather_duration_lower = 12000 //these are deciseconds. + weather_duration_upper = 15000 + + end_duration = 100 + end_message = "The downpour gradually slows until it stops." + + area_type = /area/eventmap/outside + target_trait = ZTRAIT_LONGRAIN + probability = 90 + + barometer_predictable = TRUE + + var/list/outside_longrain = list() + var/list/inside_longrain = list() + var/list/mountain_longrain = list() + // var/datum/looping_sound/active_outside_longrain/sound_ao = new(list(), FALSE, TRUE) //Outside + // var/datum/looping_sound/active_inside_longrain/sound_ai = new(list(), FALSE, TRUE) //Inside + // var/datum/looping_sound/active_mountain_longrain/sound_am = new(list(), FALSE, TRUE) //Mountain + +/datum/weather/long_rain/telegraph() //Yeah, I'm sorry but I just stole ash storm sound loops + . = ..() + var/list/eligible_areas = list() + for(var/z in impacted_z_levels) //We check the Z level + eligible_areas += SSmapping.areas_in_z["[z]"] //And append them to eligible areas list + + + for(var/i in 1 to eligible_areas.len) + var/area/place = eligible_areas[i] + if(istype(place, /area/eventmap/outside)) //If the place is this path + outside_longrain[place] = /datum/looping_sound/active_outside_longrain //Outside areas is the place + if(istype(place, /area/eventmap/inside)) + inside_longrain[place] = /datum/looping_sound/active_inside_longrain + if(istype(place, /area/eventmap/mountain)) + mountain_longrain[place] = /datum/looping_sound/active_mountain_longrain + + CHECK_TICK + + //We modify this list instead of setting it to weak/stron sounds in order to preserve things that hold a reference to it + //It's essentially a playlist for a bunch of components that chose what sound to loop based on the area a player is in + GLOB.rain_sounds += outside_longrain + return ..() + +/datum/weather/long_rain/start() + GLOB.ash_storm_sounds += mountain_longrain + GLOB.ash_storm_sounds += inside_longrain + return ..() + +/datum/weather/long_rain/end() + GLOB.ash_storm_sounds -= outside_longrain + GLOB.ash_storm_sounds -= inside_longrain + GLOB.ash_storm_sounds -= mountain_longrain + return ..() + +/datum/looping_sound/active_outside_longrain + mid_sounds = list('modular_citadel/code/modules/eventmaps/Spookystation/outsideloop1.ogg'=1, + 'modular_citadel/code/modules/eventmaps/Spookystation/outsideloop2.ogg'=1) + mid_length = 3.8 //ahahaa aaaaaaaaaa fucking shit man, but its what I got. + volume = 70 + start_sound = 'sound/ambience/acidrain_start.ogg' + start_length = 13 + end_sound = 'sound/ambience/acidrain_end.ogg' + +/datum/looping_sound/active_inside_longrain + mid_sounds = list('modular_citadel/code/modules/eventmaps/Spookystation/insideloop1.ogg'=1, + 'modular_citadel/code/modules/eventmaps/Spookystation/insideloop2.ogg'=1, + 'modular_citadel/code/modules/eventmaps/Spookystation/insideloop3.ogg'=1, + 'modular_citadel/code/modules/eventmaps/Spookystation/insideloop4.ogg'=1) + mid_length = 5.1 //AAAAAAAAAAAAAAAAAAAAAAA + volume = 60 + +/datum/looping_sound/active_mountain_longrain + mid_sounds = list('modular_citadel/code/modules/eventmaps/Spookystation/basecaveloop.ogg'=1) + mid_length = 12 //Why are we still here? Just to suffer? + volume = 60 + +/* + GRANDFATHER CLOCK + */ + +/* + 1:00 AM - overlay-2 + 2:00 AM - overlay-2 + 3:00 AM - overlay-3 + 4:00 AM - overlay-4 + 5:00 AM - overlay-4 + 6:00 AM - overlay-6 + 7:00 AM - overlay-7 + 8:00 AM - overlay-7 + 9:00 AM - overlay-9 + 10:00 AM - overlay-10 + 11:00 AM - overlay-10 + 12:00 AM - overlay-0 + */ + +/obj/machinery/grandfatherclock + name = "Grandfather Clock" + desc = "Keeps track of the time with its dials." + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/clock32x49.dmi' + icon_state = "grandfathermk4right" + density = 1 + anchored = 1 + use_power = 0 + max_integrity = 250 + var/HRimgstate = "asshouroverlay-0" + var/MMimgstate = "assminuteoverlay-0" + var/ticktock = 0 // We hold this here + var/dyndial_cycle_ticker = 0 //How many + var/playchime = 1 //Procs will reset their vars. + +/obj/machinery/grandfatherclock/Initialize(mapload) + . = ..() + update_icon() //We get it done + +/obj/machinery/grandfatherclock/process() + doodad_clock_ticker() + + +/obj/machinery/grandfatherclock/proc/doodad_clock_ticker() //We basically throttle the rest of this machine here. + + dyndial_cycle_ticker++ + + if(ticktock) //If we are true + playsound(src.loc, 'modular_citadel/code/modules/eventmaps/Spookystation/Tock.ogg', 100,0) + icon_state = "grandfathermk4right" + flick("tick", src) + ticktock = 0 //Play this noise set to false + else + playsound(src.loc, 'modular_citadel/code/modules/eventmaps/Spookystation/Tick.ogg', 100,0) + flick("tock", src) + icon_state = "grandfathermk4left" + ticktock = 1 //If we are not true, play this noise set to true + + if(dyndial_cycle_ticker >= 20) //Handles the dynamic dial + dyndial_cycle() + dyndial_cycle_ticker = 0 + +/obj/machinery/grandfatherclock/proc/dyndial_cycle() + var/ass_time = STATION_TIME(TRUE, world.time) //Fun fact, space station time has a timezone offset, If its not on display time. I added world.time to fix the compile error. I dunno if it works as intended still!! + var/hour = (text2num(time2text(ass_time, "hh"))%12) + var/minute = text2num(time2text(ass_time, "mm")) + + //to_chat(world, "dyndial cycle current says: [hour]:[minute] - Ass_time currently says [ass_time]") + if(playchime && hour == 0) + playsound(src.loc, 'modular_citadel/code/modules/eventmaps/Spookystation/midnightchime.ogg', 100, 0) + playchime = 0 + if(!playchime && hour == 11) + playchime = 1 + + switch(hour) + if(1, 2) + HRimgstate = "asshouroverlay-2" //Now it is ass, mostly because someones going to kill me for the other names. + if(3) + HRimgstate = "asshouroverlay-3" + if(4, 5) + HRimgstate = "asshouroverlay-4" + if(6) + HRimgstate = "asshouroverlay-6" + if(7, 8) + HRimgstate = "asshouroverlay-7" + if(9) + HRimgstate = "asshouroverlay-9" + if(10, 11) + HRimgstate = "asshouroverlay-10" + else + HRimgstate = "asshouroverlay-0" //Station time wraps to 0, and so does our hours. + + switch(minute) + if(0 to 3) + MMimgstate = "assminuteoverlay-0" + if(4 to 15) + MMimgstate = "assminuteoverlay-2" + if(16 to 22) + MMimgstate = "assminuteoverlay-3" + if(23 to 28) + MMimgstate = "assminuteoverlay-4" + if(29 to 33) + MMimgstate = "assminuteoverlay-6" + if(34 to 41) + MMimgstate = "assminuteoverlay-7" + if(42 to 49) + MMimgstate = "assminuteoverlay-9" + if(50 to 57) + MMimgstate = "assminuteoverlay-10" + else + MMimgstate = "assminuteoverlay-0" //This has 58 to 60 and everything else. + + update_icon() //Everything is set, lets update. + +/obj/machinery/grandfatherclock/update_icon() + cut_overlays() //We cut the overlays. + + add_overlay(MMimgstate) //And append our new states, Minute + add_overlay(HRimgstate) //Hour. + +/* + The Flora that is generated onto the basic grassturf, or can be placed for tone building. + */ + +//For ease of use, I should have appended it all here.. +//Stripped the other segments out, people don't need hay and interactions right now you know man? +//Technically we could also randomize the pixel_x, pixel_y placement of these guys for more dynamic thickets. +/obj/structure/flora/grass/spookytime + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' //32x32 iconfile + desc = "Some dry, virtually dead grass, cause its fall and not a wasteland this time." + icon_state = "tall_grass_1" + +/obj/structure/flora/grass/spookytime/New() + ..() + icon_state = "tall_grass_[rand(1,8)]" //We have 8 states. + +/obj/structure/flora/grass/spookytime/attackby(obj/item/W, mob/user, params) + if(W.sharpness && W.force > 0 && !(NODECONSTRUCT_1 in flags_1)) + to_chat(user, "You begin to harvest [src]...") + if(do_after(user, 100/W.force, target = user)) + to_chat(user, "You've collected [src]") + var/obj/item/stack/sheet/hay/H = user.get_inactive_held_item() + if(istype(H)) + H.add(1) + else + new /obj/item/stack/sheet/hay/(get_turf(src)) + qdel(src) + return 1 + else + . = ..() + +/obj/structure/flora/tree/spookytime + name = "dead tree" + desc = "It's a tree. Useful for combustion and/or construction." + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile64.dmi' //64x64 iconfile + icon_state = "deadtree_1" + log_amount = 3 + density = 1 + obj_integrity = 100 + max_integrity = 100 + +/obj/structure/flora/tree/spookytime/New() + icon_state = "deadtree_[rand(1,6)]" //We have 6 states + ..() + +/obj/structure/flora/tree/spookytimexl + name = "tall dead tree" + desc = "It's a tree. Useful for combustion and/or construction. This ones quite tall" + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/talltree128.dmi' + icon_state = "tree_1" + log_amount = 12 + density = 1 + obj_integrity = 200 + max_integrity = 200 + +/obj/structure/flora/tree/spookytimexl/New() + icon_state = "tree_[rand(1,3)]" //We have 3 states. + ..() + +/obj/structure/flora/tree/spookybranch + name = "fallen branch" + desc = "A branch from a tree" + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + icon_state = "branch_1" + log_amount = 1 + density = 0 + obj_integrity = 30 + max_integrity = 30 + +/obj/structure/flora/tree/spookybranch/New() + icon_state = "branch_[rand(1,4)]" + ..() + +/obj/structure/flora/tree/spookylog + name = "fallen tree" + desc = "A tree, that turned horizontal after it died" + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + icon_state = "timber" + log_amount = 5 + density = 0 + obj_integrity = 100 + max_integrity = 100 //only got one state man. + +/obj/structure/flora/spookyrock + name = "rock" + desc = "Its a rock man. Hard as shit, and for you quite impassible." + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + icon_state = "rock_1" + density = 1 + +/obj/structure/flora/spookyrock/New() + icon_state = "rock_[rand(1,3)]" + ..() + +/* + WALLS - BECAUSE I HAD TO REPLACE ALL OF THEM ON THE MAP AND DO IT RIGHT THIS TIME + */ +/turf/closed/wall/mineral/wood + + +/obj/structure/falsewall/wood + +//Due to the behavior of walls generally, I'm not going to make a microcosm of full flexibility +//and functionability for a ball map, but heres everything we are usually using for future reference. + +/* + TURF DIRECTIONALS, OVERALL SPAMMED STUFF ETC + */ + +//Mostly here because I was tired of searching the top stuff. +//Damaged plasteel plates, cause fuck varediting all these icons my man. +//Just search damturf for the tree + +/turf/open/floor/plasteel/damturf //ez search plasteel parent +/turf/open/floor/plasteel/damturf/damage1 + icon_state = "damaged1" +/turf/open/floor/plasteel/damturf/damage2 + icon_state = "damaged2" +/turf/open/floor/plasteel/damturf/ + icon_state = "damaged3" +/turf/open/floor/plasteel/damturf/damage4 + icon_state = "damaged4" +/turf/open/floor/plasteel/damturf/damage5 + icon_state = "damaged5" +/turf/open/floor/plasteel/damturf/scorched + icon_state = "panelscorched" +/turf/open/floor/plasteel/damturf/scorched1 + icon_state = "floorscorched1" +/turf/open/floor/plasteel/damturf/scorched2 + icon_state = "floorscorched2" +/turf/open/floor/plasteel/damturf/platdmg1 + icon_state = "platingdmg1" +/turf/open/floor/plasteel/damturf/platdmg2 + icon_state = "platingdmg2" +/turf/open/floor/plasteel/damturf/platdmg3 + icon_state = "platingdmg3" + +/turf/open/floor/wood/damturf //ez search wood parent +/turf/open/floor/wood/damturf/broken1 + icon_state = "wood-broken" +/turf/open/floor/wood/damturf/broken2 + icon_state = "wood-broken2" +/turf/open/floor/wood/damturf/broken3 + icon_state = "wood-broken3" +/turf/open/floor/wood/damturf/broken4 + icon_state = "wood-broken4" +/turf/open/floor/wood/damturf/broken5 + icon_state = "wood-broken5" +/turf/open/floor/wood/damturf/broken6 + icon_state = "wood-broken6" +/turf/open/floor/wood/damturf/broken7 + icon_state = "wood-broken7" + +//Parent that goes into coasts too +/turf/open/floor/spooktime/beach //laketime + gender = PLURAL + name = "sand" + desc = "ITS SAND!" + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + icon_state = "sand" + bullet_bounce_sound = null + tiled_dirt = 0 + var/turfverb = "dig up" + + baseturfs = /turf/open/floor/plating/spookbase/sandattachmentpoint //Alas, now people can dig out lakes. + +/turf/open/floor/spooktime/beach/attackby(obj/item/C, mob/user, params) //We dig it out with a shovel. + if((C.tool_behaviour == TOOL_SHOVEL) && params) //And beneath it we reveal dirt + new /obj/item/stack/tile/normalasssand(src) //EDIT THIS + user.visible_message("[user] digs up [src].", "You [turfverb] [src].") + playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) + make_plating() + if(..()) + return + +//Beaches and coasts and sand and shit. +/turf/open/floor/spooktime/beach/coasts + gender = NEUTER + name = "coastline" + desc = "The coastline of a sandy shore" + icon_state = "sandwater_t_S" + +/turf/open/floor/spooktime/beach/coasts/attackby(obj/item/C, mob/user, params) + return //Upon testing, digging out the coasts makes the map look like ass. + +//The water that follows the coastline also animated. +/turf/open/floor/spooktime/beach/coasts/coastS + icon_state = "sandwater_t_S" +/turf/open/floor/spooktime/beach/coasts/coastN + icon_state = "sandwater_t_N" +/turf/open/floor/spooktime/beach/coasts/coastE + icon_state = "sandwater_t_E" +/turf/open/floor/spooktime/beach/coasts/coastW + icon_state = "sandwater_t_W" +/turf/open/floor/spooktime/beach/coasts/coastSE + icon_state = "sandwater_t_SE" +/turf/open/floor/spooktime/beach/coasts/coastSW + icon_state = "sandwater_t_SW" +/turf/open/floor/spooktime/beach/coasts/coastNE + icon_state = "sandwater_t_NE" +/turf/open/floor/spooktime/beach/coasts/coastNW + icon_state = "sandwater_t_NW" + +//The coastline itself with sand +/turf/open/floor/spooktime/beach/coasts/watercoastS + icon_state = "sandwater_b_S" +/turf/open/floor/spooktime/beach/coasts/watercoastN + icon_state = "sandwater_b_N" +/turf/open/floor/spooktime/beach/coasts/watercoastW + icon_state = "sandwater_b_W" +/turf/open/floor/spooktime/beach/coasts/watercoastE + icon_state = "sandwater_b_E" +/turf/open/floor/spooktime/beach/coasts/watercoastSE + icon_state = "sandwater_b_SE" +/turf/open/floor/spooktime/beach/coasts/watercoastSW + icon_state = "sandwater_b_SW" +/turf/open/floor/spooktime/beach/coasts/watercoastNE + icon_state = "sandwater_b_NE" +/turf/open/floor/spooktime/beach/coasts/watercoastNW + icon_state = "sandwater_b_NW" + +//Beach corners +/turf/open/floor/spooktime/beach/coasts/innerN + icon_state = "sandwater_inner_N" +/turf/open/floor/spooktime/beach/coasts/innerS + icon_state = "sandwater_inner_S" +/turf/open/floor/spooktime/beach/coasts/innerE + icon_state = "sandwater_inner_E" +/turf/open/floor/spooktime/beach/coasts/innerW + icon_state = "sandwater_inner_W" + +//Shallow water same color as beach water +/turf/open/floor/spooktime/beach/water + name = "water" + desc = "Its water that seems to be a bit deep, still can wade through though." + icon_state = "water" + bullet_sizzle = 1 + footstep = FOOTSTEP_WATER + barefootstep = FOOTSTEP_WATER + clawfootstep = FOOTSTEP_WATER + heavyfootstep = FOOTSTEP_WATER + +/turf/open/floor/spooktime/beach/water/attackby(obj/item/C, mob/user, params) + return //haha nope + +//Slightly darker than the beach water color. +/turf/open/floor/spooktime/beach/watersolid //Gotta stop you at a certain point man + name = "water" + desc = "Water thats deep enough to where your spaceman ass cannot swim." + icon_state = "water2" //Now its darker lol + bullet_sizzle = 1 + density = 1 //We are now dense + footstep = FOOTSTEP_WATER + barefootstep = FOOTSTEP_WATER + clawfootstep = FOOTSTEP_WATER + heavyfootstep = FOOTSTEP_WATER + +/turf/open/floor/spooktime/beach/watersolid/attackby(obj/item/C, mob/user, params) + return //You aren't digging my lake out unless I want you to fool. + +//Motion river water with the lighting on it. +/turf/open/floor/spooktime/riverwatermotion + gender = PLURAL + name = "water" + desc = "Shallow water." + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + icon_state = "riverwater_motion" + slowdown = 1 + bullet_sizzle = 1 + bullet_bounce_sound = null //needs a splashing sound one day. + footstep = FOOTSTEP_WATER + barefootstep = FOOTSTEP_WATER + clawfootstep = FOOTSTEP_WATER + heavyfootstep = FOOTSTEP_WATER + +//No motion river water with the lighting on it. +/turf/open/floor/spooktime/riverwatermotion/nomotion + icon_state = "riverwater" + +//Cobblestone and all of its directions tied to the parent. +/turf/open/floor/spooktime/cobble //Middle and parent + name = "cobblestone path" //We don't use directional varedits otherwise the map can load them incorrect. + desc = "A simple but beautiful path made of various sized stones." + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + icon_state = "cobble_mid" //as to why? Sometimes it will spawn the turf elsewhere and move it into place. + //That means the direction will change because of this movement, usually when theres things ontop of it. + footstep = FOOTSTEP_FLOOR + barefootstep = FOOTSTEP_HARD_BAREFOOT + clawfootstep = FOOTSTEP_HARD_CLAW + heavyfootstep = FOOTSTEP_GENERIC_HEAVY + tiled_dirt = 0 + +/turf/open/floor/spooktime/cobble/cornerNW //First corner + icon_state = "cobble_corner_nw" +/turf/open/floor/spooktime/cobble/cornerNE //Now that these are hardcoded individuals. + icon_state = "cobble_corner_ne" //Movement won't change what they are on mapload. +/turf/open/floor/spooktime/cobble/cornerSW + icon_state = "cobble_corner_sw" +/turf/open/floor/spooktime/cobble/cornerSE //I found i don't need most of these but still lol. + icon_state = "cobble_corner_se" + +/turf/open/floor/spooktime/cobble/sideN //First Side + icon_state = "cobble_side_n" +/turf/open/floor/spooktime/cobble/sideS + icon_state = "cobble_side_s" +/turf/open/floor/spooktime/cobble/sideE + icon_state = "cobble_side_e" +/turf/open/floor/spooktime/cobble/sideW + icon_state = "cobble_side_w" + +//A tiny tiny bit of the total road icon file from f13 edited for grass not desert hastily. +//Theres something like 30 pieces including crosswalks, sidewalks, potholes and other shit in it man. +/turf/open/floor/spooktime/cobble/roadmid //Center piece + name = "road" + desc = "Its asphault alright" + icon_state = "road" + +/turf/open/floor/spooktime/cobble/roadsideN //road edges, I have a lot of these + icon_state = "road_side_N" +/turf/open/floor/spooktime/cobble/roadsideS //But i don't feel like adding them all for a temp map. + icon_state = "road_side_S" +/turf/open/floor/spooktime/cobble/roadsideE + icon_state = "road_side_E" +/turf/open/floor/spooktime/cobble/roadsideW + icon_state = "road_side_W" +/turf/open/floor/spooktime/cobble/roadcornerSW + icon_state = "road_corner_sw" + +/turf/open/indestructible/spooknecropolis + name = "necropolis floor" + desc = "It's regarding you suspiciously." + icon = 'icons/turf/floors.dmi' + icon_state = "necro1" + baseturfs = /turf/open/indestructible/necropolis + footstep = FOOTSTEP_LAVA + barefootstep = FOOTSTEP_LAVA + clawfootstep = FOOTSTEP_LAVA + heavyfootstep = FOOTSTEP_LAVA + tiled_dirt = FALSE + +//Fermis's umbrella + +/obj/item/umbrella + name = "umbrella" + desc = "To keep the rain off you. Use with caution on windy days." + icon = 'icons/obj/items_and_weapons.dmi' + lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' + righthand_file = 'icons/mob/inhands/items_righthand.dmi' + icon_state = "umbrella_closed" + slot_flags = ITEM_SLOT_BELT + force = 5 + throwforce = 5 + w_class = WEIGHT_CLASS_SMALL + var/open = FALSE + +/obj/item/umbrella/Initialize(mapload) + ..() + color = RANDOM_COLOUR + update_icon() + +/obj/item/umbrella/attack_self() + toggle_umbrella() + +/obj/item/umbrella/proc/toggle_umbrella() + open = !open + icon_state = "umbrella_[open ? "open" : "closed"]" + item_state = icon_state + update_icon() + +//Keep the mechs out of the mech arena +/obj/structure/trap/ctf/nomech + name = "anti-mech barrier" + desc = "attempts to bring mechs into the regular ball space may result in spontaneous crabification" + +/obj/structure/trap/ctf/nomech/Crossed(atom/movable/AM) + if(is_type_in_typecache(AM, ignore_typecache)) + return + flare() + if(ismecha(AM) || istype(AM, /obj/item/mecha_parts) || istype(AM, /obj/structure/mecha_wreckage)) + qdel(AM) + +/* + Shitty Hay Objects Sprited by me in a rush when I was half-asleep at 9am + The material + */ + +GLOBAL_LIST_INIT(hay_recipes, list ( \ + new/datum/stack_recipe("Rice Hat", /obj/item/clothing/head/rice_hat, 4, time = 5, one_per_turf = 0, on_floor = 0), \ + new/datum/stack_recipe("Hay Bed", /obj/structure/bed/badhaybed, 4, time = 15, one_per_turf = 1, on_floor = 0), \ + new/datum/stack_recipe("Wicker Basket", /obj/structure/closet/crate/awfulwickerbasket, 5, time = 40, one_per_turf = 0, on_floor = 1), \ +)) +//Thanks Gomble +/obj/item/stack/sheet/hay + name = "hay" + desc = "A bundle of hay. Food for livestock, and useful for weaving. Hail the Wickerman." + singular_name = "hay stalk" + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + icon_state = "hay" + item_state = "hay" + force = 1 + throwforce = 1 + throw_speed = 1 + throw_range = 2 + max_amount = 500 + attack_verb = list("tickled", "poked", "whipped") + hitsound = 'sound/weapons/grenadelaunch.ogg' + +/obj/item/stack/sheet/hay/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.hay_recipes + return ..() + +/obj/item/stack/sheet/hay/fifty + amount = 50 + +/obj/item/stack/sheet/hay/twenty + amount = 20 + +/obj/item/stack/sheet/hay/ten + amount = 10 + +/obj/item/stack/sheet/hay/five + amount = 5 + + +/obj/item/stack/sheet/hay/update_icon() + var/amount = get_amount() + if((amount <= 4) && (amount > 0)) + icon_state = "hay[amount]" + else + icon_state = "hay" + +/* + Hay Objects hastily drawn by me at 9am in a rush. + */ +//Shitty bed +/obj/structure/bed/badhaybed + name = "Low-quality Hay Bed" + desc = "It looks like someone hastily put this together, even if the builder didn't." + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + icon_state = "shitty_hay_bed" + anchored = 1 + can_buckle = 1 + buckle_lying = 1 + resistance_flags = FLAMMABLE + max_integrity = 50 + integrity_failure = 30 + buildstacktype = /obj/item/stack/sheet/hay + buildstackamount = 5 + +//Awful Wicker Basket +/obj/structure/closet/crate/awfulwickerbasket + name = "Low-quality Wicker Basket" + desc = "A handmade wicker basket, you don't know why it looks like this. But you probably don't like it." + icon = 'modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi' + icon_state = "shitty_basket" //yes, there is no space on crates so the other state is shitty_basketopen + resistance_flags = FLAMMABLE + material_drop = /obj/item/stack/sheet/hay + material_drop_amount = 5 diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/Tick.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/Tick.ogg new file mode 100644 index 0000000000..a3e0e3931e Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/Tick.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/Tock.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/Tock.ogg new file mode 100644 index 0000000000..265d775e9c Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/Tock.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/areas.dmi b/modular_citadel/code/modules/eventmaps/Spookystation/areas.dmi new file mode 100644 index 0000000000..f442b76f11 Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/areas.dmi differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/basecaveloop.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/basecaveloop.ogg new file mode 100644 index 0000000000..da25ab77a0 Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/basecaveloop.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/baseinsideloop.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/baseinsideloop.ogg new file mode 100644 index 0000000000..a08cfa32ad Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/baseinsideloop.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/baseoutsideloop.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/baseoutsideloop.ogg new file mode 100644 index 0000000000..8fed222a90 Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/baseoutsideloop.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/caveloop1.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/caveloop1.ogg new file mode 100644 index 0000000000..6ff1b3da76 Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/caveloop1.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/caveloop2.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/caveloop2.ogg new file mode 100644 index 0000000000..2a5a971adc Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/caveloop2.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/caveloop3.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/caveloop3.ogg new file mode 100644 index 0000000000..4b13c59382 Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/caveloop3.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/caveloop4.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/caveloop4.ogg new file mode 100644 index 0000000000..22d6e54e89 Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/caveloop4.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/clock32x49.dmi b/modular_citadel/code/modules/eventmaps/Spookystation/clock32x49.dmi new file mode 100644 index 0000000000..4f0083950a Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/clock32x49.dmi differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/halloweenPersiWork.dm b/modular_citadel/code/modules/eventmaps/Spookystation/halloweenPersiWork.dm new file mode 100644 index 0000000000..f14846744f --- /dev/null +++ b/modular_citadel/code/modules/eventmaps/Spookystation/halloweenPersiWork.dm @@ -0,0 +1,311 @@ +//Halloween Fluff Papers! + +/obj/item/paper/pamphlet/balls/spookyasylum + name = "ASYLUMNAME Pamphlet" + info = "
    The Twin Nexus Hotel

    A place of Sanctuary


    Welcome to The Twin-Nexus Hotel, \[insert name here]! The loyal staff stride to their best effort to cater for the best possible experience for all space(wo)men! If you have any questions or comments, please ask one of our on-board staff for more information.
    " + +/obj/item/paper/fluff/balls/spookyasylum/cell03 + name = "Cell 3 Patient Information" + info = "Name: J. Crane
    Age: 46 Gender: M Height: 183cm Weight: 81kg
    Notes: Patient exhibits violent tendencies and is not to be released from restraints under any circumstances. To reduce risk of violent outbreaks, birds; which patient has a strong phobia towards; are no longer allowed in proximity of cells, this includes the chief of staff's pet parrot." + +/obj/item/paper/fluff/balls/spookyasylum/cell04 + name = "Cell 4 Patient Information" + info = "Name: Fidel S.
    Age: 20 Gender: M Height: 170cm Weight: 68kg
    Notes: Patient appears to be under the delusion that he is a dog, suffers from incontinence, and bites staff. Patient to be kept restrained in cell after attacking orderly Robinson, do not remove patient's muzzle outside designated meal periods." + +/obj/item/paper/fluff/balls/spookyasylum/traffickingvictim + name = "Cell 1 Patient Information" + info = "Name: S. Albright
    Age: 26 Gender: F Height: 174cm Weight: 63kg
    Notes: \[The notes are crossed out and unreadable, but there is writing on the back of the paper] Buyer found in Sol system, wealthy Martian man looking for a cheap bride, doesn't mind poor condition of the merchandise. Will be packaging with the next supply ship for transport." + +/obj/item/paper/fluff/balls/spookyasylum/healstaffnote + name = "Shipping Manifest 'Healing Staves'" + info = "Contained in this chest are several magical healing staves created by NT sanctioned warlocks, please use them in the event an employee is injured during the festivities. We hope you have a safe and enjoyable celebration, remember you are expected to return to work promptly at its conclusion.
    We apologize in the unlikely event the contents of the crate are scattered around the asylum by its teleportation." + +//Dorm Buttons + +/obj/machinery/button/door/dorms/dorm01 + name = "dorm 1 button" + id = "D100" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm02 + name = "dorm 2 button" + id = "D101" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm03 + name = "dorm 3 button" + id = "D102" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm04 + name = "dorm 4 button" + id = "D103" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm05 + name = "dorm 5 button" + id = "D104" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm06 + name = "dorm 6 button" + id = "D105" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm07 + name = "dorm 7 button" + id = "D106" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm08 + name = "dorm 8 button" + id = "D107" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm09 + name = "dorm 9 button" + id = "D108" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm10 + name = "dorm 10 button" + id = "D109" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm11 + name = "dorm 11 button" + id = "D110" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm12 + name = "dorm 12 button" + id = "D111" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm13 + name = "dorm 13 button" + id = "D112" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm14 + name = "dorm 14 button" + id = "D113" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm15 + name = "dorm 15 button" + id = "D114" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm16 + name = "dorm 16 button" + id = "D115" + normaldoorcontrol = 1 + pixel_x = 24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm17 + name = "dorm 17 button" + id = "D116" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm18 + name = "dorm 18 button" + id = "D117" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm19 + name = "dorm 19 button" + id = "D118" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/dorm20 + name = "dorm 20 button" + id = "D119" + normaldoorcontrol = 1 + pixel_x = -24 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/patient1 + name = "door bolt" + id = "D120" + normaldoorcontrol = 1 + pixel_x = 24 + pixel_y = -8 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/patient2 + name = "door bolt" + id = "D121" + normaldoorcontrol = 1 + pixel_x = 24 + pixel_y = -8 + specialfunctions = 4 + +/obj/machinery/button/door/dorms/luxury1 + name = "Privacy Shutter Control" + id = "L00" + pixel_x = -8 + pixel_y = -24 + +/obj/machinery/button/door/dorms/luxury2 + name = "Privacy Shutter Control" + id = "L01" + pixel_x = 8 + pixel_y = -24 + +/obj/machinery/button/door/dorms/luxury3 + name = "Privacy Shutter Control" + id = "L02" + pixel_x = 8 + pixel_y = 24 + +/obj/machinery/button/door/dorms/luxury4 + name = "Privacy Shutter Control" + id = "L03" + pixel_x = -24 + pixel_y = 8 + +//Dorm Doors + +/obj/machinery/door/airlock/wood/dorms/dorm01 + name = "Room 1" + id_tag = "D100" + +/obj/machinery/door/airlock/wood/dorms/dorm02 + name = "Room 2" + id_tag = "D101" + +/obj/machinery/door/airlock/wood/dorms/dorm03 + name = "Room 3" + id_tag = "D102" + +/obj/machinery/door/airlock/wood/dorms/dorm04 + name = "Room 4" + id_tag = "D103" + +/obj/machinery/door/airlock/wood/dorms/dorm05 + name = "Room 5" + id_tag = "D104" + +/obj/machinery/door/airlock/wood/dorms/dorm06 + name = "Room 6" + id_tag = "D105" + +/obj/machinery/door/airlock/wood/dorms/dorm07 + name = "Room 7" + id_tag = "D106" + +/obj/machinery/door/airlock/wood/dorms/dorm08 + name = "Room 8" + id_tag = "D107" + +/obj/machinery/door/airlock/wood/dorms/dorm09 + name = "Room 9" + id_tag = "D108" + +/obj/machinery/door/airlock/wood/dorms/dorm10 + name = "Room 10" + id_tag = "D109" + +/obj/machinery/door/airlock/wood/dorms/dorm11 + name = "Room 11" + id_tag = "D110" + +/obj/machinery/door/airlock/wood/dorms/dorm12 + name = "Room 12" + id_tag = "D111" + +/obj/machinery/door/airlock/wood/dorms/dorm13 + name = "Room 13" + id_tag = "D112" + +/obj/machinery/door/airlock/wood/dorms/dorm14 + name = "Room 14" + id_tag = "D113" + +/obj/machinery/door/airlock/wood/dorms/dorm15 + name = "Room 15" + id_tag = "D114" + +/obj/machinery/door/airlock/wood/dorms/dorm16 + name = "Room 16" + id_tag = "D115" + +/obj/machinery/door/airlock/wood/dorms/dorm17 + name = "Room 17" + id_tag = "D116" + +/obj/machinery/door/airlock/wood/dorms/dorm18 + name = "Room 18" + id_tag = "D117" + +/obj/machinery/door/airlock/wood/dorms/dorm19 + name = "Room 19" + id_tag = "D118" + +/obj/machinery/door/airlock/wood/dorms/dorm20 + name = "Room 20" + id_tag = "D119" + +/obj/machinery/door/airlock/wood/dorms/patient1 + name = "Recovery Room 1" + id_tag = "D120" + +/obj/machinery/door/airlock/wood/dorms/patient2 + name = "Recovery Room 2" + id_tag = "D121" + +//Luxury Dorm Shutters + +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury01 + name = "Privacy Shutters" + id = "L00" + +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury02 + name = "Privacy Shutters" + id = "L01" + +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury03 + name = "Privacy Shutters" + id = "L02" + +/obj/machinery/door/poddoor/shutters/preopen/luxury_dorms/luxury04 + name = "Privacy Shutters" + id = "L03" diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi b/modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi new file mode 100644 index 0000000000..21ac510615 Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/iconfile32.dmi differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/iconfile64.dmi b/modular_citadel/code/modules/eventmaps/Spookystation/iconfile64.dmi new file mode 100644 index 0000000000..5643a969df Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/iconfile64.dmi differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/insideloop1.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/insideloop1.ogg new file mode 100644 index 0000000000..e271d8e681 Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/insideloop1.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/insideloop2.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/insideloop2.ogg new file mode 100644 index 0000000000..de527107bb Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/insideloop2.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/insideloop3.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/insideloop3.ogg new file mode 100644 index 0000000000..db17ab45b3 Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/insideloop3.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/insideloop4.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/insideloop4.ogg new file mode 100644 index 0000000000..aeba02c11e Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/insideloop4.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/midnightchime.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/midnightchime.ogg new file mode 100644 index 0000000000..95ac3a0284 Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/midnightchime.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/outsideloop1.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/outsideloop1.ogg new file mode 100644 index 0000000000..d7122821af Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/outsideloop1.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/outsideloop2.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/outsideloop2.ogg new file mode 100644 index 0000000000..f4b8526b5c Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/outsideloop2.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/talltree128.dmi b/modular_citadel/code/modules/eventmaps/Spookystation/talltree128.dmi new file mode 100644 index 0000000000..96be612bad Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/talltree128.dmi differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/treefall.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/treefall.ogg new file mode 100644 index 0000000000..cd5379ca77 Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/treefall.ogg differ diff --git a/modular_citadel/code/modules/eventmaps/Spookystation/woodchop.ogg b/modular_citadel/code/modules/eventmaps/Spookystation/woodchop.ogg new file mode 100644 index 0000000000..0ef5a9edbe Binary files /dev/null and b/modular_citadel/code/modules/eventmaps/Spookystation/woodchop.ogg differ diff --git a/modular_citadel/code/modules/festive/32x64.dm b/modular_citadel/code/modules/festive/32x64.dm new file mode 100644 index 0000000000..5687cdead3 --- /dev/null +++ b/modular_citadel/code/modules/festive/32x64.dm @@ -0,0 +1,60 @@ +//Festive Light Poles + +/obj/structure/streetdecor/lamp + name = "lamp pole" + desc = "A metal pole with latern. Very effective at lighting up the cold streets on a breezy night." + layer = 4 + density = TRUE + anchored = TRUE + light_power = 1.4 + light_range = 15 + light_color = "#ffffdd" + icon = 'modular_citadel/code/modules/festive/32x64icons.dmi' + icon_state = "lamp_post" + max_integrity = 9999999 + +/obj/structure/streetdecor/lampfestive + name = "festive lamp pole" + desc = "A metal pole with latern and christmas decorations. Very effective at warming up the spirits of people." + layer = 4 + density = TRUE + anchored = TRUE + light_power = 1.6 + light_range = 15 + light_color = "#ffffdd" + icon = 'modular_citadel/code/modules/festive/32x64icons.dmi' + icon_state = "lamp_post_festive" + max_integrity = 9999999 + +/obj/structure/streetdecor/wreathpole + name = "wreath pole" + desc = "A metal pole with a fancy wreath." + layer = 4 + density = TRUE + anchored = TRUE + + icon = 'modular_citadel/code/modules/festive/32x64icons.dmi' + icon_state = "wreath_post" + +/obj/structure/streetdecor/welcomesign + name = "Welcome sign" + desc = "A tartan trapped sign welcoming you to Nova Edina." + layer = 4 + density = TRUE + anchored = TRUE + + icon = 'modular_citadel/code/modules/festive/city_sign.dmi' + icon_state = "sign" + +/obj/structure/streetdecor/bigtree + name = "Big festive tree" + desc = "Big tree. Big heck. Big festive cheer!" + layer = 4 + density = TRUE + anchored = TRUE + light_power = 2 + light_range = 30 + light_color = "#ffeeab" + icon = 'modular_citadel/code/modules/festive/bigtree.dmi' + icon_state = "bigtree" + max_integrity = 9999999 diff --git a/modular_citadel/code/modules/festive/32x64icons.dmi b/modular_citadel/code/modules/festive/32x64icons.dmi new file mode 100644 index 0000000000..13c0bb08f1 Binary files /dev/null and b/modular_citadel/code/modules/festive/32x64icons.dmi differ diff --git a/modular_citadel/code/modules/festive/alleywaybricks.dmi b/modular_citadel/code/modules/festive/alleywaybricks.dmi new file mode 100644 index 0000000000..aa82a71fad Binary files /dev/null and b/modular_citadel/code/modules/festive/alleywaybricks.dmi differ diff --git a/modular_citadel/code/modules/festive/bigtree.dmi b/modular_citadel/code/modules/festive/bigtree.dmi new file mode 100644 index 0000000000..7d8fdfff6c Binary files /dev/null and b/modular_citadel/code/modules/festive/bigtree.dmi differ diff --git a/modular_citadel/code/modules/festive/blue_brick_wall.dmi b/modular_citadel/code/modules/festive/blue_brick_wall.dmi new file mode 100644 index 0000000000..2a15e628b7 Binary files /dev/null and b/modular_citadel/code/modules/festive/blue_brick_wall.dmi differ diff --git a/modular_citadel/code/modules/festive/blue_brick_window.dmi b/modular_citadel/code/modules/festive/blue_brick_window.dmi new file mode 100644 index 0000000000..7ed65fceeb Binary files /dev/null and b/modular_citadel/code/modules/festive/blue_brick_window.dmi differ diff --git a/modular_citadel/code/modules/festive/city_sign.dmi b/modular_citadel/code/modules/festive/city_sign.dmi new file mode 100644 index 0000000000..c4a41f7b76 Binary files /dev/null and b/modular_citadel/code/modules/festive/city_sign.dmi differ diff --git a/modular_citadel/code/modules/festive/cobblestone.dmi b/modular_citadel/code/modules/festive/cobblestone.dmi new file mode 100644 index 0000000000..f7218d8dc8 Binary files /dev/null and b/modular_citadel/code/modules/festive/cobblestone.dmi differ diff --git a/modular_citadel/code/modules/festive/festive_decals.dm b/modular_citadel/code/modules/festive/festive_decals.dm new file mode 100644 index 0000000000..a0d520da5f --- /dev/null +++ b/modular_citadel/code/modules/festive/festive_decals.dm @@ -0,0 +1,53 @@ +/obj/effect/decal/festive + name = "Festive item!" + desc = "It fills you with holiday cheer." + icon = 'modular_citadel/code/modules/festive/festive_objects.dmi' + icon_state = "holly" + plane = -5 //makes the graffiti visible over a wall. I think + +/obj/effect/decal/festive/holly + name = "Holly" + desc = "A prickly, yet cheerful flora laden with ripe berries of festive joy." + +/obj/effect/decal/festive/fairylights + name = "Fairy lights" + desc = "A strand of smol glowing lights, almost as if the lights themselves were faries." + icon_state = "y_fairylights" + light_power = 1.6 + light_range = 3 + light_color = "#ffeeab" + +/obj/effect/decal/festive/mistletoe + name = "Mistletoe" + desc = "A plant that causes 2 victims underneath to engage in a smooch!" + icon_state = "mistletoe" + +/obj/effect/decal/festive/christmas_reef + name = "Christmas reef" + desc = "A ring reef of festive plants." + icon_state = "christmas_reef" + +/obj/effect/decal/festive/green_stockings + name = "Green stockings" + desc = "3 wee booties out on a row, hoping for presents from the fat man's tow." + icon_state = "green_stockings" + +/obj/effect/decal/festive/red_stockings + name = "Red stockings" + desc = "Santa seems to enjoy socks a lot, huh." + icon_state = "red_stockings" + +/obj/effect/decal/festive/large_red_stocking + name = "Large red stocking" + desc = "A big hecking chonker of a sock, a braisen display of greed, or simply the sock of a large man?" + icon_state = "large_red_stocking" + +/obj/effect/decal/festive/large_green_stocking + name = "Large green stocking" + desc = "They say his sock grew 3 sizes that day." + icon_state = "large_green_stocking" + +/obj/effect/decal/festive/christmas_ivy_string + name = "Festive ivy" + desc = "In a recent study performed by the local university, it was found that ivy doesn't grow to live and thrive, but instead to spread festive cheer. You cannot help but feel the holiday spirit wrangle around you fantastically." //I am super tired and I wordswordswords + icon_state = "christmas_ivy_string" diff --git a/modular_citadel/code/modules/festive/festive_notes.dm b/modular_citadel/code/modules/festive/festive_notes.dm new file mode 100644 index 0000000000..1da6fdd179 --- /dev/null +++ b/modular_citadel/code/modules/festive/festive_notes.dm @@ -0,0 +1,7 @@ +/obj/item/paper/fluff/festive/note_for_qm + name = "To the Quartermaster(s)" + info = "Seeing as this is an event for employees spanning the entire sector, it's possible you may not be the only Quartermaster present today and you'll have to share this office should that be the case. Fortunately, you shouldn't need to share a locker - you shall find some additional lockers with quartermaster access in your department's locker room. Should you require additional lockers however, you will need to contact Central Command directly.
    Additionally, the successful capture of a Syndicate freighter has left us with a surplus of Donksoft weaponry. Considering they pose far less of a concern than their real counterparts, your department has been put in charge of their distribution. Just be sure not to keep them all for yourself - 'tis the season of giving, after all.
    - Administrator Roux" + +/obj/item/paper/fluff/festive/note_for_chap + name = "A letter to the Chaplain" + info = "Chaplain,
    You might not be alone in your duties today. Seeing as these are special circumstances, you will find additional supplies with which to arm your fellow clergymen.
    Do we expect you to need to use what's inside? Thankfully, no. Alas, should malicious occult forces strike, we want your compatriots to be equipped to face them.
    At the very least, don't just give these out to anyone. Every time I see an assistant running around with a holy 'sord', I can feel my insides crumble...
    Soulstone Obelisk
    Department of Higher Dimensional Affairs" diff --git a/modular_citadel/code/modules/festive/festive_objects.dmi b/modular_citadel/code/modules/festive/festive_objects.dmi new file mode 100644 index 0000000000..b13095a408 Binary files /dev/null and b/modular_citadel/code/modules/festive/festive_objects.dmi differ diff --git a/modular_citadel/code/modules/festive/grey_brick_wall.dmi b/modular_citadel/code/modules/festive/grey_brick_wall.dmi new file mode 100644 index 0000000000..bf96b4c7cf Binary files /dev/null and b/modular_citadel/code/modules/festive/grey_brick_wall.dmi differ diff --git a/modular_citadel/code/modules/festive/grey_brick_window.dmi b/modular_citadel/code/modules/festive/grey_brick_window.dmi new file mode 100644 index 0000000000..72a289e7fa Binary files /dev/null and b/modular_citadel/code/modules/festive/grey_brick_window.dmi differ diff --git a/modular_citadel/code/modules/festive/grey_panel_wall.dmi b/modular_citadel/code/modules/festive/grey_panel_wall.dmi new file mode 100644 index 0000000000..2a8e5a531c Binary files /dev/null and b/modular_citadel/code/modules/festive/grey_panel_wall.dmi differ diff --git a/modular_citadel/code/modules/festive/privacy.dm b/modular_citadel/code/modules/festive/privacy.dm new file mode 100644 index 0000000000..2500009358 --- /dev/null +++ b/modular_citadel/code/modules/festive/privacy.dm @@ -0,0 +1,26 @@ +//How to use: +//Set the name of off the the objects you want controlled by 1 button to the same name +//Set the tar_name of this to the same name +//Press the button in game. + +/obj/machinery/button/privacy + name = "Privacy toggle" + var/tar_name + var/tint_objs = list() + +/obj/machinery/button/privacy/setup_device() + if(!device) + for(var/obj/O in get_area(src)) + if(O.name == tar_name) + tint_objs += O + ..() + +/obj/machinery/button/privacy/attack_hand(mob/user) + .=..() + for(var/obj/O in tint_objs) + if(O.opacity) + O.color = "#919191" + O.opacity = 0 + else + O.opacity = 1 + O.color = "#000000" diff --git a/modular_citadel/code/modules/festive/rails.dmi b/modular_citadel/code/modules/festive/rails.dmi new file mode 100644 index 0000000000..0eb71450d3 Binary files /dev/null and b/modular_citadel/code/modules/festive/rails.dmi differ diff --git a/modular_citadel/code/modules/festive/red_brick_wall.dmi b/modular_citadel/code/modules/festive/red_brick_wall.dmi new file mode 100644 index 0000000000..0aa3e105f2 Binary files /dev/null and b/modular_citadel/code/modules/festive/red_brick_wall.dmi differ diff --git a/modular_citadel/code/modules/festive/red_brick_window.dmi b/modular_citadel/code/modules/festive/red_brick_window.dmi new file mode 100644 index 0000000000..de6c466416 Binary files /dev/null and b/modular_citadel/code/modules/festive/red_brick_window.dmi differ diff --git a/modular_citadel/code/modules/festive/sidewalk.dmi b/modular_citadel/code/modules/festive/sidewalk.dmi new file mode 100644 index 0000000000..00e5eaa49b Binary files /dev/null and b/modular_citadel/code/modules/festive/sidewalk.dmi differ diff --git a/modular_citadel/code/modules/festive/stairs.dmi b/modular_citadel/code/modules/festive/stairs.dmi new file mode 100644 index 0000000000..72be1a31d4 Binary files /dev/null and b/modular_citadel/code/modules/festive/stairs.dmi differ diff --git a/modular_citadel/code/modules/festive/streetdecals.dmi b/modular_citadel/code/modules/festive/streetdecals.dmi new file mode 100644 index 0000000000..fc36212d9a Binary files /dev/null and b/modular_citadel/code/modules/festive/streetdecals.dmi differ diff --git a/modular_citadel/code/modules/festive/trainplatform.dmi b/modular_citadel/code/modules/festive/trainplatform.dmi new file mode 100644 index 0000000000..7910958167 Binary files /dev/null and b/modular_citadel/code/modules/festive/trainplatform.dmi differ diff --git a/modular_citadel/code/modules/festive/trainplatformedges.dmi b/modular_citadel/code/modules/festive/trainplatformedges.dmi new file mode 100644 index 0000000000..841cc5bb85 Binary files /dev/null and b/modular_citadel/code/modules/festive/trainplatformedges.dmi differ diff --git a/modular_citadel/code/modules/festive/turfs.dm b/modular_citadel/code/modules/festive/turfs.dm new file mode 100644 index 0000000000..dd119a25e7 --- /dev/null +++ b/modular_citadel/code/modules/festive/turfs.dm @@ -0,0 +1,1729 @@ +//Turfy Turfs + +/turf/open/floor/grass/snow/edina//But for now, we just handle what is outside, for light control etc. + name = "Scottish snow" + desc = "Looks super chilly!" + + light_range = 3 //MIDNIGHT BLUE + light_power = 0.15 //NOT PITCH BLACK, JUST REALLY DARK + light_color = "#00111a" //The light can technically cycle on a timer worldwide, but no daynight cycle. + baseturfs = /turf/open/floor/grass/snow/edina //If we explode or die somehow, we just make more! Ahahaha!!! + tiled_dirt = 0 //NO TILESMOOTHING DIRT/DIRT SPAWNS OR SOME SHIT + //initial_gas_mix = OPENTURF_DEFAULT_ATMOS //DO NOT FREEZE EVERYONE TO DEATH ON CHRISTMAS + initial_gas_mix = FESTIVE_ATMOS + planetary_atmos = 1 //Uses new!!! planetmos wow!!! maybe? + +//lets people build +/turf/open/floor/grass/snow/edina/attackby(obj/item/C, mob/user, params) + .=..() + if(istype(C, /obj/item/stack/tile)) + for(var/obj/O in src) + if(O.level == 1) //ex. pipes laid underneath a tile + for(var/M in O.buckled_mobs) + to_chat(user, "Someone is buckled to \the [O]! Unbuckle [M] to move \him out of the way.") + return + var/obj/item/stack/tile/W = C + if(!W.use(1)) + return + var/turf/open/floor/T = PlaceOnTop(W.turf_type) + T.icon_state = initial(T.icon_state) + if(istype(W, /obj/item/stack/tile/light)) //TODO: get rid of this ugly check somehow + var/obj/item/stack/tile/light/L = W + var/turf/open/floor/light/F = T + F.state = L.state + playsound(src, 'sound/weapons/genhit.ogg', 50, 1) + +/turf/open/floor/festive/cobblestone + name = "cobblestone" + baseturfs = /turf/open/floor/festive/cobblestone + icon = 'modular_citadel/code/modules/festive/cobblestone.dmi' + icon_state = "unsmooth" + smooth = SMOOTH_MORE | SMOOTH_BORDER + canSmoothWith = list(/turf/open/floor/festive/cobblestone) + initial_gas_mix = FESTIVE_ATMOS + planetary_atmos = 1 + +/turf/open/floor/festive/cobblestone/safe //this is literally cobblestone but safe for inside use because I don't want to fuck with aesthetics + baseturfs = /turf/open/floor/festive/cobblestone/safe + initial_gas_mix = OPENTURF_DEFAULT_ATMOS + planetary_atmos = FALSE + +/turf/open/floor/festive/sidewalk + name = "sidewalk" + baseturfs = /turf/open/floor/festive/sidewalk + icon = 'modular_citadel/code/modules/festive/sidewalk.dmi' + icon_state = "unsmooth" + smooth = SMOOTH_MORE | SMOOTH_BORDER + canSmoothWith = list(/turf/open/floor/festive/sidewalk) + initial_gas_mix = FESTIVE_ATMOS + planetary_atmos = 1 + +/turf/open/floor/festive/alleyway + name = "alleyway bricks" + baseturfs = /turf/open/floor/festive/alleyway + icon = 'modular_citadel/code/modules/festive/alleywaybricks.dmi' + icon_state = "unsmooth" + smooth = SMOOTH_MORE | SMOOTH_BORDER + canSmoothWith = list(/turf/open/floor/festive/alleyway, /turf/open/floor/festive/white_alleyway) + initial_gas_mix = FESTIVE_ATMOS + planetary_atmos = 1 + +/turf/open/floor/festive/alleyway/safe //this is literally alleyway but safe for inside use because I don't want to fuck with aesthetics + baseturfs = /turf/open/floor/festive/alleyway/safe + initial_gas_mix = OPENTURF_DEFAULT_ATMOS + planetary_atmos = FALSE + +/turf/open/floor/festive/white_alleyway + name = "alleyway bricks" + baseturfs = /turf/open/floor/festive/alleyway + icon = 'modular_citadel/code/modules/festive/white_alleywaybricks.dmi' + icon_state = "unsmooth" + smooth = SMOOTH_MORE | SMOOTH_BORDER + canSmoothWith = list(/turf/open/floor/festive/alleyway, /turf/open/floor/festive/white_alleyway) + initial_gas_mix = FESTIVE_ATMOS + planetary_atmos = 1 + +/turf/open/floor/festive/trainplatform + name = "trainplatform" + baseturfs = /turf/open/floor/festive/trainplatform + icon = 'modular_citadel/code/modules/festive/trainplatform.dmi' + icon_state = "unsmooth" + smooth = SMOOTH_MORE | SMOOTH_BORDER + canSmoothWith = list(/turf/open/floor/festive/trainplatform) + initial_gas_mix = FESTIVE_ATMOS + planetary_atmos = 1 + +/turf/open/floor/festive/trainplatform/safe //this is literally train platform but safe for inside use because I don't want to remap the strip club + baseturfs = /turf/open/floor/festive/trainplatform/safe + initial_gas_mix = OPENTURF_DEFAULT_ATMOS + planetary_atmos = FALSE + +/turf/open/floor/festive/stairs/stairsnorth + name = "stairs north" + icon = 'modular_citadel/code/modules/festive/stairs.dmi' + icon_state = "stairs_north" + +/turf/open/floor/festive/stairs/stairssouth + name = "stairs south" + icon = 'modular_citadel/code/modules/festive/stairs.dmi' + icon_state = "stairs_south" + +/turf/open/floor/festive/stairs/stairseast + name = "stairs east" + icon = 'modular_citadel/code/modules/festive/stairs.dmi' + icon_state = "stairs_east" + +/turf/open/floor/festive/stairs/stairswest + name = "stairs west" + icon = 'modular_citadel/code/modules/festive/stairs.dmi' + icon_state = "stairs_west" + +/turf/open/floor/festive/wooden/wooden1 + name = "tile planks" + baseturfs = /turf/open/floor/festive/wooden/wooden1 + icon = 'modular_citadel/code/modules/festive/wooden.dmi' + icon_state = "wooden_1" + +/turf/open/floor/festive/wooden/wooden2 + name = "decorative planks" + baseturfs = /turf/open/floor/festive/wooden/wooden2 + icon = 'modular_citadel/code/modules/festive/wooden.dmi' + icon_state = "wooden_2" + + + +//Grey Bricks, this will hurt some peoples eyes. + + + +/turf/closed/festive/greybrick + name = "grey brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/grey_brick_wall.dmi' + icon_state = "grey_brick" + smooth = SMOOTH_MORE + canSmoothWith = list(/turf/closed/festive/greybrick/greybrickte, /turf/closed/festive/greybrick/greybricktw, /turf/closed/festive/greybrick/greybrickts, /turf/closed/festive/greybrick/greybricktn, /turf/closed/festive/greybrick/greybrickcornernw, /turf/closed/festive/greybrick/greybrickcornerne, /turf/closed/festive/greybrick/greybrickcornersw, /turf/closed/festive/greybrick/greybrickcornerse, /turf/closed/festive/greybrick/greybrickwe, /turf/closed/festive/greybrick/greybrickns, /obj/structure/festive/greybrick/windowNSRightEnd, /obj/structure/festive/greybrick/windowNSLeftEnd, /turf/closed/festive/greybrick) + +/turf/closed/festive/greybrick/greybrickns + name = "grey brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/grey_brick_wall.dmi' + icon_state = "grey_brick_wall_ns" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greybrick/greybrickwe + name = "grey brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/grey_brick_wall.dmi' + icon_state = "grey_brick_wall_we" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greybrick/greybrickcornerse + name = "grey brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/grey_brick_wall.dmi' + icon_state = "grey_brick_corner_se" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greybrick/greybrickcornersw + name = "grey brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/grey_brick_wall.dmi' + icon_state = "grey_brick_corner_sw" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greybrick/greybrickcornerne + name = "grey brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/grey_brick_wall.dmi' + icon_state = "grey_brick_corner_ne" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greybrick/greybrickcornernw + name = "grey brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/grey_brick_wall.dmi' + icon_state = "grey_brick_corner_nw" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greybrick/greybricktn + name = "grey brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/grey_brick_wall.dmi' + icon_state = "grey_brick_t_n" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greybrick/greybrickts + name = "grey brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/grey_brick_wall.dmi' + icon_state = "grey_brick_t_s" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greybrick/greybricktw + name = "grey brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/grey_brick_wall.dmi' + icon_state = "grey_brick_t_w" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greybrick/greybrickte + name = "grey brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/grey_brick_wall.dmi' + icon_state = "grey_brick_t_e" + smooth = SMOOTH_FALSE + +/obj/structure/festive/greybrick/windowdoorweend1 + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_we_doorend_1" + density = TRUE + anchored = TRUE + +/obj/structure/festive/greybrick/windowdoorweend2 + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_we_doorend_2" + density = TRUE + anchored = TRUE + +/obj/structure/festive/greybrick/windowdoornsend1 + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_ns_doorend_1" + density = TRUE + anchored = TRUE + +/obj/structure/festive/greybrick/windowdoornsend2 + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_ns_doorend_2" + density = TRUE + anchored = TRUE + +/obj/structure/festive/greybrick/windowWE + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_we" + density = TRUE + anchored = TRUE + +/obj/structure/festive/greybrick/windowWERight + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_we_right" + density = TRUE + anchored = TRUE + +/obj/structure/festive/greybrick/windowWERightEnd + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_we_right_end" + canSmoothWith = list(/turf/closed/festive/greybrick) + density = TRUE + anchored = TRUE + +/obj/structure/festive/greybrick/windowWEMiddle + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_we_middle" + density = TRUE + anchored = TRUE + +/obj/structure/festive/greybrick/windowWELeft + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_we_left" + density = TRUE + anchored = TRUE + +/obj/structure/festive/greybrick/windowWELeftEnd + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_we_left_end" + canSmoothWith = list(/turf/closed/festive/greybrick) + density = TRUE + anchored = TRUE + +/obj/structure/festive/greybrick/windowNS + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_ns" + density = TRUE + anchored = TRUE + +/obj/structure/festive/greybrick/windowNSRight + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_ns_right" + density = TRUE + anchored = TRUE + +/obj/structure/festive/greybrick/windowNSRightEnd + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_ns_right_end" + canSmoothWith = list(/turf/closed/festive/greybrick) + density = TRUE + anchored = TRUE + +/obj/structure/festive/greybrick/windowNSMiddle + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_ns_middle" + density = TRUE + anchored = TRUE + +/obj/structure/festive/greybrick/windowNSLeft + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_ns_left" + density = TRUE + anchored = TRUE + +/obj/structure/festive/greybrick/windowNSLeftEnd + name = "grey window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/grey_brick_window.dmi' + icon_state = "grey_brick_window_ns_left_end" + canSmoothWith = list(/turf/closed/festive/greybrick) + density = TRUE + anchored = TRUE + + + +//Red Bricks + + + +/turf/closed/festive/redbrick + name = "red brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/red_brick_wall.dmi' + icon_state = "red_brick" + smooth = SMOOTH_MORE + canSmoothWith = list(/turf/closed/festive/redbrick/redbrickte, /turf/closed/festive/redbrick/redbricktw, /turf/closed/festive/redbrick/redbrickts, /turf/closed/festive/redbrick/redbricktn, /turf/closed/festive/redbrick/redbrickcornernw, /turf/closed/festive/redbrick/redbrickcornerne, /turf/closed/festive/redbrick/redbrickcornersw, /turf/closed/festive/redbrick/redbrickcornerse, /turf/closed/festive/redbrick/redbrickwe, /turf/closed/festive/redbrick/redbrickns, /obj/structure/festive/redbrick/windowNSRightEnd, /obj/structure/festive/redbrick/windowNSLeftEnd, /turf/closed/festive/redbrick) + +/turf/closed/festive/redbrick/redbrickns + name = "red brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/red_brick_wall.dmi' + icon_state = "red_brick_wall_ns" + smooth = SMOOTH_FALSE + +/turf/closed/festive/redbrick/redbrickwe + name = "red brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/red_brick_wall.dmi' + icon_state = "red_brick_wall_we" + smooth = SMOOTH_FALSE + +/turf/closed/festive/redbrick/redbrickcornerse + name = "red brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/red_brick_wall.dmi' + icon_state = "red_brick_corner_se" + smooth = SMOOTH_FALSE + +/turf/closed/festive/redbrick/redbrickcornersw + name = "red brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/red_brick_wall.dmi' + icon_state = "red_brick_corner_sw" + smooth = SMOOTH_FALSE + +/turf/closed/festive/redbrick/redbrickcornerne + name = "red brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/red_brick_wall.dmi' + icon_state = "red_brick_corner_ne" + smooth = SMOOTH_FALSE + +/turf/closed/festive/redbrick/redbrickcornernw + name = "red brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/red_brick_wall.dmi' + icon_state = "red_brick_corner_nw" + smooth = SMOOTH_FALSE + +/turf/closed/festive/redbrick/redbricktn + name = "red brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/red_brick_wall.dmi' + icon_state = "red_brick_t_n" + smooth = SMOOTH_FALSE + +/turf/closed/festive/redbrick/redbrickts + name = "red brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/red_brick_wall.dmi' + icon_state = "red_brick_t_s" + smooth = SMOOTH_FALSE + +/turf/closed/festive/redbrick/redbricktw + name = "red brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/red_brick_wall.dmi' + icon_state = "red_brick_t_w" + smooth = SMOOTH_FALSE + +/turf/closed/festive/redbrick/redbrickte + name = "red brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/red_brick_wall.dmi' + icon_state = "red_brick_t_e" + smooth = SMOOTH_FALSE + +/obj/structure/festive/redbrick/windowdoorweend1 + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_we_doorend_1" + density = TRUE + anchored = TRUE + +/obj/structure/festive/redbrick/windowdoorweend2 + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_we_doorend_2" + density = TRUE + anchored = TRUE + +/obj/structure/festive/redbrick/windowdoornsend1 + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_ns_doorend_1" + density = TRUE + anchored = TRUE + +/obj/structure/festive/redbrick/windowdoornsend2 + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_ns_doorend_2" + density = TRUE + anchored = TRUE + +/obj/structure/festive/redbrick/windowWE + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_we" + density = TRUE + anchored = TRUE + +/obj/structure/festive/redbrick/windowWERight + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_we_right" + density = TRUE + anchored = TRUE + +/obj/structure/festive/redbrick/windowWERightEnd + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_we_right_end" + canSmoothWith = list(/turf/closed/festive/redbrick) + density = TRUE + anchored = TRUE + +/obj/structure/festive/redbrick/windowWEMiddle + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_we_middle" + density = TRUE + anchored = TRUE + +/obj/structure/festive/redbrick/windowWELeft + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_we_left" + density = TRUE + anchored = TRUE + +/obj/structure/festive/redbrick/windowWELeftEnd + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_we_left_end" + canSmoothWith = list(/turf/closed/festive/redbrick) + density = TRUE + anchored = TRUE + +/obj/structure/festive/redbrick/windowNS + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_ns" + density = TRUE + anchored = TRUE + +/obj/structure/festive/redbrick/windowNSRight + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_ns_right" + density = TRUE + anchored = TRUE + +/obj/structure/festive/redbrick/windowNSRightEnd + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_ns_right_end" + canSmoothWith = list(/turf/closed/festive/redbrick) + density = TRUE + anchored = TRUE + +/obj/structure/festive/redbrick/windowNSMiddle + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_ns_middle" + density = TRUE + anchored = TRUE + +/obj/structure/festive/redbrick/windowNSLeft + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_ns_left" + density = TRUE + anchored = TRUE + +/obj/structure/festive/redbrick/windowNSLeftEnd + name = "red window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/red_brick_window.dmi' + icon_state = "red_brick_window_ns_left_end" + canSmoothWith = list(/turf/closed/festive/redbrick) + density = TRUE + anchored = TRUE + + + +//white Bricks + + + +/turf/closed/festive/whitebrick + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick" + smooth = SMOOTH_MORE + canSmoothWith = list(/turf/closed/festive/whitebrick/whitebrickte, /turf/closed/festive/whitebrick/whitebricktw, /turf/closed/festive/whitebrick/whitebrickts, /turf/closed/festive/whitebrick/whitebricktn, /turf/closed/festive/whitebrick/whitebrickcornernw, /turf/closed/festive/whitebrick/whitebrickcornerne, /turf/closed/festive/whitebrick/whitebrickcornersw, /turf/closed/festive/whitebrick/whitebrickcornerse, /turf/closed/festive/whitebrick/whitebrickwe, /turf/closed/festive/whitebrick/whitebrickns, /obj/structure/festive/whitebrick/windowNSRightEnd, /obj/structure/festive/whitebrick/windowNSLeftEnd, /turf/closed/festive/whitebrick) + +/turf/closed/festive/whitebrick/whitebrickns + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_wall_ns" + smooth = SMOOTH_FALSE + +/turf/closed/festive/whitebrick/whitebrickwe + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_wall_we" + smooth = SMOOTH_FALSE + +/turf/closed/festive/whitebrick/whitebrickcornerse + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_corner_se" + smooth = SMOOTH_FALSE + +/turf/closed/festive/whitebrick/whitebrickcornersw + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_corner_sw" + smooth = SMOOTH_FALSE + +/turf/closed/festive/whitebrick/whitebrickcornerne + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_corner_ne" + smooth = SMOOTH_FALSE + +/turf/closed/festive/whitebrick/whitebrickcornernw + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_corner_nw" + smooth = SMOOTH_FALSE + +/turf/closed/festive/whitebrick/whitebricktn + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_t_n" + smooth = SMOOTH_FALSE + +/turf/closed/festive/whitebrick/whitebrickts + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_t_s" + smooth = SMOOTH_FALSE + +/turf/closed/festive/whitebrick/whitebricktw + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_t_w" + smooth = SMOOTH_FALSE + +/turf/closed/festive/whitebrick/whitebrickte + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_t_e" + smooth = SMOOTH_FALSE + +/obj/structure/festive/whitebrick/windowdoorweend1 + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we_doorend_1" + density = TRUE + anchored = TRUE + +/obj/structure/festive/whitebrick/windowdoorweend2 + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we_doorend_2" + density = TRUE + anchored = TRUE + +/obj/structure/festive/whitebrick/windowdoornsend1 + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns_doorend_1" + density = TRUE + anchored = TRUE + +/obj/structure/festive/whitebrick/windowdoornsend2 + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns_doorend_2" + density = TRUE + anchored = TRUE + +/obj/structure/festive/whitebrick/windowWE + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we" + density = TRUE + anchored = TRUE + +/obj/structure/festive/whitebrick/windowWERight + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we_right" + density = TRUE + anchored = TRUE + +/obj/structure/festive/whitebrick/windowWERightEnd + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we_right_end" + canSmoothWith = list(/turf/closed/festive/whitebrick) + density = TRUE + anchored = TRUE + +/obj/structure/festive/whitebrick/windowWEMiddle + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we_middle" + density = TRUE + anchored = TRUE + +/obj/structure/festive/whitebrick/windowWELeft + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we_left" + density = TRUE + anchored = TRUE + +/obj/structure/festive/whitebrick/windowWELeftEnd + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we_left_end" + canSmoothWith = list(/turf/closed/festive/whitebrick) + density = TRUE + anchored = TRUE + +/obj/structure/festive/whitebrick/windowNS + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns" + density = TRUE + anchored = TRUE + +/obj/structure/festive/whitebrick/windowNSRight + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns_right" + density = TRUE + anchored = TRUE + +/obj/structure/festive/whitebrick/windowNSRightEnd + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns_right_end" + canSmoothWith = list(/turf/closed/festive/whitebrick) + density = TRUE + anchored = TRUE + +/obj/structure/festive/whitebrick/windowNSMiddle + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns_middle" + density = TRUE + anchored = TRUE + +/obj/structure/festive/whitebrick/windowNSLeft + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns_left" + density = TRUE + anchored = TRUE + +/obj/structure/festive/whitebrick/windowNSLeftEnd + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns_left_end" + canSmoothWith = list(/turf/closed/festive/whitebrick) + density = TRUE + anchored = TRUE + + +//Cream Bricks + +/turf/closed/festive/creambrick + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick" + smooth = SMOOTH_MORE + canSmoothWith = list(/turf/closed/festive/creambrick/creambrickte, /turf/closed/festive/creambrick/creambricktw, /turf/closed/festive/creambrick/creambrickts, /turf/closed/festive/creambrick/creambricktn, /turf/closed/festive/creambrick/creambrickcornernw, /turf/closed/festive/creambrick/creambrickcornerne, /turf/closed/festive/creambrick/creambrickcornersw, /turf/closed/festive/creambrick/creambrickcornerse, /turf/closed/festive/creambrick/creambrickwe, /turf/closed/festive/creambrick/creambrickns, /obj/structure/festive/creambrick/windowNSRightEnd, /obj/structure/festive/creambrick/windowNSLeftEnd, /turf/closed/festive/creambrick) + color = "#fff6cc" + +/turf/closed/festive/creambrick/creambrickns + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_wall_ns" + smooth = SMOOTH_FALSE + +/turf/closed/festive/creambrick/creambrickwe + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_wall_we" + smooth = SMOOTH_FALSE + +/turf/closed/festive/creambrick/creambrickcornerse + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_corner_se" + smooth = SMOOTH_FALSE + +/turf/closed/festive/creambrick/creambrickcornersw + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_corner_sw" + smooth = SMOOTH_FALSE + +/turf/closed/festive/creambrick/creambrickcornerne + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_corner_ne" + smooth = SMOOTH_FALSE + +/turf/closed/festive/creambrick/creambrickcornernw + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_corner_nw" + smooth = SMOOTH_FALSE + +/turf/closed/festive/creambrick/creambricktn + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_t_n" + smooth = SMOOTH_FALSE + +/turf/closed/festive/creambrick/creambrickts + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_t_s" + smooth = SMOOTH_FALSE + +/turf/closed/festive/creambrick/creambricktw + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_t_w" + smooth = SMOOTH_FALSE + +/turf/closed/festive/creambrick/creambrickte + name = "white brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/white_brick_wall.dmi' + icon_state = "white_brick_t_e" + smooth = SMOOTH_FALSE + +/obj/structure/festive/creambrick/windowdoorweend1 + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we_doorend_1" + density = TRUE + anchored = TRUE + +/obj/structure/festive/creambrick + color = "#fff6cc" + +/obj/structure/festive/creambrick/windowdoorweend2 + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we_doorend_2" + density = TRUE + anchored = TRUE + +/obj/structure/festive/creambrick/windowdoornsend1 + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns_doorend_1" + density = TRUE + anchored = TRUE + +/obj/structure/festive/creambrick/windowdoornsend2 + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns_doorend_2" + density = TRUE + anchored = TRUE + +/obj/structure/festive/creambrick/windowWE + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we" + density = TRUE + anchored = TRUE + +/obj/structure/festive/creambrick/windowWERight + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we_right" + density = TRUE + anchored = TRUE + +/obj/structure/festive/creambrick/windowWERightEnd + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we_right_end" + canSmoothWith = list(/turf/closed/festive/creambrick) + density = TRUE + anchored = TRUE + +/obj/structure/festive/creambrick/windowWEMiddle + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we_middle" + density = TRUE + anchored = TRUE + +/obj/structure/festive/creambrick/windowWELeft + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we_left" + density = TRUE + anchored = TRUE + +/obj/structure/festive/creambrick/windowWELeftEnd + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_we_left_end" + canSmoothWith = list(/turf/closed/festive/creambrick) + density = TRUE + anchored = TRUE + +/obj/structure/festive/creambrick/windowNS + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns" + density = TRUE + anchored = TRUE + +/obj/structure/festive/creambrick/windowNSRight + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns_right" + density = TRUE + anchored = TRUE + +/obj/structure/festive/creambrick/windowNSRightEnd + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns_right_end" + canSmoothWith = list(/turf/closed/festive/creambrick) + density = TRUE + anchored = TRUE + +/obj/structure/festive/creambrick/windowNSMiddle + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns_middle" + density = TRUE + anchored = TRUE + +/obj/structure/festive/creambrick/windowNSLeft + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns_left" + density = TRUE + anchored = TRUE + +/obj/structure/festive/creambrick/windowNSLeftEnd + name = "white window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/white_brick_window.dmi' + icon_state = "white_brick_window_ns_left_end" + canSmoothWith = list(/turf/closed/festive/creambrick) + density = TRUE + anchored = TRUE + +//Blue Bricks + + + +/turf/closed/festive/bluebrick + name = "blue brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/blue_brick_wall.dmi' + icon_state = "blue_brick" + smooth = SMOOTH_MORE + canSmoothWith = list(/turf/closed/festive/bluebrick/bluebrickte, /turf/closed/festive/bluebrick/bluebricktw, /turf/closed/festive/bluebrick/bluebrickts, /turf/closed/festive/bluebrick/bluebricktn, /turf/closed/festive/bluebrick/bluebrickcornernw, /turf/closed/festive/bluebrick/bluebrickcornerne, /turf/closed/festive/bluebrick/bluebrickcornersw, /turf/closed/festive/bluebrick/bluebrickcornerse, /turf/closed/festive/bluebrick/bluebrickwe, /turf/closed/festive/bluebrick/bluebrickns, /obj/structure/festive/bluebrick/windowNSRightEnd, /obj/structure/festive/bluebrick/windowNSLeftEnd, /turf/closed/festive/bluebrick) + +/turf/closed/festive/bluebrick/bluebrickns + name = "blue brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/blue_brick_wall.dmi' + icon_state = "blue_brick_wall_ns" + smooth = SMOOTH_FALSE + +/turf/closed/festive/bluebrick/bluebrickwe + name = "blue brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/blue_brick_wall.dmi' + icon_state = "blue_brick_wall_we" + smooth = SMOOTH_FALSE + +/turf/closed/festive/bluebrick/bluebrickcornerse + name = "blue brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/blue_brick_wall.dmi' + icon_state = "blue_brick_corner_se" + smooth = SMOOTH_FALSE + +/turf/closed/festive/bluebrick/bluebrickcornersw + name = "blue brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/blue_brick_wall.dmi' + icon_state = "blue_brick_corner_sw" + smooth = SMOOTH_FALSE + +/turf/closed/festive/bluebrick/bluebrickcornerne + name = "blue brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/blue_brick_wall.dmi' + icon_state = "blue_brick_corner_ne" + smooth = SMOOTH_FALSE + +/turf/closed/festive/bluebrick/bluebrickcornernw + name = "blue brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/blue_brick_wall.dmi' + icon_state = "blue_brick_corner_nw" + smooth = SMOOTH_FALSE + +/turf/closed/festive/bluebrick/bluebricktn + name = "blue brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/blue_brick_wall.dmi' + icon_state = "blue_brick_t_n" + smooth = SMOOTH_FALSE + +/turf/closed/festive/bluebrick/bluebrickts + name = "blue brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/blue_brick_wall.dmi' + icon_state = "blue_brick_t_s" + smooth = SMOOTH_FALSE + +/turf/closed/festive/bluebrick/bluebricktw + name = "blue brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/blue_brick_wall.dmi' + icon_state = "blue_brick_t_w" + smooth = SMOOTH_FALSE + +/turf/closed/festive/bluebrick/bluebrickte + name = "blue brick wall" + desc = "A brick wall, intricately built up." + icon = 'modular_citadel/code/modules/festive/blue_brick_wall.dmi' + icon_state = "blue_brick_t_e" + smooth = SMOOTH_FALSE + +/obj/structure/festive/bluebrick/windowdoorweend1 + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_we_doorend_1" + density = TRUE + anchored = TRUE + +/obj/structure/festive/bluebrick/windowdoorweend2 + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_we_doorend_2" + density = TRUE + anchored = TRUE + +/obj/structure/festive/bluebrick/windowdoornsend1 + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_ns_doorend_1" + density = TRUE + anchored = TRUE + +/obj/structure/festive/bluebrick/windowdoornsend2 + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_ns_doorend_2" + density = TRUE + anchored = TRUE + +/obj/structure/festive/bluebrick/windowWE + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_we" + density = TRUE + anchored = TRUE + +/obj/structure/festive/bluebrick/windowWERight + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_we_right" + density = TRUE + anchored = TRUE + +/obj/structure/festive/bluebrick/windowWERightEnd + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_we_right_end" + canSmoothWith = list(/turf/closed/festive/bluebrick) + density = TRUE + anchored = TRUE + +/obj/structure/festive/bluebrick/windowWEMiddle + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_we_middle" + density = TRUE + anchored = TRUE + +/obj/structure/festive/bluebrick/windowWELeft + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_we_left" + density = TRUE + anchored = TRUE + +/obj/structure/festive/bluebrick/windowWELeftEnd + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_we_left_end" + canSmoothWith = list(/turf/closed/festive/bluebrick) + density = TRUE + anchored = TRUE + +/obj/structure/festive/bluebrick/windowNS + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_ns" + density = TRUE + anchored = TRUE + +/obj/structure/festive/bluebrick/windowNSRight + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_ns_right" + density = TRUE + anchored = TRUE + +/obj/structure/festive/bluebrick/windowNSRightEnd + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_ns_right_end" + canSmoothWith = list(/turf/closed/festive/bluebrick) + density = TRUE + anchored = TRUE + +/obj/structure/festive/bluebrick/windowNSMiddle + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_ns_middle" + density = TRUE + anchored = TRUE + +/obj/structure/festive/bluebrick/windowNSLeft + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_ns_left" + density = TRUE + anchored = TRUE + +/obj/structure/festive/bluebrick/windowNSLeftEnd + name = "blue window" + desc = "A brick wall, intricately built up. Comes with a window." + icon = 'modular_citadel/code/modules/festive/blue_brick_window.dmi' + icon_state = "blue_brick_window_ns_left_end" + canSmoothWith = list(/turf/closed/festive/bluebrick) + density = TRUE + anchored = TRUE + + + +//Panel Walls + + + +//Grey Paneled Walls + + + +/turf/closed/festive/greypanel + name = "grey panel wall" + desc = "A panel wall, with horizontal sidings." + icon = 'modular_citadel/code/modules/festive/grey_panel_wall.dmi' + icon_state = "grey_panel" + smooth = SMOOTH_MORE + canSmoothWith = list(/turf/closed/festive/greypanel/greypanelte, /turf/closed/festive/greypanel/greypaneltw, /turf/closed/festive/greypanel/greypanelts, /turf/closed/festive/greypanel/greypaneltn, /turf/closed/festive/greypanel/greypanelcornernw, /turf/closed/festive/greypanel/greypanelcornerne, /turf/closed/festive/greypanel/greypanelcornersw, /turf/closed/festive/greypanel/greypanelcornerse, /turf/closed/festive/greypanel/greypanelwe, /turf/closed/festive/greypanel/greypanelns, /turf/closed/festive/greypanel) + +/turf/closed/festive/greypanel/greypanelns + name = "grey panel wall" + desc = "A panel wall, with horizontal sidings." + icon = 'modular_citadel/code/modules/festive/grey_panel_wall.dmi' + icon_state = "grey_panel_wall_ns" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greypanel/greypanelwe + name = "grey panel wall" + desc = "A panel wall, with horizontal sidings." + icon = 'modular_citadel/code/modules/festive/grey_panel_wall.dmi' + icon_state = "grey_panel_wall_we" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greypanel/greypanelcornerse + name = "grey panel wall" + desc = "A panel wall, with horizontal sidings." + icon = 'modular_citadel/code/modules/festive/grey_panel_wall.dmi' + icon_state = "grey_panel_corner_se" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greypanel/greypanelcornersw + name = "grey panel wall" + desc = "A panel wall, with horizontal sidings." + icon = 'modular_citadel/code/modules/festive/grey_panel_wall.dmi' + icon_state = "grey_panel_corner_sw" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greypanel/greypanelcornerne + name = "grey panel wall" + desc = "A panel wall, with horizontal sidings." + icon = 'modular_citadel/code/modules/festive/grey_panel_wall.dmi' + icon_state = "grey_panel_corner_ne" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greypanel/greypanelcornernw + name = "grey panel wall" + desc = "A panel wall, with horizontal sidings." + icon = 'modular_citadel/code/modules/festive/grey_panel_wall.dmi' + icon_state = "grey_panel_corner_nw" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greypanel/greypaneltn + name = "grey panel wall" + desc = "A panel wall, with horizontal sidings." + icon = 'modular_citadel/code/modules/festive/grey_panel_wall.dmi' + icon_state = "grey_panel_t_n" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greypanel/greypanelts + name = "grey panel wall" + desc = "A panel wall, with horizontal sidings." + icon = 'modular_citadel/code/modules/festive/grey_panel_wall.dmi' + icon_state = "grey_panel_t_s" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greypanel/greypaneltw + name = "grey panel wall" + desc = "A panel wall, with horizontal sidings." + icon = 'modular_citadel/code/modules/festive/grey_panel_wall.dmi' + icon_state = "grey_panel_t_w" + smooth = SMOOTH_FALSE + +/turf/closed/festive/greypanel/greypanelte + name = "grey panel wall" + desc = "A panel wall, with horizontal sidings." + icon = 'modular_citadel/code/modules/festive/grey_panel_wall.dmi' + icon_state = "grey_panel_t_e" + smooth = SMOOTH_FALSE + +//Train Decals + +/obj/effect/festive/trainrails/north + name = "trainrail north" + icon = 'modular_citadel/code/modules/festive/rails.dmi' + icon_state = "trainrails_north" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/trainrails/south + name = "trainrail south" + icon = 'modular_citadel/code/modules/festive/rails.dmi' + icon_state = "trainrails_south" + layer = TURF_DECAL_LAYER + +//Streets Decals + +/obj/effect/festive/street/streetlinewest + name = "street line west" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_w" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlineeast + name = "street line east" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_e" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlinesouth + name = "street line south" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_s" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlinenorth + name = "street line north" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_n" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlinesw + name = "street line southwest" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_sw" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlinese + name = "street line southeast" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_se" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlinene + name = "street line northeast" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_ne" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlinenw + name = "street line northwest" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_nw" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlineinnernw + name = "street line inner northwest" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_inner_nw" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlineinnerne + name = "street line inner northeast" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_inner_ne" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlineinnersw + name = "street line inner southwest" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_inner_sw" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlineinnerse + name = "street line inner southeast" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_inner_se" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlinemns + name = "street line middle northsouth" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_m_ns" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlinemwe + name = "street line middle westeast" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_m_we" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlinewm + name = "street line west middle" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_wm" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlineem + name = "street line east middle" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_em" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlinenm + name = "street line north middle" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_nm" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetlinesm + name = "street line south middle" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_line_sm" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetliftedtile1 + name = "street tile lifted" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_lifted_tile_1" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/streetliftedtile2 + name = "street tile lifted" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "street_lifted_tile_2" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/sidewalkw + name = "street walk west" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "side_walk_w" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/sidewalke + name = "street walk east" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "side_walk_e" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/sidewalkn + name = "street walk north" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "side_walk_n" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/sidewalks + name = "street walk south" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "side_walk_s" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/sidewalknsm + name = "street walk middle ns" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "side_walk_nsm" + layer = TURF_DECAL_LAYER + +/obj/effect/festive/street/sidewalkwem + name = "street walk middle we" + icon = 'modular_citadel/code/modules/festive/streetdecals.dmi' + icon_state = "side_walk_wem" + layer = TURF_DECAL_LAYER + + + +//train platform stuff +//I know, this is stupid of me to do, but it's all I could get working with my brain + +/obj/structure/festive/trainplatform/edge_north + name = "train platform" + icon = 'modular_citadel/code/modules/festive/trainplatformedges.dmi' + icon_state = "edge_north" + anchored = TRUE + density = TRUE + layer = ABOVE_OBJ_LAYER //Just above doors + flags_1 = ON_BORDER_1 + var/reinf = FALSE + var/ini_dir = null + var/fulltile = FALSE + CanAtmosPass = ATMOS_PASS_PROC + +/obj/structure/festive/trainplatform/edge_north/Initialize(mapload, direct) + . = ..() + if(direct) + setDir(direct) + + ini_dir = dir + air_update_turf(1) + +/obj/structure/festive/trainplatform/edge_north/setDir(direct) + if(!fulltile) + ..() + else + ..(FULLTILE_WINDOW_DIR) + +/obj/structure/festive/trainplatform/edge_north/CanPass(atom/movable/mover, turf/target) + if(istype(mover) && (mover.pass_flags & PASSGLASS)) + return 1 + if(dir == FULLTILE_WINDOW_DIR) + return 0 + if(get_dir(loc, target) == dir) + return !density + if(istype(mover, /obj/structure/festive/trainplatform/edge_north)) + var/obj/structure/window/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/structure/windoor_assembly)) + var/obj/structure/festive/trainplatform/edge_north/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir)) + return FALSE + return 1 + +/obj/structure/festive/trainplatform/edge_north/CheckExit(atom/movable/O, turf/target) + if(istype(O) && (O.pass_flags & PASSGLASS)) + return 1 + if(get_dir(O.loc, target) == dir) + return 0 + return 1 + +/obj/structure/festive/trainplatform/edge_north + dir = SOUTH + + + +/obj/structure/festive/trainplatform/edge_south + name = "train platform" + icon = 'modular_citadel/code/modules/festive/trainplatformedges.dmi' + icon_state = "edge_south" + anchored = TRUE + density = TRUE + layer = ABOVE_OBJ_LAYER //Just above doors + flags_1 = ON_BORDER_1 + var/reinf = FALSE + var/ini_dir = null + var/fulltile = FALSE + CanAtmosPass = ATMOS_PASS_PROC + +/obj/structure/festive/trainplatform/edge_south/Initialize(mapload, direct) + . = ..() + if(direct) + setDir(direct) + + ini_dir = dir + air_update_turf(1) + +/obj/structure/festive/trainplatform/edge_south/setDir(direct) + if(!fulltile) + ..() + else + ..(FULLTILE_WINDOW_DIR) + +/obj/structure/festive/trainplatform/edge_south/CanPass(atom/movable/mover, turf/target) + if(istype(mover) && (mover.pass_flags & PASSGLASS)) + return 1 + if(dir == FULLTILE_WINDOW_DIR) + return 0 + if(get_dir(loc, target) == dir) + return !density + if(istype(mover, /obj/structure/festive/trainplatform/edge_south)) + var/obj/structure/window/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/structure/windoor_assembly)) + var/obj/structure/festive/trainplatform/edge_south/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir)) + return FALSE + return 1 + +/obj/structure/festive/trainplatform/edge_north/CheckExit(atom/movable/O, turf/target) + if(istype(O) && (O.pass_flags & PASSGLASS)) + return 1 + if(get_dir(O.loc, target) == dir) + return 0 + return 1 + +/obj/structure/festive/trainplatform/edge_south + dir = NORTH + + + +/obj/structure/festive/trainplatform/edge_east + name = "train platform" + icon = 'modular_citadel/code/modules/festive/trainplatformedges.dmi' + icon_state = "edge_east" + anchored = TRUE + density = TRUE + layer = ABOVE_OBJ_LAYER //Just above doors + flags_1 = ON_BORDER_1 + var/reinf = FALSE + var/ini_dir = null + var/fulltile = FALSE + CanAtmosPass = ATMOS_PASS_PROC + +/obj/structure/festive/trainplatform/edge_east/Initialize(mapload, direct) + . = ..() + if(direct) + setDir(direct) + + ini_dir = dir + air_update_turf(1) + +/obj/structure/festive/trainplatform/edge_east/setDir(direct) + if(!fulltile) + ..() + else + ..(FULLTILE_WINDOW_DIR) + +/obj/structure/festive/trainplatform/edge_east/CanPass(atom/movable/mover, turf/target) + if(istype(mover) && (mover.pass_flags & PASSGLASS)) + return 1 + if(dir == FULLTILE_WINDOW_DIR) + return 0 + if(get_dir(loc, target) == dir) + return !density + if(istype(mover, /obj/structure/festive/trainplatform/edge_east)) + var/obj/structure/window/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/structure/windoor_assembly)) + var/obj/structure/festive/trainplatform/edge_east/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir)) + return FALSE + return 1 + +/obj/structure/festive/trainplatform/edge_east/CheckExit(atom/movable/O, turf/target) + if(istype(O) && (O.pass_flags & PASSGLASS)) + return 1 + if(get_dir(O.loc, target) == dir) + return 0 + return 1 + +/obj/structure/festive/trainplatform/edge_east + dir = WEST + + + +/obj/structure/festive/trainplatform/edge_west + name = "train platform" + icon = 'modular_citadel/code/modules/festive/trainplatformedges.dmi' + icon_state = "edge_west" + anchored = TRUE + density = TRUE + layer = ABOVE_OBJ_LAYER //Just above doors + flags_1 = ON_BORDER_1 + var/reinf = FALSE + var/ini_dir = null + var/fulltile = FALSE + CanAtmosPass = ATMOS_PASS_PROC + +/obj/structure/festive/trainplatform/edge_west/Initialize(mapload, direct) + . = ..() + if(direct) + setDir(direct) + + ini_dir = dir + air_update_turf(1) + +/obj/structure/festive/trainplatform/edge_west/setDir(direct) + if(!fulltile) + ..() + else + ..(FULLTILE_WINDOW_DIR) + +/obj/structure/festive/trainplatform/edge_west/CanPass(atom/movable/mover, turf/target) + if(istype(mover) && (mover.pass_flags & PASSGLASS)) + return 1 + if(dir == FULLTILE_WINDOW_DIR) + return 0 + if(get_dir(loc, target) == dir) + return !density + if(istype(mover, /obj/structure/festive/trainplatform/edge_west)) + var/obj/structure/window/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/structure/windoor_assembly)) + var/obj/structure/festive/trainplatform/edge_west/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir)) + return FALSE + return 1 + +/obj/structure/festive/trainplatform/edge_west/CheckExit(atom/movable/O, turf/target) + if(istype(O) && (O.pass_flags & PASSGLASS)) + return 1 + if(get_dir(O.loc, target) == dir) + return 0 + return 1 + +/obj/structure/festive/trainplatform/edge_west + dir = EAST + +/obj/structure/festive/trainplatform/necorner + name = "train platform" + icon = 'modular_citadel/code/modules/festive/trainplatformedges.dmi' + icon_state = "ne_corner" + anchored = TRUE + +/obj/structure/festive/trainplatform/nwcorner + name = "train platform" + icon = 'modular_citadel/code/modules/festive/trainplatformedges.dmi' + icon_state = "nw_corner" + anchored = TRUE + +/obj/structure/festive/trainplatform/secorner + name = "train platform" + icon = 'modular_citadel/code/modules/festive/trainplatformedges.dmi' + icon_state = "se_corner" + anchored = TRUE + +/obj/structure/festive/trainplatform/swcorner + name = "train platform" + icon = 'modular_citadel/code/modules/festive/trainplatformedges.dmi' + icon_state = "sw_corner" + anchored = TRUE diff --git a/modular_citadel/code/modules/festive/wheelchair.dm b/modular_citadel/code/modules/festive/wheelchair.dm new file mode 100644 index 0000000000..80f9156cdd --- /dev/null +++ b/modular_citadel/code/modules/festive/wheelchair.dm @@ -0,0 +1,114 @@ +/obj/vehicle/sealed/vectorcraft/rideable/Initialize(mapload) + . = ..() + +/obj/vehicle/sealed/vectorcraft/rideable/post_unbuckle_mob(mob/living/M) + remove_occupant(M) + M.pixel_x = 0 + M.pixel_y = 0 + return ..() + +/obj/vehicle/sealed/vectorcraft/rideable/post_buckle_mob(mob/living/M) + add_occupant(M) + return ..() + +/obj/vehicle/sealed/vectorcraft/rideable/move_car() + .=..() + driver.pixel_x = pixel_x + driver.pixel_y = pixel_y + driver.forceMove(src.loc) + driver.setDir(dir) + +/obj/vehicle/sealed/vectorcraft/rideable/mob_enter(mob/living/M) + if(!istype(M)) + return FALSE + M.visible_message("[M] climbs into \the [src]!") + M.forceMove(src.loc) + add_occupant(M) + if(!driver) + driver = M + if(gear != "auto") + gear = driver.a_intent + start_engine() + driver.pixel_x = pixel_x + driver.pixel_y = pixel_y + return TRUE + +/obj/vehicle/sealed/vectorcraft/rideable/mob_exit(mob/living/M) + .=..() + driver.pixel_x = 0 + driver.pixel_y = 0 + +/obj/vehicle/sealed/vectorcraft/rideable/wheelchair + name = "Hoverchair" + desc = "A chair with big hoverpads. It looks like you can move in this on your own." + icon = 'icons/obj/vehicles.dmi' + icon_state = "wheelchair" + layer = OBJ_LAYER + max_integrity = 100 + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 20, ACID = 30) //Wheelchairs aren't super tough yo + canmove = TRUE + density = FALSE //Thought I couldn't fix this one easily, phew + + + max_acceleration = 1.5 + accel_step = 0.5 + acceleration = 0.35 + max_deceleration = 1 + max_velocity = 20 + boost_power = 15 + gear = "auto" + +/obj/vehicle/sealed/vectorcraft/rideable/wheelchair/ComponentInitialize() //Since it's technically a chair I want it to have chair properties + . = ..() + AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE, CALLBACK(src, .proc/can_user_rotate),CALLBACK(src, .proc/can_be_rotated),null) + + +/obj/vehicle/sealed/vectorcraft/rideable/wheelchair/Destroy() + if(has_buckled_mobs()) + var/mob/living/carbon/H = buckled_mobs[1] + unbuckle_mob(H) + return ..() + +/obj/vehicle/sealed/vectorcraft/rideable/wheelchair/move_car() + . = ..() + cut_overlays() + playsound(src, 'sound/effects/roll.ogg', 75, 1) + if(has_buckled_mobs()) + handle_rotation_overlayed() + +/obj/vehicle/sealed/vectorcraft/rideable/wheelchair/post_buckle_mob(mob/living/user) + . = ..() + handle_rotation_overlayed() + +/obj/vehicle/sealed/vectorcraft/rideable/wheelchair/post_unbuckle_mob() + . = ..() + cut_overlays() + +/obj/vehicle/sealed/vectorcraft/rideable/wheelchair/setDir(newdir) + ..() + handle_rotation(newdir) + +/obj/vehicle/sealed/vectorcraft/rideable/wheelchair/proc/handle_rotation(direction) + if(has_buckled_mobs()) + handle_rotation_overlayed() + for(var/m in buckled_mobs) + var/mob/living/buckled_mob = m + buckled_mob.setDir(direction) + +/obj/vehicle/sealed/vectorcraft/rideable/wheelchair/proc/handle_rotation_overlayed() + cut_overlays() + var/image/V = image(icon = icon, icon_state = "wheelchair_overlay", layer = FLY_LAYER, dir = src.dir) + add_overlay(V) + + +/obj/vehicle/sealed/vectorcraft/rideable/wheelchair/proc/can_be_rotated(mob/living/user) + return TRUE + +/obj/vehicle/sealed/vectorcraft/rideable/wheelchair/proc/can_user_rotate(mob/living/user) + var/mob/living/L = driver + if(istype(L)) + if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return FALSE + if(isobserver(user) && CONFIG_GET(flag/ghost_interaction)) + return TRUE + return FALSE diff --git a/modular_citadel/code/modules/festive/white_alleywaybricks.dmi b/modular_citadel/code/modules/festive/white_alleywaybricks.dmi new file mode 100644 index 0000000000..c5026661e3 Binary files /dev/null and b/modular_citadel/code/modules/festive/white_alleywaybricks.dmi differ diff --git a/modular_citadel/code/modules/festive/white_brick_wall.dmi b/modular_citadel/code/modules/festive/white_brick_wall.dmi new file mode 100644 index 0000000000..67784e5771 Binary files /dev/null and b/modular_citadel/code/modules/festive/white_brick_wall.dmi differ diff --git a/modular_citadel/code/modules/festive/white_brick_window.dmi b/modular_citadel/code/modules/festive/white_brick_window.dmi new file mode 100644 index 0000000000..3477e00839 Binary files /dev/null and b/modular_citadel/code/modules/festive/white_brick_window.dmi differ diff --git a/modular_citadel/code/modules/festive/wooden.dmi b/modular_citadel/code/modules/festive/wooden.dmi new file mode 100644 index 0000000000..34cdae85b2 Binary files /dev/null and b/modular_citadel/code/modules/festive/wooden.dmi differ diff --git a/modular_citadel/code/modules/mentor/mentor_memo.dm b/modular_citadel/code/modules/mentor/mentor_memo.dm index 59ea92febd..c64101c30e 100644 --- a/modular_citadel/code/modules/mentor/mentor_memo.dm +++ b/modular_citadel/code/modules/mentor/mentor_memo.dm @@ -94,7 +94,7 @@ var/datum/db_query/update_query = SSdbcore.NewQuery({" UPDATE [format_table_name("mentor_memo")] SET memotext = :new_memo, last_editor = :ckey, edits = :edit_text WHERE ckey = :target_ckey - "}, list("new_memo" = new_memo, "ckey" = ckey, "edit_text" = (edit_text ? "" : edit_text), "target_ckey" = target_ckey)) + "}, list("new_memo" = new_memo, "ckey" = ckey, "edit_text" = (edit_text || ""), "target_ckey" = target_ckey)) if(!update_query.Execute()) var/err = update_query.ErrorMsg() qdel(update_query) diff --git a/modular_citadel/code/modules/mob/cit_emotes.dm b/modular_citadel/code/modules/mob/cit_emotes.dm index 0adb12e5a1..8a6643d239 100644 --- a/modular_citadel/code/modules/mob/cit_emotes.dm +++ b/modular_citadel/code/modules/mob/cit_emotes.dm @@ -77,7 +77,8 @@ restraint_check = TRUE /datum/emote/living/snap/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -93,7 +94,8 @@ restraint_check = TRUE /datum/emote/living/snap2/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -109,7 +111,8 @@ restraint_check = TRUE /datum/emote/living/snap3/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -125,7 +128,8 @@ restraint_check = FALSE /datum/emote/living/awoo/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -141,7 +145,8 @@ restraint_check = FALSE /datum/emote/living/hiss/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -157,7 +162,8 @@ restraint_check = FALSE /datum/emote/living/meow/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -173,7 +179,8 @@ restraint_check = FALSE /datum/emote/living/purr/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -189,7 +196,8 @@ restraint_check = FALSE /datum/emote/living/nya/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -205,7 +213,8 @@ restraint_check = FALSE /datum/emote/living/weh/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -221,7 +230,8 @@ restraint_check = FALSE /datum/emote/living/peep/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -244,7 +254,8 @@ restraint_check = FALSE /datum/emote/living/mothsqueak/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -260,7 +271,8 @@ restraint_check = FALSE /datum/emote/living/merp/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -276,7 +288,8 @@ restraint_check = FALSE /datum/emote/living/bark/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -293,7 +306,8 @@ restraint_check = FALSE /datum/emote/living/squish/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -310,7 +324,8 @@ restraint_check = FALSE /datum/emote/living/pain/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return if(user.nextsoundemote >= world.time) return @@ -331,6 +346,7 @@ restraint_check = TRUE /datum/emote/living/clap1/run_emote(mob/living/user, params) - if(!(. = ..())) + . = ..() + if(!.) return playsound(user, 'modular_citadel/sound/voice/clap.ogg', 50, 1, -1) diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm index f66c0289b6..bdbed07fb1 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm @@ -135,14 +135,14 @@ Creating a chem with a low purity will make you permanently fall in love with so color = "#660015" // rgb: , 0, 255 taste_description = "synthetic chocolate, a base tone of alcohol, and high notes of roses" overdose_threshold = 100 //If this is too easy to get 100u of this, then double it please. - metabolization_rate = 0.1//It has to be slow, so there's time for the effect. + metabolization_rate = 0.25 * REAGENTS_METABOLISM//It has to be slow, so there's time for the effect. data = list("creatorID" = null, "creatorGender" = null, "creatorName" = null) var/creatorID //ckey var/creatorGender var/creatorName var/mob/living/creator pH = 10 - chemical_flags = REAGENT_ONMOBMERGE | REAGENT_DONOTSPLIT //Procs on_mob_add when merging into a human + chemical_flags = REAGENT_ONMOBMERGE | REAGENT_DONOTSPLIT | REAGENT_ALL_PROCESS //Procs on_mob_add when merging into a human can_synth = FALSE value = REAGENT_VALUE_EXCEPTIONAL @@ -266,55 +266,20 @@ Creating a chem with a low purity will make you permanently fall in love with so //Creates a gas cloud when the reaction blows up, causing everyone in it to fall in love with someone/something while it's in their system. /datum/reagent/fermi/enthrallExplo//Created in a gas cloud when it explodes name = "Gaseous MKUltra" - description = "A forbidden deep red gas that overwhelms a foreign body, causing the person they next lay their eyes on to become more interesting. Studies have shown that people are 66% more likely to make friends with this in the air. Produced when MKUltra explodes." + description = "A deep red gas that when taken into a body, the recipient will experience a high and reduced control in their body for as long as it is in their system. Produced when MKUltra explodes." color = "#2C051A" // rgb: , 0, 255 - metabolization_rate = 0.1 - taste_description = "synthetic chocolate, a base tone of alcohol, and high notes of roses." - chemical_flags = REAGENT_DONOTSPLIT + metabolization_rate = 1 + taste_description = "extremely bitter chocolate" + chemical_flags = REAGENT_DONOTSPLIT | REAGENT_ORGANIC_PROCESS can_synth = FALSE - var/mob/living/carbon/love - var/lewd = FALSE -/datum/reagent/fermi/enthrallExplo/on_mob_life(mob/living/carbon/M)//Love gas, only affects while it's in your system,Gives a positive moodlet if close, gives brain damagea and a negative moodlet if not close enough. - if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) - return ..() - if(!M.has_status_effect(STATUS_EFFECT_INLOVE)) - var/list/seen = (M.fov_view(M.client?.view || world.view) - M) | viewers(M.client?.view || world.view, M) - for(var/victim in seen) - if((isanimal(victim)) || (!isliving(victim))) - seen -= victim - if(!length(seen)) - return - love = pick(seen) - M.apply_status_effect(STATUS_EFFECT_INLOVE, love) - lewd = (M.client?.prefs.cit_toggles & HYPNO) && (love.client?.prefs.cit_toggles & HYPNO) - to_chat(M, "[(lewd?"":"")][(lewd?"You develop a sudden crush on [love], your heart beginning to race as you look upon them with new eyes.":"You suddenly feel like making friends with [love].")] You feel strangely drawn towards them.") - log_reagent("FERMICHEM: [M] ckey: [M.key] has temporarily bonded with [love] ckey: [love.key]") - SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times people have bonded") - else - if(get_dist(M, love) < 8) - var/message = "[(lewd?"I'm next to my crush..! Eee!":"I'm making friends with [love]!")]" - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "InLove", /datum/mood_event/InLove, message) - SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "MissingLove") - else - var/message = "[(lewd?"I can't keep my crush off my mind, I need to see them again!":"I really want to make friends with [love]!")]" - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "MissingLove", /datum/mood_event/MissingLove, message) - SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "InLove") - if(prob(5)) - M.Stun(10) - M.emote("whimper")//does this exist? - to_chat(M, "[(lewd?"":"")] You're overcome with a desire to see [love].") - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5)//I found out why everyone was so damaged! - ..() - -/datum/reagent/fermi/enthrallExplo/on_mob_delete(mob/living/carbon/M) - if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) - return ..() - M.remove_status_effect(STATUS_EFFECT_INLOVE) - SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "InLove") - SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "MissingLove") - to_chat(M, "[(lewd?"":"")]Your feelings for [love] suddenly vanish!") - log_reagent("FERMICHEM: [M] ckey: [M.key] is no longer in temp bond") +/datum/reagent/fermi/enthrallExplo/on_mob_life(mob/living/carbon/M) //Drug them, jitter them, dizzy them, confuse them + M.Dizzy(5) + M.Jitter(5) + M.set_drugginess(15) + if(!M.confused) + M.confused = 1 + M.confused = max(M.confused, 20) ..() /datum/reagent/fermi/proc/FallInLove(mob/living/carbon/Lover, mob/living/carbon/Love) diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm index 3725e46b38..0c62637d37 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm @@ -169,17 +169,17 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING if(21) to_chat(M, "You feel the synethic cells rest uncomfortably within your body as they start to pulse and grow rapidly.") if(22 to 29) - M.adjust_nutrition(M.nutrition/10) + M.adjust_nutrition(10) if(30) to_chat(M, "You feel the synethic cells grow and expand within yourself, bloating your body outwards.") if(31 to 49) - M.adjust_nutrition(M.nutrition/5) + M.adjust_nutrition(20) if(50) to_chat(M, "The synthetic cells begin to merge with your body, it feels like your body is made of a viscous water, making your movements difficult.") M.action_cooldown_mod += 4//If this makes you fast then please fix it, it should make you slow!! //candidates = pollGhostCandidates("Do you want to play as a clone of [M.name] and do you agree to respect their character and act in a similar manner to them? I swear to god if you diddle them I will be very disapointed in you. ", "FermiClone", null, ROLE_SENTIENCE, 300) // see poll_ignore.dm, should allow admins to ban greifers or bullies if(51 to 79) - M.adjust_nutrition(M.nutrition/2) + M.adjust_nutrition(50) if(80) to_chat(M, "The cells begin to precipitate outwards of your body, you feel like you'll split soon...") if (M.nutrition < 20000) @@ -304,6 +304,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING /datum/reagent/fermi/SDGFheal name = "synthetic-derived healing factor" description = "Leftover SDGF is transferred into the resulting clone, which quickly heals up the stresses from suddenly splitting. Restores blood, nutrition, and repaires brain and clone damage quickly. Only obtainable from using excess SDGF, and only enters the cloned body." + taste_description = "slime" metabolization_rate = 0.8 can_synth = FALSE @@ -336,7 +337,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING var/startHunger can_synth = TRUE taste_description = "a weird chemical fleshy flavour" - chemical_flags = REAGENT_SNEAKYNAME + chemical_flags = REAGENT_SNEAKYNAME | REAGENT_ALL_PROCESS value = REAGENT_VALUE_RARE /datum/reagent/impure/SDZF/on_mob_life(mob/living/carbon/M) //If you're bad at fermichem, turns your clone into a zombie instead. diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm index bdc599a5e2..2be1a97873 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm @@ -163,7 +163,7 @@ I'd like to point out from my calculations it'll take about 60-80 minutes to die if(-INFINITY to 30) to_chat(M, "Your body disperses from existence, as you become one with the universe.") to_chat(M, "As your body disappears, your consciousness doesn't. Should you find a way back into the mortal coil, your memories of your previous life remain with you. (At the cost of staying in character while dead. Failure to do this may get you banned from this chem. You are still obligated to follow your directives if you play a midround antag, you do not remember the afterlife IC)")//Legalised IC OOK? I have a suspicion this won't make it past the review. At least it'll be presented as a neat idea! If this is unacceptable how about the player can retain living memories across lives if they die in this way only. - deadchat_broadcast("[M] has become one with the universe, meaning that their IC conciousness is continuous in a new life. If they find a way back to life, they are allowed to remember their previous life. Be careful what you say. If they abuse this, bwoink the FUCK outta them.") + deadchat_broadcast(" has become one with the universe, meaning that their IC conciousness is continuous in a new life. If they find a way back to life, they are allowed to remember their previous life. Be careful what you say. If they abuse this, bwoink the FUCK outta them.", "[M]", M, message_type=DEADCHAT_ANNOUNCEMENT) M.visible_message("[M] suddenly disappears, their body evaporating from existence, freeing [M] from their mortal coil.") message_admins("[M] (ckey: [M.ckey]) has become one with the universe, and have continuous memories thoughout their lives should they find a way to come back to life (such as an inteligence potion, midround antag, ghost role).") SSblackbox.record_feedback("tally", "fermi_chem", 1, "Astral obliterations") diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/eigentstasium.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/eigentstasium.dm index 40077cd02a..d26eb088ea 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/eigentstasium.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/eigentstasium.dm @@ -12,7 +12,7 @@ /datum/reagent/fermi/eigenstate name = "Eigenstasium" description = "A strange mixture formed from a controlled reaction of bluespace with plasma, that causes localised eigenstate fluxuations within the patient" - taste_description = "wiggly cosmic dust." + taste_description = "wiggly cosmic dust" color = "#5020F4" // rgb: 50, 20, 255 overdose_threshold = 15 addiction_threshold = 15 diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm index 1265fb1769..1296e7d686 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm @@ -22,7 +22,7 @@ name = "Succubus milk" description = "A volatile collodial mixture derived from milk that encourages mammary production via a potent estrogen mix." color = "#E60584" // rgb: 96, 0, 255 - taste_description = "a milky ice cream like flavour." + taste_description = "a milky ice cream like flavour" overdose_threshold = 17 metabolization_rate = 0.25 impure_chem = /datum/reagent/fermi/BEsmaller //If you make an inpure chem, it stalls growth @@ -37,7 +37,7 @@ if(volume >= 15) //To prevent monkey breast farms var/turf/T = get_turf(M) var/obj/item/organ/genital/breasts/B = new /obj/item/organ/genital/breasts(T) - M.visible_message("A pair of breasts suddenly fly out of the [M]!") + M.visible_message("A pair of breasts suddenly fly out of [M]!") var/T2 = get_random_station_turf() M.adjustBruteLoss(25) M.DefaultCombatKnockdown(50) @@ -106,7 +106,7 @@ name = "Modesty milk" description = "A volatile collodial mixture derived from milk that encourages mammary reduction via a potent estrogen mix. Produced by reacting impure Succubus milk." color = "#E60584" // rgb: 96, 0, 255 - taste_description = "a milky ice cream like flavour." + taste_description = "a milky ice cream like flavour" metabolization_rate = 0.25 can_synth = FALSE value = REAGENT_VALUE_RARE @@ -121,7 +121,7 @@ /datum/reagent/fermi/BEsmaller_hypo name = "Rectify milk" //Rectify color = "#E60584" - taste_description = "a milky ice cream like flavour." + taste_description = "a milky ice cream like flavour" metabolization_rate = 0.25 description = "A medicine used to treat organomegaly in a patient's breasts." var/sizeConv = list("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5) @@ -175,7 +175,7 @@ if(volume >= 15) //to prevent monkey penis farms var/turf/T = get_turf(M) var/obj/item/organ/genital/penis/P = new /obj/item/organ/genital/penis(T) - M.visible_message("A penis suddenly flies out of the [M]!") + M.visible_message("A penis suddenly flies out of [M]!") var/T2 = get_random_station_turf() M.adjustBruteLoss(25) M.DefaultCombatKnockdown(50) @@ -283,3 +283,87 @@ else if(P.length < optimal_size) P.modify_size(0.1, 0, optimal_size) return ..() + + + +///Ass enhancer +/datum/reagent/fermi/butt_enlarger + name = "Denbu Tincture" //on Hyper it was 'Denbu Draft' but this makes it more consistent with the rectifying chemical down below. + description = "A mixture of natural vitamins and valentines plant extract, causing butt enlargement in humanoids." + color = "#e8ff1b" + taste_description = "butter with a sweet aftertaste" //pass me the butter, OM NOM + overdose_threshold = 17 + can_synth = FALSE + +/datum/reagent/fermi/butt_enlarger/on_mob_metabolize(mob/living/carbon/M) + . = ..() + if(!ishuman(M)) //leaving the monkey feature for those desperate for goon level comedy. + if(volume >= 15) //to prevent monkey butt farms + var/turf/T = get_turf(M) + var/obj/item/organ/genital/butt/B = new /obj/item/organ/genital/butt(T) + M.visible_message("An ass suddenly flies out of [M]!") + var/T2 = get_random_station_turf() + M.adjustBruteLoss(25) + M.DefaultCombatKnockdown(50) + M.Stun(50) + B.throw_at(T2, 8, 1) + M.reagents.del_reagent(type) + return + var/mob/living/carbon/human/H = M + if(!H.getorganslot(ORGAN_SLOT_BUTT) && H.emergent_genital_call()) + H.genital_override = TRUE + +/datum/reagent/fermi/butt_enlarger/on_mob_life(mob/living/carbon/M) //Increases butt size + if(!ishuman(M)) + return ..() + var/mob/living/carbon/human/H = M + if(!(H.client?.prefs.cit_toggles & BUTT_ENLARGEMENT)) + return ..() + var/obj/item/organ/genital/butt/B = M.getorganslot(ORGAN_SLOT_BUTT) + if(!B) //If they don't have a butt. Give them one! + var/obj/item/organ/genital/butt/nB = new + nB.Insert(M) + if(nB) + if(M.dna.species.use_skintones && M.dna.features["genitals_use_skintone"]) + nB.color = SKINTONE2HEX(H.skin_tone) + else if(M.dna.features["butt_color"]) + nB.color = "#[M.dna.features["butt_color"]]" + else + nB.color = SKINTONE2HEX(H.skin_tone) + nB.size = 1 + to_chat(M, "Your ass cheeks bulge outwards and feel more plush.") + M.reagents.remove_reagent(type, 5) + B = nB + //If they have, increase size. + if(B.size_cached < BUTT_SIZE_MAX) //just in case + B.modify_size(0.05) + ..() + +/datum/reagent/fermi/AEsmaller_hypo //"BEsmaller" already exists so using "AE" instead, A is for ass. + name = "Rectify tincture" + color = "#e8ff1b" + taste_description = "butter" + description = "A medicine used to treat organomegaly in a patient's ass." + metabolization_rate = 0.5 + can_synth = TRUE + +/datum/reagent/fermi/AEsmaller_hypo/on_mob_metabolize(mob/living/M) + . = ..() + if(!ishuman(M)) + return + var/mob/living/carbon/human/H = M + if(!H.getorganslot(ORGAN_SLOT_BUTT) && H.dna.features["has_butt"]) + H.give_genital(/obj/item/organ/genital/butt) + +/datum/reagent/fermi/AEsmaller_hypo/on_mob_life(mob/living/carbon/M) + var/obj/item/organ/genital/butt/B = M.getorganslot(ORGAN_SLOT_BUTT) + if(!B) + return ..() + var/optimal_size = M.dna.features["butt_size"] + if(!optimal_size)//Fast fix for those who don't want it. + B.modify_size(-0.2) + else if(B.size > optimal_size) + B.modify_size(-0.1, optimal_size) + else if(B.size < optimal_size) + B.modify_size(0.1, 0, optimal_size) + return ..() diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm index c6fae2ff8f..bc598e81e3 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm @@ -3,12 +3,13 @@ /datum/reagent/fermi name = "Fermi" //This should never exist, but it does so that it can exist in the case of errors.. - taste_description = "affection and love!" + taste_description = "the default fermi taste" can_synth = FALSE value = 20 impure_chem = /datum/reagent/impure/fermiTox // What chemical is metabolised with an inpure reaction inverse_chem_val = 0.25 // If the impurity is below 0.5, replace ALL of the chem with inverse_chemupon metabolising inverse_chem = /datum/reagent/impure/fermiTox + chemical_flags = REAGENT_ALL_PROCESS //Lets just default to robots being able to process these funky chems. //This should process fermichems to find out how pure they are and what effect to do. @@ -33,10 +34,10 @@ name = "Hat growth serium" description = "A strange substance that draws in a hat from the hat dimention." color = "#7c311a" // rgb: , 0, 255 - taste_description = "like jerky, whiskey and an off aftertaste of a crypt." + taste_description = "like jerky, whiskey and an off aftertaste of a crypt" metabolization_rate = 0.2 overdose_threshold = 25 - chemical_flags = REAGENT_DONOTSPLIT + chemical_flags = REAGENT_DONOTSPLIT | REAGENT_ALL_PROCESS pH = 4 can_synth = TRUE @@ -47,7 +48,7 @@ var/obj/item/W = M.head M.dropItemToGround(W, TRUE) var/hat = new /obj/item/clothing/head/hattip() - M.equip_to_slot(hat, SLOT_HEAD, 1, 1) + M.equip_to_slot(hat, ITEM_SLOT_HEAD, 1, 1) /datum/reagent/fermi/hatmium/on_mob_life(mob/living/carbon/human/M) @@ -84,7 +85,7 @@ metabolization_rate = 0.5 * REAGENTS_METABOLISM inverse_chem_val = 0 var/obj/item/organ/tongue/nT - chemical_flags = REAGENT_DONOTSPLIT + chemical_flags = REAGENT_DONOTSPLIT | REAGENT_ALL_PROCESS pH = 5 var/obj/item/organ/tongue/T can_synth = TRUE @@ -200,7 +201,7 @@ impure_chem = /datum/reagent/fermi/nanite_b_goneTox //If you make an inpure chem, it stalls growth inverse_chem_val = 0.25 inverse_chem = /datum/reagent/fermi/nanite_b_goneTox //At really impure vols, it just becomes 100% inverse - taste_description = "what can only be described as licking a battery." + taste_description = "what can only be described as licking a battery" pH = 9 value = 90 can_synth = FALSE @@ -239,8 +240,9 @@ /datum/reagent/fermi/nanite_b_goneTox name = "Electromagnetic crystals" description = "Causes items upon the patient to sometimes short out, as well as causing a shock in the patient, if the residual charge between the crystals builds up to sufficient quantities" + taste_description = "shocking pain" metabolization_rate = 0.5 - chemical_flags = REAGENT_INVISIBLE + chemical_flags = REAGENT_INVISIBLE | REAGENT_ALL_PROCESS //Increases shock events. /datum/reagent/fermi/nanite_b_goneTox/on_mob_life(mob/living/carbon/C)//Damages the taker if their purity is low. Extended use of impure chemicals will make the original die. (thus can't be spammed unless you've very good) @@ -261,7 +263,7 @@ /datum/reagent/fermi/fermiAcid name = "Acid vapour" description = "Someone didn't do like an otter, and add acid to water." - taste_description = "acid burns, ow" + taste_description = "burning" color = "#FFFFFF" pH = 0 can_synth = FALSE @@ -303,7 +305,7 @@ /datum/reagent/fermi/fermiTest name = "Fermis Test Reagent" description = "You should be really careful with this...! Also, how did you get this?" - chemical_flags = REAGENT_FORCEONNEW + chemical_flags = REAGENT_FORCEONNEW | REAGENT_ALL_PROCESS can_synth = FALSE /datum/reagent/fermi/fermiTest/on_new(datum/reagents/holder) @@ -337,8 +339,9 @@ name = "Strong acidic buffer" description = "This reagent will consume itself and move the pH of a beaker towards acidity when added to another." color = "#fbc314" + taste_description = "burning" pH = 0 - chemical_flags = REAGENT_FORCEONNEW + chemical_flags = REAGENT_FORCEONNEW | REAGENT_ALL_PROCESS can_synth = TRUE var/strength = 1.5 @@ -367,6 +370,7 @@ name = "Acidic buffer" description = "This reagent will consume itself and move the pH of a beaker towards acidity when added to another." color = "#fbf344" + taste_description = "vinegar" pH = 4 can_synth = TRUE strength = 0.25 @@ -375,8 +379,9 @@ name = "Strong basic buffer" description = "This reagent will consume itself and move the pH of a beaker towards alkalinity when added to another." color = "#3853a4" + taste_description = "burning" pH = 14 - chemical_flags = REAGENT_FORCEONNEW + chemical_flags = REAGENT_FORCEONNEW | REAGENT_ALL_PROCESS can_synth = TRUE var/strength = 1.5 @@ -384,6 +389,7 @@ name = "Basic buffer" description = "This reagent will consume itself and move the pH of a beaker towards alkalinity when added to another." color = "#5873c4" + taste_description = "something soapy" pH = 10 can_synth = TRUE strength = 0.25 diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm index 2cdaef9c91..6695194008 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm @@ -98,8 +98,8 @@ description = "Synthetic tissue used for grafting onto damaged organs during surgery, or for treating limb damage. Has a very tight growth window between 305-320, any higher and the temperature will cause the cells to die. Additionally, growth time is considerably long, so chemists are encouraged to leave beakers with said reaction ongoing, while they tend to their other duties." pH = 7.6 metabolization_rate = 0.05 //Give them time to graft - data = list("grown_volume" = 0, "injected_vol" = 0) - var/borrowed_health + data = list("grown_volume" = 0, "injected_vol" = 0, "borrowed_health" = 0) + var/borrowed_health = 0 color = "#FFDADA" value = REAGENT_VALUE_COMMON @@ -107,31 +107,51 @@ if(iscarbon(M)) var/mob/living/carbon/C = M var/healing_factor = (((data["grown_volume"] / 100) + 1)*reac_volume) - if(method in list(PATCH, TOUCH)) - if (M.stat == DEAD) - M.visible_message("The synthetic tissue rapidly grafts into [M]'s wounds, attemping to repair the damage as quickly as possible.") - borrowed_health += healing_factor - M.adjustBruteLoss(-healing_factor*2) - M.adjustFireLoss(-healing_factor*2) - M.adjustToxLoss(-healing_factor) - M.adjustCloneLoss(-healing_factor) - M.updatehealth() + if(method == PATCH) //Needs to actually be applied via patch / hypo / medspray and not just beakersplashed. + if (C.stat == DEAD) + C.visible_message("The synthetic tissue rapidly grafts into [M]'s wounds, attempting to repair the damage as quickly as possible.") + var/preheal_brute = C.getBruteLoss() + var/preheal_burn = C.getFireLoss() + var/preheal_tox = C.getToxLoss() + var/preheal_oxy = C.getOxyLoss() + C.adjustBruteLoss(-healing_factor*2) + C.adjustFireLoss(-healing_factor*2) + C.adjustToxLoss(-healing_factor) + C.adjustCloneLoss(-healing_factor) + borrowed_health += (preheal_brute - C.getBruteLoss()) + (preheal_burn - C.getFireLoss()) + (preheal_tox - C.getToxLoss()) + ((preheal_oxy - C.getOxyLoss()) / 2) //Ironically this means that while slimes get damaged by the toxheal, it will reduce borrowed health and longterm effects. Funky! + C.updatehealth() if(data["grown_volume"] > 135 && ((C.health + C.oxyloss)>=80)) - if(M.revive()) - M.emote("gasp") + var/tplus = world.time - M.timeofdeath + if(C.can_revive(ignore_timelimit = TRUE, maximum_brute_dam = MAX_REVIVE_BRUTE_DAMAGE / 2, maximum_fire_dam = MAX_REVIVE_FIRE_DAMAGE / 2, ignore_heart = TRUE) && C.revive()) + C.grab_ghost() + C.emote("gasp") borrowed_health *= 2 if(borrowed_health < 100) borrowed_health = 100 - log_combat(M, M, "revived", src) + log_combat(C, C, "revived", src) + var/list/policies = CONFIG_GET(keyed_list/policy) + var/policy = policies[POLICYCONFIG_ON_DEFIB_LATE] //Always causes memory loss due to the nature of synthtissue + if(policy) + to_chat(C, policy) + C.log_message("revived using synthtissue, [tplus] deciseconds from time of death, considered late revival due to usage of synthtissue.", LOG_GAME) else + var/preheal_brute = C.getBruteLoss() + var/preheal_burn = C.getFireLoss() M.adjustBruteLoss(-healing_factor) M.adjustFireLoss(-healing_factor) - to_chat(M, "You feel your flesh merge with the synthetic tissue! It stings like hell!") + var/datum/reagent/synthtissue/active_tissue = M.reagents.has_reagent(/datum/reagent/synthtissue) + var/imperfect = FALSE //Merging with synthtissue that has borrowed health + if(active_tissue && active_tissue.borrowed_health) + borrowed_health += (preheal_brute - C.getBruteLoss()) + (preheal_burn - C.getFireLoss()) + imperfect = TRUE + to_chat(M, "You feel your flesh [imperfect ? "partially and painfully" : ""] merge with the synthetic tissue! It stings like hell[imperfect ? " and is making you feel terribly sick" : ""]!") SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine) + data["borrowed_health"] += borrowed_health //Preserve health offset + borrowed_health = 0 //We are applying this to someone else, so this info will be transferred via data. if(method==INJECT) data["injected_vol"] = reac_volume var/obj/item/organ/heart/H = C.getorganslot(ORGAN_SLOT_HEART) - if(data["grown_volume"] > 50 && H.organ_flags & ORGAN_FAILING) + if(H && data["grown_volume"] > 50 && H.organ_flags & ORGAN_FAILING) H.applyOrganDamage(-20) ..() @@ -145,16 +165,19 @@ C.reagents.remove_reagent(type, 15) to_chat(C, "You feel something reform inside of you!") - data["injected_vol"] -= metabolization_rate + data["injected_vol"] = max(0, data["injected_vol"] - metabolization_rate * C.metabolism_efficiency) //No negatives. if(borrowed_health) - C.adjustToxLoss(1) - C.adjustCloneLoss(1) - borrowed_health -= 1 + var/ratio = (current_cycle > SYNTHTISSUE_DAMAGE_FLIP_CYCLES) ? 0 : (1 - (current_cycle / SYNTHTISSUE_DAMAGE_FLIP_CYCLES)) + var/payback = 2 * C.metabolism_efficiency //How much borrowed health we are paying back. Starts as cloneloss, slowly flips over to toxloss. + C.adjustToxLoss((1 - ratio) * payback * REAGENTS_EFFECT_MULTIPLIER, forced = TRUE, toxins_type = TOX_OMNI) + C.adjustCloneLoss(ratio * payback * REAGENTS_EFFECT_MULTIPLIER) + borrowed_health = max(borrowed_health - payback, 0) ..() /datum/reagent/synthtissue/on_merge(passed_data) if(!passed_data) return ..() + borrowed_health += max(0, passed_data["borrowed_health"]) if(passed_data["grown_volume"] > data["grown_volume"]) data["grown_volume"] = passed_data["grown_volume"] if(iscarbon(holder.my_atom)) @@ -166,11 +189,16 @@ /datum/reagent/synthtissue/on_new(passed_data) if(!passed_data) return ..() + borrowed_health = min(passed_data["borrowed_health"] + borrowed_health, SYNTHTISSUE_BORROW_CAP) if(passed_data["grown_volume"] > data["grown_volume"]) data["grown_volume"] = passed_data["grown_volume"] update_name() ..() +/datum/reagent/synthtissue/post_copy_data() + data["borrowed_health"] = 0 //We passed this along to something that needed it, set it back to 0 so we don't do it twice. + return ..() + /datum/reagent/synthtissue/proc/update_name() //They are but babes on creation and have to grow unto godhood switch(data["grown_volume"]) if(-INFINITY to 50) @@ -193,15 +221,16 @@ C.adjustCloneLoss(borrowed_health*1.25) C.adjustAllOrganLoss(borrowed_health*0.25) M.updatehealth() - if(borrowed_health && C.health < -20) - M.stat = DEAD + if(C.stat != DEAD && borrowed_health && C.health < -20) M.visible_message("The synthetic tissue degrades off [M]'s wounds as they collapse to the floor.") + M.death() //NEEDS ON_MOB_DEAD() /datum/reagent/fermi/zeolites - name = "Artificial Zeolites" + name = "Artificial Zeolite" description = "Lab made Zeolite, used to clear radiation from people and items alike! Splashing just a small amount(5u) onto any item can clear away large amounts of contamination, as long as its purity is at least 0.7." pH = 8 + taste_description = "chalky metal" color = "#FFDADA" metabolization_rate = 8 * REAGENTS_METABOLISM //Metabolizes fast but heals a lot! Lasts far longer if more pure. value = REAGENT_VALUE_RARE //Relatively hard to make now, might be fine with VERY_RARE instead depending on feedback. diff --git a/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm index edaaeb19b2..ce27433c07 100644 --- a/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm +++ b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm @@ -344,8 +344,13 @@ E.creatorID = B.data["ckey"] /datum/chemical_reaction/fermi/enthrall/FermiExplode(datum/reagents/R0, var/atom/my_atom, volume, temp, pH) + var/turf/T = get_turf(my_atom) + var/datum/reagents/R = new/datum/reagents(1000) + var/datum/effect_system/smoke_spread/chem/s = new() + R.add_reagent(/datum/reagent/fermi/enthrallExplo, volume) + s.set_up(R, volume/2, T) + s.start() R0.clear_reagents() - ..() /datum/chemical_reaction/fermi/hatmium // done name = "Hat growth serum" @@ -543,6 +548,8 @@ FermiExplode = FALSE PurityMin = 0.2 + is_secret = TRUE + /datum/chemical_reaction/fermi/secretcatchem/New() //rand doesn't seem to work with n^-e OptimalTempMin += rand(-100, 100) diff --git a/modular_citadel/code/modules/reagents/objects/clothes.dm b/modular_citadel/code/modules/reagents/objects/clothes.dm index ab4d49c56f..9b3b63d5af 100644 --- a/modular_citadel/code/modules/reagents/objects/clothes.dm +++ b/modular_citadel/code/modules/reagents/objects/clothes.dm @@ -6,7 +6,7 @@ icon = 'icons/obj/clothing/hats.dmi' icon_state = "cowboy" desc = "A synthesized hat. You feel compelled to keep it on all times." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) //item_flags = NODROP //Tips their hat! /obj/item/clothing/head/hattip/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) @@ -37,7 +37,7 @@ /obj/item/clothing/head/hattip/equipped(mob/M, slot) . = ..() - if (slot == SLOT_HEAD) + if (slot == ITEM_SLOT_HEAD) RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) else UnregisterSignal(M, COMSIG_MOB_SAY) diff --git a/modular_citadel/code/modules/reagents/objects/items.dm b/modular_citadel/code/modules/reagents/objects/items.dm index f4316b3c58..fa8b98f432 100644 --- a/modular_citadel/code/modules/reagents/objects/items.dm +++ b/modular_citadel/code/modules/reagents/objects/items.dm @@ -140,7 +140,16 @@ out_message += "A reaction appears to be occuring currently.\n" out_message += "Chemicals found in the beaker:\n" for(var/datum/reagent/R in cont.reagents.reagent_list) - out_message += "[R.volume]u of [R.name], Purity: [R.purity], [(scanmode?"[(R.overdose_threshold?"Overdose: [R.overdose_threshold]u, ":"")][(R.addiction_threshold?"Addiction: [R.addiction_threshold]u, ":"")]Base pH: [R.pH].":".")]\n" + var/processtype + if(CHECK_MULTIPLE_BITFIELDS(R.chemical_flags, (REAGENT_ROBOTIC_PROCESS | REAGENT_ORGANIC_PROCESS))) + processtype = "Both robots and organics" + else if(R.chemical_flags & REAGENT_ROBOTIC_PROCESS) + processtype = "Robots only" + else if(R.chemical_flags & REAGENT_ORGANIC_PROCESS) + processtype = "Organics only" + else + processtype = "Noone?! (Report this to Nanotrasen's spacetime department immediately)" + out_message += "[R.volume]u of [R.name], Purity: [R.purity], [(scanmode?"[(R.overdose_threshold?"Overdose: [R.overdose_threshold]u, ":"")][(R.addiction_threshold?"Addiction: [R.addiction_threshold]u, ":"")]Metabolized by: [processtype], Base pH: [R.pH].":".")]\n" if(scanmode) out_message += "Analysis: [R.description]\n" to_chat(user, "[out_message]") diff --git a/modular_citadel/code/modules/vectorcrafts/vector_process.dm b/modular_citadel/code/modules/vectorcrafts/vector_process.dm new file mode 100644 index 0000000000..cc4bd1d074 --- /dev/null +++ b/modular_citadel/code/modules/vectorcrafts/vector_process.dm @@ -0,0 +1,28 @@ +PROCESSING_SUBSYSTEM_DEF(vectorcraft) + name = "Vectorcraft Movement" + priority = 40 + wait = 2 + stat_tag = "VC" + flags = SS_NO_INIT|SS_TICKER|SS_KEEP_TIMING + + //var/flightsuit_processing = FLIGHTSUIT_PROCESSING_FULL + + +/* unsure if needed +/datum/controller/subsystem/processing/vectorcraft/Initialize() + sync_flightsuit_processing() + +/datum/controller/subsystem/processing/vectorcraft/vv_edit_var(var_name, var_value) + ..() + switch(var_name) + if("flightsuit_processing") + sync_flightsuit_processing() + +/datum/controller/subsystem/processing/vectorcraft/proc/sync_flightsuit_processing() + for(var/obj/vehicle/sealed/vectorcraft/VC in processing) + VC.sync_processing(src) + if(flightsuit_processing == FLIGHTSUIT_PROCESSING_NONE) //Don't even bother firing. + can_fire = FALSE + else + can_fire = TRUE +*/ diff --git a/modular_citadel/code/modules/vectorcrafts/vectorcar_heads.dm b/modular_citadel/code/modules/vectorcrafts/vectorcar_heads.dm new file mode 100644 index 0000000000..e89f8b147e --- /dev/null +++ b/modular_citadel/code/modules/vectorcrafts/vectorcar_heads.dm @@ -0,0 +1,28 @@ +/obj/vehicle/sealed/vectorcraft/CMO + name = "CMO's hovercar" + icon_state = "zoomscoot_CMO" + +/obj/vehicle/sealed/vectorcraft/RD + name = "RD's hovercar" + icon_state = "zoomscoot_RD" + +/obj/vehicle/sealed/vectorcraft/hop + name = "HOP\'s hovercar" + icon_state = "zoomscoot_HOP" + +/obj/vehicle/sealed/vectorcraft/hos + name = "HOS\'s hovercar" + icon_state = "zoomscoot_HOS" + +/obj/vehicle/sealed/vectorcraft/CE + name = "CE\'s hovercar" + icon_state = "zoomscoot_CE" + +/obj/vehicle/sealed/vectorcraft/QM + name = "QM\'s hovercar" + icon_state = "zoomscoot_QM" + +/obj/vehicle/sealed/vectorcraft/CAPT + name = "Captain\'s hovercar" + icon_state = "zoomscoot_CAPT" + boost_power = 20 //gosh capt how come CC lets you have more boost power? diff --git a/modular_citadel/code/modules/vectorcrafts/vectorcraft.dm b/modular_citadel/code/modules/vectorcrafts/vectorcraft.dm new file mode 100644 index 0000000000..399a1c5f06 --- /dev/null +++ b/modular_citadel/code/modules/vectorcrafts/vectorcraft.dm @@ -0,0 +1,615 @@ +#define SPEED_MOD 5 +#define PX_OFFSET 16 //half of total px size of sprite +//Cars that drfit +//By Fermi! + + +/obj/vehicle/sealed/vectorcraft + name = "all-terrain hovercraft" + desc = "An all-terrain vehicle built for traversing rough terrain with ease. One of the few old-Earth technologies that are still relevant on most planet-bound outposts." + icon_state = "zoomscoot" + movedelay = 5 + //allow_diagonal_dir = TRUE - find fix for this later + inertia_moving = FALSE + animate_movement = 0 + max_integrity = 100 + //key_type = /obj/item/key + var/obj/structure/trunk //Trunkspace of craft + var/vector = list("x" = 0, "y" = 0) //vector math + var/tile_loc = list("x" = 0, "y" = 0) //x y offset of tile + var/max_acceleration = 5.25 + var/accel_step = 0.3 + var/acceleration = 0.4 + var/max_deceleration = 2 + var/max_velocity = 110 + var/boost_power = 15 + var/enginesound_delay = 0 + var/gear + var/boost_cooldown + + //Changes for custom + var/i_m_acell + var/i_m_decell + var/i_boost + var/i_acell + + var/mob/living/carbon/human/driver + +/obj/vehicle/sealed/vectorcraft/Initialize(mapload) + ..() + i_m_acell = max_acceleration + i_m_decell = max_deceleration + i_boost = boost_power + i_acell = acceleration + +/obj/vehicle/sealed/vectorcraft/mob_enter(mob/living/M) + if(!driver) + driver = M + if(gear != "auto") + gear = driver.a_intent + start_engine() + to_chat(M, "How to drive: \nHold wasd to gain speed in a direction, c to enable/disable the clutch, 1 2 3 4 to change gears while holding a direction (make sure the clutch is enabled when you change gears, you should hear a sound when you've successfully changed gears), r to toggle handbrake, hold alt for brake and press shift for boost (the machine will beep when the boost is recharged)! If you hear an ebbing sound like \"brbrbrbrbr\" you need to gear down, the whining sound means you need to gear up. Hearing a pleasant \"whumwhumwhum\" is optimal gearage! It can be a lil slow to start, so make sure you're in the 1st gear.\n") + return ..() + +/obj/vehicle/sealed/vectorcraft/mob_exit(mob/living/M) + .=..() + if(!driver) + stop_engine() + return + if(driver.client) + driver.client.pixel_x = 0 + driver.client.pixel_y = 0 + driver.pixel_x = 0 + driver.pixel_y = 0 + if(M == driver) + driver = null + gear = initial(gear) + stop_engine() + + +////////////////////////////////////////////////////////////// +// Main driving checks // +////////////////////////////////////////////////////////////// + +/obj/vehicle/sealed/vectorcraft/proc/start_engine() + if(dead_check()) + return + START_PROCESSING(SSvectorcraft, src) + check_gears() + if(!driver) + stop_engine() + + +/obj/vehicle/sealed/vectorcraft/proc/stop_engine() + STOP_PROCESSING(SSvectorcraft, src) + vector = list("x" = 0, "y" = 0) + acceleration = initial(acceleration) + +/obj/vehicle/sealed/vectorcraft/proc/dead_check() + if(driver.stat > 0) + mob_exit(driver) + stop_engine() + return TRUE + return FALSE + + + +//Move the damn car +/obj/vehicle/sealed/vectorcraft/vehicle_move(cached_direction) + if(!driver) + stop_engine() + if(driver.stat == DEAD) + mob_exit(driver) + dir = cached_direction + check_gears() + check_boost() + calc_acceleration() + calc_vector(cached_direction) + /* + var/direction = calc_angle() + if(!direction) + direction = cached_direction + return + */ + + /* depreciated + //movespeed + if(lastmove + movedelay > world.time) + return FALSE + lastmove = world.time + if(trailer) + var/dir_to_move = get_dir(trailer.loc, loc) + var/did_move = step(src, direction) + if(did_move) + step(trailer, dir_to_move) + return did_move + else + after_move(direction) + return step(src, direction) + */ + +//Passive hover drift +/obj/vehicle/sealed/vectorcraft/proc/hover_loop() + check_boost() + if(driver.m_intent == MOVE_INTENT_WALK) + var/deceleration = max_deceleration + if(driver.in_throw_mode) + deceleration *= 1.5 + friction(deceleration, TRUE) + else if(driver.in_throw_mode) + friction(max_deceleration*1.2, TRUE) + friction(max_deceleration/4) + + if(trailer) + var/dir_to_move = get_dir(trailer.loc, loc) + var/did_move = move_car() + if(did_move) + step(trailer, dir_to_move) + trailer.pixel_x = tile_loc["x"] + trailer.pixel_y = tile_loc["y"] + after_move(did_move) + return did_move + else + var/direction = move_car() + after_move(direction) + return direction + +//I got over messy process procs +/obj/vehicle/sealed/vectorcraft/process() + hover_loop() + dead_check() + +////////////////////////////////////////////////////////////// +// Movement procs // +////////////////////////////////////////////////////////////// + +/obj/vehicle/sealed/vectorcraft/proc/move_car() + + + if(GLOB.Debug2) + message_admins("Pre_ Tile_loc: [tile_loc["x"]], [tile_loc["y"]] Vector: [vector["x"]],[vector["y"]]") + + var/cached_tile = tile_loc + tile_loc["x"] += vector["x"]/SPEED_MOD + tile_loc["y"] += vector["y"]/SPEED_MOD + //range = -16 to 16 + var/x_move = 0 + if(tile_loc["x"] > PX_OFFSET) + x_move = round((tile_loc["x"]+PX_OFFSET) / (PX_OFFSET*2), 1) + tile_loc["x"] = ((tile_loc["x"]+PX_OFFSET) % (PX_OFFSET*2))-PX_OFFSET + else if(tile_loc["x"] < -PX_OFFSET) + x_move = round((tile_loc["x"]-PX_OFFSET) / (PX_OFFSET*2), 1) + tile_loc["x"] = ((tile_loc["x"]-PX_OFFSET) % -(PX_OFFSET*2))+PX_OFFSET + + + + var/y_move = 0 + if(tile_loc["y"] > PX_OFFSET) + y_move = round((tile_loc["y"]+PX_OFFSET) / (PX_OFFSET*2), 1) + tile_loc["y"] = ((tile_loc["y"]+PX_OFFSET) % (PX_OFFSET*2))-PX_OFFSET + else if(tile_loc["y"] < -PX_OFFSET) + y_move = round((tile_loc["y"]-PX_OFFSET) / (PX_OFFSET*2), 1) + tile_loc["y"] = ((tile_loc["y"]-PX_OFFSET) % -(PX_OFFSET*2))+PX_OFFSET + + if(!(x_move == 0 && y_move == 0)) + var/turf/T = get_offset_target_turf(src, x_move, y_move) + for(var/atom/A in T.contents) + Bump(A) + if(A.density) + ricochet() + tile_loc = cached_tile + return FALSE + if(T.density) + ricochet() + tile_loc = cached_tile + return FALSE + + x += x_move + y += y_move + pixel_x = round(tile_loc["x"], 1) + pixel_y = round(tile_loc["y"], 1) + if(driver && driver.client) + driver.client.pixel_x = pixel_x + driver.client.pixel_y = pixel_y + + + if(GLOB.Debug2) + message_admins("Post TileLoc:[tile_loc["x"]], [tile_loc["y"]] Movement: [x_move],[y_move]") + message_admins("Pix:[pixel_x],[pixel_y] TileLoc:[tile_loc["x"]], [tile_loc["y"]]. [round(tile_loc["x"])], [round(tile_loc["y"])]") + //no tile movement + + if(x_move == 0 && y_move == 0) + return FALSE + + //var/direction = calc_step_angle(x_move, y_move) + //if(direction) //If the movement is greater than 2 + // step(src, direction) + // after_move(direction) + + + + + return TRUE + +////////////////////////////////////////////////////////////// +// Check procs // +////////////////////////////////////////////////////////////// + +//check the cooldown on the boost +/obj/vehicle/sealed/vectorcraft/proc/check_boost() + if(enginesound_delay < world.time) + enginesound_delay = 0 + if(!boost_cooldown) + return + if(boost_cooldown < world.time) + boost_cooldown = 0 + playsound(src.loc,'sound/vehicles/boost_ready.ogg', 65, 0) + return + +//Make sure the clutch is on while changing gears!! +/obj/vehicle/sealed/vectorcraft/proc/check_gears() + if(!driver) + for(var/i in contents) + if(iscarbon(i)) + var/mob/living/carbon/C = i + driver = C + to_chat(driver, "You shuffle across to the driver's seat of the [src]") + start_engine() + break + if(!driver) + stop_engine() + return + if(!gear) + gear = driver.a_intent + if(gear == "auto") + return + //USE THE CCLUUUTCHHH + if(gear != driver.a_intent && SEND_SIGNAL(driver, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) + //playsound + to_chat(driver, "The gearbox gives out a horrific sound!") + playsound(src.loc,'sound/vehicles/clutch_fail.ogg', 70, 0) + apply_damage(5) + acceleration = acceleration/2 + else if(gear != driver.a_intent && SEND_SIGNAL(driver, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) + playsound(src.loc,'sound/vehicles/clutch_win.ogg', 100, 0) + gear = driver.a_intent + +//Bounce the car off a wall +/obj/vehicle/sealed/vectorcraft/proc/bounce() + vector["x"] = -vector["x"]/2 + vector["y"] = -vector["y"]/2 + acceleration /= 2 + +/obj/vehicle/sealed/vectorcraft/proc/ricochet(x_move, y_move) + var/speed = calc_speed() + apply_damage(speed/10) + bounce() + +////////////////////////////////////////////////////////////// +// Damage procs // +////////////////////////////////////////////////////////////// +//Repairing +/obj/vehicle/sealed/vectorcraft/attackby(obj/item/O, mob/user, params) + .=..() + if(istype(O, /obj/item/weldingtool) && user.a_intent != INTENT_HARM) + if(obj_integrity < max_integrity) + if(!O.tool_start_check(user, amount=0)) + return + + user.visible_message("[user] begins repairing [src].", \ + "You begin repairing [src]...", \ + "You hear welding.") + + if(O.use_tool(src, user, 40, volume=50)) + to_chat(user, "You repair [src].") + apply_damage(-max_integrity) + else + to_chat(user, "[src] does not need repairs.") + + +/obj/vehicle/sealed/vectorcraft/attack_hand(mob/user) + remove_key(driver) + ..() + +//Heals/damages the car +/obj/vehicle/sealed/vectorcraft/proc/apply_damage(damage) + obj_integrity -= damage + var/healthratio = ((obj_integrity/max_integrity)/4) + 0.75 + max_acceleration = initial(max_acceleration) * healthratio + max_deceleration = initial(max_deceleration) * healthratio + boost_power = initial(boost_power) * healthratio + + if(obj_integrity <= 0) + mob_exit(driver) + var/datum/effect_system/reagents_explosion/e = new() + var/turf/T = get_turf(src) + e.set_up(1, T, 1, 3) + e.start() + visible_message("The [src] explodes from taking too much damage!") + qdel(src) + if(obj_integrity > max_integrity) + obj_integrity = max_integrity + +// +/obj/vehicle/sealed/vectorcraft/Bump(atom/M) + var/speed = calc_speed() + if(isliving(M)) + var/mob/living/C = M + if(!C.anchored) + var/atom/throw_target = get_edge_target_turf(C, calc_angle()) + C.throw_at(throw_target, 10, 14) + to_chat(C, "You are hit by the [src]!") + to_chat(driver, "You just ran into [C] you crazy lunatic!") + C.adjustBruteLoss(speed/10) + return ..() + //playsound + if(istype(M, /obj/vehicle/sealed/vectorcraft)) + var/obj/vehicle/sealed/vectorcraft/Vc = M + Vc.apply_damage(speed/5) + Vc.vector["x"] += vector["x"]/2 + Vc.vector["y"] += vector["y"]/2 + apply_damage(speed/10) + bounce() + return ..() + if(istype(M, /obj/)) + var/obj/O = M + if(O.density) + O.take_damage(speed*2.5) + return ..() + +////////////////////////////////////////////////////////////// +// Calc procs // +////////////////////////////////////////////////////////////// +/*Calc_step_angle calculates angle based off pixel x,y movement (x,y in) +Calc angle calcus angle based off vectors +calc_speed() returns the highest var of x or y relative +calc accel calculates the acceleration to be added to vector +calc vector updates the internal vector +friction reduces the vector by an ammount to both axis*/ + +//How fast the car is going atm +/obj/vehicle/sealed/vectorcraft/proc/calc_velocity() //Depreciated. + var/speed = calc_speed() + switch(speed) + if(-INFINITY to 10) + movedelay = 5 + inertia_move_delay = 5 + if(10 to 20) + movedelay = 4 + inertia_move_delay = 4 + if(20 to 35) + movedelay = 3 + inertia_move_delay = 3 + if(35 to 60) + movedelay = 2 + inertia_move_delay = 2 + if(60 to 90) + movedelay = 1 + inertia_move_delay = 1 + if(90 to INFINITY) + movedelay = 0 + inertia_move_delay = 0 + return + +/* +if(driver.sprinting && !(boost_cooldown)) + acceleration += boost_power //You got boost power! + boost_cooldown = world.time + 150 + playsound(src.loc,'sound/vehicles/boost.ogg', 50, 0) + //playsound +*/ + +/obj/vehicle/sealed/vectorcraft/proc/calc_step_angle(x, y) + if((sqrt(x**2))>1 || (sqrt(y**2))>1) //Too large a movement for a step + return FALSE + if(x == 1) + if (y == 1) + return NORTHEAST + else if (y == -1) + return SOUTHEAST + else if (y == 0) + return EAST + else + message_admins("something went wrong; y = [y]") + else if (x == -1) + if (y == 1) + return NORTHWEST + else if (y == -1) + return SOUTHWEST + else if (y == 0) + return WEST + else + message_admins("something went wrong; y = [y]") + else if (x != 0) + message_admins("something went wrong; x = [x]") + + if (y == 1) + return NORTH + else if (y == -1) + return SOUTH + else if (x != 0) + message_admins("something went wrong; y = [y]") + return FALSE + +//Returns the angle to move towards +/obj/vehicle/sealed/vectorcraft/proc/calc_angle() + var/x = round(vector["x"], 1) + var/y = round(vector["y"], 1) + if(y == 0) + if(x > 0) + return EAST + else if(x < 0) + return WEST + if(x == 0) + if(y > 0) + return NORTH + else if(y < 0) + return SOUTH + if(x == 0 || y == 0) + return FALSE + var/angle = (ATAN2(x,y)) + //if(angle < 0) + // angle += 360 + //message_admins("x:[x], y: [y], angle:[angle]") + + //I WISH I HAD RADIANSSSSSSSSSS + if(angle > 0) + switch(angle) + if(0 to 22) + return EAST + if(22 to 67) + return NORTHEAST + if(67 to 112) + return NORTH + if(112 to 157) + return NORTHWEST + if(157 to 180) + return WEST + else + switch(angle) + if(0 to -22) + return EAST + if(-22 to -67) + return SOUTHEAST + if(-67 to -112) + return SOUTH + if(-112 to -157) + return SOUTHWEST + if(-157 to -180) + return WEST + + +//updates the internal speed of the car (used for crashing) +/obj/vehicle/sealed/vectorcraft/proc/calc_speed() + var/speed = max(sqrt((vector["x"]**2)), sqrt((vector["y"]**2))) + return speed + +//Converts "gear" from intent to numerics +/obj/vehicle/sealed/vectorcraft/proc/convert_gear() + switch(gear) + if("help") + return 1 + if("disarm") + return 2 + if("grab") + return 3 + if("harm") + return 4 + +//Calculates the acceleration +/obj/vehicle/sealed/vectorcraft/proc/calc_acceleration() //Make speed 0 - 100 regardless of gear here + if(SEND_SIGNAL(driver, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE))//clutch is on + return FALSE + if(gear == "auto") + acceleration += accel_step + acceleration = clamp(acceleration, initial(acceleration), max_acceleration) + if(!enginesound_delay) + playsound(src.loc,'sound/vehicles/norm_eng.ogg', 25, 0) + enginesound_delay = world.time + 16 + return + + var/gear_val = convert_gear() + var/min_accel = max_acceleration*( (((gear_val-1) * 20) + ((gear_val-1)*5)) /100) + var/max_accel = max_acceleration*((gear_val * 25)/100) //1.25 - 5 + + if(acceleration < min_accel) + acceleration += accel_step/10 + if(!enginesound_delay) + playsound(src.loc,'sound/vehicles/low_eng.ogg', 25, 0) + enginesound_delay = world.time + 16 + else if (acceleration > max_accel) + acceleration -= accel_step + if(!enginesound_delay) + playsound(src.loc,'sound/vehicles/high_eng.ogg', 25, 0) + enginesound_delay = world.time + 16 + else + if(gear_val == 1) + acceleration += accel_step*3.5 + else + acceleration += accel_step + if(!enginesound_delay) + playsound(src.loc,'sound/vehicles/norm_eng.ogg', 25, 0) + enginesound_delay = world.time + 16 + + if(acceleration > ((max_acceleration*calc_speed())/90) && acceleration > max_acceleration/5) + acceleration -= accel_step*2 + if(!enginesound_delay) + playsound(src.loc,'sound/vehicles/high_eng.ogg', 25, 0) + enginesound_delay = world.time + 16 + return + + acceleration = clamp(acceleration, initial(acceleration), max_acceleration) + +//calulate the vector change +/obj/vehicle/sealed/vectorcraft/proc/calc_vector(direction) + if(SEND_SIGNAL(driver, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE))//clutch is on + return FALSE + var/cached_acceleration = acceleration + var/boost_active = FALSE + if((driver.combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) && !(boost_cooldown)) + cached_acceleration += boost_power //You got boost power! + boost_cooldown = world.time + 80 + playsound(src.loc,'sound/vehicles/boost.ogg', 100, 0) + boost_active = TRUE + //playsound + + var/result_vector = vector + switch(direction) + if(NORTH) + result_vector["y"] += cached_acceleration + if(NORTHEAST) + result_vector["x"] += cached_acceleration/1.4 + result_vector["y"] += cached_acceleration/1.4 + if(EAST) + result_vector["x"] += cached_acceleration + if(SOUTHEAST) + result_vector["x"] += cached_acceleration/1.4 + result_vector["y"] -= cached_acceleration/1.4 + if(SOUTH) + result_vector["y"] -= cached_acceleration + if(SOUTHWEST) + result_vector["x"] -= cached_acceleration/1.4 + result_vector["y"] -= cached_acceleration/1.4 + if(WEST) + result_vector["x"] -= cached_acceleration + if(NORTHWEST) + result_vector["y"] += cached_acceleration/1.4 + result_vector["x"] -= cached_acceleration/1.4 + + if(boost_active) + vector["x"] = result_vector["x"] + vector["y"] = result_vector["y"] + else + vector["x"] = clamp(result_vector["x"], -max_velocity, max_velocity) + vector["y"] = clamp(result_vector["y"], -max_velocity, max_velocity) + + if(vector["x"] > max_velocity || vector["x"] < -max_velocity) + vector["x"] = vector["x"] - (vector["x"]/10) + vector["x"] = clamp(vector["x"], -250, 250) + if(vector["y"] > max_velocity || vector["y"] < -max_velocity) + vector["y"] = vector["y"] - (vector["y"]/10) + vector["y"] = clamp(vector["y"], -250, 250) + + return + +//Reduces speed +/obj/vehicle/sealed/vectorcraft/proc/friction(change, sfx = FALSE) + //decell X + if(vector["x"] == 0 && vector["y"] == 0) + return + if(vector["x"] <= -change) + vector["x"] += change + else if(vector["x"] >= change) + vector["x"] -= change + else + vector["x"] = 0 + //decell Y + if(vector["y"] <= -change) + vector["y"] += change + else if(vector["y"] >= change) + vector["y"] -= change + else + vector["y"] = 0 + + if(sfx) + playsound(src.loc,'sound/vehicles/skid.ogg', 50, 0) diff --git a/modular_citadel/code/modules/vectorcrafts/vectortruck.dm b/modular_citadel/code/modules/vectorcrafts/vectortruck.dm new file mode 100644 index 0000000000..c46a81df59 --- /dev/null +++ b/modular_citadel/code/modules/vectorcrafts/vectortruck.dm @@ -0,0 +1,147 @@ +/obj/vehicle/sealed/vectorcraft/boot + name = "Hovertruck" + desc = "An all-terrain vehicle built for traversing rough terrain with ease. This one comes equipt with a sizeable boot that can store up to 3 items!" + icon_state = "truck" + max_integrity = 200 + var/obj/structure/boot = list()//Trunkspace of craft + var/boot_size = 3 + max_acceleration = 3 + accel_step = 0.15 + acceleration = 0.3 + max_deceleration = 5 + max_velocity = 80 + boost_power = 20 + enginesound_delay = 0 + var/static/radial_heal = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_heal") + var/static/radial_eject_car = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject_car") + var/static/radial_eject_key = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject_key") + var/static/radial_eject_boot = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject_boot") + +/obj/vehicle/sealed/vectorcraft/boot/MouseDrop_T(atom/dropping, mob/user) + if(istype(dropping, /obj/)) + if(LAZYLEN(boot) < boot_size) + boot += dropping + to_chat(user, "You add the [dropping] to the [src]'s boot!") + return TRUE + if(iscarbon(dropping)) + var/mob/living/carbon/M = dropping + mob_try_enter(M) + to_chat(user, "You put [M] into the [src]!") + return TRUE + +/obj/vehicle/sealed/vectorcraft/boot/proc/eject_boot() + for(var/obj/o in boot) + o.forceMove(drop_location()) + +/obj/vehicle/sealed/vectorcraft/boot/ambulance //weewoos have to go fast + name = "Ambulance" + var/obj/machinery/sleeper/Sl + max_acceleration = 3 + accel_step = 0.15 + acceleration = 0.3 + max_deceleration = 5 + max_velocity = 100 + boost_power = 25 + enginesound_delay = 0 + icon_state = "ambutruck" + var/weewoo = FALSE + var/weewoocount = 0 + +/obj/vehicle/sealed/vectorcraft/boot/ambulance/Initialize(mapload) + . = ..() + Sl = new /obj/machinery/sleeper + +/obj/vehicle/sealed/vectorcraft/boot/ambulance/process() + ..() + if(weewoo) + weewoo() + +/obj/vehicle/sealed/vectorcraft/boot/ambulance/MouseDrop_T(mob/living/L, mob/user) + if(isliving(L)) + Sl.close_machine(L) + to_chat(user, "You put [L] into the [src]'s emergency sleeper!") + return TRUE + ..() + +/obj/vehicle/sealed/vectorcraft/boot/ambulance/proc/weewoo() + if(weewoocount>10) + weewoocount = 0 + + return + weewoo++ + +/obj/vehicle/sealed/vectorcraft/boot/ambulance/ui_interact(mob/user) // taken from the microwave/grinder + . = ..() + + var/list/options = list() + + if(isAI(user)) + options["radial_eject_car"] = radial_eject_car + else + if(vector["y"] == 0 && vector["x"] == 0) + options["radial_eject_car"] = radial_eject_car + if(Sl.occupant) + options["radial_heal"] = radial_heal + if(inserted_key) + if(!driver) + options["radial_eject_key"] = radial_eject_key + if(length(boot)) + options["radial_eject_boot"] = radial_eject_boot + + var/choice + + if(length(options) < 1) + return + if(length(options) == 1) + for(var/key in options) + choice = key + else + choice = show_radial_menu(user, src, options, require_near = !issilicon(user)) + + // post choice verification + if(isAI(user) || !user.canUseTopic(src, !issilicon(user))) + return + + switch(choice) + if("eject_car") + if(driver) + remove_occupant(driver) + else + for(var/mob/m in occupants) + remove_occupant(m) + if("radial_heal") + Sl.ui_interact(user) + if("eject_key") + to_chat(user, "You remove \the [inserted_key] from \the [src].") + inserted_key.forceMove(drop_location()) + user.put_in_hands(inserted_key) + inserted_key = null + if("eject_boot") + eject_boot(user) + + +/obj/vehicle/sealed/vectorcraft/boot/ambulance/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/reagent_containers/sleeper_buffer)) + var/obj/item/reagent_containers/sleeper_buffer/SB = I + if((SB.reagents.total_volume + Sl.reagents.total_volume) < Sl.reagents.maximum_volume) + SB.reagents.trans_to(Sl.reagents, SB.reagents.total_volume) + visible_message("[user] places the [SB] into the [src].") + qdel(SB) + return + else + SB.reagents.trans_to(Sl.reagents, SB.reagents.total_volume) + visible_message("[user] adds as much as they can to the [src] from the [SB].") + return + if(istype(I, /obj/item/reagent_containers)) + var/obj/item/reagent_containers/RC = I + if(RC.reagents.total_volume == 0) + to_chat(user, "The [I] is empty!") + for(var/datum/reagent/R in RC.reagents.reagent_list) + if((obj_flags & EMAGGED) || (allowed(usr))) + break + if(!istype(R, /datum/reagent/medicine)) + visible_message("The [src] gives out a hearty boop and rejects the [I]. The Sleeper's screen flashes with a pompous \"Medicines only, please.\"") + return + RC.reagents.trans_to(Sl.reagents, 1000) + visible_message("[user] adds as much as they can to the [src] from the [I].") + return diff --git a/modular_citadel/code/modules/vectorcrafts/vectorvariants.dm b/modular_citadel/code/modules/vectorcrafts/vectorvariants.dm new file mode 100644 index 0000000000..0fa1ec590d --- /dev/null +++ b/modular_citadel/code/modules/vectorcrafts/vectorvariants.dm @@ -0,0 +1,57 @@ +/obj/vehicle/sealed/vectorcraft/cyber + name = "Cyberscuttle" + desc = "A robust hovercar that, until recently, could self drive. Unfortunately it was found that the AI was terrified of orbs and drove away from them at all costs. Overall a smashing hovercar." + max_acceleration = 4.5 + accel_step = 0.4 + acceleration = 0.5 + max_deceleration = 3.5 + max_velocity = 95 + max_integrity = 150 + icon_state = "cyber" + +/obj/vehicle/sealed/vectorcraft/clown + name = "Clowncraft" + icon_state = "clowncar" + max_acceleration = 4.7 + accel_step = 0.4 + acceleration = 0.5 + max_deceleration = 4 + max_velocity = 90 + boost_power = 25 + max_integrity = 80 + +/obj/vehicle/sealed/vectorcraft/truck + name = "Hovertruck" + desc = "An all-terrain vehicle built for traversing rough terrain with ease." + gear = "auto" + icon_state = "truck" + max_acceleration = 4.25 + accel_step = 0.4 + acceleration = 0.5 + max_deceleration = 5 + max_velocity = 90 + boost_power = 10 + max_integrity = 200 + +/obj/vehicle/sealed/vectorcraft/ambulance + name = "Ambulance" + icon_state = "ambutruck" + max_acceleration = 4.25 + accel_step = 0.4 + acceleration = 0.5 + max_deceleration = 5 + max_velocity = 90 + boost_power = 40 + max_integrity = 200 + +/obj/vehicle/sealed/vectorcraft/auto + name = "Automatic hovercraft" + gear = "auto" + icon_state = "zoomscoot_auto" + max_acceleration = 4 + accel_step = 0.22 + acceleration = 0.30 + max_deceleration = 2 + max_velocity = 90 + boost_power = 5 + max_integrity = 100 diff --git a/modular_citadel/icons/mob/32x64_mam_ears.dmi b/modular_citadel/icons/mob/32x64_mam_ears.dmi new file mode 100644 index 0000000000..4edcc9dc7e Binary files /dev/null and b/modular_citadel/icons/mob/32x64_mam_ears.dmi differ diff --git a/modular_citadel/icons/mob/mam_tails.dmi b/modular_citadel/icons/mob/mam_tails.dmi index c1ffced3d5..f30f7480f6 100644 Binary files a/modular_citadel/icons/mob/mam_tails.dmi and b/modular_citadel/icons/mob/mam_tails.dmi differ diff --git a/modular_citadel/icons/mob/mam_taur.dmi b/modular_citadel/icons/mob/mam_taur.dmi index cf332019af..cc4bc0446c 100644 Binary files a/modular_citadel/icons/mob/mam_taur.dmi and b/modular_citadel/icons/mob/mam_taur.dmi differ diff --git a/modular_citadel/icons/mob/widerobot.dmi b/modular_citadel/icons/mob/widerobot.dmi index 50c29bb75f..cc986cfa9d 100644 Binary files a/modular_citadel/icons/mob/widerobot.dmi and b/modular_citadel/icons/mob/widerobot.dmi differ diff --git a/rust_g.dll b/rust_g.dll index 8ef1c59a10..26f6942861 100644 Binary files a/rust_g.dll and b/rust_g.dll differ diff --git a/sound/ambience/ambimaint10.ogg b/sound/ambience/ambimaint10.ogg new file mode 100644 index 0000000000..769f95f93d Binary files /dev/null and b/sound/ambience/ambimaint10.ogg differ diff --git a/sound/ambience/antag/thatshowfamiliesworks.ogg b/sound/ambience/antag/thatshowfamiliesworks.ogg new file mode 100644 index 0000000000..4ecad617e7 Binary files /dev/null and b/sound/ambience/antag/thatshowfamiliesworks.ogg differ diff --git a/sound/announcer/intern/alerts/1.ogg b/sound/announcer/intern/alerts/1.ogg new file mode 100644 index 0000000000..c4d182bc8c Binary files /dev/null and b/sound/announcer/intern/alerts/1.ogg differ diff --git a/sound/announcer/intern/alerts/10.ogg b/sound/announcer/intern/alerts/10.ogg new file mode 100644 index 0000000000..7380ccdeef Binary files /dev/null and b/sound/announcer/intern/alerts/10.ogg differ diff --git a/sound/announcer/intern/alerts/11.ogg b/sound/announcer/intern/alerts/11.ogg new file mode 100644 index 0000000000..ca548dcc20 Binary files /dev/null and b/sound/announcer/intern/alerts/11.ogg differ diff --git a/sound/announcer/intern/alerts/12.ogg b/sound/announcer/intern/alerts/12.ogg new file mode 100644 index 0000000000..8d71419798 Binary files /dev/null and b/sound/announcer/intern/alerts/12.ogg differ diff --git a/sound/announcer/intern/alerts/13.ogg b/sound/announcer/intern/alerts/13.ogg new file mode 100644 index 0000000000..128c7aa424 Binary files /dev/null and b/sound/announcer/intern/alerts/13.ogg differ diff --git a/sound/announcer/intern/alerts/14.ogg b/sound/announcer/intern/alerts/14.ogg new file mode 100644 index 0000000000..81d54101be Binary files /dev/null and b/sound/announcer/intern/alerts/14.ogg differ diff --git a/sound/announcer/intern/alerts/2.ogg b/sound/announcer/intern/alerts/2.ogg new file mode 100644 index 0000000000..a2ef615d56 Binary files /dev/null and b/sound/announcer/intern/alerts/2.ogg differ diff --git a/sound/announcer/intern/alerts/3.ogg b/sound/announcer/intern/alerts/3.ogg new file mode 100644 index 0000000000..51613ff036 Binary files /dev/null and b/sound/announcer/intern/alerts/3.ogg differ diff --git a/sound/announcer/intern/alerts/4.ogg b/sound/announcer/intern/alerts/4.ogg new file mode 100644 index 0000000000..874536ca72 Binary files /dev/null and b/sound/announcer/intern/alerts/4.ogg differ diff --git a/sound/announcer/intern/alerts/5.ogg b/sound/announcer/intern/alerts/5.ogg new file mode 100644 index 0000000000..0af0d28ce1 Binary files /dev/null and b/sound/announcer/intern/alerts/5.ogg differ diff --git a/sound/announcer/intern/alerts/6.ogg b/sound/announcer/intern/alerts/6.ogg new file mode 100644 index 0000000000..a65006a8c0 Binary files /dev/null and b/sound/announcer/intern/alerts/6.ogg differ diff --git a/sound/announcer/intern/alerts/7.ogg b/sound/announcer/intern/alerts/7.ogg new file mode 100644 index 0000000000..4a1d3f013a Binary files /dev/null and b/sound/announcer/intern/alerts/7.ogg differ diff --git a/sound/announcer/intern/alerts/8.ogg b/sound/announcer/intern/alerts/8.ogg new file mode 100644 index 0000000000..83ca80f493 Binary files /dev/null and b/sound/announcer/intern/alerts/8.ogg differ diff --git a/sound/announcer/intern/alerts/9.ogg b/sound/announcer/intern/alerts/9.ogg new file mode 100644 index 0000000000..3c0c45b25d Binary files /dev/null and b/sound/announcer/intern/alerts/9.ogg differ diff --git a/sound/announcer/intern/aliens.ogg b/sound/announcer/intern/aliens.ogg new file mode 100644 index 0000000000..9dd3c07697 Binary files /dev/null and b/sound/announcer/intern/aliens.ogg differ diff --git a/sound/announcer/intern/animes.ogg b/sound/announcer/intern/animes.ogg new file mode 100644 index 0000000000..36102c3e60 Binary files /dev/null and b/sound/announcer/intern/animes.ogg differ diff --git a/sound/announcer/intern/commandreport/1.ogg b/sound/announcer/intern/commandreport/1.ogg new file mode 100644 index 0000000000..e3108b13d1 Binary files /dev/null and b/sound/announcer/intern/commandreport/1.ogg differ diff --git a/sound/announcer/intern/commandreport/2.ogg b/sound/announcer/intern/commandreport/2.ogg new file mode 100644 index 0000000000..cd67500426 Binary files /dev/null and b/sound/announcer/intern/commandreport/2.ogg differ diff --git a/sound/announcer/intern/commandreport/3.ogg b/sound/announcer/intern/commandreport/3.ogg new file mode 100644 index 0000000000..94241c5ba5 Binary files /dev/null and b/sound/announcer/intern/commandreport/3.ogg differ diff --git a/sound/announcer/intern/granomalies.ogg b/sound/announcer/intern/granomalies.ogg new file mode 100644 index 0000000000..88944b63b2 Binary files /dev/null and b/sound/announcer/intern/granomalies.ogg differ diff --git a/sound/announcer/intern/intercept.ogg b/sound/announcer/intern/intercept.ogg new file mode 100644 index 0000000000..a87274abd9 Binary files /dev/null and b/sound/announcer/intern/intercept.ogg differ diff --git a/sound/announcer/intern/ionstorm.ogg b/sound/announcer/intern/ionstorm.ogg new file mode 100644 index 0000000000..9e7b5c6b23 Binary files /dev/null and b/sound/announcer/intern/ionstorm.ogg differ diff --git a/sound/announcer/intern/meteors.ogg b/sound/announcer/intern/meteors.ogg new file mode 100644 index 0000000000..c68c4bd8cc Binary files /dev/null and b/sound/announcer/intern/meteors.ogg differ diff --git a/sound/announcer/intern/outbreak5.ogg b/sound/announcer/intern/outbreak5.ogg new file mode 100644 index 0000000000..cf98b95fd7 Binary files /dev/null and b/sound/announcer/intern/outbreak5.ogg differ diff --git a/sound/announcer/intern/outbreak7.ogg b/sound/announcer/intern/outbreak7.ogg new file mode 100644 index 0000000000..297a1bbe8d Binary files /dev/null and b/sound/announcer/intern/outbreak7.ogg differ diff --git a/sound/announcer/intern/poweroff.ogg b/sound/announcer/intern/poweroff.ogg new file mode 100644 index 0000000000..4b71053653 Binary files /dev/null and b/sound/announcer/intern/poweroff.ogg differ diff --git a/sound/announcer/intern/poweron.ogg b/sound/announcer/intern/poweron.ogg new file mode 100644 index 0000000000..509cd398e6 Binary files /dev/null and b/sound/announcer/intern/poweron.ogg differ diff --git a/sound/announcer/intern/radiation.ogg b/sound/announcer/intern/radiation.ogg new file mode 100644 index 0000000000..08db53ebfd Binary files /dev/null and b/sound/announcer/intern/radiation.ogg differ diff --git a/sound/announcer/intern/shuttlecalled.ogg b/sound/announcer/intern/shuttlecalled.ogg new file mode 100644 index 0000000000..c903367cdf Binary files /dev/null and b/sound/announcer/intern/shuttlecalled.ogg differ diff --git a/sound/announcer/intern/shuttledock.ogg b/sound/announcer/intern/shuttledock.ogg new file mode 100644 index 0000000000..9f6ccd1a93 Binary files /dev/null and b/sound/announcer/intern/shuttledock.ogg differ diff --git a/sound/announcer/intern/shuttlerecalled.ogg b/sound/announcer/intern/shuttlerecalled.ogg new file mode 100644 index 0000000000..e259a79f35 Binary files /dev/null and b/sound/announcer/intern/shuttlerecalled.ogg differ diff --git a/sound/announcer/intern/spanomalies.ogg b/sound/announcer/intern/spanomalies.ogg new file mode 100644 index 0000000000..9bed8eae3a Binary files /dev/null and b/sound/announcer/intern/spanomalies.ogg differ diff --git a/sound/announcer/intern/welcome/1.ogg b/sound/announcer/intern/welcome/1.ogg new file mode 100644 index 0000000000..758f1967e0 Binary files /dev/null and b/sound/announcer/intern/welcome/1.ogg differ diff --git a/sound/announcer/intern/welcome/2.ogg b/sound/announcer/intern/welcome/2.ogg new file mode 100644 index 0000000000..c2e72be510 Binary files /dev/null and b/sound/announcer/intern/welcome/2.ogg differ diff --git a/sound/announcer/intern/welcome/3.ogg b/sound/announcer/intern/welcome/3.ogg new file mode 100644 index 0000000000..004f57371d Binary files /dev/null and b/sound/announcer/intern/welcome/3.ogg differ diff --git a/sound/announcer/intern/welcome/4.ogg b/sound/announcer/intern/welcome/4.ogg new file mode 100644 index 0000000000..c4e1f7667c Binary files /dev/null and b/sound/announcer/intern/welcome/4.ogg differ diff --git a/sound/announcer/intern/welcome/5.ogg b/sound/announcer/intern/welcome/5.ogg new file mode 100644 index 0000000000..641b8208a4 Binary files /dev/null and b/sound/announcer/intern/welcome/5.ogg differ diff --git a/sound/announcer/intern/welcome/6.ogg b/sound/announcer/intern/welcome/6.ogg new file mode 100644 index 0000000000..b0fc38237f Binary files /dev/null and b/sound/announcer/intern/welcome/6.ogg differ diff --git a/sound/effects/body-armor-rolling.ogg b/sound/effects/body-armor-rolling.ogg new file mode 100644 index 0000000000..220e6b4584 Binary files /dev/null and b/sound/effects/body-armor-rolling.ogg differ diff --git a/sound/effects/families_police.ogg b/sound/effects/families_police.ogg new file mode 100644 index 0000000000..38940f3f0a Binary files /dev/null and b/sound/effects/families_police.ogg differ diff --git a/sound/effects/rbmk/alarm.ogg b/sound/effects/rbmk/alarm.ogg new file mode 100644 index 0000000000..8e698a69f1 Binary files /dev/null and b/sound/effects/rbmk/alarm.ogg differ diff --git a/sound/effects/rbmk/meltdown.ogg b/sound/effects/rbmk/meltdown.ogg new file mode 100644 index 0000000000..9c0a1a9917 Binary files /dev/null and b/sound/effects/rbmk/meltdown.ogg differ diff --git a/sound/effects/rbmk/reactor_hum.ogg b/sound/effects/rbmk/reactor_hum.ogg new file mode 100644 index 0000000000..adc1e867ed Binary files /dev/null and b/sound/effects/rbmk/reactor_hum.ogg differ diff --git a/sound/effects/rbmk/switch.ogg b/sound/effects/rbmk/switch.ogg new file mode 100644 index 0000000000..668d3b0310 Binary files /dev/null and b/sound/effects/rbmk/switch.ogg differ diff --git a/sound/effects/rbmk/switch2.ogg b/sound/effects/rbmk/switch2.ogg new file mode 100644 index 0000000000..b9cd7d1540 Binary files /dev/null and b/sound/effects/rbmk/switch2.ogg differ diff --git a/sound/effects/rbmk/switch3.ogg b/sound/effects/rbmk/switch3.ogg new file mode 100644 index 0000000000..b89cbab4cc Binary files /dev/null and b/sound/effects/rbmk/switch3.ogg differ diff --git a/sound/effects/rbmk/turbine_end.ogg b/sound/effects/rbmk/turbine_end.ogg new file mode 100644 index 0000000000..55859aff90 Binary files /dev/null and b/sound/effects/rbmk/turbine_end.ogg differ diff --git a/sound/effects/rbmk/turbine_mid.ogg b/sound/effects/rbmk/turbine_mid.ogg new file mode 100644 index 0000000000..2010370425 Binary files /dev/null and b/sound/effects/rbmk/turbine_mid.ogg differ diff --git a/sound/effects/rbmk/turbine_start.ogg b/sound/effects/rbmk/turbine_start.ogg new file mode 100644 index 0000000000..4104d0f627 Binary files /dev/null and b/sound/effects/rbmk/turbine_start.ogg differ diff --git a/sound/effects/ship/freespace2/crane_1.wav b/sound/effects/ship/freespace2/crane_1.wav new file mode 100644 index 0000000000..394bd658cb Binary files /dev/null and b/sound/effects/ship/freespace2/crane_1.wav differ diff --git a/sound/effects/ship/reactor/falloutwind.ogg b/sound/effects/ship/reactor/falloutwind.ogg new file mode 100644 index 0000000000..4119371517 Binary files /dev/null and b/sound/effects/ship/reactor/falloutwind.ogg differ diff --git a/sound/effects/ship/reactor/startup.ogg b/sound/effects/ship/reactor/startup.ogg new file mode 100644 index 0000000000..4df6e736c5 Binary files /dev/null and b/sound/effects/ship/reactor/startup.ogg differ diff --git a/sound/effects/ship/reactor/startup2.ogg b/sound/effects/ship/reactor/startup2.ogg new file mode 100644 index 0000000000..b11e80fc82 Binary files /dev/null and b/sound/effects/ship/reactor/startup2.ogg differ diff --git a/sound/items/handling/screwdriver_drop.ogg b/sound/items/handling/screwdriver_drop.ogg new file mode 100644 index 0000000000..d460fd0aed Binary files /dev/null and b/sound/items/handling/screwdriver_drop.ogg differ diff --git a/sound/items/handling/screwdriver_pickup.ogg b/sound/items/handling/screwdriver_pickup.ogg new file mode 100644 index 0000000000..368f1bfd27 Binary files /dev/null and b/sound/items/handling/screwdriver_pickup.ogg differ diff --git a/sound/items/modsuit/atrocinator_step.ogg b/sound/items/modsuit/atrocinator_step.ogg new file mode 100644 index 0000000000..deda85ac35 Binary files /dev/null and b/sound/items/modsuit/atrocinator_step.ogg differ diff --git a/sound/items/modsuit/ballin.ogg b/sound/items/modsuit/ballin.ogg new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sound/items/modsuit/ballout.ogg b/sound/items/modsuit/ballout.ogg new file mode 100644 index 0000000000..f911f1a6a6 Binary files /dev/null and b/sound/items/modsuit/ballout.ogg differ diff --git a/sound/items/modsuit/flamethrower.ogg b/sound/items/modsuit/flamethrower.ogg new file mode 100644 index 0000000000..447245d50b Binary files /dev/null and b/sound/items/modsuit/flamethrower.ogg differ diff --git a/sound/items/modsuit/inflate_bloon.ogg b/sound/items/modsuit/inflate_bloon.ogg new file mode 100644 index 0000000000..9b030d66ce Binary files /dev/null and b/sound/items/modsuit/inflate_bloon.ogg differ diff --git a/sound/items/modsuit/loader_charge.ogg b/sound/items/modsuit/loader_charge.ogg new file mode 100644 index 0000000000..61d5531f72 Binary files /dev/null and b/sound/items/modsuit/loader_charge.ogg differ diff --git a/sound/items/modsuit/loader_launch.ogg b/sound/items/modsuit/loader_launch.ogg new file mode 100644 index 0000000000..513118f3c6 Binary files /dev/null and b/sound/items/modsuit/loader_launch.ogg differ diff --git a/sound/items/modsuit/magnetic_harness.ogg b/sound/items/modsuit/magnetic_harness.ogg new file mode 100644 index 0000000000..3d19fccc56 Binary files /dev/null and b/sound/items/modsuit/magnetic_harness.ogg differ diff --git a/sound/items/modsuit/rewinder.ogg b/sound/items/modsuit/rewinder.ogg new file mode 100644 index 0000000000..2587562dc1 Binary files /dev/null and b/sound/items/modsuit/rewinder.ogg differ diff --git a/sound/items/modsuit/springlock.ogg b/sound/items/modsuit/springlock.ogg new file mode 100644 index 0000000000..8d0013d263 Binary files /dev/null and b/sound/items/modsuit/springlock.ogg differ diff --git a/sound/items/modsuit/tem_shot.ogg b/sound/items/modsuit/tem_shot.ogg new file mode 100644 index 0000000000..50905b95f1 Binary files /dev/null and b/sound/items/modsuit/tem_shot.ogg differ diff --git a/sound/items/modsuit/time_anchor_set.ogg b/sound/items/modsuit/time_anchor_set.ogg new file mode 100644 index 0000000000..457f8e6dba Binary files /dev/null and b/sound/items/modsuit/time_anchor_set.ogg differ diff --git a/sound/items/taperecorder/tape_flip.ogg b/sound/items/taperecorder/tape_flip.ogg new file mode 100644 index 0000000000..fae3e07373 Binary files /dev/null and b/sound/items/taperecorder/tape_flip.ogg differ diff --git a/sound/items/taperecorder/taperecorder_close.ogg b/sound/items/taperecorder/taperecorder_close.ogg new file mode 100644 index 0000000000..ab9f521c5f Binary files /dev/null and b/sound/items/taperecorder/taperecorder_close.ogg differ diff --git a/sound/items/taperecorder/taperecorder_hiss_mid.ogg b/sound/items/taperecorder/taperecorder_hiss_mid.ogg new file mode 100644 index 0000000000..50ef4f2171 Binary files /dev/null and b/sound/items/taperecorder/taperecorder_hiss_mid.ogg differ diff --git a/sound/items/taperecorder/taperecorder_hiss_start.ogg b/sound/items/taperecorder/taperecorder_hiss_start.ogg new file mode 100644 index 0000000000..fa57041a72 Binary files /dev/null and b/sound/items/taperecorder/taperecorder_hiss_start.ogg differ diff --git a/sound/items/taperecorder/taperecorder_open.ogg b/sound/items/taperecorder/taperecorder_open.ogg new file mode 100644 index 0000000000..7b7110fa58 Binary files /dev/null and b/sound/items/taperecorder/taperecorder_open.ogg differ diff --git a/sound/items/taperecorder/taperecorder_play.ogg b/sound/items/taperecorder/taperecorder_play.ogg new file mode 100644 index 0000000000..1bf4d7a3bd Binary files /dev/null and b/sound/items/taperecorder/taperecorder_play.ogg differ diff --git a/sound/items/taperecorder/taperecorder_print.ogg b/sound/items/taperecorder/taperecorder_print.ogg new file mode 100644 index 0000000000..7912d08dc9 Binary files /dev/null and b/sound/items/taperecorder/taperecorder_print.ogg differ diff --git a/sound/items/taperecorder/taperecorder_stop.ogg b/sound/items/taperecorder/taperecorder_stop.ogg new file mode 100644 index 0000000000..a3b0f65992 Binary files /dev/null and b/sound/items/taperecorder/taperecorder_stop.ogg differ diff --git a/sound/machines/creak.ogg b/sound/machines/creak.ogg new file mode 100644 index 0000000000..edb9802b08 Binary files /dev/null and b/sound/machines/creak.ogg differ diff --git a/sound/machines/scanbuzz.ogg b/sound/machines/scanbuzz.ogg new file mode 100644 index 0000000000..d3422bc8f4 Binary files /dev/null and b/sound/machines/scanbuzz.ogg differ diff --git a/sound/machines/wewewew.ogg b/sound/machines/wewewew.ogg new file mode 100644 index 0000000000..b521e0c976 Binary files /dev/null and b/sound/machines/wewewew.ogg differ diff --git a/sound/mecha/hydraulic.ogg b/sound/mecha/hydraulic.ogg new file mode 100644 index 0000000000..3281ed2dc0 Binary files /dev/null and b/sound/mecha/hydraulic.ogg differ diff --git a/sound/mecha/mech_shield_deflect.ogg b/sound/mecha/mech_shield_deflect.ogg new file mode 100644 index 0000000000..5c1970d872 Binary files /dev/null and b/sound/mecha/mech_shield_deflect.ogg differ diff --git a/sound/mecha/mech_shield_drop.ogg b/sound/mecha/mech_shield_drop.ogg new file mode 100644 index 0000000000..21c6cb5edb Binary files /dev/null and b/sound/mecha/mech_shield_drop.ogg differ diff --git a/sound/mecha/mech_shield_raise.ogg b/sound/mecha/mech_shield_raise.ogg new file mode 100644 index 0000000000..65ad70ad14 Binary files /dev/null and b/sound/mecha/mech_shield_raise.ogg differ diff --git a/sound/misc/bloop.ogg b/sound/misc/bloop.ogg new file mode 100644 index 0000000000..cfe1c24426 Binary files /dev/null and b/sound/misc/bloop.ogg differ diff --git a/sound/misc/emergency_meeting.ogg b/sound/misc/emergency_meeting.ogg new file mode 100644 index 0000000000..ad27236ef0 Binary files /dev/null and b/sound/misc/emergency_meeting.ogg differ diff --git a/sound/misc/license.txt b/sound/misc/license.txt new file mode 100644 index 0000000000..b92a4a279a --- /dev/null +++ b/sound/misc/license.txt @@ -0,0 +1,5 @@ +bloop.ogg by my man Tim Khan +(https://freesound.org/people/tim.kahn/sounds/130377/) + +knuckles.ogg by CGEffex. Shortened and cut. +https://freesound.org/people/CGEffex/sounds/93981/ \ No newline at end of file diff --git a/sound/misc/seth.ogg b/sound/misc/seth.ogg new file mode 100644 index 0000000000..8def150775 Binary files /dev/null and b/sound/misc/seth.ogg differ diff --git a/sound/surgery/cautery1.ogg b/sound/surgery/cautery1.ogg new file mode 100644 index 0000000000..fa714439e5 Binary files /dev/null and b/sound/surgery/cautery1.ogg differ diff --git a/sound/surgery/cautery2.ogg b/sound/surgery/cautery2.ogg new file mode 100644 index 0000000000..334c98f6cd Binary files /dev/null and b/sound/surgery/cautery2.ogg differ diff --git a/sound/surgery/hemostat1.ogg b/sound/surgery/hemostat1.ogg new file mode 100644 index 0000000000..d68c82620d Binary files /dev/null and b/sound/surgery/hemostat1.ogg differ diff --git a/sound/surgery/organ1.ogg b/sound/surgery/organ1.ogg new file mode 100644 index 0000000000..d6cdd6271f Binary files /dev/null and b/sound/surgery/organ1.ogg differ diff --git a/sound/surgery/organ2.ogg b/sound/surgery/organ2.ogg new file mode 100644 index 0000000000..9199c7d1a2 Binary files /dev/null and b/sound/surgery/organ2.ogg differ diff --git a/sound/surgery/retractor1.ogg b/sound/surgery/retractor1.ogg new file mode 100644 index 0000000000..de7c31199e Binary files /dev/null and b/sound/surgery/retractor1.ogg differ diff --git a/sound/surgery/retractor2.ogg b/sound/surgery/retractor2.ogg new file mode 100644 index 0000000000..620fafe035 Binary files /dev/null and b/sound/surgery/retractor2.ogg differ diff --git a/sound/surgery/saw.ogg b/sound/surgery/saw.ogg new file mode 100644 index 0000000000..8e7a47f0fa Binary files /dev/null and b/sound/surgery/saw.ogg differ diff --git a/sound/surgery/scalpel1.ogg b/sound/surgery/scalpel1.ogg new file mode 100644 index 0000000000..6c0fe5dad9 Binary files /dev/null and b/sound/surgery/scalpel1.ogg differ diff --git a/sound/surgery/scalpel2.ogg b/sound/surgery/scalpel2.ogg new file mode 100644 index 0000000000..4976722393 Binary files /dev/null and b/sound/surgery/scalpel2.ogg differ diff --git a/sound/vehicles/boost.ogg b/sound/vehicles/boost.ogg new file mode 100644 index 0000000000..92ff266b8c Binary files /dev/null and b/sound/vehicles/boost.ogg differ diff --git a/sound/vehicles/boost_ready.ogg b/sound/vehicles/boost_ready.ogg new file mode 100644 index 0000000000..42030ee600 Binary files /dev/null and b/sound/vehicles/boost_ready.ogg differ diff --git a/sound/vehicles/carcannon1.ogg b/sound/vehicles/carcannon1.ogg new file mode 100644 index 0000000000..751fa6f754 Binary files /dev/null and b/sound/vehicles/carcannon1.ogg differ diff --git a/sound/vehicles/carcannon2.ogg b/sound/vehicles/carcannon2.ogg new file mode 100644 index 0000000000..7bc86d7cbc Binary files /dev/null and b/sound/vehicles/carcannon2.ogg differ diff --git a/sound/vehicles/carcannon3.ogg b/sound/vehicles/carcannon3.ogg new file mode 100644 index 0000000000..80407e553f Binary files /dev/null and b/sound/vehicles/carcannon3.ogg differ diff --git a/sound/vehicles/clowncar_cannonmode1.ogg b/sound/vehicles/clowncar_cannonmode1.ogg new file mode 100644 index 0000000000..aa21c8f990 Binary files /dev/null and b/sound/vehicles/clowncar_cannonmode1.ogg differ diff --git a/sound/vehicles/clowncar_cannonmode2.ogg b/sound/vehicles/clowncar_cannonmode2.ogg new file mode 100644 index 0000000000..931e146422 Binary files /dev/null and b/sound/vehicles/clowncar_cannonmode2.ogg differ diff --git a/sound/vehicles/clutch_fail.ogg b/sound/vehicles/clutch_fail.ogg new file mode 100644 index 0000000000..c8e07a6251 Binary files /dev/null and b/sound/vehicles/clutch_fail.ogg differ diff --git a/sound/vehicles/clutch_win.ogg b/sound/vehicles/clutch_win.ogg new file mode 100644 index 0000000000..0af36eed8e Binary files /dev/null and b/sound/vehicles/clutch_win.ogg differ diff --git a/sound/vehicles/high_eng.ogg b/sound/vehicles/high_eng.ogg new file mode 100644 index 0000000000..7da7233c09 Binary files /dev/null and b/sound/vehicles/high_eng.ogg differ diff --git a/sound/vehicles/low_eng.ogg b/sound/vehicles/low_eng.ogg new file mode 100644 index 0000000000..d6843b87c5 Binary files /dev/null and b/sound/vehicles/low_eng.ogg differ diff --git a/sound/vehicles/norm_eng.ogg b/sound/vehicles/norm_eng.ogg new file mode 100644 index 0000000000..7fb70e6760 Binary files /dev/null and b/sound/vehicles/norm_eng.ogg differ diff --git a/sound/vehicles/skid.ogg b/sound/vehicles/skid.ogg new file mode 100644 index 0000000000..08ae4116ca Binary files /dev/null and b/sound/vehicles/skid.ogg differ diff --git a/sound/voice/barks/chitter.ogg b/sound/voice/barks/chitter.ogg new file mode 100644 index 0000000000..0d162fa303 Binary files /dev/null and b/sound/voice/barks/chitter.ogg differ diff --git a/sound/weapons/revolverempty.ogg b/sound/weapons/revolverempty.ogg new file mode 100644 index 0000000000..81ddb1e2e0 Binary files /dev/null and b/sound/weapons/revolverempty.ogg differ diff --git a/strings/cas_white.txt b/strings/cas_white.txt index 3e229862a2..397c7febff 100644 --- a/strings/cas_white.txt +++ b/strings/cas_white.txt @@ -72,7 +72,7 @@ Supermatter undergarments. A permaban. Stealing all the miners' ore. Bluespace artillery. -Poly reading porn over the radio again. +Polly reading porn over the radio again. Mining the shaft. Grab intent. A blob zombie with an erection. diff --git a/strings/flavor_objectives/traitor/assistant.txt b/strings/flavor_objectives/traitor/assistant.txt index e69de29bb2..0ce4c3b131 100644 --- a/strings/flavor_objectives/traitor/assistant.txt +++ b/strings/flavor_objectives/traitor/assistant.txt @@ -0,0 +1 @@ +There are no flavor objectives for this job so you got this one because it's needed for Github to stop screaming. If you get this because someone enabled flavor objectives without rechecking them, yell at coders. \ No newline at end of file diff --git a/strings/flavor_objectives/traitor/engineering.txt b/strings/flavor_objectives/traitor/engineering.txt index e69de29bb2..0ce4c3b131 100644 --- a/strings/flavor_objectives/traitor/engineering.txt +++ b/strings/flavor_objectives/traitor/engineering.txt @@ -0,0 +1 @@ +There are no flavor objectives for this job so you got this one because it's needed for Github to stop screaming. If you get this because someone enabled flavor objectives without rechecking them, yell at coders. \ No newline at end of file diff --git a/strings/flavor_objectives/traitor/medical.txt b/strings/flavor_objectives/traitor/medical.txt index e69de29bb2..0ce4c3b131 100644 --- a/strings/flavor_objectives/traitor/medical.txt +++ b/strings/flavor_objectives/traitor/medical.txt @@ -0,0 +1 @@ +There are no flavor objectives for this job so you got this one because it's needed for Github to stop screaming. If you get this because someone enabled flavor objectives without rechecking them, yell at coders. \ No newline at end of file diff --git a/strings/phobia.json b/strings/phobia.json index fc8fb31995..ee25cc62fa 100644 --- a/strings/phobia.json +++ b/strings/phobia.json @@ -250,6 +250,7 @@ "bird", "beak", "poly", + "polly", "wing", "claw", "peck", diff --git a/strings/sillytips.txt b/strings/sillytips.txt index 8e28284534..ba10f80bf1 100644 --- a/strings/sillytips.txt +++ b/strings/sillytips.txt @@ -8,14 +8,14 @@ Just like real life the entropy of the game can only increase with time. If thin Completing your objectives is good practice, but the best antagonists will strive to do more than the bare minimum to really leave an impression. The more obscure and underused a game mechanic is, the less likely your victims are to be able to deal with it. Space is cold and it will quickly freeze you to death if you don't protect yourself. This isn't how thermodynamics really works but just go with it. -Blobs are weak to fire! Use a flame thrower for maximum damage! +Blobs are weak to fire! Use a flamethrower for maximum friendly fire! Cleanbot. The wizard is supposed to be extremely strong in one on one combat, stop getting mad about it. Sometimes a round will just be a bust. C'est la vie. This is a game that is constantly being developed for. Expect things to be added, removed, fixed, and broken on a daily basis. It's fun to try and predict the round type from the tip of the round message. They said the QM could never be a head, but we showed them. -The birb remembers. +The bird remembers. Your sprite represents your hitbox, so that afro makes you easier to kill. The sacrifices we make for style. Sometimes admins will just do stuff. Roll with it. The remake will never come out. @@ -32,18 +32,22 @@ There are at least 11 ways to get through plastic flaps. How many can you name? FEED ME A STRAY CAT Did you know that tossing the clown into a singularity will either increase or decrease its size by a large amount? Don't worry, you can always circlejerk your hate on the discord about furries. -Play a Vampire, they're overpowered and broken with no downsides that matter! -You can make a Beepsky with E-swords that will murder people for not wearing their IDs! -You can make a Beepsky with Toy-E-Swords if you want. It's like a cheaper Beepsky that will trip people and maybe shout on the sec channel about people its "Arresting" -There is a magic chem that turns people into Cat Girls/Boys. Its called "Felinid Mutation Toxin"! -Having Neko ears and tails or Cat ears and tails does not make you into a Felinid race! -Mhelp is basically useless, and never used correctly. Being a Mentor just means that admins will do Mhelps for you and you get to learn the round type when someone asks you a basic question regarding their antag status. -Toxins Bombs are not the only way to get RnD points. However, nobody will ever do any other method to get sci points... +You can make a Beepsky with E-swords instead of batons that will kill people for existing wrong. +You can make a Beepsky with Toy-E-Swords instead of batons that will try to kill people out of spite alone. +Do not ask about the purrbation. +Ask about the purrbation. +Mhelp is basically useless, and never used correctly. Being a Mentor just means that Admins will answer tickets for you and you get to learn the round type when someone asks a basic question regarding their antag role. +Toxins Bombs are the only way to get Research points. There's others, but we don't talk about them. Plasma men are a powerful race with many perks! No really, I swear! So what if they need an "ERP Plasma room" to fuck, who cares! -As a Cargo Tech make sure to always buy a tesla to sell back to CC. They love those those. Trust me! +As a Cargo Technician make sure to always buy a tesla to sell back to CC. They love those. Trust me! ;HELP MAINT +Help. Admins always regret meme options in their polls. Putting cat ears on securitrons makes them table people and nya. Mekhi isn't a cat, but he still goes on the table, just roll with it. As a Changeling, you can live without a head as they are merely vestigal to you, now, finally, you can be a Dullahan without it being Halloween. People actually have fictional sex between fictional characters in this game. When in doubt, take a break. A long break, preferably. If the game is wearing down your mental state and it's starting to lose any semblance of fun value, go and do something else for a month or two. By the time you come back, everything you liked will have been changed anyways. +Coders aren't real people. +MARRY AND REPRODUCE +TOUCH GRASS +Floorbot. diff --git a/strings/tips.txt b/strings/tips.txt index d4373b3606..46dfe1d796 100644 --- a/strings/tips.txt +++ b/strings/tips.txt @@ -1,93 +1,97 @@ Where the space map levels connect is randomized every round, but are otherwise kept consistent within rounds. Remember that they are not necessarily bidirectional! You can catch thrown items by toggling on your throw mode with an empty hand active. -To crack the safe in the vault, have a stethoscope in one of your hands and fiddle with the tumbler or you can alternatively use several concentrated explosive charges on it. Remember that the latter may result in the contents of the safe becoming a pile of ash. +To crack the safe in the vault, have a stethoscope in one of your hands and fiddle with the tumbler or use a couple C4s on it. Remember the latter option may result in the contents of the safe becoming non-existant. You can climb onto a table by dragging yourself onto one. This takes time and drops the items in your hands on the table. Clicking on a table that someone else is climbing onto will knock them down. You can drag other players onto yourself to open the strip menu, letting you remove their equipment or force them to wear something. Note that exosuits or helmets will block your access to the clothing beneath them, and that certain items take longer to strip or put on than others. Clicking on a windoor rather then bumping into it will keep it open, you can click it again to close it. You can spray a fire extinguisher, throw items or fire a gun while floating through space to change your direction. Simply fire opposite to where you want to go. You can change the control scheme by pressing tab. One is WASD, the other is the arrow keys. Keep in mind that hotkeys are also changed with this. -All vending machines can be hacked to obtain some contraband items from them, and many may charge extra credits to give you premium items. +Most vending machines can be hacked to obtain contraband items from them. Firesuits and winter coats offer mild protection from the cold, allowing you to spend longer periods of time near breaches and space than if wearing nothing at all. +A firesuit and a hardhat make you immune to pressure damage, allowing you to spacewalk while only worrying about the cold. Glass shards can be welded to make glass, and metal rods can be welded to make metal. Ores can be welded too, but this takes a lot of fuel. If you need to drag multiple people either to safety or to space, bring a locker or crate over and stuff them all in before hauling them off. You can grab someone by clicking on them with the grab intent, then upgrade the grab by clicking on them once more. An aggressive grab can temporarily stun someone depending on their luck with resisting out of it, allowing you to slam them on a table by clicking on it, or throw them by toggling on throwing. -Holding alt and left clicking a tile will allow you to see its contents in the top right window pane, which is much faster than right clicking. +Holding alt and left clicking a tile will allow you to see its contents in the top right window pane, which is generally faster than right clicking. The resist button will allow you to resist out of handcuffs, being buckled to a chair or bed, out of locked lockers and more. Whenever you're stuck, try resisting! You can move an item out of the way by dragging it and then clicking on an adjacent tile with an empty hand. -You can recolor certain items like jumpsuits and gloves in washing machines by also throwing in a crayon. For more advanced fashion you can spray items with a spray can to tint its colors. Some items work better than others at displaying their tints, like sterile and paper masks, or darkly colored gloves. +You can recolor certain items like jumpsuits and gloves in washing machines by also throwing in a crayon. For more advanced fashion you can spray items with a spray can to change their tint, or toy with color matrixes at the ColorMate. Maintenance is full of equipment that is randomized every round. Look around and see if anything is worth using. Some roles cannot be antagonists by default, but antag selection is decided first. For instance, you can set Security Officer to High without affecting your chances of becoming an antag - the game will just assign you to your next preferred role - or in the case that you have no such preferences set, a random role entirely. There are many places around the station to hide contraband. A few for starters: linen boxes, toilet cisterns, body bags. Experiment to find more! -On all maps, you can use a machine in the vault to deposit space cash for cargo points. Otherwise, use it to steal the station's cash and get out before the alarm goes off. -As the Captain, you are one of the highest priority targets on the station. Everything from revolutions looking to thwart your rule, to nuclear operatives seeking the disk, to traitors that need to rob you of your several high value items - or your life are all things to be concerned about. +On all maps, you can use the bank terminal in the vault to deposit space cash for cargo points. On the contrary, can be used to drain the station's cash. Just remember to get out before the alarm goes off! +As the Captain, you are one of the highest priority targets on the station. Everything from revolutions looking to thwart your rule, to nuclear operatives seeking the station's destruction, or simply down-bad antagonists looking for loot. Walk with eyes behind your head at all times. As the Captain, always take the nuclear disk and pinpointer with you every shift. It's a good idea to give one of these to another head you can trust with keeping it safe, such as the Head of Personnel. As the Captain, you have absolute access and control over the station, but this does not mean that being a horrible person won't result in mutiny and a ban. As the Captain, you have a fancy pen that can be used as a holdout dagger or even as a scalpel in surgery! As the Captain, you can purchase a new emergency shuttle using a communications console. Some require credits, while others give you credits in exchange. Keep in mind that purchasing dangerous shuttles will incur the ire of your crew. -As the Chief Medical Officer, your hypospray is like the ones that your Medical Doctors can buy, except it comes in a fancy box that can hold several more hypovials than the standard, and already comes preloaded with specially-made high-capacity hypovials that hold double the reagents the standard ones do. +As the Chief Medical Officer, your hypospray is like the ones that your Medical Doctors can buy, except it comes in a fancy box that can hold several more hypovials than the standard, and already comes preloaded with special high-capacity hypovials that hold double the reagents the standard ones do. As the Chief Medical Officer, coordinate and communicate with your doctors, chemists, and paramedics during a nuclear emergency, blob infestation, or some other crisis to keep people alive and fighting. -As a Medical Doctor, pester Research for improved surgical tools. They work faster, combine the purposes of several tools in one (scalpel/saw, retractor/hemostat, drill/cautery), and don't cost many materials to boot! -As a Medical Doctor, the surgical saw and drill are both powerful weapons, the saw is sharp and can slice and dice, while the drill can quickly blind someone if aimed for the eyes. The laser scalpel is an upgraded version producible with Research's aid, and it has the highest force of most common place weapons, while still remaining sharp. -As a Medical Doctor, your belt can hold a full set of surgical tools. Using sterilizine before each attempt during surgery will reduce your failure chance on tricky steps or when using less-than-optimal equipment. -As a Medical Doctor, you can attempt to drain blood from a husk with a syringe to determine the cause. If you can extract blood, it was caused by extreme temperatures or lasers, if there is no blood to extract, you have confirmed the presence of changelings. -As a Medical Doctor, while both heal toxin damage, the difference between charcoal and antitoxin is that charcoal will actively remove all other reagents from one's body, while antitoxin only removes various toxins - but can overdose. +As a Medical Doctor, pester Research for upgraded surgical tools. They work faster and combine the purposes of several tools in one (scalpel/saw, retractor/hemostat, drill/cautery). +As a Medical Doctor, the surgical saw and drill are both powerful weapons, the saw is sharp and can cause wounds, while the drill can quickly blind someone if aimed for the eyes. The laser scalpel is an upgraded version of the saw producible with Research's aid, and it has the highest force of any printable weapon, while still remaining sharp. +As a Medical Doctor, your belt can hold up to a full set of surgical tools alongside most other medical equipment. +As a Medical Doctor, sterilizine will dramaticlaly increase the chances of consecutive surgical steps. Consider applying some during tricky surgical steps or when using less-than-optimal equipment. +As a Medical Doctor, you can attempt to drain blood from a husk with a syringe to determine the cause. If you can extract blood, it was likely caused by extreme temperatures or lasers, if there is no blood to extract, you may have confirmed the presence of changelings. +As a Medical Doctor, while both heal toxin damage, the difference between charcoal and antitoxin is that charcoal will actively remove all other reagents from one's body with no maluses, while antitoxin only removes various toxins - but can overdose. As a Medical Doctor, you can surgically implant or extract things from people's chests by performing a cavity implant. This could range from inserting a suicide bomb to embedding the nuke disk into the Captain's chest. -As a Medical Doctor, it's of utmost urgency that you tend to anyone who's been hugged by a facehugger. You only have a couple of minutes from the initial attachment to perform organ manipulation to their chest and remove the rapidly developing alien embryo before it bursts out and immediately kills your patient. +As a Medical Doctor, it's of utmost urgency that you tend to anyone who's been hugged by a facehugger. You only have a couple of minutes from the initial attachment to perform organ manipulation on their chest and remove the alien embryo before it bursts out as a dangerous alien larva. As a Medical Doctor, you must target the correct limb and be on help intent when trying to perform surgery on someone. Using disarm attempt will intentionally fail the surgery step. -As a Medical Doctor, corpses with the "...and their soul has departed" description no longer have a ghost attached to them and can't be revived. However it may prove useful to be creative in your revivification techniques with these bodies. +As a Medical Doctor, corpses with the "...and their soul has departed" description no longer have a ghost attached to them and can't be revived. However it may prove useful to keep an eye on these corpses in event their owner comes back. +As a Medical Doctor, morgue slabs will display differing colors depending on what's inside. Red is a currently-unrevivable corpse, yellow is a non-organic object, and green is a currently-revivable corpse. The latter-most will play an alarm whenever a ghost occupies the dead body. As a Medical Doctor, treating plasmamen is not impossible! Salbutamol and epinephrine stops them from suffocating due to lack of internals and showers stop them from burning alive. You can even perform surgery on them by doing the procedure on a roller bed under a shower. As a Medical Doctor, you can point your penlight at people to create a medical hologram. This lets them know that you're coming to treat them. As a Medical Doctor, you can extract implants by holding an empty implant case in your offhand while performing the extraction step. As a Medical Doctor, clone scanning people will implant them with a health tracker that displays their vitals in the clone records. Useful to check on crew members that didn't activate suit sensors! As a Medical Doctor, you can deal with patients who have absurd amounts of wounds by putting them in cryo. This will slowly treat all of their wounds simultaneously, but is much slower than direct treatment. -As a Medical Doctor, Critical Slash wounds are one of the most dangerous conditions someone can have. Apply gauze, epipens, sutures, cauteries, whatever you can, as soon as possible! +As a Medical Doctor, weeping avulsions are one of the most dangerous conditions someone can have. Apply gauze, epipens, sutures, cauteries, whatever you can, as soon as possible! As a Medical Doctor, Saline-Glucose not only acts as a temporary boost to a patient's blood level, it also speeds regeneration! Perfect for drained patients! -As a Medical Doctor, medical gauze is an incredibly underrated tool. It can be used to entirely halt a limb from bleeding or sling one that's been shattered until it can be given proper attention. This even works on the dead, too! Be sure to stop someone's bleeding whether they're in critical condition or a corpse, as dragging someone whom is bleeding will rapidly deplete them of all their blood. +As a Medical Doctor, medical gauze is an incredibly useful tool. It can be used to staunch a limb's bleeding bleeding or sling one that's been broken until it can be given proper attention. This even works on the dead, too! +As a Medical Doctor, dragging someone who is bleeding will rapidly cause their blood levels to drop into lethal levels - use fireman carrying, roller beds or even closets and crates to transport patients without giving yourself more work. As a Chemist, there are dozens of chemicals that can heal, and even more that can cause harm. See which chemicals have the best synergy, both in healing, and in harming. Experiment! As a Chemist, some chemicals can only be synthesized by heating up the contents in the chemical heater. As a Chemist, you will be expected to supply crew with certain chemicals. For example, clonexadone and mannitol for the cryo tubes, unstable mutagen and saltpetre for botany as well as healing pills and patches for the front desk. As a Chemist, you can make 100u bottles from plastic sheets. The ChemMaster can produce infinite 30u glass bottles as well. -As a Chemist, be sure to stock up some hypovials with useful chemicals for any doctors looking to heal on the go, you can also print out the deluxe hypovials at an autolathe specifically for the CMO's special hypospray. -As a Chemist, the reagent dartgun, while neutered in its ability to harm - can still be loaded up with morphine for a ghetto sedation weapon, and a quick shot of charcoal can make a slime hybrid regret their life choices in an instant. +As a Chemist, be sure to stock up some hypovials with useful chemicals for any doctors looking to heal on the go - you can also print deluxe hypovials at an autolathe for the CMO's special hypospray. +As a Chemist, the reagent dartgun, while neutered in its ability to harm - can still be loaded with morphine for a ghetto sedation weapon, and a quick shot of charcoal can make a slime hybrid regret their life choices in an instant. As a Geneticist, you can eject someone from cloning early by clicking on the cloner pod with your ID. Note that they will suffer more genetic damage and may lose vital organs from this. -As a Geneticist, becoming a hulk makes you capable of dealing high melee damage, becoming immune to most traditional stuns, and punching through walls. However, you can't fire guns, and will lose your hulk status if you take too much damage. -As the Virologist, your viruses can range from healing powers so great that you can heal out of critical status, or diseases so dangerous they can kill the entire crew with airborne spontaneous combustion. Experiment! +As a Geneticist, becoming a hulk makes you capable of dealing high melee damage, becoming immune to most traditional stuns, and punching through walls. However, you can't fire guns, and will lose your hulk status if you enter critical condition. +As the Virologist, your viruses can range from healing powers so great they heal you out of critical condition, or diseases so dangerous they can kill the entire crew with airborne spontaneous combustion. Experiment! As the Virologist, you only require small amounts of vaccine to heal a sick patient. Work with the Chemist to distribute your cures more efficiently. As the Research Director, you can take AIs out of their cores by loading them into an intelliCard, and then from there into an AI system integrity restorer computer to revive and/or repair them. As the Research Director, you can lock down cyborgs instead of blowing them up. Then you can have their laws reset or if that doesn't work, safely dismantled. As the Research Director, you can upgrade your modular console with better computer parts to speed up its functions. This can be useful when using the AI system integrity restorer. As the Research Director, your console's NTnet monitoring tool can be used to retrieve airlock passkeys, provided that someone used a door remote. -As a Scientist, you can use the mutation toxin obtained from green slimes to turn yourself into a jelly mutant. Each subspecies has unique features - for example telepathic powers, duplicating bodies or integrating slime extracts for several unique effects! +As a Scientist, you can use the mutation toxin obtained from green slimes to turn yourself into a jelly mutant. Each subspecies has unique features - from telepathic powers and duplicating bodies or integrating slime extracts for several unique effects! As a Scientist, you can maximize the number of uses you get out of a slime by feeding it slime steroid, created from purple slimes, while alive. You can then apply extract enhancer, created from cerulean slimes, on each extract. -As a Scientist, you can disable anomalies by scanning them with an analyzer, and then sending a signal on the frequency it gives you with a remote signalling device. Alternatively, you can print out anomaly defusal tools which can instantly disable an anomaly at the protolathe with some research, both of these methods will leave behind an anomaly core, which can be used to construct a Phazon mech, or be used in the destructive analyzer for a 10,000 point bonus! +As a Scientist, you can disable anomalies by scanning them with an analyzer, and then sending a signal on the frequency it gives you with a remote signalling device. Alternatively, you can print anomaly defusal tools which can instantly disable an anomaly at the protolathe with some research, both of these methods will leave behind an anomaly core, which can be used for a couple scientific boons. As a Scientist, researchable stock parts can seriously improve the efficiency and speed of machines around the station. In some cases, it can even unlock new functions. As a Scientist, you can generate research points by letting the tachyon-doppler array record increasingly large explosions. As a Scientist, getting drunk just enough will speed up research. Skol! As a Scientist, you can get points by placing slime cores into the destructive analyzer! This even works with crossbred slime cores. -As a Scientist, you can get a minuscule amount of points by sacrificing a packet of seeds from Hydroponics into the destructive analyzer! While each individual one may not yield many points per, you can quite easily amass a very large variety of seeds, which could add up over time for a couple extra minutes shaved off of maxing out RND. +As a Scientist, you can get points by placing seed packets into the destructive analyzer! This even works with mutated plants. +As a Scientist, any machine which prints things - be it your protolathe or circuit imprinters - can be used to teleport raw materials directly from the ore silo straight into your workplace. As a Roboticist, keep an ear out for anomaly announcements. If you get your hands on an anomaly core, you can build a Phazon mech! -As a Roboticist, you can repair your cyborgs with a welding tool. If they have taken burn damage from lasers, you can remove their battery, expose the wiring with a screwdriver and replace their wires with a cable coil. +As a Roboticist, you can repair a cyborg's brute damage with a welding tool. If they have taken burn damage, you can remove their battery, expose the wiring with a screwdriver and replace their wires with a cable coil. As a Roboticist, you can reset a cyborg's module by cutting and mending the reset wire with a wire cutter. -As a Roboticist, pay mind when toying with a cyborg's wires. It's best to pulse wires before immediately cutting them, as cutting them right away without knowing what they do may sever them from the AI, or disable their camera. +As a Roboticist, pay mind when toying with a cyborg's wires. It's best to pulse wires before immediately cutting them, as cutting them right away without knowing what they do may sever them from the AI or disable their camera. As a Roboticist, you can greatly help out Shaft Miners by building a Firefighter APLU equipped with a hydraulic clamp and plasma cutter. The mech is ash storm proof and can even walk across lava! -As a Roboticist, you can augment people with cyborg limbs. Augmented limbs are immune to the vacuum of space and temperatures while they can very easily be repaired with welders (brute) and cable coils (burn). -As a Roboticist, you can use your printer that is linked to the ore silo to teleport mats into your work place! +As a Roboticist, you can augment people with cyborg limbs. Augmented limbs are immune both pressure and temperature while being very easily be repaired with welders (brute) and cable coils (burn). As a Roboticist, you can upgrade cleanbots with adv mops and brooms to make them faster and better! As a Roboticist, you can upgrade medical bots with diamond-tipped syringes, hyposprays, and chemistry machine boards to make their injections pierce hardsuits, work faster, and inject higher quality medicines! As the AI, you can click on people's names when they speak over the radio to jump your eye to them. This only works if there are cameras that can see them and are not wearing anything which would obsfuscate their face or tracking capabilities. As the AI, you can quickly open and close doors by holding shift while clicking them, bolt them when holding ctrl, and even shock them while holding alt. As the AI, you can take pictures with your camera and upload them to newscasters. Cyborgs also share from this pool of pictures. As a Cyborg, choose your module carefully, as only having your reset wire cut and mended by someone capable of manipulation will let you repick it. If possible, refrain from choosing a module until a situation that requires one occurs. -As a Cyborg, you are immune to most forms of stunning, and excel at almost everything far better than humans. However, flashes and EMPs can easily stunlock you and you fall short in performing any tasks which require hands. -As a Cyborg, you are impervious to fires and heat. If you are rogue, you can release plasma fires everywhere and walk through them without a care in the world! +As a Cyborg, you are immune to most forms of stuns, and excel at almost everything far better than humans. However, both flashes and EMPs can easily stunlock you and you fall short in performing most complex tasks involving hands. +As a Cyborg, you are impervious to fires and heat. If you are feeling malfunctional, you can release plasma fires all over and walk through them without a care in the world! As a Cyborg, you are extremely vulnerable to EMPs as EMPs both stun you and damage you. The ion rifle in the armory or a traitor with an EMP kit can kill you in seconds. As a Service Cyborg, your spray can knocks people down. However, it is blocked by gas masks. -As an Engineering Cyborg, you can attach air alarm/fire alarm/APC frames to walls by placing them on the floor and using a screwdriver on them. Alternatively, you can use your in-built pseudo-hand manipulator to show those organics who's boss! It can even perform complex tasks such as removing cells from APCs, or inserting plasma canisters into radiation collectors. +As an Engineering Cyborg, you can attach air alarm/fire alarm/APC frames to walls by placing them on the floor and using a screwdriver on them. Alternatively, you can use your manipulator to show those organics who's boss to perform other basic tasks such as removing cells from APCs or inserting plasma canisters into radiation collectors. As a Medical Cyborg, you can fully perform surgery and even augment people. Best of all, they have a 0% failure chance, even if done on the floor. As a Janitor Cyborg, you are the bane of all slaughter demons and can even foil Bubblegum himself. Cleaning up blood stains will severely gimp them, although the latter may just turn you into robotic paste. As a Janitor Cyborg, you get a fancy bottle of drying agent! If you want to be nice, spray the janitor's galoshes with them to magically upgrade them to absorbent galoshes which automatically dry tiles. As the Chief Engineer, you can rename areas or create entirely new ones using your station blueprints. -As the Chief Engineer, your hardsuit is significantly better than everybody else's. It has the best features of both engineering and atmospherics hardsuits - boasting nigh-invulnerability to radiation and all atmospheric conditions. +As the Chief Engineer, your hardsuit is significantly better than everybody else's. It has the best features of both engineering and atmospherics hardsuits - boasting complete invulnerability to radiation and most atmospheric conditions. As the Chief Engineer, you can spy on and even forge PDA communications with the message monitor console! The key is in your office. As the Chief Engineer, your locker contains a jetpack upgrade that can be attached to hardsuits. As the Chief Engineer, the power flow control console in your office will show you APC infos and lets you control them remotely. @@ -104,7 +108,7 @@ As an Engineer, don't underestimate the humble P.A.C.M.A.N. generators. With upg As an Engineer, your departmental protolathe and circuit printer can manufacture the necessary circuit boards and components to build just about anything. Make extra medical machinery everywhere! Build a gibber for security! Set up an array of emitters pointing down the hall! The possibilities are endless! As an Engineer, you can pry open secure storage by disabling the engine room APC's environmental breaker. This is obviously a bad idea if the engine is running. As an Engineer, don't forget that Cargo has access to a meteor defense satellite that can be ordered BEFORE meteors hit the station. Any idle Engineers should have this on their to-do list. -As an Engineer, your RCD can be reloaded with mineral sheets instead of just compressed matter cartridges. Materials which are combined alloys of other materials (such as reinforced glass and plasteel) provide more matter per sheet to the RCD. +As an Engineer, your RCD can be reloaded with mineral sheets instead of just compressed matter cartridges. Materials which are combined alloys of other materials (such as reinforced glass and plasteel) provide significantly more matter per sheet to the RCD. As an Atmospheric Technician, you can unwrench a pipe regardless of the pressures of the gases inside, but if they're too high they can burst out and injure you! As an Atmospheric Technician, look into replacing your gas pumps with volumetric gas pumps, as those move air in flat numerical amounts, rather than percentages which leave trace gases. As an Atmospheric Technician, you are better suited to fighting fires than anyone else. As such, you have access to better firesuits, backpack firefighter tanks, and a completely heat and fire proof hardsuit. @@ -112,7 +116,8 @@ As an Atmospheric Technician, your backpack firefighter tank can launch resin. T As an Atmospheric Technician, your ATMOS holofan projectors can blocks gases and heat while allowing objects to pass through. With it, you can quickly contain gas spills, fires and hull breaches. Or, use it to create a plasmaman friendly lounge. As an Atmospheric Technician, burning a plasma/oxygen mix inside the incinerator will not only produce power, but also gases such as tritium and water vapor. As an Atmospheric Technician, you can change the layer of a pipe by clicking with it on a wrenched pipe or other atmos component of the desired layer. -As an Atmospheric Technician, you can take a few cans worth of N2/N2O and cool it down at local freezers. This is a good idea when dealing with (or preparing for) a supermatter meltdown. +As an Atmospheric Technician, you can take a few cans worth of N2 and cool it down at local freezers. This is a good idea when dealing with (or preparing for) a supermatter meltdown. +As an Atmospheric Technician, while N2O may be good at cooling the supermatter, it will quickly degrade into flammable oxygen. As the Head of Security, you are expected to coordinate your security force to handle any threat that comes to the station. Sometimes it means making use of the armory to handle a blob, sometimes it means being ruthless during a revolution or cult. As the Head of Security, you can call for executions or forced cyborgization, but may require the Captain's approval. As the Head of Security, don't let the power go to your head. You may have high access, great equipment, and a miniature army at your side, but being a terrible person without a good reason is grounds for banning. @@ -123,10 +128,10 @@ As the Warden, never underestimate the power of tech slugs! Scattershot fires a As the Warden, you can use a surgical saw on riot shotguns to shorten the barrel, making them able to fit in your backpack. Make sure to empty them prior lest you blast yourself in the face! As the Warden, you can implant criminals you suspect might re-offend with devices that will track their location and allow you to remotely inject them with disabling chemicals. As the Warden, you can use handcuffs on orange prisoner shoes to turn them into cuffed shoes, forcing prisoners to walk and potentially thwarting an escape. -As the Warden, tracker implants can be used on crewmembers. Doing this will let you track their person even without suit sensors and even instantly teleport to them at the local teleporter, although the implant will biodegrade after 5 minutes if its holder ever expires. +As the Warden, tracker implants can be used on crewmembers. Doing this will let you track their person even without suit sensors and even instantly teleport to them with the local teleporter. Keep in mind the implant will biodegrade after 5 minutes if its holder ever expires. As the Warden, cryostasis shotgun darts hold 10u of chemicals that will not react until it hits someone. -As the Warden, chemical implants can be loaded with a cocktail of healing or combat chems, perfect for the HoS or other security officers to make use of in a pinch. Be sure to keep a eye on them though, as they cannot be injected without the prisoner management console! EMPs or starvation might lead to the chemical implant going off preemptively. -As the Warden, tracker implants can be used on your security officers. Doing this will let you be able to message them when telecomms are out, or when you suspect comms are compromised. This is also good against rogue AIs as the prisoner tracker doesn't leave logs or alarms for the AI. +As the Warden, chemical implants can be used both on friends and foe alike. Give your underlings a cocktail of healing stimulants to be injected in a pinch, or give your parolees some lethal incentive to not reoffend. +As the Warden, tracking implants can be used on both friends and foe alike. Give your underlings one to keep tabs on their locations and privately message them if you suspect communications may be comprimised, or use them to keep track of your parolees and their general doings. As a Security Officer, remember that correlation does not equal causation. Someone may have just been at the wrong place at the wrong time! As a Security Officer, remember that your belt can hold more than one stun baton. As a Security Officer, remember harm beating someone in the head with a blunt object can deconvert them form a being a revolutionary! This sadly doesn't work against either cult, nor does this protect them from getting reconverted unlike a mindshield implant. @@ -136,47 +141,50 @@ As a Security Officer, your security HUDglasses can not only see crewmates' job As a Security Officer, mindshield implants can only prevent someone from being turned into a cultist: unlike revolutionaries, it will not de-cult them if they have already been converted. As a Security Officer, examining someone while wearing your security HUDglasses can allow you to swiftly edit their records and criminal status. Be sure to set someone to WANTED if you can't catch up to them, as it'll alert other officers of who's the bad guy, and cause the little security droids to chase after them for you. As a Security Officer, you can take out the power cell on your baton to replace it with a better or fully charged one. Just use a screwdriver on your baton to remove the old cell. -As a Security Officer, you can just about any firearm on your vest, this even works with other non-standard armor-substitutes like security winter coats! +As a Security Officer, you can place just about any firearm on your vest slot, and this even works with other non-standard armor-substitutes like security winter coats! As the Detective, people leave fingerprints everywhere and on everything. With the exception of white latex, gloves will hide them. All is not lost, however, as gloves leave fibers specific to their kind such as black or nitrile, pointing to a general department. -As the Detective, you can use your forensics scanner from a distance. Use this to scan boxes or other storage containers. +As the Detective, you can use your forensics scanner from a distance. Use this to scan boxes or other storage containers which might vacuum up your scanner on interaction. As the Detective, your revolver can be loaded with .357 ammunition. Use a screwdriver to permanently modify your revolver into using this type of ammunition, be warned however, firing it has a decent chance to cause the revolver to misfire and shoot you in the foot. As the Lawyer, try to negotiate with the Warden if sentences seem too high for the crime. As the Lawyer, you can try to convince the Captain and Head of Security to hold trials for prisoners in the courtroom. As the Head of Personnel, you are not higher ranking than other heads of staff, even though you are expected to take the Captain's place first should he go missing. If the situation seems too rough for you, consider allowing another head to become temporary Captain. -As the Head of Personnel, you are just as large a target as the Captain because of the potential power your ID and computer can hand out and your comparative vulnerability. +As the Head of Personnel, you are just as large a target as the Captain because of the potential power your ID and computer can hand out with your comparative vulnerability. As the Mime, your invisible wall power blocks people as well as projectiles. You can use it in a pinch to delay your pursuer. As the Mime, you can use :r and :l to speak through your ventriloquist dummy. Sadly, this only works if your vow is broken, but at least you don't have to sacrifice your dignity by actually talking. As the Mime, your oath of silence is your source of power. Breaking it robs you of your powers and of your honor. -As the Mime, breaking your vow of silence is seen as incredibly dishonorable. Most people will seek to trouble and generally ignore a talking Mime. +As the Mime, breaking your vow of silence is seen as incredibly dishonorable. Most people will generally seek to trouble or even harm a talking Mime. +As the Mime, your PDA can infect others' with a virus that mutes their ringtone. Finally, peace and quiet. As the Clown, if you lose your banana peel, you can still slip people with your PDA! Honk! As the Clown, eating bananas heals you slightly. Honk! As the Clown, your Holy Grail is the mineral bananium, which can be given to the Roboticist to build you a fun and robust mech beloved by everyone. As the Clown, you can use your stamp on a sheet of flattened cardboard as the first step of making a honkbot. Fun for the whole crew! -As the Clown, your number one way to win over the crew's favor is by telling jokes and putting forth effort into being comedic. Everyone loves a good clown, but everyone despises a bad one. +As the Clown, your number one way to win over the crew's favor is by putting forth proper effort to be comedic. Everyone loves a good clown, but on a similar note everyone despises a bad one. +As the Clown, your PDA can infect others' with a virus that makes their ringtone a bike horn. You can get more charges by slipping people with your PDA! Honk! As the Chaplain, your null rod has a lot of functions: while being an incredibly powerful weapon with an array of potential utilities depending upon the skin you chose for it, it also nulls cultist and wizard magic entirely, making you immune to them both and in some cases even harming the caster so long as you keep it in a pocket or in your hands. As the Chaplain, you can bless any water container by hitting it with your bible to turn it into holy water. Holy water has a myriad of uses against both cults and large amounts of it are a great contributor to success against them. As the Chaplain, your null rod will kill clockwork marauders in two hits while actively hindering their overall combat capabilities just by being nearby to them. As the Chaplain, your bible is also a container that can store a singular small item. Depending on your God, your starting bible may come with a surprise! -As the Chaplain, you are much more likely to get a response by praying to the Gods than most people as your prayers will send a special noise cue directly to them! To further your chances of getting a response even further, pretty up your altar with crayon runes and wire art, and be sure to put a decent amount of effort into your prayers themselves. The Gods don't like lazy bums. +As the Chaplain, you are much more likely to get a response by praying to the Gods than most people as your prayers will send a special noise cue directly to them! To further your chances of getting a response even further, pretty up your altar with crayon runes and wire art, and be sure to put a decent amount of effort into your prayers themselves! The Gods always love a good ritual display. As a Botanist, you can hack the MegaSeed Vendor to get access to more exotic seeds. These seeds can alternatively be ordered from cargo. As a Botanist, you can mutate the plants growing in your hydroponics trays with unstable mutagen or, as an alternative, crude radioactives from chemistry to get special variations. As a Botanist, you should look into increasing the potency of your plants. This is shown by the size of the plant's sprite, and can increase the amount of chemicals, points gained from grinding them in the biogenerator, and lets people know you are a proficient botanist. As a Botanist, you can combine production trait chemicals and mix your own complex chemicals inside of the plants themselves using precursors. Chlorine (blumpkin) + radium and phosphorus (glowshrooms) equals unstable mutagen! As a Botanist, earthsblood is an incredibly powerful chemical found in Ambrosia Gaia, it heals all types of damages very rapidly but causes lingering brain damage and has a nasty overdose. You can combine the chemicals from watermelons (water), grass (hydrogen), and cherries (sugar) to mix mannitol in with your earthsblood to completely counteract its main drawback! -As a Botanist, Ambrosia Gaia is a plant mutated from Ambrosia Deus, which is a plant mutated from Ambrosia Vulgaris. The reagent contained within this plant known as earthsblood makes for a vastly superior fertilizer than most, giving decent stat boosts to most stats, and automatically killing weeds and pests! +As a Botanist, Ambrosia Gaia is a plant mutated from Ambrosia Deus, which in turn is mutated from Ambrosia Vulgaris. The reagent contained within this plant known as earthsblood makes for a vastly superior fertilizer than most, giving decent stat boosts to most stats, and automatically killing weeds and pests! As a Cook, you can load your food into snack vending machines. As a Cook, you can rename your custom made food with a pen. -As a Cook, any food you make will be much healthier than the junk food found in vendors. Having the crew routinely eating from you will provide minor buffs. +As a Cook, most any food you make will be much healthier than the junk food found in vendors. Having the crew routinely eating from you will provide minor buffs. As a Cook, being in the kitchen will make you remember the basics of Close Quarters Cooking (CQC). It is highly effective at removing Assistants from your workplace. -As a Cook, your Kitchenmate can vend out trays that fit on your belt slot. These trays pick up 7 food items at a time and are a quick way to transport large meals. +As a Cook, your KitchenMate can vend out trays that fit on your belt slot. These trays pick up 7 food items at a time and are a quick way to transport large meals. As a Cook, the advanced roasting stick is used to cook food at a distance, and can be used on SME, singularity, and other objects that cook food normally. As a Cook, the deep frier is a tool which can turn very large quantities of seemingly useless objects into food, albeit nutritionally poor and awful tasting food, but hey, food is food. -As the Bartender, the drinks you start with only give you the basics. If you want more advanced mixtures, look into working with chemistry, hydroponics, or even mining for things to grind up and throw in! +As the Bartender, the drinks you start with only give you the basics. If you want more advanced mixtures, look into working with chemistry, hydroponics, and even mining for things to grind up and throw in! As the Bartender, you can use a circular saw on your shotgun to make it easier to store. Make sure to empty them prior lest you blast yourself in the face! -As a Janitor, if someone steals your janicart, you can instead use your spray bottles, soap, and arsenal of slippery objects to exact your bloody revenge.. ..or just order another one from Cargo. +As a Janitor, if someone steals your janicart, you can instead use your spray bottles, soap, and arsenal of slippery objects to exact your bloody revenge... or just order another one from Cargo. As a Janitor, the trash bag can be used to hold more than trash. Tools, medical equipment, smuggled nuclear disks... You name it! As a Janitor, mousetraps can be used as bomb triggers to booby-trap containers. -As the Curator, for what it's worth, your toys and position are fairly robust. You can order a claymore, a whip, or a free space suit all at roundstart. The claymore is fairly underwhelming, however the whip is an incredibly robust weapon capable of always disarming, and that space suit is also better than the ones in EVA. +As a Janitor, you can use the cartridge preinstalled into your PDA to get coordinates of various janitorial equipments around the station, such as mops or your janicart. +As the Curator, for what it's worth, your toys and position are fairly robust. You can order a claymore, a whip, or a free space suit all at roundstart. The claymore is has decent force, while the whip is an incredibly robust weapon capable of disarming, and the space suit is better than the ones in EVA. As the Curator, be sure to keep the shelves stocked and the library clean for crew. As a Cargo Technician, you can hack MULEbots to make them faster, run over people in their way, and even let you ride them! As a Cargo Technician, you can order contraband items from the supply shuttle console by de-constructing it and using a multitool on the circuit board, the re-assembling it. @@ -187,30 +195,32 @@ As the Quartermaster, be sure to check the manifests on crates you receive to ma As the Quartermaster, you can construct an express supply console that instantly delivers crates by drop pod. The impact will cause a small explosion as well. As a Shaft Miner, the northern side of Lavaland has a lot more rare minerals than on the south. As a Shaft Miner, every monster on Lavaland has a pattern you can exploit to minimize damage from the encounters. -As a Shaft Miner, you can harvest goliath plates from goliaths and upgrade your explorer's suit, mining hardsuits as well as Firefighter APLUs with them, greatly reducing incoming melee damage. +As a Shaft Miner, you can harvest goliath plates from goliaths and upgrade your explorer suit, mining hardsuits as well as Firefighter APLUs with them, greatly reducing incoming melee damage. As a Shaft Miner, always have a GPS on you, so a fellow miner or cyborg can come to save you if you die. As a Shaft Miner, you can craft a variety of equipment from the local fauna. Bone axes, lava boats and ash drake armour are just a few of them! -As a Traitor, the cryptographic sequencer (emag) can not only open lockers, crates, APCs and more. It can also do things like hack cyborgs, and even cause bots to go berserk. Use it on the right machines, and you can even contact the Syndicate. Experiment! +As a Traitor, the cryptographic sequencer (emag) can not only open lockers, crates, APCs and more. It can also do things like hack cyborgs and cause bots to go berserk. Use it on the right machines, and you can even contact the Syndicate. Experiment! As a Traitor, subverting the AI to serve you can make it an extremely powerful ally. However, be careful of the wording in the laws you give it, as it may use your poorly written laws against you! As a Traitor, the Captain and the Head of Security are two of the most difficult to kill targets on the station. If either one is your target, plan carefully. As a Traitor, you can manufacture and recycle revolver bullets at a hacked autolathe, making the revolver an extremely powerful tool if you manage to nab an autolathe for yourself. As a Traitor, you may sometimes be assigned to hunt other traitors, and in turn be hunted by others. As a Traitor, the syndicate encryption key is very useful for coordinating plans with your fellow traitors -- or, of course, betraying them. As a Traitor, plasma can be injected into many things to sabotage them. Power cells, light bulbs, cigars and e-cigs will all explode when used. +as a Traitor, swiping another traitor's uplink against your own while it is unlocked will drain the funds from theirs, regardless of its lock status. As a Nuclear Operative, communication is key! Use :t or :h to speak to your fellow operatives and coordinate an attack plan. -As a Nuclear Operative, you should look into purchasing one of the three Syndicate cyborgs in your uplink, as they can provide useful tactical support, function as walking access machines, are immune to conventional stuns, and can easily take down the AI. +As a Nuclear Operative, you should look into purchasing one of the three Syndicate cyborgs in your uplink, as they can provide useful tactical support by opening airlocks without trouble, easily sabotaging electrical systems, and killing the AI with comical ease. As a Nuclear Operative, stick together! While your equipment is robust, your fellow operatives are much better at saving your life: they can drag you away from danger while stunned and provide cover fire. As a Nuclear Operative, you might end up in a situation where the AI has bolted you into a room. Having some spare C4 in your pocket can save your life. As a Monkey, you can crawl through air or scrubber vents by alt+left clicking them. You must drop everything you are wearing and holding to do this, however. As a Monkey, you can still wear a few human items, such as backpacks, gas masks and hats, and still have two free hands. As the Malfunctioning AI, you can shunt to an APC if the situation gets bad. This disables your doomsday device if it is active. As the Malfunctioning AI, you should either order your cyborgs to dismantle the robotics console or blow it up yourself in order to protect them. Do note that this will prevent you from hacking any cyborg made in the future. -As the Malfunctioning AI, look into flooding the station with plasma fires to kill off large portions of the crew, letting you pick off the remaining few with space suits who escaped. -Xenomorphs? Any source of burn damage severely harms them. Science can craft deadly tech shells like pulse slugs and laser scatter shot that are highly effective against any alien threat. +As the Malfunctioning AI, look into flooding the station with plasma to kill off large portions of the crew, letting you pick off the remaining few with space suits who escaped. +As the Malfunctioning AI, keep in mind that hacked cyborgs will explode violently enough to create breaches and gib bystandars when detonated as opposed to the comparatively gentle boom of the uncomprimised. +When fighting Aliens, any source of burn damage severely harms them. Science can craft deadly tech shells that are highly effective against any alien threat. When fighting Aliens, it can be a good idea to turn off the gravity due to the every caste of alien's lack of zero-gravity control, especially Hunters and Drones, which are completely and utterly helpless. -When fighting Aliens, consider a shield. A raised shield can halt their attempts to slash at you, and their disarms will always remove an item in your hand before knocking you over, always having something in your hand, no matter how small or worthless, can save your life. +When fighting Aliens, consider investing in a shield. A raised shield can halt their attempts to slash at you, and their disarms will always attempt to remove an item in your hand before knocking you over, meaing having something in your hand - no matter how small or worthless - can save your life. As an Alien, your melee prowess is unmatched, but your ranged abilities are sorely lacking. Make use of corners to force a melee confrontation! -As an Alien, you take double damage from all burn attacks, such as lasers, welding tools, and fires. Furthermore, fire can destroy your resin and eggs. Expose areas to space to starve away any flamethrower fires before they can do damage! +As an Alien, you take double damage from all burn attacks, such as lasers, welding tools, and fires. Furthermore, fire can destroy your resin and eggs. Expose areas to space to starve away any flames before they can do damage! As an Alien, resin floors not only regenerate your plasma supply, but also passively heal you. Fight on resin floors to gain a home turf advantage! As an Alien, the facehugger is by far your most powerful weapon because of its ability to instantly win a fight. Remember however that certain helmets, such as biohoods or space helmets will completely block facehugger attacks. As an Alien, you are unable to pick up or use any human items or machinery. Instead, you should focus on sabotaging APCs, computers, cameras and either stowing, spacing, or melting any weapons you find. @@ -234,9 +244,9 @@ As a Revolutionary, cargo can be your best friend or your worst nightmare. In th As a Revolutionary, your main power comes from how quickly you spread. Convert people as fast as you can and overwhelm the heads of staff before security can arm up. As a Changeling, the Extract DNA sting counts for your genome absorb objective, but does not let you respec your powers. As a Changeling, you can absorb someone by strangling them and using the Absorb verb; this gives you the ability to rechoose your powers, the DNA of whoever you absorbed, the memory of the absorbed, and some samples of things the absorbed said. -As a Changeling, absorbing someone will give you their full memory. This can include things such as a Traitor's uplink, thus absorbing one will allow you to access the Traitor uplink and buy toys for your Changeling self to abuse. -As a Changeling, absorbing another Changeling will permanently boost your chemical reserve, allow you to pick more abilities, and make the victim unable to revive. Be careful when exposing your identity to other Changelings, as they may be out of those wonderful benefits. -As a Changeling, BZ gas will dramatically slow down or even halt your natural chemical regeneration, be sure to avoid it at all costs as some lunatics may try and flood portions of the station to deal with you. +As a Changeling, absorbing someone will give you their full memory. This can include things such as a Traitor's uplink. +As a Changeling, absorbing another Changeling will permanently boost your chemical reserve, allow you to pick more abilities, and make the victim unable to revive. Be careful when exposing your identity to other Changelings, as they may be out for those wonderful benefits. +As a Changeling, BZ gas will dramatically slow down or even halt your natural chemical regeneration. As a Changeling, death is not the end for you! You can revive after 40 seconds from being dead by triggering your stasis ability, and then waiting for the prompt to resurrect yourself to show up. As a Changeling, your Regenerate Limbs power will quickly heal all of your wounds, but they'll still leave scars. Changelings can use Fleshmend to get rid of scars, or you can ingest Carpotoxin to get rid of them like a normal person. As a Cultist, do not cause too much chaos before your objective is completed. If the shuttle gets called too soon, you may not have enough time to win. @@ -293,21 +303,20 @@ You can light a cigar on a supermatter crystal. Using sticky tape on items can make them stick to people and walls! Be careful, grenades might stick to your hand during the moment of truth! In a pinch, stripping yourself naked will give you a sizeable resistance to being tackled. What do you value more, your freedom or your dignity? Wearing riot armor makes you significantly more effective at performing tackle takedowns, but will use extra stamina with each leap! It will also significantly protect you from other tackles! -Epipens contain a powerful coagulant that drastically reduces bleeding on all bleeding wounds. If you don't have time to properly treat someone with lots of slashes or piercings, stick them with a pen to buy some time! +Emergency epinephrine pens contain a powerful coagulant that drastically reduces bleeding on all bleeding wounds. If you don't have time to properly treat someone with lots of slashes or piercings, stick them with a pen to buy some time! Anything you can light a cigarette with, you can use to cauterize a bleeding wound. Technically, that includes the supermatter. -Suit storage units, when hacked, entirely purge radiation from any carbon mob put inside of them when cycling, at the cost of some horrific burns, this is a very effective strategy to clean someone up after they bathed in the engine. -Laser pointers can be upgraded by replacing its micro laser with a better one from RnD! Use a screwdriver on it to remove the old laser. Upgrading the laser pointer gives you better odds of stunning a cyborg, and even blinding people with sunglasses. -Being out of combat mode makes makes you deal less damage to people and objects when attacking. This stacks with the penalty incurred by resting. -Resting makes you deal less damage to people and objects when attacking. This stacks with the penalty incurred by being out of combat mode. -You do not regenerate as much stamina while in combat mode. Resting (being on the ground) makes you regenerate stamina faster. +Suit storage units, when hacked, entirely purge radiation from any carbon mob put inside of them when cycling, at the cost of some horrific burns, this is a very effective strategy to clean someone of radiation after an engine bath. +Laser pointers can be upgraded by replacing its micro-laser with a higher-tiered one from Research! Use a screwdriver on it to remove the old laser. Upgrading the laser pointer gives you better odds of stunning a cyborg, and even lets you blind people wear sunglasses. +Resting makes you deal less damage to people and objects when attacking. +Resting makes you regenerate stamina faster. Keybinds can be reassigned in character setup on the keybindings tab. This is extremely useful, especially if you know how to use independent binds. -If your suit sensors have been shorted out, you can use cable coil to fix them by using the coil on your suit. Your suit needs to be in proper condition, however. -Most clothing when damaged can be repaired using cloth, but there may be some clothes out there that will require different stacks of materials. +If your suit sensors have been shorted out, you can fix them by using the coil on your suit. +Most clothing damage can be repaired using cloth, but there may be some clothes out there that will require different stacks of materials. You should under no circumstances, teleport bread. Food made from upgraded machines has a higher quality. Food with a high enough quality can give good moodlets even if your species dislikes the kind of food! Frying something makes it edible, while still maintaining its original functionality. Slimepeople are damaged by most things that heal toxin damage, and healed by most things that deal it. You can recognise people with this functionality through them having a cyan coloured species name when examined! EMPs can be created by mixing uranium and iron. The power of the pulse is determined by the distance from its epicentre, and the maximum distance is determined by the volume of the reaction! -Lizards start with a disabled mutation that allows them to breath fire. This can be unlocked through the usage of genetics! -Several loadout items can be unlocked through progress in parts of the game. The progress for these can be tracked in the loadout menu. - +Some lizardpeople start with an unactivated mutation that allows them to breath fire. This can be unlocked through the usage of genetics! +Some loadout items can be unlocked through progress in parts of the game. The progress for these can be tracked in the loadout menu. +It's easy to forget that everyone else you're playing with is a real person trying to have as much fun as you are. Be nice to your fellow spacemen. diff --git a/strings/traumas.json b/strings/traumas.json index e5048d41b2..195a28364b 100644 --- a/strings/traumas.json +++ b/strings/traumas.json @@ -70,7 +70,7 @@ "NO PRED CAN eVER CATCH MI", "SCIENCE GIB SHINK RAY PLS", "KILL PUNPUN 4 FUN xDD", - "i play @pick(roles) to only ORDER not DO", + "i play @pick(importantroles) to only ORDER not DO", "CRAGO ORDER @pick(cargo) PLS", "erp?", "i want to digest u!!!", @@ -98,6 +98,7 @@ "nerf blob!1", "iM NOT A FUWRRYY!!!", "FOURTEEN INCHES SOFT!!!", + "SPLUUUUUUUUUUUUUUUUUUUUUUURTS!!!!!!!!!!", "@pick(semicolon)N-NYAAAAAA~", "@pick(bug)", "@pick(semicolon)wtf??????????? @pick(bug)", @@ -133,7 +134,10 @@ "@pick(semicolon)Assaltign a sec osficer aren't crime if ur @pick(roles)", ";SEC I SPILED MU JICE HELELPH HELPJ JLEP HELP", "@pick(semicolon) atmos is chemistyr is radation fast air is FASTER cheemsitry and FASTER RADIATION AND FASTER DEATH!!!", - "@pick(semicolon) FUC'KING MuNKEY WAch TALKN SHIT" + "@pick(semicolon) FUC'KING MuNKEY WAch TALKN SHIT", + "@pick(semicolon)How do I set up the. SHow do I set u p the Singu. how I the scrungulartiy????", + "@pick(semicolon)@pick(roles) is suSpicious!!!", + "@pick(semicolon)NOOO!!!OOOOOOO!! @pick(roles) HALP!!" ], "mutations": [ @@ -184,7 +188,11 @@ "haylo", "EEGEE", "mr terry", - "berry" + "berry", + "are pee", + "mayne", + "air ret", + "dise" ], "create_verbs": [ @@ -199,7 +207,8 @@ "treaitors", "sheadow lings", "abdoocters", - "revinent" + "revinent", + "ninja" ], "bug": [ @@ -266,20 +275,63 @@ "YOUR LIFE IS IMPORTANT. KEEP IT." ], - "roles": [ + "importantroles": [ "heds", "ceptin", "hop", - "arrdee", + "hos", + "see emo", + "cee ee", + "arr dee", + "q m", "sek" ], + "roles": [ + "ceptin", + "hop", + "hos", + "see emo", + "cee ee", + "arr dee", + "q m", + "assistent", + "cargo", + "mine r", + "bart ender", + "chef", + "botonist", + "janny", + "clon", + "mime", + "librarian", + "chap", + "ai", + "borg", + "egnineer", + "atmos", + "docter", + "paradocter", + "cheemsist", + "viroligist", + "genetocist", + "science", + "robotocist", + "wardon", + "det", + "shitcurity", + "prihsoner" + ], + "cargo": [ "GUNS", "HATS", "PIZEH", "MEMES", - "GLOWY CYSTAL" + "GLOWY CYSTAL", + "SINGLO", + "TESLO", + "NULLZ" ], "s_roles": [ @@ -289,6 +341,7 @@ "admen", "mantor", "bluh daymon", - "wizzerd" + "wizzerd", + "nookies" ] } diff --git a/tgstation.dme b/tgstation.dme index 65c5b7acab..bb585d8b07 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -15,6 +15,8 @@ // BEGIN_INCLUDE #include "_maps\_basemap.dm" +#include "_maps\map_files\FestiveBall\doorButtonOrganizer.dm" +#include "code\__byond_version_compat.dm" #include "code\_compile_options.dm" #include "code\world.dm" #include "code\__DEFINES\_auxtools.dm" @@ -27,7 +29,7 @@ #include "code\__DEFINES\admin.dm" #include "code\__DEFINES\antagonists.dm" #include "code\__DEFINES\atmospherics.dm" -#include "code\__DEFINES\atom_hud.dm" +#include "code\__DEFINES\bitfields.dm" #include "code\__DEFINES\blackmarket.dm" #include "code\__DEFINES\botany.dm" #include "code\__DEFINES\callbacks.dm" @@ -36,7 +38,6 @@ #include "code\__DEFINES\citadel_defines.dm" #include "code\__DEFINES\cleaning.dm" #include "code\__DEFINES\clockcult.dm" -#include "code\__DEFINES\colors.dm" #include "code\__DEFINES\combat.dm" #include "code\__DEFINES\configuration.dm" #include "code\__DEFINES\construction.dm" @@ -54,8 +55,10 @@ #include "code\__DEFINES\explosion.dm" #include "code\__DEFINES\exports.dm" #include "code\__DEFINES\fantasy_affixes.dm" +#include "code\__DEFINES\fonts.dm" #include "code\__DEFINES\food.dm" #include "code\__DEFINES\footsteps.dm" +#include "code\__DEFINES\gun.dm" #include "code\__DEFINES\hud.dm" #include "code\__DEFINES\instruments.dm" #include "code\__DEFINES\integrated_electronics.dm" @@ -69,14 +72,17 @@ #include "code\__DEFINES\loadout.dm" #include "code\__DEFINES\logging.dm" #include "code\__DEFINES\machines.dm" +#include "code\__DEFINES\mapexporting.dm" #include "code\__DEFINES\maps.dm" #include "code\__DEFINES\materials.dm" #include "code\__DEFINES\maths.dm" #include "code\__DEFINES\MC.dm" +#include "code\__DEFINES\mecha.dm" #include "code\__DEFINES\melee.dm" #include "code\__DEFINES\menu.dm" #include "code\__DEFINES\misc.dm" #include "code\__DEFINES\mobs.dm" +#include "code\__DEFINES\mod.dm" #include "code\__DEFINES\monkeys.dm" #include "code\__DEFINES\move_force.dm" #include "code\__DEFINES\movement.dm" @@ -103,7 +109,9 @@ #include "code\__DEFINES\rockpaperscissors.dm" #include "code\__DEFINES\role_preferences.dm" #include "code\__DEFINES\rust_g.dm" +#include "code\__DEFINES\rust_g_overrides.dm" #include "code\__DEFINES\say.dm" +#include "code\__DEFINES\screentips.dm" #include "code\__DEFINES\security_levels.dm" #include "code\__DEFINES\shuttles.dm" #include "code\__DEFINES\sight.dm" @@ -113,8 +121,11 @@ #include "code\__DEFINES\species.dm" #include "code\__DEFINES\stat.dm" #include "code\__DEFINES\stat_tracking.dm" +#include "code\__DEFINES\station.dm" #include "code\__DEFINES\status_effects.dm" +#include "code\__DEFINES\strippable.dm" #include "code\__DEFINES\subsystems.dm" +#include "code\__DEFINES\text.dm" #include "code\__DEFINES\tgs.config.dm" #include "code\__DEFINES\tgs.dm" #include "code\__DEFINES\tgui.dm" @@ -123,6 +134,7 @@ #include "code\__DEFINES\traits.dm" #include "code\__DEFINES\turf_flags.dm" #include "code\__DEFINES\typeids.dm" +#include "code\__DEFINES\uplink.dm" #include "code\__DEFINES\vehicles.dm" #include "code\__DEFINES\voreconstants.dm" #include "code\__DEFINES\vote.dm" @@ -138,6 +150,9 @@ #include "code\__DEFINES\_flags\shields.dm" #include "code\__DEFINES\admin\keybindings.dm" #include "code\__DEFINES\chemistry\reactions.dm" +#include "code\__DEFINES\color\color_priority.dm" +#include "code\__DEFINES\color\colors.dm" +#include "code\__DEFINES\color\lum.dm" #include "code\__DEFINES\combat\attack_types.dm" #include "code\__DEFINES\combat\block.dm" #include "code\__DEFINES\combat\block_parry.dm" @@ -145,10 +160,21 @@ #include "code\__DEFINES\dcs\flags.dm" #include "code\__DEFINES\dcs\helpers.dm" #include "code\__DEFINES\dcs\signals.dm" +#include "code\__DEFINES\dcs\signals\signals_hud.dm" +#include "code\__DEFINES\dcs\signals\signals_medical.dm" +#include "code\__DEFINES\dcs\signals\signals_mod.dm" +#include "code\__DEFINES\dcs\signals\signals_painting.dm" +#include "code\__DEFINES\dcs\signals\signals_reagent.dm" +#include "code\__DEFINES\dcs\signals\signals_screentips.dm" +#include "code\__DEFINES\dcs\signals\signals_subsystem.dm" +#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_movement.dm" +#include "code\__DEFINES\dcs\signals\signals_mob\signals_mob_living.dm" #include "code\__DEFINES\mapping\maploader.dm" #include "code\__DEFINES\material\worth.dm" #include "code\__DEFINES\mobs\innate_abilities.dm" #include "code\__DEFINES\mobs\slowdowns.dm" +#include "code\__DEFINES\rendering\atom_hud.dm" +#include "code\__DEFINES\rendering\parallax.dm" #include "code\__DEFINES\research\anomalies.dm" #include "code\__DEFINES\research\stock_parts.dm" #include "code\__DEFINES\skills\defines.dm" @@ -162,9 +188,10 @@ #include "code\__HELPERS\_string_lists.dm" #include "code\__HELPERS\angles.dm" #include "code\__HELPERS\areas.dm" -#include "code\__HELPERS\AStar.dm" #include "code\__HELPERS\chat.dm" +#include "code\__HELPERS\clients.dm" #include "code\__HELPERS\cmp.dm" +#include "code\__HELPERS\config.dm" #include "code\__HELPERS\custom_holoforms.dm" #include "code\__HELPERS\dates.dm" #include "code\__HELPERS\dna.dm" @@ -179,10 +206,12 @@ #include "code\__HELPERS\icons.dm" #include "code\__HELPERS\level_traits.dm" #include "code\__HELPERS\lighting.dm" +#include "code\__HELPERS\markov.dm" #include "code\__HELPERS\matrices.dm" #include "code\__HELPERS\mobs.dm" #include "code\__HELPERS\mouse_control.dm" #include "code\__HELPERS\names.dm" +#include "code\__HELPERS\path.dm" #include "code\__HELPERS\priority_announce.dm" #include "code\__HELPERS\pronouns.dm" #include "code\__HELPERS\qdel.dm" @@ -203,7 +232,10 @@ #include "code\__HELPERS\vector.dm" #include "code\__HELPERS\verbs.dm" #include "code\__HELPERS\view.dm" +#include "code\__HELPERS\weakref.dm" #include "code\__HELPERS\yelling.dm" +#include "code\__HELPERS\matrices\color_matrix.dm" +#include "code\__HELPERS\matrices\transform_matrix.dm" #include "code\__HELPERS\sorts\__main.dm" #include "code\__HELPERS\sorts\InsertSort.dm" #include "code\__HELPERS\sorts\MergeSort.dm" @@ -216,6 +248,7 @@ #include "code\_globalvars\logging.dm" #include "code\_globalvars\misc.dm" #include "code\_globalvars\regexes.dm" +#include "code\_globalvars\tgui.dm" #include "code\_globalvars\traits.dm" #include "code\_globalvars\lists\achievements.dm" #include "code\_globalvars\lists\client.dm" @@ -258,7 +291,7 @@ #include "code\_onclick\hud\credits.dm" #include "code\_onclick\hud\devil.dm" #include "code\_onclick\hud\drones.dm" -#include "code\_onclick\hud\fullscreen.dm" +#include "code\_onclick\hud\families.dm" #include "code\_onclick\hud\generic_dextrous.dm" #include "code\_onclick\hud\ghost.dm" #include "code\_onclick\hud\guardian.dm" @@ -268,7 +301,7 @@ #include "code\_onclick\hud\map_popups.dm" #include "code\_onclick\hud\monkey.dm" #include "code\_onclick\hud\movable_screen_objects.dm" -#include "code\_onclick\hud\parallax.dm" +#include "code\_onclick\hud\new_player.dm" #include "code\_onclick\hud\picture_in_picture.dm" #include "code\_onclick\hud\plane_master.dm" #include "code\_onclick\hud\radial.dm" @@ -276,6 +309,7 @@ #include "code\_onclick\hud\revenanthud.dm" #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" +#include "code\_onclick\hud\screentip.dm" #include "code\_onclick\hud\simple_animal.dm" #include "code\_onclick\hud\swarmer.dm" #include "code\_onclick\hud\screen_objects\clickdelay.dm" @@ -283,6 +317,16 @@ #include "code\_onclick\hud\screen_objects\stamina.dm" #include "code\_onclick\hud\screen_objects\storage.dm" #include "code\_onclick\hud\screen_objects\vore.dm" +#include "code\_rendering\mob.dm" +#include "code\_rendering\atom_huds\alternate_appearance.dm" +#include "code\_rendering\atom_huds\atom_hud.dm" +#include "code\_rendering\atom_huds\data_huds.dm" +#include "code\_rendering\clickcatcher\clickcatcher.dm" +#include "code\_rendering\fullscreen\fullscreen.dm" +#include "code\_rendering\parallax\parallax.dm" +#include "code\_rendering\parallax\parallax_holder.dm" +#include "code\_rendering\parallax\parallax_object.dm" +#include "code\_rendering\parallax\types\space.dm" #include "code\controllers\admin.dm" #include "code\controllers\configuration_citadel.dm" #include "code\controllers\controller.dm" @@ -296,6 +340,7 @@ #include "code\controllers\configuration\entries\admin.dm" #include "code\controllers\configuration\entries\alert.dm" #include "code\controllers\configuration\entries\antag_rep.dm" +#include "code\controllers\configuration\entries\bot.dm" #include "code\controllers\configuration\entries\comms.dm" #include "code\controllers\configuration\entries\connections.dm" #include "code\controllers\configuration\entries\dbconfig.dm" @@ -321,7 +366,6 @@ #include "code\controllers\configuration\entries\vote.dm" #include "code\controllers\subsystem\achievements.dm" #include "code\controllers\subsystem\activity.dm" -#include "code\controllers\subsystem\adjacent_air.dm" #include "code\controllers\subsystem\air.dm" #include "code\controllers\subsystem\assets.dm" #include "code\controllers\subsystem\atoms.dm" @@ -369,8 +413,10 @@ #include "code\controllers\subsystem\radio.dm" #include "code\controllers\subsystem\research.dm" #include "code\controllers\subsystem\runechat.dm" +#include "code\controllers\subsystem\security_level.dm" #include "code\controllers\subsystem\server_maint.dm" #include "code\controllers\subsystem\shuttle.dm" +#include "code\controllers\subsystem\sound_loops.dm" #include "code\controllers\subsystem\sounds.dm" #include "code\controllers\subsystem\spacedrift.dm" #include "code\controllers\subsystem\statpanel.dm" @@ -389,7 +435,7 @@ #include "code\controllers\subsystem\persistence\_persistence.dm" #include "code\controllers\subsystem\persistence\cleanable_debris.dm" #include "code\controllers\subsystem\persistence\panic_bunker.dm" -#include "code\controllers\subsystem\persistence\poly_parrot.dm" +#include "code\controllers\subsystem\persistence\polly_parrot.dm" #include "code\controllers\subsystem\persistence\recent_votes_etc.dm" #include "code\controllers\subsystem\persistence\secret_satchels.dm" #include "code\controllers\subsystem\persistence\trophies.dm" @@ -405,6 +451,7 @@ #include "code\controllers\subsystem\processing\processing.dm" #include "code\controllers\subsystem\processing\projectiles.dm" #include "code\controllers\subsystem\processing\quirks.dm" +#include "code\controllers\subsystem\processing\station.dm" #include "code\controllers\subsystem\processing\status_effects.dm" #include "code\controllers\subsystem\processing\weather.dm" #include "code\controllers\subsystem\processing\wet_floors.dm" @@ -412,6 +459,7 @@ #include "code\datums\action.dm" #include "code\datums\ai_laws.dm" #include "code\datums\armor.dm" +#include "code\datums\bark.dm" #include "code\datums\beam.dm" #include "code\datums\beepsky_fashion.dm" #include "code\datums\browser.dm" @@ -432,7 +480,6 @@ #include "code\datums\forced_movement.dm" #include "code\datums\holocall.dm" #include "code\datums\http.dm" -#include "code\datums\hud.dm" #include "code\datums\mind.dm" #include "code\datums\mutable_appearance.dm" #include "code\datums\numbered_display.dm" @@ -456,12 +503,19 @@ #include "code\datums\achievements\_awards.dm" #include "code\datums\achievements\boss_achievements.dm" #include "code\datums\achievements\boss_scores.dm" +#include "code\datums\achievements\job_achievements.dm" +#include "code\datums\achievements\job_scores.dm" #include "code\datums\achievements\mafia_achievements.dm" #include "code\datums\achievements\misc_achievements.dm" #include "code\datums\achievements\misc_scores.dm" #include "code\datums\achievements\skill_achievements.dm" #include "code\datums\actions\beam_rifle.dm" -#include "code\datums\actions\ninja.dm" +#include "code\datums\announcers\_announcer.dm" +#include "code\datums\announcers\default_announcer.dm" +#include "code\datums\announcers\intern_announcer.dm" +#include "code\datums\announcers\medbot_announcer.dm" +#include "code\datums\atmosphere\_atmosphere.dm" +#include "code\datums\atmosphere\planetary.dm" #include "code\datums\brain_damage\brain_trauma.dm" #include "code\datums\brain_damage\hypnosis.dm" #include "code\datums\brain_damage\imaginary_friend.dm" @@ -471,10 +525,12 @@ #include "code\datums\brain_damage\severe.dm" #include "code\datums\brain_damage\special.dm" #include "code\datums\brain_damage\split_personality.dm" +#include "code\datums\changelog\changelog.dm" #include "code\datums\components\_component.dm" #include "code\datums\components\acid.dm" #include "code\datums\components\activity.dm" #include "code\datums\components\anti_magic.dm" +#include "code\datums\components\area_sound_manager.dm" #include "code\datums\components\armor_plate.dm" #include "code\datums\components\bane.dm" #include "code\datums\components\bouncy.dm" @@ -484,6 +540,7 @@ #include "code\datums\components\combat_mode.dm" #include "code\datums\components\construction.dm" #include "code\datums\components\dejavu.dm" +#include "code\datums\components\dullahan.dm" #include "code\datums\components\earprotection.dm" #include "code\datums\components\edible.dm" #include "code\datums\components\edit_complainer.dm" @@ -492,6 +549,7 @@ #include "code\datums\components\field_of_vision.dm" #include "code\datums\components\footstep.dm" #include "code\datums\components\fried.dm" +#include "code\datums\components\fullauto.dm" #include "code\datums\components\gps.dm" #include "code\datums\components\honkspam.dm" #include "code\datums\components\identification.dm" @@ -509,6 +567,7 @@ #include "code\datums\components\mirage_border.dm" #include "code\datums\components\mirv.dm" #include "code\datums\components\mood.dm" +#include "code\datums\components\multiple_lives.dm" #include "code\datums\components\nanites.dm" #include "code\datums\components\ntnet_interface.dm" #include "code\datums\components\omen.dm" @@ -516,6 +575,7 @@ #include "code\datums\components\paintable.dm" #include "code\datums\components\pellet_cloud.dm" #include "code\datums\components\phantomthief.dm" +#include "code\datums\components\pricetag.dm" #include "code\datums\components\rad_insulation.dm" #include "code\datums\components\radioactive.dm" #include "code\datums\components\remote_materials.dm" @@ -579,6 +639,7 @@ #include "code\datums\diseases\brainrot.dm" #include "code\datums\diseases\cold.dm" #include "code\datums\diseases\cold9.dm" +#include "code\datums\diseases\crabcancer.dm" #include "code\datums\diseases\dna_spread.dm" #include "code\datums\diseases\fake_gbs.dm" #include "code\datums\diseases\flu.dm" @@ -632,6 +693,7 @@ #include "code\datums\elements\bed_tucking.dm" #include "code\datums\elements\bsa_blocker.dm" #include "code\datums\elements\cleaning.dm" +#include "code\datums\elements\connect_loc.dm" #include "code\datums\elements\decal.dm" #include "code\datums\elements\dusts_on_catatonia.dm" #include "code\datums\elements\dusts_on_leaving_area.dm" @@ -644,12 +706,14 @@ #include "code\datums\elements\forced_gravity.dm" #include "code\datums\elements\ghost_role_eligibility.dm" #include "code\datums\elements\mob_holder.dm" +#include "code\datums\elements\object_reskinning.dm" #include "code\datums\elements\photosynthesis.dm" #include "code\datums\elements\polychromic.dm" #include "code\datums\elements\scavenging.dm" #include "code\datums\elements\snail_crawl.dm" #include "code\datums\elements\spellcasting.dm" #include "code\datums\elements\squish.dm" +#include "code\datums\elements\strippable.dm" #include "code\datums\elements\swimming.dm" #include "code\datums\elements\sword_point.dm" #include "code\datums\elements\tactical.dm" @@ -658,10 +722,16 @@ #include "code\datums\elements\update_icon_blocker.dm" #include "code\datums\elements\update_icon_updates_onmob.dm" #include "code\datums\elements\ventcrawling.dm" +#include "code\datums\elements\weather_listener.dm" #include "code\datums\elements\wuv.dm" +#include "code\datums\elements\screentips\contextual_screentip_bare_hands.dm" +#include "code\datums\elements\screentips\contextual_screentip_item_typechecks.dm" +#include "code\datums\elements\screentips\contextual_screentip_sharpness.dm" +#include "code\datums\elements\screentips\contextual_screentip_tools.dm" #include "code\datums\helper_datums\events.dm" #include "code\datums\helper_datums\getrev.dm" #include "code\datums\helper_datums\icon_snapshot.dm" +#include "code\datums\helper_datums\stack_end_detector.dm" #include "code\datums\helper_datums\teleport.dm" #include "code\datums\looping_sounds\_looping_sound.dm" #include "code\datums\looping_sounds\item_sounds.dm" @@ -687,6 +757,7 @@ #include "code\datums\materials\basemats.dm" #include "code\datums\materials\meat.dm" #include "code\datums\materials\pizza.dm" +#include "code\datums\mocking\client.dm" #include "code\datums\mood_events\beauty_events.dm" #include "code\datums\mood_events\drink_events.dm" #include "code\datums\mood_events\drug_events.dm" @@ -712,6 +783,9 @@ #include "code\datums\ruins\lavaland.dm" #include "code\datums\ruins\space.dm" #include "code\datums\ruins\station.dm" +#include "code\datums\screentips\atom_context.dm" +#include "code\datums\screentips\item_context.dm" +#include "code\datums\screentips\screentips.dm" #include "code\datums\skills\_check_skills.dm" #include "code\datums\skills\_skill.dm" #include "code\datums\skills\_skill_holder.dm" @@ -722,6 +796,11 @@ #include "code\datums\skills\modifiers\job.dm" #include "code\datums\skills\modifiers\mood.dm" #include "code\datums\skills\modifiers\organs.dm" +#include "code\datums\station_traits\_station_trait.dm" +#include "code\datums\station_traits\admin_panel.dm" +#include "code\datums\station_traits\negative_traits.dm" +#include "code\datums\station_traits\neutral_traits.dm" +#include "code\datums\station_traits\positive_traits.dm" #include "code\datums\status_effects\buffs.dm" #include "code\datums\status_effects\debuffs.dm" #include "code\datums\status_effects\gas.dm" @@ -733,9 +812,9 @@ #include "code\datums\traits\negative.dm" #include "code\datums\traits\neutral.dm" #include "code\datums\weather\weather.dm" -#include "code\datums\weather\weather_types\acid_rain.dm" #include "code\datums\weather\weather_types\ash_storm.dm" #include "code\datums\weather\weather_types\floor_is_lava.dm" +#include "code\datums\weather\weather_types\ice_storm.dm" #include "code\datums\weather\weather_types\radiation_storm.dm" #include "code\datums\weather\weather_types\snow_storm.dm" #include "code\datums\weather\weather_types\void_storm.dm" @@ -747,6 +826,7 @@ #include "code\datums\wires\emitter.dm" #include "code\datums\wires\explosive.dm" #include "code\datums\wires\microwave.dm" +#include "code\datums\wires\mod.dm" #include "code\datums\wires\mulebot.dm" #include "code\datums\wires\particle_accelerator.dm" #include "code\datums\wires\r_n_d.dm" @@ -763,12 +843,10 @@ #include "code\datums\wounds\loss.dm" #include "code\datums\wounds\pierce.dm" #include "code\datums\wounds\slash.dm" -#include "code\game\alternate_appearance.dm" #include "code\game\atoms.dm" #include "code\game\atoms_movable.dm" #include "code\game\atoms_movement.dm" #include "code\game\communications.dm" -#include "code\game\data_huds.dm" #include "code\game\say.dm" #include "code\game\shuttle_engines.dm" #include "code\game\sound.dm" @@ -778,6 +856,7 @@ #include "code\game\area\Space_Station_13_areas.dm" #include "code\game\area\areas\away_content.dm" #include "code\game\area\areas\centcom.dm" +#include "code\game\area\areas\edina.dm" #include "code\game\area\areas\holodeck.dm" #include "code\game\area\areas\mining.dm" #include "code\game\area\areas\shuttles.dm" @@ -806,25 +885,17 @@ #include "code\game\gamemodes\devil\objectives.dm" #include "code\game\gamemodes\devil\devil agent\devil_agent.dm" #include "code\game\gamemodes\dynamic\dynamic.dm" +#include "code\game\gamemodes\dynamic\dynamic_hijacking.dm" +#include "code\game\gamemodes\dynamic\dynamic_logging.dm" #include "code\game\gamemodes\dynamic\dynamic_rulesets.dm" #include "code\game\gamemodes\dynamic\dynamic_rulesets_latejoin.dm" #include "code\game\gamemodes\dynamic\dynamic_rulesets_midround.dm" -#include "code\game\gamemodes\dynamic\dynamic_rulesets_minor.dm" #include "code\game\gamemodes\dynamic\dynamic_rulesets_roundstart.dm" -#include "code\game\gamemodes\dynamic\dynamic_storytellers.dm" +#include "code\game\gamemodes\dynamic\dynamic_simulations.dm" +#include "code\game\gamemodes\dynamic\ruleset_picking.dm" #include "code\game\gamemodes\eldritch_cult\eldritch_cult.dm" #include "code\game\gamemodes\extended\extended.dm" -#include "code\game\gamemodes\gangs\dominator.dm" -#include "code\game\gamemodes\gangs\dominator_countdown.dm" -#include "code\game\gamemodes\gangs\gang.dm" -#include "code\game\gamemodes\gangs\gang_datums.dm" -#include "code\game\gamemodes\gangs\gang_decals.dm" -#include "code\game\gamemodes\gangs\gang_hud.dm" -#include "code\game\gamemodes\gangs\gang_items.dm" -#include "code\game\gamemodes\gangs\gang_pen.dm" -#include "code\game\gamemodes\gangs\gangs.dm" -#include "code\game\gamemodes\gangs\gangtool.dm" -#include "code\game\gamemodes\gangs\implant_gang.dm" +#include "code\game\gamemodes\gang\gang.dm" #include "code\game\gamemodes\meteor\meteor.dm" #include "code\game\gamemodes\meteor\meteors.dm" #include "code\game\gamemodes\monkey\monkey.dm" @@ -844,11 +915,13 @@ #include "code\game\machinery\announcement_system.dm" #include "code\game\machinery\aug_manipulator.dm" #include "code\game\machinery\autolathe.dm" +#include "code\game\machinery\autoloom.dm" #include "code\game\machinery\bank_machine.dm" #include "code\game\machinery\Beacon.dm" #include "code\game\machinery\bloodbankgen.dm" #include "code\game\machinery\buttons.dm" #include "code\game\machinery\cell_charger.dm" +#include "code\game\machinery\civilian_bountys.dm" #include "code\game\machinery\cloning.dm" #include "code\game\machinery\colormate.dm" #include "code\game\machinery\constructable_frame.dm" @@ -876,6 +949,8 @@ #include "code\game\machinery\mass_driver.dm" #include "code\game\machinery\navbeacon.dm" #include "code\game\machinery\PDApainter.dm" +#include "code\game\machinery\posi_alert.dm" +#include "code\game\machinery\prisonlabor.dm" #include "code\game\machinery\quantum_pad.dm" #include "code\game\machinery\recharger.dm" #include "code\game\machinery\rechargestation.dm" @@ -886,6 +961,7 @@ #include "code\game\machinery\Sleeper.dm" #include "code\game\machinery\slotmachine.dm" #include "code\game\machinery\spaceheater.dm" +#include "code\game\machinery\stasis.dm" #include "code\game\machinery\status_display.dm" #include "code\game\machinery\suit_storage_unit.dm" #include "code\game\machinery\syndicatebeacon.dm" @@ -925,7 +1001,6 @@ #include "code\game\machinery\computer\telecrystalconsoles.dm" #include "code\game\machinery\computer\teleporter.dm" #include "code\game\machinery\computer\arcade\battle.dm" -#include "code\game\machinery\computer\arcade\minesweeper.dm" #include "code\game\machinery\computer\arcade\misc_arcade.dm" #include "code\game\machinery\computer\arcade\orion_trail.dm" #include "code\game\machinery\computer\prisoner\_prisoner.dm" @@ -973,36 +1048,6 @@ #include "code\game\machinery\telecomms\machines\receiver.dm" #include "code\game\machinery\telecomms\machines\relay.dm" #include "code\game\machinery\telecomms\machines\server.dm" -#include "code\game\mecha\mech_bay.dm" -#include "code\game\mecha\mech_fabricator.dm" -#include "code\game\mecha\mecha.dm" -#include "code\game\mecha\mecha_actions.dm" -#include "code\game\mecha\mecha_construction_paths.dm" -#include "code\game\mecha\mecha_control_console.dm" -#include "code\game\mecha\mecha_defense.dm" -#include "code\game\mecha\mecha_parts.dm" -#include "code\game\mecha\mecha_topic.dm" -#include "code\game\mecha\mecha_wreckage.dm" -#include "code\game\mecha\combat\combat.dm" -#include "code\game\mecha\combat\durand.dm" -#include "code\game\mecha\combat\gygax.dm" -#include "code\game\mecha\combat\honker.dm" -#include "code\game\mecha\combat\marauder.dm" -#include "code\game\mecha\combat\neovgre.dm" -#include "code\game\mecha\combat\phazon.dm" -#include "code\game\mecha\combat\reticence.dm" -#include "code\game\mecha\equipment\mecha_equipment.dm" -#include "code\game\mecha\equipment\tools\medical_tools.dm" -#include "code\game\mecha\equipment\tools\mining_tools.dm" -#include "code\game\mecha\equipment\tools\other_tools.dm" -#include "code\game\mecha\equipment\tools\work_tools.dm" -#include "code\game\mecha\equipment\weapons\mecha_ammo.dm" -#include "code\game\mecha\equipment\weapons\weapons.dm" -#include "code\game\mecha\medical\medical.dm" -#include "code\game\mecha\medical\medigax.dm" -#include "code\game\mecha\medical\odysseus.dm" -#include "code\game\mecha\working\ripley.dm" -#include "code\game\mecha\working\working.dm" #include "code\game\objects\buckling.dm" #include "code\game\objects\empulse.dm" #include "code\game\objects\items.dm" @@ -1098,6 +1143,7 @@ #include "code\game\objects\items\dna_injector.dm" #include "code\game\objects\items\documents.dm" #include "code\game\objects\items\dualsaber.dm" +#include "code\game\objects\items\dyekit.dm" #include "code\game\objects\items\eightball.dm" #include "code\game\objects\items\electrostaff.dm" #include "code\game\objects\items\extinguisher.dm" @@ -1140,6 +1186,7 @@ #include "code\game\objects\items\singularityhammer.dm" #include "code\game\objects\items\spear.dm" #include "code\game\objects\items\stunbaton.dm" +#include "code\game\objects\items\summon.dm" #include "code\game\objects\items\taster.dm" #include "code\game\objects\items\teleportation.dm" #include "code\game\objects\items\teleprod.dm" @@ -1182,6 +1229,7 @@ #include "code\game\objects\items\devices\reverse_bear_trap.dm" #include "code\game\objects\items\devices\scanners.dm" #include "code\game\objects\items\devices\sensor_device.dm" +#include "code\game\objects\items\devices\swapper.dm" #include "code\game\objects\items\devices\taperecorder.dm" #include "code\game\objects\items\devices\traitordevices.dm" #include "code\game\objects\items\devices\transfer_valve.dm" @@ -1237,9 +1285,11 @@ #include "code\game\objects\items\robot\robot_upgrades.dm" #include "code\game\objects\items\stacks\bscrystal.dm" #include "code\game\objects\items\stacks\cash.dm" +#include "code\game\objects\items\stacks\license_plates.dm" #include "code\game\objects\items\stacks\medical.dm" #include "code\game\objects\items\stacks\rods.dm" #include "code\game\objects\items\stacks\stack.dm" +#include "code\game\objects\items\stacks\stack_recipe.dm" #include "code\game\objects\items\stacks\tape.dm" #include "code\game\objects\items\stacks\telecrystal.dm" #include "code\game\objects\items\stacks\tickets.dm" @@ -1389,6 +1439,7 @@ #include "code\game\turfs\closed.dm" #include "code\game\turfs\open.dm" #include "code\game\turfs\turf.dm" +#include "code\game\turfs\open\floor\catwalk_plating.dm" #include "code\game\turfs\simulated\chasm.dm" #include "code\game\turfs\simulated\dirtystation.dm" #include "code\game\turfs\simulated\floor.dm" @@ -1433,6 +1484,7 @@ #include "code\modules\admin\create_object.dm" #include "code\modules\admin\create_poll.dm" #include "code\modules\admin\create_turf.dm" +#include "code\modules\admin\force_event.dm" #include "code\modules\admin\fun_balloon.dm" #include "code\modules\admin\holder2.dm" #include "code\modules\admin\ipintel.dm" @@ -1443,6 +1495,7 @@ #include "code\modules\admin\outfits.dm" #include "code\modules\admin\permissionedit.dm" #include "code\modules\admin\player_panel.dm" +#include "code\modules\admin\playtimes.dm" #include "code\modules\admin\sound_emitter.dm" #include "code\modules\admin\sql_message_system.dm" #include "code\modules\admin\stickyban.dm" @@ -1535,6 +1588,7 @@ #include "code\modules\antagonists\abductor\machinery\dispenser.dm" #include "code\modules\antagonists\abductor\machinery\experiment.dm" #include "code\modules\antagonists\abductor\machinery\pad.dm" +#include "code\modules\antagonists\ashwalker\ashwalker.dm" #include "code\modules\antagonists\blob\blob.dm" #include "code\modules\antagonists\blob\blob\blob_report.dm" #include "code\modules\antagonists\blob\blob\overmind.dm" @@ -1613,7 +1667,6 @@ #include "code\modules\antagonists\changeling\powers\panacea.dm" #include "code\modules\antagonists\changeling\powers\pheromone_receptors.dm" #include "code\modules\antagonists\changeling\powers\regenerate.dm" -#include "code\modules\antagonists\changeling\powers\revive.dm" #include "code\modules\antagonists\changeling\powers\shriek.dm" #include "code\modules\antagonists\changeling\powers\spiders.dm" #include "code\modules\antagonists\changeling\powers\strained_muscles.dm" @@ -1721,6 +1774,12 @@ #include "code\modules\antagonists\fugitive\fugitive_outfits.dm" #include "code\modules\antagonists\fugitive\fugitive_ship.dm" #include "code\modules\antagonists\fugitive\hunter.dm" +#include "code\modules\antagonists\gang\cellphone.dm" +#include "code\modules\antagonists\gang\gang.dm" +#include "code\modules\antagonists\gang\handler.dm" +#include "code\modules\antagonists\gang\induction_package.dm" +#include "code\modules\antagonists\gang\outfits.dm" +#include "code\modules\antagonists\gang\themes.dm" #include "code\modules\antagonists\greentext\greentext.dm" #include "code\modules\antagonists\greybois\greybois.dm" #include "code\modules\antagonists\highlander\highlander.dm" @@ -1729,7 +1788,6 @@ #include "code\modules\antagonists\morph\morph.dm" #include "code\modules\antagonists\morph\morph_antag.dm" #include "code\modules\antagonists\nightmare\nightmare.dm" -#include "code\modules\antagonists\ninja\ninja.dm" #include "code\modules\antagonists\nukeop\clownop.dm" #include "code\modules\antagonists\nukeop\nukeop.dm" #include "code\modules\antagonists\nukeop\equipment\borgchameleon.dm" @@ -1753,6 +1811,7 @@ #include "code\modules\antagonists\slaughter\slaughter_antag.dm" #include "code\modules\antagonists\slaughter\slaughterevent.dm" #include "code\modules\antagonists\space_dragon\space_dragon.dm" +#include "code\modules\antagonists\space_ninja\space_ninja.dm" #include "code\modules\antagonists\survivalist\survivalist.dm" #include "code\modules\antagonists\swarmer\swarmer.dm" #include "code\modules\antagonists\swarmer\swarmer_event.dm" @@ -1781,6 +1840,7 @@ #include "code\modules\arousal\genitals.dm" #include "code\modules\arousal\genitals_sprite_accessories.dm" #include "code\modules\arousal\organs\breasts.dm" +#include "code\modules\arousal\organs\butt.dm" #include "code\modules\arousal\organs\penis.dm" #include "code\modules\arousal\organs\testicles.dm" #include "code\modules\arousal\organs\vagina.dm" @@ -1885,6 +1945,7 @@ #include "code\modules\awaymissions\mission_code\stationCollision.dm" #include "code\modules\awaymissions\mission_code\undergroundoutpost45.dm" #include "code\modules\awaymissions\mission_code\wildwest.dm" +#include "code\modules\balloon_alert\balloon_alert.dm" #include "code\modules\buildmode\bm_mode.dm" #include "code\modules\buildmode\buildmode.dm" #include "code\modules\buildmode\buttons.dm" @@ -1896,6 +1957,7 @@ #include "code\modules\buildmode\submodes\copy.dm" #include "code\modules\buildmode\submodes\fill.dm" #include "code\modules\buildmode\submodes\mapgen.dm" +#include "code\modules\buildmode\submodes\save_area.dm" #include "code\modules\buildmode\submodes\throwing.dm" #include "code\modules\buildmode\submodes\variable_edit.dm" #include "code\modules\cargo\bounty.dm" @@ -1936,6 +1998,8 @@ #include "code\modules\cargo\bounties\slime.dm" #include "code\modules\cargo\bounties\special.dm" #include "code\modules\cargo\bounties\virus.dm" +#include "code\modules\cargo\exports\civilain_bounty.dm" +#include "code\modules\cargo\exports\engineering.dm" #include "code\modules\cargo\exports\food_wine.dm" #include "code\modules\cargo\exports\gear.dm" #include "code\modules\cargo\exports\large_objects.dm" @@ -1966,6 +2030,7 @@ #include "code\modules\client\client_colour.dm" #include "code\modules\client\client_defines.dm" #include "code\modules\client\client_procs.dm" +#include "code\modules\client\client_vpn_detect.dm" #include "code\modules\client\message.dm" #include "code\modules\client\player_details.dm" #include "code\modules\client\preferences.dm" @@ -1989,10 +2054,12 @@ #include "code\modules\clothing\glasses\engine_goggles.dm" #include "code\modules\clothing\glasses\hud.dm" #include "code\modules\clothing\glasses\phantomthief.dm" +#include "code\modules\clothing\glasses\prescription_kit.dm" #include "code\modules\clothing\gloves\_gloves.dm" #include "code\modules\clothing\gloves\boxing.dm" #include "code\modules\clothing\gloves\color.dm" #include "code\modules\clothing\gloves\miscellaneous.dm" +#include "code\modules\clothing\gloves\mittens.dm" #include "code\modules\clothing\gloves\ring.dm" #include "code\modules\clothing\gloves\tacklers.dm" #include "code\modules\clothing\head\_head.dm" @@ -2087,6 +2154,7 @@ #include "code\modules\events\anomaly_grav.dm" #include "code\modules\events\anomaly_pyro.dm" #include "code\modules\events\anomaly_vortex.dm" +#include "code\modules\events\atmos_speed.dm" #include "code\modules\events\aurora_caelus.dm" #include "code\modules\events\blob.dm" #include "code\modules\events\brain_trauma.dm" @@ -2123,8 +2191,10 @@ #include "code\modules\events\processor_overload.dm" #include "code\modules\events\radiation_storm.dm" #include "code\modules\events\sentience.dm" +#include "code\modules\events\shuttle_catastrophe.dm" #include "code\modules\events\shuttle_loan.dm" #include "code\modules\events\space_dragon.dm" +#include "code\modules\events\space_ninja.dm" #include "code\modules\events\spacevine.dm" #include "code\modules\events\spider_infestation.dm" #include "code\modules\events\spontaneous_appendicitis.dm" @@ -2132,6 +2202,7 @@ #include "code\modules\events\supermatter_surge.dm" #include "code\modules\events\supernova.dm" #include "code\modules\events\travelling_trader.dm" +#include "code\modules\events\untie_shoes.dm" #include "code\modules\events\vent_clog.dm" #include "code\modules\events\wisdomcow.dm" #include "code\modules\events\wormholes.dm" @@ -2222,6 +2293,7 @@ #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_spaghetti.dm" #include "code\modules\games\cas.dm" #include "code\modules\games\unum.dm" +#include "code\modules\holiday\dynamic.dm" #include "code\modules\holiday\easter.dm" #include "code\modules\holiday\holidays.dm" #include "code\modules\holiday\halloween\bartholomew.dm" @@ -2369,6 +2441,7 @@ #include "code\modules\jobs\job_types\medical_doctor.dm" #include "code\modules\jobs\job_types\mime.dm" #include "code\modules\jobs\job_types\paramedic.dm" +#include "code\modules\jobs\job_types\prisoner.dm" #include "code\modules\jobs\job_types\quartermaster.dm" #include "code\modules\jobs\job_types\research_director.dm" #include "code\modules\jobs\job_types\roboticist.dm" @@ -2411,6 +2484,7 @@ #include "code\modules\language\monkey.dm" #include "code\modules\language\mushroom.dm" #include "code\modules\language\narsian.dm" +#include "code\modules\language\neokanji.dm" #include "code\modules\language\ratvarian.dm" #include "code\modules\language\signlanguage.dm" #include "code\modules\language\slime.dm" @@ -2437,6 +2511,7 @@ #include "code\modules\mafia\map_pieces.dm" #include "code\modules\mafia\outfits.dm" #include "code\modules\mafia\roles.dm" +#include "code\modules\mapexporting\mapexporter.dm" #include "code\modules\mapping\map_config.dm" #include "code\modules\mapping\map_orientation_pattern.dm" #include "code\modules\mapping\map_template.dm" @@ -2468,13 +2543,13 @@ #include "code\modules\mining\machine_vending.dm" #include "code\modules\mining\mine_items.dm" #include "code\modules\mining\minebot.dm" -#include "code\modules\mining\mint.dm" #include "code\modules\mining\money_bag.dm" #include "code\modules\mining\ores_coins.dm" #include "code\modules\mining\point_bank.dm" #include "code\modules\mining\satchel_ore_boxdm.dm" #include "code\modules\mining\shelters.dm" #include "code\modules\mining\equipment\explorer_gear.dm" +#include "code\modules\mining\equipment\gauntlet_styles.dm" #include "code\modules\mining\equipment\goliath_hide.dm" #include "code\modules\mining\equipment\kinetic_crusher.dm" #include "code\modules\mining\equipment\lazarus_injector.dm" @@ -2489,6 +2564,7 @@ #include "code\modules\mining\laborcamp\laborshuttle.dm" #include "code\modules\mining\laborcamp\laborstacker.dm" #include "code\modules\mining\lavaland\ash_flora.dm" +#include "code\modules\mining\lavaland\ash_tree.dm" #include "code\modules\mining\lavaland\necropolis_chests.dm" #include "code\modules\mining\lavaland\ruins\gym.dm" #include "code\modules\mob\clickdelay.dm" @@ -2501,14 +2577,15 @@ #include "code\modules\mob\mob.dm" #include "code\modules\mob\mob_defines.dm" #include "code\modules\mob\mob_helpers.dm" +#include "code\modules\mob\mob_lists.dm" #include "code\modules\mob\mob_movement.dm" #include "code\modules\mob\mob_transformation_simple.dm" +#include "code\modules\mob\mob_update_icons.dm" #include "code\modules\mob\say.dm" #include "code\modules\mob\say_vr.dm" #include "code\modules\mob\status_procs.dm" #include "code\modules\mob\transform_procs.dm" #include "code\modules\mob\typing_indicator.dm" -#include "code\modules\mob\update_icons.dm" #include "code\modules\mob\camera\camera.dm" #include "code\modules\mob\dead\dead.dm" #include "code\modules\mob\dead\new_player\login.dm" @@ -2563,13 +2640,14 @@ #include "code\modules\mob\living\living_movement.dm" #include "code\modules\mob\living\living_signals.dm" #include "code\modules\mob\living\living_sprint.dm" +#include "code\modules\mob\living\living_update_icons.dm" #include "code\modules\mob\living\login.dm" #include "code\modules\mob\living\logout.dm" #include "code\modules\mob\living\say.dm" +#include "code\modules\mob\living\smell.dm" #include "code\modules\mob\living\stamina_buffer.dm" #include "code\modules\mob\living\status_procs.dm" #include "code\modules\mob\living\taste.dm" -#include "code\modules\mob\living\update_icons.dm" #include "code\modules\mob\living\ventcrawling.dm" #include "code\modules\mob\living\brain\brain.dm" #include "code\modules\mob\living\brain\brain_item.dm" @@ -2582,10 +2660,13 @@ #include "code\modules\mob\living\brain\status_procs.dm" #include "code\modules\mob\living\carbon\carbon.dm" #include "code\modules\mob\living\carbon\carbon_active_parry.dm" +#include "code\modules\mob\living\carbon\carbon_context.dm" #include "code\modules\mob\living\carbon\carbon_defense.dm" #include "code\modules\mob\living\carbon\carbon_defines.dm" #include "code\modules\mob\living\carbon\carbon_movement.dm" #include "code\modules\mob\living\carbon\carbon_sprint.dm" +#include "code\modules\mob\living\carbon\carbon_stripping.dm" +#include "code\modules\mob\living\carbon\carbon_update_icons.dm" #include "code\modules\mob\living\carbon\damage_procs.dm" #include "code\modules\mob\living\carbon\death.dm" #include "code\modules\mob\living\carbon\emote.dm" @@ -2595,9 +2676,9 @@ #include "code\modules\mob\living\carbon\life.dm" #include "code\modules\mob\living\carbon\say.dm" #include "code\modules\mob\living\carbon\status_procs.dm" -#include "code\modules\mob\living\carbon\update_icons.dm" #include "code\modules\mob\living\carbon\alien\alien.dm" #include "code\modules\mob\living\carbon\alien\alien_defense.dm" +#include "code\modules\mob\living\carbon\alien\alien_update_icons.dm" #include "code\modules\mob\living\carbon\alien\damage_procs.dm" #include "code\modules\mob\living\carbon\alien\death.dm" #include "code\modules\mob\living\carbon\alien\emote.dm" @@ -2608,14 +2689,13 @@ #include "code\modules\mob\living\carbon\alien\say.dm" #include "code\modules\mob\living\carbon\alien\screen.dm" #include "code\modules\mob\living\carbon\alien\status_procs.dm" -#include "code\modules\mob\living\carbon\alien\update_icons.dm" #include "code\modules\mob\living\carbon\alien\humanoid\alien_powers.dm" #include "code\modules\mob\living\carbon\alien\humanoid\death.dm" #include "code\modules\mob\living\carbon\alien\humanoid\humanoid.dm" #include "code\modules\mob\living\carbon\alien\humanoid\humanoid_defense.dm" +#include "code\modules\mob\living\carbon\alien\humanoid\humanoid_update_icons.dm" #include "code\modules\mob\living\carbon\alien\humanoid\life.dm" #include "code\modules\mob\living\carbon\alien\humanoid\queen.dm" -#include "code\modules\mob\living\carbon\alien\humanoid\update_icons.dm" #include "code\modules\mob\living\carbon\alien\humanoid\caste\drone.dm" #include "code\modules\mob\living\carbon\alien\humanoid\caste\hunter.dm" #include "code\modules\mob\living\carbon\alien\humanoid\caste\praetorian.dm" @@ -2624,9 +2704,9 @@ #include "code\modules\mob\living\carbon\alien\larva\inventory.dm" #include "code\modules\mob\living\carbon\alien\larva\larva.dm" #include "code\modules\mob\living\carbon\alien\larva\larva_defense.dm" +#include "code\modules\mob\living\carbon\alien\larva\larva_update_icons.dm" #include "code\modules\mob\living\carbon\alien\larva\life.dm" #include "code\modules\mob\living\carbon\alien\larva\powers.dm" -#include "code\modules\mob\living\carbon\alien\larva\update_icons.dm" #include "code\modules\mob\living\carbon\alien\special\alien_embryo.dm" #include "code\modules\mob\living\carbon\alien\special\facehugger.dm" #include "code\modules\mob\living\carbon\human\damage_procs.dm" @@ -2636,11 +2716,14 @@ #include "code\modules\mob\living\carbon\human\examine.dm" #include "code\modules\mob\living\carbon\human\human.dm" #include "code\modules\mob\living\carbon\human\human_block.dm" +#include "code\modules\mob\living\carbon\human\human_context.dm" #include "code\modules\mob\living\carbon\human\human_defense.dm" #include "code\modules\mob\living\carbon\human\human_defines.dm" #include "code\modules\mob\living\carbon\human\human_helpers.dm" #include "code\modules\mob\living\carbon\human\human_mobility.dm" #include "code\modules\mob\living\carbon\human\human_movement.dm" +#include "code\modules\mob\living\carbon\human\human_stripping.dm" +#include "code\modules\mob\living\carbon\human\human_update_icons.dm" #include "code\modules\mob\living\carbon\human\inventory.dm" #include "code\modules\mob\living\carbon\human\life.dm" #include "code\modules\mob\living\carbon\human\login.dm" @@ -2649,18 +2732,16 @@ #include "code\modules\mob\living\carbon\human\species.dm" #include "code\modules\mob\living\carbon\human\status_procs.dm" #include "code\modules\mob\living\carbon\human\typing_indicator.dm" -#include "code\modules\mob\living\carbon\human\update_icons.dm" #include "code\modules\mob\living\carbon\human\innate_abilities\blobform.dm" +#include "code\modules\mob\living\carbon\human\innate_abilities\coiling.dm" #include "code\modules\mob\living\carbon\human\innate_abilities\customization.dm" #include "code\modules\mob\living\carbon\human\innate_abilities\limb_regeneration.dm" #include "code\modules\mob\living\carbon\human\species_types\abductor.dm" #include "code\modules\mob\living\carbon\human\species_types\android.dm" -#include "code\modules\mob\living\carbon\human\species_types\angel.dm" #include "code\modules\mob\living\carbon\human\species_types\anthropomorph.dm" #include "code\modules\mob\living\carbon\human\species_types\arachnid.dm" #include "code\modules\mob\living\carbon\human\species_types\bugmen.dm" #include "code\modules\mob\living\carbon\human\species_types\corporate.dm" -#include "code\modules\mob\living\carbon\human\species_types\dullahan.dm" #include "code\modules\mob\living\carbon\human\species_types\dwarves.dm" #include "code\modules\mob\living\carbon\human\species_types\ethereal.dm" #include "code\modules\mob\living\carbon\human\species_types\felinid.dm" @@ -2686,8 +2767,8 @@ #include "code\modules\mob\living\carbon\monkey\life.dm" #include "code\modules\mob\living\carbon\monkey\monkey.dm" #include "code\modules\mob\living\carbon\monkey\monkey_defense.dm" +#include "code\modules\mob\living\carbon\monkey\monkey_update_icons.dm" #include "code\modules\mob\living\carbon\monkey\punpun.dm" -#include "code\modules\mob\living\carbon\monkey\update_icons.dm" #include "code\modules\mob\living\silicon\custom_holoform.dm" #include "code\modules\mob\living\silicon\damage_procs.dm" #include "code\modules\mob\living\silicon\death.dm" @@ -2702,6 +2783,7 @@ #include "code\modules\mob\living\silicon\ai\ai_defense.dm" #include "code\modules\mob\living\silicon\ai\ai_portrait_picker.dm" #include "code\modules\mob\living\silicon\ai\death.dm" +#include "code\modules\mob\living\silicon\ai\emote.dm" #include "code\modules\mob\living\silicon\ai\examine.dm" #include "code\modules\mob\living\silicon\ai\laws.dm" #include "code\modules\mob\living\silicon\ai\life.dm" @@ -2718,10 +2800,10 @@ #include "code\modules\mob\living\silicon\pai\pai.dm" #include "code\modules\mob\living\silicon\pai\pai_defense.dm" #include "code\modules\mob\living\silicon\pai\pai_shell.dm" +#include "code\modules\mob\living\silicon\pai\pai_update_icon.dm" #include "code\modules\mob\living\silicon\pai\personality.dm" #include "code\modules\mob\living\silicon\pai\say.dm" #include "code\modules\mob\living\silicon\pai\software.dm" -#include "code\modules\mob\living\silicon\pai\update_icon.dm" #include "code\modules\mob\living\silicon\robot\death.dm" #include "code\modules\mob\living\silicon\robot\emote.dm" #include "code\modules\mob\living\silicon\robot\examine.dm" @@ -2736,8 +2818,8 @@ #include "code\modules\mob\living\silicon\robot\robot_modules.dm" #include "code\modules\mob\living\silicon\robot\robot_movement.dm" #include "code\modules\mob\living\silicon\robot\robot_sprint.dm" +#include "code\modules\mob\living\silicon\robot\robot_update_icons.dm" #include "code\modules\mob\living\silicon\robot\say.dm" -#include "code\modules\mob\living\silicon\robot\update_icons.dm" #include "code\modules\mob\living\simple_animal\animal_defense.dm" #include "code\modules\mob\living\simple_animal\astral.dm" #include "code\modules\mob\living\simple_animal\constructs.dm" @@ -2788,6 +2870,9 @@ #include "code\modules\mob\living\simple_animal\friendly\drone\say.dm" #include "code\modules\mob\living\simple_animal\friendly\drone\verbs.dm" #include "code\modules\mob\living\simple_animal\friendly\drone\visuals_icons.dm" +#include "code\modules\mob\living\simple_animal\gremlin\gremlin.dm" +#include "code\modules\mob\living\simple_animal\gremlin\gremlin_act.dm" +#include "code\modules\mob\living\simple_animal\gremlin\gremlin_event.dm" #include "code\modules\mob\living\simple_animal\guardian\guardian.dm" #include "code\modules\mob\living\simple_animal\guardian\types\assassin.dm" #include "code\modules\mob\living\simple_animal\guardian\types\charger.dm" @@ -2824,6 +2909,7 @@ #include "code\modules\mob\living\simple_animal\hostile\nanotrasen.dm" #include "code\modules\mob\living\simple_animal\hostile\netherworld.dm" #include "code\modules\mob\living\simple_animal\hostile\pirate.dm" +#include "code\modules\mob\living\simple_animal\hostile\plaguerat.dm" #include "code\modules\mob\living\simple_animal\hostile\regalrat.dm" #include "code\modules\mob\living\simple_animal\hostile\russian.dm" #include "code\modules\mob\living\simple_animal\hostile\sharks.dm" @@ -2889,6 +2975,27 @@ #include "code\modules\mob\living\simple_animal\slime\slime.dm" #include "code\modules\mob\living\simple_animal\slime\slime_mobility.dm" #include "code\modules\mob\living\simple_animal\slime\subtypes.dm" +#include "code\modules\mod\mod_actions.dm" +#include "code\modules\mod\mod_activation.dm" +#include "code\modules\mod\mod_ai.dm" +#include "code\modules\mod\mod_clothes.dm" +#include "code\modules\mod\mod_construction.dm" +#include "code\modules\mod\mod_control.dm" +#include "code\modules\mod\mod_paint.dm" +#include "code\modules\mod\mod_theme.dm" +#include "code\modules\mod\mod_types.dm" +#include "code\modules\mod\mod_ui.dm" +#include "code\modules\mod\modules\_module.dm" +#include "code\modules\mod\modules\modules.dm" +#include "code\modules\mod\modules\modules_engineering.dm" +#include "code\modules\mod\modules\modules_general.dm" +#include "code\modules\mod\modules\modules_maint.dm" +#include "code\modules\mod\modules\modules_medical.dm" +#include "code\modules\mod\modules\modules_science.dm" +#include "code\modules\mod\modules\modules_security.dm" +#include "code\modules\mod\modules\modules_service.dm" +#include "code\modules\mod\modules\modules_supply.dm" +#include "code\modules\mod\modules\modules_visor.dm" #include "code\modules\modular_computers\laptop_vendor.dm" #include "code\modules\modular_computers\computers\_modular_computer_shared.dm" #include "code\modules\modular_computers\computers\item\computer.dm" @@ -2915,7 +3022,6 @@ #include "code\modules\modular_computers\file_system\programs\borg_monitor.dm" #include "code\modules\modular_computers\file_system\programs\budgetordering.dm" #include "code\modules\modular_computers\file_system\programs\card.dm" -#include "code\modules\modular_computers\file_system\programs\cargobounty.dm" #include "code\modules\modular_computers\file_system\programs\configurator.dm" #include "code\modules\modular_computers\file_system\programs\crewmanifest.dm" #include "code\modules\modular_computers\file_system\programs\file_browser.dm" @@ -2923,11 +3029,13 @@ #include "code\modules\modular_computers\file_system\programs\ntdownloader.dm" #include "code\modules\modular_computers\file_system\programs\ntmonitor.dm" #include "code\modules\modular_computers\file_system\programs\ntnrc_client.dm" +#include "code\modules\modular_computers\file_system\programs\portrait_printer.dm" #include "code\modules\modular_computers\file_system\programs\powermonitor.dm" #include "code\modules\modular_computers\file_system\programs\radar.dm" #include "code\modules\modular_computers\file_system\programs\robocontrol.dm" #include "code\modules\modular_computers\file_system\programs\robotact.dm" #include "code\modules\modular_computers\file_system\programs\secureye.dm" +#include "code\modules\modular_computers\file_system\programs\signaler.dm" #include "code\modules\modular_computers\file_system\programs\sm_monitor.dm" #include "code\modules\modular_computers\file_system\programs\antagonist\contract_uplink.dm" #include "code\modules\modular_computers\file_system\programs\antagonist\dos.dm" @@ -2963,7 +3071,7 @@ #include "code\modules\newscaster\wanted_message.dm" #include "code\modules\ninja\__ninjaDefines.dm" #include "code\modules\ninja\energy_katana.dm" -#include "code\modules\ninja\ninja_event.dm" +#include "code\modules\ninja\ninja_explosive.dm" #include "code\modules\ninja\outfit.dm" #include "code\modules\ninja\suit\gloves.dm" #include "code\modules\ninja\suit\head.dm" @@ -2972,17 +3080,17 @@ #include "code\modules\ninja\suit\shoes.dm" #include "code\modules\ninja\suit\suit.dm" #include "code\modules\ninja\suit\suit_attackby.dm" -#include "code\modules\ninja\suit\suit_initialisation.dm" -#include "code\modules\ninja\suit\suit_process.dm" -#include "code\modules\ninja\suit\n_suit_verbs\energy_net_nets.dm" -#include "code\modules\ninja\suit\n_suit_verbs\ninja_adrenaline.dm" -#include "code\modules\ninja\suit\n_suit_verbs\ninja_cost_check.dm" -#include "code\modules\ninja\suit\n_suit_verbs\ninja_empulse.dm" -#include "code\modules\ninja\suit\n_suit_verbs\ninja_net.dm" -#include "code\modules\ninja\suit\n_suit_verbs\ninja_smoke.dm" -#include "code\modules\ninja\suit\n_suit_verbs\ninja_stars.dm" -#include "code\modules\ninja\suit\n_suit_verbs\ninja_stealth.dm" -#include "code\modules\ninja\suit\n_suit_verbs\ninja_sword_recall.dm" +#include "code\modules\ninja\suit\ninja_equipment_actions\energy_net_nets.dm" +#include "code\modules\ninja\suit\ninja_equipment_actions\ninja_adrenaline.dm" +#include "code\modules\ninja\suit\ninja_equipment_actions\ninja_cost_check.dm" +#include "code\modules\ninja\suit\ninja_equipment_actions\ninja_empulse.dm" +#include "code\modules\ninja\suit\ninja_equipment_actions\ninja_glove_toggle.dm" +#include "code\modules\ninja\suit\ninja_equipment_actions\ninja_net.dm" +#include "code\modules\ninja\suit\ninja_equipment_actions\ninja_stars.dm" +#include "code\modules\ninja\suit\ninja_equipment_actions\ninja_status_read.dm" +#include "code\modules\ninja\suit\ninja_equipment_actions\ninja_stealth.dm" +#include "code\modules\ninja\suit\ninja_equipment_actions\ninja_suit_initialisation.dm" +#include "code\modules\ninja\suit\ninja_equipment_actions\ninja_sword_recall.dm" #include "code\modules\NTNet\netdata.dm" #include "code\modules\NTNet\network.dm" #include "code\modules\NTNet\relays.dm" @@ -3054,6 +3162,9 @@ #include "code\modules\power\antimatter\containment_jar.dm" #include "code\modules\power\antimatter\control.dm" #include "code\modules\power\antimatter\shielding.dm" +#include "code\modules\power\reactor\fuel_rods.dm" +#include "code\modules\power\reactor\rbmk.dm" +#include "code\modules\power\reactor\reactor_cargo.dm" #include "code\modules\power\singularity\collector.dm" #include "code\modules\power\singularity\containment_field.dm" #include "code\modules\power\singularity\emitter.dm" @@ -3262,6 +3373,7 @@ #include "code\modules\reagents\reagent_containers\spray.dm" #include "code\modules\reagents\reagent_containers\syringes.dm" #include "code\modules\recycling\conveyor2.dm" +#include "code\modules\recycling\conveyor_sorter.dm" #include "code\modules\recycling\sortingmachinery.dm" #include "code\modules\recycling\disposal\bin.dm" #include "code\modules\recycling\disposal\construction.dm" @@ -3297,6 +3409,7 @@ #include "code\modules\research\designs\medical_designs.dm" #include "code\modules\research\designs\mining_designs.dm" #include "code\modules\research\designs\misc_designs.dm" +#include "code\modules\research\designs\mod_designs.dm" #include "code\modules\research\designs\nanite_designs.dm" #include "code\modules\research\designs\power_designs.dm" #include "code\modules\research\designs\smelting_designs.dm" @@ -3366,6 +3479,7 @@ #include "code\modules\research\techweb\nodes\mecha_nodes.dm" #include "code\modules\research\techweb\nodes\medical_nodes.dm" #include "code\modules\research\techweb\nodes\misc_nodes.dm" +#include "code\modules\research\techweb\nodes\mod_nodes.dm" #include "code\modules\research\techweb\nodes\nanites_nodes.dm" #include "code\modules\research\techweb\nodes\robotics_nodes.dm" #include "code\modules\research\techweb\nodes\syndicate_nodes.dm" @@ -3545,6 +3659,7 @@ #include "code\modules\surgery\advanced\necrotic_revival.dm" #include "code\modules\surgery\advanced\pacification.dm" #include "code\modules\surgery\advanced\revival.dm" +#include "code\modules\surgery\advanced\robot_brainwashing.dm" #include "code\modules\surgery\advanced\toxichealing.dm" #include "code\modules\surgery\advanced\viral_bonding.dm" #include "code\modules\surgery\advanced\bioware\bioware.dm" @@ -3587,6 +3702,7 @@ #include "code\modules\tgs\includes.dm" #include "code\modules\tgui\external.dm" #include "code\modules\tgui\states.dm" +#include "code\modules\tgui\status_composers.dm" #include "code\modules\tgui\tgui.dm" #include "code\modules\tgui\tgui_alert.dm" #include "code\modules\tgui\tgui_input_list.dm" @@ -3598,6 +3714,7 @@ #include "code\modules\tgui\states\debug.dm" #include "code\modules\tgui\states\deep_inventory.dm" #include "code\modules\tgui\states\default.dm" +#include "code\modules\tgui\states\fun.dm" #include "code\modules\tgui\states\hands.dm" #include "code\modules\tgui\states\human_adjacent.dm" #include "code\modules\tgui\states\inventory.dm" @@ -3647,6 +3764,38 @@ #include "code\modules\vehicles\wheelchair.dm" #include "code\modules\vehicles\cars\car.dm" #include "code\modules\vehicles\cars\clowncar.dm" +#include "code\modules\vehicles\mecha\_mecha.dm" +#include "code\modules\vehicles\mecha\mech_bay.dm" +#include "code\modules\vehicles\mecha\mech_fabricator.dm" +#include "code\modules\vehicles\mecha\mech_melee_attack.dm" +#include "code\modules\vehicles\mecha\mecha_actions.dm" +#include "code\modules\vehicles\mecha\mecha_construction_paths.dm" +#include "code\modules\vehicles\mecha\mecha_control_console.dm" +#include "code\modules\vehicles\mecha\mecha_defense.dm" +#include "code\modules\vehicles\mecha\mecha_parts.dm" +#include "code\modules\vehicles\mecha\mecha_topic.dm" +#include "code\modules\vehicles\mecha\mecha_wreckage.dm" +#include "code\modules\vehicles\mecha\combat\combat.dm" +#include "code\modules\vehicles\mecha\combat\durand.dm" +#include "code\modules\vehicles\mecha\combat\five_stars.dm" +#include "code\modules\vehicles\mecha\combat\gygax.dm" +#include "code\modules\vehicles\mecha\combat\honker.dm" +#include "code\modules\vehicles\mecha\combat\marauder.dm" +#include "code\modules\vehicles\mecha\combat\medigax.dm" +#include "code\modules\vehicles\mecha\combat\neovgre.dm" +#include "code\modules\vehicles\mecha\combat\phazon.dm" +#include "code\modules\vehicles\mecha\combat\reticence.dm" +#include "code\modules\vehicles\mecha\equipment\mecha_equipment.dm" +#include "code\modules\vehicles\mecha\equipment\tools\medical_tools.dm" +#include "code\modules\vehicles\mecha\equipment\tools\mining_tools.dm" +#include "code\modules\vehicles\mecha\equipment\tools\other_tools.dm" +#include "code\modules\vehicles\mecha\equipment\tools\weapon_bay.dm" +#include "code\modules\vehicles\mecha\equipment\tools\work_tools.dm" +#include "code\modules\vehicles\mecha\equipment\weapons\mecha_ammo.dm" +#include "code\modules\vehicles\mecha\equipment\weapons\weapons.dm" +#include "code\modules\vehicles\mecha\medical\odysseus.dm" +#include "code\modules\vehicles\mecha\working\ripley.dm" +#include "code\modules\vehicles\mecha\working\working.dm" #include "code\modules\vending\_vending.dm" #include "code\modules\vending\assist.dm" #include "code\modules\vending\autodrobe.dm" @@ -3697,9 +3846,14 @@ #include "interface\menu.dm" #include "interface\stylesheet.dm" #include "interface\skin.dmf" +#include "interface\fonts\fonts_datum.dm" +#include "interface\fonts\grand_9k.dm" +#include "interface\fonts\pixellari.dm" +#include "interface\fonts\spess_font.dm" +#include "interface\fonts\tiny_unicode.dm" +#include "interface\fonts\vcr_osd_mono.dm" #include "modular_citadel\code\datums\components\souldeath.dm" #include "modular_citadel\code\datums\status_effects\chems.dm" -#include "modular_citadel\code\game\objects\cit_screenshake.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\souldeath.dm" #include "modular_citadel\code\modules\admin\holder2.dm" #include "modular_citadel\code\modules\admin\secrets.dm" @@ -3711,6 +3865,7 @@ #include "modular_citadel\code\modules\client\loadout\_medical.dm" #include "modular_citadel\code\modules\client\loadout\_security.dm" #include "modular_citadel\code\modules\client\loadout\_service.dm" +#include "modular_citadel\code\modules\client\loadout\accessory.dm" #include "modular_citadel\code\modules\client\loadout\backpack.dm" #include "modular_citadel\code\modules\client\loadout\glasses.dm" #include "modular_citadel\code\modules\client\loadout\gloves.dm" @@ -3722,6 +3877,14 @@ #include "modular_citadel\code\modules\client\loadout\suit.dm" #include "modular_citadel\code\modules\client\loadout\uniform.dm" #include "modular_citadel\code\modules\client\loadout\unlockable.dm" +#include "modular_citadel\code\modules\client\loadout\donator\accessory.dm" +#include "modular_citadel\code\modules\client\loadout\donator\backpack.dm" +#include "modular_citadel\code\modules\client\loadout\donator\gloves.dm" +#include "modular_citadel\code\modules\client\loadout\donator\mask.dm" +#include "modular_citadel\code\modules\client\loadout\donator\neck.dm" +#include "modular_citadel\code\modules\client\loadout\donator\shoes.dm" +#include "modular_citadel\code\modules\client\loadout\donator\suit.dm" +#include "modular_citadel\code\modules\client\loadout\donator\uniform.dm" #include "modular_citadel\code\modules\client\verbs\who.dm" #include "modular_citadel\code\modules\clothing\neck.dm" #include "modular_citadel\code\modules\clothing\trek.dm" @@ -3729,6 +3892,14 @@ #include "modular_citadel\code\modules\custom_loadout\custom_items.dm" #include "modular_citadel\code\modules\custom_loadout\load_to_mob.dm" #include "modular_citadel\code\modules\custom_loadout\read_from_file.dm" +#include "modular_citadel\code\modules\eventmaps\Spookystation\halloweenPersiWork.dm" +#include "modular_citadel\code\modules\eventmaps\Spookystation\JTGSZwork.dm" +#include "modular_citadel\code\modules\festive\32x64.dm" +#include "modular_citadel\code\modules\festive\festive_decals.dm" +#include "modular_citadel\code\modules\festive\festive_notes.dm" +#include "modular_citadel\code\modules\festive\privacy.dm" +#include "modular_citadel\code\modules\festive\turfs.dm" +#include "modular_citadel\code\modules\festive\wheelchair.dm" #include "modular_citadel\code\modules\mentor\dementor.dm" #include "modular_citadel\code\modules\mentor\follow.dm" #include "modular_citadel\code\modules\mentor\mentor.dm" @@ -3767,4 +3938,9 @@ #include "modular_citadel\code\modules\reagents\chemistry\recipes\fermi.dm" #include "modular_citadel\code\modules\reagents\objects\clothes.dm" #include "modular_citadel\code\modules\reagents\objects\items.dm" +#include "modular_citadel\code\modules\vectorcrafts\vector_process.dm" +#include "modular_citadel\code\modules\vectorcrafts\vectorcar_heads.dm" +#include "modular_citadel\code\modules\vectorcrafts\vectorcraft.dm" +#include "modular_citadel\code\modules\vectorcrafts\vectortruck.dm" +#include "modular_citadel\code\modules\vectorcrafts\vectorvariants.dm" // END_INCLUDE diff --git a/tgui/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs b/tgui/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs index e64e6dda16..527659ff97 100644 --- a/tgui/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs +++ b/tgui/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs @@ -1,8 +1,347 @@ /* eslint-disable */ +//prettier-ignore module.exports = { name: "@yarnpkg/plugin-interactive-tools", factory: function (require) { -var plugin;plugin=(()=>{var __webpack_modules__={7560:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>K});function r(e,t,n,r){var i,o=arguments.length,u=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)u=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(u=(o<3?i(u):o>3?i(t,n,u):i(t,n))||u);return o>3&&u&&Object.defineProperty(t,n,u),u}const i=require("@yarnpkg/cli"),o=require("@yarnpkg/core");var u=n(9245),a=n(7382);const l=(0,a.memo)(({active:e})=>{const t=(0,a.useMemo)(()=>e?"◉":"◯",[e]),n=(0,a.useMemo)(()=>e?"green":"yellow",[e]);return a.createElement(u.Text,{color:n},t)});function s({active:e},t,n){const{stdin:r}=(0,u.useStdin)(),i=(0,a.useCallback)((e,n)=>t(e,n),n);(0,a.useEffect)(()=>{if(e&&r)return r.on("keypress",i),()=>{r.off("keypress",i)}},[e,i,r])}var c;!function(e){e.BEFORE="before",e.AFTER="after"}(c||(c={}));const f=function(e,t,{active:n,minus:r,plus:i,set:o,loop:u=!0}){s({active:n},(n,a)=>{const l=t.indexOf(e);switch(a.name){case r:{const e=l-1;if(u)return void o(t[(t.length+e)%t.length]);if(e<0)return;o(t[e])}break;case i:{const e=l+1;if(u)return void o(t[e%t.length]);if(e>=t.length)return;o(t[e])}}},[t,e,i,o,u])},d=({active:e=!0,children:t=[],radius:n=10,size:r=1,loop:i=!0,onFocusRequest:o,willReachEnd:l})=>{const d=a.Children.map(t,e=>(e=>{if(null===e.key)throw new Error("Expected all children to have a key");return e.key})(e)),p=d[0],[h,v]=(0,a.useState)(p),m=d.indexOf(h);(0,a.useEffect)(()=>{d.includes(h)||v(p)},[t]),(0,a.useEffect)(()=>{l&&m>=d.length-2&&l()},[m]),function({active:e},t,n){s({active:e},(e,n)=>{"tab"===n.name&&(n.shift?t(c.BEFORE):t(c.AFTER))},n)}({active:e&&!!o},e=>{null==o||o(e)},[o]),f(h,d,{active:e,minus:"up",plus:"down",set:v,loop:i});let g=m-n,y=m+n;y>d.length&&(g-=y-d.length,y=d.length),g<0&&(y+=-g,g=0),y>=d.length&&(y=d.length-1);const _=[];for(let n=g;n<=y;++n){const i=d[n],o=e&&i===h;_.push(a.createElement(u.Box,{key:i,height:r},a.createElement(u.Box,{marginLeft:1,marginRight:1},a.createElement(u.Text,null,o?a.createElement(u.Text,{color:"cyan",bold:!0},">"):" ")),a.createElement(u.Box,null,a.cloneElement(t[n],{active:o}))))}return a.createElement(u.Box,{flexDirection:"column",width:"100%"},_)},p=require("readline"),h=a.createContext(null),v=({children:e})=>{const{stdin:t,setRawMode:n}=(0,u.useStdin)();(0,a.useEffect)(()=>{n&&n(!0),t&&(0,p.emitKeypressEvents)(t)},[t,n]);const[r,i]=(0,a.useState)(new Map),o=(0,a.useMemo)(()=>({getAll:()=>r,get:e=>r.get(e),set:(e,t)=>i(new Map([...r,[e,t]]))}),[r,i]);return a.createElement(h.Provider,{value:o,children:e})};function m(e,t){const n=(0,a.useContext)(h);if(null===n)throw new Error("Expected this hook to run with a ministore context attached");if(void 0===e)return n.getAll();const r=(0,a.useCallback)(t=>{n.set(e,t)},[e,n.set]);let i=n.get(e);return void 0===i&&(i=t),[i,r]}async function g(e,t){let n;const{waitUntilExit:r}=(0,u.render)(a.createElement(v,null,a.createElement(e,Object.assign({},t,{useSubmit:e=>{const{exit:t}=(0,u.useApp)();s({active:!0},(r,i)=>{"return"===i.name&&(n=e,t())},[t,e])}}))));return await r(),n}const y=require("clipanion");var _=n(7840),b=n(4410);const w={appId:"OFCNCOG2CU",apiKey:"6fe4476ee5a1832882e326b506d14126",indexName:"npm-search"},E=n.n(b)()(w.appId,w.apiKey).initIndex(w.indexName),D=async(e,t=0)=>await E.search(e,{analyticsTags:["yarn-plugin-interactive-tools"],attributesToRetrieve:["name","version","owner","repository","humanDownloadsLast30Days"],page:t,hitsPerPage:10}),S=["regular","dev","peer"];class C extends i.BaseCommand{async execute(){const e=await o.Configuration.find(this.context.cwd,this.context.plugins),t=()=>a.createElement(u.Box,{flexDirection:"row"},a.createElement(u.Box,{flexDirection:"column",width:48},a.createElement(u.Box,null,a.createElement(u.Text,null,"Press ",a.createElement(u.Text,{bold:!0,color:"cyanBright"},""),"/",a.createElement(u.Text,{bold:!0,color:"cyanBright"},"")," to move between packages.")),a.createElement(u.Box,null,a.createElement(u.Text,null,"Press ",a.createElement(u.Text,{bold:!0,color:"cyanBright"},"")," to select a package.")),a.createElement(u.Box,null,a.createElement(u.Text,null,"Press ",a.createElement(u.Text,{bold:!0,color:"cyanBright"},"")," again to change the target."))),a.createElement(u.Box,{flexDirection:"column"},a.createElement(u.Box,{marginLeft:1},a.createElement(u.Text,null,"Press ",a.createElement(u.Text,{bold:!0,color:"cyanBright"},"")," to install the selected packages.")),a.createElement(u.Box,{marginLeft:1},a.createElement(u.Text,null,"Press ",a.createElement(u.Text,{bold:!0,color:"cyanBright"},"")," to abort.")))),n=()=>a.createElement(a.Fragment,null,a.createElement(u.Box,{width:15},a.createElement(u.Text,{bold:!0,underline:!0,color:"gray"},"Owner")),a.createElement(u.Box,{width:11},a.createElement(u.Text,{bold:!0,underline:!0,color:"gray"},"Version")),a.createElement(u.Box,{width:10},a.createElement(u.Text,{bold:!0,underline:!0,color:"gray"},"Downloads"))),r=()=>a.createElement(u.Box,{width:17},a.createElement(u.Text,{bold:!0,underline:!0,color:"gray"},"Target")),i=({hit:t,active:n})=>{const[r,i]=m(t.name,null);s({active:n},(e,t)=>{if("space"!==t.name)return;if(!r)return void i(S[0]);const n=S.indexOf(r)+1;n===S.length?i(null):i(S[n])},[r,i]);const l=o.structUtils.parseIdent(t.name),c=o.structUtils.prettyIdent(e,l);return a.createElement(u.Box,null,a.createElement(u.Box,{width:45},a.createElement(u.Text,{bold:!0,wrap:"wrap"},c)),a.createElement(u.Box,{width:14,marginLeft:1},a.createElement(u.Text,{bold:!0,wrap:"truncate"},t.owner.name)),a.createElement(u.Box,{width:10,marginLeft:1},a.createElement(u.Text,{italic:!0,wrap:"truncate"},t.version)),a.createElement(u.Box,{width:16,marginLeft:1},a.createElement(u.Text,null,t.humanDownloadsLast30Days)))},c=({name:t,active:n})=>{const[r]=m(t,null),i=o.structUtils.parseIdent(t);return a.createElement(u.Box,null,a.createElement(u.Box,{width:47},a.createElement(u.Text,{bold:!0}," - ",o.structUtils.prettyIdent(e,i))),S.map(e=>a.createElement(u.Box,{key:e,width:14,marginLeft:1},a.createElement(u.Text,null," ",a.createElement(l,{active:r===e})," ",a.createElement(u.Text,{bold:!0},e)))))},f=()=>a.createElement(u.Box,{marginTop:1},a.createElement(u.Text,null,"Powered by Algolia.")),p=await g(({useSubmit:e})=>{const o=m();e(o);const l=Array.from(o.keys()).filter(e=>null!==o.get(e)),[s,p]=(0,a.useState)(""),[h,v]=(0,a.useState)(0),[g,y]=(0,a.useState)([]);return(0,a.useEffect)(()=>{s?(async()=>{v(0);const e=await D(s);e.query===s&&y(e.hits)})():y([])},[s]),a.createElement(u.Box,{flexDirection:"column"},a.createElement(t,null),a.createElement(u.Box,{flexDirection:"row",marginTop:1},a.createElement(u.Text,{bold:!0},"Search: "),a.createElement(u.Box,{width:41},a.createElement(_.ZP,{value:s,onChange:e=>{e.match(/\t| /)||p(e)},placeholder:"i.e. babel, webpack, react...",showCursor:!1})),a.createElement(n,null)),g.length?a.createElement(d,{radius:2,loop:!1,children:g.map(e=>a.createElement(i,{key:e.name,hit:e,active:!1})),willReachEnd:async()=>{const e=await D(s,h+1);e.query===s&&e.page-1===h&&(v(e.page),y([...g,...e.hits]))}}):a.createElement(u.Text,{color:"gray"},"Start typing..."),a.createElement(u.Box,{flexDirection:"row",marginTop:1},a.createElement(u.Box,{width:49},a.createElement(u.Text,{bold:!0},"Selected:")),a.createElement(r,null)),l.length?l.map(e=>a.createElement(c,{key:e,name:e,active:!1})):a.createElement(u.Text,{color:"gray"},"No selected packages..."),a.createElement(f,null))},{});if(void 0===p)return 1;const h=Array.from(p.keys()).filter(e=>"regular"===p.get(e)),v=Array.from(p.keys()).filter(e=>"dev"===p.get(e)),y=Array.from(p.keys()).filter(e=>"peer"===p.get(e));return h.length&&await this.cli.run(["add",...h]),v.length&&await this.cli.run(["add","--dev",...v]),y&&await this.cli.run(["add","--peer",...y]),0}}C.usage=y.Command.Usage({category:"Interactive commands",description:"open the search interface",details:"\n This command opens a fullscreen terminal interface where you can search for and install packages from the npm registry.\n ",examples:[["Open the search window","yarn search"]]}),r([y.Command.Path("search")],C.prototype,"execute",null);var k=n(5882),T=n.n(k);const x=({length:e,active:t})=>{if(0===e)return null;const n=e>1?" "+T().underline(" ".repeat(e-1)):" ";return a.createElement(u.Text,{dimColor:!t},n)},A=function({active:e,skewer:t,options:n,value:r,onChange:i,sizes:o=[]}){const s=n.map(({value:e})=>e),c=s.indexOf(r);return f(r,s,{active:e,minus:"left",plus:"right",set:i}),a.createElement(a.Fragment,null,n.map(({label:n},r)=>{const i=r===c,s=o[r]-1||0,f=n.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,""),d=Math.max(0,s-f.length-2);return a.createElement(u.Box,{key:n,width:s,marginLeft:1},a.createElement(u.Text,{wrap:"truncate"},a.createElement(l,{active:i})," ",n),t?a.createElement(x,{active:e,length:d}):null)}))},O=require("@yarnpkg/plugin-essentials");function P(){}function I(e,t,n,r,i){for(var o=0,u=t.length,a=0,l=0;oe.length?n:e})),s.value=e.join(f)}else s.value=e.join(n.slice(a,a+s.count));a+=s.count,s.added||(l+=s.count)}}var d=t[u-1];return u>1&&"string"==typeof d.value&&(d.added||d.removed)&&e.equals("",d.value)&&(t[u-2].value+=d.value,t.pop()),t}function N(e){return{newPos:e.newPos,components:e.components.slice(0)}}P.prototype={diff:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.callback;"function"==typeof n&&(r=n,n={}),this.options=n;var i=this;function o(e){return r?(setTimeout((function(){r(void 0,e)}),0),!0):e}e=this.castInput(e),t=this.castInput(t),e=this.removeEmpty(this.tokenize(e));var u=(t=this.removeEmpty(this.tokenize(t))).length,a=e.length,l=1,s=u+a,c=[{newPos:-1,components:[]}],f=this.extractCommon(c[0],t,e,0);if(c[0].newPos+1>=u&&f+1>=a)return o([{value:this.join(t),count:t.length}]);function d(){for(var n=-1*l;n<=l;n+=2){var r=void 0,s=c[n-1],f=c[n+1],d=(f?f.newPos:0)-n;s&&(c[n-1]=void 0);var p=s&&s.newPos+1=u&&d+1>=a)return o(I(i,r.components,t,e,i.useLongestToken));c[n]=r}else c[n]=void 0}l++}if(r)!function e(){setTimeout((function(){if(l>s)return r();d()||e()}),0)}();else for(;l<=s;){var p=d();if(p)return p}},pushComponent:function(e,t,n){var r=e[e.length-1];r&&r.added===t&&r.removed===n?e[e.length-1]={count:r.count+1,added:t,removed:n}:e.push({count:1,added:t,removed:n})},extractCommon:function(e,t,n,r){for(var i=t.length,o=n.length,u=e.newPos,a=u-r,l=0;u+1=?)?)([0-9]+)(\.[0-9]+)(\.[0-9]+)((?:-\S+)?)$/;class Y extends i.BaseCommand{async execute(){const e=await o.Configuration.find(this.context.cwd,this.context.plugins),{project:t,workspace:n}=await o.Project.find(e,this.context.cwd),r=await o.Cache.find(e);if(!n)throw new i.WorkspaceRequiredError(t.cwd,this.context.cwd);const l=(t,n)=>{const r=(i=t,u=n,a=M(a,{ignoreWhitespace:!0}),L.diff(i,u,a));var i,u,a;let l="";for(const t of r)t.added?l+=o.formatUtils.pretty(e,t.value,"green"):t.removed||(l+=t.value);return l},s=(t,n)=>{if(t===n)return n;const r=o.structUtils.parseRange(t),i=o.structUtils.parseRange(n),u=r.selector.match($),a=i.selector.match($);if(!u||!a)return l(t,n);const s=["gray","red","yellow","green","magenta"];let c=null,f="";for(let t=1;t{const u=await O.suggestUtils.fetchDescriptorFrom(e,o,{project:t,cache:r,preserveModifier:i,workspace:n});return null!==u?u.range:e.range},f=()=>a.createElement(u.Box,{flexDirection:"row"},a.createElement(u.Box,{flexDirection:"column",width:49},a.createElement(u.Box,{marginLeft:1},a.createElement(u.Text,null,"Press ",a.createElement(u.Text,{bold:!0,color:"cyanBright"},""),"/",a.createElement(u.Text,{bold:!0,color:"cyanBright"},"")," to select packages.")),a.createElement(u.Box,{marginLeft:1},a.createElement(u.Text,null,"Press ",a.createElement(u.Text,{bold:!0,color:"cyanBright"},""),"/",a.createElement(u.Text,{bold:!0,color:"cyanBright"},"")," to select versions."))),a.createElement(u.Box,{flexDirection:"column"},a.createElement(u.Box,{marginLeft:1},a.createElement(u.Text,null,"Press ",a.createElement(u.Text,{bold:!0,color:"cyanBright"},"")," to install.")),a.createElement(u.Box,{marginLeft:1},a.createElement(u.Text,null,"Press ",a.createElement(u.Text,{bold:!0,color:"cyanBright"},"")," to abort.")))),p=()=>a.createElement(u.Box,{flexDirection:"row",paddingTop:1,paddingBottom:1},a.createElement(u.Box,{width:50},a.createElement(u.Text,{bold:!0},a.createElement(u.Text,{color:"greenBright"},"?")," Pick the packages you want to upgrade.")),a.createElement(u.Box,{width:17},a.createElement(u.Text,{bold:!0,underline:!0,color:"gray"},"Current")),a.createElement(u.Box,{width:17},a.createElement(u.Text,{bold:!0,underline:!0,color:"gray"},"Range")),a.createElement(u.Box,{width:17},a.createElement(u.Text,{bold:!0,underline:!0,color:"gray"},"Latest"))),h=({active:t,descriptor:n,suggestions:r})=>{const[i,l]=m(n.descriptorHash,null),s=o.structUtils.stringifyIdent(n),c=Math.max(0,45-s.length);return a.createElement(a.Fragment,null,a.createElement(u.Box,null,a.createElement(u.Box,{width:45},a.createElement(u.Text,{bold:!0},o.structUtils.prettyIdent(e,n)),a.createElement(x,{active:t,length:c})),null!==r?a.createElement(A,{active:t,options:r,value:i,skewer:!0,onChange:l,sizes:[17,17,17]}):a.createElement(u.Box,{marginLeft:2},a.createElement(u.Text,{color:"gray"},"Fetching suggestions..."))))},v=({dependencies:e})=>{const[t,n]=(0,a.useState)(null),r=(0,a.useRef)(!0);return(0,a.useEffect)(()=>()=>{r.current=!1}),(0,a.useEffect)(()=>{Promise.all(e.map(e=>(async e=>{const t=G().valid(e.range)?"^"+e.range:e.range,[n,r]=await Promise.all([c(e,e.range,t).catch(()=>null),c(e,e.range,"latest").catch(()=>null)]),i=[{value:null,label:e.range}];return n&&n!==e.range&&i.push({value:n,label:s(e.range,n)}),r&&r!==n&&r!==e.range&&i.push({value:r,label:s(e.range,r)}),i})(e))).then(t=>{const i=e.map((e,n)=>[e,t[n]]).filter(([e,t])=>t.length>1);r.current&&n(i)})},[]),t?t.length?a.createElement(d,{radius:10,children:t.map(([e,t])=>a.createElement(h,{key:e.descriptorHash,active:!1,descriptor:e,suggestions:t}))}):a.createElement(u.Text,null,"No upgrades found"):a.createElement(u.Text,null,"Fetching suggestions...")},y=await g(({useSubmit:e})=>{e(m());const n=new Map;for(const e of t.workspaces)for(const r of["dependencies","devDependencies"])for(const i of e.manifest[r].values())null===t.tryWorkspaceByDescriptor(i)&&n.set(i.descriptorHash,i);const r=o.miscUtils.sortMap(n.values(),e=>o.structUtils.stringifyDescriptor(e));return a.createElement(u.Box,{flexDirection:"column"},a.createElement(f,null),a.createElement(p,null),a.createElement(v,{dependencies:r}))},{});if(void 0===y)return 1;let _=!1;for(const e of t.workspaces)for(const t of["dependencies","devDependencies"]){const n=e.manifest[t];for(const e of n.values()){const t=y.get(e.descriptorHash);null!=t&&(n.set(e.identHash,o.structUtils.makeDescriptor(e,t)),_=!0)}}if(!_)return 0;return(await o.StreamReport.start({configuration:e,stdout:this.context.stdout,includeLogs:!this.context.quiet},async e=>{await t.install({cache:r,report:e})})).exitCode()}}Y.usage=y.Command.Usage({category:"Interactive commands",description:"open the upgrade interface",details:"\n This command opens a fullscreen terminal interface where you can see any out of date packages used by your application, their status compared to the latest versions available on the remote registry, and select packages to upgrade.\n ",examples:[["Open the upgrade window","yarn upgrade-interactive"]]}),r([y.Command.Path("upgrade-interactive")],Y.prototype,"execute",null);const K={commands:[C,Y]}},7840:(e,t,n)=>{"use strict";const r=n(7382),i=n(7382),o=n(9245),u=n(1525),a=({value:e,placeholder:t="",focus:n=!0,mask:a,highlightPastedText:l=!1,showCursor:s=!0,onChange:c,onSubmit:f})=>{const[{cursorOffset:d,cursorWidth:p},h]=i.useState({cursorOffset:(e||"").length,cursorWidth:0});i.useEffect(()=>{h(t=>{if(!n||!s)return t;const r=e||"";return t.cursorOffset>r.length-1?{cursorOffset:r.length,cursorWidth:0}:t})},[e,n,s]);const v=l?p:0,m=a?a.repeat(e.length):e;let g=m,y=t?u.grey(t):void 0;if(s&&n){y=t.length>0?u.inverse(t[0])+u.grey(t.slice(1)):u.inverse(" "),g=m.length>0?"":u.inverse(" ");let e=0;for(const t of m)g+=e>=d-v&&e<=d?u.inverse(t):t,e++;m.length>0&&d===m.length&&(g+=u.inverse(" "))}return o.useInput((t,n)=>{if(n.upArrow||n.downArrow||n.ctrl&&"c"===t||n.tab||n.shift&&n.tab)return;if(n.return)return void(f&&f(e));let r=d,i=e,o=0;n.leftArrow?s&&r--:n.rightArrow?s&&r++:n.backspace||n.delete?d>0&&(i=e.slice(0,d-1)+e.slice(d,e.length),r--):(i=e.slice(0,d)+t+e.slice(d,e.length),r+=t.length,t.length>1&&(o=t.length)),d<0&&(r=0),d>e.length&&(r=e.length),h({cursorOffset:r,cursorWidth:o}),i!==e&&c(i)},{isActive:n}),r.createElement(o.Text,null,t?m.length>0?g:y:g)};t.ZP=a},9902:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(1525)),o=/^(rgb|hsl|hsv|hwb)\(\s?(\d+),\s?(\d+),\s?(\d+)\s?\)$/,u=/^(ansi|ansi256)\(\s?(\d+)\s?\)$/,a=(e,t)=>"foreground"===t?e:"bg"+e[0].toUpperCase()+e.slice(1);t.default=(e,t,n)=>{if(!t)return e;if(t in i.default){const r=a(t,n);return i.default[r](e)}if(t.startsWith("#")){const r=a("hex",n);return i.default[r](t)(e)}if(t.startsWith("ansi")){const r=u.exec(t);if(!r)return e;const o=a(r[1],n),l=Number(r[2]);return i.default[o](l)(e)}if(t.startsWith("rgb")||t.startsWith("hsl")||t.startsWith("hsv")||t.startsWith("hwb")){const r=o.exec(t);if(!r)return e;const u=a(r[1],n),l=Number(r[2]),s=Number(r[3]),c=Number(r[4]);return i.default[u](l,s,c)(e)}return e}},2773:function(e,t,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.hasOwnProperty.call(e,n)&&r(t,e,n);return i(t,e),t},u=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const a=o(n(7382)),l=u(n(1696)),s=u(n(5512)),c=u(n(1489)),f=u(n(6834)),d=u(n(5001)),p=u(n(2560)),h=u(n(9052));class v extends a.PureComponent{constructor(){super(...arguments),this.state={isFocusEnabled:!0,activeFocusId:void 0,focusables:[],error:void 0},this.rawModeEnabledCount=0,this.handleSetRawMode=e=>{const{stdin:t}=this.props;if(!this.isRawModeSupported())throw t===process.stdin?new Error("Raw mode is not supported on the current process.stdin, which Ink uses as input stream by default.\nRead about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported"):new Error("Raw mode is not supported on the stdin provided to Ink.\nRead about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported");if(t.setEncoding("utf8"),e)return 0===this.rawModeEnabledCount&&(t.addListener("data",this.handleInput),t.resume(),t.setRawMode(!0)),void this.rawModeEnabledCount++;0==--this.rawModeEnabledCount&&(t.setRawMode(!1),t.removeListener("data",this.handleInput),t.pause())},this.handleInput=e=>{""===e&&this.props.exitOnCtrlC&&this.handleExit(),""===e&&this.state.activeFocusId&&this.setState({activeFocusId:void 0}),this.state.isFocusEnabled&&this.state.focusables.length>0&&("\t"===e&&this.focusNext(),""===e&&this.focusPrevious())},this.handleExit=e=>{this.isRawModeSupported()&&this.handleSetRawMode(!1),this.props.onExit(e)},this.enableFocus=()=>{this.setState({isFocusEnabled:!0})},this.disableFocus=()=>{this.setState({isFocusEnabled:!1})},this.focusNext=()=>{this.setState(e=>{const t=e.focusables[0].id;return{activeFocusId:this.findNextFocusable(e)||t}})},this.focusPrevious=()=>{this.setState(e=>{const t=e.focusables[e.focusables.length-1].id;return{activeFocusId:this.findPreviousFocusable(e)||t}})},this.addFocusable=(e,{autoFocus:t})=>{this.setState(n=>{let r=n.activeFocusId;return!r&&t&&(r=e),{activeFocusId:r,focusables:[...n.focusables,{id:e,isActive:!0}]}})},this.removeFocusable=e=>{this.setState(t=>({activeFocusId:t.activeFocusId===e?void 0:t.activeFocusId,focusables:t.focusables.filter(t=>t.id!==e)}))},this.activateFocusable=e=>{this.setState(t=>({focusables:t.focusables.map(t=>t.id!==e?t:{id:e,isActive:!0})}))},this.deactivateFocusable=e=>{this.setState(t=>({activeFocusId:t.activeFocusId===e?void 0:t.activeFocusId,focusables:t.focusables.map(t=>t.id!==e?t:{id:e,isActive:!1})}))},this.findNextFocusable=e=>{for(let t=e.focusables.findIndex(t=>t.id===e.activeFocusId)+1;t{for(let t=e.focusables.findIndex(t=>t.id===e.activeFocusId)-1;t>=0;t--)if(e.focusables[t].isActive)return e.focusables[t].id}}static getDerivedStateFromError(e){return{error:e}}isRawModeSupported(){return this.props.stdin.isTTY}render(){return a.default.createElement(s.default.Provider,{value:{exit:this.handleExit}},a.default.createElement(c.default.Provider,{value:{stdin:this.props.stdin,setRawMode:this.handleSetRawMode,isRawModeSupported:this.isRawModeSupported(),internal_exitOnCtrlC:this.props.exitOnCtrlC}},a.default.createElement(f.default.Provider,{value:{stdout:this.props.stdout,write:this.props.writeToStdout}},a.default.createElement(d.default.Provider,{value:{stderr:this.props.stderr,write:this.props.writeToStderr}},a.default.createElement(p.default.Provider,{value:{activeId:this.state.activeFocusId,add:this.addFocusable,remove:this.removeFocusable,activate:this.activateFocusable,deactivate:this.deactivateFocusable,enableFocus:this.enableFocus,disableFocus:this.disableFocus,focusNext:this.focusNext,focusPrevious:this.focusPrevious}},this.state.error?a.default.createElement(h.default,{error:this.state.error}):this.props.children)))))}componentDidMount(){l.default.hide(this.props.stdout)}componentWillUnmount(){l.default.show(this.props.stdout),this.isRawModeSupported()&&this.handleSetRawMode(!1)}componentDidCatch(e){this.handleExit(e)}}t.default=v,v.displayName="InternalApp"},5512:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(7382).createContext({exit:()=>{}});r.displayName="InternalAppContext",t.default=r},5277:function(e,t,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.hasOwnProperty.call(e,n)&&r(t,e,n);return i(t,e),t},u=this&&this.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(r=Object.getOwnPropertySymbols(e);i{var{children:n}=e,r=u(e,["children"]);const i=Object.assign(Object.assign({},r),{marginLeft:r.marginLeft||r.marginX||r.margin||0,marginRight:r.marginRight||r.marginX||r.margin||0,marginTop:r.marginTop||r.marginY||r.margin||0,marginBottom:r.marginBottom||r.marginY||r.margin||0,paddingLeft:r.paddingLeft||r.paddingX||r.padding||0,paddingRight:r.paddingRight||r.paddingX||r.padding||0,paddingTop:r.paddingTop||r.paddingY||r.padding||0,paddingBottom:r.paddingBottom||r.paddingY||r.padding||0});return a.default.createElement("ink-box",{ref:t,style:i},n)});l.displayName="Box",l.defaultProps={flexDirection:"row",flexGrow:0,flexShrink:1},t.default=l},9052:function(e,t,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.hasOwnProperty.call(e,n)&&r(t,e,n);return i(t,e),t},u=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const a=o(n(5747)),l=u(n(7382)),s=u(n(9796)),c=u(n(9908)),f=u(n(5277)),d=u(n(9146)),p=new s.default({cwd:process.cwd(),internals:s.default.nodeInternals()});t.default=({error:e})=>{const t=e.stack?e.stack.split("\n").slice(1):void 0,n=t?p.parseLine(t[0]):void 0;let r,i=0;if((null==n?void 0:n.file)&&(null==n?void 0:n.line)&&a.existsSync(n.file)){const e=a.readFileSync(n.file,"utf8");if(r=c.default(e,n.line),r)for(const{line:e}of r)i=Math.max(i,String(e).length)}return l.default.createElement(f.default,{flexDirection:"column",padding:1},l.default.createElement(f.default,null,l.default.createElement(d.default,{backgroundColor:"red",color:"white"}," ","ERROR"," "),l.default.createElement(d.default,null," ",e.message)),n&&l.default.createElement(f.default,{marginTop:1},l.default.createElement(d.default,{dimColor:!0},n.file,":",n.line,":",n.column)),n&&r&&l.default.createElement(f.default,{marginTop:1,flexDirection:"column"},r.map(({line:e,value:t})=>l.default.createElement(f.default,{key:e},l.default.createElement(f.default,{width:i+1},l.default.createElement(d.default,{dimColor:e!==n.line,backgroundColor:e===n.line?"red":void 0,color:e===n.line?"white":void 0},String(e).padStart(i," "),":")),l.default.createElement(d.default,{key:e,backgroundColor:e===n.line?"red":void 0,color:e===n.line?"white":void 0}," "+t)))),e.stack&&l.default.createElement(f.default,{marginTop:1,flexDirection:"column"},e.stack.split("\n").slice(1).map(e=>{const t=p.parseLine(e);return t?l.default.createElement(f.default,{key:e},l.default.createElement(d.default,{dimColor:!0},"- "),l.default.createElement(d.default,{dimColor:!0,bold:!0},t.function),l.default.createElement(d.default,{dimColor:!0,color:"gray"}," ","(",t.file,":",t.line,":",t.column,")")):l.default.createElement(f.default,{key:e},l.default.createElement(d.default,{dimColor:!0},"- "),l.default.createElement(d.default,{dimColor:!0,bold:!0},e))})))}},2560:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(7382).createContext({activeId:void 0,add:()=>{},remove:()=>{},activate:()=>{},deactivate:()=>{},enableFocus:()=>{},disableFocus:()=>{},focusNext:()=>{},focusPrevious:()=>{}});r.displayName="InternalFocusContext",t.default=r},8200:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(7382)),o=({count:e=1})=>i.default.createElement("ink-text",null,"\n".repeat(e));o.displayName="Newline",t.default=o},2198:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(7382)),o=r(n(5277)),u=()=>i.default.createElement(o.default,{flexGrow:1});u.displayName="Spacer",t.default=u},8915:function(e,t,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.hasOwnProperty.call(e,n)&&r(t,e,n);return i(t,e),t};Object.defineProperty(t,"__esModule",{value:!0});const u=o(n(7382)),a=e=>{const{items:t,children:n,style:r}=e,[i,o]=u.useState(0),a=u.useMemo(()=>t.slice(i),[t,i]);u.useLayoutEffect(()=>{o(t.length)},[t.length]);const l=a.map((e,t)=>n(e,i+t)),s=u.useMemo(()=>Object.assign({position:"absolute",flexDirection:"column"},r),[r]);return u.default.createElement("ink-box",{internal_static:!0,style:s},l)};a.displayName="Static",t.default=a},5001:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(7382).createContext({stderr:void 0,write:()=>{}});r.displayName="InternalStderrContext",t.default=r},1489:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(7382).createContext({stdin:void 0,setRawMode:()=>{},isRawModeSupported:!1,internal_exitOnCtrlC:!0});r.displayName="InternalStdinContext",t.default=r},6834:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(7382).createContext({stdout:void 0,write:()=>{}});r.displayName="InternalStdoutContext",t.default=r},9146:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(7382)),o=r(n(1525)),u=r(n(9902)),a=({color:e,backgroundColor:t,dimColor:n,bold:r,italic:a,underline:l,strikethrough:s,inverse:c,wrap:f,children:d})=>{if(null==d)return null;return i.default.createElement("ink-text",{style:{flexGrow:0,flexShrink:1,flexDirection:"row",textWrap:f},internal_transform:i=>(n&&(i=o.default.dim(i)),e&&(i=u.default(i,e,"foreground")),t&&(i=u.default(i,t,"background")),r&&(i=o.default.bold(i)),a&&(i=o.default.italic(i)),l&&(i=o.default.underline(i)),s&&(i=o.default.strikethrough(i)),c&&(i=o.default.inverse(i)),i)},d)};a.displayName="Text",a.defaultProps={dimColor:!1,bold:!1,italic:!1,underline:!1,strikethrough:!1,wrap:"wrap"},t.default=a},4592:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(7382)),o=({children:e,transform:t})=>null==e?null:i.default.createElement("ink-text",{style:{flexGrow:0,flexShrink:1,flexDirection:"row"},internal_transform:t},e);o.displayName="Transform",t.default=o},146:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(3296)),o=n(5187),u=global;u.WebSocket||(u.WebSocket=i.default),u.window||(u.window=global),u.window.__REACT_DEVTOOLS_COMPONENT_FILTERS__=[{type:1,value:7,isEnabled:!0},{type:2,value:"InternalApp",isEnabled:!0,isValid:!0},{type:2,value:"InternalAppContext",isEnabled:!0,isValid:!0},{type:2,value:"InternalStdoutContext",isEnabled:!0,isValid:!0},{type:2,value:"InternalStderrContext",isEnabled:!0,isValid:!0},{type:2,value:"InternalStdinContext",isEnabled:!0,isValid:!0},{type:2,value:"InternalFocusContext",isEnabled:!0,isValid:!0}],o.connectToDevTools()},9864:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.setTextNodeValue=t.createTextNode=t.setStyle=t.setAttribute=t.removeChildNode=t.insertBeforeNode=t.appendChildNode=t.createNode=t.TEXT_NAME=void 0;const i=r(n(6401)),o=r(n(8113)),u=r(n(5809)),a=r(n(2030)),l=r(n(9099));t.TEXT_NAME="#text",t.createNode=e=>{var t;const n={nodeName:e,style:{},attributes:{},childNodes:[],parentNode:null,yogaNode:"ink-virtual-text"===e?void 0:i.default.Node.create()};return"ink-text"===e&&(null===(t=n.yogaNode)||void 0===t||t.setMeasureFunc(s.bind(null,n))),n},t.appendChildNode=(e,n)=>{var r;n.parentNode&&t.removeChildNode(n.parentNode,n),n.parentNode=e,e.childNodes.push(n),n.yogaNode&&(null===(r=e.yogaNode)||void 0===r||r.insertChild(n.yogaNode,e.yogaNode.getChildCount())),"ink-text"!==e.nodeName&&"ink-virtual-text"!==e.nodeName||f(e)},t.insertBeforeNode=(e,n,r)=>{var i,o;n.parentNode&&t.removeChildNode(n.parentNode,n),n.parentNode=e;const u=e.childNodes.indexOf(r);if(u>=0)return e.childNodes.splice(u,0,n),void(n.yogaNode&&(null===(i=e.yogaNode)||void 0===i||i.insertChild(n.yogaNode,u)));e.childNodes.push(n),n.yogaNode&&(null===(o=e.yogaNode)||void 0===o||o.insertChild(n.yogaNode,e.yogaNode.getChildCount())),"ink-text"!==e.nodeName&&"ink-virtual-text"!==e.nodeName||f(e)},t.removeChildNode=(e,t)=>{var n,r;t.yogaNode&&(null===(r=null===(n=t.parentNode)||void 0===n?void 0:n.yogaNode)||void 0===r||r.removeChild(t.yogaNode)),t.parentNode=null;const i=e.childNodes.indexOf(t);i>=0&&e.childNodes.splice(i,1),"ink-text"!==e.nodeName&&"ink-virtual-text"!==e.nodeName||f(e)},t.setAttribute=(e,t,n)=>{e.attributes[t]=n},t.setStyle=(e,t)=>{e.style=t,e.yogaNode&&u.default(e.yogaNode,t)},t.createTextNode=e=>{const n={nodeName:"#text",nodeValue:e,yogaNode:void 0,parentNode:null,style:{}};return t.setTextNodeValue(n,e),n};const s=function(e,t){var n,r;const i="#text"===e.nodeName?e.nodeValue:l.default(e),u=o.default(i);if(u.width<=t)return u;if(u.width>=1&&t>0&&t<1)return u;const s=null!==(r=null===(n=e.style)||void 0===n?void 0:n.textWrap)&&void 0!==r?r:"wrap",c=a.default(i,t,s);return o.default(c)},c=e=>{var t;if(e&&e.parentNode)return null!==(t=e.yogaNode)&&void 0!==t?t:c(e.parentNode)},f=e=>{const t=c(e);null==t||t.markDirty()};t.setTextNodeValue=(e,t)=>{"string"!=typeof t&&(t=String(t)),e.nodeValue=t,f(e)}},317:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(6401));t.default=e=>e.getComputedWidth()-e.getComputedPadding(i.default.EDGE_LEFT)-e.getComputedPadding(i.default.EDGE_RIGHT)-e.getComputedBorder(i.default.EDGE_LEFT)-e.getComputedBorder(i.default.EDGE_RIGHT)},4699:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=n(7382),o=r(n(5512));t.default=()=>i.useContext(o.default)},5442:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=n(7382),o=r(n(2560));t.default=()=>{const e=i.useContext(o.default);return{enableFocus:e.enableFocus,disableFocus:e.disableFocus,focusNext:e.focusNext,focusPrevious:e.focusPrevious}}},8230:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=n(7382),o=r(n(2560)),u=r(n(1541));t.default=({isActive:e=!0,autoFocus:t=!1}={})=>{const{isRawModeSupported:n,setRawMode:r}=u.default(),{activeId:a,add:l,remove:s,activate:c,deactivate:f}=i.useContext(o.default),d=i.useMemo(()=>Math.random().toString().slice(2,7),[]);return i.useEffect(()=>(l(d,{autoFocus:t}),()=>{s(d)}),[d,t]),i.useEffect(()=>{e?c(d):f(d)},[e,d]),i.useEffect(()=>{if(n&&e)return r(!0),()=>{r(!1)}},[e]),{isFocused:Boolean(d)&&a===d}}},4495:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=n(7382),o=r(n(1541));t.default=(e,t={})=>{const{stdin:n,setRawMode:r,internal_exitOnCtrlC:u}=o.default();i.useEffect(()=>{if(!1!==t.isActive)return r(!0),()=>{r(!1)}},[t.isActive,r]),i.useEffect(()=>{if(!1===t.isActive)return;const r=t=>{let n=String(t);const r={upArrow:""===n,downArrow:""===n,leftArrow:""===n,rightArrow:""===n,pageDown:"[6~"===n,pageUp:"[5~"===n,return:"\r"===n,escape:""===n,ctrl:!1,shift:!1,tab:"\t"===n||""===n,backspace:"\b"===n,delete:""===n||"[3~"===n,meta:!1};n<=""&&!r.return&&(n=String.fromCharCode(n.charCodeAt(0)+"a".charCodeAt(0)-1),r.ctrl=!0),n.startsWith("")&&(n=n.slice(1),r.meta=!0);const i=n>="A"&&n<="Z",o=n>="А"&&n<="Я";1===n.length&&(i||o)&&(r.shift=!0),r.tab&&"[Z"===n&&(r.shift=!0),(r.tab||r.backspace||r.delete)&&(n=""),"c"===n&&r.ctrl&&u||e(n,r)};return null==n||n.on("data",r),()=>{null==n||n.off("data",r)}},[t.isActive,n,u,e])}},1686:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=n(7382),o=r(n(5001));t.default=()=>i.useContext(o.default)},1541:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=n(7382),o=r(n(1489));t.default=()=>i.useContext(o.default)},9890:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=n(7382),o=r(n(6834));t.default=()=>i.useContext(o.default)},9245:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(9417);Object.defineProperty(t,"render",{enumerable:!0,get:function(){return r.default}});var i=n(5277);Object.defineProperty(t,"Box",{enumerable:!0,get:function(){return i.default}});var o=n(9146);Object.defineProperty(t,"Text",{enumerable:!0,get:function(){return o.default}});var u=n(8915);Object.defineProperty(t,"Static",{enumerable:!0,get:function(){return u.default}});var a=n(4592);Object.defineProperty(t,"Transform",{enumerable:!0,get:function(){return a.default}});var l=n(8200);Object.defineProperty(t,"Newline",{enumerable:!0,get:function(){return l.default}});var s=n(2198);Object.defineProperty(t,"Spacer",{enumerable:!0,get:function(){return s.default}});var c=n(4495);Object.defineProperty(t,"useInput",{enumerable:!0,get:function(){return c.default}});var f=n(4699);Object.defineProperty(t,"useApp",{enumerable:!0,get:function(){return f.default}});var d=n(1541);Object.defineProperty(t,"useStdin",{enumerable:!0,get:function(){return d.default}});var p=n(9890);Object.defineProperty(t,"useStdout",{enumerable:!0,get:function(){return p.default}});var h=n(1686);Object.defineProperty(t,"useStderr",{enumerable:!0,get:function(){return h.default}});var v=n(8230);Object.defineProperty(t,"useFocus",{enumerable:!0,get:function(){return v.default}});var m=n(5442);Object.defineProperty(t,"useFocusManager",{enumerable:!0,get:function(){return m.default}});var g=n(3887);Object.defineProperty(t,"measureElement",{enumerable:!0,get:function(){return g.default}})},3206:function(e,t,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.hasOwnProperty.call(e,n)&&r(t,e,n);return i(t,e),t},u=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const a=u(n(7382)),l=n(464),s=u(n(503)),c=u(n(7589)),f=u(n(2738)),d=u(n(2633)),p=u(n(5117)),h=u(n(5691)),v=u(n(6458)),m=u(n(8070)),g=o(n(9864)),y=u(n(9679)),_=u(n(2773)),b="false"!==process.env.CI&&f.default,w=()=>{};t.default=class{constructor(e){this.resolveExitPromise=()=>{},this.rejectExitPromise=()=>{},this.unsubscribeExit=()=>{},this.onRender=()=>{if(this.isUnmounted)return;const{output:e,outputHeight:t,staticOutput:n}=h.default(this.rootNode,this.options.stdout.columns||80),r=n&&"\n"!==n;return this.options.debug?(r&&(this.fullStaticOutput+=n),void this.options.stdout.write(this.fullStaticOutput+e)):b?(r&&this.options.stdout.write(n),void(this.lastOutput=e)):(r&&(this.fullStaticOutput+=n),t>=this.options.stdout.rows?(this.options.stdout.write(c.default.clearTerminal+this.fullStaticOutput+e),void(this.lastOutput=e)):(r&&(this.log.clear(),this.options.stdout.write(n),this.log(e)),r||e===this.lastOutput||this.throttledLog(e),void(this.lastOutput=e)))},d.default(this),this.options=e,this.rootNode=g.createNode("ink-root"),this.rootNode.onRender=e.debug?this.onRender:l.throttle(this.onRender,32,{leading:!0,trailing:!0}),this.rootNode.onImmediateRender=this.onRender,this.log=s.default.create(e.stdout),this.throttledLog=e.debug?this.log:l.throttle(this.log,void 0,{leading:!0,trailing:!0}),this.isUnmounted=!1,this.lastOutput="",this.fullStaticOutput="",this.container=p.default.createContainer(this.rootNode,!1,!1),this.unsubscribeExit=v.default(this.unmount,{alwaysLast:!1}),"true"===process.env.DEV&&p.default.injectIntoDevTools({bundleType:0,version:"16.13.1",rendererPackageName:"ink"}),e.patchConsole&&this.patchConsole(),b||(e.stdout.on("resize",this.onRender),this.unsubscribeResize=()=>{e.stdout.off("resize",this.onRender)})}render(e){const t=a.default.createElement(_.default,{stdin:this.options.stdin,stdout:this.options.stdout,stderr:this.options.stderr,writeToStdout:this.writeToStdout,writeToStderr:this.writeToStderr,exitOnCtrlC:this.options.exitOnCtrlC,onExit:this.unmount},e);p.default.updateContainer(t,this.container,null,w)}writeToStdout(e){this.isUnmounted||(this.options.debug?this.options.stdout.write(e+this.fullStaticOutput+this.lastOutput):b?this.options.stdout.write(e):(this.log.clear(),this.options.stdout.write(e),this.log(this.lastOutput)))}writeToStderr(e){if(!this.isUnmounted)return this.options.debug?(this.options.stderr.write(e),void this.options.stdout.write(this.fullStaticOutput+this.lastOutput)):void(b?this.options.stderr.write(e):(this.log.clear(),this.options.stderr.write(e),this.log(this.lastOutput)))}unmount(e){this.isUnmounted||(this.onRender(),this.unsubscribeExit(),"function"==typeof this.restoreConsole&&this.restoreConsole(),"function"==typeof this.unsubscribeResize&&this.unsubscribeResize(),b?this.options.stdout.write(this.lastOutput+"\n"):this.options.debug||this.log.done(),this.isUnmounted=!0,p.default.updateContainer(null,this.container,null,w),y.default.delete(this.options.stdout),e instanceof Error?this.rejectExitPromise(e):this.resolveExitPromise())}waitUntilExit(){return this.exitPromise||(this.exitPromise=new Promise((e,t)=>{this.resolveExitPromise=e,this.rejectExitPromise=t})),this.exitPromise}clear(){b||this.options.debug||this.log.clear()}patchConsole(){this.options.debug||(this.restoreConsole=m.default((e,t)=>{if("stdout"===e&&this.writeToStdout(t),"stderr"===e){t.startsWith("The above error occurred")||this.writeToStderr(t)}}))}}},9679:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=new WeakMap},503:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(7589)),o=r(n(1696));t.default={create:(e,{showCursor:t=!1}={})=>{let n=0,r="",u=!1;const a=a=>{t||u||(o.default.hide(),u=!0);const l=a+"\n";l!==r&&(r=l,e.write(i.default.eraseLines(n)+l),n=l.split("\n").length)};return a.clear=()=>{e.write(i.default.eraseLines(n)),r="",n=0},a.done=()=>{r="",n=0,t||(o.default.show(),u=!1)},a}}},3887:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=e=>{var t,n,r,i;return{width:null!==(n=null===(t=e.yogaNode)||void 0===t?void 0:t.getComputedWidth())&&void 0!==n?n:0,height:null!==(i=null===(r=e.yogaNode)||void 0===r?void 0:r.getComputedHeight())&&void 0!==i?i:0}}},8113:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(8949)),o={};t.default=e=>{if(0===e.length)return{width:0,height:0};if(o[e])return o[e];const t=i.default(e),n=e.split("\n").length;return o[e]={width:t,height:n},{width:t,height:n}}},4110:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(1566)),o=r(n(3262));t.default=class{constructor(e){this.writes=[];const{width:t,height:n}=e;this.width=t,this.height=n}write(e,t,n,r){const{transformers:i}=r;n&&this.writes.push({x:e,y:t,text:n,transformers:i})}get(){const e=[];for(let t=0;te.trimRight()).join("\n"),height:e.length}}}},5117:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=n(7181),o=r(n(7714)),u=r(n(6401)),a=n(9864);"true"===process.env.DEV&&n(146);const l=e=>{null==e||e.unsetMeasureFunc(),null==e||e.freeRecursive()};t.default=o.default({schedulePassiveEffects:i.unstable_scheduleCallback,cancelPassiveEffects:i.unstable_cancelCallback,now:Date.now,getRootHostContext:()=>({isInsideText:!1}),prepareForCommit:()=>{},resetAfterCommit:e=>{if(e.isStaticDirty)return e.isStaticDirty=!1,void("function"==typeof e.onImmediateRender&&e.onImmediateRender());"function"==typeof e.onRender&&e.onRender()},getChildHostContext:(e,t)=>{const n="ink-text"===t||"ink-virtual-text"===t;return e.isInsideText===n?e:{isInsideText:n}},shouldSetTextContent:()=>!1,createInstance:(e,t,n,r)=>{if(r.isInsideText&&"ink-box"===e)throw new Error(" can’t be nested inside component");const i="ink-text"===e&&r.isInsideText?"ink-virtual-text":e,o=a.createNode(i);for(const[e,n]of Object.entries(t))"children"!==e&&("style"===e?a.setStyle(o,n):"internal_transform"===e?o.internal_transform=n:"internal_static"===e?o.internal_static=!0:a.setAttribute(o,e,n));return o},createTextInstance:(e,t,n)=>{if(!n.isInsideText)throw new Error(`Text string "${e}" must be rendered inside component`);return a.createTextNode(e)},resetTextContent:()=>{},hideTextInstance:e=>{a.setTextNodeValue(e,"")},unhideTextInstance:(e,t)=>{a.setTextNodeValue(e,t)},getPublicInstance:e=>e,hideInstance:e=>{var t;null===(t=e.yogaNode)||void 0===t||t.setDisplay(u.default.DISPLAY_NONE)},unhideInstance:e=>{var t;null===(t=e.yogaNode)||void 0===t||t.setDisplay(u.default.DISPLAY_FLEX)},appendInitialChild:a.appendChildNode,appendChild:a.appendChildNode,insertBefore:a.insertBeforeNode,finalizeInitialChildren:(e,t,n,r)=>(e.internal_static&&(r.isStaticDirty=!0,r.staticNode=e),!1),supportsMutation:!0,appendChildToContainer:a.appendChildNode,insertInContainerBefore:a.insertBeforeNode,removeChildFromContainer:(e,t)=>{a.removeChildNode(e,t),l(t.yogaNode)},prepareUpdate:(e,t,n,r,i)=>{e.internal_static&&(i.isStaticDirty=!0);const o={},u=Object.keys(r);for(const e of u)if(r[e]!==n[e]){if("style"===e&&"object"==typeof r.style&&"object"==typeof n.style){const e=r.style,t=n.style,i=Object.keys(e);for(const n of i){if("borderStyle"===n||"borderColor"===n){if("object"!=typeof o.style){const e={};o.style=e}o.style.borderStyle=e.borderStyle,o.style.borderColor=e.borderColor}if(e[n]!==t[n]){if("object"!=typeof o.style){const e={};o.style=e}o.style[n]=e[n]}}continue}o[e]=r[e]}return o},commitUpdate:(e,t)=>{for(const[n,r]of Object.entries(t))"children"!==n&&("style"===n?a.setStyle(e,r):"internal_transform"===n?e.internal_transform=r:"internal_static"===n?e.internal_static=!0:a.setAttribute(e,n,r))},commitTextUpdate:(e,t,n)=>{a.setTextNodeValue(e,n)},removeChild:(e,t)=>{a.removeChildNode(e,t),l(t.yogaNode)}})},4907:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(4097)),o=r(n(9902));t.default=(e,t,n,r)=>{if("string"==typeof n.style.borderStyle){const u=n.yogaNode.getComputedWidth(),a=n.yogaNode.getComputedHeight(),l=n.style.borderColor,s=i.default[n.style.borderStyle],c=o.default(s.topLeft+s.horizontal.repeat(u-2)+s.topRight,l,"foreground"),f=(o.default(s.vertical,l,"foreground")+"\n").repeat(a-2),d=o.default(s.bottomLeft+s.horizontal.repeat(u-2)+s.bottomRight,l,"foreground");r.write(e,t,c,{transformers:[]}),r.write(e,t+1,f,{transformers:[]}),r.write(e+u-1,t+1,f,{transformers:[]}),r.write(e,t+a-1,d,{transformers:[]})}}},3782:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(6401)),o=r(n(8949)),u=r(n(9646)),a=r(n(2030)),l=r(n(317)),s=r(n(9099)),c=r(n(4907)),f=(e,t,n)=>{var r;const{offsetX:d=0,offsetY:p=0,transformers:h=[],skipStaticElements:v}=n;if(v&&e.internal_static)return;const{yogaNode:m}=e;if(m){if(m.getDisplay()===i.default.DISPLAY_NONE)return;const n=d+m.getComputedLeft(),g=p+m.getComputedTop();let y=h;if("function"==typeof e.internal_transform&&(y=[e.internal_transform,...h]),"ink-text"===e.nodeName){let i=s.default(e);if(i.length>0){const s=o.default(i),c=l.default(m);if(s>c){const t=null!==(r=e.style.textWrap)&&void 0!==r?r:"wrap";i=a.default(i,c,t)}i=((e,t)=>{var n;const r=null===(n=e.childNodes[0])||void 0===n?void 0:n.yogaNode;if(r){const e=r.getComputedLeft(),n=r.getComputedTop();t="\n".repeat(n)+u.default(t,e)}return t})(e,i),t.write(n,g,i,{transformers:y})}return}if("ink-box"===e.nodeName&&c.default(n,g,e,t),"ink-root"===e.nodeName||"ink-box"===e.nodeName)for(const r of e.childNodes)f(r,t,{offsetX:n,offsetY:g,transformers:y,skipStaticElements:v})}};t.default=f},9417:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(3206)),o=r(n(9679)),u=n(2413);t.default=(e,t)=>{const n=Object.assign({stdout:process.stdout,stdin:process.stdin,stderr:process.stderr,debug:!1,exitOnCtrlC:!0,patchConsole:!0},a(t)),r=l(n.stdout,()=>new i.default(n));return r.render(e),{rerender:r.render,unmount:()=>r.unmount(),waitUntilExit:r.waitUntilExit,cleanup:()=>o.default.delete(n.stdout),clear:r.clear}};const a=(e={})=>e instanceof u.Stream?{stdout:e,stdin:process.stdin}:e,l=(e,t)=>{let n;return o.default.has(e)?n=o.default.get(e):(n=t(),o.default.set(e,n)),n}},5691:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(6401)),o=r(n(3782)),u=r(n(4110));t.default=(e,t)=>{var n;if(e.yogaNode.setWidth(t),e.yogaNode){e.yogaNode.calculateLayout(void 0,void 0,i.default.DIRECTION_LTR);const t=new u.default({width:e.yogaNode.getComputedWidth(),height:e.yogaNode.getComputedHeight()});let r;o.default(e,t,{skipStaticElements:!0}),(null===(n=e.staticNode)||void 0===n?void 0:n.yogaNode)&&(r=new u.default({width:e.staticNode.yogaNode.getComputedWidth(),height:e.staticNode.yogaNode.getComputedHeight()}),o.default(e.staticNode,r,{skipStaticElements:!1}));const{output:a,height:l}=t.get();return{output:a,outputHeight:l,staticOutput:r?r.get().output+"\n":""}}return{output:"",outputHeight:0,staticOutput:""}}},9099:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const n=e=>{let t="";if(e.childNodes.length>0)for(const r of e.childNodes){let e="";"#text"===r.nodeName?e=r.nodeValue:("ink-text"!==r.nodeName&&"ink-virtual-text"!==r.nodeName||(e=n(r)),e.length>0&&"function"==typeof r.internal_transform&&(e=r.internal_transform(e))),t+=e}return t};t.default=n},5809:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(6401));t.default=(e,t={})=>{((e,t)=>{"position"in t&&e.setPositionType("absolute"===t.position?i.default.POSITION_TYPE_ABSOLUTE:i.default.POSITION_TYPE_RELATIVE)})(e,t),((e,t)=>{"marginLeft"in t&&e.setMargin(i.default.EDGE_START,t.marginLeft||0),"marginRight"in t&&e.setMargin(i.default.EDGE_END,t.marginRight||0),"marginTop"in t&&e.setMargin(i.default.EDGE_TOP,t.marginTop||0),"marginBottom"in t&&e.setMargin(i.default.EDGE_BOTTOM,t.marginBottom||0)})(e,t),((e,t)=>{"paddingLeft"in t&&e.setPadding(i.default.EDGE_LEFT,t.paddingLeft||0),"paddingRight"in t&&e.setPadding(i.default.EDGE_RIGHT,t.paddingRight||0),"paddingTop"in t&&e.setPadding(i.default.EDGE_TOP,t.paddingTop||0),"paddingBottom"in t&&e.setPadding(i.default.EDGE_BOTTOM,t.paddingBottom||0)})(e,t),((e,t)=>{var n;"flexGrow"in t&&e.setFlexGrow(null!==(n=t.flexGrow)&&void 0!==n?n:0),"flexShrink"in t&&e.setFlexShrink("number"==typeof t.flexShrink?t.flexShrink:1),"flexDirection"in t&&("row"===t.flexDirection&&e.setFlexDirection(i.default.FLEX_DIRECTION_ROW),"row-reverse"===t.flexDirection&&e.setFlexDirection(i.default.FLEX_DIRECTION_ROW_REVERSE),"column"===t.flexDirection&&e.setFlexDirection(i.default.FLEX_DIRECTION_COLUMN),"column-reverse"===t.flexDirection&&e.setFlexDirection(i.default.FLEX_DIRECTION_COLUMN_REVERSE)),"flexBasis"in t&&("number"==typeof t.flexBasis?e.setFlexBasis(t.flexBasis):"string"==typeof t.flexBasis?e.setFlexBasisPercent(Number.parseInt(t.flexBasis,10)):e.setFlexBasis(NaN)),"alignItems"in t&&("stretch"!==t.alignItems&&t.alignItems||e.setAlignItems(i.default.ALIGN_STRETCH),"flex-start"===t.alignItems&&e.setAlignItems(i.default.ALIGN_FLEX_START),"center"===t.alignItems&&e.setAlignItems(i.default.ALIGN_CENTER),"flex-end"===t.alignItems&&e.setAlignItems(i.default.ALIGN_FLEX_END)),"alignSelf"in t&&("auto"!==t.alignSelf&&t.alignSelf||e.setAlignSelf(i.default.ALIGN_AUTO),"flex-start"===t.alignSelf&&e.setAlignSelf(i.default.ALIGN_FLEX_START),"center"===t.alignSelf&&e.setAlignSelf(i.default.ALIGN_CENTER),"flex-end"===t.alignSelf&&e.setAlignSelf(i.default.ALIGN_FLEX_END)),"justifyContent"in t&&("flex-start"!==t.justifyContent&&t.justifyContent||e.setJustifyContent(i.default.JUSTIFY_FLEX_START),"center"===t.justifyContent&&e.setJustifyContent(i.default.JUSTIFY_CENTER),"flex-end"===t.justifyContent&&e.setJustifyContent(i.default.JUSTIFY_FLEX_END),"space-between"===t.justifyContent&&e.setJustifyContent(i.default.JUSTIFY_SPACE_BETWEEN),"space-around"===t.justifyContent&&e.setJustifyContent(i.default.JUSTIFY_SPACE_AROUND))})(e,t),((e,t)=>{var n,r;"width"in t&&("number"==typeof t.width?e.setWidth(t.width):"string"==typeof t.width?e.setWidthPercent(Number.parseInt(t.width,10)):e.setWidthAuto()),"height"in t&&("number"==typeof t.height?e.setHeight(t.height):"string"==typeof t.height?e.setHeightPercent(Number.parseInt(t.height,10)):e.setHeightAuto()),"minWidth"in t&&("string"==typeof t.minWidth?e.setMinWidthPercent(Number.parseInt(t.minWidth,10)):e.setMinWidth(null!==(n=t.minWidth)&&void 0!==n?n:0)),"minHeight"in t&&("string"==typeof t.minHeight?e.setMinHeightPercent(Number.parseInt(t.minHeight,10)):e.setMinHeight(null!==(r=t.minHeight)&&void 0!==r?r:0))})(e,t),((e,t)=>{"display"in t&&e.setDisplay("flex"===t.display?i.default.DISPLAY_FLEX:i.default.DISPLAY_NONE)})(e,t),((e,t)=>{if("borderStyle"in t){const n="string"==typeof t.borderStyle?1:0;e.setBorder(i.default.EDGE_TOP,n),e.setBorder(i.default.EDGE_BOTTOM,n),e.setBorder(i.default.EDGE_LEFT,n),e.setBorder(i.default.EDGE_RIGHT,n)}})(e,t)}},2030:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(n(4332)),o=r(n(5301)),u={};t.default=(e,t,n)=>{const r=e+String(t)+String(n);if(u[r])return u[r];let a=e;if("wrap"===n&&(a=i.default(e,t,{trim:!1,hard:!0})),n.startsWith("truncate")){let r="end";"truncate-middle"===n&&(r="middle"),"truncate-start"===n&&(r="start"),a=o.default(e,t,{position:r})}return u[r]=a,a}},5767:(e,t,n)=>{ +var plugin=(()=>{var PR=Object.create,J1=Object.defineProperty,MR=Object.defineProperties,FR=Object.getOwnPropertyDescriptor,LR=Object.getOwnPropertyDescriptors,RR=Object.getOwnPropertyNames,hh=Object.getOwnPropertySymbols,NR=Object.getPrototypeOf,Z4=Object.prototype.hasOwnProperty,aD=Object.prototype.propertyIsEnumerable;var dD=(i,u,f)=>u in i?J1(i,u,{enumerable:!0,configurable:!0,writable:!0,value:f}):i[u]=f,dt=(i,u)=>{for(var f in u||(u={}))Z4.call(u,f)&&dD(i,f,u[f]);if(hh)for(var f of hh(u))aD.call(u,f)&&dD(i,f,u[f]);return i},zn=(i,u)=>MR(i,LR(u)),BR=i=>J1(i,"__esModule",{value:!0});var Si=(i,u)=>{var f={};for(var c in i)Z4.call(i,c)&&u.indexOf(c)<0&&(f[c]=i[c]);if(i!=null&&hh)for(var c of hh(i))u.indexOf(c)<0&&aD.call(i,c)&&(f[c]=i[c]);return f};var Me=(i,u)=>()=>(u||i((u={exports:{}}).exports,u),u.exports),jR=(i,u)=>{for(var f in u)J1(i,f,{get:u[f],enumerable:!0})},UR=(i,u,f)=>{if(u&&typeof u=="object"||typeof u=="function")for(let c of RR(u))!Z4.call(i,c)&&c!=="default"&&J1(i,c,{get:()=>u[c],enumerable:!(f=FR(u,c))||f.enumerable});return i},Er=i=>UR(BR(J1(i!=null?PR(NR(i)):{},"default",i&&i.__esModule&&"default"in i?{get:()=>i.default,enumerable:!0}:{value:i,enumerable:!0})),i);var ey=Me((YH,pD)=>{"use strict";var hD=Object.getOwnPropertySymbols,qR=Object.prototype.hasOwnProperty,zR=Object.prototype.propertyIsEnumerable;function WR(i){if(i==null)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(i)}function HR(){try{if(!Object.assign)return!1;var i=new String("abc");if(i[5]="de",Object.getOwnPropertyNames(i)[0]==="5")return!1;for(var u={},f=0;f<10;f++)u["_"+String.fromCharCode(f)]=f;var c=Object.getOwnPropertyNames(u).map(function(t){return u[t]});if(c.join("")!=="0123456789")return!1;var g={};return"abcdefghijklmnopqrst".split("").forEach(function(t){g[t]=t}),Object.keys(Object.assign({},g)).join("")==="abcdefghijklmnopqrst"}catch(t){return!1}}pD.exports=HR()?Object.assign:function(i,u){for(var f,c=WR(i),g,t=1;t{"use strict";var ty=ey(),as=typeof Symbol=="function"&&Symbol.for,Q1=as?Symbol.for("react.element"):60103,bR=as?Symbol.for("react.portal"):60106,GR=as?Symbol.for("react.fragment"):60107,VR=as?Symbol.for("react.strict_mode"):60108,YR=as?Symbol.for("react.profiler"):60114,$R=as?Symbol.for("react.provider"):60109,KR=as?Symbol.for("react.context"):60110,XR=as?Symbol.for("react.forward_ref"):60112,JR=as?Symbol.for("react.suspense"):60113,QR=as?Symbol.for("react.memo"):60115,ZR=as?Symbol.for("react.lazy"):60116,mD=typeof Symbol=="function"&&Symbol.iterator;function Z1(i){for(var u="https://reactjs.org/docs/error-decoder.html?invariant="+i,f=1;fmh.length&&mh.push(i)}function uy(i,u,f,c){var g=typeof i;(g==="undefined"||g==="boolean")&&(i=null);var t=!1;if(i===null)t=!0;else switch(g){case"string":case"number":t=!0;break;case"object":switch(i.$$typeof){case Q1:case bR:t=!0}}if(t)return f(c,i,u===""?"."+sy(i,0):u),1;if(t=0,u=u===""?".":u+":",Array.isArray(i))for(var C=0;C{"use strict";kD.exports=xD()});var AD=Me((ga,e2)=>{(function(){var i,u="4.17.21",f=200,c="Unsupported core-js use. Try https://npms.io/search?q=ponyfill.",g="Expected a function",t="Invalid `variable` option passed into `_.template`",C="__lodash_hash_undefined__",A=500,x="__lodash_placeholder__",D=1,L=2,N=4,j=1,$=2,h=1,re=2,ce=4,Q=8,oe=16,Se=32,me=64,De=128,J=256,Te=512,Oe=30,Le="...",ot=800,ct=16,Ue=1,be=2,At=3,Ot=1/0,Nt=9007199254740991,Je=17976931348623157e292,V=0/0,ne=4294967295,ge=ne-1,Z=ne>>>1,Ae=[["ary",De],["bind",h],["bindKey",re],["curry",Q],["curryRight",oe],["flip",Te],["partial",Se],["partialRight",me],["rearg",J]],at="[object Arguments]",it="[object Array]",Ft="[object AsyncFunction]",jt="[object Boolean]",hn="[object Date]",Un="[object DOMException]",Jt="[object Error]",Yt="[object Function]",cr="[object GeneratorFunction]",w="[object Map]",pt="[object Number]",Mn="[object Null]",Bn="[object Object]",Xn="[object Promise]",vr="[object Proxy]",gr="[object RegExp]",r0="[object Set]",Ci="[object String]",yo="[object Symbol]",Ds="[object Undefined]",Mu="[object WeakMap]",Gf="[object WeakSet]",iu="[object ArrayBuffer]",ou="[object DataView]",ol="[object Float32Array]",ul="[object Float64Array]",Es="[object Int8Array]",Uo="[object Int16Array]",sl="[object Int32Array]",Ss="[object Uint8Array]",Cs="[object Uint8ClampedArray]",Ti="[object Uint16Array]",Fu="[object Uint32Array]",ll=/\b__p \+= '';/g,fl=/\b(__p \+=) '' \+/g,cl=/(__e\(.*?\)|\b__t\)) \+\n'';/g,al=/&(?:amp|lt|gt|quot|#39);/g,Ui=/[&<>"']/g,Mr=RegExp(al.source),Ac=RegExp(Ui.source),of=/<%-([\s\S]+?)%>/g,Ts=/<%([\s\S]+?)%>/g,xs=/<%=([\s\S]+?)%>/g,dl=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,qi=/^\w*$/,qo=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,kr=/[\\^$.*+?()[\]{}|]/g,Fr=RegExp(kr.source),si=/^\s+/,H0=/\s/,b0=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Bt=/\{\n\/\* \[wrapped with (.+)\] \*/,Lu=/,? & /,c0=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,Ru=/[()=,{}\[\]\/\s]/,ks=/\\(\\)?/g,As=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,uu=/\w*$/,wo=/^[-+]0x[0-9a-f]+$/i,zo=/^0b[01]+$/i,Os=/^\[object .+?Constructor\]$/,Is=/^0o[0-7]+$/i,uf=/^(?:0|[1-9]\d*)$/,_n=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,Nu=/($^)/,Wo=/['\n\r\u2028\u2029\\]/g,su="\\ud800-\\udfff",Ps="\\u0300-\\u036f",pl="\\ufe20-\\ufe2f",Vf="\\u20d0-\\u20ff",hl=Ps+pl+Vf,Bu="\\u2700-\\u27bf",ju="a-z\\xdf-\\xf6\\xf8-\\xff",sf="\\xac\\xb1\\xd7\\xf7",ro="\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf",Ms="\\u2000-\\u206f",ml=" \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",Uu="A-Z\\xc0-\\xd6\\xd8-\\xde",G0="\\ufe0e\\ufe0f",Fs=sf+ro+Ms+ml,tt="['\u2019]",zi="["+su+"]",lu="["+Fs+"]",Ho="["+hl+"]",O0="\\d+",vl="["+Bu+"]",gl="["+ju+"]",fu="[^"+su+Fs+O0+Bu+ju+Uu+"]",_l="\\ud83c[\\udffb-\\udfff]",Sn="(?:"+Ho+"|"+_l+")",gt="[^"+su+"]",en="(?:\\ud83c[\\udde6-\\uddff]){2}",I0="[\\ud800-\\udbff][\\udc00-\\udfff]",li="["+Uu+"]",qu="\\u200d",Wi="(?:"+gl+"|"+fu+")",zu="(?:"+li+"|"+fu+")",Wu="(?:"+tt+"(?:d|ll|m|re|s|t|ve))?",Ls="(?:"+tt+"(?:D|LL|M|RE|S|T|VE))?",fi=Sn+"?",e0="["+G0+"]?",io="(?:"+qu+"(?:"+[gt,en,I0].join("|")+")"+e0+fi+")*",D0="\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",Do="\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])",i0=e0+fi+io,Rs="(?:"+[vl,en,I0].join("|")+")"+i0,a0="(?:"+[gt+Ho+"?",Ho,en,I0,zi].join("|")+")",Hu=RegExp(tt,"g"),V0=RegExp(Ho,"g"),bu=RegExp(_l+"(?="+_l+")|"+a0+i0,"g"),Ns=RegExp([li+"?"+gl+"+"+Wu+"(?="+[lu,li,"$"].join("|")+")",zu+"+"+Ls+"(?="+[lu,li+Wi,"$"].join("|")+")",li+"?"+Wi+"+"+Wu,li+"+"+Ls,Do,D0,O0,Rs].join("|"),"g"),bo=RegExp("["+qu+su+hl+G0+"]"),P0=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,ln=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],lf=-1,nr={};nr[ol]=nr[ul]=nr[Es]=nr[Uo]=nr[sl]=nr[Ss]=nr[Cs]=nr[Ti]=nr[Fu]=!0,nr[at]=nr[it]=nr[iu]=nr[jt]=nr[ou]=nr[hn]=nr[Jt]=nr[Yt]=nr[w]=nr[pt]=nr[Bn]=nr[gr]=nr[r0]=nr[Ci]=nr[Mu]=!1;var rr={};rr[at]=rr[it]=rr[iu]=rr[ou]=rr[jt]=rr[hn]=rr[ol]=rr[ul]=rr[Es]=rr[Uo]=rr[sl]=rr[w]=rr[pt]=rr[Bn]=rr[gr]=rr[r0]=rr[Ci]=rr[yo]=rr[Ss]=rr[Cs]=rr[Ti]=rr[Fu]=!0,rr[Jt]=rr[Yt]=rr[Mu]=!1;var Go={\u00C0:"A",\u00C1:"A",\u00C2:"A",\u00C3:"A",\u00C4:"A",\u00C5:"A",\u00E0:"a",\u00E1:"a",\u00E2:"a",\u00E3:"a",\u00E4:"a",\u00E5:"a",\u00C7:"C",\u00E7:"c",\u00D0:"D",\u00F0:"d",\u00C8:"E",\u00C9:"E",\u00CA:"E",\u00CB:"E",\u00E8:"e",\u00E9:"e",\u00EA:"e",\u00EB:"e",\u00CC:"I",\u00CD:"I",\u00CE:"I",\u00CF:"I",\u00EC:"i",\u00ED:"i",\u00EE:"i",\u00EF:"i",\u00D1:"N",\u00F1:"n",\u00D2:"O",\u00D3:"O",\u00D4:"O",\u00D5:"O",\u00D6:"O",\u00D8:"O",\u00F2:"o",\u00F3:"o",\u00F4:"o",\u00F5:"o",\u00F6:"o",\u00F8:"o",\u00D9:"U",\u00DA:"U",\u00DB:"U",\u00DC:"U",\u00F9:"u",\u00FA:"u",\u00FB:"u",\u00FC:"u",\u00DD:"Y",\u00FD:"y",\u00FF:"y",\u00C6:"Ae",\u00E6:"ae",\u00DE:"Th",\u00FE:"th",\u00DF:"ss",\u0100:"A",\u0102:"A",\u0104:"A",\u0101:"a",\u0103:"a",\u0105:"a",\u0106:"C",\u0108:"C",\u010A:"C",\u010C:"C",\u0107:"c",\u0109:"c",\u010B:"c",\u010D:"c",\u010E:"D",\u0110:"D",\u010F:"d",\u0111:"d",\u0112:"E",\u0114:"E",\u0116:"E",\u0118:"E",\u011A:"E",\u0113:"e",\u0115:"e",\u0117:"e",\u0119:"e",\u011B:"e",\u011C:"G",\u011E:"G",\u0120:"G",\u0122:"G",\u011D:"g",\u011F:"g",\u0121:"g",\u0123:"g",\u0124:"H",\u0126:"H",\u0125:"h",\u0127:"h",\u0128:"I",\u012A:"I",\u012C:"I",\u012E:"I",\u0130:"I",\u0129:"i",\u012B:"i",\u012D:"i",\u012F:"i",\u0131:"i",\u0134:"J",\u0135:"j",\u0136:"K",\u0137:"k",\u0138:"k",\u0139:"L",\u013B:"L",\u013D:"L",\u013F:"L",\u0141:"L",\u013A:"l",\u013C:"l",\u013E:"l",\u0140:"l",\u0142:"l",\u0143:"N",\u0145:"N",\u0147:"N",\u014A:"N",\u0144:"n",\u0146:"n",\u0148:"n",\u014B:"n",\u014C:"O",\u014E:"O",\u0150:"O",\u014D:"o",\u014F:"o",\u0151:"o",\u0154:"R",\u0156:"R",\u0158:"R",\u0155:"r",\u0157:"r",\u0159:"r",\u015A:"S",\u015C:"S",\u015E:"S",\u0160:"S",\u015B:"s",\u015D:"s",\u015F:"s",\u0161:"s",\u0162:"T",\u0164:"T",\u0166:"T",\u0163:"t",\u0165:"t",\u0167:"t",\u0168:"U",\u016A:"U",\u016C:"U",\u016E:"U",\u0170:"U",\u0172:"U",\u0169:"u",\u016B:"u",\u016D:"u",\u016F:"u",\u0171:"u",\u0173:"u",\u0174:"W",\u0175:"w",\u0176:"Y",\u0177:"y",\u0178:"Y",\u0179:"Z",\u017B:"Z",\u017D:"Z",\u017A:"z",\u017C:"z",\u017E:"z",\u0132:"IJ",\u0133:"ij",\u0152:"Oe",\u0153:"oe",\u0149:"'n",\u017F:"s"},Gu={"&":"&","<":"<",">":">",'"':""","'":"'"},yl={"&":"&","<":"<",">":">",""":'"',"'":"'"},cu={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Bs=parseFloat,Vu=parseInt,M0=typeof global=="object"&&global&&global.Object===Object&&global,au=typeof self=="object"&&self&&self.Object===Object&&self,Lr=M0||au||Function("return this")(),F=typeof ga=="object"&&ga&&!ga.nodeType&&ga,R=F&&typeof e2=="object"&&e2&&!e2.nodeType&&e2,U=R&&R.exports===F,H=U&&M0.process,fe=function(){try{var ae=R&&R.require&&R.require("util").types;return ae||H&&H.binding&&H.binding("util")}catch(Be){}}(),ue=fe&&fe.isArrayBuffer,de=fe&&fe.isDate,W=fe&&fe.isMap,ve=fe&&fe.isRegExp,Fe=fe&&fe.isSet,Ge=fe&&fe.isTypedArray;function K(ae,Be,Ie){switch(Ie.length){case 0:return ae.call(Be);case 1:return ae.call(Be,Ie[0]);case 2:return ae.call(Be,Ie[0],Ie[1]);case 3:return ae.call(Be,Ie[0],Ie[1],Ie[2])}return ae.apply(Be,Ie)}function xe(ae,Be,Ie,ht){for(var mt=-1,wn=ae==null?0:ae.length;++mt-1}function wt(ae,Be,Ie){for(var ht=-1,mt=ae==null?0:ae.length;++ht-1;);return Ie}function js(ae,Be){for(var Ie=ae.length;Ie--&&Qe(Be,ae[Ie],0)>-1;);return Ie}function Dl(ae,Be){for(var Ie=ae.length,ht=0;Ie--;)ae[Ie]===Be&&++ht;return ht}var du=Cn(Go),Yu=Cn(Gu);function Us(ae){return"\\"+cu[ae]}function oo(ae,Be){return ae==null?i:ae[Be]}function Hi(ae){return bo.test(ae)}function qs(ae){return P0.test(ae)}function F0(ae){for(var Be,Ie=[];!(Be=ae.next()).done;)Ie.push(Be.value);return Ie}function Gr(ae){var Be=-1,Ie=Array(ae.size);return ae.forEach(function(ht,mt){Ie[++Be]=[mt,ht]}),Ie}function ir(ae,Be){return function(Ie){return ae(Be(Ie))}}function L0(ae,Be){for(var Ie=-1,ht=ae.length,mt=0,wn=[];++Ie-1}function Ju(a,p){var E=this.__data__,I=hf(E,a);return I<0?(++this.size,E.push([a,p])):E[I][1]=p,this}Z0.prototype.clear=df,Z0.prototype.delete=Ba,Z0.prototype.get=Oc,Z0.prototype.has=mu,Z0.prototype.set=Ju;function ei(a){var p=-1,E=a==null?0:a.length;for(this.clear();++p=p?a:p)),a}function vi(a,p,E,I,B,G){var te,se=p&D,Ee=p&L,$e=p&N;if(E&&(te=B?E(a,I,B,G):E(a)),te!==i)return te;if(!Jr(a))return a;var Ke=On(a);if(Ke){if(te=f1(a),!se)return Xr(a,te)}else{var nt=U0(a),Ct=nt==Yt||nt==cr;if(Eu(a))return Od(a,se);if(nt==Bn||nt==at||Ct&&!B){if(te=Ee||Ct?{}:zd(a),!se)return Ee?Zu(a,Wa(te,a)):j0(a,mf(te,a))}else{if(!rr[nt])return B?a:{};te=Wd(a,nt,se)}}G||(G=new co);var Gt=G.get(a);if(Gt)return Gt;G.set(a,te),kp(a)?a.forEach(function(dn){te.add(vi(dn,p,E,dn,a,G))}):Tp(a)&&a.forEach(function(dn,Yn){te.set(Yn,vi(dn,p,E,Yn,a,G))});var an=$e?Ee?Dn:r1:Ee?Yi:q0,qn=Ke?i:an(a);return je(qn||a,function(dn,Yn){qn&&(Yn=dn,dn=a[Yn]),xl(te,Yn,vi(dn,p,E,Yn,a,G))}),te}function Xf(a){var p=q0(a);return function(E){return Rc(E,a,p)}}function Rc(a,p,E){var I=E.length;if(a==null)return!I;for(a=$t(a);I--;){var B=E[I],G=p[B],te=a[B];if(te===i&&!(B in a)||!G(te))return!1}return!0}function Jf(a,p,E){if(typeof a!="function")throw new Yr(g);return wf(function(){a.apply(i,E)},p)}function ao(a,p,E,I){var B=-1,G=xt,te=!0,se=a.length,Ee=[],$e=p.length;if(!se)return Ee;E&&(p=lt(p,qr(E))),I?(G=wt,te=!1):p.length>=f&&(G=So,te=!1,p=new vu(p));e:for(;++BB?0:B+E),I=I===i||I>B?B:jn(I),I<0&&(I+=B),I=E>I?0:Ip(I);E0&&E(se)?p>1?k0(se,p-1,E,I,B):Rt(B,se):I||(B[B.length]=se)}return B}var v=ec(),m=ec(!0);function S(a,p){return a&&v(a,p,q0)}function O(a,p){return a&&m(a,p,q0)}function M(a,p){return st(p,function(E){return rs(a[E])})}function b(a,p){p=Gs(p,a);for(var E=0,I=p.length;a!=null&&Ep}function ut(a,p){return a!=null&&or.call(a,p)}function In(a,p){return a!=null&&p in $t(a)}function A0(a,p,E){return a>=kn(p,E)&&a=120&&Ke.length>=120)?new vu(te&&Ke):i}Ke=a[0];var nt=-1,Ct=se[0];e:for(;++nt-1;)se!==a&&C0.call(se,Ee,1),C0.call(a,Ee,1);return a}function jc(a,p){for(var E=a?p.length:0,I=E-1;E--;){var B=p[E];if(E==I||B!==G){var G=B;es(B)?C0.call(a,B,1):$a(a,B)}}return a}function Ga(a,p){return a+hu(Ai()*(p-a+1))}function Lm(a,p,E,I){for(var B=-1,G=wr(B0((p-a)/(E||1)),0),te=Ie(G);G--;)te[I?G:++B]=a,a+=E;return te}function Va(a,p){var E="";if(!a||p<1||p>Nt)return E;do p%2&&(E+=a),p=hu(p/2),p&&(a+=a);while(p);return E}function Wn(a,p){return m1(Gd(a,p,$i),a+"")}function wd(a){return Fc(Ef(a))}function Dd(a,p){var E=Ef(a);return Yc(E,mi(p,0,E.length))}function Ol(a,p,E,I){if(!Jr(a))return a;p=Gs(p,a);for(var B=-1,G=p.length,te=G-1,se=a;se!=null&&++BB?0:B+p),E=E>B?B:E,E<0&&(E+=B),B=p>E?0:E-p>>>0,p>>>=0;for(var G=Ie(B);++I>>1,te=a[G];te!==null&&!mo(te)&&(E?te<=p:te=f){var $e=p?null:bm(a);if($e)return Y0($e);te=!1,B=So,Ee=new vu}else Ee=p?[]:se;e:for(;++I=I?a:Oo(a,p,E)}var Ad=pu||function(a){return Lr.clearTimeout(a)};function Od(a,p){if(p)return a.slice();var E=a.length,I=Nr?Nr(E):new a.constructor(E);return a.copy(I),I}function Qa(a){var p=new a.constructor(a.byteLength);return new R0(p).set(new R0(a)),p}function jm(a,p){var E=p?Qa(a.buffer):a.buffer;return new a.constructor(E,a.byteOffset,a.byteLength)}function Um(a){var p=new a.constructor(a.source,uu.exec(a));return p.lastIndex=a.lastIndex,p}function qm(a){return Wr?$t(Wr.call(a)):{}}function Id(a,p){var E=p?Qa(a.buffer):a.buffer;return new a.constructor(E,a.byteOffset,a.length)}function Pd(a,p){if(a!==p){var E=a!==i,I=a===null,B=a===a,G=mo(a),te=p!==i,se=p===null,Ee=p===p,$e=mo(p);if(!se&&!$e&&!G&&a>p||G&&te&&Ee&&!se&&!$e||I&&te&&Ee||!E&&Ee||!B)return 1;if(!I&&!G&&!$e&&a=se)return Ee;var $e=E[I];return Ee*($e=="desc"?-1:1)}}return a.index-p.index}function gf(a,p,E,I){for(var B=-1,G=a.length,te=E.length,se=-1,Ee=p.length,$e=wr(G-te,0),Ke=Ie(Ee+$e),nt=!I;++se1?E[B-1]:i,te=B>2?E[2]:i;for(G=a.length>3&&typeof G=="function"?(B--,G):i,te&&Ii(E[0],E[1],te)&&(G=B<3?i:G,B=1),p=$t(p);++I-1?B[G?p[te]:te]:i}}function Rd(a){return yu(function(p){var E=p.length,I=E,B=Qn.prototype.thru;for(a&&p.reverse();I--;){var G=p[I];if(typeof G!="function")throw new Yr(g);if(B&&!te&&Gc(G)=="wrapper")var te=new Qn([],!0)}for(I=te?I:E;++I1&&er.reverse(),Ke&&Eese))return!1;var $e=G.get(a),Ke=G.get(p);if($e&&Ke)return $e==p&&Ke==a;var nt=-1,Ct=!0,Gt=E&$?new vu:i;for(G.set(a,p),G.set(p,a);++nt1?"& ":"")+p[I],p=p.join(E>2?", ":" "),a.replace(b0,`{ +/* [wrapped with `+p+`] */ +`)}function Xm(a){return On(a)||Ll(a)||!!(di&&a&&a[di])}function es(a,p){var E=typeof a;return p=p==null?Nt:p,!!p&&(E=="number"||E!="symbol"&&uf.test(a))&&a>-1&&a%1==0&&a0){if(++p>=ot)return arguments[0]}else p=0;return a.apply(i,arguments)}}function Yc(a,p){var E=-1,I=a.length,B=I-1;for(p=p===i?I:p;++E1?a[p-1]:i;return E=typeof E=="function"?(a.pop(),E):i,sp(a,E)});function fp(a){var p=z(a);return p.__chain__=!0,p}function cp(a,p){return p(a),a}function Kc(a,p){return p(a)}var Wv=yu(function(a){var p=a.length,E=p?a[0]:0,I=this.__wrapped__,B=function(G){return Hs(G,a)};return p>1||this.__actions__.length||!(I instanceof nn)||!es(E)?this.thru(B):(I=I.slice(E,+E+(p?1:0)),I.__actions__.push({func:Kc,args:[B],thisArg:i}),new Qn(I,this.__chain__).thru(function(G){return p&&!G.length&&G.push(i),G}))});function Hv(){return fp(this)}function bv(){return new Qn(this.value(),this.__chain__)}function Gv(){this.__values__===i&&(this.__values__=Op(this.value()));var a=this.__index__>=this.__values__.length,p=a?i:this.__values__[this.__index__++];return{done:a,value:p}}function Vv(){return this}function Yv(a){for(var p,E=this;E instanceof Or;){var I=Jd(E);I.__index__=0,I.__values__=i,p?B.__wrapped__=I:p=I;var B=I;E=E.__wrapped__}return B.__wrapped__=a,p}function Ml(){var a=this.__wrapped__;if(a instanceof nn){var p=a;return this.__actions__.length&&(p=new nn(this)),p=p.reverse(),p.__actions__.push({func:Kc,args:[g1],thisArg:i}),new Qn(p,this.__chain__)}return this.thru(g1)}function Fl(){return xd(this.__wrapped__,this.__actions__)}var Xc=_f(function(a,p,E){or.call(a,E)?++a[E]:ti(a,E,1)});function $v(a,p,E){var I=On(a)?rt:Nc;return E&&Ii(a,p,E)&&(p=i),I(a,cn(p,3))}function Kv(a,p){var E=On(a)?st:Qf;return E(a,cn(p,3))}var Xv=Ld(Qd),D1=Ld($c);function Jv(a,p){return k0(Jc(a,p),1)}function Qv(a,p){return k0(Jc(a,p),Ot)}function ap(a,p,E){return E=E===i?1:jn(E),k0(Jc(a,p),E)}function dp(a,p){var E=On(a)?je:$o;return E(a,cn(p,3))}function pp(a,p){var E=On(a)?Xe:kl;return E(a,cn(p,3))}var Zv=_f(function(a,p,E){or.call(a,E)?a[E].push(p):ti(a,E,[p])});function eg(a,p,E,I){a=Vi(a)?a:Ef(a),E=E&&!I?jn(E):0;var B=a.length;return E<0&&(E=wr(B+E,0)),ia(a)?E<=B&&a.indexOf(p,E)>-1:!!B&&Qe(a,p,E)>-1}var tg=Wn(function(a,p,E){var I=-1,B=typeof p=="function",G=Vi(a)?Ie(a.length):[];return $o(a,function(te){G[++I]=B?K(p,te,E):po(te,p,E)}),G}),hp=_f(function(a,p,E){ti(a,E,p)});function Jc(a,p){var E=On(a)?lt:vd;return E(a,cn(p,3))}function ng(a,p,E,I){return a==null?[]:(On(p)||(p=p==null?[]:[p]),E=I?i:E,On(E)||(E=E==null?[]:[E]),Oi(a,p,E))}var rg=_f(function(a,p,E){a[E?0:1].push(p)},function(){return[[],[]]});function mp(a,p,E){var I=On(a)?yn:bn,B=arguments.length<3;return I(a,cn(p,4),E,B,$o)}function ig(a,p,E){var I=On(a)?sn:bn,B=arguments.length<3;return I(a,cn(p,4),E,B,kl)}function og(a,p){var E=On(a)?st:Qf;return E(a,Zc(cn(p,3)))}function ug(a){var p=On(a)?Fc:wd;return p(a)}function sg(a,p,E){(E?Ii(a,p,E):p===i)?p=1:p=jn(p);var I=On(a)?Lc:Dd;return I(a,p)}function lg(a){var p=On(a)?Kf:Ao;return p(a)}function E1(a){if(a==null)return 0;if(Vi(a))return ia(a)?Rr(a):a.length;var p=U0(a);return p==w||p==r0?a.size:Zf(a).length}function fg(a,p,E){var I=On(a)?ar:Nm;return E&&Ii(a,p,E)&&(p=i),I(a,cn(p,3))}var cg=Wn(function(a,p){if(a==null)return[];var E=p.length;return E>1&&Ii(a,p[0],p[1])?p=[]:E>2&&Ii(p[0],p[1],p[2])&&(p=[p[0]]),Oi(a,k0(p,1),[])}),rc=Sl||function(){return Lr.Date.now()};function ag(a,p){if(typeof p!="function")throw new Yr(g);return a=jn(a),function(){if(--a<1)return p.apply(this,arguments)}}function vp(a,p,E){return p=E?i:p,p=a&&p==null?a.length:p,Lt(a,De,i,i,i,i,p)}function gp(a,p){var E;if(typeof p!="function")throw new Yr(g);return a=jn(a),function(){return--a>0&&(E=p.apply(this,arguments)),a<=1&&(p=i),E}}var S1=Wn(function(a,p,E){var I=h;if(E.length){var B=L0(E,An(S1));I|=Se}return Lt(a,I,p,E,B)}),_p=Wn(function(a,p,E){var I=h|re;if(E.length){var B=L0(E,An(_p));I|=Se}return Lt(p,I,a,E,B)});function C1(a,p,E){p=E?i:p;var I=Lt(a,Q,i,i,i,i,i,p);return I.placeholder=C1.placeholder,I}function yp(a,p,E){p=E?i:p;var I=Lt(a,oe,i,i,i,i,i,p);return I.placeholder=yp.placeholder,I}function wp(a,p,E){var I,B,G,te,se,Ee,$e=0,Ke=!1,nt=!1,Ct=!0;if(typeof a!="function")throw new Yr(g);p=Fo(p)||0,Jr(E)&&(Ke=!!E.leading,nt="maxWait"in E,G=nt?wr(Fo(E.maxWait)||0,p):G,Ct="trailing"in E?!!E.trailing:Ct);function Gt(f0){var Jo=I,Su=B;return I=B=i,$e=f0,te=a.apply(Su,Jo),te}function an(f0){return $e=f0,se=wf(Yn,p),Ke?Gt(f0):te}function qn(f0){var Jo=f0-Ee,Su=f0-$e,Zp=p-Jo;return nt?kn(Zp,G-Su):Zp}function dn(f0){var Jo=f0-Ee,Su=f0-$e;return Ee===i||Jo>=p||Jo<0||nt&&Su>=G}function Yn(){var f0=rc();if(dn(f0))return er(f0);se=wf(Yn,qn(f0))}function er(f0){return se=i,Ct&&I?Gt(f0):(I=B=i,te)}function vo(){se!==i&&Ad(se),$e=0,I=Ee=B=se=i}function Pi(){return se===i?te:er(rc())}function Mi(){var f0=rc(),Jo=dn(f0);if(I=arguments,B=this,Ee=f0,Jo){if(se===i)return an(Ee);if(nt)return Ad(se),se=wf(Yn,p),Gt(Ee)}return se===i&&(se=wf(Yn,p)),te}return Mi.cancel=vo,Mi.flush=Pi,Mi}var dg=Wn(function(a,p){return Jf(a,1,p)}),Dp=Wn(function(a,p,E){return Jf(a,Fo(p)||0,E)});function pg(a){return Lt(a,Te)}function Qc(a,p){if(typeof a!="function"||p!=null&&typeof p!="function")throw new Yr(g);var E=function(){var I=arguments,B=p?p.apply(this,I):I[0],G=E.cache;if(G.has(B))return G.get(B);var te=a.apply(this,I);return E.cache=G.set(B,te)||G,te};return E.cache=new(Qc.Cache||ei),E}Qc.Cache=ei;function Zc(a){if(typeof a!="function")throw new Yr(g);return function(){var p=arguments;switch(p.length){case 0:return!a.call(this);case 1:return!a.call(this,p[0]);case 2:return!a.call(this,p[0],p[1]);case 3:return!a.call(this,p[0],p[1],p[2])}return!a.apply(this,p)}}function ea(a){return gp(2,a)}var hg=Bm(function(a,p){p=p.length==1&&On(p[0])?lt(p[0],qr(cn())):lt(k0(p,1),qr(cn()));var E=p.length;return Wn(function(I){for(var B=-1,G=kn(I.length,E);++B=p}),Ll=_i(function(){return arguments}())?_i:function(a){return n0(a)&&or.call(a,"callee")&&!N0.call(a,"callee")},On=Ie.isArray,x1=ue?qr(ue):Re;function Vi(a){return a!=null&&na(a.length)&&!rs(a)}function l0(a){return n0(a)&&Vi(a)}function kg(a){return a===!0||a===!1||n0(a)&&Ye(a)==jt}var Eu=pi||W1,Ag=de?qr(de):Ce;function Og(a){return n0(a)&&a.nodeType===1&&!ic(a)}function Cp(a){if(a==null)return!0;if(Vi(a)&&(On(a)||typeof a=="string"||typeof a.splice=="function"||Eu(a)||Df(a)||Ll(a)))return!a.length;var p=U0(a);if(p==w||p==r0)return!a.size;if(nc(a))return!Zf(a).length;for(var E in a)if(or.call(a,E))return!1;return!0}function Ig(a,p){return ze(a,p)}function Pg(a,p,E){E=typeof E=="function"?E:i;var I=E?E(a,p):i;return I===i?ze(a,p,i,E):!!I}function k1(a){if(!n0(a))return!1;var p=Ye(a);return p==Jt||p==Un||typeof a.message=="string"&&typeof a.name=="string"&&!ic(a)}function Mg(a){return typeof a=="number"&&Br(a)}function rs(a){if(!Jr(a))return!1;var p=Ye(a);return p==Yt||p==cr||p==Ft||p==vr}function A1(a){return typeof a=="number"&&a==jn(a)}function na(a){return typeof a=="number"&&a>-1&&a%1==0&&a<=Nt}function Jr(a){var p=typeof a;return a!=null&&(p=="object"||p=="function")}function n0(a){return a!=null&&typeof a=="object"}var Tp=W?qr(W):on;function Fg(a,p){return a===p||sr(a,p,Nn(p))}function Lg(a,p,E){return E=typeof E=="function"?E:i,sr(a,p,Nn(p),E)}function Rg(a){return xp(a)&&a!=+a}function Ng(a){if(Zm(a))throw new mt(c);return mn(a)}function Bg(a){return a===null}function O1(a){return a==null}function xp(a){return typeof a=="number"||n0(a)&&Ye(a)==pt}function ic(a){if(!n0(a)||Ye(a)!=Bn)return!1;var p=uo(a);if(p===null)return!0;var E=or.call(p,"constructor")&&p.constructor;return typeof E=="function"&&E instanceof E&&bi.call(E)==af}var ra=ve?qr(ve):pr;function jg(a){return A1(a)&&a>=-Nt&&a<=Nt}var kp=Fe?qr(Fe):Hr;function ia(a){return typeof a=="string"||!On(a)&&n0(a)&&Ye(a)==Ci}function mo(a){return typeof a=="symbol"||n0(a)&&Ye(a)==yo}var Df=Ge?qr(Ge):Vn;function Ap(a){return a===i}function Ug(a){return n0(a)&&U0(a)==Mu}function qg(a){return n0(a)&&Ye(a)==Gf}var zg=bc(Ha),Wg=bc(function(a,p){return a<=p});function Op(a){if(!a)return[];if(Vi(a))return ia(a)?Jn(a):Xr(a);if(u0&&a[u0])return F0(a[u0]());var p=U0(a),E=p==w?Gr:p==r0?Y0:Ef;return E(a)}function is(a){if(!a)return a===0?a:0;if(a=Fo(a),a===Ot||a===-Ot){var p=a<0?-1:1;return p*Je}return a===a?a:0}function jn(a){var p=is(a),E=p%1;return p===p?E?p-E:p:0}function Ip(a){return a?mi(jn(a),0,ne):0}function Fo(a){if(typeof a=="number")return a;if(mo(a))return V;if(Jr(a)){var p=typeof a.valueOf=="function"?a.valueOf():a;a=Jr(p)?p+"":p}if(typeof a!="string")return a===0?a:+a;a=E0(a);var E=zo.test(a);return E||Is.test(a)?Vu(a.slice(2),E?2:8):wo.test(a)?V:+a}function oa(a){return yi(a,Yi(a))}function Hg(a){return a?mi(jn(a),-Nt,Nt):a===0?a:0}function yr(a){return a==null?"":ho(a)}var Pp=Io(function(a,p){if(nc(p)||Vi(p)){yi(p,q0(p),a);return}for(var E in p)or.call(p,E)&&xl(a,E,p[E])}),Mp=Io(function(a,p){yi(p,Yi(p),a)}),ua=Io(function(a,p,E,I){yi(p,Yi(p),a,I)}),bg=Io(function(a,p,E,I){yi(p,q0(p),a,I)}),Gg=yu(Hs);function Vg(a,p){var E=dr(a);return p==null?E:mf(E,p)}var Fp=Wn(function(a,p){a=$t(a);var E=-1,I=p.length,B=I>2?p[2]:i;for(B&&Ii(p[0],p[1],B)&&(I=1);++E1),G}),yi(a,Dn(a),E),I&&(E=vi(E,D|L|N,Gm));for(var B=p.length;B--;)$a(E,p[B]);return E});function l_(a,p){return Bp(a,Zc(cn(p)))}var f_=yu(function(a,p){return a==null?{}:Fm(a,p)});function Bp(a,p){if(a==null)return{};var E=lt(Dn(a),function(I){return[I]});return p=cn(p),yd(a,E,function(I,B){return p(I,B[0])})}function c_(a,p,E){p=Gs(p,a);var I=-1,B=p.length;for(B||(B=1,a=i);++Ip){var I=a;a=p,p=I}if(E||a%1||p%1){var B=Ai();return kn(a+B*(p-a+Bs("1e-"+((B+"").length-1))),p)}return Ga(a,p)}var __=yf(function(a,p,E){return p=p.toLowerCase(),a+(E?Wp(p):p)});function Wp(a){return L1(yr(a).toLowerCase())}function Hp(a){return a=yr(a),a&&a.replace(_n,du).replace(V0,"")}function y_(a,p,E){a=yr(a),p=ho(p);var I=a.length;E=E===i?I:mi(jn(E),0,I);var B=E;return E-=p.length,E>=0&&a.slice(E,B)==p}function M1(a){return a=yr(a),a&&Ac.test(a)?a.replace(Ui,Yu):a}function w_(a){return a=yr(a),a&&Fr.test(a)?a.replace(kr,"\\$&"):a}var D_=yf(function(a,p,E){return a+(E?"-":"")+p.toLowerCase()}),bp=yf(function(a,p,E){return a+(E?" ":"")+p.toLowerCase()}),E_=Fd("toLowerCase");function S_(a,p,E){a=yr(a),p=jn(p);var I=p?Rr(a):0;if(!p||I>=p)return a;var B=(p-I)/2;return Hc(hu(B),E)+a+Hc(B0(B),E)}function C_(a,p,E){a=yr(a),p=jn(p);var I=p?Rr(a):0;return p&&I>>0,E?(a=yr(a),a&&(typeof p=="string"||p!=null&&!ra(p))&&(p=ho(p),!p&&Hi(a))?Vs(Jn(a),0,E):a.split(p,E)):[]}var I_=yf(function(a,p,E){return a+(E?" ":"")+L1(p)});function P_(a,p,E){return a=yr(a),E=E==null?0:mi(jn(E),0,a.length),p=ho(p),a.slice(E,E+p.length)==p}function M_(a,p,E){var I=z.templateSettings;E&&Ii(a,p,E)&&(p=i),a=yr(a),p=ua({},p,I,n1);var B=ua({},p.imports,I.imports,n1),G=q0(B),te=Eo(B,G),se,Ee,$e=0,Ke=p.interpolate||Nu,nt="__p += '",Ct=X0((p.escape||Nu).source+"|"+Ke.source+"|"+(Ke===xs?As:Nu).source+"|"+(p.evaluate||Nu).source+"|$","g"),Gt="//# sourceURL="+(or.call(p,"sourceURL")?(p.sourceURL+"").replace(/\s/g," "):"lodash.templateSources["+ ++lf+"]")+` +`;a.replace(Ct,function(dn,Yn,er,vo,Pi,Mi){return er||(er=vo),nt+=a.slice($e,Mi).replace(Wo,Us),Yn&&(se=!0,nt+=`' + +__e(`+Yn+`) + +'`),Pi&&(Ee=!0,nt+=`'; +`+Pi+`; +__p += '`),er&&(nt+=`' + +((__t = (`+er+`)) == null ? '' : __t) + +'`),$e=Mi+dn.length,dn}),nt+=`'; +`;var an=or.call(p,"variable")&&p.variable;if(!an)nt=`with (obj) { +`+nt+` +} +`;else if(Ru.test(an))throw new mt(t);nt=(Ee?nt.replace(ll,""):nt).replace(fl,"$1").replace(cl,"$1;"),nt="function("+(an||"obj")+`) { +`+(an?"":`obj || (obj = {}); +`)+"var __t, __p = ''"+(se?", __e = _.escape":"")+(Ee?`, __j = Array.prototype.join; +function print() { __p += __j.call(arguments, '') } +`:`; +`)+nt+`return __p +}`;var qn=$p(function(){return wn(G,Gt+"return "+nt).apply(i,te)});if(qn.source=nt,k1(qn))throw qn;return qn}function F_(a){return yr(a).toLowerCase()}function L_(a){return yr(a).toUpperCase()}function R_(a,p,E){if(a=yr(a),a&&(E||p===i))return E0(a);if(!a||!(p=ho(p)))return a;var I=Jn(a),B=Jn(p),G=wl(I,B),te=js(I,B)+1;return Vs(I,G,te).join("")}function F1(a,p,E){if(a=yr(a),a&&(E||p===i))return a.slice(0,ai(a)+1);if(!a||!(p=ho(p)))return a;var I=Jn(a),B=js(I,Jn(p))+1;return Vs(I,0,B).join("")}function N_(a,p,E){if(a=yr(a),a&&(E||p===i))return a.replace(si,"");if(!a||!(p=ho(p)))return a;var I=Jn(a),B=wl(I,Jn(p));return Vs(I,B).join("")}function B_(a,p){var E=Oe,I=Le;if(Jr(p)){var B="separator"in p?p.separator:B;E="length"in p?jn(p.length):E,I="omission"in p?ho(p.omission):I}a=yr(a);var G=a.length;if(Hi(a)){var te=Jn(a);G=te.length}if(E>=G)return a;var se=E-Rr(I);if(se<1)return I;var Ee=te?Vs(te,0,se).join(""):a.slice(0,se);if(B===i)return Ee+I;if(te&&(se+=Ee.length-se),ra(B)){if(a.slice(se).search(B)){var $e,Ke=Ee;for(B.global||(B=X0(B.source,yr(uu.exec(B))+"g")),B.lastIndex=0;$e=B.exec(Ke);)var nt=$e.index;Ee=Ee.slice(0,nt===i?se:nt)}}else if(a.indexOf(ho(B),se)!=se){var Ct=Ee.lastIndexOf(B);Ct>-1&&(Ee=Ee.slice(0,Ct))}return Ee+I}function Vp(a){return a=yr(a),a&&Mr.test(a)?a.replace(al,o0):a}var j_=yf(function(a,p,E){return a+(E?" ":"")+p.toUpperCase()}),L1=Fd("toUpperCase");function Yp(a,p,E){return a=yr(a),p=E?i:p,p===i?qs(a)?cf(a):d0(a):a.match(p)||[]}var $p=Wn(function(a,p){try{return K(a,i,p)}catch(E){return k1(E)?E:new mt(E)}}),U_=yu(function(a,p){return je(p,function(E){E=Xo(E),ti(a,E,S1(a[E],a))}),a});function Kp(a){var p=a==null?0:a.length,E=cn();return a=p?lt(a,function(I){if(typeof I[1]!="function")throw new Yr(g);return[E(I[0]),I[1]]}):[],Wn(function(I){for(var B=-1;++BNt)return[];var E=ne,I=kn(a,ne);p=cn(p),a-=ne;for(var B=ci(I,p);++E0||p<0)?new nn(E):(a<0?E=E.takeRight(-a):a&&(E=E.drop(a)),p!==i&&(p=jn(p),E=p<0?E.dropRight(-p):E.take(p-a)),E)},nn.prototype.takeRightWhile=function(a){return this.reverse().takeWhile(a).reverse()},nn.prototype.toArray=function(){return this.take(ne)},S(nn.prototype,function(a,p){var E=/^(?:filter|find|map|reject)|While$/.test(p),I=/^(?:head|last)$/.test(p),B=z[I?"take"+(p=="last"?"Right":""):p],G=I||/^find/.test(p);!B||(z.prototype[p]=function(){var te=this.__wrapped__,se=I?[1]:arguments,Ee=te instanceof nn,$e=se[0],Ke=Ee||On(te),nt=function(Yn){var er=B.apply(z,Rt([Yn],se));return I&&Ct?er[0]:er};Ke&&E&&typeof $e=="function"&&$e.length!=1&&(Ee=Ke=!1);var Ct=this.__chain__,Gt=!!this.__actions__.length,an=G&&!Ct,qn=Ee&&!Gt;if(!G&&Ke){te=qn?te:new nn(this);var dn=a.apply(te,se);return dn.__actions__.push({func:Kc,args:[nt],thisArg:i}),new Qn(dn,Ct)}return an&&qn?a.apply(this,se):(dn=this.thru(nt),an?I?dn.value()[0]:dn.value():dn)})}),je(["pop","push","shift","sort","splice","unshift"],function(a){var p=$r[a],E=/^(?:push|sort|unshift)$/.test(a)?"tap":"thru",I=/^(?:pop|shift)$/.test(a);z.prototype[a]=function(){var B=arguments;if(I&&!this.__chain__){var G=this.value();return p.apply(On(G)?G:[],B)}return this[E](function(te){return p.apply(On(te)?te:[],B)})}}),S(nn.prototype,function(a,p){var E=z[p];if(E){var I=E.name+"";or.call(bt,I)||(bt[I]=[]),bt[I].push({name:p,func:E})}}),bt[zc(i,re).name]=[{name:"wrapper",func:i}],nn.prototype.clone=s0,nn.prototype.reverse=t0,nn.prototype.value=g0,z.prototype.at=Wv,z.prototype.chain=Hv,z.prototype.commit=bv,z.prototype.next=Gv,z.prototype.plant=Yv,z.prototype.reverse=Ml,z.prototype.toJSON=z.prototype.valueOf=z.prototype.value=Fl,z.prototype.first=z.prototype.head,u0&&(z.prototype[u0]=Vv),z},K0=$0();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Lr._=K0,define(function(){return K0})):R?((R.exports=K0)._=K0,F._=K0):Lr._=K0}).call(ga)});var ay=Me((XH,cy)=>{"use strict";var fr=cy.exports;cy.exports.default=fr;var Pr="[",t2="]",ya="\x07",vh=";",OD=process.env.TERM_PROGRAM==="Apple_Terminal";fr.cursorTo=(i,u)=>{if(typeof i!="number")throw new TypeError("The `x` argument is required");return typeof u!="number"?Pr+(i+1)+"G":Pr+(u+1)+";"+(i+1)+"H"};fr.cursorMove=(i,u)=>{if(typeof i!="number")throw new TypeError("The `x` argument is required");let f="";return i<0?f+=Pr+-i+"D":i>0&&(f+=Pr+i+"C"),u<0?f+=Pr+-u+"A":u>0&&(f+=Pr+u+"B"),f};fr.cursorUp=(i=1)=>Pr+i+"A";fr.cursorDown=(i=1)=>Pr+i+"B";fr.cursorForward=(i=1)=>Pr+i+"C";fr.cursorBackward=(i=1)=>Pr+i+"D";fr.cursorLeft=Pr+"G";fr.cursorSavePosition=OD?"7":Pr+"s";fr.cursorRestorePosition=OD?"8":Pr+"u";fr.cursorGetPosition=Pr+"6n";fr.cursorNextLine=Pr+"E";fr.cursorPrevLine=Pr+"F";fr.cursorHide=Pr+"?25l";fr.cursorShow=Pr+"?25h";fr.eraseLines=i=>{let u="";for(let f=0;f[t2,"8",vh,vh,u,ya,i,t2,"8",vh,vh,ya].join("");fr.image=(i,u={})=>{let f=`${t2}1337;File=inline=1`;return u.width&&(f+=`;width=${u.width}`),u.height&&(f+=`;height=${u.height}`),u.preserveAspectRatio===!1&&(f+=";preserveAspectRatio=0"),f+":"+i.toString("base64")+ya};fr.iTerm={setCwd:(i=process.cwd())=>`${t2}50;CurrentDir=${i}${ya}`,annotation:(i,u={})=>{let f=`${t2}1337;`,c=typeof u.x!="undefined",g=typeof u.y!="undefined";if((c||g)&&!(c&&g&&typeof u.length!="undefined"))throw new Error("`x`, `y` and `length` must be defined when `x` or `y` is defined");return i=i.replace(/\|/g,""),f+=u.isHidden?"AddHiddenAnnotation=":"AddAnnotation=",u.length>0?f+=(c?[i,u.length,u.x,u.y]:[u.length,i]).join("|"):f+=i,f+ya}}});var PD=Me((JH,dy)=>{"use strict";var ID=(i,u)=>{for(let f of Reflect.ownKeys(u))Object.defineProperty(i,f,Object.getOwnPropertyDescriptor(u,f));return i};dy.exports=ID;dy.exports.default=ID});var FD=Me((QH,gh)=>{"use strict";var oN=PD(),_h=new WeakMap,MD=(i,u={})=>{if(typeof i!="function")throw new TypeError("Expected a function");let f,c=!1,g=0,t=i.displayName||i.name||"",C=function(...A){if(_h.set(C,++g),c){if(u.throw===!0)throw new Error(`Function \`${t}\` can only be called once`);return f}return c=!0,f=i.apply(this,A),i=null,f};return oN(C,i),_h.set(C,g),C};gh.exports=MD;gh.exports.default=MD;gh.exports.callCount=i=>{if(!_h.has(i))throw new Error(`The given function \`${i.name}\` is not wrapped by the \`onetime\` package`);return _h.get(i)}});var LD=Me((ZH,yh)=>{yh.exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"];process.platform!=="win32"&&yh.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT");process.platform==="linux"&&yh.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")});var vy=Me((eb,n2)=>{var uN=require("assert"),r2=LD(),sN=/^win/i.test(process.platform),wh=require("events");typeof wh!="function"&&(wh=wh.EventEmitter);var Bi;process.__signal_exit_emitter__?Bi=process.__signal_exit_emitter__:(Bi=process.__signal_exit_emitter__=new wh,Bi.count=0,Bi.emitted={});Bi.infinite||(Bi.setMaxListeners(Infinity),Bi.infinite=!0);n2.exports=function(i,u){uN.equal(typeof i,"function","a callback must be provided for exit handler"),i2===!1&&RD();var f="exit";u&&u.alwaysLast&&(f="afterexit");var c=function(){Bi.removeListener(f,i),Bi.listeners("exit").length===0&&Bi.listeners("afterexit").length===0&&py()};return Bi.on(f,i),c};n2.exports.unload=py;function py(){!i2||(i2=!1,r2.forEach(function(i){try{process.removeListener(i,hy[i])}catch(u){}}),process.emit=my,process.reallyExit=ND,Bi.count-=1)}function wa(i,u,f){Bi.emitted[i]||(Bi.emitted[i]=!0,Bi.emit(i,u,f))}var hy={};r2.forEach(function(i){hy[i]=function(){var f=process.listeners(i);f.length===Bi.count&&(py(),wa("exit",null,i),wa("afterexit",null,i),sN&&i==="SIGHUP"&&(i="SIGINT"),process.kill(process.pid,i))}});n2.exports.signals=function(){return r2};n2.exports.load=RD;var i2=!1;function RD(){i2||(i2=!0,Bi.count+=1,r2=r2.filter(function(i){try{return process.on(i,hy[i]),!0}catch(u){return!1}}),process.emit=fN,process.reallyExit=lN)}var ND=process.reallyExit;function lN(i){process.exitCode=i||0,wa("exit",process.exitCode,null),wa("afterexit",process.exitCode,null),ND.call(process,process.exitCode)}var my=process.emit;function fN(i,u){if(i==="exit"){u!==void 0&&(process.exitCode=u);var f=my.apply(this,arguments);return wa("exit",process.exitCode,null),wa("afterexit",process.exitCode,null),f}else return my.apply(this,arguments)}});var jD=Me((tb,BD)=>{"use strict";var cN=FD(),aN=vy();BD.exports=cN(()=>{aN(()=>{process.stderr.write("[?25h")},{alwaysLast:!0})})});var gy=Me(Da=>{"use strict";var dN=jD(),Dh=!1;Da.show=(i=process.stderr)=>{!i.isTTY||(Dh=!1,i.write("[?25h"))};Da.hide=(i=process.stderr)=>{!i.isTTY||(dN(),Dh=!0,i.write("[?25l"))};Da.toggle=(i,u)=>{i!==void 0&&(Dh=i),Dh?Da.show(u):Da.hide(u)}});var WD=Me(o2=>{"use strict";var UD=o2&&o2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(o2,"__esModule",{value:!0});var qD=UD(ay()),zD=UD(gy()),pN=(i,{showCursor:u=!1}={})=>{let f=0,c="",g=!1,t=C=>{!u&&!g&&(zD.default.hide(),g=!0);let A=C+` +`;A!==c&&(c=A,i.write(qD.default.eraseLines(f)+A),f=A.split(` +`).length)};return t.clear=()=>{i.write(qD.default.eraseLines(f)),c="",f=0},t.done=()=>{c="",f=0,u||(zD.default.show(),g=!1)},t};o2.default={create:pN}});var bD=Me((ib,HD)=>{HD.exports=[{name:"AppVeyor",constant:"APPVEYOR",env:"APPVEYOR",pr:"APPVEYOR_PULL_REQUEST_NUMBER"},{name:"Azure Pipelines",constant:"AZURE_PIPELINES",env:"SYSTEM_TEAMFOUNDATIONCOLLECTIONURI",pr:"SYSTEM_PULLREQUEST_PULLREQUESTID"},{name:"Bamboo",constant:"BAMBOO",env:"bamboo_planKey"},{name:"Bitbucket Pipelines",constant:"BITBUCKET",env:"BITBUCKET_COMMIT",pr:"BITBUCKET_PR_ID"},{name:"Bitrise",constant:"BITRISE",env:"BITRISE_IO",pr:"BITRISE_PULL_REQUEST"},{name:"Buddy",constant:"BUDDY",env:"BUDDY_WORKSPACE_ID",pr:"BUDDY_EXECUTION_PULL_REQUEST_ID"},{name:"Buildkite",constant:"BUILDKITE",env:"BUILDKITE",pr:{env:"BUILDKITE_PULL_REQUEST",ne:"false"}},{name:"CircleCI",constant:"CIRCLE",env:"CIRCLECI",pr:"CIRCLE_PULL_REQUEST"},{name:"Cirrus CI",constant:"CIRRUS",env:"CIRRUS_CI",pr:"CIRRUS_PR"},{name:"AWS CodeBuild",constant:"CODEBUILD",env:"CODEBUILD_BUILD_ARN"},{name:"Codeship",constant:"CODESHIP",env:{CI_NAME:"codeship"}},{name:"Drone",constant:"DRONE",env:"DRONE",pr:{DRONE_BUILD_EVENT:"pull_request"}},{name:"dsari",constant:"DSARI",env:"DSARI"},{name:"GitLab CI",constant:"GITLAB",env:"GITLAB_CI"},{name:"GoCD",constant:"GOCD",env:"GO_PIPELINE_LABEL"},{name:"Hudson",constant:"HUDSON",env:"HUDSON_URL"},{name:"Jenkins",constant:"JENKINS",env:["JENKINS_URL","BUILD_ID"],pr:{any:["ghprbPullId","CHANGE_ID"]}},{name:"Magnum CI",constant:"MAGNUM",env:"MAGNUM"},{name:"Netlify CI",constant:"NETLIFY",env:"NETLIFY_BUILD_BASE",pr:{env:"PULL_REQUEST",ne:"false"}},{name:"Sail CI",constant:"SAIL",env:"SAILCI",pr:"SAIL_PULL_REQUEST_NUMBER"},{name:"Semaphore",constant:"SEMAPHORE",env:"SEMAPHORE",pr:"PULL_REQUEST_NUMBER"},{name:"Shippable",constant:"SHIPPABLE",env:"SHIPPABLE",pr:{IS_PULL_REQUEST:"true"}},{name:"Solano CI",constant:"SOLANO",env:"TDDIUM",pr:"TDDIUM_PR_ID"},{name:"Strider CD",constant:"STRIDER",env:"STRIDER"},{name:"TaskCluster",constant:"TASKCLUSTER",env:["TASK_ID","RUN_ID"]},{name:"TeamCity",constant:"TEAMCITY",env:"TEAMCITY_VERSION"},{name:"Travis CI",constant:"TRAVIS",env:"TRAVIS",pr:{env:"TRAVIS_PULL_REQUEST",ne:"false"}}]});var YD=Me(ru=>{"use strict";var GD=bD(),nl=process.env;Object.defineProperty(ru,"_vendors",{value:GD.map(function(i){return i.constant})});ru.name=null;ru.isPR=null;GD.forEach(function(i){var u=Array.isArray(i.env)?i.env:[i.env],f=u.every(function(c){return VD(c)});if(ru[i.constant]=f,f)switch(ru.name=i.name,typeof i.pr){case"string":ru.isPR=!!nl[i.pr];break;case"object":"env"in i.pr?ru.isPR=i.pr.env in nl&&nl[i.pr.env]!==i.pr.ne:"any"in i.pr?ru.isPR=i.pr.any.some(function(c){return!!nl[c]}):ru.isPR=VD(i.pr);break;default:ru.isPR=null}});ru.isCI=!!(nl.CI||nl.CONTINUOUS_INTEGRATION||nl.BUILD_NUMBER||nl.RUN_ID||ru.name);function VD(i){return typeof i=="string"?!!nl[i]:Object.keys(i).every(function(u){return nl[u]===i[u]})}});var KD=Me((ub,$D)=>{"use strict";$D.exports=YD().isCI});var JD=Me((sb,XD)=>{"use strict";var hN=i=>{let u=new Set;do for(let f of Reflect.ownKeys(i))u.add([i,f]);while((i=Reflect.getPrototypeOf(i))&&i!==Object.prototype);return u};XD.exports=(i,{include:u,exclude:f}={})=>{let c=g=>{let t=C=>typeof C=="string"?g===C:C.test(g);return u?u.some(t):f?!f.some(t):!0};for(let[g,t]of hN(i.constructor.prototype)){if(t==="constructor"||!c(t))continue;let C=Reflect.getOwnPropertyDescriptor(g,t);C&&typeof C.value=="function"&&(i[t]=i[t].bind(i))}return i}});var iE=Me(Sr=>{"use strict";Object.defineProperty(Sr,"__esModule",{value:!0});var Ea,u2,Eh,Sh,_y;typeof window=="undefined"||typeof MessageChannel!="function"?(Sa=null,yy=null,wy=function(){if(Sa!==null)try{var i=Sr.unstable_now();Sa(!0,i),Sa=null}catch(u){throw setTimeout(wy,0),u}},QD=Date.now(),Sr.unstable_now=function(){return Date.now()-QD},Ea=function(i){Sa!==null?setTimeout(Ea,0,i):(Sa=i,setTimeout(wy,0))},u2=function(i,u){yy=setTimeout(i,u)},Eh=function(){clearTimeout(yy)},Sh=function(){return!1},_y=Sr.unstable_forceFrameRate=function(){}):(Ch=window.performance,Dy=window.Date,ZD=window.setTimeout,eE=window.clearTimeout,typeof console!="undefined"&&(tE=window.cancelAnimationFrame,typeof window.requestAnimationFrame!="function"&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),typeof tE!="function"&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")),typeof Ch=="object"&&typeof Ch.now=="function"?Sr.unstable_now=function(){return Ch.now()}:(nE=Dy.now(),Sr.unstable_now=function(){return Dy.now()-nE}),s2=!1,l2=null,Th=-1,Ey=5,Sy=0,Sh=function(){return Sr.unstable_now()>=Sy},_y=function(){},Sr.unstable_forceFrameRate=function(i){0>i||125kh(C,f))x!==void 0&&0>kh(x,C)?(i[c]=x,i[A]=f,c=A):(i[c]=C,i[t]=f,c=t);else if(x!==void 0&&0>kh(x,f))i[c]=x,i[A]=f,c=A;else break e}}return u}return null}function kh(i,u){var f=i.sortIndex-u.sortIndex;return f!==0?f:i.id-u.id}var ds=[],Nf=[],mN=1,_o=null,to=3,Oh=!1,pc=!1,f2=!1;function Ih(i){for(var u=Iu(Nf);u!==null;){if(u.callback===null)Ah(Nf);else if(u.startTime<=i)Ah(Nf),u.sortIndex=u.expirationTime,Ty(ds,u);else break;u=Iu(Nf)}}function xy(i){if(f2=!1,Ih(i),!pc)if(Iu(ds)!==null)pc=!0,Ea(ky);else{var u=Iu(Nf);u!==null&&u2(xy,u.startTime-i)}}function ky(i,u){pc=!1,f2&&(f2=!1,Eh()),Oh=!0;var f=to;try{for(Ih(u),_o=Iu(ds);_o!==null&&(!(_o.expirationTime>u)||i&&!Sh());){var c=_o.callback;if(c!==null){_o.callback=null,to=_o.priorityLevel;var g=c(_o.expirationTime<=u);u=Sr.unstable_now(),typeof g=="function"?_o.callback=g:_o===Iu(ds)&&Ah(ds),Ih(u)}else Ah(ds);_o=Iu(ds)}if(_o!==null)var t=!0;else{var C=Iu(Nf);C!==null&&u2(xy,C.startTime-u),t=!1}return t}finally{_o=null,to=f,Oh=!1}}function rE(i){switch(i){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var vN=_y;Sr.unstable_ImmediatePriority=1;Sr.unstable_UserBlockingPriority=2;Sr.unstable_NormalPriority=3;Sr.unstable_IdlePriority=5;Sr.unstable_LowPriority=4;Sr.unstable_runWithPriority=function(i,u){switch(i){case 1:case 2:case 3:case 4:case 5:break;default:i=3}var f=to;to=i;try{return u()}finally{to=f}};Sr.unstable_next=function(i){switch(to){case 1:case 2:case 3:var u=3;break;default:u=to}var f=to;to=u;try{return i()}finally{to=f}};Sr.unstable_scheduleCallback=function(i,u,f){var c=Sr.unstable_now();if(typeof f=="object"&&f!==null){var g=f.delay;g=typeof g=="number"&&0c?(i.sortIndex=g,Ty(Nf,i),Iu(ds)===null&&i===Iu(Nf)&&(f2?Eh():f2=!0,u2(xy,g-c))):(i.sortIndex=f,Ty(ds,i),pc||Oh||(pc=!0,Ea(ky))),i};Sr.unstable_cancelCallback=function(i){i.callback=null};Sr.unstable_wrapCallback=function(i){var u=to;return function(){var f=to;to=u;try{return i.apply(this,arguments)}finally{to=f}}};Sr.unstable_getCurrentPriorityLevel=function(){return to};Sr.unstable_shouldYield=function(){var i=Sr.unstable_now();Ih(i);var u=Iu(ds);return u!==_o&&_o!==null&&u!==null&&u.callback!==null&&u.startTime<=i&&u.expirationTime<_o.expirationTime||Sh()};Sr.unstable_requestPaint=vN;Sr.unstable_continueExecution=function(){pc||Oh||(pc=!0,Ea(ky))};Sr.unstable_pauseExecution=function(){};Sr.unstable_getFirstCallbackNode=function(){return Iu(ds)};Sr.unstable_Profiling=null});var Ay=Me((fb,oE)=>{"use strict";oE.exports=iE()});var uE=Me((cb,c2)=>{c2.exports=function i(u){"use strict";var f=ey(),c=lr(),g=Ay();function t(v){for(var m="https://reactjs.org/docs/error-decoder.html?invariant="+v,S=1;Sqo||(v.current=qi[qo],qi[qo]=null,qo--)}function Fr(v,m){qo++,qi[qo]=v.current,v.current=m}var si={},H0={current:si},b0={current:!1},Bt=si;function Lu(v,m){var S=v.type.contextTypes;if(!S)return si;var O=v.stateNode;if(O&&O.__reactInternalMemoizedUnmaskedChildContext===m)return O.__reactInternalMemoizedMaskedChildContext;var M={},b;for(b in S)M[b]=m[b];return O&&(v=v.stateNode,v.__reactInternalMemoizedUnmaskedChildContext=m,v.__reactInternalMemoizedMaskedChildContext=M),M}function c0(v){return v=v.childContextTypes,v!=null}function Ru(v){kr(b0,v),kr(H0,v)}function ks(v){kr(b0,v),kr(H0,v)}function As(v,m,S){if(H0.current!==si)throw Error(t(168));Fr(H0,m,v),Fr(b0,S,v)}function uu(v,m,S){var O=v.stateNode;if(v=m.childContextTypes,typeof O.getChildContext!="function")return S;O=O.getChildContext();for(var M in O)if(!(M in v))throw Error(t(108,Oe(m)||"Unknown",M));return f({},S,{},O)}function wo(v){var m=v.stateNode;return m=m&&m.__reactInternalMemoizedMergedChildContext||si,Bt=H0.current,Fr(H0,m,v),Fr(b0,b0.current,v),!0}function zo(v,m,S){var O=v.stateNode;if(!O)throw Error(t(169));S?(m=uu(v,m,Bt),O.__reactInternalMemoizedMergedChildContext=m,kr(b0,v),kr(H0,v),Fr(H0,m,v)):kr(b0,v),Fr(b0,S,v)}var Os=g.unstable_runWithPriority,Is=g.unstable_scheduleCallback,uf=g.unstable_cancelCallback,_n=g.unstable_shouldYield,Nu=g.unstable_requestPaint,Wo=g.unstable_now,su=g.unstable_getCurrentPriorityLevel,Ps=g.unstable_ImmediatePriority,pl=g.unstable_UserBlockingPriority,Vf=g.unstable_NormalPriority,hl=g.unstable_LowPriority,Bu=g.unstable_IdlePriority,ju={},sf=Nu!==void 0?Nu:function(){},ro=null,Ms=null,ml=!1,Uu=Wo(),G0=1e4>Uu?Wo:function(){return Wo()-Uu};function Fs(){switch(su()){case Ps:return 99;case pl:return 98;case Vf:return 97;case hl:return 96;case Bu:return 95;default:throw Error(t(332))}}function tt(v){switch(v){case 99:return Ps;case 98:return pl;case 97:return Vf;case 96:return hl;case 95:return Bu;default:throw Error(t(332))}}function zi(v,m){return v=tt(v),Os(v,m)}function lu(v,m,S){return v=tt(v),Is(v,m,S)}function Ho(v){return ro===null?(ro=[v],Ms=Is(Ps,vl)):ro.push(v),ju}function O0(){if(Ms!==null){var v=Ms;Ms=null,uf(v)}vl()}function vl(){if(!ml&&ro!==null){ml=!0;var v=0;try{var m=ro;zi(99,function(){for(;v=m&&(ai=!0),v.firstContext=null)}function D0(v,m){if(zu!==v&&m!==!1&&m!==0)if((typeof m!="number"||m===1073741823)&&(zu=v,m=1073741823),m={context:v,observedBits:m,next:null},Wi===null){if(qu===null)throw Error(t(308));Wi=m,qu.dependencies={expirationTime:0,firstContext:m,responders:null}}else Wi=Wi.next=m;return Jt?v._currentValue:v._currentValue2}var Do=!1;function i0(v){return{baseState:v,firstUpdate:null,lastUpdate:null,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function Rs(v){return{baseState:v.baseState,firstUpdate:v.firstUpdate,lastUpdate:v.lastUpdate,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function a0(v,m){return{expirationTime:v,suspenseConfig:m,tag:0,payload:null,callback:null,next:null,nextEffect:null}}function Hu(v,m){v.lastUpdate===null?v.firstUpdate=v.lastUpdate=m:(v.lastUpdate.next=m,v.lastUpdate=m)}function V0(v,m){var S=v.alternate;if(S===null){var O=v.updateQueue,M=null;O===null&&(O=v.updateQueue=i0(v.memoizedState))}else O=v.updateQueue,M=S.updateQueue,O===null?M===null?(O=v.updateQueue=i0(v.memoizedState),M=S.updateQueue=i0(S.memoizedState)):O=v.updateQueue=Rs(M):M===null&&(M=S.updateQueue=Rs(O));M===null||O===M?Hu(O,m):O.lastUpdate===null||M.lastUpdate===null?(Hu(O,m),Hu(M,m)):(Hu(O,m),M.lastUpdate=m)}function bu(v,m){var S=v.updateQueue;S=S===null?v.updateQueue=i0(v.memoizedState):Ns(v,S),S.lastCapturedUpdate===null?S.firstCapturedUpdate=S.lastCapturedUpdate=m:(S.lastCapturedUpdate.next=m,S.lastCapturedUpdate=m)}function Ns(v,m){var S=v.alternate;return S!==null&&m===S.updateQueue&&(m=v.updateQueue=Rs(m)),m}function bo(v,m,S,O,M,b){switch(S.tag){case 1:return v=S.payload,typeof v=="function"?v.call(b,O,M):v;case 3:v.effectTag=v.effectTag&-4097|64;case 0:if(v=S.payload,M=typeof v=="function"?v.call(b,O,M):v,M==null)break;return f({},O,M);case 2:Do=!0}return O}function P0(v,m,S,O,M){Do=!1,m=Ns(v,m);for(var b=m.baseState,ee=null,Ye=0,Ze=m.firstUpdate,ut=b;Ze!==null;){var In=Ze.expirationTime;Inpr?(Hr=mn,mn=null):Hr=mn.sibling;var Vn=jr(Re,mn,ze[pr],Et);if(Vn===null){mn===null&&(mn=Hr);break}v&&mn&&Vn.alternate===null&&m(Re,mn),Ce=b(Vn,Ce,pr),sr===null?on=Vn:sr.sibling=Vn,sr=Vn,mn=Hr}if(pr===ze.length)return S(Re,mn),on;if(mn===null){for(;prpr?(Hr=mn,mn=null):Hr=mn.sibling;var ni=jr(Re,mn,Vn.value,Et);if(ni===null){mn===null&&(mn=Hr);break}v&&mn&&ni.alternate===null&&m(Re,mn),Ce=b(ni,Ce,pr),sr===null?on=ni:sr.sibling=ni,sr=ni,mn=Hr}if(Vn.done)return S(Re,mn),on;if(mn===null){for(;!Vn.done;pr++,Vn=ze.next())Vn=A0(Re,Vn.value,Et),Vn!==null&&(Ce=b(Vn,Ce,pr),sr===null?on=Vn:sr.sibling=Vn,sr=Vn);return on}for(mn=O(Re,mn);!Vn.done;pr++,Vn=ze.next())Vn=gi(mn,Re,pr,Vn.value,Et),Vn!==null&&(v&&Vn.alternate!==null&&mn.delete(Vn.key===null?pr:Vn.key),Ce=b(Vn,Ce,pr),sr===null?on=Vn:sr.sibling=Vn,sr=Vn);return v&&mn.forEach(function(Zf){return m(Re,Zf)}),on}return function(Re,Ce,ze,Et){var on=typeof ze=="object"&&ze!==null&&ze.type===L&&ze.key===null;on&&(ze=ze.props.children);var sr=typeof ze=="object"&&ze!==null;if(sr)switch(ze.$$typeof){case x:e:{for(sr=ze.key,on=Ce;on!==null;){if(on.key===sr)if(on.tag===7?ze.type===L:on.elementType===ze.type){S(Re,on.sibling),Ce=M(on,ze.type===L?ze.props.children:ze.props,Et),Ce.ref=au(Re,on,ze),Ce.return=Re,Re=Ce;break e}else{S(Re,on);break}else m(Re,on);on=on.sibling}ze.type===L?(Ce=mi(ze.props.children,Re.mode,Et,ze.key),Ce.return=Re,Re=Ce):(Et=Hs(ze.type,ze.key,ze.props,null,Re.mode,Et),Et.ref=au(Re,Ce,ze),Et.return=Re,Re=Et)}return ee(Re);case D:e:{for(on=ze.key;Ce!==null;){if(Ce.key===on)if(Ce.tag===4&&Ce.stateNode.containerInfo===ze.containerInfo&&Ce.stateNode.implementation===ze.implementation){S(Re,Ce.sibling),Ce=M(Ce,ze.children||[],Et),Ce.return=Re,Re=Ce;break e}else{S(Re,Ce);break}else m(Re,Ce);Ce=Ce.sibling}Ce=Xf(ze,Re.mode,Et),Ce.return=Re,Re=Ce}return ee(Re)}if(typeof ze=="string"||typeof ze=="number")return ze=""+ze,Ce!==null&&Ce.tag===6?(S(Re,Ce.sibling),Ce=M(Ce,ze,Et),Ce.return=Re,Re=Ce):(S(Re,Ce),Ce=vi(ze,Re.mode,Et),Ce.return=Re,Re=Ce),ee(Re);if(M0(ze))return po(Re,Ce,ze,Et);if(J(ze))return _i(Re,Ce,ze,Et);if(sr&&Lr(Re,ze),typeof ze=="undefined"&&!on)switch(Re.tag){case 1:case 0:throw Re=Re.type,Error(t(152,Re.displayName||Re.name||"Component"))}return S(Re,Ce)}}var R=F(!0),U=F(!1),H={},fe={current:H},ue={current:H},de={current:H};function W(v){if(v===H)throw Error(t(174));return v}function ve(v,m){Fr(de,m,v),Fr(ue,v,v),Fr(fe,H,v),m=Ot(m),kr(fe,v),Fr(fe,m,v)}function Fe(v){kr(fe,v),kr(ue,v),kr(de,v)}function Ge(v){var m=W(de.current),S=W(fe.current);m=Nt(S,v.type,m),S!==m&&(Fr(ue,v,v),Fr(fe,m,v))}function K(v){ue.current===v&&(kr(fe,v),kr(ue,v))}var xe={current:0};function je(v){for(var m=v;m!==null;){if(m.tag===13){var S=m.memoizedState;if(S!==null&&(S=S.dehydrated,S===null||ll(S)||fl(S)))return m}else if(m.tag===19&&m.memoizedProps.revealOrder!==void 0){if((m.effectTag&64)!=0)return m}else if(m.child!==null){m.child.return=m,m=m.child;continue}if(m===v)break;for(;m.sibling===null;){if(m.return===null||m.return===v)return null;m=m.return}m.sibling.return=m.return,m=m.sibling}return null}function Xe(v,m){return{responder:v,props:m}}var rt=C.ReactCurrentDispatcher,st=C.ReactCurrentBatchConfig,xt=0,wt=null,lt=null,Rt=null,yn=null,sn=null,ar=null,rn=0,Hn=null,d0=0,Cr=!1,He=null,Qe=0;function Ne(){throw Error(t(321))}function ft(v,m){if(m===null)return!1;for(var S=0;Srn&&(rn=In,pf(rn))):(Yf(In,Ze.suspenseConfig),b=Ze.eagerReducer===v?Ze.eagerState:v(b,Ze.action)),ee=Ze,Ze=Ze.next}while(Ze!==null&&Ze!==O);ut||(Ye=ee,M=b),Sn(b,m.memoizedState)||(ai=!0),m.memoizedState=b,m.baseUpdate=Ye,m.baseState=M,S.lastRenderedState=b}return[m.memoizedState,S.dispatch]}function ci(v){var m=Cn();return typeof v=="function"&&(v=v()),m.memoizedState=m.baseState=v,v=m.queue={last:null,dispatch:null,lastRenderedReducer:p0,lastRenderedState:v},v=v.dispatch=Us.bind(null,wt,v),[m.memoizedState,v]}function xi(v){return h0(p0,v)}function E0(v,m,S,O){return v={tag:v,create:m,destroy:S,deps:O,next:null},Hn===null?(Hn={lastEffect:null},Hn.lastEffect=v.next=v):(m=Hn.lastEffect,m===null?Hn.lastEffect=v.next=v:(S=m.next,m.next=v,v.next=S,Hn.lastEffect=v)),v}function qr(v,m,S,O){var M=Cn();d0|=v,M.memoizedState=E0(m,S,void 0,O===void 0?null:O)}function Eo(v,m,S,O){var M=bn();O=O===void 0?null:O;var b=void 0;if(lt!==null){var ee=lt.memoizedState;if(b=ee.destroy,O!==null&&ft(O,ee.deps)){E0(0,S,b,O);return}}d0|=v,M.memoizedState=E0(m,S,b,O)}function So(v,m){return qr(516,192,v,m)}function wl(v,m){return Eo(516,192,v,m)}function js(v,m){if(typeof m=="function")return v=v(),m(v),function(){m(null)};if(m!=null)return v=v(),m.current=v,function(){m.current=null}}function Dl(){}function du(v,m){return Cn().memoizedState=[v,m===void 0?null:m],v}function Yu(v,m){var S=bn();m=m===void 0?null:m;var O=S.memoizedState;return O!==null&&m!==null&&ft(m,O[1])?O[0]:(S.memoizedState=[v,m],v)}function Us(v,m,S){if(!(25>Qe))throw Error(t(301));var O=v.alternate;if(v===wt||O!==null&&O===wt)if(Cr=!0,v={expirationTime:xt,suspenseConfig:null,action:S,eagerReducer:null,eagerState:null,next:null},He===null&&(He=new Map),S=He.get(m),S===void 0)He.set(m,v);else{for(m=S;m.next!==null;)m=m.next;m.next=v}else{var M=g0(),b=nr.suspense;M=Kr(M,v,b),b={expirationTime:M,suspenseConfig:b,action:S,eagerReducer:null,eagerState:null,next:null};var ee=m.last;if(ee===null)b.next=b;else{var Ye=ee.next;Ye!==null&&(b.next=Ye),ee.next=b}if(m.last=b,v.expirationTime===0&&(O===null||O.expirationTime===0)&&(O=m.lastRenderedReducer,O!==null))try{var Ze=m.lastRenderedState,ut=O(Ze,S);if(b.eagerReducer=O,b.eagerState=ut,Sn(ut,Ze))return}catch(In){}finally{}_0(v,M)}}var oo={readContext:D0,useCallback:Ne,useContext:Ne,useEffect:Ne,useImperativeHandle:Ne,useLayoutEffect:Ne,useMemo:Ne,useReducer:Ne,useRef:Ne,useState:Ne,useDebugValue:Ne,useResponder:Ne,useDeferredValue:Ne,useTransition:Ne},Hi={readContext:D0,useCallback:du,useContext:D0,useEffect:So,useImperativeHandle:function(v,m,S){return S=S!=null?S.concat([v]):null,qr(4,36,js.bind(null,m,v),S)},useLayoutEffect:function(v,m){return qr(4,36,v,m)},useMemo:function(v,m){var S=Cn();return m=m===void 0?null:m,v=v(),S.memoizedState=[v,m],v},useReducer:function(v,m,S){var O=Cn();return m=S!==void 0?S(m):m,O.memoizedState=O.baseState=m,v=O.queue={last:null,dispatch:null,lastRenderedReducer:v,lastRenderedState:m},v=v.dispatch=Us.bind(null,wt,v),[O.memoizedState,v]},useRef:function(v){var m=Cn();return v={current:v},m.memoizedState=v},useState:ci,useDebugValue:Dl,useResponder:Xe,useDeferredValue:function(v,m){var S=ci(v),O=S[0],M=S[1];return So(function(){g.unstable_next(function(){var b=st.suspense;st.suspense=m===void 0?null:m;try{M(v)}finally{st.suspense=b}})},[v,m]),O},useTransition:function(v){var m=ci(!1),S=m[0],O=m[1];return[du(function(M){O(!0),g.unstable_next(function(){var b=st.suspense;st.suspense=v===void 0?null:v;try{O(!1),M()}finally{st.suspense=b}})},[v,S]),S]}},qs={readContext:D0,useCallback:Yu,useContext:D0,useEffect:wl,useImperativeHandle:function(v,m,S){return S=S!=null?S.concat([v]):null,Eo(4,36,js.bind(null,m,v),S)},useLayoutEffect:function(v,m){return Eo(4,36,v,m)},useMemo:function(v,m){var S=bn();m=m===void 0?null:m;var O=S.memoizedState;return O!==null&&m!==null&&ft(m,O[1])?O[0]:(v=v(),S.memoizedState=[v,m],v)},useReducer:h0,useRef:function(){return bn().memoizedState},useState:xi,useDebugValue:Dl,useResponder:Xe,useDeferredValue:function(v,m){var S=xi(v),O=S[0],M=S[1];return wl(function(){g.unstable_next(function(){var b=st.suspense;st.suspense=m===void 0?null:m;try{M(v)}finally{st.suspense=b}})},[v,m]),O},useTransition:function(v){var m=xi(!1),S=m[0],O=m[1];return[Yu(function(M){O(!0),g.unstable_next(function(){var b=st.suspense;st.suspense=v===void 0?null:v;try{O(!1),M()}finally{st.suspense=b}})},[v,S]),S]}},F0=null,Gr=null,ir=!1;function L0(v,m){var S=xo(5,null,null,0);S.elementType="DELETED",S.type="DELETED",S.stateNode=m,S.return=v,S.effectTag=8,v.lastEffect!==null?(v.lastEffect.nextEffect=S,v.lastEffect=S):v.firstEffect=v.lastEffect=S}function Y0(v,m){switch(v.tag){case 5:return m=Ti(m,v.type,v.pendingProps),m!==null?(v.stateNode=m,!0):!1;case 6:return m=Fu(m,v.pendingProps),m!==null?(v.stateNode=m,!0):!1;case 13:return!1;default:return!1}}function Co(v){if(ir){var m=Gr;if(m){var S=m;if(!Y0(v,m)){if(m=cl(S),!m||!Y0(v,m)){v.effectTag=v.effectTag&-1025|2,ir=!1,F0=v;return}L0(F0,S)}F0=v,Gr=al(m)}else v.effectTag=v.effectTag&-1025|2,ir=!1,F0=v}}function $u(v){for(v=v.return;v!==null&&v.tag!==5&&v.tag!==3&&v.tag!==13;)v=v.return;F0=v}function Vo(v){if(!w||v!==F0)return!1;if(!ir)return $u(v),ir=!0,!1;var m=v.type;if(v.tag!==5||m!=="head"&&m!=="body"&&!at(m,v.memoizedProps))for(m=Gr;m;)L0(v,m),m=cl(m);if($u(v),v.tag===13){if(!w)throw Error(t(316));if(v=v.memoizedState,v=v!==null?v.dehydrated:null,!v)throw Error(t(317));Gr=Ac(v)}else Gr=F0?cl(v.stateNode):null;return!0}function Rr(){w&&(Gr=F0=null,ir=!1)}var Jn=C.ReactCurrentOwner,ai=!1;function o0(v,m,S,O){m.child=v===null?U(m,null,S,O):R(m,v.child,S,O)}function Vr(v,m,S,O,M){S=S.render;var b=m.ref;return io(m,M),O=St(v,m,S,O,b,M),v!==null&&!ai?(m.updateQueue=v.updateQueue,m.effectTag&=-517,v.expirationTime<=M&&(v.expirationTime=0),X0(v,m,M)):(m.effectTag|=1,o0(v,m,O,M),m.child)}function ff(v,m,S,O,M,b){if(v===null){var ee=S.type;return typeof ee=="function"&&!mf(ee)&&ee.defaultProps===void 0&&S.compare===null&&S.defaultProps===void 0?(m.tag=15,m.type=ee,cf(v,m,ee,O,M,b)):(v=Hs(S.type,null,O,null,m.mode,b),v.ref=m.ref,v.return=m,m.child=v)}return ee=v.child,Mm)&&Qn.set(v,m)))}}function Gi(v,m){v.expirationTimev?m:v)}function x0(v){if(v.lastExpiredTime!==0)v.callbackExpirationTime=1073741823,v.callbackPriority=99,v.callbackNode=Ho(Z0.bind(null,v));else{var m=fo(v),S=v.callbackNode;if(m===0)S!==null&&(v.callbackNode=null,v.callbackExpirationTime=0,v.callbackPriority=90);else{var O=g0();if(m===1073741823?O=99:m===1||m===2?O=95:(O=10*(1073741821-m)-10*(1073741821-O),O=0>=O?99:250>=O?98:5250>=O?97:95),S!==null){var M=v.callbackPriority;if(v.callbackExpirationTime===m&&M>=O)return;S!==ju&&uf(S)}v.callbackExpirationTime=m,v.callbackPriority=O,m=m===1073741823?Ho(Z0.bind(null,v)):lu(O,Xu.bind(null,v),{timeout:10*(1073741821-m)-G0()}),v.callbackNode=m}}}function Xu(v,m){if(t0=0,m)return m=g0(),kl(v,m),x0(v),null;var S=fo(v);if(S!==0){if(m=v.callbackNode,(Kt&(Br|zr))!==Fn)throw Error(t(327));if(Ws(),v===X&&S===ye||mu(v,S),Y!==null){var O=Kt;Kt|=Br;var M=ei(v);do try{Ua();break}catch(Ye){Ju(v,Ye)}while(1);if(Wu(),Kt=O,B0.current=M,he===wr)throw m=We,mu(v,S),ao(v,S),x0(v),m;if(Y===null)switch(M=v.finishedWork=v.current.alternate,v.finishedExpirationTime=S,O=he,X=null,O){case lo:case wr:throw Error(t(345));case kn:kl(v,2=S){v.lastPingedTime=S,mu(v,S);break}}if(b=fo(v),b!==0&&b!==S)break;if(O!==0&&O!==S){v.lastPingedTime=O;break}v.timeoutHandle=jt(gu.bind(null,v),M);break}gu(v);break;case hi:if(ao(v,S),O=v.lastSuspendedTime,S===O&&(v.nextKnownPendingLevel=$f(M)),qt&&(M=v.lastPingedTime,M===0||M>=S)){v.lastPingedTime=S,mu(v,S);break}if(M=fo(v),M!==0&&M!==S)break;if(O!==0&&O!==S){v.lastPingedTime=O;break}if(Dt!==1073741823?O=10*(1073741821-Dt)-G0():et===1073741823?O=0:(O=10*(1073741821-et)-5e3,M=G0(),S=10*(1073741821-S)-M,O=M-O,0>O&&(O=0),O=(120>O?120:480>O?480:1080>O?1080:1920>O?1920:3e3>O?3e3:4320>O?4320:1960*Cl(O/1960))-O,S=O?O=0:(M=ee.busyDelayMs|0,b=G0()-(10*(1073741821-b)-(ee.timeoutMs|0||5e3)),O=b<=M?0:M+O-b),10 component higher in the tree to provide a loading indicator or placeholder to display.`+dl(M))}he!==Ai&&(he=kn),b=zs(b,M),Ze=O;do{switch(Ze.tag){case 3:ee=b,Ze.effectTag|=4096,Ze.expirationTime=m;var Ce=pu(Ze,ee,m);bu(Ze,Ce);break e;case 1:ee=b;var ze=Ze.type,Et=Ze.stateNode;if((Ze.effectTag&64)==0&&(typeof ze.getDerivedStateFromError=="function"||Et!==null&&typeof Et.componentDidCatch=="function"&&(Ar===null||!Ar.has(Et)))){Ze.effectTag|=4096,Ze.expirationTime=m;var on=Sl(Ze,ee,m);bu(Ze,on);break e}}Ze=Ze.return}while(Ze!==null)}Y=vu(Y)}catch(sr){m=sr;continue}break}while(1)}function ei(){var v=B0.current;return B0.current=oo,v===null?oo:v}function Yf(v,m){vZt&&(Zt=v)}function ja(){for(;Y!==null;)Y=Ic(Y)}function Ua(){for(;Y!==null&&!_n();)Y=Ic(Y)}function Ic(v){var m=Lc(v.alternate,v,ye);return v.memoizedProps=v.pendingProps,m===null&&(m=vu(v)),hu.current=null,m}function vu(v){Y=v;do{var m=Y.alternate;if(v=Y.return,(Y.effectTag&2048)==0){e:{var S=m;m=Y;var O=ye,M=m.pendingProps;switch(m.tag){case 2:break;case 16:break;case 15:case 0:break;case 1:c0(m.type)&&Ru(m);break;case 3:Fe(m),ks(m),M=m.stateNode,M.pendingContext&&(M.context=M.pendingContext,M.pendingContext=null),(S===null||S.child===null)&&Vo(m)&&ki(m),$r(m);break;case 5:K(m);var b=W(de.current);if(O=m.type,S!==null&&m.stateNode!=null)m0(S,m,O,M,b),S.ref!==m.ref&&(m.effectTag|=128);else if(M){if(S=W(fe.current),Vo(m)){if(M=m,!w)throw Error(t(175));S=Ui(M.stateNode,M.type,M.memoizedProps,b,S,M),M.updateQueue=S,S=S!==null,S&&ki(m)}else{var ee=ne(O,M,b,S,m);Yr(ee,m,!1,!1),m.stateNode=ee,Z(ee,O,M,b,S)&&ki(m)}m.ref!==null&&(m.effectTag|=128)}else if(m.stateNode===null)throw Error(t(166));break;case 6:if(S&&m.stateNode!=null)Tn(S,m,S.memoizedProps,M);else{if(typeof M!="string"&&m.stateNode===null)throw Error(t(166));if(S=W(de.current),b=W(fe.current),Vo(m)){if(S=m,!w)throw Error(t(176));(S=Mr(S.stateNode,S.memoizedProps,S))&&ki(m)}else m.stateNode=Ft(M,S,b,m)}break;case 11:break;case 13:if(kr(xe,m),M=m.memoizedState,(m.effectTag&64)!=0){m.expirationTime=O;break e}M=M!==null,b=!1,S===null?m.memoizedProps.fallback!==void 0&&Vo(m):(O=S.memoizedState,b=O!==null,M||O===null||(O=S.child.sibling,O!==null&&(ee=m.firstEffect,ee!==null?(m.firstEffect=O,O.nextEffect=ee):(m.firstEffect=m.lastEffect=O,O.nextEffect=null),O.effectTag=8))),M&&!b&&(m.mode&2)!=0&&(S===null&&m.memoizedProps.unstable_avoidThisFallback!==!0||(xe.current&1)!=0?he===lo&&(he=T0):((he===lo||he===T0)&&(he=hi),Zt!==0&&X!==null&&(ao(X,ye),$o(X,Zt)))),cr&&M&&(m.effectTag|=4),Yt&&(M||b)&&(m.effectTag|=4);break;case 7:break;case 8:break;case 12:break;case 4:Fe(m),$r(m);break;case 10:fi(m);break;case 9:break;case 14:break;case 17:c0(m.type)&&Ru(m);break;case 19:if(kr(xe,m),M=m.memoizedState,M===null)break;if(b=(m.effectTag&64)!=0,ee=M.rendering,ee===null){if(b)bi(M,!1);else if(he!==lo||S!==null&&(S.effectTag&64)!=0)for(S=m.child;S!==null;){if(ee=je(S),ee!==null){for(m.effectTag|=64,bi(M,!1),S=ee.updateQueue,S!==null&&(m.updateQueue=S,m.effectTag|=4),M.lastEffect===null&&(m.firstEffect=null),m.lastEffect=M.lastEffect,S=O,M=m.child;M!==null;)b=M,O=S,b.effectTag&=2,b.nextEffect=null,b.firstEffect=null,b.lastEffect=null,ee=b.alternate,ee===null?(b.childExpirationTime=0,b.expirationTime=O,b.child=null,b.memoizedProps=null,b.memoizedState=null,b.updateQueue=null,b.dependencies=null):(b.childExpirationTime=ee.childExpirationTime,b.expirationTime=ee.expirationTime,b.child=ee.child,b.memoizedProps=ee.memoizedProps,b.memoizedState=ee.memoizedState,b.updateQueue=ee.updateQueue,O=ee.dependencies,b.dependencies=O===null?null:{expirationTime:O.expirationTime,firstContext:O.firstContext,responders:O.responders}),M=M.sibling;Fr(xe,xe.current&1|2,m),m=m.child;break e}S=S.sibling}}else{if(!b)if(S=je(ee),S!==null){if(m.effectTag|=64,b=!0,S=S.updateQueue,S!==null&&(m.updateQueue=S,m.effectTag|=4),bi(M,!0),M.tail===null&&M.tailMode==="hidden"&&!ee.alternate){m=m.lastEffect=M.lastEffect,m!==null&&(m.nextEffect=null);break}}else G0()>M.tailExpiration&&1M&&(M=O),ee>M&&(M=ee),b=b.sibling;S.childExpirationTime=M}if(m!==null)return m;v!==null&&(v.effectTag&2048)==0&&(v.firstEffect===null&&(v.firstEffect=Y.firstEffect),Y.lastEffect!==null&&(v.lastEffect!==null&&(v.lastEffect.nextEffect=Y.firstEffect),v.lastEffect=Y.lastEffect),1v?m:v}function gu(v){var m=Fs();return zi(99,co.bind(null,v,m)),null}function co(v,m){do Ws();while(dr!==null);if((Kt&(Br|zr))!==Fn)throw Error(t(327));var S=v.finishedWork,O=v.finishedExpirationTime;if(S===null)return null;if(v.finishedWork=null,v.finishedExpirationTime=0,S===v.current)throw Error(t(177));v.callbackNode=null,v.callbackExpirationTime=0,v.callbackPriority=90,v.nextKnownPendingLevel=0;var M=$f(S);if(v.firstPendingTime=M,O<=v.lastSuspendedTime?v.firstSuspendedTime=v.lastSuspendedTime=v.nextKnownPendingLevel=0:O<=v.firstSuspendedTime&&(v.firstSuspendedTime=O-1),O<=v.lastPingedTime&&(v.lastPingedTime=0),O<=v.lastExpiredTime&&(v.lastExpiredTime=0),v===X&&(Y=X=null,ye=0),1=S?mt(v,m,S):(Fr(xe,xe.current&1,m),m=X0(v,m,S),m!==null?m.sibling:null);Fr(xe,xe.current&1,m);break;case 19:if(O=m.childExpirationTime>=S,(v.effectTag&64)!=0){if(O)return $t(v,m,S);m.effectTag|=64}if(M=m.memoizedState,M!==null&&(M.rendering=null,M.tail=null),Fr(xe,xe.current,m),!O)return null}return X0(v,m,S)}ai=!1}}else ai=!1;switch(m.expirationTime=0,m.tag){case 2:if(O=m.type,v!==null&&(v.alternate=null,m.alternate=null,m.effectTag|=2),v=m.pendingProps,M=Lu(m,H0.current),io(m,S),M=St(null,m,O,v,M,S),m.effectTag|=1,typeof M=="object"&&M!==null&&typeof M.render=="function"&&M.$$typeof===void 0){if(m.tag=1,Qt(),c0(O)){var b=!0;wo(m)}else b=!1;m.memoizedState=M.state!==null&&M.state!==void 0?M.state:null;var ee=O.getDerivedStateFromProps;typeof ee=="function"&&Go(m,O,ee,v),M.updater=Gu,m.stateNode=M,M._reactInternalFiber=m,Vu(m,O,v,S),m=Be(null,m,O,!0,b,S)}else m.tag=0,o0(null,m,M,S),m=m.child;return m;case 16:if(M=m.elementType,v!==null&&(v.alternate=null,m.alternate=null,m.effectTag|=2),v=m.pendingProps,Te(M),M._status!==1)throw M._result;switch(M=M._result,m.type=M,b=m.tag=Wa(M),v=I0(M,v),b){case 0:m=K0(null,m,M,v,S);break;case 1:m=ae(null,m,M,v,S);break;case 11:m=Vr(null,m,M,v,S);break;case 14:m=ff(null,m,M,I0(M.type,v),O,S);break;default:throw Error(t(306,M,""))}return m;case 0:return O=m.type,M=m.pendingProps,M=m.elementType===O?M:I0(O,M),K0(v,m,O,M,S);case 1:return O=m.type,M=m.pendingProps,M=m.elementType===O?M:I0(O,M),ae(v,m,O,M,S);case 3:if(Ie(m),O=m.updateQueue,O===null)throw Error(t(282));if(M=m.memoizedState,M=M!==null?M.element:null,P0(m,O,m.pendingProps,null,S),O=m.memoizedState.element,O===M)Rr(),m=X0(v,m,S);else{if((M=m.stateNode.hydrate)&&(w?(Gr=al(m.stateNode.containerInfo),F0=m,M=ir=!0):M=!1),M)for(S=U(m,null,O,S),m.child=S;S;)S.effectTag=S.effectTag&-3|1024,S=S.sibling;else o0(v,m,O,S),Rr();m=m.child}return m;case 5:return Ge(m),v===null&&Co(m),O=m.type,M=m.pendingProps,b=v!==null?v.memoizedProps:null,ee=M.children,at(O,M)?ee=null:b!==null&&at(O,b)&&(m.effectTag|=16),$0(v,m),m.mode&4&&S!==1&&it(O,M)?(m.expirationTime=m.childExpirationTime=1,m=null):(o0(v,m,ee,S),m=m.child),m;case 6:return v===null&&Co(m),null;case 13:return mt(v,m,S);case 4:return ve(m,m.stateNode.containerInfo),O=m.pendingProps,v===null?m.child=R(m,null,O,S):o0(v,m,O,S),m.child;case 11:return O=m.type,M=m.pendingProps,M=m.elementType===O?M:I0(O,M),Vr(v,m,O,M,S);case 7:return o0(v,m,m.pendingProps,S),m.child;case 8:return o0(v,m,m.pendingProps.children,S),m.child;case 12:return o0(v,m,m.pendingProps.children,S),m.child;case 10:e:{if(O=m.type._context,M=m.pendingProps,ee=m.memoizedProps,b=M.value,Ls(m,b),ee!==null){var Ye=ee.value;if(b=Sn(Ye,b)?0:(typeof O._calculateChangedBits=="function"?O._calculateChangedBits(Ye,b):1073741823)|0,b===0){if(ee.children===M.children&&!b0.current){m=X0(v,m,S);break e}}else for(Ye=m.child,Ye!==null&&(Ye.return=m);Ye!==null;){var Ze=Ye.dependencies;if(Ze!==null){ee=Ye.child;for(var ut=Ze.firstContext;ut!==null;){if(ut.context===O&&(ut.observedBits&b)!=0){Ye.tag===1&&(ut=a0(S,null),ut.tag=2,V0(Ye,ut)),Ye.expirationTime=m&&v<=m}function ao(v,m){var S=v.firstSuspendedTime,O=v.lastSuspendedTime;Sm||S===0)&&(v.lastSuspendedTime=m),m<=v.lastPingedTime&&(v.lastPingedTime=0),m<=v.lastExpiredTime&&(v.lastExpiredTime=0)}function $o(v,m){m>v.firstPendingTime&&(v.firstPendingTime=m);var S=v.firstSuspendedTime;S!==0&&(m>=S?v.firstSuspendedTime=v.lastSuspendedTime=v.nextKnownPendingLevel=0:m>=v.lastSuspendedTime&&(v.lastSuspendedTime=m+1),m>v.nextKnownPendingLevel&&(v.nextKnownPendingLevel=m))}function kl(v,m){var S=v.lastExpiredTime;(S===0||S>m)&&(v.lastExpiredTime=m)}function Nc(v){var m=v._reactInternalFiber;if(m===void 0)throw typeof v.render=="function"?Error(t(188)):Error(t(268,Object.keys(v)));return v=Ue(m),v===null?null:v.stateNode}function Al(v,m){v=v.memoizedState,v!==null&&v.dehydrated!==null&&v.retryTime{"use strict";sE.exports=uE()});var cE=Me((db,fE)=>{"use strict";var gN={ALIGN_COUNT:8,ALIGN_AUTO:0,ALIGN_FLEX_START:1,ALIGN_CENTER:2,ALIGN_FLEX_END:3,ALIGN_STRETCH:4,ALIGN_BASELINE:5,ALIGN_SPACE_BETWEEN:6,ALIGN_SPACE_AROUND:7,DIMENSION_COUNT:2,DIMENSION_WIDTH:0,DIMENSION_HEIGHT:1,DIRECTION_COUNT:3,DIRECTION_INHERIT:0,DIRECTION_LTR:1,DIRECTION_RTL:2,DISPLAY_COUNT:2,DISPLAY_FLEX:0,DISPLAY_NONE:1,EDGE_COUNT:9,EDGE_LEFT:0,EDGE_TOP:1,EDGE_RIGHT:2,EDGE_BOTTOM:3,EDGE_START:4,EDGE_END:5,EDGE_HORIZONTAL:6,EDGE_VERTICAL:7,EDGE_ALL:8,EXPERIMENTAL_FEATURE_COUNT:1,EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS:0,FLEX_DIRECTION_COUNT:4,FLEX_DIRECTION_COLUMN:0,FLEX_DIRECTION_COLUMN_REVERSE:1,FLEX_DIRECTION_ROW:2,FLEX_DIRECTION_ROW_REVERSE:3,JUSTIFY_COUNT:6,JUSTIFY_FLEX_START:0,JUSTIFY_CENTER:1,JUSTIFY_FLEX_END:2,JUSTIFY_SPACE_BETWEEN:3,JUSTIFY_SPACE_AROUND:4,JUSTIFY_SPACE_EVENLY:5,LOG_LEVEL_COUNT:6,LOG_LEVEL_ERROR:0,LOG_LEVEL_WARN:1,LOG_LEVEL_INFO:2,LOG_LEVEL_DEBUG:3,LOG_LEVEL_VERBOSE:4,LOG_LEVEL_FATAL:5,MEASURE_MODE_COUNT:3,MEASURE_MODE_UNDEFINED:0,MEASURE_MODE_EXACTLY:1,MEASURE_MODE_AT_MOST:2,NODE_TYPE_COUNT:2,NODE_TYPE_DEFAULT:0,NODE_TYPE_TEXT:1,OVERFLOW_COUNT:3,OVERFLOW_VISIBLE:0,OVERFLOW_HIDDEN:1,OVERFLOW_SCROLL:2,POSITION_TYPE_COUNT:2,POSITION_TYPE_RELATIVE:0,POSITION_TYPE_ABSOLUTE:1,PRINT_OPTIONS_COUNT:3,PRINT_OPTIONS_LAYOUT:1,PRINT_OPTIONS_STYLE:2,PRINT_OPTIONS_CHILDREN:4,UNIT_COUNT:4,UNIT_UNDEFINED:0,UNIT_POINT:1,UNIT_PERCENT:2,UNIT_AUTO:3,WRAP_COUNT:3,WRAP_NO_WRAP:0,WRAP_WRAP:1,WRAP_WRAP_REVERSE:2};fE.exports=gN});var hE=Me((pb,aE)=>{"use strict";var _N=Object.assign||function(i){for(var u=1;u"}}]),i}(),dE=function(){Ph(i,null,[{key:"fromJS",value:function(f){var c=f.width,g=f.height;return new i(c,g)}}]);function i(u,f){Iy(this,i),this.width=u,this.height=f}return Ph(i,[{key:"fromJS",value:function(f){f(this.width,this.height)}},{key:"toString",value:function(){return""}}]),i}(),pE=function(){function i(u,f){Iy(this,i),this.unit=u,this.value=f}return Ph(i,[{key:"fromJS",value:function(f){f(this.unit,this.value)}},{key:"toString",value:function(){switch(this.unit){case ps.UNIT_POINT:return String(this.value);case ps.UNIT_PERCENT:return this.value+"%";case ps.UNIT_AUTO:return"auto";default:return this.value+"?"}}},{key:"valueOf",value:function(){return this.value}}]),i}();aE.exports=function(i,u){function f(C,A,x){var D=C[A];C[A]=function(){for(var L=arguments.length,N=Array(L),j=0;j1?N-1:0),$=1;$1&&arguments[1]!==void 0?arguments[1]:NaN,x=arguments.length>2&&arguments[2]!==void 0?arguments[2]:NaN,D=arguments.length>3&&arguments[3]!==void 0?arguments[3]:ps.DIRECTION_LTR;return C.call(this,A,x,D)}),_N({Config:u.Config,Node:u.Node,Layout:i("Layout",yN),Size:i("Size",dE),Value:i("Value",pE),getInstanceCount:function(){return u.getInstanceCount.apply(u,arguments)}},ps)}});var mE=Me((exports,module)=>{(function(i,u){typeof define=="function"&&define.amd?define([],function(){return u}):typeof module=="object"&&module.exports?module.exports=u:(i.nbind=i.nbind||{}).init=u})(exports,function(Module,cb){typeof Module=="function"&&(cb=Module,Module={}),Module.onRuntimeInitialized=function(i,u){return function(){i&&i.apply(this,arguments);try{Module.ccall("nbind_init")}catch(f){u(f);return}u(null,{bind:Module._nbind_value,reflect:Module.NBind.reflect,queryType:Module.NBind.queryType,toggleLightGC:Module.toggleLightGC,lib:Module})}}(Module.onRuntimeInitialized,cb);var Module;Module||(Module=(typeof Module!="undefined"?Module:null)||{});var moduleOverrides={};for(var key in Module)Module.hasOwnProperty(key)&&(moduleOverrides[key]=Module[key]);var ENVIRONMENT_IS_WEB=!1,ENVIRONMENT_IS_WORKER=!1,ENVIRONMENT_IS_NODE=!1,ENVIRONMENT_IS_SHELL=!1;if(Module.ENVIRONMENT)if(Module.ENVIRONMENT==="WEB")ENVIRONMENT_IS_WEB=!0;else if(Module.ENVIRONMENT==="WORKER")ENVIRONMENT_IS_WORKER=!0;else if(Module.ENVIRONMENT==="NODE")ENVIRONMENT_IS_NODE=!0;else if(Module.ENVIRONMENT==="SHELL")ENVIRONMENT_IS_SHELL=!0;else throw new Error("The provided Module['ENVIRONMENT'] value is not valid. It must be one of: WEB|WORKER|NODE|SHELL.");else ENVIRONMENT_IS_WEB=typeof window=="object",ENVIRONMENT_IS_WORKER=typeof importScripts=="function",ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof require=="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER,ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE){Module.print||(Module.print=console.log),Module.printErr||(Module.printErr=console.warn);var nodeFS,nodePath;Module.read=function(u,f){nodeFS||(nodeFS={}("")),nodePath||(nodePath={}("")),u=nodePath.normalize(u);var c=nodeFS.readFileSync(u);return f?c:c.toString()},Module.readBinary=function(u){var f=Module.read(u,!0);return f.buffer||(f=new Uint8Array(f)),assert(f.buffer),f},Module.load=function(u){globalEval(read(u))},Module.thisProgram||(process.argv.length>1?Module.thisProgram=process.argv[1].replace(/\\/g,"/"):Module.thisProgram="unknown-program"),Module.arguments=process.argv.slice(2),typeof module!="undefined"&&(module.exports=Module),Module.inspect=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL)Module.print||(Module.print=print),typeof printErr!="undefined"&&(Module.printErr=printErr),typeof read!="undefined"?Module.read=read:Module.read=function(){throw"no read() available"},Module.readBinary=function(u){if(typeof readbuffer=="function")return new Uint8Array(readbuffer(u));var f=read(u,"binary");return assert(typeof f=="object"),f},typeof scriptArgs!="undefined"?Module.arguments=scriptArgs:typeof arguments!="undefined"&&(Module.arguments=arguments),typeof quit=="function"&&(Module.quit=function(i,u){quit(i)});else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(Module.read=function(u){var f=new XMLHttpRequest;return f.open("GET",u,!1),f.send(null),f.responseText},ENVIRONMENT_IS_WORKER&&(Module.readBinary=function(u){var f=new XMLHttpRequest;return f.open("GET",u,!1),f.responseType="arraybuffer",f.send(null),new Uint8Array(f.response)}),Module.readAsync=function(u,f,c){var g=new XMLHttpRequest;g.open("GET",u,!0),g.responseType="arraybuffer",g.onload=function(){g.status==200||g.status==0&&g.response?f(g.response):c()},g.onerror=c,g.send(null)},typeof arguments!="undefined"&&(Module.arguments=arguments),typeof console!="undefined")Module.print||(Module.print=function(u){console.log(u)}),Module.printErr||(Module.printErr=function(u){console.warn(u)});else{var TRY_USE_DUMP=!1;Module.print||(Module.print=TRY_USE_DUMP&&typeof dump!="undefined"?function(i){dump(i)}:function(i){})}ENVIRONMENT_IS_WORKER&&(Module.load=importScripts),typeof Module.setWindowTitle=="undefined"&&(Module.setWindowTitle=function(i){document.title=i})}else throw"Unknown runtime environment. Where are we?";function globalEval(i){eval.call(null,i)}!Module.load&&Module.read&&(Module.load=function(u){globalEval(Module.read(u))}),Module.print||(Module.print=function(){}),Module.printErr||(Module.printErr=Module.print),Module.arguments||(Module.arguments=[]),Module.thisProgram||(Module.thisProgram="./this.program"),Module.quit||(Module.quit=function(i,u){throw u}),Module.print=Module.print,Module.printErr=Module.printErr,Module.preRun=[],Module.postRun=[];for(var key in moduleOverrides)moduleOverrides.hasOwnProperty(key)&&(Module[key]=moduleOverrides[key]);moduleOverrides=void 0;var Runtime={setTempRet0:function(i){return tempRet0=i,i},getTempRet0:function(){return tempRet0},stackSave:function(){return STACKTOP},stackRestore:function(i){STACKTOP=i},getNativeTypeSize:function(i){switch(i){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(i[i.length-1]==="*")return Runtime.QUANTUM_SIZE;if(i[0]==="i"){var u=parseInt(i.substr(1));return assert(u%8==0),u/8}else return 0}}},getNativeFieldSize:function(i){return Math.max(Runtime.getNativeTypeSize(i),Runtime.QUANTUM_SIZE)},STACK_ALIGN:16,prepVararg:function(i,u){return u==="double"||u==="i64"?i&7&&(assert((i&7)==4),i+=4):assert((i&3)==0),i},getAlignSize:function(i,u,f){return!f&&(i=="i64"||i=="double")?8:i?Math.min(u||(i?Runtime.getNativeFieldSize(i):0),Runtime.QUANTUM_SIZE):Math.min(u,8)},dynCall:function(i,u,f){return f&&f.length?Module["dynCall_"+i].apply(null,[u].concat(f)):Module["dynCall_"+i].call(null,u)},functionPointers:[],addFunction:function(i){for(var u=0;u>2],f=(u+i+15|0)&-16;if(HEAP32[DYNAMICTOP_PTR>>2]=f,f>=TOTAL_MEMORY){var c=enlargeMemory();if(!c)return HEAP32[DYNAMICTOP_PTR>>2]=u,0}return u},alignMemory:function(i,u){var f=i=Math.ceil(i/(u||16))*(u||16);return f},makeBigInt:function(i,u,f){var c=f?+(i>>>0)+ +(u>>>0)*4294967296:+(i>>>0)+ +(u|0)*4294967296;return c},GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0};Module.Runtime=Runtime;var ABORT=0,EXITSTATUS=0;function assert(i,u){i||abort("Assertion failed: "+u)}function getCFunc(ident){var func=Module["_"+ident];if(!func)try{func=eval("_"+ident)}catch(i){}return assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)"),func}var cwrap,ccall;(function(){var JSfuncs={stackSave:function(){Runtime.stackSave()},stackRestore:function(){Runtime.stackRestore()},arrayToC:function(i){var u=Runtime.stackAlloc(i.length);return writeArrayToMemory(i,u),u},stringToC:function(i){var u=0;if(i!=null&&i!==0){var f=(i.length<<2)+1;u=Runtime.stackAlloc(f),stringToUTF8(i,u,f)}return u}},toC={string:JSfuncs.stringToC,array:JSfuncs.arrayToC};ccall=function(u,f,c,g,t){var C=getCFunc(u),A=[],x=0;if(g)for(var D=0;D>0]=u;break;case"i8":HEAP8[i>>0]=u;break;case"i16":HEAP16[i>>1]=u;break;case"i32":HEAP32[i>>2]=u;break;case"i64":tempI64=[u>>>0,(tempDouble=u,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[i>>2]=tempI64[0],HEAP32[i+4>>2]=tempI64[1];break;case"float":HEAPF32[i>>2]=u;break;case"double":HEAPF64[i>>3]=u;break;default:abort("invalid type for setValue: "+f)}}Module.setValue=setValue;function getValue(i,u,f){switch(u=u||"i8",u.charAt(u.length-1)==="*"&&(u="i32"),u){case"i1":return HEAP8[i>>0];case"i8":return HEAP8[i>>0];case"i16":return HEAP16[i>>1];case"i32":return HEAP32[i>>2];case"i64":return HEAP32[i>>2];case"float":return HEAPF32[i>>2];case"double":return HEAPF64[i>>3];default:abort("invalid type for setValue: "+u)}return null}Module.getValue=getValue;var ALLOC_NORMAL=0,ALLOC_STACK=1,ALLOC_STATIC=2,ALLOC_DYNAMIC=3,ALLOC_NONE=4;Module.ALLOC_NORMAL=ALLOC_NORMAL,Module.ALLOC_STACK=ALLOC_STACK,Module.ALLOC_STATIC=ALLOC_STATIC,Module.ALLOC_DYNAMIC=ALLOC_DYNAMIC,Module.ALLOC_NONE=ALLOC_NONE;function allocate(i,u,f,c){var g,t;typeof i=="number"?(g=!0,t=i):(g=!1,t=i.length);var C=typeof u=="string"?u:null,A;if(f==ALLOC_NONE?A=c:A=[typeof _malloc=="function"?_malloc:Runtime.staticAlloc,Runtime.stackAlloc,Runtime.staticAlloc,Runtime.dynamicAlloc][f===void 0?ALLOC_STATIC:f](Math.max(t,C?1:u.length)),g){var c=A,x;for(assert((A&3)==0),x=A+(t&~3);c>2]=0;for(x=A+t;c>0]=0;return A}if(C==="i8")return i.subarray||i.slice?HEAPU8.set(i,A):HEAPU8.set(new Uint8Array(i),A),A;for(var D=0,L,N,j;D>0],f|=c,!(c==0&&!u||(g++,u&&g==u)););u||(u=g);var t="";if(f<128){for(var C=1024,A;u>0;)A=String.fromCharCode.apply(String,HEAPU8.subarray(i,i+Math.min(u,C))),t=t?t+A:A,i+=C,u-=C;return t}return Module.UTF8ToString(i)}Module.Pointer_stringify=Pointer_stringify;function AsciiToString(i){for(var u="";;){var f=HEAP8[i++>>0];if(!f)return u;u+=String.fromCharCode(f)}}Module.AsciiToString=AsciiToString;function stringToAscii(i,u){return writeAsciiToMemory(i,u,!1)}Module.stringToAscii=stringToAscii;var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):void 0;function UTF8ArrayToString(i,u){for(var f=u;i[f];)++f;if(f-u>16&&i.subarray&&UTF8Decoder)return UTF8Decoder.decode(i.subarray(u,f));for(var c,g,t,C,A,x,D="";;){if(c=i[u++],!c)return D;if(!(c&128)){D+=String.fromCharCode(c);continue}if(g=i[u++]&63,(c&224)==192){D+=String.fromCharCode((c&31)<<6|g);continue}if(t=i[u++]&63,(c&240)==224?c=(c&15)<<12|g<<6|t:(C=i[u++]&63,(c&248)==240?c=(c&7)<<18|g<<12|t<<6|C:(A=i[u++]&63,(c&252)==248?c=(c&3)<<24|g<<18|t<<12|C<<6|A:(x=i[u++]&63,c=(c&1)<<30|g<<24|t<<18|C<<12|A<<6|x))),c<65536)D+=String.fromCharCode(c);else{var L=c-65536;D+=String.fromCharCode(55296|L>>10,56320|L&1023)}}}Module.UTF8ArrayToString=UTF8ArrayToString;function UTF8ToString(i){return UTF8ArrayToString(HEAPU8,i)}Module.UTF8ToString=UTF8ToString;function stringToUTF8Array(i,u,f,c){if(!(c>0))return 0;for(var g=f,t=f+c-1,C=0;C=55296&&A<=57343&&(A=65536+((A&1023)<<10)|i.charCodeAt(++C)&1023),A<=127){if(f>=t)break;u[f++]=A}else if(A<=2047){if(f+1>=t)break;u[f++]=192|A>>6,u[f++]=128|A&63}else if(A<=65535){if(f+2>=t)break;u[f++]=224|A>>12,u[f++]=128|A>>6&63,u[f++]=128|A&63}else if(A<=2097151){if(f+3>=t)break;u[f++]=240|A>>18,u[f++]=128|A>>12&63,u[f++]=128|A>>6&63,u[f++]=128|A&63}else if(A<=67108863){if(f+4>=t)break;u[f++]=248|A>>24,u[f++]=128|A>>18&63,u[f++]=128|A>>12&63,u[f++]=128|A>>6&63,u[f++]=128|A&63}else{if(f+5>=t)break;u[f++]=252|A>>30,u[f++]=128|A>>24&63,u[f++]=128|A>>18&63,u[f++]=128|A>>12&63,u[f++]=128|A>>6&63,u[f++]=128|A&63}}return u[f]=0,f-g}Module.stringToUTF8Array=stringToUTF8Array;function stringToUTF8(i,u,f){return stringToUTF8Array(i,HEAPU8,u,f)}Module.stringToUTF8=stringToUTF8;function lengthBytesUTF8(i){for(var u=0,f=0;f=55296&&c<=57343&&(c=65536+((c&1023)<<10)|i.charCodeAt(++f)&1023),c<=127?++u:c<=2047?u+=2:c<=65535?u+=3:c<=2097151?u+=4:c<=67108863?u+=5:u+=6}return u}Module.lengthBytesUTF8=lengthBytesUTF8;var UTF16Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf-16le"):void 0;function demangle(i){var u=Module.___cxa_demangle||Module.__cxa_demangle;if(u){try{var f=i.substr(1),c=lengthBytesUTF8(f)+1,g=_malloc(c);stringToUTF8(f,g,c);var t=_malloc(4),C=u(g,0,0,t);if(getValue(t,"i32")===0&&C)return Pointer_stringify(C)}catch(A){}finally{g&&_free(g),t&&_free(t),C&&_free(C)}return i}return Runtime.warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling"),i}function demangleAll(i){var u=/__Z[\w\d_]+/g;return i.replace(u,function(f){var c=demangle(f);return f===c?f:f+" ["+c+"]"})}function jsStackTrace(){var i=new Error;if(!i.stack){try{throw new Error(0)}catch(u){i=u}if(!i.stack)return"(no stack trace available)"}return i.stack.toString()}function stackTrace(){var i=jsStackTrace();return Module.extraStackTrace&&(i+=` +`+Module.extraStackTrace()),demangleAll(i)}Module.stackTrace=stackTrace;var HEAP,buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferViews(){Module.HEAP8=HEAP8=new Int8Array(buffer),Module.HEAP16=HEAP16=new Int16Array(buffer),Module.HEAP32=HEAP32=new Int32Array(buffer),Module.HEAPU8=HEAPU8=new Uint8Array(buffer),Module.HEAPU16=HEAPU16=new Uint16Array(buffer),Module.HEAPU32=HEAPU32=new Uint32Array(buffer),Module.HEAPF32=HEAPF32=new Float32Array(buffer),Module.HEAPF64=HEAPF64=new Float64Array(buffer)}var STATIC_BASE,STATICTOP,staticSealed,STACK_BASE,STACKTOP,STACK_MAX,DYNAMIC_BASE,DYNAMICTOP_PTR;STATIC_BASE=STATICTOP=STACK_BASE=STACKTOP=STACK_MAX=DYNAMIC_BASE=DYNAMICTOP_PTR=0,staticSealed=!1;function abortOnCannotGrowMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or (4) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}function enlargeMemory(){abortOnCannotGrowMemory()}var TOTAL_STACK=Module.TOTAL_STACK||5242880,TOTAL_MEMORY=Module.TOTAL_MEMORY||134217728;TOTAL_MEMORY0;){var u=i.shift();if(typeof u=="function"){u();continue}var f=u.func;typeof f=="number"?u.arg===void 0?Module.dynCall_v(f):Module.dynCall_vi(f,u.arg):f(u.arg===void 0?null:u.arg)}}var __ATPRERUN__=[],__ATINIT__=[],__ATMAIN__=[],__ATEXIT__=[],__ATPOSTRUN__=[],runtimeInitialized=!1,runtimeExited=!1;function preRun(){if(Module.preRun)for(typeof Module.preRun=="function"&&(Module.preRun=[Module.preRun]);Module.preRun.length;)addOnPreRun(Module.preRun.shift());callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){runtimeInitialized||(runtimeInitialized=!0,callRuntimeCallbacks(__ATINIT__))}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__),runtimeExited=!0}function postRun(){if(Module.postRun)for(typeof Module.postRun=="function"&&(Module.postRun=[Module.postRun]);Module.postRun.length;)addOnPostRun(Module.postRun.shift());callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(i){__ATPRERUN__.unshift(i)}Module.addOnPreRun=addOnPreRun;function addOnInit(i){__ATINIT__.unshift(i)}Module.addOnInit=addOnInit;function addOnPreMain(i){__ATMAIN__.unshift(i)}Module.addOnPreMain=addOnPreMain;function addOnExit(i){__ATEXIT__.unshift(i)}Module.addOnExit=addOnExit;function addOnPostRun(i){__ATPOSTRUN__.unshift(i)}Module.addOnPostRun=addOnPostRun;function intArrayFromString(i,u,f){var c=f>0?f:lengthBytesUTF8(i)+1,g=new Array(c),t=stringToUTF8Array(i,g,0,g.length);return u&&(g.length=t),g}Module.intArrayFromString=intArrayFromString;function intArrayToString(i){for(var u=[],f=0;f255&&(c&=255),u.push(String.fromCharCode(c))}return u.join("")}Module.intArrayToString=intArrayToString;function writeStringToMemory(i,u,f){Runtime.warnOnce("writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!");var c,g;f&&(g=u+lengthBytesUTF8(i),c=HEAP8[g]),stringToUTF8(i,u,Infinity),f&&(HEAP8[g]=c)}Module.writeStringToMemory=writeStringToMemory;function writeArrayToMemory(i,u){HEAP8.set(i,u)}Module.writeArrayToMemory=writeArrayToMemory;function writeAsciiToMemory(i,u,f){for(var c=0;c>0]=i.charCodeAt(c);f||(HEAP8[u>>0]=0)}if(Module.writeAsciiToMemory=writeAsciiToMemory,(!Math.imul||Math.imul(4294967295,5)!==-5)&&(Math.imul=function(u,f){var c=u>>>16,g=u&65535,t=f>>>16,C=f&65535;return g*C+(c*C+g*t<<16)|0}),Math.imul=Math.imul,!Math.fround){var froundBuffer=new Float32Array(1);Math.fround=function(i){return froundBuffer[0]=i,froundBuffer[0]}}Math.fround=Math.fround,Math.clz32||(Math.clz32=function(i){i=i>>>0;for(var u=0;u<32;u++)if(i&1<<31-u)return u;return 32}),Math.clz32=Math.clz32,Math.trunc||(Math.trunc=function(i){return i<0?Math.ceil(i):Math.floor(i)}),Math.trunc=Math.trunc;var Math_abs=Math.abs,Math_cos=Math.cos,Math_sin=Math.sin,Math_tan=Math.tan,Math_acos=Math.acos,Math_asin=Math.asin,Math_atan=Math.atan,Math_atan2=Math.atan2,Math_exp=Math.exp,Math_log=Math.log,Math_sqrt=Math.sqrt,Math_ceil=Math.ceil,Math_floor=Math.floor,Math_pow=Math.pow,Math_imul=Math.imul,Math_fround=Math.fround,Math_round=Math.round,Math_min=Math.min,Math_clz32=Math.clz32,Math_trunc=Math.trunc,runDependencies=0,runDependencyWatcher=null,dependenciesFulfilled=null;function getUniqueRunDependency(i){return i}function addRunDependency(i){runDependencies++,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies)}Module.addRunDependency=addRunDependency;function removeRunDependency(i){if(runDependencies--,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies),runDependencies==0&&(runDependencyWatcher!==null&&(clearInterval(runDependencyWatcher),runDependencyWatcher=null),dependenciesFulfilled)){var u=dependenciesFulfilled;dependenciesFulfilled=null,u()}}Module.removeRunDependency=removeRunDependency,Module.preloadedImages={},Module.preloadedAudios={};var ASM_CONSTS=[function(i,u,f,c,g,t,C,A){return _nbind.callbackSignatureList[i].apply(this,arguments)}];function _emscripten_asm_const_iiiiiiii(i,u,f,c,g,t,C,A){return ASM_CONSTS[i](u,f,c,g,t,C,A)}function _emscripten_asm_const_iiiii(i,u,f,c,g){return ASM_CONSTS[i](u,f,c,g)}function _emscripten_asm_const_iiidddddd(i,u,f,c,g,t,C,A,x){return ASM_CONSTS[i](u,f,c,g,t,C,A,x)}function _emscripten_asm_const_iiididi(i,u,f,c,g,t,C){return ASM_CONSTS[i](u,f,c,g,t,C)}function _emscripten_asm_const_iiii(i,u,f,c){return ASM_CONSTS[i](u,f,c)}function _emscripten_asm_const_iiiid(i,u,f,c,g){return ASM_CONSTS[i](u,f,c,g)}function _emscripten_asm_const_iiiiii(i,u,f,c,g,t){return ASM_CONSTS[i](u,f,c,g,t)}STATIC_BASE=Runtime.GLOBAL_BASE,STATICTOP=STATIC_BASE+12800,__ATINIT__.push({func:function(){__GLOBAL__sub_I_Yoga_cpp()}},{func:function(){__GLOBAL__sub_I_nbind_cc()}},{func:function(){__GLOBAL__sub_I_common_cc()}},{func:function(){__GLOBAL__sub_I_Binding_cc()}}),allocate([0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,192,127,0,0,192,127,0,0,192,127,3,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,3,0,0,0,0,0,192,127,3,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,192,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,192,127,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,0,0,128,191,0,0,128,191,0,0,192,127,0,0,0,0,0,0,0,0,0,0,128,63,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,190,12,0,0,200,12,0,0,208,12,0,0,216,12,0,0,230,12,0,0,242,12,0,0,1,0,0,0,3,0,0,0,0,0,0,0,2,0,0,0,0,0,192,127,3,0,0,0,180,45,0,0,181,45,0,0,182,45,0,0,181,45,0,0,182,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,1,0,0,0,4,0,0,0,183,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,184,45,0,0,185,45,0,0,181,45,0,0,181,45,0,0,182,45,0,0,186,45,0,0,185,45,0,0,148,4,0,0,3,0,0,0,187,45,0,0,164,4,0,0,188,45,0,0,2,0,0,0,189,45,0,0,164,4,0,0,188,45,0,0,185,45,0,0,164,4,0,0,185,45,0,0,164,4,0,0,188,45,0,0,181,45,0,0,182,45,0,0,181,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,0,0,0,6,0,0,0,1,0,0,0,7,0,0,0,183,45,0,0,182,45,0,0,181,45,0,0,190,45,0,0,190,45,0,0,182,45,0,0,182,45,0,0,185,45,0,0,181,45,0,0,185,45,0,0,182,45,0,0,181,45,0,0,185,45,0,0,182,45,0,0,185,45,0,0,48,5,0,0,3,0,0,0,56,5,0,0,1,0,0,0,189,45,0,0,185,45,0,0,164,4,0,0,76,5,0,0,2,0,0,0,191,45,0,0,186,45,0,0,182,45,0,0,185,45,0,0,192,45,0,0,185,45,0,0,182,45,0,0,186,45,0,0,185,45,0,0,76,5,0,0,76,5,0,0,136,5,0,0,182,45,0,0,181,45,0,0,2,0,0,0,190,45,0,0,136,5,0,0,56,19,0,0,156,5,0,0,2,0,0,0,184,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0,0,9,0,0,0,1,0,0,0,10,0,0,0,204,5,0,0,181,45,0,0,181,45,0,0,2,0,0,0,180,45,0,0,204,5,0,0,2,0,0,0,195,45,0,0,236,5,0,0,97,19,0,0,198,45,0,0,211,45,0,0,212,45,0,0,213,45,0,0,214,45,0,0,215,45,0,0,188,45,0,0,182,45,0,0,216,45,0,0,217,45,0,0,218,45,0,0,219,45,0,0,192,45,0,0,181,45,0,0,0,0,0,0,185,45,0,0,110,19,0,0,186,45,0,0,115,19,0,0,221,45,0,0,120,19,0,0,148,4,0,0,132,19,0,0,96,6,0,0,145,19,0,0,222,45,0,0,164,19,0,0,223,45,0,0,173,19,0,0,0,0,0,0,3,0,0,0,104,6,0,0,1,0,0,0,187,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,12,0,0,0,1,0,0,0,13,0,0,0,185,45,0,0,224,45,0,0,164,6,0,0,188,45,0,0,172,6,0,0,180,6,0,0,2,0,0,0,188,6,0,0,7,0,0,0,224,45,0,0,7,0,0,0,164,6,0,0,1,0,0,0,213,45,0,0,185,45,0,0,224,45,0,0,172,6,0,0,185,45,0,0,224,45,0,0,164,6,0,0,185,45,0,0,224,45,0,0,211,45,0,0,211,45,0,0,222,45,0,0,211,45,0,0,224,45,0,0,222,45,0,0,211,45,0,0,224,45,0,0,172,6,0,0,222,45,0,0,211,45,0,0,224,45,0,0,188,45,0,0,222,45,0,0,211,45,0,0,40,7,0,0,188,45,0,0,2,0,0,0,224,45,0,0,185,45,0,0,188,45,0,0,188,45,0,0,188,45,0,0,188,45,0,0,222,45,0,0,224,45,0,0,148,4,0,0,185,45,0,0,148,4,0,0,148,4,0,0,148,4,0,0,148,4,0,0,148,4,0,0,185,45,0,0,164,6,0,0,148,4,0,0,0,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,15,0,0,0,1,0,0,0,16,0,0,0,148,7,0,0,2,0,0,0,225,45,0,0,183,45,0,0,188,45,0,0,168,7,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,234,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,148,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,9,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,242,45,0,0,0,4,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67,111,117,108,100,32,110,111,116,32,97,108,108,111,99,97,116,101,32,109,101,109,111,114,121,32,102,111,114,32,110,111,100,101,0,67,97,110,110,111,116,32,114,101,115,101,116,32,97,32,110,111,100,101,32,119,104,105,99,104,32,115,116,105,108,108,32,104,97,115,32,99,104,105,108,100,114,101,110,32,97,116,116,97,99,104,101,100,0,67,97,110,110,111,116,32,114,101,115,101,116,32,97,32,110,111,100,101,32,115,116,105,108,108,32,97,116,116,97,99,104,101,100,32,116,111,32,97,32,112,97,114,101,110,116,0,67,111,117,108,100,32,110,111,116,32,97,108,108,111,99,97,116,101,32,109,101,109,111,114,121,32,102,111,114,32,99,111,110,102,105,103,0,67,97,110,110,111,116,32,115,101,116,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,58,32,78,111,100,101,115,32,119,105,116,104,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,115,32,99,97,110,110,111,116,32,104,97,118,101,32,99,104,105,108,100,114,101,110,46,0,67,104,105,108,100,32,97,108,114,101,97,100,121,32,104,97,115,32,97,32,112,97,114,101,110,116,44,32,105,116,32,109,117,115,116,32,98,101,32,114,101,109,111,118,101,100,32,102,105,114,115,116,46,0,67,97,110,110,111,116,32,97,100,100,32,99,104,105,108,100,58,32,78,111,100,101,115,32,119,105,116,104,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,115,32,99,97,110,110,111,116,32,104,97,118,101,32,99,104,105,108,100,114,101,110,46,0,79,110,108,121,32,108,101,97,102,32,110,111,100,101,115,32,119,105,116,104,32,99,117,115,116,111,109,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,115,115,104,111,117,108,100,32,109,97,110,117,97,108,108,121,32,109,97,114,107,32,116,104,101,109,115,101,108,118,101,115,32,97,115,32,100,105,114,116,121,0,67,97,110,110,111,116,32,103,101,116,32,108,97,121,111,117,116,32,112,114,111,112,101,114,116,105,101,115,32,111,102,32,109,117,108,116,105,45,101,100,103,101,32,115,104,111,114,116,104,97,110,100,115,0,37,115,37,100,46,123,91,115,107,105,112,112,101,100,93,32,0,119,109,58,32,37,115,44,32,104,109,58,32,37,115,44,32,97,119,58,32,37,102,32,97,104,58,32,37,102,32,61,62,32,100,58,32,40,37,102,44,32,37,102,41,32,37,115,10,0,37,115,37,100,46,123,37,115,0,42,0,119,109,58,32,37,115,44,32,104,109,58,32,37,115,44,32,97,119,58,32,37,102,32,97,104,58,32,37,102,32,37,115,10,0,37,115,37,100,46,125,37,115,0,119,109,58,32,37,115,44,32,104,109,58,32,37,115,44,32,100,58,32,40,37,102,44,32,37,102,41,32,37,115,10,0,79,117,116,32,111,102,32,99,97,99,104,101,32,101,110,116,114,105,101,115,33,10,0,83,99,97,108,101,32,102,97,99,116,111,114,32,115,104,111,117,108,100,32,110,111,116,32,98,101,32,108,101,115,115,32,116,104,97,110,32,122,101,114,111,0,105,110,105,116,105,97,108,0,37,115,10,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,85,78,68,69,70,73,78,69,68,0,69,88,65,67,84,76,89,0,65,84,95,77,79,83,84,0,76,65,89,95,85,78,68,69,70,73,78,69,68,0,76,65,89,95,69,88,65,67,84,76,89,0,76,65,89,95,65,84,95,77,79,83,84,0,97,118,97,105,108,97,98,108,101,87,105,100,116,104,32,105,115,32,105,110,100,101,102,105,110,105,116,101,32,115,111,32,119,105,100,116,104,77,101,97,115,117,114,101,77,111,100,101,32,109,117,115,116,32,98,101,32,89,71,77,101,97,115,117,114,101,77,111,100,101,85,110,100,101,102,105,110,101,100,0,97,118,97,105,108,97,98,108,101,72,101,105,103,104,116,32,105,115,32,105,110,100,101,102,105,110,105,116,101,32,115,111,32,104,101,105,103,104,116,77,101,97,115,117,114,101,77,111,100,101,32,109,117,115,116,32,98,101,32,89,71,77,101,97,115,117,114,101,77,111,100,101,85,110,100,101,102,105,110,101,100,0,102,108,101,120,0,115,116,114,101,116,99,104,0,109,117,108,116,105,108,105,110,101,45,115,116,114,101,116,99,104,0,69,120,112,101,99,116,101,100,32,110,111,100,101,32,116,111,32,104,97,118,101,32,99,117,115,116,111,109,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,0,109,101,97,115,117,114,101,0,69,120,112,101,99,116,32,99,117,115,116,111,109,32,98,97,115,101,108,105,110,101,32,102,117,110,99,116,105,111,110,32,116,111,32,110,111,116,32,114,101,116,117,114,110,32,78,97,78,0,97,98,115,45,109,101,97,115,117,114,101,0,97,98,115,45,108,97,121,111,117,116,0,78,111,100,101,0,99,114,101,97,116,101,68,101,102,97,117,108,116,0,99,114,101,97,116,101,87,105,116,104,67,111,110,102,105,103,0,100,101,115,116,114,111,121,0,114,101,115,101,116,0,99,111,112,121,83,116,121,108,101,0,115,101,116,80,111,115,105,116,105,111,110,84,121,112,101,0,115,101,116,80,111,115,105,116,105,111,110,0,115,101,116,80,111,115,105,116,105,111,110,80,101,114,99,101,110,116,0,115,101,116,65,108,105,103,110,67,111,110,116,101,110,116,0,115,101,116,65,108,105,103,110,73,116,101,109,115,0,115,101,116,65,108,105,103,110,83,101,108,102,0,115,101,116,70,108,101,120,68,105,114,101,99,116,105,111,110,0,115,101,116,70,108,101,120,87,114,97,112,0,115,101,116,74,117,115,116,105,102,121,67,111,110,116,101,110,116,0,115,101,116,77,97,114,103,105,110,0,115,101,116,77,97,114,103,105,110,80,101,114,99,101,110,116,0,115,101,116,77,97,114,103,105,110,65,117,116,111,0,115,101,116,79,118,101,114,102,108,111,119,0,115,101,116,68,105,115,112,108,97,121,0,115,101,116,70,108,101,120,0,115,101,116,70,108,101,120,66,97,115,105,115,0,115,101,116,70,108,101,120,66,97,115,105,115,80,101,114,99,101,110,116,0,115,101,116,70,108,101,120,71,114,111,119,0,115,101,116,70,108,101,120,83,104,114,105,110,107,0,115,101,116,87,105,100,116,104,0,115,101,116,87,105,100,116,104,80,101,114,99,101,110,116,0,115,101,116,87,105,100,116,104,65,117,116,111,0,115,101,116,72,101,105,103,104,116,0,115,101,116,72,101,105,103,104,116,80,101,114,99,101,110,116,0,115,101,116,72,101,105,103,104,116,65,117,116,111,0,115,101,116,77,105,110,87,105,100,116,104,0,115,101,116,77,105,110,87,105,100,116,104,80,101,114,99,101,110,116,0,115,101,116,77,105,110,72,101,105,103,104,116,0,115,101,116,77,105,110,72,101,105,103,104,116,80,101,114,99,101,110,116,0,115,101,116,77,97,120,87,105,100,116,104,0,115,101,116,77,97,120,87,105,100,116,104,80,101,114,99,101,110,116,0,115,101,116,77,97,120,72,101,105,103,104,116,0,115,101,116,77,97,120,72,101,105,103,104,116,80,101,114,99,101,110,116,0,115,101,116,65,115,112,101,99,116,82,97,116,105,111,0,115,101,116,66,111,114,100,101,114,0,115,101,116,80,97,100,100,105,110,103,0,115,101,116,80,97,100,100,105,110,103,80,101,114,99,101,110,116,0,103,101,116,80,111,115,105,116,105,111,110,84,121,112,101,0,103,101,116,80,111,115,105,116,105,111,110,0,103,101,116,65,108,105,103,110,67,111,110,116,101,110,116,0,103,101,116,65,108,105,103,110,73,116,101,109,115,0,103,101,116,65,108,105,103,110,83,101,108,102,0,103,101,116,70,108,101,120,68,105,114,101,99,116,105,111,110,0,103,101,116,70,108,101,120,87,114,97,112,0,103,101,116,74,117,115,116,105,102,121,67,111,110,116,101,110,116,0,103,101,116,77,97,114,103,105,110,0,103,101,116,70,108,101,120,66,97,115,105,115,0,103,101,116,70,108,101,120,71,114,111,119,0,103,101,116,70,108,101,120,83,104,114,105,110,107,0,103,101,116,87,105,100,116,104,0,103,101,116,72,101,105,103,104,116,0,103,101,116,77,105,110,87,105,100,116,104,0,103,101,116,77,105,110,72,101,105,103,104,116,0,103,101,116,77,97,120,87,105,100,116,104,0,103,101,116,77,97,120,72,101,105,103,104,116,0,103,101,116,65,115,112,101,99,116,82,97,116,105,111,0,103,101,116,66,111,114,100,101,114,0,103,101,116,79,118,101,114,102,108,111,119,0,103,101,116,68,105,115,112,108,97,121,0,103,101,116,80,97,100,100,105,110,103,0,105,110,115,101,114,116,67,104,105,108,100,0,114,101,109,111,118,101,67,104,105,108,100,0,103,101,116,67,104,105,108,100,67,111,117,110,116,0,103,101,116,80,97,114,101,110,116,0,103,101,116,67,104,105,108,100,0,115,101,116,77,101,97,115,117,114,101,70,117,110,99,0,117,110,115,101,116,77,101,97,115,117,114,101,70,117,110,99,0,109,97,114,107,68,105,114,116,121,0,105,115,68,105,114,116,121,0,99,97,108,99,117,108,97,116,101,76,97,121,111,117,116,0,103,101,116,67,111,109,112,117,116,101,100,76,101,102,116,0,103,101,116,67,111,109,112,117,116,101,100,82,105,103,104,116,0,103,101,116,67,111,109,112,117,116,101,100,84,111,112,0,103,101,116,67,111,109,112,117,116,101,100,66,111,116,116,111,109,0,103,101,116,67,111,109,112,117,116,101,100,87,105,100,116,104,0,103,101,116,67,111,109,112,117,116,101,100,72,101,105,103,104,116,0,103,101,116,67,111,109,112,117,116,101,100,76,97,121,111,117,116,0,103,101,116,67,111,109,112,117,116,101,100,77,97,114,103,105,110,0,103,101,116,67,111,109,112,117,116,101,100,66,111,114,100,101,114,0,103,101,116,67,111,109,112,117,116,101,100,80,97,100,100,105,110,103,0,67,111,110,102,105,103,0,99,114,101,97,116,101,0,115,101,116,69,120,112,101,114,105,109,101,110,116,97,108,70,101,97,116,117,114,101,69,110,97,98,108,101,100,0,115,101,116,80,111,105,110,116,83,99,97,108,101,70,97,99,116,111,114,0,105,115,69,120,112,101,114,105,109,101,110,116,97,108,70,101,97,116,117,114,101,69,110,97,98,108,101,100,0,86,97,108,117,101,0,76,97,121,111,117,116,0,83,105,122,101,0,103,101,116,73,110,115,116,97,110,99,101,67,111,117,110,116,0,73,110,116,54,52,0,1,1,1,2,2,4,4,4,4,8,8,4,8,118,111,105,100,0,98,111,111,108,0,115,116,100,58,58,115,116,114,105,110,103,0,99,98,70,117,110,99,116,105,111,110,32,38,0,99,111,110,115,116,32,99,98,70,117,110,99,116,105,111,110,32,38,0,69,120,116,101,114,110,97,108,0,66,117,102,102,101,114,0,78,66,105,110,100,73,68,0,78,66,105,110,100,0,98,105,110,100,95,118,97,108,117,101,0,114,101,102,108,101,99,116,0,113,117,101,114,121,84,121,112,101,0,108,97,108,108,111,99,0,108,114,101,115,101,116,0,123,114,101,116,117,114,110,40,95,110,98,105,110,100,46,99,97,108,108,98,97,99,107,83,105,103,110,97,116,117,114,101,76,105,115,116,91,36,48,93,46,97,112,112,108,121,40,116,104,105,115,44,97,114,103,117,109,101,110,116,115,41,41,59,125,0,95,110,98,105,110,100,95,110,101,119,0,17,0,10,0,17,17,17,0,0,0,0,5,0,0,0,0,0,0,9,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,15,10,17,17,17,3,10,7,0,1,19,9,11,11,0,0,9,6,11,0,0,11,0,6,17,0,0,0,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,10,10,17,17,17,0,10,0,0,2,0,9,11,0,0,0,9,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,13,0,0,0,0,9,14,0,0,0,0,0,14,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,15,0,0,0,0,9,16,0,0,0,0,0,16,0,0,16,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,10,0,0,0,0,9,11,0,0,0,0,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,45,43,32,32,32,48,88,48,120,0,40,110,117,108,108,41,0,45,48,88,43,48,88,32,48,88,45,48,120,43,48,120,32,48,120,0,105,110,102,0,73,78,70,0,110,97,110,0,78,65,78,0,48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,46,0,84,33,34,25,13,1,2,3,17,75,28,12,16,4,11,29,18,30,39,104,110,111,112,113,98,32,5,6,15,19,20,21,26,8,22,7,40,36,23,24,9,10,14,27,31,37,35,131,130,125,38,42,43,60,61,62,63,67,71,74,77,88,89,90,91,92,93,94,95,96,97,99,100,101,102,103,105,106,107,108,114,115,116,121,122,123,124,0,73,108,108,101,103,97,108,32,98,121,116,101,32,115,101,113,117,101,110,99,101,0,68,111,109,97,105,110,32,101,114,114,111,114,0,82,101,115,117,108,116,32,110,111,116,32,114,101,112,114,101,115,101,110,116,97,98,108,101,0,78,111,116,32,97,32,116,116,121,0,80,101,114,109,105,115,115,105,111,110,32,100,101,110,105,101,100,0,79,112,101,114,97,116,105,111,110,32,110,111,116,32,112,101,114,109,105,116,116,101,100,0,78,111,32,115,117,99,104,32,102,105,108,101,32,111,114,32,100,105,114,101,99,116,111,114,121,0,78,111,32,115,117,99,104,32,112,114,111,99,101,115,115,0,70,105,108,101,32,101,120,105,115,116,115,0,86,97,108,117,101,32,116,111,111,32,108,97,114,103,101,32,102,111,114,32,100,97,116,97,32,116,121,112,101,0,78,111,32,115,112,97,99,101,32,108,101,102,116,32,111,110,32,100,101,118,105,99,101,0,79,117,116,32,111,102,32,109,101,109,111,114,121,0,82,101,115,111,117,114,99,101,32,98,117,115,121,0,73,110,116,101,114,114,117,112,116,101,100,32,115,121,115,116,101,109,32,99,97,108,108,0,82,101,115,111,117,114,99,101,32,116,101,109,112,111,114,97,114,105,108,121,32,117,110,97,118,97,105,108,97,98,108,101,0,73,110,118,97,108,105,100,32,115,101,101,107,0,67,114,111,115,115,45,100,101,118,105,99,101,32,108,105,110,107,0,82,101,97,100,45,111,110,108,121,32,102,105,108,101,32,115,121,115,116,101,109,0,68,105,114,101,99,116,111,114,121,32,110,111,116,32,101,109,112,116,121,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,112,101,101,114,0,79,112,101,114,97,116,105,111,110,32,116,105,109,101,100,32,111,117,116,0,67,111,110,110,101,99,116,105,111,110,32,114,101,102,117,115,101,100,0,72,111,115,116,32,105,115,32,100,111,119,110,0,72,111,115,116,32,105,115,32,117,110,114,101,97,99,104,97,98,108,101,0,65,100,100,114,101,115,115,32,105,110,32,117,115,101,0,66,114,111,107,101,110,32,112,105,112,101,0,73,47,79,32,101,114,114,111,114,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,32,111,114,32,97,100,100,114,101,115,115,0,66,108,111,99,107,32,100,101,118,105,99,101,32,114,101,113,117,105,114,101,100,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,0,78,111,116,32,97,32,100,105,114,101,99,116,111,114,121,0,73,115,32,97,32,100,105,114,101,99,116,111,114,121,0,84,101,120,116,32,102,105,108,101,32,98,117,115,121,0,69,120,101,99,32,102,111,114,109,97,116,32,101,114,114,111,114,0,73,110,118,97,108,105,100,32,97,114,103,117,109,101,110,116,0,65,114,103,117,109,101,110,116,32,108,105,115,116,32,116,111,111,32,108,111,110,103,0,83,121,109,98,111,108,105,99,32,108,105,110,107,32,108,111,111,112,0,70,105,108,101,110,97,109,101,32,116,111,111,32,108,111,110,103,0,84,111,111,32,109,97,110,121,32,111,112,101,110,32,102,105,108,101,115,32,105,110,32,115,121,115,116,101,109,0,78,111,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,115,32,97,118,97,105,108,97,98,108,101,0,66,97,100,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,0,78,111,32,99,104,105,108,100,32,112,114,111,99,101,115,115,0,66,97,100,32,97,100,100,114,101,115,115,0,70,105,108,101,32,116,111,111,32,108,97,114,103,101,0,84,111,111,32,109,97,110,121,32,108,105,110,107,115,0,78,111,32,108,111,99,107,115,32,97,118,97,105,108,97,98,108,101,0,82,101,115,111,117,114,99,101,32,100,101,97,100,108,111,99,107,32,119,111,117,108,100,32,111,99,99,117,114,0,83,116,97,116,101,32,110,111,116,32,114,101,99,111,118,101,114,97,98,108,101,0,80,114,101,118,105,111,117,115,32,111,119,110,101,114,32,100,105,101,100,0,79,112,101,114,97,116,105,111,110,32,99,97,110,99,101,108,101,100,0,70,117,110,99,116,105,111,110,32,110,111,116,32,105,109,112,108,101,109,101,110,116,101,100,0,78,111,32,109,101,115,115,97,103,101,32,111,102,32,100,101,115,105,114,101,100,32,116,121,112,101,0,73,100,101,110,116,105,102,105,101,114,32,114,101,109,111,118,101,100,0,68,101,118,105,99,101,32,110,111,116,32,97,32,115,116,114,101,97,109,0,78,111,32,100,97,116,97,32,97,118,97,105,108,97,98,108,101,0,68,101,118,105,99,101,32,116,105,109,101,111,117,116,0,79,117,116,32,111,102,32,115,116,114,101,97,109,115,32,114,101,115,111,117,114,99,101,115,0,76,105,110,107,32,104,97,115,32,98,101,101,110,32,115,101,118,101,114,101,100,0,80,114,111,116,111,99,111,108,32,101,114,114,111,114,0,66,97,100,32,109,101,115,115,97,103,101,0,70,105,108,101,32,100,101,115,99,114,105,112,116,111,114,32,105,110,32,98,97,100,32,115,116,97,116,101,0,78,111,116,32,97,32,115,111,99,107,101,116,0,68,101,115,116,105,110,97,116,105,111,110,32,97,100,100,114,101,115,115,32,114,101,113,117,105,114,101,100,0,77,101,115,115,97,103,101,32,116,111,111,32,108,97,114,103,101,0,80,114,111,116,111,99,111,108,32,119,114,111,110,103,32,116,121,112,101,32,102,111,114,32,115,111,99,107,101,116,0,80,114,111,116,111,99,111,108,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,80,114,111,116,111,99,111,108,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,83,111,99,107,101,116,32,116,121,112,101,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,78,111,116,32,115,117,112,112,111,114,116,101,100,0,80,114,111,116,111,99,111,108,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,65,100,100,114,101,115,115,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,32,98,121,32,112,114,111,116,111,99,111,108,0,65,100,100,114,101,115,115,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,78,101,116,119,111,114,107,32,105,115,32,100,111,119,110,0,78,101,116,119,111,114,107,32,117,110,114,101,97,99,104,97,98,108,101,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,110,101,116,119,111,114,107,0,67,111,110,110,101,99,116,105,111,110,32,97,98,111,114,116,101,100,0,78,111,32,98,117,102,102,101,114,32,115,112,97,99,101,32,97,118,97,105,108,97,98,108,101,0,83,111,99,107,101,116,32,105,115,32,99,111,110,110,101,99,116,101,100,0,83,111,99,107,101,116,32,110,111,116,32,99,111,110,110,101,99,116,101,100,0,67,97,110,110,111,116,32,115,101,110,100,32,97,102,116,101,114,32,115,111,99,107,101,116,32,115,104,117,116,100,111,119,110,0,79,112,101,114,97,116,105,111,110,32,97,108,114,101,97,100,121,32,105,110,32,112,114,111,103,114,101,115,115,0,79,112,101,114,97,116,105,111,110,32,105,110,32,112,114,111,103,114,101,115,115,0,83,116,97,108,101,32,102,105,108,101,32,104,97,110,100,108,101,0,82,101,109,111,116,101,32,73,47,79,32,101,114,114,111,114,0,81,117,111,116,97,32,101,120,99,101,101,100,101,100,0,78,111,32,109,101,100,105,117,109,32,102,111,117,110,100,0,87,114,111,110,103,32,109,101,100,105,117,109,32,116,121,112,101,0,78,111,32,101,114,114,111,114,32,105,110,102,111,114,109,97,116,105,111,110,0,0],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE);var tempDoublePtr=STATICTOP;STATICTOP+=16;function _atexit(i,u){__ATEXIT__.unshift({func:i,arg:u})}function ___cxa_atexit(){return _atexit.apply(null,arguments)}function _abort(){Module.abort()}function __ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj(){Module.printErr("missing function: _ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj"),abort(-1)}function __decorate(i,u,f,c){var g=arguments.length,t=g<3?u:c===null?c=Object.getOwnPropertyDescriptor(u,f):c,C;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")t=Reflect.decorate(i,u,f,c);else for(var A=i.length-1;A>=0;A--)(C=i[A])&&(t=(g<3?C(t):g>3?C(u,f,t):C(u,f))||t);return g>3&&t&&Object.defineProperty(u,f,t),t}function _defineHidden(i){return function(u,f){Object.defineProperty(u,f,{configurable:!1,enumerable:!1,value:i,writable:!0})}}var _nbind={};function __nbind_free_external(i){_nbind.externalList[i].dereference(i)}function __nbind_reference_external(i){_nbind.externalList[i].reference()}function _llvm_stackrestore(i){var u=_llvm_stacksave,f=u.LLVM_SAVEDSTACKS[i];u.LLVM_SAVEDSTACKS.splice(i,1),Runtime.stackRestore(f)}function __nbind_register_pool(i,u,f,c){_nbind.Pool.pageSize=i,_nbind.Pool.usedPtr=u/4,_nbind.Pool.rootPtr=f,_nbind.Pool.pagePtr=c/4,HEAP32[u/4]=16909060,HEAP8[u]==1&&(_nbind.bigEndian=!0),HEAP32[u/4]=0,_nbind.makeTypeKindTbl=(t={},t[1024]=_nbind.PrimitiveType,t[64]=_nbind.Int64Type,t[2048]=_nbind.BindClass,t[3072]=_nbind.BindClassPtr,t[4096]=_nbind.SharedClassPtr,t[5120]=_nbind.ArrayType,t[6144]=_nbind.ArrayType,t[7168]=_nbind.CStringType,t[9216]=_nbind.CallbackType,t[10240]=_nbind.BindType,t),_nbind.makeTypeNameTbl={Buffer:_nbind.BufferType,External:_nbind.ExternalType,Int64:_nbind.Int64Type,_nbind_new:_nbind.CreateValueType,bool:_nbind.BooleanType,"cbFunction &":_nbind.CallbackType,"const cbFunction &":_nbind.CallbackType,"const std::string &":_nbind.StringType,"std::string":_nbind.StringType},Module.toggleLightGC=_nbind.toggleLightGC,_nbind.callUpcast=Module.dynCall_ii;var g=_nbind.makeType(_nbind.constructType,{flags:2048,id:0,name:""});g.proto=Module,_nbind.BindClass.list.push(g);var t}function _emscripten_set_main_loop_timing(i,u){if(Browser.mainLoop.timingMode=i,Browser.mainLoop.timingValue=u,!Browser.mainLoop.func)return 1;if(i==0)Browser.mainLoop.scheduler=function(){var C=Math.max(0,Browser.mainLoop.tickStartTime+u-_emscripten_get_now())|0;setTimeout(Browser.mainLoop.runner,C)},Browser.mainLoop.method="timeout";else if(i==1)Browser.mainLoop.scheduler=function(){Browser.requestAnimationFrame(Browser.mainLoop.runner)},Browser.mainLoop.method="rAF";else if(i==2){if(!window.setImmediate){let t=function(C){C.source===window&&C.data===c&&(C.stopPropagation(),f.shift()())};var g=t,f=[],c="setimmediate";window.addEventListener("message",t,!0),window.setImmediate=function(A){f.push(A),ENVIRONMENT_IS_WORKER?(Module.setImmediates===void 0&&(Module.setImmediates=[]),Module.setImmediates.push(A),window.postMessage({target:c})):window.postMessage(c,"*")}}Browser.mainLoop.scheduler=function(){window.setImmediate(Browser.mainLoop.runner)},Browser.mainLoop.method="immediate"}return 0}function _emscripten_get_now(){abort()}function _emscripten_set_main_loop(i,u,f,c,g){Module.noExitRuntime=!0,assert(!Browser.mainLoop.func,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters."),Browser.mainLoop.func=i,Browser.mainLoop.arg=c;var t;typeof c!="undefined"?t=function(){Module.dynCall_vi(i,c)}:t=function(){Module.dynCall_v(i)};var C=Browser.mainLoop.currentlyRunningMainloop;if(Browser.mainLoop.runner=function(){if(!ABORT){if(Browser.mainLoop.queue.length>0){var x=Date.now(),D=Browser.mainLoop.queue.shift();if(D.func(D.arg),Browser.mainLoop.remainingBlockers){var L=Browser.mainLoop.remainingBlockers,N=L%1==0?L-1:Math.floor(L);D.counted?Browser.mainLoop.remainingBlockers=N:(N=N+.5,Browser.mainLoop.remainingBlockers=(8*L+N)/9)}if(console.log('main loop blocker "'+D.name+'" took '+(Date.now()-x)+" ms"),Browser.mainLoop.updateStatus(),C1&&Browser.mainLoop.currentFrameNumber%Browser.mainLoop.timingValue!=0){Browser.mainLoop.scheduler();return}else Browser.mainLoop.timingMode==0&&(Browser.mainLoop.tickStartTime=_emscripten_get_now());Browser.mainLoop.method==="timeout"&&Module.ctx&&(Module.printErr("Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!"),Browser.mainLoop.method=""),Browser.mainLoop.runIter(t),!(C0?_emscripten_set_main_loop_timing(0,1e3/u):_emscripten_set_main_loop_timing(1,1),Browser.mainLoop.scheduler()),f)throw"SimulateInfiniteLoop"}var Browser={mainLoop:{scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause:function(){Browser.mainLoop.scheduler=null,Browser.mainLoop.currentlyRunningMainloop++},resume:function(){Browser.mainLoop.currentlyRunningMainloop++;var i=Browser.mainLoop.timingMode,u=Browser.mainLoop.timingValue,f=Browser.mainLoop.func;Browser.mainLoop.func=null,_emscripten_set_main_loop(f,0,!1,Browser.mainLoop.arg,!0),_emscripten_set_main_loop_timing(i,u),Browser.mainLoop.scheduler()},updateStatus:function(){if(Module.setStatus){var i=Module.statusMessage||"Please wait...",u=Browser.mainLoop.remainingBlockers,f=Browser.mainLoop.expectedBlockers;u?u=6;){var Le=J>>Te-6&63;Te-=6,De+=Se[Le]}return Te==2?(De+=Se[(J&3)<<4],De+=me+me):Te==4&&(De+=Se[(J&15)<<2],De+=me),De}h.src="data:audio/x-"+C.substr(-3)+";base64,"+Q(t),L(h)},h.src=$,Browser.safeSetTimeout(function(){L(h)},1e4)}else return N()},Module.preloadPlugins.push(u);function f(){Browser.pointerLock=document.pointerLockElement===Module.canvas||document.mozPointerLockElement===Module.canvas||document.webkitPointerLockElement===Module.canvas||document.msPointerLockElement===Module.canvas}var c=Module.canvas;c&&(c.requestPointerLock=c.requestPointerLock||c.mozRequestPointerLock||c.webkitRequestPointerLock||c.msRequestPointerLock||function(){},c.exitPointerLock=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock||document.msExitPointerLock||function(){},c.exitPointerLock=c.exitPointerLock.bind(document),document.addEventListener("pointerlockchange",f,!1),document.addEventListener("mozpointerlockchange",f,!1),document.addEventListener("webkitpointerlockchange",f,!1),document.addEventListener("mspointerlockchange",f,!1),Module.elementPointerLock&&c.addEventListener("click",function(g){!Browser.pointerLock&&Module.canvas.requestPointerLock&&(Module.canvas.requestPointerLock(),g.preventDefault())},!1))},createContext:function(i,u,f,c){if(u&&Module.ctx&&i==Module.canvas)return Module.ctx;var g,t;if(u){var C={antialias:!1,alpha:!1};if(c)for(var A in c)C[A]=c[A];t=GL.createContext(i,C),t&&(g=GL.getContext(t).GLctx)}else g=i.getContext("2d");return g?(f&&(u||assert(typeof GLctx=="undefined","cannot set in module if GLctx is used, but we are a non-GL context that would replace it"),Module.ctx=g,u&&GL.makeContextCurrent(t),Module.useWebGL=u,Browser.moduleContextCreatedCallbacks.forEach(function(x){x()}),Browser.init()),g):null},destroyContext:function(i,u,f){},fullscreenHandlersInstalled:!1,lockPointer:void 0,resizeCanvas:void 0,requestFullscreen:function(i,u,f){Browser.lockPointer=i,Browser.resizeCanvas=u,Browser.vrDevice=f,typeof Browser.lockPointer=="undefined"&&(Browser.lockPointer=!0),typeof Browser.resizeCanvas=="undefined"&&(Browser.resizeCanvas=!1),typeof Browser.vrDevice=="undefined"&&(Browser.vrDevice=null);var c=Module.canvas;function g(){Browser.isFullscreen=!1;var C=c.parentNode;(document.fullscreenElement||document.mozFullScreenElement||document.msFullscreenElement||document.webkitFullscreenElement||document.webkitCurrentFullScreenElement)===C?(c.exitFullscreen=document.exitFullscreen||document.cancelFullScreen||document.mozCancelFullScreen||document.msExitFullscreen||document.webkitCancelFullScreen||function(){},c.exitFullscreen=c.exitFullscreen.bind(document),Browser.lockPointer&&c.requestPointerLock(),Browser.isFullscreen=!0,Browser.resizeCanvas&&Browser.setFullscreenCanvasSize()):(C.parentNode.insertBefore(c,C),C.parentNode.removeChild(C),Browser.resizeCanvas&&Browser.setWindowedCanvasSize()),Module.onFullScreen&&Module.onFullScreen(Browser.isFullscreen),Module.onFullscreen&&Module.onFullscreen(Browser.isFullscreen),Browser.updateCanvasDimensions(c)}Browser.fullscreenHandlersInstalled||(Browser.fullscreenHandlersInstalled=!0,document.addEventListener("fullscreenchange",g,!1),document.addEventListener("mozfullscreenchange",g,!1),document.addEventListener("webkitfullscreenchange",g,!1),document.addEventListener("MSFullscreenChange",g,!1));var t=document.createElement("div");c.parentNode.insertBefore(t,c),t.appendChild(c),t.requestFullscreen=t.requestFullscreen||t.mozRequestFullScreen||t.msRequestFullscreen||(t.webkitRequestFullscreen?function(){t.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)}:null)||(t.webkitRequestFullScreen?function(){t.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}:null),f?t.requestFullscreen({vrDisplay:f}):t.requestFullscreen()},requestFullScreen:function(i,u,f){return Module.printErr("Browser.requestFullScreen() is deprecated. Please call Browser.requestFullscreen instead."),Browser.requestFullScreen=function(c,g,t){return Browser.requestFullscreen(c,g,t)},Browser.requestFullscreen(i,u,f)},nextRAF:0,fakeRequestAnimationFrame:function(i){var u=Date.now();if(Browser.nextRAF===0)Browser.nextRAF=u+1e3/60;else for(;u+2>=Browser.nextRAF;)Browser.nextRAF+=1e3/60;var f=Math.max(Browser.nextRAF-u,0);setTimeout(i,f)},requestAnimationFrame:function(u){typeof window=="undefined"?Browser.fakeRequestAnimationFrame(u):(window.requestAnimationFrame||(window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame||Browser.fakeRequestAnimationFrame),window.requestAnimationFrame(u))},safeCallback:function(i){return function(){if(!ABORT)return i.apply(null,arguments)}},allowAsyncCallbacks:!0,queuedAsyncCallbacks:[],pauseAsyncCallbacks:function(){Browser.allowAsyncCallbacks=!1},resumeAsyncCallbacks:function(){if(Browser.allowAsyncCallbacks=!0,Browser.queuedAsyncCallbacks.length>0){var i=Browser.queuedAsyncCallbacks;Browser.queuedAsyncCallbacks=[],i.forEach(function(u){u()})}},safeRequestAnimationFrame:function(i){return Browser.requestAnimationFrame(function(){ABORT||(Browser.allowAsyncCallbacks?i():Browser.queuedAsyncCallbacks.push(i))})},safeSetTimeout:function(i,u){return Module.noExitRuntime=!0,setTimeout(function(){ABORT||(Browser.allowAsyncCallbacks?i():Browser.queuedAsyncCallbacks.push(i))},u)},safeSetInterval:function(i,u){return Module.noExitRuntime=!0,setInterval(function(){ABORT||Browser.allowAsyncCallbacks&&i()},u)},getMimetype:function(i){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",bmp:"image/bmp",ogg:"audio/ogg",wav:"audio/wav",mp3:"audio/mpeg"}[i.substr(i.lastIndexOf(".")+1)]},getUserMedia:function(i){window.getUserMedia||(window.getUserMedia=navigator.getUserMedia||navigator.mozGetUserMedia),window.getUserMedia(i)},getMovementX:function(i){return i.movementX||i.mozMovementX||i.webkitMovementX||0},getMovementY:function(i){return i.movementY||i.mozMovementY||i.webkitMovementY||0},getMouseWheelDelta:function(i){var u=0;switch(i.type){case"DOMMouseScroll":u=i.detail;break;case"mousewheel":u=i.wheelDelta;break;case"wheel":u=i.deltaY;break;default:throw"unrecognized mouse wheel event: "+i.type}return u},mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:function(i){if(Browser.pointerLock)i.type!="mousemove"&&"mozMovementX"in i?Browser.mouseMovementX=Browser.mouseMovementY=0:(Browser.mouseMovementX=Browser.getMovementX(i),Browser.mouseMovementY=Browser.getMovementY(i)),typeof SDL!="undefined"?(Browser.mouseX=SDL.mouseX+Browser.mouseMovementX,Browser.mouseY=SDL.mouseY+Browser.mouseMovementY):(Browser.mouseX+=Browser.mouseMovementX,Browser.mouseY+=Browser.mouseMovementY);else{var u=Module.canvas.getBoundingClientRect(),f=Module.canvas.width,c=Module.canvas.height,g=typeof window.scrollX!="undefined"?window.scrollX:window.pageXOffset,t=typeof window.scrollY!="undefined"?window.scrollY:window.pageYOffset;if(i.type==="touchstart"||i.type==="touchend"||i.type==="touchmove"){var C=i.touch;if(C===void 0)return;var A=C.pageX-(g+u.left),x=C.pageY-(t+u.top);A=A*(f/u.width),x=x*(c/u.height);var D={x:A,y:x};if(i.type==="touchstart")Browser.lastTouches[C.identifier]=D,Browser.touches[C.identifier]=D;else if(i.type==="touchend"||i.type==="touchmove"){var L=Browser.touches[C.identifier];L||(L=D),Browser.lastTouches[C.identifier]=L,Browser.touches[C.identifier]=D}return}var N=i.pageX-(g+u.left),j=i.pageY-(t+u.top);N=N*(f/u.width),j=j*(c/u.height),Browser.mouseMovementX=N-Browser.mouseX,Browser.mouseMovementY=j-Browser.mouseY,Browser.mouseX=N,Browser.mouseY=j}},asyncLoad:function(i,u,f,c){var g=c?"":getUniqueRunDependency("al "+i);Module.readAsync(i,function(t){assert(t,'Loading data file "'+i+'" failed (no arrayBuffer).'),u(new Uint8Array(t)),g&&removeRunDependency(g)},function(t){if(f)f();else throw'Loading data file "'+i+'" failed.'}),g&&addRunDependency(g)},resizeListeners:[],updateResizeListeners:function(){var i=Module.canvas;Browser.resizeListeners.forEach(function(u){u(i.width,i.height)})},setCanvasSize:function(i,u,f){var c=Module.canvas;Browser.updateCanvasDimensions(c,i,u),f||Browser.updateResizeListeners()},windowedWidth:0,windowedHeight:0,setFullscreenCanvasSize:function(){if(typeof SDL!="undefined"){var i=HEAPU32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2];i=i|8388608,HEAP32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2]=i}Browser.updateResizeListeners()},setWindowedCanvasSize:function(){if(typeof SDL!="undefined"){var i=HEAPU32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2];i=i&~8388608,HEAP32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2]=i}Browser.updateResizeListeners()},updateCanvasDimensions:function(i,u,f){u&&f?(i.widthNative=u,i.heightNative=f):(u=i.widthNative,f=i.heightNative);var c=u,g=f;if(Module.forcedAspectRatio&&Module.forcedAspectRatio>0&&(c/g>2];return u},getStr:function(){var i=Pointer_stringify(SYSCALLS.get());return i},get64:function(){var i=SYSCALLS.get(),u=SYSCALLS.get();return i>=0?assert(u===0):assert(u===-1),i},getZero:function(){assert(SYSCALLS.get()===0)}};function ___syscall6(i,u){SYSCALLS.varargs=u;try{var f=SYSCALLS.getStreamFromFD();return FS.close(f),0}catch(c){return(typeof FS=="undefined"||!(c instanceof FS.ErrnoError))&&abort(c),-c.errno}}function ___syscall54(i,u){SYSCALLS.varargs=u;try{return 0}catch(f){return(typeof FS=="undefined"||!(f instanceof FS.ErrnoError))&&abort(f),-f.errno}}function _typeModule(i){var u=[[0,1,"X"],[1,1,"const X"],[128,1,"X *"],[256,1,"X &"],[384,1,"X &&"],[512,1,"std::shared_ptr"],[640,1,"std::unique_ptr"],[5120,1,"std::vector"],[6144,2,"std::array"],[9216,-1,"std::function"]];function f(x,D,L,N,j,$){if(D==1){var h=N&896;(h==128||h==256||h==384)&&(x="X const")}var re;return $?re=L.replace("X",x).replace("Y",j):re=x.replace("X",L).replace("Y",j),re.replace(/([*&]) (?=[*&])/g,"$1")}function c(x,D,L,N,j){throw new Error(x+" type "+L.replace("X",D+"?")+(N?" with flag "+N:"")+" in "+j)}function g(x,D,L,N,j,$,h,re){$===void 0&&($="X"),re===void 0&&(re=1);var ce=L(x);if(ce)return ce;var Q=N(x),oe=Q.placeholderFlag,Se=u[oe];h&&Se&&($=f(h[2],h[0],$,Se[0],"?",!0));var me;oe==0&&(me="Unbound"),oe>=10&&(me="Corrupt"),re>20&&(me="Deeply nested"),me&&c(me,x,$,oe,j||"?");var De=Q.paramList[0],J=g(De,D,L,N,j,$,Se,re+1),Te,Oe={flags:Se[0],id:x,name:"",paramList:[J]},Le=[],ot="?";switch(Q.placeholderFlag){case 1:Te=J.spec;break;case 2:if((J.flags&15360)==1024&&J.spec.ptrSize==1){Oe.flags=7168;break}case 3:case 6:case 5:Te=J.spec,(J.flags&15360)!=2048;break;case 8:ot=""+Q.paramList[1],Oe.paramList.push(Q.paramList[1]);break;case 9:for(var ct=0,Ue=Q.paramList[1];ct>2]=i),i}function _llvm_stacksave(){var i=_llvm_stacksave;return i.LLVM_SAVEDSTACKS||(i.LLVM_SAVEDSTACKS=[]),i.LLVM_SAVEDSTACKS.push(Runtime.stackSave()),i.LLVM_SAVEDSTACKS.length-1}function ___syscall140(i,u){SYSCALLS.varargs=u;try{var f=SYSCALLS.getStreamFromFD(),c=SYSCALLS.get(),g=SYSCALLS.get(),t=SYSCALLS.get(),C=SYSCALLS.get(),A=g;return FS.llseek(f,A,C),HEAP32[t>>2]=f.position,f.getdents&&A===0&&C===0&&(f.getdents=null),0}catch(x){return(typeof FS=="undefined"||!(x instanceof FS.ErrnoError))&&abort(x),-x.errno}}function ___syscall146(i,u){SYSCALLS.varargs=u;try{var f=SYSCALLS.get(),c=SYSCALLS.get(),g=SYSCALLS.get(),t=0;___syscall146.buffer||(___syscall146.buffers=[null,[],[]],___syscall146.printChar=function(L,N){var j=___syscall146.buffers[L];assert(j),N===0||N===10?((L===1?Module.print:Module.printErr)(UTF8ArrayToString(j,0)),j.length=0):j.push(N)});for(var C=0;C>2],x=HEAP32[c+(C*8+4)>>2],D=0;Di.pageSize/2||u>i.pageSize-f){var c=_nbind.typeNameTbl.NBind.proto;return c.lalloc(u)}else return HEAPU32[i.usedPtr]=f+u,i.rootPtr+f},i.lreset=function(u,f){var c=HEAPU32[i.pagePtr];if(c){var g=_nbind.typeNameTbl.NBind.proto;g.lreset(u,f)}else HEAPU32[i.usedPtr]=u},i}();_nbind.Pool=Pool;function constructType(i,u){var f=i==10240?_nbind.makeTypeNameTbl[u.name]||_nbind.BindType:_nbind.makeTypeKindTbl[i],c=new f(u);return typeIdTbl[u.id]=c,_nbind.typeNameTbl[u.name]=c,c}_nbind.constructType=constructType;function getType(i){return typeIdTbl[i]}_nbind.getType=getType;function queryType(i){var u=HEAPU8[i],f=_nbind.structureList[u][1];i/=4,f<0&&(++i,f=HEAPU32[i]+1);var c=Array.prototype.slice.call(HEAPU32.subarray(i+1,i+1+f));return u==9&&(c=[c[0],c.slice(1)]),{paramList:c,placeholderFlag:u}}_nbind.queryType=queryType;function getTypes(i,u){return i.map(function(f){return typeof f=="number"?_nbind.getComplexType(f,constructType,getType,queryType,u):_nbind.typeNameTbl[f]})}_nbind.getTypes=getTypes;function readTypeIdList(i,u){return Array.prototype.slice.call(HEAPU32,i/4,i/4+u)}_nbind.readTypeIdList=readTypeIdList;function readAsciiString(i){for(var u=i;HEAPU8[u++];);return String.fromCharCode.apply("",HEAPU8.subarray(i,u-1))}_nbind.readAsciiString=readAsciiString;function readPolicyList(i){var u={};if(i)for(;;){var f=HEAPU32[i/4];if(!f)break;u[readAsciiString(f)]=!0,i+=4}return u}_nbind.readPolicyList=readPolicyList;function getDynCall(i,u){var f={float32_t:"d",float64_t:"d",int64_t:"d",uint64_t:"d",void:"v"},c=i.map(function(t){return f[t.name]||"i"}).join(""),g=Module["dynCall_"+c];if(!g)throw new Error("dynCall_"+c+" not found for "+u+"("+i.map(function(t){return t.name}).join(", ")+")");return g}_nbind.getDynCall=getDynCall;function addMethod(i,u,f,c){var g=i[u];i.hasOwnProperty(u)&&g?((g.arity||g.arity===0)&&(g=_nbind.makeOverloader(g,g.arity),i[u]=g),g.addMethod(f,c)):(f.arity=c,i[u]=f)}_nbind.addMethod=addMethod;function throwError(i){throw new Error(i)}_nbind.throwError=throwError,_nbind.bigEndian=!1,_a=_typeModule(_typeModule),_nbind.Type=_a.Type,_nbind.makeType=_a.makeType,_nbind.getComplexType=_a.getComplexType,_nbind.structureList=_a.structureList;var BindType=function(i){__extends(u,i);function u(){var f=i!==null&&i.apply(this,arguments)||this;return f.heap=HEAPU32,f.ptrSize=4,f}return u.prototype.needsWireRead=function(f){return!!this.wireRead||!!this.makeWireRead},u.prototype.needsWireWrite=function(f){return!!this.wireWrite||!!this.makeWireWrite},u}(_nbind.Type);_nbind.BindType=BindType;var PrimitiveType=function(i){__extends(u,i);function u(f){var c=i.call(this,f)||this,g=f.flags&32?{32:HEAPF32,64:HEAPF64}:f.flags&8?{8:HEAPU8,16:HEAPU16,32:HEAPU32}:{8:HEAP8,16:HEAP16,32:HEAP32};return c.heap=g[f.ptrSize*8],c.ptrSize=f.ptrSize,c}return u.prototype.needsWireWrite=function(f){return!!f&&!!f.Strict},u.prototype.makeWireWrite=function(f,c){return c&&c.Strict&&function(g){if(typeof g=="number")return g;throw new Error("Type mismatch")}},u}(BindType);_nbind.PrimitiveType=PrimitiveType;function pushCString(i,u){if(i==null){if(u&&u.Nullable)return 0;throw new Error("Type mismatch")}if(u&&u.Strict){if(typeof i!="string")throw new Error("Type mismatch")}else i=i.toString();var f=Module.lengthBytesUTF8(i)+1,c=_nbind.Pool.lalloc(f);return Module.stringToUTF8Array(i,HEAPU8,c,f),c}_nbind.pushCString=pushCString;function popCString(i){return i===0?null:Module.Pointer_stringify(i)}_nbind.popCString=popCString;var CStringType=function(i){__extends(u,i);function u(){var f=i!==null&&i.apply(this,arguments)||this;return f.wireRead=popCString,f.wireWrite=pushCString,f.readResources=[_nbind.resources.pool],f.writeResources=[_nbind.resources.pool],f}return u.prototype.makeWireWrite=function(f,c){return function(g){return pushCString(g,c)}},u}(BindType);_nbind.CStringType=CStringType;var BooleanType=function(i){__extends(u,i);function u(){var f=i!==null&&i.apply(this,arguments)||this;return f.wireRead=function(c){return!!c},f}return u.prototype.needsWireWrite=function(f){return!!f&&!!f.Strict},u.prototype.makeWireRead=function(f){return"!!("+f+")"},u.prototype.makeWireWrite=function(f,c){return c&&c.Strict&&function(g){if(typeof g=="boolean")return g;throw new Error("Type mismatch")}||f},u}(BindType);_nbind.BooleanType=BooleanType;var Wrapper=function(){function i(){}return i.prototype.persist=function(){this.__nbindState|=1},i}();_nbind.Wrapper=Wrapper;function makeBound(i,u){var f=function(c){__extends(g,c);function g(t,C,A,x){var D=c.call(this)||this;if(!(D instanceof g))return new(Function.prototype.bind.apply(g,Array.prototype.concat.apply([null],arguments)));var L=C,N=A,j=x;if(t!==_nbind.ptrMarker){var $=D.__nbindConstructor.apply(D,arguments);L=4096|512,j=HEAPU32[$/4],N=HEAPU32[$/4+1]}var h={configurable:!0,enumerable:!1,value:null,writable:!1},re={__nbindFlags:L,__nbindPtr:N};j&&(re.__nbindShared=j,_nbind.mark(D));for(var ce=0,Q=Object.keys(re);ce>=1;var f=_nbind.valueList[i];return _nbind.valueList[i]=firstFreeValue,firstFreeValue=i,f}else{if(u)return _nbind.popShared(i,u);throw new Error("Invalid value slot "+i)}}_nbind.popValue=popValue;var valueBase=18446744073709552e3;function push64(i){return typeof i=="number"?i:pushValue(i)*4096+valueBase}function pop64(i){return i=3?C=Buffer.from(t):C=new Buffer(t),C.copy(c)}else getBuffer(c).set(t)}}_nbind.commitBuffer=commitBuffer;var dirtyList=[],gcTimer=0;function sweep(){for(var i=0,u=dirtyList;i>2]=DYNAMIC_BASE,staticSealed=!0;function invoke_viiiii(i,u,f,c,g,t){try{Module.dynCall_viiiii(i,u,f,c,g,t)}catch(C){if(typeof C!="number"&&C!=="longjmp")throw C;Module.setThrew(1,0)}}function invoke_vif(i,u,f){try{Module.dynCall_vif(i,u,f)}catch(c){if(typeof c!="number"&&c!=="longjmp")throw c;Module.setThrew(1,0)}}function invoke_vid(i,u,f){try{Module.dynCall_vid(i,u,f)}catch(c){if(typeof c!="number"&&c!=="longjmp")throw c;Module.setThrew(1,0)}}function invoke_fiff(i,u,f,c){try{return Module.dynCall_fiff(i,u,f,c)}catch(g){if(typeof g!="number"&&g!=="longjmp")throw g;Module.setThrew(1,0)}}function invoke_vi(i,u){try{Module.dynCall_vi(i,u)}catch(f){if(typeof f!="number"&&f!=="longjmp")throw f;Module.setThrew(1,0)}}function invoke_vii(i,u,f){try{Module.dynCall_vii(i,u,f)}catch(c){if(typeof c!="number"&&c!=="longjmp")throw c;Module.setThrew(1,0)}}function invoke_ii(i,u){try{return Module.dynCall_ii(i,u)}catch(f){if(typeof f!="number"&&f!=="longjmp")throw f;Module.setThrew(1,0)}}function invoke_viddi(i,u,f,c,g){try{Module.dynCall_viddi(i,u,f,c,g)}catch(t){if(typeof t!="number"&&t!=="longjmp")throw t;Module.setThrew(1,0)}}function invoke_vidd(i,u,f,c){try{Module.dynCall_vidd(i,u,f,c)}catch(g){if(typeof g!="number"&&g!=="longjmp")throw g;Module.setThrew(1,0)}}function invoke_iiii(i,u,f,c){try{return Module.dynCall_iiii(i,u,f,c)}catch(g){if(typeof g!="number"&&g!=="longjmp")throw g;Module.setThrew(1,0)}}function invoke_diii(i,u,f,c){try{return Module.dynCall_diii(i,u,f,c)}catch(g){if(typeof g!="number"&&g!=="longjmp")throw g;Module.setThrew(1,0)}}function invoke_di(i,u){try{return Module.dynCall_di(i,u)}catch(f){if(typeof f!="number"&&f!=="longjmp")throw f;Module.setThrew(1,0)}}function invoke_iid(i,u,f){try{return Module.dynCall_iid(i,u,f)}catch(c){if(typeof c!="number"&&c!=="longjmp")throw c;Module.setThrew(1,0)}}function invoke_iii(i,u,f){try{return Module.dynCall_iii(i,u,f)}catch(c){if(typeof c!="number"&&c!=="longjmp")throw c;Module.setThrew(1,0)}}function invoke_viiddi(i,u,f,c,g,t){try{Module.dynCall_viiddi(i,u,f,c,g,t)}catch(C){if(typeof C!="number"&&C!=="longjmp")throw C;Module.setThrew(1,0)}}function invoke_viiiiii(i,u,f,c,g,t,C){try{Module.dynCall_viiiiii(i,u,f,c,g,t,C)}catch(A){if(typeof A!="number"&&A!=="longjmp")throw A;Module.setThrew(1,0)}}function invoke_dii(i,u,f){try{return Module.dynCall_dii(i,u,f)}catch(c){if(typeof c!="number"&&c!=="longjmp")throw c;Module.setThrew(1,0)}}function invoke_i(i){try{return Module.dynCall_i(i)}catch(u){if(typeof u!="number"&&u!=="longjmp")throw u;Module.setThrew(1,0)}}function invoke_iiiiii(i,u,f,c,g,t){try{return Module.dynCall_iiiiii(i,u,f,c,g,t)}catch(C){if(typeof C!="number"&&C!=="longjmp")throw C;Module.setThrew(1,0)}}function invoke_viiid(i,u,f,c,g){try{Module.dynCall_viiid(i,u,f,c,g)}catch(t){if(typeof t!="number"&&t!=="longjmp")throw t;Module.setThrew(1,0)}}function invoke_viififi(i,u,f,c,g,t,C){try{Module.dynCall_viififi(i,u,f,c,g,t,C)}catch(A){if(typeof A!="number"&&A!=="longjmp")throw A;Module.setThrew(1,0)}}function invoke_viii(i,u,f,c){try{Module.dynCall_viii(i,u,f,c)}catch(g){if(typeof g!="number"&&g!=="longjmp")throw g;Module.setThrew(1,0)}}function invoke_v(i){try{Module.dynCall_v(i)}catch(u){if(typeof u!="number"&&u!=="longjmp")throw u;Module.setThrew(1,0)}}function invoke_viid(i,u,f,c){try{Module.dynCall_viid(i,u,f,c)}catch(g){if(typeof g!="number"&&g!=="longjmp")throw g;Module.setThrew(1,0)}}function invoke_idd(i,u,f){try{return Module.dynCall_idd(i,u,f)}catch(c){if(typeof c!="number"&&c!=="longjmp")throw c;Module.setThrew(1,0)}}function invoke_viiii(i,u,f,c,g){try{Module.dynCall_viiii(i,u,f,c,g)}catch(t){if(typeof t!="number"&&t!=="longjmp")throw t;Module.setThrew(1,0)}}Module.asmGlobalArg={Math,Int8Array,Int16Array,Int32Array,Uint8Array,Uint16Array,Uint32Array,Float32Array,Float64Array,NaN:NaN,Infinity:Infinity},Module.asmLibraryArg={abort,assert,enlargeMemory,getTotalMemory,abortOnCannotGrowMemory,invoke_viiiii,invoke_vif,invoke_vid,invoke_fiff,invoke_vi,invoke_vii,invoke_ii,invoke_viddi,invoke_vidd,invoke_iiii,invoke_diii,invoke_di,invoke_iid,invoke_iii,invoke_viiddi,invoke_viiiiii,invoke_dii,invoke_i,invoke_iiiiii,invoke_viiid,invoke_viififi,invoke_viii,invoke_v,invoke_viid,invoke_idd,invoke_viiii,_emscripten_asm_const_iiiii,_emscripten_asm_const_iiidddddd,_emscripten_asm_const_iiiid,__nbind_reference_external,_emscripten_asm_const_iiiiiiii,_removeAccessorPrefix,_typeModule,__nbind_register_pool,__decorate,_llvm_stackrestore,___cxa_atexit,__extends,__nbind_get_value_object,__ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj,_emscripten_set_main_loop_timing,__nbind_register_primitive,__nbind_register_type,_emscripten_memcpy_big,__nbind_register_function,___setErrNo,__nbind_register_class,__nbind_finish,_abort,_nbind_value,_llvm_stacksave,___syscall54,_defineHidden,_emscripten_set_main_loop,_emscripten_get_now,__nbind_register_callback_signature,_emscripten_asm_const_iiiiii,__nbind_free_external,_emscripten_asm_const_iiii,_emscripten_asm_const_iiididi,___syscall6,_atexit,___syscall140,___syscall146,DYNAMICTOP_PTR,tempDoublePtr,ABORT,STACKTOP,STACK_MAX,cttz_i8,___dso_handle};var asm=function(i,u,f){var c=new i.Int8Array(f),g=new i.Int16Array(f),t=new i.Int32Array(f),C=new i.Uint8Array(f),A=new i.Uint16Array(f),x=new i.Uint32Array(f),D=new i.Float32Array(f),L=new i.Float64Array(f),N=u.DYNAMICTOP_PTR|0,j=u.tempDoublePtr|0,$=u.ABORT|0,h=u.STACKTOP|0,re=u.STACK_MAX|0,ce=u.cttz_i8|0,Q=u.___dso_handle|0,oe=0,Se=0,me=0,De=0,J=i.NaN,Te=i.Infinity,Oe=0,Le=0,ot=0,ct=0,Ue=0,be=0,At=i.Math.floor,Ot=i.Math.abs,Nt=i.Math.sqrt,Je=i.Math.pow,V=i.Math.cos,ne=i.Math.sin,ge=i.Math.tan,Z=i.Math.acos,Ae=i.Math.asin,at=i.Math.atan,it=i.Math.atan2,Ft=i.Math.exp,jt=i.Math.log,hn=i.Math.ceil,Un=i.Math.imul,Jt=i.Math.min,Yt=i.Math.max,cr=i.Math.clz32,w=i.Math.fround,pt=u.abort,Mn=u.assert,Bn=u.enlargeMemory,Xn=u.getTotalMemory,vr=u.abortOnCannotGrowMemory,gr=u.invoke_viiiii,r0=u.invoke_vif,Ci=u.invoke_vid,yo=u.invoke_fiff,Ds=u.invoke_vi,Mu=u.invoke_vii,Gf=u.invoke_ii,iu=u.invoke_viddi,ou=u.invoke_vidd,ol=u.invoke_iiii,ul=u.invoke_diii,Es=u.invoke_di,Uo=u.invoke_iid,sl=u.invoke_iii,Ss=u.invoke_viiddi,Cs=u.invoke_viiiiii,Ti=u.invoke_dii,Fu=u.invoke_i,ll=u.invoke_iiiiii,fl=u.invoke_viiid,cl=u.invoke_viififi,al=u.invoke_viii,Ui=u.invoke_v,Mr=u.invoke_viid,Ac=u.invoke_idd,of=u.invoke_viiii,Ts=u._emscripten_asm_const_iiiii,xs=u._emscripten_asm_const_iiidddddd,dl=u._emscripten_asm_const_iiiid,qi=u.__nbind_reference_external,qo=u._emscripten_asm_const_iiiiiiii,kr=u._removeAccessorPrefix,Fr=u._typeModule,si=u.__nbind_register_pool,H0=u.__decorate,b0=u._llvm_stackrestore,Bt=u.___cxa_atexit,Lu=u.__extends,c0=u.__nbind_get_value_object,Ru=u.__ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj,ks=u._emscripten_set_main_loop_timing,As=u.__nbind_register_primitive,uu=u.__nbind_register_type,wo=u._emscripten_memcpy_big,zo=u.__nbind_register_function,Os=u.___setErrNo,Is=u.__nbind_register_class,uf=u.__nbind_finish,_n=u._abort,Nu=u._nbind_value,Wo=u._llvm_stacksave,su=u.___syscall54,Ps=u._defineHidden,pl=u._emscripten_set_main_loop,Vf=u._emscripten_get_now,hl=u.__nbind_register_callback_signature,Bu=u._emscripten_asm_const_iiiiii,ju=u.__nbind_free_external,sf=u._emscripten_asm_const_iiii,ro=u._emscripten_asm_const_iiididi,Ms=u.___syscall6,ml=u._atexit,Uu=u.___syscall140,G0=u.___syscall146,Fs=w(0);let tt=w(0);function zi(e){e=e|0;var n=0;return n=h,h=h+e|0,h=h+15&-16,n|0}function lu(){return h|0}function Ho(e){e=e|0,h=e}function O0(e,n){e=e|0,n=n|0,h=e,re=n}function vl(e,n){e=e|0,n=n|0,oe||(oe=e,Se=n)}function gl(e){e=e|0,be=e}function fu(){return be|0}function _l(){var e=0,n=0;vn(8104,8,400)|0,vn(8504,408,540)|0,e=9044,n=e+44|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));c[9088]=0,c[9089]=1,t[2273]=0,t[2274]=948,t[2275]=948,Bt(17,8104,Q|0)|0}function Sn(e){e=e|0,lf(e+948|0)}function gt(e){return e=w(e),((Ar(e)|0)&2147483647)>>>0>2139095040|0}function en(e,n,r){e=e|0,n=n|0,r=r|0;e:do if(t[e+(n<<3)+4>>2]|0)e=e+(n<<3)|0;else{if((n|2|0)==3?t[e+60>>2]|0:0){e=e+56|0;break}switch(n|0){case 0:case 2:case 4:case 5:{if(t[e+52>>2]|0){e=e+48|0;break e}break}default:}if(t[e+68>>2]|0){e=e+64|0;break}else{e=(n|1|0)==5?948:r;break}}while(0);return e|0}function I0(e){e=e|0;var n=0;return n=uh(1e3)|0,li(e,(n|0)!=0,2456),t[2276]=(t[2276]|0)+1,vn(n|0,8104,1e3)|0,c[e+2>>0]|0&&(t[n+4>>2]=2,t[n+12>>2]=4),t[n+976>>2]=e,n|0}function li(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0;s=h,h=h+16|0,o=s,n||(t[o>>2]=r,zs(e,5,3197,o)),h=s}function qu(){return I0(956)|0}function Wi(e){e=e|0;var n=0;return n=Tt(1e3)|0,zu(n,e),li(t[e+976>>2]|0,1,2456),t[2276]=(t[2276]|0)+1,t[n+944>>2]=0,n|0}function zu(e,n){e=e|0,n=n|0;var r=0;vn(e|0,n|0,948)|0,af(e+948|0,n+948|0),r=e+960|0,e=n+960|0,n=r+40|0;do t[r>>2]=t[e>>2],r=r+4|0,e=e+4|0;while((r|0)<(n|0))}function Wu(e){e=e|0;var n=0,r=0,o=0,s=0;if(n=e+944|0,r=t[n>>2]|0,r|0&&(Ls(r+948|0,e)|0,t[n>>2]=0),r=fi(e)|0,r|0){n=0;do t[(e0(e,n)|0)+944>>2]=0,n=n+1|0;while((n|0)!=(r|0))}r=e+948|0,o=t[r>>2]|0,s=e+952|0,n=t[s>>2]|0,(n|0)!=(o|0)&&(t[s>>2]=n+(~((n+-4-o|0)>>>2)<<2)),io(r),sh(e),t[2276]=(t[2276]|0)+-1}function Ls(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0;o=t[e>>2]|0,_=e+4|0,r=t[_>>2]|0,l=r;e:do if((o|0)==(r|0))s=o,d=4;else for(e=o;;){if((t[e>>2]|0)==(n|0)){s=e,d=4;break e}if(e=e+4|0,(e|0)==(r|0)){e=0;break}}while(0);return(d|0)==4&&((s|0)!=(r|0)?(o=s+4|0,e=l-o|0,n=e>>2,n&&(Y1(s|0,o|0,e|0)|0,r=t[_>>2]|0),e=s+(n<<2)|0,(r|0)==(e|0)||(t[_>>2]=r+(~((r+-4-e|0)>>>2)<<2)),e=1):e=0),e|0}function fi(e){return e=e|0,(t[e+952>>2]|0)-(t[e+948>>2]|0)>>2|0}function e0(e,n){e=e|0,n=n|0;var r=0;return r=t[e+948>>2]|0,(t[e+952>>2]|0)-r>>2>>>0>n>>>0?e=t[r+(n<<2)>>2]|0:e=0,e|0}function io(e){e=e|0;var n=0,r=0,o=0,s=0;o=h,h=h+32|0,n=o,s=t[e>>2]|0,r=(t[e+4>>2]|0)-s|0,((t[e+8>>2]|0)-s|0)>>>0>r>>>0&&(s=r>>2,z(n,s,s,e+8|0),dr(e,n),Or(n)),h=o}function D0(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0;k=fi(e)|0;do if(k|0){if((t[(e0(e,0)|0)+944>>2]|0)==(e|0)){if(!(Ls(e+948|0,n)|0))break;vn(n+400|0,8504,540)|0,t[n+944>>2]=0,ln(e);break}d=t[(t[e+976>>2]|0)+12>>2]|0,_=e+948|0,y=(d|0)==0,r=0,l=0;do o=t[(t[_>>2]|0)+(l<<2)>>2]|0,(o|0)==(n|0)?ln(e):(s=Wi(o)|0,t[(t[_>>2]|0)+(r<<2)>>2]=s,t[s+944>>2]=e,y||Q4[d&15](o,s,e,r),r=r+1|0),l=l+1|0;while((l|0)!=(k|0));if(r>>>0>>0){y=e+948|0,_=e+952|0,d=r,r=t[_>>2]|0;do l=(t[y>>2]|0)+(d<<2)|0,o=l+4|0,s=r-o|0,n=s>>2,n&&(Y1(l|0,o|0,s|0)|0,r=t[_>>2]|0),s=r,o=l+(n<<2)|0,(s|0)!=(o|0)&&(r=s+(~((s+-4-o|0)>>>2)<<2)|0,t[_>>2]=r),d=d+1|0;while((d|0)!=(k|0))}}while(0)}function Do(e){e=e|0;var n=0,r=0,o=0,s=0;i0(e,(fi(e)|0)==0,2491),i0(e,(t[e+944>>2]|0)==0,2545),n=e+948|0,r=t[n>>2]|0,o=e+952|0,s=t[o>>2]|0,(s|0)!=(r|0)&&(t[o>>2]=s+(~((s+-4-r|0)>>>2)<<2)),io(n),n=e+976|0,r=t[n>>2]|0,vn(e|0,8104,1e3)|0,c[r+2>>0]|0&&(t[e+4>>2]=2,t[e+12>>2]=4),t[n>>2]=r}function i0(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0;s=h,h=h+16|0,o=s,n||(t[o>>2]=r,wn(e,5,3197,o)),h=s}function Rs(){return t[2276]|0}function a0(){var e=0;return e=uh(20)|0,Hu((e|0)!=0,2592),t[2277]=(t[2277]|0)+1,t[e>>2]=t[239],t[e+4>>2]=t[240],t[e+8>>2]=t[241],t[e+12>>2]=t[242],t[e+16>>2]=t[243],e|0}function Hu(e,n){e=e|0,n=n|0;var r=0,o=0;o=h,h=h+16|0,r=o,e||(t[r>>2]=n,wn(0,5,3197,r)),h=o}function V0(e){e=e|0,sh(e),t[2277]=(t[2277]|0)+-1}function bu(e,n){e=e|0,n=n|0;var r=0;n?(i0(e,(fi(e)|0)==0,2629),r=1):(r=0,n=0),t[e+964>>2]=n,t[e+988>>2]=r}function Ns(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;o=h,h=h+16|0,l=o+8|0,s=o+4|0,d=o,t[s>>2]=n,i0(e,(t[n+944>>2]|0)==0,2709),i0(e,(t[e+964>>2]|0)==0,2763),bo(e),n=e+948|0,t[d>>2]=(t[n>>2]|0)+(r<<2),t[l>>2]=t[d>>2],P0(n,l,s)|0,t[(t[s>>2]|0)+944>>2]=e,ln(e),h=o}function bo(e){e=e|0;var n=0,r=0,o=0,s=0,l=0,d=0,_=0;if(r=fi(e)|0,r|0?(t[(e0(e,0)|0)+944>>2]|0)!=(e|0):0){o=t[(t[e+976>>2]|0)+12>>2]|0,s=e+948|0,l=(o|0)==0,n=0;do d=t[(t[s>>2]|0)+(n<<2)>>2]|0,_=Wi(d)|0,t[(t[s>>2]|0)+(n<<2)>>2]=_,t[_+944>>2]=e,l||Q4[o&15](d,_,e,n),n=n+1|0;while((n|0)!=(r|0))}}function P0(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0,we=0,le=0,ie=0,Pe=0,ke=0;Pe=h,h=h+64|0,P=Pe+52|0,_=Pe+48|0,q=Pe+28|0,we=Pe+24|0,le=Pe+20|0,ie=Pe,o=t[e>>2]|0,l=o,n=o+((t[n>>2]|0)-l>>2<<2)|0,o=e+4|0,s=t[o>>2]|0,d=e+8|0;do if(s>>>0<(t[d>>2]|0)>>>0){if((n|0)==(s|0)){t[n>>2]=t[r>>2],t[o>>2]=(t[o>>2]|0)+4;break}Qn(e,n,s,n+4|0),n>>>0<=r>>>0&&(r=(t[o>>2]|0)>>>0>r>>>0?r+4|0:r),t[n>>2]=t[r>>2]}else{o=(s-l>>2)+1|0,s=Q0(e)|0,s>>>0>>0&&$n(e),T=t[e>>2]|0,k=(t[d>>2]|0)-T|0,l=k>>1,z(ie,k>>2>>>0>>1>>>0?l>>>0>>0?o:l:s,n-T>>2,e+8|0),T=ie+8|0,o=t[T>>2]|0,l=ie+12|0,k=t[l>>2]|0,d=k,y=o;do if((o|0)==(k|0)){if(k=ie+4|0,o=t[k>>2]|0,ke=t[ie>>2]|0,s=ke,o>>>0<=ke>>>0){o=d-s>>1,o=(o|0)==0?1:o,z(q,o,o>>>2,t[ie+16>>2]|0),t[we>>2]=t[k>>2],t[le>>2]=t[T>>2],t[_>>2]=t[we>>2],t[P>>2]=t[le>>2],s0(q,_,P),o=t[ie>>2]|0,t[ie>>2]=t[q>>2],t[q>>2]=o,o=q+4|0,ke=t[k>>2]|0,t[k>>2]=t[o>>2],t[o>>2]=ke,o=q+8|0,ke=t[T>>2]|0,t[T>>2]=t[o>>2],t[o>>2]=ke,o=q+12|0,ke=t[l>>2]|0,t[l>>2]=t[o>>2],t[o>>2]=ke,Or(q),o=t[T>>2]|0;break}l=o,d=((l-s>>2)+1|0)/-2|0,_=o+(d<<2)|0,s=y-l|0,l=s>>2,l&&(Y1(_|0,o|0,s|0)|0,o=t[k>>2]|0),ke=_+(l<<2)|0,t[T>>2]=ke,t[k>>2]=o+(d<<2),o=ke}while(0);t[o>>2]=t[r>>2],t[T>>2]=(t[T>>2]|0)+4,n=nn(e,ie,n)|0,Or(ie)}while(0);return h=Pe,n|0}function ln(e){e=e|0;var n=0;do{if(n=e+984|0,c[n>>0]|0)break;c[n>>0]=1,D[e+504>>2]=w(J),e=t[e+944>>2]|0}while((e|0)!=0)}function lf(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-4-o|0)>>>2)<<2)),Ve(r))}function nr(e){return e=e|0,t[e+944>>2]|0}function rr(e){e=e|0,i0(e,(t[e+964>>2]|0)!=0,2832),ln(e)}function Go(e){return e=e|0,(c[e+984>>0]|0)!=0|0}function Gu(e,n){e=e|0,n=n|0,fL(e,n,400)|0&&(vn(e|0,n|0,400)|0,ln(e))}function yl(e){e=e|0;var n=tt;return n=w(D[e+44>>2]),e=gt(n)|0,w(e?w(0):n)}function cu(e){e=e|0;var n=tt;return n=w(D[e+48>>2]),gt(n)|0&&(n=c[(t[e+976>>2]|0)+2>>0]|0?w(1):w(0)),w(n)}function Bs(e,n){e=e|0,n=n|0,t[e+980>>2]=n}function Vu(e){return e=e|0,t[e+980>>2]|0}function M0(e,n){e=e|0,n=n|0;var r=0;r=e+4|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,ln(e))}function au(e){return e=e|0,t[e+4>>2]|0}function Lr(e,n){e=e|0,n=n|0;var r=0;r=e+8|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,ln(e))}function F(e){return e=e|0,t[e+8>>2]|0}function R(e,n){e=e|0,n=n|0;var r=0;r=e+12|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,ln(e))}function U(e){return e=e|0,t[e+12>>2]|0}function H(e,n){e=e|0,n=n|0;var r=0;r=e+16|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,ln(e))}function fe(e){return e=e|0,t[e+16>>2]|0}function ue(e,n){e=e|0,n=n|0;var r=0;r=e+20|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,ln(e))}function de(e){return e=e|0,t[e+20>>2]|0}function W(e,n){e=e|0,n=n|0;var r=0;r=e+24|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,ln(e))}function ve(e){return e=e|0,t[e+24>>2]|0}function Fe(e,n){e=e|0,n=n|0;var r=0;r=e+28|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,ln(e))}function Ge(e){return e=e|0,t[e+28>>2]|0}function K(e,n){e=e|0,n=n|0;var r=0;r=e+32|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,ln(e))}function xe(e){return e=e|0,t[e+32>>2]|0}function je(e,n){e=e|0,n=n|0;var r=0;r=e+36|0,(t[r>>2]|0)!=(n|0)&&(t[r>>2]=n,ln(e))}function Xe(e){return e=e|0,t[e+36>>2]|0}function rt(e,n){e=e|0,n=w(n);var r=0;r=e+40|0,w(D[r>>2])!=n&&(D[r>>2]=n,ln(e))}function st(e,n){e=e|0,n=w(n);var r=0;r=e+44|0,w(D[r>>2])!=n&&(D[r>>2]=n,ln(e))}function xt(e,n){e=e|0,n=w(n);var r=0;r=e+48|0,w(D[r>>2])!=n&&(D[r>>2]=n,ln(e))}function wt(e,n){e=e|0,n=w(n);var r=0,o=0,s=0,l=0;l=gt(n)|0,r=(l^1)&1,o=e+52|0,s=e+56|0,(l|w(D[o>>2])==n?(t[s>>2]|0)==(r|0):0)||(D[o>>2]=n,t[s>>2]=r,ln(e))}function lt(e,n){e=e|0,n=w(n);var r=0,o=0;o=e+52|0,r=e+56|0,(w(D[o>>2])==n?(t[r>>2]|0)==2:0)||(D[o>>2]=n,o=gt(n)|0,t[r>>2]=o?3:2,ln(e))}function Rt(e,n){e=e|0,n=n|0;var r=0,o=0;o=n+52|0,r=t[o+4>>2]|0,n=e,t[n>>2]=t[o>>2],t[n+4>>2]=r}function yn(e,n,r){e=e|0,n=n|0,r=w(r);var o=0,s=0,l=0;l=gt(r)|0,o=(l^1)&1,s=e+132+(n<<3)|0,n=e+132+(n<<3)+4|0,(l|w(D[s>>2])==r?(t[n>>2]|0)==(o|0):0)||(D[s>>2]=r,t[n>>2]=o,ln(e))}function sn(e,n,r){e=e|0,n=n|0,r=w(r);var o=0,s=0,l=0;l=gt(r)|0,o=l?0:2,s=e+132+(n<<3)|0,n=e+132+(n<<3)+4|0,(l|w(D[s>>2])==r?(t[n>>2]|0)==(o|0):0)||(D[s>>2]=r,t[n>>2]=o,ln(e))}function ar(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=n+132+(r<<3)|0,n=t[o+4>>2]|0,r=e,t[r>>2]=t[o>>2],t[r+4>>2]=n}function rn(e,n,r){e=e|0,n=n|0,r=w(r);var o=0,s=0,l=0;l=gt(r)|0,o=(l^1)&1,s=e+60+(n<<3)|0,n=e+60+(n<<3)+4|0,(l|w(D[s>>2])==r?(t[n>>2]|0)==(o|0):0)||(D[s>>2]=r,t[n>>2]=o,ln(e))}function Hn(e,n,r){e=e|0,n=n|0,r=w(r);var o=0,s=0,l=0;l=gt(r)|0,o=l?0:2,s=e+60+(n<<3)|0,n=e+60+(n<<3)+4|0,(l|w(D[s>>2])==r?(t[n>>2]|0)==(o|0):0)||(D[s>>2]=r,t[n>>2]=o,ln(e))}function d0(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=n+60+(r<<3)|0,n=t[o+4>>2]|0,r=e,t[r>>2]=t[o>>2],t[r+4>>2]=n}function Cr(e,n){e=e|0,n=n|0;var r=0;r=e+60+(n<<3)+4|0,(t[r>>2]|0)!=3&&(D[e+60+(n<<3)>>2]=w(J),t[r>>2]=3,ln(e))}function He(e,n,r){e=e|0,n=n|0,r=w(r);var o=0,s=0,l=0;l=gt(r)|0,o=(l^1)&1,s=e+204+(n<<3)|0,n=e+204+(n<<3)+4|0,(l|w(D[s>>2])==r?(t[n>>2]|0)==(o|0):0)||(D[s>>2]=r,t[n>>2]=o,ln(e))}function Qe(e,n,r){e=e|0,n=n|0,r=w(r);var o=0,s=0,l=0;l=gt(r)|0,o=l?0:2,s=e+204+(n<<3)|0,n=e+204+(n<<3)+4|0,(l|w(D[s>>2])==r?(t[n>>2]|0)==(o|0):0)||(D[s>>2]=r,t[n>>2]=o,ln(e))}function Ne(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=n+204+(r<<3)|0,n=t[o+4>>2]|0,r=e,t[r>>2]=t[o>>2],t[r+4>>2]=n}function ft(e,n,r){e=e|0,n=n|0,r=w(r);var o=0,s=0,l=0;l=gt(r)|0,o=(l^1)&1,s=e+276+(n<<3)|0,n=e+276+(n<<3)+4|0,(l|w(D[s>>2])==r?(t[n>>2]|0)==(o|0):0)||(D[s>>2]=r,t[n>>2]=o,ln(e))}function St(e,n){return e=e|0,n=n|0,w(D[e+276+(n<<3)>>2])}function Qt(e,n){e=e|0,n=w(n);var r=0,o=0,s=0,l=0;l=gt(n)|0,r=(l^1)&1,o=e+348|0,s=e+352|0,(l|w(D[o>>2])==n?(t[s>>2]|0)==(r|0):0)||(D[o>>2]=n,t[s>>2]=r,ln(e))}function Cn(e,n){e=e|0,n=w(n);var r=0,o=0;o=e+348|0,r=e+352|0,(w(D[o>>2])==n?(t[r>>2]|0)==2:0)||(D[o>>2]=n,o=gt(n)|0,t[r>>2]=o?3:2,ln(e))}function bn(e){e=e|0;var n=0;n=e+352|0,(t[n>>2]|0)!=3&&(D[e+348>>2]=w(J),t[n>>2]=3,ln(e))}function p0(e,n){e=e|0,n=n|0;var r=0,o=0;o=n+348|0,r=t[o+4>>2]|0,n=e,t[n>>2]=t[o>>2],t[n+4>>2]=r}function h0(e,n){e=e|0,n=w(n);var r=0,o=0,s=0,l=0;l=gt(n)|0,r=(l^1)&1,o=e+356|0,s=e+360|0,(l|w(D[o>>2])==n?(t[s>>2]|0)==(r|0):0)||(D[o>>2]=n,t[s>>2]=r,ln(e))}function ci(e,n){e=e|0,n=w(n);var r=0,o=0;o=e+356|0,r=e+360|0,(w(D[o>>2])==n?(t[r>>2]|0)==2:0)||(D[o>>2]=n,o=gt(n)|0,t[r>>2]=o?3:2,ln(e))}function xi(e){e=e|0;var n=0;n=e+360|0,(t[n>>2]|0)!=3&&(D[e+356>>2]=w(J),t[n>>2]=3,ln(e))}function E0(e,n){e=e|0,n=n|0;var r=0,o=0;o=n+356|0,r=t[o+4>>2]|0,n=e,t[n>>2]=t[o>>2],t[n+4>>2]=r}function qr(e,n){e=e|0,n=w(n);var r=0,o=0,s=0,l=0;l=gt(n)|0,r=(l^1)&1,o=e+364|0,s=e+368|0,(l|w(D[o>>2])==n?(t[s>>2]|0)==(r|0):0)||(D[o>>2]=n,t[s>>2]=r,ln(e))}function Eo(e,n){e=e|0,n=w(n);var r=0,o=0,s=0,l=0;l=gt(n)|0,r=l?0:2,o=e+364|0,s=e+368|0,(l|w(D[o>>2])==n?(t[s>>2]|0)==(r|0):0)||(D[o>>2]=n,t[s>>2]=r,ln(e))}function So(e,n){e=e|0,n=n|0;var r=0,o=0;o=n+364|0,r=t[o+4>>2]|0,n=e,t[n>>2]=t[o>>2],t[n+4>>2]=r}function wl(e,n){e=e|0,n=w(n);var r=0,o=0,s=0,l=0;l=gt(n)|0,r=(l^1)&1,o=e+372|0,s=e+376|0,(l|w(D[o>>2])==n?(t[s>>2]|0)==(r|0):0)||(D[o>>2]=n,t[s>>2]=r,ln(e))}function js(e,n){e=e|0,n=w(n);var r=0,o=0,s=0,l=0;l=gt(n)|0,r=l?0:2,o=e+372|0,s=e+376|0,(l|w(D[o>>2])==n?(t[s>>2]|0)==(r|0):0)||(D[o>>2]=n,t[s>>2]=r,ln(e))}function Dl(e,n){e=e|0,n=n|0;var r=0,o=0;o=n+372|0,r=t[o+4>>2]|0,n=e,t[n>>2]=t[o>>2],t[n+4>>2]=r}function du(e,n){e=e|0,n=w(n);var r=0,o=0,s=0,l=0;l=gt(n)|0,r=(l^1)&1,o=e+380|0,s=e+384|0,(l|w(D[o>>2])==n?(t[s>>2]|0)==(r|0):0)||(D[o>>2]=n,t[s>>2]=r,ln(e))}function Yu(e,n){e=e|0,n=w(n);var r=0,o=0,s=0,l=0;l=gt(n)|0,r=l?0:2,o=e+380|0,s=e+384|0,(l|w(D[o>>2])==n?(t[s>>2]|0)==(r|0):0)||(D[o>>2]=n,t[s>>2]=r,ln(e))}function Us(e,n){e=e|0,n=n|0;var r=0,o=0;o=n+380|0,r=t[o+4>>2]|0,n=e,t[n>>2]=t[o>>2],t[n+4>>2]=r}function oo(e,n){e=e|0,n=w(n);var r=0,o=0,s=0,l=0;l=gt(n)|0,r=(l^1)&1,o=e+388|0,s=e+392|0,(l|w(D[o>>2])==n?(t[s>>2]|0)==(r|0):0)||(D[o>>2]=n,t[s>>2]=r,ln(e))}function Hi(e,n){e=e|0,n=w(n);var r=0,o=0,s=0,l=0;l=gt(n)|0,r=l?0:2,o=e+388|0,s=e+392|0,(l|w(D[o>>2])==n?(t[s>>2]|0)==(r|0):0)||(D[o>>2]=n,t[s>>2]=r,ln(e))}function qs(e,n){e=e|0,n=n|0;var r=0,o=0;o=n+388|0,r=t[o+4>>2]|0,n=e,t[n>>2]=t[o>>2],t[n+4>>2]=r}function F0(e,n){e=e|0,n=w(n);var r=0;r=e+396|0,w(D[r>>2])!=n&&(D[r>>2]=n,ln(e))}function Gr(e){return e=e|0,w(D[e+396>>2])}function ir(e){return e=e|0,w(D[e+400>>2])}function L0(e){return e=e|0,w(D[e+404>>2])}function Y0(e){return e=e|0,w(D[e+408>>2])}function Co(e){return e=e|0,w(D[e+412>>2])}function $u(e){return e=e|0,w(D[e+416>>2])}function Vo(e){return e=e|0,w(D[e+420>>2])}function Rr(e,n){switch(e=e|0,n=n|0,i0(e,(n|0)<6,2918),n|0){case 0:{n=(t[e+496>>2]|0)==2?5:4;break}case 2:{n=(t[e+496>>2]|0)==2?4:5;break}default:}return w(D[e+424+(n<<2)>>2])}function Jn(e,n){switch(e=e|0,n=n|0,i0(e,(n|0)<6,2918),n|0){case 0:{n=(t[e+496>>2]|0)==2?5:4;break}case 2:{n=(t[e+496>>2]|0)==2?4:5;break}default:}return w(D[e+448+(n<<2)>>2])}function ai(e,n){switch(e=e|0,n=n|0,i0(e,(n|0)<6,2918),n|0){case 0:{n=(t[e+496>>2]|0)==2?5:4;break}case 2:{n=(t[e+496>>2]|0)==2?4:5;break}default:}return w(D[e+472+(n<<2)>>2])}function o0(e,n){e=e|0,n=n|0;var r=0,o=tt;return r=t[e+4>>2]|0,(r|0)==(t[n+4>>2]|0)?r?(o=w(D[e>>2]),e=w(Ot(w(o-w(D[n>>2]))))>2]=0,t[o+4>>2]=0,t[o+8>>2]=0,Ru(o|0,e|0,n|0,0),wn(e,3,(c[o+11>>0]|0)<0?t[o>>2]|0:o,r),ML(o),h=r}function $0(e,n,r,o){e=w(e),n=w(n),r=r|0,o=o|0;var s=tt;e=w(e*n),s=w(V4(e,w(1)));do if(Vr(s,w(0))|0)e=w(e-s);else{if(e=w(e-s),Vr(s,w(1))|0){e=w(e+w(1));break}if(r){e=w(e+w(1));break}o||(s>w(.5)?s=w(1):(o=Vr(s,w(.5))|0,s=w(o?1:0)),e=w(e+s))}while(0);return w(e/n)}function K0(e,n,r,o,s,l,d,_,y,k,T,P,q){e=e|0,n=w(n),r=r|0,o=w(o),s=s|0,l=w(l),d=d|0,_=w(_),y=w(y),k=w(k),T=w(T),P=w(P),q=q|0;var we=0,le=tt,ie=tt,Pe=tt,ke=tt,qe=tt,pe=tt;return y>2]),le!=w(0)):0)?(Pe=w($0(n,le,0,0)),ke=w($0(o,le,0,0)),ie=w($0(l,le,0,0)),le=w($0(_,le,0,0))):(ie=l,Pe=n,le=_,ke=o),(s|0)==(e|0)?we=Vr(ie,Pe)|0:we=0,(d|0)==(r|0)?q=Vr(le,ke)|0:q=0,((we?0:(qe=w(n-T),!(ae(e,qe,y)|0)))?!(Be(e,qe,s,y)|0):0)?we=Ie(e,qe,s,l,y)|0:we=1,((q?0:(pe=w(o-P),!(ae(r,pe,k)|0)))?!(Be(r,pe,d,k)|0):0)?q=Ie(r,pe,d,_,k)|0:q=1,q=we&q),q|0}function ae(e,n,r){return e=e|0,n=w(n),r=w(r),(e|0)==1?e=Vr(n,r)|0:e=0,e|0}function Be(e,n,r,o){return e=e|0,n=w(n),r=r|0,o=w(o),(e|0)==2&(r|0)==0?n>=o?e=1:e=Vr(n,o)|0:e=0,e|0}function Ie(e,n,r,o,s){return e=e|0,n=w(n),r=r|0,o=w(o),s=w(s),(e|0)==2&(r|0)==2&o>n?s<=n?e=1:e=Vr(n,s)|0:e=0,e|0}function ht(e,n,r,o,s,l,d,_,y,k,T){e=e|0,n=w(n),r=w(r),o=o|0,s=s|0,l=l|0,d=w(d),_=w(_),y=y|0,k=k|0,T=T|0;var P=0,q=0,we=0,le=0,ie=tt,Pe=tt,ke=0,qe=0,pe=0,_e=0,vt=0,Ln=0,Ht=0,It=0,gn=0,Pn=0,zt=0,Dr=tt,Ki=tt,Xi=tt,Ji=0,Ro=0;zt=h,h=h+160|0,It=zt+152|0,Ht=zt+120|0,Ln=zt+104|0,pe=zt+72|0,le=zt+56|0,vt=zt+8|0,qe=zt,_e=(t[2279]|0)+1|0,t[2279]=_e,gn=e+984|0,((c[gn>>0]|0)!=0?(t[e+512>>2]|0)!=(t[2278]|0):0)?ke=4:(t[e+516>>2]|0)==(o|0)?Pn=0:ke=4,(ke|0)==4&&(t[e+520>>2]=0,t[e+924>>2]=-1,t[e+928>>2]=-1,D[e+932>>2]=w(-1),D[e+936>>2]=w(-1),Pn=1);e:do if(t[e+964>>2]|0)if(ie=w(mt(e,2,d)),Pe=w(mt(e,0,d)),P=e+916|0,Xi=w(D[P>>2]),Ki=w(D[e+920>>2]),Dr=w(D[e+932>>2]),K0(s,n,l,r,t[e+924>>2]|0,Xi,t[e+928>>2]|0,Ki,Dr,w(D[e+936>>2]),ie,Pe,T)|0)ke=22;else if(we=t[e+520>>2]|0,!we)ke=21;else for(q=0;;){if(P=e+524+(q*24|0)|0,Dr=w(D[P>>2]),Ki=w(D[e+524+(q*24|0)+4>>2]),Xi=w(D[e+524+(q*24|0)+16>>2]),K0(s,n,l,r,t[e+524+(q*24|0)+8>>2]|0,Dr,t[e+524+(q*24|0)+12>>2]|0,Ki,Xi,w(D[e+524+(q*24|0)+20>>2]),ie,Pe,T)|0){ke=22;break e}if(q=q+1|0,q>>>0>=we>>>0){ke=21;break}}else{if(y){if(P=e+916|0,!(Vr(w(D[P>>2]),n)|0)){ke=21;break}if(!(Vr(w(D[e+920>>2]),r)|0)){ke=21;break}if((t[e+924>>2]|0)!=(s|0)){ke=21;break}P=(t[e+928>>2]|0)==(l|0)?P:0,ke=22;break}if(we=t[e+520>>2]|0,!we)ke=21;else for(q=0;;){if(P=e+524+(q*24|0)|0,((Vr(w(D[P>>2]),n)|0?Vr(w(D[e+524+(q*24|0)+4>>2]),r)|0:0)?(t[e+524+(q*24|0)+8>>2]|0)==(s|0):0)?(t[e+524+(q*24|0)+12>>2]|0)==(l|0):0){ke=22;break e}if(q=q+1|0,q>>>0>=we>>>0){ke=21;break}}}while(0);do if((ke|0)==21)c[11697]|0?(P=0,ke=28):(P=0,ke=31);else if((ke|0)==22){if(q=(c[11697]|0)!=0,!((P|0)!=0&(Pn^1)))if(q){ke=28;break}else{ke=31;break}le=P+16|0,t[e+908>>2]=t[le>>2],we=P+20|0,t[e+912>>2]=t[we>>2],(c[11698]|0)==0|q^1||(t[qe>>2]=Gn(_e)|0,t[qe+4>>2]=_e,wn(e,4,2972,qe),q=t[e+972>>2]|0,q|0&&Nl[q&127](e),s=$t(s,y)|0,l=$t(l,y)|0,Ro=+w(D[le>>2]),Ji=+w(D[we>>2]),t[vt>>2]=s,t[vt+4>>2]=l,L[vt+8>>3]=+n,L[vt+16>>3]=+r,L[vt+24>>3]=Ro,L[vt+32>>3]=Ji,t[vt+40>>2]=k,wn(e,4,2989,vt))}while(0);return(ke|0)==28&&(q=Gn(_e)|0,t[le>>2]=q,t[le+4>>2]=_e,t[le+8>>2]=Pn?3047:11699,wn(e,4,3038,le),q=t[e+972>>2]|0,q|0&&Nl[q&127](e),vt=$t(s,y)|0,ke=$t(l,y)|0,t[pe>>2]=vt,t[pe+4>>2]=ke,L[pe+8>>3]=+n,L[pe+16>>3]=+r,t[pe+24>>2]=k,wn(e,4,3049,pe),ke=31),(ke|0)==31&&(X0(e,n,r,o,s,l,d,_,y,T),c[11697]|0&&(q=t[2279]|0,vt=Gn(q)|0,t[Ln>>2]=vt,t[Ln+4>>2]=q,t[Ln+8>>2]=Pn?3047:11699,wn(e,4,3083,Ln),q=t[e+972>>2]|0,q|0&&Nl[q&127](e),vt=$t(s,y)|0,Ln=$t(l,y)|0,Ji=+w(D[e+908>>2]),Ro=+w(D[e+912>>2]),t[Ht>>2]=vt,t[Ht+4>>2]=Ln,L[Ht+8>>3]=Ji,L[Ht+16>>3]=Ro,t[Ht+24>>2]=k,wn(e,4,3092,Ht)),t[e+516>>2]=o,P||(q=e+520|0,P=t[q>>2]|0,(P|0)==16&&(c[11697]|0&&wn(e,4,3124,It),t[q>>2]=0,P=0),y?P=e+916|0:(t[q>>2]=P+1,P=e+524+(P*24|0)|0),D[P>>2]=n,D[P+4>>2]=r,t[P+8>>2]=s,t[P+12>>2]=l,t[P+16>>2]=t[e+908>>2],t[P+20>>2]=t[e+912>>2],P=0)),y&&(t[e+416>>2]=t[e+908>>2],t[e+420>>2]=t[e+912>>2],c[e+985>>0]=1,c[gn>>0]=0),t[2279]=(t[2279]|0)+-1,t[e+512>>2]=t[2278],h=zt,Pn|(P|0)==0|0}function mt(e,n,r){e=e|0,n=n|0,r=w(r);var o=tt;return o=w(Tr(e,n,r)),w(o+w(R0(e,n,r)))}function wn(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0;l=h,h=h+16|0,s=l,t[s>>2]=o,e?o=t[e+976>>2]|0:o=0,Ku(o,e,n,r,s),h=l}function Gn(e){return e=e|0,(e>>>0>60?3201:3201+(60-e)|0)|0}function $t(e,n){e=e|0,n=n|0;var r=0,o=0,s=0;return s=h,h=h+32|0,r=s+12|0,o=s,t[r>>2]=t[254],t[r+4>>2]=t[255],t[r+8>>2]=t[256],t[o>>2]=t[257],t[o+4>>2]=t[258],t[o+8>>2]=t[259],(e|0)>2?e=11699:e=t[(n?o:r)+(e<<2)>>2]|0,h=s,e|0}function X0(e,n,r,o,s,l,d,_,y,k){e=e|0,n=w(n),r=w(r),o=o|0,s=s|0,l=l|0,d=w(d),_=w(_),y=y|0,k=k|0;var T=0,P=0,q=0,we=0,le=tt,ie=tt,Pe=tt,ke=tt,qe=tt,pe=tt,_e=tt,vt=0,Ln=0,Ht=0,It=tt,gn=tt,Pn=0,zt=tt,Dr=0,Ki=0,Xi=0,Ji=0,Ro=0,kf=0,Af=0,Cu=0,Of=0,Js=0,Qs=0,If=0,Pf=0,Mf=0,Kn=0,Tu=0,Ff=0,us=0,Lf=tt,Rf=tt,Zs=tt,el=tt,ss=tt,Fi=0,nu=0,go=0,xu=0,jl=0,Ul=tt,tl=tt,ql=tt,zl=tt,Li=tt,Di=tt,ku=0,xr=tt,Wl=tt,Qi=tt,ls=tt,Zi=tt,fs=tt,Hl=0,bl=0,cs=tt,Ri=tt,Au=0,Gl=0,Vl=0,Yl=0,En=tt,br=0,Ei=0,eo=0,Ni=0,xn=0,Vt=0,Ou=0,kt=tt,$l=0,Qr=0;Ou=h,h=h+16|0,Fi=Ou+12|0,nu=Ou+8|0,go=Ou+4|0,xu=Ou,i0(e,(s|0)==0|(gt(n)|0)^1,3326),i0(e,(l|0)==0|(gt(r)|0)^1,3406),Ei=so(e,o)|0,t[e+496>>2]=Ei,xn=N0(2,Ei)|0,Vt=N0(0,Ei)|0,D[e+440>>2]=w(Tr(e,xn,d)),D[e+444>>2]=w(R0(e,xn,d)),D[e+428>>2]=w(Tr(e,Vt,d)),D[e+436>>2]=w(R0(e,Vt,d)),D[e+464>>2]=w(C0(e,xn)),D[e+468>>2]=w(di(e,xn)),D[e+452>>2]=w(C0(e,Vt)),D[e+460>>2]=w(di(e,Vt)),D[e+488>>2]=w(u0(e,xn,d)),D[e+492>>2]=w(v0(e,xn,d)),D[e+476>>2]=w(u0(e,Vt,d)),D[e+484>>2]=w(v0(e,Vt,d));do if(t[e+964>>2]|0)To(e,n,r,s,l,d,_);else{if(eo=e+948|0,Ni=(t[e+952>>2]|0)-(t[eo>>2]|0)>>2,!Ni){pu(e,n,r,s,l,d,_);break}if(y?0:Sl(e,n,r,s,l,d,_)|0)break;bo(e),Tu=e+508|0,c[Tu>>0]=0,xn=N0(t[e+4>>2]|0,Ei)|0,Vt=Cl(xn,Ei)|0,br=Nr(xn)|0,Ff=t[e+8>>2]|0,Gl=e+28|0,us=(t[Gl>>2]|0)!=0,Zi=br?d:_,cs=br?_:d,Lf=w(B0(e,xn,d)),Rf=w(hu(e,xn,d)),le=w(B0(e,Vt,d)),fs=w(Fn(e,xn,d)),Ri=w(Fn(e,Vt,d)),Ht=br?s:l,Au=br?l:s,En=br?fs:Ri,qe=br?Ri:fs,ls=w(mt(e,2,d)),ke=w(mt(e,0,d)),ie=w(w(Tn(e+364|0,d))-En),Pe=w(w(Tn(e+380|0,d))-En),pe=w(w(Tn(e+372|0,_))-qe),_e=w(w(Tn(e+388|0,_))-qe),Zs=br?ie:pe,el=br?Pe:_e,ls=w(n-ls),n=w(ls-En),gt(n)|0?En=n:En=w(Ur(w(cc(n,Pe)),ie)),Wl=w(r-ke),n=w(Wl-qe),gt(n)|0?Qi=n:Qi=w(Ur(w(cc(n,_e)),pe)),ie=br?En:Qi,xr=br?Qi:En;e:do if((Ht|0)==1)for(o=0,P=0;;){if(T=e0(e,P)|0,!o)(w(Br(T))>w(0)?w(zr(T))>w(0):0)?o=T:o=0;else if(pi(T)|0){we=0;break e}if(P=P+1|0,P>>>0>=Ni>>>0){we=o;break}}else we=0;while(0);vt=we+500|0,Ln=we+504|0,o=0,T=0,n=w(0),q=0;do{if(P=t[(t[eo>>2]|0)+(q<<2)>>2]|0,(t[P+36>>2]|0)==1)lo(P),c[P+985>>0]=1,c[P+984>>0]=0;else{$r(P),y&&Yo(P,so(P,Ei)|0,ie,xr,En);do if((t[P+24>>2]|0)!=1)if((P|0)==(we|0)){t[vt>>2]=t[2278],D[Ln>>2]=w(0);break}else{wr(e,P,En,s,Qi,En,Qi,l,Ei,k);break}else T|0&&(t[T+960>>2]=P),t[P+960>>2]=0,T=P,o=(o|0)==0?P:o;while(0);Di=w(D[P+504>>2]),n=w(n+w(Di+w(mt(P,xn,En))))}q=q+1|0}while((q|0)!=(Ni|0));for(Xi=n>ie,ku=us&((Ht|0)==2&Xi)?1:Ht,Dr=(Au|0)==1,Ro=Dr&(y^1),kf=(ku|0)==1,Af=(ku|0)==2,Cu=976+(xn<<2)|0,Of=(Au|2|0)==2,Mf=Dr&(us^1),Js=1040+(Vt<<2)|0,Qs=1040+(xn<<2)|0,If=976+(Vt<<2)|0,Pf=(Au|0)!=1,Xi=us&((Ht|0)!=0&Xi),Ki=e+976|0,Dr=Dr^1,n=ie,Pn=0,Ji=0,Di=w(0),ss=w(0);;){e:do if(Pn>>>0>>0)for(Ln=t[eo>>2]|0,q=0,_e=w(0),pe=w(0),Pe=w(0),ie=w(0),P=0,T=0,we=Pn;;){if(vt=t[Ln+(we<<2)>>2]|0,(t[vt+36>>2]|0)!=1?(t[vt+940>>2]=Ji,(t[vt+24>>2]|0)!=1):0){if(ke=w(mt(vt,xn,En)),Kn=t[Cu>>2]|0,r=w(Tn(vt+380+(Kn<<3)|0,Zi)),qe=w(D[vt+504>>2]),r=w(cc(r,qe)),r=w(Ur(w(Tn(vt+364+(Kn<<3)|0,Zi)),r)),us&(q|0)!=0&w(ke+w(pe+r))>n){l=q,ke=_e,Ht=we;break e}ke=w(ke+r),r=w(pe+ke),ke=w(_e+ke),pi(vt)|0&&(Pe=w(Pe+w(Br(vt))),ie=w(ie-w(qe*w(zr(vt))))),T|0&&(t[T+960>>2]=vt),t[vt+960>>2]=0,q=q+1|0,T=vt,P=(P|0)==0?vt:P}else ke=_e,r=pe;if(we=we+1|0,we>>>0>>0)_e=ke,pe=r;else{l=q,Ht=we;break}}else l=0,ke=w(0),Pe=w(0),ie=w(0),P=0,Ht=Pn;while(0);Kn=Pe>w(0)&Pew(0)&ieel&((gt(el)|0)^1))n=el,Kn=51;else if(c[(t[Ki>>2]|0)+3>>0]|0)Kn=51;else{if(It!=w(0)?w(Br(e))!=w(0):0){Kn=53;break}n=ke,Kn=53}while(0);if((Kn|0)==51&&(Kn=0,gt(n)|0?Kn=53:(gn=w(n-ke),zt=n)),(Kn|0)==53&&(Kn=0,ke>2]|0,we=gnw(0),pe=w(gn/It),Pe=w(0),ke=w(0),n=w(0),T=P;do r=w(Tn(T+380+(q<<3)|0,Zi)),ie=w(Tn(T+364+(q<<3)|0,Zi)),ie=w(cc(r,w(Ur(ie,w(D[T+504>>2]))))),we?(r=w(ie*w(zr(T))),(r!=w(-0)?(kt=w(ie-w(qe*r)),Ul=w(kn(T,xn,kt,zt,En)),kt!=Ul):0)&&(Pe=w(Pe-w(Ul-ie)),n=w(n+r))):((vt?(tl=w(Br(T)),tl!=w(0)):0)?(kt=w(ie+w(pe*tl)),ql=w(kn(T,xn,kt,zt,En)),kt!=ql):0)&&(Pe=w(Pe-w(ql-ie)),ke=w(ke-tl)),T=t[T+960>>2]|0;while((T|0)!=0);if(n=w(_e+n),ie=w(gn+Pe),jl)n=w(0);else{qe=w(It+ke),we=t[Cu>>2]|0,vt=iew(0),qe=w(ie/qe),n=w(0);do{kt=w(Tn(P+380+(we<<3)|0,Zi)),Pe=w(Tn(P+364+(we<<3)|0,Zi)),Pe=w(cc(kt,w(Ur(Pe,w(D[P+504>>2]))))),vt?(kt=w(Pe*w(zr(P))),ie=w(-kt),kt!=w(-0)?(kt=w(pe*ie),ie=w(kn(P,xn,w(Pe+(Ln?ie:kt)),zt,En))):ie=Pe):(q?(zl=w(Br(P)),zl!=w(0)):0)?ie=w(kn(P,xn,w(Pe+w(qe*zl)),zt,En)):ie=Pe,n=w(n-w(ie-Pe)),ke=w(mt(P,xn,En)),r=w(mt(P,Vt,En)),ie=w(ie+ke),D[nu>>2]=ie,t[xu>>2]=1,Pe=w(D[P+396>>2]);e:do if(gt(Pe)|0){T=gt(xr)|0;do if(!T){if(Xi|(m0(P,Vt,xr)|0|Dr)||(T0(e,P)|0)!=4||(t[(hi(P,Vt)|0)+4>>2]|0)==3||(t[(Ai(P,Vt)|0)+4>>2]|0)==3)break;D[Fi>>2]=xr,t[go>>2]=1;break e}while(0);if(m0(P,Vt,xr)|0){T=t[P+992+(t[If>>2]<<2)>>2]|0,kt=w(r+w(Tn(T,xr))),D[Fi>>2]=kt,T=Pf&(t[T+4>>2]|0)==2,t[go>>2]=((gt(kt)|0|T)^1)&1;break}else{D[Fi>>2]=xr,t[go>>2]=T?0:2;break}}else kt=w(ie-ke),It=w(kt/Pe),kt=w(Pe*kt),t[go>>2]=1,D[Fi>>2]=w(r+(br?It:kt));while(0);Kt(P,xn,zt,En,xu,nu),Kt(P,Vt,xr,En,go,Fi);do if(m0(P,Vt,xr)|0?0:(T0(e,P)|0)==4){if((t[(hi(P,Vt)|0)+4>>2]|0)==3){T=0;break}T=(t[(Ai(P,Vt)|0)+4>>2]|0)!=3}else T=0;while(0);kt=w(D[nu>>2]),It=w(D[Fi>>2]),$l=t[xu>>2]|0,Qr=t[go>>2]|0,ht(P,br?kt:It,br?It:kt,Ei,br?$l:Qr,br?Qr:$l,En,Qi,y&(T^1),3488,k)|0,c[Tu>>0]=c[Tu>>0]|c[P+508>>0],P=t[P+960>>2]|0}while((P|0)!=0)}}else n=w(0);if(n=w(gn+n),Qr=n>0]=Qr|C[Tu>>0],Af&n>w(0)?(T=t[Cu>>2]|0,((t[e+364+(T<<3)+4>>2]|0)!=0?(Li=w(Tn(e+364+(T<<3)|0,Zi)),Li>=w(0)):0)?ie=w(Ur(w(0),w(Li-w(zt-n)))):ie=w(0)):ie=n,vt=Pn>>>0>>0,vt){we=t[eo>>2]|0,q=Pn,T=0;do P=t[we+(q<<2)>>2]|0,t[P+24>>2]|0||(T=((t[(hi(P,xn)|0)+4>>2]|0)==3&1)+T|0,T=T+((t[(Ai(P,xn)|0)+4>>2]|0)==3&1)|0),q=q+1|0;while((q|0)!=(Ht|0));T?(ke=w(0),r=w(0)):Kn=101}else Kn=101;e:do if((Kn|0)==101)switch(Kn=0,Ff|0){case 1:{T=0,ke=w(ie*w(.5)),r=w(0);break e}case 2:{T=0,ke=ie,r=w(0);break e}case 3:{if(l>>>0<=1){T=0,ke=w(0),r=w(0);break e}r=w((l+-1|0)>>>0),T=0,ke=w(0),r=w(w(Ur(ie,w(0)))/r);break e}case 5:{r=w(ie/w((l+1|0)>>>0)),T=0,ke=r;break e}case 4:{r=w(ie/w(l>>>0)),T=0,ke=w(r*w(.5));break e}default:{T=0,ke=w(0),r=w(0);break e}}while(0);if(n=w(Lf+ke),vt){Pe=w(ie/w(T|0)),q=t[eo>>2]|0,P=Pn,ie=w(0);do{T=t[q+(P<<2)>>2]|0;e:do if((t[T+36>>2]|0)!=1){switch(t[T+24>>2]|0){case 1:{if(X(T,xn)|0){if(!y)break e;kt=w(Y(T,xn,zt)),kt=w(kt+w(C0(e,xn))),kt=w(kt+w(Tr(T,xn,En))),D[T+400+(t[Qs>>2]<<2)>>2]=kt;break e}break}case 0:if(Qr=(t[(hi(T,xn)|0)+4>>2]|0)==3,kt=w(Pe+n),n=Qr?kt:n,y&&(Qr=T+400+(t[Qs>>2]<<2)|0,D[Qr>>2]=w(n+w(D[Qr>>2]))),Qr=(t[(Ai(T,xn)|0)+4>>2]|0)==3,kt=w(Pe+n),n=Qr?kt:n,Ro){kt=w(r+w(mt(T,xn,En))),ie=xr,n=w(n+w(kt+w(D[T+504>>2])));break e}else{n=w(n+w(r+w(ye(T,xn,En)))),ie=w(Ur(ie,w(ye(T,Vt,En))));break e}default:}y&&(kt=w(ke+w(C0(e,xn))),Qr=T+400+(t[Qs>>2]<<2)|0,D[Qr>>2]=w(kt+w(D[Qr>>2])))}while(0);P=P+1|0}while((P|0)!=(Ht|0))}else ie=w(0);if(r=w(Rf+n),Of?ke=w(w(kn(e,Vt,w(Ri+ie),cs,d))-Ri):ke=xr,Pe=w(w(kn(e,Vt,w(Ri+(Mf?xr:ie)),cs,d))-Ri),vt&y){P=Pn;do{q=t[(t[eo>>2]|0)+(P<<2)>>2]|0;do if((t[q+36>>2]|0)!=1){if((t[q+24>>2]|0)==1){if(X(q,Vt)|0){if(kt=w(Y(q,Vt,xr)),kt=w(kt+w(C0(e,Vt))),kt=w(kt+w(Tr(q,Vt,En))),T=t[Js>>2]|0,D[q+400+(T<<2)>>2]=kt,!(gt(kt)|0))break}else T=t[Js>>2]|0;kt=w(C0(e,Vt)),D[q+400+(T<<2)>>2]=w(kt+w(Tr(q,Vt,En)));break}T=T0(e,q)|0;do if((T|0)==4){if((t[(hi(q,Vt)|0)+4>>2]|0)==3){Kn=139;break}if((t[(Ai(q,Vt)|0)+4>>2]|0)==3){Kn=139;break}if(m0(q,Vt,xr)|0){n=le;break}$l=t[q+908+(t[Cu>>2]<<2)>>2]|0,t[Fi>>2]=$l,n=w(D[q+396>>2]),Qr=gt(n)|0,ie=(t[j>>2]=$l,w(D[j>>2])),Qr?n=Pe:(gn=w(mt(q,Vt,En)),kt=w(ie/n),n=w(n*ie),n=w(gn+(br?kt:n))),D[nu>>2]=n,D[Fi>>2]=w(w(mt(q,xn,En))+ie),t[go>>2]=1,t[xu>>2]=1,Kt(q,xn,zt,En,go,Fi),Kt(q,Vt,xr,En,xu,nu),n=w(D[Fi>>2]),gn=w(D[nu>>2]),kt=br?n:gn,n=br?gn:n,Qr=((gt(kt)|0)^1)&1,ht(q,kt,n,Ei,Qr,((gt(n)|0)^1)&1,En,Qi,1,3493,k)|0,n=le}else Kn=139;while(0);e:do if((Kn|0)==139){Kn=0,n=w(ke-w(ye(q,Vt,En)));do if((t[(hi(q,Vt)|0)+4>>2]|0)==3){if((t[(Ai(q,Vt)|0)+4>>2]|0)!=3)break;n=w(le+w(Ur(w(0),w(n*w(.5)))));break e}while(0);if((t[(Ai(q,Vt)|0)+4>>2]|0)==3){n=le;break}if((t[(hi(q,Vt)|0)+4>>2]|0)==3){n=w(le+w(Ur(w(0),n)));break}switch(T|0){case 1:{n=le;break e}case 2:{n=w(le+w(n*w(.5)));break e}default:{n=w(le+n);break e}}}while(0);kt=w(Di+n),Qr=q+400+(t[Js>>2]<<2)|0,D[Qr>>2]=w(kt+w(D[Qr>>2]))}while(0);P=P+1|0}while((P|0)!=(Ht|0))}if(Di=w(Di+Pe),ss=w(Ur(ss,r)),l=Ji+1|0,Ht>>>0>=Ni>>>0)break;n=zt,Pn=Ht,Ji=l}do if(y){if(T=l>>>0>1,T?0:!(he(e)|0))break;if(!(gt(xr)|0)){n=w(xr-Di);e:do switch(t[e+12>>2]|0){case 3:{le=w(le+n),pe=w(0);break}case 2:{le=w(le+w(n*w(.5))),pe=w(0);break}case 4:{xr>Di?pe=w(n/w(l>>>0)):pe=w(0);break}case 7:if(xr>Di){le=w(le+w(n/w(l<<1>>>0))),pe=w(n/w(l>>>0)),pe=T?pe:w(0);break e}else{le=w(le+w(n*w(.5))),pe=w(0);break e}case 6:{pe=w(n/w(Ji>>>0)),pe=xr>Di&T?pe:w(0);break}default:pe=w(0)}while(0);if(l|0)for(vt=1040+(Vt<<2)|0,Ln=976+(Vt<<2)|0,we=0,P=0;;){e:do if(P>>>0>>0)for(ie=w(0),Pe=w(0),n=w(0),q=P;;){T=t[(t[eo>>2]|0)+(q<<2)>>2]|0;do if((t[T+36>>2]|0)!=1?(t[T+24>>2]|0)==0:0){if((t[T+940>>2]|0)!=(we|0))break e;if(We(T,Vt)|0&&(kt=w(D[T+908+(t[Ln>>2]<<2)>>2]),n=w(Ur(n,w(kt+w(mt(T,Vt,En)))))),(T0(e,T)|0)!=5)break;Li=w(et(T)),Li=w(Li+w(Tr(T,0,En))),kt=w(D[T+912>>2]),kt=w(w(kt+w(mt(T,0,En)))-Li),Li=w(Ur(Pe,Li)),kt=w(Ur(ie,kt)),ie=kt,Pe=Li,n=w(Ur(n,w(Li+kt)))}while(0);if(T=q+1|0,T>>>0>>0)q=T;else{q=T;break}}else Pe=w(0),n=w(0),q=P;while(0);if(qe=w(pe+n),r=le,le=w(le+qe),P>>>0>>0){ke=w(r+Pe),T=P;do{P=t[(t[eo>>2]|0)+(T<<2)>>2]|0;e:do if((t[P+36>>2]|0)!=1?(t[P+24>>2]|0)==0:0)switch(T0(e,P)|0){case 1:{kt=w(r+w(Tr(P,Vt,En))),D[P+400+(t[vt>>2]<<2)>>2]=kt;break e}case 3:{kt=w(w(le-w(R0(P,Vt,En)))-w(D[P+908+(t[Ln>>2]<<2)>>2])),D[P+400+(t[vt>>2]<<2)>>2]=kt;break e}case 2:{kt=w(r+w(w(qe-w(D[P+908+(t[Ln>>2]<<2)>>2]))*w(.5))),D[P+400+(t[vt>>2]<<2)>>2]=kt;break e}case 4:{if(kt=w(r+w(Tr(P,Vt,En))),D[P+400+(t[vt>>2]<<2)>>2]=kt,m0(P,Vt,xr)|0||(br?(ie=w(D[P+908>>2]),n=w(ie+w(mt(P,xn,En))),Pe=qe):(Pe=w(D[P+912>>2]),Pe=w(Pe+w(mt(P,Vt,En))),n=qe,ie=w(D[P+908>>2])),Vr(n,ie)|0?Vr(Pe,w(D[P+912>>2]))|0:0))break e;ht(P,n,Pe,Ei,1,1,En,Qi,1,3501,k)|0;break e}case 5:{D[P+404>>2]=w(w(ke-w(et(P)))+w(Y(P,0,xr)));break e}default:break e}while(0);T=T+1|0}while((T|0)!=(q|0))}if(we=we+1|0,(we|0)==(l|0))break;P=q}}}while(0);if(D[e+908>>2]=w(kn(e,2,ls,d,d)),D[e+912>>2]=w(kn(e,0,Wl,_,d)),((ku|0)!=0?(Hl=t[e+32>>2]|0,bl=(ku|0)==2,!(bl&(Hl|0)!=2)):0)?bl&(Hl|0)==2&&(n=w(fs+zt),n=w(Ur(w(cc(n,w(Dt(e,xn,ss,Zi)))),fs)),Kn=198):(n=w(kn(e,xn,ss,Zi,d)),Kn=198),(Kn|0)==198&&(D[e+908+(t[976+(xn<<2)>>2]<<2)>>2]=n),((Au|0)!=0?(Vl=t[e+32>>2]|0,Yl=(Au|0)==2,!(Yl&(Vl|0)!=2)):0)?Yl&(Vl|0)==2&&(n=w(Ri+xr),n=w(Ur(w(cc(n,w(Dt(e,Vt,w(Ri+Di),cs)))),Ri)),Kn=204):(n=w(kn(e,Vt,w(Ri+Di),cs,d)),Kn=204),(Kn|0)==204&&(D[e+908+(t[976+(Vt<<2)>>2]<<2)>>2]=n),y){if((t[Gl>>2]|0)==2){P=976+(Vt<<2)|0,q=1040+(Vt<<2)|0,T=0;do we=e0(e,T)|0,t[we+24>>2]|0||($l=t[P>>2]|0,kt=w(D[e+908+($l<<2)>>2]),Qr=we+400+(t[q>>2]<<2)|0,kt=w(kt-w(D[Qr>>2])),D[Qr>>2]=w(kt-w(D[we+908+($l<<2)>>2]))),T=T+1|0;while((T|0)!=(Ni|0))}if(o|0){T=br?ku:s;do bt(e,o,En,T,Qi,Ei,k),o=t[o+960>>2]|0;while((o|0)!=0)}if(T=(xn|2|0)==3,P=(Vt|2|0)==3,T|P){o=0;do q=t[(t[eo>>2]|0)+(o<<2)>>2]|0,(t[q+36>>2]|0)!=1&&(T&&Zt(e,q,xn),P&&Zt(e,q,Vt)),o=o+1|0;while((o|0)!=(Ni|0))}}}while(0);h=Ou}function ki(e,n){e=e|0,n=w(n);var r=0;li(e,n>=w(0),3147),r=n==w(0),D[e+4>>2]=r?w(0):n}function Yr(e,n,r,o){e=e|0,n=w(n),r=w(r),o=o|0;var s=tt,l=tt,d=0,_=0,y=0;t[2278]=(t[2278]|0)+1,$r(e),m0(e,2,n)|0?(s=w(Tn(t[e+992>>2]|0,n)),y=1,s=w(s+w(mt(e,2,n)))):(s=w(Tn(e+380|0,n)),s>=w(0)?y=2:(y=((gt(n)|0)^1)&1,s=n)),m0(e,0,r)|0?(l=w(Tn(t[e+996>>2]|0,r)),_=1,l=w(l+w(mt(e,0,n)))):(l=w(Tn(e+388|0,r)),l>=w(0)?_=2:(_=((gt(r)|0)^1)&1,l=r)),d=e+976|0,(ht(e,s,l,o,y,_,n,r,1,3189,t[d>>2]|0)|0?(Yo(e,t[e+496>>2]|0,n,r,n),bi(e,w(D[(t[d>>2]|0)+4>>2]),w(0),w(0)),c[11696]|0):0)&&ff(e,7)}function $r(e){e=e|0;var n=0,r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0;_=h,h=h+32|0,d=_+24|0,l=_+16|0,o=_+8|0,s=_,r=0;do n=e+380+(r<<3)|0,((t[e+380+(r<<3)+4>>2]|0)!=0?(y=n,k=t[y+4>>2]|0,T=o,t[T>>2]=t[y>>2],t[T+4>>2]=k,T=e+364+(r<<3)|0,k=t[T+4>>2]|0,y=s,t[y>>2]=t[T>>2],t[y+4>>2]=k,t[l>>2]=t[o>>2],t[l+4>>2]=t[o+4>>2],t[d>>2]=t[s>>2],t[d+4>>2]=t[s+4>>2],o0(l,d)|0):0)||(n=e+348+(r<<3)|0),t[e+992+(r<<2)>>2]=n,r=r+1|0;while((r|0)!=2);h=_}function m0(e,n,r){e=e|0,n=n|0,r=w(r);var o=0;switch(e=t[e+992+(t[976+(n<<2)>>2]<<2)>>2]|0,t[e+4>>2]|0){case 0:case 3:{e=0;break}case 1:{w(D[e>>2])>2])>2]|0){case 2:{n=w(w(w(D[e>>2])*n)/w(100));break}case 1:{n=w(D[e>>2]);break}default:n=w(J)}return w(n)}function Yo(e,n,r,o,s){e=e|0,n=n|0,r=w(r),o=w(o),s=w(s);var l=0,d=tt;n=t[e+944>>2]|0?n:1,l=N0(t[e+4>>2]|0,n)|0,n=Cl(l,n)|0,r=w(Wr(e,l,r)),o=w(Wr(e,n,o)),d=w(r+w(Tr(e,l,s))),D[e+400+(t[1040+(l<<2)>>2]<<2)>>2]=d,r=w(r+w(R0(e,l,s))),D[e+400+(t[1e3+(l<<2)>>2]<<2)>>2]=r,r=w(o+w(Tr(e,n,s))),D[e+400+(t[1040+(n<<2)>>2]<<2)>>2]=r,s=w(o+w(R0(e,n,s))),D[e+400+(t[1e3+(n<<2)>>2]<<2)>>2]=s}function bi(e,n,r,o){e=e|0,n=w(n),r=w(r),o=w(o);var s=0,l=0,d=tt,_=tt,y=0,k=0,T=tt,P=0,q=tt,we=tt,le=tt,ie=tt;if(n!=w(0)&&(s=e+400|0,ie=w(D[s>>2]),l=e+404|0,le=w(D[l>>2]),P=e+416|0,we=w(D[P>>2]),k=e+420|0,d=w(D[k>>2]),q=w(ie+r),T=w(le+o),o=w(q+we),_=w(T+d),y=(t[e+988>>2]|0)==1,D[s>>2]=w($0(ie,n,0,y)),D[l>>2]=w($0(le,n,0,y)),r=w(V4(w(we*n),w(1))),Vr(r,w(0))|0?l=0:l=(Vr(r,w(1))|0)^1,r=w(V4(w(d*n),w(1))),Vr(r,w(0))|0?s=0:s=(Vr(r,w(1))|0)^1,ie=w($0(o,n,y&l,y&(l^1))),D[P>>2]=w(ie-w($0(q,n,0,y))),ie=w($0(_,n,y&s,y&(s^1))),D[k>>2]=w(ie-w($0(T,n,0,y))),l=(t[e+952>>2]|0)-(t[e+948>>2]|0)>>2,l|0)){s=0;do bi(e0(e,s)|0,n,q,T),s=s+1|0;while((s|0)!=(l|0))}}function or(e,n,r,o,s){switch(e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,r|0){case 5:case 0:{e=q8(t[489]|0,o,s)|0;break}default:e=AL(o,s)|0}return e|0}function zs(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0;s=h,h=h+16|0,l=s,t[l>>2]=o,Ku(e,0,n,r,l),h=s}function Ku(e,n,r,o,s){if(e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,e=e|0?e:956,sD[t[e+8>>2]&1](e,n,r,o,s)|0,(r|0)==5)_n();else return}function J0(e,n,r){e=e|0,n=n|0,r=r|0,c[e+n>>0]=r&1}function af(e,n){e=e|0,n=n|0;var r=0,o=0;t[e>>2]=0,t[e+4>>2]=0,t[e+8>>2]=0,r=n+4|0,o=(t[r>>2]|0)-(t[n>>2]|0)>>2,o|0&&(S0(e,o),El(e,t[n>>2]|0,t[r>>2]|0,o))}function S0(e,n){e=e|0,n=n|0;var r=0;if((Q0(e)|0)>>>0>>0&&$n(e),n>>>0>1073741823)_n();else{r=Tt(n<<2)|0,t[e+4>>2]=r,t[e>>2]=r,t[e+8>>2]=r+(n<<2);return}}function El(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0,o=e+4|0,e=r-n|0,(e|0)>0&&(vn(t[o>>2]|0,n|0,e|0)|0,t[o>>2]=(t[o>>2]|0)+(e>>>2<<2))}function Q0(e){return e=e|0,1073741823}function Tr(e,n,r){return e=e|0,n=n|0,r=w(r),(Nr(n)|0?(t[e+96>>2]|0)!=0:0)?e=e+92|0:e=en(e+60|0,t[1040+(n<<2)>>2]|0,992)|0,w(uo(e,r))}function R0(e,n,r){return e=e|0,n=n|0,r=w(r),(Nr(n)|0?(t[e+104>>2]|0)!=0:0)?e=e+100|0:e=en(e+60|0,t[1e3+(n<<2)>>2]|0,992)|0,w(uo(e,r))}function Nr(e){return e=e|0,(e|1|0)==3|0}function uo(e,n){return e=e|0,n=w(n),(t[e+4>>2]|0)==3?n=w(0):n=w(Tn(e,n)),w(n)}function so(e,n){return e=e|0,n=n|0,e=t[e>>2]|0,((e|0)==0?(n|0)>1?n:1:e)|0}function N0(e,n){e=e|0,n=n|0;var r=0;e:do if((n|0)==2){switch(e|0){case 2:{e=3;break e}case 3:break;default:{r=4;break e}}e=2}else r=4;while(0);return e|0}function C0(e,n){e=e|0,n=n|0;var r=tt;return((Nr(n)|0?(t[e+312>>2]|0)!=0:0)?(r=w(D[e+308>>2]),r>=w(0)):0)||(r=w(Ur(w(D[(en(e+276|0,t[1040+(n<<2)>>2]|0,992)|0)>>2]),w(0)))),w(r)}function di(e,n){e=e|0,n=n|0;var r=tt;return((Nr(n)|0?(t[e+320>>2]|0)!=0:0)?(r=w(D[e+316>>2]),r>=w(0)):0)||(r=w(Ur(w(D[(en(e+276|0,t[1e3+(n<<2)>>2]|0,992)|0)>>2]),w(0)))),w(r)}function u0(e,n,r){e=e|0,n=n|0,r=w(r);var o=tt;return((Nr(n)|0?(t[e+240>>2]|0)!=0:0)?(o=w(Tn(e+236|0,r)),o>=w(0)):0)||(o=w(Ur(w(Tn(en(e+204|0,t[1040+(n<<2)>>2]|0,992)|0,r)),w(0)))),w(o)}function v0(e,n,r){e=e|0,n=n|0,r=w(r);var o=tt;return((Nr(n)|0?(t[e+248>>2]|0)!=0:0)?(o=w(Tn(e+244|0,r)),o>=w(0)):0)||(o=w(Ur(w(Tn(en(e+204|0,t[1e3+(n<<2)>>2]|0,992)|0,r)),w(0)))),w(o)}function To(e,n,r,o,s,l,d){e=e|0,n=w(n),r=w(r),o=o|0,s=s|0,l=w(l),d=w(d);var _=tt,y=tt,k=tt,T=tt,P=tt,q=tt,we=0,le=0,ie=0;ie=h,h=h+16|0,we=ie,le=e+964|0,i0(e,(t[le>>2]|0)!=0,3519),_=w(Fn(e,2,n)),y=w(Fn(e,0,n)),k=w(mt(e,2,n)),T=w(mt(e,0,n)),gt(n)|0?P=n:P=w(Ur(w(0),w(w(n-k)-_))),gt(r)|0?q=r:q=w(Ur(w(0),w(w(r-T)-y))),(o|0)==1&(s|0)==1?(D[e+908>>2]=w(kn(e,2,w(n-k),l,l)),n=w(kn(e,0,w(r-T),d,l))):(lD[t[le>>2]&1](we,e,P,o,q,s),P=w(_+w(D[we>>2])),q=w(n-k),D[e+908>>2]=w(kn(e,2,(o|2|0)==2?P:q,l,l)),q=w(y+w(D[we+4>>2])),n=w(r-T),n=w(kn(e,0,(s|2|0)==2?q:n,d,l))),D[e+912>>2]=n,h=ie}function pu(e,n,r,o,s,l,d){e=e|0,n=w(n),r=w(r),o=o|0,s=s|0,l=w(l),d=w(d);var _=tt,y=tt,k=tt,T=tt;k=w(Fn(e,2,l)),_=w(Fn(e,0,l)),T=w(mt(e,2,l)),y=w(mt(e,0,l)),n=w(n-T),D[e+908>>2]=w(kn(e,2,(o|2|0)==2?k:n,l,l)),r=w(r-y),D[e+912>>2]=w(kn(e,0,(s|2|0)==2?_:r,d,l))}function Sl(e,n,r,o,s,l,d){e=e|0,n=w(n),r=w(r),o=o|0,s=s|0,l=w(l),d=w(d);var _=0,y=tt,k=tt;return _=(o|0)==2,((n<=w(0)&_?0:!(r<=w(0)&(s|0)==2))?!((o|0)==1&(s|0)==1):0)?e=0:(y=w(mt(e,0,l)),k=w(mt(e,2,l)),_=n>2]=w(kn(e,2,_?w(0):n,l,l)),n=w(r-y),_=r>2]=w(kn(e,0,_?w(0):n,d,l)),e=1),e|0}function Cl(e,n){return e=e|0,n=n|0,qt(e)|0?e=N0(2,n)|0:e=0,e|0}function B0(e,n,r){return e=e|0,n=n|0,r=w(r),r=w(u0(e,n,r)),w(r+w(C0(e,n)))}function hu(e,n,r){return e=e|0,n=n|0,r=w(r),r=w(v0(e,n,r)),w(r+w(di(e,n)))}function Fn(e,n,r){e=e|0,n=n|0,r=w(r);var o=tt;return o=w(B0(e,n,r)),w(o+w(hu(e,n,r)))}function pi(e){return e=e|0,t[e+24>>2]|0?e=0:w(Br(e))!=w(0)?e=1:e=w(zr(e))!=w(0),e|0}function Br(e){e=e|0;var n=tt;if(t[e+944>>2]|0){if(n=w(D[e+44>>2]),gt(n)|0)return n=w(D[e+40>>2]),e=n>w(0)&((gt(n)|0)^1),w(e?n:w(0))}else n=w(0);return w(n)}function zr(e){e=e|0;var n=tt,r=0,o=tt;do if(t[e+944>>2]|0){if(n=w(D[e+48>>2]),gt(n)|0){if(r=c[(t[e+976>>2]|0)+2>>0]|0,r<<24>>24==0?(o=w(D[e+40>>2]),o>24?w(1):w(0)}}else n=w(0);while(0);return w(n)}function lo(e){e=e|0;var n=0,r=0;if(pa(e+400|0,0,540)|0,c[e+985>>0]=1,bo(e),r=fi(e)|0,r|0){n=e+948|0,e=0;do lo(t[(t[n>>2]|0)+(e<<2)>>2]|0),e=e+1|0;while((e|0)!=(r|0))}}function wr(e,n,r,o,s,l,d,_,y,k){e=e|0,n=n|0,r=w(r),o=o|0,s=w(s),l=w(l),d=w(d),_=_|0,y=y|0,k=k|0;var T=0,P=tt,q=0,we=0,le=tt,ie=tt,Pe=0,ke=tt,qe=0,pe=tt,_e=0,vt=0,Ln=0,Ht=0,It=0,gn=0,Pn=0,zt=0,Dr=0,Ki=0;Dr=h,h=h+16|0,Ln=Dr+12|0,Ht=Dr+8|0,It=Dr+4|0,gn=Dr,zt=N0(t[e+4>>2]|0,y)|0,_e=Nr(zt)|0,P=w(Tn(Ut(n)|0,_e?l:d)),vt=m0(n,2,l)|0,Pn=m0(n,0,d)|0;do if(gt(P)|0?0:!(gt(_e?r:s)|0)){if(T=n+504|0,!(gt(w(D[T>>2]))|0)&&(!(fn(t[n+976>>2]|0,0)|0)||(t[n+500>>2]|0)==(t[2278]|0)))break;D[T>>2]=w(Ur(P,w(Fn(n,zt,l))))}else q=7;while(0);do if((q|0)==7){if(qe=_e^1,!(qe|vt^1)){d=w(Tn(t[n+992>>2]|0,l)),D[n+504>>2]=w(Ur(d,w(Fn(n,2,l))));break}if(!(_e|Pn^1)){d=w(Tn(t[n+996>>2]|0,d)),D[n+504>>2]=w(Ur(d,w(Fn(n,0,l))));break}D[Ln>>2]=w(J),D[Ht>>2]=w(J),t[It>>2]=0,t[gn>>2]=0,ke=w(mt(n,2,l)),pe=w(mt(n,0,l)),vt?(le=w(ke+w(Tn(t[n+992>>2]|0,l))),D[Ln>>2]=le,t[It>>2]=1,we=1):(we=0,le=w(J)),Pn?(P=w(pe+w(Tn(t[n+996>>2]|0,d))),D[Ht>>2]=P,t[gn>>2]=1,T=1):(T=0,P=w(J)),q=t[e+32>>2]|0,_e&(q|0)==2?q=2:(gt(le)|0?!(gt(r)|0):0)&&(D[Ln>>2]=r,t[It>>2]=2,we=2,le=r),(((q|0)==2&qe?0:gt(P)|0)?!(gt(s)|0):0)&&(D[Ht>>2]=s,t[gn>>2]=2,T=2,P=s),ie=w(D[n+396>>2]),Pe=gt(ie)|0;do if(Pe)q=we;else{if((we|0)==1&qe){D[Ht>>2]=w(w(le-ke)/ie),t[gn>>2]=1,T=1,q=1;break}_e&(T|0)==1?(D[Ln>>2]=w(ie*w(P-pe)),t[It>>2]=1,T=1,q=1):q=we}while(0);Ki=gt(r)|0,we=(T0(e,n)|0)!=4,(_e|vt|((o|0)!=1|Ki)|(we|(q|0)==1)?0:(D[Ln>>2]=r,t[It>>2]=1,!Pe))&&(D[Ht>>2]=w(w(r-ke)/ie),t[gn>>2]=1,T=1),(Pn|qe|((_|0)!=1|(gt(s)|0))|(we|(T|0)==1)?0:(D[Ht>>2]=s,t[gn>>2]=1,!Pe))&&(D[Ln>>2]=w(ie*w(s-pe)),t[It>>2]=1),Kt(n,2,l,l,It,Ln),Kt(n,0,d,l,gn,Ht),r=w(D[Ln>>2]),s=w(D[Ht>>2]),ht(n,r,s,y,t[It>>2]|0,t[gn>>2]|0,l,d,0,3565,k)|0,d=w(D[n+908+(t[976+(zt<<2)>>2]<<2)>>2]),D[n+504>>2]=w(Ur(d,w(Fn(n,zt,l))))}while(0);t[n+500>>2]=t[2278],h=Dr}function kn(e,n,r,o,s){return e=e|0,n=n|0,r=w(r),o=w(o),s=w(s),o=w(Dt(e,n,r,o)),w(Ur(o,w(Fn(e,n,s))))}function T0(e,n){return e=e|0,n=n|0,n=n+20|0,n=t[((t[n>>2]|0)==0?e+16|0:n)>>2]|0,((n|0)==5?qt(t[e+4>>2]|0)|0:0)&&(n=1),n|0}function hi(e,n){return e=e|0,n=n|0,(Nr(n)|0?(t[e+96>>2]|0)!=0:0)?n=4:n=t[1040+(n<<2)>>2]|0,e+60+(n<<3)|0}function Ai(e,n){return e=e|0,n=n|0,(Nr(n)|0?(t[e+104>>2]|0)!=0:0)?n=5:n=t[1e3+(n<<2)>>2]|0,e+60+(n<<3)|0}function Kt(e,n,r,o,s,l){switch(e=e|0,n=n|0,r=w(r),o=w(o),s=s|0,l=l|0,r=w(Tn(e+380+(t[976+(n<<2)>>2]<<3)|0,r)),r=w(r+w(mt(e,n,o))),t[s>>2]|0){case 2:case 1:{s=gt(r)|0,o=w(D[l>>2]),D[l>>2]=s|o>2]=2,D[l>>2]=r);break}default:}}function X(e,n){return e=e|0,n=n|0,e=e+132|0,(Nr(n)|0?(t[(en(e,4,948)|0)+4>>2]|0)!=0:0)?e=1:e=(t[(en(e,t[1040+(n<<2)>>2]|0,948)|0)+4>>2]|0)!=0,e|0}function Y(e,n,r){e=e|0,n=n|0,r=w(r);var o=0,s=0;return e=e+132|0,(Nr(n)|0?(o=en(e,4,948)|0,(t[o+4>>2]|0)!=0):0)?s=4:(o=en(e,t[1040+(n<<2)>>2]|0,948)|0,t[o+4>>2]|0?s=4:r=w(0)),(s|0)==4&&(r=w(Tn(o,r))),w(r)}function ye(e,n,r){e=e|0,n=n|0,r=w(r);var o=tt;return o=w(D[e+908+(t[976+(n<<2)>>2]<<2)>>2]),o=w(o+w(Tr(e,n,r))),w(o+w(R0(e,n,r)))}function he(e){e=e|0;var n=0,r=0,o=0;e:do if(qt(t[e+4>>2]|0)|0)n=0;else if((t[e+16>>2]|0)!=5)if(r=fi(e)|0,!r)n=0;else for(n=0;;){if(o=e0(e,n)|0,(t[o+24>>2]|0)==0?(t[o+20>>2]|0)==5:0){n=1;break e}if(n=n+1|0,n>>>0>=r>>>0){n=0;break}}else n=1;while(0);return n|0}function We(e,n){e=e|0,n=n|0;var r=tt;return r=w(D[e+908+(t[976+(n<<2)>>2]<<2)>>2]),r>=w(0)&((gt(r)|0)^1)|0}function et(e){e=e|0;var n=tt,r=0,o=0,s=0,l=0,d=0,_=0,y=tt;if(r=t[e+968>>2]|0,r)y=w(D[e+908>>2]),n=w(D[e+912>>2]),n=w(rD[r&0](e,y,n)),i0(e,(gt(n)|0)^1,3573);else{l=fi(e)|0;do if(l|0){for(r=0,s=0;;){if(o=e0(e,s)|0,t[o+940>>2]|0){d=8;break}if((t[o+24>>2]|0)!=1)if(_=(T0(e,o)|0)==5,_){r=o;break}else r=(r|0)==0?o:r;if(s=s+1|0,s>>>0>=l>>>0){d=8;break}}if((d|0)==8&&!r)break;return n=w(et(r)),w(n+w(D[r+404>>2]))}while(0);n=w(D[e+912>>2])}return w(n)}function Dt(e,n,r,o){e=e|0,n=n|0,r=w(r),o=w(o);var s=tt,l=0;return qt(n)|0?(n=1,l=3):Nr(n)|0?(n=0,l=3):(o=w(J),s=w(J)),(l|0)==3&&(s=w(Tn(e+364+(n<<3)|0,o)),o=w(Tn(e+380+(n<<3)|0,o))),l=o=w(0)&((gt(o)|0)^1)),r=l?o:r,l=s>=w(0)&((gt(s)|0)^1)&r>2]|0,l)|0,le=Cl(Pe,l)|0,ie=Nr(Pe)|0,P=w(mt(n,2,r)),q=w(mt(n,0,r)),m0(n,2,r)|0?_=w(P+w(Tn(t[n+992>>2]|0,r))):(X(n,2)|0?_t(n,2)|0:0)?(_=w(D[e+908>>2]),y=w(C0(e,2)),y=w(_-w(y+w(di(e,2)))),_=w(Y(n,2,r)),_=w(kn(n,2,w(y-w(_+w(_r(n,2,r)))),r,r))):_=w(J),m0(n,0,s)|0?y=w(q+w(Tn(t[n+996>>2]|0,s))):(X(n,0)|0?_t(n,0)|0:0)?(y=w(D[e+912>>2]),qe=w(C0(e,0)),qe=w(y-w(qe+w(di(e,0)))),y=w(Y(n,0,s)),y=w(kn(n,0,w(qe-w(y+w(_r(n,0,s)))),s,r))):y=w(J),k=gt(_)|0,T=gt(y)|0;do if(k^T?(we=w(D[n+396>>2]),!(gt(we)|0)):0)if(k){_=w(P+w(w(y-q)*we));break}else{qe=w(q+w(w(_-P)/we)),y=T?qe:y;break}while(0);T=gt(_)|0,k=gt(y)|0,T|k&&(pe=(T^1)&1,o=r>w(0)&((o|0)!=0&T),_=ie?_:o?r:_,ht(n,_,y,l,ie?pe:o?2:pe,T&(k^1)&1,_,y,0,3623,d)|0,_=w(D[n+908>>2]),_=w(_+w(mt(n,2,r))),y=w(D[n+912>>2]),y=w(y+w(mt(n,0,r)))),ht(n,_,y,l,1,1,_,y,1,3635,d)|0,(_t(n,Pe)|0?!(X(n,Pe)|0):0)?(pe=t[976+(Pe<<2)>>2]|0,qe=w(D[e+908+(pe<<2)>>2]),qe=w(qe-w(D[n+908+(pe<<2)>>2])),qe=w(qe-w(di(e,Pe))),qe=w(qe-w(R0(n,Pe,r))),qe=w(qe-w(_r(n,Pe,ie?r:s))),D[n+400+(t[1040+(Pe<<2)>>2]<<2)>>2]=qe):ke=21;do if((ke|0)==21){if(X(n,Pe)|0?0:(t[e+8>>2]|0)==1){pe=t[976+(Pe<<2)>>2]|0,qe=w(D[e+908+(pe<<2)>>2]),qe=w(w(qe-w(D[n+908+(pe<<2)>>2]))*w(.5)),D[n+400+(t[1040+(Pe<<2)>>2]<<2)>>2]=qe;break}(X(n,Pe)|0?0:(t[e+8>>2]|0)==2)&&(pe=t[976+(Pe<<2)>>2]|0,qe=w(D[e+908+(pe<<2)>>2]),qe=w(qe-w(D[n+908+(pe<<2)>>2])),D[n+400+(t[1040+(Pe<<2)>>2]<<2)>>2]=qe)}while(0);(_t(n,le)|0?!(X(n,le)|0):0)?(pe=t[976+(le<<2)>>2]|0,qe=w(D[e+908+(pe<<2)>>2]),qe=w(qe-w(D[n+908+(pe<<2)>>2])),qe=w(qe-w(di(e,le))),qe=w(qe-w(R0(n,le,r))),qe=w(qe-w(_r(n,le,ie?s:r))),D[n+400+(t[1040+(le<<2)>>2]<<2)>>2]=qe):ke=30;do if((ke|0)==30?!(X(n,le)|0):0){if((T0(e,n)|0)==2){pe=t[976+(le<<2)>>2]|0,qe=w(D[e+908+(pe<<2)>>2]),qe=w(w(qe-w(D[n+908+(pe<<2)>>2]))*w(.5)),D[n+400+(t[1040+(le<<2)>>2]<<2)>>2]=qe;break}pe=(T0(e,n)|0)==3,pe^(t[e+28>>2]|0)==2&&(pe=t[976+(le<<2)>>2]|0,qe=w(D[e+908+(pe<<2)>>2]),qe=w(qe-w(D[n+908+(pe<<2)>>2])),D[n+400+(t[1040+(le<<2)>>2]<<2)>>2]=qe)}while(0)}function Zt(e,n,r){e=e|0,n=n|0,r=r|0;var o=tt,s=0;s=t[976+(r<<2)>>2]|0,o=w(D[n+908+(s<<2)>>2]),o=w(w(D[e+908+(s<<2)>>2])-o),o=w(o-w(D[n+400+(t[1040+(r<<2)>>2]<<2)>>2])),D[n+400+(t[1e3+(r<<2)>>2]<<2)>>2]=o}function qt(e){return e=e|0,(e|1|0)==1|0}function Ut(e){e=e|0;var n=tt;switch(t[e+56>>2]|0){case 0:case 3:{n=w(D[e+40>>2]),n>w(0)&((gt(n)|0)^1)?e=c[(t[e+976>>2]|0)+2>>0]|0?1056:992:e=1056;break}default:e=e+52|0}return e|0}function fn(e,n){return e=e|0,n=n|0,(c[e+n>>0]|0)!=0|0}function _t(e,n){return e=e|0,n=n|0,e=e+132|0,(Nr(n)|0?(t[(en(e,5,948)|0)+4>>2]|0)!=0:0)?e=1:e=(t[(en(e,t[1e3+(n<<2)>>2]|0,948)|0)+4>>2]|0)!=0,e|0}function _r(e,n,r){e=e|0,n=n|0,r=w(r);var o=0,s=0;return e=e+132|0,(Nr(n)|0?(o=en(e,5,948)|0,(t[o+4>>2]|0)!=0):0)?s=4:(o=en(e,t[1e3+(n<<2)>>2]|0,948)|0,t[o+4>>2]|0?s=4:r=w(0)),(s|0)==4&&(r=w(Tn(o,r))),w(r)}function Wr(e,n,r){return e=e|0,n=n|0,r=w(r),X(e,n)|0?r=w(Y(e,n,r)):r=w(-w(_r(e,n,r))),w(r)}function Ar(e){return e=w(e),D[j>>2]=e,t[j>>2]|0|0}function z(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>1073741823)_n();else{s=Tt(n<<2)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r<<2)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n<<2)}function dr(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(0-(s>>2)<<2)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function Or(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~((o+-4-n|0)>>>2)<<2)),e=t[e>>2]|0,e|0&&Ve(e)}function Qn(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0;if(d=e+4|0,_=t[d>>2]|0,s=_-o|0,l=s>>2,e=n+(l<<2)|0,e>>>0>>0){o=_;do t[o>>2]=t[e>>2],e=e+4|0,o=(t[d>>2]|0)+4|0,t[d>>2]=o;while(e>>>0>>0)}l|0&&Y1(_+(0-l<<2)|0,n|0,s|0)|0}function nn(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0;return _=n+4|0,y=t[_>>2]|0,s=t[e>>2]|0,d=r,l=d-s|0,o=y+(0-(l>>2)<<2)|0,t[_>>2]=o,(l|0)>0&&vn(o|0,s|0,l|0)|0,s=e+4|0,l=n+8|0,o=(t[s>>2]|0)-d|0,(o|0)>0&&(vn(t[l>>2]|0,r|0,o|0)|0,t[l>>2]=(t[l>>2]|0)+(o>>>2<<2)),d=t[e>>2]|0,t[e>>2]=t[_>>2],t[_>>2]=d,d=t[s>>2]|0,t[s>>2]=t[l>>2],t[l>>2]=d,d=e+8|0,r=n+12|0,e=t[d>>2]|0,t[d>>2]=t[r>>2],t[r>>2]=e,t[n>>2]=t[_>>2],y|0}function s0(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;if(d=t[n>>2]|0,l=t[r>>2]|0,(d|0)!=(l|0)){s=e+8|0,r=((l+-4-d|0)>>>2)+1|0,e=d,o=t[s>>2]|0;do t[o>>2]=t[e>>2],o=(t[s>>2]|0)+4|0,t[s>>2]=o,e=e+4|0;while((e|0)!=(l|0));t[n>>2]=d+(r<<2)}}function t0(){_l()}function g0(){var e=0;return e=Tt(4)|0,Kr(e),e|0}function Kr(e){e=e|0,t[e>>2]=a0()|0}function _0(e){e=e|0,e|0&&(Gi(e),Ve(e))}function Gi(e){e=e|0,V0(t[e>>2]|0)}function fo(e,n,r){e=e|0,n=n|0,r=r|0,J0(t[e>>2]|0,n,r)}function x0(e,n){e=e|0,n=w(n),ki(t[e>>2]|0,n)}function Xu(e,n){return e=e|0,n=n|0,fn(t[e>>2]|0,n)|0}function Z0(){var e=0;return e=Tt(8)|0,df(e,0),e|0}function df(e,n){e=e|0,n=n|0,n?n=I0(t[n>>2]|0)|0:n=qu()|0,t[e>>2]=n,t[e+4>>2]=0,Bs(n,e)}function Ba(e){e=e|0;var n=0;return n=Tt(8)|0,df(n,e),n|0}function Oc(e){e=e|0,e|0&&(mu(e),Ve(e))}function mu(e){e=e|0;var n=0;Wu(t[e>>2]|0),n=e+4|0,e=t[n>>2]|0,t[n>>2]=0,e|0&&(Ju(e),Ve(e))}function Ju(e){e=e|0,ei(e)}function ei(e){e=e|0,e=t[e>>2]|0,e|0&&ju(e|0)}function Yf(e){return e=e|0,Vu(e)|0}function pf(e){e=e|0;var n=0,r=0;r=e+4|0,n=t[r>>2]|0,t[r>>2]=0,n|0&&(Ju(n),Ve(n)),Do(t[e>>2]|0)}function ja(e,n){e=e|0,n=n|0,Gu(t[e>>2]|0,t[n>>2]|0)}function Ua(e,n){e=e|0,n=n|0,W(t[e>>2]|0,n)}function Ic(e,n,r){e=e|0,n=n|0,r=+r,yn(t[e>>2]|0,n,w(r))}function vu(e,n,r){e=e|0,n=n|0,r=+r,sn(t[e>>2]|0,n,w(r))}function $f(e,n){e=e|0,n=n|0,R(t[e>>2]|0,n)}function gu(e,n){e=e|0,n=n|0,H(t[e>>2]|0,n)}function co(e,n){e=e|0,n=n|0,ue(t[e>>2]|0,n)}function qa(e,n){e=e|0,n=n|0,M0(t[e>>2]|0,n)}function Ws(e,n){e=e|0,n=n|0,Fe(t[e>>2]|0,n)}function za(e,n){e=e|0,n=n|0,Lr(t[e>>2]|0,n)}function Pc(e,n,r){e=e|0,n=n|0,r=+r,rn(t[e>>2]|0,n,w(r))}function Qu(e,n,r){e=e|0,n=n|0,r=+r,Hn(t[e>>2]|0,n,w(r))}function Mc(e,n){e=e|0,n=n|0,Cr(t[e>>2]|0,n)}function Fc(e,n){e=e|0,n=n|0,K(t[e>>2]|0,n)}function Lc(e,n){e=e|0,n=n|0,je(t[e>>2]|0,n)}function Kf(e,n){e=e|0,n=+n,rt(t[e>>2]|0,w(n))}function Tl(e,n){e=e|0,n=+n,wt(t[e>>2]|0,w(n))}function xl(e,n){e=e|0,n=+n,lt(t[e>>2]|0,w(n))}function hf(e,n){e=e|0,n=+n,st(t[e>>2]|0,w(n))}function xo(e,n){e=e|0,n=+n,xt(t[e>>2]|0,w(n))}function mf(e,n){e=e|0,n=+n,Qt(t[e>>2]|0,w(n))}function Wa(e,n){e=e|0,n=+n,Cn(t[e>>2]|0,w(n))}function ti(e){e=e|0,bn(t[e>>2]|0)}function Hs(e,n){e=e|0,n=+n,h0(t[e>>2]|0,w(n))}function mi(e,n){e=e|0,n=+n,ci(t[e>>2]|0,w(n))}function vi(e){e=e|0,xi(t[e>>2]|0)}function Xf(e,n){e=e|0,n=+n,qr(t[e>>2]|0,w(n))}function Rc(e,n){e=e|0,n=+n,Eo(t[e>>2]|0,w(n))}function Jf(e,n){e=e|0,n=+n,wl(t[e>>2]|0,w(n))}function ao(e,n){e=e|0,n=+n,js(t[e>>2]|0,w(n))}function $o(e,n){e=e|0,n=+n,du(t[e>>2]|0,w(n))}function kl(e,n){e=e|0,n=+n,Yu(t[e>>2]|0,w(n))}function Nc(e,n){e=e|0,n=+n,oo(t[e>>2]|0,w(n))}function Al(e,n){e=e|0,n=+n,Hi(t[e>>2]|0,w(n))}function vf(e,n){e=e|0,n=+n,F0(t[e>>2]|0,w(n))}function Qf(e,n,r){e=e|0,n=n|0,r=+r,ft(t[e>>2]|0,n,w(r))}function k0(e,n,r){e=e|0,n=n|0,r=+r,He(t[e>>2]|0,n,w(r))}function v(e,n,r){e=e|0,n=n|0,r=+r,Qe(t[e>>2]|0,n,w(r))}function m(e){return e=e|0,ve(t[e>>2]|0)|0}function S(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0;o=h,h=h+16|0,s=o,ar(s,t[n>>2]|0,r),O(e,s),h=o}function O(e,n){e=e|0,n=n|0,M(e,t[n+4>>2]|0,+w(D[n>>2]))}function M(e,n,r){e=e|0,n=n|0,r=+r,t[e>>2]=n,L[e+8>>3]=r}function b(e){return e=e|0,U(t[e>>2]|0)|0}function ee(e){return e=e|0,fe(t[e>>2]|0)|0}function Ye(e){return e=e|0,de(t[e>>2]|0)|0}function Ze(e){return e=e|0,au(t[e>>2]|0)|0}function ut(e){return e=e|0,Ge(t[e>>2]|0)|0}function In(e){return e=e|0,F(t[e>>2]|0)|0}function A0(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0;o=h,h=h+16|0,s=o,d0(s,t[n>>2]|0,r),O(e,s),h=o}function jr(e){return e=e|0,xe(t[e>>2]|0)|0}function gi(e){return e=e|0,Xe(t[e>>2]|0)|0}function po(e,n){e=e|0,n=n|0;var r=0,o=0;r=h,h=h+16|0,o=r,Rt(o,t[n>>2]|0),O(e,o),h=r}function _i(e){return e=e|0,+ +w(yl(t[e>>2]|0))}function Re(e){return e=e|0,+ +w(cu(t[e>>2]|0))}function Ce(e,n){e=e|0,n=n|0;var r=0,o=0;r=h,h=h+16|0,o=r,p0(o,t[n>>2]|0),O(e,o),h=r}function ze(e,n){e=e|0,n=n|0;var r=0,o=0;r=h,h=h+16|0,o=r,E0(o,t[n>>2]|0),O(e,o),h=r}function Et(e,n){e=e|0,n=n|0;var r=0,o=0;r=h,h=h+16|0,o=r,So(o,t[n>>2]|0),O(e,o),h=r}function on(e,n){e=e|0,n=n|0;var r=0,o=0;r=h,h=h+16|0,o=r,Dl(o,t[n>>2]|0),O(e,o),h=r}function sr(e,n){e=e|0,n=n|0;var r=0,o=0;r=h,h=h+16|0,o=r,Us(o,t[n>>2]|0),O(e,o),h=r}function mn(e,n){e=e|0,n=n|0;var r=0,o=0;r=h,h=h+16|0,o=r,qs(o,t[n>>2]|0),O(e,o),h=r}function pr(e){return e=e|0,+ +w(Gr(t[e>>2]|0))}function Hr(e,n){return e=e|0,n=n|0,+ +w(St(t[e>>2]|0,n))}function Vn(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0;o=h,h=h+16|0,s=o,Ne(s,t[n>>2]|0,r),O(e,s),h=o}function ni(e,n,r){e=e|0,n=n|0,r=r|0,Ns(t[e>>2]|0,t[n>>2]|0,r)}function Zf(e,n){e=e|0,n=n|0,D0(t[e>>2]|0,t[n>>2]|0)}function Pm(e){return e=e|0,fi(t[e>>2]|0)|0}function Ha(e){return e=e|0,e=nr(t[e>>2]|0)|0,e?e=Yf(e)|0:e=0,e|0}function vd(e,n){return e=e|0,n=n|0,e=e0(t[e>>2]|0,n)|0,e?e=Yf(e)|0:e=0,e|0}function gd(e,n){e=e|0,n=n|0;var r=0,o=0;o=Tt(4)|0,ba(o,n),r=e+4|0,n=t[r>>2]|0,t[r>>2]=o,n|0&&(Ju(n),Ve(n)),bu(t[e>>2]|0,1)}function ba(e,n){e=e|0,n=n|0,Oo(e,n)}function Bc(e,n,r,o,s,l){e=e|0,n=n|0,r=w(r),o=o|0,s=w(s),l=l|0;var d=0,_=0;d=h,h=h+16|0,_=d,Mm(_,Vu(n)|0,+r,o,+s,l),D[e>>2]=w(+L[_>>3]),D[e+4>>2]=w(+L[_+8>>3]),h=d}function Mm(e,n,r,o,s,l){e=e|0,n=n|0,r=+r,o=o|0,s=+s,l=l|0;var d=0,_=0,y=0,k=0,T=0;d=h,h=h+32|0,T=d+8|0,k=d+20|0,y=d,_=d+16|0,L[T>>3]=r,t[k>>2]=o,L[y>>3]=s,t[_>>2]=l,_d(e,t[n+4>>2]|0,T,k,y,_),h=d}function _d(e,n,r,o,s,l){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0;var d=0,_=0;d=h,h=h+16|0,_=d,Zo(_),n=Oi(n)|0,Fm(e,n,+L[r>>3],t[o>>2]|0,+L[s>>3],t[l>>2]|0),eu(_),h=d}function Oi(e){return e=e|0,t[e>>2]|0}function Fm(e,n,r,o,s,l){e=e|0,n=n|0,r=+r,o=o|0,s=+s,l=l|0;var d=0;d=ko(yd()|0)|0,r=+Ko(r),o=jc(o)|0,s=+Ko(s),Ga(e,ro(0,d|0,n|0,+r,o|0,+s,jc(l)|0)|0)}function yd(){var e=0;return c[7608]|0||(Ed(9120),e=7608,t[e>>2]=1,t[e+4>>2]=0),9120}function ko(e){return e=e|0,t[e+8>>2]|0}function Ko(e){return e=+e,+ +Ol(e)}function jc(e){return e=e|0,Dd(e)|0}function Ga(e,n){e=e|0,n=n|0;var r=0,o=0,s=0;s=h,h=h+32|0,r=s,o=n,o&1?(Lm(r,0),c0(o|0,r|0)|0,Va(e,r),Wn(r)):(t[e>>2]=t[n>>2],t[e+4>>2]=t[n+4>>2],t[e+8>>2]=t[n+8>>2],t[e+12>>2]=t[n+12>>2]),h=s}function Lm(e,n){e=e|0,n=n|0,wd(e,n),t[e+8>>2]=0,c[e+24>>0]=0}function Va(e,n){e=e|0,n=n|0,n=n+8|0,t[e>>2]=t[n>>2],t[e+4>>2]=t[n+4>>2],t[e+8>>2]=t[n+8>>2],t[e+12>>2]=t[n+12>>2]}function Wn(e){e=e|0,c[e+24>>0]=0}function wd(e,n){e=e|0,n=n|0,t[e>>2]=n}function Dd(e){return e=e|0,e|0}function Ol(e){return e=+e,+e}function Ed(e){e=e|0,Ao(e,Rm()|0,4)}function Rm(){return 1064}function Ao(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r,t[e+8>>2]=hl(n|0,r+1|0)|0}function Oo(e,n){e=e|0,n=n|0,n=t[n>>2]|0,t[e>>2]=n,qi(n|0)}function Nm(e){e=e|0;var n=0,r=0;r=e+4|0,n=t[r>>2]|0,t[r>>2]=0,n|0&&(Ju(n),Ve(n)),bu(t[e>>2]|0,0)}function Uc(e){e=e|0,rr(t[e>>2]|0)}function Ya(e){return e=e|0,Go(t[e>>2]|0)|0}function Sd(e,n,r,o){e=e|0,n=+n,r=+r,o=o|0,Yr(t[e>>2]|0,w(n),w(r),o)}function Cd(e){return e=e|0,+ +w(ir(t[e>>2]|0))}function ho(e){return e=e|0,+ +w(Y0(t[e>>2]|0))}function bs(e){return e=e|0,+ +w(L0(t[e>>2]|0))}function $a(e){return e=e|0,+ +w(Co(t[e>>2]|0))}function Td(e){return e=e|0,+ +w($u(t[e>>2]|0))}function qc(e){return e=e|0,+ +w(Vo(t[e>>2]|0))}function xd(e,n){e=e|0,n=n|0,L[e>>3]=+w(ir(t[n>>2]|0)),L[e+8>>3]=+w(Y0(t[n>>2]|0)),L[e+16>>3]=+w(L0(t[n>>2]|0)),L[e+24>>3]=+w(Co(t[n>>2]|0)),L[e+32>>3]=+w($u(t[n>>2]|0)),L[e+40>>3]=+w(Vo(t[n>>2]|0))}function Ka(e,n){return e=e|0,n=n|0,+ +w(Rr(t[e>>2]|0,n))}function kd(e,n){return e=e|0,n=n|0,+ +w(Jn(t[e>>2]|0,n))}function Xa(e,n){return e=e|0,n=n|0,+ +w(ai(t[e>>2]|0,n))}function Ja(){return Rs()|0}function Gs(){Bm(),Vs(),Ad(),Od(),Qa(),jm()}function Bm(){hO(11713,4938,1)}function Vs(){FA(10448)}function Ad(){hA(10408)}function Od(){Bk(10324)}function Qa(){Gx(10096)}function jm(){Um(9132)}function Um(e){e=e|0;var n=0,r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0,we=0,le=0,ie=0,Pe=0,ke=0,qe=0,pe=0,_e=0,vt=0,Ln=0,Ht=0,It=0,gn=0,Pn=0,zt=0,Dr=0,Ki=0,Xi=0,Ji=0,Ro=0,kf=0,Af=0,Cu=0,Of=0,Js=0,Qs=0,If=0,Pf=0,Mf=0,Kn=0,Tu=0,Ff=0,us=0,Lf=0,Rf=0,Zs=0,el=0,ss=0,Fi=0,nu=0,go=0,xu=0,jl=0,Ul=0,tl=0,ql=0,zl=0,Li=0,Di=0,ku=0,xr=0,Wl=0,Qi=0,ls=0,Zi=0,fs=0,Hl=0,bl=0,cs=0,Ri=0,Au=0,Gl=0,Vl=0,Yl=0,En=0,br=0,Ei=0,eo=0,Ni=0,xn=0,Vt=0,Ou=0;n=h,h=h+672|0,r=n+656|0,Ou=n+648|0,Vt=n+640|0,xn=n+632|0,Ni=n+624|0,eo=n+616|0,Ei=n+608|0,br=n+600|0,En=n+592|0,Yl=n+584|0,Vl=n+576|0,Gl=n+568|0,Au=n+560|0,Ri=n+552|0,cs=n+544|0,bl=n+536|0,Hl=n+528|0,fs=n+520|0,Zi=n+512|0,ls=n+504|0,Qi=n+496|0,Wl=n+488|0,xr=n+480|0,ku=n+472|0,Di=n+464|0,Li=n+456|0,zl=n+448|0,ql=n+440|0,tl=n+432|0,Ul=n+424|0,jl=n+416|0,xu=n+408|0,go=n+400|0,nu=n+392|0,Fi=n+384|0,ss=n+376|0,el=n+368|0,Zs=n+360|0,Rf=n+352|0,Lf=n+344|0,us=n+336|0,Ff=n+328|0,Tu=n+320|0,Kn=n+312|0,Mf=n+304|0,Pf=n+296|0,If=n+288|0,Qs=n+280|0,Js=n+272|0,Of=n+264|0,Cu=n+256|0,Af=n+248|0,kf=n+240|0,Ro=n+232|0,Ji=n+224|0,Xi=n+216|0,Ki=n+208|0,Dr=n+200|0,zt=n+192|0,Pn=n+184|0,gn=n+176|0,It=n+168|0,Ht=n+160|0,Ln=n+152|0,vt=n+144|0,_e=n+136|0,pe=n+128|0,qe=n+120|0,ke=n+112|0,Pe=n+104|0,ie=n+96|0,le=n+88|0,we=n+80|0,q=n+72|0,P=n+64|0,T=n+56|0,k=n+48|0,y=n+40|0,_=n+32|0,d=n+24|0,l=n+16|0,s=n+8|0,o=n,qm(e,3646),Id(e,3651,2)|0,Pd(e,3665,2)|0,zm(e,3682,18)|0,t[Ou>>2]=19,t[Ou+4>>2]=0,t[r>>2]=t[Ou>>2],t[r+4>>2]=t[Ou+4>>2],gf(e,3690,r)|0,t[Vt>>2]=1,t[Vt+4>>2]=0,t[r>>2]=t[Vt>>2],t[r+4>>2]=t[Vt+4>>2],Md(e,3696,r)|0,t[xn>>2]=2,t[xn+4>>2]=0,t[r>>2]=t[xn>>2],t[r+4>>2]=t[xn+4>>2],Xr(e,3706,r)|0,t[Ni>>2]=1,t[Ni+4>>2]=0,t[r>>2]=t[Ni>>2],t[r+4>>2]=t[Ni+4>>2],yi(e,3722,r)|0,t[eo>>2]=2,t[eo+4>>2]=0,t[r>>2]=t[eo>>2],t[r+4>>2]=t[eo+4>>2],yi(e,3734,r)|0,t[Ei>>2]=3,t[Ei+4>>2]=0,t[r>>2]=t[Ei>>2],t[r+4>>2]=t[Ei+4>>2],Xr(e,3753,r)|0,t[br>>2]=4,t[br+4>>2]=0,t[r>>2]=t[br>>2],t[r+4>>2]=t[br+4>>2],Xr(e,3769,r)|0,t[En>>2]=5,t[En+4>>2]=0,t[r>>2]=t[En>>2],t[r+4>>2]=t[En+4>>2],Xr(e,3783,r)|0,t[Yl>>2]=6,t[Yl+4>>2]=0,t[r>>2]=t[Yl>>2],t[r+4>>2]=t[Yl+4>>2],Xr(e,3796,r)|0,t[Vl>>2]=7,t[Vl+4>>2]=0,t[r>>2]=t[Vl>>2],t[r+4>>2]=t[Vl+4>>2],Xr(e,3813,r)|0,t[Gl>>2]=8,t[Gl+4>>2]=0,t[r>>2]=t[Gl>>2],t[r+4>>2]=t[Gl+4>>2],Xr(e,3825,r)|0,t[Au>>2]=3,t[Au+4>>2]=0,t[r>>2]=t[Au>>2],t[r+4>>2]=t[Au+4>>2],yi(e,3843,r)|0,t[Ri>>2]=4,t[Ri+4>>2]=0,t[r>>2]=t[Ri>>2],t[r+4>>2]=t[Ri+4>>2],yi(e,3853,r)|0,t[cs>>2]=9,t[cs+4>>2]=0,t[r>>2]=t[cs>>2],t[r+4>>2]=t[cs+4>>2],Xr(e,3870,r)|0,t[bl>>2]=10,t[bl+4>>2]=0,t[r>>2]=t[bl>>2],t[r+4>>2]=t[bl+4>>2],Xr(e,3884,r)|0,t[Hl>>2]=11,t[Hl+4>>2]=0,t[r>>2]=t[Hl>>2],t[r+4>>2]=t[Hl+4>>2],Xr(e,3896,r)|0,t[fs>>2]=1,t[fs+4>>2]=0,t[r>>2]=t[fs>>2],t[r+4>>2]=t[fs+4>>2],j0(e,3907,r)|0,t[Zi>>2]=2,t[Zi+4>>2]=0,t[r>>2]=t[Zi>>2],t[r+4>>2]=t[Zi+4>>2],j0(e,3915,r)|0,t[ls>>2]=3,t[ls+4>>2]=0,t[r>>2]=t[ls>>2],t[r+4>>2]=t[ls+4>>2],j0(e,3928,r)|0,t[Qi>>2]=4,t[Qi+4>>2]=0,t[r>>2]=t[Qi>>2],t[r+4>>2]=t[Qi+4>>2],j0(e,3948,r)|0,t[Wl>>2]=5,t[Wl+4>>2]=0,t[r>>2]=t[Wl>>2],t[r+4>>2]=t[Wl+4>>2],j0(e,3960,r)|0,t[xr>>2]=6,t[xr+4>>2]=0,t[r>>2]=t[xr>>2],t[r+4>>2]=t[xr+4>>2],j0(e,3974,r)|0,t[ku>>2]=7,t[ku+4>>2]=0,t[r>>2]=t[ku>>2],t[r+4>>2]=t[ku+4>>2],j0(e,3983,r)|0,t[Di>>2]=20,t[Di+4>>2]=0,t[r>>2]=t[Di>>2],t[r+4>>2]=t[Di+4>>2],gf(e,3999,r)|0,t[Li>>2]=8,t[Li+4>>2]=0,t[r>>2]=t[Li>>2],t[r+4>>2]=t[Li+4>>2],j0(e,4012,r)|0,t[zl>>2]=9,t[zl+4>>2]=0,t[r>>2]=t[zl>>2],t[r+4>>2]=t[zl+4>>2],j0(e,4022,r)|0,t[ql>>2]=21,t[ql+4>>2]=0,t[r>>2]=t[ql>>2],t[r+4>>2]=t[ql+4>>2],gf(e,4039,r)|0,t[tl>>2]=10,t[tl+4>>2]=0,t[r>>2]=t[tl>>2],t[r+4>>2]=t[tl+4>>2],j0(e,4053,r)|0,t[Ul>>2]=11,t[Ul+4>>2]=0,t[r>>2]=t[Ul>>2],t[r+4>>2]=t[Ul+4>>2],j0(e,4065,r)|0,t[jl>>2]=12,t[jl+4>>2]=0,t[r>>2]=t[jl>>2],t[r+4>>2]=t[jl+4>>2],j0(e,4084,r)|0,t[xu>>2]=13,t[xu+4>>2]=0,t[r>>2]=t[xu>>2],t[r+4>>2]=t[xu+4>>2],j0(e,4097,r)|0,t[go>>2]=14,t[go+4>>2]=0,t[r>>2]=t[go>>2],t[r+4>>2]=t[go+4>>2],j0(e,4117,r)|0,t[nu>>2]=15,t[nu+4>>2]=0,t[r>>2]=t[nu>>2],t[r+4>>2]=t[nu+4>>2],j0(e,4129,r)|0,t[Fi>>2]=16,t[Fi+4>>2]=0,t[r>>2]=t[Fi>>2],t[r+4>>2]=t[Fi+4>>2],j0(e,4148,r)|0,t[ss>>2]=17,t[ss+4>>2]=0,t[r>>2]=t[ss>>2],t[r+4>>2]=t[ss+4>>2],j0(e,4161,r)|0,t[el>>2]=18,t[el+4>>2]=0,t[r>>2]=t[el>>2],t[r+4>>2]=t[el+4>>2],j0(e,4181,r)|0,t[Zs>>2]=5,t[Zs+4>>2]=0,t[r>>2]=t[Zs>>2],t[r+4>>2]=t[Zs+4>>2],yi(e,4196,r)|0,t[Rf>>2]=6,t[Rf+4>>2]=0,t[r>>2]=t[Rf>>2],t[r+4>>2]=t[Rf+4>>2],yi(e,4206,r)|0,t[Lf>>2]=7,t[Lf+4>>2]=0,t[r>>2]=t[Lf>>2],t[r+4>>2]=t[Lf+4>>2],yi(e,4217,r)|0,t[us>>2]=3,t[us+4>>2]=0,t[r>>2]=t[us>>2],t[r+4>>2]=t[us+4>>2],Zu(e,4235,r)|0,t[Ff>>2]=1,t[Ff+4>>2]=0,t[r>>2]=t[Ff>>2],t[r+4>>2]=t[Ff+4>>2],_f(e,4251,r)|0,t[Tu>>2]=4,t[Tu+4>>2]=0,t[r>>2]=t[Tu>>2],t[r+4>>2]=t[Tu+4>>2],Zu(e,4263,r)|0,t[Kn>>2]=5,t[Kn+4>>2]=0,t[r>>2]=t[Kn>>2],t[r+4>>2]=t[Kn+4>>2],Zu(e,4279,r)|0,t[Mf>>2]=6,t[Mf+4>>2]=0,t[r>>2]=t[Mf>>2],t[r+4>>2]=t[Mf+4>>2],Zu(e,4293,r)|0,t[Pf>>2]=7,t[Pf+4>>2]=0,t[r>>2]=t[Pf>>2],t[r+4>>2]=t[Pf+4>>2],Zu(e,4306,r)|0,t[If>>2]=8,t[If+4>>2]=0,t[r>>2]=t[If>>2],t[r+4>>2]=t[If+4>>2],Zu(e,4323,r)|0,t[Qs>>2]=9,t[Qs+4>>2]=0,t[r>>2]=t[Qs>>2],t[r+4>>2]=t[Qs+4>>2],Zu(e,4335,r)|0,t[Js>>2]=2,t[Js+4>>2]=0,t[r>>2]=t[Js>>2],t[r+4>>2]=t[Js+4>>2],_f(e,4353,r)|0,t[Of>>2]=12,t[Of+4>>2]=0,t[r>>2]=t[Of>>2],t[r+4>>2]=t[Of+4>>2],Io(e,4363,r)|0,t[Cu>>2]=1,t[Cu+4>>2]=0,t[r>>2]=t[Cu>>2],t[r+4>>2]=t[Cu+4>>2],_u(e,4376,r)|0,t[Af>>2]=2,t[Af+4>>2]=0,t[r>>2]=t[Af>>2],t[r+4>>2]=t[Af+4>>2],_u(e,4388,r)|0,t[kf>>2]=13,t[kf+4>>2]=0,t[r>>2]=t[kf>>2],t[r+4>>2]=t[kf+4>>2],Io(e,4402,r)|0,t[Ro>>2]=14,t[Ro+4>>2]=0,t[r>>2]=t[Ro>>2],t[r+4>>2]=t[Ro+4>>2],Io(e,4411,r)|0,t[Ji>>2]=15,t[Ji+4>>2]=0,t[r>>2]=t[Ji>>2],t[r+4>>2]=t[Ji+4>>2],Io(e,4421,r)|0,t[Xi>>2]=16,t[Xi+4>>2]=0,t[r>>2]=t[Xi>>2],t[r+4>>2]=t[Xi+4>>2],Io(e,4433,r)|0,t[Ki>>2]=17,t[Ki+4>>2]=0,t[r>>2]=t[Ki>>2],t[r+4>>2]=t[Ki+4>>2],Io(e,4446,r)|0,t[Dr>>2]=18,t[Dr+4>>2]=0,t[r>>2]=t[Dr>>2],t[r+4>>2]=t[Dr+4>>2],Io(e,4458,r)|0,t[zt>>2]=3,t[zt+4>>2]=0,t[r>>2]=t[zt>>2],t[r+4>>2]=t[zt+4>>2],_u(e,4471,r)|0,t[Pn>>2]=1,t[Pn+4>>2]=0,t[r>>2]=t[Pn>>2],t[r+4>>2]=t[Pn+4>>2],ec(e,4486,r)|0,t[gn>>2]=10,t[gn+4>>2]=0,t[r>>2]=t[gn>>2],t[r+4>>2]=t[gn+4>>2],Zu(e,4496,r)|0,t[It>>2]=11,t[It+4>>2]=0,t[r>>2]=t[It>>2],t[r+4>>2]=t[It+4>>2],Zu(e,4508,r)|0,t[Ht>>2]=3,t[Ht+4>>2]=0,t[r>>2]=t[Ht>>2],t[r+4>>2]=t[Ht+4>>2],_f(e,4519,r)|0,t[Ln>>2]=4,t[Ln+4>>2]=0,t[r>>2]=t[Ln>>2],t[r+4>>2]=t[Ln+4>>2],Wm(e,4530,r)|0,t[vt>>2]=19,t[vt+4>>2]=0,t[r>>2]=t[vt>>2],t[r+4>>2]=t[vt+4>>2],Fd(e,4542,r)|0,t[_e>>2]=12,t[_e+4>>2]=0,t[r>>2]=t[_e>>2],t[r+4>>2]=t[_e+4>>2],yf(e,4554,r)|0,t[pe>>2]=13,t[pe+4>>2]=0,t[r>>2]=t[pe>>2],t[r+4>>2]=t[pe+4>>2],tc(e,4568,r)|0,t[qe>>2]=2,t[qe+4>>2]=0,t[r>>2]=t[qe>>2],t[r+4>>2]=t[qe+4>>2],Hm(e,4578,r)|0,t[ke>>2]=20,t[ke+4>>2]=0,t[r>>2]=t[ke>>2],t[r+4>>2]=t[ke+4>>2],Ld(e,4587,r)|0,t[Pe>>2]=22,t[Pe+4>>2]=0,t[r>>2]=t[Pe>>2],t[r+4>>2]=t[Pe+4>>2],gf(e,4602,r)|0,t[ie>>2]=23,t[ie+4>>2]=0,t[r>>2]=t[ie>>2],t[r+4>>2]=t[ie+4>>2],gf(e,4619,r)|0,t[le>>2]=14,t[le+4>>2]=0,t[r>>2]=t[le>>2],t[r+4>>2]=t[le+4>>2],Rd(e,4629,r)|0,t[we>>2]=1,t[we+4>>2]=0,t[r>>2]=t[we>>2],t[r+4>>2]=t[we+4>>2],zc(e,4637,r)|0,t[q>>2]=4,t[q+4>>2]=0,t[r>>2]=t[q>>2],t[r+4>>2]=t[q+4>>2],_u(e,4653,r)|0,t[P>>2]=5,t[P+4>>2]=0,t[r>>2]=t[P>>2],t[r+4>>2]=t[P+4>>2],_u(e,4669,r)|0,t[T>>2]=6,t[T+4>>2]=0,t[r>>2]=t[T>>2],t[r+4>>2]=t[T+4>>2],_u(e,4686,r)|0,t[k>>2]=7,t[k+4>>2]=0,t[r>>2]=t[k>>2],t[r+4>>2]=t[k+4>>2],_u(e,4701,r)|0,t[y>>2]=8,t[y+4>>2]=0,t[r>>2]=t[y>>2],t[r+4>>2]=t[y+4>>2],_u(e,4719,r)|0,t[_>>2]=9,t[_+4>>2]=0,t[r>>2]=t[_>>2],t[r+4>>2]=t[_+4>>2],_u(e,4736,r)|0,t[d>>2]=21,t[d+4>>2]=0,t[r>>2]=t[d>>2],t[r+4>>2]=t[d+4>>2],Nd(e,4754,r)|0,t[l>>2]=2,t[l+4>>2]=0,t[r>>2]=t[l>>2],t[r+4>>2]=t[l+4>>2],ec(e,4772,r)|0,t[s>>2]=3,t[s+4>>2]=0,t[r>>2]=t[s>>2],t[r+4>>2]=t[s+4>>2],ec(e,4790,r)|0,t[o>>2]=4,t[o+4>>2]=0,t[r>>2]=t[o>>2],t[r+4>>2]=t[o+4>>2],ec(e,4808,r)|0,h=n}function qm(e,n){e=e|0,n=n|0;var r=0;r=Nx()|0,t[e>>2]=r,Bx(r,n),Cf(t[e>>2]|0)}function Id(e,n,r){return e=e|0,n=n|0,r=r|0,Ex(e,Zn(n)|0,r,0),e|0}function Pd(e,n,r){return e=e|0,n=n|0,r=r|0,ux(e,Zn(n)|0,r,0),e|0}function zm(e,n,r){return e=e|0,n=n|0,r=r|0,V9(e,Zn(n)|0,r,0),e|0}function gf(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],I9(e,n,s),h=o,e|0}function Md(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],vo(e,n,s),h=o,e|0}function Xr(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],a(e,n,s),h=o,e|0}function yi(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],n4(e,n,s),h=o,e|0}function j0(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],b_(e,n,s),h=o,e|0}function Zu(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],L_(e,n,s),h=o,e|0}function _f(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Hp(e,n,s),h=o,e|0}function Io(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],e_(e,n,s),h=o,e|0}function _u(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Ip(e,n,s),h=o,e|0}function ec(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Ng(e,n,s),h=o,e|0}function Wm(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],l0(e,n,s),h=o,e|0}function Fd(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],hg(e,n,s),h=o,e|0}function yf(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],sg(e,n,s),h=o,e|0}function tc(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Kv(e,n,s),h=o,e|0}function Hm(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],y1(e,n,s),h=o,e|0}function Ld(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],wv(e,n,s),h=o,e|0}function Rd(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],fv(e,n,s),h=o,e|0}function zc(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Gd(e,n,s),h=o,e|0}function Nd(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Wc(e,n,s),h=o,e|0}function Wc(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Hc(e,r,s,1),h=o}function Zn(e){return e=e|0,e|0}function Hc(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=Za()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=Bd(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,bc(l,o)|0,o),h=s}function Za(){var e=0,n=0;if(c[7616]|0||(yu(9136),Bt(24,9136,Q|0)|0,n=7616,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9136)|0)){e=9136,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));yu(9136)}return 9136}function Bd(e){return e=e|0,0}function bc(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=Za()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],n1(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(jd(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function ur(e,n,r,o,s,l){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0;var d=0,_=0,y=0,k=0,T=0,P=0,q=0,we=0;d=h,h=h+32|0,q=d+24|0,P=d+20|0,y=d+16|0,T=d+12|0,k=d+8|0,_=d+4|0,we=d,t[P>>2]=n,t[y>>2]=r,t[T>>2]=o,t[k>>2]=s,t[_>>2]=l,l=e+28|0,t[we>>2]=t[l>>2],t[q>>2]=t[we>>2],e1(e+24|0,q,P,T,k,y,_)|0,t[l>>2]=t[t[l>>2]>>2],h=d}function e1(e,n,r,o,s,l,d){return e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0,d=d|0,e=bm(n)|0,n=Tt(24)|0,t1(n+4|0,t[r>>2]|0,t[o>>2]|0,t[s>>2]|0,t[l>>2]|0,t[d>>2]|0),t[n>>2]=t[e>>2],t[e>>2]=n,n|0}function bm(e){return e=e|0,t[e>>2]|0}function t1(e,n,r,o,s,l){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0,t[e>>2]=n,t[e+4>>2]=r,t[e+8>>2]=o,t[e+12>>2]=s,t[e+16>>2]=l}function Lt(e,n){return e=e|0,n=n|0,n|e|0}function n1(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function jd(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=Gm(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,Ud(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],n1(l,o,r),t[y>>2]=(t[y>>2]|0)+12,Vm(e,_),Ym(_),h=k;return}}function Gm(e){return e=e|0,357913941}function Ud(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function Vm(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function Ym(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function yu(e){e=e|0,Gc(e)}function r1(e){e=e|0,i1(e+24|0)}function Dn(e){return e=e|0,t[e>>2]|0}function i1(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function Gc(e){e=e|0;var n=0;n=An()|0,Nn(e,2,3,n,cn()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function An(){return 9228}function cn(){return 1140}function Vc(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0;return r=h,h=h+16|0,o=r+8|0,s=r,l=Il(e)|0,e=t[l+4>>2]|0,t[s>>2]=t[l>>2],t[s+4>>2]=e,t[o>>2]=t[s>>2],t[o+4>>2]=t[s+4>>2],n=$m(n,o)|0,h=r,n|0}function Nn(e,n,r,o,s,l){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0,t[e>>2]=n,t[e+4>>2]=r,t[e+8>>2]=o,t[e+12>>2]=s,t[e+16>>2]=l}function Il(e){return e=e|0,(t[(Za()|0)+24>>2]|0)+(e*12|0)|0}function $m(e,n){e=e|0,n=n|0;var r=0,o=0,s=0;return s=h,h=h+48|0,o=s,r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),Bl[r&31](o,e),o=o1(o)|0,h=s,o|0}function o1(e){e=e|0;var n=0,r=0,o=0,s=0;return s=h,h=h+32|0,n=s+12|0,r=s,o=U0(u1()|0)|0,o?(s1(n,o),l1(r,n),qd(e,r),e=f1(n)|0):e=zd(e)|0,h=s,e|0}function u1(){var e=0;return c[7632]|0||(nc(9184),Bt(25,9184,Q|0)|0,e=7632,t[e>>2]=1,t[e+4>>2]=0),9184}function U0(e){return e=e|0,t[e+36>>2]|0}function s1(e,n){e=e|0,n=n|0,t[e>>2]=n,t[e+4>>2]=e,t[e+8>>2]=0}function l1(e,n){e=e|0,n=n|0,t[e>>2]=t[n>>2],t[e+4>>2]=t[n+4>>2],t[e+8>>2]=0}function qd(e,n){e=e|0,n=n|0,Ii(n,e,e+8|0,e+16|0,e+24|0,e+32|0,e+40|0)|0}function f1(e){return e=e|0,t[(t[e+4>>2]|0)+8>>2]|0}function zd(e){e=e|0;var n=0,r=0,o=0,s=0,l=0,d=0,_=0,y=0;y=h,h=h+16|0,r=y+4|0,o=y,s=Qo(8)|0,l=s,d=Tt(48)|0,_=d,n=_+48|0;do t[_>>2]=t[e>>2],_=_+4|0,e=e+4|0;while((_|0)<(n|0));return n=l+4|0,t[n>>2]=d,_=Tt(8)|0,d=t[n>>2]|0,t[o>>2]=0,t[r>>2]=t[o>>2],Wd(_,d,r),t[s>>2]=_,h=y,l|0}function Wd(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,r=Tt(16)|0,t[r+4>>2]=0,t[r+8>>2]=0,t[r>>2]=1092,t[r+12>>2]=n,t[e+4>>2]=r}function Km(e){e=e|0,da(e),Ve(e)}function Xm(e){e=e|0,e=t[e+12>>2]|0,e|0&&Ve(e)}function es(e){e=e|0,Ve(e)}function Ii(e,n,r,o,s,l,d){return e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0,d=d|0,l=c1(t[e>>2]|0,n,r,o,s,l,d)|0,d=e+4|0,t[(t[d>>2]|0)+8>>2]=l,t[(t[d>>2]|0)+8>>2]|0}function c1(e,n,r,o,s,l,d){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0,d=d|0;var _=0,y=0;return _=h,h=h+16|0,y=_,Zo(y),e=Oi(e)|0,d=Jm(e,+L[n>>3],+L[r>>3],+L[o>>3],+L[s>>3],+L[l>>3],+L[d>>3])|0,eu(y),h=_,d|0}function Jm(e,n,r,o,s,l,d){e=e|0,n=+n,r=+r,o=+o,s=+s,l=+l,d=+d;var _=0;return _=ko(a1()|0)|0,n=+Ko(n),r=+Ko(r),o=+Ko(o),s=+Ko(s),l=+Ko(l),xs(0,_|0,e|0,+n,+r,+o,+s,+l,+ +Ko(d))|0}function a1(){var e=0;return c[7624]|0||(Qm(9172),e=7624,t[e>>2]=1,t[e+4>>2]=0),9172}function Qm(e){e=e|0,Ao(e,Zm()|0,6)}function Zm(){return 1112}function nc(e){e=e|0,Ys(e)}function Hd(e){e=e|0,d1(e+24|0),bd(e+16|0)}function d1(e){e=e|0,tv(e)}function bd(e){e=e|0,ev(e)}function ev(e){e=e|0;var n=0,r=0;if(n=t[e>>2]|0,n|0)do r=n,n=t[n>>2]|0,Ve(r);while((n|0)!=0);t[e>>2]=0}function tv(e){e=e|0;var n=0,r=0;if(n=t[e>>2]|0,n|0)do r=n,n=t[n>>2]|0,Ve(r);while((n|0)!=0);t[e>>2]=0}function Ys(e){e=e|0;var n=0;t[e+16>>2]=0,t[e+20>>2]=0,n=e+24|0,t[n>>2]=0,t[e+28>>2]=n,t[e+36>>2]=0,c[e+40>>0]=0,c[e+41>>0]=0}function Gd(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Vd(e,r,s,0),h=o}function Vd(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=p1()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=h1(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,Yd(l,o)|0,o),h=s}function p1(){var e=0,n=0;if(c[7640]|0||(Xo(9232),Bt(26,9232,Q|0)|0,n=7640,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9232)|0)){e=9232,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Xo(9232)}return 9232}function h1(e){return e=e|0,0}function Yd(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=p1()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],wf(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(m1(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function wf(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function m1(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=$d(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,Kd(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],wf(l,o,r),t[y>>2]=(t[y>>2]|0)+12,Yc(e,_),Xd(_),h=k;return}}function $d(e){return e=e|0,357913941}function Kd(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function Yc(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function Xd(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function Xo(e){e=e|0,Jd(e)}function Pl(e){e=e|0,nv(e+24|0)}function nv(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function Jd(e){e=e|0;var n=0;n=An()|0,Nn(e,2,1,n,rv()|0,3),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function rv(){return 1144}function iv(e,n,r,o,s){e=e|0,n=n|0,r=+r,o=+o,s=s|0;var l=0,d=0,_=0,y=0;l=h,h=h+16|0,d=l+8|0,_=l,y=ov(e)|0,e=t[y+4>>2]|0,t[_>>2]=t[y>>2],t[_+4>>2]=e,t[d>>2]=t[_>>2],t[d+4>>2]=t[_+4>>2],uv(n,d,r,o,s),h=l}function ov(e){return e=e|0,(t[(p1()|0)+24>>2]|0)+(e*12|0)|0}function uv(e,n,r,o,s){e=e|0,n=n|0,r=+r,o=+o,s=s|0;var l=0,d=0,_=0,y=0,k=0;k=h,h=h+16|0,d=k+2|0,_=k+1|0,y=k,l=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(l=t[(t[e>>2]|0)+l>>2]|0),wu(d,r),r=+Du(d,r),wu(_,o),o=+Du(_,o),ts(y,s),y=ns(y,s)|0,iD[l&1](e,r,o,y),h=k}function wu(e,n){e=e|0,n=+n}function Du(e,n){return e=e|0,n=+n,+ +lv(n)}function ts(e,n){e=e|0,n=n|0}function ns(e,n){return e=e|0,n=n|0,sv(n)|0}function sv(e){return e=e|0,e|0}function lv(e){return e=+e,+e}function fv(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Qd(e,r,s,1),h=o}function Qd(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=$c()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=Zd(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,cv(l,o)|0,o),h=s}function $c(){var e=0,n=0;if(c[7648]|0||(np(9268),Bt(27,9268,Q|0)|0,n=7648,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9268)|0)){e=9268,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));np(9268)}return 9268}function Zd(e){return e=e|0,0}function cv(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=$c()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],ep(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(av(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function ep(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function av(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=tp(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,dv(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],ep(l,o,r),t[y>>2]=(t[y>>2]|0)+12,pv(e,_),hv(_),h=k;return}}function tp(e){return e=e|0,357913941}function dv(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function pv(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function hv(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function np(e){e=e|0,Po(e)}function mv(e){e=e|0,vv(e+24|0)}function vv(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function Po(e){e=e|0;var n=0;n=An()|0,Nn(e,2,4,n,gv()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function gv(){return 1160}function _v(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0;return r=h,h=h+16|0,o=r+8|0,s=r,l=yv(e)|0,e=t[l+4>>2]|0,t[s>>2]=t[l>>2],t[s+4>>2]=e,t[o>>2]=t[s>>2],t[o+4>>2]=t[s+4>>2],n=rp(n,o)|0,h=r,n|0}function yv(e){return e=e|0,(t[($c()|0)+24>>2]|0)+(e*12|0)|0}function rp(e,n){e=e|0,n=n|0;var r=0;return r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),ip(dc[r&31](e)|0)|0}function ip(e){return e=e|0,e&1|0}function wv(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Dv(e,r,s,0),h=o}function Dv(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=v1()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=g1(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,Ev(l,o)|0,o),h=s}function v1(){var e=0,n=0;if(c[7656]|0||(up(9304),Bt(28,9304,Q|0)|0,n=7656,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9304)|0)){e=9304,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));up(9304)}return 9304}function g1(e){return e=e|0,0}function Ev(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=v1()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],op(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(Sv(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function op(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function Sv(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=Cv(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,Tv(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],op(l,o,r),t[y>>2]=(t[y>>2]|0)+12,xv(e,_),kv(_),h=k;return}}function Cv(e){return e=e|0,357913941}function Tv(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function xv(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function kv(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function up(e){e=e|0,Iv(e)}function Av(e){e=e|0,Ov(e+24|0)}function Ov(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function Iv(e){e=e|0;var n=0;n=An()|0,Nn(e,2,5,n,Pv()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function Pv(){return 1164}function Mv(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;o=h,h=h+16|0,s=o+8|0,l=o,d=Fv(e)|0,e=t[d+4>>2]|0,t[l>>2]=t[d>>2],t[l+4>>2]=e,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Lv(n,s,r),h=o}function Fv(e){return e=e|0,(t[(v1()|0)+24>>2]|0)+(e*12|0)|0}function Lv(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0;l=h,h=h+16|0,s=l,o=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(o=t[(t[e>>2]|0)+o>>2]|0),$s(s,r),r=Ks(s,r)|0,Bl[o&31](e,r),Xs(s),h=l}function $s(e,n){e=e|0,n=n|0,Rv(e,n)}function Ks(e,n){return e=e|0,n=n|0,e|0}function Xs(e){e=e|0,Ju(e)}function Rv(e,n){e=e|0,n=n|0,_1(e,n)}function _1(e,n){e=e|0,n=n|0,t[e>>2]=n}function y1(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],sp(e,r,s,0),h=o}function sp(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=w1()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=Nv(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,Bv(l,o)|0,o),h=s}function w1(){var e=0,n=0;if(c[7664]|0||(cp(9340),Bt(29,9340,Q|0)|0,n=7664,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9340)|0)){e=9340,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));cp(9340)}return 9340}function Nv(e){return e=e|0,0}function Bv(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=w1()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],lp(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(jv(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function lp(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function jv(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=Uv(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,qv(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],lp(l,o,r),t[y>>2]=(t[y>>2]|0)+12,zv(e,_),fp(_),h=k;return}}function Uv(e){return e=e|0,357913941}function qv(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function zv(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function fp(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function cp(e){e=e|0,Hv(e)}function Kc(e){e=e|0,Wv(e+24|0)}function Wv(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function Hv(e){e=e|0;var n=0;n=An()|0,Nn(e,2,4,n,bv()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function bv(){return 1180}function Gv(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=Vv(e)|0,e=t[d+4>>2]|0,t[l>>2]=t[d>>2],t[l+4>>2]=e,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],r=Yv(n,s,r)|0,h=o,r|0}function Vv(e){return e=e|0,(t[(w1()|0)+24>>2]|0)+(e*12|0)|0}function Yv(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0;return l=h,h=h+16|0,s=l,o=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(o=t[(t[e>>2]|0)+o>>2]|0),Ml(s,r),s=Fl(s,r)|0,s=Xc(J4[o&15](e,s)|0)|0,h=l,s|0}function Ml(e,n){e=e|0,n=n|0}function Fl(e,n){return e=e|0,n=n|0,$v(n)|0}function Xc(e){return e=e|0,e|0}function $v(e){return e=e|0,e|0}function Kv(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Xv(e,r,s,0),h=o}function Xv(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=D1()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=Jv(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,Qv(l,o)|0,o),h=s}function D1(){var e=0,n=0;if(c[7672]|0||(hp(9376),Bt(30,9376,Q|0)|0,n=7672,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9376)|0)){e=9376,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));hp(9376)}return 9376}function Jv(e){return e=e|0,0}function Qv(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=D1()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],ap(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(dp(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function ap(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function dp(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=pp(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,Zv(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],ap(l,o,r),t[y>>2]=(t[y>>2]|0)+12,eg(e,_),tg(_),h=k;return}}function pp(e){return e=e|0,357913941}function Zv(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function eg(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function tg(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function hp(e){e=e|0,rg(e)}function Jc(e){e=e|0,ng(e+24|0)}function ng(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function rg(e){e=e|0;var n=0;n=An()|0,Nn(e,2,5,n,mp()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function mp(){return 1196}function ig(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0;return r=h,h=h+16|0,o=r+8|0,s=r,l=og(e)|0,e=t[l+4>>2]|0,t[s>>2]=t[l>>2],t[s+4>>2]=e,t[o>>2]=t[s>>2],t[o+4>>2]=t[s+4>>2],n=ug(n,o)|0,h=r,n|0}function og(e){return e=e|0,(t[(D1()|0)+24>>2]|0)+(e*12|0)|0}function ug(e,n){e=e|0,n=n|0;var r=0;return r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),Xc(dc[r&31](e)|0)|0}function sg(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],lg(e,r,s,1),h=o}function lg(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=E1()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=fg(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,cg(l,o)|0,o),h=s}function E1(){var e=0,n=0;if(c[7680]|0||(C1(9412),Bt(31,9412,Q|0)|0,n=7680,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9412)|0)){e=9412,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));C1(9412)}return 9412}function fg(e){return e=e|0,0}function cg(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=E1()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],rc(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(ag(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function rc(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function ag(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=vp(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,gp(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],rc(l,o,r),t[y>>2]=(t[y>>2]|0)+12,S1(e,_),_p(_),h=k;return}}function vp(e){return e=e|0,357913941}function gp(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function S1(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function _p(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function C1(e){e=e|0,dg(e)}function yp(e){e=e|0,wp(e+24|0)}function wp(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function dg(e){e=e|0;var n=0;n=An()|0,Nn(e,2,6,n,Dp()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function Dp(){return 1200}function pg(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0;return r=h,h=h+16|0,o=r+8|0,s=r,l=Qc(e)|0,e=t[l+4>>2]|0,t[s>>2]=t[l>>2],t[s+4>>2]=e,t[o>>2]=t[s>>2],t[o+4>>2]=t[s+4>>2],n=Zc(n,o)|0,h=r,n|0}function Qc(e){return e=e|0,(t[(E1()|0)+24>>2]|0)+(e*12|0)|0}function Zc(e,n){e=e|0,n=n|0;var r=0;return r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),ea(dc[r&31](e)|0)|0}function ea(e){return e=e|0,e|0}function hg(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],T1(e,r,s,0),h=o}function T1(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=ta()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=mg(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,vg(l,o)|0,o),h=s}function ta(){var e=0,n=0;if(c[7688]|0||(Sp(9448),Bt(32,9448,Q|0)|0,n=7688,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9448)|0)){e=9448,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Sp(9448)}return 9448}function mg(e){return e=e|0,0}function vg(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=ta()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],Ep(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(gg(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function Ep(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function gg(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=_g(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,yg(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],Ep(l,o,r),t[y>>2]=(t[y>>2]|0)+12,wg(e,_),Dg(_),h=k;return}}function _g(e){return e=e|0,357913941}function yg(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function wg(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function Dg(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function Sp(e){e=e|0,Cg(e)}function Eg(e){e=e|0,Sg(e+24|0)}function Sg(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function Cg(e){e=e|0;var n=0;n=An()|0,Nn(e,2,6,n,Mo()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function Mo(){return 1204}function Tg(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;o=h,h=h+16|0,s=o+8|0,l=o,d=xg(e)|0,e=t[d+4>>2]|0,t[l>>2]=t[d>>2],t[l+4>>2]=e,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Ll(n,s,r),h=o}function xg(e){return e=e|0,(t[(ta()|0)+24>>2]|0)+(e*12|0)|0}function Ll(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0;l=h,h=h+16|0,s=l,o=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(o=t[(t[e>>2]|0)+o>>2]|0),On(s,r),s=x1(s,r)|0,Bl[o&31](e,s),h=l}function On(e,n){e=e|0,n=n|0}function x1(e,n){return e=e|0,n=n|0,Vi(n)|0}function Vi(e){return e=e|0,e|0}function l0(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],kg(e,r,s,0),h=o}function kg(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=Eu()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=Ag(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,Og(l,o)|0,o),h=s}function Eu(){var e=0,n=0;if(c[7696]|0||(A1(9484),Bt(33,9484,Q|0)|0,n=7696,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9484)|0)){e=9484,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));A1(9484)}return 9484}function Ag(e){return e=e|0,0}function Og(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=Eu()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],Cp(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(Ig(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function Cp(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function Ig(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=Pg(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,k1(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],Cp(l,o,r),t[y>>2]=(t[y>>2]|0)+12,Mg(e,_),rs(_),h=k;return}}function Pg(e){return e=e|0,357913941}function k1(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function Mg(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function rs(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function A1(e){e=e|0,n0(e)}function na(e){e=e|0,Jr(e+24|0)}function Jr(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function n0(e){e=e|0;var n=0;n=An()|0,Nn(e,2,1,n,Tp()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function Tp(){return 1212}function Fg(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0;s=h,h=h+16|0,l=s+8|0,d=s,_=Lg(e)|0,e=t[_+4>>2]|0,t[d>>2]=t[_>>2],t[d+4>>2]=e,t[l>>2]=t[d>>2],t[l+4>>2]=t[d+4>>2],Rg(n,l,r,o),h=s}function Lg(e){return e=e|0,(t[(Eu()|0)+24>>2]|0)+(e*12|0)|0}function Rg(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0;_=h,h=h+16|0,l=_+1|0,d=_,s=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(s=t[(t[e>>2]|0)+s>>2]|0),On(l,r),l=x1(l,r)|0,Ml(d,o),d=Fl(d,o)|0,X1[s&15](e,l,d),h=_}function Ng(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Bg(e,r,s,1),h=o}function Bg(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=O1()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=xp(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,ic(l,o)|0,o),h=s}function O1(){var e=0,n=0;if(c[7704]|0||(Ap(9520),Bt(34,9520,Q|0)|0,n=7704,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9520)|0)){e=9520,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Ap(9520)}return 9520}function xp(e){return e=e|0,0}function ic(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=O1()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],ra(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(jg(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function ra(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function jg(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=kp(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,ia(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],ra(l,o,r),t[y>>2]=(t[y>>2]|0)+12,mo(e,_),Df(_),h=k;return}}function kp(e){return e=e|0,357913941}function ia(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function mo(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function Df(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function Ap(e){e=e|0,zg(e)}function Ug(e){e=e|0,qg(e+24|0)}function qg(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function zg(e){e=e|0;var n=0;n=An()|0,Nn(e,2,1,n,Wg()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function Wg(){return 1224}function Op(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;return s=h,h=h+16|0,l=s+8|0,d=s,_=is(e)|0,e=t[_+4>>2]|0,t[d>>2]=t[_>>2],t[d+4>>2]=e,t[l>>2]=t[d>>2],t[l+4>>2]=t[d+4>>2],o=+jn(n,l,r),h=s,+o}function is(e){return e=e|0,(t[(O1()|0)+24>>2]|0)+(e*12|0)|0}function jn(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return l=h,h=h+16|0,s=l,o=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(o=t[(t[e>>2]|0)+o>>2]|0),ts(s,r),s=ns(s,r)|0,d=+Ol(+uD[o&7](e,s)),h=l,+d}function Ip(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Fo(e,r,s,1),h=o}function Fo(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=oa()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=Hg(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,yr(l,o)|0,o),h=s}function oa(){var e=0,n=0;if(c[7712]|0||(Fp(9556),Bt(35,9556,Q|0)|0,n=7712,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9556)|0)){e=9556,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Fp(9556)}return 9556}function Hg(e){return e=e|0,0}function yr(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=oa()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],Pp(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(Mp(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function Pp(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function Mp(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=ua(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,bg(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],Pp(l,o,r),t[y>>2]=(t[y>>2]|0)+12,Gg(e,_),Vg(_),h=k;return}}function ua(e){return e=e|0,357913941}function bg(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function Gg(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function Vg(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function Fp(e){e=e|0,Kg(e)}function Yg(e){e=e|0,$g(e+24|0)}function $g(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function Kg(e){e=e|0;var n=0;n=An()|0,Nn(e,2,5,n,Xg()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function Xg(){return 1232}function Jg(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=Qg(e)|0,e=t[d+4>>2]|0,t[l>>2]=t[d>>2],t[l+4>>2]=e,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],r=+Zg(n,s),h=o,+r}function Qg(e){return e=e|0,(t[(oa()|0)+24>>2]|0)+(e*12|0)|0}function Zg(e,n){e=e|0,n=n|0;var r=0;return r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),+ +Ol(+oD[r&15](e))}function e_(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],t_(e,r,s,1),h=o}function t_(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=oc()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=n_(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,I1(l,o)|0,o),h=s}function oc(){var e=0,n=0;if(c[7720]|0||(Rp(9592),Bt(36,9592,Q|0)|0,n=7720,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9592)|0)){e=9592,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Rp(9592)}return 9592}function n_(e){return e=e|0,0}function I1(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=oc()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],Lp(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(r_(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function Lp(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function r_(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=i_(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,q0(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],Lp(l,o,r),t[y>>2]=(t[y>>2]|0)+12,Yi(e,_),o_(_),h=k;return}}function i_(e){return e=e|0,357913941}function q0(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function Yi(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function o_(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function Rp(e){e=e|0,s_(e)}function u_(e){e=e|0,Np(e+24|0)}function Np(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function s_(e){e=e|0;var n=0;n=An()|0,Nn(e,2,7,n,l_()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function l_(){return 1276}function f_(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0;return r=h,h=h+16|0,o=r+8|0,s=r,l=Bp(e)|0,e=t[l+4>>2]|0,t[s>>2]=t[l>>2],t[s+4>>2]=e,t[o>>2]=t[s>>2],t[o+4>>2]=t[s+4>>2],n=c_(n,o)|0,h=r,n|0}function Bp(e){return e=e|0,(t[(oc()|0)+24>>2]|0)+(e*12|0)|0}function c_(e,n){e=e|0,n=n|0;var r=0,o=0,s=0;return s=h,h=h+16|0,o=s,r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),Bl[r&31](o,e),o=jp(o)|0,h=s,o|0}function jp(e){e=e|0;var n=0,r=0,o=0,s=0;return s=h,h=h+32|0,n=s+12|0,r=s,o=U0(Up()|0)|0,o?(s1(n,o),l1(r,n),qp(e,r),e=f1(n)|0):e=zp(e)|0,h=s,e|0}function Up(){var e=0;return c[7736]|0||(Wp(9640),Bt(25,9640,Q|0)|0,e=7736,t[e>>2]=1,t[e+4>>2]=0),9640}function qp(e,n){e=e|0,n=n|0,Ef(n,e,e+8|0)|0}function zp(e){e=e|0;var n=0,r=0,o=0,s=0,l=0,d=0,_=0;return r=h,h=h+16|0,s=r+4|0,d=r,o=Qo(8)|0,n=o,_=Tt(16)|0,t[_>>2]=t[e>>2],t[_+4>>2]=t[e+4>>2],t[_+8>>2]=t[e+8>>2],t[_+12>>2]=t[e+12>>2],l=n+4|0,t[l>>2]=_,e=Tt(8)|0,l=t[l>>2]|0,t[d>>2]=0,t[s>>2]=t[d>>2],P1(e,l,s),t[o>>2]=e,h=r,n|0}function P1(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,r=Tt(16)|0,t[r+4>>2]=0,t[r+8>>2]=0,t[r>>2]=1244,t[r+12>>2]=n,t[e+4>>2]=r}function a_(e){e=e|0,da(e),Ve(e)}function d_(e){e=e|0,e=t[e+12>>2]|0,e|0&&Ve(e)}function p_(e){e=e|0,Ve(e)}function Ef(e,n,r){return e=e|0,n=n|0,r=r|0,n=h_(t[e>>2]|0,n,r)|0,r=e+4|0,t[(t[r>>2]|0)+8>>2]=n,t[(t[r>>2]|0)+8>>2]|0}function h_(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0;return o=h,h=h+16|0,s=o,Zo(s),e=Oi(e)|0,r=m_(e,t[n>>2]|0,+L[r>>3])|0,eu(s),h=o,r|0}function m_(e,n,r){e=e|0,n=n|0,r=+r;var o=0;return o=ko(v_()|0)|0,n=jc(n)|0,dl(0,o|0,e|0,n|0,+ +Ko(r))|0}function v_(){var e=0;return c[7728]|0||(g_(9628),e=7728,t[e>>2]=1,t[e+4>>2]=0),9628}function g_(e){e=e|0,Ao(e,__()|0,2)}function __(){return 1264}function Wp(e){e=e|0,Ys(e)}function Hp(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],y_(e,r,s,1),h=o}function y_(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=M1()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=w_(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,D_(l,o)|0,o),h=s}function M1(){var e=0,n=0;if(c[7744]|0||(Gp(9684),Bt(37,9684,Q|0)|0,n=7744,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9684)|0)){e=9684,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Gp(9684)}return 9684}function w_(e){return e=e|0,0}function D_(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=M1()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],bp(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(E_(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function bp(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function E_(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=S_(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,C_(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],bp(l,o,r),t[y>>2]=(t[y>>2]|0)+12,T_(e,_),x_(_),h=k;return}}function S_(e){return e=e|0,357913941}function C_(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function T_(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function x_(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function Gp(e){e=e|0,O_(e)}function k_(e){e=e|0,A_(e+24|0)}function A_(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function O_(e){e=e|0;var n=0;n=An()|0,Nn(e,2,5,n,I_()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function I_(){return 1280}function P_(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=M_(e)|0,e=t[d+4>>2]|0,t[l>>2]=t[d>>2],t[l+4>>2]=e,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],r=F_(n,s,r)|0,h=o,r|0}function M_(e){return e=e|0,(t[(M1()|0)+24>>2]|0)+(e*12|0)|0}function F_(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return d=h,h=h+32|0,s=d,l=d+16|0,o=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(o=t[(t[e>>2]|0)+o>>2]|0),ts(l,r),l=ns(l,r)|0,X1[o&15](s,e,l),l=jp(s)|0,h=d,l|0}function L_(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],R_(e,r,s,1),h=o}function R_(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=F1()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=N_(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,B_(l,o)|0,o),h=s}function F1(){var e=0,n=0;if(c[7752]|0||(Kp(9720),Bt(38,9720,Q|0)|0,n=7752,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9720)|0)){e=9720,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Kp(9720)}return 9720}function N_(e){return e=e|0,0}function B_(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=F1()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],Vp(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(j_(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function Vp(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function j_(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=L1(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,Yp(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],Vp(l,o,r),t[y>>2]=(t[y>>2]|0)+12,$p(e,_),U_(_),h=k;return}}function L1(e){return e=e|0,357913941}function Yp(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function $p(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function U_(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function Kp(e){e=e|0,z_(e)}function q_(e){e=e|0,R1(e+24|0)}function R1(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function z_(e){e=e|0;var n=0;n=An()|0,Nn(e,2,8,n,W_()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function W_(){return 1288}function H_(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0;return r=h,h=h+16|0,o=r+8|0,s=r,l=$i(e)|0,e=t[l+4>>2]|0,t[s>>2]=t[l>>2],t[s+4>>2]=e,t[o>>2]=t[s>>2],t[o+4>>2]=t[s+4>>2],n=N1(n,o)|0,h=r,n|0}function $i(e){return e=e|0,(t[(F1()|0)+24>>2]|0)+(e*12|0)|0}function N1(e,n){e=e|0,n=n|0;var r=0;return r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),Dd(dc[r&31](e)|0)|0}function b_(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],G_(e,r,s,0),h=o}function G_(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=B1()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=V_(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,j1(l,o)|0,o),h=s}function B1(){var e=0,n=0;if(c[7760]|0||(q1(9756),Bt(39,9756,Q|0)|0,n=7760,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9756)|0)){e=9756,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));q1(9756)}return 9756}function V_(e){return e=e|0,0}function j1(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=B1()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],Xp(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(U1(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function Xp(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function U1(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=Y_(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,$_(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],Xp(l,o,r),t[y>>2]=(t[y>>2]|0)+12,K_(e,_),X_(_),h=k;return}}function Y_(e){return e=e|0,357913941}function $_(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function K_(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function X_(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function q1(e){e=e|0,Z_(e)}function J_(e){e=e|0,Q_(e+24|0)}function Q_(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function Z_(e){e=e|0;var n=0;n=An()|0,Nn(e,2,8,n,z1()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function z1(){return 1292}function W1(e,n,r){e=e|0,n=n|0,r=+r;var o=0,s=0,l=0,d=0;o=h,h=h+16|0,s=o+8|0,l=o,d=e4(e)|0,e=t[d+4>>2]|0,t[l>>2]=t[d>>2],t[l+4>>2]=e,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],t4(n,s,r),h=o}function e4(e){return e=e|0,(t[(B1()|0)+24>>2]|0)+(e*12|0)|0}function t4(e,n,r){e=e|0,n=n|0,r=+r;var o=0,s=0,l=0;l=h,h=h+16|0,s=l,o=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(o=t[(t[e>>2]|0)+o>>2]|0),wu(s,r),r=+Du(s,r),nD[o&31](e,r),h=l}function n4(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],r4(e,r,s,0),h=o}function r4(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=H1()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=i4(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,o4(l,o)|0,o),h=s}function H1(){var e=0,n=0;if(c[7768]|0||(Qp(9792),Bt(40,9792,Q|0)|0,n=7768,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9792)|0)){e=9792,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Qp(9792)}return 9792}function i4(e){return e=e|0,0}function o4(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=H1()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],Jp(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(u4(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function Jp(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function u4(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=s4(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,l4(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],Jp(l,o,r),t[y>>2]=(t[y>>2]|0)+12,f4(e,_),c4(_),h=k;return}}function s4(e){return e=e|0,357913941}function l4(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function f4(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function c4(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function Qp(e){e=e|0,p4(e)}function a4(e){e=e|0,d4(e+24|0)}function d4(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function p4(e){e=e|0;var n=0;n=An()|0,Nn(e,2,1,n,h4()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function h4(){return 1300}function m4(e,n,r,o){e=e|0,n=n|0,r=r|0,o=+o;var s=0,l=0,d=0,_=0;s=h,h=h+16|0,l=s+8|0,d=s,_=v4(e)|0,e=t[_+4>>2]|0,t[d>>2]=t[_>>2],t[d+4>>2]=e,t[l>>2]=t[d>>2],t[l+4>>2]=t[d+4>>2],g4(n,l,r,o),h=s}function v4(e){return e=e|0,(t[(H1()|0)+24>>2]|0)+(e*12|0)|0}function g4(e,n,r,o){e=e|0,n=n|0,r=r|0,o=+o;var s=0,l=0,d=0,_=0;_=h,h=h+16|0,l=_+1|0,d=_,s=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(s=t[(t[e>>2]|0)+s>>2]|0),ts(l,r),l=ns(l,r)|0,wu(d,o),o=+Du(d,o),cD[s&15](e,l,o),h=_}function a(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],p(e,r,s,0),h=o}function p(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=E()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=I(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,B(l,o)|0,o),h=s}function E(){var e=0,n=0;if(c[7776]|0||(nt(9828),Bt(41,9828,Q|0)|0,n=7776,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9828)|0)){e=9828,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));nt(9828)}return 9828}function I(e){return e=e|0,0}function B(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=E()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],G(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(te(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function G(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function te(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=se(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,Ee(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],G(l,o,r),t[y>>2]=(t[y>>2]|0)+12,$e(e,_),Ke(_),h=k;return}}function se(e){return e=e|0,357913941}function Ee(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function $e(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function Ke(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function nt(e){e=e|0,an(e)}function Ct(e){e=e|0,Gt(e+24|0)}function Gt(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function an(e){e=e|0;var n=0;n=An()|0,Nn(e,2,7,n,qn()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function qn(){return 1312}function dn(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;o=h,h=h+16|0,s=o+8|0,l=o,d=Yn(e)|0,e=t[d+4>>2]|0,t[l>>2]=t[d>>2],t[l+4>>2]=e,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],er(n,s,r),h=o}function Yn(e){return e=e|0,(t[(E()|0)+24>>2]|0)+(e*12|0)|0}function er(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0;l=h,h=h+16|0,s=l,o=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(o=t[(t[e>>2]|0)+o>>2]|0),ts(s,r),s=ns(s,r)|0,Bl[o&31](e,s),h=l}function vo(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Pi(e,r,s,0),h=o}function Pi(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=Mi()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=f0(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,Jo(l,o)|0,o),h=s}function Mi(){var e=0,n=0;if(c[7784]|0||(kw(9864),Bt(42,9864,Q|0)|0,n=7784,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9864)|0)){e=9864,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));kw(9864)}return 9864}function f0(e){return e=e|0,0}function Jo(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=Mi()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],Su(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(Zp(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function Su(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function Zp(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=v9(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,g9(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],Su(l,o,r),t[y>>2]=(t[y>>2]|0)+12,_9(e,_),y9(_),h=k;return}}function v9(e){return e=e|0,357913941}function g9(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function _9(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function y9(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function kw(e){e=e|0,E9(e)}function w9(e){e=e|0,D9(e+24|0)}function D9(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function E9(e){e=e|0;var n=0;n=An()|0,Nn(e,2,8,n,S9()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function S9(){return 1320}function C9(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;o=h,h=h+16|0,s=o+8|0,l=o,d=T9(e)|0,e=t[d+4>>2]|0,t[l>>2]=t[d>>2],t[l+4>>2]=e,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],x9(n,s,r),h=o}function T9(e){return e=e|0,(t[(Mi()|0)+24>>2]|0)+(e*12|0)|0}function x9(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0;l=h,h=h+16|0,s=l,o=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(o=t[(t[e>>2]|0)+o>>2]|0),k9(s,r),s=A9(s,r)|0,Bl[o&31](e,s),h=l}function k9(e,n){e=e|0,n=n|0}function A9(e,n){return e=e|0,n=n|0,O9(n)|0}function O9(e){return e=e|0,e|0}function I9(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],P9(e,r,s,0),h=o}function P9(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=_4()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=M9(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,F9(l,o)|0,o),h=s}function _4(){var e=0,n=0;if(c[7792]|0||(Ow(9900),Bt(43,9900,Q|0)|0,n=7792,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9900)|0)){e=9900,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Ow(9900)}return 9900}function M9(e){return e=e|0,0}function F9(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=_4()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],Aw(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(L9(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function Aw(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function L9(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=R9(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,N9(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],Aw(l,o,r),t[y>>2]=(t[y>>2]|0)+12,B9(e,_),j9(_),h=k;return}}function R9(e){return e=e|0,357913941}function N9(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function B9(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function j9(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function Ow(e){e=e|0,z9(e)}function U9(e){e=e|0,q9(e+24|0)}function q9(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function z9(e){e=e|0;var n=0;n=An()|0,Nn(e,2,22,n,W9()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function W9(){return 1344}function H9(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0;r=h,h=h+16|0,o=r+8|0,s=r,l=b9(e)|0,e=t[l+4>>2]|0,t[s>>2]=t[l>>2],t[s+4>>2]=e,t[o>>2]=t[s>>2],t[o+4>>2]=t[s+4>>2],G9(n,o),h=r}function b9(e){return e=e|0,(t[(_4()|0)+24>>2]|0)+(e*12|0)|0}function G9(e,n){e=e|0,n=n|0;var r=0;r=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(r=t[(t[e>>2]|0)+r>>2]|0),Nl[r&127](e)}function V9(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0;l=t[e>>2]|0,s=y4()|0,e=Y9(r)|0,ur(l,n,s,e,$9(r,o)|0,o)}function y4(){var e=0,n=0;if(c[7800]|0||(Pw(9936),Bt(44,9936,Q|0)|0,n=7800,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9936)|0)){e=9936,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Pw(9936)}return 9936}function Y9(e){return e=e|0,e|0}function $9(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0;return _=h,h=h+16|0,s=_,l=_+4|0,t[s>>2]=e,y=y4()|0,d=y+24|0,n=Lt(n,4)|0,t[l>>2]=n,r=y+28|0,o=t[r>>2]|0,o>>>0<(t[y+32>>2]|0)>>>0?(Iw(o,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(K9(d,s,l),n=t[r>>2]|0),h=_,(n-(t[d>>2]|0)>>3)+-1|0}function Iw(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function K9(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0;if(_=h,h=h+32|0,s=_,l=e+4|0,d=((t[l>>2]|0)-(t[e>>2]|0)>>3)+1|0,o=X9(e)|0,o>>>0>>0)$n(e);else{y=t[e>>2]|0,T=(t[e+8>>2]|0)-y|0,k=T>>2,J9(s,T>>3>>>0>>1>>>0?k>>>0>>0?d:k:o,(t[l>>2]|0)-y>>3,e+8|0),d=s+8|0,Iw(t[d>>2]|0,t[n>>2]|0,t[r>>2]|0),t[d>>2]=(t[d>>2]|0)+8,Q9(e,s),Z9(s),h=_;return}}function X9(e){return e=e|0,536870911}function J9(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>536870911)_n();else{s=Tt(n<<3)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r<<3)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n<<3)}function Q9(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(0-(s>>3)<<3)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function Z9(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~((o+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&Ve(e)}function Pw(e){e=e|0,nx(e)}function ex(e){e=e|0,tx(e+24|0)}function tx(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function nx(e){e=e|0;var n=0;n=An()|0,Nn(e,1,23,n,Mo()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function rx(e,n){e=e|0,n=n|0,ox(t[(ix(e)|0)>>2]|0,n)}function ix(e){return e=e|0,(t[(y4()|0)+24>>2]|0)+(e<<3)|0}function ox(e,n){e=e|0,n=n|0;var r=0,o=0;r=h,h=h+16|0,o=r,On(o,n),n=x1(o,n)|0,Nl[e&127](n),h=r}function ux(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0;l=t[e>>2]|0,s=w4()|0,e=sx(r)|0,ur(l,n,s,e,lx(r,o)|0,o)}function w4(){var e=0,n=0;if(c[7808]|0||(Fw(9972),Bt(45,9972,Q|0)|0,n=7808,t[n>>2]=1,t[n+4>>2]=0),!(Dn(9972)|0)){e=9972,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Fw(9972)}return 9972}function sx(e){return e=e|0,e|0}function lx(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0;return _=h,h=h+16|0,s=_,l=_+4|0,t[s>>2]=e,y=w4()|0,d=y+24|0,n=Lt(n,4)|0,t[l>>2]=n,r=y+28|0,o=t[r>>2]|0,o>>>0<(t[y+32>>2]|0)>>>0?(Mw(o,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(fx(d,s,l),n=t[r>>2]|0),h=_,(n-(t[d>>2]|0)>>3)+-1|0}function Mw(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function fx(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0;if(_=h,h=h+32|0,s=_,l=e+4|0,d=((t[l>>2]|0)-(t[e>>2]|0)>>3)+1|0,o=cx(e)|0,o>>>0>>0)$n(e);else{y=t[e>>2]|0,T=(t[e+8>>2]|0)-y|0,k=T>>2,ax(s,T>>3>>>0>>1>>>0?k>>>0>>0?d:k:o,(t[l>>2]|0)-y>>3,e+8|0),d=s+8|0,Mw(t[d>>2]|0,t[n>>2]|0,t[r>>2]|0),t[d>>2]=(t[d>>2]|0)+8,dx(e,s),px(s),h=_;return}}function cx(e){return e=e|0,536870911}function ax(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>536870911)_n();else{s=Tt(n<<3)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r<<3)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n<<3)}function dx(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(0-(s>>3)<<3)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function px(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~((o+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&Ve(e)}function Fw(e){e=e|0,vx(e)}function hx(e){e=e|0,mx(e+24|0)}function mx(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function vx(e){e=e|0;var n=0;n=An()|0,Nn(e,1,9,n,gx()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function gx(){return 1348}function _x(e,n){return e=e|0,n=n|0,wx(t[(yx(e)|0)>>2]|0,n)|0}function yx(e){return e=e|0,(t[(w4()|0)+24>>2]|0)+(e<<3)|0}function wx(e,n){e=e|0,n=n|0;var r=0,o=0;return r=h,h=h+16|0,o=r,Lw(o,n),n=Rw(o,n)|0,n=Xc(dc[e&31](n)|0)|0,h=r,n|0}function Lw(e,n){e=e|0,n=n|0}function Rw(e,n){return e=e|0,n=n|0,Dx(n)|0}function Dx(e){return e=e|0,e|0}function Ex(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0;l=t[e>>2]|0,s=D4()|0,e=Sx(r)|0,ur(l,n,s,e,Cx(r,o)|0,o)}function D4(){var e=0,n=0;if(c[7816]|0||(Bw(10008),Bt(46,10008,Q|0)|0,n=7816,t[n>>2]=1,t[n+4>>2]=0),!(Dn(10008)|0)){e=10008,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Bw(10008)}return 10008}function Sx(e){return e=e|0,e|0}function Cx(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0;return _=h,h=h+16|0,s=_,l=_+4|0,t[s>>2]=e,y=D4()|0,d=y+24|0,n=Lt(n,4)|0,t[l>>2]=n,r=y+28|0,o=t[r>>2]|0,o>>>0<(t[y+32>>2]|0)>>>0?(Nw(o,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(Tx(d,s,l),n=t[r>>2]|0),h=_,(n-(t[d>>2]|0)>>3)+-1|0}function Nw(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function Tx(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0;if(_=h,h=h+32|0,s=_,l=e+4|0,d=((t[l>>2]|0)-(t[e>>2]|0)>>3)+1|0,o=xx(e)|0,o>>>0>>0)$n(e);else{y=t[e>>2]|0,T=(t[e+8>>2]|0)-y|0,k=T>>2,kx(s,T>>3>>>0>>1>>>0?k>>>0>>0?d:k:o,(t[l>>2]|0)-y>>3,e+8|0),d=s+8|0,Nw(t[d>>2]|0,t[n>>2]|0,t[r>>2]|0),t[d>>2]=(t[d>>2]|0)+8,Ax(e,s),Ox(s),h=_;return}}function xx(e){return e=e|0,536870911}function kx(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>536870911)_n();else{s=Tt(n<<3)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r<<3)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n<<3)}function Ax(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(0-(s>>3)<<3)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function Ox(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~((o+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&Ve(e)}function Bw(e){e=e|0,Mx(e)}function Ix(e){e=e|0,Px(e+24|0)}function Px(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function Mx(e){e=e|0;var n=0;n=An()|0,Nn(e,1,15,n,mp()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function Fx(e){return e=e|0,Rx(t[(Lx(e)|0)>>2]|0)|0}function Lx(e){return e=e|0,(t[(D4()|0)+24>>2]|0)+(e<<3)|0}function Rx(e){return e=e|0,Xc(ph[e&7]()|0)|0}function Nx(){var e=0;return c[7832]|0||(bx(10052),Bt(25,10052,Q|0)|0,e=7832,t[e>>2]=1,t[e+4>>2]=0),10052}function Bx(e,n){e=e|0,n=n|0,t[e>>2]=jx()|0,t[e+4>>2]=Ux()|0,t[e+12>>2]=n,t[e+8>>2]=qx()|0,t[e+32>>2]=2}function jx(){return 11709}function Ux(){return 1188}function qx(){return eh()|0}function zx(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0,(Sf(o,896)|0)==512?r|0&&(Wx(r),Ve(r)):n|0&&(mu(n),Ve(n))}function Sf(e,n){return e=e|0,n=n|0,n&e|0}function Wx(e){e=e|0,e=t[e+4>>2]|0,e|0&&Tf(e)}function eh(){var e=0;return c[7824]|0||(t[2511]=Hx()|0,t[2512]=0,e=7824,t[e>>2]=1,t[e+4>>2]=0),10044}function Hx(){return 0}function bx(e){e=e|0,Ys(e)}function Gx(e){e=e|0;var n=0,r=0,o=0,s=0,l=0;n=h,h=h+32|0,r=n+24|0,l=n+16|0,s=n+8|0,o=n,Vx(e,4827),Yx(e,4834,3)|0,$x(e,3682,47)|0,t[l>>2]=9,t[l+4>>2]=0,t[r>>2]=t[l>>2],t[r+4>>2]=t[l+4>>2],Kx(e,4841,r)|0,t[s>>2]=1,t[s+4>>2]=0,t[r>>2]=t[s>>2],t[r+4>>2]=t[s+4>>2],Xx(e,4871,r)|0,t[o>>2]=10,t[o+4>>2]=0,t[r>>2]=t[o>>2],t[r+4>>2]=t[o+4>>2],Jx(e,4891,r)|0,h=n}function Vx(e,n){e=e|0,n=n|0;var r=0;r=Ok()|0,t[e>>2]=r,Ik(r,n),Cf(t[e>>2]|0)}function Yx(e,n,r){return e=e|0,n=n|0,r=r|0,pk(e,Zn(n)|0,r,0),e|0}function $x(e,n,r){return e=e|0,n=n|0,r=r|0,Q7(e,Zn(n)|0,r,0),e|0}function Kx(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],F7(e,n,s),h=o,e|0}function Xx(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],h7(e,n,s),h=o,e|0}function Jx(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=t[r+4>>2]|0,t[l>>2]=t[r>>2],t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Qx(e,n,s),h=o,e|0}function Qx(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],Zx(e,r,s,1),h=o}function Zx(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=E4()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=e7(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,t7(l,o)|0,o),h=s}function E4(){var e=0,n=0;if(c[7840]|0||(Uw(10100),Bt(48,10100,Q|0)|0,n=7840,t[n>>2]=1,t[n+4>>2]=0),!(Dn(10100)|0)){e=10100,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Uw(10100)}return 10100}function e7(e){return e=e|0,0}function t7(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=E4()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],jw(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(n7(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function jw(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function n7(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=r7(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,i7(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],jw(l,o,r),t[y>>2]=(t[y>>2]|0)+12,o7(e,_),u7(_),h=k;return}}function r7(e){return e=e|0,357913941}function i7(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function o7(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function u7(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function Uw(e){e=e|0,f7(e)}function s7(e){e=e|0,l7(e+24|0)}function l7(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function f7(e){e=e|0;var n=0;n=An()|0,Nn(e,2,6,n,c7()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function c7(){return 1364}function a7(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;return o=h,h=h+16|0,s=o+8|0,l=o,d=d7(e)|0,e=t[d+4>>2]|0,t[l>>2]=t[d>>2],t[l+4>>2]=e,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],r=p7(n,s,r)|0,h=o,r|0}function d7(e){return e=e|0,(t[(E4()|0)+24>>2]|0)+(e*12|0)|0}function p7(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0;return l=h,h=h+16|0,s=l,o=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(o=t[(t[e>>2]|0)+o>>2]|0),ts(s,r),s=ns(s,r)|0,s=ip(J4[o&15](e,s)|0)|0,h=l,s|0}function h7(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],m7(e,r,s,0),h=o}function m7(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=S4()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=v7(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,g7(l,o)|0,o),h=s}function S4(){var e=0,n=0;if(c[7848]|0||(zw(10136),Bt(49,10136,Q|0)|0,n=7848,t[n>>2]=1,t[n+4>>2]=0),!(Dn(10136)|0)){e=10136,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));zw(10136)}return 10136}function v7(e){return e=e|0,0}function g7(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=S4()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],qw(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(_7(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function qw(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function _7(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=y7(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,w7(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],qw(l,o,r),t[y>>2]=(t[y>>2]|0)+12,D7(e,_),E7(_),h=k;return}}function y7(e){return e=e|0,357913941}function w7(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function D7(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function E7(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function zw(e){e=e|0,T7(e)}function S7(e){e=e|0,C7(e+24|0)}function C7(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function T7(e){e=e|0;var n=0;n=An()|0,Nn(e,2,9,n,x7()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function x7(){return 1372}function k7(e,n,r){e=e|0,n=n|0,r=+r;var o=0,s=0,l=0,d=0;o=h,h=h+16|0,s=o+8|0,l=o,d=A7(e)|0,e=t[d+4>>2]|0,t[l>>2]=t[d>>2],t[l+4>>2]=e,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],O7(n,s,r),h=o}function A7(e){return e=e|0,(t[(S4()|0)+24>>2]|0)+(e*12|0)|0}function O7(e,n,r){e=e|0,n=n|0,r=+r;var o=0,s=0,l=0,d=tt;l=h,h=h+16|0,s=l,o=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(o=t[(t[e>>2]|0)+o>>2]|0),I7(s,r),d=w(P7(s,r)),tD[o&1](e,d),h=l}function I7(e,n){e=e|0,n=+n}function P7(e,n){return e=e|0,n=+n,w(M7(n))}function M7(e){return e=+e,w(e)}function F7(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,s=o+8|0,l=o,_=t[r>>2]|0,d=t[r+4>>2]|0,r=Zn(n)|0,t[l>>2]=_,t[l+4>>2]=d,t[s>>2]=t[l>>2],t[s+4>>2]=t[l+4>>2],L7(e,r,s,0),h=o}function L7(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0,y=0,k=0,T=0;s=h,h=h+32|0,l=s+16|0,T=s+8|0,_=s,k=t[r>>2]|0,y=t[r+4>>2]|0,d=t[e>>2]|0,e=C4()|0,t[T>>2]=k,t[T+4>>2]=y,t[l>>2]=t[T>>2],t[l+4>>2]=t[T+4>>2],r=R7(l)|0,t[_>>2]=k,t[_+4>>2]=y,t[l>>2]=t[_>>2],t[l+4>>2]=t[_+4>>2],ur(d,n,e,r,N7(l,o)|0,o),h=s}function C4(){var e=0,n=0;if(c[7856]|0||(Hw(10172),Bt(50,10172,Q|0)|0,n=7856,t[n>>2]=1,t[n+4>>2]=0),!(Dn(10172)|0)){e=10172,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Hw(10172)}return 10172}function R7(e){return e=e|0,0}function N7(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0;return T=h,h=h+32|0,s=T+24|0,d=T+16|0,_=T,y=T+8|0,l=t[e>>2]|0,o=t[e+4>>2]|0,t[_>>2]=l,t[_+4>>2]=o,P=C4()|0,k=P+24|0,e=Lt(n,4)|0,t[y>>2]=e,n=P+28|0,r=t[n>>2]|0,r>>>0<(t[P+32>>2]|0)>>>0?(t[d>>2]=l,t[d+4>>2]=o,t[s>>2]=t[d>>2],t[s+4>>2]=t[d+4>>2],Ww(r,s,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(B7(k,_,y),e=t[n>>2]|0),h=T,((e-(t[k>>2]|0)|0)/12|0)+-1|0}function Ww(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=t[n+4>>2]|0,t[e>>2]=t[n>>2],t[e+4>>2]=o,t[e+8>>2]=r}function B7(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;if(k=h,h=h+48|0,o=k+32|0,d=k+24|0,_=k,y=e+4|0,s=(((t[y>>2]|0)-(t[e>>2]|0)|0)/12|0)+1|0,l=j7(e)|0,l>>>0>>0)$n(e);else{T=t[e>>2]|0,q=((t[e+8>>2]|0)-T|0)/12|0,P=q<<1,U7(_,q>>>0>>1>>>0?P>>>0>>0?s:P:l,((t[y>>2]|0)-T|0)/12|0,e+8|0),y=_+8|0,l=t[y>>2]|0,s=t[n+4>>2]|0,r=t[r>>2]|0,t[d>>2]=t[n>>2],t[d+4>>2]=s,t[o>>2]=t[d>>2],t[o+4>>2]=t[d+4>>2],Ww(l,o,r),t[y>>2]=(t[y>>2]|0)+12,q7(e,_),z7(_),h=k;return}}function j7(e){return e=e|0,357913941}function U7(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>357913941)_n();else{s=Tt(n*12|0)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r*12|0)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n*12|0)}function q7(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(((s|0)/-12|0)*12|0)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function z7(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~(((o+-12-n|0)>>>0)/12|0)*12|0)),e=t[e>>2]|0,e|0&&Ve(e)}function Hw(e){e=e|0,b7(e)}function W7(e){e=e|0,H7(e+24|0)}function H7(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~(((n+-12-o|0)>>>0)/12|0)*12|0)),Ve(r))}function b7(e){e=e|0;var n=0;n=An()|0,Nn(e,2,3,n,G7()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function G7(){return 1380}function V7(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0;s=h,h=h+16|0,l=s+8|0,d=s,_=Y7(e)|0,e=t[_+4>>2]|0,t[d>>2]=t[_>>2],t[d+4>>2]=e,t[l>>2]=t[d>>2],t[l+4>>2]=t[d+4>>2],$7(n,l,r,o),h=s}function Y7(e){return e=e|0,(t[(C4()|0)+24>>2]|0)+(e*12|0)|0}function $7(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0;_=h,h=h+16|0,l=_+1|0,d=_,s=t[n>>2]|0,n=t[n+4>>2]|0,e=e+(n>>1)|0,n&1&&(s=t[(t[e>>2]|0)+s>>2]|0),ts(l,r),l=ns(l,r)|0,K7(d,o),d=X7(d,o)|0,X1[s&15](e,l,d),h=_}function K7(e,n){e=e|0,n=n|0}function X7(e,n){return e=e|0,n=n|0,J7(n)|0}function J7(e){return e=e|0,(e|0)!=0|0}function Q7(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0;l=t[e>>2]|0,s=T4()|0,e=Z7(r)|0,ur(l,n,s,e,ek(r,o)|0,o)}function T4(){var e=0,n=0;if(c[7864]|0||(Gw(10208),Bt(51,10208,Q|0)|0,n=7864,t[n>>2]=1,t[n+4>>2]=0),!(Dn(10208)|0)){e=10208,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Gw(10208)}return 10208}function Z7(e){return e=e|0,e|0}function ek(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0;return _=h,h=h+16|0,s=_,l=_+4|0,t[s>>2]=e,y=T4()|0,d=y+24|0,n=Lt(n,4)|0,t[l>>2]=n,r=y+28|0,o=t[r>>2]|0,o>>>0<(t[y+32>>2]|0)>>>0?(bw(o,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(tk(d,s,l),n=t[r>>2]|0),h=_,(n-(t[d>>2]|0)>>3)+-1|0}function bw(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function tk(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0;if(_=h,h=h+32|0,s=_,l=e+4|0,d=((t[l>>2]|0)-(t[e>>2]|0)>>3)+1|0,o=nk(e)|0,o>>>0>>0)$n(e);else{y=t[e>>2]|0,T=(t[e+8>>2]|0)-y|0,k=T>>2,rk(s,T>>3>>>0>>1>>>0?k>>>0>>0?d:k:o,(t[l>>2]|0)-y>>3,e+8|0),d=s+8|0,bw(t[d>>2]|0,t[n>>2]|0,t[r>>2]|0),t[d>>2]=(t[d>>2]|0)+8,ik(e,s),ok(s),h=_;return}}function nk(e){return e=e|0,536870911}function rk(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>536870911)_n();else{s=Tt(n<<3)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r<<3)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n<<3)}function ik(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(0-(s>>3)<<3)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function ok(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~((o+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&Ve(e)}function Gw(e){e=e|0,lk(e)}function uk(e){e=e|0,sk(e+24|0)}function sk(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function lk(e){e=e|0;var n=0;n=An()|0,Nn(e,1,24,n,fk()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function fk(){return 1392}function ck(e,n){e=e|0,n=n|0,dk(t[(ak(e)|0)>>2]|0,n)}function ak(e){return e=e|0,(t[(T4()|0)+24>>2]|0)+(e<<3)|0}function dk(e,n){e=e|0,n=n|0;var r=0,o=0;r=h,h=h+16|0,o=r,Lw(o,n),n=Rw(o,n)|0,Nl[e&127](n),h=r}function pk(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0;l=t[e>>2]|0,s=x4()|0,e=hk(r)|0,ur(l,n,s,e,mk(r,o)|0,o)}function x4(){var e=0,n=0;if(c[7872]|0||(Yw(10244),Bt(52,10244,Q|0)|0,n=7872,t[n>>2]=1,t[n+4>>2]=0),!(Dn(10244)|0)){e=10244,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));Yw(10244)}return 10244}function hk(e){return e=e|0,e|0}function mk(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0;return _=h,h=h+16|0,s=_,l=_+4|0,t[s>>2]=e,y=x4()|0,d=y+24|0,n=Lt(n,4)|0,t[l>>2]=n,r=y+28|0,o=t[r>>2]|0,o>>>0<(t[y+32>>2]|0)>>>0?(Vw(o,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(vk(d,s,l),n=t[r>>2]|0),h=_,(n-(t[d>>2]|0)>>3)+-1|0}function Vw(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function vk(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0;if(_=h,h=h+32|0,s=_,l=e+4|0,d=((t[l>>2]|0)-(t[e>>2]|0)>>3)+1|0,o=gk(e)|0,o>>>0>>0)$n(e);else{y=t[e>>2]|0,T=(t[e+8>>2]|0)-y|0,k=T>>2,_k(s,T>>3>>>0>>1>>>0?k>>>0>>0?d:k:o,(t[l>>2]|0)-y>>3,e+8|0),d=s+8|0,Vw(t[d>>2]|0,t[n>>2]|0,t[r>>2]|0),t[d>>2]=(t[d>>2]|0)+8,yk(e,s),wk(s),h=_;return}}function gk(e){return e=e|0,536870911}function _k(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>536870911)_n();else{s=Tt(n<<3)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r<<3)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n<<3)}function yk(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(0-(s>>3)<<3)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function wk(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~((o+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&Ve(e)}function Yw(e){e=e|0,Sk(e)}function Dk(e){e=e|0,Ek(e+24|0)}function Ek(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function Sk(e){e=e|0;var n=0;n=An()|0,Nn(e,1,16,n,Ck()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function Ck(){return 1400}function Tk(e){return e=e|0,kk(t[(xk(e)|0)>>2]|0)|0}function xk(e){return e=e|0,(t[(x4()|0)+24>>2]|0)+(e<<3)|0}function kk(e){return e=e|0,Ak(ph[e&7]()|0)|0}function Ak(e){return e=e|0,e|0}function Ok(){var e=0;return c[7880]|0||(Nk(10280),Bt(25,10280,Q|0)|0,e=7880,t[e>>2]=1,t[e+4>>2]=0),10280}function Ik(e,n){e=e|0,n=n|0,t[e>>2]=Pk()|0,t[e+4>>2]=Mk()|0,t[e+12>>2]=n,t[e+8>>2]=Fk()|0,t[e+32>>2]=4}function Pk(){return 11711}function Mk(){return 1356}function Fk(){return eh()|0}function Lk(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0,(Sf(o,896)|0)==512?r|0&&(Rk(r),Ve(r)):n|0&&(Gi(n),Ve(n))}function Rk(e){e=e|0,e=t[e+4>>2]|0,e|0&&Tf(e)}function Nk(e){e=e|0,Ys(e)}function Bk(e){e=e|0,jk(e,4920),Uk(e)|0,qk(e)|0}function jk(e,n){e=e|0,n=n|0;var r=0;r=Up()|0,t[e>>2]=r,sA(r,n),Cf(t[e>>2]|0)}function Uk(e){e=e|0;var n=0;return n=t[e>>2]|0,uc(n,Jk()|0),e|0}function qk(e){e=e|0;var n=0;return n=t[e>>2]|0,uc(n,zk()|0),e|0}function zk(){var e=0;return c[7888]|0||($w(10328),Bt(53,10328,Q|0)|0,e=7888,t[e>>2]=1,t[e+4>>2]=0),Dn(10328)|0||$w(10328),10328}function uc(e,n){e=e|0,n=n|0,ur(e,0,n,0,0,0)}function $w(e){e=e|0,bk(e),sc(e,10)}function Wk(e){e=e|0,Hk(e+24|0)}function Hk(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function bk(e){e=e|0;var n=0;n=An()|0,Nn(e,5,1,n,$k()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function Gk(e,n,r){e=e|0,n=n|0,r=+r,Vk(e,n,r)}function sc(e,n){e=e|0,n=n|0,t[e+20>>2]=n}function Vk(e,n,r){e=e|0,n=n|0,r=+r;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+16|0,l=o+8|0,_=o+13|0,s=o,d=o+12|0,ts(_,n),t[l>>2]=ns(_,n)|0,wu(d,r),L[s>>3]=+Du(d,r),Yk(e,l,s),h=o}function Yk(e,n,r){e=e|0,n=n|0,r=r|0,M(e+8|0,t[n>>2]|0,+L[r>>3]),c[e+24>>0]=1}function $k(){return 1404}function Kk(e,n){return e=e|0,n=+n,Xk(e,n)|0}function Xk(e,n){e=e|0,n=+n;var r=0,o=0,s=0,l=0,d=0,_=0,y=0;return o=h,h=h+16|0,l=o+4|0,d=o+8|0,_=o,s=Qo(8)|0,r=s,y=Tt(16)|0,ts(l,e),e=ns(l,e)|0,wu(d,n),M(y,e,+Du(d,n)),d=r+4|0,t[d>>2]=y,e=Tt(8)|0,d=t[d>>2]|0,t[_>>2]=0,t[l>>2]=t[_>>2],P1(e,d,l),t[s>>2]=e,h=o,r|0}function Jk(){var e=0;return c[7896]|0||(Kw(10364),Bt(54,10364,Q|0)|0,e=7896,t[e>>2]=1,t[e+4>>2]=0),Dn(10364)|0||Kw(10364),10364}function Kw(e){e=e|0,eA(e),sc(e,55)}function Qk(e){e=e|0,Zk(e+24|0)}function Zk(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function eA(e){e=e|0;var n=0;n=An()|0,Nn(e,5,4,n,iA()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function tA(e){e=e|0,nA(e)}function nA(e){e=e|0,rA(e)}function rA(e){e=e|0,Xw(e+8|0),c[e+24>>0]=1}function Xw(e){e=e|0,t[e>>2]=0,L[e+8>>3]=0}function iA(){return 1424}function oA(){return uA()|0}function uA(){var e=0,n=0,r=0,o=0,s=0,l=0,d=0;return n=h,h=h+16|0,s=n+4|0,d=n,r=Qo(8)|0,e=r,o=Tt(16)|0,Xw(o),l=e+4|0,t[l>>2]=o,o=Tt(8)|0,l=t[l>>2]|0,t[d>>2]=0,t[s>>2]=t[d>>2],P1(o,l,s),t[r>>2]=o,h=n,e|0}function sA(e,n){e=e|0,n=n|0,t[e>>2]=lA()|0,t[e+4>>2]=fA()|0,t[e+12>>2]=n,t[e+8>>2]=cA()|0,t[e+32>>2]=5}function lA(){return 11710}function fA(){return 1416}function cA(){return th()|0}function aA(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0,(Sf(o,896)|0)==512?r|0&&(dA(r),Ve(r)):n|0&&Ve(n)}function dA(e){e=e|0,e=t[e+4>>2]|0,e|0&&Tf(e)}function th(){var e=0;return c[7904]|0||(t[2600]=pA()|0,t[2601]=0,e=7904,t[e>>2]=1,t[e+4>>2]=0),10400}function pA(){return t[357]|0}function hA(e){e=e|0,mA(e,4926),vA(e)|0}function mA(e,n){e=e|0,n=n|0;var r=0;r=u1()|0,t[e>>2]=r,kA(r,n),Cf(t[e>>2]|0)}function vA(e){e=e|0;var n=0;return n=t[e>>2]|0,uc(n,gA()|0),e|0}function gA(){var e=0;return c[7912]|0||(Jw(10412),Bt(56,10412,Q|0)|0,e=7912,t[e>>2]=1,t[e+4>>2]=0),Dn(10412)|0||Jw(10412),10412}function Jw(e){e=e|0,wA(e),sc(e,57)}function _A(e){e=e|0,yA(e+24|0)}function yA(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function wA(e){e=e|0;var n=0;n=An()|0,Nn(e,5,5,n,CA()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function DA(e){e=e|0,EA(e)}function EA(e){e=e|0,SA(e)}function SA(e){e=e|0;var n=0,r=0;n=e+8|0,r=n+48|0;do t[n>>2]=0,n=n+4|0;while((n|0)<(r|0));c[e+56>>0]=1}function CA(){return 1432}function TA(){return xA()|0}function xA(){var e=0,n=0,r=0,o=0,s=0,l=0,d=0,_=0;d=h,h=h+16|0,e=d+4|0,n=d,r=Qo(8)|0,o=r,s=Tt(48)|0,l=s,_=l+48|0;do t[l>>2]=0,l=l+4|0;while((l|0)<(_|0));return l=o+4|0,t[l>>2]=s,_=Tt(8)|0,l=t[l>>2]|0,t[n>>2]=0,t[e>>2]=t[n>>2],Wd(_,l,e),t[r>>2]=_,h=d,o|0}function kA(e,n){e=e|0,n=n|0,t[e>>2]=AA()|0,t[e+4>>2]=OA()|0,t[e+12>>2]=n,t[e+8>>2]=IA()|0,t[e+32>>2]=6}function AA(){return 11704}function OA(){return 1436}function IA(){return th()|0}function PA(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0,(Sf(o,896)|0)==512?r|0&&(MA(r),Ve(r)):n|0&&Ve(n)}function MA(e){e=e|0,e=t[e+4>>2]|0,e|0&&Tf(e)}function FA(e){e=e|0,LA(e,4933),RA(e)|0,NA(e)|0}function LA(e,n){e=e|0,n=n|0;var r=0;r=uO()|0,t[e>>2]=r,sO(r,n),Cf(t[e>>2]|0)}function RA(e){e=e|0;var n=0;return n=t[e>>2]|0,uc(n,XA()|0),e|0}function NA(e){e=e|0;var n=0;return n=t[e>>2]|0,uc(n,BA()|0),e|0}function BA(){var e=0;return c[7920]|0||(Qw(10452),Bt(58,10452,Q|0)|0,e=7920,t[e>>2]=1,t[e+4>>2]=0),Dn(10452)|0||Qw(10452),10452}function Qw(e){e=e|0,qA(e),sc(e,1)}function jA(e){e=e|0,UA(e+24|0)}function UA(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function qA(e){e=e|0;var n=0;n=An()|0,Nn(e,5,1,n,bA()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function zA(e,n,r){e=e|0,n=+n,r=+r,WA(e,n,r)}function WA(e,n,r){e=e|0,n=+n,r=+r;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+32|0,l=o+8|0,_=o+17|0,s=o,d=o+16|0,wu(_,n),L[l>>3]=+Du(_,n),wu(d,r),L[s>>3]=+Du(d,r),HA(e,l,s),h=o}function HA(e,n,r){e=e|0,n=n|0,r=r|0,Zw(e+8|0,+L[n>>3],+L[r>>3]),c[e+24>>0]=1}function Zw(e,n,r){e=e|0,n=+n,r=+r,L[e>>3]=n,L[e+8>>3]=r}function bA(){return 1472}function GA(e,n){return e=+e,n=+n,VA(e,n)|0}function VA(e,n){e=+e,n=+n;var r=0,o=0,s=0,l=0,d=0,_=0,y=0;return o=h,h=h+16|0,d=o+4|0,_=o+8|0,y=o,s=Qo(8)|0,r=s,l=Tt(16)|0,wu(d,e),e=+Du(d,e),wu(_,n),Zw(l,e,+Du(_,n)),_=r+4|0,t[_>>2]=l,l=Tt(8)|0,_=t[_>>2]|0,t[y>>2]=0,t[d>>2]=t[y>>2],e8(l,_,d),t[s>>2]=l,h=o,r|0}function e8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,r=Tt(16)|0,t[r+4>>2]=0,t[r+8>>2]=0,t[r>>2]=1452,t[r+12>>2]=n,t[e+4>>2]=r}function YA(e){e=e|0,da(e),Ve(e)}function $A(e){e=e|0,e=t[e+12>>2]|0,e|0&&Ve(e)}function KA(e){e=e|0,Ve(e)}function XA(){var e=0;return c[7928]|0||(t8(10488),Bt(59,10488,Q|0)|0,e=7928,t[e>>2]=1,t[e+4>>2]=0),Dn(10488)|0||t8(10488),10488}function t8(e){e=e|0,ZA(e),sc(e,60)}function JA(e){e=e|0,QA(e+24|0)}function QA(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function ZA(e){e=e|0;var n=0;n=An()|0,Nn(e,5,6,n,rO()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function eO(e){e=e|0,tO(e)}function tO(e){e=e|0,nO(e)}function nO(e){e=e|0,n8(e+8|0),c[e+24>>0]=1}function n8(e){e=e|0,t[e>>2]=0,t[e+4>>2]=0,t[e+8>>2]=0,t[e+12>>2]=0}function rO(){return 1492}function iO(){return oO()|0}function oO(){var e=0,n=0,r=0,o=0,s=0,l=0,d=0;return n=h,h=h+16|0,s=n+4|0,d=n,r=Qo(8)|0,e=r,o=Tt(16)|0,n8(o),l=e+4|0,t[l>>2]=o,o=Tt(8)|0,l=t[l>>2]|0,t[d>>2]=0,t[s>>2]=t[d>>2],e8(o,l,s),t[r>>2]=o,h=n,e|0}function uO(){var e=0;return c[7936]|0||(pO(10524),Bt(25,10524,Q|0)|0,e=7936,t[e>>2]=1,t[e+4>>2]=0),10524}function sO(e,n){e=e|0,n=n|0,t[e>>2]=lO()|0,t[e+4>>2]=fO()|0,t[e+12>>2]=n,t[e+8>>2]=cO()|0,t[e+32>>2]=7}function lO(){return 11700}function fO(){return 1484}function cO(){return th()|0}function aO(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0,(Sf(o,896)|0)==512?r|0&&(dO(r),Ve(r)):n|0&&Ve(n)}function dO(e){e=e|0,e=t[e+4>>2]|0,e|0&&Tf(e)}function pO(e){e=e|0,Ys(e)}function hO(e,n,r){e=e|0,n=n|0,r=r|0,e=Zn(n)|0,n=mO(r)|0,r=vO(r,0)|0,VO(e,n,r,k4()|0,0)}function mO(e){return e=e|0,e|0}function vO(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0;return _=h,h=h+16|0,s=_,l=_+4|0,t[s>>2]=e,y=k4()|0,d=y+24|0,n=Lt(n,4)|0,t[l>>2]=n,r=y+28|0,o=t[r>>2]|0,o>>>0<(t[y+32>>2]|0)>>>0?(i8(o,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(SO(d,s,l),n=t[r>>2]|0),h=_,(n-(t[d>>2]|0)>>3)+-1|0}function k4(){var e=0,n=0;if(c[7944]|0||(r8(10568),Bt(61,10568,Q|0)|0,n=7944,t[n>>2]=1,t[n+4>>2]=0),!(Dn(10568)|0)){e=10568,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));r8(10568)}return 10568}function r8(e){e=e|0,yO(e)}function gO(e){e=e|0,_O(e+24|0)}function _O(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function yO(e){e=e|0;var n=0;n=An()|0,Nn(e,1,17,n,Dp()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function wO(e){return e=e|0,EO(t[(DO(e)|0)>>2]|0)|0}function DO(e){return e=e|0,(t[(k4()|0)+24>>2]|0)+(e<<3)|0}function EO(e){return e=e|0,ea(ph[e&7]()|0)|0}function i8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function SO(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0;if(_=h,h=h+32|0,s=_,l=e+4|0,d=((t[l>>2]|0)-(t[e>>2]|0)>>3)+1|0,o=CO(e)|0,o>>>0>>0)$n(e);else{y=t[e>>2]|0,T=(t[e+8>>2]|0)-y|0,k=T>>2,TO(s,T>>3>>>0>>1>>>0?k>>>0>>0?d:k:o,(t[l>>2]|0)-y>>3,e+8|0),d=s+8|0,i8(t[d>>2]|0,t[n>>2]|0,t[r>>2]|0),t[d>>2]=(t[d>>2]|0)+8,xO(e,s),kO(s),h=_;return}}function CO(e){return e=e|0,536870911}function TO(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>536870911)_n();else{s=Tt(n<<3)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r<<3)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n<<3)}function xO(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(0-(s>>3)<<3)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function kO(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~((o+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&Ve(e)}function AO(){OO()}function OO(){IO(10604)}function IO(e){e=e|0,PO(e,4955)}function PO(e,n){e=e|0,n=n|0;var r=0;r=MO()|0,t[e>>2]=r,FO(r,n),Cf(t[e>>2]|0)}function MO(){var e=0;return c[7952]|0||(WO(10612),Bt(25,10612,Q|0)|0,e=7952,t[e>>2]=1,t[e+4>>2]=0),10612}function FO(e,n){e=e|0,n=n|0,t[e>>2]=BO()|0,t[e+4>>2]=jO()|0,t[e+12>>2]=n,t[e+8>>2]=UO()|0,t[e+32>>2]=8}function Cf(e){e=e|0;var n=0,r=0;n=h,h=h+16|0,r=n,sa()|0,t[r>>2]=e,LO(10608,r),h=n}function sa(){return c[11714]|0||(t[2652]=0,Bt(62,10608,Q|0)|0,c[11714]=1),10608}function LO(e,n){e=e|0,n=n|0;var r=0;r=Tt(8)|0,t[r+4>>2]=t[n>>2],t[r>>2]=t[e>>2],t[e>>2]=r}function RO(e){e=e|0,NO(e)}function NO(e){e=e|0;var n=0,r=0;if(n=t[e>>2]|0,n|0)do r=n,n=t[n>>2]|0,Ve(r);while((n|0)!=0);t[e>>2]=0}function BO(){return 11715}function jO(){return 1496}function UO(){return eh()|0}function qO(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0,(Sf(o,896)|0)==512?r|0&&(zO(r),Ve(r)):n|0&&Ve(n)}function zO(e){e=e|0,e=t[e+4>>2]|0,e|0&&Tf(e)}function WO(e){e=e|0,Ys(e)}function HO(e,n){e=e|0,n=n|0;var r=0,o=0;sa()|0,r=t[2652]|0;e:do if(r|0){for(;o=t[r+4>>2]|0,!(o|0?(U8(A4(o)|0,e)|0)==0:0);)if(r=t[r>>2]|0,!r)break e;bO(o,n)}while(0)}function A4(e){return e=e|0,t[e+12>>2]|0}function bO(e,n){e=e|0,n=n|0;var r=0;e=e+36|0,r=t[e>>2]|0,r|0&&(Ju(r),Ve(r)),r=Tt(4)|0,ba(r,n),t[e>>2]=r}function O4(){return c[11716]|0||(t[2664]=0,Bt(63,10656,Q|0)|0,c[11716]=1),10656}function o8(){var e=0;return c[11717]|0?e=t[2665]|0:(GO(),t[2665]=1504,c[11717]=1,e=1504),e|0}function GO(){c[11740]|0||(c[11718]=Lt(Lt(8,0)|0,0)|0,c[11719]=Lt(Lt(0,0)|0,0)|0,c[11720]=Lt(Lt(0,16)|0,0)|0,c[11721]=Lt(Lt(8,0)|0,0)|0,c[11722]=Lt(Lt(0,0)|0,0)|0,c[11723]=Lt(Lt(8,0)|0,0)|0,c[11724]=Lt(Lt(0,0)|0,0)|0,c[11725]=Lt(Lt(8,0)|0,0)|0,c[11726]=Lt(Lt(0,0)|0,0)|0,c[11727]=Lt(Lt(8,0)|0,0)|0,c[11728]=Lt(Lt(0,0)|0,0)|0,c[11729]=Lt(Lt(0,0)|0,32)|0,c[11730]=Lt(Lt(0,0)|0,32)|0,c[11740]=1)}function u8(){return 1572}function VO(e,n,r,o,s){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0;var l=0,d=0,_=0,y=0,k=0,T=0;l=h,h=h+32|0,T=l+16|0,k=l+12|0,y=l+8|0,_=l+4|0,d=l,t[T>>2]=e,t[k>>2]=n,t[y>>2]=r,t[_>>2]=o,t[d>>2]=s,O4()|0,YO(10656,T,k,y,_,d),h=l}function YO(e,n,r,o,s,l){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0;var d=0;d=Tt(24)|0,t1(d+4|0,t[n>>2]|0,t[r>>2]|0,t[o>>2]|0,t[s>>2]|0,t[l>>2]|0),t[d>>2]=t[e>>2],t[e>>2]=d}function s8(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0,we=0,le=0,ie=0,Pe=0,ke=0,qe=0;if(qe=h,h=h+32|0,le=qe+20|0,ie=qe+8|0,Pe=qe+4|0,ke=qe,n=t[n>>2]|0,n|0){we=le+4|0,y=le+8|0,k=ie+4|0,T=ie+8|0,P=ie+8|0,q=le+8|0;do{if(d=n+4|0,_=I4(d)|0,_|0){if(s=b1(_)|0,t[le>>2]=0,t[we>>2]=0,t[y>>2]=0,o=(G1(_)|0)+1|0,$O(le,o),o|0)for(;o=o+-1|0,os(ie,t[s>>2]|0),l=t[we>>2]|0,l>>>0<(t[q>>2]|0)>>>0?(t[l>>2]=t[ie>>2],t[we>>2]=(t[we>>2]|0)+4):P4(le,ie),o;)s=s+4|0;o=V1(_)|0,t[ie>>2]=0,t[k>>2]=0,t[T>>2]=0;e:do if(t[o>>2]|0)for(s=0,l=0;;){if((s|0)==(l|0)?KO(ie,o):(t[s>>2]=t[o>>2],t[k>>2]=(t[k>>2]|0)+4),o=o+4|0,!(t[o>>2]|0))break e;s=t[k>>2]|0,l=t[P>>2]|0}while(0);t[Pe>>2]=nh(d)|0,t[ke>>2]=Dn(_)|0,XO(r,e,Pe,ke,le,ie),M4(ie),Rl(le)}n=t[n>>2]|0}while((n|0)!=0)}h=qe}function I4(e){return e=e|0,t[e+12>>2]|0}function b1(e){return e=e|0,t[e+12>>2]|0}function G1(e){return e=e|0,t[e+16>>2]|0}function $O(e,n){e=e|0,n=n|0;var r=0,o=0,s=0;s=h,h=h+32|0,r=s,o=t[e>>2]|0,(t[e+8>>2]|0)-o>>2>>>0>>0&&(m8(r,n,(t[e+4>>2]|0)-o>>2,e+8|0),v8(e,r),g8(r)),h=s}function P4(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0;if(d=h,h=h+32|0,r=d,o=e+4|0,s=((t[o>>2]|0)-(t[e>>2]|0)>>2)+1|0,l=h8(e)|0,l>>>0>>0)$n(e);else{_=t[e>>2]|0,k=(t[e+8>>2]|0)-_|0,y=k>>1,m8(r,k>>2>>>0>>1>>>0?y>>>0>>0?s:y:l,(t[o>>2]|0)-_>>2,e+8|0),l=r+8|0,t[t[l>>2]>>2]=t[n>>2],t[l>>2]=(t[l>>2]|0)+4,v8(e,r),g8(r),h=d;return}}function V1(e){return e=e|0,t[e+8>>2]|0}function KO(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0;if(d=h,h=h+32|0,r=d,o=e+4|0,s=((t[o>>2]|0)-(t[e>>2]|0)>>2)+1|0,l=p8(e)|0,l>>>0>>0)$n(e);else{_=t[e>>2]|0,k=(t[e+8>>2]|0)-_|0,y=k>>1,mI(r,k>>2>>>0>>1>>>0?y>>>0>>0?s:y:l,(t[o>>2]|0)-_>>2,e+8|0),l=r+8|0,t[t[l>>2]>>2]=t[n>>2],t[l>>2]=(t[l>>2]|0)+4,vI(e,r),gI(r),h=d;return}}function nh(e){return e=e|0,t[e>>2]|0}function XO(e,n,r,o,s,l){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0,JO(e,n,r,o,s,l)}function M4(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-4-o|0)>>>2)<<2)),Ve(r))}function Rl(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-4-o|0)>>>2)<<2)),Ve(r))}function JO(e,n,r,o,s,l){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0;var d=0,_=0,y=0,k=0,T=0,P=0;d=h,h=h+48|0,T=d+40|0,_=d+32|0,P=d+24|0,y=d+12|0,k=d,Zo(_),e=Oi(e)|0,t[P>>2]=t[n>>2],r=t[r>>2]|0,o=t[o>>2]|0,F4(y,s),QO(k,l),t[T>>2]=t[P>>2],ZO(e,T,r,o,y,k),M4(k),Rl(y),eu(_),h=d}function F4(e,n){e=e|0,n=n|0;var r=0,o=0;t[e>>2]=0,t[e+4>>2]=0,t[e+8>>2]=0,r=n+4|0,o=(t[r>>2]|0)-(t[n>>2]|0)>>2,o|0&&(pI(e,o),hI(e,t[n>>2]|0,t[r>>2]|0,o))}function QO(e,n){e=e|0,n=n|0;var r=0,o=0;t[e>>2]=0,t[e+4>>2]=0,t[e+8>>2]=0,r=n+4|0,o=(t[r>>2]|0)-(t[n>>2]|0)>>2,o|0&&(aI(e,o),dI(e,t[n>>2]|0,t[r>>2]|0,o))}function ZO(e,n,r,o,s,l){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0;var d=0,_=0,y=0,k=0,T=0,P=0;d=h,h=h+32|0,T=d+28|0,P=d+24|0,_=d+12|0,y=d,k=ko(eI()|0)|0,t[P>>2]=t[n>>2],t[T>>2]=t[P>>2],n=lc(T)|0,r=l8(r)|0,o=L4(o)|0,t[_>>2]=t[s>>2],T=s+4|0,t[_+4>>2]=t[T>>2],P=s+8|0,t[_+8>>2]=t[P>>2],t[P>>2]=0,t[T>>2]=0,t[s>>2]=0,s=R4(_)|0,t[y>>2]=t[l>>2],T=l+4|0,t[y+4>>2]=t[T>>2],P=l+8|0,t[y+8>>2]=t[P>>2],t[P>>2]=0,t[T>>2]=0,t[l>>2]=0,qo(0,k|0,e|0,n|0,r|0,o|0,s|0,tI(y)|0)|0,M4(y),Rl(_),h=d}function eI(){var e=0;return c[7968]|0||(fI(10708),e=7968,t[e>>2]=1,t[e+4>>2]=0),10708}function lc(e){return e=e|0,c8(e)|0}function l8(e){return e=e|0,f8(e)|0}function L4(e){return e=e|0,ea(e)|0}function R4(e){return e=e|0,rI(e)|0}function tI(e){return e=e|0,nI(e)|0}function nI(e){e=e|0;var n=0,r=0,o=0;if(o=(t[e+4>>2]|0)-(t[e>>2]|0)|0,r=o>>2,o=Qo(o+4|0)|0,t[o>>2]=r,r|0){n=0;do t[o+4+(n<<2)>>2]=f8(t[(t[e>>2]|0)+(n<<2)>>2]|0)|0,n=n+1|0;while((n|0)!=(r|0))}return o|0}function f8(e){return e=e|0,e|0}function rI(e){e=e|0;var n=0,r=0,o=0;if(o=(t[e+4>>2]|0)-(t[e>>2]|0)|0,r=o>>2,o=Qo(o+4|0)|0,t[o>>2]=r,r|0){n=0;do t[o+4+(n<<2)>>2]=c8((t[e>>2]|0)+(n<<2)|0)|0,n=n+1|0;while((n|0)!=(r|0))}return o|0}function c8(e){e=e|0;var n=0,r=0,o=0,s=0;return s=h,h=h+32|0,n=s+12|0,r=s,o=U0(a8()|0)|0,o?(s1(n,o),l1(r,n),UF(e,r),e=f1(n)|0):e=iI(e)|0,h=s,e|0}function a8(){var e=0;return c[7960]|0||(lI(10664),Bt(25,10664,Q|0)|0,e=7960,t[e>>2]=1,t[e+4>>2]=0),10664}function iI(e){e=e|0;var n=0,r=0,o=0,s=0,l=0,d=0,_=0;return r=h,h=h+16|0,s=r+4|0,d=r,o=Qo(8)|0,n=o,_=Tt(4)|0,t[_>>2]=t[e>>2],l=n+4|0,t[l>>2]=_,e=Tt(8)|0,l=t[l>>2]|0,t[d>>2]=0,t[s>>2]=t[d>>2],d8(e,l,s),t[o>>2]=e,h=r,n|0}function d8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,r=Tt(16)|0,t[r+4>>2]=0,t[r+8>>2]=0,t[r>>2]=1656,t[r+12>>2]=n,t[e+4>>2]=r}function oI(e){e=e|0,da(e),Ve(e)}function uI(e){e=e|0,e=t[e+12>>2]|0,e|0&&Ve(e)}function sI(e){e=e|0,Ve(e)}function lI(e){e=e|0,Ys(e)}function fI(e){e=e|0,Ao(e,cI()|0,5)}function cI(){return 1676}function aI(e,n){e=e|0,n=n|0;var r=0;if((p8(e)|0)>>>0>>0&&$n(e),n>>>0>1073741823)_n();else{r=Tt(n<<2)|0,t[e+4>>2]=r,t[e>>2]=r,t[e+8>>2]=r+(n<<2);return}}function dI(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0,o=e+4|0,e=r-n|0,(e|0)>0&&(vn(t[o>>2]|0,n|0,e|0)|0,t[o>>2]=(t[o>>2]|0)+(e>>>2<<2))}function p8(e){return e=e|0,1073741823}function pI(e,n){e=e|0,n=n|0;var r=0;if((h8(e)|0)>>>0>>0&&$n(e),n>>>0>1073741823)_n();else{r=Tt(n<<2)|0,t[e+4>>2]=r,t[e>>2]=r,t[e+8>>2]=r+(n<<2);return}}function hI(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0,o=e+4|0,e=r-n|0,(e|0)>0&&(vn(t[o>>2]|0,n|0,e|0)|0,t[o>>2]=(t[o>>2]|0)+(e>>>2<<2))}function h8(e){return e=e|0,1073741823}function mI(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>1073741823)_n();else{s=Tt(n<<2)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r<<2)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n<<2)}function vI(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(0-(s>>2)<<2)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function gI(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~((o+-4-n|0)>>>2)<<2)),e=t[e>>2]|0,e|0&&Ve(e)}function m8(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>1073741823)_n();else{s=Tt(n<<2)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r<<2)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n<<2)}function v8(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(0-(s>>2)<<2)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function g8(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~((o+-4-n|0)>>>2)<<2)),e=t[e>>2]|0,e|0&&Ve(e)}function _I(e,n,r,o,s){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0;var l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0,we=0,le=0,ie=0;if(ie=h,h=h+32|0,T=ie+20|0,P=ie+12|0,k=ie+16|0,q=ie+4|0,we=ie,le=ie+8|0,_=o8()|0,l=t[_>>2]|0,d=t[l>>2]|0,d|0)for(y=t[_+8>>2]|0,_=t[_+4>>2]|0;os(T,d),yI(e,T,_,y),l=l+4|0,d=t[l>>2]|0,d;)y=y+1|0,_=_+1|0;if(l=u8()|0,d=t[l>>2]|0,d|0)do os(T,d),t[P>>2]=t[l+4>>2],wI(n,T,P),l=l+8|0,d=t[l>>2]|0;while((d|0)!=0);if(l=t[(sa()|0)>>2]|0,l|0)do n=t[l+4>>2]|0,os(T,t[(la(n)|0)>>2]|0),t[P>>2]=A4(n)|0,DI(r,T,P),l=t[l>>2]|0;while((l|0)!=0);if(os(k,0),l=O4()|0,t[T>>2]=t[k>>2],s8(T,l,s),l=t[(sa()|0)>>2]|0,l|0){e=T+4|0,n=T+8|0,r=T+8|0;do{if(y=t[l+4>>2]|0,os(P,t[(la(y)|0)>>2]|0),EI(q,_8(y)|0),d=t[q>>2]|0,d|0){t[T>>2]=0,t[e>>2]=0,t[n>>2]=0;do os(we,t[(la(t[d+4>>2]|0)|0)>>2]|0),_=t[e>>2]|0,_>>>0<(t[r>>2]|0)>>>0?(t[_>>2]=t[we>>2],t[e>>2]=(t[e>>2]|0)+4):P4(T,we),d=t[d>>2]|0;while((d|0)!=0);SI(o,P,T),Rl(T)}t[le>>2]=t[P>>2],k=y8(y)|0,t[T>>2]=t[le>>2],s8(T,k,s),bd(q),l=t[l>>2]|0}while((l|0)!=0)}h=ie}function yI(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0,RI(e,n,r,o)}function wI(e,n,r){e=e|0,n=n|0,r=r|0,LI(e,n,r)}function la(e){return e=e|0,e|0}function DI(e,n,r){e=e|0,n=n|0,r=r|0,II(e,n,r)}function _8(e){return e=e|0,e+16|0}function EI(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0;if(l=h,h=h+16|0,s=l+8|0,r=l,t[e>>2]=0,o=t[n>>2]|0,t[s>>2]=o,t[r>>2]=e,r=OI(r)|0,o|0){if(o=Tt(12)|0,d=(w8(s)|0)+4|0,e=t[d+4>>2]|0,n=o+4|0,t[n>>2]=t[d>>2],t[n+4>>2]=e,n=t[t[s>>2]>>2]|0,t[s>>2]=n,!n)e=o;else for(n=o;e=Tt(12)|0,y=(w8(s)|0)+4|0,_=t[y+4>>2]|0,d=e+4|0,t[d>>2]=t[y>>2],t[d+4>>2]=_,t[n>>2]=e,d=t[t[s>>2]>>2]|0,t[s>>2]=d,d;)n=e;t[e>>2]=t[r>>2],t[r>>2]=o}h=l}function SI(e,n,r){e=e|0,n=n|0,r=r|0,CI(e,n,r)}function y8(e){return e=e|0,e+24|0}function CI(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+32|0,d=o+24|0,s=o+16|0,_=o+12|0,l=o,Zo(s),e=Oi(e)|0,t[_>>2]=t[n>>2],F4(l,r),t[d>>2]=t[_>>2],TI(e,d,l),Rl(l),eu(s),h=o}function TI(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=h,h=h+32|0,d=o+16|0,_=o+12|0,s=o,l=ko(xI()|0)|0,t[_>>2]=t[n>>2],t[d>>2]=t[_>>2],n=lc(d)|0,t[s>>2]=t[r>>2],d=r+4|0,t[s+4>>2]=t[d>>2],_=r+8|0,t[s+8>>2]=t[_>>2],t[_>>2]=0,t[d>>2]=0,t[r>>2]=0,Ts(0,l|0,e|0,n|0,R4(s)|0)|0,Rl(s),h=o}function xI(){var e=0;return c[7976]|0||(kI(10720),e=7976,t[e>>2]=1,t[e+4>>2]=0),10720}function kI(e){e=e|0,Ao(e,AI()|0,2)}function AI(){return 1732}function OI(e){return e=e|0,t[e>>2]|0}function w8(e){return e=e|0,t[e>>2]|0}function II(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;o=h,h=h+32|0,l=o+16|0,s=o+8|0,d=o,Zo(s),e=Oi(e)|0,t[d>>2]=t[n>>2],r=t[r>>2]|0,t[l>>2]=t[d>>2],D8(e,l,r),eu(s),h=o}function D8(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;o=h,h=h+16|0,l=o+4|0,d=o,s=ko(PI()|0)|0,t[d>>2]=t[n>>2],t[l>>2]=t[d>>2],n=lc(l)|0,Ts(0,s|0,e|0,n|0,l8(r)|0)|0,h=o}function PI(){var e=0;return c[7984]|0||(MI(10732),e=7984,t[e>>2]=1,t[e+4>>2]=0),10732}function MI(e){e=e|0,Ao(e,FI()|0,2)}function FI(){return 1744}function LI(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;o=h,h=h+32|0,l=o+16|0,s=o+8|0,d=o,Zo(s),e=Oi(e)|0,t[d>>2]=t[n>>2],r=t[r>>2]|0,t[l>>2]=t[d>>2],D8(e,l,r),eu(s),h=o}function RI(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0;s=h,h=h+32|0,d=s+16|0,l=s+8|0,_=s,Zo(l),e=Oi(e)|0,t[_>>2]=t[n>>2],r=c[r>>0]|0,o=c[o>>0]|0,t[d>>2]=t[_>>2],NI(e,d,r,o),eu(l),h=s}function NI(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0;s=h,h=h+16|0,d=s+4|0,_=s,l=ko(BI()|0)|0,t[_>>2]=t[n>>2],t[d>>2]=t[_>>2],n=lc(d)|0,r=fa(r)|0,Bu(0,l|0,e|0,n|0,r|0,fa(o)|0)|0,h=s}function BI(){var e=0;return c[7992]|0||(UI(10744),e=7992,t[e>>2]=1,t[e+4>>2]=0),10744}function fa(e){return e=e|0,jI(e)|0}function jI(e){return e=e|0,e&255|0}function UI(e){e=e|0,Ao(e,qI()|0,3)}function qI(){return 1756}function zI(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;switch(q=h,h=h+32|0,_=q+8|0,y=q+4|0,k=q+20|0,T=q,_1(e,0),o=jF(n)|0,t[_>>2]=0,P=_+4|0,t[P>>2]=0,t[_+8>>2]=0,o<<24>>24){case 0:{c[k>>0]=0,WI(y,r,k),rh(e,y)|0,ei(y);break}case 8:{P=z4(n)|0,c[k>>0]=8,os(T,t[P+4>>2]|0),HI(y,r,k,T,P+8|0),rh(e,y)|0,ei(y);break}case 9:{if(l=z4(n)|0,n=t[l+4>>2]|0,n|0)for(d=_+8|0,s=l+12|0;n=n+-1|0,os(y,t[s>>2]|0),o=t[P>>2]|0,o>>>0<(t[d>>2]|0)>>>0?(t[o>>2]=t[y>>2],t[P>>2]=(t[P>>2]|0)+4):P4(_,y),n;)s=s+4|0;c[k>>0]=9,os(T,t[l+8>>2]|0),bI(y,r,k,T,_),rh(e,y)|0,ei(y);break}default:P=z4(n)|0,c[k>>0]=o,os(T,t[P+4>>2]|0),GI(y,r,k,T),rh(e,y)|0,ei(y)}Rl(_),h=q}function WI(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0;o=h,h=h+16|0,s=o,Zo(s),n=Oi(n)|0,iP(e,n,c[r>>0]|0),eu(s),h=o}function rh(e,n){e=e|0,n=n|0;var r=0;return r=t[e>>2]|0,r|0&&ju(r|0),t[e>>2]=t[n>>2],t[n>>2]=0,e|0}function HI(e,n,r,o,s){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0;var l=0,d=0,_=0,y=0;l=h,h=h+32|0,_=l+16|0,d=l+8|0,y=l,Zo(d),n=Oi(n)|0,r=c[r>>0]|0,t[y>>2]=t[o>>2],s=t[s>>2]|0,t[_>>2]=t[y>>2],eP(e,n,r,_,s),eu(d),h=l}function bI(e,n,r,o,s){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0;var l=0,d=0,_=0,y=0,k=0;l=h,h=h+32|0,y=l+24|0,d=l+16|0,k=l+12|0,_=l,Zo(d),n=Oi(n)|0,r=c[r>>0]|0,t[k>>2]=t[o>>2],F4(_,s),t[y>>2]=t[k>>2],XI(e,n,r,y,_),Rl(_),eu(d),h=l}function GI(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0;s=h,h=h+32|0,d=s+16|0,l=s+8|0,_=s,Zo(l),n=Oi(n)|0,r=c[r>>0]|0,t[_>>2]=t[o>>2],t[d>>2]=t[_>>2],VI(e,n,r,d),eu(l),h=s}function VI(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0,d=0,_=0;s=h,h=h+16|0,l=s+4|0,_=s,d=ko(YI()|0)|0,r=fa(r)|0,t[_>>2]=t[o>>2],t[l>>2]=t[_>>2],ih(e,Ts(0,d|0,n|0,r|0,lc(l)|0)|0),h=s}function YI(){var e=0;return c[8e3]|0||($I(10756),e=8e3,t[e>>2]=1,t[e+4>>2]=0),10756}function ih(e,n){e=e|0,n=n|0,_1(e,n)}function $I(e){e=e|0,Ao(e,KI()|0,2)}function KI(){return 1772}function XI(e,n,r,o,s){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0;var l=0,d=0,_=0,y=0,k=0;l=h,h=h+32|0,y=l+16|0,k=l+12|0,d=l,_=ko(JI()|0)|0,r=fa(r)|0,t[k>>2]=t[o>>2],t[y>>2]=t[k>>2],o=lc(y)|0,t[d>>2]=t[s>>2],y=s+4|0,t[d+4>>2]=t[y>>2],k=s+8|0,t[d+8>>2]=t[k>>2],t[k>>2]=0,t[y>>2]=0,t[s>>2]=0,ih(e,Bu(0,_|0,n|0,r|0,o|0,R4(d)|0)|0),Rl(d),h=l}function JI(){var e=0;return c[8008]|0||(QI(10768),e=8008,t[e>>2]=1,t[e+4>>2]=0),10768}function QI(e){e=e|0,Ao(e,ZI()|0,3)}function ZI(){return 1784}function eP(e,n,r,o,s){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0;var l=0,d=0,_=0,y=0;l=h,h=h+16|0,_=l+4|0,y=l,d=ko(tP()|0)|0,r=fa(r)|0,t[y>>2]=t[o>>2],t[_>>2]=t[y>>2],o=lc(_)|0,ih(e,Bu(0,d|0,n|0,r|0,o|0,L4(s)|0)|0),h=l}function tP(){var e=0;return c[8016]|0||(nP(10780),e=8016,t[e>>2]=1,t[e+4>>2]=0),10780}function nP(e){e=e|0,Ao(e,rP()|0,3)}function rP(){return 1800}function iP(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;o=ko(oP()|0)|0,ih(e,sf(0,o|0,n|0,fa(r)|0)|0)}function oP(){var e=0;return c[8024]|0||(uP(10792),e=8024,t[e>>2]=1,t[e+4>>2]=0),10792}function uP(e){e=e|0,Ao(e,sP()|0,1)}function sP(){return 1816}function lP(){fP(),cP(),aP()}function fP(){t[2702]=K8(65536)|0}function cP(){PP(10856)}function aP(){dP(10816)}function dP(e){e=e|0,pP(e,5044),hP(e)|0}function pP(e,n){e=e|0,n=n|0;var r=0;r=a8()|0,t[e>>2]=r,TP(r,n),Cf(t[e>>2]|0)}function hP(e){e=e|0;var n=0;return n=t[e>>2]|0,uc(n,mP()|0),e|0}function mP(){var e=0;return c[8032]|0||(E8(10820),Bt(64,10820,Q|0)|0,e=8032,t[e>>2]=1,t[e+4>>2]=0),Dn(10820)|0||E8(10820),10820}function E8(e){e=e|0,_P(e),sc(e,25)}function vP(e){e=e|0,gP(e+24|0)}function gP(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function _P(e){e=e|0;var n=0;n=An()|0,Nn(e,5,18,n,EP()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function yP(e,n){e=e|0,n=n|0,wP(e,n)}function wP(e,n){e=e|0,n=n|0;var r=0,o=0,s=0;r=h,h=h+16|0,o=r,s=r+4|0,Ml(s,n),t[o>>2]=Fl(s,n)|0,DP(e,o),h=r}function DP(e,n){e=e|0,n=n|0,S8(e+4|0,t[n>>2]|0),c[e+8>>0]=1}function S8(e,n){e=e|0,n=n|0,t[e>>2]=n}function EP(){return 1824}function SP(e){return e=e|0,CP(e)|0}function CP(e){e=e|0;var n=0,r=0,o=0,s=0,l=0,d=0,_=0;return r=h,h=h+16|0,s=r+4|0,d=r,o=Qo(8)|0,n=o,_=Tt(4)|0,Ml(s,e),S8(_,Fl(s,e)|0),l=n+4|0,t[l>>2]=_,e=Tt(8)|0,l=t[l>>2]|0,t[d>>2]=0,t[s>>2]=t[d>>2],d8(e,l,s),t[o>>2]=e,h=r,n|0}function Qo(e){e=e|0;var n=0,r=0;return e=e+7&-8,(e>>>0<=32768?(n=t[2701]|0,e>>>0<=(65536-n|0)>>>0):0)?(r=(t[2702]|0)+n|0,t[2701]=n+e,e=r):(e=K8(e+8|0)|0,t[e>>2]=t[2703],t[2703]=e,e=e+8|0),e|0}function TP(e,n){e=e|0,n=n|0,t[e>>2]=xP()|0,t[e+4>>2]=kP()|0,t[e+12>>2]=n,t[e+8>>2]=AP()|0,t[e+32>>2]=9}function xP(){return 11744}function kP(){return 1832}function AP(){return th()|0}function OP(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0,(Sf(o,896)|0)==512?r|0&&(IP(r),Ve(r)):n|0&&Ve(n)}function IP(e){e=e|0,e=t[e+4>>2]|0,e|0&&Tf(e)}function PP(e){e=e|0,MP(e,5052),FP(e)|0,LP(e,5058,26)|0,RP(e,5069,1)|0,NP(e,5077,10)|0,BP(e,5087,19)|0,jP(e,5094,27)|0}function MP(e,n){e=e|0,n=n|0;var r=0;r=IF()|0,t[e>>2]=r,PF(r,n),Cf(t[e>>2]|0)}function FP(e){e=e|0;var n=0;return n=t[e>>2]|0,uc(n,vF()|0),e|0}function LP(e,n,r){return e=e|0,n=n|0,r=r|0,QM(e,Zn(n)|0,r,0),e|0}function RP(e,n,r){return e=e|0,n=n|0,r=r|0,BM(e,Zn(n)|0,r,0),e|0}function NP(e,n,r){return e=e|0,n=n|0,r=r|0,mM(e,Zn(n)|0,r,0),e|0}function BP(e,n,r){return e=e|0,n=n|0,r=r|0,eM(e,Zn(n)|0,r,0),e|0}function C8(e,n){e=e|0,n=n|0;var r=0,o=0;e:for(;;){for(r=t[2703]|0;;){if((r|0)==(n|0))break e;if(o=t[r>>2]|0,t[2703]=o,!r)r=o;else break}Ve(r)}t[2701]=e}function jP(e,n,r){return e=e|0,n=n|0,r=r|0,UP(e,Zn(n)|0,r,0),e|0}function UP(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0;l=t[e>>2]|0,s=N4()|0,e=qP(r)|0,ur(l,n,s,e,zP(r,o)|0,o)}function N4(){var e=0,n=0;if(c[8040]|0||(x8(10860),Bt(65,10860,Q|0)|0,n=8040,t[n>>2]=1,t[n+4>>2]=0),!(Dn(10860)|0)){e=10860,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));x8(10860)}return 10860}function qP(e){return e=e|0,e|0}function zP(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0;return _=h,h=h+16|0,s=_,l=_+4|0,t[s>>2]=e,y=N4()|0,d=y+24|0,n=Lt(n,4)|0,t[l>>2]=n,r=y+28|0,o=t[r>>2]|0,o>>>0<(t[y+32>>2]|0)>>>0?(T8(o,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(WP(d,s,l),n=t[r>>2]|0),h=_,(n-(t[d>>2]|0)>>3)+-1|0}function T8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function WP(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0;if(_=h,h=h+32|0,s=_,l=e+4|0,d=((t[l>>2]|0)-(t[e>>2]|0)>>3)+1|0,o=HP(e)|0,o>>>0>>0)$n(e);else{y=t[e>>2]|0,T=(t[e+8>>2]|0)-y|0,k=T>>2,bP(s,T>>3>>>0>>1>>>0?k>>>0>>0?d:k:o,(t[l>>2]|0)-y>>3,e+8|0),d=s+8|0,T8(t[d>>2]|0,t[n>>2]|0,t[r>>2]|0),t[d>>2]=(t[d>>2]|0)+8,GP(e,s),VP(s),h=_;return}}function HP(e){return e=e|0,536870911}function bP(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>536870911)_n();else{s=Tt(n<<3)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r<<3)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n<<3)}function GP(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(0-(s>>3)<<3)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function VP(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~((o+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&Ve(e)}function x8(e){e=e|0,KP(e)}function YP(e){e=e|0,$P(e+24|0)}function $P(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function KP(e){e=e|0;var n=0;n=An()|0,Nn(e,1,11,n,XP()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function XP(){return 1840}function JP(e,n,r){e=e|0,n=n|0,r=r|0,ZP(t[(QP(e)|0)>>2]|0,n,r)}function QP(e){return e=e|0,(t[(N4()|0)+24>>2]|0)+(e<<3)|0}function ZP(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0;o=h,h=h+16|0,l=o+1|0,s=o,Ml(l,n),n=Fl(l,n)|0,Ml(s,r),r=Fl(s,r)|0,Bl[e&31](n,r),h=o}function eM(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0;l=t[e>>2]|0,s=B4()|0,e=tM(r)|0,ur(l,n,s,e,nM(r,o)|0,o)}function B4(){var e=0,n=0;if(c[8048]|0||(A8(10896),Bt(66,10896,Q|0)|0,n=8048,t[n>>2]=1,t[n+4>>2]=0),!(Dn(10896)|0)){e=10896,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));A8(10896)}return 10896}function tM(e){return e=e|0,e|0}function nM(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0;return _=h,h=h+16|0,s=_,l=_+4|0,t[s>>2]=e,y=B4()|0,d=y+24|0,n=Lt(n,4)|0,t[l>>2]=n,r=y+28|0,o=t[r>>2]|0,o>>>0<(t[y+32>>2]|0)>>>0?(k8(o,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(rM(d,s,l),n=t[r>>2]|0),h=_,(n-(t[d>>2]|0)>>3)+-1|0}function k8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function rM(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0;if(_=h,h=h+32|0,s=_,l=e+4|0,d=((t[l>>2]|0)-(t[e>>2]|0)>>3)+1|0,o=iM(e)|0,o>>>0>>0)$n(e);else{y=t[e>>2]|0,T=(t[e+8>>2]|0)-y|0,k=T>>2,oM(s,T>>3>>>0>>1>>>0?k>>>0>>0?d:k:o,(t[l>>2]|0)-y>>3,e+8|0),d=s+8|0,k8(t[d>>2]|0,t[n>>2]|0,t[r>>2]|0),t[d>>2]=(t[d>>2]|0)+8,uM(e,s),sM(s),h=_;return}}function iM(e){return e=e|0,536870911}function oM(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>536870911)_n();else{s=Tt(n<<3)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r<<3)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n<<3)}function uM(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(0-(s>>3)<<3)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function sM(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~((o+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&Ve(e)}function A8(e){e=e|0,cM(e)}function lM(e){e=e|0,fM(e+24|0)}function fM(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function cM(e){e=e|0;var n=0;n=An()|0,Nn(e,1,11,n,aM()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function aM(){return 1852}function dM(e,n){return e=e|0,n=n|0,hM(t[(pM(e)|0)>>2]|0,n)|0}function pM(e){return e=e|0,(t[(B4()|0)+24>>2]|0)+(e<<3)|0}function hM(e,n){e=e|0,n=n|0;var r=0,o=0;return r=h,h=h+16|0,o=r,Ml(o,n),n=Fl(o,n)|0,n=ea(dc[e&31](n)|0)|0,h=r,n|0}function mM(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0;l=t[e>>2]|0,s=j4()|0,e=vM(r)|0,ur(l,n,s,e,gM(r,o)|0,o)}function j4(){var e=0,n=0;if(c[8056]|0||(I8(10932),Bt(67,10932,Q|0)|0,n=8056,t[n>>2]=1,t[n+4>>2]=0),!(Dn(10932)|0)){e=10932,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));I8(10932)}return 10932}function vM(e){return e=e|0,e|0}function gM(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0;return _=h,h=h+16|0,s=_,l=_+4|0,t[s>>2]=e,y=j4()|0,d=y+24|0,n=Lt(n,4)|0,t[l>>2]=n,r=y+28|0,o=t[r>>2]|0,o>>>0<(t[y+32>>2]|0)>>>0?(O8(o,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(_M(d,s,l),n=t[r>>2]|0),h=_,(n-(t[d>>2]|0)>>3)+-1|0}function O8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function _M(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0;if(_=h,h=h+32|0,s=_,l=e+4|0,d=((t[l>>2]|0)-(t[e>>2]|0)>>3)+1|0,o=yM(e)|0,o>>>0>>0)$n(e);else{y=t[e>>2]|0,T=(t[e+8>>2]|0)-y|0,k=T>>2,wM(s,T>>3>>>0>>1>>>0?k>>>0>>0?d:k:o,(t[l>>2]|0)-y>>3,e+8|0),d=s+8|0,O8(t[d>>2]|0,t[n>>2]|0,t[r>>2]|0),t[d>>2]=(t[d>>2]|0)+8,DM(e,s),EM(s),h=_;return}}function yM(e){return e=e|0,536870911}function wM(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>536870911)_n();else{s=Tt(n<<3)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r<<3)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n<<3)}function DM(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(0-(s>>3)<<3)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function EM(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~((o+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&Ve(e)}function I8(e){e=e|0,TM(e)}function SM(e){e=e|0,CM(e+24|0)}function CM(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function TM(e){e=e|0;var n=0;n=An()|0,Nn(e,1,7,n,xM()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function xM(){return 1860}function kM(e,n,r){return e=e|0,n=n|0,r=r|0,OM(t[(AM(e)|0)>>2]|0,n,r)|0}function AM(e){return e=e|0,(t[(j4()|0)+24>>2]|0)+(e<<3)|0}function OM(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0;return o=h,h=h+32|0,d=o+12|0,l=o+8|0,_=o,y=o+16|0,s=o+4|0,IM(y,n),PM(_,y,n),$s(s,r),r=Ks(s,r)|0,t[d>>2]=t[_>>2],X1[e&15](l,d,r),r=MM(l)|0,ei(l),Xs(s),h=o,r|0}function IM(e,n){e=e|0,n=n|0}function PM(e,n,r){e=e|0,n=n|0,r=r|0,FM(e,r)}function MM(e){return e=e|0,Oi(e)|0}function FM(e,n){e=e|0,n=n|0;var r=0,o=0,s=0;s=h,h=h+16|0,r=s,o=n,o&1?(LM(r,0),c0(o|0,r|0)|0,RM(e,r),NM(r)):t[e>>2]=t[n>>2],h=s}function LM(e,n){e=e|0,n=n|0,wd(e,n),t[e+4>>2]=0,c[e+8>>0]=0}function RM(e,n){e=e|0,n=n|0,t[e>>2]=t[n+4>>2]}function NM(e){e=e|0,c[e+8>>0]=0}function BM(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0;l=t[e>>2]|0,s=U4()|0,e=jM(r)|0,ur(l,n,s,e,UM(r,o)|0,o)}function U4(){var e=0,n=0;if(c[8064]|0||(M8(10968),Bt(68,10968,Q|0)|0,n=8064,t[n>>2]=1,t[n+4>>2]=0),!(Dn(10968)|0)){e=10968,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));M8(10968)}return 10968}function jM(e){return e=e|0,e|0}function UM(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0;return _=h,h=h+16|0,s=_,l=_+4|0,t[s>>2]=e,y=U4()|0,d=y+24|0,n=Lt(n,4)|0,t[l>>2]=n,r=y+28|0,o=t[r>>2]|0,o>>>0<(t[y+32>>2]|0)>>>0?(P8(o,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(qM(d,s,l),n=t[r>>2]|0),h=_,(n-(t[d>>2]|0)>>3)+-1|0}function P8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function qM(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0;if(_=h,h=h+32|0,s=_,l=e+4|0,d=((t[l>>2]|0)-(t[e>>2]|0)>>3)+1|0,o=zM(e)|0,o>>>0>>0)$n(e);else{y=t[e>>2]|0,T=(t[e+8>>2]|0)-y|0,k=T>>2,WM(s,T>>3>>>0>>1>>>0?k>>>0>>0?d:k:o,(t[l>>2]|0)-y>>3,e+8|0),d=s+8|0,P8(t[d>>2]|0,t[n>>2]|0,t[r>>2]|0),t[d>>2]=(t[d>>2]|0)+8,HM(e,s),bM(s),h=_;return}}function zM(e){return e=e|0,536870911}function WM(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>536870911)_n();else{s=Tt(n<<3)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r<<3)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n<<3)}function HM(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(0-(s>>3)<<3)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function bM(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~((o+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&Ve(e)}function M8(e){e=e|0,YM(e)}function GM(e){e=e|0,VM(e+24|0)}function VM(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function YM(e){e=e|0;var n=0;n=An()|0,Nn(e,1,1,n,$M()|0,5),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function $M(){return 1872}function KM(e,n,r,o,s,l){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0,JM(t[(XM(e)|0)>>2]|0,n,r,o,s,l)}function XM(e){return e=e|0,(t[(U4()|0)+24>>2]|0)+(e<<3)|0}function JM(e,n,r,o,s,l){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0;var d=0,_=0,y=0,k=0,T=0,P=0;d=h,h=h+32|0,_=d+16|0,y=d+12|0,k=d+8|0,T=d+4|0,P=d,$s(_,n),n=Ks(_,n)|0,$s(y,r),r=Ks(y,r)|0,$s(k,o),o=Ks(k,o)|0,$s(T,s),s=Ks(T,s)|0,$s(P,l),l=Ks(P,l)|0,eD[e&1](n,r,o,s,l),Xs(P),Xs(T),Xs(k),Xs(y),Xs(_),h=d}function QM(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0;l=t[e>>2]|0,s=q4()|0,e=ZM(r)|0,ur(l,n,s,e,eF(r,o)|0,o)}function q4(){var e=0,n=0;if(c[8072]|0||(L8(11004),Bt(69,11004,Q|0)|0,n=8072,t[n>>2]=1,t[n+4>>2]=0),!(Dn(11004)|0)){e=11004,n=e+36|0;do t[e>>2]=0,e=e+4|0;while((e|0)<(n|0));L8(11004)}return 11004}function ZM(e){return e=e|0,e|0}function eF(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0,_=0,y=0;return _=h,h=h+16|0,s=_,l=_+4|0,t[s>>2]=e,y=q4()|0,d=y+24|0,n=Lt(n,4)|0,t[l>>2]=n,r=y+28|0,o=t[r>>2]|0,o>>>0<(t[y+32>>2]|0)>>>0?(F8(o,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(tF(d,s,l),n=t[r>>2]|0),h=_,(n-(t[d>>2]|0)>>3)+-1|0}function F8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function tF(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0;if(_=h,h=h+32|0,s=_,l=e+4|0,d=((t[l>>2]|0)-(t[e>>2]|0)>>3)+1|0,o=nF(e)|0,o>>>0>>0)$n(e);else{y=t[e>>2]|0,T=(t[e+8>>2]|0)-y|0,k=T>>2,rF(s,T>>3>>>0>>1>>>0?k>>>0>>0?d:k:o,(t[l>>2]|0)-y>>3,e+8|0),d=s+8|0,F8(t[d>>2]|0,t[n>>2]|0,t[r>>2]|0),t[d>>2]=(t[d>>2]|0)+8,iF(e,s),oF(s),h=_;return}}function nF(e){return e=e|0,536870911}function rF(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0;t[e+12>>2]=0,t[e+16>>2]=o;do if(n)if(n>>>0>536870911)_n();else{s=Tt(n<<3)|0;break}else s=0;while(0);t[e>>2]=s,o=s+(r<<3)|0,t[e+8>>2]=o,t[e+4>>2]=o,t[e+12>>2]=s+(n<<3)}function iF(e,n){e=e|0,n=n|0;var r=0,o=0,s=0,l=0,d=0;o=t[e>>2]|0,d=e+4|0,l=n+4|0,s=(t[d>>2]|0)-o|0,r=(t[l>>2]|0)+(0-(s>>3)<<3)|0,t[l>>2]=r,(s|0)>0?(vn(r|0,o|0,s|0)|0,o=l,r=t[l>>2]|0):o=l,l=t[e>>2]|0,t[e>>2]=r,t[o>>2]=l,l=n+8|0,s=t[d>>2]|0,t[d>>2]=t[l>>2],t[l>>2]=s,l=e+8|0,d=n+12|0,e=t[l>>2]|0,t[l>>2]=t[d>>2],t[d>>2]=e,t[n>>2]=t[o>>2]}function oF(e){e=e|0;var n=0,r=0,o=0;n=t[e+4>>2]|0,r=e+8|0,o=t[r>>2]|0,(o|0)!=(n|0)&&(t[r>>2]=o+(~((o+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&Ve(e)}function L8(e){e=e|0,lF(e)}function uF(e){e=e|0,sF(e+24|0)}function sF(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function lF(e){e=e|0;var n=0;n=An()|0,Nn(e,1,12,n,fF()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function fF(){return 1896}function cF(e,n,r){e=e|0,n=n|0,r=r|0,dF(t[(aF(e)|0)>>2]|0,n,r)}function aF(e){return e=e|0,(t[(q4()|0)+24>>2]|0)+(e<<3)|0}function dF(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0;o=h,h=h+16|0,l=o+4|0,s=o,pF(l,n),n=hF(l,n)|0,$s(s,r),r=Ks(s,r)|0,Bl[e&31](n,r),Xs(s),h=o}function pF(e,n){e=e|0,n=n|0}function hF(e,n){return e=e|0,n=n|0,mF(n)|0}function mF(e){return e=e|0,e|0}function vF(){var e=0;return c[8080]|0||(R8(11040),Bt(70,11040,Q|0)|0,e=8080,t[e>>2]=1,t[e+4>>2]=0),Dn(11040)|0||R8(11040),11040}function R8(e){e=e|0,yF(e),sc(e,71)}function gF(e){e=e|0,_F(e+24|0)}function _F(e){e=e|0;var n=0,r=0,o=0;r=t[e>>2]|0,o=r,r|0&&(e=e+4|0,n=t[e>>2]|0,(n|0)!=(r|0)&&(t[e>>2]=n+(~((n+-8-o|0)>>>3)<<3)),Ve(r))}function yF(e){e=e|0;var n=0;n=An()|0,Nn(e,5,7,n,SF()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function wF(e){e=e|0,DF(e)}function DF(e){e=e|0,EF(e)}function EF(e){e=e|0,c[e+8>>0]=1}function SF(){return 1936}function CF(){return TF()|0}function TF(){var e=0,n=0,r=0,o=0,s=0,l=0,d=0;return n=h,h=h+16|0,s=n+4|0,d=n,r=Qo(8)|0,e=r,l=e+4|0,t[l>>2]=Tt(1)|0,o=Tt(8)|0,l=t[l>>2]|0,t[d>>2]=0,t[s>>2]=t[d>>2],xF(o,l,s),t[r>>2]=o,h=n,e|0}function xF(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,r=Tt(16)|0,t[r+4>>2]=0,t[r+8>>2]=0,t[r>>2]=1916,t[r+12>>2]=n,t[e+4>>2]=r}function kF(e){e=e|0,da(e),Ve(e)}function AF(e){e=e|0,e=t[e+12>>2]|0,e|0&&Ve(e)}function OF(e){e=e|0,Ve(e)}function IF(){var e=0;return c[8088]|0||(BF(11076),Bt(25,11076,Q|0)|0,e=8088,t[e>>2]=1,t[e+4>>2]=0),11076}function PF(e,n){e=e|0,n=n|0,t[e>>2]=MF()|0,t[e+4>>2]=FF()|0,t[e+12>>2]=n,t[e+8>>2]=LF()|0,t[e+32>>2]=10}function MF(){return 11745}function FF(){return 1940}function LF(){return eh()|0}function RF(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0,(Sf(o,896)|0)==512?r|0&&(NF(r),Ve(r)):n|0&&Ve(n)}function NF(e){e=e|0,e=t[e+4>>2]|0,e|0&&Tf(e)}function BF(e){e=e|0,Ys(e)}function os(e,n){e=e|0,n=n|0,t[e>>2]=n}function z4(e){return e=e|0,t[e>>2]|0}function jF(e){return e=e|0,c[t[e>>2]>>0]|0}function UF(e,n){e=e|0,n=n|0;var r=0,o=0;r=h,h=h+16|0,o=r,t[o>>2]=t[e>>2],qF(n,o)|0,h=r}function qF(e,n){e=e|0,n=n|0;var r=0;return r=zF(t[e>>2]|0,n)|0,n=e+4|0,t[(t[n>>2]|0)+8>>2]=r,t[(t[n>>2]|0)+8>>2]|0}function zF(e,n){e=e|0,n=n|0;var r=0,o=0;return r=h,h=h+16|0,o=r,Zo(o),e=Oi(e)|0,n=WF(e,t[n>>2]|0)|0,eu(o),h=r,n|0}function Zo(e){e=e|0,t[e>>2]=t[2701],t[e+4>>2]=t[2703]}function WF(e,n){e=e|0,n=n|0;var r=0;return r=ko(HF()|0)|0,sf(0,r|0,e|0,L4(n)|0)|0}function eu(e){e=e|0,C8(t[e>>2]|0,t[e+4>>2]|0)}function HF(){var e=0;return c[8096]|0||(bF(11120),e=8096,t[e>>2]=1,t[e+4>>2]=0),11120}function bF(e){e=e|0,Ao(e,GF()|0,1)}function GF(){return 1948}function VF(){YF()}function YF(){var e=0,n=0,r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0,we=0,le=0,ie=0;if(le=h,h=h+16|0,T=le+4|0,P=le,si(65536,10804,t[2702]|0,10812),r=o8()|0,n=t[r>>2]|0,e=t[n>>2]|0,e|0)for(o=t[r+8>>2]|0,r=t[r+4>>2]|0;As(e|0,C[r>>0]|0|0,c[o>>0]|0),n=n+4|0,e=t[n>>2]|0,e;)o=o+1|0,r=r+1|0;if(e=u8()|0,n=t[e>>2]|0,n|0)do uu(n|0,t[e+4>>2]|0),e=e+8|0,n=t[e>>2]|0;while((n|0)!=0);uu($F()|0,5167),k=sa()|0,e=t[k>>2]|0;e:do if(e|0){do KF(t[e+4>>2]|0),e=t[e>>2]|0;while((e|0)!=0);if(e=t[k>>2]|0,e|0){y=k;do{for(;s=e,e=t[e>>2]|0,s=t[s+4>>2]|0,!!(XF(s)|0);)if(t[P>>2]=y,t[T>>2]=t[P>>2],JF(k,T)|0,!e)break e;if(QF(s),y=t[y>>2]|0,n=N8(s)|0,l=Wo()|0,d=h,h=h+((1*(n<<2)|0)+15&-16)|0,_=h,h=h+((1*(n<<2)|0)+15&-16)|0,n=t[(_8(s)|0)>>2]|0,n|0)for(r=d,o=_;t[r>>2]=t[(la(t[n+4>>2]|0)|0)>>2],t[o>>2]=t[n+8>>2],n=t[n>>2]|0,n;)r=r+4|0,o=o+4|0;ie=la(s)|0,n=ZF(s)|0,r=N8(s)|0,o=eL(s)|0,Is(ie|0,n|0,d|0,_|0,r|0,o|0,A4(s)|0),b0(l|0)}while((e|0)!=0)}}while(0);if(e=t[(O4()|0)>>2]|0,e|0)do ie=e+4|0,k=I4(ie)|0,s=V1(k)|0,l=b1(k)|0,d=(G1(k)|0)+1|0,_=oh(k)|0,y=B8(ie)|0,k=Dn(k)|0,T=nh(ie)|0,P=W4(ie)|0,zo(0,s|0,l|0,d|0,_|0,y|0,k|0,T|0,P|0,H4(ie)|0),e=t[e>>2]|0;while((e|0)!=0);e=t[(sa()|0)>>2]|0;e:do if(e|0){t:for(;;){if(n=t[e+4>>2]|0,n|0?(q=t[(la(n)|0)>>2]|0,we=t[(y8(n)|0)>>2]|0,we|0):0){r=we;do{n=r+4|0,o=I4(n)|0;n:do if(o|0)switch(Dn(o)|0){case 0:break t;case 4:case 3:case 2:{_=V1(o)|0,y=b1(o)|0,k=(G1(o)|0)+1|0,T=oh(o)|0,P=Dn(o)|0,ie=nh(n)|0,zo(q|0,_|0,y|0,k|0,T|0,0,P|0,ie|0,W4(n)|0,H4(n)|0);break n}case 1:{d=V1(o)|0,_=b1(o)|0,y=(G1(o)|0)+1|0,k=oh(o)|0,T=B8(n)|0,P=Dn(o)|0,ie=nh(n)|0,zo(q|0,d|0,_|0,y|0,k|0,T|0,P|0,ie|0,W4(n)|0,H4(n)|0);break n}case 5:{k=V1(o)|0,T=b1(o)|0,P=(G1(o)|0)+1|0,ie=oh(o)|0,zo(q|0,k|0,T|0,P|0,ie|0,tL(o)|0,Dn(o)|0,0,0,0);break n}default:break n}while(0);r=t[r>>2]|0}while((r|0)!=0)}if(e=t[e>>2]|0,!e)break e}_n()}while(0);uf(),h=le}function $F(){return 11703}function KF(e){e=e|0,c[e+40>>0]=0}function XF(e){return e=e|0,(c[e+40>>0]|0)!=0|0}function JF(e,n){return e=e|0,n=n|0,n=nL(n)|0,e=t[n>>2]|0,t[n>>2]=t[e>>2],Ve(e),t[n>>2]|0}function QF(e){e=e|0,c[e+40>>0]=1}function N8(e){return e=e|0,t[e+20>>2]|0}function ZF(e){return e=e|0,t[e+8>>2]|0}function eL(e){return e=e|0,t[e+32>>2]|0}function oh(e){return e=e|0,t[e+4>>2]|0}function B8(e){return e=e|0,t[e+4>>2]|0}function W4(e){return e=e|0,t[e+8>>2]|0}function H4(e){return e=e|0,t[e+16>>2]|0}function tL(e){return e=e|0,t[e+20>>2]|0}function nL(e){return e=e|0,t[e>>2]|0}function uh(e){e=e|0;var n=0,r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0,we=0,le=0,ie=0,Pe=0,ke=0,qe=0,pe=0,_e=0,vt=0;vt=h,h=h+16|0,q=vt;do if(e>>>0<245){if(k=e>>>0<11?16:e+11&-8,e=k>>>3,P=t[2783]|0,r=P>>>e,r&3|0)return n=(r&1^1)+e|0,e=11172+(n<<1<<2)|0,r=e+8|0,o=t[r>>2]|0,s=o+8|0,l=t[s>>2]|0,(e|0)==(l|0)?t[2783]=P&~(1<>2]=e,t[r>>2]=l),_e=n<<3,t[o+4>>2]=_e|3,_e=o+_e+4|0,t[_e>>2]=t[_e>>2]|1,_e=s,h=vt,_e|0;if(T=t[2785]|0,k>>>0>T>>>0){if(r|0)return n=2<>>12&16,n=n>>>d,r=n>>>5&8,n=n>>>r,s=n>>>2&4,n=n>>>s,e=n>>>1&2,n=n>>>e,o=n>>>1&1,o=(r|d|s|e|o)+(n>>>o)|0,n=11172+(o<<1<<2)|0,e=n+8|0,s=t[e>>2]|0,d=s+8|0,r=t[d>>2]|0,(n|0)==(r|0)?(e=P&~(1<>2]=n,t[e>>2]=r,e=P),l=(o<<3)-k|0,t[s+4>>2]=k|3,o=s+k|0,t[o+4>>2]=l|1,t[o+l>>2]=l,T|0&&(s=t[2788]|0,n=T>>>3,r=11172+(n<<1<<2)|0,n=1<>2]|0):(t[2783]=e|n,n=r,e=r+8|0),t[e>>2]=s,t[n+12>>2]=s,t[s+8>>2]=n,t[s+12>>2]=r),t[2785]=l,t[2788]=o,_e=d,h=vt,_e|0;if(_=t[2784]|0,_){if(r=(_&0-_)+-1|0,d=r>>>12&16,r=r>>>d,l=r>>>5&8,r=r>>>l,y=r>>>2&4,r=r>>>y,o=r>>>1&2,r=r>>>o,e=r>>>1&1,e=t[11436+((l|d|y|o|e)+(r>>>e)<<2)>>2]|0,r=(t[e+4>>2]&-8)-k|0,o=t[e+16+(((t[e+16>>2]|0)==0&1)<<2)>>2]|0,!o)y=e,l=r;else{do d=(t[o+4>>2]&-8)-k|0,y=d>>>0>>0,r=y?d:r,e=y?o:e,o=t[o+16+(((t[o+16>>2]|0)==0&1)<<2)>>2]|0;while((o|0)!=0);y=e,l=r}if(d=y+k|0,y>>>0>>0){s=t[y+24>>2]|0,n=t[y+12>>2]|0;do if((n|0)==(y|0)){if(e=y+20|0,n=t[e>>2]|0,!n&&(e=y+16|0,n=t[e>>2]|0,!n)){r=0;break}for(;;){if(r=n+20|0,o=t[r>>2]|0,o|0){n=o,e=r;continue}if(r=n+16|0,o=t[r>>2]|0,o)n=o,e=r;else break}t[e>>2]=0,r=n}else r=t[y+8>>2]|0,t[r+12>>2]=n,t[n+8>>2]=r,r=n;while(0);do if(s|0){if(n=t[y+28>>2]|0,e=11436+(n<<2)|0,(y|0)==(t[e>>2]|0)){if(t[e>>2]=r,!r){t[2784]=_&~(1<>2]|0)!=(y|0)&1)<<2)>>2]=r,!r)break;t[r+24>>2]=s,n=t[y+16>>2]|0,n|0&&(t[r+16>>2]=n,t[n+24>>2]=r),n=t[y+20>>2]|0,n|0&&(t[r+20>>2]=n,t[n+24>>2]=r)}while(0);return l>>>0<16?(_e=l+k|0,t[y+4>>2]=_e|3,_e=y+_e+4|0,t[_e>>2]=t[_e>>2]|1):(t[y+4>>2]=k|3,t[d+4>>2]=l|1,t[d+l>>2]=l,T|0&&(o=t[2788]|0,n=T>>>3,r=11172+(n<<1<<2)|0,n=1<>2]|0):(t[2783]=P|n,n=r,e=r+8|0),t[e>>2]=o,t[n+12>>2]=o,t[o+8>>2]=n,t[o+12>>2]=r),t[2785]=l,t[2788]=d),_e=y+8|0,h=vt,_e|0}else P=k}else P=k}else P=k}else if(e>>>0<=4294967231)if(e=e+11|0,k=e&-8,y=t[2784]|0,y){o=0-k|0,e=e>>>8,e?k>>>0>16777215?_=31:(P=(e+1048320|0)>>>16&8,pe=e<>>16&4,pe=pe<>>16&2,_=14-(T|P|_)+(pe<<_>>>15)|0,_=k>>>(_+7|0)&1|_<<1):_=0,r=t[11436+(_<<2)>>2]|0;e:do if(!r)r=0,e=0,pe=57;else for(e=0,d=k<<((_|0)==31?0:25-(_>>>1)|0),l=0;;){if(s=(t[r+4>>2]&-8)-k|0,s>>>0>>0)if(s)e=r,o=s;else{e=r,o=0,s=r,pe=61;break e}if(s=t[r+20>>2]|0,r=t[r+16+(d>>>31<<2)>>2]|0,l=(s|0)==0|(s|0)==(r|0)?l:s,s=(r|0)==0,s){r=l,pe=57;break}else d=d<<((s^1)&1)}while(0);if((pe|0)==57){if((r|0)==0&(e|0)==0){if(e=2<<_,e=y&(e|0-e),!e){P=k;break}P=(e&0-e)+-1|0,d=P>>>12&16,P=P>>>d,l=P>>>5&8,P=P>>>l,_=P>>>2&4,P=P>>>_,T=P>>>1&2,P=P>>>T,r=P>>>1&1,e=0,r=t[11436+((l|d|_|T|r)+(P>>>r)<<2)>>2]|0}r?(s=r,pe=61):(_=e,d=o)}if((pe|0)==61)for(;;)if(pe=0,r=(t[s+4>>2]&-8)-k|0,P=r>>>0>>0,r=P?r:o,e=P?s:e,s=t[s+16+(((t[s+16>>2]|0)==0&1)<<2)>>2]|0,s)o=r,pe=61;else{_=e,d=r;break}if((_|0)!=0?d>>>0<((t[2785]|0)-k|0)>>>0:0){if(l=_+k|0,_>>>0>=l>>>0)return _e=0,h=vt,_e|0;s=t[_+24>>2]|0,n=t[_+12>>2]|0;do if((n|0)==(_|0)){if(e=_+20|0,n=t[e>>2]|0,!n&&(e=_+16|0,n=t[e>>2]|0,!n)){n=0;break}for(;;){if(r=n+20|0,o=t[r>>2]|0,o|0){n=o,e=r;continue}if(r=n+16|0,o=t[r>>2]|0,o)n=o,e=r;else break}t[e>>2]=0}else _e=t[_+8>>2]|0,t[_e+12>>2]=n,t[n+8>>2]=_e;while(0);do if(s){if(e=t[_+28>>2]|0,r=11436+(e<<2)|0,(_|0)==(t[r>>2]|0)){if(t[r>>2]=n,!n){o=y&~(1<>2]|0)!=(_|0)&1)<<2)>>2]=n,!n){o=y;break}t[n+24>>2]=s,e=t[_+16>>2]|0,e|0&&(t[n+16>>2]=e,t[e+24>>2]=n),e=t[_+20>>2]|0,e&&(t[n+20>>2]=e,t[e+24>>2]=n),o=y}else o=y;while(0);do if(d>>>0>=16){if(t[_+4>>2]=k|3,t[l+4>>2]=d|1,t[l+d>>2]=d,n=d>>>3,d>>>0<256){r=11172+(n<<1<<2)|0,e=t[2783]|0,n=1<>2]|0):(t[2783]=e|n,n=r,e=r+8|0),t[e>>2]=l,t[n+12>>2]=l,t[l+8>>2]=n,t[l+12>>2]=r;break}if(n=d>>>8,n?d>>>0>16777215?n=31:(pe=(n+1048320|0)>>>16&8,_e=n<>>16&4,_e=_e<>>16&2,n=14-(qe|pe|n)+(_e<>>15)|0,n=d>>>(n+7|0)&1|n<<1):n=0,r=11436+(n<<2)|0,t[l+28>>2]=n,e=l+16|0,t[e+4>>2]=0,t[e>>2]=0,e=1<>2]=l,t[l+24>>2]=r,t[l+12>>2]=l,t[l+8>>2]=l;break}for(e=d<<((n|0)==31?0:25-(n>>>1)|0),r=t[r>>2]|0;;){if((t[r+4>>2]&-8|0)==(d|0)){pe=97;break}if(o=r+16+(e>>>31<<2)|0,n=t[o>>2]|0,n)e=e<<1,r=n;else{pe=96;break}}if((pe|0)==96){t[o>>2]=l,t[l+24>>2]=r,t[l+12>>2]=l,t[l+8>>2]=l;break}else if((pe|0)==97){pe=r+8|0,_e=t[pe>>2]|0,t[_e+12>>2]=l,t[pe>>2]=l,t[l+8>>2]=_e,t[l+12>>2]=r,t[l+24>>2]=0;break}}else _e=d+k|0,t[_+4>>2]=_e|3,_e=_+_e+4|0,t[_e>>2]=t[_e>>2]|1;while(0);return _e=_+8|0,h=vt,_e|0}else P=k}else P=k;else P=-1;while(0);if(r=t[2785]|0,r>>>0>=P>>>0)return n=r-P|0,e=t[2788]|0,n>>>0>15?(_e=e+P|0,t[2788]=_e,t[2785]=n,t[_e+4>>2]=n|1,t[_e+n>>2]=n,t[e+4>>2]=P|3):(t[2785]=0,t[2788]=0,t[e+4>>2]=r|3,_e=e+r+4|0,t[_e>>2]=t[_e>>2]|1),_e=e+8|0,h=vt,_e|0;if(d=t[2786]|0,d>>>0>P>>>0)return qe=d-P|0,t[2786]=qe,_e=t[2789]|0,pe=_e+P|0,t[2789]=pe,t[pe+4>>2]=qe|1,t[_e+4>>2]=P|3,_e=_e+8|0,h=vt,_e|0;if(t[2901]|0?e=t[2903]|0:(t[2903]=4096,t[2902]=4096,t[2904]=-1,t[2905]=-1,t[2906]=0,t[2894]=0,e=q&-16^1431655768,t[q>>2]=e,t[2901]=e,e=4096),_=P+48|0,y=P+47|0,l=e+y|0,s=0-e|0,k=l&s,k>>>0<=P>>>0||(e=t[2893]|0,e|0?(T=t[2891]|0,q=T+k|0,q>>>0<=T>>>0|q>>>0>e>>>0):0))return _e=0,h=vt,_e|0;e:do if(t[2894]&4)n=0,pe=133;else{r=t[2789]|0;t:do if(r){for(o=11580;e=t[o>>2]|0,!(e>>>0<=r>>>0?(ie=o+4|0,(e+(t[ie>>2]|0)|0)>>>0>r>>>0):0);)if(e=t[o+8>>2]|0,e)o=e;else{pe=118;break t}if(n=l-d&s,n>>>0<2147483647)if(e=xf(n|0)|0,(e|0)==((t[o>>2]|0)+(t[ie>>2]|0)|0)){if((e|0)!=(-1|0)){d=n,l=e,pe=135;break e}}else o=e,pe=126;else n=0}else pe=118;while(0);do if((pe|0)==118)if(r=xf(0)|0,(r|0)!=(-1|0)?(n=r,we=t[2902]|0,le=we+-1|0,n=((le&n|0)==0?0:(le+n&0-we)-n|0)+k|0,we=t[2891]|0,le=n+we|0,n>>>0>P>>>0&n>>>0<2147483647):0){if(ie=t[2893]|0,ie|0?le>>>0<=we>>>0|le>>>0>ie>>>0:0){n=0;break}if(e=xf(n|0)|0,(e|0)==(r|0)){d=n,l=r,pe=135;break e}else o=e,pe=126}else n=0;while(0);do if((pe|0)==126){if(r=0-n|0,!(_>>>0>n>>>0&(n>>>0<2147483647&(o|0)!=(-1|0))))if((o|0)==(-1|0)){n=0;break}else{d=n,l=o,pe=135;break e}if(e=t[2903]|0,e=y-n+e&0-e,e>>>0>=2147483647){d=n,l=o,pe=135;break e}if((xf(e|0)|0)==(-1|0)){xf(r|0)|0,n=0;break}else{d=e+n|0,l=o,pe=135;break e}}while(0);t[2894]=t[2894]|4,pe=133}while(0);if((((pe|0)==133?k>>>0<2147483647:0)?(qe=xf(k|0)|0,ie=xf(0)|0,Pe=ie-qe|0,ke=Pe>>>0>(P+40|0)>>>0,!((qe|0)==(-1|0)|ke^1|qe>>>0>>0&((qe|0)!=(-1|0)&(ie|0)!=(-1|0))^1)):0)&&(d=ke?Pe:n,l=qe,pe=135),(pe|0)==135){n=(t[2891]|0)+d|0,t[2891]=n,n>>>0>(t[2892]|0)>>>0&&(t[2892]=n),y=t[2789]|0;do if(y){for(n=11580;;){if(e=t[n>>2]|0,r=n+4|0,o=t[r>>2]|0,(l|0)==(e+o|0)){pe=145;break}if(s=t[n+8>>2]|0,s)n=s;else break}if(((pe|0)==145?(t[n+12>>2]&8|0)==0:0)?y>>>0>>0&y>>>0>=e>>>0:0){t[r>>2]=o+d,_e=y+8|0,_e=(_e&7|0)==0?0:0-_e&7,pe=y+_e|0,_e=(t[2786]|0)+(d-_e)|0,t[2789]=pe,t[2786]=_e,t[pe+4>>2]=_e|1,t[pe+_e+4>>2]=40,t[2790]=t[2905];break}for(l>>>0<(t[2787]|0)>>>0&&(t[2787]=l),r=l+d|0,n=11580;;){if((t[n>>2]|0)==(r|0)){pe=153;break}if(e=t[n+8>>2]|0,e)n=e;else break}if((pe|0)==153?(t[n+12>>2]&8|0)==0:0){t[n>>2]=l,T=n+4|0,t[T>>2]=(t[T>>2]|0)+d,T=l+8|0,T=l+((T&7|0)==0?0:0-T&7)|0,n=r+8|0,n=r+((n&7|0)==0?0:0-n&7)|0,k=T+P|0,_=n-T-P|0,t[T+4>>2]=P|3;do if((n|0)!=(y|0)){if((n|0)==(t[2788]|0)){_e=(t[2785]|0)+_|0,t[2785]=_e,t[2788]=k,t[k+4>>2]=_e|1,t[k+_e>>2]=_e;break}if(e=t[n+4>>2]|0,(e&3|0)==1){d=e&-8,o=e>>>3;e:do if(e>>>0<256)if(e=t[n+8>>2]|0,r=t[n+12>>2]|0,(r|0)==(e|0)){t[2783]=t[2783]&~(1<>2]=r,t[r+8>>2]=e;break}else{l=t[n+24>>2]|0,e=t[n+12>>2]|0;do if((e|0)==(n|0)){if(o=n+16|0,r=o+4|0,e=t[r>>2]|0,!e)if(e=t[o>>2]|0,e)r=o;else{e=0;break}for(;;){if(o=e+20|0,s=t[o>>2]|0,s|0){e=s,r=o;continue}if(o=e+16|0,s=t[o>>2]|0,s)e=s,r=o;else break}t[r>>2]=0}else _e=t[n+8>>2]|0,t[_e+12>>2]=e,t[e+8>>2]=_e;while(0);if(!l)break;r=t[n+28>>2]|0,o=11436+(r<<2)|0;do if((n|0)!=(t[o>>2]|0)){if(t[l+16+(((t[l+16>>2]|0)!=(n|0)&1)<<2)>>2]=e,!e)break e}else{if(t[o>>2]=e,e|0)break;t[2784]=t[2784]&~(1<>2]=l,r=n+16|0,o=t[r>>2]|0,o|0&&(t[e+16>>2]=o,t[o+24>>2]=e),r=t[r+4>>2]|0,!r)break;t[e+20>>2]=r,t[r+24>>2]=e}while(0);n=n+d|0,s=d+_|0}else s=_;if(n=n+4|0,t[n>>2]=t[n>>2]&-2,t[k+4>>2]=s|1,t[k+s>>2]=s,n=s>>>3,s>>>0<256){r=11172+(n<<1<<2)|0,e=t[2783]|0,n=1<>2]|0):(t[2783]=e|n,n=r,e=r+8|0),t[e>>2]=k,t[n+12>>2]=k,t[k+8>>2]=n,t[k+12>>2]=r;break}n=s>>>8;do if(!n)n=0;else{if(s>>>0>16777215){n=31;break}pe=(n+1048320|0)>>>16&8,_e=n<>>16&4,_e=_e<>>16&2,n=14-(qe|pe|n)+(_e<>>15)|0,n=s>>>(n+7|0)&1|n<<1}while(0);if(o=11436+(n<<2)|0,t[k+28>>2]=n,e=k+16|0,t[e+4>>2]=0,t[e>>2]=0,e=t[2784]|0,r=1<>2]=k,t[k+24>>2]=o,t[k+12>>2]=k,t[k+8>>2]=k;break}for(e=s<<((n|0)==31?0:25-(n>>>1)|0),r=t[o>>2]|0;;){if((t[r+4>>2]&-8|0)==(s|0)){pe=194;break}if(o=r+16+(e>>>31<<2)|0,n=t[o>>2]|0,n)e=e<<1,r=n;else{pe=193;break}}if((pe|0)==193){t[o>>2]=k,t[k+24>>2]=r,t[k+12>>2]=k,t[k+8>>2]=k;break}else if((pe|0)==194){pe=r+8|0,_e=t[pe>>2]|0,t[_e+12>>2]=k,t[pe>>2]=k,t[k+8>>2]=_e,t[k+12>>2]=r,t[k+24>>2]=0;break}}else _e=(t[2786]|0)+_|0,t[2786]=_e,t[2789]=k,t[k+4>>2]=_e|1;while(0);return _e=T+8|0,h=vt,_e|0}for(n=11580;e=t[n>>2]|0,!(e>>>0<=y>>>0?(_e=e+(t[n+4>>2]|0)|0,_e>>>0>y>>>0):0);)n=t[n+8>>2]|0;s=_e+-47|0,e=s+8|0,e=s+((e&7|0)==0?0:0-e&7)|0,s=y+16|0,e=e>>>0>>0?y:e,n=e+8|0,r=l+8|0,r=(r&7|0)==0?0:0-r&7,pe=l+r|0,r=d+-40-r|0,t[2789]=pe,t[2786]=r,t[pe+4>>2]=r|1,t[pe+r+4>>2]=40,t[2790]=t[2905],r=e+4|0,t[r>>2]=27,t[n>>2]=t[2895],t[n+4>>2]=t[2896],t[n+8>>2]=t[2897],t[n+12>>2]=t[2898],t[2895]=l,t[2896]=d,t[2898]=0,t[2897]=n,n=e+24|0;do pe=n,n=n+4|0,t[n>>2]=7;while((pe+8|0)>>>0<_e>>>0);if((e|0)!=(y|0)){if(l=e-y|0,t[r>>2]=t[r>>2]&-2,t[y+4>>2]=l|1,t[e>>2]=l,n=l>>>3,l>>>0<256){r=11172+(n<<1<<2)|0,e=t[2783]|0,n=1<>2]|0):(t[2783]=e|n,n=r,e=r+8|0),t[e>>2]=y,t[n+12>>2]=y,t[y+8>>2]=n,t[y+12>>2]=r;break}if(n=l>>>8,n?l>>>0>16777215?r=31:(pe=(n+1048320|0)>>>16&8,_e=n<>>16&4,_e=_e<>>16&2,r=14-(qe|pe|r)+(_e<>>15)|0,r=l>>>(r+7|0)&1|r<<1):r=0,o=11436+(r<<2)|0,t[y+28>>2]=r,t[y+20>>2]=0,t[s>>2]=0,n=t[2784]|0,e=1<>2]=y,t[y+24>>2]=o,t[y+12>>2]=y,t[y+8>>2]=y;break}for(e=l<<((r|0)==31?0:25-(r>>>1)|0),r=t[o>>2]|0;;){if((t[r+4>>2]&-8|0)==(l|0)){pe=216;break}if(o=r+16+(e>>>31<<2)|0,n=t[o>>2]|0,n)e=e<<1,r=n;else{pe=215;break}}if((pe|0)==215){t[o>>2]=y,t[y+24>>2]=r,t[y+12>>2]=y,t[y+8>>2]=y;break}else if((pe|0)==216){pe=r+8|0,_e=t[pe>>2]|0,t[_e+12>>2]=y,t[pe>>2]=y,t[y+8>>2]=_e,t[y+12>>2]=r,t[y+24>>2]=0;break}}}else{_e=t[2787]|0,(_e|0)==0|l>>>0<_e>>>0&&(t[2787]=l),t[2895]=l,t[2896]=d,t[2898]=0,t[2792]=t[2901],t[2791]=-1,n=0;do _e=11172+(n<<1<<2)|0,t[_e+12>>2]=_e,t[_e+8>>2]=_e,n=n+1|0;while((n|0)!=32);_e=l+8|0,_e=(_e&7|0)==0?0:0-_e&7,pe=l+_e|0,_e=d+-40-_e|0,t[2789]=pe,t[2786]=_e,t[pe+4>>2]=_e|1,t[pe+_e+4>>2]=40,t[2790]=t[2905]}while(0);if(n=t[2786]|0,n>>>0>P>>>0)return qe=n-P|0,t[2786]=qe,_e=t[2789]|0,pe=_e+P|0,t[2789]=pe,t[pe+4>>2]=qe|1,t[_e+4>>2]=P|3,_e=_e+8|0,h=vt,_e|0}return t[(ca()|0)>>2]=12,_e=0,h=vt,_e|0}function sh(e){e=e|0;var n=0,r=0,o=0,s=0,l=0,d=0,_=0,y=0;if(!!e){r=e+-8|0,s=t[2787]|0,e=t[e+-4>>2]|0,n=e&-8,y=r+n|0;do if(e&1)_=r,d=r;else{if(o=t[r>>2]|0,!(e&3)||(d=r+(0-o)|0,l=o+n|0,d>>>0>>0))return;if((d|0)==(t[2788]|0)){if(e=y+4|0,n=t[e>>2]|0,(n&3|0)!=3){_=d,n=l;break}t[2785]=l,t[e>>2]=n&-2,t[d+4>>2]=l|1,t[d+l>>2]=l;return}if(r=o>>>3,o>>>0<256)if(e=t[d+8>>2]|0,n=t[d+12>>2]|0,(n|0)==(e|0)){t[2783]=t[2783]&~(1<>2]=n,t[n+8>>2]=e,_=d,n=l;break}s=t[d+24>>2]|0,e=t[d+12>>2]|0;do if((e|0)==(d|0)){if(r=d+16|0,n=r+4|0,e=t[n>>2]|0,!e)if(e=t[r>>2]|0,e)n=r;else{e=0;break}for(;;){if(r=e+20|0,o=t[r>>2]|0,o|0){e=o,n=r;continue}if(r=e+16|0,o=t[r>>2]|0,o)e=o,n=r;else break}t[n>>2]=0}else _=t[d+8>>2]|0,t[_+12>>2]=e,t[e+8>>2]=_;while(0);if(s){if(n=t[d+28>>2]|0,r=11436+(n<<2)|0,(d|0)==(t[r>>2]|0)){if(t[r>>2]=e,!e){t[2784]=t[2784]&~(1<>2]|0)!=(d|0)&1)<<2)>>2]=e,!e){_=d,n=l;break}t[e+24>>2]=s,n=d+16|0,r=t[n>>2]|0,r|0&&(t[e+16>>2]=r,t[r+24>>2]=e),n=t[n+4>>2]|0,n?(t[e+20>>2]=n,t[n+24>>2]=e,_=d,n=l):(_=d,n=l)}else _=d,n=l}while(0);if(!(d>>>0>=y>>>0)&&(e=y+4|0,o=t[e>>2]|0,!!(o&1))){if(o&2)t[e>>2]=o&-2,t[_+4>>2]=n|1,t[d+n>>2]=n,s=n;else{if(e=t[2788]|0,(y|0)==(t[2789]|0)){if(y=(t[2786]|0)+n|0,t[2786]=y,t[2789]=_,t[_+4>>2]=y|1,(_|0)!=(e|0))return;t[2788]=0,t[2785]=0;return}if((y|0)==(e|0)){y=(t[2785]|0)+n|0,t[2785]=y,t[2788]=d,t[_+4>>2]=y|1,t[d+y>>2]=y;return}s=(o&-8)+n|0,r=o>>>3;do if(o>>>0<256)if(n=t[y+8>>2]|0,e=t[y+12>>2]|0,(e|0)==(n|0)){t[2783]=t[2783]&~(1<>2]=e,t[e+8>>2]=n;break}else{l=t[y+24>>2]|0,e=t[y+12>>2]|0;do if((e|0)==(y|0)){if(r=y+16|0,n=r+4|0,e=t[n>>2]|0,!e)if(e=t[r>>2]|0,e)n=r;else{r=0;break}for(;;){if(r=e+20|0,o=t[r>>2]|0,o|0){e=o,n=r;continue}if(r=e+16|0,o=t[r>>2]|0,o)e=o,n=r;else break}t[n>>2]=0,r=e}else r=t[y+8>>2]|0,t[r+12>>2]=e,t[e+8>>2]=r,r=e;while(0);if(l|0){if(e=t[y+28>>2]|0,n=11436+(e<<2)|0,(y|0)==(t[n>>2]|0)){if(t[n>>2]=r,!r){t[2784]=t[2784]&~(1<>2]|0)!=(y|0)&1)<<2)>>2]=r,!r)break;t[r+24>>2]=l,e=y+16|0,n=t[e>>2]|0,n|0&&(t[r+16>>2]=n,t[n+24>>2]=r),e=t[e+4>>2]|0,e|0&&(t[r+20>>2]=e,t[e+24>>2]=r)}}while(0);if(t[_+4>>2]=s|1,t[d+s>>2]=s,(_|0)==(t[2788]|0)){t[2785]=s;return}}if(e=s>>>3,s>>>0<256){r=11172+(e<<1<<2)|0,n=t[2783]|0,e=1<>2]|0):(t[2783]=n|e,e=r,n=r+8|0),t[n>>2]=_,t[e+12>>2]=_,t[_+8>>2]=e,t[_+12>>2]=r;return}e=s>>>8,e?s>>>0>16777215?e=31:(d=(e+1048320|0)>>>16&8,y=e<>>16&4,y=y<>>16&2,e=14-(l|d|e)+(y<>>15)|0,e=s>>>(e+7|0)&1|e<<1):e=0,o=11436+(e<<2)|0,t[_+28>>2]=e,t[_+20>>2]=0,t[_+16>>2]=0,n=t[2784]|0,r=1<>>1)|0),r=t[o>>2]|0;;){if((t[r+4>>2]&-8|0)==(s|0)){e=73;break}if(o=r+16+(n>>>31<<2)|0,e=t[o>>2]|0,e)n=n<<1,r=e;else{e=72;break}}if((e|0)==72){t[o>>2]=_,t[_+24>>2]=r,t[_+12>>2]=_,t[_+8>>2]=_;break}else if((e|0)==73){d=r+8|0,y=t[d>>2]|0,t[y+12>>2]=_,t[d>>2]=_,t[_+8>>2]=y,t[_+12>>2]=r,t[_+24>>2]=0;break}}else t[2784]=n|r,t[o>>2]=_,t[_+24>>2]=o,t[_+12>>2]=_,t[_+8>>2]=_;while(0);if(y=(t[2791]|0)+-1|0,t[2791]=y,!y)e=11588;else return;for(;e=t[e>>2]|0,e;)e=e+8|0;t[2791]=-1}}}function rL(){return 11628}function iL(e){e=e|0;var n=0,r=0;return n=h,h=h+16|0,r=n,t[r>>2]=sL(t[e+60>>2]|0)|0,e=lh(Ms(6,r|0)|0)|0,h=n,e|0}function j8(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0,we=0;P=h,h=h+48|0,k=P+16|0,l=P,s=P+32|0,_=e+28|0,o=t[_>>2]|0,t[s>>2]=o,y=e+20|0,o=(t[y>>2]|0)-o|0,t[s+4>>2]=o,t[s+8>>2]=n,t[s+12>>2]=r,o=o+r|0,d=e+60|0,t[l>>2]=t[d>>2],t[l+4>>2]=s,t[l+8>>2]=2,l=lh(G0(146,l|0)|0)|0;e:do if((o|0)!=(l|0)){for(n=2;!((l|0)<0);)if(o=o-l|0,we=t[s+4>>2]|0,q=l>>>0>we>>>0,s=q?s+8|0:s,n=(q<<31>>31)+n|0,we=l-(q?we:0)|0,t[s>>2]=(t[s>>2]|0)+we,q=s+4|0,t[q>>2]=(t[q>>2]|0)-we,t[k>>2]=t[d>>2],t[k+4>>2]=s,t[k+8>>2]=n,l=lh(G0(146,k|0)|0)|0,(o|0)==(l|0)){T=3;break e}t[e+16>>2]=0,t[_>>2]=0,t[y>>2]=0,t[e>>2]=t[e>>2]|32,(n|0)==2?r=0:r=r-(t[s+4>>2]|0)|0}else T=3;while(0);return(T|0)==3&&(we=t[e+44>>2]|0,t[e+16>>2]=we+(t[e+48>>2]|0),t[_>>2]=we,t[y>>2]=we),h=P,r|0}function oL(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0;return s=h,h=h+32|0,l=s,o=s+20|0,t[l>>2]=t[e+60>>2],t[l+4>>2]=0,t[l+8>>2]=n,t[l+12>>2]=o,t[l+16>>2]=r,(lh(Uu(140,l|0)|0)|0)<0?(t[o>>2]=-1,e=-1):e=t[o>>2]|0,h=s,e|0}function lh(e){return e=e|0,e>>>0>4294963200&&(t[(ca()|0)>>2]=0-e,e=-1),e|0}function ca(){return(uL()|0)+64|0}function uL(){return b4()|0}function b4(){return 2084}function sL(e){return e=e|0,e|0}function lL(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0;return s=h,h=h+32|0,o=s,t[e+36>>2]=1,((t[e>>2]&64|0)==0?(t[o>>2]=t[e+60>>2],t[o+4>>2]=21523,t[o+8>>2]=s+16,su(54,o|0)|0):0)&&(c[e+75>>0]=-1),o=j8(e,n,r)|0,h=s,o|0}function U8(e,n){e=e|0,n=n|0;var r=0,o=0;if(r=c[e>>0]|0,o=c[n>>0]|0,r<<24>>24==0?1:r<<24>>24!=o<<24>>24)e=o;else{do e=e+1|0,n=n+1|0,r=c[e>>0]|0,o=c[n>>0]|0;while(!(r<<24>>24==0?1:r<<24>>24!=o<<24>>24));e=o}return(r&255)-(e&255)|0}function fL(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0;e:do if(!r)e=0;else{for(;o=c[e>>0]|0,s=c[n>>0]|0,o<<24>>24==s<<24>>24;)if(r=r+-1|0,r)e=e+1|0,n=n+1|0;else{e=0;break e}e=(o&255)-(s&255)|0}while(0);return e|0}function q8(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0,we=0,le=0,ie=0;ie=h,h=h+224|0,T=ie+120|0,P=ie+80|0,we=ie,le=ie+136|0,o=P,s=o+40|0;do t[o>>2]=0,o=o+4|0;while((o|0)<(s|0));return t[T>>2]=t[r>>2],(G4(0,n,T,we,P)|0)<0?r=-1:((t[e+76>>2]|0)>-1?q=cL(e)|0:q=0,r=t[e>>2]|0,k=r&32,(c[e+74>>0]|0)<1&&(t[e>>2]=r&-33),o=e+48|0,t[o>>2]|0?r=G4(e,n,T,we,P)|0:(s=e+44|0,l=t[s>>2]|0,t[s>>2]=le,d=e+28|0,t[d>>2]=le,_=e+20|0,t[_>>2]=le,t[o>>2]=80,y=e+16|0,t[y>>2]=le+80,r=G4(e,n,T,we,P)|0,l&&(dh[t[e+36>>2]&7](e,0,0)|0,r=(t[_>>2]|0)==0?-1:r,t[s>>2]=l,t[o>>2]=0,t[y>>2]=0,t[d>>2]=0,t[_>>2]=0)),o=t[e>>2]|0,t[e>>2]=o|k,q|0&&aL(e),r=(o&32|0)==0?r:-1),h=ie,r|0}function G4(e,n,r,o,s){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0;var l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0,we=0,le=0,ie=0,Pe=0,ke=0,qe=0,pe=0,_e=0,vt=0,Ln=0,Ht=0,It=0,gn=0,Pn=0,zt=0;zt=h,h=h+64|0,Ht=zt+16|0,It=zt,vt=zt+24|0,gn=zt+8|0,Pn=zt+20|0,t[Ht>>2]=n,qe=(e|0)!=0,pe=vt+40|0,_e=pe,vt=vt+39|0,Ln=gn+4|0,d=0,l=0,T=0;e:for(;;){do if((l|0)>-1)if((d|0)>(2147483647-l|0)){t[(ca()|0)>>2]=75,l=-1;break}else{l=d+l|0;break}while(0);if(d=c[n>>0]|0,d<<24>>24)_=n;else{ke=87;break}t:for(;;){switch(d<<24>>24){case 37:{d=_,ke=9;break t}case 0:{d=_;break t}default:}Pe=_+1|0,t[Ht>>2]=Pe,d=c[Pe>>0]|0,_=Pe}t:do if((ke|0)==9)for(;;){if(ke=0,(c[_+1>>0]|0)!=37)break t;if(d=d+1|0,_=_+2|0,t[Ht>>2]=_,(c[_>>0]|0)==37)ke=9;else break}while(0);if(d=d-n|0,qe&&ri(e,n,d),d|0){n=_;continue}y=_+1|0,d=(c[y>>0]|0)+-48|0,d>>>0<10?(Pe=(c[_+2>>0]|0)==36,ie=Pe?d:-1,T=Pe?1:T,y=Pe?_+3|0:y):ie=-1,t[Ht>>2]=y,d=c[y>>0]|0,_=(d<<24>>24)+-32|0;t:do if(_>>>0<32)for(k=0,P=d;;){if(d=1<<_,!(d&75913)){d=P;break t}if(k=d|k,y=y+1|0,t[Ht>>2]=y,d=c[y>>0]|0,_=(d<<24>>24)+-32|0,_>>>0>=32)break;P=d}else k=0;while(0);if(d<<24>>24==42){if(_=y+1|0,d=(c[_>>0]|0)+-48|0,d>>>0<10?(c[y+2>>0]|0)==36:0)t[s+(d<<2)>>2]=10,d=t[o+((c[_>>0]|0)+-48<<3)>>2]|0,T=1,y=y+3|0;else{if(T|0){l=-1;break}qe?(T=(t[r>>2]|0)+(4-1)&~(4-1),d=t[T>>2]|0,t[r>>2]=T+4,T=0,y=_):(d=0,T=0,y=_)}t[Ht>>2]=y,Pe=(d|0)<0,d=Pe?0-d|0:d,k=Pe?k|8192:k}else{if(d=z8(Ht)|0,(d|0)<0){l=-1;break}y=t[Ht>>2]|0}do if((c[y>>0]|0)==46){if((c[y+1>>0]|0)!=42){t[Ht>>2]=y+1,_=z8(Ht)|0,y=t[Ht>>2]|0;break}if(P=y+2|0,_=(c[P>>0]|0)+-48|0,_>>>0<10?(c[y+3>>0]|0)==36:0){t[s+(_<<2)>>2]=10,_=t[o+((c[P>>0]|0)+-48<<3)>>2]|0,y=y+4|0,t[Ht>>2]=y;break}if(T|0){l=-1;break e}qe?(Pe=(t[r>>2]|0)+(4-1)&~(4-1),_=t[Pe>>2]|0,t[r>>2]=Pe+4):_=0,t[Ht>>2]=P,y=P}else _=-1;while(0);for(le=0;;){if(((c[y>>0]|0)+-65|0)>>>0>57){l=-1;break e}if(Pe=y+1|0,t[Ht>>2]=Pe,P=c[(c[y>>0]|0)+-65+(5178+(le*58|0))>>0]|0,q=P&255,(q+-1|0)>>>0<8)le=q,y=Pe;else break}if(!(P<<24>>24)){l=-1;break}we=(ie|0)>-1;do if(P<<24>>24==19)if(we){l=-1;break e}else ke=49;else{if(we){t[s+(ie<<2)>>2]=q,we=o+(ie<<3)|0,ie=t[we+4>>2]|0,ke=It,t[ke>>2]=t[we>>2],t[ke+4>>2]=ie,ke=49;break}if(!qe){l=0;break e}W8(It,q,r)}while(0);if((ke|0)==49?(ke=0,!qe):0){d=0,n=Pe;continue}y=c[y>>0]|0,y=(le|0)!=0&(y&15|0)==3?y&-33:y,we=k&-65537,ie=(k&8192|0)==0?k:we;t:do switch(y|0){case 110:switch((le&255)<<24>>24){case 0:{t[t[It>>2]>>2]=l,d=0,n=Pe;continue e}case 1:{t[t[It>>2]>>2]=l,d=0,n=Pe;continue e}case 2:{d=t[It>>2]|0,t[d>>2]=l,t[d+4>>2]=((l|0)<0)<<31>>31,d=0,n=Pe;continue e}case 3:{g[t[It>>2]>>1]=l,d=0,n=Pe;continue e}case 4:{c[t[It>>2]>>0]=l,d=0,n=Pe;continue e}case 6:{t[t[It>>2]>>2]=l,d=0,n=Pe;continue e}case 7:{d=t[It>>2]|0,t[d>>2]=l,t[d+4>>2]=((l|0)<0)<<31>>31,d=0,n=Pe;continue e}default:{d=0,n=Pe;continue e}}case 112:{y=120,_=_>>>0>8?_:8,n=ie|8,ke=61;break}case 88:case 120:{n=ie,ke=61;break}case 111:{y=It,n=t[y>>2]|0,y=t[y+4>>2]|0,q=pL(n,y,pe)|0,we=_e-q|0,k=0,P=5642,_=(ie&8|0)==0|(_|0)>(we|0)?_:we+1|0,we=ie,ke=67;break}case 105:case 100:if(y=It,n=t[y>>2]|0,y=t[y+4>>2]|0,(y|0)<0){n=fh(0,0,n|0,y|0)|0,y=be,k=It,t[k>>2]=n,t[k+4>>2]=y,k=1,P=5642,ke=66;break t}else{k=(ie&2049|0)!=0&1,P=(ie&2048|0)==0?(ie&1|0)==0?5642:5644:5643,ke=66;break t}case 117:{y=It,k=0,P=5642,n=t[y>>2]|0,y=t[y+4>>2]|0,ke=66;break}case 99:{c[vt>>0]=t[It>>2],n=vt,k=0,P=5642,q=pe,y=1,_=we;break}case 109:{y=hL(t[(ca()|0)>>2]|0)|0,ke=71;break}case 115:{y=t[It>>2]|0,y=y|0?y:5652,ke=71;break}case 67:{t[gn>>2]=t[It>>2],t[Ln>>2]=0,t[It>>2]=gn,q=-1,y=gn,ke=75;break}case 83:{n=t[It>>2]|0,_?(q=_,y=n,ke=75):(wi(e,32,d,0,ie),n=0,ke=84);break}case 65:case 71:case 70:case 69:case 97:case 103:case 102:case 101:{d=vL(e,+L[It>>3],d,_,ie,y)|0,n=Pe;continue e}default:k=0,P=5642,q=pe,y=_,_=ie}while(0);t:do if((ke|0)==61)ie=It,le=t[ie>>2]|0,ie=t[ie+4>>2]|0,q=dL(le,ie,pe,y&32)|0,P=(n&8|0)==0|(le|0)==0&(ie|0)==0,k=P?0:2,P=P?5642:5642+(y>>4)|0,we=n,n=le,y=ie,ke=67;else if((ke|0)==66)q=aa(n,y,pe)|0,we=ie,ke=67;else if((ke|0)==71)ke=0,ie=mL(y,0,_)|0,le=(ie|0)==0,n=y,k=0,P=5642,q=le?y+_|0:ie,y=le?_:ie-y|0,_=we;else if((ke|0)==75){for(ke=0,P=y,n=0,_=0;k=t[P>>2]|0,!(!k||(_=H8(Pn,k)|0,(_|0)<0|_>>>0>(q-n|0)>>>0));)if(n=_+n|0,q>>>0>n>>>0)P=P+4|0;else break;if((_|0)<0){l=-1;break e}if(wi(e,32,d,n,ie),!n)n=0,ke=84;else for(k=0;;){if(_=t[y>>2]|0,!_){ke=84;break t}if(_=H8(Pn,_)|0,k=_+k|0,(k|0)>(n|0)){ke=84;break t}if(ri(e,Pn,_),k>>>0>=n>>>0){ke=84;break}else y=y+4|0}}while(0);if((ke|0)==67)ke=0,y=(n|0)!=0|(y|0)!=0,ie=(_|0)!=0|y,y=((y^1)&1)+(_e-q)|0,n=ie?q:pe,q=pe,y=ie?(_|0)>(y|0)?_:y:_,_=(_|0)>-1?we&-65537:we;else if((ke|0)==84){ke=0,wi(e,32,d,n,ie^8192),d=(d|0)>(n|0)?d:n,n=Pe;continue}le=q-n|0,we=(y|0)<(le|0)?le:y,ie=we+k|0,d=(d|0)<(ie|0)?ie:d,wi(e,32,d,ie,_),ri(e,P,k),wi(e,48,d,ie,_^65536),wi(e,48,we,le,0),ri(e,n,le),wi(e,32,d,ie,_^8192),n=Pe}e:do if((ke|0)==87&&!e)if(!T)l=0;else{for(l=1;n=t[s+(l<<2)>>2]|0,!!n;)if(W8(o+(l<<3)|0,n,r),l=l+1|0,(l|0)>=10){l=1;break e}for(;;){if(t[s+(l<<2)>>2]|0){l=-1;break e}if(l=l+1|0,(l|0)>=10){l=1;break}}}while(0);return h=zt,l|0}function cL(e){return e=e|0,0}function aL(e){e=e|0}function ri(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]&32||TL(n,r,e)|0}function z8(e){e=e|0;var n=0,r=0,o=0;if(r=t[e>>2]|0,o=(c[r>>0]|0)+-48|0,o>>>0<10){n=0;do n=o+(n*10|0)|0,r=r+1|0,t[e>>2]=r,o=(c[r>>0]|0)+-48|0;while(o>>>0<10)}else n=0;return n|0}function W8(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0;e:do if(n>>>0<=20)do switch(n|0){case 9:{o=(t[r>>2]|0)+(4-1)&~(4-1),n=t[o>>2]|0,t[r>>2]=o+4,t[e>>2]=n;break e}case 10:{o=(t[r>>2]|0)+(4-1)&~(4-1),n=t[o>>2]|0,t[r>>2]=o+4,o=e,t[o>>2]=n,t[o+4>>2]=((n|0)<0)<<31>>31;break e}case 11:{o=(t[r>>2]|0)+(4-1)&~(4-1),n=t[o>>2]|0,t[r>>2]=o+4,o=e,t[o>>2]=n,t[o+4>>2]=0;break e}case 12:{o=(t[r>>2]|0)+(8-1)&~(8-1),n=o,s=t[n>>2]|0,n=t[n+4>>2]|0,t[r>>2]=o+8,o=e,t[o>>2]=s,t[o+4>>2]=n;break e}case 13:{s=(t[r>>2]|0)+(4-1)&~(4-1),o=t[s>>2]|0,t[r>>2]=s+4,o=(o&65535)<<16>>16,s=e,t[s>>2]=o,t[s+4>>2]=((o|0)<0)<<31>>31;break e}case 14:{s=(t[r>>2]|0)+(4-1)&~(4-1),o=t[s>>2]|0,t[r>>2]=s+4,s=e,t[s>>2]=o&65535,t[s+4>>2]=0;break e}case 15:{s=(t[r>>2]|0)+(4-1)&~(4-1),o=t[s>>2]|0,t[r>>2]=s+4,o=(o&255)<<24>>24,s=e,t[s>>2]=o,t[s+4>>2]=((o|0)<0)<<31>>31;break e}case 16:{s=(t[r>>2]|0)+(4-1)&~(4-1),o=t[s>>2]|0,t[r>>2]=s+4,s=e,t[s>>2]=o&255,t[s+4>>2]=0;break e}case 17:{s=(t[r>>2]|0)+(8-1)&~(8-1),l=+L[s>>3],t[r>>2]=s+8,L[e>>3]=l;break e}case 18:{s=(t[r>>2]|0)+(8-1)&~(8-1),l=+L[s>>3],t[r>>2]=s+8,L[e>>3]=l;break e}default:break e}while(0);while(0)}function dL(e,n,r,o){if(e=e|0,n=n|0,r=r|0,o=o|0,!((e|0)==0&(n|0)==0))do r=r+-1|0,c[r>>0]=C[5694+(e&15)>>0]|0|o,e=ch(e|0,n|0,4)|0,n=be;while(!((e|0)==0&(n|0)==0));return r|0}function pL(e,n,r){if(e=e|0,n=n|0,r=r|0,!((e|0)==0&(n|0)==0))do r=r+-1|0,c[r>>0]=e&7|48,e=ch(e|0,n|0,3)|0,n=be;while(!((e|0)==0&(n|0)==0));return r|0}function aa(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;if(n>>>0>0|(n|0)==0&e>>>0>4294967295){for(;o=K4(e|0,n|0,10,0)|0,r=r+-1|0,c[r>>0]=o&255|48,o=e,e=$4(e|0,n|0,10,0)|0,n>>>0>9|(n|0)==9&o>>>0>4294967295;)n=be;n=e}else n=e;if(n)for(;r=r+-1|0,c[r>>0]=(n>>>0)%10|0|48,!(n>>>0<10);)n=(n>>>0)/10|0;return r|0}function hL(e){return e=e|0,DL(e,t[(wL()|0)+188>>2]|0)|0}function mL(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;l=n&255,o=(r|0)!=0;e:do if(o&(e&3|0)!=0)for(s=n&255;;){if((c[e>>0]|0)==s<<24>>24){d=6;break e}if(e=e+1|0,r=r+-1|0,o=(r|0)!=0,!(o&(e&3|0)!=0)){d=5;break}}else d=5;while(0);(d|0)==5&&(o?d=6:r=0);e:do if((d|0)==6&&(s=n&255,(c[e>>0]|0)!=s<<24>>24)){o=Un(l,16843009)|0;t:do if(r>>>0>3){for(;l=t[e>>2]^o,!((l&-2139062144^-2139062144)&l+-16843009|0);)if(e=e+4|0,r=r+-4|0,r>>>0<=3){d=11;break t}}else d=11;while(0);if((d|0)==11&&!r){r=0;break}for(;;){if((c[e>>0]|0)==s<<24>>24)break e;if(e=e+1|0,r=r+-1|0,!r){r=0;break}}}while(0);return(r|0?e:0)|0}function wi(e,n,r,o,s){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0;var l=0,d=0;if(d=h,h=h+256|0,l=d,(r|0)>(o|0)&(s&73728|0)==0){if(s=r-o|0,pa(l|0,n|0,(s>>>0<256?s:256)|0)|0,s>>>0>255){n=r-o|0;do ri(e,l,256),s=s+-256|0;while(s>>>0>255);s=n&255}ri(e,l,s)}h=d}function H8(e,n){return e=e|0,n=n|0,e?e=_L(e,n,0)|0:e=0,e|0}function vL(e,n,r,o,s,l){e=e|0,n=+n,r=r|0,o=o|0,s=s|0,l=l|0;var d=0,_=0,y=0,k=0,T=0,P=0,q=0,we=0,le=0,ie=0,Pe=0,ke=0,qe=0,pe=0,_e=0,vt=0,Ln=0,Ht=0,It=0,gn=0,Pn=0,zt=0,Dr=0;Dr=h,h=h+560|0,y=Dr+8|0,Pe=Dr,zt=Dr+524|0,Pn=zt,k=Dr+512|0,t[Pe>>2]=0,gn=k+12|0,b8(n)|0,(be|0)<0?(n=-n,Ht=1,Ln=5659):(Ht=(s&2049|0)!=0&1,Ln=(s&2048|0)==0?(s&1|0)==0?5660:5665:5662),b8(n)|0,It=be&2146435072;do if(It>>>0<2146435072|(It|0)==2146435072&0<0){if(we=+gL(n,Pe)*2,d=we!=0,d&&(t[Pe>>2]=(t[Pe>>2]|0)+-1),qe=l|32,(qe|0)==97){le=l&32,q=(le|0)==0?Ln:Ln+9|0,P=Ht|2,d=12-o|0;do if(o>>>0>11|(d|0)==0)n=we;else{n=8;do d=d+-1|0,n=n*16;while((d|0)!=0);if((c[q>>0]|0)==45){n=-(n+(-we-n));break}else{n=we+n-n;break}}while(0);_=t[Pe>>2]|0,d=(_|0)<0?0-_|0:_,d=aa(d,((d|0)<0)<<31>>31,gn)|0,(d|0)==(gn|0)&&(d=k+11|0,c[d>>0]=48),c[d+-1>>0]=(_>>31&2)+43,T=d+-2|0,c[T>>0]=l+15,k=(o|0)<1,y=(s&8|0)==0,d=zt;do It=~~n,_=d+1|0,c[d>>0]=C[5694+It>>0]|le,n=(n-+(It|0))*16,((_-Pn|0)==1?!(y&(k&n==0)):0)?(c[_>>0]=46,d=d+2|0):d=_;while(n!=0);It=d-Pn|0,Pn=gn-T|0,gn=(o|0)!=0&(It+-2|0)<(o|0)?o+2|0:It,d=Pn+P+gn|0,wi(e,32,r,d,s),ri(e,q,P),wi(e,48,r,d,s^65536),ri(e,zt,It),wi(e,48,gn-It|0,0,0),ri(e,T,Pn),wi(e,32,r,d,s^8192);break}_=(o|0)<0?6:o,d?(d=(t[Pe>>2]|0)+-28|0,t[Pe>>2]=d,n=we*268435456):(n=we,d=t[Pe>>2]|0),It=(d|0)<0?y:y+288|0,y=It;do _e=~~n>>>0,t[y>>2]=_e,y=y+4|0,n=(n-+(_e>>>0))*1e9;while(n!=0);if((d|0)>0)for(k=It,P=y;;){if(T=(d|0)<29?d:29,d=P+-4|0,d>>>0>=k>>>0){y=0;do pe=X8(t[d>>2]|0,0,T|0)|0,pe=Y4(pe|0,be|0,y|0,0)|0,_e=be,ke=K4(pe|0,_e|0,1e9,0)|0,t[d>>2]=ke,y=$4(pe|0,_e|0,1e9,0)|0,d=d+-4|0;while(d>>>0>=k>>>0);y&&(k=k+-4|0,t[k>>2]=y)}for(y=P;!(y>>>0<=k>>>0);)if(d=y+-4|0,!(t[d>>2]|0))y=d;else break;if(d=(t[Pe>>2]|0)-T|0,t[Pe>>2]=d,(d|0)>0)P=y;else break}else k=It;if((d|0)<0){o=((_+25|0)/9|0)+1|0,ie=(qe|0)==102;do{if(le=0-d|0,le=(le|0)<9?le:9,k>>>0>>0){T=(1<>>le,q=0,d=k;do _e=t[d>>2]|0,t[d>>2]=(_e>>>le)+q,q=Un(_e&T,P)|0,d=d+4|0;while(d>>>0>>0);d=(t[k>>2]|0)==0?k+4|0:k,q?(t[y>>2]=q,k=d,d=y+4|0):(k=d,d=y)}else k=(t[k>>2]|0)==0?k+4|0:k,d=y;y=ie?It:k,y=(d-y>>2|0)>(o|0)?y+(o<<2)|0:d,d=(t[Pe>>2]|0)+le|0,t[Pe>>2]=d}while((d|0)<0);d=k,o=y}else d=k,o=y;if(_e=It,d>>>0>>0){if(y=(_e-d>>2)*9|0,T=t[d>>2]|0,T>>>0>=10){k=10;do k=k*10|0,y=y+1|0;while(T>>>0>=k>>>0)}}else y=0;if(ie=(qe|0)==103,ke=(_|0)!=0,k=_-((qe|0)!=102?y:0)+((ke&ie)<<31>>31)|0,(k|0)<(((o-_e>>2)*9|0)+-9|0)){if(k=k+9216|0,le=It+4+(((k|0)/9|0)+-1024<<2)|0,k=((k|0)%9|0)+1|0,(k|0)<9){T=10;do T=T*10|0,k=k+1|0;while((k|0)!=9)}else T=10;if(P=t[le>>2]|0,q=(P>>>0)%(T>>>0)|0,k=(le+4|0)==(o|0),k&(q|0)==0)k=le;else if(we=(((P>>>0)/(T>>>0)|0)&1|0)==0?9007199254740992:9007199254740994,pe=(T|0)/2|0,n=q>>>0>>0?.5:k&(q|0)==(pe|0)?1:1.5,Ht&&(pe=(c[Ln>>0]|0)==45,n=pe?-n:n,we=pe?-we:we),k=P-q|0,t[le>>2]=k,we+n!=we){if(pe=k+T|0,t[le>>2]=pe,pe>>>0>999999999)for(y=le;k=y+-4|0,t[y>>2]=0,k>>>0>>0&&(d=d+-4|0,t[d>>2]=0),pe=(t[k>>2]|0)+1|0,t[k>>2]=pe,pe>>>0>999999999;)y=k;else k=le;if(y=(_e-d>>2)*9|0,P=t[d>>2]|0,P>>>0>=10){T=10;do T=T*10|0,y=y+1|0;while(P>>>0>=T>>>0)}}else k=le;k=k+4|0,k=o>>>0>k>>>0?k:o,pe=d}else k=o,pe=d;for(qe=k;;){if(qe>>>0<=pe>>>0){Pe=0;break}if(d=qe+-4|0,!(t[d>>2]|0))qe=d;else{Pe=1;break}}o=0-y|0;do if(ie)if(d=((ke^1)&1)+_|0,(d|0)>(y|0)&(y|0)>-5?(T=l+-1|0,_=d+-1-y|0):(T=l+-2|0,_=d+-1|0),d=s&8,d)le=d;else{if(Pe?(vt=t[qe+-4>>2]|0,(vt|0)!=0):0)if((vt>>>0)%10|0)k=0;else{k=0,d=10;do d=d*10|0,k=k+1|0;while(!((vt>>>0)%(d>>>0)|0|0))}else k=9;if(d=((qe-_e>>2)*9|0)+-9|0,(T|32|0)==102){le=d-k|0,le=(le|0)>0?le:0,_=(_|0)<(le|0)?_:le,le=0;break}else{le=d+y-k|0,le=(le|0)>0?le:0,_=(_|0)<(le|0)?_:le,le=0;break}}else T=l,le=s&8;while(0);if(ie=_|le,P=(ie|0)!=0&1,q=(T|32|0)==102,q)ke=0,d=(y|0)>0?y:0;else{if(d=(y|0)<0?o:y,d=aa(d,((d|0)<0)<<31>>31,gn)|0,k=gn,(k-d|0)<2)do d=d+-1|0,c[d>>0]=48;while((k-d|0)<2);c[d+-1>>0]=(y>>31&2)+43,d=d+-2|0,c[d>>0]=T,ke=d,d=k-d|0}if(d=Ht+1+_+P+d|0,wi(e,32,r,d,s),ri(e,Ln,Ht),wi(e,48,r,d,s^65536),q){T=pe>>>0>It>>>0?It:pe,le=zt+9|0,P=le,q=zt+8|0,k=T;do{if(y=aa(t[k>>2]|0,0,le)|0,(k|0)==(T|0))(y|0)==(le|0)&&(c[q>>0]=48,y=q);else if(y>>>0>zt>>>0){pa(zt|0,48,y-Pn|0)|0;do y=y+-1|0;while(y>>>0>zt>>>0)}ri(e,y,P-y|0),k=k+4|0}while(k>>>0<=It>>>0);if(ie|0&&ri(e,5710,1),k>>>0>>0&(_|0)>0)for(;;){if(y=aa(t[k>>2]|0,0,le)|0,y>>>0>zt>>>0){pa(zt|0,48,y-Pn|0)|0;do y=y+-1|0;while(y>>>0>zt>>>0)}if(ri(e,y,(_|0)<9?_:9),k=k+4|0,y=_+-9|0,k>>>0>>0&(_|0)>9)_=y;else{_=y;break}}wi(e,48,_+9|0,9,0)}else{if(ie=Pe?qe:pe+4|0,(_|0)>-1){Pe=zt+9|0,le=(le|0)==0,o=Pe,P=0-Pn|0,q=zt+8|0,T=pe;do{y=aa(t[T>>2]|0,0,Pe)|0,(y|0)==(Pe|0)&&(c[q>>0]=48,y=q);do if((T|0)==(pe|0)){if(k=y+1|0,ri(e,y,1),le&(_|0)<1){y=k;break}ri(e,5710,1),y=k}else{if(y>>>0<=zt>>>0)break;pa(zt|0,48,y+P|0)|0;do y=y+-1|0;while(y>>>0>zt>>>0)}while(0);Pn=o-y|0,ri(e,y,(_|0)>(Pn|0)?Pn:_),_=_-Pn|0,T=T+4|0}while(T>>>0>>0&(_|0)>-1)}wi(e,48,_+18|0,18,0),ri(e,ke,gn-ke|0)}wi(e,32,r,d,s^8192)}else zt=(l&32|0)!=0,d=Ht+3|0,wi(e,32,r,d,s&-65537),ri(e,Ln,Ht),ri(e,n!=n|!1?zt?5686:5690:zt?5678:5682,3),wi(e,32,r,d,s^8192);while(0);return h=Dr,((d|0)<(r|0)?r:d)|0}function b8(e){e=+e;var n=0;return L[j>>3]=e,n=t[j>>2]|0,be=t[j+4>>2]|0,n|0}function gL(e,n){return e=+e,n=n|0,+ +G8(e,n)}function G8(e,n){e=+e,n=n|0;var r=0,o=0,s=0;switch(L[j>>3]=e,r=t[j>>2]|0,o=t[j+4>>2]|0,s=ch(r|0,o|0,52)|0,s&2047){case 0:{e!=0?(e=+G8(e*18446744073709552e3,n),r=(t[n>>2]|0)+-64|0):r=0,t[n>>2]=r;break}case 2047:break;default:t[n>>2]=(s&2047)+-1022,t[j>>2]=r,t[j+4>>2]=o&-2146435073|1071644672,e=+L[j>>3]}return+e}function _L(e,n,r){e=e|0,n=n|0,r=r|0;do if(e){if(n>>>0<128){c[e>>0]=n,e=1;break}if(!(t[t[(yL()|0)+188>>2]>>2]|0))if((n&-128|0)==57216){c[e>>0]=n,e=1;break}else{t[(ca()|0)>>2]=84,e=-1;break}if(n>>>0<2048){c[e>>0]=n>>>6|192,c[e+1>>0]=n&63|128,e=2;break}if(n>>>0<55296|(n&-8192|0)==57344){c[e>>0]=n>>>12|224,c[e+1>>0]=n>>>6&63|128,c[e+2>>0]=n&63|128,e=3;break}if((n+-65536|0)>>>0<1048576){c[e>>0]=n>>>18|240,c[e+1>>0]=n>>>12&63|128,c[e+2>>0]=n>>>6&63|128,c[e+3>>0]=n&63|128,e=4;break}else{t[(ca()|0)>>2]=84,e=-1;break}}else e=1;while(0);return e|0}function yL(){return b4()|0}function wL(){return b4()|0}function DL(e,n){e=e|0,n=n|0;var r=0,o=0;for(o=0;;){if((C[5712+o>>0]|0)==(e|0)){e=2;break}if(r=o+1|0,(r|0)==87){r=5800,o=87,e=5;break}else o=r}if((e|0)==2&&(o?(r=5800,e=5):r=5800),(e|0)==5)for(;;){do e=r,r=r+1|0;while((c[e>>0]|0)!=0);if(o=o+-1|0,o)e=5;else break}return EL(r,t[n+20>>2]|0)|0}function EL(e,n){return e=e|0,n=n|0,SL(e,n)|0}function SL(e,n){return e=e|0,n=n|0,n?n=CL(t[n>>2]|0,t[n+4>>2]|0,e)|0:n=0,(n|0?n:e)|0}function CL(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0;q=(t[e>>2]|0)+1794895138|0,l=fc(t[e+8>>2]|0,q)|0,o=fc(t[e+12>>2]|0,q)|0,s=fc(t[e+16>>2]|0,q)|0;e:do if((l>>>0>>2>>>0?(P=n-(l<<2)|0,o>>>0

    >>0&s>>>0

    >>0):0)?((s|o)&3|0)==0:0){for(P=o>>>2,T=s>>>2,k=0;;){if(_=l>>>1,y=k+_|0,d=y<<1,s=d+P|0,o=fc(t[e+(s<<2)>>2]|0,q)|0,s=fc(t[e+(s+1<<2)>>2]|0,q)|0,!(s>>>0>>0&o>>>0<(n-s|0)>>>0)){o=0;break e}if(c[e+(s+o)>>0]|0){o=0;break e}if(o=U8(r,e+s|0)|0,!o)break;if(o=(o|0)<0,(l|0)==1){o=0;break e}else k=o?k:y,l=o?_:l-_|0}o=d+T|0,s=fc(t[e+(o<<2)>>2]|0,q)|0,o=fc(t[e+(o+1<<2)>>2]|0,q)|0,o>>>0>>0&s>>>0<(n-o|0)>>>0?o=(c[e+(o+s)>>0]|0)==0?e+o|0:0:o=0}else o=0;while(0);return o|0}function fc(e,n){e=e|0,n=n|0;var r=0;return r=Z8(e|0)|0,((n|0)==0?e:r)|0}function TL(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0,_=0;o=r+16|0,s=t[o>>2]|0,s?l=5:xL(r)|0?o=0:(s=t[o>>2]|0,l=5);e:do if((l|0)==5){if(_=r+20|0,d=t[_>>2]|0,o=d,(s-d|0)>>>0>>0){o=dh[t[r+36>>2]&7](r,e,n)|0;break}t:do if((c[r+75>>0]|0)>-1){for(d=n;;){if(!d){l=0,s=e;break t}if(s=d+-1|0,(c[e+s>>0]|0)==10)break;d=s}if(o=dh[t[r+36>>2]&7](r,e,d)|0,o>>>0>>0)break e;l=d,s=e+d|0,n=n-d|0,o=t[_>>2]|0}else l=0,s=e;while(0);vn(o|0,s|0,n|0)|0,t[_>>2]=(t[_>>2]|0)+n,o=l+n|0}while(0);return o|0}function xL(e){e=e|0;var n=0,r=0;return n=e+74|0,r=c[n>>0]|0,c[n>>0]=r+255|r,n=t[e>>2]|0,n&8?(t[e>>2]=n|32,e=-1):(t[e+8>>2]=0,t[e+4>>2]=0,r=t[e+44>>2]|0,t[e+28>>2]=r,t[e+20>>2]=r,t[e+16>>2]=r+(t[e+48>>2]|0),e=0),e|0}function Ur(e,n){e=w(e),n=w(n);var r=0,o=0;r=V8(e)|0;do if((r&2147483647)>>>0<=2139095040){if(o=V8(n)|0,(o&2147483647)>>>0<=2139095040)if((o^r|0)<0){e=(r|0)<0?n:e;break}else{e=e>2]=e,t[j>>2]|0|0}function cc(e,n){e=w(e),n=w(n);var r=0,o=0;r=Y8(e)|0;do if((r&2147483647)>>>0<=2139095040){if(o=Y8(n)|0,(o&2147483647)>>>0<=2139095040)if((o^r|0)<0){e=(r|0)<0?e:n;break}else{e=e>2]=e,t[j>>2]|0|0}function V4(e,n){e=w(e),n=w(n);var r=0,o=0,s=0,l=0,d=0,_=0,y=0,k=0;l=(D[j>>2]=e,t[j>>2]|0),_=(D[j>>2]=n,t[j>>2]|0),r=l>>>23&255,d=_>>>23&255,y=l&-2147483648,s=_<<1;e:do if((s|0)!=0?!((r|0)==255|((kL(n)|0)&2147483647)>>>0>2139095040):0){if(o=l<<1,o>>>0<=s>>>0)return n=w(e*w(0)),w((o|0)==(s|0)?n:e);if(r)o=l&8388607|8388608;else{if(r=l<<9,(r|0)>-1){o=r,r=0;do r=r+-1|0,o=o<<1;while((o|0)>-1)}else r=0;o=l<<1-r}if(d)_=_&8388607|8388608;else{if(l=_<<9,(l|0)>-1){s=0;do s=s+-1|0,l=l<<1;while((l|0)>-1)}else s=0;d=s,_=_<<1-s}s=o-_|0,l=(s|0)>-1;t:do if((r|0)>(d|0)){for(;;){if(l)if(s)o=s;else break;if(o=o<<1,r=r+-1|0,s=o-_|0,l=(s|0)>-1,(r|0)<=(d|0))break t}n=w(e*w(0));break e}while(0);if(l)if(s)o=s;else{n=w(e*w(0));break}if(o>>>0<8388608)do o=o<<1,r=r+-1|0;while(o>>>0<8388608);(r|0)>0?r=o+-8388608|r<<23:r=o>>>(1-r|0),n=(t[j>>2]=r|y,w(D[j>>2]))}else k=3;while(0);return(k|0)==3&&(n=w(e*n),n=w(n/n)),w(n)}function kL(e){return e=w(e),D[j>>2]=e,t[j>>2]|0|0}function AL(e,n){return e=e|0,n=n|0,q8(t[582]|0,e,n)|0}function $n(e){e=e|0,_n()}function da(e){e=e|0}function OL(e,n){return e=e|0,n=n|0,0}function IL(e){return e=e|0,($8(e+4|0)|0)==-1?(Nl[t[(t[e>>2]|0)+8>>2]&127](e),e=1):e=0,e|0}function $8(e){e=e|0;var n=0;return n=t[e>>2]|0,t[e>>2]=n+-1,n+-1|0}function Tf(e){e=e|0,IL(e)|0&&PL(e)}function PL(e){e=e|0;var n=0;n=e+8|0,((t[n>>2]|0)!=0?($8(n)|0)!=-1:0)||Nl[t[(t[e>>2]|0)+16>>2]&127](e)}function Tt(e){e=e|0;var n=0;for(n=(e|0)==0?1:e;e=uh(n)|0,!(e|0);){if(e=FL()|0,!e){e=0;break}fD[e&0]()}return e|0}function K8(e){return e=e|0,Tt(e)|0}function Ve(e){e=e|0,sh(e)}function ML(e){e=e|0,(c[e+11>>0]|0)<0&&Ve(t[e>>2]|0)}function FL(){var e=0;return e=t[2923]|0,t[2923]=e+0,e|0}function LL(){}function fh(e,n,r,o){return e=e|0,n=n|0,r=r|0,o=o|0,o=n-o-(r>>>0>e>>>0|0)>>>0,be=o,e-r>>>0|0|0}function Y4(e,n,r,o){return e=e|0,n=n|0,r=r|0,o=o|0,r=e+r>>>0,be=n+o+(r>>>0>>0|0)>>>0,r|0|0}function pa(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0,d=0;if(l=e+r|0,n=n&255,(r|0)>=67){for(;e&3;)c[e>>0]=n,e=e+1|0;for(o=l&-4|0,s=o-64|0,d=n|n<<8|n<<16|n<<24;(e|0)<=(s|0);)t[e>>2]=d,t[e+4>>2]=d,t[e+8>>2]=d,t[e+12>>2]=d,t[e+16>>2]=d,t[e+20>>2]=d,t[e+24>>2]=d,t[e+28>>2]=d,t[e+32>>2]=d,t[e+36>>2]=d,t[e+40>>2]=d,t[e+44>>2]=d,t[e+48>>2]=d,t[e+52>>2]=d,t[e+56>>2]=d,t[e+60>>2]=d,e=e+64|0;for(;(e|0)<(o|0);)t[e>>2]=d,e=e+4|0}for(;(e|0)<(l|0);)c[e>>0]=n,e=e+1|0;return l-r|0}function X8(e,n,r){return e=e|0,n=n|0,r=r|0,(r|0)<32?(be=n<>>32-r,e<>>r,e>>>r|(n&(1<>>r-32|0)}function vn(e,n,r){e=e|0,n=n|0,r=r|0;var o=0,s=0,l=0;if((r|0)>=8192)return wo(e|0,n|0,r|0)|0;if(l=e|0,s=e+r|0,(e&3)==(n&3)){for(;e&3;){if(!r)return l|0;c[e>>0]=c[n>>0]|0,e=e+1|0,n=n+1|0,r=r-1|0}for(r=s&-4|0,o=r-64|0;(e|0)<=(o|0);)t[e>>2]=t[n>>2],t[e+4>>2]=t[n+4>>2],t[e+8>>2]=t[n+8>>2],t[e+12>>2]=t[n+12>>2],t[e+16>>2]=t[n+16>>2],t[e+20>>2]=t[n+20>>2],t[e+24>>2]=t[n+24>>2],t[e+28>>2]=t[n+28>>2],t[e+32>>2]=t[n+32>>2],t[e+36>>2]=t[n+36>>2],t[e+40>>2]=t[n+40>>2],t[e+44>>2]=t[n+44>>2],t[e+48>>2]=t[n+48>>2],t[e+52>>2]=t[n+52>>2],t[e+56>>2]=t[n+56>>2],t[e+60>>2]=t[n+60>>2],e=e+64|0,n=n+64|0;for(;(e|0)<(r|0);)t[e>>2]=t[n>>2],e=e+4|0,n=n+4|0}else for(r=s-4|0;(e|0)<(r|0);)c[e>>0]=c[n>>0]|0,c[e+1>>0]=c[n+1>>0]|0,c[e+2>>0]=c[n+2>>0]|0,c[e+3>>0]=c[n+3>>0]|0,e=e+4|0,n=n+4|0;for(;(e|0)<(s|0);)c[e>>0]=c[n>>0]|0,e=e+1|0,n=n+1|0;return l|0}function J8(e){e=e|0;var n=0;return n=c[ce+(e&255)>>0]|0,(n|0)<8?n|0:(n=c[ce+(e>>8&255)>>0]|0,(n|0)<8?n+8|0:(n=c[ce+(e>>16&255)>>0]|0,(n|0)<8?n+16|0:(c[ce+(e>>>24)>>0]|0)+24|0))}function Q8(e,n,r,o,s){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0;var l=0,d=0,_=0,y=0,k=0,T=0,P=0,q=0,we=0,le=0;if(T=e,y=n,k=y,d=r,q=o,_=q,!k)return l=(s|0)!=0,_?l?(t[s>>2]=e|0,t[s+4>>2]=n&0,q=0,s=0,be=q,s|0):(q=0,s=0,be=q,s|0):(l&&(t[s>>2]=(T>>>0)%(d>>>0),t[s+4>>2]=0),q=0,s=(T>>>0)/(d>>>0)>>>0,be=q,s|0);l=(_|0)==0;do if(d){if(!l){if(l=(cr(_|0)|0)-(cr(k|0)|0)|0,l>>>0<=31){P=l+1|0,_=31-l|0,n=l-31>>31,d=P,e=T>>>(P>>>0)&n|k<<_,n=k>>>(P>>>0)&n,l=0,_=T<<_;break}return s?(t[s>>2]=e|0,t[s+4>>2]=y|n&0,q=0,s=0,be=q,s|0):(q=0,s=0,be=q,s|0)}if(l=d-1|0,l&d|0){_=(cr(d|0)|0)+33-(cr(k|0)|0)|0,le=64-_|0,P=32-_|0,y=P>>31,we=_-32|0,n=we>>31,d=_,e=P-1>>31&k>>>(we>>>0)|(k<>>(_>>>0))&n,n=n&k>>>(_>>>0),l=T<>>(we>>>0))&y|T<>31;break}return s|0&&(t[s>>2]=l&T,t[s+4>>2]=0),(d|0)==1?(we=y|n&0,le=e|0|0,be=we,le|0):(le=J8(d|0)|0,we=k>>>(le>>>0)|0,le=k<<32-le|T>>>(le>>>0)|0,be=we,le|0)}else{if(l)return s|0&&(t[s>>2]=(k>>>0)%(d>>>0),t[s+4>>2]=0),we=0,le=(k>>>0)/(d>>>0)>>>0,be=we,le|0;if(!T)return s|0&&(t[s>>2]=0,t[s+4>>2]=(k>>>0)%(_>>>0)),we=0,le=(k>>>0)/(_>>>0)>>>0,be=we,le|0;if(l=_-1|0,!(l&_))return s|0&&(t[s>>2]=e|0,t[s+4>>2]=l&k|n&0),we=0,le=k>>>((J8(_|0)|0)>>>0),be=we,le|0;if(l=(cr(_|0)|0)-(cr(k|0)|0)|0,l>>>0<=30){n=l+1|0,_=31-l|0,d=n,e=k<<_|T>>>(n>>>0),n=k>>>(n>>>0),l=0,_=T<<_;break}return s?(t[s>>2]=e|0,t[s+4>>2]=y|n&0,we=0,le=0,be=we,le|0):(we=0,le=0,be=we,le|0)}while(0);if(!d)k=_,y=0,_=0;else{P=r|0|0,T=q|o&0,k=Y4(P|0,T|0,-1,-1)|0,r=be,y=_,_=0;do o=y,y=l>>>31|y<<1,l=_|l<<1,o=e<<1|o>>>31|0,q=e>>>31|n<<1|0,fh(k|0,r|0,o|0,q|0)|0,le=be,we=le>>31|((le|0)<0?-1:0)<<1,_=we&1,e=fh(o|0,q|0,we&P|0,(((le|0)<0?-1:0)>>31|((le|0)<0?-1:0)<<1)&T|0)|0,n=be,d=d-1|0;while((d|0)!=0);k=y,y=0}return d=0,s|0&&(t[s>>2]=e,t[s+4>>2]=n),we=(l|0)>>>31|(k|d)<<1|(d<<1|l>>>31)&0|y,le=(l<<1|0>>>31)&-2|_,be=we,le|0}function $4(e,n,r,o){return e=e|0,n=n|0,r=r|0,o=o|0,Q8(e,n,r,o,0)|0}function xf(e){e=e|0;var n=0,r=0;return r=e+15&-16|0,n=t[N>>2]|0,e=n+r|0,(r|0)>0&(e|0)<(n|0)|(e|0)<0?(vr()|0,Os(12),-1):(t[N>>2]=e,((e|0)>(Xn()|0)?(Bn()|0)==0:0)?(t[N>>2]=n,Os(12),-1):n|0)}function Y1(e,n,r){e=e|0,n=n|0,r=r|0;var o=0;if((n|0)<(e|0)&(e|0)<(n+r|0)){for(o=e,n=n+r|0,e=e+r|0;(r|0)>0;)e=e-1|0,n=n-1|0,r=r-1|0,c[e>>0]=c[n>>0]|0;e=o}else vn(e,n,r)|0;return e|0}function K4(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0;var s=0,l=0;return l=h,h=h+16|0,s=l|0,Q8(e,n,r,o,s)|0,h=l,be=t[s+4>>2]|0,t[s>>2]|0|0}function Z8(e){return e=e|0,(e&255)<<24|(e>>8&255)<<16|(e>>16&255)<<8|e>>>24|0}function RL(e,n,r,o,s,l){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0,eD[e&1](n|0,r|0,o|0,s|0,l|0)}function NL(e,n,r){e=e|0,n=n|0,r=w(r),tD[e&1](n|0,w(r))}function BL(e,n,r){e=e|0,n=n|0,r=+r,nD[e&31](n|0,+r)}function jL(e,n,r,o){return e=e|0,n=n|0,r=w(r),o=w(o),w(rD[e&0](n|0,w(r),w(o)))}function UL(e,n){e=e|0,n=n|0,Nl[e&127](n|0)}function qL(e,n,r){e=e|0,n=n|0,r=r|0,Bl[e&31](n|0,r|0)}function zL(e,n){return e=e|0,n=n|0,dc[e&31](n|0)|0}function WL(e,n,r,o,s){e=e|0,n=n|0,r=+r,o=+o,s=s|0,iD[e&1](n|0,+r,+o,s|0)}function HL(e,n,r,o){e=e|0,n=n|0,r=+r,o=+o,CR[e&1](n|0,+r,+o)}function bL(e,n,r,o){return e=e|0,n=n|0,r=r|0,o=o|0,dh[e&7](n|0,r|0,o|0)|0}function VL(e,n,r,o){return e=e|0,n=n|0,r=r|0,o=o|0,+TR[e&1](n|0,r|0,o|0)}function YL(e,n){return e=e|0,n=n|0,+oD[e&15](n|0)}function $L(e,n,r){return e=e|0,n=n|0,r=+r,xR[e&1](n|0,+r)|0}function KL(e,n,r){return e=e|0,n=n|0,r=r|0,J4[e&15](n|0,r|0)|0}function XL(e,n,r,o,s,l){e=e|0,n=n|0,r=r|0,o=+o,s=+s,l=l|0,kR[e&1](n|0,r|0,+o,+s,l|0)}function JL(e,n,r,o,s,l,d){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0,d=d|0,AR[e&1](n|0,r|0,o|0,s|0,l|0,d|0)}function QL(e,n,r){return e=e|0,n=n|0,r=r|0,+uD[e&7](n|0,r|0)}function ZL(e){return e=e|0,ph[e&7]()|0}function eR(e,n,r,o,s,l){return e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0,sD[e&1](n|0,r|0,o|0,s|0,l|0)|0}function tR(e,n,r,o,s){e=e|0,n=n|0,r=r|0,o=o|0,s=+s,OR[e&1](n|0,r|0,o|0,+s)}function nR(e,n,r,o,s,l,d){e=e|0,n=n|0,r=r|0,o=w(o),s=s|0,l=w(l),d=d|0,lD[e&1](n|0,r|0,w(o),s|0,w(l),d|0)}function rR(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0,X1[e&15](n|0,r|0,o|0)}function iR(e){e=e|0,fD[e&0]()}function oR(e,n,r,o){e=e|0,n=n|0,r=r|0,o=+o,cD[e&15](n|0,r|0,+o)}function uR(e,n,r){return e=e|0,n=+n,r=+r,IR[e&1](+n,+r)|0}function sR(e,n,r,o,s){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,Q4[e&15](n|0,r|0,o|0,s|0)}function lR(e,n,r,o,s){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,pt(0)}function fR(e,n){e=e|0,n=w(n),pt(1)}function Lo(e,n){e=e|0,n=+n,pt(2)}function cR(e,n,r){return e=e|0,n=w(n),r=w(r),pt(3),tt}function tn(e){e=e|0,pt(4)}function $1(e,n){e=e|0,n=n|0,pt(5)}function tu(e){return e=e|0,pt(6),0}function aR(e,n,r,o){e=e|0,n=+n,r=+r,o=o|0,pt(7)}function dR(e,n,r){e=e|0,n=+n,r=+r,pt(8)}function pR(e,n,r){return e=e|0,n=n|0,r=r|0,pt(9),0}function hR(e,n,r){return e=e|0,n=n|0,r=r|0,pt(10),0}function ac(e){return e=e|0,pt(11),0}function mR(e,n){return e=e|0,n=+n,pt(12),0}function K1(e,n){return e=e|0,n=n|0,pt(13),0}function vR(e,n,r,o,s){e=e|0,n=n|0,r=+r,o=+o,s=s|0,pt(14)}function gR(e,n,r,o,s,l){e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,l=l|0,pt(15)}function X4(e,n){return e=e|0,n=n|0,pt(16),0}function _R(){return pt(17),0}function yR(e,n,r,o,s){return e=e|0,n=n|0,r=r|0,o=o|0,s=s|0,pt(18),0}function wR(e,n,r,o){e=e|0,n=n|0,r=r|0,o=+o,pt(19)}function DR(e,n,r,o,s,l){e=e|0,n=n|0,r=w(r),o=o|0,s=w(s),l=l|0,pt(20)}function ah(e,n,r){e=e|0,n=n|0,r=r|0,pt(21)}function ER(){pt(22)}function ha(e,n,r){e=e|0,n=n|0,r=+r,pt(23)}function SR(e,n){return e=+e,n=+n,pt(24),0}function ma(e,n,r,o){e=e|0,n=n|0,r=r|0,o=o|0,pt(25)}var eD=[lR,_I],tD=[fR,x0],nD=[Lo,Kf,Tl,xl,hf,xo,mf,Wa,Hs,mi,Xf,Rc,Jf,ao,$o,kl,Nc,Al,vf,Lo,Lo,Lo,Lo,Lo,Lo,Lo,Lo,Lo,Lo,Lo,Lo,Lo],rD=[cR],Nl=[tn,da,Km,Xm,es,a_,d_,p_,YA,$A,KA,oI,uI,sI,kF,AF,OF,Sn,Oc,pf,ti,vi,Nm,Uc,r1,Hd,Pl,mv,Av,Kc,Jc,yp,Eg,na,Ug,Yg,u_,k_,q_,J_,a4,Ct,w9,U9,ex,hx,Ix,_0,s7,S7,W7,uk,Dk,Wk,Qk,tA,_A,DA,jA,JA,eO,gO,RO,d1,vP,YP,lM,SM,GM,uF,gF,wF,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn,tn],Bl=[$1,ja,Ua,$f,gu,co,qa,Ws,za,Mc,Fc,Lc,po,Ce,ze,Et,on,sr,mn,Zf,gd,xd,H9,rx,ck,yP,HO,C8,$1,$1,$1,$1],dc=[tu,iL,Ba,m,b,ee,Ye,Ze,ut,In,jr,gi,Pm,Ha,Ya,Fx,Tk,wO,SP,Qo,tu,tu,tu,tu,tu,tu,tu,tu,tu,tu,tu,tu],iD=[aR,Sd],CR=[dR,zA],dh=[pR,j8,oL,lL,Gv,P_,a7,kM],TR=[hR,Op],oD=[ac,_i,Re,pr,Cd,ho,bs,$a,Td,qc,ac,ac,ac,ac,ac,ac],xR=[mR,Kk],J4=[K1,OL,vd,Vc,_v,ig,pg,f_,H_,_x,Xu,dM,K1,K1,K1,K1],kR=[vR,iv],AR=[gR,KM],uD=[X4,Hr,Ka,kd,Xa,Jg,X4,X4],ph=[_R,Ja,Z0,g0,oA,TA,iO,CF],sD=[yR,or],OR=[wR,m4],lD=[DR,Bc],X1=[ah,S,A0,Vn,ni,Mv,Tg,dn,C9,fo,zI,JP,cF,ah,ah,ah],fD=[ER],cD=[ha,Ic,vu,Pc,Qu,Qf,k0,v,W1,k7,Gk,ha,ha,ha,ha,ha],IR=[SR,GA],Q4=[ma,Fg,zx,V7,Lk,aA,PA,aO,qO,OP,RF,ma,ma,ma,ma,ma];return{_llvm_bswap_i32:Z8,dynCall_idd:uR,dynCall_i:ZL,_i64Subtract:fh,___udivdi3:$4,dynCall_vif:NL,setThrew:vl,dynCall_viii:rR,_bitshift64Lshr:ch,_bitshift64Shl:X8,dynCall_vi:UL,dynCall_viiddi:XL,dynCall_diii:VL,dynCall_iii:KL,_memset:pa,_sbrk:xf,_memcpy:vn,__GLOBAL__sub_I_Yoga_cpp:t0,dynCall_vii:qL,___uremdi3:K4,dynCall_vid:BL,stackAlloc:zi,_nbind_init:VF,getTempRet0:fu,dynCall_di:YL,dynCall_iid:$L,setTempRet0:gl,_i64Add:Y4,dynCall_fiff:jL,dynCall_iiii:bL,_emscripten_get_global_libc:rL,dynCall_viid:oR,dynCall_viiid:tR,dynCall_viififi:nR,dynCall_ii:zL,__GLOBAL__sub_I_Binding_cc:lP,dynCall_viiii:sR,dynCall_iiiiii:eR,stackSave:lu,dynCall_viiiii:RL,__GLOBAL__sub_I_nbind_cc:Gs,dynCall_vidd:HL,_free:sh,runPostSets:LL,dynCall_viiiiii:JL,establishStackSpace:O0,_memmove:Y1,stackRestore:Ho,_malloc:uh,__GLOBAL__sub_I_common_cc:AO,dynCall_viddi:WL,dynCall_dii:QL,dynCall_v:iR}}(Module.asmGlobalArg,Module.asmLibraryArg,buffer),_llvm_bswap_i32=Module._llvm_bswap_i32=asm._llvm_bswap_i32,getTempRet0=Module.getTempRet0=asm.getTempRet0,___udivdi3=Module.___udivdi3=asm.___udivdi3,setThrew=Module.setThrew=asm.setThrew,_bitshift64Lshr=Module._bitshift64Lshr=asm._bitshift64Lshr,_bitshift64Shl=Module._bitshift64Shl=asm._bitshift64Shl,_memset=Module._memset=asm._memset,_sbrk=Module._sbrk=asm._sbrk,_memcpy=Module._memcpy=asm._memcpy,stackAlloc=Module.stackAlloc=asm.stackAlloc,___uremdi3=Module.___uremdi3=asm.___uremdi3,_nbind_init=Module._nbind_init=asm._nbind_init,_i64Subtract=Module._i64Subtract=asm._i64Subtract,setTempRet0=Module.setTempRet0=asm.setTempRet0,_i64Add=Module._i64Add=asm._i64Add,_emscripten_get_global_libc=Module._emscripten_get_global_libc=asm._emscripten_get_global_libc,__GLOBAL__sub_I_Yoga_cpp=Module.__GLOBAL__sub_I_Yoga_cpp=asm.__GLOBAL__sub_I_Yoga_cpp,__GLOBAL__sub_I_Binding_cc=Module.__GLOBAL__sub_I_Binding_cc=asm.__GLOBAL__sub_I_Binding_cc,stackSave=Module.stackSave=asm.stackSave,__GLOBAL__sub_I_nbind_cc=Module.__GLOBAL__sub_I_nbind_cc=asm.__GLOBAL__sub_I_nbind_cc,_free=Module._free=asm._free,runPostSets=Module.runPostSets=asm.runPostSets,establishStackSpace=Module.establishStackSpace=asm.establishStackSpace,_memmove=Module._memmove=asm._memmove,stackRestore=Module.stackRestore=asm.stackRestore,_malloc=Module._malloc=asm._malloc,__GLOBAL__sub_I_common_cc=Module.__GLOBAL__sub_I_common_cc=asm.__GLOBAL__sub_I_common_cc,dynCall_viiiii=Module.dynCall_viiiii=asm.dynCall_viiiii,dynCall_vif=Module.dynCall_vif=asm.dynCall_vif,dynCall_vid=Module.dynCall_vid=asm.dynCall_vid,dynCall_fiff=Module.dynCall_fiff=asm.dynCall_fiff,dynCall_vi=Module.dynCall_vi=asm.dynCall_vi,dynCall_vii=Module.dynCall_vii=asm.dynCall_vii,dynCall_ii=Module.dynCall_ii=asm.dynCall_ii,dynCall_viddi=Module.dynCall_viddi=asm.dynCall_viddi,dynCall_vidd=Module.dynCall_vidd=asm.dynCall_vidd,dynCall_iiii=Module.dynCall_iiii=asm.dynCall_iiii,dynCall_diii=Module.dynCall_diii=asm.dynCall_diii,dynCall_di=Module.dynCall_di=asm.dynCall_di,dynCall_iid=Module.dynCall_iid=asm.dynCall_iid,dynCall_iii=Module.dynCall_iii=asm.dynCall_iii,dynCall_viiddi=Module.dynCall_viiddi=asm.dynCall_viiddi,dynCall_viiiiii=Module.dynCall_viiiiii=asm.dynCall_viiiiii,dynCall_dii=Module.dynCall_dii=asm.dynCall_dii,dynCall_i=Module.dynCall_i=asm.dynCall_i,dynCall_iiiiii=Module.dynCall_iiiiii=asm.dynCall_iiiiii,dynCall_viiid=Module.dynCall_viiid=asm.dynCall_viiid,dynCall_viififi=Module.dynCall_viififi=asm.dynCall_viififi,dynCall_viii=Module.dynCall_viii=asm.dynCall_viii,dynCall_v=Module.dynCall_v=asm.dynCall_v,dynCall_viid=Module.dynCall_viid=asm.dynCall_viid,dynCall_idd=Module.dynCall_idd=asm.dynCall_idd,dynCall_viiii=Module.dynCall_viiii=asm.dynCall_viiii;Runtime.stackAlloc=Module.stackAlloc,Runtime.stackSave=Module.stackSave,Runtime.stackRestore=Module.stackRestore,Runtime.establishStackSpace=Module.establishStackSpace,Runtime.setTempRet0=Module.setTempRet0,Runtime.getTempRet0=Module.getTempRet0,Module.asm=asm;function ExitStatus(i){this.name="ExitStatus",this.message="Program terminated with exit("+i+")",this.status=i}ExitStatus.prototype=new Error,ExitStatus.prototype.constructor=ExitStatus;var initialStackTop,preloadStartTime=null,calledMain=!1;dependenciesFulfilled=function i(){Module.calledRun||run(),Module.calledRun||(dependenciesFulfilled=i)},Module.callMain=Module.callMain=function(u){u=u||[],ensureInitRuntime();var f=u.length+1;function c(){for(var x=0;x<4-1;x++)g.push(0)}var g=[allocate(intArrayFromString(Module.thisProgram),"i8",ALLOC_NORMAL)];c();for(var t=0;t0||(preRun(),runDependencies>0)||Module.calledRun)return;function u(){Module.calledRun||(Module.calledRun=!0,!ABORT&&(ensureInitRuntime(),preMain(),Module.onRuntimeInitialized&&Module.onRuntimeInitialized(),Module._main&&shouldRunNow&&Module.callMain(i),postRun()))}Module.setStatus?(Module.setStatus("Running..."),setTimeout(function(){setTimeout(function(){Module.setStatus("")},1),u()},1)):u()}Module.run=Module.run=run;function exit(i,u){u&&Module.noExitRuntime||(Module.noExitRuntime||(ABORT=!0,EXITSTATUS=i,STACKTOP=initialStackTop,exitRuntime(),Module.onExit&&Module.onExit(i)),ENVIRONMENT_IS_NODE&&process.exit(i),Module.quit(i,new ExitStatus(i)))}Module.exit=Module.exit=exit;var abortDecorators=[];function abort(i){Module.onAbort&&Module.onAbort(i),i!==void 0?(Module.print(i),Module.printErr(i),i=JSON.stringify(i)):i="",ABORT=!0,EXITSTATUS=1;var u=` +If this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.`,f="abort("+i+") at "+stackTrace()+u;throw abortDecorators&&abortDecorators.forEach(function(c){f=c(f,i)}),f}if(Module.abort=Module.abort=abort,Module.preInit)for(typeof Module.preInit=="function"&&(Module.preInit=[Module.preInit]);Module.preInit.length>0;)Module.preInit.pop()();var shouldRunNow=!0;Module.noInitialRun&&(shouldRunNow=!1),run()})});var hc=Me((hb,vE)=>{"use strict";var wN=hE(),DN=mE(),Py=!1,My=null;DN({},function(i,u){if(!Py){if(Py=!0,i)throw i;My=u}});if(!Py)throw new Error("Failed to load the yoga module - it needed to be loaded synchronously, but didn't");vE.exports=wN(My.bind,My.lib)});var _E=Me((mb,gE)=>{"use strict";gE.exports=({onlyFirst:i=!1}={})=>{let u=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(u,i?void 0:"g")}});var Fy=Me((vb,yE)=>{"use strict";var EN=_E();yE.exports=i=>typeof i=="string"?i.replace(EN(),""):i});var Ry=Me((gb,Ly)=>{"use strict";var wE=i=>Number.isNaN(i)?!1:i>=4352&&(i<=4447||i===9001||i===9002||11904<=i&&i<=12871&&i!==12351||12880<=i&&i<=19903||19968<=i&&i<=42182||43360<=i&&i<=43388||44032<=i&&i<=55203||63744<=i&&i<=64255||65040<=i&&i<=65049||65072<=i&&i<=65131||65281<=i&&i<=65376||65504<=i&&i<=65510||110592<=i&&i<=110593||127488<=i&&i<=127569||131072<=i&&i<=262141);Ly.exports=wE;Ly.exports.default=wE});var EE=Me((_b,DE)=>{"use strict";DE.exports=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g}});var Mh=Me((yb,Ny)=>{"use strict";var SN=Fy(),CN=Ry(),TN=EE(),SE=i=>{if(i=i.replace(TN()," "),typeof i!="string"||i.length===0)return 0;i=SN(i);let u=0;for(let f=0;f=127&&c<=159||c>=768&&c<=879||(c>65535&&f++,u+=CN(c)?2:1)}return u};Ny.exports=SE;Ny.exports.default=SE});var jy=Me((wb,By)=>{"use strict";var xN=Mh(),CE=i=>{let u=0;for(let f of i.split(` +`))u=Math.max(u,xN(f));return u};By.exports=CE;By.exports.default=CE});var TE=Me(a2=>{"use strict";var kN=a2&&a2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(a2,"__esModule",{value:!0});var AN=kN(jy()),Uy={};a2.default=i=>{if(i.length===0)return{width:0,height:0};if(Uy[i])return Uy[i];let u=AN.default(i),f=i.split(` +`).length;return Uy[i]={width:u,height:f},{width:u,height:f}}});var xE=Me(d2=>{"use strict";var ON=d2&&d2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(d2,"__esModule",{value:!0});var hr=ON(hc()),IN=(i,u)=>{"position"in u&&i.setPositionType(u.position==="absolute"?hr.default.POSITION_TYPE_ABSOLUTE:hr.default.POSITION_TYPE_RELATIVE)},PN=(i,u)=>{"marginLeft"in u&&i.setMargin(hr.default.EDGE_START,u.marginLeft||0),"marginRight"in u&&i.setMargin(hr.default.EDGE_END,u.marginRight||0),"marginTop"in u&&i.setMargin(hr.default.EDGE_TOP,u.marginTop||0),"marginBottom"in u&&i.setMargin(hr.default.EDGE_BOTTOM,u.marginBottom||0)},MN=(i,u)=>{"paddingLeft"in u&&i.setPadding(hr.default.EDGE_LEFT,u.paddingLeft||0),"paddingRight"in u&&i.setPadding(hr.default.EDGE_RIGHT,u.paddingRight||0),"paddingTop"in u&&i.setPadding(hr.default.EDGE_TOP,u.paddingTop||0),"paddingBottom"in u&&i.setPadding(hr.default.EDGE_BOTTOM,u.paddingBottom||0)},FN=(i,u)=>{var f;"flexGrow"in u&&i.setFlexGrow((f=u.flexGrow)!==null&&f!==void 0?f:0),"flexShrink"in u&&i.setFlexShrink(typeof u.flexShrink=="number"?u.flexShrink:1),"flexDirection"in u&&(u.flexDirection==="row"&&i.setFlexDirection(hr.default.FLEX_DIRECTION_ROW),u.flexDirection==="row-reverse"&&i.setFlexDirection(hr.default.FLEX_DIRECTION_ROW_REVERSE),u.flexDirection==="column"&&i.setFlexDirection(hr.default.FLEX_DIRECTION_COLUMN),u.flexDirection==="column-reverse"&&i.setFlexDirection(hr.default.FLEX_DIRECTION_COLUMN_REVERSE)),"flexBasis"in u&&(typeof u.flexBasis=="number"?i.setFlexBasis(u.flexBasis):typeof u.flexBasis=="string"?i.setFlexBasisPercent(Number.parseInt(u.flexBasis,10)):i.setFlexBasis(NaN)),"alignItems"in u&&((u.alignItems==="stretch"||!u.alignItems)&&i.setAlignItems(hr.default.ALIGN_STRETCH),u.alignItems==="flex-start"&&i.setAlignItems(hr.default.ALIGN_FLEX_START),u.alignItems==="center"&&i.setAlignItems(hr.default.ALIGN_CENTER),u.alignItems==="flex-end"&&i.setAlignItems(hr.default.ALIGN_FLEX_END)),"alignSelf"in u&&((u.alignSelf==="auto"||!u.alignSelf)&&i.setAlignSelf(hr.default.ALIGN_AUTO),u.alignSelf==="flex-start"&&i.setAlignSelf(hr.default.ALIGN_FLEX_START),u.alignSelf==="center"&&i.setAlignSelf(hr.default.ALIGN_CENTER),u.alignSelf==="flex-end"&&i.setAlignSelf(hr.default.ALIGN_FLEX_END)),"justifyContent"in u&&((u.justifyContent==="flex-start"||!u.justifyContent)&&i.setJustifyContent(hr.default.JUSTIFY_FLEX_START),u.justifyContent==="center"&&i.setJustifyContent(hr.default.JUSTIFY_CENTER),u.justifyContent==="flex-end"&&i.setJustifyContent(hr.default.JUSTIFY_FLEX_END),u.justifyContent==="space-between"&&i.setJustifyContent(hr.default.JUSTIFY_SPACE_BETWEEN),u.justifyContent==="space-around"&&i.setJustifyContent(hr.default.JUSTIFY_SPACE_AROUND))},LN=(i,u)=>{var f,c;"width"in u&&(typeof u.width=="number"?i.setWidth(u.width):typeof u.width=="string"?i.setWidthPercent(Number.parseInt(u.width,10)):i.setWidthAuto()),"height"in u&&(typeof u.height=="number"?i.setHeight(u.height):typeof u.height=="string"?i.setHeightPercent(Number.parseInt(u.height,10)):i.setHeightAuto()),"minWidth"in u&&(typeof u.minWidth=="string"?i.setMinWidthPercent(Number.parseInt(u.minWidth,10)):i.setMinWidth((f=u.minWidth)!==null&&f!==void 0?f:0)),"minHeight"in u&&(typeof u.minHeight=="string"?i.setMinHeightPercent(Number.parseInt(u.minHeight,10)):i.setMinHeight((c=u.minHeight)!==null&&c!==void 0?c:0))},RN=(i,u)=>{"display"in u&&i.setDisplay(u.display==="flex"?hr.default.DISPLAY_FLEX:hr.default.DISPLAY_NONE)},NN=(i,u)=>{if("borderStyle"in u){let f=typeof u.borderStyle=="string"?1:0;i.setBorder(hr.default.EDGE_TOP,f),i.setBorder(hr.default.EDGE_BOTTOM,f),i.setBorder(hr.default.EDGE_LEFT,f),i.setBorder(hr.default.EDGE_RIGHT,f)}};d2.default=(i,u={})=>{IN(i,u),PN(i,u),MN(i,u),FN(i,u),LN(i,u),RN(i,u),NN(i,u)}});var AE=Me((Sb,kE)=>{"use strict";kE.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}});var qy=Me((Cb,OE)=>{var p2=AE(),IE={};for(let i of Object.keys(p2))IE[p2[i]]=i;var Xt={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};OE.exports=Xt;for(let i of Object.keys(Xt)){if(!("channels"in Xt[i]))throw new Error("missing channels property: "+i);if(!("labels"in Xt[i]))throw new Error("missing channel labels property: "+i);if(Xt[i].labels.length!==Xt[i].channels)throw new Error("channel and label counts mismatch: "+i);let{channels:u,labels:f}=Xt[i];delete Xt[i].channels,delete Xt[i].labels,Object.defineProperty(Xt[i],"channels",{value:u}),Object.defineProperty(Xt[i],"labels",{value:f})}Xt.rgb.hsl=function(i){let u=i[0]/255,f=i[1]/255,c=i[2]/255,g=Math.min(u,f,c),t=Math.max(u,f,c),C=t-g,A,x;t===g?A=0:u===t?A=(f-c)/C:f===t?A=2+(c-u)/C:c===t&&(A=4+(u-f)/C),A=Math.min(A*60,360),A<0&&(A+=360);let D=(g+t)/2;return t===g?x=0:D<=.5?x=C/(t+g):x=C/(2-t-g),[A,x*100,D*100]};Xt.rgb.hsv=function(i){let u,f,c,g,t,C=i[0]/255,A=i[1]/255,x=i[2]/255,D=Math.max(C,A,x),L=D-Math.min(C,A,x),N=function(j){return(D-j)/6/L+1/2};return L===0?(g=0,t=0):(t=L/D,u=N(C),f=N(A),c=N(x),C===D?g=c-f:A===D?g=1/3+u-c:x===D&&(g=2/3+f-u),g<0?g+=1:g>1&&(g-=1)),[g*360,t*100,D*100]};Xt.rgb.hwb=function(i){let u=i[0],f=i[1],c=i[2],g=Xt.rgb.hsl(i)[0],t=1/255*Math.min(u,Math.min(f,c));return c=1-1/255*Math.max(u,Math.max(f,c)),[g,t*100,c*100]};Xt.rgb.cmyk=function(i){let u=i[0]/255,f=i[1]/255,c=i[2]/255,g=Math.min(1-u,1-f,1-c),t=(1-u-g)/(1-g)||0,C=(1-f-g)/(1-g)||0,A=(1-c-g)/(1-g)||0;return[t*100,C*100,A*100,g*100]};function BN(i,u){return(i[0]-u[0])**2+(i[1]-u[1])**2+(i[2]-u[2])**2}Xt.rgb.keyword=function(i){let u=IE[i];if(u)return u;let f=Infinity,c;for(let g of Object.keys(p2)){let t=p2[g],C=BN(i,t);C.04045?((u+.055)/1.055)**2.4:u/12.92,f=f>.04045?((f+.055)/1.055)**2.4:f/12.92,c=c>.04045?((c+.055)/1.055)**2.4:c/12.92;let g=u*.4124+f*.3576+c*.1805,t=u*.2126+f*.7152+c*.0722,C=u*.0193+f*.1192+c*.9505;return[g*100,t*100,C*100]};Xt.rgb.lab=function(i){let u=Xt.rgb.xyz(i),f=u[0],c=u[1],g=u[2];f/=95.047,c/=100,g/=108.883,f=f>.008856?f**(1/3):7.787*f+16/116,c=c>.008856?c**(1/3):7.787*c+16/116,g=g>.008856?g**(1/3):7.787*g+16/116;let t=116*c-16,C=500*(f-c),A=200*(c-g);return[t,C,A]};Xt.hsl.rgb=function(i){let u=i[0]/360,f=i[1]/100,c=i[2]/100,g,t,C;if(f===0)return C=c*255,[C,C,C];c<.5?g=c*(1+f):g=c+f-c*f;let A=2*c-g,x=[0,0,0];for(let D=0;D<3;D++)t=u+1/3*-(D-1),t<0&&t++,t>1&&t--,6*t<1?C=A+(g-A)*6*t:2*t<1?C=g:3*t<2?C=A+(g-A)*(2/3-t)*6:C=A,x[D]=C*255;return x};Xt.hsl.hsv=function(i){let u=i[0],f=i[1]/100,c=i[2]/100,g=f,t=Math.max(c,.01);c*=2,f*=c<=1?c:2-c,g*=t<=1?t:2-t;let C=(c+f)/2,A=c===0?2*g/(t+g):2*f/(c+f);return[u,A*100,C*100]};Xt.hsv.rgb=function(i){let u=i[0]/60,f=i[1]/100,c=i[2]/100,g=Math.floor(u)%6,t=u-Math.floor(u),C=255*c*(1-f),A=255*c*(1-f*t),x=255*c*(1-f*(1-t));switch(c*=255,g){case 0:return[c,x,C];case 1:return[A,c,C];case 2:return[C,c,x];case 3:return[C,A,c];case 4:return[x,C,c];case 5:return[c,C,A]}};Xt.hsv.hsl=function(i){let u=i[0],f=i[1]/100,c=i[2]/100,g=Math.max(c,.01),t,C;C=(2-f)*c;let A=(2-f)*g;return t=f*g,t/=A<=1?A:2-A,t=t||0,C/=2,[u,t*100,C*100]};Xt.hwb.rgb=function(i){let u=i[0]/360,f=i[1]/100,c=i[2]/100,g=f+c,t;g>1&&(f/=g,c/=g);let C=Math.floor(6*u),A=1-c;t=6*u-C,(C&1)!=0&&(t=1-t);let x=f+t*(A-f),D,L,N;switch(C){default:case 6:case 0:D=A,L=x,N=f;break;case 1:D=x,L=A,N=f;break;case 2:D=f,L=A,N=x;break;case 3:D=f,L=x,N=A;break;case 4:D=x,L=f,N=A;break;case 5:D=A,L=f,N=x;break}return[D*255,L*255,N*255]};Xt.cmyk.rgb=function(i){let u=i[0]/100,f=i[1]/100,c=i[2]/100,g=i[3]/100,t=1-Math.min(1,u*(1-g)+g),C=1-Math.min(1,f*(1-g)+g),A=1-Math.min(1,c*(1-g)+g);return[t*255,C*255,A*255]};Xt.xyz.rgb=function(i){let u=i[0]/100,f=i[1]/100,c=i[2]/100,g,t,C;return g=u*3.2406+f*-1.5372+c*-.4986,t=u*-.9689+f*1.8758+c*.0415,C=u*.0557+f*-.204+c*1.057,g=g>.0031308?1.055*g**(1/2.4)-.055:g*12.92,t=t>.0031308?1.055*t**(1/2.4)-.055:t*12.92,C=C>.0031308?1.055*C**(1/2.4)-.055:C*12.92,g=Math.min(Math.max(0,g),1),t=Math.min(Math.max(0,t),1),C=Math.min(Math.max(0,C),1),[g*255,t*255,C*255]};Xt.xyz.lab=function(i){let u=i[0],f=i[1],c=i[2];u/=95.047,f/=100,c/=108.883,u=u>.008856?u**(1/3):7.787*u+16/116,f=f>.008856?f**(1/3):7.787*f+16/116,c=c>.008856?c**(1/3):7.787*c+16/116;let g=116*f-16,t=500*(u-f),C=200*(f-c);return[g,t,C]};Xt.lab.xyz=function(i){let u=i[0],f=i[1],c=i[2],g,t,C;t=(u+16)/116,g=f/500+t,C=t-c/200;let A=t**3,x=g**3,D=C**3;return t=A>.008856?A:(t-16/116)/7.787,g=x>.008856?x:(g-16/116)/7.787,C=D>.008856?D:(C-16/116)/7.787,g*=95.047,t*=100,C*=108.883,[g,t,C]};Xt.lab.lch=function(i){let u=i[0],f=i[1],c=i[2],g;g=Math.atan2(c,f)*360/2/Math.PI,g<0&&(g+=360);let C=Math.sqrt(f*f+c*c);return[u,C,g]};Xt.lch.lab=function(i){let u=i[0],f=i[1],g=i[2]/360*2*Math.PI,t=f*Math.cos(g),C=f*Math.sin(g);return[u,t,C]};Xt.rgb.ansi16=function(i,u=null){let[f,c,g]=i,t=u===null?Xt.rgb.hsv(i)[2]:u;if(t=Math.round(t/50),t===0)return 30;let C=30+(Math.round(g/255)<<2|Math.round(c/255)<<1|Math.round(f/255));return t===2&&(C+=60),C};Xt.hsv.ansi16=function(i){return Xt.rgb.ansi16(Xt.hsv.rgb(i),i[2])};Xt.rgb.ansi256=function(i){let u=i[0],f=i[1],c=i[2];return u===f&&f===c?u<8?16:u>248?231:Math.round((u-8)/247*24)+232:16+36*Math.round(u/255*5)+6*Math.round(f/255*5)+Math.round(c/255*5)};Xt.ansi16.rgb=function(i){let u=i%10;if(u===0||u===7)return i>50&&(u+=3.5),u=u/10.5*255,[u,u,u];let f=(~~(i>50)+1)*.5,c=(u&1)*f*255,g=(u>>1&1)*f*255,t=(u>>2&1)*f*255;return[c,g,t]};Xt.ansi256.rgb=function(i){if(i>=232){let t=(i-232)*10+8;return[t,t,t]}i-=16;let u,f=Math.floor(i/36)/5*255,c=Math.floor((u=i%36)/6)/5*255,g=u%6/5*255;return[f,c,g]};Xt.rgb.hex=function(i){let f=(((Math.round(i[0])&255)<<16)+((Math.round(i[1])&255)<<8)+(Math.round(i[2])&255)).toString(16).toUpperCase();return"000000".substring(f.length)+f};Xt.hex.rgb=function(i){let u=i.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!u)return[0,0,0];let f=u[0];u[0].length===3&&(f=f.split("").map(A=>A+A).join(""));let c=parseInt(f,16),g=c>>16&255,t=c>>8&255,C=c&255;return[g,t,C]};Xt.rgb.hcg=function(i){let u=i[0]/255,f=i[1]/255,c=i[2]/255,g=Math.max(Math.max(u,f),c),t=Math.min(Math.min(u,f),c),C=g-t,A,x;return C<1?A=t/(1-C):A=0,C<=0?x=0:g===u?x=(f-c)/C%6:g===f?x=2+(c-u)/C:x=4+(u-f)/C,x/=6,x%=1,[x*360,C*100,A*100]};Xt.hsl.hcg=function(i){let u=i[1]/100,f=i[2]/100,c=f<.5?2*u*f:2*u*(1-f),g=0;return c<1&&(g=(f-.5*c)/(1-c)),[i[0],c*100,g*100]};Xt.hsv.hcg=function(i){let u=i[1]/100,f=i[2]/100,c=u*f,g=0;return c<1&&(g=(f-c)/(1-c)),[i[0],c*100,g*100]};Xt.hcg.rgb=function(i){let u=i[0]/360,f=i[1]/100,c=i[2]/100;if(f===0)return[c*255,c*255,c*255];let g=[0,0,0],t=u%1*6,C=t%1,A=1-C,x=0;switch(Math.floor(t)){case 0:g[0]=1,g[1]=C,g[2]=0;break;case 1:g[0]=A,g[1]=1,g[2]=0;break;case 2:g[0]=0,g[1]=1,g[2]=C;break;case 3:g[0]=0,g[1]=A,g[2]=1;break;case 4:g[0]=C,g[1]=0,g[2]=1;break;default:g[0]=1,g[1]=0,g[2]=A}return x=(1-f)*c,[(f*g[0]+x)*255,(f*g[1]+x)*255,(f*g[2]+x)*255]};Xt.hcg.hsv=function(i){let u=i[1]/100,f=i[2]/100,c=u+f*(1-u),g=0;return c>0&&(g=u/c),[i[0],g*100,c*100]};Xt.hcg.hsl=function(i){let u=i[1]/100,c=i[2]/100*(1-u)+.5*u,g=0;return c>0&&c<.5?g=u/(2*c):c>=.5&&c<1&&(g=u/(2*(1-c))),[i[0],g*100,c*100]};Xt.hcg.hwb=function(i){let u=i[1]/100,f=i[2]/100,c=u+f*(1-u);return[i[0],(c-u)*100,(1-c)*100]};Xt.hwb.hcg=function(i){let u=i[1]/100,f=i[2]/100,c=1-f,g=c-u,t=0;return g<1&&(t=(c-g)/(1-g)),[i[0],g*100,t*100]};Xt.apple.rgb=function(i){return[i[0]/65535*255,i[1]/65535*255,i[2]/65535*255]};Xt.rgb.apple=function(i){return[i[0]/255*65535,i[1]/255*65535,i[2]/255*65535]};Xt.gray.rgb=function(i){return[i[0]/100*255,i[0]/100*255,i[0]/100*255]};Xt.gray.hsl=function(i){return[0,0,i[0]]};Xt.gray.hsv=Xt.gray.hsl;Xt.gray.hwb=function(i){return[0,100,i[0]]};Xt.gray.cmyk=function(i){return[0,0,0,i[0]]};Xt.gray.lab=function(i){return[i[0],0,0]};Xt.gray.hex=function(i){let u=Math.round(i[0]/100*255)&255,c=((u<<16)+(u<<8)+u).toString(16).toUpperCase();return"000000".substring(c.length)+c};Xt.rgb.gray=function(i){return[(i[0]+i[1]+i[2])/3/255*100]}});var ME=Me((Tb,PE)=>{var Fh=qy();function jN(){let i={},u=Object.keys(Fh);for(let f=u.length,c=0;c{var zy=qy(),WN=ME(),Ca={},HN=Object.keys(zy);function bN(i){let u=function(...f){let c=f[0];return c==null?c:(c.length>1&&(f=c),i(f))};return"conversion"in i&&(u.conversion=i.conversion),u}function GN(i){let u=function(...f){let c=f[0];if(c==null)return c;c.length>1&&(f=c);let g=i(f);if(typeof g=="object")for(let t=g.length,C=0;C{Ca[i]={},Object.defineProperty(Ca[i],"channels",{value:zy[i].channels}),Object.defineProperty(Ca[i],"labels",{value:zy[i].labels});let u=WN(i);Object.keys(u).forEach(c=>{let g=u[c];Ca[i][c]=GN(g),Ca[i][c].raw=bN(g)})});FE.exports=Ca});var Rh=Me((kb,RE)=>{"use strict";var NE=(i,u)=>(...f)=>`[${i(...f)+u}m`,BE=(i,u)=>(...f)=>{let c=i(...f);return`[${38+u};5;${c}m`},jE=(i,u)=>(...f)=>{let c=i(...f);return`[${38+u};2;${c[0]};${c[1]};${c[2]}m`},Lh=i=>i,UE=(i,u,f)=>[i,u,f],Ta=(i,u,f)=>{Object.defineProperty(i,u,{get:()=>{let c=f();return Object.defineProperty(i,u,{value:c,enumerable:!0,configurable:!0}),c},enumerable:!0,configurable:!0})},Wy,xa=(i,u,f,c)=>{Wy===void 0&&(Wy=LE());let g=c?10:0,t={};for(let[C,A]of Object.entries(Wy)){let x=C==="ansi16"?"ansi":C;C===u?t[x]=i(f,g):typeof A=="object"&&(t[x]=i(A[u],g))}return t};function VN(){let i=new Map,u={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};u.color.gray=u.color.blackBright,u.bgColor.bgGray=u.bgColor.bgBlackBright,u.color.grey=u.color.blackBright,u.bgColor.bgGrey=u.bgColor.bgBlackBright;for(let[f,c]of Object.entries(u)){for(let[g,t]of Object.entries(c))u[g]={open:`[${t[0]}m`,close:`[${t[1]}m`},c[g]=u[g],i.set(t[0],t[1]);Object.defineProperty(u,f,{value:c,enumerable:!1})}return Object.defineProperty(u,"codes",{value:i,enumerable:!1}),u.color.close="",u.bgColor.close="",Ta(u.color,"ansi",()=>xa(NE,"ansi16",Lh,!1)),Ta(u.color,"ansi256",()=>xa(BE,"ansi256",Lh,!1)),Ta(u.color,"ansi16m",()=>xa(jE,"rgb",UE,!1)),Ta(u.bgColor,"ansi",()=>xa(NE,"ansi16",Lh,!0)),Ta(u.bgColor,"ansi256",()=>xa(BE,"ansi256",Lh,!0)),Ta(u.bgColor,"ansi16m",()=>xa(jE,"rgb",UE,!0)),u}Object.defineProperty(RE,"exports",{enumerable:!0,get:VN})});var WE=Me((Ab,qE)=>{"use strict";var h2=Mh(),YN=Fy(),$N=Rh(),Hy=new Set(["","\x9B"]),KN=39,zE=i=>`${Hy.values().next().value}[${i}m`,XN=i=>i.split(" ").map(u=>h2(u)),by=(i,u,f)=>{let c=[...u],g=!1,t=h2(YN(i[i.length-1]));for(let[C,A]of c.entries()){let x=h2(A);if(t+x<=f?i[i.length-1]+=A:(i.push(A),t=0),Hy.has(A))g=!0;else if(g&&A==="m"){g=!1;continue}g||(t+=x,t===f&&C0&&i.length>1&&(i[i.length-2]+=i.pop())},JN=i=>{let u=i.split(" "),f=u.length;for(;f>0&&!(h2(u[f-1])>0);)f--;return f===u.length?i:u.slice(0,f).join(" ")+u.slice(f).join("")},QN=(i,u,f={})=>{if(f.trim!==!1&&i.trim()==="")return"";let c="",g="",t,C=XN(i),A=[""];for(let[x,D]of i.split(" ").entries()){f.trim!==!1&&(A[A.length-1]=A[A.length-1].trimLeft());let L=h2(A[A.length-1]);if(x!==0&&(L>=u&&(f.wordWrap===!1||f.trim===!1)&&(A.push(""),L=0),(L>0||f.trim===!1)&&(A[A.length-1]+=" ",L++)),f.hard&&C[x]>u){let N=u-L,j=1+Math.floor((C[x]-N-1)/u);Math.floor((C[x]-1)/u)u&&L>0&&C[x]>0){if(f.wordWrap===!1&&Lu&&f.wordWrap===!1){by(A,D,u);continue}A[A.length-1]+=D}f.trim!==!1&&(A=A.map(JN)),c=A.join(` +`);for(let[x,D]of[...c].entries()){if(g+=D,Hy.has(D)){let N=parseFloat(/\d[^m]*/.exec(c.slice(x,x+4)));t=N===KN?null:N}let L=$N.codes.get(Number(t));t&&L&&(c[x+1]===` +`?g+=zE(L):D===` +`&&(g+=zE(t)))}return g};qE.exports=(i,u,f)=>String(i).normalize().replace(/\r\n/g,` +`).split(` +`).map(c=>QN(c,u,f)).join(` +`)});var GE=Me((Ob,HE)=>{"use strict";var bE="[\uD800-\uDBFF][\uDC00-\uDFFF]",ZN=i=>i&&i.exact?new RegExp(`^${bE}$`):new RegExp(bE,"g");HE.exports=ZN});var Gy=Me((Ib,VE)=>{"use strict";var eB=Ry(),tB=GE(),YE=Rh(),$E=["","\x9B"],Nh=i=>`${$E[0]}[${i}m`,KE=(i,u,f)=>{let c=[];i=[...i];for(let g of i){let t=g;g.match(";")&&(g=g.split(";")[0][0]+"0");let C=YE.codes.get(parseInt(g,10));if(C){let A=i.indexOf(C.toString());A>=0?i.splice(A,1):c.push(Nh(u?C:t))}else if(u){c.push(Nh(0));break}else c.push(Nh(t))}if(u&&(c=c.filter((g,t)=>c.indexOf(g)===t),f!==void 0)){let g=Nh(YE.codes.get(parseInt(f,10)));c=c.reduce((t,C)=>C===g?[C,...t]:[...t,C],[])}return c.join("")};VE.exports=(i,u,f)=>{let c=[...i.normalize()],g=[];f=typeof f=="number"?f:c.length;let t=!1,C,A=0,x="";for(let[D,L]of c.entries()){let N=!1;if($E.includes(L)){let j=/\d[^m]*/.exec(i.slice(D,D+18));C=j&&j.length>0?j[0]:void 0,Au&&A<=f)x+=L;else if(A===u&&!t&&C!==void 0)x=KE(g);else if(A>=f){x+=KE(g,!0,C);break}}return x}});var JE=Me((Pb,XE)=>{"use strict";var Bf=Gy(),nB=Mh();function Bh(i,u,f){if(i.charAt(u)===" ")return u;for(let c=1;c<=3;c++)if(f){if(i.charAt(u+c)===" ")return u+c}else if(i.charAt(u-c)===" ")return u-c;return u}XE.exports=(i,u,f)=>{f=dt({position:"end",preferTruncationOnSpace:!1},f);let{position:c,space:g,preferTruncationOnSpace:t}=f,C="\u2026",A=1;if(typeof i!="string")throw new TypeError(`Expected \`input\` to be a string, got ${typeof i}`);if(typeof u!="number")throw new TypeError(`Expected \`columns\` to be a number, got ${typeof u}`);if(u<1)return"";if(u===1)return C;let x=nB(i);if(x<=u)return i;if(c==="start"){if(t){let D=Bh(i,x-u+1,!0);return C+Bf(i,D,x).trim()}return g===!0&&(C+=" ",A=2),C+Bf(i,x-u+A,x)}if(c==="middle"){g===!0&&(C=" "+C+" ",A=3);let D=Math.floor(u/2);if(t){let L=Bh(i,D),N=Bh(i,x-(u-D)+1,!0);return Bf(i,0,L)+C+Bf(i,N,x).trim()}return Bf(i,0,D)+C+Bf(i,x-(u-D)+A,x)}if(c==="end"){if(t){let D=Bh(i,u-1);return Bf(i,0,D)+C}return g===!0&&(C=" "+C,A=2),Bf(i,0,u-A)+C}throw new Error(`Expected \`options.position\` to be either \`start\`, \`middle\` or \`end\`, got ${c}`)}});var Yy=Me(m2=>{"use strict";var QE=m2&&m2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(m2,"__esModule",{value:!0});var rB=QE(WE()),iB=QE(JE()),Vy={};m2.default=(i,u,f)=>{let c=i+String(u)+String(f);if(Vy[c])return Vy[c];let g=i;if(f==="wrap"&&(g=rB.default(i,u,{trim:!1,hard:!0})),f.startsWith("truncate")){let t="end";f==="truncate-middle"&&(t="middle"),f==="truncate-start"&&(t="start"),g=iB.default(i,u,{position:t})}return Vy[c]=g,g}});var Ky=Me($y=>{"use strict";Object.defineProperty($y,"__esModule",{value:!0});var ZE=i=>{let u="";if(i.childNodes.length>0)for(let f of i.childNodes){let c="";f.nodeName==="#text"?c=f.nodeValue:((f.nodeName==="ink-text"||f.nodeName==="ink-virtual-text")&&(c=ZE(f)),c.length>0&&typeof f.internal_transform=="function"&&(c=f.internal_transform(c))),u+=c}return u};$y.default=ZE});var Xy=Me(Zr=>{"use strict";var v2=Zr&&Zr.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Zr,"__esModule",{value:!0});Zr.setTextNodeValue=Zr.createTextNode=Zr.setStyle=Zr.setAttribute=Zr.removeChildNode=Zr.insertBeforeNode=Zr.appendChildNode=Zr.createNode=Zr.TEXT_NAME=void 0;var oB=v2(hc()),e6=v2(TE()),uB=v2(xE()),sB=v2(Yy()),lB=v2(Ky());Zr.TEXT_NAME="#text";Zr.createNode=i=>{var u;let f={nodeName:i,style:{},attributes:{},childNodes:[],parentNode:null,yogaNode:i==="ink-virtual-text"?void 0:oB.default.Node.create()};return i==="ink-text"&&((u=f.yogaNode)===null||u===void 0||u.setMeasureFunc(fB.bind(null,f))),f};Zr.appendChildNode=(i,u)=>{var f;u.parentNode&&Zr.removeChildNode(u.parentNode,u),u.parentNode=i,i.childNodes.push(u),u.yogaNode&&((f=i.yogaNode)===null||f===void 0||f.insertChild(u.yogaNode,i.yogaNode.getChildCount())),(i.nodeName==="ink-text"||i.nodeName==="ink-virtual-text")&&jh(i)};Zr.insertBeforeNode=(i,u,f)=>{var c,g;u.parentNode&&Zr.removeChildNode(u.parentNode,u),u.parentNode=i;let t=i.childNodes.indexOf(f);if(t>=0){i.childNodes.splice(t,0,u),u.yogaNode&&((c=i.yogaNode)===null||c===void 0||c.insertChild(u.yogaNode,t));return}i.childNodes.push(u),u.yogaNode&&((g=i.yogaNode)===null||g===void 0||g.insertChild(u.yogaNode,i.yogaNode.getChildCount())),(i.nodeName==="ink-text"||i.nodeName==="ink-virtual-text")&&jh(i)};Zr.removeChildNode=(i,u)=>{var f,c;u.yogaNode&&((c=(f=u.parentNode)===null||f===void 0?void 0:f.yogaNode)===null||c===void 0||c.removeChild(u.yogaNode)),u.parentNode=null;let g=i.childNodes.indexOf(u);g>=0&&i.childNodes.splice(g,1),(i.nodeName==="ink-text"||i.nodeName==="ink-virtual-text")&&jh(i)};Zr.setAttribute=(i,u,f)=>{i.attributes[u]=f};Zr.setStyle=(i,u)=>{i.style=u,i.yogaNode&&uB.default(i.yogaNode,u)};Zr.createTextNode=i=>{let u={nodeName:"#text",nodeValue:i,yogaNode:void 0,parentNode:null,style:{}};return Zr.setTextNodeValue(u,i),u};var fB=function(i,u){var f,c;let g=i.nodeName==="#text"?i.nodeValue:lB.default(i),t=e6.default(g);if(t.width<=u||t.width>=1&&u>0&&u<1)return t;let C=(c=(f=i.style)===null||f===void 0?void 0:f.textWrap)!==null&&c!==void 0?c:"wrap",A=sB.default(g,u,C);return e6.default(A)},t6=i=>{var u;if(!(!i||!i.parentNode))return(u=i.yogaNode)!==null&&u!==void 0?u:t6(i.parentNode)},jh=i=>{let u=t6(i);u==null||u.markDirty()};Zr.setTextNodeValue=(i,u)=>{typeof u!="string"&&(u=String(u)),i.nodeValue=u,jh(i)}});var mc=Me((Rb,n6)=>{"use strict";n6.exports={BINARY_TYPES:["nodebuffer","arraybuffer","fragments"],GUID:"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",kStatusCode:Symbol("status-code"),kWebSocket:Symbol("websocket"),EMPTY_BUFFER:Buffer.alloc(0),NOOP:()=>{}}});var g2=Me((Nb,Jy)=>{"use strict";var{EMPTY_BUFFER:cB}=mc();function r6(i,u){if(i.length===0)return cB;if(i.length===1)return i[0];let f=Buffer.allocUnsafe(u),c=0;for(let g=0;g{"use strict";var l6=Symbol("kDone"),Qy=Symbol("kRun"),f6=class{constructor(u){this[l6]=()=>{this.pending--,this[Qy]()},this.concurrency=u||Infinity,this.jobs=[],this.pending=0}add(u){this.jobs.push(u),this[Qy]()}[Qy](){if(this.pending!==this.concurrency&&this.jobs.length){let u=this.jobs.shift();this.pending++,u(this[l6])}}};s6.exports=f6});var w2=Me((jb,a6)=>{"use strict";var _2=require("zlib"),d6=g2(),aB=c6(),{kStatusCode:p6,NOOP:dB}=mc(),pB=Buffer.from([0,0,255,255]),qh=Symbol("permessage-deflate"),Xl=Symbol("total-length"),y2=Symbol("callback"),jf=Symbol("buffers"),Zy=Symbol("error"),zh,h6=class{constructor(u,f,c){if(this._maxPayload=c|0,this._options=u||{},this._threshold=this._options.threshold!==void 0?this._options.threshold:1024,this._isServer=!!f,this._deflate=null,this._inflate=null,this.params=null,!zh){let g=this._options.concurrencyLimit!==void 0?this._options.concurrencyLimit:10;zh=new aB(g)}}static get extensionName(){return"permessage-deflate"}offer(){let u={};return this._options.serverNoContextTakeover&&(u.server_no_context_takeover=!0),this._options.clientNoContextTakeover&&(u.client_no_context_takeover=!0),this._options.serverMaxWindowBits&&(u.server_max_window_bits=this._options.serverMaxWindowBits),this._options.clientMaxWindowBits?u.client_max_window_bits=this._options.clientMaxWindowBits:this._options.clientMaxWindowBits==null&&(u.client_max_window_bits=!0),u}accept(u){return u=this.normalizeParams(u),this.params=this._isServer?this.acceptAsServer(u):this.acceptAsClient(u),this.params}cleanup(){if(this._inflate&&(this._inflate.close(),this._inflate=null),this._deflate){let u=this._deflate[y2];this._deflate.close(),this._deflate=null,u&&u(new Error("The deflate stream was closed while data was being processed"))}}acceptAsServer(u){let f=this._options,c=u.find(g=>!(f.serverNoContextTakeover===!1&&g.server_no_context_takeover||g.server_max_window_bits&&(f.serverMaxWindowBits===!1||typeof f.serverMaxWindowBits=="number"&&f.serverMaxWindowBits>g.server_max_window_bits)||typeof f.clientMaxWindowBits=="number"&&!g.client_max_window_bits));if(!c)throw new Error("None of the extension offers can be accepted");return f.serverNoContextTakeover&&(c.server_no_context_takeover=!0),f.clientNoContextTakeover&&(c.client_no_context_takeover=!0),typeof f.serverMaxWindowBits=="number"&&(c.server_max_window_bits=f.serverMaxWindowBits),typeof f.clientMaxWindowBits=="number"?c.client_max_window_bits=f.clientMaxWindowBits:(c.client_max_window_bits===!0||f.clientMaxWindowBits===!1)&&delete c.client_max_window_bits,c}acceptAsClient(u){let f=u[0];if(this._options.clientNoContextTakeover===!1&&f.client_no_context_takeover)throw new Error('Unexpected parameter "client_no_context_takeover"');if(!f.client_max_window_bits)typeof this._options.clientMaxWindowBits=="number"&&(f.client_max_window_bits=this._options.clientMaxWindowBits);else if(this._options.clientMaxWindowBits===!1||typeof this._options.clientMaxWindowBits=="number"&&f.client_max_window_bits>this._options.clientMaxWindowBits)throw new Error('Unexpected or invalid parameter "client_max_window_bits"');return f}normalizeParams(u){return u.forEach(f=>{Object.keys(f).forEach(c=>{let g=f[c];if(g.length>1)throw new Error(`Parameter "${c}" must have only a single value`);if(g=g[0],c==="client_max_window_bits"){if(g!==!0){let t=+g;if(!Number.isInteger(t)||t<8||t>15)throw new TypeError(`Invalid value for parameter "${c}": ${g}`);g=t}else if(!this._isServer)throw new TypeError(`Invalid value for parameter "${c}": ${g}`)}else if(c==="server_max_window_bits"){let t=+g;if(!Number.isInteger(t)||t<8||t>15)throw new TypeError(`Invalid value for parameter "${c}": ${g}`);g=t}else if(c==="client_no_context_takeover"||c==="server_no_context_takeover"){if(g!==!0)throw new TypeError(`Invalid value for parameter "${c}": ${g}`)}else throw new Error(`Unknown parameter "${c}"`);f[c]=g})}),u}decompress(u,f,c){zh.add(g=>{this._decompress(u,f,(t,C)=>{g(),c(t,C)})})}compress(u,f,c){zh.add(g=>{this._compress(u,f,(t,C)=>{g(),c(t,C)})})}_decompress(u,f,c){let g=this._isServer?"client":"server";if(!this._inflate){let t=`${g}_max_window_bits`,C=typeof this.params[t]!="number"?_2.Z_DEFAULT_WINDOWBITS:this.params[t];this._inflate=_2.createInflateRaw(zn(dt({},this._options.zlibInflateOptions),{windowBits:C})),this._inflate[qh]=this,this._inflate[Xl]=0,this._inflate[jf]=[],this._inflate.on("error",mB),this._inflate.on("data",m6)}this._inflate[y2]=c,this._inflate.write(u),f&&this._inflate.write(pB),this._inflate.flush(()=>{let t=this._inflate[Zy];if(t){this._inflate.close(),this._inflate=null,c(t);return}let C=d6.concat(this._inflate[jf],this._inflate[Xl]);this._inflate._readableState.endEmitted?(this._inflate.close(),this._inflate=null):(this._inflate[Xl]=0,this._inflate[jf]=[],f&&this.params[`${g}_no_context_takeover`]&&this._inflate.reset()),c(null,C)})}_compress(u,f,c){let g=this._isServer?"server":"client";if(!this._deflate){let t=`${g}_max_window_bits`,C=typeof this.params[t]!="number"?_2.Z_DEFAULT_WINDOWBITS:this.params[t];this._deflate=_2.createDeflateRaw(zn(dt({},this._options.zlibDeflateOptions),{windowBits:C})),this._deflate[Xl]=0,this._deflate[jf]=[],this._deflate.on("error",dB),this._deflate.on("data",hB)}this._deflate[y2]=c,this._deflate.write(u),this._deflate.flush(_2.Z_SYNC_FLUSH,()=>{if(!this._deflate)return;let t=d6.concat(this._deflate[jf],this._deflate[Xl]);f&&(t=t.slice(0,t.length-4)),this._deflate[y2]=null,this._deflate[Xl]=0,this._deflate[jf]=[],f&&this.params[`${g}_no_context_takeover`]&&this._deflate.reset(),c(null,t)})}};a6.exports=h6;function hB(i){this[jf].push(i),this[Xl]+=i.length}function m6(i){if(this[Xl]+=i.length,this[qh]._maxPayload<1||this[Xl]<=this[qh]._maxPayload){this[jf].push(i);return}this[Zy]=new RangeError("Max payload size exceeded"),this[Zy][p6]=1009,this.removeListener("data",m6),this.reset()}function mB(i){this[qh]._inflate=null,i[p6]=1007,this[y2](i)}});var t3=Me((Ub,e3)=>{"use strict";function v6(i){return i>=1e3&&i<=1014&&i!==1004&&i!==1005&&i!==1006||i>=3e3&&i<=4999}function g6(i){let u=i.length,f=0;for(;f=u||(i[f+1]&192)!=128||(i[f+2]&192)!=128||i[f]===224&&(i[f+1]&224)==128||i[f]===237&&(i[f+1]&224)==160)return!1;f+=3}else if((i[f]&248)==240){if(f+3>=u||(i[f+1]&192)!=128||(i[f+2]&192)!=128||(i[f+3]&192)!=128||i[f]===240&&(i[f+1]&240)==128||i[f]===244&&i[f+1]>143||i[f]>244)return!1;f+=4}else return!1;return!0}try{let i=require("utf-8-validate");typeof i=="object"&&(i=i.Validation.isValidUTF8),e3.exports={isValidStatusCode:v6,isValidUTF8(u){return u.length<150?g6(u):i(u)}}}catch(i){e3.exports={isValidStatusCode:v6,isValidUTF8:g6}}});var i3=Me((qb,_6)=>{"use strict";var{Writable:vB}=require("stream"),y6=w2(),{BINARY_TYPES:gB,EMPTY_BUFFER:_B,kStatusCode:yB,kWebSocket:wB}=mc(),{concat:n3,toArrayBuffer:DB,unmask:EB}=g2(),{isValidStatusCode:SB,isValidUTF8:w6}=t3(),D2=0,D6=1,E6=2,S6=3,r3=4,CB=5,C6=class extends vB{constructor(u,f,c,g){super();this._binaryType=u||gB[0],this[wB]=void 0,this._extensions=f||{},this._isServer=!!c,this._maxPayload=g|0,this._bufferedBytes=0,this._buffers=[],this._compressed=!1,this._payloadLength=0,this._mask=void 0,this._fragmented=0,this._masked=!1,this._fin=!1,this._opcode=0,this._totalPayloadLength=0,this._messageLength=0,this._fragments=[],this._state=D2,this._loop=!1}_write(u,f,c){if(this._opcode===8&&this._state==D2)return c();this._bufferedBytes+=u.length,this._buffers.push(u),this.startLoop(c)}consume(u){if(this._bufferedBytes-=u,u===this._buffers[0].length)return this._buffers.shift();if(u=c.length?f.set(this._buffers.shift(),g):(f.set(new Uint8Array(c.buffer,c.byteOffset,u),g),this._buffers[0]=c.slice(u)),u-=c.length}while(u>0);return f}startLoop(u){let f;this._loop=!0;do switch(this._state){case D2:f=this.getInfo();break;case D6:f=this.getPayloadLength16();break;case E6:f=this.getPayloadLength64();break;case S6:this.getMask();break;case r3:f=this.getData(u);break;default:this._loop=!1;return}while(this._loop);u(f)}getInfo(){if(this._bufferedBytes<2){this._loop=!1;return}let u=this.consume(2);if((u[0]&48)!=0)return this._loop=!1,ii(RangeError,"RSV2 and RSV3 must be clear",!0,1002);let f=(u[0]&64)==64;if(f&&!this._extensions[y6.extensionName])return this._loop=!1,ii(RangeError,"RSV1 must be clear",!0,1002);if(this._fin=(u[0]&128)==128,this._opcode=u[0]&15,this._payloadLength=u[1]&127,this._opcode===0){if(f)return this._loop=!1,ii(RangeError,"RSV1 must be clear",!0,1002);if(!this._fragmented)return this._loop=!1,ii(RangeError,"invalid opcode 0",!0,1002);this._opcode=this._fragmented}else if(this._opcode===1||this._opcode===2){if(this._fragmented)return this._loop=!1,ii(RangeError,`invalid opcode ${this._opcode}`,!0,1002);this._compressed=f}else if(this._opcode>7&&this._opcode<11){if(!this._fin)return this._loop=!1,ii(RangeError,"FIN must be set",!0,1002);if(f)return this._loop=!1,ii(RangeError,"RSV1 must be clear",!0,1002);if(this._payloadLength>125)return this._loop=!1,ii(RangeError,`invalid payload length ${this._payloadLength}`,!0,1002)}else return this._loop=!1,ii(RangeError,`invalid opcode ${this._opcode}`,!0,1002);if(!this._fin&&!this._fragmented&&(this._fragmented=this._opcode),this._masked=(u[1]&128)==128,this._isServer){if(!this._masked)return this._loop=!1,ii(RangeError,"MASK must be set",!0,1002)}else if(this._masked)return this._loop=!1,ii(RangeError,"MASK must be clear",!0,1002);if(this._payloadLength===126)this._state=D6;else if(this._payloadLength===127)this._state=E6;else return this.haveLength()}getPayloadLength16(){if(this._bufferedBytes<2){this._loop=!1;return}return this._payloadLength=this.consume(2).readUInt16BE(0),this.haveLength()}getPayloadLength64(){if(this._bufferedBytes<8){this._loop=!1;return}let u=this.consume(8),f=u.readUInt32BE(0);return f>Math.pow(2,53-32)-1?(this._loop=!1,ii(RangeError,"Unsupported WebSocket frame: payload length > 2^53 - 1",!1,1009)):(this._payloadLength=f*Math.pow(2,32)+u.readUInt32BE(4),this.haveLength())}haveLength(){if(this._payloadLength&&this._opcode<8&&(this._totalPayloadLength+=this._payloadLength,this._totalPayloadLength>this._maxPayload&&this._maxPayload>0))return this._loop=!1,ii(RangeError,"Max payload size exceeded",!1,1009);this._masked?this._state=S6:this._state=r3}getMask(){if(this._bufferedBytes<4){this._loop=!1;return}this._mask=this.consume(4),this._state=r3}getData(u){let f=_B;if(this._payloadLength){if(this._bufferedBytes7)return this.controlMessage(f);if(this._compressed){this._state=CB,this.decompress(f,u);return}return f.length&&(this._messageLength=this._totalPayloadLength,this._fragments.push(f)),this.dataMessage()}decompress(u,f){this._extensions[y6.extensionName].decompress(u,this._fin,(g,t)=>{if(g)return f(g);if(t.length){if(this._messageLength+=t.length,this._messageLength>this._maxPayload&&this._maxPayload>0)return f(ii(RangeError,"Max payload size exceeded",!1,1009));this._fragments.push(t)}let C=this.dataMessage();if(C)return f(C);this.startLoop(f)})}dataMessage(){if(this._fin){let u=this._messageLength,f=this._fragments;if(this._totalPayloadLength=0,this._messageLength=0,this._fragmented=0,this._fragments=[],this._opcode===2){let c;this._binaryType==="nodebuffer"?c=n3(f,u):this._binaryType==="arraybuffer"?c=DB(n3(f,u)):c=f,this.emit("message",c)}else{let c=n3(f,u);if(!w6(c))return this._loop=!1,ii(Error,"invalid UTF-8 sequence",!0,1007);this.emit("message",c.toString())}}this._state=D2}controlMessage(u){if(this._opcode===8)if(this._loop=!1,u.length===0)this.emit("conclude",1005,""),this.end();else{if(u.length===1)return ii(RangeError,"invalid payload length 1",!0,1002);{let f=u.readUInt16BE(0);if(!SB(f))return ii(RangeError,`invalid status code ${f}`,!0,1002);let c=u.slice(2);if(!w6(c))return ii(Error,"invalid UTF-8 sequence",!0,1007);this.emit("conclude",f,c.toString()),this.end()}}else this._opcode===9?this.emit("ping",u):this.emit("pong",u);this._state=D2}};_6.exports=C6;function ii(i,u,f,c){let g=new i(f?`Invalid WebSocket frame: ${u}`:u);return Error.captureStackTrace(g,ii),g[yB]=c,g}});var o3=Me((zb,T6)=>{"use strict";var{randomFillSync:TB}=require("crypto"),x6=w2(),{EMPTY_BUFFER:xB}=mc(),{isValidStatusCode:kB}=t3(),{mask:k6,toBuffer:Jl}=g2(),vc=Buffer.alloc(4),Ql=class{constructor(u,f){this._extensions=f||{},this._socket=u,this._firstFragment=!0,this._compress=!1,this._bufferedBytes=0,this._deflating=!1,this._queue=[]}static frame(u,f){let c=f.mask&&f.readOnly,g=f.mask?6:2,t=u.length;u.length>=65536?(g+=8,t=127):u.length>125&&(g+=2,t=126);let C=Buffer.allocUnsafe(c?u.length+g:g);return C[0]=f.fin?f.opcode|128:f.opcode,f.rsv1&&(C[0]|=64),C[1]=t,t===126?C.writeUInt16BE(u.length,2):t===127&&(C.writeUInt32BE(0,2),C.writeUInt32BE(u.length,6)),f.mask?(TB(vc,0,4),C[1]|=128,C[g-4]=vc[0],C[g-3]=vc[1],C[g-2]=vc[2],C[g-1]=vc[3],c?(k6(u,vc,C,g,u.length),[C]):(k6(u,vc,u,0,u.length),[C,u])):[C,u]}close(u,f,c,g){let t;if(u===void 0)t=xB;else{if(typeof u!="number"||!kB(u))throw new TypeError("First argument must be a valid error code number");if(f===void 0||f==="")t=Buffer.allocUnsafe(2),t.writeUInt16BE(u,0);else{let C=Buffer.byteLength(f);if(C>123)throw new RangeError("The message must not be greater than 123 bytes");t=Buffer.allocUnsafe(2+C),t.writeUInt16BE(u,0),t.write(f,2)}}this._deflating?this.enqueue([this.doClose,t,c,g]):this.doClose(t,c,g)}doClose(u,f,c){this.sendFrame(Ql.frame(u,{fin:!0,rsv1:!1,opcode:8,mask:f,readOnly:!1}),c)}ping(u,f,c){let g=Jl(u);if(g.length>125)throw new RangeError("The data size must not be greater than 125 bytes");this._deflating?this.enqueue([this.doPing,g,f,Jl.readOnly,c]):this.doPing(g,f,Jl.readOnly,c)}doPing(u,f,c,g){this.sendFrame(Ql.frame(u,{fin:!0,rsv1:!1,opcode:9,mask:f,readOnly:c}),g)}pong(u,f,c){let g=Jl(u);if(g.length>125)throw new RangeError("The data size must not be greater than 125 bytes");this._deflating?this.enqueue([this.doPong,g,f,Jl.readOnly,c]):this.doPong(g,f,Jl.readOnly,c)}doPong(u,f,c,g){this.sendFrame(Ql.frame(u,{fin:!0,rsv1:!1,opcode:10,mask:f,readOnly:c}),g)}send(u,f,c){let g=Jl(u),t=this._extensions[x6.extensionName],C=f.binary?2:1,A=f.compress;if(this._firstFragment?(this._firstFragment=!1,A&&t&&(A=g.length>=t._threshold),this._compress=A):(A=!1,C=0),f.fin&&(this._firstFragment=!0),t){let x={fin:f.fin,rsv1:A,opcode:C,mask:f.mask,readOnly:Jl.readOnly};this._deflating?this.enqueue([this.dispatch,g,this._compress,x,c]):this.dispatch(g,this._compress,x,c)}else this.sendFrame(Ql.frame(g,{fin:f.fin,rsv1:!1,opcode:C,mask:f.mask,readOnly:Jl.readOnly}),c)}dispatch(u,f,c,g){if(!f){this.sendFrame(Ql.frame(u,c),g);return}let t=this._extensions[x6.extensionName];this._bufferedBytes+=u.length,this._deflating=!0,t.compress(u,c.fin,(C,A)=>{if(this._socket.destroyed){let x=new Error("The socket was closed while data was being compressed");typeof g=="function"&&g(x);for(let D=0;D{"use strict";var E2=class{constructor(u,f){this.target=f,this.type=u}},O6=class extends E2{constructor(u,f){super("message",f);this.data=u}},I6=class extends E2{constructor(u,f,c){super("close",c);this.wasClean=c._closeFrameReceived&&c._closeFrameSent,this.reason=f,this.code=u}},P6=class extends E2{constructor(u){super("open",u)}},M6=class extends E2{constructor(u,f){super("error",f);this.message=u.message,this.error=u}},AB={addEventListener(i,u,f){if(typeof u!="function")return;function c(x){u.call(this,new O6(x,this))}function g(x,D){u.call(this,new I6(x,D,this))}function t(x){u.call(this,new M6(x,this))}function C(){u.call(this,new P6(this))}let A=f&&f.once?"once":"on";i==="message"?(c._listener=u,this[A](i,c)):i==="close"?(g._listener=u,this[A](i,g)):i==="error"?(t._listener=u,this[A](i,t)):i==="open"?(C._listener=u,this[A](i,C)):this[A](i,u)},removeEventListener(i,u){let f=this.listeners(i);for(let c=0;c{"use strict";var S2=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0];function rl(i,u,f){i[u]===void 0?i[u]=[f]:i[u].push(f)}function OB(i){let u=Object.create(null);if(i===void 0||i==="")return u;let f=Object.create(null),c=!1,g=!1,t=!1,C,A,x=-1,D=-1,L=0;for(;L{let f=i[u];return Array.isArray(f)||(f=[f]),f.map(c=>[u].concat(Object.keys(c).map(g=>{let t=c[g];return Array.isArray(t)||(t=[t]),t.map(C=>C===!0?g:`${g}=${C}`).join("; ")})).join("; ")).join(", ")}).join(", ")}L6.exports={format:IB,parse:OB}});var a3=Me((bb,R6)=>{"use strict";var PB=require("events"),MB=require("https"),FB=require("http"),N6=require("net"),LB=require("tls"),{randomBytes:RB,createHash:NB}=require("crypto"),{URL:s3}=require("url"),Uf=w2(),BB=i3(),jB=o3(),{BINARY_TYPES:B6,EMPTY_BUFFER:l3,GUID:UB,kStatusCode:qB,kWebSocket:No,NOOP:j6}=mc(),{addEventListener:zB,removeEventListener:WB}=F6(),{format:HB,parse:bB}=u3(),{toBuffer:GB}=g2(),U6=["CONNECTING","OPEN","CLOSING","CLOSED"],f3=[8,13],VB=30*1e3,mr=class extends PB{constructor(u,f,c){super();this._binaryType=B6[0],this._closeCode=1006,this._closeFrameReceived=!1,this._closeFrameSent=!1,this._closeMessage="",this._closeTimer=null,this._extensions={},this._protocol="",this._readyState=mr.CONNECTING,this._receiver=null,this._sender=null,this._socket=null,u!==null?(this._bufferedAmount=0,this._isServer=!1,this._redirects=0,Array.isArray(f)?f=f.join(", "):typeof f=="object"&&f!==null&&(c=f,f=void 0),q6(this,u,f,c)):this._isServer=!0}get binaryType(){return this._binaryType}set binaryType(u){!B6.includes(u)||(this._binaryType=u,this._receiver&&(this._receiver._binaryType=u))}get bufferedAmount(){return this._socket?this._socket._writableState.length+this._sender._bufferedBytes:this._bufferedAmount}get extensions(){return Object.keys(this._extensions).join()}get protocol(){return this._protocol}get readyState(){return this._readyState}get url(){return this._url}setSocket(u,f,c){let g=new BB(this.binaryType,this._extensions,this._isServer,c);this._sender=new jB(u,this._extensions),this._receiver=g,this._socket=u,g[No]=this,u[No]=this,g.on("conclude",YB),g.on("drain",$B),g.on("error",KB),g.on("message",XB),g.on("ping",JB),g.on("pong",QB),u.setTimeout(0),u.setNoDelay(),f.length>0&&u.unshift(f),u.on("close",z6),u.on("data",Wh),u.on("end",W6),u.on("error",H6),this._readyState=mr.OPEN,this.emit("open")}emitClose(){if(!this._socket){this._readyState=mr.CLOSED,this.emit("close",this._closeCode,this._closeMessage);return}this._extensions[Uf.extensionName]&&this._extensions[Uf.extensionName].cleanup(),this._receiver.removeAllListeners(),this._readyState=mr.CLOSED,this.emit("close",this._closeCode,this._closeMessage)}close(u,f){if(this.readyState!==mr.CLOSED){if(this.readyState===mr.CONNECTING){let c="WebSocket was closed before the connection was established";return Zl(this,this._req,c)}if(this.readyState===mr.CLOSING){this._closeFrameSent&&this._closeFrameReceived&&this._socket.end();return}this._readyState=mr.CLOSING,this._sender.close(u,f,!this._isServer,c=>{c||(this._closeFrameSent=!0,this._closeFrameReceived&&this._socket.end())}),this._closeTimer=setTimeout(this._socket.destroy.bind(this._socket),VB)}}ping(u,f,c){if(this.readyState===mr.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof u=="function"?(c=u,u=f=void 0):typeof f=="function"&&(c=f,f=void 0),typeof u=="number"&&(u=u.toString()),this.readyState!==mr.OPEN){c3(this,u,c);return}f===void 0&&(f=!this._isServer),this._sender.ping(u||l3,f,c)}pong(u,f,c){if(this.readyState===mr.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof u=="function"?(c=u,u=f=void 0):typeof f=="function"&&(c=f,f=void 0),typeof u=="number"&&(u=u.toString()),this.readyState!==mr.OPEN){c3(this,u,c);return}f===void 0&&(f=!this._isServer),this._sender.pong(u||l3,f,c)}send(u,f,c){if(this.readyState===mr.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof f=="function"&&(c=f,f={}),typeof u=="number"&&(u=u.toString()),this.readyState!==mr.OPEN){c3(this,u,c);return}let g=dt({binary:typeof u!="string",mask:!this._isServer,compress:!0,fin:!0},f);this._extensions[Uf.extensionName]||(g.compress=!1),this._sender.send(u||l3,g,c)}terminate(){if(this.readyState!==mr.CLOSED){if(this.readyState===mr.CONNECTING){let u="WebSocket was closed before the connection was established";return Zl(this,this._req,u)}this._socket&&(this._readyState=mr.CLOSING,this._socket.destroy())}}};U6.forEach((i,u)=>{let f={enumerable:!0,value:u};Object.defineProperty(mr.prototype,i,f),Object.defineProperty(mr,i,f)});["binaryType","bufferedAmount","extensions","protocol","readyState","url"].forEach(i=>{Object.defineProperty(mr.prototype,i,{enumerable:!0})});["open","error","close","message"].forEach(i=>{Object.defineProperty(mr.prototype,`on${i}`,{configurable:!0,enumerable:!0,get(){let u=this.listeners(i);for(let f=0;f{Zl(i,j,"Opening handshake has timed out")}),j.on("error",$=>{j===null||j.aborted||(j=i._req=null,i._readyState=mr.CLOSING,i.emit("error",$),i.emitClose())}),j.on("response",$=>{let h=$.headers.location,re=$.statusCode;if(h&&g.followRedirects&&re>=300&&re<400){if(++i._redirects>g.maxRedirects){Zl(i,j,"Maximum redirects exceeded");return}j.abort();let ce=new s3(h,u);q6(i,ce,f,c)}else i.emit("unexpected-response",j,$)||Zl(i,j,`Unexpected server response: ${$.statusCode}`)}),j.on("upgrade",($,h,re)=>{if(i.emit("upgrade",$),i.readyState!==mr.CONNECTING)return;j=i._req=null;let ce=NB("sha1").update(D+UB).digest("base64");if($.headers["sec-websocket-accept"]!==ce){Zl(i,h,"Invalid Sec-WebSocket-Accept header");return}let Q=$.headers["sec-websocket-protocol"],oe=(f||"").split(/, */),Se;if(!f&&Q?Se="Server sent a subprotocol but none was requested":f&&!Q?Se="Server sent no subprotocol":Q&&!oe.includes(Q)&&(Se="Server sent an invalid subprotocol"),Se){Zl(i,h,Se);return}if(Q&&(i._protocol=Q),N)try{let me=bB($.headers["sec-websocket-extensions"]);me[Uf.extensionName]&&(N.accept(me[Uf.extensionName]),i._extensions[Uf.extensionName]=N)}catch(me){Zl(i,h,"Invalid Sec-WebSocket-Extensions header");return}i.setSocket(h,re,g.maxPayload)})}function ZB(i){return i.path=i.socketPath,N6.connect(i)}function ej(i){return i.path=void 0,!i.servername&&i.servername!==""&&(i.servername=N6.isIP(i.host)?"":i.host),LB.connect(i)}function Zl(i,u,f){i._readyState=mr.CLOSING;let c=new Error(f);Error.captureStackTrace(c,Zl),u.setHeader?(u.abort(),u.socket&&!u.socket.destroyed&&u.socket.destroy(),u.once("abort",i.emitClose.bind(i)),i.emit("error",c)):(u.destroy(c),u.once("error",i.emit.bind(i,"error")),u.once("close",i.emitClose.bind(i)))}function c3(i,u,f){if(u){let c=GB(u).length;i._socket?i._sender._bufferedBytes+=c:i._bufferedAmount+=c}if(f){let c=new Error(`WebSocket is not open: readyState ${i.readyState} (${U6[i.readyState]})`);f(c)}}function YB(i,u){let f=this[No];f._socket.removeListener("data",Wh),f._socket.resume(),f._closeFrameReceived=!0,f._closeMessage=u,f._closeCode=i,i===1005?f.close():f.close(i,u)}function $B(){this[No]._socket.resume()}function KB(i){let u=this[No];u._socket.removeListener("data",Wh),u._readyState=mr.CLOSING,u._closeCode=i[qB],u.emit("error",i),u._socket.destroy()}function b6(){this[No].emitClose()}function XB(i){this[No].emit("message",i)}function JB(i){let u=this[No];u.pong(i,!u._isServer,j6),u.emit("ping",i)}function QB(i){this[No].emit("pong",i)}function z6(){let i=this[No];this.removeListener("close",z6),this.removeListener("end",W6),i._readyState=mr.CLOSING,i._socket.read(),i._receiver.end(),this.removeListener("data",Wh),this[No]=void 0,clearTimeout(i._closeTimer),i._receiver._writableState.finished||i._receiver._writableState.errorEmitted?i.emitClose():(i._receiver.on("error",b6),i._receiver.on("finish",b6))}function Wh(i){this[No]._receiver.write(i)||this.pause()}function W6(){let i=this[No];i._readyState=mr.CLOSING,i._receiver.end(),this.end()}function H6(){let i=this[No];this.removeListener("error",H6),this.on("error",j6),i&&(i._readyState=mr.CLOSING,this.destroy())}});var $6=Me((Gb,G6)=>{"use strict";var{Duplex:tj}=require("stream");function V6(i){i.emit("close")}function nj(){!this.destroyed&&this._writableState.finished&&this.destroy()}function Y6(i){this.removeListener("error",Y6),this.destroy(),this.listenerCount("error")===0&&this.emit("error",i)}function rj(i,u){let f=!0;function c(){f&&i._socket.resume()}i.readyState===i.CONNECTING?i.once("open",function(){i._receiver.removeAllListeners("drain"),i._receiver.on("drain",c)}):(i._receiver.removeAllListeners("drain"),i._receiver.on("drain",c));let g=new tj(zn(dt({},u),{autoDestroy:!1,emitClose:!1,objectMode:!1,writableObjectMode:!1}));return i.on("message",function(C){g.push(C)||(f=!1,i._socket.pause())}),i.once("error",function(C){g.destroyed||g.destroy(C)}),i.once("close",function(){g.destroyed||g.push(null)}),g._destroy=function(t,C){if(i.readyState===i.CLOSED){C(t),process.nextTick(V6,g);return}let A=!1;i.once("error",function(D){A=!0,C(D)}),i.once("close",function(){A||C(t),process.nextTick(V6,g)}),i.terminate()},g._final=function(t){if(i.readyState===i.CONNECTING){i.once("open",function(){g._final(t)});return}i._socket!==null&&(i._socket._writableState.finished?(t(),g._readableState.endEmitted&&g.destroy()):(i._socket.once("finish",function(){t()}),i.close()))},g._read=function(){i.readyState===i.OPEN&&!f&&(f=!0,i._receiver._writableState.needDrain||i._socket.resume())},g._write=function(t,C,A){if(i.readyState===i.CONNECTING){i.once("open",function(){g._write(t,C,A)});return}i.send(t,A)},g.on("end",nj),g.on("error",Y6),g}G6.exports=rj});var J6=Me((Vb,K6)=>{"use strict";var ij=require("events"),{createHash:oj}=require("crypto"),{createServer:uj,STATUS_CODES:d3}=require("http"),gc=w2(),sj=a3(),{format:lj,parse:fj}=u3(),{GUID:cj,kWebSocket:aj}=mc(),dj=/^[+/0-9A-Za-z]{22}==$/,X6=class extends ij{constructor(u,f){super();if(u=dt({maxPayload:100*1024*1024,perMessageDeflate:!1,handleProtocols:null,clientTracking:!0,verifyClient:null,noServer:!1,backlog:null,server:null,host:null,path:null,port:null},u),u.port==null&&!u.server&&!u.noServer)throw new TypeError('One of the "port", "server", or "noServer" options must be specified');if(u.port!=null?(this._server=uj((c,g)=>{let t=d3[426];g.writeHead(426,{"Content-Length":t.length,"Content-Type":"text/plain"}),g.end(t)}),this._server.listen(u.port,u.host,u.backlog,f)):u.server&&(this._server=u.server),this._server){let c=this.emit.bind(this,"connection");this._removeListeners=pj(this._server,{listening:this.emit.bind(this,"listening"),error:this.emit.bind(this,"error"),upgrade:(g,t,C)=>{this.handleUpgrade(g,t,C,c)}})}u.perMessageDeflate===!0&&(u.perMessageDeflate={}),u.clientTracking&&(this.clients=new Set),this.options=u}address(){if(this.options.noServer)throw new Error('The server is operating in "noServer" mode');return this._server?this._server.address():null}close(u){if(u&&this.once("close",u),this.clients)for(let c of this.clients)c.terminate();let f=this._server;if(f&&(this._removeListeners(),this._removeListeners=this._server=null,this.options.port!=null)){f.close(()=>this.emit("close"));return}process.nextTick(hj,this)}shouldHandle(u){if(this.options.path){let f=u.url.indexOf("?");if((f!==-1?u.url.slice(0,f):u.url)!==this.options.path)return!1}return!0}handleUpgrade(u,f,c,g){f.on("error",p3);let t=u.headers["sec-websocket-key"]!==void 0?u.headers["sec-websocket-key"].trim():!1,C=+u.headers["sec-websocket-version"],A={};if(u.method!=="GET"||u.headers.upgrade.toLowerCase()!=="websocket"||!t||!dj.test(t)||C!==8&&C!==13||!this.shouldHandle(u))return Hh(f,400);if(this.options.perMessageDeflate){let x=new gc(this.options.perMessageDeflate,!0,this.options.maxPayload);try{let D=fj(u.headers["sec-websocket-extensions"]);D[gc.extensionName]&&(x.accept(D[gc.extensionName]),A[gc.extensionName]=x)}catch(D){return Hh(f,400)}}if(this.options.verifyClient){let x={origin:u.headers[`${C===8?"sec-websocket-origin":"origin"}`],secure:!!(u.socket.authorized||u.socket.encrypted),req:u};if(this.options.verifyClient.length===2){this.options.verifyClient(x,(D,L,N,j)=>{if(!D)return Hh(f,L||401,N,j);this.completeUpgrade(t,A,u,f,c,g)});return}if(!this.options.verifyClient(x))return Hh(f,401)}this.completeUpgrade(t,A,u,f,c,g)}completeUpgrade(u,f,c,g,t,C){if(!g.readable||!g.writable)return g.destroy();if(g[aj])throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration");let A=oj("sha1").update(u+cj).digest("base64"),x=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${A}`],D=new sj(null),L=c.headers["sec-websocket-protocol"];if(L&&(L=L.split(",").map(mj),this.options.handleProtocols?L=this.options.handleProtocols(L,c):L=L[0],L&&(x.push(`Sec-WebSocket-Protocol: ${L}`),D._protocol=L)),f[gc.extensionName]){let N=f[gc.extensionName].params,j=lj({[gc.extensionName]:[N]});x.push(`Sec-WebSocket-Extensions: ${j}`),D._extensions=f}this.emit("headers",x,c),g.write(x.concat(`\r +`).join(`\r +`)),g.removeListener("error",p3),D.setSocket(g,t,this.options.maxPayload),this.clients&&(this.clients.add(D),D.on("close",()=>this.clients.delete(D))),C(D,c)}};K6.exports=X6;function pj(i,u){for(let f of Object.keys(u))i.on(f,u[f]);return function(){for(let c of Object.keys(u))i.removeListener(c,u[c])}}function hj(i){i.emit("close")}function p3(){this.destroy()}function Hh(i,u,f,c){i.writable&&(f=f||d3[u],c=dt({Connection:"close","Content-Type":"text/html","Content-Length":Buffer.byteLength(f)},c),i.write(`HTTP/1.1 ${u} ${d3[u]}\r +`+Object.keys(c).map(g=>`${g}: ${c[g]}`).join(`\r +`)+`\r +\r +`+f)),i.removeListener("error",p3),i.destroy()}function mj(i){return i.trim()}});var Z6=Me((Yb,Q6)=>{"use strict";var C2=a3();C2.createWebSocketStream=$6();C2.Server=J6();C2.Receiver=i3();C2.Sender=o3();Q6.exports=C2});var eS=Me(bh=>{"use strict";var vj=bh&&bh.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(bh,"__esModule",{value:!0});var gj=vj(Z6()),T2=global;T2.WebSocket||(T2.WebSocket=gj.default);T2.window||(T2.window=global);T2.window.__REACT_DEVTOOLS_COMPONENT_FILTERS__=[{type:1,value:7,isEnabled:!0},{type:2,value:"InternalApp",isEnabled:!0,isValid:!0},{type:2,value:"InternalAppContext",isEnabled:!0,isValid:!0},{type:2,value:"InternalStdoutContext",isEnabled:!0,isValid:!0},{type:2,value:"InternalStderrContext",isEnabled:!0,isValid:!0},{type:2,value:"InternalStdinContext",isEnabled:!0,isValid:!0},{type:2,value:"InternalFocusContext",isEnabled:!0,isValid:!0}]});var tS=Me((Gh,h3)=>{(function(i,u){typeof Gh=="object"&&typeof h3=="object"?h3.exports=u():typeof define=="function"&&define.amd?define([],u):typeof Gh=="object"?Gh.ReactDevToolsBackend=u():i.ReactDevToolsBackend=u()})(window,function(){return function(i){var u={};function f(c){if(u[c])return u[c].exports;var g=u[c]={i:c,l:!1,exports:{}};return i[c].call(g.exports,g,g.exports,f),g.l=!0,g.exports}return f.m=i,f.c=u,f.d=function(c,g,t){f.o(c,g)||Object.defineProperty(c,g,{enumerable:!0,get:t})},f.r=function(c){typeof Symbol!="undefined"&&Symbol.toStringTag&&Object.defineProperty(c,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(c,"__esModule",{value:!0})},f.t=function(c,g){if(1&g&&(c=f(c)),8&g||4&g&&typeof c=="object"&&c&&c.__esModule)return c;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:c}),2&g&&typeof c!="string")for(var C in c)f.d(t,C,function(A){return c[A]}.bind(null,C));return t},f.n=function(c){var g=c&&c.__esModule?function(){return c.default}:function(){return c};return f.d(g,"a",g),g},f.o=function(c,g){return Object.prototype.hasOwnProperty.call(c,g)},f.p="",f(f.s=20)}([function(i,u,f){"use strict";i.exports=f(12)},function(i,u,f){"use strict";var c=Object.getOwnPropertySymbols,g=Object.prototype.hasOwnProperty,t=Object.prototype.propertyIsEnumerable;function C(A){if(A==null)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(A)}i.exports=function(){try{if(!Object.assign)return!1;var A=new String("abc");if(A[5]="de",Object.getOwnPropertyNames(A)[0]==="5")return!1;for(var x={},D=0;D<10;D++)x["_"+String.fromCharCode(D)]=D;if(Object.getOwnPropertyNames(x).map(function(N){return x[N]}).join("")!=="0123456789")return!1;var L={};return"abcdefghijklmnopqrst".split("").forEach(function(N){L[N]=N}),Object.keys(Object.assign({},L)).join("")==="abcdefghijklmnopqrst"}catch(N){return!1}}()?Object.assign:function(A,x){for(var D,L,N=C(A),j=1;j=J||Ft<0||Nt&&it-At>=ot}function Z(){var it=ce();if(ge(it))return Ae(it);Ue=setTimeout(Z,function(Ft){var jt=J-(Ft-be);return Nt?re(jt,ot-(Ft-At)):jt}(it))}function Ae(it){return Ue=void 0,Je&&Oe?V(it):(Oe=Le=void 0,ct)}function at(){var it=ce(),Ft=ge(it);if(Oe=arguments,Le=this,be=it,Ft){if(Ue===void 0)return ne(be);if(Nt)return Ue=setTimeout(Z,J),V(be)}return Ue===void 0&&(Ue=setTimeout(Z,J)),ct}return J=me(J)||0,oe(Te)&&(Ot=!!Te.leading,ot=(Nt="maxWait"in Te)?h(me(Te.maxWait)||0,J):ot,Je="trailing"in Te?!!Te.trailing:Je),at.cancel=function(){Ue!==void 0&&clearTimeout(Ue),At=0,Oe=be=Le=Ue=void 0},at.flush=function(){return Ue===void 0?ct:Ae(ce())},at}function oe(De){var J=g(De);return!!De&&(J=="object"||J=="function")}function Se(De){return g(De)=="symbol"||function(J){return!!J&&g(J)=="object"}(De)&&$.call(De)=="[object Symbol]"}function me(De){if(typeof De=="number")return De;if(Se(De))return NaN;if(oe(De)){var J=typeof De.valueOf=="function"?De.valueOf():De;De=oe(J)?J+"":J}if(typeof De!="string")return De===0?De:+De;De=De.replace(t,"");var Te=A.test(De);return Te||x.test(De)?D(De.slice(2),Te?2:8):C.test(De)?NaN:+De}i.exports=function(De,J,Te){var Oe=!0,Le=!0;if(typeof De!="function")throw new TypeError("Expected a function");return oe(Te)&&(Oe="leading"in Te?!!Te.leading:Oe,Le="trailing"in Te?!!Te.trailing:Le),Q(De,J,{leading:Oe,maxWait:J,trailing:Le})}}).call(this,f(4))},function(i,u,f){(function(c){function g(V){return(g=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(ne){return typeof ne}:function(ne){return ne&&typeof Symbol=="function"&&ne.constructor===Symbol&&ne!==Symbol.prototype?"symbol":typeof ne})(V)}var t;u=i.exports=h,t=(c===void 0?"undefined":g(c))==="object"&&c.env&&c.env.NODE_DEBUG&&/\bsemver\b/i.test(c.env.NODE_DEBUG)?function(){var V=Array.prototype.slice.call(arguments,0);V.unshift("SEMVER"),console.log.apply(console,V)}:function(){},u.SEMVER_SPEC_VERSION="2.0.0";var C=Number.MAX_SAFE_INTEGER||9007199254740991,A=u.re=[],x=u.src=[],D=u.tokens={},L=0;function N(V){D[V]=L++}N("NUMERICIDENTIFIER"),x[D.NUMERICIDENTIFIER]="0|[1-9]\\d*",N("NUMERICIDENTIFIERLOOSE"),x[D.NUMERICIDENTIFIERLOOSE]="[0-9]+",N("NONNUMERICIDENTIFIER"),x[D.NONNUMERICIDENTIFIER]="\\d*[a-zA-Z-][a-zA-Z0-9-]*",N("MAINVERSION"),x[D.MAINVERSION]="("+x[D.NUMERICIDENTIFIER]+")\\.("+x[D.NUMERICIDENTIFIER]+")\\.("+x[D.NUMERICIDENTIFIER]+")",N("MAINVERSIONLOOSE"),x[D.MAINVERSIONLOOSE]="("+x[D.NUMERICIDENTIFIERLOOSE]+")\\.("+x[D.NUMERICIDENTIFIERLOOSE]+")\\.("+x[D.NUMERICIDENTIFIERLOOSE]+")",N("PRERELEASEIDENTIFIER"),x[D.PRERELEASEIDENTIFIER]="(?:"+x[D.NUMERICIDENTIFIER]+"|"+x[D.NONNUMERICIDENTIFIER]+")",N("PRERELEASEIDENTIFIERLOOSE"),x[D.PRERELEASEIDENTIFIERLOOSE]="(?:"+x[D.NUMERICIDENTIFIERLOOSE]+"|"+x[D.NONNUMERICIDENTIFIER]+")",N("PRERELEASE"),x[D.PRERELEASE]="(?:-("+x[D.PRERELEASEIDENTIFIER]+"(?:\\."+x[D.PRERELEASEIDENTIFIER]+")*))",N("PRERELEASELOOSE"),x[D.PRERELEASELOOSE]="(?:-?("+x[D.PRERELEASEIDENTIFIERLOOSE]+"(?:\\."+x[D.PRERELEASEIDENTIFIERLOOSE]+")*))",N("BUILDIDENTIFIER"),x[D.BUILDIDENTIFIER]="[0-9A-Za-z-]+",N("BUILD"),x[D.BUILD]="(?:\\+("+x[D.BUILDIDENTIFIER]+"(?:\\."+x[D.BUILDIDENTIFIER]+")*))",N("FULL"),N("FULLPLAIN"),x[D.FULLPLAIN]="v?"+x[D.MAINVERSION]+x[D.PRERELEASE]+"?"+x[D.BUILD]+"?",x[D.FULL]="^"+x[D.FULLPLAIN]+"$",N("LOOSEPLAIN"),x[D.LOOSEPLAIN]="[v=\\s]*"+x[D.MAINVERSIONLOOSE]+x[D.PRERELEASELOOSE]+"?"+x[D.BUILD]+"?",N("LOOSE"),x[D.LOOSE]="^"+x[D.LOOSEPLAIN]+"$",N("GTLT"),x[D.GTLT]="((?:<|>)?=?)",N("XRANGEIDENTIFIERLOOSE"),x[D.XRANGEIDENTIFIERLOOSE]=x[D.NUMERICIDENTIFIERLOOSE]+"|x|X|\\*",N("XRANGEIDENTIFIER"),x[D.XRANGEIDENTIFIER]=x[D.NUMERICIDENTIFIER]+"|x|X|\\*",N("XRANGEPLAIN"),x[D.XRANGEPLAIN]="[v=\\s]*("+x[D.XRANGEIDENTIFIER]+")(?:\\.("+x[D.XRANGEIDENTIFIER]+")(?:\\.("+x[D.XRANGEIDENTIFIER]+")(?:"+x[D.PRERELEASE]+")?"+x[D.BUILD]+"?)?)?",N("XRANGEPLAINLOOSE"),x[D.XRANGEPLAINLOOSE]="[v=\\s]*("+x[D.XRANGEIDENTIFIERLOOSE]+")(?:\\.("+x[D.XRANGEIDENTIFIERLOOSE]+")(?:\\.("+x[D.XRANGEIDENTIFIERLOOSE]+")(?:"+x[D.PRERELEASELOOSE]+")?"+x[D.BUILD]+"?)?)?",N("XRANGE"),x[D.XRANGE]="^"+x[D.GTLT]+"\\s*"+x[D.XRANGEPLAIN]+"$",N("XRANGELOOSE"),x[D.XRANGELOOSE]="^"+x[D.GTLT]+"\\s*"+x[D.XRANGEPLAINLOOSE]+"$",N("COERCE"),x[D.COERCE]="(^|[^\\d])(\\d{1,16})(?:\\.(\\d{1,16}))?(?:\\.(\\d{1,16}))?(?:$|[^\\d])",N("COERCERTL"),A[D.COERCERTL]=new RegExp(x[D.COERCE],"g"),N("LONETILDE"),x[D.LONETILDE]="(?:~>?)",N("TILDETRIM"),x[D.TILDETRIM]="(\\s*)"+x[D.LONETILDE]+"\\s+",A[D.TILDETRIM]=new RegExp(x[D.TILDETRIM],"g"),N("TILDE"),x[D.TILDE]="^"+x[D.LONETILDE]+x[D.XRANGEPLAIN]+"$",N("TILDELOOSE"),x[D.TILDELOOSE]="^"+x[D.LONETILDE]+x[D.XRANGEPLAINLOOSE]+"$",N("LONECARET"),x[D.LONECARET]="(?:\\^)",N("CARETTRIM"),x[D.CARETTRIM]="(\\s*)"+x[D.LONECARET]+"\\s+",A[D.CARETTRIM]=new RegExp(x[D.CARETTRIM],"g"),N("CARET"),x[D.CARET]="^"+x[D.LONECARET]+x[D.XRANGEPLAIN]+"$",N("CARETLOOSE"),x[D.CARETLOOSE]="^"+x[D.LONECARET]+x[D.XRANGEPLAINLOOSE]+"$",N("COMPARATORLOOSE"),x[D.COMPARATORLOOSE]="^"+x[D.GTLT]+"\\s*("+x[D.LOOSEPLAIN]+")$|^$",N("COMPARATOR"),x[D.COMPARATOR]="^"+x[D.GTLT]+"\\s*("+x[D.FULLPLAIN]+")$|^$",N("COMPARATORTRIM"),x[D.COMPARATORTRIM]="(\\s*)"+x[D.GTLT]+"\\s*("+x[D.LOOSEPLAIN]+"|"+x[D.XRANGEPLAIN]+")",A[D.COMPARATORTRIM]=new RegExp(x[D.COMPARATORTRIM],"g"),N("HYPHENRANGE"),x[D.HYPHENRANGE]="^\\s*("+x[D.XRANGEPLAIN]+")\\s+-\\s+("+x[D.XRANGEPLAIN]+")\\s*$",N("HYPHENRANGELOOSE"),x[D.HYPHENRANGELOOSE]="^\\s*("+x[D.XRANGEPLAINLOOSE]+")\\s+-\\s+("+x[D.XRANGEPLAINLOOSE]+")\\s*$",N("STAR"),x[D.STAR]="(<|>)?=?\\s*\\*";for(var j=0;j256||!(ne.loose?A[D.LOOSE]:A[D.FULL]).test(V))return null;try{return new h(V,ne)}catch(ge){return null}}function h(V,ne){if(ne&&g(ne)==="object"||(ne={loose:!!ne,includePrerelease:!1}),V instanceof h){if(V.loose===ne.loose)return V;V=V.version}else if(typeof V!="string")throw new TypeError("Invalid Version: "+V);if(V.length>256)throw new TypeError("version is longer than 256 characters");if(!(this instanceof h))return new h(V,ne);t("SemVer",V,ne),this.options=ne,this.loose=!!ne.loose;var ge=V.trim().match(ne.loose?A[D.LOOSE]:A[D.FULL]);if(!ge)throw new TypeError("Invalid Version: "+V);if(this.raw=V,this.major=+ge[1],this.minor=+ge[2],this.patch=+ge[3],this.major>C||this.major<0)throw new TypeError("Invalid major version");if(this.minor>C||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>C||this.patch<0)throw new TypeError("Invalid patch version");ge[4]?this.prerelease=ge[4].split(".").map(function(Z){if(/^[0-9]+$/.test(Z)){var Ae=+Z;if(Ae>=0&&Ae=0;)typeof this.prerelease[ge]=="number"&&(this.prerelease[ge]++,ge=-2);ge===-1&&this.prerelease.push(0)}ne&&(this.prerelease[0]===ne?isNaN(this.prerelease[1])&&(this.prerelease=[ne,0]):this.prerelease=[ne,0]);break;default:throw new Error("invalid increment argument: "+V)}return this.format(),this.raw=this.version,this},u.inc=function(V,ne,ge,Z){typeof ge=="string"&&(Z=ge,ge=void 0);try{return new h(V,ge).inc(ne,Z).version}catch(Ae){return null}},u.diff=function(V,ne){if(me(V,ne))return null;var ge=$(V),Z=$(ne),Ae="";if(ge.prerelease.length||Z.prerelease.length){Ae="pre";var at="prerelease"}for(var it in ge)if((it==="major"||it==="minor"||it==="patch")&&ge[it]!==Z[it])return Ae+it;return at},u.compareIdentifiers=ce;var re=/^[0-9]+$/;function ce(V,ne){var ge=re.test(V),Z=re.test(ne);return ge&&Z&&(V=+V,ne=+ne),V===ne?0:ge&&!Z?-1:Z&&!ge?1:V0}function Se(V,ne,ge){return Q(V,ne,ge)<0}function me(V,ne,ge){return Q(V,ne,ge)===0}function De(V,ne,ge){return Q(V,ne,ge)!==0}function J(V,ne,ge){return Q(V,ne,ge)>=0}function Te(V,ne,ge){return Q(V,ne,ge)<=0}function Oe(V,ne,ge,Z){switch(ne){case"===":return g(V)==="object"&&(V=V.version),g(ge)==="object"&&(ge=ge.version),V===ge;case"!==":return g(V)==="object"&&(V=V.version),g(ge)==="object"&&(ge=ge.version),V!==ge;case"":case"=":case"==":return me(V,ge,Z);case"!=":return De(V,ge,Z);case">":return oe(V,ge,Z);case">=":return J(V,ge,Z);case"<":return Se(V,ge,Z);case"<=":return Te(V,ge,Z);default:throw new TypeError("Invalid operator: "+ne)}}function Le(V,ne){if(ne&&g(ne)==="object"||(ne={loose:!!ne,includePrerelease:!1}),V instanceof Le){if(V.loose===!!ne.loose)return V;V=V.value}if(!(this instanceof Le))return new Le(V,ne);t("comparator",V,ne),this.options=ne,this.loose=!!ne.loose,this.parse(V),this.semver===ot?this.value="":this.value=this.operator+this.semver.version,t("comp",this)}u.rcompareIdentifiers=function(V,ne){return ce(ne,V)},u.major=function(V,ne){return new h(V,ne).major},u.minor=function(V,ne){return new h(V,ne).minor},u.patch=function(V,ne){return new h(V,ne).patch},u.compare=Q,u.compareLoose=function(V,ne){return Q(V,ne,!0)},u.compareBuild=function(V,ne,ge){var Z=new h(V,ge),Ae=new h(ne,ge);return Z.compare(Ae)||Z.compareBuild(Ae)},u.rcompare=function(V,ne,ge){return Q(ne,V,ge)},u.sort=function(V,ne){return V.sort(function(ge,Z){return u.compareBuild(ge,Z,ne)})},u.rsort=function(V,ne){return V.sort(function(ge,Z){return u.compareBuild(Z,ge,ne)})},u.gt=oe,u.lt=Se,u.eq=me,u.neq=De,u.gte=J,u.lte=Te,u.cmp=Oe,u.Comparator=Le;var ot={};function ct(V,ne){if(ne&&g(ne)==="object"||(ne={loose:!!ne,includePrerelease:!1}),V instanceof ct)return V.loose===!!ne.loose&&V.includePrerelease===!!ne.includePrerelease?V:new ct(V.raw,ne);if(V instanceof Le)return new ct(V.value,ne);if(!(this instanceof ct))return new ct(V,ne);if(this.options=ne,this.loose=!!ne.loose,this.includePrerelease=!!ne.includePrerelease,this.raw=V,this.set=V.split(/\s*\|\|\s*/).map(function(ge){return this.parseRange(ge.trim())},this).filter(function(ge){return ge.length}),!this.set.length)throw new TypeError("Invalid SemVer Range: "+V);this.format()}function Ue(V,ne){for(var ge=!0,Z=V.slice(),Ae=Z.pop();ge&&Z.length;)ge=Z.every(function(at){return Ae.intersects(at,ne)}),Ae=Z.pop();return ge}function be(V){return!V||V.toLowerCase()==="x"||V==="*"}function At(V,ne,ge,Z,Ae,at,it,Ft,jt,hn,Un,Jt,Yt){return((ne=be(ge)?"":be(Z)?">="+ge+".0.0":be(Ae)?">="+ge+"."+Z+".0":">="+ne)+" "+(Ft=be(jt)?"":be(hn)?"<"+(+jt+1)+".0.0":be(Un)?"<"+jt+"."+(+hn+1)+".0":Jt?"<="+jt+"."+hn+"."+Un+"-"+Jt:"<="+Ft)).trim()}function Ot(V,ne,ge){for(var Z=0;Z0){var Ae=V[Z].semver;if(Ae.major===ne.major&&Ae.minor===ne.minor&&Ae.patch===ne.patch)return!0}return!1}return!0}function Nt(V,ne,ge){try{ne=new ct(ne,ge)}catch(Z){return!1}return ne.test(V)}function Je(V,ne,ge,Z){var Ae,at,it,Ft,jt;switch(V=new h(V,Z),ne=new ct(ne,Z),ge){case">":Ae=oe,at=Te,it=Se,Ft=">",jt=">=";break;case"<":Ae=Se,at=J,it=oe,Ft="<",jt="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(Nt(V,ne,Z))return!1;for(var hn=0;hn=0.0.0")),Jt=Jt||cr,Yt=Yt||cr,Ae(cr.semver,Jt.semver,Z)?Jt=cr:it(cr.semver,Yt.semver,Z)&&(Yt=cr)}),Jt.operator===Ft||Jt.operator===jt||(!Yt.operator||Yt.operator===Ft)&&at(V,Yt.semver)||Yt.operator===jt&&it(V,Yt.semver))return!1}return!0}Le.prototype.parse=function(V){var ne=this.options.loose?A[D.COMPARATORLOOSE]:A[D.COMPARATOR],ge=V.match(ne);if(!ge)throw new TypeError("Invalid comparator: "+V);this.operator=ge[1]!==void 0?ge[1]:"",this.operator==="="&&(this.operator=""),ge[2]?this.semver=new h(ge[2],this.options.loose):this.semver=ot},Le.prototype.toString=function(){return this.value},Le.prototype.test=function(V){if(t("Comparator.test",V,this.options.loose),this.semver===ot||V===ot)return!0;if(typeof V=="string")try{V=new h(V,this.options)}catch(ne){return!1}return Oe(V,this.operator,this.semver,this.options)},Le.prototype.intersects=function(V,ne){if(!(V instanceof Le))throw new TypeError("a Comparator is required");var ge;if(ne&&g(ne)==="object"||(ne={loose:!!ne,includePrerelease:!1}),this.operator==="")return this.value===""||(ge=new ct(V.value,ne),Nt(this.value,ge,ne));if(V.operator==="")return V.value===""||(ge=new ct(this.value,ne),Nt(V.semver,ge,ne));var Z=!(this.operator!==">="&&this.operator!==">"||V.operator!==">="&&V.operator!==">"),Ae=!(this.operator!=="<="&&this.operator!=="<"||V.operator!=="<="&&V.operator!=="<"),at=this.semver.version===V.semver.version,it=!(this.operator!==">="&&this.operator!=="<="||V.operator!==">="&&V.operator!=="<="),Ft=Oe(this.semver,"<",V.semver,ne)&&(this.operator===">="||this.operator===">")&&(V.operator==="<="||V.operator==="<"),jt=Oe(this.semver,">",V.semver,ne)&&(this.operator==="<="||this.operator==="<")&&(V.operator===">="||V.operator===">");return Z||Ae||at&&it||Ft||jt},u.Range=ct,ct.prototype.format=function(){return this.range=this.set.map(function(V){return V.join(" ").trim()}).join("||").trim(),this.range},ct.prototype.toString=function(){return this.range},ct.prototype.parseRange=function(V){var ne=this.options.loose;V=V.trim();var ge=ne?A[D.HYPHENRANGELOOSE]:A[D.HYPHENRANGE];V=V.replace(ge,At),t("hyphen replace",V),V=V.replace(A[D.COMPARATORTRIM],"$1$2$3"),t("comparator trim",V,A[D.COMPARATORTRIM]),V=(V=(V=V.replace(A[D.TILDETRIM],"$1~")).replace(A[D.CARETTRIM],"$1^")).split(/\s+/).join(" ");var Z=ne?A[D.COMPARATORLOOSE]:A[D.COMPARATOR],Ae=V.split(" ").map(function(at){return function(it,Ft){return t("comp",it,Ft),it=function(jt,hn){return jt.trim().split(/\s+/).map(function(Un){return function(Jt,Yt){t("caret",Jt,Yt);var cr=Yt.loose?A[D.CARETLOOSE]:A[D.CARET];return Jt.replace(cr,function(w,pt,Mn,Bn,Xn){var vr;return t("caret",Jt,w,pt,Mn,Bn,Xn),be(pt)?vr="":be(Mn)?vr=">="+pt+".0.0 <"+(+pt+1)+".0.0":be(Bn)?vr=pt==="0"?">="+pt+"."+Mn+".0 <"+pt+"."+(+Mn+1)+".0":">="+pt+"."+Mn+".0 <"+(+pt+1)+".0.0":Xn?(t("replaceCaret pr",Xn),vr=pt==="0"?Mn==="0"?">="+pt+"."+Mn+"."+Bn+"-"+Xn+" <"+pt+"."+Mn+"."+(+Bn+1):">="+pt+"."+Mn+"."+Bn+"-"+Xn+" <"+pt+"."+(+Mn+1)+".0":">="+pt+"."+Mn+"."+Bn+"-"+Xn+" <"+(+pt+1)+".0.0"):(t("no pr"),vr=pt==="0"?Mn==="0"?">="+pt+"."+Mn+"."+Bn+" <"+pt+"."+Mn+"."+(+Bn+1):">="+pt+"."+Mn+"."+Bn+" <"+pt+"."+(+Mn+1)+".0":">="+pt+"."+Mn+"."+Bn+" <"+(+pt+1)+".0.0"),t("caret return",vr),vr})}(Un,hn)}).join(" ")}(it,Ft),t("caret",it),it=function(jt,hn){return jt.trim().split(/\s+/).map(function(Un){return function(Jt,Yt){var cr=Yt.loose?A[D.TILDELOOSE]:A[D.TILDE];return Jt.replace(cr,function(w,pt,Mn,Bn,Xn){var vr;return t("tilde",Jt,w,pt,Mn,Bn,Xn),be(pt)?vr="":be(Mn)?vr=">="+pt+".0.0 <"+(+pt+1)+".0.0":be(Bn)?vr=">="+pt+"."+Mn+".0 <"+pt+"."+(+Mn+1)+".0":Xn?(t("replaceTilde pr",Xn),vr=">="+pt+"."+Mn+"."+Bn+"-"+Xn+" <"+pt+"."+(+Mn+1)+".0"):vr=">="+pt+"."+Mn+"."+Bn+" <"+pt+"."+(+Mn+1)+".0",t("tilde return",vr),vr})}(Un,hn)}).join(" ")}(it,Ft),t("tildes",it),it=function(jt,hn){return t("replaceXRanges",jt,hn),jt.split(/\s+/).map(function(Un){return function(Jt,Yt){Jt=Jt.trim();var cr=Yt.loose?A[D.XRANGELOOSE]:A[D.XRANGE];return Jt.replace(cr,function(w,pt,Mn,Bn,Xn,vr){t("xRange",Jt,w,pt,Mn,Bn,Xn,vr);var gr=be(Mn),r0=gr||be(Bn),Ci=r0||be(Xn),yo=Ci;return pt==="="&&yo&&(pt=""),vr=Yt.includePrerelease?"-0":"",gr?w=pt===">"||pt==="<"?"<0.0.0-0":"*":pt&&yo?(r0&&(Bn=0),Xn=0,pt===">"?(pt=">=",r0?(Mn=+Mn+1,Bn=0,Xn=0):(Bn=+Bn+1,Xn=0)):pt==="<="&&(pt="<",r0?Mn=+Mn+1:Bn=+Bn+1),w=pt+Mn+"."+Bn+"."+Xn+vr):r0?w=">="+Mn+".0.0"+vr+" <"+(+Mn+1)+".0.0"+vr:Ci&&(w=">="+Mn+"."+Bn+".0"+vr+" <"+Mn+"."+(+Bn+1)+".0"+vr),t("xRange return",w),w})}(Un,hn)}).join(" ")}(it,Ft),t("xrange",it),it=function(jt,hn){return t("replaceStars",jt,hn),jt.trim().replace(A[D.STAR],"")}(it,Ft),t("stars",it),it}(at,this.options)},this).join(" ").split(/\s+/);return this.options.loose&&(Ae=Ae.filter(function(at){return!!at.match(Z)})),Ae=Ae.map(function(at){return new Le(at,this.options)},this)},ct.prototype.intersects=function(V,ne){if(!(V instanceof ct))throw new TypeError("a Range is required");return this.set.some(function(ge){return Ue(ge,ne)&&V.set.some(function(Z){return Ue(Z,ne)&&ge.every(function(Ae){return Z.every(function(at){return Ae.intersects(at,ne)})})})})},u.toComparators=function(V,ne){return new ct(V,ne).set.map(function(ge){return ge.map(function(Z){return Z.value}).join(" ").trim().split(" ")})},ct.prototype.test=function(V){if(!V)return!1;if(typeof V=="string")try{V=new h(V,this.options)}catch(ge){return!1}for(var ne=0;ne":at.prerelease.length===0?at.patch++:at.prerelease.push(0),at.raw=at.format();case"":case">=":ge&&!oe(ge,at)||(ge=at);break;case"<":case"<=":break;default:throw new Error("Unexpected operation: "+Ae.operator)}});return ge&&V.test(ge)?ge:null},u.validRange=function(V,ne){try{return new ct(V,ne).range||"*"}catch(ge){return null}},u.ltr=function(V,ne,ge){return Je(V,ne,"<",ge)},u.gtr=function(V,ne,ge){return Je(V,ne,">",ge)},u.outside=Je,u.prerelease=function(V,ne){var ge=$(V,ne);return ge&&ge.prerelease.length?ge.prerelease:null},u.intersects=function(V,ne,ge){return V=new ct(V,ge),ne=new ct(ne,ge),V.intersects(ne)},u.coerce=function(V,ne){if(V instanceof h)return V;if(typeof V=="number"&&(V=String(V)),typeof V!="string")return null;var ge=null;if((ne=ne||{}).rtl){for(var Z;(Z=A[D.COERCERTL].exec(V))&&(!ge||ge.index+ge[0].length!==V.length);)ge&&Z.index+Z[0].length===ge.index+ge[0].length||(ge=Z),A[D.COERCERTL].lastIndex=Z.index+Z[1].length+Z[2].length;A[D.COERCERTL].lastIndex=-1}else ge=V.match(A[D.COERCE]);return ge===null?null:$(ge[2]+"."+(ge[3]||"0")+"."+(ge[4]||"0"),ne)}}).call(this,f(5))},function(i,u){function f(g){return(f=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(g)}var c;c=function(){return this}();try{c=c||new Function("return this")()}catch(g){(typeof window=="undefined"?"undefined":f(window))==="object"&&(c=window)}i.exports=c},function(i,u){var f,c,g=i.exports={};function t(){throw new Error("setTimeout has not been defined")}function C(){throw new Error("clearTimeout has not been defined")}function A(ce){if(f===setTimeout)return setTimeout(ce,0);if((f===t||!f)&&setTimeout)return f=setTimeout,setTimeout(ce,0);try{return f(ce,0)}catch(Q){try{return f.call(null,ce,0)}catch(oe){return f.call(this,ce,0)}}}(function(){try{f=typeof setTimeout=="function"?setTimeout:t}catch(ce){f=t}try{c=typeof clearTimeout=="function"?clearTimeout:C}catch(ce){c=C}})();var x,D=[],L=!1,N=-1;function j(){L&&x&&(L=!1,x.length?D=x.concat(D):N=-1,D.length&&$())}function $(){if(!L){var ce=A(j);L=!0;for(var Q=D.length;Q;){for(x=D,D=[];++N1)for(var oe=1;oethis[C])return De(this,this[h].get(Ue)),!1;var Je=this[h].get(Ue).value;return this[N]&&(this[j]||this[N](Ue,Je.value)),Je.now=Ot,Je.maxAge=At,Je.value=be,this[A]+=Nt-Je.length,Je.length=Nt,this.get(Ue),me(this),!0}var V=new J(Ue,be,Nt,Ot,At);return V.length>this[C]?(this[N]&&this[N](Ue,be),!1):(this[A]+=V.length,this[$].unshift(V),this[h].set(Ue,this[$].head),me(this),!0)}},{key:"has",value:function(Ue){if(!this[h].has(Ue))return!1;var be=this[h].get(Ue).value;return!Se(this,be)}},{key:"get",value:function(Ue){return oe(this,Ue,!0)}},{key:"peek",value:function(Ue){return oe(this,Ue,!1)}},{key:"pop",value:function(){var Ue=this[$].tail;return Ue?(De(this,Ue),Ue.value):null}},{key:"del",value:function(Ue){De(this,this[h].get(Ue))}},{key:"load",value:function(Ue){this.reset();for(var be=Date.now(),At=Ue.length-1;At>=0;At--){var Ot=Ue[At],Nt=Ot.e||0;if(Nt===0)this.set(Ot.k,Ot.v);else{var Je=Nt-be;Je>0&&this.set(Ot.k,Ot.v,Je)}}}},{key:"prune",value:function(){var Ue=this;this[h].forEach(function(be,At){return oe(Ue,At,!1)})}},{key:"max",set:function(Ue){if(typeof Ue!="number"||Ue<0)throw new TypeError("max must be a non-negative number");this[C]=Ue||1/0,me(this)},get:function(){return this[C]}},{key:"allowStale",set:function(Ue){this[D]=!!Ue},get:function(){return this[D]}},{key:"maxAge",set:function(Ue){if(typeof Ue!="number")throw new TypeError("maxAge must be a non-negative number");this[L]=Ue,me(this)},get:function(){return this[L]}},{key:"lengthCalculator",set:function(Ue){var be=this;typeof Ue!="function"&&(Ue=ce),Ue!==this[x]&&(this[x]=Ue,this[A]=0,this[$].forEach(function(At){At.length=be[x](At.value,At.key),be[A]+=At.length})),me(this)},get:function(){return this[x]}},{key:"length",get:function(){return this[A]}},{key:"itemCount",get:function(){return this[$].length}}])&&g(Le.prototype,ot),ct&&g(Le,ct),Oe}(),oe=function(Oe,Le,ot){var ct=Oe[h].get(Le);if(ct){var Ue=ct.value;if(Se(Oe,Ue)){if(De(Oe,ct),!Oe[D])return}else ot&&(Oe[re]&&(ct.value.now=Date.now()),Oe[$].unshiftNode(ct));return Ue.value}},Se=function(Oe,Le){if(!Le||!Le.maxAge&&!Oe[L])return!1;var ot=Date.now()-Le.now;return Le.maxAge?ot>Le.maxAge:Oe[L]&&ot>Oe[L]},me=function(Oe){if(Oe[A]>Oe[C])for(var Le=Oe[$].tail;Oe[A]>Oe[C]&&Le!==null;){var ot=Le.prev;De(Oe,Le),Le=ot}},De=function(Oe,Le){if(Le){var ot=Le.value;Oe[N]&&Oe[N](ot.key,ot.value),Oe[A]-=ot.length,Oe[h].delete(ot.key),Oe[$].removeNode(Le)}},J=function Oe(Le,ot,ct,Ue,be){c(this,Oe),this.key=Le,this.value=ot,this.length=ct,this.now=Ue,this.maxAge=be||0},Te=function(Oe,Le,ot,ct){var Ue=ot.value;Se(Oe,Ue)&&(De(Oe,ot),Oe[D]||(Ue=void 0)),Ue&&Le.call(ct,Ue.value,Ue.key,Oe)};i.exports=Q},function(i,u,f){(function(c){function g(t){return(g=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(C){return typeof C}:function(C){return C&&typeof Symbol=="function"&&C.constructor===Symbol&&C!==Symbol.prototype?"symbol":typeof C})(t)}i.exports=function(){if(typeof document=="undefined"||!document.addEventListener)return null;var t,C,A,x={};return x.copy=function(){var D=!1,L=null,N=!1;function j(){D=!1,L=null,N&&window.getSelection().removeAllRanges(),N=!1}return document.addEventListener("copy",function($){if(D){for(var h in L)$.clipboardData.setData(h,L[h]);$.preventDefault()}}),function($){return new Promise(function(h,re){D=!0,typeof $=="string"?L={"text/plain":$}:$ instanceof Node?L={"text/html":new XMLSerializer().serializeToString($)}:$ instanceof Object?L=$:re("Invalid data type. Must be string, DOM node, or an object mapping MIME types to strings."),function ce(Q){try{if(document.execCommand("copy"))j(),h();else{if(Q)throw j(),new Error("Unable to copy. Perhaps it's not available in your browser?");(function(){var oe=document.getSelection();if(!document.queryCommandEnabled("copy")&&oe.isCollapsed){var Se=document.createRange();Se.selectNodeContents(document.body),oe.removeAllRanges(),oe.addRange(Se),N=!0}})(),ce(!0)}}catch(oe){j(),re(oe)}}(!1)})}}(),x.paste=(A=!1,document.addEventListener("paste",function(D){if(A){A=!1,D.preventDefault();var L=t;t=null,L(D.clipboardData.getData(C))}}),function(D){return new Promise(function(L,N){A=!0,t=L,C=D||"text/plain";try{document.execCommand("paste")||(A=!1,N(new Error("Unable to paste. Pasting only works in Internet Explorer at the moment.")))}catch(j){A=!1,N(new Error(j))}})}),typeof ClipboardEvent=="undefined"&&window.clipboardData!==void 0&&window.clipboardData.setData!==void 0&&(function(D){function L(me,De){return function(){me.apply(De,arguments)}}function N(me){if(g(this)!="object")throw new TypeError("Promises must be constructed via new");if(typeof me!="function")throw new TypeError("not a function");this._state=null,this._value=null,this._deferreds=[],Q(me,L($,this),L(h,this))}function j(me){var De=this;return this._state===null?void this._deferreds.push(me):void oe(function(){var J=De._state?me.onFulfilled:me.onRejected;if(J!==null){var Te;try{Te=J(De._value)}catch(Oe){return void me.reject(Oe)}me.resolve(Te)}else(De._state?me.resolve:me.reject)(De._value)})}function $(me){try{if(me===this)throw new TypeError("A promise cannot be resolved with itself.");if(me&&(g(me)=="object"||typeof me=="function")){var De=me.then;if(typeof De=="function")return void Q(L(De,me),L($,this),L(h,this))}this._state=!0,this._value=me,re.call(this)}catch(J){h.call(this,J)}}function h(me){this._state=!1,this._value=me,re.call(this)}function re(){for(var me=0,De=this._deferreds.length;De>me;me++)j.call(this,this._deferreds[me]);this._deferreds=null}function ce(me,De,J,Te){this.onFulfilled=typeof me=="function"?me:null,this.onRejected=typeof De=="function"?De:null,this.resolve=J,this.reject=Te}function Q(me,De,J){var Te=!1;try{me(function(Oe){Te||(Te=!0,De(Oe))},function(Oe){Te||(Te=!0,J(Oe))})}catch(Oe){if(Te)return;Te=!0,J(Oe)}}var oe=N.immediateFn||typeof c=="function"&&c||function(me){setTimeout(me,1)},Se=Array.isArray||function(me){return Object.prototype.toString.call(me)==="[object Array]"};N.prototype.catch=function(me){return this.then(null,me)},N.prototype.then=function(me,De){var J=this;return new N(function(Te,Oe){j.call(J,new ce(me,De,Te,Oe))})},N.all=function(){var me=Array.prototype.slice.call(arguments.length===1&&Se(arguments[0])?arguments[0]:arguments);return new N(function(De,J){function Te(ot,ct){try{if(ct&&(g(ct)=="object"||typeof ct=="function")){var Ue=ct.then;if(typeof Ue=="function")return void Ue.call(ct,function(be){Te(ot,be)},J)}me[ot]=ct,--Oe==0&&De(me)}catch(be){J(be)}}if(me.length===0)return De([]);for(var Oe=me.length,Le=0;LeTe;Te++)me[Te].then(De,J)})},i.exports?i.exports=N:D.Promise||(D.Promise=N)}(this),x.copy=function(D){return new Promise(function(L,N){if(typeof D!="string"&&!("text/plain"in D))throw new Error("You must provide a text/plain type.");var j=typeof D=="string"?D:D["text/plain"];window.clipboardData.setData("Text",j)?L():N(new Error("Copying was rejected."))})},x.paste=function(){return new Promise(function(D,L){var N=window.clipboardData.getData("Text");N?D(N):L(new Error("Pasting was rejected."))})}),x}()}).call(this,f(13).setImmediate)},function(i,u,f){"use strict";i.exports=f(15)},function(i,u,f){"use strict";f.r(u),u.default=`:root { + /** + * IMPORTANT: When new theme variables are added below\u2013 also add them to SettingsContext updateThemeVariables() + */ + + /* Light theme */ + --light-color-attribute-name: #ef6632; + --light-color-attribute-name-not-editable: #23272f; + --light-color-attribute-name-inverted: rgba(255, 255, 255, 0.7); + --light-color-attribute-value: #1a1aa6; + --light-color-attribute-value-inverted: #ffffff; + --light-color-attribute-editable-value: #1a1aa6; + --light-color-background: #ffffff; + --light-color-background-hover: rgba(0, 136, 250, 0.1); + --light-color-background-inactive: #e5e5e5; + --light-color-background-invalid: #fff0f0; + --light-color-background-selected: #0088fa; + --light-color-button-background: #ffffff; + --light-color-button-background-focus: #ededed; + --light-color-button: #5f6673; + --light-color-button-disabled: #cfd1d5; + --light-color-button-active: #0088fa; + --light-color-button-focus: #23272f; + --light-color-button-hover: #23272f; + --light-color-border: #eeeeee; + --light-color-commit-did-not-render-fill: #cfd1d5; + --light-color-commit-did-not-render-fill-text: #000000; + --light-color-commit-did-not-render-pattern: #cfd1d5; + --light-color-commit-did-not-render-pattern-text: #333333; + --light-color-commit-gradient-0: #37afa9; + --light-color-commit-gradient-1: #63b19e; + --light-color-commit-gradient-2: #80b393; + --light-color-commit-gradient-3: #97b488; + --light-color-commit-gradient-4: #abb67d; + --light-color-commit-gradient-5: #beb771; + --light-color-commit-gradient-6: #cfb965; + --light-color-commit-gradient-7: #dfba57; + --light-color-commit-gradient-8: #efbb49; + --light-color-commit-gradient-9: #febc38; + --light-color-commit-gradient-text: #000000; + --light-color-component-name: #6a51b2; + --light-color-component-name-inverted: #ffffff; + --light-color-component-badge-background: rgba(0, 0, 0, 0.1); + --light-color-component-badge-background-inverted: rgba(255, 255, 255, 0.25); + --light-color-component-badge-count: #777d88; + --light-color-component-badge-count-inverted: rgba(255, 255, 255, 0.7); + --light-color-context-background: rgba(0,0,0,.9); + --light-color-context-background-hover: rgba(255, 255, 255, 0.1); + --light-color-context-background-selected: #178fb9; + --light-color-context-border: #3d424a; + --light-color-context-text: #ffffff; + --light-color-context-text-selected: #ffffff; + --light-color-dim: #777d88; + --light-color-dimmer: #cfd1d5; + --light-color-dimmest: #eff0f1; + --light-color-error-background: hsl(0, 100%, 97%); + --light-color-error-border: hsl(0, 100%, 92%); + --light-color-error-text: #ff0000; + --light-color-expand-collapse-toggle: #777d88; + --light-color-link: #0000ff; + --light-color-modal-background: rgba(255, 255, 255, 0.75); + --light-color-record-active: #fc3a4b; + --light-color-record-hover: #3578e5; + --light-color-record-inactive: #0088fa; + --light-color-scroll-thumb: #c2c2c2; + --light-color-scroll-track: #fafafa; + --light-color-search-match: yellow; + --light-color-search-match-current: #f7923b; + --light-color-selected-tree-highlight-active: rgba(0, 136, 250, 0.1); + --light-color-selected-tree-highlight-inactive: rgba(0, 0, 0, 0.05); + --light-color-shadow: rgba(0, 0, 0, 0.25); + --light-color-tab-selected-border: #0088fa; + --light-color-text: #000000; + --light-color-text-invalid: #ff0000; + --light-color-text-selected: #ffffff; + --light-color-toggle-background-invalid: #fc3a4b; + --light-color-toggle-background-on: #0088fa; + --light-color-toggle-background-off: #cfd1d5; + --light-color-toggle-text: #ffffff; + --light-color-tooltip-background: rgba(0, 0, 0, 0.9); + --light-color-tooltip-text: #ffffff; + + /* Dark theme */ + --dark-color-attribute-name: #9d87d2; + --dark-color-attribute-name-not-editable: #ededed; + --dark-color-attribute-name-inverted: #282828; + --dark-color-attribute-value: #cedae0; + --dark-color-attribute-value-inverted: #ffffff; + --dark-color-attribute-editable-value: yellow; + --dark-color-background: #282c34; + --dark-color-background-hover: rgba(255, 255, 255, 0.1); + --dark-color-background-inactive: #3d424a; + --dark-color-background-invalid: #5c0000; + --dark-color-background-selected: #178fb9; + --dark-color-button-background: #282c34; + --dark-color-button-background-focus: #3d424a; + --dark-color-button: #afb3b9; + --dark-color-button-active: #61dafb; + --dark-color-button-disabled: #4f5766; + --dark-color-button-focus: #a2e9fc; + --dark-color-button-hover: #ededed; + --dark-color-border: #3d424a; + --dark-color-commit-did-not-render-fill: #777d88; + --dark-color-commit-did-not-render-fill-text: #000000; + --dark-color-commit-did-not-render-pattern: #666c77; + --dark-color-commit-did-not-render-pattern-text: #ffffff; + --dark-color-commit-gradient-0: #37afa9; + --dark-color-commit-gradient-1: #63b19e; + --dark-color-commit-gradient-2: #80b393; + --dark-color-commit-gradient-3: #97b488; + --dark-color-commit-gradient-4: #abb67d; + --dark-color-commit-gradient-5: #beb771; + --dark-color-commit-gradient-6: #cfb965; + --dark-color-commit-gradient-7: #dfba57; + --dark-color-commit-gradient-8: #efbb49; + --dark-color-commit-gradient-9: #febc38; + --dark-color-commit-gradient-text: #000000; + --dark-color-component-name: #61dafb; + --dark-color-component-name-inverted: #282828; + --dark-color-component-badge-background: rgba(255, 255, 255, 0.25); + --dark-color-component-badge-background-inverted: rgba(0, 0, 0, 0.25); + --dark-color-component-badge-count: #8f949d; + --dark-color-component-badge-count-inverted: rgba(255, 255, 255, 0.7); + --dark-color-context-background: rgba(255,255,255,.9); + --dark-color-context-background-hover: rgba(0, 136, 250, 0.1); + --dark-color-context-background-selected: #0088fa; + --dark-color-context-border: #eeeeee; + --dark-color-context-text: #000000; + --dark-color-context-text-selected: #ffffff; + --dark-color-dim: #8f949d; + --dark-color-dimmer: #777d88; + --dark-color-dimmest: #4f5766; + --dark-color-error-background: #200; + --dark-color-error-border: #900; + --dark-color-error-text: #f55; + --dark-color-expand-collapse-toggle: #8f949d; + --dark-color-link: #61dafb; + --dark-color-modal-background: rgba(0, 0, 0, 0.75); + --dark-color-record-active: #fc3a4b; + --dark-color-record-hover: #a2e9fc; + --dark-color-record-inactive: #61dafb; + --dark-color-scroll-thumb: #afb3b9; + --dark-color-scroll-track: #313640; + --dark-color-search-match: yellow; + --dark-color-search-match-current: #f7923b; + --dark-color-selected-tree-highlight-active: rgba(23, 143, 185, 0.15); + --dark-color-selected-tree-highlight-inactive: rgba(255, 255, 255, 0.05); + --dark-color-shadow: rgba(0, 0, 0, 0.5); + --dark-color-tab-selected-border: #178fb9; + --dark-color-text: #ffffff; + --dark-color-text-invalid: #ff8080; + --dark-color-text-selected: #ffffff; + --dark-color-toggle-background-invalid: #fc3a4b; + --dark-color-toggle-background-on: #178fb9; + --dark-color-toggle-background-off: #777d88; + --dark-color-toggle-text: #ffffff; + --dark-color-tooltip-background: rgba(255, 255, 255, 0.9); + --dark-color-tooltip-text: #000000; + + /* Font smoothing */ + --light-font-smoothing: auto; + --dark-font-smoothing: antialiased; + --font-smoothing: auto; + + /* Compact density */ + --compact-font-size-monospace-small: 9px; + --compact-font-size-monospace-normal: 11px; + --compact-font-size-monospace-large: 15px; + --compact-font-size-sans-small: 10px; + --compact-font-size-sans-normal: 12px; + --compact-font-size-sans-large: 14px; + --compact-line-height-data: 18px; + --compact-root-font-size: 16px; + + /* Comfortable density */ + --comfortable-font-size-monospace-small: 10px; + --comfortable-font-size-monospace-normal: 13px; + --comfortable-font-size-monospace-large: 17px; + --comfortable-font-size-sans-small: 12px; + --comfortable-font-size-sans-normal: 14px; + --comfortable-font-size-sans-large: 16px; + --comfortable-line-height-data: 22px; + --comfortable-root-font-size: 20px; + + /* GitHub.com system fonts */ + --font-family-monospace: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, + Courier, monospace; + --font-family-sans: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, + Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol; + + /* Constant values shared between JS and CSS */ + --interaction-commit-size: 10px; + --interaction-label-width: 200px; +} +`},function(i,u,f){"use strict";function c(x){var D=this;if(D instanceof c||(D=new c),D.tail=null,D.head=null,D.length=0,x&&typeof x.forEach=="function")x.forEach(function(j){D.push(j)});else if(arguments.length>0)for(var L=0,N=arguments.length;L1)L=D;else{if(!this.head)throw new TypeError("Reduce of empty list with no initial value");N=this.head.next,L=this.head.value}for(var j=0;N!==null;j++)L=x(L,N.value,j),N=N.next;return L},c.prototype.reduceReverse=function(x,D){var L,N=this.tail;if(arguments.length>1)L=D;else{if(!this.tail)throw new TypeError("Reduce of empty list with no initial value");N=this.tail.prev,L=this.tail.value}for(var j=this.length-1;N!==null;j--)L=x(L,N.value,j),N=N.prev;return L},c.prototype.toArray=function(){for(var x=new Array(this.length),D=0,L=this.head;L!==null;D++)x[D]=L.value,L=L.next;return x},c.prototype.toArrayReverse=function(){for(var x=new Array(this.length),D=0,L=this.tail;L!==null;D++)x[D]=L.value,L=L.prev;return x},c.prototype.slice=function(x,D){(D=D||this.length)<0&&(D+=this.length),(x=x||0)<0&&(x+=this.length);var L=new c;if(Dthis.length&&(D=this.length);for(var N=0,j=this.head;j!==null&&Nthis.length&&(D=this.length);for(var N=this.length,j=this.tail;j!==null&&N>D;N--)j=j.prev;for(;j!==null&&N>x;N--,j=j.prev)L.push(j.value);return L},c.prototype.splice=function(x,D){x>this.length&&(x=this.length-1),x<0&&(x=this.length+x);for(var L=0,N=this.head;N!==null&&L=0&&(A._idleTimeoutId=setTimeout(function(){A._onTimeout&&A._onTimeout()},x))},f(14),u.setImmediate=typeof self!="undefined"&&self.setImmediate||c!==void 0&&c.setImmediate||this&&this.setImmediate,u.clearImmediate=typeof self!="undefined"&&self.clearImmediate||c!==void 0&&c.clearImmediate||this&&this.clearImmediate}).call(this,f(4))},function(i,u,f){(function(c,g){(function(t,C){"use strict";if(!t.setImmediate){var A,x,D,L,N,j=1,$={},h=!1,re=t.document,ce=Object.getPrototypeOf&&Object.getPrototypeOf(t);ce=ce&&ce.setTimeout?ce:t,{}.toString.call(t.process)==="[object process]"?A=function(Se){g.nextTick(function(){oe(Se)})}:function(){if(t.postMessage&&!t.importScripts){var Se=!0,me=t.onmessage;return t.onmessage=function(){Se=!1},t.postMessage("","*"),t.onmessage=me,Se}}()?(L="setImmediate$"+Math.random()+"$",N=function(Se){Se.source===t&&typeof Se.data=="string"&&Se.data.indexOf(L)===0&&oe(+Se.data.slice(L.length))},t.addEventListener?t.addEventListener("message",N,!1):t.attachEvent("onmessage",N),A=function(Se){t.postMessage(L+Se,"*")}):t.MessageChannel?((D=new MessageChannel).port1.onmessage=function(Se){oe(Se.data)},A=function(Se){D.port2.postMessage(Se)}):re&&"onreadystatechange"in re.createElement("script")?(x=re.documentElement,A=function(Se){var me=re.createElement("script");me.onreadystatechange=function(){oe(Se),me.onreadystatechange=null,x.removeChild(me),me=null},x.appendChild(me)}):A=function(Se){setTimeout(oe,0,Se)},ce.setImmediate=function(Se){typeof Se!="function"&&(Se=new Function(""+Se));for(var me=new Array(arguments.length-1),De=0;Dene;ne++)if((V=Q(Je,Ot,ne))!==-1){ce=ne,Ot=V;break e}Ot=-1}}e:{if(Je=Nt,(V=j().get(At.primitive))!==void 0){for(ne=0;neOt-Je?null:Nt.slice(Je,Ot-1))!==null){if(Ot=0,Le!==null){for(;OtOt;Le--)ot=Ue.pop()}for(Le=Nt.length-Ot-1;1<=Le;Le--)Ot=[],ot.push({id:null,isStateEditable:!1,name:Se(Nt[Le-1].functionName),value:void 0,subHooks:Ot}),Ue.push(ot),ot=Ot;Le=Nt}Ot=(Nt=At.primitive)==="Context"||Nt==="DebugValue"?null:ct++,ot.push({id:Ot,isStateEditable:Nt==="Reducer"||Nt==="State",name:Nt,value:At.value,subHooks:[]})}return function ge(Z,Ae){for(var at=[],it=0;it-1&&($=$.replace(/eval code/g,"eval").replace(/(\(eval at [^()]*)|(\),.*$)/g,""));var h=$.replace(/^\s+/,"").replace(/\(eval code/g,"("),re=h.match(/ (\((.+):(\d+):(\d+)\)$)/),ce=(h=re?h.replace(re[0],""):h).split(/\s+/).slice(1),Q=this.extractLocation(re?re[1]:ce.pop()),oe=ce.join(" ")||void 0,Se=["eval",""].indexOf(Q[0])>-1?void 0:Q[0];return new x({functionName:oe,fileName:Se,lineNumber:Q[1],columnNumber:Q[2],source:$})},this)},parseFFOrSafari:function(j){return j.stack.split(` +`).filter(function($){return!$.match(N)},this).map(function($){if($.indexOf(" > eval")>-1&&($=$.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g,":$1")),$.indexOf("@")===-1&&$.indexOf(":")===-1)return new x({functionName:$});var h=/((.*".+"[^@]*)?[^@]*)(?:@)/,re=$.match(h),ce=re&&re[1]?re[1]:void 0,Q=this.extractLocation($.replace(h,""));return new x({functionName:ce,fileName:Q[0],lineNumber:Q[1],columnNumber:Q[2],source:$})},this)},parseOpera:function(j){return!j.stacktrace||j.message.indexOf(` +`)>-1&&j.message.split(` +`).length>j.stacktrace.split(` +`).length?this.parseOpera9(j):j.stack?this.parseOpera11(j):this.parseOpera10(j)},parseOpera9:function(j){for(var $=/Line (\d+).*script (?:in )?(\S+)/i,h=j.message.split(` +`),re=[],ce=2,Q=h.length;ce/,"$2").replace(/\([^)]*\)/g,"")||void 0;Q.match(/\(([^)]*)\)/)&&(h=Q.replace(/^[^(]+\(([^)]*)\)$/,"$1"));var Se=h===void 0||h==="[arguments not available]"?void 0:h.split(",");return new x({functionName:oe,args:Se,fileName:ce[0],lineNumber:ce[1],columnNumber:ce[2],source:$})},this)}}})=="function"?c.apply(u,g):c)===void 0||(i.exports=t)})()},function(i,u,f){var c,g,t;(function(C,A){"use strict";g=[],(t=typeof(c=function(){function x(oe){return oe.charAt(0).toUpperCase()+oe.substring(1)}function D(oe){return function(){return this[oe]}}var L=["isConstructor","isEval","isNative","isToplevel"],N=["columnNumber","lineNumber"],j=["fileName","functionName","source"],$=L.concat(N,j,["args"]);function h(oe){if(oe)for(var Se=0;Se<$.length;Se++)oe[$[Se]]!==void 0&&this["set"+x($[Se])](oe[$[Se]])}h.prototype={getArgs:function(){return this.args},setArgs:function(oe){if(Object.prototype.toString.call(oe)!=="[object Array]")throw new TypeError("Args must be an Array");this.args=oe},getEvalOrigin:function(){return this.evalOrigin},setEvalOrigin:function(oe){if(oe instanceof h)this.evalOrigin=oe;else{if(!(oe instanceof Object))throw new TypeError("Eval Origin must be an Object or StackFrame");this.evalOrigin=new h(oe)}},toString:function(){var oe=this.getFileName()||"",Se=this.getLineNumber()||"",me=this.getColumnNumber()||"",De=this.getFunctionName()||"";return this.getIsEval()?oe?"[eval] ("+oe+":"+Se+":"+me+")":"[eval]:"+Se+":"+me:De?De+" ("+oe+":"+Se+":"+me+")":oe+":"+Se+":"+me}},h.fromString=function(oe){var Se=oe.indexOf("("),me=oe.lastIndexOf(")"),De=oe.substring(0,Se),J=oe.substring(Se+1,me).split(","),Te=oe.substring(me+1);if(Te.indexOf("@")===0)var Oe=/@(.+?)(?::(\d+))?(?::(\d+))?$/.exec(Te,""),Le=Oe[1],ot=Oe[2],ct=Oe[3];return new h({functionName:De,args:J||void 0,fileName:Le,lineNumber:ot||void 0,columnNumber:ct||void 0})};for(var re=0;re1?de-1:0),ve=1;ve=0&&de.splice(W,1)}}}])&&c(R.prototype,U),H&&c(R,H),F}(),t=f(2),C=f.n(t);try{var A=f(9).default,x=function(F){var R=new RegExp("".concat(F,": ([0-9]+)")),U=A.match(R);return parseInt(U[1],10)};x("comfortable-line-height-data"),x("compact-line-height-data")}catch(F){}function D(F){try{return sessionStorage.getItem(F)}catch(R){return null}}function L(F){try{sessionStorage.removeItem(F)}catch(R){}}function N(F,R){try{return sessionStorage.setItem(F,R)}catch(U){}}var j=function(F,R){return F===R},$=f(1),h=f.n($);function re(F){return F.ownerDocument?F.ownerDocument.defaultView:null}function ce(F){var R=re(F);return R?R.frameElement:null}function Q(F){var R=me(F);return oe([F.getBoundingClientRect(),{top:R.borderTop,left:R.borderLeft,bottom:R.borderBottom,right:R.borderRight,width:0,height:0}])}function oe(F){return F.reduce(function(R,U){return R==null?U:{top:R.top+U.top,left:R.left+U.left,width:R.width,height:R.height,bottom:R.bottom+U.bottom,right:R.right+U.right}})}function Se(F,R){var U=ce(F);if(U&&U!==R){for(var H=[F.getBoundingClientRect()],fe=U,ue=!1;fe;){var de=Q(fe);if(H.push(de),fe=ce(fe),ue)break;fe&&re(fe)===R&&(ue=!0)}return oe(H)}return F.getBoundingClientRect()}function me(F){var R=window.getComputedStyle(F);return{borderLeft:parseInt(R.borderLeftWidth,10),borderRight:parseInt(R.borderRightWidth,10),borderTop:parseInt(R.borderTopWidth,10),borderBottom:parseInt(R.borderBottomWidth,10),marginLeft:parseInt(R.marginLeft,10),marginRight:parseInt(R.marginRight,10),marginTop:parseInt(R.marginTop,10),marginBottom:parseInt(R.marginBottom,10),paddingLeft:parseInt(R.paddingLeft,10),paddingRight:parseInt(R.paddingRight,10),paddingTop:parseInt(R.paddingTop,10),paddingBottom:parseInt(R.paddingBottom,10)}}function De(F,R){var U;if(typeof Symbol=="undefined"||F[Symbol.iterator]==null){if(Array.isArray(F)||(U=function(ve,Fe){if(!!ve){if(typeof ve=="string")return J(ve,Fe);var Ge=Object.prototype.toString.call(ve).slice(8,-1);if(Ge==="Object"&&ve.constructor&&(Ge=ve.constructor.name),Ge==="Map"||Ge==="Set")return Array.from(ve);if(Ge==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(Ge))return J(ve,Fe)}}(F))||R&&F&&typeof F.length=="number"){U&&(F=U);var H=0,fe=function(){};return{s:fe,n:function(){return H>=F.length?{done:!0}:{done:!1,value:F[H++]}},e:function(ve){throw ve},f:fe}}throw new TypeError(`Invalid attempt to iterate non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var ue,de=!0,W=!1;return{s:function(){U=F[Symbol.iterator]()},n:function(){var ve=U.next();return de=ve.done,ve},e:function(ve){W=!0,ue=ve},f:function(){try{de||U.return==null||U.return()}finally{if(W)throw ue}}}}function J(F,R){(R==null||R>F.length)&&(R=F.length);for(var U=0,H=new Array(R);Ude.left+de.width&&(K=de.left+de.width-Ge-5),{style:{top:ve+="px",left:K+="px"}}}(R,U,{width:H.width,height:H.height});h()(this.tip.style,fe.style)}}]),F}(),Ue=function(){function F(){Te(this,F);var R=window.__REACT_DEVTOOLS_TARGET_WINDOW__||window;this.window=R;var U=window.__REACT_DEVTOOLS_TARGET_WINDOW__||window;this.tipBoundsWindow=U;var H=R.document;this.container=H.createElement("div"),this.container.style.zIndex="10000000",this.tip=new ct(H,this.container),this.rects=[],H.body.appendChild(this.container)}return Le(F,[{key:"remove",value:function(){this.tip.remove(),this.rects.forEach(function(R){R.remove()}),this.rects.length=0,this.container.parentNode&&this.container.parentNode.removeChild(this.container)}},{key:"inspect",value:function(R,U){for(var H=this,fe=R.filter(function(Xe){return Xe.nodeType===Node.ELEMENT_NODE});this.rects.length>fe.length;)this.rects.pop().remove();if(fe.length!==0){for(;this.rects.length1&&arguments[1]!==void 0?arguments[1]:j,je=void 0,Xe=[],rt=void 0,st=!1,xt=function(lt,Rt){return xe(lt,Xe[Rt])},wt=function(){for(var lt=arguments.length,Rt=Array(lt),yn=0;yn5&&arguments[5]!==void 0?arguments[5]:0,W=cl(F);switch(W){case"html_element":return R.push(H),{inspectable:!1,preview_short:Mr(F,!1),preview_long:Mr(F,!0),name:F.tagName,type:W};case"function":return R.push(H),{inspectable:!1,preview_short:Mr(F,!1),preview_long:Mr(F,!0),name:typeof F.name!="function"&&F.name?F.name:"function",type:W};case"string":return F.length<=500?F:F.slice(0,500)+"...";case"bigint":case"symbol":return R.push(H),{inspectable:!1,preview_short:Mr(F,!1),preview_long:Mr(F,!0),name:F.toString(),type:W};case"react_element":return R.push(H),{inspectable:!1,preview_short:Mr(F,!1),preview_long:Mr(F,!0),name:al(F)||"Unknown",type:W};case"array_buffer":case"data_view":return R.push(H),{inspectable:!1,preview_short:Mr(F,!1),preview_long:Mr(F,!0),name:W==="data_view"?"DataView":"ArrayBuffer",size:F.byteLength,type:W};case"array":return ue=fe(H),de>=2&&!ue?yo(W,!0,F,R,H):F.map(function(Ge,K){return Ds(Ge,R,U,H.concat([K]),fe,ue?1:de+1)});case"html_all_collection":case"typed_array":case"iterator":if(ue=fe(H),de>=2&&!ue)return yo(W,!0,F,R,H);var ve={unserializable:!0,type:W,readonly:!0,size:W==="typed_array"?F.length:void 0,preview_short:Mr(F,!1),preview_long:Mr(F,!0),name:F.constructor&&F.constructor.name!=="Object"?F.constructor.name:""};return r0(F[Symbol.iterator])&&Array.from(F).forEach(function(Ge,K){return ve[K]=Ds(Ge,R,U,H.concat([K]),fe,ue?1:de+1)}),U.push(H),ve;case"opaque_iterator":return R.push(H),{inspectable:!1,preview_short:Mr(F,!1),preview_long:Mr(F,!0),name:F[Symbol.toStringTag],type:W};case"date":case"regexp":return R.push(H),{inspectable:!1,preview_short:Mr(F,!1),preview_long:Mr(F,!0),name:F.toString(),type:W};case"object":if(ue=fe(H),de>=2&&!ue)return yo(W,!0,F,R,H);var Fe={};return Es(F).forEach(function(Ge){var K=Ge.toString();Fe[K]=Ds(F[Ge],R,U,H.concat([K]),fe,ue?1:de+1)}),Fe;case"infinity":case"nan":case"undefined":return R.push(H),{type:W};default:return F}}function Mu(F){return(Mu=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(R){return typeof R}:function(R){return R&&typeof Symbol=="function"&&R.constructor===Symbol&&R!==Symbol.prototype?"symbol":typeof R})(F)}function Gf(F){return function(R){if(Array.isArray(R))return iu(R)}(F)||function(R){if(typeof Symbol!="undefined"&&Symbol.iterator in Object(R))return Array.from(R)}(F)||function(R,U){if(!!R){if(typeof R=="string")return iu(R,U);var H=Object.prototype.toString.call(R).slice(8,-1);if(H==="Object"&&R.constructor&&(H=R.constructor.name),H==="Map"||H==="Set")return Array.from(R);if(H==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(H))return iu(R,U)}}(F)||function(){throw new TypeError(`Invalid attempt to spread non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}()}function iu(F,R){(R==null||R>F.length)&&(R=F.length);for(var U=0,H=new Array(R);UR.toString()?1:R.toString()>F.toString()?-1:0}function Es(F){for(var R=[],U=F,H=function(){var fe=[].concat(Gf(Object.keys(U)),Gf(Object.getOwnPropertySymbols(U))),ue=Object.getOwnPropertyDescriptors(U);fe.forEach(function(de){ue[de].enumerable&&R.push(de)}),U=Object.getPrototypeOf(U)};U!=null;)H();return R}function Uo(F){var R=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"Anonymous",U=ou.get(F);if(U!=null)return U;var H=R;return typeof F.displayName=="string"?H=F.displayName:typeof F.name=="string"&&F.name!==""&&(H=F.name),ou.set(F,H),H}var sl=0;function Ss(){return++sl}function Cs(F){var R=ol.get(F);if(R!==void 0)return R;for(var U=new Array(F.length),H=0;H1&&arguments[1]!==void 0?arguments[1]:50;return F.length>R?F.substr(0,R)+"\u2026":F}function Mr(F,R){if(F!=null&&hasOwnProperty.call(F,Ci.type))return R?F[Ci.preview_long]:F[Ci.preview_short];switch(cl(F)){case"html_element":return"<".concat(Ui(F.tagName.toLowerCase())," />");case"function":return Ui("\u0192 ".concat(typeof F.name=="function"?"":F.name,"() {}"));case"string":return'"'.concat(F,'"');case"bigint":return Ui(F.toString()+"n");case"regexp":case"symbol":return Ui(F.toString());case"react_element":return"<".concat(Ui(al(F)||"Unknown")," />");case"array_buffer":return"ArrayBuffer(".concat(F.byteLength,")");case"data_view":return"DataView(".concat(F.buffer.byteLength,")");case"array":if(R){for(var U="",H=0;H0&&(U+=", "),!((U+=Mr(F[H],!1)).length>50));H++);return"[".concat(Ui(U),"]")}var fe=hasOwnProperty.call(F,Ci.size)?F[Ci.size]:F.length;return"Array(".concat(fe,")");case"typed_array":var ue="".concat(F.constructor.name,"(").concat(F.length,")");if(R){for(var de="",W=0;W0&&(de+=", "),!((de+=F[W]).length>50));W++);return"".concat(ue," [").concat(Ui(de),"]")}return ue;case"iterator":var ve=F.constructor.name;if(R){for(var Fe=Array.from(F),Ge="",K=0;K0&&(Ge+=", "),Array.isArray(xe)){var je=Mr(xe[0],!0),Xe=Mr(xe[1],!1);Ge+="".concat(je," => ").concat(Xe)}else Ge+=Mr(xe,!1);if(Ge.length>50)break}return"".concat(ve,"(").concat(F.size,") {").concat(Ui(Ge),"}")}return"".concat(ve,"(").concat(F.size,")");case"opaque_iterator":return F[Symbol.toStringTag];case"date":return F.toString();case"object":if(R){for(var rt=Es(F).sort(ul),st="",xt=0;xt0&&(st+=", "),(st+="".concat(wt.toString(),": ").concat(Mr(F[wt],!1))).length>50)break}return"{".concat(Ui(st),"}")}return"{\u2026}";case"boolean":case"number":case"infinity":case"nan":case"null":case"undefined":return F;default:try{return Ui(""+F)}catch(lt){return"unserializable"}}}var Ac=f(7);function of(F){return(of=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(R){return typeof R}:function(R){return R&&typeof Symbol=="function"&&R.constructor===Symbol&&R!==Symbol.prototype?"symbol":typeof R})(F)}function Ts(F,R){var U=Object.keys(F);if(Object.getOwnPropertySymbols){var H=Object.getOwnPropertySymbols(F);R&&(H=H.filter(function(fe){return Object.getOwnPropertyDescriptor(F,fe).enumerable})),U.push.apply(U,H)}return U}function xs(F){for(var R=1;R2&&arguments[2]!==void 0?arguments[2]:[];if(F!==null){var H=[],fe=[],ue=Ds(F,H,fe,U,R);return{data:ue,cleaned:H,unserializable:fe}}return null}function qo(F){var R,U,H=(R=F,U=new Set,JSON.stringify(R,function(de,W){if(of(W)==="object"&&W!==null){if(U.has(W))return;U.add(W)}return typeof W=="bigint"?W.toString()+"n":W})),fe=H===void 0?"undefined":H,ue=window.__REACT_DEVTOOLS_GLOBAL_HOOK__.clipboardCopyText;typeof ue=="function"?ue(fe).catch(function(de){}):Object(Ac.copy)(fe)}function kr(F,R){var U=arguments.length>2&&arguments[2]!==void 0?arguments[2]:0,H=R[U],fe=Array.isArray(F)?F.slice():xs({},F);return U+1===R.length?Array.isArray(fe)?fe.splice(H,1):delete fe[H]:fe[H]=kr(F[H],R,U+1),fe}function Fr(F,R,U){var H=arguments.length>3&&arguments[3]!==void 0?arguments[3]:0,fe=R[H],ue=Array.isArray(F)?F.slice():xs({},F);if(H+1===R.length){var de=U[H];ue[de]=ue[fe],Array.isArray(ue)?ue.splice(fe,1):delete ue[fe]}else ue[fe]=Fr(F[fe],R,U,H+1);return ue}function si(F,R,U){var H=arguments.length>3&&arguments[3]!==void 0?arguments[3]:0;if(H>=R.length)return U;var fe=R[H],ue=Array.isArray(F)?F.slice():xs({},F);return ue[fe]=si(F[fe],R,U,H+1),ue}var H0=f(8);function b0(F,R){var U=Object.keys(F);if(Object.getOwnPropertySymbols){var H=Object.getOwnPropertySymbols(F);R&&(H=H.filter(function(fe){return Object.getOwnPropertyDescriptor(F,fe).enumerable})),U.push.apply(U,H)}return U}function Bt(F){for(var R=1;R=F.length?{done:!0}:{done:!1,value:F[H++]}},e:function(ve){throw ve},f:fe}}throw new TypeError(`Invalid attempt to iterate non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var ue,de=!0,W=!1;return{s:function(){U=F[Symbol.iterator]()},n:function(){var ve=U.next();return de=ve.done,ve},e:function(ve){W=!0,ue=ve},f:function(){try{de||U.return==null||U.return()}finally{if(W)throw ue}}}}function As(F,R){if(F){if(typeof F=="string")return uu(F,R);var U=Object.prototype.toString.call(F).slice(8,-1);return U==="Object"&&F.constructor&&(U=F.constructor.name),U==="Map"||U==="Set"?Array.from(F):U==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(U)?uu(F,R):void 0}}function uu(F,R){(R==null||R>F.length)&&(R=F.length);for(var U=0,H=new Array(R);U0){var et=ue(X);if(et!=null){var Dt,bt=ks(du);try{for(bt.s();!(Dt=bt.n()).done;)if(Dt.value.test(et))return!0}catch(fn){bt.e(fn)}finally{bt.f()}}}if(Y!=null&&Yu.size>0){var Zt,qt=Y.fileName,Ut=ks(Yu);try{for(Ut.s();!(Zt=Ut.n()).done;)if(Zt.value.test(qt))return!0}catch(fn){Ut.e(fn)}finally{Ut.f()}}return!1}function Gr(X){var Y=X.type;switch(X.tag){case Xe:case ar:return 1;case je:case rn:return 5;case wt:return 6;case lt:return 11;case yn:return 7;case Rt:case sn:case xt:return 9;case Hn:case Cr:return 8;case He:return 12;case Qe:return 13;default:switch(de(Y)){case 60111:case"Symbol(react.concurrent_mode)":case"Symbol(react.async_mode)":return 9;case 60109:case"Symbol(react.provider)":return 2;case 60110:case"Symbol(react.context)":return 2;case 60108:case"Symbol(react.strict_mode)":return 9;case 60114:case"Symbol(react.profiler)":return 10;default:return 9}}}function ir(X){if(Co.has(X))return X;var Y=X.alternate;return Y!=null&&Co.has(Y)?Y:(Co.add(X),X)}window.__REACT_DEVTOOLS_COMPONENT_FILTERS__!=null?qs(window.__REACT_DEVTOOLS_COMPONENT_FILTERS__):qs([{type:1,value:7,isEnabled:!0}]);var L0=new Map,Y0=new Map,Co=new Set,$u=new Map,Vo=new Map,Rr=-1;function Jn(X){if(!L0.has(X)){var Y=Ss();L0.set(X,Y),Y0.set(Y,X)}return L0.get(X)}function ai(X){switch(Gr(X)){case 1:if(N0!==null){var Y=Jn(ir(X)),ye=Vr(X);ye!==null&&N0.set(Y,ye)}}}var o0={};function Vr(X){switch(Gr(X)){case 1:var Y=X.stateNode,ye=o0,he=o0;return Y!=null&&(Y.constructor&&Y.constructor.contextType!=null?he=Y.context:(ye=Y.context)&&Object.keys(ye).length===0&&(ye=o0)),[ye,he];default:return null}}function ff(X){switch(Gr(X)){case 1:if(N0!==null){var Y=Jn(ir(X)),ye=N0.has(Y)?N0.get(Y):null,he=Vr(X);if(ye==null||he==null)return null;var We=Ru(ye,2),et=We[0],Dt=We[1],bt=Ru(he,2),Zt=bt[0],qt=bt[1];if(Zt!==o0)return $0(et,Zt);if(qt!==o0)return Dt!==qt}}return null}function cf(X,Y){if(X==null||Y==null)return!1;if(Y.hasOwnProperty("baseState")&&Y.hasOwnProperty("memoizedState")&&Y.hasOwnProperty("next")&&Y.hasOwnProperty("queue"))for(;Y!==null;){if(Y.memoizedState!==X.memoizedState)return!0;Y=Y.next,X=X.next}return!1}function $0(X,Y){if(X==null||Y==null||Y.hasOwnProperty("baseState")&&Y.hasOwnProperty("memoizedState")&&Y.hasOwnProperty("next")&&Y.hasOwnProperty("queue"))return null;var ye,he=[],We=ks(new Set([].concat(c0(Object.keys(X)),c0(Object.keys(Y)))));try{for(We.s();!(ye=We.n()).done;){var et=ye.value;X[et]!==Y[et]&&he.push(et)}}catch(Dt){We.e(Dt)}finally{We.f()}return he}function K0(X,Y){switch(Y.tag){case Xe:case je:case rt:case Hn:case Cr:return(zo(Y)&K)===K;default:return X.memoizedProps!==Y.memoizedProps||X.memoizedState!==Y.memoizedState||X.ref!==Y.ref}}var ae=[],Be=[],Ie=[],ht=[],mt=new Map,wn=0,Gn=null;function $t(X){ae.push(X)}function X0(X){if(ae.length!==0||Be.length!==0||Ie.length!==0||Gn!==null||u0){var Y=Be.length+Ie.length+(Gn===null?0:1),ye=new Array(3+wn+(Y>0?2+Y:0)+ae.length),he=0;if(ye[he++]=R,ye[he++]=Rr,ye[he++]=wn,mt.forEach(function(bt,Zt){ye[he++]=Zt.length;for(var qt=Cs(Zt),Ut=0;Ut0){ye[he++]=2,ye[he++]=Y;for(var We=Be.length-1;We>=0;We--)ye[he++]=Be[We];for(var et=0;et0?X.forEach(function(Y){F.emit("operations",Y)}):(Fn!==null&&(zr=!0),F.getFiberRoots(R).forEach(function(Y){T0(Rr=Jn(ir(Y.current)),Y.current),u0&&Y.memoizedInteractions!=null&&(uo={changeDescriptions:To?new Map:null,durations:[],commitTime:Os()-v0,interactions:Array.from(Y.memoizedInteractions).map(function(ye){return Bt(Bt({},ye),{},{timestamp:ye.timestamp-v0})}),maxActualDuration:0,priorityLevel:null}),$r(Y.current,null,!1,!1),X0(),Rr=-1}))},getBestMatchForTrackedPath:function(){if(Fn===null||pi===null)return null;for(var X=pi;X!==null&&F0(X);)X=X.return;return X===null?null:{id:Jn(ir(X)),isFullMatch:Br===Fn.length-1}},getDisplayNameForFiberID:function(X){var Y=Y0.get(X);return Y!=null?ue(Y):null},getFiberIDForNative:function(X){var Y=arguments.length>1&&arguments[1]!==void 0&&arguments[1],ye=U.findFiberByHostInstance(X);if(ye!=null){if(Y)for(;ye!==null&&F0(ye);)ye=ye.return;return Jn(ir(ye))}return null},getInstanceAndStyle:function(X){var Y=null,ye=null,he=J0(X);return he!==null&&(Y=he.stateNode,he.memoizedProps!==null&&(ye=he.memoizedProps.style)),{instance:Y,style:ye}},getOwnersList:function(X){var Y=J0(X);if(Y==null)return null;var ye=Y._debugOwner,he=[{displayName:ue(Y)||"Anonymous",id:X,type:Gr(Y)}];if(ye)for(var We=ye;We!==null;)he.unshift({displayName:ue(We)||"Anonymous",id:Jn(ir(We)),type:Gr(We)}),We=We._debugOwner||null;return he},getPathForElement:function(X){var Y=Y0.get(X);if(Y==null)return null;for(var ye=[];Y!==null;)ye.push(Ai(Y)),Y=Y.return;return ye.reverse(),ye},getProfilingData:function(){var X=[];if(pu===null)throw Error("getProfilingData() called before any profiling data was recorded");return pu.forEach(function(Y,ye){var he=[],We=[],et=new Map,Dt=new Map,bt=so!==null&&so.get(ye)||"Unknown";C0!=null&&C0.forEach(function(Zt,qt){di!=null&&di.get(qt)===ye&&We.push([qt,Zt])}),Y.forEach(function(Zt,qt){var Ut=Zt.changeDescriptions,fn=Zt.durations,_t=Zt.interactions,_r=Zt.maxActualDuration,Wr=Zt.priorityLevel,Ar=Zt.commitTime,z=[];_t.forEach(function(s0){et.has(s0.id)||et.set(s0.id,s0),z.push(s0.id);var t0=Dt.get(s0.id);t0!=null?t0.push(qt):Dt.set(s0.id,[qt])});for(var dr=[],Or=[],Qn=0;Qn1?kn.set(Ut,fn-1):kn.delete(Ut),wr.delete(Zt)}(Rr),Yr(ye,!1))}else T0(Rr,ye),$r(ye,null,!1,!1);if(u0&&We){var bt=pu.get(Rr);bt!=null?bt.push(uo):pu.set(Rr,[uo])}X0(),oo&&F.emit("traceUpdates",Hi),Rr=-1},handleCommitFiberUnmount:function(X){Yr(X,!1)},inspectElement:function(X,Y){if(Tr(X)){if(Y!=null){R0(Y);var ye=null;return Y[0]==="hooks"&&(ye="hooks"),{id:X,type:"hydrated-path",path:Y,value:qi(Ti(S0,Y),Nr(null,ye),Y)}}return{id:X,type:"no-change"}}if(El=!1,S0!==null&&S0.id===X||(Q0={}),(S0=af(X))===null)return{id:X,type:"not-found"};Y!=null&&R0(Y),function(We){var et=We.hooks,Dt=We.id,bt=We.props,Zt=Y0.get(Dt);if(Zt!=null){var qt=Zt.elementType,Ut=Zt.stateNode,fn=Zt.tag,_t=Zt.type;switch(fn){case Xe:case ar:case rn:H.$r=Ut;break;case je:H.$r={hooks:et,props:bt,type:_t};break;case wt:H.$r={props:bt,type:_t.render};break;case Hn:case Cr:H.$r={props:bt,type:qt!=null&&qt.type!=null?qt.type:_t};break;default:H.$r=null}}else console.warn('Could not find Fiber with id "'.concat(Dt,'"'))}(S0);var he=Bt({},S0);return he.context=qi(he.context,Nr("context",null)),he.hooks=qi(he.hooks,Nr("hooks","hooks")),he.props=qi(he.props,Nr("props",null)),he.state=qi(he.state,Nr("state",null)),{id:X,type:"full-data",value:he}},logElementToConsole:function(X){var Y=Tr(X)?S0:af(X);if(Y!==null){var ye=typeof console.groupCollapsed=="function";ye&&console.groupCollapsed("[Click to expand] %c<".concat(Y.displayName||"Component"," />"),"color: var(--dom-tag-name-color); font-weight: normal;"),Y.props!==null&&console.log("Props:",Y.props),Y.state!==null&&console.log("State:",Y.state),Y.hooks!==null&&console.log("Hooks:",Y.hooks);var he=zs(X);he!==null&&console.log("Nodes:",he),Y.source!==null&&console.log("Location:",Y.source),(window.chrome||/firefox/i.test(navigator.userAgent))&&console.log("Right-click any value to save it as a global variable for further inspection."),ye&&console.groupEnd()}else console.warn('Could not find Fiber with id "'.concat(X,'"'))},prepareViewAttributeSource:function(X,Y){Tr(X)&&(window.$attribute=Ti(S0,Y))},prepareViewElementSource:function(X){var Y=Y0.get(X);if(Y!=null){var ye=Y.elementType,he=Y.tag,We=Y.type;switch(he){case Xe:case ar:case rn:case je:H.$type=We;break;case wt:H.$type=We.render;break;case Hn:case Cr:H.$type=ye!=null&&ye.type!=null?ye.type:We;break;default:H.$type=null}}else console.warn('Could not find Fiber with id "'.concat(X,'"'))},overrideSuspense:function(X,Y){if(typeof Eo!="function"||typeof So!="function")throw new Error("Expected overrideSuspense() to not get called for earlier React versions.");Y?(B0.add(X),B0.size===1&&Eo(hu)):(B0.delete(X),B0.size===0&&Eo(Cl));var ye=Y0.get(X);ye!=null&&So(ye)},overrideValueAtPath:function(X,Y,ye,he,We){var et=J0(Y);if(et!==null){var Dt=et.stateNode;switch(X){case"context":switch(he=he.slice(1),et.tag){case Xe:he.length===0?Dt.context=We:fl(Dt.context,he,We),Dt.forceUpdate()}break;case"hooks":typeof p0=="function"&&p0(et,ye,he,We);break;case"props":switch(et.tag){case Xe:et.pendingProps=si(Dt.props,he,We),Dt.forceUpdate();break;default:typeof xi=="function"&&xi(et,he,We)}break;case"state":switch(et.tag){case Xe:fl(Dt.state,he,We),Dt.forceUpdate()}}}},renamePath:function(X,Y,ye,he,We){var et=J0(Y);if(et!==null){var Dt=et.stateNode;switch(X){case"context":switch(he=he.slice(1),We=We.slice(1),et.tag){case Xe:he.length===0||ll(Dt.context,he,We),Dt.forceUpdate()}break;case"hooks":typeof ci=="function"&&ci(et,ye,he,We);break;case"props":Dt===null?typeof qr=="function"&&qr(et,he,We):(et.pendingProps=Fr(Dt.props,he,We),Dt.forceUpdate());break;case"state":ll(Dt.state,he,We),Dt.forceUpdate()}}},renderer:U,setTraceUpdatesEnabled:function(X){oo=X},setTrackedPath:lo,startProfiling:Sl,stopProfiling:function(){u0=!1,To=!1},storeAsGlobal:function(X,Y,ye){if(Tr(X)){var he=Ti(S0,Y),We="$reactTemp".concat(ye);window[We]=he,console.log(We),console.log(he)}},updateComponentFilters:function(X){if(u0)throw Error("Cannot modify filter preferences while profiling");F.getFiberRoots(R).forEach(function(Y){Rr=Jn(ir(Y.current)),m0(Y.current),Yr(Y.current,!1),Rr=-1}),qs(X),kn.clear(),F.getFiberRoots(R).forEach(function(Y){T0(Rr=Jn(ir(Y.current)),Y.current),$r(Y.current,null,!1,!1),X0(Y),Rr=-1})}}}var _n;function Nu(F){return(Nu=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(R){return typeof R}:function(R){return R&&typeof Symbol=="function"&&R.constructor===Symbol&&R!==Symbol.prototype?"symbol":typeof R})(F)}function Wo(F,R,U){if(_n===void 0)try{throw Error()}catch(fe){var H=fe.stack.trim().match(/\n( *(at )?)/);_n=H&&H[1]||""}return` +`+_n+F}var su=!1;function Ps(F,R,U){if(!F||su)return"";var H,fe=Error.prepareStackTrace;Error.prepareStackTrace=void 0,su=!0;var ue=U.current;U.current=null;try{if(R){var de=function(){throw Error()};if(Object.defineProperty(de.prototype,"props",{set:function(){throw Error()}}),(typeof Reflect=="undefined"?"undefined":Nu(Reflect))==="object"&&Reflect.construct){try{Reflect.construct(de,[])}catch(xe){H=xe}Reflect.construct(F,[],de)}else{try{de.call()}catch(xe){H=xe}F.call(de.prototype)}}else{try{throw Error()}catch(xe){H=xe}F()}}catch(xe){if(xe&&H&&typeof xe.stack=="string"){for(var W=xe.stack.split(` +`),ve=H.stack.split(` +`),Fe=W.length-1,Ge=ve.length-1;Fe>=1&&Ge>=0&&W[Fe]!==ve[Ge];)Ge--;for(;Fe>=1&&Ge>=0;Fe--,Ge--)if(W[Fe]!==ve[Ge]){if(Fe!==1||Ge!==1)do if(Fe--,--Ge<0||W[Fe]!==ve[Ge])return` +`+W[Fe].replace(" at new "," at ");while(Fe>=1&&Ge>=0);break}}}finally{su=!1,Error.prepareStackTrace=fe,U.current=ue}var K=F?F.displayName||F.name:"";return K?Wo(K):""}function pl(F,R,U,H){return Ps(F,!1,H)}function Vf(F,R,U){var H=F.HostComponent,fe=F.LazyComponent,ue=F.SuspenseComponent,de=F.SuspenseListComponent,W=F.FunctionComponent,ve=F.IndeterminateComponent,Fe=F.SimpleMemoComponent,Ge=F.ForwardRef,K=F.Block,xe=F.ClassComponent;switch(R.tag){case H:return Wo(R.type);case fe:return Wo("Lazy");case ue:return Wo("Suspense");case de:return Wo("SuspenseList");case W:case ve:case Fe:return pl(R.type,0,0,U);case Ge:return pl(R.type.render,0,0,U);case K:return pl(R.type._render,0,0,U);case xe:return function(je,Xe,rt,st){return Ps(je,!0,st)}(R.type,0,0,U);default:return""}}function hl(F,R,U){try{var H="",fe=R;do H+=Vf(F,fe,U),fe=fe.return;while(fe);return H}catch(ue){return` +Error generating stack: `+ue.message+` +`+ue.stack}}function Bu(F,R){var U;if(typeof Symbol=="undefined"||F[Symbol.iterator]==null){if(Array.isArray(F)||(U=function(ve,Fe){if(!!ve){if(typeof ve=="string")return ju(ve,Fe);var Ge=Object.prototype.toString.call(ve).slice(8,-1);if(Ge==="Object"&&ve.constructor&&(Ge=ve.constructor.name),Ge==="Map"||Ge==="Set")return Array.from(ve);if(Ge==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(Ge))return ju(ve,Fe)}}(F))||R&&F&&typeof F.length=="number"){U&&(F=U);var H=0,fe=function(){};return{s:fe,n:function(){return H>=F.length?{done:!0}:{done:!1,value:F[H++]}},e:function(ve){throw ve},f:fe}}throw new TypeError(`Invalid attempt to iterate non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var ue,de=!0,W=!1;return{s:function(){U=F[Symbol.iterator]()},n:function(){var ve=U.next();return de=ve.done,ve},e:function(ve){W=!0,ue=ve},f:function(){try{de||U.return==null||U.return()}finally{if(W)throw ue}}}}function ju(F,R){(R==null||R>F.length)&&(R=F.length);for(var U=0,H=new Array(R);U0?Fe[Fe.length-1]:null,xe=K!==null&&(ro.test(K)||Ms.test(K));if(!xe){var je,Xe=Bu(ml.values());try{for(Xe.s();!(je=Xe.n()).done;){var rt=je.value,st=rt.currentDispatcherRef,xt=rt.getCurrentFiber,wt=rt.workTagMap,lt=xt();if(lt!=null){var Rt=hl(wt,lt,st);Rt!==""&&Fe.push(Rt);break}}}catch(yn){Xe.e(yn)}finally{Xe.f()}}}catch(yn){}ue.apply(void 0,Fe)};de.__REACT_DEVTOOLS_ORIGINAL_METHOD__=ue,Uu[fe]=de}catch(W){}})}}function O0(F){return(O0=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(R){return typeof R}:function(R){return R&&typeof Symbol=="function"&&R.constructor===Symbol&&R!==Symbol.prototype?"symbol":typeof R})(F)}function vl(F,R){for(var U=0;UF.length)&&(R=F.length);for(var U=0,H=new Array(R);U1?W-1:0),Fe=1;Fe0?K[K.length-1]:0),K.push(St),W.set(Ne,Fe(ft._topLevelWrapper));try{var Qt=He.apply(this,Qe);return K.pop(),Qt}catch(bn){throw K=[],bn}finally{if(K.length===0){var Cn=W.get(Ne);if(Cn===void 0)throw new Error("Expected to find root ID.");yn(Cn)}}},performUpdateIfNecessary:function(He,Qe){var Ne=Qe[0];if(P0(Ne)===9)return He.apply(this,Qe);var ft=Fe(Ne);K.push(ft);var St=ln(Ne);try{var Qt=He.apply(this,Qe),Cn=ln(Ne);return Ge(St,Cn)||Xe(Ne,ft,Cn),K.pop(),Qt}catch(p0){throw K=[],p0}finally{if(K.length===0){var bn=W.get(Ne);if(bn===void 0)throw new Error("Expected to find root ID.");yn(bn)}}},receiveComponent:function(He,Qe){var Ne=Qe[0];if(P0(Ne)===9)return He.apply(this,Qe);var ft=Fe(Ne);K.push(ft);var St=ln(Ne);try{var Qt=He.apply(this,Qe),Cn=ln(Ne);return Ge(St,Cn)||Xe(Ne,ft,Cn),K.pop(),Qt}catch(p0){throw K=[],p0}finally{if(K.length===0){var bn=W.get(Ne);if(bn===void 0)throw new Error("Expected to find root ID.");yn(bn)}}},unmountComponent:function(He,Qe){var Ne=Qe[0];if(P0(Ne)===9)return He.apply(this,Qe);var ft=Fe(Ne);K.push(ft);try{var St=He.apply(this,Qe);return K.pop(),function(Cn,bn){wt.push(bn),ue.delete(bn)}(0,ft),St}catch(Cn){throw K=[],Cn}finally{if(K.length===0){var Qt=W.get(Ne);if(Qt===void 0)throw new Error("Expected to find root ID.");yn(Qt)}}}}));var st=[],xt=new Map,wt=[],lt=0,Rt=null;function yn(He){if(st.length!==0||wt.length!==0||Rt!==null){var Qe=wt.length+(Rt===null?0:1),Ne=new Array(3+lt+(Qe>0?2+Qe:0)+st.length),ft=0;if(Ne[ft++]=R,Ne[ft++]=He,Ne[ft++]=lt,xt.forEach(function(Cn,bn){Ne[ft++]=bn.length;for(var p0=Cs(bn),h0=0;h00){Ne[ft++]=2,Ne[ft++]=Qe;for(var St=0;St"),"color: var(--dom-tag-name-color); font-weight: normal;"),Qe.props!==null&&console.log("Props:",Qe.props),Qe.state!==null&&console.log("State:",Qe.state),Qe.context!==null&&console.log("Context:",Qe.context);var ft=fe(He);ft!==null&&console.log("Node:",ft),(window.chrome||/firefox/i.test(navigator.userAgent))&&console.log("Right-click any value to save it as a global variable for further inspection."),Ne&&console.groupEnd()}else console.warn('Could not find element with id "'.concat(He,'"'))},overrideSuspense:function(){throw new Error("overrideSuspense not supported by this renderer")},overrideValueAtPath:function(He,Qe,Ne,ft,St){var Qt=ue.get(Qe);if(Qt!=null){var Cn=Qt._instance;if(Cn!=null)switch(He){case"context":fl(Cn.context,ft,St),a0(Cn);break;case"hooks":throw new Error("Hooks not supported by this renderer");case"props":var bn=Qt._currentElement;Qt._currentElement=V0(V0({},bn),{},{props:si(bn.props,ft,St)}),a0(Cn);break;case"state":fl(Cn.state,ft,St),a0(Cn)}}},renamePath:function(He,Qe,Ne,ft,St){var Qt=ue.get(Qe);if(Qt!=null){var Cn=Qt._instance;if(Cn!=null)switch(He){case"context":ll(Cn.context,ft,St),a0(Cn);break;case"hooks":throw new Error("Hooks not supported by this renderer");case"props":var bn=Qt._currentElement;Qt._currentElement=V0(V0({},bn),{},{props:Fr(bn.props,ft,St)}),a0(Cn);break;case"state":ll(Cn.state,ft,St),a0(Cn)}}},prepareViewAttributeSource:function(He,Qe){var Ne=Cr(He);Ne!==null&&(window.$attribute=Ti(Ne,Qe))},prepareViewElementSource:function(He){var Qe=ue.get(He);if(Qe!=null){var Ne=Qe._currentElement;Ne!=null?H.$type=Ne.type:console.warn('Could not find element with id "'.concat(He,'"'))}else console.warn('Could not find instance with id "'.concat(He,'"'))},renderer:U,setTraceUpdatesEnabled:function(He){},setTrackedPath:function(He){},startProfiling:function(){},stopProfiling:function(){},storeAsGlobal:function(He,Qe,Ne){var ft=Cr(He);if(ft!==null){var St=Ti(ft,Qe),Qt="$reactTemp".concat(Ne);window[Qt]=St,console.log(Qt),console.log(St)}},updateComponentFilters:function(He){}}}function nr(F,R){var U=!1,H={bottom:0,left:0,right:0,top:0},fe=R[F];if(fe!=null){for(var ue=0,de=Object.keys(H);ue0?"development":"production";var st=Function.prototype.toString;if(rt.Mount&&rt.Mount._renderNewRootComponent){var xt=st.call(rt.Mount._renderNewRootComponent);return xt.indexOf("function")!==0?"production":xt.indexOf("storedMeasure")!==-1?"development":xt.indexOf("should be a pure function")!==-1?xt.indexOf("NODE_ENV")!==-1||xt.indexOf("development")!==-1||xt.indexOf("true")!==-1?"development":xt.indexOf("nextElement")!==-1||xt.indexOf("nextComponent")!==-1?"unminified":"development":xt.indexOf("nextElement")!==-1||xt.indexOf("nextComponent")!==-1?"unminified":"outdated"}}catch(wt){}return"production"}(ve);try{var K=window.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__!==!1,xe=window.__REACT_DEVTOOLS_BREAK_ON_CONSOLE_ERRORS__===!0;(K||xe)&&(zi(ve),Ho({appendComponentStack:K,breakOnConsoleErrors:xe}))}catch(rt){}var je=F.__REACT_DEVTOOLS_ATTACH__;if(typeof je=="function"){var Xe=je(W,Fe,ve,F);W.rendererInterfaces.set(Fe,Xe)}return W.emit("renderer",{id:Fe,renderer:ve,reactBuildType:Ge}),Fe},on:function(ve,Fe){ue[ve]||(ue[ve]=[]),ue[ve].push(Fe)},off:function(ve,Fe){if(ue[ve]){var Ge=ue[ve].indexOf(Fe);Ge!==-1&&ue[ve].splice(Ge,1),ue[ve].length||delete ue[ve]}},sub:function(ve,Fe){return W.on(ve,Fe),function(){return W.off(ve,Fe)}},supportsFiber:!0,checkDCE:function(ve){try{Function.prototype.toString.call(ve).indexOf("^_^")>-1&&(U=!0,setTimeout(function(){throw new Error("React is running in production mode, but dead code elimination has not been applied. Read how to correctly configure React for production: https://reactjs.org/link/perf-use-production-build")}))}catch(Fe){}},onCommitFiberUnmount:function(ve,Fe){var Ge=fe.get(ve);Ge!=null&&Ge.handleCommitFiberUnmount(Fe)},onCommitFiberRoot:function(ve,Fe,Ge){var K=W.getFiberRoots(ve),xe=Fe.current,je=K.has(Fe),Xe=xe.memoizedState==null||xe.memoizedState.element==null;je||Xe?je&&Xe&&K.delete(Fe):K.add(Fe);var rt=fe.get(ve);rt!=null&&rt.handleCommitFiberRoot(Fe,Ge)}};Object.defineProperty(F,"__REACT_DEVTOOLS_GLOBAL_HOOK__",{configurable:!1,enumerable:!1,get:function(){return W}})})(window);var M0=window.__REACT_DEVTOOLS_GLOBAL_HOOK__,au=[{type:1,value:7,isEnabled:!0}];function Lr(F){if(M0!=null){var R=F||{},U=R.host,H=U===void 0?"localhost":U,fe=R.nativeStyleEditorValidAttributes,ue=R.useHttps,de=ue!==void 0&&ue,W=R.port,ve=W===void 0?8097:W,Fe=R.websocket,Ge=R.resolveRNStyle,K=Ge===void 0?null:Ge,xe=R.isAppActive,je=de?"wss":"ws",Xe=null;if((xe===void 0?function(){return!0}:xe)()){var rt=null,st=[],xt=je+"://"+H+":"+ve,wt=Fe||new window.WebSocket(xt);wt.onclose=function(){rt!==null&&rt.emit("shutdown"),lt()},wt.onerror=function(){lt()},wt.onmessage=function(Rt){var yn;try{if(typeof Rt.data!="string")throw Error();yn=JSON.parse(Rt.data)}catch(sn){return void console.error("[React DevTools] Failed to parse JSON: "+Rt.data)}st.forEach(function(sn){try{sn(yn)}catch(ar){throw console.log("[React DevTools] Error calling listener",yn),console.log("error:",ar),ar}})},wt.onopen=function(){(rt=new Do({listen:function(rn){return st.push(rn),function(){var Hn=st.indexOf(rn);Hn>=0&&st.splice(Hn,1)}},send:function(rn,Hn,d0){wt.readyState===wt.OPEN?wt.send(JSON.stringify({event:rn,payload:Hn})):(rt!==null&&rt.shutdown(),lt())}})).addListener("inspectElement",function(rn){var Hn=rn.id,d0=rn.rendererID,Cr=Rt.rendererInterfaces[d0];if(Cr!=null){var He=Cr.findNativeNodesForFiberID(Hn);He!=null&&He[0]!=null&&Rt.emit("showNativeHighlight",He[0])}}),rt.addListener("updateComponentFilters",function(rn){au=rn}),window.__REACT_DEVTOOLS_COMPONENT_FILTERS__==null&&rt.send("overrideComponentFilters",au);var Rt=new I0(rt);if(Rt.addListener("shutdown",function(){M0.emit("shutdown")}),function(rn,Hn,d0){if(rn==null)return function(){};var Cr=[rn.sub("renderer-attached",function(Ne){var ft=Ne.id,St=(Ne.renderer,Ne.rendererInterface);Hn.setRendererInterface(ft,St),St.flushInitialOperations()}),rn.sub("unsupported-renderer-version",function(Ne){Hn.onUnsupportedRenderer(Ne)}),rn.sub("operations",Hn.onHookOperations),rn.sub("traceUpdates",Hn.onTraceUpdates)],He=function(Ne,ft){var St=rn.rendererInterfaces.get(Ne);St==null&&(typeof ft.findFiberByHostInstance=="function"?St=uf(rn,Ne,ft,d0):ft.ComponentTree&&(St=lf(rn,Ne,ft,d0)),St!=null&&rn.rendererInterfaces.set(Ne,St)),St!=null?rn.emit("renderer-attached",{id:Ne,renderer:ft,rendererInterface:St}):rn.emit("unsupported-renderer-version",Ne)};rn.renderers.forEach(function(Ne,ft){He(ft,Ne)}),Cr.push(rn.sub("renderer",function(Ne){var ft=Ne.id,St=Ne.renderer;He(ft,St)})),rn.emit("react-devtools",Hn),rn.reactDevtoolsAgent=Hn;var Qe=function(){Cr.forEach(function(Ne){return Ne()}),rn.rendererInterfaces.forEach(function(Ne){Ne.cleanup()}),rn.reactDevtoolsAgent=null};Hn.addListener("shutdown",Qe),Cr.push(function(){Hn.removeListener("shutdown",Qe)})}(M0,Rt,window),K!=null||M0.resolveRNStyle!=null)Gu(rt,Rt,K||M0.resolveRNStyle,fe||M0.nativeStyleEditorValidAttributes||null);else{var yn,sn,ar=function(){rt!==null&&Gu(rt,Rt,yn,sn)};M0.hasOwnProperty("resolveRNStyle")||Object.defineProperty(M0,"resolveRNStyle",{enumerable:!1,get:function(){return yn},set:function(rn){yn=rn,ar()}}),M0.hasOwnProperty("nativeStyleEditorValidAttributes")||Object.defineProperty(M0,"nativeStyleEditorValidAttributes",{enumerable:!1,get:function(){return sn},set:function(rn){sn=rn,ar()}})}}}else lt()}function lt(){Xe===null&&(Xe=setTimeout(function(){return Lr(F)},2e3))}}}])})});var rS=Me(nS=>{"use strict";Object.defineProperty(nS,"__esModule",{value:!0});eS();var _j=tS();_j.connectToDevTools()});var lS=Me(x2=>{"use strict";var iS=x2&&x2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(x2,"__esModule",{value:!0});var oS=Ay(),yj=iS(lE()),uS=iS(hc()),no=Xy();process.env.DEV==="true"&&rS();var sS=i=>{i==null||i.unsetMeasureFunc(),i==null||i.freeRecursive()};x2.default=yj.default({schedulePassiveEffects:oS.unstable_scheduleCallback,cancelPassiveEffects:oS.unstable_cancelCallback,now:Date.now,getRootHostContext:()=>({isInsideText:!1}),prepareForCommit:()=>{},resetAfterCommit:i=>{if(i.isStaticDirty){i.isStaticDirty=!1,typeof i.onImmediateRender=="function"&&i.onImmediateRender();return}typeof i.onRender=="function"&&i.onRender()},getChildHostContext:(i,u)=>{let f=i.isInsideText,c=u==="ink-text"||u==="ink-virtual-text";return f===c?i:{isInsideText:c}},shouldSetTextContent:()=>!1,createInstance:(i,u,f,c)=>{if(c.isInsideText&&i==="ink-box")throw new Error(" can\u2019t be nested inside component");let g=i==="ink-text"&&c.isInsideText?"ink-virtual-text":i,t=no.createNode(g);for(let[C,A]of Object.entries(u))C!=="children"&&(C==="style"?no.setStyle(t,A):C==="internal_transform"?t.internal_transform=A:C==="internal_static"?t.internal_static=!0:no.setAttribute(t,C,A));return t},createTextInstance:(i,u,f)=>{if(!f.isInsideText)throw new Error(`Text string "${i}" must be rendered inside component`);return no.createTextNode(i)},resetTextContent:()=>{},hideTextInstance:i=>{no.setTextNodeValue(i,"")},unhideTextInstance:(i,u)=>{no.setTextNodeValue(i,u)},getPublicInstance:i=>i,hideInstance:i=>{var u;(u=i.yogaNode)===null||u===void 0||u.setDisplay(uS.default.DISPLAY_NONE)},unhideInstance:i=>{var u;(u=i.yogaNode)===null||u===void 0||u.setDisplay(uS.default.DISPLAY_FLEX)},appendInitialChild:no.appendChildNode,appendChild:no.appendChildNode,insertBefore:no.insertBeforeNode,finalizeInitialChildren:(i,u,f,c)=>(i.internal_static&&(c.isStaticDirty=!0,c.staticNode=i),!1),supportsMutation:!0,appendChildToContainer:no.appendChildNode,insertInContainerBefore:no.insertBeforeNode,removeChildFromContainer:(i,u)=>{no.removeChildNode(i,u),sS(u.yogaNode)},prepareUpdate:(i,u,f,c,g)=>{i.internal_static&&(g.isStaticDirty=!0);let t={},C=Object.keys(c);for(let A of C)if(c[A]!==f[A]){if(A==="style"&&typeof c.style=="object"&&typeof f.style=="object"){let D=c.style,L=f.style,N=Object.keys(D);for(let j of N){if(j==="borderStyle"||j==="borderColor"){if(typeof t.style!="object"){let $={};t.style=$}t.style.borderStyle=D.borderStyle,t.style.borderColor=D.borderColor}if(D[j]!==L[j]){if(typeof t.style!="object"){let $={};t.style=$}t.style[j]=D[j]}}continue}t[A]=c[A]}return t},commitUpdate:(i,u)=>{for(let[f,c]of Object.entries(u))f!=="children"&&(f==="style"?no.setStyle(i,c):f==="internal_transform"?i.internal_transform=c:f==="internal_static"?i.internal_static=!0:no.setAttribute(i,f,c))},commitTextUpdate:(i,u,f)=>{no.setTextNodeValue(i,f)},removeChild:(i,u)=>{no.removeChildNode(i,u),sS(u.yogaNode)}})});var cS=Me((Jb,fS)=>{"use strict";fS.exports=(i,u=1,f)=>{if(f=dt({indent:" ",includeEmptyLines:!1},f),typeof i!="string")throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof i}\``);if(typeof u!="number")throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof u}\``);if(typeof f.indent!="string")throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof f.indent}\``);if(u===0)return i;let c=f.includeEmptyLines?/^/gm:/^(?!\s*$)/gm;return i.replace(c,f.indent.repeat(u))}});var aS=Me(k2=>{"use strict";var wj=k2&&k2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(k2,"__esModule",{value:!0});var Vh=wj(hc());k2.default=i=>i.getComputedWidth()-i.getComputedPadding(Vh.default.EDGE_LEFT)-i.getComputedPadding(Vh.default.EDGE_RIGHT)-i.getComputedBorder(Vh.default.EDGE_LEFT)-i.getComputedBorder(Vh.default.EDGE_RIGHT)});var pS=Me((Zb,dS)=>{dS.exports={single:{topLeft:"\u250C",topRight:"\u2510",bottomRight:"\u2518",bottomLeft:"\u2514",vertical:"\u2502",horizontal:"\u2500"},double:{topLeft:"\u2554",topRight:"\u2557",bottomRight:"\u255D",bottomLeft:"\u255A",vertical:"\u2551",horizontal:"\u2550"},round:{topLeft:"\u256D",topRight:"\u256E",bottomRight:"\u256F",bottomLeft:"\u2570",vertical:"\u2502",horizontal:"\u2500"},bold:{topLeft:"\u250F",topRight:"\u2513",bottomRight:"\u251B",bottomLeft:"\u2517",vertical:"\u2503",horizontal:"\u2501"},singleDouble:{topLeft:"\u2553",topRight:"\u2556",bottomRight:"\u255C",bottomLeft:"\u2559",vertical:"\u2551",horizontal:"\u2500"},doubleSingle:{topLeft:"\u2552",topRight:"\u2555",bottomRight:"\u255B",bottomLeft:"\u2558",vertical:"\u2502",horizontal:"\u2550"},classic:{topLeft:"+",topRight:"+",bottomRight:"+",bottomLeft:"+",vertical:"|",horizontal:"-"}}});var mS=Me((eG,m3)=>{"use strict";var hS=pS();m3.exports=hS;m3.exports.default=hS});var gS=Me((tG,vS)=>{"use strict";vS.exports=(i,u=process.argv)=>{let f=i.startsWith("-")?"":i.length===1?"-":"--",c=u.indexOf(f+i),g=u.indexOf("--");return c!==-1&&(g===-1||c{"use strict";var Dj=require("os"),yS=require("tty"),Pu=gS(),{env:oi}=process,qf;Pu("no-color")||Pu("no-colors")||Pu("color=false")||Pu("color=never")?qf=0:(Pu("color")||Pu("colors")||Pu("color=true")||Pu("color=always"))&&(qf=1);"FORCE_COLOR"in oi&&(oi.FORCE_COLOR==="true"?qf=1:oi.FORCE_COLOR==="false"?qf=0:qf=oi.FORCE_COLOR.length===0?1:Math.min(parseInt(oi.FORCE_COLOR,10),3));function v3(i){return i===0?!1:{level:i,hasBasic:!0,has256:i>=2,has16m:i>=3}}function g3(i,u){if(qf===0)return 0;if(Pu("color=16m")||Pu("color=full")||Pu("color=truecolor"))return 3;if(Pu("color=256"))return 2;if(i&&!u&&qf===void 0)return 0;let f=qf||0;if(oi.TERM==="dumb")return f;if(process.platform==="win32"){let c=Dj.release().split(".");return Number(c[0])>=10&&Number(c[2])>=10586?Number(c[2])>=14931?3:2:1}if("CI"in oi)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some(c=>c in oi)||oi.CI_NAME==="codeship"?1:f;if("TEAMCITY_VERSION"in oi)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(oi.TEAMCITY_VERSION)?1:0;if("GITHUB_ACTIONS"in oi)return 1;if(oi.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in oi){let c=parseInt((oi.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(oi.TERM_PROGRAM){case"iTerm.app":return c>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(oi.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(oi.TERM)||"COLORTERM"in oi?1:f}function Ej(i){let u=g3(i,i&&i.isTTY);return v3(u)}_S.exports={supportsColor:Ej,stdout:v3(g3(!0,yS.isatty(1))),stderr:v3(g3(!0,yS.isatty(2)))}});var ES=Me((rG,DS)=>{"use strict";var Sj=(i,u,f)=>{let c=i.indexOf(u);if(c===-1)return i;let g=u.length,t=0,C="";do C+=i.substr(t,c-t)+u+f,t=c+g,c=i.indexOf(u,t);while(c!==-1);return C+=i.substr(t),C},Cj=(i,u,f,c)=>{let g=0,t="";do{let C=i[c-1]==="\r";t+=i.substr(g,(C?c-1:c)-g)+u+(C?`\r +`:` +`)+f,g=c+1,c=i.indexOf(` +`,g)}while(c!==-1);return t+=i.substr(g),t};DS.exports={stringReplaceAll:Sj,stringEncaseCRLFWithFirstIndex:Cj}});var kS=Me((iG,SS)=>{"use strict";var Tj=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,CS=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,xj=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,kj=/\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi,Aj=new Map([["n",` +`],["r","\r"],["t"," "],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e",""],["a","\x07"]]);function TS(i){let u=i[0]==="u",f=i[1]==="{";return u&&!f&&i.length===5||i[0]==="x"&&i.length===3?String.fromCharCode(parseInt(i.slice(1),16)):u&&f?String.fromCodePoint(parseInt(i.slice(2,-1),16)):Aj.get(i)||i}function Oj(i,u){let f=[],c=u.trim().split(/\s*,\s*/g),g;for(let t of c){let C=Number(t);if(!Number.isNaN(C))f.push(C);else if(g=t.match(xj))f.push(g[2].replace(kj,(A,x,D)=>x?TS(x):D));else throw new Error(`Invalid Chalk template style argument: ${t} (in style '${i}')`)}return f}function Ij(i){CS.lastIndex=0;let u=[],f;for(;(f=CS.exec(i))!==null;){let c=f[1];if(f[2]){let g=Oj(c,f[2]);u.push([c].concat(g))}else u.push([c])}return u}function xS(i,u){let f={};for(let g of u)for(let t of g.styles)f[t[0]]=g.inverse?null:t.slice(1);let c=i;for(let[g,t]of Object.entries(f))if(!!Array.isArray(t)){if(!(g in c))throw new Error(`Unknown Chalk style: ${g}`);c=t.length>0?c[g](...t):c[g]}return c}SS.exports=(i,u)=>{let f=[],c=[],g=[];if(u.replace(Tj,(t,C,A,x,D,L)=>{if(C)g.push(TS(C));else if(x){let N=g.join("");g=[],c.push(f.length===0?N:xS(i,f)(N)),f.push({inverse:A,styles:Ij(x)})}else if(D){if(f.length===0)throw new Error("Found extraneous } in Chalk template literal");c.push(xS(i,f)(g.join(""))),g=[],f.pop()}else g.push(L)}),c.push(g.join("")),f.length>0){let t=`Chalk template literal is missing ${f.length} closing bracket${f.length===1?"":"s"} (\`}\`)`;throw new Error(t)}return c.join("")}});var Jh=Me((oG,AS)=>{"use strict";var A2=Rh(),{stdout:_3,stderr:y3}=wS(),{stringReplaceAll:Pj,stringEncaseCRLFWithFirstIndex:Mj}=ES(),{isArray:Yh}=Array,OS=["ansi","ansi","ansi256","ansi16m"],ka=Object.create(null),Fj=(i,u={})=>{if(u.level&&!(Number.isInteger(u.level)&&u.level>=0&&u.level<=3))throw new Error("The `level` option should be an integer from 0 to 3");let f=_3?_3.level:0;i.level=u.level===void 0?f:u.level},IS=class{constructor(u){return PS(u)}},PS=i=>{let u={};return Fj(u,i),u.template=(...f)=>MS(u.template,...f),Object.setPrototypeOf(u,$h.prototype),Object.setPrototypeOf(u.template,u),u.template.constructor=()=>{throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.")},u.template.Instance=IS,u.template};function $h(i){return PS(i)}for(let[i,u]of Object.entries(A2))ka[i]={get(){let f=Kh(this,w3(u.open,u.close,this._styler),this._isEmpty);return Object.defineProperty(this,i,{value:f}),f}};ka.visible={get(){let i=Kh(this,this._styler,!0);return Object.defineProperty(this,"visible",{value:i}),i}};var LS=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(let i of LS)ka[i]={get(){let{level:u}=this;return function(...f){let c=w3(A2.color[OS[u]][i](...f),A2.color.close,this._styler);return Kh(this,c,this._isEmpty)}}};for(let i of LS){let u="bg"+i[0].toUpperCase()+i.slice(1);ka[u]={get(){let{level:f}=this;return function(...c){let g=w3(A2.bgColor[OS[f]][i](...c),A2.bgColor.close,this._styler);return Kh(this,g,this._isEmpty)}}}}var Lj=Object.defineProperties(()=>{},zn(dt({},ka),{level:{enumerable:!0,get(){return this._generator.level},set(i){this._generator.level=i}}})),w3=(i,u,f)=>{let c,g;return f===void 0?(c=i,g=u):(c=f.openAll+i,g=u+f.closeAll),{open:i,close:u,openAll:c,closeAll:g,parent:f}},Kh=(i,u,f)=>{let c=(...g)=>Yh(g[0])&&Yh(g[0].raw)?RS(c,MS(c,...g)):RS(c,g.length===1?""+g[0]:g.join(" "));return Object.setPrototypeOf(c,Lj),c._generator=i,c._styler=u,c._isEmpty=f,c},RS=(i,u)=>{if(i.level<=0||!u)return i._isEmpty?"":u;let f=i._styler;if(f===void 0)return u;let{openAll:c,closeAll:g}=f;if(u.indexOf("")!==-1)for(;f!==void 0;)u=Pj(u,f.close,f.open),f=f.parent;let t=u.indexOf(` +`);return t!==-1&&(u=Mj(u,g,c,t)),c+u+g},D3,MS=(i,...u)=>{let[f]=u;if(!Yh(f)||!Yh(f.raw))return u.join(" ");let c=u.slice(1),g=[f.raw[0]];for(let t=1;t{"use strict";var Rj=O2&&O2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(O2,"__esModule",{value:!0});var I2=Rj(Jh()),Nj=/^(rgb|hsl|hsv|hwb)\(\s?(\d+),\s?(\d+),\s?(\d+)\s?\)$/,Bj=/^(ansi|ansi256)\(\s?(\d+)\s?\)$/,Qh=(i,u)=>u==="foreground"?i:"bg"+i[0].toUpperCase()+i.slice(1);O2.default=(i,u,f)=>{if(!u)return i;if(u in I2.default){let g=Qh(u,f);return I2.default[g](i)}if(u.startsWith("#")){let g=Qh("hex",f);return I2.default[g](u)(i)}if(u.startsWith("ansi")){let g=Bj.exec(u);if(!g)return i;let t=Qh(g[1],f),C=Number(g[2]);return I2.default[t](C)(i)}if(u.startsWith("rgb")||u.startsWith("hsl")||u.startsWith("hsv")||u.startsWith("hwb")){let g=Nj.exec(u);if(!g)return i;let t=Qh(g[1],f),C=Number(g[2]),A=Number(g[3]),x=Number(g[4]);return I2.default[t](C,A,x)(i)}return i}});var BS=Me(P2=>{"use strict";var NS=P2&&P2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(P2,"__esModule",{value:!0});var jj=NS(mS()),S3=NS(E3());P2.default=(i,u,f,c)=>{if(typeof f.style.borderStyle=="string"){let g=f.yogaNode.getComputedWidth(),t=f.yogaNode.getComputedHeight(),C=f.style.borderColor,A=jj.default[f.style.borderStyle],x=S3.default(A.topLeft+A.horizontal.repeat(g-2)+A.topRight,C,"foreground"),D=(S3.default(A.vertical,C,"foreground")+` +`).repeat(t-2),L=S3.default(A.bottomLeft+A.horizontal.repeat(g-2)+A.bottomRight,C,"foreground");c.write(i,u,x,{transformers:[]}),c.write(i,u+1,D,{transformers:[]}),c.write(i+g-1,u+1,D,{transformers:[]}),c.write(i,u+t-1,L,{transformers:[]})}}});var US=Me(M2=>{"use strict";var _c=M2&&M2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(M2,"__esModule",{value:!0});var Uj=_c(hc()),qj=_c(jy()),zj=_c(cS()),Wj=_c(Yy()),Hj=_c(aS()),bj=_c(Ky()),Gj=_c(BS()),Vj=(i,u)=>{var f;let c=(f=i.childNodes[0])===null||f===void 0?void 0:f.yogaNode;if(c){let g=c.getComputedLeft(),t=c.getComputedTop();u=` +`.repeat(t)+zj.default(u,g)}return u},jS=(i,u,f)=>{var c;let{offsetX:g=0,offsetY:t=0,transformers:C=[],skipStaticElements:A}=f;if(A&&i.internal_static)return;let{yogaNode:x}=i;if(x){if(x.getDisplay()===Uj.default.DISPLAY_NONE)return;let D=g+x.getComputedLeft(),L=t+x.getComputedTop(),N=C;if(typeof i.internal_transform=="function"&&(N=[i.internal_transform,...C]),i.nodeName==="ink-text"){let j=bj.default(i);if(j.length>0){let $=qj.default(j),h=Hj.default(x);if($>h){let re=(c=i.style.textWrap)!==null&&c!==void 0?c:"wrap";j=Wj.default(j,h,re)}j=Vj(i,j),u.write(D,L,j,{transformers:N})}return}if(i.nodeName==="ink-box"&&Gj.default(D,L,i,u),i.nodeName==="ink-root"||i.nodeName==="ink-box")for(let j of i.childNodes)jS(j,u,{offsetX:D,offsetY:L,transformers:N,skipStaticElements:A})}};M2.default=jS});var zS=Me((fG,qS)=>{"use strict";qS.exports=i=>{i=Object.assign({onlyFirst:!1},i);let u=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(u,i.onlyFirst?void 0:"g")}});var HS=Me((cG,C3)=>{"use strict";var Yj=zS(),WS=i=>typeof i=="string"?i.replace(Yj(),""):i;C3.exports=WS;C3.exports.default=WS});var VS=Me((aG,bS)=>{"use strict";var GS="[\uD800-\uDBFF][\uDC00-\uDFFF]";bS.exports=i=>i&&i.exact?new RegExp(`^${GS}$`):new RegExp(GS,"g")});var $S=Me((dG,T3)=>{"use strict";var $j=HS(),Kj=VS(),YS=i=>$j(i).replace(Kj()," ").length;T3.exports=YS;T3.exports.default=YS});var QS=Me(F2=>{"use strict";var KS=F2&&F2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(F2,"__esModule",{value:!0});var XS=KS(Gy()),Xj=KS($S()),JS=class{constructor(u){this.writes=[];let{width:f,height:c}=u;this.width=f,this.height=c}write(u,f,c,g){let{transformers:t}=g;!c||this.writes.push({x:u,y:f,text:c,transformers:t})}get(){let u=[];for(let c=0;cc.trimRight()).join(` +`),height:u.length}}};F2.default=JS});var t5=Me(L2=>{"use strict";var x3=L2&&L2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(L2,"__esModule",{value:!0});var Jj=x3(hc()),ZS=x3(US()),e5=x3(QS());L2.default=(i,u)=>{var f;if(i.yogaNode.setWidth(u),i.yogaNode){i.yogaNode.calculateLayout(void 0,void 0,Jj.default.DIRECTION_LTR);let c=new e5.default({width:i.yogaNode.getComputedWidth(),height:i.yogaNode.getComputedHeight()});ZS.default(i,c,{skipStaticElements:!0});let g;((f=i.staticNode)===null||f===void 0?void 0:f.yogaNode)&&(g=new e5.default({width:i.staticNode.yogaNode.getComputedWidth(),height:i.staticNode.yogaNode.getComputedHeight()}),ZS.default(i.staticNode,g,{skipStaticElements:!1}));let{output:t,height:C}=c.get();return{output:t,outputHeight:C,staticOutput:g?`${g.get().output} +`:""}}return{output:"",outputHeight:0,staticOutput:""}}});var o5=Me((mG,n5)=>{"use strict";var r5=require("stream"),i5=["assert","count","countReset","debug","dir","dirxml","error","group","groupCollapsed","groupEnd","info","log","table","time","timeEnd","timeLog","trace","warn"],k3={},Qj=i=>{let u=new r5.PassThrough,f=new r5.PassThrough;u.write=g=>i("stdout",g),f.write=g=>i("stderr",g);let c=new console.Console(u,f);for(let g of i5)k3[g]=console[g],console[g]=c[g];return()=>{for(let g of i5)console[g]=k3[g];k3={}}};n5.exports=Qj});var O3=Me(A3=>{"use strict";Object.defineProperty(A3,"__esModule",{value:!0});A3.default=new WeakMap});var P3=Me(I3=>{"use strict";Object.defineProperty(I3,"__esModule",{value:!0});var Zj=lr(),u5=Zj.createContext({exit:()=>{}});u5.displayName="InternalAppContext";I3.default=u5});var F3=Me(M3=>{"use strict";Object.defineProperty(M3,"__esModule",{value:!0});var eU=lr(),s5=eU.createContext({stdin:void 0,setRawMode:()=>{},isRawModeSupported:!1,internal_exitOnCtrlC:!0});s5.displayName="InternalStdinContext";M3.default=s5});var R3=Me(L3=>{"use strict";Object.defineProperty(L3,"__esModule",{value:!0});var tU=lr(),l5=tU.createContext({stdout:void 0,write:()=>{}});l5.displayName="InternalStdoutContext";L3.default=l5});var B3=Me(N3=>{"use strict";Object.defineProperty(N3,"__esModule",{value:!0});var nU=lr(),f5=nU.createContext({stderr:void 0,write:()=>{}});f5.displayName="InternalStderrContext";N3.default=f5});var Zh=Me(j3=>{"use strict";Object.defineProperty(j3,"__esModule",{value:!0});var rU=lr(),c5=rU.createContext({activeId:void 0,add:()=>{},remove:()=>{},activate:()=>{},deactivate:()=>{},enableFocus:()=>{},disableFocus:()=>{},focusNext:()=>{},focusPrevious:()=>{}});c5.displayName="InternalFocusContext";j3.default=c5});var d5=Me((EG,a5)=>{"use strict";var iU=/[|\\{}()[\]^$+*?.-]/g;a5.exports=i=>{if(typeof i!="string")throw new TypeError("Expected a string");return i.replace(iU,"\\$&")}});var v5=Me((SG,p5)=>{"use strict";var oU=d5(),h5=[].concat(require("module").builtinModules,"bootstrap_node","node").map(i=>new RegExp(`(?:\\(${i}\\.js:\\d+:\\d+\\)$|^\\s*at ${i}\\.js:\\d+:\\d+$)`));h5.push(/\(internal\/[^:]+:\d+:\d+\)$/,/\s*at internal\/[^:]+:\d+:\d+$/,/\/\.node-spawn-wrap-\w+-\w+\/node:\d+:\d+\)?$/);var em=class{constructor(u){u=dt({ignoredPackages:[]},u),"internals"in u||(u.internals=em.nodeInternals()),"cwd"in u||(u.cwd=process.cwd()),this._cwd=u.cwd.replace(/\\/g,"/"),this._internals=[].concat(u.internals,uU(u.ignoredPackages)),this._wrapCallSite=u.wrapCallSite||!1}static nodeInternals(){return[...h5]}clean(u,f=0){f=" ".repeat(f),Array.isArray(u)||(u=u.split(` +`)),!/^\s*at /.test(u[0])&&/^\s*at /.test(u[1])&&(u=u.slice(1));let c=!1,g=null,t=[];return u.forEach(C=>{if(C=C.replace(/\\/g,"/"),this._internals.some(x=>x.test(C)))return;let A=/^\s*at /.test(C);c?C=C.trimEnd().replace(/^(\s+)at /,"$1"):(C=C.trim(),A&&(C=C.slice(3))),C=C.replace(`${this._cwd}/`,""),C&&(A?(g&&(t.push(g),g=null),t.push(C)):(c=!0,g=C))}),t.map(C=>`${f}${C} +`).join("")}captureString(u,f=this.captureString){typeof u=="function"&&(f=u,u=Infinity);let{stackTraceLimit:c}=Error;u&&(Error.stackTraceLimit=u);let g={};Error.captureStackTrace(g,f);let{stack:t}=g;return Error.stackTraceLimit=c,this.clean(t)}capture(u,f=this.capture){typeof u=="function"&&(f=u,u=Infinity);let{prepareStackTrace:c,stackTraceLimit:g}=Error;Error.prepareStackTrace=(A,x)=>this._wrapCallSite?x.map(this._wrapCallSite):x,u&&(Error.stackTraceLimit=u);let t={};Error.captureStackTrace(t,f);let{stack:C}=t;return Object.assign(Error,{prepareStackTrace:c,stackTraceLimit:g}),C}at(u=this.at){let[f]=this.capture(1,u);if(!f)return{};let c={line:f.getLineNumber(),column:f.getColumnNumber()};m5(c,f.getFileName(),this._cwd),f.isConstructor()&&(c.constructor=!0),f.isEval()&&(c.evalOrigin=f.getEvalOrigin()),f.isNative()&&(c.native=!0);let g;try{g=f.getTypeName()}catch(A){}g&&g!=="Object"&&g!=="[object Object]"&&(c.type=g);let t=f.getFunctionName();t&&(c.function=t);let C=f.getMethodName();return C&&t!==C&&(c.method=C),c}parseLine(u){let f=u&&u.match(sU);if(!f)return null;let c=f[1]==="new",g=f[2],t=f[3],C=f[4],A=Number(f[5]),x=Number(f[6]),D=f[7],L=f[8],N=f[9],j=f[10]==="native",$=f[11]===")",h,re={};if(L&&(re.line=Number(L)),N&&(re.column=Number(N)),$&&D){let ce=0;for(let Q=D.length-1;Q>0;Q--)if(D.charAt(Q)===")")ce++;else if(D.charAt(Q)==="("&&D.charAt(Q-1)===" "&&(ce--,ce===-1&&D.charAt(Q-1)===" ")){let oe=D.slice(0,Q-1);D=D.slice(Q+1),g+=` (${oe}`;break}}if(g){let ce=g.match(lU);ce&&(g=ce[1],h=ce[2])}return m5(re,D,this._cwd),c&&(re.constructor=!0),t&&(re.evalOrigin=t,re.evalLine=A,re.evalColumn=x,re.evalFile=C&&C.replace(/\\/g,"/")),j&&(re.native=!0),g&&(re.function=g),h&&g!==h&&(re.method=h),re}};function m5(i,u,f){u&&(u=u.replace(/\\/g,"/"),u.startsWith(`${f}/`)&&(u=u.slice(f.length+1)),i.file=u)}function uU(i){if(i.length===0)return[];let u=i.map(f=>oU(f));return new RegExp(`[/\\\\]node_modules[/\\\\](?:${u.join("|")})[/\\\\][^:]+:\\d+:\\d+`)}var sU=new RegExp("^(?:\\s*at )?(?:(new) )?(?:(.*?) \\()?(?:eval at ([^ ]+) \\((.+?):(\\d+):(\\d+)\\), )?(?:(.+?):(\\d+):(\\d+)|(native))(\\)?)$"),lU=/^(.*?) \[as (.*?)\]$/;p5.exports=em});var _5=Me((CG,g5)=>{"use strict";g5.exports=(i,u)=>i.replace(/^\t+/gm,f=>" ".repeat(f.length*(u||2)))});var w5=Me((TG,y5)=>{"use strict";var fU=_5(),cU=(i,u)=>{let f=[],c=i-u,g=i+u;for(let t=c;t<=g;t++)f.push(t);return f};y5.exports=(i,u,f)=>{if(typeof i!="string")throw new TypeError("Source code is missing.");if(!u||u<1)throw new TypeError("Line number must start from `1`.");if(i=fU(i).split(/\r?\n/),!(u>i.length))return f=dt({around:3},f),cU(u,f.around).filter(c=>i[c-1]!==void 0).map(c=>({line:c,value:i[c-1]}))}});var tm=Me(hs=>{"use strict";var aU=hs&&hs.__createBinding||(Object.create?function(i,u,f,c){c===void 0&&(c=f),Object.defineProperty(i,c,{enumerable:!0,get:function(){return u[f]}})}:function(i,u,f,c){c===void 0&&(c=f),i[c]=u[f]}),dU=hs&&hs.__setModuleDefault||(Object.create?function(i,u){Object.defineProperty(i,"default",{enumerable:!0,value:u})}:function(i,u){i.default=u}),pU=hs&&hs.__importStar||function(i){if(i&&i.__esModule)return i;var u={};if(i!=null)for(var f in i)f!=="default"&&Object.hasOwnProperty.call(i,f)&&aU(u,i,f);return dU(u,i),u},hU=hs&&hs.__rest||function(i,u){var f={};for(var c in i)Object.prototype.hasOwnProperty.call(i,c)&&u.indexOf(c)<0&&(f[c]=i[c]);if(i!=null&&typeof Object.getOwnPropertySymbols=="function")for(var g=0,c=Object.getOwnPropertySymbols(i);g{var{children:f}=i,c=hU(i,["children"]);let g=Object.assign(Object.assign({},c),{marginLeft:c.marginLeft||c.marginX||c.margin||0,marginRight:c.marginRight||c.marginX||c.margin||0,marginTop:c.marginTop||c.marginY||c.margin||0,marginBottom:c.marginBottom||c.marginY||c.margin||0,paddingLeft:c.paddingLeft||c.paddingX||c.padding||0,paddingRight:c.paddingRight||c.paddingX||c.padding||0,paddingTop:c.paddingTop||c.paddingY||c.padding||0,paddingBottom:c.paddingBottom||c.paddingY||c.padding||0});return D5.default.createElement("ink-box",{ref:u,style:g},f)});U3.displayName="Box";U3.defaultProps={flexDirection:"row",flexGrow:0,flexShrink:1};hs.default=U3});var W3=Me(R2=>{"use strict";var q3=R2&&R2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(R2,"__esModule",{value:!0});var mU=q3(lr()),Aa=q3(Jh()),E5=q3(E3()),z3=({color:i,backgroundColor:u,dimColor:f,bold:c,italic:g,underline:t,strikethrough:C,inverse:A,wrap:x,children:D})=>{if(D==null)return null;let L=N=>(f&&(N=Aa.default.dim(N)),i&&(N=E5.default(N,i,"foreground")),u&&(N=E5.default(N,u,"background")),c&&(N=Aa.default.bold(N)),g&&(N=Aa.default.italic(N)),t&&(N=Aa.default.underline(N)),C&&(N=Aa.default.strikethrough(N)),A&&(N=Aa.default.inverse(N)),N);return mU.default.createElement("ink-text",{style:{flexGrow:0,flexShrink:1,flexDirection:"row",textWrap:x},internal_transform:L},D)};z3.displayName="Text";z3.defaultProps={dimColor:!1,bold:!1,italic:!1,underline:!1,strikethrough:!1,wrap:"wrap"};R2.default=z3});var x5=Me(ms=>{"use strict";var vU=ms&&ms.__createBinding||(Object.create?function(i,u,f,c){c===void 0&&(c=f),Object.defineProperty(i,c,{enumerable:!0,get:function(){return u[f]}})}:function(i,u,f,c){c===void 0&&(c=f),i[c]=u[f]}),gU=ms&&ms.__setModuleDefault||(Object.create?function(i,u){Object.defineProperty(i,"default",{enumerable:!0,value:u})}:function(i,u){i.default=u}),_U=ms&&ms.__importStar||function(i){if(i&&i.__esModule)return i;var u={};if(i!=null)for(var f in i)f!=="default"&&Object.hasOwnProperty.call(i,f)&&vU(u,i,f);return gU(u,i),u},N2=ms&&ms.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(ms,"__esModule",{value:!0});var S5=_U(require("fs")),ui=N2(lr()),C5=N2(v5()),yU=N2(w5()),ef=N2(tm()),il=N2(W3()),T5=new C5.default({cwd:process.cwd(),internals:C5.default.nodeInternals()}),wU=({error:i})=>{let u=i.stack?i.stack.split(` +`).slice(1):void 0,f=u?T5.parseLine(u[0]):void 0,c,g=0;if((f==null?void 0:f.file)&&(f==null?void 0:f.line)&&S5.existsSync(f.file)){let t=S5.readFileSync(f.file,"utf8");if(c=yU.default(t,f.line),c)for(let{line:C}of c)g=Math.max(g,String(C).length)}return ui.default.createElement(ef.default,{flexDirection:"column",padding:1},ui.default.createElement(ef.default,null,ui.default.createElement(il.default,{backgroundColor:"red",color:"white"}," ","ERROR"," "),ui.default.createElement(il.default,null," ",i.message)),f&&ui.default.createElement(ef.default,{marginTop:1},ui.default.createElement(il.default,{dimColor:!0},f.file,":",f.line,":",f.column)),f&&c&&ui.default.createElement(ef.default,{marginTop:1,flexDirection:"column"},c.map(({line:t,value:C})=>ui.default.createElement(ef.default,{key:t},ui.default.createElement(ef.default,{width:g+1},ui.default.createElement(il.default,{dimColor:t!==f.line,backgroundColor:t===f.line?"red":void 0,color:t===f.line?"white":void 0},String(t).padStart(g," "),":")),ui.default.createElement(il.default,{key:t,backgroundColor:t===f.line?"red":void 0,color:t===f.line?"white":void 0}," "+C)))),i.stack&&ui.default.createElement(ef.default,{marginTop:1,flexDirection:"column"},i.stack.split(` +`).slice(1).map(t=>{let C=T5.parseLine(t);return C?ui.default.createElement(ef.default,{key:t},ui.default.createElement(il.default,{dimColor:!0},"- "),ui.default.createElement(il.default,{dimColor:!0,bold:!0},C.function),ui.default.createElement(il.default,{dimColor:!0,color:"gray"}," ","(",C.file,":",C.line,":",C.column,")")):ui.default.createElement(ef.default,{key:t},ui.default.createElement(il.default,{dimColor:!0},"- "),ui.default.createElement(il.default,{dimColor:!0,bold:!0},t))})))};ms.default=wU});var A5=Me(vs=>{"use strict";var DU=vs&&vs.__createBinding||(Object.create?function(i,u,f,c){c===void 0&&(c=f),Object.defineProperty(i,c,{enumerable:!0,get:function(){return u[f]}})}:function(i,u,f,c){c===void 0&&(c=f),i[c]=u[f]}),EU=vs&&vs.__setModuleDefault||(Object.create?function(i,u){Object.defineProperty(i,"default",{enumerable:!0,value:u})}:function(i,u){i.default=u}),SU=vs&&vs.__importStar||function(i){if(i&&i.__esModule)return i;var u={};if(i!=null)for(var f in i)f!=="default"&&Object.hasOwnProperty.call(i,f)&&DU(u,i,f);return EU(u,i),u},yc=vs&&vs.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(vs,"__esModule",{value:!0});var wc=SU(lr()),k5=yc(gy()),CU=yc(P3()),TU=yc(F3()),xU=yc(R3()),kU=yc(B3()),AU=yc(Zh()),OU=yc(x5()),IU=" ",PU="",MU="",H3=class extends wc.PureComponent{constructor(){super(...arguments);this.state={isFocusEnabled:!0,activeFocusId:void 0,focusables:[],error:void 0},this.rawModeEnabledCount=0,this.handleSetRawMode=u=>{let{stdin:f}=this.props;if(!this.isRawModeSupported())throw f===process.stdin?new Error(`Raw mode is not supported on the current process.stdin, which Ink uses as input stream by default. +Read about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported`):new Error(`Raw mode is not supported on the stdin provided to Ink. +Read about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported`);if(f.setEncoding("utf8"),u){this.rawModeEnabledCount===0&&(f.addListener("data",this.handleInput),f.resume(),f.setRawMode(!0)),this.rawModeEnabledCount++;return}--this.rawModeEnabledCount==0&&(f.setRawMode(!1),f.removeListener("data",this.handleInput),f.pause())},this.handleInput=u=>{u===""&&this.props.exitOnCtrlC&&this.handleExit(),u===MU&&this.state.activeFocusId&&this.setState({activeFocusId:void 0}),this.state.isFocusEnabled&&this.state.focusables.length>0&&(u===IU&&this.focusNext(),u===PU&&this.focusPrevious())},this.handleExit=u=>{this.isRawModeSupported()&&this.handleSetRawMode(!1),this.props.onExit(u)},this.enableFocus=()=>{this.setState({isFocusEnabled:!0})},this.disableFocus=()=>{this.setState({isFocusEnabled:!1})},this.focusNext=()=>{this.setState(u=>{let f=u.focusables[0].id;return{activeFocusId:this.findNextFocusable(u)||f}})},this.focusPrevious=()=>{this.setState(u=>{let f=u.focusables[u.focusables.length-1].id;return{activeFocusId:this.findPreviousFocusable(u)||f}})},this.addFocusable=(u,{autoFocus:f})=>{this.setState(c=>{let g=c.activeFocusId;return!g&&f&&(g=u),{activeFocusId:g,focusables:[...c.focusables,{id:u,isActive:!0}]}})},this.removeFocusable=u=>{this.setState(f=>({activeFocusId:f.activeFocusId===u?void 0:f.activeFocusId,focusables:f.focusables.filter(c=>c.id!==u)}))},this.activateFocusable=u=>{this.setState(f=>({focusables:f.focusables.map(c=>c.id!==u?c:{id:u,isActive:!0})}))},this.deactivateFocusable=u=>{this.setState(f=>({activeFocusId:f.activeFocusId===u?void 0:f.activeFocusId,focusables:f.focusables.map(c=>c.id!==u?c:{id:u,isActive:!1})}))},this.findNextFocusable=u=>{let f=u.focusables.findIndex(c=>c.id===u.activeFocusId);for(let c=f+1;c{let f=u.focusables.findIndex(c=>c.id===u.activeFocusId);for(let c=f-1;c>=0;c--)if(u.focusables[c].isActive)return u.focusables[c].id}}static getDerivedStateFromError(u){return{error:u}}isRawModeSupported(){return this.props.stdin.isTTY}render(){return wc.default.createElement(CU.default.Provider,{value:{exit:this.handleExit}},wc.default.createElement(TU.default.Provider,{value:{stdin:this.props.stdin,setRawMode:this.handleSetRawMode,isRawModeSupported:this.isRawModeSupported(),internal_exitOnCtrlC:this.props.exitOnCtrlC}},wc.default.createElement(xU.default.Provider,{value:{stdout:this.props.stdout,write:this.props.writeToStdout}},wc.default.createElement(kU.default.Provider,{value:{stderr:this.props.stderr,write:this.props.writeToStderr}},wc.default.createElement(AU.default.Provider,{value:{activeId:this.state.activeFocusId,add:this.addFocusable,remove:this.removeFocusable,activate:this.activateFocusable,deactivate:this.deactivateFocusable,enableFocus:this.enableFocus,disableFocus:this.disableFocus,focusNext:this.focusNext,focusPrevious:this.focusPrevious}},this.state.error?wc.default.createElement(OU.default,{error:this.state.error}):this.props.children)))))}componentDidMount(){k5.default.hide(this.props.stdout)}componentWillUnmount(){k5.default.show(this.props.stdout),this.isRawModeSupported()&&this.handleSetRawMode(!1)}componentDidCatch(u){this.handleExit(u)}};vs.default=H3;H3.displayName="InternalApp"});var M5=Me(gs=>{"use strict";var FU=gs&&gs.__createBinding||(Object.create?function(i,u,f,c){c===void 0&&(c=f),Object.defineProperty(i,c,{enumerable:!0,get:function(){return u[f]}})}:function(i,u,f,c){c===void 0&&(c=f),i[c]=u[f]}),LU=gs&&gs.__setModuleDefault||(Object.create?function(i,u){Object.defineProperty(i,"default",{enumerable:!0,value:u})}:function(i,u){i.default=u}),RU=gs&&gs.__importStar||function(i){if(i&&i.__esModule)return i;var u={};if(i!=null)for(var f in i)f!=="default"&&Object.hasOwnProperty.call(i,f)&&FU(u,i,f);return LU(u,i),u},_s=gs&&gs.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(gs,"__esModule",{value:!0});var NU=_s(lr()),O5=AD(),BU=_s(WD()),jU=_s(ay()),UU=_s(KD()),qU=_s(JD()),nm=_s(lS()),zU=_s(t5()),WU=_s(vy()),HU=_s(o5()),bU=RU(Xy()),GU=_s(O3()),VU=_s(A5()),Oa=process.env.CI==="false"?!1:UU.default,I5=()=>{},P5=class{constructor(u){this.resolveExitPromise=()=>{},this.rejectExitPromise=()=>{},this.unsubscribeExit=()=>{},this.onRender=()=>{if(this.isUnmounted)return;let{output:f,outputHeight:c,staticOutput:g}=zU.default(this.rootNode,this.options.stdout.columns||80),t=g&&g!==` +`;if(this.options.debug){t&&(this.fullStaticOutput+=g),this.options.stdout.write(this.fullStaticOutput+f);return}if(Oa){t&&this.options.stdout.write(g),this.lastOutput=f;return}if(t&&(this.fullStaticOutput+=g),c>=this.options.stdout.rows){this.options.stdout.write(jU.default.clearTerminal+this.fullStaticOutput+f),this.lastOutput=f;return}t&&(this.log.clear(),this.options.stdout.write(g),this.log(f)),!t&&f!==this.lastOutput&&this.throttledLog(f),this.lastOutput=f},qU.default(this),this.options=u,this.rootNode=bU.createNode("ink-root"),this.rootNode.onRender=u.debug?this.onRender:O5.throttle(this.onRender,32,{leading:!0,trailing:!0}),this.rootNode.onImmediateRender=this.onRender,this.log=BU.default.create(u.stdout),this.throttledLog=u.debug?this.log:O5.throttle(this.log,void 0,{leading:!0,trailing:!0}),this.isUnmounted=!1,this.lastOutput="",this.fullStaticOutput="",this.container=nm.default.createContainer(this.rootNode,!1,!1),this.unsubscribeExit=WU.default(this.unmount,{alwaysLast:!1}),process.env.DEV==="true"&&nm.default.injectIntoDevTools({bundleType:0,version:"16.13.1",rendererPackageName:"ink"}),u.patchConsole&&this.patchConsole(),Oa||(u.stdout.on("resize",this.onRender),this.unsubscribeResize=()=>{u.stdout.off("resize",this.onRender)})}render(u){let f=NU.default.createElement(VU.default,{stdin:this.options.stdin,stdout:this.options.stdout,stderr:this.options.stderr,writeToStdout:this.writeToStdout,writeToStderr:this.writeToStderr,exitOnCtrlC:this.options.exitOnCtrlC,onExit:this.unmount},u);nm.default.updateContainer(f,this.container,null,I5)}writeToStdout(u){if(!this.isUnmounted){if(this.options.debug){this.options.stdout.write(u+this.fullStaticOutput+this.lastOutput);return}if(Oa){this.options.stdout.write(u);return}this.log.clear(),this.options.stdout.write(u),this.log(this.lastOutput)}}writeToStderr(u){if(!this.isUnmounted){if(this.options.debug){this.options.stderr.write(u),this.options.stdout.write(this.fullStaticOutput+this.lastOutput);return}if(Oa){this.options.stderr.write(u);return}this.log.clear(),this.options.stderr.write(u),this.log(this.lastOutput)}}unmount(u){this.isUnmounted||(this.onRender(),this.unsubscribeExit(),typeof this.restoreConsole=="function"&&this.restoreConsole(),typeof this.unsubscribeResize=="function"&&this.unsubscribeResize(),Oa?this.options.stdout.write(this.lastOutput+` +`):this.options.debug||this.log.done(),this.isUnmounted=!0,nm.default.updateContainer(null,this.container,null,I5),GU.default.delete(this.options.stdout),u instanceof Error?this.rejectExitPromise(u):this.resolveExitPromise())}waitUntilExit(){return this.exitPromise||(this.exitPromise=new Promise((u,f)=>{this.resolveExitPromise=u,this.rejectExitPromise=f})),this.exitPromise}clear(){!Oa&&!this.options.debug&&this.log.clear()}patchConsole(){this.options.debug||(this.restoreConsole=HU.default((u,f)=>{u==="stdout"&&this.writeToStdout(f),u==="stderr"&&(f.startsWith("The above error occurred")||this.writeToStderr(f))}))}};gs.default=P5});var L5=Me(B2=>{"use strict";var F5=B2&&B2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(B2,"__esModule",{value:!0});var YU=F5(M5()),rm=F5(O3()),$U=require("stream"),JU=(i,u)=>{let f=Object.assign({stdout:process.stdout,stdin:process.stdin,stderr:process.stderr,debug:!1,exitOnCtrlC:!0,patchConsole:!0},KU(u)),c=XU(f.stdout,()=>new YU.default(f));return c.render(i),{rerender:c.render,unmount:()=>c.unmount(),waitUntilExit:c.waitUntilExit,cleanup:()=>rm.default.delete(f.stdout),clear:c.clear}};B2.default=JU;var KU=(i={})=>i instanceof $U.Stream?{stdout:i,stdin:process.stdin}:i,XU=(i,u)=>{let f;return rm.default.has(i)?f=rm.default.get(i):(f=u(),rm.default.set(i,f)),f}});var N5=Me(tf=>{"use strict";var QU=tf&&tf.__createBinding||(Object.create?function(i,u,f,c){c===void 0&&(c=f),Object.defineProperty(i,c,{enumerable:!0,get:function(){return u[f]}})}:function(i,u,f,c){c===void 0&&(c=f),i[c]=u[f]}),ZU=tf&&tf.__setModuleDefault||(Object.create?function(i,u){Object.defineProperty(i,"default",{enumerable:!0,value:u})}:function(i,u){i.default=u}),eq=tf&&tf.__importStar||function(i){if(i&&i.__esModule)return i;var u={};if(i!=null)for(var f in i)f!=="default"&&Object.hasOwnProperty.call(i,f)&&QU(u,i,f);return ZU(u,i),u};Object.defineProperty(tf,"__esModule",{value:!0});var j2=eq(lr()),R5=i=>{let{items:u,children:f,style:c}=i,[g,t]=j2.useState(0),C=j2.useMemo(()=>u.slice(g),[u,g]);j2.useLayoutEffect(()=>{t(u.length)},[u.length]);let A=C.map((D,L)=>f(D,g+L)),x=j2.useMemo(()=>Object.assign({position:"absolute",flexDirection:"column"},c),[c]);return j2.default.createElement("ink-box",{internal_static:!0,style:x},A)};R5.displayName="Static";tf.default=R5});var j5=Me(U2=>{"use strict";var tq=U2&&U2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(U2,"__esModule",{value:!0});var nq=tq(lr()),B5=({children:i,transform:u})=>i==null?null:nq.default.createElement("ink-text",{style:{flexGrow:0,flexShrink:1,flexDirection:"row"},internal_transform:u},i);B5.displayName="Transform";U2.default=B5});var q5=Me(q2=>{"use strict";var rq=q2&&q2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(q2,"__esModule",{value:!0});var iq=rq(lr()),U5=({count:i=1})=>iq.default.createElement("ink-text",null,` +`.repeat(i));U5.displayName="Newline";q2.default=U5});var H5=Me(z2=>{"use strict";var z5=z2&&z2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(z2,"__esModule",{value:!0});var oq=z5(lr()),uq=z5(tm()),W5=()=>oq.default.createElement(uq.default,{flexGrow:1});W5.displayName="Spacer";z2.default=W5});var im=Me(W2=>{"use strict";var sq=W2&&W2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(W2,"__esModule",{value:!0});var lq=lr(),fq=sq(F3()),cq=()=>lq.useContext(fq.default);W2.default=cq});var G5=Me(H2=>{"use strict";var aq=H2&&H2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(H2,"__esModule",{value:!0});var b5=lr(),dq=aq(im()),pq=(i,u={})=>{let{stdin:f,setRawMode:c,internal_exitOnCtrlC:g}=dq.default();b5.useEffect(()=>{if(u.isActive!==!1)return c(!0),()=>{c(!1)}},[u.isActive,c]),b5.useEffect(()=>{if(u.isActive===!1)return;let t=C=>{let A=String(C),x={upArrow:A==="",downArrow:A==="",leftArrow:A==="",rightArrow:A==="",pageDown:A==="[6~",pageUp:A==="[5~",return:A==="\r",escape:A==="",ctrl:!1,shift:!1,tab:A===" "||A==="",backspace:A==="\b",delete:A==="\x7F"||A==="[3~",meta:!1};A<=""&&!x.return&&(A=String.fromCharCode(A.charCodeAt(0)+"a".charCodeAt(0)-1),x.ctrl=!0),A.startsWith("")&&(A=A.slice(1),x.meta=!0);let D=A>="A"&&A<="Z",L=A>="\u0410"&&A<="\u042F";A.length===1&&(D||L)&&(x.shift=!0),x.tab&&A==="[Z"&&(x.shift=!0),(x.tab||x.backspace||x.delete)&&(A=""),(!(A==="c"&&x.ctrl)||!g)&&i(A,x)};return f==null||f.on("data",t),()=>{f==null||f.off("data",t)}},[u.isActive,f,g,i])};H2.default=pq});var V5=Me(b2=>{"use strict";var hq=b2&&b2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(b2,"__esModule",{value:!0});var mq=lr(),vq=hq(P3()),gq=()=>mq.useContext(vq.default);b2.default=gq});var Y5=Me(G2=>{"use strict";var _q=G2&&G2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(G2,"__esModule",{value:!0});var yq=lr(),wq=_q(R3()),Dq=()=>yq.useContext(wq.default);G2.default=Dq});var $5=Me(V2=>{"use strict";var Eq=V2&&V2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(V2,"__esModule",{value:!0});var Sq=lr(),Cq=Eq(B3()),Tq=()=>Sq.useContext(Cq.default);V2.default=Tq});var X5=Me(Y2=>{"use strict";var K5=Y2&&Y2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Y2,"__esModule",{value:!0});var $2=lr(),xq=K5(Zh()),kq=K5(im()),Aq=({isActive:i=!0,autoFocus:u=!1}={})=>{let{isRawModeSupported:f,setRawMode:c}=kq.default(),{activeId:g,add:t,remove:C,activate:A,deactivate:x}=$2.useContext(xq.default),D=$2.useMemo(()=>Math.random().toString().slice(2,7),[]);return $2.useEffect(()=>(t(D,{autoFocus:u}),()=>{C(D)}),[D,u]),$2.useEffect(()=>{i?A(D):x(D)},[i,D]),$2.useEffect(()=>{if(!(!f||!i))return c(!0),()=>{c(!1)}},[i]),{isFocused:Boolean(D)&&g===D}};Y2.default=Aq});var J5=Me(K2=>{"use strict";var Oq=K2&&K2.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(K2,"__esModule",{value:!0});var Iq=lr(),Pq=Oq(Zh()),Mq=()=>{let i=Iq.useContext(Pq.default);return{enableFocus:i.enableFocus,disableFocus:i.disableFocus,focusNext:i.focusNext,focusPrevious:i.focusPrevious}};K2.default=Mq});var Q5=Me(b3=>{"use strict";Object.defineProperty(b3,"__esModule",{value:!0});b3.default=i=>{var u,f,c,g;return{width:(f=(u=i.yogaNode)===null||u===void 0?void 0:u.getComputedWidth())!==null&&f!==void 0?f:0,height:(g=(c=i.yogaNode)===null||c===void 0?void 0:c.getComputedHeight())!==null&&g!==void 0?g:0}}});var ys=Me(ji=>{"use strict";Object.defineProperty(ji,"__esModule",{value:!0});var Fq=L5();Object.defineProperty(ji,"render",{enumerable:!0,get:function(){return Fq.default}});var Lq=tm();Object.defineProperty(ji,"Box",{enumerable:!0,get:function(){return Lq.default}});var Rq=W3();Object.defineProperty(ji,"Text",{enumerable:!0,get:function(){return Rq.default}});var Nq=N5();Object.defineProperty(ji,"Static",{enumerable:!0,get:function(){return Nq.default}});var Bq=j5();Object.defineProperty(ji,"Transform",{enumerable:!0,get:function(){return Bq.default}});var jq=q5();Object.defineProperty(ji,"Newline",{enumerable:!0,get:function(){return jq.default}});var Uq=H5();Object.defineProperty(ji,"Spacer",{enumerable:!0,get:function(){return Uq.default}});var qq=G5();Object.defineProperty(ji,"useInput",{enumerable:!0,get:function(){return qq.default}});var zq=V5();Object.defineProperty(ji,"useApp",{enumerable:!0,get:function(){return zq.default}});var Wq=im();Object.defineProperty(ji,"useStdin",{enumerable:!0,get:function(){return Wq.default}});var Hq=Y5();Object.defineProperty(ji,"useStdout",{enumerable:!0,get:function(){return Hq.default}});var bq=$5();Object.defineProperty(ji,"useStderr",{enumerable:!0,get:function(){return bq.default}});var Gq=X5();Object.defineProperty(ji,"useFocus",{enumerable:!0,get:function(){return Gq.default}});var Vq=J5();Object.defineProperty(ji,"useFocusManager",{enumerable:!0,get:function(){return Vq.default}});var Yq=Q5();Object.defineProperty(ji,"measureElement",{enumerable:!0,get:function(){return Yq.default}})});var lC=Me(X2=>{"use strict";Object.defineProperty(X2,"__esModule",{value:!0});X2.UncontrolledTextInput=void 0;var oC=lr(),Y3=lr(),uC=ys(),Sc=Jh(),sC=({value:i,placeholder:u="",focus:f=!0,mask:c,highlightPastedText:g=!1,showCursor:t=!0,onChange:C,onSubmit:A})=>{let[{cursorOffset:x,cursorWidth:D},L]=Y3.useState({cursorOffset:(i||"").length,cursorWidth:0});Y3.useEffect(()=>{L(re=>{if(!f||!t)return re;let ce=i||"";return re.cursorOffset>ce.length-1?{cursorOffset:ce.length,cursorWidth:0}:re})},[i,f,t]);let N=g?D:0,j=c?c.repeat(i.length):i,$=j,h=u?Sc.grey(u):void 0;if(t&&f){h=u.length>0?Sc.inverse(u[0])+Sc.grey(u.slice(1)):Sc.inverse(" "),$=j.length>0?"":Sc.inverse(" ");let re=0;for(let ce of j)re>=x-N&&re<=x?$+=Sc.inverse(ce):$+=ce,re++;j.length>0&&x===j.length&&($+=Sc.inverse(" "))}return uC.useInput((re,ce)=>{if(ce.upArrow||ce.downArrow||ce.ctrl&&re==="c"||ce.tab||ce.shift&&ce.tab)return;if(ce.return){A&&A(i);return}let Q=x,oe=i,Se=0;ce.leftArrow?t&&Q--:ce.rightArrow?t&&Q++:ce.backspace||ce.delete?x>0&&(oe=i.slice(0,x-1)+i.slice(x,i.length),Q--):(oe=i.slice(0,x)+re+i.slice(x,i.length),Q+=re.length,re.length>1&&(Se=re.length)),x<0&&(Q=0),x>i.length&&(Q=i.length),L({cursorOffset:Q,cursorWidth:Se}),oe!==i&&C(oe)},{isActive:f}),oC.createElement(uC.Text,null,u?j.length>0?$:h:$)};X2.default=sC;X2.UncontrolledTextInput=i=>{let[u,f]=Y3.useState("");return oC.createElement(sC,Object.assign({},i,{value:u,onChange:f}))}});var cC=Me(pm=>{"use strict";Object.defineProperty(pm,"__esModule",{value:!0});function J2(i){let u=[...i.caches],f=u.shift();return f===void 0?fC():{get(c,g,t={miss:()=>Promise.resolve()}){return f.get(c,g,t).catch(()=>J2({caches:u}).get(c,g,t))},set(c,g){return f.set(c,g).catch(()=>J2({caches:u}).set(c,g))},delete(c){return f.delete(c).catch(()=>J2({caches:u}).delete(c))},clear(){return f.clear().catch(()=>J2({caches:u}).clear())}}}function fC(){return{get(i,u,f={miss:()=>Promise.resolve()}){return u().then(g=>Promise.all([g,f.miss(g)])).then(([g])=>g)},set(i,u){return Promise.resolve(u)},delete(i){return Promise.resolve()},clear(){return Promise.resolve()}}}pm.createFallbackableCache=J2;pm.createNullCache=fC});var dC=Me((fV,aC)=>{aC.exports=cC()});var pC=Me($3=>{"use strict";Object.defineProperty($3,"__esModule",{value:!0});function $q(i={serializable:!0}){let u={};return{get(f,c,g={miss:()=>Promise.resolve()}){let t=JSON.stringify(f);if(t in u)return Promise.resolve(i.serializable?JSON.parse(u[t]):u[t]);let C=c(),A=g&&g.miss||(()=>Promise.resolve());return C.then(x=>A(x)).then(()=>C)},set(f,c){return u[JSON.stringify(f)]=i.serializable?JSON.stringify(c):c,Promise.resolve(c)},delete(f){return delete u[JSON.stringify(f)],Promise.resolve()},clear(){return u={},Promise.resolve()}}}$3.createInMemoryCache=$q});var mC=Me((aV,hC)=>{hC.exports=pC()});var gC=Me(ws=>{"use strict";Object.defineProperty(ws,"__esModule",{value:!0});function Kq(i,u,f){let c={"x-algolia-api-key":f,"x-algolia-application-id":u};return{headers(){return i===K3.WithinHeaders?c:{}},queryParameters(){return i===K3.WithinQueryParameters?c:{}}}}function Xq(i){let u=0,f=()=>(u++,new Promise(c=>{setTimeout(()=>{c(i(f))},Math.min(100*u,1e3))}));return i(f)}function vC(i,u=(f,c)=>Promise.resolve()){return Object.assign(i,{wait(f){return vC(i.then(c=>Promise.all([u(c,f),c])).then(c=>c[1]))}})}function Jq(i){let u=i.length-1;for(u;u>0;u--){let f=Math.floor(Math.random()*(u+1)),c=i[u];i[u]=i[f],i[f]=c}return i}function Qq(i,u){return Object.keys(u!==void 0?u:{}).forEach(f=>{i[f]=u[f](i)}),i}function Zq(i,...u){let f=0;return i.replace(/%s/g,()=>encodeURIComponent(u[f++]))}var ez="4.2.0",tz=i=>()=>i.transporter.requester.destroy(),K3={WithinQueryParameters:0,WithinHeaders:1};ws.AuthMode=K3;ws.addMethods=Qq;ws.createAuth=Kq;ws.createRetryablePromise=Xq;ws.createWaitablePromise=vC;ws.destroy=tz;ws.encode=Zq;ws.shuffle=Jq;ws.version=ez});var Q2=Me((pV,_C)=>{_C.exports=gC()});var yC=Me(X3=>{"use strict";Object.defineProperty(X3,"__esModule",{value:!0});var nz={Delete:"DELETE",Get:"GET",Post:"POST",Put:"PUT"};X3.MethodEnum=nz});var Z2=Me((mV,wC)=>{wC.exports=yC()});var RC=Me(y0=>{"use strict";Object.defineProperty(y0,"__esModule",{value:!0});var DC=Z2();function J3(i,u){let f=i||{},c=f.data||{};return Object.keys(f).forEach(g=>{["timeout","headers","queryParameters","data","cacheable"].indexOf(g)===-1&&(c[g]=f[g])}),{data:Object.entries(c).length>0?c:void 0,timeout:f.timeout||u,headers:f.headers||{},queryParameters:f.queryParameters||{},cacheable:f.cacheable}}var hm={Read:1,Write:2,Any:3},Ia={Up:1,Down:2,Timeouted:3},EC=2*60*1e3;function Q3(i,u=Ia.Up){return zn(dt({},i),{status:u,lastUpdate:Date.now()})}function SC(i){return i.status===Ia.Up||Date.now()-i.lastUpdate>EC}function CC(i){return i.status===Ia.Timeouted&&Date.now()-i.lastUpdate<=EC}function Z3(i){return{protocol:i.protocol||"https",url:i.url,accept:i.accept||hm.Any}}function rz(i,u){return Promise.all(u.map(f=>i.get(f,()=>Promise.resolve(Q3(f))))).then(f=>{let c=f.filter(A=>SC(A)),g=f.filter(A=>CC(A)),t=[...c,...g],C=t.length>0?t.map(A=>Z3(A)):u;return{getTimeout(A,x){return(g.length===0&&A===0?1:g.length+3+A)*x},statelessHosts:C}})}var iz=({isTimedOut:i,status:u})=>!i&&~~u==0,oz=i=>{let u=i.status;return i.isTimedOut||iz(i)||~~(u/100)!=2&&~~(u/100)!=4},uz=({status:i})=>~~(i/100)==2,sz=(i,u)=>oz(i)?u.onRetry(i):uz(i)?u.onSucess(i):u.onFail(i);function PC(i,u,f,c){let g=[],t=AC(f,c),C=OC(i,c),A=f.method,x=f.method!==DC.MethodEnum.Get?{}:dt(dt({},f.data),c.data),D=dt(dt(dt({"x-algolia-agent":i.userAgent.value},i.queryParameters),x),c.queryParameters),L=0,N=(j,$)=>{let h=j.pop();if(h===void 0)throw IC(ew(g));let re={data:t,headers:C,method:A,url:kC(h,f.path,D),connectTimeout:$(L,i.timeouts.connect),responseTimeout:$(L,c.timeout)},ce=oe=>{let Se={request:re,response:oe,host:h,triesLeft:j.length};return g.push(Se),Se},Q={onSucess:oe=>TC(oe),onRetry(oe){let Se=ce(oe);return oe.isTimedOut&&L++,Promise.all([i.logger.info("Retryable failure",tw(Se)),i.hostsCache.set(h,Q3(h,oe.isTimedOut?Ia.Timeouted:Ia.Down))]).then(()=>N(j,$))},onFail(oe){throw ce(oe),xC(oe,ew(g))}};return i.requester.send(re).then(oe=>sz(oe,Q))};return rz(i.hostsCache,u).then(j=>N([...j.statelessHosts].reverse(),j.getTimeout))}function lz(i){let{hostsCache:u,logger:f,requester:c,requestsCache:g,responsesCache:t,timeouts:C,userAgent:A,hosts:x,queryParameters:D,headers:L}=i,N={hostsCache:u,logger:f,requester:c,requestsCache:g,responsesCache:t,timeouts:C,userAgent:A,headers:L,queryParameters:D,hosts:x.map(j=>Z3(j)),read(j,$){let h=J3($,N.timeouts.read),re=()=>PC(N,N.hosts.filter(oe=>(oe.accept&hm.Read)!=0),j,h);if((h.cacheable!==void 0?h.cacheable:j.cacheable)!==!0)return re();let Q={request:j,mappedRequestOptions:h,transporter:{queryParameters:N.queryParameters,headers:N.headers}};return N.responsesCache.get(Q,()=>N.requestsCache.get(Q,()=>N.requestsCache.set(Q,re()).then(oe=>Promise.all([N.requestsCache.delete(Q),oe]),oe=>Promise.all([N.requestsCache.delete(Q),Promise.reject(oe)])).then(([oe,Se])=>Se)),{miss:oe=>N.responsesCache.set(Q,oe)})},write(j,$){return PC(N,N.hosts.filter(h=>(h.accept&hm.Write)!=0),j,J3($,N.timeouts.write))}};return N}function fz(i){let u={value:`Algolia for JavaScript (${i})`,add(f){let c=`; ${f.segment}${f.version!==void 0?` (${f.version})`:""}`;return u.value.indexOf(c)===-1&&(u.value=`${u.value}${c}`),u}};return u}function TC(i){try{return JSON.parse(i.content)}catch(u){throw MC(u.message,i)}}function xC({content:i,status:u},f){let c=i;try{c=JSON.parse(i).message}catch(g){}return FC(c,u,f)}function cz(i,...u){let f=0;return i.replace(/%s/g,()=>encodeURIComponent(u[f++]))}function kC(i,u,f){let c=LC(f),g=`${i.protocol}://${i.url}/${u.charAt(0)==="/"?u.substr(1):u}`;return c.length&&(g+=`?${c}`),g}function LC(i){let u=f=>Object.prototype.toString.call(f)==="[object Object]"||Object.prototype.toString.call(f)==="[object Array]";return Object.keys(i).map(f=>cz("%s=%s",f,u(i[f])?JSON.stringify(i[f]):i[f])).join("&")}function AC(i,u){if(i.method===DC.MethodEnum.Get||i.data===void 0&&u.data===void 0)return;let f=Array.isArray(i.data)?i.data:dt(dt({},i.data),u.data);return JSON.stringify(f)}function OC(i,u){let f=dt(dt({},i.headers),u.headers),c={};return Object.keys(f).forEach(g=>{let t=f[g];c[g.toLowerCase()]=t}),c}function ew(i){return i.map(u=>tw(u))}function tw(i){let u=i.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return zn(dt({},i),{request:zn(dt({},i.request),{headers:dt(dt({},i.request.headers),u)})})}function FC(i,u,f){return{name:"ApiError",message:i,status:u,transporterStackTrace:f}}function MC(i,u){return{name:"DeserializationError",message:i,response:u}}function IC(i){return{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:i}}y0.CallEnum=hm;y0.HostStatusEnum=Ia;y0.createApiError=FC;y0.createDeserializationError=MC;y0.createMappedRequestOptions=J3;y0.createRetryError=IC;y0.createStatefulHost=Q3;y0.createStatelessHost=Z3;y0.createTransporter=lz;y0.createUserAgent=fz;y0.deserializeFailure=xC;y0.deserializeSuccess=TC;y0.isStatefulHostTimeouted=CC;y0.isStatefulHostUp=SC;y0.serializeData=AC;y0.serializeHeaders=OC;y0.serializeQueryParameters=LC;y0.serializeUrl=kC;y0.stackFrameWithoutCredentials=tw;y0.stackTraceWithoutCredentials=ew});var ed=Me((gV,NC)=>{NC.exports=RC()});var BC=Me(Hf=>{"use strict";Object.defineProperty(Hf,"__esModule",{value:!0});var Pa=Q2(),az=ed(),td=Z2(),dz=i=>{let u=i.region||"us",f=Pa.createAuth(Pa.AuthMode.WithinHeaders,i.appId,i.apiKey),c=az.createTransporter(zn(dt({hosts:[{url:`analytics.${u}.algolia.com`}]},i),{headers:dt(zn(dt({},f.headers()),{"content-type":"application/json"}),i.headers),queryParameters:dt(dt({},f.queryParameters()),i.queryParameters)})),g=i.appId;return Pa.addMethods({appId:g,transporter:c},i.methods)},pz=i=>(u,f)=>i.transporter.write({method:td.MethodEnum.Post,path:"2/abtests",data:u},f),hz=i=>(u,f)=>i.transporter.write({method:td.MethodEnum.Delete,path:Pa.encode("2/abtests/%s",u)},f),mz=i=>(u,f)=>i.transporter.read({method:td.MethodEnum.Get,path:Pa.encode("2/abtests/%s",u)},f),vz=i=>u=>i.transporter.read({method:td.MethodEnum.Get,path:"2/abtests"},u),gz=i=>(u,f)=>i.transporter.write({method:td.MethodEnum.Post,path:Pa.encode("2/abtests/%s/stop",u)},f);Hf.addABTest=pz;Hf.createAnalyticsClient=dz;Hf.deleteABTest=hz;Hf.getABTest=mz;Hf.getABTests=vz;Hf.stopABTest=gz});var UC=Me((yV,jC)=>{jC.exports=BC()});var zC=Me(nd=>{"use strict";Object.defineProperty(nd,"__esModule",{value:!0});var nw=Q2(),_z=ed(),qC=Z2(),yz=i=>{let u=i.region||"us",f=nw.createAuth(nw.AuthMode.WithinHeaders,i.appId,i.apiKey),c=_z.createTransporter(zn(dt({hosts:[{url:`recommendation.${u}.algolia.com`}]},i),{headers:dt(zn(dt({},f.headers()),{"content-type":"application/json"}),i.headers),queryParameters:dt(dt({},f.queryParameters()),i.queryParameters)}));return nw.addMethods({appId:i.appId,transporter:c},i.methods)},wz=i=>u=>i.transporter.read({method:qC.MethodEnum.Get,path:"1/strategies/personalization"},u),Dz=i=>(u,f)=>i.transporter.write({method:qC.MethodEnum.Post,path:"1/strategies/personalization",data:u},f);nd.createRecommendationClient=yz;nd.getPersonalizationStrategy=wz;nd.setPersonalizationStrategy=Dz});var HC=Me((DV,WC)=>{WC.exports=zC()});var nT=Me(yt=>{"use strict";Object.defineProperty(yt,"__esModule",{value:!0});var Wt=Q2(),jo=ed(),Rn=Z2(),Ez=require("crypto");function mm(i){let u=f=>i.request(f).then(c=>{if(i.batch!==void 0&&i.batch(c.hits),!i.shouldStop(c))return c.cursor?u({cursor:c.cursor}):u({page:(f.page||0)+1})});return u({})}var Sz=i=>{let u=i.appId,f=Wt.createAuth(i.authMode!==void 0?i.authMode:Wt.AuthMode.WithinHeaders,u,i.apiKey),c=jo.createTransporter(zn(dt({hosts:[{url:`${u}-dsn.algolia.net`,accept:jo.CallEnum.Read},{url:`${u}.algolia.net`,accept:jo.CallEnum.Write}].concat(Wt.shuffle([{url:`${u}-1.algolianet.com`},{url:`${u}-2.algolianet.com`},{url:`${u}-3.algolianet.com`}]))},i),{headers:dt(zn(dt({},f.headers()),{"content-type":"application/x-www-form-urlencoded"}),i.headers),queryParameters:dt(dt({},f.queryParameters()),i.queryParameters)})),g={transporter:c,appId:u,addAlgoliaAgent(t,C){c.userAgent.add({segment:t,version:C})},clearCache(){return Promise.all([c.requestsCache.clear(),c.responsesCache.clear()]).then(()=>{})}};return Wt.addMethods(g,i.methods)};function bC(){return{name:"MissingObjectIDError",message:"All objects must have an unique objectID (like a primary key) to be valid. Algolia is also able to generate objectIDs automatically but *it's not recommended*. To do it, use the `{'autoGenerateObjectIDIfNotExist': true}` option."}}function GC(){return{name:"ObjectNotFoundError",message:"Object not found."}}function VC(){return{name:"ValidUntilNotFoundError",message:"ValidUntil not found in given secured api key."}}var Cz=i=>(u,f)=>{let A=f||{},{queryParameters:c}=A,g=Si(A,["queryParameters"]),t=dt({acl:u},c!==void 0?{queryParameters:c}:{}),C=(x,D)=>Wt.createRetryablePromise(L=>rd(i)(x.key,D).catch(N=>{if(N.status!==404)throw N;return L()}));return Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Post,path:"1/keys",data:t},g),C)},Tz=i=>(u,f,c)=>{let g=jo.createMappedRequestOptions(c);return g.queryParameters["X-Algolia-User-ID"]=u,i.transporter.write({method:Rn.MethodEnum.Post,path:"1/clusters/mapping",data:{cluster:f}},g)},xz=i=>(u,f,c)=>i.transporter.write({method:Rn.MethodEnum.Post,path:"1/clusters/mapping/batch",data:{users:u,cluster:f}},c),vm=i=>(u,f,c)=>{let g=(t,C)=>id(i)(u,{methods:{waitTask:z0}}).waitTask(t.taskID,C);return Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Post,path:Wt.encode("1/indexes/%s/operation",u),data:{operation:"copy",destination:f}},c),g)},kz=i=>(u,f,c)=>vm(i)(u,f,zn(dt({},c),{scope:[gm.Rules]})),Az=i=>(u,f,c)=>vm(i)(u,f,zn(dt({},c),{scope:[gm.Settings]})),Oz=i=>(u,f,c)=>vm(i)(u,f,zn(dt({},c),{scope:[gm.Synonyms]})),Iz=i=>(u,f)=>{let c=(g,t)=>Wt.createRetryablePromise(C=>rd(i)(u,t).then(C).catch(A=>{if(A.status!==404)throw A}));return Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Delete,path:Wt.encode("1/keys/%s",u)},f),c)},Pz=()=>(i,u)=>{let f=jo.serializeQueryParameters(u),c=Ez.createHmac("sha256",i).update(f).digest("hex");return Buffer.from(c+f).toString("base64")},rd=i=>(u,f)=>i.transporter.read({method:Rn.MethodEnum.Get,path:Wt.encode("1/keys/%s",u)},f),Mz=i=>u=>i.transporter.read({method:Rn.MethodEnum.Get,path:"1/logs"},u),Fz=()=>i=>{let u=Buffer.from(i,"base64").toString("ascii"),f=/validUntil=(\d+)/,c=u.match(f);if(c===null)throw VC();return parseInt(c[1],10)-Math.round(new Date().getTime()/1e3)},Lz=i=>u=>i.transporter.read({method:Rn.MethodEnum.Get,path:"1/clusters/mapping/top"},u),Rz=i=>(u,f)=>i.transporter.read({method:Rn.MethodEnum.Get,path:Wt.encode("1/clusters/mapping/%s",u)},f),Nz=i=>u=>{let g=u||{},{retrieveMappings:f}=g,c=Si(g,["retrieveMappings"]);return f===!0&&(c.getClusters=!0),i.transporter.read({method:Rn.MethodEnum.Get,path:"1/clusters/mapping/pending"},c)},id=i=>(u,f={})=>{let c={transporter:i.transporter,appId:i.appId,indexName:u};return Wt.addMethods(c,f.methods)},Bz=i=>u=>i.transporter.read({method:Rn.MethodEnum.Get,path:"1/keys"},u),jz=i=>u=>i.transporter.read({method:Rn.MethodEnum.Get,path:"1/clusters"},u),Uz=i=>u=>i.transporter.read({method:Rn.MethodEnum.Get,path:"1/indexes"},u),qz=i=>u=>i.transporter.read({method:Rn.MethodEnum.Get,path:"1/clusters/mapping"},u),zz=i=>(u,f,c)=>{let g=(t,C)=>id(i)(u,{methods:{waitTask:z0}}).waitTask(t.taskID,C);return Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Post,path:Wt.encode("1/indexes/%s/operation",u),data:{operation:"move",destination:f}},c),g)},Wz=i=>(u,f)=>{let c=(g,t)=>Promise.all(Object.keys(g.taskID).map(C=>id(i)(C,{methods:{waitTask:z0}}).waitTask(g.taskID[C],t)));return Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Post,path:"1/indexes/*/batch",data:{requests:u}},f),c)},Hz=i=>(u,f)=>i.transporter.read({method:Rn.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:u}},f),bz=i=>(u,f)=>{let c=u.map(g=>zn(dt({},g),{params:jo.serializeQueryParameters(g.params||{})}));return i.transporter.read({method:Rn.MethodEnum.Post,path:"1/indexes/*/queries",data:{requests:c},cacheable:!0},f)},Gz=i=>(u,f)=>Promise.all(u.map(c=>{let A=c.params,{facetName:g,facetQuery:t}=A,C=Si(A,["facetName","facetQuery"]);return id(i)(c.indexName,{methods:{searchForFacetValues:YC}}).searchForFacetValues(g,t,dt(dt({},f),C))})),Vz=i=>(u,f)=>{let c=jo.createMappedRequestOptions(f);return c.queryParameters["X-Algolia-User-ID"]=u,i.transporter.write({method:Rn.MethodEnum.Delete,path:"1/clusters/mapping"},c)},Yz=i=>(u,f)=>{let c=(g,t)=>Wt.createRetryablePromise(C=>rd(i)(u,t).catch(A=>{if(A.status!==404)throw A;return C()}));return Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Post,path:Wt.encode("1/keys/%s/restore",u)},f),c)},$z=i=>(u,f)=>i.transporter.read({method:Rn.MethodEnum.Post,path:"1/clusters/mapping/search",data:{query:u}},f),Kz=i=>(u,f)=>{let c=Object.assign({},f),L=f||{},{queryParameters:g}=L,t=Si(L,["queryParameters"]),C=g?{queryParameters:g}:{},A=["acl","indexes","referers","restrictSources","queryParameters","description","maxQueriesPerIPPerHour","maxHitsPerQuery"],x=N=>Object.keys(c).filter(j=>A.indexOf(j)!==-1).every(j=>N[j]===c[j]),D=(N,j)=>Wt.createRetryablePromise($=>rd(i)(u,j).then(h=>x(h)?Promise.resolve():$()));return Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Put,path:Wt.encode("1/keys/%s",u),data:C},t),D)},$C=i=>(u,f)=>{let c=(g,t)=>z0(i)(g.taskID,t);return Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Post,path:Wt.encode("1/indexes/%s/batch",i.indexName),data:{requests:u}},f),c)},Xz=i=>u=>mm(zn(dt({},u),{shouldStop:f=>f.cursor===void 0,request:f=>i.transporter.read({method:Rn.MethodEnum.Post,path:Wt.encode("1/indexes/%s/browse",i.indexName),data:f},u)})),Jz=i=>u=>{let f=dt({hitsPerPage:1e3},u);return mm(zn(dt({},f),{shouldStop:c=>c.hits.lengthzn(dt({},g),{hits:g.hits.map(t=>(delete t._highlightResult,t))}))}}))},Qz=i=>u=>{let f=dt({hitsPerPage:1e3},u);return mm(zn(dt({},f),{shouldStop:c=>c.hits.lengthzn(dt({},g),{hits:g.hits.map(t=>(delete t._highlightResult,t))}))}}))},_m=i=>(u,f,c)=>{let x=c||{},{batchSize:g}=x,t=Si(x,["batchSize"]),C={taskIDs:[],objectIDs:[]},A=(D=0)=>{let L=[],N;for(N=D;N({action:f,body:j})),t).then(j=>(C.objectIDs=C.objectIDs.concat(j.objectIDs),C.taskIDs.push(j.taskID),N++,A(N)))};return Wt.createWaitablePromise(A(),(D,L)=>Promise.all(D.taskIDs.map(N=>z0(i)(N,L))))},Zz=i=>u=>Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Post,path:Wt.encode("1/indexes/%s/clear",i.indexName)},u),(f,c)=>z0(i)(f.taskID,c)),eW=i=>u=>{let t=u||{},{forwardToReplicas:f}=t,c=Si(t,["forwardToReplicas"]),g=jo.createMappedRequestOptions(c);return f&&(g.queryParameters.forwardToReplicas=1),Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Post,path:Wt.encode("1/indexes/%s/rules/clear",i.indexName)},g),(C,A)=>z0(i)(C.taskID,A))},tW=i=>u=>{let t=u||{},{forwardToReplicas:f}=t,c=Si(t,["forwardToReplicas"]),g=jo.createMappedRequestOptions(c);return f&&(g.queryParameters.forwardToReplicas=1),Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Post,path:Wt.encode("1/indexes/%s/synonyms/clear",i.indexName)},g),(C,A)=>z0(i)(C.taskID,A))},nW=i=>(u,f)=>Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Post,path:Wt.encode("1/indexes/%s/deleteByQuery",i.indexName),data:u},f),(c,g)=>z0(i)(c.taskID,g)),rW=i=>u=>Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Delete,path:Wt.encode("1/indexes/%s",i.indexName)},u),(f,c)=>z0(i)(f.taskID,c)),iW=i=>(u,f)=>Wt.createWaitablePromise(JC(i)([u],f).then(c=>({taskID:c.taskIDs[0]})),(c,g)=>z0(i)(c.taskID,g)),JC=i=>(u,f)=>{let c=u.map(g=>({objectID:g}));return _m(i)(c,Cc.DeleteObject,f)},oW=i=>(u,f)=>{let C=f||{},{forwardToReplicas:c}=C,g=Si(C,["forwardToReplicas"]),t=jo.createMappedRequestOptions(g);return c&&(t.queryParameters.forwardToReplicas=1),Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Delete,path:Wt.encode("1/indexes/%s/rules/%s",i.indexName,u)},t),(A,x)=>z0(i)(A.taskID,x))},uW=i=>(u,f)=>{let C=f||{},{forwardToReplicas:c}=C,g=Si(C,["forwardToReplicas"]),t=jo.createMappedRequestOptions(g);return c&&(t.queryParameters.forwardToReplicas=1),Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Delete,path:Wt.encode("1/indexes/%s/synonyms/%s",i.indexName,u)},t),(A,x)=>z0(i)(A.taskID,x))},sW=i=>u=>QC(i)(u).then(()=>!0).catch(f=>{if(f.status!==404)throw f;return!1}),lW=i=>(u,f)=>{let x=f||{},{query:c,paginate:g}=x,t=Si(x,["query","paginate"]),C=0,A=()=>ZC(i)(c||"",zn(dt({},t),{page:C})).then(D=>{for(let[L,N]of Object.entries(D.hits))if(u(N))return{object:N,position:parseInt(L,10),page:C};if(C++,g===!1||C>=D.nbPages)throw GC();return A()});return A()},fW=i=>(u,f)=>i.transporter.read({method:Rn.MethodEnum.Get,path:Wt.encode("1/indexes/%s/%s",i.indexName,u)},f),cW=()=>(i,u)=>{for(let[f,c]of Object.entries(i.hits))if(c.objectID===u)return parseInt(f,10);return-1},aW=i=>(u,f)=>{let C=f||{},{attributesToRetrieve:c}=C,g=Si(C,["attributesToRetrieve"]),t=u.map(A=>dt({indexName:i.indexName,objectID:A},c?{attributesToRetrieve:c}:{}));return i.transporter.read({method:Rn.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:t}},g)},dW=i=>(u,f)=>i.transporter.read({method:Rn.MethodEnum.Get,path:Wt.encode("1/indexes/%s/rules/%s",i.indexName,u)},f),QC=i=>u=>i.transporter.read({method:Rn.MethodEnum.Get,path:Wt.encode("1/indexes/%s/settings",i.indexName),data:{getVersion:2}},u),pW=i=>(u,f)=>i.transporter.read({method:Rn.MethodEnum.Get,path:Wt.encode("1/indexes/%s/synonyms/%s",i.indexName,u)},f),eT=i=>(u,f)=>i.transporter.read({method:Rn.MethodEnum.Get,path:Wt.encode("1/indexes/%s/task/%s",i.indexName,u.toString())},f),hW=i=>(u,f)=>Wt.createWaitablePromise(tT(i)([u],f).then(c=>({objectID:c.objectIDs[0],taskID:c.taskIDs[0]})),(c,g)=>z0(i)(c.taskID,g)),tT=i=>(u,f)=>{let C=f||{},{createIfNotExists:c}=C,g=Si(C,["createIfNotExists"]),t=c?Cc.PartialUpdateObject:Cc.PartialUpdateObjectNoCreate;return _m(i)(u,t,g)},mW=i=>(u,f)=>{let h=f||{},{safe:c,autoGenerateObjectIDIfNotExist:g,batchSize:t}=h,C=Si(h,["safe","autoGenerateObjectIDIfNotExist","batchSize"]),A=(re,ce,Q,oe)=>Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Post,path:Wt.encode("1/indexes/%s/operation",re),data:{operation:Q,destination:ce}},oe),(Se,me)=>z0(i)(Se.taskID,me)),x=Math.random().toString(36).substring(7),D=`${i.indexName}_tmp_${x}`,L=rw({appId:i.appId,transporter:i.transporter,indexName:D}),N=[],j=A(i.indexName,D,"copy",zn(dt({},C),{scope:["settings","synonyms","rules"]}));N.push(j);let $=(c?j.wait(C):j).then(()=>{let re=L(u,zn(dt({},C),{autoGenerateObjectIDIfNotExist:g,batchSize:t}));return N.push(re),c?re.wait(C):re}).then(()=>{let re=A(D,i.indexName,"move",C);return N.push(re),c?re.wait(C):re}).then(()=>Promise.all(N)).then(([re,ce,Q])=>({objectIDs:ce.objectIDs,taskIDs:[re.taskID,...ce.taskIDs,Q.taskID]}));return Wt.createWaitablePromise($,(re,ce)=>Promise.all(N.map(Q=>Q.wait(ce))))},vW=i=>(u,f)=>iw(i)(u,zn(dt({},f),{clearExistingRules:!0})),gW=i=>(u,f)=>ow(i)(u,zn(dt({},f),{replaceExistingSynonyms:!0})),_W=i=>(u,f)=>Wt.createWaitablePromise(rw(i)([u],f).then(c=>({objectID:c.objectIDs[0],taskID:c.taskIDs[0]})),(c,g)=>z0(i)(c.taskID,g)),rw=i=>(u,f)=>{let C=f||{},{autoGenerateObjectIDIfNotExist:c}=C,g=Si(C,["autoGenerateObjectIDIfNotExist"]),t=c?Cc.AddObject:Cc.UpdateObject;if(t===Cc.UpdateObject){for(let A of u)if(A.objectID===void 0)return Wt.createWaitablePromise(Promise.reject(bC()))}return _m(i)(u,t,g)},yW=i=>(u,f)=>iw(i)([u],f),iw=i=>(u,f)=>{let A=f||{},{forwardToReplicas:c,clearExistingRules:g}=A,t=Si(A,["forwardToReplicas","clearExistingRules"]),C=jo.createMappedRequestOptions(t);return c&&(C.queryParameters.forwardToReplicas=1),g&&(C.queryParameters.clearExistingRules=1),Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Post,path:Wt.encode("1/indexes/%s/rules/batch",i.indexName),data:u},C),(x,D)=>z0(i)(x.taskID,D))},wW=i=>(u,f)=>ow(i)([u],f),ow=i=>(u,f)=>{let A=f||{},{forwardToReplicas:c,replaceExistingSynonyms:g}=A,t=Si(A,["forwardToReplicas","replaceExistingSynonyms"]),C=jo.createMappedRequestOptions(t);return c&&(C.queryParameters.forwardToReplicas=1),g&&(C.queryParameters.replaceExistingSynonyms=1),Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Post,path:Wt.encode("1/indexes/%s/synonyms/batch",i.indexName),data:u},C),(x,D)=>z0(i)(x.taskID,D))},ZC=i=>(u,f)=>i.transporter.read({method:Rn.MethodEnum.Post,path:Wt.encode("1/indexes/%s/query",i.indexName),data:{query:u},cacheable:!0},f),YC=i=>(u,f,c)=>i.transporter.read({method:Rn.MethodEnum.Post,path:Wt.encode("1/indexes/%s/facets/%s/query",i.indexName,u),data:{facetQuery:f},cacheable:!0},c),KC=i=>(u,f)=>i.transporter.read({method:Rn.MethodEnum.Post,path:Wt.encode("1/indexes/%s/rules/search",i.indexName),data:{query:u}},f),XC=i=>(u,f)=>i.transporter.read({method:Rn.MethodEnum.Post,path:Wt.encode("1/indexes/%s/synonyms/search",i.indexName),data:{query:u}},f),DW=i=>(u,f)=>{let C=f||{},{forwardToReplicas:c}=C,g=Si(C,["forwardToReplicas"]),t=jo.createMappedRequestOptions(g);return c&&(t.queryParameters.forwardToReplicas=1),Wt.createWaitablePromise(i.transporter.write({method:Rn.MethodEnum.Put,path:Wt.encode("1/indexes/%s/settings",i.indexName),data:u},t),(A,x)=>z0(i)(A.taskID,x))},z0=i=>(u,f)=>Wt.createRetryablePromise(c=>eT(i)(u,f).then(g=>g.status!=="published"?c():void 0)),EW={AddObject:"addObject",Analytics:"analytics",Browser:"browse",DeleteIndex:"deleteIndex",DeleteObject:"deleteObject",EditSettings:"editSettings",ListIndexes:"listIndexes",Logs:"logs",Recommendation:"recommendation",Search:"search",SeeUnretrievableAttributes:"seeUnretrievableAttributes",Settings:"settings",Usage:"usage"},Cc={AddObject:"addObject",UpdateObject:"updateObject",PartialUpdateObject:"partialUpdateObject",PartialUpdateObjectNoCreate:"partialUpdateObjectNoCreate",DeleteObject:"deleteObject"},gm={Settings:"settings",Synonyms:"synonyms",Rules:"rules"},SW={None:"none",StopIfEnoughMatches:"stopIfEnoughMatches"},CW={Synonym:"synonym",OneWaySynonym:"oneWaySynonym",AltCorrection1:"altCorrection1",AltCorrection2:"altCorrection2",Placeholder:"placeholder"};yt.ApiKeyACLEnum=EW;yt.BatchActionEnum=Cc;yt.ScopeEnum=gm;yt.StrategyEnum=SW;yt.SynonymEnum=CW;yt.addApiKey=Cz;yt.assignUserID=Tz;yt.assignUserIDs=xz;yt.batch=$C;yt.browseObjects=Xz;yt.browseRules=Jz;yt.browseSynonyms=Qz;yt.chunkedBatch=_m;yt.clearObjects=Zz;yt.clearRules=eW;yt.clearSynonyms=tW;yt.copyIndex=vm;yt.copyRules=kz;yt.copySettings=Az;yt.copySynonyms=Oz;yt.createBrowsablePromise=mm;yt.createMissingObjectIDError=bC;yt.createObjectNotFoundError=GC;yt.createSearchClient=Sz;yt.createValidUntilNotFoundError=VC;yt.deleteApiKey=Iz;yt.deleteBy=nW;yt.deleteIndex=rW;yt.deleteObject=iW;yt.deleteObjects=JC;yt.deleteRule=oW;yt.deleteSynonym=uW;yt.exists=sW;yt.findObject=lW;yt.generateSecuredApiKey=Pz;yt.getApiKey=rd;yt.getLogs=Mz;yt.getObject=fW;yt.getObjectPosition=cW;yt.getObjects=aW;yt.getRule=dW;yt.getSecuredApiKeyRemainingValidity=Fz;yt.getSettings=QC;yt.getSynonym=pW;yt.getTask=eT;yt.getTopUserIDs=Lz;yt.getUserID=Rz;yt.hasPendingMappings=Nz;yt.initIndex=id;yt.listApiKeys=Bz;yt.listClusters=jz;yt.listIndices=Uz;yt.listUserIDs=qz;yt.moveIndex=zz;yt.multipleBatch=Wz;yt.multipleGetObjects=Hz;yt.multipleQueries=bz;yt.multipleSearchForFacetValues=Gz;yt.partialUpdateObject=hW;yt.partialUpdateObjects=tT;yt.removeUserID=Vz;yt.replaceAllObjects=mW;yt.replaceAllRules=vW;yt.replaceAllSynonyms=gW;yt.restoreApiKey=Yz;yt.saveObject=_W;yt.saveObjects=rw;yt.saveRule=yW;yt.saveRules=iw;yt.saveSynonym=wW;yt.saveSynonyms=ow;yt.search=ZC;yt.searchForFacetValues=YC;yt.searchRules=KC;yt.searchSynonyms=XC;yt.searchUserIDs=$z;yt.setSettings=DW;yt.updateApiKey=Kz;yt.waitTask=z0});var iT=Me((SV,rT)=>{rT.exports=nT()});var oT=Me(ym=>{"use strict";Object.defineProperty(ym,"__esModule",{value:!0});function TW(){return{debug(i,u){return Promise.resolve()},info(i,u){return Promise.resolve()},error(i,u){return Promise.resolve()}}}var xW={Debug:1,Info:2,Error:3};ym.LogLevelEnum=xW;ym.createNullLogger=TW});var sT=Me((TV,uT)=>{uT.exports=oT()});var cT=Me(uw=>{"use strict";Object.defineProperty(uw,"__esModule",{value:!0});var lT=require("http"),fT=require("https"),kW=require("url");function AW(){let i={keepAlive:!0},u=new lT.Agent(i),f=new fT.Agent(i);return{send(c){return new Promise(g=>{let t=kW.parse(c.url),C=t.query===null?t.pathname:`${t.pathname}?${t.query}`,A=dt({agent:t.protocol==="https:"?f:u,hostname:t.hostname,path:C,method:c.method,headers:c.headers},t.port!==void 0?{port:t.port||""}:{}),x=(t.protocol==="https:"?fT:lT).request(A,j=>{let $="";j.on("data",h=>$+=h),j.on("end",()=>{clearTimeout(L),clearTimeout(N),g({status:j.statusCode||0,content:$,isTimedOut:!1})})}),D=(j,$)=>setTimeout(()=>{x.abort(),g({status:0,content:$,isTimedOut:!0})},j*1e3),L=D(c.connectTimeout,"Connection timeout"),N;x.on("error",j=>{clearTimeout(L),clearTimeout(N),g({status:0,content:j.message,isTimedOut:!1})}),x.once("response",()=>{clearTimeout(L),N=D(c.responseTimeout,"Socket timeout")}),c.data!==void 0&&x.write(c.data),x.end()})},destroy(){return u.destroy(),f.destroy(),Promise.resolve()}}}uw.createNodeHttpRequester=AW});var dT=Me((kV,aT)=>{aT.exports=cT()});var vT=Me((AV,pT)=>{"use strict";var hT=dC(),OW=mC(),Ma=UC(),sw=Q2(),lw=HC(),Mt=iT(),IW=sT(),PW=dT(),MW=ed();function mT(i,u,f){let c={appId:i,apiKey:u,timeouts:{connect:2,read:5,write:30},requester:PW.createNodeHttpRequester(),logger:IW.createNullLogger(),responsesCache:hT.createNullCache(),requestsCache:hT.createNullCache(),hostsCache:OW.createInMemoryCache(),userAgent:MW.createUserAgent(sw.version).add({segment:"Node.js",version:process.versions.node})};return Mt.createSearchClient(zn(dt(dt({},c),f),{methods:{search:Mt.multipleQueries,searchForFacetValues:Mt.multipleSearchForFacetValues,multipleBatch:Mt.multipleBatch,multipleGetObjects:Mt.multipleGetObjects,multipleQueries:Mt.multipleQueries,copyIndex:Mt.copyIndex,copySettings:Mt.copySettings,copyRules:Mt.copyRules,copySynonyms:Mt.copySynonyms,moveIndex:Mt.moveIndex,listIndices:Mt.listIndices,getLogs:Mt.getLogs,listClusters:Mt.listClusters,multipleSearchForFacetValues:Mt.multipleSearchForFacetValues,getApiKey:Mt.getApiKey,addApiKey:Mt.addApiKey,listApiKeys:Mt.listApiKeys,updateApiKey:Mt.updateApiKey,deleteApiKey:Mt.deleteApiKey,restoreApiKey:Mt.restoreApiKey,assignUserID:Mt.assignUserID,assignUserIDs:Mt.assignUserIDs,getUserID:Mt.getUserID,searchUserIDs:Mt.searchUserIDs,listUserIDs:Mt.listUserIDs,getTopUserIDs:Mt.getTopUserIDs,removeUserID:Mt.removeUserID,hasPendingMappings:Mt.hasPendingMappings,generateSecuredApiKey:Mt.generateSecuredApiKey,getSecuredApiKeyRemainingValidity:Mt.getSecuredApiKeyRemainingValidity,destroy:sw.destroy,initIndex:g=>t=>Mt.initIndex(g)(t,{methods:{batch:Mt.batch,delete:Mt.deleteIndex,getObject:Mt.getObject,getObjects:Mt.getObjects,saveObject:Mt.saveObject,saveObjects:Mt.saveObjects,search:Mt.search,searchForFacetValues:Mt.searchForFacetValues,waitTask:Mt.waitTask,setSettings:Mt.setSettings,getSettings:Mt.getSettings,partialUpdateObject:Mt.partialUpdateObject,partialUpdateObjects:Mt.partialUpdateObjects,deleteObject:Mt.deleteObject,deleteObjects:Mt.deleteObjects,deleteBy:Mt.deleteBy,clearObjects:Mt.clearObjects,browseObjects:Mt.browseObjects,getObjectPosition:Mt.getObjectPosition,findObject:Mt.findObject,exists:Mt.exists,saveSynonym:Mt.saveSynonym,saveSynonyms:Mt.saveSynonyms,getSynonym:Mt.getSynonym,searchSynonyms:Mt.searchSynonyms,browseSynonyms:Mt.browseSynonyms,deleteSynonym:Mt.deleteSynonym,clearSynonyms:Mt.clearSynonyms,replaceAllObjects:Mt.replaceAllObjects,replaceAllSynonyms:Mt.replaceAllSynonyms,searchRules:Mt.searchRules,getRule:Mt.getRule,deleteRule:Mt.deleteRule,saveRule:Mt.saveRule,saveRules:Mt.saveRules,replaceAllRules:Mt.replaceAllRules,browseRules:Mt.browseRules,clearRules:Mt.clearRules}}),initAnalytics:()=>g=>Ma.createAnalyticsClient(zn(dt(dt({},c),g),{methods:{addABTest:Ma.addABTest,getABTest:Ma.getABTest,getABTests:Ma.getABTests,stopABTest:Ma.stopABTest,deleteABTest:Ma.deleteABTest}})),initRecommendation:()=>g=>lw.createRecommendationClient(zn(dt(dt({},c),g),{methods:{getPersonalizationStrategy:lw.getPersonalizationStrategy,setPersonalizationStrategy:lw.setPersonalizationStrategy}}))}}))}mT.version=sw.version;pT.exports=mT});var _T=Me((OV,fw)=>{var gT=vT();fw.exports=gT;fw.exports.default=gT});var rf=Me(dw=>{"use strict";Object.defineProperty(dw,"__esModule",{value:!0});dw.default=kT;function kT(){}kT.prototype={diff:function(u,f){var c=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},g=c.callback;typeof c=="function"&&(g=c,c={}),this.options=c;var t=this;function C(re){return g?(setTimeout(function(){g(void 0,re)},0),!0):re}u=this.castInput(u),f=this.castInput(f),u=this.removeEmpty(this.tokenize(u)),f=this.removeEmpty(this.tokenize(f));var A=f.length,x=u.length,D=1,L=A+x,N=[{newPos:-1,components:[]}],j=this.extractCommon(N[0],f,u,0);if(N[0].newPos+1>=A&&j+1>=x)return C([{value:this.join(f),count:f.length}]);function $(){for(var re=-1*D;re<=D;re+=2){var ce=void 0,Q=N[re-1],oe=N[re+1],Se=(oe?oe.newPos:0)-re;Q&&(N[re-1]=void 0);var me=Q&&Q.newPos+1=A&&Se+1>=x)return C(LW(t,ce.components,f,u,t.useLongestToken));N[re]=ce}D++}if(g)(function re(){setTimeout(function(){if(D>L)return g();$()||re()},0)})();else for(;D<=L;){var h=$();if(h)return h}},pushComponent:function(u,f,c){var g=u[u.length-1];g&&g.added===f&&g.removed===c?u[u.length-1]={count:g.count+1,added:f,removed:c}:u.push({count:1,added:f,removed:c})},extractCommon:function(u,f,c,g){for(var t=f.length,C=c.length,A=u.newPos,x=A-g,D=0;A+1$.length?re:$}),D.value=i.join(L)}else D.value=i.join(f.slice(A,A+D.count));A+=D.count,D.added||(x+=D.count)}}var j=u[C-1];return C>1&&typeof j.value=="string"&&(j.added||j.removed)&&i.equals("",j.value)&&(u[C-2].value+=j.value,u.pop()),u}function RW(i){return{newPos:i.newPos,components:i.components.slice(0)}}});var OT=Me(ld=>{"use strict";Object.defineProperty(ld,"__esModule",{value:!0});ld.diffChars=NW;ld.characterDiff=void 0;var jW=BW(rf());function BW(i){return i&&i.__esModule?i:{default:i}}var AT=new jW.default;ld.characterDiff=AT;function NW(i,u,f){return AT.diff(i,u,f)}});var hw=Me(pw=>{"use strict";Object.defineProperty(pw,"__esModule",{value:!0});pw.generateOptions=UW;function UW(i,u){if(typeof i=="function")u.callback=i;else if(i)for(var f in i)i.hasOwnProperty(f)&&(u[f]=i[f]);return u}});var MT=Me(Fa=>{"use strict";Object.defineProperty(Fa,"__esModule",{value:!0});Fa.diffWords=qW;Fa.diffWordsWithSpace=zW;Fa.wordDiff=void 0;var HW=WW(rf()),bW=hw();function WW(i){return i&&i.__esModule?i:{default:i}}var IT=/^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/,PT=/\S/,fd=new HW.default;Fa.wordDiff=fd;fd.equals=function(i,u){return this.options.ignoreCase&&(i=i.toLowerCase(),u=u.toLowerCase()),i===u||this.options.ignoreWhitespace&&!PT.test(i)&&!PT.test(u)};fd.tokenize=function(i){for(var u=i.split(/(\s+|[()[\]{}'"]|\b)/),f=0;f{"use strict";Object.defineProperty(La,"__esModule",{value:!0});La.diffLines=GW;La.diffTrimmedLines=VW;La.lineDiff=void 0;var $W=YW(rf()),KW=hw();function YW(i){return i&&i.__esModule?i:{default:i}}var Dm=new $W.default;La.lineDiff=Dm;Dm.tokenize=function(i){var u=[],f=i.split(/(\n|\r\n)/);f[f.length-1]||f.pop();for(var c=0;c{"use strict";Object.defineProperty(cd,"__esModule",{value:!0});cd.diffSentences=XW;cd.sentenceDiff=void 0;var QW=JW(rf());function JW(i){return i&&i.__esModule?i:{default:i}}var mw=new QW.default;cd.sentenceDiff=mw;mw.tokenize=function(i){return i.split(/(\S.+?[.!?])(?=\s+|$)/)};function XW(i,u,f){return mw.diff(i,u,f)}});var LT=Me(ad=>{"use strict";Object.defineProperty(ad,"__esModule",{value:!0});ad.diffCss=ZW;ad.cssDiff=void 0;var tH=eH(rf());function eH(i){return i&&i.__esModule?i:{default:i}}var vw=new tH.default;ad.cssDiff=vw;vw.tokenize=function(i){return i.split(/([{}:;,]|\s+)/)};function ZW(i,u,f){return vw.diff(i,u,f)}});var NT=Me(Ra=>{"use strict";Object.defineProperty(Ra,"__esModule",{value:!0});Ra.diffJson=nH;Ra.canonicalize=Sm;Ra.jsonDiff=void 0;var RT=rH(rf()),iH=Em();function rH(i){return i&&i.__esModule?i:{default:i}}function Cm(i){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Cm=function(f){return typeof f}:Cm=function(f){return f&&typeof Symbol=="function"&&f.constructor===Symbol&&f!==Symbol.prototype?"symbol":typeof f},Cm(i)}var oH=Object.prototype.toString,xc=new RT.default;Ra.jsonDiff=xc;xc.useLongestToken=!0;xc.tokenize=iH.lineDiff.tokenize;xc.castInput=function(i){var u=this.options,f=u.undefinedReplacement,c=u.stringifyReplacer,g=c===void 0?function(t,C){return typeof C=="undefined"?f:C}:c;return typeof i=="string"?i:JSON.stringify(Sm(i,null,null,g),g," ")};xc.equals=function(i,u){return RT.default.prototype.equals.call(xc,i.replace(/,([\r\n])/g,"$1"),u.replace(/,([\r\n])/g,"$1"))};function nH(i,u,f){return xc.diff(i,u,f)}function Sm(i,u,f,c,g){u=u||[],f=f||[],c&&(i=c(g,i));var t;for(t=0;t{"use strict";Object.defineProperty(dd,"__esModule",{value:!0});dd.diffArrays=uH;dd.arrayDiff=void 0;var lH=sH(rf());function sH(i){return i&&i.__esModule?i:{default:i}}var pd=new lH.default;dd.arrayDiff=pd;pd.tokenize=function(i){return i.slice()};pd.join=pd.removeEmpty=function(i){return i};function uH(i,u,f){return pd.diff(i,u,f)}});var Tm=Me(gw=>{"use strict";Object.defineProperty(gw,"__esModule",{value:!0});gw.parsePatch=fH;function fH(i){var u=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},f=i.split(/\r\n|[\n\v\f\r\x85]/),c=i.match(/\r\n|[\n\v\f\r\x85]/g)||[],g=[],t=0;function C(){var D={};for(g.push(D);t{"use strict";Object.defineProperty(_w,"__esModule",{value:!0});_w.default=cH;function cH(i,u,f){var c=!0,g=!1,t=!1,C=1;return function A(){if(c&&!t){if(g?C++:c=!1,i+C<=f)return C;t=!0}if(!g)return t||(c=!0),u<=i-C?-C++:(g=!0,A())}}});var zT=Me(xm=>{"use strict";Object.defineProperty(xm,"__esModule",{value:!0});xm.applyPatch=UT;xm.applyPatches=aH;var qT=Tm(),pH=dH(jT());function dH(i){return i&&i.__esModule?i:{default:i}}function UT(i,u){var f=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(typeof u=="string"&&(u=(0,qT.parsePatch)(u)),Array.isArray(u)){if(u.length>1)throw new Error("applyPatch only works with a single input.");u=u[0]}var c=i.split(/\r\n|[\n\v\f\r\x85]/),g=i.match(/\r\n|[\n\v\f\r\x85]/g)||[],t=u.hunks,C=f.compareLine||function(Ot,Nt,Je,V){return Nt===V},A=0,x=f.fuzzFactor||0,D=0,L=0,N,j;function $(Ot,Nt){for(var Je=0;Je0?V[0]:" ",ge=V.length>0?V.substr(1):V;if(ne===" "||ne==="-"){if(!C(Nt+1,c[Nt],ne,ge)&&(A++,A>x))return!1;Nt++}}return!0}for(var h=0;h0?Le[0]:" ",ct=Le.length>0?Le.substr(1):Le,Ue=J.linedelimiters[Oe];if(ot===" ")Te++;else if(ot==="-")c.splice(Te,1),g.splice(Te,1);else if(ot==="+")c.splice(Te,0,ct),g.splice(Te,0,Ue),Te++;else if(ot==="\\"){var be=J.lines[Oe-1]?J.lines[Oe-1][0]:null;be==="+"?N=!0:be==="-"&&(j=!0)}}}if(N)for(;!c[c.length-1];)c.pop(),g.pop();else j&&(c.push(""),g.push(` +`));for(var At=0;At{"use strict";Object.defineProperty(hd,"__esModule",{value:!0});hd.structuredPatch=WT;hd.createTwoFilesPatch=HT;hd.createPatch=hH;var mH=Em();function yw(i){return _H(i)||gH(i)||vH()}function vH(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function gH(i){if(Symbol.iterator in Object(i)||Object.prototype.toString.call(i)==="[object Arguments]")return Array.from(i)}function _H(i){if(Array.isArray(i)){for(var u=0,f=new Array(i.length);u0?x(J.lines.slice(-C.context)):[],L-=j.length,N-=j.length)}(De=j).push.apply(De,yw(me.map(function(At){return(Se.added?"+":"-")+At}))),Se.added?h+=me.length:$+=me.length}else{if(L)if(me.length<=C.context*2&&oe=A.length-2&&me.length<=C.context){var ct=/\n$/.test(f),Ue=/\n$/.test(c),be=me.length==0&&j.length>ot.oldLines;!ct&&be&&j.splice(ot.oldLines,0,"\\ No newline at end of file"),(!ct&&!be||!Ue)&&j.push("\\ No newline at end of file")}D.push(ot),L=0,N=0,j=[]}$+=me.length,h+=me.length}},ce=0;ce{"use strict";Object.defineProperty(km,"__esModule",{value:!0});km.arrayEqual=yH;km.arrayStartsWith=bT;function yH(i,u){return i.length!==u.length?!1:bT(i,u)}function bT(i,u){if(u.length>i.length)return!1;for(var f=0;f{"use strict";Object.defineProperty(Am,"__esModule",{value:!0});Am.calcLineCount=VT;Am.merge=wH;var DH=ww(),EH=Tm(),Dw=GT();function Na(i){return TH(i)||CH(i)||SH()}function SH(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function CH(i){if(Symbol.iterator in Object(i)||Object.prototype.toString.call(i)==="[object Arguments]")return Array.from(i)}function TH(i){if(Array.isArray(i)){for(var u=0,f=new Array(i.length);u{"use strict";Object.defineProperty(Cw,"__esModule",{value:!0});Cw.convertChangesToDMP=OH;function OH(i){for(var u=[],f,c,g=0;g{"use strict";Object.defineProperty(Tw,"__esModule",{value:!0});Tw.convertChangesToXML=IH;function IH(i){for(var u=[],f=0;f"):c.removed&&u.push(""),u.push(PH(c.value)),c.added?u.push(""):c.removed&&u.push("")}return u.join("")}function PH(i){var u=i;return u=u.replace(/&/g,"&"),u=u.replace(//g,">"),u=u.replace(/"/g,"""),u}});var f9=Me(w0=>{"use strict";Object.defineProperty(w0,"__esModule",{value:!0});Object.defineProperty(w0,"Diff",{enumerable:!0,get:function(){return MH.default}});Object.defineProperty(w0,"diffChars",{enumerable:!0,get:function(){return FH.diffChars}});Object.defineProperty(w0,"diffWords",{enumerable:!0,get:function(){return o9.diffWords}});Object.defineProperty(w0,"diffWordsWithSpace",{enumerable:!0,get:function(){return o9.diffWordsWithSpace}});Object.defineProperty(w0,"diffLines",{enumerable:!0,get:function(){return u9.diffLines}});Object.defineProperty(w0,"diffTrimmedLines",{enumerable:!0,get:function(){return u9.diffTrimmedLines}});Object.defineProperty(w0,"diffSentences",{enumerable:!0,get:function(){return LH.diffSentences}});Object.defineProperty(w0,"diffCss",{enumerable:!0,get:function(){return RH.diffCss}});Object.defineProperty(w0,"diffJson",{enumerable:!0,get:function(){return s9.diffJson}});Object.defineProperty(w0,"canonicalize",{enumerable:!0,get:function(){return s9.canonicalize}});Object.defineProperty(w0,"diffArrays",{enumerable:!0,get:function(){return NH.diffArrays}});Object.defineProperty(w0,"applyPatch",{enumerable:!0,get:function(){return l9.applyPatch}});Object.defineProperty(w0,"applyPatches",{enumerable:!0,get:function(){return l9.applyPatches}});Object.defineProperty(w0,"parsePatch",{enumerable:!0,get:function(){return BH.parsePatch}});Object.defineProperty(w0,"merge",{enumerable:!0,get:function(){return jH.merge}});Object.defineProperty(w0,"structuredPatch",{enumerable:!0,get:function(){return xw.structuredPatch}});Object.defineProperty(w0,"createTwoFilesPatch",{enumerable:!0,get:function(){return xw.createTwoFilesPatch}});Object.defineProperty(w0,"createPatch",{enumerable:!0,get:function(){return xw.createPatch}});Object.defineProperty(w0,"convertChangesToDMP",{enumerable:!0,get:function(){return UH.convertChangesToDMP}});Object.defineProperty(w0,"convertChangesToXML",{enumerable:!0,get:function(){return qH.convertChangesToXML}});var MH=zH(rf()),FH=OT(),o9=MT(),u9=Em(),LH=FT(),RH=LT(),s9=NT(),NH=BT(),l9=zT(),BH=Tm(),jH=n9(),xw=ww(),UH=r9(),qH=i9();function zH(i){return i&&i.__esModule?i:{default:i}}});var HH={};jR(HH,{default:()=>GH});var wT=Er(require("@yarnpkg/cli")),Tc=Er(require("@yarnpkg/core"));var Z5=Er(ys()),Dc=Er(lr()),om=(0,Dc.memo)(({active:i})=>{let u=(0,Dc.useMemo)(()=>i?"\u25C9":"\u25EF",[i]),f=(0,Dc.useMemo)(()=>i?"green":"yellow",[i]);return Dc.default.createElement(Z5.Text,{color:f},u)});var Wf=Er(ys()),Bo=Er(lr());var eC=Er(ys()),um=Er(lr());function zf({active:i},u,f){let{stdin:c}=(0,eC.useStdin)(),g=(0,um.useCallback)((t,C)=>u(t,C),f);(0,um.useEffect)(()=>{if(!(!i||!c))return c.on("keypress",g),()=>{c.off("keypress",g)}},[i,g,c])}var sm;(function(f){f.BEFORE="before",f.AFTER="after"})(sm||(sm={}));var tC=function({active:i},u,f){zf({active:i},(c,g)=>{g.name==="tab"&&(g.shift?u(sm.BEFORE):u(sm.AFTER))},f)};var lm=function(i,u,{active:f,minus:c,plus:g,set:t,loop:C=!0}){zf({active:f},(A,x)=>{let D=u.indexOf(i);switch(x.name){case c:{let L=D-1;if(C){t(u[(u.length+L)%u.length]);return}if(L<0)return;t(u[L])}break;case g:{let L=D+1;if(C){t(u[L%u.length]);return}if(L>=u.length)return;t(u[L])}break}},[u,i,g,t,C])};var fm=({active:i=!0,children:u=[],radius:f=10,size:c=1,loop:g=!0,onFocusRequest:t,willReachEnd:C})=>{let A=ce=>{if(ce.key===null)throw new Error("Expected all children to have a key");return ce.key},x=Bo.default.Children.map(u,ce=>A(ce)),D=x[0],[L,N]=(0,Bo.useState)(D),j=x.indexOf(L);(0,Bo.useEffect)(()=>{x.includes(L)||N(D)},[u]),(0,Bo.useEffect)(()=>{C&&j>=x.length-2&&C()},[j]),tC({active:i&&!!t},ce=>{t==null||t(ce)},[t]),lm(L,x,{active:i,minus:"up",plus:"down",set:N,loop:g});let $=j-f,h=j+f;h>x.length&&($-=h-x.length,h=x.length),$<0&&(h+=-$,$=0),h>=x.length&&(h=x.length-1);let re=[];for(let ce=$;ce<=h;++ce){let Q=x[ce],oe=i&&Q===L;re.push(Bo.default.createElement(Wf.Box,{key:Q,height:c},Bo.default.createElement(Wf.Box,{marginLeft:1,marginRight:1},Bo.default.createElement(Wf.Text,null,oe?Bo.default.createElement(Wf.Text,{color:"cyan",bold:!0},">"):" ")),Bo.default.createElement(Wf.Box,null,Bo.default.cloneElement(u[ce],{active:oe}))))}return Bo.default.createElement(Wf.Box,{flexDirection:"column",width:"100%"},re)};var cm=Er(lr());var nC=Er(ys()),nf=Er(lr()),rC=Er(require("readline")),G3=nf.default.createContext(null),iC=({children:i})=>{let{stdin:u,setRawMode:f}=(0,nC.useStdin)();(0,nf.useEffect)(()=>{f&&f(!0),u&&(0,rC.emitKeypressEvents)(u)},[u,f]);let[c,g]=(0,nf.useState)(new Map),t=(0,nf.useMemo)(()=>({getAll:()=>c,get:C=>c.get(C),set:(C,A)=>g(new Map([...c,[C,A]]))}),[c,g]);return nf.default.createElement(G3.Provider,{value:t,children:i})};function Ec(i,u){let f=(0,cm.useContext)(G3);if(f===null)throw new Error("Expected this hook to run with a ministore context attached");if(typeof i=="undefined")return f.getAll();let c=(0,cm.useCallback)(t=>{f.set(i,t)},[i,f.set]),g=f.get(i);return typeof g=="undefined"&&(g=u),[g,c]}var am=Er(ys()),V3=Er(lr());async function dm(i,u){let f,c=t=>{let{exit:C}=(0,am.useApp)();zf({active:!0},(A,x)=>{x.name==="return"&&(f=t,C())},[C,t])},{waitUntilExit:g}=(0,am.render)(V3.default.createElement(iC,null,V3.default.createElement(i,zn(dt({},u),{useSubmit:c}))));return await g(),f}var DT=Er(require("clipanion")),ET=Er(lC()),un=Er(ys()),Pt=Er(lr());var yT=Er(_T()),cw={appId:"OFCNCOG2CU",apiKey:"6fe4476ee5a1832882e326b506d14126",indexName:"npm-search"},FW=(0,yT.default)(cw.appId,cw.apiKey).initIndex(cw.indexName),aw=async(i,u=0)=>await FW.search(i,{analyticsTags:["yarn-plugin-interactive-tools"],attributesToRetrieve:["name","version","owner","repository","humanDownloadsLast30Days"],page:u,hitsPerPage:10});var od=["regular","dev","peer"],ud=class extends wT.BaseCommand{async execute(){let u=await Tc.Configuration.find(this.context.cwd,this.context.plugins),f=()=>Pt.default.createElement(un.Box,{flexDirection:"row"},Pt.default.createElement(un.Box,{flexDirection:"column",width:48},Pt.default.createElement(un.Box,null,Pt.default.createElement(un.Text,null,"Press ",Pt.default.createElement(un.Text,{bold:!0,color:"cyanBright"},""),"/",Pt.default.createElement(un.Text,{bold:!0,color:"cyanBright"},"")," to move between packages.")),Pt.default.createElement(un.Box,null,Pt.default.createElement(un.Text,null,"Press ",Pt.default.createElement(un.Text,{bold:!0,color:"cyanBright"},"")," to select a package.")),Pt.default.createElement(un.Box,null,Pt.default.createElement(un.Text,null,"Press ",Pt.default.createElement(un.Text,{bold:!0,color:"cyanBright"},"")," again to change the target."))),Pt.default.createElement(un.Box,{flexDirection:"column"},Pt.default.createElement(un.Box,{marginLeft:1},Pt.default.createElement(un.Text,null,"Press ",Pt.default.createElement(un.Text,{bold:!0,color:"cyanBright"},"")," to install the selected packages.")),Pt.default.createElement(un.Box,{marginLeft:1},Pt.default.createElement(un.Text,null,"Press ",Pt.default.createElement(un.Text,{bold:!0,color:"cyanBright"},"")," to abort.")))),c=()=>Pt.default.createElement(Pt.default.Fragment,null,Pt.default.createElement(un.Box,{width:15},Pt.default.createElement(un.Text,{bold:!0,underline:!0,color:"gray"},"Owner")),Pt.default.createElement(un.Box,{width:11},Pt.default.createElement(un.Text,{bold:!0,underline:!0,color:"gray"},"Version")),Pt.default.createElement(un.Box,{width:10},Pt.default.createElement(un.Text,{bold:!0,underline:!0,color:"gray"},"Downloads"))),g=()=>Pt.default.createElement(un.Box,{width:17},Pt.default.createElement(un.Text,{bold:!0,underline:!0,color:"gray"},"Target")),t=({hit:$,active:h})=>{let[re,ce]=Ec($.name,null);zf({active:h},(Se,me)=>{if(me.name!=="space")return;if(!re){ce(od[0]);return}let De=od.indexOf(re)+1;De===od.length?ce(null):ce(od[De])},[re,ce]);let Q=Tc.structUtils.parseIdent($.name),oe=Tc.structUtils.prettyIdent(u,Q);return Pt.default.createElement(un.Box,null,Pt.default.createElement(un.Box,{width:45},Pt.default.createElement(un.Text,{bold:!0,wrap:"wrap"},oe)),Pt.default.createElement(un.Box,{width:14,marginLeft:1},Pt.default.createElement(un.Text,{bold:!0,wrap:"truncate"},$.owner.name)),Pt.default.createElement(un.Box,{width:10,marginLeft:1},Pt.default.createElement(un.Text,{italic:!0,wrap:"truncate"},$.version)),Pt.default.createElement(un.Box,{width:16,marginLeft:1},Pt.default.createElement(un.Text,null,$.humanDownloadsLast30Days)))},C=({name:$,active:h})=>{let[re]=Ec($,null),ce=Tc.structUtils.parseIdent($);return Pt.default.createElement(un.Box,null,Pt.default.createElement(un.Box,{width:47},Pt.default.createElement(un.Text,{bold:!0}," - ",Tc.structUtils.prettyIdent(u,ce))),od.map(Q=>Pt.default.createElement(un.Box,{key:Q,width:14,marginLeft:1},Pt.default.createElement(un.Text,null," ",Pt.default.createElement(om,{active:re===Q})," ",Pt.default.createElement(un.Text,{bold:!0},Q)))))},A=()=>Pt.default.createElement(un.Box,{marginTop:1},Pt.default.createElement(un.Text,null,"Powered by Algolia.")),D=await dm(({useSubmit:$})=>{let h=Ec();$(h);let re=Array.from(h.keys()).filter(Le=>h.get(Le)!==null),[ce,Q]=(0,Pt.useState)(""),[oe,Se]=(0,Pt.useState)(0),[me,De]=(0,Pt.useState)([]),J=Le=>{Le.match(/\t| /)||Q(Le)},Te=async()=>{Se(0);let Le=await aw(ce);Le.query===ce&&De(Le.hits)},Oe=async()=>{let Le=await aw(ce,oe+1);Le.query===ce&&Le.page-1===oe&&(Se(Le.page),De([...me,...Le.hits]))};return(0,Pt.useEffect)(()=>{ce?Te():De([])},[ce]),Pt.default.createElement(un.Box,{flexDirection:"column"},Pt.default.createElement(f,null),Pt.default.createElement(un.Box,{flexDirection:"row",marginTop:1},Pt.default.createElement(un.Text,{bold:!0},"Search: "),Pt.default.createElement(un.Box,{width:41},Pt.default.createElement(ET.default,{value:ce,onChange:J,placeholder:"i.e. babel, webpack, react...",showCursor:!1})),Pt.default.createElement(c,null)),me.length?Pt.default.createElement(fm,{radius:2,loop:!1,children:me.map(Le=>Pt.default.createElement(t,{key:Le.name,hit:Le,active:!1})),willReachEnd:Oe}):Pt.default.createElement(un.Text,{color:"gray"},"Start typing..."),Pt.default.createElement(un.Box,{flexDirection:"row",marginTop:1},Pt.default.createElement(un.Box,{width:49},Pt.default.createElement(un.Text,{bold:!0},"Selected:")),Pt.default.createElement(g,null)),re.length?re.map(Le=>Pt.default.createElement(C,{key:Le,name:Le,active:!1})):Pt.default.createElement(un.Text,{color:"gray"},"No selected packages..."),Pt.default.createElement(A,null))},{});if(typeof D=="undefined")return 1;let L=Array.from(D.keys()).filter($=>D.get($)==="regular"),N=Array.from(D.keys()).filter($=>D.get($)==="dev"),j=Array.from(D.keys()).filter($=>D.get($)==="peer");return L.length&&await this.cli.run(["add",...L]),N.length&&await this.cli.run(["add","--dev",...N]),j&&await this.cli.run(["add","--peer",...j]),0}};ud.paths=[["search"]],ud.usage=DT.Command.Usage({category:"Interactive commands",description:"open the search interface",details:` + This command opens a fullscreen terminal interface where you can search for and install packages from the npm registry. + `,examples:[["Open the search window","yarn search"]]});var ST=ud;var Im=Er(require("@yarnpkg/cli")),W0=Er(require("@yarnpkg/core"));var sd=Er(ys()),bf=Er(lr());var CT=Er(ys()),TT=Er(lr()),wm=({length:i,active:u})=>{if(i===0)return null;let f=i>1?` ${"-".repeat(i-1)}`:" ";return TT.default.createElement(CT.Text,{dimColor:!u},f)};var xT=function({active:i,skewer:u,options:f,value:c,onChange:g,sizes:t=[]}){let C=f.filter(({label:x})=>!!x).map(({value:x})=>x),A=f.findIndex(x=>x.value===c&&x.label!="");return lm(c,C,{active:i,minus:"left",plus:"right",set:g}),bf.default.createElement(bf.default.Fragment,null,f.map(({label:x},D)=>{let L=D===A,N=t[D]-1||0,j=x.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,""),$=Math.max(0,N-j.length-2);return x?bf.default.createElement(sd.Box,{key:x,width:N,marginLeft:1},bf.default.createElement(sd.Text,{wrap:"truncate"},bf.default.createElement(om,{active:L})," ",x),u?bf.default.createElement(wm,{active:i,length:$}):null):bf.default.createElement(sd.Box,{key:`spacer-${D}`,width:N,marginLeft:1})}))};var c9=Er(require("@yarnpkg/plugin-essentials")),a9=Er(require("clipanion")),d9=Er(f9()),tr=Er(ys()),pn=Er(lr()),p9=Er(require("semver")),h9=/^((?:[\^~]|>=?)?)([0-9]+)(\.[0-9]+)(\.[0-9]+)((?:-\S+)?)$/,WH=10,md=class extends Im.BaseCommand{async execute(){let u=await W0.Configuration.find(this.context.cwd,this.context.plugins),{project:f,workspace:c}=await W0.Project.find(u,this.context.cwd),g=await W0.Cache.find(u);if(!c)throw new Im.WorkspaceRequiredError(f.cwd,this.context.cwd);await f.restoreInstallState({restoreResolutions:!1});let t=(Q,oe)=>{let Se=(0,d9.diffWords)(Q,oe),me="";for(let De of Se)De.added?me+=W0.formatUtils.pretty(u,De.value,"green"):De.removed||(me+=De.value);return me},C=(Q,oe)=>{if(Q===oe)return oe;let Se=W0.structUtils.parseRange(Q),me=W0.structUtils.parseRange(oe),De=Se.selector.match(h9),J=me.selector.match(h9);if(!De||!J)return t(Q,oe);let Te=["gray","red","yellow","green","magenta"],Oe=null,Le="";for(let ot=1;ot{let me=await c9.suggestUtils.fetchDescriptorFrom(Q,Se,{project:f,cache:g,preserveModifier:oe,workspace:c});return me!==null?me.range:Q.range},x=async Q=>{let oe=p9.default.valid(Q.range)?`^${Q.range}`:Q.range,[Se,me]=await Promise.all([A(Q,Q.range,oe).catch(()=>null),A(Q,Q.range,"latest").catch(()=>null)]),De=[{value:null,label:Q.range}];return Se&&Se!==Q.range?De.push({value:Se,label:C(Q.range,Se)}):De.push({value:null,label:""}),me&&me!==Se&&me!==Q.range?De.push({value:me,label:C(Q.range,me)}):De.push({value:null,label:""}),De},D=()=>pn.default.createElement(tr.Box,{flexDirection:"row"},pn.default.createElement(tr.Box,{flexDirection:"column",width:49},pn.default.createElement(tr.Box,{marginLeft:1},pn.default.createElement(tr.Text,null,"Press ",pn.default.createElement(tr.Text,{bold:!0,color:"cyanBright"},""),"/",pn.default.createElement(tr.Text,{bold:!0,color:"cyanBright"},"")," to select packages.")),pn.default.createElement(tr.Box,{marginLeft:1},pn.default.createElement(tr.Text,null,"Press ",pn.default.createElement(tr.Text,{bold:!0,color:"cyanBright"},""),"/",pn.default.createElement(tr.Text,{bold:!0,color:"cyanBright"},"")," to select versions."))),pn.default.createElement(tr.Box,{flexDirection:"column"},pn.default.createElement(tr.Box,{marginLeft:1},pn.default.createElement(tr.Text,null,"Press ",pn.default.createElement(tr.Text,{bold:!0,color:"cyanBright"},"")," to install.")),pn.default.createElement(tr.Box,{marginLeft:1},pn.default.createElement(tr.Text,null,"Press ",pn.default.createElement(tr.Text,{bold:!0,color:"cyanBright"},"")," to abort.")))),L=()=>pn.default.createElement(tr.Box,{flexDirection:"row",paddingTop:1,paddingBottom:1},pn.default.createElement(tr.Box,{width:50},pn.default.createElement(tr.Text,{bold:!0},pn.default.createElement(tr.Text,{color:"greenBright"},"?")," Pick the packages you want to upgrade.")),pn.default.createElement(tr.Box,{width:17},pn.default.createElement(tr.Text,{bold:!0,underline:!0,color:"gray"},"Current")),pn.default.createElement(tr.Box,{width:17},pn.default.createElement(tr.Text,{bold:!0,underline:!0,color:"gray"},"Range")),pn.default.createElement(tr.Box,{width:17},pn.default.createElement(tr.Text,{bold:!0,underline:!0,color:"gray"},"Latest"))),N=({active:Q,descriptor:oe,suggestions:Se})=>{let[me,De]=Ec(oe.descriptorHash,null),J=W0.structUtils.stringifyIdent(oe),Te=Math.max(0,45-J.length);return pn.default.createElement(pn.default.Fragment,null,pn.default.createElement(tr.Box,null,pn.default.createElement(tr.Box,{width:45},pn.default.createElement(tr.Text,{bold:!0},W0.structUtils.prettyIdent(u,oe)),pn.default.createElement(wm,{active:Q,length:Te})),Se!==null?pn.default.createElement(xT,{active:Q,options:Se,value:me,skewer:!0,onChange:De,sizes:[17,17,17]}):pn.default.createElement(tr.Box,{marginLeft:2},pn.default.createElement(tr.Text,{color:"gray"},"Fetching suggestions..."))))},j=({dependencies:Q})=>{let[oe,Se]=(0,pn.useState)(null),me=(0,pn.useRef)(!0);return(0,pn.useEffect)(()=>()=>{me.current=!1}),(0,pn.useEffect)(()=>{Promise.all(Q.map(De=>x(De))).then(De=>{let J=Q.map((Te,Oe)=>{let Le=De[Oe];return[Te,Le]}).filter(([Te,Oe])=>Oe.filter(Le=>Le.label!=="").length>1);me.current&&Se(J)})},[]),oe?oe.length?pn.default.createElement(fm,{radius:WH,children:oe.map(([De,J])=>pn.default.createElement(N,{key:De.descriptorHash,active:!1,descriptor:De,suggestions:J}))}):pn.default.createElement(tr.Text,null,"No upgrades found"):pn.default.createElement(tr.Text,null,"Fetching suggestions...")},h=await dm(({useSubmit:Q})=>{Q(Ec());let oe=new Map;for(let me of f.workspaces)for(let De of["dependencies","devDependencies"])for(let J of me.manifest[De].values())f.tryWorkspaceByDescriptor(J)===null&&oe.set(J.descriptorHash,J);let Se=W0.miscUtils.sortMap(oe.values(),me=>W0.structUtils.stringifyDescriptor(me));return pn.default.createElement(tr.Box,{flexDirection:"column"},pn.default.createElement(D,null),pn.default.createElement(L,null),pn.default.createElement(j,{dependencies:Se}))},{});if(typeof h=="undefined")return 1;let re=!1;for(let Q of f.workspaces)for(let oe of["dependencies","devDependencies"]){let Se=Q.manifest[oe];for(let me of Se.values()){let De=h.get(me.descriptorHash);typeof De!="undefined"&&De!==null&&(Se.set(me.identHash,W0.structUtils.makeDescriptor(me,De)),re=!0)}}return re?(await W0.StreamReport.start({configuration:u,stdout:this.context.stdout,includeLogs:!this.context.quiet},async Q=>{await f.install({cache:g,report:Q})})).exitCode():0}};md.paths=[["upgrade-interactive"]],md.usage=a9.Command.Usage({category:"Interactive commands",description:"open the upgrade interface",details:` + This command opens a fullscreen terminal interface where you can see any out of date packages used by your application, their status compared to the latest versions available on the remote registry, and select packages to upgrade. + `,examples:[["Open the upgrade window","yarn upgrade-interactive"]]});var m9=md;var bH={commands:[ST,m9]},GH=bH;return HH;})(); +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ +/** + * @license + * Lodash + * Copyright OpenJS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ +/** @license React v0.0.0-experimental-51a3aa6af + * react-debug-tools.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/** @license React v0.0.0-experimental-51a3aa6af + * react-is.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/** @license React v0.0.0-experimental-51a3aa6af + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/** @license React v0.18.0 + * scheduler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ /** @license React v0.24.0 * react-reconciler.production.min.js * @@ -11,51 +350,6 @@ var plugin;plugin=(()=>{var __webpack_modules__={7560:(e,t,n)=>{"use strict";n.r * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -e.exports=function t(r){"use strict";var i=n(9381),o=n(7382),u=n(7181);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;nOe||(e.current=Ae[Oe],Ae[Oe]=null,Oe--)}function Ie(e,t){Oe++,Ae[Oe]=e.current,e.current=t}var Ne={},Me={current:Ne},Re={current:!1},Fe=Ne;function Le(e,t){var n=e.type.contextTypes;if(!n)return Ne;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var i,o={};for(i in n)o[i]=t[i];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=o),o}function Be(e){return null!=(e=e.childContextTypes)}function je(e){Pe(Re),Pe(Me)}function Ue(e){Pe(Re),Pe(Me)}function ze(e,t,n){if(Me.current!==Ne)throw Error(a(168));Ie(Me,t),Ie(Re,n)}function We(e,t,n){var r=e.stateNode;if(e=t.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var o in r=r.getChildContext())if(!(o in e))throw Error(a(108,C(t)||"Unknown",o));return i({},n,{},r)}function He(e){var t=e.stateNode;return t=t&&t.__reactInternalMemoizedMergedChildContext||Ne,Fe=Me.current,Ie(Me,t),Ie(Re,Re.current),!0}function Ve(e,t,n){var r=e.stateNode;if(!r)throw Error(a(169));n?(t=We(e,t,Fe),r.__reactInternalMemoizedMergedChildContext=t,Pe(Re),Pe(Me),Ie(Me,t)):Pe(Re),Ie(Re,n)}var qe=u.unstable_runWithPriority,Ge=u.unstable_scheduleCallback,$e=u.unstable_cancelCallback,Ye=u.unstable_shouldYield,Ke=u.unstable_requestPaint,Xe=u.unstable_now,Qe=u.unstable_getCurrentPriorityLevel,Je=u.unstable_ImmediatePriority,Ze=u.unstable_UserBlockingPriority,et=u.unstable_NormalPriority,tt=u.unstable_LowPriority,nt=u.unstable_IdlePriority,rt={},it=void 0!==Ke?Ke:function(){},ot=null,ut=null,at=!1,lt=Xe(),st=1e4>lt?Xe:function(){return Xe()-lt};function ct(){switch(Qe()){case Je:return 99;case Ze:return 98;case et:return 97;case tt:return 96;case nt:return 95;default:throw Error(a(332))}}function ft(e){switch(e){case 99:return Je;case 98:return Ze;case 97:return et;case 96:return tt;case 95:return nt;default:throw Error(a(332))}}function dt(e,t){return e=ft(e),qe(e,t)}function pt(e,t,n){return e=ft(e),Ge(e,t,n)}function ht(e){return null===ot?(ot=[e],ut=Ge(Je,mt)):ot.push(e),rt}function vt(){if(null!==ut){var e=ut;ut=null,$e(e)}mt()}function mt(){if(!at&&null!==ot){at=!0;var e=0;try{var t=ot;dt(99,(function(){for(;e=t&&(dr=!0),e.firstContext=null)}function It(e,t){if(kt!==e&&!1!==t&&0!==t)if("number"==typeof t&&1073741823!==t||(kt=e,t=1073741823),t={context:e,observedBits:t,next:null},null===Ct){if(null===St)throw Error(a(308));Ct=t,St.dependencies={expirationTime:0,firstContext:t,responders:null}}else Ct=Ct.next=t;return q?e._currentValue:e._currentValue2}var Nt=!1;function Mt(e){return{baseState:e,firstUpdate:null,lastUpdate:null,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function Rt(e){return{baseState:e.baseState,firstUpdate:e.firstUpdate,lastUpdate:e.lastUpdate,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function Ft(e,t){return{expirationTime:e,suspenseConfig:t,tag:0,payload:null,callback:null,next:null,nextEffect:null}}function Lt(e,t){null===e.lastUpdate?e.firstUpdate=e.lastUpdate=t:(e.lastUpdate.next=t,e.lastUpdate=t)}function Bt(e,t){var n=e.alternate;if(null===n){var r=e.updateQueue,i=null;null===r&&(r=e.updateQueue=Mt(e.memoizedState))}else r=e.updateQueue,i=n.updateQueue,null===r?null===i?(r=e.updateQueue=Mt(e.memoizedState),i=n.updateQueue=Mt(n.memoizedState)):r=e.updateQueue=Rt(i):null===i&&(i=n.updateQueue=Rt(r));null===i||r===i?Lt(r,t):null===r.lastUpdate||null===i.lastUpdate?(Lt(r,t),Lt(i,t)):(Lt(r,t),i.lastUpdate=t)}function jt(e,t){var n=e.updateQueue;null===(n=null===n?e.updateQueue=Mt(e.memoizedState):Ut(e,n)).lastCapturedUpdate?n.firstCapturedUpdate=n.lastCapturedUpdate=t:(n.lastCapturedUpdate.next=t,n.lastCapturedUpdate=t)}function Ut(e,t){var n=e.alternate;return null!==n&&t===n.updateQueue&&(t=e.updateQueue=Rt(t)),t}function zt(e,t,n,r,o,u){switch(n.tag){case 1:return"function"==typeof(e=n.payload)?e.call(u,r,o):e;case 3:e.effectTag=-4097&e.effectTag|64;case 0:if(null==(o="function"==typeof(e=n.payload)?e.call(u,r,o):e))break;return i({},r,o);case 2:Nt=!0}return r}function Wt(e,t,n,r,i){Nt=!1;for(var o=(t=Ut(e,t)).baseState,u=null,a=0,l=t.firstUpdate,s=o;null!==l;){var c=l.expirationTime;cd?(p=f,f=null):p=f.sibling;var h=m(i,f,a[d],l);if(null===h){null===f&&(f=p);break}e&&f&&null===h.alternate&&t(i,f),u=o(h,u,d),null===c?s=h:c.sibling=h,c=h,f=p}if(d===a.length)return n(i,f),s;if(null===f){for(;dp?(h=d,d=null):h=d.sibling;var _=m(i,d,y.value,s);if(null===_){null===d&&(d=h);break}e&&d&&null===_.alternate&&t(i,d),u=o(_,u,p),null===f?c=_:f.sibling=_,f=_,d=h}if(y.done)return n(i,d),c;if(null===d){for(;!y.done;p++,y=l.next())null!==(y=v(i,y.value,s))&&(u=o(y,u,p),null===f?c=y:f.sibling=y,f=y);return c}for(d=r(i,d);!y.done;p++,y=l.next())null!==(y=g(d,i,p,y.value,s))&&(e&&null!==y.alternate&&d.delete(null===y.key?p:y.key),u=o(y,u,p),null===f?c=y:f.sibling=y,f=y);return e&&d.forEach((function(e){return t(i,e)})),c}return function(e,r,o,l){var s="object"==typeof o&&null!==o&&o.type===d&&null===o.key;s&&(o=o.props.children);var p="object"==typeof o&&null!==o;if(p)switch(o.$$typeof){case c:e:{for(p=o.key,s=r;null!==s;){if(s.key===p){if(7===s.tag?o.type===d:s.elementType===o.type){n(e,s.sibling),(r=i(s,o.type===d?o.props.children:o.props)).ref=en(e,s,o),r.return=e,e=r;break e}n(e,s);break}t(e,s),s=s.sibling}o.type===d?((r=so(o.props.children,e.mode,l,o.key)).return=e,e=r):((l=lo(o.type,o.key,o.props,null,e.mode,l)).ref=en(e,r,o),l.return=e,e=l)}return u(e);case f:e:{for(s=o.key;null!==r;){if(r.key===s){if(4===r.tag&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),(r=i(r,o.children||[])).return=e,e=r;break e}n(e,r);break}t(e,r),r=r.sibling}(r=fo(o,e.mode,l)).return=e,e=r}return u(e)}if("string"==typeof o||"number"==typeof o)return o=""+o,null!==r&&6===r.tag?(n(e,r.sibling),(r=i(r,o)).return=e,e=r):(n(e,r),(r=co(o,e.mode,l)).return=e,e=r),u(e);if(Zt(o))return y(e,r,o,l);if(S(o))return _(e,r,o,l);if(p&&tn(e,o),void 0===o&&!s)switch(e.tag){case 1:case 0:throw e=e.type,Error(a(152,e.displayName||e.name||"Component"))}return n(e,r)}}var rn=nn(!0),on=nn(!1),un={},an={current:un},ln={current:un},sn={current:un};function cn(e){if(e===un)throw Error(a(174));return e}function fn(e,t){Ie(sn,t),Ie(ln,e),Ie(an,un),t=P(t),Pe(an),Ie(an,t)}function dn(e){Pe(an),Pe(ln),Pe(sn)}function pn(e){var t=cn(sn.current),n=cn(an.current);n!==(t=I(n,e.type,t))&&(Ie(ln,e),Ie(an,t))}function hn(e){ln.current===e&&(Pe(an),Pe(ln))}var vn={current:0};function mn(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||ye(n)||_e(n)))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(0!=(64&t.effectTag))return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}function gn(e,t){return{responder:e,props:t}}var yn=l.ReactCurrentDispatcher,_n=l.ReactCurrentBatchConfig,bn=0,wn=null,En=null,Dn=null,Sn=null,Cn=null,kn=null,Tn=0,xn=null,An=0,On=!1,Pn=null,In=0;function Nn(){throw Error(a(321))}function Mn(e,t){if(null===t)return!1;for(var n=0;nTn&&zi(Tn=f)):(Ui(f,s.suspenseConfig),o=s.eagerReducer===e?s.eagerState:e(o,s.action)),u=s,s=s.next}while(null!==s&&s!==r);c||(l=u,i=o),_t(o,t.memoizedState)||(dr=!0),t.memoizedState=o,t.baseUpdate=l,t.baseState=i,n.lastRenderedState=o}return[t.memoizedState,n.dispatch]}function zn(e){var t=Ln();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e=(e=t.queue={last:null,dispatch:null,lastRenderedReducer:jn,lastRenderedState:e}).dispatch=Jn.bind(null,wn,e),[t.memoizedState,e]}function Wn(e){return Un(jn)}function Hn(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},null===xn?(xn={lastEffect:null}).lastEffect=e.next=e:null===(t=xn.lastEffect)?xn.lastEffect=e.next=e:(n=t.next,t.next=e,e.next=n,xn.lastEffect=e),e}function Vn(e,t,n,r){var i=Ln();An|=e,i.memoizedState=Hn(t,n,void 0,void 0===r?null:r)}function qn(e,t,n,r){var i=Bn();r=void 0===r?null:r;var o=void 0;if(null!==En){var u=En.memoizedState;if(o=u.destroy,null!==r&&Mn(r,u.deps))return void Hn(0,n,o,r)}An|=e,i.memoizedState=Hn(t,n,o,r)}function Gn(e,t){return Vn(516,192,e,t)}function $n(e,t){return qn(516,192,e,t)}function Yn(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function Kn(){}function Xn(e,t){return Ln().memoizedState=[e,void 0===t?null:t],e}function Qn(e,t){var n=Bn();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&Mn(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function Jn(e,t,n){if(!(25>In))throw Error(a(301));var r=e.alternate;if(e===wn||null!==r&&r===wn)if(On=!0,e={expirationTime:bn,suspenseConfig:null,action:n,eagerReducer:null,eagerState:null,next:null},null===Pn&&(Pn=new Map),void 0===(n=Pn.get(t)))Pn.set(t,e);else{for(t=n;null!==t.next;)t=t.next;t.next=e}else{var i=xi(),o=qt.suspense;o={expirationTime:i=Ai(i,e,o),suspenseConfig:o,action:n,eagerReducer:null,eagerState:null,next:null};var u=t.last;if(null===u)o.next=o;else{var l=u.next;null!==l&&(o.next=l),u.next=o}if(t.last=o,0===e.expirationTime&&(null===r||0===r.expirationTime)&&null!==(r=t.lastRenderedReducer))try{var s=t.lastRenderedState,c=r(s,n);if(o.eagerReducer=r,o.eagerState=c,_t(c,s))return}catch(e){}Oi(e,i)}}var Zn={readContext:It,useCallback:Nn,useContext:Nn,useEffect:Nn,useImperativeHandle:Nn,useLayoutEffect:Nn,useMemo:Nn,useReducer:Nn,useRef:Nn,useState:Nn,useDebugValue:Nn,useResponder:Nn,useDeferredValue:Nn,useTransition:Nn},er={readContext:It,useCallback:Xn,useContext:It,useEffect:Gn,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,Vn(4,36,Yn.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Vn(4,36,e,t)},useMemo:function(e,t){var n=Ln();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=Ln();return t=void 0!==n?n(t):t,r.memoizedState=r.baseState=t,e=(e=r.queue={last:null,dispatch:null,lastRenderedReducer:e,lastRenderedState:t}).dispatch=Jn.bind(null,wn,e),[r.memoizedState,e]},useRef:function(e){return e={current:e},Ln().memoizedState=e},useState:zn,useDebugValue:Kn,useResponder:gn,useDeferredValue:function(e,t){var n=zn(e),r=n[0],i=n[1];return Gn((function(){u.unstable_next((function(){var n=_n.suspense;_n.suspense=void 0===t?null:t;try{i(e)}finally{_n.suspense=n}}))}),[e,t]),r},useTransition:function(e){var t=zn(!1),n=t[0],r=t[1];return[Xn((function(t){r(!0),u.unstable_next((function(){var n=_n.suspense;_n.suspense=void 0===e?null:e;try{r(!1),t()}finally{_n.suspense=n}}))}),[e,n]),n]}},tr={readContext:It,useCallback:Qn,useContext:It,useEffect:$n,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,qn(4,36,Yn.bind(null,t,e),n)},useLayoutEffect:function(e,t){return qn(4,36,e,t)},useMemo:function(e,t){var n=Bn();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&Mn(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)},useReducer:Un,useRef:function(){return Bn().memoizedState},useState:Wn,useDebugValue:Kn,useResponder:gn,useDeferredValue:function(e,t){var n=Wn(),r=n[0],i=n[1];return $n((function(){u.unstable_next((function(){var n=_n.suspense;_n.suspense=void 0===t?null:t;try{i(e)}finally{_n.suspense=n}}))}),[e,t]),r},useTransition:function(e){var t=Wn(),n=t[0],r=t[1];return[Qn((function(t){r(!0),u.unstable_next((function(){var n=_n.suspense;_n.suspense=void 0===e?null:e;try{r(!1),t()}finally{_n.suspense=n}}))}),[e,n]),n]}},nr=null,rr=null,ir=!1;function or(e,t){var n=oo(5,null,null,0);n.elementType="DELETED",n.type="DELETED",n.stateNode=t,n.return=e,n.effectTag=8,null!==e.lastEffect?(e.lastEffect.nextEffect=n,e.lastEffect=n):e.firstEffect=e.lastEffect=n}function ur(e,t){switch(e.tag){case 5:return null!==(t=me(t,e.type,e.pendingProps))&&(e.stateNode=t,!0);case 6:return null!==(t=ge(t,e.pendingProps))&&(e.stateNode=t,!0);case 13:default:return!1}}function ar(e){if(ir){var t=rr;if(t){var n=t;if(!ur(e,t)){if(!(t=be(n))||!ur(e,t))return e.effectTag=-1025&e.effectTag|2,ir=!1,void(nr=e);or(nr,n)}nr=e,rr=we(t)}else e.effectTag=-1025&e.effectTag|2,ir=!1,nr=e}}function lr(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;nr=e}function sr(e){if(!Y||e!==nr)return!1;if(!ir)return lr(e),ir=!0,!1;var t=e.type;if(5!==e.tag||"head"!==t&&"body"!==t&&!j(t,e.memoizedProps))for(t=rr;t;)or(e,t),t=be(t);if(lr(e),13===e.tag){if(!Y)throw Error(a(316));if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(a(317));rr=Se(e)}else rr=nr?be(e.stateNode):null;return!0}function cr(){Y&&(rr=nr=null,ir=!1)}var fr=l.ReactCurrentOwner,dr=!1;function pr(e,t,n,r){t.child=null===e?on(t,null,n,r):rn(t,e.child,n,r)}function hr(e,t,n,r,i){n=n.render;var o=t.ref;return Pt(t,i),r=Rn(e,t,n,r,o,i),null===e||dr?(t.effectTag|=1,pr(e,t,r,i),t.child):(t.updateQueue=e.updateQueue,t.effectTag&=-517,e.expirationTime<=i&&(e.expirationTime=0),Pr(e,t,i))}function vr(e,t,n,r,i,o){if(null===e){var u=n.type;return"function"!=typeof u||uo(u)||void 0!==u.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=lo(n.type,null,r,null,t.mode,o)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=u,mr(e,t,u,r,i,o))}return u=e.child,it)&&Si.set(e,t))}}function Pi(e,t){e.expirationTime(e=e.nextKnownPendingLevel)?t:e:t}function Ni(e){if(0!==e.lastExpiredTime)e.callbackExpirationTime=1073741823,e.callbackPriority=99,e.callbackNode=ht(Ri.bind(null,e));else{var t=Ii(e),n=e.callbackNode;if(0===t)null!==n&&(e.callbackNode=null,e.callbackExpirationTime=0,e.callbackPriority=90);else{var r=xi();if(1073741823===t?r=99:1===t||2===t?r=95:r=0>=(r=10*(1073741821-t)-10*(1073741821-r))?99:250>=r?98:5250>=r?97:95,null!==n){var i=e.callbackPriority;if(e.callbackExpirationTime===t&&i>=r)return;n!==rt&&$e(n)}e.callbackExpirationTime=t,e.callbackPriority=r,t=1073741823===t?ht(Ri.bind(null,e)):pt(r,Mi.bind(null,e),{timeout:10*(1073741821-t)-st()}),e.callbackNode=t}}}function Mi(e,t){if(Ti=0,t)return go(e,t=xi()),Ni(e),null;var n=Ii(e);if(0!==n){if(t=e.callbackNode,0!=(48&oi))throw Error(a(327));if(Xi(),e===ui&&n===li||Li(e,n),null!==ai){var r=oi;oi|=ii;for(var i=ji();;)try{Hi();break}catch(t){Bi(e,t)}if(Tt(),oi=r,ni.current=i,1===si)throw t=ci,Li(e,n),vo(e,n),Ni(e),t;if(null===ai)switch(i=e.finishedWork=e.current.alternate,e.finishedExpirationTime=n,r=si,ui=null,r){case 0:case 1:throw Error(a(345));case 2:go(e,2=n){e.lastPingedTime=n,Li(e,n);break}}if(0!==(o=Ii(e))&&o!==n)break;if(0!==r&&r!==n){e.lastPingedTime=r;break}e.timeoutHandle=W($i.bind(null,e),i);break}$i(e);break;case 4:if(vo(e,n),n===(r=e.lastSuspendedTime)&&(e.nextKnownPendingLevel=Gi(i)),vi&&(0===(i=e.lastPingedTime)||i>=n)){e.lastPingedTime=n,Li(e,n);break}if(0!==(i=Ii(e))&&i!==n)break;if(0!==r&&r!==n){e.lastPingedTime=r;break}if(1073741823!==di?r=10*(1073741821-di)-st():1073741823===fi?r=0:(r=10*(1073741821-fi)-5e3,0>(r=(i=st())-r)&&(r=0),(n=10*(1073741821-n)-i)<(r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*ti(r/1960))-r)&&(r=n)),10=(r=0|u.busyMinDurationMs)?r=0:(i=0|u.busyDelayMs,r=(o=st()-(10*(1073741821-o)-(0|u.timeoutMs||5e3)))<=i?0:i+r-o),10 component higher in the tree to provide a loading indicator or placeholder to display."+xe(i))}5!==si&&(si=2),o=Fr(o,i),l=r;do{switch(l.tag){case 3:u=o,l.effectTag|=4096,l.expirationTime=t,jt(l,Jr(l,u,t));break e;case 1:u=o;var g=l.type,y=l.stateNode;if(0==(64&l.effectTag)&&("function"==typeof g.getDerivedStateFromError||null!==y&&"function"==typeof y.componentDidCatch&&(null===bi||!bi.has(y)))){l.effectTag|=4096,l.expirationTime=t,jt(l,Zr(l,u,t));break e}}l=l.return}while(null!==l)}ai=qi(ai)}catch(e){t=e;continue}break}}function ji(){var e=ni.current;return ni.current=Zn,null===e?Zn:e}function Ui(e,t){ehi&&(hi=e)}function Wi(){for(;null!==ai;)ai=Vi(ai)}function Hi(){for(;null!==ai&&!Ye();)ai=Vi(ai)}function Vi(e){var t=ei(e.alternate,e,li);return e.memoizedProps=e.pendingProps,null===t&&(t=qi(e)),ri.current=null,t}function qi(e){ai=e;do{var t=ai.alternate;if(e=ai.return,0==(2048&ai.effectTag)){e:{var n=t,r=li,i=(t=ai).pendingProps;switch(t.tag){case 2:case 16:break;case 15:case 0:break;case 1:Be(t.type)&&je();break;case 3:dn(),Ue(),(i=t.stateNode).pendingContext&&(i.context=i.pendingContext,i.pendingContext=null),(null===n||null===n.child)&&sr(t)&&Ir(t),Dr(t);break;case 5:hn(t);var o=cn(sn.current);if(r=t.type,null!==n&&null!=t.stateNode)Sr(n,t,r,i,o),n.ref!==t.ref&&(t.effectTag|=128);else if(i){if(n=cn(an.current),sr(t)){if(i=t,!Y)throw Error(a(175));n=Ee(i.stateNode,i.type,i.memoizedProps,o,n,i),i.updateQueue=n,(n=null!==n)&&Ir(t)}else{var u=R(r,i,o,n,t);Er(u,t,!1,!1),t.stateNode=u,L(u,r,i,o,n)&&Ir(t)}null!==t.ref&&(t.effectTag|=128)}else if(null===t.stateNode)throw Error(a(166));break;case 6:if(n&&null!=t.stateNode)Cr(n,t,n.memoizedProps,i);else{if("string"!=typeof i&&null===t.stateNode)throw Error(a(166));if(n=cn(sn.current),o=cn(an.current),sr(t)){if(n=t,!Y)throw Error(a(176));(n=De(n.stateNode,n.memoizedProps,n))&&Ir(t)}else t.stateNode=z(i,n,o,t)}break;case 11:break;case 13:if(Pe(vn),i=t.memoizedState,0!=(64&t.effectTag)){t.expirationTime=r;break e}i=null!==i,o=!1,null===n?void 0!==t.memoizedProps.fallback&&sr(t):(o=null!==(r=n.memoizedState),i||null===r||null!==(r=n.child.sibling)&&(null!==(u=t.firstEffect)?(t.firstEffect=r,r.nextEffect=u):(t.firstEffect=t.lastEffect=r,r.nextEffect=null),r.effectTag=8)),i&&!o&&0!=(2&t.mode)&&(null===n&&!0!==t.memoizedProps.unstable_avoidThisFallback||0!=(1&vn.current)?0===si&&(si=3):(0!==si&&3!==si||(si=4),0!==hi&&null!==ui&&(vo(ui,li),mo(ui,hi)))),$&&i&&(t.effectTag|=4),G&&(i||o)&&(t.effectTag|=4);break;case 7:case 8:case 12:break;case 4:dn(),Dr(t);break;case 10:At(t);break;case 9:case 14:break;case 17:Be(t.type)&&je();break;case 19:if(Pe(vn),null===(i=t.memoizedState))break;if(o=0!=(64&t.effectTag),null===(u=i.rendering)){if(o)Mr(i,!1);else if(0!==si||null!==n&&0!=(64&n.effectTag))for(n=t.child;null!==n;){if(null!==(u=mn(n))){for(t.effectTag|=64,Mr(i,!1),null!==(n=u.updateQueue)&&(t.updateQueue=n,t.effectTag|=4),null===i.lastEffect&&(t.firstEffect=null),t.lastEffect=i.lastEffect,n=r,i=t.child;null!==i;)r=n,(o=i).effectTag&=2,o.nextEffect=null,o.firstEffect=null,o.lastEffect=null,null===(u=o.alternate)?(o.childExpirationTime=0,o.expirationTime=r,o.child=null,o.memoizedProps=null,o.memoizedState=null,o.updateQueue=null,o.dependencies=null):(o.childExpirationTime=u.childExpirationTime,o.expirationTime=u.expirationTime,o.child=u.child,o.memoizedProps=u.memoizedProps,o.memoizedState=u.memoizedState,o.updateQueue=u.updateQueue,r=u.dependencies,o.dependencies=null===r?null:{expirationTime:r.expirationTime,firstContext:r.firstContext,responders:r.responders}),i=i.sibling;Ie(vn,1&vn.current|2),t=t.child;break e}n=n.sibling}}else{if(!o)if(null!==(n=mn(u))){if(t.effectTag|=64,o=!0,null!==(n=n.updateQueue)&&(t.updateQueue=n,t.effectTag|=4),Mr(i,!0),null===i.tail&&"hidden"===i.tailMode&&!u.alternate){null!==(t=t.lastEffect=i.lastEffect)&&(t.nextEffect=null);break}}else st()>i.tailExpiration&&1i&&(i=r),(u=o.childExpirationTime)>i&&(i=u),o=o.sibling;n.childExpirationTime=i}if(null!==t)return t;null!==e&&0==(2048&e.effectTag)&&(null===e.firstEffect&&(e.firstEffect=ai.firstEffect),null!==ai.lastEffect&&(null!==e.lastEffect&&(e.lastEffect.nextEffect=ai.firstEffect),e.lastEffect=ai.lastEffect),1(e=e.childExpirationTime)?t:e}function $i(e){var t=ct();return dt(99,Yi.bind(null,e,t)),null}function Yi(e,t){do{Xi()}while(null!==Ei);if(0!=(48&oi))throw Error(a(327));var n=e.finishedWork,r=e.finishedExpirationTime;if(null===n)return null;if(e.finishedWork=null,e.finishedExpirationTime=0,n===e.current)throw Error(a(177));e.callbackNode=null,e.callbackExpirationTime=0,e.callbackPriority=90,e.nextKnownPendingLevel=0;var i=Gi(n);if(e.firstPendingTime=i,r<=e.lastSuspendedTime?e.firstSuspendedTime=e.lastSuspendedTime=e.nextKnownPendingLevel=0:r<=e.firstSuspendedTime&&(e.firstSuspendedTime=r-1),r<=e.lastPingedTime&&(e.lastPingedTime=0),r<=e.lastExpiredTime&&(e.lastExpiredTime=0),e===ui&&(ai=ui=null,li=0),1=n?Tr(e,t,n):(Ie(vn,1&vn.current),null!==(t=Pr(e,t,n))?t.sibling:null);Ie(vn,1&vn.current);break;case 19:if(r=t.childExpirationTime>=n,0!=(64&e.effectTag)){if(r)return Or(e,t,n);t.effectTag|=64}if(null!==(i=t.memoizedState)&&(i.rendering=null,i.tail=null),Ie(vn,vn.current),!r)return null}return Pr(e,t,n)}dr=!1}}else dr=!1;switch(t.expirationTime=0,t.tag){case 2:if(r=t.type,null!==e&&(e.alternate=null,t.alternate=null,t.effectTag|=2),e=t.pendingProps,i=Le(t,Me.current),Pt(t,n),i=Rn(null,t,r,e,i,n),t.effectTag|=1,"object"==typeof i&&null!==i&&"function"==typeof i.render&&void 0===i.$$typeof){if(t.tag=1,Fn(),Be(r)){var o=!0;He(t)}else o=!1;t.memoizedState=null!==i.state&&void 0!==i.state?i.state:null;var u=r.getDerivedStateFromProps;"function"==typeof u&&$t(t,r,u,e),i.updater=Yt,t.stateNode=i,i._reactInternalFiber=t,Jt(t,r,e,n),t=br(null,t,r,!0,o,n)}else t.tag=0,pr(null,t,i,n),t=t.child;return t;case 16:if(i=t.elementType,null!==e&&(e.alternate=null,t.alternate=null,t.effectTag|=2),e=t.pendingProps,function(e){if(-1===e._status){e._status=0;var t=e._ctor;t=t(),e._result=t,t.then((function(t){0===e._status&&(t=t.default,e._status=1,e._result=t)}),(function(t){0===e._status&&(e._status=2,e._result=t)}))}}(i),1!==i._status)throw i._result;switch(i=i._result,t.type=i,o=t.tag=function(e){if("function"==typeof e)return uo(e)?1:0;if(null!=e){if((e=e.$$typeof)===y)return 11;if(e===w)return 14}return 2}(i),e=Et(i,e),o){case 0:t=yr(null,t,i,e,n);break;case 1:t=_r(null,t,i,e,n);break;case 11:t=hr(null,t,i,e,n);break;case 14:t=vr(null,t,i,Et(i.type,e),r,n);break;default:throw Error(a(306,i,""))}return t;case 0:return r=t.type,i=t.pendingProps,yr(e,t,r,i=t.elementType===r?i:Et(r,i),n);case 1:return r=t.type,i=t.pendingProps,_r(e,t,r,i=t.elementType===r?i:Et(r,i),n);case 3:if(wr(t),null===(r=t.updateQueue))throw Error(a(282));if(i=null!==(i=t.memoizedState)?i.element:null,Wt(t,r,t.pendingProps,null,n),(r=t.memoizedState.element)===i)cr(),t=Pr(e,t,n);else{if((i=t.stateNode.hydrate)&&(Y?(rr=we(t.stateNode.containerInfo),nr=t,i=ir=!0):i=!1),i)for(n=on(t,null,r,n),t.child=n;n;)n.effectTag=-3&n.effectTag|1024,n=n.sibling;else pr(e,t,r,n),cr();t=t.child}return t;case 5:return pn(t),null===e&&ar(t),r=t.type,i=t.pendingProps,o=null!==e?e.memoizedProps:null,u=i.children,j(r,i)?u=null:null!==o&&j(r,o)&&(t.effectTag|=16),gr(e,t),4&t.mode&&1!==n&&U(r,i)?(t.expirationTime=t.childExpirationTime=1,t=null):(pr(e,t,u,n),t=t.child),t;case 6:return null===e&&ar(t),null;case 13:return Tr(e,t,n);case 4:return fn(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=rn(t,null,r,n):pr(e,t,r,n),t.child;case 11:return r=t.type,i=t.pendingProps,hr(e,t,r,i=t.elementType===r?i:Et(r,i),n);case 7:return pr(e,t,t.pendingProps,n),t.child;case 8:case 12:return pr(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,i=t.pendingProps,u=t.memoizedProps,xt(t,o=i.value),null!==u){var l=u.value;if(0===(o=_t(l,o)?0:0|("function"==typeof r._calculateChangedBits?r._calculateChangedBits(l,o):1073741823))){if(u.children===i.children&&!Re.current){t=Pr(e,t,n);break e}}else for(null!==(l=t.child)&&(l.return=t);null!==l;){var s=l.dependencies;if(null!==s){u=l.child;for(var c=s.firstContext;null!==c;){if(c.context===r&&0!=(c.observedBits&o)){1===l.tag&&((c=Ft(n,null)).tag=2,Bt(l,c)),l.expirationTime=t&&e<=t}function vo(e,t){var n=e.firstSuspendedTime,r=e.lastSuspendedTime;nt||0===n)&&(e.lastSuspendedTime=t),t<=e.lastPingedTime&&(e.lastPingedTime=0),t<=e.lastExpiredTime&&(e.lastExpiredTime=0)}function mo(e,t){t>e.firstPendingTime&&(e.firstPendingTime=t);var n=e.firstSuspendedTime;0!==n&&(t>=n?e.firstSuspendedTime=e.lastSuspendedTime=e.nextKnownPendingLevel=0:t>=e.lastSuspendedTime&&(e.lastSuspendedTime=t+1),t>e.nextKnownPendingLevel&&(e.nextKnownPendingLevel=t))}function go(e,t){var n=e.lastExpiredTime;(0===n||n>t)&&(e.lastExpiredTime=t)}function yo(e){var t=e._reactInternalFiber;if(void 0===t){if("function"==typeof e.render)throw Error(a(188));throw Error(a(268,Object.keys(e)))}return null===(e=A(t))?null:e.stateNode}function _o(e,t){null!==(e=e.memoizedState)&&null!==e.dehydrated&&e.retryTime{"use strict";e.exports=n(5767)},3296:(e,t,n)=>{"use strict";const r=n(5760);r.createWebSocketStream=n(6387),r.Server=n(43),r.Receiver=n(1762),r.Sender=n(9576),e.exports=r},8716:(e,t,n)=>{"use strict";const{EMPTY_BUFFER:r}=n(5739);function i(e,t){if(0===e.length)return r;if(1===e.length)return e[0];const n=Buffer.allocUnsafe(t);let i=0;for(let t=0;t{"use strict";e.exports={BINARY_TYPES:["nodebuffer","arraybuffer","fragments"],GUID:"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",kStatusCode:Symbol("status-code"),kWebSocket:Symbol("websocket"),EMPTY_BUFFER:Buffer.alloc(0),NOOP:()=>{}}},7002:e=>{"use strict";class t{constructor(e,t){this.target=t,this.type=e}}class n extends t{constructor(e,t){super("message",t),this.data=e}}class r extends t{constructor(e,t,n){super("close",n),this.wasClean=n._closeFrameReceived&&n._closeFrameSent,this.reason=t,this.code=e}}class i extends t{constructor(e){super("open",e)}}class o extends t{constructor(e,t){super("error",t),this.message=e.message,this.error=e}}const u={addEventListener(e,t,u){if("function"!=typeof t)return;function a(e){t.call(this,new n(e,this))}function l(e,n){t.call(this,new r(e,n,this))}function s(e){t.call(this,new o(e,this))}function c(){t.call(this,new i(this))}const f=u&&u.once?"once":"on";"message"===e?(a._listener=t,this[f](e,a)):"close"===e?(l._listener=t,this[f](e,l)):"error"===e?(s._listener=t,this[f](e,s)):"open"===e?(c._listener=t,this[f](e,c)):this[f](e,t)},removeEventListener(e,t){const n=this.listeners(e);for(let r=0;r{"use strict";const t=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0];function n(e,t,n){void 0===e[t]?e[t]=[n]:e[t].push(n)}e.exports={format:function(e){return Object.keys(e).map(t=>{let n=e[t];return Array.isArray(n)||(n=[n]),n.map(e=>[t].concat(Object.keys(e).map(t=>{let n=e[t];return Array.isArray(n)||(n=[n]),n.map(e=>!0===e?t:`${t}=${e}`).join("; ")})).join("; ")).join(", ")}).join(", ")},parse:function(e){const r=Object.create(null);if(void 0===e||""===e)return r;let i,o,u=Object.create(null),a=!1,l=!1,s=!1,c=-1,f=-1,d=0;for(;d{"use strict";const t=Symbol("kDone"),n=Symbol("kRun");e.exports=class{constructor(e){this[t]=()=>{this.pending--,this[n]()},this.concurrency=e||1/0,this.jobs=[],this.pending=0}add(e){this.jobs.push(e),this[n]()}[n](){if(this.pending!==this.concurrency&&this.jobs.length){const e=this.jobs.shift();this.pending++,e(this[t])}}}},2309:(e,t,n)=>{"use strict";const r=n(8761),i=n(8716),o=n(1390),{kStatusCode:u,NOOP:a}=n(5739),l=Buffer.from([0,0,255,255]),s=Symbol("permessage-deflate"),c=Symbol("total-length"),f=Symbol("callback"),d=Symbol("buffers"),p=Symbol("error");let h;function v(e){this[d].push(e),this[c]+=e.length}function m(e){this[c]+=e.length,this[s]._maxPayload<1||this[c]<=this[s]._maxPayload?this[d].push(e):(this[p]=new RangeError("Max payload size exceeded"),this[p][u]=1009,this.removeListener("data",m),this.reset())}function g(e){this[s]._inflate=null,e[u]=1007,this[f](e)}e.exports=class{constructor(e,t,n){if(this._maxPayload=0|n,this._options=e||{},this._threshold=void 0!==this._options.threshold?this._options.threshold:1024,this._isServer=!!t,this._deflate=null,this._inflate=null,this.params=null,!h){const e=void 0!==this._options.concurrencyLimit?this._options.concurrencyLimit:10;h=new o(e)}}static get extensionName(){return"permessage-deflate"}offer(){const e={};return this._options.serverNoContextTakeover&&(e.server_no_context_takeover=!0),this._options.clientNoContextTakeover&&(e.client_no_context_takeover=!0),this._options.serverMaxWindowBits&&(e.server_max_window_bits=this._options.serverMaxWindowBits),this._options.clientMaxWindowBits?e.client_max_window_bits=this._options.clientMaxWindowBits:null==this._options.clientMaxWindowBits&&(e.client_max_window_bits=!0),e}accept(e){return e=this.normalizeParams(e),this.params=this._isServer?this.acceptAsServer(e):this.acceptAsClient(e),this.params}cleanup(){if(this._inflate&&(this._inflate.close(),this._inflate=null),this._deflate){const e=this._deflate[f];this._deflate.close(),this._deflate=null,e&&e(new Error("The deflate stream was closed while data was being processed"))}}acceptAsServer(e){const t=this._options,n=e.find(e=>!(!1===t.serverNoContextTakeover&&e.server_no_context_takeover||e.server_max_window_bits&&(!1===t.serverMaxWindowBits||"number"==typeof t.serverMaxWindowBits&&t.serverMaxWindowBits>e.server_max_window_bits)||"number"==typeof t.clientMaxWindowBits&&!e.client_max_window_bits));if(!n)throw new Error("None of the extension offers can be accepted");return t.serverNoContextTakeover&&(n.server_no_context_takeover=!0),t.clientNoContextTakeover&&(n.client_no_context_takeover=!0),"number"==typeof t.serverMaxWindowBits&&(n.server_max_window_bits=t.serverMaxWindowBits),"number"==typeof t.clientMaxWindowBits?n.client_max_window_bits=t.clientMaxWindowBits:!0!==n.client_max_window_bits&&!1!==t.clientMaxWindowBits||delete n.client_max_window_bits,n}acceptAsClient(e){const t=e[0];if(!1===this._options.clientNoContextTakeover&&t.client_no_context_takeover)throw new Error('Unexpected parameter "client_no_context_takeover"');if(t.client_max_window_bits){if(!1===this._options.clientMaxWindowBits||"number"==typeof this._options.clientMaxWindowBits&&t.client_max_window_bits>this._options.clientMaxWindowBits)throw new Error('Unexpected or invalid parameter "client_max_window_bits"')}else"number"==typeof this._options.clientMaxWindowBits&&(t.client_max_window_bits=this._options.clientMaxWindowBits);return t}normalizeParams(e){return e.forEach(e=>{Object.keys(e).forEach(t=>{let n=e[t];if(n.length>1)throw new Error(`Parameter "${t}" must have only a single value`);if(n=n[0],"client_max_window_bits"===t){if(!0!==n){const e=+n;if(!Number.isInteger(e)||e<8||e>15)throw new TypeError(`Invalid value for parameter "${t}": ${n}`);n=e}else if(!this._isServer)throw new TypeError(`Invalid value for parameter "${t}": ${n}`)}else if("server_max_window_bits"===t){const e=+n;if(!Number.isInteger(e)||e<8||e>15)throw new TypeError(`Invalid value for parameter "${t}": ${n}`);n=e}else{if("client_no_context_takeover"!==t&&"server_no_context_takeover"!==t)throw new Error(`Unknown parameter "${t}"`);if(!0!==n)throw new TypeError(`Invalid value for parameter "${t}": ${n}`)}e[t]=n})}),e}decompress(e,t,n){h.add(r=>{this._decompress(e,t,(e,t)=>{r(),n(e,t)})})}compress(e,t,n){h.add(r=>{this._compress(e,t,(e,t)=>{r(),n(e,t)})})}_decompress(e,t,n){const o=this._isServer?"client":"server";if(!this._inflate){const e=o+"_max_window_bits",t="number"!=typeof this.params[e]?r.Z_DEFAULT_WINDOWBITS:this.params[e];this._inflate=r.createInflateRaw({...this._options.zlibInflateOptions,windowBits:t}),this._inflate[s]=this,this._inflate[c]=0,this._inflate[d]=[],this._inflate.on("error",g),this._inflate.on("data",m)}this._inflate[f]=n,this._inflate.write(e),t&&this._inflate.write(l),this._inflate.flush(()=>{const e=this._inflate[p];if(e)return this._inflate.close(),this._inflate=null,void n(e);const r=i.concat(this._inflate[d],this._inflate[c]);t&&this.params[o+"_no_context_takeover"]?(this._inflate.close(),this._inflate=null):(this._inflate[c]=0,this._inflate[d]=[]),n(null,r)})}_compress(e,t,n){const o=this._isServer?"server":"client";if(!this._deflate){const e=o+"_max_window_bits",t="number"!=typeof this.params[e]?r.Z_DEFAULT_WINDOWBITS:this.params[e];this._deflate=r.createDeflateRaw({...this._options.zlibDeflateOptions,windowBits:t}),this._deflate[c]=0,this._deflate[d]=[],this._deflate.on("error",a),this._deflate.on("data",v)}this._deflate[f]=n,this._deflate.write(e),this._deflate.flush(r.Z_SYNC_FLUSH,()=>{if(!this._deflate)return;let e=i.concat(this._deflate[d],this._deflate[c]);t&&(e=e.slice(0,e.length-4)),this._deflate[f]=null,t&&this.params[o+"_no_context_takeover"]?(this._deflate.close(),this._deflate=null):(this._deflate[c]=0,this._deflate[d]=[]),n(null,e)})}}},1762:(e,t,n)=>{"use strict";const{Writable:r}=n(2413),i=n(2309),{BINARY_TYPES:o,EMPTY_BUFFER:u,kStatusCode:a,kWebSocket:l}=n(5739),{concat:s,toArrayBuffer:c,unmask:f}=n(8716),{isValidStatusCode:d,isValidUTF8:p}=n(9498);function h(e,t,n,r){const i=new e(n?"Invalid WebSocket frame: "+t:t);return Error.captureStackTrace(i,h),i[a]=r,i}e.exports=class extends r{constructor(e,t,n,r){super(),this._binaryType=e||o[0],this[l]=void 0,this._extensions=t||{},this._isServer=!!n,this._maxPayload=0|r,this._bufferedBytes=0,this._buffers=[],this._compressed=!1,this._payloadLength=0,this._mask=void 0,this._fragmented=0,this._masked=!1,this._fin=!1,this._opcode=0,this._totalPayloadLength=0,this._messageLength=0,this._fragments=[],this._state=0,this._loop=!1}_write(e,t,n){if(8===this._opcode&&0==this._state)return n();this._bufferedBytes+=e.length,this._buffers.push(e),this.startLoop(n)}consume(e){if(this._bufferedBytes-=e,e===this._buffers[0].length)return this._buffers.shift();if(e=n.length?t.set(this._buffers.shift(),r):(t.set(new Uint8Array(n.buffer,n.byteOffset,e),r),this._buffers[0]=n.slice(e)),e-=n.length}while(e>0);return t}startLoop(e){let t;this._loop=!0;do{switch(this._state){case 0:t=this.getInfo();break;case 1:t=this.getPayloadLength16();break;case 2:t=this.getPayloadLength64();break;case 3:this.getMask();break;case 4:t=this.getData(e);break;default:return void(this._loop=!1)}}while(this._loop);e(t)}getInfo(){if(this._bufferedBytes<2)return void(this._loop=!1);const e=this.consume(2);if(0!=(48&e[0]))return this._loop=!1,h(RangeError,"RSV2 and RSV3 must be clear",!0,1002);const t=64==(64&e[0]);if(t&&!this._extensions[i.extensionName])return this._loop=!1,h(RangeError,"RSV1 must be clear",!0,1002);if(this._fin=128==(128&e[0]),this._opcode=15&e[0],this._payloadLength=127&e[1],0===this._opcode){if(t)return this._loop=!1,h(RangeError,"RSV1 must be clear",!0,1002);if(!this._fragmented)return this._loop=!1,h(RangeError,"invalid opcode 0",!0,1002);this._opcode=this._fragmented}else if(1===this._opcode||2===this._opcode){if(this._fragmented)return this._loop=!1,h(RangeError,"invalid opcode "+this._opcode,!0,1002);this._compressed=t}else{if(!(this._opcode>7&&this._opcode<11))return this._loop=!1,h(RangeError,"invalid opcode "+this._opcode,!0,1002);if(!this._fin)return this._loop=!1,h(RangeError,"FIN must be set",!0,1002);if(t)return this._loop=!1,h(RangeError,"RSV1 must be clear",!0,1002);if(this._payloadLength>125)return this._loop=!1,h(RangeError,"invalid payload length "+this._payloadLength,!0,1002)}if(this._fin||this._fragmented||(this._fragmented=this._opcode),this._masked=128==(128&e[1]),this._isServer){if(!this._masked)return this._loop=!1,h(RangeError,"MASK must be set",!0,1002)}else if(this._masked)return this._loop=!1,h(RangeError,"MASK must be clear",!0,1002);if(126===this._payloadLength)this._state=1;else{if(127!==this._payloadLength)return this.haveLength();this._state=2}}getPayloadLength16(){if(!(this._bufferedBytes<2))return this._payloadLength=this.consume(2).readUInt16BE(0),this.haveLength();this._loop=!1}getPayloadLength64(){if(this._bufferedBytes<8)return void(this._loop=!1);const e=this.consume(8),t=e.readUInt32BE(0);return t>Math.pow(2,21)-1?(this._loop=!1,h(RangeError,"Unsupported WebSocket frame: payload length > 2^53 - 1",!1,1009)):(this._payloadLength=t*Math.pow(2,32)+e.readUInt32BE(4),this.haveLength())}haveLength(){if(this._payloadLength&&this._opcode<8&&(this._totalPayloadLength+=this._payloadLength,this._totalPayloadLength>this._maxPayload&&this._maxPayload>0))return this._loop=!1,h(RangeError,"Max payload size exceeded",!1,1009);this._masked?this._state=3:this._state=4}getMask(){this._bufferedBytes<4?this._loop=!1:(this._mask=this.consume(4),this._state=4)}getData(e){let t=u;if(this._payloadLength){if(this._bufferedBytes7?this.controlMessage(t):this._compressed?(this._state=5,void this.decompress(t,e)):(t.length&&(this._messageLength=this._totalPayloadLength,this._fragments.push(t)),this.dataMessage())}decompress(e,t){this._extensions[i.extensionName].decompress(e,this._fin,(e,n)=>{if(e)return t(e);if(n.length){if(this._messageLength+=n.length,this._messageLength>this._maxPayload&&this._maxPayload>0)return t(h(RangeError,"Max payload size exceeded",!1,1009));this._fragments.push(n)}const r=this.dataMessage();if(r)return t(r);this.startLoop(t)})}dataMessage(){if(this._fin){const e=this._messageLength,t=this._fragments;if(this._totalPayloadLength=0,this._messageLength=0,this._fragmented=0,this._fragments=[],2===this._opcode){let n;n="nodebuffer"===this._binaryType?s(t,e):"arraybuffer"===this._binaryType?c(s(t,e)):t,this.emit("message",n)}else{const n=s(t,e);if(!p(n))return this._loop=!1,h(Error,"invalid UTF-8 sequence",!0,1007);this.emit("message",n.toString())}}this._state=0}controlMessage(e){if(8===this._opcode)if(this._loop=!1,0===e.length)this.emit("conclude",1005,""),this.end();else{if(1===e.length)return h(RangeError,"invalid payload length 1",!0,1002);{const t=e.readUInt16BE(0);if(!d(t))return h(RangeError,"invalid status code "+t,!0,1002);const n=e.slice(2);if(!p(n))return h(Error,"invalid UTF-8 sequence",!0,1007);this.emit("conclude",t,n.toString()),this.end()}}else 9===this._opcode?this.emit("ping",e):this.emit("pong",e);this._state=0}}},9576:(e,t,n)=>{"use strict";const{randomFillSync:r}=n(6417),i=n(2309),{EMPTY_BUFFER:o}=n(5739),{isValidStatusCode:u}=n(9498),{mask:a,toBuffer:l}=n(8716),s=Buffer.alloc(4);class c{constructor(e,t){this._extensions=t||{},this._socket=e,this._firstFragment=!0,this._compress=!1,this._bufferedBytes=0,this._deflating=!1,this._queue=[]}static frame(e,t){const n=t.mask&&t.readOnly;let i=t.mask?6:2,o=e.length;e.length>=65536?(i+=8,o=127):e.length>125&&(i+=2,o=126);const u=Buffer.allocUnsafe(n?e.length+i:i);return u[0]=t.fin?128|t.opcode:t.opcode,t.rsv1&&(u[0]|=64),u[1]=o,126===o?u.writeUInt16BE(e.length,2):127===o&&(u.writeUInt32BE(0,2),u.writeUInt32BE(e.length,6)),t.mask?(r(s,0,4),u[1]|=128,u[i-4]=s[0],u[i-3]=s[1],u[i-2]=s[2],u[i-1]=s[3],n?(a(e,s,u,i,e.length),[u]):(a(e,s,e,0,e.length),[u,e])):[u,e]}close(e,t,n,r){let i;if(void 0===e)i=o;else{if("number"!=typeof e||!u(e))throw new TypeError("First argument must be a valid error code number");if(void 0===t||""===t)i=Buffer.allocUnsafe(2),i.writeUInt16BE(e,0);else{const n=Buffer.byteLength(t);if(n>123)throw new RangeError("The message must not be greater than 123 bytes");i=Buffer.allocUnsafe(2+n),i.writeUInt16BE(e,0),i.write(t,2)}}this._deflating?this.enqueue([this.doClose,i,n,r]):this.doClose(i,n,r)}doClose(e,t,n){this.sendFrame(c.frame(e,{fin:!0,rsv1:!1,opcode:8,mask:t,readOnly:!1}),n)}ping(e,t,n){const r=l(e);if(r.length>125)throw new RangeError("The data size must not be greater than 125 bytes");this._deflating?this.enqueue([this.doPing,r,t,l.readOnly,n]):this.doPing(r,t,l.readOnly,n)}doPing(e,t,n,r){this.sendFrame(c.frame(e,{fin:!0,rsv1:!1,opcode:9,mask:t,readOnly:n}),r)}pong(e,t,n){const r=l(e);if(r.length>125)throw new RangeError("The data size must not be greater than 125 bytes");this._deflating?this.enqueue([this.doPong,r,t,l.readOnly,n]):this.doPong(r,t,l.readOnly,n)}doPong(e,t,n,r){this.sendFrame(c.frame(e,{fin:!0,rsv1:!1,opcode:10,mask:t,readOnly:n}),r)}send(e,t,n){const r=l(e),o=this._extensions[i.extensionName];let u=t.binary?2:1,a=t.compress;if(this._firstFragment?(this._firstFragment=!1,a&&o&&(a=r.length>=o._threshold),this._compress=a):(a=!1,u=0),t.fin&&(this._firstFragment=!0),o){const e={fin:t.fin,rsv1:a,opcode:u,mask:t.mask,readOnly:l.readOnly};this._deflating?this.enqueue([this.dispatch,r,this._compress,e,n]):this.dispatch(r,this._compress,e,n)}else this.sendFrame(c.frame(r,{fin:t.fin,rsv1:!1,opcode:u,mask:t.mask,readOnly:l.readOnly}),n)}dispatch(e,t,n,r){if(!t)return void this.sendFrame(c.frame(e,n),r);const o=this._extensions[i.extensionName];this._bufferedBytes+=e.length,this._deflating=!0,o.compress(e,n.fin,(t,i)=>{if(this._socket.destroyed){const e=new Error("The socket was closed while data was being compressed");"function"==typeof r&&r(e);for(let t=0;t{"use strict";const{Duplex:r}=n(2413);function i(e){e.emit("close")}function o(){!this.destroyed&&this._writableState.finished&&this.destroy()}function u(e){this.removeListener("error",u),this.destroy(),0===this.listenerCount("error")&&this.emit("error",e)}e.exports=function(e,t){let n=!0;function a(){n&&e._socket.resume()}e.readyState===e.CONNECTING?e.once("open",(function(){e._receiver.removeAllListeners("drain"),e._receiver.on("drain",a)})):(e._receiver.removeAllListeners("drain"),e._receiver.on("drain",a));const l=new r({...t,autoDestroy:!1,emitClose:!1,objectMode:!1,writableObjectMode:!1});return e.on("message",(function(t){l.push(t)||(n=!1,e._socket.pause())})),e.once("error",(function(e){l.destroyed||l.destroy(e)})),e.once("close",(function(){l.destroyed||l.push(null)})),l._destroy=function(t,n){if(e.readyState===e.CLOSED)return n(t),void process.nextTick(i,l);let r=!1;e.once("error",(function(e){r=!0,n(e)})),e.once("close",(function(){r||n(t),process.nextTick(i,l)})),e.terminate()},l._final=function(t){e.readyState!==e.CONNECTING?null!==e._socket&&(e._socket._writableState.finished?(t(),l._readableState.endEmitted&&l.destroy()):(e._socket.once("finish",(function(){t()})),e.close())):e.once("open",(function(){l._final(t)}))},l._read=function(){e.readyState!==e.OPEN||n||(n=!0,e._receiver._writableState.needDrain||e._socket.resume())},l._write=function(t,n,r){e.readyState!==e.CONNECTING?e.send(t,r):e.once("open",(function(){l._write(t,n,r)}))},l.on("end",o),l.on("error",u),l}},9498:(e,t,n)=>{"use strict";try{const e=n(Object(function(){var e=new Error("Cannot find module 'utf-8-validate'");throw e.code="MODULE_NOT_FOUND",e}()));t.isValidUTF8="object"==typeof e?e.Validation.isValidUTF8:e}catch(e){t.isValidUTF8=()=>!0}t.isValidStatusCode=e=>e>=1e3&&e<=1014&&1004!==e&&1005!==e&&1006!==e||e>=3e3&&e<=4999},43:(e,t,n)=>{"use strict";const r=n(8614),{createHash:i}=n(6417),{createServer:o,STATUS_CODES:u}=n(8605),a=n(2309),l=n(5760),{format:s,parse:c}=n(8162),{GUID:f,kWebSocket:d}=n(5739),p=/^[+/0-9A-Za-z]{22}==$/;function h(e){e.emit("close")}function v(){this.destroy()}function m(e,t,n,r){e.writable&&(n=n||u[t],r={Connection:"close","Content-Type":"text/html","Content-Length":Buffer.byteLength(n),...r},e.write(`HTTP/1.1 ${t} ${u[t]}\r\n`+Object.keys(r).map(e=>`${e}: ${r[e]}`).join("\r\n")+"\r\n\r\n"+n)),e.removeListener("error",v),e.destroy()}e.exports=class extends r{constructor(e,t){if(super(),null==(e={maxPayload:104857600,perMessageDeflate:!1,handleProtocols:null,clientTracking:!0,verifyClient:null,noServer:!1,backlog:null,server:null,host:null,path:null,port:null,...e}).port&&!e.server&&!e.noServer)throw new TypeError('One of the "port", "server", or "noServer" options must be specified');null!=e.port?(this._server=o((e,t)=>{const n=u[426];t.writeHead(426,{"Content-Length":n.length,"Content-Type":"text/plain"}),t.end(n)}),this._server.listen(e.port,e.host,e.backlog,t)):e.server&&(this._server=e.server),this._server&&(this._removeListeners=function(e,t){for(const n of Object.keys(t))e.on(n,t[n]);return function(){for(const n of Object.keys(t))e.removeListener(n,t[n])}}(this._server,{listening:this.emit.bind(this,"listening"),error:this.emit.bind(this,"error"),upgrade:(e,t,n)=>{this.handleUpgrade(e,t,n,t=>{this.emit("connection",t,e)})}})),!0===e.perMessageDeflate&&(e.perMessageDeflate={}),e.clientTracking&&(this.clients=new Set),this.options=e}address(){if(this.options.noServer)throw new Error('The server is operating in "noServer" mode');return this._server?this._server.address():null}close(e){if(e&&this.once("close",e),this.clients)for(const e of this.clients)e.terminate();const t=this._server;t&&(this._removeListeners(),this._removeListeners=this._server=null,null!=this.options.port)?t.close(()=>this.emit("close")):process.nextTick(h,this)}shouldHandle(e){if(this.options.path){const t=e.url.indexOf("?");if((-1!==t?e.url.slice(0,t):e.url)!==this.options.path)return!1}return!0}handleUpgrade(e,t,n,r){t.on("error",v);const i=void 0!==e.headers["sec-websocket-key"]&&e.headers["sec-websocket-key"].trim(),o=+e.headers["sec-websocket-version"],u={};if("GET"!==e.method||"websocket"!==e.headers.upgrade.toLowerCase()||!i||!p.test(i)||8!==o&&13!==o||!this.shouldHandle(e))return m(t,400);if(this.options.perMessageDeflate){const n=new a(this.options.perMessageDeflate,!0,this.options.maxPayload);try{const t=c(e.headers["sec-websocket-extensions"]);t[a.extensionName]&&(n.accept(t[a.extensionName]),u[a.extensionName]=n)}catch(e){return m(t,400)}}if(this.options.verifyClient){const a={origin:e.headers[""+(8===o?"sec-websocket-origin":"origin")],secure:!(!e.connection.authorized&&!e.connection.encrypted),req:e};if(2===this.options.verifyClient.length)return void this.options.verifyClient(a,(o,a,l,s)=>{if(!o)return m(t,a||401,l,s);this.completeUpgrade(i,u,e,t,n,r)});if(!this.options.verifyClient(a))return m(t,401)}this.completeUpgrade(i,u,e,t,n,r)}completeUpgrade(e,t,n,r,o,u){if(!r.readable||!r.writable)return r.destroy();if(r[d])throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration");const c=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade","Sec-WebSocket-Accept: "+i("sha1").update(e+f).digest("base64")],p=new l(null);let h=n.headers["sec-websocket-protocol"];if(h&&(h=h.trim().split(/ *, */),h=this.options.handleProtocols?this.options.handleProtocols(h,n):h[0],h&&(c.push("Sec-WebSocket-Protocol: "+h),p.protocol=h)),t[a.extensionName]){const e=t[a.extensionName].params,n=s({[a.extensionName]:[e]});c.push("Sec-WebSocket-Extensions: "+n),p._extensions=t}this.emit("headers",c,n),r.write(c.concat("\r\n").join("\r\n")),r.removeListener("error",v),p.setSocket(r,o,this.options.maxPayload),this.clients&&(this.clients.add(p),p.on("close",()=>this.clients.delete(p))),u(p)}}},5760:(e,t,n)=>{"use strict";const r=n(8614),i=n(7211),o=n(8605),u=n(1631),a=n(4016),{randomBytes:l,createHash:s}=n(6417),{URL:c}=n(8835),f=n(2309),d=n(1762),p=n(9576),{BINARY_TYPES:h,EMPTY_BUFFER:v,GUID:m,kStatusCode:g,kWebSocket:y,NOOP:_}=n(5739),{addEventListener:b,removeEventListener:w}=n(7002),{format:E,parse:D}=n(8162),{toBuffer:S}=n(8716),C=["CONNECTING","OPEN","CLOSING","CLOSED"],k=[8,13];class T extends r{constructor(e,t,n){super(),this.readyState=T.CONNECTING,this.protocol="",this._binaryType=h[0],this._closeFrameReceived=!1,this._closeFrameSent=!1,this._closeMessage="",this._closeTimer=null,this._closeCode=1006,this._extensions={},this._receiver=null,this._sender=null,this._socket=null,null!==e?(this._bufferedAmount=0,this._isServer=!1,this._redirects=0,Array.isArray(t)?t=t.join(", "):"object"==typeof t&&null!==t&&(n=t,t=void 0),function e(t,n,r,u){const a={protocolVersion:k[1],maxPayload:104857600,perMessageDeflate:!0,followRedirects:!1,maxRedirects:10,...u,createConnection:void 0,socketPath:void 0,hostname:void 0,protocol:void 0,timeout:void 0,method:void 0,host:void 0,path:void 0,port:void 0};if(!k.includes(a.protocolVersion))throw new RangeError(`Unsupported protocol version: ${a.protocolVersion} (supported versions: ${k.join(", ")})`);let d;n instanceof c?(d=n,t.url=n.href):(d=new c(n),t.url=n);const p="ws+unix:"===d.protocol;if(!(d.host||p&&d.pathname))throw new Error("Invalid URL: "+t.url);const h="wss:"===d.protocol||"https:"===d.protocol,v=h?443:80,g=l(16).toString("base64"),y=h?i.get:o.get;let _;a.createConnection=h?A:x,a.defaultPort=a.defaultPort||v,a.port=d.port||v,a.host=d.hostname.startsWith("[")?d.hostname.slice(1,-1):d.hostname,a.headers={"Sec-WebSocket-Version":a.protocolVersion,"Sec-WebSocket-Key":g,Connection:"Upgrade",Upgrade:"websocket",...a.headers},a.path=d.pathname+d.search,a.timeout=a.handshakeTimeout,a.perMessageDeflate&&(_=new f(!0!==a.perMessageDeflate?a.perMessageDeflate:{},!1,a.maxPayload),a.headers["Sec-WebSocket-Extensions"]=E({[f.extensionName]:_.offer()}));r&&(a.headers["Sec-WebSocket-Protocol"]=r);a.origin&&(a.protocolVersion<13?a.headers["Sec-WebSocket-Origin"]=a.origin:a.headers.Origin=a.origin);(d.username||d.password)&&(a.auth=`${d.username}:${d.password}`);if(p){const e=a.path.split(":");a.socketPath=e[0],a.path=e[1]}let b=t._req=y(a);a.timeout&&b.on("timeout",()=>{O(t,b,"Opening handshake has timed out")});b.on("error",e=>{t._req.aborted||(b=t._req=null,t.readyState=T.CLOSING,t.emit("error",e),t.emitClose())}),b.on("response",i=>{const o=i.headers.location,l=i.statusCode;if(o&&a.followRedirects&&l>=300&&l<400){if(++t._redirects>a.maxRedirects)return void O(t,b,"Maximum redirects exceeded");b.abort();const i=new c(o,n);e(t,i,r,u)}else t.emit("unexpected-response",b,i)||O(t,b,"Unexpected server response: "+i.statusCode)}),b.on("upgrade",(e,n,i)=>{if(t.emit("upgrade",e),t.readyState!==T.CONNECTING)return;b=t._req=null;const o=s("sha1").update(g+m).digest("base64");if(e.headers["sec-websocket-accept"]!==o)return void O(t,n,"Invalid Sec-WebSocket-Accept header");const u=e.headers["sec-websocket-protocol"],l=(r||"").split(/, */);let c;if(!r&&u?c="Server sent a subprotocol but none was requested":r&&!u?c="Server sent no subprotocol":u&&!l.includes(u)&&(c="Server sent an invalid subprotocol"),c)O(t,n,c);else{if(u&&(t.protocol=u),_)try{const n=D(e.headers["sec-websocket-extensions"]);n[f.extensionName]&&(_.accept(n[f.extensionName]),t._extensions[f.extensionName]=_)}catch(e){return void O(t,n,"Invalid Sec-WebSocket-Extensions header")}t.setSocket(n,i,a.maxPayload)}})}(this,e,t,n)):this._isServer=!0}get CONNECTING(){return T.CONNECTING}get CLOSING(){return T.CLOSING}get CLOSED(){return T.CLOSED}get OPEN(){return T.OPEN}get binaryType(){return this._binaryType}set binaryType(e){h.includes(e)&&(this._binaryType=e,this._receiver&&(this._receiver._binaryType=e))}get bufferedAmount(){return this._socket?this._socket._writableState.length+this._sender._bufferedBytes:this._bufferedAmount}get extensions(){return Object.keys(this._extensions).join()}setSocket(e,t,n){const r=new d(this._binaryType,this._extensions,this._isServer,n);this._sender=new p(e,this._extensions),this._receiver=r,this._socket=e,r[y]=this,e[y]=this,r.on("conclude",I),r.on("drain",N),r.on("error",M),r.on("message",F),r.on("ping",L),r.on("pong",B),e.setTimeout(0),e.setNoDelay(),t.length>0&&e.unshift(t),e.on("close",j),e.on("data",U),e.on("end",z),e.on("error",W),this.readyState=T.OPEN,this.emit("open")}emitClose(){if(!this._socket)return this.readyState=T.CLOSED,void this.emit("close",this._closeCode,this._closeMessage);this._extensions[f.extensionName]&&this._extensions[f.extensionName].cleanup(),this._receiver.removeAllListeners(),this.readyState=T.CLOSED,this.emit("close",this._closeCode,this._closeMessage)}close(e,t){if(this.readyState!==T.CLOSED){if(this.readyState===T.CONNECTING){const e="WebSocket was closed before the connection was established";return O(this,this._req,e)}this.readyState!==T.CLOSING?(this.readyState=T.CLOSING,this._sender.close(e,t,!this._isServer,e=>{e||(this._closeFrameSent=!0,this._closeFrameReceived&&this._socket.end())}),this._closeTimer=setTimeout(this._socket.destroy.bind(this._socket),3e4)):this._closeFrameSent&&this._closeFrameReceived&&this._socket.end()}}ping(e,t,n){if(this.readyState===T.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");"function"==typeof e?(n=e,e=t=void 0):"function"==typeof t&&(n=t,t=void 0),"number"==typeof e&&(e=e.toString()),this.readyState===T.OPEN?(void 0===t&&(t=!this._isServer),this._sender.ping(e||v,t,n)):P(this,e,n)}pong(e,t,n){if(this.readyState===T.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");"function"==typeof e?(n=e,e=t=void 0):"function"==typeof t&&(n=t,t=void 0),"number"==typeof e&&(e=e.toString()),this.readyState===T.OPEN?(void 0===t&&(t=!this._isServer),this._sender.pong(e||v,t,n)):P(this,e,n)}send(e,t,n){if(this.readyState===T.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if("function"==typeof t&&(n=t,t={}),"number"==typeof e&&(e=e.toString()),this.readyState!==T.OPEN)return void P(this,e,n);const r={binary:"string"!=typeof e,mask:!this._isServer,compress:!0,fin:!0,...t};this._extensions[f.extensionName]||(r.compress=!1),this._sender.send(e||v,r,n)}terminate(){if(this.readyState!==T.CLOSED){if(this.readyState===T.CONNECTING){const e="WebSocket was closed before the connection was established";return O(this,this._req,e)}this._socket&&(this.readyState=T.CLOSING,this._socket.destroy())}}}function x(e){return e.path=e.socketPath,u.connect(e)}function A(e){return e.path=void 0,e.servername||""===e.servername||(e.servername=e.host),a.connect(e)}function O(e,t,n){e.readyState=T.CLOSING;const r=new Error(n);Error.captureStackTrace(r,O),t.setHeader?(t.abort(),t.once("abort",e.emitClose.bind(e)),e.emit("error",r)):(t.destroy(r),t.once("error",e.emit.bind(e,"error")),t.once("close",e.emitClose.bind(e)))}function P(e,t,n){if(t){const n=S(t).length;e._socket?e._sender._bufferedBytes+=n:e._bufferedAmount+=n}if(n){n(new Error(`WebSocket is not open: readyState ${e.readyState} (${C[e.readyState]})`))}}function I(e,t){const n=this[y];n._socket.removeListener("data",U),n._socket.resume(),n._closeFrameReceived=!0,n._closeMessage=t,n._closeCode=e,1005===e?n.close():n.close(e,t)}function N(){this[y]._socket.resume()}function M(e){const t=this[y];t._socket.removeListener("data",U),t.readyState=T.CLOSING,t._closeCode=e[g],t.emit("error",e),t._socket.destroy()}function R(){this[y].emitClose()}function F(e){this[y].emit("message",e)}function L(e){const t=this[y];t.pong(e,!t._isServer,_),t.emit("ping",e)}function B(e){this[y].emit("pong",e)}function j(){const e=this[y];this.removeListener("close",j),this.removeListener("end",z),e.readyState=T.CLOSING,e._socket.read(),e._receiver.end(),this.removeListener("data",U),this[y]=void 0,clearTimeout(e._closeTimer),e._receiver._writableState.finished||e._receiver._writableState.errorEmitted?e.emitClose():(e._receiver.on("error",R),e._receiver.on("finish",R))}function U(e){this[y]._receiver.write(e)||this.pause()}function z(){const e=this[y];e.readyState=T.CLOSING,e._receiver.end(),this.end()}function W(){const e=this[y];this.removeListener("error",W),this.on("error",_),e&&(e.readyState=T.CLOSING,this.destroy())}C.forEach((e,t)=>{T[e]=t}),["open","error","close","message"].forEach(e=>{Object.defineProperty(T.prototype,"on"+e,{get(){const t=this.listeners(e);for(let e=0;e{"use strict";function r(e){const t=[...e.caches],n=t.shift();return void 0===n?i():{get:(e,i,o={miss:()=>Promise.resolve()})=>n.get(e,i,o).catch(()=>r({caches:t}).get(e,i,o)),set:(e,i)=>n.set(e,i).catch(()=>r({caches:t}).set(e,i)),delete:e=>n.delete(e).catch(()=>r({caches:t}).delete(e)),clear:()=>n.clear().catch(()=>r({caches:t}).clear())}}function i(){return{get:(e,t,n={miss:()=>Promise.resolve()})=>t().then(e=>Promise.all([e,n.miss(e)])).then(([e])=>e),set:(e,t)=>Promise.resolve(t),delete:e=>Promise.resolve(),clear:()=>Promise.resolve()}}n.r(t),n.d(t,{createFallbackableCache:()=>r,createNullCache:()=>i})},6712:(e,t,n)=>{"use strict";function r(e={serializable:!0}){let t={};return{get(n,r,i={miss:()=>Promise.resolve()}){const o=JSON.stringify(n);if(o in t)return Promise.resolve(e.serializable?JSON.parse(t[o]):t[o]);const u=r(),a=i&&i.miss||(()=>Promise.resolve());return u.then(e=>a(e)).then(()=>u)},set:(n,r)=>(t[JSON.stringify(n)]=e.serializable?JSON.stringify(r):r,Promise.resolve(r)),delete:e=>(delete t[JSON.stringify(e)],Promise.resolve()),clear:()=>(t={},Promise.resolve())}}n.r(t),n.d(t,{createInMemoryCache:()=>r})},2223:(e,t,n)=>{"use strict";n.r(t),n.d(t,{addABTest:()=>a,createAnalyticsClient:()=>u,deleteABTest:()=>l,getABTest:()=>s,getABTests:()=>c,stopABTest:()=>f});var r=n(1757),i=n(7858),o=n(5541);const u=e=>{const t=e.region||"us",n=(0,r.createAuth)(r.AuthMode.WithinHeaders,e.appId,e.apiKey),o=(0,i.createTransporter)({hosts:[{url:`analytics.${t}.algolia.com`}],...e,headers:{...n.headers(),"content-type":"application/json",...e.headers},queryParameters:{...n.queryParameters(),...e.queryParameters}}),u=e.appId;return(0,r.addMethods)({appId:u,transporter:o},e.methods)},a=e=>(t,n)=>e.transporter.write({method:o.N.Post,path:"2/abtests",data:t},n),l=e=>(t,n)=>e.transporter.write({method:o.N.Delete,path:(0,r.encode)("2/abtests/%s",t)},n),s=e=>(t,n)=>e.transporter.read({method:o.N.Get,path:(0,r.encode)("2/abtests/%s",t)},n),c=e=>t=>e.transporter.read({method:o.N.Get,path:"2/abtests"},t),f=e=>(t,n)=>e.transporter.write({method:o.N.Post,path:(0,r.encode)("2/abtests/%s/stop",t)},n)},1757:(e,t,n)=>{"use strict";function r(e,t,n){const r={"x-algolia-api-key":n,"x-algolia-application-id":t};return{headers:()=>e===f.WithinHeaders?r:{},queryParameters:()=>e===f.WithinQueryParameters?r:{}}}function i(e){let t=0;const n=()=>(t++,new Promise(r=>{setTimeout(()=>{r(e(n))},Math.min(100*t,1e3))}));return e(n)}function o(e,t=((e,t)=>Promise.resolve())){return Object.assign(e,{wait:n=>o(e.then(e=>Promise.all([t(e,n),e])).then(e=>e[1]))})}function u(e){let t=e.length-1;for(;t>0;t--){const n=Math.floor(Math.random()*(t+1)),r=e[t];e[t]=e[n],e[n]=r}return e}function a(e,t){return Object.keys(void 0!==t?t:{}).forEach(n=>{e[n]=t[n](e)}),e}function l(e,...t){let n=0;return e.replace(/%s/g,()=>encodeURIComponent(t[n++]))}n.r(t),n.d(t,{AuthMode:()=>f,addMethods:()=>a,createAuth:()=>r,createRetryablePromise:()=>i,createWaitablePromise:()=>o,destroy:()=>c,encode:()=>l,shuffle:()=>u,version:()=>s});const s="4.2.0",c=e=>()=>e.transporter.requester.destroy(),f={WithinQueryParameters:0,WithinHeaders:1}},103:(e,t,n)=>{"use strict";n.r(t),n.d(t,{createRecommendationClient:()=>u,getPersonalizationStrategy:()=>a,setPersonalizationStrategy:()=>l});var r=n(1757),i=n(7858),o=n(5541);const u=e=>{const t=e.region||"us",n=(0,r.createAuth)(r.AuthMode.WithinHeaders,e.appId,e.apiKey),o=(0,i.createTransporter)({hosts:[{url:`recommendation.${t}.algolia.com`}],...e,headers:{...n.headers(),"content-type":"application/json",...e.headers},queryParameters:{...n.queryParameters(),...e.queryParameters}});return(0,r.addMethods)({appId:e.appId,transporter:o},e.methods)},a=e=>t=>e.transporter.read({method:o.N.Get,path:"1/strategies/personalization"},t),l=e=>(t,n)=>e.transporter.write({method:o.N.Post,path:"1/strategies/personalization",data:t},n)},6586:(e,t,n)=>{"use strict";n.r(t),n.d(t,{ApiKeyACLEnum:()=>Te,BatchActionEnum:()=>xe,ScopeEnum:()=>Ae,StrategyEnum:()=>Oe,SynonymEnum:()=>Pe,addApiKey:()=>d,assignUserID:()=>p,assignUserIDs:()=>h,batch:()=>z,browseObjects:()=>W,browseRules:()=>H,browseSynonyms:()=>V,chunkedBatch:()=>q,clearObjects:()=>G,clearRules:()=>$,clearSynonyms:()=>Y,copyIndex:()=>v,copyRules:()=>m,copySettings:()=>g,copySynonyms:()=>y,createBrowsablePromise:()=>a,createMissingObjectIDError:()=>s,createObjectNotFoundError:()=>c,createSearchClient:()=>l,createValidUntilNotFoundError:()=>f,deleteApiKey:()=>_,deleteBy:()=>K,deleteIndex:()=>X,deleteObject:()=>Q,deleteObjects:()=>J,deleteRule:()=>Z,deleteSynonym:()=>ee,exists:()=>te,findObject:()=>ne,generateSecuredApiKey:()=>b,getApiKey:()=>w,getLogs:()=>E,getObject:()=>re,getObjectPosition:()=>ie,getObjects:()=>oe,getRule:()=>ue,getSecuredApiKeyRemainingValidity:()=>D,getSettings:()=>ae,getSynonym:()=>le,getTask:()=>se,getTopUserIDs:()=>S,getUserID:()=>C,hasPendingMappings:()=>k,initIndex:()=>T,listApiKeys:()=>x,listClusters:()=>A,listIndices:()=>O,listUserIDs:()=>P,moveIndex:()=>I,multipleBatch:()=>N,multipleGetObjects:()=>M,multipleQueries:()=>R,multipleSearchForFacetValues:()=>F,partialUpdateObject:()=>ce,partialUpdateObjects:()=>fe,removeUserID:()=>L,replaceAllObjects:()=>de,replaceAllRules:()=>pe,replaceAllSynonyms:()=>he,restoreApiKey:()=>B,saveObject:()=>ve,saveObjects:()=>me,saveRule:()=>ge,saveRules:()=>ye,saveSynonym:()=>_e,saveSynonyms:()=>be,search:()=>we,searchForFacetValues:()=>Ee,searchRules:()=>De,searchSynonyms:()=>Se,searchUserIDs:()=>j,setSettings:()=>Ce,updateApiKey:()=>U,waitTask:()=>ke});var r=n(1757),i=n(7858),o=n(5541),u=n(6417);function a(e){const t=n=>e.request(n).then(r=>{if(void 0!==e.batch&&e.batch(r.hits),!e.shouldStop(r))return r.cursor?t({cursor:r.cursor}):t({page:(n.page||0)+1})});return t({})}const l=e=>{const t=e.appId,n=(0,r.createAuth)(void 0!==e.authMode?e.authMode:r.AuthMode.WithinHeaders,t,e.apiKey),o=(0,i.createTransporter)({hosts:[{url:t+"-dsn.algolia.net",accept:i.CallEnum.Read},{url:t+".algolia.net",accept:i.CallEnum.Write}].concat((0,r.shuffle)([{url:t+"-1.algolianet.com"},{url:t+"-2.algolianet.com"},{url:t+"-3.algolianet.com"}])),...e,headers:{...n.headers(),"content-type":"application/x-www-form-urlencoded",...e.headers},queryParameters:{...n.queryParameters(),...e.queryParameters}}),u={transporter:o,appId:t,addAlgoliaAgent(e,t){o.userAgent.add({segment:e,version:t})},clearCache:()=>Promise.all([o.requestsCache.clear(),o.responsesCache.clear()]).then(()=>{})};return(0,r.addMethods)(u,e.methods)};function s(){return{name:"MissingObjectIDError",message:"All objects must have an unique objectID (like a primary key) to be valid. Algolia is also able to generate objectIDs automatically but *it's not recommended*. To do it, use the `{'autoGenerateObjectIDIfNotExist': true}` option."}}function c(){return{name:"ObjectNotFoundError",message:"Object not found."}}function f(){return{name:"ValidUntilNotFoundError",message:"ValidUntil not found in given secured api key."}}const d=e=>(t,n)=>{const{queryParameters:i,...u}=n||{},a={acl:t,...void 0!==i?{queryParameters:i}:{}};return(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Post,path:"1/keys",data:a},u),(t,n)=>(0,r.createRetryablePromise)(r=>w(e)(t.key,n).catch(e=>{if(404!==e.status)throw e;return r()})))},p=e=>(t,n,r)=>{const u=(0,i.createMappedRequestOptions)(r);return u.queryParameters["X-Algolia-User-ID"]=t,e.transporter.write({method:o.N.Post,path:"1/clusters/mapping",data:{cluster:n}},u)},h=e=>(t,n,r)=>e.transporter.write({method:o.N.Post,path:"1/clusters/mapping/batch",data:{users:t,cluster:n}},r),v=e=>(t,n,i)=>(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Post,path:(0,r.encode)("1/indexes/%s/operation",t),data:{operation:"copy",destination:n}},i),(n,r)=>T(e)(t,{methods:{waitTask:ke}}).waitTask(n.taskID,r)),m=e=>(t,n,r)=>v(e)(t,n,{...r,scope:[Ae.Rules]}),g=e=>(t,n,r)=>v(e)(t,n,{...r,scope:[Ae.Settings]}),y=e=>(t,n,r)=>v(e)(t,n,{...r,scope:[Ae.Synonyms]}),_=e=>(t,n)=>(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Delete,path:(0,r.encode)("1/keys/%s",t)},n),(n,i)=>(0,r.createRetryablePromise)(n=>w(e)(t,i).then(n).catch(e=>{if(404!==e.status)throw e}))),b=()=>(e,t)=>{const n=(0,i.serializeQueryParameters)(t),r=(0,u.createHmac)("sha256",e).update(n).digest("hex");return Buffer.from(r+n).toString("base64")},w=e=>(t,n)=>e.transporter.read({method:o.N.Get,path:(0,r.encode)("1/keys/%s",t)},n),E=e=>t=>e.transporter.read({method:o.N.Get,path:"1/logs"},t),D=()=>e=>{const t=Buffer.from(e,"base64").toString("ascii").match(/validUntil=(\d+)/);if(null===t)throw{name:"ValidUntilNotFoundError",message:"ValidUntil not found in given secured api key."};return parseInt(t[1],10)-Math.round((new Date).getTime()/1e3)},S=e=>t=>e.transporter.read({method:o.N.Get,path:"1/clusters/mapping/top"},t),C=e=>(t,n)=>e.transporter.read({method:o.N.Get,path:(0,r.encode)("1/clusters/mapping/%s",t)},n),k=e=>t=>{const{retrieveMappings:n,...r}=t||{};return!0===n&&(r.getClusters=!0),e.transporter.read({method:o.N.Get,path:"1/clusters/mapping/pending"},r)},T=e=>(t,n={})=>{const i={transporter:e.transporter,appId:e.appId,indexName:t};return(0,r.addMethods)(i,n.methods)},x=e=>t=>e.transporter.read({method:o.N.Get,path:"1/keys"},t),A=e=>t=>e.transporter.read({method:o.N.Get,path:"1/clusters"},t),O=e=>t=>e.transporter.read({method:o.N.Get,path:"1/indexes"},t),P=e=>t=>e.transporter.read({method:o.N.Get,path:"1/clusters/mapping"},t),I=e=>(t,n,i)=>(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Post,path:(0,r.encode)("1/indexes/%s/operation",t),data:{operation:"move",destination:n}},i),(n,r)=>T(e)(t,{methods:{waitTask:ke}}).waitTask(n.taskID,r)),N=e=>(t,n)=>(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Post,path:"1/indexes/*/batch",data:{requests:t}},n),(t,n)=>Promise.all(Object.keys(t.taskID).map(r=>T(e)(r,{methods:{waitTask:ke}}).waitTask(t.taskID[r],n)))),M=e=>(t,n)=>e.transporter.read({method:o.N.Post,path:"1/indexes/*/objects",data:{requests:t}},n),R=e=>(t,n)=>{const r=t.map(e=>({...e,params:(0,i.serializeQueryParameters)(e.params||{})}));return e.transporter.read({method:o.N.Post,path:"1/indexes/*/queries",data:{requests:r},cacheable:!0},n)},F=e=>(t,n)=>Promise.all(t.map(t=>{const{facetName:r,facetQuery:i,...o}=t.params;return T(e)(t.indexName,{methods:{searchForFacetValues:Ee}}).searchForFacetValues(r,i,{...n,...o})})),L=e=>(t,n)=>{const r=(0,i.createMappedRequestOptions)(n);return r.queryParameters["X-Algolia-User-ID"]=t,e.transporter.write({method:o.N.Delete,path:"1/clusters/mapping"},r)},B=e=>(t,n)=>(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Post,path:(0,r.encode)("1/keys/%s/restore",t)},n),(n,i)=>(0,r.createRetryablePromise)(n=>w(e)(t,i).catch(e=>{if(404!==e.status)throw e;return n()}))),j=e=>(t,n)=>e.transporter.read({method:o.N.Post,path:"1/clusters/mapping/search",data:{query:t}},n),U=e=>(t,n)=>{const i=Object.assign({},n),{queryParameters:u,...a}=n||{},l=u?{queryParameters:u}:{},s=["acl","indexes","referers","restrictSources","queryParameters","description","maxQueriesPerIPPerHour","maxHitsPerQuery"];return(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Put,path:(0,r.encode)("1/keys/%s",t),data:l},a),(n,o)=>(0,r.createRetryablePromise)(n=>w(e)(t,o).then(e=>(e=>Object.keys(i).filter(e=>-1!==s.indexOf(e)).every(t=>e[t]===i[t]))(e)?Promise.resolve():n())))},z=e=>(t,n)=>(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Post,path:(0,r.encode)("1/indexes/%s/batch",e.indexName),data:{requests:t}},n),(t,n)=>ke(e)(t.taskID,n)),W=e=>t=>a({...t,shouldStop:e=>void 0===e.cursor,request:n=>e.transporter.read({method:o.N.Post,path:(0,r.encode)("1/indexes/%s/browse",e.indexName),data:n},t)}),H=e=>t=>{const n={hitsPerPage:1e3,...t};return a({...n,shouldStop:e=>e.hits.lengthDe(e)("",{...n,...t}).then(e=>({...e,hits:e.hits.map(e=>(delete e._highlightResult,e))}))})},V=e=>t=>{const n={hitsPerPage:1e3,...t};return a({...n,shouldStop:e=>e.hits.lengthSe(e)("",{...n,...t}).then(e=>({...e,hits:e.hits.map(e=>(delete e._highlightResult,e))}))})},q=e=>(t,n,i)=>{const{batchSize:o,...u}=i||{},a={taskIDs:[],objectIDs:[]},l=(r=0)=>{const i=[];let s;for(s=r;s({action:n,body:e})),u).then(e=>(a.objectIDs=a.objectIDs.concat(e.objectIDs),a.taskIDs.push(e.taskID),s++,l(s)))};return(0,r.createWaitablePromise)(l(),(t,n)=>Promise.all(t.taskIDs.map(t=>ke(e)(t,n))))},G=e=>t=>(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Post,path:(0,r.encode)("1/indexes/%s/clear",e.indexName)},t),(t,n)=>ke(e)(t.taskID,n)),$=e=>t=>{const{forwardToReplicas:n,...u}=t||{},a=(0,i.createMappedRequestOptions)(u);return n&&(a.queryParameters.forwardToReplicas=1),(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Post,path:(0,r.encode)("1/indexes/%s/rules/clear",e.indexName)},a),(t,n)=>ke(e)(t.taskID,n))},Y=e=>t=>{const{forwardToReplicas:n,...u}=t||{},a=(0,i.createMappedRequestOptions)(u);return n&&(a.queryParameters.forwardToReplicas=1),(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Post,path:(0,r.encode)("1/indexes/%s/synonyms/clear",e.indexName)},a),(t,n)=>ke(e)(t.taskID,n))},K=e=>(t,n)=>(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Post,path:(0,r.encode)("1/indexes/%s/deleteByQuery",e.indexName),data:t},n),(t,n)=>ke(e)(t.taskID,n)),X=e=>t=>(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Delete,path:(0,r.encode)("1/indexes/%s",e.indexName)},t),(t,n)=>ke(e)(t.taskID,n)),Q=e=>(t,n)=>(0,r.createWaitablePromise)(J(e)([t],n).then(e=>({taskID:e.taskIDs[0]})),(t,n)=>ke(e)(t.taskID,n)),J=e=>(t,n)=>{const r=t.map(e=>({objectID:e}));return q(e)(r,xe.DeleteObject,n)},Z=e=>(t,n)=>{const{forwardToReplicas:u,...a}=n||{},l=(0,i.createMappedRequestOptions)(a);return u&&(l.queryParameters.forwardToReplicas=1),(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Delete,path:(0,r.encode)("1/indexes/%s/rules/%s",e.indexName,t)},l),(t,n)=>ke(e)(t.taskID,n))},ee=e=>(t,n)=>{const{forwardToReplicas:u,...a}=n||{},l=(0,i.createMappedRequestOptions)(a);return u&&(l.queryParameters.forwardToReplicas=1),(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Delete,path:(0,r.encode)("1/indexes/%s/synonyms/%s",e.indexName,t)},l),(t,n)=>ke(e)(t.taskID,n))},te=e=>t=>ae(e)(t).then(()=>!0).catch(e=>{if(404!==e.status)throw e;return!1}),ne=e=>(t,n)=>{const{query:r,paginate:i,...o}=n||{};let u=0;const a=()=>we(e)(r||"",{...o,page:u}).then(e=>{for(const[n,r]of Object.entries(e.hits))if(t(r))return{object:r,position:parseInt(n,10),page:u};if(u++,!1===i||u>=e.nbPages)throw{name:"ObjectNotFoundError",message:"Object not found."};return a()});return a()},re=e=>(t,n)=>e.transporter.read({method:o.N.Get,path:(0,r.encode)("1/indexes/%s/%s",e.indexName,t)},n),ie=()=>(e,t)=>{for(const[n,r]of Object.entries(e.hits))if(r.objectID===t)return parseInt(n,10);return-1},oe=e=>(t,n)=>{const{attributesToRetrieve:r,...i}=n||{},u=t.map(t=>({indexName:e.indexName,objectID:t,...r?{attributesToRetrieve:r}:{}}));return e.transporter.read({method:o.N.Post,path:"1/indexes/*/objects",data:{requests:u}},i)},ue=e=>(t,n)=>e.transporter.read({method:o.N.Get,path:(0,r.encode)("1/indexes/%s/rules/%s",e.indexName,t)},n),ae=e=>t=>e.transporter.read({method:o.N.Get,path:(0,r.encode)("1/indexes/%s/settings",e.indexName),data:{getVersion:2}},t),le=e=>(t,n)=>e.transporter.read({method:o.N.Get,path:(0,r.encode)("1/indexes/%s/synonyms/%s",e.indexName,t)},n),se=e=>(t,n)=>e.transporter.read({method:o.N.Get,path:(0,r.encode)("1/indexes/%s/task/%s",e.indexName,t.toString())},n),ce=e=>(t,n)=>(0,r.createWaitablePromise)(fe(e)([t],n).then(e=>({objectID:e.objectIDs[0],taskID:e.taskIDs[0]})),(t,n)=>ke(e)(t.taskID,n)),fe=e=>(t,n)=>{const{createIfNotExists:r,...i}=n||{},o=r?xe.PartialUpdateObject:xe.PartialUpdateObjectNoCreate;return q(e)(t,o,i)},de=e=>(t,n)=>{const{safe:i,autoGenerateObjectIDIfNotExist:u,batchSize:a,...l}=n||{},s=(t,n,i,u)=>(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Post,path:(0,r.encode)("1/indexes/%s/operation",t),data:{operation:i,destination:n}},u),(t,n)=>ke(e)(t.taskID,n)),c=Math.random().toString(36).substring(7),f=`${e.indexName}_tmp_${c}`,d=me({appId:e.appId,transporter:e.transporter,indexName:f});let p=[];const h=s(e.indexName,f,"copy",{...l,scope:["settings","synonyms","rules"]});p.push(h);const v=(i?h.wait(l):h).then(()=>{const e=d(t,{...l,autoGenerateObjectIDIfNotExist:u,batchSize:a});return p.push(e),i?e.wait(l):e}).then(()=>{const t=s(f,e.indexName,"move",l);return p.push(t),i?t.wait(l):t}).then(()=>Promise.all(p)).then(([e,t,n])=>({objectIDs:t.objectIDs,taskIDs:[e.taskID,...t.taskIDs,n.taskID]}));return(0,r.createWaitablePromise)(v,(e,t)=>Promise.all(p.map(e=>e.wait(t))))},pe=e=>(t,n)=>ye(e)(t,{...n,clearExistingRules:!0}),he=e=>(t,n)=>be(e)(t,{...n,replaceExistingSynonyms:!0}),ve=e=>(t,n)=>(0,r.createWaitablePromise)(me(e)([t],n).then(e=>({objectID:e.objectIDs[0],taskID:e.taskIDs[0]})),(t,n)=>ke(e)(t.taskID,n)),me=e=>(t,n)=>{const{autoGenerateObjectIDIfNotExist:i,...o}=n||{},u=i?xe.AddObject:xe.UpdateObject;if(u===xe.UpdateObject)for(const e of t)if(void 0===e.objectID)return(0,r.createWaitablePromise)(Promise.reject({name:"MissingObjectIDError",message:"All objects must have an unique objectID (like a primary key) to be valid. Algolia is also able to generate objectIDs automatically but *it's not recommended*. To do it, use the `{'autoGenerateObjectIDIfNotExist': true}` option."}));return q(e)(t,u,o)},ge=e=>(t,n)=>ye(e)([t],n),ye=e=>(t,n)=>{const{forwardToReplicas:u,clearExistingRules:a,...l}=n||{},s=(0,i.createMappedRequestOptions)(l);return u&&(s.queryParameters.forwardToReplicas=1),a&&(s.queryParameters.clearExistingRules=1),(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Post,path:(0,r.encode)("1/indexes/%s/rules/batch",e.indexName),data:t},s),(t,n)=>ke(e)(t.taskID,n))},_e=e=>(t,n)=>be(e)([t],n),be=e=>(t,n)=>{const{forwardToReplicas:u,replaceExistingSynonyms:a,...l}=n||{},s=(0,i.createMappedRequestOptions)(l);return u&&(s.queryParameters.forwardToReplicas=1),a&&(s.queryParameters.replaceExistingSynonyms=1),(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Post,path:(0,r.encode)("1/indexes/%s/synonyms/batch",e.indexName),data:t},s),(t,n)=>ke(e)(t.taskID,n))},we=e=>(t,n)=>e.transporter.read({method:o.N.Post,path:(0,r.encode)("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},n),Ee=e=>(t,n,i)=>e.transporter.read({method:o.N.Post,path:(0,r.encode)("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:n},cacheable:!0},i),De=e=>(t,n)=>e.transporter.read({method:o.N.Post,path:(0,r.encode)("1/indexes/%s/rules/search",e.indexName),data:{query:t}},n),Se=e=>(t,n)=>e.transporter.read({method:o.N.Post,path:(0,r.encode)("1/indexes/%s/synonyms/search",e.indexName),data:{query:t}},n),Ce=e=>(t,n)=>{const{forwardToReplicas:u,...a}=n||{},l=(0,i.createMappedRequestOptions)(a);return u&&(l.queryParameters.forwardToReplicas=1),(0,r.createWaitablePromise)(e.transporter.write({method:o.N.Put,path:(0,r.encode)("1/indexes/%s/settings",e.indexName),data:t},l),(t,n)=>ke(e)(t.taskID,n))},ke=e=>(t,n)=>(0,r.createRetryablePromise)(r=>se(e)(t,n).then(e=>"published"!==e.status?r():void 0)),Te={AddObject:"addObject",Analytics:"analytics",Browser:"browse",DeleteIndex:"deleteIndex",DeleteObject:"deleteObject",EditSettings:"editSettings",ListIndexes:"listIndexes",Logs:"logs",Recommendation:"recommendation",Search:"search",SeeUnretrievableAttributes:"seeUnretrievableAttributes",Settings:"settings",Usage:"usage"},xe={AddObject:"addObject",UpdateObject:"updateObject",PartialUpdateObject:"partialUpdateObject",PartialUpdateObjectNoCreate:"partialUpdateObjectNoCreate",DeleteObject:"deleteObject"},Ae={Settings:"settings",Synonyms:"synonyms",Rules:"rules"},Oe={None:"none",StopIfEnoughMatches:"stopIfEnoughMatches"},Pe={Synonym:"synonym",OneWaySynonym:"oneWaySynonym",AltCorrection1:"altCorrection1",AltCorrection2:"altCorrection2",Placeholder:"placeholder"}},8045:(e,t,n)=>{"use strict";function r(){return{debug:(e,t)=>Promise.resolve(),info:(e,t)=>Promise.resolve(),error:(e,t)=>Promise.resolve()}}n.r(t),n.d(t,{LogLevelEnum:()=>i,createNullLogger:()=>r});const i={Debug:1,Info:2,Error:3}},5541:(e,t,n)=>{"use strict";n.d(t,{N:()=>r});const r={Delete:"DELETE",Get:"GET",Post:"POST",Put:"PUT"}},9178:(e,t,n)=>{"use strict";n.r(t),n.d(t,{createNodeHttpRequester:()=>u});var r=n(8605),i=n(7211),o=n(8835);function u(){const e={keepAlive:!0},t=new r.Agent(e),n=new i.Agent(e);return{send:e=>new Promise(u=>{const a=(0,o.parse)(e.url),l=null===a.query?a.pathname:`${a.pathname}?${a.query}`,s={agent:"https:"===a.protocol?n:t,hostname:a.hostname,path:l,method:e.method,headers:e.headers,...void 0!==a.port?{port:a.port||""}:{}},c=("https:"===a.protocol?i:r).request(s,e=>{let t="";e.on("data",e=>t+=e),e.on("end",()=>{clearTimeout(d),clearTimeout(p),u({status:e.statusCode||0,content:t,isTimedOut:!1})})}),f=(e,t)=>setTimeout(()=>{c.abort(),u({status:0,content:t,isTimedOut:!0})},1e3*e),d=f(e.connectTimeout,"Connection timeout");let p;c.on("error",e=>{clearTimeout(d),clearTimeout(p),u({status:0,content:e.message,isTimedOut:!1})}),c.once("response",()=>{clearTimeout(d),p=f(e.responseTimeout,"Socket timeout")}),void 0!==e.data&&c.write(e.data),c.end()}),destroy:()=>(t.destroy(),n.destroy(),Promise.resolve())}}},7858:(e,t,n)=>{"use strict";n.r(t),n.d(t,{CallEnum:()=>o,HostStatusEnum:()=>u,createApiError:()=>E,createDeserializationError:()=>D,createMappedRequestOptions:()=>i,createRetryError:()=>S,createStatefulHost:()=>a,createStatelessHost:()=>c,createTransporter:()=>d,createUserAgent:()=>p,deserializeFailure:()=>v,deserializeSuccess:()=>h,isStatefulHostTimeouted:()=>s,isStatefulHostUp:()=>l,serializeData:()=>y,serializeHeaders:()=>_,serializeQueryParameters:()=>g,serializeUrl:()=>m,stackFrameWithoutCredentials:()=>w,stackTraceWithoutCredentials:()=>b});var r=n(5541);function i(e,t){const n=e||{},r=n.data||{};return Object.keys(n).forEach(e=>{-1===["timeout","headers","queryParameters","data","cacheable"].indexOf(e)&&(r[e]=n[e])}),{data:Object.entries(r).length>0?r:void 0,timeout:n.timeout||t,headers:n.headers||{},queryParameters:n.queryParameters||{},cacheable:n.cacheable}}const o={Read:1,Write:2,Any:3},u={Up:1,Down:2,Timeouted:3};function a(e,t=u.Up){return{...e,status:t,lastUpdate:Date.now()}}function l(e){return e.status===u.Up||Date.now()-e.lastUpdate>12e4}function s(e){return e.status===u.Timeouted&&Date.now()-e.lastUpdate<=12e4}function c(e){return{protocol:e.protocol||"https",url:e.url,accept:e.accept||o.Any}}function f(e,t,n,i){const o=[],f=y(n,i),d=_(e,i),p=n.method,g=n.method!==r.N.Get?{}:{...n.data,...i.data},E={"x-algolia-agent":e.userAgent.value,...e.queryParameters,...g,...i.queryParameters};let D=0;const C=(t,r)=>{const l=t.pop();if(void 0===l)throw S(b(o));const s={data:f,headers:d,method:p,url:m(l,n.path,E),connectTimeout:r(D,e.timeouts.connect),responseTimeout:r(D,i.timeout)},c=e=>{const n={request:s,response:e,host:l,triesLeft:t.length};return o.push(n),n},g={onSucess:e=>h(e),onRetry(n){const i=c(n);return n.isTimedOut&&D++,Promise.all([e.logger.info("Retryable failure",w(i)),e.hostsCache.set(l,a(l,n.isTimedOut?u.Timeouted:u.Down))]).then(()=>C(t,r))},onFail(e){throw c(e),v(e,b(o))}};return e.requester.send(s).then(e=>((e,t)=>(e=>{const t=e.status;return e.isTimedOut||(({isTimedOut:e,status:t})=>!e&&0==~~t)(e)||2!=~~(t/100)&&4!=~~(t/100)})(e)?t.onRetry(e):(({status:e})=>2==~~(e/100))(e)?t.onSucess(e):t.onFail(e))(e,g))};return function(e,t){return Promise.all(t.map(t=>e.get(t,()=>Promise.resolve(a(t))))).then(e=>{const n=e.filter(e=>l(e)),r=e.filter(e=>s(e)),i=[...n,...r];return{getTimeout:(e,t)=>(0===r.length&&0===e?1:r.length+3+e)*t,statelessHosts:i.length>0?i.map(e=>c(e)):t}})}(e.hostsCache,t).then(e=>C([...e.statelessHosts].reverse(),e.getTimeout))}function d(e){const{hostsCache:t,logger:n,requester:r,requestsCache:u,responsesCache:a,timeouts:l,userAgent:s,hosts:d,queryParameters:p,headers:h}=e,v={hostsCache:t,logger:n,requester:r,requestsCache:u,responsesCache:a,timeouts:l,userAgent:s,headers:h,queryParameters:p,hosts:d.map(e=>c(e)),read(e,t){const n=i(t,v.timeouts.read),r=()=>f(v,v.hosts.filter(e=>0!=(e.accept&o.Read)),e,n);if(!0!==(void 0!==n.cacheable?n.cacheable:e.cacheable))return r();const u={request:e,mappedRequestOptions:n,transporter:{queryParameters:v.queryParameters,headers:v.headers}};return v.responsesCache.get(u,()=>v.requestsCache.get(u,()=>v.requestsCache.set(u,r()).then(e=>Promise.all([v.requestsCache.delete(u),e]),e=>Promise.all([v.requestsCache.delete(u),Promise.reject(e)])).then(([e,t])=>t)),{miss:e=>v.responsesCache.set(u,e)})},write:(e,t)=>f(v,v.hosts.filter(e=>0!=(e.accept&o.Write)),e,i(t,v.timeouts.write))};return v}function p(e){const t={value:`Algolia for JavaScript (${e})`,add(e){const n=`; ${e.segment}${void 0!==e.version?` (${e.version})`:""}`;return-1===t.value.indexOf(n)&&(t.value=`${t.value}${n}`),t}};return t}function h(e){try{return JSON.parse(e.content)}catch(t){throw D(t.message,e)}}function v({content:e,status:t},n){let r=e;try{r=JSON.parse(e).message}catch(e){}return E(r,t,n)}function m(e,t,n){const r=g(n);let i=`${e.protocol}://${e.url}/${"/"===t.charAt(0)?t.substr(1):t}`;return r.length&&(i+="?"+r),i}function g(e){return Object.keys(e).map(t=>{return function(e,...t){let n=0;return e.replace(/%s/g,()=>encodeURIComponent(t[n++]))}("%s=%s",t,(n=e[t],"[object Object]"===Object.prototype.toString.call(n)||"[object Array]"===Object.prototype.toString.call(n)?JSON.stringify(e[t]):e[t]));var n}).join("&")}function y(e,t){if(e.method===r.N.Get||void 0===e.data&&void 0===t.data)return;const n=Array.isArray(e.data)?e.data:{...e.data,...t.data};return JSON.stringify(n)}function _(e,t){const n={...e.headers,...t.headers},r={};return Object.keys(n).forEach(e=>{const t=n[e];r[e.toLowerCase()]=t}),r}function b(e){return e.map(e=>w(e))}function w(e){const t=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return{...e,request:{...e.request,headers:{...e.request.headers,...t}}}}function E(e,t,n){return{name:"ApiError",message:e,status:t,transporterStackTrace:n}}function D(e,t){return{name:"DeserializationError",message:e,response:t}}function S(e){return{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:e}}},8774:(e,t,n)=>{"use strict";var r=n(469),i=n(6712),o=n(2223),u=n(1757),a=n(103),l=n(6586),s=n(8045),c=n(9178),f=n(7858);function d(e,t,n){const d={appId:e,apiKey:t,timeouts:{connect:2,read:5,write:30},requester:c.createNodeHttpRequester(),logger:s.createNullLogger(),responsesCache:r.createNullCache(),requestsCache:r.createNullCache(),hostsCache:i.createInMemoryCache(),userAgent:f.createUserAgent(u.version).add({segment:"Node.js",version:process.versions.node})};return l.createSearchClient({...d,...n,methods:{search:l.multipleQueries,searchForFacetValues:l.multipleSearchForFacetValues,multipleBatch:l.multipleBatch,multipleGetObjects:l.multipleGetObjects,multipleQueries:l.multipleQueries,copyIndex:l.copyIndex,copySettings:l.copySettings,copyRules:l.copyRules,copySynonyms:l.copySynonyms,moveIndex:l.moveIndex,listIndices:l.listIndices,getLogs:l.getLogs,listClusters:l.listClusters,multipleSearchForFacetValues:l.multipleSearchForFacetValues,getApiKey:l.getApiKey,addApiKey:l.addApiKey,listApiKeys:l.listApiKeys,updateApiKey:l.updateApiKey,deleteApiKey:l.deleteApiKey,restoreApiKey:l.restoreApiKey,assignUserID:l.assignUserID,assignUserIDs:l.assignUserIDs,getUserID:l.getUserID,searchUserIDs:l.searchUserIDs,listUserIDs:l.listUserIDs,getTopUserIDs:l.getTopUserIDs,removeUserID:l.removeUserID,hasPendingMappings:l.hasPendingMappings,generateSecuredApiKey:l.generateSecuredApiKey,getSecuredApiKeyRemainingValidity:l.getSecuredApiKeyRemainingValidity,destroy:u.destroy,initIndex:e=>t=>l.initIndex(e)(t,{methods:{batch:l.batch,delete:l.deleteIndex,getObject:l.getObject,getObjects:l.getObjects,saveObject:l.saveObject,saveObjects:l.saveObjects,search:l.search,searchForFacetValues:l.searchForFacetValues,waitTask:l.waitTask,setSettings:l.setSettings,getSettings:l.getSettings,partialUpdateObject:l.partialUpdateObject,partialUpdateObjects:l.partialUpdateObjects,deleteObject:l.deleteObject,deleteObjects:l.deleteObjects,deleteBy:l.deleteBy,clearObjects:l.clearObjects,browseObjects:l.browseObjects,getObjectPosition:l.getObjectPosition,findObject:l.findObject,exists:l.exists,saveSynonym:l.saveSynonym,saveSynonyms:l.saveSynonyms,getSynonym:l.getSynonym,searchSynonyms:l.searchSynonyms,browseSynonyms:l.browseSynonyms,deleteSynonym:l.deleteSynonym,clearSynonyms:l.clearSynonyms,replaceAllObjects:l.replaceAllObjects,replaceAllSynonyms:l.replaceAllSynonyms,searchRules:l.searchRules,getRule:l.getRule,deleteRule:l.deleteRule,saveRule:l.saveRule,saveRules:l.saveRules,replaceAllRules:l.replaceAllRules,browseRules:l.browseRules,clearRules:l.clearRules}}),initAnalytics:()=>e=>o.createAnalyticsClient({...d,...e,methods:{addABTest:o.addABTest,getABTest:o.getABTest,getABTests:o.getABTests,stopABTest:o.stopABTest,deleteABTest:o.deleteABTest}}),initRecommendation:()=>e=>a.createRecommendationClient({...d,...e,methods:{getPersonalizationStrategy:a.getPersonalizationStrategy,setPersonalizationStrategy:a.setPersonalizationStrategy}})}})}d.version=u.version,e.exports=d},4410:(e,t,n)=>{const r=n(8774);e.exports=r,e.exports.default=r},7589:e=>{"use strict";const t=e.exports;e.exports.default=t;const n="[",r="]",i="",o=";",u="Apple_Terminal"===process.env.TERM_PROGRAM;t.cursorTo=(e,t)=>{if("number"!=typeof e)throw new TypeError("The `x` argument is required");return"number"!=typeof t?n+(e+1)+"G":n+(t+1)+";"+(e+1)+"H"},t.cursorMove=(e,t)=>{if("number"!=typeof e)throw new TypeError("The `x` argument is required");let r="";return e<0?r+=n+-e+"D":e>0&&(r+=n+e+"C"),t<0?r+=n+-t+"A":t>0&&(r+=n+t+"B"),r},t.cursorUp=(e=1)=>n+e+"A",t.cursorDown=(e=1)=>n+e+"B",t.cursorForward=(e=1)=>n+e+"C",t.cursorBackward=(e=1)=>n+e+"D",t.cursorLeft="",t.cursorSavePosition=u?"7":"",t.cursorRestorePosition=u?"8":"",t.cursorGetPosition="",t.cursorNextLine="",t.cursorPrevLine="",t.cursorHide="[?25l",t.cursorShow="[?25h",t.eraseLines=e=>{let n="";for(let r=0;r[r,"8",o,o,t,i,e,r,"8",o,o,i].join(""),t.image=(e,t={})=>{let n=r+"1337;File=inline=1";return t.width&&(n+=";width="+t.width),t.height&&(n+=";height="+t.height),!1===t.preserveAspectRatio&&(n+=";preserveAspectRatio=0"),n+":"+e.toString("base64")+i},t.iTerm={setCwd:(e=process.cwd())=>`${r}50;CurrentDir=${e}${i}`,annotation:(e,t={})=>{let n=r+"1337;";const o=void 0!==t.x,u=void 0!==t.y;if((o||u)&&(!o||!u||void 0===t.length))throw new Error("`x`, `y` and `length` must be defined when `x` or `y` is defined");return e=e.replace(/\|/g,""),n+=t.isHidden?"AddHiddenAnnotation=":"AddAnnotation=",t.length>0?n+=(o?[e,t.length,t.x,t.y]:[t.length,e]).join("|"):n+=e,n+i}}},5378:e=>{"use strict";e.exports=e=>{e=Object.assign({onlyFirst:!1},e);const t=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(t,e.onlyFirst?void 0:"g")}},1337:e=>{"use strict";e.exports=({onlyFirst:e=!1}={})=>{const t=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(t,e?void 0:"g")}},8483:(e,t,n)=>{"use strict";e=n.nmd(e);const r=(e,t)=>(...n)=>`[${e(...n)+t}m`,i=(e,t)=>(...n)=>{const r=e(...n);return`[${38+t};5;${r}m`},o=(e,t)=>(...n)=>{const r=e(...n);return`[${38+t};2;${r[0]};${r[1]};${r[2]}m`},u=e=>e,a=(e,t,n)=>[e,t,n],l=(e,t,n)=>{Object.defineProperty(e,t,{get:()=>{const r=n();return Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0}),r},enumerable:!0,configurable:!0})};let s;const c=(e,t,r,i)=>{void 0===s&&(s=n(2744));const o=i?10:0,u={};for(const[n,i]of Object.entries(s)){const a="ansi16"===n?"ansi":n;n===t?u[a]=e(r,o):"object"==typeof i&&(u[a]=e(i[t],o))}return u};Object.defineProperty(e,"exports",{enumerable:!0,get:function(){const e=new Map,t={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};t.color.gray=t.color.blackBright,t.bgColor.bgGray=t.bgColor.bgBlackBright,t.color.grey=t.color.blackBright,t.bgColor.bgGrey=t.bgColor.bgBlackBright;for(const[n,r]of Object.entries(t)){for(const[n,i]of Object.entries(r))t[n]={open:`[${i[0]}m`,close:`[${i[1]}m`},r[n]=t[n],e.set(i[0],i[1]);Object.defineProperty(t,n,{value:r,enumerable:!1})}return Object.defineProperty(t,"codes",{value:e,enumerable:!1}),t.color.close="",t.bgColor.close="",l(t.color,"ansi",()=>c(r,"ansi16",u,!1)),l(t.color,"ansi256",()=>c(i,"ansi256",u,!1)),l(t.color,"ansi16m",()=>c(o,"rgb",a,!1)),l(t.bgColor,"ansi",()=>c(r,"ansi16",u,!0)),l(t.bgColor,"ansi256",()=>c(i,"ansi256",u,!0)),l(t.bgColor,"ansi16m",()=>c(o,"rgb",a,!0)),t}})},5640:e=>{"use strict";e.exports=e=>e&&e.exact?new RegExp("^[\ud800-\udbff][\udc00-\udfff]$"):new RegExp("[\ud800-\udbff][\udc00-\udfff]","g")},409:e=>{"use strict";e.exports=e=>e&&e.exact?new RegExp("^[\ud800-\udbff][\udc00-\udfff]$"):new RegExp("[\ud800-\udbff][\udc00-\udfff]","g")},2633:e=>{"use strict";e.exports=(e,{include:t,exclude:n}={})=>{const r=e=>{const r=t=>"string"==typeof t?e===t:t.test(e);return t?t.some(r):!n||!n.some(r)};for(const[t,n]of(e=>{const t=new Set;do{for(const n of Reflect.ownKeys(e))t.add([e,n])}while((e=Reflect.getPrototypeOf(e))&&e!==Object.prototype);return t})(e.constructor.prototype)){if("constructor"===n||!r(n))continue;const i=Reflect.getOwnPropertyDescriptor(t,n);i&&"function"==typeof i.value&&(e[n]=e[n].bind(e))}return e}},5882:(e,t,n)=>{"use strict";const r=n(8483),{stdout:i,stderr:o}=n(9428),{stringReplaceAll:u,stringEncaseCRLFWithFirstIndex:a}=n(3327),l=["ansi","ansi","ansi256","ansi16m"],s=Object.create(null);class c{constructor(e){return f(e)}}const f=e=>{const t={};return((e,t={})=>{if(t.level>3||t.level<0)throw new Error("The `level` option should be an integer from 0 to 3");const n=i?i.level:0;e.level=void 0===t.level?n:t.level})(t,e),t.template=(...e)=>_(t.template,...e),Object.setPrototypeOf(t,d.prototype),Object.setPrototypeOf(t.template,t),t.template.constructor=()=>{throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.")},t.template.Instance=c,t.template};function d(e){return f(e)}for(const[e,t]of Object.entries(r))s[e]={get(){const n=m(this,v(t.open,t.close,this._styler),this._isEmpty);return Object.defineProperty(this,e,{value:n}),n}};s.visible={get(){const e=m(this,this._styler,!0);return Object.defineProperty(this,"visible",{value:e}),e}};const p=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(const e of p)s[e]={get(){const{level:t}=this;return function(...n){const i=v(r.color[l[t]][e](...n),r.color.close,this._styler);return m(this,i,this._isEmpty)}}};for(const e of p){s["bg"+e[0].toUpperCase()+e.slice(1)]={get(){const{level:t}=this;return function(...n){const i=v(r.bgColor[l[t]][e](...n),r.bgColor.close,this._styler);return m(this,i,this._isEmpty)}}}}const h=Object.defineProperties(()=>{},{...s,level:{enumerable:!0,get(){return this._generator.level},set(e){this._generator.level=e}}}),v=(e,t,n)=>{let r,i;return void 0===n?(r=e,i=t):(r=n.openAll+e,i=t+n.closeAll),{open:e,close:t,openAll:r,closeAll:i,parent:n}},m=(e,t,n)=>{const r=(...e)=>g(r,1===e.length?""+e[0]:e.join(" "));return r.__proto__=h,r._generator=e,r._styler=t,r._isEmpty=n,r},g=(e,t)=>{if(e.level<=0||!t)return e._isEmpty?"":t;let n=e._styler;if(void 0===n)return t;const{openAll:r,closeAll:i}=n;if(-1!==t.indexOf(""))for(;void 0!==n;)t=u(t,n.close,n.open),n=n.parent;const o=t.indexOf("\n");return-1!==o&&(t=a(t,i,r,o)),r+t+i};let y;const _=(e,...t)=>{const[r]=t;if(!Array.isArray(r))return t.join(" ");const i=t.slice(1),o=[r.raw[0]];for(let e=1;e{"use strict";const t=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,n=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,r=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,i=/\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.)|([^\\])/gi,o=new Map([["n","\n"],["r","\r"],["t","\t"],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e",""],["a",""]]);function u(e){const t="u"===e[0],n="{"===e[1];return t&&!n&&5===e.length||"x"===e[0]&&3===e.length?String.fromCharCode(parseInt(e.slice(1),16)):t&&n?String.fromCodePoint(parseInt(e.slice(2,-1),16)):o.get(e)||e}function a(e,t){const n=[],o=t.trim().split(/\s*,\s*/g);let a;for(const t of o){const o=Number(t);if(Number.isNaN(o)){if(!(a=t.match(r)))throw new Error(`Invalid Chalk template style argument: ${t} (in style '${e}')`);n.push(a[2].replace(i,(e,t,n)=>t?u(t):n))}else n.push(o)}return n}function l(e){n.lastIndex=0;const t=[];let r;for(;null!==(r=n.exec(e));){const e=r[1];if(r[2]){const n=a(e,r[2]);t.push([e].concat(n))}else t.push([e])}return t}function s(e,t){const n={};for(const e of t)for(const t of e.styles)n[t[0]]=e.inverse?null:t.slice(1);let r=e;for(const[e,t]of Object.entries(n))if(Array.isArray(t)){if(!(e in r))throw new Error("Unknown Chalk style: "+e);r=t.length>0?r[e](...t):r[e]}return r}e.exports=(e,n)=>{const r=[],i=[];let o=[];if(n.replace(t,(t,n,a,c,f,d)=>{if(n)o.push(u(n));else if(c){const t=o.join("");o=[],i.push(0===r.length?t:s(e,r)(t)),r.push({inverse:a,styles:l(c)})}else if(f){if(0===r.length)throw new Error("Found extraneous } in Chalk template literal");i.push(s(e,r)(o.join(""))),o=[],r.pop()}else o.push(d)}),i.push(o.join("")),r.length>0){const e=`Chalk template literal is missing ${r.length} closing bracket${1===r.length?"":"s"} (\`}\`)`;throw new Error(e)}return i.join("")}},3327:e=>{"use strict";e.exports={stringReplaceAll:(e,t,n)=>{let r=e.indexOf(t);if(-1===r)return e;const i=t.length;let o=0,u="";do{u+=e.substr(o,r-o)+t+n,o=r+i,r=e.indexOf(t,o)}while(-1!==r);return u+=e.substr(o),u},stringEncaseCRLFWithFirstIndex:(e,t,n,r)=>{let i=0,o="";do{const u="\r"===e[r-1];o+=e.substr(i,(u?r-1:r)-i)+t+(u?"\r\n":"\n")+n,i=r+1,r=e.indexOf("\n",i)}while(-1!==r);return o+=e.substr(i),o}}},1525:(e,t,n)=>{"use strict";const r=n(8483),{stdout:i,stderr:o}=n(9428),{stringReplaceAll:u,stringEncaseCRLFWithFirstIndex:a}=n(6539),{isArray:l}=Array,s=["ansi","ansi","ansi256","ansi16m"],c=Object.create(null);class f{constructor(e){return d(e)}}const d=e=>{const t={};return((e,t={})=>{if(t.level&&!(Number.isInteger(t.level)&&t.level>=0&&t.level<=3))throw new Error("The `level` option should be an integer from 0 to 3");const n=i?i.level:0;e.level=void 0===t.level?n:t.level})(t,e),t.template=(...e)=>b(t.template,...e),Object.setPrototypeOf(t,p.prototype),Object.setPrototypeOf(t.template,t),t.template.constructor=()=>{throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.")},t.template.Instance=f,t.template};function p(e){return d(e)}for(const[e,t]of Object.entries(r))c[e]={get(){const n=g(this,m(t.open,t.close,this._styler),this._isEmpty);return Object.defineProperty(this,e,{value:n}),n}};c.visible={get(){const e=g(this,this._styler,!0);return Object.defineProperty(this,"visible",{value:e}),e}};const h=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(const e of h)c[e]={get(){const{level:t}=this;return function(...n){const i=m(r.color[s[t]][e](...n),r.color.close,this._styler);return g(this,i,this._isEmpty)}}};for(const e of h){c["bg"+e[0].toUpperCase()+e.slice(1)]={get(){const{level:t}=this;return function(...n){const i=m(r.bgColor[s[t]][e](...n),r.bgColor.close,this._styler);return g(this,i,this._isEmpty)}}}}const v=Object.defineProperties(()=>{},{...c,level:{enumerable:!0,get(){return this._generator.level},set(e){this._generator.level=e}}}),m=(e,t,n)=>{let r,i;return void 0===n?(r=e,i=t):(r=n.openAll+e,i=t+n.closeAll),{open:e,close:t,openAll:r,closeAll:i,parent:n}},g=(e,t,n)=>{const r=(...e)=>l(e[0])&&l(e[0].raw)?y(r,b(r,...e)):y(r,1===e.length?""+e[0]:e.join(" "));return Object.setPrototypeOf(r,v),r._generator=e,r._styler=t,r._isEmpty=n,r},y=(e,t)=>{if(e.level<=0||!t)return e._isEmpty?"":t;let n=e._styler;if(void 0===n)return t;const{openAll:r,closeAll:i}=n;if(-1!==t.indexOf(""))for(;void 0!==n;)t=u(t,n.close,n.open),n=n.parent;const o=t.indexOf("\n");return-1!==o&&(t=a(t,i,r,o)),r+t+i};let _;const b=(e,...t)=>{const[r]=t;if(!l(r)||!l(r.raw))return t.join(" ");const i=t.slice(1),o=[r.raw[0]];for(let e=1;e{"use strict";const t=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,n=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,r=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,i=/\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi,o=new Map([["n","\n"],["r","\r"],["t","\t"],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e",""],["a",""]]);function u(e){const t="u"===e[0],n="{"===e[1];return t&&!n&&5===e.length||"x"===e[0]&&3===e.length?String.fromCharCode(parseInt(e.slice(1),16)):t&&n?String.fromCodePoint(parseInt(e.slice(2,-1),16)):o.get(e)||e}function a(e,t){const n=[],o=t.trim().split(/\s*,\s*/g);let a;for(const t of o){const o=Number(t);if(Number.isNaN(o)){if(!(a=t.match(r)))throw new Error(`Invalid Chalk template style argument: ${t} (in style '${e}')`);n.push(a[2].replace(i,(e,t,n)=>t?u(t):n))}else n.push(o)}return n}function l(e){n.lastIndex=0;const t=[];let r;for(;null!==(r=n.exec(e));){const e=r[1];if(r[2]){const n=a(e,r[2]);t.push([e].concat(n))}else t.push([e])}return t}function s(e,t){const n={};for(const e of t)for(const t of e.styles)n[t[0]]=e.inverse?null:t.slice(1);let r=e;for(const[e,t]of Object.entries(n))if(Array.isArray(t)){if(!(e in r))throw new Error("Unknown Chalk style: "+e);r=t.length>0?r[e](...t):r[e]}return r}e.exports=(e,n)=>{const r=[],i=[];let o=[];if(n.replace(t,(t,n,a,c,f,d)=>{if(n)o.push(u(n));else if(c){const t=o.join("");o=[],i.push(0===r.length?t:s(e,r)(t)),r.push({inverse:a,styles:l(c)})}else if(f){if(0===r.length)throw new Error("Found extraneous } in Chalk template literal");i.push(s(e,r)(o.join(""))),o=[],r.pop()}else o.push(d)}),i.push(o.join("")),r.length>0){const e=`Chalk template literal is missing ${r.length} closing bracket${1===r.length?"":"s"} (\`}\`)`;throw new Error(e)}return i.join("")}},6539:e=>{"use strict";e.exports={stringReplaceAll:(e,t,n)=>{let r=e.indexOf(t);if(-1===r)return e;const i=t.length;let o=0,u="";do{u+=e.substr(o,r-o)+t+n,o=r+i,r=e.indexOf(t,o)}while(-1!==r);return u+=e.substr(o),u},stringEncaseCRLFWithFirstIndex:(e,t,n,r)=>{let i=0,o="";do{const u="\r"===e[r-1];o+=e.substr(i,(u?r-1:r)-i)+t+(u?"\r\n":"\n")+n,i=r+1,r=e.indexOf("\n",i)}while(-1!==r);return o+=e.substr(i),o}}},5864:(e,t,n)=>{"use strict";var r=n(5832),i=process.env;function o(e){return"string"==typeof e?!!i[e]:Object.keys(e).every((function(t){return i[t]===e[t]}))}Object.defineProperty(t,"_vendors",{value:r.map((function(e){return e.constant}))}),t.name=null,t.isPR=null,r.forEach((function(e){var n=(Array.isArray(e.env)?e.env:[e.env]).every((function(e){return o(e)}));if(t[e.constant]=n,n)switch(t.name=e.name,typeof e.pr){case"string":t.isPR=!!i[e.pr];break;case"object":"env"in e.pr?t.isPR=e.pr.env in i&&i[e.pr.env]!==e.pr.ne:"any"in e.pr?t.isPR=e.pr.any.some((function(e){return!!i[e]})):t.isPR=o(e.pr);break;default:t.isPR=null}})),t.isCI=!!(i.CI||i.CONTINUOUS_INTEGRATION||i.BUILD_NUMBER||i.RUN_ID||t.name)},5832:e=>{"use strict";e.exports=JSON.parse('[{"name":"AppVeyor","constant":"APPVEYOR","env":"APPVEYOR","pr":"APPVEYOR_PULL_REQUEST_NUMBER"},{"name":"Azure Pipelines","constant":"AZURE_PIPELINES","env":"SYSTEM_TEAMFOUNDATIONCOLLECTIONURI","pr":"SYSTEM_PULLREQUEST_PULLREQUESTID"},{"name":"Bamboo","constant":"BAMBOO","env":"bamboo_planKey"},{"name":"Bitbucket Pipelines","constant":"BITBUCKET","env":"BITBUCKET_COMMIT","pr":"BITBUCKET_PR_ID"},{"name":"Bitrise","constant":"BITRISE","env":"BITRISE_IO","pr":"BITRISE_PULL_REQUEST"},{"name":"Buddy","constant":"BUDDY","env":"BUDDY_WORKSPACE_ID","pr":"BUDDY_EXECUTION_PULL_REQUEST_ID"},{"name":"Buildkite","constant":"BUILDKITE","env":"BUILDKITE","pr":{"env":"BUILDKITE_PULL_REQUEST","ne":"false"}},{"name":"CircleCI","constant":"CIRCLE","env":"CIRCLECI","pr":"CIRCLE_PULL_REQUEST"},{"name":"Cirrus CI","constant":"CIRRUS","env":"CIRRUS_CI","pr":"CIRRUS_PR"},{"name":"AWS CodeBuild","constant":"CODEBUILD","env":"CODEBUILD_BUILD_ARN"},{"name":"Codeship","constant":"CODESHIP","env":{"CI_NAME":"codeship"}},{"name":"Drone","constant":"DRONE","env":"DRONE","pr":{"DRONE_BUILD_EVENT":"pull_request"}},{"name":"dsari","constant":"DSARI","env":"DSARI"},{"name":"GitLab CI","constant":"GITLAB","env":"GITLAB_CI"},{"name":"GoCD","constant":"GOCD","env":"GO_PIPELINE_LABEL"},{"name":"Hudson","constant":"HUDSON","env":"HUDSON_URL"},{"name":"Jenkins","constant":"JENKINS","env":["JENKINS_URL","BUILD_ID"],"pr":{"any":["ghprbPullId","CHANGE_ID"]}},{"name":"Magnum CI","constant":"MAGNUM","env":"MAGNUM"},{"name":"Netlify CI","constant":"NETLIFY","env":"NETLIFY_BUILD_BASE","pr":{"env":"PULL_REQUEST","ne":"false"}},{"name":"Sail CI","constant":"SAIL","env":"SAILCI","pr":"SAIL_PULL_REQUEST_NUMBER"},{"name":"Semaphore","constant":"SEMAPHORE","env":"SEMAPHORE","pr":"PULL_REQUEST_NUMBER"},{"name":"Shippable","constant":"SHIPPABLE","env":"SHIPPABLE","pr":{"IS_PULL_REQUEST":"true"}},{"name":"Solano CI","constant":"SOLANO","env":"TDDIUM","pr":"TDDIUM_PR_ID"},{"name":"Strider CD","constant":"STRIDER","env":"STRIDER"},{"name":"TaskCluster","constant":"TASKCLUSTER","env":["TASK_ID","RUN_ID"]},{"name":"TeamCity","constant":"TEAMCITY","env":"TEAMCITY_VERSION"},{"name":"Travis CI","constant":"TRAVIS","env":"TRAVIS","pr":{"env":"TRAVIS_PULL_REQUEST","ne":"false"}}]')},4163:e=>{"use strict";e.exports=JSON.parse('{"single":{"topLeft":"┌","topRight":"┐","bottomRight":"┘","bottomLeft":"└","vertical":"│","horizontal":"─"},"double":{"topLeft":"╔","topRight":"╗","bottomRight":"╝","bottomLeft":"╚","vertical":"║","horizontal":"═"},"round":{"topLeft":"╭","topRight":"╮","bottomRight":"╯","bottomLeft":"╰","vertical":"│","horizontal":"─"},"bold":{"topLeft":"┏","topRight":"┓","bottomRight":"┛","bottomLeft":"┗","vertical":"┃","horizontal":"━"},"singleDouble":{"topLeft":"╓","topRight":"╖","bottomRight":"╜","bottomLeft":"╙","vertical":"║","horizontal":"─"},"doubleSingle":{"topLeft":"╒","topRight":"╕","bottomRight":"╛","bottomLeft":"╘","vertical":"│","horizontal":"═"},"classic":{"topLeft":"+","topRight":"+","bottomRight":"+","bottomLeft":"+","vertical":"|","horizontal":"-"}}')},4097:(e,t,n)=>{"use strict";const r=n(4163);e.exports=r,e.exports.default=r},1696:(e,t,n)=>{"use strict";const r=n(3390);let i=!1;t.show=(e=process.stderr)=>{e.isTTY&&(i=!1,e.write("[?25h"))},t.hide=(e=process.stderr)=>{e.isTTY&&(r(),i=!0,e.write("[?25l"))},t.toggle=(e,n)=>{void 0!==e&&(i=e),i?t.show(n):t.hide(n)}},5301:(e,t,n)=>{"use strict";const r=n(1566),i=n(5043);function o(e,t,n){if(" "===e.charAt(t))return t;for(let r=1;r<=3;r++)if(n){if(" "===e.charAt(t+r))return t+r}else if(" "===e.charAt(t-r))return t-r;return t}e.exports=(e,t,n)=>{n={position:"end",preferTruncationOnSpace:!1,...n};const{position:u,space:a,preferTruncationOnSpace:l}=n;let s="…",c=1;if("string"!=typeof e)throw new TypeError("Expected `input` to be a string, got "+typeof e);if("number"!=typeof t)throw new TypeError("Expected `columns` to be a number, got "+typeof t);if(t<1)return"";if(1===t)return s;const f=i(e);if(f<=t)return e;if("start"===u){if(l){const n=o(e,f-t+1,!0);return s+r(e,n,f).trim()}return!0===a&&(s+=" ",c=2),s+r(e,f-t+c,f)}if("middle"===u){!0===a&&(s=" "+s+" ",c=3);const n=Math.floor(t/2);if(l){const i=o(e,n),u=o(e,f-(t-n)+1,!0);return r(e,0,i)+s+r(e,u,f).trim()}return r(e,0,n)+s+r(e,f-(t-n)+c,f)}if("end"===u){if(l){const n=o(e,t-1);return r(e,0,n)+s}return!0===a&&(s=" "+s,c=2),r(e,0,t-c)+s}throw new Error("Expected `options.position` to be either `start`, `middle` or `end`, got "+u)}},9908:(e,t,n)=>{"use strict";const r=n(3287);e.exports=(e,t,n)=>{if("string"!=typeof e)throw new TypeError("Source code is missing.");if(!t||t<1)throw new TypeError("Line number must start from `1`.");if(!(t>(e=r(e).split(/\r?\n/)).length))return((e,t)=>{const n=[],r=e+t;for(let i=e-t;i<=r;i++)n.push(i);return n})(t,(n={around:3,...n}).around).filter(t=>void 0!==e[t-1]).map(t=>({line:t,value:e[t-1]}))}},5311:(e,t,n)=>{const r=n(3300),i={};for(const e of Object.keys(r))i[r[e]]=e;const o={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};e.exports=o;for(const e of Object.keys(o)){if(!("channels"in o[e]))throw new Error("missing channels property: "+e);if(!("labels"in o[e]))throw new Error("missing channel labels property: "+e);if(o[e].labels.length!==o[e].channels)throw new Error("channel and label counts mismatch: "+e);const{channels:t,labels:n}=o[e];delete o[e].channels,delete o[e].labels,Object.defineProperty(o[e],"channels",{value:t}),Object.defineProperty(o[e],"labels",{value:n})}o.rgb.hsl=function(e){const t=e[0]/255,n=e[1]/255,r=e[2]/255,i=Math.min(t,n,r),o=Math.max(t,n,r),u=o-i;let a,l;o===i?a=0:t===o?a=(n-r)/u:n===o?a=2+(r-t)/u:r===o&&(a=4+(t-n)/u),a=Math.min(60*a,360),a<0&&(a+=360);const s=(i+o)/2;return l=o===i?0:s<=.5?u/(o+i):u/(2-o-i),[a,100*l,100*s]},o.rgb.hsv=function(e){let t,n,r,i,o;const u=e[0]/255,a=e[1]/255,l=e[2]/255,s=Math.max(u,a,l),c=s-Math.min(u,a,l),f=function(e){return(s-e)/6/c+.5};return 0===c?(i=0,o=0):(o=c/s,t=f(u),n=f(a),r=f(l),u===s?i=r-n:a===s?i=1/3+t-r:l===s&&(i=2/3+n-t),i<0?i+=1:i>1&&(i-=1)),[360*i,100*o,100*s]},o.rgb.hwb=function(e){const t=e[0],n=e[1];let r=e[2];const i=o.rgb.hsl(e)[0],u=1/255*Math.min(t,Math.min(n,r));return r=1-1/255*Math.max(t,Math.max(n,r)),[i,100*u,100*r]},o.rgb.cmyk=function(e){const t=e[0]/255,n=e[1]/255,r=e[2]/255,i=Math.min(1-t,1-n,1-r);return[100*((1-t-i)/(1-i)||0),100*((1-n-i)/(1-i)||0),100*((1-r-i)/(1-i)||0),100*i]},o.rgb.keyword=function(e){const t=i[e];if(t)return t;let n,o=1/0;for(const t of Object.keys(r)){const i=r[t],l=(a=i,((u=e)[0]-a[0])**2+(u[1]-a[1])**2+(u[2]-a[2])**2);l.04045?((t+.055)/1.055)**2.4:t/12.92,n=n>.04045?((n+.055)/1.055)**2.4:n/12.92,r=r>.04045?((r+.055)/1.055)**2.4:r/12.92;return[100*(.4124*t+.3576*n+.1805*r),100*(.2126*t+.7152*n+.0722*r),100*(.0193*t+.1192*n+.9505*r)]},o.rgb.lab=function(e){const t=o.rgb.xyz(e);let n=t[0],r=t[1],i=t[2];n/=95.047,r/=100,i/=108.883,n=n>.008856?n**(1/3):7.787*n+16/116,r=r>.008856?r**(1/3):7.787*r+16/116,i=i>.008856?i**(1/3):7.787*i+16/116;return[116*r-16,500*(n-r),200*(r-i)]},o.hsl.rgb=function(e){const t=e[0]/360,n=e[1]/100,r=e[2]/100;let i,o,u;if(0===n)return u=255*r,[u,u,u];i=r<.5?r*(1+n):r+n-r*n;const a=2*r-i,l=[0,0,0];for(let e=0;e<3;e++)o=t+1/3*-(e-1),o<0&&o++,o>1&&o--,u=6*o<1?a+6*(i-a)*o:2*o<1?i:3*o<2?a+(i-a)*(2/3-o)*6:a,l[e]=255*u;return l},o.hsl.hsv=function(e){const t=e[0];let n=e[1]/100,r=e[2]/100,i=n;const o=Math.max(r,.01);r*=2,n*=r<=1?r:2-r,i*=o<=1?o:2-o;return[t,100*(0===r?2*i/(o+i):2*n/(r+n)),100*((r+n)/2)]},o.hsv.rgb=function(e){const t=e[0]/60,n=e[1]/100;let r=e[2]/100;const i=Math.floor(t)%6,o=t-Math.floor(t),u=255*r*(1-n),a=255*r*(1-n*o),l=255*r*(1-n*(1-o));switch(r*=255,i){case 0:return[r,l,u];case 1:return[a,r,u];case 2:return[u,r,l];case 3:return[u,a,r];case 4:return[l,u,r];case 5:return[r,u,a]}},o.hsv.hsl=function(e){const t=e[0],n=e[1]/100,r=e[2]/100,i=Math.max(r,.01);let o,u;u=(2-n)*r;const a=(2-n)*i;return o=n*i,o/=a<=1?a:2-a,o=o||0,u/=2,[t,100*o,100*u]},o.hwb.rgb=function(e){const t=e[0]/360;let n=e[1]/100,r=e[2]/100;const i=n+r;let o;i>1&&(n/=i,r/=i);const u=Math.floor(6*t),a=1-r;o=6*t-u,0!=(1&u)&&(o=1-o);const l=n+o*(a-n);let s,c,f;switch(u){default:case 6:case 0:s=a,c=l,f=n;break;case 1:s=l,c=a,f=n;break;case 2:s=n,c=a,f=l;break;case 3:s=n,c=l,f=a;break;case 4:s=l,c=n,f=a;break;case 5:s=a,c=n,f=l}return[255*s,255*c,255*f]},o.cmyk.rgb=function(e){const t=e[0]/100,n=e[1]/100,r=e[2]/100,i=e[3]/100;return[255*(1-Math.min(1,t*(1-i)+i)),255*(1-Math.min(1,n*(1-i)+i)),255*(1-Math.min(1,r*(1-i)+i))]},o.xyz.rgb=function(e){const t=e[0]/100,n=e[1]/100,r=e[2]/100;let i,o,u;return i=3.2406*t+-1.5372*n+-.4986*r,o=-.9689*t+1.8758*n+.0415*r,u=.0557*t+-.204*n+1.057*r,i=i>.0031308?1.055*i**(1/2.4)-.055:12.92*i,o=o>.0031308?1.055*o**(1/2.4)-.055:12.92*o,u=u>.0031308?1.055*u**(1/2.4)-.055:12.92*u,i=Math.min(Math.max(0,i),1),o=Math.min(Math.max(0,o),1),u=Math.min(Math.max(0,u),1),[255*i,255*o,255*u]},o.xyz.lab=function(e){let t=e[0],n=e[1],r=e[2];t/=95.047,n/=100,r/=108.883,t=t>.008856?t**(1/3):7.787*t+16/116,n=n>.008856?n**(1/3):7.787*n+16/116,r=r>.008856?r**(1/3):7.787*r+16/116;return[116*n-16,500*(t-n),200*(n-r)]},o.lab.xyz=function(e){let t,n,r;n=(e[0]+16)/116,t=e[1]/500+n,r=n-e[2]/200;const i=n**3,o=t**3,u=r**3;return n=i>.008856?i:(n-16/116)/7.787,t=o>.008856?o:(t-16/116)/7.787,r=u>.008856?u:(r-16/116)/7.787,t*=95.047,n*=100,r*=108.883,[t,n,r]},o.lab.lch=function(e){const t=e[0],n=e[1],r=e[2];let i;i=360*Math.atan2(r,n)/2/Math.PI,i<0&&(i+=360);return[t,Math.sqrt(n*n+r*r),i]},o.lch.lab=function(e){const t=e[0],n=e[1],r=e[2]/360*2*Math.PI;return[t,n*Math.cos(r),n*Math.sin(r)]},o.rgb.ansi16=function(e,t=null){const[n,r,i]=e;let u=null===t?o.rgb.hsv(e)[2]:t;if(u=Math.round(u/50),0===u)return 30;let a=30+(Math.round(i/255)<<2|Math.round(r/255)<<1|Math.round(n/255));return 2===u&&(a+=60),a},o.hsv.ansi16=function(e){return o.rgb.ansi16(o.hsv.rgb(e),e[2])},o.rgb.ansi256=function(e){const t=e[0],n=e[1],r=e[2];if(t===n&&n===r)return t<8?16:t>248?231:Math.round((t-8)/247*24)+232;return 16+36*Math.round(t/255*5)+6*Math.round(n/255*5)+Math.round(r/255*5)},o.ansi16.rgb=function(e){let t=e%10;if(0===t||7===t)return e>50&&(t+=3.5),t=t/10.5*255,[t,t,t];const n=.5*(1+~~(e>50));return[(1&t)*n*255,(t>>1&1)*n*255,(t>>2&1)*n*255]},o.ansi256.rgb=function(e){if(e>=232){const t=10*(e-232)+8;return[t,t,t]}let t;e-=16;return[Math.floor(e/36)/5*255,Math.floor((t=e%36)/6)/5*255,t%6/5*255]},o.rgb.hex=function(e){const t=(((255&Math.round(e[0]))<<16)+((255&Math.round(e[1]))<<8)+(255&Math.round(e[2]))).toString(16).toUpperCase();return"000000".substring(t.length)+t},o.hex.rgb=function(e){const t=e.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!t)return[0,0,0];let n=t[0];3===t[0].length&&(n=n.split("").map(e=>e+e).join(""));const r=parseInt(n,16);return[r>>16&255,r>>8&255,255&r]},o.rgb.hcg=function(e){const t=e[0]/255,n=e[1]/255,r=e[2]/255,i=Math.max(Math.max(t,n),r),o=Math.min(Math.min(t,n),r),u=i-o;let a,l;return a=u<1?o/(1-u):0,l=u<=0?0:i===t?(n-r)/u%6:i===n?2+(r-t)/u:4+(t-n)/u,l/=6,l%=1,[360*l,100*u,100*a]},o.hsl.hcg=function(e){const t=e[1]/100,n=e[2]/100,r=n<.5?2*t*n:2*t*(1-n);let i=0;return r<1&&(i=(n-.5*r)/(1-r)),[e[0],100*r,100*i]},o.hsv.hcg=function(e){const t=e[1]/100,n=e[2]/100,r=t*n;let i=0;return r<1&&(i=(n-r)/(1-r)),[e[0],100*r,100*i]},o.hcg.rgb=function(e){const t=e[0]/360,n=e[1]/100,r=e[2]/100;if(0===n)return[255*r,255*r,255*r];const i=[0,0,0],o=t%1*6,u=o%1,a=1-u;let l=0;switch(Math.floor(o)){case 0:i[0]=1,i[1]=u,i[2]=0;break;case 1:i[0]=a,i[1]=1,i[2]=0;break;case 2:i[0]=0,i[1]=1,i[2]=u;break;case 3:i[0]=0,i[1]=a,i[2]=1;break;case 4:i[0]=u,i[1]=0,i[2]=1;break;default:i[0]=1,i[1]=0,i[2]=a}return l=(1-n)*r,[255*(n*i[0]+l),255*(n*i[1]+l),255*(n*i[2]+l)]},o.hcg.hsv=function(e){const t=e[1]/100,n=t+e[2]/100*(1-t);let r=0;return n>0&&(r=t/n),[e[0],100*r,100*n]},o.hcg.hsl=function(e){const t=e[1]/100,n=e[2]/100*(1-t)+.5*t;let r=0;return n>0&&n<.5?r=t/(2*n):n>=.5&&n<1&&(r=t/(2*(1-n))),[e[0],100*r,100*n]},o.hcg.hwb=function(e){const t=e[1]/100,n=t+e[2]/100*(1-t);return[e[0],100*(n-t),100*(1-n)]},o.hwb.hcg=function(e){const t=e[1]/100,n=1-e[2]/100,r=n-t;let i=0;return r<1&&(i=(n-r)/(1-r)),[e[0],100*r,100*i]},o.apple.rgb=function(e){return[e[0]/65535*255,e[1]/65535*255,e[2]/65535*255]},o.rgb.apple=function(e){return[e[0]/255*65535,e[1]/255*65535,e[2]/255*65535]},o.gray.rgb=function(e){return[e[0]/100*255,e[0]/100*255,e[0]/100*255]},o.gray.hsl=function(e){return[0,0,e[0]]},o.gray.hsv=o.gray.hsl,o.gray.hwb=function(e){return[0,100,e[0]]},o.gray.cmyk=function(e){return[0,0,0,e[0]]},o.gray.lab=function(e){return[e[0],0,0]},o.gray.hex=function(e){const t=255&Math.round(e[0]/100*255),n=((t<<16)+(t<<8)+t).toString(16).toUpperCase();return"000000".substring(n.length)+n},o.rgb.gray=function(e){return[(e[0]+e[1]+e[2])/3/255*100]}},2744:(e,t,n)=>{const r=n(5311),i=n(8577),o={};Object.keys(r).forEach(e=>{o[e]={},Object.defineProperty(o[e],"channels",{value:r[e].channels}),Object.defineProperty(o[e],"labels",{value:r[e].labels});const t=i(e);Object.keys(t).forEach(n=>{const r=t[n];o[e][n]=function(e){const t=function(...t){const n=t[0];if(null==n)return n;n.length>1&&(t=n);const r=e(t);if("object"==typeof r)for(let e=r.length,t=0;t1&&(t=n),e(t))};return"conversion"in e&&(t.conversion=e.conversion),t}(r)})}),e.exports=o},8577:(e,t,n)=>{const r=n(5311);function i(e){const t=function(){const e={},t=Object.keys(r);for(let n=t.length,r=0;r{"use strict";e.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},3287:e=>{"use strict";e.exports=(e,t)=>e.replace(/^\t+/gm,e=>" ".repeat(e.length*(t||2)))},1013:e=>{"use strict";e.exports=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g}},8759:e=>{"use strict";const t=/[|\\{}()[\]^$+*?.-]/g;e.exports=e=>{if("string"!=typeof e)throw new TypeError("Expected a string");return e.replace(t,"\\$&")}},2918:e=>{"use strict";e.exports=(e,t=process.argv)=>{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),i=t.indexOf("--");return-1!==r&&(-1===i||r{"use strict";e.exports=(e,t=1,n)=>{if(n={indent:" ",includeEmptyLines:!1,...n},"string"!=typeof e)throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof e}\``);if("number"!=typeof t)throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof t}\``);if("string"!=typeof n.indent)throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof n.indent}\``);if(0===t)return e;const r=n.includeEmptyLines?/^/gm:/^(?!\s*$)/gm;return e.replace(r,n.indent.repeat(t))}},2738:(e,t,n)=>{"use strict";e.exports=n(5864).isCI},7347:e=>{"use strict";const t=e=>!Number.isNaN(e)&&(e>=4352&&(e<=4447||9001===e||9002===e||11904<=e&&e<=12871&&12351!==e||12880<=e&&e<=19903||19968<=e&&e<=42182||43360<=e&&e<=43388||44032<=e&&e<=55203||63744<=e&&e<=64255||65040<=e&&e<=65049||65072<=e&&e<=65131||65281<=e&&e<=65376||65504<=e&&e<=65510||110592<=e&&e<=110593||127488<=e&&e<=127569||131072<=e&&e<=262141));e.exports=t,e.exports.default=t},464:function(e,t,n){var r; -/** - * @license - * Lodash - * Copyright OpenJS Foundation and other contributors - * Released under MIT license - * Based on Underscore.js 1.8.3 - * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - */e=n.nmd(e),function(){var i="Expected a function",o="__lodash_placeholder__",u=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],a="[object Arguments]",l="[object Array]",s="[object Boolean]",c="[object Date]",f="[object Error]",d="[object Function]",p="[object GeneratorFunction]",h="[object Map]",v="[object Number]",m="[object Object]",g="[object RegExp]",y="[object Set]",_="[object String]",b="[object Symbol]",w="[object WeakMap]",E="[object ArrayBuffer]",D="[object DataView]",S="[object Float32Array]",C="[object Float64Array]",k="[object Int8Array]",T="[object Int16Array]",x="[object Int32Array]",A="[object Uint8Array]",O="[object Uint16Array]",P="[object Uint32Array]",I=/\b__p \+= '';/g,N=/\b(__p \+=) '' \+/g,M=/(__e\(.*?\)|\b__t\)) \+\n'';/g,R=/&(?:amp|lt|gt|quot|#39);/g,F=/[&<>"']/g,L=RegExp(R.source),B=RegExp(F.source),j=/<%-([\s\S]+?)%>/g,U=/<%([\s\S]+?)%>/g,z=/<%=([\s\S]+?)%>/g,W=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,H=/^\w*$/,V=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,q=/[\\^$.*+?()[\]{}|]/g,G=RegExp(q.source),$=/^\s+|\s+$/g,Y=/^\s+/,K=/\s+$/,X=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Q=/\{\n\/\* \[wrapped with (.+)\] \*/,J=/,? & /,Z=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,ee=/\\(\\)?/g,te=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,ne=/\w*$/,re=/^[-+]0x[0-9a-f]+$/i,ie=/^0b[01]+$/i,oe=/^\[object .+?Constructor\]$/,ue=/^0o[0-7]+$/i,ae=/^(?:0|[1-9]\d*)$/,le=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,se=/($^)/,ce=/['\n\r\u2028\u2029\\]/g,fe="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",de="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",pe="[\\ud800-\\udfff]",he="["+de+"]",ve="["+fe+"]",me="\\d+",ge="[\\u2700-\\u27bf]",ye="[a-z\\xdf-\\xf6\\xf8-\\xff]",_e="[^\\ud800-\\udfff"+de+me+"\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde]",be="\\ud83c[\\udffb-\\udfff]",we="[^\\ud800-\\udfff]",Ee="(?:\\ud83c[\\udde6-\\uddff]){2}",De="[\\ud800-\\udbff][\\udc00-\\udfff]",Se="[A-Z\\xc0-\\xd6\\xd8-\\xde]",Ce="(?:"+ye+"|"+_e+")",ke="(?:"+Se+"|"+_e+")",Te="(?:"+ve+"|"+be+")"+"?",xe="[\\ufe0e\\ufe0f]?"+Te+("(?:\\u200d(?:"+[we,Ee,De].join("|")+")[\\ufe0e\\ufe0f]?"+Te+")*"),Ae="(?:"+[ge,Ee,De].join("|")+")"+xe,Oe="(?:"+[we+ve+"?",ve,Ee,De,pe].join("|")+")",Pe=RegExp("['’]","g"),Ie=RegExp(ve,"g"),Ne=RegExp(be+"(?="+be+")|"+Oe+xe,"g"),Me=RegExp([Se+"?"+ye+"+(?:['’](?:d|ll|m|re|s|t|ve))?(?="+[he,Se,"$"].join("|")+")",ke+"+(?:['’](?:D|LL|M|RE|S|T|VE))?(?="+[he,Se+Ce,"$"].join("|")+")",Se+"?"+Ce+"+(?:['’](?:d|ll|m|re|s|t|ve))?",Se+"+(?:['’](?:D|LL|M|RE|S|T|VE))?","\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",me,Ae].join("|"),"g"),Re=RegExp("[\\u200d\\ud800-\\udfff"+fe+"\\ufe0e\\ufe0f]"),Fe=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Le=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],Be=-1,je={};je[S]=je[C]=je[k]=je[T]=je[x]=je[A]=je["[object Uint8ClampedArray]"]=je[O]=je[P]=!0,je[a]=je[l]=je[E]=je[s]=je[D]=je[c]=je[f]=je[d]=je[h]=je[v]=je[m]=je[g]=je[y]=je[_]=je[w]=!1;var Ue={};Ue[a]=Ue[l]=Ue[E]=Ue[D]=Ue[s]=Ue[c]=Ue[S]=Ue[C]=Ue[k]=Ue[T]=Ue[x]=Ue[h]=Ue[v]=Ue[m]=Ue[g]=Ue[y]=Ue[_]=Ue[b]=Ue[A]=Ue["[object Uint8ClampedArray]"]=Ue[O]=Ue[P]=!0,Ue[f]=Ue[d]=Ue[w]=!1;var ze={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},We=parseFloat,He=parseInt,Ve="object"==typeof global&&global&&global.Object===Object&&global,qe="object"==typeof self&&self&&self.Object===Object&&self,Ge=Ve||qe||Function("return this")(),$e=t&&!t.nodeType&&t,Ye=$e&&e&&!e.nodeType&&e,Ke=Ye&&Ye.exports===$e,Xe=Ke&&Ve.process,Qe=function(){try{var e=Ye&&Ye.require&&Ye.require("util").types;return e||Xe&&Xe.binding&&Xe.binding("util")}catch(e){}}(),Je=Qe&&Qe.isArrayBuffer,Ze=Qe&&Qe.isDate,et=Qe&&Qe.isMap,tt=Qe&&Qe.isRegExp,nt=Qe&&Qe.isSet,rt=Qe&&Qe.isTypedArray;function it(e,t,n){switch(n.length){case 0:return e.call(t);case 1:return e.call(t,n[0]);case 2:return e.call(t,n[0],n[1]);case 3:return e.call(t,n[0],n[1],n[2])}return e.apply(t,n)}function ot(e,t,n,r){for(var i=-1,o=null==e?0:e.length;++i-1}function ft(e,t,n){for(var r=-1,i=null==e?0:e.length;++r-1;);return n}function Nt(e,t){for(var n=e.length;n--&&bt(t,e[n],0)>-1;);return n}function Mt(e,t){for(var n=e.length,r=0;n--;)e[n]===t&&++r;return r}var Rt=Ct({À:"A",Á:"A",Â:"A",Ã:"A",Ä:"A",Å:"A",à:"a",á:"a",â:"a",ã:"a",ä:"a",å:"a",Ç:"C",ç:"c",Ð:"D",ð:"d",È:"E",É:"E",Ê:"E",Ë:"E",è:"e",é:"e",ê:"e",ë:"e",Ì:"I",Í:"I",Î:"I",Ï:"I",ì:"i",í:"i",î:"i",ï:"i",Ñ:"N",ñ:"n",Ò:"O",Ó:"O",Ô:"O",Õ:"O",Ö:"O",Ø:"O",ò:"o",ó:"o",ô:"o",õ:"o",ö:"o",ø:"o",Ù:"U",Ú:"U",Û:"U",Ü:"U",ù:"u",ú:"u",û:"u",ü:"u",Ý:"Y",ý:"y",ÿ:"y",Æ:"Ae",æ:"ae",Þ:"Th",þ:"th",ß:"ss",Ā:"A",Ă:"A",Ą:"A",ā:"a",ă:"a",ą:"a",Ć:"C",Ĉ:"C",Ċ:"C",Č:"C",ć:"c",ĉ:"c",ċ:"c",č:"c",Ď:"D",Đ:"D",ď:"d",đ:"d",Ē:"E",Ĕ:"E",Ė:"E",Ę:"E",Ě:"E",ē:"e",ĕ:"e",ė:"e",ę:"e",ě:"e",Ĝ:"G",Ğ:"G",Ġ:"G",Ģ:"G",ĝ:"g",ğ:"g",ġ:"g",ģ:"g",Ĥ:"H",Ħ:"H",ĥ:"h",ħ:"h",Ĩ:"I",Ī:"I",Ĭ:"I",Į:"I",İ:"I",ĩ:"i",ī:"i",ĭ:"i",į:"i",ı:"i",Ĵ:"J",ĵ:"j",Ķ:"K",ķ:"k",ĸ:"k",Ĺ:"L",Ļ:"L",Ľ:"L",Ŀ:"L",Ł:"L",ĺ:"l",ļ:"l",ľ:"l",ŀ:"l",ł:"l",Ń:"N",Ņ:"N",Ň:"N",Ŋ:"N",ń:"n",ņ:"n",ň:"n",ŋ:"n",Ō:"O",Ŏ:"O",Ő:"O",ō:"o",ŏ:"o",ő:"o",Ŕ:"R",Ŗ:"R",Ř:"R",ŕ:"r",ŗ:"r",ř:"r",Ś:"S",Ŝ:"S",Ş:"S",Š:"S",ś:"s",ŝ:"s",ş:"s",š:"s",Ţ:"T",Ť:"T",Ŧ:"T",ţ:"t",ť:"t",ŧ:"t",Ũ:"U",Ū:"U",Ŭ:"U",Ů:"U",Ű:"U",Ų:"U",ũ:"u",ū:"u",ŭ:"u",ů:"u",ű:"u",ų:"u",Ŵ:"W",ŵ:"w",Ŷ:"Y",ŷ:"y",Ÿ:"Y",Ź:"Z",Ż:"Z",Ž:"Z",ź:"z",ż:"z",ž:"z",IJ:"IJ",ij:"ij",Œ:"Oe",œ:"oe",ʼn:"'n",ſ:"s"}),Ft=Ct({"&":"&","<":"<",">":">",'"':""","'":"'"});function Lt(e){return"\\"+ze[e]}function Bt(e){return Re.test(e)}function jt(e){var t=-1,n=Array(e.size);return e.forEach((function(e,r){n[++t]=[r,e]})),n}function Ut(e,t){return function(n){return e(t(n))}}function zt(e,t){for(var n=-1,r=e.length,i=0,u=[];++n",""":'"',"'":"'"});var $t=function e(t){var n,r=(t=null==t?Ge:$t.defaults(Ge.Object(),t,$t.pick(Ge,Le))).Array,fe=t.Date,de=t.Error,pe=t.Function,he=t.Math,ve=t.Object,me=t.RegExp,ge=t.String,ye=t.TypeError,_e=r.prototype,be=pe.prototype,we=ve.prototype,Ee=t["__core-js_shared__"],De=be.toString,Se=we.hasOwnProperty,Ce=0,ke=(n=/[^.]+$/.exec(Ee&&Ee.keys&&Ee.keys.IE_PROTO||""))?"Symbol(src)_1."+n:"",Te=we.toString,xe=De.call(ve),Ae=Ge._,Oe=me("^"+De.call(Se).replace(q,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),Ne=Ke?t.Buffer:void 0,Re=t.Symbol,ze=t.Uint8Array,Ve=Ne?Ne.allocUnsafe:void 0,qe=Ut(ve.getPrototypeOf,ve),$e=ve.create,Ye=we.propertyIsEnumerable,Xe=_e.splice,Qe=Re?Re.isConcatSpreadable:void 0,gt=Re?Re.iterator:void 0,Ct=Re?Re.toStringTag:void 0,Yt=function(){try{var e=Zi(ve,"defineProperty");return e({},"",{}),e}catch(e){}}(),Kt=t.clearTimeout!==Ge.clearTimeout&&t.clearTimeout,Xt=fe&&fe.now!==Ge.Date.now&&fe.now,Qt=t.setTimeout!==Ge.setTimeout&&t.setTimeout,Jt=he.ceil,Zt=he.floor,en=ve.getOwnPropertySymbols,tn=Ne?Ne.isBuffer:void 0,nn=t.isFinite,rn=_e.join,on=Ut(ve.keys,ve),un=he.max,an=he.min,ln=fe.now,sn=t.parseInt,cn=he.random,fn=_e.reverse,dn=Zi(t,"DataView"),pn=Zi(t,"Map"),hn=Zi(t,"Promise"),vn=Zi(t,"Set"),mn=Zi(t,"WeakMap"),gn=Zi(ve,"create"),yn=mn&&new mn,_n={},bn=To(dn),wn=To(pn),En=To(hn),Dn=To(vn),Sn=To(mn),Cn=Re?Re.prototype:void 0,kn=Cn?Cn.valueOf:void 0,Tn=Cn?Cn.toString:void 0;function xn(e){if(Vu(e)&&!Nu(e)&&!(e instanceof In)){if(e instanceof Pn)return e;if(Se.call(e,"__wrapped__"))return xo(e)}return new Pn(e)}var An=function(){function e(){}return function(t){if(!Hu(t))return{};if($e)return $e(t);e.prototype=t;var n=new e;return e.prototype=void 0,n}}();function On(){}function Pn(e,t){this.__wrapped__=e,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=void 0}function In(e){this.__wrapped__=e,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Nn(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t=t?e:t)),e}function Xn(e,t,n,r,i,o){var u,l=1&t,f=2&t,w=4&t;if(n&&(u=i?n(e,r,i,o):n(e)),void 0!==u)return u;if(!Hu(e))return e;var I=Nu(e);if(I){if(u=function(e){var t=e.length,n=new e.constructor(t);t&&"string"==typeof e[0]&&Se.call(e,"index")&&(n.index=e.index,n.input=e.input);return n}(e),!l)return gi(e,u)}else{var N=no(e),M=N==d||N==p;if(Lu(e))return fi(e,l);if(N==m||N==a||M&&!i){if(u=f||M?{}:io(e),!l)return f?function(e,t){return yi(e,to(e),t)}(e,function(e,t){return e&&yi(t,wa(t),e)}(u,e)):function(e,t){return yi(e,eo(e),t)}(e,Gn(u,e))}else{if(!Ue[N])return i?e:{};u=function(e,t,n){var r=e.constructor;switch(t){case E:return di(e);case s:case c:return new r(+e);case D:return function(e,t){var n=t?di(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.byteLength)}(e,n);case S:case C:case k:case T:case x:case A:case"[object Uint8ClampedArray]":case O:case P:return pi(e,n);case h:return new r;case v:case _:return new r(e);case g:return function(e){var t=new e.constructor(e.source,ne.exec(e));return t.lastIndex=e.lastIndex,t}(e);case y:return new r;case b:return i=e,kn?ve(kn.call(i)):{}}var i}(e,N,l)}}o||(o=new Ln);var R=o.get(e);if(R)return R;o.set(e,u),Ku(e)?e.forEach((function(r){u.add(Xn(r,t,n,r,e,o))})):qu(e)&&e.forEach((function(r,i){u.set(i,Xn(r,t,n,i,e,o))}));var F=I?void 0:(w?f?Gi:qi:f?wa:ba)(e);return ut(F||e,(function(r,i){F&&(r=e[i=r]),Hn(u,i,Xn(r,t,n,i,e,o))})),u}function Qn(e,t,n){var r=n.length;if(null==e)return!r;for(e=ve(e);r--;){var i=n[r],o=t[i],u=e[i];if(void 0===u&&!(i in e)||!o(u))return!1}return!0}function Jn(e,t,n){if("function"!=typeof e)throw new ye(i);return bo((function(){e.apply(void 0,n)}),t)}function Zn(e,t,n,r){var i=-1,o=ct,u=!0,a=e.length,l=[],s=t.length;if(!a)return l;n&&(t=dt(t,At(n))),r?(o=ft,u=!1):t.length>=200&&(o=Pt,u=!1,t=new Fn(t));e:for(;++i-1},Mn.prototype.set=function(e,t){var n=this.__data__,r=Vn(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this},Rn.prototype.clear=function(){this.size=0,this.__data__={hash:new Nn,map:new(pn||Mn),string:new Nn}},Rn.prototype.delete=function(e){var t=Qi(this,e).delete(e);return this.size-=t?1:0,t},Rn.prototype.get=function(e){return Qi(this,e).get(e)},Rn.prototype.has=function(e){return Qi(this,e).has(e)},Rn.prototype.set=function(e,t){var n=Qi(this,e),r=n.size;return n.set(e,t),this.size+=n.size==r?0:1,this},Fn.prototype.add=Fn.prototype.push=function(e){return this.__data__.set(e,"__lodash_hash_undefined__"),this},Fn.prototype.has=function(e){return this.__data__.has(e)},Ln.prototype.clear=function(){this.__data__=new Mn,this.size=0},Ln.prototype.delete=function(e){var t=this.__data__,n=t.delete(e);return this.size=t.size,n},Ln.prototype.get=function(e){return this.__data__.get(e)},Ln.prototype.has=function(e){return this.__data__.has(e)},Ln.prototype.set=function(e,t){var n=this.__data__;if(n instanceof Mn){var r=n.__data__;if(!pn||r.length<199)return r.push([e,t]),this.size=++n.size,this;n=this.__data__=new Rn(r)}return n.set(e,t),this.size=n.size,this};var er=wi(lr),tr=wi(sr,!0);function nr(e,t){var n=!0;return er(e,(function(e,r,i){return n=!!t(e,r,i)})),n}function rr(e,t,n){for(var r=-1,i=e.length;++r0&&n(a)?t>1?or(a,t-1,n,r,i):pt(i,a):r||(i[i.length]=a)}return i}var ur=Ei(),ar=Ei(!0);function lr(e,t){return e&&ur(e,t,ba)}function sr(e,t){return e&&ar(e,t,ba)}function cr(e,t){return st(t,(function(t){return Uu(e[t])}))}function fr(e,t){for(var n=0,r=(t=ai(t,e)).length;null!=e&&nt}function vr(e,t){return null!=e&&Se.call(e,t)}function mr(e,t){return null!=e&&t in ve(e)}function gr(e,t,n){for(var i=n?ft:ct,o=e[0].length,u=e.length,a=u,l=r(u),s=1/0,c=[];a--;){var f=e[a];a&&t&&(f=dt(f,At(t))),s=an(f.length,s),l[a]=!n&&(t||o>=120&&f.length>=120)?new Fn(a&&f):void 0}f=e[0];var d=-1,p=l[0];e:for(;++d=a)return l;var s=n[r];return l*("desc"==s?-1:1)}}return e.index-t.index}(e,t,n)}))}function Nr(e,t,n){for(var r=-1,i=t.length,o={};++r-1;)a!==e&&Xe.call(a,l,1),Xe.call(e,l,1);return e}function Rr(e,t){for(var n=e?t.length:0,r=n-1;n--;){var i=t[n];if(n==r||i!==o){var o=i;uo(i)?Xe.call(e,i,1):Zr(e,i)}}return e}function Fr(e,t){return e+Zt(cn()*(t-e+1))}function Lr(e,t){var n="";if(!e||t<1||t>9007199254740991)return n;do{t%2&&(n+=e),(t=Zt(t/2))&&(e+=e)}while(t);return n}function Br(e,t){return wo(vo(e,t,Ga),e+"")}function jr(e){return jn(Aa(e))}function Ur(e,t){var n=Aa(e);return So(n,Kn(t,0,n.length))}function zr(e,t,n,r){if(!Hu(e))return e;for(var i=-1,o=(t=ai(t,e)).length,u=o-1,a=e;null!=a&&++io?0:o+t),(n=n>o?o:n)<0&&(n+=o),o=t>n?0:n-t>>>0,t>>>=0;for(var u=r(o);++i>>1,u=e[o];null!==u&&!Qu(u)&&(n?u<=t:u=200){var s=t?null:Li(e);if(s)return Wt(s);u=!1,i=Pt,l=new Fn}else l=t?[]:a;e:for(;++r=r?e:qr(e,t,n)}var ci=Kt||function(e){return Ge.clearTimeout(e)};function fi(e,t){if(t)return e.slice();var n=e.length,r=Ve?Ve(n):new e.constructor(n);return e.copy(r),r}function di(e){var t=new e.constructor(e.byteLength);return new ze(t).set(new ze(e)),t}function pi(e,t){var n=t?di(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.length)}function hi(e,t){if(e!==t){var n=void 0!==e,r=null===e,i=e==e,o=Qu(e),u=void 0!==t,a=null===t,l=t==t,s=Qu(t);if(!a&&!s&&!o&&e>t||o&&u&&l&&!a&&!s||r&&u&&l||!n&&l||!i)return 1;if(!r&&!o&&!s&&e1?n[i-1]:void 0,u=i>2?n[2]:void 0;for(o=e.length>3&&"function"==typeof o?(i--,o):void 0,u&&ao(n[0],n[1],u)&&(o=i<3?void 0:o,i=1),t=ve(t);++r-1?i[o?t[u]:u]:void 0}}function Ti(e){return Vi((function(t){var n=t.length,r=n,o=Pn.prototype.thru;for(e&&t.reverse();r--;){var u=t[r];if("function"!=typeof u)throw new ye(i);if(o&&!a&&"wrapper"==Yi(u))var a=new Pn([],!0)}for(r=a?r:n;++r1&&_.reverse(),f&&sa))return!1;var s=o.get(e),c=o.get(t);if(s&&c)return s==t&&c==e;var f=-1,d=!0,p=2&n?new Fn:void 0;for(o.set(e,t),o.set(t,e);++f-1&&e%1==0&&e1?"& ":"")+t[r],t=t.join(n>2?", ":" "),e.replace(X,"{\n/* [wrapped with "+t+"] */\n")}(r,function(e,t){return ut(u,(function(n){var r="_."+n[0];t&n[1]&&!ct(e,r)&&e.push(r)})),e.sort()}(function(e){var t=e.match(Q);return t?t[1].split(J):[]}(r),n)))}function Do(e){var t=0,n=0;return function(){var r=ln(),i=16-(r-n);if(n=r,i>0){if(++t>=800)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}function So(e,t){var n=-1,r=e.length,i=r-1;for(t=void 0===t?r:t;++n1?e[t-1]:void 0;return n="function"==typeof n?(e.pop(),n):void 0,Yo(e,n)}));function tu(e){var t=xn(e);return t.__chain__=!0,t}function nu(e,t){return t(e)}var ru=Vi((function(e){var t=e.length,n=t?e[0]:0,r=this.__wrapped__,i=function(t){return Yn(t,e)};return!(t>1||this.__actions__.length)&&r instanceof In&&uo(n)?((r=r.slice(n,+n+(t?1:0))).__actions__.push({func:nu,args:[i],thisArg:void 0}),new Pn(r,this.__chain__).thru((function(e){return t&&!e.length&&e.push(void 0),e}))):this.thru(i)}));var iu=_i((function(e,t,n){Se.call(e,n)?++e[n]:$n(e,n,1)}));var ou=ki(Io),uu=ki(No);function au(e,t){return(Nu(e)?ut:er)(e,Xi(t,3))}function lu(e,t){return(Nu(e)?at:tr)(e,Xi(t,3))}var su=_i((function(e,t,n){Se.call(e,n)?e[n].push(t):$n(e,n,[t])}));var cu=Br((function(e,t,n){var i=-1,o="function"==typeof t,u=Ru(e)?r(e.length):[];return er(e,(function(e){u[++i]=o?it(t,e,n):yr(e,t,n)})),u})),fu=_i((function(e,t,n){$n(e,n,t)}));function du(e,t){return(Nu(e)?dt:Tr)(e,Xi(t,3))}var pu=_i((function(e,t,n){e[n?0:1].push(t)}),(function(){return[[],[]]}));var hu=Br((function(e,t){if(null==e)return[];var n=t.length;return n>1&&ao(e,t[0],t[1])?t=[]:n>2&&ao(t[0],t[1],t[2])&&(t=[t[0]]),Ir(e,or(t,1),[])})),vu=Xt||function(){return Ge.Date.now()};function mu(e,t,n){return t=n?void 0:t,ji(e,128,void 0,void 0,void 0,void 0,t=e&&null==t?e.length:t)}function gu(e,t){var n;if("function"!=typeof t)throw new ye(i);return e=ra(e),function(){return--e>0&&(n=t.apply(this,arguments)),e<=1&&(t=void 0),n}}var yu=Br((function(e,t,n){var r=1;if(n.length){var i=zt(n,Ki(yu));r|=32}return ji(e,r,t,n,i)})),_u=Br((function(e,t,n){var r=3;if(n.length){var i=zt(n,Ki(_u));r|=32}return ji(t,r,e,n,i)}));function bu(e,t,n){var r,o,u,a,l,s,c=0,f=!1,d=!1,p=!0;if("function"!=typeof e)throw new ye(i);function h(t){var n=r,i=o;return r=o=void 0,c=t,a=e.apply(i,n)}function v(e){return c=e,l=bo(g,t),f?h(e):a}function m(e){var n=e-s;return void 0===s||n>=t||n<0||d&&e-c>=u}function g(){var e=vu();if(m(e))return y(e);l=bo(g,function(e){var n=t-(e-s);return d?an(n,u-(e-c)):n}(e))}function y(e){return l=void 0,p&&r?h(e):(r=o=void 0,a)}function _(){var e=vu(),n=m(e);if(r=arguments,o=this,s=e,n){if(void 0===l)return v(s);if(d)return ci(l),l=bo(g,t),h(s)}return void 0===l&&(l=bo(g,t)),a}return t=oa(t)||0,Hu(n)&&(f=!!n.leading,u=(d="maxWait"in n)?un(oa(n.maxWait)||0,t):u,p="trailing"in n?!!n.trailing:p),_.cancel=function(){void 0!==l&&ci(l),c=0,r=s=o=l=void 0},_.flush=function(){return void 0===l?a:y(vu())},_}var wu=Br((function(e,t){return Jn(e,1,t)})),Eu=Br((function(e,t,n){return Jn(e,oa(t)||0,n)}));function Du(e,t){if("function"!=typeof e||null!=t&&"function"!=typeof t)throw new ye(i);var n=function(){var r=arguments,i=t?t.apply(this,r):r[0],o=n.cache;if(o.has(i))return o.get(i);var u=e.apply(this,r);return n.cache=o.set(i,u)||o,u};return n.cache=new(Du.Cache||Rn),n}function Su(e){if("function"!=typeof e)throw new ye(i);return function(){var t=arguments;switch(t.length){case 0:return!e.call(this);case 1:return!e.call(this,t[0]);case 2:return!e.call(this,t[0],t[1]);case 3:return!e.call(this,t[0],t[1],t[2])}return!e.apply(this,t)}}Du.Cache=Rn;var Cu=li((function(e,t){var n=(t=1==t.length&&Nu(t[0])?dt(t[0],At(Xi())):dt(or(t,1),At(Xi()))).length;return Br((function(r){for(var i=-1,o=an(r.length,n);++i=t})),Iu=_r(function(){return arguments}())?_r:function(e){return Vu(e)&&Se.call(e,"callee")&&!Ye.call(e,"callee")},Nu=r.isArray,Mu=Je?At(Je):function(e){return Vu(e)&&pr(e)==E};function Ru(e){return null!=e&&Wu(e.length)&&!Uu(e)}function Fu(e){return Vu(e)&&Ru(e)}var Lu=tn||ol,Bu=Ze?At(Ze):function(e){return Vu(e)&&pr(e)==c};function ju(e){if(!Vu(e))return!1;var t=pr(e);return t==f||"[object DOMException]"==t||"string"==typeof e.message&&"string"==typeof e.name&&!$u(e)}function Uu(e){if(!Hu(e))return!1;var t=pr(e);return t==d||t==p||"[object AsyncFunction]"==t||"[object Proxy]"==t}function zu(e){return"number"==typeof e&&e==ra(e)}function Wu(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}function Hu(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}function Vu(e){return null!=e&&"object"==typeof e}var qu=et?At(et):function(e){return Vu(e)&&no(e)==h};function Gu(e){return"number"==typeof e||Vu(e)&&pr(e)==v}function $u(e){if(!Vu(e)||pr(e)!=m)return!1;var t=qe(e);if(null===t)return!0;var n=Se.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&De.call(n)==xe}var Yu=tt?At(tt):function(e){return Vu(e)&&pr(e)==g};var Ku=nt?At(nt):function(e){return Vu(e)&&no(e)==y};function Xu(e){return"string"==typeof e||!Nu(e)&&Vu(e)&&pr(e)==_}function Qu(e){return"symbol"==typeof e||Vu(e)&&pr(e)==b}var Ju=rt?At(rt):function(e){return Vu(e)&&Wu(e.length)&&!!je[pr(e)]};var Zu=Mi(kr),ea=Mi((function(e,t){return e<=t}));function ta(e){if(!e)return[];if(Ru(e))return Xu(e)?qt(e):gi(e);if(gt&&e[gt])return function(e){for(var t,n=[];!(t=e.next()).done;)n.push(t.value);return n}(e[gt]());var t=no(e);return(t==h?jt:t==y?Wt:Aa)(e)}function na(e){return e?(e=oa(e))===1/0||e===-1/0?17976931348623157e292*(e<0?-1:1):e==e?e:0:0===e?e:0}function ra(e){var t=na(e),n=t%1;return t==t?n?t-n:t:0}function ia(e){return e?Kn(ra(e),0,4294967295):0}function oa(e){if("number"==typeof e)return e;if(Qu(e))return NaN;if(Hu(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=Hu(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace($,"");var n=ie.test(e);return n||ue.test(e)?He(e.slice(2),n?2:8):re.test(e)?NaN:+e}function ua(e){return yi(e,wa(e))}function aa(e){return null==e?"":Qr(e)}var la=bi((function(e,t){if(fo(t)||Ru(t))yi(t,ba(t),e);else for(var n in t)Se.call(t,n)&&Hn(e,n,t[n])})),sa=bi((function(e,t){yi(t,wa(t),e)})),ca=bi((function(e,t,n,r){yi(t,wa(t),e,r)})),fa=bi((function(e,t,n,r){yi(t,ba(t),e,r)})),da=Vi(Yn);var pa=Br((function(e,t){e=ve(e);var n=-1,r=t.length,i=r>2?t[2]:void 0;for(i&&ao(t[0],t[1],i)&&(r=1);++n1),t})),yi(e,Gi(e),n),r&&(n=Xn(n,7,Wi));for(var i=t.length;i--;)Zr(n,t[i]);return n}));var Ca=Vi((function(e,t){return null==e?{}:function(e,t){return Nr(e,t,(function(t,n){return ma(e,n)}))}(e,t)}));function ka(e,t){if(null==e)return{};var n=dt(Gi(e),(function(e){return[e]}));return t=Xi(t),Nr(e,n,(function(e,n){return t(e,n[0])}))}var Ta=Bi(ba),xa=Bi(wa);function Aa(e){return null==e?[]:Ot(e,ba(e))}var Oa=Si((function(e,t,n){return t=t.toLowerCase(),e+(n?Pa(t):t)}));function Pa(e){return ja(aa(e).toLowerCase())}function Ia(e){return(e=aa(e))&&e.replace(le,Rt).replace(Ie,"")}var Na=Si((function(e,t,n){return e+(n?"-":"")+t.toLowerCase()})),Ma=Si((function(e,t,n){return e+(n?" ":"")+t.toLowerCase()})),Ra=Di("toLowerCase");var Fa=Si((function(e,t,n){return e+(n?"_":"")+t.toLowerCase()}));var La=Si((function(e,t,n){return e+(n?" ":"")+ja(t)}));var Ba=Si((function(e,t,n){return e+(n?" ":"")+t.toUpperCase()})),ja=Di("toUpperCase");function Ua(e,t,n){return e=aa(e),void 0===(t=n?void 0:t)?function(e){return Fe.test(e)}(e)?function(e){return e.match(Me)||[]}(e):function(e){return e.match(Z)||[]}(e):e.match(t)||[]}var za=Br((function(e,t){try{return it(e,void 0,t)}catch(e){return ju(e)?e:new de(e)}})),Wa=Vi((function(e,t){return ut(t,(function(t){t=ko(t),$n(e,t,yu(e[t],e))})),e}));function Ha(e){return function(){return e}}var Va=Ti(),qa=Ti(!0);function Ga(e){return e}function $a(e){return Dr("function"==typeof e?e:Xn(e,1))}var Ya=Br((function(e,t){return function(n){return yr(n,e,t)}})),Ka=Br((function(e,t){return function(n){return yr(e,n,t)}}));function Xa(e,t,n){var r=ba(t),i=cr(t,r);null!=n||Hu(t)&&(i.length||!r.length)||(n=t,t=e,e=this,i=cr(t,ba(t)));var o=!(Hu(n)&&"chain"in n&&!n.chain),u=Uu(e);return ut(i,(function(n){var r=t[n];e[n]=r,u&&(e.prototype[n]=function(){var t=this.__chain__;if(o||t){var n=e(this.__wrapped__),i=n.__actions__=gi(this.__actions__);return i.push({func:r,args:arguments,thisArg:e}),n.__chain__=t,n}return r.apply(e,pt([this.value()],arguments))})})),e}function Qa(){}var Ja=Pi(dt),Za=Pi(lt),el=Pi(mt);function tl(e){return lo(e)?St(ko(e)):function(e){return function(t){return fr(t,e)}}(e)}var nl=Ni(),rl=Ni(!0);function il(){return[]}function ol(){return!1}var ul=Oi((function(e,t){return e+t}),0),al=Fi("ceil"),ll=Oi((function(e,t){return e/t}),1),sl=Fi("floor");var cl,fl=Oi((function(e,t){return e*t}),1),dl=Fi("round"),pl=Oi((function(e,t){return e-t}),0);return xn.after=function(e,t){if("function"!=typeof t)throw new ye(i);return e=ra(e),function(){if(--e<1)return t.apply(this,arguments)}},xn.ary=mu,xn.assign=la,xn.assignIn=sa,xn.assignInWith=ca,xn.assignWith=fa,xn.at=da,xn.before=gu,xn.bind=yu,xn.bindAll=Wa,xn.bindKey=_u,xn.castArray=function(){if(!arguments.length)return[];var e=arguments[0];return Nu(e)?e:[e]},xn.chain=tu,xn.chunk=function(e,t,n){t=(n?ao(e,t,n):void 0===t)?1:un(ra(t),0);var i=null==e?0:e.length;if(!i||t<1)return[];for(var o=0,u=0,a=r(Jt(i/t));oi?0:i+n),(r=void 0===r||r>i?i:ra(r))<0&&(r+=i),r=n>r?0:ia(r);n>>0)?(e=aa(e))&&("string"==typeof t||null!=t&&!Yu(t))&&!(t=Qr(t))&&Bt(e)?si(qt(e),0,n):e.split(t,n):[]},xn.spread=function(e,t){if("function"!=typeof e)throw new ye(i);return t=null==t?0:un(ra(t),0),Br((function(n){var r=n[t],i=si(n,0,t);return r&&pt(i,r),it(e,this,i)}))},xn.tail=function(e){var t=null==e?0:e.length;return t?qr(e,1,t):[]},xn.take=function(e,t,n){return e&&e.length?qr(e,0,(t=n||void 0===t?1:ra(t))<0?0:t):[]},xn.takeRight=function(e,t,n){var r=null==e?0:e.length;return r?qr(e,(t=r-(t=n||void 0===t?1:ra(t)))<0?0:t,r):[]},xn.takeRightWhile=function(e,t){return e&&e.length?ti(e,Xi(t,3),!1,!0):[]},xn.takeWhile=function(e,t){return e&&e.length?ti(e,Xi(t,3)):[]},xn.tap=function(e,t){return t(e),e},xn.throttle=function(e,t,n){var r=!0,o=!0;if("function"!=typeof e)throw new ye(i);return Hu(n)&&(r="leading"in n?!!n.leading:r,o="trailing"in n?!!n.trailing:o),bu(e,t,{leading:r,maxWait:t,trailing:o})},xn.thru=nu,xn.toArray=ta,xn.toPairs=Ta,xn.toPairsIn=xa,xn.toPath=function(e){return Nu(e)?dt(e,ko):Qu(e)?[e]:gi(Co(aa(e)))},xn.toPlainObject=ua,xn.transform=function(e,t,n){var r=Nu(e),i=r||Lu(e)||Ju(e);if(t=Xi(t,4),null==n){var o=e&&e.constructor;n=i?r?new o:[]:Hu(e)&&Uu(o)?An(qe(e)):{}}return(i?ut:lr)(e,(function(e,r,i){return t(n,e,r,i)})),n},xn.unary=function(e){return mu(e,1)},xn.union=Vo,xn.unionBy=qo,xn.unionWith=Go,xn.uniq=function(e){return e&&e.length?Jr(e):[]},xn.uniqBy=function(e,t){return e&&e.length?Jr(e,Xi(t,2)):[]},xn.uniqWith=function(e,t){return t="function"==typeof t?t:void 0,e&&e.length?Jr(e,void 0,t):[]},xn.unset=function(e,t){return null==e||Zr(e,t)},xn.unzip=$o,xn.unzipWith=Yo,xn.update=function(e,t,n){return null==e?e:ei(e,t,ui(n))},xn.updateWith=function(e,t,n,r){return r="function"==typeof r?r:void 0,null==e?e:ei(e,t,ui(n),r)},xn.values=Aa,xn.valuesIn=function(e){return null==e?[]:Ot(e,wa(e))},xn.without=Ko,xn.words=Ua,xn.wrap=function(e,t){return ku(ui(t),e)},xn.xor=Xo,xn.xorBy=Qo,xn.xorWith=Jo,xn.zip=Zo,xn.zipObject=function(e,t){return ii(e||[],t||[],Hn)},xn.zipObjectDeep=function(e,t){return ii(e||[],t||[],zr)},xn.zipWith=eu,xn.entries=Ta,xn.entriesIn=xa,xn.extend=sa,xn.extendWith=ca,Xa(xn,xn),xn.add=ul,xn.attempt=za,xn.camelCase=Oa,xn.capitalize=Pa,xn.ceil=al,xn.clamp=function(e,t,n){return void 0===n&&(n=t,t=void 0),void 0!==n&&(n=(n=oa(n))==n?n:0),void 0!==t&&(t=(t=oa(t))==t?t:0),Kn(oa(e),t,n)},xn.clone=function(e){return Xn(e,4)},xn.cloneDeep=function(e){return Xn(e,5)},xn.cloneDeepWith=function(e,t){return Xn(e,5,t="function"==typeof t?t:void 0)},xn.cloneWith=function(e,t){return Xn(e,4,t="function"==typeof t?t:void 0)},xn.conformsTo=function(e,t){return null==t||Qn(e,t,ba(t))},xn.deburr=Ia,xn.defaultTo=function(e,t){return null==e||e!=e?t:e},xn.divide=ll,xn.endsWith=function(e,t,n){e=aa(e),t=Qr(t);var r=e.length,i=n=void 0===n?r:Kn(ra(n),0,r);return(n-=t.length)>=0&&e.slice(n,i)==t},xn.eq=Au,xn.escape=function(e){return(e=aa(e))&&B.test(e)?e.replace(F,Ft):e},xn.escapeRegExp=function(e){return(e=aa(e))&&G.test(e)?e.replace(q,"\\$&"):e},xn.every=function(e,t,n){var r=Nu(e)?lt:nr;return n&&ao(e,t,n)&&(t=void 0),r(e,Xi(t,3))},xn.find=ou,xn.findIndex=Io,xn.findKey=function(e,t){return yt(e,Xi(t,3),lr)},xn.findLast=uu,xn.findLastIndex=No,xn.findLastKey=function(e,t){return yt(e,Xi(t,3),sr)},xn.floor=sl,xn.forEach=au,xn.forEachRight=lu,xn.forIn=function(e,t){return null==e?e:ur(e,Xi(t,3),wa)},xn.forInRight=function(e,t){return null==e?e:ar(e,Xi(t,3),wa)},xn.forOwn=function(e,t){return e&&lr(e,Xi(t,3))},xn.forOwnRight=function(e,t){return e&&sr(e,Xi(t,3))},xn.get=va,xn.gt=Ou,xn.gte=Pu,xn.has=function(e,t){return null!=e&&ro(e,t,vr)},xn.hasIn=ma,xn.head=Ro,xn.identity=Ga,xn.includes=function(e,t,n,r){e=Ru(e)?e:Aa(e),n=n&&!r?ra(n):0;var i=e.length;return n<0&&(n=un(i+n,0)),Xu(e)?n<=i&&e.indexOf(t,n)>-1:!!i&&bt(e,t,n)>-1},xn.indexOf=function(e,t,n){var r=null==e?0:e.length;if(!r)return-1;var i=null==n?0:ra(n);return i<0&&(i=un(r+i,0)),bt(e,t,i)},xn.inRange=function(e,t,n){return t=na(t),void 0===n?(n=t,t=0):n=na(n),function(e,t,n){return e>=an(t,n)&&e=-9007199254740991&&e<=9007199254740991},xn.isSet=Ku,xn.isString=Xu,xn.isSymbol=Qu,xn.isTypedArray=Ju,xn.isUndefined=function(e){return void 0===e},xn.isWeakMap=function(e){return Vu(e)&&no(e)==w},xn.isWeakSet=function(e){return Vu(e)&&"[object WeakSet]"==pr(e)},xn.join=function(e,t){return null==e?"":rn.call(e,t)},xn.kebabCase=Na,xn.last=jo,xn.lastIndexOf=function(e,t,n){var r=null==e?0:e.length;if(!r)return-1;var i=r;return void 0!==n&&(i=(i=ra(n))<0?un(r+i,0):an(i,r-1)),t==t?function(e,t,n){for(var r=n+1;r--;)if(e[r]===t)return r;return r}(e,t,i):_t(e,Et,i,!0)},xn.lowerCase=Ma,xn.lowerFirst=Ra,xn.lt=Zu,xn.lte=ea,xn.max=function(e){return e&&e.length?rr(e,Ga,hr):void 0},xn.maxBy=function(e,t){return e&&e.length?rr(e,Xi(t,2),hr):void 0},xn.mean=function(e){return Dt(e,Ga)},xn.meanBy=function(e,t){return Dt(e,Xi(t,2))},xn.min=function(e){return e&&e.length?rr(e,Ga,kr):void 0},xn.minBy=function(e,t){return e&&e.length?rr(e,Xi(t,2),kr):void 0},xn.stubArray=il,xn.stubFalse=ol,xn.stubObject=function(){return{}},xn.stubString=function(){return""},xn.stubTrue=function(){return!0},xn.multiply=fl,xn.nth=function(e,t){return e&&e.length?Pr(e,ra(t)):void 0},xn.noConflict=function(){return Ge._===this&&(Ge._=Ae),this},xn.noop=Qa,xn.now=vu,xn.pad=function(e,t,n){e=aa(e);var r=(t=ra(t))?Vt(e):0;if(!t||r>=t)return e;var i=(t-r)/2;return Ii(Zt(i),n)+e+Ii(Jt(i),n)},xn.padEnd=function(e,t,n){e=aa(e);var r=(t=ra(t))?Vt(e):0;return t&&rt){var r=e;e=t,t=r}if(n||e%1||t%1){var i=cn();return an(e+i*(t-e+We("1e-"+((i+"").length-1))),t)}return Fr(e,t)},xn.reduce=function(e,t,n){var r=Nu(e)?ht:kt,i=arguments.length<3;return r(e,Xi(t,4),n,i,er)},xn.reduceRight=function(e,t,n){var r=Nu(e)?vt:kt,i=arguments.length<3;return r(e,Xi(t,4),n,i,tr)},xn.repeat=function(e,t,n){return t=(n?ao(e,t,n):void 0===t)?1:ra(t),Lr(aa(e),t)},xn.replace=function(){var e=arguments,t=aa(e[0]);return e.length<3?t:t.replace(e[1],e[2])},xn.result=function(e,t,n){var r=-1,i=(t=ai(t,e)).length;for(i||(i=1,e=void 0);++r9007199254740991)return[];var n=4294967295,r=an(e,4294967295);e-=4294967295;for(var i=xt(r,t=Xi(t));++n=o)return e;var a=n-Vt(r);if(a<1)return r;var l=u?si(u,0,a).join(""):e.slice(0,a);if(void 0===i)return l+r;if(u&&(a+=l.length-a),Yu(i)){if(e.slice(a).search(i)){var s,c=l;for(i.global||(i=me(i.source,aa(ne.exec(i))+"g")),i.lastIndex=0;s=i.exec(c);)var f=s.index;l=l.slice(0,void 0===f?a:f)}}else if(e.indexOf(Qr(i),a)!=a){var d=l.lastIndexOf(i);d>-1&&(l=l.slice(0,d))}return l+r},xn.unescape=function(e){return(e=aa(e))&&L.test(e)?e.replace(R,Gt):e},xn.uniqueId=function(e){var t=++Ce;return aa(e)+t},xn.upperCase=Ba,xn.upperFirst=ja,xn.each=au,xn.eachRight=lu,xn.first=Ro,Xa(xn,(cl={},lr(xn,(function(e,t){Se.call(xn.prototype,t)||(cl[t]=e)})),cl),{chain:!1}),xn.VERSION="4.17.20",ut(["bind","bindKey","curry","curryRight","partial","partialRight"],(function(e){xn[e].placeholder=xn})),ut(["drop","take"],(function(e,t){In.prototype[e]=function(n){n=void 0===n?1:un(ra(n),0);var r=this.__filtered__&&!t?new In(this):this.clone();return r.__filtered__?r.__takeCount__=an(n,r.__takeCount__):r.__views__.push({size:an(n,4294967295),type:e+(r.__dir__<0?"Right":"")}),r},In.prototype[e+"Right"]=function(t){return this.reverse()[e](t).reverse()}})),ut(["filter","map","takeWhile"],(function(e,t){var n=t+1,r=1==n||3==n;In.prototype[e]=function(e){var t=this.clone();return t.__iteratees__.push({iteratee:Xi(e,3),type:n}),t.__filtered__=t.__filtered__||r,t}})),ut(["head","last"],(function(e,t){var n="take"+(t?"Right":"");In.prototype[e]=function(){return this[n](1).value()[0]}})),ut(["initial","tail"],(function(e,t){var n="drop"+(t?"":"Right");In.prototype[e]=function(){return this.__filtered__?new In(this):this[n](1)}})),In.prototype.compact=function(){return this.filter(Ga)},In.prototype.find=function(e){return this.filter(e).head()},In.prototype.findLast=function(e){return this.reverse().find(e)},In.prototype.invokeMap=Br((function(e,t){return"function"==typeof e?new In(this):this.map((function(n){return yr(n,e,t)}))})),In.prototype.reject=function(e){return this.filter(Su(Xi(e)))},In.prototype.slice=function(e,t){e=ra(e);var n=this;return n.__filtered__&&(e>0||t<0)?new In(n):(e<0?n=n.takeRight(-e):e&&(n=n.drop(e)),void 0!==t&&(n=(t=ra(t))<0?n.dropRight(-t):n.take(t-e)),n)},In.prototype.takeRightWhile=function(e){return this.reverse().takeWhile(e).reverse()},In.prototype.toArray=function(){return this.take(4294967295)},lr(In.prototype,(function(e,t){var n=/^(?:filter|find|map|reject)|While$/.test(t),r=/^(?:head|last)$/.test(t),i=xn[r?"take"+("last"==t?"Right":""):t],o=r||/^find/.test(t);i&&(xn.prototype[t]=function(){var t=this.__wrapped__,u=r?[1]:arguments,a=t instanceof In,l=u[0],s=a||Nu(t),c=function(e){var t=i.apply(xn,pt([e],u));return r&&f?t[0]:t};s&&n&&"function"==typeof l&&1!=l.length&&(a=s=!1);var f=this.__chain__,d=!!this.__actions__.length,p=o&&!f,h=a&&!d;if(!o&&s){t=h?t:new In(this);var v=e.apply(t,u);return v.__actions__.push({func:nu,args:[c],thisArg:void 0}),new Pn(v,f)}return p&&h?e.apply(this,u):(v=this.thru(c),p?r?v.value()[0]:v.value():v)})})),ut(["pop","push","shift","sort","splice","unshift"],(function(e){var t=_e[e],n=/^(?:push|sort|unshift)$/.test(e)?"tap":"thru",r=/^(?:pop|shift)$/.test(e);xn.prototype[e]=function(){var e=arguments;if(r&&!this.__chain__){var i=this.value();return t.apply(Nu(i)?i:[],e)}return this[n]((function(n){return t.apply(Nu(n)?n:[],e)}))}})),lr(In.prototype,(function(e,t){var n=xn[t];if(n){var r=n.name+"";Se.call(_n,r)||(_n[r]=[]),_n[r].push({name:t,func:n})}})),_n[xi(void 0,2).name]=[{name:"wrapper",func:void 0}],In.prototype.clone=function(){var e=new In(this.__wrapped__);return e.__actions__=gi(this.__actions__),e.__dir__=this.__dir__,e.__filtered__=this.__filtered__,e.__iteratees__=gi(this.__iteratees__),e.__takeCount__=this.__takeCount__,e.__views__=gi(this.__views__),e},In.prototype.reverse=function(){if(this.__filtered__){var e=new In(this);e.__dir__=-1,e.__filtered__=!0}else(e=this.clone()).__dir__*=-1;return e},In.prototype.value=function(){var e=this.__wrapped__.value(),t=this.__dir__,n=Nu(e),r=t<0,i=n?e.length:0,o=function(e,t,n){var r=-1,i=n.length;for(;++r=this.__values__.length;return{done:e,value:e?void 0:this.__values__[this.__index__++]}},xn.prototype.plant=function(e){for(var t,n=this;n instanceof On;){var r=xo(n);r.__index__=0,r.__values__=void 0,t?i.__wrapped__=r:t=r;var i=r;n=n.__wrapped__}return i.__wrapped__=e,t},xn.prototype.reverse=function(){var e=this.__wrapped__;if(e instanceof In){var t=e;return this.__actions__.length&&(t=new In(this)),(t=t.reverse()).__actions__.push({func:nu,args:[Ho],thisArg:void 0}),new Pn(t,this.__chain__)}return this.thru(Ho)},xn.prototype.toJSON=xn.prototype.valueOf=xn.prototype.value=function(){return ni(this.__wrapped__,this.__actions__)},xn.prototype.first=xn.prototype.head,gt&&(xn.prototype[gt]=function(){return this}),xn}();Ge._=$t,void 0===(r=function(){return $t}.call(t,n,t,e))||(e.exports=r)}.call(this)},1573:e=>{"use strict";const t=(e,t)=>{for(const n of Reflect.ownKeys(t))Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n));return e};e.exports=t,e.exports.default=t},9381:e=>{"use strict"; -/* -object-assign -(c) Sindre Sorhus -@license MIT -*/var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;function i(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,o){for(var u,a,l=i(e),s=1;s{"use strict";const r=n(1573),i=new WeakMap,o=(e,t={})=>{if("function"!=typeof e)throw new TypeError("Expected a function");let n,o=!1,u=0;const a=e.displayName||e.name||"",l=function(...r){if(i.set(l,++u),o){if(!0===t.throw)throw new Error(`Function \`${a}\` can only be called once`);return n}return o=!0,n=e.apply(this,r),e=null,n};return r(l,e),i.set(l,u),l};e.exports=o,e.exports.default=o,e.exports.callCount=e=>{if(!i.has(e))throw new Error(`The given function \`${e.name}\` is not wrapped by the \`onetime\` package`);return i.get(e)}},8070:(e,t,n)=>{"use strict";const r=n(2413),i=["assert","count","countReset","debug","dir","dirxml","error","group","groupCollapsed","groupEnd","info","log","table","time","timeEnd","timeLog","trace","warn"];let o={};e.exports=e=>{const t=new r.PassThrough,n=new r.PassThrough;t.write=t=>e("stdout",t),n.write=t=>e("stderr",t);const u=new console.Console(t,n);for(const e of i)o[e]=console[e],console[e]=u[e];return()=>{for(const e of i)console[e]=o[e];o={}}}},5187:e=>{window,e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=20)}([function(e,t,n){"use strict";e.exports=n(12)},function(e,t,n){"use strict"; -/* -object-assign -(c) Sindre Sorhus -@license MIT -*/var r=Object.getOwnPropertySymbols,i=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable;function u(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,a,l=u(e),s=1;s=t||n<0||f&&e-s>=o}function w(){var e=h();if(b(e))return E(e);a=setTimeout(w,function(e){var n=t-(e-l);return f?p(n,o-(e-s)):n}(e))}function E(e){return a=void 0,m&&r?y(e):(r=i=void 0,u)}function D(){var e=h(),n=b(e);if(r=arguments,i=this,l=e,n){if(void 0===a)return _(l);if(f)return a=setTimeout(w,t),y(l)}return void 0===a&&(a=setTimeout(w,t)),u}return t=g(t)||0,v(n)&&(c=!!n.leading,o=(f="maxWait"in n)?d(g(n.maxWait)||0,t):o,m="trailing"in n?!!n.trailing:m),D.cancel=function(){void 0!==a&&clearTimeout(a),s=0,r=l=i=a=void 0},D.flush=function(){return void 0===a?u:E(h())},D}(e,t,{leading:r,maxWait:t,trailing:i})}}).call(this,n(4))},function(e,t,n){(function(n){function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var i;t=e.exports=p,i="object"===(void 0===n?"undefined":r(n))&&n.env&&n.env.NODE_DEBUG&&/\bsemver\b/i.test(n.env.NODE_DEBUG)?function(){var e=Array.prototype.slice.call(arguments,0);e.unshift("SEMVER"),console.log.apply(console,e)}:function(){},t.SEMVER_SPEC_VERSION="2.0.0";var o=Number.MAX_SAFE_INTEGER||9007199254740991,u=t.re=[],a=t.src=[],l=t.tokens={},s=0;function c(e){l[e]=s++}c("NUMERICIDENTIFIER"),a[l.NUMERICIDENTIFIER]="0|[1-9]\\d*",c("NUMERICIDENTIFIERLOOSE"),a[l.NUMERICIDENTIFIERLOOSE]="[0-9]+",c("NONNUMERICIDENTIFIER"),a[l.NONNUMERICIDENTIFIER]="\\d*[a-zA-Z-][a-zA-Z0-9-]*",c("MAINVERSION"),a[l.MAINVERSION]="("+a[l.NUMERICIDENTIFIER]+")\\.("+a[l.NUMERICIDENTIFIER]+")\\.("+a[l.NUMERICIDENTIFIER]+")",c("MAINVERSIONLOOSE"),a[l.MAINVERSIONLOOSE]="("+a[l.NUMERICIDENTIFIERLOOSE]+")\\.("+a[l.NUMERICIDENTIFIERLOOSE]+")\\.("+a[l.NUMERICIDENTIFIERLOOSE]+")",c("PRERELEASEIDENTIFIER"),a[l.PRERELEASEIDENTIFIER]="(?:"+a[l.NUMERICIDENTIFIER]+"|"+a[l.NONNUMERICIDENTIFIER]+")",c("PRERELEASEIDENTIFIERLOOSE"),a[l.PRERELEASEIDENTIFIERLOOSE]="(?:"+a[l.NUMERICIDENTIFIERLOOSE]+"|"+a[l.NONNUMERICIDENTIFIER]+")",c("PRERELEASE"),a[l.PRERELEASE]="(?:-("+a[l.PRERELEASEIDENTIFIER]+"(?:\\."+a[l.PRERELEASEIDENTIFIER]+")*))",c("PRERELEASELOOSE"),a[l.PRERELEASELOOSE]="(?:-?("+a[l.PRERELEASEIDENTIFIERLOOSE]+"(?:\\."+a[l.PRERELEASEIDENTIFIERLOOSE]+")*))",c("BUILDIDENTIFIER"),a[l.BUILDIDENTIFIER]="[0-9A-Za-z-]+",c("BUILD"),a[l.BUILD]="(?:\\+("+a[l.BUILDIDENTIFIER]+"(?:\\."+a[l.BUILDIDENTIFIER]+")*))",c("FULL"),c("FULLPLAIN"),a[l.FULLPLAIN]="v?"+a[l.MAINVERSION]+a[l.PRERELEASE]+"?"+a[l.BUILD]+"?",a[l.FULL]="^"+a[l.FULLPLAIN]+"$",c("LOOSEPLAIN"),a[l.LOOSEPLAIN]="[v=\\s]*"+a[l.MAINVERSIONLOOSE]+a[l.PRERELEASELOOSE]+"?"+a[l.BUILD]+"?",c("LOOSE"),a[l.LOOSE]="^"+a[l.LOOSEPLAIN]+"$",c("GTLT"),a[l.GTLT]="((?:<|>)?=?)",c("XRANGEIDENTIFIERLOOSE"),a[l.XRANGEIDENTIFIERLOOSE]=a[l.NUMERICIDENTIFIERLOOSE]+"|x|X|\\*",c("XRANGEIDENTIFIER"),a[l.XRANGEIDENTIFIER]=a[l.NUMERICIDENTIFIER]+"|x|X|\\*",c("XRANGEPLAIN"),a[l.XRANGEPLAIN]="[v=\\s]*("+a[l.XRANGEIDENTIFIER]+")(?:\\.("+a[l.XRANGEIDENTIFIER]+")(?:\\.("+a[l.XRANGEIDENTIFIER]+")(?:"+a[l.PRERELEASE]+")?"+a[l.BUILD]+"?)?)?",c("XRANGEPLAINLOOSE"),a[l.XRANGEPLAINLOOSE]="[v=\\s]*("+a[l.XRANGEIDENTIFIERLOOSE]+")(?:\\.("+a[l.XRANGEIDENTIFIERLOOSE]+")(?:\\.("+a[l.XRANGEIDENTIFIERLOOSE]+")(?:"+a[l.PRERELEASELOOSE]+")?"+a[l.BUILD]+"?)?)?",c("XRANGE"),a[l.XRANGE]="^"+a[l.GTLT]+"\\s*"+a[l.XRANGEPLAIN]+"$",c("XRANGELOOSE"),a[l.XRANGELOOSE]="^"+a[l.GTLT]+"\\s*"+a[l.XRANGEPLAINLOOSE]+"$",c("COERCE"),a[l.COERCE]="(^|[^\\d])(\\d{1,16})(?:\\.(\\d{1,16}))?(?:\\.(\\d{1,16}))?(?:$|[^\\d])",c("COERCERTL"),u[l.COERCERTL]=new RegExp(a[l.COERCE],"g"),c("LONETILDE"),a[l.LONETILDE]="(?:~>?)",c("TILDETRIM"),a[l.TILDETRIM]="(\\s*)"+a[l.LONETILDE]+"\\s+",u[l.TILDETRIM]=new RegExp(a[l.TILDETRIM],"g"),c("TILDE"),a[l.TILDE]="^"+a[l.LONETILDE]+a[l.XRANGEPLAIN]+"$",c("TILDELOOSE"),a[l.TILDELOOSE]="^"+a[l.LONETILDE]+a[l.XRANGEPLAINLOOSE]+"$",c("LONECARET"),a[l.LONECARET]="(?:\\^)",c("CARETTRIM"),a[l.CARETTRIM]="(\\s*)"+a[l.LONECARET]+"\\s+",u[l.CARETTRIM]=new RegExp(a[l.CARETTRIM],"g"),c("CARET"),a[l.CARET]="^"+a[l.LONECARET]+a[l.XRANGEPLAIN]+"$",c("CARETLOOSE"),a[l.CARETLOOSE]="^"+a[l.LONECARET]+a[l.XRANGEPLAINLOOSE]+"$",c("COMPARATORLOOSE"),a[l.COMPARATORLOOSE]="^"+a[l.GTLT]+"\\s*("+a[l.LOOSEPLAIN]+")$|^$",c("COMPARATOR"),a[l.COMPARATOR]="^"+a[l.GTLT]+"\\s*("+a[l.FULLPLAIN]+")$|^$",c("COMPARATORTRIM"),a[l.COMPARATORTRIM]="(\\s*)"+a[l.GTLT]+"\\s*("+a[l.LOOSEPLAIN]+"|"+a[l.XRANGEPLAIN]+")",u[l.COMPARATORTRIM]=new RegExp(a[l.COMPARATORTRIM],"g"),c("HYPHENRANGE"),a[l.HYPHENRANGE]="^\\s*("+a[l.XRANGEPLAIN]+")\\s+-\\s+("+a[l.XRANGEPLAIN]+")\\s*$",c("HYPHENRANGELOOSE"),a[l.HYPHENRANGELOOSE]="^\\s*("+a[l.XRANGEPLAINLOOSE]+")\\s+-\\s+("+a[l.XRANGEPLAINLOOSE]+")\\s*$",c("STAR"),a[l.STAR]="(<|>)?=?\\s*\\*";for(var f=0;f256)return null;if(!(t.loose?u[l.LOOSE]:u[l.FULL]).test(e))return null;try{return new p(e,t)}catch(e){return null}}function p(e,t){if(t&&"object"===r(t)||(t={loose:!!t,includePrerelease:!1}),e instanceof p){if(e.loose===t.loose)return e;e=e.version}else if("string"!=typeof e)throw new TypeError("Invalid Version: "+e);if(e.length>256)throw new TypeError("version is longer than 256 characters");if(!(this instanceof p))return new p(e,t);i("SemVer",e,t),this.options=t,this.loose=!!t.loose;var n=e.trim().match(t.loose?u[l.LOOSE]:u[l.FULL]);if(!n)throw new TypeError("Invalid Version: "+e);if(this.raw=e,this.major=+n[1],this.minor=+n[2],this.patch=+n[3],this.major>o||this.major<0)throw new TypeError("Invalid major version");if(this.minor>o||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>o||this.patch<0)throw new TypeError("Invalid patch version");n[4]?this.prerelease=n[4].split(".").map((function(e){if(/^[0-9]+$/.test(e)){var t=+e;if(t>=0&&t=0;)"number"==typeof this.prerelease[n]&&(this.prerelease[n]++,n=-2);-1===n&&this.prerelease.push(0)}t&&(this.prerelease[0]===t?isNaN(this.prerelease[1])&&(this.prerelease=[t,0]):this.prerelease=[t,0]);break;default:throw new Error("invalid increment argument: "+e)}return this.format(),this.raw=this.version,this},t.inc=function(e,t,n,r){"string"==typeof n&&(r=n,n=void 0);try{return new p(e,n).inc(t,r).version}catch(e){return null}},t.diff=function(e,t){if(_(e,t))return null;var n=d(e),r=d(t),i="";if(n.prerelease.length||r.prerelease.length){i="pre";var o="prerelease"}for(var u in n)if(("major"===u||"minor"===u||"patch"===u)&&n[u]!==r[u])return i+u;return o},t.compareIdentifiers=v;var h=/^[0-9]+$/;function v(e,t){var n=h.test(e),r=h.test(t);return n&&r&&(e=+e,t=+t),e===t?0:n&&!r?-1:r&&!n?1:e0}function y(e,t,n){return m(e,t,n)<0}function _(e,t,n){return 0===m(e,t,n)}function b(e,t,n){return 0!==m(e,t,n)}function w(e,t,n){return m(e,t,n)>=0}function E(e,t,n){return m(e,t,n)<=0}function D(e,t,n,i){switch(t){case"===":return"object"===r(e)&&(e=e.version),"object"===r(n)&&(n=n.version),e===n;case"!==":return"object"===r(e)&&(e=e.version),"object"===r(n)&&(n=n.version),e!==n;case"":case"=":case"==":return _(e,n,i);case"!=":return b(e,n,i);case">":return g(e,n,i);case">=":return w(e,n,i);case"<":return y(e,n,i);case"<=":return E(e,n,i);default:throw new TypeError("Invalid operator: "+t)}}function S(e,t){if(t&&"object"===r(t)||(t={loose:!!t,includePrerelease:!1}),e instanceof S){if(e.loose===!!t.loose)return e;e=e.value}if(!(this instanceof S))return new S(e,t);i("comparator",e,t),this.options=t,this.loose=!!t.loose,this.parse(e),this.semver===C?this.value="":this.value=this.operator+this.semver.version,i("comp",this)}t.rcompareIdentifiers=function(e,t){return v(t,e)},t.major=function(e,t){return new p(e,t).major},t.minor=function(e,t){return new p(e,t).minor},t.patch=function(e,t){return new p(e,t).patch},t.compare=m,t.compareLoose=function(e,t){return m(e,t,!0)},t.compareBuild=function(e,t,n){var r=new p(e,n),i=new p(t,n);return r.compare(i)||r.compareBuild(i)},t.rcompare=function(e,t,n){return m(t,e,n)},t.sort=function(e,n){return e.sort((function(e,r){return t.compareBuild(e,r,n)}))},t.rsort=function(e,n){return e.sort((function(e,r){return t.compareBuild(r,e,n)}))},t.gt=g,t.lt=y,t.eq=_,t.neq=b,t.gte=w,t.lte=E,t.cmp=D,t.Comparator=S;var C={};function k(e,t){if(t&&"object"===r(t)||(t={loose:!!t,includePrerelease:!1}),e instanceof k)return e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease?e:new k(e.raw,t);if(e instanceof S)return new k(e.value,t);if(!(this instanceof k))return new k(e,t);if(this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease,this.raw=e,this.set=e.split(/\s*\|\|\s*/).map((function(e){return this.parseRange(e.trim())}),this).filter((function(e){return e.length})),!this.set.length)throw new TypeError("Invalid SemVer Range: "+e);this.format()}function T(e,t){for(var n=!0,r=e.slice(),i=r.pop();n&&r.length;)n=r.every((function(e){return i.intersects(e,t)})),i=r.pop();return n}function x(e){return!e||"x"===e.toLowerCase()||"*"===e}function A(e,t,n,r,i,o,u,a,l,s,c,f,d){return((t=x(n)?"":x(r)?">="+n+".0.0":x(i)?">="+n+"."+r+".0":">="+t)+" "+(a=x(l)?"":x(s)?"<"+(+l+1)+".0.0":x(c)?"<"+l+"."+(+s+1)+".0":f?"<="+l+"."+s+"."+c+"-"+f:"<="+a)).trim()}function O(e,t,n){for(var r=0;r0){var o=e[r].semver;if(o.major===t.major&&o.minor===t.minor&&o.patch===t.patch)return!0}return!1}return!0}function P(e,t,n){try{t=new k(t,n)}catch(e){return!1}return t.test(e)}function I(e,t,n,r){var i,o,u,a,l;switch(e=new p(e,r),t=new k(t,r),n){case">":i=g,o=E,u=y,a=">",l=">=";break;case"<":i=y,o=w,u=g,a="<",l="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(P(e,t,r))return!1;for(var s=0;s=0.0.0")),f=f||e,d=d||e,i(e.semver,f.semver,r)?f=e:u(e.semver,d.semver,r)&&(d=e)})),f.operator===a||f.operator===l)return!1;if((!d.operator||d.operator===a)&&o(e,d.semver))return!1;if(d.operator===l&&u(e,d.semver))return!1}return!0}S.prototype.parse=function(e){var t=this.options.loose?u[l.COMPARATORLOOSE]:u[l.COMPARATOR],n=e.match(t);if(!n)throw new TypeError("Invalid comparator: "+e);this.operator=void 0!==n[1]?n[1]:"","="===this.operator&&(this.operator=""),n[2]?this.semver=new p(n[2],this.options.loose):this.semver=C},S.prototype.toString=function(){return this.value},S.prototype.test=function(e){if(i("Comparator.test",e,this.options.loose),this.semver===C||e===C)return!0;if("string"==typeof e)try{e=new p(e,this.options)}catch(e){return!1}return D(e,this.operator,this.semver,this.options)},S.prototype.intersects=function(e,t){if(!(e instanceof S))throw new TypeError("a Comparator is required");var n;if(t&&"object"===r(t)||(t={loose:!!t,includePrerelease:!1}),""===this.operator)return""===this.value||(n=new k(e.value,t),P(this.value,n,t));if(""===e.operator)return""===e.value||(n=new k(this.value,t),P(e.semver,n,t));var i=!(">="!==this.operator&&">"!==this.operator||">="!==e.operator&&">"!==e.operator),o=!("<="!==this.operator&&"<"!==this.operator||"<="!==e.operator&&"<"!==e.operator),u=this.semver.version===e.semver.version,a=!(">="!==this.operator&&"<="!==this.operator||">="!==e.operator&&"<="!==e.operator),l=D(this.semver,"<",e.semver,t)&&(">="===this.operator||">"===this.operator)&&("<="===e.operator||"<"===e.operator),s=D(this.semver,">",e.semver,t)&&("<="===this.operator||"<"===this.operator)&&(">="===e.operator||">"===e.operator);return i||o||u&&a||l||s},t.Range=k,k.prototype.format=function(){return this.range=this.set.map((function(e){return e.join(" ").trim()})).join("||").trim(),this.range},k.prototype.toString=function(){return this.range},k.prototype.parseRange=function(e){var t=this.options.loose;e=e.trim();var n=t?u[l.HYPHENRANGELOOSE]:u[l.HYPHENRANGE];e=e.replace(n,A),i("hyphen replace",e),e=e.replace(u[l.COMPARATORTRIM],"$1$2$3"),i("comparator trim",e,u[l.COMPARATORTRIM]),e=(e=(e=e.replace(u[l.TILDETRIM],"$1~")).replace(u[l.CARETTRIM],"$1^")).split(/\s+/).join(" ");var r=t?u[l.COMPARATORLOOSE]:u[l.COMPARATOR],o=e.split(" ").map((function(e){return function(e,t){return i("comp",e,t),e=function(e,t){return e.trim().split(/\s+/).map((function(e){return function(e,t){i("caret",e,t);var n=t.loose?u[l.CARETLOOSE]:u[l.CARET];return e.replace(n,(function(t,n,r,o,u){var a;return i("caret",e,t,n,r,o,u),x(n)?a="":x(r)?a=">="+n+".0.0 <"+(+n+1)+".0.0":x(o)?a="0"===n?">="+n+"."+r+".0 <"+n+"."+(+r+1)+".0":">="+n+"."+r+".0 <"+(+n+1)+".0.0":u?(i("replaceCaret pr",u),a="0"===n?"0"===r?">="+n+"."+r+"."+o+"-"+u+" <"+n+"."+r+"."+(+o+1):">="+n+"."+r+"."+o+"-"+u+" <"+n+"."+(+r+1)+".0":">="+n+"."+r+"."+o+"-"+u+" <"+(+n+1)+".0.0"):(i("no pr"),a="0"===n?"0"===r?">="+n+"."+r+"."+o+" <"+n+"."+r+"."+(+o+1):">="+n+"."+r+"."+o+" <"+n+"."+(+r+1)+".0":">="+n+"."+r+"."+o+" <"+(+n+1)+".0.0"),i("caret return",a),a}))}(e,t)})).join(" ")}(e,t),i("caret",e),e=function(e,t){return e.trim().split(/\s+/).map((function(e){return function(e,t){var n=t.loose?u[l.TILDELOOSE]:u[l.TILDE];return e.replace(n,(function(t,n,r,o,u){var a;return i("tilde",e,t,n,r,o,u),x(n)?a="":x(r)?a=">="+n+".0.0 <"+(+n+1)+".0.0":x(o)?a=">="+n+"."+r+".0 <"+n+"."+(+r+1)+".0":u?(i("replaceTilde pr",u),a=">="+n+"."+r+"."+o+"-"+u+" <"+n+"."+(+r+1)+".0"):a=">="+n+"."+r+"."+o+" <"+n+"."+(+r+1)+".0",i("tilde return",a),a}))}(e,t)})).join(" ")}(e,t),i("tildes",e),e=function(e,t){return i("replaceXRanges",e,t),e.split(/\s+/).map((function(e){return function(e,t){e=e.trim();var n=t.loose?u[l.XRANGELOOSE]:u[l.XRANGE];return e.replace(n,(function(n,r,o,u,a,l){i("xRange",e,n,r,o,u,a,l);var s=x(o),c=s||x(u),f=c||x(a),d=f;return"="===r&&d&&(r=""),l=t.includePrerelease?"-0":"",s?n=">"===r||"<"===r?"<0.0.0-0":"*":r&&d?(c&&(u=0),a=0,">"===r?(r=">=",c?(o=+o+1,u=0,a=0):(u=+u+1,a=0)):"<="===r&&(r="<",c?o=+o+1:u=+u+1),n=r+o+"."+u+"."+a+l):c?n=">="+o+".0.0"+l+" <"+(+o+1)+".0.0"+l:f&&(n=">="+o+"."+u+".0"+l+" <"+o+"."+(+u+1)+".0"+l),i("xRange return",n),n}))}(e,t)})).join(" ")}(e,t),i("xrange",e),e=function(e,t){return i("replaceStars",e,t),e.trim().replace(u[l.STAR],"")}(e,t),i("stars",e),e}(e,this.options)}),this).join(" ").split(/\s+/);return this.options.loose&&(o=o.filter((function(e){return!!e.match(r)}))),o.map((function(e){return new S(e,this.options)}),this)},k.prototype.intersects=function(e,t){if(!(e instanceof k))throw new TypeError("a Range is required");return this.set.some((function(n){return T(n,t)&&e.set.some((function(e){return T(e,t)&&n.every((function(n){return e.every((function(e){return n.intersects(e,t)}))}))}))}))},t.toComparators=function(e,t){return new k(e,t).set.map((function(e){return e.map((function(e){return e.value})).join(" ").trim().split(" ")}))},k.prototype.test=function(e){if(!e)return!1;if("string"==typeof e)try{e=new p(e,this.options)}catch(e){return!1}for(var t=0;t":0===t.prerelease.length?t.patch++:t.prerelease.push(0),t.raw=t.format();case"":case">=":n&&!g(n,t)||(n=t);break;case"<":case"<=":break;default:throw new Error("Unexpected operation: "+e.operator)}}));return n&&e.test(n)?n:null},t.validRange=function(e,t){try{return new k(e,t).range||"*"}catch(e){return null}},t.ltr=function(e,t,n){return I(e,t,"<",n)},t.gtr=function(e,t,n){return I(e,t,">",n)},t.outside=I,t.prerelease=function(e,t){var n=d(e,t);return n&&n.prerelease.length?n.prerelease:null},t.intersects=function(e,t,n){return e=new k(e,n),t=new k(t,n),e.intersects(t)},t.coerce=function(e,t){if(e instanceof p)return e;if("number"==typeof e&&(e=String(e)),"string"!=typeof e)return null;var n=null;if((t=t||{}).rtl){for(var r;(r=u[l.COERCERTL].exec(e))&&(!n||n.index+n[0].length!==e.length);)n&&r.index+r[0].length===n.index+n[0].length||(n=r),u[l.COERCERTL].lastIndex=r.index+r[1].length+r[2].length;u[l.COERCERTL].lastIndex=-1}else n=e.match(u[l.COERCE]);return null===n?null:d(n[2]+"."+(n[3]||"0")+"."+(n[4]||"0"),t)}}).call(this,n(5))},function(e,t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var r;r=function(){return this}();try{r=r||new Function("return this")()}catch(e){"object"===("undefined"==typeof window?"undefined":n(window))&&(r=window)}e.exports=r},function(e,t){var n,r,i=e.exports={};function o(){throw new Error("setTimeout has not been defined")}function u(){throw new Error("clearTimeout has not been defined")}function a(e){if(n===setTimeout)return setTimeout(e,0);if((n===o||!n)&&setTimeout)return n=setTimeout,setTimeout(e,0);try{return n(e,0)}catch(t){try{return n.call(null,e,0)}catch(t){return n.call(this,e,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:o}catch(e){n=o}try{r="function"==typeof clearTimeout?clearTimeout:u}catch(e){r=u}}();var l,s=[],c=!1,f=-1;function d(){c&&l&&(c=!1,l.length?s=l.concat(s):f=-1,s.length&&p())}function p(){if(!c){var e=a(d);c=!0;for(var t=s.length;t;){for(l=s,s=[];++f1)for(var n=1;nthis[u])return w(this,this[h].get(e)),!1;var o=this[h].get(e).value;return this[f]&&(this[d]||this[f](e,o.value)),o.now=r,o.maxAge=n,o.value=t,this[a]+=i-o.length,o.length=i,this.get(e),b(this),!0}var s=new E(e,t,i,r,n);return s.length>this[u]?(this[f]&&this[f](e,t),!1):(this[a]+=s.length,this[p].unshift(s),this[h].set(e,this[p].head),b(this),!0)}},{key:"has",value:function(e){if(!this[h].has(e))return!1;var t=this[h].get(e).value;return!_(this,t)}},{key:"get",value:function(e){return y(this,e,!0)}},{key:"peek",value:function(e){return y(this,e,!1)}},{key:"pop",value:function(){var e=this[p].tail;return e?(w(this,e),e.value):null}},{key:"del",value:function(e){w(this,this[h].get(e))}},{key:"load",value:function(e){this.reset();for(var t=Date.now(),n=e.length-1;n>=0;n--){var r=e[n],i=r.e||0;if(0===i)this.set(r.k,r.v);else{var o=i-t;o>0&&this.set(r.k,r.v,o)}}}},{key:"prune",value:function(){var e=this;this[h].forEach((function(t,n){return y(e,n,!1)}))}},{key:"max",set:function(e){if("number"!=typeof e||e<0)throw new TypeError("max must be a non-negative number");this[u]=e||1/0,b(this)},get:function(){return this[u]}},{key:"allowStale",set:function(e){this[s]=!!e},get:function(){return this[s]}},{key:"maxAge",set:function(e){if("number"!=typeof e)throw new TypeError("maxAge must be a non-negative number");this[c]=e,b(this)},get:function(){return this[c]}},{key:"lengthCalculator",set:function(e){var t=this;"function"!=typeof e&&(e=m),e!==this[l]&&(this[l]=e,this[a]=0,this[p].forEach((function(e){e.length=t[l](e.value,e.key),t[a]+=e.length}))),b(this)},get:function(){return this[l]}},{key:"length",get:function(){return this[a]}},{key:"itemCount",get:function(){return this[p].length}}])&&i(t.prototype,n),e}(),y=function(e,t,n){var r=e[h].get(t);if(r){var i=r.value;if(_(e,i)){if(w(e,r),!e[s])return}else n&&(e[v]&&(r.value.now=Date.now()),e[p].unshiftNode(r));return i.value}},_=function(e,t){if(!t||!t.maxAge&&!e[c])return!1;var n=Date.now()-t.now;return t.maxAge?n>t.maxAge:e[c]&&n>e[c]},b=function(e){if(e[a]>e[u])for(var t=e[p].tail;e[a]>e[u]&&null!==t;){var n=t.prev;w(e,t),t=n}},w=function(e,t){if(t){var n=t.value;e[f]&&e[f](n.key,n.value),e[a]-=n.length,e[h].delete(n.key),e[p].removeNode(t)}},E=function e(t,n,i,o,u){r(this,e),this.key=t,this.value=n,this.length=i,this.now=o,this.maxAge=u||0},D=function(e,t,n,r){var i=n.value;_(e,i)&&(w(e,n),e[s]||(i=void 0)),i&&t.call(r,i.value,i.key,e)};e.exports=g},function(e,t,n){(function(t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}e.exports=function(){if("undefined"==typeof document||!document.addEventListener)return null;var r,i,o,u={};return u.copy=function(){var e=!1,t=null,n=!1;function r(){e=!1,t=null,n&&window.getSelection().removeAllRanges(),n=!1}return document.addEventListener("copy",(function(n){if(e){for(var r in t)n.clipboardData.setData(r,t[r]);n.preventDefault()}})),function(i){return new Promise((function(o,u){e=!0,"string"==typeof i?t={"text/plain":i}:i instanceof Node?t={"text/html":(new XMLSerializer).serializeToString(i)}:i instanceof Object?t=i:u("Invalid data type. Must be string, DOM node, or an object mapping MIME types to strings."),function e(t){try{if(document.execCommand("copy"))r(),o();else{if(t)throw r(),new Error("Unable to copy. Perhaps it's not available in your browser?");!function(){var e=document.getSelection();if(!document.queryCommandEnabled("copy")&&e.isCollapsed){var t=document.createRange();t.selectNodeContents(document.body),e.removeAllRanges(),e.addRange(t),n=!0}}(),e(!0)}}catch(e){r(),u(e)}}(!1)}))}}(),u.paste=(o=!1,document.addEventListener("paste",(function(e){if(o){o=!1,e.preventDefault();var t=r;r=null,t(e.clipboardData.getData(i))}})),function(e){return new Promise((function(t,n){o=!0,r=t,i=e||"text/plain";try{document.execCommand("paste")||(o=!1,n(new Error("Unable to paste. Pasting only works in Internet Explorer at the moment.")))}catch(e){o=!1,n(new Error(e))}}))}),"undefined"==typeof ClipboardEvent&&void 0!==window.clipboardData&&void 0!==window.clipboardData.setData&&( -/*! promise-polyfill 2.0.1 */ -function(r){function i(e,t){return function(){e.apply(t,arguments)}}function o(e){if("object"!=n(this))throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=null,this._value=null,this._deferreds=[],f(e,i(a,this),i(l,this))}function u(e){var t=this;return null===this._state?void this._deferreds.push(e):void d((function(){var n=t._state?e.onFulfilled:e.onRejected;if(null!==n){var r;try{r=n(t._value)}catch(t){return void e.reject(t)}e.resolve(r)}else(t._state?e.resolve:e.reject)(t._value)}))}function a(e){try{if(e===this)throw new TypeError("A promise cannot be resolved with itself.");if(e&&("object"==n(e)||"function"==typeof e)){var t=e.then;if("function"==typeof t)return void f(i(t,e),i(a,this),i(l,this))}this._state=!0,this._value=e,s.call(this)}catch(e){l.call(this,e)}}function l(e){this._state=!1,this._value=e,s.call(this)}function s(){for(var e=0,t=this._deferreds.length;t>e;e++)u.call(this,this._deferreds[e]);this._deferreds=null}function c(e,t,n,r){this.onFulfilled="function"==typeof e?e:null,this.onRejected="function"==typeof t?t:null,this.resolve=n,this.reject=r}function f(e,t,n){var r=!1;try{e((function(e){r||(r=!0,t(e))}),(function(e){r||(r=!0,n(e))}))}catch(e){if(r)return;r=!0,n(e)}}var d=o.immediateFn||"function"==typeof t&&t||function(e){setTimeout(e,1)},p=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)};o.prototype.catch=function(e){return this.then(null,e)},o.prototype.then=function(e,t){var n=this;return new o((function(r,i){u.call(n,new c(e,t,r,i))}))},o.all=function(){var e=Array.prototype.slice.call(1===arguments.length&&p(arguments[0])?arguments[0]:arguments);return new o((function(t,r){function i(u,a){try{if(a&&("object"==n(a)||"function"==typeof a)){var l=a.then;if("function"==typeof l)return void l.call(a,(function(e){i(u,e)}),r)}e[u]=a,0==--o&&t(e)}catch(e){r(e)}}if(0===e.length)return t([]);for(var o=e.length,u=0;ur;r++)e[r].then(t,n)}))},e.exports?e.exports=o:r.Promise||(r.Promise=o)}(this),u.copy=function(e){return new Promise((function(t,n){if("string"!=typeof e&&!("text/plain"in e))throw new Error("You must provide a text/plain type.");var r="string"==typeof e?e:e["text/plain"];window.clipboardData.setData("Text",r)?t():n(new Error("Copying was rejected."))}))},u.paste=function(){return new Promise((function(e,t){var n=window.clipboardData.getData("Text");n?e(n):t(new Error("Pasting was rejected."))}))}),u}()}).call(this,n(13).setImmediate)},function(e,t,n){"use strict";e.exports=n(15)},function(e,t,n){"use strict";n.r(t),t.default=":root {\n /**\n * IMPORTANT: When new theme variables are added below– also add them to SettingsContext updateThemeVariables()\n */\n\n /* Light theme */\n --light-color-attribute-name: #ef6632;\n --light-color-attribute-name-not-editable: #23272f;\n --light-color-attribute-name-inverted: rgba(255, 255, 255, 0.7);\n --light-color-attribute-value: #1a1aa6;\n --light-color-attribute-value-inverted: #ffffff;\n --light-color-attribute-editable-value: #1a1aa6;\n --light-color-background: #ffffff;\n --light-color-background-hover: rgba(0, 136, 250, 0.1);\n --light-color-background-inactive: #e5e5e5;\n --light-color-background-invalid: #fff0f0;\n --light-color-background-selected: #0088fa;\n --light-color-button-background: #ffffff;\n --light-color-button-background-focus: #ededed;\n --light-color-button: #5f6673;\n --light-color-button-disabled: #cfd1d5;\n --light-color-button-active: #0088fa;\n --light-color-button-focus: #23272f;\n --light-color-button-hover: #23272f;\n --light-color-border: #eeeeee;\n --light-color-commit-did-not-render-fill: #cfd1d5;\n --light-color-commit-did-not-render-fill-text: #000000;\n --light-color-commit-did-not-render-pattern: #cfd1d5;\n --light-color-commit-did-not-render-pattern-text: #333333;\n --light-color-commit-gradient-0: #37afa9;\n --light-color-commit-gradient-1: #63b19e;\n --light-color-commit-gradient-2: #80b393;\n --light-color-commit-gradient-3: #97b488;\n --light-color-commit-gradient-4: #abb67d;\n --light-color-commit-gradient-5: #beb771;\n --light-color-commit-gradient-6: #cfb965;\n --light-color-commit-gradient-7: #dfba57;\n --light-color-commit-gradient-8: #efbb49;\n --light-color-commit-gradient-9: #febc38;\n --light-color-commit-gradient-text: #000000;\n --light-color-component-name: #6a51b2;\n --light-color-component-name-inverted: #ffffff;\n --light-color-component-badge-background: rgba(0, 0, 0, 0.1);\n --light-color-component-badge-background-inverted: rgba(255, 255, 255, 0.25);\n --light-color-component-badge-count: #777d88;\n --light-color-component-badge-count-inverted: rgba(255, 255, 255, 0.7);\n --light-color-context-background: rgba(0,0,0,.9);\n --light-color-context-background-hover: rgba(255, 255, 255, 0.1);\n --light-color-context-background-selected: #178fb9;\n --light-color-context-border: #3d424a;\n --light-color-context-text: #ffffff;\n --light-color-context-text-selected: #ffffff;\n --light-color-dim: #777d88;\n --light-color-dimmer: #cfd1d5;\n --light-color-dimmest: #eff0f1;\n --light-color-error-background: hsl(0, 100%, 97%);\n --light-color-error-border: hsl(0, 100%, 92%);\n --light-color-error-text: #ff0000;\n --light-color-expand-collapse-toggle: #777d88;\n --light-color-link: #0000ff;\n --light-color-modal-background: rgba(255, 255, 255, 0.75);\n --light-color-record-active: #fc3a4b;\n --light-color-record-hover: #3578e5;\n --light-color-record-inactive: #0088fa;\n --light-color-scroll-thumb: #c2c2c2;\n --light-color-scroll-track: #fafafa;\n --light-color-search-match: yellow;\n --light-color-search-match-current: #f7923b;\n --light-color-selected-tree-highlight-active: rgba(0, 136, 250, 0.1);\n --light-color-selected-tree-highlight-inactive: rgba(0, 0, 0, 0.05);\n --light-color-shadow: rgba(0, 0, 0, 0.25);\n --light-color-tab-selected-border: #0088fa;\n --light-color-text: #000000;\n --light-color-text-invalid: #ff0000;\n --light-color-text-selected: #ffffff;\n --light-color-toggle-background-invalid: #fc3a4b;\n --light-color-toggle-background-on: #0088fa;\n --light-color-toggle-background-off: #cfd1d5;\n --light-color-toggle-text: #ffffff;\n --light-color-tooltip-background: rgba(0, 0, 0, 0.9);\n --light-color-tooltip-text: #ffffff;\n\n /* Dark theme */\n --dark-color-attribute-name: #9d87d2;\n --dark-color-attribute-name-not-editable: #ededed;\n --dark-color-attribute-name-inverted: #282828;\n --dark-color-attribute-value: #cedae0;\n --dark-color-attribute-value-inverted: #ffffff;\n --dark-color-attribute-editable-value: yellow;\n --dark-color-background: #282c34;\n --dark-color-background-hover: rgba(255, 255, 255, 0.1);\n --dark-color-background-inactive: #3d424a;\n --dark-color-background-invalid: #5c0000;\n --dark-color-background-selected: #178fb9;\n --dark-color-button-background: #282c34;\n --dark-color-button-background-focus: #3d424a;\n --dark-color-button: #afb3b9;\n --dark-color-button-active: #61dafb;\n --dark-color-button-disabled: #4f5766;\n --dark-color-button-focus: #a2e9fc;\n --dark-color-button-hover: #ededed;\n --dark-color-border: #3d424a;\n --dark-color-commit-did-not-render-fill: #777d88;\n --dark-color-commit-did-not-render-fill-text: #000000;\n --dark-color-commit-did-not-render-pattern: #666c77;\n --dark-color-commit-did-not-render-pattern-text: #ffffff;\n --dark-color-commit-gradient-0: #37afa9;\n --dark-color-commit-gradient-1: #63b19e;\n --dark-color-commit-gradient-2: #80b393;\n --dark-color-commit-gradient-3: #97b488;\n --dark-color-commit-gradient-4: #abb67d;\n --dark-color-commit-gradient-5: #beb771;\n --dark-color-commit-gradient-6: #cfb965;\n --dark-color-commit-gradient-7: #dfba57;\n --dark-color-commit-gradient-8: #efbb49;\n --dark-color-commit-gradient-9: #febc38;\n --dark-color-commit-gradient-text: #000000;\n --dark-color-component-name: #61dafb;\n --dark-color-component-name-inverted: #282828;\n --dark-color-component-badge-background: rgba(255, 255, 255, 0.25);\n --dark-color-component-badge-background-inverted: rgba(0, 0, 0, 0.25);\n --dark-color-component-badge-count: #8f949d;\n --dark-color-component-badge-count-inverted: rgba(255, 255, 255, 0.7);\n --dark-color-context-background: rgba(255,255,255,.9);\n --dark-color-context-background-hover: rgba(0, 136, 250, 0.1);\n --dark-color-context-background-selected: #0088fa;\n --dark-color-context-border: #eeeeee;\n --dark-color-context-text: #000000;\n --dark-color-context-text-selected: #ffffff;\n --dark-color-dim: #8f949d;\n --dark-color-dimmer: #777d88;\n --dark-color-dimmest: #4f5766;\n --dark-color-error-background: #200;\n --dark-color-error-border: #900;\n --dark-color-error-text: #f55;\n --dark-color-expand-collapse-toggle: #8f949d;\n --dark-color-link: #61dafb;\n --dark-color-modal-background: rgba(0, 0, 0, 0.75);\n --dark-color-record-active: #fc3a4b;\n --dark-color-record-hover: #a2e9fc;\n --dark-color-record-inactive: #61dafb;\n --dark-color-scroll-thumb: #afb3b9;\n --dark-color-scroll-track: #313640;\n --dark-color-search-match: yellow;\n --dark-color-search-match-current: #f7923b;\n --dark-color-selected-tree-highlight-active: rgba(23, 143, 185, 0.15);\n --dark-color-selected-tree-highlight-inactive: rgba(255, 255, 255, 0.05);\n --dark-color-shadow: rgba(0, 0, 0, 0.5);\n --dark-color-tab-selected-border: #178fb9;\n --dark-color-text: #ffffff;\n --dark-color-text-invalid: #ff8080;\n --dark-color-text-selected: #ffffff;\n --dark-color-toggle-background-invalid: #fc3a4b;\n --dark-color-toggle-background-on: #178fb9;\n --dark-color-toggle-background-off: #777d88;\n --dark-color-toggle-text: #ffffff;\n --dark-color-tooltip-background: rgba(255, 255, 255, 0.9);\n --dark-color-tooltip-text: #000000;\n\n /* Font smoothing */\n --light-font-smoothing: auto;\n --dark-font-smoothing: antialiased;\n --font-smoothing: auto;\n\n /* Compact density */\n --compact-font-size-monospace-small: 9px;\n --compact-font-size-monospace-normal: 11px;\n --compact-font-size-monospace-large: 15px;\n --compact-font-size-sans-small: 10px;\n --compact-font-size-sans-normal: 12px;\n --compact-font-size-sans-large: 14px;\n --compact-line-height-data: 18px;\n --compact-root-font-size: 16px;\n\n /* Comfortable density */\n --comfortable-font-size-monospace-small: 10px;\n --comfortable-font-size-monospace-normal: 13px;\n --comfortable-font-size-monospace-large: 17px;\n --comfortable-font-size-sans-small: 12px;\n --comfortable-font-size-sans-normal: 14px;\n --comfortable-font-size-sans-large: 16px;\n --comfortable-line-height-data: 22px;\n --comfortable-root-font-size: 20px;\n\n /* GitHub.com system fonts */\n --font-family-monospace: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo,\n Courier, monospace;\n --font-family-sans: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica,\n Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;\n\n /* Constant values shared between JS and CSS */\n --interaction-commit-size: 10px;\n --interaction-label-width: 200px;\n}\n"},function(e,t,n){"use strict";function r(e){var t=this;if(t instanceof r||(t=new r),t.tail=null,t.head=null,t.length=0,e&&"function"==typeof e.forEach)e.forEach((function(e){t.push(e)}));else if(arguments.length>0)for(var n=0,i=arguments.length;n1)n=t;else{if(!this.head)throw new TypeError("Reduce of empty list with no initial value");r=this.head.next,n=this.head.value}for(var i=0;null!==r;i++)n=e(n,r.value,i),r=r.next;return n},r.prototype.reduceReverse=function(e,t){var n,r=this.tail;if(arguments.length>1)n=t;else{if(!this.tail)throw new TypeError("Reduce of empty list with no initial value");r=this.tail.prev,n=this.tail.value}for(var i=this.length-1;null!==r;i--)n=e(n,r.value,i),r=r.prev;return n},r.prototype.toArray=function(){for(var e=new Array(this.length),t=0,n=this.head;null!==n;t++)e[t]=n.value,n=n.next;return e},r.prototype.toArrayReverse=function(){for(var e=new Array(this.length),t=0,n=this.tail;null!==n;t++)e[t]=n.value,n=n.prev;return e},r.prototype.slice=function(e,t){(t=t||this.length)<0&&(t+=this.length),(e=e||0)<0&&(e+=this.length);var n=new r;if(tthis.length&&(t=this.length);for(var i=0,o=this.head;null!==o&&ithis.length&&(t=this.length);for(var i=this.length,o=this.tail;null!==o&&i>t;i--)o=o.prev;for(;null!==o&&i>e;i--,o=o.prev)n.push(o.value);return n},r.prototype.splice=function(e,t){e>this.length&&(e=this.length-1),e<0&&(e=this.length+e);for(var n=0,r=this.head;null!==r&&n=0&&(e._idleTimeoutId=setTimeout((function(){e._onTimeout&&e._onTimeout()}),t))},n(14),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(this,n(4))},function(e,t,n){(function(e,t){!function(e,n){"use strict";if(!e.setImmediate){var r,i,o,u,a,l=1,s={},c=!1,f=e.document,d=Object.getPrototypeOf&&Object.getPrototypeOf(e);d=d&&d.setTimeout?d:e,"[object process]"==={}.toString.call(e.process)?r=function(e){t.nextTick((function(){h(e)}))}:function(){if(e.postMessage&&!e.importScripts){var t=!0,n=e.onmessage;return e.onmessage=function(){t=!1},e.postMessage("","*"),e.onmessage=n,t}}()?(u="setImmediate$"+Math.random()+"$",a=function(t){t.source===e&&"string"==typeof t.data&&0===t.data.indexOf(u)&&h(+t.data.slice(u.length))},e.addEventListener?e.addEventListener("message",a,!1):e.attachEvent("onmessage",a),r=function(t){e.postMessage(u+t,"*")}):e.MessageChannel?((o=new MessageChannel).port1.onmessage=function(e){h(e.data)},r=function(e){o.port2.postMessage(e)}):f&&"onreadystatechange"in f.createElement("script")?(i=f.documentElement,r=function(e){var t=f.createElement("script");t.onreadystatechange=function(){h(e),t.onreadystatechange=null,i.removeChild(t),t=null},i.appendChild(t)}):r=function(e){setTimeout(h,0,e)},d.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;nv;v++)if(-1!==(h=g(p,c,v))){m=v,c=h;break e}c=-1}}e:{if(p=f,void 0!==(h=d().get(s.primitive)))for(v=0;vc-p?null:f.slice(p,c-1))){if(c=0,null!==r){for(;cc;r--)i=a.pop()}for(r=f.length-c-1;1<=r;r--)c=[],i.push({id:null,isStateEditable:!1,name:_(f[r-1].functionName),value:void 0,subHooks:c}),a.push(i),i=c;r=f}c="Context"===(f=s.primitive)||"DebugValue"===f?null:u++,i.push({id:c,isStateEditable:"Reducer"===f||"State"===f,name:f,value:s.value,subHooks:[]})}return function e(t,n){for(var r=[],i=0;i-1&&(t=t.replace(/eval code/g,"eval").replace(/(\(eval at [^()]*)|(\),.*$)/g,""));var n=t.replace(/^\s+/,"").replace(/\(eval code/g,"("),r=n.match(/ (\((.+):(\d+):(\d+)\)$)/),i=(n=r?n.replace(r[0],""):n).split(/\s+/).slice(1),o=this.extractLocation(r?r[1]:i.pop()),u=i.join(" ")||void 0,a=["eval",""].indexOf(o[0])>-1?void 0:o[0];return new e({functionName:u,fileName:a,lineNumber:o[1],columnNumber:o[2],source:t})}),this)},parseFFOrSafari:function(t){return t.stack.split("\n").filter((function(e){return!e.match(r)}),this).map((function(t){if(t.indexOf(" > eval")>-1&&(t=t.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g,":$1")),-1===t.indexOf("@")&&-1===t.indexOf(":"))return new e({functionName:t});var n=/((.*".+"[^@]*)?[^@]*)(?:@)/,r=t.match(n),i=r&&r[1]?r[1]:void 0,o=this.extractLocation(t.replace(n,""));return new e({functionName:i,fileName:o[0],lineNumber:o[1],columnNumber:o[2],source:t})}),this)},parseOpera:function(e){return!e.stacktrace||e.message.indexOf("\n")>-1&&e.message.split("\n").length>e.stacktrace.split("\n").length?this.parseOpera9(e):e.stack?this.parseOpera11(e):this.parseOpera10(e)},parseOpera9:function(t){for(var n=/Line (\d+).*script (?:in )?(\S+)/i,r=t.message.split("\n"),i=[],o=2,u=r.length;o/,"$2").replace(/\([^)]*\)/g,"")||void 0;o.match(/\(([^)]*)\)/)&&(n=o.replace(/^[^(]+\(([^)]*)\)$/,"$1"));var a=void 0===n||"[arguments not available]"===n?void 0:n.split(",");return new e({functionName:u,args:a,fileName:i[0],lineNumber:i[1],columnNumber:i[2],source:t})}),this)}}})?r.apply(t,i):r)||(e.exports=o)}()},function(e,t,n){var r,i,o;!function(n,u){"use strict";i=[],void 0===(o="function"==typeof(r=function(){function e(e){return e.charAt(0).toUpperCase()+e.substring(1)}function t(e){return function(){return this[e]}}var n=["isConstructor","isEval","isNative","isToplevel"],r=["columnNumber","lineNumber"],i=["fileName","functionName","source"],o=n.concat(r,i,["args"]);function u(t){if(t)for(var n=0;n1?n-1:0),i=1;i=0&&n.splice(r,1)}}}])&&r(t.prototype,n),e}(),o=n(2),u=n.n(o);try{var a=n(9).default,l=function(e){var t=new RegExp("".concat(e,": ([0-9]+)")),n=a.match(t);return parseInt(n[1],10)};l("comfortable-line-height-data"),l("compact-line-height-data")}catch(e){}function s(e){try{return sessionStorage.getItem(e)}catch(e){return null}}function c(e){try{sessionStorage.removeItem(e)}catch(e){}}function f(e,t){try{return sessionStorage.setItem(e,t)}catch(e){}}var d=function(e,t){return e===t},p=n(1),h=n.n(p);function v(e){return e.ownerDocument?e.ownerDocument.defaultView:null}function m(e){var t=v(e);return t?t.frameElement:null}function g(e){var t=b(e);return y([e.getBoundingClientRect(),{top:t.borderTop,left:t.borderLeft,bottom:t.borderBottom,right:t.borderRight,width:0,height:0}])}function y(e){return e.reduce((function(e,t){return null==e?t:{top:e.top+t.top,left:e.left+t.left,width:e.width,height:e.height,bottom:e.bottom+t.bottom,right:e.right+t.right}}))}function _(e,t){var n=m(e);if(n&&n!==t){for(var r=[e.getBoundingClientRect()],i=n,o=!1;i;){var u=g(i);if(r.push(u),i=m(i),o)break;i&&v(i)===t&&(o=!0)}return y(r)}return e.getBoundingClientRect()}function b(e){var t=window.getComputedStyle(e);return{borderLeft:parseInt(t.borderLeftWidth,10),borderRight:parseInt(t.borderRightWidth,10),borderTop:parseInt(t.borderTopWidth,10),borderBottom:parseInt(t.borderBottomWidth,10),marginLeft:parseInt(t.marginLeft,10),marginRight:parseInt(t.marginRight,10),marginTop:parseInt(t.marginTop,10),marginBottom:parseInt(t.marginBottom,10),paddingLeft:parseInt(t.paddingLeft,10),paddingRight:parseInt(t.paddingRight,10),paddingTop:parseInt(t.paddingTop,10),paddingBottom:parseInt(t.paddingBottom,10)}}function w(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);nt.left+t.width&&(u=t.left+t.width-o-5),{style:{top:r+="px",left:u+="px"}}}(e,t,{width:n.width,height:n.height});h()(this.tip.style,r.style)}}]),e}(),T=function(){function e(){E(this,e);var t=window.__REACT_DEVTOOLS_TARGET_WINDOW__||window;this.window=t;var n=window.__REACT_DEVTOOLS_TARGET_WINDOW__||window;this.tipBoundsWindow=n;var r=t.document;this.container=r.createElement("div"),this.container.style.zIndex="10000000",this.tip=new k(r,this.container),this.rects=[],r.body.appendChild(this.container)}return S(e,[{key:"remove",value:function(){this.tip.remove(),this.rects.forEach((function(e){e.remove()})),this.rects.length=0,this.container.parentNode&&this.container.parentNode.removeChild(this.container)}},{key:"inspect",value:function(e,t){for(var n=this,r=e.filter((function(e){return e.nodeType===Node.ELEMENT_NODE}));this.rects.length>r.length;)this.rects.pop().remove();if(0!==r.length){for(;this.rects.length=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,u=!0,a=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return u=e.done,e},e:function(e){a=!0,o=e},f:function(){try{u||null==n.return||n.return()}finally{if(a)throw o}}}}(u.rendererInterfaces.values());try{for(s.s();!(a=s.n()).done;){var c=a.value,f=c.getFiberIDForNative(o,!0);if(null!==f){l=c.getDisplayNameForFiberID(f,!0);break}}}catch(e){s.e(e)}finally{s.f()}l&&(t+=" (in "+l+")")}}this.tip.updateText(t,i.right-i.left,i.bottom-i.top);var d=_(this.tipBoundsWindow.document.documentElement,this.window);this.tip.updatePosition({top:i.top,left:i.left,height:i.bottom-i.top,width:i.right-i.left},{top:d.top+this.tipBoundsWindow.scrollY,left:d.left+this.tipBoundsWindow.scrollX,height:this.tipBoundsWindow.innerHeight,width:this.tipBoundsWindow.innerWidth})}}}]),e}();function x(e,t,n){h()(n.style,{borderTopWidth:e[t+"Top"]+"px",borderLeftWidth:e[t+"Left"]+"px",borderRightWidth:e[t+"Right"]+"px",borderBottomWidth:e[t+"Bottom"]+"px",borderStyle:"solid"})}var A={background:"rgba(120, 170, 210, 0.7)",padding:"rgba(77, 200, 0, 0.3)",margin:"rgba(255, 155, 0, 0.3)",border:"rgba(255, 200, 50, 0.3)"},O=null,P=null;function I(){O=null,null!==P&&(P.remove(),P=null)}function N(e,t,n){null!=window.document&&(null!==O&&clearTimeout(O),null!=e&&(null===P&&(P=new T),P.inspect(e,t),n&&(O=setTimeout(I,2e3))))}var M=new Set,R=["#37afa9","#63b19e","#80b393","#97b488","#abb67d","#beb771","#cfb965","#dfba57","#efbb49","#febc38"],F=null;function L(e){return(L="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var B="object"===("undefined"==typeof performance?"undefined":L(performance))&&"function"==typeof performance.now?function(){return performance.now()}:function(){return Date.now()},j=new Map,U=null,z=!1,W=null;function H(e){z&&(e.forEach((function(e){var t=j.get(e),n=B(),r=null!=t?t.lastMeasuredAt:0,i=null!=t?t.rect:null;(null===i||r+2505&&void 0!==arguments[5]?arguments[5]:0,a=me(e);switch(a){case"html_element":return t.push(r),{inspectable:!1,preview_short:_e(e,!1),preview_long:_e(e,!0),name:e.tagName,type:a};case"function":return t.push(r),{inspectable:!1,preview_short:_e(e,!1),preview_long:_e(e,!0),name:"function"!=typeof e.name&&e.name?e.name:"function",type:a};case"string":return e.length<=500?e:e.slice(0,500)+"...";case"bigint":case"symbol":return t.push(r),{inspectable:!1,preview_short:_e(e,!1),preview_long:_e(e,!0),name:e.toString(),type:a};case"react_element":return t.push(r),{inspectable:!1,preview_short:_e(e,!1),preview_long:_e(e,!0),name:ge(e)||"Unknown",type:a};case"array_buffer":case"data_view":return t.push(r),{inspectable:!1,preview_short:_e(e,!1),preview_long:_e(e,!0),name:"data_view"===a?"DataView":"ArrayBuffer",size:e.byteLength,type:a};case"array":return o=i(r),u>=2&&!o?Z(a,!0,e,t,r):e.map((function(e,a){return ee(e,t,n,r.concat([a]),i,o?1:u+1)}));case"html_all_collection":case"typed_array":case"iterator":if(o=i(r),u>=2&&!o)return Z(a,!0,e,t,r);var l={unserializable:!0,type:a,readonly:!0,size:"typed_array"===a?e.length:void 0,preview_short:_e(e,!1),preview_long:_e(e,!0),name:e.constructor&&"Object"!==e.constructor.name?e.constructor.name:""};return Q(e[Symbol.iterator])&&Array.from(e).forEach((function(e,a){return l[a]=ee(e,t,n,r.concat([a]),i,o?1:u+1)})),n.push(r),l;case"opaque_iterator":return t.push(r),{inspectable:!1,preview_short:_e(e,!1),preview_long:_e(e,!0),name:e[Symbol.toStringTag],type:a};case"date":case"regexp":return t.push(r),{inspectable:!1,preview_short:_e(e,!1),preview_long:_e(e,!0),name:e.toString(),type:a};case"object":if(o=i(r),u>=2&&!o)return Z(a,!0,e,t,r);var s={};return ae(e).forEach((function(a){var l=a.toString();s[l]=ee(e[a],t,n,r.concat([l]),i,o?1:u+1)})),s;case"infinity":case"nan":case"undefined":return t.push(r),{type:a};default:return e}}function te(e){return(te="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function ne(e){return function(e){if(Array.isArray(e))return re(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return re(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?re(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function re(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);nt.toString()?1:t.toString()>e.toString()?-1:0}function ae(e){for(var t=[],n=e,r=function(){var e=[].concat(ne(Object.keys(n)),ne(Object.getOwnPropertySymbols(n))),r=Object.getOwnPropertyDescriptors(n);e.forEach((function(e){r[e].enumerable&&t.push(e)})),n=Object.getPrototypeOf(n)};null!=n;)r();return t}function le(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"Anonymous",n=ie.get(e);if(null!=n)return n;var r=t;return"string"==typeof e.displayName?r=e.displayName:"string"==typeof e.name&&""!==e.name&&(r=e.name),ie.set(e,r),r}var se=0;function ce(){return++se}function fe(e){var t=oe.get(e);if(void 0!==t)return t;for(var n=new Array(e.length),r=0;r1&&void 0!==arguments[1]?arguments[1]:50;return e.length>t?e.substr(0,t)+"…":e}function _e(e,t){if(null!=e&&hasOwnProperty.call(e,J.type))return t?e[J.preview_long]:e[J.preview_short];switch(me(e)){case"html_element":return"<".concat(ye(e.tagName.toLowerCase())," />");case"function":return ye("ƒ ".concat("function"==typeof e.name?"":e.name,"() {}"));case"string":return'"'.concat(e,'"');case"bigint":return ye(e.toString()+"n");case"regexp":case"symbol":return ye(e.toString());case"react_element":return"<".concat(ye(ge(e)||"Unknown")," />");case"array_buffer":return"ArrayBuffer(".concat(e.byteLength,")");case"data_view":return"DataView(".concat(e.buffer.byteLength,")");case"array":if(t){for(var n="",r=0;r0&&(n+=", "),!((n+=_e(e[r],!1)).length>50));r++);return"[".concat(ye(n),"]")}var i=hasOwnProperty.call(e,J.size)?e[J.size]:e.length;return"Array(".concat(i,")");case"typed_array":var o="".concat(e.constructor.name,"(").concat(e.length,")");if(t){for(var u="",a=0;a0&&(u+=", "),!((u+=e[a]).length>50));a++);return"".concat(o," [").concat(ye(u),"]")}return o;case"iterator":var l=e.constructor.name;if(t){for(var s=Array.from(e),c="",f=0;f0&&(c+=", "),Array.isArray(d)){var p=_e(d[0],!0),h=_e(d[1],!1);c+="".concat(p," => ").concat(h)}else c+=_e(d,!1);if(c.length>50)break}return"".concat(l,"(").concat(e.size,") {").concat(ye(c),"}")}return"".concat(l,"(").concat(e.size,")");case"opaque_iterator":return e[Symbol.toStringTag];case"date":return e.toString();case"object":if(t){for(var v=ae(e).sort(ue),m="",g=0;g0&&(m+=", "),(m+="".concat(y.toString(),": ").concat(_e(e[y],!1))).length>50)break}return"{".concat(ye(m),"}")}return"{…}";case"boolean":case"number":case"infinity":case"nan":case"null":case"undefined":return e;default:try{return ye(""+e)}catch(e){return"unserializable"}}}var be=n(7);function we(e){return(we="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function Ee(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function De(e){for(var t=1;t2&&void 0!==arguments[2]?arguments[2]:[];if(null!==e){var r=[],i=[],o=ee(e,r,i,n,t);return{data:o,cleaned:r,unserializable:i}}return null}function ke(e){var t,n,r=(t=e,n=new Set,JSON.stringify(t,(function(e,t){if("object"===we(t)&&null!==t){if(n.has(t))return;n.add(t)}return"bigint"==typeof t?t.toString()+"n":t}))),i=void 0===r?"undefined":r,o=window.__REACT_DEVTOOLS_GLOBAL_HOOK__.clipboardCopyText;"function"==typeof o?o(i).catch((function(e){})):Object(be.copy)(i)}function Te(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,r=t[n],i=Array.isArray(e)?e.slice():De({},e);return n+1===t.length?Array.isArray(i)?i.splice(r,1):delete i[r]:i[r]=Te(e[r],t,n+1),i}function xe(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,i=t[r],o=Array.isArray(e)?e.slice():De({},e);if(r+1===t.length){var u=n[r];o[u]=o[i],Array.isArray(o)?o.splice(i,1):delete o[i]}else o[i]=xe(e[i],t,n,r+1);return o}function Ae(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0;if(r>=t.length)return n;var i=t[r],o=Array.isArray(e)?e.slice():De({},e);return o[i]=Ae(e[i],t,n,r+1),o}var Oe=n(8);function Pe(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Ie(e){for(var t=1;t=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,u=!0,a=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return u=e.done,e},e:function(e){a=!0,o=e},f:function(){try{u||null==n.return||n.return()}finally{if(a)throw o}}}}function Le(e,t){if(e){if("string"==typeof e)return Be(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Be(e,t):void 0}}function Be(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0){var a=o(e);if(null!=a){var l,s=Fe(Y);try{for(s.s();!(l=s.n()).done;)if(l.value.test(a))return!0}catch(e){s.e(e)}finally{s.f()}}}if(null!=t&&K.size>0){var c,f=t.fileName,d=Fe(K);try{for(d.s();!(c=d.n()).done;)if(c.value.test(f))return!0}catch(e){d.e(e)}finally{d.f()}}return!1}function te(e){var t=e.type;switch(e.tag){case v:case S:return 1;case h:case C:return 5;case _:return 6;case b:return 11;case E:return 7;case w:case D:case y:return 9;case k:case x:return 8;case A:return 12;case O:return 13;default:switch(u(t)){case 60111:case"Symbol(react.concurrent_mode)":case"Symbol(react.async_mode)":return 9;case 60109:case"Symbol(react.provider)":return 2;case 60110:case"Symbol(react.context)":return 2;case 60108:case"Symbol(react.strict_mode)":return 9;case 60114:case"Symbol(react.profiler)":return 10;default:return 9}}}function ne(e){if(oe.has(e))return e;var t=e.alternate;return null!=t&&oe.has(t)?t:(oe.add(e),e)}null!=window.__REACT_DEVTOOLS_COMPONENT_FILTERS__?Z(window.__REACT_DEVTOOLS_COMPONENT_FILTERS__):Z([{type:1,value:7,isEnabled:!0}]);var re=new Map,ie=new Map,oe=new Set,ue=new Map,ae=new Map,le=-1;function se(e){if(!re.has(e)){var t=ce();re.set(e,t),ie.set(t,e)}return re.get(e)}function me(e){switch(te(e)){case 1:if(null!==dt){var t=se(ne(e)),n=ye(e);null!==n&&dt.set(t,n)}}}var ge={};function ye(e){switch(te(e)){case 1:var t=e.stateNode,n=ge,r=ge;return null!=t&&(t.constructor&&null!=t.constructor.contextType?r=t.context:(n=t.context)&&0===Object.keys(n).length&&(n=ge)),[n,r];default:return null}}function _e(e){switch(te(e)){case 1:if(null!==dt){var t=se(ne(e)),n=dt.has(t)?dt.get(t):null,r=ye(e);if(null==n||null==r)return null;var i=Re(n,2),o=i[0],u=i[1],a=Re(r,2),l=a[0],s=a[1];if(l!==ge)return we(o,l);if(s!==ge)return u!==s}}return null}function be(e,t){if(null==e||null==t)return!1;if(t.hasOwnProperty("baseState")&&t.hasOwnProperty("memoizedState")&&t.hasOwnProperty("next")&&t.hasOwnProperty("queue"))for(;null!==t;){if(t.memoizedState!==e.memoizedState)return!0;t=t.next,e=e.next}return!1}function we(e,t){if(null==e||null==t)return null;if(t.hasOwnProperty("baseState")&&t.hasOwnProperty("memoizedState")&&t.hasOwnProperty("next")&&t.hasOwnProperty("queue"))return null;var n,r=[],i=Fe(new Set([].concat(Me(Object.keys(e)),Me(Object.keys(t)))));try{for(i.s();!(n=i.n()).done;){var o=n.value;e[o]!==t[o]&&r.push(o)}}catch(e){i.e(e)}finally{i.f()}return r}function Ee(e,t){switch(t.tag){case v:case h:case m:case k:case x:return(Ue(t)&d)===d;default:return e.memoizedProps!==t.memoizedProps||e.memoizedState!==t.memoizedState||e.ref!==t.ref}}var De=[],Se=[],Pe=[],Ne=[],Le=new Map,Be=0,je=null;function ze(e){De.push(e)}function Ve(n){if(0!==De.length||0!==Se.length||0!==Pe.length||null!==je||vt){var r=Se.length+Pe.length+(null===je?0:1),i=new Array(3+Be+(r>0?2+r:0)+De.length),o=0;if(i[o++]=t,i[o++]=le,i[o++]=Be,Le.forEach((function(e,t){i[o++]=t.length;for(var n=fe(t),r=0;r0){i[o++]=2,i[o++]=r;for(var u=Se.length-1;u>=0;u--)i[o++]=Se[u];for(var a=0;a0?n.forEach((function(t){e.emit("operations",t)})):(null!==Dt&&(kt=!0),e.getFiberRoots(t).forEach((function(e){Ot(le=se(ne(e.current)),e.current),vt&&null!=e.memoizedInteractions&&(st={changeDescriptions:gt?new Map:null,durations:[],commitTime:We()-mt,interactions:Array.from(e.memoizedInteractions).map((function(e){return Ie(Ie({},e),{},{timestamp:e.timestamp-mt})})),maxActualDuration:0,priorityLevel:null}),$e(e.current,null,!1,!1),Ve(),le=-1})))},getBestMatchForTrackedPath:function(){if(null===Dt)return null;if(null===St)return null;for(var e=St;null!==e&&ee(e);)e=e.return;return null===e?null:{id:se(ne(e)),isFullMatch:Ct===Dt.length-1}},getDisplayNameForFiberID:function(e){var t=ie.get(e);return null!=t?o(t):null},getFiberIDForNative:function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=n.findFiberByHostInstance(e);if(null!=r){if(t)for(;null!==r&&ee(r);)r=r.return;return se(ne(r))}return null},getInstanceAndStyle:function(e){var t=null,n=null,r=et(e);return null!==r&&(t=r.stateNode,null!==r.memoizedProps&&(n=r.memoizedProps.style)),{instance:t,style:n}},getOwnersList:function(e){var t=et(e);if(null==t)return null;var n=t._debugOwner,r=[{displayName:o(t)||"Anonymous",id:e,type:te(t)}];if(n)for(var i=n;null!==i;)r.unshift({displayName:o(i)||"Anonymous",id:se(ne(i)),type:te(i)}),i=i._debugOwner||null;return r},getPathForElement:function(e){var t=ie.get(e);if(null==t)return null;for(var n=[];null!==t;)n.push(It(t)),t=t.return;return n.reverse(),n},getProfilingData:function(){var e=[];if(null===yt)throw Error("getProfilingData() called before any profiling data was recorded");return yt.forEach((function(t,n){var r=[],i=[],o=new Map,u=new Map,a=null!==ft&&ft.get(n)||"Unknown";null!=pt&&pt.forEach((function(e,t){null!=ht&&ht.get(t)===n&&i.push([t,e])})),t.forEach((function(e,t){var n=e.changeDescriptions,i=e.durations,a=e.interactions,l=e.maxActualDuration,s=e.priorityLevel,c=e.commitTime,f=[];a.forEach((function(e){o.has(e.id)||o.set(e.id,e),f.push(e.id);var n=u.get(e.id);null!=n?n.push(t):u.set(e.id,[t])}));for(var d=[],p=[],h=0;h1?At.set(n,r-1):At.delete(n),xt.delete(e)}(le),Ge(r,!1))}else Ot(le,r),$e(r,null,!1,!1);if(vt&&o){var l=yt.get(le);null!=l?l.push(st):yt.set(le,[st])}Ve(),Q&&e.emit("traceUpdates",J),le=-1},handleCommitFiberUnmount:function(e){Ge(e,!1)},inspectElement:function(e,t){if(ot(e)){if(null!=t){ut(t);var n=null;return"hooks"===t[0]&&(n="hooks"),{id:e,type:"hydrated-path",path:t,value:Ce(de(nt,t),at(null,n),t)}}return{id:e,type:"no-change"}}if(rt=!1,null!==nt&&nt.id===e||(it={}),null===(nt=tt(e)))return{id:e,type:"not-found"};null!=t&&ut(t),function(e){var t=e.hooks,n=e.id,i=e.props,o=ie.get(n);if(null!=o){var u=o.elementType,a=o.stateNode,l=o.tag,s=o.type;switch(l){case v:case S:case C:r.$r=a;break;case h:r.$r={hooks:t,props:i,type:s};break;case _:r.$r={props:i,type:s.render};break;case k:case x:r.$r={props:i,type:null!=u&&null!=u.type?u.type:s};break;default:r.$r=null}}else console.warn('Could not find Fiber with id "'.concat(n,'"'))}(nt);var i=Ie({},nt);return i.context=Ce(i.context,at("context",null)),i.hooks=Ce(i.hooks,at("hooks","hooks")),i.props=Ce(i.props,at("props",null)),i.state=Ce(i.state,at("state",null)),{id:e,type:"full-data",value:i}},logElementToConsole:function(e){var t=ot(e)?nt:tt(e);if(null!==t){var n="function"==typeof console.groupCollapsed;n&&console.groupCollapsed("[Click to expand] %c<".concat(t.displayName||"Component"," />"),"color: var(--dom-tag-name-color); font-weight: normal;"),null!==t.props&&console.log("Props:",t.props),null!==t.state&&console.log("State:",t.state),null!==t.hooks&&console.log("Hooks:",t.hooks);var r=Je(e);null!==r&&console.log("Nodes:",r),null!==t.source&&console.log("Location:",t.source),(window.chrome||/firefox/i.test(navigator.userAgent))&&console.log("Right-click any value to save it as a global variable for further inspection."),n&&console.groupEnd()}else console.warn('Could not find Fiber with id "'.concat(e,'"'))},prepareViewAttributeSource:function(e,t){ot(e)&&(window.$attribute=de(nt,t))},prepareViewElementSource:function(e){var t=ie.get(e);if(null!=t){var n=t.elementType,i=t.tag,o=t.type;switch(i){case v:case S:case C:case h:r.$type=o;break;case _:r.$type=o.render;break;case k:case x:r.$type=null!=n&&null!=n.type?n.type:o;break;default:r.$type=null}}else console.warn('Could not find Fiber with id "'.concat(e,'"'))},overrideSuspense:function(e,t){if("function"!=typeof H||"function"!=typeof V)throw new Error("Expected overrideSuspense() to not get called for earlier React versions.");t?(wt.add(e),1===wt.size&&H(Et)):(wt.delete(e),0===wt.size&&H(bt));var n=ie.get(e);null!=n&&V(n)},overrideValueAtPath:function(e,t,n,r,i){var o=et(t);if(null!==o){var u=o.stateNode;switch(e){case"context":switch(r=r.slice(1),o.tag){case v:0===r.length?u.context=i:ve(u.context,r,i),u.forceUpdate()}break;case"hooks":"function"==typeof L&&L(o,n,r,i);break;case"props":switch(o.tag){case v:o.pendingProps=Ae(u.props,r,i),u.forceUpdate();break;default:"function"==typeof U&&U(o,r,i)}break;case"state":switch(o.tag){case v:ve(u.state,r,i),u.forceUpdate()}}}},renamePath:function(e,t,n,r,i){var o=et(t);if(null!==o){var u=o.stateNode;switch(e){case"context":switch(r=r.slice(1),i=i.slice(1),o.tag){case v:0===r.length||he(u.context,r,i),u.forceUpdate()}break;case"hooks":"function"==typeof j&&j(o,n,r,i);break;case"props":null===u?"function"==typeof W&&W(o,r,i):(o.pendingProps=xe(u.props,r,i),u.forceUpdate());break;case"state":he(u.state,r,i),u.forceUpdate()}}},renderer:n,setTraceUpdatesEnabled:function(e){Q=e},setTrackedPath:Tt,startProfiling:_t,stopProfiling:function(){vt=!1,gt=!1},storeAsGlobal:function(e,t,n){if(ot(e)){var r=de(nt,t),i="$reactTemp".concat(n);window[i]=r,console.log(i),console.log(r)}},updateComponentFilters:function(n){if(vt)throw Error("Cannot modify filter preferences while profiling");e.getFiberRoots(t).forEach((function(e){le=se(ne(e.current)),Ye(e.current),Ge(e.current,!1),le=-1})),Z(n),At.clear(),e.getFiberRoots(t).forEach((function(e){Ot(le=se(ne(e.current)),e.current),$e(e.current,null,!1,!1),Ve(),le=-1}))}}}function qe(e){return(qe="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function Ge(e,t,n){if(void 0===ze)try{throw Error()}catch(e){var r=e.stack.trim().match(/\n( *(at )?)/);ze=r&&r[1]||""}return"\n"+ze+e}var $e=!1;function Ye(e,t,n){if(!e||$e)return"";var r,i=Error.prepareStackTrace;Error.prepareStackTrace=void 0,$e=!0;var o=n.current;n.current=null;try{if(t){var u=function(){throw Error()};if(Object.defineProperty(u.prototype,"props",{set:function(){throw Error()}}),"object"===("undefined"==typeof Reflect?"undefined":qe(Reflect))&&Reflect.construct){try{Reflect.construct(u,[])}catch(e){r=e}Reflect.construct(e,[],u)}else{try{u.call()}catch(e){r=e}e.call(u.prototype)}}else{try{throw Error()}catch(e){r=e}e()}}catch(e){if(e&&r&&"string"==typeof e.stack){for(var a=e.stack.split("\n"),l=r.stack.split("\n"),s=a.length-1,c=l.length-1;s>=1&&c>=0&&a[s]!==l[c];)c--;for(;s>=1&&c>=0;s--,c--)if(a[s]!==l[c]){if(1!==s||1!==c)do{if(s--,--c<0||a[s]!==l[c])return"\n"+a[s].replace(" at new "," at ")}while(s>=1&&c>=0);break}}}finally{$e=!1,Error.prepareStackTrace=i,n.current=o}var f=e?e.displayName||e.name:"";return f?Ge(f):""}function Ke(e,t,n,r){return Ye(e,!1,r)}function Xe(e,t,n){var r=e.HostComponent,i=e.LazyComponent,o=e.SuspenseComponent,u=e.SuspenseListComponent,a=e.FunctionComponent,l=e.IndeterminateComponent,s=e.SimpleMemoComponent,c=e.ForwardRef,f=e.Block,d=e.ClassComponent;switch(t.tag){case r:return Ge(t.type);case i:return Ge("Lazy");case o:return Ge("Suspense");case u:return Ge("SuspenseList");case a:case l:case s:return Ke(t.type,0,0,n);case c:return Ke(t.type.render,0,0,n);case f:return Ke(t.type._render,0,0,n);case d:return function(e,t,n,r){return Ye(e,!0,r)}(t.type,0,0,n);default:return""}}function Qe(e,t,n){try{var r="",i=t;do{r+=Xe(e,i,n),i=i.return}while(i);return r}catch(e){return"\nError generating stack: "+e.message+"\n"+e.stack}}function Je(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return Ze(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Ze(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,i=function(){};return{s:i,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,u=!0,a=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return u=e.done,e},e:function(e){a=!0,o=e},f:function(){try{u||null==n.return||n.return()}finally{if(a)throw o}}}}function Ze(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0?r[r.length-1]:null,u=null!==o&&(tt.test(o)||nt.test(o));if(!u){var a,l=Je(rt.values());try{for(l.s();!(a=l.n()).done;){var s=a.value,c=s.currentDispatcherRef,f=s.getCurrentFiber,d=s.workTagMap,p=f();if(null!=p){var h=Qe(d,p,c);""!==h&&r.push(h);break}}}catch(e){l.e(e)}finally{l.f()}}}catch(e){}t.apply(void 0,r)};n.__REACT_DEVTOOLS_ORIGINAL_METHOD__=t,it[e]=n}catch(e){}}))}}function ft(e){return(ft="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function dt(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:d,n=void 0,r=[],i=void 0,o=!1,u=function(e,n){return t(e,r[n])},a=function(){for(var t=arguments.length,a=Array(t),l=0;le.length)&&(t=e.length);for(var n=0,r=new Array(t);n1?t-1:0),r=1;r0?"development":"production";var t=Function.prototype.toString;if(e.Mount&&e.Mount._renderNewRootComponent){var n=t.call(e.Mount._renderNewRootComponent);return 0!==n.indexOf("function")?"production":-1!==n.indexOf("storedMeasure")?"development":-1!==n.indexOf("should be a pure function")?-1!==n.indexOf("NODE_ENV")||-1!==n.indexOf("development")||-1!==n.indexOf("true")?"development":-1!==n.indexOf("nextElement")||-1!==n.indexOf("nextComponent")?"unminified":"development":-1!==n.indexOf("nextElement")||-1!==n.indexOf("nextComponent")?"unminified":"outdated"}}catch(e){}return"production"}(r);try{var l=!1!==window.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__,s=!0===window.__REACT_DEVTOOLS_BREAK_ON_CONSOLE_ERRORS__;(l||s)&&(lt(r),ct({appendComponentStack:l,breakOnConsoleErrors:s}))}catch(e){}var c=e.__REACT_DEVTOOLS_ATTACH__;if("function"==typeof c){var f=c(a,i,r,e);a.rendererInterfaces.set(i,f)}return a.emit("renderer",{id:i,renderer:r,reactBuildType:o}),i},on:function(e,t){o[e]||(o[e]=[]),o[e].push(t)},off:function(e,t){if(o[e]){var n=o[e].indexOf(t);-1!==n&&o[e].splice(n,1),o[e].length||delete o[e]}},sub:function(e,t){return a.on(e,t),function(){return a.off(e,t)}},supportsFiber:!0,checkDCE:function(e){try{Function.prototype.toString.call(e).indexOf("^_^")>-1&&(n=!0,setTimeout((function(){throw new Error("React is running in production mode, but dead code elimination has not been applied. Read how to correctly configure React for production: https://reactjs.org/link/perf-use-production-build")})))}catch(e){}},onCommitFiberUnmount:function(e,t){var n=i.get(e);null!=n&&n.handleCommitFiberUnmount(t)},onCommitFiberRoot:function(e,t,n){var r=a.getFiberRoots(e),o=t.current,u=r.has(t),l=null==o.memoizedState||null==o.memoizedState.element;u||l?u&&l&&r.delete(t):r.add(t);var s=i.get(e);null!=s&&s.handleCommitFiberRoot(t,n)}};Object.defineProperty(e,"__REACT_DEVTOOLS_GLOBAL_HOOK__",{configurable:!1,enumerable:!1,get:function(){return a}})}(window);var $t=window.__REACT_DEVTOOLS_GLOBAL_HOOK__,Yt=[{type:1,value:7,isEnabled:!0}];function Kt(e){if(null!=$t){var t=e||{},n=t.host,r=void 0===n?"localhost":n,i=t.nativeStyleEditorValidAttributes,o=t.useHttps,u=void 0!==o&&o,a=t.port,l=void 0===a?8097:a,s=t.websocket,c=t.resolveRNStyle,f=void 0===c?null:c,d=t.isAppActive,p=u?"wss":"ws",h=null;if((void 0===d?function(){return!0}:d)()){var v=null,m=[],g=p+"://"+r+":"+l,y=s||new window.WebSocket(g);y.onclose=function(){null!==v&&v.emit("shutdown"),_()},y.onerror=function(){_()},y.onmessage=function(e){var t;try{if("string"!=typeof e.data)throw Error();t=JSON.parse(e.data)}catch(t){return void console.error("[React DevTools] Failed to parse JSON: "+e.data)}m.forEach((function(e){try{e(t)}catch(e){throw console.log("[React DevTools] Error calling listener",t),console.log("error:",e),e}}))},y.onopen=function(){(v=new xt({listen:function(e){return m.push(e),function(){var t=m.indexOf(e);t>=0&&m.splice(t,1)}},send:function(e,t,n){y.readyState===y.OPEN?y.send(JSON.stringify({event:e,payload:t})):(null!==v&&v.shutdown(),_())}})).addListener("inspectElement",(function(t){var n=t.id,r=t.rendererID,i=e.rendererInterfaces[r];if(null!=i){var o=i.findNativeNodesForFiberID(n);null!=o&&null!=o[0]&&e.emit("showNativeHighlight",o[0])}})),v.addListener("updateComponentFilters",(function(e){Yt=e})),null==window.__REACT_DEVTOOLS_COMPONENT_FILTERS__&&v.send("overrideComponentFilters",Yt);var e=new yt(v);if(e.addListener("shutdown",(function(){$t.emit("shutdown")})),function(e,t,n){if(null==e)return function(){};var r=[e.sub("renderer-attached",(function(e){var n=e.id,r=(e.renderer,e.rendererInterface);t.setRendererInterface(n,r),r.flushInitialOperations()})),e.sub("unsupported-renderer-version",(function(e){t.onUnsupportedRenderer(e)})),e.sub("operations",t.onHookOperations),e.sub("traceUpdates",t.onTraceUpdates)],i=function(t,r){var i=e.rendererInterfaces.get(t);null==i&&("function"==typeof r.findFiberByHostInstance?i=Ve(e,t,r,n):r.ComponentTree&&(i=function(e,t,n,r){var i,o=new Map,u=new WeakMap,a=new WeakMap,l=null;function s(e){if("object"!==Rt(e)||null===e)throw new Error("Invalid internal instance: "+e);if(!u.has(e)){var t=ce();u.set(e,t),o.set(t,e)}return u.get(e)}function c(e,t){if(e.length!==t.length)return!1;for(var n=0;n0?f[f.length-1]:0),f.push(i),a.set(n,s(r._topLevelWrapper));try{var o=e.apply(this,t);return f.pop(),o}catch(e){throw f=[],e}finally{if(0===f.length){var u=a.get(n);if(void 0===u)throw new Error("Expected to find root ID.");w(u)}}},performUpdateIfNecessary:function(e,t){var n=t[0];if(9===Lt(n))return e.apply(this,t);var r=s(n);f.push(r);var i=Bt(n);try{var o=e.apply(this,t),u=Bt(n);return c(i,u)||h(0,r,u),f.pop(),o}catch(e){throw f=[],e}finally{if(0===f.length){var l=a.get(n);if(void 0===l)throw new Error("Expected to find root ID.");w(l)}}},receiveComponent:function(e,t){var n=t[0];if(9===Lt(n))return e.apply(this,t);var r=s(n);f.push(r);var i=Bt(n);try{var o=e.apply(this,t),u=Bt(n);return c(i,u)||h(0,r,u),f.pop(),o}catch(e){throw f=[],e}finally{if(0===f.length){var l=a.get(n);if(void 0===l)throw new Error("Expected to find root ID.");w(l)}}},unmountComponent:function(e,t){var n=t[0];if(9===Lt(n))return e.apply(this,t);var r=s(n);f.push(r);try{var i=e.apply(this,t);return f.pop(),function(e,t){y.push(t),o.delete(t)}(0,r),i}catch(e){throw f=[],e}finally{if(0===f.length){var u=a.get(n);if(void 0===u)throw new Error("Expected to find root ID.");w(u)}}}}));var m=[],g=new Map,y=[],_=0,b=null;function w(n){if(0!==m.length||0!==y.length||null!==b){var r=y.length+(null===b?0:1),i=new Array(3+_+(r>0?2+r:0)+m.length),o=0;if(i[o++]=t,i[o++]=n,i[o++]=_,g.forEach((function(e,t){i[o++]=t.length;for(var n=fe(t),r=0;r0){i[o++]=2,i[o++]=r;for(var u=0;u"),"color: var(--dom-tag-name-color); font-weight: normal;"),null!==t.props&&console.log("Props:",t.props),null!==t.state&&console.log("State:",t.state),null!==t.context&&console.log("Context:",t.context);var r=i(e);null!==r&&console.log("Node:",r),(window.chrome||/firefox/i.test(navigator.userAgent))&&console.log("Right-click any value to save it as a global variable for further inspection."),n&&console.groupEnd()}else console.warn('Could not find element with id "'.concat(e,'"'))},overrideSuspense:function(){throw new Error("overrideSuspense not supported by this renderer")},overrideValueAtPath:function(e,t,n,r,i){var u=o.get(t);if(null!=u){var a=u._instance;if(null!=a)switch(e){case"context":ve(a.context,r,i),Pt(a);break;case"hooks":throw new Error("Hooks not supported by this renderer");case"props":var l=u._currentElement;u._currentElement=Nt(Nt({},l),{},{props:Ae(l.props,r,i)}),Pt(a);break;case"state":ve(a.state,r,i),Pt(a)}}},renamePath:function(e,t,n,r,i){var u=o.get(t);if(null!=u){var a=u._instance;if(null!=a)switch(e){case"context":he(a.context,r,i),Pt(a);break;case"hooks":throw new Error("Hooks not supported by this renderer");case"props":var l=u._currentElement;u._currentElement=Nt(Nt({},l),{},{props:xe(l.props,r,i)}),Pt(a);break;case"state":he(a.state,r,i),Pt(a)}}},prepareViewAttributeSource:function(e,t){var n=T(e);null!==n&&(window.$attribute=de(n,t))},prepareViewElementSource:function(e){var t=o.get(e);if(null!=t){var n=t._currentElement;null!=n?r.$type=n.type:console.warn('Could not find element with id "'.concat(e,'"'))}else console.warn('Could not find instance with id "'.concat(e,'"'))},renderer:n,setTraceUpdatesEnabled:function(e){},setTrackedPath:function(e){},startProfiling:function(){},stopProfiling:function(){},storeAsGlobal:function(e,t,n){var r=T(e);if(null!==r){var i=de(r,t),o="$reactTemp".concat(n);window[o]=i,console.log(o),console.log(i)}},updateComponentFilters:function(e){}}}(e,t,r,n)),null!=i&&e.rendererInterfaces.set(t,i)),null!=i?e.emit("renderer-attached",{id:t,renderer:r,rendererInterface:i}):e.emit("unsupported-renderer-version",t)};e.renderers.forEach((function(e,t){i(t,e)})),r.push(e.sub("renderer",(function(e){var t=e.id,n=e.renderer;i(t,n)}))),e.emit("react-devtools",t),e.reactDevtoolsAgent=t;var o=function(){r.forEach((function(e){return e()})),e.rendererInterfaces.forEach((function(e){e.cleanup()})),e.reactDevtoolsAgent=null};t.addListener("shutdown",o),r.push((function(){t.removeListener("shutdown",o)}))}($t,e,window),null!=f||null!=$t.resolveRNStyle)Wt(v,e,f||$t.resolveRNStyle,i||$t.nativeStyleEditorValidAttributes||null);else{var t,n,r=function(){null!==v&&Wt(v,e,t,n)};$t.hasOwnProperty("resolveRNStyle")||Object.defineProperty($t,"resolveRNStyle",{enumerable:!1,get:function(){return t},set:function(e){t=e,r()}}),$t.hasOwnProperty("nativeStyleEditorValidAttributes")||Object.defineProperty($t,"nativeStyleEditorValidAttributes",{enumerable:!1,get:function(){return n},set:function(e){n=e,r()}})}}}else _()}function _(){null===h&&(h=setTimeout((function(){return Kt(e)}),2e3))}}}])},6099:(e,t,n)=>{"use strict"; /** @license React v16.13.1 * react.production.min.js * @@ -63,15 +357,7 @@ function(r){function i(e,t){return function(){e.apply(t,arguments)}}function o(e * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var r=n(9381),i="function"==typeof Symbol&&Symbol.for,o=i?Symbol.for("react.element"):60103,u=i?Symbol.for("react.portal"):60106,a=i?Symbol.for("react.fragment"):60107,l=i?Symbol.for("react.strict_mode"):60108,s=i?Symbol.for("react.profiler"):60114,c=i?Symbol.for("react.provider"):60109,f=i?Symbol.for("react.context"):60110,d=i?Symbol.for("react.forward_ref"):60112,p=i?Symbol.for("react.suspense"):60113,h=i?Symbol.for("react.memo"):60115,v=i?Symbol.for("react.lazy"):60116,m="function"==typeof Symbol&&Symbol.iterator;function g(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;nO.length&&O.push(e)}function N(e,t,n){return null==e?0:function e(t,n,r,i){var a=typeof t;"undefined"!==a&&"boolean"!==a||(t=null);var l=!1;if(null===t)l=!0;else switch(a){case"string":case"number":l=!0;break;case"object":switch(t.$$typeof){case o:case u:l=!0}}if(l)return r(i,t,""===n?"."+M(t,0):n),1;if(l=0,n=""===n?".":n+":",Array.isArray(t))for(var s=0;s{"use strict";e.exports=n(6099)},3390:(e,t,n)=>{"use strict";const r=n(834),i=n(6458);e.exports=r(()=>{i(()=>{process.stderr.write("[?25h")},{alwaysLast:!0})})},706:(e,t)=>{"use strict"; -/** @license React v0.18.0 - * scheduler.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var n,r,i,o,u;if(Object.defineProperty(t,"__esModule",{value:!0}),"undefined"==typeof window||"function"!=typeof MessageChannel){var a=null,l=null,s=function(){if(null!==a)try{var e=t.unstable_now();a(!0,e),a=null}catch(e){throw setTimeout(s,0),e}},c=Date.now();t.unstable_now=function(){return Date.now()-c},n=function(e){null!==a?setTimeout(n,0,e):(a=e,setTimeout(s,0))},r=function(e,t){l=setTimeout(e,t)},i=function(){clearTimeout(l)},o=function(){return!1},u=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,d=window.Date,p=window.setTimeout,h=window.clearTimeout;if("undefined"!=typeof console){var v=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof v&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var m=d.now();t.unstable_now=function(){return d.now()-m}}var g=!1,y=null,_=-1,b=5,w=0;o=function(){return t.unstable_now()>=w},u=function(){},t.unstable_forceFrameRate=function(e){0>e||125T(u,n))void 0!==l&&0>T(l,u)?(e[r]=l,e[a]=n,r=a):(e[r]=u,e[o]=n,r=o);else{if(!(void 0!==l&&0>T(l,n)))break e;e[r]=l,e[a]=n,r=a}}}return t}return null}function T(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var x=[],A=[],O=1,P=null,I=3,N=!1,M=!1,R=!1;function F(e){for(var t=C(A);null!==t;){if(null===t.callback)k(A);else{if(!(t.startTime<=e))break;k(A),t.sortIndex=t.expirationTime,S(x,t)}t=C(A)}}function L(e){if(R=!1,F(e),!M)if(null!==C(x))M=!0,n(B);else{var t=C(A);null!==t&&r(L,t.startTime-e)}}function B(e,n){M=!1,R&&(R=!1,i()),N=!0;var u=I;try{for(F(n),P=C(x);null!==P&&(!(P.expirationTime>n)||e&&!o());){var a=P.callback;if(null!==a){P.callback=null,I=P.priorityLevel;var l=a(P.expirationTime<=n);n=t.unstable_now(),"function"==typeof l?P.callback=l:P===C(x)&&k(x),F(n)}else k(x);P=C(x)}if(null!==P)var s=!0;else{var c=C(A);null!==c&&r(L,c.startTime-n),s=!1}return s}finally{P=null,I=u,N=!1}}function j(e){switch(e){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var U=u;t.unstable_ImmediatePriority=1,t.unstable_UserBlockingPriority=2,t.unstable_NormalPriority=3,t.unstable_IdlePriority=5,t.unstable_LowPriority=4,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=I;I=e;try{return t()}finally{I=n}},t.unstable_next=function(e){switch(I){case 1:case 2:case 3:var t=3;break;default:t=I}var n=I;I=t;try{return e()}finally{I=n}},t.unstable_scheduleCallback=function(e,o,u){var a=t.unstable_now();if("object"==typeof u&&null!==u){var l=u.delay;l="number"==typeof l&&0a?(e.sortIndex=l,S(A,e),null===C(x)&&e===C(A)&&(R?i():R=!0,r(L,l-a))):(e.sortIndex=u,S(x,e),M||N||(M=!0,n(B))),e},t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_wrapCallback=function(e){var t=I;return function(){var n=I;I=t;try{return e.apply(this,arguments)}finally{I=n}}},t.unstable_getCurrentPriorityLevel=function(){return I},t.unstable_shouldYield=function(){var e=t.unstable_now();F(e);var n=C(x);return n!==P&&null!==P&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime{"use strict";e.exports=n(706)},6458:(e,t,n)=>{var r,i=n(2357),o=n(8082),u=n(8614);function a(){c&&(c=!1,o.forEach((function(e){try{process.removeListener(e,s[e])}catch(e){}})),process.emit=h,process.reallyExit=d,r.count-=1)}function l(e,t,n){r.emitted[e]||(r.emitted[e]=!0,r.emit(e,t,n))}"function"!=typeof u&&(u=u.EventEmitter),process.__signal_exit_emitter__?r=process.__signal_exit_emitter__:((r=process.__signal_exit_emitter__=new u).count=0,r.emitted={}),r.infinite||(r.setMaxListeners(1/0),r.infinite=!0),e.exports=function(e,t){i.equal(typeof e,"function","a callback must be provided for exit handler"),!1===c&&f();var n="exit";t&&t.alwaysLast&&(n="afterexit");return r.on(n,e),function(){r.removeListener(n,e),0===r.listeners("exit").length&&0===r.listeners("afterexit").length&&a()}},e.exports.unload=a;var s={};o.forEach((function(e){s[e]=function(){process.listeners(e).length===r.count&&(a(),l("exit",null,e),l("afterexit",null,e),process.kill(process.pid,e))}})),e.exports.signals=function(){return o},e.exports.load=f;var c=!1;function f(){c||(c=!0,r.count+=1,o=o.filter((function(e){try{return process.on(e,s[e]),!0}catch(e){return!1}})),process.emit=v,process.reallyExit=p)}var d=process.reallyExit;function p(e){process.exitCode=e||0,l("exit",process.exitCode,null),l("afterexit",process.exitCode,null),d.call(process,process.exitCode)}var h=process.emit;function v(e,t){if("exit"===e){void 0!==t&&(process.exitCode=t);var n=h.apply(this,arguments);return l("exit",process.exitCode,null),l("afterexit",process.exitCode,null),n}return h.apply(this,arguments)}},8082:e=>{e.exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"],"win32"!==process.platform&&e.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT"),"linux"===process.platform&&e.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")},1566:(e,t,n)=>{"use strict";const r=n(7347),i=n(409),o=n(8483),u=["","›"],a=e=>`${u[0]}[${e}m`,l=(e,t,n)=>{let r=[];e=[...e];for(let n of e){const i=n;n.match(";")&&(n=n.split(";")[0][0]+"0");const u=o.codes.get(parseInt(n,10));if(u){const n=e.indexOf(u.toString());n>=0?e.splice(n,1):r.push(a(t?u:i))}else{if(t){r.push(a(0));break}r.push(a(i))}}if(t&&(r=r.filter((e,t)=>r.indexOf(e)===t),void 0!==n)){const e=a(o.codes.get(parseInt(n,10)));r=r.reduce((t,n)=>n===e?[n,...t]:[...t,n],[])}return r.join("")};e.exports=(e,t,n)=>{const o=[...e.normalize()],a=[];n="number"==typeof n?n:o.length;let s,c=!1,f=0,d="";for(const[p,h]of o.entries()){let o=!1;if(u.includes(h)){const t=/\d[^m]*/.exec(e.slice(p,p+18));s=t&&t.length>0?t[0]:void 0,ft&&f<=n)d+=h;else if(f!==t||c||void 0===s){if(f>=n){d+=l(a,!0,s);break}}else d=l(a)}return d}},9796:(e,t,n)=>{"use strict";const r=n(8759),i=[].concat(n(2282).builtinModules,"bootstrap_node","node").map(e=>new RegExp(`(?:\\(${e}\\.js:\\d+:\\d+\\)$|^\\s*at ${e}\\.js:\\d+:\\d+$)`));i.push(/\(internal\/[^:]+:\d+:\d+\)$/,/\s*at internal\/[^:]+:\d+:\d+$/,/\/\.node-spawn-wrap-\w+-\w+\/node:\d+:\d+\)?$/);class o{constructor(e){"internals"in(e={ignoredPackages:[],...e})==!1&&(e.internals=o.nodeInternals()),"cwd"in e==!1&&(e.cwd=process.cwd()),this._cwd=e.cwd.replace(/\\/g,"/"),this._internals=[].concat(e.internals,function(e){if(0===e.length)return[];const t=e.map(e=>r(e));return new RegExp(`[/\\\\]node_modules[/\\\\](?:${t.join("|")})[/\\\\][^:]+:\\d+:\\d+`)}(e.ignoredPackages)),this._wrapCallSite=e.wrapCallSite||!1}static nodeInternals(){return[...i]}clean(e,t=0){t=" ".repeat(t),Array.isArray(e)||(e=e.split("\n")),!/^\s*at /.test(e[0])&&/^\s*at /.test(e[1])&&(e=e.slice(1));let n=!1,r=null;const i=[];return e.forEach(e=>{if(e=e.replace(/\\/g,"/"),this._internals.some(t=>t.test(e)))return;const t=/^\s*at /.test(e);n?e=e.trimEnd().replace(/^(\s+)at /,"$1"):(e=e.trim(),t&&(e=e.slice(3))),(e=e.replace(this._cwd+"/",""))&&(t?(r&&(i.push(r),r=null),i.push(e)):(n=!0,r=e))}),i.map(e=>`${t}${e}\n`).join("")}captureString(e,t=this.captureString){"function"==typeof e&&(t=e,e=1/0);const{stackTraceLimit:n}=Error;e&&(Error.stackTraceLimit=e);const r={};Error.captureStackTrace(r,t);const{stack:i}=r;return Error.stackTraceLimit=n,this.clean(i)}capture(e,t=this.capture){"function"==typeof e&&(t=e,e=1/0);const{prepareStackTrace:n,stackTraceLimit:r}=Error;Error.prepareStackTrace=(e,t)=>this._wrapCallSite?t.map(this._wrapCallSite):t,e&&(Error.stackTraceLimit=e);const i={};Error.captureStackTrace(i,t);const{stack:o}=i;return Object.assign(Error,{prepareStackTrace:n,stackTraceLimit:r}),o}at(e=this.at){const[t]=this.capture(1,e);if(!t)return{};const n={line:t.getLineNumber(),column:t.getColumnNumber()};let r;u(n,t.getFileName(),this._cwd),t.isConstructor()&&(n.constructor=!0),t.isEval()&&(n.evalOrigin=t.getEvalOrigin()),t.isNative()&&(n.native=!0);try{r=t.getTypeName()}catch(e){}r&&"Object"!==r&&"[object Object]"!==r&&(n.type=r);const i=t.getFunctionName();i&&(n.function=i);const o=t.getMethodName();return o&&i!==o&&(n.method=o),n}parseLine(e){const t=e&&e.match(a);if(!t)return null;const n="new"===t[1];let r=t[2];const i=t[3],o=t[4],s=Number(t[5]),c=Number(t[6]);let f=t[7];const d=t[8],p=t[9],h="native"===t[10],v=")"===t[11];let m;const g={};if(d&&(g.line=Number(d)),p&&(g.column=Number(p)),v&&f){let e=0;for(let t=f.length-1;t>0;t--)if(")"===f.charAt(t))e++;else if("("===f.charAt(t)&&" "===f.charAt(t-1)&&(e--,-1===e&&" "===f.charAt(t-1))){const e=f.slice(0,t-1),n=f.slice(t+1);f=n,r+=" ("+e;break}}if(r){const e=r.match(l);e&&(r=e[1],m=e[2])}return u(g,f,this._cwd),n&&(g.constructor=!0),i&&(g.evalOrigin=i,g.evalLine=s,g.evalColumn=c,g.evalFile=o&&o.replace(/\\/g,"/")),h&&(g.native=!0),r&&(g.function=r),m&&r!==m&&(g.method=m),g}}function u(e,t,n){t&&((t=t.replace(/\\/g,"/")).startsWith(n+"/")&&(t=t.slice(n.length+1)),e.file=t)}const a=new RegExp("^(?:\\s*at )?(?:(new) )?(?:(.*?) \\()?(?:eval at ([^ ]+) \\((.+?):(\\d+):(\\d+)\\), )?(?:(.+?):(\\d+):(\\d+)|(native))(\\)?)$"),l=/^(.*?) \[as (.*?)\]$/;e.exports=o},3262:(e,t,n)=>{"use strict";const r=n(7402),i=n(5640),o=e=>r(e).replace(i()," ").length;e.exports=o,e.exports.default=o},5043:(e,t,n)=>{"use strict";const r=n(7915),i=n(7347),o=n(1013),u=e=>{if("string"!=typeof(e=e.replace(o()," "))||0===e.length)return 0;e=r(e);let t=0;for(let n=0;n=127&&r<=159||(r>=768&&r<=879||(r>65535&&n++,t+=i(r)?2:1))}return t};e.exports=u,e.exports.default=u},7402:(e,t,n)=>{"use strict";const r=n(5378),i=e=>"string"==typeof e?e.replace(r(),""):e;e.exports=i,e.exports.default=i},7915:(e,t,n)=>{"use strict";const r=n(1337);e.exports=e=>"string"==typeof e?e.replace(r(),""):e},9428:(e,t,n)=>{"use strict";const r=n(2087),i=n(3867),o=n(2918),{env:u}=process;let a;function l(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function s(e,t){if(0===a)return 0;if(o("color=16m")||o("color=full")||o("color=truecolor"))return 3;if(o("color=256"))return 2;if(e&&!t&&void 0===a)return 0;const n=a||0;if("dumb"===u.TERM)return n;if("win32"===process.platform){const e=r.release().split(".");return Number(e[0])>=10&&Number(e[2])>=10586?Number(e[2])>=14931?3:2:1}if("CI"in u)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some(e=>e in u)||"codeship"===u.CI_NAME?1:n;if("TEAMCITY_VERSION"in u)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(u.TEAMCITY_VERSION)?1:0;if("GITHUB_ACTIONS"in u)return 1;if("truecolor"===u.COLORTERM)return 3;if("TERM_PROGRAM"in u){const e=parseInt((u.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(u.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(u.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(u.TERM)||"COLORTERM"in u?1:n}o("no-color")||o("no-colors")||o("color=false")||o("color=never")?a=0:(o("color")||o("colors")||o("color=true")||o("color=always"))&&(a=1),"FORCE_COLOR"in u&&(a="true"===u.FORCE_COLOR?1:"false"===u.FORCE_COLOR?0:0===u.FORCE_COLOR.length?1:Math.min(parseInt(u.FORCE_COLOR,10),3)),e.exports={supportsColor:function(e){return l(s(e,e&&e.isTTY))},stdout:l(s(!0,i.isatty(1))),stderr:l(s(!0,i.isatty(2)))}},8949:(e,t,n)=>{"use strict";const r=n(5043),i=e=>{let t=0;for(const n of e.split("\n"))t=Math.max(t,r(n));return t};e.exports=i,e.exports.default=i},4332:(e,t,n)=>{"use strict";const r=n(5043),i=n(7915),o=n(8483),u=new Set(["","›"]),a=e=>`${u.values().next().value}[${e}m`,l=(e,t,n)=>{const o=[...t];let a=!1,l=r(i(e[e.length-1]));for(const[t,i]of o.entries()){const s=r(i);if(l+s<=n?e[e.length-1]+=i:(e.push(i),l=0),u.has(i))a=!0;else if(a&&"m"===i){a=!1;continue}a||(l+=s,l===n&&t0&&e.length>1&&(e[e.length-2]+=e.pop())},s=e=>{const t=e.split(" ");let n=t.length;for(;n>0&&!(r(t[n-1])>0);)n--;return n===t.length?e:t.slice(0,n).join(" ")+t.slice(n).join("")},c=(e,t,n={})=>{if(!1!==n.trim&&""===e.trim())return"";let i,c="",f="";const d=(e=>e.split(" ").map(e=>r(e)))(e);let p=[""];for(const[i,o]of e.split(" ").entries()){!1!==n.trim&&(p[p.length-1]=p[p.length-1].trimLeft());let e=r(p[p.length-1]);if(0!==i&&(e>=t&&(!1===n.wordWrap||!1===n.trim)&&(p.push(""),e=0),(e>0||!1===n.trim)&&(p[p.length-1]+=" ",e++)),n.hard&&d[i]>t){const n=t-e,r=1+Math.floor((d[i]-n-1)/t);Math.floor((d[i]-1)/t)t&&e>0&&d[i]>0){if(!1===n.wordWrap&&et&&!1===n.wordWrap?l(p,o,t):p[p.length-1]+=o}}!1!==n.trim&&(p=p.map(s)),c=p.join("\n");for(const[e,t]of[...c].entries()){if(f+=t,u.has(t)){const t=parseFloat(/\d[^m]*/.exec(c.slice(e,e+4)));i=39===t?null:t}const n=o.codes.get(Number(i));i&&n&&("\n"===c[e+1]?f+=a(n):"\n"===t&&(f+=a(i)))}return f};e.exports=(e,t,n)=>String(e).normalize().replace(/\r\n/g,"\n").split("\n").map(e=>c(e,t,n)).join("\n")},3354:function(module,exports){var __WEBPACK_AMD_DEFINE_ARRAY__,__WEBPACK_AMD_DEFINE_RESULT__,wrapper;wrapper=function(Module,cb){var Module;"function"==typeof Module&&(cb=Module,Module={}),Module.onRuntimeInitialized=function(e,t){return function(){e&&e.apply(this,arguments);try{Module.ccall("nbind_init")}catch(e){return void t(e)}t(null,{bind:Module._nbind_value,reflect:Module.NBind.reflect,queryType:Module.NBind.queryType,toggleLightGC:Module.toggleLightGC,lib:Module})}}(Module.onRuntimeInitialized,cb),Module||(Module=(void 0!==Module?Module:null)||{});var moduleOverrides={};for(var key in Module)Module.hasOwnProperty(key)&&(moduleOverrides[key]=Module[key]);var ENVIRONMENT_IS_WEB=!1,ENVIRONMENT_IS_WORKER=!1,ENVIRONMENT_IS_NODE=!1,ENVIRONMENT_IS_SHELL=!1,nodeFS,nodePath;if(Module.ENVIRONMENT)if("WEB"===Module.ENVIRONMENT)ENVIRONMENT_IS_WEB=!0;else if("WORKER"===Module.ENVIRONMENT)ENVIRONMENT_IS_WORKER=!0;else if("NODE"===Module.ENVIRONMENT)ENVIRONMENT_IS_NODE=!0;else{if("SHELL"!==Module.ENVIRONMENT)throw new Error("The provided Module['ENVIRONMENT'] value is not valid. It must be one of: WEB|WORKER|NODE|SHELL.");ENVIRONMENT_IS_SHELL=!0}else ENVIRONMENT_IS_WEB="object"==typeof window,ENVIRONMENT_IS_WORKER="function"==typeof importScripts,ENVIRONMENT_IS_NODE="object"==typeof process&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER,ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE)Module.print||(Module.print=console.log),Module.printErr||(Module.printErr=console.warn),Module.read=function(e,t){nodeFS||(nodeFS={}("")),nodePath||(nodePath={}("")),e=nodePath.normalize(e);var n=nodeFS.readFileSync(e);return t?n:n.toString()},Module.readBinary=function(e){var t=Module.read(e,!0);return t.buffer||(t=new Uint8Array(t)),assert(t.buffer),t},Module.load=function(e){globalEval(read(e))},Module.thisProgram||(process.argv.length>1?Module.thisProgram=process.argv[1].replace(/\\/g,"/"):Module.thisProgram="unknown-program"),Module.arguments=process.argv.slice(2),module.exports=Module,Module.inspect=function(){return"[Emscripten Module object]"};else if(ENVIRONMENT_IS_SHELL)Module.print||(Module.print=print),"undefined"!=typeof printErr&&(Module.printErr=printErr),"undefined"!=typeof read?Module.read=read:Module.read=function(){throw"no read() available"},Module.readBinary=function(e){if("function"==typeof readbuffer)return new Uint8Array(readbuffer(e));var t=read(e,"binary");return assert("object"==typeof t),t},"undefined"!=typeof scriptArgs?Module.arguments=scriptArgs:void 0!==arguments&&(Module.arguments=arguments),"function"==typeof quit&&(Module.quit=function(e,t){quit(e)});else{if(!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER)throw"Unknown runtime environment. Where are we?";if(Module.read=function(e){var t=new XMLHttpRequest;return t.open("GET",e,!1),t.send(null),t.responseText},ENVIRONMENT_IS_WORKER&&(Module.readBinary=function(e){var t=new XMLHttpRequest;return t.open("GET",e,!1),t.responseType="arraybuffer",t.send(null),new Uint8Array(t.response)}),Module.readAsync=function(e,t,n){var r=new XMLHttpRequest;r.open("GET",e,!0),r.responseType="arraybuffer",r.onload=function(){200==r.status||0==r.status&&r.response?t(r.response):n()},r.onerror=n,r.send(null)},void 0!==arguments&&(Module.arguments=arguments),"undefined"!=typeof console)Module.print||(Module.print=function(e){console.log(e)}),Module.printErr||(Module.printErr=function(e){console.warn(e)});else{var TRY_USE_DUMP=!1;Module.print||(Module.print=TRY_USE_DUMP&&"undefined"!=typeof dump?function(e){dump(e)}:function(e){})}ENVIRONMENT_IS_WORKER&&(Module.load=importScripts),void 0===Module.setWindowTitle&&(Module.setWindowTitle=function(e){document.title=e})}function globalEval(e){eval.call(null,e)}for(var key in!Module.load&&Module.read&&(Module.load=function(e){globalEval(Module.read(e))}),Module.print||(Module.print=function(){}),Module.printErr||(Module.printErr=Module.print),Module.arguments||(Module.arguments=[]),Module.thisProgram||(Module.thisProgram="./this.program"),Module.quit||(Module.quit=function(e,t){throw t}),Module.print=Module.print,Module.printErr=Module.printErr,Module.preRun=[],Module.postRun=[],moduleOverrides)moduleOverrides.hasOwnProperty(key)&&(Module[key]=moduleOverrides[key]);moduleOverrides=void 0;var Runtime={setTempRet0:function(e){return tempRet0=e,e},getTempRet0:function(){return tempRet0},stackSave:function(){return STACKTOP},stackRestore:function(e){STACKTOP=e},getNativeTypeSize:function(e){switch(e){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:if("*"===e[e.length-1])return Runtime.QUANTUM_SIZE;if("i"===e[0]){var t=parseInt(e.substr(1));return assert(t%8==0),t/8}return 0}},getNativeFieldSize:function(e){return Math.max(Runtime.getNativeTypeSize(e),Runtime.QUANTUM_SIZE)},STACK_ALIGN:16,prepVararg:function(e,t){return"double"===t||"i64"===t?7&e&&(assert(4==(7&e)),e+=4):assert(0==(3&e)),e},getAlignSize:function(e,t,n){return n||"i64"!=e&&"double"!=e?e?Math.min(t||(e?Runtime.getNativeFieldSize(e):0),Runtime.QUANTUM_SIZE):Math.min(t,8):8},dynCall:function(e,t,n){return n&&n.length?Module["dynCall_"+e].apply(null,[t].concat(n)):Module["dynCall_"+e].call(null,t)},functionPointers:[],addFunction:function(e){for(var t=0;t>2],n=-16&(t+e+15|0);return HEAP32[DYNAMICTOP_PTR>>2]=n,n>=TOTAL_MEMORY&&!enlargeMemory()?(HEAP32[DYNAMICTOP_PTR>>2]=t,0):t},alignMemory:function(e,t){return e=Math.ceil(e/(t||16))*(t||16)},makeBigInt:function(e,t,n){return n?+(e>>>0)+4294967296*+(t>>>0):+(e>>>0)+4294967296*+(0|t)},GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0};Module.Runtime=Runtime;var ABORT=0,EXITSTATUS=0,cwrap,ccall;function assert(e,t){e||abort("Assertion failed: "+t)}function getCFunc(ident){var func=Module["_"+ident];if(!func)try{func=eval("_"+ident)}catch(e){}return assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)"),func}function setValue(e,t,n,r){switch("*"===(n=n||"i8").charAt(n.length-1)&&(n="i32"),n){case"i1":case"i8":HEAP8[e>>0]=t;break;case"i16":HEAP16[e>>1]=t;break;case"i32":HEAP32[e>>2]=t;break;case"i64":tempI64=[t>>>0,(tempDouble=t,+Math_abs(tempDouble)>=1?tempDouble>0?(0|Math_min(+Math_floor(tempDouble/4294967296),4294967295))>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[e>>2]=tempI64[0],HEAP32[e+4>>2]=tempI64[1];break;case"float":HEAPF32[e>>2]=t;break;case"double":HEAPF64[e>>3]=t;break;default:abort("invalid type for setValue: "+n)}}function getValue(e,t,n){switch("*"===(t=t||"i8").charAt(t.length-1)&&(t="i32"),t){case"i1":case"i8":return HEAP8[e>>0];case"i16":return HEAP16[e>>1];case"i32":case"i64":return HEAP32[e>>2];case"float":return HEAPF32[e>>2];case"double":return HEAPF64[e>>3];default:abort("invalid type for setValue: "+t)}return null}!function(){var JSfuncs={stackSave:function(){Runtime.stackSave()},stackRestore:function(){Runtime.stackRestore()},arrayToC:function(e){var t=Runtime.stackAlloc(e.length);return writeArrayToMemory(e,t),t},stringToC:function(e){var t=0;if(null!=e&&0!==e){var n=1+(e.length<<2);stringToUTF8(e,t=Runtime.stackAlloc(n),n)}return t}},toC={string:JSfuncs.stringToC,array:JSfuncs.arrayToC};ccall=function(e,t,n,r,i){var o=getCFunc(e),u=[],a=0;if(r)for(var l=0;l>2]=0;for(l=u+o;r>0]=0;return u}if("i8"===a)return e.subarray||e.slice?HEAPU8.set(e,u):HEAPU8.set(new Uint8Array(e),u),u;for(var s,c,f,d=0;d>0],(0!=n||t)&&(i++,!t||i!=t););t||(t=i);var o="";if(r<128){for(var u;t>0;)u=String.fromCharCode.apply(String,HEAPU8.subarray(e,e+Math.min(t,1024))),o=o?o+u:u,e+=1024,t-=1024;return o}return Module.UTF8ToString(e)}function AsciiToString(e){for(var t="";;){var n=HEAP8[e++>>0];if(!n)return t;t+=String.fromCharCode(n)}}function stringToAscii(e,t){return writeAsciiToMemory(e,t,!1)}Module.ALLOC_NORMAL=ALLOC_NORMAL,Module.ALLOC_STACK=ALLOC_STACK,Module.ALLOC_STATIC=ALLOC_STATIC,Module.ALLOC_DYNAMIC=ALLOC_DYNAMIC,Module.ALLOC_NONE=ALLOC_NONE,Module.allocate=allocate,Module.getMemory=getMemory,Module.Pointer_stringify=Pointer_stringify,Module.AsciiToString=AsciiToString,Module.stringToAscii=stringToAscii;var UTF8Decoder="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0;function UTF8ArrayToString(e,t){for(var n=t;e[n];)++n;if(n-t>16&&e.subarray&&UTF8Decoder)return UTF8Decoder.decode(e.subarray(t,n));for(var r,i,o,u,a,l="";;){if(!(r=e[t++]))return l;if(128&r)if(i=63&e[t++],192!=(224&r))if(o=63&e[t++],224==(240&r)?r=(15&r)<<12|i<<6|o:(u=63&e[t++],240==(248&r)?r=(7&r)<<18|i<<12|o<<6|u:(a=63&e[t++],r=248==(252&r)?(3&r)<<24|i<<18|o<<12|u<<6|a:(1&r)<<30|i<<24|o<<18|u<<12|a<<6|63&e[t++])),r<65536)l+=String.fromCharCode(r);else{var s=r-65536;l+=String.fromCharCode(55296|s>>10,56320|1023&s)}else l+=String.fromCharCode((31&r)<<6|i);else l+=String.fromCharCode(r)}}function UTF8ToString(e){return UTF8ArrayToString(HEAPU8,e)}function stringToUTF8Array(e,t,n,r){if(!(r>0))return 0;for(var i=n,o=n+r-1,u=0;u=55296&&a<=57343&&(a=65536+((1023&a)<<10)|1023&e.charCodeAt(++u)),a<=127){if(n>=o)break;t[n++]=a}else if(a<=2047){if(n+1>=o)break;t[n++]=192|a>>6,t[n++]=128|63&a}else if(a<=65535){if(n+2>=o)break;t[n++]=224|a>>12,t[n++]=128|a>>6&63,t[n++]=128|63&a}else if(a<=2097151){if(n+3>=o)break;t[n++]=240|a>>18,t[n++]=128|a>>12&63,t[n++]=128|a>>6&63,t[n++]=128|63&a}else if(a<=67108863){if(n+4>=o)break;t[n++]=248|a>>24,t[n++]=128|a>>18&63,t[n++]=128|a>>12&63,t[n++]=128|a>>6&63,t[n++]=128|63&a}else{if(n+5>=o)break;t[n++]=252|a>>30,t[n++]=128|a>>24&63,t[n++]=128|a>>18&63,t[n++]=128|a>>12&63,t[n++]=128|a>>6&63,t[n++]=128|63&a}}return t[n]=0,n-i}function stringToUTF8(e,t,n){return stringToUTF8Array(e,HEAPU8,t,n)}function lengthBytesUTF8(e){for(var t=0,n=0;n=55296&&r<=57343&&(r=65536+((1023&r)<<10)|1023&e.charCodeAt(++n)),r<=127?++t:t+=r<=2047?2:r<=65535?3:r<=2097151?4:r<=67108863?5:6}return t}Module.UTF8ArrayToString=UTF8ArrayToString,Module.UTF8ToString=UTF8ToString,Module.stringToUTF8Array=stringToUTF8Array,Module.stringToUTF8=stringToUTF8,Module.lengthBytesUTF8=lengthBytesUTF8;var UTF16Decoder="undefined"!=typeof TextDecoder?new TextDecoder("utf-16le"):void 0,HEAP,buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64,STATIC_BASE,STATICTOP,staticSealed,STACK_BASE,STACKTOP,STACK_MAX,DYNAMIC_BASE,DYNAMICTOP_PTR;function demangle(e){var t=Module.___cxa_demangle||Module.__cxa_demangle;if(t){try{var n=e.substr(1),r=lengthBytesUTF8(n)+1,i=_malloc(r);stringToUTF8(n,i,r);var o=_malloc(4),u=t(i,0,0,o);if(0===getValue(o,"i32")&&u)return Pointer_stringify(u)}catch(e){}finally{i&&_free(i),o&&_free(o),u&&_free(u)}return e}return Runtime.warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling"),e}function demangleAll(e){return e.replace(/__Z[\w\d_]+/g,(function(e){var t=demangle(e);return e===t?e:e+" ["+t+"]"}))}function jsStackTrace(){var e=new Error;if(!e.stack){try{throw new Error(0)}catch(t){e=t}if(!e.stack)return"(no stack trace available)"}return e.stack.toString()}function stackTrace(){var e=jsStackTrace();return Module.extraStackTrace&&(e+="\n"+Module.extraStackTrace()),demangleAll(e)}function updateGlobalBufferViews(){Module.HEAP8=HEAP8=new Int8Array(buffer),Module.HEAP16=HEAP16=new Int16Array(buffer),Module.HEAP32=HEAP32=new Int32Array(buffer),Module.HEAPU8=HEAPU8=new Uint8Array(buffer),Module.HEAPU16=HEAPU16=new Uint16Array(buffer),Module.HEAPU32=HEAPU32=new Uint32Array(buffer),Module.HEAPF32=HEAPF32=new Float32Array(buffer),Module.HEAPF64=HEAPF64=new Float64Array(buffer)}function abortOnCannotGrowMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or (4) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}function enlargeMemory(){abortOnCannotGrowMemory()}Module.stackTrace=stackTrace,STATIC_BASE=STATICTOP=STACK_BASE=STACKTOP=STACK_MAX=DYNAMIC_BASE=DYNAMICTOP_PTR=0,staticSealed=!1;var TOTAL_STACK=Module.TOTAL_STACK||5242880,TOTAL_MEMORY=Module.TOTAL_MEMORY||134217728;function getTotalMemory(){return TOTAL_MEMORY}if(TOTAL_MEMORY0;){var t=e.shift();if("function"!=typeof t){var n=t.func;"number"==typeof n?void 0===t.arg?Module.dynCall_v(n):Module.dynCall_vi(n,t.arg):n(void 0===t.arg?null:t.arg)}else t()}}Module.HEAP=HEAP,Module.buffer=buffer,Module.HEAP8=HEAP8,Module.HEAP16=HEAP16,Module.HEAP32=HEAP32,Module.HEAPU8=HEAPU8,Module.HEAPU16=HEAPU16,Module.HEAPU32=HEAPU32,Module.HEAPF32=HEAPF32,Module.HEAPF64=HEAPF64;var __ATPRERUN__=[],__ATINIT__=[],__ATMAIN__=[],__ATEXIT__=[],__ATPOSTRUN__=[],runtimeInitialized=!1,runtimeExited=!1;function preRun(){if(Module.preRun)for("function"==typeof Module.preRun&&(Module.preRun=[Module.preRun]);Module.preRun.length;)addOnPreRun(Module.preRun.shift());callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){runtimeInitialized||(runtimeInitialized=!0,callRuntimeCallbacks(__ATINIT__))}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__),runtimeExited=!0}function postRun(){if(Module.postRun)for("function"==typeof Module.postRun&&(Module.postRun=[Module.postRun]);Module.postRun.length;)addOnPostRun(Module.postRun.shift());callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(e){__ATPRERUN__.unshift(e)}function addOnInit(e){__ATINIT__.unshift(e)}function addOnPreMain(e){__ATMAIN__.unshift(e)}function addOnExit(e){__ATEXIT__.unshift(e)}function addOnPostRun(e){__ATPOSTRUN__.unshift(e)}function intArrayFromString(e,t,n){var r=n>0?n:lengthBytesUTF8(e)+1,i=new Array(r),o=stringToUTF8Array(e,i,0,i.length);return t&&(i.length=o),i}function intArrayToString(e){for(var t=[],n=0;n255&&(r&=255),t.push(String.fromCharCode(r))}return t.join("")}function writeStringToMemory(e,t,n){var r,i;Runtime.warnOnce("writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!"),n&&(i=t+lengthBytesUTF8(e),r=HEAP8[i]),stringToUTF8(e,t,1/0),n&&(HEAP8[i]=r)}function writeArrayToMemory(e,t){HEAP8.set(e,t)}function writeAsciiToMemory(e,t,n){for(var r=0;r>0]=e.charCodeAt(r);n||(HEAP8[t>>0]=0)}if(Module.addOnPreRun=addOnPreRun,Module.addOnInit=addOnInit,Module.addOnPreMain=addOnPreMain,Module.addOnExit=addOnExit,Module.addOnPostRun=addOnPostRun,Module.intArrayFromString=intArrayFromString,Module.intArrayToString=intArrayToString,Module.writeStringToMemory=writeStringToMemory,Module.writeArrayToMemory=writeArrayToMemory,Module.writeAsciiToMemory=writeAsciiToMemory,Math.imul&&-5===Math.imul(4294967295,5)||(Math.imul=function(e,t){var n=65535&e,r=65535&t;return n*r+((e>>>16)*r+n*(t>>>16)<<16)|0}),Math.imul=Math.imul,!Math.fround){var froundBuffer=new Float32Array(1);Math.fround=function(e){return froundBuffer[0]=e,froundBuffer[0]}}Math.fround=Math.fround,Math.clz32||(Math.clz32=function(e){e>>>=0;for(var t=0;t<32;t++)if(e&1<<31-t)return t;return 32}),Math.clz32=Math.clz32,Math.trunc||(Math.trunc=function(e){return e<0?Math.ceil(e):Math.floor(e)}),Math.trunc=Math.trunc;var Math_abs=Math.abs,Math_cos=Math.cos,Math_sin=Math.sin,Math_tan=Math.tan,Math_acos=Math.acos,Math_asin=Math.asin,Math_atan=Math.atan,Math_atan2=Math.atan2,Math_exp=Math.exp,Math_log=Math.log,Math_sqrt=Math.sqrt,Math_ceil=Math.ceil,Math_floor=Math.floor,Math_pow=Math.pow,Math_imul=Math.imul,Math_fround=Math.fround,Math_round=Math.round,Math_min=Math.min,Math_clz32=Math.clz32,Math_trunc=Math.trunc,runDependencies=0,runDependencyWatcher=null,dependenciesFulfilled=null;function getUniqueRunDependency(e){return e}function addRunDependency(e){runDependencies++,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies)}function removeRunDependency(e){if(runDependencies--,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies),0==runDependencies&&(null!==runDependencyWatcher&&(clearInterval(runDependencyWatcher),runDependencyWatcher=null),dependenciesFulfilled)){var t=dependenciesFulfilled;dependenciesFulfilled=null,t()}}Module.addRunDependency=addRunDependency,Module.removeRunDependency=removeRunDependency,Module.preloadedImages={},Module.preloadedAudios={};var ASM_CONSTS=[function(e,t,n,r,i,o,u,a){return _nbind.callbackSignatureList[e].apply(this,arguments)}];function _emscripten_asm_const_iiiiiiii(e,t,n,r,i,o,u,a){return ASM_CONSTS[e](t,n,r,i,o,u,a)}function _emscripten_asm_const_iiiii(e,t,n,r,i){return ASM_CONSTS[e](t,n,r,i)}function _emscripten_asm_const_iiidddddd(e,t,n,r,i,o,u,a,l){return ASM_CONSTS[e](t,n,r,i,o,u,a,l)}function _emscripten_asm_const_iiididi(e,t,n,r,i,o,u){return ASM_CONSTS[e](t,n,r,i,o,u)}function _emscripten_asm_const_iiii(e,t,n,r){return ASM_CONSTS[e](t,n,r)}function _emscripten_asm_const_iiiid(e,t,n,r,i){return ASM_CONSTS[e](t,n,r,i)}function _emscripten_asm_const_iiiiii(e,t,n,r,i,o){return ASM_CONSTS[e](t,n,r,i,o)}STATIC_BASE=Runtime.GLOBAL_BASE,STATICTOP=STATIC_BASE+12800,__ATINIT__.push({func:function(){__GLOBAL__sub_I_Yoga_cpp()}},{func:function(){__GLOBAL__sub_I_nbind_cc()}},{func:function(){__GLOBAL__sub_I_common_cc()}},{func:function(){__GLOBAL__sub_I_Binding_cc()}}),allocate([0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,192,127,0,0,192,127,0,0,192,127,3,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,3,0,0,0,0,0,192,127,3,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,192,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,192,127,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,0,0,128,191,0,0,128,191,0,0,192,127,0,0,0,0,0,0,0,0,0,0,128,63,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,190,12,0,0,200,12,0,0,208,12,0,0,216,12,0,0,230,12,0,0,242,12,0,0,1,0,0,0,3,0,0,0,0,0,0,0,2,0,0,0,0,0,192,127,3,0,0,0,180,45,0,0,181,45,0,0,182,45,0,0,181,45,0,0,182,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,1,0,0,0,4,0,0,0,183,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,184,45,0,0,185,45,0,0,181,45,0,0,181,45,0,0,182,45,0,0,186,45,0,0,185,45,0,0,148,4,0,0,3,0,0,0,187,45,0,0,164,4,0,0,188,45,0,0,2,0,0,0,189,45,0,0,164,4,0,0,188,45,0,0,185,45,0,0,164,4,0,0,185,45,0,0,164,4,0,0,188,45,0,0,181,45,0,0,182,45,0,0,181,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,0,0,0,6,0,0,0,1,0,0,0,7,0,0,0,183,45,0,0,182,45,0,0,181,45,0,0,190,45,0,0,190,45,0,0,182,45,0,0,182,45,0,0,185,45,0,0,181,45,0,0,185,45,0,0,182,45,0,0,181,45,0,0,185,45,0,0,182,45,0,0,185,45,0,0,48,5,0,0,3,0,0,0,56,5,0,0,1,0,0,0,189,45,0,0,185,45,0,0,164,4,0,0,76,5,0,0,2,0,0,0,191,45,0,0,186,45,0,0,182,45,0,0,185,45,0,0,192,45,0,0,185,45,0,0,182,45,0,0,186,45,0,0,185,45,0,0,76,5,0,0,76,5,0,0,136,5,0,0,182,45,0,0,181,45,0,0,2,0,0,0,190,45,0,0,136,5,0,0,56,19,0,0,156,5,0,0,2,0,0,0,184,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0,0,9,0,0,0,1,0,0,0,10,0,0,0,204,5,0,0,181,45,0,0,181,45,0,0,2,0,0,0,180,45,0,0,204,5,0,0,2,0,0,0,195,45,0,0,236,5,0,0,97,19,0,0,198,45,0,0,211,45,0,0,212,45,0,0,213,45,0,0,214,45,0,0,215,45,0,0,188,45,0,0,182,45,0,0,216,45,0,0,217,45,0,0,218,45,0,0,219,45,0,0,192,45,0,0,181,45,0,0,0,0,0,0,185,45,0,0,110,19,0,0,186,45,0,0,115,19,0,0,221,45,0,0,120,19,0,0,148,4,0,0,132,19,0,0,96,6,0,0,145,19,0,0,222,45,0,0,164,19,0,0,223,45,0,0,173,19,0,0,0,0,0,0,3,0,0,0,104,6,0,0,1,0,0,0,187,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,12,0,0,0,1,0,0,0,13,0,0,0,185,45,0,0,224,45,0,0,164,6,0,0,188,45,0,0,172,6,0,0,180,6,0,0,2,0,0,0,188,6,0,0,7,0,0,0,224,45,0,0,7,0,0,0,164,6,0,0,1,0,0,0,213,45,0,0,185,45,0,0,224,45,0,0,172,6,0,0,185,45,0,0,224,45,0,0,164,6,0,0,185,45,0,0,224,45,0,0,211,45,0,0,211,45,0,0,222,45,0,0,211,45,0,0,224,45,0,0,222,45,0,0,211,45,0,0,224,45,0,0,172,6,0,0,222,45,0,0,211,45,0,0,224,45,0,0,188,45,0,0,222,45,0,0,211,45,0,0,40,7,0,0,188,45,0,0,2,0,0,0,224,45,0,0,185,45,0,0,188,45,0,0,188,45,0,0,188,45,0,0,188,45,0,0,222,45,0,0,224,45,0,0,148,4,0,0,185,45,0,0,148,4,0,0,148,4,0,0,148,4,0,0,148,4,0,0,148,4,0,0,185,45,0,0,164,6,0,0,148,4,0,0,0,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,15,0,0,0,1,0,0,0,16,0,0,0,148,7,0,0,2,0,0,0,225,45,0,0,183,45,0,0,188,45,0,0,168,7,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,234,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,148,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,9,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,242,45,0,0,0,4,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67,111,117,108,100,32,110,111,116,32,97,108,108,111,99,97,116,101,32,109,101,109,111,114,121,32,102,111,114,32,110,111,100,101,0,67,97,110,110,111,116,32,114,101,115,101,116,32,97,32,110,111,100,101,32,119,104,105,99,104,32,115,116,105,108,108,32,104,97,115,32,99,104,105,108,100,114,101,110,32,97,116,116,97,99,104,101,100,0,67,97,110,110,111,116,32,114,101,115,101,116,32,97,32,110,111,100,101,32,115,116,105,108,108,32,97,116,116,97,99,104,101,100,32,116,111,32,97,32,112,97,114,101,110,116,0,67,111,117,108,100,32,110,111,116,32,97,108,108,111,99,97,116,101,32,109,101,109,111,114,121,32,102,111,114,32,99,111,110,102,105,103,0,67,97,110,110,111,116,32,115,101,116,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,58,32,78,111,100,101,115,32,119,105,116,104,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,115,32,99,97,110,110,111,116,32,104,97,118,101,32,99,104,105,108,100,114,101,110,46,0,67,104,105,108,100,32,97,108,114,101,97,100,121,32,104,97,115,32,97,32,112,97,114,101,110,116,44,32,105,116,32,109,117,115,116,32,98,101,32,114,101,109,111,118,101,100,32,102,105,114,115,116,46,0,67,97,110,110,111,116,32,97,100,100,32,99,104,105,108,100,58,32,78,111,100,101,115,32,119,105,116,104,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,115,32,99,97,110,110,111,116,32,104,97,118,101,32,99,104,105,108,100,114,101,110,46,0,79,110,108,121,32,108,101,97,102,32,110,111,100,101,115,32,119,105,116,104,32,99,117,115,116,111,109,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,115,115,104,111,117,108,100,32,109,97,110,117,97,108,108,121,32,109,97,114,107,32,116,104,101,109,115,101,108,118,101,115,32,97,115,32,100,105,114,116,121,0,67,97,110,110,111,116,32,103,101,116,32,108,97,121,111,117,116,32,112,114,111,112,101,114,116,105,101,115,32,111,102,32,109,117,108,116,105,45,101,100,103,101,32,115,104,111,114,116,104,97,110,100,115,0,37,115,37,100,46,123,91,115,107,105,112,112,101,100,93,32,0,119,109,58,32,37,115,44,32,104,109,58,32,37,115,44,32,97,119,58,32,37,102,32,97,104,58,32,37,102,32,61,62,32,100,58,32,40,37,102,44,32,37,102,41,32,37,115,10,0,37,115,37,100,46,123,37,115,0,42,0,119,109,58,32,37,115,44,32,104,109,58,32,37,115,44,32,97,119,58,32,37,102,32,97,104,58,32,37,102,32,37,115,10,0,37,115,37,100,46,125,37,115,0,119,109,58,32,37,115,44,32,104,109,58,32,37,115,44,32,100,58,32,40,37,102,44,32,37,102,41,32,37,115,10,0,79,117,116,32,111,102,32,99,97,99,104,101,32,101,110,116,114,105,101,115,33,10,0,83,99,97,108,101,32,102,97,99,116,111,114,32,115,104,111,117,108,100,32,110,111,116,32,98,101,32,108,101,115,115,32,116,104,97,110,32,122,101,114,111,0,105,110,105,116,105,97,108,0,37,115,10,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,85,78,68,69,70,73,78,69,68,0,69,88,65,67,84,76,89,0,65,84,95,77,79,83,84,0,76,65,89,95,85,78,68,69,70,73,78,69,68,0,76,65,89,95,69,88,65,67,84,76,89,0,76,65,89,95,65,84,95,77,79,83,84,0,97,118,97,105,108,97,98,108,101,87,105,100,116,104,32,105,115,32,105,110,100,101,102,105,110,105,116,101,32,115,111,32,119,105,100,116,104,77,101,97,115,117,114,101,77,111,100,101,32,109,117,115,116,32,98,101,32,89,71,77,101,97,115,117,114,101,77,111,100,101,85,110,100,101,102,105,110,101,100,0,97,118,97,105,108,97,98,108,101,72,101,105,103,104,116,32,105,115,32,105,110,100,101,102,105,110,105,116,101,32,115,111,32,104,101,105,103,104,116,77,101,97,115,117,114,101,77,111,100,101,32,109,117,115,116,32,98,101,32,89,71,77,101,97,115,117,114,101,77,111,100,101,85,110,100,101,102,105,110,101,100,0,102,108,101,120,0,115,116,114,101,116,99,104,0,109,117,108,116,105,108,105,110,101,45,115,116,114,101,116,99,104,0,69,120,112,101,99,116,101,100,32,110,111,100,101,32,116,111,32,104,97,118,101,32,99,117,115,116,111,109,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,0,109,101,97,115,117,114,101,0,69,120,112,101,99,116,32,99,117,115,116,111,109,32,98,97,115,101,108,105,110,101,32,102,117,110,99,116,105,111,110,32,116,111,32,110,111,116,32,114,101,116,117,114,110,32,78,97,78,0,97,98,115,45,109,101,97,115,117,114,101,0,97,98,115,45,108,97,121,111,117,116,0,78,111,100,101,0,99,114,101,97,116,101,68,101,102,97,117,108,116,0,99,114,101,97,116,101,87,105,116,104,67,111,110,102,105,103,0,100,101,115,116,114,111,121,0,114,101,115,101,116,0,99,111,112,121,83,116,121,108,101,0,115,101,116,80,111,115,105,116,105,111,110,84,121,112,101,0,115,101,116,80,111,115,105,116,105,111,110,0,115,101,116,80,111,115,105,116,105,111,110,80,101,114,99,101,110,116,0,115,101,116,65,108,105,103,110,67,111,110,116,101,110,116,0,115,101,116,65,108,105,103,110,73,116,101,109,115,0,115,101,116,65,108,105,103,110,83,101,108,102,0,115,101,116,70,108,101,120,68,105,114,101,99,116,105,111,110,0,115,101,116,70,108,101,120,87,114,97,112,0,115,101,116,74,117,115,116,105,102,121,67,111,110,116,101,110,116,0,115,101,116,77,97,114,103,105,110,0,115,101,116,77,97,114,103,105,110,80,101,114,99,101,110,116,0,115,101,116,77,97,114,103,105,110,65,117,116,111,0,115,101,116,79,118,101,114,102,108,111,119,0,115,101,116,68,105,115,112,108,97,121,0,115,101,116,70,108,101,120,0,115,101,116,70,108,101,120,66,97,115,105,115,0,115,101,116,70,108,101,120,66,97,115,105,115,80,101,114,99,101,110,116,0,115,101,116,70,108,101,120,71,114,111,119,0,115,101,116,70,108,101,120,83,104,114,105,110,107,0,115,101,116,87,105,100,116,104,0,115,101,116,87,105,100,116,104,80,101,114,99,101,110,116,0,115,101,116,87,105,100,116,104,65,117,116,111,0,115,101,116,72,101,105,103,104,116,0,115,101,116,72,101,105,103,104,116,80,101,114,99,101,110,116,0,115,101,116,72,101,105,103,104,116,65,117,116,111,0,115,101,116,77,105,110,87,105,100,116,104,0,115,101,116,77,105,110,87,105,100,116,104,80,101,114,99,101,110,116,0,115,101,116,77,105,110,72,101,105,103,104,116,0,115,101,116,77,105,110,72,101,105,103,104,116,80,101,114,99,101,110,116,0,115,101,116,77,97,120,87,105,100,116,104,0,115,101,116,77,97,120,87,105,100,116,104,80,101,114,99,101,110,116,0,115,101,116,77,97,120,72,101,105,103,104,116,0,115,101,116,77,97,120,72,101,105,103,104,116,80,101,114,99,101,110,116,0,115,101,116,65,115,112,101,99,116,82,97,116,105,111,0,115,101,116,66,111,114,100,101,114,0,115,101,116,80,97,100,100,105,110,103,0,115,101,116,80,97,100,100,105,110,103,80,101,114,99,101,110,116,0,103,101,116,80,111,115,105,116,105,111,110,84,121,112,101,0,103,101,116,80,111,115,105,116,105,111,110,0,103,101,116,65,108,105,103,110,67,111,110,116,101,110,116,0,103,101,116,65,108,105,103,110,73,116,101,109,115,0,103,101,116,65,108,105,103,110,83,101,108,102,0,103,101,116,70,108,101,120,68,105,114,101,99,116,105,111,110,0,103,101,116,70,108,101,120,87,114,97,112,0,103,101,116,74,117,115,116,105,102,121,67,111,110,116,101,110,116,0,103,101,116,77,97,114,103,105,110,0,103,101,116,70,108,101,120,66,97,115,105,115,0,103,101,116,70,108,101,120,71,114,111,119,0,103,101,116,70,108,101,120,83,104,114,105,110,107,0,103,101,116,87,105,100,116,104,0,103,101,116,72,101,105,103,104,116,0,103,101,116,77,105,110,87,105,100,116,104,0,103,101,116,77,105,110,72,101,105,103,104,116,0,103,101,116,77,97,120,87,105,100,116,104,0,103,101,116,77,97,120,72,101,105,103,104,116,0,103,101,116,65,115,112,101,99,116,82,97,116,105,111,0,103,101,116,66,111,114,100,101,114,0,103,101,116,79,118,101,114,102,108,111,119,0,103,101,116,68,105,115,112,108,97,121,0,103,101,116,80,97,100,100,105,110,103,0,105,110,115,101,114,116,67,104,105,108,100,0,114,101,109,111,118,101,67,104,105,108,100,0,103,101,116,67,104,105,108,100,67,111,117,110,116,0,103,101,116,80,97,114,101,110,116,0,103,101,116,67,104,105,108,100,0,115,101,116,77,101,97,115,117,114,101,70,117,110,99,0,117,110,115,101,116,77,101,97,115,117,114,101,70,117,110,99,0,109,97,114,107,68,105,114,116,121,0,105,115,68,105,114,116,121,0,99,97,108,99,117,108,97,116,101,76,97,121,111,117,116,0,103,101,116,67,111,109,112,117,116,101,100,76,101,102,116,0,103,101,116,67,111,109,112,117,116,101,100,82,105,103,104,116,0,103,101,116,67,111,109,112,117,116,101,100,84,111,112,0,103,101,116,67,111,109,112,117,116,101,100,66,111,116,116,111,109,0,103,101,116,67,111,109,112,117,116,101,100,87,105,100,116,104,0,103,101,116,67,111,109,112,117,116,101,100,72,101,105,103,104,116,0,103,101,116,67,111,109,112,117,116,101,100,76,97,121,111,117,116,0,103,101,116,67,111,109,112,117,116,101,100,77,97,114,103,105,110,0,103,101,116,67,111,109,112,117,116,101,100,66,111,114,100,101,114,0,103,101,116,67,111,109,112,117,116,101,100,80,97,100,100,105,110,103,0,67,111,110,102,105,103,0,99,114,101,97,116,101,0,115,101,116,69,120,112,101,114,105,109,101,110,116,97,108,70,101,97,116,117,114,101,69,110,97,98,108,101,100,0,115,101,116,80,111,105,110,116,83,99,97,108,101,70,97,99,116,111,114,0,105,115,69,120,112,101,114,105,109,101,110,116,97,108,70,101,97,116,117,114,101,69,110,97,98,108,101,100,0,86,97,108,117,101,0,76,97,121,111,117,116,0,83,105,122,101,0,103,101,116,73,110,115,116,97,110,99,101,67,111,117,110,116,0,73,110,116,54,52,0,1,1,1,2,2,4,4,4,4,8,8,4,8,118,111,105,100,0,98,111,111,108,0,115,116,100,58,58,115,116,114,105,110,103,0,99,98,70,117,110,99,116,105,111,110,32,38,0,99,111,110,115,116,32,99,98,70,117,110,99,116,105,111,110,32,38,0,69,120,116,101,114,110,97,108,0,66,117,102,102,101,114,0,78,66,105,110,100,73,68,0,78,66,105,110,100,0,98,105,110,100,95,118,97,108,117,101,0,114,101,102,108,101,99,116,0,113,117,101,114,121,84,121,112,101,0,108,97,108,108,111,99,0,108,114,101,115,101,116,0,123,114,101,116,117,114,110,40,95,110,98,105,110,100,46,99,97,108,108,98,97,99,107,83,105,103,110,97,116,117,114,101,76,105,115,116,91,36,48,93,46,97,112,112,108,121,40,116,104,105,115,44,97,114,103,117,109,101,110,116,115,41,41,59,125,0,95,110,98,105,110,100,95,110,101,119,0,17,0,10,0,17,17,17,0,0,0,0,5,0,0,0,0,0,0,9,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,15,10,17,17,17,3,10,7,0,1,19,9,11,11,0,0,9,6,11,0,0,11,0,6,17,0,0,0,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,10,10,17,17,17,0,10,0,0,2,0,9,11,0,0,0,9,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,13,0,0,0,0,9,14,0,0,0,0,0,14,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,15,0,0,0,0,9,16,0,0,0,0,0,16,0,0,16,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,10,0,0,0,0,9,11,0,0,0,0,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,45,43,32,32,32,48,88,48,120,0,40,110,117,108,108,41,0,45,48,88,43,48,88,32,48,88,45,48,120,43,48,120,32,48,120,0,105,110,102,0,73,78,70,0,110,97,110,0,78,65,78,0,48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,46,0,84,33,34,25,13,1,2,3,17,75,28,12,16,4,11,29,18,30,39,104,110,111,112,113,98,32,5,6,15,19,20,21,26,8,22,7,40,36,23,24,9,10,14,27,31,37,35,131,130,125,38,42,43,60,61,62,63,67,71,74,77,88,89,90,91,92,93,94,95,96,97,99,100,101,102,103,105,106,107,108,114,115,116,121,122,123,124,0,73,108,108,101,103,97,108,32,98,121,116,101,32,115,101,113,117,101,110,99,101,0,68,111,109,97,105,110,32,101,114,114,111,114,0,82,101,115,117,108,116,32,110,111,116,32,114,101,112,114,101,115,101,110,116,97,98,108,101,0,78,111,116,32,97,32,116,116,121,0,80,101,114,109,105,115,115,105,111,110,32,100,101,110,105,101,100,0,79,112,101,114,97,116,105,111,110,32,110,111,116,32,112,101,114,109,105,116,116,101,100,0,78,111,32,115,117,99,104,32,102,105,108,101,32,111,114,32,100,105,114,101,99,116,111,114,121,0,78,111,32,115,117,99,104,32,112,114,111,99,101,115,115,0,70,105,108,101,32,101,120,105,115,116,115,0,86,97,108,117,101,32,116,111,111,32,108,97,114,103,101,32,102,111,114,32,100,97,116,97,32,116,121,112,101,0,78,111,32,115,112,97,99,101,32,108,101,102,116,32,111,110,32,100,101,118,105,99,101,0,79,117,116,32,111,102,32,109,101,109,111,114,121,0,82,101,115,111,117,114,99,101,32,98,117,115,121,0,73,110,116,101,114,114,117,112,116,101,100,32,115,121,115,116,101,109,32,99,97,108,108,0,82,101,115,111,117,114,99,101,32,116,101,109,112,111,114,97,114,105,108,121,32,117,110,97,118,97,105,108,97,98,108,101,0,73,110,118,97,108,105,100,32,115,101,101,107,0,67,114,111,115,115,45,100,101,118,105,99,101,32,108,105,110,107,0,82,101,97,100,45,111,110,108,121,32,102,105,108,101,32,115,121,115,116,101,109,0,68,105,114,101,99,116,111,114,121,32,110,111,116,32,101,109,112,116,121,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,112,101,101,114,0,79,112,101,114,97,116,105,111,110,32,116,105,109,101,100,32,111,117,116,0,67,111,110,110,101,99,116,105,111,110,32,114,101,102,117,115,101,100,0,72,111,115,116,32,105,115,32,100,111,119,110,0,72,111,115,116,32,105,115,32,117,110,114,101,97,99,104,97,98,108,101,0,65,100,100,114,101,115,115,32,105,110,32,117,115,101,0,66,114,111,107,101,110,32,112,105,112,101,0,73,47,79,32,101,114,114,111,114,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,32,111,114,32,97,100,100,114,101,115,115,0,66,108,111,99,107,32,100,101,118,105,99,101,32,114,101,113,117,105,114,101,100,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,0,78,111,116,32,97,32,100,105,114,101,99,116,111,114,121,0,73,115,32,97,32,100,105,114,101,99,116,111,114,121,0,84,101,120,116,32,102,105,108,101,32,98,117,115,121,0,69,120,101,99,32,102,111,114,109,97,116,32,101,114,114,111,114,0,73,110,118,97,108,105,100,32,97,114,103,117,109,101,110,116,0,65,114,103,117,109,101,110,116,32,108,105,115,116,32,116,111,111,32,108,111,110,103,0,83,121,109,98,111,108,105,99,32,108,105,110,107,32,108,111,111,112,0,70,105,108,101,110,97,109,101,32,116,111,111,32,108,111,110,103,0,84,111,111,32,109,97,110,121,32,111,112,101,110,32,102,105,108,101,115,32,105,110,32,115,121,115,116,101,109,0,78,111,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,115,32,97,118,97,105,108,97,98,108,101,0,66,97,100,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,0,78,111,32,99,104,105,108,100,32,112,114,111,99,101,115,115,0,66,97,100,32,97,100,100,114,101,115,115,0,70,105,108,101,32,116,111,111,32,108,97,114,103,101,0,84,111,111,32,109,97,110,121,32,108,105,110,107,115,0,78,111,32,108,111,99,107,115,32,97,118,97,105,108,97,98,108,101,0,82,101,115,111,117,114,99,101,32,100,101,97,100,108,111,99,107,32,119,111,117,108,100,32,111,99,99,117,114,0,83,116,97,116,101,32,110,111,116,32,114,101,99,111,118,101,114,97,98,108,101,0,80,114,101,118,105,111,117,115,32,111,119,110,101,114,32,100,105,101,100,0,79,112,101,114,97,116,105,111,110,32,99,97,110,99,101,108,101,100,0,70,117,110,99,116,105,111,110,32,110,111,116,32,105,109,112,108,101,109,101,110,116,101,100,0,78,111,32,109,101,115,115,97,103,101,32,111,102,32,100,101,115,105,114,101,100,32,116,121,112,101,0,73,100,101,110,116,105,102,105,101,114,32,114,101,109,111,118,101,100,0,68,101,118,105,99,101,32,110,111,116,32,97,32,115,116,114,101,97,109,0,78,111,32,100,97,116,97,32,97,118,97,105,108,97,98,108,101,0,68,101,118,105,99,101,32,116,105,109,101,111,117,116,0,79,117,116,32,111,102,32,115,116,114,101,97,109,115,32,114,101,115,111,117,114,99,101,115,0,76,105,110,107,32,104,97,115,32,98,101,101,110,32,115,101,118,101,114,101,100,0,80,114,111,116,111,99,111,108,32,101,114,114,111,114,0,66,97,100,32,109,101,115,115,97,103,101,0,70,105,108,101,32,100,101,115,99,114,105,112,116,111,114,32,105,110,32,98,97,100,32,115,116,97,116,101,0,78,111,116,32,97,32,115,111,99,107,101,116,0,68,101,115,116,105,110,97,116,105,111,110,32,97,100,100,114,101,115,115,32,114,101,113,117,105,114,101,100,0,77,101,115,115,97,103,101,32,116,111,111,32,108,97,114,103,101,0,80,114,111,116,111,99,111,108,32,119,114,111,110,103,32,116,121,112,101,32,102,111,114,32,115,111,99,107,101,116,0,80,114,111,116,111,99,111,108,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,80,114,111,116,111,99,111,108,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,83,111,99,107,101,116,32,116,121,112,101,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,78,111,116,32,115,117,112,112,111,114,116,101,100,0,80,114,111,116,111,99,111,108,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,65,100,100,114,101,115,115,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,32,98,121,32,112,114,111,116,111,99,111,108,0,65,100,100,114,101,115,115,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,78,101,116,119,111,114,107,32,105,115,32,100,111,119,110,0,78,101,116,119,111,114,107,32,117,110,114,101,97,99,104,97,98,108,101,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,110,101,116,119,111,114,107,0,67,111,110,110,101,99,116,105,111,110,32,97,98,111,114,116,101,100,0,78,111,32,98,117,102,102,101,114,32,115,112,97,99,101,32,97,118,97,105,108,97,98,108,101,0,83,111,99,107,101,116,32,105,115,32,99,111,110,110,101,99,116,101,100,0,83,111,99,107,101,116,32,110,111,116,32,99,111,110,110,101,99,116,101,100,0,67,97,110,110,111,116,32,115,101,110,100,32,97,102,116,101,114,32,115,111,99,107,101,116,32,115,104,117,116,100,111,119,110,0,79,112,101,114,97,116,105,111,110,32,97,108,114,101,97,100,121,32,105,110,32,112,114,111,103,114,101,115,115,0,79,112,101,114,97,116,105,111,110,32,105,110,32,112,114,111,103,114,101,115,115,0,83,116,97,108,101,32,102,105,108,101,32,104,97,110,100,108,101,0,82,101,109,111,116,101,32,73,47,79,32,101,114,114,111,114,0,81,117,111,116,97,32,101,120,99,101,101,100,101,100,0,78,111,32,109,101,100,105,117,109,32,102,111,117,110,100,0,87,114,111,110,103,32,109,101,100,105,117,109,32,116,121,112,101,0,78,111,32,101,114,114,111,114,32,105,110,102,111,114,109,97,116,105,111,110,0,0],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE);var tempDoublePtr=STATICTOP;function _atexit(e,t){__ATEXIT__.unshift({func:e,arg:t})}function ___cxa_atexit(){return _atexit.apply(null,arguments)}function _abort(){Module.abort()}function __ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj(){Module.printErr("missing function: _ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj"),abort(-1)}function __decorate(e,t,n,r){var i,o=arguments.length,u=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)u=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(u=(o<3?i(u):o>3?i(t,n,u):i(t,n))||u);return o>3&&u&&Object.defineProperty(t,n,u),u}function _defineHidden(e){return function(t,n){Object.defineProperty(t,n,{configurable:!1,enumerable:!1,value:e,writable:!0})}}STATICTOP+=16;var _nbind={};function __nbind_free_external(e){_nbind.externalList[e].dereference(e)}function __nbind_reference_external(e){_nbind.externalList[e].reference()}function _llvm_stackrestore(e){var t=_llvm_stacksave,n=t.LLVM_SAVEDSTACKS[e];t.LLVM_SAVEDSTACKS.splice(e,1),Runtime.stackRestore(n)}function __nbind_register_pool(e,t,n,r){_nbind.Pool.pageSize=e,_nbind.Pool.usedPtr=t/4,_nbind.Pool.rootPtr=n,_nbind.Pool.pagePtr=r/4,HEAP32[t/4]=16909060,1==HEAP8[t]&&(_nbind.bigEndian=!0),HEAP32[t/4]=0,_nbind.makeTypeKindTbl=((i={})[1024]=_nbind.PrimitiveType,i[64]=_nbind.Int64Type,i[2048]=_nbind.BindClass,i[3072]=_nbind.BindClassPtr,i[4096]=_nbind.SharedClassPtr,i[5120]=_nbind.ArrayType,i[6144]=_nbind.ArrayType,i[7168]=_nbind.CStringType,i[9216]=_nbind.CallbackType,i[10240]=_nbind.BindType,i),_nbind.makeTypeNameTbl={Buffer:_nbind.BufferType,External:_nbind.ExternalType,Int64:_nbind.Int64Type,_nbind_new:_nbind.CreateValueType,bool:_nbind.BooleanType,"cbFunction &":_nbind.CallbackType,"const cbFunction &":_nbind.CallbackType,"const std::string &":_nbind.StringType,"std::string":_nbind.StringType},Module.toggleLightGC=_nbind.toggleLightGC,_nbind.callUpcast=Module.dynCall_ii;var i,o=_nbind.makeType(_nbind.constructType,{flags:2048,id:0,name:""});o.proto=Module,_nbind.BindClass.list.push(o)}function _emscripten_set_main_loop_timing(e,t){if(Browser.mainLoop.timingMode=e,Browser.mainLoop.timingValue=t,!Browser.mainLoop.func)return 1;if(0==e)Browser.mainLoop.scheduler=function(){var e=0|Math.max(0,Browser.mainLoop.tickStartTime+t-_emscripten_get_now());setTimeout(Browser.mainLoop.runner,e)},Browser.mainLoop.method="timeout";else if(1==e)Browser.mainLoop.scheduler=function(){Browser.requestAnimationFrame(Browser.mainLoop.runner)},Browser.mainLoop.method="rAF";else if(2==e){if(!window.setImmediate){var n=[];window.addEventListener("message",(function(e){e.source===window&&"setimmediate"===e.data&&(e.stopPropagation(),n.shift()())}),!0),window.setImmediate=function(e){n.push(e),ENVIRONMENT_IS_WORKER?(void 0===Module.setImmediates&&(Module.setImmediates=[]),Module.setImmediates.push(e),window.postMessage({target:"setimmediate"})):window.postMessage("setimmediate","*")}}Browser.mainLoop.scheduler=function(){window.setImmediate(Browser.mainLoop.runner)},Browser.mainLoop.method="immediate"}return 0}function _emscripten_get_now(){abort()}function _emscripten_set_main_loop(e,t,n,r,i){var o;Module.noExitRuntime=!0,assert(!Browser.mainLoop.func,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters."),Browser.mainLoop.func=e,Browser.mainLoop.arg=r,o=void 0!==r?function(){Module.dynCall_vi(e,r)}:function(){Module.dynCall_v(e)};var u=Browser.mainLoop.currentlyRunningMainloop;if(Browser.mainLoop.runner=function(){if(!ABORT)if(Browser.mainLoop.queue.length>0){var e=Date.now(),t=Browser.mainLoop.queue.shift();if(t.func(t.arg),Browser.mainLoop.remainingBlockers){var n=Browser.mainLoop.remainingBlockers,r=n%1==0?n-1:Math.floor(n);t.counted?Browser.mainLoop.remainingBlockers=r:(r+=.5,Browser.mainLoop.remainingBlockers=(8*n+r)/9)}if(console.log('main loop blocker "'+t.name+'" took '+(Date.now()-e)+" ms"),Browser.mainLoop.updateStatus(),u1&&Browser.mainLoop.currentFrameNumber%Browser.mainLoop.timingValue!=0?Browser.mainLoop.scheduler():(0==Browser.mainLoop.timingMode&&(Browser.mainLoop.tickStartTime=_emscripten_get_now()),"timeout"===Browser.mainLoop.method&&Module.ctx&&(Module.printErr("Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!"),Browser.mainLoop.method=""),Browser.mainLoop.runIter(o),u0?_emscripten_set_main_loop_timing(0,1e3/t):_emscripten_set_main_loop_timing(1,1),Browser.mainLoop.scheduler()),n)throw"SimulateInfiniteLoop"}var Browser={mainLoop:{scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause:function(){Browser.mainLoop.scheduler=null,Browser.mainLoop.currentlyRunningMainloop++},resume:function(){Browser.mainLoop.currentlyRunningMainloop++;var e=Browser.mainLoop.timingMode,t=Browser.mainLoop.timingValue,n=Browser.mainLoop.func;Browser.mainLoop.func=null,_emscripten_set_main_loop(n,0,!1,Browser.mainLoop.arg,!0),_emscripten_set_main_loop_timing(e,t),Browser.mainLoop.scheduler()},updateStatus:function(){if(Module.setStatus){var e=Module.statusMessage||"Please wait...",t=Browser.mainLoop.remainingBlockers,n=Browser.mainLoop.expectedBlockers;t?t=6;){var u=r>>i-6&63;i-=6,n+=t[u]}return 2==i?(n+=t[(3&r)<<4],n+="=="):4==i&&(n+=t[(15&r)<<2],n+="="),n}(e),o(s))},s.src=l,Browser.safeSetTimeout((function(){o(s)}),1e4)}};Module.preloadPlugins.push(t);var n=Module.canvas;n&&(n.requestPointerLock=n.requestPointerLock||n.mozRequestPointerLock||n.webkitRequestPointerLock||n.msRequestPointerLock||function(){},n.exitPointerLock=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock||document.msExitPointerLock||function(){},n.exitPointerLock=n.exitPointerLock.bind(document),document.addEventListener("pointerlockchange",r,!1),document.addEventListener("mozpointerlockchange",r,!1),document.addEventListener("webkitpointerlockchange",r,!1),document.addEventListener("mspointerlockchange",r,!1),Module.elementPointerLock&&n.addEventListener("click",(function(e){!Browser.pointerLock&&Module.canvas.requestPointerLock&&(Module.canvas.requestPointerLock(),e.preventDefault())}),!1))}function r(){Browser.pointerLock=document.pointerLockElement===Module.canvas||document.mozPointerLockElement===Module.canvas||document.webkitPointerLockElement===Module.canvas||document.msPointerLockElement===Module.canvas}},createContext:function(e,t,n,r){if(t&&Module.ctx&&e==Module.canvas)return Module.ctx;var i,o;if(t){var u={antialias:!1,alpha:!1};if(r)for(var a in r)u[a]=r[a];(o=GL.createContext(e,u))&&(i=GL.getContext(o).GLctx)}else i=e.getContext("2d");return i?(n&&(t||assert("undefined"==typeof GLctx,"cannot set in module if GLctx is used, but we are a non-GL context that would replace it"),Module.ctx=i,t&&GL.makeContextCurrent(o),Module.useWebGL=t,Browser.moduleContextCreatedCallbacks.forEach((function(e){e()})),Browser.init()),i):null},destroyContext:function(e,t,n){},fullscreenHandlersInstalled:!1,lockPointer:void 0,resizeCanvas:void 0,requestFullscreen:function(e,t,n){Browser.lockPointer=e,Browser.resizeCanvas=t,Browser.vrDevice=n,void 0===Browser.lockPointer&&(Browser.lockPointer=!0),void 0===Browser.resizeCanvas&&(Browser.resizeCanvas=!1),void 0===Browser.vrDevice&&(Browser.vrDevice=null);var r=Module.canvas;function i(){Browser.isFullscreen=!1;var e=r.parentNode;(document.fullscreenElement||document.mozFullScreenElement||document.msFullscreenElement||document.webkitFullscreenElement||document.webkitCurrentFullScreenElement)===e?(r.exitFullscreen=document.exitFullscreen||document.cancelFullScreen||document.mozCancelFullScreen||document.msExitFullscreen||document.webkitCancelFullScreen||function(){},r.exitFullscreen=r.exitFullscreen.bind(document),Browser.lockPointer&&r.requestPointerLock(),Browser.isFullscreen=!0,Browser.resizeCanvas&&Browser.setFullscreenCanvasSize()):(e.parentNode.insertBefore(r,e),e.parentNode.removeChild(e),Browser.resizeCanvas&&Browser.setWindowedCanvasSize()),Module.onFullScreen&&Module.onFullScreen(Browser.isFullscreen),Module.onFullscreen&&Module.onFullscreen(Browser.isFullscreen),Browser.updateCanvasDimensions(r)}Browser.fullscreenHandlersInstalled||(Browser.fullscreenHandlersInstalled=!0,document.addEventListener("fullscreenchange",i,!1),document.addEventListener("mozfullscreenchange",i,!1),document.addEventListener("webkitfullscreenchange",i,!1),document.addEventListener("MSFullscreenChange",i,!1));var o=document.createElement("div");r.parentNode.insertBefore(o,r),o.appendChild(r),o.requestFullscreen=o.requestFullscreen||o.mozRequestFullScreen||o.msRequestFullscreen||(o.webkitRequestFullscreen?function(){o.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)}:null)||(o.webkitRequestFullScreen?function(){o.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}:null),n?o.requestFullscreen({vrDisplay:n}):o.requestFullscreen()},requestFullScreen:function(e,t,n){return Module.printErr("Browser.requestFullScreen() is deprecated. Please call Browser.requestFullscreen instead."),Browser.requestFullScreen=function(e,t,n){return Browser.requestFullscreen(e,t,n)},Browser.requestFullscreen(e,t,n)},nextRAF:0,fakeRequestAnimationFrame:function(e){var t=Date.now();if(0===Browser.nextRAF)Browser.nextRAF=t+1e3/60;else for(;t+2>=Browser.nextRAF;)Browser.nextRAF+=1e3/60;var n=Math.max(Browser.nextRAF-t,0);setTimeout(e,n)},requestAnimationFrame:function(e){"undefined"==typeof window?Browser.fakeRequestAnimationFrame(e):(window.requestAnimationFrame||(window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame||Browser.fakeRequestAnimationFrame),window.requestAnimationFrame(e))},safeCallback:function(e){return function(){if(!ABORT)return e.apply(null,arguments)}},allowAsyncCallbacks:!0,queuedAsyncCallbacks:[],pauseAsyncCallbacks:function(){Browser.allowAsyncCallbacks=!1},resumeAsyncCallbacks:function(){if(Browser.allowAsyncCallbacks=!0,Browser.queuedAsyncCallbacks.length>0){var e=Browser.queuedAsyncCallbacks;Browser.queuedAsyncCallbacks=[],e.forEach((function(e){e()}))}},safeRequestAnimationFrame:function(e){return Browser.requestAnimationFrame((function(){ABORT||(Browser.allowAsyncCallbacks?e():Browser.queuedAsyncCallbacks.push(e))}))},safeSetTimeout:function(e,t){return Module.noExitRuntime=!0,setTimeout((function(){ABORT||(Browser.allowAsyncCallbacks?e():Browser.queuedAsyncCallbacks.push(e))}),t)},safeSetInterval:function(e,t){return Module.noExitRuntime=!0,setInterval((function(){ABORT||Browser.allowAsyncCallbacks&&e()}),t)},getMimetype:function(e){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",bmp:"image/bmp",ogg:"audio/ogg",wav:"audio/wav",mp3:"audio/mpeg"}[e.substr(e.lastIndexOf(".")+1)]},getUserMedia:function(e){window.getUserMedia||(window.getUserMedia=navigator.getUserMedia||navigator.mozGetUserMedia),window.getUserMedia(e)},getMovementX:function(e){return e.movementX||e.mozMovementX||e.webkitMovementX||0},getMovementY:function(e){return e.movementY||e.mozMovementY||e.webkitMovementY||0},getMouseWheelDelta:function(e){var t=0;switch(e.type){case"DOMMouseScroll":t=e.detail;break;case"mousewheel":t=e.wheelDelta;break;case"wheel":t=e.deltaY;break;default:throw"unrecognized mouse wheel event: "+e.type}return t},mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:function(e){if(Browser.pointerLock)"mousemove"!=e.type&&"mozMovementX"in e?Browser.mouseMovementX=Browser.mouseMovementY=0:(Browser.mouseMovementX=Browser.getMovementX(e),Browser.mouseMovementY=Browser.getMovementY(e)),"undefined"!=typeof SDL?(Browser.mouseX=SDL.mouseX+Browser.mouseMovementX,Browser.mouseY=SDL.mouseY+Browser.mouseMovementY):(Browser.mouseX+=Browser.mouseMovementX,Browser.mouseY+=Browser.mouseMovementY);else{var t=Module.canvas.getBoundingClientRect(),n=Module.canvas.width,r=Module.canvas.height,i=void 0!==window.scrollX?window.scrollX:window.pageXOffset,o=void 0!==window.scrollY?window.scrollY:window.pageYOffset;if("touchstart"===e.type||"touchend"===e.type||"touchmove"===e.type){var u=e.touch;if(void 0===u)return;var a=u.pageX-(i+t.left),l=u.pageY-(o+t.top),s={x:a*=n/t.width,y:l*=r/t.height};if("touchstart"===e.type)Browser.lastTouches[u.identifier]=s,Browser.touches[u.identifier]=s;else if("touchend"===e.type||"touchmove"===e.type){var c=Browser.touches[u.identifier];c||(c=s),Browser.lastTouches[u.identifier]=c,Browser.touches[u.identifier]=s}return}var f=e.pageX-(i+t.left),d=e.pageY-(o+t.top);f*=n/t.width,d*=r/t.height,Browser.mouseMovementX=f-Browser.mouseX,Browser.mouseMovementY=d-Browser.mouseY,Browser.mouseX=f,Browser.mouseY=d}},asyncLoad:function(e,t,n,r){var i=r?"":getUniqueRunDependency("al "+e);Module.readAsync(e,(function(n){assert(n,'Loading data file "'+e+'" failed (no arrayBuffer).'),t(new Uint8Array(n)),i&&removeRunDependency(i)}),(function(t){if(!n)throw'Loading data file "'+e+'" failed.';n()})),i&&addRunDependency(i)},resizeListeners:[],updateResizeListeners:function(){var e=Module.canvas;Browser.resizeListeners.forEach((function(t){t(e.width,e.height)}))},setCanvasSize:function(e,t,n){var r=Module.canvas;Browser.updateCanvasDimensions(r,e,t),n||Browser.updateResizeListeners()},windowedWidth:0,windowedHeight:0,setFullscreenCanvasSize:function(){if("undefined"!=typeof SDL){var e=HEAPU32[SDL.screen+0*Runtime.QUANTUM_SIZE>>2];e|=8388608,HEAP32[SDL.screen+0*Runtime.QUANTUM_SIZE>>2]=e}Browser.updateResizeListeners()},setWindowedCanvasSize:function(){if("undefined"!=typeof SDL){var e=HEAPU32[SDL.screen+0*Runtime.QUANTUM_SIZE>>2];e&=-8388609,HEAP32[SDL.screen+0*Runtime.QUANTUM_SIZE>>2]=e}Browser.updateResizeListeners()},updateCanvasDimensions:function(e,t,n){t&&n?(e.widthNative=t,e.heightNative=n):(t=e.widthNative,n=e.heightNative);var r=t,i=n;if(Module.forcedAspectRatio&&Module.forcedAspectRatio>0&&(r/i>2]},getStr:function(){return Pointer_stringify(SYSCALLS.get())},get64:function(){var e=SYSCALLS.get(),t=SYSCALLS.get();return assert(e>=0?0===t:-1===t),e},getZero:function(){assert(0===SYSCALLS.get())}};function ___syscall6(e,t){SYSCALLS.varargs=t;try{var n=SYSCALLS.getStreamFromFD();return FS.close(n),0}catch(e){return"undefined"!=typeof FS&&e instanceof FS.ErrnoError||abort(e),-e.errno}}function ___syscall54(e,t){SYSCALLS.varargs=t;try{return 0}catch(e){return"undefined"!=typeof FS&&e instanceof FS.ErrnoError||abort(e),-e.errno}}function _typeModule(e){var t=[[0,1,"X"],[1,1,"const X"],[128,1,"X *"],[256,1,"X &"],[384,1,"X &&"],[512,1,"std::shared_ptr"],[640,1,"std::unique_ptr"],[5120,1,"std::vector"],[6144,2,"std::array"],[9216,-1,"std::function"]];function n(e,t,n,r,i,o){if(1==t){var u=896&r;128!=u&&256!=u&&384!=u||(e="X const")}return(o?n.replace("X",e).replace("Y",i):e.replace("X",n).replace("Y",i)).replace(/([*&]) (?=[*&])/g,"$1")}function r(e,t){var n=t.flags,r=896&n,i=15360&n;return t.name||1024!=i||(1==t.ptrSize?t.name=(16&n?"":(8&n?"un":"")+"signed ")+"char":t.name=(8&n?"u":"")+(32&n?"float":"int")+8*t.ptrSize+"_t"),8!=t.ptrSize||32&n||(i=64),2048==i&&(512==r||640==r?i=4096:r&&(i=3072)),e(i,t)}var i={Type:function(){function e(e){this.id=e.id,this.name=e.name,this.flags=e.flags,this.spec=e}return e.prototype.toString=function(){return this.name},e}(),getComplexType:function e(i,o,u,a,l,s,c,f){void 0===s&&(s="X"),void 0===f&&(f=1);var d=u(i);if(d)return d;var p,h=a(i),v=h.placeholderFlag,m=t[v];c&&m&&(s=n(c[2],c[0],s,m[0],"?",!0)),0==v&&(p="Unbound"),v>=10&&(p="Corrupt"),f>20&&(p="Deeply nested"),p&&function(e,t,n,r,i){throw new Error(e+" type "+n.replace("X",t+"?")+(r?" with flag "+r:"")+" in "+i)}(p,i,s,v,l||"?");var g,y=e(h.paramList[0],o,u,a,l,s,m,f+1),_={flags:m[0],id:i,name:"",paramList:[y]},b=[],w="?";switch(h.placeholderFlag){case 1:g=y.spec;break;case 2:if(1024==(15360&y.flags)&&1==y.spec.ptrSize){_.flags=7168;break}case 3:case 6:case 5:g=y.spec,y.flags;break;case 8:w=""+h.paramList[1],_.paramList.push(h.paramList[1]);break;case 9:for(var E=0,D=h.paramList[1];E>2]=e),e}function _llvm_stacksave(){var e=_llvm_stacksave;return e.LLVM_SAVEDSTACKS||(e.LLVM_SAVEDSTACKS=[]),e.LLVM_SAVEDSTACKS.push(Runtime.stackSave()),e.LLVM_SAVEDSTACKS.length-1}function ___syscall140(e,t){SYSCALLS.varargs=t;try{var n=SYSCALLS.getStreamFromFD(),r=(SYSCALLS.get(),SYSCALLS.get()),i=SYSCALLS.get(),o=SYSCALLS.get(),u=r;return FS.llseek(n,u,o),HEAP32[i>>2]=n.position,n.getdents&&0===u&&0===o&&(n.getdents=null),0}catch(e){return"undefined"!=typeof FS&&e instanceof FS.ErrnoError||abort(e),-e.errno}}function ___syscall146(e,t){SYSCALLS.varargs=t;try{var n=SYSCALLS.get(),r=SYSCALLS.get(),i=SYSCALLS.get(),o=0;___syscall146.buffer||(___syscall146.buffers=[null,[],[]],___syscall146.printChar=function(e,t){var n=___syscall146.buffers[e];assert(n),0===t||10===t?((1===e?Module.print:Module.printErr)(UTF8ArrayToString(n,0)),n.length=0):n.push(t)});for(var u=0;u>2],l=HEAP32[r+(8*u+4)>>2],s=0;se.pageSize/2||t>e.pageSize-n?_nbind.typeNameTbl.NBind.proto.lalloc(t):(HEAPU32[e.usedPtr]=n+t,e.rootPtr+n)},e.lreset=function(t,n){HEAPU32[e.pagePtr]?_nbind.typeNameTbl.NBind.proto.lreset(t,n):HEAPU32[e.usedPtr]=t},e}();function constructType(e,t){var n=new(10240==e?_nbind.makeTypeNameTbl[t.name]||_nbind.BindType:_nbind.makeTypeKindTbl[e])(t);return typeIdTbl[t.id]=n,_nbind.typeNameTbl[t.name]=n,n}function getType(e){return typeIdTbl[e]}function queryType(e){var t=HEAPU8[e],n=_nbind.structureList[t][1];e/=4,n<0&&(++e,n=HEAPU32[e]+1);var r=Array.prototype.slice.call(HEAPU32.subarray(e+1,e+1+n));return 9==t&&(r=[r[0],r.slice(1)]),{paramList:r,placeholderFlag:t}}function getTypes(e,t){return e.map((function(e){return"number"==typeof e?_nbind.getComplexType(e,constructType,getType,queryType,t):_nbind.typeNameTbl[e]}))}function readTypeIdList(e,t){return Array.prototype.slice.call(HEAPU32,e/4,e/4+t)}function readAsciiString(e){for(var t=e;HEAPU8[t++];);return String.fromCharCode.apply("",HEAPU8.subarray(e,t-1))}function readPolicyList(e){var t={};if(e)for(;;){var n=HEAPU32[e/4];if(!n)break;t[readAsciiString(n)]=!0,e+=4}return t}function getDynCall(e,t){var n={float32_t:"d",float64_t:"d",int64_t:"d",uint64_t:"d",void:"v"},r=e.map((function(e){return n[e.name]||"i"})).join(""),i=Module["dynCall_"+r];if(!i)throw new Error("dynCall_"+r+" not found for "+t+"("+e.map((function(e){return e.name})).join(", ")+")");return i}function addMethod(e,t,n,r){var i=e[t];e.hasOwnProperty(t)&&i?((i.arity||0===i.arity)&&(i=_nbind.makeOverloader(i,i.arity),e[t]=i),i.addMethod(n,r)):(n.arity=r,e[t]=n)}function throwError(e){throw new Error(e)}_nbind.Pool=Pool,_nbind.constructType=constructType,_nbind.getType=getType,_nbind.queryType=queryType,_nbind.getTypes=getTypes,_nbind.readTypeIdList=readTypeIdList,_nbind.readAsciiString=readAsciiString,_nbind.readPolicyList=readPolicyList,_nbind.getDynCall=getDynCall,_nbind.addMethod=addMethod,_nbind.throwError=throwError,_nbind.bigEndian=!1,_a=_typeModule(_typeModule),_nbind.Type=_a.Type,_nbind.makeType=_a.makeType,_nbind.getComplexType=_a.getComplexType,_nbind.structureList=_a.structureList;var BindType=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.heap=HEAPU32,t.ptrSize=4,t}return __extends(t,e),t.prototype.needsWireRead=function(e){return!!this.wireRead||!!this.makeWireRead},t.prototype.needsWireWrite=function(e){return!!this.wireWrite||!!this.makeWireWrite},t}(_nbind.Type);_nbind.BindType=BindType;var PrimitiveType=function(e){function t(t){var n=e.call(this,t)||this,r=32&t.flags?{32:HEAPF32,64:HEAPF64}:8&t.flags?{8:HEAPU8,16:HEAPU16,32:HEAPU32}:{8:HEAP8,16:HEAP16,32:HEAP32};return n.heap=r[8*t.ptrSize],n.ptrSize=t.ptrSize,n}return __extends(t,e),t.prototype.needsWireWrite=function(e){return!!e&&!!e.Strict},t.prototype.makeWireWrite=function(e,t){return t&&t.Strict&&function(e){if("number"==typeof e)return e;throw new Error("Type mismatch")}},t}(BindType);function pushCString(e,t){if(null==e){if(t&&t.Nullable)return 0;throw new Error("Type mismatch")}if(t&&t.Strict){if("string"!=typeof e)throw new Error("Type mismatch")}else e=e.toString();var n=Module.lengthBytesUTF8(e)+1,r=_nbind.Pool.lalloc(n);return Module.stringToUTF8Array(e,HEAPU8,r,n),r}function popCString(e){return 0===e?null:Module.Pointer_stringify(e)}_nbind.PrimitiveType=PrimitiveType,_nbind.pushCString=pushCString,_nbind.popCString=popCString;var CStringType=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.wireRead=popCString,t.wireWrite=pushCString,t.readResources=[_nbind.resources.pool],t.writeResources=[_nbind.resources.pool],t}return __extends(t,e),t.prototype.makeWireWrite=function(e,t){return function(e){return pushCString(e,t)}},t}(BindType);_nbind.CStringType=CStringType;var BooleanType=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.wireRead=function(e){return!!e},t}return __extends(t,e),t.prototype.needsWireWrite=function(e){return!!e&&!!e.Strict},t.prototype.makeWireRead=function(e){return"!!("+e+")"},t.prototype.makeWireWrite=function(e,t){return t&&t.Strict&&function(e){if("boolean"==typeof e)return e;throw new Error("Type mismatch")}||e},t}(BindType);_nbind.BooleanType=BooleanType;var Wrapper=function(){function e(){}return e.prototype.persist=function(){this.__nbindState|=1},e}();function makeBound(e,t){var n=function(e){function n(t,r,i,o){var u=e.call(this)||this;if(!(u instanceof n))return new(Function.prototype.bind.apply(n,Array.prototype.concat.apply([null],arguments)));var a=r,l=i,s=o;if(t!==_nbind.ptrMarker){var c=u.__nbindConstructor.apply(u,arguments);a=4608,s=HEAPU32[c/4],l=HEAPU32[c/4+1]}var f={configurable:!0,enumerable:!1,value:null,writable:!1},d={__nbindFlags:a,__nbindPtr:l};s&&(d.__nbindShared=s,_nbind.mark(u));for(var p=0,h=Object.keys(d);p>=1;var n=_nbind.valueList[e];return _nbind.valueList[e]=firstFreeValue,firstFreeValue=e,n}if(t)return _nbind.popShared(e,t);throw new Error("Invalid value slot "+e)}_nbind.pushValue=pushValue,_nbind.popValue=popValue;var valueBase=0x10000000000000000;function push64(e){return"number"==typeof e?e:4096*pushValue(e)+valueBase}function pop64(e){return e=3?Buffer.from(o):new Buffer(o)).copy(r):getBuffer(r).set(o)}}_nbind.BufferType=BufferType,_nbind.commitBuffer=commitBuffer;var dirtyList=[],gcTimer=0;function sweep(){for(var e=0,t=dirtyList;e>2]=DYNAMIC_BASE,staticSealed=!0,Module.asmGlobalArg={Math,Int8Array,Int16Array,Int32Array,Uint8Array,Uint16Array,Uint32Array,Float32Array,Float64Array,NaN:NaN,Infinity:1/0},Module.asmLibraryArg={abort,assert,enlargeMemory,getTotalMemory,abortOnCannotGrowMemory,invoke_viiiii,invoke_vif,invoke_vid,invoke_fiff,invoke_vi,invoke_vii,invoke_ii,invoke_viddi,invoke_vidd,invoke_iiii,invoke_diii,invoke_di,invoke_iid,invoke_iii,invoke_viiddi,invoke_viiiiii,invoke_dii,invoke_i,invoke_iiiiii,invoke_viiid,invoke_viififi,invoke_viii,invoke_v,invoke_viid,invoke_idd,invoke_viiii,_emscripten_asm_const_iiiii,_emscripten_asm_const_iiidddddd,_emscripten_asm_const_iiiid,__nbind_reference_external,_emscripten_asm_const_iiiiiiii,_removeAccessorPrefix,_typeModule,__nbind_register_pool,__decorate,_llvm_stackrestore,___cxa_atexit,__extends,__nbind_get_value_object,__ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj,_emscripten_set_main_loop_timing,__nbind_register_primitive,__nbind_register_type,_emscripten_memcpy_big,__nbind_register_function,___setErrNo,__nbind_register_class,__nbind_finish,_abort,_nbind_value,_llvm_stacksave,___syscall54,_defineHidden,_emscripten_set_main_loop,_emscripten_get_now,__nbind_register_callback_signature,_emscripten_asm_const_iiiiii,__nbind_free_external,_emscripten_asm_const_iiii,_emscripten_asm_const_iiididi,___syscall6,_atexit,___syscall140,___syscall146,DYNAMICTOP_PTR,tempDoublePtr,ABORT,STACKTOP,STACK_MAX,cttz_i8,___dso_handle};var asm=function(e,t,n){"use asm";var r=new e.Int8Array(n);var i=new e.Int16Array(n);var o=new e.Int32Array(n);var u=new e.Uint8Array(n);var a=new e.Uint16Array(n);var l=new e.Uint32Array(n);var s=new e.Float32Array(n);var c=new e.Float64Array(n);var f=t.DYNAMICTOP_PTR|0;var d=t.tempDoublePtr|0;var p=t.ABORT|0;var h=t.STACKTOP|0;var v=t.STACK_MAX|0;var m=t.cttz_i8|0;var g=t.___dso_handle|0;var y=0;var _=0;var b=0;var w=0;var E=e.NaN,D=e.Infinity;var S=0,C=0,k=0,T=0,x=0.0;var A=0;var O=e.Math.floor;var P=e.Math.abs;var I=e.Math.sqrt;var N=e.Math.pow;var M=e.Math.cos;var R=e.Math.sin;var F=e.Math.tan;var L=e.Math.acos;var B=e.Math.asin;var j=e.Math.atan;var U=e.Math.atan2;var z=e.Math.exp;var W=e.Math.log;var H=e.Math.ceil;var V=e.Math.imul;var q=e.Math.min;var G=e.Math.max;var $=e.Math.clz32;var Y=e.Math.fround;var K=t.abort;var X=t.assert;var Q=t.enlargeMemory;var J=t.getTotalMemory;var Z=t.abortOnCannotGrowMemory;var ee=t.invoke_viiiii;var te=t.invoke_vif;var ne=t.invoke_vid;var re=t.invoke_fiff;var ie=t.invoke_vi;var oe=t.invoke_vii;var ue=t.invoke_ii;var ae=t.invoke_viddi;var le=t.invoke_vidd;var se=t.invoke_iiii;var ce=t.invoke_diii;var fe=t.invoke_di;var de=t.invoke_iid;var pe=t.invoke_iii;var he=t.invoke_viiddi;var ve=t.invoke_viiiiii;var me=t.invoke_dii;var ge=t.invoke_i;var ye=t.invoke_iiiiii;var _e=t.invoke_viiid;var be=t.invoke_viififi;var we=t.invoke_viii;var Ee=t.invoke_v;var De=t.invoke_viid;var Se=t.invoke_idd;var Ce=t.invoke_viiii;var ke=t._emscripten_asm_const_iiiii;var Te=t._emscripten_asm_const_iiidddddd;var xe=t._emscripten_asm_const_iiiid;var Ae=t.__nbind_reference_external;var Oe=t._emscripten_asm_const_iiiiiiii;var Pe=t._removeAccessorPrefix;var Ie=t._typeModule;var Ne=t.__nbind_register_pool;var Me=t.__decorate;var Re=t._llvm_stackrestore;var Fe=t.___cxa_atexit;var Le=t.__extends;var Be=t.__nbind_get_value_object;var je=t.__ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj;var Ue=t._emscripten_set_main_loop_timing;var ze=t.__nbind_register_primitive;var We=t.__nbind_register_type;var He=t._emscripten_memcpy_big;var Ve=t.__nbind_register_function;var qe=t.___setErrNo;var Ge=t.__nbind_register_class;var $e=t.__nbind_finish;var Ye=t._abort;var Ke=t._nbind_value;var Xe=t._llvm_stacksave;var Qe=t.___syscall54;var Je=t._defineHidden;var Ze=t._emscripten_set_main_loop;var et=t._emscripten_get_now;var tt=t.__nbind_register_callback_signature;var nt=t._emscripten_asm_const_iiiiii;var rt=t.__nbind_free_external;var it=t._emscripten_asm_const_iiii;var ot=t._emscripten_asm_const_iiididi;var ut=t.___syscall6;var at=t._atexit;var lt=t.___syscall140;var st=t.___syscall146;var ct=Y(0);const ft=Y(0);function dt(e){e=e|0;var t=0;t=h;h=h+e|0;h=h+15&-16;return t|0}function pt(){return h|0}function ht(e){e=e|0;h=e}function vt(e,t){e=e|0;t=t|0;h=e;v=t}function mt(e,t){e=e|0;t=t|0;if(!y){y=e;_=t}}function gt(e){e=e|0;A=e}function yt(){return A|0}function _t(){var e=0,t=0;ix(8104,8,400)|0;ix(8504,408,540)|0;e=9044;t=e+44|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));r[9088]=0;r[9089]=1;o[2273]=0;o[2274]=948;o[2275]=948;Fe(17,8104,g|0)|0;return}function bt(e){e=e|0;qt(e+948|0);return}function wt(e){e=Y(e);return((Ii(e)|0)&2147483647)>>>0>2139095040|0}function Et(e,t,n){e=e|0;t=t|0;n=n|0;e:do{if(!(o[e+(t<<3)+4>>2]|0)){if((t|2|0)==3?o[e+60>>2]|0:0){e=e+56|0;break}switch(t|0){case 0:case 2:case 4:case 5:{if(o[e+52>>2]|0){e=e+48|0;break e}break}default:{}}if(!(o[e+68>>2]|0)){e=(t|1|0)==5?948:n;break}else{e=e+64|0;break}}else e=e+(t<<3)|0}while(0);return e|0}function Dt(e){e=e|0;var t=0;t=qk(1e3)|0;St(e,(t|0)!=0,2456);o[2276]=(o[2276]|0)+1;ix(t|0,8104,1e3)|0;if(r[e+2>>0]|0){o[t+4>>2]=2;o[t+12>>2]=4}o[t+976>>2]=e;return t|0}function St(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0;i=h;h=h+16|0;r=i;if(!t){o[r>>2]=n;Lr(e,5,3197,r)}h=i;return}function Ct(){return Dt(956)|0}function kt(e){e=e|0;var t=0;t=$T(1e3)|0;Tt(t,e);St(o[e+976>>2]|0,1,2456);o[2276]=(o[2276]|0)+1;o[t+944>>2]=0;return t|0}function Tt(e,t){e=e|0;t=t|0;var n=0;ix(e|0,t|0,948)|0;Ur(e+948|0,t+948|0);n=e+960|0;e=t+960|0;t=n+40|0;do{o[n>>2]=o[e>>2];n=n+4|0;e=e+4|0}while((n|0)<(t|0));return}function xt(e){e=e|0;var t=0,n=0,r=0,i=0;t=e+944|0;n=o[t>>2]|0;if(n|0){At(n+948|0,e)|0;o[t>>2]=0}n=Ot(e)|0;if(n|0){t=0;do{o[(Pt(e,t)|0)+944>>2]=0;t=t+1|0}while((t|0)!=(n|0))}n=e+948|0;r=o[n>>2]|0;i=e+952|0;t=o[i>>2]|0;if((t|0)!=(r|0))o[i>>2]=t+(~((t+-4-r|0)>>>2)<<2);It(n);Gk(e);o[2276]=(o[2276]|0)+-1;return}function At(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0;r=o[e>>2]|0;l=e+4|0;n=o[l>>2]|0;u=n;e:do{if((r|0)==(n|0)){i=r;a=4}else{e=r;while(1){if((o[e>>2]|0)==(t|0)){i=e;a=4;break e}e=e+4|0;if((e|0)==(n|0)){e=0;break}}}}while(0);if((a|0)==4)if((i|0)!=(n|0)){r=i+4|0;e=u-r|0;t=e>>2;if(t){sx(i|0,r|0,e|0)|0;n=o[l>>2]|0}e=i+(t<<2)|0;if((n|0)==(e|0))e=1;else{o[l>>2]=n+(~((n+-4-e|0)>>>2)<<2);e=1}}else e=0;return e|0}function Ot(e){e=e|0;return(o[e+952>>2]|0)-(o[e+948>>2]|0)>>2|0}function Pt(e,t){e=e|0;t=t|0;var n=0;n=o[e+948>>2]|0;if((o[e+952>>2]|0)-n>>2>>>0>t>>>0)e=o[n+(t<<2)>>2]|0;else e=0;return e|0}function It(e){e=e|0;var t=0,n=0,r=0,i=0;r=h;h=h+32|0;t=r;i=o[e>>2]|0;n=(o[e+4>>2]|0)-i|0;if(((o[e+8>>2]|0)-i|0)>>>0>n>>>0){i=n>>2;Ni(t,i,i,e+8|0);Mi(e,t);Ri(t)}h=r;return}function Nt(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0;c=Ot(e)|0;do{if(c|0){if((o[(Pt(e,0)|0)+944>>2]|0)==(e|0)){if(!(At(e+948|0,t)|0))break;ix(t+400|0,8504,540)|0;o[t+944>>2]=0;Vt(e);break}a=o[(o[e+976>>2]|0)+12>>2]|0;l=e+948|0;s=(a|0)==0;n=0;u=0;do{r=o[(o[l>>2]|0)+(u<<2)>>2]|0;if((r|0)==(t|0))Vt(e);else{i=kt(r)|0;o[(o[l>>2]|0)+(n<<2)>>2]=i;o[i+944>>2]=e;if(!s)RA[a&15](r,i,e,n);n=n+1|0}u=u+1|0}while((u|0)!=(c|0));if(n>>>0>>0){s=e+948|0;l=e+952|0;a=n;n=o[l>>2]|0;do{u=(o[s>>2]|0)+(a<<2)|0;r=u+4|0;i=n-r|0;t=i>>2;if(!t)i=n;else{sx(u|0,r|0,i|0)|0;n=o[l>>2]|0;i=n}r=u+(t<<2)|0;if((i|0)!=(r|0)){n=i+(~((i+-4-r|0)>>>2)<<2)|0;o[l>>2]=n}a=a+1|0}while((a|0)!=(c|0))}}}while(0);return}function Mt(e){e=e|0;var t=0,n=0,i=0,u=0;Rt(e,(Ot(e)|0)==0,2491);Rt(e,(o[e+944>>2]|0)==0,2545);t=e+948|0;n=o[t>>2]|0;i=e+952|0;u=o[i>>2]|0;if((u|0)!=(n|0))o[i>>2]=u+(~((u+-4-n|0)>>>2)<<2);It(t);t=e+976|0;n=o[t>>2]|0;ix(e|0,8104,1e3)|0;if(r[n+2>>0]|0){o[e+4>>2]=2;o[e+12>>2]=4}o[t>>2]=n;return}function Rt(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0;i=h;h=h+16|0;r=i;if(!t){o[r>>2]=n;Cr(e,5,3197,r)}h=i;return}function Ft(){return o[2276]|0}function Lt(){var e=0;e=qk(20)|0;Bt((e|0)!=0,2592);o[2277]=(o[2277]|0)+1;o[e>>2]=o[239];o[e+4>>2]=o[240];o[e+8>>2]=o[241];o[e+12>>2]=o[242];o[e+16>>2]=o[243];return e|0}function Bt(e,t){e=e|0;t=t|0;var n=0,r=0;r=h;h=h+16|0;n=r;if(!e){o[n>>2]=t;Cr(0,5,3197,n)}h=r;return}function jt(e){e=e|0;Gk(e);o[2277]=(o[2277]|0)+-1;return}function Ut(e,t){e=e|0;t=t|0;var n=0;if(!t){n=0;t=0}else{Rt(e,(Ot(e)|0)==0,2629);n=1}o[e+964>>2]=t;o[e+988>>2]=n;return}function zt(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;u=r+8|0;i=r+4|0;a=r;o[i>>2]=t;Rt(e,(o[t+944>>2]|0)==0,2709);Rt(e,(o[e+964>>2]|0)==0,2763);Wt(e);t=e+948|0;o[a>>2]=(o[t>>2]|0)+(n<<2);o[u>>2]=o[a>>2];Ht(t,u,i)|0;o[(o[i>>2]|0)+944>>2]=e;Vt(e);h=r;return}function Wt(e){e=e|0;var t=0,n=0,r=0,i=0,u=0,a=0,l=0;n=Ot(e)|0;if(n|0?(o[(Pt(e,0)|0)+944>>2]|0)!=(e|0):0){r=o[(o[e+976>>2]|0)+12>>2]|0;i=e+948|0;u=(r|0)==0;t=0;do{a=o[(o[i>>2]|0)+(t<<2)>>2]|0;l=kt(a)|0;o[(o[i>>2]|0)+(t<<2)>>2]=l;o[l+944>>2]=e;if(!u)RA[r&15](a,l,e,t);t=t+1|0}while((t|0)!=(n|0))}return}function Ht(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0,v=0,m=0,g=0,y=0,_=0;y=h;h=h+64|0;d=y+52|0;l=y+48|0;p=y+28|0;v=y+24|0;m=y+20|0;g=y;r=o[e>>2]|0;u=r;t=r+((o[t>>2]|0)-u>>2<<2)|0;r=e+4|0;i=o[r>>2]|0;a=e+8|0;do{if(i>>>0<(o[a>>2]|0)>>>0){if((t|0)==(i|0)){o[t>>2]=o[n>>2];o[r>>2]=(o[r>>2]|0)+4;break}Fi(e,t,i,t+4|0);if(t>>>0<=n>>>0)n=(o[r>>2]|0)>>>0>n>>>0?n+4|0:n;o[t>>2]=o[n>>2]}else{r=(i-u>>2)+1|0;i=Hr(e)|0;if(i>>>0>>0)UT(e);f=o[e>>2]|0;c=(o[a>>2]|0)-f|0;u=c>>1;Ni(g,c>>2>>>0>>1>>>0?u>>>0>>0?r:u:i,t-f>>2,e+8|0);f=g+8|0;r=o[f>>2]|0;u=g+12|0;c=o[u>>2]|0;a=c;s=r;do{if((r|0)==(c|0)){c=g+4|0;r=o[c>>2]|0;_=o[g>>2]|0;i=_;if(r>>>0<=_>>>0){r=a-i>>1;r=(r|0)==0?1:r;Ni(p,r,r>>>2,o[g+16>>2]|0);o[v>>2]=o[c>>2];o[m>>2]=o[f>>2];o[l>>2]=o[v>>2];o[d>>2]=o[m>>2];Bi(p,l,d);r=o[g>>2]|0;o[g>>2]=o[p>>2];o[p>>2]=r;r=p+4|0;_=o[c>>2]|0;o[c>>2]=o[r>>2];o[r>>2]=_;r=p+8|0;_=o[f>>2]|0;o[f>>2]=o[r>>2];o[r>>2]=_;r=p+12|0;_=o[u>>2]|0;o[u>>2]=o[r>>2];o[r>>2]=_;Ri(p);r=o[f>>2]|0;break}u=r;a=((u-i>>2)+1|0)/-2|0;l=r+(a<<2)|0;i=s-u|0;u=i>>2;if(u){sx(l|0,r|0,i|0)|0;r=o[c>>2]|0}_=l+(u<<2)|0;o[f>>2]=_;o[c>>2]=r+(a<<2);r=_}}while(0);o[r>>2]=o[n>>2];o[f>>2]=(o[f>>2]|0)+4;t=Li(e,g,t)|0;Ri(g)}}while(0);h=y;return t|0}function Vt(e){e=e|0;var t=0;do{t=e+984|0;if(r[t>>0]|0)break;r[t>>0]=1;s[e+504>>2]=Y(E);e=o[e+944>>2]|0}while((e|0)!=0);return}function qt(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-4-r|0)>>>2)<<2);KT(n)}return}function Gt(e){e=e|0;return o[e+944>>2]|0}function $t(e){e=e|0;Rt(e,(o[e+964>>2]|0)!=0,2832);Vt(e);return}function Yt(e){e=e|0;return(r[e+984>>0]|0)!=0|0}function Kt(e,t){e=e|0;t=t|0;if(iT(e,t,400)|0){ix(e|0,t|0,400)|0;Vt(e)}return}function Xt(e){e=e|0;var t=ft;t=Y(s[e+44>>2]);e=wt(t)|0;return Y(e?Y(0.0):t)}function Qt(e){e=e|0;var t=ft;t=Y(s[e+48>>2]);if(wt(t)|0)t=r[(o[e+976>>2]|0)+2>>0]|0?Y(1.0):Y(0.0);return Y(t)}function Jt(e,t){e=e|0;t=t|0;o[e+980>>2]=t;return}function Zt(e){e=e|0;return o[e+980>>2]|0}function en(e,t){e=e|0;t=t|0;var n=0;n=e+4|0;if((o[n>>2]|0)!=(t|0)){o[n>>2]=t;Vt(e)}return}function tn(e){e=e|0;return o[e+4>>2]|0}function nn(e,t){e=e|0;t=t|0;var n=0;n=e+8|0;if((o[n>>2]|0)!=(t|0)){o[n>>2]=t;Vt(e)}return}function rn(e){e=e|0;return o[e+8>>2]|0}function on(e,t){e=e|0;t=t|0;var n=0;n=e+12|0;if((o[n>>2]|0)!=(t|0)){o[n>>2]=t;Vt(e)}return}function un(e){e=e|0;return o[e+12>>2]|0}function an(e,t){e=e|0;t=t|0;var n=0;n=e+16|0;if((o[n>>2]|0)!=(t|0)){o[n>>2]=t;Vt(e)}return}function ln(e){e=e|0;return o[e+16>>2]|0}function sn(e,t){e=e|0;t=t|0;var n=0;n=e+20|0;if((o[n>>2]|0)!=(t|0)){o[n>>2]=t;Vt(e)}return}function cn(e){e=e|0;return o[e+20>>2]|0}function fn(e,t){e=e|0;t=t|0;var n=0;n=e+24|0;if((o[n>>2]|0)!=(t|0)){o[n>>2]=t;Vt(e)}return}function dn(e){e=e|0;return o[e+24>>2]|0}function pn(e,t){e=e|0;t=t|0;var n=0;n=e+28|0;if((o[n>>2]|0)!=(t|0)){o[n>>2]=t;Vt(e)}return}function hn(e){e=e|0;return o[e+28>>2]|0}function vn(e,t){e=e|0;t=t|0;var n=0;n=e+32|0;if((o[n>>2]|0)!=(t|0)){o[n>>2]=t;Vt(e)}return}function mn(e){e=e|0;return o[e+32>>2]|0}function gn(e,t){e=e|0;t=t|0;var n=0;n=e+36|0;if((o[n>>2]|0)!=(t|0)){o[n>>2]=t;Vt(e)}return}function yn(e){e=e|0;return o[e+36>>2]|0}function _n(e,t){e=e|0;t=Y(t);var n=0;n=e+40|0;if(Y(s[n>>2])!=t){s[n>>2]=t;Vt(e)}return}function bn(e,t){e=e|0;t=Y(t);var n=0;n=e+44|0;if(Y(s[n>>2])!=t){s[n>>2]=t;Vt(e)}return}function wn(e,t){e=e|0;t=Y(t);var n=0;n=e+48|0;if(Y(s[n>>2])!=t){s[n>>2]=t;Vt(e)}return}function En(e,t){e=e|0;t=Y(t);var n=0,r=0,i=0,u=0;u=wt(t)|0;n=(u^1)&1;r=e+52|0;i=e+56|0;if(!(u|Y(s[r>>2])==t?(o[i>>2]|0)==(n|0):0)){s[r>>2]=t;o[i>>2]=n;Vt(e)}return}function Dn(e,t){e=e|0;t=Y(t);var n=0,r=0;r=e+52|0;n=e+56|0;if(!(!(Y(s[r>>2])!=t)?(o[n>>2]|0)==2:0)){s[r>>2]=t;r=wt(t)|0;o[n>>2]=r?3:2;Vt(e)}return}function Sn(e,t){e=e|0;t=t|0;var n=0,r=0;r=t+52|0;n=o[r+4>>2]|0;t=e;o[t>>2]=o[r>>2];o[t+4>>2]=n;return}function Cn(e,t,n){e=e|0;t=t|0;n=Y(n);var r=0,i=0,u=0;u=wt(n)|0;r=(u^1)&1;i=e+132+(t<<3)|0;t=e+132+(t<<3)+4|0;if(!(u|Y(s[i>>2])==n?(o[t>>2]|0)==(r|0):0)){s[i>>2]=n;o[t>>2]=r;Vt(e)}return}function kn(e,t,n){e=e|0;t=t|0;n=Y(n);var r=0,i=0,u=0;u=wt(n)|0;r=u?0:2;i=e+132+(t<<3)|0;t=e+132+(t<<3)+4|0;if(!(u|Y(s[i>>2])==n?(o[t>>2]|0)==(r|0):0)){s[i>>2]=n;o[t>>2]=r;Vt(e)}return}function Tn(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=t+132+(n<<3)|0;t=o[r+4>>2]|0;n=e;o[n>>2]=o[r>>2];o[n+4>>2]=t;return}function xn(e,t,n){e=e|0;t=t|0;n=Y(n);var r=0,i=0,u=0;u=wt(n)|0;r=(u^1)&1;i=e+60+(t<<3)|0;t=e+60+(t<<3)+4|0;if(!(u|Y(s[i>>2])==n?(o[t>>2]|0)==(r|0):0)){s[i>>2]=n;o[t>>2]=r;Vt(e)}return}function An(e,t,n){e=e|0;t=t|0;n=Y(n);var r=0,i=0,u=0;u=wt(n)|0;r=u?0:2;i=e+60+(t<<3)|0;t=e+60+(t<<3)+4|0;if(!(u|Y(s[i>>2])==n?(o[t>>2]|0)==(r|0):0)){s[i>>2]=n;o[t>>2]=r;Vt(e)}return}function On(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=t+60+(n<<3)|0;t=o[r+4>>2]|0;n=e;o[n>>2]=o[r>>2];o[n+4>>2]=t;return}function Pn(e,t){e=e|0;t=t|0;var n=0;n=e+60+(t<<3)+4|0;if((o[n>>2]|0)!=3){s[e+60+(t<<3)>>2]=Y(E);o[n>>2]=3;Vt(e)}return}function In(e,t,n){e=e|0;t=t|0;n=Y(n);var r=0,i=0,u=0;u=wt(n)|0;r=(u^1)&1;i=e+204+(t<<3)|0;t=e+204+(t<<3)+4|0;if(!(u|Y(s[i>>2])==n?(o[t>>2]|0)==(r|0):0)){s[i>>2]=n;o[t>>2]=r;Vt(e)}return}function Nn(e,t,n){e=e|0;t=t|0;n=Y(n);var r=0,i=0,u=0;u=wt(n)|0;r=u?0:2;i=e+204+(t<<3)|0;t=e+204+(t<<3)+4|0;if(!(u|Y(s[i>>2])==n?(o[t>>2]|0)==(r|0):0)){s[i>>2]=n;o[t>>2]=r;Vt(e)}return}function Mn(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=t+204+(n<<3)|0;t=o[r+4>>2]|0;n=e;o[n>>2]=o[r>>2];o[n+4>>2]=t;return}function Rn(e,t,n){e=e|0;t=t|0;n=Y(n);var r=0,i=0,u=0;u=wt(n)|0;r=(u^1)&1;i=e+276+(t<<3)|0;t=e+276+(t<<3)+4|0;if(!(u|Y(s[i>>2])==n?(o[t>>2]|0)==(r|0):0)){s[i>>2]=n;o[t>>2]=r;Vt(e)}return}function Fn(e,t){e=e|0;t=t|0;return Y(s[e+276+(t<<3)>>2])}function Ln(e,t){e=e|0;t=Y(t);var n=0,r=0,i=0,u=0;u=wt(t)|0;n=(u^1)&1;r=e+348|0;i=e+352|0;if(!(u|Y(s[r>>2])==t?(o[i>>2]|0)==(n|0):0)){s[r>>2]=t;o[i>>2]=n;Vt(e)}return}function Bn(e,t){e=e|0;t=Y(t);var n=0,r=0;r=e+348|0;n=e+352|0;if(!(!(Y(s[r>>2])!=t)?(o[n>>2]|0)==2:0)){s[r>>2]=t;r=wt(t)|0;o[n>>2]=r?3:2;Vt(e)}return}function jn(e){e=e|0;var t=0;t=e+352|0;if((o[t>>2]|0)!=3){s[e+348>>2]=Y(E);o[t>>2]=3;Vt(e)}return}function Un(e,t){e=e|0;t=t|0;var n=0,r=0;r=t+348|0;n=o[r+4>>2]|0;t=e;o[t>>2]=o[r>>2];o[t+4>>2]=n;return}function zn(e,t){e=e|0;t=Y(t);var n=0,r=0,i=0,u=0;u=wt(t)|0;n=(u^1)&1;r=e+356|0;i=e+360|0;if(!(u|Y(s[r>>2])==t?(o[i>>2]|0)==(n|0):0)){s[r>>2]=t;o[i>>2]=n;Vt(e)}return}function Wn(e,t){e=e|0;t=Y(t);var n=0,r=0;r=e+356|0;n=e+360|0;if(!(!(Y(s[r>>2])!=t)?(o[n>>2]|0)==2:0)){s[r>>2]=t;r=wt(t)|0;o[n>>2]=r?3:2;Vt(e)}return}function Hn(e){e=e|0;var t=0;t=e+360|0;if((o[t>>2]|0)!=3){s[e+356>>2]=Y(E);o[t>>2]=3;Vt(e)}return}function Vn(e,t){e=e|0;t=t|0;var n=0,r=0;r=t+356|0;n=o[r+4>>2]|0;t=e;o[t>>2]=o[r>>2];o[t+4>>2]=n;return}function qn(e,t){e=e|0;t=Y(t);var n=0,r=0,i=0,u=0;u=wt(t)|0;n=(u^1)&1;r=e+364|0;i=e+368|0;if(!(u|Y(s[r>>2])==t?(o[i>>2]|0)==(n|0):0)){s[r>>2]=t;o[i>>2]=n;Vt(e)}return}function Gn(e,t){e=e|0;t=Y(t);var n=0,r=0,i=0,u=0;u=wt(t)|0;n=u?0:2;r=e+364|0;i=e+368|0;if(!(u|Y(s[r>>2])==t?(o[i>>2]|0)==(n|0):0)){s[r>>2]=t;o[i>>2]=n;Vt(e)}return}function $n(e,t){e=e|0;t=t|0;var n=0,r=0;r=t+364|0;n=o[r+4>>2]|0;t=e;o[t>>2]=o[r>>2];o[t+4>>2]=n;return}function Yn(e,t){e=e|0;t=Y(t);var n=0,r=0,i=0,u=0;u=wt(t)|0;n=(u^1)&1;r=e+372|0;i=e+376|0;if(!(u|Y(s[r>>2])==t?(o[i>>2]|0)==(n|0):0)){s[r>>2]=t;o[i>>2]=n;Vt(e)}return}function Kn(e,t){e=e|0;t=Y(t);var n=0,r=0,i=0,u=0;u=wt(t)|0;n=u?0:2;r=e+372|0;i=e+376|0;if(!(u|Y(s[r>>2])==t?(o[i>>2]|0)==(n|0):0)){s[r>>2]=t;o[i>>2]=n;Vt(e)}return}function Xn(e,t){e=e|0;t=t|0;var n=0,r=0;r=t+372|0;n=o[r+4>>2]|0;t=e;o[t>>2]=o[r>>2];o[t+4>>2]=n;return}function Qn(e,t){e=e|0;t=Y(t);var n=0,r=0,i=0,u=0;u=wt(t)|0;n=(u^1)&1;r=e+380|0;i=e+384|0;if(!(u|Y(s[r>>2])==t?(o[i>>2]|0)==(n|0):0)){s[r>>2]=t;o[i>>2]=n;Vt(e)}return}function Jn(e,t){e=e|0;t=Y(t);var n=0,r=0,i=0,u=0;u=wt(t)|0;n=u?0:2;r=e+380|0;i=e+384|0;if(!(u|Y(s[r>>2])==t?(o[i>>2]|0)==(n|0):0)){s[r>>2]=t;o[i>>2]=n;Vt(e)}return}function Zn(e,t){e=e|0;t=t|0;var n=0,r=0;r=t+380|0;n=o[r+4>>2]|0;t=e;o[t>>2]=o[r>>2];o[t+4>>2]=n;return}function er(e,t){e=e|0;t=Y(t);var n=0,r=0,i=0,u=0;u=wt(t)|0;n=(u^1)&1;r=e+388|0;i=e+392|0;if(!(u|Y(s[r>>2])==t?(o[i>>2]|0)==(n|0):0)){s[r>>2]=t;o[i>>2]=n;Vt(e)}return}function tr(e,t){e=e|0;t=Y(t);var n=0,r=0,i=0,u=0;u=wt(t)|0;n=u?0:2;r=e+388|0;i=e+392|0;if(!(u|Y(s[r>>2])==t?(o[i>>2]|0)==(n|0):0)){s[r>>2]=t;o[i>>2]=n;Vt(e)}return}function nr(e,t){e=e|0;t=t|0;var n=0,r=0;r=t+388|0;n=o[r+4>>2]|0;t=e;o[t>>2]=o[r>>2];o[t+4>>2]=n;return}function rr(e,t){e=e|0;t=Y(t);var n=0;n=e+396|0;if(Y(s[n>>2])!=t){s[n>>2]=t;Vt(e)}return}function ir(e){e=e|0;return Y(s[e+396>>2])}function or(e){e=e|0;return Y(s[e+400>>2])}function ur(e){e=e|0;return Y(s[e+404>>2])}function ar(e){e=e|0;return Y(s[e+408>>2])}function lr(e){e=e|0;return Y(s[e+412>>2])}function sr(e){e=e|0;return Y(s[e+416>>2])}function cr(e){e=e|0;return Y(s[e+420>>2])}function fr(e,t){e=e|0;t=t|0;Rt(e,(t|0)<6,2918);switch(t|0){case 0:{t=(o[e+496>>2]|0)==2?5:4;break}case 2:{t=(o[e+496>>2]|0)==2?4:5;break}default:{}}return Y(s[e+424+(t<<2)>>2])}function dr(e,t){e=e|0;t=t|0;Rt(e,(t|0)<6,2918);switch(t|0){case 0:{t=(o[e+496>>2]|0)==2?5:4;break}case 2:{t=(o[e+496>>2]|0)==2?4:5;break}default:{}}return Y(s[e+448+(t<<2)>>2])}function pr(e,t){e=e|0;t=t|0;Rt(e,(t|0)<6,2918);switch(t|0){case 0:{t=(o[e+496>>2]|0)==2?5:4;break}case 2:{t=(o[e+496>>2]|0)==2?4:5;break}default:{}}return Y(s[e+472+(t<<2)>>2])}function hr(e,t){e=e|0;t=t|0;var n=0,r=ft;n=o[e+4>>2]|0;if((n|0)==(o[t+4>>2]|0)){if(!n)e=1;else{r=Y(s[e>>2]);e=Y(P(Y(r-Y(s[t>>2]))))>2]=0;o[i+4>>2]=0;o[i+8>>2]=0;je(i|0,e|0,t|0,0);Cr(e,3,(r[i+11>>0]|0)<0?o[i>>2]|0:i,n);XT(i);h=n;return}function yr(e,t,n,r){e=Y(e);t=Y(t);n=n|0;r=r|0;var i=ft;e=Y(e*t);i=Y(LT(e,Y(1.0)));do{if(!(vr(i,Y(0.0))|0)){e=Y(e-i);if(vr(i,Y(1.0))|0){e=Y(e+Y(1.0));break}if(n){e=Y(e+Y(1.0));break}if(!r){if(i>Y(.5))i=Y(1.0);else{r=vr(i,Y(.5))|0;i=r?Y(1.0):Y(0.0)}e=Y(e+i)}}else e=Y(e-i)}while(0);return Y(e/t)}function _r(e,t,n,r,i,o,u,a,l,c,f,d,p){e=e|0;t=Y(t);n=n|0;r=Y(r);i=i|0;o=Y(o);u=u|0;a=Y(a);l=Y(l);c=Y(c);f=Y(f);d=Y(d);p=p|0;var h=0,v=ft,m=ft,g=ft,y=ft,_=ft,b=ft;if(l>2]),v!=Y(0.0)):0){g=Y(yr(t,v,0,0));y=Y(yr(r,v,0,0));m=Y(yr(o,v,0,0));v=Y(yr(a,v,0,0))}else{m=o;g=t;v=a;y=r}if((i|0)==(e|0))h=vr(m,g)|0;else h=0;if((u|0)==(n|0))p=vr(v,y)|0;else p=0;if((!h?(_=Y(t-f),!(br(e,_,l)|0)):0)?!(wr(e,_,i,l)|0):0)h=Er(e,_,i,o,l)|0;else h=1;if((!p?(b=Y(r-d),!(br(n,b,c)|0)):0)?!(wr(n,b,u,c)|0):0)p=Er(n,b,u,a,c)|0;else p=1;p=h&p}return p|0}function br(e,t,n){e=e|0;t=Y(t);n=Y(n);if((e|0)==1)e=vr(t,n)|0;else e=0;return e|0}function wr(e,t,n,r){e=e|0;t=Y(t);n=n|0;r=Y(r);if((e|0)==2&(n|0)==0){if(!(t>=r))e=vr(t,r)|0;else e=1}else e=0;return e|0}function Er(e,t,n,r,i){e=e|0;t=Y(t);n=n|0;r=Y(r);i=Y(i);if((e|0)==2&(n|0)==2&r>t){if(!(i<=t))e=vr(t,i)|0;else e=1}else e=0;return e|0}function Dr(e,t,n,i,u,a,l,f,d,p,v){e=e|0;t=Y(t);n=Y(n);i=i|0;u=u|0;a=a|0;l=Y(l);f=Y(f);d=d|0;p=p|0;v=v|0;var m=0,g=0,y=0,_=0,b=ft,w=ft,E=0,D=0,S=0,C=0,k=0,T=0,x=0,A=0,O=0,P=0,I=0,N=ft,M=ft,R=ft,F=0.0,L=0.0;I=h;h=h+160|0;A=I+152|0;x=I+120|0;T=I+104|0;S=I+72|0;_=I+56|0;k=I+8|0;D=I;C=(o[2279]|0)+1|0;o[2279]=C;O=e+984|0;if((r[O>>0]|0)!=0?(o[e+512>>2]|0)!=(o[2278]|0):0)E=4;else if((o[e+516>>2]|0)==(i|0))P=0;else E=4;if((E|0)==4){o[e+520>>2]=0;o[e+924>>2]=-1;o[e+928>>2]=-1;s[e+932>>2]=Y(-1.0);s[e+936>>2]=Y(-1.0);P=1}e:do{if(!(o[e+964>>2]|0)){if(d){m=e+916|0;if(!(vr(Y(s[m>>2]),t)|0)){E=21;break}if(!(vr(Y(s[e+920>>2]),n)|0)){E=21;break}if((o[e+924>>2]|0)!=(u|0)){E=21;break}m=(o[e+928>>2]|0)==(a|0)?m:0;E=22;break}y=o[e+520>>2]|0;if(!y)E=21;else{g=0;while(1){m=e+524+(g*24|0)|0;if(((vr(Y(s[m>>2]),t)|0?vr(Y(s[e+524+(g*24|0)+4>>2]),n)|0:0)?(o[e+524+(g*24|0)+8>>2]|0)==(u|0):0)?(o[e+524+(g*24|0)+12>>2]|0)==(a|0):0){E=22;break e}g=g+1|0;if(g>>>0>=y>>>0){E=21;break}}}}else{b=Y(Sr(e,2,l));w=Y(Sr(e,0,l));m=e+916|0;R=Y(s[m>>2]);M=Y(s[e+920>>2]);N=Y(s[e+932>>2]);if(!(_r(u,t,a,n,o[e+924>>2]|0,R,o[e+928>>2]|0,M,N,Y(s[e+936>>2]),b,w,v)|0)){y=o[e+520>>2]|0;if(!y)E=21;else{g=0;while(1){m=e+524+(g*24|0)|0;N=Y(s[m>>2]);M=Y(s[e+524+(g*24|0)+4>>2]);R=Y(s[e+524+(g*24|0)+16>>2]);if(_r(u,t,a,n,o[e+524+(g*24|0)+8>>2]|0,N,o[e+524+(g*24|0)+12>>2]|0,M,R,Y(s[e+524+(g*24|0)+20>>2]),b,w,v)|0){E=22;break e}g=g+1|0;if(g>>>0>=y>>>0){E=21;break}}}}else E=22}}while(0);do{if((E|0)==21){if(!(r[11697]|0)){m=0;E=31}else{m=0;E=28}}else if((E|0)==22){g=(r[11697]|0)!=0;if(!((m|0)!=0&(P^1)))if(g){E=28;break}else{E=31;break}_=m+16|0;o[e+908>>2]=o[_>>2];y=m+20|0;o[e+912>>2]=o[y>>2];if(!((r[11698]|0)==0|g^1)){o[D>>2]=kr(C)|0;o[D+4>>2]=C;Cr(e,4,2972,D);g=o[e+972>>2]|0;if(g|0)hA[g&127](e);u=Tr(u,d)|0;a=Tr(a,d)|0;L=+Y(s[_>>2]);F=+Y(s[y>>2]);o[k>>2]=u;o[k+4>>2]=a;c[k+8>>3]=+t;c[k+16>>3]=+n;c[k+24>>3]=L;c[k+32>>3]=F;o[k+40>>2]=p;Cr(e,4,2989,k)}}}while(0);if((E|0)==28){g=kr(C)|0;o[_>>2]=g;o[_+4>>2]=C;o[_+8>>2]=P?3047:11699;Cr(e,4,3038,_);g=o[e+972>>2]|0;if(g|0)hA[g&127](e);k=Tr(u,d)|0;E=Tr(a,d)|0;o[S>>2]=k;o[S+4>>2]=E;c[S+8>>3]=+t;c[S+16>>3]=+n;o[S+24>>2]=p;Cr(e,4,3049,S);E=31}if((E|0)==31){xr(e,t,n,i,u,a,l,f,d,v);if(r[11697]|0){g=o[2279]|0;k=kr(g)|0;o[T>>2]=k;o[T+4>>2]=g;o[T+8>>2]=P?3047:11699;Cr(e,4,3083,T);g=o[e+972>>2]|0;if(g|0)hA[g&127](e);k=Tr(u,d)|0;T=Tr(a,d)|0;F=+Y(s[e+908>>2]);L=+Y(s[e+912>>2]);o[x>>2]=k;o[x+4>>2]=T;c[x+8>>3]=F;c[x+16>>3]=L;o[x+24>>2]=p;Cr(e,4,3092,x)}o[e+516>>2]=i;if(!m){g=e+520|0;m=o[g>>2]|0;if((m|0)==16){if(r[11697]|0)Cr(e,4,3124,A);o[g>>2]=0;m=0}if(d)m=e+916|0;else{o[g>>2]=m+1;m=e+524+(m*24|0)|0}s[m>>2]=t;s[m+4>>2]=n;o[m+8>>2]=u;o[m+12>>2]=a;o[m+16>>2]=o[e+908>>2];o[m+20>>2]=o[e+912>>2];m=0}}if(d){o[e+416>>2]=o[e+908>>2];o[e+420>>2]=o[e+912>>2];r[e+985>>0]=1;r[O>>0]=0}o[2279]=(o[2279]|0)+-1;o[e+512>>2]=o[2278];h=I;return P|(m|0)==0|0}function Sr(e,t,n){e=e|0;t=t|0;n=Y(n);var r=ft;r=Y(Vr(e,t,n));return Y(r+Y(qr(e,t,n)))}function Cr(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0;u=h;h=h+16|0;i=u;o[i>>2]=r;if(!e)r=0;else r=o[e+976>>2]|0;Br(r,e,t,n,i);h=u;return}function kr(e){e=e|0;return(e>>>0>60?3201:3201+(60-e)|0)|0}function Tr(e,t){e=e|0;t=t|0;var n=0,r=0,i=0;i=h;h=h+32|0;n=i+12|0;r=i;o[n>>2]=o[254];o[n+4>>2]=o[255];o[n+8>>2]=o[256];o[r>>2]=o[257];o[r+4>>2]=o[258];o[r+8>>2]=o[259];if((e|0)>2)e=11699;else e=o[(t?r:n)+(e<<2)>>2]|0;h=i;return e|0}function xr(e,t,n,i,a,l,c,f,p,v){e=e|0;t=Y(t);n=Y(n);i=i|0;a=a|0;l=l|0;c=Y(c);f=Y(f);p=p|0;v=v|0;var m=0,g=0,y=0,_=0,b=ft,w=ft,E=ft,D=ft,S=ft,C=ft,k=ft,T=0,x=0,A=0,O=ft,P=ft,I=0,N=ft,M=0,R=0,F=0,L=0,B=0,j=0,U=0,z=0,W=0,H=0,V=0,q=0,G=0,$=0,K=0,X=0,Q=0,J=0,Z=ft,ee=ft,te=ft,ne=ft,re=ft,ie=0,oe=0,ue=0,ae=0,le=0,se=ft,ce=ft,fe=ft,de=ft,pe=ft,he=ft,ve=0,me=ft,ge=ft,ye=ft,_e=ft,be=ft,we=ft,Ee=0,De=0,Se=ft,Ce=ft,ke=0,Te=0,xe=0,Ae=0,Oe=ft,Pe=0,Ie=0,Ne=0,Me=0,Re=0,Fe=0,Le=0,Be=ft,je=0,Ue=0;Le=h;h=h+16|0;ie=Le+12|0;oe=Le+8|0;ue=Le+4|0;ae=Le;Rt(e,(a|0)==0|(wt(t)|0)^1,3326);Rt(e,(l|0)==0|(wt(n)|0)^1,3406);Ie=Yr(e,i)|0;o[e+496>>2]=Ie;Re=Kr(2,Ie)|0;Fe=Kr(0,Ie)|0;s[e+440>>2]=Y(Vr(e,Re,c));s[e+444>>2]=Y(qr(e,Re,c));s[e+428>>2]=Y(Vr(e,Fe,c));s[e+436>>2]=Y(qr(e,Fe,c));s[e+464>>2]=Y(Xr(e,Re));s[e+468>>2]=Y(Qr(e,Re));s[e+452>>2]=Y(Xr(e,Fe));s[e+460>>2]=Y(Qr(e,Fe));s[e+488>>2]=Y(Jr(e,Re,c));s[e+492>>2]=Y(Zr(e,Re,c));s[e+476>>2]=Y(Jr(e,Fe,c));s[e+484>>2]=Y(Zr(e,Fe,c));do{if(!(o[e+964>>2]|0)){Ne=e+948|0;Me=(o[e+952>>2]|0)-(o[Ne>>2]|0)>>2;if(!Me){ti(e,t,n,a,l,c,f);break}if(!p?ni(e,t,n,a,l,c,f)|0:0)break;Wt(e);X=e+508|0;r[X>>0]=0;Re=Kr(o[e+4>>2]|0,Ie)|0;Fe=ri(Re,Ie)|0;Pe=Gr(Re)|0;Q=o[e+8>>2]|0;Te=e+28|0;J=(o[Te>>2]|0)!=0;be=Pe?c:f;Se=Pe?f:c;Z=Y(ii(e,Re,c));ee=Y(oi(e,Re,c));b=Y(ii(e,Fe,c));we=Y(ui(e,Re,c));Ce=Y(ui(e,Fe,c));A=Pe?a:l;ke=Pe?l:a;Oe=Pe?we:Ce;S=Pe?Ce:we;_e=Y(Sr(e,2,c));D=Y(Sr(e,0,c));w=Y(Y(Nr(e+364|0,c))-Oe);E=Y(Y(Nr(e+380|0,c))-Oe);C=Y(Y(Nr(e+372|0,f))-S);k=Y(Y(Nr(e+388|0,f))-S);te=Pe?w:C;ne=Pe?E:k;_e=Y(t-_e);t=Y(_e-Oe);if(wt(t)|0)Oe=t;else Oe=Y(NT(Y(RT(t,E)),w));ge=Y(n-D);t=Y(ge-S);if(wt(t)|0)ye=t;else ye=Y(NT(Y(RT(t,k)),C));w=Pe?Oe:ye;me=Pe?ye:Oe;e:do{if((A|0)==1){i=0;g=0;while(1){m=Pt(e,g)|0;if(!i){if(Y(li(m))>Y(0.0)?Y(si(m))>Y(0.0):0)i=m;else i=0}else if(ai(m)|0){_=0;break e}g=g+1|0;if(g>>>0>=Me>>>0){_=i;break}}}else _=0}while(0);T=_+500|0;x=_+504|0;i=0;m=0;t=Y(0.0);y=0;do{g=o[(o[Ne>>2]|0)+(y<<2)>>2]|0;if((o[g+36>>2]|0)==1){ci(g);r[g+985>>0]=1;r[g+984>>0]=0}else{Pr(g);if(p)Mr(g,Yr(g,Ie)|0,w,me,Oe);do{if((o[g+24>>2]|0)!=1){if((g|0)==(_|0)){o[T>>2]=o[2278];s[x>>2]=Y(0.0);break}else{fi(e,g,Oe,a,ye,Oe,ye,l,Ie,v);break}}else{if(m|0)o[m+960>>2]=g;o[g+960>>2]=0;m=g;i=(i|0)==0?g:i}}while(0);he=Y(s[g+504>>2]);t=Y(t+Y(he+Y(Sr(g,Re,Oe))))}y=y+1|0}while((y|0)!=(Me|0));F=t>w;ve=J&((A|0)==2&F)?1:A;M=(ke|0)==1;B=M&(p^1);j=(ve|0)==1;U=(ve|0)==2;z=976+(Re<<2)|0;W=(ke|2|0)==2;$=M&(J^1);H=1040+(Fe<<2)|0;V=1040+(Re<<2)|0;q=976+(Fe<<2)|0;G=(ke|0)!=1;F=J&((A|0)!=0&F);R=e+976|0;M=M^1;t=w;I=0;L=0;he=Y(0.0);re=Y(0.0);while(1){e:do{if(I>>>0>>0){x=o[Ne>>2]|0;y=0;k=Y(0.0);C=Y(0.0);E=Y(0.0);w=Y(0.0);g=0;m=0;_=I;while(1){T=o[x+(_<<2)>>2]|0;if((o[T+36>>2]|0)!=1?(o[T+940>>2]=L,(o[T+24>>2]|0)!=1):0){D=Y(Sr(T,Re,Oe));K=o[z>>2]|0;n=Y(Nr(T+380+(K<<3)|0,be));S=Y(s[T+504>>2]);n=Y(RT(n,S));n=Y(NT(Y(Nr(T+364+(K<<3)|0,be)),n));if(J&(y|0)!=0&Y(D+Y(C+n))>t){l=y;D=k;A=_;break e}D=Y(D+n);n=Y(C+D);D=Y(k+D);if(ai(T)|0){E=Y(E+Y(li(T)));w=Y(w-Y(S*Y(si(T))))}if(m|0)o[m+960>>2]=T;o[T+960>>2]=0;y=y+1|0;m=T;g=(g|0)==0?T:g}else{D=k;n=C}_=_+1|0;if(_>>>0>>0){k=D;C=n}else{l=y;A=_;break}}}else{l=0;D=Y(0.0);E=Y(0.0);w=Y(0.0);g=0;A=I}}while(0);K=E>Y(0.0)&EY(0.0)&wne&((wt(ne)|0)^1))){if(!(r[(o[R>>2]|0)+3>>0]|0)){if(!(O==Y(0.0))?!(Y(li(e))==Y(0.0)):0){K=53;break}t=D;K=53}else K=51}else{t=ne;K=51}}else{t=te;K=51}}else K=51}while(0);if((K|0)==51){K=0;if(wt(t)|0)K=53;else{P=Y(t-D);N=t}}if((K|0)==53){K=0;if(D>2]|0;_=PY(0.0);C=Y(P/O);E=Y(0.0);D=Y(0.0);t=Y(0.0);m=g;do{n=Y(Nr(m+380+(y<<3)|0,be));w=Y(Nr(m+364+(y<<3)|0,be));w=Y(RT(n,Y(NT(w,Y(s[m+504>>2])))));if(_){n=Y(w*Y(si(m)));if(n!=Y(-0.0)?(Be=Y(w-Y(S*n)),se=Y(di(m,Re,Be,N,Oe)),Be!=se):0){E=Y(E-Y(se-w));t=Y(t+n)}}else if((T?(ce=Y(li(m)),ce!=Y(0.0)):0)?(Be=Y(w+Y(C*ce)),fe=Y(di(m,Re,Be,N,Oe)),Be!=fe):0){E=Y(E-Y(fe-w));D=Y(D-ce)}m=o[m+960>>2]|0}while((m|0)!=0);t=Y(k+t);w=Y(P+E);if(!le){S=Y(O+D);_=o[z>>2]|0;T=wY(0.0);S=Y(w/S);t=Y(0.0);do{Be=Y(Nr(g+380+(_<<3)|0,be));E=Y(Nr(g+364+(_<<3)|0,be));E=Y(RT(Be,Y(NT(E,Y(s[g+504>>2])))));if(T){Be=Y(E*Y(si(g)));w=Y(-Be);if(Be!=Y(-0.0)){Be=Y(C*w);w=Y(di(g,Re,Y(E+(x?w:Be)),N,Oe))}else w=E}else if(y?(de=Y(li(g)),de!=Y(0.0)):0)w=Y(di(g,Re,Y(E+Y(S*de)),N,Oe));else w=E;t=Y(t-Y(w-E));D=Y(Sr(g,Re,Oe));n=Y(Sr(g,Fe,Oe));w=Y(w+D);s[oe>>2]=w;o[ae>>2]=1;E=Y(s[g+396>>2]);e:do{if(wt(E)|0){m=wt(me)|0;do{if(!m){if(F|(Ir(g,Fe,me)|0|M))break;if((pi(e,g)|0)!=4)break;if((o[(hi(g,Fe)|0)+4>>2]|0)==3)break;if((o[(vi(g,Fe)|0)+4>>2]|0)==3)break;s[ie>>2]=me;o[ue>>2]=1;break e}}while(0);if(Ir(g,Fe,me)|0){m=o[g+992+(o[q>>2]<<2)>>2]|0;Be=Y(n+Y(Nr(m,me)));s[ie>>2]=Be;m=G&(o[m+4>>2]|0)==2;o[ue>>2]=((wt(Be)|0|m)^1)&1;break}else{s[ie>>2]=me;o[ue>>2]=m?0:2;break}}else{Be=Y(w-D);O=Y(Be/E);Be=Y(E*Be);o[ue>>2]=1;s[ie>>2]=Y(n+(Pe?O:Be))}}while(0);mi(g,Re,N,Oe,ae,oe);mi(g,Fe,me,Oe,ue,ie);do{if(!(Ir(g,Fe,me)|0)?(pi(e,g)|0)==4:0){if((o[(hi(g,Fe)|0)+4>>2]|0)==3){m=0;break}m=(o[(vi(g,Fe)|0)+4>>2]|0)!=3}else m=0}while(0);Be=Y(s[oe>>2]);O=Y(s[ie>>2]);je=o[ae>>2]|0;Ue=o[ue>>2]|0;Dr(g,Pe?Be:O,Pe?O:Be,Ie,Pe?je:Ue,Pe?Ue:je,Oe,ye,p&(m^1),3488,v)|0;r[X>>0]=r[X>>0]|r[g+508>>0];g=o[g+960>>2]|0}while((g|0)!=0)}else t=Y(0.0)}else t=Y(0.0);t=Y(P+t);Ue=t>0]=Ue|u[X>>0];if(U&t>Y(0.0)){m=o[z>>2]|0;if((o[e+364+(m<<3)+4>>2]|0)!=0?(pe=Y(Nr(e+364+(m<<3)|0,be)),pe>=Y(0.0)):0)w=Y(NT(Y(0.0),Y(pe-Y(N-t))));else w=Y(0.0)}else w=t;T=I>>>0>>0;if(T){_=o[Ne>>2]|0;y=I;m=0;do{g=o[_+(y<<2)>>2]|0;if(!(o[g+24>>2]|0)){m=((o[(hi(g,Re)|0)+4>>2]|0)==3&1)+m|0;m=m+((o[(vi(g,Re)|0)+4>>2]|0)==3&1)|0}y=y+1|0}while((y|0)!=(A|0));if(m){D=Y(0.0);n=Y(0.0)}else K=101}else K=101;e:do{if((K|0)==101){K=0;switch(Q|0){case 1:{m=0;D=Y(w*Y(.5));n=Y(0.0);break e}case 2:{m=0;D=w;n=Y(0.0);break e}case 3:{if(l>>>0<=1){m=0;D=Y(0.0);n=Y(0.0);break e}n=Y((l+-1|0)>>>0);m=0;D=Y(0.0);n=Y(Y(NT(w,Y(0.0)))/n);break e}case 5:{n=Y(w/Y((l+1|0)>>>0));m=0;D=n;break e}case 4:{n=Y(w/Y(l>>>0));m=0;D=Y(n*Y(.5));break e}default:{m=0;D=Y(0.0);n=Y(0.0);break e}}}}while(0);t=Y(Z+D);if(T){E=Y(w/Y(m|0));y=o[Ne>>2]|0;g=I;w=Y(0.0);do{m=o[y+(g<<2)>>2]|0;e:do{if((o[m+36>>2]|0)!=1){switch(o[m+24>>2]|0){case 1:{if(gi(m,Re)|0){if(!p)break e;Be=Y(yi(m,Re,N));Be=Y(Be+Y(Xr(e,Re)));Be=Y(Be+Y(Vr(m,Re,Oe)));s[m+400+(o[V>>2]<<2)>>2]=Be;break e}break}case 0:{Ue=(o[(hi(m,Re)|0)+4>>2]|0)==3;Be=Y(E+t);t=Ue?Be:t;if(p){Ue=m+400+(o[V>>2]<<2)|0;s[Ue>>2]=Y(t+Y(s[Ue>>2]))}Ue=(o[(vi(m,Re)|0)+4>>2]|0)==3;Be=Y(E+t);t=Ue?Be:t;if(B){Be=Y(n+Y(Sr(m,Re,Oe)));w=me;t=Y(t+Y(Be+Y(s[m+504>>2])));break e}else{t=Y(t+Y(n+Y(_i(m,Re,Oe))));w=Y(NT(w,Y(_i(m,Fe,Oe))));break e}}default:{}}if(p){Be=Y(D+Y(Xr(e,Re)));Ue=m+400+(o[V>>2]<<2)|0;s[Ue>>2]=Y(Be+Y(s[Ue>>2]))}}}while(0);g=g+1|0}while((g|0)!=(A|0))}else w=Y(0.0);n=Y(ee+t);if(W)D=Y(Y(di(e,Fe,Y(Ce+w),Se,c))-Ce);else D=me;E=Y(Y(di(e,Fe,Y(Ce+($?me:w)),Se,c))-Ce);if(T&p){g=I;do{y=o[(o[Ne>>2]|0)+(g<<2)>>2]|0;do{if((o[y+36>>2]|0)!=1){if((o[y+24>>2]|0)==1){if(gi(y,Fe)|0){Be=Y(yi(y,Fe,me));Be=Y(Be+Y(Xr(e,Fe)));Be=Y(Be+Y(Vr(y,Fe,Oe)));m=o[H>>2]|0;s[y+400+(m<<2)>>2]=Be;if(!(wt(Be)|0))break}else m=o[H>>2]|0;Be=Y(Xr(e,Fe));s[y+400+(m<<2)>>2]=Y(Be+Y(Vr(y,Fe,Oe)));break}m=pi(e,y)|0;do{if((m|0)==4){if((o[(hi(y,Fe)|0)+4>>2]|0)==3){K=139;break}if((o[(vi(y,Fe)|0)+4>>2]|0)==3){K=139;break}if(Ir(y,Fe,me)|0){t=b;break}je=o[y+908+(o[z>>2]<<2)>>2]|0;o[ie>>2]=je;t=Y(s[y+396>>2]);Ue=wt(t)|0;w=(o[d>>2]=je,Y(s[d>>2]));if(Ue)t=E;else{P=Y(Sr(y,Fe,Oe));Be=Y(w/t);t=Y(t*w);t=Y(P+(Pe?Be:t))}s[oe>>2]=t;s[ie>>2]=Y(Y(Sr(y,Re,Oe))+w);o[ue>>2]=1;o[ae>>2]=1;mi(y,Re,N,Oe,ue,ie);mi(y,Fe,me,Oe,ae,oe);t=Y(s[ie>>2]);P=Y(s[oe>>2]);Be=Pe?t:P;t=Pe?P:t;Ue=((wt(Be)|0)^1)&1;Dr(y,Be,t,Ie,Ue,((wt(t)|0)^1)&1,Oe,ye,1,3493,v)|0;t=b}else K=139}while(0);e:do{if((K|0)==139){K=0;t=Y(D-Y(_i(y,Fe,Oe)));do{if((o[(hi(y,Fe)|0)+4>>2]|0)==3){if((o[(vi(y,Fe)|0)+4>>2]|0)!=3)break;t=Y(b+Y(NT(Y(0.0),Y(t*Y(.5)))));break e}}while(0);if((o[(vi(y,Fe)|0)+4>>2]|0)==3){t=b;break}if((o[(hi(y,Fe)|0)+4>>2]|0)==3){t=Y(b+Y(NT(Y(0.0),t)));break}switch(m|0){case 1:{t=b;break e}case 2:{t=Y(b+Y(t*Y(.5)));break e}default:{t=Y(b+t);break e}}}}while(0);Be=Y(he+t);Ue=y+400+(o[H>>2]<<2)|0;s[Ue>>2]=Y(Be+Y(s[Ue>>2]))}}while(0);g=g+1|0}while((g|0)!=(A|0))}he=Y(he+E);re=Y(NT(re,n));l=L+1|0;if(A>>>0>=Me>>>0)break;else{t=N;I=A;L=l}}do{if(p){m=l>>>0>1;if(!m?!(bi(e)|0):0)break;if(!(wt(me)|0)){t=Y(me-he);e:do{switch(o[e+12>>2]|0){case 3:{b=Y(b+t);C=Y(0.0);break}case 2:{b=Y(b+Y(t*Y(.5)));C=Y(0.0);break}case 4:{if(me>he)C=Y(t/Y(l>>>0));else C=Y(0.0);break}case 7:if(me>he){b=Y(b+Y(t/Y(l<<1>>>0)));C=Y(t/Y(l>>>0));C=m?C:Y(0.0);break e}else{b=Y(b+Y(t*Y(.5)));C=Y(0.0);break e}case 6:{C=Y(t/Y(L>>>0));C=me>he&m?C:Y(0.0);break}default:C=Y(0.0)}}while(0);if(l|0){T=1040+(Fe<<2)|0;x=976+(Fe<<2)|0;_=0;g=0;while(1){e:do{if(g>>>0>>0){w=Y(0.0);E=Y(0.0);t=Y(0.0);y=g;while(1){m=o[(o[Ne>>2]|0)+(y<<2)>>2]|0;do{if((o[m+36>>2]|0)!=1?(o[m+24>>2]|0)==0:0){if((o[m+940>>2]|0)!=(_|0))break e;if(wi(m,Fe)|0){Be=Y(s[m+908+(o[x>>2]<<2)>>2]);t=Y(NT(t,Y(Be+Y(Sr(m,Fe,Oe)))))}if((pi(e,m)|0)!=5)break;pe=Y(Ei(m));pe=Y(pe+Y(Vr(m,0,Oe)));Be=Y(s[m+912>>2]);Be=Y(Y(Be+Y(Sr(m,0,Oe)))-pe);pe=Y(NT(E,pe));Be=Y(NT(w,Be));w=Be;E=pe;t=Y(NT(t,Y(pe+Be)))}}while(0);m=y+1|0;if(m>>>0>>0)y=m;else{y=m;break}}}else{E=Y(0.0);t=Y(0.0);y=g}}while(0);S=Y(C+t);n=b;b=Y(b+S);if(g>>>0>>0){D=Y(n+E);m=g;do{g=o[(o[Ne>>2]|0)+(m<<2)>>2]|0;e:do{if((o[g+36>>2]|0)!=1?(o[g+24>>2]|0)==0:0)switch(pi(e,g)|0){case 1:{Be=Y(n+Y(Vr(g,Fe,Oe)));s[g+400+(o[T>>2]<<2)>>2]=Be;break e}case 3:{Be=Y(Y(b-Y(qr(g,Fe,Oe)))-Y(s[g+908+(o[x>>2]<<2)>>2]));s[g+400+(o[T>>2]<<2)>>2]=Be;break e}case 2:{Be=Y(n+Y(Y(S-Y(s[g+908+(o[x>>2]<<2)>>2]))*Y(.5)));s[g+400+(o[T>>2]<<2)>>2]=Be;break e}case 4:{Be=Y(n+Y(Vr(g,Fe,Oe)));s[g+400+(o[T>>2]<<2)>>2]=Be;if(Ir(g,Fe,me)|0)break e;if(Pe){w=Y(s[g+908>>2]);t=Y(w+Y(Sr(g,Re,Oe)));E=S}else{E=Y(s[g+912>>2]);E=Y(E+Y(Sr(g,Fe,Oe)));t=S;w=Y(s[g+908>>2])}if(vr(t,w)|0?vr(E,Y(s[g+912>>2]))|0:0)break e;Dr(g,t,E,Ie,1,1,Oe,ye,1,3501,v)|0;break e}case 5:{s[g+404>>2]=Y(Y(D-Y(Ei(g)))+Y(yi(g,0,me)));break e}default:break e}}while(0);m=m+1|0}while((m|0)!=(y|0))}_=_+1|0;if((_|0)==(l|0))break;else g=y}}}}}while(0);s[e+908>>2]=Y(di(e,2,_e,c,c));s[e+912>>2]=Y(di(e,0,ge,f,c));if((ve|0)!=0?(Ee=o[e+32>>2]|0,De=(ve|0)==2,!(De&(Ee|0)!=2)):0){if(De&(Ee|0)==2){t=Y(we+N);t=Y(NT(Y(RT(t,Y(Di(e,Re,re,be)))),we));K=198}}else{t=Y(di(e,Re,re,be,c));K=198}if((K|0)==198)s[e+908+(o[976+(Re<<2)>>2]<<2)>>2]=t;if((ke|0)!=0?(xe=o[e+32>>2]|0,Ae=(ke|0)==2,!(Ae&(xe|0)!=2)):0){if(Ae&(xe|0)==2){t=Y(Ce+me);t=Y(NT(Y(RT(t,Y(Di(e,Fe,Y(Ce+he),Se)))),Ce));K=204}}else{t=Y(di(e,Fe,Y(Ce+he),Se,c));K=204}if((K|0)==204)s[e+908+(o[976+(Fe<<2)>>2]<<2)>>2]=t;if(p){if((o[Te>>2]|0)==2){g=976+(Fe<<2)|0;y=1040+(Fe<<2)|0;m=0;do{_=Pt(e,m)|0;if(!(o[_+24>>2]|0)){je=o[g>>2]|0;Be=Y(s[e+908+(je<<2)>>2]);Ue=_+400+(o[y>>2]<<2)|0;Be=Y(Be-Y(s[Ue>>2]));s[Ue>>2]=Y(Be-Y(s[_+908+(je<<2)>>2]))}m=m+1|0}while((m|0)!=(Me|0))}if(i|0){m=Pe?ve:a;do{Si(e,i,Oe,m,ye,Ie,v);i=o[i+960>>2]|0}while((i|0)!=0)}m=(Re|2|0)==3;g=(Fe|2|0)==3;if(m|g){i=0;do{y=o[(o[Ne>>2]|0)+(i<<2)>>2]|0;if((o[y+36>>2]|0)!=1){if(m)Ci(e,y,Re);if(g)Ci(e,y,Fe)}i=i+1|0}while((i|0)!=(Me|0))}}}else ei(e,t,n,a,l,c,f)}while(0);h=Le;return}function Ar(e,t){e=e|0;t=Y(t);var n=0;St(e,t>=Y(0.0),3147);n=t==Y(0.0);s[e+4>>2]=n?Y(0.0):t;return}function Or(e,t,n,i){e=e|0;t=Y(t);n=Y(n);i=i|0;var u=ft,a=ft,l=0,c=0,f=0;o[2278]=(o[2278]|0)+1;Pr(e);if(!(Ir(e,2,t)|0)){u=Y(Nr(e+380|0,t));if(!(u>=Y(0.0))){f=((wt(t)|0)^1)&1;u=t}else f=2}else{u=Y(Nr(o[e+992>>2]|0,t));f=1;u=Y(u+Y(Sr(e,2,t)))}if(!(Ir(e,0,n)|0)){a=Y(Nr(e+388|0,n));if(!(a>=Y(0.0))){c=((wt(n)|0)^1)&1;a=n}else c=2}else{a=Y(Nr(o[e+996>>2]|0,n));c=1;a=Y(a+Y(Sr(e,0,t)))}l=e+976|0;if(Dr(e,u,a,i,f,c,t,n,1,3189,o[l>>2]|0)|0?(Mr(e,o[e+496>>2]|0,t,n,t),Rr(e,Y(s[(o[l>>2]|0)+4>>2]),Y(0.0),Y(0.0)),r[11696]|0):0)mr(e,7);return}function Pr(e){e=e|0;var t=0,n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0;l=h;h=h+32|0;a=l+24|0;u=l+16|0;r=l+8|0;i=l;n=0;do{t=e+380+(n<<3)|0;if(!((o[e+380+(n<<3)+4>>2]|0)!=0?(s=t,c=o[s+4>>2]|0,f=r,o[f>>2]=o[s>>2],o[f+4>>2]=c,f=e+364+(n<<3)|0,c=o[f+4>>2]|0,s=i,o[s>>2]=o[f>>2],o[s+4>>2]=c,o[u>>2]=o[r>>2],o[u+4>>2]=o[r+4>>2],o[a>>2]=o[i>>2],o[a+4>>2]=o[i+4>>2],hr(u,a)|0):0))t=e+348+(n<<3)|0;o[e+992+(n<<2)>>2]=t;n=n+1|0}while((n|0)!=2);h=l;return}function Ir(e,t,n){e=e|0;t=t|0;n=Y(n);var r=0;e=o[e+992+(o[976+(t<<2)>>2]<<2)>>2]|0;switch(o[e+4>>2]|0){case 0:case 3:{e=0;break}case 1:{if(Y(s[e>>2])>2])>2]|0){case 2:{t=Y(Y(Y(s[e>>2])*t)/Y(100.0));break}case 1:{t=Y(s[e>>2]);break}default:t=Y(E)}return Y(t)}function Mr(e,t,n,r,i){e=e|0;t=t|0;n=Y(n);r=Y(r);i=Y(i);var u=0,a=ft;t=o[e+944>>2]|0?t:1;u=Kr(o[e+4>>2]|0,t)|0;t=ri(u,t)|0;n=Y(Pi(e,u,n));r=Y(Pi(e,t,r));a=Y(n+Y(Vr(e,u,i)));s[e+400+(o[1040+(u<<2)>>2]<<2)>>2]=a;n=Y(n+Y(qr(e,u,i)));s[e+400+(o[1e3+(u<<2)>>2]<<2)>>2]=n;n=Y(r+Y(Vr(e,t,i)));s[e+400+(o[1040+(t<<2)>>2]<<2)>>2]=n;i=Y(r+Y(qr(e,t,i)));s[e+400+(o[1e3+(t<<2)>>2]<<2)>>2]=i;return}function Rr(e,t,n,r){e=e|0;t=Y(t);n=Y(n);r=Y(r);var i=0,u=0,a=ft,l=ft,c=0,f=0,d=ft,p=0,h=ft,v=ft,m=ft,g=ft;if(!(t==Y(0.0))){i=e+400|0;g=Y(s[i>>2]);u=e+404|0;m=Y(s[u>>2]);p=e+416|0;v=Y(s[p>>2]);f=e+420|0;a=Y(s[f>>2]);h=Y(g+n);d=Y(m+r);r=Y(h+v);l=Y(d+a);c=(o[e+988>>2]|0)==1;s[i>>2]=Y(yr(g,t,0,c));s[u>>2]=Y(yr(m,t,0,c));n=Y(LT(Y(v*t),Y(1.0)));if(vr(n,Y(0.0))|0)u=0;else u=(vr(n,Y(1.0))|0)^1;n=Y(LT(Y(a*t),Y(1.0)));if(vr(n,Y(0.0))|0)i=0;else i=(vr(n,Y(1.0))|0)^1;g=Y(yr(r,t,c&u,c&(u^1)));s[p>>2]=Y(g-Y(yr(h,t,0,c)));g=Y(yr(l,t,c&i,c&(i^1)));s[f>>2]=Y(g-Y(yr(d,t,0,c)));u=(o[e+952>>2]|0)-(o[e+948>>2]|0)>>2;if(u|0){i=0;do{Rr(Pt(e,i)|0,t,h,d);i=i+1|0}while((i|0)!=(u|0))}}return}function Fr(e,t,n,r,i){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;switch(n|0){case 5:case 0:{e=oT(o[489]|0,r,i)|0;break}default:e=jT(r,i)|0}return e|0}function Lr(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0;i=h;h=h+16|0;u=i;o[u>>2]=r;Br(e,0,t,n,u);h=i;return}function Br(e,t,n,r,i){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;e=e|0?e:956;xA[o[e+8>>2]&1](e,t,n,r,i)|0;if((n|0)==5)Ye();else return}function jr(e,t,n){e=e|0;t=t|0;n=n|0;r[e+t>>0]=n&1;return}function Ur(e,t){e=e|0;t=t|0;var n=0,r=0;o[e>>2]=0;o[e+4>>2]=0;o[e+8>>2]=0;n=t+4|0;r=(o[n>>2]|0)-(o[t>>2]|0)>>2;if(r|0){zr(e,r);Wr(e,o[t>>2]|0,o[n>>2]|0,r)}return}function zr(e,t){e=e|0;t=t|0;var n=0;if((Hr(e)|0)>>>0>>0)UT(e);if(t>>>0>1073741823)Ye();else{n=$T(t<<2)|0;o[e+4>>2]=n;o[e>>2]=n;o[e+8>>2]=n+(t<<2);return}}function Wr(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;r=e+4|0;e=n-t|0;if((e|0)>0){ix(o[r>>2]|0,t|0,e|0)|0;o[r>>2]=(o[r>>2]|0)+(e>>>2<<2)}return}function Hr(e){e=e|0;return 1073741823}function Vr(e,t,n){e=e|0;t=t|0;n=Y(n);if(Gr(t)|0?(o[e+96>>2]|0)!=0:0)e=e+92|0;else e=Et(e+60|0,o[1040+(t<<2)>>2]|0,992)|0;return Y($r(e,n))}function qr(e,t,n){e=e|0;t=t|0;n=Y(n);if(Gr(t)|0?(o[e+104>>2]|0)!=0:0)e=e+100|0;else e=Et(e+60|0,o[1e3+(t<<2)>>2]|0,992)|0;return Y($r(e,n))}function Gr(e){e=e|0;return(e|1|0)==3|0}function $r(e,t){e=e|0;t=Y(t);if((o[e+4>>2]|0)==3)t=Y(0.0);else t=Y(Nr(e,t));return Y(t)}function Yr(e,t){e=e|0;t=t|0;e=o[e>>2]|0;return((e|0)==0?(t|0)>1?t:1:e)|0}function Kr(e,t){e=e|0;t=t|0;var n=0;e:do{if((t|0)==2){switch(e|0){case 2:{e=3;break e}case 3:break;default:{n=4;break e}}e=2}else n=4}while(0);return e|0}function Xr(e,t){e=e|0;t=t|0;var n=ft;if(!((Gr(t)|0?(o[e+312>>2]|0)!=0:0)?(n=Y(s[e+308>>2]),n>=Y(0.0)):0))n=Y(NT(Y(s[(Et(e+276|0,o[1040+(t<<2)>>2]|0,992)|0)>>2]),Y(0.0)));return Y(n)}function Qr(e,t){e=e|0;t=t|0;var n=ft;if(!((Gr(t)|0?(o[e+320>>2]|0)!=0:0)?(n=Y(s[e+316>>2]),n>=Y(0.0)):0))n=Y(NT(Y(s[(Et(e+276|0,o[1e3+(t<<2)>>2]|0,992)|0)>>2]),Y(0.0)));return Y(n)}function Jr(e,t,n){e=e|0;t=t|0;n=Y(n);var r=ft;if(!((Gr(t)|0?(o[e+240>>2]|0)!=0:0)?(r=Y(Nr(e+236|0,n)),r>=Y(0.0)):0))r=Y(NT(Y(Nr(Et(e+204|0,o[1040+(t<<2)>>2]|0,992)|0,n)),Y(0.0)));return Y(r)}function Zr(e,t,n){e=e|0;t=t|0;n=Y(n);var r=ft;if(!((Gr(t)|0?(o[e+248>>2]|0)!=0:0)?(r=Y(Nr(e+244|0,n)),r>=Y(0.0)):0))r=Y(NT(Y(Nr(Et(e+204|0,o[1e3+(t<<2)>>2]|0,992)|0,n)),Y(0.0)));return Y(r)}function ei(e,t,n,r,i,u,a){e=e|0;t=Y(t);n=Y(n);r=r|0;i=i|0;u=Y(u);a=Y(a);var l=ft,c=ft,f=ft,d=ft,p=ft,v=ft,m=0,g=0,y=0;y=h;h=h+16|0;m=y;g=e+964|0;Rt(e,(o[g>>2]|0)!=0,3519);l=Y(ui(e,2,t));c=Y(ui(e,0,t));f=Y(Sr(e,2,t));d=Y(Sr(e,0,t));if(wt(t)|0)p=t;else p=Y(NT(Y(0.0),Y(Y(t-f)-l)));if(wt(n)|0)v=n;else v=Y(NT(Y(0.0),Y(Y(n-d)-c)));if((r|0)==1&(i|0)==1){s[e+908>>2]=Y(di(e,2,Y(t-f),u,u));t=Y(di(e,0,Y(n-d),a,u))}else{OA[o[g>>2]&1](m,e,p,r,v,i);p=Y(l+Y(s[m>>2]));v=Y(t-f);s[e+908>>2]=Y(di(e,2,(r|2|0)==2?p:v,u,u));v=Y(c+Y(s[m+4>>2]));t=Y(n-d);t=Y(di(e,0,(i|2|0)==2?v:t,a,u))}s[e+912>>2]=t;h=y;return}function ti(e,t,n,r,i,o,u){e=e|0;t=Y(t);n=Y(n);r=r|0;i=i|0;o=Y(o);u=Y(u);var a=ft,l=ft,c=ft,f=ft;c=Y(ui(e,2,o));a=Y(ui(e,0,o));f=Y(Sr(e,2,o));l=Y(Sr(e,0,o));t=Y(t-f);s[e+908>>2]=Y(di(e,2,(r|2|0)==2?c:t,o,o));n=Y(n-l);s[e+912>>2]=Y(di(e,0,(i|2|0)==2?a:n,u,o));return}function ni(e,t,n,r,i,o,u){e=e|0;t=Y(t);n=Y(n);r=r|0;i=i|0;o=Y(o);u=Y(u);var a=0,l=ft,c=ft;a=(r|0)==2;if((!(t<=Y(0.0)&a)?!(n<=Y(0.0)&(i|0)==2):0)?!((r|0)==1&(i|0)==1):0)e=0;else{l=Y(Sr(e,0,o));c=Y(Sr(e,2,o));a=t>2]=Y(di(e,2,a?Y(0.0):t,o,o));t=Y(n-l);a=n>2]=Y(di(e,0,a?Y(0.0):t,u,o));e=1}return e|0}function ri(e,t){e=e|0;t=t|0;if(ki(e)|0)e=Kr(2,t)|0;else e=0;return e|0}function ii(e,t,n){e=e|0;t=t|0;n=Y(n);n=Y(Jr(e,t,n));return Y(n+Y(Xr(e,t)))}function oi(e,t,n){e=e|0;t=t|0;n=Y(n);n=Y(Zr(e,t,n));return Y(n+Y(Qr(e,t)))}function ui(e,t,n){e=e|0;t=t|0;n=Y(n);var r=ft;r=Y(ii(e,t,n));return Y(r+Y(oi(e,t,n)))}function ai(e){e=e|0;if(!(o[e+24>>2]|0)){if(Y(li(e))!=Y(0.0))e=1;else e=Y(si(e))!=Y(0.0)}else e=0;return e|0}function li(e){e=e|0;var t=ft;if(o[e+944>>2]|0){t=Y(s[e+44>>2]);if(wt(t)|0){t=Y(s[e+40>>2]);e=t>Y(0.0)&((wt(t)|0)^1);return Y(e?t:Y(0.0))}}else t=Y(0.0);return Y(t)}function si(e){e=e|0;var t=ft,n=0,i=ft;do{if(o[e+944>>2]|0){t=Y(s[e+48>>2]);if(wt(t)|0){n=r[(o[e+976>>2]|0)+2>>0]|0;if(n<<24>>24==0?(i=Y(s[e+40>>2]),i>24?Y(1.0):Y(0.0)}}else t=Y(0.0)}while(0);return Y(t)}function ci(e){e=e|0;var t=0,n=0;tx(e+400|0,0,540)|0;r[e+985>>0]=1;Wt(e);n=Ot(e)|0;if(n|0){t=e+948|0;e=0;do{ci(o[(o[t>>2]|0)+(e<<2)>>2]|0);e=e+1|0}while((e|0)!=(n|0))}return}function fi(e,t,n,r,i,u,a,l,c,f){e=e|0;t=t|0;n=Y(n);r=r|0;i=Y(i);u=Y(u);a=Y(a);l=l|0;c=c|0;f=f|0;var d=0,p=ft,v=0,m=0,g=ft,y=ft,_=0,b=ft,w=0,D=ft,S=0,C=0,k=0,T=0,x=0,A=0,O=0,P=0,I=0,N=0;I=h;h=h+16|0;k=I+12|0;T=I+8|0;x=I+4|0;A=I;P=Kr(o[e+4>>2]|0,c)|0;S=Gr(P)|0;p=Y(Nr(Ti(t)|0,S?u:a));C=Ir(t,2,u)|0;O=Ir(t,0,a)|0;do{if(!(wt(p)|0)?!(wt(S?n:i)|0):0){d=t+504|0;if(!(wt(Y(s[d>>2]))|0)){if(!(xi(o[t+976>>2]|0,0)|0))break;if((o[t+500>>2]|0)==(o[2278]|0))break}s[d>>2]=Y(NT(p,Y(ui(t,P,u))))}else v=7}while(0);do{if((v|0)==7){w=S^1;if(!(w|C^1)){a=Y(Nr(o[t+992>>2]|0,u));s[t+504>>2]=Y(NT(a,Y(ui(t,2,u))));break}if(!(S|O^1)){a=Y(Nr(o[t+996>>2]|0,a));s[t+504>>2]=Y(NT(a,Y(ui(t,0,u))));break}s[k>>2]=Y(E);s[T>>2]=Y(E);o[x>>2]=0;o[A>>2]=0;b=Y(Sr(t,2,u));D=Y(Sr(t,0,u));if(C){g=Y(b+Y(Nr(o[t+992>>2]|0,u)));s[k>>2]=g;o[x>>2]=1;m=1}else{m=0;g=Y(E)}if(O){p=Y(D+Y(Nr(o[t+996>>2]|0,a)));s[T>>2]=p;o[A>>2]=1;d=1}else{d=0;p=Y(E)}v=o[e+32>>2]|0;if(!(S&(v|0)==2)){if(wt(g)|0?!(wt(n)|0):0){s[k>>2]=n;o[x>>2]=2;m=2;g=n}}else v=2;if((!((v|0)==2&w)?wt(p)|0:0)?!(wt(i)|0):0){s[T>>2]=i;o[A>>2]=2;d=2;p=i}y=Y(s[t+396>>2]);_=wt(y)|0;do{if(!_){if((m|0)==1&w){s[T>>2]=Y(Y(g-b)/y);o[A>>2]=1;d=1;v=1;break}if(S&(d|0)==1){s[k>>2]=Y(y*Y(p-D));o[x>>2]=1;d=1;v=1}else v=m}else v=m}while(0);N=wt(n)|0;m=(pi(e,t)|0)!=4;if(!(S|C|((r|0)!=1|N)|(m|(v|0)==1))?(s[k>>2]=n,o[x>>2]=1,!_):0){s[T>>2]=Y(Y(n-b)/y);o[A>>2]=1;d=1}if(!(O|w|((l|0)!=1|(wt(i)|0))|(m|(d|0)==1))?(s[T>>2]=i,o[A>>2]=1,!_):0){s[k>>2]=Y(y*Y(i-D));o[x>>2]=1}mi(t,2,u,u,x,k);mi(t,0,a,u,A,T);n=Y(s[k>>2]);i=Y(s[T>>2]);Dr(t,n,i,c,o[x>>2]|0,o[A>>2]|0,u,a,0,3565,f)|0;a=Y(s[t+908+(o[976+(P<<2)>>2]<<2)>>2]);s[t+504>>2]=Y(NT(a,Y(ui(t,P,u))))}}while(0);o[t+500>>2]=o[2278];h=I;return}function di(e,t,n,r,i){e=e|0;t=t|0;n=Y(n);r=Y(r);i=Y(i);r=Y(Di(e,t,n,r));return Y(NT(r,Y(ui(e,t,i))))}function pi(e,t){e=e|0;t=t|0;t=t+20|0;t=o[((o[t>>2]|0)==0?e+16|0:t)>>2]|0;if((t|0)==5?ki(o[e+4>>2]|0)|0:0)t=1;return t|0}function hi(e,t){e=e|0;t=t|0;if(Gr(t)|0?(o[e+96>>2]|0)!=0:0)t=4;else t=o[1040+(t<<2)>>2]|0;return e+60+(t<<3)|0}function vi(e,t){e=e|0;t=t|0;if(Gr(t)|0?(o[e+104>>2]|0)!=0:0)t=5;else t=o[1e3+(t<<2)>>2]|0;return e+60+(t<<3)|0}function mi(e,t,n,r,i,u){e=e|0;t=t|0;n=Y(n);r=Y(r);i=i|0;u=u|0;n=Y(Nr(e+380+(o[976+(t<<2)>>2]<<3)|0,n));n=Y(n+Y(Sr(e,t,r)));switch(o[i>>2]|0){case 2:case 1:{i=wt(n)|0;r=Y(s[u>>2]);s[u>>2]=i|r>2]=2;s[u>>2]=n}break}default:{}}return}function gi(e,t){e=e|0;t=t|0;e=e+132|0;if(Gr(t)|0?(o[(Et(e,4,948)|0)+4>>2]|0)!=0:0)e=1;else e=(o[(Et(e,o[1040+(t<<2)>>2]|0,948)|0)+4>>2]|0)!=0;return e|0}function yi(e,t,n){e=e|0;t=t|0;n=Y(n);var r=0,i=0;e=e+132|0;if(Gr(t)|0?(r=Et(e,4,948)|0,(o[r+4>>2]|0)!=0):0)i=4;else{r=Et(e,o[1040+(t<<2)>>2]|0,948)|0;if(!(o[r+4>>2]|0))n=Y(0.0);else i=4}if((i|0)==4)n=Y(Nr(r,n));return Y(n)}function _i(e,t,n){e=e|0;t=t|0;n=Y(n);var r=ft;r=Y(s[e+908+(o[976+(t<<2)>>2]<<2)>>2]);r=Y(r+Y(Vr(e,t,n)));return Y(r+Y(qr(e,t,n)))}function bi(e){e=e|0;var t=0,n=0,r=0;e:do{if(!(ki(o[e+4>>2]|0)|0)){if((o[e+16>>2]|0)!=5){n=Ot(e)|0;if(!n)t=0;else{t=0;while(1){r=Pt(e,t)|0;if((o[r+24>>2]|0)==0?(o[r+20>>2]|0)==5:0){t=1;break e}t=t+1|0;if(t>>>0>=n>>>0){t=0;break}}}}else t=1}else t=0}while(0);return t|0}function wi(e,t){e=e|0;t=t|0;var n=ft;n=Y(s[e+908+(o[976+(t<<2)>>2]<<2)>>2]);return n>=Y(0.0)&((wt(n)|0)^1)|0}function Ei(e){e=e|0;var t=ft,n=0,r=0,i=0,u=0,a=0,l=0,c=ft;n=o[e+968>>2]|0;if(!n){u=Ot(e)|0;do{if(u|0){n=0;i=0;while(1){r=Pt(e,i)|0;if(o[r+940>>2]|0){a=8;break}if((o[r+24>>2]|0)!=1){l=(pi(e,r)|0)==5;if(l){n=r;break}else n=(n|0)==0?r:n}i=i+1|0;if(i>>>0>=u>>>0){a=8;break}}if((a|0)==8)if(!n)break;t=Y(Ei(n));return Y(t+Y(s[n+404>>2]))}}while(0);t=Y(s[e+912>>2])}else{c=Y(s[e+908>>2]);t=Y(s[e+912>>2]);t=Y(pA[n&0](e,c,t));Rt(e,(wt(t)|0)^1,3573)}return Y(t)}function Di(e,t,n,r){e=e|0;t=t|0;n=Y(n);r=Y(r);var i=ft,o=0;if(!(ki(t)|0)){if(Gr(t)|0){t=0;o=3}else{r=Y(E);i=Y(E)}}else{t=1;o=3}if((o|0)==3){i=Y(Nr(e+364+(t<<3)|0,r));r=Y(Nr(e+380+(t<<3)|0,r))}o=r=Y(0.0)&((wt(r)|0)^1));n=o?r:n;o=i>=Y(0.0)&((wt(i)|0)^1)&n>2]|0,u)|0;m=ri(y,u)|0;g=Gr(y)|0;p=Y(Sr(t,2,n));h=Y(Sr(t,0,n));if(!(Ir(t,2,n)|0)){if(gi(t,2)|0?Ai(t,2)|0:0){l=Y(s[e+908>>2]);c=Y(Xr(e,2));c=Y(l-Y(c+Y(Qr(e,2))));l=Y(yi(t,2,n));l=Y(di(t,2,Y(c-Y(l+Y(Oi(t,2,n)))),n,n))}else l=Y(E)}else l=Y(p+Y(Nr(o[t+992>>2]|0,n)));if(!(Ir(t,0,i)|0)){if(gi(t,0)|0?Ai(t,0)|0:0){c=Y(s[e+912>>2]);b=Y(Xr(e,0));b=Y(c-Y(b+Y(Qr(e,0))));c=Y(yi(t,0,i));c=Y(di(t,0,Y(b-Y(c+Y(Oi(t,0,i)))),i,n))}else c=Y(E)}else c=Y(h+Y(Nr(o[t+996>>2]|0,i)));f=wt(l)|0;d=wt(c)|0;do{if(f^d?(v=Y(s[t+396>>2]),!(wt(v)|0)):0)if(f){l=Y(p+Y(Y(c-h)*v));break}else{b=Y(h+Y(Y(l-p)/v));c=d?b:c;break}}while(0);d=wt(l)|0;f=wt(c)|0;if(d|f){w=(d^1)&1;r=n>Y(0.0)&((r|0)!=0&d);l=g?l:r?n:l;Dr(t,l,c,u,g?w:r?2:w,d&(f^1)&1,l,c,0,3623,a)|0;l=Y(s[t+908>>2]);l=Y(l+Y(Sr(t,2,n)));c=Y(s[t+912>>2]);c=Y(c+Y(Sr(t,0,n)))}Dr(t,l,c,u,1,1,l,c,1,3635,a)|0;if(Ai(t,y)|0?!(gi(t,y)|0):0){w=o[976+(y<<2)>>2]|0;b=Y(s[e+908+(w<<2)>>2]);b=Y(b-Y(s[t+908+(w<<2)>>2]));b=Y(b-Y(Qr(e,y)));b=Y(b-Y(qr(t,y,n)));b=Y(b-Y(Oi(t,y,g?n:i)));s[t+400+(o[1040+(y<<2)>>2]<<2)>>2]=b}else _=21;do{if((_|0)==21){if(!(gi(t,y)|0)?(o[e+8>>2]|0)==1:0){w=o[976+(y<<2)>>2]|0;b=Y(s[e+908+(w<<2)>>2]);b=Y(Y(b-Y(s[t+908+(w<<2)>>2]))*Y(.5));s[t+400+(o[1040+(y<<2)>>2]<<2)>>2]=b;break}if(!(gi(t,y)|0)?(o[e+8>>2]|0)==2:0){w=o[976+(y<<2)>>2]|0;b=Y(s[e+908+(w<<2)>>2]);b=Y(b-Y(s[t+908+(w<<2)>>2]));s[t+400+(o[1040+(y<<2)>>2]<<2)>>2]=b}}}while(0);if(Ai(t,m)|0?!(gi(t,m)|0):0){w=o[976+(m<<2)>>2]|0;b=Y(s[e+908+(w<<2)>>2]);b=Y(b-Y(s[t+908+(w<<2)>>2]));b=Y(b-Y(Qr(e,m)));b=Y(b-Y(qr(t,m,n)));b=Y(b-Y(Oi(t,m,g?i:n)));s[t+400+(o[1040+(m<<2)>>2]<<2)>>2]=b}else _=30;do{if((_|0)==30?!(gi(t,m)|0):0){if((pi(e,t)|0)==2){w=o[976+(m<<2)>>2]|0;b=Y(s[e+908+(w<<2)>>2]);b=Y(Y(b-Y(s[t+908+(w<<2)>>2]))*Y(.5));s[t+400+(o[1040+(m<<2)>>2]<<2)>>2]=b;break}w=(pi(e,t)|0)==3;if(w^(o[e+28>>2]|0)==2){w=o[976+(m<<2)>>2]|0;b=Y(s[e+908+(w<<2)>>2]);b=Y(b-Y(s[t+908+(w<<2)>>2]));s[t+400+(o[1040+(m<<2)>>2]<<2)>>2]=b}}}while(0);return}function Ci(e,t,n){e=e|0;t=t|0;n=n|0;var r=ft,i=0;i=o[976+(n<<2)>>2]|0;r=Y(s[t+908+(i<<2)>>2]);r=Y(Y(s[e+908+(i<<2)>>2])-r);r=Y(r-Y(s[t+400+(o[1040+(n<<2)>>2]<<2)>>2]));s[t+400+(o[1e3+(n<<2)>>2]<<2)>>2]=r;return}function ki(e){e=e|0;return(e|1|0)==1|0}function Ti(e){e=e|0;var t=ft;switch(o[e+56>>2]|0){case 0:case 3:{t=Y(s[e+40>>2]);if(t>Y(0.0)&((wt(t)|0)^1))e=r[(o[e+976>>2]|0)+2>>0]|0?1056:992;else e=1056;break}default:e=e+52|0}return e|0}function xi(e,t){e=e|0;t=t|0;return(r[e+t>>0]|0)!=0|0}function Ai(e,t){e=e|0;t=t|0;e=e+132|0;if(Gr(t)|0?(o[(Et(e,5,948)|0)+4>>2]|0)!=0:0)e=1;else e=(o[(Et(e,o[1e3+(t<<2)>>2]|0,948)|0)+4>>2]|0)!=0;return e|0}function Oi(e,t,n){e=e|0;t=t|0;n=Y(n);var r=0,i=0;e=e+132|0;if(Gr(t)|0?(r=Et(e,5,948)|0,(o[r+4>>2]|0)!=0):0)i=4;else{r=Et(e,o[1e3+(t<<2)>>2]|0,948)|0;if(!(o[r+4>>2]|0))n=Y(0.0);else i=4}if((i|0)==4)n=Y(Nr(r,n));return Y(n)}function Pi(e,t,n){e=e|0;t=t|0;n=Y(n);if(gi(e,t)|0)n=Y(yi(e,t,n));else n=Y(-Y(Oi(e,t,n)));return Y(n)}function Ii(e){e=Y(e);return(s[d>>2]=e,o[d>>2]|0)|0}function Ni(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>1073741823)Ye();else{i=$T(t<<2)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n<<2)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t<<2);return}function Mi(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(0-(i>>2)<<2)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function Ri(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~((r+-4-t|0)>>>2)<<2);e=o[e>>2]|0;if(e|0)KT(e);return}function Fi(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0;a=e+4|0;l=o[a>>2]|0;i=l-r|0;u=i>>2;e=t+(u<<2)|0;if(e>>>0>>0){r=l;do{o[r>>2]=o[e>>2];e=e+4|0;r=(o[a>>2]|0)+4|0;o[a>>2]=r}while(e>>>0>>0)}if(u|0)sx(l+(0-u<<2)|0,t|0,i|0)|0;return}function Li(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0;l=t+4|0;s=o[l>>2]|0;i=o[e>>2]|0;a=n;u=a-i|0;r=s+(0-(u>>2)<<2)|0;o[l>>2]=r;if((u|0)>0)ix(r|0,i|0,u|0)|0;i=e+4|0;u=t+8|0;r=(o[i>>2]|0)-a|0;if((r|0)>0){ix(o[u>>2]|0,n|0,r|0)|0;o[u>>2]=(o[u>>2]|0)+(r>>>2<<2)}a=o[e>>2]|0;o[e>>2]=o[l>>2];o[l>>2]=a;a=o[i>>2]|0;o[i>>2]=o[u>>2];o[u>>2]=a;a=e+8|0;n=t+12|0;e=o[a>>2]|0;o[a>>2]=o[n>>2];o[n>>2]=e;o[t>>2]=o[l>>2];return s|0}function Bi(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;a=o[t>>2]|0;u=o[n>>2]|0;if((a|0)!=(u|0)){i=e+8|0;n=((u+-4-a|0)>>>2)+1|0;e=a;r=o[i>>2]|0;do{o[r>>2]=o[e>>2];r=(o[i>>2]|0)+4|0;o[i>>2]=r;e=e+4|0}while((e|0)!=(u|0));o[t>>2]=a+(n<<2)}return}function ji(){_t();return}function Ui(){var e=0;e=$T(4)|0;zi(e);return e|0}function zi(e){e=e|0;o[e>>2]=Lt()|0;return}function Wi(e){e=e|0;if(e|0){Hi(e);KT(e)}return}function Hi(e){e=e|0;jt(o[e>>2]|0);return}function Vi(e,t,n){e=e|0;t=t|0;n=n|0;jr(o[e>>2]|0,t,n);return}function qi(e,t){e=e|0;t=Y(t);Ar(o[e>>2]|0,t);return}function Gi(e,t){e=e|0;t=t|0;return xi(o[e>>2]|0,t)|0}function $i(){var e=0;e=$T(8)|0;Yi(e,0);return e|0}function Yi(e,t){e=e|0;t=t|0;if(!t)t=Ct()|0;else t=Dt(o[t>>2]|0)|0;o[e>>2]=t;o[e+4>>2]=0;Jt(t,e);return}function Ki(e){e=e|0;var t=0;t=$T(8)|0;Yi(t,e);return t|0}function Xi(e){e=e|0;if(e|0){Qi(e);KT(e)}return}function Qi(e){e=e|0;var t=0;xt(o[e>>2]|0);t=e+4|0;e=o[t>>2]|0;o[t>>2]=0;if(e|0){Ji(e);KT(e)}return}function Ji(e){e=e|0;Zi(e);return}function Zi(e){e=e|0;e=o[e>>2]|0;if(e|0)rt(e|0);return}function eo(e){e=e|0;return Zt(e)|0}function to(e){e=e|0;var t=0,n=0;n=e+4|0;t=o[n>>2]|0;o[n>>2]=0;if(t|0){Ji(t);KT(t)}Mt(o[e>>2]|0);return}function no(e,t){e=e|0;t=t|0;Kt(o[e>>2]|0,o[t>>2]|0);return}function ro(e,t){e=e|0;t=t|0;fn(o[e>>2]|0,t);return}function io(e,t,n){e=e|0;t=t|0;n=+n;Cn(o[e>>2]|0,t,Y(n));return}function oo(e,t,n){e=e|0;t=t|0;n=+n;kn(o[e>>2]|0,t,Y(n));return}function uo(e,t){e=e|0;t=t|0;on(o[e>>2]|0,t);return}function ao(e,t){e=e|0;t=t|0;an(o[e>>2]|0,t);return}function lo(e,t){e=e|0;t=t|0;sn(o[e>>2]|0,t);return}function so(e,t){e=e|0;t=t|0;en(o[e>>2]|0,t);return}function co(e,t){e=e|0;t=t|0;pn(o[e>>2]|0,t);return}function fo(e,t){e=e|0;t=t|0;nn(o[e>>2]|0,t);return}function po(e,t,n){e=e|0;t=t|0;n=+n;xn(o[e>>2]|0,t,Y(n));return}function ho(e,t,n){e=e|0;t=t|0;n=+n;An(o[e>>2]|0,t,Y(n));return}function vo(e,t){e=e|0;t=t|0;Pn(o[e>>2]|0,t);return}function mo(e,t){e=e|0;t=t|0;vn(o[e>>2]|0,t);return}function go(e,t){e=e|0;t=t|0;gn(o[e>>2]|0,t);return}function yo(e,t){e=e|0;t=+t;_n(o[e>>2]|0,Y(t));return}function _o(e,t){e=e|0;t=+t;En(o[e>>2]|0,Y(t));return}function bo(e,t){e=e|0;t=+t;Dn(o[e>>2]|0,Y(t));return}function wo(e,t){e=e|0;t=+t;bn(o[e>>2]|0,Y(t));return}function Eo(e,t){e=e|0;t=+t;wn(o[e>>2]|0,Y(t));return}function Do(e,t){e=e|0;t=+t;Ln(o[e>>2]|0,Y(t));return}function So(e,t){e=e|0;t=+t;Bn(o[e>>2]|0,Y(t));return}function Co(e){e=e|0;jn(o[e>>2]|0);return}function ko(e,t){e=e|0;t=+t;zn(o[e>>2]|0,Y(t));return}function To(e,t){e=e|0;t=+t;Wn(o[e>>2]|0,Y(t));return}function xo(e){e=e|0;Hn(o[e>>2]|0);return}function Ao(e,t){e=e|0;t=+t;qn(o[e>>2]|0,Y(t));return}function Oo(e,t){e=e|0;t=+t;Gn(o[e>>2]|0,Y(t));return}function Po(e,t){e=e|0;t=+t;Yn(o[e>>2]|0,Y(t));return}function Io(e,t){e=e|0;t=+t;Kn(o[e>>2]|0,Y(t));return}function No(e,t){e=e|0;t=+t;Qn(o[e>>2]|0,Y(t));return}function Mo(e,t){e=e|0;t=+t;Jn(o[e>>2]|0,Y(t));return}function Ro(e,t){e=e|0;t=+t;er(o[e>>2]|0,Y(t));return}function Fo(e,t){e=e|0;t=+t;tr(o[e>>2]|0,Y(t));return}function Lo(e,t){e=e|0;t=+t;rr(o[e>>2]|0,Y(t));return}function Bo(e,t,n){e=e|0;t=t|0;n=+n;Rn(o[e>>2]|0,t,Y(n));return}function jo(e,t,n){e=e|0;t=t|0;n=+n;In(o[e>>2]|0,t,Y(n));return}function Uo(e,t,n){e=e|0;t=t|0;n=+n;Nn(o[e>>2]|0,t,Y(n));return}function zo(e){e=e|0;return dn(o[e>>2]|0)|0}function Wo(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0;r=h;h=h+16|0;i=r;Tn(i,o[t>>2]|0,n);Ho(e,i);h=r;return}function Ho(e,t){e=e|0;t=t|0;Vo(e,o[t+4>>2]|0,+Y(s[t>>2]));return}function Vo(e,t,n){e=e|0;t=t|0;n=+n;o[e>>2]=t;c[e+8>>3]=n;return}function qo(e){e=e|0;return un(o[e>>2]|0)|0}function Go(e){e=e|0;return ln(o[e>>2]|0)|0}function $o(e){e=e|0;return cn(o[e>>2]|0)|0}function Yo(e){e=e|0;return tn(o[e>>2]|0)|0}function Ko(e){e=e|0;return hn(o[e>>2]|0)|0}function Xo(e){e=e|0;return rn(o[e>>2]|0)|0}function Qo(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0;r=h;h=h+16|0;i=r;On(i,o[t>>2]|0,n);Ho(e,i);h=r;return}function Jo(e){e=e|0;return mn(o[e>>2]|0)|0}function Zo(e){e=e|0;return yn(o[e>>2]|0)|0}function eu(e,t){e=e|0;t=t|0;var n=0,r=0;n=h;h=h+16|0;r=n;Sn(r,o[t>>2]|0);Ho(e,r);h=n;return}function tu(e){e=e|0;return+ +Y(Xt(o[e>>2]|0))}function nu(e){e=e|0;return+ +Y(Qt(o[e>>2]|0))}function ru(e,t){e=e|0;t=t|0;var n=0,r=0;n=h;h=h+16|0;r=n;Un(r,o[t>>2]|0);Ho(e,r);h=n;return}function iu(e,t){e=e|0;t=t|0;var n=0,r=0;n=h;h=h+16|0;r=n;Vn(r,o[t>>2]|0);Ho(e,r);h=n;return}function ou(e,t){e=e|0;t=t|0;var n=0,r=0;n=h;h=h+16|0;r=n;$n(r,o[t>>2]|0);Ho(e,r);h=n;return}function uu(e,t){e=e|0;t=t|0;var n=0,r=0;n=h;h=h+16|0;r=n;Xn(r,o[t>>2]|0);Ho(e,r);h=n;return}function au(e,t){e=e|0;t=t|0;var n=0,r=0;n=h;h=h+16|0;r=n;Zn(r,o[t>>2]|0);Ho(e,r);h=n;return}function lu(e,t){e=e|0;t=t|0;var n=0,r=0;n=h;h=h+16|0;r=n;nr(r,o[t>>2]|0);Ho(e,r);h=n;return}function su(e){e=e|0;return+ +Y(ir(o[e>>2]|0))}function cu(e,t){e=e|0;t=t|0;return+ +Y(Fn(o[e>>2]|0,t))}function fu(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0;r=h;h=h+16|0;i=r;Mn(i,o[t>>2]|0,n);Ho(e,i);h=r;return}function du(e,t,n){e=e|0;t=t|0;n=n|0;zt(o[e>>2]|0,o[t>>2]|0,n);return}function pu(e,t){e=e|0;t=t|0;Nt(o[e>>2]|0,o[t>>2]|0);return}function hu(e){e=e|0;return Ot(o[e>>2]|0)|0}function vu(e){e=e|0;e=Gt(o[e>>2]|0)|0;if(!e)e=0;else e=eo(e)|0;return e|0}function mu(e,t){e=e|0;t=t|0;e=Pt(o[e>>2]|0,t)|0;if(!e)e=0;else e=eo(e)|0;return e|0}function gu(e,t){e=e|0;t=t|0;var n=0,r=0;r=$T(4)|0;yu(r,t);n=e+4|0;t=o[n>>2]|0;o[n>>2]=r;if(t|0){Ji(t);KT(t)}Ut(o[e>>2]|0,1);return}function yu(e,t){e=e|0;t=t|0;Bu(e,t);return}function _u(e,t,n,r,i,o){e=e|0;t=t|0;n=Y(n);r=r|0;i=Y(i);o=o|0;var u=0,a=0;u=h;h=h+16|0;a=u;bu(a,Zt(t)|0,+n,r,+i,o);s[e>>2]=Y(+c[a>>3]);s[e+4>>2]=Y(+c[a+8>>3]);h=u;return}function bu(e,t,n,r,i,u){e=e|0;t=t|0;n=+n;r=r|0;i=+i;u=u|0;var a=0,l=0,s=0,f=0,d=0;a=h;h=h+32|0;d=a+8|0;f=a+20|0;s=a;l=a+16|0;c[d>>3]=n;o[f>>2]=r;c[s>>3]=i;o[l>>2]=u;wu(e,o[t+4>>2]|0,d,f,s,l);h=a;return}function wu(e,t,n,r,i,u){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;u=u|0;var a=0,l=0;a=h;h=h+16|0;l=a;Dk(l);t=Eu(t)|0;Du(e,t,+c[n>>3],o[r>>2]|0,+c[i>>3],o[u>>2]|0);Ck(l);h=a;return}function Eu(e){e=e|0;return o[e>>2]|0}function Du(e,t,n,r,i,o){e=e|0;t=t|0;n=+n;r=r|0;i=+i;o=o|0;var u=0;u=Cu(Su()|0)|0;n=+ku(n);r=Tu(r)|0;i=+ku(i);xu(e,ot(0,u|0,t|0,+n,r|0,+i,Tu(o)|0)|0);return}function Su(){var e=0;if(!(r[7608]|0)){Ru(9120);e=7608;o[e>>2]=1;o[e+4>>2]=0}return 9120}function Cu(e){e=e|0;return o[e+8>>2]|0}function ku(e){e=+e;return+ +Mu(e)}function Tu(e){e=e|0;return Nu(e)|0}function xu(e,t){e=e|0;t=t|0;var n=0,r=0,i=0;i=h;h=h+32|0;n=i;r=t;if(!(r&1)){o[e>>2]=o[t>>2];o[e+4>>2]=o[t+4>>2];o[e+8>>2]=o[t+8>>2];o[e+12>>2]=o[t+12>>2]}else{Au(n,0);Be(r|0,n|0)|0;Ou(e,n);Pu(n)}h=i;return}function Au(e,t){e=e|0;t=t|0;Iu(e,t);o[e+8>>2]=0;r[e+24>>0]=0;return}function Ou(e,t){e=e|0;t=t|0;t=t+8|0;o[e>>2]=o[t>>2];o[e+4>>2]=o[t+4>>2];o[e+8>>2]=o[t+8>>2];o[e+12>>2]=o[t+12>>2];return}function Pu(e){e=e|0;r[e+24>>0]=0;return}function Iu(e,t){e=e|0;t=t|0;o[e>>2]=t;return}function Nu(e){e=e|0;return e|0}function Mu(e){e=+e;return+e}function Ru(e){e=e|0;Lu(e,Fu()|0,4);return}function Fu(){return 1064}function Lu(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;o[e+4>>2]=n;o[e+8>>2]=tt(t|0,n+1|0)|0;return}function Bu(e,t){e=e|0;t=t|0;t=o[t>>2]|0;o[e>>2]=t;Ae(t|0);return}function ju(e){e=e|0;var t=0,n=0;n=e+4|0;t=o[n>>2]|0;o[n>>2]=0;if(t|0){Ji(t);KT(t)}Ut(o[e>>2]|0,0);return}function Uu(e){e=e|0;$t(o[e>>2]|0);return}function zu(e){e=e|0;return Yt(o[e>>2]|0)|0}function Wu(e,t,n,r){e=e|0;t=+t;n=+n;r=r|0;Or(o[e>>2]|0,Y(t),Y(n),r);return}function Hu(e){e=e|0;return+ +Y(or(o[e>>2]|0))}function Vu(e){e=e|0;return+ +Y(ar(o[e>>2]|0))}function qu(e){e=e|0;return+ +Y(ur(o[e>>2]|0))}function Gu(e){e=e|0;return+ +Y(lr(o[e>>2]|0))}function $u(e){e=e|0;return+ +Y(sr(o[e>>2]|0))}function Yu(e){e=e|0;return+ +Y(cr(o[e>>2]|0))}function Ku(e,t){e=e|0;t=t|0;c[e>>3]=+Y(or(o[t>>2]|0));c[e+8>>3]=+Y(ar(o[t>>2]|0));c[e+16>>3]=+Y(ur(o[t>>2]|0));c[e+24>>3]=+Y(lr(o[t>>2]|0));c[e+32>>3]=+Y(sr(o[t>>2]|0));c[e+40>>3]=+Y(cr(o[t>>2]|0));return}function Xu(e,t){e=e|0;t=t|0;return+ +Y(fr(o[e>>2]|0,t))}function Qu(e,t){e=e|0;t=t|0;return+ +Y(dr(o[e>>2]|0,t))}function Ju(e,t){e=e|0;t=t|0;return+ +Y(pr(o[e>>2]|0,t))}function Zu(){return Ft()|0}function ea(){ta();na();ra();ia();oa();ua();return}function ta(){zb(11713,4938,1);return}function na(){tb(10448);return}function ra(){R_(10408);return}function ia(){Jy(10324);return}function oa(){qm(10096);return}function ua(){aa(9132);return}function aa(e){e=e|0;var t=0,n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0,v=0,m=0,g=0,y=0,_=0,b=0,w=0,E=0,D=0,S=0,C=0,k=0,T=0,x=0,A=0,O=0,P=0,I=0,N=0,M=0,R=0,F=0,L=0,B=0,j=0,U=0,z=0,W=0,H=0,V=0,q=0,G=0,$=0,Y=0,K=0,X=0,Q=0,J=0,Z=0,ee=0,te=0,ne=0,re=0,ie=0,oe=0,ue=0,ae=0,le=0,se=0,ce=0,fe=0,de=0,pe=0,he=0,ve=0,me=0,ge=0,ye=0,_e=0,be=0,we=0,Ee=0,De=0,Se=0,Ce=0,ke=0,Te=0,xe=0,Ae=0,Oe=0,Pe=0,Ie=0;t=h;h=h+672|0;n=t+656|0;Ie=t+648|0;Pe=t+640|0;Oe=t+632|0;Ae=t+624|0;xe=t+616|0;Te=t+608|0;ke=t+600|0;Ce=t+592|0;Se=t+584|0;De=t+576|0;Ee=t+568|0;we=t+560|0;be=t+552|0;_e=t+544|0;ye=t+536|0;ge=t+528|0;me=t+520|0;ve=t+512|0;he=t+504|0;pe=t+496|0;de=t+488|0;fe=t+480|0;ce=t+472|0;se=t+464|0;le=t+456|0;ae=t+448|0;ue=t+440|0;oe=t+432|0;ie=t+424|0;re=t+416|0;ne=t+408|0;te=t+400|0;ee=t+392|0;Z=t+384|0;J=t+376|0;Q=t+368|0;X=t+360|0;K=t+352|0;Y=t+344|0;$=t+336|0;G=t+328|0;q=t+320|0;V=t+312|0;H=t+304|0;W=t+296|0;z=t+288|0;U=t+280|0;j=t+272|0;B=t+264|0;L=t+256|0;F=t+248|0;R=t+240|0;M=t+232|0;N=t+224|0;I=t+216|0;P=t+208|0;O=t+200|0;A=t+192|0;x=t+184|0;T=t+176|0;k=t+168|0;C=t+160|0;S=t+152|0;D=t+144|0;E=t+136|0;w=t+128|0;b=t+120|0;_=t+112|0;y=t+104|0;g=t+96|0;m=t+88|0;v=t+80|0;p=t+72|0;d=t+64|0;f=t+56|0;c=t+48|0;s=t+40|0;l=t+32|0;a=t+24|0;u=t+16|0;i=t+8|0;r=t;la(e,3646);sa(e,3651,2)|0;ca(e,3665,2)|0;fa(e,3682,18)|0;o[Ie>>2]=19;o[Ie+4>>2]=0;o[n>>2]=o[Ie>>2];o[n+4>>2]=o[Ie+4>>2];da(e,3690,n)|0;o[Pe>>2]=1;o[Pe+4>>2]=0;o[n>>2]=o[Pe>>2];o[n+4>>2]=o[Pe+4>>2];pa(e,3696,n)|0;o[Oe>>2]=2;o[Oe+4>>2]=0;o[n>>2]=o[Oe>>2];o[n+4>>2]=o[Oe+4>>2];ha(e,3706,n)|0;o[Ae>>2]=1;o[Ae+4>>2]=0;o[n>>2]=o[Ae>>2];o[n+4>>2]=o[Ae+4>>2];va(e,3722,n)|0;o[xe>>2]=2;o[xe+4>>2]=0;o[n>>2]=o[xe>>2];o[n+4>>2]=o[xe+4>>2];va(e,3734,n)|0;o[Te>>2]=3;o[Te+4>>2]=0;o[n>>2]=o[Te>>2];o[n+4>>2]=o[Te+4>>2];ha(e,3753,n)|0;o[ke>>2]=4;o[ke+4>>2]=0;o[n>>2]=o[ke>>2];o[n+4>>2]=o[ke+4>>2];ha(e,3769,n)|0;o[Ce>>2]=5;o[Ce+4>>2]=0;o[n>>2]=o[Ce>>2];o[n+4>>2]=o[Ce+4>>2];ha(e,3783,n)|0;o[Se>>2]=6;o[Se+4>>2]=0;o[n>>2]=o[Se>>2];o[n+4>>2]=o[Se+4>>2];ha(e,3796,n)|0;o[De>>2]=7;o[De+4>>2]=0;o[n>>2]=o[De>>2];o[n+4>>2]=o[De+4>>2];ha(e,3813,n)|0;o[Ee>>2]=8;o[Ee+4>>2]=0;o[n>>2]=o[Ee>>2];o[n+4>>2]=o[Ee+4>>2];ha(e,3825,n)|0;o[we>>2]=3;o[we+4>>2]=0;o[n>>2]=o[we>>2];o[n+4>>2]=o[we+4>>2];va(e,3843,n)|0;o[be>>2]=4;o[be+4>>2]=0;o[n>>2]=o[be>>2];o[n+4>>2]=o[be+4>>2];va(e,3853,n)|0;o[_e>>2]=9;o[_e+4>>2]=0;o[n>>2]=o[_e>>2];o[n+4>>2]=o[_e+4>>2];ha(e,3870,n)|0;o[ye>>2]=10;o[ye+4>>2]=0;o[n>>2]=o[ye>>2];o[n+4>>2]=o[ye+4>>2];ha(e,3884,n)|0;o[ge>>2]=11;o[ge+4>>2]=0;o[n>>2]=o[ge>>2];o[n+4>>2]=o[ge+4>>2];ha(e,3896,n)|0;o[me>>2]=1;o[me+4>>2]=0;o[n>>2]=o[me>>2];o[n+4>>2]=o[me+4>>2];ma(e,3907,n)|0;o[ve>>2]=2;o[ve+4>>2]=0;o[n>>2]=o[ve>>2];o[n+4>>2]=o[ve+4>>2];ma(e,3915,n)|0;o[he>>2]=3;o[he+4>>2]=0;o[n>>2]=o[he>>2];o[n+4>>2]=o[he+4>>2];ma(e,3928,n)|0;o[pe>>2]=4;o[pe+4>>2]=0;o[n>>2]=o[pe>>2];o[n+4>>2]=o[pe+4>>2];ma(e,3948,n)|0;o[de>>2]=5;o[de+4>>2]=0;o[n>>2]=o[de>>2];o[n+4>>2]=o[de+4>>2];ma(e,3960,n)|0;o[fe>>2]=6;o[fe+4>>2]=0;o[n>>2]=o[fe>>2];o[n+4>>2]=o[fe+4>>2];ma(e,3974,n)|0;o[ce>>2]=7;o[ce+4>>2]=0;o[n>>2]=o[ce>>2];o[n+4>>2]=o[ce+4>>2];ma(e,3983,n)|0;o[se>>2]=20;o[se+4>>2]=0;o[n>>2]=o[se>>2];o[n+4>>2]=o[se+4>>2];da(e,3999,n)|0;o[le>>2]=8;o[le+4>>2]=0;o[n>>2]=o[le>>2];o[n+4>>2]=o[le+4>>2];ma(e,4012,n)|0;o[ae>>2]=9;o[ae+4>>2]=0;o[n>>2]=o[ae>>2];o[n+4>>2]=o[ae+4>>2];ma(e,4022,n)|0;o[ue>>2]=21;o[ue+4>>2]=0;o[n>>2]=o[ue>>2];o[n+4>>2]=o[ue+4>>2];da(e,4039,n)|0;o[oe>>2]=10;o[oe+4>>2]=0;o[n>>2]=o[oe>>2];o[n+4>>2]=o[oe+4>>2];ma(e,4053,n)|0;o[ie>>2]=11;o[ie+4>>2]=0;o[n>>2]=o[ie>>2];o[n+4>>2]=o[ie+4>>2];ma(e,4065,n)|0;o[re>>2]=12;o[re+4>>2]=0;o[n>>2]=o[re>>2];o[n+4>>2]=o[re+4>>2];ma(e,4084,n)|0;o[ne>>2]=13;o[ne+4>>2]=0;o[n>>2]=o[ne>>2];o[n+4>>2]=o[ne+4>>2];ma(e,4097,n)|0;o[te>>2]=14;o[te+4>>2]=0;o[n>>2]=o[te>>2];o[n+4>>2]=o[te+4>>2];ma(e,4117,n)|0;o[ee>>2]=15;o[ee+4>>2]=0;o[n>>2]=o[ee>>2];o[n+4>>2]=o[ee+4>>2];ma(e,4129,n)|0;o[Z>>2]=16;o[Z+4>>2]=0;o[n>>2]=o[Z>>2];o[n+4>>2]=o[Z+4>>2];ma(e,4148,n)|0;o[J>>2]=17;o[J+4>>2]=0;o[n>>2]=o[J>>2];o[n+4>>2]=o[J+4>>2];ma(e,4161,n)|0;o[Q>>2]=18;o[Q+4>>2]=0;o[n>>2]=o[Q>>2];o[n+4>>2]=o[Q+4>>2];ma(e,4181,n)|0;o[X>>2]=5;o[X+4>>2]=0;o[n>>2]=o[X>>2];o[n+4>>2]=o[X+4>>2];va(e,4196,n)|0;o[K>>2]=6;o[K+4>>2]=0;o[n>>2]=o[K>>2];o[n+4>>2]=o[K+4>>2];va(e,4206,n)|0;o[Y>>2]=7;o[Y+4>>2]=0;o[n>>2]=o[Y>>2];o[n+4>>2]=o[Y+4>>2];va(e,4217,n)|0;o[$>>2]=3;o[$+4>>2]=0;o[n>>2]=o[$>>2];o[n+4>>2]=o[$+4>>2];ga(e,4235,n)|0;o[G>>2]=1;o[G+4>>2]=0;o[n>>2]=o[G>>2];o[n+4>>2]=o[G+4>>2];ya(e,4251,n)|0;o[q>>2]=4;o[q+4>>2]=0;o[n>>2]=o[q>>2];o[n+4>>2]=o[q+4>>2];ga(e,4263,n)|0;o[V>>2]=5;o[V+4>>2]=0;o[n>>2]=o[V>>2];o[n+4>>2]=o[V+4>>2];ga(e,4279,n)|0;o[H>>2]=6;o[H+4>>2]=0;o[n>>2]=o[H>>2];o[n+4>>2]=o[H+4>>2];ga(e,4293,n)|0;o[W>>2]=7;o[W+4>>2]=0;o[n>>2]=o[W>>2];o[n+4>>2]=o[W+4>>2];ga(e,4306,n)|0;o[z>>2]=8;o[z+4>>2]=0;o[n>>2]=o[z>>2];o[n+4>>2]=o[z+4>>2];ga(e,4323,n)|0;o[U>>2]=9;o[U+4>>2]=0;o[n>>2]=o[U>>2];o[n+4>>2]=o[U+4>>2];ga(e,4335,n)|0;o[j>>2]=2;o[j+4>>2]=0;o[n>>2]=o[j>>2];o[n+4>>2]=o[j+4>>2];ya(e,4353,n)|0;o[B>>2]=12;o[B+4>>2]=0;o[n>>2]=o[B>>2];o[n+4>>2]=o[B+4>>2];_a(e,4363,n)|0;o[L>>2]=1;o[L+4>>2]=0;o[n>>2]=o[L>>2];o[n+4>>2]=o[L+4>>2];ba(e,4376,n)|0;o[F>>2]=2;o[F+4>>2]=0;o[n>>2]=o[F>>2];o[n+4>>2]=o[F+4>>2];ba(e,4388,n)|0;o[R>>2]=13;o[R+4>>2]=0;o[n>>2]=o[R>>2];o[n+4>>2]=o[R+4>>2];_a(e,4402,n)|0;o[M>>2]=14;o[M+4>>2]=0;o[n>>2]=o[M>>2];o[n+4>>2]=o[M+4>>2];_a(e,4411,n)|0;o[N>>2]=15;o[N+4>>2]=0;o[n>>2]=o[N>>2];o[n+4>>2]=o[N+4>>2];_a(e,4421,n)|0;o[I>>2]=16;o[I+4>>2]=0;o[n>>2]=o[I>>2];o[n+4>>2]=o[I+4>>2];_a(e,4433,n)|0;o[P>>2]=17;o[P+4>>2]=0;o[n>>2]=o[P>>2];o[n+4>>2]=o[P+4>>2];_a(e,4446,n)|0;o[O>>2]=18;o[O+4>>2]=0;o[n>>2]=o[O>>2];o[n+4>>2]=o[O+4>>2];_a(e,4458,n)|0;o[A>>2]=3;o[A+4>>2]=0;o[n>>2]=o[A>>2];o[n+4>>2]=o[A+4>>2];ba(e,4471,n)|0;o[x>>2]=1;o[x+4>>2]=0;o[n>>2]=o[x>>2];o[n+4>>2]=o[x+4>>2];wa(e,4486,n)|0;o[T>>2]=10;o[T+4>>2]=0;o[n>>2]=o[T>>2];o[n+4>>2]=o[T+4>>2];ga(e,4496,n)|0;o[k>>2]=11;o[k+4>>2]=0;o[n>>2]=o[k>>2];o[n+4>>2]=o[k+4>>2];ga(e,4508,n)|0;o[C>>2]=3;o[C+4>>2]=0;o[n>>2]=o[C>>2];o[n+4>>2]=o[C+4>>2];ya(e,4519,n)|0;o[S>>2]=4;o[S+4>>2]=0;o[n>>2]=o[S>>2];o[n+4>>2]=o[S+4>>2];Ea(e,4530,n)|0;o[D>>2]=19;o[D+4>>2]=0;o[n>>2]=o[D>>2];o[n+4>>2]=o[D+4>>2];Da(e,4542,n)|0;o[E>>2]=12;o[E+4>>2]=0;o[n>>2]=o[E>>2];o[n+4>>2]=o[E+4>>2];Sa(e,4554,n)|0;o[w>>2]=13;o[w+4>>2]=0;o[n>>2]=o[w>>2];o[n+4>>2]=o[w+4>>2];Ca(e,4568,n)|0;o[b>>2]=2;o[b+4>>2]=0;o[n>>2]=o[b>>2];o[n+4>>2]=o[b+4>>2];ka(e,4578,n)|0;o[_>>2]=20;o[_+4>>2]=0;o[n>>2]=o[_>>2];o[n+4>>2]=o[_+4>>2];Ta(e,4587,n)|0;o[y>>2]=22;o[y+4>>2]=0;o[n>>2]=o[y>>2];o[n+4>>2]=o[y+4>>2];da(e,4602,n)|0;o[g>>2]=23;o[g+4>>2]=0;o[n>>2]=o[g>>2];o[n+4>>2]=o[g+4>>2];da(e,4619,n)|0;o[m>>2]=14;o[m+4>>2]=0;o[n>>2]=o[m>>2];o[n+4>>2]=o[m+4>>2];xa(e,4629,n)|0;o[v>>2]=1;o[v+4>>2]=0;o[n>>2]=o[v>>2];o[n+4>>2]=o[v+4>>2];Aa(e,4637,n)|0;o[p>>2]=4;o[p+4>>2]=0;o[n>>2]=o[p>>2];o[n+4>>2]=o[p+4>>2];ba(e,4653,n)|0;o[d>>2]=5;o[d+4>>2]=0;o[n>>2]=o[d>>2];o[n+4>>2]=o[d+4>>2];ba(e,4669,n)|0;o[f>>2]=6;o[f+4>>2]=0;o[n>>2]=o[f>>2];o[n+4>>2]=o[f+4>>2];ba(e,4686,n)|0;o[c>>2]=7;o[c+4>>2]=0;o[n>>2]=o[c>>2];o[n+4>>2]=o[c+4>>2];ba(e,4701,n)|0;o[s>>2]=8;o[s+4>>2]=0;o[n>>2]=o[s>>2];o[n+4>>2]=o[s+4>>2];ba(e,4719,n)|0;o[l>>2]=9;o[l+4>>2]=0;o[n>>2]=o[l>>2];o[n+4>>2]=o[l+4>>2];ba(e,4736,n)|0;o[a>>2]=21;o[a+4>>2]=0;o[n>>2]=o[a>>2];o[n+4>>2]=o[a+4>>2];Oa(e,4754,n)|0;o[u>>2]=2;o[u+4>>2]=0;o[n>>2]=o[u>>2];o[n+4>>2]=o[u+4>>2];wa(e,4772,n)|0;o[i>>2]=3;o[i+4>>2]=0;o[n>>2]=o[i>>2];o[n+4>>2]=o[i+4>>2];wa(e,4790,n)|0;o[r>>2]=4;o[r+4>>2]=0;o[n>>2]=o[r>>2];o[n+4>>2]=o[r+4>>2];wa(e,4808,n)|0;h=t;return}function la(e,t){e=e|0;t=t|0;var n=0;n=Mm()|0;o[e>>2]=n;Rm(n,t);cw(o[e>>2]|0);return}function sa(e,t,n){e=e|0;t=t|0;n=n|0;gm(e,Ia(t)|0,n,0);return e|0}function ca(e,t,n){e=e|0;t=t|0;n=n|0;Xv(e,Ia(t)|0,n,0);return e|0}function fa(e,t,n){e=e|0;t=t|0;n=n|0;Nv(e,Ia(t)|0,n,0);return e|0}function da(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];hv(e,t,i);h=r;return e|0}function pa(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Gh(e,t,i);h=r;return e|0}function ha(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Th(e,t,i);h=r;return e|0}function va(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];lh(e,t,i);h=r;return e|0}function ma(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Hp(e,t,i);h=r;return e|0}function ga(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Sp(e,t,i);h=r;return e|0}function ya(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];op(e,t,i);h=r;return e|0}function _a(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Cd(e,t,i);h=r;return e|0}function ba(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];ud(e,t,i);h=r;return e|0}function wa(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];zf(e,t,i);h=r;return e|0}function Ea(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Ef(e,t,i);h=r;return e|0}function Da(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Zc(e,t,i);h=r;return e|0}function Sa(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Nc(e,t,i);h=r;return e|0}function Ca(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];hc(e,t,i);h=r;return e|0}function ka(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];qs(e,t,i);h=r;return e|0}function Ta(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];ws(e,t,i);h=r;return e|0}function xa(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];ts(e,t,i);h=r;return e|0}function Aa(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Ol(e,t,i);h=r;return e|0}function Oa(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Pa(e,t,i);h=r;return e|0}function Pa(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Na(e,n,i,1);h=r;return}function Ia(e){e=e|0;return e|0}function Na(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=Ma()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=Ra(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,Fa(u,r)|0,r);h=i;return}function Ma(){var e=0,t=0;if(!(r[7616]|0)){Ya(9136);Fe(24,9136,g|0)|0;t=7616;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9136)|0)){e=9136;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));Ya(9136)}return 9136}function Ra(e){e=e|0;return 0}function Fa(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=Ma()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];Wa(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{Ha(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function La(e,t,n,r,i,u){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;u=u|0;var a=0,l=0,s=0,c=0,f=0,d=0,p=0,v=0;a=h;h=h+32|0;p=a+24|0;d=a+20|0;s=a+16|0;f=a+12|0;c=a+8|0;l=a+4|0;v=a;o[d>>2]=t;o[s>>2]=n;o[f>>2]=r;o[c>>2]=i;o[l>>2]=u;u=e+28|0;o[v>>2]=o[u>>2];o[p>>2]=o[v>>2];Ba(e+24|0,p,d,f,c,s,l)|0;o[u>>2]=o[o[u>>2]>>2];h=a;return}function Ba(e,t,n,r,i,u,a){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;u=u|0;a=a|0;e=ja(t)|0;t=$T(24)|0;Ua(t+4|0,o[n>>2]|0,o[r>>2]|0,o[i>>2]|0,o[u>>2]|0,o[a>>2]|0);o[t>>2]=o[e>>2];o[e>>2]=t;return t|0}function ja(e){e=e|0;return o[e>>2]|0}function Ua(e,t,n,r,i,u){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;u=u|0;o[e>>2]=t;o[e+4>>2]=n;o[e+8>>2]=r;o[e+12>>2]=i;o[e+16>>2]=u;return}function za(e,t){e=e|0;t=t|0;return t|e|0}function Wa(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function Ha(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=Va(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;qa(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];Wa(u,r,n);o[s>>2]=(o[s>>2]|0)+12;Ga(e,l);$a(l);h=c;return}}function Va(e){e=e|0;return 357913941}function qa(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function Ga(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function $a(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function Ya(e){e=e|0;Ja(e);return}function Ka(e){e=e|0;Qa(e+24|0);return}function Xa(e){e=e|0;return o[e>>2]|0}function Qa(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function Ja(e){e=e|0;var t=0;t=Za()|0;nl(e,2,3,t,el()|0,0);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function Za(){return 9228}function el(){return 1140}function tl(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0;n=h;h=h+16|0;r=n+8|0;i=n;u=rl(e)|0;e=o[u+4>>2]|0;o[i>>2]=o[u>>2];o[i+4>>2]=e;o[r>>2]=o[i>>2];o[r+4>>2]=o[i+4>>2];t=il(t,r)|0;h=n;return t|0}function nl(e,t,n,r,i,u){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;u=u|0;o[e>>2]=t;o[e+4>>2]=n;o[e+8>>2]=r;o[e+12>>2]=i;o[e+16>>2]=u;return}function rl(e){e=e|0;return(o[(Ma()|0)+24>>2]|0)+(e*12|0)|0}function il(e,t){e=e|0;t=t|0;var n=0,r=0,i=0;i=h;h=h+48|0;r=i;n=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)n=o[(o[e>>2]|0)+n>>2]|0;vA[n&31](r,e);r=ol(r)|0;h=i;return r|0}function ol(e){e=e|0;var t=0,n=0,r=0,i=0;i=h;h=h+32|0;t=i+12|0;n=i;r=al(ul()|0)|0;if(!r)e=dl(e)|0;else{ll(t,r);sl(n,t);cl(e,n);e=fl(t)|0}h=i;return e|0}function ul(){var e=0;if(!(r[7632]|0)){Dl(9184);Fe(25,9184,g|0)|0;e=7632;o[e>>2]=1;o[e+4>>2]=0}return 9184}function al(e){e=e|0;return o[e+36>>2]|0}function ll(e,t){e=e|0;t=t|0;o[e>>2]=t;o[e+4>>2]=e;o[e+8>>2]=0;return}function sl(e,t){e=e|0;t=t|0;o[e>>2]=o[t>>2];o[e+4>>2]=o[t+4>>2];o[e+8>>2]=0;return}function cl(e,t){e=e|0;t=t|0;gl(t,e,e+8|0,e+16|0,e+24|0,e+32|0,e+40|0)|0;return}function fl(e){e=e|0;return o[(o[e+4>>2]|0)+8>>2]|0}function dl(e){e=e|0;var t=0,n=0,r=0,i=0,u=0,a=0,l=0,s=0;s=h;h=h+16|0;n=s+4|0;r=s;i=UD(8)|0;u=i;a=$T(48)|0;l=a;t=l+48|0;do{o[l>>2]=o[e>>2];l=l+4|0;e=e+4|0}while((l|0)<(t|0));t=u+4|0;o[t>>2]=a;l=$T(8)|0;a=o[t>>2]|0;o[r>>2]=0;o[n>>2]=o[r>>2];pl(l,a,n);o[i>>2]=l;h=s;return u|0}function pl(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;n=$T(16)|0;o[n+4>>2]=0;o[n+8>>2]=0;o[n>>2]=1092;o[n+12>>2]=t;o[e+4>>2]=n;return}function hl(e){e=e|0;zT(e);KT(e);return}function vl(e){e=e|0;e=o[e+12>>2]|0;if(e|0)KT(e);return}function ml(e){e=e|0;KT(e);return}function gl(e,t,n,r,i,u,a){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;u=u|0;a=a|0;u=yl(o[e>>2]|0,t,n,r,i,u,a)|0;a=e+4|0;o[(o[a>>2]|0)+8>>2]=u;return o[(o[a>>2]|0)+8>>2]|0}function yl(e,t,n,r,i,o,u){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;o=o|0;u=u|0;var a=0,l=0;a=h;h=h+16|0;l=a;Dk(l);e=Eu(e)|0;u=_l(e,+c[t>>3],+c[n>>3],+c[r>>3],+c[i>>3],+c[o>>3],+c[u>>3])|0;Ck(l);h=a;return u|0}function _l(e,t,n,r,i,o,u){e=e|0;t=+t;n=+n;r=+r;i=+i;o=+o;u=+u;var a=0;a=Cu(bl()|0)|0;t=+ku(t);n=+ku(n);r=+ku(r);i=+ku(i);o=+ku(o);return Te(0,a|0,e|0,+t,+n,+r,+i,+o,+ +ku(u))|0}function bl(){var e=0;if(!(r[7624]|0)){wl(9172);e=7624;o[e>>2]=1;o[e+4>>2]=0}return 9172}function wl(e){e=e|0;Lu(e,El()|0,6);return}function El(){return 1112}function Dl(e){e=e|0;Al(e);return}function Sl(e){e=e|0;Cl(e+24|0);kl(e+16|0);return}function Cl(e){e=e|0;xl(e);return}function kl(e){e=e|0;Tl(e);return}function Tl(e){e=e|0;var t=0,n=0;t=o[e>>2]|0;if(t|0)do{n=t;t=o[t>>2]|0;KT(n)}while((t|0)!=0);o[e>>2]=0;return}function xl(e){e=e|0;var t=0,n=0;t=o[e>>2]|0;if(t|0)do{n=t;t=o[t>>2]|0;KT(n)}while((t|0)!=0);o[e>>2]=0;return}function Al(e){e=e|0;var t=0;o[e+16>>2]=0;o[e+20>>2]=0;t=e+24|0;o[t>>2]=0;o[e+28>>2]=t;o[e+36>>2]=0;r[e+40>>0]=0;r[e+41>>0]=0;return}function Ol(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Pl(e,n,i,0);h=r;return}function Pl(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=Il()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=Nl(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,Ml(u,r)|0,r);h=i;return}function Il(){var e=0,t=0;if(!(r[7640]|0)){zl(9232);Fe(26,9232,g|0)|0;t=7640;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9232)|0)){e=9232;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));zl(9232)}return 9232}function Nl(e){e=e|0;return 0}function Ml(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=Il()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];Rl(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{Fl(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function Rl(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function Fl(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=Ll(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;Bl(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];Rl(u,r,n);o[s>>2]=(o[s>>2]|0)+12;jl(e,l);Ul(l);h=c;return}}function Ll(e){e=e|0;return 357913941}function Bl(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function jl(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function Ul(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function zl(e){e=e|0;Vl(e);return}function Wl(e){e=e|0;Hl(e+24|0);return}function Hl(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function Vl(e){e=e|0;var t=0;t=Za()|0;nl(e,2,1,t,ql()|0,3);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function ql(){return 1144}function Gl(e,t,n,r,i){e=e|0;t=t|0;n=+n;r=+r;i=i|0;var u=0,a=0,l=0,s=0;u=h;h=h+16|0;a=u+8|0;l=u;s=$l(e)|0;e=o[s+4>>2]|0;o[l>>2]=o[s>>2];o[l+4>>2]=e;o[a>>2]=o[l>>2];o[a+4>>2]=o[l+4>>2];Yl(t,a,n,r,i);h=u;return}function $l(e){e=e|0;return(o[(Il()|0)+24>>2]|0)+(e*12|0)|0}function Yl(e,t,n,r,i){e=e|0;t=t|0;n=+n;r=+r;i=i|0;var u=0,a=0,l=0,s=0,c=0;c=h;h=h+16|0;a=c+2|0;l=c+1|0;s=c;u=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)u=o[(o[e>>2]|0)+u>>2]|0;Kl(a,n);n=+Xl(a,n);Kl(l,r);r=+Xl(l,r);Ql(s,i);s=Jl(s,i)|0;gA[u&1](e,n,r,s);h=c;return}function Kl(e,t){e=e|0;t=+t;return}function Xl(e,t){e=e|0;t=+t;return+ +es(t)}function Ql(e,t){e=e|0;t=t|0;return}function Jl(e,t){e=e|0;t=t|0;return Zl(t)|0}function Zl(e){e=e|0;return e|0}function es(e){e=+e;return+e}function ts(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];ns(e,n,i,1);h=r;return}function ns(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=rs()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=is(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,os(u,r)|0,r);h=i;return}function rs(){var e=0,t=0;if(!(r[7648]|0)){ds(9268);Fe(27,9268,g|0)|0;t=7648;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9268)|0)){e=9268;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));ds(9268)}return 9268}function is(e){e=e|0;return 0}function os(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=rs()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];us(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{as(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function us(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function as(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=ls(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;ss(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];us(u,r,n);o[s>>2]=(o[s>>2]|0)+12;cs(e,l);fs(l);h=c;return}}function ls(e){e=e|0;return 357913941}function ss(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function cs(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function fs(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function ds(e){e=e|0;vs(e);return}function ps(e){e=e|0;hs(e+24|0);return}function hs(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function vs(e){e=e|0;var t=0;t=Za()|0;nl(e,2,4,t,ms()|0,0);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function ms(){return 1160}function gs(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0;n=h;h=h+16|0;r=n+8|0;i=n;u=ys(e)|0;e=o[u+4>>2]|0;o[i>>2]=o[u>>2];o[i+4>>2]=e;o[r>>2]=o[i>>2];o[r+4>>2]=o[i+4>>2];t=_s(t,r)|0;h=n;return t|0}function ys(e){e=e|0;return(o[(rs()|0)+24>>2]|0)+(e*12|0)|0}function _s(e,t){e=e|0;t=t|0;var n=0;n=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)n=o[(o[e>>2]|0)+n>>2]|0;return bs(mA[n&31](e)|0)|0}function bs(e){e=e|0;return e&1|0}function ws(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Es(e,n,i,0);h=r;return}function Es(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=Ds()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=Ss(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,Cs(u,r)|0,r);h=i;return}function Ds(){var e=0,t=0;if(!(r[7656]|0)){Is(9304);Fe(28,9304,g|0)|0;t=7656;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9304)|0)){e=9304;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));Is(9304)}return 9304}function Ss(e){e=e|0;return 0}function Cs(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=Ds()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];ks(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{Ts(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function ks(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function Ts(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=xs(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;As(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];ks(u,r,n);o[s>>2]=(o[s>>2]|0)+12;Os(e,l);Ps(l);h=c;return}}function xs(e){e=e|0;return 357913941}function As(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function Os(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function Ps(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function Is(e){e=e|0;Rs(e);return}function Ns(e){e=e|0;Ms(e+24|0);return}function Ms(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function Rs(e){e=e|0;var t=0;t=Za()|0;nl(e,2,5,t,Fs()|0,1);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function Fs(){return 1164}function Ls(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=Bs(e)|0;e=o[a+4>>2]|0;o[u>>2]=o[a>>2];o[u+4>>2]=e;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];js(t,i,n);h=r;return}function Bs(e){e=e|0;return(o[(Ds()|0)+24>>2]|0)+(e*12|0)|0}function js(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0;u=h;h=h+16|0;i=u;r=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)r=o[(o[e>>2]|0)+r>>2]|0;Us(i,n);n=zs(i,n)|0;vA[r&31](e,n);Ws(i);h=u;return}function Us(e,t){e=e|0;t=t|0;Hs(e,t);return}function zs(e,t){e=e|0;t=t|0;return e|0}function Ws(e){e=e|0;Ji(e);return}function Hs(e,t){e=e|0;t=t|0;Vs(e,t);return}function Vs(e,t){e=e|0;t=t|0;o[e>>2]=t;return}function qs(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Gs(e,n,i,0);h=r;return}function Gs(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=$s()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=Ys(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,Ks(u,r)|0,r);h=i;return}function $s(){var e=0,t=0;if(!(r[7664]|0)){nc(9340);Fe(29,9340,g|0)|0;t=7664;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9340)|0)){e=9340;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));nc(9340)}return 9340}function Ys(e){e=e|0;return 0}function Ks(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=$s()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];Xs(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{Qs(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function Xs(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function Qs(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=Js(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;Zs(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];Xs(u,r,n);o[s>>2]=(o[s>>2]|0)+12;ec(e,l);tc(l);h=c;return}}function Js(e){e=e|0;return 357913941}function Zs(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function ec(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function tc(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function nc(e){e=e|0;oc(e);return}function rc(e){e=e|0;ic(e+24|0);return}function ic(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function oc(e){e=e|0;var t=0;t=Za()|0;nl(e,2,4,t,uc()|0,1);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function uc(){return 1180}function ac(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=lc(e)|0;e=o[a+4>>2]|0;o[u>>2]=o[a>>2];o[u+4>>2]=e;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];n=sc(t,i,n)|0;h=r;return n|0}function lc(e){e=e|0;return(o[($s()|0)+24>>2]|0)+(e*12|0)|0}function sc(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0;u=h;h=h+16|0;i=u;r=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)r=o[(o[e>>2]|0)+r>>2]|0;cc(i,n);i=fc(i,n)|0;i=dc(DA[r&15](e,i)|0)|0;h=u;return i|0}function cc(e,t){e=e|0;t=t|0;return}function fc(e,t){e=e|0;t=t|0;return pc(t)|0}function dc(e){e=e|0;return e|0}function pc(e){e=e|0;return e|0}function hc(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];vc(e,n,i,0);h=r;return}function vc(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=mc()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=gc(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,yc(u,r)|0,r);h=i;return}function mc(){var e=0,t=0;if(!(r[7672]|0)){Cc(9376);Fe(30,9376,g|0)|0;t=7672;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9376)|0)){e=9376;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));Cc(9376)}return 9376}function gc(e){e=e|0;return 0}function yc(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=mc()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];_c(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{bc(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function _c(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function bc(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=wc(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;Ec(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];_c(u,r,n);o[s>>2]=(o[s>>2]|0)+12;Dc(e,l);Sc(l);h=c;return}}function wc(e){e=e|0;return 357913941}function Ec(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function Dc(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function Sc(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function Cc(e){e=e|0;xc(e);return}function kc(e){e=e|0;Tc(e+24|0);return}function Tc(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function xc(e){e=e|0;var t=0;t=Za()|0;nl(e,2,5,t,Ac()|0,0);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function Ac(){return 1196}function Oc(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0;n=h;h=h+16|0;r=n+8|0;i=n;u=Pc(e)|0;e=o[u+4>>2]|0;o[i>>2]=o[u>>2];o[i+4>>2]=e;o[r>>2]=o[i>>2];o[r+4>>2]=o[i+4>>2];t=Ic(t,r)|0;h=n;return t|0}function Pc(e){e=e|0;return(o[(mc()|0)+24>>2]|0)+(e*12|0)|0}function Ic(e,t){e=e|0;t=t|0;var n=0;n=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)n=o[(o[e>>2]|0)+n>>2]|0;return dc(mA[n&31](e)|0)|0}function Nc(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Mc(e,n,i,1);h=r;return}function Mc(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=Rc()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=Fc(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,Lc(u,r)|0,r);h=i;return}function Rc(){var e=0,t=0;if(!(r[7680]|0)){Vc(9412);Fe(31,9412,g|0)|0;t=7680;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9412)|0)){e=9412;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));Vc(9412)}return 9412}function Fc(e){e=e|0;return 0}function Lc(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=Rc()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];Bc(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{jc(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function Bc(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function jc(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=Uc(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;zc(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];Bc(u,r,n);o[s>>2]=(o[s>>2]|0)+12;Wc(e,l);Hc(l);h=c;return}}function Uc(e){e=e|0;return 357913941}function zc(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function Wc(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function Hc(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function Vc(e){e=e|0;$c(e);return}function qc(e){e=e|0;Gc(e+24|0);return}function Gc(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function $c(e){e=e|0;var t=0;t=Za()|0;nl(e,2,6,t,Yc()|0,0);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function Yc(){return 1200}function Kc(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0;n=h;h=h+16|0;r=n+8|0;i=n;u=Xc(e)|0;e=o[u+4>>2]|0;o[i>>2]=o[u>>2];o[i+4>>2]=e;o[r>>2]=o[i>>2];o[r+4>>2]=o[i+4>>2];t=Qc(t,r)|0;h=n;return t|0}function Xc(e){e=e|0;return(o[(Rc()|0)+24>>2]|0)+(e*12|0)|0}function Qc(e,t){e=e|0;t=t|0;var n=0;n=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)n=o[(o[e>>2]|0)+n>>2]|0;return Jc(mA[n&31](e)|0)|0}function Jc(e){e=e|0;return e|0}function Zc(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];ef(e,n,i,0);h=r;return}function ef(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=tf()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=nf(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,rf(u,r)|0,r);h=i;return}function tf(){var e=0,t=0;if(!(r[7688]|0)){ff(9448);Fe(32,9448,g|0)|0;t=7688;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9448)|0)){e=9448;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));ff(9448)}return 9448}function nf(e){e=e|0;return 0}function rf(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=tf()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];of(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{uf(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function of(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function uf(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=af(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;lf(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];of(u,r,n);o[s>>2]=(o[s>>2]|0)+12;sf(e,l);cf(l);h=c;return}}function af(e){e=e|0;return 357913941}function lf(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function sf(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function cf(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function ff(e){e=e|0;hf(e);return}function df(e){e=e|0;pf(e+24|0);return}function pf(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function hf(e){e=e|0;var t=0;t=Za()|0;nl(e,2,6,t,vf()|0,1);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function vf(){return 1204}function mf(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=gf(e)|0;e=o[a+4>>2]|0;o[u>>2]=o[a>>2];o[u+4>>2]=e;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];yf(t,i,n);h=r;return}function gf(e){e=e|0;return(o[(tf()|0)+24>>2]|0)+(e*12|0)|0}function yf(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0;u=h;h=h+16|0;i=u;r=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)r=o[(o[e>>2]|0)+r>>2]|0;_f(i,n);i=bf(i,n)|0;vA[r&31](e,i);h=u;return}function _f(e,t){e=e|0;t=t|0;return}function bf(e,t){e=e|0;t=t|0;return wf(t)|0}function wf(e){e=e|0;return e|0}function Ef(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Df(e,n,i,0);h=r;return}function Df(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=Sf()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=Cf(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,kf(u,r)|0,r);h=i;return}function Sf(){var e=0,t=0;if(!(r[7696]|0)){Nf(9484);Fe(33,9484,g|0)|0;t=7696;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9484)|0)){e=9484;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));Nf(9484)}return 9484}function Cf(e){e=e|0;return 0}function kf(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=Sf()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];Tf(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{xf(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function Tf(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function xf(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=Af(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;Of(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];Tf(u,r,n);o[s>>2]=(o[s>>2]|0)+12;Pf(e,l);If(l);h=c;return}}function Af(e){e=e|0;return 357913941}function Of(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function Pf(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function If(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function Nf(e){e=e|0;Ff(e);return}function Mf(e){e=e|0;Rf(e+24|0);return}function Rf(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function Ff(e){e=e|0;var t=0;t=Za()|0;nl(e,2,1,t,Lf()|0,2);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function Lf(){return 1212}function Bf(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0;i=h;h=h+16|0;u=i+8|0;a=i;l=jf(e)|0;e=o[l+4>>2]|0;o[a>>2]=o[l>>2];o[a+4>>2]=e;o[u>>2]=o[a>>2];o[u+4>>2]=o[a+4>>2];Uf(t,u,n,r);h=i;return}function jf(e){e=e|0;return(o[(Sf()|0)+24>>2]|0)+(e*12|0)|0}function Uf(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0;l=h;h=h+16|0;u=l+1|0;a=l;i=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)i=o[(o[e>>2]|0)+i>>2]|0;_f(u,n);u=bf(u,n)|0;cc(a,r);a=fc(a,r)|0;PA[i&15](e,u,a);h=l;return}function zf(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Wf(e,n,i,1);h=r;return}function Wf(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=Hf()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=Vf(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,qf(u,r)|0,r);h=i;return}function Hf(){var e=0,t=0;if(!(r[7704]|0)){Jf(9520);Fe(34,9520,g|0)|0;t=7704;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9520)|0)){e=9520;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));Jf(9520)}return 9520}function Vf(e){e=e|0;return 0}function qf(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=Hf()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];Gf(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{$f(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function Gf(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function $f(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=Yf(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;Kf(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];Gf(u,r,n);o[s>>2]=(o[s>>2]|0)+12;Xf(e,l);Qf(l);h=c;return}}function Yf(e){e=e|0;return 357913941}function Kf(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function Xf(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function Qf(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function Jf(e){e=e|0;td(e);return}function Zf(e){e=e|0;ed(e+24|0);return}function ed(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function td(e){e=e|0;var t=0;t=Za()|0;nl(e,2,1,t,nd()|0,1);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function nd(){return 1224}function rd(e,t,n){e=e|0;t=t|0;n=n|0;var r=0.0,i=0,u=0,a=0,l=0;i=h;h=h+16|0;u=i+8|0;a=i;l=id(e)|0;e=o[l+4>>2]|0;o[a>>2]=o[l>>2];o[a+4>>2]=e;o[u>>2]=o[a>>2];o[u+4>>2]=o[a+4>>2];r=+od(t,u,n);h=i;return+r}function id(e){e=e|0;return(o[(Hf()|0)+24>>2]|0)+(e*12|0)|0}function od(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0.0;u=h;h=h+16|0;i=u;r=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)r=o[(o[e>>2]|0)+r>>2]|0;Ql(i,n);i=Jl(i,n)|0;a=+Mu(+kA[r&7](e,i));h=u;return+a}function ud(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];ad(e,n,i,1);h=r;return}function ad(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=ld()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=sd(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,cd(u,r)|0,r);h=i;return}function ld(){var e=0,t=0;if(!(r[7712]|0)){gd(9556);Fe(35,9556,g|0)|0;t=7712;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9556)|0)){e=9556;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));gd(9556)}return 9556}function sd(e){e=e|0;return 0}function cd(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=ld()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];fd(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{dd(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function fd(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function dd(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=pd(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;hd(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];fd(u,r,n);o[s>>2]=(o[s>>2]|0)+12;vd(e,l);md(l);h=c;return}}function pd(e){e=e|0;return 357913941}function hd(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function vd(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function md(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function gd(e){e=e|0;bd(e);return}function yd(e){e=e|0;_d(e+24|0);return}function _d(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function bd(e){e=e|0;var t=0;t=Za()|0;nl(e,2,5,t,wd()|0,0);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function wd(){return 1232}function Ed(e,t){e=e|0;t=t|0;var n=0.0,r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=Dd(e)|0;e=o[a+4>>2]|0;o[u>>2]=o[a>>2];o[u+4>>2]=e;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];n=+Sd(t,i);h=r;return+n}function Dd(e){e=e|0;return(o[(ld()|0)+24>>2]|0)+(e*12|0)|0}function Sd(e,t){e=e|0;t=t|0;var n=0;n=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)n=o[(o[e>>2]|0)+n>>2]|0;return+ +Mu(+wA[n&15](e))}function Cd(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];kd(e,n,i,1);h=r;return}function kd(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=Td()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=xd(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,Ad(u,r)|0,r);h=i;return}function Td(){var e=0,t=0;if(!(r[7720]|0)){Fd(9592);Fe(36,9592,g|0)|0;t=7720;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9592)|0)){e=9592;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));Fd(9592)}return 9592}function xd(e){e=e|0;return 0}function Ad(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=Td()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];Od(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{Pd(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function Od(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function Pd(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=Id(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;Nd(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];Od(u,r,n);o[s>>2]=(o[s>>2]|0)+12;Md(e,l);Rd(l);h=c;return}}function Id(e){e=e|0;return 357913941}function Nd(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function Md(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function Rd(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function Fd(e){e=e|0;jd(e);return}function Ld(e){e=e|0;Bd(e+24|0);return}function Bd(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function jd(e){e=e|0;var t=0;t=Za()|0;nl(e,2,7,t,Ud()|0,0);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function Ud(){return 1276}function zd(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0;n=h;h=h+16|0;r=n+8|0;i=n;u=Wd(e)|0;e=o[u+4>>2]|0;o[i>>2]=o[u>>2];o[i+4>>2]=e;o[r>>2]=o[i>>2];o[r+4>>2]=o[i+4>>2];t=Hd(t,r)|0;h=n;return t|0}function Wd(e){e=e|0;return(o[(Td()|0)+24>>2]|0)+(e*12|0)|0}function Hd(e,t){e=e|0;t=t|0;var n=0,r=0,i=0;i=h;h=h+16|0;r=i;n=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)n=o[(o[e>>2]|0)+n>>2]|0;vA[n&31](r,e);r=Vd(r)|0;h=i;return r|0}function Vd(e){e=e|0;var t=0,n=0,r=0,i=0;i=h;h=h+32|0;t=i+12|0;n=i;r=al(qd()|0)|0;if(!r)e=$d(e)|0;else{ll(t,r);sl(n,t);Gd(e,n);e=fl(t)|0}h=i;return e|0}function qd(){var e=0;if(!(r[7736]|0)){ip(9640);Fe(25,9640,g|0)|0;e=7736;o[e>>2]=1;o[e+4>>2]=0}return 9640}function Gd(e,t){e=e|0;t=t|0;Jd(t,e,e+8|0)|0;return}function $d(e){e=e|0;var t=0,n=0,r=0,i=0,u=0,a=0,l=0;n=h;h=h+16|0;i=n+4|0;a=n;r=UD(8)|0;t=r;l=$T(16)|0;o[l>>2]=o[e>>2];o[l+4>>2]=o[e+4>>2];o[l+8>>2]=o[e+8>>2];o[l+12>>2]=o[e+12>>2];u=t+4|0;o[u>>2]=l;e=$T(8)|0;u=o[u>>2]|0;o[a>>2]=0;o[i>>2]=o[a>>2];Yd(e,u,i);o[r>>2]=e;h=n;return t|0}function Yd(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;n=$T(16)|0;o[n+4>>2]=0;o[n+8>>2]=0;o[n>>2]=1244;o[n+12>>2]=t;o[e+4>>2]=n;return}function Kd(e){e=e|0;zT(e);KT(e);return}function Xd(e){e=e|0;e=o[e+12>>2]|0;if(e|0)KT(e);return}function Qd(e){e=e|0;KT(e);return}function Jd(e,t,n){e=e|0;t=t|0;n=n|0;t=Zd(o[e>>2]|0,t,n)|0;n=e+4|0;o[(o[n>>2]|0)+8>>2]=t;return o[(o[n>>2]|0)+8>>2]|0}function Zd(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0;r=h;h=h+16|0;i=r;Dk(i);e=Eu(e)|0;n=ep(e,o[t>>2]|0,+c[n>>3])|0;Ck(i);h=r;return n|0}function ep(e,t,n){e=e|0;t=t|0;n=+n;var r=0;r=Cu(tp()|0)|0;t=Tu(t)|0;return xe(0,r|0,e|0,t|0,+ +ku(n))|0}function tp(){var e=0;if(!(r[7728]|0)){np(9628);e=7728;o[e>>2]=1;o[e+4>>2]=0}return 9628}function np(e){e=e|0;Lu(e,rp()|0,2);return}function rp(){return 1264}function ip(e){e=e|0;Al(e);return}function op(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];up(e,n,i,1);h=r;return}function up(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=ap()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=lp(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,sp(u,r)|0,r);h=i;return}function ap(){var e=0,t=0;if(!(r[7744]|0)){mp(9684);Fe(37,9684,g|0)|0;t=7744;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9684)|0)){e=9684;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));mp(9684)}return 9684}function lp(e){e=e|0;return 0}function sp(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=ap()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];cp(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{fp(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function cp(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function fp(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=dp(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;pp(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];cp(u,r,n);o[s>>2]=(o[s>>2]|0)+12;hp(e,l);vp(l);h=c;return}}function dp(e){e=e|0;return 357913941}function pp(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function hp(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function vp(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function mp(e){e=e|0;_p(e);return}function gp(e){e=e|0;yp(e+24|0);return}function yp(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function _p(e){e=e|0;var t=0;t=Za()|0;nl(e,2,5,t,bp()|0,1);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function bp(){return 1280}function wp(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=Ep(e)|0;e=o[a+4>>2]|0;o[u>>2]=o[a>>2];o[u+4>>2]=e;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];n=Dp(t,i,n)|0;h=r;return n|0}function Ep(e){e=e|0;return(o[(ap()|0)+24>>2]|0)+(e*12|0)|0}function Dp(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;a=h;h=h+32|0;i=a;u=a+16|0;r=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)r=o[(o[e>>2]|0)+r>>2]|0;Ql(u,n);u=Jl(u,n)|0;PA[r&15](i,e,u);u=Vd(i)|0;h=a;return u|0}function Sp(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Cp(e,n,i,1);h=r;return}function Cp(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=kp()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=Tp(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,xp(u,r)|0,r);h=i;return}function kp(){var e=0,t=0;if(!(r[7752]|0)){Rp(9720);Fe(38,9720,g|0)|0;t=7752;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9720)|0)){e=9720;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));Rp(9720)}return 9720}function Tp(e){e=e|0;return 0}function xp(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=kp()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];Ap(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{Op(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function Ap(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function Op(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=Pp(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;Ip(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];Ap(u,r,n);o[s>>2]=(o[s>>2]|0)+12;Np(e,l);Mp(l);h=c;return}}function Pp(e){e=e|0;return 357913941}function Ip(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function Np(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function Mp(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function Rp(e){e=e|0;Bp(e);return}function Fp(e){e=e|0;Lp(e+24|0);return}function Lp(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function Bp(e){e=e|0;var t=0;t=Za()|0;nl(e,2,8,t,jp()|0,0);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function jp(){return 1288}function Up(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0;n=h;h=h+16|0;r=n+8|0;i=n;u=zp(e)|0;e=o[u+4>>2]|0;o[i>>2]=o[u>>2];o[i+4>>2]=e;o[r>>2]=o[i>>2];o[r+4>>2]=o[i+4>>2];t=Wp(t,r)|0;h=n;return t|0}function zp(e){e=e|0;return(o[(kp()|0)+24>>2]|0)+(e*12|0)|0}function Wp(e,t){e=e|0;t=t|0;var n=0;n=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)n=o[(o[e>>2]|0)+n>>2]|0;return Nu(mA[n&31](e)|0)|0}function Hp(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Vp(e,n,i,0);h=r;return}function Vp(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=qp()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=Gp(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,$p(u,r)|0,r);h=i;return}function qp(){var e=0,t=0;if(!(r[7760]|0)){eh(9756);Fe(39,9756,g|0)|0;t=7760;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9756)|0)){e=9756;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));eh(9756)}return 9756}function Gp(e){e=e|0;return 0}function $p(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=qp()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];Yp(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{Kp(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function Yp(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function Kp(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=Xp(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;Qp(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];Yp(u,r,n);o[s>>2]=(o[s>>2]|0)+12;Jp(e,l);Zp(l);h=c;return}}function Xp(e){e=e|0;return 357913941}function Qp(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function Jp(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function Zp(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function eh(e){e=e|0;rh(e);return}function th(e){e=e|0;nh(e+24|0);return}function nh(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function rh(e){e=e|0;var t=0;t=Za()|0;nl(e,2,8,t,ih()|0,1);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function ih(){return 1292}function oh(e,t,n){e=e|0;t=t|0;n=+n;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=uh(e)|0;e=o[a+4>>2]|0;o[u>>2]=o[a>>2];o[u+4>>2]=e;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];ah(t,i,n);h=r;return}function uh(e){e=e|0;return(o[(qp()|0)+24>>2]|0)+(e*12|0)|0}function ah(e,t,n){e=e|0;t=t|0;n=+n;var r=0,i=0,u=0;u=h;h=h+16|0;i=u;r=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)r=o[(o[e>>2]|0)+r>>2]|0;Kl(i,n);n=+Xl(i,n);dA[r&31](e,n);h=u;return}function lh(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];sh(e,n,i,0);h=r;return}function sh(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=ch()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=fh(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,dh(u,r)|0,r);h=i;return}function ch(){var e=0,t=0;if(!(r[7768]|0)){_h(9792);Fe(40,9792,g|0)|0;t=7768;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9792)|0)){e=9792;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));_h(9792)}return 9792}function fh(e){e=e|0;return 0}function dh(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=ch()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];ph(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{hh(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function ph(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function hh(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=vh(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;mh(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];ph(u,r,n);o[s>>2]=(o[s>>2]|0)+12;gh(e,l);yh(l);h=c;return}}function vh(e){e=e|0;return 357913941}function mh(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function gh(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function yh(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function _h(e){e=e|0;Eh(e);return}function bh(e){e=e|0;wh(e+24|0);return}function wh(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function Eh(e){e=e|0;var t=0;t=Za()|0;nl(e,2,1,t,Dh()|0,2);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function Dh(){return 1300}function Sh(e,t,n,r){e=e|0;t=t|0;n=n|0;r=+r;var i=0,u=0,a=0,l=0;i=h;h=h+16|0;u=i+8|0;a=i;l=Ch(e)|0;e=o[l+4>>2]|0;o[a>>2]=o[l>>2];o[a+4>>2]=e;o[u>>2]=o[a>>2];o[u+4>>2]=o[a+4>>2];kh(t,u,n,r);h=i;return}function Ch(e){e=e|0;return(o[(ch()|0)+24>>2]|0)+(e*12|0)|0}function kh(e,t,n,r){e=e|0;t=t|0;n=n|0;r=+r;var i=0,u=0,a=0,l=0;l=h;h=h+16|0;u=l+1|0;a=l;i=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)i=o[(o[e>>2]|0)+i>>2]|0;Ql(u,n);u=Jl(u,n)|0;Kl(a,r);r=+Xl(a,r);NA[i&15](e,u,r);h=l;return}function Th(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];xh(e,n,i,0);h=r;return}function xh(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=Ah()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=Oh(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,Ph(u,r)|0,r);h=i;return}function Ah(){var e=0,t=0;if(!(r[7776]|0)){Bh(9828);Fe(41,9828,g|0)|0;t=7776;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9828)|0)){e=9828;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));Bh(9828)}return 9828}function Oh(e){e=e|0;return 0}function Ph(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=Ah()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];Ih(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{Nh(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function Ih(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function Nh(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=Mh(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;Rh(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];Ih(u,r,n);o[s>>2]=(o[s>>2]|0)+12;Fh(e,l);Lh(l);h=c;return}}function Mh(e){e=e|0;return 357913941}function Rh(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function Fh(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function Lh(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function Bh(e){e=e|0;zh(e);return}function jh(e){e=e|0;Uh(e+24|0);return}function Uh(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function zh(e){e=e|0;var t=0;t=Za()|0;nl(e,2,7,t,Wh()|0,1);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function Wh(){return 1312}function Hh(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=Vh(e)|0;e=o[a+4>>2]|0;o[u>>2]=o[a>>2];o[u+4>>2]=e;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];qh(t,i,n);h=r;return}function Vh(e){e=e|0;return(o[(Ah()|0)+24>>2]|0)+(e*12|0)|0}function qh(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0;u=h;h=h+16|0;i=u;r=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)r=o[(o[e>>2]|0)+r>>2]|0;Ql(i,n);i=Jl(i,n)|0;vA[r&31](e,i);h=u;return}function Gh(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];$h(e,n,i,0);h=r;return}function $h(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=Yh()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=Kh(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,Xh(u,r)|0,r);h=i;return}function Yh(){var e=0,t=0;if(!(r[7784]|0)){rv(9864);Fe(42,9864,g|0)|0;t=7784;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9864)|0)){e=9864;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));rv(9864)}return 9864}function Kh(e){e=e|0;return 0}function Xh(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=Yh()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];Qh(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{Jh(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function Qh(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function Jh(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=Zh(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;ev(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];Qh(u,r,n);o[s>>2]=(o[s>>2]|0)+12;tv(e,l);nv(l);h=c;return}}function Zh(e){e=e|0;return 357913941}function ev(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function tv(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function nv(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function rv(e){e=e|0;uv(e);return}function iv(e){e=e|0;ov(e+24|0);return}function ov(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function uv(e){e=e|0;var t=0;t=Za()|0;nl(e,2,8,t,av()|0,1);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function av(){return 1320}function lv(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=sv(e)|0;e=o[a+4>>2]|0;o[u>>2]=o[a>>2];o[u+4>>2]=e;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];cv(t,i,n);h=r;return}function sv(e){e=e|0;return(o[(Yh()|0)+24>>2]|0)+(e*12|0)|0}function cv(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0;u=h;h=h+16|0;i=u;r=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)r=o[(o[e>>2]|0)+r>>2]|0;fv(i,n);i=dv(i,n)|0;vA[r&31](e,i);h=u;return}function fv(e,t){e=e|0;t=t|0;return}function dv(e,t){e=e|0;t=t|0;return pv(t)|0}function pv(e){e=e|0;return e|0}function hv(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];vv(e,n,i,0);h=r;return}function vv(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=mv()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=gv(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,yv(u,r)|0,r);h=i;return}function mv(){var e=0,t=0;if(!(r[7792]|0)){Cv(9900);Fe(43,9900,g|0)|0;t=7792;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9900)|0)){e=9900;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));Cv(9900)}return 9900}function gv(e){e=e|0;return 0}function yv(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=mv()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];_v(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{bv(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function _v(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function bv(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=wv(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;Ev(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];_v(u,r,n);o[s>>2]=(o[s>>2]|0)+12;Dv(e,l);Sv(l);h=c;return}}function wv(e){e=e|0;return 357913941}function Ev(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function Dv(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function Sv(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function Cv(e){e=e|0;xv(e);return}function kv(e){e=e|0;Tv(e+24|0);return}function Tv(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function xv(e){e=e|0;var t=0;t=Za()|0;nl(e,2,22,t,Av()|0,0);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function Av(){return 1344}function Ov(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0;n=h;h=h+16|0;r=n+8|0;i=n;u=Pv(e)|0;e=o[u+4>>2]|0;o[i>>2]=o[u>>2];o[i+4>>2]=e;o[r>>2]=o[i>>2];o[r+4>>2]=o[i+4>>2];Iv(t,r);h=n;return}function Pv(e){e=e|0;return(o[(mv()|0)+24>>2]|0)+(e*12|0)|0}function Iv(e,t){e=e|0;t=t|0;var n=0;n=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)n=o[(o[e>>2]|0)+n>>2]|0;hA[n&127](e);return}function Nv(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0;u=o[e>>2]|0;i=Mv()|0;e=Rv(n)|0;La(u,t,i,e,Fv(n,r)|0,r);return}function Mv(){var e=0,t=0;if(!(r[7800]|0)){Hv(9936);Fe(44,9936,g|0)|0;t=7800;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9936)|0)){e=9936;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));Hv(9936)}return 9936}function Rv(e){e=e|0;return e|0}function Fv(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0;l=h;h=h+16|0;i=l;u=l+4|0;o[i>>2]=e;s=Mv()|0;a=s+24|0;t=za(t,4)|0;o[u>>2]=t;n=s+28|0;r=o[n>>2]|0;if(r>>>0<(o[s+32>>2]|0)>>>0){Lv(r,e,t);t=(o[n>>2]|0)+8|0;o[n>>2]=t}else{Bv(a,i,u);t=o[n>>2]|0}h=l;return(t-(o[a>>2]|0)>>3)+-1|0}function Lv(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;o[e+4>>2]=n;return}function Bv(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0;l=h;h=h+32|0;i=l;u=e+4|0;a=((o[u>>2]|0)-(o[e>>2]|0)>>3)+1|0;r=jv(e)|0;if(r>>>0>>0)UT(e);else{s=o[e>>2]|0;f=(o[e+8>>2]|0)-s|0;c=f>>2;Uv(i,f>>3>>>0>>1>>>0?c>>>0>>0?a:c:r,(o[u>>2]|0)-s>>3,e+8|0);a=i+8|0;Lv(o[a>>2]|0,o[t>>2]|0,o[n>>2]|0);o[a>>2]=(o[a>>2]|0)+8;zv(e,i);Wv(i);h=l;return}}function jv(e){e=e|0;return 536870911}function Uv(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>536870911)Ye();else{i=$T(t<<3)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n<<3)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t<<3);return}function zv(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(0-(i>>3)<<3)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function Wv(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~((r+-8-t|0)>>>3)<<3);e=o[e>>2]|0;if(e|0)KT(e);return}function Hv(e){e=e|0;Gv(e);return}function Vv(e){e=e|0;qv(e+24|0);return}function qv(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function Gv(e){e=e|0;var t=0;t=Za()|0;nl(e,1,23,t,vf()|0,1);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function $v(e,t){e=e|0;t=t|0;Kv(o[(Yv(e)|0)>>2]|0,t);return}function Yv(e){e=e|0;return(o[(Mv()|0)+24>>2]|0)+(e<<3)|0}function Kv(e,t){e=e|0;t=t|0;var n=0,r=0;n=h;h=h+16|0;r=n;_f(r,t);t=bf(r,t)|0;hA[e&127](t);h=n;return}function Xv(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0;u=o[e>>2]|0;i=Qv()|0;e=Jv(n)|0;La(u,t,i,e,Zv(n,r)|0,r);return}function Qv(){var e=0,t=0;if(!(r[7808]|0)){um(9972);Fe(45,9972,g|0)|0;t=7808;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(9972)|0)){e=9972;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));um(9972)}return 9972}function Jv(e){e=e|0;return e|0}function Zv(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0;l=h;h=h+16|0;i=l;u=l+4|0;o[i>>2]=e;s=Qv()|0;a=s+24|0;t=za(t,4)|0;o[u>>2]=t;n=s+28|0;r=o[n>>2]|0;if(r>>>0<(o[s+32>>2]|0)>>>0){em(r,e,t);t=(o[n>>2]|0)+8|0;o[n>>2]=t}else{tm(a,i,u);t=o[n>>2]|0}h=l;return(t-(o[a>>2]|0)>>3)+-1|0}function em(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;o[e+4>>2]=n;return}function tm(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0;l=h;h=h+32|0;i=l;u=e+4|0;a=((o[u>>2]|0)-(o[e>>2]|0)>>3)+1|0;r=nm(e)|0;if(r>>>0>>0)UT(e);else{s=o[e>>2]|0;f=(o[e+8>>2]|0)-s|0;c=f>>2;rm(i,f>>3>>>0>>1>>>0?c>>>0>>0?a:c:r,(o[u>>2]|0)-s>>3,e+8|0);a=i+8|0;em(o[a>>2]|0,o[t>>2]|0,o[n>>2]|0);o[a>>2]=(o[a>>2]|0)+8;im(e,i);om(i);h=l;return}}function nm(e){e=e|0;return 536870911}function rm(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>536870911)Ye();else{i=$T(t<<3)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n<<3)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t<<3);return}function im(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(0-(i>>3)<<3)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function om(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~((r+-8-t|0)>>>3)<<3);e=o[e>>2]|0;if(e|0)KT(e);return}function um(e){e=e|0;sm(e);return}function am(e){e=e|0;lm(e+24|0);return}function lm(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function sm(e){e=e|0;var t=0;t=Za()|0;nl(e,1,9,t,cm()|0,1);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function cm(){return 1348}function fm(e,t){e=e|0;t=t|0;return pm(o[(dm(e)|0)>>2]|0,t)|0}function dm(e){e=e|0;return(o[(Qv()|0)+24>>2]|0)+(e<<3)|0}function pm(e,t){e=e|0;t=t|0;var n=0,r=0;n=h;h=h+16|0;r=n;hm(r,t);t=vm(r,t)|0;t=dc(mA[e&31](t)|0)|0;h=n;return t|0}function hm(e,t){e=e|0;t=t|0;return}function vm(e,t){e=e|0;t=t|0;return mm(t)|0}function mm(e){e=e|0;return e|0}function gm(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0;u=o[e>>2]|0;i=ym()|0;e=_m(n)|0;La(u,t,i,e,bm(n,r)|0,r);return}function ym(){var e=0,t=0;if(!(r[7816]|0)){Tm(10008);Fe(46,10008,g|0)|0;t=7816;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(10008)|0)){e=10008;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));Tm(10008)}return 10008}function _m(e){e=e|0;return e|0}function bm(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0;l=h;h=h+16|0;i=l;u=l+4|0;o[i>>2]=e;s=ym()|0;a=s+24|0;t=za(t,4)|0;o[u>>2]=t;n=s+28|0;r=o[n>>2]|0;if(r>>>0<(o[s+32>>2]|0)>>>0){wm(r,e,t);t=(o[n>>2]|0)+8|0;o[n>>2]=t}else{Em(a,i,u);t=o[n>>2]|0}h=l;return(t-(o[a>>2]|0)>>3)+-1|0}function wm(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;o[e+4>>2]=n;return}function Em(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0;l=h;h=h+32|0;i=l;u=e+4|0;a=((o[u>>2]|0)-(o[e>>2]|0)>>3)+1|0;r=Dm(e)|0;if(r>>>0>>0)UT(e);else{s=o[e>>2]|0;f=(o[e+8>>2]|0)-s|0;c=f>>2;Sm(i,f>>3>>>0>>1>>>0?c>>>0>>0?a:c:r,(o[u>>2]|0)-s>>3,e+8|0);a=i+8|0;wm(o[a>>2]|0,o[t>>2]|0,o[n>>2]|0);o[a>>2]=(o[a>>2]|0)+8;Cm(e,i);km(i);h=l;return}}function Dm(e){e=e|0;return 536870911}function Sm(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>536870911)Ye();else{i=$T(t<<3)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n<<3)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t<<3);return}function Cm(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(0-(i>>3)<<3)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function km(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~((r+-8-t|0)>>>3)<<3);e=o[e>>2]|0;if(e|0)KT(e);return}function Tm(e){e=e|0;Om(e);return}function xm(e){e=e|0;Am(e+24|0);return}function Am(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function Om(e){e=e|0;var t=0;t=Za()|0;nl(e,1,15,t,Ac()|0,0);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function Pm(e){e=e|0;return Nm(o[(Im(e)|0)>>2]|0)|0}function Im(e){e=e|0;return(o[(ym()|0)+24>>2]|0)+(e<<3)|0}function Nm(e){e=e|0;return dc(TA[e&7]()|0)|0}function Mm(){var e=0;if(!(r[7832]|0)){Vm(10052);Fe(25,10052,g|0)|0;e=7832;o[e>>2]=1;o[e+4>>2]=0}return 10052}function Rm(e,t){e=e|0;t=t|0;o[e>>2]=Fm()|0;o[e+4>>2]=Lm()|0;o[e+12>>2]=t;o[e+8>>2]=Bm()|0;o[e+32>>2]=2;return}function Fm(){return 11709}function Lm(){return 1188}function Bm(){return Wm()|0}function jm(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;if((Um(r,896)|0)==512){if(n|0){zm(n);KT(n)}}else if(t|0){Qi(t);KT(t)}return}function Um(e,t){e=e|0;t=t|0;return t&e|0}function zm(e){e=e|0;e=o[e+4>>2]|0;if(e|0)qT(e);return}function Wm(){var e=0;if(!(r[7824]|0)){o[2511]=Hm()|0;o[2512]=0;e=7824;o[e>>2]=1;o[e+4>>2]=0}return 10044}function Hm(){return 0}function Vm(e){e=e|0;Al(e);return}function qm(e){e=e|0;var t=0,n=0,r=0,i=0,u=0;t=h;h=h+32|0;n=t+24|0;u=t+16|0;i=t+8|0;r=t;Gm(e,4827);$m(e,4834,3)|0;Ym(e,3682,47)|0;o[u>>2]=9;o[u+4>>2]=0;o[n>>2]=o[u>>2];o[n+4>>2]=o[u+4>>2];Km(e,4841,n)|0;o[i>>2]=1;o[i+4>>2]=0;o[n>>2]=o[i>>2];o[n+4>>2]=o[i+4>>2];Xm(e,4871,n)|0;o[r>>2]=10;o[r+4>>2]=0;o[n>>2]=o[r>>2];o[n+4>>2]=o[r+4>>2];Qm(e,4891,n)|0;h=t;return}function Gm(e,t){e=e|0;t=t|0;var n=0;n=Vy()|0;o[e>>2]=n;qy(n,t);cw(o[e>>2]|0);return}function $m(e,t,n){e=e|0;t=t|0;n=n|0;Cy(e,Ia(t)|0,n,0);return e|0}function Ym(e,t,n){e=e|0;t=t|0;n=n|0;ay(e,Ia(t)|0,n,0);return e|0}function Km(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];jg(e,t,i);h=r;return e|0}function Xm(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];gg(e,t,i);h=r;return e|0}function Qm(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=o[n+4>>2]|0;o[u>>2]=o[n>>2];o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Jm(e,t,i);h=r;return e|0}function Jm(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Zm(e,n,i,1);h=r;return}function Zm(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=eg()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=tg(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,ng(u,r)|0,r);h=i;return}function eg(){var e=0,t=0;if(!(r[7840]|0)){sg(10100);Fe(48,10100,g|0)|0;t=7840;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(10100)|0)){e=10100;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));sg(10100)}return 10100}function tg(e){e=e|0;return 0}function ng(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=eg()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];rg(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{ig(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function rg(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function ig(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=og(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;ug(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];rg(u,r,n);o[s>>2]=(o[s>>2]|0)+12;ag(e,l);lg(l);h=c;return}}function og(e){e=e|0;return 357913941}function ug(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function ag(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function lg(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function sg(e){e=e|0;dg(e);return}function cg(e){e=e|0;fg(e+24|0);return}function fg(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function dg(e){e=e|0;var t=0;t=Za()|0;nl(e,2,6,t,pg()|0,1);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function pg(){return 1364}function hg(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=vg(e)|0;e=o[a+4>>2]|0;o[u>>2]=o[a>>2];o[u+4>>2]=e;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];n=mg(t,i,n)|0;h=r;return n|0}function vg(e){e=e|0;return(o[(eg()|0)+24>>2]|0)+(e*12|0)|0}function mg(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0;u=h;h=h+16|0;i=u;r=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)r=o[(o[e>>2]|0)+r>>2]|0;Ql(i,n);i=Jl(i,n)|0;i=bs(DA[r&15](e,i)|0)|0;h=u;return i|0}function gg(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];yg(e,n,i,0);h=r;return}function yg(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=_g()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=bg(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,wg(u,r)|0,r);h=i;return}function _g(){var e=0,t=0;if(!(r[7848]|0)){xg(10136);Fe(49,10136,g|0)|0;t=7848;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(10136)|0)){e=10136;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));xg(10136)}return 10136}function bg(e){e=e|0;return 0}function wg(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=_g()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];Eg(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{Dg(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function Eg(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function Dg(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=Sg(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;Cg(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];Eg(u,r,n);o[s>>2]=(o[s>>2]|0)+12;kg(e,l);Tg(l);h=c;return}}function Sg(e){e=e|0;return 357913941}function Cg(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function kg(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function Tg(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function xg(e){e=e|0;Pg(e);return}function Ag(e){e=e|0;Og(e+24|0);return}function Og(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function Pg(e){e=e|0;var t=0;t=Za()|0;nl(e,2,9,t,Ig()|0,1);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function Ig(){return 1372}function Ng(e,t,n){e=e|0;t=t|0;n=+n;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;i=r+8|0;u=r;a=Mg(e)|0;e=o[a+4>>2]|0;o[u>>2]=o[a>>2];o[u+4>>2]=e;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Rg(t,i,n);h=r;return}function Mg(e){e=e|0;return(o[(_g()|0)+24>>2]|0)+(e*12|0)|0}function Rg(e,t,n){e=e|0;t=t|0;n=+n;var r=0,i=0,u=0,a=ft;u=h;h=h+16|0;i=u;r=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)r=o[(o[e>>2]|0)+r>>2]|0;Fg(i,n);a=Y(Lg(i,n));fA[r&1](e,a);h=u;return}function Fg(e,t){e=e|0;t=+t;return}function Lg(e,t){e=e|0;t=+t;return Y(Bg(t))}function Bg(e){e=+e;return Y(e)}function jg(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;i=r+8|0;u=r;l=o[n>>2]|0;a=o[n+4>>2]|0;n=Ia(t)|0;o[u>>2]=l;o[u+4>>2]=a;o[i>>2]=o[u>>2];o[i+4>>2]=o[u+4>>2];Ug(e,n,i,0);h=r;return}function Ug(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0;i=h;h=h+32|0;u=i+16|0;f=i+8|0;l=i;c=o[n>>2]|0;s=o[n+4>>2]|0;a=o[e>>2]|0;e=zg()|0;o[f>>2]=c;o[f+4>>2]=s;o[u>>2]=o[f>>2];o[u+4>>2]=o[f+4>>2];n=Wg(u)|0;o[l>>2]=c;o[l+4>>2]=s;o[u>>2]=o[l>>2];o[u+4>>2]=o[l+4>>2];La(a,t,e,n,Hg(u,r)|0,r);h=i;return}function zg(){var e=0,t=0;if(!(r[7856]|0)){Xg(10172);Fe(50,10172,g|0)|0;t=7856;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(10172)|0)){e=10172;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));Xg(10172)}return 10172}function Wg(e){e=e|0;return 0}function Hg(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0;f=h;h=h+32|0;i=f+24|0;a=f+16|0;l=f;s=f+8|0;u=o[e>>2]|0;r=o[e+4>>2]|0;o[l>>2]=u;o[l+4>>2]=r;d=zg()|0;c=d+24|0;e=za(t,4)|0;o[s>>2]=e;t=d+28|0;n=o[t>>2]|0;if(n>>>0<(o[d+32>>2]|0)>>>0){o[a>>2]=u;o[a+4>>2]=r;o[i>>2]=o[a>>2];o[i+4>>2]=o[a+4>>2];Vg(n,i,e);e=(o[t>>2]|0)+12|0;o[t>>2]=e}else{qg(c,l,s);e=o[t>>2]|0}h=f;return((e-(o[c>>2]|0)|0)/12|0)+-1|0}function Vg(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=o[t+4>>2]|0;o[e>>2]=o[t>>2];o[e+4>>2]=r;o[e+8>>2]=n;return}function qg(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0;c=h;h=h+48|0;r=c+32|0;a=c+24|0;l=c;s=e+4|0;i=(((o[s>>2]|0)-(o[e>>2]|0)|0)/12|0)+1|0;u=Gg(e)|0;if(u>>>0>>0)UT(e);else{f=o[e>>2]|0;p=((o[e+8>>2]|0)-f|0)/12|0;d=p<<1;$g(l,p>>>0>>1>>>0?d>>>0>>0?i:d:u,((o[s>>2]|0)-f|0)/12|0,e+8|0);s=l+8|0;u=o[s>>2]|0;i=o[t+4>>2]|0;n=o[n>>2]|0;o[a>>2]=o[t>>2];o[a+4>>2]=i;o[r>>2]=o[a>>2];o[r+4>>2]=o[a+4>>2];Vg(u,r,n);o[s>>2]=(o[s>>2]|0)+12;Yg(e,l);Kg(l);h=c;return}}function Gg(e){e=e|0;return 357913941}function $g(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>357913941)Ye();else{i=$T(t*12|0)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n*12|0)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t*12|0);return}function Yg(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(((i|0)/-12|0)*12|0)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function Kg(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~(((r+-12-t|0)>>>0)/12|0)*12|0);e=o[e>>2]|0;if(e|0)KT(e);return}function Xg(e){e=e|0;Zg(e);return}function Qg(e){e=e|0;Jg(e+24|0);return}function Jg(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~(((t+-12-r|0)>>>0)/12|0)*12|0);KT(n)}return}function Zg(e){e=e|0;var t=0;t=Za()|0;nl(e,2,3,t,ey()|0,2);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function ey(){return 1380}function ty(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0;i=h;h=h+16|0;u=i+8|0;a=i;l=ny(e)|0;e=o[l+4>>2]|0;o[a>>2]=o[l>>2];o[a+4>>2]=e;o[u>>2]=o[a>>2];o[u+4>>2]=o[a+4>>2];ry(t,u,n,r);h=i;return}function ny(e){e=e|0;return(o[(zg()|0)+24>>2]|0)+(e*12|0)|0}function ry(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0;l=h;h=h+16|0;u=l+1|0;a=l;i=o[t>>2]|0;t=o[t+4>>2]|0;e=e+(t>>1)|0;if(t&1)i=o[(o[e>>2]|0)+i>>2]|0;Ql(u,n);u=Jl(u,n)|0;iy(a,r);a=oy(a,r)|0;PA[i&15](e,u,a);h=l;return}function iy(e,t){e=e|0;t=t|0;return}function oy(e,t){e=e|0;t=t|0;return uy(t)|0}function uy(e){e=e|0;return(e|0)!=0|0}function ay(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0;u=o[e>>2]|0;i=ly()|0;e=sy(n)|0;La(u,t,i,e,cy(n,r)|0,r);return}function ly(){var e=0,t=0;if(!(r[7864]|0)){gy(10208);Fe(51,10208,g|0)|0;t=7864;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(10208)|0)){e=10208;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));gy(10208)}return 10208}function sy(e){e=e|0;return e|0}function cy(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0;l=h;h=h+16|0;i=l;u=l+4|0;o[i>>2]=e;s=ly()|0;a=s+24|0;t=za(t,4)|0;o[u>>2]=t;n=s+28|0;r=o[n>>2]|0;if(r>>>0<(o[s+32>>2]|0)>>>0){fy(r,e,t);t=(o[n>>2]|0)+8|0;o[n>>2]=t}else{dy(a,i,u);t=o[n>>2]|0}h=l;return(t-(o[a>>2]|0)>>3)+-1|0}function fy(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;o[e+4>>2]=n;return}function dy(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0;l=h;h=h+32|0;i=l;u=e+4|0;a=((o[u>>2]|0)-(o[e>>2]|0)>>3)+1|0;r=py(e)|0;if(r>>>0>>0)UT(e);else{s=o[e>>2]|0;f=(o[e+8>>2]|0)-s|0;c=f>>2;hy(i,f>>3>>>0>>1>>>0?c>>>0>>0?a:c:r,(o[u>>2]|0)-s>>3,e+8|0);a=i+8|0;fy(o[a>>2]|0,o[t>>2]|0,o[n>>2]|0);o[a>>2]=(o[a>>2]|0)+8;vy(e,i);my(i);h=l;return}}function py(e){e=e|0;return 536870911}function hy(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>536870911)Ye();else{i=$T(t<<3)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n<<3)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t<<3);return}function vy(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(0-(i>>3)<<3)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function my(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~((r+-8-t|0)>>>3)<<3);e=o[e>>2]|0;if(e|0)KT(e);return}function gy(e){e=e|0;by(e);return}function yy(e){e=e|0;_y(e+24|0);return}function _y(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function by(e){e=e|0;var t=0;t=Za()|0;nl(e,1,24,t,wy()|0,1);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function wy(){return 1392}function Ey(e,t){e=e|0;t=t|0;Sy(o[(Dy(e)|0)>>2]|0,t);return}function Dy(e){e=e|0;return(o[(ly()|0)+24>>2]|0)+(e<<3)|0}function Sy(e,t){e=e|0;t=t|0;var n=0,r=0;n=h;h=h+16|0;r=n;hm(r,t);t=vm(r,t)|0;hA[e&127](t);h=n;return}function Cy(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0;u=o[e>>2]|0;i=ky()|0;e=Ty(n)|0;La(u,t,i,e,xy(n,r)|0,r);return}function ky(){var e=0,t=0;if(!(r[7872]|0)){Ry(10244);Fe(52,10244,g|0)|0;t=7872;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(10244)|0)){e=10244;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));Ry(10244)}return 10244}function Ty(e){e=e|0;return e|0}function xy(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0;l=h;h=h+16|0;i=l;u=l+4|0;o[i>>2]=e;s=ky()|0;a=s+24|0;t=za(t,4)|0;o[u>>2]=t;n=s+28|0;r=o[n>>2]|0;if(r>>>0<(o[s+32>>2]|0)>>>0){Ay(r,e,t);t=(o[n>>2]|0)+8|0;o[n>>2]=t}else{Oy(a,i,u);t=o[n>>2]|0}h=l;return(t-(o[a>>2]|0)>>3)+-1|0}function Ay(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;o[e+4>>2]=n;return}function Oy(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0;l=h;h=h+32|0;i=l;u=e+4|0;a=((o[u>>2]|0)-(o[e>>2]|0)>>3)+1|0;r=Py(e)|0;if(r>>>0>>0)UT(e);else{s=o[e>>2]|0;f=(o[e+8>>2]|0)-s|0;c=f>>2;Iy(i,f>>3>>>0>>1>>>0?c>>>0>>0?a:c:r,(o[u>>2]|0)-s>>3,e+8|0);a=i+8|0;Ay(o[a>>2]|0,o[t>>2]|0,o[n>>2]|0);o[a>>2]=(o[a>>2]|0)+8;Ny(e,i);My(i);h=l;return}}function Py(e){e=e|0;return 536870911}function Iy(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>536870911)Ye();else{i=$T(t<<3)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n<<3)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t<<3);return}function Ny(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(0-(i>>3)<<3)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function My(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~((r+-8-t|0)>>>3)<<3);e=o[e>>2]|0;if(e|0)KT(e);return}function Ry(e){e=e|0;By(e);return}function Fy(e){e=e|0;Ly(e+24|0);return}function Ly(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function By(e){e=e|0;var t=0;t=Za()|0;nl(e,1,16,t,jy()|0,0);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function jy(){return 1400}function Uy(e){e=e|0;return Wy(o[(zy(e)|0)>>2]|0)|0}function zy(e){e=e|0;return(o[(ky()|0)+24>>2]|0)+(e<<3)|0}function Wy(e){e=e|0;return Hy(TA[e&7]()|0)|0}function Hy(e){e=e|0;return e|0}function Vy(){var e=0;if(!(r[7880]|0)){Qy(10280);Fe(25,10280,g|0)|0;e=7880;o[e>>2]=1;o[e+4>>2]=0}return 10280}function qy(e,t){e=e|0;t=t|0;o[e>>2]=Gy()|0;o[e+4>>2]=$y()|0;o[e+12>>2]=t;o[e+8>>2]=Yy()|0;o[e+32>>2]=4;return}function Gy(){return 11711}function $y(){return 1356}function Yy(){return Wm()|0}function Ky(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;if((Um(r,896)|0)==512){if(n|0){Xy(n);KT(n)}}else if(t|0){Hi(t);KT(t)}return}function Xy(e){e=e|0;e=o[e+4>>2]|0;if(e|0)qT(e);return}function Qy(e){e=e|0;Al(e);return}function Jy(e){e=e|0;Zy(e,4920);e_(e)|0;t_(e)|0;return}function Zy(e,t){e=e|0;t=t|0;var n=0;n=qd()|0;o[e>>2]=n;T_(n,t);cw(o[e>>2]|0);return}function e_(e){e=e|0;var t=0;t=o[e>>2]|0;r_(t,v_()|0);return e|0}function t_(e){e=e|0;var t=0;t=o[e>>2]|0;r_(t,n_()|0);return e|0}function n_(){var e=0;if(!(r[7888]|0)){i_(10328);Fe(53,10328,g|0)|0;e=7888;o[e>>2]=1;o[e+4>>2]=0}if(!(Xa(10328)|0))i_(10328);return 10328}function r_(e,t){e=e|0;t=t|0;La(e,0,t,0,0,0);return}function i_(e){e=e|0;a_(e);s_(e,10);return}function o_(e){e=e|0;u_(e+24|0);return}function u_(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function a_(e){e=e|0;var t=0;t=Za()|0;nl(e,5,1,t,d_()|0,2);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function l_(e,t,n){e=e|0;t=t|0;n=+n;c_(e,t,n);return}function s_(e,t){e=e|0;t=t|0;o[e+20>>2]=t;return}function c_(e,t,n){e=e|0;t=t|0;n=+n;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+16|0;u=r+8|0;l=r+13|0;i=r;a=r+12|0;Ql(l,t);o[u>>2]=Jl(l,t)|0;Kl(a,n);c[i>>3]=+Xl(a,n);f_(e,u,i);h=r;return}function f_(e,t,n){e=e|0;t=t|0;n=n|0;Vo(e+8|0,o[t>>2]|0,+c[n>>3]);r[e+24>>0]=1;return}function d_(){return 1404}function p_(e,t){e=e|0;t=+t;return h_(e,t)|0}function h_(e,t){e=e|0;t=+t;var n=0,r=0,i=0,u=0,a=0,l=0,s=0;r=h;h=h+16|0;u=r+4|0;a=r+8|0;l=r;i=UD(8)|0;n=i;s=$T(16)|0;Ql(u,e);e=Jl(u,e)|0;Kl(a,t);Vo(s,e,+Xl(a,t));a=n+4|0;o[a>>2]=s;e=$T(8)|0;a=o[a>>2]|0;o[l>>2]=0;o[u>>2]=o[l>>2];Yd(e,a,u);o[i>>2]=e;h=r;return n|0}function v_(){var e=0;if(!(r[7896]|0)){m_(10364);Fe(54,10364,g|0)|0;e=7896;o[e>>2]=1;o[e+4>>2]=0}if(!(Xa(10364)|0))m_(10364);return 10364}function m_(e){e=e|0;__(e);s_(e,55);return}function g_(e){e=e|0;y_(e+24|0);return}function y_(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function __(e){e=e|0;var t=0;t=Za()|0;nl(e,5,4,t,S_()|0,0);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function b_(e){e=e|0;w_(e);return}function w_(e){e=e|0;E_(e);return}function E_(e){e=e|0;D_(e+8|0);r[e+24>>0]=1;return}function D_(e){e=e|0;o[e>>2]=0;c[e+8>>3]=0.0;return}function S_(){return 1424}function C_(){return k_()|0}function k_(){var e=0,t=0,n=0,r=0,i=0,u=0,a=0;t=h;h=h+16|0;i=t+4|0;a=t;n=UD(8)|0;e=n;r=$T(16)|0;D_(r);u=e+4|0;o[u>>2]=r;r=$T(8)|0;u=o[u>>2]|0;o[a>>2]=0;o[i>>2]=o[a>>2];Yd(r,u,i);o[n>>2]=r;h=t;return e|0}function T_(e,t){e=e|0;t=t|0;o[e>>2]=x_()|0;o[e+4>>2]=A_()|0;o[e+12>>2]=t;o[e+8>>2]=O_()|0;o[e+32>>2]=5;return}function x_(){return 11710}function A_(){return 1416}function O_(){return N_()|0}function P_(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;if((Um(r,896)|0)==512){if(n|0){I_(n);KT(n)}}else if(t|0)KT(t);return}function I_(e){e=e|0;e=o[e+4>>2]|0;if(e|0)qT(e);return}function N_(){var e=0;if(!(r[7904]|0)){o[2600]=M_()|0;o[2601]=0;e=7904;o[e>>2]=1;o[e+4>>2]=0}return 10400}function M_(){return o[357]|0}function R_(e){e=e|0;F_(e,4926);L_(e)|0;return}function F_(e,t){e=e|0;t=t|0;var n=0;n=ul()|0;o[e>>2]=n;K_(n,t);cw(o[e>>2]|0);return}function L_(e){e=e|0;var t=0;t=o[e>>2]|0;r_(t,B_()|0);return e|0}function B_(){var e=0;if(!(r[7912]|0)){j_(10412);Fe(56,10412,g|0)|0;e=7912;o[e>>2]=1;o[e+4>>2]=0}if(!(Xa(10412)|0))j_(10412);return 10412}function j_(e){e=e|0;W_(e);s_(e,57);return}function U_(e){e=e|0;z_(e+24|0);return}function z_(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function W_(e){e=e|0;var t=0;t=Za()|0;nl(e,5,5,t,G_()|0,0);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function H_(e){e=e|0;V_(e);return}function V_(e){e=e|0;q_(e);return}function q_(e){e=e|0;var t=0,n=0;t=e+8|0;n=t+48|0;do{o[t>>2]=0;t=t+4|0}while((t|0)<(n|0));r[e+56>>0]=1;return}function G_(){return 1432}function $_(){return Y_()|0}function Y_(){var e=0,t=0,n=0,r=0,i=0,u=0,a=0,l=0;a=h;h=h+16|0;e=a+4|0;t=a;n=UD(8)|0;r=n;i=$T(48)|0;u=i;l=u+48|0;do{o[u>>2]=0;u=u+4|0}while((u|0)<(l|0));u=r+4|0;o[u>>2]=i;l=$T(8)|0;u=o[u>>2]|0;o[t>>2]=0;o[e>>2]=o[t>>2];pl(l,u,e);o[n>>2]=l;h=a;return r|0}function K_(e,t){e=e|0;t=t|0;o[e>>2]=X_()|0;o[e+4>>2]=Q_()|0;o[e+12>>2]=t;o[e+8>>2]=J_()|0;o[e+32>>2]=6;return}function X_(){return 11704}function Q_(){return 1436}function J_(){return N_()|0}function Z_(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;if((Um(r,896)|0)==512){if(n|0){eb(n);KT(n)}}else if(t|0)KT(t);return}function eb(e){e=e|0;e=o[e+4>>2]|0;if(e|0)qT(e);return}function tb(e){e=e|0;nb(e,4933);rb(e)|0;ib(e)|0;return}function nb(e,t){e=e|0;t=t|0;var n=0;n=Nb()|0;o[e>>2]=n;Mb(n,t);cw(o[e>>2]|0);return}function rb(e){e=e|0;var t=0;t=o[e>>2]|0;r_(t,wb()|0);return e|0}function ib(e){e=e|0;var t=0;t=o[e>>2]|0;r_(t,ob()|0);return e|0}function ob(){var e=0;if(!(r[7920]|0)){ub(10452);Fe(58,10452,g|0)|0;e=7920;o[e>>2]=1;o[e+4>>2]=0}if(!(Xa(10452)|0))ub(10452);return 10452}function ub(e){e=e|0;sb(e);s_(e,1);return}function ab(e){e=e|0;lb(e+24|0);return}function lb(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function sb(e){e=e|0;var t=0;t=Za()|0;nl(e,5,1,t,hb()|0,2);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function cb(e,t,n){e=e|0;t=+t;n=+n;fb(e,t,n);return}function fb(e,t,n){e=e|0;t=+t;n=+n;var r=0,i=0,o=0,u=0,a=0;r=h;h=h+32|0;o=r+8|0;a=r+17|0;i=r;u=r+16|0;Kl(a,t);c[o>>3]=+Xl(a,t);Kl(u,n);c[i>>3]=+Xl(u,n);db(e,o,i);h=r;return}function db(e,t,n){e=e|0;t=t|0;n=n|0;pb(e+8|0,+c[t>>3],+c[n>>3]);r[e+24>>0]=1;return}function pb(e,t,n){e=e|0;t=+t;n=+n;c[e>>3]=t;c[e+8>>3]=n;return}function hb(){return 1472}function vb(e,t){e=+e;t=+t;return mb(e,t)|0}function mb(e,t){e=+e;t=+t;var n=0,r=0,i=0,u=0,a=0,l=0,s=0;r=h;h=h+16|0;a=r+4|0;l=r+8|0;s=r;i=UD(8)|0;n=i;u=$T(16)|0;Kl(a,e);e=+Xl(a,e);Kl(l,t);pb(u,e,+Xl(l,t));l=n+4|0;o[l>>2]=u;u=$T(8)|0;l=o[l>>2]|0;o[s>>2]=0;o[a>>2]=o[s>>2];gb(u,l,a);o[i>>2]=u;h=r;return n|0}function gb(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;n=$T(16)|0;o[n+4>>2]=0;o[n+8>>2]=0;o[n>>2]=1452;o[n+12>>2]=t;o[e+4>>2]=n;return}function yb(e){e=e|0;zT(e);KT(e);return}function _b(e){e=e|0;e=o[e+12>>2]|0;if(e|0)KT(e);return}function bb(e){e=e|0;KT(e);return}function wb(){var e=0;if(!(r[7928]|0)){Eb(10488);Fe(59,10488,g|0)|0;e=7928;o[e>>2]=1;o[e+4>>2]=0}if(!(Xa(10488)|0))Eb(10488);return 10488}function Eb(e){e=e|0;Cb(e);s_(e,60);return}function Db(e){e=e|0;Sb(e+24|0);return}function Sb(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function Cb(e){e=e|0;var t=0;t=Za()|0;nl(e,5,6,t,Ob()|0,0);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function kb(e){e=e|0;Tb(e);return}function Tb(e){e=e|0;xb(e);return}function xb(e){e=e|0;Ab(e+8|0);r[e+24>>0]=1;return}function Ab(e){e=e|0;o[e>>2]=0;o[e+4>>2]=0;o[e+8>>2]=0;o[e+12>>2]=0;return}function Ob(){return 1492}function Pb(){return Ib()|0}function Ib(){var e=0,t=0,n=0,r=0,i=0,u=0,a=0;t=h;h=h+16|0;i=t+4|0;a=t;n=UD(8)|0;e=n;r=$T(16)|0;Ab(r);u=e+4|0;o[u>>2]=r;r=$T(8)|0;u=o[u>>2]|0;o[a>>2]=0;o[i>>2]=o[a>>2];gb(r,u,i);o[n>>2]=r;h=t;return e|0}function Nb(){var e=0;if(!(r[7936]|0)){Ub(10524);Fe(25,10524,g|0)|0;e=7936;o[e>>2]=1;o[e+4>>2]=0}return 10524}function Mb(e,t){e=e|0;t=t|0;o[e>>2]=Rb()|0;o[e+4>>2]=Fb()|0;o[e+12>>2]=t;o[e+8>>2]=Lb()|0;o[e+32>>2]=7;return}function Rb(){return 11700}function Fb(){return 1484}function Lb(){return N_()|0}function Bb(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;if((Um(r,896)|0)==512){if(n|0){jb(n);KT(n)}}else if(t|0)KT(t);return}function jb(e){e=e|0;e=o[e+4>>2]|0;if(e|0)qT(e);return}function Ub(e){e=e|0;Al(e);return}function zb(e,t,n){e=e|0;t=t|0;n=n|0;e=Ia(t)|0;t=Wb(n)|0;n=Hb(n,0)|0;xw(e,t,n,Vb()|0,0);return}function Wb(e){e=e|0;return e|0}function Hb(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0;l=h;h=h+16|0;i=l;u=l+4|0;o[i>>2]=e;s=Vb()|0;a=s+24|0;t=za(t,4)|0;o[u>>2]=t;n=s+28|0;r=o[n>>2]|0;if(r>>>0<(o[s+32>>2]|0)>>>0){Jb(r,e,t);t=(o[n>>2]|0)+8|0;o[n>>2]=t}else{Zb(a,i,u);t=o[n>>2]|0}h=l;return(t-(o[a>>2]|0)>>3)+-1|0}function Vb(){var e=0,t=0;if(!(r[7944]|0)){qb(10568);Fe(61,10568,g|0)|0;t=7944;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(10568)|0)){e=10568;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));qb(10568)}return 10568}function qb(e){e=e|0;Yb(e);return}function Gb(e){e=e|0;$b(e+24|0);return}function $b(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function Yb(e){e=e|0;var t=0;t=Za()|0;nl(e,1,17,t,Yc()|0,0);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function Kb(e){e=e|0;return Qb(o[(Xb(e)|0)>>2]|0)|0}function Xb(e){e=e|0;return(o[(Vb()|0)+24>>2]|0)+(e<<3)|0}function Qb(e){e=e|0;return Jc(TA[e&7]()|0)|0}function Jb(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;o[e+4>>2]=n;return}function Zb(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0;l=h;h=h+32|0;i=l;u=e+4|0;a=((o[u>>2]|0)-(o[e>>2]|0)>>3)+1|0;r=ew(e)|0;if(r>>>0>>0)UT(e);else{s=o[e>>2]|0;f=(o[e+8>>2]|0)-s|0;c=f>>2;tw(i,f>>3>>>0>>1>>>0?c>>>0>>0?a:c:r,(o[u>>2]|0)-s>>3,e+8|0);a=i+8|0;Jb(o[a>>2]|0,o[t>>2]|0,o[n>>2]|0);o[a>>2]=(o[a>>2]|0)+8;nw(e,i);rw(i);h=l;return}}function ew(e){e=e|0;return 536870911}function tw(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>536870911)Ye();else{i=$T(t<<3)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n<<3)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t<<3);return}function nw(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(0-(i>>3)<<3)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function rw(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~((r+-8-t|0)>>>3)<<3);e=o[e>>2]|0;if(e|0)KT(e);return}function iw(){ow();return}function ow(){uw(10604);return}function uw(e){e=e|0;aw(e,4955);return}function aw(e,t){e=e|0;t=t|0;var n=0;n=lw()|0;o[e>>2]=n;sw(n,t);cw(o[e>>2]|0);return}function lw(){var e=0;if(!(r[7952]|0)){bw(10612);Fe(25,10612,g|0)|0;e=7952;o[e>>2]=1;o[e+4>>2]=0}return 10612}function sw(e,t){e=e|0;t=t|0;o[e>>2]=vw()|0;o[e+4>>2]=mw()|0;o[e+12>>2]=t;o[e+8>>2]=gw()|0;o[e+32>>2]=8;return}function cw(e){e=e|0;var t=0,n=0;t=h;h=h+16|0;n=t;fw()|0;o[n>>2]=e;dw(10608,n);h=t;return}function fw(){if(!(r[11714]|0)){o[2652]=0;Fe(62,10608,g|0)|0;r[11714]=1}return 10608}function dw(e,t){e=e|0;t=t|0;var n=0;n=$T(8)|0;o[n+4>>2]=o[t>>2];o[n>>2]=o[e>>2];o[e>>2]=n;return}function pw(e){e=e|0;hw(e);return}function hw(e){e=e|0;var t=0,n=0;t=o[e>>2]|0;if(t|0)do{n=t;t=o[t>>2]|0;KT(n)}while((t|0)!=0);o[e>>2]=0;return}function vw(){return 11715}function mw(){return 1496}function gw(){return Wm()|0}function yw(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;if((Um(r,896)|0)==512){if(n|0){_w(n);KT(n)}}else if(t|0)KT(t);return}function _w(e){e=e|0;e=o[e+4>>2]|0;if(e|0)qT(e);return}function bw(e){e=e|0;Al(e);return}function ww(e,t){e=e|0;t=t|0;var n=0,r=0;fw()|0;n=o[2652]|0;e:do{if(n|0){while(1){r=o[n+4>>2]|0;if(r|0?(rT(Ew(r)|0,e)|0)==0:0)break;n=o[n>>2]|0;if(!n)break e}Dw(r,t)}}while(0);return}function Ew(e){e=e|0;return o[e+12>>2]|0}function Dw(e,t){e=e|0;t=t|0;var n=0;e=e+36|0;n=o[e>>2]|0;if(n|0){Ji(n);KT(n)}n=$T(4)|0;yu(n,t);o[e>>2]=n;return}function Sw(){if(!(r[11716]|0)){o[2664]=0;Fe(63,10656,g|0)|0;r[11716]=1}return 10656}function Cw(){var e=0;if(!(r[11717]|0)){kw();o[2665]=1504;r[11717]=1;e=1504}else e=o[2665]|0;return e|0}function kw(){if(!(r[11740]|0)){r[11718]=za(za(8,0)|0,0)|0;r[11719]=za(za(0,0)|0,0)|0;r[11720]=za(za(0,16)|0,0)|0;r[11721]=za(za(8,0)|0,0)|0;r[11722]=za(za(0,0)|0,0)|0;r[11723]=za(za(8,0)|0,0)|0;r[11724]=za(za(0,0)|0,0)|0;r[11725]=za(za(8,0)|0,0)|0;r[11726]=za(za(0,0)|0,0)|0;r[11727]=za(za(8,0)|0,0)|0;r[11728]=za(za(0,0)|0,0)|0;r[11729]=za(za(0,0)|0,32)|0;r[11730]=za(za(0,0)|0,32)|0;r[11740]=1}return}function Tw(){return 1572}function xw(e,t,n,r,i){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;var u=0,a=0,l=0,s=0,c=0,f=0;u=h;h=h+32|0;f=u+16|0;c=u+12|0;s=u+8|0;l=u+4|0;a=u;o[f>>2]=e;o[c>>2]=t;o[s>>2]=n;o[l>>2]=r;o[a>>2]=i;Sw()|0;Aw(10656,f,c,s,l,a);h=u;return}function Aw(e,t,n,r,i,u){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;u=u|0;var a=0;a=$T(24)|0;Ua(a+4|0,o[t>>2]|0,o[n>>2]|0,o[r>>2]|0,o[i>>2]|0,o[u>>2]|0);o[a>>2]=o[e>>2];o[e>>2]=a;return}function Ow(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0,v=0,m=0,g=0,y=0,_=0,b=0;b=h;h=h+32|0;m=b+20|0;g=b+8|0;y=b+4|0;_=b;t=o[t>>2]|0;if(t|0){v=m+4|0;s=m+8|0;c=g+4|0;f=g+8|0;d=g+8|0;p=m+8|0;do{a=t+4|0;l=Pw(a)|0;if(l|0){i=Iw(l)|0;o[m>>2]=0;o[v>>2]=0;o[s>>2]=0;r=(Nw(l)|0)+1|0;Mw(m,r);if(r|0)while(1){r=r+-1|0;gk(g,o[i>>2]|0);u=o[v>>2]|0;if(u>>>0<(o[p>>2]|0)>>>0){o[u>>2]=o[g>>2];o[v>>2]=(o[v>>2]|0)+4}else Rw(m,g);if(!r)break;else i=i+4|0}r=Fw(l)|0;o[g>>2]=0;o[c>>2]=0;o[f>>2]=0;e:do{if(o[r>>2]|0){i=0;u=0;while(1){if((i|0)==(u|0))Lw(g,r);else{o[i>>2]=o[r>>2];o[c>>2]=(o[c>>2]|0)+4}r=r+4|0;if(!(o[r>>2]|0))break e;i=o[c>>2]|0;u=o[d>>2]|0}}}while(0);o[y>>2]=Bw(a)|0;o[_>>2]=Xa(l)|0;jw(n,e,y,_,m,g);Uw(g);zw(m)}t=o[t>>2]|0}while((t|0)!=0)}h=b;return}function Pw(e){e=e|0;return o[e+12>>2]|0}function Iw(e){e=e|0;return o[e+12>>2]|0}function Nw(e){e=e|0;return o[e+16>>2]|0}function Mw(e,t){e=e|0;t=t|0;var n=0,r=0,i=0;i=h;h=h+32|0;n=i;r=o[e>>2]|0;if((o[e+8>>2]|0)-r>>2>>>0>>0){bE(n,t,(o[e+4>>2]|0)-r>>2,e+8|0);wE(e,n);EE(n)}h=i;return}function Rw(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0;a=h;h=h+32|0;n=a;r=e+4|0;i=((o[r>>2]|0)-(o[e>>2]|0)>>2)+1|0;u=mE(e)|0;if(u>>>0>>0)UT(e);else{l=o[e>>2]|0;c=(o[e+8>>2]|0)-l|0;s=c>>1;bE(n,c>>2>>>0>>1>>>0?s>>>0>>0?i:s:u,(o[r>>2]|0)-l>>2,e+8|0);u=n+8|0;o[o[u>>2]>>2]=o[t>>2];o[u>>2]=(o[u>>2]|0)+4;wE(e,n);EE(n);h=a;return}}function Fw(e){e=e|0;return o[e+8>>2]|0}function Lw(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0;a=h;h=h+32|0;n=a;r=e+4|0;i=((o[r>>2]|0)-(o[e>>2]|0)>>2)+1|0;u=pE(e)|0;if(u>>>0>>0)UT(e);else{l=o[e>>2]|0;c=(o[e+8>>2]|0)-l|0;s=c>>1;gE(n,c>>2>>>0>>1>>>0?s>>>0>>0?i:s:u,(o[r>>2]|0)-l>>2,e+8|0);u=n+8|0;o[o[u>>2]>>2]=o[t>>2];o[u>>2]=(o[u>>2]|0)+4;yE(e,n);_E(n);h=a;return}}function Bw(e){e=e|0;return o[e>>2]|0}function jw(e,t,n,r,i,o){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;o=o|0;Ww(e,t,n,r,i,o);return}function Uw(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-4-r|0)>>>2)<<2);KT(n)}return}function zw(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-4-r|0)>>>2)<<2);KT(n)}return}function Ww(e,t,n,r,i,u){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;u=u|0;var a=0,l=0,s=0,c=0,f=0,d=0;a=h;h=h+48|0;f=a+40|0;l=a+32|0;d=a+24|0;s=a+12|0;c=a;Dk(l);e=Eu(e)|0;o[d>>2]=o[t>>2];n=o[n>>2]|0;r=o[r>>2]|0;Hw(s,i);Vw(c,u);o[f>>2]=o[d>>2];qw(e,f,n,r,s,c);Uw(c);zw(s);Ck(l);h=a;return}function Hw(e,t){e=e|0;t=t|0;var n=0,r=0;o[e>>2]=0;o[e+4>>2]=0;o[e+8>>2]=0;n=t+4|0;r=(o[n>>2]|0)-(o[t>>2]|0)>>2;if(r|0){hE(e,r);vE(e,o[t>>2]|0,o[n>>2]|0,r)}return}function Vw(e,t){e=e|0;t=t|0;var n=0,r=0;o[e>>2]=0;o[e+4>>2]=0;o[e+8>>2]=0;n=t+4|0;r=(o[n>>2]|0)-(o[t>>2]|0)>>2;if(r|0){fE(e,r);dE(e,o[t>>2]|0,o[n>>2]|0,r)}return}function qw(e,t,n,r,i,u){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;u=u|0;var a=0,l=0,s=0,c=0,f=0,d=0;a=h;h=h+32|0;f=a+28|0;d=a+24|0;l=a+12|0;s=a;c=Cu(Gw()|0)|0;o[d>>2]=o[t>>2];o[f>>2]=o[d>>2];t=$w(f)|0;n=Yw(n)|0;r=Kw(r)|0;o[l>>2]=o[i>>2];f=i+4|0;o[l+4>>2]=o[f>>2];d=i+8|0;o[l+8>>2]=o[d>>2];o[d>>2]=0;o[f>>2]=0;o[i>>2]=0;i=Xw(l)|0;o[s>>2]=o[u>>2];f=u+4|0;o[s+4>>2]=o[f>>2];d=u+8|0;o[s+8>>2]=o[d>>2];o[d>>2]=0;o[f>>2]=0;o[u>>2]=0;Oe(0,c|0,e|0,t|0,n|0,r|0,i|0,Qw(s)|0)|0;Uw(s);zw(l);h=a;return}function Gw(){var e=0;if(!(r[7968]|0)){sE(10708);e=7968;o[e>>2]=1;o[e+4>>2]=0}return 10708}function $w(e){e=e|0;return tE(e)|0}function Yw(e){e=e|0;return Zw(e)|0}function Kw(e){e=e|0;return Jc(e)|0}function Xw(e){e=e|0;return eE(e)|0}function Qw(e){e=e|0;return Jw(e)|0}function Jw(e){e=e|0;var t=0,n=0,r=0;r=(o[e+4>>2]|0)-(o[e>>2]|0)|0;n=r>>2;r=UD(r+4|0)|0;o[r>>2]=n;if(n|0){t=0;do{o[r+4+(t<<2)>>2]=Zw(o[(o[e>>2]|0)+(t<<2)>>2]|0)|0;t=t+1|0}while((t|0)!=(n|0))}return r|0}function Zw(e){e=e|0;return e|0}function eE(e){e=e|0;var t=0,n=0,r=0;r=(o[e+4>>2]|0)-(o[e>>2]|0)|0;n=r>>2;r=UD(r+4|0)|0;o[r>>2]=n;if(n|0){t=0;do{o[r+4+(t<<2)>>2]=tE((o[e>>2]|0)+(t<<2)|0)|0;t=t+1|0}while((t|0)!=(n|0))}return r|0}function tE(e){e=e|0;var t=0,n=0,r=0,i=0;i=h;h=h+32|0;t=i+12|0;n=i;r=al(nE()|0)|0;if(!r)e=rE(e)|0;else{ll(t,r);sl(n,t);bk(e,n);e=fl(t)|0}h=i;return e|0}function nE(){var e=0;if(!(r[7960]|0)){lE(10664);Fe(25,10664,g|0)|0;e=7960;o[e>>2]=1;o[e+4>>2]=0}return 10664}function rE(e){e=e|0;var t=0,n=0,r=0,i=0,u=0,a=0,l=0;n=h;h=h+16|0;i=n+4|0;a=n;r=UD(8)|0;t=r;l=$T(4)|0;o[l>>2]=o[e>>2];u=t+4|0;o[u>>2]=l;e=$T(8)|0;u=o[u>>2]|0;o[a>>2]=0;o[i>>2]=o[a>>2];iE(e,u,i);o[r>>2]=e;h=n;return t|0}function iE(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;n=$T(16)|0;o[n+4>>2]=0;o[n+8>>2]=0;o[n>>2]=1656;o[n+12>>2]=t;o[e+4>>2]=n;return}function oE(e){e=e|0;zT(e);KT(e);return}function uE(e){e=e|0;e=o[e+12>>2]|0;if(e|0)KT(e);return}function aE(e){e=e|0;KT(e);return}function lE(e){e=e|0;Al(e);return}function sE(e){e=e|0;Lu(e,cE()|0,5);return}function cE(){return 1676}function fE(e,t){e=e|0;t=t|0;var n=0;if((pE(e)|0)>>>0>>0)UT(e);if(t>>>0>1073741823)Ye();else{n=$T(t<<2)|0;o[e+4>>2]=n;o[e>>2]=n;o[e+8>>2]=n+(t<<2);return}}function dE(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;r=e+4|0;e=n-t|0;if((e|0)>0){ix(o[r>>2]|0,t|0,e|0)|0;o[r>>2]=(o[r>>2]|0)+(e>>>2<<2)}return}function pE(e){e=e|0;return 1073741823}function hE(e,t){e=e|0;t=t|0;var n=0;if((mE(e)|0)>>>0>>0)UT(e);if(t>>>0>1073741823)Ye();else{n=$T(t<<2)|0;o[e+4>>2]=n;o[e>>2]=n;o[e+8>>2]=n+(t<<2);return}}function vE(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;r=e+4|0;e=n-t|0;if((e|0)>0){ix(o[r>>2]|0,t|0,e|0)|0;o[r>>2]=(o[r>>2]|0)+(e>>>2<<2)}return}function mE(e){e=e|0;return 1073741823}function gE(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>1073741823)Ye();else{i=$T(t<<2)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n<<2)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t<<2);return}function yE(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(0-(i>>2)<<2)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function _E(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~((r+-4-t|0)>>>2)<<2);e=o[e>>2]|0;if(e|0)KT(e);return}function bE(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>1073741823)Ye();else{i=$T(t<<2)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n<<2)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t<<2);return}function wE(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(0-(i>>2)<<2)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function EE(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~((r+-4-t|0)>>>2)<<2);e=o[e>>2]|0;if(e|0)KT(e);return}function DE(e,t,n,r,i){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;var u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0,v=0,m=0,g=0;g=h;h=h+32|0;f=g+20|0;d=g+12|0;c=g+16|0;p=g+4|0;v=g;m=g+8|0;l=Cw()|0;u=o[l>>2]|0;a=o[u>>2]|0;if(a|0){s=o[l+8>>2]|0;l=o[l+4>>2]|0;while(1){gk(f,a);SE(e,f,l,s);u=u+4|0;a=o[u>>2]|0;if(!a)break;else{s=s+1|0;l=l+1|0}}}u=Tw()|0;a=o[u>>2]|0;if(a|0)do{gk(f,a);o[d>>2]=o[u+4>>2];CE(t,f,d);u=u+8|0;a=o[u>>2]|0}while((a|0)!=0);u=o[(fw()|0)>>2]|0;if(u|0)do{t=o[u+4>>2]|0;gk(f,o[(kE(t)|0)>>2]|0);o[d>>2]=Ew(t)|0;TE(n,f,d);u=o[u>>2]|0}while((u|0)!=0);gk(c,0);u=Sw()|0;o[f>>2]=o[c>>2];Ow(f,u,i);u=o[(fw()|0)>>2]|0;if(u|0){e=f+4|0;t=f+8|0;n=f+8|0;do{s=o[u+4>>2]|0;gk(d,o[(kE(s)|0)>>2]|0);AE(p,xE(s)|0);a=o[p>>2]|0;if(a|0){o[f>>2]=0;o[e>>2]=0;o[t>>2]=0;do{gk(v,o[(kE(o[a+4>>2]|0)|0)>>2]|0);l=o[e>>2]|0;if(l>>>0<(o[n>>2]|0)>>>0){o[l>>2]=o[v>>2];o[e>>2]=(o[e>>2]|0)+4}else Rw(f,v);a=o[a>>2]|0}while((a|0)!=0);OE(r,d,f);zw(f)}o[m>>2]=o[d>>2];c=PE(s)|0;o[f>>2]=o[m>>2];Ow(f,c,i);kl(p);u=o[u>>2]|0}while((u|0)!=0)}h=g;return}function SE(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;qE(e,t,n,r);return}function CE(e,t,n){e=e|0;t=t|0;n=n|0;VE(e,t,n);return}function kE(e){e=e|0;return e|0}function TE(e,t,n){e=e|0;t=t|0;n=n|0;jE(e,t,n);return}function xE(e){e=e|0;return e+16|0}function AE(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0;u=h;h=h+16|0;i=u+8|0;n=u;o[e>>2]=0;r=o[t>>2]|0;o[i>>2]=r;o[n>>2]=e;n=LE(n)|0;if(r|0){r=$T(12)|0;a=(BE(i)|0)+4|0;e=o[a+4>>2]|0;t=r+4|0;o[t>>2]=o[a>>2];o[t+4>>2]=e;t=o[o[i>>2]>>2]|0;o[i>>2]=t;if(!t)e=r;else{t=r;while(1){e=$T(12)|0;s=(BE(i)|0)+4|0;l=o[s+4>>2]|0;a=e+4|0;o[a>>2]=o[s>>2];o[a+4>>2]=l;o[t>>2]=e;a=o[o[i>>2]>>2]|0;o[i>>2]=a;if(!a)break;else t=e}}o[e>>2]=o[n>>2];o[n>>2]=r}h=u;return}function OE(e,t,n){e=e|0;t=t|0;n=n|0;IE(e,t,n);return}function PE(e){e=e|0;return e+24|0}function IE(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+32|0;a=r+24|0;i=r+16|0;l=r+12|0;u=r;Dk(i);e=Eu(e)|0;o[l>>2]=o[t>>2];Hw(u,n);o[a>>2]=o[l>>2];NE(e,a,u);zw(u);Ck(i);h=r;return}function NE(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0;r=h;h=h+32|0;a=r+16|0;l=r+12|0;i=r;u=Cu(ME()|0)|0;o[l>>2]=o[t>>2];o[a>>2]=o[l>>2];t=$w(a)|0;o[i>>2]=o[n>>2];a=n+4|0;o[i+4>>2]=o[a>>2];l=n+8|0;o[i+8>>2]=o[l>>2];o[l>>2]=0;o[a>>2]=0;o[n>>2]=0;ke(0,u|0,e|0,t|0,Xw(i)|0)|0;zw(i);h=r;return}function ME(){var e=0;if(!(r[7976]|0)){RE(10720);e=7976;o[e>>2]=1;o[e+4>>2]=0}return 10720}function RE(e){e=e|0;Lu(e,FE()|0,2);return}function FE(){return 1732}function LE(e){e=e|0;return o[e>>2]|0}function BE(e){e=e|0;return o[e>>2]|0}function jE(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+32|0;u=r+16|0;i=r+8|0;a=r;Dk(i);e=Eu(e)|0;o[a>>2]=o[t>>2];n=o[n>>2]|0;o[u>>2]=o[a>>2];UE(e,u,n);Ck(i);h=r;return}function UE(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+16|0;u=r+4|0;a=r;i=Cu(zE()|0)|0;o[a>>2]=o[t>>2];o[u>>2]=o[a>>2];t=$w(u)|0;ke(0,i|0,e|0,t|0,Yw(n)|0)|0;h=r;return}function zE(){var e=0;if(!(r[7984]|0)){WE(10732);e=7984;o[e>>2]=1;o[e+4>>2]=0}return 10732}function WE(e){e=e|0;Lu(e,HE()|0,2);return}function HE(){return 1744}function VE(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0;r=h;h=h+32|0;u=r+16|0;i=r+8|0;a=r;Dk(i);e=Eu(e)|0;o[a>>2]=o[t>>2];n=o[n>>2]|0;o[u>>2]=o[a>>2];UE(e,u,n);Ck(i);h=r;return}function qE(e,t,n,i){e=e|0;t=t|0;n=n|0;i=i|0;var u=0,a=0,l=0,s=0;u=h;h=h+32|0;l=u+16|0;a=u+8|0;s=u;Dk(a);e=Eu(e)|0;o[s>>2]=o[t>>2];n=r[n>>0]|0;i=r[i>>0]|0;o[l>>2]=o[s>>2];GE(e,l,n,i);Ck(a);h=u;return}function GE(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0;i=h;h=h+16|0;a=i+4|0;l=i;u=Cu($E()|0)|0;o[l>>2]=o[t>>2];o[a>>2]=o[l>>2];t=$w(a)|0;n=YE(n)|0;nt(0,u|0,e|0,t|0,n|0,YE(r)|0)|0;h=i;return}function $E(){var e=0;if(!(r[7992]|0)){XE(10744);e=7992;o[e>>2]=1;o[e+4>>2]=0}return 10744}function YE(e){e=e|0;return KE(e)|0}function KE(e){e=e|0;return e&255|0}function XE(e){e=e|0;Lu(e,QE()|0,3);return}function QE(){return 1756}function JE(e,t,n){e=e|0;t=t|0;n=n|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0,v=0;v=h;h=h+32|0;s=v+8|0;c=v+4|0;f=v+20|0;d=v;Vs(e,0);i=_k(t)|0;o[s>>2]=0;p=s+4|0;o[p>>2]=0;o[s+8>>2]=0;switch(i<<24>>24){case 0:{r[f>>0]=0;ZE(c,n,f);eD(e,c)|0;Zi(c);break}case 8:{p=yk(t)|0;r[f>>0]=8;gk(d,o[p+4>>2]|0);tD(c,n,f,d,p+8|0);eD(e,c)|0;Zi(c);break}case 9:{a=yk(t)|0;t=o[a+4>>2]|0;if(t|0){l=s+8|0;u=a+12|0;while(1){t=t+-1|0;gk(c,o[u>>2]|0);i=o[p>>2]|0;if(i>>>0<(o[l>>2]|0)>>>0){o[i>>2]=o[c>>2];o[p>>2]=(o[p>>2]|0)+4}else Rw(s,c);if(!t)break;else u=u+4|0}}r[f>>0]=9;gk(d,o[a+8>>2]|0);nD(c,n,f,d,s);eD(e,c)|0;Zi(c);break}default:{p=yk(t)|0;r[f>>0]=i;gk(d,o[p+4>>2]|0);rD(c,n,f,d);eD(e,c)|0;Zi(c)}}zw(s);h=v;return}function ZE(e,t,n){e=e|0;t=t|0;n=n|0;var i=0,o=0;i=h;h=h+16|0;o=i;Dk(o);t=Eu(t)|0;gD(e,t,r[n>>0]|0);Ck(o);h=i;return}function eD(e,t){e=e|0;t=t|0;var n=0;n=o[e>>2]|0;if(n|0)rt(n|0);o[e>>2]=o[t>>2];o[t>>2]=0;return e|0}function tD(e,t,n,i,u){e=e|0;t=t|0;n=n|0;i=i|0;u=u|0;var a=0,l=0,s=0,c=0;a=h;h=h+32|0;s=a+16|0;l=a+8|0;c=a;Dk(l);t=Eu(t)|0;n=r[n>>0]|0;o[c>>2]=o[i>>2];u=o[u>>2]|0;o[s>>2]=o[c>>2];pD(e,t,n,s,u);Ck(l);h=a;return}function nD(e,t,n,i,u){e=e|0;t=t|0;n=n|0;i=i|0;u=u|0;var a=0,l=0,s=0,c=0,f=0;a=h;h=h+32|0;c=a+24|0;l=a+16|0;f=a+12|0;s=a;Dk(l);t=Eu(t)|0;n=r[n>>0]|0;o[f>>2]=o[i>>2];Hw(s,u);o[c>>2]=o[f>>2];sD(e,t,n,c,s);zw(s);Ck(l);h=a;return}function rD(e,t,n,i){e=e|0;t=t|0;n=n|0;i=i|0;var u=0,a=0,l=0,s=0;u=h;h=h+32|0;l=u+16|0;a=u+8|0;s=u;Dk(a);t=Eu(t)|0;n=r[n>>0]|0;o[s>>2]=o[i>>2];o[l>>2]=o[s>>2];iD(e,t,n,l);Ck(a);h=u;return}function iD(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0,a=0,l=0;i=h;h=h+16|0;u=i+4|0;l=i;a=Cu(oD()|0)|0;n=YE(n)|0;o[l>>2]=o[r>>2];o[u>>2]=o[l>>2];uD(e,ke(0,a|0,t|0,n|0,$w(u)|0)|0);h=i;return}function oD(){var e=0;if(!(r[8e3]|0)){aD(10756);e=8e3;o[e>>2]=1;o[e+4>>2]=0}return 10756}function uD(e,t){e=e|0;t=t|0;Vs(e,t);return}function aD(e){e=e|0;Lu(e,lD()|0,2);return}function lD(){return 1772}function sD(e,t,n,r,i){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;var u=0,a=0,l=0,s=0,c=0;u=h;h=h+32|0;s=u+16|0;c=u+12|0;a=u;l=Cu(cD()|0)|0;n=YE(n)|0;o[c>>2]=o[r>>2];o[s>>2]=o[c>>2];r=$w(s)|0;o[a>>2]=o[i>>2];s=i+4|0;o[a+4>>2]=o[s>>2];c=i+8|0;o[a+8>>2]=o[c>>2];o[c>>2]=0;o[s>>2]=0;o[i>>2]=0;uD(e,nt(0,l|0,t|0,n|0,r|0,Xw(a)|0)|0);zw(a);h=u;return}function cD(){var e=0;if(!(r[8008]|0)){fD(10768);e=8008;o[e>>2]=1;o[e+4>>2]=0}return 10768}function fD(e){e=e|0;Lu(e,dD()|0,3);return}function dD(){return 1784}function pD(e,t,n,r,i){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;var u=0,a=0,l=0,s=0;u=h;h=h+16|0;l=u+4|0;s=u;a=Cu(hD()|0)|0;n=YE(n)|0;o[s>>2]=o[r>>2];o[l>>2]=o[s>>2];r=$w(l)|0;uD(e,nt(0,a|0,t|0,n|0,r|0,Kw(i)|0)|0);h=u;return}function hD(){var e=0;if(!(r[8016]|0)){vD(10780);e=8016;o[e>>2]=1;o[e+4>>2]=0}return 10780}function vD(e){e=e|0;Lu(e,mD()|0,3);return}function mD(){return 1800}function gD(e,t,n){e=e|0;t=t|0;n=n|0;var r=0;r=Cu(yD()|0)|0;uD(e,it(0,r|0,t|0,YE(n)|0)|0);return}function yD(){var e=0;if(!(r[8024]|0)){_D(10792);e=8024;o[e>>2]=1;o[e+4>>2]=0}return 10792}function _D(e){e=e|0;Lu(e,bD()|0,1);return}function bD(){return 1816}function wD(){ED();DD();SD();return}function ED(){o[2702]=YT(65536)|0;return}function DD(){$D(10856);return}function SD(){CD(10816);return}function CD(e){e=e|0;kD(e,5044);TD(e)|0;return}function kD(e,t){e=e|0;t=t|0;var n=0;n=nE()|0;o[e>>2]=n;zD(n,t);cw(o[e>>2]|0);return}function TD(e){e=e|0;var t=0;t=o[e>>2]|0;r_(t,xD()|0);return e|0}function xD(){var e=0;if(!(r[8032]|0)){AD(10820);Fe(64,10820,g|0)|0;e=8032;o[e>>2]=1;o[e+4>>2]=0}if(!(Xa(10820)|0))AD(10820);return 10820}function AD(e){e=e|0;ID(e);s_(e,25);return}function OD(e){e=e|0;PD(e+24|0);return}function PD(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function ID(e){e=e|0;var t=0;t=Za()|0;nl(e,5,18,t,LD()|0,1);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function ND(e,t){e=e|0;t=t|0;MD(e,t);return}function MD(e,t){e=e|0;t=t|0;var n=0,r=0,i=0;n=h;h=h+16|0;r=n;i=n+4|0;cc(i,t);o[r>>2]=fc(i,t)|0;RD(e,r);h=n;return}function RD(e,t){e=e|0;t=t|0;FD(e+4|0,o[t>>2]|0);r[e+8>>0]=1;return}function FD(e,t){e=e|0;t=t|0;o[e>>2]=t;return}function LD(){return 1824}function BD(e){e=e|0;return jD(e)|0}function jD(e){e=e|0;var t=0,n=0,r=0,i=0,u=0,a=0,l=0;n=h;h=h+16|0;i=n+4|0;a=n;r=UD(8)|0;t=r;l=$T(4)|0;cc(i,e);FD(l,fc(i,e)|0);u=t+4|0;o[u>>2]=l;e=$T(8)|0;u=o[u>>2]|0;o[a>>2]=0;o[i>>2]=o[a>>2];iE(e,u,i);o[r>>2]=e;h=n;return t|0}function UD(e){e=e|0;var t=0,n=0;e=e+7&-8;if(e>>>0<=32768?(t=o[2701]|0,e>>>0<=(65536-t|0)>>>0):0){n=(o[2702]|0)+t|0;o[2701]=t+e;e=n}else{e=YT(e+8|0)|0;o[e>>2]=o[2703];o[2703]=e;e=e+8|0}return e|0}function zD(e,t){e=e|0;t=t|0;o[e>>2]=WD()|0;o[e+4>>2]=HD()|0;o[e+12>>2]=t;o[e+8>>2]=VD()|0;o[e+32>>2]=9;return}function WD(){return 11744}function HD(){return 1832}function VD(){return N_()|0}function qD(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;if((Um(r,896)|0)==512){if(n|0){GD(n);KT(n)}}else if(t|0)KT(t);return}function GD(e){e=e|0;e=o[e+4>>2]|0;if(e|0)qT(e);return}function $D(e){e=e|0;YD(e,5052);KD(e)|0;XD(e,5058,26)|0;QD(e,5069,1)|0;JD(e,5077,10)|0;ZD(e,5087,19)|0;tS(e,5094,27)|0;return}function YD(e,t){e=e|0;t=t|0;var n=0;n=sk()|0;o[e>>2]=n;ck(n,t);cw(o[e>>2]|0);return}function KD(e){e=e|0;var t=0;t=o[e>>2]|0;r_(t,YC()|0);return e|0}function XD(e,t,n){e=e|0;t=t|0;n=n|0;TC(e,Ia(t)|0,n,0);return e|0}function QD(e,t,n){e=e|0;t=t|0;n=n|0;sC(e,Ia(t)|0,n,0);return e|0}function JD(e,t,n){e=e|0;t=t|0;n=n|0;BS(e,Ia(t)|0,n,0);return e|0}function ZD(e,t,n){e=e|0;t=t|0;n=n|0;bS(e,Ia(t)|0,n,0);return e|0}function eS(e,t){e=e|0;t=t|0;var n=0,r=0;e:while(1){n=o[2703]|0;while(1){if((n|0)==(t|0))break e;r=o[n>>2]|0;o[2703]=r;if(!n)n=r;else break}KT(n)}o[2701]=e;return}function tS(e,t,n){e=e|0;t=t|0;n=n|0;nS(e,Ia(t)|0,n,0);return e|0}function nS(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0;u=o[e>>2]|0;i=rS()|0;e=iS(n)|0;La(u,t,i,e,oS(n,r)|0,r);return}function rS(){var e=0,t=0;if(!(r[8040]|0)){dS(10860);Fe(65,10860,g|0)|0;t=8040;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(10860)|0)){e=10860;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));dS(10860)}return 10860}function iS(e){e=e|0;return e|0}function oS(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0;l=h;h=h+16|0;i=l;u=l+4|0;o[i>>2]=e;s=rS()|0;a=s+24|0;t=za(t,4)|0;o[u>>2]=t;n=s+28|0;r=o[n>>2]|0;if(r>>>0<(o[s+32>>2]|0)>>>0){uS(r,e,t);t=(o[n>>2]|0)+8|0;o[n>>2]=t}else{aS(a,i,u);t=o[n>>2]|0}h=l;return(t-(o[a>>2]|0)>>3)+-1|0}function uS(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;o[e+4>>2]=n;return}function aS(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0;l=h;h=h+32|0;i=l;u=e+4|0;a=((o[u>>2]|0)-(o[e>>2]|0)>>3)+1|0;r=lS(e)|0;if(r>>>0>>0)UT(e);else{s=o[e>>2]|0;f=(o[e+8>>2]|0)-s|0;c=f>>2;sS(i,f>>3>>>0>>1>>>0?c>>>0>>0?a:c:r,(o[u>>2]|0)-s>>3,e+8|0);a=i+8|0;uS(o[a>>2]|0,o[t>>2]|0,o[n>>2]|0);o[a>>2]=(o[a>>2]|0)+8;cS(e,i);fS(i);h=l;return}}function lS(e){e=e|0;return 536870911}function sS(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>536870911)Ye();else{i=$T(t<<3)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n<<3)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t<<3);return}function cS(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(0-(i>>3)<<3)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function fS(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~((r+-8-t|0)>>>3)<<3);e=o[e>>2]|0;if(e|0)KT(e);return}function dS(e){e=e|0;vS(e);return}function pS(e){e=e|0;hS(e+24|0);return}function hS(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function vS(e){e=e|0;var t=0;t=Za()|0;nl(e,1,11,t,mS()|0,2);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function mS(){return 1840}function gS(e,t,n){e=e|0;t=t|0;n=n|0;_S(o[(yS(e)|0)>>2]|0,t,n);return}function yS(e){e=e|0;return(o[(rS()|0)+24>>2]|0)+(e<<3)|0}function _S(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,o=0;r=h;h=h+16|0;o=r+1|0;i=r;cc(o,t);t=fc(o,t)|0;cc(i,n);n=fc(i,n)|0;vA[e&31](t,n);h=r;return}function bS(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0;u=o[e>>2]|0;i=wS()|0;e=ES(n)|0;La(u,t,i,e,DS(n,r)|0,r);return}function wS(){var e=0,t=0;if(!(r[8048]|0)){OS(10896);Fe(66,10896,g|0)|0;t=8048;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(10896)|0)){e=10896;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));OS(10896)}return 10896}function ES(e){e=e|0;return e|0}function DS(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0;l=h;h=h+16|0;i=l;u=l+4|0;o[i>>2]=e;s=wS()|0;a=s+24|0;t=za(t,4)|0;o[u>>2]=t;n=s+28|0;r=o[n>>2]|0;if(r>>>0<(o[s+32>>2]|0)>>>0){SS(r,e,t);t=(o[n>>2]|0)+8|0;o[n>>2]=t}else{CS(a,i,u);t=o[n>>2]|0}h=l;return(t-(o[a>>2]|0)>>3)+-1|0}function SS(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;o[e+4>>2]=n;return}function CS(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0;l=h;h=h+32|0;i=l;u=e+4|0;a=((o[u>>2]|0)-(o[e>>2]|0)>>3)+1|0;r=kS(e)|0;if(r>>>0>>0)UT(e);else{s=o[e>>2]|0;f=(o[e+8>>2]|0)-s|0;c=f>>2;TS(i,f>>3>>>0>>1>>>0?c>>>0>>0?a:c:r,(o[u>>2]|0)-s>>3,e+8|0);a=i+8|0;SS(o[a>>2]|0,o[t>>2]|0,o[n>>2]|0);o[a>>2]=(o[a>>2]|0)+8;xS(e,i);AS(i);h=l;return}}function kS(e){e=e|0;return 536870911}function TS(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>536870911)Ye();else{i=$T(t<<3)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n<<3)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t<<3);return}function xS(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(0-(i>>3)<<3)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function AS(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~((r+-8-t|0)>>>3)<<3);e=o[e>>2]|0;if(e|0)KT(e);return}function OS(e){e=e|0;NS(e);return}function PS(e){e=e|0;IS(e+24|0);return}function IS(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function NS(e){e=e|0;var t=0;t=Za()|0;nl(e,1,11,t,MS()|0,1);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function MS(){return 1852}function RS(e,t){e=e|0;t=t|0;return LS(o[(FS(e)|0)>>2]|0,t)|0}function FS(e){e=e|0;return(o[(wS()|0)+24>>2]|0)+(e<<3)|0}function LS(e,t){e=e|0;t=t|0;var n=0,r=0;n=h;h=h+16|0;r=n;cc(r,t);t=fc(r,t)|0;t=Jc(mA[e&31](t)|0)|0;h=n;return t|0}function BS(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0;u=o[e>>2]|0;i=jS()|0;e=US(n)|0;La(u,t,i,e,zS(n,r)|0,r);return}function jS(){var e=0,t=0;if(!(r[8056]|0)){YS(10932);Fe(67,10932,g|0)|0;t=8056;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(10932)|0)){e=10932;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));YS(10932)}return 10932}function US(e){e=e|0;return e|0}function zS(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0;l=h;h=h+16|0;i=l;u=l+4|0;o[i>>2]=e;s=jS()|0;a=s+24|0;t=za(t,4)|0;o[u>>2]=t;n=s+28|0;r=o[n>>2]|0;if(r>>>0<(o[s+32>>2]|0)>>>0){WS(r,e,t);t=(o[n>>2]|0)+8|0;o[n>>2]=t}else{HS(a,i,u);t=o[n>>2]|0}h=l;return(t-(o[a>>2]|0)>>3)+-1|0}function WS(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;o[e+4>>2]=n;return}function HS(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0;l=h;h=h+32|0;i=l;u=e+4|0;a=((o[u>>2]|0)-(o[e>>2]|0)>>3)+1|0;r=VS(e)|0;if(r>>>0>>0)UT(e);else{s=o[e>>2]|0;f=(o[e+8>>2]|0)-s|0;c=f>>2;qS(i,f>>3>>>0>>1>>>0?c>>>0>>0?a:c:r,(o[u>>2]|0)-s>>3,e+8|0);a=i+8|0;WS(o[a>>2]|0,o[t>>2]|0,o[n>>2]|0);o[a>>2]=(o[a>>2]|0)+8;GS(e,i);$S(i);h=l;return}}function VS(e){e=e|0;return 536870911}function qS(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>536870911)Ye();else{i=$T(t<<3)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n<<3)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t<<3);return}function GS(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(0-(i>>3)<<3)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function $S(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~((r+-8-t|0)>>>3)<<3);e=o[e>>2]|0;if(e|0)KT(e);return}function YS(e){e=e|0;QS(e);return}function KS(e){e=e|0;XS(e+24|0);return}function XS(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function QS(e){e=e|0;var t=0;t=Za()|0;nl(e,1,7,t,JS()|0,2);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function JS(){return 1860}function ZS(e,t,n){e=e|0;t=t|0;n=n|0;return tC(o[(eC(e)|0)>>2]|0,t,n)|0}function eC(e){e=e|0;return(o[(jS()|0)+24>>2]|0)+(e<<3)|0}function tC(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0;r=h;h=h+32|0;a=r+12|0;u=r+8|0;l=r;s=r+16|0;i=r+4|0;nC(s,t);rC(l,s,t);Us(i,n);n=zs(i,n)|0;o[a>>2]=o[l>>2];PA[e&15](u,a,n);n=iC(u)|0;Zi(u);Ws(i);h=r;return n|0}function nC(e,t){e=e|0;t=t|0;return}function rC(e,t,n){e=e|0;t=t|0;n=n|0;oC(e,n);return}function iC(e){e=e|0;return Eu(e)|0}function oC(e,t){e=e|0;t=t|0;var n=0,r=0,i=0;i=h;h=h+16|0;n=i;r=t;if(!(r&1))o[e>>2]=o[t>>2];else{uC(n,0);Be(r|0,n|0)|0;aC(e,n);lC(n)}h=i;return}function uC(e,t){e=e|0;t=t|0;Iu(e,t);o[e+4>>2]=0;r[e+8>>0]=0;return}function aC(e,t){e=e|0;t=t|0;o[e>>2]=o[t+4>>2];return}function lC(e){e=e|0;r[e+8>>0]=0;return}function sC(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0;u=o[e>>2]|0;i=cC()|0;e=fC(n)|0;La(u,t,i,e,dC(n,r)|0,r);return}function cC(){var e=0,t=0;if(!(r[8064]|0)){_C(10968);Fe(68,10968,g|0)|0;t=8064;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(10968)|0)){e=10968;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));_C(10968)}return 10968}function fC(e){e=e|0;return e|0}function dC(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0;l=h;h=h+16|0;i=l;u=l+4|0;o[i>>2]=e;s=cC()|0;a=s+24|0;t=za(t,4)|0;o[u>>2]=t;n=s+28|0;r=o[n>>2]|0;if(r>>>0<(o[s+32>>2]|0)>>>0){pC(r,e,t);t=(o[n>>2]|0)+8|0;o[n>>2]=t}else{hC(a,i,u);t=o[n>>2]|0}h=l;return(t-(o[a>>2]|0)>>3)+-1|0}function pC(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;o[e+4>>2]=n;return}function hC(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0;l=h;h=h+32|0;i=l;u=e+4|0;a=((o[u>>2]|0)-(o[e>>2]|0)>>3)+1|0;r=vC(e)|0;if(r>>>0>>0)UT(e);else{s=o[e>>2]|0;f=(o[e+8>>2]|0)-s|0;c=f>>2;mC(i,f>>3>>>0>>1>>>0?c>>>0>>0?a:c:r,(o[u>>2]|0)-s>>3,e+8|0);a=i+8|0;pC(o[a>>2]|0,o[t>>2]|0,o[n>>2]|0);o[a>>2]=(o[a>>2]|0)+8;gC(e,i);yC(i);h=l;return}}function vC(e){e=e|0;return 536870911}function mC(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>536870911)Ye();else{i=$T(t<<3)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n<<3)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t<<3);return}function gC(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(0-(i>>3)<<3)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function yC(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~((r+-8-t|0)>>>3)<<3);e=o[e>>2]|0;if(e|0)KT(e);return}function _C(e){e=e|0;EC(e);return}function bC(e){e=e|0;wC(e+24|0);return}function wC(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function EC(e){e=e|0;var t=0;t=Za()|0;nl(e,1,1,t,DC()|0,5);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function DC(){return 1872}function SC(e,t,n,r,i,u){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;u=u|0;kC(o[(CC(e)|0)>>2]|0,t,n,r,i,u);return}function CC(e){e=e|0;return(o[(cC()|0)+24>>2]|0)+(e<<3)|0}function kC(e,t,n,r,i,o){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;o=o|0;var u=0,a=0,l=0,s=0,c=0,f=0;u=h;h=h+32|0;a=u+16|0;l=u+12|0;s=u+8|0;c=u+4|0;f=u;Us(a,t);t=zs(a,t)|0;Us(l,n);n=zs(l,n)|0;Us(s,r);r=zs(s,r)|0;Us(c,i);i=zs(c,i)|0;Us(f,o);o=zs(f,o)|0;cA[e&1](t,n,r,i,o);Ws(f);Ws(c);Ws(s);Ws(l);Ws(a);h=u;return}function TC(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0;u=o[e>>2]|0;i=xC()|0;e=AC(n)|0;La(u,t,i,e,OC(n,r)|0,r);return}function xC(){var e=0,t=0;if(!(r[8072]|0)){LC(11004);Fe(69,11004,g|0)|0;t=8072;o[t>>2]=1;o[t+4>>2]=0}if(!(Xa(11004)|0)){e=11004;t=e+36|0;do{o[e>>2]=0;e=e+4|0}while((e|0)<(t|0));LC(11004)}return 11004}function AC(e){e=e|0;return e|0}function OC(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0,l=0,s=0;l=h;h=h+16|0;i=l;u=l+4|0;o[i>>2]=e;s=xC()|0;a=s+24|0;t=za(t,4)|0;o[u>>2]=t;n=s+28|0;r=o[n>>2]|0;if(r>>>0<(o[s+32>>2]|0)>>>0){PC(r,e,t);t=(o[n>>2]|0)+8|0;o[n>>2]=t}else{IC(a,i,u);t=o[n>>2]|0}h=l;return(t-(o[a>>2]|0)>>3)+-1|0}function PC(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;o[e+4>>2]=n;return}function IC(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0;l=h;h=h+32|0;i=l;u=e+4|0;a=((o[u>>2]|0)-(o[e>>2]|0)>>3)+1|0;r=NC(e)|0;if(r>>>0>>0)UT(e);else{s=o[e>>2]|0;f=(o[e+8>>2]|0)-s|0;c=f>>2;MC(i,f>>3>>>0>>1>>>0?c>>>0>>0?a:c:r,(o[u>>2]|0)-s>>3,e+8|0);a=i+8|0;PC(o[a>>2]|0,o[t>>2]|0,o[n>>2]|0);o[a>>2]=(o[a>>2]|0)+8;RC(e,i);FC(i);h=l;return}}function NC(e){e=e|0;return 536870911}function MC(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0;o[e+12>>2]=0;o[e+16>>2]=r;do{if(t){if(t>>>0>536870911)Ye();else{i=$T(t<<3)|0;break}}else i=0}while(0);o[e>>2]=i;r=i+(n<<3)|0;o[e+8>>2]=r;o[e+4>>2]=r;o[e+12>>2]=i+(t<<3);return}function RC(e,t){e=e|0;t=t|0;var n=0,r=0,i=0,u=0,a=0;r=o[e>>2]|0;a=e+4|0;u=t+4|0;i=(o[a>>2]|0)-r|0;n=(o[u>>2]|0)+(0-(i>>3)<<3)|0;o[u>>2]=n;if((i|0)>0){ix(n|0,r|0,i|0)|0;r=u;n=o[u>>2]|0}else r=u;u=o[e>>2]|0;o[e>>2]=n;o[r>>2]=u;u=t+8|0;i=o[a>>2]|0;o[a>>2]=o[u>>2];o[u>>2]=i;u=e+8|0;a=t+12|0;e=o[u>>2]|0;o[u>>2]=o[a>>2];o[a>>2]=e;o[t>>2]=o[r>>2];return}function FC(e){e=e|0;var t=0,n=0,r=0;t=o[e+4>>2]|0;n=e+8|0;r=o[n>>2]|0;if((r|0)!=(t|0))o[n>>2]=r+(~((r+-8-t|0)>>>3)<<3);e=o[e>>2]|0;if(e|0)KT(e);return}function LC(e){e=e|0;UC(e);return}function BC(e){e=e|0;jC(e+24|0);return}function jC(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function UC(e){e=e|0;var t=0;t=Za()|0;nl(e,1,12,t,zC()|0,2);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function zC(){return 1896}function WC(e,t,n){e=e|0;t=t|0;n=n|0;VC(o[(HC(e)|0)>>2]|0,t,n);return}function HC(e){e=e|0;return(o[(xC()|0)+24>>2]|0)+(e<<3)|0}function VC(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,o=0;r=h;h=h+16|0;o=r+4|0;i=r;qC(o,t);t=GC(o,t)|0;Us(i,n);n=zs(i,n)|0;vA[e&31](t,n);Ws(i);h=r;return}function qC(e,t){e=e|0;t=t|0;return}function GC(e,t){e=e|0;t=t|0;return $C(t)|0}function $C(e){e=e|0;return e|0}function YC(){var e=0;if(!(r[8080]|0)){KC(11040);Fe(70,11040,g|0)|0;e=8080;o[e>>2]=1;o[e+4>>2]=0}if(!(Xa(11040)|0))KC(11040);return 11040}function KC(e){e=e|0;JC(e);s_(e,71);return}function XC(e){e=e|0;QC(e+24|0);return}function QC(e){e=e|0;var t=0,n=0,r=0;n=o[e>>2]|0;r=n;if(n|0){e=e+4|0;t=o[e>>2]|0;if((t|0)!=(n|0))o[e>>2]=t+(~((t+-8-r|0)>>>3)<<3);KT(n)}return}function JC(e){e=e|0;var t=0;t=Za()|0;nl(e,5,7,t,nk()|0,0);o[e+24>>2]=0;o[e+28>>2]=0;o[e+32>>2]=0;return}function ZC(e){e=e|0;ek(e);return}function ek(e){e=e|0;tk(e);return}function tk(e){e=e|0;r[e+8>>0]=1;return}function nk(){return 1936}function rk(){return ik()|0}function ik(){var e=0,t=0,n=0,r=0,i=0,u=0,a=0;t=h;h=h+16|0;i=t+4|0;a=t;n=UD(8)|0;e=n;u=e+4|0;o[u>>2]=$T(1)|0;r=$T(8)|0;u=o[u>>2]|0;o[a>>2]=0;o[i>>2]=o[a>>2];ok(r,u,i);o[n>>2]=r;h=t;return e|0}function ok(e,t,n){e=e|0;t=t|0;n=n|0;o[e>>2]=t;n=$T(16)|0;o[n+4>>2]=0;o[n+8>>2]=0;o[n>>2]=1916;o[n+12>>2]=t;o[e+4>>2]=n;return}function uk(e){e=e|0;zT(e);KT(e);return}function ak(e){e=e|0;e=o[e+12>>2]|0;if(e|0)KT(e);return}function lk(e){e=e|0;KT(e);return}function sk(){var e=0;if(!(r[8088]|0)){mk(11076);Fe(25,11076,g|0)|0;e=8088;o[e>>2]=1;o[e+4>>2]=0}return 11076}function ck(e,t){e=e|0;t=t|0;o[e>>2]=fk()|0;o[e+4>>2]=dk()|0;o[e+12>>2]=t;o[e+8>>2]=pk()|0;o[e+32>>2]=10;return}function fk(){return 11745}function dk(){return 1940}function pk(){return Wm()|0}function hk(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;if((Um(r,896)|0)==512){if(n|0){vk(n);KT(n)}}else if(t|0)KT(t);return}function vk(e){e=e|0;e=o[e+4>>2]|0;if(e|0)qT(e);return}function mk(e){e=e|0;Al(e);return}function gk(e,t){e=e|0;t=t|0;o[e>>2]=t;return}function yk(e){e=e|0;return o[e>>2]|0}function _k(e){e=e|0;return r[o[e>>2]>>0]|0}function bk(e,t){e=e|0;t=t|0;var n=0,r=0;n=h;h=h+16|0;r=n;o[r>>2]=o[e>>2];wk(t,r)|0;h=n;return}function wk(e,t){e=e|0;t=t|0;var n=0;n=Ek(o[e>>2]|0,t)|0;t=e+4|0;o[(o[t>>2]|0)+8>>2]=n;return o[(o[t>>2]|0)+8>>2]|0}function Ek(e,t){e=e|0;t=t|0;var n=0,r=0;n=h;h=h+16|0;r=n;Dk(r);e=Eu(e)|0;t=Sk(e,o[t>>2]|0)|0;Ck(r);h=n;return t|0}function Dk(e){e=e|0;o[e>>2]=o[2701];o[e+4>>2]=o[2703];return}function Sk(e,t){e=e|0;t=t|0;var n=0;n=Cu(kk()|0)|0;return it(0,n|0,e|0,Kw(t)|0)|0}function Ck(e){e=e|0;eS(o[e>>2]|0,o[e+4>>2]|0);return}function kk(){var e=0;if(!(r[8096]|0)){Tk(11120);e=8096;o[e>>2]=1;o[e+4>>2]=0}return 11120}function Tk(e){e=e|0;Lu(e,xk()|0,1);return}function xk(){return 1948}function Ak(){Ok();return}function Ok(){var e=0,t=0,n=0,i=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0,v=0,m=0,g=0,y=0,_=0;y=h;h=h+16|0;p=y+4|0;v=y;Ne(65536,10804,o[2702]|0,10812);n=Cw()|0;t=o[n>>2]|0;e=o[t>>2]|0;if(e|0){i=o[n+8>>2]|0;n=o[n+4>>2]|0;while(1){ze(e|0,u[n>>0]|0|0,r[i>>0]|0);t=t+4|0;e=o[t>>2]|0;if(!e)break;else{i=i+1|0;n=n+1|0}}}e=Tw()|0;t=o[e>>2]|0;if(t|0)do{We(t|0,o[e+4>>2]|0);e=e+8|0;t=o[e>>2]|0}while((t|0)!=0);We(Pk()|0,5167);d=fw()|0;e=o[d>>2]|0;e:do{if(e|0){do{Ik(o[e+4>>2]|0);e=o[e>>2]|0}while((e|0)!=0);e=o[d>>2]|0;if(e|0){f=d;do{while(1){a=e;e=o[e>>2]|0;a=o[a+4>>2]|0;if(!(Nk(a)|0))break;o[v>>2]=f;o[p>>2]=o[v>>2];Mk(d,p)|0;if(!e)break e}Rk(a);f=o[f>>2]|0;t=Fk(a)|0;l=Xe()|0;s=h;h=h+((1*(t<<2)|0)+15&-16)|0;c=h;h=h+((1*(t<<2)|0)+15&-16)|0;t=o[(xE(a)|0)>>2]|0;if(t|0){n=s;i=c;while(1){o[n>>2]=o[(kE(o[t+4>>2]|0)|0)>>2];o[i>>2]=o[t+8>>2];t=o[t>>2]|0;if(!t)break;else{n=n+4|0;i=i+4|0}}}_=kE(a)|0;t=Lk(a)|0;n=Fk(a)|0;i=Bk(a)|0;Ge(_|0,t|0,s|0,c|0,n|0,i|0,Ew(a)|0);Re(l|0)}while((e|0)!=0)}}}while(0);e=o[(Sw()|0)>>2]|0;if(e|0)do{_=e+4|0;d=Pw(_)|0;a=Fw(d)|0;l=Iw(d)|0;s=(Nw(d)|0)+1|0;c=jk(d)|0;f=Uk(_)|0;d=Xa(d)|0;p=Bw(_)|0;v=zk(_)|0;Ve(0,a|0,l|0,s|0,c|0,f|0,d|0,p|0,v|0,Wk(_)|0);e=o[e>>2]|0}while((e|0)!=0);e=o[(fw()|0)>>2]|0;e:do{if(e|0){t:while(1){t=o[e+4>>2]|0;if(t|0?(m=o[(kE(t)|0)>>2]|0,g=o[(PE(t)|0)>>2]|0,g|0):0){n=g;do{t=n+4|0;i=Pw(t)|0;n:do{if(i|0)switch(Xa(i)|0){case 0:break t;case 4:case 3:case 2:{c=Fw(i)|0;f=Iw(i)|0;d=(Nw(i)|0)+1|0;p=jk(i)|0;v=Xa(i)|0;_=Bw(t)|0;Ve(m|0,c|0,f|0,d|0,p|0,0,v|0,_|0,zk(t)|0,Wk(t)|0);break n}case 1:{s=Fw(i)|0;c=Iw(i)|0;f=(Nw(i)|0)+1|0;d=jk(i)|0;p=Uk(t)|0;v=Xa(i)|0;_=Bw(t)|0;Ve(m|0,s|0,c|0,f|0,d|0,p|0,v|0,_|0,zk(t)|0,Wk(t)|0);break n}case 5:{d=Fw(i)|0;p=Iw(i)|0;v=(Nw(i)|0)+1|0;_=jk(i)|0;Ve(m|0,d|0,p|0,v|0,_|0,Hk(i)|0,Xa(i)|0,0,0,0);break n}default:break n}}while(0);n=o[n>>2]|0}while((n|0)!=0)}e=o[e>>2]|0;if(!e)break e}Ye()}}while(0);$e();h=y;return}function Pk(){return 11703}function Ik(e){e=e|0;r[e+40>>0]=0;return}function Nk(e){e=e|0;return(r[e+40>>0]|0)!=0|0}function Mk(e,t){e=e|0;t=t|0;t=Vk(t)|0;e=o[t>>2]|0;o[t>>2]=o[e>>2];KT(e);return o[t>>2]|0}function Rk(e){e=e|0;r[e+40>>0]=1;return}function Fk(e){e=e|0;return o[e+20>>2]|0}function Lk(e){e=e|0;return o[e+8>>2]|0}function Bk(e){e=e|0;return o[e+32>>2]|0}function jk(e){e=e|0;return o[e+4>>2]|0}function Uk(e){e=e|0;return o[e+4>>2]|0}function zk(e){e=e|0;return o[e+8>>2]|0}function Wk(e){e=e|0;return o[e+16>>2]|0}function Hk(e){e=e|0;return o[e+20>>2]|0}function Vk(e){e=e|0;return o[e>>2]|0}function qk(e){e=e|0;var t=0,n=0,r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0,v=0,m=0,g=0,y=0,_=0,b=0,w=0,E=0,D=0;D=h;h=h+16|0;p=D;do{if(e>>>0<245){c=e>>>0<11?16:e+11&-8;e=c>>>3;d=o[2783]|0;n=d>>>e;if(n&3|0){t=(n&1^1)+e|0;e=11172+(t<<1<<2)|0;n=e+8|0;r=o[n>>2]|0;i=r+8|0;u=o[i>>2]|0;if((e|0)==(u|0))o[2783]=d&~(1<>2]=e;o[n>>2]=u}E=t<<3;o[r+4>>2]=E|3;E=r+E+4|0;o[E>>2]=o[E>>2]|1;E=i;h=D;return E|0}f=o[2785]|0;if(c>>>0>f>>>0){if(n|0){t=2<>>12&16;t=t>>>a;n=t>>>5&8;t=t>>>n;i=t>>>2&4;t=t>>>i;e=t>>>1&2;t=t>>>e;r=t>>>1&1;r=(n|a|i|e|r)+(t>>>r)|0;t=11172+(r<<1<<2)|0;e=t+8|0;i=o[e>>2]|0;a=i+8|0;n=o[a>>2]|0;if((t|0)==(n|0)){e=d&~(1<>2]=t;o[e>>2]=n;e=d}u=(r<<3)-c|0;o[i+4>>2]=c|3;r=i+c|0;o[r+4>>2]=u|1;o[r+u>>2]=u;if(f|0){i=o[2788]|0;t=f>>>3;n=11172+(t<<1<<2)|0;t=1<>2]|0}o[e>>2]=i;o[t+12>>2]=i;o[i+8>>2]=t;o[i+12>>2]=n}o[2785]=u;o[2788]=r;E=a;h=D;return E|0}l=o[2784]|0;if(l){n=(l&0-l)+-1|0;a=n>>>12&16;n=n>>>a;u=n>>>5&8;n=n>>>u;s=n>>>2&4;n=n>>>s;r=n>>>1&2;n=n>>>r;e=n>>>1&1;e=o[11436+((u|a|s|r|e)+(n>>>e)<<2)>>2]|0;n=(o[e+4>>2]&-8)-c|0;r=o[e+16+(((o[e+16>>2]|0)==0&1)<<2)>>2]|0;if(!r){s=e;u=n}else{do{a=(o[r+4>>2]&-8)-c|0;s=a>>>0>>0;n=s?a:n;e=s?r:e;r=o[r+16+(((o[r+16>>2]|0)==0&1)<<2)>>2]|0}while((r|0)!=0);s=e;u=n}a=s+c|0;if(s>>>0>>0){i=o[s+24>>2]|0;t=o[s+12>>2]|0;do{if((t|0)==(s|0)){e=s+20|0;t=o[e>>2]|0;if(!t){e=s+16|0;t=o[e>>2]|0;if(!t){n=0;break}}while(1){n=t+20|0;r=o[n>>2]|0;if(r|0){t=r;e=n;continue}n=t+16|0;r=o[n>>2]|0;if(!r)break;else{t=r;e=n}}o[e>>2]=0;n=t}else{n=o[s+8>>2]|0;o[n+12>>2]=t;o[t+8>>2]=n;n=t}}while(0);do{if(i|0){t=o[s+28>>2]|0;e=11436+(t<<2)|0;if((s|0)==(o[e>>2]|0)){o[e>>2]=n;if(!n){o[2784]=l&~(1<>2]|0)!=(s|0)&1)<<2)>>2]=n;if(!n)break}o[n+24>>2]=i;t=o[s+16>>2]|0;if(t|0){o[n+16>>2]=t;o[t+24>>2]=n}t=o[s+20>>2]|0;if(t|0){o[n+20>>2]=t;o[t+24>>2]=n}}}while(0);if(u>>>0<16){E=u+c|0;o[s+4>>2]=E|3;E=s+E+4|0;o[E>>2]=o[E>>2]|1}else{o[s+4>>2]=c|3;o[a+4>>2]=u|1;o[a+u>>2]=u;if(f|0){r=o[2788]|0;t=f>>>3;n=11172+(t<<1<<2)|0;t=1<>2]|0}o[e>>2]=r;o[t+12>>2]=r;o[r+8>>2]=t;o[r+12>>2]=n}o[2785]=u;o[2788]=a}E=s+8|0;h=D;return E|0}else d=c}else d=c}else d=c}else if(e>>>0<=4294967231){e=e+11|0;c=e&-8;s=o[2784]|0;if(s){r=0-c|0;e=e>>>8;if(e){if(c>>>0>16777215)l=31;else{d=(e+1048320|0)>>>16&8;w=e<>>16&4;w=w<>>16&2;l=14-(f|d|l)+(w<>>15)|0;l=c>>>(l+7|0)&1|l<<1}}else l=0;n=o[11436+(l<<2)>>2]|0;e:do{if(!n){n=0;e=0;w=57}else{e=0;a=c<<((l|0)==31?0:25-(l>>>1)|0);u=0;while(1){i=(o[n+4>>2]&-8)-c|0;if(i>>>0>>0)if(!i){e=n;r=0;i=n;w=61;break e}else{e=n;r=i}i=o[n+20>>2]|0;n=o[n+16+(a>>>31<<2)>>2]|0;u=(i|0)==0|(i|0)==(n|0)?u:i;i=(n|0)==0;if(i){n=u;w=57;break}else a=a<<((i^1)&1)}}}while(0);if((w|0)==57){if((n|0)==0&(e|0)==0){e=2<>>12&16;d=d>>>a;u=d>>>5&8;d=d>>>u;l=d>>>2&4;d=d>>>l;f=d>>>1&2;d=d>>>f;n=d>>>1&1;e=0;n=o[11436+((u|a|l|f|n)+(d>>>n)<<2)>>2]|0}if(!n){l=e;a=r}else{i=n;w=61}}if((w|0)==61)while(1){w=0;n=(o[i+4>>2]&-8)-c|0;d=n>>>0>>0;n=d?n:r;e=d?i:e;i=o[i+16+(((o[i+16>>2]|0)==0&1)<<2)>>2]|0;if(!i){l=e;a=n;break}else{r=n;w=61}}if((l|0)!=0?a>>>0<((o[2785]|0)-c|0)>>>0:0){u=l+c|0;if(l>>>0>=u>>>0){E=0;h=D;return E|0}i=o[l+24>>2]|0;t=o[l+12>>2]|0;do{if((t|0)==(l|0)){e=l+20|0;t=o[e>>2]|0;if(!t){e=l+16|0;t=o[e>>2]|0;if(!t){t=0;break}}while(1){n=t+20|0;r=o[n>>2]|0;if(r|0){t=r;e=n;continue}n=t+16|0;r=o[n>>2]|0;if(!r)break;else{t=r;e=n}}o[e>>2]=0}else{E=o[l+8>>2]|0;o[E+12>>2]=t;o[t+8>>2]=E}}while(0);do{if(i){e=o[l+28>>2]|0;n=11436+(e<<2)|0;if((l|0)==(o[n>>2]|0)){o[n>>2]=t;if(!t){r=s&~(1<>2]|0)!=(l|0)&1)<<2)>>2]=t;if(!t){r=s;break}}o[t+24>>2]=i;e=o[l+16>>2]|0;if(e|0){o[t+16>>2]=e;o[e+24>>2]=t}e=o[l+20>>2]|0;if(e){o[t+20>>2]=e;o[e+24>>2]=t;r=s}else r=s}else r=s}while(0);do{if(a>>>0>=16){o[l+4>>2]=c|3;o[u+4>>2]=a|1;o[u+a>>2]=a;t=a>>>3;if(a>>>0<256){n=11172+(t<<1<<2)|0;e=o[2783]|0;t=1<>2]|0}o[e>>2]=u;o[t+12>>2]=u;o[u+8>>2]=t;o[u+12>>2]=n;break}t=a>>>8;if(t){if(a>>>0>16777215)t=31;else{w=(t+1048320|0)>>>16&8;E=t<>>16&4;E=E<>>16&2;t=14-(b|w|t)+(E<>>15)|0;t=a>>>(t+7|0)&1|t<<1}}else t=0;n=11436+(t<<2)|0;o[u+28>>2]=t;e=u+16|0;o[e+4>>2]=0;o[e>>2]=0;e=1<>2]=u;o[u+24>>2]=n;o[u+12>>2]=u;o[u+8>>2]=u;break}e=a<<((t|0)==31?0:25-(t>>>1)|0);n=o[n>>2]|0;while(1){if((o[n+4>>2]&-8|0)==(a|0)){w=97;break}r=n+16+(e>>>31<<2)|0;t=o[r>>2]|0;if(!t){w=96;break}else{e=e<<1;n=t}}if((w|0)==96){o[r>>2]=u;o[u+24>>2]=n;o[u+12>>2]=u;o[u+8>>2]=u;break}else if((w|0)==97){w=n+8|0;E=o[w>>2]|0;o[E+12>>2]=u;o[w>>2]=u;o[u+8>>2]=E;o[u+12>>2]=n;o[u+24>>2]=0;break}}else{E=a+c|0;o[l+4>>2]=E|3;E=l+E+4|0;o[E>>2]=o[E>>2]|1}}while(0);E=l+8|0;h=D;return E|0}else d=c}else d=c}else d=-1}while(0);n=o[2785]|0;if(n>>>0>=d>>>0){t=n-d|0;e=o[2788]|0;if(t>>>0>15){E=e+d|0;o[2788]=E;o[2785]=t;o[E+4>>2]=t|1;o[E+t>>2]=t;o[e+4>>2]=d|3}else{o[2785]=0;o[2788]=0;o[e+4>>2]=n|3;E=e+n+4|0;o[E>>2]=o[E>>2]|1}E=e+8|0;h=D;return E|0}a=o[2786]|0;if(a>>>0>d>>>0){b=a-d|0;o[2786]=b;E=o[2789]|0;w=E+d|0;o[2789]=w;o[w+4>>2]=b|1;o[E+4>>2]=d|3;E=E+8|0;h=D;return E|0}if(!(o[2901]|0)){o[2903]=4096;o[2902]=4096;o[2904]=-1;o[2905]=-1;o[2906]=0;o[2894]=0;e=p&-16^1431655768;o[p>>2]=e;o[2901]=e;e=4096}else e=o[2903]|0;l=d+48|0;s=d+47|0;u=e+s|0;i=0-e|0;c=u&i;if(c>>>0<=d>>>0){E=0;h=D;return E|0}e=o[2893]|0;if(e|0?(f=o[2891]|0,p=f+c|0,p>>>0<=f>>>0|p>>>0>e>>>0):0){E=0;h=D;return E|0}e:do{if(!(o[2894]&4)){n=o[2789]|0;t:do{if(n){r=11580;while(1){e=o[r>>2]|0;if(e>>>0<=n>>>0?(g=r+4|0,(e+(o[g>>2]|0)|0)>>>0>n>>>0):0)break;e=o[r+8>>2]|0;if(!e){w=118;break t}else r=e}t=u-a&i;if(t>>>0<2147483647){e=lx(t|0)|0;if((e|0)==((o[r>>2]|0)+(o[g>>2]|0)|0)){if((e|0)!=(-1|0)){a=t;u=e;w=135;break e}}else{r=e;w=126}}else t=0}else w=118}while(0);do{if((w|0)==118){n=lx(0)|0;if((n|0)!=(-1|0)?(t=n,v=o[2902]|0,m=v+-1|0,t=((m&t|0)==0?0:(m+t&0-v)-t|0)+c|0,v=o[2891]|0,m=t+v|0,t>>>0>d>>>0&t>>>0<2147483647):0){g=o[2893]|0;if(g|0?m>>>0<=v>>>0|m>>>0>g>>>0:0){t=0;break}e=lx(t|0)|0;if((e|0)==(n|0)){a=t;u=n;w=135;break e}else{r=e;w=126}}else t=0}}while(0);do{if((w|0)==126){n=0-t|0;if(!(l>>>0>t>>>0&(t>>>0<2147483647&(r|0)!=(-1|0))))if((r|0)==(-1|0)){t=0;break}else{a=t;u=r;w=135;break e}e=o[2903]|0;e=s-t+e&0-e;if(e>>>0>=2147483647){a=t;u=r;w=135;break e}if((lx(e|0)|0)==(-1|0)){lx(n|0)|0;t=0;break}else{a=e+t|0;u=r;w=135;break e}}}while(0);o[2894]=o[2894]|4;w=133}else{t=0;w=133}}while(0);if(((w|0)==133?c>>>0<2147483647:0)?(b=lx(c|0)|0,g=lx(0)|0,y=g-b|0,_=y>>>0>(d+40|0)>>>0,!((b|0)==(-1|0)|_^1|b>>>0>>0&((b|0)!=(-1|0)&(g|0)!=(-1|0))^1)):0){a=_?y:t;u=b;w=135}if((w|0)==135){t=(o[2891]|0)+a|0;o[2891]=t;if(t>>>0>(o[2892]|0)>>>0)o[2892]=t;s=o[2789]|0;do{if(s){t=11580;while(1){e=o[t>>2]|0;n=t+4|0;r=o[n>>2]|0;if((u|0)==(e+r|0)){w=145;break}i=o[t+8>>2]|0;if(!i)break;else t=i}if(((w|0)==145?(o[t+12>>2]&8|0)==0:0)?s>>>0>>0&s>>>0>=e>>>0:0){o[n>>2]=r+a;E=s+8|0;E=(E&7|0)==0?0:0-E&7;w=s+E|0;E=(o[2786]|0)+(a-E)|0;o[2789]=w;o[2786]=E;o[w+4>>2]=E|1;o[w+E+4>>2]=40;o[2790]=o[2905];break}if(u>>>0<(o[2787]|0)>>>0)o[2787]=u;n=u+a|0;t=11580;while(1){if((o[t>>2]|0)==(n|0)){w=153;break}e=o[t+8>>2]|0;if(!e)break;else t=e}if((w|0)==153?(o[t+12>>2]&8|0)==0:0){o[t>>2]=u;f=t+4|0;o[f>>2]=(o[f>>2]|0)+a;f=u+8|0;f=u+((f&7|0)==0?0:0-f&7)|0;t=n+8|0;t=n+((t&7|0)==0?0:0-t&7)|0;c=f+d|0;l=t-f-d|0;o[f+4>>2]=d|3;do{if((t|0)!=(s|0)){if((t|0)==(o[2788]|0)){E=(o[2785]|0)+l|0;o[2785]=E;o[2788]=c;o[c+4>>2]=E|1;o[c+E>>2]=E;break}e=o[t+4>>2]|0;if((e&3|0)==1){a=e&-8;r=e>>>3;e:do{if(e>>>0<256){e=o[t+8>>2]|0;n=o[t+12>>2]|0;if((n|0)==(e|0)){o[2783]=o[2783]&~(1<>2]=n;o[n+8>>2]=e;break}}else{u=o[t+24>>2]|0;e=o[t+12>>2]|0;do{if((e|0)==(t|0)){r=t+16|0;n=r+4|0;e=o[n>>2]|0;if(!e){e=o[r>>2]|0;if(!e){e=0;break}else n=r}while(1){r=e+20|0;i=o[r>>2]|0;if(i|0){e=i;n=r;continue}r=e+16|0;i=o[r>>2]|0;if(!i)break;else{e=i;n=r}}o[n>>2]=0}else{E=o[t+8>>2]|0;o[E+12>>2]=e;o[e+8>>2]=E}}while(0);if(!u)break;n=o[t+28>>2]|0;r=11436+(n<<2)|0;do{if((t|0)!=(o[r>>2]|0)){o[u+16+(((o[u+16>>2]|0)!=(t|0)&1)<<2)>>2]=e;if(!e)break e}else{o[r>>2]=e;if(e|0)break;o[2784]=o[2784]&~(1<>2]=u;n=t+16|0;r=o[n>>2]|0;if(r|0){o[e+16>>2]=r;o[r+24>>2]=e}n=o[n+4>>2]|0;if(!n)break;o[e+20>>2]=n;o[n+24>>2]=e}}while(0);t=t+a|0;i=a+l|0}else i=l;t=t+4|0;o[t>>2]=o[t>>2]&-2;o[c+4>>2]=i|1;o[c+i>>2]=i;t=i>>>3;if(i>>>0<256){n=11172+(t<<1<<2)|0;e=o[2783]|0;t=1<>2]|0}o[e>>2]=c;o[t+12>>2]=c;o[c+8>>2]=t;o[c+12>>2]=n;break}t=i>>>8;do{if(!t)t=0;else{if(i>>>0>16777215){t=31;break}w=(t+1048320|0)>>>16&8;E=t<>>16&4;E=E<>>16&2;t=14-(b|w|t)+(E<>>15)|0;t=i>>>(t+7|0)&1|t<<1}}while(0);r=11436+(t<<2)|0;o[c+28>>2]=t;e=c+16|0;o[e+4>>2]=0;o[e>>2]=0;e=o[2784]|0;n=1<>2]=c;o[c+24>>2]=r;o[c+12>>2]=c;o[c+8>>2]=c;break}e=i<<((t|0)==31?0:25-(t>>>1)|0);n=o[r>>2]|0;while(1){if((o[n+4>>2]&-8|0)==(i|0)){w=194;break}r=n+16+(e>>>31<<2)|0;t=o[r>>2]|0;if(!t){w=193;break}else{e=e<<1;n=t}}if((w|0)==193){o[r>>2]=c;o[c+24>>2]=n;o[c+12>>2]=c;o[c+8>>2]=c;break}else if((w|0)==194){w=n+8|0;E=o[w>>2]|0;o[E+12>>2]=c;o[w>>2]=c;o[c+8>>2]=E;o[c+12>>2]=n;o[c+24>>2]=0;break}}else{E=(o[2786]|0)+l|0;o[2786]=E;o[2789]=c;o[c+4>>2]=E|1}}while(0);E=f+8|0;h=D;return E|0}t=11580;while(1){e=o[t>>2]|0;if(e>>>0<=s>>>0?(E=e+(o[t+4>>2]|0)|0,E>>>0>s>>>0):0)break;t=o[t+8>>2]|0}i=E+-47|0;e=i+8|0;e=i+((e&7|0)==0?0:0-e&7)|0;i=s+16|0;e=e>>>0>>0?s:e;t=e+8|0;n=u+8|0;n=(n&7|0)==0?0:0-n&7;w=u+n|0;n=a+-40-n|0;o[2789]=w;o[2786]=n;o[w+4>>2]=n|1;o[w+n+4>>2]=40;o[2790]=o[2905];n=e+4|0;o[n>>2]=27;o[t>>2]=o[2895];o[t+4>>2]=o[2896];o[t+8>>2]=o[2897];o[t+12>>2]=o[2898];o[2895]=u;o[2896]=a;o[2898]=0;o[2897]=t;t=e+24|0;do{w=t;t=t+4|0;o[t>>2]=7}while((w+8|0)>>>0>>0);if((e|0)!=(s|0)){u=e-s|0;o[n>>2]=o[n>>2]&-2;o[s+4>>2]=u|1;o[e>>2]=u;t=u>>>3;if(u>>>0<256){n=11172+(t<<1<<2)|0;e=o[2783]|0;t=1<>2]|0}o[e>>2]=s;o[t+12>>2]=s;o[s+8>>2]=t;o[s+12>>2]=n;break}t=u>>>8;if(t){if(u>>>0>16777215)n=31;else{w=(t+1048320|0)>>>16&8;E=t<>>16&4;E=E<>>16&2;n=14-(b|w|n)+(E<>>15)|0;n=u>>>(n+7|0)&1|n<<1}}else n=0;r=11436+(n<<2)|0;o[s+28>>2]=n;o[s+20>>2]=0;o[i>>2]=0;t=o[2784]|0;e=1<>2]=s;o[s+24>>2]=r;o[s+12>>2]=s;o[s+8>>2]=s;break}e=u<<((n|0)==31?0:25-(n>>>1)|0);n=o[r>>2]|0;while(1){if((o[n+4>>2]&-8|0)==(u|0)){w=216;break}r=n+16+(e>>>31<<2)|0;t=o[r>>2]|0;if(!t){w=215;break}else{e=e<<1;n=t}}if((w|0)==215){o[r>>2]=s;o[s+24>>2]=n;o[s+12>>2]=s;o[s+8>>2]=s;break}else if((w|0)==216){w=n+8|0;E=o[w>>2]|0;o[E+12>>2]=s;o[w>>2]=s;o[s+8>>2]=E;o[s+12>>2]=n;o[s+24>>2]=0;break}}}else{E=o[2787]|0;if((E|0)==0|u>>>0>>0)o[2787]=u;o[2895]=u;o[2896]=a;o[2898]=0;o[2792]=o[2901];o[2791]=-1;t=0;do{E=11172+(t<<1<<2)|0;o[E+12>>2]=E;o[E+8>>2]=E;t=t+1|0}while((t|0)!=32);E=u+8|0;E=(E&7|0)==0?0:0-E&7;w=u+E|0;E=a+-40-E|0;o[2789]=w;o[2786]=E;o[w+4>>2]=E|1;o[w+E+4>>2]=40;o[2790]=o[2905]}}while(0);t=o[2786]|0;if(t>>>0>d>>>0){b=t-d|0;o[2786]=b;E=o[2789]|0;w=E+d|0;o[2789]=w;o[w+4>>2]=b|1;o[E+4>>2]=d|3;E=E+8|0;h=D;return E|0}}o[(Jk()|0)>>2]=12;E=0;h=D;return E|0}function Gk(e){e=e|0;var t=0,n=0,r=0,i=0,u=0,a=0,l=0,s=0;if(!e)return;n=e+-8|0;i=o[2787]|0;e=o[e+-4>>2]|0;t=e&-8;s=n+t|0;do{if(!(e&1)){r=o[n>>2]|0;if(!(e&3))return;a=n+(0-r)|0;u=r+t|0;if(a>>>0>>0)return;if((a|0)==(o[2788]|0)){e=s+4|0;t=o[e>>2]|0;if((t&3|0)!=3){l=a;t=u;break}o[2785]=u;o[e>>2]=t&-2;o[a+4>>2]=u|1;o[a+u>>2]=u;return}n=r>>>3;if(r>>>0<256){e=o[a+8>>2]|0;t=o[a+12>>2]|0;if((t|0)==(e|0)){o[2783]=o[2783]&~(1<>2]=t;o[t+8>>2]=e;l=a;t=u;break}}i=o[a+24>>2]|0;e=o[a+12>>2]|0;do{if((e|0)==(a|0)){n=a+16|0;t=n+4|0;e=o[t>>2]|0;if(!e){e=o[n>>2]|0;if(!e){e=0;break}else t=n}while(1){n=e+20|0;r=o[n>>2]|0;if(r|0){e=r;t=n;continue}n=e+16|0;r=o[n>>2]|0;if(!r)break;else{e=r;t=n}}o[t>>2]=0}else{l=o[a+8>>2]|0;o[l+12>>2]=e;o[e+8>>2]=l}}while(0);if(i){t=o[a+28>>2]|0;n=11436+(t<<2)|0;if((a|0)==(o[n>>2]|0)){o[n>>2]=e;if(!e){o[2784]=o[2784]&~(1<>2]|0)!=(a|0)&1)<<2)>>2]=e;if(!e){l=a;t=u;break}}o[e+24>>2]=i;t=a+16|0;n=o[t>>2]|0;if(n|0){o[e+16>>2]=n;o[n+24>>2]=e}t=o[t+4>>2]|0;if(t){o[e+20>>2]=t;o[t+24>>2]=e;l=a;t=u}else{l=a;t=u}}else{l=a;t=u}}else{l=n;a=n}}while(0);if(a>>>0>=s>>>0)return;e=s+4|0;r=o[e>>2]|0;if(!(r&1))return;if(!(r&2)){e=o[2788]|0;if((s|0)==(o[2789]|0)){s=(o[2786]|0)+t|0;o[2786]=s;o[2789]=l;o[l+4>>2]=s|1;if((l|0)!=(e|0))return;o[2788]=0;o[2785]=0;return}if((s|0)==(e|0)){s=(o[2785]|0)+t|0;o[2785]=s;o[2788]=a;o[l+4>>2]=s|1;o[a+s>>2]=s;return}i=(r&-8)+t|0;n=r>>>3;do{if(r>>>0<256){t=o[s+8>>2]|0;e=o[s+12>>2]|0;if((e|0)==(t|0)){o[2783]=o[2783]&~(1<>2]=e;o[e+8>>2]=t;break}}else{u=o[s+24>>2]|0;e=o[s+12>>2]|0;do{if((e|0)==(s|0)){n=s+16|0;t=n+4|0;e=o[t>>2]|0;if(!e){e=o[n>>2]|0;if(!e){n=0;break}else t=n}while(1){n=e+20|0;r=o[n>>2]|0;if(r|0){e=r;t=n;continue}n=e+16|0;r=o[n>>2]|0;if(!r)break;else{e=r;t=n}}o[t>>2]=0;n=e}else{n=o[s+8>>2]|0;o[n+12>>2]=e;o[e+8>>2]=n;n=e}}while(0);if(u|0){e=o[s+28>>2]|0;t=11436+(e<<2)|0;if((s|0)==(o[t>>2]|0)){o[t>>2]=n;if(!n){o[2784]=o[2784]&~(1<>2]|0)!=(s|0)&1)<<2)>>2]=n;if(!n)break}o[n+24>>2]=u;e=s+16|0;t=o[e>>2]|0;if(t|0){o[n+16>>2]=t;o[t+24>>2]=n}e=o[e+4>>2]|0;if(e|0){o[n+20>>2]=e;o[e+24>>2]=n}}}}while(0);o[l+4>>2]=i|1;o[a+i>>2]=i;if((l|0)==(o[2788]|0)){o[2785]=i;return}}else{o[e>>2]=r&-2;o[l+4>>2]=t|1;o[a+t>>2]=t;i=t}e=i>>>3;if(i>>>0<256){n=11172+(e<<1<<2)|0;t=o[2783]|0;e=1<>2]|0}o[t>>2]=l;o[e+12>>2]=l;o[l+8>>2]=e;o[l+12>>2]=n;return}e=i>>>8;if(e){if(i>>>0>16777215)e=31;else{a=(e+1048320|0)>>>16&8;s=e<>>16&4;s=s<>>16&2;e=14-(u|a|e)+(s<>>15)|0;e=i>>>(e+7|0)&1|e<<1}}else e=0;r=11436+(e<<2)|0;o[l+28>>2]=e;o[l+20>>2]=0;o[l+16>>2]=0;t=o[2784]|0;n=1<>>1)|0);n=o[r>>2]|0;while(1){if((o[n+4>>2]&-8|0)==(i|0)){e=73;break}r=n+16+(t>>>31<<2)|0;e=o[r>>2]|0;if(!e){e=72;break}else{t=t<<1;n=e}}if((e|0)==72){o[r>>2]=l;o[l+24>>2]=n;o[l+12>>2]=l;o[l+8>>2]=l;break}else if((e|0)==73){a=n+8|0;s=o[a>>2]|0;o[s+12>>2]=l;o[a>>2]=l;o[l+8>>2]=s;o[l+12>>2]=n;o[l+24>>2]=0;break}}else{o[2784]=t|n;o[r>>2]=l;o[l+24>>2]=r;o[l+12>>2]=l;o[l+8>>2]=l}}while(0);s=(o[2791]|0)+-1|0;o[2791]=s;if(!s)e=11588;else return;while(1){e=o[e>>2]|0;if(!e)break;else e=e+8|0}o[2791]=-1;return}function $k(){return 11628}function Yk(e){e=e|0;var t=0,n=0;t=h;h=h+16|0;n=t;o[n>>2]=tT(o[e+60>>2]|0)|0;e=Qk(ut(6,n|0)|0)|0;h=t;return e|0}function Kk(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0,v=0;d=h;h=h+48|0;c=d+16|0;u=d;i=d+32|0;l=e+28|0;r=o[l>>2]|0;o[i>>2]=r;s=e+20|0;r=(o[s>>2]|0)-r|0;o[i+4>>2]=r;o[i+8>>2]=t;o[i+12>>2]=n;r=r+n|0;a=e+60|0;o[u>>2]=o[a>>2];o[u+4>>2]=i;o[u+8>>2]=2;u=Qk(st(146,u|0)|0)|0;e:do{if((r|0)!=(u|0)){t=2;while(1){if((u|0)<0)break;r=r-u|0;v=o[i+4>>2]|0;p=u>>>0>v>>>0;i=p?i+8|0:i;t=(p<<31>>31)+t|0;v=u-(p?v:0)|0;o[i>>2]=(o[i>>2]|0)+v;p=i+4|0;o[p>>2]=(o[p>>2]|0)-v;o[c>>2]=o[a>>2];o[c+4>>2]=i;o[c+8>>2]=t;u=Qk(st(146,c|0)|0)|0;if((r|0)==(u|0)){f=3;break e}}o[e+16>>2]=0;o[l>>2]=0;o[s>>2]=0;o[e>>2]=o[e>>2]|32;if((t|0)==2)n=0;else n=n-(o[i+4>>2]|0)|0}else f=3}while(0);if((f|0)==3){v=o[e+44>>2]|0;o[e+16>>2]=v+(o[e+48>>2]|0);o[l>>2]=v;o[s>>2]=v}h=d;return n|0}function Xk(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0;i=h;h=h+32|0;u=i;r=i+20|0;o[u>>2]=o[e+60>>2];o[u+4>>2]=0;o[u+8>>2]=t;o[u+12>>2]=r;o[u+16>>2]=n;if((Qk(lt(140,u|0)|0)|0)<0){o[r>>2]=-1;e=-1}else e=o[r>>2]|0;h=i;return e|0}function Qk(e){e=e|0;if(e>>>0>4294963200){o[(Jk()|0)>>2]=0-e;e=-1}return e|0}function Jk(){return(Zk()|0)+64|0}function Zk(){return eT()|0}function eT(){return 2084}function tT(e){e=e|0;return e|0}function nT(e,t,n){e=e|0;t=t|0;n=n|0;var i=0,u=0;u=h;h=h+32|0;i=u;o[e+36>>2]=1;if((o[e>>2]&64|0)==0?(o[i>>2]=o[e+60>>2],o[i+4>>2]=21523,o[i+8>>2]=u+16,Qe(54,i|0)|0):0)r[e+75>>0]=-1;i=Kk(e,t,n)|0;h=u;return i|0}function rT(e,t){e=e|0;t=t|0;var n=0,i=0;n=r[e>>0]|0;i=r[t>>0]|0;if(n<<24>>24==0?1:n<<24>>24!=i<<24>>24)e=i;else{do{e=e+1|0;t=t+1|0;n=r[e>>0]|0;i=r[t>>0]|0}while(!(n<<24>>24==0?1:n<<24>>24!=i<<24>>24));e=i}return(n&255)-(e&255)|0}function iT(e,t,n){e=e|0;t=t|0;n=n|0;var i=0,o=0;e:do{if(!n)e=0;else{while(1){i=r[e>>0]|0;o=r[t>>0]|0;if(i<<24>>24!=o<<24>>24)break;n=n+-1|0;if(!n){e=0;break e}else{e=e+1|0;t=t+1|0}}e=(i&255)-(o&255)|0}}while(0);return e|0}function oT(e,t,n){e=e|0;t=t|0;n=n|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0,v=0,m=0,g=0,y=0;y=h;h=h+224|0;d=y+120|0;p=y+80|0;m=y;g=y+136|0;i=p;u=i+40|0;do{o[i>>2]=0;i=i+4|0}while((i|0)<(u|0));o[d>>2]=o[n>>2];if((uT(0,t,d,m,p)|0)<0)n=-1;else{if((o[e+76>>2]|0)>-1)v=aT(e)|0;else v=0;n=o[e>>2]|0;f=n&32;if((r[e+74>>0]|0)<1)o[e>>2]=n&-33;i=e+48|0;if(!(o[i>>2]|0)){u=e+44|0;a=o[u>>2]|0;o[u>>2]=g;l=e+28|0;o[l>>2]=g;s=e+20|0;o[s>>2]=g;o[i>>2]=80;c=e+16|0;o[c>>2]=g+80;n=uT(e,t,d,m,p)|0;if(a){_A[o[e+36>>2]&7](e,0,0)|0;n=(o[s>>2]|0)==0?-1:n;o[u>>2]=a;o[i>>2]=0;o[c>>2]=0;o[l>>2]=0;o[s>>2]=0}}else n=uT(e,t,d,m,p)|0;i=o[e>>2]|0;o[e>>2]=i|f;if(v|0)lT(e);n=(i&32|0)==0?n:-1}h=y;return n|0}function uT(e,t,n,u,a){e=e|0;t=t|0;n=n|0;u=u|0;a=a|0;var l=0,s=0,f=0,d=0,p=0,v=0,m=0,g=0,y=0,_=0,b=0,w=0,E=0,D=0,S=0,C=0,k=0,T=0,x=0,O=0,P=0,I=0,N=0;N=h;h=h+64|0;x=N+16|0;O=N;k=N+24|0;P=N+8|0;I=N+20|0;o[x>>2]=t;D=(e|0)!=0;S=k+40|0;C=S;k=k+39|0;T=P+4|0;s=0;l=0;v=0;e:while(1){do{if((l|0)>-1)if((s|0)>(2147483647-l|0)){o[(Jk()|0)>>2]=75;l=-1;break}else{l=s+l|0;break}}while(0);s=r[t>>0]|0;if(!(s<<24>>24)){E=87;break}else f=t;t:while(1){switch(s<<24>>24){case 37:{s=f;E=9;break t}case 0:{s=f;break t}default:{}}w=f+1|0;o[x>>2]=w;s=r[w>>0]|0;f=w}t:do{if((E|0)==9)while(1){E=0;if((r[f+1>>0]|0)!=37)break t;s=s+1|0;f=f+2|0;o[x>>2]=f;if((r[f>>0]|0)==37)E=9;else break}}while(0);s=s-t|0;if(D)sT(e,t,s);if(s|0){t=f;continue}d=f+1|0;s=(r[d>>0]|0)+-48|0;if(s>>>0<10){w=(r[f+2>>0]|0)==36;b=w?s:-1;v=w?1:v;d=w?f+3|0:d}else b=-1;o[x>>2]=d;s=r[d>>0]|0;f=(s<<24>>24)+-32|0;t:do{if(f>>>0<32){p=0;m=s;while(1){s=1<>2]=d;s=r[d>>0]|0;f=(s<<24>>24)+-32|0;if(f>>>0>=32)break;else m=s}}else p=0}while(0);if(s<<24>>24==42){f=d+1|0;s=(r[f>>0]|0)+-48|0;if(s>>>0<10?(r[d+2>>0]|0)==36:0){o[a+(s<<2)>>2]=10;s=o[u+((r[f>>0]|0)+-48<<3)>>2]|0;v=1;d=d+3|0}else{if(v|0){l=-1;break}if(D){v=(o[n>>2]|0)+(4-1)&~(4-1);s=o[v>>2]|0;o[n>>2]=v+4;v=0;d=f}else{s=0;v=0;d=f}}o[x>>2]=d;w=(s|0)<0;s=w?0-s|0:s;p=w?p|8192:p}else{s=cT(x)|0;if((s|0)<0){l=-1;break}d=o[x>>2]|0}do{if((r[d>>0]|0)==46){if((r[d+1>>0]|0)!=42){o[x>>2]=d+1;f=cT(x)|0;d=o[x>>2]|0;break}m=d+2|0;f=(r[m>>0]|0)+-48|0;if(f>>>0<10?(r[d+3>>0]|0)==36:0){o[a+(f<<2)>>2]=10;f=o[u+((r[m>>0]|0)+-48<<3)>>2]|0;d=d+4|0;o[x>>2]=d;break}if(v|0){l=-1;break e}if(D){w=(o[n>>2]|0)+(4-1)&~(4-1);f=o[w>>2]|0;o[n>>2]=w+4}else f=0;o[x>>2]=m;d=m}else f=-1}while(0);_=0;while(1){if(((r[d>>0]|0)+-65|0)>>>0>57){l=-1;break e}w=d+1|0;o[x>>2]=w;m=r[(r[d>>0]|0)+-65+(5178+(_*58|0))>>0]|0;g=m&255;if((g+-1|0)>>>0<8){_=g;d=w}else break}if(!(m<<24>>24)){l=-1;break}y=(b|0)>-1;do{if(m<<24>>24==19){if(y){l=-1;break e}else E=49}else{if(y){o[a+(b<<2)>>2]=g;y=u+(b<<3)|0;b=o[y+4>>2]|0;E=O;o[E>>2]=o[y>>2];o[E+4>>2]=b;E=49;break}if(!D){l=0;break e}fT(O,g,n)}}while(0);if((E|0)==49?(E=0,!D):0){s=0;t=w;continue}d=r[d>>0]|0;d=(_|0)!=0&(d&15|0)==3?d&-33:d;y=p&-65537;b=(p&8192|0)==0?p:y;t:do{switch(d|0){case 110:switch((_&255)<<24>>24){case 0:{o[o[O>>2]>>2]=l;s=0;t=w;continue e}case 1:{o[o[O>>2]>>2]=l;s=0;t=w;continue e}case 2:{s=o[O>>2]|0;o[s>>2]=l;o[s+4>>2]=((l|0)<0)<<31>>31;s=0;t=w;continue e}case 3:{i[o[O>>2]>>1]=l;s=0;t=w;continue e}case 4:{r[o[O>>2]>>0]=l;s=0;t=w;continue e}case 6:{o[o[O>>2]>>2]=l;s=0;t=w;continue e}case 7:{s=o[O>>2]|0;o[s>>2]=l;o[s+4>>2]=((l|0)<0)<<31>>31;s=0;t=w;continue e}default:{s=0;t=w;continue e}}case 112:{d=120;f=f>>>0>8?f:8;t=b|8;E=61;break}case 88:case 120:{t=b;E=61;break}case 111:{d=O;t=o[d>>2]|0;d=o[d+4>>2]|0;g=pT(t,d,S)|0;y=C-g|0;p=0;m=5642;f=(b&8|0)==0|(f|0)>(y|0)?f:y+1|0;y=b;E=67;break}case 105:case 100:{d=O;t=o[d>>2]|0;d=o[d+4>>2]|0;if((d|0)<0){t=ZT(0,0,t|0,d|0)|0;d=A;p=O;o[p>>2]=t;o[p+4>>2]=d;p=1;m=5642;E=66;break t}else{p=(b&2049|0)!=0&1;m=(b&2048|0)==0?(b&1|0)==0?5642:5644:5643;E=66;break t}}case 117:{d=O;p=0;m=5642;t=o[d>>2]|0;d=o[d+4>>2]|0;E=66;break}case 99:{r[k>>0]=o[O>>2];t=k;p=0;m=5642;g=S;d=1;f=y;break}case 109:{d=vT(o[(Jk()|0)>>2]|0)|0;E=71;break}case 115:{d=o[O>>2]|0;d=d|0?d:5652;E=71;break}case 67:{o[P>>2]=o[O>>2];o[T>>2]=0;o[O>>2]=P;g=-1;d=P;E=75;break}case 83:{t=o[O>>2]|0;if(!f){gT(e,32,s,0,b);t=0;E=84}else{g=f;d=t;E=75}break}case 65:case 71:case 70:case 69:case 97:case 103:case 102:case 101:{s=_T(e,+c[O>>3],s,f,b,d)|0;t=w;continue e}default:{p=0;m=5642;g=S;d=f;f=b}}}while(0);t:do{if((E|0)==61){b=O;_=o[b>>2]|0;b=o[b+4>>2]|0;g=dT(_,b,S,d&32)|0;m=(t&8|0)==0|(_|0)==0&(b|0)==0;p=m?0:2;m=m?5642:5642+(d>>4)|0;y=t;t=_;d=b;E=67}else if((E|0)==66){g=hT(t,d,S)|0;y=b;E=67}else if((E|0)==71){E=0;b=mT(d,0,f)|0;_=(b|0)==0;t=d;p=0;m=5642;g=_?d+f|0:b;d=_?f:b-d|0;f=y}else if((E|0)==75){E=0;m=d;t=0;f=0;while(1){p=o[m>>2]|0;if(!p)break;f=yT(I,p)|0;if((f|0)<0|f>>>0>(g-t|0)>>>0)break;t=f+t|0;if(g>>>0>t>>>0)m=m+4|0;else break}if((f|0)<0){l=-1;break e}gT(e,32,s,t,b);if(!t){t=0;E=84}else{p=0;while(1){f=o[d>>2]|0;if(!f){E=84;break t}f=yT(I,f)|0;p=f+p|0;if((p|0)>(t|0)){E=84;break t}sT(e,I,f);if(p>>>0>=t>>>0){E=84;break}else d=d+4|0}}}}while(0);if((E|0)==67){E=0;d=(t|0)!=0|(d|0)!=0;b=(f|0)!=0|d;d=((d^1)&1)+(C-g)|0;t=b?g:S;g=S;d=b?(f|0)>(d|0)?f:d:f;f=(f|0)>-1?y&-65537:y}else if((E|0)==84){E=0;gT(e,32,s,t,b^8192);s=(s|0)>(t|0)?s:t;t=w;continue}_=g-t|0;y=(d|0)<(_|0)?_:d;b=y+p|0;s=(s|0)<(b|0)?b:s;gT(e,32,s,b,f);sT(e,m,p);gT(e,48,s,b,f^65536);gT(e,48,y,_,0);sT(e,t,_);gT(e,32,s,b,f^8192);t=w}e:do{if((E|0)==87)if(!e)if(!v)l=0;else{l=1;while(1){t=o[a+(l<<2)>>2]|0;if(!t)break;fT(u+(l<<3)|0,t,n);l=l+1|0;if((l|0)>=10){l=1;break e}}while(1){if(o[a+(l<<2)>>2]|0){l=-1;break e}l=l+1|0;if((l|0)>=10){l=1;break}}}}while(0);h=N;return l|0}function aT(e){e=e|0;return 0}function lT(e){e=e|0;return}function sT(e,t,n){e=e|0;t=t|0;n=n|0;if(!(o[e>>2]&32))PT(t,n,e)|0;return}function cT(e){e=e|0;var t=0,n=0,i=0;n=o[e>>2]|0;i=(r[n>>0]|0)+-48|0;if(i>>>0<10){t=0;do{t=i+(t*10|0)|0;n=n+1|0;o[e>>2]=n;i=(r[n>>0]|0)+-48|0}while(i>>>0<10)}else t=0;return t|0}function fT(e,t,n){e=e|0;t=t|0;n=n|0;var r=0,i=0,u=0.0;e:do{if(t>>>0<=20)do{switch(t|0){case 9:{r=(o[n>>2]|0)+(4-1)&~(4-1);t=o[r>>2]|0;o[n>>2]=r+4;o[e>>2]=t;break e}case 10:{r=(o[n>>2]|0)+(4-1)&~(4-1);t=o[r>>2]|0;o[n>>2]=r+4;r=e;o[r>>2]=t;o[r+4>>2]=((t|0)<0)<<31>>31;break e}case 11:{r=(o[n>>2]|0)+(4-1)&~(4-1);t=o[r>>2]|0;o[n>>2]=r+4;r=e;o[r>>2]=t;o[r+4>>2]=0;break e}case 12:{r=(o[n>>2]|0)+(8-1)&~(8-1);t=r;i=o[t>>2]|0;t=o[t+4>>2]|0;o[n>>2]=r+8;r=e;o[r>>2]=i;o[r+4>>2]=t;break e}case 13:{i=(o[n>>2]|0)+(4-1)&~(4-1);r=o[i>>2]|0;o[n>>2]=i+4;r=(r&65535)<<16>>16;i=e;o[i>>2]=r;o[i+4>>2]=((r|0)<0)<<31>>31;break e}case 14:{i=(o[n>>2]|0)+(4-1)&~(4-1);r=o[i>>2]|0;o[n>>2]=i+4;i=e;o[i>>2]=r&65535;o[i+4>>2]=0;break e}case 15:{i=(o[n>>2]|0)+(4-1)&~(4-1);r=o[i>>2]|0;o[n>>2]=i+4;r=(r&255)<<24>>24;i=e;o[i>>2]=r;o[i+4>>2]=((r|0)<0)<<31>>31;break e}case 16:{i=(o[n>>2]|0)+(4-1)&~(4-1);r=o[i>>2]|0;o[n>>2]=i+4;i=e;o[i>>2]=r&255;o[i+4>>2]=0;break e}case 17:{i=(o[n>>2]|0)+(8-1)&~(8-1);u=+c[i>>3];o[n>>2]=i+8;c[e>>3]=u;break e}case 18:{i=(o[n>>2]|0)+(8-1)&~(8-1);u=+c[i>>3];o[n>>2]=i+8;c[e>>3]=u;break e}default:break e}}while(0)}while(0);return}function dT(e,t,n,i){e=e|0;t=t|0;n=n|0;i=i|0;if(!((e|0)==0&(t|0)==0))do{n=n+-1|0;r[n>>0]=u[5694+(e&15)>>0]|0|i;e=rx(e|0,t|0,4)|0;t=A}while(!((e|0)==0&(t|0)==0));return n|0}function pT(e,t,n){e=e|0;t=t|0;n=n|0;if(!((e|0)==0&(t|0)==0))do{n=n+-1|0;r[n>>0]=e&7|48;e=rx(e|0,t|0,3)|0;t=A}while(!((e|0)==0&(t|0)==0));return n|0}function hT(e,t,n){e=e|0;t=t|0;n=n|0;var i=0;if(t>>>0>0|(t|0)==0&e>>>0>4294967295){while(1){i=cx(e|0,t|0,10,0)|0;n=n+-1|0;r[n>>0]=i&255|48;i=e;e=ax(e|0,t|0,10,0)|0;if(!(t>>>0>9|(t|0)==9&i>>>0>4294967295))break;else t=A}t=e}else t=e;if(t)while(1){n=n+-1|0;r[n>>0]=(t>>>0)%10|0|48;if(t>>>0<10)break;else t=(t>>>0)/10|0}return n|0}function vT(e){e=e|0;return kT(e,o[(CT()|0)+188>>2]|0)|0}function mT(e,t,n){e=e|0;t=t|0;n=n|0;var i=0,u=0,a=0,l=0;a=t&255;i=(n|0)!=0;e:do{if(i&(e&3|0)!=0){u=t&255;while(1){if((r[e>>0]|0)==u<<24>>24){l=6;break e}e=e+1|0;n=n+-1|0;i=(n|0)!=0;if(!(i&(e&3|0)!=0)){l=5;break}}}else l=5}while(0);if((l|0)==5)if(i)l=6;else n=0;e:do{if((l|0)==6){u=t&255;if((r[e>>0]|0)!=u<<24>>24){i=V(a,16843009)|0;t:do{if(n>>>0>3)while(1){a=o[e>>2]^i;if((a&-2139062144^-2139062144)&a+-16843009|0)break;e=e+4|0;n=n+-4|0;if(n>>>0<=3){l=11;break t}}else l=11}while(0);if((l|0)==11)if(!n){n=0;break}while(1){if((r[e>>0]|0)==u<<24>>24)break e;e=e+1|0;n=n+-1|0;if(!n){n=0;break}}}}}while(0);return(n|0?e:0)|0}function gT(e,t,n,r,i){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;var o=0,u=0;u=h;h=h+256|0;o=u;if((n|0)>(r|0)&(i&73728|0)==0){i=n-r|0;tx(o|0,t|0,(i>>>0<256?i:256)|0)|0;if(i>>>0>255){t=n-r|0;do{sT(e,o,256);i=i+-256|0}while(i>>>0>255);i=t&255}sT(e,o,i)}h=u;return}function yT(e,t){e=e|0;t=t|0;if(!e)e=0;else e=DT(e,t,0)|0;return e|0}function _T(e,t,n,i,a,l){e=e|0;t=+t;n=n|0;i=i|0;a=a|0;l=l|0;var s=0,c=0,f=0,d=0,p=0,v=0,m=0,g=0.0,y=0,_=0,b=0,w=0,E=0,D=0,S=0,C=0,k=0,T=0,x=0,O=0,P=0,I=0,N=0;N=h;h=h+560|0;f=N+8|0;b=N;I=N+524|0;P=I;d=N+512|0;o[b>>2]=0;O=d+12|0;bT(t)|0;if((A|0)<0){t=-t;T=1;k=5659}else{T=(a&2049|0)!=0&1;k=(a&2048|0)==0?(a&1|0)==0?5660:5665:5662}bT(t)|0;x=A&2146435072;do{if(x>>>0<2146435072|(x|0)==2146435072&0<0){g=+wT(t,b)*2.0;s=g!=0.0;if(s)o[b>>2]=(o[b>>2]|0)+-1;E=l|32;if((E|0)==97){y=l&32;m=(y|0)==0?k:k+9|0;v=T|2;s=12-i|0;do{if(!(i>>>0>11|(s|0)==0)){t=8.0;do{s=s+-1|0;t=t*16.0}while((s|0)!=0);if((r[m>>0]|0)==45){t=-(t+(-g-t));break}else{t=g+t-t;break}}else t=g}while(0);c=o[b>>2]|0;s=(c|0)<0?0-c|0:c;s=hT(s,((s|0)<0)<<31>>31,O)|0;if((s|0)==(O|0)){s=d+11|0;r[s>>0]=48}r[s+-1>>0]=(c>>31&2)+43;p=s+-2|0;r[p>>0]=l+15;d=(i|0)<1;f=(a&8|0)==0;s=I;do{x=~~t;c=s+1|0;r[s>>0]=u[5694+x>>0]|y;t=(t-+(x|0))*16.0;if((c-P|0)==1?!(f&(d&t==0.0)):0){r[c>>0]=46;s=s+2|0}else s=c}while(t!=0.0);x=s-P|0;P=O-p|0;O=(i|0)!=0&(x+-2|0)<(i|0)?i+2|0:x;s=P+v+O|0;gT(e,32,n,s,a);sT(e,m,v);gT(e,48,n,s,a^65536);sT(e,I,x);gT(e,48,O-x|0,0,0);sT(e,p,P);gT(e,32,n,s,a^8192);break}c=(i|0)<0?6:i;if(s){s=(o[b>>2]|0)+-28|0;o[b>>2]=s;t=g*268435456.0}else{t=g;s=o[b>>2]|0}x=(s|0)<0?f:f+288|0;f=x;do{S=~~t>>>0;o[f>>2]=S;f=f+4|0;t=(t-+(S>>>0))*1.0e9}while(t!=0.0);if((s|0)>0){d=x;v=f;while(1){p=(s|0)<29?s:29;s=v+-4|0;if(s>>>0>=d>>>0){f=0;do{D=nx(o[s>>2]|0,0,p|0)|0;D=ex(D|0,A|0,f|0,0)|0;S=A;w=cx(D|0,S|0,1e9,0)|0;o[s>>2]=w;f=ax(D|0,S|0,1e9,0)|0;s=s+-4|0}while(s>>>0>=d>>>0);if(f){d=d+-4|0;o[d>>2]=f}}f=v;while(1){if(f>>>0<=d>>>0)break;s=f+-4|0;if(!(o[s>>2]|0))f=s;else break}s=(o[b>>2]|0)-p|0;o[b>>2]=s;if((s|0)>0)v=f;else break}}else d=x;if((s|0)<0){i=((c+25|0)/9|0)+1|0;_=(E|0)==102;do{y=0-s|0;y=(y|0)<9?y:9;if(d>>>0>>0){p=(1<>>y;m=0;s=d;do{S=o[s>>2]|0;o[s>>2]=(S>>>y)+m;m=V(S&p,v)|0;s=s+4|0}while(s>>>0>>0);s=(o[d>>2]|0)==0?d+4|0:d;if(!m){d=s;s=f}else{o[f>>2]=m;d=s;s=f+4|0}}else{d=(o[d>>2]|0)==0?d+4|0:d;s=f}f=_?x:d;f=(s-f>>2|0)>(i|0)?f+(i<<2)|0:s;s=(o[b>>2]|0)+y|0;o[b>>2]=s}while((s|0)<0);s=d;i=f}else{s=d;i=f}S=x;if(s>>>0>>0){f=(S-s>>2)*9|0;p=o[s>>2]|0;if(p>>>0>=10){d=10;do{d=d*10|0;f=f+1|0}while(p>>>0>=d>>>0)}}else f=0;_=(E|0)==103;w=(c|0)!=0;d=c-((E|0)!=102?f:0)+((w&_)<<31>>31)|0;if((d|0)<(((i-S>>2)*9|0)+-9|0)){d=d+9216|0;y=x+4+(((d|0)/9|0)+-1024<<2)|0;d=((d|0)%9|0)+1|0;if((d|0)<9){p=10;do{p=p*10|0;d=d+1|0}while((d|0)!=9)}else p=10;v=o[y>>2]|0;m=(v>>>0)%(p>>>0)|0;d=(y+4|0)==(i|0);if(!(d&(m|0)==0)){g=(((v>>>0)/(p>>>0)|0)&1|0)==0?9007199254740992.0:9007199254740994.0;D=(p|0)/2|0;t=m>>>0>>0?.5:d&(m|0)==(D|0)?1.0:1.5;if(T){D=(r[k>>0]|0)==45;t=D?-t:t;g=D?-g:g}d=v-m|0;o[y>>2]=d;if(g+t!=g){D=d+p|0;o[y>>2]=D;if(D>>>0>999999999){f=y;while(1){d=f+-4|0;o[f>>2]=0;if(d>>>0>>0){s=s+-4|0;o[s>>2]=0}D=(o[d>>2]|0)+1|0;o[d>>2]=D;if(D>>>0>999999999)f=d;else break}}else d=y;f=(S-s>>2)*9|0;v=o[s>>2]|0;if(v>>>0>=10){p=10;do{p=p*10|0;f=f+1|0}while(v>>>0>=p>>>0)}}else d=y}else d=y;d=d+4|0;d=i>>>0>d>>>0?d:i;D=s}else{d=i;D=s}E=d;while(1){if(E>>>0<=D>>>0){b=0;break}s=E+-4|0;if(!(o[s>>2]|0))E=s;else{b=1;break}}i=0-f|0;do{if(_){s=((w^1)&1)+c|0;if((s|0)>(f|0)&(f|0)>-5){p=l+-1|0;c=s+-1-f|0}else{p=l+-2|0;c=s+-1|0}s=a&8;if(!s){if(b?(C=o[E+-4>>2]|0,(C|0)!=0):0){if(!((C>>>0)%10|0)){d=0;s=10;do{s=s*10|0;d=d+1|0}while(!((C>>>0)%(s>>>0)|0|0))}else d=0}else d=9;s=((E-S>>2)*9|0)+-9|0;if((p|32|0)==102){y=s-d|0;y=(y|0)>0?y:0;c=(c|0)<(y|0)?c:y;y=0;break}else{y=s+f-d|0;y=(y|0)>0?y:0;c=(c|0)<(y|0)?c:y;y=0;break}}else y=s}else{p=l;y=a&8}}while(0);_=c|y;v=(_|0)!=0&1;m=(p|32|0)==102;if(m){w=0;s=(f|0)>0?f:0}else{s=(f|0)<0?i:f;s=hT(s,((s|0)<0)<<31>>31,O)|0;d=O;if((d-s|0)<2)do{s=s+-1|0;r[s>>0]=48}while((d-s|0)<2);r[s+-1>>0]=(f>>31&2)+43;s=s+-2|0;r[s>>0]=p;w=s;s=d-s|0}s=T+1+c+v+s|0;gT(e,32,n,s,a);sT(e,k,T);gT(e,48,n,s,a^65536);if(m){p=D>>>0>x>>>0?x:D;y=I+9|0;v=y;m=I+8|0;d=p;do{f=hT(o[d>>2]|0,0,y)|0;if((d|0)==(p|0)){if((f|0)==(y|0)){r[m>>0]=48;f=m}}else if(f>>>0>I>>>0){tx(I|0,48,f-P|0)|0;do{f=f+-1|0}while(f>>>0>I>>>0)}sT(e,f,v-f|0);d=d+4|0}while(d>>>0<=x>>>0);if(_|0)sT(e,5710,1);if(d>>>0>>0&(c|0)>0)while(1){f=hT(o[d>>2]|0,0,y)|0;if(f>>>0>I>>>0){tx(I|0,48,f-P|0)|0;do{f=f+-1|0}while(f>>>0>I>>>0)}sT(e,f,(c|0)<9?c:9);d=d+4|0;f=c+-9|0;if(!(d>>>0>>0&(c|0)>9)){c=f;break}else c=f}gT(e,48,c+9|0,9,0)}else{_=b?E:D+4|0;if((c|0)>-1){b=I+9|0;y=(y|0)==0;i=b;v=0-P|0;m=I+8|0;p=D;do{f=hT(o[p>>2]|0,0,b)|0;if((f|0)==(b|0)){r[m>>0]=48;f=m}do{if((p|0)==(D|0)){d=f+1|0;sT(e,f,1);if(y&(c|0)<1){f=d;break}sT(e,5710,1);f=d}else{if(f>>>0<=I>>>0)break;tx(I|0,48,f+v|0)|0;do{f=f+-1|0}while(f>>>0>I>>>0)}}while(0);P=i-f|0;sT(e,f,(c|0)>(P|0)?P:c);c=c-P|0;p=p+4|0}while(p>>>0<_>>>0&(c|0)>-1)}gT(e,48,c+18|0,18,0);sT(e,w,O-w|0)}gT(e,32,n,s,a^8192)}else{I=(l&32|0)!=0;s=T+3|0;gT(e,32,n,s,a&-65537);sT(e,k,T);sT(e,t!=t|0.0!=0.0?I?5686:5690:I?5678:5682,3);gT(e,32,n,s,a^8192)}}while(0);h=N;return((s|0)<(n|0)?n:s)|0}function bT(e){e=+e;var t=0;c[d>>3]=e;t=o[d>>2]|0;A=o[d+4>>2]|0;return t|0}function wT(e,t){e=+e;t=t|0;return+ +ET(e,t)}function ET(e,t){e=+e;t=t|0;var n=0,r=0,i=0;c[d>>3]=e;n=o[d>>2]|0;r=o[d+4>>2]|0;i=rx(n|0,r|0,52)|0;switch(i&2047){case 0:{if(e!=0.0){e=+ET(e*18446744073709551616.0,t);n=(o[t>>2]|0)+-64|0}else n=0;o[t>>2]=n;break}case 2047:break;default:{o[t>>2]=(i&2047)+-1022;o[d>>2]=n;o[d+4>>2]=r&-2146435073|1071644672;e=+c[d>>3]}}return+e}function DT(e,t,n){e=e|0;t=t|0;n=n|0;do{if(e){if(t>>>0<128){r[e>>0]=t;e=1;break}if(!(o[o[(ST()|0)+188>>2]>>2]|0))if((t&-128|0)==57216){r[e>>0]=t;e=1;break}else{o[(Jk()|0)>>2]=84;e=-1;break}if(t>>>0<2048){r[e>>0]=t>>>6|192;r[e+1>>0]=t&63|128;e=2;break}if(t>>>0<55296|(t&-8192|0)==57344){r[e>>0]=t>>>12|224;r[e+1>>0]=t>>>6&63|128;r[e+2>>0]=t&63|128;e=3;break}if((t+-65536|0)>>>0<1048576){r[e>>0]=t>>>18|240;r[e+1>>0]=t>>>12&63|128;r[e+2>>0]=t>>>6&63|128;r[e+3>>0]=t&63|128;e=4;break}else{o[(Jk()|0)>>2]=84;e=-1;break}}else e=1}while(0);return e|0}function ST(){return eT()|0}function CT(){return eT()|0}function kT(e,t){e=e|0;t=t|0;var n=0,i=0;i=0;while(1){if((u[5712+i>>0]|0)==(e|0)){e=2;break}n=i+1|0;if((n|0)==87){n=5800;i=87;e=5;break}else i=n}if((e|0)==2)if(!i)n=5800;else{n=5800;e=5}if((e|0)==5)while(1){do{e=n;n=n+1|0}while((r[e>>0]|0)!=0);i=i+-1|0;if(!i)break;else e=5}return TT(n,o[t+20>>2]|0)|0}function TT(e,t){e=e|0;t=t|0;return xT(e,t)|0}function xT(e,t){e=e|0;t=t|0;if(!t)t=0;else t=AT(o[t>>2]|0,o[t+4>>2]|0,e)|0;return(t|0?t:e)|0}function AT(e,t,n){e=e|0;t=t|0;n=n|0;var i=0,u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0,h=0;h=(o[e>>2]|0)+1794895138|0;a=OT(o[e+8>>2]|0,h)|0;i=OT(o[e+12>>2]|0,h)|0;u=OT(o[e+16>>2]|0,h)|0;e:do{if((a>>>0>>2>>>0?(p=t-(a<<2)|0,i>>>0

    >>0&u>>>0

    >>0):0)?((u|i)&3|0)==0:0){p=i>>>2;d=u>>>2;f=0;while(1){s=a>>>1;c=f+s|0;l=c<<1;u=l+p|0;i=OT(o[e+(u<<2)>>2]|0,h)|0;u=OT(o[e+(u+1<<2)>>2]|0,h)|0;if(!(u>>>0>>0&i>>>0<(t-u|0)>>>0)){i=0;break e}if(r[e+(u+i)>>0]|0){i=0;break e}i=rT(n,e+u|0)|0;if(!i)break;i=(i|0)<0;if((a|0)==1){i=0;break e}else{f=i?f:c;a=i?s:a-s|0}}i=l+d|0;u=OT(o[e+(i<<2)>>2]|0,h)|0;i=OT(o[e+(i+1<<2)>>2]|0,h)|0;if(i>>>0>>0&u>>>0<(t-i|0)>>>0)i=(r[e+(i+u)>>0]|0)==0?e+i|0:0;else i=0}else i=0}while(0);return i|0}function OT(e,t){e=e|0;t=t|0;var n=0;n=fx(e|0)|0;return((t|0)==0?e:n)|0}function PT(e,t,n){e=e|0;t=t|0;n=n|0;var i=0,u=0,a=0,l=0,s=0;i=n+16|0;u=o[i>>2]|0;if(!u){if(!(IT(n)|0)){u=o[i>>2]|0;a=5}else i=0}else a=5;e:do{if((a|0)==5){s=n+20|0;l=o[s>>2]|0;i=l;if((u-l|0)>>>0>>0){i=_A[o[n+36>>2]&7](n,e,t)|0;break}t:do{if((r[n+75>>0]|0)>-1){l=t;while(1){if(!l){a=0;u=e;break t}u=l+-1|0;if((r[e+u>>0]|0)==10)break;else l=u}i=_A[o[n+36>>2]&7](n,e,l)|0;if(i>>>0>>0)break e;a=l;u=e+l|0;t=t-l|0;i=o[s>>2]|0}else{a=0;u=e}}while(0);ix(i|0,u|0,t|0)|0;o[s>>2]=(o[s>>2]|0)+t;i=a+t|0}}while(0);return i|0}function IT(e){e=e|0;var t=0,n=0;t=e+74|0;n=r[t>>0]|0;r[t>>0]=n+255|n;t=o[e>>2]|0;if(!(t&8)){o[e+8>>2]=0;o[e+4>>2]=0;n=o[e+44>>2]|0;o[e+28>>2]=n;o[e+20>>2]=n;o[e+16>>2]=n+(o[e+48>>2]|0);e=0}else{o[e>>2]=t|32;e=-1}return e|0}function NT(e,t){e=Y(e);t=Y(t);var n=0,r=0;n=MT(e)|0;do{if((n&2147483647)>>>0<=2139095040){r=MT(t)|0;if((r&2147483647)>>>0<=2139095040)if((r^n|0)<0){e=(n|0)<0?t:e;break}else{e=e>2]=e,o[d>>2]|0)|0}function RT(e,t){e=Y(e);t=Y(t);var n=0,r=0;n=FT(e)|0;do{if((n&2147483647)>>>0<=2139095040){r=FT(t)|0;if((r&2147483647)>>>0<=2139095040)if((r^n|0)<0){e=(n|0)<0?e:t;break}else{e=e>2]=e,o[d>>2]|0)|0}function LT(e,t){e=Y(e);t=Y(t);var n=0,r=0,i=0,u=0,a=0,l=0,c=0,f=0;u=(s[d>>2]=e,o[d>>2]|0);l=(s[d>>2]=t,o[d>>2]|0);n=u>>>23&255;a=l>>>23&255;c=u&-2147483648;i=l<<1;e:do{if((i|0)!=0?!((n|0)==255|((BT(t)|0)&2147483647)>>>0>2139095040):0){r=u<<1;if(r>>>0<=i>>>0){t=Y(e*Y(0.0));return Y((r|0)==(i|0)?t:e)}if(!n){n=u<<9;if((n|0)>-1){r=n;n=0;do{n=n+-1|0;r=r<<1}while((r|0)>-1)}else n=0;r=u<<1-n}else r=u&8388607|8388608;if(!a){u=l<<9;if((u|0)>-1){i=0;do{i=i+-1|0;u=u<<1}while((u|0)>-1)}else i=0;a=i;l=l<<1-i}else l=l&8388607|8388608;i=r-l|0;u=(i|0)>-1;t:do{if((n|0)>(a|0)){while(1){if(u)if(!i)break;else r=i;r=r<<1;n=n+-1|0;i=r-l|0;u=(i|0)>-1;if((n|0)<=(a|0))break t}t=Y(e*Y(0.0));break e}}while(0);if(u)if(!i){t=Y(e*Y(0.0));break}else r=i;if(r>>>0<8388608)do{r=r<<1;n=n+-1|0}while(r>>>0<8388608);if((n|0)>0)n=r+-8388608|n<<23;else n=r>>>(1-n|0);t=(o[d>>2]=n|c,Y(s[d>>2]))}else f=3}while(0);if((f|0)==3){t=Y(e*t);t=Y(t/t)}return Y(t)}function BT(e){e=Y(e);return(s[d>>2]=e,o[d>>2]|0)|0}function jT(e,t){e=e|0;t=t|0;return oT(o[582]|0,e,t)|0}function UT(e){e=e|0;Ye()}function zT(e){e=e|0;return}function WT(e,t){e=e|0;t=t|0;return 0}function HT(e){e=e|0;if((VT(e+4|0)|0)==-1){hA[o[(o[e>>2]|0)+8>>2]&127](e);e=1}else e=0;return e|0}function VT(e){e=e|0;var t=0;t=o[e>>2]|0;o[e>>2]=t+-1;return t+-1|0}function qT(e){e=e|0;if(HT(e)|0)GT(e);return}function GT(e){e=e|0;var t=0;t=e+8|0;if(!((o[t>>2]|0)!=0?(VT(t)|0)!=-1:0))hA[o[(o[e>>2]|0)+16>>2]&127](e);return}function $T(e){e=e|0;var t=0;t=(e|0)==0?1:e;while(1){e=qk(t)|0;if(e|0)break;e=QT()|0;if(!e){e=0;break}IA[e&0]()}return e|0}function YT(e){e=e|0;return $T(e)|0}function KT(e){e=e|0;Gk(e);return}function XT(e){e=e|0;if((r[e+11>>0]|0)<0)KT(o[e>>2]|0);return}function QT(){var e=0;e=o[2923]|0;o[2923]=e+0;return e|0}function JT(){}function ZT(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;r=t-r-(n>>>0>e>>>0|0)>>>0;return(A=r,e-n>>>0|0)|0}function ex(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;n=e+n>>>0;return(A=t+r+(n>>>0>>0|0)>>>0,n|0)|0}function tx(e,t,n){e=e|0;t=t|0;n=n|0;var i=0,u=0,a=0,l=0;a=e+n|0;t=t&255;if((n|0)>=67){while(e&3){r[e>>0]=t;e=e+1|0}i=a&-4|0;u=i-64|0;l=t|t<<8|t<<16|t<<24;while((e|0)<=(u|0)){o[e>>2]=l;o[e+4>>2]=l;o[e+8>>2]=l;o[e+12>>2]=l;o[e+16>>2]=l;o[e+20>>2]=l;o[e+24>>2]=l;o[e+28>>2]=l;o[e+32>>2]=l;o[e+36>>2]=l;o[e+40>>2]=l;o[e+44>>2]=l;o[e+48>>2]=l;o[e+52>>2]=l;o[e+56>>2]=l;o[e+60>>2]=l;e=e+64|0}while((e|0)<(i|0)){o[e>>2]=l;e=e+4|0}}while((e|0)<(a|0)){r[e>>0]=t;e=e+1|0}return a-n|0}function nx(e,t,n){e=e|0;t=t|0;n=n|0;if((n|0)<32){A=t<>>32-n;return e<>>n;return e>>>n|(t&(1<>>n-32|0}function ix(e,t,n){e=e|0;t=t|0;n=n|0;var i=0,u=0,a=0;if((n|0)>=8192)return He(e|0,t|0,n|0)|0;a=e|0;u=e+n|0;if((e&3)==(t&3)){while(e&3){if(!n)return a|0;r[e>>0]=r[t>>0]|0;e=e+1|0;t=t+1|0;n=n-1|0}n=u&-4|0;i=n-64|0;while((e|0)<=(i|0)){o[e>>2]=o[t>>2];o[e+4>>2]=o[t+4>>2];o[e+8>>2]=o[t+8>>2];o[e+12>>2]=o[t+12>>2];o[e+16>>2]=o[t+16>>2];o[e+20>>2]=o[t+20>>2];o[e+24>>2]=o[t+24>>2];o[e+28>>2]=o[t+28>>2];o[e+32>>2]=o[t+32>>2];o[e+36>>2]=o[t+36>>2];o[e+40>>2]=o[t+40>>2];o[e+44>>2]=o[t+44>>2];o[e+48>>2]=o[t+48>>2];o[e+52>>2]=o[t+52>>2];o[e+56>>2]=o[t+56>>2];o[e+60>>2]=o[t+60>>2];e=e+64|0;t=t+64|0}while((e|0)<(n|0)){o[e>>2]=o[t>>2];e=e+4|0;t=t+4|0}}else{n=u-4|0;while((e|0)<(n|0)){r[e>>0]=r[t>>0]|0;r[e+1>>0]=r[t+1>>0]|0;r[e+2>>0]=r[t+2>>0]|0;r[e+3>>0]=r[t+3>>0]|0;e=e+4|0;t=t+4|0}}while((e|0)<(u|0)){r[e>>0]=r[t>>0]|0;e=e+1|0;t=t+1|0}return a|0}function ox(e){e=e|0;var t=0;t=r[m+(e&255)>>0]|0;if((t|0)<8)return t|0;t=r[m+(e>>8&255)>>0]|0;if((t|0)<8)return t+8|0;t=r[m+(e>>16&255)>>0]|0;if((t|0)<8)return t+16|0;return(r[m+(e>>>24)>>0]|0)+24|0}function ux(e,t,n,r,i){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;var u=0,a=0,l=0,s=0,c=0,f=0,d=0,p=0,h=0,v=0;f=e;s=t;c=s;a=n;p=r;l=p;if(!c){u=(i|0)!=0;if(!l){if(u){o[i>>2]=(f>>>0)%(a>>>0);o[i+4>>2]=0}p=0;i=(f>>>0)/(a>>>0)>>>0;return(A=p,i)|0}else{if(!u){p=0;i=0;return(A=p,i)|0}o[i>>2]=e|0;o[i+4>>2]=t&0;p=0;i=0;return(A=p,i)|0}}u=(l|0)==0;do{if(a){if(!u){u=($(l|0)|0)-($(c|0)|0)|0;if(u>>>0<=31){d=u+1|0;l=31-u|0;t=u-31>>31;a=d;e=f>>>(d>>>0)&t|c<>>(d>>>0)&t;u=0;l=f<>2]=e|0;o[i+4>>2]=s|t&0;p=0;i=0;return(A=p,i)|0}u=a-1|0;if(u&a|0){l=($(a|0)|0)+33-($(c|0)|0)|0;v=64-l|0;d=32-l|0;s=d>>31;h=l-32|0;t=h>>31;a=l;e=d-1>>31&c>>>(h>>>0)|(c<>>(l>>>0))&t;t=t&c>>>(l>>>0);u=f<>>(h>>>0))&s|f<>31;break}if(i|0){o[i>>2]=u&f;o[i+4>>2]=0}if((a|0)==1){h=s|t&0;v=e|0|0;return(A=h,v)|0}else{v=ox(a|0)|0;h=c>>>(v>>>0)|0;v=c<<32-v|f>>>(v>>>0)|0;return(A=h,v)|0}}else{if(u){if(i|0){o[i>>2]=(c>>>0)%(a>>>0);o[i+4>>2]=0}h=0;v=(c>>>0)/(a>>>0)>>>0;return(A=h,v)|0}if(!f){if(i|0){o[i>>2]=0;o[i+4>>2]=(c>>>0)%(l>>>0)}h=0;v=(c>>>0)/(l>>>0)>>>0;return(A=h,v)|0}u=l-1|0;if(!(u&l)){if(i|0){o[i>>2]=e|0;o[i+4>>2]=u&c|t&0}h=0;v=c>>>((ox(l|0)|0)>>>0);return(A=h,v)|0}u=($(l|0)|0)-($(c|0)|0)|0;if(u>>>0<=30){t=u+1|0;l=31-u|0;a=t;e=c<>>(t>>>0);t=c>>>(t>>>0);u=0;l=f<>2]=e|0;o[i+4>>2]=s|t&0;h=0;v=0;return(A=h,v)|0}}while(0);if(!a){c=l;s=0;l=0}else{d=n|0|0;f=p|r&0;c=ex(d|0,f|0,-1,-1)|0;n=A;s=l;l=0;do{r=s;s=u>>>31|s<<1;u=l|u<<1;r=e<<1|r>>>31|0;p=e>>>31|t<<1|0;ZT(c|0,n|0,r|0,p|0)|0;v=A;h=v>>31|((v|0)<0?-1:0)<<1;l=h&1;e=ZT(r|0,p|0,h&d|0,(((v|0)<0?-1:0)>>31|((v|0)<0?-1:0)<<1)&f|0)|0;t=A;a=a-1|0}while((a|0)!=0);c=s;s=0}a=0;if(i|0){o[i>>2]=e;o[i+4>>2]=t}h=(u|0)>>>31|(c|a)<<1|(a<<1|u>>>31)&0|s;v=(u<<1|0>>>31)&-2|l;return(A=h,v)|0}function ax(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;return ux(e,t,n,r,0)|0}function lx(e){e=e|0;var t=0,n=0;n=e+15&-16|0;t=o[f>>2]|0;e=t+n|0;if((n|0)>0&(e|0)<(t|0)|(e|0)<0){Z()|0;qe(12);return-1}o[f>>2]=e;if((e|0)>(J()|0)?(Q()|0)==0:0){o[f>>2]=t;qe(12);return-1}return t|0}function sx(e,t,n){e=e|0;t=t|0;n=n|0;var i=0;if((t|0)<(e|0)&(e|0)<(t+n|0)){i=e;t=t+n|0;e=e+n|0;while((n|0)>0){e=e-1|0;t=t-1|0;n=n-1|0;r[e>>0]=r[t>>0]|0}e=i}else ix(e,t,n)|0;return e|0}function cx(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;var i=0,u=0;u=h;h=h+16|0;i=u|0;ux(e,t,n,r,i)|0;h=u;return(A=o[i+4>>2]|0,o[i>>2]|0)|0}function fx(e){e=e|0;return(e&255)<<24|(e>>8&255)<<16|(e>>16&255)<<8|e>>>24|0}function dx(e,t,n,r,i,o){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;o=o|0;cA[e&1](t|0,n|0,r|0,i|0,o|0)}function px(e,t,n){e=e|0;t=t|0;n=Y(n);fA[e&1](t|0,Y(n))}function hx(e,t,n){e=e|0;t=t|0;n=+n;dA[e&31](t|0,+n)}function vx(e,t,n,r){e=e|0;t=t|0;n=Y(n);r=Y(r);return Y(pA[e&0](t|0,Y(n),Y(r)))}function mx(e,t){e=e|0;t=t|0;hA[e&127](t|0)}function gx(e,t,n){e=e|0;t=t|0;n=n|0;vA[e&31](t|0,n|0)}function yx(e,t){e=e|0;t=t|0;return mA[e&31](t|0)|0}function _x(e,t,n,r,i){e=e|0;t=t|0;n=+n;r=+r;i=i|0;gA[e&1](t|0,+n,+r,i|0)}function bx(e,t,n,r){e=e|0;t=t|0;n=+n;r=+r;yA[e&1](t|0,+n,+r)}function wx(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;return _A[e&7](t|0,n|0,r|0)|0}function Ex(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;return+bA[e&1](t|0,n|0,r|0)}function Dx(e,t){e=e|0;t=t|0;return+wA[e&15](t|0)}function Sx(e,t,n){e=e|0;t=t|0;n=+n;return EA[e&1](t|0,+n)|0}function Cx(e,t,n){e=e|0;t=t|0;n=n|0;return DA[e&15](t|0,n|0)|0}function kx(e,t,n,r,i,o){e=e|0;t=t|0;n=n|0;r=+r;i=+i;o=o|0;SA[e&1](t|0,n|0,+r,+i,o|0)}function Tx(e,t,n,r,i,o,u){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;o=o|0;u=u|0;CA[e&1](t|0,n|0,r|0,i|0,o|0,u|0)}function xx(e,t,n){e=e|0;t=t|0;n=n|0;return+kA[e&7](t|0,n|0)}function Ax(e){e=e|0;return TA[e&7]()|0}function Ox(e,t,n,r,i,o){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;o=o|0;return xA[e&1](t|0,n|0,r|0,i|0,o|0)|0}function Px(e,t,n,r,i){e=e|0;t=t|0;n=n|0;r=r|0;i=+i;AA[e&1](t|0,n|0,r|0,+i)}function Ix(e,t,n,r,i,o,u){e=e|0;t=t|0;n=n|0;r=Y(r);i=i|0;o=Y(o);u=u|0;OA[e&1](t|0,n|0,Y(r),i|0,Y(o),u|0)}function Nx(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;PA[e&15](t|0,n|0,r|0)}function Mx(e){e=e|0;IA[e&0]()}function Rx(e,t,n,r){e=e|0;t=t|0;n=n|0;r=+r;NA[e&15](t|0,n|0,+r)}function Fx(e,t,n){e=e|0;t=+t;n=+n;return MA[e&1](+t,+n)|0}function Lx(e,t,n,r,i){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;RA[e&15](t|0,n|0,r|0,i|0)}function Bx(e,t,n,r,i){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;K(0)}function jx(e,t){e=e|0;t=Y(t);K(1)}function Ux(e,t){e=e|0;t=+t;K(2)}function zx(e,t,n){e=e|0;t=Y(t);n=Y(n);K(3);return ft}function Wx(e){e=e|0;K(4)}function Hx(e,t){e=e|0;t=t|0;K(5)}function Vx(e){e=e|0;K(6);return 0}function qx(e,t,n,r){e=e|0;t=+t;n=+n;r=r|0;K(7)}function Gx(e,t,n){e=e|0;t=+t;n=+n;K(8)}function $x(e,t,n){e=e|0;t=t|0;n=n|0;K(9);return 0}function Yx(e,t,n){e=e|0;t=t|0;n=n|0;K(10);return 0.0}function Kx(e){e=e|0;K(11);return 0.0}function Xx(e,t){e=e|0;t=+t;K(12);return 0}function Qx(e,t){e=e|0;t=t|0;K(13);return 0}function Jx(e,t,n,r,i){e=e|0;t=t|0;n=+n;r=+r;i=i|0;K(14)}function Zx(e,t,n,r,i,o){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;o=o|0;K(15)}function eA(e,t){e=e|0;t=t|0;K(16);return 0.0}function tA(){K(17);return 0}function nA(e,t,n,r,i){e=e|0;t=t|0;n=n|0;r=r|0;i=i|0;K(18);return 0}function rA(e,t,n,r){e=e|0;t=t|0;n=n|0;r=+r;K(19)}function iA(e,t,n,r,i,o){e=e|0;t=t|0;n=Y(n);r=r|0;i=Y(i);o=o|0;K(20)}function oA(e,t,n){e=e|0;t=t|0;n=n|0;K(21)}function uA(){K(22)}function aA(e,t,n){e=e|0;t=t|0;n=+n;K(23)}function lA(e,t){e=+e;t=+t;K(24);return 0}function sA(e,t,n,r){e=e|0;t=t|0;n=n|0;r=r|0;K(25)}var cA=[Bx,DE];var fA=[jx,qi];var dA=[Ux,yo,_o,bo,wo,Eo,Do,So,ko,To,Ao,Oo,Po,Io,No,Mo,Ro,Fo,Lo,Ux,Ux,Ux,Ux,Ux,Ux,Ux,Ux,Ux,Ux,Ux,Ux,Ux];var pA=[zx];var hA=[Wx,zT,hl,vl,ml,Kd,Xd,Qd,yb,_b,bb,oE,uE,aE,uk,ak,lk,bt,Xi,to,Co,xo,ju,Uu,Ka,Sl,Wl,ps,Ns,rc,kc,qc,df,Mf,Zf,yd,Ld,gp,Fp,th,bh,jh,iv,kv,Vv,am,xm,Wi,cg,Ag,Qg,yy,Fy,o_,g_,b_,U_,H_,ab,Db,kb,Gb,pw,Cl,OD,pS,PS,KS,bC,BC,XC,ZC,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx,Wx];var vA=[Hx,no,ro,uo,ao,lo,so,co,fo,vo,mo,go,eu,ru,iu,ou,uu,au,lu,pu,gu,Ku,Ov,$v,Ey,ND,ww,eS,Hx,Hx,Hx,Hx];var mA=[Vx,Yk,Ki,zo,qo,Go,$o,Yo,Ko,Xo,Jo,Zo,hu,vu,zu,Pm,Uy,Kb,BD,UD,Vx,Vx,Vx,Vx,Vx,Vx,Vx,Vx,Vx,Vx,Vx,Vx];var gA=[qx,Wu];var yA=[Gx,cb];var _A=[$x,Kk,Xk,nT,ac,wp,hg,ZS];var bA=[Yx,rd];var wA=[Kx,tu,nu,su,Hu,Vu,qu,Gu,$u,Yu,Kx,Kx,Kx,Kx,Kx,Kx];var EA=[Xx,p_];var DA=[Qx,WT,mu,tl,gs,Oc,Kc,zd,Up,fm,Gi,RS,Qx,Qx,Qx,Qx];var SA=[Jx,Gl];var CA=[Zx,SC];var kA=[eA,cu,Xu,Qu,Ju,Ed,eA,eA];var TA=[tA,Zu,$i,Ui,C_,$_,Pb,rk];var xA=[nA,Fr];var AA=[rA,Sh];var OA=[iA,_u];var PA=[oA,Wo,Qo,fu,du,Ls,mf,Hh,lv,Vi,JE,gS,WC,oA,oA,oA];var IA=[uA];var NA=[aA,io,oo,po,ho,Bo,jo,Uo,oh,Ng,l_,aA,aA,aA,aA,aA];var MA=[lA,vb];var RA=[sA,Bf,jm,ty,Ky,P_,Z_,Bb,yw,qD,hk,sA,sA,sA,sA,sA];return{_llvm_bswap_i32:fx,dynCall_idd:Fx,dynCall_i:Ax,_i64Subtract:ZT,___udivdi3:ax,dynCall_vif:px,setThrew:mt,dynCall_viii:Nx,_bitshift64Lshr:rx,_bitshift64Shl:nx,dynCall_vi:mx,dynCall_viiddi:kx,dynCall_diii:Ex,dynCall_iii:Cx,_memset:tx,_sbrk:lx,_memcpy:ix,__GLOBAL__sub_I_Yoga_cpp:ji,dynCall_vii:gx,___uremdi3:cx,dynCall_vid:hx,stackAlloc:dt,_nbind_init:Ak,getTempRet0:yt,dynCall_di:Dx,dynCall_iid:Sx,setTempRet0:gt,_i64Add:ex,dynCall_fiff:vx,dynCall_iiii:wx,_emscripten_get_global_libc:$k,dynCall_viid:Rx,dynCall_viiid:Px,dynCall_viififi:Ix,dynCall_ii:yx,__GLOBAL__sub_I_Binding_cc:wD,dynCall_viiii:Lx,dynCall_iiiiii:Ox,stackSave:pt,dynCall_viiiii:dx,__GLOBAL__sub_I_nbind_cc:ea,dynCall_vidd:bx,_free:Gk,runPostSets:JT,dynCall_viiiiii:Tx,establishStackSpace:vt,_memmove:sx,stackRestore:ht,_malloc:qk,__GLOBAL__sub_I_common_cc:iw,dynCall_viddi:_x,dynCall_dii:xx,dynCall_v:Mx}}(Module.asmGlobalArg,Module.asmLibraryArg,buffer),_llvm_bswap_i32=Module._llvm_bswap_i32=asm._llvm_bswap_i32,getTempRet0=Module.getTempRet0=asm.getTempRet0,___udivdi3=Module.___udivdi3=asm.___udivdi3,setThrew=Module.setThrew=asm.setThrew,_bitshift64Lshr=Module._bitshift64Lshr=asm._bitshift64Lshr,_bitshift64Shl=Module._bitshift64Shl=asm._bitshift64Shl,_memset=Module._memset=asm._memset,_sbrk=Module._sbrk=asm._sbrk,_memcpy=Module._memcpy=asm._memcpy,stackAlloc=Module.stackAlloc=asm.stackAlloc,___uremdi3=Module.___uremdi3=asm.___uremdi3,_nbind_init=Module._nbind_init=asm._nbind_init,_i64Subtract=Module._i64Subtract=asm._i64Subtract,setTempRet0=Module.setTempRet0=asm.setTempRet0,_i64Add=Module._i64Add=asm._i64Add,_emscripten_get_global_libc=Module._emscripten_get_global_libc=asm._emscripten_get_global_libc,__GLOBAL__sub_I_Yoga_cpp=Module.__GLOBAL__sub_I_Yoga_cpp=asm.__GLOBAL__sub_I_Yoga_cpp,__GLOBAL__sub_I_Binding_cc=Module.__GLOBAL__sub_I_Binding_cc=asm.__GLOBAL__sub_I_Binding_cc,stackSave=Module.stackSave=asm.stackSave,__GLOBAL__sub_I_nbind_cc=Module.__GLOBAL__sub_I_nbind_cc=asm.__GLOBAL__sub_I_nbind_cc,_free=Module._free=asm._free,runPostSets=Module.runPostSets=asm.runPostSets,establishStackSpace=Module.establishStackSpace=asm.establishStackSpace,_memmove=Module._memmove=asm._memmove,stackRestore=Module.stackRestore=asm.stackRestore,_malloc=Module._malloc=asm._malloc,__GLOBAL__sub_I_common_cc=Module.__GLOBAL__sub_I_common_cc=asm.__GLOBAL__sub_I_common_cc,dynCall_viiiii=Module.dynCall_viiiii=asm.dynCall_viiiii,dynCall_vif=Module.dynCall_vif=asm.dynCall_vif,dynCall_vid=Module.dynCall_vid=asm.dynCall_vid,dynCall_fiff=Module.dynCall_fiff=asm.dynCall_fiff,dynCall_vi=Module.dynCall_vi=asm.dynCall_vi,dynCall_vii=Module.dynCall_vii=asm.dynCall_vii,dynCall_ii=Module.dynCall_ii=asm.dynCall_ii,dynCall_viddi=Module.dynCall_viddi=asm.dynCall_viddi,dynCall_vidd=Module.dynCall_vidd=asm.dynCall_vidd,dynCall_iiii=Module.dynCall_iiii=asm.dynCall_iiii,dynCall_diii=Module.dynCall_diii=asm.dynCall_diii,dynCall_di=Module.dynCall_di=asm.dynCall_di,dynCall_iid=Module.dynCall_iid=asm.dynCall_iid,dynCall_iii=Module.dynCall_iii=asm.dynCall_iii,dynCall_viiddi=Module.dynCall_viiddi=asm.dynCall_viiddi,dynCall_viiiiii=Module.dynCall_viiiiii=asm.dynCall_viiiiii,dynCall_dii=Module.dynCall_dii=asm.dynCall_dii,dynCall_i=Module.dynCall_i=asm.dynCall_i,dynCall_iiiiii=Module.dynCall_iiiiii=asm.dynCall_iiiiii,dynCall_viiid=Module.dynCall_viiid=asm.dynCall_viiid,dynCall_viififi=Module.dynCall_viififi=asm.dynCall_viififi,dynCall_viii=Module.dynCall_viii=asm.dynCall_viii,dynCall_v=Module.dynCall_v=asm.dynCall_v,dynCall_viid=Module.dynCall_viid=asm.dynCall_viid,dynCall_idd=Module.dynCall_idd=asm.dynCall_idd,dynCall_viiii=Module.dynCall_viiii=asm.dynCall_viiii,initialStackTop;function ExitStatus(e){this.name="ExitStatus",this.message="Program terminated with exit("+e+")",this.status=e}Runtime.stackAlloc=Module.stackAlloc,Runtime.stackSave=Module.stackSave,Runtime.stackRestore=Module.stackRestore,Runtime.establishStackSpace=Module.establishStackSpace,Runtime.setTempRet0=Module.setTempRet0,Runtime.getTempRet0=Module.getTempRet0,Module.asm=asm,ExitStatus.prototype=new Error,ExitStatus.prototype.constructor=ExitStatus;var preloadStartTime=null,calledMain=!1;function run(e){function t(){Module.calledRun||(Module.calledRun=!0,ABORT||(ensureInitRuntime(),preMain(),Module.onRuntimeInitialized&&Module.onRuntimeInitialized(),Module._main&&shouldRunNow&&Module.callMain(e),postRun()))}e=e||Module.arguments,null===preloadStartTime&&(preloadStartTime=Date.now()),runDependencies>0||(preRun(),runDependencies>0||Module.calledRun||(Module.setStatus?(Module.setStatus("Running..."),setTimeout((function(){setTimeout((function(){Module.setStatus("")}),1),t()}),1)):t()))}function exit(e,t){t&&Module.noExitRuntime||(Module.noExitRuntime||(ABORT=!0,EXITSTATUS=e,STACKTOP=initialStackTop,exitRuntime(),Module.onExit&&Module.onExit(e)),ENVIRONMENT_IS_NODE&&process.exit(e),Module.quit(e,new ExitStatus(e)))}dependenciesFulfilled=function e(){Module.calledRun||run(),Module.calledRun||(dependenciesFulfilled=e)},Module.callMain=Module.callMain=function(e){e=e||[],ensureInitRuntime();var t=e.length+1;function n(){for(var e=0;e<3;e++)r.push(0)}var r=[allocate(intArrayFromString(Module.thisProgram),"i8",ALLOC_NORMAL)];n();for(var i=0;i0;)Module.preInit.pop()();var shouldRunNow=!0;Module.noInitialRun&&(shouldRunNow=!1),run()},void 0===(__WEBPACK_AMD_DEFINE_RESULT__=function(){return wrapper}.apply(exports,__WEBPACK_AMD_DEFINE_ARRAY__=[]))||(module.exports=__WEBPACK_AMD_DEFINE_RESULT__)},3019:e=>{"use strict";e.exports={ALIGN_COUNT:8,ALIGN_AUTO:0,ALIGN_FLEX_START:1,ALIGN_CENTER:2,ALIGN_FLEX_END:3,ALIGN_STRETCH:4,ALIGN_BASELINE:5,ALIGN_SPACE_BETWEEN:6,ALIGN_SPACE_AROUND:7,DIMENSION_COUNT:2,DIMENSION_WIDTH:0,DIMENSION_HEIGHT:1,DIRECTION_COUNT:3,DIRECTION_INHERIT:0,DIRECTION_LTR:1,DIRECTION_RTL:2,DISPLAY_COUNT:2,DISPLAY_FLEX:0,DISPLAY_NONE:1,EDGE_COUNT:9,EDGE_LEFT:0,EDGE_TOP:1,EDGE_RIGHT:2,EDGE_BOTTOM:3,EDGE_START:4,EDGE_END:5,EDGE_HORIZONTAL:6,EDGE_VERTICAL:7,EDGE_ALL:8,EXPERIMENTAL_FEATURE_COUNT:1,EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS:0,FLEX_DIRECTION_COUNT:4,FLEX_DIRECTION_COLUMN:0,FLEX_DIRECTION_COLUMN_REVERSE:1,FLEX_DIRECTION_ROW:2,FLEX_DIRECTION_ROW_REVERSE:3,JUSTIFY_COUNT:6,JUSTIFY_FLEX_START:0,JUSTIFY_CENTER:1,JUSTIFY_FLEX_END:2,JUSTIFY_SPACE_BETWEEN:3,JUSTIFY_SPACE_AROUND:4,JUSTIFY_SPACE_EVENLY:5,LOG_LEVEL_COUNT:6,LOG_LEVEL_ERROR:0,LOG_LEVEL_WARN:1,LOG_LEVEL_INFO:2,LOG_LEVEL_DEBUG:3,LOG_LEVEL_VERBOSE:4,LOG_LEVEL_FATAL:5,MEASURE_MODE_COUNT:3,MEASURE_MODE_UNDEFINED:0,MEASURE_MODE_EXACTLY:1,MEASURE_MODE_AT_MOST:2,NODE_TYPE_COUNT:2,NODE_TYPE_DEFAULT:0,NODE_TYPE_TEXT:1,OVERFLOW_COUNT:3,OVERFLOW_VISIBLE:0,OVERFLOW_HIDDEN:1,OVERFLOW_SCROLL:2,POSITION_TYPE_COUNT:2,POSITION_TYPE_RELATIVE:0,POSITION_TYPE_ABSOLUTE:1,PRINT_OPTIONS_COUNT:3,PRINT_OPTIONS_LAYOUT:1,PRINT_OPTIONS_STYLE:2,PRINT_OPTIONS_CHILDREN:4,UNIT_COUNT:4,UNIT_UNDEFINED:0,UNIT_POINT:1,UNIT_PERCENT:2,UNIT_AUTO:3,WRAP_COUNT:3,WRAP_NO_WRAP:0,WRAP_WRAP:1,WRAP_WRAP_REVERSE:2}},6401:(e,t,n)=>{"use strict";var r=n(7180),i=n(3354),o=!1,u=null;if(i({},(function(e,t){if(!o){if(o=!0,e)throw e;u=t}})),!o)throw new Error("Failed to load the yoga module - it needed to be loaded synchronously, but didn't");e.exports=r(u.bind,u.lib)},7180:(e,t,n)=>{"use strict";var r=Object.assign||function(e){for(var t=1;t"}}]),e}(),s=function(){function e(t,n){u(this,e),this.width=t,this.height=n}return i(e,null,[{key:"fromJS",value:function(t){return new e(t.width,t.height)}}]),i(e,[{key:"fromJS",value:function(e){e(this.width,this.height)}},{key:"toString",value:function(){return""}}]),e}(),c=function(){function e(t,n){u(this,e),this.unit=t,this.value=n}return i(e,[{key:"fromJS",value:function(e){e(this.unit,this.value)}},{key:"toString",value:function(){switch(this.unit){case a.UNIT_POINT:return String(this.value);case a.UNIT_PERCENT:return this.value+"%";case a.UNIT_AUTO:return"auto";default:return this.value+"?"}}},{key:"valueOf",value:function(){return this.value}}]),e}();e.exports=function(e,t){function n(e,t,n){var r=e[t];e[t]=function(){for(var e=arguments.length,t=Array(e),i=0;i1?t-1:0),i=1;i1&&void 0!==arguments[1]?arguments[1]:NaN,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:NaN,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:a.DIRECTION_LTR;return e.call(this,t,n,r)})),r({Config:t.Config,Node:t.Node,Layout:e("Layout",l),Size:e("Size",s),Value:e("Value",c),getInstanceCount:function(){return t.getInstanceCount.apply(t,arguments)}},a)}},2357:e=>{"use strict";e.exports=require("assert")},6417:e=>{"use strict";e.exports=require("crypto")},8614:e=>{"use strict";e.exports=require("events")},5747:e=>{"use strict";e.exports=require("fs")},8605:e=>{"use strict";e.exports=require("http")},7211:e=>{"use strict";e.exports=require("https")},2282:e=>{"use strict";e.exports=require("module")},1631:e=>{"use strict";e.exports=require("net")},2087:e=>{"use strict";e.exports=require("os")},2413:e=>{"use strict";e.exports=require("stream")},4016:e=>{"use strict";e.exports=require("tls")},3867:e=>{"use strict";e.exports=require("tty")},8835:e=>{"use strict";e.exports=require("url")},8761:e=>{"use strict";e.exports=require("zlib")}},__webpack_module_cache__={};function __webpack_require__(e){if(__webpack_module_cache__[e])return __webpack_module_cache__[e].exports;var t=__webpack_module_cache__[e]={id:e,loaded:!1,exports:{}};return __webpack_modules__[e].call(t.exports,t,t.exports,__webpack_require__),t.loaded=!0,t.exports}return __webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),__webpack_require__(7560)})(); + */ return plugin; } -}; \ No newline at end of file +}; diff --git a/tgui/.yarn/releases/yarn-2.4.1.cjs b/tgui/.yarn/releases/yarn-2.4.1.cjs deleted file mode 100644 index 65ec5dde19..0000000000 --- a/tgui/.yarn/releases/yarn-2.4.1.cjs +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env node -module.exports=(()=>{var e={25545:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=25545,e.exports=t},44692:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>g});var A=r(54143);const n={optional:!0},o=[["@samverschueren/stream-to-observable@<0.3.1",{peerDependenciesMeta:{rxjs:n,zenObservable:n}}],["any-observable@<0.5.1",{peerDependenciesMeta:{rxjs:n,zenObservable:n}}],["@pm2/agent@<1.0.4",{dependencies:{debug:"*"}}],["debug@<4.2.0",{peerDependenciesMeta:{"supports-color":n}}],["got@<11",{dependencies:{"@types/responselike":"^1.0.0","@types/keyv":"^3.1.1"}}],["cacheable-lookup@<4.1.2",{dependencies:{"@types/keyv":"^3.1.1"}}],["http-link-dataloader@*",{peerDependencies:{graphql:"^0.13.1 || ^14.0.0"}}],["typescript-language-server@*",{dependencies:{"vscode-jsonrpc":"^5.0.1","vscode-languageserver-protocol":"^3.15.0"}}],["postcss-syntax@*",{peerDependenciesMeta:{"postcss-html":n,"postcss-jsx":n,"postcss-less":n,"postcss-markdown":n,"postcss-scss":n}}],["jss-plugin-rule-value-function@<=10.1.1",{dependencies:{"tiny-warning":"^1.0.2"}}],["ink-select-input@<4.1.0",{peerDependencies:{react:"^16.8.2"}}],["promise-inflight@*",{peerDependenciesMeta:{bluebird:n}}],["reactcss@*",{peerDependencies:{react:"*"}}],["react-color@<=2.19.0",{peerDependencies:{react:"*"}}],["gatsby-plugin-i18n@*",{dependencies:{ramda:"^0.24.1"}}],["useragent@^2.0.0",{dependencies:{request:"^2.88.0",yamlparser:"0.0.x",semver:"5.5.x"}}],["@apollographql/apollo-tools@*",{peerDependencies:{graphql:"^14.2.1 || ^15.0.0"}}],["material-table@^2.0.0",{dependencies:{"@babel/runtime":"^7.11.2"}}],["@babel/parser@*",{dependencies:{"@babel/types":"^7.8.3"}}],["fork-ts-checker-webpack-plugin@*",{peerDependencies:{eslint:">= 6",typescript:">= 2.7",webpack:">= 4"},peerDependenciesMeta:{eslint:n}}],["rc-animate@*",{peerDependencies:{react:"^15.0.0 || ^16.0.0","react-dom":"^15.0.0 || ^16.0.0"}}],["react-bootstrap-table2-paginator@*",{dependencies:{classnames:"^2.2.6"}}],["react-draggable@<=4.4.3",{peerDependencies:{react:">= 16.3.0","react-dom":">= 16.3.0"}}],["apollo-upload-client@<14",{peerDependencies:{graphql:"14 - 15"}}],["react-instantsearch-core@<=6.7.0",{peerDependencies:{algoliasearch:">= 3.1 < 5"}}],["react-instantsearch-dom@<=6.7.0",{dependencies:{"react-fast-compare":"^3.0.0"}}],["ws@<7.2.1",{peerDependencies:{bufferutil:"^4.0.1","utf-8-validate":"^5.0.2"},peerDependenciesMeta:{bufferutil:n,"utf-8-validate":n}}],["react-portal@*",{peerDependencies:{"react-dom":"^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0"}}]];let i,s,a;const c=new Map([[A.makeIdent(null,"fsevents").identHash,function(){return void 0===i&&(i=r(78761).brotliDecompressSync(Buffer.from("G7weAByFTVk3Vs7UfHhq4yykgEM7pbW7TI43SG2S5tvGrwHBAzdz+s/npQ6tgEvobvxisrPIadkXeUAJotBn5bDZ5kAhcRqsIHe3F75Walet5hNalwgFDtxb0BiDUjiUQkjG0yW2hto9HPgiCkm316d6bC0kST72YN7D7rfkhCE9x4J0XwB0yavalxpUu2t9xszHrmtwalOxT7VslsxWcB1qpqZwERUra4psWhTV8BgwWeizurec82Caf1ABL11YMfbf8FJ9JBceZOkgmvrQPbC9DUldX/yMbmX06UQluCEjSwUoyO+EZPIjofr+/oAZUck2enraRD+oWLlnlYnj8xB+gwSo9lmmks4fXv574qSqcWA6z21uYkzMu3EWj+K23RxeQlLqiE35/rC8GcS4CGkKHKKq+zAIQwD9iRDNfiAqueLLpicFFrNsAI4zeTD/eO9MHcnRa5m8UT+M2+V+AkFST4BlKneiAQRSdST8KEAIyFlULt6wa9EBd0Ds28VmpaxquJdVt+nwdEs5xUskI13OVtFyY0UrQIRAlCuvvWivvlSKQfTO+2Q8OyUR1W5RvetaPz4jD27hdtwHFFA1Ptx6Ee/t2cY2rg2G46M1pNDRf2pWhvpy8pqMnuI3++4OF3+7OFIWXGjh+o7Nr2jNvbiYcQdQS1h903/jVFgOpA0yJ78z+x759bFA0rq+6aY5qPB4FzS3oYoLupDUhD9nDz6F6H7hpnlMf18KNKDu4IKjTWwrAnY6MFQw1W6ymOALHlFyCZmQhldg1MQHaMVVQTVgDC60TfaBqG++Y8PEoFhN/PBTZT175KNP/BlHDYGOOBmnBdzqJKplZ/ljiVG0ZBzfqeBRrrUkn6rA54462SgiliKoYVnbeptMdXNfAuaupIEi0bApF10TlgHfmEJAPUVidRVFyDupSem5po5vErPqWKhKbUIp0LozpYsIKK57dM/HKr+nguF+7924IIWMICkQ8JUigs9D+W+c4LnNoRtPPKNRUiCYmP+Jfo2lfKCKw8qpraEeWU3uiNRO6zcyKQoXPR5htmzzLznke7b4YbXW3I1lIRzmgG02Udb58U+7TpwyN7XymCgH+wuPDthZVQvRZuEP+SnLtMicz9m5zASWOBiAcLmkuFlTKuHspSIhCBD0yUPKcxu81A+4YD78rA2vtwsUEday9WNyrShyrl60rWmA+SmbYZkQOwFJWArxRYYc5jGhA5ikxYw1rx3ei4NmeX/lKiwpZ9Ln1tV2Ae7sArvxuVLbJjqJRjW1vFXAyHpvLG+8MJ6T2Ubx5M2KDa2SN6vuIGxJ9WQM9Mk3Q7aCNiZONXllhqq24DmoLbQfW2rYWsOgHWjtOmIQMyMKdiHZDjoyIq5+U700nZ6odJAoYXPQBvFNiQ78d5jaXliBqLTJEqUCwi+LiH2mx92EmNKDsJL74Z613+3lf20pxkV1+erOrjj8pW00vsPaahKUM+05ssd5uwM7K482KWEf3TCwlg/o3e5ngto7qSMz7YteIgCsF1UOcsLk7F7MxWbvrPMY473ew0G+noVL8EPbkmEMftMSeL6HFub/zy+2JQ==","base64")).toString()),i}],[A.makeIdent(null,"resolve").identHash,function(){return void 0===s&&(s=r(78761).brotliDecompressSync(Buffer.from("G1QTIIzURnVBnGa0VPvr81orV8AFIqdU0sqrdcVgCdukgAZwi8a50gLk9+19Z2NcUILjmzXkzt4dzm5a6Yoys+/9qnKiaApXukOiuoyUaMcynG4X7X4vBaIE/PL30gwG6HSGJkLxb9PnLjfMr+748n7sM6C/NycK6ber/bX1reVVxta6W/31tZIhfrS+upoE/TPRHj0S/l0T59gTGdtKOp1OmMOJt9rhfucDdLJ2tgyfnO+u4YMkQAcYq/nebTcDmbXhqhgo6iQA4M3m4xya4Cos3p6klmkmQT+S4DLDZfwfMF+sUCx36KleOtaHLQfEIz0Bmncj/Ngi3lqOl4391EWEfIss6gVp3oDUGwsSZJKeOVONJWZg+Mue3KUMV3aMqYJ+7b2219D+GFDi8EV5y/Y+5J+He0oNjKAgqLsJziEsS9uIaCu3BHBKSXxNKKa2ShbfglcWoiiVT2kfGI7Gw+YJ/Sqy1H6wdFWtyVUQIa82JPwbeV25YKLzc5ZIFM6GCPSA+J9dTvJbs5LuuKnLP3f09gCu2jxqsAv6CA+ZySVaUJr2d3A70BC/uBCKr2OVrWgC3fSwb7NlfkgSEEiejrMGvhya9lMbVI6lMsFKN330A1/FOaefHQdNGLEZ3IwFF87H3xVlM0Xxsmbi/7A60oymRcIe0tH90alG6ez/yA7jwYotxuHWZdR+1HlMcddGHAV6QD/gXYPV0wnNv47I+5FGevzZFMqWSO8GU4nQ3FjsdgdJcD+c1rvudERKuLyd7bxiBpnsMDHsvPP4nXdXkld/gUNks3GAE1Otmb90bavDyiw4Mrx496Iw+jbLTgsCZGZXSZ9vM55C7KGe4HyJAKXEk0iT/Cj/PFwLJBN7pcP7ZFfYtUApGTWKkYhI9IE2zt/5ByH72wdvH+88b71zuv/FMCX3w6x5nzhY44Cg5IYv9LeKwHuHIWgPbfgrAcUxOlKkPRdQOIDF/aBuLPJAXD+TgxCNXx4jQxeR/qlBWVikFPfEI4rXMUc4kZ2w9KbPKYRvFUag0dVlVoyUP4zfidbTXAdZF88jAckl+NHjLFCNdX7EQ1PbLSOl+P+MqgwEOCi6dxgWZ7NCwJBjWKpk1LaxwKrhZ4aEC/0lMPJYe5S8xAakDcmA2kSS86GjEMTrv3VEu0S0YGZcxToMV524G4WAc4CReePePdipvs4aXRL5p+aeN96yfMGjsiTbQNxgbdRKc+keQ+NxYIEm1mBtEO29WrcbrqNbQRMR66KpGG4aG0NtmRyZ2JhUvu0paCklRlID8PT3gSiwZrqr4XZXoBBzBMrveWCuOg7iTgGDXDdbGi8XHkQf5KXDGFUxWueu5wkSa6gMWY1599g2piQjwBKIAPt4N5cOZdFBidz2feGwEAy1j1UydGxDSCCUsh314cUIIRV/dWCheceubL2gU8CibewmP7UxmN5kN4I7zfQhPxkP0NCcei8GXQpw4c3krEzW7PR2hgi/hqqqR58UJ/ZVfWxfcH5ZKMo4itkmPK0FCGxzzIRP20lK/gz28Y03sY233KvSVWUKl9rcbX6MbHjpUG8MvNlw72p6FwTejv92zgpnCxVJnIHHZhCBxNcHF5RTveRp513hUtTHHq4BIndlytZT5xoTSYfHKqKNr4o9kcGINIz6tZSKRdtbON3Ydr9cgqxHIeisMNIsvPg/IFMZuBbSqqDLeSO5dak1cGr76FtH2PC7hs0S0Oq3GsmF1Ga4YABAMGcdPAWzTk26B7cKV91I2b0V/GYvnsEQ1YGntRqi5EQqTlgZszbV/32GuZtUF49JOA/r4jAdwUOsbPo6mNoBlJPYjM5axrZaWQf33bFsLWqiyvvDOM4x0Ng802T7cuP2a3q98GWq6yiq6q3M77hcZlOUnmryctRYmI4Hb2F5XixFohkBmySCjU+M7/WQVE5YAtnlxiUJDhFN0y1tNeMWY9E0MfZi2rQ4eC72WXjsAA==","base64")).toString()),s}],[A.makeIdent(null,"typescript").identHash,function(){return void 0===a&&(a=r(78761).brotliDecompressSync(Buffer.from("W1w+GkWwcQCPbZnUKPI4CFN/7EyEjZic7gS0LuAO0yfO0XnBUqmjRfsndcrEHKBP46+kNRcXE9T69UCzOMQD2EWA28SPiEUXz6UxaKl+dNhtngmN0KaY5gpIi1/+TP/v5+ul7zo6uRXScKu4Va6wcMpgwWjlQmZyLR397/MiXMMwmQ2WvoleaS23WLFmcLXTID0zCnXDyL3LdHSWRzWaZNoLpQ9ftzCssvn5UUSQrkz2sjzf3FK1NFu+8MED3YPNhfn/v5/12R4CVF9IQuGG7fgP2feee7pDDUmqVieV+oB0zrn3vaTyUtWAVR8A1BCrGaPH2BFy2OkUfQTXowAdqflCqJlUTVednHQBLhT0zgNplLM1/LC3YUtdVskGoP/n5IyllimTGsG0NiyeBsnDvH4hH244pgDEQlJuVFqDssvZiI4GfTjk18cws931bs/fNgZQUYmiSRwdZE7xvHTIs32JGu2uwAFKZKNm70VPRJNCpGAyptX+XMo0EYIMW+yfv/zpskSSzFwETa/caJp1bP8q7M9KD+vPBeP7ltn/S/T63wuZer7nGibzgC/N86sEdD34FbrYIfv5F55+7bVf/STBcAM9rTWWnzIYiKTay4uuRz9aDz1HiI/TeSXrj01C7+4FeNlKohYUwh1qXjemQMsA7KWH4IRDSrz8UaMQ5e6niK87ZFzvWB+6cn6IpWkrDPYI+LccLeGDX/DjRmmXLSGqSbu/WWcMAapgUUR9G3oqqY9mKz+GXe1HPlxFqBRbdhzQbxghtNtlE5TL2qkf5+arA/5VdO5ZrOH+kWjf6tx/bbXyNntYEVEl+ucEeht+7F++iVCO3lpE64CAVx7+6FNBcAO3m1AB0mTOMwIUDj1x5S+ma30rDtHMWY+KOF6d3arYY4j+tx008aAsS5fNfP1+ykdDDgYoJD9pHr+K2Wh5m1MFc/Vap0k8uXi1iivbu2CuV+oLD00s3gdd7XTaHBIYzGLjy5SjHbYO6IkbTFtHzlwfqdIsdb8CjpaChourHi63UT1gaCFBIvQr/kKbKcUX4sdOFDKI8N/kaaISAVtiu356imQHboaw4apcePacaTwFAXdejxkgicEn0wRpVzhZd1W/sUByw4X7rqPMIVlhS+3o+8I9djctba2396mLfpdNnSzoN2QyZ2A9PzEPmLs+x3EUNH4EPic+KYDtCNNEYKJMwupjr9W6GNPhTs877JpSFYGxiAzFfKZINCng6GQoGbMHX3gxgznmtgDV+apTCz9MzBpe7pUioV6Ckv4bpmXPikXOg2pfxpNn+RhLxQwsU0Y0ILkRGUFsbWdIc3MPVC9Kyp+aRSH7ufRUV5irDZgCzr4oF+ZQpAwLv3hrwX+/c/cqxIsw6oUQcXFCySTK+ZACOwcZm4FwOcoRDlGTdERvi5xePFkjoBz0OrUmoCAB7eRjBm93fmb4Fi/jmDrfAFXG2ryCdGVfkJzOap1qqXsmQgAFjf3UMIyX60yCl5nrZ4RA6PYYoDKP/gabiPKtkHDEzEO2N389febkiCRZPiTlI7Z5fXzo/E+8tKZXrtDRd+fozGKAfMg8l9FbZhHMX+w/2rlggkIouL4LpXxB1PzweCqhj5rdeIremOt1ZKHAU8+547LJnpRQG02p8tMmMeGSuOvsqP6O1KVyB6SWvcw5rFKW87N42c2myjca3Vjt2LMkPrbz9FfYmJJLlI18upFczbc51+dTdxUx0cpNkFIMiBjru9+tXzGHQ+HMT7nsNVfkJjW/asI0WVmvLJzcuDluyz8h+8UGZTQXExSCw9O9kD3lZk+1eXswBd0jthuq+4hm3vQtqQIMtbejHjQCISfPOGFyjjlaEo41utZWunTOz3N1DRK7ho8np0bv4fCTIAOy9+JiaumSo8+7H0Cg4CIICjqp15L84qMQ477qLQeW5Zed2Xn+9DKSxHFYu4UQ1rnFbCIX12+1NScfCujiTVYtcppJAPj2DB27ctiNSLf1bRSbEHmzLwqM7HW7Kn9vzUf+hTRQ6iQ2y3RGUnoanyvESLRxOVNTWrcCY9dXv1/bq+GkwMXbo5PGVYnb9Q/sOq+tpVsOvJnt2nBnq4LIHT6EBYTZXoUHez41cJszqbPoyz4pJMX8nhKFI5dbWls7fpPbVaIrqhkgvkkvuK3oqTbQkKv6RXiUULEgyC6NHvFlAgL0EdVIbMQG+1byGiYRtq31I5U77Cpc7VonG7oPgiYbfuXCAZXXVrmk85BCObe1DRj3obm9xwDY69ZKCemnOlGBkB6+LbAIoGBk34KATc8ktyyoxmtdCjnJ7Uhgihw+QWZzRJwQBSY7Z0R8HeEQ/pUvl6RzCrMFI0lmjTh7pK2cvW4G6APAhAoHu8TlVeL1DJOBqW66oRjtC5VEoig3xg7ybQmx9h3fSCQaefhZbunZbf1DS/YZFSuHZlh+aMb8x5C5uUcv8YLJpUlnNB79aJPt771o4XlpExDHD04Rsfgk/SUwiL5rllcbL9XpCrHVOBZhNNfXqMlDOJjL9sbALIiYV02uk14sOY/JoPnJx8sxIIY+iFouatS7AU//Cw17qSa2uWodwFjeY1/Ouw2iv29QLUKWg77BKwnwPHPf45VFu9dPABATrZ2P/YEYy33tjHJfD6u90W/bqk3fX67VYKbktMpAGbZ6VdPuu4lUg/63irWRiCMtozcM3sCql/Vxdf/mjGFVpYgmoXp4LacW0hWoYnW4sBOVw/FbgOLMCvl4Thg9D21xyqGHeHgQ2H0YPnZTi+7u1P0Lx3nCKpyVVZtEkJs7Mpri/iRBd18aEFdTbzQF37AgVmn9PNUUNNblFpPzuTnvfRrqz9mF1OV9Eu/Ncj7DlxeIc69Q/r53Wdfn5rwffHYx/HsU9ZMIFbra7eRKVJ4zPP8v2ESdKxoFDoYPwNt++y4sU9TJCmvc61y8ecV7Bil1/BWMH2hsRJDvsPXnVtVkKwb6fg20IT9+DLzTx/y3SJrsLIlt/LONXfOiOMjG9riLVagboHG8mPzmewlQWLFvL6NciWO+hcP2lyr+gXx8c70MGCBwKmelr67I0cUzYBlnu2J90JEhPDtT0E57XgAxYO0fVdJSS/MtxQONPfnPBMNY424/sGnpB12aa/FdB3E+7XdOTvtHn61T0MwHh0GtgdgGg18//zwFDcQ9Y6rFZnuyndmycJnWnEz9D7lV2V7IjcvT6GSgxx9E4VjoowXhIEAQtDGPdhA0NcPQhQsAhJnxrsiFLmyBhdW+i5cCJ60RAFiJKq3ePwMDl3ng+8BgpoXv2c3QozfwvNiPvuC3A295+FxgK0PEiQsAIIAZW1gNaNvtNKDX9QgA8AgSmo2yl4P5wGamA6hHL+DYgRemwp8KnjGO3RzcowQrAGznF3/586f/XkYv2IN55GxgOdNm+uBCxtHal2+dmeFPCMboO4IBbRcuAGDT9F1R2GnAyGqf4N2Ji7RGACAaL8IxfVUod2J3/D1eh1/Ulq++EBXu3el1SgYAQJshkP+f67/+7Pz/Y3Rj3KKrny0TjGpV2VFcMKiaXw8G0B5S8pOcbh/N5gvu8IQvrK3tdeotAEDDjLJ4IrIxlir5hDRvTpOsEHZdquzuDth7/rlMAMBCQdNCjD9U08CcebX5TOUISzQxw6LTFgAoctVpw+KqS7RHNeZcqbRLAKBFleRw5DMVOO2/2l6HNoLCYqbXKWwBADsZbWwLYwG21l6bmDKAN60RAChFEdGYhvcCel+cBttJND32cnSl8ioA7Ga50Yxr9No07X0tHwX9N4GPbETVbzNfTZUtALA4Ntxow+AqJ9uPyopxldWNAIDGimRM4+ERcf463QkjY5fMa2K+KsaoSa9TMgAA2pUeqHGzZ4qfreJJbCUzttt3ANkM+xz0Nn4I6yvTOxeLcn9g9IQf2OXudeotAEAxy3kaN9tbDEYNT1ob0Nhq1+FdLxepmQBARO8gIuBv0vaTCeqJtxztcRrDsgsXACjTdLsgbBSetbxo7SfvejkplwDAaemzDxdf44S/VM/f1/5yFBesdeECALV4bvGiCUeeRY7WbnnX5KRsAgAWbQmbrngnXi01Kb39aXSXEqwAcJ3laonKN6Hx3plriPuM0J+oz9LYK5V4pMYFAFbMvlLWcIerqLmbq5jWCACY0PqYQkV37mmlpNS9KjFXIz4uCdxPqgTTUXqcYZu8waKpOxLI6JuC/V5ksD0JpWyHgyT1poEBU9LhF8KTrthVERadLLToCjoSr958kVOhYyzBcDVw5Ndnl0fn5/E7Uu1lV2uJv/V6oe8Tr7qIGZ/FXyhwbF0IGcm+PWuvDt43oObzo4dN3gbiB9M4AOe3H/NxCh7619L5VVqzxfL2JmJ5fXXv4zJ3IY0ErqSfJ7PtGEktqiboa5y/Q52IEn0P8mYMFxAe3t4u3ax2+SY5p5obSRj3F+6kvjC9qstmdnG7T+TjF7+r5nWaYxkFSAEDL3fLK/8bzW6MQwOFhyLVtdnHxsg+EIYpRuoyY6edsN2djKfaEzMckzlI95n3WEGyGlfHyFw4JOw9rTtLtN+bxrAGyEVDdGnVWK8YSwreubXAB1qsoatSBnTTKcv456EvBhSCO17tehk/PyuIBT4gaucnrjhnAPp7DuQisGahq4p0/CRE/HG1qLo0Q7iA0XvTHate9Dh29ogluynBd/gx5I7DbX3w4L2QsEMuP+XCF6UNYcnOuVsGRukgCilp3TSNNF4kUQURoktlSM6Dj9DSUGOUWiwwpKGyzHE//CxgDPBxPyUCGZrxW4ZlkdRgBUIWbF9mG00rsSUy1obI/qbMIZGfjC9yukfd9UhoYUpvDaHjO7hG44Udz7OeR/Zrp5E8nwR3/1mnSuXjfgHEl4mcT17VGU0cOniN9XdALACmBu18UycBEU5/pPKjLXL8Q0E6pTHlrFbyiFBtlJgNfKzYJzHay9Kc+s2DGBwIvDCqj8cn5nS8lm1cXyBfd3l18QmRuiyQWmQPMjmfJRBeP9rxQv8T6fhQUanWZstFi3aNN3DO+9TBG6bDVxnspz4XBtWiwsbVN6cwY0K9j4kJbMPLcTQMP1xKAgAb9mZcea1MX1oXNVeNS882t2HwumNLuGhFk375yWps2MeYtH3cXRYuWv21UwDEy3Jjr+sURkgo45Os3/LkY77VdRKARZNJS1UOZlJH1uwIMIM7bNKYPM9JOMaFgmZh1nSG8aZRChKaLItYBTyOWP8iMV0NWwf1Z7ZMxoZMphQGQkIO6Fp0Xe7ye5npMRFVjzaN5ETLVKiKQzHBu3ocLSODGbF6kZHa7SO+jsz7aO3+EV/zf4/VlfCSRx7ICP5hxjqU7DgTq1gktzOL777yk/gmO5RjY62fRfif39YGBi2J1YKBiTkT14Mh6Ncog6LCearFt3pYpJMTu2QXxjvdtlVY8J4HxBG2V1f2QOKHq5OFB7xo2WT34wIQ0esyQTjlkE/HgAypV1iiWWLHxW/iiB3m6+y+IS3LoAZ+mOEa2qatUK+ZFFyxJj0Wk1E2ZTr16UcSEvwn+rjUyN0k48p8Xm/0iPXaCbDSJTZuDcWySeTCid67IarLslDs7ZpwAC6hcs8eFiZe+um1sdkTCpNjdHG3N1f23j4UwxkLWmaTLbLxSTGDnktFEdfkVKrzmol49ZZRVnafOxvtjROKpRG3N1N2Cnjahr6K09GoGG8UzjazD6J3ZJS7JHKls5Wuex1VarJDBWNdiV8Jelgy9BIChq3EbTUCjo6UBRzCO7Dn86RqagkXvhYr1sMyo0wb/byZo8QspZN/ZOft1AjjBv90LL0vKNKpidcs+MzVW39s44JVOZ6yV4iPPVimkIuasd+2lBNGNXu/RACmVL64PGoiuNbUZjVaz2R1xq4zoVEy9Jiq7kyHJ+g+JVP3mkUMdaVpAIYVYKDGZ5TMAID6i4ZGFz71SWuX+pWiCQBIQDHlDsCTJXDgJvJc0rcnbiSTkib1IrmQjbqDrcdknqx7tSO6zTQqhrUCRNzMAMCQvqJI0o6D1r7B5OuXQxMAWH0DZ1N+BUBnCvSx38rs8wLvsp6KRFOoW92ZnCF68OpeuygxFQCzmsgKEa47efretdO61yaBOU2j1rDWAm0nMwDgY6Co5ZLCCmS1s9QnhyYAkBLYMeUawDobQEJWbFmWkvaP2a93BezvXbyp5e7g/7U4LIj7cYjwxOHKaQYAHIRZnnyCXXlnjs8FSLudBPNOc/MZED4dsVaP5cXApLp9EGJw2OvAmIBdscLuuemG2cHCyKyx7Bml78kupF8cDgybmXnIHz0cVVRUjK803dX5Qab7hSkmaMmHycio6VxwM4+I5V2nzLNXMi0r0EAliMp584sZIc1b8hU7xR8Z5qMzAZGlBdy/OvvIhJWYF1P9mDSjL7LsmKaBIBWXs1+1n1CDTmvK8DKnx4KmYSIVJBK3pMLgUPn/ngu4ZW+Y4jBBKYUSvZ0qe5CDUHn06sFL8eqdg92tKUkezfWR+WzUPH7wZSbPmcCWIsOwqjOiWR43yt6uFtUsq6HBLMXzruosfbKTmCCT5jiW6em5ojGzigzj0oFo9x/sEb00a1t7+t9DeBZ1x5lPQEnvWNfMCgnzM42+1LxOp6+yONAw7UUF7rycap14bp13FpBEoolDn+3wHW09u3jUYHjEQW8ac8ucd8F91GHZRkBlXxDWRJey0sKrL4+ITdBdNYMUXts+Doyeh8gjxYWJ70HIMAgthBhd4xga0pScg+PBlG+zeGSHNTv25Jqym85XIsVBOmSQ46+2Fp+Fu2vIZ8v2JVsaiGQOguhiLD2gfXqasd/I4Qd94PCE8rTg61hVOCyIR2nMAICFs6WCcJZBL15MzlX2qYKvTX+Kx7/LBACmFsuLXTzzB8wXcXfxEr7A8QJmGtEC6LF62dN8hmNO7hjesDCeHePYrMNzr6u7wVU7IRjU6S44B9TP8r4zJ0vbx4iy7VjcGgfccHKY7U31SwutCUfun0NboOw/mgDxuaG+f9W+Hrn1Kv2kNEnthUWP+6SbG1/YjQ5U2X3v+vPZ1HWvT8BhCxUICv93H0bp0SbhVbQPR9A59CMjYSnHzMYvCH/tOEEo4Ggr7Vcx+rHXmmn72aUpi52FNlpSC6TJ0Si+2H2pnh8vepfOrKdGYG0lFgkWWfPD1sl+VHSfNb7fOkWDC6vIXPFzuFvw7ZihgY/FlVuMG30lC5+d2dKZ/Zd7z+c9k10vqUNscuBoxaO1VLfeCbIvOL9+RWpHhzU7G46TgHv5C6aAiCIqK8snWuHnTH/e5Olj1ZcAniIilXcFw3rlNwLuupkBgF2AVhNWopRenOqR3d4GaFyaAIAMzJbdbxGYm40SAGwXLbNKJs8AeVHSlGpkRJePDkDheS3TB9dfK+n2FhFeyioHwEeExFBq0mP+Vuzk5B/I+G/cZ0R0Uk85AD4k5MYNlw71J4f3Jh8Pbyfi+o+IWIfEFvfj1XhGoEnPZAYAJgIxqwlPqSgygGW3NwEehyYA0GTB2az7O/ZDbpMAgEZWNKvpPcz3yNR5aW3w+hzi/7UqfUhscT8GUXtqRfEzzQwAsPwp7fGIKYqMOzY/8KcLx81i18ifpptRmr8VPT6opL9wU3grbmrhz7c9Skaj4AYhpJbH1j5Xgm14ZN0rKEvY7j75ESj9xY8aAdMJFADdy8sMjR2FL8BpN84vrWIUPvdrgpMraslLa2oK+QJETX712brJqogh0j8EtyjJzUOGHIGyn9ONBdIBkD0BkWTfWgkdwItmjaZopqn2P9rRgLXpYFr6RIEr0+4aybofbaud725r7sB7F6TqGUa1BwLjuqjw6wo69En03bIjqOVFnXP9RwgSYaoNnNrWVHfQ9Rph7tqP0pAce+xDXDruL+rHcz6ln2lhl2aY0mE0yb0Byz7yjnVtQw+pv/TcR9ZePJqQKjl3lazZAaKI9TxKhwWhzxbISAmnQzsBiJNtGE3ApmUYUzfA4KaTxK71l3dnVnW9OkwBAF+rnZnUF/dOqbMOYZRMX9tXHlYn16QjrVItvUoPkuGpvqf0YWgPXOSO0IzQod5ofO2O/gzdmk94YAlD/CqD/o1pCP2JNhhFftGwLUaBvNlL+tdJBLOhBUZCOpik6IMamqdK3AnDxBg+16WKa3WE02KzpCC3msVpuGGKnY5zNGVToAc3sZUVgevfZuhzOhfprO0AHJ0ck2kxSE2c2GKlwUhxyZGUmc7JpFh/ZktxOQ47vAAh7I4fD0MRKW6Fk1QYOGhFfVPDUZXawarezdJtWzwpZ2WiQYZfiKDvuwmupCjWqyp2R+hCRtw9DG0ww0EEXEuCUsgexlgwF/05fhIOXAA6/Int1cvu7ni0ptzkn7hi2hQ72CFrpPVG9U7XVPc8bJIVFtuFStUC0Ymw4AsLcrJiqp9gcYoDYrgLHJqRPHcrms4maIQ1Ket4RBgu17M2T0pASvSFthi87RJuDpVEkH6k5dR1ykArccYr+bmFoKY8u8rVz/dMjfe8VwRsMq/5qPLvTKso5B1mV9NptFcJkKAoJ9EiP3/sxVrsVB6MdUuoQxMwIs3Rl21sjpABsWWwbJBBLogFg/UivowbwTjhd6fo7NDhjO/dVML5RAY/PMSSuqOKxtSguJnAG7PYzbuN/CVMlWvz15VfTe5hWjGp4IwZpDQRJcKcsMok0p86BrSMgQrLGaKLgeI+o6Xjs1xw3FXuyxJtM+ZzOco2b8YwxBTw/NHPM8tVu06TiCisjAdElQ3cRxb8Trca+MyL+QbicxmYkVlZZoAtlkVzfEgfak67uNLjxaIdXQFD5ibCBfPpNVHq8Jj250wV7DKILjsePNvIR4x+TD6WWFC5nsNoXj3H7sr7fhYfh3WO8meCv95w2CaVcEXiw0VaCeWhWUWnbirbtKcqlO3nKeFnv45hIvQTRBuGFDvkn7MGDNjoQm50f+la/j5Tkaei+bBnTEzfouLBTeLwIlrIw3saHYRowtRo9P4QDl+NIumkebp5/WnSzE2+xjPAwl+rmqvkwfOkUfXcus1IjdfiLxUzADDgGtk8Yor/17hExdmvqXO5ae2oVI3FbIYrEwDA3BnrbCaLmQ/4a5BLp45+5XsSWD0A1wpoLe769NGrL+CGokfiPiDqMBDP0RVPkuU84euRruOvPSFAdbmsjljUNAWgVh378jd1xZRmqsJPRKODdwKhPiDBBatW7DAMEUoCRQ+HAEqSWPj9XN+/ijxXTFXzt+T0EW0BIN2yZZubSxwHwAddxl1j67kDpzgDjSDSdQlj7YhkxQ62PZsu2rnIbW8BkUaraxON7yZRTwDb00LdMfFa2hmtBjGWzfVm/GOC5LSE0RLHsp8enD811dvrof79paGjqn0SLX8t5TVb0gUQ6MOu2lwJfP+O6d2Vh2ULJSDp+5HB54V5H+CNN25tXvrIM3Exe1jX2WMCJrldyxiIItGuRwvlg1K89N+AyTkg9k0TW1QxO+2ZBH2aNKpNmxxrUvtQUn9AcLo3cNgbDru8mfxwvHPaDHr6k/EvS84yT+8fzP5FpFn75MLfj8EwbhZ8XA2o10BzmE8XWhCsO+vYNg9pGFPWbki0+dipJBpAh3FlZ13n0OzgVbBypRzreqSsdapRzjR+kT8ajyv/wxlufqwztJpldU2HbjTrhHeSBKPhjLO5fveAbAx8KJxm/dl5vaSbdVSNw8xWrmjS4dKOb0LE+bGtct751nCJR/6aieShrRLXiGlk2NTevGkUKt0Jm+XC1TSjbYqQsmK6rtHecJfAVDbEyxvTF1jFp/DAASds88fYKuhmMbWiuZnYTJOWEfXjTsIZrqGZ/fFOBg+ux2bAat12KYxskoRoUeTH6ZLThB/f0+eCqfasE1AxXaAFA20ihHk4cEJsZdaYAVHoQUlLCq4pa4mCAM2NNN5vsDgfLS0jvSP38yfaxiYoOHUmJisj9kr05cPOnh4+9rSPbNJ9Vs/BjnqB/8qr6Y+rew1G+9xsMFWSe4gJ85kz7rpMZ3RGTrM6LbCQAmf1TaWzYGIdqGpcmzyJKaElwibK/S5MK6w5JHjfTNxXohxKX0hlsQy85UphZQbeCA0s+6+nxOzKL3hCyO/j9Ra2d4RN2W0p9OF4xBfEubmu7Mi1Zd5mJ4G+ctkiV67Hv3zUB6IjPW1CW9M01FTYpeP0w42u+I2r1QZVvE2JsSf/Y1X3MHUbJXROEw7yryYQIun3d21drZ5J2ZKUQNcBPkssPg7x2jSqgpgtgtc+1BE7rfDKGKnn3I8ZMx09ZKkxYhdXorKgaZs3St6TuEx5Ejj9CBgsuHyKsWtaZt5hwMAXyYlo0kd6KcxJMyKxGxpItyH/bLPStYdIF6tC05vTSPQEJ5g54kVuqyolx5yEFa6BHUWJdBLHrQWmXZfTEqZbHbtlmeQpmu/NvVITfcb1Um5EIi0dEGJ7cOMls9vbPIamwpPF6qLiUEbvqh06xsT5bk2LQoa9aV9KiiJ2CAEC5iH271UUxo8HDcMN+47Woypfh1IKCFsxV3Bp4+pShdFt5CoVNj5hMn3stg30e5U+9e8WVeM9nsVuw19bcbjRQ1yJ++h0dtPd7ne8E86JIs3uOm8MvvYmbIprFoID8dIBKroQMIaGHclF8KscsOD468XQYSpYMAZhRyd0tBtfvxxeg8g1OFErQaPUIXEmYXnvyt/vnqNY2qkI9wxepu0m0IEVwOLLmOxipZaba2SQlSwwLeZQSGxYbsA7PxY9CpLQnwjsjWwFnJwZuL8pBT4J//q4Gjwi5Lgfp67KUnt8TfEzhRkAiPxx+nicm9h5UyhhMepDcxKbndNje4zmRc5MACBTz8gcdGHBJmeQUyV6d0vremf1AwCZBZEqQq0HtJ2cT9ugHebFcoGWW/jTAWSOTXC3OJsc5D3znTrcEEpqviR7DGEV5imxJZDucrMzQHPMLVYBsbqYvWcQ4fxbPaDhlhXtDDIS30bX0uq8tCmsuteHMM5DeCkNJADP/VujPSY+lNbfxbyZ2ew6+W3396KTckECcJEoN22p9LN+dod6CprLZHcjehyxvHSMarrVYchYxVUaMwDQwmM3Dz2Y8uc6ZNjsmM0jx5tzSkf42KEJAAxo6WLbHIC3WXpX7O9y9gMAU0C2FaUDNk0fBUSMsRbIsv9s4Jxl4AXs5N6KkJWVY7rNaf29153LRy/seL1XA4vkga/jkP5yItMgn6lmAMAKTw956J+WP+0Wx2Lflj/oDSczP9YTlNMcXHGheVk5xrF4YeU4CEl895GLY+G5BERrPEm0Gxe8uYPlguiNi9N5N37A3GXImFDHf/w4vMgTxIvgYogpSQR3zPG1p36WjntvYm3fRYd5LTWqGxOFJwq5OfZThLmbvBn5KRKMXHgXeinFfcqwxjTyU8IxUSDwRG+mxHn6shNUou2su5PoFtDT/gU/xq7htejanGN1k8K259gQj1TMAEChWuK5bR6a8Aqnqhg6+7Ttoj9hjjE7EwDYybeHZoL7W60Zbo/eTwKbZIztZey/exyzXwRLsqz9urZiHo53r14X3urKVNNuHA7h03UPlcUAQK6Ot7mPkhe7knFZWS0+lXYM/3ZXdbNq9Jp+SkSUEugfzw3rUPAGHFt+5hj+7S7MslogGEOCw+CW8c6o97Tz5uxC+RqYL7nyQHbnMpLW03FTT+3tW/1RtigWZHZ9uWJMQGbNSvZYBRlVXfYenyBcYF4R3YX8DB3T4i3/6Kw7SQvS7r96rzkOaS3ux1aiLfZewfPJSes9ovV0El6Lxo54i1VFTiU2XcwAQLfwuSufOHNx+JIVwulQc89aG9ayD7UoNAGAmiwis4uKzYg79gOiu1RuJVpbPbsgABCa27p6YEFhK7OIgVBr9mbEQEAZ4lkxEKZtv5EYiIhVsBIDkTTle2qpUjIpEKSuEiVBvLmoLeVmGIK8nVtkBLKumJ0lyGH+nSuQW2VFKSIjT8f03O2T89sl9uCvL+u9elAgSAD++7dGto5pyfCen2R3VI/Ll07qvXZQNEgAjhIlb9YhqPiIfLpoik+qk9AxQpD/7wUXL/LHhpUHrE5jBgCqzXA5oFYPpt6Yy0VWe6E+yxng7NIEAHBA2rZhAaVMOTULiJwGAUALCFtRS2CV6RsAe43xNhCy/zRA0DJQAyfG+4CszB3TdqxPx3jnd7SK4aOyknbcEMyIAHJmBgkA4IhP+HiRp34/RpwXf9p9ijQeN+9sJoJZEj8+FwZUhXYgky4YhmsuqjBb0lIbY4qSbU8ihKM9yLZIJFhcsscsD7J7vL7jD7O594DyiT+sEsxGCB3Wv1B6/VXeifOVXMtmwBY2O/F4jBs4uClZ+IRem24kbxL38eY+dODEHrfT5/17HQAgHQ8YG52fUA7J7Sy4w6f0OHaIjV4kyTzGkHipCbsY4yNGoRrseJxrHd1cxyN/jnEjRqXvGEM3+TCctjrGgVIdC67AwalQEKQXQZ4P7pSDZ+q/fNHZA2n5rPP4x7cB/cjP3HEDNKsgODUtHinnAIAx/Me1YI4p9mpAXpj0jOpfEE4bFLXNrgWzurnQPnaLBhfnGc7vlfiNLEsVgmWOD/yRf3/4690FmNn84un1rxEc2XDHH82fo6/lwf/WhP6Eyv/2kjxpYw8jcGN4A9Ty7duef514wvg/uTXr/cUvA/cf6Xblhu6DTk32Du+d4+2ek+Mjja2qtkAYByMhh94nWO/lNbjgS0REIgn/8RwxSmSs3VBt1a/hod24mkpBI0O7cX1MmZOsviPEkXbaTATTzlxYtDeeJvMlz9eQ0/YcpbuuTAyQ3cHFZd3NQKPy7k5b5fiA4TovKuYWy3i8Hjq+6H6Vf/vomBh3F0NTx46fzwD5OuUeTp2Hc24PxNPEZrj9EJ3G5XTTsZxeMx681t1EDx6vzC7re1p+IYfM4aN3+fsjFiqNdyz/S7Z3wMwOJGqb7DjsFsqVOhn/WNXp+JmMs/tlY2aGG6RZJSEB9meiAYBgyrd/cxA7eLRRyWc0r0drv9IHZDSne4YmADALkKpsAqW6hre30HlKyCKDUvOz/wAACgVSWPi5NshK7nYRyHd5cTogJ4W/TNNMXCSYRmUgMshUIz+Z3sPdi24M6komM5thYRKgypQy5sU1pDwutSCK+YxIEA/FbAmgrSs26A7Ec2mPFGSkaZh2mbwe73R+Jhb0xys1Q8MK/QjAj//WyLQwrQX+vUXqPNQ369S/kSZZWPEfAfg6lJssYTouITR7ncdIrxdR9HkSbmDMKgaSQrnnAIDUrEUZy8RZuAHGFfucJkkLgTqdnVvoYw4oOTQBAJrWZBMFE8DCNhfUZZAJLCjn/AcAemnxYv80AGL+pjTwxhQ3aW1o/UG0HFgGILBs+rkA","base64")).toString()),a}]]),g={hooks:{registerPackageExtensions:async(e,t)=>{for(const[e,r]of o)t(A.parseDescriptor(e,!0),r)},getBuiltinPatch:async(e,t)=>{var r;if(!t.startsWith("compat/"))return;const n=A.parseIdent(t.slice("compat/".length)),o=null===(r=c.get(n.identHash))||void 0===r?void 0:r();return void 0!==o?o:null},reduceDependency:async(e,t,r,n)=>void 0===c.get(e.identHash)?e:A.makeDescriptor(e,A.makeRange({protocol:"patch:",source:A.stringifyDescriptor(e),selector:`builtin`,params:null}))}}},10189:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>p});var A=r(36370),n=r(25413),o=r(54143),i=r(40822);class s extends n.BaseCommand{constructor(){super(...arguments),this.quiet=!1,this.args=[]}async execute(){const e=[];this.pkg&&e.push("--package",this.pkg),this.quiet&&e.push("--quiet");const t=o.parseIdent(this.command),r=o.makeIdent(t.scope,"create-"+t.name);return this.cli.run(["dlx",...e,o.stringifyIdent(r),...this.args])}}(0,A.gn)([i.Command.String("-p,--package",{description:"The package to run the provided command from"})],s.prototype,"pkg",void 0),(0,A.gn)([i.Command.Boolean("-q,--quiet",{description:"Only report critical errors instead of printing the full install logs"})],s.prototype,"quiet",void 0),(0,A.gn)([i.Command.String()],s.prototype,"command",void 0),(0,A.gn)([i.Command.Proxy()],s.prototype,"args",void 0),(0,A.gn)([i.Command.Path("create")],s.prototype,"execute",null);var a=r(39922),c=r(85824),g=r(63088),l=r(43896),u=r(46009);class h extends n.BaseCommand{constructor(){super(...arguments),this.quiet=!1,this.args=[]}async execute(){return a.VK.telemetry=null,await l.xfs.mktempPromise(async e=>{const t=u.y1.join(e,"dlx-"+process.pid);await l.xfs.mkdirPromise(t),await l.xfs.writeFilePromise(u.y1.join(t,"package.json"),"{}\n"),await l.xfs.writeFilePromise(u.y1.join(t,"yarn.lock"),"");const r=u.y1.join(t,".yarnrc.yml"),A=await a.VK.findProjectCwd(this.context.cwd,u.QS.lockfile),i=null!==A?u.y1.join(A,".yarnrc.yml"):null;null!==i&&l.xfs.existsSync(i)?(await l.xfs.copyFilePromise(i,r),await a.VK.updateConfiguration(t,e=>{const t={...e,enableGlobalCache:!0,enableTelemetry:!1};return Array.isArray(e.plugins)&&(t.plugins=e.plugins.map(e=>{const t="string"==typeof e?e:e.path,r=u.cS.isAbsolute(t)?t:u.cS.resolve(u.cS.fromPortablePath(A),t);return"string"==typeof e?r:{path:r,spec:e.spec}})),t})):await l.xfs.writeFilePromise(r,"enableGlobalCache: true\nenableTelemetry: false\n");const s=void 0!==this.pkg?[this.pkg]:[this.command],h=o.parseDescriptor(this.command).name,p=await this.cli.run(["add","--",...s],{cwd:t,quiet:this.quiet});if(0!==p)return p;this.quiet||this.context.stdout.write("\n");const d=await a.VK.find(t,this.context.plugins),{project:C,workspace:f}=await c.I.find(d,t);if(null===f)throw new n.WorkspaceRequiredError(C.cwd,t);return await C.restoreInstallState(),await g.executeWorkspaceAccessibleBinary(f,h,this.args,{cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr})})}}h.usage=i.Command.Usage({description:"run a package in a temporary environment",details:"\n This command will install a package within a temporary environment, and run its binary script if it contains any. The binary will run within the current cwd.\n\n By default Yarn will download the package named `command`, but this can be changed through the use of the `-p,--package` flag which will instruct Yarn to still run the same command but from a different package.\n\n Using `yarn dlx` as a replacement of `yarn add` isn't recommended, as it makes your project non-deterministic (Yarn doesn't keep track of the packages installed through `dlx` - neither their name, nor their version).\n ",examples:[["Use create-react-app to create a new React app","yarn dlx create-react-app ./my-app"]]}),(0,A.gn)([i.Command.String("-p,--package",{description:"The package to run the provided command from"})],h.prototype,"pkg",void 0),(0,A.gn)([i.Command.Boolean("-q,--quiet",{description:"Only report critical errors instead of printing the full install logs"})],h.prototype,"quiet",void 0),(0,A.gn)([i.Command.String()],h.prototype,"command",void 0),(0,A.gn)([i.Command.Proxy()],h.prototype,"args",void 0),(0,A.gn)([i.Command.Path("dlx")],h.prototype,"execute",null);const p={commands:[s,h]}},34777:(e,t,r)=>{"use strict";r.r(t),r.d(t,{dedupeUtils:()=>A,default:()=>We,suggestUtils:()=>A});var A={};r.r(A),r.d(A,{Modifier:()=>o,Strategy:()=>i,Target:()=>n,applyModifier:()=>S,extractDescriptorFromPath:()=>N,extractRangeModifier:()=>v,fetchDescriptorFrom:()=>K,findProjectDescriptors:()=>k,getModifier:()=>D,getSuggestedDescriptors:()=>F});var n,o,i,s=r(39922),a=r(36370),c=r(25413),g=r(28148),l=r(62152),u=r(92659),h=r(85824),p=r(15815),d=r(54143),C=r(40822),f=r(61899),I=r(33720),E=r(46611),B=r(71643),y=r(43896),m=r(46009),w=r(53887),Q=r.n(w);function D(e,t){return e.exact?o.EXACT:e.caret?o.CARET:e.tilde?o.TILDE:t.configuration.get("defaultSemverRangePrefix")}!function(e){e.REGULAR="dependencies",e.DEVELOPMENT="devDependencies",e.PEER="peerDependencies"}(n||(n={})),function(e){e.CARET="^",e.TILDE="~",e.EXACT=""}(o||(o={})),function(e){e.KEEP="keep",e.REUSE="reuse",e.PROJECT="project",e.LATEST="latest",e.CACHE="cache"}(i||(i={}));const b=/^([\^~]?)[0-9]+(?:\.[0-9]+){0,2}(?:-\S+)?$/;function v(e,{project:t}){const r=e.match(b);return r?r[1]:t.configuration.get("defaultSemverRangePrefix")}function S(e,t){let{protocol:r,source:A,params:n,selector:o}=d.parseRange(e.range);return Q().valid(o)&&(o=`${t}${e.range}`),d.makeDescriptor(e,d.makeRange({protocol:r,source:A,params:n,selector:o}))}async function k(e,{project:t,target:r}){const A=new Map,o=e=>{let t=A.get(e.descriptorHash);return t||A.set(e.descriptorHash,t={descriptor:e,locators:[]}),t};for(const A of t.workspaces)if(r===n.PEER){const t=A.manifest.peerDependencies.get(e.identHash);void 0!==t&&o(t).locators.push(A.locator)}else{const t=A.manifest.dependencies.get(e.identHash),i=A.manifest.devDependencies.get(e.identHash);r===n.DEVELOPMENT?void 0!==i?o(i).locators.push(A.locator):void 0!==t&&o(t).locators.push(A.locator):void 0!==t?o(t).locators.push(A.locator):void 0!==i&&o(i).locators.push(A.locator)}return A}async function N(e,{cwd:t,workspace:r}){return await async function(e){return await y.xfs.mktempPromise(async t=>{const r=s.VK.create(t);return r.useWithSource(t,{enableMirror:!1,compressionLevel:0},t,{overwrite:!0}),await e(new g.C(t,{configuration:r,check:!1,immutable:!1}))})}(async A=>{m.y1.isAbsolute(e)||(e=m.y1.relative(r.cwd,m.y1.resolve(t,e))).match(/^\.{0,2}\//)||(e="./"+e);const{project:n}=r,o=await K(d.makeIdent(null,"archive"),e,{project:r.project,cache:A,workspace:r});if(!o)throw new Error("Assertion failed: The descriptor should have been found");const i=new I.$,s=n.configuration.makeResolver(),a=n.configuration.makeFetcher(),c={checksums:n.storedChecksums,project:n,cache:A,fetcher:a,report:i,resolver:s},g=s.bindDescriptor(o,r.anchoredLocator,c),l=d.convertDescriptorToLocator(g),u=await a.fetch(l,c),h=await E.G.find(u.prefixPath,{baseFs:u.packageFs});if(!h.name)throw new Error("Target path doesn't have a name");return d.makeDescriptor(h.name,e)})}async function F(e,{project:t,workspace:r,cache:A,target:o,modifier:s,strategies:a,maxResults:c=1/0}){if(!(c>=0))throw new Error(`Invalid maxResults (${c})`);if("unknown"!==e.range)return{suggestions:[{descriptor:e,name:"Use "+d.prettyDescriptor(t.configuration,e),reason:"(unambiguous explicit request)"}],rejections:[]};const g=null!=r&&r.manifest[o].get(e.identHash)||null,l=[],u=[],h=async e=>{try{await e()}catch(e){u.push(e)}};for(const u of a){if(l.length>=c)break;switch(u){case i.KEEP:await h(async()=>{g&&l.push({descriptor:g,name:"Keep "+d.prettyDescriptor(t.configuration,g),reason:"(no changes)"})});break;case i.REUSE:await h(async()=>{for(const{descriptor:A,locators:n}of(await k(e,{project:t,target:o})).values()){if(1===n.length&&n[0].locatorHash===r.anchoredLocator.locatorHash&&a.includes(i.KEEP))continue;let e="(originally used by "+d.prettyLocator(t.configuration,n[0]);e+=n.length>1?` and ${n.length-1} other${n.length>2?"s":""})`:")",l.push({descriptor:A,name:"Reuse "+d.prettyDescriptor(t.configuration,A),reason:e})}});break;case i.CACHE:await h(async()=>{for(const r of t.storedDescriptors.values())r.identHash===e.identHash&&l.push({descriptor:r,name:"Reuse "+d.prettyDescriptor(t.configuration,r),reason:"(already used somewhere in the lockfile)"})});break;case i.PROJECT:await h(async()=>{if(null!==r.manifest.name&&e.identHash===r.manifest.name.identHash)return;const A=t.tryWorkspaceByIdent(e);null!==A&&l.push({descriptor:A.anchoredDescriptor,name:"Attach "+d.prettyWorkspace(t.configuration,A),reason:`(local workspace at ${A.cwd})`})});break;case i.LATEST:await h(async()=>{if("unknown"!==e.range)l.push({descriptor:e,name:"Use "+d.prettyRange(t.configuration,e.range),reason:"(explicit range requested)"});else if(o===n.PEER)l.push({descriptor:d.makeDescriptor(e,"*"),name:"Use *",reason:"(catch-all peer dependency pattern)"});else if(t.configuration.get("enableNetwork")){let n=await K(e,"latest",{project:t,cache:A,workspace:r,preserveModifier:!1});n&&(n=S(n,s),l.push({descriptor:n,name:"Use "+d.prettyDescriptor(t.configuration,n),reason:"(resolved from latest)"}))}else l.push({descriptor:null,name:"Resolve from latest",reason:B.pretty(t.configuration,"(unavailable because enableNetwork is toggled off)","grey")})})}}return{suggestions:l.slice(0,c),rejections:u.slice(0,c)}}async function K(e,t,{project:r,cache:A,workspace:n,preserveModifier:o=!0}){const i=d.makeDescriptor(e,t),s=new I.$,a=r.configuration.makeFetcher(),c=r.configuration.makeResolver(),g={project:r,fetcher:a,cache:A,checksums:r.storedChecksums,report:s,skipIntegrityCheck:!0},l={...g,resolver:c,fetchOptions:g},u=c.bindDescriptor(i,n.anchoredLocator,l),h=await c.getCandidates(u,new Map,l);if(0===h.length)return null;const p=h[0];let{protocol:C,source:f,params:E,selector:B}=d.parseRange(d.convertToManifestRange(p.reference));if(C===r.configuration.get("defaultProtocol")&&(C=null),Q().valid(B)&&!1!==o){B=v("string"==typeof o?o:i.range,{project:r})+B}return d.makeDescriptor(p,d.makeRange({protocol:C,source:f,params:E,selector:B}))}class M extends c.BaseCommand{constructor(){super(...arguments),this.packages=[],this.json=!1,this.exact=!1,this.tilde=!1,this.caret=!1,this.dev=!1,this.peer=!1,this.optional=!1,this.preferDev=!1,this.interactive=null,this.cached=!1}async execute(){var e;const t=await s.VK.find(this.context.cwd,this.context.plugins),{project:r,workspace:A}=await h.I.find(t,this.context.cwd),o=await g.C.find(t);if(!A)throw new c.WorkspaceRequiredError(r.cwd,this.context.cwd);await r.restoreInstallState({restoreResolutions:!1});const a=null!==(e=this.interactive)&&void 0!==e?e:t.get("preferInteractive"),I=D(this,r),E=[...a?[i.REUSE]:[],i.PROJECT,...this.cached?[i.CACHE]:[],i.LATEST],B=a?1/0:1,y=await Promise.all(this.packages.map(async e=>{const t=e.match(/^\.{0,2}\//)?await N(e,{cwd:this.context.cwd,workspace:A}):d.parseDescriptor(e),i=function(e,t,{dev:r,peer:A,preferDev:o,optional:i}){const s=e.manifest[n.REGULAR].has(t.identHash),a=e.manifest[n.DEVELOPMENT].has(t.identHash),c=e.manifest[n.PEER].has(t.identHash);if((r||A)&&s)throw new C.UsageError(`Package "${d.prettyIdent(e.project.configuration,t)}" is already listed as a regular dependency - remove the -D,-P flags or remove it from your dependencies first`);if(!r&&!A&&c)throw new C.UsageError(`Package "${d.prettyIdent(e.project.configuration,t)}" is already listed as a peer dependency - use either of -D or -P, or remove it from your peer dependencies first`);if(i&&a)throw new C.UsageError(`Package "${d.prettyIdent(e.project.configuration,t)}" is already listed as a dev dependency - remove the -O flag or remove it from your dev dependencies first`);if(i&&!A&&c)throw new C.UsageError(`Package "${d.prettyIdent(e.project.configuration,t)}" is already listed as a peer dependency - remove the -O flag or add the -P flag or remove it from your peer dependencies first`);if((r||o)&&i)throw new C.UsageError(`Package "${d.prettyIdent(e.project.configuration,t)}" cannot simultaneously be a dev dependency and an optional dependency`);return A?n.PEER:r||o?n.DEVELOPMENT:s?n.REGULAR:a?n.DEVELOPMENT:n.REGULAR}(A,t,{dev:this.dev,peer:this.peer,preferDev:this.preferDev,optional:this.optional});return[t,await F(t,{project:r,workspace:A,cache:o,target:i,modifier:I,strategies:E,maxResults:B}),i]})),m=await l.h.start({configuration:t,stdout:this.context.stdout,suggestInstall:!1},async e=>{for(const[A,{suggestions:n,rejections:o}]of y){if(0===n.filter(e=>null!==e.descriptor).length){const[n]=o;if(void 0===n)throw new Error("Assertion failed: Expected an error to have been set");const i=this.cli.error(n);r.configuration.get("enableNetwork")?e.reportError(u.b.CANT_SUGGEST_RESOLUTIONS,`${d.prettyDescriptor(t,A)} can't be resolved to a satisfying range:\n\n${i}`):e.reportError(u.b.CANT_SUGGEST_RESOLUTIONS,`${d.prettyDescriptor(t,A)} can't be resolved to a satisfying range (note: network resolution has been disabled):\n\n${i}`)}}});if(m.hasErrors())return m.exitCode();let w=!1;const Q=[],b=[];for(const[,{suggestions:e},t]of y){let r;const n=e.filter(e=>null!==e.descriptor),o=n[0].descriptor,i=n.every(e=>d.areDescriptorsEqual(e.descriptor,o));1===n.length||i?r=o:(w=!0,({answer:r}=await(0,f.prompt)({type:"select",name:"answer",message:"Which range do you want to use?",choices:e.map(({descriptor:e,name:t,reason:r})=>e?{name:t,hint:r,descriptor:e}:{name:t,hint:r,disabled:!0}),onCancel:()=>process.exit(130),result(e){return this.find(e,"descriptor")},stdin:this.context.stdin,stdout:this.context.stdout})));const s=A.manifest[t].get(r.identHash);void 0!==s&&s.descriptorHash===r.descriptorHash||(A.manifest[t].set(r.identHash,r),this.optional&&("dependencies"===t?A.manifest.ensureDependencyMeta({...r,range:"unknown"}).optional=!0:"peerDependencies"===t&&(A.manifest.ensurePeerDependencyMeta({...r,range:"unknown"}).optional=!0)),void 0===s?Q.push([A,t,r,E]):b.push([A,t,s,r]))}await t.triggerMultipleHooks(e=>e.afterWorkspaceDependencyAddition,Q),await t.triggerMultipleHooks(e=>e.afterWorkspaceDependencyReplacement,b),w&&this.context.stdout.write("\n");return(await p.Pk.start({configuration:t,json:this.json,stdout:this.context.stdout,includeLogs:!this.context.quiet},async e=>{await r.install({cache:o,report:e})})).exitCode()}}M.usage=C.Command.Usage({description:"add dependencies to the project",details:"\n This command adds a package to the package.json for the nearest workspace.\n\n - If it didn't exist before, the package will by default be added to the regular `dependencies` field, but this behavior can be overriden thanks to the `-D,--dev` flag (which will cause the dependency to be added to the `devDependencies` field instead) and the `-P,--peer` flag (which will do the same but for `peerDependencies`).\n\n - If the package was already listed in your dependencies, it will by default be upgraded whether it's part of your `dependencies` or `devDependencies` (it won't ever update `peerDependencies`, though).\n\n - If set, the `--prefer-dev` flag will operate as a more flexible `-D,--dev` in that it will add the package to your `devDependencies` if it isn't already listed in either `dependencies` or `devDependencies`, but it will also happily upgrade your `dependencies` if that's what you already use (whereas `-D,--dev` would throw an exception).\n\n - If set, the `-O,--optional` flag will add the package to the `optionalDependencies` field and, in combination with the `-P,--peer` flag, it will add the package as an optional peer dependency. If the package was already listed in your `dependencies`, it will be upgraded to `optionalDependencies`. If the package was already listed in your `peerDependencies`, in combination with the `-P,--peer` flag, it will be upgraded to an optional peer dependency: `\"peerDependenciesMeta\": { \"\": { \"optional\": true } }`\n\n - If the added package doesn't specify a range at all its `latest` tag will be resolved and the returned version will be used to generate a new semver range (using the `^` modifier by default unless otherwise configured via the `defaultSemverRangePrefix` configuration, or the `~` modifier if `-T,--tilde` is specified, or no modifier at all if `-E,--exact` is specified). Two exceptions to this rule: the first one is that if the package is a workspace then its local version will be used, and the second one is that if you use `-P,--peer` the default range will be `*` and won't be resolved at all.\n\n - If the added package specifies a range (such as `^1.0.0`, `latest`, or `rc`), Yarn will add this range as-is in the resulting package.json entry (in particular, tags such as `rc` will be encoded as-is rather than being converted into a semver range).\n\n If the `--cached` option is used, Yarn will preferably reuse the highest version already used somewhere within the project, even if through a transitive dependency.\n\n If the `-i,--interactive` option is used (or if the `preferInteractive` settings is toggled on) the command will first try to check whether other workspaces in the project use the specified package and, if so, will offer to reuse them.\n\n For a compilation of all the supported protocols, please consult the dedicated page from our website: https://yarnpkg.com/features/protocols.\n ",examples:[["Add a regular package to the current workspace","$0 add lodash"],["Add a specific version for a package to the current workspace","$0 add lodash@1.2.3"],["Add a package from a GitHub repository (the master branch) to the current workspace using a URL","$0 add lodash@https://github.com/lodash/lodash"],["Add a package from a GitHub repository (the master branch) to the current workspace using the GitHub protocol","$0 add lodash@github:lodash/lodash"],["Add a package from a GitHub repository (the master branch) to the current workspace using the GitHub protocol (shorthand)","$0 add lodash@lodash/lodash"],["Add a package from a specific branch of a GitHub repository to the current workspace using the GitHub protocol (shorthand)","$0 add lodash-es@lodash/lodash#es"]]}),(0,a.gn)([C.Command.Rest()],M.prototype,"packages",void 0),(0,a.gn)([C.Command.Boolean("--json",{description:"Format the output as an NDJSON stream"})],M.prototype,"json",void 0),(0,a.gn)([C.Command.Boolean("-E,--exact",{description:"Don't use any semver modifier on the resolved range"})],M.prototype,"exact",void 0),(0,a.gn)([C.Command.Boolean("-T,--tilde",{description:"Use the `~` semver modifier on the resolved range"})],M.prototype,"tilde",void 0),(0,a.gn)([C.Command.Boolean("-C,--caret",{description:"Use the `^` semver modifier on the resolved range"})],M.prototype,"caret",void 0),(0,a.gn)([C.Command.Boolean("-D,--dev",{description:"Add a package as a dev dependency"})],M.prototype,"dev",void 0),(0,a.gn)([C.Command.Boolean("-P,--peer",{description:"Add a package as a peer dependency"})],M.prototype,"peer",void 0),(0,a.gn)([C.Command.Boolean("-O,--optional",{description:"Add / upgrade a package to an optional regular / peer dependency"})],M.prototype,"optional",void 0),(0,a.gn)([C.Command.Boolean("--prefer-dev",{description:"Add / upgrade a package to a dev dependency"})],M.prototype,"preferDev",void 0),(0,a.gn)([C.Command.Boolean("-i,--interactive",{description:"Reuse the specified package from other workspaces in the project"})],M.prototype,"interactive",void 0),(0,a.gn)([C.Command.Boolean("--cached",{description:"Reuse the highest version already used somewhere within the project"})],M.prototype,"cached",void 0),(0,a.gn)([C.Command.Path("add")],M.prototype,"execute",null);var R=r(63088);class x extends c.BaseCommand{constructor(){super(...arguments),this.verbose=!1,this.json=!1}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),{project:t,locator:r}=await h.I.find(e,this.context.cwd);if(await t.restoreInstallState(),this.name){const A=(await R.getPackageAccessibleBinaries(r,{project:t})).get(this.name);if(!A)throw new C.UsageError(`Couldn't find a binary named "${this.name}" for package "${d.prettyLocator(e,r)}"`);const[,n]=A;return this.context.stdout.write(n+"\n"),0}return(await p.Pk.start({configuration:e,json:this.json,stdout:this.context.stdout},async A=>{const n=await R.getPackageAccessibleBinaries(r,{project:t}),o=Array.from(n.keys()).reduce((e,t)=>Math.max(e,t.length),0);for(const[e,[t,r]]of n)A.reportJson({name:e,source:d.stringifyIdent(t),path:r});if(this.verbose)for(const[t,[r]]of n)A.reportInfo(null,`${t.padEnd(o," ")} ${d.prettyLocator(e,r)}`);else for(const e of n.keys())A.reportInfo(null,e)})).exitCode()}}x.usage=C.Command.Usage({description:"get the path to a binary script",details:"\n When used without arguments, this command will print the list of all the binaries available in the current workspace. Adding the `-v,--verbose` flag will cause the output to contain both the binary name and the locator of the package that provides the binary.\n\n When an argument is specified, this command will just print the path to the binary on the standard output and exit. Note that the reported path may be stored within a zip archive.\n ",examples:[["List all the available binaries","$0 bin"],["Print the path to a specific binary","$0 bin eslint"]]}),(0,a.gn)([C.Command.String({required:!1})],x.prototype,"name",void 0),(0,a.gn)([C.Command.Boolean("-v,--verbose",{description:"Print both the binary name and the locator of the package that provides the binary"})],x.prototype,"verbose",void 0),(0,a.gn)([C.Command.Boolean("--json",{description:"Format the output as an NDJSON stream"})],x.prototype,"json",void 0),(0,a.gn)([C.Command.Path("bin")],x.prototype,"execute",null);class L extends c.BaseCommand{constructor(){super(...arguments),this.mirror=!1,this.all=!1}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),t=await g.C.find(e);return(await p.Pk.start({configuration:e,stdout:this.context.stdout},async()=>{const e=(this.all||this.mirror)&&null!==t.mirrorCwd,r=!this.mirror;e&&await y.xfs.removePromise(t.mirrorCwd),r&&await y.xfs.removePromise(t.cwd)})).exitCode()}}L.usage=C.Command.Usage({description:"remove the shared cache files",details:"\n This command will remove all the files from the cache.\n ",examples:[["Remove all the local archives","$0 cache clean"],["Remove all the archives stored in the ~/.yarn directory","$0 cache clean --mirror"]]}),(0,a.gn)([C.Command.Boolean("--mirror",{description:"Remove the global cache files instead of the local cache files"})],L.prototype,"mirror",void 0),(0,a.gn)([C.Command.Boolean("--all",{description:"Remove both the global cache files and the local cache files of the current project"})],L.prototype,"all",void 0),(0,a.gn)([C.Command.Path("cache","clean")],L.prototype,"execute",null);var P=r(73632),O=r(44674),U=r.n(O),T=r(31669);class j extends c.BaseCommand{constructor(){super(...arguments),this.json=!1,this.unsafe=!1}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),t=this.name.replace(/[.[].*$/,""),r=this.name.replace(/^[^.[]*/,"");if(void 0===e.settings.get(t))throw new C.UsageError(`Couldn't find a configuration settings named "${t}"`);const A=e.getSpecial(t,{hideSecrets:!this.unsafe,getNativePaths:!0}),n=P.convertMapsToIndexableObjects(A),o=r?U()(n,r):n,i=await p.Pk.start({configuration:e,includeFooter:!1,json:this.json,stdout:this.context.stdout},async e=>{e.reportJson(o)});if(!this.json){if("string"==typeof o)return this.context.stdout.write(o+"\n"),i.exitCode();T.inspect.styles.name="cyan",this.context.stdout.write((0,T.inspect)(o,{depth:1/0,colors:e.get("enableColors"),compact:!1})+"\n")}return i.exitCode()}}j.usage=C.Command.Usage({description:"read a configuration settings",details:"\n This command will print a configuration setting.\n\n Secrets (such as tokens) will be redacted from the output by default. If this behavior isn't desired, set the `--no-redacted` to get the untransformed value.\n ",examples:[["Print a simple configuration setting","yarn config get yarnPath"],["Print a complex configuration setting","yarn config get packageExtensions"],["Print a nested field from the configuration","yarn config get 'npmScopes[\"my-company\"].npmRegistryServer'"],["Print a token from the configuration","yarn config get npmAuthToken --no-redacted"],["Print a configuration setting as JSON","yarn config get packageExtensions --json"]]}),(0,a.gn)([C.Command.String()],j.prototype,"name",void 0),(0,a.gn)([C.Command.Boolean("--json",{description:"Format the output as an NDJSON stream"})],j.prototype,"json",void 0),(0,a.gn)([C.Command.Boolean("--no-redacted",{description:"Don't redact secrets (such as tokens) from the output"})],j.prototype,"unsafe",void 0),(0,a.gn)([C.Command.Path("config","get")],j.prototype,"execute",null);var Y=r(82558),G=r.n(Y),H=r(81534),J=r.n(H);class q extends c.BaseCommand{constructor(){super(...arguments),this.json=!1,this.home=!1}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins);if(!e.projectCwd)throw new C.UsageError("This command must be run from within a project folder");const t=this.name.replace(/[.[].*$/,""),r=this.name.replace(/^[^.[]*\.?/,"");if(void 0===e.settings.get(t))throw new C.UsageError(`Couldn't find a configuration settings named "${t}"`);const A=this.json?JSON.parse(this.value):this.value,n=this.home?e=>s.VK.updateHomeConfiguration(e):t=>s.VK.updateConfiguration(e.projectCwd,t);await n(e=>{if(r){const t=G()(e);return J()(t,this.name,A),t}return{...e,[t]:A}});const o=(await s.VK.find(this.context.cwd,this.context.plugins)).getSpecial(t,{hideSecrets:!0,getNativePaths:!0}),i=P.convertMapsToIndexableObjects(o),a=r?U()(i,r):i;return(await p.Pk.start({configuration:e,includeFooter:!1,stdout:this.context.stdout},async t=>{T.inspect.styles.name="cyan",t.reportInfo(u.b.UNNAMED,`Successfully set ${this.name} to ${(0,T.inspect)(a,{depth:1/0,colors:e.get("enableColors"),compact:!1})}`)})).exitCode()}}q.usage=C.Command.Usage({description:"change a configuration settings",details:"\n This command will set a configuration setting.\n\n When used without the `--json` flag, it can only set a simple configuration setting (a string, a number, or a boolean).\n\n When used with the `--json` flag, it can set both simple and complex configuration settings, including Arrays and Objects.\n ",examples:[["Set a simple configuration setting (a string, a number, or a boolean)","yarn config set initScope myScope"],["Set a simple configuration setting (a string, a number, or a boolean) using the `--json` flag",'yarn config set initScope --json \\"myScope\\"'],["Set a complex configuration setting (an Array) using the `--json` flag",'yarn config set unsafeHttpWhitelist --json \'["*.example.com", "example.com"]\''],["Set a complex configuration setting (an Object) using the `--json` flag",'yarn config set packageExtensions --json \'{ "@babel/parser@*": { "dependencies": { "@babel/types": "*" } } }\''],["Set a nested configuration setting",'yarn config set npmScopes.company.npmRegistryServer "https://npm.example.com"'],["Set a nested configuration setting using indexed access for non-simple keys",'yarn config set \'npmRegistries["//npm.example.com"].npmAuthToken\' "ffffffff-ffff-ffff-ffff-ffffffffffff"']]}),(0,a.gn)([C.Command.String()],q.prototype,"name",void 0),(0,a.gn)([C.Command.String()],q.prototype,"value",void 0),(0,a.gn)([C.Command.Boolean("--json",{description:"Set complex configuration settings to JSON values"})],q.prototype,"json",void 0),(0,a.gn)([C.Command.Boolean("-H,--home",{description:"Update the home configuration instead of the project configuration"})],q.prototype,"home",void 0),(0,a.gn)([C.Command.Path("config","set")],q.prototype,"execute",null);class z extends c.BaseCommand{constructor(){super(...arguments),this.verbose=!1,this.why=!1,this.json=!1}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins,{strict:!1});return(await p.Pk.start({configuration:e,json:this.json,stdout:this.context.stdout},async t=>{if(e.invalid.size>0&&!this.json){for(const[r,A]of e.invalid)t.reportError(u.b.INVALID_CONFIGURATION_KEY,`Invalid configuration key "${r}" in ${A}`);t.reportSeparator()}if(this.json){const r=P.sortMap(e.settings.keys(),e=>e);for(const A of r){const r=e.settings.get(A),n=e.getSpecial(A,{hideSecrets:!0,getNativePaths:!0}),o=e.sources.get(A);this.verbose?t.reportJson({key:A,effective:n,source:o}):t.reportJson({key:A,effective:n,source:o,...r})}}else{const r=P.sortMap(e.settings.keys(),e=>e),A=r.reduce((e,t)=>Math.max(e,t.length),0),n={breakLength:1/0,colors:e.get("enableColors"),maxArrayLength:2};if(this.why||this.verbose){const o=r.map(t=>{const r=e.settings.get(t);if(!r)throw new Error(`Assertion failed: This settings ("${t}") should have been registered`);return[t,this.why?e.sources.get(t)||"":r.description]}),i=o.reduce((e,[,t])=>Math.max(e,t.length),0);for(const[r,s]of o)t.reportInfo(null,`${r.padEnd(A," ")} ${s.padEnd(i," ")} ${(0,T.inspect)(e.getSpecial(r,{hideSecrets:!0,getNativePaths:!0}),n)}`)}else for(const o of r)t.reportInfo(null,`${o.padEnd(A," ")} ${(0,T.inspect)(e.getSpecial(o,{hideSecrets:!0,getNativePaths:!0}),n)}`)}})).exitCode()}}z.usage=C.Command.Usage({description:"display the current configuration",details:"\n This command prints the current active configuration settings.\n ",examples:[["Print the active configuration settings","$0 config"]]}),(0,a.gn)([C.Command.Boolean("-v,--verbose",{description:"Print the setting description on top of the regular key/value information"})],z.prototype,"verbose",void 0),(0,a.gn)([C.Command.Boolean("--why",{description:"Print the reason why a setting is set a particular way"})],z.prototype,"why",void 0),(0,a.gn)([C.Command.Boolean("--json",{description:"Format the output as an NDJSON stream"})],z.prototype,"json",void 0),(0,a.gn)([C.Command.Path("config")],z.prototype,"execute",null);var W,V=r(15966),X=r(35691),_=r(2401),Z=r.n(_);!function(e){e.HIGHEST="highest"}(W||(W={}));const $=new Set(Object.values(W)),ee={highest:async(e,t,{resolver:r,fetcher:A,resolveOptions:n,fetchOptions:o})=>{const i=new Map;for(const[t,r]of e.storedResolutions){const A=e.storedDescriptors.get(t);if(void 0===A)throw new Error(`Assertion failed: The descriptor (${t}) should have been registered`);P.getSetWithDefault(i,A.identHash).add(r)}return Array.from(e.storedDescriptors.values(),async A=>{if(t.length&&!Z().isMatch(d.stringifyIdent(A),t))return null;const o=e.storedResolutions.get(A.descriptorHash);if(void 0===o)throw new Error(`Assertion failed: The resolution (${A.descriptorHash}) should have been registered`);const s=e.originalPackages.get(o);if(void 0===s)return null;if(!r.shouldPersistResolution(s,n))return null;const a=i.get(A.identHash);if(void 0===a)throw new Error(`Assertion failed: The resolutions (${A.identHash}) should have been registered`);if(1===a.size)return null;const c=[...a].map(t=>{const r=e.originalPackages.get(t);if(void 0===r)throw new Error(`Assertion failed: The package (${t}) should have been registered`);return r.reference}),g=await r.getSatisfying(A,c,n),l=null==g?void 0:g[0];if(void 0===l)return null;const u=l.locatorHash,h=e.originalPackages.get(u);if(void 0===h)throw new Error(`Assertion failed: The package (${u}) should have been registered`);return u===o?null:{descriptor:A,currentPackage:s,updatedPackage:h}})}};class te extends c.BaseCommand{constructor(){super(...arguments),this.patterns=[],this.strategy=W.HIGHEST,this.check=!1,this.json=!1}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),{project:t}=await h.I.find(e,this.context.cwd),r=await g.C.find(e);let A=0;const n=await p.Pk.start({configuration:e,includeFooter:!1,stdout:this.context.stdout,json:this.json},async e=>{A=await async function(e,{strategy:t,patterns:r,cache:A,report:n}){const{configuration:o}=e,i=new I.$,s=o.makeResolver(),a=o.makeFetcher(),c={cache:A,checksums:e.storedChecksums,fetcher:a,project:e,report:i,skipIntegrityCheck:!0},g={project:e,resolver:s,report:i,fetchOptions:c};return await n.startTimerPromise("Deduplication step",async()=>{const A=ee[t],i=await A(e,r,{resolver:s,resolveOptions:g,fetcher:a,fetchOptions:c}),l=X.yG.progressViaCounter(i.length);n.reportProgress(l);let h,p=0;switch(await Promise.all(i.map(t=>t.then(t=>{if(null===t)return;p++;const{descriptor:r,currentPackage:A,updatedPackage:i}=t;n.reportInfo(u.b.UNNAMED,`${d.prettyDescriptor(o,r)} can be deduped from ${d.prettyLocator(o,A)} to ${d.prettyLocator(o,i)}`),n.reportJson({descriptor:d.stringifyDescriptor(r),currentResolution:d.stringifyLocator(A),updatedResolution:d.stringifyLocator(i)}),e.storedResolutions.set(r.descriptorHash,i.locatorHash)}).finally(()=>l.tick()))),p){case 0:h="No packages";break;case 1:h="One package";break;default:h=p+" packages"}const C=B.pretty(o,t,B.Type.CODE);return n.reportInfo(u.b.UNNAMED,`${h} can be deduped using the ${C} strategy`),p})}(t,{strategy:this.strategy,patterns:this.patterns,cache:r,report:e})});if(n.hasErrors())return n.exitCode();if(this.check)return A?1:0;return(await p.Pk.start({configuration:e,stdout:this.context.stdout,json:this.json},async e=>{await t.install({cache:r,report:e})})).exitCode()}}te.schema=V.object().shape({strategy:V.string().test({name:"strategy",message:"${path} must be one of ${strategies}",params:{strategies:[...$].join(", ")},test:e=>$.has(e)})}),te.usage=C.Command.Usage({description:"deduplicate dependencies with overlapping ranges",details:"\n Duplicates are defined as descriptors with overlapping ranges being resolved and locked to different locators. They are a natural consequence of Yarn's deterministic installs, but they can sometimes pile up and unnecessarily increase the size of your project.\n\n This command dedupes dependencies in the current project using different strategies (only one is implemented at the moment):\n\n - `highest`: Reuses (where possible) the locators with the highest versions. This means that dependencies can only be upgraded, never downgraded. It's also guaranteed that it never takes more than a single pass to dedupe the entire dependency tree.\n\n **Note:** Even though it never produces a wrong dependency tree, this command should be used with caution, as it modifies the dependency tree, which can sometimes cause problems when packages don't strictly follow semver recommendations. Because of this, it is recommended to also review the changes manually.\n\n If set, the `-c,--check` flag will only report the found duplicates, without persisting the modified dependency tree. If changes are found, the command will exit with a non-zero exit code, making it suitable for CI purposes.\n\n This command accepts glob patterns as arguments (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n ### In-depth explanation:\n\n Yarn doesn't deduplicate dependencies by default, otherwise installs wouldn't be deterministic and the lockfile would be useless. What it actually does is that it tries to not duplicate dependencies in the first place.\n\n **Example:** If `foo@^2.3.4` (a dependency of a dependency) has already been resolved to `foo@2.3.4`, running `yarn add foo@*`will cause Yarn to reuse `foo@2.3.4`, even if the latest `foo` is actually `foo@2.10.14`, thus preventing unnecessary duplication.\n\n Duplication happens when Yarn can't unlock dependencies that have already been locked inside the lockfile.\n\n **Example:** If `foo@^2.3.4` (a dependency of a dependency) has already been resolved to `foo@2.3.4`, running `yarn add foo@2.10.14` will cause Yarn to install `foo@2.10.14` because the existing resolution doesn't satisfy the range `2.10.14`. This behavior can lead to (sometimes) unwanted duplication, since now the lockfile contains 2 separate resolutions for the 2 `foo` descriptors, even though they have overlapping ranges, which means that the lockfile can be simplified so that both descriptors resolve to `foo@2.10.14`.\n ",examples:[["Dedupe all packages","$0 dedupe"],["Dedupe all packages using a specific strategy","$0 dedupe --strategy highest"],["Dedupe a specific package","$0 dedupe lodash"],["Dedupe all packages with the `@babel/*` scope","$0 dedupe '@babel/*'"],["Check for duplicates (can be used as a CI step)","$0 dedupe --check"]]}),(0,a.gn)([C.Command.Rest()],te.prototype,"patterns",void 0),(0,a.gn)([C.Command.String("-s,--strategy",{description:"The strategy to use when deduping dependencies"})],te.prototype,"strategy",void 0),(0,a.gn)([C.Command.Boolean("-c,--check",{description:"Exit with exit code 1 when duplicates are found, without persisting the dependency tree"})],te.prototype,"check",void 0),(0,a.gn)([C.Command.Boolean("--json",{description:"Format the output as an NDJSON stream"})],te.prototype,"json",void 0),(0,a.gn)([C.Command.Path("dedupe")],te.prototype,"execute",null);class re extends C.Command{async execute(){const{plugins:e}=await s.VK.find(this.context.cwd,this.context.plugins),t=[];for(const r of e){const{commands:e}=r[1];if(e){const A=C.Cli.from(e).definitions();t.push([r[0],A])}}const A=this.cli.definitions(),n=r(60306)["@yarnpkg/builder"].bundles.standard;for(const e of t){const t=e[1];for(const r of t)A.find(e=>{return t=e.path,A=r.path,t.split(" ").slice(1).join()===A.split(" ").slice(1).join();var t,A}).plugin={name:e[0],isDefault:n.includes(e[0])}}this.context.stdout.write(JSON.stringify({commands:A},null,2)+"\n")}}(0,a.gn)([C.Command.Path("--clipanion=definitions")],re.prototype,"execute",null);class Ae extends C.Command{async execute(){this.context.stdout.write(this.cli.usage(null))}}(0,a.gn)([C.Command.Path("help"),C.Command.Path("--help"),C.Command.Path("-h")],Ae.prototype,"execute",null);class ne extends C.Command{constructor(){super(...arguments),this.args=[]}async execute(){if(this.leadingArgument.match(/[\\/]/)&&!d.tryParseIdent(this.leadingArgument)){const e=m.y1.resolve(this.context.cwd,m.cS.toPortablePath(this.leadingArgument));return await this.cli.run(this.args,{cwd:e})}return await this.cli.run(["run",this.leadingArgument,...this.args])}}(0,a.gn)([C.Command.String()],ne.prototype,"leadingArgument",void 0),(0,a.gn)([C.Command.Proxy()],ne.prototype,"args",void 0);var oe=r(59355);class ie extends C.Command{async execute(){this.context.stdout.write((oe.o||"")+"\n")}}(0,a.gn)([C.Command.Path("-v"),C.Command.Path("--version")],ie.prototype,"execute",null);var se=r(6220);class ae extends c.BaseCommand{constructor(){super(...arguments),this.args=[]}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),{project:t}=await h.I.find(e,this.context.cwd);return await y.xfs.mktempPromise(async e=>{const{code:r}=await se.pipevp(this.commandName,this.args,{cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,env:await R.makeScriptEnv({project:t,binFolder:e})});return r})}}ae.usage=C.Command.Usage({description:"execute a shell command",details:"\n This command simply executes a shell binary within the context of the root directory of the active workspace.\n\n It also makes sure to call it in a way that's compatible with the current project (for example, on PnP projects the environment will be setup in such a way that PnP will be correctly injected into the environment).\n ",examples:[["Execute a shell command","$0 exec echo Hello World"]]}),(0,a.gn)([C.Command.String()],ae.prototype,"commandName",void 0),(0,a.gn)([C.Command.Proxy()],ae.prototype,"args",void 0),(0,a.gn)([C.Command.Path("exec")],ae.prototype,"execute",null);var ce=r(36545);class ge extends c.BaseCommand{async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),{project:t}=await h.I.find(e,this.context.cwd);if(await t.applyLightResolution(),void 0!==this.hash)return await async function(e,t,r){const{configuration:A}=t,n=t.peerRequirements.get(e);if(void 0===n)throw new Error(`No peerDependency requirements found for hash: "${e}"`);return(await p.Pk.start({configuration:A,stdout:r.stdout,includeFooter:!1},async e=>{var r,o;const i=t.storedPackages.get(n.subject);if(void 0===i)throw new Error("Assertion failed: Expected the subject package to have been registered");const s=t.storedPackages.get(n.rootRequester);if(void 0===s)throw new Error("Assertion failed: Expected the root package to have been registered");const a=null!==(r=i.dependencies.get(n.requested.identHash))&&void 0!==r?r:null,c=null!==a?t.storedResolutions.get(a.descriptorHash):null;if(void 0===c)throw new Error("Assertion failed: Expected the resolution to have been registered");const g=null!==c?t.storedPackages.get(c):null;if(void 0===g)throw new Error("Assertion failed: Expected the provided package to have been registered");const l=[...n.allRequesters.values()].map(e=>{const r=t.storedPackages.get(e);if(void 0===r)throw new Error("Assertion failed: Expected the package to be registered");const A=d.devirtualizeLocator(r),o=t.storedPackages.get(A.locatorHash);if(void 0===o)throw new Error("Assertion failed: Expected the package to be registered");const i=o.peerDependencies.get(n.requested.identHash);if(void 0===i)throw new Error("Assertion failed: Expected the peer dependency to be registered");return{pkg:r,peerDependency:i}});if(null!==g){const t=l.every(({peerDependency:e})=>ce.satisfiesWithPrereleases(g.version,e.range));e.reportInfo(u.b.UNNAMED,`${d.prettyLocator(A,i)} provides ${d.prettyLocator(A,g)} with version ${d.prettyReference(A,null!==(o=g.version)&&void 0!==o?o:"")}, which ${t?"satisfies":"doesn't satisfy"} the following requirements:`)}else e.reportInfo(u.b.UNNAMED,`${d.prettyLocator(A,i)} doesn't provide ${d.prettyIdent(A,n.requested)}, breaking the following requirements:`);e.reportSeparator();const h=B.mark(A),p=[];for(const{pkg:e,peerDependency:t}of P.sortMap(l,e=>d.stringifyLocator(e.pkg))){const r=null!==g&&ce.satisfiesWithPrereleases(g.version,t.range)?h.Check:h.Cross;p.push({stringifiedLocator:d.stringifyLocator(e),prettyLocator:d.prettyLocator(A,e),prettyRange:d.prettyRange(A,t.range),mark:r})}const C=Math.max(...p.map(({stringifiedLocator:e})=>e.length)),f=Math.max(...p.map(({prettyRange:e})=>e.length));for(const{stringifiedLocator:t,prettyLocator:r,prettyRange:A,mark:n}of P.sortMap(p,({stringifiedLocator:e})=>e))e.reportInfo(null,`${r.padEnd(C+(r.length-t.length)," ")} → ${A.padEnd(f," ")} ${n}`);p.length>1&&(e.reportSeparator(),e.reportInfo(u.b.UNNAMED,"Note: these requirements start with "+d.prettyLocator(t.configuration,s)))})).exitCode()}(this.hash,t,{stdout:this.context.stdout});return(await p.Pk.start({configuration:e,stdout:this.context.stdout,includeFooter:!1},async r=>{var A;const n=[([,e])=>d.stringifyLocator(t.storedPackages.get(e.subject)),([,e])=>d.stringifyIdent(e.requested)];for(const[o,i]of P.sortMap(t.peerRequirements,n)){const n=t.storedPackages.get(i.subject);if(void 0===n)throw new Error("Assertion failed: Expected the subject package to have been registered");const s=t.storedPackages.get(i.rootRequester);if(void 0===s)throw new Error("Assertion failed: Expected the root package to have been registered");const a=null!==(A=n.dependencies.get(i.requested.identHash))&&void 0!==A?A:null,c=B.pretty(e,o,B.Type.CODE),g=d.prettyLocator(e,n),l=d.prettyIdent(e,i.requested),u=d.prettyIdent(e,s),h=i.allRequesters.length-1,p="descendant"+(1===h?"":"s"),C=h>0?` and ${h} ${p}`:"",f=null!==a?"provides":"doesn't provide";r.reportInfo(null,`${c} → ${g} ${f} ${l} to ${u}${C}`)}})).exitCode()}}ge.schema=V.object().shape({hash:V.string().matches(/^p[0-9a-f]{5}$/)}),ge.usage=C.Command.Usage({description:"explain a set of peer requirements",details:"\n A set of peer requirements represents all peer requirements that a dependent must satisfy when providing a given peer request to a requester and its descendants.\n\n When the hash argument is specified, this command prints a detailed explanation of all requirements of the set corresponding to the hash and whether they're satisfied or not.\n\n When used without arguments, this command lists all sets of peer requirements and the corresponding hash that can be used to get detailed information about a given set.\n\n **Note:** A hash is a six-letter p-prefixed code that can be obtained from peer dependency warnings or from the list of all peer requirements (`yarn explain peer-requirements`).\n ",examples:[["Explain the corresponding set of peer requirements for a hash","$0 explain peer-requirements p1a4ed"],["List all sets of peer requirements","$0 explain peer-requirements"]]}),(0,a.gn)([C.Command.String({required:!1})],ge.prototype,"hash",void 0),(0,a.gn)([C.Command.Path("explain","peer-requirements")],ge.prototype,"execute",null);var le=r(85875);class ue extends c.BaseCommand{constructor(){super(...arguments),this.all=!1,this.recursive=!1,this.extra=[],this.cache=!1,this.dependents=!1,this.manifest=!1,this.nameOnly=!1,this.virtuals=!1,this.json=!1,this.patterns=[]}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await h.I.find(e,this.context.cwd),A=await g.C.find(e);if(!r&&!this.all)throw new c.WorkspaceRequiredError(t.cwd,this.context.cwd);await t.restoreInstallState();const n=new Set(this.extra);this.cache&&n.add("cache"),this.dependents&&n.add("dependents"),this.manifest&&n.add("manifest");const o=(e,{recursive:r})=>{const A=e.anchoredLocator.locatorHash,n=new Map,o=[A];for(;o.length>0;){const e=o.shift();if(n.has(e))continue;const i=t.storedPackages.get(e);if(void 0===i)throw new Error("Assertion failed: Expected the package to be registered");if(n.set(e,i),d.isVirtualLocator(i)&&o.push(d.devirtualizeLocator(i).locatorHash),r||e===A)for(const e of i.dependencies.values()){const r=t.storedResolutions.get(e.descriptorHash);if(void 0===r)throw new Error("Assertion failed: Expected the resolution to be registered");o.push(r)}}return n.values()},i=({all:e,recursive:A})=>e&&A?t.storedPackages.values():e?(({recursive:e})=>{const r=new Map;for(const A of t.workspaces)for(const t of o(A,{recursive:e}))r.set(t.locatorHash,t);return r.values()})({recursive:A}):o(r,{recursive:A}),{selection:a,sortedLookup:l}=(({all:e,recursive:t})=>{const r=i({all:e,recursive:t}),A=this.patterns.map(e=>{const t=d.parseLocator(e),r=Z().makeRe(d.stringifyIdent(t)),A=d.isVirtualLocator(t),n=A?d.devirtualizeLocator(t):t;return e=>{const o=d.stringifyIdent(e);if(!r.test(o))return!1;if("unknown"===t.reference)return!0;const i=d.isVirtualLocator(e),s=i?d.devirtualizeLocator(e):e;return(!A||!i||t.reference===e.reference)&&n.reference===s.reference}}),n=P.sortMap([...r],e=>d.stringifyLocator(e));return{selection:n.filter(e=>0===A.length||A.some(t=>t(e))),sortedLookup:n}})({all:this.all,recursive:this.recursive});if(0===a.length)throw new C.UsageError("No package matched your request");const u=new Map;if(this.dependents)for(const e of l)for(const r of e.dependencies.values()){const A=t.storedResolutions.get(r.descriptorHash);if(void 0===A)throw new Error("Assertion failed: Expected the resolution to be registered");P.getArrayWithDefault(u,A).push(e)}const p=new Map;for(const e of l){if(!d.isVirtualLocator(e))continue;const t=d.devirtualizeLocator(e);P.getArrayWithDefault(p,t.locatorHash).push(e)}const f={},m={children:f},w=e.makeFetcher(),Q={project:t,fetcher:w,cache:A,checksums:t.storedChecksums,report:new I.$,skipIntegrityCheck:!0},D=[async(e,t,r)=>{var A,n;if(!t.has("manifest"))return;const o=await w.fetch(e,Q);let i;try{i=await E.G.find(o.prefixPath,{baseFs:o.packageFs})}finally{null===(A=o.releaseFs)||void 0===A||A.call(o)}r("Manifest",{License:B.tuple(B.Type.NO_HINT,i.license),Homepage:B.tuple(B.Type.URL,null!==(n=i.raw.homepage)&&void 0!==n?n:null)})},async(e,r,n)=>{var o;if(!r.has("cache"))return;const i=null!==(o=t.storedChecksums.get(e.locatorHash))&&void 0!==o?o:null,s=A.getLocatorPath(e,i);let a;if(null!==s)try{a=y.xfs.statSync(s)}catch(e){}const c=void 0!==a?[a.size,B.Type.SIZE]:void 0;n("Cache",{Checksum:B.tuple(B.Type.NO_HINT,i),Path:B.tuple(B.Type.PATH,s),Size:c})}];for(const r of a){const A=d.isVirtualLocator(r);if(!this.virtuals&&A)continue;const o={},i={value:[r,B.Type.LOCATOR],children:o};if(f[d.stringifyLocator(r)]=i,this.nameOnly){delete i.children;continue}const s=p.get(r.locatorHash);void 0!==s&&(o.Instances={label:"Instances",value:B.tuple(B.Type.NUMBER,s.length)}),o.Version={label:"Version",value:B.tuple(B.Type.NO_HINT,r.version)};const a=(e,t)=>{const r={};if(o[e]=r,Array.isArray(t))r.children=t.map(e=>({value:e}));else{const e={};r.children=e;for(const[r,A]of Object.entries(t))void 0!==A&&(e[r]={label:r,value:A})}};if(!A){for(const e of D)await e(r,n,a);await e.triggerHook(e=>e.fetchPackageInfo,r,n,a)}r.bin.size>0&&!A&&a("Exported Binaries",[...r.bin.keys()].map(e=>B.tuple(B.Type.PATH,e)));const c=u.get(r.locatorHash);void 0!==c&&c.length>0&&a("Dependents",c.map(e=>B.tuple(B.Type.LOCATOR,e))),r.dependencies.size>0&&!A&&a("Dependencies",[...r.dependencies.values()].map(e=>{var r;const A=t.storedResolutions.get(e.descriptorHash),n=void 0!==A&&null!==(r=t.storedPackages.get(A))&&void 0!==r?r:null;return B.tuple(B.Type.RESOLUTION,{descriptor:e,locator:n})})),r.peerDependencies.size>0&&A&&a("Peer dependencies",[...r.peerDependencies.values()].map(e=>{var A,n;const o=r.dependencies.get(e.identHash),i=void 0!==o&&null!==(A=t.storedResolutions.get(o.descriptorHash))&&void 0!==A?A:null,s=null!==i&&null!==(n=t.storedPackages.get(i))&&void 0!==n?n:null;return B.tuple(B.Type.RESOLUTION,{descriptor:e,locator:s})}))}le.emitTree(m,{configuration:e,json:this.json,stdout:this.context.stdout,separators:this.nameOnly?0:2})}}ue.usage=C.Command.Usage({description:"see information related to packages",details:"\n This command prints various information related to the specified packages, accepting glob patterns.\n\n By default, if the locator reference is missing, Yarn will default to print the information about all the matching direct dependencies of the package for the active workspace. To instead print all versions of the package that are direct dependencies of any of your workspaces, use the `-A,--all` flag. Adding the `-R,--recursive` flag will also report transitive dependencies.\n\n Some fields will be hidden by default in order to keep the output readable, but can be selectively displayed by using additional options (`--dependents`, `--manifest`, `--virtuals`, ...) described in the option descriptions.\n\n Note that this command will only print the information directly related to the selected packages - if you wish to know why the package is there in the first place, use `yarn why` which will do just that (it also provides a `-R,--recursive` flag that may be of some help).\n ",examples:[["Show information about Lodash","$0 info lodash"]]}),(0,a.gn)([C.Command.Boolean("-A,--all",{description:"Print versions of a package from the whole project"})],ue.prototype,"all",void 0),(0,a.gn)([C.Command.Boolean("-R,--recursive",{description:"Print information for all packages, including transitive dependencies"})],ue.prototype,"recursive",void 0),(0,a.gn)([C.Command.Array("-X,--extra",{description:"An array of requests of extra data provided by plugins"})],ue.prototype,"extra",void 0),(0,a.gn)([C.Command.Boolean("--cache",{description:"Print information about the cache entry of a package (path, size, checksum)"})],ue.prototype,"cache",void 0),(0,a.gn)([C.Command.Boolean("--dependents",{description:"Print all dependents for each matching package"})],ue.prototype,"dependents",void 0),(0,a.gn)([C.Command.Boolean("--manifest",{description:"Print data obtained by looking at the package archive (license, homepage, ...)"})],ue.prototype,"manifest",void 0),(0,a.gn)([C.Command.Boolean("--name-only",{description:"Only print the name for the matching packages"})],ue.prototype,"nameOnly",void 0),(0,a.gn)([C.Command.Boolean("--virtuals",{description:"Print each instance of the virtual packages"})],ue.prototype,"virtuals",void 0),(0,a.gn)([C.Command.Boolean("--json",{description:"Format the output as an NDJSON stream"})],ue.prototype,"json",void 0),(0,a.gn)([C.Command.Rest()],ue.prototype,"patterns",void 0),(0,a.gn)([C.Command.Path("info")],ue.prototype,"execute",null);var he=r(11640),pe=r(5864);class de extends c.BaseCommand{constructor(){super(...arguments),this.json=!1,this.checkCache=!1,this.skipBuilds=!1,this.silent=!1}async execute(){var e,t,r;const A=await s.VK.find(this.context.cwd,this.context.plugins);void 0!==this.inlineBuilds&&A.useWithSource("",{enableInlineBuilds:this.inlineBuilds},A.startingCwd,{overwrite:!0});const n=!!process.env.NOW_BUILDER,o=!!process.env.NETLIFY,i=!!process.env.FUNCTION_TARGET||!!process.env.GOOGLE_RUNTIME,a=async(e,{error:t})=>{const r=await p.Pk.start({configuration:A,stdout:this.context.stdout,includeFooter:!1},async r=>{t?r.reportError(u.b.DEPRECATED_CLI_SETTINGS,e):r.reportWarning(u.b.DEPRECATED_CLI_SETTINGS,e)});return r.hasErrors()?r.exitCode():null};if(void 0!==this.ignoreEngines){const e=await a("The --ignore-engines option is deprecated; engine checking isn't a core feature anymore",{error:!n});if(null!==e)return e}if(void 0!==this.registry){const e=await a("The --registry option is deprecated; prefer setting npmRegistryServer in your .yarnrc.yml file",{error:!1});if(null!==e)return e}if(void 0!==this.preferOffline){const e=await a("The --prefer-offline flag is deprecated; use the --cached flag with 'yarn add' instead",{error:!n});if(null!==e)return e}if(void 0!==this.production){const e=await a("The --production option is deprecated on 'install'; use 'yarn workspaces focus' instead",{error:!0});if(null!==e)return e}if(void 0!==this.nonInteractive){const e=await a("The --non-interactive option is deprecated",{error:!i});if(null!==e)return e}if(void 0!==this.frozenLockfile){const e=await a("The --frozen-lockfile option is deprecated; use --immutable and/or --immutable-cache instead",{error:!i&&!pe.TRAVIS});if(null!==e)return e}if(void 0!==this.cacheFolder){const e=await a("The cache-folder option has been deprecated; use rc settings instead",{error:!o});if(null!==e)return e}const l=void 0===this.immutable&&void 0===this.frozenLockfile?null!==(e=A.get("enableImmutableInstalls"))&&void 0!==e&&e:null!==(r=null!==(t=this.immutable)&&void 0!==t?t:this.frozenLockfile)&&void 0!==r&&r;if(null!==A.projectCwd){const e=await p.Pk.start({configuration:A,json:this.json,stdout:this.context.stdout,includeFooter:!1},async e=>{await async function(e,t){if(!e.projectCwd)return!1;const r=m.y1.join(e.projectCwd,e.get("lockfileFilename"));if(!await y.xfs.existsPromise(r))return!1;const A=await y.xfs.readFilePromise(r,"utf8");if(!A.includes("<<<<<<<"))return!1;if(t)throw new X.lk(u.b.AUTOMERGE_IMMUTABLE,"Cannot autofix a lockfile when running an immutable install");const[n,o]=function(e){const t=[[],[]],r=e.split(/\r?\n/g);let A=!1;for(;r.length>0;){const e=r.shift();if(void 0===e)throw new Error("Assertion failed: Some lines should remain");if(e.startsWith("<<<<<<<")){for(;r.length>0;){const e=r.shift();if(void 0===e)throw new Error("Assertion failed: Some lines should remain");if("======="===e){A=!1;break}A||e.startsWith("|||||||")?A=!0:t[0].push(e)}for(;r.length>0;){const e=r.shift();if(void 0===e)throw new Error("Assertion failed: Some lines should remain");if(e.startsWith(">>>>>>>"))break;t[1].push(e)}}else t[0].push(e),t[1].push(e)}return[t[0].join("\n"),t[1].join("\n")]}(A);let i,s;try{i=(0,he.parseSyml)(n),s=(0,he.parseSyml)(o)}catch(e){throw new X.lk(u.b.AUTOMERGE_FAILED_TO_PARSE,"The individual variants of the lockfile failed to parse")}const a={...i,...s};for(const[e,t]of Object.entries(a))"string"==typeof t&&delete a[e];return await y.xfs.changeFilePromise(r,(0,he.stringifySyml)(a),{automaticNewlines:!0}),!0}(A,l)&&(e.reportInfo(u.b.AUTOMERGE_SUCCESS,"Automatically fixed merge conflicts 👍"),e.reportSeparator())});if(e.hasErrors())return e.exitCode()}if(null!==A.projectCwd){const e=await p.Pk.start({configuration:A,json:this.json,stdout:this.context.stdout,includeFooter:!1},async e=>{var t;(null===(t=s.VK.telemetry)||void 0===t?void 0:t.isNew)&&(e.reportInfo(u.b.TELEMETRY_NOTICE,"Yarn will periodically gather anonymous telemetry: https://yarnpkg.com/advanced/telemetry"),e.reportInfo(u.b.TELEMETRY_NOTICE,`Run ${B.pretty(A,"yarn config set --home enableTelemetry 0",B.Type.CODE)} to disable`),e.reportSeparator())});if(e.hasErrors())return e.exitCode()}const{project:d,workspace:C}=await h.I.find(A,this.context.cwd),f=await g.C.find(A,{immutable:this.immutableCache,check:this.checkCache});if(!C)throw new c.WorkspaceRequiredError(d.cwd,this.context.cwd);await d.restoreInstallState({restoreResolutions:!1});return(await p.Pk.start({configuration:A,json:this.json,stdout:this.context.stdout,includeLogs:!0},async e=>{await d.install({cache:f,report:e,immutable:l,skipBuild:this.skipBuilds})})).exitCode()}}de.usage=C.Command.Usage({description:"install the project dependencies",details:"\n This command setup your project if needed. The installation is splitted in four different steps that each have their own characteristics:\n\n - **Resolution:** First the package manager will resolve your dependencies. The exact way a dependency version is privileged over another isn't standardized outside of the regular semver guarantees. If a package doesn't resolve to what you would expect, check that all dependencies are correctly declared (also check our website for more information: ).\n\n - **Fetch:** Then we download all the dependencies if needed, and make sure that they're all stored within our cache (check the value of `cacheFolder` in `yarn config` to see where are stored the cache files).\n\n - **Link:** Then we send the dependency tree information to internal plugins tasked from writing them on the disk in some form (for example by generating the .pnp.js file you might know).\n\n - **Build:** Once the dependency tree has been written on the disk, the package manager will now be free to run the build scripts for all packages that might need it, in a topological order compatible with the way they depend on one another.\n\n Note that running this command is not part of the recommended workflow. Yarn supports zero-installs, which means that as long as you store your cache and your .pnp.js file inside your repository, everything will work without requiring any install right after cloning your repository or switching branches.\n\n If the `--immutable` option is set, Yarn will abort with an error exit code if the lockfile was to be modified (other paths can be added using the `immutablePaths` configuration setting). For backward compatibility we offer an alias under the name of `--frozen-lockfile`, but it will be removed in a later release.\n\n If the `--immutable-cache` option is set, Yarn will abort with an error exit code if the cache folder was to be modified (either because files would be added, or because they'd be removed).\n\n If the `--check-cache` option is set, Yarn will always refetch the packages and will ensure that their checksum matches what's 1/ described in the lockfile 2/ inside the existing cache files (if present). This is recommended as part of your CI workflow if you're both following the Zero-Installs model and accepting PRs from third-parties, as they'd otherwise have the ability to alter the checked-in packages before submitting them.\n\n If the `--inline-builds` option is set, Yarn will verbosely print the output of the build steps of your dependencies (instead of writing them into individual files). This is likely useful mostly for debug purposes only when using Docker-like environments.\n\n If the `--skip-builds` option is set, Yarn will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the later will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n ",examples:[["Install the project","$0 install"],["Validate a project when using Zero-Installs","$0 install --immutable --immutable-cache"],["Validate a project when using Zero-Installs (slightly safer if you accept external PRs)","$0 install --immutable --immutable-cache --check-cache"]]}),(0,a.gn)([C.Command.Boolean("--json",{description:"Format the output as an NDJSON stream"})],de.prototype,"json",void 0),(0,a.gn)([C.Command.Boolean("--immutable",{description:"Abort with an error exit code if the lockfile was to be modified"})],de.prototype,"immutable",void 0),(0,a.gn)([C.Command.Boolean("--immutable-cache",{description:"Abort with an error exit code if the cache folder was to be modified"})],de.prototype,"immutableCache",void 0),(0,a.gn)([C.Command.Boolean("--check-cache",{description:"Always refetch the packages and ensure that their checksums are consistent"})],de.prototype,"checkCache",void 0),(0,a.gn)([C.Command.Boolean("--production",{hidden:!0})],de.prototype,"production",void 0),(0,a.gn)([C.Command.Boolean("--non-interactive",{hidden:!0})],de.prototype,"nonInteractive",void 0),(0,a.gn)([C.Command.Boolean("--frozen-lockfile",{hidden:!0})],de.prototype,"frozenLockfile",void 0),(0,a.gn)([C.Command.Boolean("--prefer-offline",{hidden:!0})],de.prototype,"preferOffline",void 0),(0,a.gn)([C.Command.Boolean("--ignore-engines",{hidden:!0})],de.prototype,"ignoreEngines",void 0),(0,a.gn)([C.Command.String("--registry",{hidden:!0})],de.prototype,"registry",void 0),(0,a.gn)([C.Command.Boolean("--inline-builds",{description:"Verbosely print the output of the build steps of dependencies"})],de.prototype,"inlineBuilds",void 0),(0,a.gn)([C.Command.Boolean("--skip-builds",{description:"Skip the build step altogether"})],de.prototype,"skipBuilds",void 0),(0,a.gn)([C.Command.String("--cache-folder",{hidden:!0})],de.prototype,"cacheFolder",void 0),(0,a.gn)([C.Command.Boolean("--silent",{hidden:!0})],de.prototype,"silent",void 0),(0,a.gn)([C.Command.Path(),C.Command.Path("install")],de.prototype,"execute",null);class Ce extends c.BaseCommand{constructor(){super(...arguments),this.all=!1,this.private=!1,this.relative=!1}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await h.I.find(e,this.context.cwd),A=await g.C.find(e);if(!r)throw new c.WorkspaceRequiredError(t.cwd,this.context.cwd);const n=m.y1.resolve(this.context.cwd,m.cS.toPortablePath(this.destination)),o=await s.VK.find(n,this.context.plugins),{project:i,workspace:a}=await h.I.find(o,n);if(!a)throw new c.WorkspaceRequiredError(i.cwd,n);const l=t.topLevelWorkspace,u=[];if(this.all){for(const e of i.workspaces)!e.manifest.name||e.manifest.private&&!this.private||u.push(e);if(0===u.length)throw new C.UsageError("No workspace found to be linked in the target project")}else{if(!a.manifest.name)throw new C.UsageError("The target workspace doesn't have a name and thus cannot be linked");if(a.manifest.private&&!this.private)throw new C.UsageError("The target workspace is marked private - use the --private flag to link it anyway");u.push(a)}for(const e of u){const r=d.stringifyIdent(e.locator),A=this.relative?m.y1.relative(t.cwd,e.cwd):e.cwd;l.manifest.resolutions.push({pattern:{descriptor:{fullName:r}},reference:"portal:"+A})}return(await p.Pk.start({configuration:e,stdout:this.context.stdout},async e=>{await t.install({cache:A,report:e})})).exitCode()}}Ce.usage=C.Command.Usage({description:"connect the local project to another one",details:"\n This command will set a new `resolutions` field in the project-level manifest and point it to the workspace at the specified location (even if part of another project).\n\n There is no `yarn unlink` command. To unlink the workspaces from the current project one must revert the changes made to the `resolutions` field.\n ",examples:[["Register a remote workspace for use in the current project","$0 link ~/ts-loader"],["Register all workspaces from a remote project for use in the current project","$0 link ~/jest --all"]]}),(0,a.gn)([C.Command.String()],Ce.prototype,"destination",void 0),(0,a.gn)([C.Command.Boolean("-A,--all",{description:"Link all workspaces belonging to the target project to the current one"})],Ce.prototype,"all",void 0),(0,a.gn)([C.Command.Boolean("-p,--private",{description:"Also link private workspaces belonging to the target project to the current one"})],Ce.prototype,"private",void 0),(0,a.gn)([C.Command.Boolean("-r,--relative",{description:"Link workspaces using relative paths instead of absolute paths"})],Ce.prototype,"relative",void 0),(0,a.gn)([C.Command.Path("link")],Ce.prototype,"execute",null);class fe extends c.BaseCommand{constructor(){super(...arguments),this.args=[]}async execute(){return this.cli.run(["exec","node",...this.args])}}fe.usage=C.Command.Usage({description:"run node with the hook already setup",details:"\n This command simply runs Node. It also makes sure to call it in a way that's compatible with the current project (for example, on PnP projects the environment will be setup in such a way that PnP will be correctly injected into the environment).\n\n The Node process will use the exact same version of Node as the one used to run Yarn itself, which might be a good way to ensure that your commands always use a consistent Node version.\n ",examples:[["Run a Node script","$0 node ./my-script.js"]]}),(0,a.gn)([C.Command.Proxy()],fe.prototype,"args",void 0),(0,a.gn)([C.Command.Path("node")],fe.prototype,"execute",null);var Ie=r(20624),Ee=r(12087),Be=r(85622),ye=r.n(Be),me=r(79669);class we extends c.BaseCommand{constructor(){super(...arguments),this.onlyIfNeeded=!1}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins);if(e.get("yarnPath")&&this.onlyIfNeeded)return 0;let t;if("latest"===this.version||"berry"===this.version)t="https://github.com/yarnpkg/berry/raw/master/packages/yarnpkg-cli/bin/yarn.js";else if("classic"===this.version)t="https://nightly.yarnpkg.com/latest.js";else if(ce.satisfiesWithPrereleases(this.version,">=2.0.0"))t=`https://github.com/yarnpkg/berry/raw/%40yarnpkg/cli/${this.version}/packages/yarnpkg-cli/bin/yarn.js`;else{if(!ce.satisfiesWithPrereleases(this.version,"^0.x || ^1.x"))throw Q().validRange(this.version)?new C.UsageError("Support for ranges got removed - please use the exact version you want to install, or 'latest' to get the latest build available"):new C.UsageError(`Invalid version descriptor "${this.version}"`);t=`https://github.com/yarnpkg/yarn/releases/download/v${this.version}/yarn-${this.version}.js`}return(await p.Pk.start({configuration:e,stdout:this.context.stdout},async r=>{r.reportInfo(u.b.UNNAMED,"Downloading "+B.pretty(e,t,"green"));const A=await me.get(t,{configuration:e});await Qe(e,null,A,{report:r})})).exitCode()}}async function Qe(e,t,r,{report:A}){const n=e.projectCwd?e.projectCwd:e.startingCwd;null===t&&await y.xfs.mktempPromise(async e=>{const A=m.y1.join(e,"yarn.cjs");await y.xfs.writeFilePromise(A,r);const{stdout:o}=await se.execvp(process.execPath,[m.cS.fromPortablePath(A),"--version"],{cwd:n,env:{...process.env,YARN_IGNORE_PATH:"1"}});if(t=o.trim(),!Q().valid(t))throw new Error("Invalid semver version")});const o=m.y1.resolve(n,".yarn/releases"),i=m.y1.resolve(o,`yarn-${t}.cjs`),a=m.y1.relative(e.startingCwd,i),c=m.y1.relative(n,i),g=e.get("yarnPath"),l=null===g||g.startsWith(o+"/");A.reportInfo(u.b.UNNAMED,"Saving the new release in "+B.pretty(e,a,"magenta")),await y.xfs.removePromise(m.y1.dirname(i)),await y.xfs.mkdirPromise(m.y1.dirname(i),{recursive:!0}),await y.xfs.writeFilePromise(i,r),await y.xfs.chmodPromise(i,493),l&&await s.VK.updateConfiguration(n,{yarnPath:c})}we.usage=C.Command.Usage({description:"lock the Yarn version used by the project",details:"\n This command will download a specific release of Yarn directly from the Yarn GitHub repository, will store it inside your project, and will change the `yarnPath` settings from your project `.yarnrc.yml` file to point to the new file.\n\n A very good use case for this command is to enforce the version of Yarn used by the any single member of your team inside a same project - by doing this you ensure that you have control on Yarn upgrades and downgrades (including on your deployment servers), and get rid of most of the headaches related to someone using a slightly different version and getting a different behavior than you.\n ",examples:[["Download the latest release from the Yarn repository","$0 set version latest"],["Download the latest classic release from the Yarn repository","$0 set version classic"],["Download a specific Yarn 2 build","$0 set version 2.0.0-rc.30"],["Switch back to a specific Yarn 1 release","$0 set version 1.22.1"]]}),(0,a.gn)([C.Command.Boolean("--only-if-needed",{description:"Only lock the Yarn version if it isn't already locked"})],we.prototype,"onlyIfNeeded",void 0),(0,a.gn)([C.Command.String()],we.prototype,"version",void 0),(0,a.gn)([C.Command.Path("policies","set-version"),C.Command.Path("set","version")],we.prototype,"execute",null);const De=/^[0-9]+$/;function be(e){return De.test(e)?`pull/${e}/head`:e}class ve extends c.BaseCommand{constructor(){super(...arguments),this.repository="https://github.com/yarnpkg/berry.git",this.branch="master",this.plugins=[],this.noMinify=!1,this.force=!1}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),t=void 0!==this.installPath?m.y1.resolve(this.context.cwd,m.cS.toPortablePath(this.installPath)):m.y1.resolve(m.cS.toPortablePath((0,Ee.tmpdir)()),"yarnpkg-sources",Ie.makeHash(this.repository).slice(0,6));return(await p.Pk.start({configuration:e,stdout:this.context.stdout},async r=>{await ke(this,{configuration:e,report:r,target:t}),r.reportSeparator(),r.reportInfo(u.b.UNNAMED,"Building a fresh bundle"),r.reportSeparator(),await Se((({plugins:e,noMinify:t},r)=>[["yarn","build:cli",...(new Array).concat(...e.map(e=>["--plugin",ye().resolve(r,e)])),...t?["--no-minify"]:[],"|"]])(this,t),{configuration:e,context:this.context,target:t}),r.reportSeparator();const A=m.y1.resolve(t,"packages/yarnpkg-cli/bundles/yarn.js"),n=await y.xfs.readFilePromise(A);await Qe(e,"sources",n,{report:r})})).exitCode()}}async function Se(e,{configuration:t,context:r,target:A}){for(const[n,...o]of e){const e="|"===o[o.length-1];if(e&&o.pop(),e)await se.pipevp(n,o,{cwd:A,stdin:r.stdin,stdout:r.stdout,stderr:r.stderr,strict:!0});else{r.stdout.write(B.pretty(t," $ "+[n,...o].join(" "),"grey")+"\n");try{await se.execvp(n,o,{cwd:A,strict:!0})}catch(e){throw r.stdout.write(e.stdout||e.stack),e}}}}async function ke(e,{configuration:t,report:r,target:A}){let n=!1;if(!e.force&&y.xfs.existsSync(m.y1.join(A,".git"))){r.reportInfo(u.b.UNNAMED,"Fetching the latest commits"),r.reportSeparator();try{await Se((({branch:e})=>[["git","fetch","origin",be(e),"--force"],["git","reset","--hard","FETCH_HEAD"],["git","clean","-dfx"]])(e),{configuration:t,context:e.context,target:A}),n=!0}catch(e){r.reportSeparator(),r.reportWarning(u.b.UNNAMED,"Repository update failed; we'll try to regenerate it")}}n||(r.reportInfo(u.b.UNNAMED,"Cloning the remote repository"),r.reportSeparator(),await y.xfs.removePromise(A),await y.xfs.mkdirPromise(A,{recursive:!0}),await Se((({repository:e,branch:t},r)=>[["git","init",m.cS.fromPortablePath(r)],["git","remote","add","origin",e],["git","fetch","origin",be(t)],["git","reset","--hard","FETCH_HEAD"]])(e,A),{configuration:t,context:e.context,target:A}))}ve.usage=C.Command.Usage({description:"build Yarn from master",details:"\n This command will clone the Yarn repository into a temporary folder, then build it. The resulting bundle will then be copied into the local project.\n ",examples:[["Build Yarn from master","$0 set version from sources"]]}),(0,a.gn)([C.Command.String("--path",{description:"The path where the repository should be cloned to"})],ve.prototype,"installPath",void 0),(0,a.gn)([C.Command.String("--repository",{description:"The repository that should be cloned"})],ve.prototype,"repository",void 0),(0,a.gn)([C.Command.String("--branch",{description:"The branch of the repository that should be cloned"})],ve.prototype,"branch",void 0),(0,a.gn)([C.Command.Array("--plugin",{description:"An array of additional plugins that should be included in the bundle"})],ve.prototype,"plugins",void 0),(0,a.gn)([C.Command.Boolean("--no-minify",{description:"Build a bundle for development (debugging) - non-minified and non-mangled"})],ve.prototype,"noMinify",void 0),(0,a.gn)([C.Command.Boolean("-f,--force",{description:"Always clone the repository instead of trying to fetch the latest commits"})],ve.prototype,"force",void 0),(0,a.gn)([C.Command.Path("set","version","from","sources")],ve.prototype,"execute",null);var Ne=r(78835);const Fe=require("vm");async function Ke(e){const t=await me.get("https://raw.githubusercontent.com/yarnpkg/berry/master/plugins.yml",{configuration:e});return(0,he.parseSyml)(t.toString())}class Me extends c.BaseCommand{constructor(){super(...arguments),this.json=!1}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins);return(await p.Pk.start({configuration:e,json:this.json,stdout:this.context.stdout},async t=>{const r=await Ke(e);for(const[e,{experimental:A,...n}]of Object.entries(r)){let r=e;A&&(r+=" [experimental]"),t.reportJson({name:e,experimental:A,...n}),t.reportInfo(null,r)}})).exitCode()}}Me.usage=C.Command.Usage({category:"Plugin-related commands",description:"list the available official plugins",details:"\n This command prints the plugins available directly from the Yarn repository. Only those plugins can be referenced by name in `yarn plugin import`.\n ",examples:[["List the official plugins","$0 plugin list"]]}),(0,a.gn)([C.Command.Boolean("--json",{description:"Format the output as an NDJSON stream"})],Me.prototype,"json",void 0),(0,a.gn)([C.Command.Path("plugin","list")],Me.prototype,"execute",null);class Re extends c.BaseCommand{async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins);return(await p.Pk.start({configuration:e,stdout:this.context.stdout},async t=>{const{project:r}=await h.I.find(e,this.context.cwd);let A,n;if(this.name.match(/^\.{0,2}[\\/]/)||m.cS.isAbsolute(this.name)){const o=m.y1.resolve(this.context.cwd,m.cS.toPortablePath(this.name));t.reportInfo(u.b.UNNAMED,"Reading "+B.pretty(e,o,B.Type.PATH)),A=m.y1.relative(r.cwd,o),n=await y.xfs.readFilePromise(o)}else{let r;if(this.name.match(/^https?:/)){try{new Ne.URL(this.name)}catch(e){throw new X.lk(u.b.INVALID_PLUGIN_REFERENCE,`Plugin specifier "${this.name}" is neither a plugin name nor a valid url`)}A=this.name,r=this.name}else{const t=d.parseIdent(this.name.replace(/^((@yarnpkg\/)?plugin-)?/,"@yarnpkg/plugin-")),n=d.stringifyIdent(t),o=await Ke(e);if(!Object.prototype.hasOwnProperty.call(o,n))throw new X.lk(u.b.PLUGIN_NAME_NOT_FOUND,`Couldn't find a plugin named "${n}" on the remote registry. Note that only the plugins referenced on our website (https://github.com/yarnpkg/berry/blob/master/plugins.yml) can be referenced by their name; any other plugin will have to be referenced through its public url (for example https://github.com/yarnpkg/berry/raw/master/packages/plugin-typescript/bin/%40yarnpkg/plugin-typescript.js).`);A=n,r=o[n].url}t.reportInfo(u.b.UNNAMED,"Downloading "+B.pretty(e,r,"green")),n=await me.get(r,{configuration:e})}await xe(A,n,{project:r,report:t})})).exitCode()}}async function xe(e,t,{project:r,report:A}){const{configuration:n}=r,o={},i={exports:o};(0,Fe.runInNewContext)(t.toString(),{module:i,exports:o});const a=i.exports.name,c=`.yarn/plugins/${a}.cjs`,g=m.y1.resolve(r.cwd,c);A.reportInfo(u.b.UNNAMED,"Saving the new plugin in "+B.pretty(n,c,"magenta")),await y.xfs.mkdirPromise(m.y1.dirname(g),{recursive:!0}),await y.xfs.writeFilePromise(g,t);const l={path:c,spec:e};await s.VK.updateConfiguration(r.cwd,e=>{const t=[];let A=!1;for(const n of e.plugins||[]){const e="string"!=typeof n?n.path:n,o=m.y1.resolve(r.cwd,m.cS.toPortablePath(e)),{name:i}=P.dynamicRequire(m.cS.fromPortablePath(o));i!==a?t.push(n):(t.push(l),A=!0)}return A||t.push(l),{...e,plugins:t}})}Re.usage=C.Command.Usage({category:"Plugin-related commands",description:"download a plugin",details:"\n This command downloads the specified plugin from its remote location and updates the configuration to reference it in further CLI invocations.\n\n Three types of plugin references are accepted:\n\n - If the plugin is stored within the Yarn repository, it can be referenced by name.\n - Third-party plugins can be referenced directly through their public urls.\n - Local plugins can be referenced by their path on the disk.\n\n Plugins cannot be downloaded from the npm registry, and aren't allowed to have dependencies (they need to be bundled into a single file, possibly thanks to the `@yarnpkg/builder` package).\n ",examples:[['Download and activate the "@yarnpkg/plugin-exec" plugin',"$0 plugin import @yarnpkg/plugin-exec"],['Download and activate the "@yarnpkg/plugin-exec" plugin (shorthand)',"$0 plugin import exec"],["Download and activate a community plugin","$0 plugin import https://example.org/path/to/plugin.js"],["Activate a local plugin","$0 plugin import ./path/to/plugin.js"]]}),(0,a.gn)([C.Command.String()],Re.prototype,"name",void 0),(0,a.gn)([C.Command.Path("plugin","import")],Re.prototype,"execute",null);class Le extends c.BaseCommand{constructor(){super(...arguments),this.repository="https://github.com/yarnpkg/berry.git",this.branch="master",this.noMinify=!1,this.force=!1}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),t=void 0!==this.installPath?m.y1.resolve(this.context.cwd,m.cS.toPortablePath(this.installPath)):m.y1.resolve(m.cS.toPortablePath((0,Ee.tmpdir)()),"yarnpkg-sources",Ie.makeHash(this.repository).slice(0,6));return(await p.Pk.start({configuration:e,stdout:this.context.stdout},async r=>{const{project:A}=await h.I.find(e,this.context.cwd),n=d.parseIdent(this.name.replace(/^((@yarnpkg\/)?plugin-)?/,"@yarnpkg/plugin-")),o=d.stringifyIdent(n),i=await Ke(e);if(!Object.prototype.hasOwnProperty.call(i,o))throw new X.lk(u.b.PLUGIN_NAME_NOT_FOUND,`Couldn't find a plugin named "${o}" on the remote registry. Note that only the plugins referenced on our website (https://github.com/yarnpkg/berry/blob/master/plugins.yml) can be built and imported from sources.`);const s=o,a=s.replace(/@yarnpkg\//,"");await ke(this,{configuration:e,report:r,target:t}),r.reportSeparator(),r.reportInfo(u.b.UNNAMED,"Building a fresh "+a),r.reportSeparator(),await Se((({pluginName:e,noMinify:t},r)=>[["yarn","build:"+e,...t?["--no-minify"]:[],"|"]])({pluginName:a,noMinify:this.noMinify}),{configuration:e,context:this.context,target:t}),r.reportSeparator();const c=m.y1.resolve(t,`packages/${a}/bundles/${s}.js`),g=await y.xfs.readFilePromise(c);await xe(s,g,{project:A,report:r})})).exitCode()}}Le.usage=C.Command.Usage({category:"Plugin-related commands",description:"build a plugin from sources",details:"\n This command clones the Yarn repository into a temporary folder, builds the specified contrib plugin and updates the configuration to reference it in further CLI invocations.\n\n The plugins can be referenced by their short name if sourced from the official Yarn repository.\n ",examples:[['Build and activate the "@yarnpkg/plugin-exec" plugin',"$0 plugin import from sources @yarnpkg/plugin-exec"],['Build and activate the "@yarnpkg/plugin-exec" plugin (shorthand)',"$0 plugin import from sources exec"]]}),(0,a.gn)([C.Command.String()],Le.prototype,"name",void 0),(0,a.gn)([C.Command.String("--path",{description:"The path where the repository should be cloned to"})],Le.prototype,"installPath",void 0),(0,a.gn)([C.Command.String("--repository",{description:"The repository that should be cloned"})],Le.prototype,"repository",void 0),(0,a.gn)([C.Command.String("--branch",{description:"The branch of the repository that should be cloned"})],Le.prototype,"branch",void 0),(0,a.gn)([C.Command.Boolean("--no-minify",{description:"Build a plugin for development (debugging) - non-minified and non-mangled"})],Le.prototype,"noMinify",void 0),(0,a.gn)([C.Command.Boolean("-f,--force",{description:"Always clone the repository instead of trying to fetch the latest commits"})],Le.prototype,"force",void 0),(0,a.gn)([C.Command.Path("plugin","import","from","sources")],Le.prototype,"execute",null);class Pe extends c.BaseCommand{async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),{project:t}=await h.I.find(e,this.context.cwd);return(await p.Pk.start({configuration:e,stdout:this.context.stdout},async r=>{const A=this.name,n=d.parseIdent(A);if(!e.plugins.has(A))throw new C.UsageError(d.prettyIdent(e,n)+" isn't referenced by the current configuration");const o=`.yarn/plugins/${A}.cjs`,i=m.y1.resolve(t.cwd,o);y.xfs.existsSync(i)&&(r.reportInfo(u.b.UNNAMED,`Removing ${B.pretty(e,o,B.Type.PATH)}...`),await y.xfs.removePromise(i)),r.reportInfo(u.b.UNNAMED,"Updating the configuration..."),await s.VK.updateConfiguration(t.cwd,e=>{if(!Array.isArray(e.plugins))return e;const t=e.plugins.filter(e=>e.path!==o);return e.plugins.length===t.length?e:{...e,plugins:t}})})).exitCode()}}Pe.usage=C.Command.Usage({category:"Plugin-related commands",description:"remove a plugin",details:"\n This command deletes the specified plugin from the .yarn/plugins folder and removes it from the configuration.\n\n **Note:** The plugins have to be referenced by their name property, which can be obtained using the `yarn plugin runtime` command. Shorthands are not allowed.\n ",examples:[["Remove a plugin imported from the Yarn repository","$0 plugin remove @yarnpkg/plugin-typescript"],["Remove a plugin imported from a local file","$0 plugin remove my-local-plugin"]]}),(0,a.gn)([C.Command.String()],Pe.prototype,"name",void 0),(0,a.gn)([C.Command.Path("plugin","remove")],Pe.prototype,"execute",null);class Oe extends c.BaseCommand{constructor(){super(...arguments),this.json=!1}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins);return(await p.Pk.start({configuration:e,json:this.json,stdout:this.context.stdout},async t=>{for(const r of e.plugins.keys()){const e=this.context.plugins.plugins.has(r);let A=r;e&&(A+=" [builtin]"),t.reportJson({name:r,builtin:e}),t.reportInfo(null,""+A)}})).exitCode()}}Oe.usage=C.Command.Usage({category:"Plugin-related commands",description:"list the active plugins",details:"\n This command prints the currently active plugins. Will be displayed both builtin plugins and external plugins.\n ",examples:[["List the currently active plugins","$0 plugin runtime"]]}),(0,a.gn)([C.Command.Boolean("--json",{description:"Format the output as an NDJSON stream"})],Oe.prototype,"json",void 0),(0,a.gn)([C.Command.Path("plugin","runtime")],Oe.prototype,"execute",null);class Ue extends c.BaseCommand{constructor(){super(...arguments),this.idents=[]}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await h.I.find(e,this.context.cwd),A=await g.C.find(e);if(!r)throw new c.WorkspaceRequiredError(t.cwd,this.context.cwd);const n=new Set;for(const e of this.idents)n.add(d.parseIdent(e).identHash);await t.resolveEverything({cache:A,report:new I.$});const o=e.get("bstatePath"),i=y.xfs.existsSync(o)?(0,he.parseSyml)(await y.xfs.readFilePromise(o,"utf8")):{},a=new Map;for(const e of t.storedPackages.values()){if(!Object.prototype.hasOwnProperty.call(i,e.locatorHash))continue;if(0===n.size||n.has(e.identHash))continue;const t=i[e.locatorHash];a.set(e.locatorHash,t)}if(a.size>0){const r=e.get("bstatePath"),A=h.I.generateBuildStateFile(a,t.storedPackages);await y.xfs.mkdirPromise(m.y1.dirname(r),{recursive:!0}),await y.xfs.changeFilePromise(r,A,{automaticNewlines:!0})}else await y.xfs.removePromise(o);return(await p.Pk.start({configuration:e,stdout:this.context.stdout,includeLogs:!this.context.quiet},async e=>{await t.install({cache:A,report:e})})).exitCode()}}Ue.usage=C.Command.Usage({description:"rebuild the project's native packages",details:"\n This command will automatically cause Yarn to forget about previous compilations of the given packages and to run them again.\n\n Note that while Yarn forgets the compilation, the previous artifacts aren't erased from the filesystem and may affect the next builds (in good or bad). To avoid this, you may remove the .yarn/unplugged folder, or any other relevant location where packages might have been stored (Yarn may offer a way to do that automatically in the future).\n\n By default all packages will be rebuilt, but you can filter the list by specifying the names of the packages you want to clear from memory.\n ",examples:[["Rebuild all packages","$0 rebuild"],["Rebuild fsevents only","$0 rebuild fsevents"]]}),(0,a.gn)([C.Command.Rest()],Ue.prototype,"idents",void 0),(0,a.gn)([C.Command.Path("rebuild")],Ue.prototype,"execute",null);class Te extends c.BaseCommand{constructor(){super(...arguments),this.all=!1,this.patterns=[]}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await h.I.find(e,this.context.cwd),A=await g.C.find(e);if(!r)throw new c.WorkspaceRequiredError(t.cwd,this.context.cwd);await t.restoreInstallState({restoreResolutions:!1});const o=this.all?t.workspaces:[r],i=[n.REGULAR,n.DEVELOPMENT,n.PEER],a=[];let l=!1;const u=[];for(const e of this.patterns){let t=!1;const r=d.parseIdent(e);for(const A of o){const n=[...A.manifest.peerDependenciesMeta.keys()];for(const r of Z()(n,e))A.manifest.peerDependenciesMeta.delete(r),l=!0,t=!0;for(const e of i){const n=A.manifest.getForScope(e),o=[...n.values()].map(e=>d.stringifyIdent(e));for(const i of Z()(o,d.stringifyIdent(r))){const{identHash:r}=d.parseIdent(i),o=n.get(r);if(void 0===o)throw new Error("Assertion failed: Expected the descriptor to be registered");A.manifest[e].delete(r),u.push([A,e,o]),l=!0,t=!0}}}t||a.push(e)}const f=a.length>1?"Patterns":"Pattern",I=a.length>1?"don't":"doesn't",E=this.all?"any":"this";if(a.length>0)throw new C.UsageError(`${f} ${B.prettyList(e,a,s.a5.CODE)} ${I} match any packages referenced by ${E} workspace`);if(l){await e.triggerMultipleHooks(e=>e.afterWorkspaceDependencyRemoval,u);return(await p.Pk.start({configuration:e,stdout:this.context.stdout},async e=>{await t.install({cache:A,report:e})})).exitCode()}return 0}}Te.usage=C.Command.Usage({description:"remove dependencies from the project",details:"\n This command will remove the packages matching the specified patterns from the current workspace.\n\n This command accepts glob patterns as arguments (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n ",examples:[["Remove a dependency from the current project","$0 remove lodash"],["Remove a dependency from all workspaces at once","$0 remove lodash --all"],["Remove all dependencies starting with `eslint-`","$0 remove 'eslint-*'"],["Remove all dependencies with the `@babel` scope","$0 remove '@babel/*'"],["Remove all dependencies matching `react-dom` or `react-helmet`","$0 remove 'react-{dom,helmet}'"]]}),(0,a.gn)([C.Command.Boolean("-A,--all",{description:"Apply the operation to all workspaces from the current project"})],Te.prototype,"all",void 0),(0,a.gn)([C.Command.Rest()],Te.prototype,"patterns",void 0),(0,a.gn)([C.Command.Path("remove")],Te.prototype,"execute",null);class je extends c.BaseCommand{async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await h.I.find(e,this.context.cwd);if(!r)throw new c.WorkspaceRequiredError(t.cwd,this.context.cwd);return(await p.Pk.start({configuration:e,stdout:this.context.stdout},async t=>{const A=r.manifest.scripts,n=P.sortMap(A.keys(),e=>e),o={breakLength:1/0,colors:e.get("enableColors"),maxArrayLength:2},i=n.reduce((e,t)=>Math.max(e,t.length),0);for(const[e,r]of A.entries())t.reportInfo(null,`${e.padEnd(i," ")} ${(0,T.inspect)(r,o)}`)})).exitCode()}}(0,a.gn)([C.Command.Path("run")],je.prototype,"execute",null);class Ye extends c.BaseCommand{constructor(){super(...arguments),this.inspect=!1,this.inspectBrk=!1,this.topLevel=!1,this.binariesOnly=!1,this.args=[]}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r,locator:A}=await h.I.find(e,this.context.cwd);await t.restoreInstallState();const n=this.topLevel?t.topLevelWorkspace.anchoredLocator:A;if(!this.binariesOnly&&await R.hasPackageScript(n,this.scriptName,{project:t}))return await R.executePackageScript(n,this.scriptName,this.args,{project:t,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr});if((await R.getPackageAccessibleBinaries(n,{project:t})).get(this.scriptName)){const e=[];return this.inspect&&("string"==typeof this.inspect?e.push("--inspect="+this.inspect):e.push("--inspect")),this.inspectBrk&&("string"==typeof this.inspectBrk?e.push("--inspect-brk="+this.inspectBrk):e.push("--inspect-brk")),await R.executePackageAccessibleBinary(n,this.scriptName,this.args,{cwd:this.context.cwd,project:t,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,nodeArgs:e})}if(!this.topLevel&&!this.binariesOnly&&r&&this.scriptName.includes(":")){const e=(await Promise.all(t.workspaces.map(async e=>e.manifest.scripts.has(this.scriptName)?e:null))).filter(e=>null!==e);if(1===e.length)return await R.executeWorkspaceScript(e[0],this.scriptName,this.args,{stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr})}if(this.topLevel)throw"node-gyp"===this.scriptName?new C.UsageError(`Couldn't find a script name "${this.scriptName}" in the top-level (used by ${d.prettyLocator(e,A)}). This typically happens because some package depends on "node-gyp" to build itself, but didn't list it in their dependencies. To fix that, please run "yarn add node-gyp" into your top-level workspace. You also can open an issue on the repository of the specified package to suggest them to use an optional peer dependency.`):new C.UsageError(`Couldn't find a script name "${this.scriptName}" in the top-level (used by ${d.prettyLocator(e,A)}).`);{if("global"===this.scriptName)throw new C.UsageError("The 'yarn global' commands have been removed in 2.x - consider using 'yarn dlx' or a third-party plugin instead");const e=[this.scriptName].concat(this.args);for(const[t,r]of c.pluginCommands)for(const A of r)if(e.length>=A.length&&JSON.stringify(e.slice(0,A.length))===JSON.stringify(A))throw new C.UsageError(`Couldn't find a script named "${this.scriptName}", but a matching command can be found in the ${t} plugin. You can install it with "yarn plugin import ${t}".`);throw new C.UsageError(`Couldn't find a script named "${this.scriptName}".`)}}}Ye.usage=C.Command.Usage({description:"run a script defined in the package.json",details:"\n This command will run a tool. The exact tool that will be executed will depend on the current state of your workspace:\n\n - If the `scripts` field from your local package.json contains a matching script name, its definition will get executed.\n\n - Otherwise, if one of the local workspace's dependencies exposes a binary with a matching name, this binary will get executed.\n\n - Otherwise, if the specified name contains a colon character and if one of the workspaces in the project contains exactly one script with a matching name, then this script will get executed.\n\n Whatever happens, the cwd of the spawned process will be the workspace that declares the script (which makes it possible to call commands cross-workspaces using the third syntax).\n ",examples:[["Run the tests from the local workspace","$0 run test"],['Same thing, but without the "run" keyword',"$0 test"],["Inspect Webpack while running","$0 run --inspect-brk webpack"]]}),(0,a.gn)([C.Command.String("--inspect",{tolerateBoolean:!0,description:"Forwarded to the underlying Node process when executing a binary"})],Ye.prototype,"inspect",void 0),(0,a.gn)([C.Command.String("--inspect-brk",{tolerateBoolean:!0,description:"Forwarded to the underlying Node process when executing a binary"})],Ye.prototype,"inspectBrk",void 0),(0,a.gn)([C.Command.Boolean("-T,--top-level",{hidden:!0})],Ye.prototype,"topLevel",void 0),(0,a.gn)([C.Command.Boolean("-B,--binaries-only",{hidden:!0})],Ye.prototype,"binariesOnly",void 0),(0,a.gn)([C.Command.Boolean("--silent",{hidden:!0})],Ye.prototype,"silent",void 0),(0,a.gn)([C.Command.String()],Ye.prototype,"scriptName",void 0),(0,a.gn)([C.Command.Proxy()],Ye.prototype,"args",void 0),(0,a.gn)([C.Command.Path("run")],Ye.prototype,"execute",null);class Ge extends c.BaseCommand{constructor(){super(...arguments),this.save=!1}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await h.I.find(e,this.context.cwd),A=await g.C.find(e);if(!r)throw new c.WorkspaceRequiredError(t.cwd,this.context.cwd);const n=d.parseDescriptor(this.descriptor,!0),o=d.makeDescriptor(n,this.resolution);t.storedDescriptors.set(n.descriptorHash,n),t.storedDescriptors.set(o.descriptorHash,o),t.resolutionAliases.set(n.descriptorHash,o.descriptorHash);return(await p.Pk.start({configuration:e,stdout:this.context.stdout},async e=>{await t.install({cache:A,report:e})})).exitCode()}}Ge.usage=C.Command.Usage({description:"enforce a package resolution",details:'\n This command updates the resolution table so that `descriptor` is resolved by `resolution`.\n\n Note that by default this command only affect the current resolution table - meaning that this "manual override" will disappear if you remove the lockfile, or if the package disappear from the table. If you wish to make the enforced resolution persist whatever happens, add the `-s,--save` flag which will also edit the `resolutions` field from your top-level manifest.\n\n Note that no attempt is made at validating that `resolution` is a valid resolution entry for `descriptor`.\n ',examples:[["Force all instances of lodash@npm:^1.2.3 to resolve to 1.5.0","$0 set resolution lodash@npm:^1.2.3 1.5.0"]]}),(0,a.gn)([C.Command.String()],Ge.prototype,"descriptor",void 0),(0,a.gn)([C.Command.String()],Ge.prototype,"resolution",void 0),(0,a.gn)([C.Command.Boolean("-s,--save",{description:"Persist the resolution inside the top-level manifest"})],Ge.prototype,"save",void 0),(0,a.gn)([C.Command.Path("set","resolution")],Ge.prototype,"execute",null);class He extends c.BaseCommand{constructor(){super(...arguments),this.patterns=[],this.interactive=null,this.exact=!1,this.tilde=!1,this.caret=!1}async execute(){var e;const t=await s.VK.find(this.context.cwd,this.context.plugins),{project:r,workspace:A}=await h.I.find(t,this.context.cwd),o=await g.C.find(t);if(!A)throw new c.WorkspaceRequiredError(r.cwd,this.context.cwd);const a=null!==(e=this.interactive)&&void 0!==e?e:t.get("preferInteractive"),I=D(this,r),E=a?[i.KEEP,i.REUSE,i.PROJECT,i.LATEST]:[i.PROJECT,i.LATEST],y=[],m=[];for(const e of this.patterns){let t=!1;const A=d.parseDescriptor(e);for(const e of r.workspaces)for(const i of[n.REGULAR,n.DEVELOPMENT]){const n=[...e.manifest.getForScope(i).values()].map(e=>d.stringifyIdent(e));for(const s of Z()(n,d.stringifyIdent(A))){const n=d.parseIdent(s),a=e.manifest[i].get(n.identHash);if(void 0===a)throw new Error("Assertion failed: Expected the descriptor to be registered");const c=d.makeDescriptor(n,A.range);y.push(Promise.resolve().then(async()=>[e,i,a,await F(c,{project:r,workspace:e,cache:o,target:i,modifier:I,strategies:E})])),t=!0}}t||m.push(e)}if(m.length>1)throw new C.UsageError(`Patterns ${B.prettyList(t,m,s.a5.CODE)} don't match any packages referenced by any workspace`);if(m.length>0)throw new C.UsageError(`Pattern ${B.prettyList(t,m,s.a5.CODE)} doesn't match any packages referenced by any workspace`);const w=await Promise.all(y),Q=await l.h.start({configuration:t,stdout:this.context.stdout,suggestInstall:!1},async e=>{for(const[,,A,{suggestions:n,rejections:o}]of w){const i=n.filter(e=>null!==e.descriptor);if(0===i.length){const[n]=o;if(void 0===n)throw new Error("Assertion failed: Expected an error to have been set");const i=this.cli.error(n);r.configuration.get("enableNetwork")?e.reportError(u.b.CANT_SUGGEST_RESOLUTIONS,`${d.prettyDescriptor(t,A)} can't be resolved to a satisfying range\n\n${i}`):e.reportError(u.b.CANT_SUGGEST_RESOLUTIONS,`${d.prettyDescriptor(t,A)} can't be resolved to a satisfying range (note: network resolution has been disabled)\n\n${i}`)}else i.length>1&&!a&&e.reportError(u.b.CANT_SUGGEST_RESOLUTIONS,d.prettyDescriptor(t,A)+" has multiple possible upgrade strategies; use -i to disambiguate manually")}});if(Q.hasErrors())return Q.exitCode();let b=!1;const v=[];for(const[e,A,,{suggestions:n}]of w){let o;const i=n.filter(e=>null!==e.descriptor),s=i[0].descriptor,a=i.every(e=>d.areDescriptorsEqual(e.descriptor,s));1===i.length||a?o=s:(b=!0,({answer:o}=await(0,f.prompt)({type:"select",name:"answer",message:`Which range to you want to use in ${d.prettyWorkspace(t,e)} ❯ ${A}?`,choices:n.map(({descriptor:e,name:t,reason:r})=>e?{name:t,hint:r,descriptor:e}:{name:t,hint:r,disabled:!0}),onCancel:()=>process.exit(130),result(e){return this.find(e,"descriptor")},stdin:this.context.stdin,stdout:this.context.stdout})));const c=e.manifest[A].get(o.identHash);if(void 0===c)throw new Error("Assertion failed: This descriptor should have a matching entry");if(c.descriptorHash!==o.descriptorHash)e.manifest[A].set(o.identHash,o),v.push([e,A,c,o]);else{const A=t.makeResolver(),n={project:r,resolver:A},o=A.bindDescriptor(c,e.anchoredLocator,n);r.forgetResolution(o)}}await t.triggerMultipleHooks(e=>e.afterWorkspaceDependencyReplacement,v),b&&this.context.stdout.write("\n");return(await p.Pk.start({configuration:t,stdout:this.context.stdout},async e=>{await r.install({cache:o,report:e})})).exitCode()}}He.usage=C.Command.Usage({description:"upgrade dependencies across the project",details:"\n This command upgrades the packages matching the list of specified patterns to their latest available version across the whole project (regardless of whether they're part of `dependencies` or `devDependencies` - `peerDependencies` won't be affected). This is a project-wide command: all workspaces will be upgraded in the process.\n\n If `-i,--interactive` is set (or if the `preferInteractive` settings is toggled on) the command will offer various choices, depending on the detected upgrade paths. Some upgrades require this flag in order to resolve ambiguities.\n\n The, `-C,--caret`, `-E,--exact` and `-T,--tilde` options have the same meaning as in the `add` command (they change the modifier used when the range is missing or a tag, and are ignored when the range is explicitly set).\n\n Generally you can see `yarn up` as a counterpart to what was `yarn upgrade --latest` in Yarn 1 (ie it ignores the ranges previously listed in your manifests), but unlike `yarn upgrade` which only upgraded dependencies in the current workspace, `yarn up` will upgrade all workspaces at the same time.\n\n This command accepts glob patterns as arguments (if valid Descriptors and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n **Note:** The ranges have to be static, only the package scopes and names can contain glob patterns.\n ",examples:[["Upgrade all instances of lodash to the latest release","$0 up lodash"],["Upgrade all instances of lodash to the latest release, but ask confirmation for each","$0 up lodash -i"],["Upgrade all instances of lodash to 1.2.3","$0 up lodash@1.2.3"],["Upgrade all instances of packages with the `@babel` scope to the latest release","$0 up '@babel/*'"],["Upgrade all instances of packages containing the word `jest` to the latest release","$0 up '*jest*'"],["Upgrade all instances of packages with the `@babel` scope to 7.0.0","$0 up '@babel/*@7.0.0'"]]}),(0,a.gn)([C.Command.Rest()],He.prototype,"patterns",void 0),(0,a.gn)([C.Command.Boolean("-i,--interactive",{description:"Offer various choices, depending on the detected upgrade paths"})],He.prototype,"interactive",void 0),(0,a.gn)([C.Command.Boolean("-E,--exact",{description:"Don't use any semver modifier on the resolved range"})],He.prototype,"exact",void 0),(0,a.gn)([C.Command.Boolean("-T,--tilde",{description:"Use the `~` semver modifier on the resolved range"})],He.prototype,"tilde",void 0),(0,a.gn)([C.Command.Boolean("-C,--caret",{description:"Use the `^` semver modifier on the resolved range"})],He.prototype,"caret",void 0),(0,a.gn)([C.Command.Path("up")],He.prototype,"execute",null);class Je extends c.BaseCommand{constructor(){super(...arguments),this.recursive=!1,this.json=!1,this.peers=!1}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await h.I.find(e,this.context.cwd);if(!r)throw new c.WorkspaceRequiredError(t.cwd,this.context.cwd);await t.restoreInstallState();const A=d.parseIdent(this.package).identHash,n=this.recursive?function(e,t,{configuration:r,peers:A}){const n=P.sortMap(e.workspaces,e=>d.stringifyLocator(e.anchoredLocator)),o=new Set,i=new Set,s=r=>{if(o.has(r.locatorHash))return i.has(r.locatorHash);if(o.add(r.locatorHash),r.identHash===t)return i.add(r.locatorHash),!0;let n=!1;r.identHash===t&&(n=!0);for(const t of r.dependencies.values()){if(!A&&r.peerDependencies.has(t.identHash))continue;const o=e.storedResolutions.get(t.descriptorHash);if(!o)throw new Error("Assertion failed: The resolution should have been registered");const i=e.storedPackages.get(o);if(!i)throw new Error("Assertion failed: The package should have been registered");s(i)&&(n=!0)}return n&&i.add(r.locatorHash),n};for(const t of n){const r=e.storedPackages.get(t.anchoredLocator.locatorHash);if(!r)throw new Error("Assertion failed: The package should have been registered");s(r)}const a=new Set,c={},g={children:c},l=(t,r,n)=>{if(!i.has(t.locatorHash))return;const o={},s={value:null!==n?B.tuple(B.Type.DEPENDENT,{locator:t,descriptor:n}):B.tuple(B.Type.LOCATOR,t),children:o};if(r[d.stringifyLocator(t)]=s,!a.has(t.locatorHash)&&(a.add(t.locatorHash),null===n||!e.tryWorkspaceByLocator(t)))for(const r of t.dependencies.values()){if(!A&&t.peerDependencies.has(r.identHash))continue;const n=e.storedResolutions.get(r.descriptorHash);if(!n)throw new Error("Assertion failed: The resolution should have been registered");const i=e.storedPackages.get(n);if(!i)throw new Error("Assertion failed: The package should have been registered");l(i,o,r)}};for(const t of n){const r=e.storedPackages.get(t.anchoredLocator.locatorHash);if(!r)throw new Error("Assertion failed: The package should have been registered");l(r,c,null)}return g}(t,A,{configuration:e,peers:this.peers}):function(e,t,{configuration:r,peers:A}){const n=P.sortMap(e.storedPackages.values(),e=>d.stringifyLocator(e)),o={},i={children:o};for(const r of n){const n={},i=null;for(const s of r.dependencies.values()){if(!A&&r.peerDependencies.has(s.identHash))continue;const a=e.storedResolutions.get(s.descriptorHash);if(!a)throw new Error("Assertion failed: The resolution should have been registered");const c=e.storedPackages.get(a);if(!c)throw new Error("Assertion failed: The package should have been registered");if(c.identHash!==t)continue;if(null===i){const e=d.stringifyLocator(r);o[e]={value:[r,B.Type.LOCATOR],children:n}}const g=d.stringifyLocator(c);n[g]={value:[{descriptor:s,locator:c},B.Type.DEPENDENT]}}}return i}(t,A,{configuration:e,peers:this.peers});le.emitTree(n,{configuration:e,stdout:this.context.stdout,json:this.json,separators:1})}}Je.usage=C.Command.Usage({description:"display the reason why a package is needed",details:'\n This command prints the exact reasons why a package appears in the dependency tree.\n\n If `-R,--recursive` is set, the listing will go in depth and will list, for each workspaces, what are all the paths that lead to the dependency. Note that the display is somewhat optimized in that it will not print the package listing twice for a single package, so if you see a leaf named "Foo" when looking for "Bar", it means that "Foo" already got printed higher in the tree.\n ',examples:[["Explain why lodash is used in your project","$0 why lodash"]]}),(0,a.gn)([C.Command.String()],Je.prototype,"package",void 0),(0,a.gn)([C.Command.Boolean("-R,--recursive",{description:"List, for each workspace, what are all the paths that lead to the dependency"})],Je.prototype,"recursive",void 0),(0,a.gn)([C.Command.Boolean("--json",{description:"Format the output as an NDJSON stream"})],Je.prototype,"json",void 0),(0,a.gn)([C.Command.Boolean("--peers",{description:"Also print the peer dependencies that match the specified name"})],Je.prototype,"peers",void 0),(0,a.gn)([C.Command.Path("why")],Je.prototype,"execute",null);class qe extends c.BaseCommand{constructor(){super(...arguments),this.verbose=!1,this.json=!1}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),{project:t}=await h.I.find(e,this.context.cwd);return(await p.Pk.start({configuration:e,json:this.json,stdout:this.context.stdout},async e=>{for(const r of t.workspaces){const{manifest:A}=r;let n;if(this.verbose){const e=new Set,r=new Set;for(const n of E.G.hardDependencies)for(const[o,i]of A.getForScope(n)){const A=t.tryWorkspaceByDescriptor(i);null===A?t.workspacesByIdent.has(o)&&r.add(i):e.add(A)}n={workspaceDependencies:Array.from(e).map(e=>e.relativeCwd),mismatchedWorkspaceDependencies:Array.from(r).map(e=>d.stringifyDescriptor(e))}}e.reportInfo(null,""+r.relativeCwd),e.reportJson({location:r.relativeCwd,name:A.name?d.stringifyIdent(A.name):null,...n})}})).exitCode()}}qe.usage=C.Command.Usage({category:"Workspace-related commands",description:"list all available workspaces",details:"\n This command will print the list of all workspaces in the project. If both the `-v,--verbose` and `--json` options are set, Yarn will also return the cross-dependencies between each workspaces (useful when you wish to automatically generate Buck / Bazel rules).\n "}),(0,a.gn)([C.Command.Boolean("-v,--verbose",{description:"Also return the cross-dependencies between workspaces"})],qe.prototype,"verbose",void 0),(0,a.gn)([C.Command.Boolean("--json",{description:"Format the output as an NDJSON stream"})],qe.prototype,"json",void 0),(0,a.gn)([C.Command.Path("workspaces","list")],qe.prototype,"execute",null);class ze extends C.Command{constructor(){super(...arguments),this.args=[]}async execute(){const e=await s.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await h.I.find(e,this.context.cwd);if(!r)throw new c.WorkspaceRequiredError(t.cwd,this.context.cwd);const A=t.workspaces,n=new Map(A.map(e=>{const t=d.convertToIdent(e.locator);return[d.stringifyIdent(t),e]})),o=n.get(this.workspaceName);if(void 0===o){const e=Array.from(n.keys()).sort();throw new C.UsageError(`Workspace '${this.workspaceName}' not found. Did you mean any of the following:\n - ${e.join("\n - ")}?`)}return this.cli.run([this.commandName,...this.args],{cwd:o.cwd})}}ze.usage=C.Command.Usage({category:"Workspace-related commands",description:"run a command within the specified workspace",details:"\n This command will run a given sub-command on a single workspace.\n ",examples:[["Add a package to a single workspace","yarn workspace components add -D react"],["Run build script on a single workspace","yarn workspace components run build"]]}),(0,a.gn)([C.Command.String()],ze.prototype,"workspaceName",void 0),(0,a.gn)([C.Command.String()],ze.prototype,"commandName",void 0),(0,a.gn)([C.Command.Proxy()],ze.prototype,"args",void 0),(0,a.gn)([C.Command.Path("workspace")],ze.prototype,"execute",null);const We={configuration:{enableImmutableInstalls:{description:"If true, prevents the install command from modifying the lockfile",type:s.a2.BOOLEAN,default:!1},defaultSemverRangePrefix:{description:"The default save prefix: '^', '~' or ''",type:s.a2.STRING,values:["^","~",""],default:o.CARET}},commands:[L,j,q,Ge,ve,we,qe,re,Ae,ne,ie,M,x,z,te,ae,ge,ue,de,Ce,fe,Le,Re,Pe,Me,Oe,Ue,Te,je,Ye,He,Je,ze]}},68023:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>E,fileUtils:()=>A});var A={};r.r(A),r.d(A,{makeArchiveFromLocator:()=>p,makeBufferFromLocator:()=>d,makeLocator:()=>h,makeSpec:()=>u,parseSpec:()=>l});var n=r(54143),o=r(46009);const i=/^(?:[a-zA-Z]:[\\/]|\.{0,2}\/)/,s=/^[^?]*\.(?:tar\.gz|tgz)(?:::.*)?$/;var a=r(73632),c=r(72785),g=r(75448);function l(e){const{params:t,selector:r}=n.parseRange(e),A=o.cS.toPortablePath(r);return{parentLocator:t&&"string"==typeof t.locator?n.parseLocator(t.locator):null,path:A}}function u({parentLocator:e,path:t,folderHash:r,protocol:A}){const o=null!==e?{locator:n.stringifyLocator(e)}:{},i=void 0!==r?{hash:r}:{};return n.makeRange({protocol:A,source:t,selector:t,params:{...i,...o}})}function h(e,{parentLocator:t,path:r,folderHash:A,protocol:o}){return n.makeLocator(e,u({parentLocator:t,path:r,folderHash:A,protocol:o}))}async function p(e,{protocol:t,fetchOptions:r,inMemory:A=!1}){const{parentLocator:i,path:s}=n.parseFileStyleRange(e.reference,{protocol:t}),l=o.y1.isAbsolute(s)?{packageFs:new g.M(o.LZ.root),prefixPath:o.LZ.dot,localPath:o.LZ.root}:await r.fetcher.fetch(i,r),u=l.localPath?{packageFs:new g.M(o.LZ.root),prefixPath:o.y1.relative(o.LZ.root,l.localPath)}:l;l!==u&&l.releaseFs&&l.releaseFs();const h=u.packageFs,p=o.y1.join(u.prefixPath,s);return await a.releaseAfterUseAsync(async()=>await c.makeArchiveFromDirectory(p,{baseFs:h,prefixPath:n.getIdentVendorPath(e),compressionLevel:r.project.configuration.get("compressionLevel"),inMemory:A}),u.releaseFs)}async function d(e,{protocol:t,fetchOptions:r}){return(await p(e,{protocol:t,fetchOptions:r,inMemory:!0})).getBufferAndClose()}var C=r(20624),f=r(32485),I=r(46611);const E={fetchers:[class{supports(e,t){return!!s.test(e.reference)&&!!e.reference.startsWith("file:")}getLocalPath(e,t){return null}async fetch(e,t){const r=t.checksums.get(e.locatorHash)||null,[A,o,i]=await t.cache.fetchPackageFromCache(e,r,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,n.prettyLocator(t.project.configuration,e)+" can't be found in the cache and will be fetched from the disk"),loader:()=>this.fetchFromDisk(e,t),skipIntegrityCheck:t.skipIntegrityCheck});return{packageFs:A,releaseFs:o,prefixPath:n.getIdentVendorPath(e),checksum:i}}async fetchFromDisk(e,t){const{parentLocator:r,path:A}=n.parseFileStyleRange(e.reference,{protocol:"file:"}),i=o.y1.isAbsolute(A)?{packageFs:new g.M(o.LZ.root),prefixPath:o.LZ.dot,localPath:o.LZ.root}:await t.fetcher.fetch(r,t),s=i.localPath?{packageFs:new g.M(o.LZ.root),prefixPath:o.y1.relative(o.LZ.root,i.localPath)}:i;i!==s&&i.releaseFs&&i.releaseFs();const l=s.packageFs,u=o.y1.join(s.prefixPath,A),h=await l.readFilePromise(u);return await a.releaseAfterUseAsync(async()=>await c.convertToZip(h,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:n.getIdentVendorPath(e),stripComponents:1}),s.releaseFs)}},class{supports(e,t){return!!e.reference.startsWith("file:")}getLocalPath(e,t){const{parentLocator:r,path:A}=n.parseFileStyleRange(e.reference,{protocol:"file:"});if(o.y1.isAbsolute(A))return A;const i=t.fetcher.getLocalPath(r,t);return null===i?null:o.y1.resolve(i,A)}async fetch(e,t){const r=t.checksums.get(e.locatorHash)||null,[A,o,i]=await t.cache.fetchPackageFromCache(e,r,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,n.prettyLocator(t.project.configuration,e)+" can't be found in the cache and will be fetched from the disk"),loader:()=>this.fetchFromDisk(e,t),skipIntegrityCheck:t.skipIntegrityCheck});return{packageFs:A,releaseFs:o,prefixPath:n.getIdentVendorPath(e),localPath:this.getLocalPath(e,t),checksum:i}}async fetchFromDisk(e,t){return p(e,{protocol:"file:",fetchOptions:t})}}],resolvers:[class{supportsDescriptor(e,t){return!!s.test(e.range)&&(!!e.range.startsWith("file:")||!!i.test(e.range))}supportsLocator(e,t){return!!s.test(e.reference)&&!!e.reference.startsWith("file:")}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,r){return i.test(e.range)&&(e=n.makeDescriptor(e,"file:"+e.range)),n.bindDescriptor(e,{locator:n.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,r){let A=e.range;return A.startsWith("file:")&&(A=A.slice("file:".length)),[n.makeLocator(e,"file:"+o.cS.toPortablePath(A))]}async getSatisfying(e,t,r){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");const r=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),A=await a.releaseAfterUseAsync(async()=>await I.G.find(r.prefixPath,{baseFs:r.packageFs}),r.releaseFs);return{...e,version:A.version||"0.0.0",languageName:t.project.configuration.get("defaultLanguageName"),linkType:f.Un.HARD,dependencies:A.dependencies,peerDependencies:A.peerDependencies,dependenciesMeta:A.dependenciesMeta,peerDependenciesMeta:A.peerDependenciesMeta,bin:A.bin}}},class{supportsDescriptor(e,t){return!!e.range.match(i)||!!e.range.startsWith("file:")}supportsLocator(e,t){return!!e.reference.startsWith("file:")}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,r){return i.test(e.range)&&(e=n.makeDescriptor(e,"file:"+e.range)),n.bindDescriptor(e,{locator:n.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");const{path:A,parentLocator:o}=l(e.range);if(null===o)throw new Error("Assertion failed: The descriptor should have been bound");const i=await d(n.makeLocator(e,n.makeRange({protocol:"file:",source:A,selector:A,params:{locator:n.stringifyLocator(o)}})),{protocol:"file:",fetchOptions:r.fetchOptions});return[h(e,{parentLocator:o,path:A,folderHash:C.makeHash("1",i).slice(0,6),protocol:"file:"})]}async getSatisfying(e,t,r){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");const r=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),A=await a.releaseAfterUseAsync(async()=>await I.G.find(r.prefixPath,{baseFs:r.packageFs}),r.releaseFs);return{...e,version:A.version||"0.0.0",languageName:t.project.configuration.get("defaultLanguageName"),linkType:f.Un.HARD,dependencies:A.dependencies,peerDependencies:A.peerDependencies,dependenciesMeta:A.dependenciesMeta,peerDependenciesMeta:A.peerDependenciesMeta,bin:A.bin}}}]}},75641:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>F,gitUtils:()=>A});var A={};r.r(A),r.d(A,{TreeishProtocols:()=>y,clone:()=>S,isGitUrl:()=>m,lsRemote:()=>b,normalizeLocator:()=>D,normalizeRepoUrl:()=>Q,resolveUrl:()=>v,splitRepoUrl:()=>w});var n=r(39922),o=r(54143),i=r(63088),s=r(73632),a=r(72785),c=r(43896),g=r(46009),l=r(79669),u=r(6220),h=r(71191),p=r.n(h),d=r(53887),C=r.n(d),f=r(78835),I=r.n(f);function E(){return{...process.env,GIT_SSH_COMMAND:"ssh -o BatchMode=yes"}}const B=[/^ssh:/,/^git(?:\+[^:]+)?:/,/^(?:git\+)?https?:[^#]+\/[^#]+(?:\.git)(?:#.*)?$/,/^git@[^#]+\/[^#]+\.git(?:#.*)?$/,/^(?:github:|https:\/\/github\.com\/)?(?!\.{1,2}\/)([a-zA-Z._0-9-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z._0-9-]+?)(?:\.git)?(?:#.*)?$/,/^https:\/\/github\.com\/(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)\/tarball\/(.+)?$/];var y;function m(e){return!!e&&B.some(t=>!!e.match(t))}function w(e){const t=(e=Q(e)).indexOf("#");if(-1===t)return{repo:e,treeish:{protocol:y.Head,request:"master"},extra:{}};const r=e.slice(0,t),A=e.slice(t+1);if(A.match(/^[a-z]+=/)){const e=p().parse(A);for(const[t,r]of Object.entries(e))if("string"!=typeof r)throw new Error(`Assertion failed: The ${t} parameter must be a literal string`);const t=Object.values(y).find(t=>Object.prototype.hasOwnProperty.call(e,t));let n,o;void 0!==t?(n=t,o=e[t]):(n=y.Head,o="master");for(const t of Object.values(y))delete e[t];return{repo:r,treeish:{protocol:n,request:o},extra:e}}{const e=A.indexOf(":");let t,n;return-1===e?(t=null,n=A):(t=A.slice(0,e),n=A.slice(e+1)),{repo:r,treeish:{protocol:t,request:n},extra:{}}}}function Q(e,{git:t=!1}={}){var r;if(e=(e=(e=e.replace(/^git\+https:/,"https:")).replace(/^(?:github:|https:\/\/github\.com\/)?(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)(?:\.git)?(#.*)?$/,"https://github.com/$1/$2.git$3")).replace(/^https:\/\/github\.com\/(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)\/tarball\/(.+)?$/,"https://github.com/$1/$2.git#$3"),t){let t;e=e.replace(/^git\+([^:]+):/,"$1:");try{t=I().parse(e)}catch(e){t=null}t&&"ssh:"===t.protocol&&(null===(r=t.path)||void 0===r?void 0:r.startsWith("/:"))&&(e=e.replace(/^ssh:\/\//,""))}return e}function D(e){return o.makeLocator(e,Q(e.reference))}async function b(e,t){const r=Q(e,{git:!0});if(!l.getNetworkSettings(r,{configuration:t}).enableNetwork)throw new Error(`Request to '${r}' has been blocked because of your configuration settings`);let A;try{A=await u.execvp("git",["ls-remote","--refs",r],{cwd:t.startingCwd,env:E(),strict:!0})}catch(t){throw t.message=`Listing the refs for ${e} failed`,t}const n=new Map,o=/^([a-f0-9]{40})\t(refs\/[^\n]+)/gm;let i;for(;null!==(i=o.exec(A.stdout));)n.set(i[2],i[1]);return n}async function v(e,t){const{repo:r,treeish:{protocol:A,request:n},extra:o}=w(e),i=await b(r,t),s=(e,t)=>{switch(e){case y.Commit:if(!t.match(/^[a-f0-9]{40}$/))throw new Error("Invalid commit hash");return p().stringify({...o,commit:t});case y.Head:{const e=i.get("refs/heads/"+t);if(void 0===e)throw new Error(`Unknown head ("${t}")`);return p().stringify({...o,commit:e})}case y.Tag:{const e=i.get("refs/tags/"+t);if(void 0===e)throw new Error(`Unknown tag ("${t}")`);return p().stringify({...o,commit:e})}case y.Semver:{if(!C().validRange(t))throw new Error(`Invalid range ("${t}")`);const e=new Map([...i.entries()].filter(([e])=>e.startsWith("refs/tags/")).map(([e,t])=>[C().parse(e.slice(10)),t]).filter(e=>null!==e[0])),r=C().maxSatisfying([...e.keys()],t);if(null===r)throw new Error(`No matching range ("${t}")`);return p().stringify({...o,commit:e.get(r)})}case null:{let e;if(null!==(e=a(y.Commit,t)))return e;if(null!==(e=a(y.Tag,t)))return e;if(null!==(e=a(y.Head,t)))return e;throw t.match(/^[a-f0-9]+$/)?new Error(`Couldn't resolve "${t}" as either a commit, a tag, or a head - if a commit, use the 40-characters commit hash`):new Error(`Couldn't resolve "${t}" as either a commit, a tag, or a head`)}default:throw new Error(`Invalid Git resolution protocol ("${e}")`)}},a=(e,t)=>{try{return s(e,t)}catch(e){return null}};return`${r}#${s(A,n)}`}async function S(e,t){return await t.getLimit("cloneConcurrency")(async()=>{const{repo:r,treeish:{protocol:A,request:n}}=w(e);if("commit"!==A)throw new Error("Invalid treeish protocol when cloning");const o=Q(r,{git:!0});if(!1===l.getNetworkSettings(o,{configuration:t}).enableNetwork)throw new Error(`Request to '${o}' has been blocked because of your configuration settings`);const i=await c.xfs.mktempPromise(),s={cwd:i,env:E(),strict:!0};try{await u.execvp("git",["clone","-c core.autocrlf=false",o,g.cS.fromPortablePath(i)],s),await u.execvp("git",["checkout",""+n],s)}catch(e){throw e.message="Repository clone failed: "+e.message,e}return i})}!function(e){e.Commit="commit",e.Head="head",e.Tag="tag",e.Semver="semver"}(y||(y={}));var k=r(32485),N=r(46611);const F={configuration:{cloneConcurrency:{description:"Maximal number of concurrent clones",type:n.a2.NUMBER,default:2}},fetchers:[class{supports(e,t){return m(e.reference)}getLocalPath(e,t){return null}async fetch(e,t){const r=t.checksums.get(e.locatorHash)||null,A=D(e),n=new Map(t.checksums);n.set(A.locatorHash,r);const i={...t,checksums:n},s=await this.downloadHosted(A,i);if(null!==s)return s;const[a,c,g]=await t.cache.fetchPackageFromCache(e,r,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,o.prettyLocator(t.project.configuration,e)+" can't be found in the cache and will be fetched from the remote repository"),loader:()=>this.cloneFromRemote(A,i),skipIntegrityCheck:t.skipIntegrityCheck});return{packageFs:a,releaseFs:c,prefixPath:o.getIdentVendorPath(e),checksum:g}}async downloadHosted(e,t){return t.project.configuration.reduceHook(e=>e.fetchHostedRepository,null,e,t)}async cloneFromRemote(e,t){const r=await S(e.reference,t.project.configuration),A=w(e.reference),n=g.y1.join(r,"package.tgz");await i.prepareExternalProject(r,n,{configuration:t.project.configuration,report:t.report,workspace:A.extra.workspace});const l=await c.xfs.readFilePromise(n);return await s.releaseAfterUseAsync(async()=>await a.convertToZip(l,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:o.getIdentVendorPath(e),stripComponents:1}))}}],resolvers:[class{supportsDescriptor(e,t){return m(e.range)}supportsLocator(e,t){return m(e.reference)}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,r){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,r){const A=await v(e.range,r.project.configuration);return[o.makeLocator(e,A)]}async getSatisfying(e,t,r){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");const r=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),A=await s.releaseAfterUseAsync(async()=>await N.G.find(r.prefixPath,{baseFs:r.packageFs}),r.releaseFs);return{...e,version:A.version||"0.0.0",languageName:t.project.configuration.get("defaultLanguageName"),linkType:k.Un.HARD,dependencies:A.dependencies,peerDependencies:A.peerDependencies,dependenciesMeta:A.dependenciesMeta,peerDependenciesMeta:A.peerDependenciesMeta,bin:A.bin}}}]}},68126:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>d});var A=r(54143),n=r(79669),o=r(72785),i=r(63088),s=r(43896),a=r(75448),c=r(46009),g=r(75641),l=r(71191),u=r.n(l);const h=[/^https?:\/\/(?:([^/]+?)@)?github.com\/([^/#]+)\/([^/#]+)\/tarball\/([^/#]+)(?:#(.*))?$/,/^https?:\/\/(?:([^/]+?)@)?github.com\/([^/#]+)\/([^/#]+?)(?:\.git)?(?:#(.*))?$/];class p{supports(e,t){return!(!(r=e.reference)||!h.some(e=>!!r.match(e)));var r}getLocalPath(e,t){return null}async fetch(e,t){const r=t.checksums.get(e.locatorHash)||null,[n,o,i]=await t.cache.fetchPackageFromCache(e,r,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,A.prettyLocator(t.project.configuration,e)+" can't be found in the cache and will be fetched from GitHub"),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck});return{packageFs:n,releaseFs:o,prefixPath:A.getIdentVendorPath(e),checksum:i}}async fetchFromNetwork(e,t){const r=await n.get(this.getLocatorUrl(e,t),{configuration:t.project.configuration});return await s.xfs.mktempPromise(async n=>{const l=new a.M(n);await o.extractArchiveTo(r,l,{stripComponents:1});const u=g.gitUtils.splitRepoUrl(e.reference),h=c.y1.join(n,"package.tgz");await i.prepareExternalProject(n,h,{configuration:t.project.configuration,report:t.report,workspace:u.extra.workspace});const p=await s.xfs.readFilePromise(h);return await o.convertToZip(p,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:A.getIdentVendorPath(e),stripComponents:1})})}getLocatorUrl(e,t){const{auth:r,username:A,reponame:n,treeish:o}=function(e){let t;for(const r of h)if(t=e.match(r),t)break;if(!t)throw new Error(`Input cannot be parsed as a valid GitHub URL ('${e}').`);let[,r,A,n,o="master"]=t;const{commit:i}=u().parse(o);return o=i||o.replace(/[^:]*:/,""),{auth:r,username:A,reponame:n,treeish:o}}(e.reference);return`https://${r?r+"@":""}github.com/${A}/${n}/archive/${o}.tar.gz`}}const d={hooks:{async fetchHostedRepository(e,t,r){if(null!==e)return e;const A=new p;if(!A.supports(t,r))return null;try{return await A.fetch(t,r)}catch(e){return null}}}}},99148:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>l});var A=r(54143),n=r(79669),o=r(72785);const i=/^[^?]*\.(?:tar\.gz|tgz)(?:\?.*)?$/,s=/^https?:/;var a=r(46611),c=r(32485),g=r(73632);const l={fetchers:[class{supports(e,t){return!!i.test(e.reference)&&!!s.test(e.reference)}getLocalPath(e,t){return null}async fetch(e,t){const r=t.checksums.get(e.locatorHash)||null,[n,o,i]=await t.cache.fetchPackageFromCache(e,r,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,A.prettyLocator(t.project.configuration,e)+" can't be found in the cache and will be fetched from the remote server"),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck});return{packageFs:n,releaseFs:o,prefixPath:A.getIdentVendorPath(e),checksum:i}}async fetchFromNetwork(e,t){const r=await n.get(e.reference,{configuration:t.project.configuration});return await o.convertToZip(r,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:A.getIdentVendorPath(e),stripComponents:1})}}],resolvers:[class{supportsDescriptor(e,t){return!!i.test(e.range)&&!!s.test(e.range)}supportsLocator(e,t){return!!i.test(e.reference)&&!!s.test(e.reference)}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,r){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,r){return[A.convertDescriptorToLocator(e)]}async getSatisfying(e,t,r){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");const r=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),A=await g.releaseAfterUseAsync(async()=>await a.G.find(r.prefixPath,{baseFs:r.packageFs}),r.releaseFs);return{...e,version:A.version||"0.0.0",languageName:t.project.configuration.get("defaultLanguageName"),linkType:c.Un.HARD,dependencies:A.dependencies,peerDependencies:A.peerDependencies,dependenciesMeta:A.dependenciesMeta,peerDependenciesMeta:A.peerDependenciesMeta,bin:A.bin}}}]}},64314:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>I});var A=r(39922),n=r(36370),o=r(25413),i=r(46611),s=r(85824),a=r(6220),c=r(63088),g=r(54143),l=r(43896),u=r(46009),h=r(40822),p=r(80305),d=r.n(p),C=r(31669);class f extends o.BaseCommand{constructor(){super(...arguments),this.usev2=!1,this.assumeFreshProject=!1,this.yes=!1,this.private=!1,this.workspace=!1,this.install=!1}async execute(){if(l.xfs.existsSync(u.y1.join(this.context.cwd,i.G.fileName)))throw new h.UsageError("A package.json already exists in the specified directory");const e=await A.VK.find(this.context.cwd,this.context.plugins),t=this.install?!0===this.install?"latest":this.install:null;return null!==t?await this.executeProxy(e,t):await this.executeRegular(e)}async executeProxy(e,t){if(null!==e.get("yarnPath"))throw new h.UsageError(`Cannot use the --install flag when the current directory already uses yarnPath (from ${e.sources.get("yarnPath")})`);if(null!==e.projectCwd)throw new h.UsageError("Cannot use the --install flag when the current directory is already part of a project");l.xfs.existsSync(this.context.cwd)||await l.xfs.mkdirPromise(this.context.cwd,{recursive:!0});const r=u.y1.join(this.context.cwd,e.get("lockfileFilename"));l.xfs.existsSync(r)||await l.xfs.writeFilePromise(r,"");const A=await this.cli.run(["set","version",t]);if(0!==A)return A;this.context.stdout.write("\n");const n=["--assume-fresh-project"];return this.private&&n.push("-p"),this.workspace&&n.push("-w"),this.yes&&n.push("-y"),await l.xfs.mktempPromise(async e=>{const{code:t}=await a.pipevp("yarn",["init",...n],{cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,env:await c.makeScriptEnv({binFolder:e})});return t})}async executeRegular(e){let t=null;if(!this.assumeFreshProject)try{t=await s.I.find(e,this.context.cwd)}catch(e){t=null}l.xfs.existsSync(this.context.cwd)||await l.xfs.mkdirPromise(this.context.cwd,{recursive:!0});const r=new i.G,A=Object.fromEntries(e.get("initFields").entries());r.load(A),r.name=g.makeIdent(e.get("initScope"),u.y1.basename(this.context.cwd)),r.version=e.get("initVersion"),r.private=this.private||this.workspace,r.license=e.get("initLicense"),this.workspace&&(await l.xfs.mkdirPromise(u.y1.join(this.context.cwd,"packages"),{recursive:!0}),r.workspaceDefinitions=[{pattern:"packages/*"}]);const n={};r.exportTo(n),C.inspect.styles.name="cyan",this.context.stdout.write((0,C.inspect)(n,{depth:1/0,colors:!0,compact:!1})+"\n");const o=u.y1.join(this.context.cwd,i.G.fileName);await l.xfs.changeFilePromise(o,JSON.stringify(n,null,2)+"\n");const c=u.y1.join(this.context.cwd,"README.md");if(l.xfs.existsSync(c)||await l.xfs.writeFilePromise(c,`# ${g.stringifyIdent(r.name)}\n`),!t){const t=u.y1.join(this.context.cwd,u.QS.lockfile);await l.xfs.writeFilePromise(t,"");const r=["/.yarn/** linguist-vendored"].map(e=>e+"\n").join(""),A=u.y1.join(this.context.cwd,".gitattributes");l.xfs.existsSync(A)||await l.xfs.writeFilePromise(A,r);const n=["/.yarn/*","!/.yarn/releases","!/.yarn/plugins","!/.yarn/sdks","","# Swap the comments on the following lines if you don't wish to use zero-installs","# Documentation here: https://yarnpkg.com/features/zero-installs","!/.yarn/cache","#/.pnp.*"].map(e=>e+"\n").join(""),o=u.y1.join(this.context.cwd,".gitignore");l.xfs.existsSync(o)||await l.xfs.writeFilePromise(o,n);const i={"*":{endOfLine:"lf",insertFinalNewline:!0},"*.{js,json,.yml}":{charset:"utf-8",indentStyle:"space",indentSize:2}};d()(i,e.get("initEditorConfig"));let s="root = true\n";for(const[e,t]of Object.entries(i)){s+=`\n[${e}]\n`;for(const[e,r]of Object.entries(t)){s+=`${e.replace(/[A-Z]/g,e=>"_"+e.toLowerCase())} = ${r}\n`}}const c=u.y1.join(this.context.cwd,".editorconfig");l.xfs.existsSync(c)||await l.xfs.writeFilePromise(c,s),await a.execvp("git",["init"],{cwd:this.context.cwd})}}}f.usage=h.Command.Usage({description:"create a new package",details:"\n This command will setup a new package in your local directory.\n\n If the `-p,--private` or `-w,--workspace` options are set, the package will be private by default.\n\n If the `-w,--workspace` option is set, the package will be configured to accept a set of workspaces in the `packages/` directory.\n\n If the `-i,--install` option is given a value, Yarn will first download it using `yarn set version` and only then forward the init call to the newly downloaded bundle. Without arguments, the downloaded bundle will be `latest`.\n\n The initial settings of the manifest can be changed by using the `initScope` and `initFields` configuration values. Additionally, Yarn will generate an EditorConfig file whose rules can be altered via `initEditorConfig`, and will initialize a Git repository in the current directory.\n ",examples:[["Create a new package in the local directory","yarn init"],["Create a new private package in the local directory","yarn init -p"],["Create a new package and store the Yarn release inside","yarn init -i latest"],["Create a new private package and defines it as a workspace root","yarn init -w"]]}),(0,n.gn)([h.Command.Boolean("-2",{hidden:!0})],f.prototype,"usev2",void 0),(0,n.gn)([h.Command.Boolean("--assume-fresh-project",{hidden:!0})],f.prototype,"assumeFreshProject",void 0),(0,n.gn)([h.Command.Boolean("-y,--yes",{hidden:!0})],f.prototype,"yes",void 0),(0,n.gn)([h.Command.Boolean("-p,--private",{description:"Initialize a private package"})],f.prototype,"private",void 0),(0,n.gn)([h.Command.Boolean("-w,--workspace",{description:"Initialize a private workspace root with a `packages/` directory"})],f.prototype,"workspace",void 0),(0,n.gn)([h.Command.String("-i,--install",{tolerateBoolean:!0,description:"Initialize a package with a specific bundle that will be locked in the project"})],f.prototype,"install",void 0),(0,n.gn)([h.Command.Path("init")],f.prototype,"execute",null);const I={configuration:{initLicense:{description:"License used when creating packages via the init command",type:A.a2.STRING,default:null},initScope:{description:"Scope used when creating packages via the init command",type:A.a2.STRING,default:null},initVersion:{description:"Version used when creating packages via the init command",type:A.a2.STRING,default:null},initFields:{description:"Additional fields to set when creating packages via the init command",type:A.a2.MAP,valueDefinition:{description:"",type:A.a2.ANY}},initEditorConfig:{description:"Extra rules to define in the generator editorconfig",type:A.a2.MAP,valueDefinition:{description:"",type:A.a2.ANY}}},commands:[f]}},92994:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>g});var A=r(54143),n=r(46009),o=r(75448),i=r(10489);var s=r(46611),a=r(32485),c=r(73632);const g={fetchers:[class{supports(e,t){return!!e.reference.startsWith("link:")}getLocalPath(e,t){const{parentLocator:r,path:o}=A.parseFileStyleRange(e.reference,{protocol:"link:"});if(n.y1.isAbsolute(o))return o;const i=t.fetcher.getLocalPath(r,t);return null===i?null:n.y1.resolve(i,o)}async fetch(e,t){const{parentLocator:r,path:s}=A.parseFileStyleRange(e.reference,{protocol:"link:"}),a=n.y1.isAbsolute(s)?{packageFs:new o.M(n.LZ.root),prefixPath:n.LZ.dot,localPath:n.LZ.root}:await t.fetcher.fetch(r,t),c=a.localPath?{packageFs:new o.M(n.LZ.root),prefixPath:n.y1.relative(n.LZ.root,a.localPath)}:a;a!==c&&a.releaseFs&&a.releaseFs();const g=c.packageFs,l=n.y1.join(c.prefixPath,s);return a.localPath?{packageFs:new o.M(l,{baseFs:g}),releaseFs:c.releaseFs,prefixPath:n.LZ.dot,discardFromLookup:!0,localPath:l}:{packageFs:new i.n(l,{baseFs:g}),releaseFs:c.releaseFs,prefixPath:n.LZ.dot,discardFromLookup:!0}}},class{supports(e,t){return!!e.reference.startsWith("portal:")}getLocalPath(e,t){const{parentLocator:r,path:o}=A.parseFileStyleRange(e.reference,{protocol:"portal:"});if(n.y1.isAbsolute(o))return o;const i=t.fetcher.getLocalPath(r,t);return null===i?null:n.y1.resolve(i,o)}async fetch(e,t){const{parentLocator:r,path:s}=A.parseFileStyleRange(e.reference,{protocol:"portal:"}),a=n.y1.isAbsolute(s)?{packageFs:new o.M(n.LZ.root),prefixPath:n.LZ.dot,localPath:n.LZ.root}:await t.fetcher.fetch(r,t),c=a.localPath?{packageFs:new o.M(n.LZ.root),prefixPath:n.y1.relative(n.LZ.root,a.localPath)}:a;a!==c&&a.releaseFs&&a.releaseFs();const g=c.packageFs,l=n.y1.join(c.prefixPath,s);return a.localPath?{packageFs:new o.M(l,{baseFs:g}),releaseFs:c.releaseFs,prefixPath:n.LZ.dot,localPath:l}:{packageFs:new i.n(l,{baseFs:g}),releaseFs:c.releaseFs,prefixPath:n.LZ.dot}}}],resolvers:[class{supportsDescriptor(e,t){return!!e.range.startsWith("link:")}supportsLocator(e,t){return!!e.reference.startsWith("link:")}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,r){return A.bindDescriptor(e,{locator:A.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,r){const o=e.range.slice("link:".length);return[A.makeLocator(e,"link:"+n.cS.toPortablePath(o))]}async getSatisfying(e,t,r){return null}async resolve(e,t){return{...e,version:"0.0.0",languageName:t.project.configuration.get("defaultLanguageName"),linkType:a.Un.SOFT,dependencies:new Map,peerDependencies:new Map,dependenciesMeta:new Map,peerDependenciesMeta:new Map,bin:new Map}}},class{supportsDescriptor(e,t){return!!e.range.startsWith("portal:")}supportsLocator(e,t){return!!e.reference.startsWith("portal:")}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,r){return A.bindDescriptor(e,{locator:A.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,r){const o=e.range.slice("portal:".length);return[A.makeLocator(e,"portal:"+n.cS.toPortablePath(o))]}async getSatisfying(e,t,r){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");const r=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),A=await c.releaseAfterUseAsync(async()=>await s.G.find(r.prefixPath,{baseFs:r.packageFs}),r.releaseFs);return{...e,version:A.version||"0.0.0",languageName:t.project.configuration.get("defaultLanguageName"),linkType:a.Un.SOFT,dependencies:new Map([...A.dependencies,...A.devDependencies]),peerDependencies:A.peerDependencies,dependenciesMeta:A.dependenciesMeta,peerDependenciesMeta:A.peerDependenciesMeta,bin:A.bin}}}]}},8375:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>ne,getPnpPath:()=>Ae});var A,n=r(39922),o=r(46009),i=r(54143);!function(e){e[e.YES=0]="YES",e[e.NO=1]="NO",e[e.DEPENDS=2]="DEPENDS"}(A||(A={}));const s=(e,t)=>`${e}@${t}`,a=(e,t)=>{const r=t.indexOf("#"),A=r>=0?t.substring(r+1):t;return s(e,A)};var c;!function(e){e[e.NONE=-1]="NONE",e[e.PERF=0]="PERF",e[e.CHECK=1]="CHECK",e[e.REASONS=2]="REASONS",e[e.INTENSIVE_CHECK=9]="INTENSIVE_CHECK"}(c||(c={}));const g=(e,t)=>{if(t.decoupled)return t;const{name:r,references:A,ident:n,locator:o,dependencies:i,originalDependencies:s,hoistedDependencies:a,peerNames:c,reasons:g,isHoistBorder:l}=t,u={name:r,references:new Set(A),ident:n,locator:o,dependencies:new Map(i),originalDependencies:new Map(s),hoistedDependencies:new Map(a),peerNames:new Set(c),reasons:new Map(g),decoupled:!0,isHoistBorder:l},h=u.dependencies.get(r);return h&&h.ident==u.ident&&u.dependencies.set(r,u),e.dependencies.set(u.name,u),u},l=e=>{const t=new Set,r=(A,n=new Set)=>{if(!n.has(A)){n.add(A);for(const o of A.peerNames)if(!e.peerNames.has(o)){const A=e.dependencies.get(o);A&&!t.has(A)&&r(A,n)}t.add(A)}};for(const t of e.dependencies.values())e.peerNames.has(t.name)||r(t);return t},u=(e,t,r,A,n=new Set)=>{const o=t[t.length-1];if(n.has(o))return;n.add(o);const i=((e,t)=>{const r=new Map([[e.name,[e.ident]]]);for(const t of e.dependencies.values())e.peerNames.has(t.name)||r.set(t.name,[t.ident]);const A=Array.from(t.keys());A.sort((e,r)=>{const A=t.get(e),n=t.get(r);return n.peerDependents.size!==A.peerDependents.size?n.peerDependents.size-A.peerDependents.size:n.dependents.size-A.dependents.size});for(const t of A){const A=t.substring(0,t.indexOf("@",1)),n=t.substring(A.length+1);if(!e.peerNames.has(A)){let e=r.get(A);e||(e=[],r.set(A,e)),e.indexOf(n)<0&&e.push(n)}}return r})(o,E(o)),s=new Map(Array.from(i.entries()).map(([e,t])=>[e,t[0]])),a=o===e?new Map:(e=>{const t=new Map,r=new Set,A=n=>{if(!r.has(n)){r.add(n);for(const r of n.hoistedDependencies.values())e.dependencies.has(r.name)||t.set(r.name,r);for(const e of n.dependencies.values())n.peerNames.has(e.name)||A(e)}};return A(e),t})(o);let c;do{p(e,t,r,a,s,i,A),c=!1;for(const[e,t]of i)t.length>1&&!o.dependencies.has(e)&&(s.delete(e),t.shift(),s.set(e,t[0]),c=!0)}while(c);for(const n of o.dependencies.values())o.peerNames.has(n.name)||r.has(n.locator)||(r.add(n.locator),u(e,[...t,n],r,A),r.delete(n.locator))},h=(e,t,r,n,o,i,{outputReason:s})=>{let a,c=null,g=new Set;s&&(a=""+Array.from(e).map(e=>B(e)).join("→"));const l=t[t.length-1],u=r.ident===l.ident,h=o.get(r.name);let p=h===r.ident&&!u;if(s&&!p&&h&&!u&&(c=`- filled by: ${B(i.get(r.name)[0])} at ${a}`),p){let e=!1;const A=n.get(r.name);if(e=!A||A.ident===r.ident,s&&!e&&(c=`- filled by: ${B(A.locator)} at ${a}`),e)for(let A=1;A=1;r--){const n=t[r];for(const o of A){if(n.peerNames.has(o)&&n.originalDependencies.has(o))continue;const i=n.dependencies.get(o);i&&(r===t.length-1?g.add(i):(g=null,e=!1,s&&(c=`- peer dependency ${B(i.locator)} from parent ${B(n.locator)} was not hoisted to ${a}`))),A.delete(o)}if(!e)break}p=e}return null!==g&&g.size>0?{isHoistable:A.DEPENDS,dependsOn:g,reason:c}:{isHoistable:p?A.YES:A.NO,reason:c}},p=(e,t,r,n,o,i,s)=>{const a=t[t.length-1],u=new Set,p=(t,C,I,E)=>{if(u.has(I))return;const m=[...C,I.locator],w=new Map,Q=new Map;for(const e of l(I)){let g=null;if(g||(g=h(r,[a,...t,I],e,n,o,i,{outputReason:s.debugLevel>=c.REASONS})),Q.set(e,g),g.isHoistable===A.DEPENDS)for(const t of g.dependsOn){const r=w.get(t.name)||new Set;r.add(e.name),w.set(t.name,r)}}const D=new Set,b=(e,t,r)=>{if(!D.has(e)){D.add(e),e.ident!==I.ident&&Q.set(e,{isHoistable:A.NO,reason:r});for(const A of w.get(e.name)||[])b(I.dependencies.get(A),t,r)}};let v;s.debugLevel>=c.REASONS&&(v=""+Array.from(r).map(e=>B(e)).join("→"));for(const[e,t]of Q)t.isHoistable===A.NO&&b(e,t,`- peer dependency ${B(e.locator)} from parent ${B(I.locator)} was not hoisted to ${v}`);for(const e of Q.keys())if(!D.has(e)){I.dependencies.delete(e.name),I.hoistedDependencies.set(e.name,e),I.reasons.delete(e.name);const t=a.dependencies.get(e.name);if(t)for(const r of e.references)t.references.add(r);else a.ident!==e.ident&&(a.dependencies.set(e.name,e),E.add(e))}if(s.check){const r=d(e);if(r)throw new Error(`${r}, after hoisting dependencies of ${[a,...t,I].map(e=>B(e.locator)).join("→")}:\n${y(e)}`)}const S=l(I);for(const e of S)if(D.has(e)&&m.indexOf(e.locator)<0){const r=Q.get(e);if(r.isHoistable!==A.YES&&I.reasons.set(e.name,r.reason),!e.isHoistBorder){u.add(I);const r=g(I,e);p([...t,I],[...C,I.locator],r,f),u.delete(I)}}};let C,f=new Set(l(a));do{C=f,f=new Set;for(const e of C){if(e.locator===a.locator||e.isHoistBorder)continue;const t=g(a,e);p([],Array.from(r),t,f)}}while(f.size>0)},d=e=>{const t=[],r=new Set,A=new Set,n=(e,o)=>{if(r.has(e))return;if(r.add(e),A.has(e))return;const i=new Map(o);for(const t of e.dependencies.values())e.peerNames.has(t.name)||i.set(t.name,t);for(const r of e.originalDependencies.values()){const n=i.get(r.name),s=()=>""+Array.from(A).concat([e]).map(e=>B(e.locator)).join("→");if(e.peerNames.has(r.name)){const e=o.get(r.name);e===n&&e&&e.ident===r.ident||t.push(`${s()} - broken peer promise: expected ${r.ident} but found ${e?e.ident:e}`)}else n?n.ident!==r.ident&&t.push(`${s()} - broken require promise for ${r.name}: expected ${r.ident}, but found: ${n.ident}`):t.push(`${s()} - broken require promise: no required dependency ${r.locator} found`)}A.add(e);for(const t of e.dependencies.values())e.peerNames.has(t.name)||n(t,i);A.delete(e)};return n(e,e.dependencies),t.join("\n")},C=(e,t)=>{const{identName:r,name:A,reference:n,peerNames:o}=e,i={name:A,references:new Set([n]),locator:s(r,n),ident:a(r,n),dependencies:new Map,originalDependencies:new Map,hoistedDependencies:new Map,peerNames:new Set(o),reasons:new Map,decoupled:!0,isHoistBorder:!0},c=new Map([[e,i]]),g=(e,r)=>{let A=c.get(e);const n=!!A;if(!A){const{name:n,identName:o,reference:i,peerNames:g}=e,l=t.hoistingLimits.get(r.locator);A={name:n,references:new Set([i]),locator:s(o,i),ident:a(o,i),dependencies:new Map,originalDependencies:new Map,hoistedDependencies:new Map,peerNames:new Set(g),reasons:new Map,decoupled:!0,isHoistBorder:!!l&&l.has(n)},c.set(e,A)}if(r.dependencies.set(e.name,A),r.originalDependencies.set(e.name,A),n){const e=new Set,t=r=>{if(!e.has(r)){e.add(r),r.decoupled=!1;for(const e of r.dependencies.values())r.peerNames.has(e.name)||t(e)}};t(A)}else for(const t of e.dependencies)g(t,A)};for(const t of e.dependencies)g(t,i);return i},f=e=>e.substring(0,e.indexOf("@",1)),I=e=>{const t={name:e.name,identName:f(e.locator),references:new Set(e.references),dependencies:new Set},r=new Set([e]),A=(e,t,n)=>{const o=r.has(e);let i;if(t===e)i=n;else{const{name:t,references:r,locator:A}=e;i={name:t,identName:f(A),references:r,dependencies:new Set}}if(n.dependencies.add(i),!o){r.add(e);for(const t of e.dependencies.values())e.peerNames.has(t.name)||A(t,e,i);r.delete(e)}};for(const r of e.dependencies.values())A(r,e,t);return t},E=e=>{const t=new Map,r=new Set([e]),A=e=>{const r=(e=>`${e.name}@${e.ident}`)(e);let A=t.get(r);return A||(A={dependents:new Set,peerDependents:new Set},t.set(r,A)),A},n=(e,t)=>{const o=!!r.has(t);if(A(t).dependents.add(e.ident),!o){r.add(t);for(const e of t.dependencies.values())if(t.peerNames.has(e.name)){A(e).peerDependents.add(t.ident)}else n(t,e)}};for(const t of e.dependencies.values())e.peerNames.has(t.name)||n(e,t);return t},B=e=>{const t=e.indexOf("@",1),r=e.substring(0,t),A=e.substring(t+1);if("workspace:."===A)return".";if(A){const e=(A.indexOf("#")>0?A.split("#")[1]:A).replace("npm:","");return A.startsWith("virtual")?`v:${r}@${e}`:`${r}@${e}`}return""+r},y=e=>{let t=0;const r=(e,A,n="")=>{if(t>5e4||A.has(e))return"";t++;const o=Array.from(e.dependencies.values());let i="";A.add(e);for(let t=0;t":"")+(c!==s.name?`a:${s.name}:`:"")+B(s.locator)+(a?" "+a:"")}\n`,i+=r(s,A,`${n}${t5e4?"\nTree is too large, part of the tree has been dunped\n":"")};var m,w;!function(e){e.HARD="HARD",e.SOFT="SOFT"}(m||(m={})),function(e){e.WORKSPACES="workspaces",e.DEPENDENCIES="dependencies",e.NONE="none"}(w||(w={}));const Q=(e,t)=>{const{packageTree:r,hoistingLimits:A}=b(e,t),n=((e,t={})=>{const r=t.debugLevel||Number(process.env.NM_DEBUG_LEVEL||c.NONE),A={check:t.check||r>=c.INTENSIVE_CHECK,debugLevel:r,hoistingLimits:t.hoistingLimits||new Map};A.debugLevel>=c.PERF&&console.time("hoist");const n=C(e,A);if(u(n,[n],new Set([n.locator]),A),A.debugLevel>=c.PERF&&console.timeEnd("hoist"),A.debugLevel>=c.CHECK){const e=d(n);if(e)throw new Error(`${e}, after hoisting finished:\n${y(n)}`)}return A.debugLevel>=c.REASONS&&console.log(y(n)),I(n)})(r,{hoistingLimits:A});return v(e,n,t)},D=e=>`${e.name}@${e.reference}`;const b=(e,t)=>{const r=e.getDependencyTreeRoots(),A=new Map,n=new Map,s=e.getPackageInformation(e.topLevel);if(null===s)throw new Error("Assertion failed: Expected the top-level package to have been registered");const a=e.findPackageLocator(s.packageLocation);if(null===a)throw new Error("Assertion failed: Expected the top-level package to have a physical locator");const c=o.cS.toPortablePath(s.packageLocation),g=D(a);if(t.project){const e={children:new Map},r=t.project.cwd.split(o.y1.sep);for(const[A,n]of t.project.workspacesByCwd){const t=A.split(o.y1.sep).slice(r.length);let s=e;for(const e of t){let t=s.children.get(e);t||(t={children:new Map},s.children.set(e,t)),s=t}s.workspaceLocator={name:i.stringifyIdent(n.anchoredLocator),reference:n.anchoredLocator.reference}}const A=(e,t)=>{if(e.workspaceLocator){const r=D(t);let A=n.get(r);A||(A=new Set,n.set(r,A)),A.add(e.workspaceLocator)}for(const r of e.children.values())A(r,e.workspaceLocator||t)};for(const t of e.children.values())A(t,e.workspaceLocator)}else for(const e of r)if(e.name!==a.name||e.reference!==a.reference){let t=n.get(g);t||(t=new Set,n.set(g,t)),t.add(e)}const l={name:a.name,identName:a.name,reference:a.reference,peerNames:s.packagePeers,dependencies:new Set},u=new Map,h=(r,s,g,p,d,C,f)=>{var I,E;const B=((e,t)=>`${D(t)}:${e}`)(r,g);let y=u.get(B);const m=!!y;if(m||g.name!==a.name||g.reference!==a.reference||(y=l,u.set(B,l)),y||(y={name:r,identName:g.name,reference:g.reference,dependencies:new Set,peerNames:s.packagePeers},u.set(B,y)),f){const e=D({name:p.identName,reference:p.reference}),t=A.get(e)||new Set;A.set(e,t),t.add(y.name)}const Q=new Map(s.packageDependencies);if(t.project){const e=t.project.workspacesByCwd.get(o.cS.toPortablePath(s.packageLocation.slice(0,-1)));if(e){const t=new Set([...Array.from(e.manifest.peerDependencies.values(),e=>i.stringifyIdent(e)),...Array.from(e.manifest.peerDependenciesMeta.keys())]);for(const e of t)Q.has(e)||(Q.set(e,d.get(e)||null),y.peerNames.add(e))}}const b=D(g),v=n.get(b);if(v)for(const e of v)Q.set(e.name+"$wsroot$",e.reference);p.dependencies.add(y);const S=t.pnpifyFs||!function(e){let t=i.parseDescriptor(e);return i.isVirtualDescriptor(t)&&(t=i.devirtualizeDescriptor(t)),t.range.startsWith("portal:")}(B);if(!m&&S)for(const[r,A]of Q)if(null!==A){const n=e.getLocator(r,A),i=e.getLocator(r.replace("$wsroot$",""),A),s=e.getPackageInformation(i);if(null===s)throw new Error("Assertion failed: Expected the package to have been registered");const a=null===(I=t.hoistingLimitsByCwd)||void 0===I?void 0:I.get(C),g=o.y1.relative(c,o.cS.toPortablePath(s.packageLocation))||o.LZ.dot,l=null===(E=t.hoistingLimitsByCwd)||void 0===E?void 0:E.get(g),u=a===w.DEPENDENCIES||l===w.DEPENDENCIES||l===w.WORKSPACES;h(r,s,n,y,Q,g,u)}};return h(a.name,s,a,l,s.packageDependencies,o.LZ.dot,!1),{packageTree:l,hoistingLimits:A}};const v=(e,t,r)=>{const A=new Map,n=(t,A)=>{const{linkType:n,target:i}=function(e,t,r){const A=t.getLocator(e.name.replace("$wsroot$",""),e.reference),n=t.getPackageInformation(A);if(null===n)throw new Error("Assertion failed: Expected the package to be registered");let i,s;if(r.pnpifyFs)s=o.cS.toPortablePath(n.packageLocation),i=m.SOFT;else{const r=t.resolveVirtual&&e.reference&&e.reference.startsWith("virtual:")?t.resolveVirtual(n.packageLocation):n.packageLocation;s=o.cS.toPortablePath(r||n.packageLocation),i=n.linkType}return{linkType:i,target:s}}(t,e,r);return{locator:D(t),target:i,linkType:n,aliases:A}},s=e=>{const[t,r]=e.split("/");return r?{scope:(0,o.Zu)(t),name:(0,o.Zu)(r)}:{scope:null,name:(0,o.Zu)(t)}},a=new Set,c=(e,t)=>{if(!a.has(e)){a.add(e);for(const r of e.dependencies){if(r===e||e.identName.endsWith("$wsroot$")&&r.identName===e.identName.replace("$wsroot$",""))continue;const a=Array.from(r.references).sort(),g={name:r.identName,reference:a[0]},{name:l,scope:u}=s(r.name),h=u?[u,l]:[l],p=o.y1.join(t,"node_modules"),d=o.y1.join(p,...h),C=n(g,a.slice(1));if(!r.name.endsWith("$wsroot$")){const e=A.get(d);if(e){if(e.dirList)throw new Error(`Assertion failed: ${d} cannot merge dir node with leaf node`);{const t=i.parseLocator(e.locator),r=i.parseLocator(C.locator);if(e.linkType!==C.linkType)throw new Error(`Assertion failed: ${d} cannot merge nodes with different link types`);if(t.identHash!==r.identHash)throw new Error(`Assertion failed: ${d} cannot merge nodes with different idents ${i.stringifyLocator(t)} and ${i.stringifyLocator(r)}`);C.aliases=[...C.aliases,...e.aliases,i.parseLocator(e.locator).reference]}}A.set(d,C);const t=d.split("/"),r=t.indexOf("node_modules");let n=t.length-1;for(;r>=0&&n>r;){const e=o.cS.toPortablePath(t.slice(0,n).join(o.y1.sep)),r=(0,o.Zu)(t[n]),i=A.get(e);if(i){if(i.dirList){if(i.dirList.has(r))break;i.dirList.add(r)}}else A.set(e,{dirList:new Set([r])});n--}}c(r,C.linkType===m.SOFT?C.target:d)}}},g=n({name:t.name,reference:Array.from(t.references)[0]},[]),l=g.target;return A.set(l,g),c(t,l),A};var S=r(92659),k=r(32485),N=r(73632),F=r(46611),K=r(35691),M=r(43896),R=r(17674),x=r(53660),L=r(65281),P=r(11640),O=r(83228),U=r(58069),T=r.n(U),j=r(40822),Y=r(35747),G=r.n(Y);const H="node_modules";class J{constructor(e){this.opts=e,this.localStore=new Map,this.customData={store:new Map}}getCustomDataKey(){return JSON.stringify({name:"NodeModulesInstaller",version:1})}attachCustomData(e){this.customData=e}async installPackage(e,t){var r;const A=o.y1.resolve(t.packageFs.getRealPath(),t.prefixPath);let n=this.customData.store.get(e.locatorHash);if(void 0===n&&(n=await async function(e,t){var r;const A=null!==(r=await F.G.tryFind(t.prefixPath,{baseFs:t.packageFs}))&&void 0!==r?r:new F.G,n=new Set(["preinstall","install","postinstall"]);for(const e of A.scripts.keys())n.has(e)||A.scripts.delete(e);return{manifest:{bin:A.bin,os:A.os,cpu:A.cpu,scripts:A.scripts},misc:{extractHint:O.jsInstallUtils.getExtractHint(t),hasBindingGyp:O.jsInstallUtils.hasBindingGyp(t)}}}(0,t),e.linkType===k.Un.HARD&&this.customData.store.set(e.locatorHash,n)),!O.jsInstallUtils.checkAndReportManifestCompatibility(e,n,"link",{configuration:this.opts.project.configuration,report:this.opts.report}))return{packageLocation:null,buildDirective:null};const s=new Map,a=new Set;if(s.has(i.stringifyIdent(e))||s.set(i.stringifyIdent(e),e.reference),i.isVirtualLocator(e))for(const t of e.peerDependencies.values())s.set(i.stringifyIdent(t),null),a.add(i.stringifyIdent(t));const c={packageLocation:o.cS.fromPortablePath(A)+"/",packageDependencies:s,packagePeers:a,linkType:e.linkType,discardFromLookup:null!==(r=t.discardFromLookup)&&void 0!==r&&r};return this.localStore.set(e.locatorHash,{pkg:e,customPackageData:n,dependencyMeta:this.opts.project.getDependencyMeta(e,e.version),pnpNode:c}),{packageLocation:A,buildDirective:null}}async attachInternalDependencies(e,t){const r=this.localStore.get(e.locatorHash);if(void 0===r)throw new Error("Assertion failed: Expected information object to have been registered");for(const[e,A]of t){const t=i.areIdentsEqual(e,A)?A.reference:[i.requirableIdent(A),A.reference];r.pnpNode.packageDependencies.set(i.requirableIdent(e),t)}}async attachExternalDependents(e,t){throw new Error("External dependencies haven't been implemented for the node-modules linker")}async finalizeInstall(){if("node-modules"!==this.opts.project.configuration.get("nodeLinker"))return;const e=new R.p({baseFs:new x.A({libzip:await(0,L.getLibzipPromise)(),maxOpenFiles:80,readOnlyArchives:!0})});let t=await q(this.opts.project);if(null===t){const e=this.opts.project.configuration.get("bstatePath");await M.xfs.existsPromise(e)&&await M.xfs.unlinkPromise(e),t={locatorMap:new Map,binSymlinks:new Map,locationTree:new Map}}const r=new Map(this.opts.project.workspaces.map(e=>{var t,r;let A=this.opts.project.configuration.get("nmHoistingLimits");try{A=N.validateEnum(w,null!==(r=null===(t=e.manifest.installConfig)||void 0===t?void 0:t.hoistingLimits)&&void 0!==r?r:A)}catch(t){const r=i.prettyWorkspace(this.opts.project.configuration,e);this.opts.report.reportWarning(S.b.INVALID_MANIFEST,`${r}: Invalid 'installConfig.hoistingLimits' value. Expected one of ${Object.values(w).join(", ")}, using default: "${A}"`)}return[e.relativeCwd,A]})),A=(e=>{const t=new Map;for(const[r,A]of e.entries())if(!A.dirList){let e=t.get(A.locator);e||(e={target:A.target,linkType:A.linkType,locations:[],aliases:A.aliases},t.set(A.locator,e)),e.locations.push(r)}for(const e of t.values())e.locations=e.locations.sort((e,t)=>{const r=e.split(o.y1.delimiter).length,A=t.split(o.y1.delimiter).length;return r!==A?A-r:t.localeCompare(e)});return t})(Q({VERSIONS:{std:1},topLevel:{name:null,reference:null},getLocator:(e,t)=>Array.isArray(t)?{name:t[0],reference:t[1]}:{name:e,reference:t},getDependencyTreeRoots:()=>this.opts.project.workspaces.map(e=>{const t=e.anchoredLocator;return{name:i.stringifyIdent(e.locator),reference:t.reference}}),getPackageInformation:e=>{const t=null===e.reference?this.opts.project.topLevelWorkspace.anchoredLocator:i.makeLocator(i.parseIdent(e.name),e.reference),r=this.localStore.get(t.locatorHash);if(void 0===r)throw new Error("Assertion failed: Expected the package reference to have been registered");return r.pnpNode},findPackageLocator:e=>{const t=this.opts.project.tryWorkspaceByCwd(o.cS.toPortablePath(e));if(null!==t){const e=t.anchoredLocator;return{name:i.stringifyIdent(e),reference:e.reference}}throw new Error("Assertion failed: Unimplemented")},resolveToUnqualified:()=>{throw new Error("Assertion failed: Unimplemented")},resolveUnqualified:()=>{throw new Error("Assertion failed: Unimplemented")},resolveRequest:()=>{throw new Error("Assertion failed: Unimplemented")},resolveVirtual:e=>o.cS.fromPortablePath(R.p.resolveVirtual(o.cS.toPortablePath(e)))},{pnpifyFs:!1,hoistingLimitsByCwd:r,project:this.opts.project}));await async function(e,t,{baseFs:r,project:A,report:n,loadManifest:s}){const a=o.y1.join(A.cwd,H),{locationTree:c,binSymlinks:g}=function(e,t){const r=new Map([...e]),A=new Map([...t]);for(const[t,r]of e){const e=o.y1.join(t,H);if(!M.xfs.existsSync(e)){r.children.delete(H);for(const t of A.keys())null!==o.y1.contains(e,t)&&A.delete(t)}}return{locationTree:r,binSymlinks:A}}(e.locationTree,e.binSymlinks),l=V(t,{skipPrefix:A.cwd}),u=[],h=async({srcDir:e,dstDir:t,linkType:A})=>{const n=(async()=>{try{A===k.Un.SOFT?(await M.xfs.mkdirPromise(o.y1.dirname(t),{recursive:!0}),await X(o.y1.resolve(e),t)):await _(t,e,{baseFs:r})}catch(r){throw r.message=`While persisting ${e} -> ${t} ${r.message}`,r}finally{I.tick()}})().then(()=>u.splice(u.indexOf(n),1));u.push(n),u.length>4&&await Promise.race(u)},p=async(e,t,r)=>{const A=(async()=>{const A=async(e,t,r)=>{try{r&&r.innerLoop||await M.xfs.mkdirPromise(t,{recursive:!0});const n=await M.xfs.readdirPromise(e,{withFileTypes:!0});for(const i of n){if(!(r&&r.innerLoop||".bin"!==i.name))continue;const n=o.y1.join(e,i.name),s=o.y1.join(t,i.name);i.isDirectory()?(i.name!==H||r&&r.innerLoop)&&(await M.xfs.mkdirPromise(s,{recursive:!0}),await A(n,s,{innerLoop:!0})):await M.xfs.copyFilePromise(n,s,G().constants.COPYFILE_FICLONE)}}catch(A){throw r&&r.innerLoop||(A.message=`While cloning ${e} -> ${t} ${A.message}`),A}finally{r&&r.innerLoop||I.tick()}};await A(e,t,r)})().then(()=>u.splice(u.indexOf(A),1));u.push(A),u.length>4&&await Promise.race(u)},d=async(e,t,r)=>{if(r)for(const[A,n]of t.children){const t=r.children.get(A);await d(o.y1.join(e,A),n,t)}else t.children.has(H)&&await z(o.y1.join(e,H),{contentsOnly:!1}),await z(e,{contentsOnly:e===a})};for(const[e,t]of c){const r=l.get(e);for(const[A,n]of t.children){if("."===A)continue;const t=r?r.children.get(A):r;await d(o.y1.join(e,A),n,t)}}const C=async(e,t,r)=>{if(r){$(t.locator,r.locator)||await z(e,{contentsOnly:t.linkType===k.Un.HARD});for(const[A,n]of t.children){const t=r.children.get(A);await C(o.y1.join(e,A),n,t)}}else t.children.has(H)&&await z(o.y1.join(e,H),{contentsOnly:!0}),await z(e,{contentsOnly:t.linkType===k.Un.HARD})};for(const[e,t]of l){const r=c.get(e);for(const[A,n]of t.children){if("."===A)continue;const t=r?r.children.get(A):r;await C(o.y1.join(e,A),n,t)}}const f=[];for(const[r,{locations:n}]of e.locatorMap.entries())for(const e of n){const{locationRoot:n,segments:i}=W(e,{skipPrefix:A.cwd});let s=l.get(n),a=n;if(s){for(const e of i)if(a=o.y1.join(a,e),s=s.children.get(e),!s)break;if(s&&!$(s.locator,r)){const e=t.get(s.locator),r=e.target,A=a,n=e.linkType;r!==A&&f.push({srcDir:r,dstDir:A,linkType:n})}}}for(const[e,{locations:r}]of t.entries())for(const n of r){const{locationRoot:r,segments:i}=W(n,{skipPrefix:A.cwd});let s=c.get(r),a=l.get(r),g=r;const u=t.get(e),h=u.target,p=n;if(h===p)continue;const d=u.linkType;for(const e of i)a=a.children.get(e);if(s){for(const e of i)if(g=o.y1.join(g,e),s=s.children.get(e),!s){f.push({srcDir:h,dstDir:p,linkType:d});break}}else f.push({srcDir:h,dstDir:p,linkType:d})}const I=K.yG.progressViaCounter(f.length),E=n.reportProgress(I);try{const e=new Map;for(const t of f)t.linkType!==k.Un.SOFT&&e.has(t.srcDir)||(e.set(t.srcDir,t.dstDir),await h({...t}));await Promise.all(u),u.length=0;for(const t of f){const r=e.get(t.srcDir);t.linkType!==k.Un.SOFT&&t.dstDir!==r&&await p(r,t.dstDir)}await Promise.all(u),await M.xfs.mkdirPromise(a,{recursive:!0});const r=await async function(e,t,r,{loadManifest:A}){const n=new Map;for(const[t,{locations:r}]of e){const e=Z(t)?null:await A(t,r[0]),i=new Map;if(e)for(const[t,A]of e.bin){const e=o.y1.join(r[0],A);""!==A&&M.xfs.existsSync(e)&&i.set(t,A)}n.set(t,i)}const i=new Map,s=(e,t,A)=>{const a=new Map,c=o.y1.contains(r,e);if(A.locator&&null!==c){const t=n.get(A.locator);for(const[r,A]of t){const t=o.y1.join(e,o.cS.toPortablePath(A));a.set((0,o.Zu)(r),t)}for(const[t,r]of A.children){const A=o.y1.join(e,t),n=s(A,A,r);n.size>0&&i.set(e,new Map([...i.get(e)||new Map,...n]))}}else for(const[r,n]of A.children){const A=s(o.y1.join(e,r),t,n);for(const[e,t]of A)a.set(e,t)}return a};for(const[e,r]of t){const t=s(e,e,r);t.size>0&&i.set(e,new Map([...i.get(e)||new Map,...t]))}return i}(t,l,A.cwd,{loadManifest:s});await async function(e,t){for(const r of e.keys())if(!t.has(r)){const e=o.y1.join(r,H,".bin");await M.xfs.removePromise(e)}for(const[r,A]of t){const t=o.y1.join(r,H,".bin"),n=e.get(r)||new Map;await M.xfs.mkdirPromise(t,{recursive:!0});for(const e of n.keys())A.has(e)||(await M.xfs.removePromise(o.y1.join(t,e)),"win32"===process.platform&&await M.xfs.removePromise(o.y1.join(t,(0,o.Zu)(e+".cmd"))));for(const[e,r]of A){const A=n.get(e),i=o.y1.join(t,e);A!==r&&("win32"===process.platform?await T()(o.cS.fromPortablePath(r),o.cS.fromPortablePath(i),{createPwshFile:!1}):(await M.xfs.removePromise(i),await X(r,i),await M.xfs.chmodPromise(r,493)))}}}(g,r),await async function(e,t,r){let A="";A+="# Warning: This file is automatically generated. Removing it is fine, but will\n",A+="# cause your node_modules installation to become invalidated.\n",A+="\n",A+="__metadata:\n",A+=" version: 1\n";const n=Array.from(t.keys()).sort(),s=i.stringifyLocator(e.topLevelWorkspace.anchoredLocator);for(const i of n){const n=t.get(i);A+="\n",A+=JSON.stringify(i)+":\n",A+=" locations:\n";for(const t of n.locations){const r=o.y1.contains(e.cwd,t);if(null===r)throw new Error(`Assertion failed: Expected the path to be within the project (${t})`);A+=` - ${JSON.stringify(r)}\n`}if(n.aliases.length>0){A+=" aliases:\n";for(const e of n.aliases)A+=` - ${JSON.stringify(e)}\n`}if(i===s&&r.size>0){A+=" bin:\n";for(const[t,n]of r){const r=o.y1.contains(e.cwd,t);if(null===r)throw new Error(`Assertion failed: Expected the path to be within the project (${t})`);A+=` ${JSON.stringify(r)}:\n`;for(const[e,r]of n){const n=o.y1.relative(o.y1.join(t,H),r);A+=` ${JSON.stringify(e)}: ${JSON.stringify(n)}\n`}}}}const a=e.cwd,c=o.y1.join(a,H,".yarn-state.yml");await M.xfs.changeFilePromise(c,A,{automaticNewlines:!0})}(A,t,r)}finally{E.stop()}}(t,A,{baseFs:e,project:this.opts.project,report:this.opts.report,loadManifest:async e=>{const t=i.parseLocator(e),r=this.localStore.get(t.locatorHash);if(void 0===r)throw new Error("Assertion failed: Expected the slot to exist");return r.customPackageData.manifest}});const n=[];for(const[e,t]of A.entries()){if(Z(e))continue;const r=i.parseLocator(e),A=this.localStore.get(r.locatorHash);if(void 0===A)throw new Error("Assertion failed: Expected the slot to exist");const o=O.jsInstallUtils.extractBuildScripts(A.pkg,A.customPackageData,A.dependencyMeta,{configuration:this.opts.project.configuration,report:this.opts.report});0!==o.length&&n.push({buildLocations:t.locations,locatorHash:r.locatorHash,buildDirective:o})}return{customData:this.customData,records:n}}}async function q(e,{unrollAliases:t=!1}={}){const r=e.cwd,A=o.y1.join(r,H,".yarn-state.yml");if(!M.xfs.existsSync(A))return null;const n=(0,P.parseSyml)(await M.xfs.readFilePromise(A,"utf8"));if(n.__metadata.version>1)return null;const s=new Map,a=new Map;delete n.__metadata;for(const[e,A]of Object.entries(n)){const n=A.locations.map(e=>o.y1.join(r,e)),c=A.bin;if(c)for(const[e,t]of Object.entries(c)){const A=o.y1.join(r,o.cS.toPortablePath(e)),n=N.getMapWithDefault(a,A);for(const[e,r]of Object.entries(t))n.set((0,o.Zu)(e),o.cS.toPortablePath([A,H,r].join(o.y1.delimiter)))}if(s.set(e,{target:o.LZ.dot,linkType:k.Un.HARD,locations:n,aliases:A.aliases||[]}),t&&A.aliases)for(const t of A.aliases){const{scope:r,name:A}=i.parseLocator(e),a=i.makeLocator(i.makeIdent(r,A),t),c=i.stringifyLocator(a);s.set(c,{target:o.LZ.dot,linkType:k.Un.HARD,locations:n,aliases:[]})}}return{locatorMap:s,binSymlinks:a,locationTree:V(s,{skipPrefix:e.cwd})}}const z=async(e,t)=>{if(e.split(o.y1.sep).indexOf(H)<0)throw new Error("Assertion failed: trying to remove dir that doesn't contain node_modules: "+e);try{if(!t.innerLoop){if((await M.xfs.lstatPromise(e)).isSymbolicLink())return void await M.xfs.unlinkPromise(e)}const r=await M.xfs.readdirPromise(e,{withFileTypes:!0});for(const A of r){const r=o.y1.join(e,(0,o.Zu)(A.name));A.isDirectory()?(A.name!==H||t&&t.innerLoop)&&await z(r,{innerLoop:!0,contentsOnly:!1}):await M.xfs.unlinkPromise(r)}t.contentsOnly||await M.xfs.rmdirPromise(e)}catch(e){if("ENOENT"!==e.code&&"ENOTEMPTY"!==e.code)throw e}},W=(e,{skipPrefix:t})=>{const r=o.y1.contains(t,e);if(null===r)throw new Error(`Assertion failed: Cannot process a path that isn't part of the requested prefix (${e} isn't within ${t})`);const A=r.split(o.y1.sep).filter(e=>""!==e),n=A.indexOf(H),i=A.slice(0,n).join(o.y1.sep);return{locationRoot:o.y1.join(t,i),segments:A.slice(n)}},V=(e,{skipPrefix:t})=>{const r=new Map;if(null===e)return r;const A=()=>({children:new Map,linkType:k.Un.HARD});for(const[n,i]of e.entries()){if(i.linkType===k.Un.SOFT){if(null!==o.y1.contains(t,i.target)){const e=N.getFactoryWithDefault(r,i.target,A);e.locator=n,e.linkType=i.linkType}}for(const e of i.locations){const{locationRoot:o,segments:s}=W(e,{skipPrefix:t});let a=N.getFactoryWithDefault(r,o,A);for(let e=0;e{let r;try{"win32"===process.platform&&(r=M.xfs.lstatSync(e))}catch(e){}"win32"!=process.platform||r&&!r.isDirectory()?M.xfs.symlinkPromise(o.y1.relative(o.y1.dirname(t),e),t):M.xfs.symlinkPromise(e,t,"junction")},_=async(e,t,{baseFs:r,innerLoop:A})=>{await M.xfs.mkdirPromise(e,{recursive:!0});const n=await r.readdirPromise(t,{withFileTypes:!0}),i=async(e,t,A)=>{if(A.isFile()){const A=await r.lstatPromise(t);await r.copyFilePromise(t,e);const n=511&A.mode;420!==n&&await M.xfs.chmodPromise(e,n)}else{if(!A.isSymbolicLink())throw new Error(`Unsupported file type (file: ${t}, mode: 0o${await M.xfs.statSync(t).mode.toString(8).padStart(6,"0")})`);{const A=await r.readlinkPromise(t);await X(o.y1.resolve(o.y1.dirname(e),A),e)}}};for(const s of n){const n=o.y1.join(t,(0,o.Zu)(s.name)),a=o.y1.join(e,(0,o.Zu)(s.name));s.isDirectory()?(s.name!==H||A)&&await _(a,n,{baseFs:r,innerLoop:!0}):await i(a,n,s)}};function Z(e){let t=i.parseDescriptor(e);return i.isVirtualDescriptor(t)&&(t=i.devirtualizeDescriptor(t)),t.range.startsWith("link:")}const $=(e,t)=>{if(!e||!t)return e===t;let r=i.parseLocator(e);i.isVirtualLocator(r)&&(r=i.devirtualizeLocator(r));let A=i.parseLocator(t);return i.isVirtualLocator(A)&&(A=i.devirtualizeLocator(A)),i.areLocatorsEqual(r,A)};var ee=r(34432);class te extends O.PnpLinker{constructor(){super(...arguments),this.mode="loose"}makeInstaller(e){return new re(e)}}class re extends O.PnpInstaller{constructor(){super(...arguments),this.mode="loose"}async finalizeInstallWithPnp(e){if(this.opts.project.configuration.get("pnpMode")!==this.mode)return;const t=new R.p({baseFs:new x.A({libzip:await(0,L.getLibzipPromise)(),maxOpenFiles:80,readOnlyArchives:!0})}),r=(0,ee.oC)(e,this.opts.project.cwd,t),A=Q(r,{pnpifyFs:!1,project:this.opts.project}),n=new Map;e.fallbackPool=n;const s=(e,t)=>{const r=i.parseLocator(t.locator),A=i.stringifyIdent(r);A===e?n.set(e,r.reference):n.set(e,[A,r.reference])},a=o.y1.join(this.opts.project.cwd,o.QS.nodeModules),c=A.get(a);if(void 0===c)throw new Error("Assertion failed: Expected a root junction point");if("target"in c)throw new Error("Assertion failed: Expected the root junction point to be a directory");for(const e of c.dirList){const t=o.y1.join(a,e),r=A.get(t);if(void 0===r)throw new Error("Assertion failed: Expected the child to have been registered");if("target"in r)s(e,r);else for(const n of r.dirList){const r=o.y1.join(t,n),i=A.get(r);if(void 0===i)throw new Error("Assertion failed: Expected the subchild to have been registered");if(!("target"in i))throw new Error("Assertion failed: Expected the leaf junction to be a package");s(`${e}/${n}`,i)}}return super.finalizeInstallWithPnp(e)}}const Ae=e=>o.y1.join(e.cwd,".pnp.js"),ne={configuration:{nmHoistingLimits:{description:"Prevent packages can be hoisted past specific levels",type:n.a2.STRING,values:[w.WORKSPACES,w.DEPENDENCIES,w.NONE],default:"none"}},linkers:[class{supportsPackage(e,t){return"node-modules"===t.project.configuration.get("nodeLinker")}async findPackageLocation(e,t){const r=t.project.tryWorkspaceByLocator(e);if(r)return r.cwd;const A=await q(t.project,{unrollAliases:!0});if(null===A)throw new j.UsageError("Couldn't find the node_modules state file - running an install might help (findPackageLocation)");const n=A.locatorMap.get(i.stringifyLocator(e));if(!n){const r=new j.UsageError(`Couldn't find ${i.prettyLocator(t.project.configuration,e)} in the currently installed node_modules map - running an install might help`);throw r.code="LOCATOR_NOT_INSTALLED",r}return n.locations[0]}async findPackageLocator(e,t){const r=await q(t.project,{unrollAliases:!0});if(null===r)return null;const{locationRoot:A,segments:n}=W(o.y1.resolve(e),{skipPrefix:t.project.cwd});let s=r.locationTree.get(A);if(!s)return null;let a=s.locator;for(const e of n){if(s=s.children.get(e),!s)break;a=s.locator||a}return i.parseLocator(a)}makeInstaller(e){return new J(e)}},te]}},8190:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>X});var A,n,o=r(39922),i=r(36370),s=r(25413),a=r(85824),c=r(62152),g=r(35691),l=r(92659),u=r(85875),h=r(15815),p=r(14224),d=r(40822);!function(e){e.All="all",e.Production="production",e.Development="development"}(A||(A={})),function(e){e.Info="info",e.Low="low",e.Moderate="moderate",e.High="high",e.Critical="critical"}(n||(n={}));var C=r(54143),f=r(73632),I=r(71643);const E=[n.Info,n.Low,n.Moderate,n.High,n.Critical];function B(e,t){const r=[],A=new Set,n=e=>{A.has(e)||(A.add(e),r.push(e))};for(const e of t)n(e);const o=new Set;for(;r.length>0;){const t=r.shift(),A=e.storedResolutions.get(t);if(void 0===A)throw new Error("Assertion failed: Expected the resolution to have been registered");const i=e.storedPackages.get(A);if(i){o.add(t);for(const e of i.dependencies.values())n(e.descriptorHash)}}return o}function y(e,t,{all:r}){const A=r?e.workspaces:[t],n=A.map(e=>e.manifest),o=new Set(n.map(e=>[...e.dependencies].map(([e,t])=>e)).flat()),i=new Set(n.map(e=>[...e.devDependencies].map(([e,t])=>e)).flat()),s=A.map(e=>[...e.dependencies.values()]).flat(),a=s.filter(e=>o.has(e.identHash)).map(e=>e.descriptorHash),c=s.filter(e=>i.has(e.identHash)).map(e=>e.descriptorHash),g=B(e,a),l=B(e,c);return u=l,h=g,new Set([...u].filter(e=>!h.has(e)));var u,h}function m(e){const t={};for(const r of e)t[C.stringifyIdent(r)]=C.parseRange(r.range).selector;return t}function w(e){if(void 0===e)return new Set;const t=E.indexOf(e),r=E.slice(t);return new Set(r)}function Q(e,t){var r;const A=function(e,t){const r=w(t),A={};for(const t of r)A[t]=e[t];return A}(e,t);for(const e of Object.keys(A))if(null!==(r=A[e])&&void 0!==r&&r)return!0;return!1}class D extends s.BaseCommand{constructor(){super(...arguments),this.all=!1,this.recursive=!1,this.environment=A.All,this.json=!1,this.severity=n.Info}async execute(){const e=await o.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await a.I.find(e,this.context.cwd);if(!r)throw new s.WorkspaceRequiredError(t.cwd,this.context.cwd);await t.restoreInstallState();const n=function(e,t,{all:r,environment:n}){const o=r?e.workspaces:[t],i=[];if([A.All,A.Production].includes(n))for(const e of o)for(const t of e.manifest.dependencies.values())i.push(t);const s=[];if([A.All,A.Development].includes(n))for(const e of o)for(const t of e.manifest.devDependencies.values())s.push(t);return m([...i,...s].filter(e=>null===C.parseRange(e.range).protocol))}(t,r,{all:this.all,environment:this.environment}),i=function(e,t,{all:r}){var A;const n=y(e,t,{all:r}),o={};for(const t of e.storedPackages.values())o[C.stringifyIdent(t)]={version:null!==(A=t.version)&&void 0!==A?A:"0.0.0",integrity:t.identHash,requires:m(t.dependencies.values()),dev:n.has(C.convertLocatorToDescriptor(t).descriptorHash)};return o}(t,r,{all:this.all});if(!this.recursive)for(const e of Object.keys(i))Object.prototype.hasOwnProperty.call(n,e)?i[e].requires={}:delete i[e];const d={requires:n,dependencies:i},E=p.npmConfigUtils.getPublishRegistry(r.manifest,{configuration:e});let B;const D=await c.h.start({configuration:e,stdout:this.context.stdout},async()=>{try{B=await p.npmHttpUtils.post("/-/npm/v1/security/audits/quick",d,{authType:p.npmHttpUtils.AuthType.NO_AUTH,configuration:e,jsonResponse:!0,registry:E})}catch(e){throw"HTTPError"!==e.name?e:new g.lk(l.b.EXCEPTION,e.toString())}});if(D.hasErrors())return D.exitCode();const b=Q(B.metadata.vulnerabilities,this.severity);if(!this.json&&b)return u.emitTree(function(e,t){const r={},A={children:r};let n=Object.values(e.advisories);if(null!=t){const e=w(t);n=n.filter(t=>e.has(t.severity))}for(const e of f.sortMap(n,e=>e.module_name))r[e.module_name]={label:e.module_name,value:I.tuple(I.Type.RANGE,e.findings.map(e=>e.version).join(", ")),children:{Issue:{label:"Issue",value:I.tuple(I.Type.NO_HINT,e.title)},URL:{label:"URL",value:I.tuple(I.Type.URL,e.url)},Severity:{label:"Severity",value:I.tuple(I.Type.NO_HINT,e.severity)},"Vulnerable Versions":{label:"Vulnerable Versions",value:I.tuple(I.Type.RANGE,e.vulnerable_versions)},"Patched Versions":{label:"Patched Versions",value:I.tuple(I.Type.RANGE,e.patched_versions)},Via:{label:"Via",value:I.tuple(I.Type.NO_HINT,Array.from(new Set(e.findings.map(e=>e.paths).flat().map(e=>e.split(">")[0]))).join(", "))},Recommendation:{label:"Recommendation",value:I.tuple(I.Type.NO_HINT,e.recommendation.replace(/\n/g," "))}}};return A}(B,this.severity),{configuration:e,json:this.json,stdout:this.context.stdout,separators:2}),1;return(await h.Pk.start({configuration:e,includeFooter:!1,json:this.json,stdout:this.context.stdout},async e=>{e.reportJson(B),b||e.reportInfo(l.b.EXCEPTION,"No audit suggestions")})).exitCode()}}D.usage=d.Command.Usage({description:"perform a vulnerability audit against the installed packages",details:`\n This command checks for known security reports on the packages you use. The reports are by default extracted from the npm registry, and may or may not be relevant to your actual program (not all vulnerabilities affect all code paths).\n\n For consistency with our other commands the default is to only check the direct dependencies for the active workspace. To extend this search to all workspaces, use \`-A,--all\`. To extend this search to both direct and transitive dependencies, use \`-R,--recursive\`.\n\n Applying the \`--severity\` flag will limit the audit table to vulnerabilities of the corresponding severity and above. Valid values are ${E.map(e=>`\`${e}\``).join(", ")}.\n\n If the \`--json\` flag is set, Yarn will print the output exactly as received from the registry. Regardless of this flag, the process will exit with a non-zero exit code if a report is found for the selected packages.\n\n To understand the dependency tree requiring vulnerable packages, check the raw report with the \`--json\` flag or use \`yarn why \` to get more information as to who depends on them.\n `,examples:[["Checks for known security issues with the installed packages. The output is a list of known issues.","yarn npm audit"],["Audit dependencies in all workspaces","yarn npm audit --all"],["Limit auditing to `dependencies` (excludes `devDependencies`)","yarn npm audit --environment production"],["Show audit report as valid JSON","yarn npm audit --json"],["Audit all direct and transitive dependencies","yarn npm audit --recursive"],["Output moderate (or more severe) vulnerabilities","yarn npm audit --severity moderate"]]}),(0,i.gn)([d.Command.Boolean("-A,--all")],D.prototype,"all",void 0),(0,i.gn)([d.Command.Boolean("-R,--recursive")],D.prototype,"recursive",void 0),(0,i.gn)([d.Command.String("--environment")],D.prototype,"environment",void 0),(0,i.gn)([d.Command.Boolean("--json")],D.prototype,"json",void 0),(0,i.gn)([d.Command.String("--severity")],D.prototype,"severity",void 0),(0,i.gn)([d.Command.Path("npm","audit")],D.prototype,"execute",null);var b=r(85622),v=r.n(b),S=r(53887),k=r.n(S),N=r(31669);class F extends s.BaseCommand{constructor(){super(...arguments),this.json=!1}async execute(){const e=await o.VK.find(this.context.cwd,this.context.plugins),{project:t}=await a.I.find(e,this.context.cwd),r=void 0!==this.fields?new Set(["name",...this.fields.split(/\s*,\s*/)]):null,A=[];let n=!1;const i=await h.Pk.start({configuration:e,includeFooter:!1,json:this.json,stdout:this.context.stdout},async o=>{for(const i of this.packages){let s;if("."===i){const e=t.topLevelWorkspace;if(!e.manifest.name)throw new d.UsageError("Missing 'name' field in "+v().join(e.cwd,"package.json"));s=C.makeDescriptor(e.manifest.name,"unknown")}else s=C.parseDescriptor(i);const a=p.npmHttpUtils.getIdentUrl(s);let c;try{c=K(await p.npmHttpUtils.get(a,{configuration:e,ident:s,jsonResponse:!0}))}catch(e){throw"HTTPError"!==e.name?e:404===e.response.statusCode?new g.lk(l.b.EXCEPTION,"Package not found"):new g.lk(l.b.EXCEPTION,e.toString())}const u=Object.keys(c.versions).sort(k().compareLoose);let h=c["dist-tags"].latest||u[u.length-1];if(k().validRange(s.range)){const t=k().maxSatisfying(u,s.range);null!==t?h=t:(o.reportWarning(l.b.UNNAMED,`Unmet range ${C.prettyRange(e,s.range)}; falling back to the latest version`),n=!0)}else"unknown"!==s.range&&(o.reportWarning(l.b.UNNAMED,`Invalid range ${C.prettyRange(e,s.range)}; falling back to the latest version`),n=!0);const f=c.versions[h],I={...c,...f,version:h,versions:u};let E;if(null!==r){E={};for(const t of r){const r=I[t];void 0!==r?E[t]=r:(o.reportWarning(l.b.EXCEPTION,`The '${t}' field doesn't exist inside ${C.prettyIdent(e,s)}'s informations`),n=!0)}}else this.json||(delete I.dist,delete I.readme,delete I.users),E=I;o.reportJson(E),this.json||A.push(E)}});N.inspect.styles.name="cyan";for(const e of A)(e!==A[0]||n)&&this.context.stdout.write("\n"),this.context.stdout.write((0,N.inspect)(e,{depth:1/0,colors:!0,compact:!1})+"\n");return i.exitCode()}}function K(e){if(Array.isArray(e)){const t=[];for(let r of e)r=K(r),r&&t.push(r);return t}if("object"==typeof e&&null!==e){const t={};for(const r of Object.keys(e)){if(r.startsWith("_"))continue;const A=K(e[r]);A&&(t[r]=A)}return t}return e||null}F.usage=d.Command.Usage({category:"Npm-related commands",description:"show information about a package",details:"\n This command will fetch information about a package from the npm registry, and prints it in a tree format.\n\n The package does not have to be installed locally, but needs to have been published (in particular, local changes will be ignored even for workspaces).\n\n Append `@` to the package argument to provide information specific to the latest version that satisfies the range. If the range is invalid or if there is no version satisfying the range, the command will print a warning and fall back to the latest version.\n\n If the `-f,--fields` option is set, it's a comma-separated list of fields which will be used to only display part of the package informations.\n\n By default, this command won't return the `dist`, `readme`, and `users` fields, since they are often very long. To explicitly request those fields, explicitly list them with the `--fields` flag or request the output in JSON mode.\n ",examples:[["Show all available information about react (except the `dist`, `readme`, and `users` fields)","yarn npm info react"],["Show all available information about react as valid JSON (including the `dist`, `readme`, and `users` fields)","yarn npm info react --json"],["Show all available information about react 16.12.0","yarn npm info react@16.12.0"],["Show the description of react","yarn npm info react --fields description"],["Show all available versions of react","yarn npm info react --fields versions"],["Show the readme of react","yarn npm info react --fields readme"],["Show a few fields of react","yarn npm info react --fields homepage,repository"]]}),(0,i.gn)([d.Command.Rest()],F.prototype,"packages",void 0),(0,i.gn)([d.Command.String("-f,--fields",{description:"A comma-separated list of manifest fields that should be displayed"})],F.prototype,"fields",void 0),(0,i.gn)([d.Command.Boolean("--json",{description:"Format the output as an NDJSON stream"})],F.prototype,"json",void 0),(0,i.gn)([d.Command.Path("npm","info")],F.prototype,"execute",null);var M=r(61899);class R extends s.BaseCommand{constructor(){super(...arguments),this.publish=!1}async execute(){const e=await o.VK.find(this.context.cwd,this.context.plugins),t=await x({configuration:e,cwd:this.context.cwd,publish:this.publish,scope:this.scope});return(await h.Pk.start({configuration:e,stdout:this.context.stdout},async r=>{const A=await async function({registry:e,report:t,stdin:r,stdout:A}){if(process.env.TEST_ENV)return{name:process.env.TEST_NPM_USER||"",password:process.env.TEST_NPM_PASSWORD||""};t.reportInfo(l.b.UNNAMED,"Logging in to "+e);let n=!1;e.match(/^https:\/\/npm\.pkg\.github\.com(\/|$)/)&&(t.reportInfo(l.b.UNNAMED,"You seem to be using the GitHub Package Registry. Tokens must be generated with the 'repo', 'write:packages', and 'read:packages' permissions."),n=!0);t.reportSeparator();const{username:o,password:i}=await(0,M.prompt)([{type:"input",name:"username",message:"Username:",required:!0,onCancel:()=>process.exit(130),stdin:r,stdout:A},{type:"password",name:"password",message:n?"Token:":"Password:",required:!0,onCancel:()=>process.exit(130),stdin:r,stdout:A}]);return t.reportSeparator(),{name:o,password:i}}({registry:t,report:r,stdin:this.context.stdin,stdout:this.context.stdout}),n="/-/user/org.couchdb.user:"+encodeURIComponent(A.name),i=await p.npmHttpUtils.put(n,A,{attemptedAs:A.name,configuration:e,registry:t,jsonResponse:!0,authType:p.npmHttpUtils.AuthType.NO_AUTH});return await async function(e,t,{configuration:r,scope:A}){const n=e=>r=>{const A=f.isIndexableObject(r)?r:{},n=A[e],o=f.isIndexableObject(n)?n:{};return{...A,[e]:{...o,npmAuthToken:t}}},i=A?{npmScopes:n(A)}:{npmRegistries:n(e)};return await o.VK.updateHomeConfiguration(i)}(t,i.token,{configuration:e,scope:this.scope}),r.reportInfo(l.b.UNNAMED,"Successfully logged in")})).exitCode()}}async function x({scope:e,publish:t,configuration:r,cwd:A}){return e&&t?p.npmConfigUtils.getScopeRegistry(e,{configuration:r,type:p.npmConfigUtils.RegistryType.PUBLISH_REGISTRY}):e?p.npmConfigUtils.getScopeRegistry(e,{configuration:r}):t?p.npmConfigUtils.getPublishRegistry((await(0,s.openWorkspace)(r,A)).manifest,{configuration:r}):p.npmConfigUtils.getDefaultRegistry({configuration:r})}R.usage=d.Command.Usage({category:"Npm-related commands",description:"store new login info to access the npm registry",details:"\n This command will ask you for your username, password, and 2FA One-Time-Password (when it applies). It will then modify your local configuration (in your home folder, never in the project itself) to reference the new tokens thus generated.\n\n Adding the `-s,--scope` flag will cause the authentication to be done against whatever registry is configured for the associated scope (see also `npmScopes`).\n\n Adding the `--publish` flag will cause the authentication to be done against the registry used when publishing the package (see also `publishConfig.registry` and `npmPublishRegistry`).\n ",examples:[["Login to the default registry","yarn npm login"],["Login to the registry linked to the @my-scope registry","yarn npm login --scope my-scope"],["Login to the publish registry for the current package","yarn npm login --publish"]]}),(0,i.gn)([d.Command.String("-s,--scope",{description:"Login to the registry configured for a given scope"})],R.prototype,"scope",void 0),(0,i.gn)([d.Command.Boolean("--publish",{description:"Login to the publish registry"})],R.prototype,"publish",void 0),(0,i.gn)([d.Command.Path("npm","login")],R.prototype,"execute",null);const L=new Set(["npmAuthIdent","npmAuthToken"]);class P extends s.BaseCommand{constructor(){super(...arguments),this.publish=!1,this.all=!1}async execute(){const e=await o.VK.find(this.context.cwd,this.context.plugins),t=async()=>{var t;const r=await x({configuration:e,cwd:this.context.cwd,publish:this.publish,scope:this.scope}),A=await o.VK.find(this.context.cwd,this.context.plugins),n=C.makeIdent(null!==(t=this.scope)&&void 0!==t?t:null,"pkg");return!p.npmConfigUtils.getAuthConfiguration(r,{configuration:A,ident:n}).get("npmAuthToken")};return(await h.Pk.start({configuration:e,stdout:this.context.stdout},async r=>{if(this.all&&(await async function(){const e=e=>{let t=!1;const r=f.isIndexableObject(e)?{...e}:{};r.npmAuthToken&&(delete r.npmAuthToken,t=!0);for(const e of Object.keys(r))O(r,e)&&(t=!0);if(0!==Object.keys(r).length)return t?r:e};return await o.VK.updateHomeConfiguration({npmRegistries:e,npmScopes:e})}(),r.reportInfo(l.b.UNNAMED,"Successfully logged out from everything")),this.scope)return await U("npmScopes",this.scope),void(await t()?r.reportInfo(l.b.UNNAMED,"Successfully logged out from "+this.scope):r.reportWarning(l.b.UNNAMED,"Scope authentication settings removed, but some other ones settings still apply to it"));const A=await x({configuration:e,cwd:this.context.cwd,publish:this.publish});await U("npmRegistries",A),await t()?r.reportInfo(l.b.UNNAMED,"Successfully logged out from "+A):r.reportWarning(l.b.UNNAMED,"Registry authentication settings removed, but some other ones settings still apply to it")})).exitCode()}}function O(e,t){const r=e[t];if(!f.isIndexableObject(r))return!1;const A=new Set(Object.keys(r));if([...L].every(e=>!A.has(e)))return!1;for(const e of L)A.delete(e);if(0===A.size)return e[t]=void 0,!0;const n={...r};for(const e of L)delete n[e];return e[t]=n,!0}async function U(e,t){return await o.VK.updateHomeConfiguration({[e]:e=>{const r=f.isIndexableObject(e)?e:{};if(!Object.prototype.hasOwnProperty.call(r,t))return e;const A=r[t],n=f.isIndexableObject(A)?A:{},o=new Set(Object.keys(n));if([...L].every(e=>!o.has(e)))return e;for(const e of L)o.delete(e);if(0===o.size){if(1===Object.keys(r).length)return;return{...r,[t]:void 0}}const i={};for(const e of L)i[e]=void 0;return{...r,[t]:{...n,...i}}}})}P.usage=d.Command.Usage({category:"Npm-related commands",description:"logout of the npm registry",details:"\n This command will log you out by modifying your local configuration (in your home folder, never in the project itself) to delete all credentials linked to a registry.\n\n Adding the `-s,--scope` flag will cause the deletion to be done against whatever registry is configured for the associated scope (see also `npmScopes`).\n\n Adding the `--publish` flag will cause the deletion to be done against the registry used when publishing the package (see also `publishConfig.registry` and `npmPublishRegistry`).\n\n Adding the `-A,--all` flag will cause the deletion to be done against all registries and scopes.\n ",examples:[["Logout of the default registry","yarn npm logout"],["Logout of the @my-scope scope","yarn npm logout --scope my-scope"],["Logout of the publish registry for the current package","yarn npm logout --publish"],["Logout of all registries","yarn npm logout --all"]]}),(0,i.gn)([d.Command.String("-s,--scope",{description:"Logout of the registry configured for a given scope"})],P.prototype,"scope",void 0),(0,i.gn)([d.Command.Boolean("--publish",{description:"Logout of the publish registry"})],P.prototype,"publish",void 0),(0,i.gn)([d.Command.Boolean("-A,--all",{description:"Logout of all registries"})],P.prototype,"all",void 0),(0,i.gn)([d.Command.Path("npm","logout")],P.prototype,"execute",null);var T=r(63088),j=r(49881);class Y extends s.BaseCommand{constructor(){super(...arguments),this.tag="latest",this.tolerateRepublish=!1}async execute(){const e=await o.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await a.I.find(e,this.context.cwd);if(!r)throw new s.WorkspaceRequiredError(t.cwd,this.context.cwd);if(r.manifest.private)throw new d.UsageError("Private workspaces cannot be published");if(null===r.manifest.name||null===r.manifest.version)throw new d.UsageError("Workspaces must have valid names and versions to be published on an external registry");await t.restoreInstallState();const A=r.manifest.name,n=r.manifest.version,i=p.npmConfigUtils.getPublishRegistry(r.manifest,{configuration:e});return(await h.Pk.start({configuration:e,stdout:this.context.stdout},async t=>{if(this.tolerateRepublish)try{const r=await p.npmHttpUtils.get(p.npmHttpUtils.getIdentUrl(A),{configuration:e,registry:i,ident:A,jsonResponse:!0});if(!Object.prototype.hasOwnProperty.call(r,"versions"))throw new g.lk(l.b.REMOTE_INVALID,'Registry returned invalid data for - missing "versions" field');if(Object.prototype.hasOwnProperty.call(r.versions,n))return void t.reportWarning(l.b.UNNAMED,`Registry already knows about version ${n}; skipping.`)}catch(e){if("HTTPError"!==e.name)throw e;if(404!==e.response.statusCode)throw new g.lk(l.b.NETWORK_ERROR,`The remote server answered with HTTP ${e.response.statusCode} ${e.response.statusMessage}`)}await T.maybeExecuteWorkspaceLifecycleScript(r,"prepublish",{report:t}),await j.packUtils.prepareForPack(r,{report:t},async()=>{const n=await j.packUtils.genPackList(r);for(const e of n)t.reportInfo(null,e);const o=await j.packUtils.genPackStream(r,n),s=await f.bufferStream(o),a=await p.npmPublishUtils.makePublishBody(r,s,{access:this.access,tag:this.tag,registry:i});try{await p.npmHttpUtils.put(p.npmHttpUtils.getIdentUrl(A),a,{configuration:e,registry:i,ident:A,jsonResponse:!0})}catch(e){if("HTTPError"!==e.name)throw e;{const r=e.response.body&&e.response.body.error?e.response.body.error:`The remote server answered with HTTP ${e.response.statusCode} ${e.response.statusMessage}`;t.reportError(l.b.NETWORK_ERROR,r)}}}),t.hasErrors()||t.reportInfo(l.b.UNNAMED,"Package archive published")})).exitCode()}}Y.usage=d.Command.Usage({category:"Npm-related commands",description:"publish the active workspace to the npm registry",details:'\n This command will pack the active workspace into a fresh archive and upload it to the npm registry.\n\n The package will by default be attached to the `latest` tag on the registry, but this behavior can be overriden by using the `--tag` option.\n\n Note that for legacy reasons scoped packages are by default published with an access set to `restricted` (aka "private packages"). This requires you to register for a paid npm plan. In case you simply wish to publish a public scoped package to the registry (for free), just add the `--access public` flag. This behavior can be enabled by default through the `npmPublishAccess` settings.\n ',examples:[["Publish the active workspace","yarn npm publish"]]}),(0,i.gn)([d.Command.String("--access",{description:"The access for the published package (public or restricted)"})],Y.prototype,"access",void 0),(0,i.gn)([d.Command.String("--tag",{description:"The tag on the registry that the package should be attached to"})],Y.prototype,"tag",void 0),(0,i.gn)([d.Command.Boolean("--tolerate-republish",{description:"Warn and exit when republishing an already existing version of a package"})],Y.prototype,"tolerateRepublish",void 0),(0,i.gn)([d.Command.Path("npm","publish")],Y.prototype,"execute",null);var G=r(46009);class H extends s.BaseCommand{constructor(){super(...arguments),this.json=!1}async execute(){const e=await o.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await a.I.find(e,this.context.cwd);let A;if(void 0!==this.package)A=C.parseIdent(this.package);else{if(!r)throw new s.WorkspaceRequiredError(t.cwd,this.context.cwd);if(!r.manifest.name)throw new d.UsageError("Missing 'name' field in "+G.y1.join(r.cwd,G.QS.manifest));A=r.manifest.name}const n=await J(A,e),i={children:f.sortMap(Object.entries(n),([e])=>e).map(([e,t])=>({value:I.tuple(I.Type.RESOLUTION,{descriptor:C.makeDescriptor(A,e),locator:C.makeLocator(A,t)})}))};return u.emitTree(i,{configuration:e,json:this.json,stdout:this.context.stdout})}}async function J(e,t){const r=`/-/package${p.npmHttpUtils.getIdentUrl(e)}/dist-tags`;return p.npmHttpUtils.get(r,{configuration:t,ident:e,jsonResponse:!0}).catch(e=>{throw"HTTPError"!==e.name?e:404===e.response.statusCode?new g.lk(l.b.EXCEPTION,"Package not found"):new g.lk(l.b.EXCEPTION,e.toString())})}H.usage=d.Command.Usage({category:"Npm-related commands",description:"list all dist-tags of a package",details:"\n This command will list all tags of a package from the npm registry.\n\n If the package is not specified, Yarn will default to the current workspace.\n ",examples:[["List all tags of package `my-pkg`","yarn npm tag list my-pkg"]]}),(0,i.gn)([d.Command.String({required:!1})],H.prototype,"package",void 0),(0,i.gn)([d.Command.Boolean("--json",{description:"Format the output as an NDJSON stream"})],H.prototype,"json",void 0),(0,i.gn)([d.Command.Path("npm","tag","list")],H.prototype,"execute",null);class q extends s.BaseCommand{async execute(){const e=await o.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await a.I.find(e,this.context.cwd);if(!r)throw new s.WorkspaceRequiredError(t.cwd,this.context.cwd);const A=C.parseDescriptor(this.package,!0),n=A.range;if(!k().valid(n))throw new d.UsageError(`The range ${I.pretty(e,A.range,I.Type.RANGE)} must be a valid semver version`);const i=p.npmConfigUtils.getPublishRegistry(r.manifest,{configuration:e}),c=I.pretty(e,A,I.Type.IDENT),g=I.pretty(e,n,I.Type.RANGE),u=I.pretty(e,this.tag,I.Type.CODE);return(await h.Pk.start({configuration:e,stdout:this.context.stdout},async t=>{const r=await J(A,e);Object.prototype.hasOwnProperty.call(r,this.tag)&&r[this.tag]===n&&t.reportWarning(l.b.UNNAMED,`Tag ${u} is already set to version ${g}`);try{const t=`/-/package${p.npmHttpUtils.getIdentUrl(A)}/dist-tags/${encodeURIComponent(this.tag)}`;await p.npmHttpUtils.put(t,n,{configuration:e,registry:i,ident:A,jsonRequest:!0,jsonResponse:!0})}catch(e){if("HTTPError"!==e.name)throw e;{const r=e.response.body&&e.response.body.error?e.response.body.error:`The remote server answered with HTTP ${e.response.statusCode} ${e.response.statusMessage}`;t.reportError(l.b.NETWORK_ERROR,r)}}t.hasErrors()||t.reportInfo(l.b.UNNAMED,`Tag ${u} added to version ${g} of package ${c}`)})).exitCode()}}q.usage=d.Command.Usage({category:"Npm-related commands",description:"add a tag for a specific version of a package",details:"\n This command will add a tag to the npm registry for a specific version of a package. If the tag already exists, it will be overwritten.\n ",examples:[["Add a `beta` tag for version `2.3.4-beta.4` of package `my-pkg`","yarn npm tag add my-pkg@2.3.4-beta.4 beta"]]}),(0,i.gn)([d.Command.String()],q.prototype,"package",void 0),(0,i.gn)([d.Command.String()],q.prototype,"tag",void 0),(0,i.gn)([d.Command.Path("npm","tag","add")],q.prototype,"execute",null);var z=r(15966);class W extends s.BaseCommand{async execute(){const e=await o.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await a.I.find(e,this.context.cwd);if(!r)throw new s.WorkspaceRequiredError(t.cwd,this.context.cwd);const A=C.parseIdent(this.package),n=p.npmConfigUtils.getPublishRegistry(r.manifest,{configuration:e}),i=I.pretty(e,this.tag,I.Type.CODE),c=I.pretty(e,A,I.Type.IDENT),g=await J(A,e);if(!Object.prototype.hasOwnProperty.call(g,this.tag))throw new d.UsageError(`${i} is not a tag of package ${c}`);return(await h.Pk.start({configuration:e,stdout:this.context.stdout},async t=>{try{const t=`/-/package${p.npmHttpUtils.getIdentUrl(A)}/dist-tags/${encodeURIComponent(this.tag)}`;await p.npmHttpUtils.del(t,{configuration:e,registry:n,ident:A,jsonResponse:!0})}catch(e){if("HTTPError"!==e.name)throw e;{const r=e.response.body&&e.response.body.error?e.response.body.error:`The remote server answered with HTTP ${e.response.statusCode} ${e.response.statusMessage}`;t.reportError(l.b.NETWORK_ERROR,r)}}t.hasErrors()||t.reportInfo(l.b.UNNAMED,`Tag ${i} removed from package ${c}`)})).exitCode()}}W.schema=z.object().shape({tag:z.string().notOneOf(["latest"])}),W.usage=d.Command.Usage({category:"Npm-related commands",description:"remove a tag from a package",details:"\n This command will remove a tag from a package from the npm registry.\n ",examples:[["Remove the `beta` tag from package `my-pkg`","yarn npm tag remove my-pkg beta"]]}),(0,i.gn)([d.Command.String()],W.prototype,"package",void 0),(0,i.gn)([d.Command.String()],W.prototype,"tag",void 0),(0,i.gn)([d.Command.Path("npm","tag","remove")],W.prototype,"execute",null);class V extends s.BaseCommand{constructor(){super(...arguments),this.publish=!1}async execute(){const e=await o.VK.find(this.context.cwd,this.context.plugins);let t;t=this.scope&&this.publish?p.npmConfigUtils.getScopeRegistry(this.scope,{configuration:e,type:p.npmConfigUtils.RegistryType.PUBLISH_REGISTRY}):this.scope?p.npmConfigUtils.getScopeRegistry(this.scope,{configuration:e}):this.publish?p.npmConfigUtils.getPublishRegistry((await(0,s.openWorkspace)(e,this.context.cwd)).manifest,{configuration:e}):p.npmConfigUtils.getDefaultRegistry({configuration:e});return(await h.Pk.start({configuration:e,stdout:this.context.stdout},async r=>{try{const A=await p.npmHttpUtils.get("/-/whoami",{configuration:e,registry:t,authType:p.npmHttpUtils.AuthType.ALWAYS_AUTH,jsonResponse:!0,ident:this.scope?C.makeIdent(this.scope,""):void 0});r.reportInfo(l.b.UNNAMED,A.username)}catch(e){if("HTTPError"!==e.name)throw e;401===e.response.statusCode||403===e.response.statusCode?r.reportError(l.b.AUTHENTICATION_INVALID,"Authentication failed - your credentials may have expired"):r.reportError(l.b.AUTHENTICATION_INVALID,e.toString())}})).exitCode()}}V.usage=d.Command.Usage({category:"Npm-related commands",description:"display the name of the authenticated user",details:"\n Print the username associated with the current authentication settings to the standard output.\n\n When using `-s,--scope`, the username printed will be the one that matches the authentication settings of the registry associated with the given scope (those settings can be overriden using the `npmRegistries` map, and the registry associated with the scope is configured via the `npmScopes` map).\n\n When using `--publish`, the registry we'll select will by default be the one used when publishing packages (`publishConfig.registry` or `npmPublishRegistry` if available, otherwise we'll fallback to the regular `npmRegistryServer`).\n ",examples:[["Print username for the default registry","yarn npm whoami"],["Print username for the registry on a given scope","yarn npm whoami --scope company"]]}),(0,i.gn)([d.Command.String("-s,--scope",{description:"Print username for the registry configured for a given scope"})],V.prototype,"scope",void 0),(0,i.gn)([d.Command.Boolean("--publish",{description:"Print username for the publish registry"})],V.prototype,"publish",void 0),(0,i.gn)([d.Command.Path("npm","whoami")],V.prototype,"execute",null);const X={configuration:{npmPublishAccess:{description:"Default access of the published packages",type:o.a2.STRING,default:null}},commands:[D,F,R,P,Y,q,H,W,V]}},14224:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>W,npmConfigUtils:()=>A,npmHttpUtils:()=>n,npmPublishUtils:()=>o});var A={};r.r(A),r.d(A,{RegistryType:()=>l,getAuthConfiguration:()=>Q,getDefaultRegistry:()=>y,getPublishRegistry:()=>E,getRegistryConfiguration:()=>m,getScopeConfiguration:()=>w,getScopeRegistry:()=>B,normalizeRegistry:()=>I});var n={};r.r(n),r.d(n,{AuthType:()=>u,del:()=>N,get:()=>v,getIdentUrl:()=>b,handleInvalidAuthenticationError:()=>D,post:()=>S,put:()=>k});var o={};r.r(o),r.d(o,{makePublishBody:()=>J});var i=r(39922),s=r(54143),a=r(72785),c=r(53887),g=r.n(c);var l,u,h=r(79669),p=r(35691),d=r(92659),C=r(61899),f=r(78835);function I(e){return e.replace(/\/$/,"")}function E(e,{configuration:t}){return e.publishConfig&&e.publishConfig.registry?I(e.publishConfig.registry):e.name?B(e.name.scope,{configuration:t,type:l.PUBLISH_REGISTRY}):y({configuration:t,type:l.PUBLISH_REGISTRY})}function B(e,{configuration:t,type:r=l.FETCH_REGISTRY}){const A=w(e,{configuration:t});if(null===A)return y({configuration:t,type:r});const n=A.get(r);return null===n?y({configuration:t,type:r}):I(n)}function y({configuration:e,type:t=l.FETCH_REGISTRY}){const r=e.get(t);return I(null!==r?r:e.get(l.FETCH_REGISTRY))}function m(e,{configuration:t}){const r=t.get("npmRegistries"),A=r.get(e);if(void 0!==A)return A;const n=r.get(e.replace(/^[a-z]+:/,""));return void 0!==n?n:null}function w(e,{configuration:t}){if(null===e)return null;const r=t.get("npmScopes").get(e);return r||null}function Q(e,{configuration:t,ident:r}){const A=r&&w(r.scope,{configuration:t});if((null==A?void 0:A.get("npmAuthIdent"))||(null==A?void 0:A.get("npmAuthToken")))return A;return m(e,{configuration:t})||t}async function D(e,{attemptedAs:t,registry:r,headers:A,configuration:n}){if("HTTPError"===e.name&&401===e.response.statusCode)throw new p.lk(d.b.AUTHENTICATION_INVALID,`Invalid authentication (${"string"!=typeof t?"as "+await async function(e,t,{configuration:r}){var A;if(void 0===t||void 0===t.authorization)return"an anonymous user";try{const n=await h.get(new f.URL(e+"/-/whoami").href,{configuration:r,headers:t,jsonResponse:!0});return null!==(A=n.username)&&void 0!==A?A:"an unknown user"}catch(e){return"an unknown user"}}(r,A,{configuration:n}):"attempted as "+t})`)}function b(e){return e.scope?`/@${e.scope}%2f${e.name}`:"/"+e.name}async function v(e,{configuration:t,headers:r,ident:A,authType:n,registry:o,...i}){if(A&&void 0===o&&(o=B(A.scope,{configuration:t})),A&&A.scope&&void 0===n&&(n=u.BEST_EFFORT),"string"!=typeof o)throw new Error("Assertion failed: The registry should be a string");const s=F(o,{authType:n,configuration:t,ident:A});let a;s&&(r={...r,authorization:s});try{a=new f.URL(e)}catch(t){a=new f.URL(o+e)}try{return await h.get(a.href,{configuration:t,headers:r,...i})}catch(e){throw await D(e,{registry:o,configuration:t,headers:r}),e}}async function S(e,t,{attemptedAs:r,configuration:A,headers:n,ident:o,authType:i=u.ALWAYS_AUTH,registry:s,...a}){if(o&&void 0===s&&(s=B(o.scope,{configuration:A})),"string"!=typeof s)throw new Error("Assertion failed: The registry should be a string");const c=F(s,{authType:i,configuration:A,ident:o});c&&(n={...n,authorization:c});try{return await h.post(s+e,t,{configuration:A,headers:n,...a})}catch(o){if(!M(o))throw await D(o,{attemptedAs:r,registry:s,configuration:A,headers:n}),o;const i=await K(),c={...n,...R(i)};try{return await h.post(`${s}${e}`,t,{configuration:A,headers:c,...a})}catch(e){throw await D(e,{attemptedAs:r,registry:s,configuration:A,headers:n}),e}}}async function k(e,t,{attemptedAs:r,configuration:A,headers:n,ident:o,authType:i=u.ALWAYS_AUTH,registry:s,...a}){if(o&&void 0===s&&(s=B(o.scope,{configuration:A})),"string"!=typeof s)throw new Error("Assertion failed: The registry should be a string");const c=F(s,{authType:i,configuration:A,ident:o});c&&(n={...n,authorization:c});try{return await h.put(s+e,t,{configuration:A,headers:n,...a})}catch(o){if(!M(o))throw await D(o,{attemptedAs:r,registry:s,configuration:A,headers:n}),o;const i=await K(),c={...n,...R(i)};try{return await h.put(`${s}${e}`,t,{configuration:A,headers:c,...a})}catch(e){throw await D(e,{attemptedAs:r,registry:s,configuration:A,headers:n}),e}}}async function N(e,{attemptedAs:t,configuration:r,headers:A,ident:n,authType:o=u.ALWAYS_AUTH,registry:i,...s}){if(n&&void 0===i&&(i=B(n.scope,{configuration:r})),"string"!=typeof i)throw new Error("Assertion failed: The registry should be a string");const a=F(i,{authType:o,configuration:r,ident:n});a&&(A={...A,authorization:a});try{return await h.del(i+e,{configuration:r,headers:A,...s})}catch(n){if(!M(n))throw await D(n,{attemptedAs:t,registry:i,configuration:r,headers:A}),n;const o=await K(),a={...A,...R(o)};try{return await h.del(`${i}${e}`,{configuration:r,headers:a,...s})}catch(e){throw await D(e,{attemptedAs:t,registry:i,configuration:r,headers:A}),e}}}function F(e,{authType:t=u.CONFIGURATION,configuration:r,ident:A}){const n=Q(e,{configuration:r,ident:A}),o=function(e,t){switch(t){case u.CONFIGURATION:return e.get("npmAlwaysAuth");case u.BEST_EFFORT:case u.ALWAYS_AUTH:return!0;case u.NO_AUTH:return!1;default:throw new Error("Unreachable")}}(n,t);if(!o)return null;if(n.get("npmAuthToken"))return"Bearer "+n.get("npmAuthToken");if(n.get("npmAuthIdent"))return"Basic "+n.get("npmAuthIdent");if(o&&t!==u.BEST_EFFORT)throw new p.lk(d.b.AUTHENTICATION_NOT_FOUND,"No authentication configured for request");return null}async function K(){if(process.env.TEST_ENV)return process.env.TEST_NPM_2FA_TOKEN||"";const{otp:e}=await(0,C.prompt)({type:"password",name:"otp",message:"One-time password:",required:!0,onCancel:()=>process.exit(130)});return e}function M(e){if("HTTPError"!==e.name)return!1;try{return e.response.headers["www-authenticate"].split(/,\s*/).map(e=>e.toLowerCase()).includes("otp")}catch(e){return!1}}function R(e){return{"npm-otp":e}}!function(e){e.FETCH_REGISTRY="npmRegistryServer",e.PUBLISH_REGISTRY="npmPublishRegistry"}(l||(l={})),function(e){e[e.NO_AUTH=0]="NO_AUTH",e[e.BEST_EFFORT=1]="BEST_EFFORT",e[e.CONFIGURATION=2]="CONFIGURATION",e[e.ALWAYS_AUTH=3]="ALWAYS_AUTH"}(u||(u={}));class x{supports(e,t){if(!e.reference.startsWith("npm:"))return!1;const r=new f.URL(e.reference);return!!g().valid(r.pathname)&&!r.searchParams.has("__archiveUrl")}getLocalPath(e,t){return null}async fetch(e,t){const r=t.checksums.get(e.locatorHash)||null,[A,n,o]=await t.cache.fetchPackageFromCache(e,r,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,s.prettyLocator(t.project.configuration,e)+" can't be found in the cache and will be fetched from the remote registry"),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck});return{packageFs:A,releaseFs:n,prefixPath:s.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,t){let r;try{r=await v(x.getLocatorUrl(e),{configuration:t.project.configuration,ident:e})}catch(A){r=await v(x.getLocatorUrl(e).replace(/%2f/g,"/"),{configuration:t.project.configuration,ident:e})}return await a.convertToZip(r,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:s.getIdentVendorPath(e),stripComponents:1})}static isConventionalTarballUrl(e,t,{configuration:r}){let A=B(e.scope,{configuration:r});const n=x.getLocatorUrl(e);return t=t.replace(/^https?:(\/\/(?:[^/]+\.)?npmjs.org(?:$|\/))/,"https:$1"),A=A.replace(/^https:\/\/registry\.npmjs\.org($|\/)/,"https://registry.yarnpkg.com$1"),(t=t.replace(/^https:\/\/registry\.npmjs\.org($|\/)/,"https://registry.yarnpkg.com$1"))===A+n||t===A+n.replace(/%2f/g,"/")}static getLocatorUrl(e){const t=g().clean(e.reference.slice("npm:".length));if(null===t)throw new p.lk(d.b.RESOLVER_NOT_FOUND,"The npm semver resolver got selected, but the version isn't semver");return`${b(e)}/-/${e.name}-${t}.tgz`}}var L=r(46611),P=r(36545),O=r(32485);const U=s.makeIdent(null,"node-gyp"),T=/\b(node-gyp|prebuild-install)\b/;var j=r(52779);var Y=r(49881),G=r(76417),H=r(10129);async function J(e,t,{access:r,tag:A,registry:n}){const o=e.project.configuration,i=e.manifest.name,a=e.manifest.version,c=s.stringifyIdent(i),g=(0,G.createHash)("sha1").update(t).digest("hex"),l=H.Sd(t).toString();void 0===r&&(r=e.manifest.publishConfig&&"string"==typeof e.manifest.publishConfig.access?e.manifest.publishConfig.access:null!==o.get("npmPublishAccess")?o.get("npmPublishAccess"):i.scope?"restricted":"public");const u=await Y.packUtils.genPackageManifest(e),h=`${c}-${a}.tgz`,p=new f.URL(`${c}/-/${h}`,n);return{_id:c,_attachments:{[h]:{content_type:"application/octet-stream",data:t.toString("base64"),length:t.length}},name:c,access:r,"dist-tags":{[A]:a},versions:{[a]:{...u,_id:`${c}@${a}`,name:c,version:a,dist:{shasum:g,integrity:l,tarball:p.toString()}}}}}const q={npmAlwaysAuth:{description:"URL of the selected npm registry (note: npm enterprise isn't supported)",type:i.a2.BOOLEAN,default:!1},npmAuthIdent:{description:"Authentication identity for the npm registry (_auth in npm and yarn v1)",type:i.a2.SECRET,default:null},npmAuthToken:{description:"Authentication token for the npm registry (_authToken in npm and yarn v1)",type:i.a2.SECRET,default:null}},z={npmPublishRegistry:{description:"Registry to push packages to",type:i.a2.STRING,default:null},npmRegistryServer:{description:"URL of the selected npm registry (note: npm enterprise isn't supported)",type:i.a2.STRING,default:"https://registry.yarnpkg.com"}},W={configuration:{...q,...z,npmScopes:{description:"Settings per package scope",type:i.a2.MAP,valueDefinition:{description:"",type:i.a2.SHAPE,properties:{...q,...z}}},npmRegistries:{description:"Settings per registry",type:i.a2.MAP,normalizeKeys:I,valueDefinition:{description:"",type:i.a2.SHAPE,properties:{...q}}}},fetchers:[class{supports(e,t){if(!e.reference.startsWith("npm:"))return!1;const{selector:r,params:A}=s.parseRange(e.reference);return!!g().valid(r)&&(null!==A&&"string"==typeof A.__archiveUrl)}getLocalPath(e,t){return null}async fetch(e,t){const r=t.checksums.get(e.locatorHash)||null,[A,n,o]=await t.cache.fetchPackageFromCache(e,r,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,s.prettyLocator(t.project.configuration,e)+" can't be found in the cache and will be fetched from the remote server"),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck});return{packageFs:A,releaseFs:n,prefixPath:s.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,t){const{params:r}=s.parseRange(e.reference);if(null===r||"string"!=typeof r.__archiveUrl)throw new Error("Assertion failed: The archiveUrl querystring parameter should have been available");const A=await v(r.__archiveUrl,{configuration:t.project.configuration,ident:e});return await a.convertToZip(A,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:s.getIdentVendorPath(e),stripComponents:1})}},x],resolvers:[class{supportsDescriptor(e,t){return!!e.range.startsWith("npm:")&&!!s.tryParseDescriptor(e.range.slice("npm:".length),!0)}supportsLocator(e,t){return!1}shouldPersistResolution(e,t){throw new Error("Unreachable")}bindDescriptor(e,t,r){return e}getResolutionDependencies(e,t){const r=s.parseDescriptor(e.range.slice("npm:".length),!0);return t.resolver.getResolutionDependencies(r,t)}async getCandidates(e,t,r){const A=s.parseDescriptor(e.range.slice("npm:".length),!0);return await r.resolver.getCandidates(A,t,r)}async getSatisfying(e,t,r){const A=s.parseDescriptor(e.range.slice("npm:".length),!0);return r.resolver.getSatisfying(A,t,r)}resolve(e,t){throw new Error("Unreachable")}},class{supportsDescriptor(e,t){return!!e.range.startsWith("npm:")&&!!P.validRange(e.range.slice("npm:".length))}supportsLocator(e,t){if(!e.reference.startsWith("npm:"))return!1;const{selector:r}=s.parseRange(e.reference);return!!g().valid(r)}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,r){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,r){const A=P.validRange(e.range.slice("npm:".length));if(null===A)throw new Error("Expected a valid range, got "+e.range.slice("npm:".length));const n=await v(b(e),{configuration:r.project.configuration,ident:e,jsonResponse:!0}),o=Object.keys(n.versions).map(e=>new(g().SemVer)(e)).filter(e=>A.test(e)),i=o.filter(e=>!n.versions[e.raw].deprecated),a=i.length>0?i:o;return a.sort((e,t)=>-e.compare(t)),a.map(t=>{const A=s.makeLocator(e,"npm:"+t.raw),o=n.versions[t.raw].dist.tarball;return x.isConventionalTarballUrl(A,o,{configuration:r.project.configuration})?A:s.bindLocator(A,{__archiveUrl:o})})}async getSatisfying(e,t,r){const A=P.validRange(e.range.slice("npm:".length));if(null===A)throw new Error("Expected a valid range, got "+e.range.slice("npm:".length));return t.map(e=>{try{return new(g().SemVer)(e.slice("npm:".length))}catch(e){return null}}).filter(e=>null!==e).filter(e=>A.test(e)).sort((e,t)=>-e.compare(t)).map(t=>s.makeLocator(e,"npm:"+t.raw))}async resolve(e,t){const{selector:r}=s.parseRange(e.reference),A=g().clean(r);if(null===A)throw new p.lk(d.b.RESOLVER_NOT_FOUND,"The npm semver resolver got selected, but the version isn't semver");const n=await v(b(e),{configuration:t.project.configuration,ident:e,jsonResponse:!0});if(!Object.prototype.hasOwnProperty.call(n,"versions"))throw new p.lk(d.b.REMOTE_INVALID,'Registry returned invalid data for - missing "versions" field');if(!Object.prototype.hasOwnProperty.call(n.versions,A))throw new p.lk(d.b.REMOTE_NOT_FOUND,`Registry failed to return reference "${A}"`);const o=new L.G;if(o.load(n.versions[A]),!o.dependencies.has(U.identHash)&&!o.peerDependencies.has(U.identHash))for(const r of o.scripts.values())if(r.match(T)){o.dependencies.set(U.identHash,s.makeDescriptor(U,"latest")),t.report.reportWarning(d.b.NODE_GYP_INJECTED,s.prettyLocator(t.project.configuration,e)+": Implicit dependencies on node-gyp are discouraged");break}return"string"==typeof o.raw.deprecated&&t.report.reportWarning(d.b.DEPRECATED_PACKAGE,`${s.prettyLocator(t.project.configuration,e)} is deprecated: ${o.raw.deprecated}`),{...e,version:A,languageName:"node",linkType:O.Un.HARD,dependencies:o.dependencies,peerDependencies:o.peerDependencies,dependenciesMeta:o.dependenciesMeta,peerDependenciesMeta:o.peerDependenciesMeta,bin:o.bin}}},class{supportsDescriptor(e,t){return!!e.range.startsWith("npm:")&&!!j.c.test(e.range.slice("npm:".length))}supportsLocator(e,t){return!1}shouldPersistResolution(e,t){throw new Error("Unreachable")}bindDescriptor(e,t,r){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,r){const A=e.range.slice("npm:".length),n=await v(b(e),{configuration:r.project.configuration,ident:e,jsonResponse:!0});if(!Object.prototype.hasOwnProperty.call(n,"dist-tags"))throw new p.lk(d.b.REMOTE_INVALID,'Registry returned invalid data - missing "dist-tags" field');const o=n["dist-tags"];if(!Object.prototype.hasOwnProperty.call(o,A))throw new p.lk(d.b.REMOTE_NOT_FOUND,`Registry failed to return tag "${A}"`);const i=o[A],a=s.makeLocator(e,"npm:"+i),c=n.versions[i].dist.tarball;return x.isConventionalTarballUrl(a,c,{configuration:r.project.configuration})?[a]:[s.bindLocator(a,{__archiveUrl:c})]}async getSatisfying(e,t,r){return null}async resolve(e,t){throw new Error("Unreachable")}}]}},49881:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>T,packUtils:()=>A});var A={};r.r(A),r.d(A,{genPackList:()=>K,genPackStream:()=>N,genPackageManifest:()=>F,hasPackScripts:()=>S,prepareForPack:()=>k});var n=r(54143),o=r(35691),i=r(92659),s=r(36370),a=r(40822);class c extends a.Command{}(0,s.gn)([a.Command.String("--cwd",{hidden:!0})],c.prototype,"cwd",void 0);var g=r(46611),l=r(46009);class u extends a.UsageError{constructor(e,t){super(`This command can only be run from within a workspace of your project (${l.y1.relative(e,t)} isn't a workspace of ${l.y1.join(e,g.G.fileName)}).`)}}r(63129),r(5864),r(35747);new Map([["constraints",[["constraints","query"],["constraints","source"],["constraints"]]],["exec",[]],["interactive-tools",[["search"],["upgrade-interactive"]]],["stage",[["stage"]]],["typescript",[]],["version",[["version","apply"],["version","check"],["version"]]],["workspace-tools",[["workspaces","focus"],["workspaces","foreach"]]]]);var h=r(71643),p=r(39922);(0,s.gn)([a.Command.Path("--welcome")],class extends c{async execute(){const e=await p.VK.find(this.context.cwd,this.context.plugins);this.context.stdout.write((e=>`\n${h.pretty(e,"Welcome on Yarn 2!","bold")} 🎉 Thanks for helping us shape our vision of how projects\nshould be managed going forward.\n\nBeing still in RC, Yarn 2 isn't completely stable yet. Some features might be\nmissing, and some behaviors may have received major overhaul. In case of doubt,\nuse the following URLs to get some insight:\n\n - The changelog:\n ${h.pretty(e,"https://github.com/yarnpkg/berry/tree/CHANGELOG.md","cyan")}\n\n - Our issue tracker:\n ${h.pretty(e,"https://github.com/yarnpkg/berry","cyan")}\n\n - Our Discord server:\n ${h.pretty(e,"https://discord.gg/yarnpkg","cyan")}\n\nWe're hoping you will enjoy the experience. For now, a good start is to run\nthe two following commands:\n\n ${h.pretty(e,"find . -name node_modules -prune -exec rm -r {} \\;","magenta")}\n ${h.pretty(e,"yarn install","magenta")}\n\nOne last trick! If you need at some point to upgrade Yarn to a nightly build,\nthe following command will install the CLI straight from master:\n\n ${h.pretty(e,"yarn set version from sources","magenta")}\n\nSee you later 👋\n`)(e).trim()+"\n")}}.prototype,"execute",null);var d=r(85824),C=r(28148),f=r(33720),I=r(15815),E=r(43896),B=r(63088),y=r(10489),m=r(2401),w=r.n(m),Q=r(59938),D=r(78761);const b=["/package.json","/readme","/readme.*","/license","/license.*","/licence","/licence.*","/changelog","/changelog.*"],v=["/package.tgz",".github",".git",".hg","node_modules",".npmignore",".gitignore",".#*",".DS_Store"];async function S(e){return!!B.hasWorkspaceScript(e,"prepack")||!!B.hasWorkspaceScript(e,"postpack")}async function k(e,{report:t},r){await B.maybeExecuteWorkspaceLifecycleScript(e,"prepack",{report:t});try{await r()}finally{await B.maybeExecuteWorkspaceLifecycleScript(e,"postpack",{report:t})}}async function N(e,t){var r,A;void 0===t&&(t=await K(e));const n=new Set;for(const t of null!==(A=null===(r=e.manifest.publishConfig)||void 0===r?void 0:r.executableFiles)&&void 0!==A?A:new Set)n.add(l.y1.normalize(t));for(const t of e.manifest.bin.values())n.add(l.y1.normalize(t));const o=Q.pack();process.nextTick(async()=>{for(const r of t){const t=l.y1.normalize(r),A=l.y1.resolve(e.cwd,t),i=l.y1.join("package",t),s=await E.xfs.lstatPromise(A),a={name:i,mtime:new Date(3155328e5)},c=n.has(t)?493:420;let g,u;const h=new Promise((e,t)=>{g=e,u=t}),p=e=>{e?u(e):g()};if(s.isFile()){let r;r="package.json"===t?Buffer.from(JSON.stringify(await F(e),null,2)):await E.xfs.readFilePromise(A),o.entry({...a,mode:c,type:"file"},r,p)}else s.isSymbolicLink()?o.entry({...a,mode:c,type:"symlink",linkname:await E.xfs.readlinkPromise(A)},p):p(new Error(`Unsupported file type ${s.mode} for ${l.cS.fromPortablePath(t)}`));await h}o.finalize()});const i=(0,D.createGzip)();return o.pipe(i),i}async function F(e){const t=JSON.parse(JSON.stringify(e.manifest.raw));return await e.project.configuration.triggerHook(e=>e.beforeWorkspacePacking,e,t),t}async function K(e){var t,r,A,n,o,i,s,a;const c=e.project,g=c.configuration,u={accept:[],reject:[]};for(const e of v)u.reject.push(e);for(const e of b)u.accept.push(e);u.reject.push(g.get("rcFilename"));const h=t=>{if(null===t||!t.startsWith(e.cwd+"/"))return;const r=l.y1.relative(e.cwd,t),A=l.y1.resolve(l.LZ.root,r);u.reject.push(A)};h(l.y1.resolve(c.cwd,g.get("lockfileFilename"))),h(g.get("bstatePath")),h(g.get("cacheFolder")),h(g.get("globalFolder")),h(g.get("installStatePath")),h(g.get("virtualFolder")),h(g.get("yarnPath")),await g.triggerHook(e=>e.populateYarnPaths,c,e=>{h(e)});for(const t of c.workspaces){const r=l.y1.relative(e.cwd,t.cwd);""===r||r.match(/^(\.\.)?\//)||u.reject.push("/"+r)}const p={accept:[],reject:[]},d=null!==(r=null===(t=e.manifest.publishConfig)||void 0===t?void 0:t.main)&&void 0!==r?r:e.manifest.main,C=null!==(n=null===(A=e.manifest.publishConfig)||void 0===A?void 0:A.module)&&void 0!==n?n:e.manifest.module,f=null!==(i=null===(o=e.manifest.publishConfig)||void 0===o?void 0:o.browser)&&void 0!==i?i:e.manifest.browser,I=null!==(a=null===(s=e.manifest.publishConfig)||void 0===s?void 0:s.bin)&&void 0!==a?a:e.manifest.bin;null!=d&&p.accept.push(l.y1.resolve(l.LZ.root,d)),null!=C&&p.accept.push(l.y1.resolve(l.LZ.root,C)),"string"==typeof f&&p.accept.push(l.y1.resolve(l.LZ.root,f));for(const e of I.values())p.accept.push(l.y1.resolve(l.LZ.root,e));if(f instanceof Map)for(const[e,t]of f.entries())p.accept.push(l.y1.resolve(l.LZ.root,e)),"string"==typeof t&&p.accept.push(l.y1.resolve(l.LZ.root,t));const E=null!==e.manifest.files;if(E){p.reject.push("/*");for(const t of e.manifest.files)R(p.accept,t,{cwd:l.LZ.root})}return await async function(e,{hasExplicitFileList:t,globalList:r,ignoreList:A}){const n=[],o=new y.n(e),i=[[l.LZ.root,[A]]];for(;i.length>0;){const[e,A]=i.pop(),s=await o.lstatPromise(e);if(!x(e,{globalList:r,ignoreLists:s.isDirectory()?null:A}))if(s.isDirectory()){const n=await o.readdirPromise(e);let s=!1,a=!1;if(!t||e!==l.LZ.root)for(const e of n)s=s||".gitignore"===e,a=a||".npmignore"===e;const c=a?await M(o,e,".npmignore"):s?await M(o,e,".gitignore"):null;let g=null!==c?[c].concat(A):A;x(e,{globalList:r,ignoreLists:A})&&(g=[...A,{accept:[],reject:["**/*"]}]);for(const t of n)i.push([l.y1.resolve(e,t),g])}else(s.isFile()||s.isSymbolicLink())&&n.push(l.y1.relative(l.LZ.root,e))}return n.sort()}(e.cwd,{hasExplicitFileList:E,globalList:u,ignoreList:p})}async function M(e,t,r){const A={accept:[],reject:[]},n=await e.readFilePromise(l.y1.join(t,r),"utf8");for(const e of n.split(/\n/g))R(A.reject,e,{cwd:t});return A}function R(e,t,{cwd:r}){const A=t.trim();""!==A&&"#"!==A[0]&&e.push(function(e,{cwd:t}){const r="!"===e[0];return r&&(e=e.slice(1)),e.match(/\.{0,1}\//)&&(e=l.y1.resolve(t,e)),r&&(e="!"+e),e}(A,{cwd:r}))}function x(e,{globalList:t,ignoreLists:r}){if(L(e,t.accept))return!1;if(L(e,t.reject))return!0;if(null!==r)for(const t of r){if(L(e,t.accept))return!1;if(L(e,t.reject))return!0}return!1}function L(e,t){let r=t;const A=[];for(let e=0;e{await k(r,{report:t},async()=>{t.reportJson({base:r.cwd});const e=await K(r);for(const r of e)t.reportInfo(null,r),t.reportJson({location:r});if(!this.dryRun){const t=await N(r,e),n=E.xfs.createWriteStream(A);t.pipe(n),await new Promise(e=>{n.on("finish",e)})}}),this.dryRun||(t.reportInfo(i.b.UNNAMED,"Package archive generated in "+h.pretty(e,A,h.Type.PATH)),t.reportJson({output:A}))})).exitCode()}}O.usage=a.Command.Usage({description:"generate a tarball from the active workspace",details:"\n This command will turn the active workspace into a compressed archive suitable for publishing. The archive will by default be stored at the root of the workspace (`package.tgz`).\n\n If the `-o,---out` is set the archive will be created at the specified path. The `%s` and `%v` variables can be used within the path and will be respectively replaced by the package name and version.\n ",examples:[["Create an archive from the active workspace","yarn pack"],["List the files that would be made part of the workspace's archive","yarn pack --dry-run"],["Name and output the archive in a dedicated folder","yarn pack --out /artifacts/%s-%v.tgz"]]}),(0,s.gn)([a.Command.Boolean("--install-if-needed",{description:"Run a preliminary `yarn install` if the package contains build scripts"})],O.prototype,"installIfNeeded",void 0),(0,s.gn)([a.Command.Boolean("-n,--dry-run",{description:"Print the file paths without actually generating the package archive"})],O.prototype,"dryRun",void 0),(0,s.gn)([a.Command.Boolean("--json",{description:"Format the output as an NDJSON stream"})],O.prototype,"json",void 0),(0,s.gn)([a.Command.String("--filename",{hidden:!1,description:"Create the archive at the specified path"}),a.Command.String("-o,--out",{description:"Create the archive at the specified path"})],O.prototype,"out",void 0),(0,s.gn)([a.Command.Path("pack")],O.prototype,"execute",null);const U=["dependencies","devDependencies","peerDependencies"],T={hooks:{beforeWorkspacePacking:(e,t)=>{t.publishConfig&&(t.publishConfig.main&&(t.main=t.publishConfig.main),t.publishConfig.browser&&(t.browser=t.publishConfig.browser),t.publishConfig.module&&(t.module=t.publishConfig.module),t.publishConfig.browser&&(t.browser=t.publishConfig.browser),t.publishConfig.bin&&(t.bin=t.publishConfig.bin));const r=e.project;for(const A of U)for(const s of e.manifest.getForScope(A).values()){const e=r.tryWorkspaceByDescriptor(s),a=n.parseRange(s.range);if("workspace:"===a.protocol)if(null===e){if(null===r.tryWorkspaceByIdent(s))throw new o.lk(i.b.WORKSPACE_NOT_FOUND,n.prettyDescriptor(r.configuration,s)+": No local workspace found for this range")}else{let r;r=n.areDescriptorsEqual(s,e.anchoredDescriptor)||"*"===a.selector?e.manifest.version:a.selector,t[A][n.stringifyIdent(s)]=r}}}},commands:[O]}},29936:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>re,patchUtils:()=>A});var A={};r.r(A),r.d(A,{applyPatchFile:()=>S,diffFolders:()=>H,extractPackageToDisk:()=>G,isParentRequired:()=>j,loadPatchFiles:()=>Y,makeDescriptor:()=>O,makeLocator:()=>U,parseDescriptor:()=>x,parseLocator:()=>L,parsePatchFile:()=>D});var n=r(39922),o=r(35691),i=r(92659),s=r(54143),a=r(73632),c=r(43896),g=r(46009),l=r(90739),u=r(75448),h=r(65281),p=r(33720),d=r(6220),C=r(36545),f=r(78420);class I extends Error{constructor(e,t){super("Cannot apply hunk #"+(e+1)),this.hunk=t}}const E=/^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@.*/;function B(e){return g.y1.relative(g.LZ.root,g.y1.resolve(g.LZ.root,g.cS.toPortablePath(e)))}function y(e){const t=e.trim().match(E);if(!t)throw new Error(`Bad header line: '${e}'`);return{original:{start:Math.max(Number(t[1]),1),length:Number(t[3]||1)},patched:{start:Math.max(Number(t[4]),1),length:Number(t[6]||1)}}}var m;!function(e){e.Context="context",e.Insertion="insertion",e.Deletion="deletion"}(m||(m={}));const w={"@":"header","-":m.Deletion,"+":m.Insertion," ":m.Context,"\\":"pragma",undefined:m.Context};function Q(e){const t=511&parseInt(e,8);if(420!==t&&493!==t)throw new Error("Unexpected file mode string: "+e);return t}function D(e){const t=e.split(/\n/g);return""===t[t.length-1]&&t.pop(),function(e){const t=[];for(const r of e){const{semverExclusivity:e,diffLineFromPath:A,diffLineToPath:n,oldMode:o,newMode:i,deletedFileMode:s,newFileMode:c,renameFrom:g,renameTo:l,beforeHash:u,afterHash:h,fromPath:p,toPath:d,hunks:C}=r,f=g?"rename":s?"file deletion":c?"file creation":C&&C.length>0?"patch":"mode change";let I=null;switch(f){case"rename":if(!g||!l)throw new Error("Bad parser state: rename from & to not given");t.push({type:"rename",semverExclusivity:e,fromPath:B(g),toPath:B(l)}),I=l;break;case"file deletion":{const r=A||p;if(!r)throw new Error("Bad parse state: no path given for file deletion");t.push({type:"file deletion",semverExclusivity:e,hunk:C&&C[0]||null,path:B(r),mode:Q(s),hash:u})}break;case"file creation":{const r=n||d;if(!r)throw new Error("Bad parse state: no path given for file creation");t.push({type:"file creation",semverExclusivity:e,hunk:C&&C[0]||null,path:B(r),mode:Q(c),hash:h})}break;case"patch":case"mode change":I=d||n;break;default:a.assertNever(f)}I&&o&&i&&o!==i&&t.push({type:"mode change",semverExclusivity:e,path:B(I),oldMode:Q(o),newMode:Q(i)}),I&&C&&C.length&&t.push({type:"patch",semverExclusivity:e,path:B(I),hunks:C,beforeHash:u,afterHash:h})}return t}(function(e){const t=[];let r={semverExclusivity:null,diffLineFromPath:null,diffLineToPath:null,oldMode:null,newMode:null,deletedFileMode:null,newFileMode:null,renameFrom:null,renameTo:null,beforeHash:null,afterHash:null,fromPath:null,toPath:null,hunks:null},A="parsing header",n=null,o=null;function i(){n&&(o&&(n.parts.push(o),o=null),r.hunks.push(n),n=null)}function s(){i(),t.push(r),r={semverExclusivity:null,diffLineFromPath:null,diffLineToPath:null,oldMode:null,newMode:null,deletedFileMode:null,newFileMode:null,renameFrom:null,renameTo:null,beforeHash:null,afterHash:null,fromPath:null,toPath:null,hunks:null}}for(let t=0;te<0?e:"+"+e;throw new Error(`hunk header integrity check failed (expected @@ ${A(e.header.original.length)} ${A(e.header.patched.length)} @@, got @@ ${A(t)} ${A(r)} @@)`)}}async function v(e,t,r){const A=await e.lstatPromise(t),n=await r();if(void 0!==n&&(t=n),e.lutimesPromise)await e.lutimesPromise(t,A.atime,A.mtime);else{if(A.isSymbolicLink())throw new Error("Cannot preserve the time values of a symlink");await e.utimesPromise(t,A.atime,A.mtime)}}async function S(e,{baseFs:t=new f.S,dryRun:r=!1,version:A=null}={}){for(const n of e)if(null===n.semverExclusivity||null===A||C.satisfiesWithPrereleases(A,n.semverExclusivity))switch(n.type){case"file deletion":if(r){if(!t.existsSync(n.path))throw new Error("Trying to delete a file that doesn't exist: "+n.path)}else await v(t,g.y1.dirname(n.path),async()=>{await t.unlinkPromise(n.path)});break;case"rename":if(r){if(!t.existsSync(n.fromPath))throw new Error("Trying to move a file that doesn't exist: "+n.fromPath)}else await v(t,g.y1.dirname(n.fromPath),async()=>{await v(t,g.y1.dirname(n.toPath),async()=>{await v(t,n.fromPath,async()=>(await t.movePromise(n.fromPath,n.toPath),n.toPath))})});break;case"file creation":if(r){if(t.existsSync(n.path))throw new Error("Trying to create a file that already exists: "+n.path)}else{const e=n.hunk?n.hunk.parts[0].lines.join("\n")+(n.hunk.parts[0].noNewlineAtEndOfFile?"":"\n"):"";await t.mkdirpPromise(g.y1.dirname(n.path),{chmod:493,utimes:[315532800,315532800]}),await t.writeFilePromise(n.path,e,{mode:n.mode}),await t.utimesPromise(n.path,315532800,315532800)}break;case"patch":await v(t,n.path,async()=>{await F(n,{baseFs:t,dryRun:r})});break;case"mode change":{const e=(await t.statPromise(n.path)).mode;if(k(n.newMode)!==k(e))continue;await v(t,n.path,async()=>{await t.chmodPromise(n.path,n.newMode)})}break;default:a.assertNever(n)}}function k(e){return(64&e)>0}function N(e){return e.replace(/\s+$/,"")}async function F({hunks:e,path:t},{baseFs:r,dryRun:A=!1}){const n=await r.statSync(t).mode,o=(await r.readFileSync(t,"utf8")).split(/\n/),i=[];let s=0,c=0;for(const t of e){const r=Math.max(c,t.header.patched.start+s),A=Math.max(0,r-c),n=Math.max(0,o.length-r-t.header.original.length),a=Math.max(A,n);let g=0,l=0,u=null;for(;g<=a;){if(g<=A&&(l=r-g,u=K(t,o,l),null!==u)){g=-g;break}if(g<=n&&(l=r+g,u=K(t,o,l),null!==u))break;g+=1}if(null===u)throw new I(e.indexOf(t),t);i.push(u),s+=g,c=l+t.header.original.length}if(A)return;let g=0;for(const e of i)for(const t of e)switch(t.type){case"splice":{const e=t.index+g;o.splice(e,t.numToDelete,...t.linesToInsert),g+=t.linesToInsert.length-t.numToDelete}break;case"pop":o.pop();break;case"push":o.push(t.line);break;default:a.assertNever(t)}await r.writeFilePromise(t,o.join("\n"),{mode:n})}function K(e,t,r){const A=[];for(const o of e.parts)switch(o.type){case m.Context:case m.Deletion:for(const e of o.lines){const A=t[r];if(null==A||(n=e,N(A)!==N(n)))return null;r+=1}o.type===m.Deletion&&(A.push({type:"splice",index:r-o.lines.length,numToDelete:o.lines.length,linesToInsert:[]}),o.noNewlineAtEndOfFile&&A.push({type:"push",line:""}));break;case m.Insertion:A.push({type:"splice",index:r,numToDelete:0,linesToInsert:o.lines}),o.noNewlineAtEndOfFile&&A.push({type:"pop"});break;default:a.assertNever(o.type)}var n;return A}const M=/^builtin<([^>]+)>$/;function R(e,t){const{source:r,selector:A,params:n}=s.parseRange(e);if(null===r)throw new Error("Patch locators must explicitly define their source");const o=A?A.split(/&/).map(e=>g.cS.toPortablePath(e)):[],i=n&&"string"==typeof n.locator?s.parseLocator(n.locator):null,a=n&&"string"==typeof n.version?n.version:null;return{parentLocator:i,sourceItem:t(r),patchPaths:o,sourceVersion:a}}function x(e){const{sourceItem:t,...r}=R(e.range,s.parseDescriptor);return{...r,sourceDescriptor:t}}function L(e){const{sourceItem:t,...r}=R(e.reference,s.parseLocator);return{...r,sourceLocator:t}}function P({parentLocator:e,sourceItem:t,patchPaths:r,sourceVersion:A,patchHash:n},o){const i=null!==e?{locator:s.stringifyLocator(e)}:{},a=void 0!==A?{version:A}:{},c=void 0!==n?{hash:n}:{};return s.makeRange({protocol:"patch:",source:o(t),selector:r.join("&"),params:{...a,...c,...i}})}function O(e,{parentLocator:t,sourceDescriptor:r,patchPaths:A}){return s.makeLocator(e,P({parentLocator:t,sourceItem:r,patchPaths:A},s.stringifyDescriptor))}function U(e,{parentLocator:t,sourcePackage:r,patchPaths:A,patchHash:n}){return s.makeLocator(e,P({parentLocator:t,sourceItem:r,sourceVersion:r.version,patchPaths:A,patchHash:n},s.stringifyLocator))}function T({onAbsolute:e,onRelative:t,onBuiltin:r},A){const n=A.match(M);return null!==n?r(n[1]):g.y1.isAbsolute(A)?e(A):t(A)}function j(e){return T({onAbsolute:()=>!1,onRelative:()=>!0,onBuiltin:()=>!1},e)}async function Y(e,t,r){const A=null!==e?await r.fetcher.fetch(e,r):null,n=A&&A.localPath?{packageFs:new u.M(g.LZ.root),prefixPath:g.y1.relative(g.LZ.root,A.localPath)}:A;A&&A!==n&&A.releaseFs&&A.releaseFs();return(await a.releaseAfterUseAsync(async()=>await Promise.all(t.map(async e=>T({onAbsolute:async()=>await c.xfs.readFilePromise(e,"utf8"),onRelative:async()=>{if(null===A)throw new Error("Assertion failed: The parent locator should have been fetched");return await A.packageFs.readFilePromise(e,"utf8")},onBuiltin:async e=>await r.project.configuration.firstHook(e=>e.getBuiltinPatch,r.project,e)},e))))).map(e=>"string"==typeof e?e.replace(/\r\n?/g,"\n"):e)}async function G(e,{cache:t,project:r}){const A=r.storedChecksums,n=new p.$,o=r.configuration.makeFetcher(),i=await o.fetch(e,{cache:t,project:r,fetcher:o,checksums:A,report:n}),a=await c.xfs.mktempPromise();return await c.xfs.copyPromise(a,i.prefixPath,{baseFs:i.packageFs}),await c.xfs.writeJsonPromise(g.y1.join(a,".yarn-patch.json"),{locator:s.stringifyLocator(e)}),c.xfs.detachTemp(a),a}async function H(e,t){const r=g.cS.fromPortablePath(e).replace(/\\/g,"/"),A=g.cS.fromPortablePath(t).replace(/\\/g,"/"),{stdout:n}=await d.execvp("git",["diff","--src-prefix=a/","--dst-prefix=b/","--ignore-cr-at-eol","--full-index","--no-index",r,A],{cwd:g.cS.toPortablePath(process.cwd())}),o=r.startsWith("/")?e=>e.slice(1):e=>e;return n.replace(new RegExp(`(a|b)(${a.escapeRegExp(`/${o(r)}/`)})`,"g"),"$1/").replace(new RegExp("(a|b)"+a.escapeRegExp(`/${o(A)}/`),"g"),"$1/").replace(new RegExp(a.escapeRegExp(r+"/"),"g"),"").replace(new RegExp(a.escapeRegExp(A+"/"),"g"),"")}var J=r(71643);function q(e,{configuration:t,report:r}){for(const A of e.parts)for(const e of A.lines)switch(A.type){case m.Context:r.reportInfo(null," "+J.pretty(t,e,"grey"));break;case m.Deletion:r.reportError(i.b.FROZEN_LOCKFILE_EXCEPTION,"- "+J.pretty(t,e,J.Type.REMOVED));break;case m.Insertion:r.reportError(i.b.FROZEN_LOCKFILE_EXCEPTION,"+ "+J.pretty(t,e,J.Type.ADDED));break;default:a.assertNever(A.type)}}var z=r(20624);var W=r(36370),V=r(25413),X=r(85824),_=r(28148),Z=r(40822);class $ extends V.BaseCommand{async execute(){const e=await n.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await X.I.find(e,this.context.cwd),A=await _.C.find(e);if(!r)throw new V.WorkspaceRequiredError(t.cwd,this.context.cwd);await t.restoreInstallState();const o=g.y1.resolve(this.context.cwd,g.cS.toPortablePath(this.patchFolder)),i=g.y1.join(o,".yarn-patch.json");if(!c.xfs.existsSync(i))throw new Z.UsageError("The argument folder didn't get created by 'yarn patch'");const a=await c.xfs.readJsonPromise(i),l=s.parseLocator(a.locator,!0);if(!t.storedPackages.has(l.locatorHash))throw new Z.UsageError("No package found in the project for the given locator");const u=await G(l,{cache:A,project:t});this.context.stdout.write(await H(u,o))}}$.usage=Z.Command.Usage({description:"\n This will turn the folder passed in parameter into a patchfile suitable for consumption with the `patch:` protocol.\n\n Only folders generated through `yarn patch` are accepted as valid input for `yarn patch-commit`.\n "}),(0,W.gn)([Z.Command.String()],$.prototype,"patchFolder",void 0),(0,W.gn)([Z.Command.Path("patch-commit")],$.prototype,"execute",null);var ee=r(15815);class te extends V.BaseCommand{async execute(){const e=await n.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await X.I.find(e,this.context.cwd),A=await _.C.find(e);if(!r)throw new V.WorkspaceRequiredError(t.cwd,this.context.cwd);await t.restoreInstallState();let o=s.parseLocator(this.package);if("unknown"===o.reference){const r=a.mapAndFilter([...t.storedPackages.values()],e=>e.identHash!==o.identHash||s.isVirtualLocator(e)?a.mapAndFilter.skip:e);if(0===r.length)throw new Z.UsageError("No package found in the project for the given locator");if(r.length>1)throw new Z.UsageError("Multiple candidate packages found; explicitly choose one of them (use `yarn why ` to get more information as to who depends on them):\n"+r.map(t=>"\n- "+s.prettyLocator(e,t)).join(""));o=r[0]}if(!t.storedPackages.has(o.locatorHash))throw new Z.UsageError("No package found in the project for the given locator");await ee.Pk.start({configuration:e,stdout:this.context.stdout},async r=>{const n=await G(o,{cache:A,project:t});r.reportInfo(i.b.UNNAMED,`Package ${s.prettyLocator(e,o)} got extracted with success!`),r.reportInfo(i.b.UNNAMED,"You can now edit the following folder: "+J.pretty(e,g.cS.fromPortablePath(n),"magenta")),r.reportInfo(i.b.UNNAMED,`Once you are done run ${J.pretty(e,"yarn patch-commit "+g.cS.fromPortablePath(n),"cyan")} and Yarn will store a patchfile based on your changes.`)})}}te.usage=Z.Command.Usage({description:'\n This command will cause a package to be extracted in a temporary directory (under a folder named "patch-workdir"). This folder will be editable at will; running `yarn patch` inside it will then cause Yarn to generate a patchfile and register it into your top-level manifest (cf the `patch:` protocol).\n '}),(0,W.gn)([Z.Command.String()],te.prototype,"package",void 0),(0,W.gn)([Z.Command.Path("patch")],te.prototype,"execute",null);const re={configuration:{enableInlineHunks:{description:"If true, the installs will print unmatched patch hunks",type:n.a2.BOOLEAN,default:!1}},commands:[$,te],fetchers:[class{supports(e,t){return!!e.reference.startsWith("patch:")}getLocalPath(e,t){return null}async fetch(e,t){const r=t.checksums.get(e.locatorHash)||null,[A,n,o]=await t.cache.fetchPackageFromCache(e,r,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,s.prettyLocator(t.project.configuration,e)+" can't be found in the cache and will be fetched from the disk"),loader:()=>this.patchPackage(e,t),skipIntegrityCheck:t.skipIntegrityCheck});return{packageFs:A,releaseFs:n,prefixPath:s.getIdentVendorPath(e),localPath:this.getLocalPath(e,t),checksum:o}}async patchPackage(e,t){const{parentLocator:r,sourceLocator:A,sourceVersion:n,patchPaths:p}=L(e),d=await Y(r,p,t),C=await c.xfs.mktempPromise(),f=g.y1.join(C,"patched.zip"),E=await t.fetcher.fetch(A,t),B=s.getIdentVendorPath(e),y=await(0,h.getLibzipPromise)(),m=new l.d(f,{libzip:y,create:!0,level:t.project.configuration.get("compressionLevel")});await m.mkdirpPromise(B),await a.releaseAfterUseAsync(async()=>{await m.copyPromise(B,E.prefixPath,{baseFs:E.packageFs,stableSort:!0})},E.releaseFs);const w=new u.M(g.y1.resolve(g.LZ.root,B),{baseFs:m});for(const e of d)if(null!==e)try{await S(D(e),{baseFs:w,version:n})}catch(e){if(!(e instanceof I))throw e;const r=t.project.configuration.get("enableInlineHunks"),A=r?"":" (set enableInlineHunks for details)";throw new o.lk(i.b.PATCH_HUNK_FAILED,e.message+A,A=>{r&&q(e.hunk,{configuration:t.project.configuration,report:A})})}return m}}],resolvers:[class{supportsDescriptor(e,t){return!!e.range.startsWith("patch:")}supportsLocator(e,t){return!!e.reference.startsWith("patch:")}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,r){const{patchPaths:A}=x(e);return A.every(e=>!j(e))?e:s.bindDescriptor(e,{locator:s.stringifyLocator(t)})}getResolutionDependencies(e,t){const{sourceDescriptor:r}=x(e);return[r]}async getCandidates(e,t,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");const{parentLocator:A,sourceDescriptor:n,patchPaths:o}=x(e),i=await Y(A,o,r.fetchOptions),s=t.get(n.descriptorHash);if(void 0===s)throw new Error("Assertion failed: The dependency should have been resolved");return[U(e,{parentLocator:A,sourcePackage:s,patchPaths:o,patchHash:z.makeHash("2",...i).slice(0,6)})]}async getSatisfying(e,t,r){return null}async resolve(e,t){const{sourceLocator:r}=L(e);return{...await t.resolver.resolve(r,t),...e}}}]}},83228:(e,t,r)=>{"use strict";r.r(t),r.d(t,{PnpInstaller:()=>k,PnpLinker:()=>S,default:()=>Y,getPnpPath:()=>T,jsInstallUtils:()=>A,pnpUtils:()=>n,quotePathIfNeeded:()=>j});var A={};r.r(A),r.d(A,{checkAndReportManifestCompatibility:()=>y,extractBuildScripts:()=>m,getExtractHint:()=>Q,hasBindingGyp:()=>D});var n={};r.r(n),r.d(n,{getUnpluggedPath:()=>b});var o=r(39922),i=r(43896),s=r(46009),a=r(53887),c=r.n(a),g=r(54143),l=r(71643),u=r(73632),h=r(32485),p=r(92659),d=r(46611),C=r(17674),f=r(75448),I=r(34432),E=r(40822),B=r(92409);function y(e,t,r,{configuration:A,report:n}){return d.G.isManifestFieldCompatible(t.manifest.os,process.platform)?!!d.G.isManifestFieldCompatible(t.manifest.cpu,process.arch)||(null==n||n.reportWarningOnce(p.b.INCOMPATIBLE_CPU,`${g.prettyLocator(A,e)} The CPU architecture ${process.arch} is incompatible with this module, ${r} skipped.`),!1):(null==n||n.reportWarningOnce(p.b.INCOMPATIBLE_OS,`${g.prettyLocator(A,e)} The platform ${process.platform} is incompatible with this module, ${r} skipped.`),!1)}function m(e,t,r,{configuration:A,report:n}){const o=[];for(const e of["preinstall","install","postinstall"])t.manifest.scripts.has(e)&&o.push([B.k.SCRIPT,e]);if(!t.manifest.scripts.has("install")&&t.misc.hasBindingGyp&&o.push([B.k.SHELLCODE,"node-gyp rebuild"]),0===o.length)return[];if(!A.get("enableScripts")&&!r.built)return null==n||n.reportWarningOnce(p.b.DISABLED_BUILD_SCRIPTS,g.prettyLocator(A,e)+" lists build scripts, but all build scripts have been disabled."),[];if(e.linkType!==h.Un.HARD)return null==n||n.reportWarningOnce(p.b.SOFT_LINK_BUILD,g.prettyLocator(A,e)+" lists build scripts, but is referenced through a soft link. Soft links don't support build scripts, so they'll be ignored."),[];if(r&&!1===r.built)return null==n||n.reportInfoOnce(p.b.BUILD_DISABLED,g.prettyLocator(A,e)+" lists build scripts, but its build has been explicitly disabled through configuration."),[];return y(e,t,"build",{configuration:A,report:n})?o:[]}const w=new Set([".exe",".h",".hh",".hpp",".c",".cc",".cpp",".java",".jar",".node"]);function Q(e){return e.packageFs.getExtractHint({relevantExtensions:w})}function D(e){const t=s.y1.join(e.prefixPath,"binding.gyp");return e.packageFs.existsSync(t)}function b(e,{configuration:t}){return s.y1.resolve(t.get("pnpUnpluggedFolder"),g.slugifyLocator(e))}const v=new Set([g.makeIdent(null,"nan").identHash,g.makeIdent(null,"node-gyp").identHash,g.makeIdent(null,"node-pre-gyp").identHash,g.makeIdent(null,"node-addon-api").identHash,g.makeIdent(null,"fsevents").identHash]);class S{constructor(){this.mode="strict"}supportsPackage(e,t){return"pnp"===t.project.configuration.get("nodeLinker")&&t.project.configuration.get("pnpMode")===this.mode}async findPackageLocation(e,t){const r=T(t.project).main;if(!i.xfs.existsSync(r))throw new E.UsageError(`The project in ${l.pretty(t.project.configuration,t.project.cwd+"/package.json",l.Type.PATH)} doesn't seem to have been installed - running an install there might help`);const A=u.dynamicRequireNoCache(r),n={name:g.requirableIdent(e),reference:e.reference},o=A.getPackageInformation(n);if(!o)throw new E.UsageError(`Couldn't find ${g.prettyLocator(t.project.configuration,e)} in the currently installed PnP map - running an install might help`);return s.cS.toPortablePath(o.packageLocation)}async findPackageLocator(e,t){const A=T(t.project).main;if(!i.xfs.existsSync(A))return null;const n=s.cS.fromPortablePath(A),o=u.dynamicRequire(n);delete r.c[n];const a=o.findPackageLocator(s.cS.fromPortablePath(e));return a?g.makeLocator(g.parseIdent(a.name),a.reference):null}makeInstaller(e){return new k(e)}}class k{constructor(e){this.opts=e,this.mode="strict",this.packageRegistry=new Map,this.virtualTemplates=new Map,this.customData={store:new Map},this.unpluggedPaths=new Set,this.opts=e}getCustomDataKey(){return JSON.stringify({name:"PnpInstaller",version:1})}attachCustomData(e){this.customData=e}async installPackage(e,t){const r=g.requirableIdent(e),A=e.reference,n=!!this.opts.project.tryWorkspaceByLocator(e),o=e.peerDependencies.size>0&&!g.isVirtualLocator(e),i=!o&&!n,a=!o&&e.linkType!==h.Un.SOFT;let c=this.customData.store.get(e.locatorHash);void 0===c&&(c=await async function(e,t){var r;const A=null!==(r=await d.G.tryFind(t.prefixPath,{baseFs:t.packageFs}))&&void 0!==r?r:new d.G,n=new Set(["preinstall","install","postinstall"]);for(const e of A.scripts.keys())n.has(e)||A.scripts.delete(e);return{manifest:{os:A.os,cpu:A.cpu,scripts:A.scripts,preferUnplugged:A.preferUnplugged},misc:{extractHint:Q(t),hasBindingGyp:D(t)}}}(0,t),e.linkType===h.Un.HARD&&this.customData.store.set(e.locatorHash,c));const l=this.opts.project.getDependencyMeta(e,e.version),p=i?m(e,c,l,{configuration:this.opts.project.configuration,report:this.opts.report}):[],f=a?await this.unplugPackageIfNeeded(e,c,t,l):t.packageFs;if(s.y1.isAbsolute(t.prefixPath))throw new Error(`Assertion failed: Expected the prefix path (${t.prefixPath}) to be relative to the parent`);const I=s.y1.resolve(f.getRealPath(),t.prefixPath),E=N(this.opts.project.cwd,I),B=new Map,y=new Set;if(g.isVirtualLocator(e)){for(const t of e.peerDependencies.values())B.set(g.requirableIdent(t),null),y.add(g.stringifyIdent(t));if(!this.opts.project.tryWorkspaceByLocator(e)){const t=g.devirtualizeLocator(e);this.virtualTemplates.set(t.locatorHash,{location:N(this.opts.project.cwd,C.p.resolveVirtual(I)),locator:t})}}return u.getMapWithDefault(this.packageRegistry,r).set(A,{packageLocation:E,packageDependencies:B,packagePeers:y,linkType:e.linkType,discardFromLookup:t.discardFromLookup||!1}),{packageLocation:I,buildDirective:p.length>0?p:null}}async attachInternalDependencies(e,t){const r=this.getPackageInformation(e);for(const[e,A]of t){const t=g.areIdentsEqual(e,A)?A.reference:[g.requirableIdent(A),A.reference];r.packageDependencies.set(g.requirableIdent(e),t)}}async attachExternalDependents(e,t){for(const r of t){this.getDiskInformation(r).packageDependencies.set(g.requirableIdent(e),e.reference)}}async finalizeInstall(){const e=new Set;for(const{locator:e,location:t}of this.virtualTemplates.values())u.getMapWithDefault(this.packageRegistry,g.stringifyIdent(e)).set(e.reference,{packageLocation:t,packageDependencies:new Map,packagePeers:new Set,linkType:h.Un.SOFT,discardFromLookup:!1});this.packageRegistry.set(null,new Map([[null,this.getPackageInformation(this.opts.project.topLevelWorkspace.anchoredLocator)]]));const t=this.opts.project.configuration.get("pnpFallbackMode"),r=e,A=this.opts.project.workspaces.map(({anchoredLocator:e})=>({name:g.requirableIdent(e),reference:e.reference})),n="none"!==t,o=[],i=new Map,s=u.buildIgnorePattern([".yarn/sdks/**",...this.opts.project.configuration.get("pnpIgnorePatterns")]),a=this.packageRegistry,c=this.opts.project.configuration.get("pnpShebang");if("dependencies-only"===t)for(const e of this.opts.project.storedPackages.values())this.opts.project.tryWorkspaceByLocator(e)&&o.push({name:g.requirableIdent(e),reference:e.reference});return await this.finalizeInstallWithPnp({blacklistedLocations:r,dependencyTreeRoots:A,enableTopLevelFallback:n,fallbackExclusionList:o,fallbackPool:i,ignorePattern:s,packageRegistry:a,shebang:c}),{customData:this.customData}}async finalizeInstallWithPnp(e){if(this.opts.project.configuration.get("pnpMode")!==this.mode)return;const t=T(this.opts.project),r=this.opts.project.configuration.get("pnpDataPath");if(await i.xfs.removePromise(t.other),"pnp"!==this.opts.project.configuration.get("nodeLinker"))return await i.xfs.removePromise(t.main),void await i.xfs.removePromise(r);const A=await this.locateNodeModules(e.ignorePattern);if(A.length>0){this.opts.report.reportWarning(p.b.DANGEROUS_NODE_MODULES,"One or more node_modules have been detected and will be removed. This operation may take some time.");for(const e of A)await i.xfs.removePromise(e)}if(this.opts.project.configuration.get("pnpEnableInlining")){const A=(0,I.gY)(e);await i.xfs.changeFilePromise(t.main,A,{automaticNewlines:!0}),await i.xfs.chmodPromise(t.main,493),await i.xfs.removePromise(r)}else{const A=s.y1.relative(s.y1.dirname(t.main),r),{dataFile:n,loaderFile:o}=(0,I.Q$)({...e,dataLocation:A});await i.xfs.changeFilePromise(t.main,o,{automaticNewlines:!0}),await i.xfs.chmodPromise(t.main,493),await i.xfs.changeFilePromise(r,n,{automaticNewlines:!0}),await i.xfs.chmodPromise(r,420)}const n=this.opts.project.configuration.get("pnpUnpluggedFolder");if(0===this.unpluggedPaths.size)await i.xfs.removePromise(n);else for(const e of await i.xfs.readdirPromise(n)){const t=s.y1.resolve(n,e);this.unpluggedPaths.has(t)||await i.xfs.removePromise(t)}}async locateNodeModules(e){const t=[],r=e?new RegExp(e):null;for(const e of this.opts.project.workspaces){const A=s.y1.join(e.cwd,"node_modules");if(r&&r.test(s.y1.relative(this.opts.project.cwd,e.cwd))||!i.xfs.existsSync(A))continue;const n=await i.xfs.readdirPromise(A,{withFileTypes:!0}),o=n.filter(e=>!e.isDirectory()||".bin"===e.name||!e.name.startsWith("."));if(o.length===n.length)t.push(A);else for(const e of o)t.push(s.y1.join(A,e.name))}return t}async unplugPackageIfNeeded(e,t,r,A){return this.shouldBeUnplugged(e,t,A)?this.unplugPackage(e,r):r.packageFs}shouldBeUnplugged(e,t,r){return void 0!==r.unplugged?r.unplugged:!!v.has(e.identHash)||(null!==t.manifest.preferUnplugged?t.manifest.preferUnplugged:!!(m(e,t,r,{configuration:this.opts.project.configuration}).length>0||t.misc.extractHint))}async unplugPackage(e,t){const r=b(e,{configuration:this.opts.project.configuration});this.unpluggedPaths.add(r);const A=s.y1.join(r,t.prefixPath,".ready");return await i.xfs.existsPromise(A)||(await i.xfs.mkdirPromise(r,{recursive:!0}),await i.xfs.copyPromise(r,s.LZ.dot,{baseFs:t.packageFs,overwrite:!1}),await i.xfs.writeFilePromise(A,"")),new f.M(r)}getPackageInformation(e){const t=g.requirableIdent(e),r=e.reference,A=this.packageRegistry.get(t);if(!A)throw new Error(`Assertion failed: The package information store should have been available (for ${g.prettyIdent(this.opts.project.configuration,e)})`);const n=A.get(r);if(!n)throw new Error(`Assertion failed: The package information should have been available (for ${g.prettyLocator(this.opts.project.configuration,e)})`);return n}getDiskInformation(e){const t=u.getMapWithDefault(this.packageRegistry,"@@disk"),r=N(this.opts.project.cwd,e);return u.getFactoryWithDefault(t,r,()=>({packageLocation:r,packageDependencies:new Map,packagePeers:new Set,linkType:h.Un.SOFT,discardFromLookup:!1}))}}function N(e,t){let r=s.y1.relative(e,t);return r.match(/^\.{0,2}\//)||(r="./"+r),r.replace(/\/?$/,"/")}var F=r(36370),K=r(25413),M=r(85824),R=r(28148),x=r(15815),L=r(36545),P=r(2401),O=r.n(P);class U extends K.BaseCommand{constructor(){super(...arguments),this.patterns=[],this.all=!1,this.recursive=!1,this.json=!1}async execute(){const e=await o.VK.find(this.context.cwd,this.context.plugins),{project:t,workspace:r}=await M.I.find(e,this.context.cwd),A=await R.C.find(e);if(!r)throw new K.WorkspaceRequiredError(t.cwd,this.context.cwd);if("pnp"!==e.get("nodeLinker"))throw new E.UsageError("This command can only be used if the `nodeLinker` option is set to `pnp`");await t.restoreInstallState();const n=new Set(this.patterns),i=this.patterns.map(t=>{const r=g.parseDescriptor(t),A="unknown"!==r.range?r:g.makeDescriptor(r,"*");if(!c().validRange(A.range))throw new E.UsageError(`The range of the descriptor patterns must be a valid semver range (${g.prettyDescriptor(e,A)})`);return e=>{const r=g.stringifyIdent(e);return!!O().isMatch(r,g.stringifyIdent(A))&&(!(e.version&&!L.satisfiesWithPrereleases(e.version,A.range))&&(n.delete(t),!0))}}),s=e=>{const r=new Set,A=[],n=(e,o)=>{if(!r.has(e.locatorHash)&&(r.add(e.locatorHash),!t.tryWorkspaceByLocator(e)&&i.some(t=>t(e))&&A.push(e),!(o>0)||this.recursive))for(const r of e.dependencies.values()){const e=t.storedResolutions.get(r.descriptorHash);if(!e)throw new Error("Assertion failed: The resolution should have been registered");const A=t.storedPackages.get(e);if(!A)throw new Error("Assertion failed: The package should have been registered");n(A,o+1)}};for(const r of e){const e=t.storedPackages.get(r.anchoredLocator.locatorHash);if(!e)throw new Error("Assertion failed: The package should have been registered");n(e,0)}return A};let a,h;if(this.all&&this.recursive?(a=(()=>{const e=[];for(const r of t.storedPackages.values())t.tryWorkspaceByLocator(r)||g.isVirtualLocator(r)||!i.some(e=>e(r))||e.push(r);return e})(),h="the project"):this.all?(a=s(t.workspaces),h="any workspace"):(a=s([r]),h="this workspace"),n.size>1)throw new E.UsageError(`Patterns ${l.prettyList(e,n,l.Type.CODE)} don't match any packages referenced by ${h}`);if(n.size>0)throw new E.UsageError(`Pattern ${l.prettyList(e,n,l.Type.CODE)} doesn't match any packages referenced by ${h}`);a=u.sortMap(a,e=>g.stringifyLocator(e));return(await x.Pk.start({configuration:e,stdout:this.context.stdout,json:this.json},async r=>{var n;for(const A of a){const o=null!==(n=A.version)&&void 0!==n?n:"unknown";t.topLevelWorkspace.manifest.ensureDependencyMeta(g.makeDescriptor(A,o)).unplugged=!0,r.reportInfo(p.b.UNNAMED,`Will unpack ${g.prettyLocator(e,A)} to ${l.pretty(e,b(A,{configuration:e}),l.Type.PATH)}`),r.reportJson({locator:g.stringifyLocator(A),version:o})}await t.topLevelWorkspace.persistManifest(),r.reportSeparator(),await t.install({cache:A,report:r})})).exitCode()}}U.usage=E.Command.Usage({description:"force the unpacking of a list of packages",details:"\n This command will add the selectors matching the specified patterns to the list of packages that must be unplugged when installed.\n\n A package being unplugged means that instead of being referenced directly through its archive, it will be unpacked at install time in the directory configured via `pnpUnpluggedFolder`. Note that unpacking packages this way is generally not recommended because it'll make it harder to store your packages within the repository. However, it's a good approach to quickly and safely debug some packages, and can even sometimes be required depending on the context (for example when the package contains shellscripts).\n\n Running the command will set a persistent flag inside your top-level `package.json`, in the `dependenciesMeta` field. As such, to undo its effects, you'll need to revert the changes made to the manifest and run `yarn install` to apply the modification.\n\n By default, only direct dependencies from the current workspace are affected. If `-A,--all` is set, direct dependencies from the entire project are affected. Using the `-R,--recursive` flag will affect transitive dependencies as well as direct ones.\n\n This command accepts glob patterns inside the scope and name components (not the range). Make sure to escape the patterns to prevent your own shell from trying to expand them.\n ",examples:[["Unplug the lodash dependency from the active workspace","yarn unplug lodash"],["Unplug all instances of lodash referenced by any workspace","yarn unplug lodash -A"],["Unplug all instances of lodash referenced by the active workspace and its dependencies","yarn unplug lodash -R"],["Unplug all instances of lodash, anywhere","yarn unplug lodash -AR"],["Unplug one specific version of lodash","yarn unplug lodash@1.2.3"],["Unplug all packages with the `@babel` scope","yarn unplug '@babel/*'"],["Unplug all packages (only for testing, not recommended)","yarn unplug -R '*'"]]}),(0,F.gn)([E.Command.Rest()],U.prototype,"patterns",void 0),(0,F.gn)([E.Command.Boolean("-A,--all",{description:"Unplug direct dependencies from the entire project"})],U.prototype,"all",void 0),(0,F.gn)([E.Command.Boolean("-R,--recursive",{description:"Unplug both direct and transitive dependencies"})],U.prototype,"recursive",void 0),(0,F.gn)([E.Command.Boolean("--json",{description:"Format the output as an NDJSON stream"})],U.prototype,"json",void 0),(0,F.gn)([E.Command.Path("unplug")],U.prototype,"execute",null);const T=e=>{let t,r;return"module"===e.topLevelWorkspace.manifest.type?(t=".pnp.cjs",r=".pnp.js"):(t=".pnp.js",r=".pnp.cjs"),{main:s.y1.join(e.cwd,t),other:s.y1.join(e.cwd,r)}},j=e=>/\s/.test(e)?JSON.stringify(e):e;const Y={hooks:{populateYarnPaths:async function(e,t){t(T(e).main),t(T(e).other),t(e.configuration.get("pnpDataPath")),t(e.configuration.get("pnpUnpluggedFolder"))},setupScriptEnvironment:async function(e,t,r){const A=T(e).main,n="--require "+j(s.cS.fromPortablePath(A));if(A.includes(" ")&&c().lt(process.versions.node,"12.0.0"))throw new Error(`Expected the build location to not include spaces when using Node < 12.0.0 (${process.versions.node})`);if(i.xfs.existsSync(A)){let e=t.NODE_OPTIONS||"";const r=/\s*--require\s+\S*\.pnp\.c?js\s*/g;e=e.replace(r," ").trim(),e=e?`${n} ${e}`:n,t.NODE_OPTIONS=e}}},configuration:{nodeLinker:{description:'The linker used for installing Node packages, one of: "pnp", "node-modules"',type:o.a2.STRING,default:"pnp"},pnpMode:{description:"If 'strict', generates standard PnP maps. If 'loose', merges them with the n_m resolution.",type:o.a2.STRING,default:"strict"},pnpShebang:{description:"String to prepend to the generated PnP script",type:o.a2.STRING,default:"#!/usr/bin/env node"},pnpIgnorePatterns:{description:"Array of glob patterns; files matching them will use the classic resolution",type:o.a2.STRING,default:[],isArray:!0},pnpEnableInlining:{description:"If true, the PnP data will be inlined along with the generated loader",type:o.a2.BOOLEAN,default:!0},pnpFallbackMode:{description:"If true, the generated PnP loader will follow the top-level fallback rule",type:o.a2.STRING,default:"dependencies-only"},pnpUnpluggedFolder:{description:"Folder where the unplugged packages must be stored",type:o.a2.ABSOLUTE_PATH,default:"./.yarn/unplugged"},pnpDataPath:{description:"Path of the file where the PnP data (used by the loader) must be written",type:o.a2.ABSOLUTE_PATH,default:"./.pnp.data.json"}},linkers:[S],commands:[U]}},43418:(e,t,r)=>{"use strict";r.r(t);var A=r(50683),n=r.n(A);Object.fromEntries||(Object.fromEntries=n());var o=r(59355),i=r(10419),s=r(45330);(0,i.D)({binaryVersion:o.o||"",pluginConfiguration:(0,s.e)()})},25413:(e,t,r)=>{"use strict";r.r(t),r.d(t,{BaseCommand:()=>A.F,WorkspaceRequiredError:()=>s,getDynamicLibs:()=>c,getPluginConfiguration:()=>g.e,main:()=>h.D,openWorkspace:()=>u,pluginCommands:()=>p.f});var A=r(56087),n=r(46611),o=r(46009),i=r(40822);class s extends i.UsageError{constructor(e,t){super(`This command can only be run from within a workspace of your project (${o.y1.relative(e,t)} isn't a workspace of ${o.y1.join(e,n.G.fileName)}).`)}}const a=["@yarnpkg/cli","@yarnpkg/core","@yarnpkg/fslib","@yarnpkg/libzip","@yarnpkg/parsers","@yarnpkg/shell","clipanion","semver","yup"],c=()=>new Map(a.map(e=>[e,r(98497)(e)]));var g=r(45330),l=r(85824);async function u(e,t){const{project:r,workspace:A}=await l.I.find(e,t);if(!A)throw new s(r.cwd,t);return A}var h=r(10419),p=r(15683)},10419:(e,t,r)=>{"use strict";r.d(t,{D:()=>f});var A=r(36545),n=r(39922),o=r(81832),i=r(43896),s=r(46009),a=r(63129),c=r(5864),g=r(40822),l=r(35747),u=r(15683),h=r(36370),p=r(71643),d=r(56087);class C extends d.F{async execute(){const e=await n.VK.find(this.context.cwd,this.context.plugins);this.context.stdout.write((e=>`\n${p.pretty(e,"Welcome on Yarn 2!","bold")} 🎉 Thanks for helping us shape our vision of how projects\nshould be managed going forward.\n\nBeing still in RC, Yarn 2 isn't completely stable yet. Some features might be\nmissing, and some behaviors may have received major overhaul. In case of doubt,\nuse the following URLs to get some insight:\n\n - The changelog:\n ${p.pretty(e,"https://github.com/yarnpkg/berry/tree/CHANGELOG.md","cyan")}\n\n - Our issue tracker:\n ${p.pretty(e,"https://github.com/yarnpkg/berry","cyan")}\n\n - Our Discord server:\n ${p.pretty(e,"https://discord.gg/yarnpkg","cyan")}\n\nWe're hoping you will enjoy the experience. For now, a good start is to run\nthe two following commands:\n\n ${p.pretty(e,"find . -name node_modules -prune -exec rm -r {} \\;","magenta")}\n ${p.pretty(e,"yarn install","magenta")}\n\nOne last trick! If you need at some point to upgrade Yarn to a nightly build,\nthe following command will install the CLI straight from master:\n\n ${p.pretty(e,"yarn set version from sources","magenta")}\n\nSee you later 👋\n`)(e).trim()+"\n")}}async function f({binaryVersion:e,pluginConfiguration:t}){async function r(){const h=new g.Cli({binaryLabel:"Yarn Package Manager",binaryName:"yarn",binaryVersion:e});h.register(C);try{await async function h(p){var d,C,f,I,E;const B=process.versions.node,y=">=10.17 <14 || >14.1";if("1"!==process.env.YARN_IGNORE_NODE&&!A.satisfiesWithPrereleases(B,y))throw new g.UsageError(`This tool requires a Node version compatible with ${y} (got ${B}). Upgrade Node, or set \`YARN_IGNORE_NODE=1\` in your environment.`);const m=await n.VK.find(s.cS.toPortablePath(process.cwd()),t,{usePath:!0,strict:!1}),w=m.get("yarnPath"),Q=m.get("ignorePath"),D=m.get("ignoreCwd");if(!Q&&!D&&w===s.cS.toPortablePath(s.cS.resolve(process.argv[1])))return process.env.YARN_IGNORE_PATH="1",process.env.YARN_IGNORE_CWD="1",void await h(p);if(null===w||Q){Q&&delete process.env.YARN_IGNORE_PATH;m.get("enableTelemetry")&&!c.isCI&&process.stdout.isTTY&&(n.VK.telemetry=new o.E(m,"puba9cdc10ec5790a2cf4969dd413a47270")),null===(d=n.VK.telemetry)||void 0===d||d.reportVersion(e);for(const[e,t]of m.plugins.entries()){u.f.has(null!==(f=null===(C=e.match(/^@yarnpkg\/plugin-(.*)$/))||void 0===C?void 0:C[1])&&void 0!==f?f:"")&&(null===(I=n.VK.telemetry)||void 0===I||I.reportPluginName(e));for(const e of t.commands||[])p.register(e)}const A=p.process(process.argv.slice(2));A.help||null===(E=n.VK.telemetry)||void 0===E||E.reportCommandName(A.path.join(" "));const i=A.cwd;if(void 0!==i&&!D){const e=(0,l.realpathSync)(process.cwd()),t=(0,l.realpathSync)(i);if(e!==t)return process.chdir(i),void await r()}await p.runExit(A,{cwd:s.cS.toPortablePath(process.cwd()),plugins:t,quiet:!1,stdin:process.stdin,stdout:process.stdout,stderr:process.stderr})}else if(i.xfs.existsSync(w))try{!function(e){const t=s.cS.fromPortablePath(e);process.on("SIGINT",()=>{}),t?(0,a.execFileSync)(process.execPath,[t,...process.argv.slice(2)],{stdio:"inherit",env:{...process.env,YARN_IGNORE_PATH:"1",YARN_IGNORE_CWD:"1"}}):(0,a.execFileSync)(t,process.argv.slice(2),{stdio:"inherit",env:{...process.env,YARN_IGNORE_PATH:"1",YARN_IGNORE_CWD:"1"}})}(w)}catch(e){process.exitCode=e.code||1}else process.stdout.write(p.error(new Error(`The "yarn-path" option has been set (in ${m.sources.get("yarnPath")}), but the specified location doesn't exist (${w}).`))),process.exitCode=1}(h)}catch(e){process.stdout.write(h.error(e)),process.exitCode=1}}return r().catch(e=>{process.stdout.write(e.stack||e.message),process.exitCode=1}).finally(()=>i.xfs.rmtempPromise())}(0,h.gn)([g.Command.Path("--welcome")],C.prototype,"execute",null)},15683:(e,t,r)=>{"use strict";r.d(t,{f:()=>A});const A=new Map([["constraints",[["constraints","query"],["constraints","source"],["constraints"]]],["exec",[]],["interactive-tools",[["search"],["upgrade-interactive"]]],["stage",[["stage"]]],["typescript",[]],["version",[["version","apply"],["version","check"],["version"]]],["workspace-tools",[["workspaces","focus"],["workspaces","foreach"]]]])},56087:(e,t,r)=>{"use strict";r.d(t,{F:()=>o});var A=r(36370),n=r(40822);class o extends n.Command{}(0,A.gn)([n.Command.String("--cwd",{hidden:!0})],o.prototype,"cwd",void 0)},28148:(e,t,r)=>{"use strict";r.d(t,{C:()=>I});var A=r(78420),n=r(15037),o=r(90739),i=r(14626),s=r(46009),a=r(43896),c=r(65281),g=r(35747),l=r.n(g),u=r(92659),h=r(35691),p=r(20624),d=r(73632),C=r(54143);const f=7;class I{constructor(e,{configuration:t,immutable:r=t.get("enableImmutableCache"),check:A=!1}){this.markedFiles=new Set,this.mutexes=new Map,this.configuration=t,this.cwd=e,this.immutable=r,this.check=A;const n=t.get("cacheKeyOverride");if(null!==n)this.cacheKey=""+n;else{const e=t.get("compressionLevel"),r=e!==o.k?"c"+e:"";this.cacheKey=[f,r].join("")}}static async find(e,{immutable:t,check:r}={}){const A=new I(e.get("cacheFolder"),{configuration:e,immutable:t,check:r});return await A.setup(),A}get mirrorCwd(){if(!this.configuration.get("enableMirror"))return null;const e=this.configuration.get("globalFolder")+"/cache";return e!==this.cwd?e:null}getVersionFilename(e){return`${C.slugifyLocator(e)}-${this.cacheKey}.zip`}getChecksumFilename(e,t){const r=function(e){const t=e.indexOf("/");return-1!==t?e.slice(t+1):e}(t).slice(0,10);return`${C.slugifyLocator(e)}-${r}.zip`}getLocatorPath(e,t){if(null===this.mirrorCwd)return s.y1.resolve(this.cwd,this.getVersionFilename(e));if(null===t)return null;return E(t)!==this.cacheKey?null:s.y1.resolve(this.cwd,this.getChecksumFilename(e,t))}getLocatorMirrorPath(e){const t=this.mirrorCwd;return null!==t?s.y1.resolve(t,this.getVersionFilename(e)):null}async setup(){if(!this.configuration.get("enableGlobalCache")){await a.xfs.mkdirPromise(this.cwd,{recursive:!0});const e=s.y1.resolve(this.cwd,".gitignore");await a.xfs.changeFilePromise(e,"/.gitignore\n*.flock\n")}}async fetchPackageFromCache(e,t,{onHit:r,onMiss:g,loader:f,skipIntegrityCheck:I}){const B=this.getLocatorMirrorPath(e),y=new A.S,m=async(e,r=null)=>{const A=I&&t?t:`${this.cacheKey}/${await p.checksumFile(e)}`;if(null!==r){if(A!==(I&&t?t:`${this.cacheKey}/${await p.checksumFile(r)}`))throw new h.lk(u.b.CACHE_CHECKSUM_MISMATCH,"The remote archive doesn't match the local checksum - has the local cache been corrupted?")}if(null!==t&&A!==t){let e;switch(e=this.check?"throw":E(t)!==E(A)?"update":this.configuration.get("checksumBehavior"),e){case"ignore":return t;case"update":return A;default:case"throw":throw new h.lk(u.b.CACHE_CHECKSUM_MISMATCH,"The remote archive doesn't match the expected checksum")}}return A},w=async t=>{if(!f)throw new Error("Cache check required but no loader configured for "+C.prettyLocator(this.configuration,e));const r=await f(),A=r.getRealPath();return r.saveAndClose(),await a.xfs.chmodPromise(A,420),await m(t,A)},Q=async()=>{if(null===B||!await a.xfs.existsPromise(B)){const e=await f(),t=e.getRealPath();return e.saveAndClose(),t}const t=await a.xfs.mktempPromise(),r=s.y1.join(t,this.getVersionFilename(e));return await a.xfs.copyFilePromise(B,r,l().constants.COPYFILE_FICLONE),r},D=async()=>{if(!f)throw new Error("Cache entry required but missing for "+C.prettyLocator(this.configuration,e));if(this.immutable)throw new h.lk(u.b.IMMUTABLE_CACHE,"Cache entry required but missing for "+C.prettyLocator(this.configuration,e));const t=await Q();await a.xfs.chmodPromise(t,420);const r=await m(t),A=this.getLocatorPath(e,r);if(!A)throw new Error("Assertion failed: Expected the cache path to be available");return await this.writeFileWithLock(A,async()=>await this.writeFileWithLock(B,async()=>(await a.xfs.movePromise(t,A),null!==B&&await a.xfs.copyFilePromise(A,B,l().constants.COPYFILE_FICLONE),[A,r])))};for(let t;t=this.mutexes.get(e.locatorHash);)await t;const[b,v]=await(async()=>{const A=(async()=>{const A=this.getLocatorPath(e,t),n=null!==A&&await y.existsPromise(A),o=n?r:g;if(o&&o(),n){let e=null;const t=A;return e=this.check?await w(t):await m(t),[t,e]}return D()})();this.mutexes.set(e.locatorHash,A);try{return await A}finally{this.mutexes.delete(e.locatorHash)}})();this.markedFiles.add(b);let S=null;const k=await(0,c.getLibzipPromise)(),N=new n.v(()=>d.prettifySyncErrors(()=>S=new o.d(b,{baseFs:y,libzip:k,readOnly:!0}),t=>`Failed to open the cache entry for ${C.prettyLocator(this.configuration,e)}: ${t}`),s.y1);return[new i.K(b,{baseFs:N,pathUtils:s.y1}),()=>{null!==S&&S.discardAndClose()},v]}async writeFileWithLock(e,t){return null===e?await t():(await a.xfs.mkdirPromise(s.y1.dirname(e),{recursive:!0}),await a.xfs.lockPromise(e,async()=>await t()))}}function E(e){const t=e.indexOf("/");return-1!==t?e.slice(0,t):null}},39922:(e,t,r)=>{"use strict";r.d(t,{VK:()=>W,nh:()=>U,tr:()=>O,a5:()=>j,EW:()=>z,a2:()=>T});var A=r(43896),n=r(46009),o=r(90739),i=r(11640),s=r(54738),a=r.n(s),c=r(5864),g=r(40822),l=r(61578),u=r.n(l),h=r(53887),p=r.n(h),d=r(92413),C=r(92659),f=r(54143);const I={hooks:{reduceDependency:(e,t,r,A,{resolver:n,resolveOptions:o})=>{for(const{pattern:A,reference:i}of t.topLevelWorkspace.manifest.resolutions){if(A.from&&A.from.fullName!==f.requirableIdent(r))continue;if(A.from&&A.from.description&&A.from.description!==r.reference)continue;if(A.descriptor.fullName!==f.requirableIdent(e))continue;if(A.descriptor.description&&A.descriptor.description!==e.range)continue;return n.bindDescriptor(f.makeDescriptor(e,i),t.topLevelWorkspace.anchoredLocator,o)}return e},validateProject:async(e,t)=>{for(const r of e.workspaces){const A=f.prettyWorkspace(e.configuration,r);await e.configuration.triggerHook(e=>e.validateWorkspace,r,{reportWarning:(e,r)=>t.reportWarning(e,`${A}: ${r}`),reportError:(e,r)=>t.reportError(e,`${A}: ${r}`)})}},validateWorkspace:async(e,t)=>{const{manifest:r}=e;r.resolutions.length&&e.cwd!==e.project.cwd&&r.errors.push(new Error("Resolutions field will be ignored"));for(const e of r.errors)t.reportWarning(C.b.INVALID_MANIFEST,e.message)}}};var E=r(46611),B=r(35691);class y{constructor(e){this.fetchers=e}supports(e,t){return!!this.tryFetcher(e,t)}getLocalPath(e,t){return this.getFetcher(e,t).getLocalPath(e,t)}async fetch(e,t){const r=this.getFetcher(e,t);return await r.fetch(e,t)}tryFetcher(e,t){const r=this.fetchers.find(r=>r.supports(e,t));return r||null}getFetcher(e,t){const r=this.fetchers.find(r=>r.supports(e,t));if(!r)throw new B.lk(C.b.FETCHER_NOT_FOUND,f.prettyLocator(t.project.configuration,e)+" isn't supported by any available fetcher");return r}}var m=r(27092),w=r(52779),Q=r(60895);class D{static isVirtualDescriptor(e){return!!e.range.startsWith(D.protocol)}static isVirtualLocator(e){return!!e.reference.startsWith(D.protocol)}supportsDescriptor(e,t){return D.isVirtualDescriptor(e)}supportsLocator(e,t){return D.isVirtualLocator(e)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,r){throw new Error('Assertion failed: calling "bindDescriptor" on a virtual descriptor is unsupported')}getResolutionDependencies(e,t){throw new Error('Assertion failed: calling "getResolutionDependencies" on a virtual descriptor is unsupported')}async getCandidates(e,t,r){throw new Error('Assertion failed: calling "getCandidates" on a virtual descriptor is unsupported')}async getSatisfying(e,t,r){throw new Error('Assertion failed: calling "getSatisfying" on a virtual descriptor is unsupported')}async resolve(e,t){throw new Error('Assertion failed: calling "resolve" on a virtual locator is unsupported')}}D.protocol="virtual:";var b=r(75448),v=r(94538);class S{supports(e){return!!e.reference.startsWith(v.d.protocol)}getLocalPath(e,t){return this.getWorkspace(e,t).cwd}async fetch(e,t){const r=this.getWorkspace(e,t).cwd;return{packageFs:new b.M(r),prefixPath:n.LZ.dot,localPath:r}}getWorkspace(e,t){return t.project.getWorkspaceByCwd(e.reference.slice(v.d.protocol.length))}}var k=r(81111),N=r(71643),F=r(73632),K=r(32282),M=r.n(K);function R(e){return("undefined"!=typeof require?require:r(32178))(e)}var x=r(36545),L=r(32485);const P=new Set(["binFolder","version","flags","profile","gpg","ignoreNode","wrapOutput"]),O=".yarnrc.yml",U="yarn.lock";var T;!function(e){e.ANY="ANY",e.BOOLEAN="BOOLEAN",e.ABSOLUTE_PATH="ABSOLUTE_PATH",e.LOCATOR="LOCATOR",e.LOCATOR_LOOSE="LOCATOR_LOOSE",e.NUMBER="NUMBER",e.STRING="STRING",e.SECRET="SECRET",e.SHAPE="SHAPE",e.MAP="MAP"}(T||(T={}));const j=N.Type,Y={lastUpdateCheck:{description:"Last timestamp we checked whether new Yarn versions were available",type:T.STRING,default:null},yarnPath:{description:"Path to the local executable that must be used over the global one",type:T.ABSOLUTE_PATH,default:null},ignorePath:{description:"If true, the local executable will be ignored when using the global one",type:T.BOOLEAN,default:!1},ignoreCwd:{description:"If true, the `--cwd` flag will be ignored",type:T.BOOLEAN,default:!1},cacheKeyOverride:{description:"A global cache key override; used only for test purposes",type:T.STRING,default:null},globalFolder:{description:"Folder where are stored the system-wide settings",type:T.ABSOLUTE_PATH,default:k.getDefaultGlobalFolder()},cacheFolder:{description:"Folder where the cache files must be written",type:T.ABSOLUTE_PATH,default:"./.yarn/cache"},compressionLevel:{description:"Zip files compression level, from 0 to 9 or mixed (a variant of 9, which stores some files uncompressed, when compression doesn't yield good results)",type:T.NUMBER,values:["mixed",0,1,2,3,4,5,6,7,8,9],default:o.k},virtualFolder:{description:"Folder where the virtual packages (cf doc) will be mapped on the disk (must be named $$virtual)",type:T.ABSOLUTE_PATH,default:"./.yarn/$$virtual"},bstatePath:{description:"Path of the file where the current state of the built packages must be stored",type:T.ABSOLUTE_PATH,default:"./.yarn/build-state.yml"},lockfileFilename:{description:"Name of the files where the Yarn dependency tree entries must be stored",type:T.STRING,default:U},installStatePath:{description:"Path of the file where the install state will be persisted",type:T.ABSOLUTE_PATH,default:"./.yarn/install-state.gz"},immutablePatterns:{description:"Array of glob patterns; files matching them won't be allowed to change during immutable installs",type:T.STRING,default:[],isArray:!0},rcFilename:{description:"Name of the files where the configuration can be found",type:T.STRING,default:q()},enableGlobalCache:{description:"If true, the system-wide cache folder will be used regardless of `cache-folder`",type:T.BOOLEAN,default:!1},enableAbsoluteVirtuals:{description:"If true, the virtual symlinks will use absolute paths if required [non portable!!]",type:T.BOOLEAN,default:!1},enableColors:{description:"If true, the CLI is allowed to use colors in its output",type:T.BOOLEAN,default:N.supportsColor,defaultText:""},enableHyperlinks:{description:"If true, the CLI is allowed to use hyperlinks in its output",type:T.BOOLEAN,default:N.supportsHyperlinks,defaultText:""},enableInlineBuilds:{description:"If true, the CLI will print the build output on the command line",type:T.BOOLEAN,default:c.isCI,defaultText:""},enableProgressBars:{description:"If true, the CLI is allowed to show a progress bar for long-running events",type:T.BOOLEAN,default:!c.isCI&&process.stdout.isTTY&&process.stdout.columns>22,defaultText:""},enableTimers:{description:"If true, the CLI is allowed to print the time spent executing commands",type:T.BOOLEAN,default:!0},preferAggregateCacheInfo:{description:"If true, the CLI will only print a one-line report of any cache changes",type:T.BOOLEAN,default:c.isCI},preferInteractive:{description:"If true, the CLI will automatically use the interactive mode when called from a TTY",type:T.BOOLEAN,default:!1},preferTruncatedLines:{description:"If true, the CLI will truncate lines that would go beyond the size of the terminal",type:T.BOOLEAN,default:!1},progressBarStyle:{description:"Which style of progress bar should be used (only when progress bars are enabled)",type:T.STRING,default:void 0,defaultText:""},defaultLanguageName:{description:"Default language mode that should be used when a package doesn't offer any insight",type:T.STRING,default:"node"},defaultProtocol:{description:"Default resolution protocol used when resolving pure semver and tag ranges",type:T.STRING,default:"npm:"},enableTransparentWorkspaces:{description:"If false, Yarn won't automatically resolve workspace dependencies unless they use the `workspace:` protocol",type:T.BOOLEAN,default:!0},enableMirror:{description:"If true, the downloaded packages will be retrieved and stored in both the local and global folders",type:T.BOOLEAN,default:!0},enableNetwork:{description:"If false, the package manager will refuse to use the network if required to",type:T.BOOLEAN,default:!0},httpProxy:{description:"URL of the http proxy that must be used for outgoing http requests",type:T.STRING,default:null},httpsProxy:{description:"URL of the http proxy that must be used for outgoing https requests",type:T.STRING,default:null},unsafeHttpWhitelist:{description:"List of the hostnames for which http queries are allowed (glob patterns are supported)",type:T.STRING,default:[],isArray:!0},httpTimeout:{description:"Timeout of each http request in milliseconds",type:T.NUMBER,default:6e4},httpRetry:{description:"Retry times on http failure",type:T.NUMBER,default:3},networkConcurrency:{description:"Maximal number of concurrent requests",type:T.NUMBER,default:1/0},networkSettings:{description:"Network settings per hostname (glob patterns are supported)",type:T.MAP,valueDefinition:{description:"",type:T.SHAPE,properties:{caFilePath:{description:"Path to file containing one or multiple Certificate Authority signing certificates",type:T.ABSOLUTE_PATH,default:null},enableNetwork:{description:"If false, the package manager will refuse to use the network if required to",type:T.BOOLEAN,default:null},httpProxy:{description:"URL of the http proxy that must be used for outgoing http requests",type:T.STRING,default:null},httpsProxy:{description:"URL of the http proxy that must be used for outgoing https requests",type:T.STRING,default:null}}}},caFilePath:{description:"A path to a file containing one or multiple Certificate Authority signing certificates",type:T.ABSOLUTE_PATH,default:null},enableStrictSsl:{description:"If false, SSL certificate errors will be ignored",type:T.BOOLEAN,default:!0},logFilters:{description:"Overrides for log levels",type:T.SHAPE,isArray:!0,concatenateValues:!0,properties:{code:{description:"Code of the messages covered by this override",type:T.STRING,default:void 0},text:{description:"Code of the texts covered by this override",type:T.STRING,default:void 0},level:{description:"Log level override, set to null to remove override",type:T.STRING,values:Object.values(N.LogLevel),isNullable:!0,default:void 0}}},enableTelemetry:{description:"If true, telemetry will be periodically sent, following the rules in https://yarnpkg.com/advanced/telemetry",type:T.BOOLEAN,default:!0},telemetryInterval:{description:"Minimal amount of time between two telemetry uploads, in days",type:T.NUMBER,default:7},telemetryUserId:{description:"If you desire to tell us which project you are, you can set this field. Completely optional and opt-in.",type:T.STRING,default:null},enableScripts:{description:"If true, packages are allowed to have install scripts by default",type:T.BOOLEAN,default:!0},enableImmutableCache:{description:"If true, the cache is reputed immutable and actions that would modify it will throw",type:T.BOOLEAN,default:!1},checksumBehavior:{description:"Enumeration defining what to do when a checksum doesn't match expectations",type:T.STRING,default:"throw"},packageExtensions:{description:"Map of package corrections to apply on the dependency tree",type:T.MAP,valueDefinition:{description:"The extension that will be applied to any package whose version matches the specified range",type:T.SHAPE,properties:{dependencies:{description:"The set of dependencies that must be made available to the current package in order for it to work properly",type:T.MAP,valueDefinition:{description:"A range",type:T.STRING}},peerDependencies:{description:"Inherited dependencies - the consumer of the package will be tasked to provide them",type:T.MAP,valueDefinition:{description:"A semver range",type:T.STRING}},peerDependenciesMeta:{description:"Extra information related to the dependencies listed in the peerDependencies field",type:T.MAP,valueDefinition:{description:"The peerDependency meta",type:T.SHAPE,properties:{optional:{description:"If true, the selected peer dependency will be marked as optional by the package manager and the consumer omitting it won't be reported as an error",type:T.BOOLEAN,default:!1}}}}}}}};function G(e,t,r,A,n){if(A.isArray)return Array.isArray(r)?r.map((r,o)=>H(e,`${t}[${o}]`,r,A,n)):String(r).split(/,/).map(r=>H(e,t,r,A,n));if(Array.isArray(r))throw new Error(`Non-array configuration settings "${t}" cannot be an array`);return H(e,t,r,A,n)}function H(e,t,r,A,o){var i;switch(A.type){case T.ANY:return r;case T.SHAPE:return function(e,t,r,A,n){if("object"!=typeof r||Array.isArray(r))throw new g.UsageError(`Object configuration settings "${t}" must be an object`);const o=J(e,A,{ignoreArrays:!0});if(null===r)return o;for(const[i,s]of Object.entries(r)){const r=`${t}.${i}`;if(!A.properties[i])throw new g.UsageError(`Unrecognized configuration settings found: ${t}.${i} - run "yarn config -v" to see the list of settings supported in Yarn`);o.set(i,G(e,r,s,A.properties[i],n))}return o}(e,t,r,A,o);case T.MAP:return function(e,t,r,A,n){const o=new Map;if("object"!=typeof r||Array.isArray(r))throw new g.UsageError(`Map configuration settings "${t}" must be an object`);if(null===r)return o;for(const[i,s]of Object.entries(r)){const r=A.normalizeKeys?A.normalizeKeys(i):i,a=`${t}['${r}']`,c=A.valueDefinition;o.set(r,G(e,a,s,c,n))}return o}(e,t,r,A,o)}if(null===r&&!A.isNullable&&null!==A.default)throw new Error(`Non-nullable configuration settings "${t}" cannot be set to null`);if(null===(i=A.values)||void 0===i?void 0:i.includes(r))return r;const s=(()=>{if(A.type===T.BOOLEAN)return F.parseBoolean(r);if("string"!=typeof r)throw new Error(`Expected value (${r}) to be a string`);const e=F.replaceEnvVariables(r,{env:process.env});switch(A.type){case T.ABSOLUTE_PATH:return n.y1.resolve(o,n.cS.toPortablePath(e));case T.LOCATOR_LOOSE:return f.parseLocator(e,!1);case T.NUMBER:return parseInt(e);case T.LOCATOR:return f.parseLocator(e);default:return e}})();if(A.values&&!A.values.includes(s))throw new Error("Invalid value, expected one of "+A.values.join(", "));return s}function J(e,t,{ignoreArrays:r=!1}={}){switch(t.type){case T.SHAPE:{if(t.isArray&&!r)return[];const A=new Map;for(const[r,n]of Object.entries(t.properties))A.set(r,J(e,n));return A}case T.MAP:return t.isArray&&!r?[]:new Map;case T.ABSOLUTE_PATH:return null===t.default?null:null===e.projectCwd?n.y1.isAbsolute(t.default)?n.y1.normalize(t.default):t.isNullable?null:void 0:Array.isArray(t.default)?t.default.map(t=>n.y1.resolve(e.projectCwd,t)):n.y1.resolve(e.projectCwd,t.default);default:return t.default}}function q(){for(const[e,t]of Object.entries(process.env))if("yarn_rc_filename"===e.toLowerCase()&&"string"==typeof t)return t;return O}var z;!function(e){e[e.LOCKFILE=0]="LOCKFILE",e[e.MANIFEST=1]="MANIFEST",e[e.NONE=2]="NONE"}(z||(z={}));class W{constructor(e){this.projectCwd=null,this.plugins=new Map,this.settings=new Map,this.values=new Map,this.sources=new Map,this.invalid=new Map,this.packageExtensions=new Map,this.limits=new Map,this.startingCwd=e}static create(e,t,r){const A=new W(e);void 0===t||t instanceof Map||(A.projectCwd=t),A.importSettings(Y);const n=void 0!==r?r:t instanceof Map?t:new Map;for(const[e,t]of n)A.activatePlugin(e,t);return A}static async find(e,t,{lookup:r=z.LOCKFILE,strict:o=!0,usePath:i=!1,useRc:s=!0}={}){const c=function(){const e={};for(let[t,r]of Object.entries(process.env))t=t.toLowerCase(),t.startsWith("yarn_")&&(t=a()(t.slice("yarn_".length)),e[t]=r);return e}();delete c.rcFilename;const l=await W.findRcFiles(e),u=await W.findHomeRcFile(),h=({ignoreCwd:e,yarnPath:t,ignorePath:r,lockfileFilename:A})=>({ignoreCwd:e,yarnPath:t,ignorePath:r,lockfileFilename:A}),p=({ignoreCwd:e,yarnPath:t,ignorePath:r,lockfileFilename:A,...n})=>n,d=new W(e);d.importSettings(h(Y)),d.useWithSource("",h(c),e,{strict:!1});for(const{path:e,cwd:t,data:r}of l)d.useWithSource(e,h(r),t,{strict:!1});if(u&&d.useWithSource(u.path,h(u.data),u.cwd,{strict:!1}),i){const e=d.get("yarnPath"),t=d.get("ignorePath");if(null!==e&&!t)return d}const C=d.get("lockfileFilename");let f;switch(r){case z.LOCKFILE:f=await W.findProjectCwd(e,C);break;case z.MANIFEST:f=await W.findProjectCwd(e,null);break;case z.NONE:f=A.xfs.existsSync(n.y1.join(e,"package.json"))?n.y1.resolve(e):null}d.startingCwd=e,d.projectCwd=f,d.importSettings(p(Y));const E=new Map([["@@core",I]]);if(null!==t){for(const e of t.plugins.keys())E.set(e,(B=t.modules.get(e)).__esModule?B.default:B);const r=new Map;for(const e of new Set(M().builtinModules||Object.keys(process.binding("natives"))))r.set(e,()=>R(e));for(const[e,A]of t.modules)r.set(e,()=>A);const A=new Set,o=e=>e.default||e,i=(e,t)=>{const{factory:i,name:s}=R(n.cS.fromPortablePath(e));if(A.has(s))return;const a=new Map(r),c=e=>{if(a.has(e))return a.get(e)();throw new g.UsageError(`This plugin cannot access the package referenced via ${e} which is neither a builtin, nor an exposed entry`)},l=F.prettifySyncErrors(()=>o(i(c)),e=>`${e} (when initializing ${s}, defined in ${t})`);r.set(s,()=>l),A.add(s),E.set(s,l)};if(c.plugins)for(const t of c.plugins.split(";")){i(n.y1.resolve(e,n.cS.toPortablePath(t)),"")}for(const{path:e,cwd:t,data:r}of l)if(s&&Array.isArray(r.plugins))for(const A of r.plugins){const r="string"!=typeof A?A.path:A;i(n.y1.resolve(t,n.cS.toPortablePath(r)),e)}}var B;for(const[e,t]of E)d.activatePlugin(e,t);d.useWithSource("",p(c),e,{strict:o});for(const{path:e,cwd:t,data:r}of l)d.useWithSource(e,p(r),t,{strict:o});return u&&d.useWithSource(u.path,p(u.data),u.cwd,{strict:!1}),d.get("enableGlobalCache")&&(d.values.set("cacheFolder",d.get("globalFolder")+"/cache"),d.sources.set("cacheFolder","")),await d.refreshPackageExtensions(),d}static async findRcFiles(e){const t=q(),r=[];let o=e,s=null;for(;o!==s;){s=o;const e=n.y1.join(s,t);if(A.xfs.existsSync(e)){const t=await A.xfs.readFilePromise(e,"utf8");let n;try{n=(0,i.parseSyml)(t)}catch(r){let A="";throw t.match(/^\s+(?!-)[^:]+\s+\S+/m)&&(A=" (in particular, make sure you list the colons after each key name)"),new g.UsageError(`Parse error when loading ${e}; please check it's proper Yaml${A}`)}r.push({path:e,cwd:s,data:n})}o=n.y1.dirname(s)}return r}static async findHomeRcFile(){const e=q(),t=k.getHomeFolder(),r=n.y1.join(t,e);if(A.xfs.existsSync(r)){const e=await A.xfs.readFilePromise(r,"utf8");return{path:r,cwd:t,data:(0,i.parseSyml)(e)}}return null}static async findProjectCwd(e,t){let r=null,o=e,i=null;for(;o!==i;){if(i=o,A.xfs.existsSync(n.y1.join(i,"package.json"))&&(r=i),null!==t){if(A.xfs.existsSync(n.y1.join(i,t))){r=i;break}}else if(null!==r)break;o=n.y1.dirname(i)}return r}static async updateConfiguration(e,t){const r=q(),o=n.y1.join(e,r),s=A.xfs.existsSync(o)?(0,i.parseSyml)(await A.xfs.readFilePromise(o,"utf8")):{};let a,c=!1;if("function"==typeof t){try{a=t(s)}catch(e){a=t({})}if(a===s)return}else{a=s;for(const e of Object.keys(t)){const r=s[e],A=t[e];let n;if("function"==typeof A)try{n=A(r)}catch(e){n=A(void 0)}else n=A;r!==n&&(a[e]=n,c=!0)}if(!c)return}await A.xfs.changeFilePromise(o,(0,i.stringifySyml)(a),{automaticNewlines:!0})}static async updateHomeConfiguration(e){const t=k.getHomeFolder();return await W.updateConfiguration(t,e)}activatePlugin(e,t){this.plugins.set(e,t),void 0!==t.configuration&&this.importSettings(t.configuration)}importSettings(e){for(const[t,r]of Object.entries(e))if(null!=r){if(this.settings.has(t))throw new Error(`Cannot redefine settings "${t}"`);this.settings.set(t,r),this.values.set(t,J(this,r))}}useWithSource(e,t,r,A){try{this.use(e,t,r,A)}catch(t){throw t.message+=` (in ${N.pretty(this,e,N.Type.PATH)})`,t}}use(e,t,r,{strict:A=!0,overwrite:n=!1}={}){for(const o of Object.keys(t)){if(void 0===t[o])continue;if("plugins"===o)continue;if(""===e&&P.has(o))continue;if("rcFilename"===o)throw new g.UsageError(`The rcFilename settings can only be set via ${"yarn_RC_FILENAME".toUpperCase()}, not via a rc file`);const i=this.settings.get(o);if(!i){if(A)throw new g.UsageError(`Unrecognized or legacy configuration settings found: ${o} - run "yarn config -v" to see the list of settings supported in Yarn`);this.invalid.set(o,e);continue}if(this.sources.has(o)&&!(n||i.type===T.MAP||i.isArray&&i.concatenateValues))continue;let s;try{s=G(this,o,t[o],i,r)}catch(t){throw t.message+=" in "+N.pretty(this,e,N.Type.PATH),t}if(i.type===T.MAP){const t=this.values.get(o);this.values.set(o,new Map(n?[...t,...s]:[...s,...t])),this.sources.set(o,`${this.sources.get(o)}, ${e}`)}else if(i.isArray&&i.concatenateValues){const t=this.values.get(o);this.values.set(o,n?[...t,...s]:[...s,...t]),this.sources.set(o,`${this.sources.get(o)}, ${e}`)}else this.values.set(o,s),this.sources.set(o,e)}}get(e){if(!this.values.has(e))throw new Error(`Invalid configuration key "${e}"`);return this.values.get(e)}getSpecial(e,{hideSecrets:t=!1,getNativePaths:r=!1}){const A=this.get(e),o=this.settings.get(e);if(void 0===o)throw new g.UsageError(`Couldn't find a configuration settings named "${e}"`);return function e(t,r,A){if(r.type===T.SECRET&&"string"==typeof t&&A.hideSecrets)return"********";if(r.type===T.ABSOLUTE_PATH&&"string"==typeof t&&A.getNativePaths)return n.cS.fromPortablePath(t);if(r.isArray&&Array.isArray(t)){const n=[];for(const o of t)n.push(e(o,r,A));return n}if(r.type===T.MAP&&t instanceof Map){const n=new Map;for(const[o,i]of t.entries())n.set(o,e(i,r.valueDefinition,A));return n}if(r.type===T.SHAPE&&t instanceof Map){const n=new Map;for(const[o,i]of t.entries()){const t=r.properties[o];n.set(o,e(i,t,A))}return n}return t}(A,o,{hideSecrets:t,getNativePaths:r})}getSubprocessStreams(e,{header:t,prefix:r,report:n}){let o,i;const s=A.xfs.createWriteStream(e);if(this.get("enableInlineBuilds")){const e=n.createStreamReporter(`${r} ${N.pretty(this,"STDOUT","green")}`),t=n.createStreamReporter(`${r} ${N.pretty(this,"STDERR","red")}`);o=new d.PassThrough,o.pipe(e),o.pipe(s),i=new d.PassThrough,i.pipe(t),i.pipe(s)}else o=s,i=s,void 0!==t&&o.write(t+"\n");return{stdout:o,stderr:i}}makeResolver(){const e=[];for(const t of this.plugins.values())for(const r of t.resolvers||[])e.push(new r);return new m.B([new D,new v.d,new w.O,...e])}makeFetcher(){const e=[];for(const t of this.plugins.values())for(const r of t.fetchers||[])e.push(new r);return new y([new Q.N,new S,...e])}getLinkers(){const e=[];for(const t of this.plugins.values())for(const r of t.linkers||[])e.push(new r);return e}async refreshPackageExtensions(){this.packageExtensions=new Map;const e=this.packageExtensions,t=(t,r,{userProvided:A=!1}={})=>{if(!p().validRange(t.range))throw new Error("Only semver ranges are allowed as keys for the lockfileExtensions setting");const n=new E.G;n.load(r,{yamlCompatibilityMode:!0});const o=[];F.getArrayWithDefault(e,t.identHash).push([t.range,o]);const i={status:L._u.Inactive,userProvided:A,parentDescriptor:t};for(const e of n.dependencies.values())o.push({...i,type:L.HN.Dependency,descriptor:e,description:`${f.stringifyIdent(t)} > ${f.stringifyIdent(e)}`});for(const e of n.peerDependencies.values())o.push({...i,type:L.HN.PeerDependency,descriptor:e,description:`${f.stringifyIdent(t)} >> ${f.stringifyIdent(e)}`});for(const[e,r]of n.peerDependenciesMeta)for(const[A,n]of Object.entries(r))o.push({...i,type:L.HN.PeerDependencyMeta,selector:e,key:A,value:n,description:`${f.stringifyIdent(t)} >> ${e} / ${A}`})};await this.triggerHook(e=>e.registerPackageExtensions,this,t);for(const[e,r]of this.get("packageExtensions"))t(f.parseDescriptor(e,!0),F.convertMapsToIndexableObjects(r),{userProvided:!0})}normalizePackage(e){const t=f.copyPackage(e);if(null==this.packageExtensions)throw new Error("refreshPackageExtensions has to be called before normalizing packages");const r=this.packageExtensions.get(e.identHash);if(void 0!==r){const A=e.version;if(null!==A)for(const[e,n]of r)if(x.satisfiesWithPrereleases(A,e))for(const e of n)switch(e.status===L._u.Inactive&&(e.status=L._u.Redundant),e.type){case L.HN.Dependency:void 0===t.dependencies.get(e.descriptor.identHash)&&(e.status=L._u.Active,t.dependencies.set(e.descriptor.identHash,e.descriptor));break;case L.HN.PeerDependency:void 0===t.peerDependencies.get(e.descriptor.identHash)&&(e.status=L._u.Active,t.peerDependencies.set(e.descriptor.identHash,e.descriptor));break;case L.HN.PeerDependencyMeta:{const r=t.peerDependenciesMeta.get(e.selector);void 0!==r&&Object.prototype.hasOwnProperty.call(r,e.key)&&r[e.key]===e.value||(e.status=L._u.Active,F.getFactoryWithDefault(t.peerDependenciesMeta,e.selector,()=>({}))[e.key]=e.value)}break;default:F.assertNever(e)}}const A=e=>e.scope?`${e.scope}__${e.name}`:""+e.name;for(const e of t.peerDependencies.values()){if("@types"===e.scope)continue;const r=A(e),n=f.makeIdent("types",r);t.peerDependencies.has(n.identHash)||t.peerDependenciesMeta.has(n.identHash)||t.peerDependenciesMeta.set(f.stringifyIdent(n),{optional:!0})}for(const e of t.peerDependenciesMeta.keys()){const r=f.parseIdent(e);t.peerDependencies.has(r.identHash)||t.peerDependencies.set(r.identHash,f.makeDescriptor(r,"*"))}return t.dependencies=new Map(F.sortMap(t.dependencies,([,e])=>f.stringifyDescriptor(e))),t.peerDependencies=new Map(F.sortMap(t.peerDependencies,([,e])=>f.stringifyDescriptor(e))),t}getLimit(e){return F.getFactoryWithDefault(this.limits,e,()=>u()(this.get(e)))}async triggerHook(e,...t){for(const r of this.plugins.values()){const A=r.hooks;if(!A)continue;const n=e(A);n&&await n(...t)}}async triggerMultipleHooks(e,t){for(const r of t)await this.triggerHook(e,...r)}async reduceHook(e,t,...r){let A=t;for(const t of this.plugins.values()){const n=t.hooks;if(!n)continue;const o=e(n);o&&(A=await o(A,...r))}return A}async firstHook(e,...t){for(const r of this.plugins.values()){const A=r.hooks;if(!A)continue;const n=e(A);if(!n)continue;const o=await n(...t);if(void 0!==o)return o}return null}format(e,t){return N.pretty(this,e,t)}}W.telemetry=null},92409:(e,t,r)=>{"use strict";var A;r.d(t,{k:()=>A}),function(e){e[e.SCRIPT=0]="SCRIPT",e[e.SHELLCODE=1]="SHELLCODE"}(A||(A={}))},62152:(e,t,r)=>{"use strict";r.d(t,{h:()=>i});var A=r(35691),n=r(15815),o=r(71643);class i extends A.yG{constructor({configuration:e,stdout:t,suggestInstall:r=!0}){super(),this.errorCount=0,o.addLogFilterSupport(this,{configuration:e}),this.configuration=e,this.stdout=t,this.suggestInstall=r}static async start(e,t){const r=new this(e);try{await t(r)}catch(e){r.reportExceptionOnce(e)}finally{await r.finalize()}return r}hasErrors(){return this.errorCount>0}exitCode(){return this.hasErrors()?1:0}reportCacheHit(e){}reportCacheMiss(e){}startTimerSync(e,t,r){return("function"==typeof t?t:r)()}async startTimerPromise(e,t,r){const A="function"==typeof t?t:r;return await A()}async startCacheReport(e){return await e()}reportSeparator(){}reportInfo(e,t){}reportWarning(e,t){}reportError(e,t){this.errorCount+=1,this.stdout.write(`${o.pretty(this.configuration,"➤","redBright")} ${this.formatNameWithHyperlink(e)}: ${t}\n`)}reportProgress(e){return{...Promise.resolve().then(async()=>{for await(const{}of e);}),stop:()=>{}}}reportJson(e){}async finalize(){this.errorCount>0&&(this.stdout.write(o.pretty(this.configuration,"➤","redBright")+" Errors happened when preparing the environment required to run this command.\n"),this.suggestInstall&&this.stdout.write(o.pretty(this.configuration,"➤","redBright")+' This might be caused by packages being missing from the lockfile, in which case running "yarn install" might help.\n'))}formatNameWithHyperlink(e){return(0,n.Qw)(e,{configuration:this.configuration,json:!1})}}},46611:(e,t,r)=>{"use strict";r.d(t,{G:()=>l});var A=r(78420),n=r(46009),o=r(11640),i=r(53887),s=r.n(i),a=r(73632),c=r(36545),g=r(54143);class l{constructor(){this.indent=" ",this.name=null,this.version=null,this.os=null,this.cpu=null,this.type=null,this.private=!1,this.license=null,this.main=null,this.module=null,this.browser=null,this.languageName=null,this.bin=new Map,this.scripts=new Map,this.dependencies=new Map,this.devDependencies=new Map,this.peerDependencies=new Map,this.workspaceDefinitions=[],this.dependenciesMeta=new Map,this.peerDependenciesMeta=new Map,this.resolutions=[],this.files=null,this.publishConfig=null,this.installConfig=null,this.preferUnplugged=null,this.raw={},this.errors=[]}static async tryFind(e,{baseFs:t=new A.S}={}){const r=n.y1.join(e,"package.json");return await t.existsPromise(r)?await l.fromFile(r,{baseFs:t}):null}static async find(e,{baseFs:t}={}){const r=await l.tryFind(e,{baseFs:t});if(null===r)throw new Error("Manifest not found");return r}static async fromFile(e,{baseFs:t=new A.S}={}){const r=new l;return await r.loadFile(e,{baseFs:t}),r}static fromText(e){const t=new l;return t.loadFromText(e),t}static isManifestFieldCompatible(e,t){if(null===e)return!0;let r=!0,A=!1;for(const n of e)if("!"===n[0]){if(A=!0,t===n.slice(1))return!1}else if(r=!1,n===t)return!0;return A&&r}loadFromText(e){let t;try{t=JSON.parse(h(e)||"{}")}catch(t){throw t.message+=` (when parsing ${e})`,t}this.load(t),this.indent=u(e)}async loadFile(e,{baseFs:t=new A.S}){const r=await t.readFilePromise(e,"utf8");let n;try{n=JSON.parse(h(r)||"{}")}catch(t){throw t.message+=` (when parsing ${e})`,t}this.load(n),this.indent=u(r)}load(e,{yamlCompatibilityMode:t=!1}={}){if("object"!=typeof e||null===e)throw new Error(`Utterly invalid manifest data (${e})`);this.raw=e;const r=[];if("string"==typeof e.name)try{this.name=g.parseIdent(e.name)}catch(e){r.push(new Error("Parsing failed for the 'name' field"))}if("string"==typeof e.version&&(this.version=e.version),Array.isArray(e.os)){const t=[];this.os=t;for(const A of e.os)"string"!=typeof A?r.push(new Error("Parsing failed for the 'os' field")):t.push(A)}if(Array.isArray(e.cpu)){const t=[];this.cpu=t;for(const A of e.cpu)"string"!=typeof A?r.push(new Error("Parsing failed for the 'cpu' field")):t.push(A)}if("string"==typeof e.type&&(this.type=e.type),"boolean"==typeof e.private&&(this.private=e.private),"string"==typeof e.license&&(this.license=e.license),"string"==typeof e.languageName&&(this.languageName=e.languageName),"string"==typeof e.main&&(this.main=p(e.main)),"string"==typeof e.module&&(this.module=p(e.module)),null!=e.browser)if("string"==typeof e.browser)this.browser=p(e.browser);else{this.browser=new Map;for(const[t,r]of Object.entries(e.browser))this.browser.set(p(t),"string"==typeof r?p(r):r)}if("string"==typeof e.bin)null!==this.name?this.bin=new Map([[this.name.name,p(e.bin)]]):r.push(new Error("String bin field, but no attached package name"));else if("object"==typeof e.bin&&null!==e.bin)for(const[t,A]of Object.entries(e.bin))"string"==typeof A?this.bin.set(t,p(A)):r.push(new Error(`Invalid bin definition for '${t}'`));if("object"==typeof e.scripts&&null!==e.scripts)for(const[t,A]of Object.entries(e.scripts))"string"==typeof A?this.scripts.set(t,A):r.push(new Error(`Invalid script definition for '${t}'`));if("object"==typeof e.dependencies&&null!==e.dependencies)for(const[t,A]of Object.entries(e.dependencies)){if("string"!=typeof A){r.push(new Error(`Invalid dependency range for '${t}'`));continue}let e;try{e=g.parseIdent(t)}catch(e){r.push(new Error(`Parsing failed for the dependency name '${t}'`));continue}const n=g.makeDescriptor(e,A);this.dependencies.set(n.identHash,n)}if("object"==typeof e.devDependencies&&null!==e.devDependencies)for(const[t,A]of Object.entries(e.devDependencies)){if("string"!=typeof A){r.push(new Error(`Invalid dependency range for '${t}'`));continue}let e;try{e=g.parseIdent(t)}catch(e){r.push(new Error(`Parsing failed for the dependency name '${t}'`));continue}const n=g.makeDescriptor(e,A);this.devDependencies.set(n.identHash,n)}if("object"==typeof e.peerDependencies&&null!==e.peerDependencies)for(let[t,A]of Object.entries(e.peerDependencies)){let e;try{e=g.parseIdent(t)}catch(e){r.push(new Error(`Parsing failed for the dependency name '${t}'`));continue}"string"==typeof A&&c.validRange(A)||(r.push(new Error(`Invalid dependency range for '${t}'`)),A="*");const n=g.makeDescriptor(e,A);this.peerDependencies.set(n.identHash,n)}"object"==typeof e.workspaces&&e.workspaces.nohoist&&r.push(new Error("'nohoist' is deprecated, please use 'installConfig.hoistingLimits' instead"));const A=Array.isArray(e.workspaces)?e.workspaces:"object"==typeof e.workspaces&&null!==e.workspaces&&Array.isArray(e.workspaces.packages)?e.workspaces.packages:[];for(const e of A)"string"==typeof e?this.workspaceDefinitions.push({pattern:e}):r.push(new Error(`Invalid workspace definition for '${e}'`));if("object"==typeof e.dependenciesMeta&&null!==e.dependenciesMeta)for(const[A,n]of Object.entries(e.dependenciesMeta)){if("object"!=typeof n||null===n){r.push(new Error("Invalid meta field for '"+A));continue}const e=g.parseDescriptor(A),o=this.ensureDependencyMeta(e),i=d(n.built,{yamlCompatibilityMode:t});if(null===i){r.push(new Error(`Invalid built meta field for '${A}'`));continue}const s=d(n.optional,{yamlCompatibilityMode:t});if(null===s){r.push(new Error(`Invalid optional meta field for '${A}'`));continue}const a=d(n.unplugged,{yamlCompatibilityMode:t});null!==a?Object.assign(o,{built:i,optional:s,unplugged:a}):r.push(new Error(`Invalid unplugged meta field for '${A}'`))}if("object"==typeof e.peerDependenciesMeta&&null!==e.peerDependenciesMeta)for(const[A,n]of Object.entries(e.peerDependenciesMeta)){if("object"!=typeof n||null===n){r.push(new Error(`Invalid meta field for '${A}'`));continue}const e=g.parseDescriptor(A),o=this.ensurePeerDependencyMeta(e),i=d(n.optional,{yamlCompatibilityMode:t});null!==i?Object.assign(o,{optional:i}):r.push(new Error(`Invalid optional meta field for '${A}'`))}if("object"==typeof e.resolutions&&null!==e.resolutions)for(const[t,A]of Object.entries(e.resolutions))if("string"==typeof A)try{this.resolutions.push({pattern:(0,o.parseResolution)(t),reference:A})}catch(e){r.push(e);continue}else r.push(new Error(`Invalid resolution entry for '${t}'`));if(Array.isArray(e.files)){this.files=new Set;for(const t of e.files)"string"==typeof t?this.files.add(t):r.push(new Error(`Invalid files entry for '${t}'`))}if("object"==typeof e.publishConfig&&null!==e.publishConfig){if(this.publishConfig={},"string"==typeof e.publishConfig.access&&(this.publishConfig.access=e.publishConfig.access),"string"==typeof e.publishConfig.main&&(this.publishConfig.main=p(e.publishConfig.main)),"string"==typeof e.publishConfig.module&&(this.publishConfig.module=p(e.publishConfig.module)),null!=e.publishConfig.browser)if("string"==typeof e.publishConfig.browser)this.publishConfig.browser=p(e.publishConfig.browser);else{this.publishConfig.browser=new Map;for(const[t,r]of Object.entries(e.publishConfig.browser))this.publishConfig.browser.set(p(t),"string"==typeof r?p(r):r)}if("string"==typeof e.publishConfig.registry&&(this.publishConfig.registry=e.publishConfig.registry),"string"==typeof e.publishConfig.bin)null!==this.name?this.publishConfig.bin=new Map([[this.name.name,p(e.publishConfig.bin)]]):r.push(new Error("String bin field, but no attached package name"));else if("object"==typeof e.publishConfig.bin&&null!==e.publishConfig.bin){this.publishConfig.bin=new Map;for(const[t,A]of Object.entries(e.publishConfig.bin))"string"==typeof A?this.publishConfig.bin.set(t,p(A)):r.push(new Error(`Invalid bin definition for '${t}'`))}if(Array.isArray(e.publishConfig.executableFiles)){this.publishConfig.executableFiles=new Set;for(const t of e.publishConfig.executableFiles)"string"==typeof t?this.publishConfig.executableFiles.add(p(t)):r.push(new Error("Invalid executable file definition"))}}if("object"==typeof e.installConfig&&null!==e.installConfig){this.installConfig={};for(const t of Object.keys(e.installConfig))"hoistingLimits"===t?"string"==typeof e.installConfig.hoistingLimits?this.installConfig.hoistingLimits=e.installConfig.hoistingLimits:r.push(new Error("Invalid hoisting limits definition")):r.push(new Error("Unrecognized installConfig key: "+t))}if("object"==typeof e.optionalDependencies&&null!==e.optionalDependencies)for(const[t,A]of Object.entries(e.optionalDependencies)){if("string"!=typeof A){r.push(new Error(`Invalid dependency range for '${t}'`));continue}let e;try{e=g.parseIdent(t)}catch(e){r.push(new Error(`Parsing failed for the dependency name '${t}'`));continue}const n=g.makeDescriptor(e,A);this.dependencies.set(n.identHash,n);const o=g.makeDescriptor(e,"unknown"),i=this.ensureDependencyMeta(o);Object.assign(i,{optional:!0})}"boolean"==typeof e.preferUnplugged&&(this.preferUnplugged=e.preferUnplugged),this.errors=r}getForScope(e){switch(e){case"dependencies":return this.dependencies;case"devDependencies":return this.devDependencies;case"peerDependencies":return this.peerDependencies;default:throw new Error(`Unsupported value ("${e}")`)}}hasConsumerDependency(e){return!!this.dependencies.has(e.identHash)||!!this.peerDependencies.has(e.identHash)}hasHardDependency(e){return!!this.dependencies.has(e.identHash)||!!this.devDependencies.has(e.identHash)}hasSoftDependency(e){return!!this.peerDependencies.has(e.identHash)}hasDependency(e){return!!this.hasHardDependency(e)||!!this.hasSoftDependency(e)}isCompatibleWithOS(e){return l.isManifestFieldCompatible(this.os,e)}isCompatibleWithCPU(e){return l.isManifestFieldCompatible(this.cpu,e)}ensureDependencyMeta(e){if("unknown"!==e.range&&!s().valid(e.range))throw new Error(`Invalid meta field range for '${g.stringifyDescriptor(e)}'`);const t=g.stringifyIdent(e),r="unknown"!==e.range?e.range:null;let A=this.dependenciesMeta.get(t);A||this.dependenciesMeta.set(t,A=new Map);let n=A.get(r);return n||A.set(r,n={}),n}ensurePeerDependencyMeta(e){if("unknown"!==e.range)throw new Error(`Invalid meta field range for '${g.stringifyDescriptor(e)}'`);const t=g.stringifyIdent(e);let r=this.peerDependenciesMeta.get(t);return r||this.peerDependenciesMeta.set(t,r={}),r}setRawField(e,t,{after:r=[]}={}){const A=new Set(r.filter(e=>Object.prototype.hasOwnProperty.call(this.raw,e)));if(0===A.size||Object.prototype.hasOwnProperty.call(this.raw,e))this.raw[e]=t;else{const r=this.raw,n=this.raw={};let o=!1;for(const i of Object.keys(r))n[i]=r[i],o||(A.delete(i),0===A.size&&(n[e]=t,o=!0))}}exportTo(e,{compatibilityMode:t=!0}={}){if(Object.assign(e,this.raw),null!==this.name?e.name=g.stringifyIdent(this.name):delete e.name,null!==this.version?e.version=this.version:delete e.version,null!==this.os?e.os=this.os:delete e.os,null!==this.cpu?e.cpu=this.cpu:delete e.cpu,null!==this.type?e.type=this.type:delete e.type,this.private?e.private=!0:delete e.private,null!==this.license?e.license=this.license:delete e.license,null!==this.languageName?e.languageName=this.languageName:delete e.languageName,null!==this.main?e.main=this.main:delete e.main,null!==this.module?e.module=this.module:delete e.module,null!==this.browser){const t=this.browser;"string"==typeof t?e.browser=t:t instanceof Map&&(e.browser=Object.assign({},...Array.from(t.keys()).sort().map(e=>({[e]:t.get(e)}))))}else delete e.browser;1===this.bin.size&&null!==this.name&&this.bin.has(this.name.name)?e.bin=this.bin.get(this.name.name):this.bin.size>0?e.bin=Object.assign({},...Array.from(this.bin.keys()).sort().map(e=>({[e]:this.bin.get(e)}))):delete e.bin,this.workspaceDefinitions.length>0?this.raw.workspaces&&!Array.isArray(this.raw.workspaces)?e.workspaces={...this.raw.workspaces,packages:this.workspaceDefinitions.map(({pattern:e})=>e)}:e.workspaces=this.workspaceDefinitions.map(({pattern:e})=>e):this.raw.workspaces&&!Array.isArray(this.raw.workspaces)&&Object.keys(this.raw.workspaces).length>0?e.workspaces=this.raw.workspaces:delete e.workspaces;const r=[],A=[];for(const e of this.dependencies.values()){const n=this.dependenciesMeta.get(g.stringifyIdent(e));let o=!1;if(t&&n){const e=n.get(null);e&&e.optional&&(o=!0)}o?A.push(e):r.push(e)}r.length>0?e.dependencies=Object.assign({},...g.sortDescriptors(r).map(e=>({[g.stringifyIdent(e)]:e.range}))):delete e.dependencies,A.length>0?e.optionalDependencies=Object.assign({},...g.sortDescriptors(A).map(e=>({[g.stringifyIdent(e)]:e.range}))):delete e.optionalDependencies,this.devDependencies.size>0?e.devDependencies=Object.assign({},...g.sortDescriptors(this.devDependencies.values()).map(e=>({[g.stringifyIdent(e)]:e.range}))):delete e.devDependencies,this.peerDependencies.size>0?e.peerDependencies=Object.assign({},...g.sortDescriptors(this.peerDependencies.values()).map(e=>({[g.stringifyIdent(e)]:e.range}))):delete e.peerDependencies,e.dependenciesMeta={};for(const[r,A]of a.sortMap(this.dependenciesMeta.entries(),([e,t])=>e))for(const[n,o]of a.sortMap(A.entries(),([e,t])=>null!==e?"0"+e:"1")){const A=null!==n?g.stringifyDescriptor(g.makeDescriptor(g.parseIdent(r),n)):r,i={...o};t&&null===n&&delete i.optional,0!==Object.keys(i).length&&(e.dependenciesMeta[A]=i)}return 0===Object.keys(e.dependenciesMeta).length&&delete e.dependenciesMeta,this.peerDependenciesMeta.size>0?e.peerDependenciesMeta=Object.assign({},...a.sortMap(this.peerDependenciesMeta.entries(),([e,t])=>e).map(([e,t])=>({[e]:t}))):delete e.peerDependenciesMeta,this.resolutions.length>0?e.resolutions=Object.assign({},...this.resolutions.map(({pattern:e,reference:t})=>({[(0,o.stringifyResolution)(e)]:t}))):delete e.resolutions,null!==this.files?e.files=Array.from(this.files):delete e.files,null!==this.preferUnplugged?e.preferUnplugged=this.preferUnplugged:delete e.preferUnplugged,e}}function u(e){const t=e.match(/^[ \t]+/m);return t?t[0]:" "}function h(e){return 65279===e.charCodeAt(0)?e.slice(1):e}function p(e){return e.replace(/\\/g,"/")}function d(e,{yamlCompatibilityMode:t}){return t?a.tryParseOptionalBoolean(e):void 0===e||"boolean"==typeof e?e:null}l.fileName="package.json",l.allDependencies=["dependencies","devDependencies","peerDependencies"],l.hardDependencies=["dependencies","devDependencies"]},92659:(e,t,r)=>{"use strict";var A;function n(e){return"YN"+e.toString(10).padStart(4,"0")}r.d(t,{b:()=>A,i:()=>n}),function(e){e[e.UNNAMED=0]="UNNAMED",e[e.EXCEPTION=1]="EXCEPTION",e[e.MISSING_PEER_DEPENDENCY=2]="MISSING_PEER_DEPENDENCY",e[e.CYCLIC_DEPENDENCIES=3]="CYCLIC_DEPENDENCIES",e[e.DISABLED_BUILD_SCRIPTS=4]="DISABLED_BUILD_SCRIPTS",e[e.BUILD_DISABLED=5]="BUILD_DISABLED",e[e.SOFT_LINK_BUILD=6]="SOFT_LINK_BUILD",e[e.MUST_BUILD=7]="MUST_BUILD",e[e.MUST_REBUILD=8]="MUST_REBUILD",e[e.BUILD_FAILED=9]="BUILD_FAILED",e[e.RESOLVER_NOT_FOUND=10]="RESOLVER_NOT_FOUND",e[e.FETCHER_NOT_FOUND=11]="FETCHER_NOT_FOUND",e[e.LINKER_NOT_FOUND=12]="LINKER_NOT_FOUND",e[e.FETCH_NOT_CACHED=13]="FETCH_NOT_CACHED",e[e.YARN_IMPORT_FAILED=14]="YARN_IMPORT_FAILED",e[e.REMOTE_INVALID=15]="REMOTE_INVALID",e[e.REMOTE_NOT_FOUND=16]="REMOTE_NOT_FOUND",e[e.RESOLUTION_PACK=17]="RESOLUTION_PACK",e[e.CACHE_CHECKSUM_MISMATCH=18]="CACHE_CHECKSUM_MISMATCH",e[e.UNUSED_CACHE_ENTRY=19]="UNUSED_CACHE_ENTRY",e[e.MISSING_LOCKFILE_ENTRY=20]="MISSING_LOCKFILE_ENTRY",e[e.WORKSPACE_NOT_FOUND=21]="WORKSPACE_NOT_FOUND",e[e.TOO_MANY_MATCHING_WORKSPACES=22]="TOO_MANY_MATCHING_WORKSPACES",e[e.CONSTRAINTS_MISSING_DEPENDENCY=23]="CONSTRAINTS_MISSING_DEPENDENCY",e[e.CONSTRAINTS_INCOMPATIBLE_DEPENDENCY=24]="CONSTRAINTS_INCOMPATIBLE_DEPENDENCY",e[e.CONSTRAINTS_EXTRANEOUS_DEPENDENCY=25]="CONSTRAINTS_EXTRANEOUS_DEPENDENCY",e[e.CONSTRAINTS_INVALID_DEPENDENCY=26]="CONSTRAINTS_INVALID_DEPENDENCY",e[e.CANT_SUGGEST_RESOLUTIONS=27]="CANT_SUGGEST_RESOLUTIONS",e[e.FROZEN_LOCKFILE_EXCEPTION=28]="FROZEN_LOCKFILE_EXCEPTION",e[e.CROSS_DRIVE_VIRTUAL_LOCAL=29]="CROSS_DRIVE_VIRTUAL_LOCAL",e[e.FETCH_FAILED=30]="FETCH_FAILED",e[e.DANGEROUS_NODE_MODULES=31]="DANGEROUS_NODE_MODULES",e[e.NODE_GYP_INJECTED=32]="NODE_GYP_INJECTED",e[e.AUTHENTICATION_NOT_FOUND=33]="AUTHENTICATION_NOT_FOUND",e[e.INVALID_CONFIGURATION_KEY=34]="INVALID_CONFIGURATION_KEY",e[e.NETWORK_ERROR=35]="NETWORK_ERROR",e[e.LIFECYCLE_SCRIPT=36]="LIFECYCLE_SCRIPT",e[e.CONSTRAINTS_MISSING_FIELD=37]="CONSTRAINTS_MISSING_FIELD",e[e.CONSTRAINTS_INCOMPATIBLE_FIELD=38]="CONSTRAINTS_INCOMPATIBLE_FIELD",e[e.CONSTRAINTS_EXTRANEOUS_FIELD=39]="CONSTRAINTS_EXTRANEOUS_FIELD",e[e.CONSTRAINTS_INVALID_FIELD=40]="CONSTRAINTS_INVALID_FIELD",e[e.AUTHENTICATION_INVALID=41]="AUTHENTICATION_INVALID",e[e.PROLOG_UNKNOWN_ERROR=42]="PROLOG_UNKNOWN_ERROR",e[e.PROLOG_SYNTAX_ERROR=43]="PROLOG_SYNTAX_ERROR",e[e.PROLOG_EXISTENCE_ERROR=44]="PROLOG_EXISTENCE_ERROR",e[e.STACK_OVERFLOW_RESOLUTION=45]="STACK_OVERFLOW_RESOLUTION",e[e.AUTOMERGE_FAILED_TO_PARSE=46]="AUTOMERGE_FAILED_TO_PARSE",e[e.AUTOMERGE_IMMUTABLE=47]="AUTOMERGE_IMMUTABLE",e[e.AUTOMERGE_SUCCESS=48]="AUTOMERGE_SUCCESS",e[e.AUTOMERGE_REQUIRED=49]="AUTOMERGE_REQUIRED",e[e.DEPRECATED_CLI_SETTINGS=50]="DEPRECATED_CLI_SETTINGS",e[e.PLUGIN_NAME_NOT_FOUND=51]="PLUGIN_NAME_NOT_FOUND",e[e.INVALID_PLUGIN_REFERENCE=52]="INVALID_PLUGIN_REFERENCE",e[e.CONSTRAINTS_AMBIGUITY=53]="CONSTRAINTS_AMBIGUITY",e[e.CACHE_OUTSIDE_PROJECT=54]="CACHE_OUTSIDE_PROJECT",e[e.IMMUTABLE_INSTALL=55]="IMMUTABLE_INSTALL",e[e.IMMUTABLE_CACHE=56]="IMMUTABLE_CACHE",e[e.INVALID_MANIFEST=57]="INVALID_MANIFEST",e[e.PACKAGE_PREPARATION_FAILED=58]="PACKAGE_PREPARATION_FAILED",e[e.INVALID_RANGE_PEER_DEPENDENCY=59]="INVALID_RANGE_PEER_DEPENDENCY",e[e.INCOMPATIBLE_PEER_DEPENDENCY=60]="INCOMPATIBLE_PEER_DEPENDENCY",e[e.DEPRECATED_PACKAGE=61]="DEPRECATED_PACKAGE",e[e.INCOMPATIBLE_OS=62]="INCOMPATIBLE_OS",e[e.INCOMPATIBLE_CPU=63]="INCOMPATIBLE_CPU",e[e.FROZEN_ARTIFACT_EXCEPTION=64]="FROZEN_ARTIFACT_EXCEPTION",e[e.TELEMETRY_NOTICE=65]="TELEMETRY_NOTICE",e[e.PATCH_HUNK_FAILED=66]="PATCH_HUNK_FAILED",e[e.INVALID_CONFIGURATION_VALUE=67]="INVALID_CONFIGURATION_VALUE",e[e.UNUSED_PACKAGE_EXTENSION=68]="UNUSED_PACKAGE_EXTENSION",e[e.REDUNDANT_PACKAGE_EXTENSION=69]="REDUNDANT_PACKAGE_EXTENSION"}(A||(A={}))},27092:(e,t,r)=>{"use strict";r.d(t,{B:()=>n});var A=r(54143);class n{constructor(e){this.resolvers=e.filter(e=>e)}supportsDescriptor(e,t){return!!this.tryResolverByDescriptor(e,t)}supportsLocator(e,t){return!!this.tryResolverByLocator(e,t)}shouldPersistResolution(e,t){return this.getResolverByLocator(e,t).shouldPersistResolution(e,t)}bindDescriptor(e,t,r){return this.getResolverByDescriptor(e,r).bindDescriptor(e,t,r)}getResolutionDependencies(e,t){return this.getResolverByDescriptor(e,t).getResolutionDependencies(e,t)}async getCandidates(e,t,r){const A=this.getResolverByDescriptor(e,r);return await A.getCandidates(e,t,r)}async getSatisfying(e,t,r){return this.getResolverByDescriptor(e,r).getSatisfying(e,t,r)}async resolve(e,t){const r=this.getResolverByLocator(e,t);return await r.resolve(e,t)}tryResolverByDescriptor(e,t){const r=this.resolvers.find(r=>r.supportsDescriptor(e,t));return r||null}getResolverByDescriptor(e,t){const r=this.resolvers.find(r=>r.supportsDescriptor(e,t));if(!r)throw new Error(A.prettyDescriptor(t.project.configuration,e)+" isn't supported by any available resolver");return r}tryResolverByLocator(e,t){const r=this.resolvers.find(r=>r.supportsLocator(e,t));return r||null}getResolverByLocator(e,t){const r=this.resolvers.find(r=>r.supportsLocator(e,t));if(!r)throw new Error(A.prettyLocator(t.project.configuration,e)+" isn't supported by any available resolver");return r}}},85824:(e,t,r)=>{"use strict";r.d(t,{I:()=>ie});var A=r(43896),n=r(46009),o=r(5944),i=r(11640),s=r(40822),a=r(76417);function c(){}function g(e,t,r,A,n){for(var o=0,i=t.length,s=0,a=0;oe.length?r:e})),c.value=e.join(l)}else c.value=e.join(r.slice(s,s+c.count));s+=c.count,c.added||(a+=c.count)}}var u=t[i-1];return i>1&&"string"==typeof u.value&&(u.added||u.removed)&&e.equals("",u.value)&&(t[i-2].value+=u.value,t.pop()),t}function l(e){return{newPos:e.newPos,components:e.components.slice(0)}}c.prototype={diff:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},A=r.callback;"function"==typeof r&&(A=r,r={}),this.options=r;var n=this;function o(e){return A?(setTimeout((function(){A(void 0,e)}),0),!0):e}e=this.castInput(e),t=this.castInput(t),e=this.removeEmpty(this.tokenize(e));var i=(t=this.removeEmpty(this.tokenize(t))).length,s=e.length,a=1,c=i+s,u=[{newPos:-1,components:[]}],h=this.extractCommon(u[0],t,e,0);if(u[0].newPos+1>=i&&h+1>=s)return o([{value:this.join(t),count:t.length}]);function p(){for(var r=-1*a;r<=a;r+=2){var A=void 0,c=u[r-1],h=u[r+1],p=(h?h.newPos:0)-r;c&&(u[r-1]=void 0);var d=c&&c.newPos+1=i&&p+1>=s)return o(g(n,A.components,t,e,n.useLongestToken));u[r]=A}else u[r]=void 0}a++}if(A)!function e(){setTimeout((function(){if(a>c)return A();p()||e()}),0)}();else for(;a<=c;){var d=p();if(d)return d}},pushComponent:function(e,t,r){var A=e[e.length-1];A&&A.added===t&&A.removed===r?e[e.length-1]={count:A.count+1,added:t,removed:r}:e.push({count:1,added:t,removed:r})},extractCommon:function(e,t,r,A){for(var n=t.length,o=r.length,i=e.newPos,s=i-A,a=0;i+10?a(d.lines.slice(-i.context)):[],g-=u.length,l-=u.length)}(o=u).push.apply(o,E(n.map((function(e){return(t.added?"+":"-")+e})))),t.added?p+=n.length:h+=n.length}else{if(g)if(n.length<=2*i.context&&e=s.length-2&&n.length<=i.context){var y=/\n$/.test(r),m=/\n$/.test(A),w=0==n.length&&u.length>B.oldLines;!y&&w&&u.splice(B.oldLines,0,"\\ No newline at end of file"),(y||w)&&m||u.push("\\ No newline at end of file")}c.push(B),g=0,l=0,u=[]}h+=n.length,p+=n.length}},f=0;f`${r}#commit=${A}`],[/^https:\/\/((?:[^/]+?)@)?codeload\.github\.com\/([^/]+\/[^/]+)\/tar\.gz\/([0-9a-f]+)$/,(e,t,r="",A,n)=>`https://${r}github.com/${A}.git#commit=${n}`],[/^https:\/\/((?:[^/]+?)@)?github\.com\/([^/]+\/[^/]+?)(?:\.git)?#([0-9a-f]+)$/,(e,t,r="",A,n)=>`https://${r}github.com/${A}.git#commit=${n}`],[/^https?:\/\/[^/]+\/(?:[^/]+\/)*(?:@[^/]+\/)?([^/]+)\/(?:-|download)\/\1-[^/]+\.tgz(?:#|$)/,e=>"npm:"+e],[/^https:\/\/npm\.pkg\.github\.com\/download\/(?:@[^/]+)\/(?:[^/]+)\/(?:[^/]+)\/(?:[0-9a-f]+)$/,e=>"npm:"+e],[/^https:\/\/npm\.fontawesome\.com\/(?:@[^/]+)\/([^/]+)\/-\/([^/]+)\/\1-\2.tgz(?:#|$)/,e=>"npm:"+e],[/^[^/]+\.tgz#[0-9a-f]+$/,e=>"npm:"+e]];class T{constructor(){this.resolutions=null}async setup(e,{report:t}){const r=n.y1.join(e.cwd,e.configuration.get("lockfileFilename"));if(!A.xfs.existsSync(r))return;const o=await A.xfs.readFilePromise(r,"utf8"),s=(0,i.parseSyml)(o);if(Object.prototype.hasOwnProperty.call(s,"__metadata"))return;const a=this.resolutions=new Map;for(const r of Object.keys(s)){let A=O.tryParseDescriptor(r);if(!A){t.reportWarning(P.b.YARN_IMPORT_FAILED,`Failed to parse the string "${r}" into a proper descriptor`);continue}k().validRange(A.range)&&(A=O.makeDescriptor(A,"npm:"+A.range));const{version:n,resolved:o}=s[r];if(!o)continue;let i;for(const[e,t]of U){const r=o.match(e);if(r){i=t(n,...r);break}}if(!i){t.reportWarning(P.b.YARN_IMPORT_FAILED,`${O.prettyDescriptor(e.configuration,A)}: Only some patterns can be imported from legacy lockfiles (not "${o}")`);continue}const c=O.makeLocator(A,i);a.set(A.descriptorHash,c)}}supportsDescriptor(e,t){return!!this.resolutions&&this.resolutions.has(e.descriptorHash)}supportsLocator(e,t){return!1}shouldPersistResolution(e,t){throw new Error("Assertion failed: This resolver doesn't support resolving locators to packages")}bindDescriptor(e,t,r){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,r){if(!this.resolutions)throw new Error("Assertion failed: The resolution store should have been setup");const A=this.resolutions.get(e.descriptorHash);if(!A)throw new Error("Assertion failed: The resolution should have been registered");return[A]}async getSatisfying(e,t,r){return null}async resolve(e,t){throw new Error("Assertion failed: This resolver doesn't support resolving locators to packages")}}class j{supportsDescriptor(e,t){return!!t.project.storedResolutions.get(e.descriptorHash)||!!t.project.originalPackages.has(O.convertDescriptorToLocator(e).locatorHash)}supportsLocator(e,t){return!!t.project.originalPackages.has(e.locatorHash)}shouldPersistResolution(e,t){throw new Error("The shouldPersistResolution method shouldn't be called on the lockfile resolver, which would always answer yes")}bindDescriptor(e,t,r){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,r){let A=r.project.originalPackages.get(O.convertDescriptorToLocator(e).locatorHash);if(A)return[A];const n=r.project.storedResolutions.get(e.descriptorHash);if(!n)throw new Error("Expected the resolution to have been successful - resolution not found");if(A=r.project.originalPackages.get(n),!A)throw new Error("Expected the resolution to have been successful - package not found");return[A]}async getSatisfying(e,t,r){return null}async resolve(e,t){const r=t.project.originalPackages.get(e.locatorHash);if(!r)throw new Error("The lockfile resolver isn't meant to resolve packages - they should already have been stored into a cache");return r}}var Y=r(46611),G=r(27092),H=r(35691);class J{constructor(e){this.resolver=e}supportsDescriptor(e,t){return this.resolver.supportsDescriptor(e,t)}supportsLocator(e,t){return this.resolver.supportsLocator(e,t)}shouldPersistResolution(e,t){return this.resolver.shouldPersistResolution(e,t)}bindDescriptor(e,t,r){return this.resolver.bindDescriptor(e,t,r)}getResolutionDependencies(e,t){return this.resolver.getResolutionDependencies(e,t)}async getCandidates(e,t,r){throw new H.lk(P.b.MISSING_LOCKFILE_ENTRY,"This package doesn't seem to be present in your lockfile; try to make an install to update your resolutions")}async getSatisfying(e,t,r){throw new H.lk(P.b.MISSING_LOCKFILE_ENTRY,"This package doesn't seem to be present in your lockfile; try to make an install to update your resolutions")}async resolve(e,t){throw new H.lk(P.b.MISSING_LOCKFILE_ENTRY,"This package doesn't seem to be present in your lockfile; try to make an install to update your resolutions")}}var q=r(33720),z=r(17722),W=r(81111),V=r(71643),X=r(20624),_=r(73632),Z=r(63088),$=r(36545),ee=r(32485);const te=/ *, */g,re=/\/$/,Ae=(0,N.promisify)(R().gzip),ne=(0,N.promisify)(R().gunzip),oe={restoreInstallersCustomData:["installersCustomData"],restoreResolutions:["accessibleLocators","optionalBuilds","storedDescriptors","storedResolutions","storedPackages","lockFileChecksum"]};class ie{constructor(e,{configuration:t}){this.resolutionAliases=new Map,this.workspaces=[],this.workspacesByCwd=new Map,this.workspacesByIdent=new Map,this.storedResolutions=new Map,this.storedDescriptors=new Map,this.storedPackages=new Map,this.storedChecksums=new Map,this.accessibleLocators=new Set,this.originalPackages=new Map,this.optionalBuilds=new Set,this.peerRequirements=new Map,this.installersCustomData=new Map,this.lockFileChecksum=null,this.configuration=t,this.cwd=e}static async find(e,t){var r,o,i;if(!e.projectCwd)throw new s.UsageError("No project found in "+t);let a=e.projectCwd,c=t,g=null;for(;g!==e.projectCwd;){if(g=c,A.xfs.existsSync(n.y1.join(g,n.QS.manifest))){a=g;break}c=n.y1.dirname(g)}const l=new ie(e.projectCwd,{configuration:e});null===(r=x.VK.telemetry)||void 0===r||r.reportProject(l.cwd),await l.setupResolutions(),await l.setupWorkspaces(),null===(o=x.VK.telemetry)||void 0===o||o.reportWorkspaceCount(l.workspaces.length),null===(i=x.VK.telemetry)||void 0===i||i.reportDependencyCount(l.workspaces.reduce((e,t)=>e+t.manifest.dependencies.size+t.manifest.devDependencies.size,0));const u=l.tryWorkspaceByCwd(a);if(u)return{project:l,workspace:u,locator:u.anchoredLocator};const h=await l.findLocatorForLocation(a+"/",{strict:!0});if(h)return{project:l,locator:h,workspace:null};throw new s.UsageError(`The nearest package directory (${V.pretty(e,a,V.Type.PATH)}) doesn't seem to be part of the project declared in ${V.pretty(e,l.cwd,V.Type.PATH)}.\n\n- If the project directory is right, it might be that you forgot to list ${V.pretty(e,n.y1.relative(l.cwd,a),V.Type.PATH)} as a workspace.\n- If it isn't, it's likely because you have a yarn.lock or package.json file there, confusing the project root detection.`)}static generateBuildStateFile(e,t){let r="# Warning: This file is automatically generated. Removing it is fine, but will\n# cause all your builds to become invalidated.\n";const A=[...e].map(([e,r])=>{const A=t.get(e);if(void 0===A)throw new Error("Assertion failed: The locator should have been registered");return[O.stringifyLocator(A),A.locatorHash,r]});for(const[e,t,n]of _.sortMap(A,[e=>e[0],e=>e[1]]))r+="\n",r+=`# ${e}\n`,r+=JSON.stringify(t)+":\n",r+=` ${n}\n`;return r}async setupResolutions(){this.storedResolutions=new Map,this.storedDescriptors=new Map,this.storedPackages=new Map,this.lockFileChecksum=null;const e=n.y1.join(this.cwd,this.configuration.get("lockfileFilename")),t=this.configuration.get("defaultLanguageName");if(A.xfs.existsSync(e)){const r=await A.xfs.readFilePromise(e,"utf8");this.lockFileChecksum=X.makeHash("1",r);const n=(0,i.parseSyml)(r);if(n.__metadata){const e=n.__metadata.version,r=n.__metadata.cacheKey;for(const A of Object.keys(n)){if("__metadata"===A)continue;const o=n[A];if(void 0===o.resolution)throw new Error(`Assertion failed: Expected the lockfile entry to have a resolution field (${A})`);const i=O.parseLocator(o.resolution,!0),s=new Y.G;s.load(o,{yamlCompatibilityMode:!0});const a=s.version,c=s.languageName||t,g=o.linkType.toUpperCase(),l=s.dependencies,u=s.peerDependencies,h=s.dependenciesMeta,p=s.peerDependenciesMeta,d=s.bin;if(null!=o.checksum){const e=void 0===r||o.checksum.includes("/")?o.checksum:`${r}/${o.checksum}`;this.storedChecksums.set(i.locatorHash,e)}if(e>=4){const e={...i,version:a,languageName:c,linkType:g,dependencies:l,peerDependencies:u,dependenciesMeta:h,peerDependenciesMeta:p,bin:d};this.originalPackages.set(e.locatorHash,e)}for(const t of A.split(te)){const r=O.parseDescriptor(t);if(this.storedDescriptors.set(r.descriptorHash,r),e>=4)this.storedResolutions.set(r.descriptorHash,i.locatorHash);else{const e=O.convertLocatorToDescriptor(i);e.descriptorHash!==r.descriptorHash&&(this.storedDescriptors.set(e.descriptorHash,e),this.resolutionAliases.set(r.descriptorHash,e.descriptorHash))}}}}}}async setupWorkspaces(){this.workspaces=[],this.workspacesByCwd=new Map,this.workspacesByIdent=new Map;let e=[this.cwd];for(;e.length>0;){const t=e;e=[];for(const r of t){if(this.workspacesByCwd.has(r))continue;const t=await this.addWorkspace(r),A=this.storedPackages.get(t.anchoredLocator.locatorHash);A&&(t.dependencies=A.dependencies);for(const r of t.workspacesCwds)e.push(r)}}}async addWorkspace(e){const t=new z.j(e,{project:this});await t.setup();const r=this.workspacesByIdent.get(t.locator.identHash);if(void 0!==r)throw new Error(`Duplicate workspace name ${O.prettyIdent(this.configuration,t.locator)}: ${e} conflicts with ${r.cwd}`);return this.workspaces.push(t),this.workspacesByCwd.set(e,t),this.workspacesByIdent.set(t.locator.identHash,t),t}get topLevelWorkspace(){return this.getWorkspaceByCwd(this.cwd)}tryWorkspaceByCwd(e){n.y1.isAbsolute(e)||(e=n.y1.resolve(this.cwd,e)),e=n.y1.normalize(e).replace(/\/+$/,"");const t=this.workspacesByCwd.get(e);return t||null}getWorkspaceByCwd(e){const t=this.tryWorkspaceByCwd(e);if(!t)throw new Error(`Workspace not found (${e})`);return t}tryWorkspaceByFilePath(e){let t=null;for(const r of this.workspaces){n.y1.relative(r.cwd,e).startsWith("../")||(t&&t.cwd.length>=r.cwd.length||(t=r))}return t||null}getWorkspaceByFilePath(e){const t=this.tryWorkspaceByFilePath(e);if(!t)throw new Error(`Workspace not found (${e})`);return t}tryWorkspaceByIdent(e){const t=this.workspacesByIdent.get(e.identHash);return void 0===t?null:t}getWorkspaceByIdent(e){const t=this.tryWorkspaceByIdent(e);if(!t)throw new Error(`Workspace not found (${O.prettyIdent(this.configuration,e)})`);return t}tryWorkspaceByDescriptor(e){const t=this.tryWorkspaceByIdent(e);return null!==t&&t.accepts(e.range)?t:null}getWorkspaceByDescriptor(e){const t=this.tryWorkspaceByDescriptor(e);if(null===t)throw new Error(`Workspace not found (${O.prettyDescriptor(this.configuration,e)})`);return t}tryWorkspaceByLocator(e){O.isVirtualLocator(e)&&(e=O.devirtualizeLocator(e));const t=this.tryWorkspaceByIdent(e);return null===t||t.locator.locatorHash!==e.locatorHash&&t.anchoredLocator.locatorHash!==e.locatorHash?null:t}getWorkspaceByLocator(e){const t=this.tryWorkspaceByLocator(e);if(!t)throw new Error(`Workspace not found (${O.prettyLocator(this.configuration,e)})`);return t}refreshWorkspaceDependencies(){for(const e of this.workspaces){const t=this.storedPackages.get(e.anchoredLocator.locatorHash);if(!t)throw new Error("Assertion failed: Expected workspace to have been resolved");e.dependencies=new Map(t.dependencies)}}forgetResolution(e){const t=e=>{this.storedResolutions.delete(e),this.storedDescriptors.delete(e)},r=e=>{this.originalPackages.delete(e),this.storedPackages.delete(e),this.accessibleLocators.delete(e)};if("descriptorHash"in e){const A=this.storedResolutions.get(e.descriptorHash);t(e.descriptorHash);const n=new Set(this.storedResolutions.values());void 0===A||n.has(A)||r(A)}if("locatorHash"in e){r(e.locatorHash);for(const[r,A]of this.storedResolutions)A===e.locatorHash&&t(r)}}forgetTransientResolutions(){const e=this.configuration.makeResolver();for(const t of this.originalPackages.values()){let r;try{r=e.shouldPersistResolution(t,{project:this,resolver:e})}catch(e){r=!1}r||this.forgetResolution(t)}}forgetVirtualResolutions(){for(const e of this.storedPackages.values())for(const[t,r]of e.dependencies)O.isVirtualDescriptor(r)&&e.dependencies.set(t,O.devirtualizeDescriptor(r))}getDependencyMeta(e,t){const r={},A=this.topLevelWorkspace.manifest.dependenciesMeta.get(O.stringifyIdent(e));if(!A)return r;const n=A.get(null);if(n&&Object.assign(r,n),null===t||!k().valid(t))return r;for(const[e,n]of A)null!==e&&e===t&&Object.assign(r,n);return r}async findLocatorForLocation(e,{strict:t=!1}={}){const r=new q.$,A=this.configuration.getLinkers(),n={project:this,report:r};for(const r of A){const A=await r.findPackageLocator(e,n);if(A){if(t){if((await r.findPackageLocation(A,n)).replace(re,"")!==e.replace(re,""))continue}return A}}return null}async resolveEverything(e){if(!this.workspacesByCwd||!this.workspacesByIdent)throw new Error("Workspaces must have been setup before calling this function");this.forgetVirtualResolutions(),e.lockfileOnly||this.forgetTransientResolutions();const t=e.resolver||this.configuration.makeResolver(),r=new T;await r.setup(this,{report:e.report});const o=e.lockfileOnly?new G.B([new j,new J(t)]):new G.B([new j,r,t]),i=this.configuration.makeFetcher(),s=e.lockfileOnly?{project:this,report:e.report,resolver:o}:{project:this,report:e.report,resolver:o,fetchOptions:{project:this,cache:e.cache,checksums:this.storedChecksums,report:e.report,fetcher:i}},a=new Map,c=new Map,g=new Map,l=new Map,u=new Map,h=new Map,p=[],d=async e=>{const t=await _.prettifyAsyncErrors(async()=>await o.resolve(e,s),t=>`${O.prettyLocator(this.configuration,e)}: ${t}`);if(!O.areLocatorsEqual(e,t))throw new Error(`Assertion failed: The locator cannot be changed by the resolver (went from ${O.prettyLocator(this.configuration,e)} to ${O.prettyLocator(this.configuration,t)})`);l.set(t.locatorHash,t);const r=this.configuration.normalizePackage(t);for(const[t,A]of r.dependencies){const n=await this.configuration.reduceHook(e=>e.reduceDependency,A,this,r,A,{resolver:o,resolveOptions:s});if(!O.areIdentsEqual(A,n))throw new Error("Assertion failed: The descriptor ident cannot be changed through aliases");const i=o.bindDescriptor(n,e,s);r.dependencies.set(t,i)}return p.push(Promise.all([...r.dependencies.values()].map(e=>f(e)))),c.set(r.locatorHash,r),r},C=async e=>{const t=this.resolutionAliases.get(e.descriptorHash);if(void 0!==t)return(async(e,t)=>{const r=await f(t);return a.set(e.descriptorHash,e),g.set(e.descriptorHash,r.locatorHash),r})(e,this.storedDescriptors.get(t));const r=o.getResolutionDependencies(e,s),A=new Map(await Promise.all(r.map(async e=>[e.descriptorHash,await f(e)]))),n=(await _.prettifyAsyncErrors(async()=>await o.getCandidates(e,A,s),t=>`${O.prettyDescriptor(this.configuration,e)}: ${t}`))[0];if(void 0===n)throw new Error(O.prettyDescriptor(this.configuration,e)+": No candidates found");return a.set(e.descriptorHash,e),g.set(e.descriptorHash,n.locatorHash),(async e=>{const t=u.get(e.locatorHash);if(void 0!==t)return t;const r=Promise.resolve().then(()=>d(e));return u.set(e.locatorHash,r),r})(n)},f=e=>{const t=h.get(e.descriptorHash);if(void 0!==t)return t;a.set(e.descriptorHash,e);const r=Promise.resolve().then(()=>C(e));return h.set(e.descriptorHash,r),r};for(const e of this.workspaces){const t=e.anchoredDescriptor;p.push(f(t))}for(;p.length>0;){const e=[...p];p.length=0,await Promise.all(e)}const I=new Set(this.resolutionAliases.values()),E=new Set(c.keys()),B=new Set,y=new Map;!function({project:e,allDescriptors:t,allResolutions:r,allPackages:o,accessibleLocators:i=new Set,optionalBuilds:s=new Set,volatileDescriptors:a=new Set,peerRequirements:c=new Map,report:g,tolerateMissingPackages:l=!1}){var u;const h=new Map,p=[],d=new Map,C=new Map,f=new Map,I=new Map,E=new Map,B=new Map(e.workspaces.map(e=>{const t=e.anchoredLocator.locatorHash,r=o.get(t);if(void 0===r){if(l)return[t,null];throw new Error("Assertion failed: The workspace should have an associated package")}return[t,O.copyPackage(r)]})),y=()=>{const e=A.xfs.mktempSync(),t=n.y1.join(e,"stacktrace.log"),r=String(p.length+1).length,o=p.map((e,t)=>`${(t+1+".").padStart(r," ")} ${O.stringifyLocator(e)}\n`).join("");throw A.xfs.writeFileSync(t,o),new H.lk(P.b.STACK_OVERFLOW_RESOLUTION,"Encountered a stack overflow when resolving peer dependencies; cf "+t)},m=e=>{const t=r.get(e.descriptorHash);if(void 0===t)throw new Error("Assertion failed: The resolution should have been registered");const A=o.get(t);if(!A)throw new Error("Assertion failed: The package could not be found");return A},w=(e,t,{first:r,optional:A})=>{p.length>1e3&&y(),p.push(e);const n=Q(e,t,{first:r,optional:A});return p.pop(),n},Q=(A,n,{first:c,optional:g})=>{if(i.has(A.locatorHash))return;i.add(A.locatorHash),g||s.delete(A.locatorHash);const u=o.get(A.locatorHash);if(!u){if(l)return;throw new Error(`Assertion failed: The package (${O.prettyLocator(e.configuration,A)}) should have been registered`)}const p=[],m=[],Q=[],D=[],b=[];for(const i of Array.from(u.dependencies.values())){if(u.peerDependencies.has(i.identHash)&&!c)continue;if(O.isVirtualDescriptor(i))throw new Error("Assertion failed: Virtual packages shouldn't be encountered when virtualizing a branch");a.delete(i.descriptorHash);let s=g;if(!s){const e=u.dependenciesMeta.get(O.stringifyIdent(i));if(void 0!==e){const t=e.get(null);void 0!==t&&t.optional&&(s=!0)}}const C=r.get(i.descriptorHash);if(!C){if(l)continue;throw new Error(`Assertion failed: The resolution (${O.prettyDescriptor(e.configuration,i)}) should have been registered`)}const v=B.get(C)||o.get(C);if(!v)throw new Error(`Assertion failed: The package (${C}, resolved from ${O.prettyDescriptor(e.configuration,i)}) should have been registered`);if(0===v.peerDependencies.size){w(v,new Map,{first:!1,optional:s});continue}const S=h.get(v.locatorHash);let k,N;"number"==typeof S&&S>=2&&y();const F=new Set;let K;m.push(()=>{k=O.virtualizeDescriptor(i,A.locatorHash),N=O.virtualizePackage(v,A.locatorHash),u.dependencies.delete(i.identHash),u.dependencies.set(k.identHash,k),r.set(k.descriptorHash,N.locatorHash),t.set(k.descriptorHash,k),o.set(N.locatorHash,N),p.push([v,k,N])}),Q.push(()=>{var e;K=new Map;for(const o of N.peerDependencies.values()){let i=u.dependencies.get(o.identHash);if(!i&&O.areIdentsEqual(A,o)&&(i=O.convertLocatorToDescriptor(A),t.set(i.descriptorHash,i),r.set(i.descriptorHash,A.locatorHash),a.delete(i.descriptorHash)),i||!N.dependencies.has(o.identHash)){if(i||(i=O.makeDescriptor(o,"missing:")),N.dependencies.set(i.identHash,i),O.isVirtualDescriptor(i)){_.getSetWithDefault(f,i.descriptorHash).add(N.locatorHash)}d.set(i.identHash,i),"missing:"===i.range&&F.add(i.identHash),K.set(o.identHash,null!==(e=n.get(o.identHash))&&void 0!==e?e:N.locatorHash)}else N.peerDependencies.delete(o.identHash)}N.dependencies=new Map(_.sortMap(N.dependencies,([e,t])=>O.stringifyIdent(t)))}),D.push(()=>{if(!o.has(N.locatorHash))return;const e=h.get(v.locatorHash),t=void 0!==e?e+1:1;h.set(v.locatorHash,t),w(N,K,{first:!1,optional:s}),h.set(v.locatorHash,t-1)}),b.push(()=>{const e=u.dependencies.get(i.identHash);if(void 0===e)throw new Error("Assertion failed: Expected the peer dependency to have been turned into a dependency");const t=r.get(e.descriptorHash);if(void 0===t)throw new Error("Assertion failed: Expected the descriptor to be registered");if(_.getSetWithDefault(E,t).add(A.locatorHash),o.has(N.locatorHash)){for(const e of N.peerDependencies.values()){const t=K.get(e.identHash);if(void 0===t)throw new Error("Assertion failed: Expected the peer dependency ident to be registered");_.getArrayWithDefault(_.getMapWithDefault(I,t),O.stringifyIdent(e)).push(N.locatorHash)}for(const e of F)N.dependencies.delete(e)}})}for(const e of[...m,...Q])e();let v;do{v=!0;for(const[A,n,s]of p){if(!o.has(s.locatorHash))continue;const a=_.getMapWithDefault(C,A.locatorHash),c=X.makeHash(...[...s.dependencies.values()].map(t=>{const A="missing:"!==t.range?r.get(t.descriptorHash):"missing:";if(void 0===A)throw new Error(`Assertion failed: Expected the resolution for ${O.prettyDescriptor(e.configuration,t)} to have been registered`);return A}),n.identHash),g=a.get(c);if(void 0===g){a.set(c,n);continue}if(g===n)continue;v=!1,o.delete(s.locatorHash),t.delete(n.descriptorHash),r.delete(n.descriptorHash),i.delete(s.locatorHash);const l=f.get(n.descriptorHash)||[],h=[u.locatorHash,...l];f.delete(n.descriptorHash);for(const e of h){const t=o.get(e);void 0!==t&&t.dependencies.set(n.identHash,g)}}}while(!v);for(const e of[...D,...b])e()};for(const t of e.workspaces)a.delete(t.anchoredDescriptor.descriptorHash),w(t.anchoredLocator,new Map,{first:!0,optional:!1});let D;!function(e){e[e.NotProvided=0]="NotProvided",e[e.NotCompatible=1]="NotCompatible"}(D||(D={}));const b=[];for(const[e,t]of E){const r=o.get(e);if(void 0===r)throw new Error("Assertion failed: Expected the root to be registered");const A=I.get(e);if(void 0!==A)for(const n of t){const t=o.get(n);if(void 0!==t)for(const[i,s]of A){const A=O.parseIdent(i);if(t.peerDependencies.has(A.identHash))continue;const a="p"+X.makeHash(n,i,e).slice(0,5);c.set(a,{subject:n,requested:A,rootRequester:e,allRequesters:s});const g=r.dependencies.get(A.identHash);if(void 0!==g){const e=m(g),n=null!==(u=e.version)&&void 0!==u?u:"0.0.0",i=new Set;for(const e of s){const t=o.get(e);if(void 0===t)throw new Error("Assertion failed: Expected the link to be registered");const r=t.peerDependencies.get(A.identHash);if(void 0===r)throw new Error("Assertion failed: Expected the ident to be registered");i.add(r.range)}[...i].every(e=>$.satisfiesWithPrereleases(n,e))||b.push({type:D.NotCompatible,subject:t,requested:A,requester:r,version:n,hash:a,requirementCount:s.length})}else{const e=r.peerDependenciesMeta.get(i);(null==e?void 0:e.optional)||b.push({type:D.NotProvided,subject:t,requested:A,requester:r,hash:a})}}}}const v=[e=>O.prettyLocatorNoColors(e.subject),e=>O.stringifyIdent(e.requested),e=>""+e.type];for(const t of _.sortMap(b,v))switch(t.type){case D.NotProvided:null==g||g.reportWarning(P.b.MISSING_PEER_DEPENDENCY,`${O.prettyLocator(e.configuration,t.subject)} doesn't provide ${O.prettyIdent(e.configuration,t.requested)} (${V.pretty(e.configuration,t.hash,V.Type.CODE)}), requested by ${O.prettyIdent(e.configuration,t.requester)}`);break;case D.NotCompatible:{const r=t.requirementCount>1?"and some of its descendants request":"requests";null==g||g.reportWarning(P.b.INCOMPATIBLE_PEER_DEPENDENCY,`${O.prettyLocator(e.configuration,t.subject)} provides ${O.prettyIdent(e.configuration,t.requested)} (${V.pretty(e.configuration,t.hash,V.Type.CODE)}) with version ${O.prettyReference(e.configuration,t.version)}, which doesn't satisfy what ${O.prettyIdent(e.configuration,t.requester)} ${r}`)}}b.length>0&&(null==g||g.reportWarning(P.b.UNNAMED,`Some peer dependencies are incorrectly met; run ${V.pretty(e.configuration,"yarn explain peer-requirements ",V.Type.CODE)} for details, where ${V.pretty(e.configuration,"",V.Type.CODE)} is the six-letter p-prefixed code`))}({project:this,report:e.report,accessibleLocators:B,volatileDescriptors:I,optionalBuilds:E,peerRequirements:y,allDescriptors:a,allResolutions:g,allPackages:c});for(const e of I)a.delete(e),g.delete(e);this.storedResolutions=g,this.storedDescriptors=a,this.storedPackages=c,this.accessibleLocators=B,this.originalPackages=l,this.optionalBuilds=E,this.peerRequirements=y,this.refreshWorkspaceDependencies()}async fetchEverything({cache:e,report:t,fetcher:r}){const A=r||this.configuration.makeFetcher(),n={checksums:this.storedChecksums,project:this,cache:e,fetcher:A,report:t},o=Array.from(new Set(_.sortMap(this.storedResolutions.values(),[e=>{const t=this.storedPackages.get(e);if(!t)throw new Error("Assertion failed: The locator should have been registered");return O.stringifyLocator(t)}])));let i=!1;const s=H.yG.progressViaCounter(o.length);t.reportProgress(s);const a=v()(32);if(await t.startCacheReport(async()=>{await Promise.all(o.map(e=>a(async()=>{const r=this.storedPackages.get(e);if(!r)throw new Error("Assertion failed: The locator should have been registered");if(O.isVirtualLocator(r))return;let o;try{o=await A.fetch(r,n)}catch(e){return e.message=`${O.prettyLocator(this.configuration,r)}: ${e.message}`,t.reportExceptionOnce(e),void(i=e)}o.checksum?this.storedChecksums.set(r.locatorHash,o.checksum):this.storedChecksums.delete(r.locatorHash),o.releaseFs&&o.releaseFs()}).finally(()=>{s.tick()})))}),i)throw i}async linkEverything({cache:e,report:t,fetcher:r,skipBuild:o}){var s;const c=r||this.configuration.makeFetcher(),g={checksums:this.storedChecksums,project:this,cache:e,fetcher:c,report:t,skipIntegrityCheck:!0},l=this.configuration.getLinkers(),u={project:this,report:t},h=new Map(l.map(e=>{const t=e.makeInstaller(u),r=t.getCustomDataKey(),A=this.installersCustomData.get(r);return void 0!==A&&t.attachCustomData(A),[e,t]})),p=new Map,d=new Map,C=new Map,f=new Map(await Promise.all([...this.accessibleLocators].map(async e=>{const t=this.storedPackages.get(e);if(!t)throw new Error("Assertion failed: The locator should have been registered");return[e,await c.fetch(t,g)]})));for(const e of this.accessibleLocators){const t=this.storedPackages.get(e);if(void 0===t)throw new Error("Assertion failed: The locator should have been registered");const r=f.get(t.locatorHash);if(void 0===r)throw new Error("Assertion failed: The fetch result should have been registered");const A=this.tryWorkspaceByLocator(t);if(null!==A){const e=[],{scripts:o}=A.manifest;for(const t of["preinstall","install","postinstall"])o.has(t)&&e.push([L.k.SCRIPT,t]);try{for(const e of h.values()){if(null!==(await e.installPackage(t,r)).buildDirective)throw new Error("Assertion failed: Linkers can't return build directives for workspaces; this responsibility befalls to the Yarn core")}}finally{r.releaseFs&&r.releaseFs()}const i=n.y1.join(r.packageFs.getRealPath(),r.prefixPath);d.set(t.locatorHash,i),e.length>0&&C.set(t.locatorHash,{directives:e,buildLocations:[i]})}else{const e=l.find(e=>e.supportsPackage(t,u));if(!e)throw new H.lk(P.b.LINKER_NOT_FOUND,O.prettyLocator(this.configuration,t)+" isn't supported by any available linker");const A=h.get(e);if(!A)throw new Error("Assertion failed: The installer should have been registered");let n;try{n=await A.installPackage(t,r)}finally{r.releaseFs&&r.releaseFs()}p.set(t.locatorHash,e),d.set(t.locatorHash,n.packageLocation),n.buildDirective&&n.packageLocation&&C.set(t.locatorHash,{directives:n.buildDirective,buildLocations:[n.packageLocation]})}}const I=new Map;for(const e of this.accessibleLocators){const t=this.storedPackages.get(e);if(!t)throw new Error("Assertion failed: The locator should have been registered");const r=null!==this.tryWorkspaceByLocator(t),A=async(e,A)=>{const n=d.get(t.locatorHash);if(void 0===n)throw new Error(`Assertion failed: The package (${O.prettyLocator(this.configuration,t)}) should have been registered`);const o=[];for(const A of t.dependencies.values()){const i=this.storedResolutions.get(A.descriptorHash);if(void 0===i)throw new Error(`Assertion failed: The resolution (${O.prettyDescriptor(this.configuration,A)}, from ${O.prettyLocator(this.configuration,t)})should have been registered`);const s=this.storedPackages.get(i);if(void 0===s)throw new Error(`Assertion failed: The package (${i}, resolved from ${O.prettyDescriptor(this.configuration,A)}) should have been registered`);const a=null===this.tryWorkspaceByLocator(s)?p.get(i):null;if(void 0===a)throw new Error(`Assertion failed: The package (${i}, resolved from ${O.prettyDescriptor(this.configuration,A)}) should have been registered`);const c=null===a;if(a===e||r||c)null!==d.get(s.locatorHash)&&o.push([A,s]);else if(null!==n){_.getArrayWithDefault(I,i).push(n)}}null!==n&&await A.attachInternalDependencies(t,o)};if(r)for(const[e,t]of h)await A(e,t);else{const e=p.get(t.locatorHash);if(!e)throw new Error("Assertion failed: The linker should have been found");const r=h.get(e);if(!r)throw new Error("Assertion failed: The installer should have been registered");await A(e,r)}}for(const[e,t]of I){const r=this.storedPackages.get(e);if(!r)throw new Error("Assertion failed: The package should have been registered");const A=p.get(r.locatorHash);if(!A)throw new Error("Assertion failed: The linker should have been found");const n=h.get(A);if(!n)throw new Error("Assertion failed: The installer should have been registered");await n.attachExternalDependents(r,t)}const E=new Map;for(const e of h.values()){const t=await e.finalizeInstall();for(const e of null!==(s=null==t?void 0:t.records)&&void 0!==s?s:[])C.set(e.locatorHash,{directives:e.buildDirective,buildLocations:e.buildLocations});void 0!==(null==t?void 0:t.customData)&&E.set(e.getCustomDataKey(),t.customData)}if(this.installersCustomData=E,await this.persistInstallStateFile(),o)return;const B=new Set(this.storedPackages.keys()),y=new Set(C.keys());for(const e of y)B.delete(e);const m=(0,a.createHash)("sha512");m.update(process.versions.node),this.configuration.triggerHook(e=>e.globalHashGeneration,this,e=>{m.update("\0"),m.update(e)});const w=m.digest("hex"),Q=new Map,D=e=>{let t=Q.get(e.locatorHash);if(void 0!==t)return t;const r=this.storedPackages.get(e.locatorHash);if(void 0===r)throw new Error("Assertion failed: The package should have been registered");const A=(0,a.createHash)("sha512");A.update(e.locatorHash),Q.set(e.locatorHash,"");for(const e of r.dependencies.values()){const t=this.storedResolutions.get(e.descriptorHash);if(void 0===t)throw new Error(`Assertion failed: The resolution (${O.prettyDescriptor(this.configuration,e)}) should have been registered`);const r=this.storedPackages.get(t);if(void 0===r)throw new Error("Assertion failed: The package should have been registered");A.update(D(r))}return t=A.digest("hex"),Q.set(e.locatorHash,t),t},b=(e,t)=>{const r=(0,a.createHash)("sha512");r.update(w),r.update(D(e));for(const e of t)r.update(e);return r.digest("hex")},v=this.configuration.get("bstatePath"),S=A.xfs.existsSync(v)?(0,i.parseSyml)(await A.xfs.readFilePromise(v,"utf8")):{},k=new Map;for(;y.size>0;){const e=y.size,r=[];for(const e of y){const o=this.storedPackages.get(e);if(!o)throw new Error("Assertion failed: The package should have been registered");let i=!0;for(const e of o.dependencies.values()){const t=this.storedResolutions.get(e.descriptorHash);if(!t)throw new Error(`Assertion failed: The resolution (${O.prettyDescriptor(this.configuration,e)}) should have been registered`);if(y.has(t)){i=!1;break}}if(!i)continue;y.delete(e);const s=C.get(o.locatorHash);if(!s)throw new Error("Assertion failed: The build directive should have been registered");const a=b(o,s.buildLocations);if(Object.prototype.hasOwnProperty.call(S,o.locatorHash)&&S[o.locatorHash]===a)k.set(o.locatorHash,a);else{Object.prototype.hasOwnProperty.call(S,o.locatorHash)?t.reportInfo(P.b.MUST_REBUILD,O.prettyLocator(this.configuration,o)+" must be rebuilt because its dependency tree changed"):t.reportInfo(P.b.MUST_BUILD,O.prettyLocator(this.configuration,o)+" must be built because it never did before or the last one failed");for(const e of s.buildLocations){if(!n.y1.isAbsolute(e))throw new Error(`Assertion failed: Expected the build location to be absolute (not ${e})`);r.push((async()=>{for(const[r,i]of s.directives){let s=`# This file contains the result of Yarn building a package (${O.stringifyLocator(o)})\n`;switch(r){case L.k.SCRIPT:s+=`# Script name: ${i}\n`;break;case L.k.SHELLCODE:s+=`# Script code: ${i}\n`}const c=null;await A.xfs.mktempPromise(async g=>{const l=n.y1.join(g,"build.log"),{stdout:u,stderr:h}=this.configuration.getSubprocessStreams(l,{header:s,prefix:O.prettyLocator(this.configuration,o),report:t});let p;try{switch(r){case L.k.SCRIPT:p=await Z.executePackageScript(o,i,[],{cwd:e,project:this,stdin:c,stdout:u,stderr:h});break;case L.k.SHELLCODE:p=await Z.executePackageShellcode(o,i,[],{cwd:e,project:this,stdin:c,stdout:u,stderr:h})}}catch(e){h.write(e.stack),p=1}if(u.end(),h.end(),0===p)return k.set(o.locatorHash,a),!0;A.xfs.detachTemp(g);const d=`${O.prettyLocator(this.configuration,o)} couldn't be built successfully (exit code ${V.pretty(this.configuration,p,V.Type.NUMBER)}, logs can be found here: ${V.pretty(this.configuration,l,V.Type.PATH)})`;return t.reportInfo(P.b.BUILD_FAILED,d),this.optionalBuilds.has(o.locatorHash)?(k.set(o.locatorHash,a),!0):(t.reportError(P.b.BUILD_FAILED,d),!1)})}})())}}}if(await Promise.all(r),e===y.size){const e=Array.from(y).map(e=>{const t=this.storedPackages.get(e);if(!t)throw new Error("Assertion failed: The package should have been registered");return O.prettyLocator(this.configuration,t)}).join(", ");t.reportError(P.b.CYCLIC_DEPENDENCIES,`Some packages have circular dependencies that make their build order unsatisfiable - as a result they won't be built (affected packages are: ${e})`);break}}if(k.size>0){const e=this.configuration.get("bstatePath"),t=ie.generateBuildStateFile(k,this.storedPackages);await A.xfs.mkdirPromise(n.y1.dirname(e),{recursive:!0}),await A.xfs.changeFilePromise(e,t,{automaticNewlines:!0})}else await A.xfs.removePromise(v)}async install(e){var t,r;const i=this.configuration.get("nodeLinker");null===(t=x.VK.telemetry)||void 0===t||t.reportInstall(i),await e.report.startTimerPromise("Project validation",{skipIfEmpty:!0},async()=>{await this.configuration.triggerHook(e=>e.validateProject,this,{reportWarning:e.report.reportWarning.bind(e.report),reportError:e.report.reportError.bind(e.report)})});for(const e of this.configuration.packageExtensions.values())for(const[,t]of e)for(const e of t)e.status=ee._u.Inactive;const s=n.y1.join(this.cwd,this.configuration.get("lockfileFilename"));let a=null;if(e.immutable)try{a=await A.xfs.readFilePromise(s,"utf8")}catch(e){throw"ENOENT"===e.code?new H.lk(P.b.FROZEN_LOCKFILE_EXCEPTION,"The lockfile would have been created by this install, which is explicitly forbidden."):e}await e.report.startTimerPromise("Resolution step",async()=>{await this.resolveEverything(e)}),await e.report.startTimerPromise("Post-resolution validation",{skipIfEmpty:!0},async()=>{for(const[,t]of this.configuration.packageExtensions)for(const[,r]of t)for(const t of r)if(t.userProvided){const r=V.pretty(this.configuration,t,V.Type.PACKAGE_EXTENSION);switch(t.status){case ee._u.Inactive:e.report.reportWarning(P.b.UNUSED_PACKAGE_EXTENSION,r+": No matching package in the dependency tree; you may not need this rule anymore.");break;case ee._u.Redundant:e.report.reportWarning(P.b.REDUNDANT_PACKAGE_EXTENSION,r+": This rule seems redundant when applied on the original package; the extension may have been applied upstream.")}}if(null!==a){const t=(0,o.qH)(a,this.generateLockfile());if(t!==a){const r=w(s,s,a,t);e.report.reportSeparator();for(const t of r.hunks){e.report.reportInfo(null,`@@ -${t.oldStart},${t.oldLines} +${t.newStart},${t.newLines} @@`);for(const r of t.lines)r.startsWith("+")?e.report.reportError(P.b.FROZEN_LOCKFILE_EXCEPTION,V.pretty(this.configuration,r,V.Type.ADDED)):r.startsWith("-")?e.report.reportError(P.b.FROZEN_LOCKFILE_EXCEPTION,V.pretty(this.configuration,r,V.Type.REMOVED)):e.report.reportInfo(null,V.pretty(this.configuration,r,"grey"))}throw e.report.reportSeparator(),new H.lk(P.b.FROZEN_LOCKFILE_EXCEPTION,"The lockfile would have been modified by this install, which is explicitly forbidden.")}}});for(const e of this.configuration.packageExtensions.values())for(const[,t]of e)for(const e of t)e.userProvided&&e.status===ee._u.Active&&(null===(r=x.VK.telemetry)||void 0===r||r.reportPackageExtension(V.json(e,V.Type.PACKAGE_EXTENSION)));await e.report.startTimerPromise("Fetch step",async()=>{await this.fetchEverything(e),(void 0===e.persistProject||e.persistProject)&&await this.cacheCleanup(e)}),(void 0===e.persistProject||e.persistProject)&&await this.persist(),await e.report.startTimerPromise("Link step",async()=>{const t=e.immutable?[...new Set(this.configuration.get("immutablePatterns"))].sort():[],r=await Promise.all(t.map(async e=>X.checksumPattern(e,{cwd:this.cwd})));await this.linkEverything(e);const A=await Promise.all(t.map(async e=>X.checksumPattern(e,{cwd:this.cwd})));for(let n=0;ne.afterAllInstalled,this,e)}generateLockfile(){const e=new Map;for(const[t,r]of this.storedResolutions.entries()){let A=e.get(r);A||e.set(r,A=new Set),A.add(t)}const t={__metadata:{version:4}};for(const[r,A]of e.entries()){const e=this.originalPackages.get(r);if(!e)continue;const n=[];for(const e of A){const t=this.storedDescriptors.get(e);if(!t)throw new Error("Assertion failed: The descriptor should have been registered");n.push(t)}const o=n.map(e=>O.stringifyDescriptor(e)).sort().join(", "),i=new Y.G;let s;i.version=e.linkType===ee.Un.HARD?e.version:"0.0.0-use.local",i.languageName=e.languageName,i.dependencies=new Map(e.dependencies),i.peerDependencies=new Map(e.peerDependencies),i.dependenciesMeta=new Map(e.dependenciesMeta),i.peerDependenciesMeta=new Map(e.peerDependenciesMeta),i.bin=new Map(e.bin);const a=this.storedChecksums.get(e.locatorHash);if(void 0!==a){const e=a.indexOf("/");if(-1===e)throw new Error("Assertion failed: Expecte the checksum to reference its cache key");const r=a.slice(0,e),A=a.slice(e+1);void 0===t.__metadata.cacheKey&&(t.__metadata.cacheKey=r),s=r===t.__metadata.cacheKey?A:a}t[o]={...i.exportTo({},{compatibilityMode:!1}),linkType:e.linkType.toLowerCase(),resolution:O.stringifyLocator(e),checksum:s}}return['# This file is generated by running "yarn install" inside your project.\n',"# Manual changes might be lost - proceed with caution!\n"].join("")+"\n"+(0,i.stringifySyml)(t)}async persistLockfile(){const e=n.y1.join(this.cwd,this.configuration.get("lockfileFilename")),t=this.generateLockfile();await A.xfs.changeFilePromise(e,t,{automaticNewlines:!0})}async persistInstallStateFile(){const e=[];for(const t of Object.values(oe))e.push(...t);const t=D()(this,e),r=await Ae(K().serialize(t)),o=this.configuration.get("installStatePath");await A.xfs.mkdirPromise(n.y1.dirname(o),{recursive:!0}),await A.xfs.changeFilePromise(o,r)}async restoreInstallState({restoreInstallersCustomData:e=!0,restoreResolutions:t=!0}={}){const r=this.configuration.get("installStatePath");if(!A.xfs.existsSync(r))return void(t&&await this.applyLightResolution());const n=await A.xfs.readFilePromise(r),o=K().deserialize(await ne(n));e&&void 0!==o.installersCustomData&&(this.installersCustomData=o.installersCustomData),t&&(o.lockFileChecksum===this.lockFileChecksum?(Object.assign(this,D()(o,oe.restoreResolutions)),this.refreshWorkspaceDependencies()):await this.applyLightResolution())}async applyLightResolution(){await this.resolveEverything({lockfileOnly:!0,report:new q.$}),await this.persistInstallStateFile()}async persist(){await this.persistLockfile();for(const e of this.workspacesByCwd.values())await e.persistManifest()}async cacheCleanup({cache:e,report:t}){const r=new Set([".gitignore"]);if(A.xfs.existsSync(e.cwd)&&(0,W.isFolderInside)(e.cwd,this.cwd)){for(const o of await A.xfs.readdirPromise(e.cwd)){if(r.has(o))continue;const i=n.y1.resolve(e.cwd,o);e.markedFiles.has(i)||(e.immutable?t.reportError(P.b.IMMUTABLE_CACHE,V.pretty(this.configuration,n.y1.basename(i),"magenta")+" appears to be unused and would marked for deletion, but the cache is immutable"):(t.reportInfo(P.b.UNUSED_CACHE_ENTRY,V.pretty(this.configuration,n.y1.basename(i),"magenta")+" appears to be unused - removing"),await A.xfs.removePromise(i)))}e.markedFiles.clear()}}}},52779:(e,t,r)=>{"use strict";r.d(t,{c:()=>s,O:()=>a});var A=r(53887),n=r.n(A),o=r(36545),i=r(54143);const s=/^(?!v)[a-z0-9-.]+$/i;class a{supportsDescriptor(e,t){return!!o.validRange(e.range)||!!s.test(e.range)}supportsLocator(e,t){return!!n().valid(e.reference)||!!s.test(e.reference)}shouldPersistResolution(e,t){return t.resolver.shouldPersistResolution(this.forwardLocator(e,t),t)}bindDescriptor(e,t,r){return r.resolver.bindDescriptor(this.forwardDescriptor(e,r),t,r)}getResolutionDependencies(e,t){return t.resolver.getResolutionDependencies(this.forwardDescriptor(e,t),t)}async getCandidates(e,t,r){return await r.resolver.getCandidates(this.forwardDescriptor(e,r),t,r)}async getSatisfying(e,t,r){return await r.resolver.getSatisfying(this.forwardDescriptor(e,r),t,r)}async resolve(e,t){const r=await t.resolver.resolve(this.forwardLocator(e,t),t);return i.renamePackage(r,e)}forwardDescriptor(e,t){return i.makeDescriptor(e,`${t.project.configuration.get("defaultProtocol")}${e.range}`)}forwardLocator(e,t){return i.makeLocator(e,`${t.project.configuration.get("defaultProtocol")}${e.reference}`)}}},35691:(e,t,r)=>{"use strict";r.d(t,{lk:()=>i,yG:()=>s});var A=r(92413),n=r(24304),o=r(92659);class i extends Error{constructor(e,t,r){super(t),this.reportExtra=r,this.reportCode=e}}class s{constructor(){this.reportedInfos=new Set,this.reportedWarnings=new Set,this.reportedErrors=new Set}static progressViaCounter(e){let t,r=0,A=new Promise(e=>{t=e});const n=e=>{const n=t;A=new Promise(e=>{t=e}),r=e,n()},o=async function*(){for(;ro,set:n,tick:(e=0)=>{n(r+1)}}}reportInfoOnce(e,t,r){const A=r&&r.key?r.key:t;this.reportedInfos.has(A)||(this.reportedInfos.add(A),this.reportInfo(e,t))}reportWarningOnce(e,t,r){const A=r&&r.key?r.key:t;this.reportedWarnings.has(A)||(this.reportedWarnings.add(A),this.reportWarning(e,t))}reportErrorOnce(e,t,r){var A;const n=r&&r.key?r.key:t;this.reportedErrors.has(n)||(this.reportedErrors.add(n),this.reportError(e,t),null===(A=null==r?void 0:r.reportExtra)||void 0===A||A.call(r,this))}reportExceptionOnce(e){!function(e){return void 0!==e.reportCode}(e)?this.reportErrorOnce(o.b.EXCEPTION,e.stack||e.message,{key:e}):this.reportErrorOnce(e.reportCode,e.message,{key:e,reportExtra:e.reportExtra})}createStreamReporter(e=null){const t=new A.PassThrough,r=new n.StringDecoder;let o="";return t.on("data",t=>{let A,n=r.write(t);do{if(A=n.indexOf("\n"),-1!==A){const t=o+n.substr(0,A);n=n.substr(A+1),o="",null!==e?this.reportInfo(null,`${e} ${t}`):this.reportInfo(null,t)}}while(-1!==A);o+=n}),t.on("end",()=>{const t=r.end();""!==t&&(null!==e?this.reportInfo(null,`${e} ${t}`):this.reportInfo(null,t))}),t}}},15815:(e,t,r)=>{"use strict";r.d(t,{Qw:()=>C,Pk:()=>f});var A=r(29148),n=r.n(A),o=r(92659),i=r(35691),s=r(71643);const a=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],c=new Set([o.b.FETCH_NOT_CACHED,o.b.UNUSED_CACHE_ENTRY]),g=process.env.GITHUB_ACTIONS?{start:e=>`::group::${e}\n`,end:e=>"::endgroup::\n"}:process.env.TRAVIS?{start:e=>`travis_fold:start:${e}\n`,end:e=>`travis_fold:end:${e}\n`}:process.env.GITLAB_CI?{start:e=>`section_start:${Math.floor(Date.now()/1e3)}:${e.toLowerCase().replace(/\W+/g,"_")}\r${e}\n`,end:e=>`section_end:${Math.floor(Date.now()/1e3)}:${e.toLowerCase().replace(/\W+/g,"_")}\r`}:null,l=new Date,u=["iTerm.app","Apple_Terminal"].includes(process.env.TERM_PROGRAM)||!!process.env.WT_SESSION,h={patrick:{date:[17,3],chars:["🍀","🌱"],size:40},simba:{date:[19,7],chars:["🦁","🌴"],size:40},jack:{date:[31,10],chars:["🎃","🦇"],size:40},hogsfather:{date:[31,12],chars:["🎉","🎄"],size:40},default:{chars:["=","-"],size:80}},p=u&&Object.keys(h).find(e=>{const t=h[e];return!t.date||t.date[0]===l.getDate()&&t.date[1]===l.getMonth()+1})||"default";function d(e,{configuration:t,json:r}){const A=null===e?0:e,n=(0,o.i)(A);return r||null!==e?n:s.pretty(t,n,"grey")}function C(e,{configuration:t,json:r}){const A=d(e,{configuration:t,json:r});if(!t.get("enableHyperlinks"))return A;if(null===e||e===o.b.UNNAMED)return A;return`]8;;${`https://yarnpkg.com/advanced/error-codes#${A}---${o.b[e]}`.toLowerCase()}${A}]8;;`}class f extends i.yG{constructor({configuration:e,stdout:t,json:r=!1,includeFooter:A=!0,includeLogs:n=!r,includeInfos:o=n,includeWarnings:i=n,forgettableBufferSize:a=5,forgettableNames:g=new Set}){super(),this.uncommitted=new Set,this.cacheHitCount=0,this.cacheMissCount=0,this.warningCount=0,this.errorCount=0,this.startTime=Date.now(),this.indent=0,this.progress=new Map,this.progressTime=0,this.progressFrame=0,this.progressTimeout=null,this.forgettableLines=[],s.addLogFilterSupport(this,{configuration:e}),this.configuration=e,this.forgettableBufferSize=a,this.forgettableNames=new Set([...g,...c]),this.includeFooter=A,this.includeInfos=o,this.includeWarnings=i,this.json=r,this.stdout=t;const l=this.configuration.get("progressBarStyle")||p;if(!Object.prototype.hasOwnProperty.call(h,l))throw new Error("Assertion failed: Invalid progress bar style");this.progressStyle=h[l];const u="➤ YN0000: ┌ ".length,d=Math.max(0,Math.min(process.stdout.columns-u,80));this.progressMaxScaledSize=Math.floor(this.progressStyle.size*d/80)}static async start(e,t){const r=new this(e),A=process.emitWarning;process.emitWarning=(e,t)=>{if("string"!=typeof e){const r=e;e=r.message,t=null!=t?t:r.name}const A=void 0!==t?`${t}: ${e}`:e;r.reportWarning(o.b.UNNAMED,A)};try{await t(r)}catch(e){r.reportExceptionOnce(e)}finally{await r.finalize(),process.emitWarning=A}return r}hasErrors(){return this.errorCount>0}exitCode(){return this.hasErrors()?1:0}reportCacheHit(e){this.cacheHitCount+=1}reportCacheMiss(e,t){this.cacheMissCount+=1,void 0===t||this.configuration.get("preferAggregateCacheInfo")||this.reportInfo(o.b.FETCH_NOT_CACHED,t)}startTimerSync(e,t,r){const A="function"==typeof t?t:r,n={committed:!1,action:()=>{this.reportInfo(null,"┌ "+e),this.indent+=1,null!==g&&this.stdout.write(g.start(e))}};("function"==typeof t?{}:t).skipIfEmpty?this.uncommitted.add(n):(n.action(),n.committed=!0);const o=Date.now();try{return A()}catch(e){throw this.reportExceptionOnce(e),e}finally{const t=Date.now();this.uncommitted.delete(n),n.committed&&(this.indent-=1,null!==g&&this.stdout.write(g.end(e)),this.configuration.get("enableTimers")&&t-o>200?this.reportInfo(null,"└ Completed in "+s.pretty(this.configuration,t-o,s.Type.DURATION)):this.reportInfo(null,"└ Completed"))}}async startTimerPromise(e,t,r){const A="function"==typeof t?t:r,n={committed:!1,action:()=>{this.reportInfo(null,"┌ "+e),this.indent+=1,null!==g&&this.stdout.write(g.start(e))}};("function"==typeof t?{}:t).skipIfEmpty?this.uncommitted.add(n):(n.action(),n.committed=!0);const o=Date.now();try{return await A()}catch(e){throw this.reportExceptionOnce(e),e}finally{const t=Date.now();this.uncommitted.delete(n),n.committed&&(this.indent-=1,null!==g&&this.stdout.write(g.end(e)),this.configuration.get("enableTimers")&&t-o>200?this.reportInfo(null,"└ Completed in "+s.pretty(this.configuration,t-o,s.Type.DURATION)):this.reportInfo(null,"└ Completed"))}}async startCacheReport(e){const t=this.configuration.get("preferAggregateCacheInfo")?{cacheHitCount:this.cacheHitCount,cacheMissCount:this.cacheMissCount}:null;try{return await e()}catch(e){throw this.reportExceptionOnce(e),e}finally{null!==t&&this.reportCacheChanges(t)}}reportSeparator(){0===this.indent?this.writeLineWithForgettableReset(""):this.reportInfo(null,"")}reportInfo(e,t){if(!this.includeInfos)return;this.commit();const r=`${s.pretty(this.configuration,"➤","blueBright")} ${this.formatNameWithHyperlink(e)}: ${this.formatIndent()}${t}`;if(this.json)this.reportJson({type:"info",name:e,displayName:this.formatName(e),indent:this.formatIndent(),data:t});else if(this.forgettableNames.has(e))if(this.forgettableLines.push(r),this.forgettableLines.length>this.forgettableBufferSize){for(;this.forgettableLines.length>this.forgettableBufferSize;)this.forgettableLines.shift();this.writeLines(this.forgettableLines,{truncate:!0})}else this.writeLine(r,{truncate:!0});else this.writeLineWithForgettableReset(r)}reportWarning(e,t){this.warningCount+=1,this.includeWarnings&&(this.commit(),this.json?this.reportJson({type:"warning",name:e,displayName:this.formatName(e),indent:this.formatIndent(),data:t}):this.writeLineWithForgettableReset(`${s.pretty(this.configuration,"➤","yellowBright")} ${this.formatNameWithHyperlink(e)}: ${this.formatIndent()}${t}`))}reportError(e,t){this.errorCount+=1,this.commit(),this.json?this.reportJson({type:"error",name:e,displayName:this.formatName(e),indent:this.formatIndent(),data:t}):this.writeLineWithForgettableReset(`${s.pretty(this.configuration,"➤","redBright")} ${this.formatNameWithHyperlink(e)}: ${this.formatIndent()}${t}`,{truncate:!1})}reportProgress(e){let t=!1;const r=Promise.resolve().then(async()=>{const r={progress:0,title:void 0};this.progress.set(e,{definition:r,lastScaledSize:-1}),this.refreshProgress(-1);for await(const{progress:A,title:n}of e)t||r.progress===A&&r.title===n||(r.progress=A,r.title=n,this.refreshProgress());A()}),A=()=>{t||(t=!0,this.progress.delete(e),this.refreshProgress(1))};return{...r,stop:A}}reportJson(e){this.json&&this.writeLineWithForgettableReset(""+JSON.stringify(e))}async finalize(){if(!this.includeFooter)return;let e="";e=this.errorCount>0?"Failed with errors":this.warningCount>0?"Done with warnings":"Done";const t=s.pretty(this.configuration,Date.now()-this.startTime,s.Type.DURATION),r=this.configuration.get("enableTimers")?`${e} in ${t}`:e;this.errorCount>0?this.reportError(o.b.UNNAMED,r):this.warningCount>0?this.reportWarning(o.b.UNNAMED,r):this.reportInfo(o.b.UNNAMED,r)}writeLine(e,{truncate:t}={}){this.clearProgress({clear:!0}),this.stdout.write(this.truncate(e,{truncate:t})+"\n"),this.writeProgress()}writeLineWithForgettableReset(e,{truncate:t}={}){this.forgettableLines=[],this.writeLine(e,{truncate:t})}writeLines(e,{truncate:t}={}){this.clearProgress({delta:e.length});for(const r of e)this.stdout.write(this.truncate(r,{truncate:t})+"\n");this.writeProgress()}reportCacheChanges({cacheHitCount:e,cacheMissCount:t}){const r=this.cacheHitCount-e,A=this.cacheMissCount-t;if(0===r&&0===A)return;let n="";this.cacheHitCount>1?n+=this.cacheHitCount+" packages were already cached":1===this.cacheHitCount?n+=" - one package was already cached":n+="No packages were cached",this.cacheHitCount>0?this.cacheMissCount>1?n+=`, ${this.cacheMissCount} had to be fetched`:1===this.cacheMissCount&&(n+=", one had to be fetched"):this.cacheMissCount>1?n+=` - ${this.cacheMissCount} packages had to be fetched`:1===this.cacheMissCount&&(n+=" - one package had to be fetched"),this.reportInfo(o.b.FETCH_NOT_CACHED,n)}commit(){const e=this.uncommitted;this.uncommitted=new Set;for(const t of e)t.committed=!0,t.action()}clearProgress({delta:e=0,clear:t=!1}){this.configuration.get("enableProgressBars")&&!this.json&&this.progress.size+e>0&&(this.stdout.write(`[${this.progress.size+e}A`),(e>0||t)&&this.stdout.write(""))}writeProgress(){if(!this.configuration.get("enableProgressBars")||this.json)return;if(null!==this.progressTimeout&&clearTimeout(this.progressTimeout),this.progressTimeout=null,0===this.progress.size)return;const e=Date.now();e-this.progressTime>80&&(this.progressFrame=(this.progressFrame+1)%a.length,this.progressTime=e);const t=a[this.progressFrame];for(const e of this.progress.values()){const r=this.progressStyle.chars[0].repeat(e.lastScaledSize),A=this.progressStyle.chars[1].repeat(this.progressMaxScaledSize-e.lastScaledSize);this.stdout.write(`${s.pretty(this.configuration,"➤","blueBright")} ${this.formatName(null)}: ${t} ${r}${A}\n`)}this.progressTimeout=setTimeout(()=>{this.refreshProgress()},80)}refreshProgress(e=0){let t=!1;if(0===this.progress.size)t=!0;else for(const e of this.progress.values()){const r=Math.trunc(this.progressMaxScaledSize*e.definition.progress),A=e.lastScaledSize;if(e.lastScaledSize=r,r!==A){t=!0;break}}t&&(this.clearProgress({delta:e}),this.writeProgress())}truncate(e,{truncate:t}={}){return this.configuration.get("enableProgressBars")||(t=!1),void 0===t&&(t=this.configuration.get("preferTruncatedLines")),t&&(e=n()(e,0,process.stdout.columns-1)),e}formatName(e){return d(e,{configuration:this.configuration,json:this.json})}formatNameWithHyperlink(e){return C(e,{configuration:this.configuration,json:this.json})}formatIndent(){return"│ ".repeat(this.indent)}}},81832:(e,t,r)=>{"use strict";r.d(t,{E:()=>a});var A,n=r(43896),o=r(46009),i=r(79669),s=r(73632);!function(e){e.VERSION="version",e.COMMAND_NAME="commandName",e.PLUGIN_NAME="pluginName",e.INSTALL_COUNT="installCount",e.PROJECT_COUNT="projectCount",e.WORKSPACE_COUNT="workspaceCount",e.DEPENDENCY_COUNT="dependencyCount",e.EXTENSION="packageExtension"}(A||(A={}));class a{constructor(e,t){this.values=new Map,this.hits=new Map,this.enumerators=new Map,this.configuration=e;const r=this.getRegistryPath();this.isNew=!n.xfs.existsSync(r),this.sendReport(t),this.startBuffer()}reportVersion(e){this.reportValue(A.VERSION,e)}reportCommandName(e){this.reportValue(A.COMMAND_NAME,e||"")}reportPluginName(e){this.reportValue(A.PLUGIN_NAME,e)}reportProject(e){this.reportEnumerator(A.PROJECT_COUNT,e)}reportInstall(e){this.reportHit(A.INSTALL_COUNT,e)}reportPackageExtension(e){this.reportValue(A.EXTENSION,e)}reportWorkspaceCount(e){this.reportValue(A.WORKSPACE_COUNT,String(e))}reportDependencyCount(e){this.reportValue(A.DEPENDENCY_COUNT,String(e))}reportValue(e,t){s.getSetWithDefault(this.values,e).add(t)}reportEnumerator(e,t){s.getSetWithDefault(this.enumerators,e).add(t)}reportHit(e,t="*"){const r=s.getMapWithDefault(this.hits,e),A=s.getFactoryWithDefault(r,t,()=>0);r.set(t,A+1)}getRegistryPath(){const e=this.configuration.get("globalFolder");return o.y1.join(e,"telemetry.json")}sendReport(e){var t,r,A;const s=this.getRegistryPath();let a;try{a=n.xfs.readJsonSync(s)}catch(e){a={}}const c=Date.now(),g=24*this.configuration.get("telemetryInterval")*60*60*1e3,l=(null!==(t=a.lastUpdate)&&void 0!==t?t:c+g+Math.floor(g*Math.random()))+g;if(!(l>c&&null!=a.lastUpdate)){try{n.xfs.mkdirSync(o.y1.dirname(s),{recursive:!0}),n.xfs.writeJsonSync(s,{lastUpdate:c})}catch(e){return}if(!(l>c)&&a.blocks)for(const[t,n]of Object.entries(null!==(r=a.blocks)&&void 0!==r?r:{})){if(0===Object.keys(n).length)continue;const r=n;r.userId=t;for(const e of Object.keys(null!==(A=r.enumerators)&&void 0!==A?A:{}))r.enumerators[e]=r.enumerators[e].length;const o=`https://browser-http-intake.logs.datadoghq.eu/v1/input/${e}?ddsource=yarn`;i.post(o,r,{configuration:this.configuration}).catch(()=>{})}}}applyChanges(){var e,t,r,A,i,s,a,c,g;const l=this.getRegistryPath();let u;try{u=n.xfs.readJsonSync(l)}catch(e){u={}}const h=null!==(e=this.configuration.get("telemetryUserId"))&&void 0!==e?e:"*",p=u.blocks=null!==(t=u.blocks)&&void 0!==t?t:{},d=p[h]=null!==(r=p[h])&&void 0!==r?r:{};for(const e of this.hits.keys()){const t=d.hits=null!==(A=d.hits)&&void 0!==A?A:{},r=t[e]=null!==(i=t[e])&&void 0!==i?i:{};for(const[t,A]of this.hits.get(e))r[t]=(null!==(s=r[t])&&void 0!==s?s:0)+A}for(const e of["values","enumerators"])for(const t of this[e].keys()){const r=d[e]=null!==(a=d[e])&&void 0!==a?a:{};r[t]=[...new Set([...null!==(c=r[t])&&void 0!==c?c:[],...null!==(g=this[e].get(t))&&void 0!==g?g:[]])]}n.xfs.mkdirSync(o.y1.dirname(l),{recursive:!0}),n.xfs.writeJsonSync(l,u)}startBuffer(){process.on("exit",()=>{try{this.applyChanges()}catch(e){}})}}},33720:(e,t,r)=>{"use strict";r.d(t,{$:()=>n});var A=r(35691);class n extends A.yG{reportCacheHit(e){}reportCacheMiss(e){}startTimerSync(e,t,r){return("function"==typeof t?t:r)()}async startTimerPromise(e,t,r){const A="function"==typeof t?t:r;return await A()}async startCacheReport(e){return await e()}reportSeparator(){}reportInfo(e,t){}reportWarning(e,t){}reportError(e,t){}reportProgress(e){return{...Promise.resolve().then(async()=>{for await(const{}of e);}),stop:()=>{}}}reportJson(e){}async finalize(){}}},60895:(e,t,r)=>{"use strict";r.d(t,{N:()=>s});var A=r(17674),n=r(14626),o=r(46009),i=r(54143);class s{supports(e){return!!e.reference.startsWith("virtual:")}getLocalPath(e,t){const r=e.reference.indexOf("#");if(-1===r)throw new Error("Invalid virtual package reference");const A=e.reference.slice(r+1),n=i.makeLocator(e,A);return t.fetcher.getLocalPath(n,t)}async fetch(e,t){const r=e.reference.indexOf("#");if(-1===r)throw new Error("Invalid virtual package reference");const A=e.reference.slice(r+1),n=i.makeLocator(e,A),o=await t.fetcher.fetch(n,t);return await this.ensureVirtualLink(e,o,t)}getLocatorFilename(e){return i.slugifyLocator(e)}async ensureVirtualLink(e,t,r){const i=t.packageFs.getRealPath(),s=r.project.configuration.get("virtualFolder"),a=this.getLocatorFilename(e),c=A.p.makeVirtualPath(s,a,i),g=new n.K(c,{baseFs:t.packageFs,pathUtils:o.y1});return{...t,packageFs:g}}}},17722:(e,t,r)=>{"use strict";r.d(t,{j:()=>h});var A=r(43896),n=r(46009),o=r(58592),i=r.n(o),s=r(53887),a=r.n(s),c=r(46611),g=r(94538),l=r(20624),u=r(54143);class h{constructor(e,{project:t}){this.workspacesCwds=new Set,this.dependencies=new Map,this.project=t,this.cwd=e}async setup(){this.manifest=A.xfs.existsSync(n.y1.join(this.cwd,c.G.fileName))?await c.G.find(this.cwd):new c.G,this.relativeCwd=n.y1.relative(this.project.cwd,this.cwd)||n.LZ.dot;const e=this.manifest.name?this.manifest.name:u.makeIdent(null,`${this.computeCandidateName()}-${l.makeHash(this.relativeCwd).substr(0,6)}`),t=this.manifest.version?this.manifest.version:"0.0.0";this.locator=u.makeLocator(e,t),this.anchoredDescriptor=u.makeDescriptor(this.locator,`${g.d.protocol}${this.relativeCwd}`),this.anchoredLocator=u.makeLocator(this.locator,`${g.d.protocol}${this.relativeCwd}`);const r=this.manifest.workspaceDefinitions.map(({pattern:e})=>e),o=await i()(r,{absolute:!0,cwd:n.cS.fromPortablePath(this.cwd),expandDirectories:!1,onlyDirectories:!0,onlyFiles:!1,ignore:["**/node_modules","**/.git","**/.yarn"]});o.sort();for(const e of o){const t=n.y1.resolve(this.cwd,n.cS.toPortablePath(e));A.xfs.existsSync(n.y1.join(t,"package.json"))&&this.workspacesCwds.add(t)}}accepts(e){const t=e.indexOf(":"),r=-1!==t?e.slice(0,t+1):null,A=-1!==t?e.slice(t+1):e;return r===g.d.protocol&&n.y1.normalize(A)===this.relativeCwd||(r===g.d.protocol&&"*"===A||!!a().validRange(A)&&(r===g.d.protocol?a().satisfies(null!==this.manifest.version?this.manifest.version:"0.0.0",A):!!this.project.configuration.get("enableTransparentWorkspaces")&&(null!==this.manifest.version&&a().satisfies(this.manifest.version,A))))}computeCandidateName(){return this.cwd===this.project.cwd?"root-workspace":""+n.y1.basename(this.cwd)||"unnamed-workspace"}async persistManifest(){const e={};this.manifest.exportTo(e);const t=n.y1.join(this.cwd,c.G.fileName),r=JSON.stringify(e,null,this.manifest.indent)+"\n";await A.xfs.changeFilePromise(t,r,{automaticNewlines:!0})}}},94538:(e,t,r)=>{"use strict";r.d(t,{d:()=>n});var A=r(32485);class n{supportsDescriptor(e,t){if(e.range.startsWith(n.protocol))return!0;return null!==t.project.tryWorkspaceByDescriptor(e)}supportsLocator(e,t){return!!e.reference.startsWith(n.protocol)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,r){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,r){return[r.project.getWorkspaceByDescriptor(e).anchoredLocator]}async getSatisfying(e,t,r){return null}async resolve(e,t){const r=t.project.getWorkspaceByCwd(e.reference.slice(n.protocol.length));return{...e,version:r.manifest.version||"0.0.0",languageName:"unknown",linkType:A.Un.SOFT,dependencies:new Map([...r.manifest.dependencies,...r.manifest.devDependencies]),peerDependencies:new Map([...r.manifest.peerDependencies]),dependenciesMeta:r.manifest.dependenciesMeta,peerDependenciesMeta:r.manifest.peerDependenciesMeta,bin:r.manifest.bin}}}n.protocol="workspace:"},59355:(e,t,r)=>{"use strict";r.d(t,{o:()=>A});const A="2.4.1"},6220:(e,t,r)=>{"use strict";r.r(t),r.d(t,{EndStrategy:()=>A,pipevp:()=>g,execvp:()=>l});var A,n=r(46009),o=r(67566),i=r.n(o);function s(e){return null!==e&&"number"==typeof e.fd}function a(){}!function(e){e[e.Never=0]="Never",e[e.ErrorCode=1]="ErrorCode",e[e.Always=2]="Always"}(A||(A={}));let c=0;async function g(e,t,{cwd:r,env:o=process.env,strict:g=!1,stdin:l=null,stdout:u,stderr:p,end:d=A.Always}){const C=["pipe","pipe","pipe"];null===l?C[0]="ignore":s(l)&&(C[0]=l),s(u)&&(C[1]=u),s(p)&&(C[2]=p),0==c++&&process.on("SIGINT",a);const f=i()(e,t,{cwd:n.cS.fromPortablePath(r),env:{...o,PWD:n.cS.fromPortablePath(r)},stdio:C});s(l)||null===l||l.pipe(f.stdin),s(u)||f.stdout.pipe(u,{end:!1}),s(p)||f.stderr.pipe(p,{end:!1});const I=()=>{for(const e of new Set([u,p]))s(e)||e.end()};return new Promise((t,r)=>{f.on("error",e=>{0==--c&&process.off("SIGINT",a),d!==A.Always&&d!==A.ErrorCode||I(),r(e)}),f.on("close",(n,o)=>{0==--c&&process.off("SIGINT",a),(d===A.Always||d===A.ErrorCode&&n>0)&&I(),0!==n&&g?r(null!==n?new Error(`Child "${e}" exited with exit code ${n}`):new Error(`Child "${e}" exited with signal ${o}`)):t({code:h(n,o)})})})}async function l(e,t,{cwd:r,env:A=process.env,encoding:o="utf8",strict:s=!1}){const a=["ignore","pipe","pipe"],c=[],g=[],l=n.cS.fromPortablePath(r);void 0!==A.PWD&&(A={...A,PWD:l});const u=i()(e,t,{cwd:l,env:A,stdio:a});return u.stdout.on("data",e=>{c.push(e)}),u.stderr.on("data",e=>{g.push(e)}),await new Promise((t,r)=>{u.on("error",r),u.on("close",(A,n)=>{const i="buffer"===o?Buffer.concat(c):Buffer.concat(c).toString(o),a="buffer"===o?Buffer.concat(g):Buffer.concat(g).toString(o);0!==A&&s?r(Object.assign(new Error(`Child "${e}" exited with exit code ${A}\n\n${a}`),{code:h(A,n),stdout:i,stderr:a})):t({code:h(A,n),stdout:i,stderr:a})})})}const u=new Map([["SIGINT",2],["SIGQUIT",3],["SIGKILL",9],["SIGTERM",15]]);function h(e,t){const r=u.get(t);return void 0!==r?128+r:null!=e?e:1}},81111:(e,t,r)=>{"use strict";r.r(t),r.d(t,{getDefaultGlobalFolder:()=>o,getHomeFolder:()=>i,isFolderInside:()=>s});var A=r(46009),n=r(12087);function o(){if("win32"===process.platform){const e=A.cS.toPortablePath(process.env.LOCALAPPDATA||A.cS.join((0,n.homedir)(),"AppData","Local"));return A.y1.resolve(e,"Yarn/Berry")}if(process.env.XDG_DATA_HOME){const e=A.cS.toPortablePath(process.env.XDG_DATA_HOME);return A.y1.resolve(e,"yarn/berry")}return A.y1.resolve(i(),".yarn/berry")}function i(){return A.cS.toPortablePath((0,n.homedir)()||"/usr/local/share")}function s(e,t){const r=A.y1.relative(t,e);return r&&!r.startsWith("..")&&!A.y1.isAbsolute(r)}},71643:(e,t,r)=>{"use strict";r.r(t),r.d(t,{Type:()=>A,Style:()=>n,supportsColor:()=>h,supportsHyperlinks:()=>p,tuple:()=>I,applyStyle:()=>E,applyColor:()=>B,pretty:()=>y,prettyList:()=>m,json:()=>w,mark:()=>Q,LogLevel:()=>D,addLogFilterSupport:()=>b});var A,n,o=r(46009),i=r(95882),s=r.n(i),a=r(92659),c=r(73632),g=r(54143),l=r(32485);!function(e){e.NO_HINT="NO_HINT",e.NULL="NULL",e.SCOPE="SCOPE",e.NAME="NAME",e.RANGE="RANGE",e.REFERENCE="REFERENCE",e.NUMBER="NUMBER",e.PATH="PATH",e.URL="URL",e.ADDED="ADDED",e.REMOVED="REMOVED",e.CODE="CODE",e.DURATION="DURATION",e.SIZE="SIZE",e.IDENT="IDENT",e.DESCRIPTOR="DESCRIPTOR",e.LOCATOR="LOCATOR",e.RESOLUTION="RESOLUTION",e.DEPENDENT="DEPENDENT",e.PACKAGE_EXTENSION="PACKAGE_EXTENSION"}(A||(A={})),function(e){e[e.BOLD=2]="BOLD"}(n||(n={}));const u=process.env.GITHUB_ACTIONS?{level:2}:s().supportsColor?{level:s().supportsColor.level}:{level:0},h=0!==u.level,p=h&&!process.env.GITHUB_ACTIONS,d=new(s().Instance)(u),C=new Map([[A.NO_HINT,null],[A.NULL,["#a853b5",129]],[A.SCOPE,["#d75f00",166]],[A.NAME,["#d7875f",173]],[A.RANGE,["#00afaf",37]],[A.REFERENCE,["#87afff",111]],[A.NUMBER,["#ffd700",220]],[A.PATH,["#d75fd7",170]],[A.URL,["#d75fd7",170]],[A.ADDED,["#5faf00",70]],[A.REMOVED,["#d70000",160]],[A.CODE,["#87afff",111]],[A.SIZE,["#ffd700",220]]]),f={[A.NUMBER]:{pretty:(e,t)=>""+t,json:e=>e},[A.IDENT]:{pretty:(e,t)=>g.prettyIdent(e,t),json:e=>g.stringifyIdent(e)},[A.LOCATOR]:{pretty:(e,t)=>g.prettyLocator(e,t),json:e=>g.stringifyLocator(e)},[A.DESCRIPTOR]:{pretty:(e,t)=>g.prettyDescriptor(e,t),json:e=>g.stringifyDescriptor(e)},[A.RESOLUTION]:{pretty:(e,{descriptor:t,locator:r})=>g.prettyResolution(e,t,r),json:({descriptor:e,locator:t})=>({descriptor:g.stringifyDescriptor(e),locator:null!==t?g.stringifyLocator(t):null})},[A.DEPENDENT]:{pretty:(e,{locator:t,descriptor:r})=>g.prettyDependent(e,t,r),json:({locator:e,descriptor:t})=>({locator:g.stringifyLocator(e),descriptor:g.stringifyDescriptor(t)})},[A.PACKAGE_EXTENSION]:{pretty:(e,t)=>{switch(t.type){case l.HN.Dependency:return`${g.prettyIdent(e,t.parentDescriptor)} ➤ ${B(e,"dependencies",A.CODE)} ➤ ${g.prettyIdent(e,t.descriptor)}`;case l.HN.PeerDependency:return`${g.prettyIdent(e,t.parentDescriptor)} ➤ ${B(e,"peerDependencies",A.CODE)} ➤ ${g.prettyIdent(e,t.descriptor)}`;case l.HN.PeerDependencyMeta:return`${g.prettyIdent(e,t.parentDescriptor)} ➤ ${B(e,"peerDependenciesMeta",A.CODE)} ➤ ${g.prettyIdent(e,g.parseIdent(t.selector))} ➤ ${B(e,t.key,A.CODE)}`;default:throw new Error("Assertion failed: Unsupported package extension type: "+t.type)}},json:e=>{switch(e.type){case l.HN.Dependency:return`${g.stringifyIdent(e.parentDescriptor)} > ${g.stringifyIdent(e.descriptor)}`;case l.HN.PeerDependency:return`${g.stringifyIdent(e.parentDescriptor)} >> ${g.stringifyIdent(e.descriptor)}`;case l.HN.PeerDependencyMeta:return`${g.stringifyIdent(e.parentDescriptor)} >> ${e.selector} / ${e.key}`;default:throw new Error("Assertion failed: Unsupported package extension type: "+e.type)}}},[A.DURATION]:{pretty:(e,t)=>{if(t>6e4){const e=Math.floor(t/1e3/60),r=Math.ceil((t-60*e*1e3)/1e3);return 0===r?e+"m":`${e}m ${r}s`}{const e=Math.floor(t/1e3),r=t-1e3*e;return 0===r?e+"s":`${e}s ${r}ms`}},json:e=>e},[A.SIZE]:{pretty:(e,t)=>{const r=["KB","MB","GB","TB"];let n=r.length;for(;n>1&&t<1024**n;)n-=1;const o=1024**n;return B(e,`${Math.floor(100*t/o)/100} ${r[n-1]}`,A.NUMBER)},json:e=>e},[A.PATH]:{pretty:(e,t)=>B(e,o.cS.fromPortablePath(t),A.PATH),json:e=>o.cS.fromPortablePath(e)}};function I(e,t){return[t,e]}function E(e,t,r){return e.get("enableColors")?(r&n.BOLD&&(t=s().bold(t)),t):t}function B(e,t,r){if(!e.get("enableColors"))return t;const A=C.get(r);if(null===A)return t;const n=void 0===A?r:u.level>=3?A[0]:A[1],o="number"==typeof n?d.ansi256(n):n.startsWith("#")?d.hex(n):d[n];if("function"!=typeof o)throw new Error("Invalid format type "+n);return o(t)}function y(e,t,r){if(null===t)return B(e,"null",A.NULL);if(Object.prototype.hasOwnProperty.call(f,r)){return f[r].pretty(e,t)}if("string"!=typeof t)throw new Error("Assertion failed: Expected the value to be a string, got "+typeof t);return B(e,t,r)}function m(e,t,r,{separator:A=", "}={}){return[...t].map(t=>y(e,t,r)).join(A)}function w(e,t){if(null===e)return null;if(Object.prototype.hasOwnProperty.call(f,t))return c.overrideType(t),f[t].json(e);if("string"!=typeof e)throw new Error("Assertion failed: Expected the value to be a string, got "+typeof e);return e}function Q(e){return{Check:B(e,"✓","green"),Cross:B(e,"✘","red"),Question:B(e,"?","cyan")}}var D;function b(e,{configuration:t}){const r=t.get("logFilters"),A=new Map,n=new Map;for(const e of r){const t=e.get("level");if(void 0===t)continue;const r=e.get("code");void 0!==r&&A.set(r,t);const o=e.get("text");void 0!==o&&n.set(o,t)}const o=e.reportInfo,i=e.reportWarning,c=e.reportError,g=function(e,t,r,g){switch(((e,t,r)=>{if(null===e||e===a.b.UNNAMED)return r;if(n.size>0){const e=n.get(s().reset(t));if(void 0!==e)return null!=e?e:r}if(A.size>0){const t=A.get((0,a.i)(e));if(void 0!==t)return null!=t?t:r}return r})(t,r,g)){case D.Info:o.call(e,t,r);break;case D.Warning:i.call(e,null!=t?t:a.b.UNNAMED,r);break;case D.Error:c.call(e,null!=t?t:a.b.UNNAMED,r)}};e.reportInfo=function(...e){return g(this,...e,D.Info)},e.reportWarning=function(...e){return g(this,...e,D.Warning)},e.reportError=function(...e){return g(this,...e,D.Error)}}!function(e){e.Error="error",e.Warning="warning",e.Info="info",e.Discard="discard"}(D||(D={}))},20624:(e,t,r)=>{"use strict";r.r(t),r.d(t,{makeHash:()=>a,checksumFile:()=>c,checksumPattern:()=>g});var A=r(43896),n=r(46009),o=r(76417),i=r(58592),s=r.n(i);function a(...e){const t=(0,o.createHash)("sha512");for(const r of e)t.update(r||"");return t.digest("hex")}function c(e){return new Promise((t,r)=>{const n=(0,o.createHash)("sha512"),i=A.xfs.createReadStream(e);i.on("data",e=>{n.update(e)}),i.on("error",e=>{r(e)}),i.on("end",()=>{t(n.digest("hex"))})})}async function g(e,{cwd:t}){const r=(await s()(e,{cwd:n.cS.fromPortablePath(t),expandDirectories:!1,onlyDirectories:!0,unique:!0})).map(e=>e+"/**/*"),i=await s()([e,...r],{cwd:n.cS.fromPortablePath(t),expandDirectories:!1,onlyFiles:!1,unique:!0});i.sort();const a=await Promise.all(i.map(async e=>{const t=[Buffer.from(e)],r=n.cS.toPortablePath(e),o=await A.xfs.lstatPromise(r);return o.isSymbolicLink()?t.push(Buffer.from(await A.xfs.readlinkPromise(r))):o.isFile()&&t.push(await A.xfs.readFilePromise(r)),t.join("\0")})),c=(0,o.createHash)("sha512");for(const e of a)c.update(e);return c.digest("hex")}},79669:(e,t,r)=>{"use strict";r.r(t),r.d(t,{getNetworkSettings:()=>d,Method:()=>C,request:()=>f,get:()=>I,put:()=>E,post:()=>B,del:()=>y});var A=r(43896),n=r(57211),o=r(98605),i=r(2401),s=r.n(i),a=r(98161),c=r(78835);const g=new Map,l=new Map,u=new o.Agent({keepAlive:!0}),h=new n.Agent({keepAlive:!0});function p(e){const t=new c.URL(e),r={host:t.hostname,headers:{}};return t.port&&(r.port=Number(t.port)),{proxy:r}}function d(e,t){const r=[...t.configuration.get("networkSettings")].sort(([e],[t])=>t.length-e.length),A={enableNetwork:void 0,caFilePath:void 0,httpProxy:void 0,httpsProxy:void 0},n=Object.keys(A),o=new c.URL(e);for(const[e,t]of r)if(s().isMatch(o.hostname,e))for(const e of n){const r=t.get(e);null!==r&&void 0===A[e]&&(A[e]=r)}for(const e of n)void 0===A[e]&&(A[e]=t.configuration.get(e));return A}var C;async function f(e,t,{configuration:n,headers:o,json:i,jsonRequest:g=i,jsonResponse:f=i,method:I=C.GET}){const E=d(e,{configuration:n});if(!1===E.enableNetwork)throw new Error(`Request to '${e}' has been blocked because of your configuration settings`);const B=new c.URL(e);if("http:"===B.protocol&&!s().isMatch(B.hostname,n.get("unsafeHttpWhitelist")))throw new Error(`Unsafe http requests must be explicitly whitelisted in your configuration (${B.hostname})`);const y={agent:{http:E.httpProxy?a.httpOverHttp(p(E.httpProxy)):u,https:E.httpsProxy?a.httpsOverHttp(p(E.httpsProxy)):h},headers:o,method:I};y.responseType=f?"json":"buffer",null!==t&&(Buffer.isBuffer(t)||!g&&"string"==typeof t?y.body=t:y.json=t);const m=n.get("httpTimeout"),w=n.get("httpRetry"),Q=n.get("enableStrictSsl"),D=E.caFilePath,{default:b}=await Promise.resolve().then(r.t.bind(r,48722,7)),v=D?await async function(e){let t=l.get(e);return t||(t=A.xfs.readFilePromise(e).then(t=>(l.set(e,t),t)),l.set(e,t)),t}(D):void 0,S=b.extend({timeout:{socket:m},retry:w,https:{rejectUnauthorized:Q,certificateAuthority:v},...y});return n.getLimit("networkConcurrency")(()=>S(e))}async function I(e,{configuration:t,json:r,jsonResponse:A=r,...n}){let o=g.get(e);return o||(o=f(e,null,{configuration:t,...n}).then(t=>(g.set(e,t.body),t.body)),g.set(e,o)),!1===Buffer.isBuffer(o)&&(o=await o),A?JSON.parse(o.toString()):o}async function E(e,t,r){return(await f(e,t,{...r,method:C.PUT})).body}async function B(e,t,r){return(await f(e,t,{...r,method:C.POST})).body}async function y(e,t){return(await f(e,null,{...t,method:C.DELETE})).body}!function(e){e.GET="GET",e.PUT="PUT",e.POST="POST",e.DELETE="DELETE"}(C||(C={}))},53836:(e,t,r)=>{"use strict";r.r(t),r.d(t,{Cache:()=>p.C,DEFAULT_RC_FILENAME:()=>d.tr,DEFAULT_LOCK_FILENAME:()=>d.nh,Configuration:()=>d.VK,FormatType:()=>d.a5,ProjectLookup:()=>d.EW,SettingsType:()=>d.a2,BuildType:()=>C.k,LightReport:()=>f.h,Manifest:()=>I.G,MessageName:()=>E.b,Project:()=>B.I,TAG_REGEXP:()=>y.c,ReportError:()=>m.lk,Report:()=>m.yG,StreamReport:()=>w.Pk,TelemetryManager:()=>Q.E,ThrowReport:()=>D.$,VirtualFetcher:()=>b.N,WorkspaceResolver:()=>v.d,Workspace:()=>S.j,YarnVersion:()=>k.o,LinkType:()=>N.Un,PackageExtensionType:()=>N.HN,PackageExtensionStatus:()=>N._u,hashUtils:()=>i,httpUtils:()=>s,execUtils:()=>A,folderUtils:()=>n,formatUtils:()=>o,miscUtils:()=>a,scriptUtils:()=>c,semverUtils:()=>g,structUtils:()=>l,tgzUtils:()=>u,treeUtils:()=>h});var A=r(6220),n=r(81111),o=r(71643),i=r(20624),s=r(79669),a=r(73632),c=r(63088),g=r(36545),l=r(54143),u=r(72785),h=r(85875),p=r(28148),d=r(39922),C=r(92409),f=r(62152),I=r(46611),E=r(92659),B=r(85824),y=r(52779),m=r(35691),w=r(15815),Q=r(81832),D=r(33720),b=r(60895),v=r(94538),S=r(17722),k=r(59355),N=r(32485)},73632:(e,t,r)=>{"use strict";r.r(t),r.d(t,{escapeRegExp:()=>a,overrideType:()=>c,assertNever:()=>g,validateEnum:()=>l,mapAndFilter:()=>u,mapAndFind:()=>p,isIndexableObject:()=>C,convertMapsToIndexableObjects:()=>f,getFactoryWithDefault:()=>I,getArrayWithDefault:()=>E,getSetWithDefault:()=>B,getMapWithDefault:()=>y,releaseAfterUseAsync:()=>m,prettifyAsyncErrors:()=>w,prettifySyncErrors:()=>Q,bufferStream:()=>D,BufferStream:()=>b,DefaultStream:()=>v,dynamicRequire:()=>S,dynamicRequireNoCache:()=>k,sortMap:()=>N,buildIgnorePattern:()=>F,replaceEnvVariables:()=>K,parseBoolean:()=>M,parseOptionalBoolean:()=>R,tryParseOptionalBoolean:()=>x});var A=r(46009),n=r(40822),o=r(2401),i=r.n(o),s=r(92413);function a(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function c(e){}function g(e){throw new Error(`Assertion failed: Unexpected object '${e}'`)}function l(e,t){if(!Object.values(e).includes(t))throw new Error("Assertion failed: Invalid value for enumeration");return t}function u(e,t){const r=[];for(const A of e){const e=t(A);e!==h&&r.push(e)}return r}e=r.hmd(e);const h=Symbol();function p(e,t){for(const r of e){const e=t(r);if(e!==d)return e}}u.skip=h;const d=Symbol();function C(e){return"object"==typeof e&&null!==e}function f(e){if(e instanceof Map&&(e=Object.fromEntries(e)),C(e))for(const t of Object.keys(e)){const r=e[t];C(r)&&(e[t]=f(r))}return e}function I(e,t,r){let A=e.get(t);return void 0===A&&e.set(t,A=r()),A}function E(e,t){let r=e.get(t);return void 0===r&&e.set(t,r=[]),r}function B(e,t){let r=e.get(t);return void 0===r&&e.set(t,r=new Set),r}function y(e,t){let r=e.get(t);return void 0===r&&e.set(t,r=new Map),r}async function m(e,t){if(null==t)return await e();try{return await e()}finally{await t()}}async function w(e,t){try{return await e()}catch(e){throw e.message=t(e.message),e}}function Q(e,t){try{return e()}catch(e){throw e.message=t(e.message),e}}async function D(e){return await new Promise((t,r)=>{const A=[];e.on("error",e=>{r(e)}),e.on("data",e=>{A.push(e)}),e.on("end",()=>{t(Buffer.concat(A))})})}p.skip=d;class b extends s.Transform{constructor(){super(...arguments),this.chunks=[]}_transform(e,t,r){if("buffer"!==t||!Buffer.isBuffer(e))throw new Error("Assertion failed: BufferStream only accept buffers");this.chunks.push(e),r(null,null)}_flush(e){e(null,Buffer.concat(this.chunks))}}class v extends s.Transform{constructor(e=Buffer.alloc(0)){super(),this.active=!0,this.ifEmpty=e}_transform(e,t,r){if("buffer"!==t||!Buffer.isBuffer(e))throw new Error("Assertion failed: DefaultStream only accept buffers");this.active=!1,r(null,e)}_flush(e){this.active&&this.ifEmpty.length>0&&e(null,this.ifEmpty)}}function S(e){return"undefined"!=typeof require?require(e):r(32178)(e)}function k(t){const n=A.cS.fromPortablePath(t),o=r.c[n];let i;delete r.c[n];try{i=S(n);const t=r.c[n],A=e.children.indexOf(t);-1!==A&&e.children.splice(A,1)}finally{r.c[n]=o}return i}function N(e,t){const r=Array.from(e);Array.isArray(t)||(t=[t]);const A=[];for(const e of t)A.push(r.map(t=>e(t)));const n=r.map((e,t)=>t);return n.sort((e,t)=>{for(const r of A){const A=r[e]r[t]?1:0;if(0!==A)return A}return 0}),n.map(e=>r[e])}function F(e){return 0===e.length?null:e.map(e=>`(${i().makeRe(e,{windows:!1}).source})`).join("|")}function K(e,{env:t}){return e.replace(/\${(?[\d\w_]+)(?:)?(?:-(?[^}]*))?}/g,(...e)=>{const{variableName:r,colon:A,fallback:o}=e[e.length-1],i=Object.prototype.hasOwnProperty.call(t,r),s=t[r];if(s)return s;if(i&&!A)return s;if(null!=o)return o;throw new n.UsageError(`Environment variable not found (${r})`)})}function M(e){switch(e){case"true":case"1":case 1:case!0:return!0;case"false":case"0":case 0:case!1:return!1;default:throw new Error(`Couldn't parse "${e}" as a boolean`)}}function R(e){return void 0===e?e:M(e)}function x(e){try{return R(e)}catch(e){return null}}},63088:(e,t,r)=>{"use strict";r.r(t),r.d(t,{makeScriptEnv:()=>b,prepareExternalProject:()=>S,hasPackageScript:()=>k,executePackageScript:()=>N,executePackageShellcode:()=>F,executeWorkspaceScript:()=>M,hasWorkspaceScript:()=>R,executeWorkspaceLifecycleScript:()=>x,maybeExecuteWorkspaceLifecycleScript:()=>L,getPackageAccessibleBinaries:()=>P,getWorkspaceAccessibleBinaries:()=>O,executePackageAccessibleBinary:()=>U,executeWorkspaceAccessibleBinary:()=>T});var A,n=r(46009),o=r(53660),i=r(75448),s=r(43896),a=r(65281),c=r(76756),g=r(50730),l=r(61814),u=r.n(l),h=r(61578),p=r.n(h),d=r(92413),C=r(46611),f=r(92659),I=r(35691),E=r(15815),B=r(59355),y=r(6220),m=r(71643),w=r(73632),Q=r(54143);async function D(e,t,r,A=[]){"win32"===process.platform&&await Promise.all([s.xfs.writeFilePromise(n.y1.format({dir:e,name:t,ext:".exe"}),(0,g.O9)()),s.xfs.writeFilePromise(n.y1.format({dir:e,name:t,ext:".exe.info"}),[r,...A].join("\n")),s.xfs.writeFilePromise(n.y1.format({dir:e,name:t,ext:".cmd"}),`@"${r}" ${A.map(e=>`"${e.replace('"','""')}"`).join(" ")} %*\n`)]),await s.xfs.writeFilePromise(n.y1.join(e,t),`#!/bin/sh\nexec "${r}" ${A.map(e=>`'${e.replace(/'/g,"'\"'\"'")}'`).join(" ")} "$@"\n`),await s.xfs.chmodPromise(n.y1.join(e,t),493)}async function b({project:e,binFolder:t,lifecycleScript:r}){const A={};for(const[e,t]of Object.entries(process.env))void 0!==t&&(A["path"!==e.toLowerCase()?e:"PATH"]=t);const o=n.cS.fromPortablePath(t);A.BERRY_BIN_FOLDER=n.cS.fromPortablePath(o),await D(t,"node",process.execPath),null!==B.o&&(await D(t,"run",process.execPath,[process.argv[1],"run"]),await D(t,"yarn",process.execPath,[process.argv[1]]),await D(t,"yarnpkg",process.execPath,[process.argv[1]]),await D(t,"node-gyp",process.execPath,[process.argv[1],"run","--top-level","node-gyp"])),e&&(A.INIT_CWD=n.cS.fromPortablePath(e.configuration.startingCwd)),A.PATH=A.PATH?`${o}${n.cS.delimiter}${A.PATH}`:""+o,A.npm_execpath=`${o}${n.cS.sep}yarn`,A.npm_node_execpath=`${o}${n.cS.sep}node`;const i=null!==B.o?"yarn/"+B.o:`yarn/${w.dynamicRequire("@yarnpkg/core").version}-core`;return A.npm_config_user_agent=`${i} npm/? node/${process.versions.node} ${process.platform} ${process.arch}`,r&&(A.npm_lifecycle_event=r),e&&await e.configuration.triggerHook(e=>e.setupScriptEnvironment,e,A,async(e,r,A)=>await D(t,(0,n.Zu)(e),r,A)),A}!function(e){e.Yarn1="Yarn Classic",e.Yarn2="Yarn",e.Npm="npm",e.Pnpm="pnpm"}(A||(A={}));const v=p()(2);async function S(e,t,{configuration:r,report:o,workspace:i=null}){await v(async()=>{await s.xfs.mktempPromise(async a=>{const c=n.y1.join(a,"pack.log"),{stdout:g,stderr:l}=r.getSubprocessStreams(c,{prefix:e,report:o}),u=await async function(e){let t=null;try{t=await s.xfs.readFilePromise(n.y1.join(e,n.QS.lockfile),"utf8")}catch(e){}return null!==t?t.match(/^__metadata:$/m)?A.Yarn2:A.Yarn1:s.xfs.existsSync(n.y1.join(e,"package-lock.json"))?A.Npm:s.xfs.existsSync(n.y1.join(e,"pnpm-lock.yaml"))?A.Pnpm:null}(e);let h;null!==u?(g.write(`Installing the project using ${u}\n\n`),h=u):(g.write("No package manager detected; defaulting to Yarn\n\n"),h=A.Yarn2),await s.xfs.mktempPromise(async r=>{const o=await b({binFolder:r}),u=new Map([[A.Yarn1,async()=>{const r=null!==i?["workspace",i]:[],A=await y.pipevp("yarn",["set","version","classic","--only-if-needed"],{cwd:e,env:o,stdin:null,stdout:g,stderr:l,end:y.EndStrategy.ErrorCode});if(0!==A.code)return A.code;await s.xfs.appendFilePromise(n.y1.join(e,".npmignore"),"/.yarn\n"),g.write("\n");const a=await y.pipevp("yarn",["install"],{cwd:e,env:o,stdin:null,stdout:g,stderr:l,end:y.EndStrategy.ErrorCode});if(0!==a.code)return a.code;g.write("\n");const c=await y.pipevp("yarn",[...r,"pack","--filename",n.cS.fromPortablePath(t)],{cwd:e,env:o,stdin:null,stdout:g,stderr:l});return 0!==c.code?c.code:0}],[A.Yarn2,async()=>{const r=null!==i?["workspace",i]:[];o.YARN_ENABLE_INLINE_BUILDS="1";const A=n.y1.join(e,n.QS.lockfile);await s.xfs.existsPromise(A)||await s.xfs.writeFilePromise(A,"");const a=await y.pipevp("yarn",[...r,"pack","--install-if-needed","--filename",n.cS.fromPortablePath(t)],{cwd:e,env:o,stdin:null,stdout:g,stderr:l});return 0!==a.code?a.code:0}],[A.Npm,async()=>{if(null!==i)throw new Error("Workspaces aren't supported by npm, which has been detected as the primary package manager for "+e);delete o.npm_config_user_agent;const r=await y.pipevp("npm",["install"],{cwd:e,env:o,stdin:null,stdout:g,stderr:l,end:y.EndStrategy.ErrorCode});if(0!==r.code)return r.code;const A=new d.PassThrough,a=w.bufferStream(A);A.pipe(g);const c=await y.pipevp("npm",["pack","--silent"],{cwd:e,env:o,stdin:null,stdout:A,stderr:l});if(0!==c.code)return c.code;const u=(await a).toString().trim(),h=n.y1.resolve(e,n.cS.toPortablePath(u));return await s.xfs.renamePromise(h,t),0}]]).get(h);if(void 0===u)throw new Error("Assertion failed: Unsupported workflow");const p=await u();if(0!==p&&void 0!==p)throw s.xfs.detachTemp(a),new I.lk(f.b.PACKAGE_PREPARATION_FAILED,`Packing the package failed (exit code ${p}, logs can be found here: ${c})`)})})})}async function k(e,t,{project:r}){const A=r.storedPackages.get(e.locatorHash);if(!A)throw new Error(`Package for ${Q.prettyLocator(r.configuration,e)} not found in the project`);return await o.A.openPromise(async e=>{const o=r.configuration,s=r.configuration.getLinkers(),a={project:r,report:new E.Pk({stdout:new d.PassThrough,configuration:o})},c=s.find(e=>e.supportsPackage(A,a));if(!c)throw new Error(`The package ${Q.prettyLocator(r.configuration,A)} isn't supported by any of the available linkers`);const g=await c.findPackageLocation(A,a),l=new i.M(g,{baseFs:e});return(await C.G.find(n.LZ.dot,{baseFs:l})).scripts.has(t)},{libzip:await(0,a.getLibzipPromise)()})}async function N(e,t,r,{cwd:A,project:n,stdin:o,stdout:i,stderr:a}){return await s.xfs.mktempPromise(async s=>{const{manifest:g,env:l,cwd:u}=await K(e,{project:n,binFolder:s,cwd:A,lifecycleScript:t}),h=g.scripts.get(t);if(void 0===h)return 1;const p=await n.configuration.reduceHook(e=>e.wrapScriptExecution,async()=>await(0,c.execute)(h,r,{cwd:u,env:l,stdin:o,stdout:i,stderr:a}),n,e,t,{script:h,args:r,cwd:u,env:l,stdin:o,stdout:i,stderr:a});return await p()})}async function F(e,t,r,{cwd:A,project:n,stdin:o,stdout:i,stderr:a}){return await s.xfs.mktempPromise(async s=>{const{env:g,cwd:l}=await K(e,{project:n,binFolder:s,cwd:A});return await(0,c.execute)(t,r,{cwd:l,env:g,stdin:o,stdout:i,stderr:a})})}async function K(e,{project:t,binFolder:r,cwd:A,lifecycleScript:s}){const c=t.storedPackages.get(e.locatorHash);if(!c)throw new Error(`Package for ${Q.prettyLocator(t.configuration,e)} not found in the project`);return await o.A.openPromise(async o=>{const a=t.configuration,g=t.configuration.getLinkers(),l={project:t,report:new E.Pk({stdout:new d.PassThrough,configuration:a})},u=g.find(e=>e.supportsPackage(c,l));if(!u)throw new Error(`The package ${Q.prettyLocator(t.configuration,c)} isn't supported by any of the available linkers`);const h=await b({project:t,binFolder:r,lifecycleScript:s});await Promise.all(Array.from(await P(e,{project:t}),([e,[,t]])=>D(r,(0,n.Zu)(e),process.execPath,[t])));const p=await u.findPackageLocation(c,l),f=new i.M(p,{baseFs:o}),I=await C.G.find(n.LZ.dot,{baseFs:f});return void 0===A&&(A=p),{manifest:I,binFolder:r,env:h,cwd:A}},{libzip:await(0,a.getLibzipPromise)()})}async function M(e,t,r,{cwd:A,stdin:n,stdout:o,stderr:i}){return await N(e.anchoredLocator,t,r,{cwd:A,project:e.project,stdin:n,stdout:o,stderr:i})}function R(e,t){return e.manifest.scripts.has(t)}async function x(e,t,{cwd:r,report:A}){const{configuration:o}=e.project;await s.xfs.mktempPromise(async i=>{const a=n.y1.join(i,t+".log"),c=`# This file contains the result of Yarn calling the "${t}" lifecycle script inside a workspace ("${e.cwd}")\n`,{stdout:g,stderr:l}=o.getSubprocessStreams(a,{report:A,prefix:Q.prettyLocator(o,e.anchoredLocator),header:c});A.reportInfo(f.b.LIFECYCLE_SCRIPT,`Calling the "${t}" lifecycle script`);const h=await M(e,t,[],{cwd:r,stdin:null,stdout:g,stderr:l});if(g.end(),l.end(),0!==h)throw s.xfs.detachTemp(i),new I.lk(f.b.LIFECYCLE_SCRIPT,`${u()(t)} script failed (exit code ${m.pretty(o,h,m.Type.NUMBER)}, logs can be found here: ${m.pretty(o,a,m.Type.PATH)}); run ${m.pretty(o,"yarn "+t,m.Type.CODE)} to investigate`)})}async function L(e,t,r){R(e,t)&&await x(e,t,r)}async function P(e,{project:t}){const r=t.configuration,A=new Map,o=t.storedPackages.get(e.locatorHash);if(!o)throw new Error(`Package for ${Q.prettyLocator(r,e)} not found in the project`);const i=new d.Writable,s=r.getLinkers(),a={project:t,report:new E.Pk({configuration:r,stdout:i})},c=new Set([e.locatorHash]);for(const e of o.dependencies.values()){const A=t.storedResolutions.get(e.descriptorHash);if(!A)throw new Error(`Assertion failed: The resolution (${Q.prettyDescriptor(r,e)}) should have been registered`);c.add(A)}for(const e of c){const r=t.storedPackages.get(e);if(!r)throw new Error(`Assertion failed: The package (${e}) should have been registered`);if(0===r.bin.size)continue;const o=s.find(e=>e.supportsPackage(r,a));if(!o)continue;let i=null;try{i=await o.findPackageLocation(r,a)}catch(e){if("LOCATOR_NOT_INSTALLED"===e.code)continue;throw e}for(const[e,t]of r.bin)A.set(e,[r,n.cS.fromPortablePath(n.y1.resolve(i,t))])}return A}async function O(e){return await P(e.anchoredLocator,{project:e.project})}async function U(e,t,r,{cwd:A,project:o,stdin:i,stdout:a,stderr:c,nodeArgs:g=[]}){const l=await P(e,{project:o}),u=l.get(t);if(!u)throw new Error(`Binary not found (${t}) for ${Q.prettyLocator(o.configuration,e)}`);return await s.xfs.mktempPromise(async e=>{const[,t]=u,h=await b({project:o,binFolder:e});let p;await Promise.all(Array.from(l,([e,[,t]])=>D(h.BERRY_BIN_FOLDER,(0,n.Zu)(e),process.execPath,[t])));try{p=await y.pipevp(process.execPath,[...g,t,...r],{cwd:A,env:h,stdin:i,stdout:a,stderr:c})}finally{await s.xfs.removePromise(h.BERRY_BIN_FOLDER)}return p.code})}async function T(e,t,r,{cwd:A,stdin:n,stdout:o,stderr:i}){return await U(e.anchoredLocator,t,r,{project:e.project,cwd:A,stdin:n,stdout:o,stderr:i})}},36545:(e,t,r)=>{"use strict";r.r(t),r.d(t,{satisfiesWithPrereleases:()=>o,validRange:()=>s});var A=r(53887),n=r.n(A);function o(e,t,r=!1){let A,o;try{A=new(n().Range)(t,{includePrerelease:!0,loose:r})}catch(e){return!1}if(!e)return!1;try{o=new(n().SemVer)(e,A),o.prerelease&&(o.prerelease=[])}catch(e){return!1}return A.set.some(e=>{for(const t of e)t.semver.prerelease&&(t.semver.prerelease=[]);return e.every(e=>e.test(o))})}const i=new Map;function s(e){if(-1!==e.indexOf(":"))return null;let t=i.get(e);if(void 0!==t)return t;try{t=new(n().Range)(e)}catch(e){t=null}return i.set(e,t),t}},54143:(e,t,r)=>{"use strict";r.r(t),r.d(t,{makeIdent:()=>u,makeDescriptor:()=>h,makeLocator:()=>p,convertToIdent:()=>d,convertDescriptorToLocator:()=>C,convertLocatorToDescriptor:()=>f,convertPackageToLocator:()=>I,renamePackage:()=>E,copyPackage:()=>B,virtualizeDescriptor:()=>y,virtualizePackage:()=>m,isVirtualDescriptor:()=>w,isVirtualLocator:()=>Q,devirtualizeDescriptor:()=>D,devirtualizeLocator:()=>b,bindDescriptor:()=>v,bindLocator:()=>S,areIdentsEqual:()=>k,areDescriptorsEqual:()=>N,areLocatorsEqual:()=>F,areVirtualPackagesEquivalent:()=>K,parseIdent:()=>M,tryParseIdent:()=>R,parseDescriptor:()=>x,tryParseDescriptor:()=>L,parseLocator:()=>P,tryParseLocator:()=>O,parseRange:()=>U,parseFileStyleRange:()=>T,makeRange:()=>Y,convertToManifestRange:()=>G,requirableIdent:()=>H,stringifyIdent:()=>J,stringifyDescriptor:()=>q,stringifyLocator:()=>z,slugifyIdent:()=>W,slugifyLocator:()=>V,prettyIdent:()=>X,prettyRange:()=>Z,prettyDescriptor:()=>$,prettyReference:()=>ee,prettyLocator:()=>te,prettyLocatorNoColors:()=>re,sortDescriptors:()=>Ae,prettyWorkspace:()=>ne,prettyResolution:()=>oe,prettyDependent:()=>ie,getIdentVendorPath:()=>se});var A=r(46009),n=r(71191),o=r.n(n),i=r(53887),s=r.n(i),a=r(71643),c=r(20624),g=r(73632),l=r(54143);function u(e,t){if(null==e?void 0:e.startsWith("@"))throw new Error("Invalid scope: don't prefix it with '@'");return{identHash:c.makeHash(e,t),scope:e,name:t}}function h(e,t){return{identHash:e.identHash,scope:e.scope,name:e.name,descriptorHash:c.makeHash(e.identHash,t),range:t}}function p(e,t){return{identHash:e.identHash,scope:e.scope,name:e.name,locatorHash:c.makeHash(e.identHash,t),reference:t}}function d(e){return{identHash:e.identHash,scope:e.scope,name:e.name}}function C(e){return{identHash:e.identHash,scope:e.scope,name:e.name,locatorHash:e.descriptorHash,reference:e.range}}function f(e){return{identHash:e.identHash,scope:e.scope,name:e.name,descriptorHash:e.locatorHash,range:e.reference}}function I(e){return{identHash:e.identHash,scope:e.scope,name:e.name,locatorHash:e.locatorHash,reference:e.reference}}function E(e,t){return{identHash:t.identHash,scope:t.scope,name:t.name,locatorHash:t.locatorHash,reference:t.reference,version:e.version,languageName:e.languageName,linkType:e.linkType,dependencies:new Map(e.dependencies),peerDependencies:new Map(e.peerDependencies),dependenciesMeta:new Map(e.dependenciesMeta),peerDependenciesMeta:new Map(e.peerDependenciesMeta),bin:new Map(e.bin)}}function B(e){return E(e,e)}function y(e,t){if(t.includes("#"))throw new Error("Invalid entropy");return h(e,`virtual:${t}#${e.range}`)}function m(e,t){if(t.includes("#"))throw new Error("Invalid entropy");return E(e,p(e,`virtual:${t}#${e.reference}`))}function w(e){return e.range.startsWith("virtual:")}function Q(e){return e.reference.startsWith("virtual:")}function D(e){if(!w(e))throw new Error("Not a virtual descriptor");return h(e,e.range.replace(/^[^#]*#/,""))}function b(e){if(!Q(e))throw new Error("Not a virtual descriptor");return p(e,e.reference.replace(/^[^#]*#/,""))}function v(e,t){return e.range.includes("::")?e:h(e,`${e.range}::${o().stringify(t)}`)}function S(e,t){return e.reference.includes("::")?e:p(e,`${e.reference}::${o().stringify(t)}`)}function k(e,t){return e.identHash===t.identHash}function N(e,t){return e.descriptorHash===t.descriptorHash}function F(e,t){return e.locatorHash===t.locatorHash}function K(e,t){if(!Q(e))throw new Error("Invalid package type");if(!Q(t))throw new Error("Invalid package type");if(!k(e,t))return!1;if(e.dependencies.size!==t.dependencies.size)return!1;for(const r of e.dependencies.values()){const e=t.dependencies.get(r.identHash);if(!e)return!1;if(!N(r,e))return!1}return!0}function M(e){const t=R(e);if(!t)throw new Error(`Invalid ident (${e})`);return t}function R(e){const t=e.match(/^(?:@([^/]+?)\/)?([^/]+)$/);if(!t)return null;const[,r,A]=t;return u(void 0!==r?r:null,A)}function x(e,t=!1){const r=L(e,t);if(!r)throw new Error(`Invalid descriptor (${e})`);return r}function L(e,t=!1){const r=t?e.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))$/):e.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))?$/);if(!r)return null;const[,A,n,o]=r;if("unknown"===o)throw new Error(`Invalid range (${e})`);const i=void 0!==o?o:"unknown";return h(u(void 0!==A?A:null,n),i)}function P(e,t=!1){const r=O(e,t);if(!r)throw new Error(`Invalid locator (${e})`);return r}function O(e,t=!1){const r=t?e.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))$/):e.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))?$/);if(!r)return null;const[,A,n,o]=r;if("unknown"===o)throw new Error(`Invalid reference (${e})`);const i=void 0!==o?o:"unknown";return p(u(void 0!==A?A:null,n),i)}function U(e,t){const r=e.match(/^([^#:]*:)?((?:(?!::)[^#])*)(?:#((?:(?!::).)*))?(?:::(.*))?$/);if(null===r)throw new Error(`Invalid range (${e})`);const A=void 0!==r[1]?r[1]:null;if("string"==typeof(null==t?void 0:t.requireProtocol)&&A!==t.requireProtocol)throw new Error(`Invalid protocol (${A})`);if((null==t?void 0:t.requireProtocol)&&null===A)throw new Error(`Missing protocol (${A})`);const n=void 0!==r[3]?decodeURIComponent(r[2]):null;if((null==t?void 0:t.requireSource)&&null===n)throw new Error(`Missing source (${e})`);const i=void 0!==r[3]?decodeURIComponent(r[3]):decodeURIComponent(r[2]);return{protocol:A,source:n,selector:(null==t?void 0:t.parseSelector)?o().parse(i):i,params:void 0!==r[4]?o().parse(r[4]):null}}function T(e,{protocol:t}){const{selector:r,params:A}=U(e,{requireProtocol:t,requireBindings:!0});if("string"!=typeof A.locator)throw new Error("Assertion failed: Invalid bindings for "+e);return{parentLocator:P(A.locator,!0),path:r}}function j(e){return e=(e=(e=e.replace(/%/g,"%25")).replace(/:/g,"%3A")).replace(/#/g,"%23")}function Y({protocol:e,source:t,selector:r,params:A}){let n="";return null!==e&&(n+=""+e),null!==t&&(n+=j(t)+"#"),n+=j(r),function(e){return null!==e&&Object.entries(e).length>0}(A)&&(n+="::"+o().stringify(A)),n}function G(e){const{params:t,protocol:r,source:A,selector:n}=U(e);for(const e in t)e.startsWith("__")&&delete t[e];return Y({protocol:r,source:A,params:t,selector:n})}function H(e){return e.scope?`@${e.scope}/${e.name}`:""+e.name}function J(e){return e.scope?`@${e.scope}/${e.name}`:""+e.name}function q(e){return e.scope?`@${e.scope}/${e.name}@${e.range}`:`${e.name}@${e.range}`}function z(e){return e.scope?`@${e.scope}/${e.name}@${e.reference}`:`${e.name}@${e.reference}`}function W(e){return null!==e.scope?`@${e.scope}-${e.name}`:e.name}function V(e){const{protocol:t,selector:r}=U(e.reference),n=null!==t?t.replace(/:$/,""):"exotic",o=s().valid(r),i=null!==o?`${n}-${o}`:""+n,a=(e.scope,`${W(e)}-${i}-${e.locatorHash.slice(0,10)}`);return(0,A.Zu)(a)}function X(e,t){return t.scope?`${a.pretty(e,`@${t.scope}/`,a.Type.SCOPE)}${a.pretty(e,t.name,a.Type.NAME)}`:""+a.pretty(e,t.name,a.Type.NAME)}function _(e){if(e.startsWith("virtual:")){return`${_(e.substr(e.indexOf("#")+1))} [${e.substr("virtual:".length,5)}]`}return e.replace(/\?.*/,"?[...]")}function Z(e,t){return""+a.pretty(e,_(t),a.Type.RANGE)}function $(e,t){return`${X(e,t)}${a.pretty(e,"@",a.Type.RANGE)}${Z(e,t.range)}`}function ee(e,t){return""+a.pretty(e,_(t),a.Type.REFERENCE)}function te(e,t){return`${X(e,t)}${a.pretty(e,"@",a.Type.REFERENCE)}${ee(e,t.reference)}`}function re(e){return`${J(e)}@${_(e.reference)}`}function Ae(e){return g.sortMap(e,[e=>J(e),e=>e.range])}function ne(e,t){return X(e,t.locator)}function oe(e,t,r){const A=w(t)?D(t):t;return null===r?`${l.prettyDescriptor(e,A)} → ${a.mark(e).Cross}`:A.identHash===r.identHash?`${l.prettyDescriptor(e,A)} → ${ee(e,r.reference)}`:`${l.prettyDescriptor(e,A)} → ${te(e,r)}`}function ie(e,t,r){return null===r?""+te(e,t):`${te(e,t)} (via ${l.prettyRange(e,r.range)})`}function se(e){return"node_modules/"+H(e)}},72785:(e,t,r)=>{"use strict";r.r(t),r.d(t,{makeArchiveFromDirectory:()=>h,convertToZip:()=>p,extractArchiveTo:()=>d});var A=r(78420),n=r(46009),o=r(90739),i=r(43896),s=r(65281),a=r(59938),c=r(31669),g=r(78761),l=r.n(g);const u=(0,c.promisify)(l().gunzip);async function h(e,{baseFs:t=new A.S,prefixPath:r=n.LZ.root,compressionLevel:a,inMemory:c=!1}={}){const g=await(0,s.getLibzipPromise)();let l;if(c)l=new o.d(null,{libzip:g,level:a});else{const e=await i.xfs.mktempPromise(),t=n.y1.join(e,"archive.zip");l=new o.d(t,{create:!0,libzip:g,level:a})}const u=n.y1.resolve(n.LZ.root,r);return await l.copyPromise(u,e,{baseFs:t,stableTime:!0,stableSort:!0}),l}async function p(e,t){const r=await i.xfs.mktempPromise(),A=n.y1.join(r,"archive.zip"),{compressionLevel:a,...c}=t;return await d(e,new o.d(A,{create:!0,libzip:await(0,s.getLibzipPromise)(),level:a}),c)}async function d(e,t,{stripComponents:r=0,prefixPath:A=n.LZ.dot}={}){const o=a.extract();o.on("entry",(e,o,i)=>{var s,a;if(function(e){if("/"===e.name[0])return!0;const t=e.name.split(/\//g);return!!t.some(e=>".."===e)||t.length<=r}(e))return void i();const c=n.y1.normalize(n.cS.toPortablePath(e.name)).replace(/\/$/,"").split(/\//g);if(c.length<=r)return o.resume(),void i();const g=c.slice(r).join("/"),l=n.y1.join(A,g);let u=420;switch("directory"!==e.type&&0==(73&(null!==(s=e.mode)&&void 0!==s?s:0))||(u|=73),e.type){case"directory":t.mkdirpSync(n.y1.dirname(l),{chmod:493,utimes:[315532800,315532800]}),t.mkdirSync(l),t.chmodSync(l,u),t.utimesSync(l,315532800,315532800),i();break;case"file":{t.mkdirpSync(n.y1.dirname(l),{chmod:493,utimes:[315532800,315532800]});const e=[];o.on("data",t=>e.push(t)),o.on("end",()=>{t.writeFileSync(l,Buffer.concat(e)),t.chmodSync(l,u),t.utimesSync(l,315532800,315532800),i()})}break;case"symlink":t.mkdirpSync(n.y1.dirname(l),{chmod:493,utimes:[315532800,315532800]}),t.symlinkSync(e.linkname,l),null===(a=t.lutimesSync)||void 0===a||a.call(t,l,315532800,315532800),i();break;default:o.resume(),i()}});const i=await u(e);return await new Promise((e,r)=>{o.on("error",e=>{r(e)}),o.on("finish",()=>{e(t)}),o.end(i)})}},85875:(e,t,r)=>{"use strict";r.r(t),r.d(t,{treeNodeToTreeify:()=>o,treeNodeToJson:()=>i,emitList:()=>s,emitTree:()=>a});var A=r(94682),n=r(71643);function o(e,{configuration:t}){const r={},A=(e,r)=>{const o=Array.isArray(e)?e.entries():Object.entries(e);for(const[e,{label:i,value:s,children:a}]of o){const o=[];void 0!==i&&o.push(n.applyStyle(t,i,n.Style.BOLD)),void 0!==s&&o.push(n.pretty(t,s[0],s[1])),0===o.length&&o.push(n.applyStyle(t,""+e,n.Style.BOLD));const c=r[o.join(": ")]={};void 0!==a&&A(a,c)}};if(void 0===e.children)throw new Error("The root node must only contain children");return A(e.children,r),r}function i(e){const t=e=>{var r;if(void 0===e.children){if(void 0===e.value)throw new Error("Assertion failed: Expected a value to be set if the children are missing");return n.json(e.value[0],e.value[1])}const A=Array.isArray(e.children)?e.children.entries():Object.entries(null!==(r=e.children)&&void 0!==r?r:{}),o=Array.isArray(e.children)?[]:{};for(const[e,r]of A)o[e]=t(r);return void 0===e.value?o:{value:n.json(e.value[0],e.value[1]),children:o}};return t(e)}function s(e,{configuration:t,stdout:r,json:A}){a({children:e.map(e=>({value:e}))},{configuration:t,stdout:r,json:A})}function a(e,{configuration:t,stdout:r,json:n,separators:s=0}){var a;if(n){const t=Array.isArray(e.children)?e.children.values():Object.values(null!==(a=e.children)&&void 0!==a?a:{});for(const e of t)r.write(JSON.stringify(i(e))+"\n");return}let c=(0,A.asTree)(o(e,{configuration:t}),!1,!1);if(s>=1&&(c=c.replace(/^([├└]─)/gm,"│\n$1").replace(/^│\n/,"")),s>=2)for(let e=0;e<2;++e)c=c.replace(/^([│ ].{2}[├│ ].{2}[^\n]+\n)(([│ ]).{2}[├└].{2}[^\n]*\n[│ ].{2}[│ ].{2}[├└]─)/gm,"$1$3 │\n$2").replace(/^│\n/,"");if(s>=3)throw new Error("Only the first two levels are accepted by treeUtils.emitTree");r.write(c)}},32485:(e,t,r)=>{"use strict";var A,n,o;r.d(t,{Un:()=>A,HN:()=>n,_u:()=>o}),function(e){e.HARD="HARD",e.SOFT="SOFT"}(A||(A={})),function(e){e.Dependency="Dependency",e.PeerDependency="PeerDependency",e.PeerDependencyMeta="PeerDependencyMeta"}(n||(n={})),function(e){e.Inactive="inactive",e.Redundant="redundant",e.Active="active"}(o||(o={}))},14626:(e,t,r)=>{"use strict";r.d(t,{K:()=>n});var A=r(42096);class n extends A.p{constructor(e,{baseFs:t,pathUtils:r}){super(r),this.target=e,this.baseFs=t}getRealPath(){return this.target}getBaseFs(){return this.baseFs}mapFromBase(e){return e}mapToBase(e){return e}}},75448:(e,t,r)=>{"use strict";r.d(t,{M:()=>i});var A=r(78420),n=r(42096),o=r(46009);class i extends n.p{constructor(e,{baseFs:t=new A.S}={}){super(o.y1),this.target=this.pathUtils.normalize(e),this.baseFs=t}getRealPath(){return this.pathUtils.resolve(this.baseFs.getRealPath(),this.target)}resolve(e){return this.pathUtils.isAbsolute(e)?o.y1.normalize(e):this.baseFs.resolve(o.y1.join(this.target,e))}mapFromBase(e){return e}mapToBase(e){return this.pathUtils.isAbsolute(e)?e:this.pathUtils.join(this.target,e)}}},5944:(e,t,r)=>{"use strict";r.d(t,{fS:()=>g,uY:()=>c,qH:()=>l});var A=r(12087),n=r(35747),o=r.n(n),i=r(46009);const s=new Date(3155328e5);async function a(e,t,r,A,n,c,g,l){var u,h;const p=await async function(e,t){try{return await e.lstatPromise(t)}catch(e){return null}}(A,n),d=await c.lstatPromise(g),C=l.stableTime?{mtime:s,atime:s}:d;let f;switch(!0){case d.isDirectory():f=await async function(e,t,r,A,n,o,i,s,c,g){if(null!==o&&!o.isDirectory()){if(!g.overwrite)return!1;e.push(async()=>A.removePromise(n)),o=null}let l=!1;null===o&&(e.push(async()=>A.mkdirPromise(n,{mode:c.mode})),l=!0);const u=await i.readdirPromise(s);if(g.stableSort)for(const o of u.sort())await a(e,t,r,A,A.pathUtils.join(n,o),i,i.pathUtils.join(s,o),g)&&(l=!0);else{(await Promise.all(u.map(async o=>{await a(e,t,r,A,A.pathUtils.join(n,o),i,i.pathUtils.join(s,o),g)}))).some(e=>e)&&(l=!0)}return l}(e,t,r,A,n,p,c,g,d,l);break;case d.isFile():f=await async function(e,t,r,A,n,i,s,a,c,g){if(null!==i){if(!g.overwrite)return!1;e.push(async()=>A.removePromise(n)),i=null}const l=A===s?async()=>A.copyFilePromise(a,n,o().constants.COPYFILE_FICLONE):async()=>A.writeFilePromise(n,await s.readFilePromise(a));return e.push(async()=>l()),!0}(e,0,0,A,n,p,c,g,0,l);break;case d.isSymbolicLink():f=await async function(e,t,r,A,n,o,s,a,c,g){if(null!==o){if(!g.overwrite)return!1;e.push(async()=>A.removePromise(n)),o=null}return e.push(async()=>{await A.symlinkPromise((0,i.CI)(A.pathUtils,await s.readlinkPromise(a)),n)}),!0}(e,0,0,A,n,p,c,g,0,l);break;default:throw new Error(`Unsupported file type (${d.mode})`)}return(f||(null===(u=null==p?void 0:p.mtime)||void 0===u?void 0:u.getTime())!==C.mtime.getTime()||(null===(h=null==p?void 0:p.atime)||void 0===h?void 0:h.getTime())!==C.atime.getTime())&&(t.push(()=>r(n,C.atime,C.mtime)),f=!0),null!==p&&(511&p.mode)==(511&d.mode)||(t.push(()=>A.chmodPromise(n,511&d.mode)),f=!0),f}class c{constructor(e){this.pathUtils=e}async*genTraversePromise(e,{stableSort:t=!1}={}){const r=[e];for(;r.length>0;){const e=r.shift();if((await this.lstatPromise(e)).isDirectory()){const A=await this.readdirPromise(e);if(!t)throw new Error("Not supported");for(const t of A.sort())r.push(this.pathUtils.join(e,t))}else yield e}}async removePromise(e,{recursive:t=!0,maxRetries:r=5}={}){let A;try{A=await this.lstatPromise(e)}catch(e){if("ENOENT"===e.code)return;throw e}if(A.isDirectory()){if(t)for(const t of await this.readdirPromise(e))await this.removePromise(this.pathUtils.resolve(e,t));let A=0;do{try{await this.rmdirPromise(e);break}catch(e){if("EBUSY"===e.code||"ENOTEMPTY"===e.code){if(0===r)break;await new Promise(e=>setTimeout(e,100*A));continue}throw e}}while(A++e()))}(this,e,r,t,{overwrite:A,stableSort:n,stableTime:o})}copySync(e,t,{baseFs:r=this,overwrite:A=!0}={}){const n=r.lstatSync(t),o=this.existsSync(e);if(n.isDirectory()){this.mkdirpSync(e);const n=r.readdirSync(t);for(const o of n)this.copySync(this.pathUtils.join(e,o),r.pathUtils.join(t,o),{baseFs:r,overwrite:A})}else if(n.isFile()){if(!o||A){o&&this.removeSync(e);const A=r.readFileSync(t);this.writeFileSync(e,A)}}else{if(!n.isSymbolicLink())throw new Error(`Unsupported file type (file: ${t}, mode: 0o${n.mode.toString(8).padStart(6,"0")})`);if(!o||A){o&&this.removeSync(e);const A=r.readlinkSync(t);this.symlinkSync((0,i.CI)(this.pathUtils,A),e)}}const s=511&n.mode;this.chmodSync(e,s)}async changeFilePromise(e,t,r={}){return Buffer.isBuffer(t)?this.changeFileBufferPromise(e,t):this.changeFileTextPromise(e,t,r)}async changeFileBufferPromise(e,t){let r=Buffer.alloc(0);try{r=await this.readFilePromise(e)}catch(e){}0!==Buffer.compare(r,t)&&await this.writeFilePromise(e,t)}async changeFileTextPromise(e,t,{automaticNewlines:r}={}){let A="";try{A=await this.readFilePromise(e,"utf8")}catch(e){}const n=r?l(A,t):t;A!==n&&await this.writeFilePromise(e,n)}changeFileSync(e,t,r={}){return Buffer.isBuffer(t)?this.changeFileBufferSync(e,t):this.changeFileTextSync(e,t,r)}changeFileBufferSync(e,t){let r=Buffer.alloc(0);try{r=this.readFileSync(e)}catch(e){}0!==Buffer.compare(r,t)&&this.writeFileSync(e,t)}changeFileTextSync(e,t,{automaticNewlines:r=!1}={}){let A="";try{A=this.readFileSync(e,"utf8")}catch(e){}const n=r?l(A,t):t;A!==n&&this.writeFileSync(e,n)}async movePromise(e,t){try{await this.renamePromise(e,t)}catch(r){if("EXDEV"!==r.code)throw r;await this.copyPromise(t,e),await this.removePromise(e)}}moveSync(e,t){try{this.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;this.copySync(t,e),this.removeSync(e)}}async lockPromise(e,t){const r=e+".flock",A=Date.now();let n=null;const o=async()=>{let e;try{[e]=await this.readJsonPromise(r)}catch(e){return Date.now()-A<500}try{return process.kill(e,0),!0}catch(e){return!1}};for(;null===n;)try{n=await this.openPromise(r,"wx")}catch(e){if("EEXIST"!==e.code)throw e;if(!await o())try{await this.unlinkPromise(r);continue}catch(e){}if(!(Date.now()-A<6e4))throw new Error(`Couldn't acquire a lock in a reasonable time (via ${r})`);await new Promise(e=>setTimeout(e,1e3/60))}await this.writePromise(n,JSON.stringify([process.pid]));try{return await t()}finally{try{await this.closePromise(n),await this.unlinkPromise(r)}catch(e){}}}async readJsonPromise(e){const t=await this.readFilePromise(e,"utf8");try{return JSON.parse(t)}catch(t){throw t.message+=` (in ${e})`,t}}readJsonSync(e){const t=this.readFileSync(e,"utf8");try{return JSON.parse(t)}catch(t){throw t.message+=` (in ${e})`,t}}async writeJsonPromise(e,t){return await this.writeFilePromise(e,JSON.stringify(t,null,2)+"\n")}writeJsonSync(e,t){return this.writeFileSync(e,JSON.stringify(t,null,2)+"\n")}async preserveTimePromise(e,t){const r=await this.lstatPromise(e),A=await t();void 0!==A&&(e=A),this.lutimesPromise?await this.lutimesPromise(e,r.atime,r.mtime):r.isSymbolicLink()||await this.utimesPromise(e,r.atime,r.mtime)}async preserveTimeSync(e,t){const r=this.lstatSync(e),A=t();void 0!==A&&(e=A),this.lutimesSync?this.lutimesSync(e,r.atime,r.mtime):r.isSymbolicLink()||this.utimesSync(e,r.atime,r.mtime)}}c.DEFAULT_TIME=315532800;class g extends c{constructor(){super(i.y1)}}function l(e,t){return t.replace(/\r?\n/g,function(e){const t=e.match(/\r?\n/g);if(null===t)return A.EOL;const r=t.filter(e=>"\r\n"===e).length;return r>t.length-r?"\r\n":"\n"}(e))}},10489:(e,t,r)=>{"use strict";r.d(t,{n:()=>s});var A=r(78420),n=r(42096),o=r(46009);const i=o.LZ.root;class s extends n.p{constructor(e,{baseFs:t=new A.S}={}){super(o.y1),this.target=this.pathUtils.resolve(o.LZ.root,e),this.baseFs=t}getRealPath(){return this.pathUtils.resolve(this.baseFs.getRealPath(),this.pathUtils.relative(o.LZ.root,this.target))}getTarget(){return this.target}getBaseFs(){return this.baseFs}mapToBase(e){const t=this.pathUtils.normalize(e);if(this.pathUtils.isAbsolute(e))return this.pathUtils.resolve(this.target,this.pathUtils.relative(i,e));if(t.match(/^\.\.\/?/))throw new Error(`Resolving this path (${e}) would escape the jail`);return this.pathUtils.resolve(this.target,e)}mapFromBase(e){return this.pathUtils.resolve(i,this.pathUtils.relative(this.target,e))}}},15037:(e,t,r)=>{"use strict";r.d(t,{v:()=>n});var A=r(42096);class n extends A.p{constructor(e,t){super(t),this.instance=null,this.factory=e}get baseFs(){return this.instance||(this.instance=this.factory()),this.instance}set baseFs(e){this.instance=e}mapFromBase(e){return e}mapToBase(e){return e}}},78420:(e,t,r)=>{"use strict";r.d(t,{S:()=>a});var A=r(35747),n=r.n(A),o=r(5944),i=r(26984),s=r(46009);class a extends o.fS{constructor(e=n()){super(),this.realFs=e,void 0!==this.realFs.lutimes&&(this.lutimesPromise=this.lutimesPromiseImpl,this.lutimesSync=this.lutimesSyncImpl)}getExtractHint(){return!1}getRealPath(){return s.LZ.root}resolve(e){return s.y1.resolve(e)}async openPromise(e,t,r){return await new Promise((A,n)=>{this.realFs.open(s.cS.fromPortablePath(e),t,r,this.makeCallback(A,n))})}openSync(e,t,r){return this.realFs.openSync(s.cS.fromPortablePath(e),t,r)}async opendirPromise(e,t){return await new Promise((r,A)=>{void 0!==t?this.realFs.opendir(s.cS.fromPortablePath(e),t,this.makeCallback(r,A)):this.realFs.opendir(s.cS.fromPortablePath(e),this.makeCallback(r,A))}).then(t=>Object.defineProperty(t,"path",{value:e,configurable:!0,writable:!0}))}opendirSync(e,t){const r=void 0!==t?this.realFs.opendirSync(s.cS.fromPortablePath(e),t):this.realFs.opendirSync(s.cS.fromPortablePath(e));return Object.defineProperty(r,"path",{value:e,configurable:!0,writable:!0})}async readPromise(e,t,r=0,A=0,n=-1){return await new Promise((o,i)=>{this.realFs.read(e,t,r,A,n,(e,t)=>{e?i(e):o(t)})})}readSync(e,t,r,A,n){return this.realFs.readSync(e,t,r,A,n)}async writePromise(e,t,r,A,n){return await new Promise((o,i)=>"string"==typeof t?this.realFs.write(e,t,r,this.makeCallback(o,i)):this.realFs.write(e,t,r,A,n,this.makeCallback(o,i)))}writeSync(e,t,r,A,n){return"string"==typeof t?this.realFs.writeSync(e,t,r):this.realFs.writeSync(e,t,r,A,n)}async closePromise(e){await new Promise((t,r)=>{this.realFs.close(e,this.makeCallback(t,r))})}closeSync(e){this.realFs.closeSync(e)}createReadStream(e,t){const r=null!==e?s.cS.fromPortablePath(e):e;return this.realFs.createReadStream(r,t)}createWriteStream(e,t){const r=null!==e?s.cS.fromPortablePath(e):e;return this.realFs.createWriteStream(r,t)}async realpathPromise(e){return await new Promise((t,r)=>{this.realFs.realpath(s.cS.fromPortablePath(e),{},this.makeCallback(t,r))}).then(e=>s.cS.toPortablePath(e))}realpathSync(e){return s.cS.toPortablePath(this.realFs.realpathSync(s.cS.fromPortablePath(e),{}))}async existsPromise(e){return await new Promise(t=>{this.realFs.exists(s.cS.fromPortablePath(e),t)})}accessSync(e,t){return this.realFs.accessSync(s.cS.fromPortablePath(e),t)}async accessPromise(e,t){return await new Promise((r,A)=>{this.realFs.access(s.cS.fromPortablePath(e),t,this.makeCallback(r,A))})}existsSync(e){return this.realFs.existsSync(s.cS.fromPortablePath(e))}async statPromise(e){return await new Promise((t,r)=>{this.realFs.stat(s.cS.fromPortablePath(e),this.makeCallback(t,r))})}statSync(e){return this.realFs.statSync(s.cS.fromPortablePath(e))}async lstatPromise(e){return await new Promise((t,r)=>{this.realFs.lstat(s.cS.fromPortablePath(e),this.makeCallback(t,r))})}lstatSync(e){return this.realFs.lstatSync(s.cS.fromPortablePath(e))}async chmodPromise(e,t){return await new Promise((r,A)=>{this.realFs.chmod(s.cS.fromPortablePath(e),t,this.makeCallback(r,A))})}chmodSync(e,t){return this.realFs.chmodSync(s.cS.fromPortablePath(e),t)}async chownPromise(e,t,r){return await new Promise((A,n)=>{this.realFs.chown(s.cS.fromPortablePath(e),t,r,this.makeCallback(A,n))})}chownSync(e,t,r){return this.realFs.chownSync(s.cS.fromPortablePath(e),t,r)}async renamePromise(e,t){return await new Promise((r,A)=>{this.realFs.rename(s.cS.fromPortablePath(e),s.cS.fromPortablePath(t),this.makeCallback(r,A))})}renameSync(e,t){return this.realFs.renameSync(s.cS.fromPortablePath(e),s.cS.fromPortablePath(t))}async copyFilePromise(e,t,r=0){return await new Promise((A,n)=>{this.realFs.copyFile(s.cS.fromPortablePath(e),s.cS.fromPortablePath(t),r,this.makeCallback(A,n))})}copyFileSync(e,t,r=0){return this.realFs.copyFileSync(s.cS.fromPortablePath(e),s.cS.fromPortablePath(t),r)}async appendFilePromise(e,t,r){return await new Promise((A,n)=>{const o="string"==typeof e?s.cS.fromPortablePath(e):e;r?this.realFs.appendFile(o,t,r,this.makeCallback(A,n)):this.realFs.appendFile(o,t,this.makeCallback(A,n))})}appendFileSync(e,t,r){const A="string"==typeof e?s.cS.fromPortablePath(e):e;r?this.realFs.appendFileSync(A,t,r):this.realFs.appendFileSync(A,t)}async writeFilePromise(e,t,r){return await new Promise((A,n)=>{const o="string"==typeof e?s.cS.fromPortablePath(e):e;r?this.realFs.writeFile(o,t,r,this.makeCallback(A,n)):this.realFs.writeFile(o,t,this.makeCallback(A,n))})}writeFileSync(e,t,r){const A="string"==typeof e?s.cS.fromPortablePath(e):e;r?this.realFs.writeFileSync(A,t,r):this.realFs.writeFileSync(A,t)}async unlinkPromise(e){return await new Promise((t,r)=>{this.realFs.unlink(s.cS.fromPortablePath(e),this.makeCallback(t,r))})}unlinkSync(e){return this.realFs.unlinkSync(s.cS.fromPortablePath(e))}async utimesPromise(e,t,r){return await new Promise((A,n)=>{this.realFs.utimes(s.cS.fromPortablePath(e),t,r,this.makeCallback(A,n))})}utimesSync(e,t,r){this.realFs.utimesSync(s.cS.fromPortablePath(e),t,r)}async lutimesPromiseImpl(e,t,r){const A=this.realFs.lutimes;if(void 0===A)throw(0,i.bk)("unavailable Node binding",`lutimes '${e}'`);return await new Promise((n,o)=>{A.call(this.realFs,s.cS.fromPortablePath(e),t,r,this.makeCallback(n,o))})}lutimesSyncImpl(e,t,r){const A=this.realFs.lutimesSync;if(void 0===A)throw(0,i.bk)("unavailable Node binding",`lutimes '${e}'`);A.call(this.realFs,s.cS.fromPortablePath(e),t,r)}async mkdirPromise(e,t){return await new Promise((r,A)=>{this.realFs.mkdir(s.cS.fromPortablePath(e),t,this.makeCallback(r,A))})}mkdirSync(e,t){return this.realFs.mkdirSync(s.cS.fromPortablePath(e),t)}async rmdirPromise(e,t){return await new Promise((r,A)=>{t?this.realFs.rmdir(s.cS.fromPortablePath(e),t,this.makeCallback(r,A)):this.realFs.rmdir(s.cS.fromPortablePath(e),this.makeCallback(r,A))})}rmdirSync(e,t){return this.realFs.rmdirSync(s.cS.fromPortablePath(e),t)}async linkPromise(e,t){return await new Promise((r,A)=>{this.realFs.link(s.cS.fromPortablePath(e),s.cS.fromPortablePath(t),this.makeCallback(r,A))})}linkSync(e,t){return this.realFs.linkSync(s.cS.fromPortablePath(e),s.cS.fromPortablePath(t))}async symlinkPromise(e,t,r){const A=r||(e.endsWith("/")?"dir":"file");return await new Promise((r,n)=>{this.realFs.symlink(s.cS.fromPortablePath(e.replace(/\/+$/,"")),s.cS.fromPortablePath(t),A,this.makeCallback(r,n))})}symlinkSync(e,t,r){const A=r||(e.endsWith("/")?"dir":"file");return this.realFs.symlinkSync(s.cS.fromPortablePath(e.replace(/\/+$/,"")),s.cS.fromPortablePath(t),A)}async readFilePromise(e,t){return await new Promise((r,A)=>{const n="string"==typeof e?s.cS.fromPortablePath(e):e;this.realFs.readFile(n,t,this.makeCallback(r,A))})}readFileSync(e,t){const r="string"==typeof e?s.cS.fromPortablePath(e):e;return this.realFs.readFileSync(r,t)}async readdirPromise(e,{withFileTypes:t}={}){return await new Promise((r,A)=>{t?this.realFs.readdir(s.cS.fromPortablePath(e),{withFileTypes:!0},this.makeCallback(r,A)):this.realFs.readdir(s.cS.fromPortablePath(e),this.makeCallback(e=>r(e),A))})}readdirSync(e,{withFileTypes:t}={}){return t?this.realFs.readdirSync(s.cS.fromPortablePath(e),{withFileTypes:!0}):this.realFs.readdirSync(s.cS.fromPortablePath(e))}async readlinkPromise(e){return await new Promise((t,r)=>{this.realFs.readlink(s.cS.fromPortablePath(e),this.makeCallback(t,r))}).then(e=>s.cS.toPortablePath(e))}readlinkSync(e){return s.cS.toPortablePath(this.realFs.readlinkSync(s.cS.fromPortablePath(e)))}async truncatePromise(e,t){return await new Promise((r,A)=>{this.realFs.truncate(s.cS.fromPortablePath(e),t,this.makeCallback(r,A))})}truncateSync(e,t){return this.realFs.truncateSync(s.cS.fromPortablePath(e),t)}watch(e,t,r){return this.realFs.watch(s.cS.fromPortablePath(e),t,r)}watchFile(e,t,r){return this.realFs.watchFile(s.cS.fromPortablePath(e),t,r)}unwatchFile(e,t){return this.realFs.unwatchFile(s.cS.fromPortablePath(e),t)}makeCallback(e,t){return(r,A)=>{r?t(r):e(A)}}}},39725:(e,t,r)=>{"use strict";r.d(t,{i:()=>o});var A=r(42096),n=r(46009);class o extends A.p{constructor(e){super(n.cS),this.baseFs=e}mapFromBase(e){return n.cS.fromPortablePath(e)}mapToBase(e){return n.cS.toPortablePath(e)}}},42096:(e,t,r)=>{"use strict";r.d(t,{p:()=>n});var A=r(5944);class n extends A.uY{getExtractHint(e){return this.baseFs.getExtractHint(e)}resolve(e){return this.mapFromBase(this.baseFs.resolve(this.mapToBase(e)))}getRealPath(){return this.mapFromBase(this.baseFs.getRealPath())}async openPromise(e,t,r){return this.baseFs.openPromise(this.mapToBase(e),t,r)}openSync(e,t,r){return this.baseFs.openSync(this.mapToBase(e),t,r)}async opendirPromise(e,t){return Object.assign(await this.baseFs.opendirPromise(this.mapToBase(e),t),{path:e})}opendirSync(e,t){return Object.assign(this.baseFs.opendirSync(this.mapToBase(e),t),{path:e})}async readPromise(e,t,r,A,n){return await this.baseFs.readPromise(e,t,r,A,n)}readSync(e,t,r,A,n){return this.baseFs.readSync(e,t,r,A,n)}async writePromise(e,t,r,A,n){return"string"==typeof t?await this.baseFs.writePromise(e,t,r):await this.baseFs.writePromise(e,t,r,A,n)}writeSync(e,t,r,A,n){return"string"==typeof t?this.baseFs.writeSync(e,t,r):this.baseFs.writeSync(e,t,r,A,n)}async closePromise(e){return this.baseFs.closePromise(e)}closeSync(e){this.baseFs.closeSync(e)}createReadStream(e,t){return this.baseFs.createReadStream(null!==e?this.mapToBase(e):e,t)}createWriteStream(e,t){return this.baseFs.createWriteStream(null!==e?this.mapToBase(e):e,t)}async realpathPromise(e){return this.mapFromBase(await this.baseFs.realpathPromise(this.mapToBase(e)))}realpathSync(e){return this.mapFromBase(this.baseFs.realpathSync(this.mapToBase(e)))}async existsPromise(e){return this.baseFs.existsPromise(this.mapToBase(e))}existsSync(e){return this.baseFs.existsSync(this.mapToBase(e))}accessSync(e,t){return this.baseFs.accessSync(this.mapToBase(e),t)}async accessPromise(e,t){return this.baseFs.accessPromise(this.mapToBase(e),t)}async statPromise(e){return this.baseFs.statPromise(this.mapToBase(e))}statSync(e){return this.baseFs.statSync(this.mapToBase(e))}async lstatPromise(e){return this.baseFs.lstatPromise(this.mapToBase(e))}lstatSync(e){return this.baseFs.lstatSync(this.mapToBase(e))}async chmodPromise(e,t){return this.baseFs.chmodPromise(this.mapToBase(e),t)}chmodSync(e,t){return this.baseFs.chmodSync(this.mapToBase(e),t)}async chownPromise(e,t,r){return this.baseFs.chownPromise(this.mapToBase(e),t,r)}chownSync(e,t,r){return this.baseFs.chownSync(this.mapToBase(e),t,r)}async renamePromise(e,t){return this.baseFs.renamePromise(this.mapToBase(e),this.mapToBase(t))}renameSync(e,t){return this.baseFs.renameSync(this.mapToBase(e),this.mapToBase(t))}async copyFilePromise(e,t,r=0){return this.baseFs.copyFilePromise(this.mapToBase(e),this.mapToBase(t),r)}copyFileSync(e,t,r=0){return this.baseFs.copyFileSync(this.mapToBase(e),this.mapToBase(t),r)}async appendFilePromise(e,t,r){return this.baseFs.appendFilePromise(this.fsMapToBase(e),t,r)}appendFileSync(e,t,r){return this.baseFs.appendFileSync(this.fsMapToBase(e),t,r)}async writeFilePromise(e,t,r){return this.baseFs.writeFilePromise(this.fsMapToBase(e),t,r)}writeFileSync(e,t,r){return this.baseFs.writeFileSync(this.fsMapToBase(e),t,r)}async unlinkPromise(e){return this.baseFs.unlinkPromise(this.mapToBase(e))}unlinkSync(e){return this.baseFs.unlinkSync(this.mapToBase(e))}async utimesPromise(e,t,r){return this.baseFs.utimesPromise(this.mapToBase(e),t,r)}utimesSync(e,t,r){return this.baseFs.utimesSync(this.mapToBase(e),t,r)}async mkdirPromise(e,t){return this.baseFs.mkdirPromise(this.mapToBase(e),t)}mkdirSync(e,t){return this.baseFs.mkdirSync(this.mapToBase(e),t)}async rmdirPromise(e,t){return this.baseFs.rmdirPromise(this.mapToBase(e),t)}rmdirSync(e,t){return this.baseFs.rmdirSync(this.mapToBase(e),t)}async linkPromise(e,t){return this.baseFs.linkPromise(this.mapToBase(e),this.mapToBase(t))}linkSync(e,t){return this.baseFs.linkSync(this.mapToBase(e),this.mapToBase(t))}async symlinkPromise(e,t,r){return this.baseFs.symlinkPromise(this.mapToBase(e),this.mapToBase(t),r)}symlinkSync(e,t,r){return this.baseFs.symlinkSync(this.mapToBase(e),this.mapToBase(t),r)}async readFilePromise(e,t){return this.baseFs.readFilePromise(this.fsMapToBase(e),t)}readFileSync(e,t){return this.baseFs.readFileSync(this.fsMapToBase(e),t)}async readdirPromise(e,{withFileTypes:t}={}){return this.baseFs.readdirPromise(this.mapToBase(e),{withFileTypes:t})}readdirSync(e,{withFileTypes:t}={}){return this.baseFs.readdirSync(this.mapToBase(e),{withFileTypes:t})}async readlinkPromise(e){return this.mapFromBase(await this.baseFs.readlinkPromise(this.mapToBase(e)))}readlinkSync(e){return this.mapFromBase(this.baseFs.readlinkSync(this.mapToBase(e)))}async truncatePromise(e,t){return this.baseFs.truncatePromise(this.mapToBase(e),t)}truncateSync(e,t){return this.baseFs.truncateSync(this.mapToBase(e),t)}watch(e,t,r){return this.baseFs.watch(this.mapToBase(e),t,r)}watchFile(e,t,r){return this.baseFs.watchFile(this.mapToBase(e),t,r)}unwatchFile(e,t){return this.baseFs.unwatchFile(this.mapToBase(e),t)}fsMapToBase(e){return"number"==typeof e?e:this.mapToBase(e)}}},17674:(e,t,r)=>{"use strict";r.d(t,{p:()=>c});var A=r(78420),n=r(42096),o=r(46009);const i=/^[0-9]+$/,s=/^(\/(?:[^/]+\/)*?\$\$virtual)((?:\/((?:[^/]+-)?[a-f0-9]+)(?:\/([^/]+))?)?((?:\/.*)?))$/,a=/^([^/]+-)?[a-f0-9]+$/;class c extends n.p{constructor({baseFs:e=new A.S}={}){super(o.y1),this.baseFs=e}static makeVirtualPath(e,t,r){if("$$virtual"!==o.y1.basename(e))throw new Error('Assertion failed: Virtual folders must be named "$$virtual"');if(!o.y1.basename(t).match(a))throw new Error("Assertion failed: Virtual components must be ended by an hexadecimal hash");const A=o.y1.relative(o.y1.dirname(e),r).split("/");let n=0;for(;n{"use strict";r.d(t,{k:()=>C,d:()=>f});var A=r(35747),n=r(92413),o=r(31669),i=r(78761),s=r.n(i),a=r(5944),c=r(78420),g=r(19697),l=r(38783),u=r(22004),h=r(26984),p=r(46009),d=r(65760);const C="mixed";class f extends a.fS{constructor(e,t){super(),this.lzSource=null,this.listings=new Map,this.entries=new Map,this.fileSources=new Map,this.fds=new Map,this.nextFd=0,this.ready=!1,this.readOnly=!1,this.libzip=t.libzip;const r=t;if(this.level=void 0!==r.level?r.level:C,null===e&&(e=Buffer.from([80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])),"string"==typeof e){const{baseFs:t=new c.S}=r;this.baseFs=t,this.path=e}else this.path=null,this.baseFs=null;if(t.stats)this.stats=t.stats;else if("string"==typeof e)try{this.stats=this.baseFs.statSync(e)}catch(e){if("ENOENT"!==e.code||!r.create)throw e;this.stats=d.makeDefaultStats()}else this.stats=d.makeDefaultStats();const A=this.libzip.malloc(4);try{let n=0;if("string"==typeof e&&r.create&&(n|=this.libzip.ZIP_CREATE|this.libzip.ZIP_TRUNCATE),t.readOnly&&(n|=this.libzip.ZIP_RDONLY,this.readOnly=!0),"string"==typeof e)this.zip=this.libzip.open(p.cS.fromPortablePath(e),n,A);else{const t=this.allocateUnattachedSource(e);try{this.zip=this.libzip.openFromSource(t,n,A),this.lzSource=t}catch(e){throw this.libzip.source.free(t),e}}if(0===this.zip){const e=this.libzip.struct.errorS();throw this.libzip.error.initWithCode(e,this.libzip.getValue(A,"i32")),this.makeLibzipError(e)}}finally{this.libzip.free(A)}this.listings.set(p.LZ.root,new Set);const n=this.libzip.getNumEntries(this.zip,0);for(let e=0;ee)throw new Error("Overread");const A=this.libzip.HEAPU8.subarray(t,t+e);return Buffer.from(A)}finally{this.libzip.free(t)}}finally{this.libzip.source.close(this.lzSource),this.libzip.source.free(this.lzSource),this.ready=!1}}prepareClose(){if(!this.ready)throw h.Vw("archive closed, close");(0,l.L)(this)}saveAndClose(){if(!this.path||!this.baseFs)throw new Error("ZipFS cannot be saved and must be discarded when loaded from a buffer");if(this.prepareClose(),this.readOnly)return void this.discardAndClose();const e=this.baseFs.existsSync(this.path)?511&this.baseFs.statSync(this.path).mode:null;if(-1===this.libzip.close(this.zip))throw this.makeLibzipError(this.libzip.getError(this.zip));null===e?this.baseFs.chmodSync(this.path,this.stats.mode):e!==(511&this.baseFs.statSync(this.path).mode)&&this.baseFs.chmodSync(this.path,e),this.ready=!1}discardAndClose(){this.prepareClose(),this.libzip.discard(this.zip),this.ready=!1}resolve(e){return p.y1.resolve(p.LZ.root,e)}async openPromise(e,t,r){return this.openSync(e,t,r)}openSync(e,t,r){const A=this.nextFd++;return this.fds.set(A,{cursor:0,p:e}),A}hasOpenFileHandles(){return!!this.fds.size}async opendirPromise(e,t){return this.opendirSync(e,t)}opendirSync(e,t={}){const r=this.resolveFilename(`opendir '${e}'`,e);if(!this.entries.has(r)&&!this.listings.has(r))throw h.z6(`opendir '${e}'`);const A=this.listings.get(r);if(!A)throw h.Ab(`opendir '${e}'`);const n=[...A],o=this.openSync(r,"r");return(0,g.a)(this,r,n,{onClose:()=>{this.closeSync(o)}})}async readPromise(e,t,r,A,n){return this.readSync(e,t,r,A,n)}readSync(e,t,r=0,A=0,n=-1){const o=this.fds.get(e);if(void 0===o)throw h.Ch("read");let i;i=-1===n||null===n?o.cursor:n;const s=this.readFileSync(o.p);s.copy(t,r,i,i+A);const a=Math.max(0,Math.min(s.length-i,A));return-1!==n&&null!==n||(o.cursor+=a),a}async writePromise(e,t,r,A,n){return"string"==typeof t?this.writeSync(e,t,n):this.writeSync(e,t,r,A,n)}writeSync(e,t,r,A,n){if(void 0===this.fds.get(e))throw h.Ch("read");throw new Error("Unimplemented")}async closePromise(e){return this.closeSync(e)}closeSync(e){if(void 0===this.fds.get(e))throw h.Ch("read");this.fds.delete(e)}createReadStream(e,{encoding:t}={}){if(null===e)throw new Error("Unimplemented");const r=this.openSync(e,"r"),A=Object.assign(new n.PassThrough({emitClose:!0,autoDestroy:!0,destroy:(e,t)=>{clearImmediate(o),this.closeSync(r),t(e)}}),{close(){A.destroy()},bytesRead:0,path:e}),o=setImmediate(async()=>{try{const r=await this.readFilePromise(e,t);A.bytesRead=r.length,A.end(r)}catch(e){A.destroy(e)}});return A}createWriteStream(e,{encoding:t}={}){if(this.readOnly)throw h.YW(`open '${e}'`);if(null===e)throw new Error("Unimplemented");const r=[],A=this.openSync(e,"w"),o=Object.assign(new n.PassThrough({autoDestroy:!0,emitClose:!0,destroy:(n,o)=>{try{n?o(n):(this.writeFileSync(e,Buffer.concat(r),t),o(null))}catch(e){o(e)}finally{this.closeSync(A)}}}),{bytesWritten:0,path:e,close(){o.destroy()}});return o.on("data",e=>{const t=Buffer.from(e);o.bytesWritten+=t.length,r.push(t)}),o}async realpathPromise(e){return this.realpathSync(e)}realpathSync(e){const t=this.resolveFilename(`lstat '${e}'`,e);if(!this.entries.has(t)&&!this.listings.has(t))throw h.z6(`lstat '${e}'`);return t}async existsPromise(e){return this.existsSync(e)}existsSync(e){if(!this.ready)throw h.Vw(`archive closed, existsSync '${e}'`);if(0===this.symlinkCount){const t=p.y1.resolve(p.LZ.root,e);return this.entries.has(t)||this.listings.has(t)}let t;try{t=this.resolveFilename(`stat '${e}'`,e)}catch(e){return!1}return this.entries.has(t)||this.listings.has(t)}async accessPromise(e,t){return this.accessSync(e,t)}accessSync(e,t=A.constants.F_OK){const r=this.resolveFilename(`access '${e}'`,e);if(!this.entries.has(r)&&!this.listings.has(r))throw h.z6(`access '${e}'`);if(this.readOnly&&t&A.constants.W_OK)throw h.YW(`access '${e}'`)}async statPromise(e){return this.statSync(e)}statSync(e){const t=this.resolveFilename(`stat '${e}'`,e);if(!this.entries.has(t)&&!this.listings.has(t))throw h.z6(`stat '${e}'`);if("/"===e[e.length-1]&&!this.listings.has(t))throw h.Ab(`stat '${e}'`);return this.statImpl(`stat '${e}'`,t)}async lstatPromise(e){return this.lstatSync(e)}lstatSync(e){const t=this.resolveFilename(`lstat '${e}'`,e,!1);if(!this.entries.has(t)&&!this.listings.has(t))throw h.z6(`lstat '${e}'`);if("/"===e[e.length-1]&&!this.listings.has(t))throw h.Ab(`lstat '${e}'`);return this.statImpl(`lstat '${e}'`,t)}statImpl(e,t){const r=this.entries.get(t);if(void 0!==r){const e=this.libzip.struct.statS();if(-1===this.libzip.statIndex(this.zip,r,0,0,e))throw this.makeLibzipError(this.libzip.getError(this.zip));const A=this.stats.uid,n=this.stats.gid,o=this.libzip.struct.statSize(e)>>>0,i=512,s=Math.ceil(o/i),a=1e3*(this.libzip.struct.statMtime(e)>>>0),c=a,g=a,l=a,h=new Date(c),p=new Date(g),C=new Date(l),f=new Date(a),I=this.listings.has(t)?u.QB:this.isSymbolicLink(r)?u.Zv:u.Pe,E=I===u.QB?493:420,B=I|511&this.getUnixMode(r,E);return Object.assign(new d.StatEntry,{uid:A,gid:n,size:o,blksize:i,blocks:s,atime:h,birthtime:p,ctime:C,mtime:f,atimeMs:c,birthtimeMs:g,ctimeMs:l,mtimeMs:a,mode:B})}if(this.listings.has(t)){const e=this.stats.uid,t=this.stats.gid,r=0,A=512,n=0,o=this.stats.mtimeMs,i=this.stats.mtimeMs,s=this.stats.mtimeMs,a=this.stats.mtimeMs,c=new Date(o),g=new Date(i),l=new Date(s),h=new Date(a),p=493|u.QB;return Object.assign(new d.StatEntry,{uid:e,gid:t,size:r,blksize:A,blocks:n,atime:c,birthtime:g,ctime:l,mtime:h,atimeMs:o,birthtimeMs:i,ctimeMs:s,mtimeMs:a,mode:p})}throw new Error("Unreachable")}getUnixMode(e,t){if(-1===this.libzip.file.getExternalAttributes(this.zip,e,0,0,this.libzip.uint08S,this.libzip.uint32S))throw this.makeLibzipError(this.libzip.getError(this.zip));return this.libzip.getValue(this.libzip.uint08S,"i8")>>>0!==this.libzip.ZIP_OPSYS_UNIX?t:this.libzip.getValue(this.libzip.uint32S,"i32")>>>16}registerListing(e){let t=this.listings.get(e);if(t)return t;const r=this.registerListing(p.y1.dirname(e));return t=new Set,r.add(p.y1.basename(e)),this.listings.set(e,t),t}registerEntry(e,t){this.registerListing(p.y1.dirname(e)).add(p.y1.basename(e)),this.entries.set(e,t)}unregisterListing(e){this.listings.delete(e);const t=this.listings.get(p.y1.dirname(e));null==t||t.delete(p.y1.basename(e))}unregisterEntry(e){this.unregisterListing(e);const t=this.entries.get(e);this.entries.delete(e),void 0!==t&&(this.fileSources.delete(t),this.isSymbolicLink(t)&&this.symlinkCount--)}deleteEntry(e,t){this.unregisterEntry(e);if(-1===this.libzip.delete(this.zip,t))throw this.makeLibzipError(this.libzip.getError(this.zip))}resolveFilename(e,t,r=!0){if(!this.ready)throw h.Vw("archive closed, "+e);let A=p.y1.resolve(p.LZ.root,t);if("/"===A)return p.LZ.root;const n=this.entries.get(A);if(r&&void 0!==n){if(0!==this.symlinkCount&&this.isSymbolicLink(n)){const t=this.getFileSource(n).toString();return this.resolveFilename(e,p.y1.resolve(p.y1.dirname(A),t),!0)}return A}for(;;){const t=this.resolveFilename(e,p.y1.dirname(A),!0),n=this.listings.has(t),o=this.entries.has(t);if(!n&&!o)throw h.z6(e);if(!n)throw h.Ab(e);if(A=p.y1.resolve(t,p.y1.basename(A)),!r||0===this.symlinkCount)break;const i=this.libzip.name.locate(this.zip,A.slice(1));if(-1===i)break;if(!this.isSymbolicLink(i))break;{const e=this.getFileSource(i).toString();A=p.y1.resolve(p.y1.dirname(A),e)}}return A}allocateBuffer(e){Buffer.isBuffer(e)||(e=Buffer.from(e));const t=this.libzip.malloc(e.byteLength);if(!t)throw new Error("Couldn't allocate enough memory");return new Uint8Array(this.libzip.HEAPU8.buffer,t,e.byteLength).set(e),{buffer:t,byteLength:e.byteLength}}allocateUnattachedSource(e){const t=this.libzip.struct.errorS(),{buffer:r,byteLength:A}=this.allocateBuffer(e),n=this.libzip.source.fromUnattachedBuffer(r,A,0,!0,t);if(0===n)throw this.libzip.free(t),this.makeLibzipError(t);return n}allocateSource(e){const{buffer:t,byteLength:r}=this.allocateBuffer(e),A=this.libzip.source.fromBuffer(this.zip,t,r,0,!0);if(0===A)throw this.libzip.free(t),this.makeLibzipError(this.libzip.getError(this.zip));return A}setFileSource(e,t){const r=Buffer.isBuffer(t)?t:Buffer.from(t),A=p.y1.relative(p.LZ.root,e),n=this.allocateSource(t);try{const e=this.libzip.file.add(this.zip,A,n,this.libzip.ZIP_FL_OVERWRITE);if(-1===e)throw this.makeLibzipError(this.libzip.getError(this.zip));if("mixed"!==this.level){let t;t=0===this.level?this.libzip.ZIP_CM_STORE:this.libzip.ZIP_CM_DEFLATE;if(-1===this.libzip.file.setCompression(this.zip,e,0,t,this.level))throw this.makeLibzipError(this.libzip.getError(this.zip))}return this.fileSources.set(e,r),e}catch(e){throw this.libzip.source.free(n),e}}isSymbolicLink(e){if(0===this.symlinkCount)return!1;if(-1===this.libzip.file.getExternalAttributes(this.zip,e,0,0,this.libzip.uint08S,this.libzip.uint32S))throw this.makeLibzipError(this.libzip.getError(this.zip));if(this.libzip.getValue(this.libzip.uint08S,"i8")>>>0!==this.libzip.ZIP_OPSYS_UNIX)return!1;return(this.libzip.getValue(this.libzip.uint32S,"i32")>>>16&u.wK)===u.Zv}getFileSource(e,t={asyncDecompress:!1}){const r=this.fileSources.get(e);if(void 0!==r)return r;const A=this.libzip.struct.statS();if(-1===this.libzip.statIndex(this.zip,e,0,0,A))throw this.makeLibzipError(this.libzip.getError(this.zip));const n=this.libzip.struct.statCompSize(A),o=this.libzip.struct.statCompMethod(A),i=this.libzip.malloc(n);try{const r=this.libzip.fopenIndex(this.zip,e,0,this.libzip.ZIP_FL_COMPRESSED);if(0===r)throw this.makeLibzipError(this.libzip.getError(this.zip));try{const A=this.libzip.fread(r,i,n,0);if(-1===A)throw this.makeLibzipError(this.libzip.file.getError(r));if(An)throw new Error("Overread");const a=this.libzip.HEAPU8.subarray(i,i+n),c=Buffer.from(a);if(0===o)return this.fileSources.set(e,c),c;if(t.asyncDecompress)return new Promise((t,r)=>{s().inflateRaw(c,(A,n)=>{A?r(A):(this.fileSources.set(e,n),t(n))})});{const t=s().inflateRawSync(c);return this.fileSources.set(e,t),t}}finally{this.libzip.fclose(r)}}finally{this.libzip.free(i)}}async chmodPromise(e,t){return this.chmodSync(e,t)}chmodSync(e,t){if(this.readOnly)throw h.YW(`chmod '${e}'`);t&=493;const r=this.resolveFilename(`chmod '${e}'`,e,!1),A=this.entries.get(r);if(void 0===A)throw new Error(`Assertion failed: The entry should have been registered (${r})`);const n=-512&this.getUnixMode(A,0|u.Pe)|t;if(-1===this.libzip.file.setExternalAttributes(this.zip,A,0,0,this.libzip.ZIP_OPSYS_UNIX,n<<16))throw this.makeLibzipError(this.libzip.getError(this.zip))}async chownPromise(e,t,r){return this.chownSync(e,t,r)}chownSync(e,t,r){throw new Error("Unimplemented")}async renamePromise(e,t){return this.renameSync(e,t)}renameSync(e,t){throw new Error("Unimplemented")}async copyFilePromise(e,t,r){const{indexSource:A,indexDest:n,resolvedDestP:o}=this.prepareCopyFile(e,t,r),i=await this.getFileSource(A,{asyncDecompress:!0}),s=this.setFileSource(o,i);s!==n&&this.registerEntry(o,s)}copyFileSync(e,t,r=0){const{indexSource:A,indexDest:n,resolvedDestP:o}=this.prepareCopyFile(e,t,r),i=this.getFileSource(A),s=this.setFileSource(o,i);s!==n&&this.registerEntry(o,s)}prepareCopyFile(e,t,r=0){if(this.readOnly)throw h.YW(`copyfile '${e} -> '${t}'`);if(0!=(r&A.constants.COPYFILE_FICLONE_FORCE))throw h.bk("unsupported clone operation",`copyfile '${e}' -> ${t}'`);const n=this.resolveFilename(`copyfile '${e} -> ${t}'`,e),o=this.entries.get(n);if(void 0===o)throw h.hq(`copyfile '${e}' -> '${t}'`);const i=this.resolveFilename(`copyfile '${e}' -> ${t}'`,t),s=this.entries.get(i);if(0!=(r&(A.constants.COPYFILE_EXCL|A.constants.COPYFILE_FICLONE_FORCE))&&void 0!==s)throw h.cT(`copyfile '${e}' -> '${t}'`);return{indexSource:o,resolvedDestP:i,indexDest:s}}async appendFilePromise(e,t,r){if(this.readOnly)throw h.YW(`open '${e}'`);return void 0===r?r={flag:"a"}:"string"==typeof r?r={flag:"a",encoding:r}:void 0===r.flag&&(r={flag:"a",...r}),this.writeFilePromise(e,t,r)}appendFileSync(e,t,r={}){if(this.readOnly)throw h.YW(`open '${e}'`);return void 0===r?r={flag:"a"}:"string"==typeof r?r={flag:"a",encoding:r}:void 0===r.flag&&(r={flag:"a",...r}),this.writeFileSync(e,t,r)}async writeFilePromise(e,t,r){const{encoding:A,index:n,resolvedP:o}=this.prepareWriteFile(e,r);void 0!==n&&"object"==typeof r&&r.flag&&r.flag.includes("a")&&(t=Buffer.concat([await this.getFileSource(n,{asyncDecompress:!0}),Buffer.from(t)])),null!==A&&(t=t.toString(A));const i=this.setFileSource(o,t);i!==n&&this.registerEntry(o,i)}writeFileSync(e,t,r){const{encoding:A,index:n,resolvedP:o}=this.prepareWriteFile(e,r);void 0!==n&&"object"==typeof r&&r.flag&&r.flag.includes("a")&&(t=Buffer.concat([this.getFileSource(n),Buffer.from(t)])),null!==A&&(t=t.toString(A));const i=this.setFileSource(o,t);i!==n&&this.registerEntry(o,i)}prepareWriteFile(e,t){if("string"!=typeof e)throw h.Ch("read");if(this.readOnly)throw h.YW(`open '${e}'`);const r=this.resolveFilename(`open '${e}'`,e);if(this.listings.has(r))throw h.GA(`open '${e}'`);let A=null;"string"==typeof t?A=t:"object"==typeof t&&t.encoding&&(A=t.encoding);return{encoding:A,resolvedP:r,index:this.entries.get(r)}}async unlinkPromise(e){return this.unlinkSync(e)}unlinkSync(e){if(this.readOnly)throw h.YW(`unlink '${e}'`);const t=this.resolveFilename(`unlink '${e}'`,e);if(this.listings.has(t))throw h.GA(`unlink '${e}'`);const r=this.entries.get(t);if(void 0===r)throw h.hq(`unlink '${e}'`);this.deleteEntry(t,r)}async utimesPromise(e,t,r){return this.utimesSync(e,t,r)}utimesSync(e,t,r){if(this.readOnly)throw h.YW(`utimes '${e}'`);const A=this.resolveFilename(`utimes '${e}'`,e);this.utimesImpl(A,r)}async lutimesPromise(e,t,r){return this.lutimesSync(e,t,r)}lutimesSync(e,t,r){if(this.readOnly)throw h.YW(`lutimes '${e}'`);const A=this.resolveFilename(`utimes '${e}'`,e,!1);this.utimesImpl(A,r)}utimesImpl(e,t){this.listings.has(e)&&(this.entries.has(e)||this.hydrateDirectory(e));const r=this.entries.get(e);if(void 0===r)throw new Error("Unreachable");if(-1===this.libzip.file.setMtime(this.zip,r,0,function(e){if("string"==typeof e&&String(+e)===e)return+e;if(Number.isFinite(e))return e<0?Date.now()/1e3:e;if((0,o.isDate)(e))return e.getTime()/1e3;throw new Error("Invalid time")}(t),0))throw this.makeLibzipError(this.libzip.getError(this.zip))}async mkdirPromise(e,t){return this.mkdirSync(e,t)}mkdirSync(e,{mode:t=493,recursive:r=!1}={}){if(r)return void this.mkdirpSync(e,{chmod:t});if(this.readOnly)throw h.YW(`mkdir '${e}'`);const A=this.resolveFilename(`mkdir '${e}'`,e);if(this.entries.has(A)||this.listings.has(A))throw h.cT(`mkdir '${e}'`);this.hydrateDirectory(A),this.chmodSync(A,t)}async rmdirPromise(e,t){return this.rmdirSync(e,t)}rmdirSync(e,{recursive:t=!1}={}){if(this.readOnly)throw h.YW(`rmdir '${e}'`);if(t)return void this.removeSync(e);const r=this.resolveFilename(`rmdir '${e}'`,e),A=this.listings.get(r);if(!A)throw h.Ab(`rmdir '${e}'`);if(A.size>0)throw h.re(`rmdir '${e}'`);const n=this.entries.get(r);if(void 0===n)throw h.hq(`rmdir '${e}'`);this.deleteEntry(e,n)}hydrateDirectory(e){const t=this.libzip.dir.add(this.zip,p.y1.relative(p.LZ.root,e));if(-1===t)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.registerListing(e),this.registerEntry(e,t),t}async linkPromise(e,t){return this.linkSync(e,t)}linkSync(e,t){throw h.Hs(`link '${e}' -> '${t}'`)}async symlinkPromise(e,t){return this.symlinkSync(e,t)}symlinkSync(e,t){if(this.readOnly)throw h.YW(`symlink '${e}' -> '${t}'`);const r=this.resolveFilename(`symlink '${e}' -> '${t}'`,t);if(this.listings.has(r))throw h.GA(`symlink '${e}' -> '${t}'`);if(this.entries.has(r))throw h.cT(`symlink '${e}' -> '${t}'`);const A=this.setFileSource(r,e);this.registerEntry(r,A);if(-1===this.libzip.file.setExternalAttributes(this.zip,A,0,0,this.libzip.ZIP_OPSYS_UNIX,(511|u.Zv)<<16))throw this.makeLibzipError(this.libzip.getError(this.zip));this.symlinkCount+=1}async readFilePromise(e,t){"object"==typeof t&&(t=t?t.encoding:void 0);const r=await this.readFileBuffer(e,{asyncDecompress:!0});return t?r.toString(t):r}readFileSync(e,t){"object"==typeof t&&(t=t?t.encoding:void 0);const r=this.readFileBuffer(e);return t?r.toString(t):r}readFileBuffer(e,t={asyncDecompress:!1}){if("string"!=typeof e)throw h.Ch("read");const r=this.resolveFilename(`open '${e}'`,e);if(!this.entries.has(r)&&!this.listings.has(r))throw h.z6(`open '${e}'`);if("/"===e[e.length-1]&&!this.listings.has(r))throw h.Ab(`open '${e}'`);if(this.listings.has(r))throw h.GA("read");const A=this.entries.get(r);if(void 0===A)throw new Error("Unreachable");return this.getFileSource(A,t)}async readdirPromise(e,{withFileTypes:t}={}){return this.readdirSync(e,{withFileTypes:t})}readdirSync(e,{withFileTypes:t}={}){const r=this.resolveFilename(`scandir '${e}'`,e);if(!this.entries.has(r)&&!this.listings.has(r))throw h.z6(`scandir '${e}'`);const A=this.listings.get(r);if(!A)throw h.Ab(`scandir '${e}'`);const n=[...A];return t?n.map(t=>Object.assign(this.statImpl("lstat",p.y1.join(e,t)),{name:t})):n}async readlinkPromise(e){const t=this.prepareReadlink(e);return(await this.getFileSource(t,{asyncDecompress:!0})).toString()}readlinkSync(e){const t=this.prepareReadlink(e);return this.getFileSource(t).toString()}prepareReadlink(e){const t=this.resolveFilename(`readlink '${e}'`,e,!1);if(!this.entries.has(t)&&!this.listings.has(t))throw h.z6(`readlink '${e}'`);if("/"===e[e.length-1]&&!this.listings.has(t))throw h.Ab(`open '${e}'`);if(this.listings.has(t))throw h.hq(`readlink '${e}'`);const r=this.entries.get(t);if(void 0===r)throw new Error("Unreachable");if(!this.isSymbolicLink(r))throw h.hq(`readlink '${e}'`);return r}async truncatePromise(e,t=0){const r=this.resolveFilename(`open '${e}'`,e),A=this.entries.get(r);if(void 0===A)throw h.hq(`open '${e}'`);const n=await this.getFileSource(A,{asyncDecompress:!0}),o=Buffer.alloc(t,0);return n.copy(o),await this.writeFilePromise(e,o)}truncateSync(e,t=0){const r=this.resolveFilename(`open '${e}'`,e),A=this.entries.get(r);if(void 0===A)throw h.hq(`open '${e}'`);const n=this.getFileSource(A),o=Buffer.alloc(t,0);return n.copy(o),this.writeFileSync(e,o)}watch(e,t,r){let A;switch(typeof t){case"function":case"string":case"undefined":A=!0;break;default:({persistent:A=!0}=t)}if(!A)return{on:()=>{},close:()=>{}};const n=setInterval(()=>{},864e5);return{on:()=>{},close:()=>{clearInterval(n)}}}watchFile(e,t,r){const A=this.resolveFilename(`open '${e}'`,e);return(0,l._x)(this,A,t,r)}unwatchFile(e,t){const r=this.resolveFilename(`open '${e}'`,e);return(0,l.nd)(this,r,t)}}},53660:(e,t,r)=>{"use strict";r.d(t,{A:()=>l});var A=r(35747),n=r(5944),o=r(78420),i=r(90739),s=r(38783),a=r(46009);const c=2147483648,g=/.*?(?await this.baseFs.openPromise(e,t,r),async(e,{subPath:A})=>this.remapFd(e,await e.openPromise(A,t,r)))}openSync(e,t,r){return this.makeCallSync(e,()=>this.baseFs.openSync(e,t,r),(e,{subPath:A})=>this.remapFd(e,e.openSync(A,t,r)))}async opendirPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.opendirPromise(e,t),async(e,{subPath:r})=>await e.opendirPromise(r,t),{requireSubpath:!1})}opendirSync(e,t){return this.makeCallSync(e,()=>this.baseFs.opendirSync(e,t),(e,{subPath:r})=>e.opendirSync(r,t),{requireSubpath:!1})}async readPromise(e,t,r,A,n){if(0==(e&c))return await this.baseFs.readPromise(e,t,r,A,n);const o=this.fdMap.get(e);if(void 0===o)throw Object.assign(new Error("EBADF: bad file descriptor, read"),{code:"EBADF"});const[i,s]=o;return await i.readPromise(s,t,r,A,n)}readSync(e,t,r,A,n){if(0==(e&c))return this.baseFs.readSync(e,t,r,A,n);const o=this.fdMap.get(e);if(void 0===o)throw Object.assign(new Error("EBADF: bad file descriptor, read"),{code:"EBADF"});const[i,s]=o;return i.readSync(s,t,r,A,n)}async writePromise(e,t,r,A,n){if(0==(e&c))return"string"==typeof t?await this.baseFs.writePromise(e,t,r):await this.baseFs.writePromise(e,t,r,A,n);const o=this.fdMap.get(e);if(void 0===o)throw Object.assign(new Error("EBADF: bad file descriptor, write"),{code:"EBADF"});const[i,s]=o;return"string"==typeof t?await i.writePromise(s,t,r):await i.writePromise(s,t,r,A,n)}writeSync(e,t,r,A,n){if(0==(e&c))return"string"==typeof t?this.baseFs.writeSync(e,t,r):this.baseFs.writeSync(e,t,r,A,n);const o=this.fdMap.get(e);if(void 0===o)throw Object.assign(new Error("EBADF: bad file descriptor, write"),{code:"EBADF"});const[i,s]=o;return"string"==typeof t?i.writeSync(s,t,r):i.writeSync(s,t,r,A,n)}async closePromise(e){if(0==(e&c))return await this.baseFs.closePromise(e);const t=this.fdMap.get(e);if(void 0===t)throw Object.assign(new Error("EBADF: bad file descriptor, close"),{code:"EBADF"});this.fdMap.delete(e);const[r,A]=t;return await r.closePromise(A)}closeSync(e){if(0==(e&c))return this.baseFs.closeSync(e);const t=this.fdMap.get(e);if(void 0===t)throw Object.assign(new Error("EBADF: bad file descriptor, close"),{code:"EBADF"});this.fdMap.delete(e);const[r,A]=t;return r.closeSync(A)}createReadStream(e,t){return null===e?this.baseFs.createReadStream(e,t):this.makeCallSync(e,()=>this.baseFs.createReadStream(e,t),(e,{subPath:r})=>e.createReadStream(r,t))}createWriteStream(e,t){return null===e?this.baseFs.createWriteStream(e,t):this.makeCallSync(e,()=>this.baseFs.createWriteStream(e,t),(e,{subPath:r})=>e.createWriteStream(r,t))}async realpathPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.realpathPromise(e),async(e,{archivePath:t,subPath:r})=>{let A=this.realPaths.get(t);return void 0===A&&(A=await this.baseFs.realpathPromise(t),this.realPaths.set(t,A)),this.pathUtils.join(A,this.pathUtils.relative(a.LZ.root,await e.realpathPromise(r)))})}realpathSync(e){return this.makeCallSync(e,()=>this.baseFs.realpathSync(e),(e,{archivePath:t,subPath:r})=>{let A=this.realPaths.get(t);return void 0===A&&(A=this.baseFs.realpathSync(t),this.realPaths.set(t,A)),this.pathUtils.join(A,this.pathUtils.relative(a.LZ.root,e.realpathSync(r)))})}async existsPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.existsPromise(e),async(e,{subPath:t})=>await e.existsPromise(t))}existsSync(e){return this.makeCallSync(e,()=>this.baseFs.existsSync(e),(e,{subPath:t})=>e.existsSync(t))}async accessPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.accessPromise(e,t),async(e,{subPath:r})=>await e.accessPromise(r,t))}accessSync(e,t){return this.makeCallSync(e,()=>this.baseFs.accessSync(e,t),(e,{subPath:r})=>e.accessSync(r,t))}async statPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.statPromise(e),async(e,{subPath:t})=>await e.statPromise(t))}statSync(e){return this.makeCallSync(e,()=>this.baseFs.statSync(e),(e,{subPath:t})=>e.statSync(t))}async lstatPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.lstatPromise(e),async(e,{subPath:t})=>await e.lstatPromise(t))}lstatSync(e){return this.makeCallSync(e,()=>this.baseFs.lstatSync(e),(e,{subPath:t})=>e.lstatSync(t))}async chmodPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.chmodPromise(e,t),async(e,{subPath:r})=>await e.chmodPromise(r,t))}chmodSync(e,t){return this.makeCallSync(e,()=>this.baseFs.chmodSync(e,t),(e,{subPath:r})=>e.chmodSync(r,t))}async chownPromise(e,t,r){return await this.makeCallPromise(e,async()=>await this.baseFs.chownPromise(e,t,r),async(e,{subPath:A})=>await e.chownPromise(A,t,r))}chownSync(e,t,r){return this.makeCallSync(e,()=>this.baseFs.chownSync(e,t,r),(e,{subPath:A})=>e.chownSync(A,t,r))}async renamePromise(e,t){return await this.makeCallPromise(e,async()=>await this.makeCallPromise(t,async()=>await this.baseFs.renamePromise(e,t),async()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})}),async(e,{subPath:r})=>await this.makeCallPromise(t,async()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})},async(t,{subPath:A})=>{if(e!==t)throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"});return await e.renamePromise(r,A)}))}renameSync(e,t){return this.makeCallSync(e,()=>this.makeCallSync(t,()=>this.baseFs.renameSync(e,t),async()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})}),(e,{subPath:r})=>this.makeCallSync(t,()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})},(t,{subPath:A})=>{if(e!==t)throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"});return e.renameSync(r,A)}))}async copyFilePromise(e,t,r=0){const n=async(e,t,n,o)=>{if(0!=(r&A.constants.COPYFILE_FICLONE_FORCE))throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${t}' -> ${o}'`),{code:"EXDEV"});if(r&A.constants.COPYFILE_EXCL&&await this.existsPromise(t))throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${t}' -> '${o}'`),{code:"EEXIST"});let i;try{i=await e.readFilePromise(t)}catch(e){throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${t}' -> '${o}'`),{code:"EINVAL"})}await n.writeFilePromise(o,i)};return await this.makeCallPromise(e,async()=>await this.makeCallPromise(t,async()=>await this.baseFs.copyFilePromise(e,t,r),async(t,{subPath:r})=>await n(this.baseFs,e,t,r)),async(e,{subPath:A})=>await this.makeCallPromise(t,async()=>await n(e,A,this.baseFs,t),async(t,{subPath:o})=>e!==t?await n(e,A,t,o):await e.copyFilePromise(A,o,r)))}copyFileSync(e,t,r=0){const n=(e,t,n,o)=>{if(0!=(r&A.constants.COPYFILE_FICLONE_FORCE))throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${t}' -> ${o}'`),{code:"EXDEV"});if(r&A.constants.COPYFILE_EXCL&&this.existsSync(t))throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${t}' -> '${o}'`),{code:"EEXIST"});let i;try{i=e.readFileSync(t)}catch(e){throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${t}' -> '${o}'`),{code:"EINVAL"})}n.writeFileSync(o,i)};return this.makeCallSync(e,()=>this.makeCallSync(t,()=>this.baseFs.copyFileSync(e,t,r),(t,{subPath:r})=>n(this.baseFs,e,t,r)),(e,{subPath:A})=>this.makeCallSync(t,()=>n(e,A,this.baseFs,t),(t,{subPath:o})=>e!==t?n(e,A,t,o):e.copyFileSync(A,o,r)))}async appendFilePromise(e,t,r){return await this.makeCallPromise(e,async()=>await this.baseFs.appendFilePromise(e,t,r),async(e,{subPath:A})=>await e.appendFilePromise(A,t,r))}appendFileSync(e,t,r){return this.makeCallSync(e,()=>this.baseFs.appendFileSync(e,t,r),(e,{subPath:A})=>e.appendFileSync(A,t,r))}async writeFilePromise(e,t,r){return await this.makeCallPromise(e,async()=>await this.baseFs.writeFilePromise(e,t,r),async(e,{subPath:A})=>await e.writeFilePromise(A,t,r))}writeFileSync(e,t,r){return this.makeCallSync(e,()=>this.baseFs.writeFileSync(e,t,r),(e,{subPath:A})=>e.writeFileSync(A,t,r))}async unlinkPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.unlinkPromise(e),async(e,{subPath:t})=>await e.unlinkPromise(t))}unlinkSync(e){return this.makeCallSync(e,()=>this.baseFs.unlinkSync(e),(e,{subPath:t})=>e.unlinkSync(t))}async utimesPromise(e,t,r){return await this.makeCallPromise(e,async()=>await this.baseFs.utimesPromise(e,t,r),async(e,{subPath:A})=>await e.utimesPromise(A,t,r))}utimesSync(e,t,r){return this.makeCallSync(e,()=>this.baseFs.utimesSync(e,t,r),(e,{subPath:A})=>e.utimesSync(A,t,r))}async mkdirPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.mkdirPromise(e,t),async(e,{subPath:r})=>await e.mkdirPromise(r,t))}mkdirSync(e,t){return this.makeCallSync(e,()=>this.baseFs.mkdirSync(e,t),(e,{subPath:r})=>e.mkdirSync(r,t))}async rmdirPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.rmdirPromise(e,t),async(e,{subPath:r})=>await e.rmdirPromise(r,t))}rmdirSync(e,t){return this.makeCallSync(e,()=>this.baseFs.rmdirSync(e,t),(e,{subPath:r})=>e.rmdirSync(r,t))}async linkPromise(e,t){return await this.makeCallPromise(t,async()=>await this.baseFs.linkPromise(e,t),async(t,{subPath:r})=>await t.linkPromise(e,r))}linkSync(e,t){return this.makeCallSync(t,()=>this.baseFs.linkSync(e,t),(t,{subPath:r})=>t.linkSync(e,r))}async symlinkPromise(e,t,r){return await this.makeCallPromise(t,async()=>await this.baseFs.symlinkPromise(e,t,r),async(t,{subPath:r})=>await t.symlinkPromise(e,r))}symlinkSync(e,t,r){return this.makeCallSync(t,()=>this.baseFs.symlinkSync(e,t,r),(t,{subPath:r})=>t.symlinkSync(e,r))}async readFilePromise(e,t){return this.makeCallPromise(e,async()=>{switch(t){case"utf8":default:return await this.baseFs.readFilePromise(e,t)}},async(e,{subPath:r})=>await e.readFilePromise(r,t))}readFileSync(e,t){return this.makeCallSync(e,()=>{switch(t){case"utf8":default:return this.baseFs.readFileSync(e,t)}},(e,{subPath:r})=>e.readFileSync(r,t))}async readdirPromise(e,{withFileTypes:t}={}){return await this.makeCallPromise(e,async()=>await this.baseFs.readdirPromise(e,{withFileTypes:t}),async(e,{subPath:r})=>await e.readdirPromise(r,{withFileTypes:t}),{requireSubpath:!1})}readdirSync(e,{withFileTypes:t}={}){return this.makeCallSync(e,()=>this.baseFs.readdirSync(e,{withFileTypes:t}),(e,{subPath:r})=>e.readdirSync(r,{withFileTypes:t}),{requireSubpath:!1})}async readlinkPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.readlinkPromise(e),async(e,{subPath:t})=>await e.readlinkPromise(t))}readlinkSync(e){return this.makeCallSync(e,()=>this.baseFs.readlinkSync(e),(e,{subPath:t})=>e.readlinkSync(t))}async truncatePromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.truncatePromise(e,t),async(e,{subPath:r})=>await e.truncatePromise(r,t))}truncateSync(e,t){return this.makeCallSync(e,()=>this.baseFs.truncateSync(e,t),(e,{subPath:r})=>e.truncateSync(r,t))}watch(e,t,r){return this.makeCallSync(e,()=>this.baseFs.watch(e,t,r),(e,{subPath:A})=>e.watch(A,t,r))}watchFile(e,t,r){return this.makeCallSync(e,()=>this.baseFs.watchFile(e,t,r),()=>(0,s._x)(this,e,t,r))}unwatchFile(e,t){return this.makeCallSync(e,()=>this.baseFs.unwatchFile(e,t),()=>(0,s.nd)(this,e,t))}async makeCallPromise(e,t,r,{requireSubpath:A=!0}={}){if("string"!=typeof e)return await t();const n=this.resolve(e),o=this.findZip(n);return o?A&&"/"===o.subPath?await t():await this.getZipPromise(o.archivePath,async e=>await r(e,o)):await t()}makeCallSync(e,t,r,{requireSubpath:A=!0}={}){if("string"!=typeof e)return t();const n=this.resolve(e),o=this.findZip(n);return o?A&&"/"===o.subPath?t():this.getZipSync(o.archivePath,e=>r(e,o)):t()}findZip(e){if(this.filter&&!this.filter.test(e))return null;let t="";for(;;){const r=g.exec(e.substr(t.length));if(!r)return null;if(t=this.pathUtils.join(t,r[0]),!1===this.isZip.has(t)){if(this.notZip.has(t))continue;try{if(!this.baseFs.lstatSync(t).isFile()){this.notZip.add(t);continue}}catch(e){return null}this.isZip.add(t)}return{archivePath:t,subPath:this.pathUtils.join(a.LZ.root,e.substr(t.length))}}}limitOpenFiles(e){if(null===this.zipInstances)return;const t=Date.now();let r=t+this.maxAge,A=null===e?0:this.zipInstances.size-e;for(const[n,{zipFs:o,expiresAt:i,refCount:s}]of this.zipInstances.entries())if(0===s&&!o.hasOpenFileHandles())if(t>=i)o.saveAndClose(),this.zipInstances.delete(n),A-=1;else{if(null===e||A<=0){r=i;break}o.saveAndClose(),this.zipInstances.delete(n),A-=1}null===this.limitOpenFilesTimeout&&(null===e&&this.zipInstances.size>0||null!==e)&&(this.limitOpenFilesTimeout=setTimeout(()=>{this.limitOpenFilesTimeout=null,this.limitOpenFiles(null)},r-t).unref())}async getZipPromise(e,t){const r=async()=>({baseFs:this.baseFs,libzip:this.libzip,readOnly:this.readOnlyArchives,stats:await this.baseFs.statPromise(e)});if(this.zipInstances){let A=this.zipInstances.get(e);if(!A){const t=await r();A=this.zipInstances.get(e),A||(A={zipFs:new i.d(e,t),expiresAt:0,refCount:0})}this.zipInstances.delete(e),this.limitOpenFiles(this.maxOpenFiles-1),this.zipInstances.set(e,A),A.expiresAt=Date.now()+this.maxAge,A.refCount+=1;try{return await t(A.zipFs)}finally{A.refCount-=1}}else{const A=new i.d(e,await r());try{return await t(A)}finally{A.saveAndClose()}}}getZipSync(e,t){const r=()=>({baseFs:this.baseFs,libzip:this.libzip,readOnly:this.readOnlyArchives,stats:this.baseFs.statSync(e)});if(this.zipInstances){let A=this.zipInstances.get(e);return A||(A={zipFs:new i.d(e,r()),expiresAt:0,refCount:0}),this.zipInstances.delete(e),this.limitOpenFiles(this.maxOpenFiles-1),this.zipInstances.set(e,A),A.expiresAt=Date.now()+this.maxAge,t(A.zipFs)}{const A=new i.d(e,r());try{return t(A)}finally{A.saveAndClose()}}}}},19697:(e,t,r)=>{"use strict";r.d(t,{a:()=>o});var A=r(26984);class n{constructor(e,t,r={}){this.path=e,this.nextDirent=t,this.opts=r,this.closed=!1}throwIfClosed(){if(this.closed)throw A.Xh()}async*[Symbol.asyncIterator](){try{let e;for(;null!==(e=await this.read());)yield e}finally{await this.close()}}read(e){const t=this.readSync();return void 0!==e?e(null,t):Promise.resolve(t)}readSync(){return this.throwIfClosed(),this.nextDirent()}close(e){return this.closeSync(),void 0!==e?e(null):Promise.resolve()}closeSync(){var e,t;this.throwIfClosed(),null===(t=(e=this.opts).onClose)||void 0===t||t.call(e),this.closed=!0}}function o(e,t,r,A){return new n(t,()=>{const A=r.shift();return void 0===A?null:Object.assign(e.statSync(e.pathUtils.join(t,A)),{name:A})},A)}},38783:(e,t,r)=>{"use strict";r.d(t,{L:()=>u,nd:()=>l,_x:()=>g});var A,n,o=r(28614),i=r(65760);function s(e,t){if(e!==t)throw new Error(`Invalid StatWatcher status: expected '${t}', got '${e}'`)}!function(e){e.Change="change",e.Stop="stop"}(A||(A={})),function(e){e.Ready="ready",e.Running="running",e.Stopped="stopped"}(n||(n={}));class a extends o.EventEmitter{constructor(e,t,{bigint:r=!1}={}){super(),this.status=n.Ready,this.changeListeners=new Map,this.startTimeout=null,this.fakeFs=e,this.path=t,this.bigint=r,this.lastStats=this.stat()}static create(e,t,r){const A=new a(e,t,r);return A.start(),A}start(){s(this.status,n.Ready),this.status=n.Running,this.startTimeout=setTimeout(()=>{this.startTimeout=null,this.fakeFs.existsSync(this.path)||this.emit(A.Change,this.lastStats,this.lastStats)},3)}stop(){s(this.status,n.Running),this.status=n.Stopped,null!==this.startTimeout&&(clearTimeout(this.startTimeout),this.startTimeout=null),this.emit(A.Stop)}stat(){try{return this.fakeFs.statSync(this.path)}catch(e){if("ENOENT"===e.code)return i.makeEmptyStats();throw e}}makeInterval(e){const t=setInterval(()=>{const e=this.stat(),t=this.lastStats;i.areStatsEqual(e,t)||(this.lastStats=e,this.emit(A.Change,e,t))},e.interval);return e.persistent?t:t.unref()}registerChangeListener(e,t){this.addListener(A.Change,e),this.changeListeners.set(e,this.makeInterval(t))}unregisterChangeListener(e){this.removeListener(A.Change,e);const t=this.changeListeners.get(e);void 0!==t&&clearInterval(t),this.changeListeners.delete(e)}unregisterAllChangeListeners(){for(const e of this.changeListeners.keys())this.unregisterChangeListener(e)}hasChangeListeners(){return this.changeListeners.size>0}ref(){for(const e of this.changeListeners.values())e.ref();return this}unref(){for(const e of this.changeListeners.values())e.unref();return this}}const c=new WeakMap;function g(e,t,r,A){let n,o,i,s;switch(typeof r){case"function":n=!1,o=!0,i=5007,s=r;break;default:({bigint:n=!1,persistent:o=!0,interval:i=5007}=r),s=A}let g=c.get(e);void 0===g&&c.set(e,g=new Map);let l=g.get(t);return void 0===l&&(l=a.create(e,t,{bigint:n}),g.set(t,l)),l.registerChangeListener(s,{persistent:o,interval:i}),l}function l(e,t,r){const A=c.get(e);if(void 0===A)return;const n=A.get(t);void 0!==n&&(void 0===r?n.unregisterAllChangeListeners():n.unregisterChangeListener(r),n.hasChangeListeners()||(n.stop(),A.delete(t)))}function u(e){const t=c.get(e);if(void 0!==t)for(const r of t.keys())l(e,r)}},22004:(e,t,r)=>{"use strict";r.d(t,{wK:()=>A,QB:()=>n,Pe:()=>o,Zv:()=>i});const A=61440,n=16384,o=32768,i=40960},26984:(e,t,r)=>{"use strict";function A(e,t){return Object.assign(new Error(`${e}: ${t}`),{code:e})}function n(e){return A("EBUSY",e)}function o(e,t){return A("ENOSYS",`${e}, ${t}`)}function i(e){return A("EINVAL","invalid argument, "+e)}function s(e){return A("EBADF","bad file descriptor, "+e)}function a(e){return A("ENOENT","no such file or directory, "+e)}function c(e){return A("ENOTDIR","not a directory, "+e)}function g(e){return A("EISDIR","illegal operation on a directory, "+e)}function l(e){return A("EEXIST","file already exists, "+e)}function u(e){return A("EROFS","read-only filesystem, "+e)}function h(e){return A("ENOTEMPTY","directory not empty, "+e)}function p(e){return A("EOPNOTSUPP","operation not supported, "+e)}function d(){return A("ERR_DIR_CLOSED","Directory handle was closed")}r.d(t,{Vw:()=>n,bk:()=>o,hq:()=>i,Ch:()=>s,z6:()=>a,Ab:()=>c,GA:()=>g,cT:()=>l,YW:()=>u,re:()=>h,Hs:()=>p,Xh:()=>d,Yn:()=>C});class C extends Error{constructor(e,t){super(e),this.name="Libzip Error",this.code=t}}},43896:(e,t,r)=>{"use strict";r.r(t),r.d(t,{AliasFS:()=>u.K,CwdFS:()=>h.M,DEFAULT_COMPRESSION_LEVEL:()=>l.k,FakeFS:()=>g.uY,Filename:()=>s.QS,JailFS:()=>p.n,LazyFS:()=>d.v,NoFS:()=>f,NodeFS:()=>i.S,PortablePath:()=>s.LZ,PosixFS:()=>I.i,ProxiedFS:()=>E.p,VirtualFS:()=>B.p,ZipFS:()=>l.d,ZipOpenFS:()=>y.A,extendFs:()=>Q,normalizeLineEndings:()=>g.qH,npath:()=>s.cS,opendir:()=>c.a,patchFs:()=>w,ppath:()=>s.y1,statUtils:()=>a,toFilename:()=>s.Zu,xfs:()=>S});var A=r(12087),n=r.n(A),o=r(31669),i=r(78420),s=r(46009),a=r(65760),c=r(19697),g=r(5944),l=r(90739),u=r(14626),h=r(75448),p=r(10489),d=r(15037);const C=()=>Object.assign(new Error("ENOSYS: unsupported filesystem access"),{code:"ENOSYS"});class f extends g.uY{constructor(){super(s.y1)}getExtractHint(){throw C()}getRealPath(){throw C()}resolve(){throw C()}async openPromise(){throw C()}openSync(){throw C()}async opendirPromise(){throw C()}opendirSync(){throw C()}async readPromise(){throw C()}readSync(){throw C()}async writePromise(){throw C()}writeSync(){throw C()}async closePromise(){throw C()}closeSync(){throw C()}createWriteStream(){throw C()}createReadStream(){throw C()}async realpathPromise(){throw C()}realpathSync(){throw C()}async readdirPromise(){throw C()}readdirSync(){throw C()}async existsPromise(e){throw C()}existsSync(e){throw C()}async accessPromise(){throw C()}accessSync(){throw C()}async statPromise(){throw C()}statSync(){throw C()}async lstatPromise(e){throw C()}lstatSync(e){throw C()}async chmodPromise(){throw C()}chmodSync(){throw C()}async chownPromise(){throw C()}chownSync(){throw C()}async mkdirPromise(){throw C()}mkdirSync(){throw C()}async rmdirPromise(){throw C()}rmdirSync(){throw C()}async linkPromise(){throw C()}linkSync(){throw C()}async symlinkPromise(){throw C()}symlinkSync(){throw C()}async renamePromise(){throw C()}renameSync(){throw C()}async copyFilePromise(){throw C()}copyFileSync(){throw C()}async appendFilePromise(){throw C()}appendFileSync(){throw C()}async writeFilePromise(){throw C()}writeFileSync(){throw C()}async unlinkPromise(){throw C()}unlinkSync(){throw C()}async utimesPromise(){throw C()}utimesSync(){throw C()}async readFilePromise(){throw C()}readFileSync(){throw C()}async readlinkPromise(){throw C()}readlinkSync(){throw C()}async truncatePromise(){throw C()}truncateSync(){throw C()}watch(){throw C()}watchFile(){throw C()}unwatchFile(){throw C()}}f.instance=new f;var I=r(39725),E=r(42096),B=r(17674),y=r(53660);function m(e){const t=s.cS.toPortablePath(n().tmpdir()),r=Math.ceil(4294967296*Math.random()).toString(16).padStart(8,"0");return s.y1.join(t,`${e}${r}`)}function w(e,t){const r=new Set(["accessSync","appendFileSync","createReadStream","chmodSync","chownSync","closeSync","copyFileSync","linkSync","lstatSync","lutimesSync","mkdirSync","openSync","opendirSync","readSync","readlinkSync","readFileSync","readdirSync","readlinkSync","realpathSync","renameSync","rmdirSync","statSync","symlinkSync","truncateSync","unlinkSync","unwatchFile","utimesSync","watch","watchFile","writeFileSync","writeSync"]),A=new Set(["accessPromise","appendFilePromise","chmodPromise","chownPromise","closePromise","copyFilePromise","linkPromise","lstatPromise","lutimesPromise","mkdirPromise","openPromise","opendirPromise","readdirPromise","realpathPromise","readFilePromise","readdirPromise","readlinkPromise","renamePromise","rmdirPromise","statPromise","symlinkPromise","truncatePromise","unlinkPromise","utimesPromise","writeFilePromise","writeSync"]),n=new Set(["appendFilePromise","chmodPromise","chownPromise","closePromise","readPromise","readFilePromise","statPromise","truncatePromise","utimesPromise","writePromise","writeFilePromise"]),i=(e,t,r)=>{const A=e[t];e[t]=r,void 0!==(null==A?void 0:A[o.promisify.custom])&&(r[o.promisify.custom]=A[o.promisify.custom])};i(e,"exists",(e,...r)=>{const A="function"==typeof r[r.length-1]?r.pop():()=>{};process.nextTick(()=>{t.existsPromise(e).then(e=>{A(e)},()=>{A(!1)})})}),i(e,"read",(e,r,...A)=>{const n="function"==typeof A[A.length-1]?A.pop():()=>{};process.nextTick(()=>{t.readPromise(e,r,...A).then(e=>{n(null,e,r)},e=>{n(e)})})});for(const r of A){const A=r.replace(/Promise$/,"");if(void 0===e[A])continue;const n=t[r];if(void 0===n)continue;i(e,A,(...e)=>{const r="function"==typeof e[e.length-1]?e.pop():()=>{};process.nextTick(()=>{n.apply(t,e).then(e=>{r(null,e)},e=>{r(e)})})})}e.realpath.native=e.realpath,i(e,"existsSync",e=>{try{return t.existsSync(e)}catch(e){return!1}});for(const A of r){const r=A;if(void 0===e[r])continue;const n=t[A];void 0!==n&&i(e,r,n.bind(t))}e.realpathSync.native=e.realpathSync;{const r=process.emitWarning;let o;process.emitWarning=()=>{};try{o=e.promises}finally{process.emitWarning=r}if(void 0!==o){for(const e of A){const r=e.replace(/Promise$/,"");if(void 0===o[r])continue;const A=t[e];void 0!==A&&("open"!==e&&i(o,r,A.bind(t)))}class e{constructor(e){this.fd=e}}for(const r of n){const A=r.replace(/Promise$/,""),n=t[r];void 0!==n&&i(e.prototype,A,(function(...e){return n.call(t,this.fd,...e)}))}i(o,"open",async(...r)=>{const A=await t.openPromise(...r);return new e(A)})}}e.read[o.promisify.custom]=async(e,r,...A)=>{const n=t.readPromise(e,r,...A);return{bytesRead:await n,buffer:r}}}function Q(e,t){const r=Object.create(e);return w(r,t),r}const D=new Set;let b=!1;function v(){b||(b=!0,process.once("exit",()=>{S.rmtempSync()}))}const S=Object.assign(new i.S,{detachTemp(e){D.delete(e)},mktempSync(e){for(v();;){const t=m("xfs-");try{this.mkdirSync(t)}catch(e){if("EEXIST"===e.code)continue;throw e}const r=this.realpathSync(t);if(D.add(r),void 0===e)return t;try{return e(r)}finally{if(D.has(r)){D.delete(r);try{this.removeSync(r)}catch(e){}}}}},async mktempPromise(e){for(v();;){const t=m("xfs-");try{await this.mkdirPromise(t)}catch(e){if("EEXIST"===e.code)continue;throw e}const r=await this.realpathPromise(t);if(D.add(r),void 0===e)return r;try{return await e(r)}finally{if(D.has(r)){D.delete(r);try{await this.removePromise(r)}catch(e){}}}}},async rmtempPromise(){await Promise.all(Array.from(D.values()).map(async e=>{try{await S.removePromise(e,{maxRetries:0}),D.delete(e)}catch(e){}}))},rmtempSync(){for(const e of D)try{S.removeSync(e),D.delete(e)}catch(e){}}})},46009:(e,t,r)=>{"use strict";r.d(t,{LZ:()=>i,QS:()=>s,cS:()=>a,y1:()=>c,CI:()=>f,Zu:()=>I});var A,n=r(85622),o=r.n(n);!function(e){e[e.File=0]="File",e[e.Portable=1]="Portable",e[e.Native=2]="Native"}(A||(A={}));const i={root:"/",dot:"."},s={nodeModules:"node_modules",manifest:"package.json",lockfile:"yarn.lock",pnpJs:".pnp.js",rc:".yarnrc.yml"},a=Object.create(o()),c=Object.create(o().posix);a.cwd=()=>process.cwd(),c.cwd=()=>C(process.cwd()),c.resolve=(...e)=>e.length>0&&c.isAbsolute(e[0])?o().posix.resolve(...e):o().posix.resolve(c.cwd(),...e);const g=function(e,t,r){return(t=e.normalize(t))===(r=e.normalize(r))?".":(t.endsWith(e.sep)||(t+=e.sep),r.startsWith(t)?r.slice(t.length):null)};a.fromPortablePath=d,a.toPortablePath=C,a.contains=(e,t)=>g(a,e,t),c.contains=(e,t)=>g(c,e,t);const l=/^([a-zA-Z]:.*)$/,u=/^\\\\(\.\\)?(.*)$/,h=/^\/([a-zA-Z]:.*)$/,p=/^\/unc\/(\.dot\/)?(.*)$/;function d(e){if("win32"!==process.platform)return e;if(e.match(h))e=e.replace(h,"$1");else{if(!e.match(p))return e;e=e.replace(p,(e,t,r)=>`\\\\${t?".\\":""}${r}`)}return e.replace(/\//g,"\\")}function C(e){return"win32"!==process.platform?e:(e.match(l)?e=e.replace(l,"/$1"):e.match(u)&&(e=e.replace(u,(e,t,r)=>`/unc/${t?".dot/":""}${r}`)),e.replace(/\\/g,"/"))}function f(e,t){return e===a?d(t):C(t)}function I(e){if(""!==a.parse(e).dir||""!==c.parse(e).dir)throw new Error(`Invalid filename: "${e}"`);return e}},65760:(e,t,r)=>{"use strict";r.r(t),r.d(t,{DirEntry:()=>n,StatEntry:()=>o,makeDefaultStats:()=>i,makeEmptyStats:()=>s,areStatsEqual:()=>a});var A=r(22004);class n{constructor(){this.name="",this.mode=0}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&A.wK)===A.QB}isFIFO(){return!1}isFile(){return(this.mode&A.wK)===A.Pe}isSocket(){return!1}isSymbolicLink(){return(this.mode&A.wK)===A.Zv}}class o{constructor(){this.dev=0,this.ino=0,this.mode=0,this.nlink=1,this.rdev=0,this.blocks=1}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&A.wK)===A.QB}isFIFO(){return!1}isFile(){return(this.mode&A.wK)===A.Pe}isSocket(){return!1}isSymbolicLink(){return(this.mode&A.wK)===A.Zv}}function i(){return Object.assign(new o,{uid:0,gid:0,size:0,blksize:0,atimeMs:0,mtimeMs:0,ctimeMs:0,birthtimeMs:0,atime:new Date(0),mtime:new Date(0),ctime:new Date(0),birthtime:new Date(0),mode:420|A.Pe})}function s(){return Object.assign(i(),{nlink:0,blocks:0,mode:0})}function a(e,t){return e.atimeMs===t.atimeMs&&(e.birthtimeMs===t.birthtimeMs&&(e.blksize===t.blksize&&(e.blocks===t.blocks&&(e.ctimeMs===t.ctimeMs&&(e.dev===t.dev&&(e.gid===t.gid&&(e.ino===t.ino&&(e.isBlockDevice()===t.isBlockDevice()&&(e.isCharacterDevice()===t.isCharacterDevice()&&(e.isDirectory()===t.isDirectory()&&(e.isFIFO()===t.isFIFO()&&(e.isFile()===t.isFile()&&(e.isSocket()===t.isSocket()&&(e.isSymbolicLink()===t.isSymbolicLink()&&(e.mode===t.mode&&(e.mtimeMs===t.mtimeMs&&(e.nlink===t.nlink&&(e.rdev===t.rdev&&(e.size===t.size&&e.uid===t.uid)))))))))))))))))))}},65281:(e,t,r)=>{"use strict";r.r(t),r.d(t,{getLibzipPromise:()=>s,getLibzipSync:()=>i});const A=["number","number"];var n;!function(e){e[e.ZIP_ER_OK=0]="ZIP_ER_OK",e[e.ZIP_ER_MULTIDISK=1]="ZIP_ER_MULTIDISK",e[e.ZIP_ER_RENAME=2]="ZIP_ER_RENAME",e[e.ZIP_ER_CLOSE=3]="ZIP_ER_CLOSE",e[e.ZIP_ER_SEEK=4]="ZIP_ER_SEEK",e[e.ZIP_ER_READ=5]="ZIP_ER_READ",e[e.ZIP_ER_WRITE=6]="ZIP_ER_WRITE",e[e.ZIP_ER_CRC=7]="ZIP_ER_CRC",e[e.ZIP_ER_ZIPCLOSED=8]="ZIP_ER_ZIPCLOSED",e[e.ZIP_ER_NOENT=9]="ZIP_ER_NOENT",e[e.ZIP_ER_EXISTS=10]="ZIP_ER_EXISTS",e[e.ZIP_ER_OPEN=11]="ZIP_ER_OPEN",e[e.ZIP_ER_TMPOPEN=12]="ZIP_ER_TMPOPEN",e[e.ZIP_ER_ZLIB=13]="ZIP_ER_ZLIB",e[e.ZIP_ER_MEMORY=14]="ZIP_ER_MEMORY",e[e.ZIP_ER_CHANGED=15]="ZIP_ER_CHANGED",e[e.ZIP_ER_COMPNOTSUPP=16]="ZIP_ER_COMPNOTSUPP",e[e.ZIP_ER_EOF=17]="ZIP_ER_EOF",e[e.ZIP_ER_INVAL=18]="ZIP_ER_INVAL",e[e.ZIP_ER_NOZIP=19]="ZIP_ER_NOZIP",e[e.ZIP_ER_INTERNAL=20]="ZIP_ER_INTERNAL",e[e.ZIP_ER_INCONS=21]="ZIP_ER_INCONS",e[e.ZIP_ER_REMOVE=22]="ZIP_ER_REMOVE",e[e.ZIP_ER_DELETED=23]="ZIP_ER_DELETED",e[e.ZIP_ER_ENCRNOTSUPP=24]="ZIP_ER_ENCRNOTSUPP",e[e.ZIP_ER_RDONLY=25]="ZIP_ER_RDONLY",e[e.ZIP_ER_NOPASSWD=26]="ZIP_ER_NOPASSWD",e[e.ZIP_ER_WRONGPASSWD=27]="ZIP_ER_WRONGPASSWD",e[e.ZIP_ER_OPNOTSUPP=28]="ZIP_ER_OPNOTSUPP",e[e.ZIP_ER_INUSE=29]="ZIP_ER_INUSE",e[e.ZIP_ER_TELL=30]="ZIP_ER_TELL",e[e.ZIP_ER_COMPRESSED_DATA=31]="ZIP_ER_COMPRESSED_DATA"}(n||(n={}));let o=null;function i(){var e;return null===o&&(e=r(3368),o={get HEAP8(){return e.HEAP8},get HEAPU8(){return e.HEAPU8},errors:n,SEEK_SET:0,SEEK_CUR:1,SEEK_END:2,ZIP_CHECKCONS:4,ZIP_CREATE:1,ZIP_EXCL:2,ZIP_TRUNCATE:8,ZIP_RDONLY:16,ZIP_FL_OVERWRITE:8192,ZIP_FL_COMPRESSED:4,ZIP_OPSYS_DOS:0,ZIP_OPSYS_AMIGA:1,ZIP_OPSYS_OPENVMS:2,ZIP_OPSYS_UNIX:3,ZIP_OPSYS_VM_CMS:4,ZIP_OPSYS_ATARI_ST:5,ZIP_OPSYS_OS_2:6,ZIP_OPSYS_MACINTOSH:7,ZIP_OPSYS_Z_SYSTEM:8,ZIP_OPSYS_CPM:9,ZIP_OPSYS_WINDOWS_NTFS:10,ZIP_OPSYS_MVS:11,ZIP_OPSYS_VSE:12,ZIP_OPSYS_ACORN_RISC:13,ZIP_OPSYS_VFAT:14,ZIP_OPSYS_ALTERNATE_MVS:15,ZIP_OPSYS_BEOS:16,ZIP_OPSYS_TANDEM:17,ZIP_OPSYS_OS_400:18,ZIP_OPSYS_OS_X:19,ZIP_CM_DEFAULT:-1,ZIP_CM_STORE:0,ZIP_CM_DEFLATE:8,uint08S:e._malloc(1),uint16S:e._malloc(2),uint32S:e._malloc(4),uint64S:e._malloc(8),malloc:e._malloc,free:e._free,getValue:e.getValue,open:e.cwrap("zip_open","number",["string","number","number"]),openFromSource:e.cwrap("zip_open_from_source","number",["number","number","number"]),close:e.cwrap("zip_close","number",["number"]),discard:e.cwrap("zip_discard",null,["number"]),getError:e.cwrap("zip_get_error","number",["number"]),getName:e.cwrap("zip_get_name","string",["number","number","number"]),getNumEntries:e.cwrap("zip_get_num_entries","number",["number","number"]),delete:e.cwrap("zip_delete","number",["number","number"]),stat:e.cwrap("zip_stat","number",["number","string","number","number"]),statIndex:e.cwrap("zip_stat_index","number",["number",...A,"number","number"]),fopen:e.cwrap("zip_fopen","number",["number","string","number"]),fopenIndex:e.cwrap("zip_fopen_index","number",["number",...A,"number"]),fread:e.cwrap("zip_fread","number",["number","number","number","number"]),fclose:e.cwrap("zip_fclose","number",["number"]),dir:{add:e.cwrap("zip_dir_add","number",["number","string"])},file:{add:e.cwrap("zip_file_add","number",["number","string","number","number"]),getError:e.cwrap("zip_file_get_error","number",["number"]),getExternalAttributes:e.cwrap("zip_file_get_external_attributes","number",["number",...A,"number","number","number"]),setExternalAttributes:e.cwrap("zip_file_set_external_attributes","number",["number",...A,"number","number","number"]),setMtime:e.cwrap("zip_file_set_mtime","number",["number",...A,"number","number"]),setCompression:e.cwrap("zip_set_file_compression","number",["number",...A,"number","number"])},ext:{countSymlinks:e.cwrap("zip_ext_count_symlinks","number",["number"])},error:{initWithCode:e.cwrap("zip_error_init_with_code",null,["number","number"]),strerror:e.cwrap("zip_error_strerror","string",["number"])},name:{locate:e.cwrap("zip_name_locate","number",["number","string","number"])},source:{fromUnattachedBuffer:e.cwrap("zip_source_buffer_create","number",["number","number","number","number"]),fromBuffer:e.cwrap("zip_source_buffer","number",["number","number",...A,"number"]),free:e.cwrap("zip_source_free",null,["number"]),keep:e.cwrap("zip_source_keep",null,["number"]),open:e.cwrap("zip_source_open","number",["number"]),close:e.cwrap("zip_source_close","number",["number"]),seek:e.cwrap("zip_source_seek","number",["number",...A,"number"]),tell:e.cwrap("zip_source_tell","number",["number"]),read:e.cwrap("zip_source_read","number",["number","number","number"]),error:e.cwrap("zip_source_error","number",["number"]),setMtime:e.cwrap("zip_source_set_mtime","number",["number","number"])},struct:{stat:e.cwrap("zipstruct_stat","number",[]),statS:e.cwrap("zipstruct_statS","number",[]),statName:e.cwrap("zipstruct_stat_name","string",["number"]),statIndex:e.cwrap("zipstruct_stat_index","number",["number"]),statSize:e.cwrap("zipstruct_stat_size","number",["number"]),statCompSize:e.cwrap("zipstruct_stat_comp_size","number",["number"]),statCompMethod:e.cwrap("zipstruct_stat_comp_method","number",["number"]),statMtime:e.cwrap("zipstruct_stat_mtime","number",["number"]),error:e.cwrap("zipstruct_error","number",[]),errorS:e.cwrap("zipstruct_errorS","number",[]),errorCodeZip:e.cwrap("zipstruct_error_code_zip","number",["number"])}}),o}async function s(){return i()}},11640:(e,t,r)=>{"use strict";r.r(t),r.d(t,{parseResolution:()=>i,parseShell:()=>n,parseSyml:()=>I,stringifyResolution:()=>s,stringifySyml:()=>d});var A=r(92962);function n(e,t={isGlobPattern:()=>!1}){try{return(0,A.parse)(e,t)}catch(e){throw e.location&&(e.message=e.message.replace(/(\.)?$/,` (line ${e.location.start.line}, column ${e.location.start.column})$1`)),e}}var o=r(98261);function i(e){const t=e.match(/^\*{1,2}\/(.*)/);if(t)throw new Error(`The override for '${e}' includes a glob pattern. Glob patterns have been removed since their behaviours don't match what you'd expect. Set the override to '${t[1]}' instead.`);try{return(0,o.parse)(e)}catch(e){throw e.location&&(e.message=e.message.replace(/(\.)?$/,` (line ${e.location.start.line}, column ${e.location.start.column})$1`)),e}}function s(e){let t="";return e.from&&(t+=e.from.fullName,e.from.description&&(t+="@"+e.from.description),t+="/"),t+=e.descriptor.fullName,e.descriptor.description&&(t+="@"+e.descriptor.description),t}var a=r(21194),c=r(85443);const g=/^(?![-?:,\][{}#&*!|>'"%@` \t\r\n]).([ \t]*(?![,\][{}:# \t\r\n]).)*$/,l=["__metadata","version","resolution","dependencies","peerDependencies","dependenciesMeta","peerDependenciesMeta","binaries"];class u{constructor(e){this.data=e}}function h(e){return e.match(g)?e:JSON.stringify(e)}function p(e,t,r){if(null===e)return"null\n";if("number"==typeof e||"boolean"==typeof e)return e.toString()+"\n";if("string"==typeof e)return h(e)+"\n";if(Array.isArray(e)){if(0===e.length)return"[]\n";const r=" ".repeat(t);return"\n"+e.map(e=>`${r}- ${p(e,t+1,!1)}`).join("")}if("object"==typeof e&&e){let A,n;e instanceof u?(A=e.data,n=!1):(A=e,n=!0);const o=" ".repeat(t),i=Object.keys(A);n&&i.sort((e,t)=>{const r=l.indexOf(e),A=l.indexOf(t);return-1===r&&-1===A?et?1:0:-1!==r&&-1===A?-1:-1===r&&-1!==A?1:r-A});const s=i.filter(e=>!function e(t){return void 0===t||"object"==typeof t&&null!==t&&Object.keys(t).every(r=>e(t[r]))}(A[e])).map((e,n)=>{const i=A[e],s=h(e),a=p(i,t+1,!0),c=n>0||r?o:"";return a.startsWith("\n")?`${c}${s}:${a}`:`${c}${s}: ${a}`}).join(0===t?"\n":"")||"\n";return r?"\n"+s:""+s}throw new Error(`Unsupported value type (${e})`)}function d(e){try{const t=p(e,0,!1);return"\n"!==t?t:""}catch(e){throw e.location&&(e.message=e.message.replace(/(\.)?$/,` (line ${e.location.start.line}, column ${e.location.start.column})$1`)),e}}d.PreserveOrdering=u;const C=/^(#.*(\r?\n))*?#\s+yarn\s+lockfile\s+v1\r?\n/i;function f(e){if(C.test(e))return function(e){return e.endsWith("\n")||(e+="\n"),(0,c.parse)(e)}(e);const t=(0,a.safeLoad)(e,{schema:a.FAILSAFE_SCHEMA});if(null==t)return{};if("object"!=typeof t)throw new Error(`Expected an indexed object, got a ${typeof t} instead. Does your file follow Yaml's rules?`);if(Array.isArray(t))throw new Error("Expected an indexed object, got an array instead. Does your file follow Yaml's rules?");return t}function I(e){return f(e)}},34432:(e,t,r)=>{"use strict";var A,n;r.d(t,{gY:()=>E,Q$:()=>B,oC:()=>F}),function(e){e.HARD="HARD",e.SOFT="SOFT"}(A||(A={})),function(e){e.DEFAULT="DEFAULT",e.TOP_LEVEL="TOP_LEVEL",e.FALLBACK_EXCLUSION_LIST="FALLBACK_EXCLUSION_LIST",e.FALLBACK_EXCLUSION_ENTRIES="FALLBACK_EXCLUSION_ENTRIES",e.FALLBACK_EXCLUSION_DATA="FALLBACK_EXCLUSION_DATA",e.PACKAGE_REGISTRY_DATA="PACKAGE_REGISTRY_DATA",e.PACKAGE_REGISTRY_ENTRIES="PACKAGE_REGISTRY_ENTRIES",e.PACKAGE_STORE_DATA="PACKAGE_STORE_DATA",e.PACKAGE_STORE_ENTRIES="PACKAGE_STORE_ENTRIES",e.PACKAGE_INFORMATION_DATA="PACKAGE_INFORMATION_DATA",e.PACKAGE_DEPENDENCIES="PACKAGE_DEPENDENCIES",e.PACKAGE_DEPENDENCY="PACKAGE_DEPENDENCY"}(n||(n={}));const o={[n.DEFAULT]:{collapsed:!1,next:{"*":n.DEFAULT}},[n.TOP_LEVEL]:{collapsed:!1,next:{fallbackExclusionList:n.FALLBACK_EXCLUSION_LIST,packageRegistryData:n.PACKAGE_REGISTRY_DATA,"*":n.DEFAULT}},[n.FALLBACK_EXCLUSION_LIST]:{collapsed:!1,next:{"*":n.FALLBACK_EXCLUSION_ENTRIES}},[n.FALLBACK_EXCLUSION_ENTRIES]:{collapsed:!0,next:{"*":n.FALLBACK_EXCLUSION_DATA}},[n.FALLBACK_EXCLUSION_DATA]:{collapsed:!0,next:{"*":n.DEFAULT}},[n.PACKAGE_REGISTRY_DATA]:{collapsed:!1,next:{"*":n.PACKAGE_REGISTRY_ENTRIES}},[n.PACKAGE_REGISTRY_ENTRIES]:{collapsed:!0,next:{"*":n.PACKAGE_STORE_DATA}},[n.PACKAGE_STORE_DATA]:{collapsed:!1,next:{"*":n.PACKAGE_STORE_ENTRIES}},[n.PACKAGE_STORE_ENTRIES]:{collapsed:!0,next:{"*":n.PACKAGE_INFORMATION_DATA}},[n.PACKAGE_INFORMATION_DATA]:{collapsed:!1,next:{packageDependencies:n.PACKAGE_DEPENDENCIES,"*":n.DEFAULT}},[n.PACKAGE_DEPENDENCIES]:{collapsed:!1,next:{"*":n.PACKAGE_DEPENDENCY}},[n.PACKAGE_DEPENDENCY]:{collapsed:!0,next:{"*":n.DEFAULT}}};function i(e,t,r,A){const{next:n}=o[r];return s(t,n[e]||n["*"],A)}function s(e,t,r){const{collapsed:A}=o[t];return Array.isArray(e)?A?function(e,t,r){let A="";A+="[";for(let n=0,o=e.length;ne(t)));const n=r.map((e,t)=>t);return n.sort((e,t)=>{for(const r of A){const A=r[e]r[t]?1:0;if(0!==A)return A}return 0}),n.map(e=>r[e])}function g(e){const t=new Map,r=c(e.fallbackExclusionList||[],[({name:e,reference:t})=>e,({name:e,reference:t})=>t]);for(const{name:e,reference:A}of r){let r=t.get(e);void 0===r&&t.set(e,r=new Set),r.add(A)}return Array.from(t).map(([e,t])=>[e,Array.from(t)])}function l(e){return c(e.fallbackPool||[],([e])=>e)}function u(e){const t=[];for(const[r,A]of c(e.packageRegistry,([e])=>null===e?"0":"1"+e)){const e=[];t.push([r,e]);for(const[t,{packageLocation:n,packageDependencies:o,packagePeers:i,linkType:s,discardFromLookup:a}]of c(A,([e])=>null===e?"0":"1"+e)){const A=[];null===r||null===t||o.has(r)||A.push([r,t]);for(const[e,t]of c(o.entries(),([e])=>e))A.push([e,t]);const g=i&&i.size>0?Array.from(i):void 0,l=a||void 0;e.push([t,{packageLocation:n,packageDependencies:A,packagePeers:g,linkType:s,discardFromLookup:l}])}}return t}function h(e){return c(e.blacklistedLocations||[],e=>e)}function p(e){return{__info:["This file is automatically generated. Do not touch it, or risk","your modifications being lost. We also recommend you not to read","it either without using the @yarnpkg/pnp package, as the data layout","is entirely unspecified and WILL change from a version to another."],dependencyTreeRoots:e.dependencyTreeRoots,enableTopLevelFallback:e.enableTopLevelFallback||!1,ignorePatternData:e.ignorePattern||null,fallbackExclusionList:g(e),fallbackPool:l(e),locationBlacklistData:h(e),packageRegistryData:u(e)}}var d=r(20103),C=r.n(d);function f(e,t){return[e?e+"\n":"","/* eslint-disable */\n\n","try {\n"," Object.freeze({}).detectStrictMode = true;\n","} catch (error) {\n"," throw new Error(`The whole PnP file got strict-mode-ified, which is known to break (Emscripten libraries aren't strict mode). This usually happens when the file goes through Babel.`);\n","}\n","\n","var __non_webpack_module__ = module;\n","\n","function $$SETUP_STATE(hydrateRuntimeState, basePath) {\n",t.replace(/^/gm," "),"}\n","\n",C()()].join("")}function I(e){return JSON.stringify(e,null,2)}function E(e){const t=function(e){return[`return hydrateRuntimeState(${a(e)}, {basePath: basePath || __dirname});\n`].join("")}(p(e));return f(e.shebang,t)}function B(e){const t=p(e),r=(A=e.dataLocation,["var path = require('path');\n",`var dataLocation = path.resolve(__dirname, ${JSON.stringify(A)});\n`,"return hydrateRuntimeState(require(dataLocation), {basePath: basePath || path.dirname(dataLocation)});\n"].join(""));var A;const n=f(e.shebang,r);return{dataFile:I(t),loaderFile:n}}var y=r(35747),m=(r(85622),r(31669)),w=r(46009);var Q,D=r(17674),b=r(32282);!function(e){e.API_ERROR="API_ERROR",e.BLACKLISTED="BLACKLISTED",e.BUILTIN_NODE_RESOLUTION_FAILED="BUILTIN_NODE_RESOLUTION_FAILED",e.MISSING_DEPENDENCY="MISSING_DEPENDENCY",e.MISSING_PEER_DEPENDENCY="MISSING_PEER_DEPENDENCY",e.QUALIFIED_PATH_RESOLUTION_FAILED="QUALIFIED_PATH_RESOLUTION_FAILED",e.INTERNAL="INTERNAL",e.UNDECLARED_DEPENDENCY="UNDECLARED_DEPENDENCY",e.UNSUPPORTED="UNSUPPORTED"}(Q||(Q={}));const v=new Set([Q.BLACKLISTED,Q.BUILTIN_NODE_RESOLUTION_FAILED,Q.MISSING_DEPENDENCY,Q.MISSING_PEER_DEPENDENCY,Q.QUALIFIED_PATH_RESOLUTION_FAILED,Q.UNDECLARED_DEPENDENCY]);function S(e,t,r={}){const A=v.has(e)?"MODULE_NOT_FOUND":e,n={configurable:!0,writable:!0,enumerable:!1};return Object.defineProperties(new Error(t),{code:{...n,value:A},pnpCode:{...n,value:e},data:{...n,value:r}})}function k(e){return w.cS.normalize(w.cS.fromPortablePath(e))}function N(e,t){const r=Number(process.env.PNP_ALWAYS_WARN_ON_FALLBACK)>0,A=Number(process.env.PNP_DEBUG_LEVEL),n=new Set(b.Module.builtinModules||Object.keys(process.binding("natives"))),o=/^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:@[^/]+\/)?[^/]+)\/*(.*|)$/,i=/^(\/|\.{1,2}(\/|$))/,s=/\/$/,a={name:null,reference:null},c=[],g=new Set;if(!0===e.enableTopLevelFallback&&c.push(a),!1!==t.compatibilityMode)for(const t of["react-scripts","gatsby"]){const r=e.packageRegistry.get(t);if(r)for(const e of r.keys()){if(null===e)throw new Error("Assertion failed: This reference shouldn't be null");c.push({name:t,reference:e})}}const{ignorePattern:l,packageRegistry:u,packageLocatorsByLocations:h,packageLocationLengths:p}=e;function d(e,t){return{fn:e,args:t,error:null,result:null}}function C(e,r){if(!1===t.allowDebug)return r;if(Number.isFinite(A)){if(A>=2)return(...t)=>{const A=d(e,t);try{return A.result=r(...t)}catch(e){throw A.error=e}finally{console.trace(A)}};if(A>=1)return(...t)=>{try{return r(...t)}catch(r){const A=d(e,t);throw A.error=r,console.trace(A),r}}}return r}function f(e){const t=y(e);if(!t)throw S(Q.INTERNAL,"Couldn't find a matching entry in the dependency tree for the specified parent (this is probably an internal error)");return t}function I(t){if(null===t.name)return!0;for(const r of e.dependencyTreeRoots)if(r.name===t.name&&r.reference===t.reference)return!0;return!1}function E(e,t){return t.endsWith("/")&&(t=w.y1.join(t,"internal.js")),b.Module._resolveFilename(w.cS.fromPortablePath(e),function(e){const t=new b.Module(e,null);return t.filename=e,t.paths=b.Module._nodeModulePaths(e),t}(w.cS.fromPortablePath(t)),!1,{plugnplay:!1})}function B(t){if(null===l)return!1;const r=w.y1.contains(e.basePath,t);return null!==r&&!!l.test(r.replace(/\/$/,""))}function y({name:e,reference:t}){const r=u.get(e);if(!r)return null;const A=r.get(t);return A||null}function m(e,t){const r=new Map,A=new Set,n=t=>{const o=JSON.stringify(t.name);if(A.has(o))return;A.add(o);const i=function({name:e,reference:t}){const r=[];for(const[A,n]of u)if(null!==A)for(const[o,i]of n){if(null===o)continue;i.packageDependencies.get(e)===t&&(A===e&&o===t||r.push({name:A,reference:o}))}return r}(t);for(const t of i){if(f(t).packagePeers.has(e))n(t);else{let e=r.get(t.name);void 0===e&&r.set(t.name,e=new Set),e.add(t.reference)}}};n(t);const o=[];for(const e of[...r.keys()].sort())for(const t of[...r.get(e)].sort())o.push({name:e,reference:t});return o}function v(t){if(B(t))return null;let r=(A=w.y1.relative(e.basePath,t),w.cS.toPortablePath(A));var A;r.match(i)||(r="./"+r),t.match(s)&&!r.endsWith("/")&&(r+="/");let n=0;for(;nr.length;)n+=1;for(let e=n;eI(e))?S(Q.MISSING_PEER_DEPENDENCY,`${s.name} tried to access ${t} (a peer dependency) but it isn't provided by your application; this makes the require call ambiguous and unsound.\n\nRequired package: ${t} (via "${l}")\nRequired by: ${s.name}@${s.reference} (via ${u})\n${e.map(e=>`Ancestor breaking the chain: ${e.name}@${e.reference}\n`).join("")}\n`,{request:l,issuer:u,issuerLocator:Object.assign({},s),dependencyName:t,brokenAncestors:e}):S(Q.MISSING_PEER_DEPENDENCY,`${s.name} tried to access ${t} (a peer dependency) but it isn't provided by its ancestors; this makes the require call ambiguous and unsound.\n\nRequired package: ${t} (via "${l}")\nRequired by: ${s.name}@${s.reference} (via ${u})\n${e.map(e=>`Ancestor breaking the chain: ${e.name}@${e.reference}\n`).join("")}\n`,{request:l,issuer:u,issuerLocator:Object.assign({},s),dependencyName:t,brokenAncestors:e})}else void 0===d&&(B=!a&&n.has(A)?I(s)?S(Q.UNDECLARED_DEPENDENCY,`Your application tried to access ${t}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${t} isn't otherwise declared in your dependencies, this makes the require call ambiguous and unsound.\n\nRequired package: ${t} (via "${l}")\nRequired by: ${u}\n`,{request:l,issuer:u,dependencyName:t}):S(Q.UNDECLARED_DEPENDENCY,`${s.name} tried to access ${t}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${t} isn't otherwise declared in ${s.name}'s dependencies, this makes the require call ambiguous and unsound.\n\nRequired package: ${t} (via "${l}")\nRequired by: ${u}\n`,{request:l,issuer:u,issuerLocator:Object.assign({},s),dependencyName:t}):I(s)?S(Q.UNDECLARED_DEPENDENCY,`Your application tried to access ${t}, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound.\n\nRequired package: ${t} (via "${l}")\nRequired by: ${u}\n`,{request:l,issuer:u,dependencyName:t}):S(Q.UNDECLARED_DEPENDENCY,`${s.name} tried to access ${t}, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound.\n\nRequired package: ${t} (via "${l}")\nRequired by: ${s.name}@${s.reference} (via ${u})\n`,{request:l,issuer:u,issuerLocator:Object.assign({},s),dependencyName:t}));if(null==d){if(null===C||null===B)throw B||new Error("Assertion failed: Expected an error to have been set");d=C;const e=B.message.replace(/\n.*/g,"");B.message=e,g.has(e)||(g.add(e),process.emitWarning(B))}const y=Array.isArray(d)?{name:d[0],reference:d[1]}:{name:t,reference:d},D=f(y);if(!D.packageLocation)throw S(Q.MISSING_DEPENDENCY,`A dependency seems valid but didn't get installed for some reason. This might be caused by a partial install, such as dev vs prod.\n\nRequired package: ${y.name}@${y.reference} (via "${l}")\nRequired by: ${s.name}@${s.reference} (via ${u})\n`,{request:l,issuer:u,dependencyLocator:Object.assign({},y)});const b=D.packageLocation;h=o?w.y1.join(b,o):b}else{if(w.y1.isAbsolute(A))h=w.y1.normalize(A);else{if(!i)throw S(Q.API_ERROR,"The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute",{request:l,issuer:u});const e=w.y1.resolve(i);h=i.match(s)?w.y1.normalize(w.y1.join(e,A)):w.y1.normalize(w.y1.join(w.y1.dirname(e),A))}v(h)}return w.y1.normalize(h)}function F(e,{extensions:r=Object.keys(b.Module._extensions)}={}){const A=[],n=function e(r,A,{extensions:n}){let o;try{A.push(r),o=t.fakeFs.statSync(r)}catch(e){}if(o&&!o.isDirectory())return t.fakeFs.realpathSync(r);if(o&&o.isDirectory()){let o,i;try{o=JSON.parse(t.fakeFs.readFileSync(w.y1.join(r,"package.json"),"utf8"))}catch(e){}if(o&&o.main&&(i=w.y1.resolve(r,o.main)),i&&i!==r){const t=e(i,A,{extensions:n});if(null!==t)return t}}for(let e=0,o=n.length;e`Rejected candidate: ${k(e)}\n`).join("")}`,{unqualifiedPath:t})}}return{VERSIONS:{std:3,resolveVirtual:1,getAllLocators:1},topLevel:a,getLocator:(e,t)=>Array.isArray(t)?{name:t[0],reference:t[1]}:{name:e,reference:t},getDependencyTreeRoots:()=>[...e.dependencyTreeRoots],getAllLocators(){const e=[];for(const[t,r]of u)for(const A of r.keys())null!==t&&null!==A&&e.push({name:t,reference:A});return e},getPackageInformation:e=>{const t=y(e);if(null===t)return null;const r=w.cS.fromPortablePath(t.packageLocation);return{...t,packageLocation:r}},findPackageLocator:e=>v(w.cS.toPortablePath(e)),resolveToUnqualified:C("resolveToUnqualified",(e,t,r)=>{const A=null!==t?w.cS.toPortablePath(t):null,n=N(w.cS.toPortablePath(e),A,r);return null===n?null:w.cS.fromPortablePath(n)}),resolveUnqualified:C("resolveUnqualified",(e,t)=>w.cS.fromPortablePath(F(w.cS.toPortablePath(e),t))),resolveRequest:C("resolveRequest",(e,t,r)=>{const A=null!==t?w.cS.toPortablePath(t):null,n=function(e,t,{considerBuiltins:r,extensions:A}={}){const n=N(e,t,{considerBuiltins:r});if(null===n)return null;try{return F(n,{extensions:A})}catch(r){throw"QUALIFIED_PATH_RESOLUTION_FAILED"===r.pnpCode&&Object.assign(r.data,{request:k(e),issuer:t&&k(t)}),r}}(w.cS.toPortablePath(e),A,r);return null===n?null:w.cS.fromPortablePath(n)}),resolveVirtual:C("resolveVirtual",e=>{const t=function(e){const t=w.y1.normalize(e),r=D.p.resolveVirtual(t);return r!==t?r:null}(w.cS.toPortablePath(e));return null!==t?w.cS.fromPortablePath(t):null})}}(0,m.promisify)(y.readFile);const F=(e,t,r)=>N(function(e,{basePath:t}){const r=w.cS.toPortablePath(t),A=w.y1.resolve(r),n=null!==e.ignorePatternData?new RegExp(e.ignorePatternData):null,o=new Map(e.packageRegistryData.map(([e,t])=>[e,new Map(t.map(([e,t])=>[e,{packageLocation:w.y1.join(A,t.packageLocation),packageDependencies:new Map(t.packageDependencies),packagePeers:new Set(t.packagePeers),linkType:t.linkType,discardFromLookup:t.discardFromLookup||!1}]))])),i=new Map,s=new Set;for(const[t,r]of e.packageRegistryData)for(const[e,A]of r){if(null===t!=(null===e))throw new Error("Assertion failed: The name and reference should be null, or neither should");if(A.discardFromLookup)continue;const r={name:t,reference:e};i.set(A.packageLocation,r),s.add(A.packageLocation.length)}for(const t of e.locationBlacklistData)i.set(t,null);const a=new Map(e.fallbackExclusionList.map(([e,t])=>[e,new Set(t)])),c=new Map(e.fallbackPool);return{basePath:r,dependencyTreeRoots:e.dependencyTreeRoots,enableTopLevelFallback:e.enableTopLevelFallback,fallbackExclusionList:a,fallbackPool:c,ignorePattern:n,packageLocationLengths:[...s].sort((e,t)=>t-e),packageLocatorsByLocations:i,packageRegistry:o}}(p(e),{basePath:t}),{fakeFs:r,pnpapiResolution:w.cS.join(t,".pnp.js")})},76756:(e,t,r)=>{"use strict";r.r(t),r.d(t,{ShellError:()=>c,execute:()=>Z,globUtils:()=>A});var A={};r.r(A),r.d(A,{fastGlobOptions:()=>E,isBraceExpansion:()=>m,isGlobPattern:()=>B,match:()=>y,micromatchOptions:()=>I});var n=r(46009),o=r(78420),i=r(11640),s=r(12087),a=r(92413);class c extends Error{constructor(e){super(e),this.name="ShellError"}}var g=r(43896),l=r(39725),u=r(19347),h=r.n(u),p=r(35747),d=r.n(p),C=r(2401),f=r.n(C);const I={strictBrackets:!0},E={onlyDirectories:!1,onlyFiles:!1};function B(e){if(!f().scan(e,I).isGlob)return!1;try{f().parse(e,I)}catch(e){return!1}return!0}function y(e,{cwd:t,baseFs:r}){return h()(e,{...E,cwd:n.cS.fromPortablePath(t),fs:(0,g.extendFs)(d(),new l.i(r))})}function m(e){return f().scan(e,I).isBrace}var w,Q=r(67566),D=r.n(Q);function b(){}!function(e){e[e.STDIN=0]="STDIN",e[e.STDOUT=1]="STDOUT",e[e.STDERR=2]="STDERR"}(w||(w={}));let v=0;class S{constructor(e){this.stream=e}close(){}get(){return this.stream}}class k{constructor(){this.stream=null}close(){if(null===this.stream)throw new Error("Assertion failed: No stream attached");this.stream.end()}attach(e){this.stream=e}get(){if(null===this.stream)throw new Error("Assertion failed: No stream attached");return this.stream}}class N{constructor(e,t){this.stdin=null,this.stdout=null,this.stderr=null,this.pipe=null,this.ancestor=e,this.implementation=t}static start(e,{stdin:t,stdout:r,stderr:A}){const n=new N(null,e);return n.stdin=t,n.stdout=r,n.stderr=A,n}pipeTo(e,t=w.STDOUT){const r=new N(this,e),A=new k;return r.pipe=A,r.stdout=this.stdout,r.stderr=this.stderr,(t&w.STDOUT)===w.STDOUT?this.stdout=A:null!==this.ancestor&&(this.stderr=this.ancestor.stdout),(t&w.STDERR)===w.STDERR?this.stderr=A:null!==this.ancestor&&(this.stderr=this.ancestor.stderr),r}async exec(){const e=["ignore","ignore","ignore"];if(this.pipe)e[0]="pipe";else{if(null===this.stdin)throw new Error("Assertion failed: No input stream registered");e[0]=this.stdin.get()}let t,r;if(null===this.stdout)throw new Error("Assertion failed: No output stream registered");if(t=this.stdout,e[1]=t.get(),null===this.stderr)throw new Error("Assertion failed: No error stream registered");r=this.stderr,e[2]=r.get();const A=this.implementation(e);return this.pipe&&this.pipe.attach(A.stdin),await A.promise.then(e=>(t.close(),r.close(),e))}async run(){const e=[];for(let t=this;t;t=t.ancestor)e.push(t.exec());return(await Promise.all(e))[0]}}function F(e,t){return N.start(e,t)}var K;function M(e,t,r){const A=new a.PassThrough({autoDestroy:!0});switch(e){case w.STDIN:(t&K.Readable)===K.Readable&&r.stdin.pipe(A,{end:!1}),(t&K.Writable)===K.Writable&&r.stdin instanceof a.Writable&&A.pipe(r.stdin,{end:!1});break;case w.STDOUT:(t&K.Readable)===K.Readable&&r.stdout.pipe(A,{end:!1}),(t&K.Writable)===K.Writable&&A.pipe(r.stdout,{end:!1});break;case w.STDERR:(t&K.Readable)===K.Readable&&r.stderr.pipe(A,{end:!1}),(t&K.Writable)===K.Writable&&A.pipe(r.stderr,{end:!1});break;default:throw new c(`Bad file descriptor: "${e}"`)}return A}function R(e,t={}){const r={...e,...t};return r.environment={...e.environment,...t.environment},r.variables={...e.variables,...t.variables},r}!function(e){e[e.Readable=1]="Readable",e[e.Writable=2]="Writable"}(K||(K={}));const x=new Map([["cd",async([e=(0,s.homedir)(),...t],r,A)=>{const o=n.y1.resolve(A.cwd,n.cS.toPortablePath(e));return(await r.baseFs.statPromise(o)).isDirectory()?(A.cwd=o,0):(A.stderr.write("cd: not a directory\n"),1)}],["pwd",async(e,t,r)=>(r.stdout.write(n.cS.fromPortablePath(r.cwd)+"\n"),0)],[":",async(e,t,r)=>0],["true",async(e,t,r)=>0],["false",async(e,t,r)=>1],["exit",async([e,...t],r,A)=>A.exitCode=parseInt(null!=e?e:A.variables["?"],10)],["echo",async(e,t,r)=>(r.stdout.write(e.join(" ")+"\n"),0)],["__ysh_run_procedure",async(e,t,r)=>{const A=r.procedures[e[0]];return await F(A,{stdin:new S(r.stdin),stdout:new S(r.stdout),stderr:new S(r.stderr)}).run()}],["__ysh_set_redirects",async(e,t,r)=>{let A=r.stdin,o=r.stdout;const i=r.stderr,s=[],c=[];let g=0;for(;"--"!==e[g];){const A=e[g++],o=Number(e[g++]),i=g+o;for(let o=g;ot.baseFs.createReadStream(n.y1.resolve(r.cwd,n.cS.toPortablePath(e[o]))));break;case"<<<":s.push(()=>{const t=new a.PassThrough;return process.nextTick(()=>{t.write(e[o]+"\n"),t.end()}),t});break;case"<&":s.push(()=>M(Number(e[o]),K.Readable,r));break;case">":case">>":{const i=n.y1.resolve(r.cwd,n.cS.toPortablePath(e[o]));"/dev/null"===i?c.push(new a.Writable({autoDestroy:!0,emitClose:!0,write(e,t,r){setImmediate(r)}})):c.push(t.baseFs.createWriteStream(i,">>"===A?{flags:"a"}:void 0))}break;case">&":c.push(M(Number(e[o]),K.Writable,r));break;default:throw new Error(`Assertion failed: Unsupported redirection type: "${A}"`)}}if(s.length>0){const e=new a.PassThrough;A=e;const t=r=>{if(r===s.length)e.end();else{const A=s[r]();A.pipe(e,{end:!1}),A.on("end",()=>{t(r+1)})}};t(0)}if(c.length>0){const e=new a.PassThrough;o=e;for(const t of c)e.pipe(t)}const l=await F(G(e.slice(g+1),t,r),{stdin:new S(A),stdout:new S(o),stderr:new S(i)}).run();return await Promise.all(c.map(e=>new Promise(t=>{e.on("close",()=>{t()}),e.end()}))),l}]]);async function L(e,t,r){const A=[],n=new a.PassThrough;return n.on("data",e=>A.push(e)),await W(e,t,R(r,{stdout:n})),Buffer.concat(A).toString().replace(/[\r\n]+$/,"")}async function P(e,t,r){const A=e.map(async e=>{const A=await Y(e.args,t,r);return{name:e.name,value:A.join(" ")}});return(await Promise.all(A)).reduce((e,t)=>(e[t.name]=t.value,e),{})}function O(e){return e.match(/[^ \r\n\t]+/g)||[]}async function U(e,t,r,A,n=A){switch(e.name){case"$":A(String(process.pid));break;case"#":A(String(t.args.length));break;case"@":if(e.quoted)for(const e of t.args)n(e);else for(const e of t.args){const t=O(e);for(let e=0;e=0&&ne+t,subtraction:(e,t)=>e-t,multiplication:(e,t)=>e*t,division:(e,t)=>Math.trunc(e/t)};async function j(e,t,r){if("number"===e.type){if(Number.isInteger(e.value))return e.value;throw new Error(`Invalid number: "${e.value}", only integers are allowed`)}if("variable"===e.type){const A=[];await U({...e,quoted:!0},t,r,e=>A.push(e));const n=Number(A.join(" "));return Number.isNaN(n)?j({type:"variable",name:A.join(" ")},t,r):j({type:"number",value:n},t,r)}return T[e.type](await j(e.left,t,r),await j(e.right,t,r))}async function Y(e,t,r){const A=new Map,n=[];let o=[];const i=e=>{o.push(e)},s=()=>{o.length>0&&n.push(o.join("")),o=[]},a=e=>{i(e),s()},g=(e,t)=>{let r=A.get(e);void 0===r&&A.set(e,r=[]),r.push(t)};for(const A of e){let e=!1;switch(A.type){case"redirection":{const e=await Y(A.args,t,r);for(const t of e)g(A.subtype,t)}break;case"argument":for(const n of A.segments)switch(n.type){case"text":i(n.text);break;case"glob":i(n.pattern),e=!0;break;case"shell":{const e=await L(n.shell,t,r);if(n.quoted)i(e);else{const t=O(e);for(let e=0;e0){const e=[];for(const[t,r]of A.entries())e.splice(e.length,0,t,String(r.length),...r);n.splice(0,0,"__ysh_set_redirects",...e,"--")}return n}function G(e,t,r){t.builtins.has(e[0])||(e=["command",...e]);const A=n.cS.fromPortablePath(r.cwd);let o=r.environment;void 0!==o.PWD&&(o={...o,PWD:A});const[i,...s]=e;if("command"===i)return function(e,t,r,A){return r=>{const n=r[0]instanceof a.Transform?"pipe":r[0],o=r[1]instanceof a.Transform?"pipe":r[1],i=r[2]instanceof a.Transform?"pipe":r[2],s=D()(e,t,{...A,stdio:[n,o,i]});return 0==v++&&process.on("SIGINT",b),r[0]instanceof a.Transform&&r[0].pipe(s.stdin),r[1]instanceof a.Transform&&s.stdout.pipe(r[1],{end:!1}),r[2]instanceof a.Transform&&s.stderr.pipe(r[2],{end:!1}),{stdin:s.stdin,promise:new Promise(t=>{s.on("error",A=>{switch(0==--v&&process.off("SIGINT",b),A.code){case"ENOENT":r[2].write(`command not found: ${e}\n`),t(127);break;case"EACCES":r[2].write(`permission denied: ${e}\n`),t(128);break;default:r[2].write(`uncaught error: ${A.message}\n`),t(1)}}),s.on("exit",e=>{0==--v&&process.off("SIGINT",b),t(null!==e?e:129)})})}}}(s[0],s.slice(1),0,{cwd:A,env:o});const c=t.builtins.get(i);if(void 0===c)throw new Error(`Assertion failed: A builtin should exist for "${i}"`);return function(e){return t=>{const r="pipe"===t[0]?new a.PassThrough:t[0];return{stdin:r,promise:Promise.resolve().then(()=>e({stdin:r,stdout:t[1],stderr:t[2]}))}}}(async({stdin:e,stdout:A,stderr:n})=>(r.stdin=e,r.stdout=A,r.stderr=n,await c(s,t,r)))}function H(e,t,r){return A=>{const n=new a.PassThrough;return{stdin:n,promise:W(e,t,R(r,{stdin:n}))}}}function J(e,t,r){return A=>({stdin:new a.PassThrough,promise:W(e,t,r)})}function q(e,t,r,A){if(0===t.length)return e;{let n;do{n=String(Math.random())}while(Object.prototype.hasOwnProperty.call(A.procedures,n));return A.procedures={...A.procedures},A.procedures[n]=e,G([...t,"__ysh_run_procedure",n],r,A)}}async function z(e,t,r){let A;const n=e=>{A=e,r.variables["?"]=String(e)},o=async e=>{try{return await async function(e,t,r){let A=e,n=null,o=null;for(;A;){const e=A.then?{...r}:r;let i;switch(A.type){case"command":{const n=await Y(A.args,t,r),o=await P(A.envs,t,r);i=A.envs.length?G(n,t,R(e,{environment:o})):G(n,t,e)}break;case"subshell":{const n=await Y(A.args,t,r);i=q(H(A.subshell,t,e),n,t,e)}break;case"group":{const n=await Y(A.args,t,r);i=q(J(A.group,t,e),n,t,e)}break;case"envs":{const n=await P(A.envs,t,r);e.environment={...e.environment,...n},i=G(["true"],t,e)}}if(void 0===i)throw new Error("Assertion failed: An action should have been generated");if(null===n)o=F(i,{stdin:new S(e.stdin),stdout:new S(e.stdout),stderr:new S(e.stderr)});else{if(null===o)throw new Error("Assertion failed: The execution pipeline should have been setup");switch(n){case"|":o=o.pipeTo(i,w.STDOUT);break;case"|&":o=o.pipeTo(i,w.STDOUT|w.STDERR)}}A.then?(n=A.then.type,A=A.then.chain):A=null}if(null===o)throw new Error("Assertion failed: The execution pipeline should have been setup");return await o.run()}(e,t,r)}catch(e){if(!(e instanceof c))throw e;return r.stderr.write(e.message+"\n"),1}};for(n(await o(e.chain));e.then;){if(null!==r.exitCode)return r.exitCode;switch(e.then.type){case"&&":0===A&&n(await o(e.then.line.chain));break;case"||":0!==A&&n(await o(e.then.line.chain));break;default:throw new Error(`Assertion failed: Unsupported command type: "${e.then.type}"`)}e=e.then.line}return A}async function W(e,t,r){let A=0;for(const n of e){if(A=await z(n,t,r),null!==r.exitCode)return r.exitCode;r.variables["?"]=String(A)}return A}function V(e){switch(e.type){case"variable":return"@"===e.name||"#"===e.name||"*"===e.name||Number.isFinite(parseInt(e.name,10))||"defaultValue"in e&&!!e.defaultValue&&e.defaultValue.some(e=>X(e));case"arithmetic":return function e(t){switch(t.type){case"variable":return V(t);case"number":return!1;default:return e(t.left)||e(t.right)}}(e.arithmetic);case"shell":return _(e.shell);default:return!1}}function X(e){switch(e.type){case"redirection":return e.args.some(e=>X(e));case"argument":return e.segments.some(e=>V(e));default:throw new Error(`Assertion failed: Unsupported argument type: "${e.type}"`)}}function _(e){return e.some(e=>{for(;e;){let t=e.chain;for(;t;){let e;switch(t.type){case"subshell":e=_(t.subshell);break;case"command":e=t.envs.some(e=>e.args.some(e=>X(e)))||t.args.some(e=>X(e))}if(e)return!0;if(!t.then)break;t=t.then.chain}if(!e.then)break;e=e.then.line}return!1})}async function Z(e,t=[],{baseFs:r=new o.S,builtins:s={},cwd:c=n.cS.toPortablePath(process.cwd()),env:g=process.env,stdin:l=process.stdin,stdout:u=process.stdout,stderr:h=process.stderr,variables:p={},glob:d=A}={}){const C={};for(const[e,t]of Object.entries(g))void 0!==t&&(C[e]=t);const f=new Map(x);for(const[e,t]of Object.entries(s))f.set(e,t);null===l&&(l=new a.PassThrough).end();const I=(0,i.parseShell)(e,d);if(!_(I)&&I.length>0&&t.length>0){let e=I[I.length-1];for(;e.then;)e=e.then.line;let r=e.chain;for(;r.then;)r=r.then.chain;"command"===r.type&&(r.args=r.args.concat(t.map(e=>({type:"argument",segments:[{type:"text",text:e}]}))))}return await W(I,{args:t,baseFs:r,builtins:f,initialStdin:l,initialStdout:u,initialStderr:h,glob:d},{cwd:c,environment:C,exitCode:null,procedures:{},stdin:l,stdout:u,stderr:h,variables:Object.assign({},p,{"?":0})})}},45330:(e,t,r)=>{t.e=()=>({modules:new Map([["@yarnpkg/cli",r(25413)],["@yarnpkg/core",r(53836)],["@yarnpkg/fslib",r(43896)],["@yarnpkg/libzip",r(65281)],["@yarnpkg/parsers",r(11640)],["@yarnpkg/shell",r(76756)],["clipanion",r(40822)],["semver",r(53887)],["yup",r(15966)],["@yarnpkg/plugin-essentials",r(34777)],["@yarnpkg/plugin-compat",r(44692)],["@yarnpkg/plugin-dlx",r(10189)],["@yarnpkg/plugin-file",r(68023)],["@yarnpkg/plugin-git",r(75641)],["@yarnpkg/plugin-github",r(68126)],["@yarnpkg/plugin-http",r(99148)],["@yarnpkg/plugin-init",r(64314)],["@yarnpkg/plugin-link",r(92994)],["@yarnpkg/plugin-node-modules",r(8375)],["@yarnpkg/plugin-npm",r(14224)],["@yarnpkg/plugin-npm-cli",r(8190)],["@yarnpkg/plugin-pack",r(49881)],["@yarnpkg/plugin-patch",r(29936)],["@yarnpkg/plugin-pnp",r(83228)]]),plugins:new Set(["@yarnpkg/plugin-essentials","@yarnpkg/plugin-compat","@yarnpkg/plugin-dlx","@yarnpkg/plugin-file","@yarnpkg/plugin-git","@yarnpkg/plugin-github","@yarnpkg/plugin-http","@yarnpkg/plugin-init","@yarnpkg/plugin-link","@yarnpkg/plugin-node-modules","@yarnpkg/plugin-npm","@yarnpkg/plugin-npm-cli","@yarnpkg/plugin-pack","@yarnpkg/plugin-patch","@yarnpkg/plugin-pnp"])})},29148:(e,t,r)=>{const A=r(74988),n=/^(.*?)(\x1b\[[^m]+m|\x1b\]8;;.*?(\x1b\\|\u0007))/,o=new A;e.exports=(e,t=0,r=e.length)=>{if(t<0||r<0)throw new RangeError("Negative indices aren't supported by this implementation");const A=r-t;let i="",s=0,a=0;for(;e.length>0;){const r=e.match(n)||[e,e,void 0];let c=o.splitGraphemes(r[1]);const g=Math.min(t-s,c.length);c=c.slice(g);const l=Math.min(A-a,c.length);i+=c.slice(0,l).join(""),s+=g,a+=l,void 0!==r[2]&&(i+=r[2]),e=e.slice(r[0].length)}return i}},72912:e=>{function t(){return e.exports=t=Object.assign||function(e){for(var t=1;t{e.exports=function(e){return e&&e.__esModule?e:{default:e}}},19228:(e,t,r)=>{var A=r(54694);function n(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return n=function(){return e},e}e.exports=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==A(e)&&"function"!=typeof e)return{default:e};var t=n();if(t&&t.has(e))return t.get(e);var r={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if(Object.prototype.hasOwnProperty.call(e,i)){var s=o?Object.getOwnPropertyDescriptor(e,i):null;s&&(s.get||s.set)?Object.defineProperty(r,i,s):r[i]=e[i]}return r.default=e,t&&t.set(e,r),r}},74943:e=>{e.exports=function(e,t){if(null==e)return{};var r,A,n={},o=Object.keys(e);for(A=0;A=0||(n[r]=e[r]);return n}},62407:e=>{e.exports=function(e,t){return t||(t=e.slice(0)),e.raw=t,e}},54694:e=>{function t(r){return"function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?e.exports=t=function(e){return typeof e}:e.exports=t=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t(r)}e.exports=t},96117:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(35747);t.FILE_SYSTEM_ADAPTER={lstat:A.lstat,stat:A.stat,lstatSync:A.lstatSync,statSync:A.statSync,readdir:A.readdir,readdirSync:A.readdirSync},t.createFileSystemAdapter=function(e){return void 0===e?t.FILE_SYSTEM_ADAPTER:Object.assign(Object.assign({},t.FILE_SYSTEM_ADAPTER),e)}},79774:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=process.versions.node.split("."),A=parseInt(r[0],10),n=parseInt(r[1],10),o=A>10,i=10===A&&n>=10;t.IS_SUPPORT_READDIR_WITH_FILE_TYPES=o||i},85670:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(31020),n=r(35516),o=r(38844);function i(e={}){return e instanceof o.default?e:new o.default(e)}t.Settings=o.default,t.scandir=function(e,t,r){if("function"==typeof t)return A.read(e,i(),t);A.read(e,i(t),r)},t.scandirSync=function(e,t){const r=i(t);return n.read(e,r)}},31020:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(53403),n=r(69078),o=r(79774),i=r(65225);function s(e,t,r){t.fs.readdir(e,{withFileTypes:!0},(A,o)=>{if(null!==A)return c(r,A);const s=o.map(r=>({dirent:r,name:r.name,path:`${e}${t.pathSegmentSeparator}${r.name}`}));if(!t.followSymbolicLinks)return g(r,s);const a=s.map(e=>function(e,t){return r=>{if(!e.dirent.isSymbolicLink())return r(null,e);t.fs.stat(e.path,(A,n)=>null!==A?t.throwErrorOnBrokenSymbolicLink?r(A):r(null,e):(e.dirent=i.fs.createDirentFromStats(e.name,n),r(null,e)))}}(e,t));n(a,(e,t)=>{if(null!==e)return c(r,e);g(r,t)})})}function a(e,t,r){t.fs.readdir(e,(o,s)=>{if(null!==o)return c(r,o);const a=s.map(r=>`${e}${t.pathSegmentSeparator}${r}`),l=a.map(e=>r=>A.stat(e,t.fsStatSettings,r));n(l,(e,A)=>{if(null!==e)return c(r,e);const n=[];s.forEach((e,r)=>{const o=A[r],s={name:e,path:a[r],dirent:i.fs.createDirentFromStats(e,o)};t.stats&&(s.stats=o),n.push(s)}),g(r,n)})})}function c(e,t){e(t)}function g(e,t){e(null,t)}t.read=function(e,t,r){return!t.stats&&o.IS_SUPPORT_READDIR_WITH_FILE_TYPES?s(e,t,r):a(e,t,r)},t.readdirWithFileTypes=s,t.readdir=a},35516:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(53403),n=r(79774),o=r(65225);function i(e,t){return t.fs.readdirSync(e,{withFileTypes:!0}).map(r=>{const A={dirent:r,name:r.name,path:`${e}${t.pathSegmentSeparator}${r.name}`};if(A.dirent.isSymbolicLink()&&t.followSymbolicLinks)try{const e=t.fs.statSync(A.path);A.dirent=o.fs.createDirentFromStats(A.name,e)}catch(e){if(t.throwErrorOnBrokenSymbolicLink)throw e}return A})}function s(e,t){return t.fs.readdirSync(e).map(r=>{const n=`${e}${t.pathSegmentSeparator}${r}`,i=A.statSync(n,t.fsStatSettings),s={name:r,path:n,dirent:o.fs.createDirentFromStats(r,i)};return t.stats&&(s.stats=i),s})}t.read=function(e,t){return!t.stats&&n.IS_SUPPORT_READDIR_WITH_FILE_TYPES?i(e,t):s(e,t)},t.readdirWithFileTypes=i,t.readdir=s},38844:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(85622),n=r(53403),o=r(96117);t.default=class{constructor(e={}){this._options=e,this.followSymbolicLinks=this._getValue(this._options.followSymbolicLinks,!1),this.fs=o.createFileSystemAdapter(this._options.fs),this.pathSegmentSeparator=this._getValue(this._options.pathSegmentSeparator,A.sep),this.stats=this._getValue(this._options.stats,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!0),this.fsStatSettings=new n.Settings({followSymbolicLink:this.followSymbolicLinks,fs:this.fs,throwErrorOnBrokenSymbolicLink:this.throwErrorOnBrokenSymbolicLink})}_getValue(e,t){return void 0===e?t:e}}},72156:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});class r{constructor(e,t){this.name=e,this.isBlockDevice=t.isBlockDevice.bind(t),this.isCharacterDevice=t.isCharacterDevice.bind(t),this.isDirectory=t.isDirectory.bind(t),this.isFIFO=t.isFIFO.bind(t),this.isFile=t.isFile.bind(t),this.isSocket=t.isSocket.bind(t),this.isSymbolicLink=t.isSymbolicLink.bind(t)}}t.createDirentFromStats=function(e,t){return new r(e,t)}},65225:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(72156);t.fs=A},71208:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(35747);t.FILE_SYSTEM_ADAPTER={lstat:A.lstat,stat:A.stat,lstatSync:A.lstatSync,statSync:A.statSync},t.createFileSystemAdapter=function(e){return void 0===e?t.FILE_SYSTEM_ADAPTER:Object.assign(Object.assign({},t.FILE_SYSTEM_ADAPTER),e)}},53403:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(17790),n=r(34846),o=r(92687);function i(e={}){return e instanceof o.default?e:new o.default(e)}t.Settings=o.default,t.stat=function(e,t,r){if("function"==typeof t)return A.read(e,i(),t);A.read(e,i(t),r)},t.statSync=function(e,t){const r=i(t);return n.read(e,r)}},17790:(e,t)=>{"use strict";function r(e,t){e(t)}function A(e,t){e(null,t)}Object.defineProperty(t,"__esModule",{value:!0}),t.read=function(e,t,n){t.fs.lstat(e,(o,i)=>null!==o?r(n,o):i.isSymbolicLink()&&t.followSymbolicLink?void t.fs.stat(e,(e,o)=>{if(null!==e)return t.throwErrorOnBrokenSymbolicLink?r(n,e):A(n,i);t.markSymbolicLink&&(o.isSymbolicLink=()=>!0),A(n,o)}):A(n,i))}},34846:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.read=function(e,t){const r=t.fs.lstatSync(e);if(!r.isSymbolicLink()||!t.followSymbolicLink)return r;try{const r=t.fs.statSync(e);return t.markSymbolicLink&&(r.isSymbolicLink=()=>!0),r}catch(e){if(!t.throwErrorOnBrokenSymbolicLink)return r;throw e}}},92687:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(71208);t.default=class{constructor(e={}){this._options=e,this.followSymbolicLink=this._getValue(this._options.followSymbolicLink,!0),this.fs=A.createFileSystemAdapter(this._options.fs),this.markSymbolicLink=this._getValue(this._options.markSymbolicLink,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!0)}_getValue(e,t){return void 0===e?t:e}}},72897:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(42369),n=r(27696),o=r(22111),i=r(14954);function s(e={}){return e instanceof i.default?e:new i.default(e)}t.Settings=i.default,t.walk=function(e,t,r){if("function"==typeof t)return new A.default(e,s()).read(t);new A.default(e,s(t)).read(r)},t.walkSync=function(e,t){const r=s(t);return new o.default(e,r).read()},t.walkStream=function(e,t){const r=s(t);return new n.default(e,r).read()}},42369:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(98566);t.default=class{constructor(e,t){this._root=e,this._settings=t,this._reader=new A.default(this._root,this._settings),this._storage=new Set}read(e){this._reader.onError(t=>{!function(e,t){e(t)}(e,t)}),this._reader.onEntry(e=>{this._storage.add(e)}),this._reader.onEnd(()=>{!function(e,t){e(null,t)}(e,[...this._storage])}),this._reader.read()}}},27696:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(92413),n=r(98566);t.default=class{constructor(e,t){this._root=e,this._settings=t,this._reader=new n.default(this._root,this._settings),this._stream=new A.Readable({objectMode:!0,read:()=>{},destroy:this._reader.destroy.bind(this._reader)})}read(){return this._reader.onError(e=>{this._stream.emit("error",e)}),this._reader.onEntry(e=>{this._stream.push(e)}),this._reader.onEnd(()=>{this._stream.push(null)}),this._reader.read(),this._stream}}},22111:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(97835);t.default=class{constructor(e,t){this._root=e,this._settings=t,this._reader=new A.default(this._root,this._settings)}read(){return this._reader.read()}}},98566:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(28614),n=r(85670),o=r(98360),i=r(10750),s=r(75504);class a extends s.default{constructor(e,t){super(e,t),this._settings=t,this._scandir=n.scandir,this._emitter=new A.EventEmitter,this._queue=o(this._worker.bind(this),this._settings.concurrency),this._isFatalError=!1,this._isDestroyed=!1,this._queue.drain=()=>{this._isFatalError||this._emitter.emit("end")}}read(){return this._isFatalError=!1,this._isDestroyed=!1,setImmediate(()=>{this._pushToQueue(this._root,this._settings.basePath)}),this._emitter}destroy(){if(this._isDestroyed)throw new Error("The reader is already destroyed");this._isDestroyed=!0,this._queue.killAndDrain()}onEntry(e){this._emitter.on("entry",e)}onError(e){this._emitter.once("error",e)}onEnd(e){this._emitter.once("end",e)}_pushToQueue(e,t){const r={directory:e,base:t};this._queue.push(r,e=>{null!==e&&this._handleError(e)})}_worker(e,t){this._scandir(e.directory,this._settings.fsScandirSettings,(r,A)=>{if(null!==r)return t(r,void 0);for(const t of A)this._handleEntry(t,e.base);t(null,void 0)})}_handleError(e){i.isFatalError(this._settings,e)&&(this._isFatalError=!0,this._isDestroyed=!0,this._emitter.emit("error",e))}_handleEntry(e,t){if(this._isDestroyed||this._isFatalError)return;const r=e.path;void 0!==t&&(e.path=i.joinPathSegments(t,e.name,this._settings.pathSegmentSeparator)),i.isAppliedFilter(this._settings.entryFilter,e)&&this._emitEntry(e),e.dirent.isDirectory()&&i.isAppliedFilter(this._settings.deepFilter,e)&&this._pushToQueue(r,e.path)}_emitEntry(e){this._emitter.emit("entry",e)}}t.default=a},10750:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isFatalError=function(e,t){return null===e.errorFilter||!e.errorFilter(t)},t.isAppliedFilter=function(e,t){return null===e||e(t)},t.replacePathSegmentSeparator=function(e,t){return e.split(/[\\/]/).join(t)},t.joinPathSegments=function(e,t,r){return""===e?t:e+r+t}},75504:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(10750);t.default=class{constructor(e,t){this._root=e,this._settings=t,this._root=A.replacePathSegmentSeparator(e,t.pathSegmentSeparator)}}},97835:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(85670),n=r(10750),o=r(75504);class i extends o.default{constructor(){super(...arguments),this._scandir=A.scandirSync,this._storage=new Set,this._queue=new Set}read(){return this._pushToQueue(this._root,this._settings.basePath),this._handleQueue(),[...this._storage]}_pushToQueue(e,t){this._queue.add({directory:e,base:t})}_handleQueue(){for(const e of this._queue.values())this._handleDirectory(e.directory,e.base)}_handleDirectory(e,t){try{const r=this._scandir(e,this._settings.fsScandirSettings);for(const e of r)this._handleEntry(e,t)}catch(e){this._handleError(e)}}_handleError(e){if(n.isFatalError(this._settings,e))throw e}_handleEntry(e,t){const r=e.path;void 0!==t&&(e.path=n.joinPathSegments(t,e.name,this._settings.pathSegmentSeparator)),n.isAppliedFilter(this._settings.entryFilter,e)&&this._pushToStorage(e),e.dirent.isDirectory()&&n.isAppliedFilter(this._settings.deepFilter,e)&&this._pushToQueue(r,e.path)}_pushToStorage(e){this._storage.add(e)}}t.default=i},14954:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(85622),n=r(85670);t.default=class{constructor(e={}){this._options=e,this.basePath=this._getValue(this._options.basePath,void 0),this.concurrency=this._getValue(this._options.concurrency,1/0),this.deepFilter=this._getValue(this._options.deepFilter,null),this.entryFilter=this._getValue(this._options.entryFilter,null),this.errorFilter=this._getValue(this._options.errorFilter,null),this.pathSegmentSeparator=this._getValue(this._options.pathSegmentSeparator,A.sep),this.fsScandirSettings=new n.Settings({followSymbolicLinks:this._options.followSymbolicLinks,fs:this._options.fs,pathSegmentSeparator:this._options.pathSegmentSeparator,stats:this._options.stats,throwErrorOnBrokenSymbolicLink:this._options.throwErrorOnBrokenSymbolicLink})}_getValue(e,t){return void 0===e?t:e}}},7966:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=["Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array"];const A=["Function","Generator","AsyncGenerator","GeneratorFunction","AsyncGeneratorFunction","AsyncFunction","Observable","Array","Buffer","Object","RegExp","Date","Error","Map","Set","WeakMap","WeakSet","ArrayBuffer","SharedArrayBuffer","DataView","Promise","URL","HTMLElement",...r];const n=["null","undefined","string","number","bigint","boolean","symbol"];function o(e){return t=>typeof t===e}const{toString:i}=Object.prototype,s=e=>{const t=i.call(e).slice(8,-1);return/HTML\w+Element/.test(t)&&c.domElement(e)?"HTMLElement":(r=t,A.includes(r)?t:void 0);var r},a=e=>t=>s(t)===e;function c(e){if(null===e)return"null";switch(typeof e){case"undefined":return"undefined";case"string":return"string";case"number":return"number";case"boolean":return"boolean";case"function":return"Function";case"bigint":return"bigint";case"symbol":return"symbol"}if(c.observable(e))return"Observable";if(c.array(e))return"Array";if(c.buffer(e))return"Buffer";const t=s(e);if(t)return t;if(e instanceof String||e instanceof Boolean||e instanceof Number)throw new TypeError("Please don't use object wrappers for primitive types");return"Object"}c.undefined=o("undefined"),c.string=o("string");const g=o("number");c.number=e=>g(e)&&!c.nan(e),c.bigint=o("bigint"),c.function_=o("function"),c.null_=e=>null===e,c.class_=e=>c.function_(e)&&e.toString().startsWith("class "),c.boolean=e=>!0===e||!1===e,c.symbol=o("symbol"),c.numericString=e=>c.string(e)&&!c.emptyStringOrWhitespace(e)&&!Number.isNaN(Number(e)),c.array=(e,t)=>!!Array.isArray(e)&&(!c.function_(t)||e.every(t)),c.buffer=e=>{var t,r,A,n;return null!==(n=null===(A=null===(r=null===(t=e)||void 0===t?void 0:t.constructor)||void 0===r?void 0:r.isBuffer)||void 0===A?void 0:A.call(r,e))&&void 0!==n&&n},c.nullOrUndefined=e=>c.null_(e)||c.undefined(e),c.object=e=>!c.null_(e)&&("object"==typeof e||c.function_(e)),c.iterable=e=>{var t;return c.function_(null===(t=e)||void 0===t?void 0:t[Symbol.iterator])},c.asyncIterable=e=>{var t;return c.function_(null===(t=e)||void 0===t?void 0:t[Symbol.asyncIterator])},c.generator=e=>c.iterable(e)&&c.function_(e.next)&&c.function_(e.throw),c.asyncGenerator=e=>c.asyncIterable(e)&&c.function_(e.next)&&c.function_(e.throw),c.nativePromise=e=>a("Promise")(e);c.promise=e=>c.nativePromise(e)||(e=>{var t,r;return c.function_(null===(t=e)||void 0===t?void 0:t.then)&&c.function_(null===(r=e)||void 0===r?void 0:r.catch)})(e),c.generatorFunction=a("GeneratorFunction"),c.asyncGeneratorFunction=e=>"AsyncGeneratorFunction"===s(e),c.asyncFunction=e=>"AsyncFunction"===s(e),c.boundFunction=e=>c.function_(e)&&!e.hasOwnProperty("prototype"),c.regExp=a("RegExp"),c.date=a("Date"),c.error=a("Error"),c.map=e=>a("Map")(e),c.set=e=>a("Set")(e),c.weakMap=e=>a("WeakMap")(e),c.weakSet=e=>a("WeakSet")(e),c.int8Array=a("Int8Array"),c.uint8Array=a("Uint8Array"),c.uint8ClampedArray=a("Uint8ClampedArray"),c.int16Array=a("Int16Array"),c.uint16Array=a("Uint16Array"),c.int32Array=a("Int32Array"),c.uint32Array=a("Uint32Array"),c.float32Array=a("Float32Array"),c.float64Array=a("Float64Array"),c.bigInt64Array=a("BigInt64Array"),c.bigUint64Array=a("BigUint64Array"),c.arrayBuffer=a("ArrayBuffer"),c.sharedArrayBuffer=a("SharedArrayBuffer"),c.dataView=a("DataView"),c.directInstanceOf=(e,t)=>Object.getPrototypeOf(e)===t.prototype,c.urlInstance=e=>a("URL")(e),c.urlString=e=>{if(!c.string(e))return!1;try{return new URL(e),!0}catch(e){return!1}},c.truthy=e=>Boolean(e),c.falsy=e=>!e,c.nan=e=>Number.isNaN(e),c.primitive=e=>{return c.null_(e)||(t=typeof e,n.includes(t));var t},c.integer=e=>Number.isInteger(e),c.safeInteger=e=>Number.isSafeInteger(e),c.plainObject=e=>{if("[object Object]"!==i.call(e))return!1;const t=Object.getPrototypeOf(e);return null===t||t===Object.getPrototypeOf({})},c.typedArray=e=>{return t=s(e),r.includes(t);var t};c.arrayLike=e=>!c.nullOrUndefined(e)&&!c.function_(e)&&(e=>c.safeInteger(e)&&e>=0)(e.length),c.inRange=(e,t)=>{if(c.number(t))return e>=Math.min(0,t)&&e<=Math.max(t,0);if(c.array(t)&&2===t.length)return e>=Math.min(...t)&&e<=Math.max(...t);throw new TypeError("Invalid range: "+JSON.stringify(t))};const l=["innerHTML","ownerDocument","style","attributes","nodeValue"];c.domElement=e=>c.object(e)&&1===e.nodeType&&c.string(e.nodeName)&&!c.plainObject(e)&&l.every(t=>t in e),c.observable=e=>{var t,r,A,n;return!!e&&(e===(null===(r=(t=e)[Symbol.observable])||void 0===r?void 0:r.call(t))||e===(null===(n=(A=e)["@@observable"])||void 0===n?void 0:n.call(A)))},c.nodeStream=e=>c.object(e)&&c.function_(e.pipe)&&!c.observable(e),c.infinite=e=>e===1/0||e===-1/0;const u=e=>t=>c.integer(t)&&Math.abs(t%2)===e;c.evenInteger=u(0),c.oddInteger=u(1),c.emptyArray=e=>c.array(e)&&0===e.length,c.nonEmptyArray=e=>c.array(e)&&e.length>0,c.emptyString=e=>c.string(e)&&0===e.length,c.nonEmptyString=e=>c.string(e)&&e.length>0;c.emptyStringOrWhitespace=e=>c.emptyString(e)||(e=>c.string(e)&&!/\S/.test(e))(e),c.emptyObject=e=>c.object(e)&&!c.map(e)&&!c.set(e)&&0===Object.keys(e).length,c.nonEmptyObject=e=>c.object(e)&&!c.map(e)&&!c.set(e)&&Object.keys(e).length>0,c.emptySet=e=>c.set(e)&&0===e.size,c.nonEmptySet=e=>c.set(e)&&e.size>0,c.emptyMap=e=>c.map(e)&&0===e.size,c.nonEmptyMap=e=>c.map(e)&&e.size>0;const h=(e,t,r)=>{if(!c.function_(t))throw new TypeError("Invalid predicate: "+JSON.stringify(t));if(0===r.length)throw new TypeError("Invalid number of values");return e.call(r,t)};c.any=(e,...t)=>(c.array(e)?e:[e]).some(e=>h(Array.prototype.some,e,t)),c.all=(e,...t)=>h(Array.prototype.every,e,t);const p=(e,t,r)=>{if(!e)throw new TypeError(`Expected value which is \`${t}\`, received value of type \`${c(r)}\`.`)};t.assert={undefined:e=>p(c.undefined(e),"undefined",e),string:e=>p(c.string(e),"string",e),number:e=>p(c.number(e),"number",e),bigint:e=>p(c.bigint(e),"bigint",e),function_:e=>p(c.function_(e),"Function",e),null_:e=>p(c.null_(e),"null",e),class_:e=>p(c.class_(e),"Class",e),boolean:e=>p(c.boolean(e),"boolean",e),symbol:e=>p(c.symbol(e),"symbol",e),numericString:e=>p(c.numericString(e),"string with a number",e),array:(e,t)=>{p(c.array(e),"Array",e),t&&e.forEach(t)},buffer:e=>p(c.buffer(e),"Buffer",e),nullOrUndefined:e=>p(c.nullOrUndefined(e),"null or undefined",e),object:e=>p(c.object(e),"Object",e),iterable:e=>p(c.iterable(e),"Iterable",e),asyncIterable:e=>p(c.asyncIterable(e),"AsyncIterable",e),generator:e=>p(c.generator(e),"Generator",e),asyncGenerator:e=>p(c.asyncGenerator(e),"AsyncGenerator",e),nativePromise:e=>p(c.nativePromise(e),"native Promise",e),promise:e=>p(c.promise(e),"Promise",e),generatorFunction:e=>p(c.generatorFunction(e),"GeneratorFunction",e),asyncGeneratorFunction:e=>p(c.asyncGeneratorFunction(e),"AsyncGeneratorFunction",e),asyncFunction:e=>p(c.asyncFunction(e),"AsyncFunction",e),boundFunction:e=>p(c.boundFunction(e),"Function",e),regExp:e=>p(c.regExp(e),"RegExp",e),date:e=>p(c.date(e),"Date",e),error:e=>p(c.error(e),"Error",e),map:e=>p(c.map(e),"Map",e),set:e=>p(c.set(e),"Set",e),weakMap:e=>p(c.weakMap(e),"WeakMap",e),weakSet:e=>p(c.weakSet(e),"WeakSet",e),int8Array:e=>p(c.int8Array(e),"Int8Array",e),uint8Array:e=>p(c.uint8Array(e),"Uint8Array",e),uint8ClampedArray:e=>p(c.uint8ClampedArray(e),"Uint8ClampedArray",e),int16Array:e=>p(c.int16Array(e),"Int16Array",e),uint16Array:e=>p(c.uint16Array(e),"Uint16Array",e),int32Array:e=>p(c.int32Array(e),"Int32Array",e),uint32Array:e=>p(c.uint32Array(e),"Uint32Array",e),float32Array:e=>p(c.float32Array(e),"Float32Array",e),float64Array:e=>p(c.float64Array(e),"Float64Array",e),bigInt64Array:e=>p(c.bigInt64Array(e),"BigInt64Array",e),bigUint64Array:e=>p(c.bigUint64Array(e),"BigUint64Array",e),arrayBuffer:e=>p(c.arrayBuffer(e),"ArrayBuffer",e),sharedArrayBuffer:e=>p(c.sharedArrayBuffer(e),"SharedArrayBuffer",e),dataView:e=>p(c.dataView(e),"DataView",e),urlInstance:e=>p(c.urlInstance(e),"URL",e),urlString:e=>p(c.urlString(e),"string with a URL",e),truthy:e=>p(c.truthy(e),"truthy",e),falsy:e=>p(c.falsy(e),"falsy",e),nan:e=>p(c.nan(e),"NaN",e),primitive:e=>p(c.primitive(e),"primitive",e),integer:e=>p(c.integer(e),"integer",e),safeInteger:e=>p(c.safeInteger(e),"integer",e),plainObject:e=>p(c.plainObject(e),"plain object",e),typedArray:e=>p(c.typedArray(e),"TypedArray",e),arrayLike:e=>p(c.arrayLike(e),"array-like",e),domElement:e=>p(c.domElement(e),"HTMLElement",e),observable:e=>p(c.observable(e),"Observable",e),nodeStream:e=>p(c.nodeStream(e),"Node.js Stream",e),infinite:e=>p(c.infinite(e),"infinite number",e),emptyArray:e=>p(c.emptyArray(e),"empty array",e),nonEmptyArray:e=>p(c.nonEmptyArray(e),"non-empty array",e),emptyString:e=>p(c.emptyString(e),"empty string",e),nonEmptyString:e=>p(c.nonEmptyString(e),"non-empty string",e),emptyStringOrWhitespace:e=>p(c.emptyStringOrWhitespace(e),"empty string or whitespace",e),emptyObject:e=>p(c.emptyObject(e),"empty object",e),nonEmptyObject:e=>p(c.nonEmptyObject(e),"non-empty object",e),emptySet:e=>p(c.emptySet(e),"empty set",e),nonEmptySet:e=>p(c.nonEmptySet(e),"non-empty set",e),emptyMap:e=>p(c.emptyMap(e),"empty map",e),nonEmptyMap:e=>p(c.nonEmptyMap(e),"non-empty map",e),evenInteger:e=>p(c.evenInteger(e),"even integer",e),oddInteger:e=>p(c.oddInteger(e),"odd integer",e),directInstanceOf:(e,t)=>p(c.directInstanceOf(e,t),"T",e),inRange:(e,t)=>p(c.inRange(e,t),"in range",e),any:(e,...t)=>p(c.any(e,...t),"predicate returns truthy for any value",t),all:(e,...t)=>p(c.all(e,...t),"predicate returns truthy for all values",t)},Object.defineProperties(c,{class:{value:c.class_},function:{value:c.function_},null:{value:c.null_}}),Object.defineProperties(t.assert,{class:{value:t.assert.class_},function:{value:t.assert.function_},null:{value:t.assert.null_}}),t.default=c,e.exports=c,e.exports.default=c,e.exports.assert=t.assert},98298:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(93121),n=Number(process.versions.node.split(".")[0]),o=e=>{const t={start:Date.now(),socket:void 0,lookup:void 0,connect:void 0,secureConnect:void 0,upload:void 0,response:void 0,end:void 0,error:void 0,abort:void 0,phases:{wait:void 0,dns:void 0,tcp:void 0,tls:void 0,request:void 0,firstByte:void 0,download:void 0,total:void 0}};e.timings=t;const r=e=>{const r=e.emit.bind(e);e.emit=(A,...n)=>("error"===A&&(t.error=Date.now(),t.phases.total=t.error-t.start,e.emit=r),r(A,...n))};r(e),e.prependOnceListener("abort",()=>{t.abort=Date.now(),(!t.response||n>=13)&&(t.phases.total=Date.now()-t.start)});const o=e=>{t.socket=Date.now(),t.phases.wait=t.socket-t.start;const r=()=>{t.lookup=Date.now(),t.phases.dns=t.lookup-t.socket};e.prependOnceListener("lookup",r),A.default(e,{connect:()=>{t.connect=Date.now(),void 0===t.lookup&&(e.removeListener("lookup",r),t.lookup=t.connect,t.phases.dns=t.lookup-t.socket),t.phases.tcp=t.connect-t.lookup},secureConnect:()=>{t.secureConnect=Date.now(),t.phases.tls=t.secureConnect-t.connect}})};e.socket?o(e.socket):e.prependOnceListener("socket",o);const i=()=>{var e;t.upload=Date.now(),t.phases.request=t.upload-(null!=(e=t.secureConnect)?e:t.connect)};return("boolean"==typeof e.writableFinished?!e.writableFinished:!e.finished||0!==e.outputSize||e.socket&&0!==e.socket.writableLength)?e.prependOnceListener("finish",i):i(),e.prependOnceListener("response",e=>{t.response=Date.now(),t.phases.firstByte=t.response-t.upload,e.timings=t,r(e),e.prependOnceListener("end",()=>{t.end=Date.now(),t.phases.download=t.end-t.response,t.phases.total=t.end-t.start})}),t};t.default=o,e.exports=o,e.exports.default=o},58069:(e,t,r)=>{"use strict";l.ifExists=function(e,t,r){return l(e,t,r).catch(()=>{})};const A=r(31669),n=r(46227),o=r(85622),i=r(97369),s=/^#!\s*(?:\/usr\/bin\/env)?\s*([^ \t]+)(.*)$/,a={createPwshFile:!0,createCmdFile:i(),fs:r(35747)},c=new Map([[".js","node"],[".cmd","cmd"],[".bat","cmd"],[".ps1","pwsh"],[".sh","sh"]]);function g(e){const t={...a,...e},r=t.fs;return t.fs_={chmod:r.chmod?A.promisify(r.chmod):async()=>{},stat:A.promisify(r.stat),unlink:A.promisify(r.unlink),readFile:A.promisify(r.readFile),writeFile:A.promisify(r.writeFile)},t}async function l(e,t,r){const A=g(r);await A.fs_.stat(e),await async function(e,t,r){const A=await async function(e,t){const r=await t.fs_.readFile(e,"utf8"),A=r.trim().split(/\r*\n/)[0].match(s);if(!A){const t=o.extname(e).toLowerCase();return{program:c.get(t)||null,additionalArgs:""}}return{program:A[1],additionalArgs:A[2]}}(e,r);return await function(e,t){return n(o.dirname(e),{fs:t.fs})}(t,r),function(e,t,r,A){const n=g(A),o=[{generator:h,extension:""}];n.createCmdFile&&o.push({generator:u,extension:".cmd"});n.createPwshFile&&o.push({generator:p,extension:".ps1"});return Promise.all(o.map(A=>async function(e,t,r,A,n){const o=n.preserveSymlinks?"--preserve-symlinks":"",i=[r.additionalArgs,o].filter(e=>e).join(" ");return n=Object.assign({},n,{prog:r.program,args:i}),await function(e,t){return function(e,t){return t.fs_.unlink(e).catch(()=>{})}(e,t)}(t,n),await n.fs_.writeFile(t,A(e,t,n),"utf8"),function(e,t){return function(e,t){return t.fs_.chmod(e,493)}(e,t)}(t,n)}(e,t+A.extension,r,A.generator,n)))}(e,t,A,r)}(e,t,A)}function u(e,t,r){let A=o.relative(o.dirname(t),e).split("/").join("\\");const n=o.isAbsolute(A)?`"${A}"`:`"%~dp0\\${A}"`;let i,s=r.prog,a=r.args||"";const c=d(r.nodePath).win32;s?(i=`"%~dp0\\${s}.exe"`,A=n):(s=n,a="",A="");let g=r.progArgs?r.progArgs.join(" ")+" ":"",l=c?`@SET NODE_PATH=${c}\r\n`:"";return l+=i?`@IF EXIST ${i} (\r\n ${i} ${a} ${A} ${g}%*\r\n) ELSE (\r\n @SETLOCAL\r\n @SET PATHEXT=%PATHEXT:;.JS;=;%\r\n ${s} ${a} ${A} ${g}%*\r\n)`:`@${s} ${a} ${A} ${g}%*\r\n`,l}function h(e,t,r){let A,n=o.relative(o.dirname(t),e),i=r.prog&&r.prog.split("\\").join("/");n=n.split("\\").join("/");const s=o.isAbsolute(n)?`"${n}"`:`"$basedir/${n}"`;let a=r.args||"";const c=d(r.nodePath).posix;i?(A=`"$basedir/${r.prog}"`,n=s):(i=s,a="",n="");let g=r.progArgs?r.progArgs.join(" ")+" ":"",l="#!/bin/sh\n";l+='basedir=$(dirname "$(echo "$0" | sed -e \'s,\\\\,/,g\')")\n\ncase `uname` in\n *CYGWIN*) basedir=`cygpath -w "$basedir"`;;\nesac\n\n';const u=r.nodePath?`export NODE_PATH="${c}"\n`:"";return l+=A?u+`if [ -x ${A} ]; then\n`+` exec ${A} ${a} ${n} ${g}"$@"\nelse \n`+` exec ${i} ${a} ${n} ${g}"$@"\nfi\n`:`${u}${i} ${a} ${n} ${g}"$@"\nexit $?\n`,l}function p(e,t,r){let A=o.relative(o.dirname(t),e);const n=r.prog&&r.prog.split("\\").join("/");let i,s=n&&`"${n}$exe"`;A=A.split("\\").join("/");const a=o.isAbsolute(A)?`"${A}"`:`"$basedir/${A}"`;let c=r.args||"",g=d(r.nodePath);const l=g.win32,u=g.posix;s?(i=`"$basedir/${r.prog}$exe"`,A=a):(s=a,c="",A="");let h=r.progArgs?r.progArgs.join(" ")+" ":"",p='#!/usr/bin/env pwsh\n$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent\n\n$exe=""\n'+(r.nodePath?`$env_node_path=$env:NODE_PATH\n$env:NODE_PATH="${l}"\n`:"")+'if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {\n # Fix case when both the Windows and Linux builds of Node\n # are installed in the same directory\n $exe=".exe"\n}';return r.nodePath&&(p=p+" else {\n"+` $env:NODE_PATH="${u}"\n}`),p+="\n",p=i?p+"$ret=0\n"+`if (Test-Path ${i}) {\n # Support pipeline input\n if ($MyInvocation.ExpectingInput) {\n`+` $input | & ${i} ${c} ${A} ${h}$args\n } else {\n`+` & ${i} ${c} ${A} ${h}$args\n }\n $ret=$LASTEXITCODE\n} else {\n # Support pipeline input\n if ($MyInvocation.ExpectingInput) {\n`+` $input | & ${s} ${c} ${A} ${h}$args\n } else {\n`+` & ${s} ${c} ${A} ${h}$args\n }\n $ret=$LASTEXITCODE\n}\n`+(r.nodePath?"$env:NODE_PATH=$env_node_path\n":"")+"exit $ret\n":p+"# Support pipeline input\nif ($MyInvocation.ExpectingInput) {\n"+` $input | & ${s} ${c} ${A} ${h}$args\n} else {\n`+` & ${s} ${c} ${A} ${h}$args\n}\n`+(r.nodePath?"$env:NODE_PATH=$env_node_path\n":"")+"exit $LASTEXITCODE\n",p}function d(e){if(!e)return{win32:"",posix:""};let t="string"==typeof e?e.split(o.delimiter):Array.from(e),r={};for(let e=0;e"/mnt/"+t.toLowerCase()):t[e];r.win32=r.win32?`${r.win32};${A}`:A,r.posix=r.posix?`${r.posix}:${n}`:n,r[e]={win32:A,posix:n}}return r}e.exports=l},97991:(e,t,r)=>{"use strict";const A=/[\u001b\u009b][[\]#;?()]*(?:(?:(?:[^\W_]*;?[^\W_]*)\u0007)|(?:(?:[0-9]{1,4}(;[0-9]{0,4})*)?[~0-9=<>cf-nqrtyA-PRZ]))/g,n=()=>{const e={enabled:!0,visible:!0,styles:{},keys:{}};"FORCE_COLOR"in process.env&&(e.enabled="0"!==process.env.FORCE_COLOR);const t=(e,t,r)=>"function"==typeof e?e(t):e.wrap(t,r),n=(r,A)=>{if(""===r||null==r)return"";if(!1===e.enabled)return r;if(!1===e.visible)return"";let n=""+r,o=n.includes("\n"),i=A.length;for(i>0&&A.includes("unstyle")&&(A=[...new Set(["unstyle",...A])].reverse());i-- >0;)n=t(e.styles[A[i]],n,o);return n},o=(t,r,A)=>{e.styles[t]=(e=>{let t=e.open=`[${e.codes[0]}m`,r=e.close=`[${e.codes[1]}m`,A=e.regex=new RegExp(`\\u001b\\[${e.codes[1]}m`,"g");return e.wrap=(e,n)=>{e.includes(r)&&(e=e.replace(A,r+t));let o=t+e+r;return n?o.replace(/\r*\n/g,`${r}$&${t}`):o},e})({name:t,codes:r}),(e.keys[A]||(e.keys[A]=[])).push(t),Reflect.defineProperty(e,t,{configurable:!0,enumerable:!0,set(r){e.alias(t,r)},get(){let r=e=>n(e,r.stack);return Reflect.setPrototypeOf(r,e),r.stack=this.stack?this.stack.concat(t):[t],r}})};return o("reset",[0,0],"modifier"),o("bold",[1,22],"modifier"),o("dim",[2,22],"modifier"),o("italic",[3,23],"modifier"),o("underline",[4,24],"modifier"),o("inverse",[7,27],"modifier"),o("hidden",[8,28],"modifier"),o("strikethrough",[9,29],"modifier"),o("black",[30,39],"color"),o("red",[31,39],"color"),o("green",[32,39],"color"),o("yellow",[33,39],"color"),o("blue",[34,39],"color"),o("magenta",[35,39],"color"),o("cyan",[36,39],"color"),o("white",[37,39],"color"),o("gray",[90,39],"color"),o("grey",[90,39],"color"),o("bgBlack",[40,49],"bg"),o("bgRed",[41,49],"bg"),o("bgGreen",[42,49],"bg"),o("bgYellow",[43,49],"bg"),o("bgBlue",[44,49],"bg"),o("bgMagenta",[45,49],"bg"),o("bgCyan",[46,49],"bg"),o("bgWhite",[47,49],"bg"),o("blackBright",[90,39],"bright"),o("redBright",[91,39],"bright"),o("greenBright",[92,39],"bright"),o("yellowBright",[93,39],"bright"),o("blueBright",[94,39],"bright"),o("magentaBright",[95,39],"bright"),o("cyanBright",[96,39],"bright"),o("whiteBright",[97,39],"bright"),o("bgBlackBright",[100,49],"bgBright"),o("bgRedBright",[101,49],"bgBright"),o("bgGreenBright",[102,49],"bgBright"),o("bgYellowBright",[103,49],"bgBright"),o("bgBlueBright",[104,49],"bgBright"),o("bgMagentaBright",[105,49],"bgBright"),o("bgCyanBright",[106,49],"bgBright"),o("bgWhiteBright",[107,49],"bgBright"),e.ansiRegex=A,e.hasColor=e.hasAnsi=t=>(e.ansiRegex.lastIndex=0,"string"==typeof t&&""!==t&&e.ansiRegex.test(t)),e.alias=(t,r)=>{let A="string"==typeof r?e[r]:r;if("function"!=typeof A)throw new TypeError("Expected alias to be the name of an existing color (string) or a function");A.stack||(Reflect.defineProperty(A,"name",{value:t}),e.styles[t]=A,A.stack=[t]),Reflect.defineProperty(e,t,{configurable:!0,enumerable:!0,set(r){e.alias(t,r)},get(){let t=e=>n(e,t.stack);return Reflect.setPrototypeOf(t,e),t.stack=this.stack?this.stack.concat(A.stack):A.stack,t}})},e.theme=t=>{if(null===(r=t)||"object"!=typeof r||Array.isArray(r))throw new TypeError("Expected theme to be an object");var r;for(let r of Object.keys(t))e.alias(r,t[r]);return e},e.alias("unstyle",t=>"string"==typeof t&&""!==t?(e.ansiRegex.lastIndex=0,t.replace(e.ansiRegex,"")):""),e.alias("noop",e=>e),e.none=e.clear=e.noop,e.stripColor=e.unstyle,e.symbols=r(31283),e.define=o,e};e.exports=n(),e.exports.create=n},31283:e=>{"use strict";const t="Hyper"===process.env.TERM_PROGRAM,r="win32"===process.platform,A="linux"===process.platform,n={ballotDisabled:"☒",ballotOff:"☐",ballotOn:"☑",bullet:"•",bulletWhite:"◦",fullBlock:"█",heart:"❤",identicalTo:"≡",line:"─",mark:"※",middot:"·",minus:"-",multiplication:"×",obelus:"÷",pencilDownRight:"✎",pencilRight:"✏",pencilUpRight:"✐",percent:"%",pilcrow2:"❡",pilcrow:"¶",plusMinus:"±",section:"§",starsOff:"☆",starsOn:"★",upDownArrow:"↕"},o=Object.assign({},n,{check:"√",cross:"×",ellipsisLarge:"...",ellipsis:"...",info:"i",question:"?",questionSmall:"?",pointer:">",pointerSmall:"»",radioOff:"( )",radioOn:"(*)",warning:"‼"}),i=Object.assign({},n,{ballotCross:"✘",check:"✔",cross:"✖",ellipsisLarge:"⋯",ellipsis:"…",info:"ℹ",question:"?",questionFull:"?",questionSmall:"﹖",pointer:A?"▸":"❯",pointerSmall:A?"‣":"›",radioOff:"◯",radioOn:"◉",warning:"⚠"});e.exports=r&&!t?o:i,Reflect.defineProperty(e.exports,"common",{enumerable:!1,value:n}),Reflect.defineProperty(e.exports,"windows",{enumerable:!1,value:o}),Reflect.defineProperty(e.exports,"other",{enumerable:!1,value:i})},18483:(e,t,r)=>{"use strict";e=r.nmd(e);const A=(e,t)=>(...r)=>`[${e(...r)+t}m`,n=(e,t)=>(...r)=>{const A=e(...r);return`[${38+t};5;${A}m`},o=(e,t)=>(...r)=>{const A=e(...r);return`[${38+t};2;${A[0]};${A[1]};${A[2]}m`},i=e=>e,s=(e,t,r)=>[e,t,r],a=(e,t,r)=>{Object.defineProperty(e,t,{get:()=>{const A=r();return Object.defineProperty(e,t,{value:A,enumerable:!0,configurable:!0}),A},enumerable:!0,configurable:!0})};let c;const g=(e,t,A,n)=>{void 0===c&&(c=r(2744));const o=n?10:0,i={};for(const[r,n]of Object.entries(c)){const s="ansi16"===r?"ansi":r;r===t?i[s]=e(A,o):"object"==typeof n&&(i[s]=e(n[t],o))}return i};Object.defineProperty(e,"exports",{enumerable:!0,get:function(){const e=new Map,t={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};t.color.gray=t.color.blackBright,t.bgColor.bgGray=t.bgColor.bgBlackBright,t.color.grey=t.color.blackBright,t.bgColor.bgGrey=t.bgColor.bgBlackBright;for(const[r,A]of Object.entries(t)){for(const[r,n]of Object.entries(A))t[r]={open:`[${n[0]}m`,close:`[${n[1]}m`},A[r]=t[r],e.set(n[0],n[1]);Object.defineProperty(t,r,{value:A,enumerable:!1})}return Object.defineProperty(t,"codes",{value:e,enumerable:!1}),t.color.close="",t.bgColor.close="",a(t.color,"ansi",()=>g(A,"ansi16",i,!1)),a(t.color,"ansi256",()=>g(n,"ansi256",i,!1)),a(t.color,"ansi16m",()=>g(o,"rgb",s,!1)),a(t.bgColor,"ansi",()=>g(A,"ansi16",i,!0)),a(t.bgColor,"ansi256",()=>g(n,"ansi256",i,!0)),a(t.bgColor,"ansi16m",()=>g(o,"rgb",s,!0)),t}})},39920:e=>{"use strict";e.exports=(...e)=>[...new Set([].concat(...e))]},67648:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getBinjumper=void 0;const A=r(78761);let n=null;t.getBinjumper=function(){return n||(n=A.gunzipSync(Buffer.from("H4sIAAAAAAAACu18DXgU1dXwzOwkLMmaWTUgYtQlXRRKCASwJRh0Q7IBJdHwE0BJCCHZhejmx91ZCELM4uxqpuPWaG1rW3wV0YqVT7GlCf4U80cSLNKIgAhUUWmdZdFGsCEhkP3OuXM32fBT+/Tp+3zv99bNc/f+nb977rnnnntnsjn31jE6hmF4SKEQw+xgtI+F+faPB1LcjW/GMduHvzdmB5v93piFq0pdpkpnxUpnUZmpuKi8vEI0rbCZnO5yU2m5KfPuBaayihJb8hVXxJgpjVwrw2Szw5lP214sDNM9xgi6WJYzMdOgsgQSxzCdV0FuRAQqnVFrR7lZKj/5dGqVxVNYMi6GMWmw+GXUQIyRg6hjmFHDIG8EVPafGPQFH34b4F+iffkTwOcf0EsWbVUi5OapVKBpkYOgNJjc5cklRWIRlOOxAccOY2amD4WzMJMbk50aYOYwgsgwekgzLoKzJNtWFdphdipjoaESkgHSrEvArXC5sFyFX55Lj8GDfEs1vkSHdZTvXZeQL2P+QiwTXT1Hx7HoEnCig/A14dc2CrfkUuN1OYsZOmeNFO7ei+EuLfl3n/BHOpmgZJpNCqMwM38CmhSvW5M983ooCN490L26JsoVCt2esk/q4dfc3J5pJibazptxmtWlyUCghxW8B6HmaxR8/ZCn7JM7pdaEZp7xizcxM58CWu61F2KO0TDd72IHG9Ghh443Q/AJvoHodTOjEP+VCHw0XPXTiZTzs4Sz+CPaEeokyIG18KXh/wzH4lsJ9QgamKvPaDTEdSC5NwsBtI4wjVvgq+5C+VZNJGWkoz4nUFkDMciuPmKAYRpf92t82QjZxyLfd0OBA0P7iEzDad8b/VT+BdLJUZu2FFlwkAkArSdMAItjBgQJdUonDVg2Whj1NaRwkldbohlmE59rYWTerHbHAe0rwR9uMnuQlPtO9W6AU0boEcCo/hW8gHS8S70NyKszsYeRgdcmBqChwG/iPRqhAPTJLWoMZglm9bcIen3XExrUZqSmZBgRsDGJMsMOJWMytm0d2paLbU9DW6AC1bf9Js0e0/yZ5iQyVxqkcZMJCqggyKRjLHQlISR0GQB0HAqqPgFNUmtaSx3YM4CiSkMjjoJc6lv9A7RRoVo/N9j/q6H9obGGJy1MuGE11M8BVN3AJ0/+yyKYEyOqezmgr0oi6obZcdMmUM9UrXGziILDSK7GZlCX1q6X27BxPG28ARo3M6A56PF1i1din14bcUelhQkdhMKxq4FVEWrJ1rN0WUHLoHztUYiKn534FfxDuEvLUF60IAQCGYeHiXZuEokhiLE4CX+cQOTd3ULGt3iR/w/HQSsLNpxMAkXK6808Gh7aadjyHyQIBrnFb4kOmzASevP7GjyU5Tb2tPr97xM7QZBM1NZoqPtt38hdS5cVFrQQXgvmK9Z4Jc8gW7sUq/FHBV0K4z3i5tt4LlFx6y0/ivP0xohjPL2J4lTvbn8V677NU93FUACrUZ6+hNACnDhsasvkWBN8cYlSoy54HTQPh+Z8bIYWLjgcWnS1Bk7uyQpurqPjhQnN7o5CM+Pccera86jnbwjZOvUlHIKtEUfUos4fD/JnMlc2qXzTMV792ziGGd+q2af1OGpG2HmrXzQbxzKZgOXukDqMsrXVn8HKfbJ1vy+kOdV26x5iwF0p+9qtnRGzBfPp6btdeHwx2Kenb4zw+DJQrH+a0bdP8O7jSL/UyLZZQvmpXe6/Kzmdvt2CrxkQN3WCkUrTWcH3GNYYMGGF6earLIIXnDqT6u4QHt4HBSVvD9DytQ8VIvAIFpqJv0nN63AOU6x7wDTMfuuhNo6ss7DjUaytZO1aO3C2u0Zjy9HNuDAV67HNuGAVW2NYd4QeTj3ap5xmVt8ep+0SZWDIUmi44C0ZXPe1N/izWNhmrPtZpXq/sLMmJPeBvnwnwRBx+AUAyjbb68Lj73T/PZCL6CBj9FAZ3a2yCDJWd0h7WWR7x2ici1a5B9VNBh18mnK11/nnfuzpvV549GfAR6jfHTL7N4Kh+p0gYI3wVJP8J03LP20a3otiLMAJWTiZHcCPkEc+6N0teKeCUG1cjd/JBsZBUTMro+C9BRjI77/fK3ivBxpsU9jfUfwO99+l6s5Ecbj0Gexq70NPG3uzP50lMuPyCnw6QOAAQwjUX4x/s7gG8N1Oyd2ZKHcM4r7YH96fPH33Cj9+GS187oueXrPw6DPnwwOPh12G0JgrNbMBJ6I4qfwmbSLeQGJoQL0oS3MgfnD+2tjEIdJOpRtYG5MPIgbMUAWhbo4UyohE2gK3nCe0dmKtKfDDEMm6oEb87caNS+TmWzAezH1m45JnUjpfxrLgDQCFBSmNwvO4eR+Byg6kKTyf0tjdxoo6qYPt3mUSo67A0LW7zYMt3JlmjFmxyGORYcUyqUMPHmDDSQwfYQMUXuXNykZzB3Ru2E6yjxuvZoRXDWZZa0WAR8NFg3mqVty9oQ/h3DcQshxyMJIij0VTdxORyLJ5HKgSD1ge4fmZmK0ei1J7UGrfvrVRO/AkQ/AsIDmKNDwKUZaebhnYfzYZcI9Fzz0WHLC9Djw5tvhzecXCyyMMxM+7A1KrQVt/LRfsBxhPKNcbM2Cq+0LieN8R8UoCF4p/hjQGWfc34OW3XQveuqsHJq111NIW8DspjZr9yC0wnUq8D4F9+9xdF244m5K0fWVYC42HorAB5yboRfm1eNMs9ejEeAAzkmnDcNFAtt864l4WmsdhUCovNOvRz8zh6PRSOMqQ0EffHS/NXIW+GwmLMe1RpILgPZx4DUZ486XWeEJg6bIwnx3xz1mYifgltzX1c77Gh46kHIFxKvwz2AiicRBWtbCpH9ecHIqtcQde4wZ2PvA8RF6QdSOLYl4MH9Z/SuPgXOKHyA8KnwMyq/ebMZyyYJwDIcURcaK9TtEh1X3fIxu03KbqzehD3QaIFPRKBi9PM4c6laV63xH3gTCVP2jAIMXSZS2bMrWALzwfOP8ot0ELH1FMlf8ezisM2YKjoGRkHapTzuDVA9C9CYWSw6KFQTL0ai50pjQSdmAoUkco2D1kfkj8ijIo+WYTyCEAXErj0rBZ1oWFrgwz0YKpcSm7gwacKLnJt08cLXcqxtTDSq7e/TffbnGCPI/YxXM8GQPB70iMlGNwP5VHINFgZ5jfgP2xYjwaYSEwmxA2rhZ7HdWXWNMelUkNd6AX5QnrczYp4BGmmYqgIZDw6JVEMgPBlwbpbVSvApc2SCq8f6h94P7CtASfE08+r2JcR8fVM4aQCuCeOWAvmzDixv3uGhykaDb7l1gGjDHfjGeBreDM1T4TMVQT7Id6CMNwbak10KaOHhOen7zF8oeL5L0LYF2TyDseySZoRs1jeDqbCGBAN/sCtXupB/wTHAjdiWCFRnDC9YZhtQYdOIbULucpCMO17b+erhOT32E2IlkSBzjMBrLGgRWJIUxI3qhkm8cRYvuEev6aWv5q2IJSTwGxXov4qtTLiy8DgpEia4stgsgrGpEwZ1CBHtWRoNl4K6qile5Hm5Zf6J+Wh6c5cyV4BPySeoY9dIxEhSZlhNYQKzz+JMC8hTXcAGcABiw/jGYmkaKeTF8VG9ar1GLY0IfQrmxFp8zlhfoFev8OvJPwv47fige/pbMQGcgIftbkLhnfo4t+g9eQYXgJ/oXmBLlLvQdE12g5t0utJhhihH2jMFvQ786Bfrk9dmY25ILvL6j6EblQfgu/AnPC52HprF6cC44V13DSCmJFCcRmN2NMsJoRGp5AweywH0VveBfvBMeffQOdKdtJxMkkIrUBcOBaNEmhPs67G0B3A2RofC/CsB1vUK+IoL9C0K8G4g+iQW00gpQ8GD8oC3hFRwev1z1MFPVb8j3INff8gCI6qSLqCL2AiMFDJhlUD872wXM0fKDr3QTDNHhuxC3hvJgt9ZwTJ4ENLJB6QuIcqadfnPCRSWiwIB9DN9lyjWKU8OpCswFcCq5WPGcZYWvtx0P9CBVWX/DDsP1gOzYf+TyI/gOrwV8P+HfpZJIfLVezVnIM/sVoclgKjSiBMF1qTRqyIeQRu0sTdo6TceCwLOSgdH6iFuPIzdL5AsHbSdfhWLwHlXEtqPIB+bDcEoytkw9OEM0JsJRK/NWs/LHUR+GlPqDRgOHbEcH7Djb0TxK89aSQL3j/DwY0O2+Uz8unUF3g4OrleDOIYFYXgX3IbQpOAe7FUIP92Ty+zdft3ih/BG59nHxC+tzkn8V6egvEUk9vjXiNd7e4TKi/k4VDhdY8H5rdAWwC/r4b8Szj5ORmuSu4X9OjUD+H9eeytzrMCYL3JRalCQSuGbQPYWcB6+krEK8Rdp4GziacmEg/I59/cyIGlbdRQ/dXc+AtzKCX9eYk+Ywimk1BI+4HwQn55gRpF8gh3px6vroGiAXlJDO0qI7rcB8Mj3QZ1Ma3wMb6EY4XHZQCpIT6+Zz0qck/m/WcBdWuAXaeszXijV44HKwKYSi9mJXbw91LtG73p9iMh7U/4Kot5OR2+VBwD9nf+uUTSFdBYddDOiMfBMGxbgoK9jr5NJH3K5R3Qmq/8OMgzuGX7i9g54dWdcfoSJl/M5rKfABkTqIymy+QuaU/Qubt/RfK/EL/BTLLkTLL7QFmcFYgPoH5H5h9wbsSkXuRNhyFlhDag1YgeOdo3UgbLcF9ZdgKBvZnuTn4O6KX5sBvYLnXyf04gsBd56n/Av7TIvnnybsWL5IPwpqBqZkh7DTCSbvT05cseKegLy5g8dTWiwbyJ+kLE2g4Xj6Tdrvg/Qaa0pYK3o2Yf19c2t1kcg+XztYI3lnE+KK9jaIbb5+6d1kEH95v4nrIBjUvNI9SZ10L9V1kSwKtT4Ma6DoBdD5q/C7fl9qt5ISFZmNwCoSQQr0OOHSn7AOSifLeDXvxiYX8tXxWPqTOhLHgvYzUznpqQoxbhSXemiR3DhyghZ0jcQQ4GE81O0askQ+BFEZ1fx94vF24K+tQ3noUwCjs7IQRS204aF88scYaVu6B5jOHgy8R/Xlug8PTYbLgdPKfg+/JB8bvCtwxqFHP2WRx6ZkmFBGsFU9tJ5IDpYP9/gIO+YPo80ECZCo3C/VWDqK0JPnPgQfD+4ywM4+o/rfo+Qu4wG/o/gvyBR6AclqB2wB4On+BjsD772fTCsQRaTXi9aCmKUJ9BisHSaM7iJWAKUT2J9BxPNbh7DHcv4CTg/KB4F45GHznzQJc/u8A6Tdvx9LvsbQUS6/0R9jLYv8cdhFEO8JOjAKKmk5EpYTkg1I3K/2VDX4PzvM93xfvl3puF+1Sz1L5j8JTEN00yu3CTp3UxALGJKmnxh0tn/Lucyf5QmKnFGIfglioQPyB/EepZ4x4ELJ2FmABA7zo+2S3hgF61rGMfy4njgKkF4OHB+RZSkJCAEppDH4A4wNjblsgf4Ah0SyDbhbv5316Go0ps0jUO3oEufG+CYIKZYEBYnD/WpZ9nz0rr4PTQG07X0fCj1aIy5A3FOhZRJMD1wrGevHkDBmlngS1QvQCZR484RgS04jD5FPqB3gQh/jv1l48BOJRQlt/p9R7MEY9SEeA4iI1i8G/hPXzzxBfDFJWjYQ8C+mOac8i1+6+Iw/FgX6DbDv/NNbd36APR8I78EFd8DShH76Pc8jWVjmvU87p8PyVF3wzMciqbpVtb+ONzh9BBbBZSI1GehFnH4EXcbDRGsiZUbuBVI+P0GTZMpwJ38/JVphMv/WQmonDs+7HAG4DsIdZuUoBdj3qkfO4IgVfbxReJTXKn4OjVe8dgTctYW498chNPuVfD/x6YVvBe+UmVj5Vmx4C471OqOf8Tjatxn1CqJ+FtiA1c6TL/ReU/st4FGc/iZGO4grGB5X+vEMqhhcgk5KzH93uCdgklYJWNPY02KqnAlAa7NQTdHjp1uiZngz7KJQ9VbhSR0Cp29ppFHyvRTNMm/XZ/HYrefYVuEunnYNsO+Q2VMbj8ZFDmRiPnuAG0B2Opfpt/12wy9aIiZ6+dWJm7Y2wJ3ghXvgFh1DLWHkvKI9AuD/GetuwGu8Rt8GfxYHNQ2dTcE9tIfgfDkhK7VzwdXsdQTslgyJz9oNStMjwULt1D97hp60TJ1A7qvmBFzRxA3SnJYEj7mUF75WE6ywOFA3aXOc+ihWi5+BXA+snrVrwjcIzd4B175Oq96yDOQMFUpddvV+p7lSs+99EtiC24H2aoc8B2li5ydNXLZZ7+pIE3+9JDA4R/FZEO/UWS8HqYOeC7ZPF/TIh8Ddm4CAv1OdyUiMH7YLvEKNNg/tEGxueWcW2A/gOXIUOxOvSCRgZ3r+2sdX+dBbVg3L5HMRbL+PamBr/HK52CehdvB8adFKbLrAwIk7O2d82bJ28FxQeuBsdWzrgr3Pr29h1cGQKvlZ7LczIy8Fp4f00DWg3kH14Focafo1c68EEzdLJpwKbB+LyNgsXFj1gGWRX5zm7TlznOVsteJ+HKkYMo0Lkvu7zfuKP5S449uG5od6Iht7I1s4LgW/sUqx6+az0JxZMTsnpUKxvq4kQk+Ox+xee20DhT1KTCizT6ICyFNvbl9BXC4QPgdUDcuI4wHrWkWkKfA6LFTQd+LQv3A/+RfCWaiJaAAuWCom5ryT+Q8lr9ScMg60v9RPXNWR+0yaJCWn5YgziQfNh91fQEgMt0biIglcT/riDTxK/gdau2rxnlepjoCk8EynDcPn+ABdqTqdcsEPu2/ApPiyXc1qD2Zo8sCjhnKxUd4CHSVTfvZI+WuPJvU7oQ/CPBu2enJqNTmohvqv1NMiuQ/JfoHVX72fFo+QZWgw6MbyefxGG1m7dTlxro3iFdlH0uhG7tyvW7e3WbUQfjZxsfW5Qn4p1D8LZDBjUI/nJmmcF8aKlh/RG98f+hwwwGsW6Qz6r/lc3OkP3u0LDXdGK9TnZttWfyQrUd3wtoIfcDr4DDkpy3ha509ct+G5HcWGR5r0AcYLmir9AjouN+PjhBYiiVIMx0gX9hpDZQt239QWIAEdGzH8zOJbaWdSvRoP30fxqFjhV9DSky/0XBfCAyZNASz6nDWw6Tkv1fthkQhxs45LKjmkHhwATYhG8n6Gu8/QYJ+EzFsW2NfCZ5n0Ds86Rpwq4G1DbbfTs9ajFvVr3srNoVESJ+A6FYt2GzDLR1PL0UFN/2QMH3mlIDDYOVtCcvGgm3MTrIVNH9SCJYxBQw25w5Gs04bcDe/toYzAASoXZzHkaI068ucGbmLwX1BECmn/mtFhQo5LzNG4KrzPapvAyQ6YCAqpna/kp/swpbKAKJarehs+cQthrBQPdop0YW4I3Dt4/PR4HnYKyGPb9Gk5+F2S8Rv5Qma0H6ZExBOlH1akAEzysFGyRrVvgiI13h+rPES9vCw6eXN1X6tst2uN1hpjkvofGyLP5wPOaYuD0nngG9PITsiS3s52BQ3jtPyzwMBGzVdt7C7vppizqYecL3IIqTzPLn6uHr4i0mKoryP7b6xfBYE4FjXIv2AIxBMH7KPF1LMREYCd/FerTYf/lgp+Epf70ClwfZMr0RJRtFwoe6ALBYDViTBI4fn4w8NWycHySpLjjlQK9Uk1uYs+0ozsQZ2y4bckKCyNeAcP9HMbSHo1V0KSSYyTh/g1n8OkG3kvfiI9BOyKek2WhfIPPb6UvjLDgrUdl23GMwj4yRCpgjQE9zlGyZHgZjKY5eHUYD9ZL38B60fnX0fWSQdZLy+B6OSbnEIdSiLRsx4EcKsWOnvOUnHNcdf0d1JNzPHLvQUHJ4I14nKZjjYMIM+JKSnmIV5YZfKGHrmM/QXglS6/wT6MXBV5/+yoUSv3EHYRGvLbQMAMffRW+rIl4HpsU8bYG6lY9E0svqWOQ0sukhjCOFZYBmA9wQebofbvBfqx6z3TGXRX5ykS5BopVsnb9lSw+KdzkoC83NEKcuJlURO0CERGwIyOW3KvyYT73x2qvP9wIkiu3IMbgQ22qB9l2dPChqZ5yJRewi2LJw9bBp8gvxxBzhsAVIEkclqZd1SbF4ts0sGfK1kN2OX620DBs9e1yk122fiY0zObk6uN2qRe8gB6EghL4gX4WSz0z3BC5gWEcBzAewYNCeD/HGkGs/oxxX6XYjgYOR7wAgfsDIOV9BqHctVq832aXzuaL3xMaFmG8Ywf/MA1aJsHaajCSgvb8CPpog/gNwfgKMAF4GFDC+7PUnOPCw4/jBt5g/QxEnCReCd/5YiwwfCMZXZEMwz+ess8u53JhzZFXD+iEvTOcxPx4dalNWN5xnBqDHt3QcW3a2iKj/x8PHzpp9cO1SbvvJDrco4E7YNz2OrlDCnAonJSD5+gGlsgWILJ9ntJol9NhXMPkXtJ8FTYLvvcG3UGd0DAPYlKODPw0GfiX8rvjz0pneeHHL+IQeu24rjAWlwuOy+8GzTSOabgXDgkcIej9OQmK5VMEFO+ZkaKc3o9M3QeEhtF2qS9fNMiHIJ/k/ojcCzRALNzMEbFOE2m/DDaCnu2pYBy+63FsUg0PJwN87BCphtf0mhqKg6AGt568oWRPnc0JvnkYgjawgbmR9yvgXx8m67jguGI9lNJtl1PwBh6VjCEe6PkmnAG3XuqBneYxINbGRzMBCd2w7238bnDDfPdDUGXHm0bflnBb6gPA85ekNo9H/WnoqEPB+7D2NHhdf4RroM/L5A82nFxIHsOT2xc0CHX0cPpiDd7oiimN/rkGu5wRDbulOa02wwDO8GY4Xw8j99sZ0RClYq99Js8KDXC+z+TTpPeZWhYc4zG80zEvkXqMa0bA0XpDK3LClR1e1+0ZenyFMbKDzKdaoSdvRqnDIBsl9elEs3oUyhumxwIgVP4EFWk6J25Vdw3DvWYkevtn1R2kgjMTfFJ9hVTwVc+gL3y+vuR4E/V0vPje0aWGOw6Gq9fs5L9pvDU4np6rxD3q36PDQ7gYndxna+8RKV6zhSUvgHhfw9us6YzgfYQlz68Swu8XkVAHwqZfAknPenMCxPhijhIjNfP+DaH+/v4z74/pGOuBj3jiZQ8E2oJ3GmK1MC3SYd34U0J9dvx1fn6kp3eSaPH05ou3vpGvuRZ/5kg2OBH92z8i9iGjEZM7pUM6fJeJkU/bZaMCpwDe/zDB2TemMxLHHd2kGmFblZuYJumIbvxpv5TAarcOq6PwjpBE8Ogv5rJ+Dzmo9vLO+cpCw6imIF6pLtSfkz86/aJ8Qk3EgMiH7wyTpbQZkHZgrd1K4pJ2Xzx9nRhcOL+hlbyapQ4EELDnvSXUj6w1djdx4utCw8K4fjsQ7w++qM0XitnMBW4I38/RelP4PUN1Eoib8mV4HiOpa/Mt0H5it55B/5BkTvlSHfkFxHZ4/a2q+EyWvFQcwMtvfN8AH9cZwVCnKXXxZLb8d7JyLRYhSBypeHCQ8mH1qvPkfHht45nOMS1Sq14+tLQF4tOfA8GUI+3McOSrau8v4KPkIxBSS0aq68So8Ft4Avq2R/8aCuHl0qilLepiIhBi7yCvlQaGxnMR9EYM0tvHU3rua9SRAwSGPFqWRmli348XsRKdNvFouxSeJgJdJ5000OHHKJ548nKAoUVt1g0V6sSAPsnzXQivzESo7qq7cTyL8Za4W/yh9BbyCbmvCyaF1xeV+bD6QR+5Sb5aIQLAkpdJIbVr/VF6fafN42xd2PtozUPdK33+hFOWgKYrYfxySyU+M+0W1/oX6VOb1zj9ueeU9RC+fXZOuUr+QH5f+lwnfXpOLuRlIXXvmgX+yp7Ur9dkw/GP725mYf2myuf9a4ad+TPYCj7WkKv10mecGOtfwDad4JT4J9j3SXOeAdymW+dfE6skmdmvx7w3/kCq6sbHZjyYA7FFO74vAKen0E44CzHvYJAQ3DpEfvrYNt88GZQ4DWZ1BkRURnz4DTuWiuaf2iLeBIO5IRX8jnOy+kNuUB8m7c6U7Hf5gCWSR+ChEavIgzrywJEcyNZrj8aNGhJ5DjlUfwnIXIlGU3oHXd8ivdyuZPH+e4dJx3RSD47y3lgY2HT2ELkMiCbPA5GNMjK1Gfwig4sNpvMeJRtGMhEnYPz7vi/dSzZjUSnndcsMbMvwXWyHnKyU68/8eUxwwjKD/GcYXMKEhebJ7Ie3rjdPX5MCourDT/IxbFGipSAvfX5O1kmtCRHuoy511+qXg8/b62Bipwd3R8SDDvNkAF26TFbxdci6ebkz8d8V/Nlmg3PEhgCWpeHMRMxJx5rg+CZoWHIPwIbGtpJ3Z0NjG2m+/Ektz6f5EpovpHkuzbNpPofmmTS30DyN5tNpPo3mk2meRPNxNDfT3ETzBJqPonk8zY0019Ocp3kPlf8bmp+k+XGaH6P5IZrvp/kemu+g+Xaab6P5VppvofkLNH+O5htp/jTNn6J5Hc0fo3ktzb0099B8Pc2raC7SvJLmDpqvonlJeJ5IDpPMS8e7Qg+c005l8zacxFcNFFZZC4cLr2o8POQFdhJe4hM+teEDrePO5eT8JFs9ah25B/CAR70Cr4BSoRq4miPnMjy+0MMcCfoB4afrcS/J7tceQaRpeeRRjgAC2fFINscTlsKfTs6ZU7VWua2N1zPkGiqfvB868J7y2fOEor+gVg3hFSLhh3LlHMNLAS/EIPjGAH2fRj9nkGWtmvUBfY/nVqu3elwkWBhKiX8UZENyoz9Ach5L8APFWhsWwIIS1JFbhscI0RbobON1jN/6GImtNeaMRpVXD+wjd0k7ybtaWz9Bio/d6vZWTwAcExyJAG0APpOMlVf4hiw57zFk9HPADr6n5NWmNovXox4IjPYCSDa+k/3rczAVtai8vC0QSrpfeAP9mvyhP++pdusLmVA+/Yr8IXk1AwoLzXgnZQq/NgL5KJrH09xIcwPN9eGBhE9yP8WN/uQ4MIUENfU8+beLmuXaPwWo156jyg1mK9anUGO4P+I4GqAnN9dv1d4QtD6FbTqcO+tT8+djJYtUnp6H5RlQXoSmU/0xNtb5bV33oK/zF50Dv2SP+AtM6BxyxEB2TIb2Hhcp/wd8zuM4YcimDMt/zJi/+2gfR+mKlcXFha7CkjVTJqYklzgcTGGh07ay1CXanOQ/BW2FpeX2CmgtsV2qHT7JpOBkcoucrtLylSZ7UanDVpJkslVV2opFW4lpLFRWVoiQxySZEMpWMsN081jXzUyG01Yk2nKdFcU2l4simsaNLRmfHMMwr15jYZ4fMTQtj2gbec3Q/N+RkNb1oyyMMOrfR/NfkeHCvHG0hckB5a7Bf6YVS8tsRFlup21GDGMyLSp1iu4ixzy3zbk2rEV7hRMUblqxVrS5TEWiqaikxIlKHov/9Qk4eeX3l1esKTdVumzukgqT0+aoKC4SSyvK8R94xYriCodptQ0mFBrGluB0/EOcFaWiyVX6oC0Mu9JRsQLsafLEMhR66hTN2pLJ9+yMjBmmcTCa2YuTK5wrTRnOCpdrIrSaZrlLHSUTp0yeMnnyLVNTJqaMN6UmT0me/G/CiYAeAPp/Jct3ON/hfIfzvwPn/+dPPM3ZB+cz7Ho9e52B52tZ7f/0McI/9mwo9CsMyDPiTNyimDh+diwzjtF+gqBkE5wcEDk9Ti9xALAiLh6+s+MSEPi+mLiEWEK/BNK450MhfC8P6FjWxfHkJw/WQ8qF9hFauwnb8O21/Ava8P8OVkFbNJUV2/DfqEoi2i43jnF0HHMAdhOV1cfNuiLK+ohO4rl1MS3pbem7AHhurAYHaQ/AJkfC3ocAl+eRRHm0Ap4jEm/Wo7pH+BwpiluEXNrTNTIEPhvhNodCGyLhMxEewNNjBuHTY8lvcaCuKveGQgfxsJwJR87ZxijOzWQJOndltHEY515vjObcVUYd5xZ1f+CaACKdEslArpeTPY3K3gOy/0oXIUuWJsv8CFFmxep+yEbUs2IvrxMzpWv5dSg0DO2nAG2Em2OIMvh0HKLrucKWOP5y+PEU3/hSKJSCAHfFGfPBbvB3IfCnMqZD+/xI26uIidOnA8HMWGIf+JMRIsAkfIt9JFA+qwA2g9pcHpj5nNjlcThXeP5FHT390qD9PMKlxxkkHUCWxMQZslqAcRtiVETU7owtHKxQm/Ui/pZQSPctMk2nMh0Hnssv4gnL6444Uy5ZZPeR74w4Q3qYUxIdux74kB/SmEf144pLuCvOdHdcghUQqK7AtpAXHv6XAHxtpD5zASYDYO6IBYZz4kxVQzDn4i8ZoO9rhbQVcN+mursXdJcRuxS+rbGlRDpsuTO2hJS/fR5ML4dCd140Zs2H4DzkQv/JgTUD/Y9Cv/ERPiMuXoqyxuUuicvMiMsti4mLBzGNoBJDejuIvAsdV0mcBfq4WSTLuAQI6APXP/qbQ8DnBNrtfXH6R5HPI7r0OKMEfCZzP4kBtBZAawO0dlQG13dB06zYfzC/Yd9a8kootIbqDdY8sd1vWw/bAMes4UxGC/22dY3wN+uG6Csd9ZWO+gI16G5iL6krxMdnZ8+9CvhcGD9jAD9Dw7dw7wJ6xgXo1ljCH9+tr9sWCj1D5+tRLnNAj9z9MRHqssbeg9UsWoV5wHV3FFIX4OcP4JN5yEB8sEXOAkrPiKCSHgtdWRENjOb/8b8c9a+HQncM2FUG2pWVOI2BpZMVi7C56M8Bdu5QWJihByNg04l+1gNsLsA+qWcu8pu63VyEp5wbq0tkh9Rxnb4N+NveCIX+zlyMz2UNdbS4B5zEx6ZvhkKLh+qD2qXp7gtsEBzS0IZv27+8QPsq/hKybI+QZc7lbdRC6eTvHIwL6BqeE3eMy407BMo8xnGLQZMZA14zJ6I2Oxb3RfLzRe+EQjv+RRpLBysM/ugQvghZ9Q7+gMBl1kFWXCOnW8Be0pK5BZdonh2L+5Ae6JmaQqG7I/ymcTX1mxlanIQPUrMBZlakb11EnOG8QS+szcESgK0E2MKLYedT2DmxNq2APgR1/hzA36z5AyMQJMRwf3wB+rZD3wMX+VJufoQhz469a7Dybb7kOND7HXMZHWbEJXBPXsKVZFzeXhZSutnN1A9eZNOTqy5Y4tbYhRdYeXrsgqENl/e7uWH7BH4fX34ck7kXLzHlWbChDwwugzZqfC7Hz0j5bWwPhaKY/5mf3LrB8pyfab9bti2ibTn+fhK0vR3RZvg5xMhPXJpe5ZMM8xCkOkhbIDVC2gvpMKSTkM5BivkJ6AXSFEizIC2B5ID0EKRfQvotpGZIxyB9hb9f8hTo8imN/k2QT6blNMizIeVDckB6ENJjkH4G6TlIWyHtwN+fgrQH0kFIxyCdgNQNqR+S/qcMcxWkBEhmSEmQpkFKg5QFKRdSPiQ7pEpID0LyQqqD9EtIL0B6FdIOSM2Q9kI6DOmzn36nj0vpYwGT4ahw2eYUlZc4bBBpDbkATsef78u0OWyiLcNZKpYWFzkW2IrxfpH5krGWizbnhc3MKNZaVSpSfGYim1VaXkI4MCmknFXqdIlZpQ4b0J5FWu6yVdGGIjbLabNll65wFjnXMj52tk3MqCgrA9GyS8uh/2NsQfIZFSVhERkmhK3ZRS7R6nRWOGEmOKjnVJS4HTYke1dRGfK6arBVGyvyxzakk65dxTLMJ9wd5TCgIkfpgxeNeJIu21a0+qJmZoouu6KohEoNVB38ApuYV76KcCmxVhXbKhEQZAF9MX5+ocMFbBcVOdw25vc8vSkGKUQgyDANfOTdMcO8wy8uKhWzKpwLSstXOmx3r7gPweYxhS7RWeKuhPnDUmlxhcPB3MMUFq60iWVFpeVFzpUupgrqZSsKi93OwrKiKjzvFBZWFhbayleXOlHyR7S6HX8DEqwFai6bWFhUWVkorq2Elg+ZwmIbqBtntdDmdJZXMMztbKG9EpRlg9Z7oOx2OCqLxFXMRrawtGIFw2yC3FWs4b/MFZbhHTRYOldYUU5I/Z4rrNS6T3LITuP9A75oRYVTZG7jwfgIRysPOnZUFDPMfN5eTAyIKeDtFZW2csbG28FKS0DTdpfNdj9TzttFG4z/Ad6+BmYHIP+LL6PYL/JlK1xixZpimN3f8GW2suJK0OpWLJVVrLYxr/OVNs1ufsdXOkvLRTvDtPEgGN6kw4ro4F2lK8uLHAxzgAdFEz0fJCWkcxRLDhCJ6eHFCkfFGpjhEL/aHqY0LgoYixUgAqxQlNqGMwrCa8KhD/9vSnOt8++yZk+dQp4gwSe+TktlrtXFTlFrHVf3PztFyvqf9MFnS5Wj/5lffP3u87/xw26zMAmQ0jwWhn/uOzv4z/2w5G5q1EW/+MuSX8iZfIn24bx2Z76kkWEeYAd70m6vKht4gDwzMSV5cqLJVl5cUQJhxczEvIVZE6cnmlwiBC1FDtiqZyautbkSb78tJq3I5bKVrXCsNQF+uWtmottZPsNVvMpWVuSaWFZa7KxwVdjFicUVZTOKXGXJq1MSTRCwldptLnFRJLPbYkymNNHpdol3lNsr/kliUwkaILpsEMSUimu1KjQ4bQ+4gYWtJNdZuhqivJU2V7gvstdaBYgYfWXbVtscJgd+z0wsct1Rvrrifpsz0eQuTS/GMHJmor3I4bIlThrgMOmyLNImRYqTNmlgVKCtSWF13fYvzvj/BUaIzSoAXAAA","base64"))),n}},50730:(e,t,r)=>{"use strict";t.O9=void 0;const A=r(85622),n=r(35747),o=r(31669),i=r(67648);Object.defineProperty(t,"O9",{enumerable:!0,get:function(){return i.getBinjumper}})},73975:(e,t,r)=>{"use strict";var A=r(86897).Duplex;function n(e){if(!(this instanceof n))return new n(e);if(this._bufs=[],this.length=0,"function"==typeof e){this._callback=e;var t=function(e){this._callback&&(this._callback(e),this._callback=null)}.bind(this);this.on("pipe",(function(e){e.on("error",t)})),this.on("unpipe",(function(e){e.removeListener("error",t)}))}else this.append(e);A.call(this)}r(31669).inherits(n,A),n.prototype._offset=function(e){var t,r=0,A=0;if(0===e)return[0,0];for(;Athis.length||e<0)){var t=this._offset(e);return this._bufs[t[0]][t[1]]}},n.prototype.slice=function(e,t){return"number"==typeof e&&e<0&&(e+=this.length),"number"==typeof t&&t<0&&(t+=this.length),this.copy(null,0,e,t)},n.prototype.copy=function(e,t,r,A){if(("number"!=typeof r||r<0)&&(r=0),("number"!=typeof A||A>this.length)&&(A=this.length),r>=this.length)return e||Buffer.alloc(0);if(A<=0)return e||Buffer.alloc(0);var n,o,i=!!e,s=this._offset(r),a=A-r,c=a,g=i&&t||0,l=s[1];if(0===r&&A==this.length){if(!i)return 1===this._bufs.length?this._bufs[0]:Buffer.concat(this._bufs,this.length);for(o=0;o(n=this._bufs[o].length-l))){this._bufs[o].copy(e,g,l,l+c);break}this._bufs[o].copy(e,g,l),g+=n,c-=n,l&&(l=0)}return e},n.prototype.shallowSlice=function(e,t){if(e=e||0,t="number"!=typeof t?this.length:t,e<0&&(e+=this.length),t<0&&(t+=this.length),e===t)return new n;var r=this._offset(e),A=this._offset(t),o=this._bufs.slice(r[0],A[0]+1);return 0==A[1]?o.pop():o[o.length-1]=o[o.length-1].slice(0,A[1]),0!=r[1]&&(o[0]=o[0].slice(r[1])),new n(o)},n.prototype.toString=function(e,t,r){return this.slice(t,r).toString(e)},n.prototype.consume=function(e){for(;this._bufs.length;){if(!(e>=this._bufs[0].length)){this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift()}return this},n.prototype.duplicate=function(){for(var e=0,t=new n;ethis.length?this.length:t;for(var A=this._offset(t),o=A[0],i=A[1];o=e.length){var a=s.indexOf(e,i);if(-1!==a)return this._reverseOffset([o,a]);i=s.length-e.length+1}else{var c=this._reverseOffset([o,i]);if(this._match(c,e))return c;i++}}i=0}return-1},n.prototype._match=function(e,t){if(this.length-e{"use strict";const A=r(54900),n=r(44617),o=r(1495),i=r(425),s=(e,t={})=>{let r=[];if(Array.isArray(e))for(let A of e){let e=s.create(A,t);Array.isArray(e)?r.push(...e):r.push(e)}else r=[].concat(s.create(e,t));return t&&!0===t.expand&&!0===t.nodupes&&(r=[...new Set(r)]),r};s.parse=(e,t={})=>i(e,t),s.stringify=(e,t={})=>A("string"==typeof e?s.parse(e,t):e,t),s.compile=(e,t={})=>("string"==typeof e&&(e=s.parse(e,t)),n(e,t)),s.expand=(e,t={})=>{"string"==typeof e&&(e=s.parse(e,t));let r=o(e,t);return!0===t.noempty&&(r=r.filter(Boolean)),!0===t.nodupes&&(r=[...new Set(r)]),r},s.create=(e,t={})=>""===e||e.length<3?[e]:!0!==t.expand?s.compile(e,t):s.expand(e,t),e.exports=s},44617:(e,t,r)=>{"use strict";const A=r(52169),n=r(4542);e.exports=(e,t={})=>{let r=(e,o={})=>{let i=n.isInvalidBrace(o),s=!0===e.invalid&&!0===t.escapeInvalid,a=!0===i||!0===s,c=!0===t.escapeInvalid?"\\":"",g="";if(!0===e.isOpen)return c+e.value;if(!0===e.isClose)return c+e.value;if("open"===e.type)return a?c+e.value:"(";if("close"===e.type)return a?c+e.value:")";if("comma"===e.type)return"comma"===e.prev.type?"":a?e.value:"|";if(e.value)return e.value;if(e.nodes&&e.ranges>0){let r=n.reduce(e.nodes),o=A(...r,{...t,wrap:!1,toRegex:!0});if(0!==o.length)return r.length>1&&o.length>1?`(${o})`:o}if(e.nodes)for(let t of e.nodes)g+=r(t,e);return g};return r(e)}},5384:e=>{"use strict";e.exports={MAX_LENGTH:65536,CHAR_0:"0",CHAR_9:"9",CHAR_UPPERCASE_A:"A",CHAR_LOWERCASE_A:"a",CHAR_UPPERCASE_Z:"Z",CHAR_LOWERCASE_Z:"z",CHAR_LEFT_PARENTHESES:"(",CHAR_RIGHT_PARENTHESES:")",CHAR_ASTERISK:"*",CHAR_AMPERSAND:"&",CHAR_AT:"@",CHAR_BACKSLASH:"\\",CHAR_BACKTICK:"`",CHAR_CARRIAGE_RETURN:"\r",CHAR_CIRCUMFLEX_ACCENT:"^",CHAR_COLON:":",CHAR_COMMA:",",CHAR_DOLLAR:"$",CHAR_DOT:".",CHAR_DOUBLE_QUOTE:'"',CHAR_EQUAL:"=",CHAR_EXCLAMATION_MARK:"!",CHAR_FORM_FEED:"\f",CHAR_FORWARD_SLASH:"/",CHAR_HASH:"#",CHAR_HYPHEN_MINUS:"-",CHAR_LEFT_ANGLE_BRACKET:"<",CHAR_LEFT_CURLY_BRACE:"{",CHAR_LEFT_SQUARE_BRACKET:"[",CHAR_LINE_FEED:"\n",CHAR_NO_BREAK_SPACE:" ",CHAR_PERCENT:"%",CHAR_PLUS:"+",CHAR_QUESTION_MARK:"?",CHAR_RIGHT_ANGLE_BRACKET:">",CHAR_RIGHT_CURLY_BRACE:"}",CHAR_RIGHT_SQUARE_BRACKET:"]",CHAR_SEMICOLON:";",CHAR_SINGLE_QUOTE:"'",CHAR_SPACE:" ",CHAR_TAB:"\t",CHAR_UNDERSCORE:"_",CHAR_VERTICAL_LINE:"|",CHAR_ZERO_WIDTH_NOBREAK_SPACE:"\ufeff"}},1495:(e,t,r)=>{"use strict";const A=r(52169),n=r(54900),o=r(4542),i=(e="",t="",r=!1)=>{let A=[];if(e=[].concat(e),!(t=[].concat(t)).length)return e;if(!e.length)return r?o.flatten(t).map(e=>`{${e}}`):t;for(let n of e)if(Array.isArray(n))for(let e of n)A.push(i(e,t,r));else for(let e of t)!0===r&&"string"==typeof e&&(e=`{${e}}`),A.push(Array.isArray(e)?i(n,e,r):n+e);return o.flatten(A)};e.exports=(e,t={})=>{let r=void 0===t.rangeLimit?1e3:t.rangeLimit,s=(e,a={})=>{e.queue=[];let c=a,g=a.queue;for(;"brace"!==c.type&&"root"!==c.type&&c.parent;)c=c.parent,g=c.queue;if(e.invalid||e.dollar)return void g.push(i(g.pop(),n(e,t)));if("brace"===e.type&&!0!==e.invalid&&2===e.nodes.length)return void g.push(i(g.pop(),["{}"]));if(e.nodes&&e.ranges>0){let s=o.reduce(e.nodes);if(o.exceedsLimit(...s,t.step,r))throw new RangeError("expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.");let a=A(...s,t);return 0===a.length&&(a=n(e,t)),g.push(i(g.pop(),a)),void(e.nodes=[])}let l=o.encloseBrace(e),u=e.queue,h=e;for(;"brace"!==h.type&&"root"!==h.type&&h.parent;)h=h.parent,u=h.queue;for(let t=0;t{"use strict";const A=r(54900),{MAX_LENGTH:n,CHAR_BACKSLASH:o,CHAR_BACKTICK:i,CHAR_COMMA:s,CHAR_DOT:a,CHAR_LEFT_PARENTHESES:c,CHAR_RIGHT_PARENTHESES:g,CHAR_LEFT_CURLY_BRACE:l,CHAR_RIGHT_CURLY_BRACE:u,CHAR_LEFT_SQUARE_BRACKET:h,CHAR_RIGHT_SQUARE_BRACKET:p,CHAR_DOUBLE_QUOTE:d,CHAR_SINGLE_QUOTE:C,CHAR_NO_BREAK_SPACE:f,CHAR_ZERO_WIDTH_NOBREAK_SPACE:I}=r(5384);e.exports=(e,t={})=>{if("string"!=typeof e)throw new TypeError("Expected a string");let r=t||{},E="number"==typeof r.maxLength?Math.min(n,r.maxLength):n;if(e.length>E)throw new SyntaxError(`Input length (${e.length}), exceeds max characters (${E})`);let B,y={type:"root",input:e,nodes:[]},m=[y],w=y,Q=y,D=0,b=e.length,v=0,S=0;const k=()=>e[v++],N=e=>{if("text"===e.type&&"dot"===Q.type&&(Q.type="text"),!Q||"text"!==Q.type||"text"!==e.type)return w.nodes.push(e),e.parent=w,e.prev=Q,Q=e,e;Q.value+=e.value};for(N({type:"bos"});v0){if(w.ranges>0){w.ranges=0;let e=w.nodes.shift();w.nodes=[e,{type:"text",value:A(w)}]}N({type:"comma",value:B}),w.commas++}else if(B===a&&S>0&&0===w.commas){let e=w.nodes;if(0===S||0===e.length){N({type:"text",value:B});continue}if("dot"===Q.type){if(w.range=[],Q.value+=B,Q.type="range",3!==w.nodes.length&&5!==w.nodes.length){w.invalid=!0,w.ranges=0,Q.type="text";continue}w.ranges++,w.args=[];continue}if("range"===Q.type){e.pop();let t=e[e.length-1];t.value+=Q.value+B,Q=t,w.ranges--;continue}N({type:"dot",value:B})}else N({type:"text",value:B});else{if("brace"!==w.type){N({type:"text",value:B});continue}let e="close";w=m.pop(),w.close=!0,N({type:e,value:B}),S--,w=m[m.length-1]}else{S++;let e=Q.value&&"$"===Q.value.slice(-1)||!0===w.dollar;w=N({type:"brace",open:!0,close:!1,dollar:e,depth:S,commas:0,ranges:0,nodes:[]}),m.push(w),N({type:"open",value:B})}else{let e,r=B;for(!0!==t.keepQuotes&&(B="");v{e.nodes||("open"===e.type&&(e.isOpen=!0),"close"===e.type&&(e.isClose=!0),e.nodes||(e.type="text"),e.invalid=!0)});let e=m[m.length-1],t=e.nodes.indexOf(w);e.nodes.splice(t,1,...w.nodes)}}while(m.length>0);return N({type:"eos"}),y}},54900:(e,t,r)=>{"use strict";const A=r(4542);e.exports=(e,t={})=>{let r=(e,n={})=>{let o=t.escapeInvalid&&A.isInvalidBrace(n),i=!0===e.invalid&&!0===t.escapeInvalid,s="";if(e.value)return(o||i)&&A.isOpenOrClose(e)?"\\"+e.value:e.value;if(e.value)return e.value;if(e.nodes)for(let t of e.nodes)s+=r(t);return s};return r(e)}},4542:(e,t)=>{"use strict";t.isInteger=e=>"number"==typeof e?Number.isInteger(e):"string"==typeof e&&""!==e.trim()&&Number.isInteger(Number(e)),t.find=(e,t)=>e.nodes.find(e=>e.type===t),t.exceedsLimit=(e,r,A=1,n)=>!1!==n&&(!(!t.isInteger(e)||!t.isInteger(r))&&(Number(r)-Number(e))/Number(A)>=n),t.escapeNode=(e,t=0,r)=>{let A=e.nodes[t];A&&(r&&A.type===r||"open"===A.type||"close"===A.type)&&!0!==A.escaped&&(A.value="\\"+A.value,A.escaped=!0)},t.encloseBrace=e=>"brace"===e.type&&(e.commas>>0+e.ranges>>0==0&&(e.invalid=!0,!0)),t.isInvalidBrace=e=>"brace"===e.type&&(!(!0!==e.invalid&&!e.dollar)||(e.commas>>0+e.ranges>>0==0||!0!==e.open||!0!==e.close)&&(e.invalid=!0,!0)),t.isOpenOrClose=e=>"open"===e.type||"close"===e.type||(!0===e.open||!0===e.close),t.reduce=e=>e.reduce((e,t)=>("text"===t.type&&e.push(t.value),"range"===t.type&&(t.type="text"),e),[]),t.flatten=(...e)=>{const t=[],r=e=>{for(let A=0;A{"use strict";const{V4MAPPED:A,ADDRCONFIG:n,ALL:o,promises:{Resolver:i},lookup:s}=r(40881),{promisify:a}=r(31669),c=r(12087),g=Symbol("cacheableLookupCreateConnection"),l=Symbol("cacheableLookupInstance"),u=Symbol("expires"),h="number"==typeof o,p=e=>{if(!e||"function"!=typeof e.createConnection)throw new Error("Expected an Agent instance as the first argument")},d=()=>{let e=!1,t=!1;for(const r of Object.values(c.networkInterfaces()))for(const A of r)if(!A.internal&&("IPv6"===A.family?t=!0:e=!0,e&&t))return{has4:e,has6:t};return{has4:e,has6:t}},C={ttl:!0},f={all:!0};class I{constructor({cache:e=new Map,maxTtl:t=1/0,fallbackDuration:r=3600,errorTtl:A=.15,resolver:n=new i,lookup:o=s}={}){if(this.maxTtl=t,this.errorTtl=A,this._cache=e,this._resolver=n,this._dnsLookup=a(o),this._resolver instanceof i?(this._resolve4=this._resolver.resolve4.bind(this._resolver),this._resolve6=this._resolver.resolve6.bind(this._resolver)):(this._resolve4=a(this._resolver.resolve4.bind(this._resolver)),this._resolve6=a(this._resolver.resolve6.bind(this._resolver))),this._iface=d(),this._pending={},this._nextRemovalTime=!1,this._hostnamesToFallback=new Set,r<1)this._fallback=!1;else{this._fallback=!0;const e=setInterval(()=>{this._hostnamesToFallback.clear()},1e3*r);e.unref&&e.unref()}this.lookup=this.lookup.bind(this),this.lookupAsync=this.lookupAsync.bind(this)}set servers(e){this.clear(),this._resolver.setServers(e)}get servers(){return this._resolver.getServers()}lookup(e,t,r){if("function"==typeof t?(r=t,t={}):"number"==typeof t&&(t={family:t}),!r)throw new Error("Callback must be a function.");this.lookupAsync(e,t).then(e=>{t.all?r(null,e):r(null,e.address,e.family,e.expires,e.ttl)},r)}async lookupAsync(e,t={}){"number"==typeof t&&(t={family:t});let r=await this.query(e);if(6===t.family){const e=r.filter(e=>6===e.family);t.hints&A&&(h&&t.hints&o||0===e.length)?(e=>{for(const t of e)6!==t.family&&(t.address="::ffff:"+t.address,t.family=6)})(r):r=e}else 4===t.family&&(r=r.filter(e=>4===e.family));if(t.hints&n){const{_iface:e}=this;r=r.filter(t=>6===t.family?e.has6:e.has4)}if(0===r.length){const t=new Error("cacheableLookup ENOTFOUND "+e);throw t.code="ENOTFOUND",t.hostname=e,t}return t.all?r:r[0]}async query(e){let t=await this._cache.get(e);if(!t){const r=this._pending[e];if(r)t=await r;else{const r=this.queryAndCache(e);this._pending[e]=r,t=await r}}return t=t.map(e=>({...e})),t}async _resolve(e){const[t,r]=await Promise.all([this._resolve4(e,C),this._resolve6(e,C)].map(e=>(async e=>{try{return await e}catch(e){if("ENODATA"===e.code||"ENOTFOUND"===e.code)return[];throw e}})(e)));let A=0,n=0,o=0;const i=Date.now();for(const e of t)e.family=4,e.expires=i+1e3*e.ttl,A=Math.max(A,e.ttl);for(const e of r)e.family=6,e.expires=i+1e3*e.ttl,n=Math.max(n,e.ttl);return o=t.length>0?r.length>0?Math.min(A,n):A:n,{entries:[...t,...r],cacheTtl:o}}async _lookup(e){try{return{entries:await this._dnsLookup(e,{all:!0}),cacheTtl:0}}catch(e){return{entries:[],cacheTtl:0}}}async _set(e,t,r){if(this.maxTtl>0&&r>0){r=1e3*Math.min(r,this.maxTtl),t[u]=Date.now()+r;try{await this._cache.set(e,t,r)}catch(e){this.lookupAsync=async()=>{const t=new Error("Cache Error. Please recreate the CacheableLookup instance.");throw t.cause=e,t}}A=this._cache,Symbol.iterator in A&&this._tick(r)}var A}async queryAndCache(e){if(this._hostnamesToFallback.has(e))return this._dnsLookup(e,f);try{let t=await this._resolve(e);0===t.entries.length&&this._fallback&&(t=await this._lookup(e),0!==t.entries.length&&this._hostnamesToFallback.add(e));const r=0===t.entries.length?this.errorTtl:t.cacheTtl;return await this._set(e,t.entries,r),delete this._pending[e],t.entries}catch(t){throw delete this._pending[e],t}}_tick(e){const t=this._nextRemovalTime;(!t||e{this._nextRemovalTime=!1;let e=1/0;const t=Date.now();for(const[r,A]of this._cache){const n=A[u];t>=n?this._cache.delete(r):n("lookup"in t||(t.lookup=this.lookup),e[g](t,r))}uninstall(e){if(p(e),e[g]){if(e[l]!==this)throw new Error("The agent is not owned by this CacheableLookup instance");e.createConnection=e[g],delete e[g],delete e[l]}}updateInterfaceInfo(){const{_iface:e}=this;this._iface=d(),(e.has4&&!this._iface.has4||e.has6&&!this._iface.has6)&&this._cache.clear()}clear(e){e?this._cache.delete(e):this._cache.clear()}}e.exports=I,e.exports.default=I},11200:(e,t,r)=>{"use strict";const A=r(28614),n=r(78835),o=r(19793),i=r(58764),s=r(86834),a=r(48491),c=r(55737),g=r(15751),l=r(72515);class u{constructor(e,t){if("function"!=typeof e)throw new TypeError("Parameter `request` must be a function");return this.cache=new l({uri:"string"==typeof t&&t,store:"string"!=typeof t&&t,namespace:"cacheable-request"}),this.createCacheableRequest(e)}createCacheableRequest(e){return(t,r)=>{let l;if("string"==typeof t)l=p(n.parse(t)),t={};else if(t instanceof n.URL)l=p(n.parse(t.toString())),t={};else{const[e,...r]=(t.path||"").split("?"),A=r.length>0?"?"+r.join("?"):"";l=p({...t,pathname:e,search:A})}(t={headers:{},method:"GET",cache:!0,strictTtl:!1,automaticFailover:!1,...t,...h(l)}).headers=c(t.headers);const d=new A,C=o(n.format(l),{stripWWW:!1,removeTrailingSlash:!1,stripAuthentication:!1}),f=`${t.method}:${C}`;let I=!1,E=!1;const B=t=>{E=!0;let A,n=!1;const o=new Promise(e=>{A=()=>{n||(n=!0,e())}}),c=e=>{if(I&&!t.forceRefresh){e.status=e.statusCode;const r=s.fromObject(I.cachePolicy).revalidatedPolicy(t,e);if(!r.modified){const t=r.policy.responseHeaders();(e=new a(I.statusCode,t,I.body,I.url)).cachePolicy=r.policy,e.fromCache=!0}}let A;e.fromCache||(e.cachePolicy=new s(t,e,t),e.fromCache=!1),t.cache&&e.cachePolicy.storable()?(A=g(e),(async()=>{try{const r=i.buffer(e);if(await Promise.race([o,new Promise(t=>e.once("end",t))]),n)return;const A=await r,s={cachePolicy:e.cachePolicy.toObject(),url:e.url,statusCode:e.fromCache?I.statusCode:e.statusCode,body:A};let a=t.strictTtl?e.cachePolicy.timeToLive():void 0;t.maxTtl&&(a=a?Math.min(a,t.maxTtl):t.maxTtl),await this.cache.set(f,s,a)}catch(e){d.emit("error",new u.CacheError(e))}})()):t.cache&&I&&(async()=>{try{await this.cache.delete(f)}catch(e){d.emit("error",new u.CacheError(e))}})(),d.emit("response",A||e),"function"==typeof r&&r(A||e)};try{const r=e(t,c);r.once("error",A),r.once("abort",A),d.emit("request",r)}catch(e){d.emit("error",new u.RequestError(e))}};return(async()=>{const e=async e=>{await Promise.resolve();const t=e.cache?await this.cache.get(f):void 0;if(void 0===t)return B(e);const A=s.fromObject(t.cachePolicy);if(A.satisfiesWithoutRevalidation(e)&&!e.forceRefresh){const e=A.responseHeaders(),n=new a(t.statusCode,e,t.body,t.url);n.cachePolicy=A,n.fromCache=!0,d.emit("response",n),"function"==typeof r&&r(n)}else I=t,e.headers=A.revalidationHeaders(e),B(e)},A=e=>d.emit("error",new u.CacheError(e));this.cache.once("error",A),d.on("response",()=>this.cache.removeListener("error",A));try{await e(t)}catch(e){t.automaticFailover&&!E&&B(t),d.emit("error",new u.CacheError(e))}})(),d}}}function h(e){const t={...e};return t.path=`${e.pathname||"/"}${e.search||""}`,delete t.pathname,delete t.search,t}function p(e){return{protocol:e.protocol,auth:e.auth,hostname:e.hostname||e.host||"localhost",port:e.port,pathname:e.pathname,search:e.search}}u.RequestError=class extends Error{constructor(e){super(e.message),this.name="RequestError",Object.assign(this,e)}},u.CacheError=class extends Error{constructor(e){super(e.message),this.name="CacheError",Object.assign(this,e)}},e.exports=u},54738:e=>{"use strict";const t=(e,t)=>{if("string"!=typeof e&&!Array.isArray(e))throw new TypeError("Expected the input to be `string | string[]`");t=Object.assign({pascalCase:!1},t);if(0===(e=Array.isArray(e)?e.map(e=>e.trim()).filter(e=>e.length).join("-"):e.trim()).length)return"";if(1===e.length)return t.pascalCase?e.toUpperCase():e.toLowerCase();return e!==e.toLowerCase()&&(e=(e=>{let t=!1,r=!1,A=!1;for(let n=0;nt.toUpperCase()).replace(/\d+(\w|$)/g,e=>e.toUpperCase()),r=e,t.pascalCase?r.charAt(0).toUpperCase()+r.slice(1):r;var r};e.exports=t,e.exports.default=t},95882:(e,t,r)=>{"use strict";const A=r(18483),{stdout:n,stderr:o}=r(59428),{stringReplaceAll:i,stringEncaseCRLFWithFirstIndex:s}=r(73327),a=["ansi","ansi","ansi256","ansi16m"],c=Object.create(null);class g{constructor(e){return l(e)}}const l=e=>{const t={};return((e,t={})=>{if(t.level>3||t.level<0)throw new Error("The `level` option should be an integer from 0 to 3");const r=n?n.level:0;e.level=void 0===t.level?r:t.level})(t,e),t.template=(...e)=>E(t.template,...e),Object.setPrototypeOf(t,u.prototype),Object.setPrototypeOf(t.template,t),t.template.constructor=()=>{throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.")},t.template.Instance=g,t.template};function u(e){return l(e)}for(const[e,t]of Object.entries(A))c[e]={get(){const r=C(this,d(t.open,t.close,this._styler),this._isEmpty);return Object.defineProperty(this,e,{value:r}),r}};c.visible={get(){const e=C(this,this._styler,!0);return Object.defineProperty(this,"visible",{value:e}),e}};const h=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(const e of h)c[e]={get(){const{level:t}=this;return function(...r){const n=d(A.color[a[t]][e](...r),A.color.close,this._styler);return C(this,n,this._isEmpty)}}};for(const e of h){c["bg"+e[0].toUpperCase()+e.slice(1)]={get(){const{level:t}=this;return function(...r){const n=d(A.bgColor[a[t]][e](...r),A.bgColor.close,this._styler);return C(this,n,this._isEmpty)}}}}const p=Object.defineProperties(()=>{},{...c,level:{enumerable:!0,get(){return this._generator.level},set(e){this._generator.level=e}}}),d=(e,t,r)=>{let A,n;return void 0===r?(A=e,n=t):(A=r.openAll+e,n=t+r.closeAll),{open:e,close:t,openAll:A,closeAll:n,parent:r}},C=(e,t,r)=>{const A=(...e)=>f(A,1===e.length?""+e[0]:e.join(" "));return A.__proto__=p,A._generator=e,A._styler=t,A._isEmpty=r,A},f=(e,t)=>{if(e.level<=0||!t)return e._isEmpty?"":t;let r=e._styler;if(void 0===r)return t;const{openAll:A,closeAll:n}=r;if(-1!==t.indexOf(""))for(;void 0!==r;)t=i(t,r.close,r.open),r=r.parent;const o=t.indexOf("\n");return-1!==o&&(t=s(t,n,A,o)),A+t+n};let I;const E=(e,...t)=>{const[A]=t;if(!Array.isArray(A))return t.join(" ");const n=t.slice(1),o=[A.raw[0]];for(let e=1;e{"use strict";const t=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,r=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,A=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,n=/\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.)|([^\\])/gi,o=new Map([["n","\n"],["r","\r"],["t","\t"],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e",""],["a",""]]);function i(e){const t="u"===e[0],r="{"===e[1];return t&&!r&&5===e.length||"x"===e[0]&&3===e.length?String.fromCharCode(parseInt(e.slice(1),16)):t&&r?String.fromCodePoint(parseInt(e.slice(2,-1),16)):o.get(e)||e}function s(e,t){const r=[],o=t.trim().split(/\s*,\s*/g);let s;for(const t of o){const o=Number(t);if(Number.isNaN(o)){if(!(s=t.match(A)))throw new Error(`Invalid Chalk template style argument: ${t} (in style '${e}')`);r.push(s[2].replace(n,(e,t,r)=>t?i(t):r))}else r.push(o)}return r}function a(e){r.lastIndex=0;const t=[];let A;for(;null!==(A=r.exec(e));){const e=A[1];if(A[2]){const r=s(e,A[2]);t.push([e].concat(r))}else t.push([e])}return t}function c(e,t){const r={};for(const e of t)for(const t of e.styles)r[t[0]]=e.inverse?null:t.slice(1);let A=e;for(const[e,t]of Object.entries(r))if(Array.isArray(t)){if(!(e in A))throw new Error("Unknown Chalk style: "+e);A=t.length>0?A[e](...t):A[e]}return A}e.exports=(e,r)=>{const A=[],n=[];let o=[];if(r.replace(t,(t,r,s,g,l,u)=>{if(r)o.push(i(r));else if(g){const t=o.join("");o=[],n.push(0===A.length?t:c(e,A)(t)),A.push({inverse:s,styles:a(g)})}else if(l){if(0===A.length)throw new Error("Found extraneous } in Chalk template literal");n.push(c(e,A)(o.join(""))),o=[],A.pop()}else o.push(u)}),n.push(o.join("")),A.length>0){const e=`Chalk template literal is missing ${A.length} closing bracket${1===A.length?"":"s"} (\`}\`)`;throw new Error(e)}return n.join("")}},73327:e=>{"use strict";e.exports={stringReplaceAll:(e,t,r)=>{let A=e.indexOf(t);if(-1===A)return e;const n=t.length;let o=0,i="";do{i+=e.substr(o,A-o)+t+r,o=A+n,A=e.indexOf(t,o)}while(-1!==A);return i+=e.substr(o),i},stringEncaseCRLFWithFirstIndex:(e,t,r,A)=>{let n=0,o="";do{const i="\r"===e[A-1];o+=e.substr(n,(i?A-1:A)-n)+t+(i?"\r\n":"\n")+r,n=A+1,A=e.indexOf("\n",n)}while(-1!==A);return o+=e.substr(n),o}}},5864:(e,t,r)=>{"use strict";var A=r(85832),n=process.env;function o(e){return"string"==typeof e?!!n[e]:Object.keys(e).every((function(t){return n[t]===e[t]}))}Object.defineProperty(t,"_vendors",{value:A.map((function(e){return e.constant}))}),t.name=null,t.isPR=null,A.forEach((function(e){var r=(Array.isArray(e.env)?e.env:[e.env]).every((function(e){return o(e)}));if(t[e.constant]=r,r)switch(t.name=e.name,typeof e.pr){case"string":t.isPR=!!n[e.pr];break;case"object":"env"in e.pr?t.isPR=e.pr.env in n&&n[e.pr.env]!==e.pr.ne:"any"in e.pr?t.isPR=e.pr.any.some((function(e){return!!n[e]})):t.isPR=o(e.pr);break;default:t.isPR=null}})),t.isCI=!!(n.CI||n.CONTINUOUS_INTEGRATION||n.BUILD_NUMBER||n.RUN_ID||t.name)},85832:e=>{"use strict";e.exports=JSON.parse('[{"name":"AppVeyor","constant":"APPVEYOR","env":"APPVEYOR","pr":"APPVEYOR_PULL_REQUEST_NUMBER"},{"name":"Azure Pipelines","constant":"AZURE_PIPELINES","env":"SYSTEM_TEAMFOUNDATIONCOLLECTIONURI","pr":"SYSTEM_PULLREQUEST_PULLREQUESTID"},{"name":"Bamboo","constant":"BAMBOO","env":"bamboo_planKey"},{"name":"Bitbucket Pipelines","constant":"BITBUCKET","env":"BITBUCKET_COMMIT","pr":"BITBUCKET_PR_ID"},{"name":"Bitrise","constant":"BITRISE","env":"BITRISE_IO","pr":"BITRISE_PULL_REQUEST"},{"name":"Buddy","constant":"BUDDY","env":"BUDDY_WORKSPACE_ID","pr":"BUDDY_EXECUTION_PULL_REQUEST_ID"},{"name":"Buildkite","constant":"BUILDKITE","env":"BUILDKITE","pr":{"env":"BUILDKITE_PULL_REQUEST","ne":"false"}},{"name":"CircleCI","constant":"CIRCLE","env":"CIRCLECI","pr":"CIRCLE_PULL_REQUEST"},{"name":"Cirrus CI","constant":"CIRRUS","env":"CIRRUS_CI","pr":"CIRRUS_PR"},{"name":"AWS CodeBuild","constant":"CODEBUILD","env":"CODEBUILD_BUILD_ARN"},{"name":"Codeship","constant":"CODESHIP","env":{"CI_NAME":"codeship"}},{"name":"Drone","constant":"DRONE","env":"DRONE","pr":{"DRONE_BUILD_EVENT":"pull_request"}},{"name":"dsari","constant":"DSARI","env":"DSARI"},{"name":"GitLab CI","constant":"GITLAB","env":"GITLAB_CI"},{"name":"GoCD","constant":"GOCD","env":"GO_PIPELINE_LABEL"},{"name":"Hudson","constant":"HUDSON","env":"HUDSON_URL"},{"name":"Jenkins","constant":"JENKINS","env":["JENKINS_URL","BUILD_ID"],"pr":{"any":["ghprbPullId","CHANGE_ID"]}},{"name":"Magnum CI","constant":"MAGNUM","env":"MAGNUM"},{"name":"Netlify CI","constant":"NETLIFY","env":"NETLIFY_BUILD_BASE","pr":{"env":"PULL_REQUEST","ne":"false"}},{"name":"Sail CI","constant":"SAIL","env":"SAILCI","pr":"SAIL_PULL_REQUEST_NUMBER"},{"name":"Semaphore","constant":"SEMAPHORE","env":"SEMAPHORE","pr":"PULL_REQUEST_NUMBER"},{"name":"Shippable","constant":"SHIPPABLE","env":"SHIPPABLE","pr":{"IS_PULL_REQUEST":"true"}},{"name":"Solano CI","constant":"SOLANO","env":"TDDIUM","pr":"TDDIUM_PR_ID"},{"name":"Strider CD","constant":"STRIDER","env":"STRIDER"},{"name":"TaskCluster","constant":"TASKCLUSTER","env":["TASK_ID","RUN_ID"]},{"name":"TeamCity","constant":"TEAMCITY","env":"TEAMCITY_VERSION"},{"name":"Travis CI","constant":"TRAVIS","env":"TRAVIS","pr":{"env":"TRAVIS_PULL_REQUEST","ne":"false"}}]')},40822:(e,t,r)=>{"use strict";r.r(t),r.d(t,{Cli:()=>Y,Command:()=>M,UsageError:()=>a});const A=/^(-h|--help)(?:=([0-9]+))?$/,n=/^(--[a-z]+(?:-[a-z]+)*|-[a-zA-Z]+)$/,o=/^-[a-zA-Z]{2,}$/,i=/^([^=]+)=([\s\S]*)$/,s="1"===process.env.DEBUG_CLI;class a extends Error{constructor(e){super(e),this.clipanion={type:"usage"},this.name="UsageError"}}class c extends Error{constructor(e,t){if(super(),this.input=e,this.candidates=t,this.clipanion={type:"none"},this.name="UnknownSyntaxError",0===this.candidates.length)this.message="Command not found, but we're not sure what's the alternative.";else if(1===this.candidates.length&&null!==this.candidates[0].reason){const[{usage:e,reason:t}]=this.candidates;this.message=`${t}\n\n$ ${e}`}else if(1===this.candidates.length){const[{usage:t}]=this.candidates;this.message=`Command not found; did you mean:\n\n$ ${t}\n${l(e)}`}else this.message=`Command not found; did you mean one of:\n\n${this.candidates.map(({usage:e},t)=>`${(t+".").padStart(4)} ${e}`).join("\n")}\n\n${l(e)}`}}class g extends Error{constructor(e,t){super(),this.input=e,this.usages=t,this.clipanion={type:"none"},this.name="AmbiguousSyntaxError",this.message=`Cannot find who to pick amongst the following alternatives:\n\n${this.usages.map((e,t)=>`${(t+".").padStart(4)} ${e}`).join("\n")}\n\n${l(e)}`}}const l=e=>"While running "+e.filter(e=>"\0"!==e).map(e=>{const t=JSON.stringify(e);return e.match(/\s/)||0===e.length||t!==`"${e}"`?t:e}).join(" ");function u(e){s&&console.log(e)}const h={candidateUsage:null,errorMessage:null,ignoreOptions:!1,path:[],positionals:[],options:[],remainder:null,selectedIndex:-1};function p(e,t){return e.nodes.push(t),e.nodes.length-1}function d(e,t,r=!1){u("Running a vm on "+JSON.stringify(t));let A=[{node:0,state:{candidateUsage:null,errorMessage:null,ignoreOptions:!1,options:[],path:[],positionals:[],remainder:null,selectedIndex:null}}];!function(e,{prefix:t=""}={}){u(t+"Nodes are:");for(let r=0;r2!==e).map(({state:e})=>({usage:e.candidateUsage,reason:null})));if(s.every(({node:e})=>2===e))throw new c(t,s.map(({state:e})=>({usage:e.candidateUsage,reason:e.errorMessage})));A=I(s)}if(A.length>0){u(" Results:");for(const e of A)u(` - ${e.node} -> ${JSON.stringify(e.state)}`)}else u(" No results");return A}function C(e,t){if(null!==t.selectedIndex)return!0;if(Object.prototype.hasOwnProperty.call(e.statics,"\0"))for(const{to:t}of e.statics["\0"])if(1===t)return!0;return!1}function f(e,t){return function(e,t){const r=t.filter(e=>null!==e.selectedIndex);if(0===r.length)throw new Error;let A=0;for(const e of r)e.path.length>A&&(A=e.path.length);const n=r.filter(e=>e.path.length===A),o=e=>e.positionals.filter(({extra:e})=>!e).length+e.options.length,i=n.map(e=>({state:e,positionalCount:o(e)}));let s=0;for(const{positionalCount:e}of i)e>s&&(s=e);const a=function(e){const t=[],r=[];for(const A of e)-1===A.selectedIndex?r.push(A):t.push(A);r.length>0&&t.push(Object.assign(Object.assign({},h),{path:E(...r.map(e=>e.path)),options:r.reduce((e,t)=>e.concat(t.options),[])}));return t}(i.filter(({positionalCount:e})=>e===s).map(({state:e})=>e));if(a.length>1)throw new g(e,a.map(e=>e.candidateUsage));return a[0]}(t,d(e,[...t,"\0"]).map(({state:e})=>e))}function I(e){let t=0;for(const{state:r}of e)r.path.length>t&&(t=r.path.length);return e.filter(({state:e})=>e.path.length===t)}function E(e,t,...r){return void 0===t?Array.from(e):E(e.filter((e,r)=>e===t[r]),...r)}function B(e){return 1===e||2===e}function y(e,t=0){return{to:B(e.to)?e.to:e.to>2?e.to+t-2:e.to+t,reducer:e.reducer}}function m(e,t=0){const r={dynamics:[],shortcuts:[],statics:{}};for(const[A,n]of e.dynamics)r.dynamics.push([A,y(n,t)]);for(const A of e.shortcuts)r.shortcuts.push(y(A,t));for(const[A,n]of Object.entries(e.statics))r.statics[A]=n.map(e=>y(e,t));return r}function w(e,t,r,A,n){e.nodes[t].dynamics.push([r,{to:A,reducer:n}])}function Q(e,t,r,A){e.nodes[t].shortcuts.push({to:r,reducer:A})}function D(e,t,r,A,n){(Object.prototype.hasOwnProperty.call(e.nodes[t].statics,r)?e.nodes[t].statics[r]:e.nodes[t].statics[r]=[]).push({to:A,reducer:n})}function b(e,t,r,A){if(Array.isArray(t)){const[n,...o]=t;return e[n](r,A,...o)}return e[t](r,A)}function v(e,t){const r=Array.isArray(e)?S[e[0]]:S[e];if(void 0===r.suggest)return null;const A=Array.isArray(e)?e.slice(1):[];return r.suggest(t,...A)}const S={always:()=>!0,isOptionLike:(e,t)=>!e.ignoreOptions&&t.startsWith("-"),isNotOptionLike:(e,t)=>e.ignoreOptions||!t.startsWith("-"),isOption:(e,t,r,A)=>!e.ignoreOptions&&t===r,isBatchOption:(e,t,r)=>!e.ignoreOptions&&o.test(t)&&[...t.slice(1)].every(e=>r.includes("-"+e)),isBoundOption:(e,t,r,A)=>{const o=t.match(i);return!e.ignoreOptions&&!!o&&n.test(o[1])&&r.includes(o[1])&&A.filter(e=>e.names.includes(o[1])).every(e=>e.allowBinding)},isNegatedOption:(e,t,r)=>!e.ignoreOptions&&t==="--no-"+r.slice(2),isHelp:(e,t)=>!e.ignoreOptions&&A.test(t),isUnsupportedOption:(e,t,r)=>!e.ignoreOptions&&t.startsWith("-")&&n.test(t)&&!r.includes(t),isInvalidOption:(e,t)=>!e.ignoreOptions&&t.startsWith("-")&&!n.test(t)};S.isOption.suggest=(e,t,r=!0)=>r?null:[t];const k={setCandidateUsage:(e,t,r)=>Object.assign(Object.assign({},e),{candidateUsage:r}),setSelectedIndex:(e,t,r)=>Object.assign(Object.assign({},e),{selectedIndex:r}),pushBatch:(e,t)=>Object.assign(Object.assign({},e),{options:e.options.concat([...t.slice(1)].map(e=>({name:"-"+e,value:!0})))}),pushBound:(e,t)=>{const[,r,A]=t.match(i);return Object.assign(Object.assign({},e),{options:e.options.concat({name:r,value:A})})},pushPath:(e,t)=>Object.assign(Object.assign({},e),{path:e.path.concat(t)}),pushPositional:(e,t)=>Object.assign(Object.assign({},e),{positionals:e.positionals.concat({value:t,extra:!1})}),pushExtra:(e,t)=>Object.assign(Object.assign({},e),{positionals:e.positionals.concat({value:t,extra:!0})}),pushExtraNoLimits:(e,t)=>Object.assign(Object.assign({},e),{positionals:e.positionals.concat({value:t,extra:N})}),pushTrue:(e,t,r=t)=>Object.assign(Object.assign({},e),{options:e.options.concat({name:t,value:!0})}),pushFalse:(e,t,r=t)=>Object.assign(Object.assign({},e),{options:e.options.concat({name:r,value:!1})}),pushUndefined:(e,t)=>Object.assign(Object.assign({},e),{options:e.options.concat({name:t,value:void 0})}),pushStringValue:(e,t)=>{var r;const A=Object.assign(Object.assign({},e),{options:[...e.options]}),n=e.options[e.options.length-1];return n.value=(null!==(r=n.value)&&void 0!==r?r:[]).concat([t]),A},setStringValue:(e,t)=>{const r=Object.assign(Object.assign({},e),{options:[...e.options]});return e.options[e.options.length-1].value=t,r},inhibateOptions:e=>Object.assign(Object.assign({},e),{ignoreOptions:!0}),useHelp:(e,t,r)=>{const[,n,o]=t.match(A);return void 0!==o?Object.assign(Object.assign({},e),{options:[{name:"-c",value:String(r)},{name:"-i",value:o}]}):Object.assign(Object.assign({},e),{options:[{name:"-c",value:String(r)}]})},setError:(e,t,r)=>"\0"===t?Object.assign(Object.assign({},e),{errorMessage:r+"."}):Object.assign(Object.assign({},e),{errorMessage:`${r} ("${t}").`}),setOptionArityError:(e,t)=>{const r=e.options[e.options.length-1];return Object.assign(Object.assign({},e),{errorMessage:`Not enough arguments to option ${r.name}.`})}},N=Symbol();class F{constructor(e,t){this.allOptionNames=[],this.arity={leading:[],trailing:[],extra:[],proxy:!1},this.options=[],this.paths=[],this.cliIndex=e,this.cliOpts=t}addPath(e){this.paths.push(e)}setArity({leading:e=this.arity.leading,trailing:t=this.arity.trailing,extra:r=this.arity.extra,proxy:A=this.arity.proxy}){Object.assign(this.arity,{leading:e,trailing:t,extra:r,proxy:A})}addPositional({name:e="arg",required:t=!0}={}){if(!t&&this.arity.extra===N)throw new Error("Optional parameters cannot be declared when using .rest() or .proxy()");if(!t&&this.arity.trailing.length>0)throw new Error("Optional parameters cannot be declared after the required trailing positional arguments");t||this.arity.extra===N?this.arity.extra!==N&&0===this.arity.extra.length?this.arity.leading.push(e):this.arity.trailing.push(e):this.arity.extra.push(e)}addRest({name:e="arg",required:t=0}={}){if(this.arity.extra===N)throw new Error("Infinite lists cannot be declared multiple times in the same command");if(this.arity.trailing.length>0)throw new Error("Infinite lists cannot be declared after the required trailing positional arguments");for(let r=0;r1)throw new Error("The arity cannot be higher than 1 when the option only supports the --arg=value syntax");if(!Number.isInteger(r))throw new Error("The arity must be an integer, got "+r);if(r<0)throw new Error("The arity must be positive, got "+r);this.allOptionNames.push(...e),this.options.push({names:e,description:t,arity:r,hidden:A,allowBinding:n})}setContext(e){this.context=e}usage({detailed:e=!0,inlineOptions:t=!0}={}){const r=[this.cliOpts.binaryName],A=[];if(this.paths.length>0&&r.push(...this.paths[0]),e){for(const{names:e,arity:n,hidden:o,description:i}of this.options){if(o)continue;const s=[];for(let e=0;e`<${e}>`)),this.arity.extra===N?r.push("..."):r.push(...this.arity.extra.map(e=>`[${e}]`)),r.push(...this.arity.trailing.map(e=>`<${e}>`))}return{usage:r.join(" "),options:A}}compile(){if(void 0===this.context)throw new Error("Assertion failed: No context attached");const e={nodes:[{dynamics:[],shortcuts:[],statics:{}},{dynamics:[],shortcuts:[],statics:{}},{dynamics:[],shortcuts:[],statics:{}}]};let t=0;t=p(e,{dynamics:[],shortcuts:[],statics:{}}),D(e,0,"",t,["setCandidateUsage",this.usage().usage]);const r=this.arity.proxy?"always":"isNotOptionLike",A=this.paths.length>0?this.paths:[[]];for(const n of A){let A=t;if(n.length>0){const t=p(e,{dynamics:[],shortcuts:[],statics:{}});Q(e,A,t),this.registerOptions(e,t),A=t}for(let t=0;t0||!this.arity.proxy){const t=p(e,{dynamics:[],shortcuts:[],statics:{}});w(e,A,"isHelp",t,["useHelp",this.cliIndex]),D(e,t,"\0",1,["setSelectedIndex",-1]),this.registerOptions(e,A)}this.arity.leading.length>0&&D(e,A,"\0",2,["setError","Not enough positional arguments"]);let o=A;for(let t=0;t0||t+1!==this.arity.leading.length)&&D(e,r,"\0",2,["setError","Not enough positional arguments"]),w(e,o,"isNotOptionLike",r,"pushPositional"),o=r}let i=o;if(this.arity.extra===N||this.arity.extra.length>0){const t=p(e,{dynamics:[],shortcuts:[],statics:{}});if(Q(e,o,t),this.arity.extra===N){const A=p(e,{dynamics:[],shortcuts:[],statics:{}});this.arity.proxy||this.registerOptions(e,A),w(e,o,r,A,"pushExtraNoLimits"),w(e,A,r,A,"pushExtraNoLimits"),Q(e,A,t)}else for(let A=0;A0&&D(e,i,"\0",2,["setError","Not enough positional arguments"]);let s=i;for(let t=0;tt.length>e.length?t:e,"");if(0===r.arity)for(const n of r.names)w(e,t,["isOption",n,r.hidden||n!==A],t,"pushTrue"),n.startsWith("--")&&!n.startsWith("--no-")&&w(e,t,["isNegatedOption",n],t,["pushFalse",n]);else{let n=p(e,{dynamics:[],shortcuts:[],statics:{}});for(const o of r.names)w(e,t,["isOption",o,r.hidden||o!==A],n,"pushUndefined");for(let t=0;t=0&&e{if(t.has(A))return;t.add(A);const n=e.nodes[A];for(const e of Object.values(n.statics))for(const{to:t}of e)r(t);for(const[,{to:e}]of n.dynamics)r(e);for(const{to:e}of n.shortcuts)r(e);const o=new Set(n.shortcuts.map(({to:e})=>e));for(;n.shortcuts.length>0;){const{to:t}=n.shortcuts.shift(),r=e.nodes[t];for(const[e,t]of Object.entries(r.statics)){let r=Object.prototype.hasOwnProperty.call(n.statics,e)?n.statics[e]:n.statics[e]=[];for(const e of t)r.some(({to:t})=>e.to===t)||r.push(e)}for(const[e,t]of r.dynamics)n.dynamics.some(([r,{to:A}])=>e===r&&t.to===A)||n.dynamics.push([e,t]);for(const e of r.shortcuts)o.has(e.to)||(n.shortcuts.push(e),o.add(e.to))}};r(0)}(r),{machine:r,contexts:t,process:e=>f(r,e),suggest:(e,t)=>function(e,t,r){const A=r&&t.length>0?[""]:[],n=d(e,t,r),o=[],i=new Set,s=(t,r,A=!0)=>{let n=[r];for(;n.length>0;){const r=n;n=[];for(const o of r){const r=e.nodes[o],i=Object.keys(r.statics);for(const e of Object.keys(r.statics)){const e=i[0];for(const{to:o,reducer:i}of r.statics[e])"pushPath"===i&&(A||t.push(e),n.push(o))}}A=!1}const s=JSON.stringify(t);i.has(s)||(o.push(t),i.add(s))};for(const{node:t,state:r}of n){if(null!==r.remainder){s([r.remainder],t);continue}const n=e.nodes[t],o=C(n,r);for(const[e,r]of Object.entries(n.statics))(o&&"\0"!==e||!e.startsWith("-")&&r.some(({reducer:e})=>"pushPath"===e))&&s([...A,e],t);if(o)for(const[e,{to:o}]of n.dynamics){if(2===o)continue;const n=v(e,r);if(null!==n)for(const e of n)s([...A,e],t)}}return[...o].sort()}(r,e,t)}}}class M{constructor(){this.help=!1}static getMeta(e){const t=e.constructor;return t.meta=Object.prototype.hasOwnProperty.call(t,"meta")?t.meta:{definitions:[],transformers:[(e,t)=>{for(const{name:r,value:A}of e.options)"-h"!==r&&"--help"!==r||(t.help=A)}]}}static resolveMeta(e){const t=[],r=[];for(let A=e;A instanceof M;A=A.__proto__){const e=this.getMeta(A);for(const r of e.definitions)t.push(r);for(const t of e.transformers)r.push(t)}return{definitions:t,transformers:r}}static registerDefinition(e,t){this.getMeta(e).definitions.push(t)}static registerTransformer(e,t){this.getMeta(e).transformers.push(t)}static addPath(...e){this.Path(...e)(this.prototype,"execute")}static addOption(e,t){t(this.prototype,e)}static Path(...e){return(t,r)=>{this.registerDefinition(t,t=>{t.addPath(e)})}}static Boolean(e,{hidden:t=!1,description:r}={}){return(A,n)=>{const o=e.split(",");this.registerDefinition(A,e=>{e.addOption({names:o,arity:0,hidden:t,allowBinding:!1,description:r})}),this.registerTransformer(A,(e,t)=>{for(const{name:r,value:A}of e.options)o.includes(r)&&(t[n]=A)})}}static Counter(e,{hidden:t=!1,description:r}={}){return(A,n)=>{const o=e.split(",");this.registerDefinition(A,e=>{e.addOption({names:o,arity:0,hidden:t,allowBinding:!1,description:r})}),this.registerTransformer(A,(e,t)=>{var r;for(const{name:A,value:i}of e.options)o.includes(A)&&(null!==(r=t[n])&&void 0!==r||(t[n]=0),i?t[n]++:t[n]=0)})}}static String(e={},{arity:t=1,tolerateBoolean:r=!1,hidden:A=!1,description:n}={}){return(o,i)=>{if("string"==typeof e){const s=e.split(",");this.registerDefinition(o,e=>{e.addOption({names:s,arity:r?0:t,hidden:A,description:n})}),this.registerTransformer(o,(e,t)=>{for(const{name:r,value:A}of e.options)s.includes(r)&&(t[i]=A)})}else{const{name:t=i,required:r=!0}=e;this.registerDefinition(o,e=>{e.addPositional({name:t,required:r})}),this.registerTransformer(o,(e,t)=>{for(let A=0;A{if(0===t)throw new Error("Array options are expected to have at least an arity of 1");const i=e.split(",");this.registerDefinition(n,e=>{e.addOption({names:i,arity:t,hidden:r,description:A})}),this.registerTransformer(n,(e,t)=>{for(const{name:r,value:A}of e.options)i.includes(r)&&(t[o]=t[o]||[],t[o].push(A))})}}static Rest({required:e=0}={}){return(t,r)=>{this.registerDefinition(t,t=>{t.addRest({name:r,required:e})}),this.registerTransformer(t,(e,t,A)=>{const n=t=>{const r=e.positionals[t];return r.extra===N||!1===r.extra&&te)})}}static Proxy({required:e=0}={}){return(t,r)=>{this.registerDefinition(t,t=>{t.addProxy({required:e})}),this.registerTransformer(t,(e,t)=>{t[r]=e.positionals.map(({value:e})=>e)})}}static Usage(e){return e}static Schema(e){return e}async catch(e){throw e}async validateAndExecute(){const e=this.constructor.schema;if(void 0!==e)try{await e.validate(this)}catch(e){throw"ValidationError"===e.name&&(e.clipanion={type:"usage"}),e}const t=await this.execute();return void 0!==t?t:0}} -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */ -function R(e,t,r,A){var n,o=arguments.length,i=o<3?t:null===A?A=Object.getOwnPropertyDescriptor(t,r):A;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,r,A);else for(var s=e.length-1;s>=0;s--)(n=e[s])&&(i=(o<3?n(i):o>3?n(t,r,i):n(t,r))||i);return o>3&&i&&Object.defineProperty(t,r,i),i}M.Entries={};class x extends M{async execute(){this.context.stdout.write(this.cli.usage(null))}}R([M.Path("--help"),M.Path("-h")],x.prototype,"execute",null);class L extends M{async execute(){var e;this.context.stdout.write((null!==(e=this.cli.binaryVersion)&&void 0!==e?e:"")+"\n")}}R([M.Path("--version"),M.Path("-v")],L.prototype,"execute",null);const P={bold:e=>`${e}`,error:e=>`${e}`,code:e=>`${e}`},O={bold:e=>e,error:e=>e,code:e=>e};function U(e,{format:t,paragraphs:r}){return e=(e=(e=(e=(e=e.replace(/\r\n?/g,"\n")).replace(/^[\t ]+|[\t ]+$/gm,"")).replace(/^\n+|\n+$/g,"")).replace(/^-([^\n]*?)\n+/gm,"-$1\n\n")).replace(/\n(\n)?\n*/g,"$1"),r&&(e=e.split(/\n/).map((function(e){let t=e.match(/^[*-][\t ]+(.*)/);return t?t[1].match(/(.{1,78})(?: |$)/g).map((e,t)=>(0===t?"- ":" ")+e).join("\n"):e.match(/(.{1,80})(?: |$)/g).join("\n")})).join("\n\n")),(e=e.replace(/(`+)((?:.|[\n])*?)\1/g,(function(e,r,A){return t.code(r+A+r)})))?e+"\n":""}class T extends M{constructor(e){super(),this.contexts=e,this.commands=[]}static from(e,t){const r=new T(t);r.path=e.path;for(const t of e.options)switch(t.name){case"-c":r.commands.push(Number(t.value));break;case"-i":r.index=Number(t.value)}return r}async execute(){let e=this.commands;if(void 0!==this.index&&this.index>=0&&this.index1){this.context.stdout.write("Multiple commands match your selection:\n"),this.context.stdout.write("\n");let e=0;for(const t of this.commands)this.context.stdout.write(this.cli.usage(this.contexts[t].commandClass,{prefix:(e+++". ").padStart(5)}));this.context.stdout.write("\n"),this.context.stdout.write("Run again with -h= to see the longer details of any of those commands.\n")}}}function j(){return"0"!==process.env.FORCE_COLOR&&("1"===process.env.FORCE_COLOR||!(void 0===process.stdout||!process.stdout.isTTY))}class Y{constructor({binaryLabel:e,binaryName:t="...",binaryVersion:r,enableColors:A=j()}={}){this.registrations=new Map,this.builder=new K({binaryName:t}),this.binaryLabel=e,this.binaryName=t,this.binaryVersion=r,this.enableColors=A}static from(e,t={}){const r=new Y(t);for(const t of e)r.register(t);return r}register(e){const t=this.builder.command();this.registrations.set(e,t.cliIndex);const{definitions:r}=e.resolveMeta(e.prototype);for(const e of r)e(t);t.setContext({commandClass:e})}process(e){const{contexts:t,process:r}=this.builder.compile(),A=r(e);switch(A.selectedIndex){case-1:return T.from(A,t);default:{const{commandClass:e}=t[A.selectedIndex],r=this.registrations.get(e);if(void 0===r)throw new Error("Assertion failed: Expected the command class to have been registered.");const n=this.builder.getBuilderByIndex(r),o=new e;o.path=A.path;const{transformers:i}=e.resolveMeta(e.prototype);for(const e of i)e(A,o,n);return o}}}async run(e,t){let r,A;if(Array.isArray(e))try{r=this.process(e)}catch(e){return t.stdout.write(this.error(e)),1}else r=e;if(r.help)return t.stdout.write(this.usage(r,{detailed:!0})),0;r.context=t,r.cli={binaryLabel:this.binaryLabel,binaryName:this.binaryName,binaryVersion:this.binaryVersion,enableColors:this.enableColors,definitions:()=>this.definitions(),error:(e,t)=>this.error(e,t),process:e=>this.process(e),run:(e,r)=>this.run(e,Object.assign(Object.assign({},t),r)),usage:(e,t)=>this.usage(e,t)};try{A=await r.validateAndExecute().catch(e=>r.catch(e).then(()=>0))}catch(e){return t.stdout.write(this.error(e,{command:r})),1}return A}async runExit(e,t){process.exitCode=await this.run(e,t)}suggest(e,t){const{contexts:r,process:A,suggest:n}=this.builder.compile();return n(e,t)}definitions({colored:e=!1}={}){const t=[];for(const[r,A]of this.registrations){if(void 0===r.usage)continue;const{usage:n}=this.getUsageByIndex(A,{detailed:!1}),{usage:o,options:i}=this.getUsageByIndex(A,{detailed:!0,inlineOptions:!1}),s=void 0!==r.usage.category?U(r.usage.category,{format:this.format(e),paragraphs:!1}):void 0,a=void 0!==r.usage.description?U(r.usage.description,{format:this.format(e),paragraphs:!1}):void 0,c=void 0!==r.usage.details?U(r.usage.details,{format:this.format(e),paragraphs:!0}):void 0,g=void 0!==r.usage.examples?r.usage.examples.map(([t,r])=>[U(t,{format:this.format(e),paragraphs:!1}),r.replace(/\$0/g,this.binaryName)]):void 0;t.push({path:n,usage:o,category:s,description:a,details:c,examples:g,options:i})}return t}usage(e=null,{colored:t,detailed:r=!1,prefix:A="$ "}={}){const n=null!==e&&void 0===e.getMeta?e.constructor:e;let o="";if(n)if(r){const{description:e="",details:r="",examples:i=[]}=n.usage||{};""!==e&&(o+=U(e,{format:this.format(t),paragraphs:!1}).replace(/^./,e=>e.toUpperCase()),o+="\n"),(""!==r||i.length>0)&&(o+=this.format(t).bold("Usage:")+"\n",o+="\n");const{usage:s,options:a}=this.getUsageByRegistration(n,{inlineOptions:!1});if(o+=`${this.format(t).bold(A)}${s}\n`,a.length>0){o+="\n",o+=P.bold("Options:")+"\n";const e=a.reduce((e,t)=>Math.max(e,t.definition.length),0);o+="\n";for(const{definition:r,description:A}of a)o+=` ${r.padEnd(e)} ${U(A,{format:this.format(t),paragraphs:!1})}`}if(""!==r&&(o+="\n",o+=this.format(t).bold("Details:")+"\n",o+="\n",o+=U(r,{format:this.format(t),paragraphs:!0})),i.length>0){o+="\n",o+=this.format(t).bold("Examples:")+"\n";for(let[e,r]of i)o+="\n",o+=U(e,{format:this.format(t),paragraphs:!1}),o+=r.replace(/^/m," "+this.format(t).bold(A)).replace(/\$0/g,this.binaryName)+"\n"}}else{const{usage:e}=this.getUsageByRegistration(n);o+=`${this.format(t).bold(A)}${e}\n`}else{const e=new Map;for(const[r,A]of this.registrations.entries()){if(void 0===r.usage)continue;const n=void 0!==r.usage.category?U(r.usage.category,{format:this.format(t),paragraphs:!1}):null;let o=e.get(n);void 0===o&&e.set(n,o=[]);const{usage:i}=this.getUsageByIndex(A);o.push({commandClass:r,usage:i})}const r=Array.from(e.keys()).sort((e,t)=>null===e?-1:null===t?1:e.localeCompare(t,"en",{usage:"sort",caseFirst:"upper"})),n=void 0!==this.binaryLabel,i=void 0!==this.binaryVersion;n||i?(o+=n&&i?this.format(t).bold(`${this.binaryLabel} - ${this.binaryVersion}`)+"\n\n":n?this.format(t).bold(""+this.binaryLabel)+"\n":this.format(t).bold(""+this.binaryVersion)+"\n",o+=` ${this.format(t).bold(A)}${this.binaryName} \n`):o+=`${this.format(t).bold(A)}${this.binaryName} \n`;for(let A of r){const r=e.get(A).slice().sort((e,t)=>e.usage.localeCompare(t.usage,"en",{usage:"sort",caseFirst:"upper"})),n=null!==A?A.trim():"Where is one of";o+="\n",o+=this.format(t).bold(n+":")+"\n";for(let{commandClass:e,usage:A}of r){const r=e.usage.description||"undocumented";o+="\n",o+=` ${this.format(t).bold(A)}\n`,o+=" "+U(r,{format:this.format(t),paragraphs:!1})}}o+="\n",o+=U("You can also print more details about any of these commands by calling them after adding the `-h,--help` flag right after the command name.",{format:this.format(t),paragraphs:!0})}return o}error(e,{colored:t,command:r=null}={}){e instanceof Error||(e=new Error(`Execution failed with a non-error rejection (rejected value: ${JSON.stringify(e)})`));let A="",n=e.name.replace(/([a-z])([A-Z])/g,"$1 $2");"Error"===n&&(n="Internal Error"),A+=`${this.format(t).error(n)}: ${e.message}\n`;const o=e.clipanion;return void 0!==o?"usage"===o.type&&(A+="\n",A+=this.usage(r)):e.stack&&(A+=e.stack.replace(/^.*\n/,"")+"\n"),A}getUsageByRegistration(e,t){const r=this.registrations.get(e);if(void 0===r)throw new Error("Assertion failed: Unregistered command");return this.getUsageByIndex(r,t)}getUsageByIndex(e,t){return this.builder.getBuilderByIndex(e).usage(t)}format(e=this.enableColors){return e?P:O}}Y.defaultContext={stdin:process.stdin,stdout:process.stdout,stderr:process.stderr},M.Entries.Help=x,M.Entries.Version=L},15751:(e,t,r)=>{"use strict";const A=r(92413).PassThrough,n=r(65007);e.exports=e=>{if(!e||!e.pipe)throw new TypeError("Parameter `response` must be a response stream.");const t=new A;return n(e,t),e.pipe(t)}},15311:(e,t,r)=>{const A=r(93300),n={};for(const e of Object.keys(A))n[A[e]]=e;const o={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};e.exports=o;for(const e of Object.keys(o)){if(!("channels"in o[e]))throw new Error("missing channels property: "+e);if(!("labels"in o[e]))throw new Error("missing channel labels property: "+e);if(o[e].labels.length!==o[e].channels)throw new Error("channel and label counts mismatch: "+e);const{channels:t,labels:r}=o[e];delete o[e].channels,delete o[e].labels,Object.defineProperty(o[e],"channels",{value:t}),Object.defineProperty(o[e],"labels",{value:r})}o.rgb.hsl=function(e){const t=e[0]/255,r=e[1]/255,A=e[2]/255,n=Math.min(t,r,A),o=Math.max(t,r,A),i=o-n;let s,a;o===n?s=0:t===o?s=(r-A)/i:r===o?s=2+(A-t)/i:A===o&&(s=4+(t-r)/i),s=Math.min(60*s,360),s<0&&(s+=360);const c=(n+o)/2;return a=o===n?0:c<=.5?i/(o+n):i/(2-o-n),[s,100*a,100*c]},o.rgb.hsv=function(e){let t,r,A,n,o;const i=e[0]/255,s=e[1]/255,a=e[2]/255,c=Math.max(i,s,a),g=c-Math.min(i,s,a),l=function(e){return(c-e)/6/g+.5};return 0===g?(n=0,o=0):(o=g/c,t=l(i),r=l(s),A=l(a),i===c?n=A-r:s===c?n=1/3+t-A:a===c&&(n=2/3+r-t),n<0?n+=1:n>1&&(n-=1)),[360*n,100*o,100*c]},o.rgb.hwb=function(e){const t=e[0],r=e[1];let A=e[2];const n=o.rgb.hsl(e)[0],i=1/255*Math.min(t,Math.min(r,A));return A=1-1/255*Math.max(t,Math.max(r,A)),[n,100*i,100*A]},o.rgb.cmyk=function(e){const t=e[0]/255,r=e[1]/255,A=e[2]/255,n=Math.min(1-t,1-r,1-A);return[100*((1-t-n)/(1-n)||0),100*((1-r-n)/(1-n)||0),100*((1-A-n)/(1-n)||0),100*n]},o.rgb.keyword=function(e){const t=n[e];if(t)return t;let r,o=1/0;for(const t of Object.keys(A)){const n=A[t],a=(s=n,((i=e)[0]-s[0])**2+(i[1]-s[1])**2+(i[2]-s[2])**2);a.04045?((t+.055)/1.055)**2.4:t/12.92,r=r>.04045?((r+.055)/1.055)**2.4:r/12.92,A=A>.04045?((A+.055)/1.055)**2.4:A/12.92;return[100*(.4124*t+.3576*r+.1805*A),100*(.2126*t+.7152*r+.0722*A),100*(.0193*t+.1192*r+.9505*A)]},o.rgb.lab=function(e){const t=o.rgb.xyz(e);let r=t[0],A=t[1],n=t[2];r/=95.047,A/=100,n/=108.883,r=r>.008856?r**(1/3):7.787*r+16/116,A=A>.008856?A**(1/3):7.787*A+16/116,n=n>.008856?n**(1/3):7.787*n+16/116;return[116*A-16,500*(r-A),200*(A-n)]},o.hsl.rgb=function(e){const t=e[0]/360,r=e[1]/100,A=e[2]/100;let n,o,i;if(0===r)return i=255*A,[i,i,i];n=A<.5?A*(1+r):A+r-A*r;const s=2*A-n,a=[0,0,0];for(let e=0;e<3;e++)o=t+1/3*-(e-1),o<0&&o++,o>1&&o--,i=6*o<1?s+6*(n-s)*o:2*o<1?n:3*o<2?s+(n-s)*(2/3-o)*6:s,a[e]=255*i;return a},o.hsl.hsv=function(e){const t=e[0];let r=e[1]/100,A=e[2]/100,n=r;const o=Math.max(A,.01);A*=2,r*=A<=1?A:2-A,n*=o<=1?o:2-o;return[t,100*(0===A?2*n/(o+n):2*r/(A+r)),100*((A+r)/2)]},o.hsv.rgb=function(e){const t=e[0]/60,r=e[1]/100;let A=e[2]/100;const n=Math.floor(t)%6,o=t-Math.floor(t),i=255*A*(1-r),s=255*A*(1-r*o),a=255*A*(1-r*(1-o));switch(A*=255,n){case 0:return[A,a,i];case 1:return[s,A,i];case 2:return[i,A,a];case 3:return[i,s,A];case 4:return[a,i,A];case 5:return[A,i,s]}},o.hsv.hsl=function(e){const t=e[0],r=e[1]/100,A=e[2]/100,n=Math.max(A,.01);let o,i;i=(2-r)*A;const s=(2-r)*n;return o=r*n,o/=s<=1?s:2-s,o=o||0,i/=2,[t,100*o,100*i]},o.hwb.rgb=function(e){const t=e[0]/360;let r=e[1]/100,A=e[2]/100;const n=r+A;let o;n>1&&(r/=n,A/=n);const i=Math.floor(6*t),s=1-A;o=6*t-i,0!=(1&i)&&(o=1-o);const a=r+o*(s-r);let c,g,l;switch(i){default:case 6:case 0:c=s,g=a,l=r;break;case 1:c=a,g=s,l=r;break;case 2:c=r,g=s,l=a;break;case 3:c=r,g=a,l=s;break;case 4:c=a,g=r,l=s;break;case 5:c=s,g=r,l=a}return[255*c,255*g,255*l]},o.cmyk.rgb=function(e){const t=e[0]/100,r=e[1]/100,A=e[2]/100,n=e[3]/100;return[255*(1-Math.min(1,t*(1-n)+n)),255*(1-Math.min(1,r*(1-n)+n)),255*(1-Math.min(1,A*(1-n)+n))]},o.xyz.rgb=function(e){const t=e[0]/100,r=e[1]/100,A=e[2]/100;let n,o,i;return n=3.2406*t+-1.5372*r+-.4986*A,o=-.9689*t+1.8758*r+.0415*A,i=.0557*t+-.204*r+1.057*A,n=n>.0031308?1.055*n**(1/2.4)-.055:12.92*n,o=o>.0031308?1.055*o**(1/2.4)-.055:12.92*o,i=i>.0031308?1.055*i**(1/2.4)-.055:12.92*i,n=Math.min(Math.max(0,n),1),o=Math.min(Math.max(0,o),1),i=Math.min(Math.max(0,i),1),[255*n,255*o,255*i]},o.xyz.lab=function(e){let t=e[0],r=e[1],A=e[2];t/=95.047,r/=100,A/=108.883,t=t>.008856?t**(1/3):7.787*t+16/116,r=r>.008856?r**(1/3):7.787*r+16/116,A=A>.008856?A**(1/3):7.787*A+16/116;return[116*r-16,500*(t-r),200*(r-A)]},o.lab.xyz=function(e){let t,r,A;r=(e[0]+16)/116,t=e[1]/500+r,A=r-e[2]/200;const n=r**3,o=t**3,i=A**3;return r=n>.008856?n:(r-16/116)/7.787,t=o>.008856?o:(t-16/116)/7.787,A=i>.008856?i:(A-16/116)/7.787,t*=95.047,r*=100,A*=108.883,[t,r,A]},o.lab.lch=function(e){const t=e[0],r=e[1],A=e[2];let n;n=360*Math.atan2(A,r)/2/Math.PI,n<0&&(n+=360);return[t,Math.sqrt(r*r+A*A),n]},o.lch.lab=function(e){const t=e[0],r=e[1],A=e[2]/360*2*Math.PI;return[t,r*Math.cos(A),r*Math.sin(A)]},o.rgb.ansi16=function(e,t=null){const[r,A,n]=e;let i=null===t?o.rgb.hsv(e)[2]:t;if(i=Math.round(i/50),0===i)return 30;let s=30+(Math.round(n/255)<<2|Math.round(A/255)<<1|Math.round(r/255));return 2===i&&(s+=60),s},o.hsv.ansi16=function(e){return o.rgb.ansi16(o.hsv.rgb(e),e[2])},o.rgb.ansi256=function(e){const t=e[0],r=e[1],A=e[2];if(t===r&&r===A)return t<8?16:t>248?231:Math.round((t-8)/247*24)+232;return 16+36*Math.round(t/255*5)+6*Math.round(r/255*5)+Math.round(A/255*5)},o.ansi16.rgb=function(e){let t=e%10;if(0===t||7===t)return e>50&&(t+=3.5),t=t/10.5*255,[t,t,t];const r=.5*(1+~~(e>50));return[(1&t)*r*255,(t>>1&1)*r*255,(t>>2&1)*r*255]},o.ansi256.rgb=function(e){if(e>=232){const t=10*(e-232)+8;return[t,t,t]}let t;e-=16;return[Math.floor(e/36)/5*255,Math.floor((t=e%36)/6)/5*255,t%6/5*255]},o.rgb.hex=function(e){const t=(((255&Math.round(e[0]))<<16)+((255&Math.round(e[1]))<<8)+(255&Math.round(e[2]))).toString(16).toUpperCase();return"000000".substring(t.length)+t},o.hex.rgb=function(e){const t=e.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!t)return[0,0,0];let r=t[0];3===t[0].length&&(r=r.split("").map(e=>e+e).join(""));const A=parseInt(r,16);return[A>>16&255,A>>8&255,255&A]},o.rgb.hcg=function(e){const t=e[0]/255,r=e[1]/255,A=e[2]/255,n=Math.max(Math.max(t,r),A),o=Math.min(Math.min(t,r),A),i=n-o;let s,a;return s=i<1?o/(1-i):0,a=i<=0?0:n===t?(r-A)/i%6:n===r?2+(A-t)/i:4+(t-r)/i,a/=6,a%=1,[360*a,100*i,100*s]},o.hsl.hcg=function(e){const t=e[1]/100,r=e[2]/100,A=r<.5?2*t*r:2*t*(1-r);let n=0;return A<1&&(n=(r-.5*A)/(1-A)),[e[0],100*A,100*n]},o.hsv.hcg=function(e){const t=e[1]/100,r=e[2]/100,A=t*r;let n=0;return A<1&&(n=(r-A)/(1-A)),[e[0],100*A,100*n]},o.hcg.rgb=function(e){const t=e[0]/360,r=e[1]/100,A=e[2]/100;if(0===r)return[255*A,255*A,255*A];const n=[0,0,0],o=t%1*6,i=o%1,s=1-i;let a=0;switch(Math.floor(o)){case 0:n[0]=1,n[1]=i,n[2]=0;break;case 1:n[0]=s,n[1]=1,n[2]=0;break;case 2:n[0]=0,n[1]=1,n[2]=i;break;case 3:n[0]=0,n[1]=s,n[2]=1;break;case 4:n[0]=i,n[1]=0,n[2]=1;break;default:n[0]=1,n[1]=0,n[2]=s}return a=(1-r)*A,[255*(r*n[0]+a),255*(r*n[1]+a),255*(r*n[2]+a)]},o.hcg.hsv=function(e){const t=e[1]/100,r=t+e[2]/100*(1-t);let A=0;return r>0&&(A=t/r),[e[0],100*A,100*r]},o.hcg.hsl=function(e){const t=e[1]/100,r=e[2]/100*(1-t)+.5*t;let A=0;return r>0&&r<.5?A=t/(2*r):r>=.5&&r<1&&(A=t/(2*(1-r))),[e[0],100*A,100*r]},o.hcg.hwb=function(e){const t=e[1]/100,r=t+e[2]/100*(1-t);return[e[0],100*(r-t),100*(1-r)]},o.hwb.hcg=function(e){const t=e[1]/100,r=1-e[2]/100,A=r-t;let n=0;return A<1&&(n=(r-A)/(1-A)),[e[0],100*A,100*n]},o.apple.rgb=function(e){return[e[0]/65535*255,e[1]/65535*255,e[2]/65535*255]},o.rgb.apple=function(e){return[e[0]/255*65535,e[1]/255*65535,e[2]/255*65535]},o.gray.rgb=function(e){return[e[0]/100*255,e[0]/100*255,e[0]/100*255]},o.gray.hsl=function(e){return[0,0,e[0]]},o.gray.hsv=o.gray.hsl,o.gray.hwb=function(e){return[0,100,e[0]]},o.gray.cmyk=function(e){return[0,0,0,e[0]]},o.gray.lab=function(e){return[e[0],0,0]},o.gray.hex=function(e){const t=255&Math.round(e[0]/100*255),r=((t<<16)+(t<<8)+t).toString(16).toUpperCase();return"000000".substring(r.length)+r},o.rgb.gray=function(e){return[(e[0]+e[1]+e[2])/3/255*100]}},2744:(e,t,r)=>{const A=r(15311),n=r(78577),o={};Object.keys(A).forEach(e=>{o[e]={},Object.defineProperty(o[e],"channels",{value:A[e].channels}),Object.defineProperty(o[e],"labels",{value:A[e].labels});const t=n(e);Object.keys(t).forEach(r=>{const A=t[r];o[e][r]=function(e){const t=function(...t){const r=t[0];if(null==r)return r;r.length>1&&(t=r);const A=e(t);if("object"==typeof A)for(let e=A.length,t=0;t1&&(t=r),e(t))};return"conversion"in e&&(t.conversion=e.conversion),t}(A)})}),e.exports=o},78577:(e,t,r)=>{const A=r(15311);function n(e){const t=function(){const e={},t=Object.keys(A);for(let r=t.length,A=0;A{"use strict";e.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},67566:(e,t,r)=>{"use strict";const A=r(63129),n=r(14951),o=r(10779);function i(e,t,r){const i=n(e,t,r),s=A.spawn(i.command,i.args,i.options);return o.hookChildProcess(s,i),s}e.exports=i,e.exports.spawn=i,e.exports.sync=function(e,t,r){const i=n(e,t,r),s=A.spawnSync(i.command,i.args,i.options);return s.error=s.error||o.verifyENOENTSync(s.status,i),s},e.exports._parse=n,e.exports._enoent=o},10779:e=>{"use strict";const t="win32"===process.platform;function r(e,t){return Object.assign(new Error(`${t} ${e.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${t} ${e.command}`,path:e.command,spawnargs:e.args})}function A(e,A){return t&&1===e&&!A.file?r(A.original,"spawn"):null}e.exports={hookChildProcess:function(e,r){if(!t)return;const n=e.emit;e.emit=function(t,o){if("exit"===t){const t=A(o,r);if(t)return n.call(e,"error",t)}return n.apply(e,arguments)}},verifyENOENT:A,verifyENOENTSync:function(e,A){return t&&1===e&&!A.file?r(A.original,"spawnSync"):null},notFoundError:r}},14951:(e,t,r)=>{"use strict";const A=r(85622),n=r(47447),o=r(27066),i=r(35187),s="win32"===process.platform,a=/\.(?:com|exe)$/i,c=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function g(e){if(!s)return e;const t=function(e){e.file=n(e);const t=e.file&&i(e.file);return t?(e.args.unshift(e.file),e.command=t,n(e)):e.file}(e),r=!a.test(t);if(e.options.forceShell||r){const r=c.test(t);e.command=A.normalize(e.command),e.command=o.command(e.command),e.args=e.args.map(e=>o.argument(e,r));const n=[e.command].concat(e.args).join(" ");e.args=["/d","/s","/c",`"${n}"`],e.command=process.env.comspec||"cmd.exe",e.options.windowsVerbatimArguments=!0}return e}e.exports=function(e,t,r){t&&!Array.isArray(t)&&(r=t,t=null);const A={command:e,args:t=t?t.slice(0):[],options:r=Object.assign({},r),file:void 0,original:{command:e,args:t}};return r.shell?A:g(A)}},27066:e=>{"use strict";const t=/([()\][%!^"`<>&|;, *?])/g;e.exports.command=function(e){return e=e.replace(t,"^$1")},e.exports.argument=function(e,r){return e=(e=`"${e=(e=(e=""+e).replace(/(\\*)"/g,'$1$1\\"')).replace(/(\\*)$/,"$1$1")}"`).replace(t,"^$1"),r&&(e=e.replace(t,"^$1")),e}},35187:(e,t,r)=>{"use strict";const A=r(35747),n=r(91470);e.exports=function(e){const t=Buffer.alloc(150);let r;try{r=A.openSync(e,"r"),A.readSync(r,t,0,150,0),A.closeSync(r)}catch(e){}return n(t.toString())}},47447:(e,t,r)=>{"use strict";const A=r(85622),n=r(87945),o=r(37127);function i(e,t){const r=e.options.env||process.env,i=process.cwd(),s=null!=e.options.cwd,a=s&&void 0!==process.chdir&&!process.chdir.disabled;if(a)try{process.chdir(e.options.cwd)}catch(e){}let c;try{c=n.sync(e.command,{path:r[o({env:r})],pathExt:t?A.delimiter:void 0})}catch(e){}finally{a&&process.chdir(i)}return c&&(c=A.resolve(s?e.options.cwd:"",c)),c}e.exports=function(e){return i(e)||i(e,!0)}},93868:(e,t,r)=>{"use strict";const{Transform:A,PassThrough:n}=r(92413),o=r(78761),i=r(33527);e.exports=e=>{const t=(e.headers["content-encoding"]||"").toLowerCase();if(!["gzip","deflate","br"].includes(t))return e;const r="br"===t;if(r&&"function"!=typeof o.createBrotliDecompress)return e.destroy(new Error("Brotli is not supported on Node.js < 12")),e;let s=!0;const a=new A({transform(e,t,r){s=!1,r(null,e)},flush(e){e()}}),c=new n({autoDestroy:!1,destroy(t,r){e.destroy(),r(t)}}),g=r?o.createBrotliDecompress():o.createUnzip();return g.once("error",t=>{!s||e.readable?c.destroy(t):c.end()}),i(e,c),e.pipe(a).pipe(g).pipe(c),c}},93121:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(4016),n=(e,t)=>{let r;if("function"==typeof t){r={connect:t}}else r=t;const n="function"==typeof r.connect,o="function"==typeof r.secureConnect,i="function"==typeof r.close,s=()=>{n&&r.connect(),e instanceof A.TLSSocket&&o&&(e.authorized?r.secureConnect():e.authorizationError||e.once("secureConnect",r.secureConnect)),i&&e.once("close",r.close)};e.writable&&!e.connecting?s():e.connecting?e.once("connect",s):e.destroyed&&i&&r.close(e._hadError)};t.default=n,e.exports=n,e.exports.default=n},66241:(e,t,r)=>{"use strict";const A=r(85622),n=r(5763),o=e=>e.length>1?`{${e.join(",")}}`:e[0],i=(e,t)=>{const r="!"===e[0]?e.slice(1):e;return A.isAbsolute(r)?r:A.join(t,r)},s=(e,t)=>{if(t.files&&!Array.isArray(t.files))throw new TypeError(`Expected \`files\` to be of type \`Array\` but received type \`${typeof t.files}\``);if(t.extensions&&!Array.isArray(t.extensions))throw new TypeError(`Expected \`extensions\` to be of type \`Array\` but received type \`${typeof t.extensions}\``);return t.files&&t.extensions?t.files.map(r=>{return A.posix.join(e,(n=r,i=t.extensions,A.extname(n)?"**/"+n:`**/${n}.${o(i)}`));var n,i}):t.files?t.files.map(t=>A.posix.join(e,"**/"+t)):t.extensions?[A.posix.join(e,"**/*."+o(t.extensions))]:[A.posix.join(e,"**")]};e.exports=async(e,t)=>{if("string"!=typeof(t={cwd:process.cwd(),...t}).cwd)throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof t.cwd}\``);const r=await Promise.all([].concat(e).map(async e=>await n.isDirectory(i(e,t.cwd))?s(e,t):e));return[].concat.apply([],r)},e.exports.sync=(e,t)=>{if("string"!=typeof(t={cwd:process.cwd(),...t}).cwd)throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof t.cwd}\``);const r=[].concat(e).map(e=>n.isDirectorySync(i(e,t.cwd))?s(e,t):e);return[].concat.apply([],r)}},97681:(e,t,r)=>{var A=r(91162),n=function(){},o=function(e,t,r){if("function"==typeof t)return o(e,null,t);t||(t={}),r=A(r||n);var i=e._writableState,s=e._readableState,a=t.readable||!1!==t.readable&&e.readable,c=t.writable||!1!==t.writable&&e.writable,g=function(){e.writable||l()},l=function(){c=!1,a||r()},u=function(){a=!1,c||r()},h=function(e){r(e?new Error("exited with error code: "+e):null)},p=function(){return(!a||s&&s.ended)&&(!c||i&&i.ended)?void 0:r(new Error("premature close"))},d=function(){e.req.on("finish",l)};return!function(e){return e.setHeader&&"function"==typeof e.abort}(e)?c&&!i&&(e.on("end",g),e.on("close",g)):(e.on("complete",l),e.on("abort",p),e.req?d():e.on("request",d)),function(e){return e.stdio&&Array.isArray(e.stdio)&&3===e.stdio.length}(e)&&e.on("exit",h),e.on("end",u),e.on("finish",l),!1!==t.error&&e.on("error",r),e.on("close",p),function(){e.removeListener("complete",l),e.removeListener("abort",p),e.removeListener("request",d),e.req&&e.req.removeListener("finish",l),e.removeListener("end",g),e.removeListener("close",g),e.removeListener("finish",l),e.removeListener("exit",h),e.removeListener("end",u),e.removeListener("error",r),e.removeListener("close",p)}};e.exports=o},17067:(e,t,r)=>{var A=r(27180),n=function(){},o=function(e,t,r){if("function"==typeof t)return o(e,null,t);t||(t={}),r=A(r||n);var i=e._writableState,s=e._readableState,a=t.readable||!1!==t.readable&&e.readable,c=t.writable||!1!==t.writable&&e.writable,g=function(){e.writable||l()},l=function(){c=!1,a||r.call(e)},u=function(){a=!1,c||r.call(e)},h=function(t){r.call(e,t?new Error("exited with error code: "+t):null)},p=function(t){r.call(e,t)},d=function(){return(!a||s&&s.ended)&&(!c||i&&i.ended)?void 0:r.call(e,new Error("premature close"))},C=function(){e.req.on("finish",l)};return!function(e){return e.setHeader&&"function"==typeof e.abort}(e)?c&&!i&&(e.on("end",g),e.on("close",g)):(e.on("complete",l),e.on("abort",d),e.req?C():e.on("request",C)),function(e){return e.stdio&&Array.isArray(e.stdio)&&3===e.stdio.length}(e)&&e.on("exit",h),e.on("end",u),e.on("finish",l),!1!==t.error&&e.on("error",p),e.on("close",d),function(){e.removeListener("complete",l),e.removeListener("abort",d),e.removeListener("request",C),e.req&&e.req.removeListener("finish",l),e.removeListener("end",g),e.removeListener("close",g),e.removeListener("finish",l),e.removeListener("exit",h),e.removeListener("end",u),e.removeListener("error",p),e.removeListener("close",d)}};e.exports=o},61899:(e,t,r)=>{"use strict";const A=r(42357),n=r(28614),o=r(10278);class i extends n{constructor(e,t){super(),this.options=o.merge({},e),this.answers={...t}}register(e,t){if(o.isObject(e)){for(let t of Object.keys(e))this.register(t,e[t]);return this}A.equal(typeof t,"function","expected a function");let r=e.toLowerCase();return t.prototype instanceof this.Prompt?this.prompts[r]=t:this.prompts[r]=t(this.Prompt,this),this}async prompt(e=[]){for(let t of[].concat(e))try{"function"==typeof t&&(t=await t.call(this)),await this.ask(o.merge({},this.options,t))}catch(e){return Promise.reject(e)}return this.answers}async ask(e){"function"==typeof e&&(e=await e.call(this));let t=o.merge({},this.options,e),{type:r,name:n}=e,{set:i,get:s}=o;if("function"==typeof r&&(r=await r.call(this,e,this.answers)),!r)return this.answers[n];A(this.prompts[r],`Prompt "${r}" is not registered`);let a=new this.prompts[r](t),c=s(this.answers,n);a.state.answers=this.answers,a.enquirer=this,n&&a.on("submit",e=>{this.emit("answer",n,e,a),i(this.answers,n,e)});let g=a.emit.bind(a);return a.emit=(...e)=>(this.emit.call(this,...e),g(...e)),this.emit("prompt",a,this),t.autofill&&null!=c?(a.value=a.input=c,"show"===t.autofill&&await a.submit()):c=a.value=await a.run(),c}use(e){return e.call(this,this),this}set Prompt(e){this._Prompt=e}get Prompt(){return this._Prompt||this.constructor.Prompt}get prompts(){return this.constructor.prompts}static set Prompt(e){this._Prompt=e}static get Prompt(){return this._Prompt||r(58386)}static get prompts(){return r(53609)}static get types(){return r(13235)}static get prompt(){const e=(t,...r)=>{let A=new this(...r),n=A.emit.bind(A);return A.emit=(...t)=>(e.emit(...t),n(...t)),A.prompt(t)};return o.mixinEmitter(e,new n),e}}o.mixinEmitter(i,new n);const s=i.prompts;for(let e of Object.keys(s)){let t=e.toLowerCase(),r=t=>new s[e](t).run();i.prompt[t]=r,i[t]=r,i[e]||Reflect.defineProperty(i,e,{get:()=>s[e]})}const a=e=>{o.defineExport(i,e,()=>i.types[e])};a("ArrayPrompt"),a("AuthPrompt"),a("BooleanPrompt"),a("NumberPrompt"),a("StringPrompt"),e.exports=i},72380:(e,t,r)=>{"use strict";const A="Apple_Terminal"===process.env.TERM_PROGRAM,n=r(97991),o=r(10278),i=e.exports=t,s="[";let a=!1;const c=i.code={bell:"",beep:"",beginning:"",down:"",esc:s,getPosition:"",hide:"[?25l",line:"",lineEnd:"",lineStart:"",restorePosition:s+(A?"8":"u"),savePosition:s+(A?"7":"s"),screen:"",show:"[?25h",up:""},g=i.cursor={get hidden(){return a},hide:()=>(a=!0,c.hide),show:()=>(a=!1,c.show),forward:(e=1)=>`[${e}C`,backward:(e=1)=>`[${e}D`,nextLine:(e=1)=>"".repeat(e),prevLine:(e=1)=>"".repeat(e),up:(e=1)=>e?`[${e}A`:"",down:(e=1)=>e?`[${e}B`:"",right:(e=1)=>e?`[${e}C`:"",left:(e=1)=>e?`[${e}D`:"",to:(e,t)=>t?`[${t+1};${e+1}H`:`[${e+1}G`,move(e=0,t=0){let r="";return r+=e<0?g.left(-e):e>0?g.right(e):"",r+=t<0?g.up(-t):t>0?g.down(t):"",r},restore(e={}){let{after:t,cursor:r,initial:A,input:n,prompt:s,size:a,value:c}=e;if(A=o.isPrimitive(A)?String(A):"",n=o.isPrimitive(n)?String(n):"",c=o.isPrimitive(c)?String(c):"",a){let e=i.cursor.up(a)+i.cursor.to(s.length),t=n.length-r;return t>0&&(e+=i.cursor.left(t)),e}if(c||t){let e=!n&&A?-A.length:-n.length+r;return t&&(e-=t.length),""===n&&A&&!s.includes(A)&&(e+=A.length),i.cursor.move(e)}}},l=i.erase={screen:c.screen,up:c.up,down:c.down,line:c.line,lineEnd:c.lineEnd,lineStart:c.lineStart,lines(e){let t="";for(let r=0;r{if(!t)return l.line+g.to(0);let r=e.split(/\r?\n/),A=0;for(let e of r)A+=1+Math.floor(Math.max((o=e,[...n.unstyle(o)].length-1),0)/t);var o;return(l.line+g.prevLine()).repeat(A-1)+l.line+g.to(0)}},62475:(e,t)=>{"use strict";t.ctrl={a:"first",b:"backward",c:"cancel",d:"deleteForward",e:"last",f:"forward",g:"reset",i:"tab",k:"cutForward",l:"reset",n:"newItem",m:"cancel",j:"submit",p:"search",r:"remove",s:"save",u:"undo",w:"cutLeft",x:"toggleCursor",v:"paste"},t.shift={up:"shiftUp",down:"shiftDown",left:"shiftLeft",right:"shiftRight",tab:"prev"},t.fn={up:"pageUp",down:"pageDown",left:"pageLeft",right:"pageRight",delete:"deleteForward"},t.option={b:"backward",f:"forward",d:"cutRight",left:"cutLeft",up:"altUp",down:"altDown"},t.keys={pageup:"pageUp",pagedown:"pageDown",home:"home",end:"end",cancel:"cancel",delete:"deleteForward",backspace:"delete",down:"down",enter:"submit",escape:"cancel",left:"left",space:"space",number:"number",return:"submit",right:"right",tab:"next",up:"up"}},64083:e=>{"use strict";const t=e=>(e=>e.filter((t,r)=>e.lastIndexOf(t)===r))(e).filter(Boolean);e.exports=(e,r={},A="")=>{let n,o,{past:i=[],present:s=""}=r;switch(e){case"prev":case"undo":return n=i.slice(0,i.length-1),o=i[i.length-1]||"",{past:t([A,...n]),present:o};case"next":case"redo":return n=i.slice(1),o=i[0]||"",{past:t([...n,A]),present:o};case"save":return{past:t([...i,A]),present:""};case"remove":return o=t(i.filter(e=>e!==A)),s="",o.length&&(s=o.pop()),{past:o,present:s};default:throw new Error(`Invalid action: "${e}"`)}}},84368:(e,t,r)=>{"use strict";const A=r(97991);class n{constructor(e){this.name=e.key,this.field=e.field||{},this.value=((e="")=>"string"==typeof e?e.replace(/^['"]|['"]$/g,""):"")(e.initial||this.field.initial||""),this.message=e.message||this.name,this.cursor=0,this.input="",this.lines=[]}}function o(e,t,r,A){return(r,n,o,i)=>"function"==typeof o.field[e]?o.field[e].call(t,r,n,o,i):[A,r].find(e=>t.isValue(e))}e.exports=async e=>{let t=e.options,r=new Set(!0===t.required?[]:t.required||[]),i={...t.values,...t.initial},{tabstops:s,items:a,keys:c}=await(async(e={},t={},r=(e=>e))=>{let A=new Set,o=e.fields||[],i=e.template,s=[],a=[],c=[],g=1;"function"==typeof i&&(i=await i());let l=-1,u=()=>i[++l],h=()=>i[l+1],p=e=>{e.line=g,s.push(e)};for(p({type:"bos",value:""});le.name===s.key);s.field=o.find(e=>e.name===s.key),g||(g=new n(s),a.push(g)),g.lines.push(s.line-1);continue}let i=s[s.length-1];"text"===i.type&&i.line===g?i.value+=e:p({type:"text",value:e})}return p({type:"eos",value:""}),{input:i,tabstops:s,unique:A,keys:c,items:a}})(t,i),g=o("result",e,t),l=o("format",e,t),u=o("validate",e,t,!0),h=e.isValue.bind(e);return async(n={},o=!1)=>{let i=0;n.required=r,n.items=a,n.keys=c,n.output="";let p=async(e,t,r,A)=>{let n=await u(e,t,r,A);return!1===n?"Invalid field "+r.name:n};for(let r of s){let s=r.value,c=r.key;if("template"===r.type){if("template"===r.type){let u=a.find(e=>e.name===c);!0===t.required&&n.required.add(u.name);let d=[u.input,n.values[u.value],u.value,s].find(h),C=(u.field||{}).message||r.inner;if(o){let e=await p(n.values[c],n,u,i);if(e&&"string"==typeof e||!1===e){n.invalid.set(c,e);continue}n.invalid.delete(c);let t=await g(n.values[c],n,u,i);n.output+=A.unstyle(t);continue}u.placeholder=!1;let f=s;s=await l(s,n,u,i),d!==s?(n.values[c]=d,s=e.styles.typing(d),n.missing.delete(C)):(n.values[c]=void 0,d=`<${C}>`,s=e.styles.primary(d),u.placeholder=!0,n.required.has(c)&&n.missing.add(C)),n.missing.has(C)&&n.validating&&(s=e.styles.warning(d)),n.invalid.has(c)&&n.validating&&(s=e.styles.danger(d)),i===n.index&&(s=f!==s?e.styles.underline(s):e.styles.heading(A.unstyle(s))),i++}s&&(n.output+=s)}else s&&(n.output+=s)}let d=n.output.split("\n").map(e=>" "+e),C=a.length,f=0;for(let t of a)n.invalid.has(t.name)&&t.lines.forEach(e=>{" "===d[e][0]&&(d[e]=n.styles.danger(n.symbols.bullet)+d[e].slice(1))}),e.isValue(n.values[t.name])&&f++;return n.completed=(f/C*100).toFixed(0),n.output=d.join("\n"),n.output}}},30650:(e,t,r)=>{"use strict";const A=r(51058),n=r(62475),o=/^(?:\x1b)([a-zA-Z0-9])$/,i=/^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/,s={OP:"f1",OQ:"f2",OR:"f3",OS:"f4","[11~":"f1","[12~":"f2","[13~":"f3","[14~":"f4","[[A":"f1","[[B":"f2","[[C":"f3","[[D":"f4","[[E":"f5","[15~":"f5","[17~":"f6","[18~":"f7","[19~":"f8","[20~":"f9","[21~":"f10","[23~":"f11","[24~":"f12","[A":"up","[B":"down","[C":"right","[D":"left","[E":"clear","[F":"end","[H":"home",OA:"up",OB:"down",OC:"right",OD:"left",OE:"clear",OF:"end",OH:"home","[1~":"home","[2~":"insert","[3~":"delete","[4~":"end","[5~":"pageup","[6~":"pagedown","[[5~":"pageup","[[6~":"pagedown","[7~":"home","[8~":"end","[a":"up","[b":"down","[c":"right","[d":"left","[e":"clear","[2$":"insert","[3$":"delete","[5$":"pageup","[6$":"pagedown","[7$":"home","[8$":"end",Oa:"up",Ob:"down",Oc:"right",Od:"left",Oe:"clear","[2^":"insert","[3^":"delete","[5^":"pageup","[6^":"pagedown","[7^":"home","[8^":"end","[Z":"tab"};const a=(e="",t={})=>{let r,A={name:t.name,ctrl:!1,meta:!1,shift:!1,option:!1,sequence:e,raw:e,...t};if(Buffer.isBuffer(e)?e[0]>127&&void 0===e[1]?(e[0]-=128,e=""+String(e)):e=String(e):void 0!==e&&"string"!=typeof e?e=String(e):e||(e=A.sequence||""),A.sequence=A.sequence||e||A.name,"\r"===e)A.raw=void 0,A.name="return";else if("\n"===e)A.name="enter";else if("\t"===e)A.name="tab";else if("\b"===e||""===e||""===e||"\b"===e)A.name="backspace",A.meta=""===e.charAt(0);else if(""===e||""===e)A.name="escape",A.meta=2===e.length;else if(" "===e||" "===e)A.name="space",A.meta=2===e.length;else if(e<="")A.name=String.fromCharCode(e.charCodeAt(0)+"a".charCodeAt(0)-1),A.ctrl=!0;else if(1===e.length&&e>="0"&&e<="9")A.name="number";else if(1===e.length&&e>="a"&&e<="z")A.name=e;else if(1===e.length&&e>="A"&&e<="Z")A.name=e.toLowerCase(),A.shift=!0;else if(r=o.exec(e))A.meta=!0,A.shift=/^[A-Z]$/.test(r[1]);else if(r=i.exec(e)){let t=[...e];""===t[0]&&""===t[1]&&(A.option=!0);let n=[r[1],r[2],r[4],r[6]].filter(Boolean).join(""),o=(r[3]||r[5]||1)-1;A.ctrl=!!(4&o),A.meta=!!(10&o),A.shift=!!(1&o),A.code=n,A.name=s[n],A.shift=function(e){return["[a","[b","[c","[d","[e","[2$","[3$","[5$","[6$","[7$","[8$","[Z"].includes(e)}(n)||A.shift,A.ctrl=function(e){return["Oa","Ob","Oc","Od","Oe","[2^","[3^","[5^","[6^","[7^","[8^"].includes(e)}(n)||A.ctrl}return A};a.listen=(e={},t)=>{let{stdin:r}=e;if(!r||r!==process.stdin&&!r.isTTY)throw new Error("Invalid stream passed");let n=A.createInterface({terminal:!0,input:r});A.emitKeypressEvents(r,n);let o=(e,r)=>t(e,a(e,r),n),i=r.isRaw;r.isTTY&&r.setRawMode(!0),r.on("keypress",o),n.resume();return()=>{r.isTTY&&r.setRawMode(i),r.removeListener("keypress",o),n.pause(),n.close()}},a.action=(e,t,r)=>{let A={...n,...r};return t.ctrl?(t.action=A.ctrl[t.name],t):t.option&&A.option?(t.action=A.option[t.name],t):t.shift?(t.action=A.shift[t.name],t):(t.action=A.keys[t.name],t)},e.exports=a},96496:(e,t,r)=>{"use strict";const A=r(10278);e.exports=(e,t={})=>{e.cursorHide();let{input:r="",initial:n="",pos:o,showCursor:i=!0,color:s}=t,a=s||e.styles.placeholder,c=A.inverse(e.styles.primary),g=t=>c(e.styles.black(t)),l=r,u=g(" ");if(e.blink&&!0===e.blink.off&&(g=e=>e,u=""),i&&0===o&&""===n&&""===r)return g(" ");if(i&&0===o&&(r===n||""===r))return g(n[0])+a(n.slice(1));n=A.isPrimitive(n)?""+n:"",r=A.isPrimitive(r)?""+r:"";let h=n&&n.startsWith(r)&&n!==r,p=h?g(n[r.length]):u;if(o!==r.length&&!0===i&&(l=r.slice(0,o)+g(r[o])+r.slice(o+1),p=""),!1===i&&(p=""),h){let t=e.styles.unstyle(l+p);return l+p+a(n.slice(t.length))}return l+p}},58386:(e,t,r)=>{"use strict";const A=r(28614),n=r(97991),o=r(30650),i=r(47159),s=r(61807),a=r(26205),c=r(10278),g=r(72380);class l extends A{constructor(e={}){super(),this.name=e.name,this.type=e.type,this.options=e,a(this),i(this),this.state=new s(this),this.initial=[e.initial,e.default].find(e=>null!=e),this.stdout=e.stdout||process.stdout,this.stdin=e.stdin||process.stdin,this.scale=e.scale||1,this.term=this.options.term||process.env.TERM_PROGRAM,this.margin=function(e){"number"==typeof e&&(e=[e,e,e,e]);let t=[].concat(e||[]),r=e=>e%2==0?"\n":" ",A=[];for(let e=0;e<4;e++){let n=r(e);t[e]?A.push(n.repeat(t[e])):A.push("")}return A}(this.options.margin),this.setMaxListeners(0),function(e){let t=t=>void 0===e[t]||"function"==typeof e[t],r=["actions","choices","initial","margin","roles","styles","symbols","theme","timers","value"],A=["body","footer","error","header","hint","indicator","message","prefix","separator","skip"];for(let n of Object.keys(e.options)){if(r.includes(n))continue;if(/^on[A-Z]/.test(n))continue;let o=e.options[n];"function"==typeof o&&t(n)?A.includes(n)||(e[n]=o.bind(e)):"function"!=typeof e[n]&&(e[n]=o)}}(this)}async keypress(e,t={}){this.keypressed=!0;let r=o.action(e,o(e,t),this.options.actions);this.state.keypress=r,this.emit("keypress",e,r),this.emit("state",this.state.clone());let A=this.options[r.action]||this[r.action]||this.dispatch;if("function"==typeof A)return await A.call(this,e,r);this.alert()}alert(){delete this.state.alert,!1===this.options.show?this.emit("alert"):this.stdout.write(g.code.beep)}cursorHide(){this.stdout.write(g.cursor.hide()),c.onExit(()=>this.cursorShow())}cursorShow(){this.stdout.write(g.cursor.show())}write(e){e&&(this.stdout&&!1!==this.state.show&&this.stdout.write(e),this.state.buffer+=e)}clear(e=0){let t=this.state.buffer;this.state.buffer="",(t||e)&&!1!==this.options.show&&this.stdout.write(g.cursor.down(e)+g.clear(t,this.width))}restore(){if(this.state.closed||!1===this.options.show)return;let{prompt:e,after:t,rest:r}=this.sections(),{cursor:A,initial:n="",input:o="",value:i=""}=this,s={after:t,cursor:A,initial:n,input:o,prompt:e,size:this.state.size=r.length,value:i},a=g.cursor.restore(s);a&&this.stdout.write(a)}sections(){let{buffer:e,input:t,prompt:r}=this.state;r=n.unstyle(r);let A=n.unstyle(e),o=A.indexOf(r),i=A.slice(0,o),s=A.slice(o).split("\n"),a=s[0],c=s[s.length-1],g=(r+(t?" "+t:"")).length,l=ge.call(this,this.value),this.result=()=>r.call(this,this.value),"function"==typeof t.initial&&(this.initial=await t.initial.call(this,this)),"function"==typeof t.onRun&&await t.onRun.call(this,this),"function"==typeof t.onSubmit){let e=t.onSubmit.bind(this),r=this.submit.bind(this);delete this.options.onSubmit,this.submit=async()=>(await e(this.name,this.value,this),r())}await this.start(),await this.render()}render(){throw new Error("expected prompt to have a custom render method")}run(){return new Promise(async(e,t)=>{if(this.once("submit",e),this.once("cancel",t),await this.skip())return this.render=()=>{},this.submit();await this.initialize(),this.emit("run")})}async element(e,t,r){let{options:A,state:n,symbols:o,timers:i}=this,s=i&&i[e];n.timer=s;let a=A[e]||n[e]||o[e],c=t&&null!=t[e]?t[e]:await a;if(""===c)return c;let g=await this.resolve(c,n,t,r);return!g&&t&&t[e]?this.resolve(a,n,t,r):g}async prefix(){let e=await this.element("prefix")||this.symbols,t=this.timers&&this.timers.prefix,r=this.state;if(r.timer=t,c.isObject(e)&&(e=e[r.status]||e.pending),!c.hasColor(e)){return(this.styles[r.status]||this.styles.pending)(e)}return e}async message(){let e=await this.element("message");return c.hasColor(e)?e:this.styles.strong(e)}async separator(){let e=await this.element("separator")||this.symbols,t=this.timers&&this.timers.separator,r=this.state;r.timer=t;let A=e[r.status]||e.pending||r.separator,n=await this.resolve(A,r);return c.isObject(n)&&(n=n[r.status]||n.pending),c.hasColor(n)?n:this.styles.muted(n)}async pointer(e,t){let r=await this.element("pointer",e,t);if("string"==typeof r&&c.hasColor(r))return r;if(r){let e=this.styles,A=this.index===t,n=A?e.primary:e=>e,o=await this.resolve(r[A?"on":"off"]||r,this.state),i=c.hasColor(o)?o:n(o);return A?i:" ".repeat(o.length)}}async indicator(e,t){let r=await this.element("indicator",e,t);if("string"==typeof r&&c.hasColor(r))return r;if(r){let t=this.styles,A=!0===e.enabled,n=A?t.success:t.dark,o=r[A?"on":"off"]||r;return c.hasColor(o)?o:n(o)}return""}body(){return null}footer(){if("pending"===this.state.status)return this.element("footer")}header(){if("pending"===this.state.status)return this.element("header")}async hint(){if("pending"===this.state.status&&!this.isValue(this.state.input)){let e=await this.element("hint");return c.hasColor(e)?e:this.styles.muted(e)}}error(e){return this.state.submitted?"":e||this.state.error}format(e){return e}result(e){return e}validate(e){return!0!==this.options.required||this.isValue(e)}isValue(e){return null!=e&&""!==e}resolve(e,...t){return c.resolve(this,e,...t)}get base(){return l.prototype}get style(){return this.styles[this.state.status]}get height(){return this.options.rows||c.height(this.stdout,25)}get width(){return this.options.columns||c.width(this.stdout,80)}get size(){return{width:this.width,height:this.height}}set cursor(e){this.state.cursor=e}get cursor(){return this.state.cursor}set input(e){this.state.input=e}get input(){return this.state.input}set value(e){this.state.value=e}get value(){let{input:e,value:t}=this.state,r=[t,e].find(this.isValue.bind(this));return this.isValue(r)?r:this.initial}static get prompt(){return e=>new this(e).run()}}e.exports=l},63310:(e,t,r)=>{"use strict";const A=r(31557);e.exports=class extends A{constructor(e){super(e),this.cursorShow()}moveCursor(e){this.state.cursor+=e}dispatch(e){return this.append(e)}space(e){return this.options.multiple?super.space(e):this.append(e)}append(e){let{cursor:t,input:r}=this.state;return this.input=r.slice(0,t)+e+r.slice(t),this.moveCursor(1),this.complete()}delete(){let{cursor:e,input:t}=this.state;return t?(this.input=t.slice(0,e-1)+t.slice(e),this.moveCursor(-1),this.complete()):this.alert()}deleteForward(){let{cursor:e,input:t}=this.state;return void 0===t[e]?this.alert():(this.input=(""+t).slice(0,e)+(""+t).slice(e+1),this.complete())}number(e){return this.append(e)}async complete(){this.completing=!0,this.choices=await this.suggest(this.input,this.state._choices),this.state.limit=void 0,this.index=Math.min(Math.max(this.visible.length-1,0),this.index),await this.render(),this.completing=!1}suggest(e=this.input,t=this.state._choices){if("function"==typeof this.options.suggest)return this.options.suggest.call(this,e,t);let r=e.toLowerCase();return t.filter(e=>e.message.toLowerCase().includes(r))}pointer(){return""}format(){if(!this.focused)return this.input;if(this.options.multiple&&this.state.submitted)return this.selected.map(e=>this.styles.primary(e.message)).join(", ");if(this.state.submitted){let e=this.value=this.input=this.focused.value;return this.styles.primary(e)}return this.input}async render(){if("pending"!==this.state.status)return super.render();let e=this.options.highlight?this.options.highlight.bind(this):this.styles.placeholder,t=((e,t)=>{let r=e.toLowerCase();return e=>{let A=e.toLowerCase().indexOf(r),n=t(e.slice(A,A+r.length));return A>=0?e.slice(0,A)+n+e.slice(A+r.length):e}})(this.input,e),r=this.choices;this.choices=r.map(e=>({...e,message:t(e.message)})),await super.render(),this.choices=r}submit(){return this.options.multiple&&(this.value=this.selected.map(e=>e.name)),super.submit()}}},52810:(e,t,r)=>{"use strict";const A=r(46614);function n(e,t){return e.username===this.options.username&&e.password===this.options.password}const o=(e=n)=>{const t=[{name:"username",message:"username"},{name:"password",message:"password",format(e){if(this.options.showPassword)return e;return(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(e.length))}}];class r extends(A.create(e)){constructor(e){super({...e,choices:t})}static create(e){return o(e)}}return r};e.exports=o()},65742:(e,t,r)=>{"use strict";const A=r(82710);e.exports=class extends A{constructor(e){super(e),this.default=this.options.default||(this.initial?"(Y/n)":"(y/N)")}}},24570:(e,t,r)=>{"use strict";const A=r(31557),n=r(71447).prototype;e.exports=class extends A{constructor(e){super({...e,multiple:!0}),this.align=[this.options.align,"left"].find(e=>null!=e),this.emptyError="",this.values={}}dispatch(e,t){let r=this.focused,A=r.parent||{};return r.editable||A.editable||"a"!==e&&"i"!==e?n.dispatch.call(this,e,t):super[e]()}append(e,t){return n.append.call(this,e,t)}delete(e,t){return n.delete.call(this,e,t)}space(e){return this.focused.editable?this.append(e):super.space()}number(e){return this.focused.editable?this.append(e):super.number(e)}next(){return this.focused.editable?n.next.call(this):super.next()}prev(){return this.focused.editable?n.prev.call(this):super.prev()}async indicator(e,t){let r=e.indicator||"",A=e.editable?r:super.indicator(e,t);return await this.resolve(A,this.state,e,t)||""}indent(e){return"heading"===e.role?"":e.editable?" ":" "}async renderChoice(e,t){return e.indent="",e.editable?n.renderChoice.call(this,e,t):super.renderChoice(e,t)}error(){return""}footer(){return this.state.error}async validate(){let e=!0;for(let t of this.choices){if("function"!=typeof t.validate)continue;if("heading"===t.role)continue;let r=t.parent?this.value[t.parent.name]:this.value;if(t.editable?r=t.value===t.name?t.initial||"":t.value:this.isDisabled(t)||(r=!0===t.enabled),e=await t.validate(r,this.state),!0!==e)break}return!0!==e&&(this.state.error="string"==typeof e?e:"Invalid Input"),e}submit(){if(!0===this.focused.newChoice)return super.submit();if(this.choices.some(e=>e.newChoice))return this.alert();this.value={};for(let e of this.choices){let t=e.parent?this.value[e.parent.name]:this.value;"heading"!==e.role?e.editable?t[e.name]=e.value===e.name?e.initial||"":e.value:this.isDisabled(e)||(t[e.name]=!0===e.enabled):this.value[e.name]={}}return this.base.submit.call(this)}}},71447:(e,t,r)=>{"use strict";const A=r(97991),n=r(31557),o=r(96496);e.exports=class extends n{constructor(e){super({...e,multiple:!0}),this.type="form",this.initial=this.options.initial,this.align=[this.options.align,"right"].find(e=>null!=e),this.emptyError="",this.values={}}async reset(e){return await super.reset(),!0===e&&(this._index=this.index),this.index=this._index,this.values={},this.choices.forEach(e=>e.reset&&e.reset()),this.render()}dispatch(e){return!!e&&this.append(e)}append(e){let t=this.focused;if(!t)return this.alert();let{cursor:r,input:A}=t;return t.value=t.input=A.slice(0,r)+e+A.slice(r),t.cursor++,this.render()}delete(){let e=this.focused;if(!e||e.cursor<=0)return this.alert();let{cursor:t,input:r}=e;return e.value=e.input=r.slice(0,t-1)+r.slice(t),e.cursor--,this.render()}deleteForward(){let e=this.focused;if(!e)return this.alert();let{cursor:t,input:r}=e;if(void 0===r[t])return this.alert();let A=(""+r).slice(0,t)+(""+r).slice(t+1);return e.value=e.input=A,this.render()}right(){let e=this.focused;return e?e.cursor>=e.input.length?this.alert():(e.cursor++,this.render()):this.alert()}left(){let e=this.focused;return e?e.cursor<=0?this.alert():(e.cursor--,this.render()):this.alert()}space(e,t){return this.dispatch(e,t)}number(e,t){return this.dispatch(e,t)}next(){let e=this.focused;if(!e)return this.alert();let{initial:t,input:r}=e;return t&&t.startsWith(r)&&r!==t?(e.value=e.input=t,e.cursor=e.value.length,this.render()):super.next()}prev(){let e=this.focused;return e?0===e.cursor?super.prev():(e.value=e.input="",e.cursor=0,this.render()):this.alert()}separator(){return""}format(e){return this.state.submitted?"":super.format(e)}pointer(){return""}indicator(e){return e.input?"⦿":"⊙"}async choiceSeparator(e,t){let r=await this.resolve(e.separator,this.state,e,t)||":";return r?" "+this.styles.disabled(r):""}async renderChoice(e,t){await this.onChoice(e,t);let{state:r,styles:n}=this,{cursor:i,initial:s="",name:a,hint:c,input:g=""}=e,{muted:l,submitted:u,primary:h,danger:p}=n,d=c,C=this.index===t,f=e.validate||(()=>!0),I=await this.choiceSeparator(e,t),E=e.message;"right"===this.align&&(E=E.padStart(this.longest+1," ")),"left"===this.align&&(E=E.padEnd(this.longest+1," "));let B=this.values[a]=g||s,y=g?"success":"dark";!0!==await f.call(e,B,this.state)&&(y="danger");let m=(0,n[y])(await this.indicator(e,t))+(e.pad||""),w=this.indent(e),Q=()=>[w,m,E+I,g,d].filter(Boolean).join(" ");if(r.submitted)return E=A.unstyle(E),g=u(g),d="",Q();if(e.format)g=await e.format.call(this,g,e,t);else{let e=this.styles.muted;g=o(this,{input:g,initial:s,pos:i,showCursor:C,color:e})}return this.isValue(g)||(g=this.styles.muted(this.symbols.ellipsis)),e.result&&(this.values[a]=await e.result.call(this,B,e,t)),C&&(E=h(E)),e.error?g+=(g?" ":"")+p(e.error.trim()):e.hint&&(g+=(g?" ":"")+l(e.hint.trim())),Q()}async submit(){return this.value=this.values,super.base.submit.call(this)}}},53609:(e,t,r)=>{"use strict";const A=r(10278),n=(e,r)=>{A.defineExport(t,e,r),A.defineExport(t,e.toLowerCase(),r)};n("AutoComplete",()=>r(63310)),n("BasicAuth",()=>r(52810)),n("Confirm",()=>r(65742)),n("Editable",()=>r(24570)),n("Form",()=>r(71447)),n("Input",()=>r(12372)),n("Invisible",()=>r(32684)),n("List",()=>r(40876)),n("MultiSelect",()=>r(42293)),n("Numeral",()=>r(42126)),n("Password",()=>r(84697)),n("Scale",()=>r(99580)),n("Select",()=>r(31557)),n("Snippet",()=>r(98094)),n("Sort",()=>r(60042)),n("Survey",()=>r(25223)),n("Text",()=>r(97298)),n("Toggle",()=>r(41817)),n("Quiz",()=>r(88677))},12372:(e,t,r)=>{"use strict";const A=r(45853),n=r(64083);e.exports=class extends A{constructor(e){super(e);let t=this.options.history;if(t&&t.store){let e=t.values||this.initial;this.autosave=!!t.autosave,this.store=t.store,this.data=this.store.get("values")||{past:[],present:e},this.initial=this.data.present||this.data.past[this.data.past.length-1]}}completion(e){return this.store?(this.data=n(e,this.data,this.input),this.data.present?(this.input=this.data.present,this.cursor=this.input.length,this.render()):this.alert()):this.alert()}altUp(){return this.completion("prev")}altDown(){return this.completion("next")}prev(){return this.save(),super.prev()}save(){this.store&&(this.data=n("save",this.data,this.input),this.store.set("values",this.data))}submit(){return this.store&&!0===this.autosave&&this.save(),super.submit()}}},32684:(e,t,r)=>{"use strict";const A=r(45853);e.exports=class extends A{format(){return""}}},40876:(e,t,r)=>{"use strict";const A=r(45853);e.exports=class extends A{constructor(e={}){super(e),this.sep=this.options.separator||/, */,this.initial=e.initial||""}split(e=this.value){return e?String(e).split(this.sep):[]}format(){let e=this.state.submitted?this.styles.primary:e=>e;return this.list.map(e).join(", ")}async submit(e){let t=this.state.error||await this.validate(this.list,this.state);return!0!==t?(this.state.error=t,super.submit()):(this.value=this.list,super.submit())}get list(){return this.split()}}},42293:(e,t,r)=>{"use strict";const A=r(31557);e.exports=class extends A{constructor(e){super({...e,multiple:!0})}}},42126:(e,t,r)=>{e.exports=r(64987)},84697:(e,t,r)=>{"use strict";const A=r(45853);e.exports=class extends A{constructor(e){super(e),this.cursorShow()}format(e=this.input){if(!this.keypressed)return"";return(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(e.length))}}},88677:(e,t,r)=>{"use strict";const A=r(31557);e.exports=class extends A{constructor(e){if(super(e),"number"!=typeof this.options.correctChoice||this.options.correctChoice<0)throw new Error("Please specify the index of the correct answer from the list of choices")}async toChoices(e,t){let r=await super.toChoices(e,t);if(r.length<2)throw new Error("Please give at least two choices to the user");if(this.options.correctChoice>r.length)throw new Error("Please specify the index of the correct answer from the list of choices");return r}check(e){return e.index===this.options.correctChoice}async result(e){return{selectedAnswer:e,correctAnswer:this.options.choices[this.options.correctChoice].value,correct:await this.check(this.state)}}}},99580:(e,t,r)=>{"use strict";const A=r(97991),n=r(14723),o=r(10278);e.exports=class extends n{constructor(e={}){super(e),this.widths=[].concat(e.messageWidth||50),this.align=[].concat(e.align||"left"),this.linebreak=e.linebreak||!1,this.edgeLength=e.edgeLength||3,this.newline=e.newline||"\n ";let t=e.startNumber||1;"number"==typeof this.scale&&(this.scaleKey=!1,this.scale=Array(this.scale).fill(0).map((e,r)=>({name:r+t})))}async reset(){return this.tableized=!1,await super.reset(),this.render()}tableize(){if(!0===this.tableized)return;this.tableized=!0;let e=0;for(let t of this.choices){e=Math.max(e,t.message.length),t.scaleIndex=t.initial||2,t.scale=[];for(let e=0;e=this.scale.length-1?this.alert():(e.scaleIndex++,this.render())}left(){let e=this.focused;return e.scaleIndex<=0?this.alert():(e.scaleIndex--,this.render())}indent(){return""}format(){if(this.state.submitted){return this.choices.map(e=>this.styles.info(e.index)).join(", ")}return""}pointer(){return""}renderScaleKey(){if(!1===this.scaleKey)return"";if(this.state.submitted)return"";return["",...this.scale.map(e=>` ${e.name} - ${e.message}`)].map(e=>this.styles.muted(e)).join("\n")}renderScaleHeading(e){let t=this.scale.map(e=>e.name);"function"==typeof this.options.renderScaleHeading&&(t=this.options.renderScaleHeading.call(this,e));let r=this.scaleLength-t.join("").length,A=Math.round(r/(t.length-1)),n=t.map(e=>this.styles.strong(e)).join(" ".repeat(A)),o=" ".repeat(this.widths[0]);return this.margin[3]+o+this.margin[1]+n}scaleIndicator(e,t,r){if("function"==typeof this.options.scaleIndicator)return this.options.scaleIndicator.call(this,e,t,r);let A=e.scaleIndex===t.index;return t.disabled?this.styles.hint(this.symbols.radio.disabled):A?this.styles.success(this.symbols.radio.on):this.symbols.radio.off}renderScale(e,t){let r=e.scale.map(r=>this.scaleIndicator(e,r,t)),A="Hyper"===this.term?"":" ";return r.join(A+this.symbols.line.repeat(this.edgeLength))}async renderChoice(e,t){await this.onChoice(e,t);let r=this.index===t,n=await this.pointer(e,t),i=await e.hint;i&&!o.hasColor(i)&&(i=this.styles.muted(i));let s=e=>this.margin[3]+e.replace(/\s+$/,"").padEnd(this.widths[0]," "),a=this.newline,c=this.indent(e),g=await this.resolve(e.message,this.state,e,t),l=await this.renderScale(e,t),u=this.margin[1]+this.margin[3];this.scaleLength=A.unstyle(l).length,this.widths[0]=Math.min(this.widths[0],this.width-this.scaleLength-u.length);let h=o.wordWrap(g,{width:this.widths[0],newline:a}).split("\n").map(e=>s(e)+this.margin[1]);return r&&(l=this.styles.info(l),h=h.map(e=>this.styles.info(e))),h[0]+=l,this.linebreak&&h.push(""),[c+n,h.join("\n")].filter(Boolean)}async renderChoices(){if(this.state.submitted)return"";this.tableize();let e=this.visible.map(async(e,t)=>await this.renderChoice(e,t)),t=await Promise.all(e),r=await this.renderScaleHeading();return this.margin[0]+[r,...t.map(e=>e.join(" "))].join("\n")}async render(){let{submitted:e,size:t}=this.state,r=await this.prefix(),A=await this.separator(),n=await this.message(),o="";!1!==this.options.promptLine&&(o=[r,n,A,""].join(" "),this.state.prompt=o);let i=await this.header(),s=await this.format(),a=await this.renderScaleKey(),c=await this.error()||await this.hint(),g=await this.renderChoices(),l=await this.footer(),u=this.emptyError;s&&(o+=s),c&&!o.includes(c)&&(o+=" "+c),e&&!s&&!g.trim()&&this.multiple&&null!=u&&(o+=this.styles.danger(u)),this.clear(t),this.write([i,o,a,g,l].filter(Boolean).join("\n")),this.state.submitted||this.write(this.margin[2]),this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIndex;return this.base.submit.call(this)}}},31557:(e,t,r)=>{"use strict";const A=r(14723),n=r(10278);e.exports=class extends A{constructor(e){super(e),this.emptyError=this.options.emptyError||"No items were selected"}async dispatch(e,t){if(this.multiple)return this[t.name]?await this[t.name](e,t):await super.dispatch(e,t);this.alert()}separator(){if(this.options.separator)return super.separator();let e=this.styles.muted(this.symbols.ellipsis);return this.state.submitted?super.separator():e}pointer(e,t){return!this.multiple||this.options.pointer?super.pointer(e,t):""}indicator(e,t){return this.multiple?super.indicator(e,t):""}choiceMessage(e,t){let r=this.resolve(e.message,this.state,e,t);return"heading"!==e.role||n.hasColor(r)||(r=this.styles.strong(r)),this.resolve(r,this.state,e,t)}choiceSeparator(){return":"}async renderChoice(e,t){await this.onChoice(e,t);let r=this.index===t,A=await this.pointer(e,t),o=await this.indicator(e,t)+(e.pad||""),i=await this.resolve(e.hint,this.state,e,t);i&&!n.hasColor(i)&&(i=this.styles.muted(i));let s=this.indent(e),a=await this.choiceMessage(e,t),c=()=>[this.margin[3],s+A+o,a,this.margin[1],i].filter(Boolean).join(" ");return"heading"===e.role?c():e.disabled?(n.hasColor(a)||(a=this.styles.disabled(a)),c()):(r&&(a=this.styles.em(a)),c())}async renderChoices(){if("choices"===this.state.loading)return this.styles.warning("Loading choices");if(this.state.submitted)return"";let e=this.visible.map(async(e,t)=>await this.renderChoice(e,t)),t=await Promise.all(e);t.length||t.push(this.styles.danger("No matching choices"));let r,A=this.margin[0]+t.join("\n");return this.options.choicesHeader&&(r=await this.resolve(this.options.choicesHeader,this.state)),[r,A].filter(Boolean).join("\n")}format(){return!this.state.submitted||this.state.cancelled?"":Array.isArray(this.selected)?this.selected.map(e=>this.styles.primary(e.name)).join(", "):this.styles.primary(this.selected.name)}async render(){let{submitted:e,size:t}=this.state,r="",A=await this.header(),n=await this.prefix(),o=await this.separator(),i=await this.message();!1!==this.options.promptLine&&(r=[n,i,o,""].join(" "),this.state.prompt=r);let s=await this.format(),a=await this.error()||await this.hint(),c=await this.renderChoices(),g=await this.footer();s&&(r+=s),a&&!r.includes(a)&&(r+=" "+a),e&&!s&&!c.trim()&&this.multiple&&null!=this.emptyError&&(r+=this.styles.danger(this.emptyError)),this.clear(t),this.write([A,r,c,g].filter(Boolean).join("\n")),this.write(this.margin[2]),this.restore()}}},98094:(e,t,r)=>{"use strict";const A=r(97991),n=r(84368),o=r(58386);e.exports=class extends o{constructor(e){super(e),this.cursorHide(),this.reset(!0)}async initialize(){this.interpolate=await n(this),await super.initialize()}async reset(e){this.state.keys=[],this.state.invalid=new Map,this.state.missing=new Set,this.state.completed=0,this.state.values={},!0!==e&&(await this.initialize(),await this.render())}moveCursor(e){let t=this.getItem();this.cursor+=e,t.cursor+=e}dispatch(e,t){t.code||t.ctrl||null==e||!this.getItem()?this.alert():this.append(e,t)}append(e,t){let r=this.getItem(),A=r.input.slice(0,this.cursor),n=r.input.slice(this.cursor);this.input=r.input=`${A}${e}${n}`,this.moveCursor(1),this.render()}delete(){let e=this.getItem();if(this.cursor<=0||!e.input)return this.alert();let t=e.input.slice(this.cursor),r=e.input.slice(0,this.cursor-1);this.input=e.input=`${r}${t}`,this.moveCursor(-1),this.render()}increment(e){return e>=this.state.keys.length-1?0:e+1}decrement(e){return e<=0?this.state.keys.length-1:e-1}first(){this.state.index=0,this.render()}last(){this.state.index=this.state.keys.length-1,this.render()}right(){if(this.cursor>=this.input.length)return this.alert();this.moveCursor(1),this.render()}left(){if(this.cursor<=0)return this.alert();this.moveCursor(-1),this.render()}prev(){this.state.index=this.decrement(this.state.index),this.getItem(),this.render()}next(){this.state.index=this.increment(this.state.index),this.getItem(),this.render()}up(){this.prev()}down(){this.next()}format(e){let t=this.state.completed<100?this.styles.warning:this.styles.success;return!0===this.state.submitted&&100!==this.state.completed&&(t=this.styles.danger),t(this.state.completed+"% completed")}async render(){let{index:e,keys:t=[],submitted:r,size:A}=this.state,n=[this.options.newline,"\n"].find(e=>null!=e),o=await this.prefix(),i=await this.separator(),s=[o,await this.message(),i].filter(Boolean).join(" ");this.state.prompt=s;let a=await this.header(),c=await this.error()||"",g=await this.hint()||"",l=r?"":await this.interpolate(this.state),u=this.state.key=t[e]||"",h=await this.format(u),p=await this.footer();h&&(s+=" "+h),g&&!h&&0===this.state.completed&&(s+=" "+g),this.clear(A);let d=[a,s,l,p,c.trim()];this.write(d.filter(Boolean).join(n)),this.restore()}getItem(e){let{items:t,keys:r,index:A}=this.state,n=t.find(e=>e.name===r[A]);return n&&null!=n.input&&(this.input=n.input,this.cursor=n.cursor),n}async submit(){"function"!=typeof this.interpolate&&await this.initialize(),await this.interpolate(this.state,!0);let{invalid:e,missing:t,output:r,values:n}=this.state;if(e.size){let t="";for(let[r,A]of e)t+=`Invalid ${r}: ${A}\n`;return this.state.error=t,super.submit()}if(t.size)return this.state.error="Required: "+[...t.keys()].join(", "),super.submit();let o=A.unstyle(r).split("\n").map(e=>e.slice(1)).join("\n");return this.value={values:n,result:o},super.submit()}}},60042:(e,t,r)=>{"use strict";const A="(Use + to sort)",n=r(31557);e.exports=class extends n{constructor(e){super({...e,reorder:!1,sort:!0,multiple:!0}),this.state.hint=[this.options.hint,A].find(this.isValue.bind(this))}indicator(){return""}async renderChoice(e,t){let r=await super.renderChoice(e,t),A=this.symbols.identicalTo+" ",n=this.index===t&&this.sorting?this.styles.muted(A):" ";return!1===this.options.drag&&(n=""),!0===this.options.numbered?n+(t+1+" - ")+r:n+r}get selected(){return this.choices}submit(){return this.value=this.choices.map(e=>e.value),super.submit()}}},25223:(e,t,r)=>{"use strict";const A=r(14723);function n(e,t={}){if(Array.isArray(t.scale))return t.scale.map(e=>({...e}));let r=[];for(let t=1;tthis.styles.muted(e)),this.state.header=e.join("\n ")}}async toChoices(...e){if(this.createdScales)return!1;this.createdScales=!0;let t=await super.toChoices(...e);for(let e of t)e.scale=n(5,this.options),e.scaleIdx=2;return t}dispatch(){this.alert()}space(){let e=this.focused,t=e.scale[e.scaleIdx],r=t.selected;return e.scale.forEach(e=>e.selected=!1),t.selected=!r,this.render()}indicator(){return""}pointer(){return""}separator(){return this.styles.muted(this.symbols.ellipsis)}right(){let e=this.focused;return e.scaleIdx>=e.scale.length-1?this.alert():(e.scaleIdx++,this.render())}left(){let e=this.focused;return e.scaleIdx<=0?this.alert():(e.scaleIdx--,this.render())}indent(){return" "}async renderChoice(e,t){await this.onChoice(e,t);let r=this.index===t,A="Hyper"===this.term,n=A?9:8,o=A?"":" ",i=this.symbols.line.repeat(n),s=" ".repeat(n+(A?0:1)),a=e=>(e?this.styles.success("◉"):"◯")+o,c=t+1+".",g=r?this.styles.heading:this.styles.noop,l=await this.resolve(e.message,this.state,e,t),u=this.indent(e),h=u+e.scale.map((t,r)=>a(r===e.scaleIdx)).join(i),p=u+e.scale.map((t,r)=>(t=>t===e.scaleIdx?g(t):t)(r)).join(s);return r&&(h=this.styles.cyan(h),p=this.styles.cyan(p)),[[c,l].filter(Boolean).join(" "),h,p," "].filter(Boolean).join("\n")}async renderChoices(){if(this.state.submitted)return"";let e=this.visible.map(async(e,t)=>await this.renderChoice(e,t)),t=await Promise.all(e);return t.length||t.push(this.styles.danger("No matching choices")),t.join("\n")}format(){if(this.state.submitted){return this.choices.map(e=>this.styles.info(e.scaleIdx)).join(", ")}return""}async render(){let{submitted:e,size:t}=this.state,r=await this.prefix(),A=await this.separator(),n=[r,await this.message(),A].filter(Boolean).join(" ");this.state.prompt=n;let o=await this.header(),i=await this.format(),s=await this.error()||await this.hint(),a=await this.renderChoices(),c=await this.footer();!i&&s||(n+=" "+i),s&&!n.includes(s)&&(n+=" "+s),e&&!i&&!a&&this.multiple&&"form"!==this.type&&(n+=this.styles.danger(this.emptyError)),this.clear(t),this.write([n,o,a,c].filter(Boolean).join("\n")),this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIdx;return this.base.submit.call(this)}}},97298:(e,t,r)=>{e.exports=r(12372)},41817:(e,t,r)=>{"use strict";const A=r(82710);e.exports=class extends A{async initialize(){await super.initialize(),this.value=this.initial=!!this.options.initial,this.disabled=this.options.disabled||"no",this.enabled=this.options.enabled||"yes",await this.render()}reset(){this.value=this.initial,this.render()}delete(){this.alert()}toggle(){this.value=!this.value,this.render()}enable(){if(!0===this.value)return this.alert();this.value=!0,this.render()}disable(){if(!1===this.value)return this.alert();this.value=!1,this.render()}up(){this.toggle()}down(){this.toggle()}right(){this.toggle()}left(){this.toggle()}next(){this.toggle()}prev(){this.toggle()}dispatch(e="",t){switch(e.toLowerCase()){case" ":return this.toggle();case"1":case"y":case"t":return this.enable();case"0":case"n":case"f":return this.disable();default:return this.alert()}}format(){let e=e=>this.styles.primary.underline(e);return[this.value?this.disabled:e(this.disabled),this.value?e(this.enabled):this.enabled].join(this.styles.muted(" / "))}async render(){let{size:e}=this.state,t=await this.header(),r=await this.prefix(),A=await this.separator(),n=await this.message(),o=await this.format(),i=await this.error()||await this.hint(),s=await this.footer(),a=[r,n,A,o].join(" ");this.state.prompt=a,i&&!a.includes(i)&&(a+=" "+i),this.clear(e),this.write([t,a,s].filter(Boolean).join("\n")),this.write(this.margin[2]),this.restore()}}},27011:(e,t,r)=>{"use strict";const A=r(10278),n={default:(e,t)=>t,checkbox(e,t){throw new Error("checkbox role is not implemented yet")},editable(e,t){throw new Error("editable role is not implemented yet")},expandable(e,t){throw new Error("expandable role is not implemented yet")},heading:(e,t)=>(t.disabled="",t.indicator=[t.indicator," "].find(e=>null!=e),t.message=t.message||"",t),input(e,t){throw new Error("input role is not implemented yet")},option:(e,t)=>n.default(e,t),radio(e,t){throw new Error("radio role is not implemented yet")},separator:(e,t)=>(t.disabled="",t.indicator=[t.indicator," "].find(e=>null!=e),t.message=t.message||e.symbols.line.repeat(5),t),spacer:(e,t)=>t};e.exports=(e,t={})=>{let r=A.merge({},n,t.roles);return r[e]||r.default}},61807:(e,t,r)=>{"use strict";const{define:A,width:n}=r(10278);e.exports=class{constructor(e){let t=e.options;A(this,"_prompt",e),this.type=e.type,this.name=e.name,this.message="",this.header="",this.footer="",this.error="",this.hint="",this.input="",this.cursor=0,this.index=0,this.lines=0,this.tick=0,this.prompt="",this.buffer="",this.width=n(t.stdout||process.stdout),Object.assign(this,t),this.name=this.name||this.message,this.message=this.message||this.name,this.symbols=e.symbols,this.styles=e.styles,this.required=new Set,this.cancelled=!1,this.submitted=!1}clone(){let e={...this};return e.status=this.status,e.buffer=Buffer.from(e.buffer),delete e.clone,e}set color(e){this._color=e}get color(){let e=this.prompt.styles;if(this.cancelled)return e.cancelled;if(this.submitted)return e.submitted;let t=this._color||e[this.status];return"function"==typeof t?t:e.pending}set loading(e){this._loading=e}get loading(){return"boolean"==typeof this._loading?this._loading:!!this.loadingChoices&&"choices"}get status(){return this.cancelled?"cancelled":this.submitted?"submitted":"pending"}}},64402:(e,t,r)=>{"use strict";const A=r(10278),n=r(97991),o={default:n.noop,noop:n.noop,set inverse(e){this._inverse=e},get inverse(){return this._inverse||A.inverse(this.primary)},set complement(e){this._complement=e},get complement(){return this._complement||A.complement(this.primary)},primary:n.cyan,success:n.green,danger:n.magenta,strong:n.bold,warning:n.yellow,muted:n.dim,disabled:n.gray,dark:n.dim.gray,underline:n.underline,set info(e){this._info=e},get info(){return this._info||this.primary},set em(e){this._em=e},get em(){return this._em||this.primary.underline},set heading(e){this._heading=e},get heading(){return this._heading||this.muted.underline},set pending(e){this._pending=e},get pending(){return this._pending||this.primary},set submitted(e){this._submitted=e},get submitted(){return this._submitted||this.success},set cancelled(e){this._cancelled=e},get cancelled(){return this._cancelled||this.danger},set typing(e){this._typing=e},get typing(){return this._typing||this.dim},set placeholder(e){this._placeholder=e},get placeholder(){return this._placeholder||this.primary.dim},set highlight(e){this._highlight=e},get highlight(){return this._highlight||this.inverse},merge:(e={})=>{e.styles&&"boolean"==typeof e.styles.enabled&&(n.enabled=e.styles.enabled),e.styles&&"boolean"==typeof e.styles.visible&&(n.visible=e.styles.visible);let t=A.merge({},o,e.styles);delete t.merge;for(let e of Object.keys(n))t.hasOwnProperty(e)||Reflect.defineProperty(t,e,{get:()=>n[e]});for(let e of Object.keys(n.styles))t.hasOwnProperty(e)||Reflect.defineProperty(t,e,{get:()=>n[e]});return t}};e.exports=o},50511:(e,t,r)=>{"use strict";const A="win32"===process.platform,n=r(97991),o=r(10278),i={...n.symbols,upDownDoubleArrow:"⇕",upDownDoubleArrow2:"⬍",upDownArrow:"↕",asterisk:"*",asterism:"⁂",bulletWhite:"◦",electricArrow:"⌁",ellipsisLarge:"⋯",ellipsisSmall:"…",fullBlock:"█",identicalTo:"≡",indicator:n.symbols.check,leftAngle:"‹",mark:"※",minus:"−",multiplication:"×",obelus:"÷",percent:"%",pilcrow:"¶",pilcrow2:"❡",pencilUpRight:"✐",pencilDownRight:"✎",pencilRight:"✏",plus:"+",plusMinus:"±",pointRight:"☞",rightAngle:"›",section:"§",hexagon:{off:"⬡",on:"⬢",disabled:"⬢"},ballot:{on:"☑",off:"☐",disabled:"☒"},stars:{on:"★",off:"☆",disabled:"☆"},folder:{on:"▼",off:"▶",disabled:"▶"},prefix:{pending:n.symbols.question,submitted:n.symbols.check,cancelled:n.symbols.cross},separator:{pending:n.symbols.pointerSmall,submitted:n.symbols.middot,cancelled:n.symbols.middot},radio:{off:A?"( )":"◯",on:A?"(*)":"◉",disabled:A?"(|)":"Ⓘ"},numbers:["⓪","①","②","③","④","⑤","⑥","⑦","⑧","⑨","⑩","⑪","⑫","⑬","⑭","⑮","⑯","⑰","⑱","⑲","⑳","㉑","㉒","㉓","㉔","㉕","㉖","㉗","㉘","㉙","㉚","㉛","㉜","㉝","㉞","㉟","㊱","㊲","㊳","㊴","㊵","㊶","㊷","㊸","㊹","㊺","㊻","㊼","㊽","㊾","㊿"]};i.merge=e=>{let t=o.merge({},n.symbols,i,e.symbols);return delete t.merge,t},e.exports=i},26205:(e,t,r)=>{"use strict";const A=r(64402),n=r(50511),o=r(10278);e.exports=e=>{e.options=o.merge({},e.options.theme,e.options),e.symbols=n.merge(e.options),e.styles=A.merge(e.options)}},47159:e=>{"use strict";function t(e,t,r={}){let A=e.timers[t]={name:t,start:Date.now(),ms:0,tick:0},n=r.interval||120;A.frames=r.frames||[],A.loading=!0;let o=setInterval(()=>{A.ms=Date.now()-A.start,A.tick++,e.render()},n);return A.stop=()=>{A.loading=!1,clearInterval(o)},Reflect.defineProperty(A,"interval",{value:o}),e.once("close",()=>A.stop()),A.stop}e.exports=e=>{e.timers=e.timers||{};let r=e.options.timers;if(r)for(let A of Object.keys(r)){let n=r[A];"number"==typeof n&&(n={interval:n}),t(e,A,n)}}},14723:(e,t,r)=>{"use strict";const A=r(97991),n=r(58386),o=r(27011),i=r(10278),{reorder:s,scrollUp:a,scrollDown:c,isObject:g,swap:l}=i;function u(e,t){if(t instanceof Promise)return t;if("function"==typeof t){if(i.isAsyncFn(t))return t;t=t.call(e,e)}for(let r of t){if(Array.isArray(r.choices)){let t=r.choices.filter(t=>!e.isDisabled(t));r.enabled=t.every(e=>!0===e.enabled)}!0===e.isDisabled(r)&&delete r.enabled}return t}e.exports=class extends n{constructor(e){super(e),this.cursorHide(),this.maxSelected=e.maxSelected||1/0,this.multiple=e.multiple||!1,this.initial=e.initial||0,this.delay=e.delay||0,this.longest=0,this.num=""}async initialize(){"function"==typeof this.options.initial&&(this.initial=await this.options.initial.call(this)),await this.reset(!0),await super.initialize()}async reset(){let{choices:e,initial:t,autofocus:r,suggest:A}=this.options;if(this.state._choices=[],this.state.choices=[],this.choices=await Promise.all(await this.toChoices(e)),this.choices.forEach(e=>e.enabled=!1),"function"!=typeof A&&0===this.selectable.length)throw new Error("At least one choice must be selectable");g(t)&&(t=Object.keys(t)),Array.isArray(t)?(null!=r&&(this.index=this.findIndex(r)),t.forEach(e=>this.enable(this.find(e))),await this.render()):(null!=r&&(t=r),"string"==typeof t&&(t=this.findIndex(t)),"number"==typeof t&&t>-1&&(this.index=Math.max(0,Math.min(t,this.choices.length)),this.enable(this.find(this.index)))),this.isDisabled(this.focused)&&await this.down()}async toChoices(e,t){this.state.loadingChoices=!0;let r=[],A=0,n=async(e,t)=>{"function"==typeof e&&(e=await e.call(this)),e instanceof Promise&&(e=await e);for(let o=0;o(this.state.loadingChoices=!1,e))}async toChoice(e,t,r){if("function"==typeof e&&(e=await e.call(this,this)),e instanceof Promise&&(e=await e),"string"==typeof e&&(e={name:e}),e.normalized)return e;e.normalized=!0;let n=e.value,s=o(e.role,this.options);if("string"!=typeof(e=s(this,e)).disabled||e.hint||(e.hint=e.disabled,e.disabled=!0),!0===e.disabled&&null==e.hint&&(e.hint="(disabled)"),null!=e.index)return e;e.name=e.name||e.key||e.title||e.value||e.message,e.message=e.message||e.name||"",e.value=[e.value,e.name].find(this.isValue.bind(this)),e.input="",e.index=t,e.cursor=0,i.define(e,"parent",r),e.level=r?r.level+1:1,null==e.indent&&(e.indent=r?r.indent+" ":e.indent||""),e.path=r?r.path+"."+e.name:e.name,e.enabled=!(!this.multiple||this.isDisabled(e)||!e.enabled&&!this.isSelected(e)),this.isDisabled(e)||(this.longest=Math.max(this.longest,A.unstyle(e.message).length));let a={...e};return e.reset=(t=a.input,r=a.value)=>{for(let t of Object.keys(a))e[t]=a[t];e.input=t,e.value=r},null==n&&"function"==typeof e.initial&&(e.input=await e.initial.call(this,this.state,e,t)),e}async onChoice(e,t){this.emit("choice",e,t,this),"function"==typeof e.onChoice&&await e.onChoice.call(this,this.state,e,t)}async addChoice(e,t,r){let A=await this.toChoice(e,t,r);return this.choices.push(A),this.index=this.choices.length-1,this.limit=this.choices.length,A}async newItem(e,t,r){let A={name:"New choice name?",editable:!0,newChoice:!0,...e},n=await this.addChoice(A,t,r);return n.updateChoice=()=>{delete n.newChoice,n.name=n.message=n.input,n.input="",n.cursor=0},this.render()}indent(e){return null==e.indent?e.level>1?" ".repeat(e.level-1):"":e.indent}dispatch(e,t){if(this.multiple&&this[t.name])return this[t.name]();this.alert()}focus(e,t){return"boolean"!=typeof t&&(t=e.enabled),t&&!e.enabled&&this.selected.length>=this.maxSelected?this.alert():(this.index=e.index,e.enabled=t&&!this.isDisabled(e),e)}space(){return this.multiple?(this.toggle(this.focused),this.render()):this.alert()}a(){if(this.maxSelectede.enabled);return this.choices.forEach(t=>t.enabled=!e),this.render()}i(){return this.choices.length-this.selected.length>this.maxSelected?this.alert():(this.choices.forEach(e=>e.enabled=!e.enabled),this.render())}g(e=this.focused){return this.choices.some(e=>!!e.parent)?(this.toggle(e.parent&&!e.choices?e.parent:e),this.render()):this.a()}toggle(e,t){if(!e.enabled&&this.selected.length>=this.maxSelected)return this.alert();"boolean"!=typeof t&&(t=!e.enabled),e.enabled=t,e.choices&&e.choices.forEach(e=>this.toggle(e,t));let r=e.parent;for(;r;){let e=r.choices.filter(e=>this.isDisabled(e));r.enabled=e.every(e=>!0===e.enabled),r=r.parent}return u(this,this.choices),this.emit("toggle",e,this),e}enable(e){return this.selected.length>=this.maxSelected?this.alert():(e.enabled=!this.isDisabled(e),e.choices&&e.choices.forEach(this.enable.bind(this)),e)}disable(e){return e.enabled=!1,e.choices&&e.choices.forEach(this.disable.bind(this)),e}number(e){this.num+=e;let t=e=>{let t=Number(e);if(t>this.choices.length-1)return this.alert();let r=this.focused,A=this.choices.find(e=>t===e.index);if(!A.enabled&&this.selected.length>=this.maxSelected)return this.alert();if(-1===this.visible.indexOf(A)){let e=s(this.choices),t=e.indexOf(A);if(r.index>t){let r=e.slice(t,t+this.limit),A=e.filter(e=>!r.includes(e));this.choices=r.concat(A)}else{let r=t-this.limit+1;this.choices=e.slice(r).concat(e.slice(0,r))}}return this.index=this.choices.indexOf(A),this.toggle(this.focused),this.render()};return clearTimeout(this.numberTimeout),new Promise(e=>{let r=this.choices.length,A=this.num,n=(r=!1,n)=>{clearTimeout(this.numberTimeout),r&&(n=t(A)),this.num="",e(n)};return"0"===A||1===A.length&&Number(A+"0")>r?n(!0):Number(A)>r?n(!1,this.alert()):void(this.numberTimeout=setTimeout(()=>n(!0),this.delay))})}home(){return this.choices=s(this.choices),this.index=0,this.render()}end(){let e=this.choices.length-this.limit,t=s(this.choices);return this.choices=t.slice(e).concat(t.slice(0,e)),this.index=this.limit-1,this.render()}first(){return this.index=0,this.render()}last(){return this.index=this.visible.length-1,this.render()}prev(){return this.visible.length<=1?this.alert():this.up()}next(){return this.visible.length<=1?this.alert():this.down()}right(){return this.cursor>=this.input.length?this.alert():(this.cursor++,this.render())}left(){return this.cursor<=0?this.alert():(this.cursor--,this.render())}up(){let e=this.choices.length,t=this.visible.length,r=this.index;return!1===this.options.scroll&&0===r?this.alert():e>t&&0===r?this.scrollUp():(this.index=(r-1%e+e)%e,this.isDisabled()?this.up():this.render())}down(){let e=this.choices.length,t=this.visible.length,r=this.index;return!1===this.options.scroll&&r===t-1?this.alert():e>t&&r===t-1?this.scrollDown():(this.index=(r+1)%e,this.isDisabled()?this.down():this.render())}scrollUp(e=0){return this.choices=a(this.choices),this.index=e,this.isDisabled()?this.up():this.render()}scrollDown(e=this.visible.length-1){return this.choices=c(this.choices),this.index=e,this.isDisabled()?this.down():this.render()}async shiftUp(){return!0===this.options.sort?(this.sorting=!0,this.swap(this.index-1),await this.up(),void(this.sorting=!1)):this.scrollUp(this.index)}async shiftDown(){return!0===this.options.sort?(this.sorting=!0,this.swap(this.index+1),await this.down(),void(this.sorting=!1)):this.scrollDown(this.index)}pageUp(){return this.visible.length<=1?this.alert():(this.limit=Math.max(this.limit-1,0),this.index=Math.min(this.limit-1,this.index),this._limit=this.limit,this.isDisabled()?this.up():this.render())}pageDown(){return this.visible.length>=this.choices.length?this.alert():(this.index=Math.max(0,this.index),this.limit=Math.min(this.limit+1,this.choices.length),this._limit=this.limit,this.isDisabled()?this.down():this.render())}swap(e){l(this.choices,this.index,e)}isDisabled(e=this.focused){return!(!e||!["disabled","collapsed","hidden","completing","readonly"].some(t=>!0===e[t]))||e&&"heading"===e.role}isEnabled(e=this.focused){if(Array.isArray(e))return e.every(e=>this.isEnabled(e));if(e.choices){let t=e.choices.filter(e=>!this.isDisabled(e));return e.enabled&&t.every(e=>this.isEnabled(e))}return e.enabled&&!this.isDisabled(e)}isChoice(e,t){return e.name===t||e.index===Number(t)}isSelected(e){return Array.isArray(this.initial)?this.initial.some(t=>this.isChoice(e,t)):this.isChoice(e,this.initial)}map(e=[],t="value"){return[].concat(e||[]).reduce((e,r)=>(e[r]=this.find(r,t),e),{})}filter(e,t){let r="function"==typeof e?e:(t,r)=>[t.name,r].includes(e),A=(this.options.multiple?this.state._choices:this.choices).filter(r);return t?A.map(e=>e[t]):A}find(e,t){if(g(e))return t?e[t]:e;let r="function"==typeof e?e:(t,r)=>[t.name,r].includes(e),A=this.choices.find(r);return A?t?A[t]:A:void 0}findIndex(e){return this.choices.indexOf(this.find(e))}async submit(){let e=this.focused;if(!e)return this.alert();if(e.newChoice)return e.input?(e.updateChoice(),this.render()):this.alert();if(this.choices.some(e=>e.newChoice))return this.alert();let{reorder:t,sort:r}=this.options,A=!0===this.multiple,n=this.selected;return void 0===n?this.alert():(Array.isArray(n)&&!1!==t&&!0!==r&&(n=i.reorder(n)),this.value=A?n.map(e=>e.name):n.name,super.submit())}set choices(e=[]){this.state._choices=this.state._choices||[],this.state.choices=e;for(let t of e)this.state._choices.some(e=>e.name===t.name)||this.state._choices.push(t);if(!this._initial&&this.options.initial){this._initial=!0;let e=this.initial;if("string"==typeof e||"number"==typeof e){let t=this.find(e);t&&(this.initial=t.index,this.focus(t,!0))}}}get choices(){return u(this,this.state.choices||[])}set visible(e){this.state.visible=e}get visible(){return(this.state.visible||this.choices).slice(0,this.limit)}set limit(e){this.state.limit=e}get limit(){let{state:e,options:t,choices:r}=this,A=e.limit||this._limit||t.limit||r.length;return Math.min(A,this.height)}set value(e){super.value=e}get value(){return"string"!=typeof super.value&&super.value===this.initial?this.input:super.value}set index(e){this.state.index=e}get index(){return Math.max(0,this.state?this.state.index:0)}get enabled(){return this.filter(this.isEnabled.bind(this))}get focused(){let e=this.choices[this.index];return e&&this.state.submitted&&!0!==this.multiple&&(e.enabled=!0),e}get selectable(){return this.choices.filter(e=>!this.isDisabled(e))}get selected(){return this.multiple?this.enabled:this.focused}}},46614:(e,t,r)=>{"use strict";const A=r(71447),n=()=>{throw new Error("expected prompt to have a custom authenticate method")},o=(e=n)=>class extends A{constructor(e){super(e)}async submit(){this.value=await e.call(this,this.values,this.state),super.base.submit.call(this)}static create(e){return o(e)}};e.exports=o()},82710:(e,t,r)=>{"use strict";const A=r(58386),{isPrimitive:n,hasColor:o}=r(10278);e.exports=class extends A{constructor(e){super(e),this.cursorHide()}async initialize(){let e=await this.resolve(this.initial,this.state);this.input=await this.cast(e),await super.initialize()}dispatch(e){return this.isValue(e)?(this.input=e,this.submit()):this.alert()}format(e){let{styles:t,state:r}=this;return r.submitted?t.success(e):t.primary(e)}cast(e){return this.isTrue(e)}isTrue(e){return/^[ty1]/i.test(e)}isFalse(e){return/^[fn0]/i.test(e)}isValue(e){return n(e)&&(this.isTrue(e)||this.isFalse(e))}async hint(){if("pending"===this.state.status){let e=await this.element("hint");return o(e)?e:this.styles.muted(e)}}async render(){let{input:e,size:t}=this.state,r=await this.prefix(),A=await this.separator(),n=[r,await this.message(),this.styles.muted(this.default),A].filter(Boolean).join(" ");this.state.prompt=n;let o=await this.header(),i=this.value=this.cast(e),s=await this.format(i),a=await this.error()||await this.hint(),c=await this.footer();a&&!n.includes(a)&&(s+=" "+a),n+=" "+s,this.clear(t),this.write([o,n,c].filter(Boolean).join("\n")),this.restore()}set value(e){super.value=e}get value(){return this.cast(super.value)}}},13235:(e,t,r)=>{e.exports={ArrayPrompt:r(14723),AuthPrompt:r(46614),BooleanPrompt:r(82710),NumberPrompt:r(64987),StringPrompt:r(45853)}},64987:(e,t,r)=>{"use strict";const A=r(45853);e.exports=class extends A{constructor(e={}){super({style:"number",...e}),this.min=this.isValue(e.min)?this.toNumber(e.min):-1/0,this.max=this.isValue(e.max)?this.toNumber(e.max):1/0,this.delay=null!=e.delay?e.delay:1e3,this.float=!1!==e.float,this.round=!0===e.round||!1===e.float,this.major=e.major||10,this.minor=e.minor||1,this.initial=null!=e.initial?e.initial:"",this.input=String(this.initial),this.cursor=this.input.length,this.cursorShow()}append(e){return!/[-+.]/.test(e)||"."===e&&this.input.includes(".")?this.alert("invalid number"):super.append(e)}number(e){return super.append(e)}next(){return this.input&&this.input!==this.initial?this.alert():this.isValue(this.initial)?(this.input=this.initial,this.cursor=String(this.initial).length,this.render()):this.alert()}up(e){let t=e||this.minor,r=this.toNumber(this.input);return r>this.max+t?this.alert():(this.input=""+(r+t),this.render())}down(e){let t=e||this.minor,r=this.toNumber(this.input);return rthis.isValue(e));return this.value=this.toNumber(e||0),super.submit()}}},45853:(e,t,r)=>{"use strict";const A=r(58386),n=r(96496),{isPrimitive:o}=r(10278);e.exports=class extends A{constructor(e){super(e),this.initial=o(this.initial)?String(this.initial):"",this.initial&&this.cursorHide(),this.state.prevCursor=0,this.state.clipboard=[]}async keypress(e,t={}){let r=this.state.prevKeypress;return this.state.prevKeypress=t,!0!==this.options.multiline||"return"!==t.name||r&&"return"===r.name?super.keypress(e,t):this.append("\n",t)}moveCursor(e){this.cursor+=e}reset(){return this.input=this.value="",this.cursor=0,this.render()}dispatch(e,t){if(!e||t.ctrl||t.code)return this.alert();this.append(e)}append(e){let{cursor:t,input:r}=this.state;this.input=(""+r).slice(0,t)+e+(""+r).slice(t),this.moveCursor(String(e).length),this.render()}insert(e){this.append(e)}delete(){let{cursor:e,input:t}=this.state;if(e<=0)return this.alert();this.input=(""+t).slice(0,e-1)+(""+t).slice(e),this.moveCursor(-1),this.render()}deleteForward(){let{cursor:e,input:t}=this.state;if(void 0===t[e])return this.alert();this.input=(""+t).slice(0,e)+(""+t).slice(e+1),this.render()}cutForward(){let e=this.cursor;if(this.input.length<=e)return this.alert();this.state.clipboard.push(this.input.slice(e)),this.input=this.input.slice(0,e),this.render()}cutLeft(){let e=this.cursor;if(0===e)return this.alert();let t=this.input.slice(0,e),r=this.input.slice(e),A=t.split(" ");this.state.clipboard.push(A.pop()),this.input=A.join(" "),this.cursor=this.input.length,this.input+=r,this.render()}paste(){if(!this.state.clipboard.length)return this.alert();this.insert(this.state.clipboard.pop()),this.render()}toggleCursor(){this.state.prevCursor?(this.cursor=this.state.prevCursor,this.state.prevCursor=0):(this.state.prevCursor=this.cursor,this.cursor=0),this.render()}first(){this.cursor=0,this.render()}last(){this.cursor=this.input.length-1,this.render()}next(){let e=null!=this.initial?String(this.initial):"";if(!e||!e.startsWith(this.input))return this.alert();this.input=this.initial,this.cursor=this.initial.length,this.render()}prev(){if(!this.input)return this.alert();this.reset()}backward(){return this.left()}forward(){return this.right()}right(){return this.cursor>=this.input.length?this.alert():(this.moveCursor(1),this.render())}left(){return this.cursor<=0?this.alert():(this.moveCursor(-1),this.render())}isValue(e){return!!e}async format(e=this.value){let t=await this.resolve(this.initial,this.state);return this.state.submitted?this.styles.submitted(e||t):n(this,{input:e,initial:t,pos:this.cursor})}async render(){let e=this.state.size,t=await this.prefix(),r=await this.separator(),A=[t,await this.message(),r].filter(Boolean).join(" ");this.state.prompt=A;let n=await this.header(),o=await this.format(),i=await this.error()||await this.hint(),s=await this.footer();i&&!o.includes(i)&&(o+=" "+i),A+=" "+o,this.clear(e),this.write([n,A,s].filter(Boolean).join("\n")),this.restore()}}},10278:(e,t,r)=>{"use strict";const A=Object.prototype.toString,n=r(97991);let o=!1,i=[];const s={yellow:"blue",cyan:"red",green:"magenta",black:"white",blue:"yellow",red:"cyan",magenta:"green",white:"black"};t.longest=(e,t)=>e.reduce((e,r)=>Math.max(e,t?r[t].length:r.length),0),t.hasColor=e=>!!e&&n.hasColor(e);const a=t.isObject=e=>null!==e&&"object"==typeof e&&!Array.isArray(e);t.nativeType=e=>A.call(e).slice(8,-1).toLowerCase().replace(/\s/g,""),t.isAsyncFn=e=>"asyncfunction"===t.nativeType(e),t.isPrimitive=e=>null!=e&&"object"!=typeof e&&"function"!=typeof e,t.resolve=(e,t,...r)=>"function"==typeof t?t.call(e,...r):t,t.scrollDown=(e=[])=>[...e.slice(1),e[0]],t.scrollUp=(e=[])=>[e.pop(),...e],t.reorder=(e=[])=>{let t=e.slice();return t.sort((e,t)=>e.index>t.index?1:e.index{let A=e.length,n=r===A?0:r<0?A-1:r,o=e[t];e[t]=e[n],e[n]=o},t.width=(e,t=80)=>{let r=e&&e.columns?e.columns:t;return e&&"function"==typeof e.getWindowSize&&(r=e.getWindowSize()[0]),"win32"===process.platform?r-1:r},t.height=(e,t=20)=>{let r=e&&e.rows?e.rows:t;return e&&"function"==typeof e.getWindowSize&&(r=e.getWindowSize()[1]),r},t.wordWrap=(e,t={})=>{if(!e)return e;"number"==typeof t&&(t={width:t});let{indent:r="",newline:A="\n"+r,width:n=80}=t,o=(A+r).match(/[^\S\n]/g)||[];n-=o.length;let i=`.{1,${n}}([\\s\\u200B]+|$)|[^\\s\\u200B]+?([\\s\\u200B]+|$)`,s=e.trim(),a=new RegExp(i,"g"),c=s.match(a)||[];return c=c.map(e=>e.replace(/\n$/,"")),t.padEnd&&(c=c.map(e=>e.padEnd(n," "))),t.padStart&&(c=c.map(e=>e.padStart(n," "))),r+c.join(A)},t.unmute=e=>{let t=e.stack.find(e=>n.keys.color.includes(e));return t?n[t]:e.stack.find(e=>"bg"===e.slice(2))?n[t.slice(2)]:e=>e},t.pascal=e=>e?e[0].toUpperCase()+e.slice(1):"",t.inverse=e=>{if(!e||!e.stack)return e;let r=e.stack.find(e=>n.keys.color.includes(e));if(r){let A=n["bg"+t.pascal(r)];return A?A.black:e}let A=e.stack.find(e=>"bg"===e.slice(0,2));return A?n[A.slice(2).toLowerCase()]||e:n.none},t.complement=e=>{if(!e||!e.stack)return e;let r=e.stack.find(e=>n.keys.color.includes(e)),A=e.stack.find(e=>"bg"===e.slice(0,2));if(r&&!A)return n[s[r]||r];if(A){let r=A.slice(2).toLowerCase(),o=s[r];return o&&n["bg"+t.pascal(o)]||e}return n.none},t.meridiem=e=>{let t=e.getHours(),r=e.getMinutes(),A=t>=12?"pm":"am";return t%=12,(0===t?12:t)+":"+(r<10?"0"+r:r)+" "+A},t.set=(e={},r="",A)=>r.split(".").reduce((e,r,n,o)=>{let i=o.length-1>n?e[r]||{}:A;return!t.isObject(i)&&n{let A=null==e[t]?t.split(".").reduce((e,t)=>e&&e[t],e):e[t];return null==A?r:A},t.mixin=(e,r)=>{if(!a(e))return r;if(!a(r))return e;for(let A of Object.keys(r)){let n=Object.getOwnPropertyDescriptor(r,A);if(n.hasOwnProperty("value"))if(e.hasOwnProperty(A)&&a(n.value)){let o=Object.getOwnPropertyDescriptor(e,A);a(o.value)?e[A]=t.merge({},e[A],r[A]):Reflect.defineProperty(e,A,n)}else Reflect.defineProperty(e,A,n);else Reflect.defineProperty(e,A,n)}return e},t.merge=(...e)=>{let r={};for(let A of e)t.mixin(r,A);return r},t.mixinEmitter=(e,r)=>{let A=r.constructor.prototype;for(let n of Object.keys(A)){let o=A[n];"function"==typeof o?t.define(e,n,o.bind(r)):t.define(e,n,o)}},t.onExit=e=>{const t=(e,t)=>{o||(o=!0,i.forEach(e=>e()),!0===e&&process.exit(128+t))};0===i.length&&(process.once("SIGTERM",t.bind(null,!0,15)),process.once("SIGINT",t.bind(null,!0,2)),process.once("exit",t)),i.push(e)},t.define=(e,t,r)=>{Reflect.defineProperty(e,t,{value:r})},t.defineExport=(e,t,r)=>{let A;Reflect.defineProperty(e,t,{enumerable:!0,configurable:!0,set(e){A=e},get:()=>A?A():r()})}},19347:(e,t,r)=>{"use strict";const A=r(80598),n=r(58182),o=r(67652),i=r(81340),s=r(43754),a=r(16777);async function c(e,t){l(e);const r=g(e,n.default,t),A=await Promise.all(r);return a.array.flatten(A)}function g(e,t,r){const n=[].concat(e),o=new s.default(r),i=A.generate(n,o),a=new t(o);return i.map(a.read,a)}function l(e){if(![].concat(e).every(e=>a.string.isString(e)&&!a.string.isEmpty(e)))throw new TypeError("Patterns must be a string (non empty) or an array of strings")}!function(e){e.sync=function(e,t){l(e);const r=g(e,i.default,t);return a.array.flatten(r)},e.stream=function(e,t){l(e);const r=g(e,o.default,t);return a.stream.merge(r)},e.generateTasks=function(e,t){l(e);const r=[].concat(e),n=new s.default(t);return A.generate(r,n)},e.isDynamicPattern=function(e,t){l(e);const r=new s.default(t);return a.pattern.isDynamicPattern(e,r)},e.escapePath=function(e){return l(e),a.path.escape(e)}}(c||(c={})),e.exports=c},80598:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(16777);function n(e,t,r){const A=s(e);if("."in A){return[c(".",e,t,r)]}return a(A,t,r)}function o(e){return A.pattern.getPositivePatterns(e)}function i(e,t){return A.pattern.getNegativePatterns(e).concat(t).map(A.pattern.convertToPositivePattern)}function s(e){return e.reduce((e,t)=>{const r=A.pattern.getBaseDirectory(t);return r in e?e[r].push(t):e[r]=[t],e},{})}function a(e,t,r){return Object.keys(e).map(A=>c(A,e[A],t,r))}function c(e,t,r,n){return{dynamic:n,positive:t,negative:r,base:e,patterns:[].concat(t,r.map(A.pattern.convertToNegativePattern))}}t.generate=function(e,t){const r=o(e),s=i(e,t.ignore),a=r.filter(e=>A.pattern.isStaticPattern(e,t)),c=r.filter(e=>A.pattern.isDynamicPattern(e,t)),g=n(a,s,!1),l=n(c,s,!0);return g.concat(l)},t.convertPatternsToTasks=n,t.getPositivePatterns=o,t.getNegativePatternsAsPositive=i,t.groupPatternsByBaseDirectory=s,t.convertPatternGroupsToTasks=a,t.convertPatternGroupToTask=c},58182:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(82774),n=r(40545);class o extends n.default{constructor(){super(...arguments),this._reader=new A.default(this._settings)}read(e){const t=this._getRootDirectory(e),r=this._getReaderOptions(e),A=[];return new Promise((n,o)=>{const i=this.api(t,e,r);i.once("error",o),i.on("data",e=>A.push(r.transform(e))),i.once("end",()=>n(A))})}api(e,t,r){return t.dynamic?this._reader.dynamic(e,r):this._reader.static(t.patterns,r)}}t.default=o},65989:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(16777),n=r(42585);t.default=class{constructor(e,t){this._settings=e,this._micromatchOptions=t}getFilter(e,t,r){const A=this._getMatcher(t),n=this._getNegativePatternsRe(r);return t=>this._filter(e,t,A,n)}_getMatcher(e){return new n.default(e,this._settings,this._micromatchOptions)}_getNegativePatternsRe(e){const t=e.filter(A.pattern.isAffectDepthOfReadingPattern);return A.pattern.convertPatternsToRe(t,this._micromatchOptions)}_filter(e,t,r,n){const o=this._getEntryLevel(e,t.path);if(this._isSkippedByDeep(o))return!1;if(this._isSkippedSymbolicLink(t))return!1;const i=A.path.removeLeadingDotSegment(t.path);return!this._isSkippedByPositivePatterns(i,r)&&this._isSkippedByNegativePatterns(i,n)}_isSkippedByDeep(e){return e>=this._settings.deep}_isSkippedSymbolicLink(e){return!this._settings.followSymbolicLinks&&e.dirent.isSymbolicLink()}_getEntryLevel(e,t){const r=e.split("/").length;return t.split("/").length-(""===e?0:r)}_isSkippedByPositivePatterns(e,t){return!this._settings.baseNameMatch&&!t.match(e)}_isSkippedByNegativePatterns(e,t){return!A.pattern.matchAny(e,t)}}},37338:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(16777);t.default=class{constructor(e,t){this._settings=e,this._micromatchOptions=t,this.index=new Map}getFilter(e,t){const r=A.pattern.convertPatternsToRe(e,this._micromatchOptions),n=A.pattern.convertPatternsToRe(t,this._micromatchOptions);return e=>this._filter(e,r,n)}_filter(e,t,r){if(this._settings.unique){if(this._isDuplicateEntry(e))return!1;this._createIndexRecord(e)}if(this._onlyFileFilter(e)||this._onlyDirectoryFilter(e))return!1;if(this._isSkippedByAbsoluteNegativePatterns(e,r))return!1;const A=this._settings.baseNameMatch?e.name:e.path;return this._isMatchToPatterns(A,t)&&!this._isMatchToPatterns(e.path,r)}_isDuplicateEntry(e){return this.index.has(e.path)}_createIndexRecord(e){this.index.set(e.path,void 0)}_onlyFileFilter(e){return this._settings.onlyFiles&&!e.dirent.isFile()}_onlyDirectoryFilter(e){return this._settings.onlyDirectories&&!e.dirent.isDirectory()}_isSkippedByAbsoluteNegativePatterns(e,t){if(!this._settings.absolute)return!1;const r=A.path.makeAbsolute(this._settings.cwd,e.path);return this._isMatchToPatterns(r,t)}_isMatchToPatterns(e,t){const r=A.path.removeLeadingDotSegment(e);return A.pattern.matchAny(r,t)}}},54345:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(16777);t.default=class{constructor(e){this._settings=e}getFilter(){return e=>this._isNonFatalError(e)}_isNonFatalError(e){return A.errno.isEnoentCodeError(e)||this._settings.suppressErrors}}},34789:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(16777);t.default=class{constructor(e,t,r){this._patterns=e,this._settings=t,this._micromatchOptions=r,this._storage=[],this._fillStorage()}_fillStorage(){const e=A.pattern.expandPatternsWithBraceExpansion(this._patterns);for(const t of e){const e=this._getPatternSegments(t),r=this._splitSegmentsIntoSections(e);this._storage.push({complete:r.length<=1,pattern:t,segments:e,sections:r})}}_getPatternSegments(e){return A.pattern.getPatternParts(e,this._micromatchOptions).map(e=>A.pattern.isDynamicPattern(e,this._settings)?{dynamic:!0,pattern:e,patternRe:A.pattern.makeRe(e,this._micromatchOptions)}:{dynamic:!1,pattern:e})}_splitSegmentsIntoSections(e){return A.array.splitWhen(e,e=>e.dynamic&&A.pattern.hasGlobStar(e.pattern))}}},42585:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(34789);class n extends A.default{match(e){const t=e.split("/"),r=t.length,A=this._storage.filter(e=>!e.complete||e.segments.length>r);for(const e of A){const A=e.sections[0];if(!e.complete&&r>A.length)return!0;if(t.every((t,r)=>{const A=e.segments[r];return!(!A.dynamic||!A.patternRe.test(t))||!A.dynamic&&A.pattern===t}))return!0}return!1}}t.default=n},40545:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(85622),n=r(65989),o=r(37338),i=r(54345),s=r(77541);t.default=class{constructor(e){this._settings=e,this.errorFilter=new i.default(this._settings),this.entryFilter=new o.default(this._settings,this._getMicromatchOptions()),this.deepFilter=new n.default(this._settings,this._getMicromatchOptions()),this.entryTransformer=new s.default(this._settings)}_getRootDirectory(e){return A.resolve(this._settings.cwd,e.base)}_getReaderOptions(e){const t="."===e.base?"":e.base;return{basePath:t,pathSegmentSeparator:"/",concurrency:this._settings.concurrency,deepFilter:this.deepFilter.getFilter(t,e.positive,e.negative),entryFilter:this.entryFilter.getFilter(e.positive,e.negative),errorFilter:this.errorFilter.getFilter(),followSymbolicLinks:this._settings.followSymbolicLinks,fs:this._settings.fs,stats:this._settings.stats,throwErrorOnBrokenSymbolicLink:this._settings.throwErrorOnBrokenSymbolicLink,transform:this.entryTransformer.getTransformer()}}_getMicromatchOptions(){return{dot:this._settings.dot,matchBase:this._settings.baseNameMatch,nobrace:!this._settings.braceExpansion,nocase:!this._settings.caseSensitiveMatch,noext:!this._settings.extglob,noglobstar:!this._settings.globstar,posix:!0,strictSlashes:!1}}}},67652:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(92413),n=r(82774),o=r(40545);class i extends o.default{constructor(){super(...arguments),this._reader=new n.default(this._settings)}read(e){const t=this._getRootDirectory(e),r=this._getReaderOptions(e),n=this.api(t,e,r),o=new A.Readable({objectMode:!0,read:()=>{}});return n.once("error",e=>o.emit("error",e)).on("data",e=>o.emit("data",r.transform(e))).once("end",()=>o.emit("end")),o.once("close",()=>n.destroy()),o}api(e,t,r){return t.dynamic?this._reader.dynamic(e,r):this._reader.static(t.patterns,r)}}t.default=i},81340:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(29543),n=r(40545);class o extends n.default{constructor(){super(...arguments),this._reader=new A.default(this._settings)}read(e){const t=this._getRootDirectory(e),r=this._getReaderOptions(e);return this.api(t,e,r).map(r.transform)}api(e,t,r){return t.dynamic?this._reader.dynamic(e,r):this._reader.static(t.patterns,r)}}t.default=o},77541:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(16777);t.default=class{constructor(e){this._settings=e}getTransformer(){return e=>this._transform(e)}_transform(e){let t=e.path;return this._settings.absolute&&(t=A.path.makeAbsolute(this._settings.cwd,t),t=A.path.unixify(t)),this._settings.markDirectories&&e.dirent.isDirectory()&&(t+="/"),this._settings.objectMode?Object.assign(Object.assign({},e),{path:t}):t}}},99458:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(85622),n=r(53403),o=r(16777);t.default=class{constructor(e){this._settings=e,this._fsStatSettings=new n.Settings({followSymbolicLink:this._settings.followSymbolicLinks,fs:this._settings.fs,throwErrorOnBrokenSymbolicLink:this._settings.followSymbolicLinks})}_getFullEntryPath(e){return A.resolve(this._settings.cwd,e)}_makeEntry(e,t){const r={name:t,path:t,dirent:o.fs.createDirentFromStats(t,e)};return this._settings.stats&&(r.stats=e),r}_isFatalError(e){return!o.errno.isEnoentCodeError(e)&&!this._settings.suppressErrors}}},82774:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(92413),n=r(53403),o=r(72897),i=r(99458);class s extends i.default{constructor(){super(...arguments),this._walkStream=o.walkStream,this._stat=n.stat}dynamic(e,t){return this._walkStream(e,t)}static(e,t){const r=e.map(this._getFullEntryPath,this),n=new A.PassThrough({objectMode:!0});n._write=(A,o,i)=>this._getEntry(r[A],e[A],t).then(e=>{null!==e&&t.entryFilter(e)&&n.push(e),A===r.length-1&&n.end(),i()}).catch(i);for(let e=0;ethis._makeEntry(e,t)).catch(e=>{if(r.errorFilter(e))return null;throw e})}_getStat(e){return new Promise((t,r)=>{this._stat(e,this._fsStatSettings,(e,A)=>null===e?t(A):r(e))})}}t.default=s},29543:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(53403),n=r(72897),o=r(99458);class i extends o.default{constructor(){super(...arguments),this._walkSync=n.walkSync,this._statSync=A.statSync}dynamic(e,t){return this._walkSync(e,t)}static(e,t){const r=[];for(const A of e){const e=this._getFullEntryPath(A),n=this._getEntry(e,A,t);null!==n&&t.entryFilter(n)&&r.push(n)}return r}_getEntry(e,t,r){try{const r=this._getStat(e);return this._makeEntry(r,t)}catch(e){if(r.errorFilter(e))return null;throw e}}_getStat(e){return this._statSync(e,this._fsStatSettings)}}t.default=i},43754:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(35747),n=r(12087).cpus().length;t.DEFAULT_FILE_SYSTEM_ADAPTER={lstat:A.lstat,lstatSync:A.lstatSync,stat:A.stat,statSync:A.statSync,readdir:A.readdir,readdirSync:A.readdirSync};t.default=class{constructor(e={}){this._options=e,this.absolute=this._getValue(this._options.absolute,!1),this.baseNameMatch=this._getValue(this._options.baseNameMatch,!1),this.braceExpansion=this._getValue(this._options.braceExpansion,!0),this.caseSensitiveMatch=this._getValue(this._options.caseSensitiveMatch,!0),this.concurrency=this._getValue(this._options.concurrency,n),this.cwd=this._getValue(this._options.cwd,process.cwd()),this.deep=this._getValue(this._options.deep,1/0),this.dot=this._getValue(this._options.dot,!1),this.extglob=this._getValue(this._options.extglob,!0),this.followSymbolicLinks=this._getValue(this._options.followSymbolicLinks,!0),this.fs=this._getFileSystemMethods(this._options.fs),this.globstar=this._getValue(this._options.globstar,!0),this.ignore=this._getValue(this._options.ignore,[]),this.markDirectories=this._getValue(this._options.markDirectories,!1),this.objectMode=this._getValue(this._options.objectMode,!1),this.onlyDirectories=this._getValue(this._options.onlyDirectories,!1),this.onlyFiles=this._getValue(this._options.onlyFiles,!0),this.stats=this._getValue(this._options.stats,!1),this.suppressErrors=this._getValue(this._options.suppressErrors,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!1),this.unique=this._getValue(this._options.unique,!0),this.onlyDirectories&&(this.onlyFiles=!1),this.stats&&(this.objectMode=!0)}_getValue(e,t){return void 0===e?t:e}_getFileSystemMethods(e={}){return Object.assign(Object.assign({},t.DEFAULT_FILE_SYSTEM_ADAPTER),e)}}},60919:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.flatten=function(e){return e.reduce((e,t)=>[].concat(e,t),[])},t.splitWhen=function(e,t){const r=[[]];let A=0;for(const n of e)t(n)?(A++,r[A]=[]):r[A].push(n);return r}},35525:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isEnoentCodeError=function(e){return"ENOENT"===e.code}},62524:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});class r{constructor(e,t){this.name=e,this.isBlockDevice=t.isBlockDevice.bind(t),this.isCharacterDevice=t.isCharacterDevice.bind(t),this.isDirectory=t.isDirectory.bind(t),this.isFIFO=t.isFIFO.bind(t),this.isFile=t.isFile.bind(t),this.isSocket=t.isSocket.bind(t),this.isSymbolicLink=t.isSymbolicLink.bind(t)}}t.createDirentFromStats=function(e,t){return new r(e,t)}},16777:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(60919);t.array=A;const n=r(35525);t.errno=n;const o=r(62524);t.fs=o;const i=r(71462);t.path=i;const s=r(14659);t.pattern=s;const a=r(2042);t.stream=a;const c=r(10217);t.string=c},71462:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(85622),n=/(\\?)([()*?[\]{|}]|^!|[!+@](?=\())/g;t.unixify=function(e){return e.replace(/\\/g,"/")},t.makeAbsolute=function(e,t){return A.resolve(e,t)},t.escape=function(e){return e.replace(n,"\\$2")},t.removeLeadingDotSegment=function(e){if("."===e.charAt(0)){const t=e.charAt(1);if("/"===t||"\\"===t)return e.slice(2)}return e}},14659:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(85622),n=r(97098),o=r(2401),i=r(54722),s=/[*?]|^!/,a=/\[.*]/,c=/(?:^|[^!*+?@])\(.*\|.*\)/,g=/[!*+?@]\(.*\)/,l=/{.*(?:,|\.\.).*}/;function u(e,t={}){return!h(e,t)}function h(e,t={}){return!(!1!==t.caseSensitiveMatch&&!e.includes("\\"))||(!!(s.test(e)||a.test(e)||c.test(e))||(!(!1===t.extglob||!g.test(e))||!(!1===t.braceExpansion||!l.test(e))))}function p(e){return e.startsWith("!")&&"("!==e[1]}function d(e){return!p(e)}function C(e){return e.endsWith("/**")}function f(e){return o.braces(e,{expand:!0,nodupes:!0})}function I(e,t){return o.makeRe(e,t)}t.isStaticPattern=u,t.isDynamicPattern=h,t.convertToPositivePattern=function(e){return p(e)?e.slice(1):e},t.convertToNegativePattern=function(e){return"!"+e},t.isNegativePattern=p,t.isPositivePattern=d,t.getNegativePatterns=function(e){return e.filter(p)},t.getPositivePatterns=function(e){return e.filter(d)},t.getBaseDirectory=function(e){return n(e,{flipBackslashes:!1})},t.hasGlobStar=function(e){return e.includes("**")},t.endsWithSlashGlobStar=C,t.isAffectDepthOfReadingPattern=function(e){const t=A.basename(e);return C(e)||u(t)},t.expandPatternsWithBraceExpansion=function(e){return e.reduce((e,t)=>e.concat(f(t)),[])},t.expandBraceExpansion=f,t.getPatternParts=function(e,t){const r=i.scan(e,Object.assign(Object.assign({},t),{parts:!0}));return 0===r.parts.length?[e]:r.parts},t.makeRe=I,t.convertPatternsToRe=function(e,t){return e.map(e=>I(e,t))},t.matchAny=function(e,t){return t.some(t=>t.test(e))}},2042:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(55598);function n(e){e.forEach(e=>e.emit("close"))}t.merge=function(e){const t=A(e);return e.forEach(e=>{e.once("error",e=>t.emit("error",e))}),t.once("close",()=>n(e)),t.once("end",()=>n(e)),t}},10217:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isString=function(e){return"string"==typeof e},t.isEmpty=function(e){return""===e}},98360:(e,t,r)=>{"use strict";var A=r(2383);function n(){}function o(){this.value=null,this.callback=n,this.next=null,this.release=n,this.context=null;var e=this;this.worked=function(t,r){var A=e.callback;e.value=null,e.callback=n,A.call(e.context,t,r),e.release(e)}}e.exports=function(e,t,r){"function"==typeof e&&(r=t,t=e,e=null);var i=A(o),s=null,a=null,c=0,g={push:function(r,A){var o=i.get();o.context=e,o.release=l,o.value=r,o.callback=A||n,c===g.concurrency||g.paused?a?(a.next=o,a=o):(s=o,a=o,g.saturated()):(c++,t.call(e,o.value,o.worked))},drain:n,saturated:n,pause:function(){g.paused=!0},paused:!1,concurrency:r,running:function(){return c},resume:function(){if(!g.paused)return;g.paused=!1;for(var e=0;e{"use strict";class A{constructor(e,t,r){this.__specs=e||{},Object.keys(this.__specs).forEach(e=>{if("string"==typeof this.__specs[e]){const t=this.__specs[e],r=this.__specs[t];if(!r)throw new Error(`Alias refers to invalid key: ${t} -> ${e}`);{const A=r.aliases||[];A.push(e,t),r.aliases=[...new Set(A)],this.__specs[e]=r}}}),this.__opts=t||{},this.__providers=s(r.filter(e=>null!=e&&"object"==typeof e)),this.__isFiggyPudding=!0}get(e){return n(this,e,!0)}get[Symbol.toStringTag](){return"FiggyPudding"}forEach(e,t=this){for(let[r,A]of this.entries())e.call(t,A,r,this)}toJSON(){const e={};return this.forEach((t,r)=>{e[r]=t}),e}*entries(e){for(let e of Object.keys(this.__specs))yield[e,this.get(e)];const t=e||this.__opts.other;if(t){const e=new Set;for(let r of this.__providers){const A=r.entries?r.entries(t):a(r);for(let[r,n]of A)t(r)&&!e.has(r)&&(e.add(r),yield[r,n])}}}*[Symbol.iterator](){for(let[e,t]of this.entries())yield[e,t]}*keys(){for(let[e]of this.entries())yield e}*values(){for(let[,e]of this.entries())yield e}concat(...e){return new Proxy(new A(this.__specs,this.__opts,s(this.__providers).concat(e)),i)}}try{const e=r(31669);A.prototype[e.inspect.custom]=function(t,r){return this[Symbol.toStringTag]+" "+e.inspect(this.toJSON(),r)}}catch(e){}function n(e,t,r){let A=e.__specs[t];if(!r||A||e.__opts.other&&e.__opts.other(t)){let r;A||(A={});for(let n of e.__providers){if(r=o(t,n),void 0===r&&A.aliases&&A.aliases.length)for(let e of A.aliases)if(e!==t&&(r=o(e,n),void 0!==r))break;if(void 0!==r)break}return void 0===r&&void 0!==A.default?"function"==typeof A.default?A.default(e):A.default:r}!function(e){throw Object.assign(new Error("invalid config key requested: "+e),{code:"EBADKEY"})}(t)}function o(e,t){let r;return r=t.__isFiggyPudding?n(t,e,!1):"function"==typeof t.get?t.get(e):t[e],r}const i={has:(e,t)=>t in e.__specs&&void 0!==n(e,t,!1),ownKeys:e=>Object.keys(e.__specs),get:(e,t)=>"symbol"==typeof t||"__"===t.slice(0,2)||t in A.prototype?e[t]:e.get(t),set(e,t,r){if("symbol"==typeof t||"__"===t.slice(0,2))return e[t]=r,!0;throw new Error("figgyPudding options cannot be modified. Use .concat() instead.")},deleteProperty(){throw new Error("figgyPudding options cannot be deleted. Use .concat() and shadow them instead.")}};function s(e){const t=[];return e.forEach(e=>t.unshift(e)),t}function a(e){return Object.keys(e).map(t=>[t,e[t]])}e.exports=function(e,t){return function(...r){return new Proxy(new A(e,t,r),i)}}},52169:(e,t,r)=>{"use strict"; -/*! - * fill-range - * - * Copyright (c) 2014-present, Jon Schlinkert. - * Licensed under the MIT License. - */const A=r(31669),n=r(84615),o=e=>null!==e&&"object"==typeof e&&!Array.isArray(e),i=e=>"number"==typeof e||"string"==typeof e&&""!==e,s=e=>Number.isInteger(+e),a=e=>{let t=""+e,r=-1;if("-"===t[0]&&(t=t.slice(1)),"0"===t)return!1;for(;"0"===t[++r];);return r>0},c=(e,t,r)=>{if(t>0){let r="-"===e[0]?"-":"";r&&(e=e.slice(1)),e=r+e.padStart(r?t-1:t,"0")}return!1===r?String(e):e},g=(e,t)=>{let r="-"===e[0]?"-":"";for(r&&(e=e.slice(1),t--);e.length{if(r)return n(e,t,{wrap:!1,...A});let o=String.fromCharCode(e);return e===t?o:`[${o}-${String.fromCharCode(t)}]`},u=(e,t,r)=>{if(Array.isArray(e)){let t=!0===r.wrap,A=r.capture?"":"?:";return t?`(${A}${e.join("|")})`:e.join("|")}return n(e,t,r)},h=(...e)=>new RangeError("Invalid range arguments: "+A.inspect(...e)),p=(e,t,r)=>{if(!0===r.strictRanges)throw h([e,t]);return[]},d=(e,t,r=1,A={})=>{let n=Number(e),o=Number(t);if(!Number.isInteger(n)||!Number.isInteger(o)){if(!0===A.strictRanges)throw h([e,t]);return[]}0===n&&(n=0),0===o&&(o=0);let i=n>o,s=String(e),p=String(t),d=String(r);r=Math.max(Math.abs(r),1);let C=a(s)||a(p)||a(d),f=C?Math.max(s.length,p.length,d.length):0,I=!1===C&&!1===((e,t,r)=>"string"==typeof e||"string"==typeof t||!0===r.stringify)(e,t,A),E=A.transform||(e=>t=>!0===e?Number(t):String(t))(I);if(A.toRegex&&1===r)return l(g(e,f),g(t,f),!0,A);let B={negatives:[],positives:[]},y=[],m=0;for(;i?n>=o:n<=o;)!0===A.toRegex&&r>1?B[(w=n)<0?"negatives":"positives"].push(Math.abs(w)):y.push(c(E(n,m),f,I)),n=i?n-r:n+r,m++;var w;return!0===A.toRegex?r>1?((e,t)=>{e.negatives.sort((e,t)=>et?1:0),e.positives.sort((e,t)=>et?1:0);let r,A=t.capture?"":"?:",n="",o="";return e.positives.length&&(n=e.positives.join("|")),e.negatives.length&&(o=`-(${A}${e.negatives.join("|")})`),r=n&&o?`${n}|${o}`:n||o,t.wrap?`(${A}${r})`:r})(B,A):u(y,null,{wrap:!1,...A}):y},C=(e,t,r,A={})=>{if(null==t&&i(e))return[e];if(!i(e)||!i(t))return p(e,t,A);if("function"==typeof r)return C(e,t,1,{transform:r});if(o(r))return C(e,t,0,r);let n={...A};return!0===n.capture&&(n.wrap=!0),r=r||n.step||1,s(r)?s(e)&&s(t)?d(e,t,r,n):((e,t,r=1,A={})=>{if(!s(e)&&e.length>1||!s(t)&&t.length>1)return p(e,t,A);let n=A.transform||(e=>String.fromCharCode(e)),o=(""+e).charCodeAt(0),i=(""+t).charCodeAt(0),a=o>i,c=Math.min(o,i),g=Math.max(o,i);if(A.toRegex&&1===r)return l(c,g,!1,A);let h=[],d=0;for(;a?o>=i:o<=i;)h.push(n(o,d)),o=a?o-r:o+r,d++;return!0===A.toRegex?u(h,null,{wrap:!1,options:A}):h})(e,t,Math.max(Math.abs(r),1),n):null==r||o(r)?C(e,t,1,r):((e,t)=>{if(!0===t.strictRanges)throw new TypeError(`Expected step "${e}" to be a number`);return[]})(r,n)};e.exports=C},50683:e=>{e.exports=function(e){return[...e].reduce((e,[t,r])=>(e[t]=r,e),{})}},13302:(e,t,r)=>{e.exports=r(35747).constants||r(27619)},72137:(e,t,r)=>{"use strict";const{PassThrough:A}=r(92413);e.exports=e=>{e={...e};const{array:t}=e;let{encoding:r}=e;const n="buffer"===r;let o=!1;t?o=!(r||n):r=r||"utf8",n&&(r=null);const i=new A({objectMode:o});r&&i.setEncoding(r);let s=0;const a=[];return i.on("data",e=>{a.push(e),o?s=a.length:s+=e.length}),i.getBufferedValue=()=>t?a:n?Buffer.concat(a,s):a.join(""),i.getBufferedLength=()=>s,i}},58764:(e,t,r)=>{"use strict";const A=r(50372),n=r(72137);class o extends Error{constructor(){super("maxBuffer exceeded"),this.name="MaxBufferError"}}async function i(e,t){if(!e)return Promise.reject(new Error("Expected a stream"));t={maxBuffer:1/0,...t};const{maxBuffer:r}=t;let i;return await new Promise((s,a)=>{const c=e=>{e&&(e.bufferedData=i.getBufferedValue()),a(e)};i=A(e,n(t),e=>{e?c(e):s()}),i.on("data",()=>{i.getBufferedLength()>r&&c(new o)})}),i.getBufferedValue()}e.exports=i,e.exports.default=i,e.exports.buffer=(e,t)=>i(e,{...t,encoding:"buffer"}),e.exports.array=(e,t)=>i(e,{...t,array:!0}),e.exports.MaxBufferError=o},97098:(e,t,r)=>{"use strict";var A=r(18193),n=r(85622).posix.dirname,o="win32"===r(12087).platform(),i=/\\/g,s=/[\{\[].*[\/]*.*[\}\]]$/,a=/(^|[^\\])([\{\[]|\([^\)]+$)/,c=/\\([\*\?\|\[\]\(\)\{\}])/g;e.exports=function(e,t){Object.assign({flipBackslashes:!0},t).flipBackslashes&&o&&e.indexOf("/")<0&&(e=e.replace(i,"/")),s.test(e)&&(e+="/"),e+="a";do{e=n(e)}while(A(e)||a.test(e));return e.replace(c,"$1")}},90734:(e,t,r)=>{"use strict";const{promisify:A}=r(31669),n=r(35747),o=r(85622),i=r(19347),s=r(46458),a=r(17234),c=["**/node_modules/**","**/flow-typed/**","**/coverage/**","**/.git"],g=A(n.readFile),l=(e,t)=>{const r=a(o.relative(t.cwd,o.dirname(t.fileName)));return e.split(/\r?\n/).filter(Boolean).filter(e=>!e.startsWith("#")).map((e=>t=>t.startsWith("!")?"!"+o.posix.join(e,t.slice(1)):o.posix.join(e,t))(r))},u=e=>e.reduce((e,t)=>(e.add(l(t.content,{cwd:t.cwd,fileName:t.filePath})),e),s()),h=(e,t)=>r=>e.ignores(a(o.relative(t,((e,t)=>{if(e=a(e),o.isAbsolute(t)){if(t.startsWith(e))return t;throw new Error(`Path ${t} is not in cwd ${e}`)}return o.join(e,t)})(t,r)))),p=({ignore:e=[],cwd:t=a(process.cwd())}={})=>({ignore:e,cwd:t});e.exports=async e=>{e=p(e);const t=await i("**/.gitignore",{ignore:c.concat(e.ignore),cwd:e.cwd}),r=await Promise.all(t.map(t=>(async(e,t)=>{const r=o.join(t,e);return{cwd:t,filePath:r,content:await g(r,"utf8")}})(t,e.cwd))),A=u(r);return h(A,e.cwd)},e.exports.sync=e=>{e=p(e);const t=i.sync("**/.gitignore",{ignore:c.concat(e.ignore),cwd:e.cwd}).map(t=>((e,t)=>{const r=o.join(t,e);return{cwd:t,filePath:r,content:n.readFileSync(r,"utf8")}})(t,e.cwd)),r=u(t);return h(r,e.cwd)}},58592:(e,t,r)=>{"use strict";const A=r(35747),n=r(39920),o=r(55598),i=r(19347),s=r(66241),a=r(90734),{FilterStream:c,UniqueStream:g}=r(66160),l=()=>!1,u=e=>"!"===e[0],h=(e,t)=>{(e=>{if(!e.every(e=>"string"==typeof e))throw new TypeError("Patterns must be a string or an array of strings")})(e=n([].concat(e))),((e={})=>{if(!e.cwd)return;let t;try{t=A.statSync(e.cwd)}catch(e){return}if(!t.isDirectory())throw new Error("The `cwd` option must be a path to a directory")})(t);const r=[];t={ignore:[],expandDirectories:!0,...t};for(const[A,n]of e.entries()){if(u(n))continue;const o=e.slice(A).filter(u).map(e=>e.slice(1)),i={...t,ignore:t.ignore.concat(o)};r.push({pattern:n,options:i})}return r},p=(e,t)=>e.options.expandDirectories?((e,t)=>{let r={};return e.options.cwd&&(r.cwd=e.options.cwd),Array.isArray(e.options.expandDirectories)?r={...r,files:e.options.expandDirectories}:"object"==typeof e.options.expandDirectories&&(r={...r,...e.options.expandDirectories}),t(e.pattern,r)})(e,t):[e.pattern],d=e=>e&&e.gitignore?a.sync({cwd:e.cwd,ignore:e.ignore}):l,C=e=>t=>{const{options:r}=e;return r.ignore&&Array.isArray(r.ignore)&&r.expandDirectories&&(r.ignore=s.sync(r.ignore)),{pattern:t,options:r}};e.exports=async(e,t)=>{const r=h(e,t),[o,c]=await Promise.all([(async()=>t&&t.gitignore?a({cwd:t.cwd,ignore:t.ignore}):l)(),(async()=>{const e=await Promise.all(r.map(async e=>{const t=await p(e,s);return Promise.all(t.map(C(e)))}));return n(...e)})()]),g=await Promise.all(c.map(e=>i(e.pattern,e.options)));return n(...g).filter(e=>{return!o((t=e,t.stats instanceof A.Stats?t.path:t));var t})},e.exports.sync=(e,t)=>{const r=h(e,t).reduce((e,t)=>{const r=p(t,s.sync).map(C(t));return e.concat(r)},[]),A=d(t);return r.reduce((e,t)=>n(e,i.sync(t.pattern,t.options)),[]).filter(e=>!A(e))},e.exports.stream=(e,t)=>{const r=h(e,t).reduce((e,t)=>{const r=p(t,s.sync).map(C(t));return e.concat(r)},[]),A=d(t),n=new c(e=>!A(e)),a=new g;return o(r.map(e=>i.stream(e.pattern,e.options))).pipe(n).pipe(a)},e.exports.generateGlobTasks=h,e.exports.hasMagic=(e,t)=>[].concat(e).some(e=>i.isDynamicPattern(e,t)),e.exports.gitignore=a},66160:(e,t,r)=>{"use strict";const{Transform:A}=r(92413);class n extends A{constructor(){super({objectMode:!0})}}e.exports={FilterStream:class extends n{constructor(e){super(),this._filter=e}_transform(e,t,r){this._filter(e)&&this.push(e),r()}},UniqueStream:class extends n{constructor(){super(),this._pushed=new Set}_transform(e,t,r){this._pushed.has(e)||(this.push(e),this._pushed.add(e)),r()}}}},93576:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(14756);t.default=function(e,...t){const r=(async()=>{if(e instanceof A.RequestError)try{for(const r of t)if(r)for(const t of r)e=await t(e)}catch(t){e=t}throw e})(),n=()=>r;return r.json=n,r.text=n,r.buffer=n,r.on=n,r}},81588:function(e,t,r){"use strict";var A=this&&this.__createBinding||(Object.create?function(e,t,r,A){void 0===A&&(A=r),Object.defineProperty(e,A,{enumerable:!0,get:function(){return t[r]}})}:function(e,t,r,A){void 0===A&&(A=r),e[A]=t[r]}),n=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||A(t,e,r)};Object.defineProperty(t,"__esModule",{value:!0});const o=r(28614),i=r(7966),s=r(59351),a=r(14756),c=r(54718),g=r(9048),l=r(51743),u=r(57854),h=r(38206),p=["request","response","redirect","uploadProgress","downloadProgress"];t.default=function e(t){let r,A;const n=new o.EventEmitter,d=new s((o,s,C)=>{const f=I=>{const E=new g.default(void 0,t);E.retryCount=I,E._noPipe=!0,C(()=>E.destroy()),C.shouldReject=!1,C(()=>s(new a.CancelError(E))),r=E,E.once("response",async t=>{var r;if(t.retryCount=I,t.request.aborted)return;let n;try{n=await u.default(E),t.rawBody=n}catch(e){return}if(E._isAboutToError)return;const i=(null!==(r=t.headers["content-encoding"])&&void 0!==r?r:"").toLowerCase(),s=["gzip","deflate","br"].includes(i),{options:l}=E;if(s&&!l.decompress)t.body=n;else try{t.body=c.default(t,l.responseType,l.parseJson,l.encoding)}catch(e){if(t.body=n.toString(),h.isResponseOk(t))return void E._beforeError(e)}try{for(const[r,A]of l.hooks.afterResponse.entries())t=await A(t,async t=>{const A=g.default.normalizeArguments(void 0,{...t,retry:{calculateDelay:()=>0},throwHttpErrors:!1,resolveBodyOnly:!1},l);A.hooks.afterResponse=A.hooks.afterResponse.slice(0,r);for(const e of A.hooks.beforeRetry)await e(A);const n=e(A);return C(()=>{n.catch(()=>{}),n.cancel()}),n})}catch(e){return void E._beforeError(new a.RequestError(e.message,e,E))}h.isResponseOk(t)?(A=t,o(E.options.resolveBodyOnly?t.body:t)):E._beforeError(new a.HTTPError(t))});const B=e=>{if(d.isCanceled)return;const{options:t}=E;if(e instanceof a.HTTPError&&!t.throwHttpErrors){const{response:t}=e;o(E.options.resolveBodyOnly?t.body:t)}else s(e)};E.once("error",B),E.once("retry",(e,t)=>{var r;i.default.nodeStream(null===(r=t.request)||void 0===r?void 0:r.options.body)?B(t):f(e)}),l.default(E,n,p)};f(0)});d.on=(e,t)=>(n.on(e,t),d);const C=e=>{const t=(async()=>{await d;const{options:t}=A.request;return c.default(A,e,t.parseJson,t.encoding)})();return Object.defineProperties(t,Object.getOwnPropertyDescriptors(d)),t};return d.json=()=>{const{headers:e}=r.options;return r.writableFinished||void 0!==e.accept||(e.accept="application/json"),C("json")},d.buffer=()=>C("buffer"),d.text=()=>C("text"),d},n(r(14756),t)},41514:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(7966);t.default=(e,t)=>{if(A.default.null_(e.encoding))throw new TypeError("To get a Buffer, set `options.responseType` to `buffer` instead");A.assert.any([A.default.string,A.default.undefined],e.encoding),A.assert.any([A.default.boolean,A.default.undefined],e.resolveBodyOnly),A.assert.any([A.default.boolean,A.default.undefined],e.methodRewriting),A.assert.any([A.default.boolean,A.default.undefined],e.isStream),A.assert.any([A.default.string,A.default.undefined],e.responseType),void 0===e.responseType&&(e.responseType="text");const{retry:r}=e;if(e.retry=t?{...t.retry}:{calculateDelay:e=>e.computedValue,limit:0,methods:[],statusCodes:[],errorCodes:[],maxRetryAfter:void 0},A.default.object(r)?(e.retry={...e.retry,...r},e.retry.methods=[...new Set(e.retry.methods.map(e=>e.toUpperCase()))],e.retry.statusCodes=[...new Set(e.retry.statusCodes)],e.retry.errorCodes=[...new Set(e.retry.errorCodes)]):A.default.number(r)&&(e.retry.limit=r),A.default.undefined(e.retry.maxRetryAfter)&&(e.retry.maxRetryAfter=Math.min(...[e.timeout.request,e.timeout.connect].filter(A.default.number))),A.default.object(e.pagination)){t&&(e.pagination={...t.pagination,...e.pagination});const{pagination:r}=e;if(!A.default.function_(r.transform))throw new Error("`options.pagination.transform` must be implemented");if(!A.default.function_(r.shouldContinue))throw new Error("`options.pagination.shouldContinue` must be implemented");if(!A.default.function_(r.filter))throw new TypeError("`options.pagination.filter` must be implemented");if(!A.default.function_(r.paginate))throw new Error("`options.pagination.paginate` must be implemented")}return"json"===e.responseType&&void 0===e.headers.accept&&(e.headers.accept="application/json"),e}},54718:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(14756);t.default=(e,t,r,n)=>{const{rawBody:o}=e;try{if("text"===t)return o.toString(n);if("json"===t)return 0===o.length?"":r(o.toString());if("buffer"===t)return o;throw new A.ParseError({message:`Unknown body type '${t}'`,name:"Error"},e)}catch(t){throw new A.ParseError(t,e)}}},14756:function(e,t,r){"use strict";var A=this&&this.__createBinding||(Object.create?function(e,t,r,A){void 0===A&&(A=r),Object.defineProperty(e,A,{enumerable:!0,get:function(){return t[r]}})}:function(e,t,r,A){void 0===A&&(A=r),e[A]=t[r]}),n=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||A(t,e,r)};Object.defineProperty(t,"__esModule",{value:!0}),t.CancelError=t.ParseError=void 0;const o=r(9048);class i extends o.RequestError{constructor(e,t){const{options:r}=t.request;super(`${e.message} in "${r.url.toString()}"`,e,t.request),this.name="ParseError"}}t.ParseError=i;class s extends o.RequestError{constructor(e){super("Promise was canceled",{},e),this.name="CancelError"}get isCanceled(){return!0}}t.CancelError=s,n(r(9048),t)},53843:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.retryAfterStatusCodes=void 0,t.retryAfterStatusCodes=new Set([413,429,503]);t.default=({attemptCount:e,retryOptions:t,error:r,retryAfter:A})=>{if(e>t.limit)return 0;const n=t.methods.includes(r.options.method),o=t.errorCodes.includes(r.code),i=r.response&&t.statusCodes.includes(r.response.statusCode);if(!n||!o&&!i)return 0;if(r.response){if(A)return void 0===t.maxRetryAfter||A>t.maxRetryAfter?0:A;if(413===r.response.statusCode)return 0}return 2**(e-1)*1e3+100*Math.random()}},9048:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.UnsupportedProtocolError=t.ReadError=t.TimeoutError=t.UploadError=t.CacheError=t.HTTPError=t.MaxRedirectsError=t.RequestError=t.setNonEnumerableProperties=t.knownHookEvents=t.withoutBody=t.kIsNormalizedAlready=void 0;const A=r(31669),n=r(92413),o=r(35747),i=r(78835),s=r(98605),a=r(98605),c=r(57211),g=r(98298),l=r(30093),u=r(11200),h=r(93868),p=r(92353),d=r(55737),C=r(7966),f=r(78586),I=r(2920),E=r(51743),B=r(44947),y=r(50116),m=r(82524),w=r(85551),Q=r(57854),D=r(11338),b=r(38206),v=r(54595),S=r(41514),k=r(53843),N=new l.default,F=Symbol("request"),K=Symbol("response"),M=Symbol("responseSize"),R=Symbol("downloadedSize"),x=Symbol("bodySize"),L=Symbol("uploadedSize"),P=Symbol("serverResponsesPiped"),O=Symbol("unproxyEvents"),U=Symbol("isFromCache"),T=Symbol("cancelTimeouts"),j=Symbol("startedReading"),Y=Symbol("stopReading"),G=Symbol("triggerRead"),H=Symbol("body"),J=Symbol("jobs"),q=Symbol("originalResponse"),z=Symbol("retryTimeout");t.kIsNormalizedAlready=Symbol("isNormalizedAlready");const W=C.default.string(process.versions.brotli);t.withoutBody=new Set(["GET","HEAD"]),t.knownHookEvents=["init","beforeRequest","beforeRedirect","beforeError","beforeRetry","afterResponse"];const V=new w.default,X=new Set([300,301,302,303,304,307,308]),_=["context","body","json","form"];t.setNonEnumerableProperties=(e,t)=>{const r={};for(const t of e)if(t)for(const e of _)e in t&&(r[e]={writable:!0,configurable:!0,enumerable:!1,value:t[e]});Object.defineProperties(t,r)};class Z extends Error{constructor(e,t,r){var A;if(super(e),Error.captureStackTrace(this,this.constructor),this.name="RequestError",this.code=t.code,r instanceof se?(Object.defineProperty(this,"request",{enumerable:!1,value:r}),Object.defineProperty(this,"response",{enumerable:!1,value:r[K]}),Object.defineProperty(this,"options",{enumerable:!1,value:r.options})):Object.defineProperty(this,"options",{enumerable:!1,value:r}),this.timings=null===(A=this.request)||void 0===A?void 0:A.timings,!C.default.undefined(t.stack)){const e=this.stack.indexOf(this.message)+this.message.length,r=this.stack.slice(e).split("\n").reverse(),A=t.stack.slice(t.stack.indexOf(t.message)+t.message.length).split("\n").reverse();for(;0!==A.length&&A[0]===r[0];)r.shift();this.stack=`${this.stack.slice(0,e)}${r.reverse().join("\n")}${A.reverse().join("\n")}`}}}t.RequestError=Z;class $ extends Z{constructor(e){super(`Redirected ${e.options.maxRedirects} times. Aborting.`,{},e),this.name="MaxRedirectsError"}}t.MaxRedirectsError=$;class ee extends Z{constructor(e){super(`Response code ${e.statusCode} (${e.statusMessage})`,{},e.request),this.name="HTTPError"}}t.HTTPError=ee;class te extends Z{constructor(e,t){super(e.message,e,t),this.name="CacheError"}}t.CacheError=te;class re extends Z{constructor(e,t){super(e.message,e,t),this.name="UploadError"}}t.UploadError=re;class Ae extends Z{constructor(e,t,r){super(e.message,e,r),this.name="TimeoutError",this.event=e.event,this.timings=t}}t.TimeoutError=Ae;class ne extends Z{constructor(e,t){super(e.message,e,t),this.name="ReadError"}}t.ReadError=ne;class oe extends Z{constructor(e){super(`Unsupported protocol "${e.url.protocol}"`,{},e),this.name="UnsupportedProtocolError"}}t.UnsupportedProtocolError=oe;const ie=["socket","connect","continue","information","upgrade","timeout"];class se extends n.Duplex{constructor(e,r={},A){super({autoDestroy:!1,highWaterMark:0}),this[R]=0,this[L]=0,this.requestInitialized=!1,this[P]=new Set,this.redirects=[],this[Y]=!1,this[G]=!1,this[J]=[],this.retryCount=0,this._progressCallbacks=[];const n=()=>this._unlockWrite(),i=()=>this._lockWrite();this.on("pipe",e=>{e.prependListener("data",n),e.on("data",i),e.prependListener("end",n),e.on("end",i)}),this.on("unpipe",e=>{e.off("data",n),e.off("data",i),e.off("end",n),e.off("end",i)}),this.on("pipe",e=>{e instanceof a.IncomingMessage&&(this.options.headers={...e.headers,...this.options.headers})});const{json:s,body:c,form:g}=r;if((s||c||g)&&this._lockWrite(),t.kIsNormalizedAlready in r)this.options=r;else try{this.options=this.constructor.normalizeArguments(e,r,A)}catch(e){return C.default.nodeStream(r.body)&&r.body.destroy(),void this.destroy(e)}(async()=>{var e;try{this.options.body instanceof o.ReadStream&&await(async e=>new Promise((t,r)=>{const A=e=>{r(e)};e.pending||t(),e.once("error",A),e.once("ready",()=>{e.off("error",A),t()})}))(this.options.body);const{url:t}=this.options;if(!t)throw new TypeError("Missing `url` property");if(this.requestUrl=t.toString(),decodeURI(this.requestUrl),await this._finalizeBody(),await this._makeRequest(),this.destroyed)return void(null===(e=this[F])||void 0===e||e.destroy());for(const e of this[J])e();this[J].length=0,this.requestInitialized=!0}catch(e){if(e instanceof Z)return void this._beforeError(e);this.destroyed||this.destroy(e)}})()}static normalizeArguments(e,r,n){var o,s,a,c,g;const l=r;if(C.default.object(e)&&!C.default.urlInstance(e))r={...n,...e,...r};else{if(e&&r&&void 0!==r.url)throw new TypeError("The `url` option is mutually exclusive with the `input` argument");r={...n,...r},void 0!==e&&(r.url=e),C.default.urlInstance(r.url)&&(r.url=new i.URL(r.url.toString()))}if(!1===r.cache&&(r.cache=void 0),!1===r.dnsCache&&(r.dnsCache=void 0),C.assert.any([C.default.string,C.default.undefined],r.method),C.assert.any([C.default.object,C.default.undefined],r.headers),C.assert.any([C.default.string,C.default.urlInstance,C.default.undefined],r.prefixUrl),C.assert.any([C.default.object,C.default.undefined],r.cookieJar),C.assert.any([C.default.object,C.default.string,C.default.undefined],r.searchParams),C.assert.any([C.default.object,C.default.string,C.default.undefined],r.cache),C.assert.any([C.default.object,C.default.number,C.default.undefined],r.timeout),C.assert.any([C.default.object,C.default.undefined],r.context),C.assert.any([C.default.object,C.default.undefined],r.hooks),C.assert.any([C.default.boolean,C.default.undefined],r.decompress),C.assert.any([C.default.boolean,C.default.undefined],r.ignoreInvalidCookies),C.assert.any([C.default.boolean,C.default.undefined],r.followRedirect),C.assert.any([C.default.number,C.default.undefined],r.maxRedirects),C.assert.any([C.default.boolean,C.default.undefined],r.throwHttpErrors),C.assert.any([C.default.boolean,C.default.undefined],r.http2),C.assert.any([C.default.boolean,C.default.undefined],r.allowGetBody),C.assert.any([C.default.string,C.default.undefined],r.localAddress),C.assert.any([D.isDnsLookupIpVersion,C.default.undefined],r.dnsLookupIpVersion),C.assert.any([C.default.object,C.default.undefined],r.https),C.assert.any([C.default.boolean,C.default.undefined],r.rejectUnauthorized),r.https&&(C.assert.any([C.default.boolean,C.default.undefined],r.https.rejectUnauthorized),C.assert.any([C.default.function_,C.default.undefined],r.https.checkServerIdentity),C.assert.any([C.default.string,C.default.object,C.default.array,C.default.undefined],r.https.certificateAuthority),C.assert.any([C.default.string,C.default.object,C.default.array,C.default.undefined],r.https.key),C.assert.any([C.default.string,C.default.object,C.default.array,C.default.undefined],r.https.certificate),C.assert.any([C.default.string,C.default.undefined],r.https.passphrase),C.assert.any([C.default.string,C.default.buffer,C.default.array,C.default.undefined],r.https.pfx)),C.assert.any([C.default.object,C.default.undefined],r.cacheOptions),C.default.string(r.method)?r.method=r.method.toUpperCase():r.method="GET",r.headers===(null==n?void 0:n.headers)?r.headers={...r.headers}:r.headers=d({...null==n?void 0:n.headers,...r.headers}),"slashes"in r)throw new TypeError("The legacy `url.Url` has been deprecated. Use `URL` instead.");if("auth"in r)throw new TypeError("Parameter `auth` is deprecated. Use `username` / `password` instead.");if("searchParams"in r&&r.searchParams&&r.searchParams!==(null==n?void 0:n.searchParams)){let e;if(C.default.string(r.searchParams)||r.searchParams instanceof i.URLSearchParams)e=new i.URLSearchParams(r.searchParams);else{!function(e){for(const t in e){const r=e[t];if(!(C.default.string(r)||C.default.number(r)||C.default.boolean(r)||C.default.null_(r)||C.default.undefined(r)))throw new TypeError(`The \`searchParams\` value '${String(r)}' must be a string, number, boolean or null`)}}(r.searchParams),e=new i.URLSearchParams;for(const t in r.searchParams){const A=r.searchParams[t];null===A?e.append(t,""):void 0!==A&&e.append(t,A)}}null===(o=null==n?void 0:n.searchParams)||void 0===o||o.forEach((t,r)=>{e.has(r)||e.append(r,t)}),r.searchParams=e}if(r.username=null!==(s=r.username)&&void 0!==s?s:"",r.password=null!==(a=r.password)&&void 0!==a?a:"",C.default.undefined(r.prefixUrl)?r.prefixUrl=null!==(c=null==n?void 0:n.prefixUrl)&&void 0!==c?c:"":(r.prefixUrl=r.prefixUrl.toString(),""===r.prefixUrl||r.prefixUrl.endsWith("/")||(r.prefixUrl+="/")),C.default.string(r.url)){if(r.url.startsWith("/"))throw new Error("`input` must not start with a slash when using `prefixUrl`");r.url=m.default(r.prefixUrl+r.url,r)}else(C.default.undefined(r.url)&&""!==r.prefixUrl||r.protocol)&&(r.url=m.default(r.prefixUrl,r));if(r.url){"port"in r&&delete r.port;let{prefixUrl:e}=r;Object.defineProperty(r,"prefixUrl",{set:t=>{const A=r.url;if(!A.href.startsWith(t))throw new Error(`Cannot change \`prefixUrl\` from ${e} to ${t}: ${A.href}`);r.url=new i.URL(t+A.href.slice(e.length)),e=t},get:()=>e});let{protocol:t}=r.url;if("unix:"===t&&(t="http:",r.url=new i.URL(`http://unix${r.url.pathname}${r.url.search}`)),r.searchParams&&(r.url.search=r.searchParams.toString()),"http:"!==t&&"https:"!==t)throw new oe(r);""===r.username?r.username=r.url.username:r.url.username=r.username,""===r.password?r.password=r.url.password:r.url.password=r.password}const{cookieJar:h}=r;if(h){let{setCookie:e,getCookieString:t}=h;C.assert.function_(e),C.assert.function_(t),4===e.length&&0===t.length&&(e=A.promisify(e.bind(r.cookieJar)),t=A.promisify(t.bind(r.cookieJar)),r.cookieJar={setCookie:e,getCookieString:t})}const{cache:p}=r;if(p&&(V.has(p)||V.set(p,new u((e,t)=>{const r=e[F](e,t);return C.default.promise(r)&&(r.once=(e,t)=>{if("error"===e)r.catch(t);else{if("abort"!==e)throw new Error("Unknown HTTP2 promise event: "+e);(async()=>{try{(await r).once("abort",t)}catch(e){}})()}return r}),r},p))),r.cacheOptions={...r.cacheOptions},!0===r.dnsCache)r.dnsCache=N;else if(!C.default.undefined(r.dnsCache)&&!r.dnsCache.lookup)throw new TypeError("Parameter `dnsCache` must be a CacheableLookup instance or a boolean, got "+C.default(r.dnsCache));C.default.number(r.timeout)?r.timeout={request:r.timeout}:n&&r.timeout!==n.timeout?r.timeout={...n.timeout,...r.timeout}:r.timeout={...r.timeout},r.context||(r.context={});const f=r.hooks===(null==n?void 0:n.hooks);r.hooks={...r.hooks};for(const e of t.knownHookEvents)if(e in r.hooks){if(!C.default.array(r.hooks[e]))throw new TypeError(`Parameter \`${e}\` must be an Array, got ${C.default(r.hooks[e])}`);r.hooks[e]=[...r.hooks[e]]}else r.hooks[e]=[];if(n&&!f)for(const e of t.knownHookEvents){0!==n.hooks[e].length&&(r.hooks[e]=[...n.hooks[e],...r.hooks[e]])}if("family"in r&&v.default('"options.family" was never documented, please use "options.dnsLookupIpVersion"'),(null==n?void 0:n.https)&&(r.https={...n.https,...r.https}),"rejectUnauthorized"in r&&v.default('"options.rejectUnauthorized" is now deprecated, please use "options.https.rejectUnauthorized"'),"checkServerIdentity"in r&&v.default('"options.checkServerIdentity" was never documented, please use "options.https.checkServerIdentity"'),"ca"in r&&v.default('"options.ca" was never documented, please use "options.https.certificateAuthority"'),"key"in r&&v.default('"options.key" was never documented, please use "options.https.key"'),"cert"in r&&v.default('"options.cert" was never documented, please use "options.https.certificate"'),"passphrase"in r&&v.default('"options.passphrase" was never documented, please use "options.https.passphrase"'),"pfx"in r&&v.default('"options.pfx" was never documented, please use "options.https.pfx"'),"followRedirects"in r)throw new TypeError("The `followRedirects` option does not exist. Use `followRedirect` instead.");if(r.agent)for(const e in r.agent)if("http"!==e&&"https"!==e&&"http2"!==e)throw new TypeError(`Expected the \`options.agent\` properties to be \`http\`, \`https\` or \`http2\`, got \`${e}\``);return r.maxRedirects=null!==(g=r.maxRedirects)&&void 0!==g?g:0,t.setNonEnumerableProperties([n,l],r),S.default(r,n)}_lockWrite(){const e=()=>{throw new TypeError("The payload has been already provided")};this.write=e,this.end=e}_unlockWrite(){this.write=super.write,this.end=super.end}async _finalizeBody(){const{options:e}=this,{headers:r}=e,A=!C.default.undefined(e.form),o=!C.default.undefined(e.json),s=!C.default.undefined(e.body),a=A||o||s,c=t.withoutBody.has(e.method)&&!("GET"===e.method&&e.allowGetBody);if(this._cannotHaveBody=c,a){if(c)throw new TypeError(`The \`${e.method}\` method cannot be used with a body`);if([s,A,o].filter(e=>e).length>1)throw new TypeError("The `body`, `json` and `form` options are mutually exclusive");if(s&&!(e.body instanceof n.Readable)&&!C.default.string(e.body)&&!C.default.buffer(e.body)&&!I.default(e.body))throw new TypeError("The `body` option must be a stream.Readable, string or Buffer");if(A&&!C.default.object(e.form))throw new TypeError("The `form` option must be an Object");{const t=!C.default.string(r["content-type"]);s?(I.default(e.body)&&t&&(r["content-type"]="multipart/form-data; boundary="+e.body.getBoundary()),this[H]=e.body):A?(t&&(r["content-type"]="application/x-www-form-urlencoded"),this[H]=new i.URLSearchParams(e.form).toString()):(t&&(r["content-type"]="application/json"),this[H]=e.stringifyJson(e.json));const n=await f.default(this[H],e.headers);C.default.undefined(r["content-length"])&&C.default.undefined(r["transfer-encoding"])&&(c||C.default.undefined(n)||(r["content-length"]=String(n)))}}else c?this._lockWrite():this._unlockWrite();this[x]=Number(r["content-length"])||void 0}async _onResponseBase(e){const{options:t}=this,{url:r}=t;this[q]=e,t.decompress&&(e=h(e));const A=e.statusCode,n=e;n.statusMessage=n.statusMessage?n.statusMessage:s.STATUS_CODES[A],n.url=t.url.toString(),n.requestUrl=this.requestUrl,n.redirectUrls=this.redirects,n.request=this,n.isFromCache=e.fromCache||!1,n.ip=this.ip,n.retryCount=this.retryCount,this[U]=n.isFromCache,this[M]=Number(e.headers["content-length"])||void 0,this[K]=e,e.once("end",()=>{this[M]=this[R],this.emit("downloadProgress",this.downloadProgress)}),e.once("error",t=>{e.destroy(),this._beforeError(new ne(t,this))}),e.once("aborted",()=>{this._beforeError(new ne({name:"Error",message:"The server aborted pending request",code:"ECONNRESET"},this))}),this.emit("downloadProgress",this.downloadProgress);const o=e.headers["set-cookie"];if(C.default.object(t.cookieJar)&&o){let e=o.map(async e=>t.cookieJar.setCookie(e,r.toString()));t.ignoreInvalidCookies&&(e=e.map(async e=>e.catch(()=>{})));try{await Promise.all(e)}catch(e){return void this._beforeError(e)}}if(t.followRedirect&&e.headers.location&&X.has(A)){e.resume(),this[F]&&(this[T](),delete this[F],this[O]());if(!(303===A&&"GET"!==t.method&&"HEAD"!==t.method)&&t.methodRewriting||(t.method="GET","body"in t&&delete t.body,"json"in t&&delete t.json,"form"in t&&delete t.form,this[H]=void 0,delete t.headers["content-length"]),this.redirects.length>=t.maxRedirects)return void this._beforeError(new $(this));try{const A=Buffer.from(e.headers.location,"binary").toString(),o=new i.URL(A,r),s=o.toString();decodeURI(s),o.hostname!==r.hostname||o.port!==r.port?("host"in t.headers&&delete t.headers.host,"cookie"in t.headers&&delete t.headers.cookie,"authorization"in t.headers&&delete t.headers.authorization,(t.username||t.password)&&(t.username="",t.password="")):(o.username=t.username,o.password=t.password),this.redirects.push(s),t.url=o;for(const e of t.hooks.beforeRedirect)await e(t,n);this.emit("redirect",n,t),await this._makeRequest()}catch(e){return void this._beforeError(e)}}else if(t.isStream&&t.throwHttpErrors&&!b.isResponseOk(n))this._beforeError(new ee(n));else{e.on("readable",()=>{this[G]&&this._read()}),this.on("resume",()=>{e.resume()}),this.on("pause",()=>{e.pause()}),e.once("end",()=>{this.push(null)}),this.emit("response",e);for(const r of this[P])if(!r.headersSent){for(const A in e.headers){const n=!t.decompress||"content-encoding"!==A,o=e.headers[A];n&&r.setHeader(A,o)}r.statusCode=A}}}async _onResponse(e){try{await this._onResponseBase(e)}catch(e){this._beforeError(e)}}_onRequest(e){const{options:t}=this,{timeout:r,url:A}=t;g.default(e),this[T]=B.default(e,r,A);const n=t.cache?"cacheableResponse":"response";e.once(n,e=>{this._onResponse(e)}),e.once("error",t=>{var r;e.destroy(),null===(r=e.res)||void 0===r||r.removeAllListeners("end"),t=t instanceof B.TimeoutError?new Ae(t,this.timings,this):new Z(t.message,t,this),this._beforeError(t)}),this[O]=E.default(e,this,ie),this[F]=e,this.emit("uploadProgress",this.uploadProgress);const o=this[H],i=0===this.redirects.length?this:e;C.default.nodeStream(o)?(o.pipe(i),o.once("error",e=>{this._beforeError(new re(e,this))})):(this._unlockWrite(),C.default.undefined(o)?(this._cannotHaveBody||this._noPipe)&&(i.end(),this._lockWrite()):(this._writeRequest(o,void 0,()=>{}),i.end(),this._lockWrite())),this.emit("request",e)}async _createCacheableRequest(e,t){return new Promise((r,A)=>{let n;Object.assign(t,y.default(e)),delete t.url;const o=V.get(t.cache)(t,async e=>{e._readableState.autoDestroy=!1,n&&(await n).emit("cacheableResponse",e),r(e)});t.url=e,o.once("error",A),o.once("request",async e=>{n=e,r(n)})})}async _makeRequest(){var e,t,r,A,n;const{options:o}=this,{headers:i}=o;for(const e in i)if(C.default.undefined(i[e]))delete i[e];else if(C.default.null_(i[e]))throw new TypeError(`Use \`undefined\` instead of \`null\` to delete the \`${e}\` header`);if(o.decompress&&C.default.undefined(i["accept-encoding"])&&(i["accept-encoding"]=W?"gzip, deflate, br":"gzip, deflate"),o.cookieJar){const e=await o.cookieJar.getCookieString(o.url.toString());C.default.nonEmptyString(e)&&(o.headers.cookie=e)}for(const e of o.hooks.beforeRequest){const t=await e(o);if(!C.default.undefined(t)){o.request=()=>t;break}}o.body&&this[H]!==o.body&&(this[H]=o.body);const{agent:a,request:g,timeout:l,url:h}=o;if(o.dnsCache&&!("lookup"in o)&&(o.lookup=o.dnsCache.lookup),"unix"===h.hostname){const e=/(?.+?):(?.+)/.exec(`${h.pathname}${h.search}`);if(null==e?void 0:e.groups){const{socketPath:t,path:r}=e.groups;Object.assign(o,{socketPath:t,path:r,host:""})}}const d="https:"===h.protocol;let f;f=o.http2?p.auto:d?c.request:s.request;const I=null!==(e=o.request)&&void 0!==e?e:f,E=o.cache?this._createCacheableRequest:I;a&&!o.http2&&(o.agent=a[d?"https":"http"]),o[F]=I,delete o.request,delete o.timeout;const B=o;if(B.shared=null===(t=o.cacheOptions)||void 0===t?void 0:t.shared,B.cacheHeuristic=null===(r=o.cacheOptions)||void 0===r?void 0:r.cacheHeuristic,B.immutableMinTimeToLive=null===(A=o.cacheOptions)||void 0===A?void 0:A.immutableMinTimeToLive,B.ignoreCargoCult=null===(n=o.cacheOptions)||void 0===n?void 0:n.ignoreCargoCult,void 0!==o.dnsLookupIpVersion)try{B.family=D.dnsLookupIpVersionToFamily(o.dnsLookupIpVersion)}catch(e){throw new Error("Invalid `dnsLookupIpVersion` option value")}o.https&&("rejectUnauthorized"in o.https&&(B.rejectUnauthorized=o.https.rejectUnauthorized),o.https.checkServerIdentity&&(B.checkServerIdentity=o.https.checkServerIdentity),o.https.certificateAuthority&&(B.ca=o.https.certificateAuthority),o.https.certificate&&(B.cert=o.https.certificate),o.https.key&&(B.key=o.https.key),o.https.passphrase&&(B.passphrase=o.https.passphrase),o.https.pfx&&(B.pfx=o.https.pfx));try{let e=await E(h,B);C.default.undefined(e)&&(e=f(h,B)),o.request=g,o.timeout=l,o.agent=a,o.https&&("rejectUnauthorized"in o.https&&delete B.rejectUnauthorized,o.https.checkServerIdentity&&delete B.checkServerIdentity,o.https.certificateAuthority&&delete B.ca,o.https.certificate&&delete B.cert,o.https.key&&delete B.key,o.https.passphrase&&delete B.passphrase,o.https.pfx&&delete B.pfx),y=e,C.default.object(y)&&!("statusCode"in y)?this._onRequest(e):this.writable?(this.once("finish",()=>{this._onResponse(e)}),this._unlockWrite(),this.end(),this._lockWrite()):this._onResponse(e)}catch(e){if(e instanceof u.CacheError)throw new te(e,this);throw new Z(e.message,e,this)}var y}async _error(e){try{for(const t of this.options.hooks.beforeError)e=await t(e)}catch(t){e=new Z(t.message,t,this)}this.destroy(e)}_beforeError(e){if(this[Y])return;const{options:t}=this,r=this.retryCount+1;this[Y]=!0,e instanceof Z||(e=new Z(e.message,e,this));const A=e,{response:n}=A;(async()=>{if(n&&!n.body){n.setEncoding(this._readableState.encoding);try{n.rawBody=await Q.default(n),n.body=n.rawBody.toString()}catch(e){}}if(0!==this.listenerCount("retry")){let o;try{let e;n&&"retry-after"in n.headers&&(e=Number(n.headers["retry-after"]),Number.isNaN(e)?(e=Date.parse(n.headers["retry-after"])-Date.now(),e<=0&&(e=1)):e*=1e3),o=await t.retry.calculateDelay({attemptCount:r,retryOptions:t.retry,error:A,retryAfter:e,computedValue:k.default({attemptCount:r,retryOptions:t.retry,error:A,retryAfter:e,computedValue:0})})}catch(e){return void this._error(new Z(e.message,e,this))}if(o){const t=async()=>{try{for(const e of this.options.hooks.beforeRetry)await e(this.options,A,r)}catch(t){return void this._error(new Z(t.message,e,this))}this.destroyed||(this.destroy(),this.emit("retry",r,e))};return void(this[z]=setTimeout(t,o))}}this._error(A)})()}_read(){this[G]=!0;const e=this[K];if(e&&!this[Y]){let t;for(e.readableLength&&(this[G]=!1);null!==(t=e.read());){this[R]+=t.length,this[j]=!0;const e=this.downloadProgress;e.percent<1&&this.emit("downloadProgress",e),this.push(t)}}}_write(e,t,r){const A=()=>{this._writeRequest(e,t,r)};this.requestInitialized?A():this[J].push(A)}_writeRequest(e,t,r){this[F].destroyed||(this._progressCallbacks.push(()=>{this[L]+=Buffer.byteLength(e,t);const r=this.uploadProgress;r.percent<1&&this.emit("uploadProgress",r)}),this[F].write(e,t,e=>{e||0===this._progressCallbacks.length||this._progressCallbacks.shift()(),r(e)}))}_final(e){const t=()=>{for(;0!==this._progressCallbacks.length;)this._progressCallbacks.shift()();F in this?this[F].destroyed?e():this[F].end(t=>{t||(this[x]=this[L],this.emit("uploadProgress",this.uploadProgress),this[F].emit("upload-complete")),e(t)}):e()};this.requestInitialized?t():this[J].push(t)}_destroy(e,t){var r;this[Y]=!0,clearTimeout(this[z]),F in this&&(this[T](),(null===(r=this[K])||void 0===r?void 0:r.complete)||this[F].destroy()),null===e||C.default.undefined(e)||e instanceof Z||(e=new Z(e.message,e,this)),t(e)}get _isAboutToError(){return this[Y]}get ip(){var e;return null===(e=this[F])||void 0===e?void 0:e.socket.remoteAddress}get aborted(){var e,t,r;return(null!==(t=null===(e=this[F])||void 0===e?void 0:e.destroyed)&&void 0!==t?t:this.destroyed)&&!(null===(r=this[q])||void 0===r?void 0:r.complete)}get socket(){var e;return null===(e=this[F])||void 0===e?void 0:e.socket}get downloadProgress(){let e;return e=this[M]?this[R]/this[M]:this[M]===this[R]?1:0,{percent:e,transferred:this[R],total:this[M]}}get uploadProgress(){let e;return e=this[x]?this[L]/this[x]:this[x]===this[L]?1:0,{percent:e,transferred:this[L],total:this[x]}}get timings(){var e;return null===(e=this[F])||void 0===e?void 0:e.timings}get isFromCache(){return this[U]}pipe(e,t){if(this[j])throw new Error("Failed to pipe. The response has been emitted already.");return e instanceof a.ServerResponse&&this[P].add(e),super.pipe(e,t)}unpipe(e){return e instanceof a.ServerResponse&&this[P].delete(e),super.unpipe(e),this}}t.default=se},11338:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.dnsLookupIpVersionToFamily=t.isDnsLookupIpVersion=void 0;const r={auto:0,ipv4:4,ipv6:6};t.isDnsLookupIpVersion=e=>e in r,t.dnsLookupIpVersionToFamily=e=>{if(t.isDnsLookupIpVersion(e))return r[e];throw new Error("Invalid DNS lookup IP version")}},78586:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(35747),n=r(31669),o=r(7966),i=r(2920),s=n.promisify(A.stat);t.default=async(e,t)=>{if(t&&"content-length"in t)return Number(t["content-length"]);if(!e)return 0;if(o.default.string(e))return Buffer.byteLength(e);if(o.default.buffer(e))return e.length;if(i.default(e))return n.promisify(e.getLength.bind(e))();if(e instanceof A.ReadStream){const{size:t}=await s(e.path);return t}}},57854:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.default=async e=>{const t=[];let r=0;for await(const A of e)t.push(A),r+=Buffer.byteLength(A);return Buffer.isBuffer(t[0])?Buffer.concat(t,r):Buffer.from(t.join(""))}},2920:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(7966);t.default=e=>A.default.nodeStream(e)&&A.default.function_(e.getBoundary)},38206:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isResponseOk=void 0,t.isResponseOk=e=>{const{statusCode:t}=e,r=e.request.options.followRedirect?299:399;return t>=200&&t<=r||304===t}},82524:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(78835),n=["protocol","host","hostname","port","pathname","search"];t.default=(e,t)=>{var r,o;if(t.path){if(t.pathname)throw new TypeError("Parameters `path` and `pathname` are mutually exclusive.");if(t.search)throw new TypeError("Parameters `path` and `search` are mutually exclusive.");if(t.searchParams)throw new TypeError("Parameters `path` and `searchParams` are mutually exclusive.")}if(t.search&&t.searchParams)throw new TypeError("Parameters `search` and `searchParams` are mutually exclusive.");if(!e){if(!t.protocol)throw new TypeError("No URL protocol specified");e=`${t.protocol}//${null!==(o=null!==(r=t.hostname)&&void 0!==r?r:t.host)&&void 0!==o?o:""}`}const i=new A.URL(e);if(t.path){const e=t.path.indexOf("?");-1===e?t.pathname=t.path:(t.pathname=t.path.slice(0,e),t.search=t.path.slice(e+1)),delete t.path}for(const e of n)t[e]&&(i[e]=t[e].toString());return i}},51743:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,r){const A={};for(const n of r)A[n]=(...e)=>{t.emit(n,...e)},e.on(n,A[n]);return()=>{for(const t of r)e.off(t,A[t])}}},44947:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.TimeoutError=void 0;const A=r(11631),n=r(70148),o=Symbol("reentry"),i=()=>{};class s extends Error{constructor(e,t){super(`Timeout awaiting '${t}' for ${e}ms`),this.event=t,this.name="TimeoutError",this.code="ETIMEDOUT"}}t.TimeoutError=s,t.default=(e,t,r)=>{if(o in e)return i;e[o]=!0;const a=[],{once:c,unhandleAll:g}=n.default(),l=(e,t,r)=>{var A;const n=setTimeout(t,e,e,r);null===(A=n.unref)||void 0===A||A.call(n);const o=()=>{clearTimeout(n)};return a.push(o),o},{host:u,hostname:h}=r,p=(t,r)=>{e.destroy(new s(t,r))},d=()=>{for(const e of a)e();g()};if(e.once("error",t=>{if(d(),0===e.listenerCount("error"))throw t}),e.once("close",d),c(e,"response",e=>{c(e,"end",d)}),void 0!==t.request&&l(t.request,p,"request"),void 0!==t.socket){const r=()=>{p(t.socket,"socket")};e.setTimeout(t.socket,r),a.push(()=>{e.removeListener("timeout",r)})}return c(e,"socket",n=>{var o;const{socketPath:i}=e;if(n.connecting){const e=Boolean(null!=i?i:0!==A.isIP(null!==(o=null!=h?h:u)&&void 0!==o?o:""));if(void 0!==t.lookup&&!e&&void 0===n.address().address){const e=l(t.lookup,p,"lookup");c(n,"lookup",e)}if(void 0!==t.connect){const r=()=>l(t.connect,p,"connect");e?c(n,"connect",r()):c(n,"lookup",e=>{null===e&&c(n,"connect",r())})}void 0!==t.secureConnect&&"https:"===r.protocol&&c(n,"connect",()=>{const e=l(t.secureConnect,p,"secureConnect");c(n,"secureConnect",e)})}if(void 0!==t.send){const r=()=>l(t.send,p,"send");n.connecting?c(n,"connect",()=>{c(e,"upload-complete",r())}):c(e,"upload-complete",r())}}),void 0!==t.response&&c(e,"upload-complete",()=>{const r=l(t.response,p,"response");c(e,"response",r)}),d}},70148:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=()=>{const e=[];return{once(t,r,A){t.once(r,A),e.push({origin:t,event:r,fn:A})},unhandleAll(){for(const t of e){const{origin:e,event:r,fn:A}=t;e.removeListener(r,A)}e.length=0}}}},50116:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(7966);t.default=e=>{const t={protocol:(e=e).protocol,hostname:A.default.string(e.hostname)&&e.hostname.startsWith("[")?e.hostname.slice(1,-1):e.hostname,host:e.host,hash:e.hash,search:e.search,pathname:e.pathname,href:e.href,path:`${e.pathname||""}${e.search||""}`};return A.default.string(e.port)&&0!==e.port.length&&(t.port=Number(e.port)),(e.username||e.password)&&(t.auth=`${e.username||""}:${e.password||""}`),t}},85551:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.default=class{constructor(){this.weakMap=new WeakMap,this.map=new Map}set(e,t){"object"==typeof e?this.weakMap.set(e,t):this.map.set(e,t)}get(e){return"object"==typeof e?this.weakMap.get(e):this.map.get(e)}has(e){return"object"==typeof e?this.weakMap.has(e):this.map.has(e)}}},39226:function(e,t,r){"use strict";var A=this&&this.__createBinding||(Object.create?function(e,t,r,A){void 0===A&&(A=r),Object.defineProperty(e,A,{enumerable:!0,get:function(){return t[r]}})}:function(e,t,r,A){void 0===A&&(A=r),e[A]=t[r]}),n=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||A(t,e,r)};Object.defineProperty(t,"__esModule",{value:!0}),t.defaultHandler=void 0;const o=r(7966),i=r(81588),s=r(93576),a=r(9048),c=r(9743),g={RequestError:i.RequestError,CacheError:i.CacheError,ReadError:i.ReadError,HTTPError:i.HTTPError,MaxRedirectsError:i.MaxRedirectsError,TimeoutError:i.TimeoutError,ParseError:i.ParseError,CancelError:i.CancelError,UnsupportedProtocolError:i.UnsupportedProtocolError,UploadError:i.UploadError},l=async e=>new Promise(t=>{setTimeout(t,e)}),{normalizeArguments:u}=a.default,h=(...e)=>{let t;for(const r of e)t=u(void 0,r,t);return t},p=e=>e.isStream?new a.default(void 0,e):i.default(e),d=e=>"defaults"in e&&"options"in e.defaults,C=["get","post","put","patch","head","delete"];t.defaultHandler=(e,t)=>t(e);const f=(e,t)=>{if(e)for(const r of e)r(t)},I=e=>{e._rawHandlers=e.handlers,e.handlers=e.handlers.map(e=>(t,r)=>{let A;const n=e(t,e=>(A=r(e),A));if(n!==A&&!t.isStream&&A){const e=n,{then:t,catch:r,finally:o}=e;Object.setPrototypeOf(e,Object.getPrototypeOf(A)),Object.defineProperties(e,Object.getOwnPropertyDescriptors(A)),e.then=t,e.catch=r,e.finally=o}return n});const r=(t,r,A)=>{var n,c;let g=0;const l=t=>e.handlers[g++](t,g===e.handlers.length?p:l);if(o.default.plainObject(t)){const e={...t,...r};a.setNonEnumerableProperties([t,r],e),r=e,t=void 0}try{let o;try{f(e.options.hooks.init,r),f(null===(n=null==r?void 0:r.hooks)||void 0===n?void 0:n.init,r)}catch(e){o=e}const s=u(t,r,null!=A?A:e.options);if(s[a.kIsNormalizedAlready]=!0,o)throw new i.RequestError(o.message,o,s);return l(s)}catch(t){if(null==r?void 0:r.isStream)throw t;return s.default(t,e.options.hooks.beforeError,null===(c=null==r?void 0:r.hooks)||void 0===c?void 0:c.beforeError)}};r.extend=(...r)=>{const A=[e.options];let n,o=[...e._rawHandlers];for(const e of r)d(e)?(A.push(e.defaults.options),o.push(...e.defaults._rawHandlers),n=e.defaults.mutableDefaults):(A.push(e),"handlers"in e&&o.push(...e.handlers),n=e.mutableDefaults);return o=o.filter(e=>e!==t.defaultHandler),0===o.length&&o.push(t.defaultHandler),I({options:h(...A),handlers:o,mutableDefaults:Boolean(n)})};const A=async function*(t,A){let n=u(t,A,e.options);n.resolveBodyOnly=!1;const i=n.pagination;if(!o.default.object(i))throw new TypeError("`options.pagination` must be implemented");const s=[];let{countLimit:a}=i,c=0;for(;c{const r=[];for await(const n of A(e,t))r.push(n);return r},r.paginate.each=A,r.stream=(e,t)=>r(e,{...t,isStream:!0});for(const e of C)r[e]=(t,A)=>r(t,{...A,method:e}),r.stream[e]=(t,A)=>r(t,{...A,method:e,isStream:!0});return Object.assign(r,g),Object.defineProperty(r,"defaults",{value:e.mutableDefaults?e:c.default(e),writable:e.mutableDefaults,configurable:e.mutableDefaults,enumerable:!0}),r.mergeOptions=h,r};t.default=I,n(r(69022),t)},48722:function(e,t,r){"use strict";var A=this&&this.__createBinding||(Object.create?function(e,t,r,A){void 0===A&&(A=r),Object.defineProperty(e,A,{enumerable:!0,get:function(){return t[r]}})}:function(e,t,r,A){void 0===A&&(A=r),e[A]=t[r]}),n=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||A(t,e,r)};Object.defineProperty(t,"__esModule",{value:!0});const o=r(78835),i=r(39226),s={options:{method:"GET",retry:{limit:2,methods:["GET","PUT","HEAD","DELETE","OPTIONS","TRACE"],statusCodes:[408,413,429,500,502,503,504,521,522,524],errorCodes:["ETIMEDOUT","ECONNRESET","EADDRINUSE","ECONNREFUSED","EPIPE","ENOTFOUND","ENETUNREACH","EAI_AGAIN"],maxRetryAfter:void 0,calculateDelay:({computedValue:e})=>e},timeout:{},headers:{"user-agent":"got (https://github.com/sindresorhus/got)"},hooks:{init:[],beforeRequest:[],beforeRedirect:[],beforeRetry:[],beforeError:[],afterResponse:[]},cache:void 0,dnsCache:void 0,decompress:!0,throwHttpErrors:!0,followRedirect:!0,isStream:!1,responseType:"text",resolveBodyOnly:!1,maxRedirects:10,prefixUrl:"",methodRewriting:!0,ignoreInvalidCookies:!1,context:{},http2:!1,allowGetBody:!1,https:void 0,pagination:{transform:e=>"json"===e.request.options.responseType?e.body:JSON.parse(e.body),paginate:e=>{if(!Reflect.has(e.headers,"link"))return!1;const t=e.headers.link.split(",");let r;for(const e of t){const t=e.split(";");if(t[1].includes("next")){r=t[0].trimStart().trim(),r=r.slice(1,-1);break}}if(r){return{url:new o.URL(r)}}return!1},filter:()=>!0,shouldContinue:()=>!0,countLimit:1/0,backoff:0,requestLimit:1e4,stackAllItems:!0},parseJson:e=>JSON.parse(e),stringifyJson:e=>JSON.stringify(e),cacheOptions:{}},handlers:[i.defaultHandler],mutableDefaults:!1},a=i.default(s);t.default=a,e.exports=a,e.exports.default=a,e.exports.__esModule=!0,n(r(39226),t),n(r(81588),t)},69022:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},9743:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const A=r(7966);t.default=function e(t){for(const r of Object.values(t))(A.default.plainObject(r)||A.default.array(r))&&e(r);return Object.freeze(t)}},54595:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=new Set;t.default=e=>{r.has(e)||(r.add(e),process.emitWarning("Got: "+e,{type:"DeprecationWarning"}))}},74988:e=>{e.exports&&(e.exports=function(){var e=3,t=4,r=12,A=13,n=16,o=17;function i(e,t){void 0===t&&(t=0);var r=e.charCodeAt(t);if(55296<=r&&r<=56319&&t=1){var n=r;return 55296<=(A=e.charCodeAt(t-1))&&A<=56319?1024*(A-55296)+(n-56320)+65536:n}return r}function s(i,s,a){var c=[i].concat(s).concat([a]),g=c[c.length-2],l=a,u=c.lastIndexOf(14);if(u>1&&c.slice(1,u).every((function(t){return t==e}))&&-1==[e,A,o].indexOf(i))return 2;var h=c.lastIndexOf(t);if(h>0&&c.slice(1,h).every((function(e){return e==t}))&&-1==[r,t].indexOf(g))return c.filter((function(e){return e==t})).length%2==1?3:4;if(0==g&&1==l)return 0;if(2==g||0==g||1==g)return 14==l&&s.every((function(t){return t==e}))?2:1;if(2==l||0==l||1==l)return 1;if(6==g&&(6==l||7==l||9==l||10==l))return 0;if(!(9!=g&&7!=g||7!=l&&8!=l))return 0;if((10==g||8==g)&&8==l)return 0;if(l==e||15==l)return 0;if(5==l)return 0;if(g==r)return 0;var p=-1!=c.indexOf(e)?c.lastIndexOf(e)-1:c.length-2;return-1!=[A,o].indexOf(c[p])&&c.slice(p+1,-1).every((function(t){return t==e}))&&14==l||15==g&&-1!=[n,o].indexOf(l)?0:-1!=s.indexOf(t)?2:g==t&&l==t?0:1}function a(i){return 1536<=i&&i<=1541||1757==i||1807==i||2274==i||3406==i||69821==i||70082<=i&&i<=70083||72250==i||72326<=i&&i<=72329||73030==i?r:13==i?0:10==i?1:0<=i&&i<=9||11<=i&&i<=12||14<=i&&i<=31||127<=i&&i<=159||173==i||1564==i||6158==i||8203==i||8206<=i&&i<=8207||8232==i||8233==i||8234<=i&&i<=8238||8288<=i&&i<=8292||8293==i||8294<=i&&i<=8303||55296<=i&&i<=57343||65279==i||65520<=i&&i<=65528||65529<=i&&i<=65531||113824<=i&&i<=113827||119155<=i&&i<=119162||917504==i||917505==i||917506<=i&&i<=917535||917632<=i&&i<=917759||918e3<=i&&i<=921599?2:768<=i&&i<=879||1155<=i&&i<=1159||1160<=i&&i<=1161||1425<=i&&i<=1469||1471==i||1473<=i&&i<=1474||1476<=i&&i<=1477||1479==i||1552<=i&&i<=1562||1611<=i&&i<=1631||1648==i||1750<=i&&i<=1756||1759<=i&&i<=1764||1767<=i&&i<=1768||1770<=i&&i<=1773||1809==i||1840<=i&&i<=1866||1958<=i&&i<=1968||2027<=i&&i<=2035||2070<=i&&i<=2073||2075<=i&&i<=2083||2085<=i&&i<=2087||2089<=i&&i<=2093||2137<=i&&i<=2139||2260<=i&&i<=2273||2275<=i&&i<=2306||2362==i||2364==i||2369<=i&&i<=2376||2381==i||2385<=i&&i<=2391||2402<=i&&i<=2403||2433==i||2492==i||2494==i||2497<=i&&i<=2500||2509==i||2519==i||2530<=i&&i<=2531||2561<=i&&i<=2562||2620==i||2625<=i&&i<=2626||2631<=i&&i<=2632||2635<=i&&i<=2637||2641==i||2672<=i&&i<=2673||2677==i||2689<=i&&i<=2690||2748==i||2753<=i&&i<=2757||2759<=i&&i<=2760||2765==i||2786<=i&&i<=2787||2810<=i&&i<=2815||2817==i||2876==i||2878==i||2879==i||2881<=i&&i<=2884||2893==i||2902==i||2903==i||2914<=i&&i<=2915||2946==i||3006==i||3008==i||3021==i||3031==i||3072==i||3134<=i&&i<=3136||3142<=i&&i<=3144||3146<=i&&i<=3149||3157<=i&&i<=3158||3170<=i&&i<=3171||3201==i||3260==i||3263==i||3266==i||3270==i||3276<=i&&i<=3277||3285<=i&&i<=3286||3298<=i&&i<=3299||3328<=i&&i<=3329||3387<=i&&i<=3388||3390==i||3393<=i&&i<=3396||3405==i||3415==i||3426<=i&&i<=3427||3530==i||3535==i||3538<=i&&i<=3540||3542==i||3551==i||3633==i||3636<=i&&i<=3642||3655<=i&&i<=3662||3761==i||3764<=i&&i<=3769||3771<=i&&i<=3772||3784<=i&&i<=3789||3864<=i&&i<=3865||3893==i||3895==i||3897==i||3953<=i&&i<=3966||3968<=i&&i<=3972||3974<=i&&i<=3975||3981<=i&&i<=3991||3993<=i&&i<=4028||4038==i||4141<=i&&i<=4144||4146<=i&&i<=4151||4153<=i&&i<=4154||4157<=i&&i<=4158||4184<=i&&i<=4185||4190<=i&&i<=4192||4209<=i&&i<=4212||4226==i||4229<=i&&i<=4230||4237==i||4253==i||4957<=i&&i<=4959||5906<=i&&i<=5908||5938<=i&&i<=5940||5970<=i&&i<=5971||6002<=i&&i<=6003||6068<=i&&i<=6069||6071<=i&&i<=6077||6086==i||6089<=i&&i<=6099||6109==i||6155<=i&&i<=6157||6277<=i&&i<=6278||6313==i||6432<=i&&i<=6434||6439<=i&&i<=6440||6450==i||6457<=i&&i<=6459||6679<=i&&i<=6680||6683==i||6742==i||6744<=i&&i<=6750||6752==i||6754==i||6757<=i&&i<=6764||6771<=i&&i<=6780||6783==i||6832<=i&&i<=6845||6846==i||6912<=i&&i<=6915||6964==i||6966<=i&&i<=6970||6972==i||6978==i||7019<=i&&i<=7027||7040<=i&&i<=7041||7074<=i&&i<=7077||7080<=i&&i<=7081||7083<=i&&i<=7085||7142==i||7144<=i&&i<=7145||7149==i||7151<=i&&i<=7153||7212<=i&&i<=7219||7222<=i&&i<=7223||7376<=i&&i<=7378||7380<=i&&i<=7392||7394<=i&&i<=7400||7405==i||7412==i||7416<=i&&i<=7417||7616<=i&&i<=7673||7675<=i&&i<=7679||8204==i||8400<=i&&i<=8412||8413<=i&&i<=8416||8417==i||8418<=i&&i<=8420||8421<=i&&i<=8432||11503<=i&&i<=11505||11647==i||11744<=i&&i<=11775||12330<=i&&i<=12333||12334<=i&&i<=12335||12441<=i&&i<=12442||42607==i||42608<=i&&i<=42610||42612<=i&&i<=42621||42654<=i&&i<=42655||42736<=i&&i<=42737||43010==i||43014==i||43019==i||43045<=i&&i<=43046||43204<=i&&i<=43205||43232<=i&&i<=43249||43302<=i&&i<=43309||43335<=i&&i<=43345||43392<=i&&i<=43394||43443==i||43446<=i&&i<=43449||43452==i||43493==i||43561<=i&&i<=43566||43569<=i&&i<=43570||43573<=i&&i<=43574||43587==i||43596==i||43644==i||43696==i||43698<=i&&i<=43700||43703<=i&&i<=43704||43710<=i&&i<=43711||43713==i||43756<=i&&i<=43757||43766==i||44005==i||44008==i||44013==i||64286==i||65024<=i&&i<=65039||65056<=i&&i<=65071||65438<=i&&i<=65439||66045==i||66272==i||66422<=i&&i<=66426||68097<=i&&i<=68099||68101<=i&&i<=68102||68108<=i&&i<=68111||68152<=i&&i<=68154||68159==i||68325<=i&&i<=68326||69633==i||69688<=i&&i<=69702||69759<=i&&i<=69761||69811<=i&&i<=69814||69817<=i&&i<=69818||69888<=i&&i<=69890||69927<=i&&i<=69931||69933<=i&&i<=69940||70003==i||70016<=i&&i<=70017||70070<=i&&i<=70078||70090<=i&&i<=70092||70191<=i&&i<=70193||70196==i||70198<=i&&i<=70199||70206==i||70367==i||70371<=i&&i<=70378||70400<=i&&i<=70401||70460==i||70462==i||70464==i||70487==i||70502<=i&&i<=70508||70512<=i&&i<=70516||70712<=i&&i<=70719||70722<=i&&i<=70724||70726==i||70832==i||70835<=i&&i<=70840||70842==i||70845==i||70847<=i&&i<=70848||70850<=i&&i<=70851||71087==i||71090<=i&&i<=71093||71100<=i&&i<=71101||71103<=i&&i<=71104||71132<=i&&i<=71133||71219<=i&&i<=71226||71229==i||71231<=i&&i<=71232||71339==i||71341==i||71344<=i&&i<=71349||71351==i||71453<=i&&i<=71455||71458<=i&&i<=71461||71463<=i&&i<=71467||72193<=i&&i<=72198||72201<=i&&i<=72202||72243<=i&&i<=72248||72251<=i&&i<=72254||72263==i||72273<=i&&i<=72278||72281<=i&&i<=72283||72330<=i&&i<=72342||72344<=i&&i<=72345||72752<=i&&i<=72758||72760<=i&&i<=72765||72767==i||72850<=i&&i<=72871||72874<=i&&i<=72880||72882<=i&&i<=72883||72885<=i&&i<=72886||73009<=i&&i<=73014||73018==i||73020<=i&&i<=73021||73023<=i&&i<=73029||73031==i||92912<=i&&i<=92916||92976<=i&&i<=92982||94095<=i&&i<=94098||113821<=i&&i<=113822||119141==i||119143<=i&&i<=119145||119150<=i&&i<=119154||119163<=i&&i<=119170||119173<=i&&i<=119179||119210<=i&&i<=119213||119362<=i&&i<=119364||121344<=i&&i<=121398||121403<=i&&i<=121452||121461==i||121476==i||121499<=i&&i<=121503||121505<=i&&i<=121519||122880<=i&&i<=122886||122888<=i&&i<=122904||122907<=i&&i<=122913||122915<=i&&i<=122916||122918<=i&&i<=122922||125136<=i&&i<=125142||125252<=i&&i<=125258||917536<=i&&i<=917631||917760<=i&&i<=917999?e:127462<=i&&i<=127487?t:2307==i||2363==i||2366<=i&&i<=2368||2377<=i&&i<=2380||2382<=i&&i<=2383||2434<=i&&i<=2435||2495<=i&&i<=2496||2503<=i&&i<=2504||2507<=i&&i<=2508||2563==i||2622<=i&&i<=2624||2691==i||2750<=i&&i<=2752||2761==i||2763<=i&&i<=2764||2818<=i&&i<=2819||2880==i||2887<=i&&i<=2888||2891<=i&&i<=2892||3007==i||3009<=i&&i<=3010||3014<=i&&i<=3016||3018<=i&&i<=3020||3073<=i&&i<=3075||3137<=i&&i<=3140||3202<=i&&i<=3203||3262==i||3264<=i&&i<=3265||3267<=i&&i<=3268||3271<=i&&i<=3272||3274<=i&&i<=3275||3330<=i&&i<=3331||3391<=i&&i<=3392||3398<=i&&i<=3400||3402<=i&&i<=3404||3458<=i&&i<=3459||3536<=i&&i<=3537||3544<=i&&i<=3550||3570<=i&&i<=3571||3635==i||3763==i||3902<=i&&i<=3903||3967==i||4145==i||4155<=i&&i<=4156||4182<=i&&i<=4183||4228==i||6070==i||6078<=i&&i<=6085||6087<=i&&i<=6088||6435<=i&&i<=6438||6441<=i&&i<=6443||6448<=i&&i<=6449||6451<=i&&i<=6456||6681<=i&&i<=6682||6741==i||6743==i||6765<=i&&i<=6770||6916==i||6965==i||6971==i||6973<=i&&i<=6977||6979<=i&&i<=6980||7042==i||7073==i||7078<=i&&i<=7079||7082==i||7143==i||7146<=i&&i<=7148||7150==i||7154<=i&&i<=7155||7204<=i&&i<=7211||7220<=i&&i<=7221||7393==i||7410<=i&&i<=7411||7415==i||43043<=i&&i<=43044||43047==i||43136<=i&&i<=43137||43188<=i&&i<=43203||43346<=i&&i<=43347||43395==i||43444<=i&&i<=43445||43450<=i&&i<=43451||43453<=i&&i<=43456||43567<=i&&i<=43568||43571<=i&&i<=43572||43597==i||43755==i||43758<=i&&i<=43759||43765==i||44003<=i&&i<=44004||44006<=i&&i<=44007||44009<=i&&i<=44010||44012==i||69632==i||69634==i||69762==i||69808<=i&&i<=69810||69815<=i&&i<=69816||69932==i||70018==i||70067<=i&&i<=70069||70079<=i&&i<=70080||70188<=i&&i<=70190||70194<=i&&i<=70195||70197==i||70368<=i&&i<=70370||70402<=i&&i<=70403||70463==i||70465<=i&&i<=70468||70471<=i&&i<=70472||70475<=i&&i<=70477||70498<=i&&i<=70499||70709<=i&&i<=70711||70720<=i&&i<=70721||70725==i||70833<=i&&i<=70834||70841==i||70843<=i&&i<=70844||70846==i||70849==i||71088<=i&&i<=71089||71096<=i&&i<=71099||71102==i||71216<=i&&i<=71218||71227<=i&&i<=71228||71230==i||71340==i||71342<=i&&i<=71343||71350==i||71456<=i&&i<=71457||71462==i||72199<=i&&i<=72200||72249==i||72279<=i&&i<=72280||72343==i||72751==i||72766==i||72873==i||72881==i||72884==i||94033<=i&&i<=94078||119142==i||119149==i?5:4352<=i&&i<=4447||43360<=i&&i<=43388?6:4448<=i&&i<=4519||55216<=i&&i<=55238?7:4520<=i&&i<=4607||55243<=i&&i<=55291?8:44032==i||44060==i||44088==i||44116==i||44144==i||44172==i||44200==i||44228==i||44256==i||44284==i||44312==i||44340==i||44368==i||44396==i||44424==i||44452==i||44480==i||44508==i||44536==i||44564==i||44592==i||44620==i||44648==i||44676==i||44704==i||44732==i||44760==i||44788==i||44816==i||44844==i||44872==i||44900==i||44928==i||44956==i||44984==i||45012==i||45040==i||45068==i||45096==i||45124==i||45152==i||45180==i||45208==i||45236==i||45264==i||45292==i||45320==i||45348==i||45376==i||45404==i||45432==i||45460==i||45488==i||45516==i||45544==i||45572==i||45600==i||45628==i||45656==i||45684==i||45712==i||45740==i||45768==i||45796==i||45824==i||45852==i||45880==i||45908==i||45936==i||45964==i||45992==i||46020==i||46048==i||46076==i||46104==i||46132==i||46160==i||46188==i||46216==i||46244==i||46272==i||46300==i||46328==i||46356==i||46384==i||46412==i||46440==i||46468==i||46496==i||46524==i||46552==i||46580==i||46608==i||46636==i||46664==i||46692==i||46720==i||46748==i||46776==i||46804==i||46832==i||46860==i||46888==i||46916==i||46944==i||46972==i||47e3==i||47028==i||47056==i||47084==i||47112==i||47140==i||47168==i||47196==i||47224==i||47252==i||47280==i||47308==i||47336==i||47364==i||47392==i||47420==i||47448==i||47476==i||47504==i||47532==i||47560==i||47588==i||47616==i||47644==i||47672==i||47700==i||47728==i||47756==i||47784==i||47812==i||47840==i||47868==i||47896==i||47924==i||47952==i||47980==i||48008==i||48036==i||48064==i||48092==i||48120==i||48148==i||48176==i||48204==i||48232==i||48260==i||48288==i||48316==i||48344==i||48372==i||48400==i||48428==i||48456==i||48484==i||48512==i||48540==i||48568==i||48596==i||48624==i||48652==i||48680==i||48708==i||48736==i||48764==i||48792==i||48820==i||48848==i||48876==i||48904==i||48932==i||48960==i||48988==i||49016==i||49044==i||49072==i||49100==i||49128==i||49156==i||49184==i||49212==i||49240==i||49268==i||49296==i||49324==i||49352==i||49380==i||49408==i||49436==i||49464==i||49492==i||49520==i||49548==i||49576==i||49604==i||49632==i||49660==i||49688==i||49716==i||49744==i||49772==i||49800==i||49828==i||49856==i||49884==i||49912==i||49940==i||49968==i||49996==i||50024==i||50052==i||50080==i||50108==i||50136==i||50164==i||50192==i||50220==i||50248==i||50276==i||50304==i||50332==i||50360==i||50388==i||50416==i||50444==i||50472==i||50500==i||50528==i||50556==i||50584==i||50612==i||50640==i||50668==i||50696==i||50724==i||50752==i||50780==i||50808==i||50836==i||50864==i||50892==i||50920==i||50948==i||50976==i||51004==i||51032==i||51060==i||51088==i||51116==i||51144==i||51172==i||51200==i||51228==i||51256==i||51284==i||51312==i||51340==i||51368==i||51396==i||51424==i||51452==i||51480==i||51508==i||51536==i||51564==i||51592==i||51620==i||51648==i||51676==i||51704==i||51732==i||51760==i||51788==i||51816==i||51844==i||51872==i||51900==i||51928==i||51956==i||51984==i||52012==i||52040==i||52068==i||52096==i||52124==i||52152==i||52180==i||52208==i||52236==i||52264==i||52292==i||52320==i||52348==i||52376==i||52404==i||52432==i||52460==i||52488==i||52516==i||52544==i||52572==i||52600==i||52628==i||52656==i||52684==i||52712==i||52740==i||52768==i||52796==i||52824==i||52852==i||52880==i||52908==i||52936==i||52964==i||52992==i||53020==i||53048==i||53076==i||53104==i||53132==i||53160==i||53188==i||53216==i||53244==i||53272==i||53300==i||53328==i||53356==i||53384==i||53412==i||53440==i||53468==i||53496==i||53524==i||53552==i||53580==i||53608==i||53636==i||53664==i||53692==i||53720==i||53748==i||53776==i||53804==i||53832==i||53860==i||53888==i||53916==i||53944==i||53972==i||54e3==i||54028==i||54056==i||54084==i||54112==i||54140==i||54168==i||54196==i||54224==i||54252==i||54280==i||54308==i||54336==i||54364==i||54392==i||54420==i||54448==i||54476==i||54504==i||54532==i||54560==i||54588==i||54616==i||54644==i||54672==i||54700==i||54728==i||54756==i||54784==i||54812==i||54840==i||54868==i||54896==i||54924==i||54952==i||54980==i||55008==i||55036==i||55064==i||55092==i||55120==i||55148==i||55176==i?9:44033<=i&&i<=44059||44061<=i&&i<=44087||44089<=i&&i<=44115||44117<=i&&i<=44143||44145<=i&&i<=44171||44173<=i&&i<=44199||44201<=i&&i<=44227||44229<=i&&i<=44255||44257<=i&&i<=44283||44285<=i&&i<=44311||44313<=i&&i<=44339||44341<=i&&i<=44367||44369<=i&&i<=44395||44397<=i&&i<=44423||44425<=i&&i<=44451||44453<=i&&i<=44479||44481<=i&&i<=44507||44509<=i&&i<=44535||44537<=i&&i<=44563||44565<=i&&i<=44591||44593<=i&&i<=44619||44621<=i&&i<=44647||44649<=i&&i<=44675||44677<=i&&i<=44703||44705<=i&&i<=44731||44733<=i&&i<=44759||44761<=i&&i<=44787||44789<=i&&i<=44815||44817<=i&&i<=44843||44845<=i&&i<=44871||44873<=i&&i<=44899||44901<=i&&i<=44927||44929<=i&&i<=44955||44957<=i&&i<=44983||44985<=i&&i<=45011||45013<=i&&i<=45039||45041<=i&&i<=45067||45069<=i&&i<=45095||45097<=i&&i<=45123||45125<=i&&i<=45151||45153<=i&&i<=45179||45181<=i&&i<=45207||45209<=i&&i<=45235||45237<=i&&i<=45263||45265<=i&&i<=45291||45293<=i&&i<=45319||45321<=i&&i<=45347||45349<=i&&i<=45375||45377<=i&&i<=45403||45405<=i&&i<=45431||45433<=i&&i<=45459||45461<=i&&i<=45487||45489<=i&&i<=45515||45517<=i&&i<=45543||45545<=i&&i<=45571||45573<=i&&i<=45599||45601<=i&&i<=45627||45629<=i&&i<=45655||45657<=i&&i<=45683||45685<=i&&i<=45711||45713<=i&&i<=45739||45741<=i&&i<=45767||45769<=i&&i<=45795||45797<=i&&i<=45823||45825<=i&&i<=45851||45853<=i&&i<=45879||45881<=i&&i<=45907||45909<=i&&i<=45935||45937<=i&&i<=45963||45965<=i&&i<=45991||45993<=i&&i<=46019||46021<=i&&i<=46047||46049<=i&&i<=46075||46077<=i&&i<=46103||46105<=i&&i<=46131||46133<=i&&i<=46159||46161<=i&&i<=46187||46189<=i&&i<=46215||46217<=i&&i<=46243||46245<=i&&i<=46271||46273<=i&&i<=46299||46301<=i&&i<=46327||46329<=i&&i<=46355||46357<=i&&i<=46383||46385<=i&&i<=46411||46413<=i&&i<=46439||46441<=i&&i<=46467||46469<=i&&i<=46495||46497<=i&&i<=46523||46525<=i&&i<=46551||46553<=i&&i<=46579||46581<=i&&i<=46607||46609<=i&&i<=46635||46637<=i&&i<=46663||46665<=i&&i<=46691||46693<=i&&i<=46719||46721<=i&&i<=46747||46749<=i&&i<=46775||46777<=i&&i<=46803||46805<=i&&i<=46831||46833<=i&&i<=46859||46861<=i&&i<=46887||46889<=i&&i<=46915||46917<=i&&i<=46943||46945<=i&&i<=46971||46973<=i&&i<=46999||47001<=i&&i<=47027||47029<=i&&i<=47055||47057<=i&&i<=47083||47085<=i&&i<=47111||47113<=i&&i<=47139||47141<=i&&i<=47167||47169<=i&&i<=47195||47197<=i&&i<=47223||47225<=i&&i<=47251||47253<=i&&i<=47279||47281<=i&&i<=47307||47309<=i&&i<=47335||47337<=i&&i<=47363||47365<=i&&i<=47391||47393<=i&&i<=47419||47421<=i&&i<=47447||47449<=i&&i<=47475||47477<=i&&i<=47503||47505<=i&&i<=47531||47533<=i&&i<=47559||47561<=i&&i<=47587||47589<=i&&i<=47615||47617<=i&&i<=47643||47645<=i&&i<=47671||47673<=i&&i<=47699||47701<=i&&i<=47727||47729<=i&&i<=47755||47757<=i&&i<=47783||47785<=i&&i<=47811||47813<=i&&i<=47839||47841<=i&&i<=47867||47869<=i&&i<=47895||47897<=i&&i<=47923||47925<=i&&i<=47951||47953<=i&&i<=47979||47981<=i&&i<=48007||48009<=i&&i<=48035||48037<=i&&i<=48063||48065<=i&&i<=48091||48093<=i&&i<=48119||48121<=i&&i<=48147||48149<=i&&i<=48175||48177<=i&&i<=48203||48205<=i&&i<=48231||48233<=i&&i<=48259||48261<=i&&i<=48287||48289<=i&&i<=48315||48317<=i&&i<=48343||48345<=i&&i<=48371||48373<=i&&i<=48399||48401<=i&&i<=48427||48429<=i&&i<=48455||48457<=i&&i<=48483||48485<=i&&i<=48511||48513<=i&&i<=48539||48541<=i&&i<=48567||48569<=i&&i<=48595||48597<=i&&i<=48623||48625<=i&&i<=48651||48653<=i&&i<=48679||48681<=i&&i<=48707||48709<=i&&i<=48735||48737<=i&&i<=48763||48765<=i&&i<=48791||48793<=i&&i<=48819||48821<=i&&i<=48847||48849<=i&&i<=48875||48877<=i&&i<=48903||48905<=i&&i<=48931||48933<=i&&i<=48959||48961<=i&&i<=48987||48989<=i&&i<=49015||49017<=i&&i<=49043||49045<=i&&i<=49071||49073<=i&&i<=49099||49101<=i&&i<=49127||49129<=i&&i<=49155||49157<=i&&i<=49183||49185<=i&&i<=49211||49213<=i&&i<=49239||49241<=i&&i<=49267||49269<=i&&i<=49295||49297<=i&&i<=49323||49325<=i&&i<=49351||49353<=i&&i<=49379||49381<=i&&i<=49407||49409<=i&&i<=49435||49437<=i&&i<=49463||49465<=i&&i<=49491||49493<=i&&i<=49519||49521<=i&&i<=49547||49549<=i&&i<=49575||49577<=i&&i<=49603||49605<=i&&i<=49631||49633<=i&&i<=49659||49661<=i&&i<=49687||49689<=i&&i<=49715||49717<=i&&i<=49743||49745<=i&&i<=49771||49773<=i&&i<=49799||49801<=i&&i<=49827||49829<=i&&i<=49855||49857<=i&&i<=49883||49885<=i&&i<=49911||49913<=i&&i<=49939||49941<=i&&i<=49967||49969<=i&&i<=49995||49997<=i&&i<=50023||50025<=i&&i<=50051||50053<=i&&i<=50079||50081<=i&&i<=50107||50109<=i&&i<=50135||50137<=i&&i<=50163||50165<=i&&i<=50191||50193<=i&&i<=50219||50221<=i&&i<=50247||50249<=i&&i<=50275||50277<=i&&i<=50303||50305<=i&&i<=50331||50333<=i&&i<=50359||50361<=i&&i<=50387||50389<=i&&i<=50415||50417<=i&&i<=50443||50445<=i&&i<=50471||50473<=i&&i<=50499||50501<=i&&i<=50527||50529<=i&&i<=50555||50557<=i&&i<=50583||50585<=i&&i<=50611||50613<=i&&i<=50639||50641<=i&&i<=50667||50669<=i&&i<=50695||50697<=i&&i<=50723||50725<=i&&i<=50751||50753<=i&&i<=50779||50781<=i&&i<=50807||50809<=i&&i<=50835||50837<=i&&i<=50863||50865<=i&&i<=50891||50893<=i&&i<=50919||50921<=i&&i<=50947||50949<=i&&i<=50975||50977<=i&&i<=51003||51005<=i&&i<=51031||51033<=i&&i<=51059||51061<=i&&i<=51087||51089<=i&&i<=51115||51117<=i&&i<=51143||51145<=i&&i<=51171||51173<=i&&i<=51199||51201<=i&&i<=51227||51229<=i&&i<=51255||51257<=i&&i<=51283||51285<=i&&i<=51311||51313<=i&&i<=51339||51341<=i&&i<=51367||51369<=i&&i<=51395||51397<=i&&i<=51423||51425<=i&&i<=51451||51453<=i&&i<=51479||51481<=i&&i<=51507||51509<=i&&i<=51535||51537<=i&&i<=51563||51565<=i&&i<=51591||51593<=i&&i<=51619||51621<=i&&i<=51647||51649<=i&&i<=51675||51677<=i&&i<=51703||51705<=i&&i<=51731||51733<=i&&i<=51759||51761<=i&&i<=51787||51789<=i&&i<=51815||51817<=i&&i<=51843||51845<=i&&i<=51871||51873<=i&&i<=51899||51901<=i&&i<=51927||51929<=i&&i<=51955||51957<=i&&i<=51983||51985<=i&&i<=52011||52013<=i&&i<=52039||52041<=i&&i<=52067||52069<=i&&i<=52095||52097<=i&&i<=52123||52125<=i&&i<=52151||52153<=i&&i<=52179||52181<=i&&i<=52207||52209<=i&&i<=52235||52237<=i&&i<=52263||52265<=i&&i<=52291||52293<=i&&i<=52319||52321<=i&&i<=52347||52349<=i&&i<=52375||52377<=i&&i<=52403||52405<=i&&i<=52431||52433<=i&&i<=52459||52461<=i&&i<=52487||52489<=i&&i<=52515||52517<=i&&i<=52543||52545<=i&&i<=52571||52573<=i&&i<=52599||52601<=i&&i<=52627||52629<=i&&i<=52655||52657<=i&&i<=52683||52685<=i&&i<=52711||52713<=i&&i<=52739||52741<=i&&i<=52767||52769<=i&&i<=52795||52797<=i&&i<=52823||52825<=i&&i<=52851||52853<=i&&i<=52879||52881<=i&&i<=52907||52909<=i&&i<=52935||52937<=i&&i<=52963||52965<=i&&i<=52991||52993<=i&&i<=53019||53021<=i&&i<=53047||53049<=i&&i<=53075||53077<=i&&i<=53103||53105<=i&&i<=53131||53133<=i&&i<=53159||53161<=i&&i<=53187||53189<=i&&i<=53215||53217<=i&&i<=53243||53245<=i&&i<=53271||53273<=i&&i<=53299||53301<=i&&i<=53327||53329<=i&&i<=53355||53357<=i&&i<=53383||53385<=i&&i<=53411||53413<=i&&i<=53439||53441<=i&&i<=53467||53469<=i&&i<=53495||53497<=i&&i<=53523||53525<=i&&i<=53551||53553<=i&&i<=53579||53581<=i&&i<=53607||53609<=i&&i<=53635||53637<=i&&i<=53663||53665<=i&&i<=53691||53693<=i&&i<=53719||53721<=i&&i<=53747||53749<=i&&i<=53775||53777<=i&&i<=53803||53805<=i&&i<=53831||53833<=i&&i<=53859||53861<=i&&i<=53887||53889<=i&&i<=53915||53917<=i&&i<=53943||53945<=i&&i<=53971||53973<=i&&i<=53999||54001<=i&&i<=54027||54029<=i&&i<=54055||54057<=i&&i<=54083||54085<=i&&i<=54111||54113<=i&&i<=54139||54141<=i&&i<=54167||54169<=i&&i<=54195||54197<=i&&i<=54223||54225<=i&&i<=54251||54253<=i&&i<=54279||54281<=i&&i<=54307||54309<=i&&i<=54335||54337<=i&&i<=54363||54365<=i&&i<=54391||54393<=i&&i<=54419||54421<=i&&i<=54447||54449<=i&&i<=54475||54477<=i&&i<=54503||54505<=i&&i<=54531||54533<=i&&i<=54559||54561<=i&&i<=54587||54589<=i&&i<=54615||54617<=i&&i<=54643||54645<=i&&i<=54671||54673<=i&&i<=54699||54701<=i&&i<=54727||54729<=i&&i<=54755||54757<=i&&i<=54783||54785<=i&&i<=54811||54813<=i&&i<=54839||54841<=i&&i<=54867||54869<=i&&i<=54895||54897<=i&&i<=54923||54925<=i&&i<=54951||54953<=i&&i<=54979||54981<=i&&i<=55007||55009<=i&&i<=55035||55037<=i&&i<=55063||55065<=i&&i<=55091||55093<=i&&i<=55119||55121<=i&&i<=55147||55149<=i&&i<=55175||55177<=i&&i<=55203?10:9757==i||9977==i||9994<=i&&i<=9997||127877==i||127938<=i&&i<=127940||127943==i||127946<=i&&i<=127948||128066<=i&&i<=128067||128070<=i&&i<=128080||128110==i||128112<=i&&i<=128120||128124==i||128129<=i&&i<=128131||128133<=i&&i<=128135||128170==i||128372<=i&&i<=128373||128378==i||128400==i||128405<=i&&i<=128406||128581<=i&&i<=128583||128587<=i&&i<=128591||128675==i||128692<=i&&i<=128694||128704==i||128716==i||129304<=i&&i<=129308||129310<=i&&i<=129311||129318==i||129328<=i&&i<=129337||129341<=i&&i<=129342||129489<=i&&i<=129501?A:127995<=i&&i<=127999?14:8205==i?15:9792==i||9794==i||9877<=i&&i<=9878||9992==i||10084==i||127752==i||127806==i||127859==i||127891==i||127908==i||127912==i||127979==i||127981==i||128139==i||128187<=i&&i<=128188||128295==i||128300==i||128488==i||128640==i||128658==i?n:128102<=i&&i<=128105?o:11}return this.nextBreak=function(e,t){if(void 0===t&&(t=0),t<0)return 0;if(t>=e.length-1)return e.length;for(var r,A,n=a(i(e,t)),o=[],c=t+1;c{"use strict";e.exports=(e,t=process.argv)=>{const r=e.startsWith("-")?"":1===e.length?"-":"--",A=t.indexOf(r+e),n=t.indexOf("--");return-1!==A&&(-1===n||A{"use strict";const t=[200,203,204,206,300,301,404,405,410,414,501],r=[200,203,204,300,301,302,303,307,308,404,405,410,414,501],A={date:!0,connection:!0,"keep-alive":!0,"proxy-authenticate":!0,"proxy-authorization":!0,te:!0,trailer:!0,"transfer-encoding":!0,upgrade:!0},n={"content-length":!0,"content-encoding":!0,"transfer-encoding":!0,"content-range":!0};function o(e){const t={};if(!e)return t;const r=e.trim().split(/\s*,\s*/);for(const e of r){const[r,A]=e.split(/\s*=\s*/,2);t[r]=void 0===A||A.replace(/^"|"$/g,"")}return t}function i(e){let t=[];for(const r in e){const A=e[r];t.push(!0===A?r:r+"="+A)}if(t.length)return t.join(", ")}e.exports=class{constructor(e,t,{shared:r,cacheHeuristic:A,immutableMinTimeToLive:n,ignoreCargoCult:s,trustServerDate:a,_fromObject:c}={}){if(c)this._fromObject(c);else{if(!t||!t.headers)throw Error("Response headers missing");this._assertRequestHasHeaders(e),this._responseTime=this.now(),this._isShared=!1!==r,this._trustServerDate=void 0===a||a,this._cacheHeuristic=void 0!==A?A:.1,this._immutableMinTtl=void 0!==n?n:864e5,this._status="status"in t?t.status:200,this._resHeaders=t.headers,this._rescc=o(t.headers["cache-control"]),this._method="method"in e?e.method:"GET",this._url=e.url,this._host=e.headers.host,this._noAuthorization=!e.headers.authorization,this._reqHeaders=t.headers.vary?e.headers:null,this._reqcc=o(e.headers["cache-control"]),s&&"pre-check"in this._rescc&&"post-check"in this._rescc&&(delete this._rescc["pre-check"],delete this._rescc["post-check"],delete this._rescc["no-cache"],delete this._rescc["no-store"],delete this._rescc["must-revalidate"],this._resHeaders=Object.assign({},this._resHeaders,{"cache-control":i(this._rescc)}),delete this._resHeaders.expires,delete this._resHeaders.pragma),!t.headers["cache-control"]&&/no-cache/.test(t.headers.pragma)&&(this._rescc["no-cache"]=!0)}}now(){return Date.now()}storable(){return!(this._reqcc["no-store"]||!("GET"===this._method||"HEAD"===this._method||"POST"===this._method&&this._hasExplicitExpiration())||-1===r.indexOf(this._status)||this._rescc["no-store"]||this._isShared&&this._rescc.private||this._isShared&&!this._noAuthorization&&!this._allowsStoringAuthenticated()||!(this._resHeaders.expires||this._rescc.public||this._rescc["max-age"]||this._rescc["s-maxage"]||-1!==t.indexOf(this._status)))}_hasExplicitExpiration(){return this._isShared&&this._rescc["s-maxage"]||this._rescc["max-age"]||this._resHeaders.expires}_assertRequestHasHeaders(e){if(!e||!e.headers)throw Error("Request headers missing")}satisfiesWithoutRevalidation(e){this._assertRequestHasHeaders(e);const t=o(e.headers["cache-control"]);if(t["no-cache"]||/no-cache/.test(e.headers.pragma))return!1;if(t["max-age"]&&this.age()>t["max-age"])return!1;if(t["min-fresh"]&&this.timeToLive()<1e3*t["min-fresh"])return!1;if(this.stale()){if(!(t["max-stale"]&&!this._rescc["must-revalidate"]&&(!0===t["max-stale"]||t["max-stale"]>this.age()-this.maxAge())))return!1}return this._requestMatches(e,!1)}_requestMatches(e,t){return(!this._url||this._url===e.url)&&this._host===e.headers.host&&(!e.method||this._method===e.method||t&&"HEAD"===e.method)&&this._varyMatches(e)}_allowsStoringAuthenticated(){return this._rescc["must-revalidate"]||this._rescc.public||this._rescc["s-maxage"]}_varyMatches(e){if(!this._resHeaders.vary)return!0;if("*"===this._resHeaders.vary)return!1;const t=this._resHeaders.vary.trim().toLowerCase().split(/\s*,\s*/);for(const r of t)if(e.headers[r]!==this._reqHeaders[r])return!1;return!0}_copyWithoutHopByHopHeaders(e){const t={};for(const r in e)A[r]||(t[r]=e[r]);if(e.connection){const r=e.connection.trim().split(/\s*,\s*/);for(const e of r)delete t[e]}if(t.warning){const e=t.warning.split(/,/).filter(e=>!/^\s*1[0-9][0-9]/.test(e));e.length?t.warning=e.join(",").trim():delete t.warning}return t}responseHeaders(){const e=this._copyWithoutHopByHopHeaders(this._resHeaders),t=this.age();return t>86400&&!this._hasExplicitExpiration()&&this.maxAge()>86400&&(e.warning=(e.warning?e.warning+", ":"")+'113 - "rfc7234 5.5.4"'),e.age=""+Math.round(t),e.date=new Date(this.now()).toUTCString(),e}date(){return this._trustServerDate?this._serverDate():this._responseTime}_serverDate(){const e=Date.parse(this._resHeaders.date);if(isFinite(e)){const t=288e5;if(Math.abs(this._responseTime-e)e&&(e=t)}return e+(this.now()-this._responseTime)/1e3}_ageValue(){const e=parseInt(this._resHeaders.age);return isFinite(e)?e:0}maxAge(){if(!this.storable()||this._rescc["no-cache"])return 0;if(this._isShared&&this._resHeaders["set-cookie"]&&!this._rescc.public&&!this._rescc.immutable)return 0;if("*"===this._resHeaders.vary)return 0;if(this._isShared){if(this._rescc["proxy-revalidate"])return 0;if(this._rescc["s-maxage"])return parseInt(this._rescc["s-maxage"],10)}if(this._rescc["max-age"])return parseInt(this._rescc["max-age"],10);const e=this._rescc.immutable?this._immutableMinTtl:0,t=this._serverDate();if(this._resHeaders.expires){const r=Date.parse(this._resHeaders.expires);return Number.isNaN(r)||rr)return Math.max(e,(t-r)/1e3*this._cacheHeuristic)}return e}timeToLive(){return 1e3*Math.max(0,this.maxAge()-this.age())}stale(){return this.maxAge()<=this.age()}static fromObject(e){return new this(void 0,void 0,{_fromObject:e})}_fromObject(e){if(this._responseTime)throw Error("Reinitialized");if(!e||1!==e.v)throw Error("Invalid serialization");this._responseTime=e.t,this._isShared=e.sh,this._cacheHeuristic=e.ch,this._immutableMinTtl=void 0!==e.imm?e.imm:864e5,this._status=e.st,this._resHeaders=e.resh,this._rescc=e.rescc,this._method=e.m,this._url=e.u,this._host=e.h,this._noAuthorization=e.a,this._reqHeaders=e.reqh,this._reqcc=e.reqcc}toObject(){return{v:1,t:this._responseTime,sh:this._isShared,ch:this._cacheHeuristic,imm:this._immutableMinTtl,st:this._status,resh:this._resHeaders,rescc:this._rescc,m:this._method,u:this._url,h:this._host,a:this._noAuthorization,reqh:this._reqHeaders,reqcc:this._reqcc}}revalidationHeaders(e){this._assertRequestHasHeaders(e);const t=this._copyWithoutHopByHopHeaders(e.headers);if(delete t["if-range"],!this._requestMatches(e,!0)||!this.storable())return delete t["if-none-match"],delete t["if-modified-since"],t;this._resHeaders.etag&&(t["if-none-match"]=t["if-none-match"]?`${t["if-none-match"]}, ${this._resHeaders.etag}`:this._resHeaders.etag);if(t["accept-ranges"]||t["if-match"]||t["if-unmodified-since"]||this._method&&"GET"!=this._method){if(delete t["if-modified-since"],t["if-none-match"]){const e=t["if-none-match"].split(/,/).filter(e=>!/^\s*W\//.test(e));e.length?t["if-none-match"]=e.join(",").trim():delete t["if-none-match"]}}else this._resHeaders["last-modified"]&&!t["if-modified-since"]&&(t["if-modified-since"]=this._resHeaders["last-modified"]);return t}revalidatedPolicy(e,t){if(this._assertRequestHasHeaders(e),!t||!t.headers)throw Error("Response headers missing");let r=!1;if(void 0!==t.status&&304!=t.status?r=!1:t.headers.etag&&!/^\s*W\//.test(t.headers.etag)?r=this._resHeaders.etag&&this._resHeaders.etag.replace(/^\s*W\//,"")===t.headers.etag:this._resHeaders.etag&&t.headers.etag?r=this._resHeaders.etag.replace(/^\s*W\//,"")===t.headers.etag.replace(/^\s*W\//,""):this._resHeaders["last-modified"]?r=this._resHeaders["last-modified"]===t.headers["last-modified"]:this._resHeaders.etag||this._resHeaders["last-modified"]||t.headers.etag||t.headers["last-modified"]||(r=!0),!r)return{policy:new this.constructor(e,t),modified:304!=t.status,matches:!1};const A={};for(const e in this._resHeaders)A[e]=e in t.headers&&!n[e]?t.headers[e]:this._resHeaders[e];const o=Object.assign({},t,{status:this._status,method:this._method,headers:A});return{policy:new this.constructor(e,o,{shared:this._isShared,cacheHeuristic:this._cacheHeuristic,immutableMinTimeToLive:this._immutableMinTtl,trustServerDate:this._trustServerDate}),modified:!1,matches:!0}}}},94935:(e,t,r)=>{"use strict";const A=r(28614),n=r(4016),o=r(97565),i=r(49601),s=Symbol("currentStreamsCount"),a=Symbol("request"),c=Symbol("cachedOriginSet"),g=Symbol("gracefullyClosing"),l=["maxDeflateDynamicTableSize","maxSessionMemory","maxHeaderListPairs","maxOutstandingPings","maxReservedRemoteStreams","maxSendHeaderBlockLength","paddingStrategy","localAddress","path","rejectUnauthorized","minDHSize","ca","cert","clientCertEngine","ciphers","key","pfx","servername","minVersion","maxVersion","secureProtocol","crl","honorCipherOrder","ecdhCurve","dhparam","secureOptions","sessionIdContext"],u=(e,t)=>e.remoteSettings.maxConcurrentStreams>t.remoteSettings.maxConcurrentStreams,h=(e,t)=>{for(const r of e)r[c].lengtht[c].includes(e))&&r[s]+t[s]<=t.remoteSettings.maxConcurrentStreams&&d(r)},p=({agent:e,isFree:t})=>{const r={};for(const A in e.sessions){const n=e.sessions[A].filter(e=>{const r=e[C.kCurrentStreamsCount]{e[g]=!0,0===e[s]&&e.close()};class C extends A{constructor({timeout:e=6e4,maxSessions:t=1/0,maxFreeSessions:r=10,maxCachedTlsSessions:A=100}={}){super(),this.sessions={},this.queue={},this.timeout=e,this.maxSessions=t,this.maxFreeSessions=r,this._freeSessionsCount=0,this._sessionsCount=0,this.settings={enablePush:!1},this.tlsSessionCache=new i({maxSize:A})}static normalizeOrigin(e,t){return"string"==typeof e&&(e=new URL(e)),t&&e.hostname!==t&&(e.hostname=t),e.origin}normalizeOptions(e){let t="";if(e)for(const r of l)e[r]&&(t+=":"+e[r]);return t}_tryToCreateNewSession(e,t){if(!(e in this.queue)||!(t in this.queue[e]))return;const r=this.queue[e][t];this._sessionsCount{Array.isArray(r)?(r=[...r],A()):r=[{resolve:A,reject:n}];const i=this.normalizeOptions(t),l=C.normalizeOrigin(e,t&&t.servername);if(void 0===l){for(const{reject:e}of r)e(new TypeError("The `origin` argument needs to be a string or an URL object"));return}if(i in this.sessions){const e=this.sessions[i];let t,A=-1,n=-1;for(const r of e){const e=r.remoteSettings.maxConcurrentStreams;if(e=e||r[g]||r.destroyed)continue;t||(A=e),o>n&&(t=r,n=o)}}if(t){if(1!==r.length){for(const{reject:e}of r){e(new Error(`Expected the length of listeners to be 1, got ${r.length}.\nPlease report this to https://github.com/szmarczak/http2-wrapper/`))}return}return void r[0].resolve(t)}}if(i in this.queue){if(l in this.queue[i])return this.queue[i][l].listeners.push(...r),void this._tryToCreateNewSession(i,l)}else this.queue[i]={};const p=()=>{i in this.queue&&this.queue[i][l]===f&&(delete this.queue[i][l],0===Object.keys(this.queue[i]).length&&delete this.queue[i])},f=()=>{const A=`${l}:${i}`;let n=!1;try{const C=o.connect(e,{createConnection:this.createConnection,settings:this.settings,session:this.tlsSessionCache.get(A),...t});C[s]=0,C[g]=!1;const I=()=>C[s]{this.tlsSessionCache.set(A,e)}),C.once("error",e=>{for(const{reject:t}of r)t(e);this.tlsSessionCache.delete(A)}),C.setTimeout(this.timeout,()=>{C.destroy()}),C.once("close",()=>{if(n){E&&this._freeSessionsCount--,this._sessionsCount--;const e=this.sessions[i];e.splice(e.indexOf(C),1),0===e.length&&delete this.sessions[i]}else{const e=new Error("Session closed without receiving a SETTINGS frame");e.code="HTTP2WRAPPER_NOSETTINGS";for(const{reject:t}of r)t(e);p()}this._tryToCreateNewSession(i,l)});const B=()=>{if(i in this.queue&&I())for(const e of C[c])if(e in this.queue[i]){const{listeners:t}=this.queue[i][e];for(;0!==t.length&&I();)t.shift().resolve(C);const r=this.queue[i];if(0===r[e].listeners.length&&(delete r[e],0===Object.keys(r).length)){delete this.queue[i];break}if(!I())break}};C.on("origin",()=>{C[c]=C.originSet,I()&&(B(),h(this.sessions[i],C))}),C.once("remoteSettings",()=>{if(C.ref(),C.unref(),this._sessionsCount++,f.destroyed){const e=new Error("Agent has been destroyed");for(const t of r)t.reject(e);C.destroy()}else{C[c]=C.originSet;{const e=this.sessions;if(i in e){const t=e[i];t.splice(((e,t,r)=>{let A=0,n=e.length;for(;A>>1;r(e[o],t)?A=o+1:n=o}return A})(t,C,u),0,C)}else e[i]=[C]}this._freeSessionsCount+=1,n=!0,this.emit("session",C),B(),p(),0===C[s]&&this._freeSessionsCount>this.maxFreeSessions&&C.close(),0!==r.length&&(this.getSession(l,t,r),r.length=0),C.on("remoteSettings",()=>{B(),h(this.sessions[i],C)})}}),C[a]=C.request,C.request=(e,t)=>{if(C[g])throw new Error("The session is gracefully closing. No new streams are allowed.");const r=C[a](e,t);return C.ref(),++C[s],C[s]===C.remoteSettings.maxConcurrentStreams&&this._freeSessionsCount--,r.once("close",()=>{if(E=I(),--C[s],!C.destroyed&&!C.closed&&(((e,t)=>{for(const r of e)t[c].lengthr[c].includes(e))&&t[s]+r[s]<=r.remoteSettings.maxConcurrentStreams&&d(t)})(this.sessions[i],C),I()&&!C.closed)){E||(this._freeSessionsCount++,E=!0);const e=0===C[s];e&&C.unref(),e&&(this._freeSessionsCount>this.maxFreeSessions||C[g])?C.close():(h(this.sessions[i],C),B())}}),r}}catch(e){for(const t of r)t.reject(e);p()}};f.listeners=r,f.completed=!1,f.destroyed=!1,this.queue[i][l]=f,this._tryToCreateNewSession(i,l)})}request(e,t,r,A){return new Promise((n,o)=>{this.getSession(e,t,[{reject:o,resolve:e=>{try{n(e.request(r,A))}catch(e){o(e)}}}])})}createConnection(e,t){return C.connect(e,t)}static connect(e,t){t.ALPNProtocols=["h2"];const r=e.port||443,A=e.hostname||e.host;return void 0===t.servername&&(t.servername=A),n.connect(r,A,t)}closeFreeSessions(){for(const e of Object.values(this.sessions))for(const t of e)0===t[s]&&t.close()}destroy(e){for(const t of Object.values(this.sessions))for(const r of t)r.destroy(e);for(const e of Object.values(this.queue))for(const t of Object.values(e))t.destroyed=!0;this.queue={}}get freeSessions(){return p({agent:this,isFree:!0})}get busySessions(){return p({agent:this,isFree:!1})}}C.kCurrentStreamsCount=s,C.kGracefullyClosing=g,e.exports={Agent:C,globalAgent:new C}},2398:(e,t,r)=>{"use strict";const A=r(98605),n=r(57211),o=r(19476),i=r(49601),s=r(33134),a=r(5209),c=r(50075),g=new i({maxSize:100}),l=new Map,u=(e,t,r)=>{t._httpMessage={shouldKeepAlive:!0};const A=()=>{e.emit("free",t,r)};t.on("free",A);const n=()=>{e.removeSocket(t,r)};t.on("close",n);const o=()=>{e.removeSocket(t,r),t.off("close",n),t.off("free",A),t.off("agentRemove",o)};t.on("agentRemove",o),e.emit("free",t,r)};e.exports=async(e,t,r)=>{if(("string"==typeof e||e instanceof URL)&&(e=c(new URL(e))),"function"==typeof t&&(r=t,t=void 0),t={ALPNProtocols:["h2","http/1.1"],...e,...t,resolveSocket:!0},!Array.isArray(t.ALPNProtocols)||0===t.ALPNProtocols.length)throw new Error("The `ALPNProtocols` option must be an Array with at least one entry");t.protocol=t.protocol||"https:";const i="https:"===t.protocol;t.host=t.hostname||t.host||"localhost",t.session=t.tlsSession,t.servername=t.servername||a(t),t.port=t.port||(i?443:80),t._defaultAgent=i?n.globalAgent:A.globalAgent;const h=t.agent;if(h){if(h.addRequest)throw new Error("The `options.agent` object can contain only `http`, `https` or `http2` properties");t.agent=h[i?"https":"http"]}if(i){if("h2"===await(async e=>{const t=`${e.host}:${e.port}:${e.ALPNProtocols.sort()}`;if(!g.has(t)){if(l.has(t)){return(await l.get(t)).alpnProtocol}const{path:r,agent:A}=e;e.path=e.socketPath;const i=o(e);l.set(t,i);try{const{socket:o,alpnProtocol:s}=await i;if(g.set(t,s),e.path=r,"h2"===s)o.destroy();else{const{globalAgent:t}=n,r=n.Agent.prototype.createConnection;A?A.createConnection===r?u(A,o,e):o.destroy():t.createConnection===r?u(t,o,e):o.destroy()}return l.delete(t),s}catch(e){throw l.delete(t),e}}return g.get(t)})(t))return h&&(t.agent=h.http2),new s(t,r)}return A.request(t,r)},e.exports.protocolCache=g},33134:(e,t,r)=>{"use strict";const A=r(97565),{Writable:n}=r(92413),{Agent:o,globalAgent:i}=r(94935),s=r(53433),a=r(50075),c=r(66192),g=r(50978),{ERR_INVALID_ARG_TYPE:l,ERR_INVALID_PROTOCOL:u,ERR_HTTP_HEADERS_SENT:h,ERR_INVALID_HTTP_TOKEN:p,ERR_HTTP_INVALID_HEADER_VALUE:d,ERR_INVALID_CHAR:C}=r(64080),{HTTP2_HEADER_STATUS:f,HTTP2_HEADER_METHOD:I,HTTP2_HEADER_PATH:E,HTTP2_METHOD_CONNECT:B}=A.constants,y=Symbol("headers"),m=Symbol("origin"),w=Symbol("session"),Q=Symbol("options"),D=Symbol("flushedHeaders"),b=Symbol("jobs"),v=/^[\^`\-\w!#$%&*+.|~]+$/,S=/[^\t\u0020-\u007E\u0080-\u00FF]/;e.exports=class extends n{constructor(e,t,r){super({autoDestroy:!1});const A="string"==typeof e||e instanceof URL;if(A&&(e=a(e instanceof URL?e:new URL(e))),"function"==typeof t||void 0===t?(r=t,t=A?e:{...e}):t={...e,...t},t.h2session)this[w]=t.h2session;else if(!1===t.agent)this.agent=new o({maxFreeSessions:0});else if(void 0===t.agent||null===t.agent)"function"==typeof t.createConnection?(this.agent=new o({maxFreeSessions:0}),this.agent.createConnection=t.createConnection):this.agent=i;else{if("function"!=typeof t.agent.request)throw new l("options.agent",["Agent-like Object","undefined","false"],t.agent);this.agent=t.agent}if(t.protocol&&"https:"!==t.protocol)throw new u(t.protocol,"https:");const n=t.port||t.defaultPort||this.agent&&this.agent.defaultPort||443,s=t.hostname||t.host||"localhost";delete t.hostname,delete t.host,delete t.port;const{timeout:c}=t;if(t.timeout=void 0,this[y]=Object.create(null),this[b]=[],this.socket=null,this.connection=null,this.method=t.method||"GET",this.path=t.path,this.res=null,this.aborted=!1,this.reusedSocket=!1,t.headers)for(const[e,r]of Object.entries(t.headers))this.setHeader(e,r);t.auth&&!("authorization"in this[y])&&(this[y].authorization="Basic "+Buffer.from(t.auth).toString("base64")),t.session=t.tlsSession,t.path=t.socketPath,this[Q]=t,443===n?(this[m]="https://"+s,":authority"in this[y]||(this[y][":authority"]=s)):(this[m]=`https://${s}:${n}`,":authority"in this[y]||(this[y][":authority"]=`${s}:${n}`)),c&&this.setTimeout(c),r&&this.once("response",r),this[D]=!1}get method(){return this[y][I]}set method(e){e&&(this[y][I]=e.toUpperCase())}get path(){return this[y][E]}set path(e){e&&(this[y][E]=e)}get _mustNotHaveABody(){return"GET"===this.method||"HEAD"===this.method||"DELETE"===this.method}_write(e,t,r){if(this._mustNotHaveABody)return void r(new Error("The GET, HEAD and DELETE methods must NOT have a body"));this.flushHeaders();const A=()=>this._request.write(e,t,r);this._request?A():this[b].push(A)}_final(e){if(this.destroyed)return;this.flushHeaders();const t=()=>{this._mustNotHaveABody?e():this._request.end(e)};this._request?t():this[b].push(t)}abort(){this.res&&this.res.complete||(this.aborted||process.nextTick(()=>this.emit("abort")),this.aborted=!0,this.destroy())}_destroy(e,t){this.res&&this.res._dump(),this._request&&this._request.destroy(),t(e)}async flushHeaders(){if(this[D]||this.destroyed)return;this[D]=!0;const e=this.method===B,t=t=>{if(this._request=t,this.destroyed)return void t.destroy();e||c(t,this,["timeout","continue","close","error"]);const r=e=>(...t)=>{this.writable||this.destroyed?this.once("finish",()=>{e(...t)}):e(...t)};t.once("response",r((r,A,n)=>{const o=new s(this.socket,t.readableHighWaterMark);this.res=o,o.req=this,o.statusCode=r[f],o.headers=r,o.rawHeaders=n,o.once("end",()=>{this.aborted?(o.aborted=!0,o.emit("aborted")):(o.complete=!0,o.socket=null,o.connection=null)}),e?(o.upgrade=!0,this.emit("connect",o,t,Buffer.alloc(0))?this.emit("close"):t.destroy()):(t.on("data",e=>{o._dumped||o.push(e)||t.pause()}),t.once("end",()=>{o.push(null)}),this.emit("response",o)||o._dump())})),t.once("headers",r(e=>this.emit("information",{statusCode:e[f]}))),t.once("trailers",r((e,t,r)=>{const{res:A}=this;A.trailers=e,A.rawTrailers=r}));const{socket:A}=t.session;this.socket=A,this.connection=A;for(const e of this[b])e();this.emit("socket",this.socket)};if(this[w])try{t(this[w].request(this[y]))}catch(e){this.emit("error",e)}else{this.reusedSocket=!0;try{t(await this.agent.request(this[m],this[Q],this[y]))}catch(e){this.emit("error",e)}}}getHeader(e){if("string"!=typeof e)throw new l("name","string",e);return this[y][e.toLowerCase()]}get headersSent(){return this[D]}removeHeader(e){if("string"!=typeof e)throw new l("name","string",e);if(this.headersSent)throw new h("remove");delete this[y][e.toLowerCase()]}setHeader(e,t){if(this.headersSent)throw new h("set");if("string"!=typeof e||!v.test(e)&&!g(e))throw new p("Header name",e);if(void 0===t)throw new d(t,e);if(S.test(t))throw new C("header content",e);this[y][e.toLowerCase()]=t}setNoDelay(){}setSocketKeepAlive(){}setTimeout(e,t){const r=()=>this._request.setTimeout(e,t);return this._request?r():this[b].push(r),this}get maxHeadersCount(){if(!this.destroyed&&this._request)return this._request.session.localSettings.maxHeaderListSize}set maxHeadersCount(e){}}},53433:(e,t,r)=>{"use strict";const{Readable:A}=r(92413);e.exports=class extends A{constructor(e,t){super({highWaterMark:t,autoDestroy:!1}),this.statusCode=null,this.statusMessage="",this.httpVersion="2.0",this.httpVersionMajor=2,this.httpVersionMinor=0,this.headers={},this.trailers={},this.req=null,this.aborted=!1,this.complete=!1,this.upgrade=null,this.rawHeaders=[],this.rawTrailers=[],this.socket=e,this.connection=e,this._dumped=!1}_destroy(e){this.req._request.destroy(e)}setTimeout(e,t){return this.req.setTimeout(e,t),this}_dump(){this._dumped||(this._dumped=!0,this.removeAllListeners("data"),this.resume())}_read(){this.req&&this.req._request.resume()}}},92353:(e,t,r)=>{"use strict";const A=r(97565),n=r(94935),o=r(33134),i=r(53433),s=r(2398);e.exports={...A,ClientRequest:o,IncomingMessage:i,...n,request:(e,t,r)=>new o(e,t,r),get:(e,t,r)=>{const A=new o(e,t,r);return A.end(),A},auto:s}},5209:(e,t,r)=>{"use strict";const A=r(11631);e.exports=e=>{let t=e.host;const r=e.headers&&e.headers.host;if(r)if(r.startsWith("[")){t=-1===r.indexOf("]")?r:r.slice(1,-1)}else t=r.split(":",1)[0];return A.isIP(t)?"":t}},64080:e=>{"use strict";const t=(t,r,A)=>{e.exports[r]=class extends t{constructor(...e){super("string"==typeof A?A:A(e)),this.name=`${super.name} [${r}]`,this.code=r}}};t(TypeError,"ERR_INVALID_ARG_TYPE",e=>{const t=e[0].includes(".")?"property":"argument";let r=e[1];const A=Array.isArray(r);return A&&(r=`${r.slice(0,-1).join(", ")} or ${r.slice(-1)}`),`The "${e[0]}" ${t} must be ${A?"one of":"of"} type ${r}. Received ${typeof e[2]}`}),t(TypeError,"ERR_INVALID_PROTOCOL",e=>`Protocol "${e[0]}" not supported. Expected "${e[1]}"`),t(Error,"ERR_HTTP_HEADERS_SENT",e=>`Cannot ${e[0]} headers after they are sent to the client`),t(TypeError,"ERR_INVALID_HTTP_TOKEN",e=>`${e[0]} must be a valid HTTP token [${e[1]}]`),t(TypeError,"ERR_HTTP_INVALID_HEADER_VALUE",e=>`Invalid value "${e[0]} for header "${e[1]}"`),t(TypeError,"ERR_INVALID_CHAR",e=>`Invalid character in ${e[0]} [${e[1]}]`)},50978:e=>{"use strict";e.exports=e=>{switch(e){case":method":case":scheme":case":authority":case":path":return!0;default:return!1}}},66192:e=>{"use strict";e.exports=(e,t,r)=>{for(const A of r)e.on(A,(...e)=>t.emit(A,...e))}},50075:e=>{"use strict";e.exports=e=>{const t={protocol:e.protocol,hostname:"string"==typeof e.hostname&&e.hostname.startsWith("[")?e.hostname.slice(1,-1):e.hostname,host:e.host,hash:e.hash,search:e.search,pathname:e.pathname,href:e.href,path:`${e.pathname||""}${e.search||""}`};return"string"==typeof e.port&&0!==e.port.length&&(t.port=Number(e.port)),(e.username||e.password)&&(t.auth=`${e.username||""}:${e.password||""}`),t}},46458:e=>{function t(e){return Array.isArray(e)?e:[e]}const r=/^\s+$/,A=/^\\!/,n=/^\\#/,o=/\r?\n/g,i=/^\.*\/|^\.+$/,s="undefined"!=typeof Symbol?Symbol.for("node-ignore"):"node-ignore",a=/([0-z])-([0-z])/g,c=[[/\\?\s+$/,e=>0===e.indexOf("\\")?" ":""],[/\\\s/g,()=>" "],[/[\\^$.|*+(){]/g,e=>"\\"+e],[/\[([^\]/]*)($|\])/g,(e,t,r)=>{return"]"===r?`[${A=t,A.replace(a,(e,t,r)=>t.charCodeAt(0)<=r.charCodeAt(0)?e:"")}]`:"\\"+e;var A}],[/(?!\\)\?/g,()=>"[^/]"],[/^\//,()=>"^"],[/\//g,()=>"\\/"],[/^\^*\\\*\\\*\\\//,()=>"^(?:.*\\/)?"],[/(?:[^*])$/,e=>/\/$/.test(e)?e+"$":e+"(?=$|\\/$)"],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?"^":"(?:^|\\/)"}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(e,t,r)=>t+6t+"[^\\/]*"],[/(\^|\\\/)?\\\*$/,(e,t)=>(t?t+"[^/]+":"[^/]*")+"(?=$|\\/$)"],[/\\\\\\/g,()=>"\\"]],g=Object.create(null),l=e=>"string"==typeof e;class u{constructor(e,t,r,A){this.origin=e,this.pattern=t,this.negative=r,this.regex=A}}const h=(e,t)=>{const r=e;let o=!1;0===e.indexOf("!")&&(o=!0,e=e.substr(1));const i=((e,t,r)=>{const A=g[e];if(A)return A;const n=c.reduce((t,r)=>t.replace(r[0],r[1].bind(e)),e);return g[e]=r?new RegExp(n,"i"):new RegExp(n)})(e=e.replace(A,"!").replace(n,"#"),0,t);return new u(r,e,o,i)},p=(e,t)=>{throw new t(e)},d=(e,t,r)=>{if(!l(e))return r(`path must be a string, but got \`${t}\``,TypeError);if(!e)return r("path must not be empty",TypeError);if(d.isNotRelative(e)){return r(`path should be a ${"`path.relative()`d"} string, but got "${t}"`,RangeError)}return!0},C=e=>i.test(e);d.isNotRelative=C,d.convert=e=>e;class f{constructor({ignorecase:e=!0}={}){var t,r,A;this._rules=[],this._ignorecase=e,t=this,r=s,A=!0,Object.defineProperty(t,r,{value:A}),this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}_addPattern(e){if(e&&e[s])return this._rules=this._rules.concat(e._rules),void(this._added=!0);if((e=>e&&l(e)&&!r.test(e)&&0!==e.indexOf("#"))(e)){const t=h(e,this._ignorecase);this._added=!0,this._rules.push(t)}}add(e){return this._added=!1,t(l(e)?(e=>e.split(o))(e):e).forEach(this._addPattern,this),this._added&&this._initCache(),this}addPattern(e){return this.add(e)}_testOne(e,t){let r=!1,A=!1;return this._rules.forEach(n=>{const{negative:o}=n;if(A===o&&r!==A||o&&!r&&!A&&!t)return;n.regex.test(e)&&(r=!o,A=o)}),{ignored:r,unignored:A}}_test(e,t,r,A){const n=e&&d.convert(e);return d(n,e,p),this._t(n,t,r,A)}_t(e,t,r,A){if(e in t)return t[e];if(A||(A=e.split("/")),A.pop(),!A.length)return t[e]=this._testOne(e,r);const n=this._t(A.join("/")+"/",t,r,A);return t[e]=n.ignored?n:this._testOne(e,r)}ignores(e){return this._test(e,this._ignoreCache,!1).ignored}createFilter(){return e=>!this.ignores(e)}filter(e){return t(e).filter(this.createFilter())}test(e){return this._test(e,this._testCache,!0)}}const I=e=>new f(e),E=()=>!1;if(I.isPathValid=e=>d(e&&d.convert(e),e,E),I.default=I,e.exports=I,"undefined"!=typeof process&&(process.env&&process.env.IGNORE_TEST_WIN32||"win32"===process.platform)){const e=e=>/^\\\\\?\\/.test(e)||/["<>|\u0000-\u001F]+/u.test(e)?e:e.replace(/\\/g,"/");d.convert=e;const t=/^[a-z]:\//i;d.isNotRelative=e=>t.test(e)||C(e)}},85870:(e,t,r)=>{try{var A=r(31669);if("function"!=typeof A.inherits)throw"";e.exports=A.inherits}catch(t){e.exports=r(48145)}},48145:e=>{"function"==typeof Object.create?e.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:e.exports=function(e,t){e.super_=t;var r=function(){};r.prototype=t.prototype,e.prototype=new r,e.prototype.constructor=e}},44486:e=>{ -/*! - * is-extglob - * - * Copyright (c) 2014-2016, Jon Schlinkert. - * Licensed under the MIT License. - */ -e.exports=function(e){if("string"!=typeof e||""===e)return!1;for(var t;t=/(\\).|([@?!+*]\(.*\))/g.exec(e);){if(t[2])return!0;e=e.slice(t.index+t[0].length)}return!1}},18193:(e,t,r)=>{ -/*! - * is-glob - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ -var A=r(44486),n={"{":"}","(":")","[":"]"},o=/\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/,i=/\\(.)|(^!|[*?{}()[\]]|\(\?)/;e.exports=function(e,t){if("string"!=typeof e||""===e)return!1;if(A(e))return!0;var r,s=o;for(t&&!1===t.strict&&(s=i);r=s.exec(e);){if(r[2])return!0;var a=r.index+r[0].length,c=r[1],g=c?n[c]:null;if(c&&g){var l=e.indexOf(g,a);-1!==l&&(a=l+1)}e=e.slice(a)}return!1}},59235:e=>{"use strict"; -/*! - * is-number - * - * Copyright (c) 2014-present, Jon Schlinkert. - * Released under the MIT License. - */e.exports=function(e){return"number"==typeof e?e-e==0:"string"==typeof e&&""!==e.trim()&&(Number.isFinite?Number.isFinite(+e):isFinite(+e))}},97369:(e,t)=>{var r,A,n,o; -/*! - * is-windows - * - * Copyright © 2015-2018, Jon Schlinkert. - * Released under the MIT License. - */o=function(){"use strict";return function(){return process&&("win32"===process.platform||/^(msys|cygwin)$/.test(process.env.OSTYPE))}},t&&"object"==typeof t?e.exports=o():(A=[],void 0===(n="function"==typeof(r=o)?r.apply(t,A):r)||(e.exports=n))},64151:(e,t,r)=>{var A;r(35747);function n(e,t,r){if("function"==typeof t&&(r=t,t={}),!r){if("function"!=typeof Promise)throw new TypeError("callback not provided");return new Promise((function(r,A){n(e,t||{},(function(e,t){e?A(e):r(t)}))}))}A(e,t||{},(function(e,A){e&&("EACCES"===e.code||t&&t.ignoreErrors)&&(e=null,A=!1),r(e,A)}))}A="win32"===process.platform||global.TESTING_WINDOWS?r(3202):r(2151),e.exports=n,n.sync=function(e,t){try{return A.sync(e,t||{})}catch(e){if(t&&t.ignoreErrors||"EACCES"===e.code)return!1;throw e}}},2151:(e,t,r)=>{e.exports=n,n.sync=function(e,t){return o(A.statSync(e),t)};var A=r(35747);function n(e,t,r){A.stat(e,(function(e,A){r(e,!e&&o(A,t))}))}function o(e,t){return e.isFile()&&function(e,t){var r=e.mode,A=e.uid,n=e.gid,o=void 0!==t.uid?t.uid:process.getuid&&process.getuid(),i=void 0!==t.gid?t.gid:process.getgid&&process.getgid(),s=parseInt("100",8),a=parseInt("010",8),c=parseInt("001",8),g=s|a;return r&c||r&a&&n===i||r&s&&A===o||r&g&&0===o}(e,t)}},3202:(e,t,r)=>{e.exports=o,o.sync=function(e,t){return n(A.statSync(e),e,t)};var A=r(35747);function n(e,t,r){return!(!e.isSymbolicLink()&&!e.isFile())&&function(e,t){var r=void 0!==t.pathExt?t.pathExt:process.env.PATHEXT;if(!r)return!0;if(-1!==(r=r.split(";")).indexOf(""))return!0;for(var A=0;A{"use strict";var A=r(40744);e.exports=A},40744:(e,t,r)=>{"use strict";var A=r(55384),n=r(24129);function o(e){return function(){throw new Error("Function "+e+" is deprecated and cannot be used.")}}e.exports.Type=r(81704),e.exports.Schema=r(8212),e.exports.FAILSAFE_SCHEMA=r(44413),e.exports.JSON_SCHEMA=r(45247),e.exports.CORE_SCHEMA=r(8769),e.exports.DEFAULT_SAFE_SCHEMA=r(65483),e.exports.DEFAULT_FULL_SCHEMA=r(5235),e.exports.load=A.load,e.exports.loadAll=A.loadAll,e.exports.safeLoad=A.safeLoad,e.exports.safeLoadAll=A.safeLoadAll,e.exports.dump=n.dump,e.exports.safeDump=n.safeDump,e.exports.YAMLException=r(17345),e.exports.MINIMAL_SCHEMA=r(44413),e.exports.SAFE_SCHEMA=r(65483),e.exports.DEFAULT_SCHEMA=r(5235),e.exports.scan=o("scan"),e.exports.parse=o("parse"),e.exports.compose=o("compose"),e.exports.addConstructor=o("addConstructor")},28149:e=>{"use strict";function t(e){return null==e}e.exports.isNothing=t,e.exports.isObject=function(e){return"object"==typeof e&&null!==e},e.exports.toArray=function(e){return Array.isArray(e)?e:t(e)?[]:[e]},e.exports.repeat=function(e,t){var r,A="";for(r=0;r{"use strict";var A=r(28149),n=r(17345),o=r(5235),i=r(65483),s=Object.prototype.toString,a=Object.prototype.hasOwnProperty,c={0:"\\0",7:"\\a",8:"\\b",9:"\\t",10:"\\n",11:"\\v",12:"\\f",13:"\\r",27:"\\e",34:'\\"',92:"\\\\",133:"\\N",160:"\\_",8232:"\\L",8233:"\\P"},g=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];function l(e){var t,r,o;if(t=e.toString(16).toUpperCase(),e<=255)r="x",o=2;else if(e<=65535)r="u",o=4;else{if(!(e<=4294967295))throw new n("code point within a string may not be greater than 0xFFFFFFFF");r="U",o=8}return"\\"+r+A.repeat("0",o-t.length)+t}function u(e){this.schema=e.schema||o,this.indent=Math.max(1,e.indent||2),this.noArrayIndent=e.noArrayIndent||!1,this.skipInvalid=e.skipInvalid||!1,this.flowLevel=A.isNothing(e.flowLevel)?-1:e.flowLevel,this.styleMap=function(e,t){var r,A,n,o,i,s,c;if(null===t)return{};for(r={},n=0,o=(A=Object.keys(t)).length;nA&&" "!==e[l+1],l=o);else if(!C(i))return 5;u=u&&f(i)}c=c||g&&o-l-1>A&&" "!==e[l+1]}return a||c?r>9&&I(e)?5:c?4:3:u&&!n(e)?1:2}function B(e,t,r,A){e.dump=function(){if(0===t.length)return"''";if(!e.noCompatMode&&-1!==g.indexOf(t))return"'"+t+"'";var o=e.indent*Math.max(1,r),i=-1===e.lineWidth?-1:Math.max(Math.min(e.lineWidth,40),e.lineWidth-o),s=A||e.flowLevel>-1&&r>=e.flowLevel;switch(E(t,s,e.indent,i,(function(t){return function(e,t){var r,A;for(r=0,A=e.implicitTypes.length;r"+y(t,e.indent)+m(h(function(e,t){var r,A,n=/(\n+)([^\n]*)/g,o=(s=e.indexOf("\n"),s=-1!==s?s:e.length,n.lastIndex=s,w(e.slice(0,s),t)),i="\n"===e[0]||" "===e[0];var s;for(;A=n.exec(e);){var a=A[1],c=A[2];r=" "===c[0],o+=a+(i||r||""===c?"":"\n")+w(c,t),i=r}return o}(t,i),o));case 5:return'"'+function(e){for(var t,r,A,n="",o=0;o=55296&&t<=56319&&(r=e.charCodeAt(o+1))>=56320&&r<=57343?(n+=l(1024*(t-55296)+r-56320+65536),o++):(A=c[t],n+=!A&&C(t)?e[o]:A||l(t));return n}(t)+'"';default:throw new n("impossible error: invalid scalar style")}}()}function y(e,t){var r=I(e)?String(t):"",A="\n"===e[e.length-1];return r+(A&&("\n"===e[e.length-2]||"\n"===e)?"+":A?"":"-")+"\n"}function m(e){return"\n"===e[e.length-1]?e.slice(0,-1):e}function w(e,t){if(""===e||" "===e[0])return e;for(var r,A,n=/ [^ ]/g,o=0,i=0,s=0,a="";r=n.exec(e);)(s=r.index)-o>t&&(A=i>o?i:s,a+="\n"+e.slice(o,A),o=A+1),i=s;return a+="\n",e.length-o>t&&i>o?a+=e.slice(o,i)+"\n"+e.slice(i+1):a+=e.slice(o),a.slice(1)}function Q(e,t,r){var A,o,i,c,g,l;for(i=0,c=(o=r?e.explicitTypes:e.implicitTypes).length;i tag resolver accepts not "'+l+'" style');A=g.represent[l](t,l)}e.dump=A}return!0}return!1}function D(e,t,r,A,o,i){e.tag=null,e.dump=r,Q(e,r,!1)||Q(e,r,!0);var a=s.call(e.dump);A&&(A=e.flowLevel<0||e.flowLevel>t);var c,g,l="[object Object]"===a||"[object Array]"===a;if(l&&(g=-1!==(c=e.duplicates.indexOf(r))),(null!==e.tag&&"?"!==e.tag||g||2!==e.indent&&t>0)&&(o=!1),g&&e.usedDuplicates[c])e.dump="*ref_"+c;else{if(l&&g&&!e.usedDuplicates[c]&&(e.usedDuplicates[c]=!0),"[object Object]"===a)A&&0!==Object.keys(e.dump).length?(!function(e,t,r,A){var o,i,s,a,c,g,l="",u=e.tag,h=Object.keys(r);if(!0===e.sortKeys)h.sort();else if("function"==typeof e.sortKeys)h.sort(e.sortKeys);else if(e.sortKeys)throw new n("sortKeys must be a boolean or a function");for(o=0,i=h.length;o1024)&&(e.dump&&10===e.dump.charCodeAt(0)?g+="?":g+="? "),g+=e.dump,c&&(g+=p(e,t)),D(e,t+1,a,!0,c)&&(e.dump&&10===e.dump.charCodeAt(0)?g+=":":g+=": ",l+=g+=e.dump));e.tag=u,e.dump=l||"{}"}(e,t,e.dump,o),g&&(e.dump="&ref_"+c+e.dump)):(!function(e,t,r){var A,n,o,i,s,a="",c=e.tag,g=Object.keys(r);for(A=0,n=g.length;A1024&&(s+="? "),s+=e.dump+(e.condenseFlow?'"':"")+":"+(e.condenseFlow?"":" "),D(e,t,i,!1,!1)&&(a+=s+=e.dump));e.tag=c,e.dump="{"+a+"}"}(e,t,e.dump),g&&(e.dump="&ref_"+c+" "+e.dump));else if("[object Array]"===a){var u=e.noArrayIndent&&t>0?t-1:t;A&&0!==e.dump.length?(!function(e,t,r,A){var n,o,i="",s=e.tag;for(n=0,o=r.length;n "+e.dump)}return!0}function b(e,t){var r,A,n=[],o=[];for(function e(t,r,A){var n,o,i;if(null!==t&&"object"==typeof t)if(-1!==(o=r.indexOf(t)))-1===A.indexOf(o)&&A.push(o);else if(r.push(t),Array.isArray(t))for(o=0,i=t.length;o{"use strict";function t(e,t){Error.call(this),this.name="YAMLException",this.reason=e,this.mark=t,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():""),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||""}t.prototype=Object.create(Error.prototype),t.prototype.constructor=t,t.prototype.toString=function(e){var t=this.name+": ";return t+=this.reason||"(unknown reason)",!e&&this.mark&&(t+=" "+this.mark.toString()),t},e.exports=t},55384:(e,t,r)=>{"use strict";var A=r(28149),n=r(17345),o=r(30399),i=r(65483),s=r(5235),a=Object.prototype.hasOwnProperty,c=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,g=/[\x85\u2028\u2029]/,l=/[,\[\]\{\}]/,u=/^(?:!|!!|![a-z\-]+!)$/i,h=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function p(e){return 10===e||13===e}function d(e){return 9===e||32===e}function C(e){return 9===e||32===e||10===e||13===e}function f(e){return 44===e||91===e||93===e||123===e||125===e}function I(e){var t;return 48<=e&&e<=57?e-48:97<=(t=32|e)&&t<=102?t-97+10:-1}function E(e){return 48===e?"\0":97===e?"":98===e?"\b":116===e||9===e?"\t":110===e?"\n":118===e?"\v":102===e?"\f":114===e?"\r":101===e?"":32===e?" ":34===e?'"':47===e?"/":92===e?"\\":78===e?"…":95===e?" ":76===e?"\u2028":80===e?"\u2029":""}function B(e){return e<=65535?String.fromCharCode(e):String.fromCharCode(55296+(e-65536>>10),56320+(e-65536&1023))}for(var y=new Array(256),m=new Array(256),w=0;w<256;w++)y[w]=E(w)?1:0,m[w]=E(w);function Q(e,t){this.input=e,this.filename=t.filename||null,this.schema=t.schema||s,this.onWarning=t.onWarning||null,this.legacy=t.legacy||!1,this.json=t.json||!1,this.listener=t.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=e.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function D(e,t){return new n(t,new o(e.filename,e.input,e.position,e.line,e.position-e.lineStart))}function b(e,t){throw D(e,t)}function v(e,t){e.onWarning&&e.onWarning.call(null,D(e,t))}var S={YAML:function(e,t,r){var A,n,o;null!==e.version&&b(e,"duplication of %YAML directive"),1!==r.length&&b(e,"YAML directive accepts exactly one argument"),null===(A=/^([0-9]+)\.([0-9]+)$/.exec(r[0]))&&b(e,"ill-formed argument of the YAML directive"),n=parseInt(A[1],10),o=parseInt(A[2],10),1!==n&&b(e,"unacceptable YAML version of the document"),e.version=r[0],e.checkLineBreaks=o<2,1!==o&&2!==o&&v(e,"unsupported YAML version of the document")},TAG:function(e,t,r){var A,n;2!==r.length&&b(e,"TAG directive accepts exactly two arguments"),A=r[0],n=r[1],u.test(A)||b(e,"ill-formed tag handle (first argument) of the TAG directive"),a.call(e.tagMap,A)&&b(e,'there is a previously declared suffix for "'+A+'" tag handle'),h.test(n)||b(e,"ill-formed tag prefix (second argument) of the TAG directive"),e.tagMap[A]=n}};function k(e,t,r,A){var n,o,i,s;if(t1&&(e.result+=A.repeat("\n",t-1))}function L(e,t){var r,A,n=e.tag,o=e.anchor,i=[],s=!1;for(null!==e.anchor&&(e.anchorMap[e.anchor]=i),A=e.input.charCodeAt(e.position);0!==A&&45===A&&C(e.input.charCodeAt(e.position+1));)if(s=!0,e.position++,M(e,!0,-1)&&e.lineIndent<=t)i.push(null),A=e.input.charCodeAt(e.position);else if(r=e.line,U(e,t,3,!1,!0),i.push(e.result),M(e,!0,-1),A=e.input.charCodeAt(e.position),(e.line===r||e.lineIndent>t)&&0!==A)b(e,"bad indentation of a sequence entry");else if(e.lineIndentt?w=1:e.lineIndent===t?w=0:e.lineIndentt?w=1:e.lineIndent===t?w=0:e.lineIndentt)&&(U(e,t,4,!0,n)&&(f?h=e.result:p=e.result),f||(F(e,g,l,u,h,p,o,i),u=h=p=null),M(e,!0,-1),s=e.input.charCodeAt(e.position)),e.lineIndent>t&&0!==s)b(e,"bad indentation of a mapping entry");else if(e.lineIndent=0))break;0===o?b(e,"bad explicit indentation width of a block scalar; it cannot be less than one"):g?b(e,"repeat of an indentation width identifier"):(l=t+o-1,g=!0)}if(d(i)){do{i=e.input.charCodeAt(++e.position)}while(d(i));if(35===i)do{i=e.input.charCodeAt(++e.position)}while(!p(i)&&0!==i)}for(;0!==i;){for(K(e),e.lineIndent=0,i=e.input.charCodeAt(e.position);(!g||e.lineIndentl&&(l=e.lineIndent),p(i))u++;else{if(e.lineIndent0){for(n=i,o=0;n>0;n--)(i=I(s=e.input.charCodeAt(++e.position)))>=0?o=(o<<4)+i:b(e,"expected hexadecimal character");e.result+=B(o),e.position++}else b(e,"unknown escape sequence");r=A=e.position}else p(s)?(k(e,r,A,!0),x(e,M(e,!1,t)),r=A=e.position):e.position===e.lineStart&&R(e)?b(e,"unexpected end of the document within a double quoted scalar"):(e.position++,A=e.position)}b(e,"unexpected end of the stream within a double quoted scalar")}(e,h)?D=!0:!function(e){var t,r,A;if(42!==(A=e.input.charCodeAt(e.position)))return!1;for(A=e.input.charCodeAt(++e.position),t=e.position;0!==A&&!C(A)&&!f(A);)A=e.input.charCodeAt(++e.position);return e.position===t&&b(e,"name of an alias node must contain at least one character"),r=e.input.slice(t,e.position),e.anchorMap.hasOwnProperty(r)||b(e,'unidentified alias "'+r+'"'),e.result=e.anchorMap[r],M(e,!0,-1),!0}(e)?function(e,t,r){var A,n,o,i,s,a,c,g,l=e.kind,u=e.result;if(C(g=e.input.charCodeAt(e.position))||f(g)||35===g||38===g||42===g||33===g||124===g||62===g||39===g||34===g||37===g||64===g||96===g)return!1;if((63===g||45===g)&&(C(A=e.input.charCodeAt(e.position+1))||r&&f(A)))return!1;for(e.kind="scalar",e.result="",n=o=e.position,i=!1;0!==g;){if(58===g){if(C(A=e.input.charCodeAt(e.position+1))||r&&f(A))break}else if(35===g){if(C(e.input.charCodeAt(e.position-1)))break}else{if(e.position===e.lineStart&&R(e)||r&&f(g))break;if(p(g)){if(s=e.line,a=e.lineStart,c=e.lineIndent,M(e,!1,-1),e.lineIndent>=t){i=!0,g=e.input.charCodeAt(e.position);continue}e.position=o,e.line=s,e.lineStart=a,e.lineIndent=c;break}}i&&(k(e,n,o,!1),x(e,e.line-s),n=o=e.position,i=!1),d(g)||(o=e.position+1),g=e.input.charCodeAt(++e.position)}return k(e,n,o,!1),!!e.result||(e.kind=l,e.result=u,!1)}(e,h,1===r)&&(D=!0,null===e.tag&&(e.tag="?")):(D=!0,null===e.tag&&null===e.anchor||b(e,"alias node should not have any properties")),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):0===w&&(D=c&&L(e,E))),null!==e.tag&&"!"!==e.tag)if("?"===e.tag){for(g=0,l=e.implicitTypes.length;g tag; it should be "'+u.kind+'", not "'+e.kind+'"'),u.resolve(e.result)?(e.result=u.construct(e.result),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):b(e,"cannot resolve a node with !<"+e.tag+"> explicit tag")):b(e,"unknown tag !<"+e.tag+">");return null!==e.listener&&e.listener("close",e),null!==e.tag||null!==e.anchor||D}function T(e){var t,r,A,n,o=e.position,i=!1;for(e.version=null,e.checkLineBreaks=e.legacy,e.tagMap={},e.anchorMap={};0!==(n=e.input.charCodeAt(e.position))&&(M(e,!0,-1),n=e.input.charCodeAt(e.position),!(e.lineIndent>0||37!==n));){for(i=!0,n=e.input.charCodeAt(++e.position),t=e.position;0!==n&&!C(n);)n=e.input.charCodeAt(++e.position);for(A=[],(r=e.input.slice(t,e.position)).length<1&&b(e,"directive name must not be less than one character in length");0!==n;){for(;d(n);)n=e.input.charCodeAt(++e.position);if(35===n){do{n=e.input.charCodeAt(++e.position)}while(0!==n&&!p(n));break}if(p(n))break;for(t=e.position;0!==n&&!C(n);)n=e.input.charCodeAt(++e.position);A.push(e.input.slice(t,e.position))}0!==n&&K(e),a.call(S,r)?S[r](e,r,A):v(e,'unknown document directive "'+r+'"')}M(e,!0,-1),0===e.lineIndent&&45===e.input.charCodeAt(e.position)&&45===e.input.charCodeAt(e.position+1)&&45===e.input.charCodeAt(e.position+2)?(e.position+=3,M(e,!0,-1)):i&&b(e,"directives end mark is expected"),U(e,e.lineIndent-1,4,!1,!0),M(e,!0,-1),e.checkLineBreaks&&g.test(e.input.slice(o,e.position))&&v(e,"non-ASCII line breaks are interpreted as content"),e.documents.push(e.result),e.position===e.lineStart&&R(e)?46===e.input.charCodeAt(e.position)&&(e.position+=3,M(e,!0,-1)):e.position{"use strict";var A=r(28149);function n(e,t,r,A,n){this.name=e,this.buffer=t,this.position=r,this.line=A,this.column=n}n.prototype.getSnippet=function(e,t){var r,n,o,i,s;if(!this.buffer)return null;for(e=e||4,t=t||75,r="",n=this.position;n>0&&-1==="\0\r\n…\u2028\u2029".indexOf(this.buffer.charAt(n-1));)if(n-=1,this.position-n>t/2-1){r=" ... ",n+=5;break}for(o="",i=this.position;it/2-1){o=" ... ",i-=5;break}return s=this.buffer.slice(n,i),A.repeat(" ",e)+r+s+o+"\n"+A.repeat(" ",e+this.position-n+r.length)+"^"},n.prototype.toString=function(e){var t,r="";return this.name&&(r+='in "'+this.name+'" '),r+="at line "+(this.line+1)+", column "+(this.column+1),e||(t=this.getSnippet())&&(r+=":\n"+t),r},e.exports=n},8212:(e,t,r)=>{"use strict";var A=r(28149),n=r(17345),o=r(81704);function i(e,t,r){var A=[];return e.include.forEach((function(e){r=i(e,t,r)})),e[t].forEach((function(e){r.forEach((function(t,r){t.tag===e.tag&&t.kind===e.kind&&A.push(r)})),r.push(e)})),r.filter((function(e,t){return-1===A.indexOf(t)}))}function s(e){this.include=e.include||[],this.implicit=e.implicit||[],this.explicit=e.explicit||[],this.implicit.forEach((function(e){if(e.loadKind&&"scalar"!==e.loadKind)throw new n("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.")})),this.compiledImplicit=i(this,"implicit",[]),this.compiledExplicit=i(this,"explicit",[]),this.compiledTypeMap=function(){var e,t,r={scalar:{},sequence:{},mapping:{},fallback:{}};function A(e){r[e.kind][e.tag]=r.fallback[e.tag]=e}for(e=0,t=arguments.length;e{"use strict";var A=r(8212);e.exports=new A({include:[r(45247)]})},5235:(e,t,r)=>{"use strict";var A=r(8212);e.exports=A.DEFAULT=new A({include:[r(65483)],explicit:[r(61425),r(61872),r(79982)]})},65483:(e,t,r)=>{"use strict";var A=r(8212);e.exports=new A({include:[r(8769)],implicit:[r(83516),r(95441)],explicit:[r(34836),r(6847),r(65173),r(92025)]})},44413:(e,t,r)=>{"use strict";var A=r(8212);e.exports=new A({explicit:[r(19952),r(46557),r(90173)]})},45247:(e,t,r)=>{"use strict";var A=r(8212);e.exports=new A({include:[r(44413)],implicit:[r(40188),r(58357),r(82106),r(71945)]})},81704:(e,t,r)=>{"use strict";var A=r(17345),n=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],o=["scalar","sequence","mapping"];e.exports=function(e,t){var r,i;if(t=t||{},Object.keys(t).forEach((function(t){if(-1===n.indexOf(t))throw new A('Unknown option "'+t+'" is met in definition of "'+e+'" YAML type.')})),this.tag=e,this.kind=t.kind||null,this.resolve=t.resolve||function(){return!0},this.construct=t.construct||function(e){return e},this.instanceOf=t.instanceOf||null,this.predicate=t.predicate||null,this.represent=t.represent||null,this.defaultStyle=t.defaultStyle||null,this.styleAliases=(r=t.styleAliases||null,i={},null!==r&&Object.keys(r).forEach((function(e){r[e].forEach((function(t){i[String(t)]=e}))})),i),-1===o.indexOf(this.kind))throw new A('Unknown kind "'+this.kind+'" is specified for "'+e+'" YAML type.')}},34836:(e,t,r)=>{"use strict";var A;try{A=r(64293).Buffer}catch(e){}var n=r(81704),o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";e.exports=new n("tag:yaml.org,2002:binary",{kind:"scalar",resolve:function(e){if(null===e)return!1;var t,r,A=0,n=e.length,i=o;for(r=0;r64)){if(t<0)return!1;A+=6}return A%8==0},construct:function(e){var t,r,n=e.replace(/[\r\n=]/g,""),i=n.length,s=o,a=0,c=[];for(t=0;t>16&255),c.push(a>>8&255),c.push(255&a)),a=a<<6|s.indexOf(n.charAt(t));return 0===(r=i%4*6)?(c.push(a>>16&255),c.push(a>>8&255),c.push(255&a)):18===r?(c.push(a>>10&255),c.push(a>>2&255)):12===r&&c.push(a>>4&255),A?A.from?A.from(c):new A(c):c},predicate:function(e){return A&&A.isBuffer(e)},represent:function(e){var t,r,A="",n=0,i=e.length,s=o;for(t=0;t>18&63],A+=s[n>>12&63],A+=s[n>>6&63],A+=s[63&n]),n=(n<<8)+e[t];return 0===(r=i%3)?(A+=s[n>>18&63],A+=s[n>>12&63],A+=s[n>>6&63],A+=s[63&n]):2===r?(A+=s[n>>10&63],A+=s[n>>4&63],A+=s[n<<2&63],A+=s[64]):1===r&&(A+=s[n>>2&63],A+=s[n<<4&63],A+=s[64],A+=s[64]),A}})},58357:(e,t,r)=>{"use strict";var A=r(81704);e.exports=new A("tag:yaml.org,2002:bool",{kind:"scalar",resolve:function(e){if(null===e)return!1;var t=e.length;return 4===t&&("true"===e||"True"===e||"TRUE"===e)||5===t&&("false"===e||"False"===e||"FALSE"===e)},construct:function(e){return"true"===e||"True"===e||"TRUE"===e},predicate:function(e){return"[object Boolean]"===Object.prototype.toString.call(e)},represent:{lowercase:function(e){return e?"true":"false"},uppercase:function(e){return e?"TRUE":"FALSE"},camelcase:function(e){return e?"True":"False"}},defaultStyle:"lowercase"})},71945:(e,t,r)=>{"use strict";var A=r(28149),n=r(81704),o=new RegExp("^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");var i=/^[-+]?[0-9]+e/;e.exports=new n("tag:yaml.org,2002:float",{kind:"scalar",resolve:function(e){return null!==e&&!(!o.test(e)||"_"===e[e.length-1])},construct:function(e){var t,r,A,n;return r="-"===(t=e.replace(/_/g,"").toLowerCase())[0]?-1:1,n=[],"+-".indexOf(t[0])>=0&&(t=t.slice(1)),".inf"===t?1===r?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===t?NaN:t.indexOf(":")>=0?(t.split(":").forEach((function(e){n.unshift(parseFloat(e,10))})),t=0,A=1,n.forEach((function(e){t+=e*A,A*=60})),r*t):r*parseFloat(t,10)},predicate:function(e){return"[object Number]"===Object.prototype.toString.call(e)&&(e%1!=0||A.isNegativeZero(e))},represent:function(e,t){var r;if(isNaN(e))switch(t){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===e)switch(t){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===e)switch(t){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(A.isNegativeZero(e))return"-0.0";return r=e.toString(10),i.test(r)?r.replace("e",".e"):r},defaultStyle:"lowercase"})},82106:(e,t,r)=>{"use strict";var A=r(28149),n=r(81704);function o(e){return 48<=e&&e<=55}function i(e){return 48<=e&&e<=57}e.exports=new n("tag:yaml.org,2002:int",{kind:"scalar",resolve:function(e){if(null===e)return!1;var t,r,A=e.length,n=0,s=!1;if(!A)return!1;if("-"!==(t=e[n])&&"+"!==t||(t=e[++n]),"0"===t){if(n+1===A)return!0;if("b"===(t=e[++n])){for(n++;n=0?"0b"+e.toString(2):"-0b"+e.toString(2).slice(1)},octal:function(e){return e>=0?"0"+e.toString(8):"-0"+e.toString(8).slice(1)},decimal:function(e){return e.toString(10)},hexadecimal:function(e){return e>=0?"0x"+e.toString(16).toUpperCase():"-0x"+e.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})},79982:(e,t,r)=>{"use strict";var A;try{A=r(Object(function(){var e=new Error("Cannot find module 'esprima'");throw e.code="MODULE_NOT_FOUND",e}()))}catch(e){"undefined"!=typeof window&&(A=window.esprima)}var n=r(81704);e.exports=new n("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:function(e){if(null===e)return!1;try{var t="("+e+")",r=A.parse(t,{range:!0});return"Program"===r.type&&1===r.body.length&&"ExpressionStatement"===r.body[0].type&&("ArrowFunctionExpression"===r.body[0].expression.type||"FunctionExpression"===r.body[0].expression.type)}catch(e){return!1}},construct:function(e){var t,r="("+e+")",n=A.parse(r,{range:!0}),o=[];if("Program"!==n.type||1!==n.body.length||"ExpressionStatement"!==n.body[0].type||"ArrowFunctionExpression"!==n.body[0].expression.type&&"FunctionExpression"!==n.body[0].expression.type)throw new Error("Failed to resolve function");return n.body[0].expression.params.forEach((function(e){o.push(e.name)})),t=n.body[0].expression.body.range,"BlockStatement"===n.body[0].expression.body.type?new Function(o,r.slice(t[0]+1,t[1]-1)):new Function(o,"return "+r.slice(t[0],t[1]))},predicate:function(e){return"[object Function]"===Object.prototype.toString.call(e)},represent:function(e){return e.toString()}})},61872:(e,t,r)=>{"use strict";var A=r(81704);e.exports=new A("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:function(e){if(null===e)return!1;if(0===e.length)return!1;var t=e,r=/\/([gim]*)$/.exec(e),A="";if("/"===t[0]){if(r&&(A=r[1]),A.length>3)return!1;if("/"!==t[t.length-A.length-1])return!1}return!0},construct:function(e){var t=e,r=/\/([gim]*)$/.exec(e),A="";return"/"===t[0]&&(r&&(A=r[1]),t=t.slice(1,t.length-A.length-1)),new RegExp(t,A)},predicate:function(e){return"[object RegExp]"===Object.prototype.toString.call(e)},represent:function(e){var t="/"+e.source+"/";return e.global&&(t+="g"),e.multiline&&(t+="m"),e.ignoreCase&&(t+="i"),t}})},61425:(e,t,r)=>{"use strict";var A=r(81704);e.exports=new A("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:function(){return!0},construct:function(){},predicate:function(e){return void 0===e},represent:function(){return""}})},90173:(e,t,r)=>{"use strict";var A=r(81704);e.exports=new A("tag:yaml.org,2002:map",{kind:"mapping",construct:function(e){return null!==e?e:{}}})},95441:(e,t,r)=>{"use strict";var A=r(81704);e.exports=new A("tag:yaml.org,2002:merge",{kind:"scalar",resolve:function(e){return"<<"===e||null===e}})},40188:(e,t,r)=>{"use strict";var A=r(81704);e.exports=new A("tag:yaml.org,2002:null",{kind:"scalar",resolve:function(e){if(null===e)return!0;var t=e.length;return 1===t&&"~"===e||4===t&&("null"===e||"Null"===e||"NULL"===e)},construct:function(){return null},predicate:function(e){return null===e},represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})},6847:(e,t,r)=>{"use strict";var A=r(81704),n=Object.prototype.hasOwnProperty,o=Object.prototype.toString;e.exports=new A("tag:yaml.org,2002:omap",{kind:"sequence",resolve:function(e){if(null===e)return!0;var t,r,A,i,s,a=[],c=e;for(t=0,r=c.length;t{"use strict";var A=r(81704),n=Object.prototype.toString;e.exports=new A("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:function(e){if(null===e)return!0;var t,r,A,o,i,s=e;for(i=new Array(s.length),t=0,r=s.length;t{"use strict";var A=r(81704);e.exports=new A("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(e){return null!==e?e:[]}})},92025:(e,t,r)=>{"use strict";var A=r(81704),n=Object.prototype.hasOwnProperty;e.exports=new A("tag:yaml.org,2002:set",{kind:"mapping",resolve:function(e){if(null===e)return!0;var t,r=e;for(t in r)if(n.call(r,t)&&null!==r[t])return!1;return!0},construct:function(e){return null!==e?e:{}}})},19952:(e,t,r)=>{"use strict";var A=r(81704);e.exports=new A("tag:yaml.org,2002:str",{kind:"scalar",construct:function(e){return null!==e?e:""}})},83516:(e,t,r)=>{"use strict";var A=r(81704),n=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),o=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");e.exports=new A("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:function(e){return null!==e&&(null!==n.exec(e)||null!==o.exec(e))},construct:function(e){var t,r,A,i,s,a,c,g,l=0,u=null;if(null===(t=n.exec(e))&&(t=o.exec(e)),null===t)throw new Error("Date resolve error");if(r=+t[1],A=+t[2]-1,i=+t[3],!t[4])return new Date(Date.UTC(r,A,i));if(s=+t[4],a=+t[5],c=+t[6],t[7]){for(l=t[7].slice(0,3);l.length<3;)l+="0";l=+l}return t[9]&&(u=6e4*(60*+t[10]+ +(t[11]||0)),"-"===t[9]&&(u=-u)),g=new Date(Date.UTC(r,A,i,s,a,c,l)),u&&g.setTime(g.getTime()-u),g},instanceOf:Date,represent:function(e){return e.toISOString()}})},7427:(e,t)=>{t.stringify=function e(t){if(void 0===t)return t;if(t&&Buffer.isBuffer(t))return JSON.stringify(":base64:"+t.toString("base64"));if(t&&t.toJSON&&(t=t.toJSON()),t&&"object"==typeof t){var r="",A=Array.isArray(t);r=A?"[":"{";var n=!0;for(var o in t){var i="function"==typeof t[o]||!A&&void 0===t[o];Object.hasOwnProperty.call(t,o)&&!i&&(n||(r+=","),n=!1,A?null==t[o]?r+="null":r+=e(t[o]):void 0!==t[o]&&(r+=e(o)+":"+e(t[o])))}return r+=A?"]":"}"}return"string"==typeof t?JSON.stringify(/^:/.test(t)?":"+t:t):void 0===t?"null":JSON.stringify(t)},t.parse=function(e){return JSON.parse(e,(function(e,t){return"string"==typeof t?/^:base64:/.test(t)?Buffer.from(t.substring(8),"base64"):/^:/.test(t)?t.substring(1):t:t}))}},72515:(e,t,r)=>{"use strict";const A=r(28614),n=r(7427);e.exports=class extends A{constructor(e,t){if(super(),this.opts=Object.assign({namespace:"keyv",serialize:n.stringify,deserialize:n.parse},"string"==typeof e?{uri:e}:e,t),!this.opts.store){const e=Object.assign({},this.opts);this.opts.store=(e=>{const t={redis:"@keyv/redis",mongodb:"@keyv/mongo",mongo:"@keyv/mongo",sqlite:"@keyv/sqlite",postgresql:"@keyv/postgres",postgres:"@keyv/postgres",mysql:"@keyv/mysql"};if(e.adapter||e.uri){const A=e.adapter||/^[^:]*/.exec(e.uri)[0];return new(r(89112)(t[A]))(e)}return new Map})(e)}"function"==typeof this.opts.store.on&&this.opts.store.on("error",e=>this.emit("error",e)),this.opts.store.namespace=this.opts.namespace}_getKeyPrefix(e){return`${this.opts.namespace}:${e}`}get(e,t){e=this._getKeyPrefix(e);const{store:r}=this.opts;return Promise.resolve().then(()=>r.get(e)).then(e=>"string"==typeof e?this.opts.deserialize(e):e).then(r=>{if(void 0!==r){if(!("number"==typeof r.expires&&Date.now()>r.expires))return t&&t.raw?r:r.value;this.delete(e)}})}set(e,t,r){e=this._getKeyPrefix(e),void 0===r&&(r=this.opts.ttl),0===r&&(r=void 0);const{store:A}=this.opts;return Promise.resolve().then(()=>{const e="number"==typeof r?Date.now()+r:null;return t={value:t,expires:e},this.opts.serialize(t)}).then(t=>A.set(e,t,r)).then(()=>!0)}delete(e){e=this._getKeyPrefix(e);const{store:t}=this.opts;return Promise.resolve().then(()=>t.delete(e))}clear(){const{store:e}=this.opts;return Promise.resolve().then(()=>e.clear())}}},89112:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=89112,e.exports=t},78962:(e,t,r)=>{var A=r(99513)(r(76169),"DataView");e.exports=A},72574:(e,t,r)=>{var A=r(31713),n=r(86688),o=r(45937),i=r(5017),s=r(79457);function a(e){var t=-1,r=null==e?0:e.length;for(this.clear();++t{var A=r(14620),n=r(73682),o=r(43112),i=r(90640),s=r(9380);function a(e){var t=-1,r=null==e?0:e.length;for(this.clear();++t{var A=r(99513)(r(76169),"Map");e.exports=A},75009:(e,t,r)=>{var A=r(18209),n=r(89706),o=r(43786),i=r(17926),s=r(87345);function a(e){var t=-1,r=null==e?0:e.length;for(this.clear();++t{var A=r(99513)(r(76169),"Promise");e.exports=A},43231:(e,t,r)=>{var A=r(99513)(r(76169),"Set");e.exports=A},46235:(e,t,r)=>{var A=r(75009),n=r(74785),o=r(87760);function i(e){var t=-1,r=null==e?0:e.length;for(this.__data__=new A;++t{var A=r(29197),n=r(35678),o=r(33336),i=r(97163),s=r(43737),a=r(48548);function c(e){var t=this.__data__=new A(e);this.size=t.size}c.prototype.clear=n,c.prototype.delete=o,c.prototype.get=i,c.prototype.has=s,c.prototype.set=a,e.exports=c},69976:(e,t,r)=>{var A=r(76169).Symbol;e.exports=A},2740:(e,t,r)=>{var A=r(76169).Uint8Array;e.exports=A},47063:(e,t,r)=>{var A=r(99513)(r(76169),"WeakMap");e.exports=A},66636:e=>{e.exports=function(e,t,r){switch(r.length){case 0:return e.call(t);case 1:return e.call(t,r[0]);case 2:return e.call(t,r[0],r[1]);case 3:return e.call(t,r[0],r[1],r[2])}return e.apply(t,r)}},33326:e=>{e.exports=function(e,t){for(var r=-1,A=null==e?0:e.length;++r{e.exports=function(e,t){for(var r=-1,A=null==e?0:e.length,n=0,o=[];++r{var A=r(7089),n=r(61771),o=r(82664),i=r(10667),s=r(98041),a=r(32565),c=Object.prototype.hasOwnProperty;e.exports=function(e,t){var r=o(e),g=!r&&n(e),l=!r&&!g&&i(e),u=!r&&!g&&!l&&a(e),h=r||g||l||u,p=h?A(e.length,String):[],d=p.length;for(var C in e)!t&&!c.call(e,C)||h&&("length"==C||l&&("offset"==C||"parent"==C)||u&&("buffer"==C||"byteLength"==C||"byteOffset"==C)||s(C,d))||p.push(C);return p}},60783:e=>{e.exports=function(e,t){for(var r=-1,A=null==e?0:e.length,n=Array(A);++r{e.exports=function(e,t){for(var r=-1,A=t.length,n=e.length;++r{e.exports=function(e,t,r,A){var n=-1,o=null==e?0:e.length;for(A&&o&&(r=e[++n]);++n{e.exports=function(e,t){for(var r=-1,A=null==e?0:e.length;++r{e.exports=function(e){return e.split("")}},11852:e=>{var t=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;e.exports=function(e){return e.match(t)||[]}},26943:(e,t,r)=>{var A=r(91198),n=r(71074);e.exports=function(e,t,r){(void 0!==r&&!n(e[t],r)||void 0===r&&!(t in e))&&A(e,t,r)}},65759:(e,t,r)=>{var A=r(91198),n=r(71074),o=Object.prototype.hasOwnProperty;e.exports=function(e,t,r){var i=e[t];o.call(e,t)&&n(i,r)&&(void 0!==r||t in e)||A(e,t,r)}},39836:(e,t,r)=>{var A=r(71074);e.exports=function(e,t){for(var r=e.length;r--;)if(A(e[r][0],t))return r;return-1}},28628:(e,t,r)=>{var A=r(75182),n=r(42185);e.exports=function(e,t){return e&&A(t,n(t),e)}},78707:(e,t,r)=>{var A=r(75182),n=r(24887);e.exports=function(e,t){return e&&A(t,n(t),e)}},91198:(e,t,r)=>{var A=r(65);e.exports=function(e,t,r){"__proto__"==t&&A?A(e,t,{configurable:!0,enumerable:!0,value:r,writable:!0}):e[t]=r}},41076:(e,t,r)=>{var A=r(22851),n=r(33326),o=r(65759),i=r(28628),s=r(78707),a=r(64266),c=r(87229),g=r(23105),l=r(60741),u=r(60753),h=r(64420),p=r(79435),d=r(27908),C=r(37836),f=r(88438),I=r(82664),E=r(10667),B=r(13349),y=r(46778),m=r(33931),w=r(42185),Q={};Q["[object Arguments]"]=Q["[object Array]"]=Q["[object ArrayBuffer]"]=Q["[object DataView]"]=Q["[object Boolean]"]=Q["[object Date]"]=Q["[object Float32Array]"]=Q["[object Float64Array]"]=Q["[object Int8Array]"]=Q["[object Int16Array]"]=Q["[object Int32Array]"]=Q["[object Map]"]=Q["[object Number]"]=Q["[object Object]"]=Q["[object RegExp]"]=Q["[object Set]"]=Q["[object String]"]=Q["[object Symbol]"]=Q["[object Uint8Array]"]=Q["[object Uint8ClampedArray]"]=Q["[object Uint16Array]"]=Q["[object Uint32Array]"]=!0,Q["[object Error]"]=Q["[object Function]"]=Q["[object WeakMap]"]=!1,e.exports=function e(t,r,D,b,v,S){var k,N=1&r,F=2&r,K=4&r;if(D&&(k=v?D(t,b,v,S):D(t)),void 0!==k)return k;if(!y(t))return t;var M=I(t);if(M){if(k=d(t),!N)return c(t,k)}else{var R=p(t),x="[object Function]"==R||"[object GeneratorFunction]"==R;if(E(t))return a(t,N);if("[object Object]"==R||"[object Arguments]"==R||x&&!v){if(k=F||x?{}:f(t),!N)return F?l(t,s(k,t)):g(t,i(k,t))}else{if(!Q[R])return v?t:{};k=C(t,R,N)}}S||(S=new A);var L=S.get(t);if(L)return L;S.set(t,k),m(t)?t.forEach((function(A){k.add(e(A,r,D,A,t,S))})):B(t)&&t.forEach((function(A,n){k.set(n,e(A,r,D,n,t,S))}));var P=K?F?h:u:F?keysIn:w,O=M?void 0:P(t);return n(O||t,(function(A,n){O&&(A=t[n=A]),o(k,n,e(A,r,D,n,t,S))})),k}},15178:(e,t,r)=>{var A=r(46778),n=Object.create,o=function(){function e(){}return function(t){if(!A(t))return{};if(n)return n(t);e.prototype=t;var r=new e;return e.prototype=void 0,r}}();e.exports=o},93274:(e,t,r)=>{var A=r(40945),n=r(958);e.exports=function e(t,r,o,i,s){var a=-1,c=t.length;for(o||(o=n),s||(s=[]);++a0&&o(g)?r>1?e(g,r-1,o,i,s):A(s,g):i||(s[s.length]=g)}return s}},31689:(e,t,r)=>{var A=r(59907)();e.exports=A},62164:(e,t,r)=>{var A=r(31689),n=r(42185);e.exports=function(e,t){return e&&A(e,t,n)}},84173:(e,t,r)=>{var A=r(56725),n=r(49874);e.exports=function(e,t){for(var r=0,o=(t=A(t,e)).length;null!=e&&r{var A=r(40945),n=r(82664);e.exports=function(e,t,r){var o=t(e);return n(e)?o:A(o,r(e))}},52502:(e,t,r)=>{var A=r(69976),n=r(2854),o=r(87427),i=A?A.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":i&&i in Object(e)?n(e):o(e)}},95325:e=>{var t=Object.prototype.hasOwnProperty;e.exports=function(e,r){return null!=e&&t.call(e,r)}},3881:e=>{e.exports=function(e,t){return null!=e&&t in Object(e)}},76357:(e,t,r)=>{var A=r(52502),n=r(38496);e.exports=function(e){return n(e)&&"[object Arguments]"==A(e)}},74195:(e,t,r)=>{var A=r(48957),n=r(38496);e.exports=function e(t,r,o,i,s){return t===r||(null==t||null==r||!n(t)&&!n(r)?t!=t&&r!=r:A(t,r,o,i,e,s))}},48957:(e,t,r)=>{var A=r(22851),n=r(75500),o=r(28475),i=r(50245),s=r(79435),a=r(82664),c=r(10667),g=r(32565),l="[object Object]",u=Object.prototype.hasOwnProperty;e.exports=function(e,t,r,h,p,d){var C=a(e),f=a(t),I=C?"[object Array]":s(e),E=f?"[object Array]":s(t),B=(I="[object Arguments]"==I?l:I)==l,y=(E="[object Arguments]"==E?l:E)==l,m=I==E;if(m&&c(e)){if(!c(t))return!1;C=!0,B=!1}if(m&&!B)return d||(d=new A),C||g(e)?n(e,t,r,h,p,d):o(e,t,I,r,h,p,d);if(!(1&r)){var w=B&&u.call(e,"__wrapped__"),Q=y&&u.call(t,"__wrapped__");if(w||Q){var D=w?e.value():e,b=Q?t.value():t;return d||(d=new A),p(D,b,r,h,d)}}return!!m&&(d||(d=new A),i(e,t,r,h,p,d))}},55994:(e,t,r)=>{var A=r(79435),n=r(38496);e.exports=function(e){return n(e)&&"[object Map]"==A(e)}},66470:(e,t,r)=>{var A=r(22851),n=r(74195);e.exports=function(e,t,r,o){var i=r.length,s=i,a=!o;if(null==e)return!s;for(e=Object(e);i--;){var c=r[i];if(a&&c[2]?c[1]!==e[c[0]]:!(c[0]in e))return!1}for(;++i{var A=r(92533),n=r(15061),o=r(46778),i=r(76384),s=/^\[object .+?Constructor\]$/,a=Function.prototype,c=Object.prototype,g=a.toString,l=c.hasOwnProperty,u=RegExp("^"+g.call(l).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");e.exports=function(e){return!(!o(e)||n(e))&&(A(e)?u:s).test(i(e))}},28612:(e,t,r)=>{var A=r(79435),n=r(38496);e.exports=function(e){return n(e)&&"[object Set]"==A(e)}},98998:(e,t,r)=>{var A=r(52502),n=r(46369),o=r(38496),i={};i["[object Float32Array]"]=i["[object Float64Array]"]=i["[object Int8Array]"]=i["[object Int16Array]"]=i["[object Int32Array]"]=i["[object Uint8Array]"]=i["[object Uint8ClampedArray]"]=i["[object Uint16Array]"]=i["[object Uint32Array]"]=!0,i["[object Arguments]"]=i["[object Array]"]=i["[object ArrayBuffer]"]=i["[object Boolean]"]=i["[object DataView]"]=i["[object Date]"]=i["[object Error]"]=i["[object Function]"]=i["[object Map]"]=i["[object Number]"]=i["[object Object]"]=i["[object RegExp]"]=i["[object Set]"]=i["[object String]"]=i["[object WeakMap]"]=!1,e.exports=function(e){return o(e)&&n(e.length)&&!!i[A(e)]}},42208:(e,t,r)=>{var A=r(96962),n=r(90348),o=r(61977),i=r(82664),s=r(7430);e.exports=function(e){return"function"==typeof e?e:null==e?o:"object"==typeof e?i(e)?n(e[0],e[1]):A(e):s(e)}},50994:(e,t,r)=>{var A=r(89513),n=r(60657),o=Object.prototype.hasOwnProperty;e.exports=function(e){if(!A(e))return n(e);var t=[];for(var r in Object(e))o.call(e,r)&&"constructor"!=r&&t.push(r);return t}},8372:(e,t,r)=>{var A=r(46778),n=r(89513),o=r(95632),i=Object.prototype.hasOwnProperty;e.exports=function(e){if(!A(e))return o(e);var t=n(e),r=[];for(var s in e)("constructor"!=s||!t&&i.call(e,s))&&r.push(s);return r}},96962:(e,t,r)=>{var A=r(66470),n=r(98705),o=r(12757);e.exports=function(e){var t=n(e);return 1==t.length&&t[0][2]?o(t[0][0],t[0][1]):function(r){return r===e||A(r,e,t)}}},90348:(e,t,r)=>{var A=r(74195),n=r(44674),o=r(34878),i=r(70474),s=r(20925),a=r(12757),c=r(49874);e.exports=function(e,t){return i(e)&&s(t)?a(c(e),t):function(r){var i=n(r,e);return void 0===i&&i===t?o(r,e):A(t,i,3)}}},51264:(e,t,r)=>{var A=r(22851),n=r(26943),o=r(31689),i=r(16834),s=r(46778),a=r(24887),c=r(36883);e.exports=function e(t,r,g,l,u){t!==r&&o(r,(function(o,a){if(u||(u=new A),s(o))i(t,r,a,g,e,l,u);else{var h=l?l(c(t,a),o,a+"",t,r,u):void 0;void 0===h&&(h=o),n(t,a,h)}}),a)}},16834:(e,t,r)=>{var A=r(26943),n=r(64266),o=r(58042),i=r(87229),s=r(88438),a=r(61771),c=r(82664),g=r(16064),l=r(10667),u=r(92533),h=r(46778),p=r(11672),d=r(32565),C=r(36883),f=r(36506);e.exports=function(e,t,r,I,E,B,y){var m=C(e,r),w=C(t,r),Q=y.get(w);if(Q)A(e,r,Q);else{var D=B?B(m,w,r+"",e,t,y):void 0,b=void 0===D;if(b){var v=c(w),S=!v&&l(w),k=!v&&!S&&d(w);D=w,v||S||k?c(m)?D=m:g(m)?D=i(m):S?(b=!1,D=n(w,!0)):k?(b=!1,D=o(w,!0)):D=[]:p(w)||a(w)?(D=m,a(m)?D=f(m):h(m)&&!u(m)||(D=s(w))):b=!1}b&&(y.set(w,D),E(D,w,I,B,y),y.delete(w)),A(e,r,D)}}},72204:(e,t,r)=>{var A=r(35314),n=r(34878);e.exports=function(e,t){return A(e,t,(function(t,r){return n(e,r)}))}},35314:(e,t,r)=>{var A=r(84173),n=r(10624),o=r(56725);e.exports=function(e,t,r){for(var i=-1,s=t.length,a={};++i{e.exports=function(e){return function(t){return null==t?void 0:t[e]}}},43018:(e,t,r)=>{var A=r(84173);e.exports=function(e){return function(t){return A(t,e)}}},51587:e=>{e.exports=function(e){return function(t){return null==e?void 0:e[t]}}},30383:(e,t,r)=>{var A=r(61977),n=r(44322),o=r(3111);e.exports=function(e,t){return o(n(e,t,A),e+"")}},10624:(e,t,r)=>{var A=r(65759),n=r(56725),o=r(98041),i=r(46778),s=r(49874);e.exports=function(e,t,r,a){if(!i(e))return e;for(var c=-1,g=(t=n(t,e)).length,l=g-1,u=e;null!=u&&++c{var A=r(4967),n=r(65),o=r(61977),i=n?function(e,t){return n(e,"toString",{configurable:!0,enumerable:!1,value:A(t),writable:!0})}:o;e.exports=i},27708:e=>{e.exports=function(e,t,r){var A=-1,n=e.length;t<0&&(t=-t>n?0:n+t),(r=r>n?n:r)<0&&(r+=n),n=t>r?0:r-t>>>0,t>>>=0;for(var o=Array(n);++A{e.exports=function(e,t){for(var r=-1,A=Array(e);++r{var A=r(69976),n=r(60783),o=r(82664),i=r(65558),s=A?A.prototype:void 0,a=s?s.toString:void 0;e.exports=function e(t){if("string"==typeof t)return t;if(o(t))return n(t,e)+"";if(i(t))return a?a.call(t):"";var r=t+"";return"0"==r&&1/t==-1/0?"-0":r}},73635:e=>{e.exports=function(e){return function(t){return e(t)}}},18290:(e,t,r)=>{var A=r(60783);e.exports=function(e,t){return A(t,(function(t){return e[t]}))}},93022:e=>{e.exports=function(e,t){return e.has(t)}},56725:(e,t,r)=>{var A=r(82664),n=r(70474),o=r(8689),i=r(33580);e.exports=function(e,t){return A(e)?e:n(e,t)?[e]:o(i(e))}},92568:(e,t,r)=>{var A=r(27708);e.exports=function(e,t,r){var n=e.length;return r=void 0===r?n:r,!t&&r>=n?e:A(e,t,r)}},76255:(e,t,r)=>{var A=r(2740);e.exports=function(e){var t=new e.constructor(e.byteLength);return new A(t).set(new A(e)),t}},64266:(e,t,r)=>{e=r.nmd(e);var A=r(76169),n=t&&!t.nodeType&&t,o=n&&e&&!e.nodeType&&e,i=o&&o.exports===n?A.Buffer:void 0,s=i?i.allocUnsafe:void 0;e.exports=function(e,t){if(t)return e.slice();var r=e.length,A=s?s(r):new e.constructor(r);return e.copy(A),A}},63749:(e,t,r)=>{var A=r(76255);e.exports=function(e,t){var r=t?A(e.buffer):e.buffer;return new e.constructor(r,e.byteOffset,e.byteLength)}},41705:e=>{var t=/\w*$/;e.exports=function(e){var r=new e.constructor(e.source,t.exec(e));return r.lastIndex=e.lastIndex,r}},25791:(e,t,r)=>{var A=r(69976),n=A?A.prototype:void 0,o=n?n.valueOf:void 0;e.exports=function(e){return o?Object(o.call(e)):{}}},58042:(e,t,r)=>{var A=r(76255);e.exports=function(e,t){var r=t?A(e.buffer):e.buffer;return new e.constructor(r,e.byteOffset,e.length)}},87229:e=>{e.exports=function(e,t){var r=-1,A=e.length;for(t||(t=Array(A));++r{var A=r(65759),n=r(91198);e.exports=function(e,t,r,o){var i=!r;r||(r={});for(var s=-1,a=t.length;++s{var A=r(75182),n=r(68727);e.exports=function(e,t){return A(e,n(e),t)}},60741:(e,t,r)=>{var A=r(75182),n=r(35368);e.exports=function(e,t){return A(e,n(e),t)}},14429:(e,t,r)=>{var A=r(76169)["__core-js_shared__"];e.exports=A},27913:(e,t,r)=>{var A=r(30383),n=r(33193);e.exports=function(e){return A((function(t,r){var A=-1,o=r.length,i=o>1?r[o-1]:void 0,s=o>2?r[2]:void 0;for(i=e.length>3&&"function"==typeof i?(o--,i):void 0,s&&n(r[0],r[1],s)&&(i=o<3?void 0:i,o=1),t=Object(t);++A{e.exports=function(e){return function(t,r,A){for(var n=-1,o=Object(t),i=A(t),s=i.length;s--;){var a=i[e?s:++n];if(!1===r(o[a],a,o))break}return t}}},56989:(e,t,r)=>{var A=r(92568),n=r(93024),o=r(30475),i=r(33580);e.exports=function(e){return function(t){t=i(t);var r=n(t)?o(t):void 0,s=r?r[0]:t.charAt(0),a=r?A(r,1).join(""):t.slice(1);return s[e]()+a}}},30369:(e,t,r)=>{var A=r(66054),n=r(68968),o=r(97684),i=RegExp("['’]","g");e.exports=function(e){return function(t){return A(o(n(t).replace(i,"")),e,"")}}},69922:(e,t,r)=>{var A=r(51587)({À:"A",Á:"A",Â:"A",Ã:"A",Ä:"A",Å:"A",à:"a",á:"a",â:"a",ã:"a",ä:"a",å:"a",Ç:"C",ç:"c",Ð:"D",ð:"d",È:"E",É:"E",Ê:"E",Ë:"E",è:"e",é:"e",ê:"e",ë:"e",Ì:"I",Í:"I",Î:"I",Ï:"I",ì:"i",í:"i",î:"i",ï:"i",Ñ:"N",ñ:"n",Ò:"O",Ó:"O",Ô:"O",Õ:"O",Ö:"O",Ø:"O",ò:"o",ó:"o",ô:"o",õ:"o",ö:"o",ø:"o",Ù:"U",Ú:"U",Û:"U",Ü:"U",ù:"u",ú:"u",û:"u",ü:"u",Ý:"Y",ý:"y",ÿ:"y",Æ:"Ae",æ:"ae",Þ:"Th",þ:"th",ß:"ss",Ā:"A",Ă:"A",Ą:"A",ā:"a",ă:"a",ą:"a",Ć:"C",Ĉ:"C",Ċ:"C",Č:"C",ć:"c",ĉ:"c",ċ:"c",č:"c",Ď:"D",Đ:"D",ď:"d",đ:"d",Ē:"E",Ĕ:"E",Ė:"E",Ę:"E",Ě:"E",ē:"e",ĕ:"e",ė:"e",ę:"e",ě:"e",Ĝ:"G",Ğ:"G",Ġ:"G",Ģ:"G",ĝ:"g",ğ:"g",ġ:"g",ģ:"g",Ĥ:"H",Ħ:"H",ĥ:"h",ħ:"h",Ĩ:"I",Ī:"I",Ĭ:"I",Į:"I",İ:"I",ĩ:"i",ī:"i",ĭ:"i",į:"i",ı:"i",Ĵ:"J",ĵ:"j",Ķ:"K",ķ:"k",ĸ:"k",Ĺ:"L",Ļ:"L",Ľ:"L",Ŀ:"L",Ł:"L",ĺ:"l",ļ:"l",ľ:"l",ŀ:"l",ł:"l",Ń:"N",Ņ:"N",Ň:"N",Ŋ:"N",ń:"n",ņ:"n",ň:"n",ŋ:"n",Ō:"O",Ŏ:"O",Ő:"O",ō:"o",ŏ:"o",ő:"o",Ŕ:"R",Ŗ:"R",Ř:"R",ŕ:"r",ŗ:"r",ř:"r",Ś:"S",Ŝ:"S",Ş:"S",Š:"S",ś:"s",ŝ:"s",ş:"s",š:"s",Ţ:"T",Ť:"T",Ŧ:"T",ţ:"t",ť:"t",ŧ:"t",Ũ:"U",Ū:"U",Ŭ:"U",Ů:"U",Ű:"U",Ų:"U",ũ:"u",ū:"u",ŭ:"u",ů:"u",ű:"u",ų:"u",Ŵ:"W",ŵ:"w",Ŷ:"Y",ŷ:"y",Ÿ:"Y",Ź:"Z",Ż:"Z",Ž:"Z",ź:"z",ż:"z",ž:"z",IJ:"IJ",ij:"ij",Œ:"Oe",œ:"oe",ʼn:"'n",ſ:"s"});e.exports=A},65:(e,t,r)=>{var A=r(99513),n=function(){try{var e=A(Object,"defineProperty");return e({},"",{}),e}catch(e){}}();e.exports=n},75500:(e,t,r)=>{var A=r(46235),n=r(17765),o=r(93022);e.exports=function(e,t,r,i,s,a){var c=1&r,g=e.length,l=t.length;if(g!=l&&!(c&&l>g))return!1;var u=a.get(e);if(u&&a.get(t))return u==t;var h=-1,p=!0,d=2&r?new A:void 0;for(a.set(e,t),a.set(t,e);++h{var A=r(69976),n=r(2740),o=r(71074),i=r(75500),s=r(7877),a=r(7442),c=A?A.prototype:void 0,g=c?c.valueOf:void 0;e.exports=function(e,t,r,A,c,l,u){switch(r){case"[object DataView]":if(e.byteLength!=t.byteLength||e.byteOffset!=t.byteOffset)return!1;e=e.buffer,t=t.buffer;case"[object ArrayBuffer]":return!(e.byteLength!=t.byteLength||!l(new n(e),new n(t)));case"[object Boolean]":case"[object Date]":case"[object Number]":return o(+e,+t);case"[object Error]":return e.name==t.name&&e.message==t.message;case"[object RegExp]":case"[object String]":return e==t+"";case"[object Map]":var h=s;case"[object Set]":var p=1&A;if(h||(h=a),e.size!=t.size&&!p)return!1;var d=u.get(e);if(d)return d==t;A|=2,u.set(e,t);var C=i(h(e),h(t),A,c,l,u);return u.delete(e),C;case"[object Symbol]":if(g)return g.call(e)==g.call(t)}return!1}},50245:(e,t,r)=>{var A=r(60753),n=Object.prototype.hasOwnProperty;e.exports=function(e,t,r,o,i,s){var a=1&r,c=A(e),g=c.length;if(g!=A(t).length&&!a)return!1;for(var l=g;l--;){var u=c[l];if(!(a?u in t:n.call(t,u)))return!1}var h=s.get(e);if(h&&s.get(t))return h==t;var p=!0;s.set(e,t),s.set(t,e);for(var d=a;++l{var A=r(54690),n=r(44322),o=r(3111);e.exports=function(e){return o(n(e,void 0,A),e+"")}},68399:e=>{var t="object"==typeof global&&global&&global.Object===Object&&global;e.exports=t},60753:(e,t,r)=>{var A=r(40104),n=r(68727),o=r(42185);e.exports=function(e){return A(e,o,n)}},64420:(e,t,r)=>{var A=r(40104),n=r(35368),o=r(24887);e.exports=function(e){return A(e,o,n)}},59253:(e,t,r)=>{var A=r(69448);e.exports=function(e,t){var r=e.__data__;return A(t)?r["string"==typeof t?"string":"hash"]:r.map}},98705:(e,t,r)=>{var A=r(20925),n=r(42185);e.exports=function(e){for(var t=n(e),r=t.length;r--;){var o=t[r],i=e[o];t[r]=[o,i,A(i)]}return t}},99513:(e,t,r)=>{var A=r(91686),n=r(98054);e.exports=function(e,t){var r=n(e,t);return A(r)?r:void 0}},41181:(e,t,r)=>{var A=r(64309)(Object.getPrototypeOf,Object);e.exports=A},2854:(e,t,r)=>{var A=r(69976),n=Object.prototype,o=n.hasOwnProperty,i=n.toString,s=A?A.toStringTag:void 0;e.exports=function(e){var t=o.call(e,s),r=e[s];try{e[s]=void 0;var A=!0}catch(e){}var n=i.call(e);return A&&(t?e[s]=r:delete e[s]),n}},68727:(e,t,r)=>{var A=r(9073),n=r(62162),o=Object.prototype.propertyIsEnumerable,i=Object.getOwnPropertySymbols,s=i?function(e){return null==e?[]:(e=Object(e),A(i(e),(function(t){return o.call(e,t)})))}:n;e.exports=s},35368:(e,t,r)=>{var A=r(40945),n=r(41181),o=r(68727),i=r(62162),s=Object.getOwnPropertySymbols?function(e){for(var t=[];e;)A(t,o(e)),e=n(e);return t}:i;e.exports=s},79435:(e,t,r)=>{var A=r(78962),n=r(63603),o=r(5825),i=r(43231),s=r(47063),a=r(52502),c=r(76384),g=c(A),l=c(n),u=c(o),h=c(i),p=c(s),d=a;(A&&"[object DataView]"!=d(new A(new ArrayBuffer(1)))||n&&"[object Map]"!=d(new n)||o&&"[object Promise]"!=d(o.resolve())||i&&"[object Set]"!=d(new i)||s&&"[object WeakMap]"!=d(new s))&&(d=function(e){var t=a(e),r="[object Object]"==t?e.constructor:void 0,A=r?c(r):"";if(A)switch(A){case g:return"[object DataView]";case l:return"[object Map]";case u:return"[object Promise]";case h:return"[object Set]";case p:return"[object WeakMap]"}return t}),e.exports=d},98054:e=>{e.exports=function(e,t){return null==e?void 0:e[t]}},71507:(e,t,r)=>{var A=r(56725),n=r(61771),o=r(82664),i=r(98041),s=r(46369),a=r(49874);e.exports=function(e,t,r){for(var c=-1,g=(t=A(t,e)).length,l=!1;++c{var t=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]");e.exports=function(e){return t.test(e)}},60466:e=>{var t=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;e.exports=function(e){return t.test(e)}},31713:(e,t,r)=>{var A=r(52437);e.exports=function(){this.__data__=A?A(null):{},this.size=0}},86688:e=>{e.exports=function(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}},45937:(e,t,r)=>{var A=r(52437),n=Object.prototype.hasOwnProperty;e.exports=function(e){var t=this.__data__;if(A){var r=t[e];return"__lodash_hash_undefined__"===r?void 0:r}return n.call(t,e)?t[e]:void 0}},5017:(e,t,r)=>{var A=r(52437),n=Object.prototype.hasOwnProperty;e.exports=function(e){var t=this.__data__;return A?void 0!==t[e]:n.call(t,e)}},79457:(e,t,r)=>{var A=r(52437);e.exports=function(e,t){var r=this.__data__;return this.size+=this.has(e)?0:1,r[e]=A&&void 0===t?"__lodash_hash_undefined__":t,this}},27908:e=>{var t=Object.prototype.hasOwnProperty;e.exports=function(e){var r=e.length,A=new e.constructor(r);return r&&"string"==typeof e[0]&&t.call(e,"index")&&(A.index=e.index,A.input=e.input),A}},37836:(e,t,r)=>{var A=r(76255),n=r(63749),o=r(41705),i=r(25791),s=r(58042);e.exports=function(e,t,r){var a=e.constructor;switch(t){case"[object ArrayBuffer]":return A(e);case"[object Boolean]":case"[object Date]":return new a(+e);case"[object DataView]":return n(e,r);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return s(e,r);case"[object Map]":return new a;case"[object Number]":case"[object String]":return new a(e);case"[object RegExp]":return o(e);case"[object Set]":return new a;case"[object Symbol]":return i(e)}}},88438:(e,t,r)=>{var A=r(15178),n=r(41181),o=r(89513);e.exports=function(e){return"function"!=typeof e.constructor||o(e)?{}:A(n(e))}},958:(e,t,r)=>{var A=r(69976),n=r(61771),o=r(82664),i=A?A.isConcatSpreadable:void 0;e.exports=function(e){return o(e)||n(e)||!!(i&&e&&e[i])}},98041:e=>{var t=/^(?:0|[1-9]\d*)$/;e.exports=function(e,r){var A=typeof e;return!!(r=null==r?9007199254740991:r)&&("number"==A||"symbol"!=A&&t.test(e))&&e>-1&&e%1==0&&e{var A=r(71074),n=r(41929),o=r(98041),i=r(46778);e.exports=function(e,t,r){if(!i(r))return!1;var s=typeof t;return!!("number"==s?n(r)&&o(t,r.length):"string"==s&&t in r)&&A(r[t],e)}},70474:(e,t,r)=>{var A=r(82664),n=r(65558),o=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,i=/^\w*$/;e.exports=function(e,t){if(A(e))return!1;var r=typeof e;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=e&&!n(e))||(i.test(e)||!o.test(e)||null!=t&&e in Object(t))}},69448:e=>{e.exports=function(e){var t=typeof e;return"string"==t||"number"==t||"symbol"==t||"boolean"==t?"__proto__"!==e:null===e}},15061:(e,t,r)=>{var A,n=r(14429),o=(A=/[^.]+$/.exec(n&&n.keys&&n.keys.IE_PROTO||""))?"Symbol(src)_1."+A:"";e.exports=function(e){return!!o&&o in e}},89513:e=>{var t=Object.prototype;e.exports=function(e){var r=e&&e.constructor;return e===("function"==typeof r&&r.prototype||t)}},20925:(e,t,r)=>{var A=r(46778);e.exports=function(e){return e==e&&!A(e)}},82262:e=>{e.exports=function(e){for(var t,r=[];!(t=e.next()).done;)r.push(t.value);return r}},14620:e=>{e.exports=function(){this.__data__=[],this.size=0}},73682:(e,t,r)=>{var A=r(39836),n=Array.prototype.splice;e.exports=function(e){var t=this.__data__,r=A(t,e);return!(r<0)&&(r==t.length-1?t.pop():n.call(t,r,1),--this.size,!0)}},43112:(e,t,r)=>{var A=r(39836);e.exports=function(e){var t=this.__data__,r=A(t,e);return r<0?void 0:t[r][1]}},90640:(e,t,r)=>{var A=r(39836);e.exports=function(e){return A(this.__data__,e)>-1}},9380:(e,t,r)=>{var A=r(39836);e.exports=function(e,t){var r=this.__data__,n=A(r,e);return n<0?(++this.size,r.push([e,t])):r[n][1]=t,this}},18209:(e,t,r)=>{var A=r(72574),n=r(29197),o=r(63603);e.exports=function(){this.size=0,this.__data__={hash:new A,map:new(o||n),string:new A}}},89706:(e,t,r)=>{var A=r(59253);e.exports=function(e){var t=A(this,e).delete(e);return this.size-=t?1:0,t}},43786:(e,t,r)=>{var A=r(59253);e.exports=function(e){return A(this,e).get(e)}},17926:(e,t,r)=>{var A=r(59253);e.exports=function(e){return A(this,e).has(e)}},87345:(e,t,r)=>{var A=r(59253);e.exports=function(e,t){var r=A(this,e),n=r.size;return r.set(e,t),this.size+=r.size==n?0:1,this}},7877:e=>{e.exports=function(e){var t=-1,r=Array(e.size);return e.forEach((function(e,A){r[++t]=[A,e]})),r}},12757:e=>{e.exports=function(e,t){return function(r){return null!=r&&(r[e]===t&&(void 0!==t||e in Object(r)))}}},31948:(e,t,r)=>{var A=r(74499);e.exports=function(e){var t=A(e,(function(e){return 500===r.size&&r.clear(),e})),r=t.cache;return t}},52437:(e,t,r)=>{var A=r(99513)(Object,"create");e.exports=A},60657:(e,t,r)=>{var A=r(64309)(Object.keys,Object);e.exports=A},95632:e=>{e.exports=function(e){var t=[];if(null!=e)for(var r in Object(e))t.push(r);return t}},26391:(e,t,r)=>{e=r.nmd(e);var A=r(68399),n=t&&!t.nodeType&&t,o=n&&e&&!e.nodeType&&e,i=o&&o.exports===n&&A.process,s=function(){try{var e=o&&o.require&&o.require("util").types;return e||i&&i.binding&&i.binding("util")}catch(e){}}();e.exports=s},87427:e=>{var t=Object.prototype.toString;e.exports=function(e){return t.call(e)}},64309:e=>{e.exports=function(e,t){return function(r){return e(t(r))}}},44322:(e,t,r)=>{var A=r(66636),n=Math.max;e.exports=function(e,t,r){return t=n(void 0===t?e.length-1:t,0),function(){for(var o=arguments,i=-1,s=n(o.length-t,0),a=Array(s);++i{var A=r(68399),n="object"==typeof self&&self&&self.Object===Object&&self,o=A||n||Function("return this")();e.exports=o},36883:e=>{e.exports=function(e,t){if(("constructor"!==t||"function"!=typeof e[t])&&"__proto__"!=t)return e[t]}},74785:e=>{e.exports=function(e){return this.__data__.set(e,"__lodash_hash_undefined__"),this}},87760:e=>{e.exports=function(e){return this.__data__.has(e)}},7442:e=>{e.exports=function(e){var t=-1,r=Array(e.size);return e.forEach((function(e){r[++t]=e})),r}},3111:(e,t,r)=>{var A=r(4899),n=r(19908)(A);e.exports=n},19908:e=>{var t=Date.now;e.exports=function(e){var r=0,A=0;return function(){var n=t(),o=16-(n-A);if(A=n,o>0){if(++r>=800)return arguments[0]}else r=0;return e.apply(void 0,arguments)}}},35678:(e,t,r)=>{var A=r(29197);e.exports=function(){this.__data__=new A,this.size=0}},33336:e=>{e.exports=function(e){var t=this.__data__,r=t.delete(e);return this.size=t.size,r}},97163:e=>{e.exports=function(e){return this.__data__.get(e)}},43737:e=>{e.exports=function(e){return this.__data__.has(e)}},48548:(e,t,r)=>{var A=r(29197),n=r(63603),o=r(75009);e.exports=function(e,t){var r=this.__data__;if(r instanceof A){var i=r.__data__;if(!n||i.length<199)return i.push([e,t]),this.size=++r.size,this;r=this.__data__=new o(i)}return r.set(e,t),this.size=r.size,this}},30475:(e,t,r)=>{var A=r(1051),n=r(93024),o=r(297);e.exports=function(e){return n(e)?o(e):A(e)}},8689:(e,t,r)=>{var A=r(31948),n=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,o=/\\(\\)?/g,i=A((function(e){var t=[];return 46===e.charCodeAt(0)&&t.push(""),e.replace(n,(function(e,r,A,n){t.push(A?n.replace(o,"$1"):r||e)})),t}));e.exports=i},49874:(e,t,r)=>{var A=r(65558);e.exports=function(e){if("string"==typeof e||A(e))return e;var t=e+"";return"0"==t&&1/e==-1/0?"-0":t}},76384:e=>{var t=Function.prototype.toString;e.exports=function(e){if(null!=e){try{return t.call(e)}catch(e){}try{return e+""}catch(e){}}return""}},297:e=>{var t="[\\ud800-\\udfff]",r="[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]",A="\\ud83c[\\udffb-\\udfff]",n="[^\\ud800-\\udfff]",o="(?:\\ud83c[\\udde6-\\uddff]){2}",i="[\\ud800-\\udbff][\\udc00-\\udfff]",s="(?:"+r+"|"+A+")"+"?",a="[\\ufe0e\\ufe0f]?"+s+("(?:\\u200d(?:"+[n,o,i].join("|")+")[\\ufe0e\\ufe0f]?"+s+")*"),c="(?:"+[n+r+"?",r,o,i,t].join("|")+")",g=RegExp(A+"(?="+A+")|"+c+a,"g");e.exports=function(e){return e.match(g)||[]}},89887:e=>{var t="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",r="["+t+"]",A="\\d+",n="[\\u2700-\\u27bf]",o="[a-z\\xdf-\\xf6\\xf8-\\xff]",i="[^\\ud800-\\udfff"+t+A+"\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde]",s="(?:\\ud83c[\\udde6-\\uddff]){2}",a="[\\ud800-\\udbff][\\udc00-\\udfff]",c="[A-Z\\xc0-\\xd6\\xd8-\\xde]",g="(?:"+o+"|"+i+")",l="(?:"+c+"|"+i+")",u="(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?",h="[\\ufe0e\\ufe0f]?"+u+("(?:\\u200d(?:"+["[^\\ud800-\\udfff]",s,a].join("|")+")[\\ufe0e\\ufe0f]?"+u+")*"),p="(?:"+[n,s,a].join("|")+")"+h,d=RegExp([c+"?"+o+"+(?:['’](?:d|ll|m|re|s|t|ve))?(?="+[r,c,"$"].join("|")+")",l+"+(?:['’](?:D|LL|M|RE|S|T|VE))?(?="+[r,c+g,"$"].join("|")+")",c+"?"+g+"+(?:['’](?:d|ll|m|re|s|t|ve))?",c+"+(?:['’](?:D|LL|M|RE|S|T|VE))?","\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",A,p].join("|"),"g");e.exports=function(e){return e.match(d)||[]}},89170:(e,t,r)=>{var A=r(61814),n=r(30369)((function(e,t,r){return t=t.toLowerCase(),e+(r?A(t):t)}));e.exports=n},61814:(e,t,r)=>{var A=r(33580),n=r(72609);e.exports=function(e){return n(A(e).toLowerCase())}},82558:(e,t,r)=>{var A=r(41076);e.exports=function(e){return A(e,5)}},26052:(e,t,r)=>{var A=r(41076);e.exports=function(e,t){return A(e,5,t="function"==typeof t?t:void 0)}},4967:e=>{e.exports=function(e){return function(){return e}}},68968:(e,t,r)=>{var A=r(69922),n=r(33580),o=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,i=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g");e.exports=function(e){return(e=n(e))&&e.replace(o,A).replace(i,"")}},71074:e=>{e.exports=function(e,t){return e===t||e!=e&&t!=t}},54690:(e,t,r)=>{var A=r(93274);e.exports=function(e){return(null==e?0:e.length)?A(e,1):[]}},44674:(e,t,r)=>{var A=r(84173);e.exports=function(e,t,r){var n=null==e?void 0:A(e,t);return void 0===n?r:n}},15215:(e,t,r)=>{var A=r(95325),n=r(71507);e.exports=function(e,t){return null!=e&&n(e,t,A)}},34878:(e,t,r)=>{var A=r(3881),n=r(71507);e.exports=function(e,t){return null!=e&&n(e,t,A)}},61977:e=>{e.exports=function(e){return e}},61771:(e,t,r)=>{var A=r(76357),n=r(38496),o=Object.prototype,i=o.hasOwnProperty,s=o.propertyIsEnumerable,a=A(function(){return arguments}())?A:function(e){return n(e)&&i.call(e,"callee")&&!s.call(e,"callee")};e.exports=a},82664:e=>{var t=Array.isArray;e.exports=t},41929:(e,t,r)=>{var A=r(92533),n=r(46369);e.exports=function(e){return null!=e&&n(e.length)&&!A(e)}},16064:(e,t,r)=>{var A=r(41929),n=r(38496);e.exports=function(e){return n(e)&&A(e)}},10667:(e,t,r)=>{e=r.nmd(e);var A=r(76169),n=r(88988),o=t&&!t.nodeType&&t,i=o&&e&&!e.nodeType&&e,s=i&&i.exports===o?A.Buffer:void 0,a=(s?s.isBuffer:void 0)||n;e.exports=a},92533:(e,t,r)=>{var A=r(52502),n=r(46778);e.exports=function(e){if(!n(e))return!1;var t=A(e);return"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t}},46369:e=>{e.exports=function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}},13349:(e,t,r)=>{var A=r(55994),n=r(73635),o=r(26391),i=o&&o.isMap,s=i?n(i):A;e.exports=s},46778:e=>{e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},38496:e=>{e.exports=function(e){return null!=e&&"object"==typeof e}},11672:(e,t,r)=>{var A=r(52502),n=r(41181),o=r(38496),i=Function.prototype,s=Object.prototype,a=i.toString,c=s.hasOwnProperty,g=a.call(Object);e.exports=function(e){if(!o(e)||"[object Object]"!=A(e))return!1;var t=n(e);if(null===t)return!0;var r=c.call(t,"constructor")&&t.constructor;return"function"==typeof r&&r instanceof r&&a.call(r)==g}},33931:(e,t,r)=>{var A=r(28612),n=r(73635),o=r(26391),i=o&&o.isSet,s=i?n(i):A;e.exports=s},221:(e,t,r)=>{var A=r(52502),n=r(82664),o=r(38496);e.exports=function(e){return"string"==typeof e||!n(e)&&o(e)&&"[object String]"==A(e)}},65558:(e,t,r)=>{var A=r(52502),n=r(38496);e.exports=function(e){return"symbol"==typeof e||n(e)&&"[object Symbol]"==A(e)}},32565:(e,t,r)=>{var A=r(98998),n=r(73635),o=r(26391),i=o&&o.isTypedArray,s=i?n(i):A;e.exports=s},42185:(e,t,r)=>{var A=r(11886),n=r(50994),o=r(41929);e.exports=function(e){return o(e)?A(e):n(e)}},24887:(e,t,r)=>{var A=r(11886),n=r(8372),o=r(41929);e.exports=function(e){return o(e)?A(e,!0):n(e)}},5253:(e,t,r)=>{var A=r(91198),n=r(62164),o=r(42208);e.exports=function(e,t){var r={};return t=o(t,3),n(e,(function(e,n,o){A(r,t(e,n,o),e)})),r}},89612:(e,t,r)=>{var A=r(91198),n=r(62164),o=r(42208);e.exports=function(e,t){var r={};return t=o(t,3),n(e,(function(e,n,o){A(r,n,t(e,n,o))})),r}},74499:(e,t,r)=>{var A=r(75009);function n(e,t){if("function"!=typeof e||null!=t&&"function"!=typeof t)throw new TypeError("Expected a function");var r=function(){var A=arguments,n=t?t.apply(this,A):A[0],o=r.cache;if(o.has(n))return o.get(n);var i=e.apply(this,A);return r.cache=o.set(n,i)||o,i};return r.cache=new(n.Cache||A),r}n.Cache=A,e.exports=n},80305:(e,t,r)=>{var A=r(51264),n=r(27913)((function(e,t,r){A(e,t,r)}));e.exports=n},75130:(e,t,r)=>{var A=r(72204),n=r(87298)((function(e,t){return null==e?{}:A(e,t)}));e.exports=n},7430:(e,t,r)=>{var A=r(35400),n=r(43018),o=r(70474),i=r(49874);e.exports=function(e){return o(e)?A(i(e)):n(e)}},81534:(e,t,r)=>{var A=r(10624);e.exports=function(e,t,r){return null==e?e:A(e,t,r)}},36494:(e,t,r)=>{var A=r(30369)((function(e,t,r){return e+(r?"_":"")+t.toLowerCase()}));e.exports=A},62162:e=>{e.exports=function(){return[]}},88988:e=>{e.exports=function(){return!1}},78700:(e,t,r)=>{var A=r(69976),n=r(87229),o=r(79435),i=r(41929),s=r(221),a=r(82262),c=r(7877),g=r(7442),l=r(30475),u=r(24448),h=A?A.iterator:void 0;e.exports=function(e){if(!e)return[];if(i(e))return s(e)?l(e):n(e);if(h&&e[h])return a(e[h]());var t=o(e);return("[object Map]"==t?c:"[object Set]"==t?g:u)(e)}},36506:(e,t,r)=>{var A=r(75182),n=r(24887);e.exports=function(e){return A(e,n(e))}},33580:(e,t,r)=>{var A=r(35);e.exports=function(e){return null==e?"":A(e)}},72609:(e,t,r)=>{var A=r(56989)("toUpperCase");e.exports=A},24448:(e,t,r)=>{var A=r(18290),n=r(42185);e.exports=function(e){return null==e?[]:A(e,n(e))}},97684:(e,t,r)=>{var A=r(11852),n=r(60466),o=r(33580),i=r(89887);e.exports=function(e,t,r){return e=o(e),void 0===(t=r?void 0:t)?n(e)?i(e):A(e):e.match(t)||[]}},55737:e=>{"use strict";e.exports=e=>{const t={};for(const[r,A]of Object.entries(e))t[r.toLowerCase()]=A;return t}},46227:(e,t,r)=>{"use strict";const A=r(35747),n=r(85622),{promisify:o}=r(31669),i=r(95584).satisfies(process.version,">=10.12.0"),s=e=>{if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(n.parse(e).root,""))){const t=new Error("Path contains invalid characters: "+e);throw t.code="EINVAL",t}}},a=e=>({...{mode:511,fs:A},...e}),c=e=>{const t=new Error(`operation not permitted, mkdir '${e}'`);return t.code="EPERM",t.errno=-4048,t.path=e,t.syscall="mkdir",t};e.exports=async(e,t)=>{s(e),t=a(t);const r=o(t.fs.mkdir),g=o(t.fs.stat);if(i&&t.fs.mkdir===A.mkdir){const A=n.resolve(e);return await r(A,{mode:t.mode,recursive:!0}),A}const l=async e=>{try{return await r(e,t.mode),e}catch(t){if("EPERM"===t.code)throw t;if("ENOENT"===t.code){if(n.dirname(e)===e)throw c(e);if(t.message.includes("null bytes"))throw t;return await l(n.dirname(e)),l(e)}try{if(!(await g(e)).isDirectory())throw new Error("The path is not a directory")}catch(e){throw t}return e}};return l(n.resolve(e))},e.exports.sync=(e,t)=>{if(s(e),t=a(t),i&&t.fs.mkdirSync===A.mkdirSync){const r=n.resolve(e);return A.mkdirSync(r,{mode:t.mode,recursive:!0}),r}const r=e=>{try{t.fs.mkdirSync(e,t.mode)}catch(A){if("EPERM"===A.code)throw A;if("ENOENT"===A.code){if(n.dirname(e)===e)throw c(e);if(A.message.includes("null bytes"))throw A;return r(n.dirname(e)),r(e)}try{if(!t.fs.statSync(e).isDirectory())throw new Error("The path is not a directory")}catch(e){throw A}}return e};return r(n.resolve(e))}},55598:(e,t,r)=>{"use strict";const A=r(92413).PassThrough,n=Array.prototype.slice;function o(e,t){if(Array.isArray(e))for(let r=0,A=e.length;r0||(t=!1,g())}function o(e){function t(){e.removeListener("merge2UnpipeEnd",t),e.removeListener("end",t),n()}if(e._readableState.endEmitted)return n();e.on("merge2UnpipeEnd",t),e.on("end",t),e.pipe(a,{end:!1}),e.resume()}for(let e=0;e{"use strict";const A=r(31669),n=r(12235),o=r(54722),i=r(3598),s=e=>"string"==typeof e&&(""===e||"./"===e),a=(e,t,r)=>{t=[].concat(t),e=[].concat(e);let A=new Set,n=new Set,i=new Set,s=0,a=e=>{i.add(e.output),r&&r.onResult&&r.onResult(e)};for(let i=0;i!A.has(e));if(r&&0===c.length){if(!0===r.failglob)throw new Error(`No matches found for "${t.join(", ")}"`);if(!0===r.nonull||!0===r.nullglob)return r.unescape?t.map(e=>e.replace(/\\/g,"")):t}return c};a.match=a,a.matcher=(e,t)=>o(e,t),a.any=a.isMatch=(e,t,r)=>o(t,r)(e),a.not=(e,t,r={})=>{t=[].concat(t).map(String);let A=new Set,n=[],o=a(e,t,{...r,onResult:e=>{r.onResult&&r.onResult(e),n.push(e.output)}});for(let e of n)o.includes(e)||A.add(e);return[...A]},a.contains=(e,t,r)=>{if("string"!=typeof e)throw new TypeError(`Expected a string: "${A.inspect(e)}"`);if(Array.isArray(t))return t.some(t=>a.contains(e,t,r));if("string"==typeof t){if(s(e)||s(t))return!1;if(e.includes(t)||e.startsWith("./")&&e.slice(2).includes(t))return!0}return a.isMatch(e,t,{...r,contains:!0})},a.matchKeys=(e,t,r)=>{if(!i.isObject(e))throw new TypeError("Expected the first argument to be an object");let A=a(Object.keys(e),t,r),n={};for(let t of A)n[t]=e[t];return n},a.some=(e,t,r)=>{let A=[].concat(e);for(let e of[].concat(t)){let t=o(String(e),r);if(A.some(e=>t(e)))return!0}return!1},a.every=(e,t,r)=>{let A=[].concat(e);for(let e of[].concat(t)){let t=o(String(e),r);if(!A.every(e=>t(e)))return!1}return!0},a.all=(e,t,r)=>{if("string"!=typeof e)throw new TypeError(`Expected a string: "${A.inspect(e)}"`);return[].concat(t).every(t=>o(t,r)(e))},a.capture=(e,t,r)=>{let A=i.isWindows(r),n=o.makeRe(String(e),{...r,capture:!0}).exec(A?i.toPosixSlashes(t):t);if(n)return n.slice(1).map(e=>void 0===e?"":e)},a.makeRe=(...e)=>o.makeRe(...e),a.scan=(...e)=>o.scan(...e),a.parse=(e,t)=>{let r=[];for(let A of[].concat(e||[]))for(let e of n(String(A),t))r.push(o.parse(e,t));return r},a.braces=(e,t)=>{if("string"!=typeof e)throw new TypeError("Expected a string");return t&&!0===t.nobrace||!/\{.*\}/.test(e)?[e]:n(e,t)},a.braceExpand=(e,t)=>{if("string"!=typeof e)throw new TypeError("Expected a string");return a.braces(e,{...t,expand:!0})},e.exports=a},65007:e=>{"use strict";const t=["destroy","setTimeout","socket","headers","trailers","rawHeaders","statusCode","httpVersion","httpVersionMinor","httpVersionMajor","rawTrailers","statusMessage"];e.exports=(e,r)=>{const A=new Set(Object.keys(e).concat(t));for(const t of A)t in r||(r[t]="function"==typeof e[t]?e[t].bind(e):e[t])}},33527:e=>{"use strict";const t=["aborted","complete","headers","httpVersion","httpVersionMinor","httpVersionMajor","method","rawHeaders","rawTrailers","setTimeout","socket","statusCode","statusMessage","trailers","url"];e.exports=(e,r)=>{if(r._readableState.autoDestroy)throw new Error("The second stream must have the `autoDestroy` option set to `false`");const A=new Set(Object.keys(e).concat(t)),n={};for(const t of A)t in r||(n[t]={get(){const r=e[t];return"function"==typeof r?r.bind(e):r},set(r){e[t]=r},enumerable:!0,configurable:!1});return Object.defineProperties(r,n),e.once("aborted",()=>{r.destroy(),r.emit("aborted")}),e.once("close",()=>{e.complete&&r.readable?r.once("end",()=>{r.emit("close")}):r.emit("close")}),r}},19793:(e,t,r)=>{"use strict";const A="undefined"==typeof URL?r(78835).URL:URL,n=(e,t)=>t.some(t=>t instanceof RegExp?t.test(e):t===e),o=(e,t)=>{if(t={defaultProtocol:"http:",normalizeProtocol:!0,forceHttp:!1,forceHttps:!1,stripAuthentication:!0,stripHash:!1,stripWWW:!0,removeQueryParameters:[/^utm_\w+/i],removeTrailingSlash:!0,removeDirectoryIndex:!1,sortQueryParameters:!0,...t},Reflect.has(t,"normalizeHttps"))throw new Error("options.normalizeHttps is renamed to options.forceHttp");if(Reflect.has(t,"normalizeHttp"))throw new Error("options.normalizeHttp is renamed to options.forceHttps");if(Reflect.has(t,"stripFragment"))throw new Error("options.stripFragment is renamed to options.stripHash");if(e=e.trim(),/^data:/i.test(e))return((e,{stripHash:t})=>{const r=e.match(/^data:(.*?),(.*?)(?:#(.*))?$/);if(!r)throw new Error("Invalid URL: "+e);const A=r[1].split(";"),n=r[2],o=t?"":r[3];let i=!1;"base64"===A[A.length-1]&&(A.pop(),i=!0);const s=(A.shift()||"").toLowerCase(),a=[...A.map(e=>{let[t,r=""]=e.split("=").map(e=>e.trim());return"charset"===t&&(r=r.toLowerCase(),"us-ascii"===r)?"":`${t}${r?"="+r:""}`}).filter(Boolean)];return i&&a.push("base64"),(0!==a.length||s&&"text/plain"!==s)&&a.unshift(s),`data:${a.join(";")},${i?n.trim():n}${o?"#"+o:""}`})(e,t);const r=e.startsWith("//");!r&&/^\.*\//.test(e)||(e=e.replace(/^(?!(?:\w+:)?\/\/)|^\/\//,t.defaultProtocol));const o=new A(e);if(t.forceHttp&&t.forceHttps)throw new Error("The `forceHttp` and `forceHttps` options cannot be used together");if(t.forceHttp&&"https:"===o.protocol&&(o.protocol="http:"),t.forceHttps&&"http:"===o.protocol&&(o.protocol="https:"),t.stripAuthentication&&(o.username="",o.password=""),t.stripHash&&(o.hash=""),o.pathname&&(o.pathname=o.pathname.replace(/((?!:).|^)\/{2,}/g,(e,t)=>/^(?!\/)/g.test(t)?t+"/":"/")),o.pathname&&(o.pathname=decodeURI(o.pathname)),!0===t.removeDirectoryIndex&&(t.removeDirectoryIndex=[/^index\.[a-z]+$/]),Array.isArray(t.removeDirectoryIndex)&&t.removeDirectoryIndex.length>0){let e=o.pathname.split("/");const r=e[e.length-1];n(r,t.removeDirectoryIndex)&&(e=e.slice(0,e.length-1),o.pathname=e.slice(1).join("/")+"/")}if(o.hostname&&(o.hostname=o.hostname.replace(/\.$/,""),t.stripWWW&&/^www\.([a-z\-\d]{2,63})\.([a-z.]{2,5})$/.test(o.hostname)&&(o.hostname=o.hostname.replace(/^www\./,""))),Array.isArray(t.removeQueryParameters))for(const e of[...o.searchParams.keys()])n(e,t.removeQueryParameters)&&o.searchParams.delete(e);return t.sortQueryParameters&&o.searchParams.sort(),t.removeTrailingSlash&&(o.pathname=o.pathname.replace(/\/$/,"")),e=o.toString(),!t.removeTrailingSlash&&"/"!==o.pathname||""!==o.hash||(e=e.replace(/\/$/,"")),r&&!t.normalizeProtocol&&(e=e.replace(/^http:\/\//,"//")),t.stripProtocol&&(e=e.replace(/^(?:https?:)?\/\//,"")),e};e.exports=o,e.exports.default=o},91162:(e,t,r)=>{var A=r(98984);function n(e){var t=function(){return t.called?t.value:(t.called=!0,t.value=e.apply(this,arguments))};return t.called=!1,t}e.exports=A(n),n.proto=n((function(){Object.defineProperty(Function.prototype,"once",{value:function(){return n(this)},configurable:!0})}))},27180:(e,t,r)=>{var A=r(98984);function n(e){var t=function(){return t.called?t.value:(t.called=!0,t.value=e.apply(this,arguments))};return t.called=!1,t}function o(e){var t=function(){if(t.called)throw new Error(t.onceError);return t.called=!0,t.value=e.apply(this,arguments)},r=e.name||"Function wrapped with `once`";return t.onceError=r+" shouldn't be called more than once",t.called=!1,t}e.exports=A(n),e.exports.strict=A(o),n.proto=n((function(){Object.defineProperty(Function.prototype,"once",{value:function(){return n(this)},configurable:!0}),Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return o(this)},configurable:!0})}))},59351:e=>{"use strict";class t extends Error{constructor(e){super(e||"Promise was canceled"),this.name="CancelError"}get isCanceled(){return!0}}class r{static fn(e){return(...t)=>new r((r,A,n)=>{t.push(n),e(...t).then(r,A)})}constructor(e){this._cancelHandlers=[],this._isPending=!0,this._isCanceled=!1,this._rejectOnCancel=!0,this._promise=new Promise((t,r)=>{this._reject=r;const A=e=>{if(!this._isPending)throw new Error("The `onCancel` handler was attached after the promise settled.");this._cancelHandlers.push(e)};return Object.defineProperties(A,{shouldReject:{get:()=>this._rejectOnCancel,set:e=>{this._rejectOnCancel=e}}}),e(e=>{this._isPending=!1,t(e)},e=>{this._isPending=!1,r(e)},A)})}then(e,t){return this._promise.then(e,t)}catch(e){return this._promise.catch(e)}finally(e){return this._promise.finally(e)}cancel(e){if(this._isPending&&!this._isCanceled){if(this._cancelHandlers.length>0)try{for(const e of this._cancelHandlers)e()}catch(e){this._reject(e)}this._isCanceled=!0,this._rejectOnCancel&&this._reject(new t(e))}}get isCanceled(){return this._isCanceled}}Object.setPrototypeOf(r.prototype,Promise.prototype),e.exports=r,e.exports.CancelError=t},61578:(e,t,r)=>{"use strict";const A=r(60550),n=e=>{if(e<1)throw new TypeError("Expected `concurrency` to be a number from 1 and up");const t=[];let r=0;const n=()=>{r--,t.length>0&&t.shift()()},o=(e,t,...o)=>{r++;const i=A(e,...o);t(i),i.then(n,n)},i=(A,...n)=>new Promise(i=>((A,n,...i)=>{rr},pendingCount:{get:()=>t.length}}),i};e.exports=n,e.exports.default=n},60550:e=>{"use strict";e.exports=(e,...t)=>new Promise(r=>{r(e(...t))})},37127:e=>{"use strict";const t=(e={})=>{const t=e.env||process.env;return"win32"!==(e.platform||process.platform)?"PATH":Object.keys(t).reverse().find(e=>"PATH"===e.toUpperCase())||"Path"};e.exports=t,e.exports.default=t},5763:(e,t,r)=>{"use strict";const{promisify:A}=r(31669),n=r(35747);async function o(e,t,r){if("string"!=typeof r)throw new TypeError("Expected a string, got "+typeof r);try{return(await A(n[e])(r))[t]()}catch(e){if("ENOENT"===e.code)return!1;throw e}}function i(e,t,r){if("string"!=typeof r)throw new TypeError("Expected a string, got "+typeof r);try{return n[e](r)[t]()}catch(e){if("ENOENT"===e.code)return!1;throw e}}t.isFile=o.bind(null,"stat","isFile"),t.isDirectory=o.bind(null,"stat","isDirectory"),t.isSymlink=o.bind(null,"lstat","isSymbolicLink"),t.isFileSync=i.bind(null,"statSync","isFile"),t.isDirectorySync=i.bind(null,"statSync","isDirectory"),t.isSymlinkSync=i.bind(null,"lstatSync","isSymbolicLink")},54722:(e,t,r)=>{"use strict";e.exports=r(18828)},71086:(e,t,r)=>{"use strict";const A=r(85622),n={DOT_LITERAL:"\\.",PLUS_LITERAL:"\\+",QMARK_LITERAL:"\\?",SLASH_LITERAL:"\\/",ONE_CHAR:"(?=.)",QMARK:"[^/]",END_ANCHOR:"(?:\\/|$)",DOTS_SLASH:"\\.{1,2}(?:\\/|$)",NO_DOT:"(?!\\.)",NO_DOTS:"(?!(?:^|\\/)\\.{1,2}(?:\\/|$))",NO_DOT_SLASH:"(?!\\.{0,1}(?:\\/|$))",NO_DOTS_SLASH:"(?!\\.{1,2}(?:\\/|$))",QMARK_NO_DOT:"[^.\\/]",STAR:"[^/]*?",START_ANCHOR:"(?:^|\\/)"},o={...n,SLASH_LITERAL:"[\\\\/]",QMARK:"[^\\\\/]",STAR:"[^\\\\/]*?",DOTS_SLASH:"\\.{1,2}(?:[\\\\/]|$)",NO_DOT:"(?!\\.)",NO_DOTS:"(?!(?:^|[\\\\/])\\.{1,2}(?:[\\\\/]|$))",NO_DOT_SLASH:"(?!\\.{0,1}(?:[\\\\/]|$))",NO_DOTS_SLASH:"(?!\\.{1,2}(?:[\\\\/]|$))",QMARK_NO_DOT:"[^.\\\\/]",START_ANCHOR:"(?:^|[\\\\/])",END_ANCHOR:"(?:[\\\\/]|$)"};e.exports={MAX_LENGTH:65536,POSIX_REGEX_SOURCE:{alnum:"a-zA-Z0-9",alpha:"a-zA-Z",ascii:"\\x00-\\x7F",blank:" \\t",cntrl:"\\x00-\\x1F\\x7F",digit:"0-9",graph:"\\x21-\\x7E",lower:"a-z",print:"\\x20-\\x7E ",punct:"\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",space:" \\t\\r\\n\\v\\f",upper:"A-Z",word:"A-Za-z0-9_",xdigit:"A-Fa-f0-9"},REGEX_BACKSLASH:/\\(?![*+?^${}(|)[\]])/g,REGEX_NON_SPECIAL_CHARS:/^[^@![\].,$*+?^{}()|\\/]+/,REGEX_SPECIAL_CHARS:/[-*+?.^${}(|)[\]]/,REGEX_SPECIAL_CHARS_BACKREF:/(\\?)((\W)(\3*))/g,REGEX_SPECIAL_CHARS_GLOBAL:/([-*+?.^${}(|)[\]])/g,REGEX_REMOVE_BACKSLASH:/(?:\[.*?[^\\]\]|\\(?=.))/g,REPLACEMENTS:{"***":"*","**/**":"**","**/**/**":"**"},CHAR_0:48,CHAR_9:57,CHAR_UPPERCASE_A:65,CHAR_LOWERCASE_A:97,CHAR_UPPERCASE_Z:90,CHAR_LOWERCASE_Z:122,CHAR_LEFT_PARENTHESES:40,CHAR_RIGHT_PARENTHESES:41,CHAR_ASTERISK:42,CHAR_AMPERSAND:38,CHAR_AT:64,CHAR_BACKWARD_SLASH:92,CHAR_CARRIAGE_RETURN:13,CHAR_CIRCUMFLEX_ACCENT:94,CHAR_COLON:58,CHAR_COMMA:44,CHAR_DOT:46,CHAR_DOUBLE_QUOTE:34,CHAR_EQUAL:61,CHAR_EXCLAMATION_MARK:33,CHAR_FORM_FEED:12,CHAR_FORWARD_SLASH:47,CHAR_GRAVE_ACCENT:96,CHAR_HASH:35,CHAR_HYPHEN_MINUS:45,CHAR_LEFT_ANGLE_BRACKET:60,CHAR_LEFT_CURLY_BRACE:123,CHAR_LEFT_SQUARE_BRACKET:91,CHAR_LINE_FEED:10,CHAR_NO_BREAK_SPACE:160,CHAR_PERCENT:37,CHAR_PLUS:43,CHAR_QUESTION_MARK:63,CHAR_RIGHT_ANGLE_BRACKET:62,CHAR_RIGHT_CURLY_BRACE:125,CHAR_RIGHT_SQUARE_BRACKET:93,CHAR_SEMICOLON:59,CHAR_SINGLE_QUOTE:39,CHAR_SPACE:32,CHAR_TAB:9,CHAR_UNDERSCORE:95,CHAR_VERTICAL_LINE:124,CHAR_ZERO_WIDTH_NOBREAK_SPACE:65279,SEP:A.sep,extglobChars:e=>({"!":{type:"negate",open:"(?:(?!(?:",close:`))${e.STAR})`},"?":{type:"qmark",open:"(?:",close:")?"},"+":{type:"plus",open:"(?:",close:")+"},"*":{type:"star",open:"(?:",close:")*"},"@":{type:"at",open:"(?:",close:")"}}),globChars:e=>!0===e?o:n}},47974:(e,t,r)=>{"use strict";const A=r(71086),n=r(3598),{MAX_LENGTH:o,POSIX_REGEX_SOURCE:i,REGEX_NON_SPECIAL_CHARS:s,REGEX_SPECIAL_CHARS_BACKREF:a,REPLACEMENTS:c}=A,g=(e,t)=>{if("function"==typeof t.expandRange)return t.expandRange(...e,t);e.sort();const r=`[${e.join("-")}]`;try{new RegExp(r)}catch(t){return e.map(e=>n.escapeRegex(e)).join("..")}return r},l=(e,t)=>`Missing ${e}: "${t}" - use "\\\\${t}" to match literal characters`,u=(e,t)=>{if("string"!=typeof e)throw new TypeError("Expected a string");e=c[e]||e;const r={...t},u="number"==typeof r.maxLength?Math.min(o,r.maxLength):o;let h=e.length;if(h>u)throw new SyntaxError(`Input length: ${h}, exceeds maximum allowed length: ${u}`);const p={type:"bos",value:"",output:r.prepend||""},d=[p],C=r.capture?"":"?:",f=n.isWindows(t),I=A.globChars(f),E=A.extglobChars(I),{DOT_LITERAL:B,PLUS_LITERAL:y,SLASH_LITERAL:m,ONE_CHAR:w,DOTS_SLASH:Q,NO_DOT:D,NO_DOT_SLASH:b,NO_DOTS_SLASH:v,QMARK:S,QMARK_NO_DOT:k,STAR:N,START_ANCHOR:F}=I,K=e=>`(${C}(?:(?!${F}${e.dot?Q:B}).)*?)`,M=r.dot?"":D,R=r.dot?S:k;let x=!0===r.bash?K(r):N;r.capture&&(x=`(${x})`),"boolean"==typeof r.noext&&(r.noextglob=r.noext);const L={input:e,index:-1,start:0,dot:!0===r.dot,consumed:"",output:"",prefix:"",backtrack:!1,negated:!1,brackets:0,braces:0,parens:0,quotes:0,globstar:!1,tokens:d};e=n.removePrefix(e,L),h=e.length;const P=[],O=[],U=[];let T,j=p;const Y=()=>L.index===h-1,G=L.peek=(t=1)=>e[L.index+t],H=L.advance=()=>e[++L.index],J=()=>e.slice(L.index+1),q=(e="",t=0)=>{L.consumed+=e,L.index+=t},z=e=>{L.output+=null!=e.output?e.output:e.value,q(e.value)},W=()=>{let e=1;for(;"!"===G()&&("("!==G(2)||"?"===G(3));)H(),L.start++,e++;return e%2!=0&&(L.negated=!0,L.start++,!0)},V=e=>{L[e]++,U.push(e)},X=e=>{L[e]--,U.pop()},_=e=>{if("globstar"===j.type){const t=L.braces>0&&("comma"===e.type||"brace"===e.type),r=!0===e.extglob||P.length&&("pipe"===e.type||"paren"===e.type);"slash"===e.type||"paren"===e.type||t||r||(L.output=L.output.slice(0,-j.output.length),j.type="star",j.value="*",j.output=x,L.output+=j.output)}if(P.length&&"paren"!==e.type&&!E[e.value]&&(P[P.length-1].inner+=e.value),(e.value||e.output)&&z(e),j&&"text"===j.type&&"text"===e.type)return j.value+=e.value,void(j.output=(j.output||"")+e.value);e.prev=j,d.push(e),j=e},Z=(e,t)=>{const A={...E[t],conditions:1,inner:""};A.prev=j,A.parens=L.parens,A.output=L.output;const n=(r.capture?"(":"")+A.open;V("parens"),_({type:e,value:t,output:L.output?"":w}),_({type:"paren",extglob:!0,value:H(),output:n}),P.push(A)},$=e=>{let t=e.close+(r.capture?")":"");if("negate"===e.type){let A=x;e.inner&&e.inner.length>1&&e.inner.includes("/")&&(A=K(r)),(A!==x||Y()||/^\)+$/.test(J()))&&(t=e.close=")$))"+A),"bos"===e.prev.type&&Y()&&(L.negatedExtglob=!0)}_({type:"paren",extglob:!0,value:T,output:t}),X("parens")};if(!1!==r.fastpaths&&!/(^[*!]|[/()[\]{}"])/.test(e)){let A=!1,o=e.replace(a,(e,t,r,n,o,i)=>"\\"===n?(A=!0,e):"?"===n?t?t+n+(o?S.repeat(o.length):""):0===i?R+(o?S.repeat(o.length):""):S.repeat(r.length):"."===n?B.repeat(r.length):"*"===n?t?t+n+(o?x:""):x:t?e:"\\"+e);return!0===A&&(o=!0===r.unescape?o.replace(/\\/g,""):o.replace(/\\+/g,e=>e.length%2==0?"\\\\":e?"\\":"")),o===e&&!0===r.contains?(L.output=e,L):(L.output=n.wrapOutput(o,L,t),L)}for(;!Y();){if(T=H(),"\0"===T)continue;if("\\"===T){const e=G();if("/"===e&&!0!==r.bash)continue;if("."===e||";"===e)continue;if(!e){T+="\\",_({type:"text",value:T});continue}const t=/^\\+/.exec(J());let A=0;if(t&&t[0].length>2&&(A=t[0].length,L.index+=A,A%2!=0&&(T+="\\")),!0===r.unescape?T=H()||"":T+=H()||"",0===L.brackets){_({type:"text",value:T});continue}}if(L.brackets>0&&("]"!==T||"["===j.value||"[^"===j.value)){if(!1!==r.posix&&":"===T){const e=j.value.slice(1);if(e.includes("[")&&(j.posix=!0,e.includes(":"))){const e=j.value.lastIndexOf("["),t=j.value.slice(0,e),r=j.value.slice(e+2),A=i[r];if(A){j.value=t+A,L.backtrack=!0,H(),p.output||1!==d.indexOf(j)||(p.output=w);continue}}}("["===T&&":"!==G()||"-"===T&&"]"===G())&&(T="\\"+T),"]"!==T||"["!==j.value&&"[^"!==j.value||(T="\\"+T),!0===r.posix&&"!"===T&&"["===j.value&&(T="^"),j.value+=T,z({value:T});continue}if(1===L.quotes&&'"'!==T){T=n.escapeRegex(T),j.value+=T,z({value:T});continue}if('"'===T){L.quotes=1===L.quotes?0:1,!0===r.keepQuotes&&_({type:"text",value:T});continue}if("("===T){V("parens"),_({type:"paren",value:T});continue}if(")"===T){if(0===L.parens&&!0===r.strictBrackets)throw new SyntaxError(l("opening","("));const e=P[P.length-1];if(e&&L.parens===e.parens+1){$(P.pop());continue}_({type:"paren",value:T,output:L.parens?")":"\\)"}),X("parens");continue}if("["===T){if(!0!==r.nobracket&&J().includes("]"))V("brackets");else{if(!0!==r.nobracket&&!0===r.strictBrackets)throw new SyntaxError(l("closing","]"));T="\\"+T}_({type:"bracket",value:T});continue}if("]"===T){if(!0===r.nobracket||j&&"bracket"===j.type&&1===j.value.length){_({type:"text",value:T,output:"\\"+T});continue}if(0===L.brackets){if(!0===r.strictBrackets)throw new SyntaxError(l("opening","["));_({type:"text",value:T,output:"\\"+T});continue}X("brackets");const e=j.value.slice(1);if(!0===j.posix||"^"!==e[0]||e.includes("/")||(T="/"+T),j.value+=T,z({value:T}),!1===r.literalBrackets||n.hasRegexChars(e))continue;const t=n.escapeRegex(j.value);if(L.output=L.output.slice(0,-j.value.length),!0===r.literalBrackets){L.output+=t,j.value=t;continue}j.value=`(${C}${t}|${j.value})`,L.output+=j.value;continue}if("{"===T&&!0!==r.nobrace){V("braces");const e={type:"brace",value:T,output:"(",outputIndex:L.output.length,tokensIndex:L.tokens.length};O.push(e),_(e);continue}if("}"===T){const e=O[O.length-1];if(!0===r.nobrace||!e){_({type:"text",value:T,output:T});continue}let t=")";if(!0===e.dots){const e=d.slice(),A=[];for(let t=e.length-1;t>=0&&(d.pop(),"brace"!==e[t].type);t--)"dots"!==e[t].type&&A.unshift(e[t].value);t=g(A,r),L.backtrack=!0}if(!0!==e.comma&&!0!==e.dots){const r=L.output.slice(0,e.outputIndex),A=L.tokens.slice(e.tokensIndex);e.value=e.output="\\{",T=t="\\}",L.output=r;for(const e of A)L.output+=e.output||e.value}_({type:"brace",value:T,output:t}),X("braces"),O.pop();continue}if("|"===T){P.length>0&&P[P.length-1].conditions++,_({type:"text",value:T});continue}if(","===T){let e=T;const t=O[O.length-1];t&&"braces"===U[U.length-1]&&(t.comma=!0,e="|"),_({type:"comma",value:T,output:e});continue}if("/"===T){if("dot"===j.type&&L.index===L.start+1){L.start=L.index+1,L.consumed="",L.output="",d.pop(),j=p;continue}_({type:"slash",value:T,output:m});continue}if("."===T){if(L.braces>0&&"dot"===j.type){"."===j.value&&(j.output=B);const e=O[O.length-1];j.type="dots",j.output+=T,j.value+=T,e.dots=!0;continue}if(L.braces+L.parens===0&&"bos"!==j.type&&"slash"!==j.type){_({type:"text",value:T,output:B});continue}_({type:"dot",value:T,output:B});continue}if("?"===T){if(!(j&&"("===j.value)&&!0!==r.noextglob&&"("===G()&&"?"!==G(2)){Z("qmark",T);continue}if(j&&"paren"===j.type){const e=G();let t=T;if("<"===e&&!n.supportsLookbehinds())throw new Error("Node.js v10 or higher is required for regex lookbehinds");("("===j.value&&!/[!=<:]/.test(e)||"<"===e&&!/<([!=]|\w+>)/.test(J()))&&(t="\\"+T),_({type:"text",value:T,output:t});continue}if(!0!==r.dot&&("slash"===j.type||"bos"===j.type)){_({type:"qmark",value:T,output:k});continue}_({type:"qmark",value:T,output:S});continue}if("!"===T){if(!0!==r.noextglob&&"("===G()&&("?"!==G(2)||!/[!=<:]/.test(G(3)))){Z("negate",T);continue}if(!0!==r.nonegate&&0===L.index){W();continue}}if("+"===T){if(!0!==r.noextglob&&"("===G()&&"?"!==G(2)){Z("plus",T);continue}if(j&&"("===j.value||!1===r.regex){_({type:"plus",value:T,output:y});continue}if(j&&("bracket"===j.type||"paren"===j.type||"brace"===j.type)||L.parens>0){_({type:"plus",value:T});continue}_({type:"plus",value:y});continue}if("@"===T){if(!0!==r.noextglob&&"("===G()&&"?"!==G(2)){_({type:"at",extglob:!0,value:T,output:""});continue}_({type:"text",value:T});continue}if("*"!==T){"$"!==T&&"^"!==T||(T="\\"+T);const e=s.exec(J());e&&(T+=e[0],L.index+=e[0].length),_({type:"text",value:T});continue}if(j&&("globstar"===j.type||!0===j.star)){j.type="star",j.star=!0,j.value+=T,j.output=x,L.backtrack=!0,L.globstar=!0,q(T);continue}let t=J();if(!0!==r.noextglob&&/^\([^?]/.test(t)){Z("star",T);continue}if("star"===j.type){if(!0===r.noglobstar){q(T);continue}const A=j.prev,n=A.prev,o="slash"===A.type||"bos"===A.type,i=n&&("star"===n.type||"globstar"===n.type);if(!0===r.bash&&(!o||t[0]&&"/"!==t[0])){_({type:"star",value:T,output:""});continue}const s=L.braces>0&&("comma"===A.type||"brace"===A.type),a=P.length&&("pipe"===A.type||"paren"===A.type);if(!o&&"paren"!==A.type&&!s&&!a){_({type:"star",value:T,output:""});continue}for(;"/**"===t.slice(0,3);){const r=e[L.index+4];if(r&&"/"!==r)break;t=t.slice(3),q("/**",3)}if("bos"===A.type&&Y()){j.type="globstar",j.value+=T,j.output=K(r),L.output=j.output,L.globstar=!0,q(T);continue}if("slash"===A.type&&"bos"!==A.prev.type&&!i&&Y()){L.output=L.output.slice(0,-(A.output+j.output).length),A.output="(?:"+A.output,j.type="globstar",j.output=K(r)+(r.strictSlashes?")":"|$)"),j.value+=T,L.globstar=!0,L.output+=A.output+j.output,q(T);continue}if("slash"===A.type&&"bos"!==A.prev.type&&"/"===t[0]){const e=void 0!==t[1]?"|$":"";L.output=L.output.slice(0,-(A.output+j.output).length),A.output="(?:"+A.output,j.type="globstar",j.output=`${K(r)}${m}|${m}${e})`,j.value+=T,L.output+=A.output+j.output,L.globstar=!0,q(T+H()),_({type:"slash",value:"/",output:""});continue}if("bos"===A.type&&"/"===t[0]){j.type="globstar",j.value+=T,j.output=`(?:^|${m}|${K(r)}${m})`,L.output=j.output,L.globstar=!0,q(T+H()),_({type:"slash",value:"/",output:""});continue}L.output=L.output.slice(0,-j.output.length),j.type="globstar",j.output=K(r),j.value+=T,L.output+=j.output,L.globstar=!0,q(T);continue}const A={type:"star",value:T,output:x};!0!==r.bash?!j||"bracket"!==j.type&&"paren"!==j.type||!0!==r.regex?(L.index!==L.start&&"slash"!==j.type&&"dot"!==j.type||("dot"===j.type?(L.output+=b,j.output+=b):!0===r.dot?(L.output+=v,j.output+=v):(L.output+=M,j.output+=M),"*"!==G()&&(L.output+=w,j.output+=w)),_(A)):(A.output=T,_(A)):(A.output=".*?","bos"!==j.type&&"slash"!==j.type||(A.output=M+A.output),_(A))}for(;L.brackets>0;){if(!0===r.strictBrackets)throw new SyntaxError(l("closing","]"));L.output=n.escapeLast(L.output,"["),X("brackets")}for(;L.parens>0;){if(!0===r.strictBrackets)throw new SyntaxError(l("closing",")"));L.output=n.escapeLast(L.output,"("),X("parens")}for(;L.braces>0;){if(!0===r.strictBrackets)throw new SyntaxError(l("closing","}"));L.output=n.escapeLast(L.output,"{"),X("braces")}if(!0===r.strictSlashes||"star"!==j.type&&"bracket"!==j.type||_({type:"maybe_slash",value:"",output:m+"?"}),!0===L.backtrack){L.output="";for(const e of L.tokens)L.output+=null!=e.output?e.output:e.value,e.suffix&&(L.output+=e.suffix)}return L};u.fastpaths=(e,t)=>{const r={...t},i="number"==typeof r.maxLength?Math.min(o,r.maxLength):o,s=e.length;if(s>i)throw new SyntaxError(`Input length: ${s}, exceeds maximum allowed length: ${i}`);e=c[e]||e;const a=n.isWindows(t),{DOT_LITERAL:g,SLASH_LITERAL:l,ONE_CHAR:u,DOTS_SLASH:h,NO_DOT:p,NO_DOTS:d,NO_DOTS_SLASH:C,STAR:f,START_ANCHOR:I}=A.globChars(a),E=r.dot?d:p,B=r.dot?C:p,y=r.capture?"":"?:";let m=!0===r.bash?".*?":f;r.capture&&(m=`(${m})`);const w=e=>!0===e.noglobstar?m:`(${y}(?:(?!${I}${e.dot?h:g}).)*?)`,Q=e=>{switch(e){case"*":return`${E}${u}${m}`;case".*":return`${g}${u}${m}`;case"*.*":return`${E}${m}${g}${u}${m}`;case"*/*":return`${E}${m}${l}${u}${B}${m}`;case"**":return E+w(r);case"**/*":return`(?:${E}${w(r)}${l})?${B}${u}${m}`;case"**/*.*":return`(?:${E}${w(r)}${l})?${B}${m}${g}${u}${m}`;case"**/.*":return`(?:${E}${w(r)}${l})?${g}${u}${m}`;default:{const t=/^(.*?)\.(\w+)$/.exec(e);if(!t)return;const r=Q(t[1]);if(!r)return;return r+g+t[2]}}},D=n.removePrefix(e,{negated:!1,prefix:""});let b=Q(D);return b&&!0!==r.strictSlashes&&(b+=l+"?"),b},e.exports=u},18828:(e,t,r)=>{"use strict";const A=r(85622),n=r(95321),o=r(47974),i=r(3598),s=r(71086),a=(e,t,r=!1)=>{if(Array.isArray(e)){const A=e.map(e=>a(e,t,r));return e=>{for(const t of A){const r=t(e);if(r)return r}return!1}}const A=(n=e)&&"object"==typeof n&&!Array.isArray(n)&&e.tokens&&e.input;var n;if(""===e||"string"!=typeof e&&!A)throw new TypeError("Expected pattern to be a non-empty string");const o=t||{},s=i.isWindows(t),c=A?a.compileRe(e,t):a.makeRe(e,t,!1,!0),g=c.state;delete c.state;let l=()=>!1;if(o.ignore){const e={...t,ignore:null,onMatch:null,onResult:null};l=a(o.ignore,e,r)}const u=(r,A=!1)=>{const{isMatch:n,match:i,output:u}=a.test(r,c,t,{glob:e,posix:s}),h={glob:e,state:g,regex:c,posix:s,input:r,output:u,match:i,isMatch:n};return"function"==typeof o.onResult&&o.onResult(h),!1===n?(h.isMatch=!1,!!A&&h):l(r)?("function"==typeof o.onIgnore&&o.onIgnore(h),h.isMatch=!1,!!A&&h):("function"==typeof o.onMatch&&o.onMatch(h),!A||h)};return r&&(u.state=g),u};a.test=(e,t,r,{glob:A,posix:n}={})=>{if("string"!=typeof e)throw new TypeError("Expected input to be a string");if(""===e)return{isMatch:!1,output:""};const o=r||{},s=o.format||(n?i.toPosixSlashes:null);let c=e===A,g=c&&s?s(e):e;return!1===c&&(g=s?s(e):e,c=g===A),!1!==c&&!0!==o.capture||(c=!0===o.matchBase||!0===o.basename?a.matchBase(e,t,r,n):t.exec(g)),{isMatch:Boolean(c),match:c,output:g}},a.matchBase=(e,t,r,n=i.isWindows(r))=>(t instanceof RegExp?t:a.makeRe(t,r)).test(A.basename(e)),a.isMatch=(e,t,r)=>a(t,r)(e),a.parse=(e,t)=>Array.isArray(e)?e.map(e=>a.parse(e,t)):o(e,{...t,fastpaths:!1}),a.scan=(e,t)=>n(e,t),a.compileRe=(e,t,r=!1,A=!1)=>{if(!0===r)return e.output;const n=t||{},o=n.contains?"":"^",i=n.contains?"":"$";let s=`${o}(?:${e.output})${i}`;e&&!0===e.negated&&(s=`^(?!${s}).*$`);const c=a.toRegex(s,t);return!0===A&&(c.state=e),c},a.makeRe=(e,t,r=!1,A=!1)=>{if(!e||"string"!=typeof e)throw new TypeError("Expected a non-empty string");const n=t||{};let i,s={negated:!1,fastpaths:!0},c="";return e.startsWith("./")&&(e=e.slice(2),c=s.prefix="./"),!1===n.fastpaths||"."!==e[0]&&"*"!==e[0]||(i=o.fastpaths(e,t)),void 0===i?(s=o(e,t),s.prefix=c+(s.prefix||"")):s.output=i,a.compileRe(s,t,r,A)},a.toRegex=(e,t)=>{try{const r=t||{};return new RegExp(e,r.flags||(r.nocase?"i":""))}catch(e){if(t&&!0===t.debug)throw e;return/$^/}},a.constants=s,e.exports=a},95321:(e,t,r)=>{"use strict";const A=r(3598),{CHAR_ASTERISK:n,CHAR_AT:o,CHAR_BACKWARD_SLASH:i,CHAR_COMMA:s,CHAR_DOT:a,CHAR_EXCLAMATION_MARK:c,CHAR_FORWARD_SLASH:g,CHAR_LEFT_CURLY_BRACE:l,CHAR_LEFT_PARENTHESES:u,CHAR_LEFT_SQUARE_BRACKET:h,CHAR_PLUS:p,CHAR_QUESTION_MARK:d,CHAR_RIGHT_CURLY_BRACE:C,CHAR_RIGHT_PARENTHESES:f,CHAR_RIGHT_SQUARE_BRACKET:I}=r(71086),E=e=>e===g||e===i,B=e=>{!0!==e.isPrefix&&(e.depth=e.isGlobstar?1/0:1)};e.exports=(e,t)=>{const r=t||{},y=e.length-1,m=!0===r.parts||!0===r.scanToEnd,w=[],Q=[],D=[];let b,v,S=e,k=-1,N=0,F=0,K=!1,M=!1,R=!1,x=!1,L=!1,P=!1,O=!1,U=!1,T=!1,j=0,Y={value:"",depth:0,isGlob:!1};const G=()=>k>=y,H=()=>(b=v,S.charCodeAt(++k));for(;k0&&(q=S.slice(0,N),S=S.slice(N),F-=N),J&&!0===R&&F>0?(J=S.slice(0,F),z=S.slice(F)):!0===R?(J="",z=S):J=S,J&&""!==J&&"/"!==J&&J!==S&&E(J.charCodeAt(J.length-1))&&(J=J.slice(0,-1)),!0===r.unescape&&(z&&(z=A.removeBackslashes(z)),J&&!0===O&&(J=A.removeBackslashes(J)));const W={prefix:q,input:e,start:N,base:J,glob:z,isBrace:K,isBracket:M,isGlob:R,isExtglob:x,isGlobstar:L,negated:U};if(!0===r.tokens&&(W.maxDepth=0,E(v)||Q.push(Y),W.tokens=Q),!0===r.parts||!0===r.tokens){let t;for(let A=0;A{"use strict";const A=r(85622),n="win32"===process.platform,{REGEX_BACKSLASH:o,REGEX_REMOVE_BACKSLASH:i,REGEX_SPECIAL_CHARS:s,REGEX_SPECIAL_CHARS_GLOBAL:a}=r(71086);t.isObject=e=>null!==e&&"object"==typeof e&&!Array.isArray(e),t.hasRegexChars=e=>s.test(e),t.isRegexChar=e=>1===e.length&&t.hasRegexChars(e),t.escapeRegex=e=>e.replace(a,"\\$1"),t.toPosixSlashes=e=>e.replace(o,"/"),t.removeBackslashes=e=>e.replace(i,e=>"\\"===e?"":e),t.supportsLookbehinds=()=>{const e=process.version.slice(1).split(".").map(Number);return 3===e.length&&e[0]>=9||8===e[0]&&e[1]>=10},t.isWindows=e=>e&&"boolean"==typeof e.windows?e.windows:!0===n||"\\"===A.sep,t.escapeLast=(e,r,A)=>{const n=e.lastIndexOf(r,A);return-1===n?e:"\\"===e[n-1]?t.escapeLast(e,r,n-1):`${e.slice(0,n)}\\${e.slice(n)}`},t.removePrefix=(e,t={})=>{let r=e;return r.startsWith("./")&&(r=r.slice(2),t.prefix="./"),r},t.wrapOutput=(e,t={},r={})=>{let A=`${r.contains?"":"^"}(?:${e})${r.contains?"":"$"}`;return!0===t.negated&&(A=`(?:^(?!${A}).*$)`),A}},79588:e=>{"use strict";function t(e){this._maxSize=e,this.clear()}t.prototype.clear=function(){this._size=0,this._values={}},t.prototype.get=function(e){return this._values[e]},t.prototype.set=function(e,t){return this._size>=this._maxSize&&this.clear(),this._values.hasOwnProperty(e)||this._size++,this._values[e]=t};var r=/[^.^\]^[]+|(?=\[\]|\.\.)/g,A=/^\d+$/,n=/^\d/,o=/[~`!#$%\^&*+=\-\[\]\\';,/{}|\\":<>\?]/g,i=/^\s*(['"]?)(.*?)(\1)\s*$/,s=!1,a=new t(512),c=new t(512),g=new t(512);try{new Function("")}catch(e){s=!0}function l(e){return a.get(e)||a.set(e,u(e).map((function(e){return e.replace(i,"$2")})))}function u(e){return e.match(r)}function h(e,t,r){return"string"==typeof t&&(r=t,t=!1),r=r||"data",(e=e||"")&&"["!==e.charAt(0)&&(e="."+e),t?function(e,t){var r,A=t,n=u(e);return p(n,(function(e,t,n,o,i){r=o===i.length-1,A+=(e=t||n?"["+e+"]":"."+e)+(r?")":" || {})")})),new Array(n.length+1).join("(")+A}(e,r):r+e}function p(e,t,r){var A,n,o,i,s=e.length;for(n=0;n{var A=r(91162),n=r(97681),o=r(35747),i=function(){},s=/^v?\.0/.test(process.version),a=function(e){return"function"==typeof e},c=function(e,t,r,c){c=A(c);var g=!1;e.on("close",(function(){g=!0})),n(e,{readable:t,writable:r},(function(e){if(e)return c(e);g=!0,c()}));var l=!1;return function(t){if(!g&&!l)return l=!0,function(e){return!!s&&(!!o&&((e instanceof(o.ReadStream||i)||e instanceof(o.WriteStream||i))&&a(e.close)))}(e)?e.close(i):function(e){return e.setHeader&&a(e.abort)}(e)?e.abort():a(e.destroy)?e.destroy():void c(t||new Error("stream was destroyed"))}},g=function(e){e()},l=function(e,t){return e.pipe(t)};e.exports=function(){var e,t=Array.prototype.slice.call(arguments),r=a(t[t.length-1]||i)&&t.pop()||i;if(Array.isArray(t[0])&&(t=t[0]),t.length<2)throw new Error("pump requires two streams per minimum");var A=t.map((function(n,o){var i=o0,(function(t){e||(e=t),t&&A.forEach(g),i||(A.forEach(g),r(e))}))}));return t.reduce(l)}},49601:e=>{"use strict";class t{constructor(e={}){if(!(e.maxSize&&e.maxSize>0))throw new TypeError("`maxSize` must be a number greater than 0");this.maxSize=e.maxSize,this.onEviction=e.onEviction,this.cache=new Map,this.oldCache=new Map,this._size=0}_set(e,t){if(this.cache.set(e,t),this._size++,this._size>=this.maxSize){if(this._size=0,"function"==typeof this.onEviction)for(const[e,t]of this.oldCache.entries())this.onEviction(e,t);this.oldCache=this.cache,this.cache=new Map}}get(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e)){const t=this.oldCache.get(e);return this.oldCache.delete(e),this._set(e,t),t}}set(e,t){return this.cache.has(e)?this.cache.set(e,t):this._set(e,t),this}has(e){return this.cache.has(e)||this.oldCache.has(e)}peek(e){return this.cache.has(e)?this.cache.get(e):this.oldCache.has(e)?this.oldCache.get(e):void 0}delete(e){const t=this.cache.delete(e);return t&&this._size--,this.oldCache.delete(e)||t}clear(){this.cache.clear(),this.oldCache.clear(),this._size=0}*keys(){for(const[e]of this)yield e}*values(){for(const[,e]of this)yield e}*[Symbol.iterator](){for(const e of this.cache)yield e;for(const e of this.oldCache){const[t]=e;this.cache.has(t)||(yield e)}}get size(){let e=0;for(const t of this.oldCache.keys())this.cache.has(t)||e++;return Math.min(this._size+e,this.maxSize)}}e.exports=t},20663:e=>{"use strict";const t={};function r(e,r,A){A||(A=Error);class n extends A{constructor(e,t,A){super(function(e,t,A){return"string"==typeof r?r:r(e,t,A)}(e,t,A))}}n.prototype.name=A.name,n.prototype.code=e,t[e]=n}function A(e,t){if(Array.isArray(e)){const r=e.length;return e=e.map(e=>String(e)),r>2?`one of ${t} ${e.slice(0,r-1).join(", ")}, or `+e[r-1]:2===r?`one of ${t} ${e[0]} or ${e[1]}`:`of ${t} ${e[0]}`}return`of ${t} ${String(e)}`}r("ERR_INVALID_OPT_VALUE",(function(e,t){return'The value "'+t+'" is invalid for option "'+e+'"'}),TypeError),r("ERR_INVALID_ARG_TYPE",(function(e,t,r){let n;var o,i;let s;if("string"==typeof t&&(o="not ",t.substr(!i||i<0?0:+i,o.length)===o)?(n="must not be",t=t.replace(/^not /,"")):n="must be",function(e,t,r){return(void 0===r||r>e.length)&&(r=e.length),e.substring(r-t.length,r)===t}(e," argument"))s=`The ${e} ${n} ${A(t,"type")}`;else{s=`The "${e}" ${function(e,t,r){return"number"!=typeof r&&(r=0),!(r+t.length>e.length)&&-1!==e.indexOf(t,r)}(e,".")?"property":"argument"} ${n} ${A(t,"type")}`}return s+=". Received type "+typeof r,s}),TypeError),r("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF"),r("ERR_METHOD_NOT_IMPLEMENTED",(function(e){return"The "+e+" method is not implemented"})),r("ERR_STREAM_PREMATURE_CLOSE","Premature close"),r("ERR_STREAM_DESTROYED",(function(e){return"Cannot call "+e+" after a stream was destroyed"})),r("ERR_MULTIPLE_CALLBACK","Callback called multiple times"),r("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable"),r("ERR_STREAM_WRITE_AFTER_END","write after end"),r("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError),r("ERR_UNKNOWN_ENCODING",(function(e){return"Unknown encoding: "+e}),TypeError),r("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event"),e.exports.q=t},39138:e=>{"use strict";var t=new Set;e.exports.emitExperimentalWarning=process.emitWarning?function(e){if(!t.has(e)){var r=e+" is an experimental feature. This feature could change at any time";t.add(e),process.emitWarning(r,"ExperimentalWarning")}}:function(){}},72434:(e,t,r)=>{"use strict";var A=Object.keys||function(e){var t=[];for(var r in e)t.push(r);return t};e.exports=c;var n=r(58020),o=r(6729);r(85870)(c,n);for(var i=A(o.prototype),s=0;s{"use strict";e.exports=n;var A=r(54801);function n(e){if(!(this instanceof n))return new n(e);A.call(this,e)}r(85870)(n,A),n.prototype._transform=function(e,t,r){r(null,e)}},58020:(e,t,r)=>{"use strict";var A;e.exports=w,w.ReadableState=m;r(28614).EventEmitter;var n=function(e,t){return e.listeners(t).length},o=r(49298),i=r(64293).Buffer,s=global.Uint8Array||function(){};var a,c=r(31669);a=c&&c.debuglog?c.debuglog("stream"):function(){};var g,l,u=r(43117),h=r(32340),p=r(77433).getHighWaterMark,d=r(20663).q,C=d.ERR_INVALID_ARG_TYPE,f=d.ERR_STREAM_PUSH_AFTER_EOF,I=d.ERR_METHOD_NOT_IMPLEMENTED,E=d.ERR_STREAM_UNSHIFT_AFTER_END_EVENT,B=r(39138).emitExperimentalWarning;r(85870)(w,o);var y=["error","close","destroy","pause","resume"];function m(e,t,n){A=A||r(72434),e=e||{},"boolean"!=typeof n&&(n=t instanceof A),this.objectMode=!!e.objectMode,n&&(this.objectMode=this.objectMode||!!e.readableObjectMode),this.highWaterMark=p(this,e,"readableHighWaterMark",n),this.buffer=new u,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.paused=!0,this.emitClose=!1!==e.emitClose,this.destroyed=!1,this.defaultEncoding=e.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(g||(g=r(69538).s),this.decoder=new g(e.encoding),this.encoding=e.encoding)}function w(e){if(A=A||r(72434),!(this instanceof w))return new w(e);var t=this instanceof A;this._readableState=new m(e,this,t),this.readable=!0,e&&("function"==typeof e.read&&(this._read=e.read),"function"==typeof e.destroy&&(this._destroy=e.destroy)),o.call(this)}function Q(e,t,r,A,n){a("readableAddChunk",t);var o,c=e._readableState;if(null===t)c.reading=!1,function(e,t){if(t.ended)return;if(t.decoder){var r=t.decoder.end();r&&r.length&&(t.buffer.push(r),t.length+=t.objectMode?1:r.length)}t.ended=!0,t.sync?v(e):(t.needReadable=!1,t.emittedReadable||(t.emittedReadable=!0,S(e)))}(e,c);else if(n||(o=function(e,t){var r;A=t,i.isBuffer(A)||A instanceof s||"string"==typeof t||void 0===t||e.objectMode||(r=new C("chunk",["string","Buffer","Uint8Array"],t));var A;return r}(c,t)),o)e.emit("error",o);else if(c.objectMode||t&&t.length>0)if("string"==typeof t||c.objectMode||Object.getPrototypeOf(t)===i.prototype||(t=function(e){return i.from(e)}(t)),A)c.endEmitted?e.emit("error",new E):D(e,c,t,!0);else if(c.ended)e.emit("error",new f);else{if(c.destroyed)return!1;c.reading=!1,c.decoder&&!r?(t=c.decoder.write(t),c.objectMode||0!==t.length?D(e,c,t,!1):k(e,c)):D(e,c,t,!1)}else A||(c.reading=!1,k(e,c));return!c.ended&&(c.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=8388608?e=8388608:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function v(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(a("emitReadable",t.flowing),t.emittedReadable=!0,process.nextTick(S,e))}function S(e){var t=e._readableState;a("emitReadable_",t.destroyed,t.length,t.ended),t.destroyed||!t.length&&!t.ended||e.emit("readable"),t.needReadable=!t.flowing&&!t.ended&&t.length<=t.highWaterMark,R(e)}function k(e,t){t.readingMore||(t.readingMore=!0,process.nextTick(N,e,t))}function N(e,t){for(var r=t.length;!t.reading&&!t.ended&&t.length0,t.resumeScheduled&&!t.paused?t.flowing=!0:e.listenerCount("data")>0&&e.resume()}function K(e){a("readable nexttick read 0"),e.read(0)}function M(e,t){a("resume",t.reading),t.reading||e.read(0),t.resumeScheduled=!1,e.emit("resume"),R(e),t.flowing&&!t.reading&&e.read(0)}function R(e){var t=e._readableState;for(a("flow",t.flowing);t.flowing&&null!==e.read(););}function x(e,t){return 0===t.length?null:(t.objectMode?r=t.buffer.shift():!e||e>=t.length?(r=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.first():t.buffer.concat(t.length),t.buffer.clear()):r=t.buffer.consume(e,t.decoder),r);var r}function L(e){var t=e._readableState;a("endReadable",t.endEmitted),t.endEmitted||(t.ended=!0,process.nextTick(P,t,e))}function P(e,t){a("endReadableNT",e.endEmitted,e.length),e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function O(e,t){for(var r=0,A=e.length;r=t.highWaterMark:t.length>0)||t.ended))return a("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?L(this):v(this),null;if(0===(e=b(e,t))&&t.ended)return 0===t.length&&L(this),null;var A,n=t.needReadable;return a("need readable",n),(0===t.length||t.length-e0?x(e,t):null)?(t.needReadable=!0,e=0):(t.length-=e,t.awaitDrain=0),0===t.length&&(t.ended||(t.needReadable=!0),r!==e&&t.ended&&L(this)),null!==A&&this.emit("data",A),A},w.prototype._read=function(e){this.emit("error",new I("_read()"))},w.prototype.pipe=function(e,t){var r=this,A=this._readableState;switch(A.pipesCount){case 0:A.pipes=e;break;case 1:A.pipes=[A.pipes,e];break;default:A.pipes.push(e)}A.pipesCount+=1,a("pipe count=%d opts=%j",A.pipesCount,t);var o=(!t||!1!==t.end)&&e!==process.stdout&&e!==process.stderr?s:d;function i(t,n){a("onunpipe"),t===r&&n&&!1===n.hasUnpiped&&(n.hasUnpiped=!0,a("cleanup"),e.removeListener("close",h),e.removeListener("finish",p),e.removeListener("drain",c),e.removeListener("error",u),e.removeListener("unpipe",i),r.removeListener("end",s),r.removeListener("end",d),r.removeListener("data",l),g=!0,!A.awaitDrain||e._writableState&&!e._writableState.needDrain||c())}function s(){a("onend"),e.end()}A.endEmitted?process.nextTick(o):r.once("end",o),e.on("unpipe",i);var c=function(e){return function(){var t=e._readableState;a("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&n(e,"data")&&(t.flowing=!0,R(e))}}(r);e.on("drain",c);var g=!1;function l(t){a("ondata");var n=e.write(t);a("dest.write",n),!1===n&&((1===A.pipesCount&&A.pipes===e||A.pipesCount>1&&-1!==O(A.pipes,e))&&!g&&(a("false write response, pause",A.awaitDrain),A.awaitDrain++),r.pause())}function u(t){a("onerror",t),d(),e.removeListener("error",u),0===n(e,"error")&&e.emit("error",t)}function h(){e.removeListener("finish",p),d()}function p(){a("onfinish"),e.removeListener("close",h),d()}function d(){a("unpipe"),r.unpipe(e)}return r.on("data",l),function(e,t,r){if("function"==typeof e.prependListener)return e.prependListener(t,r);e._events&&e._events[t]?Array.isArray(e._events[t])?e._events[t].unshift(r):e._events[t]=[r,e._events[t]]:e.on(t,r)}(e,"error",u),e.once("close",h),e.once("finish",p),e.emit("pipe",r),A.flowing||(a("pipe resume"),r.resume()),e},w.prototype.unpipe=function(e){var t=this._readableState,r={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,r)),this;if(!e){var A=t.pipes,n=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var o=0;o0,!1!==A.flowing&&this.resume()):"readable"===e&&(A.endEmitted||A.readableListening||(A.readableListening=A.needReadable=!0,A.flowing=!1,A.emittedReadable=!1,a("on readable",A.length,A.reading),A.length?v(this):A.reading||process.nextTick(K,this))),r},w.prototype.addListener=w.prototype.on,w.prototype.removeListener=function(e,t){var r=o.prototype.removeListener.call(this,e,t);return"readable"===e&&process.nextTick(F,this),r},w.prototype.removeAllListeners=function(e){var t=o.prototype.removeAllListeners.apply(this,arguments);return"readable"!==e&&void 0!==e||process.nextTick(F,this),t},w.prototype.resume=function(){var e=this._readableState;return e.flowing||(a("resume"),e.flowing=!e.readableListening,function(e,t){t.resumeScheduled||(t.resumeScheduled=!0,process.nextTick(M,e,t))}(this,e)),e.paused=!1,this},w.prototype.pause=function(){return a("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(a("pause"),this._readableState.flowing=!1,this.emit("pause")),this._readableState.paused=!0,this},w.prototype.wrap=function(e){var t=this,r=this._readableState,A=!1;for(var n in e.on("end",(function(){if(a("wrapped end"),r.decoder&&!r.ended){var e=r.decoder.end();e&&e.length&&t.push(e)}t.push(null)})),e.on("data",(function(n){(a("wrapped data"),r.decoder&&(n=r.decoder.write(n)),r.objectMode&&null==n)||(r.objectMode||n&&n.length)&&(t.push(n)||(A=!0,e.pause()))})),e)void 0===this[n]&&"function"==typeof e[n]&&(this[n]=function(t){return function(){return e[t].apply(e,arguments)}}(n));for(var o=0;o{"use strict";e.exports=g;var A=r(20663).q,n=A.ERR_METHOD_NOT_IMPLEMENTED,o=A.ERR_MULTIPLE_CALLBACK,i=A.ERR_TRANSFORM_ALREADY_TRANSFORMING,s=A.ERR_TRANSFORM_WITH_LENGTH_0,a=r(72434);function c(e,t){var r=this._transformState;r.transforming=!1;var A=r.writecb;if(null===A)return this.emit("error",new o);r.writechunk=null,r.writecb=null,null!=t&&this.push(t),A(e);var n=this._readableState;n.reading=!1,(n.needReadable||n.length{"use strict";function A(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,r){var A=e.entry;e.entry=null;for(;A;){var n=A.callback;t.pendingcb--,n(r),A=A.next}t.corkedRequestsFree.next=e}(t,e)}}var n;e.exports=w,w.WritableState=m;var o={deprecate:r(73212)},i=r(49298),s=r(64293).Buffer,a=global.Uint8Array||function(){};var c,g=r(32340),l=r(77433).getHighWaterMark,u=r(20663).q,h=u.ERR_INVALID_ARG_TYPE,p=u.ERR_METHOD_NOT_IMPLEMENTED,d=u.ERR_MULTIPLE_CALLBACK,C=u.ERR_STREAM_CANNOT_PIPE,f=u.ERR_STREAM_DESTROYED,I=u.ERR_STREAM_NULL_VALUES,E=u.ERR_STREAM_WRITE_AFTER_END,B=u.ERR_UNKNOWN_ENCODING;function y(){}function m(e,t,o){n=n||r(72434),e=e||{},"boolean"!=typeof o&&(o=t instanceof n),this.objectMode=!!e.objectMode,o&&(this.objectMode=this.objectMode||!!e.writableObjectMode),this.highWaterMark=l(this,e,"writableHighWaterMark",o),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var i=!1===e.decodeStrings;this.decodeStrings=!i,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var r=e._writableState,A=r.sync,n=r.writecb;if("function"!=typeof n)throw new d;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(r),t)!function(e,t,r,A,n){--t.pendingcb,r?(process.nextTick(n,A),process.nextTick(k,e,t),e._writableState.errorEmitted=!0,e.emit("error",A)):(n(A),e._writableState.errorEmitted=!0,e.emit("error",A),k(e,t))}(e,r,A,t,n);else{var o=v(r)||e.destroyed;o||r.corked||r.bufferProcessing||!r.bufferedRequest||b(e,r),A?process.nextTick(D,e,r,o,n):D(e,r,o,n)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=!1!==e.emitClose,this.bufferedRequestCount=0,this.corkedRequestsFree=new A(this)}function w(e){var t=this instanceof(n=n||r(72434));if(!t&&!c.call(w,this))return new w(e);this._writableState=new m(e,this,t),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),i.call(this)}function Q(e,t,r,A,n,o,i){t.writelen=A,t.writecb=i,t.writing=!0,t.sync=!0,t.destroyed?t.onwrite(new f("write")):r?e._writev(n,t.onwrite):e._write(n,o,t.onwrite),t.sync=!1}function D(e,t,r,A){r||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,A(),k(e,t)}function b(e,t){t.bufferProcessing=!0;var r=t.bufferedRequest;if(e._writev&&r&&r.next){var n=t.bufferedRequestCount,o=new Array(n),i=t.corkedRequestsFree;i.entry=r;for(var s=0,a=!0;r;)o[s]=r,r.isBuf||(a=!1),r=r.next,s+=1;o.allBuffers=a,Q(e,t,!0,t.length,o,"",i.finish),t.pendingcb++,t.lastBufferedRequest=null,i.next?(t.corkedRequestsFree=i.next,i.next=null):t.corkedRequestsFree=new A(t),t.bufferedRequestCount=0}else{for(;r;){var c=r.chunk,g=r.encoding,l=r.callback;if(Q(e,t,!1,t.objectMode?1:c.length,c,g,l),r=r.next,t.bufferedRequestCount--,t.writing)break}null===r&&(t.lastBufferedRequest=null)}t.bufferedRequest=r,t.bufferProcessing=!1}function v(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function S(e,t){e._final((function(r){t.pendingcb--,r&&e.emit("error",r),t.prefinished=!0,e.emit("prefinish"),k(e,t)}))}function k(e,t){var r=v(t);return r&&(!function(e,t){t.prefinished||t.finalCalled||("function"!=typeof e._final||t.destroyed?(t.prefinished=!0,e.emit("prefinish")):(t.pendingcb++,t.finalCalled=!0,process.nextTick(S,e,t)))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"))),r}r(85870)(w,i),m.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(m.prototype,"buffer",{get:o.deprecate((function(){return this.getBuffer()}),"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(c=Function.prototype[Symbol.hasInstance],Object.defineProperty(w,Symbol.hasInstance,{value:function(e){return!!c.call(this,e)||this===w&&(e&&e._writableState instanceof m)}})):c=function(e){return e instanceof this},w.prototype.pipe=function(){this.emit("error",new C)},w.prototype.write=function(e,t,r){var A,n=this._writableState,o=!1,i=!n.objectMode&&(A=e,s.isBuffer(A)||A instanceof a);return i&&!s.isBuffer(e)&&(e=function(e){return s.from(e)}(e)),"function"==typeof t&&(r=t,t=null),i?t="buffer":t||(t=n.defaultEncoding),"function"!=typeof r&&(r=y),n.ending?function(e,t){var r=new E;e.emit("error",r),process.nextTick(t,r)}(this,r):(i||function(e,t,r,A){var n;return null===r?n=new I:"string"==typeof r||t.objectMode||(n=new h("chunk",["string","Buffer"],r)),!n||(e.emit("error",n),process.nextTick(A,n),!1)}(this,n,e,r))&&(n.pendingcb++,o=function(e,t,r,A,n,o){if(!r){var i=function(e,t,r){e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=s.from(t,r));return t}(t,A,n);A!==i&&(r=!0,n="buffer",A=i)}var a=t.objectMode?1:A.length;t.length+=a;var c=t.length-1))throw new B(e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(w.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}}),Object.defineProperty(w.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),w.prototype._write=function(e,t,r){r(new p("_write()"))},w.prototype._writev=null,w.prototype.end=function(e,t,r){var A=this._writableState;return"function"==typeof e?(r=e,e=null,t=null):"function"==typeof t&&(r=t,t=null),null!=e&&this.write(e,t),A.corked&&(A.corked=1,this.uncork()),A.ending||function(e,t,r){t.ending=!0,k(e,t),r&&(t.finished?process.nextTick(r):e.once("finish",r));t.ended=!0,e.writable=!1}(this,A,r),this},Object.defineProperty(w.prototype,"writableLength",{enumerable:!1,get:function(){return this._writableState.length}}),Object.defineProperty(w.prototype,"destroyed",{enumerable:!1,get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),w.prototype.destroy=g.destroy,w.prototype._undestroy=g.undestroy,w.prototype._destroy=function(e,t){t(e)}},4245:(e,t,r)=>{"use strict";var A;function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var o=r(91327),i=Symbol("lastResolve"),s=Symbol("lastReject"),a=Symbol("error"),c=Symbol("ended"),g=Symbol("lastPromise"),l=Symbol("handlePromise"),u=Symbol("stream");function h(e,t){return{value:e,done:t}}function p(e){var t=e[i];if(null!==t){var r=e[u].read();null!==r&&(e[g]=null,e[i]=null,e[s]=null,t(h(r,!1)))}}function d(e){process.nextTick(p,e)}var C=Object.getPrototypeOf((function(){})),f=Object.setPrototypeOf((n(A={get stream(){return this[u]},next:function(){var e=this,t=this[a];if(null!==t)return Promise.reject(t);if(this[c])return Promise.resolve(h(null,!0));if(this[u].destroyed)return new Promise((function(t,r){process.nextTick((function(){e[a]?r(e[a]):t(h(null,!0))}))}));var r,A=this[g];if(A)r=new Promise(function(e,t){return function(r,A){e.then((function(){t[l](r,A)}),A)}}(A,this));else{var n=this[u].read();if(null!==n)return Promise.resolve(h(n,!1));r=new Promise(this[l])}return this[g]=r,r}},Symbol.asyncIterator,(function(){return this})),n(A,"return",(function(){var e=this;return new Promise((function(t,r){e[u].destroy(null,(function(e){e?r(e):t(h(null,!0))}))}))})),A),C);e.exports=function(e){var t,r=Object.create(f,(n(t={},u,{value:e,writable:!0}),n(t,i,{value:null,writable:!0}),n(t,s,{value:null,writable:!0}),n(t,a,{value:null,writable:!0}),n(t,c,{value:e._readableState.endEmitted,writable:!0}),n(t,g,{value:null,writable:!0}),n(t,l,{value:function(e,t){var A=r[u].read();A?(r[g]=null,r[i]=null,r[s]=null,e(h(A,!1))):(r[i]=e,r[s]=t)},writable:!0}),t));return o(e,(function(e){if(e&&"ERR_STREAM_PREMATURE_CLOSE"!==e.code){var t=r[s];return null!==t&&(r[g]=null,r[i]=null,r[s]=null,t(e)),void(r[a]=e)}var A=r[i];null!==A&&(r[g]=null,r[i]=null,r[s]=null,A(h(null,!0))),r[c]=!0})),e.on("readable",d.bind(null,r)),r}},43117:(e,t,r)=>{"use strict";function A(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var n=r(64293).Buffer,o=r(31669).inspect,i=o&&o.custom||"inspect";e.exports=function(){function e(){this.head=null,this.tail=null,this.length=0}var t=e.prototype;return t.push=function(e){var t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length},t.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},t.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},t.clear=function(){this.head=this.tail=null,this.length=0},t.join=function(e){if(0===this.length)return"";for(var t=this.head,r=""+t.data;t=t.next;)r+=e+t.data;return r},t.concat=function(e){if(0===this.length)return n.alloc(0);for(var t,r,A,o=n.allocUnsafe(e>>>0),i=this.head,s=0;i;)t=i.data,r=o,A=s,n.prototype.copy.call(t,r,A),s+=i.data.length,i=i.next;return o},t.consume=function(e,t){var r;return en.length?n.length:e;if(o===n.length?A+=n:A+=n.slice(0,e),0===(e-=o)){o===n.length?(++r,t.next?this.head=t.next:this.head=this.tail=null):(this.head=t,t.data=n.slice(o));break}++r}return this.length-=r,A},t._getBuffer=function(e){var t=n.allocUnsafe(e),r=this.head,A=1;for(r.data.copy(t),e-=r.data.length;r=r.next;){var o=r.data,i=e>o.length?o.length:e;if(o.copy(t,t.length-e,0,i),0===(e-=i)){i===o.length?(++A,r.next?this.head=r.next:this.head=this.tail=null):(this.head=r,r.data=o.slice(i));break}++A}return this.length-=A,t},t[i]=function(e,t){return o(this,function(e){for(var t=1;t{"use strict";function t(e,t){A(e,t),r(e)}function r(e){e._writableState&&!e._writableState.emitClose||e._readableState&&!e._readableState.emitClose||e.emit("close")}function A(e,t){e.emit("error",t)}e.exports={destroy:function(e,n){var o=this,i=this._readableState&&this._readableState.destroyed,s=this._writableState&&this._writableState.destroyed;return i||s?(n?n(e):!e||this._writableState&&this._writableState.errorEmitted||process.nextTick(A,this,e),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,(function(e){!n&&e?(process.nextTick(t,o,e),o._writableState&&(o._writableState.errorEmitted=!0)):n?(process.nextTick(r,o),n(e)):process.nextTick(r,o)})),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finalCalled=!1,this._writableState.prefinished=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},91327:(e,t,r)=>{"use strict";var A=r(20663).q.ERR_STREAM_PREMATURE_CLOSE;function n(){}e.exports=function e(t,r,o){if("function"==typeof r)return e(t,null,r);r||(r={}),o=function(e){var t=!1;return function(r){t||(t=!0,e.call(this,r))}}(o||n);var i=t._writableState,s=t._readableState,a=r.readable||!1!==r.readable&&t.readable,c=r.writable||!1!==r.writable&&t.writable,g=function(){t.writable||l()},l=function(){c=!1,a||o.call(t)},u=function(){a=!1,c||o.call(t)},h=function(e){o.call(t,e)},p=function(){return(!a||s&&s.ended)&&(!c||i&&i.ended)?void 0:o.call(t,new A)},d=function(){t.req.on("finish",l)};return!function(e){return e.setHeader&&"function"==typeof e.abort}(t)?c&&!i&&(t.on("end",g),t.on("close",g)):(t.on("complete",l),t.on("abort",p),t.req?d():t.on("request",d)),t.on("end",u),t.on("finish",l),!1!==r.error&&t.on("error",h),t.on("close",p),function(){t.removeListener("complete",l),t.removeListener("abort",p),t.removeListener("request",d),t.req&&t.req.removeListener("finish",l),t.removeListener("end",g),t.removeListener("close",g),t.removeListener("finish",l),t.removeListener("end",u),t.removeListener("error",h),t.removeListener("close",p)}}},4939:(e,t,r)=>{"use strict";var A;var n=r(20663).q,o=n.ERR_MISSING_ARGS,i=n.ERR_STREAM_DESTROYED;function s(e){if(e)throw e}function a(e,t,n,o){o=function(e){var t=!1;return function(){t||(t=!0,e.apply(void 0,arguments))}}(o);var s=!1;e.on("close",(function(){s=!0})),void 0===A&&(A=r(91327)),A(e,{readable:t,writable:n},(function(e){if(e)return o(e);s=!0,o()}));var a=!1;return function(t){if(!s&&!a)return a=!0,function(e){return e.setHeader&&"function"==typeof e.abort}(e)?e.abort():"function"==typeof e.destroy?e.destroy():void o(t||new i("pipe"))}}function c(e){e()}function g(e,t){return e.pipe(t)}function l(e){return e.length?"function"!=typeof e[e.length-1]?s:e.pop():s}e.exports=function(){for(var e=arguments.length,t=new Array(e),r=0;r0,(function(e){A||(A=e),e&&i.forEach(c),o||(i.forEach(c),n(A))}))}));return t.reduce(g)}},77433:(e,t,r)=>{"use strict";var A=r(20663).q.ERR_INVALID_OPT_VALUE;e.exports={getHighWaterMark:function(e,t,r,n){var o=function(e,t,r){return null!=e.highWaterMark?e.highWaterMark:t?e[r]:null}(t,n,r);if(null!=o){if(!isFinite(o)||Math.floor(o)!==o||o<0)throw new A(n?r:"highWaterMark",o);return Math.floor(o)}return e.objectMode?16:16384}}},49298:(e,t,r)=>{e.exports=r(92413)},86897:(e,t,r)=>{var A=r(92413);"disable"===process.env.READABLE_STREAM&&A?(e.exports=A.Readable,Object.assign(e.exports,A),e.exports.Stream=A):((t=e.exports=r(58020)).Stream=A||t,t.Readable=t,t.Writable=r(6729),t.Duplex=r(72434),t.Transform=r(54801),t.PassThrough=r(52444),t.finished=r(91327),t.pipeline=r(4939))},19476:(e,t,r)=>{"use strict";const A=r(4016);e.exports=(e={})=>new Promise((t,r)=>{const n=A.connect(e,()=>{e.resolveSocket?(n.off("error",r),t({alpnProtocol:n.alpnProtocol,socket:n})):(n.destroy(),t({alpnProtocol:n.alpnProtocol}))});n.on("error",r)})},48491:(e,t,r)=>{"use strict";const A=r(92413).Readable,n=r(55737);e.exports=class extends A{constructor(e,t,r,A){if("number"!=typeof e)throw new TypeError("Argument `statusCode` should be a number");if("object"!=typeof t)throw new TypeError("Argument `headers` should be an object");if(!(r instanceof Buffer))throw new TypeError("Argument `body` should be a buffer");if("string"!=typeof A)throw new TypeError("Argument `url` should be a string");super(),this.statusCode=e,this.headers=n(t),this.body=r,this.url=A}_read(){this.push(this.body),this.push(null)}}},2383:e=>{"use strict";e.exports=function(e){var t=new e,r=t;return{get:function(){var A=t;return A.next?t=A.next:(t=new e,r=t),A.next=null,A},release:function(e){r.next=e,r=e}}}},69078:e=>{e.exports=function(e,t){var r,A,n,o=!0;Array.isArray(e)?(r=[],A=e.length):(n=Object.keys(e),r={},A=n.length);function i(e){function A(){t&&t(e,r),t=null}o?process.nextTick(A):A()}function s(e,t,n){r[e]=n,(0==--A||t)&&i(t)}A?n?n.forEach((function(t){e[t]((function(e,r){s(t,e,r)}))})):e.forEach((function(e,t){e((function(e,r){s(t,e,r)}))})):i(null);o=!1}},13499:(e,t,r)=>{var A=r(64293),n=A.Buffer;function o(e,t){for(var r in e)t[r]=e[r]}function i(e,t,r){return n(e,t,r)}n.from&&n.alloc&&n.allocUnsafe&&n.allocUnsafeSlow?e.exports=A:(o(A,t),t.Buffer=i),o(n,i),i.from=function(e,t,r){if("number"==typeof e)throw new TypeError("Argument must not be a number");return n(e,t,r)},i.alloc=function(e,t,r){if("number"!=typeof e)throw new TypeError("Argument must be a number");var A=n(e);return void 0!==t?"string"==typeof r?A.fill(t,r):A.fill(t):A.fill(0),A},i.allocUnsafe=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return n(e)},i.allocUnsafeSlow=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return A.SlowBuffer(e)}},95584:(e,t)=>{var r;t=e.exports=l,r="object"==typeof process&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?function(){var e=Array.prototype.slice.call(arguments,0);e.unshift("SEMVER"),console.log.apply(console,e)}:function(){},t.SEMVER_SPEC_VERSION="2.0.0";var A=Number.MAX_SAFE_INTEGER||9007199254740991,n=t.re=[],o=t.src=[],i=t.tokens={},s=0;function a(e){i[e]=s++}a("NUMERICIDENTIFIER"),o[i.NUMERICIDENTIFIER]="0|[1-9]\\d*",a("NUMERICIDENTIFIERLOOSE"),o[i.NUMERICIDENTIFIERLOOSE]="[0-9]+",a("NONNUMERICIDENTIFIER"),o[i.NONNUMERICIDENTIFIER]="\\d*[a-zA-Z-][a-zA-Z0-9-]*",a("MAINVERSION"),o[i.MAINVERSION]="("+o[i.NUMERICIDENTIFIER]+")\\.("+o[i.NUMERICIDENTIFIER]+")\\.("+o[i.NUMERICIDENTIFIER]+")",a("MAINVERSIONLOOSE"),o[i.MAINVERSIONLOOSE]="("+o[i.NUMERICIDENTIFIERLOOSE]+")\\.("+o[i.NUMERICIDENTIFIERLOOSE]+")\\.("+o[i.NUMERICIDENTIFIERLOOSE]+")",a("PRERELEASEIDENTIFIER"),o[i.PRERELEASEIDENTIFIER]="(?:"+o[i.NUMERICIDENTIFIER]+"|"+o[i.NONNUMERICIDENTIFIER]+")",a("PRERELEASEIDENTIFIERLOOSE"),o[i.PRERELEASEIDENTIFIERLOOSE]="(?:"+o[i.NUMERICIDENTIFIERLOOSE]+"|"+o[i.NONNUMERICIDENTIFIER]+")",a("PRERELEASE"),o[i.PRERELEASE]="(?:-("+o[i.PRERELEASEIDENTIFIER]+"(?:\\."+o[i.PRERELEASEIDENTIFIER]+")*))",a("PRERELEASELOOSE"),o[i.PRERELEASELOOSE]="(?:-?("+o[i.PRERELEASEIDENTIFIERLOOSE]+"(?:\\."+o[i.PRERELEASEIDENTIFIERLOOSE]+")*))",a("BUILDIDENTIFIER"),o[i.BUILDIDENTIFIER]="[0-9A-Za-z-]+",a("BUILD"),o[i.BUILD]="(?:\\+("+o[i.BUILDIDENTIFIER]+"(?:\\."+o[i.BUILDIDENTIFIER]+")*))",a("FULL"),a("FULLPLAIN"),o[i.FULLPLAIN]="v?"+o[i.MAINVERSION]+o[i.PRERELEASE]+"?"+o[i.BUILD]+"?",o[i.FULL]="^"+o[i.FULLPLAIN]+"$",a("LOOSEPLAIN"),o[i.LOOSEPLAIN]="[v=\\s]*"+o[i.MAINVERSIONLOOSE]+o[i.PRERELEASELOOSE]+"?"+o[i.BUILD]+"?",a("LOOSE"),o[i.LOOSE]="^"+o[i.LOOSEPLAIN]+"$",a("GTLT"),o[i.GTLT]="((?:<|>)?=?)",a("XRANGEIDENTIFIERLOOSE"),o[i.XRANGEIDENTIFIERLOOSE]=o[i.NUMERICIDENTIFIERLOOSE]+"|x|X|\\*",a("XRANGEIDENTIFIER"),o[i.XRANGEIDENTIFIER]=o[i.NUMERICIDENTIFIER]+"|x|X|\\*",a("XRANGEPLAIN"),o[i.XRANGEPLAIN]="[v=\\s]*("+o[i.XRANGEIDENTIFIER]+")(?:\\.("+o[i.XRANGEIDENTIFIER]+")(?:\\.("+o[i.XRANGEIDENTIFIER]+")(?:"+o[i.PRERELEASE]+")?"+o[i.BUILD]+"?)?)?",a("XRANGEPLAINLOOSE"),o[i.XRANGEPLAINLOOSE]="[v=\\s]*("+o[i.XRANGEIDENTIFIERLOOSE]+")(?:\\.("+o[i.XRANGEIDENTIFIERLOOSE]+")(?:\\.("+o[i.XRANGEIDENTIFIERLOOSE]+")(?:"+o[i.PRERELEASELOOSE]+")?"+o[i.BUILD]+"?)?)?",a("XRANGE"),o[i.XRANGE]="^"+o[i.GTLT]+"\\s*"+o[i.XRANGEPLAIN]+"$",a("XRANGELOOSE"),o[i.XRANGELOOSE]="^"+o[i.GTLT]+"\\s*"+o[i.XRANGEPLAINLOOSE]+"$",a("COERCE"),o[i.COERCE]="(^|[^\\d])(\\d{1,16})(?:\\.(\\d{1,16}))?(?:\\.(\\d{1,16}))?(?:$|[^\\d])",a("COERCERTL"),n[i.COERCERTL]=new RegExp(o[i.COERCE],"g"),a("LONETILDE"),o[i.LONETILDE]="(?:~>?)",a("TILDETRIM"),o[i.TILDETRIM]="(\\s*)"+o[i.LONETILDE]+"\\s+",n[i.TILDETRIM]=new RegExp(o[i.TILDETRIM],"g");a("TILDE"),o[i.TILDE]="^"+o[i.LONETILDE]+o[i.XRANGEPLAIN]+"$",a("TILDELOOSE"),o[i.TILDELOOSE]="^"+o[i.LONETILDE]+o[i.XRANGEPLAINLOOSE]+"$",a("LONECARET"),o[i.LONECARET]="(?:\\^)",a("CARETTRIM"),o[i.CARETTRIM]="(\\s*)"+o[i.LONECARET]+"\\s+",n[i.CARETTRIM]=new RegExp(o[i.CARETTRIM],"g");a("CARET"),o[i.CARET]="^"+o[i.LONECARET]+o[i.XRANGEPLAIN]+"$",a("CARETLOOSE"),o[i.CARETLOOSE]="^"+o[i.LONECARET]+o[i.XRANGEPLAINLOOSE]+"$",a("COMPARATORLOOSE"),o[i.COMPARATORLOOSE]="^"+o[i.GTLT]+"\\s*("+o[i.LOOSEPLAIN]+")$|^$",a("COMPARATOR"),o[i.COMPARATOR]="^"+o[i.GTLT]+"\\s*("+o[i.FULLPLAIN]+")$|^$",a("COMPARATORTRIM"),o[i.COMPARATORTRIM]="(\\s*)"+o[i.GTLT]+"\\s*("+o[i.LOOSEPLAIN]+"|"+o[i.XRANGEPLAIN]+")",n[i.COMPARATORTRIM]=new RegExp(o[i.COMPARATORTRIM],"g");a("HYPHENRANGE"),o[i.HYPHENRANGE]="^\\s*("+o[i.XRANGEPLAIN]+")\\s+-\\s+("+o[i.XRANGEPLAIN]+")\\s*$",a("HYPHENRANGELOOSE"),o[i.HYPHENRANGELOOSE]="^\\s*("+o[i.XRANGEPLAINLOOSE]+")\\s+-\\s+("+o[i.XRANGEPLAINLOOSE]+")\\s*$",a("STAR"),o[i.STAR]="(<|>)?=?\\s*\\*";for(var c=0;c256)return null;if(!(t.loose?n[i.LOOSE]:n[i.FULL]).test(e))return null;try{return new l(e,t)}catch(e){return null}}function l(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof l){if(e.loose===t.loose)return e;e=e.version}else if("string"!=typeof e)throw new TypeError("Invalid Version: "+e);if(e.length>256)throw new TypeError("version is longer than 256 characters");if(!(this instanceof l))return new l(e,t);r("SemVer",e,t),this.options=t,this.loose=!!t.loose;var o=e.trim().match(t.loose?n[i.LOOSE]:n[i.FULL]);if(!o)throw new TypeError("Invalid Version: "+e);if(this.raw=e,this.major=+o[1],this.minor=+o[2],this.patch=+o[3],this.major>A||this.major<0)throw new TypeError("Invalid major version");if(this.minor>A||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>A||this.patch<0)throw new TypeError("Invalid patch version");o[4]?this.prerelease=o[4].split(".").map((function(e){if(/^[0-9]+$/.test(e)){var t=+e;if(t>=0&&t=0;)"number"==typeof this.prerelease[r]&&(this.prerelease[r]++,r=-2);-1===r&&this.prerelease.push(0)}t&&(this.prerelease[0]===t?isNaN(this.prerelease[1])&&(this.prerelease=[t,0]):this.prerelease=[t,0]);break;default:throw new Error("invalid increment argument: "+e)}return this.format(),this.raw=this.version,this},t.inc=function(e,t,r,A){"string"==typeof r&&(A=r,r=void 0);try{return new l(e,r).inc(t,A).version}catch(e){return null}},t.diff=function(e,t){if(f(e,t))return null;var r=g(e),A=g(t),n="";if(r.prerelease.length||A.prerelease.length){n="pre";var o="prerelease"}for(var i in r)if(("major"===i||"minor"===i||"patch"===i)&&r[i]!==A[i])return n+i;return o},t.compareIdentifiers=h;var u=/^[0-9]+$/;function h(e,t){var r=u.test(e),A=u.test(t);return r&&A&&(e=+e,t=+t),e===t?0:r&&!A?-1:A&&!r?1:e0}function C(e,t,r){return p(e,t,r)<0}function f(e,t,r){return 0===p(e,t,r)}function I(e,t,r){return 0!==p(e,t,r)}function E(e,t,r){return p(e,t,r)>=0}function B(e,t,r){return p(e,t,r)<=0}function y(e,t,r,A){switch(t){case"===":return"object"==typeof e&&(e=e.version),"object"==typeof r&&(r=r.version),e===r;case"!==":return"object"==typeof e&&(e=e.version),"object"==typeof r&&(r=r.version),e!==r;case"":case"=":case"==":return f(e,r,A);case"!=":return I(e,r,A);case">":return d(e,r,A);case">=":return E(e,r,A);case"<":return C(e,r,A);case"<=":return B(e,r,A);default:throw new TypeError("Invalid operator: "+t)}}function m(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof m){if(e.loose===!!t.loose)return e;e=e.value}if(!(this instanceof m))return new m(e,t);r("comparator",e,t),this.options=t,this.loose=!!t.loose,this.parse(e),this.semver===w?this.value="":this.value=this.operator+this.semver.version,r("comp",this)}t.rcompareIdentifiers=function(e,t){return h(t,e)},t.major=function(e,t){return new l(e,t).major},t.minor=function(e,t){return new l(e,t).minor},t.patch=function(e,t){return new l(e,t).patch},t.compare=p,t.compareLoose=function(e,t){return p(e,t,!0)},t.compareBuild=function(e,t,r){var A=new l(e,r),n=new l(t,r);return A.compare(n)||A.compareBuild(n)},t.rcompare=function(e,t,r){return p(t,e,r)},t.sort=function(e,r){return e.sort((function(e,A){return t.compareBuild(e,A,r)}))},t.rsort=function(e,r){return e.sort((function(e,A){return t.compareBuild(A,e,r)}))},t.gt=d,t.lt=C,t.eq=f,t.neq=I,t.gte=E,t.lte=B,t.cmp=y,t.Comparator=m;var w={};function Q(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof Q)return e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease?e:new Q(e.raw,t);if(e instanceof m)return new Q(e.value,t);if(!(this instanceof Q))return new Q(e,t);if(this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease,this.raw=e,this.set=e.split(/\s*\|\|\s*/).map((function(e){return this.parseRange(e.trim())}),this).filter((function(e){return e.length})),!this.set.length)throw new TypeError("Invalid SemVer Range: "+e);this.format()}function D(e,t){for(var r=!0,A=e.slice(),n=A.pop();r&&A.length;)r=A.every((function(e){return n.intersects(e,t)})),n=A.pop();return r}function b(e){return!e||"x"===e.toLowerCase()||"*"===e}function v(e,t,r,A,n,o,i,s,a,c,g,l,u){return((t=b(r)?"":b(A)?">="+r+".0.0":b(n)?">="+r+"."+A+".0":">="+t)+" "+(s=b(a)?"":b(c)?"<"+(+a+1)+".0.0":b(g)?"<"+a+"."+(+c+1)+".0":l?"<="+a+"."+c+"."+g+"-"+l:"<="+s)).trim()}function S(e,t,A){for(var n=0;n0){var o=e[n].semver;if(o.major===t.major&&o.minor===t.minor&&o.patch===t.patch)return!0}return!1}return!0}function k(e,t,r){try{t=new Q(t,r)}catch(e){return!1}return t.test(e)}function N(e,t,r,A){var n,o,i,s,a;switch(e=new l(e,A),t=new Q(t,A),r){case">":n=d,o=B,i=C,s=">",a=">=";break;case"<":n=C,o=E,i=d,s="<",a="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(k(e,t,A))return!1;for(var c=0;c=0.0.0")),u=u||e,h=h||e,n(e.semver,u.semver,A)?u=e:i(e.semver,h.semver,A)&&(h=e)})),u.operator===s||u.operator===a)return!1;if((!h.operator||h.operator===s)&&o(e,h.semver))return!1;if(h.operator===a&&i(e,h.semver))return!1}return!0}m.prototype.parse=function(e){var t=this.options.loose?n[i.COMPARATORLOOSE]:n[i.COMPARATOR],r=e.match(t);if(!r)throw new TypeError("Invalid comparator: "+e);this.operator=void 0!==r[1]?r[1]:"","="===this.operator&&(this.operator=""),r[2]?this.semver=new l(r[2],this.options.loose):this.semver=w},m.prototype.toString=function(){return this.value},m.prototype.test=function(e){if(r("Comparator.test",e,this.options.loose),this.semver===w||e===w)return!0;if("string"==typeof e)try{e=new l(e,this.options)}catch(e){return!1}return y(e,this.operator,this.semver,this.options)},m.prototype.intersects=function(e,t){if(!(e instanceof m))throw new TypeError("a Comparator is required");var r;if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),""===this.operator)return""===this.value||(r=new Q(e.value,t),k(this.value,r,t));if(""===e.operator)return""===e.value||(r=new Q(this.value,t),k(e.semver,r,t));var A=!(">="!==this.operator&&">"!==this.operator||">="!==e.operator&&">"!==e.operator),n=!("<="!==this.operator&&"<"!==this.operator||"<="!==e.operator&&"<"!==e.operator),o=this.semver.version===e.semver.version,i=!(">="!==this.operator&&"<="!==this.operator||">="!==e.operator&&"<="!==e.operator),s=y(this.semver,"<",e.semver,t)&&(">="===this.operator||">"===this.operator)&&("<="===e.operator||"<"===e.operator),a=y(this.semver,">",e.semver,t)&&("<="===this.operator||"<"===this.operator)&&(">="===e.operator||">"===e.operator);return A||n||o&&i||s||a},t.Range=Q,Q.prototype.format=function(){return this.range=this.set.map((function(e){return e.join(" ").trim()})).join("||").trim(),this.range},Q.prototype.toString=function(){return this.range},Q.prototype.parseRange=function(e){var t=this.options.loose;e=e.trim();var A=t?n[i.HYPHENRANGELOOSE]:n[i.HYPHENRANGE];e=e.replace(A,v),r("hyphen replace",e),e=e.replace(n[i.COMPARATORTRIM],"$1$2$3"),r("comparator trim",e,n[i.COMPARATORTRIM]),e=(e=(e=e.replace(n[i.TILDETRIM],"$1~")).replace(n[i.CARETTRIM],"$1^")).split(/\s+/).join(" ");var o=t?n[i.COMPARATORLOOSE]:n[i.COMPARATOR],s=e.split(" ").map((function(e){return function(e,t){return r("comp",e,t),e=function(e,t){return e.trim().split(/\s+/).map((function(e){return function(e,t){r("caret",e,t);var A=t.loose?n[i.CARETLOOSE]:n[i.CARET];return e.replace(A,(function(t,A,n,o,i){var s;return r("caret",e,t,A,n,o,i),b(A)?s="":b(n)?s=">="+A+".0.0 <"+(+A+1)+".0.0":b(o)?s="0"===A?">="+A+"."+n+".0 <"+A+"."+(+n+1)+".0":">="+A+"."+n+".0 <"+(+A+1)+".0.0":i?(r("replaceCaret pr",i),s="0"===A?"0"===n?">="+A+"."+n+"."+o+"-"+i+" <"+A+"."+n+"."+(+o+1):">="+A+"."+n+"."+o+"-"+i+" <"+A+"."+(+n+1)+".0":">="+A+"."+n+"."+o+"-"+i+" <"+(+A+1)+".0.0"):(r("no pr"),s="0"===A?"0"===n?">="+A+"."+n+"."+o+" <"+A+"."+n+"."+(+o+1):">="+A+"."+n+"."+o+" <"+A+"."+(+n+1)+".0":">="+A+"."+n+"."+o+" <"+(+A+1)+".0.0"),r("caret return",s),s}))}(e,t)})).join(" ")}(e,t),r("caret",e),e=function(e,t){return e.trim().split(/\s+/).map((function(e){return function(e,t){var A=t.loose?n[i.TILDELOOSE]:n[i.TILDE];return e.replace(A,(function(t,A,n,o,i){var s;return r("tilde",e,t,A,n,o,i),b(A)?s="":b(n)?s=">="+A+".0.0 <"+(+A+1)+".0.0":b(o)?s=">="+A+"."+n+".0 <"+A+"."+(+n+1)+".0":i?(r("replaceTilde pr",i),s=">="+A+"."+n+"."+o+"-"+i+" <"+A+"."+(+n+1)+".0"):s=">="+A+"."+n+"."+o+" <"+A+"."+(+n+1)+".0",r("tilde return",s),s}))}(e,t)})).join(" ")}(e,t),r("tildes",e),e=function(e,t){return r("replaceXRanges",e,t),e.split(/\s+/).map((function(e){return function(e,t){e=e.trim();var A=t.loose?n[i.XRANGELOOSE]:n[i.XRANGE];return e.replace(A,(function(A,n,o,i,s,a){r("xRange",e,A,n,o,i,s,a);var c=b(o),g=c||b(i),l=g||b(s),u=l;return"="===n&&u&&(n=""),a=t.includePrerelease?"-0":"",c?A=">"===n||"<"===n?"<0.0.0-0":"*":n&&u?(g&&(i=0),s=0,">"===n?(n=">=",g?(o=+o+1,i=0,s=0):(i=+i+1,s=0)):"<="===n&&(n="<",g?o=+o+1:i=+i+1),A=n+o+"."+i+"."+s+a):g?A=">="+o+".0.0"+a+" <"+(+o+1)+".0.0"+a:l&&(A=">="+o+"."+i+".0"+a+" <"+o+"."+(+i+1)+".0"+a),r("xRange return",A),A}))}(e,t)})).join(" ")}(e,t),r("xrange",e),e=function(e,t){return r("replaceStars",e,t),e.trim().replace(n[i.STAR],"")}(e,t),r("stars",e),e}(e,this.options)}),this).join(" ").split(/\s+/);return this.options.loose&&(s=s.filter((function(e){return!!e.match(o)}))),s=s.map((function(e){return new m(e,this.options)}),this)},Q.prototype.intersects=function(e,t){if(!(e instanceof Q))throw new TypeError("a Range is required");return this.set.some((function(r){return D(r,t)&&e.set.some((function(e){return D(e,t)&&r.every((function(r){return e.every((function(e){return r.intersects(e,t)}))}))}))}))},t.toComparators=function(e,t){return new Q(e,t).set.map((function(e){return e.map((function(e){return e.value})).join(" ").trim().split(" ")}))},Q.prototype.test=function(e){if(!e)return!1;if("string"==typeof e)try{e=new l(e,this.options)}catch(e){return!1}for(var t=0;t":0===t.prerelease.length?t.patch++:t.prerelease.push(0),t.raw=t.format();case"":case">=":r&&!d(r,t)||(r=t);break;case"<":case"<=":break;default:throw new Error("Unexpected operation: "+e.operator)}}))}if(r&&e.test(r))return r;return null},t.validRange=function(e,t){try{return new Q(e,t).range||"*"}catch(e){return null}},t.ltr=function(e,t,r){return N(e,t,"<",r)},t.gtr=function(e,t,r){return N(e,t,">",r)},t.outside=N,t.prerelease=function(e,t){var r=g(e,t);return r&&r.prerelease.length?r.prerelease:null},t.intersects=function(e,t,r){return e=new Q(e,r),t=new Q(t,r),e.intersects(t)},t.coerce=function(e,t){if(e instanceof l)return e;"number"==typeof e&&(e=String(e));if("string"!=typeof e)return null;var r=null;if((t=t||{}).rtl){for(var A;(A=n[i.COERCERTL].exec(e))&&(!r||r.index+r[0].length!==e.length);)r&&A.index+A[0].length===r.index+r[0].length||(r=A),n[i.COERCERTL].lastIndex=A.index+A[1].length+A[2].length;n[i.COERCERTL].lastIndex=-1}else r=e.match(n[i.COERCE]);if(null===r)return null;return g(r[2]+"."+(r[3]||"0")+"."+(r[4]||"0"),t)}},29069:(e,t,r)=>{const A=Symbol("SemVer ANY");class n{static get ANY(){return A}constructor(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof n){if(e.loose===!!t.loose)return e;e=e.value}a("comparator",e,t),this.options=t,this.loose=!!t.loose,this.parse(e),this.semver===A?this.value="":this.value=this.operator+this.semver.version,a("comp",this)}parse(e){const t=this.options.loose?o[i.COMPARATORLOOSE]:o[i.COMPARATOR],r=e.match(t);if(!r)throw new TypeError("Invalid comparator: "+e);this.operator=void 0!==r[1]?r[1]:"","="===this.operator&&(this.operator=""),r[2]?this.semver=new c(r[2],this.options.loose):this.semver=A}toString(){return this.value}test(e){if(a("Comparator.test",e,this.options.loose),this.semver===A||e===A)return!0;if("string"==typeof e)try{e=new c(e,this.options)}catch(e){return!1}return s(e,this.operator,this.semver,this.options)}intersects(e,t){if(!(e instanceof n))throw new TypeError("a Comparator is required");if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),""===this.operator)return""===this.value||new g(e.value,t).test(this.value);if(""===e.operator)return""===e.value||new g(this.value,t).test(e.semver);const r=!(">="!==this.operator&&">"!==this.operator||">="!==e.operator&&">"!==e.operator),A=!("<="!==this.operator&&"<"!==this.operator||"<="!==e.operator&&"<"!==e.operator),o=this.semver.version===e.semver.version,i=!(">="!==this.operator&&"<="!==this.operator||">="!==e.operator&&"<="!==e.operator),a=s(this.semver,"<",e.semver,t)&&(">="===this.operator||">"===this.operator)&&("<="===e.operator||"<"===e.operator),c=s(this.semver,">",e.semver,t)&&("<="===this.operator||"<"===this.operator)&&(">="===e.operator||">"===e.operator);return r||A||o&&i||a||c}}e.exports=n;const{re:o,t:i}=r(49439),s=r(38754),a=r(6029),c=r(14772),g=r(73004)},73004:(e,t,r)=>{class A{constructor(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof A)return e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease?e:new A(e.raw,t);if(e instanceof n)return this.raw=e.value,this.set=[[e]],this.format(),this;if(this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease,this.raw=e,this.set=e.split(/\s*\|\|\s*/).map(e=>this.parseRange(e.trim())).filter(e=>e.length),!this.set.length)throw new TypeError("Invalid SemVer Range: "+e);this.format()}format(){return this.range=this.set.map(e=>e.join(" ").trim()).join("||").trim(),this.range}toString(){return this.range}parseRange(e){const t=this.options.loose;e=e.trim();const r=t?s[a.HYPHENRANGELOOSE]:s[a.HYPHENRANGE];e=e.replace(r,w(this.options.includePrerelease)),o("hyphen replace",e),e=e.replace(s[a.COMPARATORTRIM],c),o("comparator trim",e,s[a.COMPARATORTRIM]),e=(e=(e=e.replace(s[a.TILDETRIM],g)).replace(s[a.CARETTRIM],l)).split(/\s+/).join(" ");const A=t?s[a.COMPARATORLOOSE]:s[a.COMPARATOR];return e.split(" ").map(e=>h(e,this.options)).join(" ").split(/\s+/).map(e=>m(e,this.options)).filter(this.options.loose?e=>!!e.match(A):()=>!0).map(e=>new n(e,this.options))}intersects(e,t){if(!(e instanceof A))throw new TypeError("a Range is required");return this.set.some(r=>u(r,t)&&e.set.some(e=>u(e,t)&&r.every(r=>e.every(e=>r.intersects(e,t)))))}test(e){if(!e)return!1;if("string"==typeof e)try{e=new i(e,this.options)}catch(e){return!1}for(let t=0;t{let r=!0;const A=e.slice();let n=A.pop();for(;r&&A.length;)r=A.every(e=>n.intersects(e,t)),n=A.pop();return r},h=(e,t)=>(o("comp",e,t),e=f(e,t),o("caret",e),e=d(e,t),o("tildes",e),e=E(e,t),o("xrange",e),e=y(e,t),o("stars",e),e),p=e=>!e||"x"===e.toLowerCase()||"*"===e,d=(e,t)=>e.trim().split(/\s+/).map(e=>C(e,t)).join(" "),C=(e,t)=>{const r=t.loose?s[a.TILDELOOSE]:s[a.TILDE];return e.replace(r,(t,r,A,n,i)=>{let s;return o("tilde",e,t,r,A,n,i),p(r)?s="":p(A)?s=`>=${r}.0.0 <${+r+1}.0.0-0`:p(n)?s=`>=${r}.${A}.0 <${r}.${+A+1}.0-0`:i?(o("replaceTilde pr",i),s=`>=${r}.${A}.${n}-${i} <${r}.${+A+1}.0-0`):s=`>=${r}.${A}.${n} <${r}.${+A+1}.0-0`,o("tilde return",s),s})},f=(e,t)=>e.trim().split(/\s+/).map(e=>I(e,t)).join(" "),I=(e,t)=>{o("caret",e,t);const r=t.loose?s[a.CARETLOOSE]:s[a.CARET],A=t.includePrerelease?"-0":"";return e.replace(r,(t,r,n,i,s)=>{let a;return o("caret",e,t,r,n,i,s),p(r)?a="":p(n)?a=`>=${r}.0.0${A} <${+r+1}.0.0-0`:p(i)?a="0"===r?`>=${r}.${n}.0${A} <${r}.${+n+1}.0-0`:`>=${r}.${n}.0${A} <${+r+1}.0.0-0`:s?(o("replaceCaret pr",s),a="0"===r?"0"===n?`>=${r}.${n}.${i}-${s} <${r}.${n}.${+i+1}-0`:`>=${r}.${n}.${i}-${s} <${r}.${+n+1}.0-0`:`>=${r}.${n}.${i}-${s} <${+r+1}.0.0-0`):(o("no pr"),a="0"===r?"0"===n?`>=${r}.${n}.${i}${A} <${r}.${n}.${+i+1}-0`:`>=${r}.${n}.${i}${A} <${r}.${+n+1}.0-0`:`>=${r}.${n}.${i} <${+r+1}.0.0-0`),o("caret return",a),a})},E=(e,t)=>(o("replaceXRanges",e,t),e.split(/\s+/).map(e=>B(e,t)).join(" ")),B=(e,t)=>{e=e.trim();const r=t.loose?s[a.XRANGELOOSE]:s[a.XRANGE];return e.replace(r,(r,A,n,i,s,a)=>{o("xRange",e,r,A,n,i,s,a);const c=p(n),g=c||p(i),l=g||p(s),u=l;return"="===A&&u&&(A=""),a=t.includePrerelease?"-0":"",c?r=">"===A||"<"===A?"<0.0.0-0":"*":A&&u?(g&&(i=0),s=0,">"===A?(A=">=",g?(n=+n+1,i=0,s=0):(i=+i+1,s=0)):"<="===A&&(A="<",g?n=+n+1:i=+i+1),"<"===A&&(a="-0"),r=`${A+n}.${i}.${s}${a}`):g?r=`>=${n}.0.0${a} <${+n+1}.0.0-0`:l&&(r=`>=${n}.${i}.0${a} <${n}.${+i+1}.0-0`),o("xRange return",r),r})},y=(e,t)=>(o("replaceStars",e,t),e.trim().replace(s[a.STAR],"")),m=(e,t)=>(o("replaceGTE0",e,t),e.trim().replace(s[t.includePrerelease?a.GTE0PRE:a.GTE0],"")),w=e=>(t,r,A,n,o,i,s,a,c,g,l,u,h)=>`${r=p(A)?"":p(n)?`>=${A}.0.0${e?"-0":""}`:p(o)?`>=${A}.${n}.0${e?"-0":""}`:i?">="+r:`>=${r}${e?"-0":""}`} ${a=p(c)?"":p(g)?`<${+c+1}.0.0-0`:p(l)?`<${c}.${+g+1}.0-0`:u?`<=${c}.${g}.${l}-${u}`:e?`<${c}.${g}.${+l+1}-0`:"<="+a}`.trim(),Q=(e,t,r)=>{for(let r=0;r0){const A=e[r].semver;if(A.major===t.major&&A.minor===t.minor&&A.patch===t.patch)return!0}return!1}return!0}},14772:(e,t,r)=>{const A=r(6029),{MAX_LENGTH:n,MAX_SAFE_INTEGER:o}=r(76483),{re:i,t:s}=r(49439),{compareIdentifiers:a}=r(99297);class c{constructor(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof c){if(e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease)return e;e=e.version}else if("string"!=typeof e)throw new TypeError("Invalid Version: "+e);if(e.length>n)throw new TypeError(`version is longer than ${n} characters`);A("SemVer",e,t),this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease;const r=e.trim().match(t.loose?i[s.LOOSE]:i[s.FULL]);if(!r)throw new TypeError("Invalid Version: "+e);if(this.raw=e,this.major=+r[1],this.minor=+r[2],this.patch=+r[3],this.major>o||this.major<0)throw new TypeError("Invalid major version");if(this.minor>o||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>o||this.patch<0)throw new TypeError("Invalid patch version");r[4]?this.prerelease=r[4].split(".").map(e=>{if(/^[0-9]+$/.test(e)){const t=+e;if(t>=0&&t=0;)"number"==typeof this.prerelease[e]&&(this.prerelease[e]++,e=-2);-1===e&&this.prerelease.push(0)}t&&(this.prerelease[0]===t?isNaN(this.prerelease[1])&&(this.prerelease=[t,0]):this.prerelease=[t,0]);break;default:throw new Error("invalid increment argument: "+e)}return this.format(),this.raw=this.version,this}}e.exports=c},31192:(e,t,r)=>{const A=r(21883);e.exports=(e,t)=>{const r=A(e.trim().replace(/^[=v]+/,""),t);return r?r.version:null}},38754:(e,t,r)=>{const A=r(78760),n=r(83286),o=r(26544),i=r(44984),s=r(65069),a=r(93845);e.exports=(e,t,r,c)=>{switch(t){case"===":return"object"==typeof e&&(e=e.version),"object"==typeof r&&(r=r.version),e===r;case"!==":return"object"==typeof e&&(e=e.version),"object"==typeof r&&(r=r.version),e!==r;case"":case"=":case"==":return A(e,r,c);case"!=":return n(e,r,c);case">":return o(e,r,c);case">=":return i(e,r,c);case"<":return s(e,r,c);case"<=":return a(e,r,c);default:throw new TypeError("Invalid operator: "+t)}}},38113:(e,t,r)=>{const A=r(14772),n=r(21883),{re:o,t:i}=r(49439);e.exports=(e,t)=>{if(e instanceof A)return e;if("number"==typeof e&&(e=String(e)),"string"!=typeof e)return null;let r=null;if((t=t||{}).rtl){let t;for(;(t=o[i.COERCERTL].exec(e))&&(!r||r.index+r[0].length!==e.length);)r&&t.index+t[0].length===r.index+r[0].length||(r=t),o[i.COERCERTL].lastIndex=t.index+t[1].length+t[2].length;o[i.COERCERTL].lastIndex=-1}else r=e.match(o[i.COERCE]);return null===r?null:n(`${r[2]}.${r[3]||"0"}.${r[4]||"0"}`,t)}},63353:(e,t,r)=>{const A=r(14772);e.exports=(e,t,r)=>{const n=new A(e,r),o=new A(t,r);return n.compare(o)||n.compareBuild(o)}},58566:(e,t,r)=>{const A=r(17340);e.exports=(e,t)=>A(e,t,!0)},17340:(e,t,r)=>{const A=r(14772);e.exports=(e,t,r)=>new A(e,r).compare(new A(t,r))},29301:(e,t,r)=>{const A=r(21883),n=r(78760);e.exports=(e,t)=>{if(n(e,t))return null;{const r=A(e),n=A(t),o=r.prerelease.length||n.prerelease.length,i=o?"pre":"",s=o?"prerelease":"";for(const e in r)if(("major"===e||"minor"===e||"patch"===e)&&r[e]!==n[e])return i+e;return s}}},78760:(e,t,r)=>{const A=r(17340);e.exports=(e,t,r)=>0===A(e,t,r)},26544:(e,t,r)=>{const A=r(17340);e.exports=(e,t,r)=>A(e,t,r)>0},44984:(e,t,r)=>{const A=r(17340);e.exports=(e,t,r)=>A(e,t,r)>=0},24063:(e,t,r)=>{const A=r(14772);e.exports=(e,t,r,n)=>{"string"==typeof r&&(n=r,r=void 0);try{return new A(e,r).inc(t,n).version}catch(e){return null}}},65069:(e,t,r)=>{const A=r(17340);e.exports=(e,t,r)=>A(e,t,r)<0},93845:(e,t,r)=>{const A=r(17340);e.exports=(e,t,r)=>A(e,t,r)<=0},75157:(e,t,r)=>{const A=r(14772);e.exports=(e,t)=>new A(e,t).major},5195:(e,t,r)=>{const A=r(14772);e.exports=(e,t)=>new A(e,t).minor},83286:(e,t,r)=>{const A=r(17340);e.exports=(e,t,r)=>0!==A(e,t,r)},21883:(e,t,r)=>{const{MAX_LENGTH:A}=r(76483),{re:n,t:o}=r(49439),i=r(14772);e.exports=(e,t)=>{if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof i)return e;if("string"!=typeof e)return null;if(e.length>A)return null;if(!(t.loose?n[o.LOOSE]:n[o.FULL]).test(e))return null;try{return new i(e,t)}catch(e){return null}}},39592:(e,t,r)=>{const A=r(14772);e.exports=(e,t)=>new A(e,t).patch},27050:(e,t,r)=>{const A=r(21883);e.exports=(e,t)=>{const r=A(e,t);return r&&r.prerelease.length?r.prerelease:null}},93788:(e,t,r)=>{const A=r(17340);e.exports=(e,t,r)=>A(t,e,r)},15213:(e,t,r)=>{const A=r(63353);e.exports=(e,t)=>e.sort((e,r)=>A(r,e,t))},73011:(e,t,r)=>{const A=r(73004);e.exports=(e,t,r)=>{try{t=new A(t,r)}catch(e){return!1}return t.test(e)}},71102:(e,t,r)=>{const A=r(63353);e.exports=(e,t)=>e.sort((e,r)=>A(e,r,t))},99589:(e,t,r)=>{const A=r(21883);e.exports=(e,t)=>{const r=A(e,t);return r?r.version:null}},53887:(e,t,r)=>{const A=r(49439);e.exports={re:A.re,src:A.src,tokens:A.t,SEMVER_SPEC_VERSION:r(76483).SEMVER_SPEC_VERSION,SemVer:r(14772),compareIdentifiers:r(99297).compareIdentifiers,rcompareIdentifiers:r(99297).rcompareIdentifiers,parse:r(21883),valid:r(99589),clean:r(31192),inc:r(24063),diff:r(29301),major:r(75157),minor:r(5195),patch:r(39592),prerelease:r(27050),compare:r(17340),rcompare:r(93788),compareLoose:r(58566),compareBuild:r(63353),sort:r(71102),rsort:r(15213),gt:r(26544),lt:r(65069),eq:r(78760),neq:r(83286),gte:r(44984),lte:r(93845),cmp:r(38754),coerce:r(38113),Comparator:r(29069),Range:r(73004),satisfies:r(73011),toComparators:r(47753),maxSatisfying:r(1895),minSatisfying:r(33252),minVersion:r(4224),validRange:r(44315),outside:r(842),gtr:r(69258),ltr:r(36928),intersects:r(87395),simplifyRange:r(3530),subset:r(74264)}},76483:e=>{const t=Number.MAX_SAFE_INTEGER||9007199254740991;e.exports={SEMVER_SPEC_VERSION:"2.0.0",MAX_LENGTH:256,MAX_SAFE_INTEGER:t,MAX_SAFE_COMPONENT_LENGTH:16}},6029:e=>{const t="object"==typeof process&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...e)=>console.error("SEMVER",...e):()=>{};e.exports=t},99297:e=>{const t=/^[0-9]+$/,r=(e,r)=>{const A=t.test(e),n=t.test(r);return A&&n&&(e=+e,r=+r),e===r?0:A&&!n?-1:n&&!A?1:er(t,e)}},49439:(e,t,r)=>{const{MAX_SAFE_COMPONENT_LENGTH:A}=r(76483),n=r(6029),o=(t=e.exports={}).re=[],i=t.src=[],s=t.t={};let a=0;const c=(e,t,r)=>{const A=a++;n(A,t),s[e]=A,i[A]=t,o[A]=new RegExp(t,r?"g":void 0)};c("NUMERICIDENTIFIER","0|[1-9]\\d*"),c("NUMERICIDENTIFIERLOOSE","[0-9]+"),c("NONNUMERICIDENTIFIER","\\d*[a-zA-Z-][a-zA-Z0-9-]*"),c("MAINVERSION",`(${i[s.NUMERICIDENTIFIER]})\\.(${i[s.NUMERICIDENTIFIER]})\\.(${i[s.NUMERICIDENTIFIER]})`),c("MAINVERSIONLOOSE",`(${i[s.NUMERICIDENTIFIERLOOSE]})\\.(${i[s.NUMERICIDENTIFIERLOOSE]})\\.(${i[s.NUMERICIDENTIFIERLOOSE]})`),c("PRERELEASEIDENTIFIER",`(?:${i[s.NUMERICIDENTIFIER]}|${i[s.NONNUMERICIDENTIFIER]})`),c("PRERELEASEIDENTIFIERLOOSE",`(?:${i[s.NUMERICIDENTIFIERLOOSE]}|${i[s.NONNUMERICIDENTIFIER]})`),c("PRERELEASE",`(?:-(${i[s.PRERELEASEIDENTIFIER]}(?:\\.${i[s.PRERELEASEIDENTIFIER]})*))`),c("PRERELEASELOOSE",`(?:-?(${i[s.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${i[s.PRERELEASEIDENTIFIERLOOSE]})*))`),c("BUILDIDENTIFIER","[0-9A-Za-z-]+"),c("BUILD",`(?:\\+(${i[s.BUILDIDENTIFIER]}(?:\\.${i[s.BUILDIDENTIFIER]})*))`),c("FULLPLAIN",`v?${i[s.MAINVERSION]}${i[s.PRERELEASE]}?${i[s.BUILD]}?`),c("FULL",`^${i[s.FULLPLAIN]}$`),c("LOOSEPLAIN",`[v=\\s]*${i[s.MAINVERSIONLOOSE]}${i[s.PRERELEASELOOSE]}?${i[s.BUILD]}?`),c("LOOSE",`^${i[s.LOOSEPLAIN]}$`),c("GTLT","((?:<|>)?=?)"),c("XRANGEIDENTIFIERLOOSE",i[s.NUMERICIDENTIFIERLOOSE]+"|x|X|\\*"),c("XRANGEIDENTIFIER",i[s.NUMERICIDENTIFIER]+"|x|X|\\*"),c("XRANGEPLAIN",`[v=\\s]*(${i[s.XRANGEIDENTIFIER]})(?:\\.(${i[s.XRANGEIDENTIFIER]})(?:\\.(${i[s.XRANGEIDENTIFIER]})(?:${i[s.PRERELEASE]})?${i[s.BUILD]}?)?)?`),c("XRANGEPLAINLOOSE",`[v=\\s]*(${i[s.XRANGEIDENTIFIERLOOSE]})(?:\\.(${i[s.XRANGEIDENTIFIERLOOSE]})(?:\\.(${i[s.XRANGEIDENTIFIERLOOSE]})(?:${i[s.PRERELEASELOOSE]})?${i[s.BUILD]}?)?)?`),c("XRANGE",`^${i[s.GTLT]}\\s*${i[s.XRANGEPLAIN]}$`),c("XRANGELOOSE",`^${i[s.GTLT]}\\s*${i[s.XRANGEPLAINLOOSE]}$`),c("COERCE",`(^|[^\\d])(\\d{1,${A}})(?:\\.(\\d{1,${A}}))?(?:\\.(\\d{1,${A}}))?(?:$|[^\\d])`),c("COERCERTL",i[s.COERCE],!0),c("LONETILDE","(?:~>?)"),c("TILDETRIM",`(\\s*)${i[s.LONETILDE]}\\s+`,!0),t.tildeTrimReplace="$1~",c("TILDE",`^${i[s.LONETILDE]}${i[s.XRANGEPLAIN]}$`),c("TILDELOOSE",`^${i[s.LONETILDE]}${i[s.XRANGEPLAINLOOSE]}$`),c("LONECARET","(?:\\^)"),c("CARETTRIM",`(\\s*)${i[s.LONECARET]}\\s+`,!0),t.caretTrimReplace="$1^",c("CARET",`^${i[s.LONECARET]}${i[s.XRANGEPLAIN]}$`),c("CARETLOOSE",`^${i[s.LONECARET]}${i[s.XRANGEPLAINLOOSE]}$`),c("COMPARATORLOOSE",`^${i[s.GTLT]}\\s*(${i[s.LOOSEPLAIN]})$|^$`),c("COMPARATOR",`^${i[s.GTLT]}\\s*(${i[s.FULLPLAIN]})$|^$`),c("COMPARATORTRIM",`(\\s*)${i[s.GTLT]}\\s*(${i[s.LOOSEPLAIN]}|${i[s.XRANGEPLAIN]})`,!0),t.comparatorTrimReplace="$1$2$3",c("HYPHENRANGE",`^\\s*(${i[s.XRANGEPLAIN]})\\s+-\\s+(${i[s.XRANGEPLAIN]})\\s*$`),c("HYPHENRANGELOOSE",`^\\s*(${i[s.XRANGEPLAINLOOSE]})\\s+-\\s+(${i[s.XRANGEPLAINLOOSE]})\\s*$`),c("STAR","(<|>)?=?\\s*\\*"),c("GTE0","^\\s*>=\\s*0.0.0\\s*$"),c("GTE0PRE","^\\s*>=\\s*0.0.0-0\\s*$")},69258:(e,t,r)=>{const A=r(842);e.exports=(e,t,r)=>A(e,t,">",r)},87395:(e,t,r)=>{const A=r(73004);e.exports=(e,t,r)=>(e=new A(e,r),t=new A(t,r),e.intersects(t))},36928:(e,t,r)=>{const A=r(842);e.exports=(e,t,r)=>A(e,t,"<",r)},1895:(e,t,r)=>{const A=r(14772),n=r(73004);e.exports=(e,t,r)=>{let o=null,i=null,s=null;try{s=new n(t,r)}catch(e){return null}return e.forEach(e=>{s.test(e)&&(o&&-1!==i.compare(e)||(o=e,i=new A(o,r)))}),o}},33252:(e,t,r)=>{const A=r(14772),n=r(73004);e.exports=(e,t,r)=>{let o=null,i=null,s=null;try{s=new n(t,r)}catch(e){return null}return e.forEach(e=>{s.test(e)&&(o&&1!==i.compare(e)||(o=e,i=new A(o,r)))}),o}},4224:(e,t,r)=>{const A=r(14772),n=r(73004),o=r(26544);e.exports=(e,t)=>{e=new n(e,t);let r=new A("0.0.0");if(e.test(r))return r;if(r=new A("0.0.0-0"),e.test(r))return r;r=null;for(let t=0;t{const t=new A(e.semver.version);switch(e.operator){case">":0===t.prerelease.length?t.patch++:t.prerelease.push(0),t.raw=t.format();case"":case">=":r&&!o(r,t)||(r=t);break;case"<":case"<=":break;default:throw new Error("Unexpected operation: "+e.operator)}})}return r&&e.test(r)?r:null}},842:(e,t,r)=>{const A=r(14772),n=r(29069),{ANY:o}=n,i=r(73004),s=r(73011),a=r(26544),c=r(65069),g=r(93845),l=r(44984);e.exports=(e,t,r,u)=>{let h,p,d,C,f;switch(e=new A(e,u),t=new i(t,u),r){case">":h=a,p=g,d=c,C=">",f=">=";break;case"<":h=c,p=l,d=a,C="<",f="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(s(e,t,u))return!1;for(let r=0;r{e.semver===o&&(e=new n(">=0.0.0")),i=i||e,s=s||e,h(e.semver,i.semver,u)?i=e:d(e.semver,s.semver,u)&&(s=e)}),i.operator===C||i.operator===f)return!1;if((!s.operator||s.operator===C)&&p(e,s.semver))return!1;if(s.operator===f&&d(e,s.semver))return!1}return!0}},3530:(e,t,r)=>{const A=r(73011),n=r(17340);e.exports=(e,t,r)=>{const o=[];let i=null,s=null;const a=e.sort((e,t)=>n(e,t,r));for(const e of a){A(e,t,r)?(s=e,i||(i=e)):(s&&o.push([i,s]),s=null,i=null)}i&&o.push([i,null]);const c=[];for(const[e,t]of o)e===t?c.push(e):t||e!==a[0]?t?e===a[0]?c.push("<="+t):c.push(`${e} - ${t}`):c.push(">="+e):c.push("*");const g=c.join(" || "),l="string"==typeof t.raw?t.raw:String(t);return g.length{const A=r(73004),{ANY:n}=r(29069),o=r(73011),i=r(17340),s=(e,t,r)=>{if(1===e.length&&e[0].semver===n)return 1===t.length&&t[0].semver===n;const A=new Set;let s,g,l,u,h,p,d;for(const t of e)">"===t.operator||">="===t.operator?s=a(s,t,r):"<"===t.operator||"<="===t.operator?g=c(g,t,r):A.add(t.semver);if(A.size>1)return null;if(s&&g){if(l=i(s.semver,g.semver,r),l>0)return null;if(0===l&&(">="!==s.operator||"<="!==g.operator))return null}for(const e of A){if(s&&!o(e,String(s),r))return null;if(g&&!o(e,String(g),r))return null;for(const A of t)if(!o(e,String(A),r))return!1;return!0}for(const e of t){if(d=d||">"===e.operator||">="===e.operator,p=p||"<"===e.operator||"<="===e.operator,s)if(">"===e.operator||">="===e.operator){if(u=a(s,e,r),u===e)return!1}else if(">="===s.operator&&!o(s.semver,String(e),r))return!1;if(g)if("<"===e.operator||"<="===e.operator){if(h=c(g,e,r),h===e)return!1}else if("<="===g.operator&&!o(g.semver,String(e),r))return!1;if(!e.operator&&(g||s)&&0!==l)return!1}return!(s&&p&&!g&&0!==l)&&!(g&&d&&!s&&0!==l)},a=(e,t,r)=>{if(!e)return t;const A=i(e.semver,t.semver,r);return A>0?e:A<0||">"===t.operator&&">="===e.operator?t:e},c=(e,t,r)=>{if(!e)return t;const A=i(e.semver,t.semver,r);return A<0?e:A>0||"<"===t.operator&&"<="===e.operator?t:e};e.exports=(e,t,r)=>{e=new A(e,r),t=new A(t,r);let n=!1;e:for(const A of e.set){for(const e of t.set){const t=s(A,e,r);if(n=n||null!==t,t)continue e}if(n)return!1}return!0}},47753:(e,t,r)=>{const A=r(73004);e.exports=(e,t)=>new A(e,t).set.map(e=>e.map(e=>e.value).join(" ").trim().split(" "))},44315:(e,t,r)=>{const A=r(73004);e.exports=(e,t)=>{try{return new A(e,t).range||"*"}catch(e){return null}}},91470:(e,t,r)=>{"use strict";const A=r(67719);e.exports=(e="")=>{const t=e.match(A);if(!t)return null;const[r,n]=t[0].replace(/#! ?/,"").split(" "),o=r.split("/").pop();return"env"===o?n:n?`${o} ${n}`:o}},67719:e=>{"use strict";e.exports=/^#!(.*)/},17234:e=>{"use strict";e.exports=e=>{const t=/^\\\\\?\\/.test(e),r=/[^\u0000-\u0080]+/.test(e);return t||r?e:e.replace(/\\/g,"/")}},10129:(e,t,r)=>{"use strict";const A=r(76417),n=r(19184),o=r(92413).Transform,i=["sha256","sha384","sha512"],s=/^[a-z0-9+/]+(?:=?=?)$/i,a=/^([^-]+)-([^?]+)([?\S*]*)$/,c=/^([^-]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)*$/,g=/^[\x21-\x7E]+$/,l=n({algorithms:{default:["sha512"]},error:{default:!1},integrity:{},options:{default:[]},pickAlgorithm:{default:()=>B},Promise:{default:()=>Promise},sep:{default:" "},single:{default:!1},size:{},strict:{default:!1}});class u{get isHash(){return!0}constructor(e,t){const r=!!(t=l(t)).strict;this.source=e.trim();const A=this.source.match(r?c:a);if(!A)return;if(r&&!i.some(e=>e===A[1]))return;this.algorithm=A[1],this.digest=A[2];const n=A[3];this.options=n?n.slice(1).split("?"):[]}hexDigest(){return this.digest&&Buffer.from(this.digest,"base64").toString("hex")}toJSON(){return this.toString()}toString(e){if((e=l(e)).strict&&!(i.some(e=>e===this.algorithm)&&this.digest.match(s)&&(this.options||[]).every(e=>e.match(g))))return"";const t=this.options&&this.options.length?"?"+this.options.join("?"):"";return`${this.algorithm}-${this.digest}${t}`}}class h{get isIntegrity(){return!0}toJSON(){return this.toString()}toString(e){let t=(e=l(e)).sep||" ";return e.strict&&(t=t.replace(/\S+/g," ")),Object.keys(this).map(r=>this[r].map(t=>u.prototype.toString.call(t,e)).filter(e=>e.length).join(t)).filter(e=>e.length).join(t)}concat(e,t){t=l(t);const r="string"==typeof e?e:C(e,t);return p(`${this.toString(t)} ${r}`,t)}hexDigest(){return p(this,{single:!0}).hexDigest()}match(e,t){const r=p(e,t=l(t)),A=r.pickAlgorithm(t);return this[A]&&r[A]&&this[A].find(e=>r[A].find(t=>e.digest===t.digest))||!1}pickAlgorithm(e){const t=(e=l(e)).pickAlgorithm,r=Object.keys(this);if(!r.length)throw new Error("No algorithms available for "+JSON.stringify(this.toString()));return r.reduce((e,r)=>t(e,r)||e)}}function p(e,t){if(t=l(t),"string"==typeof e)return d(e,t);if(e.algorithm&&e.digest){const r=new h;return r[e.algorithm]=[e],d(C(r,t),t)}return d(C(e,t),t)}function d(e,t){return t.single?new u(e,t):e.trim().split(/\s+/).reduce((e,r)=>{const A=new u(r,t);if(A.algorithm&&A.digest){const t=A.algorithm;e[t]||(e[t]=[]),e[t].push(A)}return e},new h)}function C(e,t){return t=l(t),e.algorithm&&e.digest?u.prototype.toString.call(e,t):"string"==typeof e?C(p(e,t),t):h.prototype.toString.call(e,t)}function f(e){const t=(e=l(e)).integrity&&p(e.integrity,e),r=t&&Object.keys(t).length,n=r&&t.pickAlgorithm(e),i=r&&t[n],s=Array.from(new Set(e.algorithms.concat(n?[n]:[]))),a=s.map(A.createHash);let c=0;const g=new o({transform(e,t,r){c+=e.length,a.forEach(r=>r.update(e,t)),r(null,e,t)}}).on("end",()=>{const A=e.options&&e.options.length?"?"+e.options.join("?"):"",o=p(a.map((e,t)=>`${s[t]}-${e.digest("base64")}${A}`).join(" "),e),l=r&&o.match(t,e);if("number"==typeof e.size&&c!==e.size){const r=new Error(`stream size mismatch when checking ${t}.\n Wanted: ${e.size}\n Found: ${c}`);r.code="EBADSIZE",r.found=c,r.expected=e.size,r.sri=t,g.emit("error",r)}else if(e.integrity&&!l){const e=new Error(`${t} integrity checksum failed when using ${n}: wanted ${i} but got ${o}. (${c} bytes)`);e.code="EINTEGRITY",e.found=o,e.expected=i,e.algorithm=n,e.sri=t,g.emit("error",e)}else g.emit("size",c),g.emit("integrity",o),l&&g.emit("verified",l)});return g}e.exports.Sd=function(e,t){const r=(t=l(t)).algorithms,n=t.options&&t.options.length?"?"+t.options.join("?"):"";return r.reduce((r,o)=>{const i=A.createHash(o).update(e).digest("base64"),s=new u(`${o}-${i}${n}`,t);if(s.algorithm&&s.digest){const e=s.algorithm;r[e]||(r[e]=[]),r[e].push(s)}return r},new h)};const I=new Set(A.getHashes()),E=["md5","whirlpool","sha1","sha224","sha256","sha384","sha512","sha3","sha3-256","sha3-384","sha3-512","sha3_256","sha3_384","sha3_512"].filter(e=>I.has(e));function B(e,t){return E.indexOf(e.toLowerCase())>=E.indexOf(t.toLowerCase())?e:t}},69538:(e,t,r)=>{"use strict";var A=r(13499).Buffer,n=A.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function o(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(A.isEncoding===n||!n(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=a,this.end=c,t=4;break;case"utf8":this.fillLast=s,t=4;break;case"base64":this.text=g,this.end=l,t=3;break;default:return this.write=u,void(this.end=h)}this.lastNeed=0,this.lastTotal=0,this.lastChar=A.allocUnsafe(t)}function i(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function s(e){var t=this.lastTotal-this.lastNeed,r=function(e,t,r){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if(128!=(192&t[1]))return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&128!=(192&t[2]))return e.lastNeed=2,"�"}}(this,e);return void 0!==r?r:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(e.copy(this.lastChar,t,0,e.length),void(this.lastNeed-=e.length))}function a(e,t){if((e.length-t)%2==0){var r=e.toString("utf16le",t);if(r){var A=r.charCodeAt(r.length-1);if(A>=55296&&A<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],r.slice(0,-1)}return r}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function c(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var r=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,r)}return t}function g(e,t){var r=(e.length-t)%3;return 0===r?e.toString("base64",t):(this.lastNeed=3-r,this.lastTotal=3,1===r?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-r))}function l(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function u(e){return e.toString(this.encoding)}function h(e){return e&&e.length?this.write(e):""}t.s=o,o.prototype.write=function(e){if(0===e.length)return"";var t,r;if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";r=this.lastNeed,this.lastNeed=0}else r=0;return r=0)return n>0&&(e.lastNeed=n-1),n;if(--A=0)return n>0&&(e.lastNeed=n-2),n;if(--A=0)return n>0&&(2===n?n=0:e.lastNeed=n-3),n;return 0}(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=r;var A=e.length-(r-this.lastNeed);return e.copy(this.lastChar,0,A),e.toString("utf8",t,A)},o.prototype.fillLast=function(e){if(this.lastNeed<=e.length)return e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,e.length),this.lastNeed-=e.length}},59428:(e,t,r)=>{"use strict";const A=r(12087),n=r(33867),o=r(72918),{env:i}=process;let s;function a(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function c(e,t){if(0===s)return 0;if(o("color=16m")||o("color=full")||o("color=truecolor"))return 3;if(o("color=256"))return 2;if(e&&!t&&void 0===s)return 0;const r=s||0;if("dumb"===i.TERM)return r;if("win32"===process.platform){const e=A.release().split(".");return Number(e[0])>=10&&Number(e[2])>=10586?Number(e[2])>=14931?3:2:1}if("CI"in i)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some(e=>e in i)||"codeship"===i.CI_NAME?1:r;if("TEAMCITY_VERSION"in i)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(i.TEAMCITY_VERSION)?1:0;if("GITHUB_ACTIONS"in i)return 1;if("truecolor"===i.COLORTERM)return 3;if("TERM_PROGRAM"in i){const e=parseInt((i.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(i.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(i.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(i.TERM)||"COLORTERM"in i?1:r}o("no-color")||o("no-colors")||o("color=false")||o("color=never")?s=0:(o("color")||o("colors")||o("color=true")||o("color=always"))&&(s=1),"FORCE_COLOR"in i&&(s="true"===i.FORCE_COLOR?1:"false"===i.FORCE_COLOR?0:0===i.FORCE_COLOR.length?1:Math.min(parseInt(i.FORCE_COLOR,10),3)),e.exports={supportsColor:function(e){return a(c(e,e&&e.isTTY))},stdout:a(c(!0,n.isatty(1))),stderr:a(c(!0,n.isatty(2)))}},93255:e=>{"use strict";function t(e){return Array.prototype.slice.apply(e)}function r(e){this.status="pending",this._continuations=[],this._parent=null,this._paused=!1,e&&e.call(this,this._continueWith.bind(this),this._failWith.bind(this))}function A(e){return e&&"function"==typeof e.then}function n(e){return e}if(r.prototype={then:function(e,t){var n=r.unresolved()._setParent(this);if(this._isRejected()){if(this._paused)return this._continuations.push({promise:n,nextFn:e,catchFn:t}),n;if(t)try{var o=t(this._error);return A(o)?(this._chainPromiseData(o,n),n):r.resolve(o)._setParent(this)}catch(e){return r.reject(e)._setParent(this)}return r.reject(this._error)._setParent(this)}return this._continuations.push({promise:n,nextFn:e,catchFn:t}),this._runResolutions(),n},catch:function(e){if(this._isResolved())return r.resolve(this._data)._setParent(this);var t=r.unresolved()._setParent(this);return this._continuations.push({promise:t,catchFn:e}),this._runRejections(),t},finally:function(e){var t=!1;function r(r,o){if(!t){t=!0,e||(e=n);var i=e(r);return A(i)?i.then((function(){if(o)throw o;return r})):r}}return this.then((function(e){return r(e)})).catch((function(e){return r(null,e)}))},pause:function(){return this._paused=!0,this},resume:function(){var e=this._findFirstPaused();return e&&(e._paused=!1,e._runResolutions(),e._runRejections()),this},_findAncestry:function(){return this._continuations.reduce((function(e,t){if(t.promise){var r={promise:t.promise,children:t.promise._findAncestry()};e.push(r)}return e}),[])},_setParent:function(e){if(this._parent)throw new Error("parent already set");return this._parent=e,this},_continueWith:function(e){var t=this._findFirstPending();t&&(t._data=e,t._setResolved())},_findFirstPending:function(){return this._findFirstAncestor((function(e){return e._isPending&&e._isPending()}))},_findFirstPaused:function(){return this._findFirstAncestor((function(e){return e._paused}))},_findFirstAncestor:function(e){for(var t,r=this;r;)e(r)&&(t=r),r=r._parent;return t},_failWith:function(e){var t=this._findFirstPending();t&&(t._error=e,t._setRejected())},_takeContinuations:function(){return this._continuations.splice(0,this._continuations.length)},_runRejections:function(){if(!this._paused&&this._isRejected()){var e=this._error,t=this._takeContinuations(),r=this;t.forEach((function(t){if(t.catchFn)try{var A=t.catchFn(e);r._handleUserFunctionResult(A,t.promise)}catch(e){t.promise.reject(e)}else t.promise.reject(e)}))}},_runResolutions:function(){if(!this._paused&&this._isResolved()&&!this._isPending()){var e=this._takeContinuations();if(A(this._data))return this._handleWhenResolvedDataIsPromise(this._data);var t=this._data,r=this;e.forEach((function(e){if(e.nextFn)try{var A=e.nextFn(t);r._handleUserFunctionResult(A,e.promise)}catch(t){r._handleResolutionError(t,e)}else e.promise&&e.promise.resolve(t)}))}},_handleResolutionError:function(e,t){if(this._setRejected(),t.catchFn)try{return void t.catchFn(e)}catch(t){e=t}t.promise&&t.promise.reject(e)},_handleWhenResolvedDataIsPromise:function(e){var t=this;return e.then((function(e){t._data=e,t._runResolutions()})).catch((function(e){t._error=e,t._setRejected(),t._runRejections()}))},_handleUserFunctionResult:function(e,t){A(e)?this._chainPromiseData(e,t):t.resolve(e)},_chainPromiseData:function(e,t){e.then((function(e){t.resolve(e)})).catch((function(e){t.reject(e)}))},_setResolved:function(){this.status="resolved",this._paused||this._runResolutions()},_setRejected:function(){this.status="rejected",this._paused||this._runRejections()},_isPending:function(){return"pending"===this.status},_isResolved:function(){return"resolved"===this.status},_isRejected:function(){return"rejected"===this.status}},r.resolve=function(e){return new r((function(t,r){A(e)?e.then((function(e){t(e)})).catch((function(e){r(e)})):t(e)}))},r.reject=function(e){return new r((function(t,r){r(e)}))},r.unresolved=function(){return new r((function(e,t){this.resolve=e,this.reject=t}))},r.all=function(){var e=t(arguments);return Array.isArray(e[0])&&(e=e[0]),e.length?new r((function(t,A){var n=[],o=0,i=!1;e.forEach((function(s,a){r.resolve(s).then((function(r){n[a]=r,(o+=1)===e.length&&t(n)})).catch((function(e){!function(e){i||(i=!0,A(e))}(e)}))}))})):r.resolve([])},Promise===r)throw new Error("Please use SynchronousPromise.installGlobally() to install globally");var o=Promise;r.installGlobally=function(e){if(Promise===r)return e;var A=function(e){if(void 0===e||e.__patched)return e;var r=e;return(e=function(){r.apply(this,t(arguments))}).__patched=!0,e}(e);return Promise=r,A},r.uninstallGlobally=function(){Promise===r&&(Promise=o)},e.exports={SynchronousPromise:r}},75799:(e,t,r)=>{var A=r(31669),n=r(73975),o=r(77686),i=r(86897).Writable,s=r(86897).PassThrough,a=function(){},c=function(e){return(e&=511)&&512-e},g=function(e,t){this._parent=e,this.offset=t,s.call(this)};A.inherits(g,s),g.prototype.destroy=function(e){this._parent.destroy(e)};var l=function(e){if(!(this instanceof l))return new l(e);i.call(this,e),e=e||{},this._offset=0,this._buffer=n(),this._missing=0,this._partial=!1,this._onparse=a,this._header=null,this._stream=null,this._overflow=null,this._cb=null,this._locked=!1,this._destroyed=!1,this._pax=null,this._paxGlobal=null,this._gnuLongPath=null,this._gnuLongLinkPath=null;var t=this,r=t._buffer,A=function(){t._continue()},s=function(e){if(t._locked=!1,e)return t.destroy(e);t._stream||A()},u=function(){t._stream=null;var e=c(t._header.size);e?t._parse(e,h):t._parse(512,I),t._locked||A()},h=function(){t._buffer.consume(c(t._header.size)),t._parse(512,I),A()},p=function(){var e=t._header.size;t._paxGlobal=o.decodePax(r.slice(0,e)),r.consume(e),u()},d=function(){var e=t._header.size;t._pax=o.decodePax(r.slice(0,e)),t._paxGlobal&&(t._pax=Object.assign({},t._paxGlobal,t._pax)),r.consume(e),u()},C=function(){var A=t._header.size;this._gnuLongPath=o.decodeLongPath(r.slice(0,A),e.filenameEncoding),r.consume(A),u()},f=function(){var A=t._header.size;this._gnuLongLinkPath=o.decodeLongPath(r.slice(0,A),e.filenameEncoding),r.consume(A),u()},I=function(){var n,i=t._offset;try{n=t._header=o.decode(r.slice(0,512),e.filenameEncoding)}catch(e){t.emit("error",e)}return r.consume(512),n?"gnu-long-path"===n.type?(t._parse(n.size,C),void A()):"gnu-long-link-path"===n.type?(t._parse(n.size,f),void A()):"pax-global-header"===n.type?(t._parse(n.size,p),void A()):"pax-header"===n.type?(t._parse(n.size,d),void A()):(t._gnuLongPath&&(n.name=t._gnuLongPath,t._gnuLongPath=null),t._gnuLongLinkPath&&(n.linkname=t._gnuLongLinkPath,t._gnuLongLinkPath=null),t._pax&&(t._header=n=function(e,t){return t.path&&(e.name=t.path),t.linkpath&&(e.linkname=t.linkpath),t.size&&(e.size=parseInt(t.size,10)),e.pax=t,e}(n,t._pax),t._pax=null),t._locked=!0,n.size&&"directory"!==n.type?(t._stream=new g(t,i),t.emit("entry",n,t._stream,s),t._parse(n.size,u),void A()):(t._parse(512,I),void t.emit("entry",n,function(e,t){var r=new g(e,t);return r.end(),r}(t,i),s))):(t._parse(512,I),void A())};this._onheader=I,this._parse(512,I)};A.inherits(l,i),l.prototype.destroy=function(e){this._destroyed||(this._destroyed=!0,e&&this.emit("error",e),this.emit("close"),this._stream&&this._stream.emit("close"))},l.prototype._parse=function(e,t){this._destroyed||(this._offset+=e,this._missing=e,t===this._onheader&&(this._partial=!1),this._onparse=t)},l.prototype._continue=function(){if(!this._destroyed){var e=this._cb;this._cb=a,this._overflow?this._write(this._overflow,void 0,e):e()}},l.prototype._write=function(e,t,r){if(!this._destroyed){var A=this._stream,n=this._buffer,o=this._missing;if(e.length&&(this._partial=!0),e.lengtho&&(i=e.slice(o),e=e.slice(0,o)),A?A.end(e):n.append(e),this._overflow=i,this._onparse()}},l.prototype._final=function(e){if(this._partial)return this.destroy(new Error("Unexpected end of data"));e()},e.exports=l},77686:(e,t)=>{var r=Buffer.alloc,A="0".charCodeAt(0),n=parseInt("7777",8),o=function(e,t,r,A){for(;rt?"7777777777777777777".slice(0,t)+" ":"0000000000000000000".slice(0,t-e.length)+e+" "};var a=function(e,t,r){if(128&(e=e.slice(t,t+r))[t=0])return function(e){var t;if(128===e[0])t=!0;else{if(255!==e[0])return null;t=!1}for(var r=!1,A=[],n=e.length-1;n>0;n--){var o=e[n];t?A.push(o):r&&0===o?A.push(0):r?(r=!1,A.push(256-o)):A.push(255-o)}var i=0,s=A.length;for(n=0;n=i?i:n>=0||(n+=i)>=0?n:0);t=Math.pow(10,r)&&r++,t+r+e};t.decodeLongPath=function(e,t){return c(e,0,e.length,t)},t.encodePax=function(e){var t="";e.name&&(t+=g(" path="+e.name+"\n")),e.linkname&&(t+=g(" linkpath="+e.linkname+"\n"));var r=e.pax;if(r)for(var A in r)t+=g(" "+A+"="+r[A]+"\n");return Buffer.from(t)},t.decodePax=function(e){for(var t={};e.length;){for(var r=0;r100;){var c=o.indexOf("/");if(-1===c)return null;a+=a?"/"+o.slice(0,c):o.slice(0,c),o=o.slice(c+1)}return Buffer.byteLength(o)>100||Buffer.byteLength(a)>155||e.linkname&&Buffer.byteLength(e.linkname)>100?null:(t.write(o),t.write(s(e.mode&n,6),100),t.write(s(e.uid,6),108),t.write(s(e.gid,6),116),t.write(s(e.size,11),124),t.write(s(e.mtime.getTime()/1e3|0,11),136),t[156]=A+function(e){switch(e){case"file":return 0;case"link":return 1;case"symlink":return 2;case"character-device":return 3;case"block-device":return 4;case"directory":return 5;case"fifo":return 6;case"contiguous-file":return 7;case"pax-header":return 72}return 0}(e.type),e.linkname&&t.write(e.linkname,157),t.write("ustar\x0000",257),e.uname&&t.write(e.uname,265),e.gname&&t.write(e.gname,297),t.write(s(e.devmajor||0,6),329),t.write(s(e.devminor||0,6),337),a&&t.write(a,345),t.write(s(i(t),6),148),t)},t.decode=function(e,t){var r=0===e[156]?0:e[156]-A,n=c(e,0,100,t),o=a(e,100,8),s=a(e,108,8),g=a(e,116,8),l=a(e,124,12),u=a(e,136,12),h=function(e){switch(e){case 0:return"file";case 1:return"link";case 2:return"symlink";case 3:return"character-device";case 4:return"block-device";case 5:return"directory";case 6:return"fifo";case 7:return"contiguous-file";case 72:return"pax-header";case 55:return"pax-global-header";case 27:return"gnu-long-link-path";case 28:case 30:return"gnu-long-path"}return null}(r),p=0===e[157]?null:c(e,157,100,t),d=c(e,265,32),C=c(e,297,32),f=a(e,329,8),I=a(e,337,8);e[345]&&(n=c(e,345,155,t)+"/"+n),0===r&&n&&"/"===n[n.length-1]&&(r=5);var E=i(e);if(256===E)return null;if(E!==a(e,148,8))throw new Error("Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?");return{name:n,mode:o,uid:s,gid:g,size:l,mtime:new Date(1e3*u),type:h,linkname:p,uname:d,gname:C,devmajor:f,devminor:I}}},59938:(e,t,r)=>{t.extract=r(75799),t.pack=r(72203)},72203:(e,t,r)=>{var A=r(13302),n=r(17067),o=r(85870),i=Buffer.alloc,s=r(86897).Readable,a=r(86897).Writable,c=r(24304).StringDecoder,g=r(77686),l=parseInt("755",8),u=parseInt("644",8),h=i(1024),p=function(){},d=function(e,t){(t&=511)&&e.push(h.slice(0,512-t))};var C=function(e){a.call(this),this.written=0,this._to=e,this._destroyed=!1};o(C,a),C.prototype._write=function(e,t,r){if(this.written+=e.length,this._to.push(e))return r();this._to._drain=r},C.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var f=function(){a.call(this),this.linkname="",this._decoder=new c("utf-8"),this._destroyed=!1};o(f,a),f.prototype._write=function(e,t,r){this.linkname+=this._decoder.write(e),r()},f.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var I=function(){a.call(this),this._destroyed=!1};o(I,a),I.prototype._write=function(e,t,r){r(new Error("No body allowed for this entry"))},I.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var E=function(e){if(!(this instanceof E))return new E(e);s.call(this,e),this._drain=p,this._finalized=!1,this._finalizing=!1,this._destroyed=!1,this._stream=null};o(E,s),E.prototype.entry=function(e,t,r){if(this._stream)throw new Error("already piping an entry");if(!this._finalized&&!this._destroyed){"function"==typeof t&&(r=t,t=null),r||(r=p);var o=this;if(e.size&&"symlink"!==e.type||(e.size=0),e.type||(e.type=function(e){switch(e&A.S_IFMT){case A.S_IFBLK:return"block-device";case A.S_IFCHR:return"character-device";case A.S_IFDIR:return"directory";case A.S_IFIFO:return"fifo";case A.S_IFLNK:return"symlink"}return"file"}(e.mode)),e.mode||(e.mode="directory"===e.type?l:u),e.uid||(e.uid=0),e.gid||(e.gid=0),e.mtime||(e.mtime=new Date),"string"==typeof t&&(t=Buffer.from(t)),Buffer.isBuffer(t))return e.size=t.length,this._encode(e),this.push(t),d(o,e.size),process.nextTick(r),new I;if("symlink"===e.type&&!e.linkname){var i=new f;return n(i,(function(t){if(t)return o.destroy(),r(t);e.linkname=i.linkname,o._encode(e),r()})),i}if(this._encode(e),"file"!==e.type&&"contiguous-file"!==e.type)return process.nextTick(r),new I;var s=new C(this);return this._stream=s,n(s,(function(t){return o._stream=null,t?(o.destroy(),r(t)):s.written!==e.size?(o.destroy(),r(new Error("size mismatch"))):(d(o,e.size),o._finalizing&&o.finalize(),void r())})),s}},E.prototype.finalize=function(){this._stream?this._finalizing=!0:this._finalized||(this._finalized=!0,this.push(h),this.push(null))},E.prototype.destroy=function(e){this._destroyed||(this._destroyed=!0,e&&this.emit("error",e),this.emit("close"),this._stream&&this._stream.destroy&&this._stream.destroy())},E.prototype._encode=function(e){if(!e.pax){var t=g.encode(e);if(t)return void this.push(t)}this._encodePax(e)},E.prototype._encodePax=function(e){var t=g.encodePax({name:e.name,linkname:e.linkname,pax:e.pax}),r={name:"PaxHeader",mode:e.mode,uid:e.uid,gid:e.gid,size:t.length,mtime:e.mtime,type:"pax-header",linkname:e.linkname&&"PaxHeader",uname:e.uname,gname:e.gname,devmajor:e.devmajor,devminor:e.devminor};this.push(g.encode(r)),this.push(t),d(this,t.length),r.size=e.size,r.type=e.type,this.push(g.encode(r))},E.prototype._read=function(e){var t=this._drain;this._drain=p,t()},e.exports=E},84615:(e,t,r)=>{"use strict"; -/*! - * to-regex-range - * - * Copyright (c) 2015-present, Jon Schlinkert. - * Released under the MIT License. - */const A=r(59235),n=(e,t,r)=>{if(!1===A(e))throw new TypeError("toRegexRange: expected the first argument to be a number");if(void 0===t||e===t)return String(e);if(!1===A(t))throw new TypeError("toRegexRange: expected the second argument to be a number.");let o={relaxZeros:!0,...r};"boolean"==typeof o.strictZeros&&(o.relaxZeros=!1===o.strictZeros);let a=e+":"+t+"="+String(o.relaxZeros)+String(o.shorthand)+String(o.capture)+String(o.wrap);if(n.cache.hasOwnProperty(a))return n.cache[a].result;let c=Math.min(e,t),g=Math.max(e,t);if(1===Math.abs(c-g)){let r=e+"|"+t;return o.capture?`(${r})`:!1===o.wrap?r:`(?:${r})`}let l=p(e)||p(t),u={min:e,max:t,a:c,b:g},h=[],d=[];if(l&&(u.isPadded=l,u.maxLen=String(u.max).length),c<0){d=i(g<0?Math.abs(g):1,Math.abs(c),u,o),c=u.a=0}return g>=0&&(h=i(c,g,u,o)),u.negatives=d,u.positives=h,u.result=function(e,t,r){let A=s(e,t,"-",!1,r)||[],n=s(t,e,"",!1,r)||[],o=s(e,t,"-?",!0,r)||[];return A.concat(o).concat(n).join("|")}(d,h,o),!0===o.capture?u.result=`(${u.result})`:!1!==o.wrap&&h.length+d.length>1&&(u.result=`(?:${u.result})`),n.cache[a]=u,u.result};function o(e,t,r){if(e===t)return{pattern:e,count:[],digits:0};let A=function(e,t){let r=[];for(let A=0;A1&&n.count.pop(),n.count.push(a.count[0]),n.string=n.pattern+u(n.count),c=t+1)}return s}function s(e,t,r,A,n){let o=[];for(let n of e){let{string:e}=n;A||c(t,"string",e)||o.push(r+e),A&&c(t,"string",e)&&o.push(r+e)}return o}function a(e,t){return e>t?1:t>e?-1:0}function c(e,t,r){return e.some(e=>e[t]===r)}function g(e,t){return Number(String(e).slice(0,-t)+"9".repeat(t))}function l(e,t){return e-e%Math.pow(10,t)}function u(e){let[t=0,r=""]=e;return r||t>1?`{${t+(r?","+r:"")}}`:""}function h(e,t,r){return`[${e}${t-e==1?"":"-"}${t}]`}function p(e){return/^-?(0+)\d/.test(e)}function d(e,t,r){if(!t.isPadded)return e;let A=Math.abs(t.maxLen-String(e).length),n=!1!==r.relaxZeros;switch(A){case 0:return"";case 1:return n?"0?":"0";case 2:return n?"0{0,2}":"00";default:return n?`0{0,${A}}`:`0{${A}}`}}n.cache={},n.clearCache=()=>n.cache={},e.exports=n},75158:e=>{function t(e,t){var r=e.length,A=new Array(r),n={},o=r,i=function(e){for(var t=new Map,r=0,A=e.length;r0&&(n.forEach((function(e,t){t>0&&(g+=(e[1]?" ":"│")+" "),c||e[0]!==r||(c=!0)})),g+=function(e,t){var r=t?"└":"├";return r+=e?"─ ":"──┐"}(t,A)+t,o&&("object"!=typeof r||r instanceof Date)&&(g+=": "+r),c&&(g+=" (circular ref.)"),s(g)),!c&&"object"==typeof r){var h=function(e,t){var r=[];for(var A in e)e.hasOwnProperty(A)&&(t&&"function"==typeof e[A]||r.push(A));return r}(r,i);h.forEach((function(t){a=++l===h.length,e(t,r[t],a,u,o,i,s)}))}}var t={asLines:function(t,r,A,n){e(".",t,!1,[],r,"function"!=typeof A&&A,n||A)},asTree:function(t,r,A){var n="";return e(".",t,!1,[],r,A,(function(e){n+=e+"\n"})),n}};return t}()},36370:(e,t,r)=>{"use strict";r.d(t,{gn:()=>A});function A(e,t,r,A){var n,o=arguments.length,i=o<3?t:null===A?A=Object.getOwnPropertyDescriptor(t,r):A;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,r,A);else for(var s=e.length-1;s>=0;s--)(n=e[s])&&(i=(o<3?n(i):o>3?n(t,r,i):n(t,r))||i);return o>3&&i&&Object.defineProperty(t,r,i),i}},98161:(e,t,r)=>{e.exports=r(69876)},69876:(e,t,r)=>{"use strict";r(11631);var A,n=r(4016),o=r(98605),i=r(57211),s=r(28614),a=(r(42357),r(31669));function c(e){var t=this;t.options=e||{},t.proxyOptions=t.options.proxy||{},t.maxSockets=t.options.maxSockets||o.Agent.defaultMaxSockets,t.requests=[],t.sockets=[],t.on("free",(function(e,r,A,n){for(var o=l(r,A,n),i=0,s=t.requests.length;i=this.maxSockets?n.requests.push(o):n.createSocket(o,(function(t){function r(){n.emit("free",t,o)}function A(e){n.removeSocket(t),t.removeListener("free",r),t.removeListener("close",A),t.removeListener("agentRemove",A)}t.on("free",r),t.on("close",A),t.on("agentRemove",A),e.onSocket(t)}))},c.prototype.createSocket=function(e,t){var r=this,n={};r.sockets.push(n);var o=u({},r.proxyOptions,{method:"CONNECT",path:e.host+":"+e.port,agent:!1,headers:{host:e.host+":"+e.port}});e.localAddress&&(o.localAddress=e.localAddress),o.proxyAuth&&(o.headers=o.headers||{},o.headers["Proxy-Authorization"]="Basic "+new Buffer(o.proxyAuth).toString("base64")),A("making CONNECT request");var i=r.request(o);function s(o,s,a){var c;return i.removeAllListeners(),s.removeAllListeners(),200!==o.statusCode?(A("tunneling socket could not be established, statusCode=%d",o.statusCode),s.destroy(),(c=new Error("tunneling socket could not be established, statusCode="+o.statusCode)).code="ECONNRESET",e.request.emit("error",c),void r.removeSocket(n)):a.length>0?(A("got illegal response body from proxy"),s.destroy(),(c=new Error("got illegal response body from proxy")).code="ECONNRESET",e.request.emit("error",c),void r.removeSocket(n)):(A("tunneling connection has established"),r.sockets[r.sockets.indexOf(n)]=s,t(s))}i.useChunkedEncodingByDefault=!1,i.once("response",(function(e){e.upgrade=!0})),i.once("upgrade",(function(e,t,r){process.nextTick((function(){s(e,t,r)}))})),i.once("connect",s),i.once("error",(function(t){i.removeAllListeners(),A("tunneling socket could not be established, cause=%s\n",t.message,t.stack);var o=new Error("tunneling socket could not be established, cause="+t.message);o.code="ECONNRESET",e.request.emit("error",o),r.removeSocket(n)})),i.end()},c.prototype.removeSocket=function(e){var t=this.sockets.indexOf(e);if(-1!==t){this.sockets.splice(t,1);var r=this.requests.shift();r&&this.createSocket(r,(function(e){r.request.onSocket(e)}))}},A=process.env.NODE_DEBUG&&/\btunnel\b/.test(process.env.NODE_DEBUG)?function(){var e=Array.prototype.slice.call(arguments);"string"==typeof e[0]?e[0]="TUNNEL: "+e[0]:e.unshift("TUNNEL:"),console.error.apply(console,e)}:function(){}},73212:(e,t,r)=>{e.exports=r(31669).deprecate},87945:(e,t,r)=>{const A="win32"===process.platform||"cygwin"===process.env.OSTYPE||"msys"===process.env.OSTYPE,n=r(85622),o=A?";":":",i=r(64151),s=e=>Object.assign(new Error("not found: "+e),{code:"ENOENT"}),a=(e,t)=>{const r=t.colon||o,n=e.match(/\//)||A&&e.match(/\\/)?[""]:[...A?[process.cwd()]:[],...(t.path||process.env.PATH||"").split(r)],i=A?t.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",s=A?i.split(r):[""];return A&&-1!==e.indexOf(".")&&""!==s[0]&&s.unshift(""),{pathEnv:n,pathExt:s,pathExtExe:i}},c=(e,t,r)=>{"function"==typeof t&&(r=t,t={}),t||(t={});const{pathEnv:A,pathExt:o,pathExtExe:c}=a(e,t),g=[],l=r=>new Promise((o,i)=>{if(r===A.length)return t.all&&g.length?o(g):i(s(e));const a=A[r],c=/^".*"$/.test(a)?a.slice(1,-1):a,l=n.join(c,e),h=!c&&/^\.[\\\/]/.test(e)?e.slice(0,2)+l:l;o(u(h,r,0))}),u=(e,r,A)=>new Promise((n,s)=>{if(A===o.length)return n(l(r+1));const a=o[A];i(e+a,{pathExt:c},(o,i)=>{if(!o&&i){if(!t.all)return n(e+a);g.push(e+a)}return n(u(e,r,A+1))})});return r?l(0).then(e=>r(null,e),r):l(0)};e.exports=c,c.sync=(e,t)=>{t=t||{};const{pathEnv:r,pathExt:A,pathExtExe:o}=a(e,t),c=[];for(let s=0;s{e.exports=function e(t,r){if(t&&r)return e(t)(r);if("function"!=typeof t)throw new TypeError("need wrapper function");return Object.keys(t).forEach((function(e){A[e]=t[e]})),A;function A(){for(var e=new Array(arguments.length),r=0;r{"use strict";var A=r(60087);t.__esModule=!0,t.default=void 0;var n=A(r(15215)),o=A(r(11050)),i=function(){function e(e,t){if(this.refs=e,"function"!=typeof t){if(!(0,n.default)(t,"is"))throw new TypeError("`is:` is required for `when()` conditions");if(!t.then&&!t.otherwise)throw new TypeError("either `then:` or `otherwise:` is required for `when()` conditions");var r=t.is,A=t.then,o=t.otherwise,i="function"==typeof r?r:function(){for(var e=arguments.length,t=new Array(e),A=0;A{"use strict";var A=r(60087);t.__esModule=!0,t.default=void 0;var n=A(r(11050)),o=function(){function e(e){this._resolve=function(t,r){var A=e(t,r);if(!(0,n.default)(A))throw new TypeError("lazy() functions must return a valid schema");return A.resolve(r)}}var t=e.prototype;return t.resolve=function(e){return this._resolve(e.value,e)},t.cast=function(e,t){return this._resolve(e,t).cast(e,t)},t.validate=function(e,t){return this._resolve(e,t).validate(e,t)},t.validateSync=function(e,t){return this._resolve(e,t).validateSync(e,t)},t.validateAt=function(e,t,r){return this._resolve(t,r).validateAt(e,t,r)},t.validateSyncAt=function(e,t,r){return this._resolve(t,r).validateSyncAt(e,t,r)},e}();o.prototype.__isYupSchema__=!0;var i=o;t.default=i,e.exports=t.default},95814:(e,t,r)=>{"use strict";var A=r(60087);t.__esModule=!0,t.default=void 0;var n=A(r(72912)),o=r(79588),i="$",s=".",a=function(){function e(e,t){if(void 0===t&&(t={}),"string"!=typeof e)throw new TypeError("ref must be a string, got: "+e);if(this.key=e.trim(),""===e)throw new TypeError("ref must be a non-empty string");this.isContext=this.key[0]===i,this.isValue=this.key[0]===s,this.isSibling=!this.isContext&&!this.isValue;var r=this.isContext?i:this.isValue?s:"";this.path=this.key.slice(r.length),this.getter=this.path&&(0,o.getter)(this.path,!0),this.map=t.map}var t=e.prototype;return t.getValue=function(e){var t=this.isContext?e.context:this.isValue?e.value:e.parent;return this.getter&&(t=this.getter(t||{})),this.map&&(t=this.map(t)),t},t.cast=function(e,t){return this.getValue((0,n.default)({},t,{value:e}))},t.resolve=function(){return this},t.describe=function(){return{type:"ref",key:this.key}},t.toString=function(){return"Ref("+this.key+")"},e.isRef=function(e){return e&&e.__isYupRef},e}();t.default=a,a.prototype.__isYupRef=!0,e.exports=t.default},40828:(e,t,r)=>{"use strict";var A=r(60087);t.__esModule=!0,t.default=s;var n=A(r(21043)),o=/\$\{\s*(\w+)\s*\}/g,i=function(e){return function(t){return e.replace(o,(function(e,r){return(0,n.default)(t[r])}))}};function s(e,t,r,A){var n=this;this.name="ValidationError",this.value=t,this.path=r,this.type=A,this.errors=[],this.inner=[],e&&[].concat(e).forEach((function(e){n.errors=n.errors.concat(e.errors||e),e.inner&&(n.inner=n.inner.concat(e.inner.length?e.inner:e))})),this.message=this.errors.length>1?this.errors.length+" errors occurred":this.errors[0],Error.captureStackTrace&&Error.captureStackTrace(this,s)}s.prototype=Object.create(Error.prototype),s.prototype.constructor=s,s.isError=function(e){return e&&"ValidationError"===e.name},s.formatError=function(e,t){"string"==typeof e&&(e=i(e));var r=function(t){return t.path=t.label||t.path||"this","function"==typeof e?e(t):e};return 1===arguments.length?r:r(t)},e.exports=t.default},18830:(e,t,r)=>{"use strict";var A=r(19228),n=r(60087);t.__esModule=!0,t.default=void 0;var o=n(r(72912)),i=n(r(62407)),s=n(r(31490)),a=n(r(71665)),c=n(r(11050)),g=n(r(7045)),l=n(r(21043)),u=n(r(16434)),h=r(63802),p=A(r(80180));function d(){var e=(0,i.default)(["","[","]"]);return d=function(){return e},e}var C=f;function f(e){var t=this;if(!(this instanceof f))return new f(e);u.default.call(this,{type:"array"}),this._subType=void 0,this.withMutation((function(){t.transform((function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null})),e&&t.of(e)}))}t.default=C,(0,s.default)(f,u.default,{_typeCheck:function(e){return Array.isArray(e)},_cast:function(e,t){var r=this,A=u.default.prototype._cast.call(this,e,t);if(!this._typeCheck(A)||!this._subType)return A;var n=!1,o=A.map((function(e){var A=r._subType.cast(e,t);return A!==e&&(n=!0),A}));return n?o:A},_validate:function(e,t){var r=this;void 0===t&&(t={});var A=[],n=t.sync,i=t.path,s=this._subType,a=this._option("abortEarly",t),c=this._option("recursive",t),l=null!=t.originalValue?t.originalValue:e;return u.default.prototype._validate.call(this,e,t).catch((0,p.propagateErrors)(a,A)).then((function(e){if(!c||!s||!r._typeCheck(e)){if(A.length)throw A[0];return e}l=l||e;var u=e.map((function(r,A){var n=(0,g.default)(d(),t.path,A),i=(0,o.default)({},t,{path:n,strict:!0,parent:e,originalValue:l[A]});return!s.validate||s.validate(r,i)}));return(0,p.default)({sync:n,path:i,value:e,errors:A,endEarly:a,validations:u})}))},_isPresent:function(e){return u.default.prototype._cast.call(this,e)&&e.length>0},of:function(e){var t=this.clone();if(!1!==e&&!(0,c.default)(e))throw new TypeError("`array.of()` sub-schema must be a valid yup schema, or `false` to negate a current sub-schema. not: "+(0,l.default)(e));return t._subType=e,t},min:function(e,t){return t=t||h.array.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test:function(t){return(0,a.default)(t)||t.length>=this.resolve(e)}})},max:function(e,t){return t=t||h.array.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test:function(t){return(0,a.default)(t)||t.length<=this.resolve(e)}})},ensure:function(){var e=this;return this.default((function(){return[]})).transform((function(t){return e.isType(t)?t:null===t?[]:[].concat(t)}))},compact:function(e){var t=e?function(t,r,A){return!e(t,r,A)}:function(e){return!!e};return this.transform((function(e){return null!=e?e.filter(t):e}))},describe:function(){var e=u.default.prototype.describe.call(this);return this._subType&&(e.innerType=this._subType.describe()),e}}),e.exports=t.default},76595:(e,t,r)=>{"use strict";var A=r(60087);t.__esModule=!0,t.default=void 0;var n=A(r(31490)),o=A(r(16434)),i=s;function s(){var e=this;if(!(this instanceof s))return new s;o.default.call(this,{type:"boolean"}),this.withMutation((function(){e.transform((function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(e))return!0;if(/^(false|0)$/i.test(e))return!1}return e}))}))}t.default=i,(0,n.default)(s,o.default,{_typeCheck:function(e){return e instanceof Boolean&&(e=e.valueOf()),"boolean"==typeof e}}),e.exports=t.default},41755:(e,t,r)=>{"use strict";var A=r(60087);t.__esModule=!0,t.default=void 0;var n=A(r(16434)),o=A(r(31490)),i=A(r(76813)),s=r(63802),a=A(r(71665)),c=A(r(95814)),g=new Date(""),l=u;function u(){var e=this;if(!(this instanceof u))return new u;n.default.call(this,{type:"date"}),this.withMutation((function(){e.transform((function(e){return this.isType(e)?e:(e=(0,i.default)(e))?new Date(e):g}))}))}t.default=l,(0,o.default)(u,n.default,{_typeCheck:function(e){return t=e,"[object Date]"===Object.prototype.toString.call(t)&&!isNaN(e.getTime());var t},min:function(e,t){void 0===t&&(t=s.date.min);var r=e;if(!c.default.isRef(r)&&(r=this.cast(e),!this._typeCheck(r)))throw new TypeError("`min` must be a Date or a value that can be `cast()` to a Date");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test:function(e){return(0,a.default)(e)||e>=this.resolve(r)}})},max:function(e,t){void 0===t&&(t=s.date.max);var r=e;if(!c.default.isRef(r)&&(r=this.cast(e),!this._typeCheck(r)))throw new TypeError("`max` must be a Date or a value that can be `cast()` to a Date");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test:function(e){return(0,a.default)(e)||e<=this.resolve(r)}})}}),e.exports=t.default},15966:(e,t,r)=>{"use strict";var A=r(60087);t.__esModule=!0,t.addMethod=function(e,t,r){if(!e||!(0,d.default)(e.prototype))throw new TypeError("You must provide a yup schema constructor function");if("string"!=typeof t)throw new TypeError("A Method name must be provided");if("function"!=typeof r)throw new TypeError("Method function must be provided");e.prototype[t]=r},t.lazy=t.ref=t.boolean=void 0;var n=A(r(16434));t.mixed=n.default;var o=A(r(76595));t.bool=o.default;var i=A(r(45167));t.string=i.default;var s=A(r(72068));t.number=s.default;var a=A(r(41755));t.date=a.default;var c=A(r(51727));t.object=c.default;var g=A(r(18830));t.array=g.default;var l=A(r(95814)),u=A(r(6856)),h=A(r(40828));t.ValidationError=h.default;var p=A(r(43910));t.reach=p.default;var d=A(r(11050));t.isSchema=d.default;var C=A(r(24280));t.setLocale=C.default;var f=o.default;t.boolean=f;t.ref=function(e,t){return new l.default(e,t)};t.lazy=function(e){return new u.default(e)}},63802:(e,t,r)=>{"use strict";var A=r(60087);t.__esModule=!0,t.default=t.array=t.object=t.boolean=t.date=t.number=t.string=t.mixed=void 0;var n=A(r(21043)),o={default:"${path} is invalid",required:"${path} is a required field",oneOf:"${path} must be one of the following values: ${values}",notOneOf:"${path} must not be one of the following values: ${values}",notType:function(e){var t=e.path,r=e.type,A=e.value,o=e.originalValue,i=null!=o&&o!==A,s=t+" must be a `"+r+"` type, but the final value was: `"+(0,n.default)(A,!0)+"`"+(i?" (cast from the value `"+(0,n.default)(o,!0)+"`).":".");return null===A&&(s+='\n If "null" is intended as an empty value be sure to mark the schema as `.nullable()`'),s}};t.mixed=o;var i={length:"${path} must be exactly ${length} characters",min:"${path} must be at least ${min} characters",max:"${path} must be at most ${max} characters",matches:'${path} must match the following: "${regex}"',email:"${path} must be a valid email",url:"${path} must be a valid URL",trim:"${path} must be a trimmed string",lowercase:"${path} must be a lowercase string",uppercase:"${path} must be a upper case string"};t.string=i;var s={min:"${path} must be greater than or equal to ${min}",max:"${path} must be less than or equal to ${max}",lessThan:"${path} must be less than ${less}",moreThan:"${path} must be greater than ${more}",notEqual:"${path} must be not equal to ${notEqual}",positive:"${path} must be a positive number",negative:"${path} must be a negative number",integer:"${path} must be an integer"};t.number=s;var a={min:"${path} field must be later than ${min}",max:"${path} field must be at earlier than ${max}"};t.date=a;var c={};t.boolean=c;var g={noUnknown:"${path} field cannot have keys not specified in the object shape"};t.object=g;var l={min:"${path} field must have at least ${min} items",max:"${path} field must have less than or equal to ${max} items"};t.array=l;var u={mixed:o,string:i,number:s,date:a,object:g,array:l,boolean:c};t.default=u},16434:(e,t,r)=>{"use strict";var A=r(60087);t.__esModule=!0,t.default=I;var n=A(r(72912)),o=A(r(15215)),i=A(r(26052)),s=A(r(78700)),a=r(63802),c=A(r(94916)),g=A(r(80180)),l=A(r(22808)),u=A(r(11050)),h=A(r(54107)),p=A(r(21043)),d=A(r(95814)),C=r(43910),f=function(){function e(){this.list=new Set,this.refs=new Map}var t=e.prototype;return t.toArray=function(){return(0,s.default)(this.list).concat((0,s.default)(this.refs.values()))},t.add=function(e){d.default.isRef(e)?this.refs.set(e.key,e):this.list.add(e)},t.delete=function(e){d.default.isRef(e)?this.refs.delete(e.key,e):this.list.delete(e)},t.has=function(e,t){if(this.list.has(e))return!0;for(var r,A=this.refs.values();!(r=A.next()).done;)if(t(r.value)===e)return!0;return!1},e}();function I(e){var t=this;if(void 0===e&&(e={}),!(this instanceof I))return new I;this._deps=[],this._conditions=[],this._options={abortEarly:!0,recursive:!0},this._exclusive=Object.create(null),this._whitelist=new f,this._blacklist=new f,this.tests=[],this.transforms=[],this.withMutation((function(){t.typeError(a.mixed.notType)})),(0,o.default)(e,"default")&&(this._defaultDefault=e.default),this._type=e.type||"mixed"}for(var E=I.prototype={__isYupSchema__:!0,constructor:I,clone:function(){var e=this;return this._mutate?this:(0,i.default)(this,(function(t){if((0,u.default)(t)&&t!==e)return t}))},label:function(e){var t=this.clone();return t._label=e,t},meta:function(e){if(0===arguments.length)return this._meta;var t=this.clone();return t._meta=(0,n.default)(t._meta||{},e),t},withMutation:function(e){var t=this._mutate;this._mutate=!0;var r=e(this);return this._mutate=t,r},concat:function(e){if(!e||e===this)return this;if(e._type!==this._type&&"mixed"!==this._type)throw new TypeError("You cannot `concat()` schema's of different types: "+this._type+" and "+e._type);var t=(0,l.default)(e.clone(),this);return(0,o.default)(e,"_default")&&(t._default=e._default),t.tests=this.tests,t._exclusive=this._exclusive,t.withMutation((function(t){e.tests.forEach((function(e){t.test(e.OPTIONS)}))})),t},isType:function(e){return!(!this._nullable||null!==e)||(!this._typeCheck||this._typeCheck(e))},resolve:function(e){var t=this;if(t._conditions.length){var r=t._conditions;(t=t.clone())._conditions=[],t=(t=r.reduce((function(t,r){return r.resolve(t,e)}),t)).resolve(e)}return t},cast:function(e,t){void 0===t&&(t={});var r=this.resolve((0,n.default)({},t,{value:e})),A=r._cast(e,t);if(void 0!==e&&!1!==t.assert&&!0!==r.isType(A)){var o=(0,p.default)(e),i=(0,p.default)(A);throw new TypeError("The value of "+(t.path||"field")+' could not be cast to a value that satisfies the schema type: "'+r._type+'". \n\nattempted value: '+o+" \n"+(i!==o?"result of cast: "+i:""))}return A},_cast:function(e){var t=this,r=void 0===e?e:this.transforms.reduce((function(r,A){return A.call(t,r,e)}),e);return void 0===r&&(0,o.default)(this,"_default")&&(r=this.default()),r},_validate:function(e,t){var r=this;void 0===t&&(t={});var A=e,o=null!=t.originalValue?t.originalValue:e,i=this._option("strict",t),s=this._option("abortEarly",t),a=t.sync,c=t.path,l=this._label;i||(A=this._cast(A,(0,n.default)({assert:!1},t)));var u={value:A,path:c,schema:this,options:t,label:l,originalValue:o,sync:a},h=[];return this._typeError&&h.push(this._typeError(u)),this._whitelistError&&h.push(this._whitelistError(u)),this._blacklistError&&h.push(this._blacklistError(u)),(0,g.default)({validations:h,endEarly:s,value:A,path:c,sync:a}).then((function(e){return(0,g.default)({path:c,sync:a,value:e,endEarly:s,validations:r.tests.map((function(e){return e(u)}))})}))},validate:function(e,t){return void 0===t&&(t={}),this.resolve((0,n.default)({},t,{value:e}))._validate(e,t)},validateSync:function(e,t){var r,A;if(void 0===t&&(t={}),this.resolve((0,n.default)({},t,{value:e}))._validate(e,(0,n.default)({},t,{sync:!0})).then((function(e){return r=e})).catch((function(e){return A=e})),A)throw A;return r},isValid:function(e,t){return this.validate(e,t).then((function(){return!0})).catch((function(e){if("ValidationError"===e.name)return!1;throw e}))},isValidSync:function(e,t){try{return this.validateSync(e,t),!0}catch(e){if("ValidationError"===e.name)return!1;throw e}},getDefault:function(e){return void 0===e&&(e={}),this.resolve(e).default()},default:function(e){if(0===arguments.length){var t=(0,o.default)(this,"_default")?this._default:this._defaultDefault;return"function"==typeof t?t.call(this):(0,i.default)(t)}var r=this.clone();return r._default=e,r},strict:function(e){void 0===e&&(e=!0);var t=this.clone();return t._options.strict=e,t},_isPresent:function(e){return null!=e},required:function(e){return void 0===e&&(e=a.mixed.required),this.test({message:e,name:"required",exclusive:!0,test:function(e){return this.schema._isPresent(e)}})},notRequired:function(){var e=this.clone();return e.tests=e.tests.filter((function(e){return"required"!==e.OPTIONS.name})),e},nullable:function(e){void 0===e&&(e=!0);var t=this.clone();return t._nullable=e,t},transform:function(e){var t=this.clone();return t.transforms.push(e),t},test:function(){var e;if(void 0===(e=1===arguments.length?"function"==typeof(arguments.length<=0?void 0:arguments[0])?{test:arguments.length<=0?void 0:arguments[0]}:arguments.length<=0?void 0:arguments[0]:2===arguments.length?{name:arguments.length<=0?void 0:arguments[0],test:arguments.length<=1?void 0:arguments[1]}:{name:arguments.length<=0?void 0:arguments[0],message:arguments.length<=1?void 0:arguments[1],test:arguments.length<=2?void 0:arguments[2]}).message&&(e.message=a.mixed.default),"function"!=typeof e.test)throw new TypeError("`test` is a required parameters");var t=this.clone(),r=(0,h.default)(e),A=e.exclusive||e.name&&!0===t._exclusive[e.name];if(e.exclusive&&!e.name)throw new TypeError("Exclusive tests must provide a unique `name` identifying the test");return t._exclusive[e.name]=!!e.exclusive,t.tests=t.tests.filter((function(t){if(t.OPTIONS.name===e.name){if(A)return!1;if(t.OPTIONS.test===r.OPTIONS.test)return!1}return!0})),t.tests.push(r),t},when:function(e,t){1===arguments.length&&(t=e,e=".");var r=this.clone(),A=[].concat(e).map((function(e){return new d.default(e)}));return A.forEach((function(e){e.isSibling&&r._deps.push(e.key)})),r._conditions.push(new c.default(A,t)),r},typeError:function(e){var t=this.clone();return t._typeError=(0,h.default)({message:e,name:"typeError",test:function(e){return!(void 0!==e&&!this.schema.isType(e))||this.createError({params:{type:this.schema._type}})}}),t},oneOf:function(e,t){void 0===t&&(t=a.mixed.oneOf);var r=this.clone();return e.forEach((function(e){r._whitelist.add(e),r._blacklist.delete(e)})),r._whitelistError=(0,h.default)({message:t,name:"oneOf",test:function(e){if(void 0===e)return!0;var t=this.schema._whitelist;return!!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),r},notOneOf:function(e,t){void 0===t&&(t=a.mixed.notOneOf);var r=this.clone();return e.forEach((function(e){r._blacklist.add(e),r._whitelist.delete(e)})),r._blacklistError=(0,h.default)({message:t,name:"notOneOf",test:function(e){var t=this.schema._blacklist;return!t.has(e,this.resolve)||this.createError({params:{values:t.toArray().join(", ")}})}}),r},strip:function(e){void 0===e&&(e=!0);var t=this.clone();return t._strip=e,t},_option:function(e,t){return(0,o.default)(t,e)?t[e]:this._options[e]},describe:function(){var e=this.clone();return{type:e._type,meta:e._meta,label:e._label,tests:e.tests.map((function(e){return{name:e.OPTIONS.name,params:e.OPTIONS.params}})).filter((function(e,t,r){return r.findIndex((function(t){return t.name===e.name}))===t}))}}},B=["validate","validateSync"],y=function(){var e=B[m];E[e+"At"]=function(t,r,A){void 0===A&&(A={});var o=(0,C.getIn)(this,t,r,A.context),i=o.parent,s=o.parentPath;return o.schema[e](i&&i[s],(0,n.default)({},A,{parent:i,path:t}))}},m=0;m{"use strict";var A=r(60087);t.__esModule=!0,t.default=c;var n=A(r(31490)),o=A(r(16434)),i=r(63802),s=A(r(71665)),a=function(e){return(0,s.default)(e)||e===(0|e)};function c(){var e=this;if(!(this instanceof c))return new c;o.default.call(this,{type:"number"}),this.withMutation((function(){e.transform((function(e){var t=e;if("string"==typeof t){if(""===(t=t.replace(/\s/g,"")))return NaN;t=+t}return this.isType(t)?t:parseFloat(t)}))}))}(0,n.default)(c,o.default,{_typeCheck:function(e){return e instanceof Number&&(e=e.valueOf()),"number"==typeof e&&!function(e){return e!=+e}(e)},min:function(e,t){return void 0===t&&(t=i.number.min),this.test({message:t,name:"min",exclusive:!0,params:{min:e},test:function(t){return(0,s.default)(t)||t>=this.resolve(e)}})},max:function(e,t){return void 0===t&&(t=i.number.max),this.test({message:t,name:"max",exclusive:!0,params:{max:e},test:function(t){return(0,s.default)(t)||t<=this.resolve(e)}})},lessThan:function(e,t){return void 0===t&&(t=i.number.lessThan),this.test({message:t,name:"max",exclusive:!0,params:{less:e},test:function(t){return(0,s.default)(t)||tthis.resolve(e)}})},positive:function(e){return void 0===e&&(e=i.number.positive),this.moreThan(0,e)},negative:function(e){return void 0===e&&(e=i.number.negative),this.lessThan(0,e)},integer:function(e){return void 0===e&&(e=i.number.integer),this.test({name:"integer",message:e,test:a})},truncate:function(){return this.transform((function(e){return(0,s.default)(e)?e:0|e}))},round:function(e){var t=["ceil","floor","round","trunc"];if("trunc"===(e=e&&e.toLowerCase()||"round"))return this.truncate();if(-1===t.indexOf(e.toLowerCase()))throw new TypeError("Only valid options for round() are: "+t.join(", "));return this.transform((function(t){return(0,s.default)(t)?t:Math[e](t)}))}}),e.exports=t.default},51727:(e,t,r)=>{"use strict";var A=r(19228),n=r(60087);t.__esModule=!0,t.default=w;var o=n(r(62407)),i=n(r(72912)),s=n(r(15215)),a=n(r(36494)),c=n(r(89170)),g=n(r(5253)),l=n(r(89612)),u=r(79588),h=n(r(16434)),p=r(63802),d=n(r(18417)),C=n(r(23316)),f=n(r(31490)),I=n(r(7045)),E=A(r(80180));function B(){var e=(0,o.default)(["",".",""]);return B=function(){return e},e}function y(){var e=(0,o.default)(["",".",""]);return y=function(){return e},e}var m=function(e){return"[object Object]"===Object.prototype.toString.call(e)};function w(e){var t=this;if(!(this instanceof w))return new w(e);h.default.call(this,{type:"object",default:function(){var e=this;if(this._nodes.length){var t={};return this._nodes.forEach((function(r){t[r]=e.fields[r].default?e.fields[r].default():void 0})),t}}}),this.fields=Object.create(null),this._nodes=[],this._excludedEdges=[],this.withMutation((function(){t.transform((function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e=null}return this.isType(e)?e:null})),e&&t.shape(e)}))}(0,f.default)(w,h.default,{_typeCheck:function(e){return m(e)||"function"==typeof e},_cast:function(e,t){var r=this;void 0===t&&(t={});var A=h.default.prototype._cast.call(this,e,t);if(void 0===A)return this.default();if(!this._typeCheck(A))return A;var n=this.fields,o=!0===this._option("stripUnknown",t),a=this._nodes.concat(Object.keys(A).filter((function(e){return-1===r._nodes.indexOf(e)}))),c={},g=(0,i.default)({},t,{parent:c,__validating:!1}),l=!1;return a.forEach((function(e){var r=n[e],i=(0,s.default)(A,e);if(r){var a,u=r._options&&r._options.strict;if(g.path=(0,I.default)(y(),t.path,e),g.value=A[e],!0===(r=r.resolve(g))._strip)return void(l=l||e in A);void 0!==(a=t.__validating&&u?A[e]:r.cast(A[e],g))&&(c[e]=a)}else i&&!o&&(c[e]=A[e]);c[e]!==A[e]&&(l=!0)})),l?c:A},_validate:function(e,t){var r,A,n=this;void 0===t&&(t={});var o=t.sync,s=[],a=null!=t.originalValue?t.originalValue:e;return r=this._option("abortEarly",t),A=this._option("recursive",t),t=(0,i.default)({},t,{__validating:!0,originalValue:a}),h.default.prototype._validate.call(this,e,t).catch((0,E.propagateErrors)(r,s)).then((function(e){if(!A||!m(e)){if(s.length)throw s[0];return e}a=a||e;var c=n._nodes.map((function(r){var A=(0,I.default)(B(),t.path,r),o=n.fields[r],s=(0,i.default)({},t,{path:A,parent:e,originalValue:a[r]});return o&&o.validate?(s.strict=!0,o.validate(e[r],s)):Promise.resolve(!0)}));return(0,E.default)({sync:o,validations:c,value:e,errors:s,endEarly:r,path:t.path,sort:(0,C.default)(n.fields)})}))},concat:function(e){var t=h.default.prototype.concat.call(this,e);return t._nodes=(0,d.default)(t.fields,t._excludedEdges),t},shape:function(e,t){void 0===t&&(t=[]);var r=this.clone(),A=(0,i.default)(r.fields,e);if(r.fields=A,t.length){Array.isArray(t[0])||(t=[t]);var n=t.map((function(e){return e[0]+"-"+e[1]}));r._excludedEdges=r._excludedEdges.concat(n)}return r._nodes=(0,d.default)(A,r._excludedEdges),r},from:function(e,t,r){var A=(0,u.getter)(e,!0);return this.transform((function(n){if(null==n)return n;var o=n;return(0,s.default)(n,e)&&(o=(0,i.default)({},n),r||delete o[e],o[t]=A(n)),o}))},noUnknown:function(e,t){void 0===e&&(e=!0),void 0===t&&(t=p.object.noUnknown),"string"==typeof e&&(t=e,e=!0);var r=this.test({name:"noUnknown",exclusive:!0,message:t,test:function(t){return null==t||!e||0===function(e,t){var r=Object.keys(e.fields);return Object.keys(t).filter((function(e){return-1===r.indexOf(e)}))}(this.schema,t).length}});return r._options.stripUnknown=e,r},unknown:function(e,t){return void 0===e&&(e=!0),void 0===t&&(t=p.object.noUnknown),this.noUnknown(!e,t)},transformKeys:function(e){return this.transform((function(t){return t&&(0,g.default)(t,(function(t,r){return e(r)}))}))},camelCase:function(){return this.transformKeys(c.default)},snakeCase:function(){return this.transformKeys(a.default)},constantCase:function(){return this.transformKeys((function(e){return(0,a.default)(e).toUpperCase()}))},describe:function(){var e=h.default.prototype.describe.call(this);return e.fields=(0,l.default)(this.fields,(function(e){return e.describe()})),e}}),e.exports=t.default},24280:(e,t,r)=>{"use strict";var A=r(60087);t.__esModule=!0,t.default=function(e){Object.keys(e).forEach((function(t){Object.keys(e[t]).forEach((function(r){n.default[t][r]=e[t][r]}))}))};var n=A(r(63802));e.exports=t.default},45167:(e,t,r)=>{"use strict";var A=r(60087);t.__esModule=!0,t.default=l;var n=A(r(31490)),o=A(r(16434)),i=r(63802),s=A(r(71665)),a=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,c=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,g=function(e){return(0,s.default)(e)||e===e.trim()};function l(){var e=this;if(!(this instanceof l))return new l;o.default.call(this,{type:"string"}),this.withMutation((function(){e.transform((function(e){return this.isType(e)?e:null!=e&&e.toString?e.toString():e}))}))}(0,n.default)(l,o.default,{_typeCheck:function(e){return e instanceof String&&(e=e.valueOf()),"string"==typeof e},_isPresent:function(e){return o.default.prototype._cast.call(this,e)&&e.length>0},length:function(e,t){return void 0===t&&(t=i.string.length),this.test({message:t,name:"length",exclusive:!0,params:{length:e},test:function(t){return(0,s.default)(t)||t.length===this.resolve(e)}})},min:function(e,t){return void 0===t&&(t=i.string.min),this.test({message:t,name:"min",exclusive:!0,params:{min:e},test:function(t){return(0,s.default)(t)||t.length>=this.resolve(e)}})},max:function(e,t){return void 0===t&&(t=i.string.max),this.test({name:"max",exclusive:!0,message:t,params:{max:e},test:function(t){return(0,s.default)(t)||t.length<=this.resolve(e)}})},matches:function(e,t){var r,A=!1;return t&&(t.message||t.hasOwnProperty("excludeEmptyString")?(A=t.excludeEmptyString,r=t.message):r=t),this.test({message:r||i.string.matches,params:{regex:e},test:function(t){return(0,s.default)(t)||""===t&&A||e.test(t)}})},email:function(e){return void 0===e&&(e=i.string.email),this.matches(a,{message:e,excludeEmptyString:!0})},url:function(e){return void 0===e&&(e=i.string.url),this.matches(c,{message:e,excludeEmptyString:!0})},ensure:function(){return this.default("").transform((function(e){return null===e?"":e}))},trim:function(e){return void 0===e&&(e=i.string.trim),this.transform((function(e){return null!=e?e.trim():e})).test({message:e,name:"trim",test:g})},lowercase:function(e){return void 0===e&&(e=i.string.lowercase),this.transform((function(e){return(0,s.default)(e)?e:e.toLowerCase()})).test({message:e,name:"string_case",exclusive:!0,test:function(e){return(0,s.default)(e)||e===e.toLowerCase()}})},uppercase:function(e){return void 0===e&&(e=i.string.uppercase),this.transform((function(e){return(0,s.default)(e)?e:e.toUpperCase()})).test({message:e,name:"string_case",exclusive:!0,test:function(e){return(0,s.default)(e)||e===e.toUpperCase()}})}}),e.exports=t.default},54107:(e,t,r)=>{"use strict";var A=r(60087);t.__esModule=!0,t.createErrorFactory=l,t.default=function(e){var t=e.name,r=e.message,A=e.test,i=e.params;function g(e){var g=e.value,u=e.path,h=e.label,p=e.options,d=e.originalValue,C=e.sync,f=(0,n.default)(e,["value","path","label","options","originalValue","sync"]),I=p.parent,E=function(e){return a.default.isRef(e)?e.getValue({value:g,parent:I,context:p.context}):e},B=l({message:r,path:u,value:g,originalValue:d,params:i,label:h,resolve:E,name:t}),y=(0,o.default)({path:u,parent:I,type:t,createError:B,resolve:E,options:p},f);return function(e,t,r,A){var n=e.call(t,r);if(!A)return Promise.resolve(n);if(o=n,o&&"function"==typeof o.then&&"function"==typeof o.catch)throw new Error('Validation test of type: "'+t.type+'" returned a Promise during a synchronous validate. This test will finish after the validate call has returned');var o;return c.SynchronousPromise.resolve(n)}(A,y,g,C).then((function(e){if(s.default.isError(e))throw e;if(!e)throw B()}))}return g.OPTIONS=e,g};var n=A(r(74943)),o=A(r(72912)),i=A(r(89612)),s=A(r(40828)),a=A(r(95814)),c=r(93255),g=s.default.formatError;function l(e){var t=e.value,r=e.label,A=e.resolve,a=e.originalValue,c=(0,n.default)(e,["value","label","resolve","originalValue"]);return function(e){var n=void 0===e?{}:e,l=n.path,u=void 0===l?c.path:l,h=n.message,p=void 0===h?c.message:h,d=n.type,C=void 0===d?c.name:d,f=n.params;return f=(0,o.default)({path:u,value:t,originalValue:a,label:r},function(e,t,r){return(0,i.default)((0,o.default)({},e,t),r)}(c.params,f,A)),(0,o.default)(new s.default(g(p,f),t,u,C),{params:f})}}},31490:(e,t,r)=>{"use strict";var A=r(60087);t.__esModule=!0,t.default=function(e,t,r){e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),(0,n.default)(e.prototype,r)};var n=A(r(72912));e.exports=t.default},71665:(e,t)=>{"use strict";t.__esModule=!0,t.default=void 0;t.default=function(e){return null==e},e.exports=t.default},11050:(e,t)=>{"use strict";t.__esModule=!0,t.default=void 0;t.default=function(e){return e&&e.__isYupSchema__},e.exports=t.default},76813:(e,t)=>{"use strict";t.__esModule=!0,t.default=function(e){var t,A,n=[1,4,5,6,7,10,11],o=0;if(A=r.exec(e)){for(var i,s=0;i=n[s];++s)A[i]=+A[i]||0;A[2]=(+A[2]||1)-1,A[3]=+A[3]||1,A[7]=A[7]?String(A[7]).substr(0,3):0,void 0!==A[8]&&""!==A[8]||void 0!==A[9]&&""!==A[9]?("Z"!==A[8]&&void 0!==A[9]&&(o=60*A[10]+A[11],"+"===A[9]&&(o=0-o)),t=Date.UTC(A[1],A[2],A[3],A[4],A[5]+o,A[6],A[7])):t=+new Date(A[1],A[2],A[3],A[4],A[5],A[6],A[7])}else t=Date.parse?Date.parse(e):NaN;return t};var r=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;e.exports=t.default},7045:(e,t)=>{"use strict";t.__esModule=!0,t.default=function(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),A=1;A{"use strict";var A=r(60087);t.__esModule=!0,t.default=function e(t,r){for(var A in r)if((0,n.default)(r,A)){var s=r[A],a=t[A];if(void 0===a)t[A]=s;else{if(a===s)continue;(0,o.default)(a)?(0,o.default)(s)&&(t[A]=s.concat(a)):i(a)?i(s)&&(t[A]=e(a,s)):Array.isArray(a)&&Array.isArray(s)&&(t[A]=s.concat(a))}}return t};var n=A(r(15215)),o=A(r(11050)),i=function(e){return"[object Object]"===Object.prototype.toString.call(e)};e.exports=t.default},21043:(e,t)=>{"use strict";t.__esModule=!0,t.default=function(e,t){var r=s(e,t);return null!==r?r:JSON.stringify(e,(function(e,r){var A=s(this[e],t);return null!==A?A:r}),2)};var r=Object.prototype.toString,A=Error.prototype.toString,n=RegExp.prototype.toString,o="undefined"!=typeof Symbol?Symbol.prototype.toString:function(){return""},i=/^Symbol\((.*)\)(.*)$/;function s(e,t){if(void 0===t&&(t=!1),null==e||!0===e||!1===e)return""+e;var s=typeof e;if("number"===s)return function(e){return e!=+e?"NaN":0===e&&1/e<0?"-0":""+e}(e);if("string"===s)return t?'"'+e+'"':e;if("function"===s)return"[Function "+(e.name||"anonymous")+"]";if("symbol"===s)return o.call(e).replace(i,"Symbol($1)");var a=r.call(e).slice(8,-1);return"Date"===a?isNaN(e.getTime())?""+e:e.toISOString(e):"Error"===a||e instanceof Error?"["+A.call(e)+"]":"RegExp"===a?n.call(e):null}e.exports=t.default},43910:(e,t,r)=>{"use strict";var A=r(60087);t.__esModule=!0,t.getIn=i,t.default=void 0;var n=r(79588),o=A(r(15215));function i(e,t,r,A){var i,s,a;return A=A||r,t?((0,n.forEach)(t,(function(n,c,g){var l=c?function(e){return e.substr(0,e.length-1).substr(1)}(n):n;if(g||(0,o.default)(e,"_subType")){var u=g?parseInt(l,10):0;if(e=e.resolve({context:A,parent:i,value:r})._subType,r){if(g&&u>=r.length)throw new Error("Yup.reach cannot resolve an array item at index: "+n+", in the path: "+t+". because there is no value at that index. ");r=r[u]}}if(!g){if(e=e.resolve({context:A,parent:i,value:r}),!(0,o.default)(e,"fields")||!(0,o.default)(e.fields,l))throw new Error("The schema does not contain the path: "+t+". (failed at: "+a+' which is a type: "'+e._type+'") ');e=e.fields[l],i=r,r=r&&r[l],s=l,a=c?"["+n+"]":"."+n}})),{schema:e,parent:i,parentPath:s}):{parent:i,parentPath:t,schema:e}}var s=function(e,t,r,A){return i(e,t,r,A).schema};t.default=s},80180:(e,t,r)=>{"use strict";var A=r(60087);t.__esModule=!0,t.propagateErrors=function(e,t){return e?null:function(e){return t.push(e),e.value}},t.settled=a,t.collectErrors=c,t.default=function(e){var t=e.endEarly,r=(0,n.default)(e,["endEarly"]);return t?function(e,t,r){return s(r).all(e).catch((function(e){throw"ValidationError"===e.name&&(e.value=t),e})).then((function(){return t}))}(r.validations,r.value,r.sync):c(r)};var n=A(r(74943)),o=r(93255),i=A(r(40828)),s=function(e){return e?o.SynchronousPromise:Promise};function a(e,t){var r=s(t);return r.all(e.map((function(e){return r.resolve(e).then((function(e){return{fulfilled:!0,value:e}}),(function(e){return{fulfilled:!1,value:e}}))})))}function c(e){var t=e.validations,r=e.value,A=e.path,n=e.sync,o=e.errors,s=e.sort;return o=function(e){return void 0===e&&(e=[]),e.inner&&e.inner.length?e.inner:[].concat(e)}(o),a(t,n).then((function(e){var t=e.filter((function(e){return!e.fulfilled})).reduce((function(e,t){var r=t.value;if(!i.default.isError(r))throw r;return e.concat(r)}),[]);if(s&&t.sort(s),(o=t.concat(o)).length)throw new i.default(o,r,A);return r}))}},23316:(e,t)=>{"use strict";function r(e,t){var r=1/0;return e.some((function(e,A){if(-1!==t.path.indexOf(e))return r=A,!0})),r}t.__esModule=!0,t.default=function(e){var t=Object.keys(e);return function(e,A){return r(t,e)-r(t,A)}},e.exports=t.default},18417:(e,t,r)=>{"use strict";var A=r(60087);t.__esModule=!0,t.default=function(e,t){void 0===t&&(t=[]);var r=[],A=[];function c(e,n){var o=(0,i.split)(e)[0];~A.indexOf(o)||A.push(o),~t.indexOf(n+"-"+o)||r.push([n,o])}for(var g in e)if((0,n.default)(e,g)){var l=e[g];~A.indexOf(g)||A.push(g),s.default.isRef(l)&&l.isSibling?c(l.path,g):(0,a.default)(l)&&l._deps&&l._deps.forEach((function(e){return c(e,g)}))}return o.default.array(A,r).reverse()};var n=A(r(15215)),o=A(r(75158)),i=r(79588),s=A(r(95814)),a=A(r(11050));e.exports=t.default},60306:e=>{"use strict";e.exports=JSON.parse('{"name":"@yarnpkg/cli","version":"2.4.1","license":"BSD-2-Clause","main":"./sources/index.ts","dependencies":{"@yarnpkg/core":"workspace:^2.4.0","@yarnpkg/fslib":"workspace:^2.4.0","@yarnpkg/libzip":"workspace:^2.2.1","@yarnpkg/parsers":"workspace:^2.3.0","@yarnpkg/plugin-compat":"workspace:^2.2.1","@yarnpkg/plugin-dlx":"workspace:^2.1.4","@yarnpkg/plugin-essentials":"workspace:^2.4.0","@yarnpkg/plugin-file":"workspace:^2.2.0","@yarnpkg/plugin-git":"workspace:^2.3.0","@yarnpkg/plugin-github":"workspace:^2.1.2","@yarnpkg/plugin-http":"workspace:^2.1.2","@yarnpkg/plugin-init":"workspace:^2.2.2","@yarnpkg/plugin-link":"workspace:^2.1.1","@yarnpkg/plugin-node-modules":"workspace:^2.3.0","@yarnpkg/plugin-npm":"workspace:^2.4.0","@yarnpkg/plugin-npm-cli":"workspace:^2.3.0","@yarnpkg/plugin-pack":"workspace:^2.2.3","@yarnpkg/plugin-patch":"workspace:^2.1.2","@yarnpkg/plugin-pnp":"workspace:^2.4.0","@yarnpkg/shell":"workspace:^2.4.1","chalk":"^3.0.0","ci-info":"^2.0.0","clipanion":"^2.6.2","fromentries":"^1.2.0","semver":"^7.1.2","tslib":"^1.13.0","yup":"^0.27.0"},"devDependencies":{"@types/ci-info":"^2","@types/yup":"0.26.12","@yarnpkg/builder":"workspace:^2.1.3","@yarnpkg/monorepo":"workspace:0.0.0","@yarnpkg/pnpify":"workspace:^2.4.0","micromatch":"^4.0.2","typescript":"4.1.0-beta"},"peerDependencies":{"@yarnpkg/core":"^2.4.0"},"scripts":{"postpack":"rm -rf lib","prepack":"run build:compile \\"$(pwd)\\"","build:cli+hook":"run build:pnp:hook && builder build bundle","build:cli":"builder build bundle","run:cli":"builder run","update-local":"run build:cli --no-git-hash && rsync -a --delete bundles/ bin/"},"publishConfig":{"main":"./lib/index.js","types":"./lib/index.d.ts","bin":null},"files":["/lib/**/*","!/lib/pluginConfiguration.*","!/lib/cli.*"],"@yarnpkg/builder":{"bundles":{"standard":["@yarnpkg/plugin-essentials","@yarnpkg/plugin-compat","@yarnpkg/plugin-dlx","@yarnpkg/plugin-file","@yarnpkg/plugin-git","@yarnpkg/plugin-github","@yarnpkg/plugin-http","@yarnpkg/plugin-init","@yarnpkg/plugin-link","@yarnpkg/plugin-node-modules","@yarnpkg/plugin-npm","@yarnpkg/plugin-npm-cli","@yarnpkg/plugin-pack","@yarnpkg/plugin-patch","@yarnpkg/plugin-pnp"]}},"repository":{"type":"git","url":"ssh://git@github.com/yarnpkg/berry.git"},"engines":{"node":">=10.19.0"}}')},98497:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=98497,e.exports=t},32178:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=32178,e.exports=t},3368:(e,t,r)=>{var A,n=Object.assign({},r(35747)),o=void 0!==o?o:{},i={};for(A in o)o.hasOwnProperty(A)&&(i[A]=o[A]);var s,a,c,g,l=[],u="";u=__dirname+"/",s=function(e,t){var A=Qe(e);return A?t?A:A.toString():(c||(c=n),g||(g=r(85622)),e=g.normalize(e),c.readFileSync(e,t?null:"utf8"))},a=function(e){var t=s(e,!0);return t.buffer||(t=new Uint8Array(t)),E(t.buffer),t},process.argv.length>1&&process.argv[1].replace(/\\/g,"/"),l=process.argv.slice(2),e.exports=o,o.inspect=function(){return"[Emscripten Module object]"};var h=o.print||console.log.bind(console),p=o.printErr||console.warn.bind(console);for(A in i)i.hasOwnProperty(A)&&(o[A]=i[A]);i=null,o.arguments&&(l=o.arguments),o.thisProgram&&o.thisProgram,o.quit&&o.quit;var d,C;o.wasmBinary&&(d=o.wasmBinary),o.noExitRuntime&&o.noExitRuntime,"object"!=typeof WebAssembly&&_("no native wasm support detected");var f=new WebAssembly.Table({initial:31,maximum:31,element:"anyfunc"}),I=!1;function E(e,t){e||_("Assertion failed: "+t)}function B(e){var t=o["_"+e];return E(t,"Cannot call unknown function "+e+", make sure it is exported"),t}function y(e,t,r,A,n){var o={string:function(e){var t=0;if(null!=e&&0!==e){var r=1+(e.length<<2);b(e,t=xe(r),r)}return t},array:function(e){var t=xe(e.length);return function(e,t){N.set(e,t)}(e,t),t}};var i=B(e),s=[],a=0;if(A)for(var c=0;c=A);)++n;if(n-t>16&&e.subarray&&m)return m.decode(e.subarray(t,n));for(var o="";t>10,56320|1023&c)}}else o+=String.fromCharCode((31&i)<<6|s)}else o+=String.fromCharCode(i)}return o}function Q(e,t){return e?w(F,e,t):""}function D(e,t,r,A){if(!(A>0))return 0;for(var n=r,o=r+A-1,i=0;i=55296&&s<=57343)s=65536+((1023&s)<<10)|1023&e.charCodeAt(++i);if(s<=127){if(r>=o)break;t[r++]=s}else if(s<=2047){if(r+1>=o)break;t[r++]=192|s>>6,t[r++]=128|63&s}else if(s<=65535){if(r+2>=o)break;t[r++]=224|s>>12,t[r++]=128|s>>6&63,t[r++]=128|63&s}else{if(r+3>=o)break;t[r++]=240|s>>18,t[r++]=128|s>>12&63,t[r++]=128|s>>6&63,t[r++]=128|63&s}}return t[r]=0,r-n}function b(e,t,r){return D(e,F,t,r)}function v(e){for(var t=0,r=0;r=55296&&A<=57343&&(A=65536+((1023&A)<<10)|1023&e.charCodeAt(++r)),A<=127?++t:t+=A<=2047?2:A<=65535?3:4}return t}function S(e){var t=v(e)+1,r=Le(t);return r&&D(e,N,r,t),r}var k,N,F,K,M,R,x;function L(e){k=e,o.HEAP8=N=new Int8Array(e),o.HEAP16=K=new Int16Array(e),o.HEAP32=M=new Int32Array(e),o.HEAPU8=F=new Uint8Array(e),o.HEAPU16=new Uint16Array(e),o.HEAPU32=new Uint32Array(e),o.HEAPF32=R=new Float32Array(e),o.HEAPF64=x=new Float64Array(e)}var P=o.INITIAL_MEMORY||16777216;(C=o.wasmMemory?o.wasmMemory:new WebAssembly.Memory({initial:P/65536,maximum:32768}))&&(k=C.buffer),P=k.byteLength,L(k);var O=[],U=[],T=[],j=[];var Y=Math.abs,G=Math.ceil,H=Math.floor,J=Math.min,q=0,z=null,W=null;function V(e){q++,o.monitorRunDependencies&&o.monitorRunDependencies(q)}function X(e){if(q--,o.monitorRunDependencies&&o.monitorRunDependencies(q),0==q&&(null!==z&&(clearInterval(z),z=null),W)){var t=W;W=null,t()}}function _(e){throw o.onAbort&&o.onAbort(e),p(e+=""),I=!0,1,e="abort("+e+"). Build with -s ASSERTIONS=1 for more info.",new WebAssembly.RuntimeError(e)}o.preloadedImages={},o.preloadedAudios={};function Z(e){return t=e,r="data:application/octet-stream;base64,",String.prototype.startsWith?t.startsWith(r):0===t.indexOf(r);var t,r}var $,ee,te,re="data:application/octet-stream;base64,AGFzbQEAAAAB0QIwYAF/AX9gA39/fwF/YAJ/fwF/YAF/AGACf38AYAR/f39/AX9gBX9/f39/AX9gA39/fwBgBH9+f38Bf2AAAX9gAn9+AX9gA39+fwF/YAF/AX5gBX9/f35/AX5gA39/fgF+YAR/f35/AX5gA39+fwF+YAN/f34Bf2AEf39+fwF/YAR/f39/AX5gBH9/f38AYAZ/f39/f38Bf2AFf39+f38Bf2ACfn8Bf2ADf39/AX5gBH9+fn8AYAN/fH8AYAV/fn9/fwF/YAZ/fH9/f38Bf2ACf38BfmAAAGAFf39/f38AYAV/f39+fwBgAn9+AGADf35/AGACf3wAYAN/fHwAYAR/f35+AX9gBH9+fn8Bf2AIf35+f39/fn8Bf2ABfgF/YAN+f38Bf2AFf39/f38BfmAEf39/fgF+YAJ/fgF+YAV+fn9+fwF+YAJ+fgF8YAJ8fwF8ApIBFwFhAWMAAwFhAWQAAAFhAWUAAgFhAWYABQFhAWcAAQFhAWgAAAFhAWkAAAFhAWoAAgFhAWsAAgFhAWwAAgFhAW0AAgFhAW4ABgFhAW8AAAFhAXAABQFhAXEAAQFhAXIAAgFhAXMAAQFhAXQAAQFhAXUAAAFhAXYAAQFhAXcAAAFhAWECAYACgIACAWEBYgFwAB8DgQP/AgcDAwQAAQEDAwAKBAQPBwMDAx8LFAoAAAohDgwMAAcDDBEdAwIDAgMAAQMHCA4XBAgABQAADAAEAggIBQUAAQATAxQjAQECAwMBBgYSAwMFGAEIAwEDAAACGAcGARUBAAcEAiASCAIAFicQAgECAAYCAgIABgQAAy0FAAEBAQQACwsCAgwMAAIIGxsTCgcALwIBAAoWAQEDBgIBAgIABwcHBAMDAwMsEgsICAsBKgcBCxcKAAIJDgMJCgACAAUAAQEBAAMGAAUFBgYGAQIFBQUGFRUFAQEAAwkABQgCCBYSAgoBAgEAAgAADyYAAQEQAAICCQAJAwEAAgQAAB0OCwEACAAAABMAGAgMBAoCAgACAQcEHBcpBwEACQkJLhkZAhERCgECAAAADSsEDQUFAAEBAxEAAAADAQABAAMAAAIAAAQCAgICAgMJAwAAAgIHBBQAAAMDAwEEAQICDQYPDgsPAAokAwMDKCITAwMABAMCAg0lEAkEAgICCQAOAAkeBgkBfwFB0KHBAgsHsQI5AXgAkwMBeQCSAwF6AN0CAUEAlwIBQgDXAQFDANMBAUQAzwEBRQDNAQFGAMoBAUcAyAEBSACRAwFJAI8DAUoAugIBSwDqAQFMAOkBAU0APwFOAL8CAU8AmQIBUACYAgFRAKMCAVIAmwIBUwDoAQFUAOcBAVUA5gEBVgDlAQFXAJQCAVgA5AEBWQDjAQFaAOIBAV8A4QEBJADgAQJhYQD5AQJiYQCSAQJjYQDfAQJkYQDeAQJlYQDdAQJmYQAyAmdhAM8CAmhhABwCaWEA2AECamEASQJrYQDcAQJsYQDbAQJtYQBtAm5hANoBAm9hAO8BAnBhANkBAnFhAO4BAnJhAIkDAnNhALACAnRhAK8CAnVhAK4CAnZhAO0BAndhAOwBAnhhAOsBAnlhABkCemEAFglBAQBBAQsehgP1AvAC8QLtAuwCsQHYAtcCzALLAsoCyQLIAscCxgLFAsQCwAK9AqgCpwKlAqICW4MCggKBAoAC/gEK05oJ/wJAAQF/IwBBEGsiAyAANgIMIAMgATYCCCADIAI2AgQgAygCDARAIAMoAgwgAygCCDYCACADKAIMIAMoAgQ2AgQLC6oNAQd/AkAgAEUNACAAQXhqIgMgAEF8aigCACIBQXhxIgBqIQUCQCABQQFxDQAgAUEDcUUNASADIAMoAgAiAmsiA0HInAEoAgAiBEkNASAAIAJqIQAgA0HMnAEoAgBHBEAgAkH/AU0EQCADKAIIIgQgAkEDdiICQQN0QeCcAWpHGiAEIAMoAgwiAUYEQEG4nAFBuJwBKAIAQX4gAndxNgIADAMLIAQgATYCDCABIAQ2AggMAgsgAygCGCEGAkAgAyADKAIMIgFHBEAgBCADKAIIIgJNBEAgAigCDBoLIAIgATYCDCABIAI2AggMAQsCQCADQRRqIgIoAgAiBA0AIANBEGoiAigCACIEDQBBACEBDAELA0AgAiEHIAQiAUEUaiICKAIAIgQNACABQRBqIQIgASgCECIEDQALIAdBADYCAAsgBkUNAQJAIAMgAygCHCICQQJ0QeieAWoiBCgCAEYEQCAEIAE2AgAgAQ0BQbycAUG8nAEoAgBBfiACd3E2AgAMAwsgBkEQQRQgBigCECADRhtqIAE2AgAgAUUNAgsgASAGNgIYIAMoAhAiAgRAIAEgAjYCECACIAE2AhgLIAMoAhQiAkUNASABIAI2AhQgAiABNgIYDAELIAUoAgQiAUEDcUEDRw0AQcCcASAANgIAIAUgAUF+cTYCBCADIABBAXI2AgQgACADaiAANgIADwsgBSADTQ0AIAUoAgQiAUEBcUUNAAJAIAFBAnFFBEAgBUHQnAEoAgBGBEBB0JwBIAM2AgBBxJwBQcScASgCACAAaiIANgIAIAMgAEEBcjYCBCADQcycASgCAEcNA0HAnAFBADYCAEHMnAFBADYCAA8LIAVBzJwBKAIARgRAQcycASADNgIAQcCcAUHAnAEoAgAgAGoiADYCACADIABBAXI2AgQgACADaiAANgIADwsgAUF4cSAAaiEAAkAgAUH/AU0EQCAFKAIMIQIgBSgCCCIEIAFBA3YiAUEDdEHgnAFqIgdHBEBByJwBKAIAGgsgAiAERgRAQbicAUG4nAEoAgBBfiABd3E2AgAMAgsgAiAHRwRAQcicASgCABoLIAQgAjYCDCACIAQ2AggMAQsgBSgCGCEGAkAgBSAFKAIMIgFHBEBByJwBKAIAIAUoAggiAk0EQCACKAIMGgsgAiABNgIMIAEgAjYCCAwBCwJAIAVBFGoiAigCACIEDQAgBUEQaiICKAIAIgQNAEEAIQEMAQsDQCACIQcgBCIBQRRqIgIoAgAiBA0AIAFBEGohAiABKAIQIgQNAAsgB0EANgIACyAGRQ0AAkAgBSAFKAIcIgJBAnRB6J4BaiIEKAIARgRAIAQgATYCACABDQFBvJwBQbycASgCAEF+IAJ3cTYCAAwCCyAGQRBBFCAGKAIQIAVGG2ogATYCACABRQ0BCyABIAY2AhggBSgCECICBEAgASACNgIQIAIgATYCGAsgBSgCFCICRQ0AIAEgAjYCFCACIAE2AhgLIAMgAEEBcjYCBCAAIANqIAA2AgAgA0HMnAEoAgBHDQFBwJwBIAA2AgAPCyAFIAFBfnE2AgQgAyAAQQFyNgIEIAAgA2ogADYCAAsgAEH/AU0EQCAAQQN2IgFBA3RB4JwBaiEAAn9BuJwBKAIAIgJBASABdCIBcUUEQEG4nAEgASACcjYCACAADAELIAAoAggLIQIgACADNgIIIAIgAzYCDCADIAA2AgwgAyACNgIIDwsgA0IANwIQIAMCf0EAIABBCHYiAUUNABpBHyAAQf///wdLDQAaIAEgAUGA/j9qQRB2QQhxIgF0IgIgAkGA4B9qQRB2QQRxIgJ0IgQgBEGAgA9qQRB2QQJxIgR0QQ92IAEgAnIgBHJrIgFBAXQgACABQRVqdkEBcXJBHGoLIgI2AhwgAkECdEHongFqIQECQAJAAkBBvJwBKAIAIgRBASACdCIHcUUEQEG8nAEgBCAHcjYCACABIAM2AgAgAyABNgIYDAELIABBAEEZIAJBAXZrIAJBH0YbdCECIAEoAgAhAQNAIAEiBCgCBEF4cSAARg0CIAJBHXYhASACQQF0IQIgBCABQQRxaiIHQRBqKAIAIgENAAsgByADNgIQIAMgBDYCGAsgAyADNgIMIAMgAzYCCAwBCyAEKAIIIgAgAzYCDCAEIAM2AgggA0EANgIYIAMgBDYCDCADIAA2AggLQdicAUHYnAEoAgBBf2oiADYCACAADQBBgKABIQMDQCADKAIAIgBBCGohAyAADQALQdicAUF/NgIACwtCAQF/IwBBEGsiASQAIAEgADYCDCABKAIMBEAgASgCDC0AAUEBcQRAIAEoAgwoAgQQFgsgASgCDBAWCyABQRBqJAALQwEBfyMAQRBrIgIkACACIAA2AgwgAiABNgIIIAIoAgwCfyMAQRBrIgAgAigCCDYCDCAAKAIMQQxqCxBEIAJBEGokAAvcLgEMfyMAQRBrIgwkAAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAQfQBTQRAQbicASgCACIGQRAgAEELakF4cSAAQQtJGyIFQQN2IgB2IgFBA3EEQCABQX9zQQFxIABqIgJBA3QiBUHonAFqKAIAIgFBCGohAAJAIAEoAggiAyAFQeCcAWoiBUYEQEG4nAEgBkF+IAJ3cTYCAAwBC0HInAEoAgAaIAMgBTYCDCAFIAM2AggLIAEgAkEDdCICQQNyNgIEIAEgAmoiASABKAIEQQFyNgIEDA0LIAVBwJwBKAIAIghNDQEgAQRAAkBBAiAAdCICQQAgAmtyIAEgAHRxIgBBACAAa3FBf2oiACAAQQx2QRBxIgB2IgFBBXZBCHEiAiAAciABIAJ2IgBBAnZBBHEiAXIgACABdiIAQQF2QQJxIgFyIAAgAXYiAEEBdkEBcSIBciAAIAF2aiICQQN0IgNB6JwBaigCACIBKAIIIgAgA0HgnAFqIgNGBEBBuJwBIAZBfiACd3EiBjYCAAwBC0HInAEoAgAaIAAgAzYCDCADIAA2AggLIAFBCGohACABIAVBA3I2AgQgASAFaiIEIAJBA3QiAiAFayIDQQFyNgIEIAEgAmogAzYCACAIBEAgCEEDdiIFQQN0QeCcAWohAUHMnAEoAgAhAgJ/IAZBASAFdCIFcUUEQEG4nAEgBSAGcjYCACABDAELIAEoAggLIQUgASACNgIIIAUgAjYCDCACIAE2AgwgAiAFNgIIC0HMnAEgBDYCAEHAnAEgAzYCAAwNC0G8nAEoAgAiCkUNASAKQQAgCmtxQX9qIgAgAEEMdkEQcSIAdiIBQQV2QQhxIgIgAHIgASACdiIAQQJ2QQRxIgFyIAAgAXYiAEEBdkECcSIBciAAIAF2IgBBAXZBAXEiAXIgACABdmpBAnRB6J4BaigCACIBKAIEQXhxIAVrIQQgASECA0ACQCACKAIQIgBFBEAgAigCFCIARQ0BCyAAKAIEQXhxIAVrIgIgBCACIARJIgIbIQQgACABIAIbIQEgACECDAELCyABIAVqIgsgAU0NAiABKAIYIQkgASABKAIMIgNHBEBByJwBKAIAIAEoAggiAE0EQCAAKAIMGgsgACADNgIMIAMgADYCCAwMCyABQRRqIgIoAgAiAEUEQCABKAIQIgBFDQQgAUEQaiECCwNAIAIhByAAIgNBFGoiAigCACIADQAgA0EQaiECIAMoAhAiAA0ACyAHQQA2AgAMCwtBfyEFIABBv39LDQAgAEELaiIAQXhxIQVBvJwBKAIAIghFDQBBACAFayEEAkACQAJAAn9BACAAQQh2IgBFDQAaQR8gBUH///8HSw0AGiAAIABBgP4/akEQdkEIcSIAdCIBIAFBgOAfakEQdkEEcSIBdCICIAJBgIAPakEQdkECcSICdEEPdiAAIAFyIAJyayIAQQF0IAUgAEEVanZBAXFyQRxqCyIHQQJ0QeieAWooAgAiAkUEQEEAIQAMAQtBACEAIAVBAEEZIAdBAXZrIAdBH0YbdCEBA0ACQCACKAIEQXhxIAVrIgYgBE8NACACIQMgBiIEDQBBACEEIAIhAAwDCyAAIAIoAhQiBiAGIAIgAUEddkEEcWooAhAiAkYbIAAgBhshACABQQF0IQEgAg0ACwsgACADckUEQEECIAd0IgBBACAAa3IgCHEiAEUNAyAAQQAgAGtxQX9qIgAgAEEMdkEQcSIAdiIBQQV2QQhxIgIgAHIgASACdiIAQQJ2QQRxIgFyIAAgAXYiAEEBdkECcSIBciAAIAF2IgBBAXZBAXEiAXIgACABdmpBAnRB6J4BaigCACEACyAARQ0BCwNAIAAoAgRBeHEgBWsiAiAESSEBIAIgBCABGyEEIAAgAyABGyEDIAAoAhAiAQR/IAEFIAAoAhQLIgANAAsLIANFDQAgBEHAnAEoAgAgBWtPDQAgAyAFaiIHIANNDQEgAygCGCEJIAMgAygCDCIBRwRAQcicASgCACADKAIIIgBNBEAgACgCDBoLIAAgATYCDCABIAA2AggMCgsgA0EUaiICKAIAIgBFBEAgAygCECIARQ0EIANBEGohAgsDQCACIQYgACIBQRRqIgIoAgAiAA0AIAFBEGohAiABKAIQIgANAAsgBkEANgIADAkLQcCcASgCACIBIAVPBEBBzJwBKAIAIQACQCABIAVrIgJBEE8EQEHAnAEgAjYCAEHMnAEgACAFaiIDNgIAIAMgAkEBcjYCBCAAIAFqIAI2AgAgACAFQQNyNgIEDAELQcycAUEANgIAQcCcAUEANgIAIAAgAUEDcjYCBCAAIAFqIgEgASgCBEEBcjYCBAsgAEEIaiEADAsLQcScASgCACIBIAVLBEBBxJwBIAEgBWsiATYCAEHQnAFB0JwBKAIAIgAgBWoiAjYCACACIAFBAXI2AgQgACAFQQNyNgIEIABBCGohAAwLC0EAIQAgBUEvaiIEAn9BkKABKAIABEBBmKABKAIADAELQZygAUJ/NwIAQZSgAUKAoICAgIAENwIAQZCgASAMQQxqQXBxQdiq1aoFczYCAEGkoAFBADYCAEH0nwFBADYCAEGAIAsiAmoiBkEAIAJrIgdxIgIgBU0NCkHwnwEoAgAiAwRAQeifASgCACIIIAJqIgkgCE0NCyAJIANLDQsLQfSfAS0AAEEEcQ0FAkACQEHQnAEoAgAiAwRAQfifASEAA0AgACgCACIIIANNBEAgCCAAKAIEaiADSw0DCyAAKAIIIgANAAsLQQAQPSIBQX9GDQYgAiEGQZSgASgCACIAQX9qIgMgAXEEQCACIAFrIAEgA2pBACAAa3FqIQYLIAYgBU0NBiAGQf7///8HSw0GQfCfASgCACIABEBB6J8BKAIAIgMgBmoiByADTQ0HIAcgAEsNBwsgBhA9IgAgAUcNAQwICyAGIAFrIAdxIgZB/v///wdLDQUgBhA9IgEgACgCACAAKAIEakYNBCABIQALAkAgBUEwaiAGTQ0AIABBf0YNAEGYoAEoAgAiASAEIAZrakEAIAFrcSIBQf7///8HSwRAIAAhAQwICyABED1Bf0cEQCABIAZqIQYgACEBDAgLQQAgBmsQPRoMBQsgACIBQX9HDQYMBAsAC0EAIQMMBwtBACEBDAULIAFBf0cNAgtB9J8BQfSfASgCAEEEcjYCAAsgAkH+////B0sNASACED0iAUEAED0iAE8NASABQX9GDQEgAEF/Rg0BIAAgAWsiBiAFQShqTQ0BC0HonwFB6J8BKAIAIAZqIgA2AgAgAEHsnwEoAgBLBEBB7J8BIAA2AgALAkACQAJAQdCcASgCACIEBEBB+J8BIQADQCABIAAoAgAiAiAAKAIEIgNqRg0CIAAoAggiAA0ACwwCC0HInAEoAgAiAEEAIAEgAE8bRQRAQcicASABNgIAC0EAIQBB/J8BIAY2AgBB+J8BIAE2AgBB2JwBQX82AgBB3JwBQZCgASgCADYCAEGEoAFBADYCAANAIABBA3QiAkHonAFqIAJB4JwBaiIDNgIAIAJB7JwBaiADNgIAIABBAWoiAEEgRw0AC0HEnAEgBkFYaiIAQXggAWtBB3FBACABQQhqQQdxGyICayIDNgIAQdCcASABIAJqIgI2AgAgAiADQQFyNgIEIAAgAWpBKDYCBEHUnAFBoKABKAIANgIADAILIAAtAAxBCHENACABIARNDQAgAiAESw0AIAAgAyAGajYCBEHQnAEgBEF4IARrQQdxQQAgBEEIakEHcRsiAGoiATYCAEHEnAFBxJwBKAIAIAZqIgIgAGsiADYCACABIABBAXI2AgQgAiAEakEoNgIEQdScAUGgoAEoAgA2AgAMAQsgAUHInAEoAgAiA0kEQEHInAEgATYCACABIQMLIAEgBmohAkH4nwEhAAJAAkACQAJAAkACQANAIAIgACgCAEcEQCAAKAIIIgANAQwCCwsgAC0ADEEIcUUNAQtB+J8BIQADQCAAKAIAIgIgBE0EQCACIAAoAgRqIgMgBEsNAwsgACgCCCEADAAACwALIAAgATYCACAAIAAoAgQgBmo2AgQgAUF4IAFrQQdxQQAgAUEIakEHcRtqIgkgBUEDcjYCBCACQXggAmtBB3FBACACQQhqQQdxG2oiASAJayAFayEAIAUgCWohByABIARGBEBB0JwBIAc2AgBBxJwBQcScASgCACAAaiIANgIAIAcgAEEBcjYCBAwDCyABQcycASgCAEYEQEHMnAEgBzYCAEHAnAFBwJwBKAIAIABqIgA2AgAgByAAQQFyNgIEIAAgB2ogADYCAAwDCyABKAIEIgJBA3FBAUYEQCACQXhxIQoCQCACQf8BTQRAIAEoAggiAyACQQN2IgVBA3RB4JwBakcaIAMgASgCDCICRgRAQbicAUG4nAEoAgBBfiAFd3E2AgAMAgsgAyACNgIMIAIgAzYCCAwBCyABKAIYIQgCQCABIAEoAgwiBkcEQCADIAEoAggiAk0EQCACKAIMGgsgAiAGNgIMIAYgAjYCCAwBCwJAIAFBFGoiBCgCACIFDQAgAUEQaiIEKAIAIgUNAEEAIQYMAQsDQCAEIQIgBSIGQRRqIgQoAgAiBQ0AIAZBEGohBCAGKAIQIgUNAAsgAkEANgIACyAIRQ0AAkAgASABKAIcIgJBAnRB6J4BaiIDKAIARgRAIAMgBjYCACAGDQFBvJwBQbycASgCAEF+IAJ3cTYCAAwCCyAIQRBBFCAIKAIQIAFGG2ogBjYCACAGRQ0BCyAGIAg2AhggASgCECICBEAgBiACNgIQIAIgBjYCGAsgASgCFCICRQ0AIAYgAjYCFCACIAY2AhgLIAEgCmohASAAIApqIQALIAEgASgCBEF+cTYCBCAHIABBAXI2AgQgACAHaiAANgIAIABB/wFNBEAgAEEDdiIBQQN0QeCcAWohAAJ/QbicASgCACICQQEgAXQiAXFFBEBBuJwBIAEgAnI2AgAgAAwBCyAAKAIICyEBIAAgBzYCCCABIAc2AgwgByAANgIMIAcgATYCCAwDCyAHAn9BACAAQQh2IgFFDQAaQR8gAEH///8HSw0AGiABIAFBgP4/akEQdkEIcSIBdCICIAJBgOAfakEQdkEEcSICdCIDIANBgIAPakEQdkECcSIDdEEPdiABIAJyIANyayIBQQF0IAAgAUEVanZBAXFyQRxqCyIBNgIcIAdCADcCECABQQJ0QeieAWohAgJAQbycASgCACIDQQEgAXQiBXFFBEBBvJwBIAMgBXI2AgAgAiAHNgIADAELIABBAEEZIAFBAXZrIAFBH0YbdCEEIAIoAgAhAQNAIAEiAigCBEF4cSAARg0DIARBHXYhASAEQQF0IQQgAiABQQRxaiIDKAIQIgENAAsgAyAHNgIQCyAHIAI2AhggByAHNgIMIAcgBzYCCAwCC0HEnAEgBkFYaiIAQXggAWtBB3FBACABQQhqQQdxGyICayIHNgIAQdCcASABIAJqIgI2AgAgAiAHQQFyNgIEIAAgAWpBKDYCBEHUnAFBoKABKAIANgIAIAQgA0EnIANrQQdxQQAgA0FZakEHcRtqQVFqIgAgACAEQRBqSRsiAkEbNgIEIAJBgKABKQIANwIQIAJB+J8BKQIANwIIQYCgASACQQhqNgIAQfyfASAGNgIAQfifASABNgIAQYSgAUEANgIAIAJBGGohAANAIABBBzYCBCAAQQhqIQEgAEEEaiEAIAMgAUsNAAsgAiAERg0DIAIgAigCBEF+cTYCBCAEIAIgBGsiA0EBcjYCBCACIAM2AgAgA0H/AU0EQCADQQN2IgFBA3RB4JwBaiEAAn9BuJwBKAIAIgJBASABdCIBcUUEQEG4nAEgASACcjYCACAADAELIAAoAggLIQEgACAENgIIIAEgBDYCDCAEIAA2AgwgBCABNgIIDAQLIARCADcCECAEAn9BACADQQh2IgBFDQAaQR8gA0H///8HSw0AGiAAIABBgP4/akEQdkEIcSIAdCIBIAFBgOAfakEQdkEEcSIBdCICIAJBgIAPakEQdkECcSICdEEPdiAAIAFyIAJyayIAQQF0IAMgAEEVanZBAXFyQRxqCyIANgIcIABBAnRB6J4BaiEBAkBBvJwBKAIAIgJBASAAdCIGcUUEQEG8nAEgAiAGcjYCACABIAQ2AgAgBCABNgIYDAELIANBAEEZIABBAXZrIABBH0YbdCEAIAEoAgAhAQNAIAEiAigCBEF4cSADRg0EIABBHXYhASAAQQF0IQAgAiABQQRxaiIGKAIQIgENAAsgBiAENgIQIAQgAjYCGAsgBCAENgIMIAQgBDYCCAwDCyACKAIIIgAgBzYCDCACIAc2AgggB0EANgIYIAcgAjYCDCAHIAA2AggLIAlBCGohAAwFCyACKAIIIgAgBDYCDCACIAQ2AgggBEEANgIYIAQgAjYCDCAEIAA2AggLQcScASgCACIAIAVNDQBBxJwBIAAgBWsiATYCAEHQnAFB0JwBKAIAIgAgBWoiAjYCACACIAFBAXI2AgQgACAFQQNyNgIEIABBCGohAAwDC0G0nAFBMDYCAEEAIQAMAgsCQCAJRQ0AAkAgAygCHCIAQQJ0QeieAWoiAigCACADRgRAIAIgATYCACABDQFBvJwBIAhBfiAAd3EiCDYCAAwCCyAJQRBBFCAJKAIQIANGG2ogATYCACABRQ0BCyABIAk2AhggAygCECIABEAgASAANgIQIAAgATYCGAsgAygCFCIARQ0AIAEgADYCFCAAIAE2AhgLAkAgBEEPTQRAIAMgBCAFaiIAQQNyNgIEIAAgA2oiACAAKAIEQQFyNgIEDAELIAMgBUEDcjYCBCAHIARBAXI2AgQgBCAHaiAENgIAIARB/wFNBEAgBEEDdiIBQQN0QeCcAWohAAJ/QbicASgCACICQQEgAXQiAXFFBEBBuJwBIAEgAnI2AgAgAAwBCyAAKAIICyEBIAAgBzYCCCABIAc2AgwgByAANgIMIAcgATYCCAwBCyAHAn9BACAEQQh2IgBFDQAaQR8gBEH///8HSw0AGiAAIABBgP4/akEQdkEIcSIAdCIBIAFBgOAfakEQdkEEcSIBdCICIAJBgIAPakEQdkECcSICdEEPdiAAIAFyIAJyayIAQQF0IAQgAEEVanZBAXFyQRxqCyIANgIcIAdCADcCECAAQQJ0QeieAWohAQJAAkAgCEEBIAB0IgJxRQRAQbycASACIAhyNgIAIAEgBzYCAAwBCyAEQQBBGSAAQQF2ayAAQR9GG3QhACABKAIAIQUDQCAFIgEoAgRBeHEgBEYNAiAAQR12IQIgAEEBdCEAIAEgAkEEcWoiAigCECIFDQALIAIgBzYCEAsgByABNgIYIAcgBzYCDCAHIAc2AggMAQsgASgCCCIAIAc2AgwgASAHNgIIIAdBADYCGCAHIAE2AgwgByAANgIICyADQQhqIQAMAQsCQCAJRQ0AAkAgASgCHCIAQQJ0QeieAWoiAigCACABRgRAIAIgAzYCACADDQFBvJwBIApBfiAAd3E2AgAMAgsgCUEQQRQgCSgCECABRhtqIAM2AgAgA0UNAQsgAyAJNgIYIAEoAhAiAARAIAMgADYCECAAIAM2AhgLIAEoAhQiAEUNACADIAA2AhQgACADNgIYCwJAIARBD00EQCABIAQgBWoiAEEDcjYCBCAAIAFqIgAgACgCBEEBcjYCBAwBCyABIAVBA3I2AgQgCyAEQQFyNgIEIAQgC2ogBDYCACAIBEAgCEEDdiIDQQN0QeCcAWohAEHMnAEoAgAhAgJ/QQEgA3QiAyAGcUUEQEG4nAEgAyAGcjYCACAADAELIAAoAggLIQMgACACNgIIIAMgAjYCDCACIAA2AgwgAiADNgIIC0HMnAEgCzYCAEHAnAEgBDYCAAsgAUEIaiEACyAMQRBqJAAgAAuCBAEDfyACQYAETwRAIAAgASACEBMaIAAPCyAAIAJqIQMCQCAAIAFzQQNxRQRAAkAgAkEBSARAIAAhAgwBCyAAQQNxRQRAIAAhAgwBCyAAIQIDQCACIAEtAAA6AAAgAUEBaiEBIAJBAWoiAiADTw0BIAJBA3ENAAsLAkAgA0F8cSIEQcAASQ0AIAIgBEFAaiIFSw0AA0AgAiABKAIANgIAIAIgASgCBDYCBCACIAEoAgg2AgggAiABKAIMNgIMIAIgASgCEDYCECACIAEoAhQ2AhQgAiABKAIYNgIYIAIgASgCHDYCHCACIAEoAiA2AiAgAiABKAIkNgIkIAIgASgCKDYCKCACIAEoAiw2AiwgAiABKAIwNgIwIAIgASgCNDYCNCACIAEoAjg2AjggAiABKAI8NgI8IAFBQGshASACQUBrIgIgBU0NAAsLIAIgBE8NAQNAIAIgASgCADYCACABQQRqIQEgAkEEaiICIARJDQALDAELIANBBEkEQCAAIQIMAQsgA0F8aiIEIABJBEAgACECDAELIAAhAgNAIAIgAS0AADoAACACIAEtAAE6AAEgAiABLQACOgACIAIgAS0AAzoAAyABQQRqIQEgAkEEaiICIARNDQALCyACIANJBEADQCACIAEtAAA6AAAgAUEBaiEBIAJBAWoiAiADRw0ACwsgAAs/AQF/IwBBEGsiAyQAIAMgADYCDCADIAE2AgggAyACNgIEIAMoAgwgAygCCCADKAIEENYBIQAgA0EQaiQAIAAL3QEBAX8jAEEQayIBJAAgASAANgIMAkAgASgCDEUNACABKAIMKAIwQQBLBEAgASgCDCIAIAAoAjBBf2o2AjALIAEoAgwoAjBBAEsNACABKAIMKAIgQQBLBEAgASgCDEEBNgIgIAEoAgwQMhoLIAEoAgwoAiRBAUYEQCABKAIMEGoLAkAgASgCDCgCLEUNACABKAIMLQAoQQFxDQAgASgCDCgCLCABKAIMEIIDCyABKAIMQQBCAEEFECIaIAEoAgwoAgAEQCABKAIMKAIAEBwLIAEoAgwQFgsgAUEQaiQAC4ECAQF/IwBBEGsiASQAIAEgADYCDCABIAEoAgwoAhw2AgQgASgCBBDpAiABIAEoAgQoAhQ2AgggASgCCCABKAIMKAIQSwRAIAEgASgCDCgCEDYCCAsCQCABKAIIRQ0AIAEoAgwoAgwgASgCBCgCECABKAIIEBoaIAEoAgwiACABKAIIIAAoAgxqNgIMIAEoAgQiACABKAIIIAAoAhBqNgIQIAEoAgwiACABKAIIIAAoAhRqNgIUIAEoAgwiACAAKAIQIAEoAghrNgIQIAEoAgQiACAAKAIUIAEoAghrNgIUIAEoAgQoAhQNACABKAIEIAEoAgQoAgg2AhALIAFBEGokAAtgAQF/IwBBEGsiASQAIAEgADYCCCABIAEoAghCAhAfNgIEAkAgASgCBEUEQCABQQA7AQ4MAQsgASABKAIELQAAIAEoAgQtAAFBCHRqOwEOCyABLwEOIQAgAUEQaiQAIAALWgEBfyMAQSBrIgIkACACIAA2AhwgAiABNwMQIAIgAigCHCACKQMQEM4BNgIMIAIoAgwEQCACKAIcIgAgAikDECAAKQMQfDcDEAsgAigCDCEAIAJBIGokACAAC28BAX8jAEEQayICJAAgAiAANgIIIAIgATsBBiACIAIoAghCAhAfNgIAAkAgAigCAEUEQCACQX82AgwMAQsgAigCACACLwEGOgAAIAIoAgAgAi8BBkEIdToAASACQQA2AgwLIAIoAgwaIAJBEGokAAuPAQEBfyMAQRBrIgIkACACIAA2AgggAiABNgIEIAIgAigCCEIEEB82AgACQCACKAIARQRAIAJBfzYCDAwBCyACKAIAIAIoAgQ6AAAgAigCACACKAIEQQh2OgABIAIoAgAgAigCBEEQdjoAAiACKAIAIAIoAgRBGHY6AAMgAkEANgIMCyACKAIMGiACQRBqJAALtgIBAX8jAEEwayIEJAAgBCAANgIkIAQgATYCICAEIAI3AxggBCADNgIUAkAgBCgCJCkDGEIBIAQoAhSthoNQBEAgBCgCJEEMakEcQQAQFSAEQn83AygMAQsCQCAEKAIkKAIARQRAIAQgBCgCJCgCCCAEKAIgIAQpAxggBCgCFCAEKAIkKAIEEQ8ANwMIDAELIAQgBCgCJCgCACAEKAIkKAIIIAQoAiAgBCkDGCAEKAIUIAQoAiQoAgQRDQA3AwgLIAQpAwhCAFMEQAJAIAQoAhRBBEYNACAEKAIUQQ5GDQACQCAEKAIkIARCCEEEECJCAFMEQCAEKAIkQQxqQRRBABAVDAELIAQoAiRBDGogBCgCACAEKAIEEBULCwsgBCAEKQMINwMoCyAEKQMoIQIgBEEwaiQAIAILFwAgAC0AAEEgcUUEQCABIAIgABBxGgsLUAEBfyMAQRBrIgEkACABIAA2AgwDQCABKAIMBEAgASABKAIMKAIANgIIIAEoAgwoAgwQFiABKAIMEBYgASABKAIINgIMDAELCyABQRBqJAALfQEBfyMAQRBrIgEkACABIAA2AgwgASgCDARAIAFCADcDAANAIAEpAwAgASgCDCkDCFpFBEAgASgCDCgCACABKQMAp0EEdGoQYiABIAEpAwBCAXw3AwAMAQsLIAEoAgwoAgAQFiABKAIMKAIoECYgASgCDBAWCyABQRBqJAALPgEBfyMAQRBrIgEkACABIAA2AgwgASgCDARAIAEoAgwoAgAQFiABKAIMKAIMEBYgASgCDBAWCyABQRBqJAALbgEBfyMAQYACayIFJAACQCACIANMDQAgBEGAwARxDQAgBSABQf8BcSACIANrIgJBgAIgAkGAAkkiARsQMyABRQRAA0AgACAFQYACECMgAkGAfmoiAkH/AUsNAAsLIAAgBSACECMLIAVBgAJqJAAL1AEBAX8jAEEwayIDJAAgAyAANgIoIAMgATcDICADIAI2AhwCQCADKAIoLQAoQQFxBEAgA0F/NgIsDAELAkAgAygCKCgCIEEASwRAIAMoAhxFDQEgAygCHEEBRg0BIAMoAhxBAkYNAQsgAygCKEEMakESQQAQFSADQX82AiwMAQsgAyADKQMgNwMIIAMgAygCHDYCECADKAIoIANBCGpCEEEGECJCAFMEQCADQX82AiwMAQsgAygCKEEAOgA0IANBADYCLAsgAygCLCEAIANBMGokACAAC7gIAQF/IwBBMGsiBCQAIAQgADYCLCAEIAE2AiggBCACNgIkIAQgAzYCICAEQQA2AhQCQCAEKAIsKAKEAUEASgRAIAQoAiwoAgAoAixBAkYEQCAEKAIsEOcCIQAgBCgCLCgCACAANgIsCyAEKAIsIAQoAixBmBZqEHYgBCgCLCAEKAIsQaQWahB2IAQgBCgCLBDmAjYCFCAEIAQoAiwoAqgtQQpqQQN2NgIcIAQgBCgCLCgCrC1BCmpBA3Y2AhggBCgCGCAEKAIcTQRAIAQgBCgCGDYCHAsMAQsgBCAEKAIkQQVqIgA2AhggBCAANgIcCwJAAkAgBCgCJEEEaiAEKAIcSw0AIAQoAihFDQAgBCgCLCAEKAIoIAQoAiQgBCgCIBBXDAELAkACQCAEKAIsKAKIAUEERwRAIAQoAhggBCgCHEcNAQsgBEEDNgIQAkAgBCgCLCgCvC1BECAEKAIQa0oEQCAEIAQoAiBBAmo2AgwgBCgCLCIAIAAvAbgtIAQoAgxB//8DcSAEKAIsKAK8LXRyOwG4LSAEKAIsLwG4LUH/AXEhASAEKAIsKAIIIQIgBCgCLCIDKAIUIQAgAyAAQQFqNgIUIAAgAmogAToAACAEKAIsLwG4LUEIdSEBIAQoAiwoAgghAiAEKAIsIgMoAhQhACADIABBAWo2AhQgACACaiABOgAAIAQoAiwgBCgCDEH//wNxQRAgBCgCLCgCvC1rdTsBuC0gBCgCLCIAIAAoArwtIAQoAhBBEGtqNgK8LQwBCyAEKAIsIgAgAC8BuC0gBCgCIEECakH//wNxIAQoAiwoArwtdHI7AbgtIAQoAiwiACAEKAIQIAAoArwtajYCvC0LIAQoAixBwNsAQcDkABC1AQwBCyAEQQM2AggCQCAEKAIsKAK8LUEQIAQoAghrSgRAIAQgBCgCIEEEajYCBCAEKAIsIgAgAC8BuC0gBCgCBEH//wNxIAQoAiwoArwtdHI7AbgtIAQoAiwvAbgtQf8BcSEBIAQoAiwoAgghAiAEKAIsIgMoAhQhACADIABBAWo2AhQgACACaiABOgAAIAQoAiwvAbgtQQh1IQEgBCgCLCgCCCECIAQoAiwiAygCFCEAIAMgAEEBajYCFCAAIAJqIAE6AAAgBCgCLCAEKAIEQf//A3FBECAEKAIsKAK8LWt1OwG4LSAEKAIsIgAgACgCvC0gBCgCCEEQa2o2ArwtDAELIAQoAiwiACAALwG4LSAEKAIgQQRqQf//A3EgBCgCLCgCvC10cjsBuC0gBCgCLCIAIAQoAgggACgCvC1qNgK8LQsgBCgCLCAEKAIsKAKcFkEBaiAEKAIsKAKoFkEBaiAEKAIUQQFqEOUCIAQoAiwgBCgCLEGUAWogBCgCLEGIE2oQtQELCyAEKAIsELkBIAQoAiAEQCAEKAIsELgBCyAEQTBqJAAL1AEBAX8jAEEgayICJAAgAiAANgIYIAIgATcDECACIAIoAhhFOgAPAkAgAigCGEUEQCACIAIpAxCnEBkiADYCGCAARQRAIAJBADYCHAwCCwsgAkEYEBkiADYCCCAARQRAIAItAA9BAXEEQCACKAIYEBYLIAJBADYCHAwBCyACKAIIQQE6AAAgAigCCCACKAIYNgIEIAIoAgggAikDEDcDCCACKAIIQgA3AxAgAigCCCACLQAPQQFxOgABIAIgAigCCDYCHAsgAigCHCEAIAJBIGokACAAC3gBAX8jAEEQayIBJAAgASAANgIIIAEgASgCCEIEEB82AgQCQCABKAIERQRAIAFBADYCDAwBCyABIAEoAgQtAAAgASgCBC0AASABKAIELQACIAEoAgQtAANBCHRqQQh0akEIdGo2AgwLIAEoAgwhACABQRBqJAAgAAuQAQEDfyAAIQECQAJAIABBA3FFDQAgAC0AAEUEQEEADwsDQCABQQFqIgFBA3FFDQEgAS0AAA0ACwwBCwNAIAEiAkEEaiEBIAIoAgAiA0F/cyADQf/9+3dqcUGAgYKEeHFFDQALIANB/wFxRQRAIAIgAGsPCwNAIAItAAEhAyACQQFqIgEhAiADDQALCyABIABrC2EBAX8jAEEQayICIAA2AgggAiABNwMAAkAgAikDACACKAIIKQMIVgRAIAIoAghBADoAACACQX82AgwMAQsgAigCCEEBOgAAIAIoAgggAikDADcDECACQQA2AgwLIAIoAgwL7wEBAX8jAEEgayICJAAgAiAANgIYIAIgATcDECACIAIoAhhCCBAfNgIMAkAgAigCDEUEQCACQX82AhwMAQsgAigCDCACKQMQQv8BgzwAACACKAIMIAIpAxBCCIhC/wGDPAABIAIoAgwgAikDEEIQiEL/AYM8AAIgAigCDCACKQMQQhiIQv8BgzwAAyACKAIMIAIpAxBCIIhC/wGDPAAEIAIoAgwgAikDEEIoiEL/AYM8AAUgAigCDCACKQMQQjCIQv8BgzwABiACKAIMIAIpAxBCOIhC/wGDPAAHIAJBADYCHAsgAigCHBogAkEgaiQAC4sDAQF/IwBBMGsiAyQAIAMgADYCJCADIAE2AiAgAyACNwMYAkAgAygCJC0AKEEBcQRAIANCfzcDKAwBCwJAAkAgAygCJCgCIEEATQ0AIAMpAxhC////////////AFYNACADKQMYQgBYDQEgAygCIA0BCyADKAIkQQxqQRJBABAVIANCfzcDKAwBCyADKAIkLQA1QQFxBEAgA0J/NwMoDAELAn8jAEEQayIAIAMoAiQ2AgwgACgCDC0ANEEBcQsEQCADQgA3AygMAQsgAykDGFAEQCADQgA3AygMAQsgA0IANwMQA0AgAykDECADKQMYVARAIAMgAygCJCADKAIgIAMpAxCnaiADKQMYIAMpAxB9QQEQIiICNwMIIAJCAFMEQCADKAIkQQE6ADUgAykDEFAEQCADQn83AygMBAsgAyADKQMQNwMoDAMLIAMpAwhQBEAgAygCJEEBOgA0BSADIAMpAwggAykDEHw3AxAMAgsLCyADIAMpAxA3AygLIAMpAyghAiADQTBqJAAgAgs2AQF/IwBBEGsiASAANgIMAn4gASgCDC0AAEEBcQRAIAEoAgwpAwggASgCDCkDEH0MAQtCAAsLsgECAX8BfiMAQRBrIgEkACABIAA2AgQgASABKAIEQggQHzYCAAJAIAEoAgBFBEAgAUIANwMIDAELIAEgASgCAC0AAK0gASgCAC0AB61COIYgASgCAC0ABq1CMIZ8IAEoAgAtAAWtQiiGfCABKAIALQAErUIghnwgASgCAC0AA61CGIZ8IAEoAgAtAAKtQhCGfCABKAIALQABrUIIhnx8NwMICyABKQMIIQIgAUEQaiQAIAILqAEBAX8jAEEQayIBJAAgASAANgIIAkAgASgCCCgCIEEATQRAIAEoAghBDGpBEkEAEBUgAUF/NgIMDAELIAEoAggiACAAKAIgQX9qNgIgIAEoAggoAiBFBEAgASgCCEEAQgBBAhAiGiABKAIIKAIABEAgASgCCCgCABAyQQBIBEAgASgCCEEMakEUQQAQFQsLCyABQQA2AgwLIAEoAgwhACABQRBqJAAgAAvxAgICfwF+AkAgAkUNACAAIAJqIgNBf2ogAToAACAAIAE6AAAgAkEDSQ0AIANBfmogAToAACAAIAE6AAEgA0F9aiABOgAAIAAgAToAAiACQQdJDQAgA0F8aiABOgAAIAAgAToAAyACQQlJDQAgAEEAIABrQQNxIgRqIgMgAUH/AXFBgYKECGwiADYCACADIAIgBGtBfHEiAmoiAUF8aiAANgIAIAJBCUkNACADIAA2AgggAyAANgIEIAFBeGogADYCACABQXRqIAA2AgAgAkEZSQ0AIAMgADYCGCADIAA2AhQgAyAANgIQIAMgADYCDCABQXBqIAA2AgAgAUFsaiAANgIAIAFBaGogADYCACABQWRqIAA2AgAgAiADQQRxQRhyIgFrIgJBIEkNACAArSIFQiCGIAWEIQUgASADaiEBA0AgASAFNwMYIAEgBTcDECABIAU3AwggASAFNwMAIAFBIGohASACQWBqIgJBH0sNAAsLC9wBAQF/IwBBEGsiASQAIAEgADYCDCABKAIMBEAgASgCDCgCKARAIAEoAgwoAihBADYCKCABKAIMKAIoQgA3AyAgASgCDAJ+IAEoAgwpAxggASgCDCkDIFYEQCABKAIMKQMYDAELIAEoAgwpAyALNwMYCyABIAEoAgwpAxg3AwADQCABKQMAIAEoAgwpAwhaRQRAIAEoAgwoAgAgASkDAKdBBHRqKAIAEBYgASABKQMAQgF8NwMADAELCyABKAIMKAIAEBYgASgCDCgCBBAWIAEoAgwQFgsgAUEQaiQAC2ACAX8BfiMAQRBrIgEkACABIAA2AgQCQCABKAIEKAIkQQFHBEAgASgCBEEMakESQQAQFSABQn83AwgMAQsgASABKAIEQQBCAEENECI3AwgLIAEpAwghAiABQRBqJAAgAgugAQEBfyMAQSBrIgMkACADIAA2AhggAyABNgIUIAMgAjcDCCADIAMoAhgoAgAgAygCFCADKQMIEMsBIgI3AwACQCACQgBTBEAgAygCGEEIaiADKAIYKAIAEBggA0F/NgIcDAELIAMpAwAgAykDCFIEQCADKAIYQQhqQQZBGxAVIANBfzYCHAwBCyADQQA2AhwLIAMoAhwhACADQSBqJAAgAAtrAQF/IwBBIGsiAiAANgIcIAJCASACKAIcrYY3AxAgAkEMaiABNgIAA0AgAiACKAIMIgBBBGo2AgwgAiAAKAIANgIIIAIoAghBAEhFBEAgAiACKQMQQgEgAigCCK2GhDcDEAwBCwsgAikDEAsvAQF/IwBBEGsiASQAIAEgADYCDCABKAIMKAIIEBYgASgCDEEANgIIIAFBEGokAAvNAQEBfyMAQRBrIgIkACACIAA2AgggAiABNgIEAkAgAigCCC0AKEEBcQRAIAJBfzYCDAwBCyACKAIERQRAIAIoAghBDGpBEkEAEBUgAkF/NgIMDAELIAIoAgQQPCACKAIIKAIABEAgAigCCCgCACACKAIEEDlBAEgEQCACKAIIQQxqIAIoAggoAgAQGCACQX82AgwMAgsLIAIoAgggAigCBEI4QQMQIkIAUwRAIAJBfzYCDAwBCyACQQA2AgwLIAIoAgwhACACQRBqJAAgAAsxAQF/IwBBEGsiASQAIAEgADYCDCABKAIMBEAgASgCDBBcIAEoAgwQFgsgAUEQaiQAC98EAQF/IwBBIGsiAiAANgIYIAIgATYCFAJAIAIoAhhFBEAgAkEBNgIcDAELIAIgAigCGCgCADYCDAJAIAIoAhgoAggEQCACIAIoAhgoAgg2AhAMAQsgAkEBNgIQIAJBADYCCANAAkAgAigCCCACKAIYLwEETw0AAkAgAigCDCACKAIIai0AAEEfSgRAIAIoAgwgAigCCGotAABBgAFIDQELIAIoAgwgAigCCGotAABBDUYNACACKAIMIAIoAghqLQAAQQpGDQAgAigCDCACKAIIai0AAEEJRgRADAELIAJBAzYCEAJAIAIoAgwgAigCCGotAABB4AFxQcABRgRAIAJBATYCAAwBCwJAIAIoAgwgAigCCGotAABB8AFxQeABRgRAIAJBAjYCAAwBCwJAIAIoAgwgAigCCGotAABB+AFxQfABRgRAIAJBAzYCAAwBCyACQQQ2AhAMBAsLCyACKAIIIAIoAgBqIAIoAhgvAQRPBEAgAkEENgIQDAILIAJBATYCBANAIAIoAgQgAigCAE0EQCACKAIMIAIoAgggAigCBGpqLQAAQcABcUGAAUcEQCACQQQ2AhAMBgUgAiACKAIEQQFqNgIEDAILAAsLIAIgAigCACACKAIIajYCCAsgAiACKAIIQQFqNgIIDAELCwsgAigCGCACKAIQNgIIIAIoAhQEQAJAIAIoAhRBAkcNACACKAIQQQNHDQAgAkECNgIQIAIoAhhBAjYCCAsCQCACKAIUIAIoAhBGDQAgAigCEEEBRg0AIAJBBTYCHAwCCwsgAiACKAIQNgIcCyACKAIcC2oBAX8jAEEQayIBIAA2AgwgASgCDEIANwMAIAEoAgxBADYCCCABKAIMQn83AxAgASgCDEEANgIsIAEoAgxBfzYCKCABKAIMQgA3AxggASgCDEIANwMgIAEoAgxBADsBMCABKAIMQQA7ATILbwEBfwJAIABBA2pBfHEiAUEBTkEAAn9BqKABKAIAIgBFBEBBqKABQdChwQI2AgBB0KHBAiEACyAAIAFqIgEgAE0LGw0AIAE/AEEQdEsEQCABEBRFDQELQaigASABNgIAIAAPC0G0nAFBMDYCAEF/Cz8BAX8jAEEQayIDJAAgAyAANgIMIAMgATYCCCADIAI2AgQgAygCDCADKAIIIAMoAgQQ6wIhACADQRBqJAAgAAuqAgEBfyMAQRBrIgEkACABIAA2AgwgASgCDARAIAEoAgwoAgAEQCABKAIMKAIAEDIaIAEoAgwoAgAQHAsgASgCDCgCHBAWIAEoAgwoAiAQJiABKAIMKAIkECYgASgCDCgCUBCAAyABKAIMKAJABEAgAUIANwMAA0AgASkDACABKAIMKQMwWkUEQCABKAIMKAJAIAEpAwCnQQR0ahBiIAEgASkDAEIBfDcDAAwBCwsgASgCDCgCQBAWCyABQgA3AwADQCABKQMAIAEoAgwoAkStWkUEQCABKAIMKAJMIAEpAwCnQQJ0aigCABCDAyABIAEpAwBCAXw3AwAMAQsLIAEoAgwoAkwQFiABKAIMKAJUEPoCIAEoAgxBCGoQOCABKAIMEBYLIAFBEGokAAtvAQF/IwBBIGsiAyQAIAMgADYCGCADIAE2AhQgAyACNgIQIAMgAygCGCADKAIQrRAfNgIMAkAgAygCDEUEQCADQX82AhwMAQsgAygCDCADKAIUIAMoAhAQGhogA0EANgIcCyADKAIcGiADQSBqJAALogEBAX8jAEEgayIEJAAgBCAANgIYIAQgATcDECAEIAI2AgwgBCADNgIIIAQgBCgCDCAEKQMQECoiADYCBAJAIABFBEAgBCgCCEEOQQAQFSAEQQA2AhwMAQsgBCgCGCAEKAIEKAIEIAQpAxAgBCgCCBBhQQBIBEAgBCgCBBAXIARBADYCHAwBCyAEIAQoAgQ2AhwLIAQoAhwhACAEQSBqJAAgAAugAQEBfyMAQSBrIgMkACADIAA2AhQgAyABNgIQIAMgAjcDCCADIAMoAhA2AgQCQCADKQMIQghUBEAgA0J/NwMYDAELIwBBEGsiACADKAIUNgIMIAAoAgwoAgAhACADKAIEIAA2AgAjAEEQayIAIAMoAhQ2AgwgACgCDCgCBCEAIAMoAgQgADYCBCADQgg3AxgLIAMpAxghAiADQSBqJAAgAguDAQIDfwF+AkAgAEKAgICAEFQEQCAAIQUMAQsDQCABQX9qIgEgACAAQgqAIgVCCn59p0EwcjoAACAAQv////+fAVYhAiAFIQAgAg0ACwsgBaciAgRAA0AgAUF/aiIBIAIgAkEKbiIDQQpsa0EwcjoAACACQQlLIQQgAyECIAQNAAsLIAELPwEBfyMAQRBrIgIgADYCDCACIAE2AgggAigCDARAIAIoAgwgAigCCCgCADYCACACKAIMIAIoAggoAgQ2AgQLC7wCAQF/IwBBIGsiBCQAIAQgADYCGCAEIAE3AxAgBCACNgIMIAQgAzYCCCAEKAIIRQRAIAQgBCgCGEEIajYCCAsCQCAEKQMQIAQoAhgpAzBaBEAgBCgCCEESQQAQFSAEQQA2AhwMAQsCQCAEKAIMQQhxRQRAIAQoAhgoAkAgBCkDEKdBBHRqKAIEDQELIAQoAhgoAkAgBCkDEKdBBHRqKAIARQRAIAQoAghBEkEAEBUgBEEANgIcDAILAkAgBCgCGCgCQCAEKQMQp0EEdGotAAxBAXFFDQAgBCgCDEEIcQ0AIAQoAghBF0EAEBUgBEEANgIcDAILIAQgBCgCGCgCQCAEKQMQp0EEdGooAgA2AhwMAQsgBCAEKAIYKAJAIAQpAxCnQQR0aigCBDYCHAsgBCgCHCEAIARBIGokACAAC4QBAQF/IwBBEGsiASQAIAEgADYCCCABQdgAEBkiADYCBAJAIABFBEAgAUEANgIMDAELAkAgASgCCARAIAEoAgQgASgCCEHYABAaGgwBCyABKAIEEF0LIAEoAgRBADYCACABKAIEQQE6AAUgASABKAIENgIMCyABKAIMIQAgAUEQaiQAIAAL1AIBAX8jAEEgayIEJAAgBCAANgIYIAQgATYCFCAEIAI2AhAgBCADNgIMAkAgBCgCGEUEQCAEKAIUBEAgBCgCFEEANgIACyAEQbDTADYCHAwBCyAEKAIQQcAAcUUEQCAEKAIYKAIIRQRAIAQoAhhBABA7GgsCQAJAAkAgBCgCEEGAAXFFDQAgBCgCGCgCCEEBRg0AIAQoAhgoAghBAkcNAQsgBCgCGCgCCEEERw0BCyAEKAIYKAIMRQRAIAQoAhgoAgAgBCgCGC8BBCAEKAIYQRBqIAQoAgwQ0gEhACAEKAIYIAA2AgwgAEUEQCAEQQA2AhwMBAsLIAQoAhQEQCAEKAIUIAQoAhgoAhA2AgALIAQgBCgCGCgCDDYCHAwCCwsgBCgCFARAIAQoAhQgBCgCGC8BBDYCAAsgBCAEKAIYKAIANgIcCyAEKAIcIQAgBEEgaiQAIAALOQEBfyMAQRBrIgEgADYCDEEAIQAgASgCDC0AAEEBcQR/IAEoAgwpAxAgASgCDCkDCFEFQQALQQFxC/ICAQF/IwBBEGsiASQAIAEgADYCCAJAIAEoAggtAChBAXEEQCABQX82AgwMAQsgASgCCCgCJEEDRgRAIAEoAghBDGpBF0EAEBUgAUF/NgIMDAELAkAgASgCCCgCIEEASwRAAn8jAEEQayIAIAEoAgg2AgwgACgCDCkDGELAAINQCwRAIAEoAghBDGpBHUEAEBUgAUF/NgIMDAMLDAELIAEoAggoAgAEQCABKAIIKAIAEElBAEgEQCABKAIIQQxqIAEoAggoAgAQGCABQX82AgwMAwsLIAEoAghBAEIAQQAQIkIAUwRAIAEoAggoAgAEQCABKAIIKAIAEDIaCyABQX82AgwMAgsLIAEoAghBADoANCABKAIIQQA6ADUjAEEQayIAIAEoAghBDGo2AgwgACgCDARAIAAoAgxBADYCACAAKAIMQQA2AgQLIAEoAggiACAAKAIgQQFqNgIgIAFBADYCDAsgASgCDCEAIAFBEGokACAAC3cCAX8BfiMAQRBrIgEkACABIAA2AgQCQCABKAIELQAoQQFxBEAgAUJ/NwMIDAELIAEoAgQoAiBBAE0EQCABKAIEQQxqQRJBABAVIAFCfzcDCAwBCyABIAEoAgRBAEIAQQcQIjcDCAsgASkDCCECIAFBEGokACACC50BAQF/IwBBEGsiASAANgIIAkACQAJAIAEoAghFDQAgASgCCCgCIEUNACABKAIIKAIkDQELIAFBATYCDAwBCyABIAEoAggoAhw2AgQCQAJAIAEoAgRFDQAgASgCBCgCACABKAIIRw0AIAEoAgQoAgRBtP4ASQ0AIAEoAgQoAgRB0/4ATQ0BCyABQQE2AgwMAQsgAUEANgIMCyABKAIMC4ABAQN/IwBBEGsiAiAANgIMIAIgATYCCCACKAIIQQh2IQEgAigCDCgCCCEDIAIoAgwiBCgCFCEAIAQgAEEBajYCFCAAIANqIAE6AAAgAigCCEH/AXEhASACKAIMKAIIIQMgAigCDCICKAIUIQAgAiAAQQFqNgIUIAAgA2ogAToAAAuCAQECfyAARQRAIAEQGQ8LIAFBQE8EQEG0nAFBMDYCAEEADwsgAEF4akEQIAFBC2pBeHEgAUELSRsQ7gIiAgRAIAJBCGoPCyABEBkiAkUEQEEADwsgAiAAQXxBeCAAQXxqKAIAIgNBA3EbIANBeHFqIgMgASADIAFJGxAaGiAAEBYgAgubBQEBfyMAQUBqIgQkACAEIAA2AjggBCABNwMwIAQgAjYCLCAEIAM2AiggBEHIABAZIgA2AiQCQCAARQRAIARBADYCPAwBCyAEKAIkQgA3AzggBCgCJEIANwMYIAQoAiRCADcDMCAEKAIkQQA2AgAgBCgCJEEANgIEIAQoAiRCADcDCCAEKAIkQgA3AxAgBCgCJEEANgIoIAQoAiRCADcDIAJAIAQpAzBQBEBBCBAZIQAgBCgCJCAANgIEIABFBEAgBCgCJBAWIAQoAihBDkEAEBUgBEEANgI8DAMLIAQoAiQoAgRCADcDAAwBCyAEKAIkIAQpAzBBABC9AUEBcUUEQCAEKAIoQQ5BABAVIAQoAiQQNCAEQQA2AjwMAgsgBEIANwMIIARCADcDGCAEQgA3AxADQCAEKQMYIAQpAzBUBEAgBCgCOCAEKQMYp0EEdGopAwhQRQRAIAQoAjggBCkDGKdBBHRqKAIARQRAIAQoAihBEkEAEBUgBCgCJBA0IARBADYCPAwFCyAEKAIkKAIAIAQpAxCnQQR0aiAEKAI4IAQpAxinQQR0aigCADYCACAEKAIkKAIAIAQpAxCnQQR0aiAEKAI4IAQpAxinQQR0aikDCDcDCCAEKAIkKAIEIAQpAxinQQN0aiAEKQMINwMAIAQgBCgCOCAEKQMYp0EEdGopAwggBCkDCHw3AwggBCAEKQMQQgF8NwMQCyAEIAQpAxhCAXw3AxgMAQsLIAQoAiQgBCkDEDcDCCAEKAIkAn5CACAEKAIsDQAaIAQoAiQpAwgLNwMYIAQoAiQoAgQgBCgCJCkDCKdBA3RqIAQpAwg3AwAgBCgCJCAEKQMINwMwCyAEIAQoAiQ2AjwLIAQoAjwhACAEQUBrJAAgAAueAQEBfyMAQSBrIgQkACAEIAA2AhggBCABNwMQIAQgAjYCDCAEIAM2AgggBCAEKAIYIAQpAxAgBCgCDCAEKAIIEEUiADYCBAJAIABFBEAgBEEANgIcDAELIAQgBCgCBCgCMEEAIAQoAgwgBCgCCBBHIgA2AgAgAEUEQCAEQQA2AhwMAQsgBCAEKAIANgIcCyAEKAIcIQAgBEEgaiQAIAAL2gEBAX8jAEEgayIEJAAgBCAAOwEaIAQgATsBGCAEIAI2AhQgBCADNgIQIARBEBAZIgA2AgwCQCAARQRAIARBADYCHAwBCyAEKAIMQQA2AgAgBCgCDCAEKAIQNgIEIAQoAgwgBC8BGjsBCCAEKAIMIAQvARg7AQoCQCAELwEYQQBKBEAgBCgCFCAELwEYEMkBIQAgBCgCDCAANgIMIABFBEAgBCgCDBAWIARBADYCHAwDCwwBCyAEKAIMQQA2AgwLIAQgBCgCDDYCHAsgBCgCHCEAIARBIGokACAAC4wDAQF/IwBBIGsiBCQAIAQgADYCGCAEIAE7ARYgBCACNgIQIAQgAzYCDAJAIAQvARZFBEAgBEEANgIcDAELAkACQAJAAkAgBCgCEEGAMHEiAARAIABBgBBGDQEgAEGAIEYNAgwDCyAEQQA2AgQMAwsgBEECNgIEDAILIARBBDYCBAwBCyAEKAIMQRJBABAVIARBADYCHAwBCyAEQRQQGSIANgIIIABFBEAgBCgCDEEOQQAQFSAEQQA2AhwMAQsgBC8BFkEBahAZIQAgBCgCCCAANgIAIABFBEAgBCgCCBAWIARBADYCHAwBCyAEKAIIKAIAIAQoAhggBC8BFhAaGiAEKAIIKAIAIAQvARZqQQA6AAAgBCgCCCAELwEWOwEEIAQoAghBADYCCCAEKAIIQQA2AgwgBCgCCEEANgIQIAQoAgQEQCAEKAIIIAQoAgQQO0EFRgRAIAQoAggQJiAEKAIMQRJBABAVIARBADYCHAwCCwsgBCAEKAIINgIcCyAEKAIcIQAgBEEgaiQAIAALNwEBfyMAQRBrIgEgADYCCAJAIAEoAghFBEAgAUEAOwEODAELIAEgASgCCC8BBDsBDgsgAS8BDgtDAQN/AkAgAkUNAANAIAAtAAAiBCABLQAAIgVGBEAgAUEBaiEBIABBAWohACACQX9qIgINAQwCCwsgBCAFayEDCyADC5YBAQV/IAAoAkxBAE4EQEEBIQMLIAAoAgBBAXEiBEUEQCAAKAI0IgEEQCABIAAoAjg2AjgLIAAoAjgiAgRAIAIgATYCNAsgAEGwoQEoAgBGBEBBsKEBIAI2AgALCyAAEJsBIQEgACAAKAIMEQAAIQIgACgCYCIFBEAgBRAWCwJAIARFBEAgABAWDAELIANFDQALIAEgAnILjgMCAX8BfiMAQTBrIgQkACAEIAA2AiQgBCABNgIgIAQgAjYCHCAEIAM2AhgCQCAEKAIkRQRAIARCfzcDKAwBCyAEKAIgRQRAIAQoAhhBEkEAEBUgBEJ/NwMoDAELIAQoAhxBgyBxBEAgBEEYQRkgBCgCHEEBcRs2AhQgBEIANwMAA0AgBCkDACAEKAIkKQMwVARAIAQgBCgCJCAEKQMAIAQoAhwgBCgCGBBPNgIQIAQoAhAEQCAEKAIcQQJxBEAgBCAEKAIQIgAgABAsQQFqEKECNgIMIAQoAgwEQCAEIAQoAgxBAWo2AhALCyAEKAIgIAQoAhAgBCgCFBECAEUEQCMAQRBrIgAgBCgCGDYCDCAAKAIMBEAgACgCDEEANgIAIAAoAgxBADYCBAsgBCAEKQMANwMoDAULCyAEIAQpAwBCAXw3AwAMAQsLIAQoAhhBCUEAEBUgBEJ/NwMoDAELIAQgBCgCJCgCUCAEKAIgIAQoAhwgBCgCGBD+AjcDKAsgBCkDKCEFIARBMGokACAFC9AHAQF/IwBBIGsiASQAIAEgADYCHCABIAEoAhwoAiw2AhADQCABIAEoAhwoAjwgASgCHCgCdGsgASgCHCgCbGs2AhQgASgCHCgCbCABKAIQIAEoAhwoAixBhgJrak8EQCABKAIcKAI4IAEoAhwoAjggASgCEGogASgCECABKAIUaxAaGiABKAIcIgAgACgCcCABKAIQazYCcCABKAIcIgAgACgCbCABKAIQazYCbCABKAIcIgAgACgCXCABKAIQazYCXCABKAIcENwCIAEgASgCECABKAIUajYCFAsgASgCHCgCACgCBARAIAEgASgCHCgCACABKAIcKAJ0IAEoAhwoAjggASgCHCgCbGpqIAEoAhQQczYCGCABKAIcIgAgASgCGCAAKAJ0ajYCdCABKAIcKAJ0IAEoAhwoArQtakEDTwRAIAEgASgCHCgCbCABKAIcKAK0LWs2AgwgASgCHCABKAIcKAI4IAEoAgxqLQAANgJIIAEoAhwgASgCHCgCVCABKAIcKAI4IAEoAgxBAWpqLQAAIAEoAhwoAkggASgCHCgCWHRzcTYCSANAIAEoAhwoArQtBEAgASgCHCABKAIcKAJUIAEoAhwoAjggASgCDEECamotAAAgASgCHCgCSCABKAIcKAJYdHNxNgJIIAEoAhwoAkAgASgCDCABKAIcKAI0cUEBdGogASgCHCgCRCABKAIcKAJIQQF0ai8BADsBACABKAIcKAJEIAEoAhwoAkhBAXRqIAEoAgw7AQAgASABKAIMQQFqNgIMIAEoAhwiACAAKAK0LUF/ajYCtC0gASgCHCgCdCABKAIcKAK0LWpBA08NAQsLC0EAIQAgASgCHCgCdEGGAkkEfyABKAIcKAIAKAIEQQBHBUEAC0EBcQ0BCwsgASgCHCgCwC0gASgCHCgCPEkEQCABIAEoAhwoAmwgASgCHCgCdGo2AggCQCABKAIcKALALSABKAIISQRAIAEgASgCHCgCPCABKAIIazYCBCABKAIEQYICSwRAIAFBggI2AgQLIAEoAhwoAjggASgCCGpBACABKAIEEDMgASgCHCABKAIIIAEoAgRqNgLALQwBCyABKAIcKALALSABKAIIQYICakkEQCABIAEoAghBggJqIAEoAhwoAsAtazYCBCABKAIEIAEoAhwoAjwgASgCHCgCwC1rSwRAIAEgASgCHCgCPCABKAIcKALALWs2AgQLIAEoAhwoAjggASgCHCgCwC1qQQAgASgCBBAzIAEoAhwiACABKAIEIAAoAsAtajYCwC0LCwsgAUEgaiQAC4YFAQF/IwBBIGsiBCQAIAQgADYCHCAEIAE2AhggBCACNgIUIAQgAzYCECAEQQM2AgwCQCAEKAIcKAK8LUEQIAQoAgxrSgRAIAQgBCgCEDYCCCAEKAIcIgAgAC8BuC0gBCgCCEH//wNxIAQoAhwoArwtdHI7AbgtIAQoAhwvAbgtQf8BcSEBIAQoAhwoAgghAiAEKAIcIgMoAhQhACADIABBAWo2AhQgACACaiABOgAAIAQoAhwvAbgtQQh1IQEgBCgCHCgCCCECIAQoAhwiAygCFCEAIAMgAEEBajYCFCAAIAJqIAE6AAAgBCgCHCAEKAIIQf//A3FBECAEKAIcKAK8LWt1OwG4LSAEKAIcIgAgACgCvC0gBCgCDEEQa2o2ArwtDAELIAQoAhwiACAALwG4LSAEKAIQQf//A3EgBCgCHCgCvC10cjsBuC0gBCgCHCIAIAQoAgwgACgCvC1qNgK8LQsgBCgCHBC4ASAEKAIUQf8BcSEBIAQoAhwoAgghAiAEKAIcIgMoAhQhACADIABBAWo2AhQgACACaiABOgAAIAQoAhRB//8DcUEIdSEBIAQoAhwoAgghAiAEKAIcIgMoAhQhACADIABBAWo2AhQgACACaiABOgAAIAQoAhRBf3NB/wFxIQEgBCgCHCgCCCECIAQoAhwiAygCFCEAIAMgAEEBajYCFCAAIAJqIAE6AAAgBCgCFEF/c0H//wNxQQh1IQEgBCgCHCgCCCECIAQoAhwiAygCFCEAIAMgAEEBajYCFCAAIAJqIAE6AAAgBCgCHCgCCCAEKAIcKAIUaiAEKAIYIAQoAhQQGhogBCgCHCIAIAQoAhQgACgCFGo2AhQgBEEgaiQAC/kBAQF/IwBBIGsiAiQAIAIgADYCHCACIAE5AxACQCACKAIcRQ0AIAICfAJ8IAIrAxBEAAAAAAAAAABkBEAgAisDEAwBC0QAAAAAAAAAAAtEAAAAAAAA8D9jBEACfCACKwMQRAAAAAAAAAAAZARAIAIrAxAMAQtEAAAAAAAAAAALDAELRAAAAAAAAPA/CyACKAIcKwMoIAIoAhwrAyChoiACKAIcKwMgoDkDCCACKwMIIAIoAhwrAxihIAIoAhwrAxBkRQ0AIAIoAhwoAgAgAisDCCACKAIcKAIMIAIoAhwoAgQRGgAgAigCHCACKwMIOQMYCyACQSBqJAAL1AMBAX8jAEEgayIDJAAgAyAANgIYIAMgATYCFCADIAI2AhACQAJAIAMoAhgEQCADKAIUDQELIAMoAhBBEkEAEBUgA0EAOgAfDAELIAMoAhgpAwhCAFYEQCADIAMoAhQQfDYCDCADIAMoAgwgAygCGCgCAHA2AgggA0EANgIAIAMgAygCGCgCECADKAIIQQJ0aigCADYCBANAIAMoAgQEQAJAIAMoAgQoAhwgAygCDEcNACADKAIUIAMoAgQoAgAQWw0AAkAgAygCBCkDCEJ/UQRAAkAgAygCAARAIAMoAgAgAygCBCgCGDYCGAwBCyADKAIYKAIQIAMoAghBAnRqIAMoAgQoAhg2AgALIAMoAgQQFiADKAIYIgAgACkDCEJ/fDcDCAJAIAMoAhgiACkDCLogACgCALhEexSuR+F6hD+iY0UNACADKAIYKAIAQYACTQ0AIAMoAhggAygCGCgCAEEBdiADKAIQEFpBAXFFBEAgA0EAOgAfDAgLCwwBCyADKAIEQn83AxALIANBAToAHwwECyADIAMoAgQ2AgAgAyADKAIEKAIYNgIEDAELCwsgAygCEEEJQQAQFSADQQA6AB8LIAMtAB9BAXEhACADQSBqJAAgAAvfAgEBfyMAQTBrIgMkACADIAA2AiggAyABNgIkIAMgAjYCIAJAIAMoAiQgAygCKCgCAEYEQCADQQE6AC8MAQsgAyADKAIkQQQQeyIANgIcIABFBEAgAygCIEEOQQAQFSADQQA6AC8MAQsgAygCKCkDCEIAVgRAIANBADYCGANAIAMoAhggAygCKCgCAE9FBEAgAyADKAIoKAIQIAMoAhhBAnRqKAIANgIUA0AgAygCFARAIAMgAygCFCgCGDYCECADIAMoAhQoAhwgAygCJHA2AgwgAygCFCADKAIcIAMoAgxBAnRqKAIANgIYIAMoAhwgAygCDEECdGogAygCFDYCACADIAMoAhA2AhQMAQsLIAMgAygCGEEBajYCGAwBCwsLIAMoAigoAhAQFiADKAIoIAMoAhw2AhAgAygCKCADKAIkNgIAIANBAToALwsgAy0AL0EBcSEAIANBMGokACAAC00BAn8gAS0AACECAkAgAC0AACIDRQ0AIAIgA0cNAANAIAEtAAEhAiAALQABIgNFDQEgAUEBaiEBIABBAWohACACIANGDQALCyADIAJrC4kCAQF/IwBBEGsiASQAIAEgADYCDAJAIAEoAgwtAAVBAXEEQCABKAIMKAIAQQJxRQ0BCyABKAIMKAIwECYgASgCDEEANgIwCwJAIAEoAgwtAAVBAXEEQCABKAIMKAIAQQhxRQ0BCyABKAIMKAI0ECQgASgCDEEANgI0CwJAIAEoAgwtAAVBAXEEQCABKAIMKAIAQQRxRQ0BCyABKAIMKAI4ECYgASgCDEEANgI4CwJAIAEoAgwtAAVBAXEEQCABKAIMKAIAQYABcUUNAQsgASgCDCgCVARAIAEoAgwoAlRBACABKAIMKAJUECwQMwsgASgCDCgCVBAWIAEoAgxBADYCVAsgAUEQaiQAC/EBAQF/IwBBEGsiASAANgIMIAEoAgxBADYCACABKAIMQQA6AAQgASgCDEEAOgAFIAEoAgxBAToABiABKAIMQb8GOwEIIAEoAgxBCjsBCiABKAIMQQA7AQwgASgCDEF/NgIQIAEoAgxBADYCFCABKAIMQQA2AhggASgCDEIANwMgIAEoAgxCADcDKCABKAIMQQA2AjAgASgCDEEANgI0IAEoAgxBADYCOCABKAIMQQA2AjwgASgCDEEAOwFAIAEoAgxBgIDYjXg2AkQgASgCDEIANwNIIAEoAgxBADsBUCABKAIMQQA7AVIgASgCDEEANgJUC9oTAQF/IwBBsAFrIgMkACADIAA2AqgBIAMgATYCpAEgAyACNgKgASADQQA2ApABIAMgAygCpAEoAjBBABA7NgKUASADIAMoAqQBKAI4QQAQOzYCmAECQAJAAkACQCADKAKUAUECRgRAIAMoApgBQQFGDQELIAMoApQBQQFGBEAgAygCmAFBAkYNAQsgAygClAFBAkcNASADKAKYAUECRw0BCyADKAKkASIAIAAvAQxBgBByOwEMDAELIAMoAqQBIgAgAC8BDEH/7wNxOwEMIAMoApQBQQJGBEAgA0H14AEgAygCpAEoAjAgAygCqAFBCGoQxAE2ApABIAMoApABRQRAIANBfzYCrAEMAwsLAkAgAygCoAFBgAJxDQAgAygCmAFBAkcNACADQfXGASADKAKkASgCOCADKAKoAUEIahDEATYCSCADKAJIRQRAIAMoApABECQgA0F/NgKsAQwDCyADKAJIIAMoApABNgIAIAMgAygCSDYCkAELCwJAIAMoAqQBLwFSRQRAIAMoAqQBIgAgAC8BDEH+/wNxOwEMDAELIAMoAqQBIgAgAC8BDEEBcjsBDAsgAyADKAKkASADKAKgARCAAUEBcToAhgEgAyADKAKgAUGACnFBgApHBH8gAy0AhgEFQQELQQFxOgCHASADAn9BASADKAKkAS8BUkGBAkYNABpBASADKAKkAS8BUkGCAkYNABogAygCpAEvAVJBgwJGC0EBcToAhQEgAy0AhwFBAXEEQCADIANBIGpCHBAqNgIcIAMoAhxFBEAgAygCqAFBCGpBDkEAEBUgAygCkAEQJCADQX82AqwBDAILAkAgAygCoAFBgAJxBEACQCADKAKgAUGACHENACADKAKkASkDIEL/////D1YNACADKAKkASkDKEL/////D1gNAgsgAygCHCADKAKkASkDKBAuIAMoAhwgAygCpAEpAyAQLgwBCwJAAkAgAygCoAFBgAhxDQAgAygCpAEpAyBC/////w9WDQAgAygCpAEpAyhC/////w9WDQAgAygCpAEpA0hC/////w9YDQELIAMoAqQBKQMoQv////8PWgRAIAMoAhwgAygCpAEpAygQLgsgAygCpAEpAyBC/////w9aBEAgAygCHCADKAKkASkDIBAuCyADKAKkASkDSEL/////D1oEQCADKAIcIAMoAqQBKQNIEC4LCwsCfyMAQRBrIgAgAygCHDYCDCAAKAIMLQAAQQFxRQsEQCADKAKoAUEIakEUQQAQFSADKAIcEBcgAygCkAEQJCADQX82AqwBDAILIANBAQJ/IwBBEGsiACADKAIcNgIMAn4gACgCDC0AAEEBcQRAIAAoAgwpAxAMAQtCAAunQf//A3ELIANBIGpBgAYQUDYCjAEgAygCHBAXIAMoAowBIAMoApABNgIAIAMgAygCjAE2ApABCyADLQCFAUEBcQRAIAMgA0EVakIHECo2AhAgAygCEEUEQCADKAKoAUEIakEOQQAQFSADKAKQARAkIANBfzYCrAEMAgsgAygCEEECECAgAygCEEHP0wBBAhBAIAMoAhAgAygCpAEvAVJB/wFxEIoBIAMoAhAgAygCpAEoAhBB//8DcRAgAn8jAEEQayIAIAMoAhA2AgwgACgCDC0AAEEBcUULBEAgAygCqAFBCGpBFEEAEBUgAygCEBAXIAMoApABECQgA0F/NgKsAQwCCyADQYGyAkEHIANBFWpBgAYQUDYCDCADKAIQEBcgAygCDCADKAKQATYCACADIAMoAgw2ApABCyADIANB0ABqQi4QKiIANgJMIABFBEAgAygCqAFBCGpBDkEAEBUgAygCkAEQJCADQX82AqwBDAELIAMoAkxBxdMAQcrTACADKAKgAUGAAnEbQQQQQCADKAKgAUGAAnFFBEAgAygCTAJ/QS0gAy0AhgFBAXENABogAygCpAEvAQgLQf//A3EQIAsgAygCTAJ/QS0gAy0AhgFBAXENABogAygCpAEvAQoLQf//A3EQICADKAJMIAMoAqQBLwEMECACQCADLQCFAUEBcQRAIAMoAkxB4wAQIAwBCyADKAJMIAMoAqQBKAIQQf//A3EQIAsgAygCpAEoAhQgA0GeAWogA0GcAWoQwwEgAygCTCADLwGeARAgIAMoAkwgAy8BnAEQIAJAAkAgAy0AhQFBAXFFDQAgAygCpAEpAyhCFFoNACADKAJMQQAQIQwBCyADKAJMIAMoAqQBKAIYECELAkACQCADKAKgAUGAAnFBgAJHDQAgAygCpAEpAyBC/////w9UBEAgAygCpAEpAyhC/////w9UDQELIAMoAkxBfxAhIAMoAkxBfxAhDAELAkAgAygCpAEpAyBC/////w9UBEAgAygCTCADKAKkASkDIKcQIQwBCyADKAJMQX8QIQsCQCADKAKkASkDKEL/////D1QEQCADKAJMIAMoAqQBKQMopxAhDAELIAMoAkxBfxAhCwsgAygCTCADKAKkASgCMBBSQf//A3EQICADIAMoAqQBKAI0IAMoAqABEIIBQf//A3EgAygCkAFBgAYQggFB//8DcWo2AogBIAMoAkwgAygCiAFB//8DcRAgIAMoAqABQYACcUUEQCADKAJMIAMoAqQBKAI4EFJB//8DcRAgIAMoAkwgAygCpAEoAjxB//8DcRAgIAMoAkwgAygCpAEvAUAQICADKAJMIAMoAqQBKAJEECECQCADKAKkASkDSEL/////D1QEQCADKAJMIAMoAqQBKQNIpxAhDAELIAMoAkxBfxAhCwsCfyMAQRBrIgAgAygCTDYCDCAAKAIMLQAAQQFxRQsEQCADKAKoAUEIakEUQQAQFSADKAJMEBcgAygCkAEQJCADQX82AqwBDAELIAMoAqgBIANB0ABqAn4jAEEQayIAIAMoAkw2AgwCfiAAKAIMLQAAQQFxBEAgACgCDCkDEAwBC0IACwsQNkEASARAIAMoAkwQFyADKAKQARAkIANBfzYCrAEMAQsgAygCTBAXIAMoAqQBKAIwBEAgAygCqAEgAygCpAEoAjAQhgFBAEgEQCADKAKQARAkIANBfzYCrAEMAgsLIAMoApABBEAgAygCqAEgAygCkAFBgAYQgQFBAEgEQCADKAKQARAkIANBfzYCrAEMAgsLIAMoApABECQgAygCpAEoAjQEQCADKAKoASADKAKkASgCNCADKAKgARCBAUEASARAIANBfzYCrAEMAgsLIAMoAqABQYACcUUEQCADKAKkASgCOARAIAMoAqgBIAMoAqQBKAI4EIYBQQBIBEAgA0F/NgKsAQwDCwsLIAMgAy0AhwFBAXE2AqwBCyADKAKsASEAIANBsAFqJAAgAAuCAgEBfyMAQSBrIgUkACAFIAA2AhggBSABNgIUIAUgAjsBEiAFQQA7ARAgBSADNgIMIAUgBDYCCCAFQQA2AgQCQANAIAUoAhgEQAJAIAUoAhgvAQggBS8BEkcNACAFKAIYKAIEIAUoAgxxQYAGcUUNACAFKAIEIAUvARBIBEAgBSAFKAIEQQFqNgIEDAELIAUoAhQEQCAFKAIUIAUoAhgvAQo7AQALIAUoAhgvAQpBAEoEQCAFIAUoAhgoAgw2AhwMBAsgBUGx0wA2AhwMAwsgBSAFKAIYKAIANgIYDAELCyAFKAIIQQlBABAVIAVBADYCHAsgBSgCHCEAIAVBIGokACAAC4EDAQF/IwBBMGsiBSQAIAUgADYCKCAFIAE2AiQgBSACNgIgIAUgAzoAHyAFIAQ2AhgCQAJAIAUoAiANACAFLQAfQQFxDQAgBUEANgIsDAELIAUgBSgCICAFLQAfQQFxRUVqEBk2AhQgBSgCFEUEQCAFKAIYQQ5BABAVIAVBADYCLAwBCwJAIAUoAigEQCAFIAUoAiggBSgCIK0QHzYCECAFKAIQRQRAIAUoAhhBDkEAEBUgBSgCFBAWIAVBADYCLAwDCyAFKAIUIAUoAhAgBSgCIBAaGgwBCyAFKAIkIAUoAhQgBSgCIK0gBSgCGBBhQQBIBEAgBSgCFBAWIAVBADYCLAwCCwsgBS0AH0EBcQRAIAUoAhQgBSgCIGpBADoAACAFIAUoAhQ2AgwDQCAFKAIMIAUoAhQgBSgCIGpJBEAgBSgCDC0AAEUEQCAFKAIMQSA6AAALIAUgBSgCDEEBajYCDAwBCwsLIAUgBSgCFDYCLAsgBSgCLCEAIAVBMGokACAAC8IBAQF/IwBBMGsiBCQAIAQgADYCKCAEIAE2AiQgBCACNwMYIAQgAzYCFAJAIAQpAxhC////////////AFYEQCAEKAIUQRRBABAVIARBfzYCLAwBCyAEIAQoAiggBCgCJCAEKQMYEC8iAjcDCCACQgBTBEAgBCgCFCAEKAIoEBggBEF/NgIsDAELIAQpAwggBCkDGFMEQCAEKAIUQRFBABAVIARBfzYCLAwBCyAEQQA2AiwLIAQoAiwhACAEQTBqJAAgAAs2AQF/IwBBEGsiASQAIAEgADYCDCABKAIMEGMgASgCDCgCABA6IAEoAgwoAgQQOiABQRBqJAALqwEBAX8jAEEQayIBJAAgASAANgIMIAEoAgwoAggEQCABKAIMKAIIEBwgASgCDEEANgIICwJAIAEoAgwoAgRFDQAgASgCDCgCBCgCAEEBcUUNACABKAIMKAIEKAIQQX5HDQAgASgCDCgCBCIAIAAoAgBBfnE2AgAgASgCDCgCBCgCAEUEQCABKAIMKAIEEDogASgCDEEANgIECwsgASgCDEEAOgAMIAFBEGokAAttAQF/IwBBIGsiBCQAIAQgADYCGCAEIAE2AhQgBCACNgIQIAQgAzYCDAJAIAQoAhhFBEAgBEEANgIcDAELIAQgBCgCFCAEKAIQIAQoAgwgBCgCGEEIahCOATYCHAsgBCgCHCEAIARBIGokACAAC4EGAgF/AX4jAEGQAWsiAyQAIAMgADYChAEgAyABNgKAASADIAI2AnwgAxBdAkAgAygCgAEpAwhCAFIEQCADIAMoAoABKAIAKAIAKQNINwNgIAMgAygCgAEoAgAoAgApA0g3A2gMAQsgA0IANwNgIANCADcDaAsgA0IANwNwAkADQCADKQNwIAMoAoABKQMIVARAIAMoAoABKAIAIAMpA3CnQQR0aigCACkDSCADKQNoVARAIAMgAygCgAEoAgAgAykDcKdBBHRqKAIAKQNINwNoCyADKQNoIAMoAoABKQMgVgRAIAMoAnxBE0EAEBUgA0J/NwOIAQwDCyADIAMoAoABKAIAIAMpA3CnQQR0aigCACkDSCADKAKAASgCACADKQNwp0EEdGooAgApAyB8IAMoAoABKAIAIAMpA3CnQQR0aigCACgCMBBSQf//A3GtfEIefDcDWCADKQNYIAMpA2BWBEAgAyADKQNYNwNgCyADKQNgIAMoAoABKQMgVgRAIAMoAnxBE0EAEBUgA0J/NwOIAQwDCyADKAKEASgCACADKAKAASgCACADKQNwp0EEdGooAgApA0hBABAoQQBIBEAgAygCfCADKAKEASgCABAYIANCfzcDiAEMAwsgAyADKAKEASgCAEEAQQEgAygCfBDCAUJ/UQRAIAMQXCADQn83A4gBDAMLIAMoAoABKAIAIAMpA3CnQQR0aigCACADEPEBBEAgAygCfEEVQQAQFSADEFwgA0J/NwOIAQwDBSADKAKAASgCACADKQNwp0EEdGooAgAoAjQgAygCNBCFASEAIAMoAoABKAIAIAMpA3CnQQR0aigCACAANgI0IAMoAoABKAIAIAMpA3CnQQR0aigCAEEBOgAEIANBADYCNCADEFwgAyADKQNwQgF8NwNwDAILAAsLIAMCfiADKQNgIAMpA2h9Qv///////////wBUBEAgAykDYCADKQNofQwBC0L///////////8ACzcDiAELIAMpA4gBIQQgA0GQAWokACAEC6YBAQF/IwBBIGsiAyQAIAMgADYCGCADIAE2AhQgAyACNgIQIAMgAygCEBD6ASIANgIMAkAgAEUEQCADQQA2AhwMAQsgAygCDCADKAIYNgIAIAMoAgwgAygCFDYCBCADKAIUQRBxBEAgAygCDCIAIAAoAhRBAnI2AhQgAygCDCIAIAAoAhhBAnI2AhgLIAMgAygCDDYCHAsgAygCHCEAIANBIGokACAAC9UBAQF/IwBBIGsiBCQAIAQgADYCGCAEIAE3AxAgBCACNgIMIAQgAzYCCAJAAkAgBCkDEEL///////////8AVwRAIAQpAxBCgICAgICAgICAf1kNAQsgBCgCCEEEQT0QFSAEQX82AhwMAQsCfyAEKQMQIQEgBCgCDCEAIAQoAhgiAigCTEF/TARAIAIgASAAEJYBDAELIAIgASAAEJYBC0EASARAIAQoAghBBEG0nAEoAgAQFSAEQX82AhwMAQsgBEEANgIcCyAEKAIcIQAgBEEgaiQAIAALJwACf0EAQQAgABAFIgAgAEEbRhsiAEUNABpBtJwBIAA2AgBBAAsaC14BAX8jAEEQayIDJAAgAyABQcCAgAJxBH8gAyACQQRqNgIMIAIoAgAFQQALNgIAIAAgAUGAgAJyIAMQESIAQYFgTwRAQbScAUEAIABrNgIAQX8hAAsgA0EQaiQAIAALVQEBfyMAQRBrIgEkACABIAA2AgwCQAJAIAEoAgwoAiRBAUYNACABKAIMKAIkQQJGDQAMAQsgASgCDEEAQgBBChAiGiABKAIMQQA2AiQLIAFBEGokAAszAQF/An8gABAGIgFBYUYEQCAAEBIhAQsgAUGBYE8LBH9BtJwBQQAgAWs2AgBBfwUgAQsLaQECfwJAIAAoAhQgACgCHE0NACAAQQBBACAAKAIkEQEAGiAAKAIUDQBBfw8LIAAoAgQiASAAKAIIIgJJBEAgACABIAJrrEEBIAAoAigREAAaCyAAQQA2AhwgAEIANwMQIABCADcCBEEAC6YBAQF/IwBBEGsiAiQAIAIgADYCCCACIAE2AgQCQCACKAIILQAoQQFxBEAgAkF/NgIMDAELIAIoAggoAgAEQCACKAIIKAIAIAIoAgQQbUEASARAIAIoAghBDGogAigCCCgCABAYIAJBfzYCDAwCCwsgAigCCCACQQRqQgRBExAiQgBTBEAgAkF/NgIMDAELIAJBADYCDAsgAigCDCEAIAJBEGokACAAC0gCAX8BfiMAQRBrIgMkACADIAA2AgwgAyABNgIIIAMgAjYCBCADKAIMIAMoAgggAygCBCADKAIMQQhqEFUhBCADQRBqJAAgBAskAQF/IwBBEGsiAyQAIAMgAjYCDCAAIAEgAhCmAiADQRBqJAALpxECD38BfiMAQdAAayIFJAAgBSABNgJMIAVBN2ohEyAFQThqIRFBACEBAkADQAJAIA5BAEgNACABQf////8HIA5rSgRAQbScAUE9NgIAQX8hDgwBCyABIA5qIQ4LIAUoAkwiCiEBAkACQAJAIAotAAAiBgRAA0ACQAJAIAZB/wFxIgZFBEAgASEGDAELIAZBJUcNASABIQYDQCABLQABQSVHDQEgBSABQQJqIgg2AkwgBkEBaiEGIAEtAAIhCSAIIQEgCUElRg0ACwsgBiAKayEBIAAEQCAAIAogARAjCyABDQYgBSgCTCEBIAUCfwJAIAUoAkwsAAFBUGpBCk8NACABLQACQSRHDQAgASwAAUFQaiEQQQEhEiABQQNqDAELQX8hECABQQFqCyIBNgJMQQAhDwJAIAEsAAAiC0FgaiIIQR9LBEAgASEGDAELIAEhBkEBIAh0IglBidEEcUUNAANAIAUgAUEBaiIGNgJMIAkgD3IhDyABLAABIgtBYGoiCEEgTw0BIAYhAUEBIAh0IglBidEEcQ0ACwsCQCALQSpGBEAgBQJ/AkAgBiwAAUFQakEKTw0AIAUoAkwiAS0AAkEkRw0AIAEsAAFBAnQgBGpBwH5qQQo2AgAgASwAAUEDdCADakGAfWooAgAhDEEBIRIgAUEDagwBCyASDQZBACESQQAhDCAABEAgAiACKAIAIgFBBGo2AgAgASgCACEMCyAFKAJMQQFqCyIBNgJMIAxBf0oNAUEAIAxrIQwgD0GAwAByIQ8MAQsgBUHMAGoQowEiDEEASA0EIAUoAkwhAQtBfyEHAkAgAS0AAEEuRw0AIAEtAAFBKkYEQAJAIAEsAAJBUGpBCk8NACAFKAJMIgEtAANBJEcNACABLAACQQJ0IARqQcB+akEKNgIAIAEsAAJBA3QgA2pBgH1qKAIAIQcgBSABQQRqIgE2AkwMAgsgEg0FIAAEfyACIAIoAgAiAUEEajYCACABKAIABUEACyEHIAUgBSgCTEECaiIBNgJMDAELIAUgAUEBajYCTCAFQcwAahCjASEHIAUoAkwhAQtBACEGA0AgBiEJQX8hDSABLAAAQb9/akE5Sw0IIAUgAUEBaiILNgJMIAEsAAAhBiALIQEgBiAJQTpsakHvggFqLQAAIgZBf2pBCEkNAAsCQAJAIAZBE0cEQCAGRQ0KIBBBAE4EQCAEIBBBAnRqIAY2AgAgBSADIBBBA3RqKQMANwNADAILIABFDQggBUFAayAGIAIQogEgBSgCTCELDAILIBBBf0oNCQtBACEBIABFDQcLIA9B//97cSIIIA8gD0GAwABxGyEGQQAhDUGXgwEhECARIQ8CQAJAAkACfwJAAkACQAJAAn8CQAJAAkACQAJAAkACQCALQX9qLAAAIgFBX3EgASABQQ9xQQNGGyABIAkbIgFBqH9qDiEEFBQUFBQUFBQOFA8GDg4OFAYUFBQUAgUDFBQJFAEUFAQACwJAIAFBv39qDgcOFAsUDg4OAAsgAUHTAEYNCQwTCyAFKQNAIRRBl4MBDAULQQAhAQJAAkACQAJAAkACQAJAIAlB/wFxDggAAQIDBBoFBhoLIAUoAkAgDjYCAAwZCyAFKAJAIA42AgAMGAsgBSgCQCAOrDcDAAwXCyAFKAJAIA47AQAMFgsgBSgCQCAOOgAADBULIAUoAkAgDjYCAAwUCyAFKAJAIA6sNwMADBMLIAdBCCAHQQhLGyEHIAZBCHIhBkH4ACEBCyAFKQNAIBEgAUEgcRCqAiEKIAZBCHFFDQMgBSkDQFANAyABQQR2QZeDAWohEEECIQ0MAwsgBSkDQCAREKkCIQogBkEIcUUNAiAHIBEgCmsiAUEBaiAHIAFKGyEHDAILIAUpA0AiFEJ/VwRAIAVCACAUfSIUNwNAQQEhDUGXgwEMAQsgBkGAEHEEQEEBIQ1BmIMBDAELQZmDAUGXgwEgBkEBcSINGwshECAUIBEQQyEKCyAGQf//e3EgBiAHQX9KGyEGIAUpA0AhFAJAIAcNACAUUEUNAEEAIQcgESEKDAwLIAcgFFAgESAKa2oiASAHIAFKGyEHDAsLIAUoAkAiAUGhgwEgARsiCkEAIAcQpgEiASAHIApqIAEbIQ8gCCEGIAEgCmsgByABGyEHDAoLIAcEQCAFKAJADAILQQAhASAAQSAgDEEAIAYQJwwCCyAFQQA2AgwgBSAFKQNAPgIIIAUgBUEIajYCQEF/IQcgBUEIagshCUEAIQECQANAIAkoAgAiCEUNAQJAIAVBBGogCBClASIKQQBIIggNACAKIAcgAWtLDQAgCUEEaiEJIAcgASAKaiIBSw0BDAILC0F/IQ0gCA0LCyAAQSAgDCABIAYQJyABRQRAQQAhAQwBC0EAIQsgBSgCQCEJA0AgCSgCACIIRQ0BIAVBBGogCBClASIIIAtqIgsgAUoNASAAIAVBBGogCBAjIAlBBGohCSALIAFJDQALCyAAQSAgDCABIAZBgMAAcxAnIAwgASAMIAFKGyEBDAgLIAAgBSsDQCAMIAcgBiABQRURHAAhAQwHCyAFIAUpA0A8ADdBASEHIBMhCiAIIQYMBAsgBSABQQFqIgg2AkwgAS0AASEGIAghAQwAAAsACyAOIQ0gAA0EIBJFDQJBASEBA0AgBCABQQJ0aigCACIABEAgAyABQQN0aiAAIAIQogFBASENIAFBAWoiAUEKRw0BDAYLC0EBIQ0gAUEKTw0EA0AgBCABQQJ0aigCAA0BIAFBAWoiAUEKRw0ACwwEC0F/IQ0MAwsgAEEgIA0gDyAKayIJIAcgByAJSBsiCGoiCyAMIAwgC0gbIgEgCyAGECcgACAQIA0QIyAAQTAgASALIAZBgIAEcxAnIABBMCAIIAlBABAnIAAgCiAJECMgAEEgIAEgCyAGQYDAAHMQJwwBCwtBACENCyAFQdAAaiQAIA0LtwEBBH8CQCACKAIQIgMEfyADBSACEK0CDQEgAigCEAsgAigCFCIFayABSQRAIAIgACABIAIoAiQRAQAPCwJAIAIsAEtBAEgNACABIQQDQCAEIgNFDQEgACADQX9qIgRqLQAAQQpHDQALIAIgACADIAIoAiQRAQAiBCADSQ0BIAAgA2ohACABIANrIQEgAigCFCEFIAMhBgsgBSAAIAEQGhogAiACKAIUIAFqNgIUIAEgBmohBAsgBAvSEQEBfyMAQbABayIGJAAgBiAANgKoASAGIAE2AqQBIAYgAjYCoAEgBiADNgKcASAGIAQ2ApgBIAYgBTYClAEgBkEANgKQAQNAIAYoApABQQ9LRQRAIAZBIGogBigCkAFBAXRqQQA7AQAgBiAGKAKQAUEBajYCkAEMAQsLIAZBADYCjAEDQCAGKAKMASAGKAKgAU9FBEAgBkEgaiAGKAKkASAGKAKMAUEBdGovAQBBAXRqIgAgAC8BAEEBajsBACAGIAYoAowBQQFqNgKMAQwBCwsgBiAGKAKYASgCADYCgAEgBkEPNgKEAQNAAkAgBigChAFBAUkNACAGQSBqIAYoAoQBQQF0ai8BAA0AIAYgBigChAFBf2o2AoQBDAELCyAGKAKAASAGKAKEAUsEQCAGIAYoAoQBNgKAAQsCQCAGKAKEAUUEQCAGQcAAOgBYIAZBAToAWSAGQQA7AVogBigCnAEiASgCACEAIAEgAEEEajYCACAAIAZB2ABqIgEoAQA2AQAgBigCnAEiAigCACEAIAIgAEEEajYCACAAIAEoAQA2AQAgBigCmAFBATYCACAGQQA2AqwBDAELIAZBATYCiAEDQAJAIAYoAogBIAYoAoQBTw0AIAZBIGogBigCiAFBAXRqLwEADQAgBiAGKAKIAUEBajYCiAEMAQsLIAYoAoABIAYoAogBSQRAIAYgBigCiAE2AoABCyAGQQE2AnQgBkEBNgKQAQNAIAYoApABQQ9NBEAgBiAGKAJ0QQF0NgJ0IAYgBigCdCAGQSBqIAYoApABQQF0ai8BAGs2AnQgBigCdEEASARAIAZBfzYCrAEMAwUgBiAGKAKQAUEBajYCkAEMAgsACwsCQCAGKAJ0QQBMDQAgBigCqAEEQCAGKAKEAUEBRg0BCyAGQX82AqwBDAELIAZBADsBAiAGQQE2ApABA0AgBigCkAFBD09FBEAgBigCkAFBAWpBAXQgBmogBigCkAFBAXQgBmovAQAgBkEgaiAGKAKQAUEBdGovAQBqOwEAIAYgBigCkAFBAWo2ApABDAELCyAGQQA2AowBA0AgBigCjAEgBigCoAFJBEAgBigCpAEgBigCjAFBAXRqLwEABEAgBigClAEhASAGKAKkASAGKAKMASICQQF0ai8BAEEBdCAGaiIDLwEAIQAgAyAAQQFqOwEAIABB//8DcUEBdCABaiACOwEACyAGIAYoAowBQQFqNgKMAQwBCwsCQAJAAkACQCAGKAKoAQ4CAAECCyAGIAYoApQBIgA2AkwgBiAANgJQIAZBFDYCSAwCCyAGQbDrADYCUCAGQfDrADYCTCAGQYECNgJIDAELIAZBsOwANgJQIAZB8OwANgJMIAZBADYCSAsgBkEANgJsIAZBADYCjAEgBiAGKAKIATYCkAEgBiAGKAKcASgCADYCVCAGIAYoAoABNgJ8IAZBADYCeCAGQX82AmAgBkEBIAYoAoABdDYCcCAGIAYoAnBBAWs2AlwCQAJAIAYoAqgBQQFGBEAgBigCcEHUBksNAQsgBigCqAFBAkcNASAGKAJwQdAETQ0BCyAGQQE2AqwBDAELA0AgBiAGKAKQASAGKAJ4azoAWQJAIAYoApQBIAYoAowBQQF0ai8BAEEBaiAGKAJISQRAIAZBADoAWCAGIAYoApQBIAYoAowBQQF0ai8BADsBWgwBCwJAIAYoApQBIAYoAowBQQF0ai8BACAGKAJITwRAIAYgBigCTCAGKAKUASAGKAKMAUEBdGovAQAgBigCSGtBAXRqLwEAOgBYIAYgBigCUCAGKAKUASAGKAKMAUEBdGovAQAgBigCSGtBAXRqLwEAOwFaDAELIAZB4AA6AFggBkEAOwFaCwsgBkEBIAYoApABIAYoAnhrdDYCaCAGQQEgBigCfHQ2AmQgBiAGKAJkNgKIAQNAIAYgBigCZCAGKAJoazYCZCAGKAJUIAYoAmQgBigCbCAGKAJ4dmpBAnRqIAZB2ABqKAEANgEAIAYoAmQNAAsgBkEBIAYoApABQQFrdDYCaANAIAYoAmwgBigCaHEEQCAGIAYoAmhBAXY2AmgMAQsLAkAgBigCaARAIAYgBigCbCAGKAJoQQFrcTYCbCAGIAYoAmggBigCbGo2AmwMAQsgBkEANgJsCyAGIAYoAowBQQFqNgKMASAGQSBqIAYoApABQQF0aiIBLwEAQX9qIQAgASAAOwEAAkAgAEH//wNxRQRAIAYoApABIAYoAoQBRg0BIAYgBigCpAEgBigClAEgBigCjAFBAXRqLwEAQQF0ai8BADYCkAELAkAgBigCkAEgBigCgAFNDQAgBigCYCAGKAJsIAYoAlxxRg0AIAYoAnhFBEAgBiAGKAKAATYCeAsgBiAGKAJUIAYoAogBQQJ0ajYCVCAGIAYoApABIAYoAnhrNgJ8IAZBASAGKAJ8dDYCdANAAkAgBigCfCAGKAJ4aiAGKAKEAU8NACAGIAYoAnQgBkEgaiAGKAJ8IAYoAnhqQQF0ai8BAGs2AnQgBigCdEEATA0AIAYgBigCfEEBajYCfCAGIAYoAnRBAXQ2AnQMAQsLIAYgBigCcEEBIAYoAnx0ajYCcAJAAkAgBigCqAFBAUYEQCAGKAJwQdQGSw0BCyAGKAKoAUECRw0BIAYoAnBB0ARNDQELIAZBATYCrAEMBAsgBiAGKAJsIAYoAlxxNgJgIAYoApwBKAIAIAYoAmBBAnRqIAYoAnw6AAAgBigCnAEoAgAgBigCYEECdGogBigCgAE6AAEgBigCnAEoAgAgBigCYEECdGogBigCVCAGKAKcASgCAGtBAnU7AQILDAELCyAGKAJsBEAgBkHAADoAWCAGIAYoApABIAYoAnhrOgBZIAZBADsBWiAGKAJUIAYoAmxBAnRqIAZB2ABqKAEANgEACyAGKAKcASIAIAAoAgAgBigCcEECdGo2AgAgBigCmAEgBigCgAE2AgAgBkEANgKsAQsgBigCrAEhACAGQbABaiQAIAALsQIBAX8jAEEgayIDJAAgAyAANgIYIAMgATYCFCADIAI2AhAgAyADKAIYKAIENgIMIAMoAgwgAygCEEsEQCADIAMoAhA2AgwLAkAgAygCDEUEQCADQQA2AhwMAQsgAygCGCIAIAAoAgQgAygCDGs2AgQgAygCFCADKAIYKAIAIAMoAgwQGhoCQCADKAIYKAIcKAIYQQFGBEAgAygCGCgCMCADKAIUIAMoAgwQPiEAIAMoAhggADYCMAwBCyADKAIYKAIcKAIYQQJGBEAgAygCGCgCMCADKAIUIAMoAgwQGyEAIAMoAhggADYCMAsLIAMoAhgiACADKAIMIAAoAgBqNgIAIAMoAhgiACADKAIMIAAoAghqNgIIIAMgAygCDDYCHAsgAygCHCEAIANBIGokACAAC+0BAQF/IwBBEGsiASAANgIIAkACQAJAIAEoAghFDQAgASgCCCgCIEUNACABKAIIKAIkDQELIAFBATYCDAwBCyABIAEoAggoAhw2AgQCQAJAIAEoAgRFDQAgASgCBCgCACABKAIIRw0AIAEoAgQoAgRBKkYNASABKAIEKAIEQTlGDQEgASgCBCgCBEHFAEYNASABKAIEKAIEQckARg0BIAEoAgQoAgRB2wBGDQEgASgCBCgCBEHnAEYNASABKAIEKAIEQfEARg0BIAEoAgQoAgRBmgVGDQELIAFBATYCDAwBCyABQQA2AgwLIAEoAgwL0gQBAX8jAEEgayIDIAA2AhwgAyABNgIYIAMgAjYCFCADIAMoAhxB3BZqIAMoAhRBAnRqKAIANgIQIAMgAygCFEEBdDYCDANAAkAgAygCDCADKAIcKALQKEoNAAJAIAMoAgwgAygCHCgC0ChODQAgAygCGCADKAIcIAMoAgxBAnRqQeAWaigCAEECdGovAQAgAygCGCADKAIcQdwWaiADKAIMQQJ0aigCAEECdGovAQBOBEAgAygCGCADKAIcIAMoAgxBAnRqQeAWaigCAEECdGovAQAgAygCGCADKAIcQdwWaiADKAIMQQJ0aigCAEECdGovAQBHDQEgAygCHCADKAIMQQJ0akHgFmooAgAgAygCHEHYKGpqLQAAIAMoAhxB3BZqIAMoAgxBAnRqKAIAIAMoAhxB2Chqai0AAEoNAQsgAyADKAIMQQFqNgIMCyADKAIYIAMoAhBBAnRqLwEAIAMoAhggAygCHEHcFmogAygCDEECdGooAgBBAnRqLwEASA0AAkAgAygCGCADKAIQQQJ0ai8BACADKAIYIAMoAhxB3BZqIAMoAgxBAnRqKAIAQQJ0ai8BAEcNACADKAIQIAMoAhxB2Chqai0AACADKAIcQdwWaiADKAIMQQJ0aigCACADKAIcQdgoamotAABKDQAMAQsgAygCHEHcFmogAygCFEECdGogAygCHEHcFmogAygCDEECdGooAgA2AgAgAyADKAIMNgIUIAMgAygCDEEBdDYCDAwBCwsgAygCHEHcFmogAygCFEECdGogAygCEDYCAAvnCAEDfyMAQTBrIgIkACACIAA2AiwgAiABNgIoIAIgAigCKCgCADYCJCACIAIoAigoAggoAgA2AiAgAiACKAIoKAIIKAIMNgIcIAJBfzYCECACKAIsQQA2AtAoIAIoAixBvQQ2AtQoIAJBADYCGANAIAIoAhggAigCHE5FBEACQCACKAIkIAIoAhhBAnRqLwEABEAgAiACKAIYIgE2AhAgAigCLEHcFmohAyACKAIsIgQoAtAoQQFqIQAgBCAANgLQKCAAQQJ0IANqIAE2AgAgAigCGCACKAIsQdgoampBADoAAAwBCyACKAIkIAIoAhhBAnRqQQA7AQILIAIgAigCGEEBajYCGAwBCwsDQCACKAIsKALQKEECSARAAkAgAigCEEECSARAIAIgAigCEEEBaiIANgIQDAELQQAhAAsgAigCLEHcFmohAyACKAIsIgQoAtAoQQFqIQEgBCABNgLQKCABQQJ0IANqIAA2AgAgAiAANgIMIAIoAiQgAigCDEECdGpBATsBACACKAIMIAIoAixB2ChqakEAOgAAIAIoAiwiACAAKAKoLUF/ajYCqC0gAigCIARAIAIoAiwiACAAKAKsLSACKAIgIAIoAgxBAnRqLwECazYCrC0LDAELCyACKAIoIAIoAhA2AgQgAiACKAIsKALQKEECbTYCGANAIAIoAhhBAUhFBEAgAigCLCACKAIkIAIoAhgQdSACIAIoAhhBf2o2AhgMAQsLIAIgAigCHDYCDANAIAIgAigCLCgC4BY2AhggAigCLEHcFmohASACKAIsIgMoAtAoIQAgAyAAQX9qNgLQKCACKAIsIABBAnQgAWooAgA2AuAWIAIoAiwgAigCJEEBEHUgAiACKAIsKALgFjYCFCACKAIYIQEgAigCLEHcFmohAyACKAIsIgQoAtQoQX9qIQAgBCAANgLUKCAAQQJ0IANqIAE2AgAgAigCFCEBIAIoAixB3BZqIQMgAigCLCIEKALUKEF/aiEAIAQgADYC1CggAEECdCADaiABNgIAIAIoAiQgAigCDEECdGogAigCJCACKAIYQQJ0ai8BACACKAIkIAIoAhRBAnRqLwEAajsBACACKAIMIAIoAixB2ChqagJ/IAIoAhggAigCLEHYKGpqLQAAIAIoAhQgAigCLEHYKGpqLQAATgRAIAIoAhggAigCLEHYKGpqLQAADAELIAIoAhQgAigCLEHYKGpqLQAAC0EBajoAACACKAIkIAIoAhRBAnRqIAIoAgwiADsBAiACKAIkIAIoAhhBAnRqIAA7AQIgAiACKAIMIgBBAWo2AgwgAigCLCAANgLgFiACKAIsIAIoAiRBARB1IAIoAiwoAtAoQQJODQALIAIoAiwoAuAWIQEgAigCLEHcFmohAyACKAIsIgQoAtQoQX9qIQAgBCAANgLUKCAAQQJ0IANqIAE2AgAgAigCLCACKAIoEOQCIAIoAiQgAigCECACKAIsQbwWahDjAiACQTBqJAALTgEBfyMAQRBrIgIgADsBCiACIAE2AgQCQCACLwEKQQFGBEAgAigCBEEBRgRAIAJBADYCDAwCCyACQQQ2AgwMAQsgAkEANgIMCyACKAIMC80CAQF/IwBBMGsiBSQAIAUgADYCLCAFIAE2AiggBSACNgIkIAUgAzcDGCAFIAQ2AhQgBUIANwMIA0AgBSkDCCAFKQMYVARAIAUgBSgCJCAFKQMIp2otAAA6AAcgBSgCFEUEQCAFIAUoAiwoAhRBAnI7ARIgBSAFLwESIAUvARJBAXNsQQh2OwESIAUgBS0AByAFLwESQf8BcXM6AAcLIAUoAigEQCAFKAIoIAUpAwinaiAFLQAHOgAACyAFKAIsKAIMQX9zIAVBB2oiAEEBEBtBf3MhASAFKAIsIAE2AgwgBSgCLCAFKAIsKAIQIAUoAiwoAgxB/wFxakGFiKLAAGxBAWo2AhAgBSAFKAIsKAIQQRh2OgAHIAUoAiwoAhRBf3MgAEEBEBtBf3MhACAFKAIsIAA2AhQgBSAFKQMIQgF8NwMIDAELCyAFQTBqJAALbQEBfyMAQSBrIgQkACAEIAA2AhggBCABNgIUIAQgAjcDCCAEIAM2AgQCQCAEKAIYRQRAIARBADYCHAwBCyAEIAQoAhQgBCkDCCAEKAIEIAQoAhhBCGoQvwE2AhwLIAQoAhwhACAEQSBqJAAgAAunAwEBfyMAQSBrIgQkACAEIAA2AhggBCABNwMQIAQgAjYCDCAEIAM2AgggBCAEKAIYIAQpAxAgBCgCDEEAEEUiADYCAAJAIABFBEAgBEF/NgIcDAELIAQgBCgCGCAEKQMQIAQoAgwQwAEiADYCBCAARQRAIARBfzYCHAwBCwJAAkAgBCgCDEEIcQ0AIAQoAhgoAkAgBCkDEKdBBHRqKAIIRQ0AIAQoAhgoAkAgBCkDEKdBBHRqKAIIIAQoAggQOUEASARAIAQoAhhBCGpBD0EAEBUgBEF/NgIcDAMLDAELIAQoAggQPCAEKAIIIAQoAgAoAhg2AiwgBCgCCCAEKAIAKQMoNwMYIAQoAgggBCgCACgCFDYCKCAEKAIIIAQoAgApAyA3AyAgBCgCCCAEKAIAKAIQOwEwIAQoAgggBCgCAC8BUjsBMiAEKAIIQSBBACAEKAIALQAGQQFxG0HcAXKtNwMACyAEKAIIIAQpAxA3AxAgBCgCCCAEKAIENgIIIAQoAggiACAAKQMAQgOENwMAIARBADYCHAsgBCgCHCEAIARBIGokACAAC1kCAX8BfgJAAn9BACAARQ0AGiAArSABrX4iA6ciAiAAIAFyQYCABEkNABpBfyACIANCIIinGwsiAhAZIgBFDQAgAEF8ai0AAEEDcUUNACAAQQAgAhAzCyAAC3cBAX8jAEEQayIBIAA2AgggAUKFKjcDAAJAIAEoAghFBEAgAUEANgIMDAELA0AgASgCCC0AAARAIAEgASgCCC0AAK0gASkDAEIhfnxC/////w+DNwMAIAEgASgCCEEBajYCCAwBCwsgASABKQMAPgIMCyABKAIMC4cFAQF/IwBBMGsiBSQAIAUgADYCKCAFIAE2AiQgBSACNwMYIAUgAzYCFCAFIAQ2AhACQAJAAkAgBSgCKEUNACAFKAIkRQ0AIAUpAxhC////////////AFgNAQsgBSgCEEESQQAQFSAFQQA6AC8MAQsgBSgCKCgCAEUEQCAFKAIoQYACIAUoAhAQWkEBcUUEQCAFQQA6AC8MAgsLIAUgBSgCJBB8NgIMIAUgBSgCDCAFKAIoKAIAcDYCCCAFIAUoAigoAhAgBSgCCEECdGooAgA2AgQDQAJAIAUoAgRFDQACQCAFKAIEKAIcIAUoAgxHDQAgBSgCJCAFKAIEKAIAEFsNAAJAAkAgBSgCFEEIcQRAIAUoAgQpAwhCf1INAQsgBSgCBCkDEEJ/UQ0BCyAFKAIQQQpBABAVIAVBADoALwwECwwBCyAFIAUoAgQoAhg2AgQMAQsLIAUoAgRFBEAgBUEgEBkiADYCBCAARQRAIAUoAhBBDkEAEBUgBUEAOgAvDAILIAUoAgQgBSgCJDYCACAFKAIEIAUoAigoAhAgBSgCCEECdGooAgA2AhggBSgCKCgCECAFKAIIQQJ0aiAFKAIENgIAIAUoAgQgBSgCDDYCHCAFKAIEQn83AwggBSgCKCIAIAApAwhCAXw3AwgCQCAFKAIoIgApAwi6IAAoAgC4RAAAAAAAAOg/omRFDQAgBSgCKCgCAEGAgICAeE8NACAFKAIoIAUoAigoAgBBAXQgBSgCEBBaQQFxRQRAIAVBADoALwwDCwsLIAUoAhRBCHEEQCAFKAIEIAUpAxg3AwgLIAUoAgQgBSkDGDcDECAFQQE6AC8LIAUtAC9BAXEhACAFQTBqJAAgAAv0AwEBfyMAQdAAayIIJAAgCCAANgJIIAggATcDQCAIIAI3AzggCCADNgI0IAggBDoAMyAIIAU2AiwgCCAGNwMgIAggBzYCHAJAAkACQCAIKAJIRQ0AIAgpA0AgCCkDOHwgCCkDQFQNACAIKAIsDQEgCCkDIFANAQsgCCgCHEESQQAQFSAIQQA2AkwMAQsgCEGAARAZIgA2AhggAEUEQCAIKAIcQQ5BABAVIAhBADYCTAwBCyAIKAIYIAgpA0A3AwAgCCgCGCAIKQNAIAgpAzh8NwMIIAgoAhhBKGoQPCAIKAIYIAgtADM6AGAgCCgCGCAIKAIsNgIQIAgoAhggCCkDIDcDGCMAQRBrIgAgCCgCGEHkAGo2AgwgACgCDEEANgIAIAAoAgxBADYCBCAAKAIMQQA2AggjAEEQayIAIAgoAkg2AgwgACgCDCkDGEL/gQGDIQEgCEF/NgIIIAhBBzYCBCAIQQ42AgBBECAIEDcgAYQhASAIKAIYIAE3A3AgCCgCGCAIKAIYKQNwQsAAg0IAUkEARzoAeCAIKAI0BEAgCCgCGEEoaiAIKAI0IAgoAhwQkQFBAEgEQCAIKAIYEBYgCEEANgJMDAILCyAIIAgoAkhBASAIKAIYIAgoAhwQjgE2AkwLIAgoAkwhACAIQdAAaiQAIAALlgIBAX8jAEEwayIDJAAgAyAANgIkIAMgATcDGCADIAI2AhQCQCADKAIkKAJAIAMpAxinQQR0aigCAEUEQCADKAIUQRRBABAVIANCADcDKAwBCyADIAMoAiQoAkAgAykDGKdBBHRqKAIAKQNINwMIIAMoAiQoAgAgAykDCEEAEChBAEgEQCADKAIUIAMoAiQoAgAQGCADQgA3AygMAQsgAyADKAIkKAIAIAMoAhQQiwMiADYCBCAAQQBIBEAgA0IANwMoDAELIAMpAwggAygCBK18Qv///////////wBWBEAgAygCFEEEQRYQFSADQgA3AygMAQsgAyADKQMIIAMoAgStfDcDKAsgAykDKCEBIANBMGokACABC3cBAX8jAEEQayICIAA2AgggAiABNgIEAkACQAJAIAIoAggpAyhC/////w9aDQAgAigCCCkDIEL/////D1oNACACKAIEQYAEcUUNASACKAIIKQNIQv////8PVA0BCyACQQE6AA8MAQsgAkEAOgAPCyACLQAPQQFxC9kCAQF/IwBBIGsiAyQAIAMgADYCGCADIAE2AhQgAyACNgIQIAMgA0EMakIEECo2AggCQCADKAIIRQRAIANBfzYCHAwBCwNAIAMoAhQEQCADKAIUKAIEIAMoAhBxQYAGcQRAIAMoAghCABAtGiADKAIIIAMoAhQvAQgQICADKAIIIAMoAhQvAQoQIAJ/IwBBEGsiACADKAIINgIMIAAoAgwtAABBAXFFCwRAIAMoAhhBCGpBFEEAEBUgAygCCBAXIANBfzYCHAwECyADKAIYIANBDGpCBBA2QQBIBEAgAygCCBAXIANBfzYCHAwECyADKAIULwEKQQBKBEAgAygCGCADKAIUKAIMIAMoAhQvAQqtEDZBAEgEQCADKAIIEBcgA0F/NgIcDAULCwsgAyADKAIUKAIANgIUDAELCyADKAIIEBcgA0EANgIcCyADKAIcIQAgA0EgaiQAIAALaAEBfyMAQRBrIgIgADYCDCACIAE2AgggAkEAOwEGA0AgAigCDARAIAIoAgwoAgQgAigCCHFBgAZxBEAgAiACKAIMLwEKIAIvAQZBBGpqOwEGCyACIAIoAgwoAgA2AgwMAQsLIAIvAQYL8AEBAX8jAEEQayIBJAAgASAANgIMIAEgASgCDDYCCCABQQA2AgQDQCABKAIMBEACQAJAIAEoAgwvAQhB9cYBRg0AIAEoAgwvAQhB9eABRg0AIAEoAgwvAQhBgbICRg0AIAEoAgwvAQhBAUcNAQsgASABKAIMKAIANgIAIAEoAgggASgCDEYEQCABIAEoAgA2AggLIAEoAgxBADYCACABKAIMECQgASgCBARAIAEoAgQgASgCADYCAAsgASABKAIANgIMDAILIAEgASgCDDYCBCABIAEoAgwoAgA2AgwMAQsLIAEoAgghACABQRBqJAAgAAuzBAEBfyMAQUBqIgUkACAFIAA2AjggBSABOwE2IAUgAjYCMCAFIAM2AiwgBSAENgIoIAUgBSgCOCAFLwE2rRAqIgA2AiQCQCAARQRAIAUoAihBDkEAEBUgBUEAOgA/DAELIAVBADYCICAFQQA2AhgDQAJ/IwBBEGsiACAFKAIkNgIMIAAoAgwtAABBAXELBH8gBSgCJBAwQgRaBUEAC0EBcQRAIAUgBSgCJBAeOwEWIAUgBSgCJBAeOwEUIAUgBSgCJCAFLwEUrRAfNgIQIAUoAhBFBEAgBSgCKEEVQQAQFSAFKAIkEBcgBSgCGBAkIAVBADoAPwwDCyAFIAUvARYgBS8BFCAFKAIQIAUoAjAQUCIANgIcIABFBEAgBSgCKEEOQQAQFSAFKAIkEBcgBSgCGBAkIAVBADoAPwwDCwJAIAUoAhgEQCAFKAIgIAUoAhw2AgAgBSAFKAIcNgIgDAELIAUgBSgCHCIANgIgIAUgADYCGAsMAQsLIAUoAiQQSEEBcUUEQCAFIAUoAiQQMD4CDCAFIAUoAiQgBSgCDK0QHzYCCAJAAkAgBSgCDEEETw0AIAUoAghFDQAgBSgCCEGy0wAgBSgCDBBTRQ0BCyAFKAIoQRVBABAVIAUoAiQQFyAFKAIYECQgBUEAOgA/DAILCyAFKAIkEBcCQCAFKAIsBEAgBSgCLCAFKAIYNgIADAELIAUoAhgQJAsgBUEBOgA/CyAFLQA/QQFxIQAgBUFAayQAIAAL7wIBAX8jAEEgayICJAAgAiAANgIYIAIgATYCFAJAIAIoAhhFBEAgAiACKAIUNgIcDAELIAIgAigCGDYCCANAIAIoAggoAgAEQCACIAIoAggoAgA2AggMAQsLA0AgAigCFARAIAIgAigCFCgCADYCECACQQA2AgQgAiACKAIYNgIMA0ACQCACKAIMRQ0AAkAgAigCDC8BCCACKAIULwEIRw0AIAIoAgwvAQogAigCFC8BCkcNACACKAIMLwEKBEAgAigCDCgCDCACKAIUKAIMIAIoAgwvAQoQUw0BCyACKAIMIgAgACgCBCACKAIUKAIEQYAGcXI2AgQgAkEBNgIEDAELIAIgAigCDCgCADYCDAwBCwsgAigCFEEANgIAAkAgAigCBARAIAIoAhQQJAwBCyACKAIIIAIoAhQiADYCACACIAA2AggLIAIgAigCEDYCFAwBCwsgAiACKAIYNgIcCyACKAIcIQAgAkEgaiQAIAALXQEBfyMAQRBrIgIkACACIAA2AgggAiABNgIEAkAgAigCBEUEQCACQQA2AgwMAQsgAiACKAIIIAIoAgQoAgAgAigCBC8BBK0QNjYCDAsgAigCDCEAIAJBEGokACAAC48BAQF/IwBBEGsiAiQAIAIgADYCCCACIAE2AgQCQAJAIAIoAggEQCACKAIEDQELIAIgAigCCCACKAIERjYCDAwBCyACKAIILwEEIAIoAgQvAQRHBEAgAkEANgIMDAELIAIgAigCCCgCACACKAIEKAIAIAIoAggvAQQQU0U2AgwLIAIoAgwhACACQRBqJAAgAAtVAQF/IwBBEGsiASQAIAEgADYCDCABQQBBAEEAEBs2AgggASgCDARAIAEgASgCCCABKAIMKAIAIAEoAgwvAQQQGzYCCAsgASgCCCEAIAFBEGokACAAC6ABAQF/IwBBIGsiBSQAIAUgADYCGCAFIAE2AhQgBSACOwESIAUgAzoAESAFIAQ2AgwgBSAFKAIYIAUoAhQgBS8BEiAFLQARQQFxIAUoAgwQYCIANgIIAkAgAEUEQCAFQQA2AhwMAQsgBSAFKAIIIAUvARJBACAFKAIMEFE2AgQgBSgCCBAWIAUgBSgCBDYCHAsgBSgCHCEAIAVBIGokACAAC18BAX8jAEEQayICJAAgAiAANgIIIAIgAToAByACIAIoAghCARAfNgIAAkAgAigCAEUEQCACQX82AgwMAQsgAigCACACLQAHOgAAIAJBADYCDAsgAigCDBogAkEQaiQAC1QBAX8jAEEQayIBJAAgASAANgIIIAEgASgCCEIBEB82AgQCQCABKAIERQRAIAFBADoADwwBCyABIAEoAgQtAAA6AA8LIAEtAA8hACABQRBqJAAgAAs4AQF/IwBBEGsiASAANgIMIAEoAgxBADYCACABKAIMQQA2AgQgASgCDEEANgIIIAEoAgxBADoADAufAgEBfyMAQUBqIgUkACAFIAA3AzAgBSABNwMoIAUgAjYCJCAFIAM3AxggBSAENgIUIAUCfyAFKQMYQhBUBEAgBSgCFEESQQAQFUEADAELIAUoAiQLNgIEAkAgBSgCBEUEQCAFQn83AzgMAQsCQAJAAkACQAJAIAUoAgQoAggOAwIAAQMLIAUgBSkDMCAFKAIEKQMAfDcDCAwDCyAFIAUpAyggBSgCBCkDAHw3AwgMAgsgBSAFKAIEKQMANwMIDAELIAUoAhRBEkEAEBUgBUJ/NwM4DAELAkAgBSkDCEIAWQRAIAUpAwggBSkDKFgNAQsgBSgCFEESQQAQFSAFQn83AzgMAQsgBSAFKQMINwM4CyAFKQM4IQAgBUFAayQAIAAL6gECAX8BfiMAQSBrIgQkACAEIAA2AhggBCABNgIUIAQgAjYCECAEIAM2AgwgBCAEKAIMEI8BIgA2AggCQCAARQRAIARBADYCHAwBCyMAQRBrIgAgBCgCGDYCDCAAKAIMIgAgACgCMEEBajYCMCAEKAIIIAQoAhg2AgAgBCgCCCAEKAIUNgIEIAQoAgggBCgCEDYCCCAEKAIYIAQoAhBBAEIAQQ4gBCgCFBENACEFIAQoAgggBTcDGCAEKAIIKQMYQgBTBEAgBCgCCEI/NwMYCyAEIAQoAgg2AhwLIAQoAhwhACAEQSBqJAAgAAvqAQEBfyMAQRBrIgEkACABIAA2AgggAUE4EBkiADYCBAJAIABFBEAgASgCCEEOQQAQFSABQQA2AgwMAQsgASgCBEEANgIAIAEoAgRBADYCBCABKAIEQQA2AgggASgCBEEANgIgIAEoAgRBADYCJCABKAIEQQA6ACggASgCBEEANgIsIAEoAgRBATYCMCMAQRBrIgAgASgCBEEMajYCDCAAKAIMQQA2AgAgACgCDEEANgIEIAAoAgxBADYCCCABKAIEQQA6ADQgASgCBEEAOgA1IAEgASgCBDYCDAsgASgCDCEAIAFBEGokACAAC7ABAgF/AX4jAEEgayIDJAAgAyAANgIYIAMgATYCFCADIAI2AhAgAyADKAIQEI8BIgA2AgwCQCAARQRAIANBADYCHAwBCyADKAIMIAMoAhg2AgQgAygCDCADKAIUNgIIIAMoAhRBAEIAQQ4gAygCGBEPACEEIAMoAgwgBDcDGCADKAIMKQMYQgBTBEAgAygCDEI/NwMYCyADIAMoAgw2AhwLIAMoAhwhACADQSBqJAAgAAvDAgEBfyMAQRBrIgMgADYCDCADIAE2AgggAyACNgIEIAMoAggpAwBCAoNCAFIEQCADKAIMIAMoAggpAxA3AxALIAMoAggpAwBCBINCAFIEQCADKAIMIAMoAggpAxg3AxgLIAMoAggpAwBCCINCAFIEQCADKAIMIAMoAggpAyA3AyALIAMoAggpAwBCEINCAFIEQCADKAIMIAMoAggoAig2AigLIAMoAggpAwBCIINCAFIEQCADKAIMIAMoAggoAiw2AiwLIAMoAggpAwBCwACDQgBSBEAgAygCDCADKAIILwEwOwEwCyADKAIIKQMAQoABg0IAUgRAIAMoAgwgAygCCC8BMjsBMgsgAygCCCkDAEKAAoNCAFIEQCADKAIMIAMoAggoAjQ2AjQLIAMoAgwiACADKAIIKQMAIAApAwCENwMAQQALggUBAX8jAEHgAGsiAyQAIAMgADYCWCADIAE2AlQgAyACNgJQAkACQCADKAJUQQBOBEAgAygCWA0BCyADKAJQQRJBABAVIANBADYCXAwBCyADIAMoAlQ2AkwjAEEQayIAIAMoAlg2AgwgAyAAKAIMKQMYNwNAQeCbASkDAEJ/UQRAIANBfzYCFCADQQM2AhAgA0EHNgIMIANBBjYCCCADQQI2AgQgA0EBNgIAQeCbAUEAIAMQNzcDACADQX82AjQgA0EPNgIwIANBDTYCLCADQQw2AiggA0EKNgIkIANBCTYCIEHomwFBCCADQSBqEDc3AwALQeCbASkDACADKQNAQeCbASkDAINSBEAgAygCUEEcQQAQFSADQQA2AlwMAQtB6JsBKQMAIAMpA0BB6JsBKQMAg1IEQCADIAMoAkxBEHI2AkwLIAMoAkxBGHFBGEYEQCADKAJQQRlBABAVIANBADYCXAwBCyADIAMoAlggAygCUBD4ATYCPAJAAkACQCADKAI8QQFqDgIAAQILIANBADYCXAwCCyADKAJMQQFxRQRAIAMoAlBBCUEAEBUgA0EANgJcDAILIAMgAygCWCADKAJMIAMoAlAQZjYCXAwBCyADKAJMQQJxBEAgAygCUEEKQQAQFSADQQA2AlwMAQsgAygCWBBJQQBIBEAgAygCUCADKAJYEBggA0EANgJcDAELAkAgAygCTEEIcQRAIAMgAygCWCADKAJMIAMoAlAQZjYCOAwBCyADIAMoAlggAygCTCADKAJQEPcBNgI4CyADKAI4RQRAIAMoAlgQMhogA0EANgJcDAELIAMgAygCODYCXAsgAygCXCEAIANB4ABqJAAgAAuOAQEBfyMAQRBrIgIkACACIAA2AgwgAiABNgIIIAJBADYCBCACKAIIBEAjAEEQayIAIAIoAgg2AgwgAiAAKAIMKAIANgIEIAIoAggQpwFBAUYEQCMAQRBrIgAgAigCCDYCDEG0nAEgACgCDCgCBDYCAAsLIAIoAgwEQCACKAIMIAIoAgQ2AgALIAJBEGokAAuVAQEBfyMAQRBrIgEkACABIAA2AggCQAJ/IwBBEGsiACABKAIINgIMIAAoAgwpAxhCgIAQg1ALBEAgASgCCCgCAARAIAEgASgCCCgCABCUAUEBcToADwwCCyABQQE6AA8MAQsgASABKAIIQQBCAEESECI+AgQgASABKAIEQQBHOgAPCyABLQAPQQFxIQAgAUEQaiQAIAALfwEBfyMAQSBrIgMkACADIAA2AhggAyABNwMQIANBADYCDCADIAI2AggCQCADKQMQQv///////////wBWBEAgAygCCEEEQT0QFSADQX82AhwMAQsgAyADKAIYIAMpAxAgAygCDCADKAIIEGc2AhwLIAMoAhwhACADQSBqJAAgAAt9ACACQQFGBEAgASAAKAIIIAAoAgRrrH0hAQsCQCAAKAIUIAAoAhxLBEAgAEEAQQAgACgCJBEBABogACgCFEUNAQsgAEEANgIcIABCADcDECAAIAEgAiAAKAIoERAAQgBTDQAgAEIANwIEIAAgACgCAEFvcTYCAEEADwtBfwviAgECfyMAQSBrIgMkAAJ/AkACQEH0lwEgASwAABCYAUUEQEG0nAFBHDYCAAwBC0GYCRAZIgINAQtBAAwBCyACQQBBkAEQMyABQSsQmAFFBEAgAkEIQQQgAS0AAEHyAEYbNgIACwJAIAEtAABB4QBHBEAgAigCACEBDAELIABBA0EAEAQiAUGACHFFBEAgAyABQYAIcjYCECAAQQQgA0EQahAEGgsgAiACKAIAQYABciIBNgIACyACQf8BOgBLIAJBgAg2AjAgAiAANgI8IAIgAkGYAWo2AiwCQCABQQhxDQAgAyADQRhqNgIAIABBk6gBIAMQDg0AIAJBCjoASwsgAkEaNgIoIAJBGzYCJCACQRw2AiAgAkEdNgIMQdygASgCAEUEQCACQX82AkwLIAJBsKEBKAIANgI4QbChASgCACIABEAgACACNgI0C0GwoQEgAjYCACACCyEAIANBIGokACAACxoAIAAgARCFAiIAQQAgAC0AACABQf8BcUYbCxgAIAAoAkxBf0wEQCAAEJoBDwsgABCaAQtgAgJ/AX4gACgCKCEBQQEhAiAAQgAgAC0AAEGAAXEEf0ECQQEgACgCFCAAKAIcSxsFQQELIAEREAAiA0IAWQR+IAAoAhQgACgCHGusIAMgACgCCCAAKAIEa6x9fAUgAwsLdgEBfyAABEAgACgCTEF/TARAIAAQbA8LIAAQbA8LQbShASgCAARAQbShASgCABCbASEBC0GwoQEoAgAiAARAA0AgACgCTEEATgR/QQEFQQALGiAAKAIUIAAoAhxLBEAgABBsIAFyIQELIAAoAjgiAA0ACwsgAQsiACAAIAEQAiIAQYFgTwR/QbScAUEAIABrNgIAQX8FIAALC9YBAQF/IwBBIGsiBCQAIAQgADYCGCAEIAE3AxAgBCACNgIMIAQgAzYCCCAEIAQoAhggBCgCGCAEKQMQIAQoAgwgBCgCCBCpASIANgIAAkAgAEUEQCAEQQA2AhwMAQsgBCgCABBJQQBIBEAgBCgCGEEIaiAEKAIAEBggBCgCABAcIARBADYCHAwBCyAEIAQoAhgQlQIiADYCBCAARQRAIAQoAgAQHCAEQQA2AhwMAQsgBCgCBCAEKAIANgIUIAQgBCgCBDYCHAsgBCgCHCEAIARBIGokACAAC6YBAQF/IwBBIGsiBSQAIAUgADYCGCAFIAE3AxAgBSACNgIMIAUgAzYCCCAFIAQ2AgQgBSAFKAIYIAUpAxAgBSgCDEEAEEUiADYCAAJAIABFBEAgBUF/NgIcDAELIAUoAggEQCAFKAIIIAUoAgAvAQhBCHU6AAALIAUoAgQEQCAFKAIEIAUoAgAoAkQ2AgALIAVBADYCHAsgBSgCHCEAIAVBIGokACAAC6UEAQF/IwBBMGsiBSQAIAUgADYCKCAFIAE3AyAgBSACNgIcIAUgAzoAGyAFIAQ2AhQCQCAFKAIoIAUpAyBBAEEAEEVFBEAgBUF/NgIsDAELIAUoAigoAhhBAnEEQCAFKAIoQQhqQRlBABAVIAVBfzYCLAwBCyAFIAUoAigoAkAgBSkDIKdBBHRqNgIQIAUCfyAFKAIQKAIABEAgBSgCECgCAC8BCEEIdQwBC0EDCzoACyAFAn8gBSgCECgCAARAIAUoAhAoAgAoAkQMAQtBgIDYjXgLNgIEQQEhACAFIAUtABsgBS0AC0YEfyAFKAIUIAUoAgRHBUEBC0EBcTYCDAJAIAUoAgwEQCAFKAIQKAIERQRAIAUoAhAoAgAQRiEAIAUoAhAgADYCBCAARQRAIAUoAihBCGpBDkEAEBUgBUF/NgIsDAQLCyAFKAIQKAIEIAUoAhAoAgQvAQhB/wFxIAUtABtBCHRyOwEIIAUoAhAoAgQgBSgCFDYCRCAFKAIQKAIEIgAgACgCAEEQcjYCAAwBCyAFKAIQKAIEBEAgBSgCECgCBCIAIAAoAgBBb3E2AgACQCAFKAIQKAIEKAIARQRAIAUoAhAoAgQQOiAFKAIQQQA2AgQMAQsgBSgCECgCBCAFKAIQKAIELwEIQf8BcSAFLQALQQh0cjsBCCAFKAIQKAIEIAUoAgQ2AkQLCwsgBUEANgIsCyAFKAIsIQAgBUEwaiQAIAAL7QQCAX8BfiMAQUBqIgQkACAEIAA2AjQgBEJ/NwMoIAQgATYCJCAEIAI2AiAgBCADNgIcAkAgBCgCNCgCGEECcQRAIAQoAjRBCGpBGUEAEBUgBEJ/NwM4DAELIAQgBCgCNCkDMDcDECAEKQMoQn9RBEAgBEJ/NwMIIAQoAhxBgMAAcQRAIAQgBCgCNCAEKAIkIAQoAhxBABBVNwMICyAEKQMIQn9RBEAgBCAEKAI0EJ4CIgU3AwggBUIAUwRAIARCfzcDOAwDCwsgBCAEKQMINwMoCwJAIAQoAiRFDQAgBCgCNCAEKQMoIAQoAiQgBCgCHBCdAkUNACAEKAI0KQMwIAQpAxBSBEAgBCgCNCgCQCAEKQMop0EEdGoQYiAEKAI0IAQpAxA3AzALIARCfzcDOAwBCyAEKAI0KAJAIAQpAyinQQR0ahBjAkAgBCgCNCgCQCAEKQMop0EEdGooAgBFDQAgBCgCNCgCQCAEKQMop0EEdGooAgQEQCAEKAI0KAJAIAQpAyinQQR0aigCBCgCAEEBcQ0BCyAEKAI0KAJAIAQpAyinQQR0aigCBEUEQCAEKAI0KAJAIAQpAyinQQR0aigCABBGIQAgBCgCNCgCQCAEKQMop0EEdGogADYCBCAARQRAIAQoAjRBCGpBDkEAEBUgBEJ/NwM4DAMLCyAEKAI0KAJAIAQpAyinQQR0aigCBEF+NgIQIAQoAjQoAkAgBCkDKKdBBHRqKAIEIgAgACgCAEEBcjYCAAsgBCgCNCgCQCAEKQMop0EEdGogBCgCIDYCCCAEIAQpAyg3AzgLIAQpAzghBSAEQUBrJAAgBQuFAgEBfyMAQSBrIgIkACACIAA2AhggAiABNwMQAkAgAikDECACKAIYKQMwWgRAIAIoAhhBCGpBEkEAEBUgAkF/NgIcDAELIAIoAhgoAhhBAnEEQCACKAIYQQhqQRlBABAVIAJBfzYCHAwBCyACIAIoAhggAikDEEEAIAIoAhhBCGoQTyIANgIMIABFBEAgAkF/NgIcDAELIAIoAhgoAlAgAigCDCACKAIYQQhqEFlBAXFFBEAgAkF/NgIcDAELIAIoAhggAikDEBCgAgRAIAJBfzYCHAwBCyACKAIYKAJAIAIpAxCnQQR0akEBOgAMIAJBADYCHAsgAigCHCEAIAJBIGokACAAC5gCAAJAAkAgAUEUSw0AAkACQAJAAkACQAJAAkACQCABQXdqDgoAAQIJAwQFBgkHCAsgAiACKAIAIgFBBGo2AgAgACABKAIANgIADwsgAiACKAIAIgFBBGo2AgAgACABNAIANwMADwsgAiACKAIAIgFBBGo2AgAgACABNQIANwMADwsgAiACKAIAIgFBBGo2AgAgACABMgEANwMADwsgAiACKAIAIgFBBGo2AgAgACABMwEANwMADwsgAiACKAIAIgFBBGo2AgAgACABMAAANwMADwsgAiACKAIAIgFBBGo2AgAgACABMQAANwMADwsgACACQRYRBAALDwsgAiACKAIAQQdqQXhxIgFBCGo2AgAgACABKQMANwMAC0oBA38gACgCACwAAEFQakEKSQRAA0AgACgCACIBLAAAIQMgACABQQFqNgIAIAMgAkEKbGpBUGohAiABLAABQVBqQQpJDQALCyACC38CAX8BfiAAvSIDQjSIp0H/D3EiAkH/D0cEfCACRQRAIAEgAEQAAAAAAAAAAGEEf0EABSAARAAAAAAAAPBDoiABEKQBIQAgASgCAEFAags2AgAgAA8LIAEgAkGCeGo2AgAgA0L/////////h4B/g0KAgICAgICA8D+EvwUgAAsLEgAgAEUEQEEADwsgACABELQCC+UBAQJ/IAJBAEchAwJAAkACQCACRQ0AIABBA3FFDQAgAUH/AXEhBANAIAAtAAAgBEYNAiAAQQFqIQAgAkF/aiICQQBHIQMgAkUNASAAQQNxDQALCyADRQ0BCwJAIAAtAAAgAUH/AXFGDQAgAkEESQ0AIAFB/wFxQYGChAhsIQMDQCAAKAIAIANzIgRBf3MgBEH//ft3anFBgIGChHhxDQEgAEEEaiEAIAJBfGoiAkEDSw0ACwsgAkUNACABQf8BcSEBA0AgASAALQAARgRAIAAPCyAAQQFqIQAgAkF/aiICDQALC0EAC1oBAX8jAEEQayIBIAA2AggCQAJAIAEoAggoAgBBAE4EQCABKAIIKAIAQaAOKAIASA0BCyABQQA2AgwMAQsgASABKAIIKAIAQQJ0QbAOaigCADYCDAsgASgCDAuqAQEBfyMAQTBrIgIkACACIAA2AiggAiABNwMgIAJBADYCHAJAAkAgAigCKCgCJEEBRgRAIAIoAhxFDQEgAigCHEEBRg0BIAIoAhxBAkYNAQsgAigCKEEMakESQQAQFSACQX82AiwMAQsgAiACKQMgNwMIIAIgAigCHDYCECACQX9BACACKAIoIAJBCGpCEEEMECJCAFMbNgIsCyACKAIsIQAgAkEwaiQAIAALzQsBAX8jAEHAAWsiBSQAIAUgADYCuAEgBSABNgK0ASAFIAI3A6gBIAUgAzYCpAEgBUIANwOYASAFQgA3A5ABIAUgBDYCjAECQCAFKAK4AUUEQCAFQQA2ArwBDAELAkAgBSgCtAEEQCAFKQOoASAFKAK0ASkDMFQNAQsgBSgCuAFBCGpBEkEAEBUgBUEANgK8AQwBCwJAIAUoAqQBQQhxDQAgBSgCtAEoAkAgBSkDqAGnQQR0aigCCEUEQCAFKAK0ASgCQCAFKQOoAadBBHRqLQAMQQFxRQ0BCyAFKAK4AUEIakEPQQAQFSAFQQA2ArwBDAELIAUoArQBIAUpA6gBIAUoAqQBQQhyIAVByABqEHpBAEgEQCAFKAK4AUEIakEUQQAQFSAFQQA2ArwBDAELIAUoAqQBQSBxBEAgBSAFKAKkAUEEcjYCpAELAkAgBSkDmAFCAFgEQCAFKQOQAUIAWA0BCyAFKAKkAUEEcUUNACAFKAK4AUEIakESQQAQFSAFQQA2ArwBDAELAkAgBSkDmAFCAFgEQCAFKQOQAUIAWA0BCyAFKQOYASAFKQOQAXwgBSkDmAFaBEAgBSkDmAEgBSkDkAF8IAUpA2BYDQELIAUoArgBQQhqQRJBABAVIAVBADYCvAEMAQsgBSkDkAFQBEAgBSAFKQNgIAUpA5gBfTcDkAELIAUgBSkDkAEgBSkDYFQ6AEcgBSAFKAKkAUEgcQR/QQAFIAUvAXpBAEcLQQFxOgBFIAUgBSgCpAFBBHEEf0EABSAFLwF4QQBHC0EBcToARCAFAn8gBSgCpAFBBHEEQEEAIAUvAXgNARoLIAUtAEdBf3MLQQFxOgBGIAUtAEVBAXEEQCAFKAKMAUUEQCAFIAUoArgBKAIcNgKMAQsgBSgCjAFFBEAgBSgCuAFBCGpBGkEAEBUgBUEANgK8AQwCCwsgBSkDaFAEQCAFIAUoArgBQQBCAEEAEHk2ArwBDAELAkACQCAFLQBHQQFxRQ0AIAUtAEVBAXENACAFLQBEQQFxDQAgBSAFKQOQATcDICAFIAUpA5ABNwMoIAVBADsBOCAFIAUoAnA2AjAgBULcADcDCCAFIAUoArQBKAIAIAUpA5gBIAUpA5ABIAVBCGpBACAFKAK0ASAFKQOoASAFKAK4AUEIahB+IgA2AogBDAELIAUgBSgCtAEgBSkDqAEgBSgCpAEgBSgCuAFBCGoQRSIANgIEIABFBEAgBUEANgK8AQwCCyAFIAUoArQBKAIAQgAgBSkDaCAFQcgAaiAFKAIELwEMQQF1QQNxIAUoArQBIAUpA6gBIAUoArgBQQhqEH4iADYCiAELIABFBEAgBUEANgK8AQwBCyAFKAKIASAFKAK0ARCFA0EASARAIAUoAogBEBwgBUEANgK8AQwBCyAFLQBFQQFxBEAgBSAFLwF6QQAQdyIANgIAIABFBEAgBSgCuAFBCGpBGEEAEBUgBUEANgK8AQwCCyAFIAUoArgBIAUoAogBIAUvAXpBACAFKAKMASAFKAIAEQYANgKEASAFKAKIARAcIAUoAoQBRQRAIAVBADYCvAEMAgsgBSAFKAKEATYCiAELIAUtAERBAXEEQCAFIAUoArgBIAUoAogBIAUvAXgQqwE2AoQBIAUoAogBEBwgBSgChAFFBEAgBUEANgK8AQwCCyAFIAUoAoQBNgKIAQsgBS0ARkEBcQRAIAUgBSgCuAEgBSgCiAFBARCqATYChAEgBSgCiAEQHCAFKAKEAUUEQCAFQQA2ArwBDAILIAUgBSgChAE2AogBCwJAIAUtAEdBAXFFDQAgBS0ARUEBcUUEQCAFLQBEQQFxRQ0BCyAFIAUoArgBIAUoAogBIAUpA5gBIAUpA5ABEIcDNgKEASAFKAKIARAcIAUoAoQBRQRAIAVBADYCvAEMAgsgBSAFKAKEATYCiAELIAUgBSgCiAE2ArwBCyAFKAK8ASEAIAVBwAFqJAAgAAuEAgEBfyMAQSBrIgMkACADIAA2AhggAyABNgIUIAMgAjYCEAJAIAMoAhRFBEAgAygCGEEIakESQQAQFSADQQA2AhwMAQsgA0E4EBkiADYCDCAARQRAIAMoAhhBCGpBDkEAEBUgA0EANgIcDAELIwBBEGsiACADKAIMQQhqNgIMIAAoAgxBADYCACAAKAIMQQA2AgQgACgCDEEANgIIIAMoAgwgAygCEDYCACADKAIMQQA2AgQgAygCDEIANwMoQQBBAEEAEBshACADKAIMIAA2AjAgAygCDEIANwMYIAMgAygCGCADKAIUQRQgAygCDBBkNgIcCyADKAIcIQAgA0EgaiQAIAALQwEBfyMAQRBrIgMkACADIAA2AgwgAyABNgIIIAMgAjYCBCADKAIMIAMoAgggAygCBEEAQQAQrQEhACADQRBqJAAgAAtJAQF/IwBBEGsiASQAIAEgADYCDCABKAIMBEAgASgCDCgCrEAgASgCDCgCqEAoAgQRAwAgASgCDBA4IAEoAgwQFgsgAUEQaiQAC5cCAQF/IwBBMGsiBSQAIAUgADYCKCAFIAE2AiQgBSACNgIgIAUgAzoAHyAFIAQ2AhggBUEANgIMAkAgBSgCJEUEQCAFKAIoQQhqQRJBABAVIAVBADYCLAwBCyAFIAUoAiAgBS0AH0EBcRCuASIANgIMIABFBEAgBSgCKEEIakEQQQAQFSAFQQA2AiwMAQsgBSAFKAIgIAUtAB9BAXEgBSgCGCAFKAIMEMECIgA2AhQgAEUEQCAFKAIoQQhqQQ5BABAVIAVBADYCLAwBCyAFIAUoAiggBSgCJEETIAUoAhQQZCIANgIQIABFBEAgBSgCFBCsASAFQQA2AiwMAQsgBSAFKAIQNgIsCyAFKAIsIQAgBUEwaiQAIAALzAEBAX8jAEEgayICIAA2AhggAiABOgAXIAICfwJAIAIoAhhBf0cEQCACKAIYQX5HDQELQQgMAQsgAigCGAs7AQ4gAkEANgIQAkADQCACKAIQQdCYASgCAEkEQCACKAIQQQxsQdSYAWovAQAgAi8BDkYEQCACLQAXQQFxBEAgAiACKAIQQQxsQdSYAWooAgQ2AhwMBAsgAiACKAIQQQxsQdSYAWooAgg2AhwMAwUgAiACKAIQQQFqNgIQDAILAAsLIAJBADYCHAsgAigCHAvkAQEBfyMAQSBrIgMkACADIAA6ABsgAyABNgIUIAMgAjYCECADQcgAEBkiADYCDAJAIABFBEAgAygCEEEBQbScASgCABAVIANBADYCHAwBCyADKAIMIAMoAhA2AgAgAygCDCADLQAbQQFxOgAEIAMoAgwgAygCFDYCCAJAIAMoAgwoAghBAU4EQCADKAIMKAIIQQlMDQELIAMoAgxBCTYCCAsgAygCDEEAOgAMIAMoAgxBADYCMCADKAIMQQA2AjQgAygCDEEANgI4IAMgAygCDDYCHAsgAygCHCEAIANBIGokACAAC+MIAQF/IwBBQGoiAiAANgI4IAIgATYCNCACIAIoAjgoAnw2AjAgAiACKAI4KAI4IAIoAjgoAmxqNgIsIAIgAigCOCgCeDYCICACIAIoAjgoApABNgIcIAICfyACKAI4KAJsIAIoAjgoAixBhgJrSwRAIAIoAjgoAmwgAigCOCgCLEGGAmtrDAELQQALNgIYIAIgAigCOCgCQDYCFCACIAIoAjgoAjQ2AhAgAiACKAI4KAI4IAIoAjgoAmxqQYICajYCDCACIAIoAiwgAigCIEEBa2otAAA6AAsgAiACKAIsIAIoAiBqLQAAOgAKIAIoAjgoAnggAigCOCgCjAFPBEAgAiACKAIwQQJ2NgIwCyACKAIcIAIoAjgoAnRLBEAgAiACKAI4KAJ0NgIcCwNAAkAgAiACKAI4KAI4IAIoAjRqNgIoAkAgAigCKCACKAIgai0AACACLQAKRw0AIAIoAiggAigCIEEBa2otAAAgAi0AC0cNACACKAIoLQAAIAIoAiwtAABHDQAgAiACKAIoIgBBAWo2AiggAC0AASACKAIsLQABRwRADAELIAIgAigCLEECajYCLCACIAIoAihBAWo2AigDQCACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AigCf0EAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AihBACAALQABIAFHDQAaIAIgAigCLCIAQQFqNgIsIAAtAAEhASACIAIoAigiAEEBajYCKEEAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AihBACAALQABIAFHDQAaIAIgAigCLCIAQQFqNgIsIAAtAAEhASACIAIoAigiAEEBajYCKEEAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACKAIsIAIoAgxJC0EBcQ0ACyACQYICIAIoAgwgAigCLGtrNgIkIAIgAigCDEH+fWo2AiwgAigCJCACKAIgSgRAIAIoAjggAigCNDYCcCACIAIoAiQ2AiAgAigCJCACKAIcTg0CIAIgAigCLCACKAIgQQFrai0AADoACyACIAIoAiwgAigCIGotAAA6AAoLCyACIAIoAhQgAigCNCACKAIQcUEBdGovAQAiATYCNEEAIQAgASACKAIYSwR/IAIgAigCMEF/aiIANgIwIABBAEcFQQALQQFxDQELCwJAIAIoAiAgAigCOCgCdE0EQCACIAIoAiA2AjwMAQsgAiACKAI4KAJ0NgI8CyACKAI8C5gQAQF/IwBBMGsiAiQAIAIgADYCKCACIAE2AiQgAgJ/IAIoAigoAgxBBWsgAigCKCgCLEsEQCACKAIoKAIsDAELIAIoAigoAgxBBWsLNgIgIAJBADYCECACIAIoAigoAgAoAgQ2AgwDQAJAIAJB//8DNgIcIAIgAigCKCgCvC1BKmpBA3U2AhQgAigCKCgCACgCECACKAIUSQ0AIAIgAigCKCgCACgCECACKAIUazYCFCACIAIoAigoAmwgAigCKCgCXGs2AhggAigCHCACKAIYIAIoAigoAgAoAgRqSwRAIAIgAigCGCACKAIoKAIAKAIEajYCHAsgAigCHCACKAIUSwRAIAIgAigCFDYCHAsCQCACKAIcIAIoAiBPDQACQCACKAIcRQRAIAIoAiRBBEcNAQsgAigCJEUNACACKAIcIAIoAhggAigCKCgCACgCBGpGDQELDAELQQAhACACIAIoAiRBBEYEfyACKAIcIAIoAhggAigCKCgCACgCBGpGBUEAC0EBcUVFNgIQIAIoAihBAEEAIAIoAhAQVyACKAIoKAIIIAIoAigoAhRBBGtqIAIoAhw6AAAgAigCKCgCCCACKAIoKAIUQQNraiACKAIcQQh2OgAAIAIoAigoAgggAigCKCgCFEECa2ogAigCHEF/czoAACACKAIoKAIIIAIoAigoAhRBAWtqIAIoAhxBf3NBCHY6AAAgAigCKCgCABAdIAIoAhgEQCACKAIYIAIoAhxLBEAgAiACKAIcNgIYCyACKAIoKAIAKAIMIAIoAigoAjggAigCKCgCXGogAigCGBAaGiACKAIoKAIAIgAgAigCGCAAKAIMajYCDCACKAIoKAIAIgAgACgCECACKAIYazYCECACKAIoKAIAIgAgAigCGCAAKAIUajYCFCACKAIoIgAgAigCGCAAKAJcajYCXCACIAIoAhwgAigCGGs2AhwLIAIoAhwEQCACKAIoKAIAIAIoAigoAgAoAgwgAigCHBBzGiACKAIoKAIAIgAgAigCHCAAKAIMajYCDCACKAIoKAIAIgAgACgCECACKAIcazYCECACKAIoKAIAIgAgAigCHCAAKAIUajYCFAsgAigCEEUNAQsLIAIgAigCDCACKAIoKAIAKAIEazYCDCACKAIMBEACQCACKAIMIAIoAigoAixPBEAgAigCKEECNgKwLSACKAIoKAI4IAIoAigoAgAoAgAgAigCKCgCLGsgAigCKCgCLBAaGiACKAIoIAIoAigoAiw2AmwMAQsgAigCKCgCPCACKAIoKAJsayACKAIMTQRAIAIoAigiACAAKAJsIAIoAigoAixrNgJsIAIoAigoAjggAigCKCgCOCACKAIoKAIsaiACKAIoKAJsEBoaIAIoAigoArAtQQJJBEAgAigCKCIAIAAoArAtQQFqNgKwLQsLIAIoAigoAjggAigCKCgCbGogAigCKCgCACgCACACKAIMayACKAIMEBoaIAIoAigiACACKAIMIAAoAmxqNgJsCyACKAIoIAIoAigoAmw2AlwgAigCKCIBAn8gAigCDCACKAIoKAIsIAIoAigoArQta0sEQCACKAIoKAIsIAIoAigoArQtawwBCyACKAIMCyABKAK0LWo2ArQtCyACKAIoKALALSACKAIoKAJsSQRAIAIoAiggAigCKCgCbDYCwC0LAkAgAigCEARAIAJBAzYCLAwBCwJAIAIoAiRFDQAgAigCJEEERg0AIAIoAigoAgAoAgQNACACKAIoKAJsIAIoAigoAlxHDQAgAkEBNgIsDAELIAIgAigCKCgCPCACKAIoKAJsa0EBazYCFAJAIAIoAigoAgAoAgQgAigCFE0NACACKAIoKAJcIAIoAigoAixIDQAgAigCKCIAIAAoAlwgAigCKCgCLGs2AlwgAigCKCIAIAAoAmwgAigCKCgCLGs2AmwgAigCKCgCOCACKAIoKAI4IAIoAigoAixqIAIoAigoAmwQGhogAigCKCgCsC1BAkkEQCACKAIoIgAgACgCsC1BAWo2ArAtCyACIAIoAigoAiwgAigCFGo2AhQLIAIoAhQgAigCKCgCACgCBEsEQCACIAIoAigoAgAoAgQ2AhQLIAIoAhQEQCACKAIoKAIAIAIoAigoAjggAigCKCgCbGogAigCFBBzGiACKAIoIgAgAigCFCAAKAJsajYCbAsgAigCKCgCwC0gAigCKCgCbEkEQCACKAIoIAIoAigoAmw2AsAtCyACIAIoAigoArwtQSpqQQN1NgIUIAICf0H//wMgAigCKCgCDCACKAIUa0H//wNLDQAaIAIoAigoAgwgAigCFGsLNgIUIAICfyACKAIUIAIoAigoAixLBEAgAigCKCgCLAwBCyACKAIUCzYCICACIAIoAigoAmwgAigCKCgCXGs2AhgCQCACKAIYIAIoAiBJBEAgAigCGEUEQCACKAIkQQRHDQILIAIoAiRFDQEgAigCKCgCACgCBA0BIAIoAhggAigCFEsNAQsgAgJ/IAIoAhggAigCFEsEQCACKAIUDAELIAIoAhgLNgIcIAICf0EAIAIoAiRBBEcNABpBACACKAIoKAIAKAIEDQAaIAIoAhwgAigCGEYLQQFxRUU2AhAgAigCKCACKAIoKAI4IAIoAigoAlxqIAIoAhwgAigCEBBXIAIoAigiACACKAIcIAAoAlxqNgJcIAIoAigoAgAQHQsgAkECQQAgAigCEBs2AiwLIAIoAiwhACACQTBqJAAgAAuyAgEBfyMAQRBrIgEkACABIAA2AggCQCABKAIIEHQEQCABQX42AgwMAQsgASABKAIIKAIcKAIENgIEIAEoAggoAhwoAggEQCABKAIIKAIoIAEoAggoAhwoAgggASgCCCgCJBEEAAsgASgCCCgCHCgCRARAIAEoAggoAiggASgCCCgCHCgCRCABKAIIKAIkEQQACyABKAIIKAIcKAJABEAgASgCCCgCKCABKAIIKAIcKAJAIAEoAggoAiQRBAALIAEoAggoAhwoAjgEQCABKAIIKAIoIAEoAggoAhwoAjggASgCCCgCJBEEAAsgASgCCCgCKCABKAIIKAIcIAEoAggoAiQRBAAgASgCCEEANgIcIAFBfUEAIAEoAgRB8QBGGzYCDAsgASgCDCEAIAFBEGokACAAC+sXAQJ/IwBB8ABrIgMgADYCbCADIAE2AmggAyACNgJkIANBfzYCXCADIAMoAmgvAQI2AlQgA0EANgJQIANBBzYCTCADQQQ2AkggAygCVEUEQCADQYoBNgJMIANBAzYCSAsgA0EANgJgA0AgAygCYCADKAJkSkUEQCADIAMoAlQ2AlggAyADKAJoIAMoAmBBAWpBAnRqLwECNgJUIAMgAygCUEEBaiIANgJQAkACQCAAIAMoAkxODQAgAygCWCADKAJURw0ADAELAkAgAygCUCADKAJISARAA0AgAyADKAJsQfwUaiADKAJYQQJ0ai8BAjYCRAJAIAMoAmwoArwtQRAgAygCRGtKBEAgAyADKAJsQfwUaiADKAJYQQJ0ai8BADYCQCADKAJsIgAgAC8BuC0gAygCQEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh1IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAJAQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCREEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJsQfwUaiADKAJYQQJ0ai8BACADKAJsKAK8LXRyOwG4LSADKAJsIgAgAygCRCAAKAK8LWo2ArwtCyADIAMoAlBBf2oiADYCUCAADQALDAELAkAgAygCWARAIAMoAlggAygCXEcEQCADIAMoAmxB/BRqIAMoAlhBAnRqLwECNgI8AkAgAygCbCgCvC1BECADKAI8a0oEQCADIAMoAmxB/BRqIAMoAlhBAnRqLwEANgI4IAMoAmwiACAALwG4LSADKAI4Qf//A3EgAygCbCgCvC10cjsBuC0gAygCbC8BuC1B/wFxIQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbC8BuC1BCHUhASADKAJsKAIIIQIgAygCbCIEKAIUIQAgBCAAQQFqNgIUIAAgAmogAToAACADKAJsIAMoAjhB//8DcUEQIAMoAmwoArwta3U7AbgtIAMoAmwiACAAKAK8LSADKAI8QRBrajYCvC0MAQsgAygCbCIAIAAvAbgtIAMoAmxB/BRqIAMoAlhBAnRqLwEAIAMoAmwoArwtdHI7AbgtIAMoAmwiACADKAI8IAAoArwtajYCvC0LIAMgAygCUEF/ajYCUAsgAyADKAJsLwG+FTYCNAJAIAMoAmwoArwtQRAgAygCNGtKBEAgAyADKAJsLwG8FTYCMCADKAJsIgAgAC8BuC0gAygCMEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh1IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIwQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCNEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJsLwG8FSADKAJsKAK8LXRyOwG4LSADKAJsIgAgAygCNCAAKAK8LWo2ArwtCyADQQI2AiwCQCADKAJsKAK8LUEQIAMoAixrSgRAIAMgAygCUEEDazYCKCADKAJsIgAgAC8BuC0gAygCKEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh1IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIoQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCLEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJQQQNrQf//A3EgAygCbCgCvC10cjsBuC0gAygCbCIAIAMoAiwgACgCvC1qNgK8LQsMAQsCQCADKAJQQQpMBEAgAyADKAJsLwHCFTYCJAJAIAMoAmwoArwtQRAgAygCJGtKBEAgAyADKAJsLwHAFTYCICADKAJsIgAgAC8BuC0gAygCIEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh1IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIgQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCJEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJsLwHAFSADKAJsKAK8LXRyOwG4LSADKAJsIgAgAygCJCAAKAK8LWo2ArwtCyADQQM2AhwCQCADKAJsKAK8LUEQIAMoAhxrSgRAIAMgAygCUEEDazYCGCADKAJsIgAgAC8BuC0gAygCGEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh1IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIYQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCHEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJQQQNrQf//A3EgAygCbCgCvC10cjsBuC0gAygCbCIAIAMoAhwgACgCvC1qNgK8LQsMAQsgAyADKAJsLwHGFTYCFAJAIAMoAmwoArwtQRAgAygCFGtKBEAgAyADKAJsLwHEFTYCECADKAJsIgAgAC8BuC0gAygCEEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh1IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIQQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCFEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJsLwHEFSADKAJsKAK8LXRyOwG4LSADKAJsIgAgAygCFCAAKAK8LWo2ArwtCyADQQc2AgwCQCADKAJsKAK8LUEQIAMoAgxrSgRAIAMgAygCUEELazYCCCADKAJsIgAgAC8BuC0gAygCCEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh1IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIIQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCDEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJQQQtrQf//A3EgAygCbCgCvC10cjsBuC0gAygCbCIAIAMoAgwgACgCvC1qNgK8LQsLCwsgA0EANgJQIAMgAygCWDYCXAJAIAMoAlRFBEAgA0GKATYCTCADQQM2AkgMAQsCQCADKAJYIAMoAlRGBEAgA0EGNgJMIANBAzYCSAwBCyADQQc2AkwgA0EENgJICwsLIAMgAygCYEEBajYCYAwBCwsLkQQBAX8jAEEwayIDIAA2AiwgAyABNgIoIAMgAjYCJCADQX82AhwgAyADKAIoLwECNgIUIANBADYCECADQQc2AgwgA0EENgIIIAMoAhRFBEAgA0GKATYCDCADQQM2AggLIAMoAiggAygCJEEBakECdGpB//8DOwECIANBADYCIANAIAMoAiAgAygCJEpFBEAgAyADKAIUNgIYIAMgAygCKCADKAIgQQFqQQJ0ai8BAjYCFCADIAMoAhBBAWoiADYCEAJAAkAgACADKAIMTg0AIAMoAhggAygCFEcNAAwBCwJAIAMoAhAgAygCCEgEQCADKAIsQfwUaiADKAIYQQJ0aiIAIAMoAhAgAC8BAGo7AQAMAQsCQCADKAIYBEAgAygCGCADKAIcRwRAIAMoAiwgAygCGEECdGpB/BRqIgAgAC8BAEEBajsBAAsgAygCLCIAIABBvBVqLwEAQQFqOwG8FQwBCwJAIAMoAhBBCkwEQCADKAIsIgAgAEHAFWovAQBBAWo7AcAVDAELIAMoAiwiACAAQcQVai8BAEEBajsBxBULCwsgA0EANgIQIAMgAygCGDYCHAJAIAMoAhRFBEAgA0GKATYCDCADQQM2AggMAQsCQCADKAIYIAMoAhRGBEAgA0EGNgIMIANBAzYCCAwBCyADQQc2AgwgA0EENgIICwsLIAMgAygCIEEBajYCIAwBCwsLpxIBAn8jAEHQAGsiAyAANgJMIAMgATYCSCADIAI2AkQgA0EANgI4IAMoAkwoAqAtBEADQCADIAMoAkwoAqQtIAMoAjhBAXRqLwEANgJAIAMoAkwoApgtIQAgAyADKAI4IgFBAWo2AjggAyAAIAFqLQAANgI8AkAgAygCQEUEQCADIAMoAkggAygCPEECdGovAQI2AiwCQCADKAJMKAK8LUEQIAMoAixrSgRAIAMgAygCSCADKAI8QQJ0ai8BADYCKCADKAJMIgAgAC8BuC0gAygCKEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwvAbgtQf8BcSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwvAbgtQQh1IQEgAygCTCgCCCECIAMoAkwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCTCADKAIoQf//A3FBECADKAJMKAK8LWt1OwG4LSADKAJMIgAgACgCvC0gAygCLEEQa2o2ArwtDAELIAMoAkwiACAALwG4LSADKAJIIAMoAjxBAnRqLwEAIAMoAkwoArwtdHI7AbgtIAMoAkwiACADKAIsIAAoArwtajYCvC0LDAELIAMgAygCPC0AgFk2AjQgAyADKAJIIAMoAjRBgQJqQQJ0ai8BAjYCJAJAIAMoAkwoArwtQRAgAygCJGtKBEAgAyADKAJIIAMoAjRBgQJqQQJ0ai8BADYCICADKAJMIgAgAC8BuC0gAygCIEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwvAbgtQf8BcSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwvAbgtQQh1IQEgAygCTCgCCCECIAMoAkwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCTCADKAIgQf//A3FBECADKAJMKAK8LWt1OwG4LSADKAJMIgAgACgCvC0gAygCJEEQa2o2ArwtDAELIAMoAkwiACAALwG4LSADKAJIIAMoAjRBgQJqQQJ0ai8BACADKAJMKAK8LXRyOwG4LSADKAJMIgAgAygCJCAAKAK8LWo2ArwtCyADIAMoAjRBAnRBwOUAaigCADYCMCADKAIwBEAgAyADKAI8IAMoAjRBAnRBsOgAaigCAGs2AjwgAyADKAIwNgIcAkAgAygCTCgCvC1BECADKAIca0oEQCADIAMoAjw2AhggAygCTCIAIAAvAbgtIAMoAhhB//8DcSADKAJMKAK8LXRyOwG4LSADKAJMLwG4LUH/AXEhASADKAJMKAIIIQIgAygCTCIEKAIUIQAgBCAAQQFqNgIUIAAgAmogAToAACADKAJMLwG4LUEIdSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwgAygCGEH//wNxQRAgAygCTCgCvC1rdTsBuC0gAygCTCIAIAAoArwtIAMoAhxBEGtqNgK8LQwBCyADKAJMIgAgAC8BuC0gAygCPEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwiACADKAIcIAAoArwtajYCvC0LCyADIAMoAkBBf2o2AkAgAwJ/IAMoAkBBgAJJBEAgAygCQC0AgFUMAQsgAygCQEEHdkGAAmotAIBVCzYCNCADIAMoAkQgAygCNEECdGovAQI2AhQCQCADKAJMKAK8LUEQIAMoAhRrSgRAIAMgAygCRCADKAI0QQJ0ai8BADYCECADKAJMIgAgAC8BuC0gAygCEEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwvAbgtQf8BcSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwvAbgtQQh1IQEgAygCTCgCCCECIAMoAkwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCTCADKAIQQf//A3FBECADKAJMKAK8LWt1OwG4LSADKAJMIgAgACgCvC0gAygCFEEQa2o2ArwtDAELIAMoAkwiACAALwG4LSADKAJEIAMoAjRBAnRqLwEAIAMoAkwoArwtdHI7AbgtIAMoAkwiACADKAIUIAAoArwtajYCvC0LIAMgAygCNEECdEHA5gBqKAIANgIwIAMoAjAEQCADIAMoAkAgAygCNEECdEGw6QBqKAIAazYCQCADIAMoAjA2AgwCQCADKAJMKAK8LUEQIAMoAgxrSgRAIAMgAygCQDYCCCADKAJMIgAgAC8BuC0gAygCCEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwvAbgtQf8BcSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwvAbgtQQh1IQEgAygCTCgCCCECIAMoAkwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCTCADKAIIQf//A3FBECADKAJMKAK8LWt1OwG4LSADKAJMIgAgACgCvC0gAygCDEEQa2o2ArwtDAELIAMoAkwiACAALwG4LSADKAJAQf//A3EgAygCTCgCvC10cjsBuC0gAygCTCIAIAMoAgwgACgCvC1qNgK8LQsLCyADKAI4IAMoAkwoAqAtSQ0ACwsgAyADKAJILwGCCDYCBAJAIAMoAkwoArwtQRAgAygCBGtKBEAgAyADKAJILwGACDYCACADKAJMIgAgAC8BuC0gAygCAEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwvAbgtQf8BcSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwvAbgtQQh1IQEgAygCTCgCCCECIAMoAkwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCTCADKAIAQf//A3FBECADKAJMKAK8LWt1OwG4LSADKAJMIgAgACgCvC0gAygCBEEQa2o2ArwtDAELIAMoAkwiACAALwG4LSADKAJILwGACCADKAJMKAK8LXRyOwG4LSADKAJMIgAgAygCBCAAKAK8LWo2ArwtCwuqDAEGfyAAIAFqIQUCQAJAIAAoAgQiAkEBcQ0AIAJBA3FFDQEgACgCACIDIAFqIQEgACADayIAQcycASgCAEcEQEHInAEoAgAhBCADQf8BTQRAIAAoAggiBCADQQN2IgNBA3RB4JwBakcaIAQgACgCDCICRgRAQbicAUG4nAEoAgBBfiADd3E2AgAMAwsgBCACNgIMIAIgBDYCCAwCCyAAKAIYIQYCQCAAIAAoAgwiAkcEQCAEIAAoAggiA00EQCADKAIMGgsgAyACNgIMIAIgAzYCCAwBCwJAIABBFGoiAygCACIEDQAgAEEQaiIDKAIAIgQNAEEAIQIMAQsDQCADIQcgBCICQRRqIgMoAgAiBA0AIAJBEGohAyACKAIQIgQNAAsgB0EANgIACyAGRQ0BAkAgACAAKAIcIgNBAnRB6J4BaiIEKAIARgRAIAQgAjYCACACDQFBvJwBQbycASgCAEF+IAN3cTYCAAwDCyAGQRBBFCAGKAIQIABGG2ogAjYCACACRQ0CCyACIAY2AhggACgCECIDBEAgAiADNgIQIAMgAjYCGAsgACgCFCIDRQ0BIAIgAzYCFCADIAI2AhgMAQsgBSgCBCICQQNxQQNHDQBBwJwBIAE2AgAgBSACQX5xNgIEIAAgAUEBcjYCBCAFIAE2AgAPCwJAIAUoAgQiAkECcUUEQCAFQdCcASgCAEYEQEHQnAEgADYCAEHEnAFBxJwBKAIAIAFqIgE2AgAgACABQQFyNgIEIABBzJwBKAIARw0DQcCcAUEANgIAQcycAUEANgIADwsgBUHMnAEoAgBGBEBBzJwBIAA2AgBBwJwBQcCcASgCACABaiIBNgIAIAAgAUEBcjYCBCAAIAFqIAE2AgAPC0HInAEoAgAhAyACQXhxIAFqIQECQCACQf8BTQRAIAUoAggiBCACQQN2IgJBA3RB4JwBakcaIAQgBSgCDCIDRgRAQbicAUG4nAEoAgBBfiACd3E2AgAMAgsgBCADNgIMIAMgBDYCCAwBCyAFKAIYIQYCQCAFIAUoAgwiAkcEQCADIAUoAggiA00EQCADKAIMGgsgAyACNgIMIAIgAzYCCAwBCwJAIAVBFGoiAygCACIEDQAgBUEQaiIDKAIAIgQNAEEAIQIMAQsDQCADIQcgBCICQRRqIgMoAgAiBA0AIAJBEGohAyACKAIQIgQNAAsgB0EANgIACyAGRQ0AAkAgBSAFKAIcIgNBAnRB6J4BaiIEKAIARgRAIAQgAjYCACACDQFBvJwBQbycASgCAEF+IAN3cTYCAAwCCyAGQRBBFCAGKAIQIAVGG2ogAjYCACACRQ0BCyACIAY2AhggBSgCECIDBEAgAiADNgIQIAMgAjYCGAsgBSgCFCIDRQ0AIAIgAzYCFCADIAI2AhgLIAAgAUEBcjYCBCAAIAFqIAE2AgAgAEHMnAEoAgBHDQFBwJwBIAE2AgAPCyAFIAJBfnE2AgQgACABQQFyNgIEIAAgAWogATYCAAsgAUH/AU0EQCABQQN2IgJBA3RB4JwBaiEBAn9BuJwBKAIAIgNBASACdCICcUUEQEG4nAEgAiADcjYCACABDAELIAEoAggLIQMgASAANgIIIAMgADYCDCAAIAE2AgwgACADNgIIDwsgAEIANwIQIAACf0EAIAFBCHYiAkUNABpBHyABQf///wdLDQAaIAIgAkGA/j9qQRB2QQhxIgJ0IgMgA0GA4B9qQRB2QQRxIgN0IgQgBEGAgA9qQRB2QQJxIgR0QQ92IAIgA3IgBHJrIgJBAXQgASACQRVqdkEBcXJBHGoLIgM2AhwgA0ECdEHongFqIQICQAJAQbycASgCACIEQQEgA3QiB3FFBEBBvJwBIAQgB3I2AgAgAiAANgIAIAAgAjYCGAwBCyABQQBBGSADQQF2ayADQR9GG3QhAyACKAIAIQIDQCACIgQoAgRBeHEgAUYNAiADQR12IQIgA0EBdCEDIAQgAkEEcWoiB0EQaigCACICDQALIAcgADYCECAAIAQ2AhgLIAAgADYCDCAAIAA2AggPCyAEKAIIIgEgADYCDCAEIAA2AgggAEEANgIYIAAgBDYCDCAAIAE2AggLC5cCAQR/IwBBEGsiASAANgIMAkAgASgCDCgCvC1BEEYEQCABKAIMLwG4LUH/AXEhAiABKAIMKAIIIQMgASgCDCIEKAIUIQAgBCAAQQFqNgIUIAAgA2ogAjoAACABKAIMLwG4LUEIdSECIAEoAgwoAgghAyABKAIMIgQoAhQhACAEIABBAWo2AhQgACADaiACOgAAIAEoAgxBADsBuC0gASgCDEEANgK8LQwBCyABKAIMKAK8LUEITgRAIAEoAgwvAbgtIQIgASgCDCgCCCEDIAEoAgwiBCgCFCEAIAQgAEEBajYCFCAAIANqIAI6AAAgASgCDCIAIAAvAbgtQQh1OwG4LSABKAIMIgAgACgCvC1BCGs2ArwtCwsL7wEBBH8jAEEQayIBIAA2AgwCQCABKAIMKAK8LUEISgRAIAEoAgwvAbgtQf8BcSECIAEoAgwoAgghAyABKAIMIgQoAhQhACAEIABBAWo2AhQgACADaiACOgAAIAEoAgwvAbgtQQh1IQIgASgCDCgCCCEDIAEoAgwiBCgCFCEAIAQgAEEBajYCFCAAIANqIAI6AAAMAQsgASgCDCgCvC1BAEoEQCABKAIMLwG4LSECIAEoAgwoAgghAyABKAIMIgQoAhQhACAEIABBAWo2AhQgACADaiACOgAACwsgASgCDEEAOwG4LSABKAIMQQA2ArwtC/wBAQF/IwBBEGsiASAANgIMIAFBADYCCANAIAEoAghBngJORQRAIAEoAgxBlAFqIAEoAghBAnRqQQA7AQAgASABKAIIQQFqNgIIDAELCyABQQA2AggDQCABKAIIQR5ORQRAIAEoAgxBiBNqIAEoAghBAnRqQQA7AQAgASABKAIIQQFqNgIIDAELCyABQQA2AggDQCABKAIIQRNORQRAIAEoAgxB/BRqIAEoAghBAnRqQQA7AQAgASABKAIIQQFqNgIIDAELCyABKAIMQQE7AZQJIAEoAgxBADYCrC0gASgCDEEANgKoLSABKAIMQQA2ArAtIAEoAgxBADYCoC0LIgEBfyMAQRBrIgEkACABIAA2AgwgASgCDBAWIAFBEGokAAvpAQEBfyMAQTBrIgIgADYCJCACIAE3AxggAkIANwMQIAIgAigCJCkDCEIBfTcDCAJAA0AgAikDECACKQMIVARAIAIgAikDECACKQMIIAIpAxB9QgGIfDcDAAJAIAIoAiQoAgQgAikDAKdBA3RqKQMAIAIpAxhWBEAgAiACKQMAQgF9NwMIDAELAkAgAikDACACKAIkKQMIUgRAIAIoAiQoAgQgAikDAEIBfKdBA3RqKQMAIAIpAxhYDQELIAIgAikDADcDKAwECyACIAIpAwBCAXw3AxALDAELCyACIAIpAxA3AygLIAIpAygLpwEBAX8jAEEwayIEJAAgBCAANgIoIAQgATYCJCAEIAI3AxggBCADNgIUIAQgBCgCKCkDOCAEKAIoKQMwIAQoAiQgBCkDGCAEKAIUEI0BNwMIAkAgBCkDCEIAUwRAIARBfzYCLAwBCyAEKAIoIAQpAwg3AzggBCgCKCAEKAIoKQM4ELsBIQIgBCgCKCACNwNAIARBADYCLAsgBCgCLCEAIARBMGokACAAC+sBAQF/IwBBIGsiAyQAIAMgADYCGCADIAE3AxAgAyACNgIMAkAgAykDECADKAIYKQMQVARAIANBAToAHwwBCyADIAMoAhgoAgAgAykDEEIEhqcQTSIANgIIIABFBEAgAygCDEEOQQAQFSADQQA6AB8MAQsgAygCGCADKAIINgIAIAMgAygCGCgCBCADKQMQQgF8QgOGpxBNIgA2AgQgAEUEQCADKAIMQQ5BABAVIANBADoAHwwBCyADKAIYIAMoAgQ2AgQgAygCGCADKQMQNwMQIANBAToAHwsgAy0AH0EBcSEAIANBIGokACAAC9ACAQF/IwBBMGsiBCQAIAQgADYCKCAEIAE3AyAgBCACNgIcIAQgAzYCGAJAAkAgBCgCKA0AIAQpAyBCAFgNACAEKAIYQRJBABAVIARBADYCLAwBCyAEIAQoAiggBCkDICAEKAIcIAQoAhgQTiIANgIMIABFBEAgBEEANgIsDAELIARBGBAZIgA2AhQgAEUEQCAEKAIYQQ5BABAVIAQoAgwQNCAEQQA2AiwMAQsgBCgCFCAEKAIMNgIQIAQoAhRBADYCFEEAEAEhACAEKAIUIAA2AgwjAEEQayIAIAQoAhQ2AgwgACgCDEEANgIAIAAoAgxBADYCBCAAKAIMQQA2AgggBEECIAQoAhQgBCgCGBCQASIANgIQIABFBEAgBCgCFCgCEBA0IAQoAhQQFiAEQQA2AiwMAQsgBCAEKAIQNgIsCyAEKAIsIQAgBEEwaiQAIAALqQEBAX8jAEEwayIEJAAgBCAANgIoIAQgATcDICAEIAI2AhwgBCADNgIYAkAgBCgCKEUEQCAEKQMgQgBWBEAgBCgCGEESQQAQFSAEQQA2AiwMAgsgBEEAQgAgBCgCHCAEKAIYEL4BNgIsDAELIAQgBCgCKDYCCCAEIAQpAyA3AxAgBCAEQQhqQgEgBCgCHCAEKAIYEL4BNgIsCyAEKAIsIQAgBEEwaiQAIAALRgEBfyMAQSBrIgMkACADIAA2AhwgAyABNwMQIAMgAjYCDCADKAIcIAMpAxAgAygCDCADKAIcQQhqEE8hACADQSBqJAAgAAuNAgEBfyMAQTBrIgMkACADIAA2AiggAyABOwEmIAMgAjYCICADIAMoAigoAjQgA0EeaiADLwEmQYAGQQAQXzYCEAJAIAMoAhBFDQAgAy8BHkEFSA0AAkAgAygCEC0AAEEBRg0ADAELIAMgAygCECADLwEerRAqIgA2AhQgAEUEQAwBCyADKAIUEIsBGiADIAMoAhQQKzYCGCADKAIgEIgBIAMoAhhGBEAgAyADKAIUEDA9AQ4gAyADKAIUIAMvAQ6tEB8gAy8BDkGAEEEAEFE2AgggAygCCARAIAMoAiAQJiADIAMoAgg2AiALCyADKAIUEBcLIAMgAygCIDYCLCADKAIsIQAgA0EwaiQAIAALuRECAX8BfiMAQYABayIFJAAgBSAANgJ0IAUgATYCcCAFIAI2AmwgBSADOgBrIAUgBDYCZCAFIAUoAmxBAEc6AB0gBUEeQS4gBS0Aa0EBcRs2AigCQAJAIAUoAmwEQCAFKAJsEDAgBSgCKK1UBEAgBSgCZEETQQAQFSAFQn83A3gMAwsMAQsgBSAFKAJwIAUoAiitIAVBMGogBSgCZBBBIgA2AmwgAEUEQCAFQn83A3gMAgsLIAUoAmxCBBAfIQBBxdMAQcrTACAFLQBrQQFxGygAACAAKAAARwRAIAUoAmRBE0EAEBUgBS0AHUEBcUUEQCAFKAJsEBcLIAVCfzcDeAwBCyAFKAJ0EF0CQCAFLQBrQQFxRQRAIAUoAmwQHiEAIAUoAnQgADsBCAwBCyAFKAJ0QQA7AQgLIAUoAmwQHiEAIAUoAnQgADsBCiAFKAJsEB4hACAFKAJ0IAA7AQwgBSgCbBAeQf//A3EhACAFKAJ0IAA2AhAgBSAFKAJsEB47AS4gBSAFKAJsEB47ASwgBS8BLiAFLwEsEI0DIQAgBSgCdCAANgIUIAUoAmwQKyEAIAUoAnQgADYCGCAFKAJsECutIQYgBSgCdCAGNwMgIAUoAmwQK60hBiAFKAJ0IAY3AyggBSAFKAJsEB47ASIgBSAFKAJsEB47AR4CQCAFLQBrQQFxBEAgBUEAOwEgIAUoAnRBADYCPCAFKAJ0QQA7AUAgBSgCdEEANgJEIAUoAnRCADcDSAwBCyAFIAUoAmwQHjsBICAFKAJsEB5B//8DcSEAIAUoAnQgADYCPCAFKAJsEB4hACAFKAJ0IAA7AUAgBSgCbBArIQAgBSgCdCAANgJEIAUoAmwQK60hBiAFKAJ0IAY3A0gLAn8jAEEQayIAIAUoAmw2AgwgACgCDC0AAEEBcUULBEAgBSgCZEEUQQAQFSAFLQAdQQFxRQRAIAUoAmwQFwsgBUJ/NwN4DAELAkAgBSgCdC8BDEEBcQRAIAUoAnQvAQxBwABxBEAgBSgCdEH//wM7AVIMAgsgBSgCdEEBOwFSDAELIAUoAnRBADsBUgsgBSgCdEEANgIwIAUoAnRBADYCNCAFKAJ0QQA2AjggBSAFLwEgIAUvASIgBS8BHmpqNgIkAkAgBS0AHUEBcQRAIAUoAmwQMCAFKAIkrVQEQCAFKAJkQRVBABAVIAVCfzcDeAwDCwwBCyAFKAJsEBcgBSAFKAJwIAUoAiStQQAgBSgCZBBBIgA2AmwgAEUEQCAFQn83A3gMAgsLIAUvASIEQCAFKAJsIAUoAnAgBS8BIkEBIAUoAmQQiQEhACAFKAJ0IAA2AjAgBSgCdCgCMEUEQAJ/IwBBEGsiACAFKAJkNgIMIAAoAgwoAgBBEUYLBEAgBSgCZEEVQQAQFQsgBS0AHUEBcUUEQCAFKAJsEBcLIAVCfzcDeAwCCyAFKAJ0LwEMQYAQcQRAIAUoAnQoAjBBAhA7QQVGBEAgBSgCZEEVQQAQFSAFLQAdQQFxRQRAIAUoAmwQFwsgBUJ/NwN4DAMLCwsgBS8BHgRAIAUgBSgCbCAFKAJwIAUvAR5BACAFKAJkEGA2AhggBSgCGEUEQCAFLQAdQQFxRQRAIAUoAmwQFwsgBUJ/NwN4DAILIAUoAhggBS8BHkGAAkGABCAFLQBrQQFxGyAFKAJ0QTRqIAUoAmQQhAFBAXFFBEAgBSgCGBAWIAUtAB1BAXFFBEAgBSgCbBAXCyAFQn83A3gMAgsgBSgCGBAWIAUtAGtBAXEEQCAFKAJ0QQE6AAQLCyAFLwEgBEAgBSgCbCAFKAJwIAUvASBBACAFKAJkEIkBIQAgBSgCdCAANgI4IAUoAnQoAjhFBEAgBS0AHUEBcUUEQCAFKAJsEBcLIAVCfzcDeAwCCyAFKAJ0LwEMQYAQcQRAIAUoAnQoAjhBAhA7QQVGBEAgBSgCZEEVQQAQFSAFLQAdQQFxRQRAIAUoAmwQFwsgBUJ/NwN4DAMLCwsgBSgCdEH14AEgBSgCdCgCMBDBASEAIAUoAnQgADYCMCAFKAJ0QfXGASAFKAJ0KAI4EMEBIQAgBSgCdCAANgI4AkACQCAFKAJ0KQMoQv////8PUQ0AIAUoAnQpAyBC/////w9RDQAgBSgCdCkDSEL/////D1INAQsgBSAFKAJ0KAI0IAVBFmpBAUGAAkGABCAFLQBrQQFxGyAFKAJkEF82AgwgBSgCDEUEQCAFLQAdQQFxRQRAIAUoAmwQFwsgBUJ/NwN4DAILIAUgBSgCDCAFLwEWrRAqIgA2AhAgAEUEQCAFKAJkQQ5BABAVIAUtAB1BAXFFBEAgBSgCbBAXCyAFQn83A3gMAgsCQCAFKAJ0KQMoQv////8PUQRAIAUoAhAQMSEGIAUoAnQgBjcDKAwBCyAFLQBrQQFxBEAgBSgCEBDMAQsLIAUoAnQpAyBC/////w9RBEAgBSgCEBAxIQYgBSgCdCAGNwMgCyAFLQBrQQFxRQRAIAUoAnQpA0hC/////w9RBEAgBSgCEBAxIQYgBSgCdCAGNwNICyAFKAJ0KAI8Qf//A0YEQCAFKAIQECshACAFKAJ0IAA2AjwLCyAFKAIQEEhBAXFFBEAgBSgCZEEVQQAQFSAFKAIQEBcgBS0AHUEBcUUEQCAFKAJsEBcLIAVCfzcDeAwCCyAFKAIQEBcLAn8jAEEQayIAIAUoAmw2AgwgACgCDC0AAEEBcUULBEAgBSgCZEEUQQAQFSAFLQAdQQFxRQRAIAUoAmwQFwsgBUJ/NwN4DAELIAUtAB1BAXFFBEAgBSgCbBAXCyAFKAJ0KQNIQv///////////wBWBEAgBSgCZEEEQRYQFSAFQn83A3gMAQsgBSgCdCAFKAJkEIwDQQFxRQRAIAVCfzcDeAwBCyAFKAJ0KAI0EIMBIQAgBSgCdCAANgI0IAUgBSgCKCAFKAIkaq03A3gLIAUpA3ghBiAFQYABaiQAIAYLzQEBAX8jAEEQayIDJAAgAyAANgIMIAMgATYCCCADIAI2AgQgAyADQQxqQaygARAKNgIAAkAgAygCAEUEQCADKAIEQSE7AQAgAygCCEEAOwEADAELIAMoAgAoAhRB0ABIBEAgAygCAEHQADYCFAsgAygCBCADKAIAKAIMIAMoAgAoAhRBCXQgAygCACgCEEEFdGpBoMB9amo7AQAgAygCCCADKAIAKAIIQQt0IAMoAgAoAgRBBXRqIAMoAgAoAgBBAXVqOwEACyADQRBqJAALgwMBAX8jAEEgayIDJAAgAyAAOwEaIAMgATYCFCADIAI2AhAgAyADKAIUIANBCGpBwABBABBHIgA2AgwCQCAARQRAIANBADYCHAwBCyADKAIIQQVqQf//A0sEQCADKAIQQRJBABAVIANBADYCHAwBCyADQQAgAygCCEEFaq0QKiIANgIEIABFBEAgAygCEEEOQQAQFSADQQA2AhwMAQsgAygCBEEBEIoBIAMoAgQgAygCFBCIARAhIAMoAgQgAygCDCADKAIIEEACfyMAQRBrIgAgAygCBDYCDCAAKAIMLQAAQQFxRQsEQCADKAIQQRRBABAVIAMoAgQQFyADQQA2AhwMAQsgAyADLwEaAn8jAEEQayIAIAMoAgQ2AgwCfiAAKAIMLQAAQQFxBEAgACgCDCkDEAwBC0IAC6dB//8DcQsCfyMAQRBrIgAgAygCBDYCDCAAKAIMKAIEC0GABhBQNgIAIAMoAgQQFyADIAMoAgA2AhwLIAMoAhwhACADQSBqJAAgAAu0AgEBfyMAQTBrIgMkACADIAA2AiggAyABNwMgIAMgAjYCHAJAIAMpAyBQBEAgA0EBOgAvDAELIAMgAygCKCkDECADKQMgfDcDCAJAIAMpAwggAykDIFoEQCADKQMIQv////8AWA0BCyADKAIcQQ5BABAVIANBADoALwwBCyADIAMoAigoAgAgAykDCKdBBHQQTSIANgIEIABFBEAgAygCHEEOQQAQFSADQQA6AC8MAQsgAygCKCADKAIENgIAIAMgAygCKCkDCDcDEANAIAMpAxAgAykDCFpFBEAgAygCKCgCACADKQMQp0EEdGoQjAEgAyADKQMQQgF8NwMQDAELCyADKAIoIAMpAwgiATcDECADKAIoIAE3AwggA0EBOgAvCyADLQAvQQFxIQAgA0EwaiQAIAALzAEBAX8jAEEgayICJAAgAiAANwMQIAIgATYCDCACQTAQGSIBNgIIAkAgAUUEQCACKAIMQQ5BABAVIAJBADYCHAwBCyACKAIIQQA2AgAgAigCCEIANwMQIAIoAghCADcDCCACKAIIQgA3AyAgAigCCEIANwMYIAIoAghBADYCKCACKAIIQQA6ACwgAigCCCACKQMQIAIoAgwQxQFBAXFFBEAgAigCCBAlIAJBADYCHAwBCyACIAIoAgg2AhwLIAIoAhwhASACQSBqJAAgAQu2BQEBfyMAQTBrIgIkACACIAA2AiggAiABNwMgAkAgAikDICACKAIoKQMwWgRAIAIoAihBCGpBEkEAEBUgAkF/NgIsDAELIAIgAigCKCgCQCACKQMgp0EEdGo2AhwCQCACKAIcKAIABEAgAigCHCgCAC0ABEEBcUUNAQsgAkEANgIsDAELIAIoAhwoAgApA0hCGnxC////////////AFYEQCACKAIoQQhqQQRBFhAVIAJBfzYCLAwBCyACKAIoKAIAIAIoAhwoAgApA0hCGnxBABAoQQBIBEAgAigCKEEIaiACKAIoKAIAEBggAkF/NgIsDAELIAIgAigCKCgCAEIEIAJBGGogAigCKEEIahBBIgA2AhQgAEUEQCACQX82AiwMAQsgAiACKAIUEB47ARIgAiACKAIUEB47ARAgAigCFBBIQQFxRQRAIAIoAhQQFyACKAIoQQhqQRRBABAVIAJBfzYCLAwBCyACKAIUEBcgAi8BEEEASgRAIAIoAigoAgAgAi8BEq1BARAoQQBIBEAgAigCKEEIakEEQbScASgCABAVIAJBfzYCLAwCCyACQQAgAigCKCgCACACLwEQQQAgAigCKEEIahBgNgIIIAIoAghFBEAgAkF/NgIsDAILIAIoAgggAi8BEEGAAiACQQxqIAIoAihBCGoQhAFBAXFFBEAgAigCCBAWIAJBfzYCLAwCCyACKAIIEBYgAigCDARAIAIgAigCDBCDATYCDCACKAIcKAIAKAI0IAIoAgwQhQEhACACKAIcKAIAIAA2AjQLCyACKAIcKAIAQQE6AAQCQCACKAIcKAIERQ0AIAIoAhwoAgQtAARBAXENACACKAIcKAIEIAIoAhwoAgAoAjQ2AjQgAigCHCgCBEEBOgAECyACQQA2AiwLIAIoAiwhACACQTBqJAAgAAsHACAAKAIAC4wBAQF/IwBBIGsiAiQAIAIgADYCGCACIAE2AhQgAkEANgIQAkAgAigCFEUEQCACQQA2AhwMAQsgAiACKAIUEBk2AgwgAigCDEUEQCACKAIQQQ5BABAVIAJBADYCHAwBCyACKAIMIAIoAhggAigCFBAaGiACIAIoAgw2AhwLIAIoAhwhACACQSBqJAAgAAsYAEGonAFCADcCAEGwnAFBADYCAEGonAELiAEBAX8jAEEgayIDJAAgAyAANgIUIAMgATYCECADIAI3AwgCQAJAIAMoAhQoAiRBAUYEQCADKQMIQv///////////wBYDQELIAMoAhRBDGpBEkEAEBUgA0J/NwMYDAELIAMgAygCFCADKAIQIAMpAwhBCxAiNwMYCyADKQMYIQIgA0EgaiQAIAILcwEBfyMAQSBrIgEkACABIAA2AhggAUIINwMQIAEgASgCGCkDECABKQMQfDcDCAJAIAEpAwggASgCGCkDEFQEQCABKAIYQQA6AAAgAUF/NgIcDAELIAEgASgCGCABKQMIEC02AhwLIAEoAhwaIAFBIGokAAsIAEEBQQwQewuWAQEBfyMAQSBrIgIgADYCGCACIAE3AxACQAJAAkAgAigCGC0AAEEBcUUNACACKAIYKQMQIAIpAxB8IAIpAxBUDQAgAigCGCkDECACKQMQfCACKAIYKQMIWA0BCyACKAIYQQA6AAAgAkEANgIcDAELIAIgAigCGCgCBCACKAIYKQMQp2o2AgwgAiACKAIMNgIcCyACKAIcCwcAIAAoAigLuQIBAX8jAEEQayICIAA2AgggAiABNgIEAkAgAigCCEGAAUkEQCACKAIEIAIoAgg6AAAgAkEBNgIMDAELIAIoAghBgBBJBEAgAigCBCACKAIIQQZ2QR9xQcABcjoAACACKAIEIAIoAghBP3FBgAFyOgABIAJBAjYCDAwBCyACKAIIQYCABEkEQCACKAIEIAIoAghBDHZBD3FB4AFyOgAAIAIoAgQgAigCCEEGdkE/cUGAAXI6AAEgAigCBCACKAIIQT9xQYABcjoAAiACQQM2AgwMAQsgAigCBCACKAIIQRJ2QQdxQfABcjoAACACKAIEIAIoAghBDHZBP3FBgAFyOgABIAIoAgQgAigCCEEGdkE/cUGAAXI6AAIgAigCBCACKAIIQT9xQYABcjoAAyACQQQ2AgwLIAIoAgwLXwEBfyMAQRBrIgEgADYCCAJAIAEoAghBgAFJBEAgAUEBNgIMDAELIAEoAghBgBBJBEAgAUECNgIMDAELIAEoAghBgIAESQRAIAFBAzYCDAwBCyABQQQ2AgwLIAEoAgwL/gIBAX8jAEEwayIEJAAgBCAANgIoIAQgATYCJCAEIAI2AiAgBCADNgIcIAQgBCgCKDYCGAJAIAQoAiRFBEAgBCgCIARAIAQoAiBBADYCAAsgBEEANgIsDAELIARBATYCECAEQQA2AgwDQCAEKAIMIAQoAiRPRQRAIAQgBCgCGCAEKAIMai0AAEEBdEGwzwBqLwEAENEBIAQoAhBqNgIQIAQgBCgCDEEBajYCDAwBCwsgBCAEKAIQEBkiADYCFCAARQRAIAQoAhxBDkEAEBUgBEEANgIsDAELIARBADYCCCAEQQA2AgwDQCAEKAIMIAQoAiRPRQRAIAQgBCgCGCAEKAIMai0AAEEBdEGwzwBqLwEAIAQoAhQgBCgCCGoQ0AEgBCgCCGo2AgggBCAEKAIMQQFqNgIMDAELCyAEKAIUIAQoAhBBAWtqQQA6AAAgBCgCIARAIAQoAiAgBCgCEEEBazYCAAsgBCAEKAIUNgIsCyAEKAIsIQAgBEEwaiQAIAALBwAgACgCGAvyCwEBfyMAQSBrIgMgADYCHCADIAE2AhggAyACNgIUIAMgAygCHEEIdkGA/gNxIAMoAhxBGHZqIAMoAhxBgP4DcUEIdGogAygCHEH/AXFBGHRqNgIQIAMgAygCEEF/czYCEANAQQAhACADKAIUBH8gAygCGEEDcUEARwVBAAtBAXEEQCADKAIQQRh2IQAgAyADKAIYIgFBAWo2AhggAyABLQAAIABzQQJ0QbAvaigCACADKAIQQQh0czYCECADIAMoAhRBf2o2AhQMAQsLIAMgAygCGDYCDANAIAMoAhRBIElFBEAgAyADKAIMIgBBBGo2AgwgAyAAKAIAIAMoAhBzNgIQIAMgAygCEEEYdkECdEGwxwBqKAIAIAMoAhBBEHZB/wFxQQJ0QbA/aigCACADKAIQQf8BcUECdEGwL2ooAgAgAygCEEEIdkH/AXFBAnRBsDdqKAIAc3NzNgIQIAMgAygCDCIAQQRqNgIMIAMgACgCACADKAIQczYCECADIAMoAhBBGHZBAnRBsMcAaigCACADKAIQQRB2Qf8BcUECdEGwP2ooAgAgAygCEEH/AXFBAnRBsC9qKAIAIAMoAhBBCHZB/wFxQQJ0QbA3aigCAHNzczYCECADIAMoAgwiAEEEajYCDCADIAAoAgAgAygCEHM2AhAgAyADKAIQQRh2QQJ0QbDHAGooAgAgAygCEEEQdkH/AXFBAnRBsD9qKAIAIAMoAhBB/wFxQQJ0QbAvaigCACADKAIQQQh2Qf8BcUECdEGwN2ooAgBzc3M2AhAgAyADKAIMIgBBBGo2AgwgAyAAKAIAIAMoAhBzNgIQIAMgAygCEEEYdkECdEGwxwBqKAIAIAMoAhBBEHZB/wFxQQJ0QbA/aigCACADKAIQQf8BcUECdEGwL2ooAgAgAygCEEEIdkH/AXFBAnRBsDdqKAIAc3NzNgIQIAMgAygCDCIAQQRqNgIMIAMgACgCACADKAIQczYCECADIAMoAhBBGHZBAnRBsMcAaigCACADKAIQQRB2Qf8BcUECdEGwP2ooAgAgAygCEEH/AXFBAnRBsC9qKAIAIAMoAhBBCHZB/wFxQQJ0QbA3aigCAHNzczYCECADIAMoAgwiAEEEajYCDCADIAAoAgAgAygCEHM2AhAgAyADKAIQQRh2QQJ0QbDHAGooAgAgAygCEEEQdkH/AXFBAnRBsD9qKAIAIAMoAhBB/wFxQQJ0QbAvaigCACADKAIQQQh2Qf8BcUECdEGwN2ooAgBzc3M2AhAgAyADKAIMIgBBBGo2AgwgAyAAKAIAIAMoAhBzNgIQIAMgAygCEEEYdkECdEGwxwBqKAIAIAMoAhBBEHZB/wFxQQJ0QbA/aigCACADKAIQQf8BcUECdEGwL2ooAgAgAygCEEEIdkH/AXFBAnRBsDdqKAIAc3NzNgIQIAMgAygCDCIAQQRqNgIMIAMgACgCACADKAIQczYCECADIAMoAhBBGHZBAnRBsMcAaigCACADKAIQQRB2Qf8BcUECdEGwP2ooAgAgAygCEEH/AXFBAnRBsC9qKAIAIAMoAhBBCHZB/wFxQQJ0QbA3aigCAHNzczYCECADIAMoAhRBIGs2AhQMAQsLA0AgAygCFEEESUUEQCADIAMoAgwiAEEEajYCDCADIAAoAgAgAygCEHM2AhAgAyADKAIQQRh2QQJ0QbDHAGooAgAgAygCEEEQdkH/AXFBAnRBsD9qKAIAIAMoAhBB/wFxQQJ0QbAvaigCACADKAIQQQh2Qf8BcUECdEGwN2ooAgBzc3M2AhAgAyADKAIUQQRrNgIUDAELCyADIAMoAgw2AhggAygCFARAA0AgAygCEEEYdiEAIAMgAygCGCIBQQFqNgIYIAMgAS0AACAAc0ECdEGwL2ooAgAgAygCEEEIdHM2AhAgAyADKAIUQX9qIgA2AhQgAA0ACwsgAyADKAIQQX9zNgIQIAMoAhBBCHZBgP4DcSADKAIQQRh2aiADKAIQQYD+A3FBCHRqIAMoAhBB/wFxQRh0aguTCwEBfyMAQSBrIgMgADYCHCADIAE2AhggAyACNgIUIAMgAygCHDYCECADIAMoAhBBf3M2AhADQEEAIQAgAygCFAR/IAMoAhhBA3FBAEcFQQALQQFxBEAgAygCECEAIAMgAygCGCIBQQFqNgIYIAMgAS0AACAAc0H/AXFBAnRBsA9qKAIAIAMoAhBBCHZzNgIQIAMgAygCFEF/ajYCFAwBCwsgAyADKAIYNgIMA0AgAygCFEEgSUUEQCADIAMoAgwiAEEEajYCDCADIAAoAgAgAygCEHM2AhAgAyADKAIQQRh2QQJ0QbAPaigCACADKAIQQRB2Qf8BcUECdEGwF2ooAgAgAygCEEH/AXFBAnRBsCdqKAIAIAMoAhBBCHZB/wFxQQJ0QbAfaigCAHNzczYCECADIAMoAgwiAEEEajYCDCADIAAoAgAgAygCEHM2AhAgAyADKAIQQRh2QQJ0QbAPaigCACADKAIQQRB2Qf8BcUECdEGwF2ooAgAgAygCEEH/AXFBAnRBsCdqKAIAIAMoAhBBCHZB/wFxQQJ0QbAfaigCAHNzczYCECADIAMoAgwiAEEEajYCDCADIAAoAgAgAygCEHM2AhAgAyADKAIQQRh2QQJ0QbAPaigCACADKAIQQRB2Qf8BcUECdEGwF2ooAgAgAygCEEH/AXFBAnRBsCdqKAIAIAMoAhBBCHZB/wFxQQJ0QbAfaigCAHNzczYCECADIAMoAgwiAEEEajYCDCADIAAoAgAgAygCEHM2AhAgAyADKAIQQRh2QQJ0QbAPaigCACADKAIQQRB2Qf8BcUECdEGwF2ooAgAgAygCEEH/AXFBAnRBsCdqKAIAIAMoAhBBCHZB/wFxQQJ0QbAfaigCAHNzczYCECADIAMoAgwiAEEEajYCDCADIAAoAgAgAygCEHM2AhAgAyADKAIQQRh2QQJ0QbAPaigCACADKAIQQRB2Qf8BcUECdEGwF2ooAgAgAygCEEH/AXFBAnRBsCdqKAIAIAMoAhBBCHZB/wFxQQJ0QbAfaigCAHNzczYCECADIAMoAgwiAEEEajYCDCADIAAoAgAgAygCEHM2AhAgAyADKAIQQRh2QQJ0QbAPaigCACADKAIQQRB2Qf8BcUECdEGwF2ooAgAgAygCEEH/AXFBAnRBsCdqKAIAIAMoAhBBCHZB/wFxQQJ0QbAfaigCAHNzczYCECADIAMoAgwiAEEEajYCDCADIAAoAgAgAygCEHM2AhAgAyADKAIQQRh2QQJ0QbAPaigCACADKAIQQRB2Qf8BcUECdEGwF2ooAgAgAygCEEH/AXFBAnRBsCdqKAIAIAMoAhBBCHZB/wFxQQJ0QbAfaigCAHNzczYCECADIAMoAgwiAEEEajYCDCADIAAoAgAgAygCEHM2AhAgAyADKAIQQRh2QQJ0QbAPaigCACADKAIQQRB2Qf8BcUECdEGwF2ooAgAgAygCEEH/AXFBAnRBsCdqKAIAIAMoAhBBCHZB/wFxQQJ0QbAfaigCAHNzczYCECADIAMoAhRBIGs2AhQMAQsLA0AgAygCFEEESUUEQCADIAMoAgwiAEEEajYCDCADIAAoAgAgAygCEHM2AhAgAyADKAIQQRh2QQJ0QbAPaigCACADKAIQQRB2Qf8BcUECdEGwF2ooAgAgAygCEEH/AXFBAnRBsCdqKAIAIAMoAhBBCHZB/wFxQQJ0QbAfaigCAHNzczYCECADIAMoAhRBBGs2AhQMAQsLIAMgAygCDDYCGCADKAIUBEADQCADKAIQIQAgAyADKAIYIgFBAWo2AhggAyABLQAAIABzQf8BcUECdEGwD2ooAgAgAygCEEEIdnM2AhAgAyADKAIUQX9qIgA2AhQgAA0ACwsgAyADKAIQQX9zNgIQIAMoAhALhgEBAX8jAEEgayIDJAAgAyAANgIYIAMgATYCFCADIAI2AhACQCADKAIURQRAIANBADYCHAwBCyADQQE2AgwgAy0ADARAIAMgAygCGCADKAIUIAMoAhAQ1QE2AhwMAQsgAyADKAIYIAMoAhQgAygCEBDUATYCHAsgAygCHCEAIANBIGokACAACwcAIAAoAhALIgEBfyMAQRBrIgEgADYCDCABKAIMIgAgACgCMEEBajYCMAsUACAAIAGtIAKtQiCGhCADIAQQegsTAQF+IAAQSiIBQiCIpxAAIAGnCxIAIAAgAa0gAq1CIIaEIAMQKAsfAQF+IAAgASACrSADrUIghoQQLyIEQiCIpxAAIASnCxUAIAAgAa0gAq1CIIaEIAMgBBC/AQsUACAAIAEgAq0gA61CIIaEIAQQeQsVACAAIAGtIAKtQiCGhCADIAQQ8AELFwEBfiAAIAEgAhBuIgNCIIinEAAgA6cLFgEBfiAAIAEQkQIiAkIgiKcQACACpwsTACAAIAGtIAKtQiCGhCADEMABCyABAX4gACABIAKtIAOtQiCGhBCSAiIEQiCIpxAAIASnCxMAIAAgAa0gAq1CIIaEIAMQkwILFQAgACABrSACrUIghoQgAyAEEJYCCxcAIAAgAa0gAq1CIIaEIAMgBCAFEJ8BCxcAIAAgAa0gAq1CIIaEIAMgBCAFEJ4BCxoBAX4gACABIAIgAxCaAiIEQiCIpxAAIASnCxgBAX4gACABIAIQnAIiA0IgiKcQACADpwsRACAAIAGtIAKtQiCGhBChAQsQACMAIABrQXBxIgAkACAACwYAIAAkAAsEACMAC8QBAQF/IwBBMGsiASQAIAEgADYCKCABQQA2AiQgAUIANwMYAkADQCABKQMYIAEoAigpAzBUBEAgASABKAIoIAEpAxhBACABQRdqIAFBEGoQngE2AgwgASgCDEF/RgRAIAFBfzYCLAwDBQJAIAEtABdBA0cNACABKAIQQRB2QYDgA3FBgMACRw0AIAEgASgCJEEBajYCJAsgASABKQMYQgF8NwMYDAILAAsLIAEgASgCJDYCLAsgASgCLCEAIAFBMGokACAAC4IBAgF/AX4jAEEgayIEJAAgBCAANgIYIAQgATYCFCAEIAI2AhAgBCADNgIMIAQgBCgCGCAEKAIUIAQoAhAQbiIFNwMAAkAgBUIAUwRAIARBfzYCHAwBCyAEIAQoAhggBCkDACAEKAIQIAQoAgwQejYCHAsgBCgCHCEAIARBIGokACAAC9IDAQF/IwBBIGsiBCQAIAQgADYCGCAEIAE3AxAgBCACNgIMIAQgAzYCCAJAAkAgBCkDECAEKAIYKQMwVARAIAQoAghBCU0NAQsgBCgCGEEIakESQQAQFSAEQX82AhwMAQsgBCgCGCgCGEECcQRAIAQoAhhBCGpBGUEAEBUgBEF/NgIcDAELIAQoAgwQwwJBAXFFBEAgBCgCGEEIakEQQQAQFSAEQX82AhwMAQsgBCAEKAIYKAJAIAQpAxCnQQR0ajYCBCAEAn9BfyAEKAIEKAIARQ0AGiAEKAIEKAIAKAIQCzYCAAJAIAQoAgwgBCgCAEYEQCAEKAIEKAIEBEAgBCgCBCgCBCIAIAAoAgBBfnE2AgAgBCgCBCgCBEEAOwFQIAQoAgQoAgQoAgBFBEAgBCgCBCgCBBA6IAQoAgRBADYCBAsLDAELIAQoAgQoAgRFBEAgBCgCBCgCABBGIQAgBCgCBCAANgIEIABFBEAgBCgCGEEIakEOQQAQFSAEQX82AhwMAwsLIAQoAgQoAgQgBCgCDDYCECAEKAIEKAIEIAQoAgg7AVAgBCgCBCgCBCIAIAAoAgBBAXI2AgALIARBADYCHAsgBCgCHCEAIARBIGokACAAC5ACAQF/IwBBEGsiAiQAIAIgADYCCCACIAE2AgQCQAJAAkAgAigCCC8BCiACKAIELwEKSA0AIAIoAggoAhAgAigCBCgCEEcNACACKAIIKAIUIAIoAgQoAhRHDQAgAigCCCgCMCACKAIEKAIwEIcBDQELIAJBfzYCDAwBCwJAAkAgAigCCCgCGCACKAIEKAIYRw0AIAIoAggpAyAgAigCBCkDIFINACACKAIIKQMoIAIoAgQpAyhRDQELAkACQCACKAIELwEMQQhxRQ0AIAIoAgQoAhgNACACKAIEKQMgQgBSDQAgAigCBCkDKFANAQsgAkF/NgIMDAILCyACQQA2AgwLIAIoAgwhACACQRBqJAAgAAv6AwEBfyMAQdAAayIEJAAgBCAANgJIIAQgATcDQCAEIAI2AjwgBCADNgI4AkAgBCgCSBAwQhZUBEAgBCgCOEEVQQAQFSAEQQA2AkwMAQsjAEEQayIAIAQoAkg2AgwgBAJ+IAAoAgwtAABBAXEEQCAAKAIMKQMQDAELQgALNwMIIAQoAkhCBBAfGiAEKAJIECsEQCAEKAI4QQFBABAVIARBADYCTAwBCyAEIAQoAkgQHkH//wNxrTcDKCAEIAQoAkgQHkH//wNxrTcDICAEKQMgIAQpAyhSBEAgBCgCOEETQQAQFSAEQQA2AkwMAQsgBCAEKAJIECutNwMYIAQgBCgCSBArrTcDECAEKQMQIAQpAxh8IAQpAxBUBEAgBCgCOEEEQRYQFSAEQQA2AkwMAQsgBCkDECAEKQMYfCAEKQNAIAQpAwh8VgRAIAQoAjhBFUEAEBUgBEEANgJMDAELAkAgBCgCPEEEcUUNACAEKQMQIAQpAxh8IAQpA0AgBCkDCHxRDQAgBCgCOEEVQQAQFSAEQQA2AkwMAQsgBCAEKQMgIAQoAjgQxgEiADYCNCAARQRAIARBADYCTAwBCyAEKAI0QQA6ACwgBCgCNCAEKQMYNwMYIAQoAjQgBCkDEDcDICAEIAQoAjQ2AkwLIAQoAkwhACAEQdAAaiQAIAAL1QoBAX8jAEGwAWsiBSQAIAUgADYCqAEgBSABNgKkASAFIAI3A5gBIAUgAzYClAEgBSAENgKQASMAQRBrIgAgBSgCpAE2AgwgBQJ+IAAoAgwtAABBAXEEQCAAKAIMKQMQDAELQgALNwMYIAUoAqQBQgQQHxogBSAFKAKkARAeQf//A3E2AhAgBSAFKAKkARAeQf//A3E2AgggBSAFKAKkARAxNwM4AkAgBSkDOEL///////////8AVgRAIAUoApABQQRBFhAVIAVBADYCrAEMAQsgBSkDOEI4fCAFKQMYIAUpA5gBfFYEQCAFKAKQAUEVQQAQFSAFQQA2AqwBDAELAkACQCAFKQM4IAUpA5gBVA0AIAUpAzhCOHwgBSkDmAECfiMAQRBrIgAgBSgCpAE2AgwgACgCDCkDCAt8Vg0AIAUoAqQBIAUpAzggBSkDmAF9EC0aIAVBADoAFwwBCyAFKAKoASAFKQM4QQAQKEEASARAIAUoApABIAUoAqgBEBggBUEANgKsAQwCCyAFIAUoAqgBQjggBUFAayAFKAKQARBBIgA2AqQBIABFBEAgBUEANgKsAQwCCyAFQQE6ABcLIAUoAqQBQgQQHygAAEHQlpkwRwRAIAUoApABQRVBABAVIAUtABdBAXEEQCAFKAKkARAXCyAFQQA2AqwBDAELIAUgBSgCpAEQMTcDMAJAIAUoApQBQQRxRQ0AIAUpAzAgBSkDOHxCDHwgBSkDmAEgBSkDGHxRDQAgBSgCkAFBFUEAEBUgBS0AF0EBcQRAIAUoAqQBEBcLIAVBADYCrAEMAQsgBSgCpAFCBBAfGiAFIAUoAqQBECs2AgwgBSAFKAKkARArNgIEIAUoAhBB//8DRgRAIAUgBSgCDDYCEAsgBSgCCEH//wNGBEAgBSAFKAIENgIICwJAIAUoApQBQQRxRQ0AIAUoAgggBSgCBEYEQCAFKAIQIAUoAgxGDQELIAUoApABQRVBABAVIAUtABdBAXEEQCAFKAKkARAXCyAFQQA2AqwBDAELAkAgBSgCEEUEQCAFKAIIRQ0BCyAFKAKQAUEBQQAQFSAFLQAXQQFxBEAgBSgCpAEQFwsgBUEANgKsAQwBCyAFIAUoAqQBEDE3AyggBSAFKAKkARAxNwMgIAUpAyggBSkDIFIEQCAFKAKQAUEBQQAQFSAFLQAXQQFxBEAgBSgCpAEQFwsgBUEANgKsAQwBCyAFIAUoAqQBEDE3AzAgBSAFKAKkARAxNwOAAQJ/IwBBEGsiACAFKAKkATYCDCAAKAIMLQAAQQFxRQsEQCAFKAKQAUEUQQAQFSAFLQAXQQFxBEAgBSgCpAEQFwsgBUEANgKsAQwBCyAFLQAXQQFxBEAgBSgCpAEQFwsCQCAFKQOAAUL///////////8AWARAIAUpA4ABIAUpAzB8IAUpA4ABWg0BCyAFKAKQAUEEQRYQFSAFQQA2AqwBDAELIAUpA4ABIAUpAzB8IAUpA5gBIAUpAzh8VgRAIAUoApABQRVBABAVIAVBADYCrAEMAQsCQCAFKAKUAUEEcUUNACAFKQOAASAFKQMwfCAFKQOYASAFKQM4fFENACAFKAKQAUEVQQAQFSAFQQA2AqwBDAELIAUpAyggBSkDMEIugFYEQCAFKAKQAUEVQQAQFSAFQQA2AqwBDAELIAUgBSkDKCAFKAKQARDGASIANgKMASAARQRAIAVBADYCrAEMAQsgBSgCjAFBAToALCAFKAKMASAFKQMwNwMYIAUoAowBIAUpA4ABNwMgIAUgBSgCjAE2AqwBCyAFKAKsASEAIAVBsAFqJAAgAAviCwEBfyMAQfAAayIEJAAgBCAANgJoIAQgATYCZCAEIAI3A1ggBCADNgJUIwBBEGsiACAEKAJkNgIMIAQCfiAAKAIMLQAAQQFxBEAgACgCDCkDEAwBC0IACzcDMAJAIAQoAmQQMEIWVARAIAQoAlRBE0EAEBUgBEEANgJsDAELIAQoAmRCBBAfKAAAQdCWlTBHBEAgBCgCVEETQQAQFSAEQQA2AmwMAQsCQAJAIAQpAzBCFFQNACMAQRBrIgAgBCgCZDYCDCAAKAIMKAIEIAQpAzCnakFsaigAAEHQlpk4Rw0AIAQoAmQgBCkDMEIUfRAtGiAEIAQoAmgoAgAgBCgCZCAEKQNYIAQoAmgoAhQgBCgCVBDzATYCUAwBCyAEKAJkIAQpAzAQLRogBCAEKAJkIAQpA1ggBCgCaCgCFCAEKAJUEPIBNgJQCyAEKAJQRQRAIARBADYCbAwBCyAEKAJkIAQpAzBCFHwQLRogBCAEKAJkEB47AU4gBCgCUCkDICAEKAJQKQMYfCAEKQNYIAQpAzB8VgRAIAQoAlRBFUEAEBUgBCgCUBAlIARBADYCbAwBCwJAIAQvAU5FBEAgBCgCaCgCBEEEcUUNAQsgBCgCZCAEKQMwQhZ8EC0aIAQgBCgCZBAwNwMgAkAgBCkDICAELwFOrVoEQCAEKAJoKAIEQQRxRQ0BIAQpAyAgBC8BTq1RDQELIAQoAlRBFUEAEBUgBCgCUBAlIARBADYCbAwCCyAELwFOBEAgBCgCZCAELwFOrRAfIAQvAU5BACAEKAJUEFEhACAEKAJQIAA2AiggAEUEQCAEKAJQECUgBEEANgJsDAMLCwsCQCAEKAJQKQMgIAQpA1haBEAgBCgCZCAEKAJQKQMgIAQpA1h9EC0aIAQgBCgCZCAEKAJQKQMYEB8iADYCHCAARQRAIAQoAlRBFUEAEBUgBCgCUBAlIARBADYCbAwDCyAEIAQoAhwgBCgCUCkDGBAqIgA2AiwgAEUEQCAEKAJUQQ5BABAVIAQoAlAQJSAEQQA2AmwMAwsMAQsgBEEANgIsIAQoAmgoAgAgBCgCUCkDIEEAEChBAEgEQCAEKAJUIAQoAmgoAgAQGCAEKAJQECUgBEEANgJsDAILIAQoAmgoAgAQSiAEKAJQKQMgUgRAIAQoAlRBE0EAEBUgBCgCUBAlIARBADYCbAwCCwsgBCAEKAJQKQMYNwM4IARCADcDQANAAkAgBCkDOEIAWA0AIARBADoAGyAEKQNAIAQoAlApAwhRBEAgBCgCUC0ALEEBcQ0BIAQpAzhCLlQNASAEKAJQQoCABCAEKAJUEMUBQQFxRQRAIAQoAlAQJSAEKAIsEBcgBEEANgJsDAQLIARBAToAGwsQjgMhACAEKAJQKAIAIAQpA0CnQQR0aiAANgIAAkAgAARAIAQgBCgCUCgCACAEKQNAp0EEdGooAgAgBCgCaCgCACAEKAIsQQAgBCgCVBDCASICNwMQIAJCAFkNAQsCQCAELQAbQQFxRQ0AIwBBEGsiACAEKAJUNgIMIAAoAgwoAgBBE0cNACAEKAJUQRVBABAVCyAEKAJQECUgBCgCLBAXIARBADYCbAwDCyAEIAQpA0BCAXw3A0AgBCAEKQM4IAQpAxB9NwM4DAELCwJAIAQpA0AgBCgCUCkDCFEEQCAEKQM4QgBYDQELIAQoAlRBFUEAEBUgBCgCLBAXIAQoAlAQJSAEQQA2AmwMAQsgBCgCaCgCBEEEcQRAAkAgBCgCLARAIAQgBCgCLBBIQQFxOgAPDAELIAQgBCgCaCgCABBKNwMAIAQpAwBCAFMEQCAEKAJUIAQoAmgoAgAQGCAEKAJQECUgBEEANgJsDAMLIAQgBCkDACAEKAJQKQMgIAQoAlApAxh8UToADwsgBC0AD0EBcUUEQCAEKAJUQRVBABAVIAQoAiwQFyAEKAJQECUgBEEANgJsDAILCyAEKAIsEBcgBCAEKAJQNgJsCyAEKAJsIQAgBEHwAGokACAAC9cBAQF/IwBBIGsiAiQAIAIgADYCGCACIAE2AhQgAkGJmAE2AhAgAkEENgIMAkACQCACKAIUIAIoAgxPBEAgAigCDA0BCyACQQA2AhwMAQsgAiACKAIYQX9qNgIIA0ACQCACIAIoAghBAWogAigCEC0AACACKAIYIAIoAghrIAIoAhQgAigCDGtqEKYBIgA2AgggAEUNACACKAIIQQFqIAIoAhBBAWogAigCDEEBaxBTDQEgAiACKAIINgIcDAILCyACQQA2AhwLIAIoAhwhACACQSBqJAAgAAvBBgEBfyMAQeAAayICJAAgAiAANgJYIAIgATcDUAJAIAIpA1BCFlQEQCACKAJYQQhqQRNBABAVIAJBADYCXAwBCyACAn4gAikDUEKqgARUBEAgAikDUAwBC0KqgAQLNwMwIAIoAlgoAgBCACACKQMwfUECEChBAEgEQCMAQRBrIgAgAigCWCgCADYCDCACIAAoAgxBDGo2AggCQAJ/IwBBEGsiACACKAIINgIMIAAoAgwoAgBBBEYLBEAjAEEQayIAIAIoAgg2AgwgACgCDCgCBEEWRg0BCyACKAJYQQhqIAIoAggQRCACQQA2AlwMAgsLIAIgAigCWCgCABBKIgE3AzggAUIAUwRAIAIoAlhBCGogAigCWCgCABAYIAJBADYCXAwBCyACIAIoAlgoAgAgAikDMEEAIAIoAlhBCGoQQSIANgIMIABFBEAgAkEANgJcDAELIAJCfzcDICACQQA2AkwgAikDMEKqgARaBEAgAigCDEIUEC0aCyACQRBqQRNBABAVIAIgAigCDEIAEB82AkQDQAJAIAIgAigCRCACKAIMEDBCEn2nEPUBIgA2AkQgAEUNACACKAIMIAIoAkQCfyMAQRBrIgAgAigCDDYCDCAAKAIMKAIEC2usEC0aIAIgAigCWCACKAIMIAIpAzggAkEQahD0ASIANgJIIAAEQAJAIAIoAkwEQCACKQMgQgBXBEAgAiACKAJYIAIoAkwgAkEQahBlNwMgCyACIAIoAlggAigCSCACQRBqEGU3AygCQCACKQMgIAIpAyhTBEAgAigCTBAlIAIgAigCSDYCTCACIAIpAyg3AyAMAQsgAigCSBAlCwwBCyACIAIoAkg2AkwCQCACKAJYKAIEQQRxBEAgAiACKAJYIAIoAkwgAkEQahBlNwMgDAELIAJCADcDIAsLIAJBADYCSAsgAiACKAJEQQFqNgJEIAIoAgwgAigCRAJ/IwBBEGsiACACKAIMNgIMIAAoAgwoAgQLa6wQLRoMAQsLIAIoAgwQFyACKQMgQgBTBEAgAigCWEEIaiACQRBqEEQgAigCTBAlIAJBADYCXAwBCyACIAIoAkw2AlwLIAIoAlwhACACQeAAaiQAIAALvwUBAX8jAEHwAGsiAyQAIAMgADYCaCADIAE2AmQgAyACNgJgIANBIGoiABA8AkAgAygCaCAAEDlBAEgEQCADKAJgIAMoAmgQGCADQQA2AmwMAQsgAykDIEIEg1AEQCADKAJgQQRBigEQFSADQQA2AmwMAQsgAyADKQM4NwMYIAMgAygCaCADKAJkIAMoAmAQZiIANgJcIABFBEAgA0EANgJsDAELAkAgAykDGFBFDQAgAygCaBCUAUEBcUUNACADIAMoAlw2AmwMAQsgAyADKAJcIAMpAxgQ9gEiADYCWCAARQRAIAMoAmAgAygCXEEIahBEIwBBEGsiACADKAJoNgIMIAAoAgwiACAAKAIwQQFqNgIwIAMoAlwQPyADQQA2AmwMAQsgAygCXCADKAJYKAIANgJAIAMoAlwgAygCWCkDCDcDMCADKAJcIAMoAlgpAxA3AzggAygCXCADKAJYKAIoNgIgIAMoAlgQFiADKAJcKAJQIAMoAlwpAzAgAygCXEEIahD9AiADQgA3AxADQCADKQMQIAMoAlwpAzBUBEAgAyADKAJcKAJAIAMpAxCnQQR0aigCACgCMEEAQQAgAygCYBBHNgIMIAMoAgxFBEAjAEEQayIAIAMoAmg2AgwgACgCDCIAIAAoAjBBAWo2AjAgAygCXBA/IANBADYCbAwDCyADKAJcKAJQIAMoAgwgAykDEEEIIAMoAlxBCGoQfUEBcUUEQAJAIAMoAlwoAghBCkYEQCADKAJkQQRxRQ0BCyADKAJgIAMoAlxBCGoQRCMAQRBrIgAgAygCaDYCDCAAKAIMIgAgACgCMEEBajYCMCADKAJcED8gA0EANgJsDAQLCyADIAMpAxBCAXw3AxAMAQsLIAMoAlwgAygCXCgCFDYCGCADIAMoAlw2AmwLIAMoAmwhACADQfAAaiQAIAALwQEBAX8jAEHQAGsiAiQAIAIgADYCSCACIAE2AkQgAkEIaiIAEDwCQCACKAJIIAAQOQRAIwBBEGsiACACKAJINgIMIAIgACgCDEEMajYCBCMAQRBrIgAgAigCBDYCDAJAIAAoAgwoAgBBBUcNACMAQRBrIgAgAigCBDYCDCAAKAIMKAIEQSxHDQAgAkEANgJMDAILIAIoAkQgAigCBBBEIAJBfzYCTAwBCyACQQE2AkwLIAIoAkwhACACQdAAaiQAIAAL6gEBAX8jAEEwayIDJAAgAyAANgIoIAMgATYCJCADIAI2AiAjAEEQayIAIANBCGoiATYCDCAAKAIMQQA2AgAgACgCDEEANgIEIAAoAgxBADYCCCADIAMoAiggARD7ASIANgIYAkAgAEUEQCADKAIgIANBCGoiABCTASAAEDggA0EANgIsDAELIAMgAygCGCADKAIkIANBCGoQkgEiADYCHCAARQRAIAMoAhgQHCADKAIgIANBCGoiABCTASAAEDggA0EANgIsDAELIANBCGoQOCADIAMoAhw2AiwLIAMoAiwhACADQTBqJAAgAAvIAgEBfyMAQRBrIgEkACABIAA2AgggAUHYABAZNgIEAkAgASgCBEUEQCABKAIIQQ5BABAVIAFBADYCDAwBCyABKAIIEIEDIQAgASgCBCAANgJQIABFBEAgASgCBBAWIAFBADYCDAwBCyABKAIEQQA2AgAgASgCBEEANgIEIwBBEGsiACABKAIEQQhqNgIMIAAoAgxBADYCACAAKAIMQQA2AgQgACgCDEEANgIIIAEoAgRBADYCGCABKAIEQQA2AhQgASgCBEEANgIcIAEoAgRBADYCJCABKAIEQQA2AiAgASgCBEEAOgAoIAEoAgRCADcDOCABKAIEQgA3AzAgASgCBEEANgJAIAEoAgRBADYCSCABKAIEQQA2AkQgASgCBEEANgJMIAEoAgRBADYCVCABIAEoAgQ2AgwLIAEoAgwhACABQRBqJAAgAAuBAQEBfyMAQSBrIgIkACACIAA2AhggAkIANwMQIAJCfzcDCCACIAE2AgQCQAJAIAIoAhgEQCACKQMIQn9ZDQELIAIoAgRBEkEAEBUgAkEANgIcDAELIAIgAigCGCACKQMQIAIpAwggAigCBBD/ATYCHAsgAigCHCEAIAJBIGokACAAC80BAQJ/IwBBIGsiASQAIAEgADYCGCABQQA6ABcgAUGAgCA2AgwCQCABLQAXQQFxBEAgASABKAIMQQJyNgIMDAELIAEgASgCDDYCDAsgASgCGCEAIAEoAgwhAiABQbYDNgIAIAEgACACIAEQaSIANgIQAkAgAEEASARAIAFBADYCHAwBCyABIAEoAhBBgpgBQYaYASABLQAXQQFxGxCXASIANgIIIABFBEAgAUEANgIcDAELIAEgASgCCDYCHAsgASgCHCEAIAFBIGokACAAC8gCAQF/IwBBgAFrIgEkACABIAA2AnggASABKAJ4KAIYECxBCGoQGSIANgJ0AkAgAEUEQCABKAJ4QQ5BABAVIAFBfzYCfAwBCwJAIAEoAngoAhggAUEQahCcAUUEQCABIAEoAhw2AmwMAQsgAUF/NgJsCyABKAJ0IQAgASABKAJ4KAIYNgIAIABB+JcBIAEQbyABIAEoAnQgASgCbBCGAiIANgJwIABBf0YEQCABKAJ4QQxBtJwBKAIAEBUgASgCdBAWIAFBfzYCfAwBCyABIAEoAnBBgpgBEJcBIgA2AmggAEUEQCABKAJ4QQxBtJwBKAIAEBUgASgCcBBoIAEoAnQQaxogASgCdBAWIAFBfzYCfAwBCyABKAJ4IAEoAmg2AoQBIAEoAnggASgCdDYCgAEgAUEANgJ8CyABKAJ8IQAgAUGAAWokACAAC8AQAQF/IwBB4ABrIgQkACAEIAA2AlQgBCABNgJQIAQgAjcDSCAEIAM2AkQgBCAEKAJUNgJAIAQgBCgCUDYCPAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAQoAkQOEwYHAgwEBQoOAQMJEAsPDQgREQARCyAEQgA3A1gMEQsgBCgCQCgCGEUEQCAEKAJAQRxBABAVIARCfzcDWAwRCyAEIAQoAkAQ/QGsNwNYDBALIAQoAkAoAhgEQCAEKAJAKAIcEFQaIAQoAkBBADYCHAsgBEIANwNYDA8LIAQoAkAoAoQBEFRBAEgEQCAEKAJAQQA2AoQBIAQoAkBBBkG0nAEoAgAQFQsgBCgCQEEANgKEASAEKAJAKAKAASAEKAJAKAIYEAciAEGBYE8Ef0G0nAFBACAAazYCAEF/BSAAC0EASARAIAQoAkBBAkG0nAEoAgAQFSAEQn83A1gMDwsgBCgCQCgCgAEQFiAEKAJAQQA2AoABIARCADcDWAwOCyAEIAQoAkAgBCgCUCAEKQNIEEI3A1gMDQsgBCgCQCgCGBAWIAQoAkAoAoABEBYgBCgCQCgCHARAIAQoAkAoAhwQVBoLIAQoAkAQFiAEQgA3A1gMDAsgBCgCQCgCGARAIAQoAkAoAhgQ/AEhACAEKAJAIAA2AhwgAEUEQCAEKAJAQQtBtJwBKAIAEBUgBEJ/NwNYDA0LCyAEKAJAKQNoQgBWBEAgBCgCQCgCHCAEKAJAKQNoIAQoAkAQlQFBAEgEQCAEQn83A1gMDQsLIAQoAkBCADcDeCAEQgA3A1gMCwsCQCAEKAJAKQNwQgBWBEAgBCAEKAJAKQNwIAQoAkApA3h9NwMwIAQpAzAgBCkDSFYEQCAEIAQpA0g3AzALDAELIAQgBCkDSDcDMAsgBCkDMEL/////D1YEQCAEQv////8PNwMwCyAEIAQoAjwgBCkDMKcgBCgCQCgCHBCLAiIANgIsIABFBEACfyAEKAJAKAIcIgAoAkxBf0wEQCAAKAIADAELIAAoAgALQQV2QQFxBEAgBCgCQEEFQbScASgCABAVIARCfzcDWAwMCwsgBCgCQCIAIAApA3ggBCgCLK18NwN4IAQgBCgCLK03A1gMCgsgBCgCQCgCGBBrQQBIBEAgBCgCQEEWQbScASgCABAVIARCfzcDWAwKCyAEQgA3A1gMCQsgBCgCQCgChAEEQCAEKAJAKAKEARBUGiAEKAJAQQA2AoQBCyAEKAJAKAKAARBrGiAEKAJAKAKAARAWIAQoAkBBADYCgAEgBEIANwNYDAgLIAQCfyAEKQNIQhBUBEAgBCgCQEESQQAQFUEADAELIAQoAlALNgIYIAQoAhhFBEAgBEJ/NwNYDAgLIARBATYCHAJAAkACQAJAAkAgBCgCGCgCCA4DAAIBAwsgBCAEKAIYKQMANwMgDAMLAkAgBCgCQCkDcFAEQCAEKAJAKAIcIAQoAhgpAwBBAiAEKAJAEGdBAEgEQCAEQn83A1gMDQsgBCAEKAJAKAIcEJkBIgI3AyAgAkIAUwRAIAQoAkBBBEG0nAEoAgAQFSAEQn83A1gMDQsgBCAEKQMgIAQoAkApA2h9NwMgIARBADYCHAwBCyAEIAQoAkApA3AgBCgCGCkDAHw3AyALDAILIAQgBCgCQCkDeCAEKAIYKQMAfDcDIAwBCyAEKAJAQRJBABAVIARCfzcDWAwICwJAAkAgBCkDIEIAUw0AIAQoAkApA3BCAFIEQCAEKQMgIAQoAkApA3BWDQELIAQpAyAgBCgCQCkDaHwgBCgCQCkDaFoNAQsgBCgCQEESQQAQFSAEQn83A1gMCAsgBCgCQCAEKQMgNwN4IAQoAhwEQCAEKAJAKAIcIAQoAkApA3ggBCgCQCkDaHwgBCgCQBCVAUEASARAIARCfzcDWAwJCwsgBEIANwNYDAcLIAQCfyAEKQNIQhBUBEAgBCgCQEESQQAQFUEADAELIAQoAlALNgIUIAQoAhRFBEAgBEJ/NwNYDAcLIAQoAkAoAoQBIAQoAhQpAwAgBCgCFCgCCCAEKAJAEGdBAEgEQCAEQn83A1gMBwsgBEIANwNYDAYLIAQpA0hCOFQEQCAEQn83A1gMBgsCfyMAQRBrIgAgBCgCQEHYAGo2AgwgACgCDCgCAAsEQCAEKAJAAn8jAEEQayIAIAQoAkBB2ABqNgIMIAAoAgwoAgALAn8jAEEQayIAIAQoAkBB2ABqNgIMIAAoAgwoAgQLEBUgBEJ/NwNYDAYLIAQoAlAiACAEKAJAIgEpACA3AAAgACABKQBQNwAwIAAgASkASDcAKCAAIAEpAEA3ACAgACABKQA4NwAYIAAgASkAMDcAECAAIAEpACg3AAggBEI4NwNYDAULIAQgBCgCQCkDEDcDWAwECyAEIAQoAkApA3g3A1gMAwsgBCAEKAJAKAKEARCZATcDCCAEKQMIQgBTBEAgBCgCQEEeQbScASgCABAVIARCfzcDWAwDCyAEIAQpAwg3A1gMAgsCQCAEKAJAKAKEASIAKAJMQQBOBEAgACAAKAIAQU9xNgIADAELIAAgACgCAEFPcTYCAAsgBCAEKAJQIAQpA0inIAQoAkAoAoQBEKwCNgIEAkAgBCkDSCAEKAIErVEEQAJ/IAQoAkAoAoQBIgAoAkxBf0wEQCAAKAIADAELIAAoAgALQQV2QQFxRQ0BCyAEKAJAQQZBtJwBKAIAEBUgBEJ/NwNYDAILIAQgBCgCBK03A1gMAQsgBCgCQEEcQQAQFSAEQn83A1gLIAQpA1ghAiAEQeAAaiQAIAILoAkBAX8jAEGgAWsiBCQAIAQgADYCmAEgBEEANgKUASAEIAE3A4gBIAQgAjcDgAEgBEEANgJ8IAQgAzYCeAJAAkAgBCgClAENACAEKAKYAQ0AIAQoAnhBEkEAEBUgBEEANgKcAQwBCyAEKQOAAUIAUwRAIARCADcDgAELAkAgBCkDiAFC////////////AFgEQCAEKQOIASAEKQOAAXwgBCkDiAFaDQELIAQoAnhBEkEAEBUgBEEANgKcAQwBCyAEQYgBEBkiADYCdCAARQRAIAQoAnhBDkEAEBUgBEEANgKcAQwBCyAEKAJ0QQA2AhggBCgCmAEEQCAEKAKYARCQAiEAIAQoAnQgADYCGCAARQRAIAQoAnhBDkEAEBUgBCgCdBAWIARBADYCnAEMAgsLIAQoAnQgBCgClAE2AhwgBCgCdCAEKQOIATcDaCAEKAJ0IAQpA4ABNwNwAkAgBCgCfARAIAQoAnQiACAEKAJ8IgMpAwA3AyAgACADKQMwNwNQIAAgAykDKDcDSCAAIAMpAyA3A0AgACADKQMYNwM4IAAgAykDEDcDMCAAIAMpAwg3AyggBCgCdEEANgIoIAQoAnQiACAAKQMgQv7///8PgzcDIAwBCyAEKAJ0QSBqEDwLIAQoAnQpA3BCAFYEQCAEKAJ0IAQoAnQpA3A3AzggBCgCdCIAIAApAyBCBIQ3AyALIwBBEGsiACAEKAJ0QdgAajYCDCAAKAIMQQA2AgAgACgCDEEANgIEIAAoAgxBADYCCCAEKAJ0QQA2AoABIAQoAnRBADYChAEjAEEQayIAIAQoAnQ2AgwgACgCDEEANgIAIAAoAgxBADYCBCAAKAIMQQA2AgggBEF/NgIEIARBBzYCAEEOIAQQN0I/hCEBIAQoAnQgATcDEAJAIAQoAnQoAhgEQCAEIAQoAnQoAhggBEEYahCcAUEATjoAFyAELQAXQQFxRQRAAkAgBCgCdCkDaFBFDQAgBCgCdCkDcFBFDQAgBCgCdEL//wM3AxALCwwBCyAEAn8CQCAEKAJ0KAIcIgAoAkxBAEgNAAsgACgCPAsgBEEYahCNAkEATjoAFwsCQCAELQAXQQFxRQRAIAQoAnRB2ABqQQVBtJwBKAIAEBUMAQsgBCgCdCkDIEIQg1AEQCAEKAJ0IAQoAlg2AkggBCgCdCIAIAApAyBCEIQ3AyALIAQoAiRBgOADcUGAgAJGBEAgBCgCdEL/gQE3AxAgBCgCdCkDaCAEKAJ0KQNwfCAEKQNAVgRAIAQoAnhBEkEAEBUgBCgCdCgCGBAWIAQoAnQQFiAEQQA2ApwBDAMLIAQoAnQpA3BQBEAgBCgCdCAEKQNAIAQoAnQpA2h9NwM4IAQoAnQiACAAKQMgQgSENwMgAkAgBCgCdCgCGEUNACAEKQOIAVBFDQAgBCgCdEL//wM3AxALCwsLIAQoAnQiACAAKQMQQoCAEIQ3AxAgBEEeIAQoAnQgBCgCeBCQASIANgJwIABFBEAgBCgCdCgCGBAWIAQoAnQQFiAEQQA2ApwBDAELIAQgBCgCcDYCnAELIAQoApwBIQAgBEGgAWokACAACwkAIAAoAjwQBQv3AQEEfyMAQSBrIgMkACADIAE2AhAgAyACIAAoAjAiBEEAR2s2AhQgACgCLCEFIAMgBDYCHCADIAU2AhgCQAJAAn8Cf0EAIAAoAjwgA0EQakECIANBDGoQDSIERQ0AGkG0nAEgBDYCAEF/CwRAIANBfzYCDEF/DAELIAMoAgwiBEEASg0BIAQLIQIgACAAKAIAIAJBMHFBEHNyNgIADAELIAQgAygCFCIGTQRAIAQhAgwBCyAAIAAoAiwiBTYCBCAAIAUgBCAGa2o2AgggACgCMEUNACAAIAVBAWo2AgQgASACakF/aiAFLQAAOgAACyADQSBqJAAgAguBAwEHfyMAQSBrIgMkACADIAAoAhwiBTYCECAAKAIUIQQgAyACNgIcIAMgATYCGCADIAQgBWsiATYCFCABIAJqIQVBAiEHIANBEGohAQJ/AkACQAJ/QQAgACgCPCADQRBqQQIgA0EMahADIgRFDQAaQbScASAENgIAQX8LRQRAA0AgBSADKAIMIgRGDQIgBEF/TA0DIAEgBCABKAIEIghLIgZBA3RqIgkgBCAIQQAgBhtrIgggCSgCAGo2AgAgAUEMQQQgBhtqIgkgCSgCACAIazYCACAFIARrIQUCf0EAIAAoAjwgAUEIaiABIAYbIgEgByAGayIHIANBDGoQAyIERQ0AGkG0nAEgBDYCAEF/C0UNAAsLIANBfzYCDCAFQX9HDQELIAAgACgCLCIBNgIcIAAgATYCFCAAIAEgACgCMGo2AhAgAgwBCyAAQQA2AhwgAEIANwMQIAAgACgCAEEgcjYCAEEAIAdBAkYNABogAiABKAIEawshACADQSBqJAAgAAtgAQF/IwBBEGsiAyQAAn4Cf0EAIAAoAjwgAacgAUIgiKcgAkH/AXEgA0EIahALIgBFDQAaQbScASAANgIAQX8LRQRAIAMpAwgMAQsgA0J/NwMIQn8LIQEgA0EQaiQAIAELoQEBAX8jAEEQayIBJAAgASAANgIIAkAgASgCCCgCJEEDRgRAIAFBADYCDAwBCyABKAIIKAIgQQBLBEAgASgCCBAyQQBIBEAgAUF/NgIMDAILCyABKAIIKAIkBEAgASgCCBBqCyABKAIIQQBCAEEPECJCAFMEQCABQX82AgwMAQsgASgCCEEDNgIkIAFBADYCDAsgASgCDCEAIAFBEGokACAAC9oBAQJ/AkAgAUH/AXEiAwRAIABBA3EEQANAIAAtAAAiAkUNAyACIAFB/wFxRg0DIABBAWoiAEEDcQ0ACwsCQCAAKAIAIgJBf3MgAkH//ft3anFBgIGChHhxDQAgA0GBgoQIbCEDA0AgAiADcyICQX9zIAJB//37d2pxQYCBgoR4cQ0BIAAoAgQhAiAAQQRqIQAgAkH//ft3aiACQX9zcUGAgYKEeHFFDQALCwNAIAAiAi0AACIDBEAgAkEBaiEAIAMgAUH/AXFHDQELCyACDwsgABAsIABqDwsgAAvFAwEBfyMAQTBrIgIkACACIAA2AiggAiABNgIkIAJBADYCECACIAIoAiggAigCKBAsajYCGCACIAIoAhhBf2o2AhwDQCACKAIcIAIoAihPBH8gAigCHCwAAEHYAEYFQQALQQFxBEAgAiACKAIQQQFqNgIQIAIgAigCHEF/ajYCHAwBCwsCQCACKAIQRQRAQbScAUEcNgIAIAJBfzYCLAwBCyACIAIoAhxBAWo2AhwDQCACEIcCNgIMIAIgAigCHDYCFANAIAIoAhQgAigCGEkEQCACIAIoAgxBJHA6AAsCfyACLAALQQpIBEAgAiwAC0EwagwBCyACLAALQdcAagshACACIAIoAhQiAUEBajYCFCABIAA6AAAgAiACKAIMQSRuNgIMDAELCyACKAIoIQAgAgJ/QbYDIAIoAiRBf0YNABogAigCJAs2AgAgAiAAQcKBICACEGkiADYCICAAQQBOBEAgAigCJEF/RwRAIAIoAiggAigCJBAPIgBBgWBPBH9BtJwBQQAgAGs2AgBBAAUgAAsaCyACIAIoAiA2AiwMAgtBtJwBKAIAQRRGDQALIAJBfzYCLAsgAigCLCEAIAJBMGokACAAC1cBAn8jAEEQayIAJAACQCAAQQhqEIgCQQFxBEAgACAAKAIINgIMDAELQcShAS0AAEEBcUUEQEEAEAEQigILIAAQiQI2AgwLIAAoAgwhASAAQRBqJAAgAQulAQEBfyMAQRBrIgEkACABIAA2AgggAUEEOwEGIAFB55cBQQBBABBpIgA2AgACQCAAQQBIBEAgAUEAOgAPDAELIAEoAgAgASgCCCABLwEGEBAiAEGBYE8Ef0G0nAFBACAAazYCAEF/BSAACyABLwEGRwRAIAEoAgAQaCABQQA6AA8MAQsgASgCABBoIAFBAToADwsgAS0AD0EBcSEAIAFBEGokACAAC6EBAQR/QcyaASgCACEAAkBByJoBKAIAIgNFBEAgACAAKAIAQe2cmY4EbEG54ABqQf////8HcSIANgIADAELIABB0JoBKAIAIgJBAnRqIgEgASgCACAAQcChASgCACIBQQJ0aigCAGoiADYCAEHAoQFBACABQQFqIgEgASADRhs2AgBB0JoBQQAgAkEBaiICIAIgA0YbNgIAIABBAXYhAAsgAAujAQIDfwF+QciaASgCACIBRQRAQcyaASgCACAANgIADwtB0JoBQQNBA0EBIAFBB0YbIAFBH0YbNgIAQcChAUEANgIAAkAgAUEATARAQcyaASgCACECDAELQcyaASgCACECIACtIQQDQCACIANBAnRqIARCrf7V5NSF/ajYAH5CAXwiBEIgiD4CACADQQFqIgMgAUcNAAsLIAIgAigCAEEBcjYCAAuxAQECfyACKAJMQQBOBH9BAQVBAAsaIAIgAi0ASiIDQX9qIANyOgBKAn8gASACKAIIIAIoAgQiBGsiA0EBSA0AGiAAIAQgAyABIAMgAUkbIgMQGhogAiACKAIEIANqNgIEIAAgA2ohACABIANrCyIDBEADQAJAIAIQjAJFBEAgAiAAIAMgAigCIBEBACIEQQFqQQFLDQELIAEgA2sPCyAAIARqIQAgAyAEayIDDQALCyABC3wBAn8gACAALQBKIgFBf2ogAXI6AEogACgCFCAAKAIcSwRAIABBAEEAIAAoAiQRAQAaCyAAQQA2AhwgAEIANwMQIAAoAgAiAUEEcQRAIAAgAUEgcjYCAEF/DwsgACAAKAIsIAAoAjBqIgI2AgggACACNgIEIAFBG3RBH3ULdgECfyMAQSBrIgIkAAJ/AkAgACABEAkiA0F4RgRAIAAQjwINAQsgA0GBYE8Ef0G0nAFBACADazYCAEF/BSADCwwBCyACIAAQjgIgAiABEAIiAEGBYE8Ef0G0nAFBACAAazYCAEF/BSAACwshACACQSBqJAAgAAueAQEDfwNAIAAgAmoiAyACQdiXAWotAAA6AAAgAkEORyEEIAJBAWohAiAEDQALIAEEQEEOIQIgASEDA0AgAkEBaiECIANBCUshBCADQQpuIQMgBA0ACyAAIAJqQQA6AAADQCAAIAJBf2oiAmogASABQQpuIgNBCmxrQTByOgAAIAFBCUshBCADIQEgBA0ACw8LIANBMDoAACAAQQA6AA8LNwEBfyMAQSBrIgEkAAJ/QQEgACABQQhqEAgiAEUNABpBtJwBIAA2AgBBAAshACABQSBqJAAgAAsgAQJ/IAAQLEEBaiIBEBkiAkUEQEEADwsgAiAAIAEQGgulAQEBfyMAQSBrIgIgADYCFCACIAE2AhACQCACKAIURQRAIAJCfzcDGAwBCyACKAIQQQhxBEAgAiACKAIUKQMwNwMIA0BBACEAIAIpAwhCAFYEfyACKAIUKAJAIAIpAwhCAX2nQQR0aigCAEUFQQALQQFxBEAgAiACKQMIQn98NwMIDAELCyACIAIpAwg3AxgMAQsgAiACKAIUKQMwNwMYCyACKQMYC/IBAQF/IwBBIGsiAyQAIAMgADYCFCADIAE2AhAgAyACNwMIAkAgAygCFEUEQCADQn83AxgMAQsgAygCFCgCBARAIANCfzcDGAwBCyADKQMIQv///////////wBWBEAgAygCFEEEakESQQAQFSADQn83AxgMAQsCQCADKAIULQAQQQFxRQRAIAMpAwhQRQ0BCyADQgA3AxgMAQsgAyADKAIUKAIUIAMoAhAgAykDCBAvIgI3AwAgAkIAUwRAIAMoAhRBBGogAygCFCgCFBAYIANCfzcDGAwBCyADIAMpAwA3AxgLIAMpAxghAiADQSBqJAAgAgtHAQF/IwBBIGsiAyQAIAMgADYCHCADIAE3AxAgAyACNgIMIAMoAhwgAykDECADKAIMIAMoAhwoAhwQnQEhACADQSBqJAAgAAt/AgF/AX4jAEEgayIDJAAgAyAANgIYIAMgATYCFCADIAI2AhAgAyADKAIYIAMoAhQgAygCEBBuIgQ3AwgCQCAEQgBTBEAgA0EANgIcDAELIAMgAygCGCADKQMIIAMoAhAgAygCGCgCHBCdATYCHAsgAygCHCEAIANBIGokACAAC6oBAQF/IwBBEGsiASQAIAEgADYCCCABQRgQGSIANgIEAkAgAEUEQCABKAIIQQhqQQ5BABAVIAFBADYCDAwBCyABKAIEIAEoAgg2AgAjAEEQayIAIAEoAgRBBGo2AgwgACgCDEEANgIAIAAoAgxBADYCBCAAKAIMQQA2AgggASgCBEEAOgAQIAEoAgRBADYCFCABIAEoAgQ2AgwLIAEoAgwhACABQRBqJAAgAAvVAwEBfyMAQSBrIgQkACAEIAA2AhggBCABNwMQIAQgAjYCDCAEIAM2AggCQCAEKAIYIAQpAxBBAEEAEEVFBEAgBEF/NgIcDAELIAQoAhgoAhhBAnEEQCAEKAIYQQhqQRlBABAVIARBfzYCHAwBCyAEKAIYKAJAIAQpAxCnQQR0aigCCARAIAQoAhgoAkAgBCkDEKdBBHRqKAIIIAQoAgwQbUEASARAIAQoAhhBCGpBD0EAEBUgBEF/NgIcDAILIARBADYCHAwBCyAEIAQoAhgoAkAgBCkDEKdBBHRqNgIEQQEhACAEIAQoAgQoAgAEfyAEKAIMIAQoAgQoAgAoAhRHBUEBC0EBcTYCAAJAIAQoAgAEQCAEKAIEKAIERQRAIAQoAgQoAgAQRiEAIAQoAgQgADYCBCAARQRAIAQoAhhBCGpBDkEAEBUgBEF/NgIcDAQLCyAEKAIEKAIEIAQoAgw2AhQgBCgCBCgCBCIAIAAoAgBBIHI2AgAMAQsgBCgCBCgCBARAIAQoAgQoAgQiACAAKAIAQV9xNgIAIAQoAgQoAgQoAgBFBEAgBCgCBCgCBBA6IAQoAgRBADYCBAsLCyAEQQA2AhwLIAQoAhwhACAEQSBqJAAgAAsHACAAKAIICxgBAX8jAEEQayIBIAA2AgwgASgCDEEEagsYAQF/IwBBEGsiASAANgIMIAEoAgxBCGoLgwECAX8BfiMAQSBrIgQkACAEIAA2AhQgBCABNgIQIAQgAjYCDCAEIAM2AggCQAJAIAQoAhAEQCAEKAIMDQELIAQoAhRBCGpBEkEAEBUgBEJ/NwMYDAELIAQgBCgCFCAEKAIQIAQoAgwgBCgCCBCgATcDGAsgBCkDGCEFIARBIGokACAFC2kBAX8jAEEQayIBJAAgASAANgIMIAEoAgwoAhQEQCABKAIMKAIUEBwLIAFBADYCCCABKAIMKAIEBEAgASABKAIMKAIENgIICyABKAIMQQRqEDggASgCDBAWIAEoAgghACABQRBqJAAgAAu4AwIBfwF+IwBBMGsiAyQAIAMgADYCJCADIAE2AiAgAyACNgIcAkAgAygCJCgCGEECcQRAIAMoAiRBCGpBGUEAEBUgA0J/NwMoDAELIAMoAiBFBEAgAygCJEEIakESQQAQFSADQn83AygMAQsgA0EANgIMIAMgAygCIBAsNgIYIAMoAiAgAygCGEEBa2osAABBL0cEQCADIAMoAhhBAmoQGSIANgIMIABFBEAgAygCJEEIakEOQQAQFSADQn83AygMAgsgAygCDCADKAIgEJ8CIAMoAgwgAygCGGpBLzoAACADKAIMIAMoAhhBAWpqQQA6AAALIAMgAygCJEEAQgBBABB5IgA2AgggAEUEQCADKAIMEBYgA0J/NwMoDAELIAMgAygCJAJ/IAMoAgwEQCADKAIMDAELIAMoAiALIAMoAgggAygCHBCgATcDECADKAIMEBYCQCADKQMQQgBTBEAgAygCCBAcDAELIAMoAiQgAykDEEEAQQNBgID8jwQQnwFBAEgEQCADKAIkIAMpAxAQoQEaIANCfzcDKAwCCwsgAyADKQMQNwMoCyADKQMoIQQgA0EwaiQAIAQLmQgBAX8jAEFAaiIEJAAgBCAANgI4IAQgATcDMCAEIAI2AiwgBCADNgIoAkAgBCkDMCAEKAI4KQMwWgRAIAQoAjhBCGpBEkEAEBUgBEF/NgI8DAELIAQoAjgoAhhBAnEEQCAEKAI4QQhqQRlBABAVIARBfzYCPAwBCwJAAkAgBCgCLEUNACAEKAIsLAAARQ0AIAQgBCgCLCAEKAIsECxB//8DcSAEKAIoIAQoAjhBCGoQUSIANgIgIABFBEAgBEF/NgI8DAMLAkAgBCgCKEGAMHENACAEKAIgQQAQO0EDRw0AIAQoAiBBAjYCCAsMAQsgBEEANgIgCyAEIAQoAjggBCgCLEEAQQAQVSIBNwMQAkAgAUIAUw0AIAQpAxAgBCkDMFENACAEKAIgECYgBCgCOEEIakEKQQAQFSAEQX82AjwMAQsCQCAEKQMQQgBTDQAgBCkDECAEKQMwUg0AIAQoAiAQJiAEQQA2AjwMAQsgBCAEKAI4KAJAIAQpAzCnQQR0ajYCJAJAIAQoAiQoAgAEQCAEIAQoAiQoAgAoAjAgBCgCIBCHAUEARzoAHwwBCyAEQQA6AB8LAkAgBC0AH0EBcQ0AIAQoAiQoAgQNACAEKAIkKAIAEEYhACAEKAIkIAA2AgQgAEUEQCAEKAI4QQhqQQ5BABAVIAQoAiAQJiAEQX82AjwMAgsLIAQCfyAELQAfQQFxBEAgBCgCJCgCACgCMAwBCyAEKAIgC0EAQQAgBCgCOEEIahBHIgA2AgggAEUEQCAEKAIgECYgBEF/NgI8DAELAkAgBCgCJCgCBARAIAQgBCgCJCgCBCgCMDYCBAwBCwJAIAQoAiQoAgAEQCAEIAQoAiQoAgAoAjA2AgQMAQsgBEEANgIECwsCQCAEKAIEBEAgBCAEKAIEQQBBACAEKAI4QQhqEEciADYCDCAARQRAIAQoAiAQJiAEQX82AjwMAwsMAQsgBEEANgIMCyAEKAI4KAJQIAQoAgggBCkDMEEAIAQoAjhBCGoQfUEBcUUEQCAEKAIgECYgBEF/NgI8DAELIAQoAgwEQCAEKAI4KAJQIAQoAgxBABBZGgsCQCAELQAfQQFxBEAgBCgCJCgCBARAIAQoAiQoAgQoAgBBAnEEQCAEKAIkKAIEKAIwECYgBCgCJCgCBCIAIAAoAgBBfXE2AgACQCAEKAIkKAIEKAIARQRAIAQoAiQoAgQQOiAEKAIkQQA2AgQMAQsgBCgCJCgCBCAEKAIkKAIAKAIwNgIwCwsLIAQoAiAQJgwBCyAEKAIkKAIEKAIAQQJxBEAgBCgCJCgCBCgCMBAmCyAEKAIkKAIEIgAgACgCAEECcjYCACAEKAIkKAIEIAQoAiA2AjALIARBADYCPAsgBCgCPCEAIARBQGskACAAC98CAgF/AX4jAEFAaiIBJAAgASAANgI0AkAgASgCNCkDMEIBfCABKAI0KQM4WgRAIAEgASgCNCkDODcDGCABIAEpAxhCAYY3AxACQCABKQMQQhBUBEAgAUIQNwMQDAELIAEpAxBCgAhWBEAgAUKACDcDEAsLIAEgASkDECABKQMYfDcDGCABIAEpAxinQQR0rTcDCCABKAI0KQM4p0EEdK0gASkDCFYEQCABKAI0QQhqQQ5BABAVIAFCfzcDOAwCCyABIAEoAjQoAkAgASkDGKdBBHQQTTYCJCABKAIkRQRAIAEoAjRBCGpBDkEAEBUgAUJ/NwM4DAILIAEoAjQgASgCJDYCQCABKAI0IAEpAxg3AzgLIAEoAjQiACkDMCECIAAgAkIBfDcDMCABIAI3AyggASgCNCgCQCABKQMop0EEdGoQjAEgASABKQMoNwM4CyABKQM4IQIgAUFAayQAIAILyAEBAX8CQAJAIAAgAXNBA3ENACABQQNxBEADQCAAIAEtAAAiAjoAACACRQ0DIABBAWohACABQQFqIgFBA3ENAAsLIAEoAgAiAkF/cyACQf/9+3dqcUGAgYKEeHENAANAIAAgAjYCACABKAIEIQIgAEEEaiEAIAFBBGohASACQf/9+3dqIAJBf3NxQYCBgoR4cUUNAAsLIAAgAS0AACICOgAAIAJFDQADQCAAIAEtAAEiAjoAASAAQQFqIQAgAUEBaiEBIAINAAsLC5cEAQF/IwBBMGsiAiQAIAIgADYCKCACIAE3AyAgAkEBNgIcAkAgAikDICACKAIoKQMwWgRAIAIoAihBCGpBEkEAEBUgAkF/NgIsDAELAkAgAigCHA0AIAIoAigoAkAgAikDIKdBBHRqKAIERQ0AIAIoAigoAkAgAikDIKdBBHRqKAIEKAIAQQJxRQ0AAkAgAigCKCgCQCACKQMgp0EEdGooAgAEQCACIAIoAiggAikDIEEIIAIoAihBCGoQTyIANgIMIABFBEAgAkF/NgIsDAQLIAIgAigCKCACKAIMQQBBABBVNwMQAkAgAikDEEIAUw0AIAIpAxAgAikDIFENACACKAIoQQhqQQpBABAVIAJBfzYCLAwECwwBCyACQQA2AgwLIAIgAigCKCACKQMgQQAgAigCKEEIahBPIgA2AgggAEUEQCACQX82AiwMAgsgAigCDARAIAIoAigoAlAgAigCDCACKQMgQQAgAigCKEEIahB9QQFxRQRAIAJBfzYCLAwDCwsgAigCKCgCUCACKAIIIAIoAihBCGoQWUEBcUUEQCACKAIoKAJQIAIoAgxBABBZGiACQX82AiwMAgsLIAIoAigoAkAgAikDIKdBBHRqKAIEEDogAigCKCgCQCACKQMgp0EEdGpBADYCBCACKAIoKAJAIAIpAyCnQQR0ahBjIAJBADYCLAsgAigCLCEAIAJBMGokACAACyYBAX8DQCABRQRAQQAPCyAAIAFBf2oiAWoiAi0AAEEvRw0ACyACC6kBAQN/AkAgAC0AACICRQ0AA0AgAS0AACIERQRAIAIhAwwCCwJAIAIgBEYNACACQSByIAIgAkG/f2pBGkkbIAEtAAAiAkEgciACIAJBv39qQRpJG0YNACAALQAAIQMMAgsgAUEBaiEBIAAtAAEhAiAAQQFqIQAgAg0ACwsgA0H/AXEiAEEgciAAIABBv39qQRpJGyABLQAAIgBBIHIgACAAQb9/akEaSRtrC+gDAQN/IwBBsAFrIgEkACABIAA2AqgBIAEoAqgBEDgCQAJAIAEoAqgBKAIAQQBOBEAgASgCqAEoAgBBoA4oAgBIDQELIAEgASgCqAEoAgA2AhAgAUEgakG8lwEgAUEQahBvIAFBADYCpAEgASABQSBqNgKgAQwBCyABIAEoAqgBKAIAQQJ0QaANaigCADYCpAECQAJAAkACQCABKAKoASgCAEECdEGwDmooAgBBf2oOAgABAgsgASABKAKoASgCBEGQmgEoAgAQpAI2AqABDAILIwBBEGsiACABKAKoASgCBDYCDCABQQAgACgCDGtBAnRB2NQAaigCADYCoAEMAQsgAUEANgKgAQsLAkAgASgCoAFFBEAgASABKAKkATYCrAEMAQsgASABKAKgARAsAn8gASgCpAEEQCABKAKkARAsQQJqDAELQQALakEBahAZIgA2AhwgAEUEQCABQdgNKAIANgKsAQwBCyABKAIcIQACfyABKAKkAQRAIAEoAqQBDAELQdSXAQshAkHVlwFB1JcBIAEoAqQBGyEDIAEgASgCoAE2AgggASADNgIEIAEgAjYCACAAQc2XASABEG8gASgCqAEgASgCHDYCCCABIAEoAhw2AqwBCyABKAKsASEAIAFBsAFqJAAgAAtxAQN/AkACQANAIAAgAkHQiAFqLQAARwRAQdcAIQMgAkEBaiICQdcARw0BDAILCyACIgMNAEGwiQEhAAwBC0GwiQEhAgNAIAItAAAhBCACQQFqIgAhAiAEDQAgACECIANBf2oiAw0ACwsgASgCFBogAAszAQF/IAAoAhQiAyABIAIgACgCECADayIBIAEgAksbIgEQGhogACAAKAIUIAFqNgIUIAILigEBAn8jAEGgAWsiAyQAIANBCGpBuIcBQZABEBoaIAMgADYCNCADIAA2AhwgA0F+IABrIgRB/////wdB/////wcgBEsbIgQ2AjggAyAAIARqIgA2AiQgAyAANgIYIANBCGogASACEKsCIAQEQCADKAIcIgAgACADKAIYRmtBADoAAAsgA0GgAWokAAspACABIAEoAgBBD2pBcHEiAUEQajYCACAAIAEpAwAgASkDCBCxAjkDAAuKFwMSfwJ+AXwjAEGwBGsiCSQAIAlBADYCLAJ/IAG9IhhCf1cEQEEBIRIgAZoiAb0hGEGQhwEMAQtBASESQZOHASAEQYAQcQ0AGkGWhwEgBEEBcQ0AGkEAIRJBASETQZGHAQshFQJAIBhCgICAgICAgPj/AINCgICAgICAgPj/AFEEQCAAQSAgAiASQQNqIg0gBEH//3txECcgACAVIBIQIyAAQauHAUGvhwEgBUEgcSIDG0GjhwFBp4cBIAMbIAEgAWIbQQMQIwwBCyAJQRBqIRACQAJ/AkAgASAJQSxqEKQBIgEgAaAiAUQAAAAAAAAAAGIEQCAJIAkoAiwiBkF/ajYCLCAFQSByIhZB4QBHDQEMAwsgBUEgciIWQeEARg0CIAkoAiwhC0EGIAMgA0EASBsMAQsgCSAGQWNqIgs2AiwgAUQAAAAAAACwQaIhAUEGIAMgA0EASBsLIQogCUEwaiAJQdACaiALQQBIGyIPIQgDQCAIAn8gAUQAAAAAAADwQWMgAUQAAAAAAAAAAGZxBEAgAasMAQtBAAsiAzYCACAIQQRqIQggASADuKFEAAAAAGXNzUGiIgFEAAAAAAAAAABiDQALAkAgC0EBSARAIAshAyAIIQYgDyEHDAELIA8hByALIQMDQCADQR0gA0EdSBshDAJAIAhBfGoiBiAHSQ0AIAytIRlCACEYA0AgBiAYQv////8PgyAGNQIAIBmGfCIYIBhCgJTr3AOAIhhCgJTr3AN+fT4CACAGQXxqIgYgB08NAAsgGKciA0UNACAHQXxqIgcgAzYCAAsDQCAIIgYgB0sEQCAGQXxqIggoAgBFDQELCyAJIAkoAiwgDGsiAzYCLCAGIQggA0EASg0ACwsgA0F/TARAIApBGWpBCW1BAWohESAWQeYARiENA0BBCUEAIANrIANBd0gbIRcCQCAHIAZPBEAgByAHQQRqIAcoAgAbIQcMAQtBgJTr3AMgF3YhFEF/IBd0QX9zIQ5BACEDIAchCANAIAggAyAIKAIAIgwgF3ZqNgIAIAwgDnEgFGwhAyAIQQRqIgggBkkNAAsgByAHQQRqIAcoAgAbIQcgA0UNACAGIAM2AgAgBkEEaiEGCyAJIAkoAiwgF2oiAzYCLCAPIAcgDRsiCCARQQJ0aiAGIAYgCGtBAnUgEUobIQYgA0EASA0ACwtBACEIAkAgByAGTw0AIA8gB2tBAnVBCWwhCEEKIQMgBygCACIMQQpJDQADQCAIQQFqIQggDCADQQpsIgNPDQALCyAKQQAgCCAWQeYARhtrIBZB5wBGIApBAEdxayIDIAYgD2tBAnVBCWxBd2pIBEAgA0GAyABqIg5BCW0iDEECdCAJQTBqQQRyIAlB1AJqIAtBAEgbakGAYGohDUEKIQMgDiAMQQlsayIOQQdMBEADQCADQQpsIQMgDkEBaiIOQQhHDQALCwJAQQAgBiANQQRqIhFGIA0oAgAiDiAOIANuIgwgA2xrIhQbDQBEAAAAAAAA4D9EAAAAAAAA8D9EAAAAAAAA+D8gFCADQQF2IgtGG0QAAAAAAAD4PyAGIBFGGyAUIAtJGyEaRAEAAAAAAEBDRAAAAAAAAEBDIAxBAXEbIQECQCATDQAgFS0AAEEtRw0AIBqaIRogAZohAQsgDSAOIBRrIgs2AgAgASAaoCABYQ0AIA0gAyALaiIDNgIAIANBgJTr3ANPBEADQCANQQA2AgAgDUF8aiINIAdJBEAgB0F8aiIHQQA2AgALIA0gDSgCAEEBaiIDNgIAIANB/5Pr3ANLDQALCyAPIAdrQQJ1QQlsIQhBCiEDIAcoAgAiC0EKSQ0AA0AgCEEBaiEIIAsgA0EKbCIDTw0ACwsgDUEEaiIDIAYgBiADSxshBgsDQCAGIgsgB00iDEUEQCALQXxqIgYoAgBFDQELCwJAIBZB5wBHBEAgBEEIcSETDAELIAhBf3NBfyAKQQEgChsiBiAISiAIQXtKcSIDGyAGaiEKQX9BfiADGyAFaiEFIARBCHEiEw0AQXchBgJAIAwNACALQXxqKAIAIgxFDQBBCiEOQQAhBiAMQQpwDQADQCAGIgNBAWohBiAMIA5BCmwiDnBFDQALIANBf3MhBgsgCyAPa0ECdUEJbCEDIAVBX3FBxgBGBEBBACETIAogAyAGakF3aiIDQQAgA0EAShsiAyAKIANIGyEKDAELQQAhEyAKIAMgCGogBmpBd2oiA0EAIANBAEobIgMgCiADSBshCgsgCiATciIUQQBHIQ4gAEEgIAICfyAIQQAgCEEAShsgBUFfcSIMQcYARg0AGiAQIAggCEEfdSIDaiADc60gEBBDIgZrQQFMBEADQCAGQX9qIgZBMDoAACAQIAZrQQJIDQALCyAGQX5qIhEgBToAACAGQX9qQS1BKyAIQQBIGzoAACAQIBFrCyAKIBJqIA5qakEBaiINIAQQJyAAIBUgEhAjIABBMCACIA0gBEGAgARzECcCQAJAAkAgDEHGAEYEQCAJQRBqQQhyIQMgCUEQakEJciEIIA8gByAHIA9LGyIFIQcDQCAHNQIAIAgQQyEGAkAgBSAHRwRAIAYgCUEQak0NAQNAIAZBf2oiBkEwOgAAIAYgCUEQaksNAAsMAQsgBiAIRw0AIAlBMDoAGCADIQYLIAAgBiAIIAZrECMgB0EEaiIHIA9NDQALIBQEQCAAQbOHAUEBECMLIAcgC08NASAKQQFIDQEDQCAHNQIAIAgQQyIGIAlBEGpLBEADQCAGQX9qIgZBMDoAACAGIAlBEGpLDQALCyAAIAYgCkEJIApBCUgbECMgCkF3aiEGIAdBBGoiByALTw0DIApBCUohAyAGIQogAw0ACwwCCwJAIApBAEgNACALIAdBBGogCyAHSxshBSAJQRBqQQhyIQMgCUEQakEJciELIAchCANAIAsgCDUCACALEEMiBkYEQCAJQTA6ABggAyEGCwJAIAcgCEcEQCAGIAlBEGpNDQEDQCAGQX9qIgZBMDoAACAGIAlBEGpLDQALDAELIAAgBkEBECMgBkEBaiEGIBNFQQAgCkEBSBsNACAAQbOHAUEBECMLIAAgBiALIAZrIgYgCiAKIAZKGxAjIAogBmshCiAIQQRqIgggBU8NASAKQX9KDQALCyAAQTAgCkESakESQQAQJyAAIBEgECARaxAjDAILIAohBgsgAEEwIAZBCWpBCUEAECcLDAELIBVBCWogFSAFQSBxIgsbIQoCQCADQQtLDQBBDCADayIGRQ0ARAAAAAAAACBAIRoDQCAaRAAAAAAAADBAoiEaIAZBf2oiBg0ACyAKLQAAQS1GBEAgGiABmiAaoaCaIQEMAQsgASAaoCAaoSEBCyAQIAkoAiwiBiAGQR91IgZqIAZzrSAQEEMiBkYEQCAJQTA6AA8gCUEPaiEGCyASQQJyIQ8gCSgCLCEIIAZBfmoiDCAFQQ9qOgAAIAZBf2pBLUErIAhBAEgbOgAAIARBCHEhCCAJQRBqIQcDQCAHIgUCfyABmUQAAAAAAADgQWMEQCABqgwBC0GAgICAeAsiBkGAhwFqLQAAIAtyOgAAIAEgBrehRAAAAAAAADBAoiEBAkAgBUEBaiIHIAlBEGprQQFHDQACQCAIDQAgA0EASg0AIAFEAAAAAAAAAABhDQELIAVBLjoAASAFQQJqIQcLIAFEAAAAAAAAAABiDQALIABBICACIA8CfwJAIANFDQAgByAJa0FuaiADTg0AIAMgEGogDGtBAmoMAQsgECAJQRBqayAMayAHagsiA2oiDSAEECcgACAKIA8QIyAAQTAgAiANIARBgIAEcxAnIAAgCUEQaiAHIAlBEGprIgUQIyAAQTAgAyAFIBAgDGsiA2prQQBBABAnIAAgDCADECMLIABBICACIA0gBEGAwABzECcgCUGwBGokACACIA0gDSACSBsLLQAgAFBFBEADQCABQX9qIgEgAKdBB3FBMHI6AAAgAEIDiCIAQgBSDQALCyABCzUAIABQRQRAA0AgAUF/aiIBIACnQQ9xQYCHAWotAAAgAnI6AAAgAEIEiCIAQgBSDQALCyABC8sCAQN/IwBB0AFrIgMkACADIAI2AswBQQAhAiADQaABakEAQSgQMyADIAMoAswBNgLIAQJAQQAgASADQcgBaiADQdAAaiADQaABahBwQQBIDQAgACgCTEEATgRAQQEhAgsgACgCACEEIAAsAEpBAEwEQCAAIARBX3E2AgALIARBIHEhBQJ/IAAoAjAEQCAAIAEgA0HIAWogA0HQAGogA0GgAWoQcAwBCyAAQdAANgIwIAAgA0HQAGo2AhAgACADNgIcIAAgAzYCFCAAKAIsIQQgACADNgIsIAAgASADQcgBaiADQdAAaiADQaABahBwIARFDQAaIABBAEEAIAAoAiQRAQAaIABBADYCMCAAIAQ2AiwgAEEANgIcIABBADYCECAAKAIUGiAAQQA2AhRBAAsaIAAgACgCACAFcjYCACACRQ0ACyADQdABaiQACy8AIAECfyACKAJMQX9MBEAgACABIAIQcQwBCyAAIAEgAhBxCyIARgRAIAEPCyAAC1kBAX8gACAALQBKIgFBf2ogAXI6AEogACgCACIBQQhxBEAgACABQSByNgIAQX8PCyAAQgA3AgQgACAAKAIsIgE2AhwgACABNgIUIAAgASAAKAIwajYCEEEACwYAQaShAQsGAEGgoQELBgBBmKEBC9kDAgJ/An4jAEEgayICJAACQCABQv///////////wCDIgVCgICAgICAwP9DfCAFQoCAgICAgMCAvH98VARAIAFCBIYgAEI8iIQhBCAAQv//////////D4MiAEKBgICAgICAgAhaBEAgBEKBgICAgICAgMAAfCEEDAILIARCgICAgICAgIBAfSEEIABCgICAgICAgIAIhUIAUg0BIARCAYMgBHwhBAwBCyAAUCAFQoCAgICAgMD//wBUIAVCgICAgICAwP//AFEbRQRAIAFCBIYgAEI8iIRC/////////wODQoCAgICAgID8/wCEIQQMAQtCgICAgICAgPj/ACEEIAVC////////v//DAFYNAEIAIQQgBUIwiKciA0GR9wBJDQAgAkEQaiAAIAFC////////P4NCgICAgICAwACEIgQgA0H/iH9qELMCIAIgACAEQYH4ACADaxCyAiACKQMIQgSGIAIpAwAiAEI8iIQhBCACKQMQIAIpAxiEQgBSrSAAQv//////////D4OEIgBCgYCAgICAgIAIWgRAIARCAXwhBAwBCyAAQoCAgICAgICACIVCAFINACAEQgGDIAR8IQQLIAJBIGokACAEIAFCgICAgICAgICAf4OEvwtQAQF+AkAgA0HAAHEEQCACIANBQGqtiCEBQgAhAgwBCyADRQ0AIAJBwAAgA2uthiABIAOtIgSIhCEBIAIgBIghAgsgACABNwMAIAAgAjcDCAtQAQF+AkAgA0HAAHEEQCABIANBQGqthiECQgAhAQwBCyADRQ0AIAIgA60iBIYgAUHAACADa62IhCECIAEgBIYhAQsgACABNwMAIAAgAjcDCAuLAgACQCAABH8gAUH/AE0NAQJAQZCaASgCACgCAEUEQCABQYB/cUGAvwNGDQMMAQsgAUH/D00EQCAAIAFBP3FBgAFyOgABIAAgAUEGdkHAAXI6AABBAg8LIAFBgLADT0EAIAFBgEBxQYDAA0cbRQRAIAAgAUE/cUGAAXI6AAIgACABQQx2QeABcjoAACAAIAFBBnZBP3FBgAFyOgABQQMPCyABQYCAfGpB//8/TQRAIAAgAUE/cUGAAXI6AAMgACABQRJ2QfABcjoAACAAIAFBBnZBP3FBgAFyOgACIAAgAUEMdkE/cUGAAXI6AAFBBA8LC0G0nAFBGTYCAEF/BUEBCw8LIAAgAToAAEEBC74CAQF/IwBBwMAAayIDJAAgAyAANgK4QCADIAE2ArRAIAMgAjcDqEACQCADKAK0QBBJQQBIBEAgAygCuEBBCGogAygCtEAQGCADQX82ArxADAELIANBADYCDCADQgA3AxADQAJAIAMgAygCtEAgA0EgakKAwAAQLyICNwMYIAJCAFcNACADKAK4QCADQSBqIAMpAxgQNkEASARAIANBfzYCDAUgAykDGEKAwABSDQIgAygCuEAoAlRFDQIgAykDqEBCAFcNAiADIAMpAxggAykDEHw3AxAgAygCuEAoAlQgAykDELkgAykDqEC5oxBYDAILCwsgAykDGEIAUwRAIAMoArhAQQhqIAMoArRAEBggA0F/NgIMCyADKAK0QBAyGiADIAMoAgw2ArxACyADKAK8QCEAIANBwMAAaiQAIAALqgEBAX8jAEEwayIDJAAgAyAANgIoIAMgATYCJCADIAI3AxggAyADKAIoKAIAEDUiAjcDEAJAIAJCAFMEQCADQX82AiwMAQsgAyADKAIoIAMoAiQgAykDGBCQAyICNwMAIAJCAFMEQCADQX82AiwMAQsgAyADKAIoKAIAEDUiAjcDCCACQgBTBEAgA0F/NgIsDAELIANBADYCLAsgAygCLCEAIANBMGokACAAC/4BAQF/IwBBoMAAayICJAAgAiAANgKYQCACIAE3A5BAIAIgAikDkEC6OQMAAkADQCACKQOQQEIAVgRAIAICfkKAwAAgAikDkEBCgMAAVg0AGiACKQOQQAs+AgwgAigCmEAoAgAgAkEQaiACKAIMrSACKAKYQEEIahBhQQBIBEAgAkF/NgKcQAwDCyACKAKYQCACQRBqIAIoAgytEDZBAEgEQCACQX82ApxADAMFIAIgAikDkEAgAjUCDH03A5BAIAIoAphAKAJUIAIrAwAgAikDkEC6oSACKwMAoxBYDAILAAsLIAJBADYCnEALIAIoApxAIQAgAkGgwABqJAAgAAvnEQIBfwF+IwBBoAFrIgMkACADIAA2ApgBIAMgATYClAEgAyACNgKQAQJAIAMoApQBIANBOGoQOUEASARAIAMoApgBQQhqIAMoApQBEBggA0F/NgKcAQwBCyADKQM4QsAAg1AEQCADIAMpAzhCwACENwM4IANBADsBaAsCQAJAIAMoApABKAIQQX9HBEAgAygCkAEoAhBBfkcNAQsgAy8BaEUNACADKAKQASADLwFoNgIQDAELAkACQCADKAKQASgCEA0AIAMpAzhCBINQDQAgAyADKQM4QgiENwM4IAMgAykDUDcDWAwBCyADIAMpAzhC9////w+DNwM4CwsgAykDOEKAAYNQBEAgAyADKQM4QoABhDcDOCADQQA7AWoLIANBgAI2AiQCQCADKQM4QgSDUARAIAMgAygCJEGACHI2AiQgA0J/NwNwDAELIAMoApABIAMpA1A3AyggAyADKQNQNwNwAkAgAykDOEIIg1AEQAJAAkACQAJAAkACfwJAIAMoApABKAIQQX9HBEAgAygCkAEoAhBBfkcNAQtBCAwBCyADKAKQASgCEAtB//8DcQ4NAgMDAwMDAwMBAwMDAAMLIANClMLk8w83AxAMAwsgA0KDg7D/DzcDEAwCCyADQv////8PNwMQDAELIANCADcDEAsgAykDUCADKQMQVgRAIAMgAygCJEGACHI2AiQLDAELIAMoApABIAMpA1g3AyALCyADIAMoApgBKAIAEDUiBDcDiAEgBEIAUwRAIAMoApgBQQhqIAMoApgBKAIAEBggA0F/NgKcAQwBCyADKAKQASIAIAAvAQxB9/8DcTsBDCADIAMoApgBIAMoApABIAMoAiQQXiIANgIoIABBAEgEQCADQX82ApwBDAELIAMgAy8BaAJ/AkAgAygCkAEoAhBBf0cEQCADKAKQASgCEEF+Rw0BC0EIDAELIAMoApABKAIQC0H//wNxRzoAIiADIAMtACJBAXEEfyADLwFoQQBHBUEAC0EBcToAISADIAMvAWgEfyADLQAhBUEBC0EBcToAICADIAMtACJBAXEEfyADKAKQASgCEEEARwVBAAtBAXE6AB8gAwJ/QQEgAy0AIkEBcQ0AGkEBIAMoApABKAIAQYABcQ0AGiADKAKQAS8BUiADLwFqRwtBAXE6AB4gAyADLQAeQQFxBH8gAy8BakEARwVBAAtBAXE6AB0gAyADLQAeQQFxBH8gAygCkAEvAVJBAEcFQQALQQFxOgAcIAMgAygClAE2AjQjAEEQayIAIAMoAjQ2AgwgACgCDCIAIAAoAjBBAWo2AjAgAy0AHUEBcQRAIAMgAy8BakEAEHciADYCDCAARQRAIAMoApgBQQhqQRhBABAVIAMoAjQQHCADQX82ApwBDAILIAMgAygCmAEgAygCNCADLwFqQQAgAygCmAEoAhwgAygCDBEGACIANgIwIABFBEAgAygCNBAcIANBfzYCnAEMAgsgAygCNBAcIAMgAygCMDYCNAsgAy0AIUEBcQRAIAMgAygCmAEgAygCNCADLwFoEKsBIgA2AjAgAEUEQCADKAI0EBwgA0F/NgKcAQwCCyADKAI0EBwgAyADKAIwNgI0CyADLQAgQQFxBEAgAyADKAKYASADKAI0QQAQqgEiADYCMCAARQRAIAMoAjQQHCADQX82ApwBDAILIAMoAjQQHCADIAMoAjA2AjQLIAMtAB9BAXEEQCADIAMoApgBIAMoAjQgAygCkAEoAhAgAygCkAEvAVAQwgIiADYCMCAARQRAIAMoAjQQHCADQX82ApwBDAILIAMoAjQQHCADIAMoAjA2AjQLIAMtABxBAXEEQCADQQA2AgQCQCADKAKQASgCVARAIAMgAygCkAEoAlQ2AgQMAQsgAygCmAEoAhwEQCADIAMoApgBKAIcNgIECwsgAyADKAKQAS8BUkEBEHciADYCCCAARQRAIAMoApgBQQhqQRhBABAVIAMoAjQQHCADQX82ApwBDAILIAMgAygCmAEgAygCNCADKAKQAS8BUkEBIAMoAgQgAygCCBEGACIANgIwIABFBEAgAygCNBAcIANBfzYCnAEMAgsgAygCNBAcIAMgAygCMDYCNAsgAyADKAKYASgCABA1IgQ3A4ABIARCAFMEQCADKAKYAUEIaiADKAKYASgCABAYIANBfzYCnAEMAQsgAyADKAKYASADKAI0IAMpA3AQtQI2AiwgAygCNCADQThqEDlBAEgEQCADKAKYAUEIaiADKAI0EBggA0F/NgIsCyADIAMoAjQQuwIiADoAIyAAQRh0QRh1QQBIBEAgAygCmAFBCGogAygCNBAYIANBfzYCLAsgAygCNBAcIAMoAixBAEgEQCADQX82ApwBDAELIAMgAygCmAEoAgAQNSIENwN4IARCAFMEQCADKAKYAUEIaiADKAKYASgCABAYIANBfzYCnAEMAQsgAygCmAEoAgAgAykDiAEQqAFBAEgEQCADKAKYAUEIaiADKAKYASgCABAYIANBfzYCnAEMAQsgAykDOELkAINC5ABSBEAgAygCmAFBCGpBFEEAEBUgA0F/NgKcAQwBCyADKAKQASgCAEEgcUUEQAJAIAMpAzhCEINCAFIEQCADKAKQASADKAJgNgIUDAELIAMoApABQRRqEAEaCwsgAygCkAEgAy8BaDYCECADKAKQASADKAJkNgIYIAMoApABIAMpA1A3AyggAygCkAEgAykDeCADKQOAAX03AyAgAygCkAEgAygCkAEvAQxB+f8DcSADLQAjQQF0cjsBDCADKAKQASADKAIkQYAIcUEARxCKAyADIAMoApgBIAMoApABIAMoAiQQXiIANgIsIABBAEgEQCADQX82ApwBDAELIAMoAiggAygCLEcEQCADKAKYAUEIakEUQQAQFSADQX82ApwBDAELIAMoApgBKAIAIAMpA3gQqAFBAEgEQCADKAKYAUEIaiADKAKYASgCABAYIANBfzYCnAEMAQsgA0EANgKcAQsgAygCnAEhACADQaABaiQAIAALrwIBAX8jAEEgayICIAA2AhwgAiABNgIYIAJBADYCFCACQgA3AwACQCACKAIcLQAoQQFxRQRAIAIoAhwoAhggAigCHCgCFEYNAQsgAkEBNgIUCyACQgA3AwgDQCACKQMIIAIoAhwpAzBUBEACQAJAIAIoAhwoAkAgAikDCKdBBHRqKAIIDQAgAigCHCgCQCACKQMIp0EEdGotAAxBAXENACACKAIcKAJAIAIpAwinQQR0aigCBEUNASACKAIcKAJAIAIpAwinQQR0aigCBCgCAEUNAQsgAkEBNgIUCyACKAIcKAJAIAIpAwinQQR0ai0ADEEBcUUEQCACIAIpAwBCAXw3AwALIAIgAikDCEIBfDcDCAwBCwsgAigCGARAIAIoAhggAikDADcDAAsgAigCFAuMEAMCfwF+AXwjAEHgAGsiASQAIAEgADYCWAJAIAEoAlhFBEAgAUF/NgJcDAELIAEgASgCWCABQUBrELkCNgIkIAEpA0BQBEACQCABKAJYKAIEQQhxRQRAIAEoAiRFDQELIAEoAlgoAgAQhAJBAEgEQAJAAn8jAEEQayICIAEoAlgoAgA2AgwjAEEQayIAIAIoAgxBDGo2AgwgACgCDCgCAEEWRgsEQCMAQRBrIgIgASgCWCgCADYCDCMAQRBrIgAgAigCDEEMajYCDCAAKAIMKAIEQSxGDQELIAEoAlhBCGogASgCWCgCABAYIAFBfzYCXAwECwsLIAEoAlgQPyABQQA2AlwMAQsgASgCJEUEQCABKAJYED8gAUEANgJcDAELIAEpA0AgASgCWCkDMFYEQCABKAJYQQhqQRRBABAVIAFBfzYCXAwBCyABIAEpA0CnQQN0EBkiADYCKCAARQRAIAFBfzYCXAwBCyABQn83AzggAUIANwNIIAFCADcDUANAIAEpA1AgASgCWCkDMFQEQAJAIAEoAlgoAkAgASkDUKdBBHRqKAIARQ0AAkAgASgCWCgCQCABKQNQp0EEdGooAggNACABKAJYKAJAIAEpA1CnQQR0ai0ADEEBcQ0AIAEoAlgoAkAgASkDUKdBBHRqKAIERQ0BIAEoAlgoAkAgASkDUKdBBHRqKAIEKAIARQ0BCyABAn4gASkDOCABKAJYKAJAIAEpA1CnQQR0aigCACkDSFQEQCABKQM4DAELIAEoAlgoAkAgASkDUKdBBHRqKAIAKQNICzcDOAsgASgCWCgCQCABKQNQp0EEdGotAAxBAXFFBEAgASkDSCABKQNAWgRAIAEoAigQFiABKAJYQQhqQRRBABAVIAFBfzYCXAwECyABKAIoIAEpA0inQQN0aiABKQNQNwMAIAEgASkDSEIBfDcDSAsgASABKQNQQgF8NwNQDAELCyABKQNIIAEpA0BUBEAgASgCKBAWIAEoAlhBCGpBFEEAEBUgAUF/NgJcDAELAkACfyMAQRBrIgAgASgCWCgCADYCDCAAKAIMKQMYQoCACINQCwRAIAFCADcDOAwBCyABKQM4Qn9RBEAgAUJ/NwMYIAFCADcDOCABQgA3A1ADQCABKQNQIAEoAlgpAzBUBEAgASgCWCgCQCABKQNQp0EEdGooAgAEQCABKAJYKAJAIAEpA1CnQQR0aigCACkDSCABKQM4WgRAIAEgASgCWCgCQCABKQNQp0EEdGooAgApA0g3AzggASABKQNQNwMYCwsgASABKQNQQgF8NwNQDAELCyABKQMYQn9SBEAgASABKAJYIAEpAxggASgCWEEIahCIAyIDNwM4IANQBEAgASgCKBAWIAFBfzYCXAwECwsLIAEpAzhCAFYEQCABKAJYKAIAIAEpAzgQ9wJBAEgEQCABQgA3AzgLCwsgASkDOFAEQCABKAJYKAIAEPYCQQBIBEAgASgCWEEIaiABKAJYKAIAEBggASgCKBAWIAFBfzYCXAwCCwsgASgCWCgCVBD5AiABQQA2AiwgAUIANwNIA0ACQCABKQNIIAEpA0BaDQAgASgCWCgCVCABKQNIIgO6IAEpA0C6IgSjIANCAXy6IASjEPgCIAEgASgCKCABKQNIp0EDdGopAwA3A1AgASABKAJYKAJAIAEpA1CnQQR0ajYCEAJAAkAgASgCECgCAEUNACABKAIQKAIAKQNIIAEpAzhaDQAMAQsgAQJ/QQEgASgCECgCCA0AGiABKAIQKAIEBEBBASABKAIQKAIEKAIAQQFxDQEaCyABKAIQKAIEBH8gASgCECgCBCgCAEHAAHFBAEcFQQALC0EBcTYCFCABKAIQKAIERQRAIAEoAhAoAgAQRiEAIAEoAhAgADYCBCAARQRAIAEoAlhBCGpBDkEAEBUgAUEBNgIsDAMLCyABIAEoAhAoAgQ2AgwgASgCWCABKQNQEMcBQQBIBEAgAUEBNgIsDAILIAEgASgCWCgCABA1IgM3AzAgA0IAUwRAIAFBATYCLAwCCyABKAIMIAEpAzA3A0gCQCABKAIUBEAgAUEANgIIIAEoAhAoAghFBEAgASABKAJYIAEoAlggASkDUEEIQQAQqQEiADYCCCAARQRAIAFBATYCLAwFCwsgASgCWAJ/IAEoAggEQCABKAIIDAELIAEoAhAoAggLIAEoAgwQuAJBAEgEQCABQQE2AiwgASgCCARAIAEoAggQHAsMBAsgASgCCARAIAEoAggQHAsMAQsgASgCDCIAIAAvAQxB9/8DcTsBDCABKAJYIAEoAgxBgAIQXkEASARAIAFBATYCLAwDCyABIAEoAlggASkDUCABKAJYQQhqEH8iAzcDACADUARAIAFBATYCLAwDCyABKAJYKAIAIAEpAwBBABAoQQBIBEAgASgCWEEIaiABKAJYKAIAEBggAUEBNgIsDAMLIAEoAlggASgCDCkDIBC3AkEASARAIAFBATYCLAwDCwsLIAEgASkDSEIBfDcDSAwBCwsgASgCLEUEQCABKAJYIAEoAiggASkDQBC2AkEASARAIAFBATYCLAsLIAEoAigQFiABKAIsRQRAIAEoAlgoAgAQvAIEQCABKAJYQQhqIAEoAlgoAgAQGCABQQE2AiwLCyABKAJYKAJUEPsCIAEoAiwEQCABKAJYKAIAEGogAUF/NgJcDAELIAEoAlgQPyABQQA2AlwLIAEoAlwhACABQeAAaiQAIAALswEBAX8jAEEQayIBJAAgASAANgIIAkADQCABKAIIBEAgASgCCCkDGEKAgASDQgBSBEAgASABKAIIQQBCAEEQECI3AwAgASkDAEIAUwRAIAFB/wE6AA8MBAsgASkDAEIDVQRAIAEoAghBDGpBFEEAEBUgAUH/AToADwwECyABIAEpAwA8AA8MAwUgASABKAIIKAIANgIIDAILAAsLIAFBADoADwsgASwADyEAIAFBEGokACAAC8wBAQF/IwBBEGsiASQAIAEgADYCCAJAIAEoAggoAiRBAUcEQCABKAIIQQxqQRJBABAVIAFBfzYCDAwBCyABKAIIKAIgQQFLBEAgASgCCEEMakEdQQAQFSABQX82AgwMAQsgASgCCCgCIEEASwRAIAEoAggQMkEASARAIAFBfzYCDAwCCwsgASgCCEEAQgBBCRAiQgBTBEAgASgCCEECNgIkIAFBfzYCDAwBCyABKAIIQQA2AiQgAUEANgIMCyABKAIMIQAgAUEQaiQAIAAL2gkBAX8jAEGwAWsiBSQAIAUgADYCpAEgBSABNgKgASAFIAI2ApwBIAUgAzcDkAEgBSAENgKMASAFIAUoAqABNgKIAQJAAkACQAJAAkACQAJAAkACQAJAAkAgBSgCjAEODwABAgMEBQcICQkJCQkJBgkLIAUoAogBQgA3AyAgBUIANwOoAQwJCyAFIAUoAqQBIAUoApwBIAUpA5ABEC8iAzcDgAEgA0IAUwRAIAUoAogBQQhqIAUoAqQBEBggBUJ/NwOoAQwJCwJAIAUpA4ABUARAIAUoAogBKQMoIAUoAogBKQMgUQRAIAUoAogBQQE2AgQgBSgCiAEgBSgCiAEpAyA3AxggBSgCiAEoAgAEQCAFKAKkASAFQcgAahA5QQBIBEAgBSgCiAFBCGogBSgCpAEQGCAFQn83A6gBDA0LAkAgBSkDSEIgg1ANACAFKAJ0IAUoAogBKAIwRg0AIAUoAogBQQhqQQdBABAVIAVCfzcDqAEMDQsCQCAFKQNIQgSDUA0AIAUpA2AgBSgCiAEpAxhRDQAgBSgCiAFBCGpBFUEAEBUgBUJ/NwOoAQwNCwsLDAELAkAgBSgCiAEoAgQNACAFKAKIASkDICAFKAKIASkDKFYNACAFIAUoAogBKQMoIAUoAogBKQMgfTcDQANAIAUpA0AgBSkDgAFUBEAgBQJ+Qv////8PQv////8PIAUpA4ABIAUpA0B9VA0AGiAFKQOAASAFKQNAfQs3AzggBSgCiAEoAjAgBSgCnAEgBSkDQKdqIAUpAzinEBshACAFKAKIASAANgIwIAUoAogBIgAgBSkDOCAAKQMofDcDKCAFIAUpAzggBSkDQHw3A0AMAQsLCwsgBSgCiAEiACAFKQOAASAAKQMgfDcDICAFIAUpA4ABNwOoAQwICyAFQgA3A6gBDAcLIAUgBSgCnAE2AjQgBSgCiAEoAgQEQCAFKAI0IAUoAogBKQMYNwMYIAUoAjQgBSgCiAEoAjA2AiwgBSgCNCAFKAKIASkDGDcDICAFKAI0QQA7ATAgBSgCNEEAOwEyIAUoAjQiACAAKQMAQuwBhDcDAAsgBUIANwOoAQwGCyAFIAUoAogBQQhqIAUoApwBIAUpA5ABEEI3A6gBDAULIAUoAogBEBYgBUIANwOoAQwECyMAQRBrIgAgBSgCpAE2AgwgBSAAKAIMKQMYNwMoIAUpAyhCAFMEQCAFKAKIAUEIaiAFKAKkARAYIAVCfzcDqAEMBAsgBSkDKCEDIAVBfzYCGCAFQRA2AhQgBUEPNgIQIAVBDTYCDCAFQQw2AgggBUEKNgIEIAVBCTYCACAFQQggBRA3Qn+FIAODNwOoAQwDCyAFAn8gBSkDkAFCEFQEQCAFKAKIAUEIakESQQAQFUEADAELIAUoApwBCzYCHCAFKAIcRQRAIAVCfzcDqAEMAwsCQCAFKAKkASAFKAIcKQMAIAUoAhwoAggQKEEATgRAIAUgBSgCpAEQSiIDNwMgIANCAFkNAQsgBSgCiAFBCGogBSgCpAEQGCAFQn83A6gBDAMLIAUoAogBIAUpAyA3AyAgBUIANwOoAQwCCyAFIAUoAogBKQMgNwOoAQwBCyAFKAKIAUEIakEcQQAQFSAFQn83A6gBCyAFKQOoASEDIAVBsAFqJAAgAwvDBgEBfyMAQUBqIgQkACAEIAA2AjQgBCABNgIwIAQgAjYCLCAEIAM3AyACQAJ/IwBBEGsiACAEKAIwNgIMIAAoAgwoAgALBEAgBEJ/NwM4DAELAkAgBCkDIFBFBEAgBCgCMC0ADUEBcUUNAQsgBEIANwM4DAELIARCADcDCCAEQQA6ABsDQCAELQAbQQFxBH9BAAUgBCkDCCAEKQMgVAtBAXEEQCAEIAQpAyAgBCkDCH03AwAgBCAEKAIwKAKsQCAEKAIsIAQpAwinaiAEIAQoAjAoAqhAKAIcEQEANgIcIAQoAhxBAkcEQCAEIAQpAwAgBCkDCHw3AwgLAkACQAJAAkAgBCgCHEEBaw4DAAIBAwsgBCgCMEEBOgANAkAgBCgCMC0ADEEBcQ0ACyAEKAIwKQMgQgBTBEAgBCgCMEEUQQAQFSAEQQE6ABsMAwsCQCAEKAIwLQAOQQFxRQ0AIAQoAjApAyAgBCkDCFYNACAEKAIwQQE6AA8gBCgCMCAEKAIwKQMgNwMYIAQoAiwgBCgCMEEoaiAEKAIwKQMYpxAaGiAEIAQoAjApAxg3AzgMBgsgBEEBOgAbDAILIAQoAjAtAAxBAXEEQCAEQQE6ABsMAgsgBCAEKAI0IAQoAjBBKGpCgMAAEC8iAzcDECADQgBTBEAgBCgCMCAEKAI0EBggBEEBOgAbDAILAkAgBCkDEFAEQCAEKAIwQQE6AAwgBCgCMCgCrEAgBCgCMCgCqEAoAhgRAwAgBCgCMCkDIEIAUwRAIAQoAjBCADcDIAsMAQsCQCAEKAIwKQMgQgBZBEAgBCgCMEEAOgAODAELIAQoAjAgBCkDEDcDIAsgBCgCMCgCrEAgBCgCMEEoaiAEKQMQIAQoAjAoAqhAKAIUEREAGgsMAQsCfyMAQRBrIgAgBCgCMDYCDCAAKAIMKAIARQsEQCAEKAIwQRRBABAVCyAEQQE6ABsLDAELCyAEKQMIQgBWBEAgBCgCMEEAOgAOIAQoAjAiACAEKQMIIAApAxh8NwMYIAQgBCkDCDcDOAwBCyAEQX9BAAJ/IwBBEGsiACAEKAIwNgIMIAAoAgwoAgALG6w3AzgLIAQpAzghAyAEQUBrJAAgAwuIAQEBfyMAQRBrIgIkACACIAA2AgwgAiABNgIIIwBBEGsiACACKAIMNgIMIAAoAgxBADYCACAAKAIMQQA2AgQgACgCDEEANgIIIAIoAgwgAigCCDYCAAJAIAIoAgwQpwFBAUYEQCACKAIMQbScASgCADYCBAwBCyACKAIMQQA2AgQLIAJBEGokAAvcBQEBfyMAQTBrIgUkACAFIAA2AiQgBSABNgIgIAUgAjYCHCAFIAM3AxAgBSAENgIMIAUgBSgCIDYCCAJAAkACQAJAAkACQAJAAkACQAJAIAUoAgwOEQABAgMFBggICAgICAgIBwgECAsgBSgCCEIANwMYIAUoAghBADoADCAFKAIIQQA6AA0gBSgCCEEAOgAPIAUoAghCfzcDICAFKAIIKAKsQCAFKAIIKAKoQCgCDBEAAEEBcUUEQCAFQn83AygMCQsgBUIANwMoDAgLIAUgBSgCJCAFKAIIIAUoAhwgBSkDEBC+AjcDKAwHCyAFKAIIKAKsQCAFKAIIKAKoQCgCEBEAAEEBcUUEQCAFQn83AygMBwsgBUIANwMoDAYLIAUgBSgCHDYCBAJAIAUoAggtABBBAXEEQCAFKAIILQANQQFxBEAgBSgCBAJ/QQAgBSgCCC0AD0EBcQ0AGgJ/AkAgBSgCCCgCFEF/RwRAIAUoAggoAhRBfkcNAQtBCAwBCyAFKAIIKAIUC0H//wNxCzsBMCAFKAIEIAUoAggpAxg3AyAgBSgCBCIAIAApAwBCyACENwMADAILIAUoAgQiACAAKQMAQrf///8PgzcDAAwBCyAFKAIEQQA7ATAgBSgCBCIAIAApAwBCwACENwMAAkAgBSgCCC0ADUEBcQRAIAUoAgQgBSgCCCkDGDcDGCAFKAIEIgAgACkDAEIEhDcDAAwBCyAFKAIEIgAgACkDAEL7////D4M3AwALCyAFQgA3AygMBQsgBQJ/QQAgBSgCCC0AD0EBcQ0AGiAFKAIIKAKsQCAFKAIIKAKoQCgCCBEAAAusNwMoDAQLIAUgBSgCCCAFKAIcIAUpAxAQQjcDKAwDCyAFKAIIEKwBIAVCADcDKAwCCyAFQX82AgAgBUEQIAUQN0I/hDcDKAwBCyAFKAIIQRRBABAVIAVCfzcDKAsgBSkDKCEDIAVBMGokACADC/4CAQF/IwBBIGsiBCQAIAQgADYCGCAEIAE6ABcgBCACNgIQIAQgAzYCDCAEQbDAABAZIgA2AggCQCAARQRAIARBADYCHAwBCyMAQRBrIgAgBCgCCDYCDCAAKAIMQQA2AgAgACgCDEEANgIEIAAoAgxBADYCCCAEKAIIAn8gBC0AF0EBcQRAIAQoAhhBf0cEfyAEKAIYQX5GBUEBC0EBcQwBC0EAC0EARzoADiAEKAIIIAQoAgw2AqhAIAQoAgggBCgCGDYCFCAEKAIIIAQtABdBAXE6ABAgBCgCCEEAOgAMIAQoAghBADoADSAEKAIIQQA6AA8gBCgCCCgCqEAoAgAhAAJ/AkAgBCgCGEF/RwRAIAQoAhhBfkcNAQtBCAwBCyAEKAIYC0H//wNxIAQoAhAgBCgCCCAAEQEAIQAgBCgCCCAANgKsQCAARQRAIAQoAggQOCAEKAIIEBYgBEEANgIcDAELIAQgBCgCCDYCHAsgBCgCHCEAIARBIGokACAAC00BAX8jAEEQayIEJAAgBCAANgIMIAQgATYCCCAEIAI2AgQgBCADNgIAIAQoAgwgBCgCCCAEKAIEQQEgBCgCABCtASEAIARBEGokACAAC1sBAX8jAEEQayIBJAAgASAANgIIIAFBAToABwJAIAEoAghFBEAgAUEBOgAPDAELIAEgASgCCCABLQAHQQFxEK4BQQBHOgAPCyABLQAPQQFxIQAgAUEQaiQAIAALPAEBfyMAQRBrIgMkACADIAA7AQ4gAyABNgIIIAMgAjYCBEEAIAMoAgggAygCBBCvASEAIANBEGokACAAC68CAQF/IwBBIGsiAyQAIAMgADYCGCADIAE2AhQgAyACNgIQIAMgAygCGDYCDCADKAIMAn5C/////w9C/////w8gAygCECkDAFQNABogAygCECkDAAs+AiAgAygCDCADKAIUNgIcAkAgAygCDC0ABEEBcQRAIAMgAygCDEEQakEEQQAgAygCDC0ADEEBcRsQ2wI2AggMAQsgAyADKAIMQRBqENECNgIICyADKAIQIgAgACkDACADKAIMNQIgfTcDAAJAAkACQAJAAkAgAygCCEEFag4HAgMDAwMAAQMLIANBADYCHAwDCyADQQE2AhwMAgsgAygCDCgCFEUEQCADQQM2AhwMAgsLIAMoAgwoAgBBDSADKAIIEBUgA0ECNgIcCyADKAIcIQAgA0EgaiQAIAALJAEBfyMAQRBrIgEgADYCDCABIAEoAgw2AgggASgCCEEBOgAMC5kBAQF/IwBBIGsiAyQAIAMgADYCGCADIAE2AhQgAyACNwMIIAMgAygCGDYCBAJAAkAgAykDCEL/////D1gEQCADKAIEKAIUQQBNDQELIAMoAgQoAgBBEkEAEBUgA0EAOgAfDAELIAMoAgQgAykDCD4CFCADKAIEIAMoAhQ2AhAgA0EBOgAfCyADLQAfQQFxIQAgA0EgaiQAIAALkAEBAX8jAEEQayIBJAAgASAANgIIIAEgASgCCDYCBAJAIAEoAgQtAARBAXEEQCABIAEoAgRBEGoQsgE2AgAMAQsgASABKAIEQRBqEM0CNgIACwJAIAEoAgAEQCABKAIEKAIAQQ0gASgCABAVIAFBADoADwwBCyABQQE6AA8LIAEtAA9BAXEhACABQRBqJAAgAAvAAQEBfyMAQRBrIgEkACABIAA2AgggASABKAIINgIEIAEoAgRBADYCFCABKAIEQQA2AhAgASgCBEEANgIgIAEoAgRBADYCHAJAIAEoAgQtAARBAXEEQCABIAEoAgRBEGogASgCBCgCCBDhAjYCAAwBCyABIAEoAgRBEGoQ0gI2AgALAkAgASgCAARAIAEoAgQoAgBBDSABKAIAEBUgAUEAOgAPDAELIAFBAToADwsgAS0AD0EBcSEAIAFBEGokACAAC28BAX8jAEEQayIBIAA2AgggASABKAIINgIEAkAgASgCBC0ABEEBcUUEQCABQQA2AgwMAQsgASgCBCgCCEEDSARAIAFBAjYCDAwBCyABKAIEKAIIQQdKBEAgAUEBNgIMDAELIAFBADYCDAsgASgCDAssAQF/IwBBEGsiASQAIAEgADYCDCABIAEoAgw2AgggASgCCBAWIAFBEGokAAs8AQF/IwBBEGsiAyQAIAMgADsBDiADIAE2AgggAyACNgIEQQEgAygCCCADKAIEEK8BIQAgA0EQaiQAIAALmQEBAX8jAEEQayIBJAAgASAANgIIAkAgASgCCBBLBEAgAUF+NgIMDAELIAEgASgCCCgCHDYCBCABKAIEKAI4BEAgASgCCCgCKCABKAIEKAI4IAEoAggoAiQRBAALIAEoAggoAiggASgCCCgCHCABKAIIKAIkEQQAIAEoAghBADYCHCABQQA2AgwLIAEoAgwhACABQRBqJAAgAAudBAEBfyMAQSBrIgMkACADIAA2AhggAyABNgIUIAMgAjYCECADIAMoAhgoAhw2AgwCQCADKAIMKAI4RQRAIAMoAhgoAihBASADKAIMKAIodEEBIAMoAhgoAiARAQAhACADKAIMIAA2AjggAygCDCgCOEUEQCADQQE2AhwMAgsLIAMoAgwoAixFBEAgAygCDEEBIAMoAgwoAih0NgIsIAMoAgxBADYCNCADKAIMQQA2AjALAkAgAygCECADKAIMKAIsTwRAIAMoAgwoAjggAygCFCADKAIMKAIsayADKAIMKAIsEBoaIAMoAgxBADYCNCADKAIMIAMoAgwoAiw2AjAMAQsgAyADKAIMKAIsIAMoAgwoAjRrNgIIIAMoAgggAygCEEsEQCADIAMoAhA2AggLIAMoAgwoAjggAygCDCgCNGogAygCFCADKAIQayADKAIIEBoaIAMgAygCECADKAIIazYCEAJAIAMoAhAEQCADKAIMKAI4IAMoAhQgAygCEGsgAygCEBAaGiADKAIMIAMoAhA2AjQgAygCDCADKAIMKAIsNgIwDAELIAMoAgwiACADKAIIIAAoAjRqNgI0IAMoAgwoAjQgAygCDCgCLEYEQCADKAIMQQA2AjQLIAMoAgwoAjAgAygCDCgCLEkEQCADKAIMIgAgAygCCCAAKAIwajYCMAsLCyADQQA2AhwLIAMoAhwhACADQSBqJAAgAAsYAQF/IwBBEGsiASAANgIMIAEoAgxBDGoLPAEBfyMAQRBrIgEgADYCDCABKAIMQZDyADYCUCABKAIMQQk2AlggASgCDEGQggE2AlQgASgCDEEFNgJcC5ZPAQR/IwBB4ABrIgEkACABIAA2AlggAUECNgJUAkACQAJAIAEoAlgQSw0AIAEoAlgoAgxFDQAgASgCWCgCAA0BIAEoAlgoAgRFDQELIAFBfjYCXAwBCyABIAEoAlgoAhw2AlAgASgCUCgCBEG//gBGBEAgASgCUEHA/gA2AgQLIAEgASgCWCgCDDYCSCABIAEoAlgoAhA2AkAgASABKAJYKAIANgJMIAEgASgCWCgCBDYCRCABIAEoAlAoAjw2AjwgASABKAJQKAJANgI4IAEgASgCRDYCNCABIAEoAkA2AjAgAUEANgIQA0ACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgASgCUCgCBEHMgX9qDh8AAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHwsgASgCUCgCDEUEQCABKAJQQcD+ADYCBAwhCwNAIAEoAjhBEEkEQCABKAJERQ0hIAEgASgCREF/ajYCRCABIAEoAkwiAEEBajYCTCABIAEoAjwgAC0AACABKAI4dGo2AjwgASABKAI4QQhqNgI4DAELCwJAIAEoAlAoAgxBAnFFDQAgASgCPEGflgJHDQAgASgCUCgCKEUEQCABKAJQQQ82AigLQQBBAEEAEBshACABKAJQIAA2AhwgASABKAI8OgAMIAEgASgCPEEIdjoADSABKAJQKAIcIAFBDGpBAhAbIQAgASgCUCAANgIcIAFBADYCPCABQQA2AjggASgCUEG1/gA2AgQMIQsgASgCUEEANgIUIAEoAlAoAiQEQCABKAJQKAIkQX82AjALAkAgASgCUCgCDEEBcQRAIAEoAjxB/wFxQQh0IAEoAjxBCHZqQR9wRQ0BCyABKAJYQbbuADYCGCABKAJQQdH+ADYCBAwhCyABKAI8QQ9xQQhHBEAgASgCWEHN7gA2AhggASgCUEHR/gA2AgQMIQsgASABKAI8QQR2NgI8IAEgASgCOEEEazYCOCABIAEoAjxBD3FBCGo2AhQgASgCUCgCKEUEQCABKAJQIAEoAhQ2AigLAkAgASgCFEEPTQRAIAEoAhQgASgCUCgCKE0NAQsgASgCWEHo7gA2AhggASgCUEHR/gA2AgQMIQsgASgCUEEBIAEoAhR0NgIYQQBBAEEAED4hACABKAJQIAA2AhwgASgCWCAANgIwIAEoAlBBvf4AQb/+ACABKAI8QYAEcRs2AgQgAUEANgI8IAFBADYCOAwgCwNAIAEoAjhBEEkEQCABKAJERQ0gIAEgASgCREF/ajYCRCABIAEoAkwiAEEBajYCTCABIAEoAjwgAC0AACABKAI4dGo2AjwgASABKAI4QQhqNgI4DAELCyABKAJQIAEoAjw2AhQgASgCUCgCFEH/AXFBCEcEQCABKAJYQc3uADYCGCABKAJQQdH+ADYCBAwgCyABKAJQKAIUQYDAA3EEQCABKAJYQfzuADYCGCABKAJQQdH+ADYCBAwgCyABKAJQKAIkBEAgASgCUCgCJCABKAI8QQh2QQFxNgIACwJAIAEoAlAoAhRBgARxRQ0AIAEoAlAoAgxBBHFFDQAgASABKAI8OgAMIAEgASgCPEEIdjoADSABKAJQKAIcIAFBDGpBAhAbIQAgASgCUCAANgIcCyABQQA2AjwgAUEANgI4IAEoAlBBtv4ANgIECwNAIAEoAjhBIEkEQCABKAJERQ0fIAEgASgCREF/ajYCRCABIAEoAkwiAEEBajYCTCABIAEoAjwgAC0AACABKAI4dGo2AjwgASABKAI4QQhqNgI4DAELCyABKAJQKAIkBEAgASgCUCgCJCABKAI8NgIECwJAIAEoAlAoAhRBgARxRQ0AIAEoAlAoAgxBBHFFDQAgASABKAI8OgAMIAEgASgCPEEIdjoADSABIAEoAjxBEHY6AA4gASABKAI8QRh2OgAPIAEoAlAoAhwgAUEMakEEEBshACABKAJQIAA2AhwLIAFBADYCPCABQQA2AjggASgCUEG3/gA2AgQLA0AgASgCOEEQSQRAIAEoAkRFDR4gASABKAJEQX9qNgJEIAEgASgCTCIAQQFqNgJMIAEgASgCPCAALQAAIAEoAjh0ajYCPCABIAEoAjhBCGo2AjgMAQsLIAEoAlAoAiQEQCABKAJQKAIkIAEoAjxB/wFxNgIIIAEoAlAoAiQgASgCPEEIdjYCDAsCQCABKAJQKAIUQYAEcUUNACABKAJQKAIMQQRxRQ0AIAEgASgCPDoADCABIAEoAjxBCHY6AA0gASgCUCgCHCABQQxqQQIQGyEAIAEoAlAgADYCHAsgAUEANgI8IAFBADYCOCABKAJQQbj+ADYCBAsCQCABKAJQKAIUQYAIcQRAA0AgASgCOEEQSQRAIAEoAkRFDR8gASABKAJEQX9qNgJEIAEgASgCTCIAQQFqNgJMIAEgASgCPCAALQAAIAEoAjh0ajYCPCABIAEoAjhBCGo2AjgMAQsLIAEoAlAgASgCPDYCRCABKAJQKAIkBEAgASgCUCgCJCABKAI8NgIUCwJAIAEoAlAoAhRBgARxRQ0AIAEoAlAoAgxBBHFFDQAgASABKAI8OgAMIAEgASgCPEEIdjoADSABKAJQKAIcIAFBDGpBAhAbIQAgASgCUCAANgIcCyABQQA2AjwgAUEANgI4DAELIAEoAlAoAiQEQCABKAJQKAIkQQA2AhALCyABKAJQQbn+ADYCBAsgASgCUCgCFEGACHEEQCABIAEoAlAoAkQ2AiwgASgCLCABKAJESwRAIAEgASgCRDYCLAsgASgCLARAAkAgASgCUCgCJEUNACABKAJQKAIkKAIQRQ0AIAEgASgCUCgCJCgCFCABKAJQKAJEazYCFCABKAJQKAIkKAIQIAEoAhRqIAEoAkwCfyABKAIUIAEoAixqIAEoAlAoAiQoAhhLBEAgASgCUCgCJCgCGCABKAIUawwBCyABKAIsCxAaGgsCQCABKAJQKAIUQYAEcUUNACABKAJQKAIMQQRxRQ0AIAEoAlAoAhwgASgCTCABKAIsEBshACABKAJQIAA2AhwLIAEgASgCRCABKAIsazYCRCABIAEoAiwgASgCTGo2AkwgASgCUCIAIAAoAkQgASgCLGs2AkQLIAEoAlAoAkQNGwsgASgCUEEANgJEIAEoAlBBuv4ANgIECwJAIAEoAlAoAhRBgBBxBEAgASgCREUNGyABQQA2AiwDQCABKAJMIQAgASABKAIsIgJBAWo2AiwgASAAIAJqLQAANgIUAkAgASgCUCgCJEUNACABKAJQKAIkKAIcRQ0AIAEoAlAoAkQgASgCUCgCJCgCIE8NACABKAIUIQIgASgCUCgCJCgCHCEDIAEoAlAiBCgCRCEAIAQgAEEBajYCRCAAIANqIAI6AAALIAEoAhQEfyABKAIsIAEoAkRJBUEAC0EBcQ0ACwJAIAEoAlAoAhRBgARxRQ0AIAEoAlAoAgxBBHFFDQAgASgCUCgCHCABKAJMIAEoAiwQGyEAIAEoAlAgADYCHAsgASABKAJEIAEoAixrNgJEIAEgASgCLCABKAJMajYCTCABKAIUDRsMAQsgASgCUCgCJARAIAEoAlAoAiRBADYCHAsLIAEoAlBBADYCRCABKAJQQbv+ADYCBAsCQCABKAJQKAIUQYAgcQRAIAEoAkRFDRogAUEANgIsA0AgASgCTCEAIAEgASgCLCICQQFqNgIsIAEgACACai0AADYCFAJAIAEoAlAoAiRFDQAgASgCUCgCJCgCJEUNACABKAJQKAJEIAEoAlAoAiQoAihPDQAgASgCFCECIAEoAlAoAiQoAiQhAyABKAJQIgQoAkQhACAEIABBAWo2AkQgACADaiACOgAACyABKAIUBH8gASgCLCABKAJESQVBAAtBAXENAAsCQCABKAJQKAIUQYAEcUUNACABKAJQKAIMQQRxRQ0AIAEoAlAoAhwgASgCTCABKAIsEBshACABKAJQIAA2AhwLIAEgASgCRCABKAIsazYCRCABIAEoAiwgASgCTGo2AkwgASgCFA0aDAELIAEoAlAoAiQEQCABKAJQKAIkQQA2AiQLCyABKAJQQbz+ADYCBAsgASgCUCgCFEGABHEEQANAIAEoAjhBEEkEQCABKAJERQ0aIAEgASgCREF/ajYCRCABIAEoAkwiAEEBajYCTCABIAEoAjwgAC0AACABKAI4dGo2AjwgASABKAI4QQhqNgI4DAELCwJAIAEoAlAoAgxBBHFFDQAgASgCPCABKAJQKAIcQf//A3FGDQAgASgCWEGV7wA2AhggASgCUEHR/gA2AgQMGgsgAUEANgI8IAFBADYCOAsgASgCUCgCJARAIAEoAlAoAiQgASgCUCgCFEEJdUEBcTYCLCABKAJQKAIkQQE2AjALQQBBAEEAEBshACABKAJQIAA2AhwgASgCWCAANgIwIAEoAlBBv/4ANgIEDBgLA0AgASgCOEEgSQRAIAEoAkRFDRggASABKAJEQX9qNgJEIAEgASgCTCIAQQFqNgJMIAEgASgCPCAALQAAIAEoAjh0ajYCPCABIAEoAjhBCGo2AjgMAQsLIAEoAlAgASgCPEEIdkGA/gNxIAEoAjxBGHZqIAEoAjxBgP4DcUEIdGogASgCPEH/AXFBGHRqIgA2AhwgASgCWCAANgIwIAFBADYCPCABQQA2AjggASgCUEG+/gA2AgQLIAEoAlAoAhBFBEAgASgCWCABKAJINgIMIAEoAlggASgCQDYCECABKAJYIAEoAkw2AgAgASgCWCABKAJENgIEIAEoAlAgASgCPDYCPCABKAJQIAEoAjg2AkAgAUECNgJcDBgLQQBBAEEAED4hACABKAJQIAA2AhwgASgCWCAANgIwIAEoAlBBv/4ANgIECyABKAJUQQVGDRQgASgCVEEGRg0UCyABKAJQKAIIBEAgASABKAI8IAEoAjhBB3F2NgI8IAEgASgCOCABKAI4QQdxazYCOCABKAJQQc7+ADYCBAwVCwNAIAEoAjhBA0kEQCABKAJERQ0VIAEgASgCREF/ajYCRCABIAEoAkwiAEEBajYCTCABIAEoAjwgAC0AACABKAI4dGo2AjwgASABKAI4QQhqNgI4DAELCyABKAJQIAEoAjxBAXE2AgggASABKAI8QQF2NgI8IAEgASgCOEEBazYCOAJAAkACQAJAAkAgASgCPEEDcQ4EAAECAwQLIAEoAlBBwf4ANgIEDAMLIAEoAlAQ0AIgASgCUEHH/gA2AgQgASgCVEEGRgRAIAEgASgCPEECdjYCPCABIAEoAjhBAms2AjgMFwsMAgsgASgCUEHE/gA2AgQMAQsgASgCWEGp7wA2AhggASgCUEHR/gA2AgQLIAEgASgCPEECdjYCPCABIAEoAjhBAms2AjgMFAsgASABKAI8IAEoAjhBB3F2NgI8IAEgASgCOCABKAI4QQdxazYCOANAIAEoAjhBIEkEQCABKAJERQ0UIAEgASgCREF/ajYCRCABIAEoAkwiAEEBajYCTCABIAEoAjwgAC0AACABKAI4dGo2AjwgASABKAI4QQhqNgI4DAELCyABKAI8Qf//A3EgASgCPEEQdkH//wNzRwRAIAEoAlhBvO8ANgIYIAEoAlBB0f4ANgIEDBQLIAEoAlAgASgCPEH//wNxNgJEIAFBADYCPCABQQA2AjggASgCUEHC/gA2AgQgASgCVEEGRg0SCyABKAJQQcP+ADYCBAsgASABKAJQKAJENgIsIAEoAiwEQCABKAIsIAEoAkRLBEAgASABKAJENgIsCyABKAIsIAEoAkBLBEAgASABKAJANgIsCyABKAIsRQ0RIAEoAkggASgCTCABKAIsEBoaIAEgASgCRCABKAIsazYCRCABIAEoAiwgASgCTGo2AkwgASABKAJAIAEoAixrNgJAIAEgASgCLCABKAJIajYCSCABKAJQIgAgACgCRCABKAIsazYCRAwSCyABKAJQQb/+ADYCBAwRCwNAIAEoAjhBDkkEQCABKAJERQ0RIAEgASgCREF/ajYCRCABIAEoAkwiAEEBajYCTCABIAEoAjwgAC0AACABKAI4dGo2AjwgASABKAI4QQhqNgI4DAELCyABKAJQIAEoAjxBH3FBgQJqNgJkIAEgASgCPEEFdjYCPCABIAEoAjhBBWs2AjggASgCUCABKAI8QR9xQQFqNgJoIAEgASgCPEEFdjYCPCABIAEoAjhBBWs2AjggASgCUCABKAI8QQ9xQQRqNgJgIAEgASgCPEEEdjYCPCABIAEoAjhBBGs2AjgCQCABKAJQKAJkQZ4CTQRAIAEoAlAoAmhBHk0NAQsgASgCWEHZ7wA2AhggASgCUEHR/gA2AgQMEQsgASgCUEEANgJsIAEoAlBBxf4ANgIECwNAIAEoAlAoAmwgASgCUCgCYEkEQANAIAEoAjhBA0kEQCABKAJERQ0SIAEgASgCREF/ajYCRCABIAEoAkwiAEEBajYCTCABIAEoAjwgAC0AACABKAI4dGo2AjwgASABKAI4QQhqNgI4DAELCyABKAI8QQdxIQIgASgCUEH0AGohAyABKAJQIgQoAmwhACAEIABBAWo2AmwgAEEBdEGQ7gBqLwEAQQF0IANqIAI7AQAgASABKAI8QQN2NgI8IAEgASgCOEEDazYCOAwBCwsDQCABKAJQKAJsQRNJBEAgASgCUEH0AGohAiABKAJQIgMoAmwhACADIABBAWo2AmwgAEEBdEGQ7gBqLwEAQQF0IAJqQQA7AQAMAQsLIAEoAlAgASgCUEG0Cmo2AnAgASgCUCABKAJQKAJwNgJQIAEoAlBBBzYCWCABQQAgASgCUEH0AGpBEyABKAJQQfAAaiABKAJQQdgAaiABKAJQQfQFahByNgIQIAEoAhAEQCABKAJYQf3vADYCGCABKAJQQdH+ADYCBAwQCyABKAJQQQA2AmwgASgCUEHG/gA2AgQLA0ACQCABKAJQKAJsIAEoAlAoAmQgASgCUCgCaGpPDQADQAJAIAEgASgCUCgCUCABKAI8QQEgASgCUCgCWHRBAWtxQQJ0aigBADYBICABLQAhIAEoAjhNDQAgASgCREUNESABIAEoAkRBf2o2AkQgASABKAJMIgBBAWo2AkwgASABKAI8IAAtAAAgASgCOHRqNgI8IAEgASgCOEEIajYCOAwBCwsCQCABLwEiQRBIBEAgASABKAI8IAEtACF2NgI8IAEgASgCOCABLQAhazYCOCABLwEiIQIgASgCUEH0AGohAyABKAJQIgQoAmwhACAEIABBAWo2AmwgAEEBdCADaiACOwEADAELAkAgAS8BIkEQRgRAA0AgASgCOCABLQAhQQJqSQRAIAEoAkRFDRQgASABKAJEQX9qNgJEIAEgASgCTCIAQQFqNgJMIAEgASgCPCAALQAAIAEoAjh0ajYCPCABIAEoAjhBCGo2AjgMAQsLIAEgASgCPCABLQAhdjYCPCABIAEoAjggAS0AIWs2AjggASgCUCgCbEUEQCABKAJYQZbwADYCGCABKAJQQdH+ADYCBAwECyABIAEoAlAgASgCUCgCbEEBdGovAXI2AhQgASABKAI8QQNxQQNqNgIsIAEgASgCPEECdjYCPCABIAEoAjhBAms2AjgMAQsCQCABLwEiQRFGBEADQCABKAI4IAEtACFBA2pJBEAgASgCREUNFSABIAEoAkRBf2o2AkQgASABKAJMIgBBAWo2AkwgASABKAI8IAAtAAAgASgCOHRqNgI8IAEgASgCOEEIajYCOAwBCwsgASABKAI8IAEtACF2NgI8IAEgASgCOCABLQAhazYCOCABQQA2AhQgASABKAI8QQdxQQNqNgIsIAEgASgCPEEDdjYCPCABIAEoAjhBA2s2AjgMAQsDQCABKAI4IAEtACFBB2pJBEAgASgCREUNFCABIAEoAkRBf2o2AkQgASABKAJMIgBBAWo2AkwgASABKAI8IAAtAAAgASgCOHRqNgI8IAEgASgCOEEIajYCOAwBCwsgASABKAI8IAEtACF2NgI8IAEgASgCOCABLQAhazYCOCABQQA2AhQgASABKAI8Qf8AcUELajYCLCABIAEoAjxBB3Y2AjwgASABKAI4QQdrNgI4CwsgASgCUCgCbCABKAIsaiABKAJQKAJkIAEoAlAoAmhqSwRAIAEoAlhBlvAANgIYIAEoAlBB0f4ANgIEDAILA0AgASABKAIsIgBBf2o2AiwgAARAIAEoAhQhAiABKAJQQfQAaiEDIAEoAlAiBCgCbCEAIAQgAEEBajYCbCAAQQF0IANqIAI7AQAMAQsLCwwBCwsgASgCUCgCBEHR/gBGDQ4gASgCUC8B9ARFBEAgASgCWEGw8AA2AhggASgCUEHR/gA2AgQMDwsgASgCUCABKAJQQbQKajYCcCABKAJQIAEoAlAoAnA2AlAgASgCUEEJNgJYIAFBASABKAJQQfQAaiABKAJQKAJkIAEoAlBB8ABqIAEoAlBB2ABqIAEoAlBB9AVqEHI2AhAgASgCEARAIAEoAlhB1fAANgIYIAEoAlBB0f4ANgIEDA8LIAEoAlAgASgCUCgCcDYCVCABKAJQQQY2AlwgAUECIAEoAlBB9ABqIAEoAlAoAmRBAXRqIAEoAlAoAmggASgCUEHwAGogASgCUEHcAGogASgCUEH0BWoQcjYCECABKAIQBEAgASgCWEHx8AA2AhggASgCUEHR/gA2AgQMDwsgASgCUEHH/gA2AgQgASgCVEEGRg0NCyABKAJQQcj+ADYCBAsCQCABKAJEQQZJDQAgASgCQEGCAkkNACABKAJYIAEoAkg2AgwgASgCWCABKAJANgIQIAEoAlggASgCTDYCACABKAJYIAEoAkQ2AgQgASgCUCABKAI8NgI8IAEoAlAgASgCODYCQCABKAJYIAEoAjAQ1gIgASABKAJYKAIMNgJIIAEgASgCWCgCEDYCQCABIAEoAlgoAgA2AkwgASABKAJYKAIENgJEIAEgASgCUCgCPDYCPCABIAEoAlAoAkA2AjggASgCUCgCBEG//gBGBEAgASgCUEF/NgLINwsMDQsgASgCUEEANgLINwNAAkAgASABKAJQKAJQIAEoAjxBASABKAJQKAJYdEEBa3FBAnRqKAEANgEgIAEtACEgASgCOE0NACABKAJERQ0NIAEgASgCREF/ajYCRCABIAEoAkwiAEEBajYCTCABIAEoAjwgAC0AACABKAI4dGo2AjwgASABKAI4QQhqNgI4DAELCwJAIAEtACBFDQAgAS0AIEHwAXENACABIAEoASA2ARgDQAJAIAEgASgCUCgCUCABLwEaIAEoAjxBASABLQAZIAEtABhqdEEBa3EgAS0AGXZqQQJ0aigBADYBICABLQAZIAEtACFqIAEoAjhNDQAgASgCREUNDiABIAEoAkRBf2o2AkQgASABKAJMIgBBAWo2AkwgASABKAI8IAAtAAAgASgCOHRqNgI8IAEgASgCOEEIajYCOAwBCwsgASABKAI8IAEtABl2NgI8IAEgASgCOCABLQAZazYCOCABKAJQIgAgAS0AGSAAKALIN2o2Asg3CyABIAEoAjwgAS0AIXY2AjwgASABKAI4IAEtACFrNgI4IAEoAlAiACABLQAhIAAoAsg3ajYCyDcgASgCUCABLwEiNgJEIAEtACBFBEAgASgCUEHN/gA2AgQMDQsgAS0AIEEgcQRAIAEoAlBBfzYCyDcgASgCUEG//gA2AgQMDQsgAS0AIEHAAHEEQCABKAJYQYfxADYCGCABKAJQQdH+ADYCBAwNCyABKAJQIAEtACBBD3E2AkwgASgCUEHJ/gA2AgQLIAEoAlAoAkwEQANAIAEoAjggASgCUCgCTEkEQCABKAJERQ0NIAEgASgCREF/ajYCRCABIAEoAkwiAEEBajYCTCABIAEoAjwgAC0AACABKAI4dGo2AjwgASABKAI4QQhqNgI4DAELCyABKAJQIgAgACgCRCABKAI8QQEgASgCUCgCTHRBAWtxajYCRCABIAEoAjwgASgCUCgCTHY2AjwgASABKAI4IAEoAlAoAkxrNgI4IAEoAlAiACABKAJQKAJMIAAoAsg3ajYCyDcLIAEoAlAgASgCUCgCRDYCzDcgASgCUEHK/gA2AgQLA0ACQCABIAEoAlAoAlQgASgCPEEBIAEoAlAoAlx0QQFrcUECdGooAQA2ASAgAS0AISABKAI4TQ0AIAEoAkRFDQsgASABKAJEQX9qNgJEIAEgASgCTCIAQQFqNgJMIAEgASgCPCAALQAAIAEoAjh0ajYCPCABIAEoAjhBCGo2AjgMAQsLIAEtACBB8AFxRQRAIAEgASgBIDYBGANAAkAgASABKAJQKAJUIAEvARogASgCPEEBIAEtABkgAS0AGGp0QQFrcSABLQAZdmpBAnRqKAEANgEgIAEtABkgAS0AIWogASgCOE0NACABKAJERQ0MIAEgASgCREF/ajYCRCABIAEoAkwiAEEBajYCTCABIAEoAjwgAC0AACABKAI4dGo2AjwgASABKAI4QQhqNgI4DAELCyABIAEoAjwgAS0AGXY2AjwgASABKAI4IAEtABlrNgI4IAEoAlAiACABLQAZIAAoAsg3ajYCyDcLIAEgASgCPCABLQAhdjYCPCABIAEoAjggAS0AIWs2AjggASgCUCIAIAEtACEgACgCyDdqNgLINyABLQAgQcAAcQRAIAEoAlhBo/EANgIYIAEoAlBB0f4ANgIEDAsLIAEoAlAgAS8BIjYCSCABKAJQIAEtACBBD3E2AkwgASgCUEHL/gA2AgQLIAEoAlAoAkwEQANAIAEoAjggASgCUCgCTEkEQCABKAJERQ0LIAEgASgCREF/ajYCRCABIAEoAkwiAEEBajYCTCABIAEoAjwgAC0AACABKAI4dGo2AjwgASABKAI4QQhqNgI4DAELCyABKAJQIgAgACgCSCABKAI8QQEgASgCUCgCTHRBAWtxajYCSCABIAEoAjwgASgCUCgCTHY2AjwgASABKAI4IAEoAlAoAkxrNgI4IAEoAlAiACABKAJQKAJMIAAoAsg3ajYCyDcLIAEoAlBBzP4ANgIECyABKAJARQ0HIAEgASgCMCABKAJAazYCLAJAIAEoAlAoAkggASgCLEsEQCABIAEoAlAoAkggASgCLGs2AiwgASgCLCABKAJQKAIwSwRAIAEoAlAoAsQ3BEAgASgCWEG58QA2AhggASgCUEHR/gA2AgQMDAsLAkAgASgCLCABKAJQKAI0SwRAIAEgASgCLCABKAJQKAI0azYCLCABIAEoAlAoAjggASgCUCgCLCABKAIsa2o2AigMAQsgASABKAJQKAI4IAEoAlAoAjQgASgCLGtqNgIoCyABKAIsIAEoAlAoAkRLBEAgASABKAJQKAJENgIsCwwBCyABIAEoAkggASgCUCgCSGs2AiggASABKAJQKAJENgIsCyABKAIsIAEoAkBLBEAgASABKAJANgIsCyABIAEoAkAgASgCLGs2AkAgASgCUCIAIAAoAkQgASgCLGs2AkQDQCABIAEoAigiAEEBajYCKCAALQAAIQAgASABKAJIIgJBAWo2AkggAiAAOgAAIAEgASgCLEF/aiIANgIsIAANAAsgASgCUCgCREUEQCABKAJQQcj+ADYCBAsMCAsgASgCQEUNBiABKAJQKAJEIQAgASABKAJIIgJBAWo2AkggAiAAOgAAIAEgASgCQEF/ajYCQCABKAJQQcj+ADYCBAwHCyABKAJQKAIMBEADQCABKAI4QSBJBEAgASgCREUNCCABIAEoAkRBf2o2AkQgASABKAJMIgBBAWo2AkwgASABKAI8IAAtAAAgASgCOHRqNgI8IAEgASgCOEEIajYCOAwBCwsgASABKAIwIAEoAkBrNgIwIAEoAlgiACABKAIwIAAoAhRqNgIUIAEoAlAiACABKAIwIAAoAiBqNgIgAkAgASgCUCgCDEEEcUUNACABKAIwRQ0AAn8gASgCUCgCFARAIAEoAlAoAhwgASgCSCABKAIwayABKAIwEBsMAQsgASgCUCgCHCABKAJIIAEoAjBrIAEoAjAQPgshACABKAJQIAA2AhwgASgCWCAANgIwCyABIAEoAkA2AjACQCABKAJQKAIMQQRxRQ0AAn8gASgCUCgCFARAIAEoAjwMAQsgASgCPEEIdkGA/gNxIAEoAjxBGHZqIAEoAjxBgP4DcUEIdGogASgCPEH/AXFBGHRqCyABKAJQKAIcRg0AIAEoAlhB1/EANgIYIAEoAlBB0f4ANgIEDAgLIAFBADYCPCABQQA2AjgLIAEoAlBBz/4ANgIECwJAIAEoAlAoAgxFDQAgASgCUCgCFEUNAANAIAEoAjhBIEkEQCABKAJERQ0HIAEgASgCREF/ajYCRCABIAEoAkwiAEEBajYCTCABIAEoAjwgAC0AACABKAI4dGo2AjwgASABKAI4QQhqNgI4DAELCyABKAI8IAEoAlAoAiBHBEAgASgCWEHs8QA2AhggASgCUEHR/gA2AgQMBwsgAUEANgI8IAFBADYCOAsgASgCUEHQ/gA2AgQLIAFBATYCEAwDCyABQX02AhAMAgsgAUF8NgJcDAMLIAFBfjYCXAwCCwsgASgCWCABKAJINgIMIAEoAlggASgCQDYCECABKAJYIAEoAkw2AgAgASgCWCABKAJENgIEIAEoAlAgASgCPDYCPCABKAJQIAEoAjg2AkACQAJAIAEoAlAoAiwNACABKAIwIAEoAlgoAhBGDQEgASgCUCgCBEHR/gBPDQEgASgCUCgCBEHO/gBJDQAgASgCVEEERg0BCyABKAJYIAEoAlgoAgwgASgCMCABKAJYKAIQaxDOAgRAIAEoAlBB0v4ANgIEIAFBfDYCXAwCCwsgASABKAI0IAEoAlgoAgRrNgI0IAEgASgCMCABKAJYKAIQazYCMCABKAJYIgAgASgCNCAAKAIIajYCCCABKAJYIgAgASgCMCAAKAIUajYCFCABKAJQIgAgASgCMCAAKAIgajYCIAJAIAEoAlAoAgxBBHFFDQAgASgCMEUNAAJ/IAEoAlAoAhQEQCABKAJQKAIcIAEoAlgoAgwgASgCMGsgASgCMBAbDAELIAEoAlAoAhwgASgCWCgCDCABKAIwayABKAIwED4LIQAgASgCUCAANgIcIAEoAlggADYCMAsgASgCWCABKAJQKAJAQcAAQQAgASgCUCgCCBtqQYABQQAgASgCUCgCBEG//gBGG2pBgAJBACABKAJQKAIEQcf+AEcEfyABKAJQKAIEQcL+AEYFQQELQQFxG2o2AiwCQAJAIAEoAjRFBEAgASgCMEUNAQsgASgCVEEERw0BCyABKAIQDQAgAUF7NgIQCyABIAEoAhA2AlwLIAEoAlwhACABQeAAaiQAIAAL6AIBAX8jAEEgayIBJAAgASAANgIYIAFBcTYCFCABQZCDATYCECABQTg2AgwCQAJAAkAgASgCEEUNACABKAIQLAAAQYDuACwAAEcNACABKAIMQThGDQELIAFBejYCHAwBCyABKAIYRQRAIAFBfjYCHAwBCyABKAIYQQA2AhggASgCGCgCIEUEQCABKAIYQQU2AiAgASgCGEEANgIoCyABKAIYKAIkRQRAIAEoAhhBBjYCJAsgASABKAIYKAIoQQFB0DcgASgCGCgCIBEBADYCBCABKAIERQRAIAFBfDYCHAwBCyABKAIYIAEoAgQ2AhwgASgCBCABKAIYNgIAIAEoAgRBADYCOCABKAIEQbT+ADYCBCABIAEoAhggASgCFBDTAjYCCCABKAIIBEAgASgCGCgCKCABKAIEIAEoAhgoAiQRBAAgASgCGEEANgIcCyABIAEoAgg2AhwLIAEoAhwhACABQSBqJAAgAAutAgEBfyMAQSBrIgIkACACIAA2AhggAiABNgIUAkAgAigCGBBLBEAgAkF+NgIcDAELIAIgAigCGCgCHDYCDAJAIAIoAhRBAEgEQCACQQA2AhAgAkEAIAIoAhRrNgIUDAELIAIgAigCFEEEdUEFajYCECACKAIUQTBIBEAgAiACKAIUQQ9xNgIUCwsCQCACKAIURQ0AIAIoAhRBCE4EQCACKAIUQQ9MDQELIAJBfjYCHAwBCwJAIAIoAgwoAjhFDQAgAigCDCgCKCACKAIURg0AIAIoAhgoAiggAigCDCgCOCACKAIYKAIkEQQAIAIoAgxBADYCOAsgAigCDCACKAIQNgIMIAIoAgwgAigCFDYCKCACIAIoAhgQ1AI2AhwLIAIoAhwhACACQSBqJAAgAAtyAQF/IwBBEGsiASQAIAEgADYCCAJAIAEoAggQSwRAIAFBfjYCDAwBCyABIAEoAggoAhw2AgQgASgCBEEANgIsIAEoAgRBADYCMCABKAIEQQA2AjQgASABKAIIENUCNgIMCyABKAIMIQAgAUEQaiQAIAALmwIBAX8jAEEQayIBJAAgASAANgIIAkAgASgCCBBLBEAgAUF+NgIMDAELIAEgASgCCCgCHDYCBCABKAIEQQA2AiAgASgCCEEANgIUIAEoAghBADYCCCABKAIIQQA2AhggASgCBCgCDARAIAEoAgggASgCBCgCDEEBcTYCMAsgASgCBEG0/gA2AgQgASgCBEEANgIIIAEoAgRBADYCECABKAIEQYCAAjYCGCABKAIEQQA2AiQgASgCBEEANgI8IAEoAgRBADYCQCABKAIEIAEoAgRBtApqIgA2AnAgASgCBCAANgJUIAEoAgQgADYCUCABKAIEQQE2AsQ3IAEoAgRBfzYCyDcgAUEANgIMCyABKAIMIQAgAUEQaiQAIAALkhUBAX8jAEHgAGsiAiAANgJcIAIgATYCWCACIAIoAlwoAhw2AlQgAiACKAJcKAIANgJQIAIgAigCUCACKAJcKAIEQQVrajYCTCACIAIoAlwoAgw2AkggAiACKAJIIAIoAlggAigCXCgCEGtrNgJEIAIgAigCSCACKAJcKAIQQYECa2o2AkAgAiACKAJUKAIsNgI8IAIgAigCVCgCMDYCOCACIAIoAlQoAjQ2AjQgAiACKAJUKAI4NgIwIAIgAigCVCgCPDYCLCACIAIoAlQoAkA2AiggAiACKAJUKAJQNgIkIAIgAigCVCgCVDYCICACQQEgAigCVCgCWHRBAWs2AhwgAkEBIAIoAlQoAlx0QQFrNgIYA0AgAigCKEEPSQRAIAIgAigCUCIAQQFqNgJQIAIgAigCLCAALQAAIAIoAih0ajYCLCACIAIoAihBCGo2AiggAiACKAJQIgBBAWo2AlAgAiACKAIsIAAtAAAgAigCKHRqNgIsIAIgAigCKEEIajYCKAsgAkEQaiACKAIkIAIoAiwgAigCHHFBAnRqKAEANgEAAkACQANAIAIgAi0AETYCDCACIAIoAiwgAigCDHY2AiwgAiACKAIoIAIoAgxrNgIoIAIgAi0AEDYCDCACKAIMRQRAIAIvARIhACACIAIoAkgiAUEBajYCSCABIAA6AAAMAgsgAigCDEEQcQRAIAIgAi8BEjYCCCACIAIoAgxBD3E2AgwgAigCDARAIAIoAiggAigCDEkEQCACIAIoAlAiAEEBajYCUCACIAIoAiwgAC0AACACKAIodGo2AiwgAiACKAIoQQhqNgIoCyACIAIoAgggAigCLEEBIAIoAgx0QQFrcWo2AgggAiACKAIsIAIoAgx2NgIsIAIgAigCKCACKAIMazYCKAsgAigCKEEPSQRAIAIgAigCUCIAQQFqNgJQIAIgAigCLCAALQAAIAIoAih0ajYCLCACIAIoAihBCGo2AiggAiACKAJQIgBBAWo2AlAgAiACKAIsIAAtAAAgAigCKHRqNgIsIAIgAigCKEEIajYCKAsgAkEQaiACKAIgIAIoAiwgAigCGHFBAnRqKAEANgEAAkADQCACIAItABE2AgwgAiACKAIsIAIoAgx2NgIsIAIgAigCKCACKAIMazYCKCACIAItABA2AgwgAigCDEEQcQRAIAIgAi8BEjYCBCACIAIoAgxBD3E2AgwgAigCKCACKAIMSQRAIAIgAigCUCIAQQFqNgJQIAIgAigCLCAALQAAIAIoAih0ajYCLCACIAIoAihBCGo2AiggAigCKCACKAIMSQRAIAIgAigCUCIAQQFqNgJQIAIgAigCLCAALQAAIAIoAih0ajYCLCACIAIoAihBCGo2AigLCyACIAIoAgQgAigCLEEBIAIoAgx0QQFrcWo2AgQgAiACKAIsIAIoAgx2NgIsIAIgAigCKCACKAIMazYCKCACIAIoAkggAigCRGs2AgwCQCACKAIEIAIoAgxLBEAgAiACKAIEIAIoAgxrNgIMIAIoAgwgAigCOEsEQCACKAJUKALENwRAIAIoAlxBsO0ANgIYIAIoAlRB0f4ANgIEDAoLCyACIAIoAjA2AgACQCACKAI0RQRAIAIgAigCACACKAI8IAIoAgxrajYCACACKAIMIAIoAghJBEAgAiACKAIIIAIoAgxrNgIIA0AgAiACKAIAIgBBAWo2AgAgAC0AACEAIAIgAigCSCIBQQFqNgJIIAEgADoAACACIAIoAgxBf2oiADYCDCAADQALIAIgAigCSCACKAIEazYCAAsMAQsCQCACKAI0IAIoAgxJBEAgAiACKAIAIAIoAjwgAigCNGogAigCDGtqNgIAIAIgAigCDCACKAI0azYCDCACKAIMIAIoAghJBEAgAiACKAIIIAIoAgxrNgIIA0AgAiACKAIAIgBBAWo2AgAgAC0AACEAIAIgAigCSCIBQQFqNgJIIAEgADoAACACIAIoAgxBf2oiADYCDCAADQALIAIgAigCMDYCACACKAI0IAIoAghJBEAgAiACKAI0NgIMIAIgAigCCCACKAIMazYCCANAIAIgAigCACIAQQFqNgIAIAAtAAAhACACIAIoAkgiAUEBajYCSCABIAA6AAAgAiACKAIMQX9qIgA2AgwgAA0ACyACIAIoAkggAigCBGs2AgALCwwBCyACIAIoAgAgAigCNCACKAIMa2o2AgAgAigCDCACKAIISQRAIAIgAigCCCACKAIMazYCCANAIAIgAigCACIAQQFqNgIAIAAtAAAhACACIAIoAkgiAUEBajYCSCABIAA6AAAgAiACKAIMQX9qIgA2AgwgAA0ACyACIAIoAkggAigCBGs2AgALCwsDQCACKAIIQQJNRQRAIAIgAigCACIAQQFqNgIAIAAtAAAhACACIAIoAkgiAUEBajYCSCABIAA6AAAgAiACKAIAIgBBAWo2AgAgAC0AACEAIAIgAigCSCIBQQFqNgJIIAEgADoAACACIAIoAgAiAEEBajYCACAALQAAIQAgAiACKAJIIgFBAWo2AkggASAAOgAAIAIgAigCCEEDazYCCAwBCwsMAQsgAiACKAJIIAIoAgRrNgIAA0AgAiACKAIAIgBBAWo2AgAgAC0AACEAIAIgAigCSCIBQQFqNgJIIAEgADoAACACIAIoAgAiAEEBajYCACAALQAAIQAgAiACKAJIIgFBAWo2AkggASAAOgAAIAIgAigCACIAQQFqNgIAIAAtAAAhACACIAIoAkgiAUEBajYCSCABIAA6AAAgAiACKAIIQQNrNgIIIAIoAghBAksNAAsLIAIoAggEQCACIAIoAgAiAEEBajYCACAALQAAIQAgAiACKAJIIgFBAWo2AkggASAAOgAAIAIoAghBAUsEQCACIAIoAgAiAEEBajYCACAALQAAIQAgAiACKAJIIgFBAWo2AkggASAAOgAACwsMAgsgAigCDEHAAHFFBEAgAkEQaiACKAIgIAIvARIgAigCLEEBIAIoAgx0QQFrcWpBAnRqKAEANgEADAELCyACKAJcQc7tADYCGCACKAJUQdH+ADYCBAwECwwCCyACKAIMQcAAcUUEQCACQRBqIAIoAiQgAi8BEiACKAIsQQEgAigCDHRBAWtxakECdGooAQA2AQAMAQsLIAIoAgxBIHEEQCACKAJUQb/+ADYCBAwCCyACKAJcQeTtADYCGCACKAJUQdH+ADYCBAwBC0EAIQAgAigCUCACKAJMSQR/IAIoAkggAigCQEkFQQALQQFxDQELCyACIAIoAihBA3Y2AgggAiACKAJQIAIoAghrNgJQIAIgAigCKCACKAIIQQN0azYCKCACIAIoAixBASACKAIodEEBa3E2AiwgAigCXCACKAJQNgIAIAIoAlwgAigCSDYCDCACKAJcAn8gAigCUCACKAJMSQRAIAIoAkwgAigCUGtBBWoMAQtBBSACKAJQIAIoAkxraws2AgQgAigCXAJ/IAIoAkggAigCQEkEQCACKAJAIAIoAkhrQYECagwBC0GBAiACKAJIIAIoAkBraws2AhAgAigCVCACKAIsNgI8IAIoAlQgAigCKDYCQAvBEAECfyMAQSBrIgIkACACIAA2AhggAiABNgIUAkADQAJAIAIoAhgoAnRBhgJJBEAgAigCGBBWAkAgAigCGCgCdEGGAk8NACACKAIUDQAgAkEANgIcDAQLIAIoAhgoAnRFDQELIAJBADYCECACKAIYKAJ0QQNPBEAgAigCGCACKAIYKAJUIAIoAhgoAjggAigCGCgCbEECamotAAAgAigCGCgCSCACKAIYKAJYdHNxNgJIIAIoAhgoAkAgAigCGCgCbCACKAIYKAI0cUEBdGogAigCGCgCRCACKAIYKAJIQQF0ai8BACIAOwEAIAIgAEH//wNxNgIQIAIoAhgoAkQgAigCGCgCSEEBdGogAigCGCgCbDsBAAsgAigCGCACKAIYKAJgNgJ4IAIoAhggAigCGCgCcDYCZCACKAIYQQI2AmACQCACKAIQRQ0AIAIoAhgoAnggAigCGCgCgAFPDQAgAigCGCgCbCACKAIQayACKAIYKAIsQYYCa0sNACACKAIYIAIoAhAQsAEhACACKAIYIAA2AmACQCACKAIYKAJgQQVLDQAgAigCGCgCiAFBAUcEQCACKAIYKAJgQQNHDQEgAigCGCgCbCACKAIYKAJwa0GAIE0NAQsgAigCGEECNgJgCwsCQAJAIAIoAhgoAnhBA0kNACACKAIYKAJgIAIoAhgoAnhLDQAgAiACKAIYIgAoAmwgACgCdGpBfWo2AgggAiACKAIYKAJ4QX1qOgAHIAIgAigCGCIAKAJsIAAoAmRBf3NqOwEEIAIoAhgiACgCpC0gACgCoC1BAXRqIAIvAQQ7AQAgAi0AByEBIAIoAhgiACgCmC0hAyAAIAAoAqAtIgBBAWo2AqAtIAAgA2ogAToAACACIAIvAQRBf2o7AQQgAigCGCACLQAHQYDZAGotAABBAnRqQZgJaiIAIAAvAQBBAWo7AQAgAigCGEGIE2oCfyACLwEEQYACSARAIAIvAQQtAIBVDAELIAIvAQRBB3VBgAJqLQCAVQtBAnRqIgAgAC8BAEEBajsBACACIAIoAhgoAqAtIAIoAhgoApwtQQFrRjYCDCACKAIYIgAgACgCdCACKAIYKAJ4QQFrazYCdCACKAIYIgAgACgCeEECazYCeANAIAIoAhgiASgCbEEBaiEAIAEgADYCbCAAIAIoAghNBEAgAigCGCACKAIYKAJUIAIoAhgoAjggAigCGCgCbEECamotAAAgAigCGCgCSCACKAIYKAJYdHNxNgJIIAIoAhgoAkAgAigCGCgCbCACKAIYKAI0cUEBdGogAigCGCgCRCACKAIYKAJIQQF0ai8BACIAOwEAIAIgAEH//wNxNgIQIAIoAhgoAkQgAigCGCgCSEEBdGogAigCGCgCbDsBAAsgAigCGCIBKAJ4QX9qIQAgASAANgJ4IAANAAsgAigCGEEANgJoIAIoAhhBAjYCYCACKAIYIgAgACgCbEEBajYCbCACKAIMBEAgAigCGAJ/IAIoAhgoAlxBAE4EQCACKAIYKAI4IAIoAhgoAlxqDAELQQALIAIoAhgoAmwgAigCGCgCXGtBABApIAIoAhggAigCGCgCbDYCXCACKAIYKAIAEB0gAigCGCgCACgCEEUEQCACQQA2AhwMBgsLDAELAkAgAigCGCgCaARAIAIgAigCGCIAKAI4IAAoAmxqQX9qLQAAOgADIAIoAhgiACgCpC0gACgCoC1BAXRqQQA7AQAgAi0AAyEBIAIoAhgiACgCmC0hAyAAIAAoAqAtIgBBAWo2AqAtIAAgA2ogAToAACACKAIYIAItAANBAnRqIgAgAC8BlAFBAWo7AZQBIAIgAigCGCgCoC0gAigCGCgCnC1BAWtGNgIMIAIoAgwEQCACKAIYAn8gAigCGCgCXEEATgRAIAIoAhgoAjggAigCGCgCXGoMAQtBAAsgAigCGCgCbCACKAIYKAJca0EAECkgAigCGCACKAIYKAJsNgJcIAIoAhgoAgAQHQsgAigCGCIAIAAoAmxBAWo2AmwgAigCGCIAIAAoAnRBf2o2AnQgAigCGCgCACgCEEUEQCACQQA2AhwMBgsMAQsgAigCGEEBNgJoIAIoAhgiACAAKAJsQQFqNgJsIAIoAhgiACAAKAJ0QX9qNgJ0CwsMAQsLIAIoAhgoAmgEQCACIAIoAhgiACgCOCAAKAJsakF/ai0AADoAAiACKAIYIgAoAqQtIAAoAqAtQQF0akEAOwEAIAItAAIhASACKAIYIgAoApgtIQMgACAAKAKgLSIAQQFqNgKgLSAAIANqIAE6AAAgAigCGCACLQACQQJ0aiIAIAAvAZQBQQFqOwGUASACIAIoAhgoAqAtIAIoAhgoApwtQQFrRjYCDCACKAIYQQA2AmgLIAIoAhgCfyACKAIYKAJsQQJJBEAgAigCGCgCbAwBC0ECCzYCtC0gAigCFEEERgRAIAIoAhgCfyACKAIYKAJcQQBOBEAgAigCGCgCOCACKAIYKAJcagwBC0EACyACKAIYKAJsIAIoAhgoAlxrQQEQKSACKAIYIAIoAhgoAmw2AlwgAigCGCgCABAdIAIoAhgoAgAoAhBFBEAgAkECNgIcDAILIAJBAzYCHAwBCyACKAIYKAKgLQRAIAIoAhgCfyACKAIYKAJcQQBOBEAgAigCGCgCOCACKAIYKAJcagwBC0EACyACKAIYKAJsIAIoAhgoAlxrQQAQKSACKAIYIAIoAhgoAmw2AlwgAigCGCgCABAdIAIoAhgoAgAoAhBFBEAgAkEANgIcDAILCyACQQE2AhwLIAIoAhwhACACQSBqJAAgAAuVDQECfyMAQSBrIgIkACACIAA2AhggAiABNgIUAkADQAJAIAIoAhgoAnRBhgJJBEAgAigCGBBWAkAgAigCGCgCdEGGAk8NACACKAIUDQAgAkEANgIcDAQLIAIoAhgoAnRFDQELIAJBADYCECACKAIYKAJ0QQNPBEAgAigCGCACKAIYKAJUIAIoAhgoAjggAigCGCgCbEECamotAAAgAigCGCgCSCACKAIYKAJYdHNxNgJIIAIoAhgoAkAgAigCGCgCbCACKAIYKAI0cUEBdGogAigCGCgCRCACKAIYKAJIQQF0ai8BACIAOwEAIAIgAEH//wNxNgIQIAIoAhgoAkQgAigCGCgCSEEBdGogAigCGCgCbDsBAAsCQCACKAIQRQ0AIAIoAhgoAmwgAigCEGsgAigCGCgCLEGGAmtLDQAgAigCGCACKAIQELABIQAgAigCGCAANgJgCwJAIAIoAhgoAmBBA08EQCACIAIoAhgoAmBBfWo6AAsgAiACKAIYIgAoAmwgACgCcGs7AQggAigCGCIAKAKkLSAAKAKgLUEBdGogAi8BCDsBACACLQALIQEgAigCGCIAKAKYLSEDIAAgACgCoC0iAEEBajYCoC0gACADaiABOgAAIAIgAi8BCEF/ajsBCCACKAIYIAItAAtBgNkAai0AAEECdGpBmAlqIgAgAC8BAEEBajsBACACKAIYQYgTagJ/IAIvAQhBgAJIBEAgAi8BCC0AgFUMAQsgAi8BCEEHdUGAAmotAIBVC0ECdGoiACAALwEAQQFqOwEAIAIgAigCGCgCoC0gAigCGCgCnC1BAWtGNgIMIAIoAhgiACAAKAJ0IAIoAhgoAmBrNgJ0AkACQCACKAIYKAJgIAIoAhgoAoABSw0AIAIoAhgoAnRBA0kNACACKAIYIgAgACgCYEF/ajYCYANAIAIoAhgiACAAKAJsQQFqNgJsIAIoAhggAigCGCgCVCACKAIYKAI4IAIoAhgoAmxBAmpqLQAAIAIoAhgoAkggAigCGCgCWHRzcTYCSCACKAIYKAJAIAIoAhgoAmwgAigCGCgCNHFBAXRqIAIoAhgoAkQgAigCGCgCSEEBdGovAQAiADsBACACIABB//8DcTYCECACKAIYKAJEIAIoAhgoAkhBAXRqIAIoAhgoAmw7AQAgAigCGCIBKAJgQX9qIQAgASAANgJgIAANAAsgAigCGCIAIAAoAmxBAWo2AmwMAQsgAigCGCIAIAIoAhgoAmAgACgCbGo2AmwgAigCGEEANgJgIAIoAhggAigCGCgCOCACKAIYKAJsai0AADYCSCACKAIYIAIoAhgoAlQgAigCGCgCOCACKAIYKAJsQQFqai0AACACKAIYKAJIIAIoAhgoAlh0c3E2AkgLDAELIAIgAigCGCIAKAI4IAAoAmxqLQAAOgAHIAIoAhgiACgCpC0gACgCoC1BAXRqQQA7AQAgAi0AByEBIAIoAhgiACgCmC0hAyAAIAAoAqAtIgBBAWo2AqAtIAAgA2ogAToAACACKAIYIAItAAdBAnRqIgAgAC8BlAFBAWo7AZQBIAIgAigCGCgCoC0gAigCGCgCnC1BAWtGNgIMIAIoAhgiACAAKAJ0QX9qNgJ0IAIoAhgiACAAKAJsQQFqNgJsCyACKAIMBEAgAigCGAJ/IAIoAhgoAlxBAE4EQCACKAIYKAI4IAIoAhgoAlxqDAELQQALIAIoAhgoAmwgAigCGCgCXGtBABApIAIoAhggAigCGCgCbDYCXCACKAIYKAIAEB0gAigCGCgCACgCEEUEQCACQQA2AhwMBAsLDAELCyACKAIYAn8gAigCGCgCbEECSQRAIAIoAhgoAmwMAQtBAgs2ArQtIAIoAhRBBEYEQCACKAIYAn8gAigCGCgCXEEATgRAIAIoAhgoAjggAigCGCgCXGoMAQtBAAsgAigCGCgCbCACKAIYKAJca0EBECkgAigCGCACKAIYKAJsNgJcIAIoAhgoAgAQHSACKAIYKAIAKAIQRQRAIAJBAjYCHAwCCyACQQM2AhwMAQsgAigCGCgCoC0EQCACKAIYAn8gAigCGCgCXEEATgRAIAIoAhgoAjggAigCGCgCXGoMAQtBAAsgAigCGCgCbCACKAIYKAJca0EAECkgAigCGCACKAIYKAJsNgJcIAIoAhgoAgAQHSACKAIYKAIAKAIQRQRAIAJBADYCHAwCCwsgAkEBNgIcCyACKAIcIQAgAkEgaiQAIAALuwwBAn8jAEEwayICJAAgAiAANgIoIAIgATYCJAJAA0ACQCACKAIoKAJ0QYICTQRAIAIoAigQVgJAIAIoAigoAnRBggJLDQAgAigCJA0AIAJBADYCLAwECyACKAIoKAJ0RQ0BCyACKAIoQQA2AmACQCACKAIoKAJ0QQNJDQAgAigCKCgCbEEATQ0AIAIgAigCKCgCOCACKAIoKAJsakF/ajYCGCACIAIoAhgtAAA2AhwgAigCHCEAIAIgAigCGCIBQQFqNgIYAkAgAS0AASAARw0AIAIoAhwhACACIAIoAhgiAUEBajYCGCABLQABIABHDQAgAigCHCEAIAIgAigCGCIBQQFqNgIYIAEtAAEgAEcNACACIAIoAigoAjggAigCKCgCbGpBggJqNgIUA0AgAigCHCEBIAIgAigCGCIDQQFqNgIYAn9BACADLQABIAFHDQAaIAIoAhwhASACIAIoAhgiA0EBajYCGEEAIAMtAAEgAUcNABogAigCHCEBIAIgAigCGCIDQQFqNgIYQQAgAy0AASABRw0AGiACKAIcIQEgAiACKAIYIgNBAWo2AhhBACADLQABIAFHDQAaIAIoAhwhASACIAIoAhgiA0EBajYCGEEAIAMtAAEgAUcNABogAigCHCEBIAIgAigCGCIDQQFqNgIYQQAgAy0AASABRw0AGiACKAIcIQEgAiACKAIYIgNBAWo2AhhBACADLQABIAFHDQAaIAIoAhwhASACIAIoAhgiA0EBajYCGEEAIAMtAAEgAUcNABogAigCGCACKAIUSQtBAXENAAsgAigCKEGCAiACKAIUIAIoAhhrazYCYCACKAIoKAJgIAIoAigoAnRLBEAgAigCKCACKAIoKAJ0NgJgCwsLAkAgAigCKCgCYEEDTwRAIAIgAigCKCgCYEF9ajoAEyACQQE7ARAgAigCKCIAKAKkLSAAKAKgLUEBdGogAi8BEDsBACACLQATIQEgAigCKCIAKAKYLSEDIAAgACgCoC0iAEEBajYCoC0gACADaiABOgAAIAIgAi8BEEF/ajsBECACKAIoIAItABNBgNkAai0AAEECdGpBmAlqIgAgAC8BAEEBajsBACACKAIoQYgTagJ/IAIvARBBgAJIBEAgAi8BEC0AgFUMAQsgAi8BEEEHdUGAAmotAIBVC0ECdGoiACAALwEAQQFqOwEAIAIgAigCKCgCoC0gAigCKCgCnC1BAWtGNgIgIAIoAigiACAAKAJ0IAIoAigoAmBrNgJ0IAIoAigiACACKAIoKAJgIAAoAmxqNgJsIAIoAihBADYCYAwBCyACIAIoAigiACgCOCAAKAJsai0AADoADyACKAIoIgAoAqQtIAAoAqAtQQF0akEAOwEAIAItAA8hASACKAIoIgAoApgtIQMgACAAKAKgLSIAQQFqNgKgLSAAIANqIAE6AAAgAigCKCACLQAPQQJ0aiIAIAAvAZQBQQFqOwGUASACIAIoAigoAqAtIAIoAigoApwtQQFrRjYCICACKAIoIgAgACgCdEF/ajYCdCACKAIoIgAgACgCbEEBajYCbAsgAigCIARAIAIoAigCfyACKAIoKAJcQQBOBEAgAigCKCgCOCACKAIoKAJcagwBC0EACyACKAIoKAJsIAIoAigoAlxrQQAQKSACKAIoIAIoAigoAmw2AlwgAigCKCgCABAdIAIoAigoAgAoAhBFBEAgAkEANgIsDAQLCwwBCwsgAigCKEEANgK0LSACKAIkQQRGBEAgAigCKAJ/IAIoAigoAlxBAE4EQCACKAIoKAI4IAIoAigoAlxqDAELQQALIAIoAigoAmwgAigCKCgCXGtBARApIAIoAiggAigCKCgCbDYCXCACKAIoKAIAEB0gAigCKCgCACgCEEUEQCACQQI2AiwMAgsgAkEDNgIsDAELIAIoAigoAqAtBEAgAigCKAJ/IAIoAigoAlxBAE4EQCACKAIoKAI4IAIoAigoAlxqDAELQQALIAIoAigoAmwgAigCKCgCXGtBABApIAIoAiggAigCKCgCbDYCXCACKAIoKAIAEB0gAigCKCgCACgCEEUEQCACQQA2AiwMAgsLIAJBATYCLAsgAigCLCEAIAJBMGokACAAC8AFAQJ/IwBBIGsiAiQAIAIgADYCGCACIAE2AhQCQANAAkAgAigCGCgCdEUEQCACKAIYEFYgAigCGCgCdEUEQCACKAIURQRAIAJBADYCHAwFCwwCCwsgAigCGEEANgJgIAIgAigCGCIAKAI4IAAoAmxqLQAAOgAPIAIoAhgiACgCpC0gACgCoC1BAXRqQQA7AQAgAi0ADyEBIAIoAhgiACgCmC0hAyAAIAAoAqAtIgBBAWo2AqAtIAAgA2ogAToAACACKAIYIAItAA9BAnRqIgAgAC8BlAFBAWo7AZQBIAIgAigCGCgCoC0gAigCGCgCnC1BAWtGNgIQIAIoAhgiACAAKAJ0QX9qNgJ0IAIoAhgiACAAKAJsQQFqNgJsIAIoAhAEQCACKAIYAn8gAigCGCgCXEEATgRAIAIoAhgoAjggAigCGCgCXGoMAQtBAAsgAigCGCgCbCACKAIYKAJca0EAECkgAigCGCACKAIYKAJsNgJcIAIoAhgoAgAQHSACKAIYKAIAKAIQRQRAIAJBADYCHAwECwsMAQsLIAIoAhhBADYCtC0gAigCFEEERgRAIAIoAhgCfyACKAIYKAJcQQBOBEAgAigCGCgCOCACKAIYKAJcagwBC0EACyACKAIYKAJsIAIoAhgoAlxrQQEQKSACKAIYIAIoAhgoAmw2AlwgAigCGCgCABAdIAIoAhgoAgAoAhBFBEAgAkECNgIcDAILIAJBAzYCHAwBCyACKAIYKAKgLQRAIAIoAhgCfyACKAIYKAJcQQBOBEAgAigCGCgCOCACKAIYKAJcagwBC0EACyACKAIYKAJsIAIoAhgoAlxrQQAQKSACKAIYIAIoAhgoAmw2AlwgAigCGCgCABAdIAIoAhgoAgAoAhBFBEAgAkEANgIcDAILCyACQQE2AhwLIAIoAhwhACACQSBqJAAgAAuuJQEDfyMAQUBqIgIkACACIAA2AjggAiABNgI0AkACQAJAIAIoAjgQdA0AIAIoAjRBBUoNACACKAI0QQBODQELIAJBfjYCPAwBCyACIAIoAjgoAhw2AiwCQAJAIAIoAjgoAgxFDQAgAigCOCgCBARAIAIoAjgoAgBFDQELIAIoAiwoAgRBmgVHDQEgAigCNEEERg0BCyACKAI4QeDUACgCADYCGCACQX42AjwMAQsgAigCOCgCEEUEQCACKAI4QezUACgCADYCGCACQXs2AjwMAQsgAiACKAIsKAIoNgIwIAIoAiwgAigCNDYCKAJAIAIoAiwoAhQEQCACKAI4EB0gAigCOCgCEEUEQCACKAIsQX82AiggAkEANgI8DAMLDAELAkAgAigCOCgCBA0AIAIoAjRBAXRBCUEAIAIoAjRBBEobayACKAIwQQF0QQlBACACKAIwQQRKG2tKDQAgAigCNEEERg0AIAIoAjhB7NQAKAIANgIYIAJBezYCPAwCCwsCQCACKAIsKAIEQZoFRw0AIAIoAjgoAgRFDQAgAigCOEHs1AAoAgA2AhggAkF7NgI8DAELIAIoAiwoAgRBKkYEQCACIAIoAiwoAjBBBHRBiH9qQQh0NgIoAkACQCACKAIsKAKIAUECSARAIAIoAiwoAoQBQQJODQELIAJBADYCJAwBCwJAIAIoAiwoAoQBQQZIBEAgAkEBNgIkDAELAkAgAigCLCgChAFBBkYEQCACQQI2AiQMAQsgAkEDNgIkCwsLIAIgAigCKCACKAIkQQZ0cjYCKCACKAIsKAJsBEAgAiACKAIoQSByNgIoCyACIAIoAihBHyACKAIoQR9wa2o2AiggAigCLCACKAIoEEwgAigCLCgCbARAIAIoAiwgAigCOCgCMEEQdhBMIAIoAiwgAigCOCgCMEH//wNxEEwLQQBBAEEAED4hACACKAI4IAA2AjAgAigCLEHxADYCBCACKAI4EB0gAigCLCgCFARAIAIoAixBfzYCKCACQQA2AjwMAgsLIAIoAiwoAgRBOUYEQEEAQQBBABAbIQAgAigCOCAANgIwIAIoAiwoAgghASACKAIsIgMoAhQhACADIABBAWo2AhQgACABakEfOgAAIAIoAiwoAgghASACKAIsIgMoAhQhACADIABBAWo2AhQgACABakGLAToAACACKAIsKAIIIQEgAigCLCIDKAIUIQAgAyAAQQFqNgIUIAAgAWpBCDoAAAJAIAIoAiwoAhxFBEAgAigCLCgCCCEBIAIoAiwiAygCFCEAIAMgAEEBajYCFCAAIAFqQQA6AAAgAigCLCgCCCEBIAIoAiwiAygCFCEAIAMgAEEBajYCFCAAIAFqQQA6AAAgAigCLCgCCCEBIAIoAiwiAygCFCEAIAMgAEEBajYCFCAAIAFqQQA6AAAgAigCLCgCCCEBIAIoAiwiAygCFCEAIAMgAEEBajYCFCAAIAFqQQA6AAAgAigCLCgCCCEBIAIoAiwiAygCFCEAIAMgAEEBajYCFCAAIAFqQQA6AAACf0ECIAIoAiwoAoQBQQlGDQAaQQEhAEEEQQAgAigCLCgCiAFBAkgEfyACKAIsKAKEAUECSAVBAQtBAXEbCyEAIAIoAiwoAgghAyACKAIsIgQoAhQhASAEIAFBAWo2AhQgASADaiAAOgAAIAIoAiwoAgghASACKAIsIgMoAhQhACADIABBAWo2AhQgACABakEDOgAAIAIoAixB8QA2AgQgAigCOBAdIAIoAiwoAhQEQCACKAIsQX82AiggAkEANgI8DAQLDAELIAIoAiwoAhwoAgBFRUECQQAgAigCLCgCHCgCLBtqQQRBACACKAIsKAIcKAIQG2pBCEEAIAIoAiwoAhwoAhwbakEQQQAgAigCLCgCHCgCJBtqIQEgAigCLCgCCCEDIAIoAiwiBCgCFCEAIAQgAEEBajYCFCAAIANqIAE6AAAgAigCLCgCHCgCBEH/AXEhASACKAIsKAIIIQMgAigCLCIEKAIUIQAgBCAAQQFqNgIUIAAgA2ogAToAACACKAIsKAIcKAIEQQh2Qf8BcSEBIAIoAiwoAgghAyACKAIsIgQoAhQhACAEIABBAWo2AhQgACADaiABOgAAIAIoAiwoAhwoAgRBEHZB/wFxIQEgAigCLCgCCCEDIAIoAiwiBCgCFCEAIAQgAEEBajYCFCAAIANqIAE6AAAgAigCLCgCHCgCBEEYdiEBIAIoAiwoAgghAyACKAIsIgQoAhQhACAEIABBAWo2AhQgACADaiABOgAAAn9BAiACKAIsKAKEAUEJRg0AGkEBIQBBBEEAIAIoAiwoAogBQQJIBH8gAigCLCgChAFBAkgFQQELQQFxGwshACACKAIsKAIIIQMgAigCLCIEKAIUIQEgBCABQQFqNgIUIAEgA2ogADoAACACKAIsKAIcKAIMQf8BcSEBIAIoAiwoAgghAyACKAIsIgQoAhQhACAEIABBAWo2AhQgACADaiABOgAAIAIoAiwoAhwoAhAEQCACKAIsKAIcKAIUQf8BcSEBIAIoAiwoAgghAyACKAIsIgQoAhQhACAEIABBAWo2AhQgACADaiABOgAAIAIoAiwoAhwoAhRBCHZB/wFxIQEgAigCLCgCCCEDIAIoAiwiBCgCFCEAIAQgAEEBajYCFCAAIANqIAE6AAALIAIoAiwoAhwoAiwEQCACKAI4KAIwIAIoAiwoAgggAigCLCgCFBAbIQAgAigCOCAANgIwCyACKAIsQQA2AiAgAigCLEHFADYCBAsLIAIoAiwoAgRBxQBGBEAgAigCLCgCHCgCEARAIAIgAigCLCgCFDYCICACIAIoAiwoAhwoAhRB//8DcSACKAIsKAIgazYCHANAIAIoAiwoAhQgAigCHGogAigCLCgCDEsEQCACIAIoAiwoAgwgAigCLCgCFGs2AhggAigCLCgCCCACKAIsKAIUaiACKAIsKAIcKAIQIAIoAiwoAiBqIAIoAhgQGhogAigCLCACKAIsKAIMNgIUAkAgAigCLCgCHCgCLEUNACACKAIsKAIUIAIoAiBNDQAgAigCOCgCMCACKAIsKAIIIAIoAiBqIAIoAiwoAhQgAigCIGsQGyEAIAIoAjggADYCMAsgAigCLCIAIAIoAhggACgCIGo2AiAgAigCOBAdIAIoAiwoAhQEQCACKAIsQX82AiggAkEANgI8DAUFIAJBADYCICACIAIoAhwgAigCGGs2AhwMAgsACwsgAigCLCgCCCACKAIsKAIUaiACKAIsKAIcKAIQIAIoAiwoAiBqIAIoAhwQGhogAigCLCIAIAIoAhwgACgCFGo2AhQCQCACKAIsKAIcKAIsRQ0AIAIoAiwoAhQgAigCIE0NACACKAI4KAIwIAIoAiwoAgggAigCIGogAigCLCgCFCACKAIgaxAbIQAgAigCOCAANgIwCyACKAIsQQA2AiALIAIoAixByQA2AgQLIAIoAiwoAgRByQBGBEAgAigCLCgCHCgCHARAIAIgAigCLCgCFDYCFANAIAIoAiwoAhQgAigCLCgCDEYEQAJAIAIoAiwoAhwoAixFDQAgAigCLCgCFCACKAIUTQ0AIAIoAjgoAjAgAigCLCgCCCACKAIUaiACKAIsKAIUIAIoAhRrEBshACACKAI4IAA2AjALIAIoAjgQHSACKAIsKAIUBEAgAigCLEF/NgIoIAJBADYCPAwFCyACQQA2AhQLIAIoAiwoAhwoAhwhASACKAIsIgMoAiAhACADIABBAWo2AiAgAiAAIAFqLQAANgIQIAIoAhAhASACKAIsKAIIIQMgAigCLCIEKAIUIQAgBCAAQQFqNgIUIAAgA2ogAToAACACKAIQDQALAkAgAigCLCgCHCgCLEUNACACKAIsKAIUIAIoAhRNDQAgAigCOCgCMCACKAIsKAIIIAIoAhRqIAIoAiwoAhQgAigCFGsQGyEAIAIoAjggADYCMAsgAigCLEEANgIgCyACKAIsQdsANgIECyACKAIsKAIEQdsARgRAIAIoAiwoAhwoAiQEQCACIAIoAiwoAhQ2AgwDQCACKAIsKAIUIAIoAiwoAgxGBEACQCACKAIsKAIcKAIsRQ0AIAIoAiwoAhQgAigCDE0NACACKAI4KAIwIAIoAiwoAgggAigCDGogAigCLCgCFCACKAIMaxAbIQAgAigCOCAANgIwCyACKAI4EB0gAigCLCgCFARAIAIoAixBfzYCKCACQQA2AjwMBQsgAkEANgIMCyACKAIsKAIcKAIkIQEgAigCLCIDKAIgIQAgAyAAQQFqNgIgIAIgACABai0AADYCCCACKAIIIQEgAigCLCgCCCEDIAIoAiwiBCgCFCEAIAQgAEEBajYCFCAAIANqIAE6AAAgAigCCA0ACwJAIAIoAiwoAhwoAixFDQAgAigCLCgCFCACKAIMTQ0AIAIoAjgoAjAgAigCLCgCCCACKAIMaiACKAIsKAIUIAIoAgxrEBshACACKAI4IAA2AjALCyACKAIsQecANgIECyACKAIsKAIEQecARgRAIAIoAiwoAhwoAiwEQCACKAIsKAIUQQJqIAIoAiwoAgxLBEAgAigCOBAdIAIoAiwoAhQEQCACKAIsQX82AiggAkEANgI8DAQLCyACKAI4KAIwQf8BcSEBIAIoAiwoAgghAyACKAIsIgQoAhQhACAEIABBAWo2AhQgACADaiABOgAAIAIoAjgoAjBBCHZB/wFxIQEgAigCLCgCCCEDIAIoAiwiBCgCFCEAIAQgAEEBajYCFCAAIANqIAE6AABBAEEAQQAQGyEAIAIoAjggADYCMAsgAigCLEHxADYCBCACKAI4EB0gAigCLCgCFARAIAIoAixBfzYCKCACQQA2AjwMAgsLAkACQCACKAI4KAIEDQAgAigCLCgCdA0AIAIoAjRFDQEgAigCLCgCBEGaBUYNAQsgAgJ/IAIoAiwoAoQBRQRAIAIoAiwgAigCNBCxAQwBCwJ/IAIoAiwoAogBQQJGBEAgAigCLCACKAI0ENoCDAELAn8gAigCLCgCiAFBA0YEQCACKAIsIAIoAjQQ2QIMAQsgAigCLCACKAI0IAIoAiwoAoQBQQxsQbDqAGooAggRAgALCws2AgQCQCACKAIEQQJHBEAgAigCBEEDRw0BCyACKAIsQZoFNgIECwJAIAIoAgQEQCACKAIEQQJHDQELIAIoAjgoAhBFBEAgAigCLEF/NgIoCyACQQA2AjwMAgsgAigCBEEBRgRAAkAgAigCNEEBRgRAIAIoAiwQ6AIMAQsgAigCNEEFRwRAIAIoAixBAEEAQQAQVyACKAI0QQNGBEAgAigCLCgCRCACKAIsKAJMQQFrQQF0akEAOwEAIAIoAiwoAkRBACACKAIsKAJMQQFrQQF0EDMgAigCLCgCdEUEQCACKAIsQQA2AmwgAigCLEEANgJcIAIoAixBADYCtC0LCwsLIAIoAjgQHSACKAI4KAIQRQRAIAIoAixBfzYCKCACQQA2AjwMAwsLCyACKAI0QQRHBEAgAkEANgI8DAELIAIoAiwoAhhBAEwEQCACQQE2AjwMAQsCQCACKAIsKAIYQQJGBEAgAigCOCgCMEH/AXEhASACKAIsKAIIIQMgAigCLCIEKAIUIQAgBCAAQQFqNgIUIAAgA2ogAToAACACKAI4KAIwQQh2Qf8BcSEBIAIoAiwoAgghAyACKAIsIgQoAhQhACAEIABBAWo2AhQgACADaiABOgAAIAIoAjgoAjBBEHZB/wFxIQEgAigCLCgCCCEDIAIoAiwiBCgCFCEAIAQgAEEBajYCFCAAIANqIAE6AAAgAigCOCgCMEEYdiEBIAIoAiwoAgghAyACKAIsIgQoAhQhACAEIABBAWo2AhQgACADaiABOgAAIAIoAjgoAghB/wFxIQEgAigCLCgCCCEDIAIoAiwiBCgCFCEAIAQgAEEBajYCFCAAIANqIAE6AAAgAigCOCgCCEEIdkH/AXEhASACKAIsKAIIIQMgAigCLCIEKAIUIQAgBCAAQQFqNgIUIAAgA2ogAToAACACKAI4KAIIQRB2Qf8BcSEBIAIoAiwoAgghAyACKAIsIgQoAhQhACAEIABBAWo2AhQgACADaiABOgAAIAIoAjgoAghBGHYhASACKAIsKAIIIQMgAigCLCIEKAIUIQAgBCAAQQFqNgIUIAAgA2ogAToAAAwBCyACKAIsIAIoAjgoAjBBEHYQTCACKAIsIAIoAjgoAjBB//8DcRBMCyACKAI4EB0gAigCLCgCGEEASgRAIAIoAixBACACKAIsKAIYazYCGAsgAiACKAIsKAIURTYCPAsgAigCPCEAIAJBQGskACAAC44CAQF/IwBBIGsiASAANgIcIAEgASgCHCgCLDYCDCABIAEoAhwoAkw2AhggASABKAIcKAJEIAEoAhhBAXRqNgIQA0AgASABKAIQQX5qIgA2AhAgASAALwEANgIUIAEoAhACfyABKAIUIAEoAgxPBEAgASgCFCABKAIMawwBC0EACzsBACABIAEoAhhBf2oiADYCGCAADQALIAEgASgCDDYCGCABIAEoAhwoAkAgASgCGEEBdGo2AhADQCABIAEoAhBBfmoiADYCECABIAAvAQA2AhQgASgCEAJ/IAEoAhQgASgCDE8EQCABKAIUIAEoAgxrDAELQQALOwEAIAEgASgCGEF/aiIANgIYIAANAAsLRQBBoJwBQgA3AwBBmJwBQgA3AwBBkJwBQgA3AwBBiJwBQgA3AwBBgJwBQgA3AwBB+JsBQgA3AwBB8JsBQgA3AwBB8JsBC6gCAQF/IwBBEGsiASQAIAEgADYCDCABKAIMIAEoAgwoAixBAXQ2AjwgASgCDCgCRCABKAIMKAJMQQFrQQF0akEAOwEAIAEoAgwoAkRBACABKAIMKAJMQQFrQQF0EDMgASgCDCABKAIMKAKEAUEMbEGw6gBqLwECNgKAASABKAIMIAEoAgwoAoQBQQxsQbDqAGovAQA2AowBIAEoAgwgASgCDCgChAFBDGxBsOoAai8BBDYCkAEgASgCDCABKAIMKAKEAUEMbEGw6gBqLwEGNgJ8IAEoAgxBADYCbCABKAIMQQA2AlwgASgCDEEANgJ0IAEoAgxBADYCtC0gASgCDEECNgJ4IAEoAgxBAjYCYCABKAIMQQA2AmggASgCDEEANgJIIAFBEGokAAubAgEBfyMAQRBrIgEkACABIAA2AggCQCABKAIIEHQEQCABQX42AgwMAQsgASgCCEEANgIUIAEoAghBADYCCCABKAIIQQA2AhggASgCCEECNgIsIAEgASgCCCgCHDYCBCABKAIEQQA2AhQgASgCBCABKAIEKAIINgIQIAEoAgQoAhhBAEgEQCABKAIEQQAgASgCBCgCGGs2AhgLIAEoAgQCf0E5IAEoAgQoAhhBAkYNABpBKkHxACABKAIEKAIYGws2AgQCfyABKAIEKAIYQQJGBEBBAEEAQQAQGwwBC0EAQQBBABA+CyEAIAEoAgggADYCMCABKAIEQQA2AiggASgCBBDqAiABQQA2AgwLIAEoAgwhACABQRBqJAAgAAtFAQF/IwBBEGsiASQAIAEgADYCDCABIAEoAgwQ3wI2AgggASgCCEUEQCABKAIMKAIcEN4CCyABKAIIIQAgAUEQaiQAIAAL4AgBAX8jAEEwayICJAAgAiAANgIoIAIgATYCJCACQQg2AiAgAkFxNgIcIAJBCTYCGCACQQA2AhQgAkGQgwE2AhAgAkE4NgIMIAJBATYCBAJAAkACQCACKAIQRQ0AIAIoAhAsAABBqOoALAAARw0AIAIoAgxBOEYNAQsgAkF6NgIsDAELIAIoAihFBEAgAkF+NgIsDAELIAIoAihBADYCGCACKAIoKAIgRQRAIAIoAihBBTYCICACKAIoQQA2AigLIAIoAigoAiRFBEAgAigCKEEGNgIkCyACKAIkQX9GBEAgAkEGNgIkCwJAIAIoAhxBAEgEQCACQQA2AgQgAkEAIAIoAhxrNgIcDAELIAIoAhxBD0oEQCACQQI2AgQgAiACKAIcQRBrNgIcCwsCQAJAIAIoAhhBAUgNACACKAIYQQlKDQAgAigCIEEIRw0AIAIoAhxBCEgNACACKAIcQQ9KDQAgAigCJEEASA0AIAIoAiRBCUoNACACKAIUQQBIDQAgAigCFEEESg0AIAIoAhxBCEcNASACKAIEQQFGDQELIAJBfjYCLAwBCyACKAIcQQhGBEAgAkEJNgIcCyACIAIoAigoAihBAUHELSACKAIoKAIgEQEANgIIIAIoAghFBEAgAkF8NgIsDAELIAIoAiggAigCCDYCHCACKAIIIAIoAig2AgAgAigCCEEqNgIEIAIoAgggAigCBDYCGCACKAIIQQA2AhwgAigCCCACKAIcNgIwIAIoAghBASACKAIIKAIwdDYCLCACKAIIIAIoAggoAixBAWs2AjQgAigCCCACKAIYQQdqNgJQIAIoAghBASACKAIIKAJQdDYCTCACKAIIIAIoAggoAkxBAWs2AlQgAigCCCACKAIIKAJQQQJqQQNuNgJYIAIoAigoAiggAigCCCgCLEECIAIoAigoAiARAQAhACACKAIIIAA2AjggAigCKCgCKCACKAIIKAIsQQIgAigCKCgCIBEBACEAIAIoAgggADYCQCACKAIoKAIoIAIoAggoAkxBAiACKAIoKAIgEQEAIQAgAigCCCAANgJEIAIoAghBADYCwC0gAigCCEEBIAIoAhhBBmp0NgKcLSACIAIoAigoAiggAigCCCgCnC1BBCACKAIoKAIgEQEANgIAIAIoAgggAigCADYCCCACKAIIIAIoAggoApwtQQJ0NgIMAkACQCACKAIIKAI4RQ0AIAIoAggoAkBFDQAgAigCCCgCREUNACACKAIIKAIIDQELIAIoAghBmgU2AgQgAigCKEHo1AAoAgA2AhggAigCKBCyARogAkF8NgIsDAELIAIoAgggAigCACACKAIIKAKcLUEBdkEBdGo2AqQtIAIoAgggAigCCCgCCCACKAIIKAKcLUEDbGo2ApgtIAIoAgggAigCJDYChAEgAigCCCACKAIUNgKIASACKAIIIAIoAiA6ACQgAiACKAIoEOACNgIsCyACKAIsIQAgAkEwaiQAIAALbAEBfyMAQRBrIgIgADYCDCACIAE2AgggAkEANgIEA0AgAiACKAIEIAIoAgxBAXFyNgIEIAIgAigCDEEBdjYCDCACIAIoAgRBAXQ2AgQgAiACKAIIQX9qIgA2AgggAEEASg0ACyACKAIEQQF2C5UCAQF/IwBBQGoiAyQAIAMgADYCPCADIAE2AjggAyACNgI0IANBADYCDCADQQE2AggDQCADKAIIQQ9KRQRAIAMgAygCDCADKAI0IAMoAghBAWtBAXRqLwEAakEBdDYCDCADQRBqIAMoAghBAXRqIAMoAgw7AQAgAyADKAIIQQFqNgIIDAELCyADQQA2AgQDQCADKAIEIAMoAjhMBEAgAyADKAI8IAMoAgRBAnRqLwECNgIAIAMoAgAEQCADQRBqIAMoAgBBAXRqIgEvAQAhACABIABBAWo7AQAgAEH//wNxIAMoAgAQ4gIhACADKAI8IAMoAgRBAnRqIAA7AQALIAMgAygCBEEBajYCBAwBCwsgA0FAayQAC4gIAQF/IwBBQGoiAiAANgI8IAIgATYCOCACIAIoAjgoAgA2AjQgAiACKAI4KAIENgIwIAIgAigCOCgCCCgCADYCLCACIAIoAjgoAggoAgQ2AiggAiACKAI4KAIIKAIINgIkIAIgAigCOCgCCCgCEDYCICACQQA2AgQgAkEANgIQA0AgAigCEEEPSkUEQCACKAI8QbwWaiACKAIQQQF0akEAOwEAIAIgAigCEEEBajYCEAwBCwsgAigCNCACKAI8QdwWaiACKAI8KALUKEECdGooAgBBAnRqQQA7AQIgAiACKAI8KALUKEEBajYCHANAIAIoAhxBvQRIBEAgAiACKAI8QdwWaiACKAIcQQJ0aigCADYCGCACIAIoAjQgAigCNCACKAIYQQJ0ai8BAkECdGovAQJBAWo2AhAgAigCECACKAIgSgRAIAIgAigCIDYCECACIAIoAgRBAWo2AgQLIAIoAjQgAigCGEECdGogAigCEDsBAiACKAIYIAIoAjBMBEAgAigCPCACKAIQQQF0akG8FmoiACAALwEAQQFqOwEAIAJBADYCDCACKAIYIAIoAiROBEAgAiACKAIoIAIoAhggAigCJGtBAnRqKAIANgIMCyACIAIoAjQgAigCGEECdGovAQA7AQogAigCPCIAIAAoAqgtIAIvAQogAigCECACKAIMamxqNgKoLSACKAIsBEAgAigCPCIAIAAoAqwtIAIvAQogAigCLCACKAIYQQJ0ai8BAiACKAIMamxqNgKsLQsLIAIgAigCHEEBajYCHAwBCwsCQCACKAIERQ0AA0AgAiACKAIgQQFrNgIQA0AgAigCPEG8FmogAigCEEEBdGovAQBFBEAgAiACKAIQQX9qNgIQDAELCyACKAI8IAIoAhBBAXRqQbwWaiIAIAAvAQBBf2o7AQAgAigCPCACKAIQQQF0akG+FmoiACAALwEAQQJqOwEAIAIoAjwgAigCIEEBdGpBvBZqIgAgAC8BAEF/ajsBACACIAIoAgRBAms2AgQgAigCBEEASg0ACyACIAIoAiA2AhADQCACKAIQRQ0BIAIgAigCPEG8FmogAigCEEEBdGovAQA2AhgDQCACKAIYBEAgAigCPEHcFmohACACIAIoAhxBf2oiATYCHCACIAFBAnQgAGooAgA2AhQgAigCFCACKAIwSg0BIAIoAjQgAigCFEECdGovAQIgAigCEEcEQCACKAI8IgAgACgCqC0gAigCNCACKAIUQQJ0ai8BACACKAIQIAIoAjQgAigCFEECdGovAQJrbGo2AqgtIAIoAjQgAigCFEECdGogAigCEDsBAgsgAiACKAIYQX9qNgIYDAELCyACIAIoAhBBf2o2AhAMAAALAAsLpQsBAX8jAEFAaiIEJAAgBCAANgI8IAQgATYCOCAEIAI2AjQgBCADNgIwIARBBTYCKAJAIAQoAjwoArwtQRAgBCgCKGtKBEAgBCAEKAI4QYECazYCJCAEKAI8IgAgAC8BuC0gBCgCJEH//wNxIAQoAjwoArwtdHI7AbgtIAQoAjwvAbgtQf8BcSEBIAQoAjwoAgghAiAEKAI8IgMoAhQhACADIABBAWo2AhQgACACaiABOgAAIAQoAjwvAbgtQQh1IQEgBCgCPCgCCCECIAQoAjwiAygCFCEAIAMgAEEBajYCFCAAIAJqIAE6AAAgBCgCPCAEKAIkQf//A3FBECAEKAI8KAK8LWt1OwG4LSAEKAI8IgAgACgCvC0gBCgCKEEQa2o2ArwtDAELIAQoAjwiACAALwG4LSAEKAI4QYECa0H//wNxIAQoAjwoArwtdHI7AbgtIAQoAjwiACAEKAIoIAAoArwtajYCvC0LIARBBTYCIAJAIAQoAjwoArwtQRAgBCgCIGtKBEAgBCAEKAI0QQFrNgIcIAQoAjwiACAALwG4LSAEKAIcQf//A3EgBCgCPCgCvC10cjsBuC0gBCgCPC8BuC1B/wFxIQEgBCgCPCgCCCECIAQoAjwiAygCFCEAIAMgAEEBajYCFCAAIAJqIAE6AAAgBCgCPC8BuC1BCHUhASAEKAI8KAIIIQIgBCgCPCIDKAIUIQAgAyAAQQFqNgIUIAAgAmogAToAACAEKAI8IAQoAhxB//8DcUEQIAQoAjwoArwta3U7AbgtIAQoAjwiACAAKAK8LSAEKAIgQRBrajYCvC0MAQsgBCgCPCIAIAAvAbgtIAQoAjRBAWtB//8DcSAEKAI8KAK8LXRyOwG4LSAEKAI8IgAgBCgCICAAKAK8LWo2ArwtCyAEQQQ2AhgCQCAEKAI8KAK8LUEQIAQoAhhrSgRAIAQgBCgCMEEEazYCFCAEKAI8IgAgAC8BuC0gBCgCFEH//wNxIAQoAjwoArwtdHI7AbgtIAQoAjwvAbgtQf8BcSEBIAQoAjwoAgghAiAEKAI8IgMoAhQhACADIABBAWo2AhQgACACaiABOgAAIAQoAjwvAbgtQQh1IQEgBCgCPCgCCCECIAQoAjwiAygCFCEAIAMgAEEBajYCFCAAIAJqIAE6AAAgBCgCPCAEKAIUQf//A3FBECAEKAI8KAK8LWt1OwG4LSAEKAI8IgAgACgCvC0gBCgCGEEQa2o2ArwtDAELIAQoAjwiACAALwG4LSAEKAIwQQRrQf//A3EgBCgCPCgCvC10cjsBuC0gBCgCPCIAIAQoAhggACgCvC1qNgK8LQsgBEEANgIsA0AgBCgCLCAEKAIwTkUEQCAEQQM2AhACQCAEKAI8KAK8LUEQIAQoAhBrSgRAIAQgBCgCPEH8FGogBCgCLC0AkGhBAnRqLwECNgIMIAQoAjwiACAALwG4LSAEKAIMQf//A3EgBCgCPCgCvC10cjsBuC0gBCgCPC8BuC1B/wFxIQEgBCgCPCgCCCECIAQoAjwiAygCFCEAIAMgAEEBajYCFCAAIAJqIAE6AAAgBCgCPC8BuC1BCHUhASAEKAI8KAIIIQIgBCgCPCIDKAIUIQAgAyAAQQFqNgIUIAAgAmogAToAACAEKAI8IAQoAgxB//8DcUEQIAQoAjwoArwta3U7AbgtIAQoAjwiACAAKAK8LSAEKAIQQRBrajYCvC0MAQsgBCgCPCIAIAAvAbgtIAQoAjxB/BRqIAQoAiwtAJBoQQJ0ai8BAiAEKAI8KAK8LXRyOwG4LSAEKAI8IgAgBCgCECAAKAK8LWo2ArwtCyAEIAQoAixBAWo2AiwMAQsLIAQoAjwgBCgCPEGUAWogBCgCOEEBaxCzASAEKAI8IAQoAjxBiBNqIAQoAjRBAWsQswEgBEFAayQAC8YBAQF/IwBBEGsiASQAIAEgADYCDCABKAIMIAEoAgxBlAFqIAEoAgwoApwWELQBIAEoAgwgASgCDEGIE2ogASgCDCgCqBYQtAEgASgCDCABKAIMQbAWahB2IAFBEjYCCANAAkAgASgCCEEDSA0AIAEoAgxB/BRqIAEoAggtAJBoQQJ0ai8BAg0AIAEgASgCCEF/ajYCCAwBCwsgASgCDCIAIAAoAqgtIAEoAghBA2xBEWpqNgKoLSABKAIIIQAgAUEQaiQAIAALgwIBAX8jAEEQayIBIAA2AgggAUH/gP+ffzYCBCABQQA2AgACQANAIAEoAgBBH0wEQAJAIAEoAgRBAXFFDQAgASgCCEGUAWogASgCAEECdGovAQBFDQAgAUEANgIMDAMLIAEgASgCAEEBajYCACABIAEoAgRBAXY2AgQMAQsLAkACQCABKAIILwG4AQ0AIAEoAggvAbwBDQAgASgCCC8ByAFFDQELIAFBATYCDAwBCyABQSA2AgADQCABKAIAQYACSARAIAEoAghBlAFqIAEoAgBBAnRqLwEABEAgAUEBNgIMDAMFIAEgASgCAEEBajYCAAwCCwALCyABQQA2AgwLIAEoAgwLjgUBBH8jAEEgayIBJAAgASAANgIcIAFBAzYCGAJAIAEoAhwoArwtQRAgASgCGGtKBEAgAUECNgIUIAEoAhwiACAALwG4LSABKAIUQf//A3EgASgCHCgCvC10cjsBuC0gASgCHC8BuC1B/wFxIQIgASgCHCgCCCEDIAEoAhwiBCgCFCEAIAQgAEEBajYCFCAAIANqIAI6AAAgASgCHC8BuC1BCHUhAiABKAIcKAIIIQMgASgCHCIEKAIUIQAgBCAAQQFqNgIUIAAgA2ogAjoAACABKAIcIAEoAhRB//8DcUEQIAEoAhwoArwta3U7AbgtIAEoAhwiACAAKAK8LSABKAIYQRBrajYCvC0MAQsgASgCHCIAIAAvAbgtQQIgASgCHCgCvC10cjsBuC0gASgCHCIAIAEoAhggACgCvC1qNgK8LQsgAUHC4wAvAQA2AhACQCABKAIcKAK8LUEQIAEoAhBrSgRAIAFBwOMALwEANgIMIAEoAhwiACAALwG4LSABKAIMQf//A3EgASgCHCgCvC10cjsBuC0gASgCHC8BuC1B/wFxIQIgASgCHCgCCCEDIAEoAhwiBCgCFCEAIAQgAEEBajYCFCAAIANqIAI6AAAgASgCHC8BuC1BCHUhAiABKAIcKAIIIQMgASgCHCIEKAIUIQAgBCAAQQFqNgIUIAAgA2ogAjoAACABKAIcIAEoAgxB//8DcUEQIAEoAhwoArwta3U7AbgtIAEoAhwiACAAKAK8LSABKAIQQRBrajYCvC0MAQsgASgCHCIAIAAvAbgtQcDjAC8BACABKAIcKAK8LXRyOwG4LSABKAIcIgAgASgCECAAKAK8LWo2ArwtCyABKAIcELcBIAFBIGokAAsjAQF/IwBBEGsiASQAIAEgADYCDCABKAIMELcBIAFBEGokAAuWAQEBfyMAQRBrIgEkACABIAA2AgwgASgCDCABKAIMQZQBajYCmBYgASgCDEGA2wA2AqAWIAEoAgwgASgCDEGIE2o2AqQWIAEoAgxBlNsANgKsFiABKAIMIAEoAgxB/BRqNgKwFiABKAIMQajbADYCuBYgASgCDEEAOwG4LSABKAIMQQA2ArwtIAEoAgwQuQEgAUEQaiQAC9cNAQF/IwBBIGsiAyAANgIYIAMgATYCFCADIAI2AhAgAyADKAIYQRB2NgIMIAMgAygCGEH//wNxNgIYAkAgAygCEEEBRgRAIAMgAygCFC0AACADKAIYajYCGCADKAIYQfH/A08EQCADIAMoAhhB8f8DazYCGAsgAyADKAIYIAMoAgxqNgIMIAMoAgxB8f8DTwRAIAMgAygCDEHx/wNrNgIMCyADIAMoAhggAygCDEEQdHI2AhwMAQsgAygCFEUEQCADQQE2AhwMAQsgAygCEEEQSQRAA0AgAyADKAIQIgBBf2o2AhAgAARAIAMgAygCFCIAQQFqNgIUIAMgAC0AACADKAIYajYCGCADIAMoAhggAygCDGo2AgwMAQsLIAMoAhhB8f8DTwRAIAMgAygCGEHx/wNrNgIYCyADIAMoAgxB8f8DcDYCDCADIAMoAhggAygCDEEQdHI2AhwMAQsDQCADKAIQQbArSUUEQCADIAMoAhBBsCtrNgIQIANB2wI2AggDQCADIAMoAhQtAAAgAygCGGo2AhggAyADKAIYIAMoAgxqNgIMIAMgAygCFC0AASADKAIYajYCGCADIAMoAhggAygCDGo2AgwgAyADKAIULQACIAMoAhhqNgIYIAMgAygCGCADKAIMajYCDCADIAMoAhQtAAMgAygCGGo2AhggAyADKAIYIAMoAgxqNgIMIAMgAygCFC0ABCADKAIYajYCGCADIAMoAhggAygCDGo2AgwgAyADKAIULQAFIAMoAhhqNgIYIAMgAygCGCADKAIMajYCDCADIAMoAhQtAAYgAygCGGo2AhggAyADKAIYIAMoAgxqNgIMIAMgAygCFC0AByADKAIYajYCGCADIAMoAhggAygCDGo2AgwgAyADKAIULQAIIAMoAhhqNgIYIAMgAygCGCADKAIMajYCDCADIAMoAhQtAAkgAygCGGo2AhggAyADKAIYIAMoAgxqNgIMIAMgAygCFC0ACiADKAIYajYCGCADIAMoAhggAygCDGo2AgwgAyADKAIULQALIAMoAhhqNgIYIAMgAygCGCADKAIMajYCDCADIAMoAhQtAAwgAygCGGo2AhggAyADKAIYIAMoAgxqNgIMIAMgAygCFC0ADSADKAIYajYCGCADIAMoAhggAygCDGo2AgwgAyADKAIULQAOIAMoAhhqNgIYIAMgAygCGCADKAIMajYCDCADIAMoAhQtAA8gAygCGGo2AhggAyADKAIYIAMoAgxqNgIMIAMgAygCFEEQajYCFCADIAMoAghBf2oiADYCCCAADQALIAMgAygCGEHx/wNwNgIYIAMgAygCDEHx/wNwNgIMDAELCyADKAIQBEADQCADKAIQQRBJRQRAIAMgAygCEEEQazYCECADIAMoAhQtAAAgAygCGGo2AhggAyADKAIYIAMoAgxqNgIMIAMgAygCFC0AASADKAIYajYCGCADIAMoAhggAygCDGo2AgwgAyADKAIULQACIAMoAhhqNgIYIAMgAygCGCADKAIMajYCDCADIAMoAhQtAAMgAygCGGo2AhggAyADKAIYIAMoAgxqNgIMIAMgAygCFC0ABCADKAIYajYCGCADIAMoAhggAygCDGo2AgwgAyADKAIULQAFIAMoAhhqNgIYIAMgAygCGCADKAIMajYCDCADIAMoAhQtAAYgAygCGGo2AhggAyADKAIYIAMoAgxqNgIMIAMgAygCFC0AByADKAIYajYCGCADIAMoAhggAygCDGo2AgwgAyADKAIULQAIIAMoAhhqNgIYIAMgAygCGCADKAIMajYCDCADIAMoAhQtAAkgAygCGGo2AhggAyADKAIYIAMoAgxqNgIMIAMgAygCFC0ACiADKAIYajYCGCADIAMoAhggAygCDGo2AgwgAyADKAIULQALIAMoAhhqNgIYIAMgAygCGCADKAIMajYCDCADIAMoAhQtAAwgAygCGGo2AhggAyADKAIYIAMoAgxqNgIMIAMgAygCFC0ADSADKAIYajYCGCADIAMoAhggAygCDGo2AgwgAyADKAIULQAOIAMoAhhqNgIYIAMgAygCGCADKAIMajYCDCADIAMoAhQtAA8gAygCGGo2AhggAyADKAIYIAMoAgxqNgIMIAMgAygCFEEQajYCFAwBCwsDQCADIAMoAhAiAEF/ajYCECAABEAgAyADKAIUIgBBAWo2AhQgAyAALQAAIAMoAhhqNgIYIAMgAygCGCADKAIMajYCDAwBCwsgAyADKAIYQfH/A3A2AhggAyADKAIMQfH/A3A2AgwLIAMgAygCGCADKAIMQRB0cjYCHAsgAygCHAspAQF/IwBBEGsiAiQAIAIgADYCDCACIAE2AgggAigCCBAWIAJBEGokAAs6AQF/IwBBEGsiAyQAIAMgADYCDCADIAE2AgggAyACNgIEIAMoAgggAygCBGwQGSEAIANBEGokACAAC70HAQl/IAAoAgQiB0EDcSECIAAgB0F4cSIGaiEEAkBByJwBKAIAIgUgAEsNACACQQFGDQALAkAgAkUEQEEAIQIgAUGAAkkNASAGIAFBBGpPBEAgACECIAYgAWtBmKABKAIAQQF0TQ0CC0EADwsCQCAGIAFPBEAgBiABayICQRBJDQEgACAHQQFxIAFyQQJyNgIEIAAgAWoiASACQQNyNgIEIAQgBCgCBEEBcjYCBCABIAIQtgEMAQtBACECIARB0JwBKAIARgRAQcScASgCACAGaiIFIAFNDQIgACAHQQFxIAFyQQJyNgIEIAAgAWoiAiAFIAFrIgFBAXI2AgRBxJwBIAE2AgBB0JwBIAI2AgAMAQsgBEHMnAEoAgBGBEBBwJwBKAIAIAZqIgUgAUkNAgJAIAUgAWsiAkEQTwRAIAAgB0EBcSABckECcjYCBCAAIAFqIgEgAkEBcjYCBCAAIAVqIgUgAjYCACAFIAUoAgRBfnE2AgQMAQsgACAHQQFxIAVyQQJyNgIEIAAgBWoiASABKAIEQQFyNgIEQQAhAkEAIQELQcycASABNgIAQcCcASACNgIADAELIAQoAgQiA0ECcQ0BIANBeHEgBmoiCSABSQ0BIAkgAWshCgJAIANB/wFNBEAgBCgCCCIGIANBA3YiBUEDdEHgnAFqRxogBiAEKAIMIghGBEBBuJwBQbicASgCAEF+IAV3cTYCAAwCCyAGIAg2AgwgCCAGNgIIDAELIAQoAhghCAJAIAQgBCgCDCIDRwRAIAUgBCgCCCICTQRAIAIoAgwaCyACIAM2AgwgAyACNgIIDAELAkAgBEEUaiICKAIAIgYNACAEQRBqIgIoAgAiBg0AQQAhAwwBCwNAIAIhBSAGIgNBFGoiAigCACIGDQAgA0EQaiECIAMoAhAiBg0ACyAFQQA2AgALIAhFDQACQCAEIAQoAhwiBUECdEHongFqIgIoAgBGBEAgAiADNgIAIAMNAUG8nAFBvJwBKAIAQX4gBXdxNgIADAILIAhBEEEUIAgoAhAgBEYbaiADNgIAIANFDQELIAMgCDYCGCAEKAIQIgIEQCADIAI2AhAgAiADNgIYCyAEKAIUIgJFDQAgAyACNgIUIAIgAzYCGAsgCkEPTQRAIAAgB0EBcSAJckECcjYCBCAAIAlqIgEgASgCBEEBcjYCBAwBCyAAIAdBAXEgAXJBAnI2AgQgACABaiICIApBA3I2AgQgACAJaiIBIAEoAgRBAXI2AgQgAiAKELYBCyAAIQILIAILhAICAX8BfiMAQeAAayICJAAgAiAANgJYIAIgATYCVCACIAIoAlggAkHIAGpCDBAvIgM3AwgCQCADQgBTBEAgAigCVCACKAJYEBggAkF/NgJcDAELIAIpAwhCDFIEQCACKAJUQRFBABAVIAJBfzYCXAwBCyACKAJUIAJByABqIgAgAEIMQQAQeCACKAJYIAJBEGoQOUEASARAIAJBADYCXAwBCyACKAI4IAJBBmogAkEEahDDAQJAIAItAFMgAigCPEEYdkYNACACLQBTIAIvAQZBCHVGDQAgAigCVEEbQQAQFSACQX82AlwMAQsgAkEANgJcCyACKAJcIQAgAkHgAGokACAAC8oDAQF/IwBB0ABrIgUkACAFIAA2AkQgBSABNgJAIAUgAjYCPCAFIAM3AzAgBSAENgIsIAUgBSgCQDYCKAJAAkACQAJAAkACQAJAAkACQCAFKAIsDg8AAQIDBQYHBwcHBwcHBwQHCyAFKAJEIAUoAigQ7wJBAEgEQCAFQn83A0gMCAsgBUIANwNIDAcLIAUgBSgCRCAFKAI8IAUpAzAQLyIDNwMgIANCAFMEQCAFKAIoIAUoAkQQGCAFQn83A0gMBwsgBSgCQCAFKAI8IAUoAjwgBSkDIEEAEHggBSAFKQMgNwNIDAYLIAVCADcDSAwFCyAFIAUoAjw2AhwgBSgCHEEAOwEyIAUoAhwiACAAKQMAQoABhDcDACAFKAIcKQMAQgiDQgBSBEAgBSgCHCIAIAApAyBCDH03AyALIAVCADcDSAwECyAFQX82AhQgBUEFNgIQIAVBBDYCDCAFQQM2AgggBUECNgIEIAVBATYCACAFQQAgBRA3NwNIDAMLIAUgBSgCKCAFKAI8IAUpAzAQQjcDSAwCCyAFKAIoELoBIAVCADcDSAwBCyAFKAIoQRJBABAVIAVCfzcDSAsgBSkDSCEDIAVB0ABqJAAgAwvuAgEBfyMAQSBrIgUkACAFIAA2AhggBSABNgIUIAUgAjsBEiAFIAM2AgwgBSAENgIIAkACQAJAIAUoAghFDQAgBSgCFEUNACAFLwESQQFGDQELIAUoAhhBCGpBEkEAEBUgBUEANgIcDAELIAUoAgxBAXEEQCAFKAIYQQhqQRhBABAVIAVBADYCHAwBCyAFQRgQGSIANgIEIABFBEAgBSgCGEEIakEOQQAQFSAFQQA2AhwMAQsjAEEQayIAIAUoAgQ2AgwgACgCDEEANgIAIAAoAgxBADYCBCAAKAIMQQA2AgggBSgCBEH4rNGRATYCDCAFKAIEQYnPlZoCNgIQIAUoAgRBkPHZogM2AhQgBSgCBEEAIAUoAgggBSgCCBAsrUEBEHggBSAFKAIYIAUoAhRBAyAFKAIEEGQiADYCACAARQRAIAUoAgQQugEgBUEANgIcDAELIAUgBSgCADYCHAsgBSgCHCEAIAVBIGokACAAC+gGAQF/IwBB4ABrIgQkACAEIAA2AlQgBCABNgJQIAQgAjcDSCAEIAM2AkQCQCAEKAJUKQM4IAQpA0h8QoCABHxCAX0gBCkDSFQEQCAEKAJEQRJBABAVIARCfzcDWAwBCyAEIAQoAlQoAgQgBCgCVCkDCKdBA3RqKQMANwMgIAQoAlQpAzggBCkDSHwgBCkDIFYEQCAEIAQoAlQpAwggBCkDSCAEKQMgIAQoAlQpAzh9fUKAgAR8QgF9QhCIfDcDGCAEKQMYIAQoAlQpAxBWBEAgBCAEKAJUKQMQNwMQIAQpAxBQBEAgBEIQNwMQCwNAIAQpAxAgBCkDGFpFBEAgBCAEKQMQQgGGNwMQDAELCyAEKAJUIAQpAxAgBCgCRBC9AUEBcUUEQCAEKAJEQQ5BABAVIARCfzcDWAwDCwsDQCAEKAJUKQMIIAQpAxhUBEBBgIAEEBkhACAEKAJUKAIAIAQoAlQpAwinQQR0aiAANgIAIAAEQCAEKAJUKAIAIAQoAlQpAwinQQR0akKAgAQ3AwggBCgCVCIAIAApAwhCAXw3AwggBCAEKQMgQoCABHw3AyAgBCgCVCgCBCAEKAJUKQMIp0EDdGogBCkDIDcDAAwCBSAEKAJEQQ5BABAVIARCfzcDWAwECwALCwsgBCAEKAJUKQNANwMwIAQgBCgCVCkDOCAEKAJUKAIEIAQpAzCnQQN0aikDAH03AyggBEIANwM4A0AgBCkDOCAEKQNIVARAIAQCfiAEKQNIIAQpAzh9IAQoAlQoAgAgBCkDMKdBBHRqKQMIIAQpAyh9VARAIAQpA0ggBCkDOH0MAQsgBCgCVCgCACAEKQMwp0EEdGopAwggBCkDKH0LNwMIIAQoAlQoAgAgBCkDMKdBBHRqKAIAIAQpAyinaiAEKAJQIAQpAzinaiAEKQMIpxAaGiAEKQMIIAQoAlQoAgAgBCkDMKdBBHRqKQMIIAQpAyh9UQRAIAQgBCkDMEIBfDcDMAsgBCAEKQMIIAQpAzh8NwM4IARCADcDKAwBCwsgBCgCVCIAIAQpAzggACkDOHw3AzggBCgCVCAEKQMwNwNAIAQoAlQpAzggBCgCVCkDMFYEQCAEKAJUIAQoAlQpAzg3AzALIAQgBCkDODcDWAsgBCkDWCECIARB4ABqJAAgAgvnAwEBfyMAQUBqIgMkACADIAA2AjQgAyABNgIwIAMgAjcDKCADAn4gAykDKCADKAI0KQMwIAMoAjQpAzh9VARAIAMpAygMAQsgAygCNCkDMCADKAI0KQM4fQs3AygCQCADKQMoUARAIANCADcDOAwBCyADKQMoQv///////////wBWBEAgA0J/NwM4DAELIAMgAygCNCkDQDcDGCADIAMoAjQpAzggAygCNCgCBCADKQMYp0EDdGopAwB9NwMQIANCADcDIANAIAMpAyAgAykDKFQEQCADAn4gAykDKCADKQMgfSADKAI0KAIAIAMpAxinQQR0aikDCCADKQMQfVQEQCADKQMoIAMpAyB9DAELIAMoAjQoAgAgAykDGKdBBHRqKQMIIAMpAxB9CzcDCCADKAIwIAMpAyCnaiADKAI0KAIAIAMpAxinQQR0aigCACADKQMQp2ogAykDCKcQGhogAykDCCADKAI0KAIAIAMpAxinQQR0aikDCCADKQMQfVEEQCADIAMpAxhCAXw3AxgLIAMgAykDCCADKQMgfDcDICADQgA3AxAMAQsLIAMoAjQiACADKQMgIAApAzh8NwM4IAMoAjQgAykDGDcDQCADIAMpAyA3AzgLIAMpAzghAiADQUBrJAAgAguuBAEBfyMAQUBqIgMkACADIAA2AjggAyABNwMwIAMgAjYCLAJAIAMpAzBQBEAgA0EAQgBBASADKAIsEE42AjwMAQsgAykDMCADKAI4KQMwVgRAIAMoAixBEkEAEBUgA0EANgI8DAELIAMoAjgoAigEQCADKAIsQR1BABAVIANBADYCPAwBCyADIAMoAjggAykDMBC7ATcDICADIAMpAzAgAygCOCgCBCADKQMgp0EDdGopAwB9NwMYIAMpAxhQBEAgAyADKQMgQn98NwMgIAMgAygCOCgCACADKQMgp0EEdGopAwg3AxgLIAMgAygCOCgCACADKQMgp0EEdGopAwggAykDGH03AxAgAykDECADKQMwVgRAIAMoAixBHEEAEBUgA0EANgI8DAELIAMgAygCOCgCACADKQMgQgF8QQAgAygCLBBOIgA2AgwgAEUEQCADQQA2AjwMAQsgAygCDCgCACADKAIMKQMIQgF9p0EEdGogAykDGDcDCCADKAIMKAIEIAMoAgwpAwinQQN0aiADKQMwNwMAIAMoAgwgAykDMDcDMCADKAIMAn4gAygCOCkDGCADKAIMKQMIQgF9VARAIAMoAjgpAxgMAQsgAygCDCkDCEIBfQs3AxggAygCOCADKAIMNgIoIAMoAgwgAygCODYCKCADKAI4IAMoAgwpAwg3AyAgAygCDCADKQMgQgF8NwMgIAMgAygCDDYCPAsgAygCPCEAIANBQGskACAAC8gJAQF/IwBB8ABrIgQkACAEIAA2AmQgBCABNgJgIAQgAjcDWCAEIAM2AlQgBCAEKAJkNgJQAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAEKAJUDhQGBwIMBAUKDwADCRELEA4IEgESDRILQQBCAEEAIAQoAlAQTiEAIAQoAlAgADYCFCAARQRAIARCfzcDaAwTCyAEKAJQKAIUQgA3AzggBCgCUCgCFEIANwNAIARCADcDaAwSCyAEKAJQKAIQIAQpA1ggBCgCUBD0AiEAIAQoAlAgADYCFCAARQRAIARCfzcDaAwSCyAEKAJQKAIUIAQpA1g3AzggBCgCUCgCFCAEKAJQKAIUKQMINwNAIARCADcDaAwRCyAEQgA3A2gMEAsgBCgCUCgCEBA0IAQoAlAgBCgCUCgCFDYCECAEKAJQQQA2AhQgBEIANwNoDA8LIAQgBCgCUCAEKAJgIAQpA1gQQjcDaAwOCyAEKAJQKAIQEDQgBCgCUCgCFBA0IAQoAlAQFiAEQgA3A2gMDQsgBCgCUCgCEEIANwM4IAQoAlAoAhBCADcDQCAEQgA3A2gMDAsgBCkDWEL///////////8AVgRAIAQoAlBBEkEAEBUgBEJ/NwNoDAwLIAQgBCgCUCgCECAEKAJgIAQpA1gQ8wI3A2gMCwsgBEEAQgBBACAEKAJQEE42AkwgBCgCTEUEQCAEQn83A2gMCwsgBCgCUCgCEBA0IAQoAlAgBCgCTDYCECAEQgA3A2gMCgsgBCgCUCgCFBA0IAQoAlBBADYCFCAEQgA3A2gMCQsgBCAEKAJQKAIQIAQoAmAgBCkDWCAEKAJQELwBrDcDaAwICyAEIAQoAlAoAhQgBCgCYCAEKQNYIAQoAlAQvAGsNwNoDAcLIAQpA1hCOFQEQCAEKAJQQRJBABAVIARCfzcDaAwHCyAEIAQoAmA2AkggBCgCSBA8IAQoAkggBCgCUCgCDDYCKCAEKAJIIAQoAlAoAhApAzA3AxggBCgCSCAEKAJIKQMYNwMgIAQoAkhBADsBMCAEKAJIQQA7ATIgBCgCSELcATcDACAEQjg3A2gMBgsgBCgCUCAEKAJgKAIANgIMIARCADcDaAwFCyAEQX82AkAgBEETNgI8IARBCzYCOCAEQQ02AjQgBEEMNgIwIARBCjYCLCAEQQ82AiggBEEJNgIkIARBETYCICAEQQg2AhwgBEEHNgIYIARBBjYCFCAEQQU2AhAgBEEENgIMIARBAzYCCCAEQQI2AgQgBEEBNgIAIARBACAEEDc3A2gMBAsgBCgCUCgCECkDOEL///////////8AVgRAIAQoAlBBHkE9EBUgBEJ/NwNoDAQLIAQgBCgCUCgCECkDODcDaAwDCyAEKAJQKAIUKQM4Qv///////////wBWBEAgBCgCUEEeQT0QFSAEQn83A2gMAwsgBCAEKAJQKAIUKQM4NwNoDAILIAQpA1hC////////////AFYEQCAEKAJQQRJBABAVIARCfzcDaAwCCyAEIAQoAlAoAhQgBCgCYCAEKQNYIAQoAlAQ8gI3A2gMAQsgBCgCUEEcQQAQFSAEQn83A2gLIAQpA2ghAiAEQfAAaiQAIAILeQEBfyMAQRBrIgEkACABIAA2AggCQCABKAIIKAIkQQFGBEAgASgCCEEMakESQQAQFSABQX82AgwMAQsgASgCCEEAQgBBCBAiQgBTBEAgAUF/NgIMDAELIAEoAghBATYCJCABQQA2AgwLIAEoAgwhACABQRBqJAAgAAuDAQEBfyMAQRBrIgIkACACIAA2AgggAiABNwMAAkAgAigCCCgCJEEBRgRAIAIoAghBDGpBEkEAEBUgAkF/NgIMDAELIAIoAghBACACKQMAQREQIkIAUwRAIAJBfzYCDAwBCyACKAIIQQE2AiQgAkEANgIMCyACKAIMIQAgAkEQaiQAIAALWwEBfyMAQSBrIgMkACADIAA2AhwgAyABOQMQIAMgAjkDCCADKAIcBEAgAygCHCADKwMQOQMgIAMoAhwgAysDCDkDKCADKAIcRAAAAAAAAAAAEFgLIANBIGokAAtYAQF/IwBBEGsiASQAIAEgADYCDCABKAIMBEAgASgCDEQAAAAAAAAAADkDGCABKAIMKAIARAAAAAAAAAAAIAEoAgwoAgwgASgCDCgCBBEaAAsgAUEQaiQAC0gBAX8jAEEQayIBJAAgASAANgIMIAEoAgwEQCABKAIMKAIIBEAgASgCDCgCDCABKAIMKAIIEQMACyABKAIMEBYLIAFBEGokAAsrAQF/IwBBEGsiASQAIAEgADYCDCABKAIMRAAAAAAAAPA/EFggAUEQaiQAC5wCAgF/AXwjAEEgayIBIAA3AxAgASABKQMQukQAAAAAAADoP6M5AwgCQCABKwMIRAAA4P///+9BZARAIAFBfzYCBAwBCyABAn8gASsDCCICRAAAAAAAAPBBYyACRAAAAAAAAAAAZnEEQCACqwwBC0EACzYCBAsCQCABKAIEQYCAgIB4SwRAIAFBgICAgHg2AhwMAQsgASABKAIEQX9qNgIEIAEgASgCBCABKAIEQQF2cjYCBCABIAEoAgQgASgCBEECdnI2AgQgASABKAIEIAEoAgRBBHZyNgIEIAEgASgCBCABKAIEQQh2cjYCBCABIAEoAgQgASgCBEEQdnI2AgQgASABKAIEQQFqNgIEIAEgASgCBDYCHAsgASgCHAuTAQEBfyMAQSBrIgMkACADIAA2AhggAyABNwMQIAMgAjYCDAJAIAMpAxBQBEAgA0EBOgAfDAELIAMgAykDEBD8AjYCCCADKAIIIAMoAhgoAgBNBEAgA0EBOgAfDAELIAMoAhggAygCCCADKAIMEFpBAXFFBEAgA0EAOgAfDAELIANBAToAHwsgAy0AHxogA0EgaiQAC7MCAgF/AX4jAEEwayIEJAAgBCAANgIkIAQgATYCICAEIAI2AhwgBCADNgIYAkACQCAEKAIkBEAgBCgCIA0BCyAEKAIYQRJBABAVIARCfzcDKAwBCyAEKAIkKQMIQgBWBEAgBCAEKAIgEHw2AhQgBCAEKAIUIAQoAiQoAgBwNgIQIAQgBCgCJCgCECAEKAIQQQJ0aigCADYCDANAAkAgBCgCDEUNACAEKAIgIAQoAgwoAgAQWwRAIAQgBCgCDCgCGDYCDAwCBSAEKAIcQQhxBEAgBCgCDCkDCEJ/UgRAIAQgBCgCDCkDCDcDKAwGCwwCCyAEKAIMKQMQQn9SBEAgBCAEKAIMKQMQNwMoDAULCwsLCyAEKAIYQQlBABAVIARCfzcDKAsgBCkDKCEFIARBMGokACAFC0YBAX8jAEEQayIBJAAgASAANgIMA0AgASgCDARAIAEgASgCDCgCGDYCCCABKAIMEBYgASABKAIINgIMDAELCyABQRBqJAALlwEBAX8jAEEQayIBJAAgASAANgIMIAEoAgwEQCABKAIMKAIQBEAgAUEANgIIA0AgASgCCCABKAIMKAIASQRAIAEoAgwoAhAgASgCCEECdGooAgAEQCABKAIMKAIQIAEoAghBAnRqKAIAEP8CCyABIAEoAghBAWo2AggMAQsLIAEoAgwoAhAQFgsgASgCDBAWCyABQRBqJAALdAEBfyMAQRBrIgEkACABIAA2AgggAUEYEBkiADYCBAJAIABFBEAgASgCCEEOQQAQFSABQQA2AgwMAQsgASgCBEEANgIAIAEoAgRCADcDCCABKAIEQQA2AhAgASABKAIENgIMCyABKAIMIQAgAUEQaiQAIAALnwEBAX8jAEEQayICIAA2AgwgAiABNgIIIAJBADYCBANAIAIoAgQgAigCDCgCREkEQCACKAIMKAJMIAIoAgRBAnRqKAIAIAIoAghGBEAgAigCDCgCTCACKAIEQQJ0aiACKAIMKAJMIAIoAgwoAkRBAWtBAnRqKAIANgIAIAIoAgwiACAAKAJEQX9qNgJEBSACIAIoAgRBAWo2AgQMAgsLCwtUAQF/IwBBEGsiASQAIAEgADYCDCABKAIMQQE6ACgCfyMAQRBrIgAgASgCDEEMajYCDCAAKAIMKAIARQsEQCABKAIMQQxqQQhBABAVCyABQRBqJAAL4QEBA38jAEEgayICJAAgAiAANgIYIAIgATYCFAJAIAIoAhgoAkRBAWogAigCGCgCSE8EQCACIAIoAhgoAkhBCmo2AgwgAiACKAIYKAJMIAIoAgxBAnQQTTYCECACKAIQRQRAIAIoAhhBCGpBDkEAEBUgAkF/NgIcDAILIAIoAhggAigCDDYCSCACKAIYIAIoAhA2AkwLIAIoAhQhASACKAIYKAJMIQMgAigCGCIEKAJEIQAgBCAAQQFqNgJEIABBAnQgA2ogATYCACACQQA2AhwLIAIoAhwhACACQSBqJAAgAAtAAQF/IwBBEGsiAiQAIAIgADYCDCACIAE2AgggAigCDCACKAIINgIsIAIoAgggAigCDBCEAyEAIAJBEGokACAAC7cJAQF/IwBB4MAAayIFJAAgBSAANgLUQCAFIAE2AtBAIAUgAjYCzEAgBSADNwPAQCAFIAQ2ArxAIAUgBSgC0EA2ArhAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAUoArxADhEDBAAGAQIFCQoKCgoKCggKBwoLIAVCADcD2EAMCgsgBSAFKAK4QEHkAGogBSgCzEAgBSkDwEAQQjcD2EAMCQsgBSgCuEAQFiAFQgA3A9hADAgLIAUoArhAKAIQBEAgBSAFKAK4QCgCECAFKAK4QCkDGCAFKAK4QEHkAGoQfyIDNwOYQCADUARAIAVCfzcD2EAMCQsgBSgCuEApAwggBSkDmEB8IAUoArhAKQMIVARAIAUoArhAQeQAakEVQQAQFSAFQn83A9hADAkLIAUoArhAIgAgBSkDmEAgACkDAHw3AwAgBSgCuEAiACAFKQOYQCAAKQMIfDcDCCAFKAK4QEEANgIQCyAFKAK4QC0AeEEBcUUEQCAFQgA3A6hAA0AgBSkDqEAgBSgCuEApAwBUBEAgBQJ+QoDAACAFKAK4QCkDACAFKQOoQH1CgMAAVg0AGiAFKAK4QCkDACAFKQOoQH0LNwOgQCAFIAUoAtRAIAVBEGogBSkDoEAQLyIDNwOwQCADQgBTBEAgBSgCuEBB5ABqIAUoAtRAEBggBUJ/NwPYQAwLCyAFKQOwQFAEQCAFKAK4QEHkAGpBEUEAEBUgBUJ/NwPYQAwLBSAFIAUpA7BAIAUpA6hAfDcDqEAMAgsACwsLIAUoArhAIAUoArhAKQMANwMgIAVCADcD2EAMBwsgBSkDwEAgBSgCuEApAwggBSgCuEApAyB9VgRAIAUgBSgCuEApAwggBSgCuEApAyB9NwPAQAsgBSkDwEBQBEAgBUIANwPYQAwHCyAFKAK4QC0AeEEBcQRAIAUoAtRAIAUoArhAKQMgQQAQKEEASARAIAUoArhAQeQAaiAFKALUQBAYIAVCfzcD2EAMCAsLIAUgBSgC1EAgBSgCzEAgBSkDwEAQLyIDNwOwQCADQgBTBEAgBSgCuEBB5ABqQRFBABAVIAVCfzcD2EAMBwsgBSgCuEAiACAFKQOwQCAAKQMgfDcDICAFKQOwQFAEQCAFKAK4QCkDICAFKAK4QCkDCFQEQCAFKAK4QEHkAGpBEUEAEBUgBUJ/NwPYQAwICwsgBSAFKQOwQDcD2EAMBgsgBSAFKAK4QCkDICAFKAK4QCkDAH0gBSgCuEApAwggBSgCuEApAwB9IAUoAsxAIAUpA8BAIAUoArhAQeQAahCNATcDCCAFKQMIQgBTBEAgBUJ/NwPYQAwGCyAFKAK4QCAFKQMIIAUoArhAKQMAfDcDICAFQgA3A9hADAULIAUgBSgCzEA2AgQgBSgCBCAFKAK4QEEoaiAFKAK4QEHkAGoQkQFBAEgEQCAFQn83A9hADAULIAVCADcD2EAMBAsgBSAFKAK4QCwAYKw3A9hADAMLIAUgBSgCuEApA3A3A9hADAILIAUgBSgCuEApAyAgBSgCuEApAwB9NwPYQAwBCyAFKAK4QEHkAGpBHEEAEBUgBUJ/NwPYQAsgBSkD2EAhAyAFQeDAAGokACADC1UBAX8jAEEgayIEJAAgBCAANgIcIAQgATYCGCAEIAI3AxAgBCADNwMIIAQoAhggBCkDECAEKQMIQQBBAEEAQgAgBCgCHEEIahB+IQAgBEEgaiQAIAALtAMBAX8jAEEwayIDJAAgAyAANgIkIAMgATcDGCADIAI2AhQgAyADKAIkIAMpAxggAygCFBB/IgE3AwgCQCABUARAIANCADcDKAwBCyADIAMoAiQoAkAgAykDGKdBBHRqKAIANgIEAkAgAykDCCADKAIEKQMgfCADKQMIWgRAIAMpAwggAygCBCkDIHxC////////////AFgNAQsgAygCFEEEQRYQFSADQgA3AygMAQsgAyADKAIEKQMgIAMpAwh8NwMIIAMoAgQvAQxBCHEEQCADKAIkKAIAIAMpAwhBABAoQQBIBEAgAygCFCADKAIkKAIAEBggA0IANwMoDAILIAMoAiQoAgAgA0IEEC9CBFIEQCADKAIUIAMoAiQoAgAQGCADQgA3AygMAgsgAygAAEHQlp3AAEYEQCADIAMpAwhCBHw3AwgLIAMgAykDCEIMfDcDCCADKAIEQQAQgAFBAXEEQCADIAMpAwhCCHw3AwgLIAMpAwhC////////////AFYEQCADKAIUQQRBFhAVIANCADcDKAwCCwsgAyADKQMINwMoCyADKQMoIQEgA0EwaiQAIAELBgBBtJwBC/8BAQF/IwBBEGsiAiQAIAIgADYCDCACIAE6AAsCQCACKAIMKAIQQQ5GBEAgAigCDEE/OwEKDAELIAIoAgwoAhBBDEYEQCACKAIMQS47AQoMAQsCQCACLQALQQFxRQRAIAIoAgxBABCAAUEBcUUNAQsgAigCDEEtOwEKDAELAkAgAigCDCgCEEEIRwRAIAIoAgwvAVJBAUcNAQsgAigCDEEUOwEKDAELIAIgAigCDCgCMBBSIgA7AQggAEH//wNxQQBKBEAgAigCDCgCMCgCACACLwEIQQFrai0AAEEvRgRAIAIoAgxBFDsBCgwCCwsgAigCDEEKOwEKCyACQRBqJAALwAIBAX8jAEEwayICJAAgAiAANgIoIAJBgAI7ASYgAiABNgIgIAIgAi8BJkGAAnFBAEc6ABsgAkEeQS4gAi0AG0EBcRs2AhwCQCACKAIoQRpBHCACLQAbQQFxG6xBARAoQQBIBEAgAigCICACKAIoEBggAkF/NgIsDAELIAIgAigCKEEEQQYgAi0AG0EBcRusIAJBDmogAigCIBBBIgA2AgggAEUEQCACQX82AiwMAQsgAkEANgIUA0AgAigCFEECQQMgAi0AG0EBcRtIBEAgAiACKAIIEB5B//8DcSACKAIcajYCHCACIAIoAhRBAWo2AhQMAQsLIAIoAggQSEEBcUUEQCACKAIgQRRBABAVIAIoAggQFyACQX82AiwMAQsgAigCCBAXIAIgAigCHDYCLAsgAigCLCEAIAJBMGokACAAC/8DAQF/IwBBIGsiAiQAIAIgADYCGCACIAE2AhQCQCACKAIYKAIQQeMARwRAIAJBAToAHwwBCyACIAIoAhgoAjQgAkESakGBsgJBgAZBABBfNgIIAkAgAigCCARAIAIvARJBB04NAQsgAigCFEEVQQAQFSACQQA6AB8MAQsgAiACKAIIIAIvARKtECoiADYCDCAARQRAIAIoAhRBFEEAEBUgAkEAOgAfDAELIAJBAToABwJAAkACQCACKAIMEB5Bf2oOAgIAAQsgAigCGCkDKEIUVARAIAJBADoABwsMAQsgAigCFEEYQQAQFSACKAIMEBcgAkEAOgAfDAELIAIoAgxCAhAfLwAAQcGKAUcEQCACKAIUQRhBABAVIAIoAgwQFyACQQA6AB8MAQsCQAJAAkACQAJAIAIoAgwQiwFBf2oOAwABAgMLIAJBgQI7AQQMAwsgAkGCAjsBBAwCCyACQYMCOwEEDAELIAIoAhRBGEEAEBUgAigCDBAXIAJBADoAHwwBCyACLwESQQdHBEAgAigCFEEVQQAQFSACKAIMEBcgAkEAOgAfDAELIAIoAhggAi0AB0EBcToABiACKAIYIAIvAQQ7AVIgAigCDBAeQf//A3EhACACKAIYIAA2AhAgAigCDBAXIAJBAToAHwsgAi0AH0EBcSEAIAJBIGokACAAC7kBAQF/IwBBMGsiAiQAIAIgADsBLiACIAE7ASwgAkIANwIAIAJBADYCKCACQgA3AiAgAkIANwIYIAJCADcCECACQgA3AgggAkEANgIgIAIgAi8BLEEJdUHQAGo2AhQgAiACLwEsQQV1QQ9xQQFrNgIQIAIgAi8BLEEfcTYCDCACIAIvAS5BC3U2AgggAiACLwEuQQV1QT9xNgIEIAIgAi8BLkEBdEE+cTYCACACEAwhACACQTBqJAAgAAtMAQJ/IwBBEGsiACQAIABB2AAQGSIBNgIIAkAgAUUEQCAAQQA2AgwMAQsgACgCCBBdIAAgACgCCDYCDAsgACgCDCEBIABBEGokACABCwcAIAAvATAL4AgBAX8jAEHAAWsiAyQAIAMgADYCtAEgAyABNgKwASADIAI3A6gBIAMgAygCtAEoAgAQNSICNwMgAkAgAkIAUwRAIAMoArQBQQhqIAMoArQBKAIAEBggA0J/NwO4AQwBCyADIAMpAyA3A6ABIANBADoAFyADQgA3AxgDQCADKQMYIAMpA6gBVARAIAMgAygCtAEoAkAgAygCsAEgAykDGKdBA3RqKQMAp0EEdGo2AgwgAyADKAK0AQJ/IAMoAgwoAgQEQCADKAIMKAIEDAELIAMoAgwoAgALQYAEEF4iADYCECAAQQBIBEAgA0J/NwO4AQwDCyADKAIQBEAgA0EBOgAXCyADIAMpAxhCAXw3AxgMAQsLIAMgAygCtAEoAgAQNSICNwMgIAJCAFMEQCADKAK0AUEIaiADKAK0ASgCABAYIANCfzcDuAEMAQsgAyADKQMgIAMpA6ABfTcDmAECQCADKQOgAUL/////D1gEQCADKQOoAUL//wNYDQELIANBAToAFwsgAyADQTBqQuIAECoiADYCLCAARQRAIAMoArQBQQhqQQ5BABAVIANCfzcDuAEMAQsgAy0AF0EBcQRAIAMoAixBttMAQQQQQCADKAIsQiwQLiADKAIsQS0QICADKAIsQS0QICADKAIsQQAQISADKAIsQQAQISADKAIsIAMpA6gBEC4gAygCLCADKQOoARAuIAMoAiwgAykDmAEQLiADKAIsIAMpA6ABEC4gAygCLEG70wBBBBBAIAMoAixBABAhIAMoAiwgAykDoAEgAykDmAF8EC4gAygCLEEBECELIAMoAixBwNMAQQQQQCADKAIsQQAQISADKAIsAn5C//8DIAMpA6gBQv//A1oNABogAykDqAELp0H//wNxECAgAygCLAJ+Qv//AyADKQOoAUL//wNaDQAaIAMpA6gBC6dB//8DcRAgIAMoAiwCf0F/IAMpA5gBQv////8PWg0AGiADKQOYAacLECEgAygCLAJ/QX8gAykDoAFC/////w9aDQAaIAMpA6ABpwsQISADAn8gAygCtAEtAChBAXEEQCADKAK0ASgCJAwBCyADKAK0ASgCIAs2ApQBIAMoAiwCfyADKAKUAQRAIAMoApQBLwEEDAELQQALQf//A3EQIAJ/IwBBEGsiACADKAIsNgIMIAAoAgwtAABBAXFFCwRAIAMoArQBQQhqQRRBABAVIAMoAiwQFyADQn83A7gBDAELIAMoArQBAn8jAEEQayIAIAMoAiw2AgwgACgCDCgCBAsCfiMAQRBrIgAgAygCLDYCDAJ+IAAoAgwtAABBAXEEQCAAKAIMKQMQDAELQgALCxA2QQBIBEAgAygCLBAXIANCfzcDuAEMAQsgAygCLBAXIAMoApQBBEAgAygCtAEgAygClAEoAgAgAygClAEvAQStEDZBAEgEQCADQn83A7gBDAILCyADIAMpA5gBNwO4AQsgAykDuAEhAiADQcABaiQAIAILBwAgACgCIAsIAEEBQTgQewsDAAELC/KNAScAQYAIC5QFTm8gZXJyb3IATXVsdGktZGlzayB6aXAgYXJjaGl2ZXMgbm90IHN1cHBvcnRlZABSZW5hbWluZyB0ZW1wb3JhcnkgZmlsZSBmYWlsZWQAQ2xvc2luZyB6aXAgYXJjaGl2ZSBmYWlsZWQAU2VlayBlcnJvcgBSZWFkIGVycm9yAFdyaXRlIGVycm9yAENSQyBlcnJvcgBDb250YWluaW5nIHppcCBhcmNoaXZlIHdhcyBjbG9zZWQATm8gc3VjaCBmaWxlAEZpbGUgYWxyZWFkeSBleGlzdHMAQ2FuJ3Qgb3BlbiBmaWxlAEZhaWx1cmUgdG8gY3JlYXRlIHRlbXBvcmFyeSBmaWxlAFpsaWIgZXJyb3IATWFsbG9jIGZhaWx1cmUARW50cnkgaGFzIGJlZW4gY2hhbmdlZABDb21wcmVzc2lvbiBtZXRob2Qgbm90IHN1cHBvcnRlZABQcmVtYXR1cmUgZW5kIG9mIGZpbGUASW52YWxpZCBhcmd1bWVudABOb3QgYSB6aXAgYXJjaGl2ZQBJbnRlcm5hbCBlcnJvcgBaaXAgYXJjaGl2ZSBpbmNvbnNpc3RlbnQAQ2FuJ3QgcmVtb3ZlIGZpbGUARW50cnkgaGFzIGJlZW4gZGVsZXRlZABFbmNyeXB0aW9uIG1ldGhvZCBub3Qgc3VwcG9ydGVkAFJlYWQtb25seSBhcmNoaXZlAE5vIHBhc3N3b3JkIHByb3ZpZGVkAFdyb25nIHBhc3N3b3JkIHByb3ZpZGVkAE9wZXJhdGlvbiBub3Qgc3VwcG9ydGVkAFJlc291cmNlIHN0aWxsIGluIHVzZQBUZWxsIGVycm9yAENvbXByZXNzZWQgZGF0YSBpbnZhbGlkAEGhDQuAAQQAAAkEAAAvBAAATgQAAGkEAAB0BAAAfwQAAIsEAACVBAAAtwQAAMQEAADYBAAA6AQAAAkFAAAUBQAAIwUAADoFAABbBQAAcQUAAIIFAACUBQAAowUAALwFAADOBQAA5QUAAAUGAAAXBgAALAYAAEQGAABcBgAAcgYAAH0GAAAgAEG4DgsRAQAAAAEAAAABAAAAAQAAAAEAQdwOCwkBAAAAAQAAAAIAQYgPCwEBAEGoDwsBAQBBtA8LkkWWMAd3LGEO7rpRCZkZxG0Hj/RqcDWlY+mjlWSeMojbDqS43Hke6dXgiNnSlytMtgm9fLF+By2455Edv5BkELcd8iCwakhxufPeQb6EfdTaGuvk3W1RtdT0x4XTg1aYbBPAqGtkevli/ezJZYpPXAEU2WwGY2M9D/r1DQiNyCBuO14QaUzkQWDVcnFnotHkAzxH1ARL/YUN0mu1CqX6qLU1bJiyQtbJu9tA+bys42zYMnVc30XPDdbcWT3Rq6ww2SY6AN5RgFHXyBZh0L+19LQhI8SzVpmVus8Ppb24nrgCKAiIBV+y2QzGJOkLsYd8by8RTGhYqx1hwT0tZraQQdx2BnHbAbwg0pgqENXviYWxcR+1tgal5L+fM9S46KLJB3g0+QAPjqgJlhiYDuG7DWp/LT1tCJdsZJEBXGPm9FFra2JhbBzYMGWFTgBi8u2VBmx7pQEbwfQIglfED/XG2bBlUOm3Euq4vot8iLn83x3dYkkt2hXzfNOMZUzU+1hhsk3OUbU6dAC8o+Iwu9RBpd9K15XYPW3E0aT79NbTaulpQ/zZbjRGiGet0Lhg2nMtBETlHQMzX0wKqsl8Dd08cQVQqkECJxAQC76GIAzJJbVoV7OFbyAJ1Ga5n+Rhzg753l6YydkpIpjQsLSo18cXPbNZgQ20LjtcvbetbLrAIIO47bazv5oM4rYDmtKxdDlH1eqvd9KdFSbbBIMW3HMSC2PjhDtklD5qbQ2oWmp6C88O5J3/CZMnrgAKsZ4HfUSTD/DSowiHaPIBHv7CBmldV2L3y2dlgHE2bBnnBmtudhvU/uAr04laetoQzErdZ2/fufn5776OQ763F9WOsGDoo9bWfpPRocTC2DhS8t9P8We70WdXvKbdBrU/SzaySNorDdhMGwqv9koDNmB6BEHD72DfVd9nqO+ObjF5vmlGjLNhyxqDZryg0m8lNuJoUpV3DMwDRwu7uRYCIi8mBVW+O7rFKAu9spJatCsEarNcp//XwjHP0LWLntksHa7eW7DCZJsm8mPsnKNqdQqTbQKpBgmcPzYO64VnB3ITVwAFgkq/lRR6uOKuK7F7OBu2DJuO0pINvtXlt+/cfCHf2wvU0tOGQuLU8fiz3Whug9ofzRa+gVsmufbhd7Bvd0e3GOZaCIhwag//yjsGZlwLARH/nmWPaa5i+NP/a2FFz2wWeOIKoO7SDddUgwROwrMDOWEmZ6f3FmDQTUdpSdt3bj5KatGu3FrW2WYL30DwO9g3U668qcWeu95/z7JH6f+1MBzyvb2KwrrKMJOzU6ajtCQFNtC6kwbXzSlX3lS/Z9kjLnpms7hKYcQCG2hdlCtvKje+C7ShjgzDG98FWo3vAi0AAAAAQTEbGYJiNjLDUy0rBMVsZEX0d32Gp1pWx5ZBTwiK2chJu8LRiujv+svZ9OMMT7WsTX6utY4tg57PHJiHURLCShAj2VPTcPR4kkHvYVXXri4U5rU317WYHJaEgwVZmBuCGKkAm9v6LbCayzapXV135hxsbP/fP0HUng5azaIkhJXjFZ+MIEayp2F3qb6m4ejx59Dz6CSD3sNlssXaqq5dXeufRkQozGtvaf1wdq5rMTnvWiogLAkHC204HBLzNkbfsgddxnFUcO0wZWv09/Mqu7bCMaJ1kRyJNKAHkPu8nxe6jYQOed6pJTjvsjz/efNzvkjoan0bxUE8Kt5YBU958ER+YumHLU/CxhxU2wGKFZRAuw6Ng+gjpsLZOL8NxaA4TPS7IY+nlgrOlo0TCQDMXEgx10WLYvpuylPhd1Rdu7oVbKCj1j+NiJcOlpFQmNfeEanMx9L64eyTy/r1XNdich3meWvetVRAn4RPWVgSDhYZIxUP2nA4JJtBIz2na/1l5lrmfCUJy1dkONBOo66RAeKfihghzKczYP28Kq/hJK3u0D+0LYMSn2yyCYarJEjJ6hVT0ClGfvtod2Xi9nk/L7dIJDZ0GwkdNSoSBPK8U0uzjUhScN5leTHvfmD+8+bnv8L9/nyR0NU9oMvM+jaKg7sHkZp4VLyxOWWnqEuYgzsKqZgiyfq1CYjLrhBPXe9fDmz0Rs0/2W2MDsJ0QxJa8wIjQerBcGzBgEF32EfXNpcG5i2OxbUApYSEG7waikFxW7taaJjod0PZ2WxaHk8tFV9+NgycLRsn3RwAPhIAmLlTMYOgkGKui9FTtZIWxfTdV/TvxJSnwu/Vltn26bwHrqiNHLdr3jGcKu8qhe15a8qsSHDTbxtd+C4qRuHhNt5moAfFf2NU6FQiZfNN5fOyAqTCqRtnkYQwJqCfKbiuxeT5n979Oszz1nv96M+8a6mA/VqymT4Jn7J/OISrsCQcLPEVBzUyRioec3cxB7ThcEj10GtRNoNGeneyXWNO1/rLD+bh0sy1zPmNhNfgShKWrwsjjbbIcKCdiUG7hEZdIwMHbDgaxD8VMYUODihCmE9nA6lUfsD6eVWBy2JMH8U4gV70I5idpw6z3JYVqhsAVOVaMU/8mWJi19hTec4XT+FJVn76UJUt13vUHMxiE4qNLVK7ljSR6Lsf0NmgBuzzfl6twmVHbpFIbC+gU3XoNhI6qQcJI2pUJAgrZT8R5HmnlqVIvI9mG5GkJyqKveC8y/KhjdDrYt79wCPv5tm94bwU/NCnDT+DiiZ+spE/uSTQcPgVy2k7RuZCenf9W7VrZdz0Wn7FNwlT7nY4SPexrgm48J8SoTPMP4py/SSTAAAAADdqwgFu1IQDWb5GAtyoCQfrwssGsnyNBIUWTwW4URMOjzvRD9aFlw3h71UMZPkaCVOT2AgKLZ4KPUdcC3CjJhxHyeQdHneiHykdYB6sCy8bm2HtGsLfqxj1tWkZyPI1Ev+Y9xOmJrERkUxzEBRaPBUjMP4Ueo64Fk3kehfgRk041yyPOY6SyTu5+As6PO5EPwuEhj5SOsA8ZVACPVgXXjZvfZw3NsPaNQGpGDSEv1cxs9WVMOpr0zLdAREzkOVrJKePqSX+Me8nyVstJkxNYiN7J6AiIpnmIBXzJCEotHgqH966K0Zg/ClxCj4o9BxxLcN2syyayPUuraI3L8CNmnD351hxrlkec5kz3HIcJZN3K09RdnLxF3RFm9V1eNyJfk+2S38WCA19IWLPfKR0gHmTHkJ4yqAEev3KxnuwLrxsh0R+bd76OG/pkPpubIa1a1vsd2oCUjFoNTjzaQh/r2I/FW1jZqsrYVHB6WDU16Zl471kZLoDImaNaeBnIMvXSBehFUlOH1NLeXWRSvxj3k/LCRxOkrdaTKXdmE2YmsRGr/AGR/ZOQEXBJIJERDLNQXNYD0Aq5klCHYyLQ1Bo8VRnAjNVPrx1VwnWt1aMwPhTu6o6UuIUfFDVfr5R6DniWt9TIFuG7WZZsYekWDSR610D+ylcWkVvXm0vrV+AGzXht3H34O7PseLZpXPjXLM85mvZ/ucyZ7jlBQ165DhKJu8PIOTuVp6i7GH0YO3k4i/o04jt6Yo2q+u9XGnq8LgT/cfS0fyebJf+qQZV/ywQGvobetj7QsSe+XWuXPhI6QDzf4PC8iY9hPARV0bxlEEJ9KMry/X6lY33zf9P9mBdeNlXN7rYDon82jnjPtu89XHei5+z39Ih9d3lSzfc2Axr1+9mqda22O/UgbIt1QSkYtAzzqDRanDm010aJNIQ/l7FJ5ScxH4q2sZJQBjHzFZXwvs8lcOigtPBlegRwKivTcufxY/KxnvJyPERC8l0B0TMQ22GzRrTwM8tuQLOQJavkXf8bZAuQiuSGSjpk5w+pparVGSX8uoilcWA4JT4x7yfz61+npYTOJyhefqdJG+1mBMFd5lKuzGbfdHzmjA1iY0HX0uMXuENjmmLz4/snYCK2/dCi4JJBIm1I8aIiGSag78OWILmsB6A0drcgVTMk4RjplGFOhgXhw1y1Yag0OKpl7ogqM4EZqr5bqSrfHjrrksSKa8SrG+tJcatrBiB8acv6zOmdlV1pEE/t6XEKfig80M6oar9fKOdl76i0HPEtecZBrS+p0C2ic2CtwzbzbI7sQ+zYg9JsVVli7BoIte7X0gVugb2U7gxnJG5tIrevIPgHL3aXlq/7TSYvgAAAABlZ7y4i8gJqu6vtRJXl2KPMvDeN9xfayW5ONed7yi0xYpPCH1k4L1vAYcB17i/1krd2GryM3ff4FYQY1ifVxlQ+jCl6BSfEPpx+KxCyMB7362nx2dDCHJ1Jm/OzXB/rZUVGBEt+7ekP57QGIcn6M8aQo9zoqwgxrDJR3oIPq8yoFvIjhi1ZzsK0ACHsmk4UC8MX+yX4vBZhYeX5T3Rh4ZltOA63VpPj88/KDN3hhDk6uN3WFIN2O1AaL9R+KH4K/DEn5dIKjAiWk9XnuL2b0l/kwj1x32nQNUYwPxtTtCfNSu3I43FGJafoH8qJxlH/bp8IEECko/0EPfoSKg9WBSbWD+oI7aQHTHT96GJas92FA+oyqzhB3++hGDDBtJwoF63FxzmWbip9DzfFUyF58LR4IB+aQ4vy3trSHfDog8Ny8dosXMpxwRhTKC42fWYb0SQ/9P8flBm7hs32lZNJ7kOKEAFtsbvsKSjiAwcGrDbgX/XZzmReNIr9B9ukwP3JjtmkJqDiD8vke1YkylUYES0MQf4DN+oTR66z/Gm7N+S/om4LkZnF5tUAnAn7LtI8HHeL0zJMID521XnRWOcoD9r+ceD0xdoNsFyD4p5yzdd5K5Q4VxA/1ROJZjo9nOIi64W7zcW+ECCBJ0nPrwkH+khQXhVma/X4IvKsFwzO7ZZ7V7R5VWwflBH1Rns/2whO2IJRofa5+kyyIKOjnDUnu0osflRkF9W5II6MVg6gwmPp+ZuMx8IwYYNbaY6taThQL3BhvwFLylJF0pO9a/zdiIylhGeini+K5gd2ZcgS8n0eC6uSMDAAf3SpWZBahxelvd5OSpPl5afXfLxI+UFGWtNYH7X9Y7RYufrtt5fUo4JwjfptXrZRgBovCG80Oox34iPVmMwYfnWIgSeapq9pr0H2MEBvzZutK1TCQgVmk5yHf8pzqURhnu3dOHHD83ZEJKovqwqRhEZOCN2pYB1ZsbYEAF6YP6uz3KbyXPKIvGkV0eWGO+pOa39zF4RRQbuTXZjifHOjSZE3OhB+GRReS/5NB6TQdqxJlO/1prr6cb5s4yhRQtiDvAZB2lMob5RmzzbNieENZmSllD+Li6ZuVQm/N7onhJxXYx3FuE0zi42qatJihFF5j8DIIGDu3aR4OMT9lxb/VnpSZg+VfEhBoJsRGE+1KrOi8bPqTd+OEF/1l0mw26ziXZ81u7KxG/WHVkKsaHh5B4U84F5qEvXacsTsg53q1yhwrk5xn4BgP6pnOWZFSQLNqA2blEcjqcWZobCcdo+LN5vLEm505TwgQQJlea4sXtJDaMeLrEbSD7SQy1ZbvvD9tvpppFnUR+psMx6zgx0lGG5ZvEGBd4AAAAAdwcwlu4OYSyZCVG6B23EGXBq9I/pY6U1nmSVow7biDJ53Lik4NXpHpfS2YgJtkwrfrF8vee4LQeQvx2RHbcQZGqwIPLzuXFIhL5B3hra1H1t3eTr9NS1UYPThccTbJhWZGuowP1i+XqKZcnsFAFcT2MGbNn6Dz1jjQgN9TtuIMhMaRBe1WBB5KJncXI8A+TRSwTUR9INhf2lCrVrNbWo+kKymGzbu8nWrLz5QDLYbONF31x13NYNz6vRPVkm2TCsUd4AOsjXUYC/0GEWIbT0tVazxCPPupWZuL2lDygCuJ5fBYgIxgzZsrEL6SQvb3yHWGhMEcFhHau2Zi09dtxBkAHbcQaY0iC879UQKnGxhYkGtrUfn7/kpei41DN4B8miDwD5NJYJqI7hDpgYf2oNuwhtPS2RZGyX5mNcAWtrUfQcbGFihWUw2PJiAE5sBpXtGwGle4II9MH1D8RXZbDZxhK36VCLvrjq/LmIfGLdHd8V2i1JjNN88/vUTGVNsmFYOrVRzqO8AHTUuzDiSt+lQT3Yldek0cRt09b0+0Np6Wo0btn8rWeIRtpguNBEBC1zMwMd5aoKTF/dDXzJUAVxPCcCQaq+CxAQyQwghldotSUgb4WzuWbUCc5h5J9e3vkOKdnJmLDQmCLH16i0WbM9Fy60DYG3vVw7wLpsre24gyCav7O2A7biDHSx0prq1Uc5ndJ3rwTbJhVz3BaD42MLEpRkO4QNbWo+empaqOQOzwuTCf+dCgCuJ30HnrHwD5NEhwij0h4B8mhpBsL+92JXXYBlZ8sZbDZxbmsG5/7UG3aJ0yvgENp6WmfdSsz5ud9vjr7v+Re3vkNgsI7V1taj6KHRk3442MLET9/yUtG7Z/GmvFdnP7UG3UiyNkvYDSvarwobTDYDSvZBBHpg32Dvw6hn31Uxbo7vRmm+ecths4y8ZoMaJW/SoFJo4jbMDHeVuwtHAyICFrlVBSYvxbo7vrK9CygrtFqSXLNqBMLX/6e10M8xLNmei1verh2bZMKw7GPyJnVqo5wCbZMKnAkGqesONj9yB2eFBQBXE5W/SoLiuHoUe7Errgy2GziS0o6b5dW+DXzc77cL298hhtPS1PHU4kJo3bP4H9qDboG+Fs32uSZbb7B34Ri3R3eICFrm/w9qcGYGO8oRAQtcj2We//hirmlha//TFmzPRaAK4njXDdLuTgSDVDkDs8KnZyZh0GAW90lpR00+bnfbrtFqStnWWtxA3wtmN9g78Km8rlPeu57FR7LPfzC1/+m9vfIcyrrCilOzkzAktKOmutA2Bc3XBpNU3lcpI9lnv7Nmei7EYUq4XWgbAipvK5S0C743wwyOoVoF3xstAu+NAAAAABkbMUEyNmKCKy1Tw2RsxQR9d/RFVlqnhk9BlsfI2YoI0cK7Sfrv6Irj9NnLrLVPDLWufk2egy2Oh5gcz0rCElFT2SMQePRw02HvQZIurtdVN7XmFByYtdcFg4SWghuYWZsAqRiwLfrbqTbLmuZ3XV3/bGwc1EE/381aDp6VhCSijJ8V46eyRiC+qXdh8ejhpujz0OfD3oMk2sWyZV1drqpERp/rb2vMKHZw/Wk5MWuuICpa7wsHCSwSHDht30Y288ZdB7LtcFRx9GtlMLsq8/eiMcK2iRyRdZAHoDQXn7z7DoSNuiWp3nk8su84c/N5/2roSL5BxRt9WN4qPPB5TwXpYn5Ewk8th9tUHMaUFYoBjQ67QKYj6IO/ONnCOKDFDSG79EwKlqePE42WzlzMAAlF1zFIbvpii3fhU8q6u11Uo6BsFYiNP9aRlg6X3teYUMfMqRHs4frS9frLk3Ji11xreeYdQFS13llPhJ8WDhJYDxUjGSQ4cNo9I0GbZf1rp3zmWuZXywklTtA4ZAGRrqMYip/iM6fMISq8/WCtJOGvtD/Q7p8Sgy2GCbJsyUgkq9BTFer7fkYp4mV3aC8/efY2JEi3HQkbdAQSKjVLU7zyUkiNs3ll3nBgfu8x5+bz/v79wr/V0JF8zMugPYOKNvqakQe7sbxUeKinZTk7g5hLIpipCgm1+skQrsuIX+9dT0b0bA5t2T/NdMIOjPNaEkPqQSMCwWxwwdh3QYCXNtdHji3mBqUAtcW8G4SEcUGKGmhau1tDd+iYWmzZ2RUtTx4MNn5fJxstnD4AHN25mAASoIMxU4uuYpCStVPR3fTFFsTv9FfvwqeU9tmW1a4HvOm3HI2onDHea4Uq7yrKa3nt03BIrPhdG2/hRiouZt424X/FB6BU6FRjTfNlIgKy8+UbqcKkMISRZymfoCbkxa64/d6f+dbzzDrP6P17gKlrvJmyWv2ynwk+q4Q4fywcJLA1BxXxHipGMgcxd3NIcOG0UWvQ9XpGgzZjXbJ3y/rXTtLh5g/5zLXM4NeEja+WEkq2jSMLnaBwyIS7QYkDI11GGjhsBzEVP8QoDg6FZ0+YQn5UqQNVefrATGLLgYE4xR+YI/Resw6nnaoVltzlVAAb/E8xWtdiYpnOeVPYSeFPF1D6flZ71y2VYswc1C2NihM0lrtSH7vokQag2dBefvPsR2XCrWxIkW51U6AvOhI26CMJB6kIJFRqET9lK5aneeSPvEilpJEbZr2KKifyy7zg69CNocD93mLZ5u8jFLzhvQ2n0PwmioM/P5GyfnDQJLlpyxX4QuZGO1v9d3rcZWu1xX5a9O5TCTf3SDh2uAmusaESn/CKP8wzkyT9cgAAAAABwmo3A4TUbgJGvlkHCajcBsvC6wSNfLIFTxaFDhNRuA/RO48Nl4XWDFXv4Qka+WQI2JNTCp4tCgtcRz0cJqNwHeTJRx+idx4eYB0pGy8LrBrtYZsYq9/CGWm19RI18sgT95j/EbEmphBzTJEVPFoUFP4wIxa4jnoXeuRNOE1G4DmPLNc7yZKOOgv4uT9E7jw+hoQLPMA6Uj0CUGU2XhdYN5x9bzXawzY0GKkBMVe/hDCV1bMy02vqMxEB3SRr5ZAlqY+nJ+8x/iYtW8kjYk1MIqAneyDmmSIhJPMVKni0KCu63h8p/GBGKD4KcS1xHPQss3bDLvXImi83oq1wmo3AcVjn93MeWa5y3DOZd5MlHHZRTyt0F/FyddWbRX6J3Hh/S7ZPfQ0IFnzPYiF5gHSkeEIek3oEoMp7xsr9bLwusG1+RIdvOPrebvqQ6Wu1hmxqd+xbaDFSAmnzODVir38IY20VP2Erq2Zg6cFRZabX1GRkveNmIgO6Z+BpjUjXyyBJFaEXS1MfTkqRdXlP3mP8ThwJy0xat5JNmN2lRsSamEcG8K9FQE72RIIkwUHNMkRAD1hzQknmKkOLjB1U8WhQVTMCZ1d1vD5Wt9YJU/jAjFI6qrtQfBTiUb5+1VriOehbIFPfWWbthlikh7Fd65E0XCn7A15vRVpfrS9t4TUbgOD3cbfisc/u43Ol2eY8s1zn/tlr5bhnMuR6DQXvJko47uQgD+yinlbtYPRh6C/i5OntiNPrqzaK6mlcvf0TuPD80dLH/pdsnv9VBqn6GhAs+9h6G/mexEL4XK518wDpSPLCg3/whD0m8UZXEfQJQZT1yyuj942V+vZP/83ZeF1g2Lo3V9r8iQ7bPuM53nH1vN+zn4vd9SHS3DdL5ddrDNjWqWbv1O/YttUtsoHQYqQE0aDOM9PmcGrSJBpdxV7+EMSclCfG2ip+xxhAScJXVszDlTz7wdOCosAR6JXLTa+oyo/Fn8jJe8bJCxHxzEQHdM2GbUPPwNMazgK5LZGvlkCQbfx3kitCLpPpKBmWpj6cl2RUq5Ui6vKU4IDFn7zH+J5+rc+cOBOWnfp5oZi1bySZdwUTmzG7Sprz0X2NiTUwjEtfB44N4V6Pz4tpioCd7ItC99uJBEmCiMYjtYOaZIiCWA6/gB6w5oHc2tGEk8xUhVGmY4cXGDqG1XINqeLQoKggupeqZgTOq6Ru+a7reHyvKRJLrW+sEqytxiWn8YEYpjPrL6R1VXaltz9BoPgpxKE6Q/OjfP2qor6XnbXEc9C0BhnntkCnvreCzYmyzdsMsw+xO7FJD2Kwi2VVu9ciaLoVSF+4U/YGuZGcMbzeirS9HOCDv1pe2r6YNO0AAAAAuLxnZaoJyIsSta/uj2KXVzfe8DIla1/cndc4ucW0KO99CE+Kb73gZNcBhwFK1r+48mrY3eDfdzNYYxBWUBlXn+ilMPr6EJ8UQqz4cd97wMhnx6etdXIIQ83ObyaVrX9wLREYFT+kt/uHGNCeGs/oJ6Jzj0KwxiCsCHpHyaAyrz4YjshbCjtntbKHANAvUDhpl+xfDIVZ8OI95ZeHZYaH0d064LTPj09adzMoP+rkEIZSWHfjQO3YDfhRv2jwK/ihSJefxFoiMCrinldPf0lv9sf1CJPVQKd9bfzAGDWf0E6NI7crn5YYxScqf6C6/UcZAkEgfBD0j5KoSOj3mxRYPSOoP1gxHZC2iaH30xR2z2qsyqgPvn8H4QbDYIReoHDS5hwXt/SpuFlMFd880cLnhWl+gOB7yy8Ow3dIa8sND6JzsWjHYQTHKdm4oExEb5j1/NP/kO5mUH5W2jcbDrknTbYFQCiksO/GHAyIo4HbsBo5Z9d/K9J4kZNuH/Q7JvcDg5qQZpEvP4gpk1jttERgVAz4BzEeTajfpvHPuv6S3+xGLriJVJsXZ+wncAJx8Ei7yUwv3tv5gDBjRedVaz+gnNODx/nBNmgXeYoPcuRdN8tc4VCuTlT/QPbomCWui4hzFjfvFgSCQPi8PiedIekfJJlVeEGL4NevM1ywyu1ZtjtV5dFeR1B+sP/sGdViOyFs2odGCcgy6edwjo6CKO2e1JBR+bGC5FZfOlgxOqePCYMfM27mDYbBCLU6pm29QOGkBfyGwRdJKS+v9U5KMiJ284qeEZaYK754IJfZHXj0yUvASK4u0v0BwGpBZqX3ll4cTyo5eV2flpflI/HyTWsZBfXXfmDnYtGOX96268IJjlJ6tek3aABG2dC8IbyI3zHqMGNWjyLW+WGaap4EB72mvb8BwdittG42FQgJUx1yTpqlzin/t3uGEQ/H4XSSENnNKqy+qDgZEUaApXYj2MZmdWB6ARByz67+ynPJm1ek8SLvGJZH/a05qUURXsx2Te4GzvGJY9xEJo1k+EHo+S95UUGTHjRTJrHa65rWv7P5xukLRaGMGfAOYqFMaQc8m1G+hCc225aSmTUuLv5QJlS5mZ7o3vyMXXESNOEWd6k2Ls4RikmrAz/mRbuDgSDj4JF2W1z2E0npWf3xVT6YbIIGIdQ+YUTGi86qfjepz9Z/QThuwyZdfHaJs8TK7tZZHdZv4aGxCvMUHuRLqHmBE8tp16t3DrK5wqFcAX7GOZyp/oAkFZnlNqA2C44cUW6GZhanPtpxwixv3iyU07lJCQSB8LG45pWjDUl7G7EuHkPSPkj7blkt6dv2w1FnkabMsKkfdAzOema5YZTeBQbxAAA6JjsmZSZmJmMmYCYiINglyyXZJUImQCZqJmsmPCa6JcQllSE8ILYApwCsJaghkSGTIZIhkCEfIpQhsiW8JSAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0ATgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAGIAYwBkAGUAZgBnAGgAaQBqAGsAbABtAG4AbwBwAHEAcgBzAHQAdQB2AHcAeAB5AHoAewB8AH0AfgACI8cA/ADpAOIA5ADgAOUA5wDqAOsA6ADvAO4A7ADEAMUAyQDmAMYA9AD2APIA+wD5AP8A1gDcAKIAowClAKcgkgHhAO0A8wD6APEA0QCqALoAvwAQI6wAvQC8AKEAqwC7AJElkiWTJQIlJCVhJWIlViVVJWMlUSVXJV0lXCVbJRAlFCU0JSwlHCUAJTwlXiVfJVolVCVpJWYlYCVQJWwlZyVoJWQlZSVZJVglUiVTJWslaiUYJQwliCWEJYwlkCWAJbED3wCTA8ADowPDA7UAxAOmA5gDqQO0Ax4ixgO1AykiYSKxAGUiZCIgIyEj9wBIIrAAGSK3ABoifyCyAKAloAAAAAAAAABQSwYGAFBLBgcAUEsFBgBQSwMEAFBLAQIAQUUAbmVlZCBkaWN0aW9uYXJ5AHN0cmVhbSBlbmQAAGZpbGUgZXJyb3IAc3RyZWFtIGVycm9yAGRhdGEgZXJyb3IAaW5zdWZmaWNpZW50IG1lbW9yeQBidWZmZXIgZXJyb3IAaW5jb21wYXRpYmxlIHZlcnNpb24AQdDUAAsm0ikAAOIpAADtKQAA7ikAAPkpAAAGKgAAESoAACUqAAAyKgAA7SkAQYHVAAu2EAECAwQEBQUGBgYGBwcHBwgICAgICAgICQkJCQkJCQkKCgoKCgoKCgoKCgoKCgoKCwsLCwsLCwsLCwsLCwsLCwwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAEBESEhMTFBQUFBUVFRUWFhYWFhYWFhcXFxcXFxcXGBgYGBgYGBgYGBgYGBgYGBkZGRkZGRkZGRkZGRkZGRkaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHB0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0AAQIDBAUGBwgICQkKCgsLDAwMDA0NDQ0ODg4ODw8PDxAQEBAQEBAQERERERERERESEhISEhISEhMTExMTExMTFBQUFBQUFBQUFBQUFBQUFBUVFRUVFRUVFRUVFRUVFRUWFhYWFhYWFhYWFhYWFhYWFxcXFxcXFxcXFxcXFxcXFxgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxscwC0AAMAyAAABAQAAHgEAAA8AAABAMgAAQDMAAAAAAAAeAAAADwAAAAAAAADAMwAAAAAAABMAAAAHAAAAAAAAAAwACACMAAgATAAIAMwACAAsAAgArAAIAGwACADsAAgAHAAIAJwACABcAAgA3AAIADwACAC8AAgAfAAIAPwACAACAAgAggAIAEIACADCAAgAIgAIAKIACABiAAgA4gAIABIACACSAAgAUgAIANIACAAyAAgAsgAIAHIACADyAAgACgAIAIoACABKAAgAygAIACoACACqAAgAagAIAOoACAAaAAgAmgAIAFoACADaAAgAOgAIALoACAB6AAgA+gAIAAYACACGAAgARgAIAMYACAAmAAgApgAIAGYACADmAAgAFgAIAJYACABWAAgA1gAIADYACAC2AAgAdgAIAPYACAAOAAgAjgAIAE4ACADOAAgALgAIAK4ACABuAAgA7gAIAB4ACACeAAgAXgAIAN4ACAA+AAgAvgAIAH4ACAD+AAgAAQAIAIEACABBAAgAwQAIACEACAChAAgAYQAIAOEACAARAAgAkQAIAFEACADRAAgAMQAIALEACABxAAgA8QAIAAkACACJAAgASQAIAMkACAApAAgAqQAIAGkACADpAAgAGQAIAJkACABZAAgA2QAIADkACAC5AAgAeQAIAPkACAAFAAgAhQAIAEUACADFAAgAJQAIAKUACABlAAgA5QAIABUACACVAAgAVQAIANUACAA1AAgAtQAIAHUACAD1AAgADQAIAI0ACABNAAgAzQAIAC0ACACtAAgAbQAIAO0ACAAdAAgAnQAIAF0ACADdAAgAPQAIAL0ACAB9AAgA/QAIABMACQATAQkAkwAJAJMBCQBTAAkAUwEJANMACQDTAQkAMwAJADMBCQCzAAkAswEJAHMACQBzAQkA8wAJAPMBCQALAAkACwEJAIsACQCLAQkASwAJAEsBCQDLAAkAywEJACsACQArAQkAqwAJAKsBCQBrAAkAawEJAOsACQDrAQkAGwAJABsBCQCbAAkAmwEJAFsACQBbAQkA2wAJANsBCQA7AAkAOwEJALsACQC7AQkAewAJAHsBCQD7AAkA+wEJAAcACQAHAQkAhwAJAIcBCQBHAAkARwEJAMcACQDHAQkAJwAJACcBCQCnAAkApwEJAGcACQBnAQkA5wAJAOcBCQAXAAkAFwEJAJcACQCXAQkAVwAJAFcBCQDXAAkA1wEJADcACQA3AQkAtwAJALcBCQB3AAkAdwEJAPcACQD3AQkADwAJAA8BCQCPAAkAjwEJAE8ACQBPAQkAzwAJAM8BCQAvAAkALwEJAK8ACQCvAQkAbwAJAG8BCQDvAAkA7wEJAB8ACQAfAQkAnwAJAJ8BCQBfAAkAXwEJAN8ACQDfAQkAPwAJAD8BCQC/AAkAvwEJAH8ACQB/AQkA/wAJAP8BCQAAAAcAQAAHACAABwBgAAcAEAAHAFAABwAwAAcAcAAHAAgABwBIAAcAKAAHAGgABwAYAAcAWAAHADgABwB4AAcABAAHAEQABwAkAAcAZAAHABQABwBUAAcANAAHAHQABwADAAgAgwAIAEMACADDAAgAIwAIAKMACABjAAgA4wAIAAAABQAQAAUACAAFABgABQAEAAUAFAAFAAwABQAcAAUAAgAFABIABQAKAAUAGgAFAAYABQAWAAUADgAFAB4ABQABAAUAEQAFAAkABQAZAAUABQAFABUABQANAAUAHQAFAAMABQATAAUACwAFABsABQAHAAUAFwAFAEHg5QALTQEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAwAAAAMAAAADAAAAAwAAAAQAAAAEAAAABAAAAAQAAAAFAAAABQAAAAUAAAAFAEHQ5gALZQEAAAABAAAAAgAAAAIAAAADAAAAAwAAAAQAAAAEAAAABQAAAAUAAAAGAAAABgAAAAcAAAAHAAAACAAAAAgAAAAJAAAACQAAAAoAAAAKAAAACwAAAAsAAAAMAAAADAAAAA0AAAANAEGA6AALIwIAAAADAAAABwAAAAAAAAAQERIACAcJBgoFCwQMAw0CDgEPAEG06AALaQEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAwAAAAOAAAAEAAAABQAAAAYAAAAHAAAACAAAAAoAAAAMAAAADgAAABAAAAAUAAAAGAAAABwAAAAgAAAAKAAAADAAAAA4ABBtOkAC3oBAAAAAgAAAAMAAAAEAAAABgAAAAgAAAAMAAAAEAAAABgAAAAgAAAAMAAAAEAAAABgAAAAgAAAAMAAAAAAAQAAgAEAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAQAAAAGAAADEuMi4xMQBBuOoAC20HAAAABAAEAAgABAAIAAAABAAFABAACAAIAAAABAAGACAAIAAIAAAABAAEABAAEAAJAAAACAAQACAAIAAJAAAACAAQAIAAgAAJAAAACAAgAIAAAAEJAAAAIACAAAIBAAQJAAAAIAACAQIBABAJAEGw6wAL1gIDAAQABQAGAAcACAAJAAoACwANAA8AEQATABcAGwAfACMAKwAzADsAQwBTAGMAcwCDAKMAwwDjAAIBAAAAAAAAEAAQABAAEAAQABAAEAAQABEAEQARABEAEgASABIAEgATABMAEwATABQAFAAUABQAFQAVABUAFQAQAE0AygAAAAEAAgADAAQABQAHAAkADQARABkAIQAxAEEAYQCBAMEAAQGBAQECAQMBBAEGAQgBDAEQARgBIAEwAUABYAAAAAAQABAAEAAQABEAEQASABIAEwATABQAFAAVABUAFgAWABcAFwAYABgAGQAZABoAGgAbABsAHAAcAB0AHQBAAEAAaW52YWxpZCBkaXN0YW5jZSB0b28gZmFyIGJhY2sAaW52YWxpZCBkaXN0YW5jZSBjb2RlAGludmFsaWQgbGl0ZXJhbC9sZW5ndGggY29kZQAxLjIuMTEAQZDuAAvyAxAAEQASAAAACAAHAAkABgAKAAUACwAEAAwAAwANAAIADgABAA8AaW5jb3JyZWN0IGhlYWRlciBjaGVjawB1bmtub3duIGNvbXByZXNzaW9uIG1ldGhvZABpbnZhbGlkIHdpbmRvdyBzaXplAHVua25vd24gaGVhZGVyIGZsYWdzIHNldABoZWFkZXIgY3JjIG1pc21hdGNoAGludmFsaWQgYmxvY2sgdHlwZQBpbnZhbGlkIHN0b3JlZCBibG9jayBsZW5ndGhzAHRvbyBtYW55IGxlbmd0aCBvciBkaXN0YW5jZSBzeW1ib2xzAGludmFsaWQgY29kZSBsZW5ndGhzIHNldABpbnZhbGlkIGJpdCBsZW5ndGggcmVwZWF0AGludmFsaWQgY29kZSAtLSBtaXNzaW5nIGVuZC1vZi1ibG9jawBpbnZhbGlkIGxpdGVyYWwvbGVuZ3RocyBzZXQAaW52YWxpZCBkaXN0YW5jZXMgc2V0AGludmFsaWQgbGl0ZXJhbC9sZW5ndGggY29kZQBpbnZhbGlkIGRpc3RhbmNlIGNvZGUAaW52YWxpZCBkaXN0YW5jZSB0b28gZmFyIGJhY2sAaW5jb3JyZWN0IGRhdGEgY2hlY2sAaW5jb3JyZWN0IGxlbmd0aCBjaGVjawBBkPIAC5cRYAcAAAAIUAAACBAAFAhzABIHHwAACHAAAAgwAAAJwAAQBwoAAAhgAAAIIAAACaAAAAgAAAAIgAAACEAAAAngABAHBgAACFgAAAgYAAAJkAATBzsAAAh4AAAIOAAACdAAEQcRAAAIaAAACCgAAAmwAAAICAAACIgAAAhIAAAJ8AAQBwQAAAhUAAAIFAAVCOMAEwcrAAAIdAAACDQAAAnIABEHDQAACGQAAAgkAAAJqAAACAQAAAiEAAAIRAAACegAEAcIAAAIXAAACBwAAAmYABQHUwAACHwAAAg8AAAJ2AASBxcAAAhsAAAILAAACbgAAAgMAAAIjAAACEwAAAn4ABAHAwAACFIAAAgSABUIowATByMAAAhyAAAIMgAACcQAEQcLAAAIYgAACCIAAAmkAAAIAgAACIIAAAhCAAAJ5AAQBwcAAAhaAAAIGgAACZQAFAdDAAAIegAACDoAAAnUABIHEwAACGoAAAgqAAAJtAAACAoAAAiKAAAISgAACfQAEAcFAAAIVgAACBYAQAgAABMHMwAACHYAAAg2AAAJzAARBw8AAAhmAAAIJgAACawAAAgGAAAIhgAACEYAAAnsABAHCQAACF4AAAgeAAAJnAAUB2MAAAh+AAAIPgAACdwAEgcbAAAIbgAACC4AAAm8AAAIDgAACI4AAAhOAAAJ/ABgBwAAAAhRAAAIEQAVCIMAEgcfAAAIcQAACDEAAAnCABAHCgAACGEAAAghAAAJogAACAEAAAiBAAAIQQAACeIAEAcGAAAIWQAACBkAAAmSABMHOwAACHkAAAg5AAAJ0gARBxEAAAhpAAAIKQAACbIAAAgJAAAIiQAACEkAAAnyABAHBAAACFUAAAgVABAIAgETBysAAAh1AAAINQAACcoAEQcNAAAIZQAACCUAAAmqAAAIBQAACIUAAAhFAAAJ6gAQBwgAAAhdAAAIHQAACZoAFAdTAAAIfQAACD0AAAnaABIHFwAACG0AAAgtAAAJugAACA0AAAiNAAAITQAACfoAEAcDAAAIUwAACBMAFQjDABMHIwAACHMAAAgzAAAJxgARBwsAAAhjAAAIIwAACaYAAAgDAAAIgwAACEMAAAnmABAHBwAACFsAAAgbAAAJlgAUB0MAAAh7AAAIOwAACdYAEgcTAAAIawAACCsAAAm2AAAICwAACIsAAAhLAAAJ9gAQBwUAAAhXAAAIFwBACAAAEwczAAAIdwAACDcAAAnOABEHDwAACGcAAAgnAAAJrgAACAcAAAiHAAAIRwAACe4AEAcJAAAIXwAACB8AAAmeABQHYwAACH8AAAg/AAAJ3gASBxsAAAhvAAAILwAACb4AAAgPAAAIjwAACE8AAAn+AGAHAAAACFAAAAgQABQIcwASBx8AAAhwAAAIMAAACcEAEAcKAAAIYAAACCAAAAmhAAAIAAAACIAAAAhAAAAJ4QAQBwYAAAhYAAAIGAAACZEAEwc7AAAIeAAACDgAAAnRABEHEQAACGgAAAgoAAAJsQAACAgAAAiIAAAISAAACfEAEAcEAAAIVAAACBQAFQjjABMHKwAACHQAAAg0AAAJyQARBw0AAAhkAAAIJAAACakAAAgEAAAIhAAACEQAAAnpABAHCAAACFwAAAgcAAAJmQAUB1MAAAh8AAAIPAAACdkAEgcXAAAIbAAACCwAAAm5AAAIDAAACIwAAAhMAAAJ+QAQBwMAAAhSAAAIEgAVCKMAEwcjAAAIcgAACDIAAAnFABEHCwAACGIAAAgiAAAJpQAACAIAAAiCAAAIQgAACeUAEAcHAAAIWgAACBoAAAmVABQHQwAACHoAAAg6AAAJ1QASBxMAAAhqAAAIKgAACbUAAAgKAAAIigAACEoAAAn1ABAHBQAACFYAAAgWAEAIAAATBzMAAAh2AAAINgAACc0AEQcPAAAIZgAACCYAAAmtAAAIBgAACIYAAAhGAAAJ7QAQBwkAAAheAAAIHgAACZ0AFAdjAAAIfgAACD4AAAndABIHGwAACG4AAAguAAAJvQAACA4AAAiOAAAITgAACf0AYAcAAAAIUQAACBEAFQiDABIHHwAACHEAAAgxAAAJwwAQBwoAAAhhAAAIIQAACaMAAAgBAAAIgQAACEEAAAnjABAHBgAACFkAAAgZAAAJkwATBzsAAAh5AAAIOQAACdMAEQcRAAAIaQAACCkAAAmzAAAICQAACIkAAAhJAAAJ8wAQBwQAAAhVAAAIFQAQCAIBEwcrAAAIdQAACDUAAAnLABEHDQAACGUAAAglAAAJqwAACAUAAAiFAAAIRQAACesAEAcIAAAIXQAACB0AAAmbABQHUwAACH0AAAg9AAAJ2wASBxcAAAhtAAAILQAACbsAAAgNAAAIjQAACE0AAAn7ABAHAwAACFMAAAgTABUIwwATByMAAAhzAAAIMwAACccAEQcLAAAIYwAACCMAAAmnAAAIAwAACIMAAAhDAAAJ5wAQBwcAAAhbAAAIGwAACZcAFAdDAAAIewAACDsAAAnXABIHEwAACGsAAAgrAAAJtwAACAsAAAiLAAAISwAACfcAEAcFAAAIVwAACBcAQAgAABMHMwAACHcAAAg3AAAJzwARBw8AAAhnAAAIJwAACa8AAAgHAAAIhwAACEcAAAnvABAHCQAACF8AAAgfAAAJnwAUB2MAAAh/AAAIPwAACd8AEgcbAAAIbwAACC8AAAm/AAAIDwAACI8AAAhPAAAJ/wAQBQEAFwUBARMFEQAbBQEQEQUFABkFAQQVBUEAHQUBQBAFAwAYBQECFAUhABwFASASBQkAGgUBCBYFgQBABQAAEAUCABcFgQETBRkAGwUBGBEFBwAZBQEGFQVhAB0FAWAQBQQAGAUBAxQFMQAcBQEwEgUNABoFAQwWBcEAQAUAADEuMi4xMQAtKyAgIDBYMHgAKG51bGwpAEGwgwELQREACgAREREAAAAABQAAAAAAAAkAAAAACwAAAAAAAAAAEQAPChEREQMKBwABAAkLCwAACQYLAAALAAYRAAAAERERAEGBhAELIQsAAAAAAAAAABEACgoREREACgAAAgAJCwAAAAkACwAACwBBu4QBCwEMAEHHhAELFQwAAAAADAAAAAAJDAAAAAAADAAADABB9YQBCwEOAEGBhQELFQ0AAAAEDQAAAAAJDgAAAAAADgAADgBBr4UBCwEQAEG7hQELHg8AAAAADwAAAAAJEAAAAAAAEAAAEAAAEgAAABISEgBB8oUBCw4SAAAAEhISAAAAAAAACQBBo4YBCwELAEGvhgELFQoAAAAACgAAAAAJCwAAAAAACwAACwBB3YYBCwEMAEHphgELSwwAAAAADAAAAAAJDAAAAAAADAAADAAAMDEyMzQ1Njc4OUFCQ0RFRi0wWCswWCAwWC0weCsweCAweABpbmYASU5GAG5hbgBOQU4ALgBB3IcBCwEXAEGDiAELBf//////AEHQiAELVxkSRDsCPyxHFD0zMAobBkZLRTcPSQ6OFwNAHTxpKzYfSi0cASAlKSEIDBUWIi4QOD4LNDEYZHR1di9BCX85ESNDMkKJiosFBCYoJw0qHjWMBxpIkxOUlQBBsIkBC90OSWxsZWdhbCBieXRlIHNlcXVlbmNlAERvbWFpbiBlcnJvcgBSZXN1bHQgbm90IHJlcHJlc2VudGFibGUATm90IGEgdHR5AFBlcm1pc3Npb24gZGVuaWVkAE9wZXJhdGlvbiBub3QgcGVybWl0dGVkAE5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkATm8gc3VjaCBwcm9jZXNzAEZpbGUgZXhpc3RzAFZhbHVlIHRvbyBsYXJnZSBmb3IgZGF0YSB0eXBlAE5vIHNwYWNlIGxlZnQgb24gZGV2aWNlAE91dCBvZiBtZW1vcnkAUmVzb3VyY2UgYnVzeQBJbnRlcnJ1cHRlZCBzeXN0ZW0gY2FsbABSZXNvdXJjZSB0ZW1wb3JhcmlseSB1bmF2YWlsYWJsZQBJbnZhbGlkIHNlZWsAQ3Jvc3MtZGV2aWNlIGxpbmsAUmVhZC1vbmx5IGZpbGUgc3lzdGVtAERpcmVjdG9yeSBub3QgZW1wdHkAQ29ubmVjdGlvbiByZXNldCBieSBwZWVyAE9wZXJhdGlvbiB0aW1lZCBvdXQAQ29ubmVjdGlvbiByZWZ1c2VkAEhvc3QgaXMgZG93bgBIb3N0IGlzIHVucmVhY2hhYmxlAEFkZHJlc3MgaW4gdXNlAEJyb2tlbiBwaXBlAEkvTyBlcnJvcgBObyBzdWNoIGRldmljZSBvciBhZGRyZXNzAEJsb2NrIGRldmljZSByZXF1aXJlZABObyBzdWNoIGRldmljZQBOb3QgYSBkaXJlY3RvcnkASXMgYSBkaXJlY3RvcnkAVGV4dCBmaWxlIGJ1c3kARXhlYyBmb3JtYXQgZXJyb3IASW52YWxpZCBhcmd1bWVudABBcmd1bWVudCBsaXN0IHRvbyBsb25nAFN5bWJvbGljIGxpbmsgbG9vcABGaWxlbmFtZSB0b28gbG9uZwBUb28gbWFueSBvcGVuIGZpbGVzIGluIHN5c3RlbQBObyBmaWxlIGRlc2NyaXB0b3JzIGF2YWlsYWJsZQBCYWQgZmlsZSBkZXNjcmlwdG9yAE5vIGNoaWxkIHByb2Nlc3MAQmFkIGFkZHJlc3MARmlsZSB0b28gbGFyZ2UAVG9vIG1hbnkgbGlua3MATm8gbG9ja3MgYXZhaWxhYmxlAFJlc291cmNlIGRlYWRsb2NrIHdvdWxkIG9jY3VyAFN0YXRlIG5vdCByZWNvdmVyYWJsZQBQcmV2aW91cyBvd25lciBkaWVkAE9wZXJhdGlvbiBjYW5jZWxlZABGdW5jdGlvbiBub3QgaW1wbGVtZW50ZWQATm8gbWVzc2FnZSBvZiBkZXNpcmVkIHR5cGUASWRlbnRpZmllciByZW1vdmVkAERldmljZSBub3QgYSBzdHJlYW0ATm8gZGF0YSBhdmFpbGFibGUARGV2aWNlIHRpbWVvdXQAT3V0IG9mIHN0cmVhbXMgcmVzb3VyY2VzAExpbmsgaGFzIGJlZW4gc2V2ZXJlZABQcm90b2NvbCBlcnJvcgBCYWQgbWVzc2FnZQBGaWxlIGRlc2NyaXB0b3IgaW4gYmFkIHN0YXRlAE5vdCBhIHNvY2tldABEZXN0aW5hdGlvbiBhZGRyZXNzIHJlcXVpcmVkAE1lc3NhZ2UgdG9vIGxhcmdlAFByb3RvY29sIHdyb25nIHR5cGUgZm9yIHNvY2tldABQcm90b2NvbCBub3QgYXZhaWxhYmxlAFByb3RvY29sIG5vdCBzdXBwb3J0ZWQAU29ja2V0IHR5cGUgbm90IHN1cHBvcnRlZABOb3Qgc3VwcG9ydGVkAFByb3RvY29sIGZhbWlseSBub3Qgc3VwcG9ydGVkAEFkZHJlc3MgZmFtaWx5IG5vdCBzdXBwb3J0ZWQgYnkgcHJvdG9jb2wAQWRkcmVzcyBub3QgYXZhaWxhYmxlAE5ldHdvcmsgaXMgZG93bgBOZXR3b3JrIHVucmVhY2hhYmxlAENvbm5lY3Rpb24gcmVzZXQgYnkgbmV0d29yawBDb25uZWN0aW9uIGFib3J0ZWQATm8gYnVmZmVyIHNwYWNlIGF2YWlsYWJsZQBTb2NrZXQgaXMgY29ubmVjdGVkAFNvY2tldCBub3QgY29ubmVjdGVkAENhbm5vdCBzZW5kIGFmdGVyIHNvY2tldCBzaHV0ZG93bgBPcGVyYXRpb24gYWxyZWFkeSBpbiBwcm9ncmVzcwBPcGVyYXRpb24gaW4gcHJvZ3Jlc3MAU3RhbGUgZmlsZSBoYW5kbGUAUmVtb3RlIEkvTyBlcnJvcgBRdW90YSBleGNlZWRlZABObyBtZWRpdW0gZm91bmQAV3JvbmcgbWVkaXVtIHR5cGUATm8gZXJyb3IgaW5mb3JtYXRpb24AAFVua25vd24gZXJyb3IgJWQAJXMlcyVzAAA6IAAvcHJvYy9zZWxmL2ZkLwAvZGV2L3VyYW5kb20AcndhACVzLlhYWFhYWAByK2IAcmIAUEsFBgBBkJgBC04KAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAALAAAADAAAAA0AAAAOAAAADwAAABAAAAARAAAAAQAAAAgAAAAQTAAAMEwAQZCaAQsCgFAAQciaAQsJHwAAAGRNAAADAEHkmgELjAEt9FFYz4yxwEb2tcspMQPHBFtwMLRd/SB4f4ua2FkpUGhIiaunVgNs/7fNiD/Ud7QrpaNw8brkqPxBg/3Zb+GKei8tdJYHHw0JXgN2LHD3QKUsp29XQaiqdN+gWGQDSsfEPFOur18YBBWx420ohqsMpL9D8OlQgTlXFlI3/////////////////////w==";function Ae(e){for(;e.length>0;){var t=e.shift();if("function"!=typeof t){var r=t.func;"number"==typeof r?void 0===t.arg?f.get(r)():f.get(r)(t.arg):r(void 0===t.arg?null:t.arg)}else t(o)}}function ne(){var e=function(){var e=new Error;if(!e.stack){try{throw new Error}catch(t){e=t}if(!e.stack)return"(no stack trace available)"}return e.stack.toString()}();return o.extraStackTrace&&(e+="\n"+o.extraStackTrace()),e.replace(/\b_Z[\w\d_]+/g,(function(e){return e==e?e:e+" ["+e+"]"}))}function oe(e,t){var r=new Date(1e3*M[e>>2]);M[t>>2]=r.getUTCSeconds(),M[t+4>>2]=r.getUTCMinutes(),M[t+8>>2]=r.getUTCHours(),M[t+12>>2]=r.getUTCDate(),M[t+16>>2]=r.getUTCMonth(),M[t+20>>2]=r.getUTCFullYear()-1900,M[t+24>>2]=r.getUTCDay(),M[t+36>>2]=0,M[t+32>>2]=0;var A=Date.UTC(r.getUTCFullYear(),0,1,0,0,0,0),n=(r.getTime()-A)/864e5|0;return M[t+28>>2]=n,oe.GMTString||(oe.GMTString=S("GMT")),M[t+40>>2]=oe.GMTString,t}Z(re)||($=re,re=o.locateFile?o.locateFile($,u):u+$),U.push({func:function(){Se()}});var ie={splitPath:function(e){return/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/.exec(e).slice(1)},normalizeArray:function(e,t){for(var r=0,A=e.length-1;A>=0;A--){var n=e[A];"."===n?e.splice(A,1):".."===n?(e.splice(A,1),r++):r&&(e.splice(A,1),r--)}if(t)for(;r;r--)e.unshift("..");return e},normalize:function(e){var t="/"===e.charAt(0),r="/"===e.substr(-1);return(e=ie.normalizeArray(e.split("/").filter((function(e){return!!e})),!t).join("/"))||t||(e="."),e&&r&&(e+="/"),(t?"/":"")+e},dirname:function(e){var t=ie.splitPath(e),r=t[0],A=t[1];return r||A?(A&&(A=A.substr(0,A.length-1)),r+A):"."},basename:function(e){if("/"===e)return"/";var t=(e=(e=ie.normalize(e)).replace(/\/$/,"")).lastIndexOf("/");return-1===t?e:e.substr(t+1)},extname:function(e){return ie.splitPath(e)[3]},join:function(){var e=Array.prototype.slice.call(arguments,0);return ie.normalize(e.join("/"))},join2:function(e,t){return ie.normalize(e+"/"+t)}};function se(e){return M[ke()>>2]=e,e}var ae={resolve:function(){for(var e="",t=!1,r=arguments.length-1;r>=-1&&!t;r--){var A=r>=0?arguments[r]:pe.cwd();if("string"!=typeof A)throw new TypeError("Arguments to path.resolve must be strings");if(!A)return"";e=A+"/"+e,t="/"===A.charAt(0)}return(t?"/":"")+(e=ie.normalizeArray(e.split("/").filter((function(e){return!!e})),!t).join("/"))||"."},relative:function(e,t){function r(e){for(var t=0;t=0&&""===e[r];r--);return t>r?[]:e.slice(t,r-t+1)}e=ae.resolve(e).substr(1),t=ae.resolve(t).substr(1);for(var A=r(e.split("/")),n=r(t.split("/")),o=Math.min(A.length,n.length),i=o,s=0;s0?r.slice(0,A).toString("utf-8"):null))return null;e.input=we(t,!0)}return e.input.shift()},put_char:function(e,t){null===t||10===t?(h(w(e.output,0)),e.output=[]):0!=t&&e.output.push(t)},flush:function(e){e.output&&e.output.length>0&&(h(w(e.output,0)),e.output=[])}},default_tty1_ops:{put_char:function(e,t){null===t||10===t?(p(w(e.output,0)),e.output=[]):0!=t&&e.output.push(t)},flush:function(e){e.output&&e.output.length>0&&(p(w(e.output,0)),e.output=[])}}},ge={ops_table:null,mount:function(e){return ge.createNode(null,"/",16895,0)},createNode:function(e,t,r,A){if(pe.isBlkdev(r)||pe.isFIFO(r))throw new pe.ErrnoError(63);ge.ops_table||(ge.ops_table={dir:{node:{getattr:ge.node_ops.getattr,setattr:ge.node_ops.setattr,lookup:ge.node_ops.lookup,mknod:ge.node_ops.mknod,rename:ge.node_ops.rename,unlink:ge.node_ops.unlink,rmdir:ge.node_ops.rmdir,readdir:ge.node_ops.readdir,symlink:ge.node_ops.symlink},stream:{llseek:ge.stream_ops.llseek}},file:{node:{getattr:ge.node_ops.getattr,setattr:ge.node_ops.setattr},stream:{llseek:ge.stream_ops.llseek,read:ge.stream_ops.read,write:ge.stream_ops.write,allocate:ge.stream_ops.allocate,mmap:ge.stream_ops.mmap,msync:ge.stream_ops.msync}},link:{node:{getattr:ge.node_ops.getattr,setattr:ge.node_ops.setattr,readlink:ge.node_ops.readlink},stream:{}},chrdev:{node:{getattr:ge.node_ops.getattr,setattr:ge.node_ops.setattr},stream:pe.chrdev_stream_ops}});var n=pe.createNode(e,t,r,A);return pe.isDir(n.mode)?(n.node_ops=ge.ops_table.dir.node,n.stream_ops=ge.ops_table.dir.stream,n.contents={}):pe.isFile(n.mode)?(n.node_ops=ge.ops_table.file.node,n.stream_ops=ge.ops_table.file.stream,n.usedBytes=0,n.contents=null):pe.isLink(n.mode)?(n.node_ops=ge.ops_table.link.node,n.stream_ops=ge.ops_table.link.stream):pe.isChrdev(n.mode)&&(n.node_ops=ge.ops_table.chrdev.node,n.stream_ops=ge.ops_table.chrdev.stream),n.timestamp=Date.now(),e&&(e.contents[t]=n),n},getFileDataAsRegularArray:function(e){if(e.contents&&e.contents.subarray){for(var t=[],r=0;r=t)){t=Math.max(t,r*(r<1048576?2:1.125)>>>0),0!=r&&(t=Math.max(t,256));var A=e.contents;e.contents=new Uint8Array(t),e.usedBytes>0&&e.contents.set(A.subarray(0,e.usedBytes),0)}},resizeFileStorage:function(e,t){if(e.usedBytes!=t){if(0==t)return e.contents=null,void(e.usedBytes=0);if(!e.contents||e.contents.subarray){var r=e.contents;return e.contents=new Uint8Array(t),r&&e.contents.set(r.subarray(0,Math.min(t,e.usedBytes))),void(e.usedBytes=t)}if(e.contents||(e.contents=[]),e.contents.length>t)e.contents.length=t;else for(;e.contents.length=e.node.usedBytes)return 0;var i=Math.min(e.node.usedBytes-n,A);if(i>8&&o.subarray)t.set(o.subarray(n,n+i),r);else for(var s=0;s0||A+r>2)}catch(e){if(!e.code)throw e;throw new pe.ErrnoError(ue.convertNodeCode(e))}return t.mode},realPath:function(e){for(var t=[];e.parent!==e;)t.push(e.name),e=e.parent;return t.push(e.mount.opts.root),t.reverse(),ie.join.apply(null,t)},flagsForNode:function(e){e&=-2097153,e&=-2049,e&=-32769,e&=-524289;var t=0;for(var r in ue.flagsForNodeMap)e&r&&(t|=ue.flagsForNodeMap[r],e^=r);if(e)throw new pe.ErrnoError(28);return t},node_ops:{getattr:function(e){var t,r=ue.realPath(e);try{t=Ie.lstatSync(r)}catch(e){if(!e.code)throw e;throw new pe.ErrnoError(ue.convertNodeCode(e))}return ue.isWindows&&!t.blksize&&(t.blksize=4096),ue.isWindows&&!t.blocks&&(t.blocks=(t.size+t.blksize-1)/t.blksize|0),{dev:t.dev,ino:t.ino,mode:t.mode,nlink:t.nlink,uid:t.uid,gid:t.gid,rdev:t.rdev,size:t.size,atime:t.atime,mtime:t.mtime,ctime:t.ctime,blksize:t.blksize,blocks:t.blocks}},setattr:function(e,t){var r=ue.realPath(e);try{if(void 0!==t.mode&&(Ie.chmodSync(r,t.mode),e.mode=t.mode),void 0!==t.timestamp){var A=new Date(t.timestamp);Ie.utimesSync(r,A,A)}void 0!==t.size&&Ie.truncateSync(r,t.size)}catch(e){if(!e.code)throw e;throw new pe.ErrnoError(ue.convertNodeCode(e))}},lookup:function(e,t){var r=ie.join2(ue.realPath(e),t),A=ue.getMode(r);return ue.createNode(e,t,A)},mknod:function(e,t,r,A){var n=ue.createNode(e,t,r,A),o=ue.realPath(n);try{pe.isDir(n.mode)?Ie.mkdirSync(o,n.mode):Ie.writeFileSync(o,"",{mode:n.mode})}catch(e){if(!e.code)throw e;throw new pe.ErrnoError(ue.convertNodeCode(e))}return n},rename:function(e,t,r){var A=ue.realPath(e),n=ie.join2(ue.realPath(t),r);try{Ie.renameSync(A,n)}catch(e){if(!e.code)throw e;throw new pe.ErrnoError(ue.convertNodeCode(e))}e.name=r},unlink:function(e,t){var r=ie.join2(ue.realPath(e),t);try{Ie.unlinkSync(r)}catch(e){if(!e.code)throw e;throw new pe.ErrnoError(ue.convertNodeCode(e))}},rmdir:function(e,t){var r=ie.join2(ue.realPath(e),t);try{Ie.rmdirSync(r)}catch(e){if(!e.code)throw e;throw new pe.ErrnoError(ue.convertNodeCode(e))}},readdir:function(e){var t=ue.realPath(e);try{return Ie.readdirSync(t)}catch(e){if(!e.code)throw e;throw new pe.ErrnoError(ue.convertNodeCode(e))}},symlink:function(e,t,r){var A=ie.join2(ue.realPath(e),t);try{Ie.symlinkSync(r,A)}catch(e){if(!e.code)throw e;throw new pe.ErrnoError(ue.convertNodeCode(e))}},readlink:function(e){var t=ue.realPath(e);try{return t=Ie.readlinkSync(t),t=Ee.relative(Ee.resolve(e.mount.opts.root),t)}catch(e){if(!e.code)throw e;throw new pe.ErrnoError(ue.convertNodeCode(e))}}},stream_ops:{open:function(e){var t=ue.realPath(e.node);try{pe.isFile(e.node.mode)&&(e.nfd=Ie.openSync(t,ue.flagsForNode(e.flags)))}catch(e){if(!e.code)throw e;throw new pe.ErrnoError(ue.convertNodeCode(e))}},close:function(e){try{pe.isFile(e.node.mode)&&e.nfd&&Ie.closeSync(e.nfd)}catch(e){if(!e.code)throw e;throw new pe.ErrnoError(ue.convertNodeCode(e))}},read:function(e,t,r,A,n){if(0===A)return 0;try{return Ie.readSync(e.nfd,ue.bufferFrom(t.buffer),r,A,n)}catch(e){throw new pe.ErrnoError(ue.convertNodeCode(e))}},write:function(e,t,r,A,n){try{return Ie.writeSync(e.nfd,ue.bufferFrom(t.buffer),r,A,n)}catch(e){throw new pe.ErrnoError(ue.convertNodeCode(e))}},llseek:function(e,t,r){var A=t;if(1===r)A+=e.position;else if(2===r&&pe.isFile(e.node.mode))try{A+=Ie.fstatSync(e.nfd).size}catch(e){throw new pe.ErrnoError(ue.convertNodeCode(e))}if(A<0)throw new pe.ErrnoError(28);return A},mmap:function(e,t,r,A,n,o){if(E(0===t),!pe.isFile(e.node.mode))throw new pe.ErrnoError(43);var i=pe.mmapAlloc(r);return ue.stream_ops.read(e,N,i,r,A),{ptr:i,allocated:!0}},msync:function(e,t,r,A,n){if(!pe.isFile(e.node.mode))throw new pe.ErrnoError(43);if(2&n)return 0;ue.stream_ops.write(e,t,0,A,r,!1);return 0}}},he={lookupPath:function(e){return{path:e,node:{mode:ue.getMode(e)}}},createStandardStreams:function(){pe.streams[0]={fd:0,nfd:0,position:0,path:"",flags:0,tty:!0,seekable:!1};for(var e=1;e<3;e++)pe.streams[e]={fd:e,nfd:e,position:0,path:"",flags:577,tty:!0,seekable:!1}},cwd:function(){return process.cwd()},chdir:function(){process.chdir.apply(void 0,arguments)},mknod:function(e,t){pe.isDir(e)?Ie.mkdirSync(e,t):Ie.writeFileSync(e,"",{mode:t})},mkdir:function(){Ie.mkdirSync.apply(void 0,arguments)},symlink:function(){Ie.symlinkSync.apply(void 0,arguments)},rename:function(){Ie.renameSync.apply(void 0,arguments)},rmdir:function(){Ie.rmdirSync.apply(void 0,arguments)},readdir:function(){Ie.readdirSync.apply(void 0,arguments)},unlink:function(){Ie.unlinkSync.apply(void 0,arguments)},readlink:function(){return Ie.readlinkSync.apply(void 0,arguments)},stat:function(){return Ie.statSync.apply(void 0,arguments)},lstat:function(){return Ie.lstatSync.apply(void 0,arguments)},chmod:function(){Ie.chmodSync.apply(void 0,arguments)},fchmod:function(){Ie.fchmodSync.apply(void 0,arguments)},chown:function(){Ie.chownSync.apply(void 0,arguments)},fchown:function(){Ie.fchownSync.apply(void 0,arguments)},truncate:function(){Ie.truncateSync.apply(void 0,arguments)},ftruncate:function(){Ie.ftruncateSync.apply(void 0,arguments)},utime:function(){Ie.utimesSync.apply(void 0,arguments)},open:function(e,t,r,A){"string"==typeof t&&(t=ye.modeStringToFlags(t));var n=Ie.openSync(e,ue.flagsForNode(t),r),o=null!=A?A:pe.nextfd(n),i={fd:o,nfd:n,position:0,path:e,flags:t,seekable:!0};return pe.streams[o]=i,i},close:function(e){e.stream_ops||Ie.closeSync(e.nfd),pe.closeStream(e.fd)},llseek:function(e,t,r){if(e.stream_ops)return ye.llseek(e,t,r);var A=t;if(1===r)A+=e.position;else if(2===r)A+=Ie.fstatSync(e.nfd).size;else if(0!==r)throw new pe.ErrnoError(le.EINVAL);if(A<0)throw new pe.ErrnoError(le.EINVAL);return e.position=A,A},read:function(e,t,r,A,n){if(e.stream_ops)return ye.read(e,t,r,A,n);var o=void 0!==n;!o&&e.seekable&&(n=e.position);var i=Ie.readSync(e.nfd,ue.bufferFrom(t.buffer),r,A,n);return o||(e.position+=i),i},write:function(e,t,r,A,n){if(e.stream_ops)return ye.write(e,t,r,A,n);1024&e.flags&&pe.llseek(e,0,2);var o=void 0!==n;!o&&e.seekable&&(n=e.position);var i=Ie.writeSync(e.nfd,ue.bufferFrom(t.buffer),r,A,n);return o||(e.position+=i),i},allocate:function(){throw new pe.ErrnoError(le.EOPNOTSUPP)},mmap:function(){throw new pe.ErrnoError(le.ENODEV)},msync:function(){return 0},munmap:function(){return 0},ioctl:function(){throw new pe.ErrnoError(le.ENOTTY)}},pe={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:!1,ignorePermissions:!0,trackingDelegate:{},tracking:{openFlags:{READ:1,WRITE:2}},ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,handleFSError:function(e){if(!(e instanceof pe.ErrnoError))throw e+" : "+ne();return se(e.errno)},lookupPath:function(e,t){if(t=t||{},!(e=ae.resolve(pe.cwd(),e)))return{path:"",node:null};var r={follow_mount:!0,recurse_count:0};for(var A in r)void 0===t[A]&&(t[A]=r[A]);if(t.recurse_count>8)throw new pe.ErrnoError(32);for(var n=ie.normalizeArray(e.split("/").filter((function(e){return!!e})),!1),o=pe.root,i="/",s=0;s40)throw new pe.ErrnoError(32)}}return{path:i,node:o}},getPath:function(e){for(var t;;){if(pe.isRoot(e)){var r=e.mount.mountpoint;return t?"/"!==r[r.length-1]?r+"/"+t:r+t:r}t=t?e.name+"/"+t:e.name,e=e.parent}},hashName:function(e,t){for(var r=0,A=0;A>>0)%pe.nameTable.length},hashAddNode:function(e){var t=pe.hashName(e.parent.id,e.name);e.name_next=pe.nameTable[t],pe.nameTable[t]=e},hashRemoveNode:function(e){var t=pe.hashName(e.parent.id,e.name);if(pe.nameTable[t]===e)pe.nameTable[t]=e.name_next;else for(var r=pe.nameTable[t];r;){if(r.name_next===e){r.name_next=e.name_next;break}r=r.name_next}},lookupNode:function(e,t){var r=pe.mayLookup(e);if(r)throw new pe.ErrnoError(r,e);for(var A=pe.hashName(e.id,t),n=pe.nameTable[A];n;n=n.name_next){var o=n.name;if(n.parent.id===e.id&&o===t)return n}return pe.lookup(e,t)},createNode:function(e,t,r,A){var n=new pe.FSNode(e,t,r,A);return pe.hashAddNode(n),n},destroyNode:function(e){pe.hashRemoveNode(e)},isRoot:function(e){return e===e.parent},isMountpoint:function(e){return!!e.mounted},isFile:function(e){return 32768==(61440&e)},isDir:function(e){return 16384==(61440&e)},isLink:function(e){return 40960==(61440&e)},isChrdev:function(e){return 8192==(61440&e)},isBlkdev:function(e){return 24576==(61440&e)},isFIFO:function(e){return 4096==(61440&e)},isSocket:function(e){return 49152==(49152&e)},flagModes:{r:0,rs:1052672,"r+":2,w:577,wx:705,xw:705,"w+":578,"wx+":706,"xw+":706,a:1089,ax:1217,xa:1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function(e){var t=pe.flagModes[e];if(void 0===t)throw new Error("Unknown file open mode: "+e);return t},flagsToPermissionString:function(e){var t=["r","w","rw"][3&e];return 512&e&&(t+="w"),t},nodePermissions:function(e,t){return pe.ignorePermissions||(-1===t.indexOf("r")||292&e.mode)&&(-1===t.indexOf("w")||146&e.mode)&&(-1===t.indexOf("x")||73&e.mode)?0:2},mayLookup:function(e){var t=pe.nodePermissions(e,"x");return t||(e.node_ops.lookup?0:2)},mayCreate:function(e,t){try{pe.lookupNode(e,t);return 20}catch(e){}return pe.nodePermissions(e,"wx")},mayDelete:function(e,t,r){var A;try{A=pe.lookupNode(e,t)}catch(e){return e.errno}var n=pe.nodePermissions(e,"wx");if(n)return n;if(r){if(!pe.isDir(A.mode))return 54;if(pe.isRoot(A)||pe.getPath(A)===pe.cwd())return 10}else if(pe.isDir(A.mode))return 31;return 0},mayOpen:function(e,t){return e?pe.isLink(e.mode)?32:pe.isDir(e.mode)&&("r"!==pe.flagsToPermissionString(t)||512&t)?31:pe.nodePermissions(e,pe.flagsToPermissionString(t)):44},MAX_OPEN_FDS:4096,nextfd:function(e,t){e=e||0,t=t||pe.MAX_OPEN_FDS;for(var r=e;r<=t;r++)if(!pe.streams[r])return r;throw new pe.ErrnoError(33)},getStream:function(e){return pe.streams[e]},createStream:function(e,t,r){pe.FSStream||(pe.FSStream=function(){},pe.FSStream.prototype={object:{get:function(){return this.node},set:function(e){this.node=e}},isRead:{get:function(){return 1!=(2097155&this.flags)}},isWrite:{get:function(){return 0!=(2097155&this.flags)}},isAppend:{get:function(){return 1024&this.flags}}});var A=new pe.FSStream;for(var n in e)A[n]=e[n];e=A;var o=pe.nextfd(t,r);return e.fd=o,pe.streams[o]=e,e},closeStream:function(e){pe.streams[e]=null},chrdev_stream_ops:{open:function(e){var t=pe.getDevice(e.node.rdev);e.stream_ops=t.stream_ops,e.stream_ops.open&&e.stream_ops.open(e)},llseek:function(){throw new pe.ErrnoError(70)}},major:function(e){return e>>8},minor:function(e){return 255&e},makedev:function(e,t){return e<<8|t},registerDevice:function(e,t){pe.devices[e]={stream_ops:t}},getDevice:function(e){return pe.devices[e]},getMounts:function(e){for(var t=[],r=[e];r.length;){var A=r.pop();t.push(A),r.push.apply(r,A.mounts)}return t},syncfs:function(e,t){"function"==typeof e&&(t=e,e=!1),pe.syncFSRequests++,pe.syncFSRequests>1&&p("warning: "+pe.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work");var r=pe.getMounts(pe.root.mount),A=0;function n(e){return pe.syncFSRequests--,t(e)}function o(e){if(e)return o.errored?void 0:(o.errored=!0,n(e));++A>=r.length&&n(null)}r.forEach((function(t){if(!t.type.syncfs)return o(null);t.type.syncfs(t,e,o)}))},mount:function(e,t,r){var A,n="/"===r,o=!r;if(n&&pe.root)throw new pe.ErrnoError(10);if(!n&&!o){var i=pe.lookupPath(r,{follow_mount:!1});if(r=i.path,A=i.node,pe.isMountpoint(A))throw new pe.ErrnoError(10);if(!pe.isDir(A.mode))throw new pe.ErrnoError(54)}var s={type:e,opts:t,mountpoint:r,mounts:[]},a=e.mount(s);return a.mount=s,s.root=a,n?pe.root=a:A&&(A.mounted=s,A.mount&&A.mount.mounts.push(s)),a},unmount:function(e){var t=pe.lookupPath(e,{follow_mount:!1});if(!pe.isMountpoint(t.node))throw new pe.ErrnoError(28);var r=t.node,A=r.mounted,n=pe.getMounts(A);Object.keys(pe.nameTable).forEach((function(e){for(var t=pe.nameTable[e];t;){var r=t.name_next;-1!==n.indexOf(t.mount)&&pe.destroyNode(t),t=r}})),r.mounted=null;var o=r.mount.mounts.indexOf(A);r.mount.mounts.splice(o,1)},lookup:function(e,t){return e.node_ops.lookup(e,t)},mknod:function(e,t,r){var A=pe.lookupPath(e,{parent:!0}).node,n=ie.basename(e);if(!n||"."===n||".."===n)throw new pe.ErrnoError(28);var o=pe.mayCreate(A,n);if(o)throw new pe.ErrnoError(o);if(!A.node_ops.mknod)throw new pe.ErrnoError(63);return A.node_ops.mknod(A,n,t,r)},create:function(e,t){return t=void 0!==t?t:438,t&=4095,t|=32768,pe.mknod(e,t,0)},mkdir:function(e,t){return t=void 0!==t?t:511,t&=1023,t|=16384,pe.mknod(e,t,0)},mkdirTree:function(e,t){for(var r=e.split("/"),A="",n=0;nthis.length-1||e<0)){var t=e%this.chunkSize,r=e/this.chunkSize|0;return this.getter(r)[t]}},o.prototype.setDataGetter=function(e){this.getter=e},o.prototype.cacheLength=function(){var e=new XMLHttpRequest;if(e.open("HEAD",r,!1),e.send(null),!(e.status>=200&&e.status<300||304===e.status))throw new Error("Couldn't load "+r+". Status: "+e.status);var t,A=Number(e.getResponseHeader("Content-length")),n=(t=e.getResponseHeader("Accept-Ranges"))&&"bytes"===t,o=(t=e.getResponseHeader("Content-Encoding"))&&"gzip"===t,i=1048576;n||(i=A);var s=this;s.setDataGetter((function(e){var t=e*i,n=(e+1)*i-1;if(n=Math.min(n,A-1),void 0===s.chunks[e]&&(s.chunks[e]=function(e,t){if(e>t)throw new Error("invalid range ("+e+", "+t+") or no bytes requested!");if(t>A-1)throw new Error("only "+A+" bytes available! programmer error!");var n=new XMLHttpRequest;if(n.open("GET",r,!1),A!==i&&n.setRequestHeader("Range","bytes="+e+"-"+t),"undefined"!=typeof Uint8Array&&(n.responseType="arraybuffer"),n.overrideMimeType&&n.overrideMimeType("text/plain; charset=x-user-defined"),n.send(null),!(n.status>=200&&n.status<300||304===n.status))throw new Error("Couldn't load "+r+". Status: "+n.status);return void 0!==n.response?new Uint8Array(n.response||[]):we(n.responseText||"",!0)}(t,n)),void 0===s.chunks[e])throw new Error("doXHR failed!");return s.chunks[e]})),!o&&A||(i=A=1,A=this.getter(0).length,i=A,h("LazyFiles on gzip forces download of the whole file when length is accessed")),this._length=A,this._chunkSize=i,this.lengthKnown=!0},"undefined"!=typeof XMLHttpRequest)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var i={isDevice:!1,url:r},s=pe.createFile(e,t,i,A,n);i.contents?s.contents=i.contents:i.url&&(s.contents=null,s.url=i.url),Object.defineProperties(s,{usedBytes:{get:function(){return this.contents.length}}});var a={};return Object.keys(s.stream_ops).forEach((function(e){var t=s.stream_ops[e];a[e]=function(){if(!pe.forceLoadFile(s))throw new pe.ErrnoError(29);return t.apply(null,arguments)}})),a.read=function(e,t,r,A,n){if(!pe.forceLoadFile(s))throw new pe.ErrnoError(29);var o=e.node.contents;if(n>=o.length)return 0;var i=Math.min(o.length-n,A);if(o.slice)for(var a=0;a>2]=A.dev,M[r+4>>2]=0,M[r+8>>2]=A.ino,M[r+12>>2]=A.mode,M[r+16>>2]=A.nlink,M[r+20>>2]=A.uid,M[r+24>>2]=A.gid,M[r+28>>2]=A.rdev,M[r+32>>2]=0,te=[A.size>>>0,(ee=A.size,+Y(ee)>=1?ee>0?(0|J(+H(ee/4294967296),4294967295))>>>0:~~+G((ee-+(~~ee>>>0))/4294967296)>>>0:0)],M[r+40>>2]=te[0],M[r+44>>2]=te[1],M[r+48>>2]=4096,M[r+52>>2]=A.blocks,M[r+56>>2]=A.atime.getTime()/1e3|0,M[r+60>>2]=0,M[r+64>>2]=A.mtime.getTime()/1e3|0,M[r+68>>2]=0,M[r+72>>2]=A.ctime.getTime()/1e3|0,M[r+76>>2]=0,te=[A.ino>>>0,(ee=A.ino,+Y(ee)>=1?ee>0?(0|J(+H(ee/4294967296),4294967295))>>>0:~~+G((ee-+(~~ee>>>0))/4294967296)>>>0:0)],M[r+80>>2]=te[0],M[r+84>>2]=te[1],0},doMsync:function(e,t,r,A,n){var o=F.slice(e,e+r);pe.msync(t,o,n,r,A)},doMkdir:function(e,t){return"/"===(e=ie.normalize(e))[e.length-1]&&(e=e.substr(0,e.length-1)),pe.mkdir(e,t,0),0},doMknod:function(e,t,r){switch(61440&t){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}return pe.mknod(e,t,r),0},doReadlink:function(e,t,r){if(r<=0)return-28;var A=pe.readlink(e),n=Math.min(r,v(A)),o=N[t+n];return b(A,t,r+1),N[t+n]=o,n},doAccess:function(e,t){if(-8&t)return-28;var r;if(!(r=pe.lookupPath(e,{follow:!0}).node))return-44;var A="";return 4&t&&(A+="r"),2&t&&(A+="w"),1&t&&(A+="x"),A&&pe.nodePermissions(r,A)?-2:0},doDup:function(e,t,r){var A=pe.getStream(r);return A&&pe.close(A),pe.open(e,t,0,r,r).fd},doReadv:function(e,t,r,A){for(var n=0,o=0;o>2],s=M[t+(8*o+4)>>2],a=pe.read(e,N,i,s,A);if(a<0)return-1;if(n+=a,a>2],s=M[t+(8*o+4)>>2],a=pe.write(e,N,i,s,A);if(a<0)return-1;n+=a}return n},varargs:void 0,get:function(){return de.varargs+=4,M[de.varargs-4>>2]},getStr:function(e){return Q(e)},getStreamFromFD:function(e){var t=pe.getStream(e);if(!t)throw new pe.ErrnoError(8);return t},get64:function(e,t){return e}};function Ce(e){try{return C.grow(e-k.byteLength+65535>>>16),L(C.buffer),1}catch(e){}}var fe=function(e,t,r,A){e||(e=this),this.parent=e,this.mount=e.mount,this.mounted=null,this.id=pe.nextInode++,this.name=t,this.mode=r,this.node_ops={},this.stream_ops={},this.rdev=A};Object.defineProperties(fe.prototype,{read:{get:function(){return 365==(365&this.mode)},set:function(e){e?this.mode|=365:this.mode&=-366}},write:{get:function(){return 146==(146&this.mode)},set:function(e){e?this.mode|=146:this.mode&=-147}},isFolder:{get:function(){return pe.isDir(this.mode)}},isDevice:{get:function(){return pe.isChrdev(this.mode)}}}),pe.FSNode=fe,pe.staticInit();var Ie=n,Ee=r(85622);ue.staticInit();var Be=function(e){return function(){try{return e.apply(this,arguments)}catch(e){if(!e.code)throw e;throw new pe.ErrnoError(le[e.code])}}},ye=Object.assign({},pe);for(var me in he)pe[me]=Be(he[me]);function we(e,t,r){var A=r>0?r:v(e)+1,n=new Array(A),o=D(e,n,0,n.length);return t&&(n.length=o),n}"function"==typeof atob&&atob;function Qe(e){if(Z(e))return function(e){var t;try{t=Buffer.from(e,"base64")}catch(r){t=new Buffer(e,"base64")}return new Uint8Array(t.buffer,t.byteOffset,t.byteLength)}(e.slice("data:application/octet-stream;base64,".length))}var De,be={m:function(e,t){return oe(e,t)},b:f,r:function(e,t){try{return e=de.getStr(e),pe.chmod(e,t),0}catch(e){return void 0!==pe&&e instanceof pe.ErrnoError||_(e),-e.errno}},g:function(e,t,r){de.varargs=r;try{var A=de.getStreamFromFD(e);switch(t){case 0:return(n=de.get())<0?-28:pe.open(A.path,A.flags,0,n).fd;case 1:case 2:return 0;case 3:return A.flags;case 4:var n=de.get();return A.flags|=n,0;case 12:n=de.get();return K[n+0>>1]=2,0;case 13:case 14:return 0;case 16:case 8:return-28;case 9:return se(28),-1;default:return-28}}catch(e){return void 0!==pe&&e instanceof pe.ErrnoError||_(e),-e.errno}},l:function(e,t){try{var r=de.getStreamFromFD(e);return de.doStat(pe.stat,r.path,t)}catch(e){return void 0!==pe&&e instanceof pe.ErrnoError||_(e),-e.errno}},q:function(e,t,r){de.varargs=r;try{var A=de.getStreamFromFD(e);switch(t){case 21509:case 21505:return A.tty?0:-59;case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:return A.tty?0:-59;case 21519:if(!A.tty)return-59;var n=de.get();return M[n>>2]=0,0;case 21520:return A.tty?-28:-59;case 21531:n=de.get();return pe.ioctl(A,t,n);case 21523:case 21524:return A.tty?0:-59;default:_("bad ioctl syscall "+t)}}catch(e){return void 0!==pe&&e instanceof pe.ErrnoError||_(e),-e.errno}},t:function(e,t,r){de.varargs=r;try{var A=de.getStr(e),n=de.get();return pe.open(A,t,n).fd}catch(e){return void 0!==pe&&e instanceof pe.ErrnoError||_(e),-e.errno}},s:function(e,t,r){try{var A=de.getStreamFromFD(e);return pe.read(A,N,t,r)}catch(e){return void 0!==pe&&e instanceof pe.ErrnoError||_(e),-e.errno}},j:function(e,t){try{return e=de.getStr(e),t=de.getStr(t),pe.rename(e,t),0}catch(e){return void 0!==pe&&e instanceof pe.ErrnoError||_(e),-e.errno}},u:function(e){try{return e=de.getStr(e),pe.rmdir(e),0}catch(e){return void 0!==pe&&e instanceof pe.ErrnoError||_(e),-e.errno}},e:function(e,t){try{return e=de.getStr(e),de.doStat(pe.stat,e,t)}catch(e){return void 0!==pe&&e instanceof pe.ErrnoError||_(e),-e.errno}},i:function(e){try{return e=de.getStr(e),pe.unlink(e),0}catch(e){return void 0!==pe&&e instanceof pe.ErrnoError||_(e),-e.errno}},v:function(e,t,r){F.copyWithin(e,t,t+r)},w:function(e){e>>>=0;var t=F.length;if(e>2147483648)return!1;for(var r,A,n=1;n<=4;n*=2){var o=t*(1+.2/n);if(o=Math.min(o,e+100663296),Ce(Math.min(2147483648,((r=Math.max(16777216,e,o))%(A=65536)>0&&(r+=A-r%A),r))))return!0}return!1},h:function(e){try{var t=de.getStreamFromFD(e);return pe.close(t),0}catch(e){return void 0!==pe&&e instanceof pe.ErrnoError||_(e),e.errno}},k:function(e,t){try{var r=de.getStreamFromFD(e),A=r.tty?2:pe.isDir(r.mode)?3:pe.isLink(r.mode)?7:4;return N[t>>0]=A,0}catch(e){return void 0!==pe&&e instanceof pe.ErrnoError||_(e),e.errno}},p:function(e,t,r,A){try{var n=de.getStreamFromFD(e),o=de.doReadv(n,t,r);return M[A>>2]=o,0}catch(e){return void 0!==pe&&e instanceof pe.ErrnoError||_(e),e.errno}},n:function(e,t,r,A,n){try{var o=de.getStreamFromFD(e),i=4294967296*r+(t>>>0);return i<=-9007199254740992||i>=9007199254740992?-61:(pe.llseek(o,i,A),te=[o.position>>>0,(ee=o.position,+Y(ee)>=1?ee>0?(0|J(+H(ee/4294967296),4294967295))>>>0:~~+G((ee-+(~~ee>>>0))/4294967296)>>>0:0)],M[n>>2]=te[0],M[n+4>>2]=te[1],o.getdents&&0===i&&0===A&&(o.getdents=null),0)}catch(e){return void 0!==pe&&e instanceof pe.ErrnoError||_(e),e.errno}},f:function(e,t,r,A){try{var n=de.getStreamFromFD(e),o=de.doWritev(n,t,r);return M[A>>2]=o,0}catch(e){return void 0!==pe&&e instanceof pe.ErrnoError||_(e),e.errno}},a:C,c:function(e){0|e},d:function(e){var t=Date.now()/1e3|0;return e&&(M[e>>2]=t),t},o:function(e){!function e(){if(!e.called){e.called=!0,M[Ke()>>2]=60*(new Date).getTimezoneOffset();var t=(new Date).getFullYear(),r=new Date(t,0,1),A=new Date(t,6,1);M[Fe()>>2]=Number(r.getTimezoneOffset()!=A.getTimezoneOffset());var n=a(r),o=a(A),i=S(n),s=S(o);A.getTimezoneOffset()>2]=i,M[Ne()+4>>2]=s):(M[Ne()>>2]=s,M[Ne()+4>>2]=i)}function a(e){var t=e.toTimeString().match(/\(([A-Za-z ]+)\)$/);return t?t[1]:"GMT"}}();var t=Date.UTC(M[e+20>>2]+1900,M[e+16>>2],M[e+12>>2],M[e+8>>2],M[e+4>>2],M[e>>2],0),r=new Date(t);M[e+24>>2]=r.getUTCDay();var A=Date.UTC(r.getUTCFullYear(),0,1,0,0,0,0),n=(r.getTime()-A)/864e5|0;return M[e+28>>2]=n,r.getTime()/1e3|0}},ve=function(){var e={a:be};function t(e,t){var r=e.exports;o.asm=r,X()}if(V(),o.instantiateWasm)try{return o.instantiateWasm(e,t)}catch(e){return p("Module.instantiateWasm callback failed with error: "+e),!1}return function(){var r,A,n;try{n=function(){try{if(d)return new Uint8Array(d);var e=Qe(re);if(e)return e;if(a)return a(re);throw"sync fetching of the wasm failed: you can preload it to Module['wasmBinary'] manually, or emcc.py will do that for you when generating HTML (but not JS)"}catch(e){_(e)}}(),A=new WebAssembly.Module(n),r=new WebAssembly.Instance(A,e)}catch(e){var o=e.toString();throw p("failed to compile wasm module: "+o),(o.indexOf("imported Memory")>=0||o.indexOf("memory import")>=0)&&p("Memory size incompatibility issues may be due to changing INITIAL_MEMORY at runtime to something too large. Use ALLOW_MEMORY_GROWTH to allow any size memory (and also make sure not to set INITIAL_MEMORY at runtime to something smaller than it was at compile time)."),e}t(r)}(),o.asm}(),Se=o.___wasm_call_ctors=ve.x,ke=(o._zipstruct_stat=ve.y,o._zipstruct_statS=ve.z,o._zipstruct_stat_name=ve.A,o._zipstruct_stat_index=ve.B,o._zipstruct_stat_size=ve.C,o._zipstruct_stat_mtime=ve.D,o._zipstruct_error=ve.E,o._zipstruct_errorS=ve.F,o._zipstruct_error_code_zip=ve.G,o._zipstruct_stat_comp_size=ve.H,o._zipstruct_stat_comp_method=ve.I,o._zip_close=ve.J,o._zip_delete=ve.K,o._zip_dir_add=ve.L,o._zip_discard=ve.M,o._zip_error_init_with_code=ve.N,o._zip_get_error=ve.O,o._zip_file_get_error=ve.P,o._zip_error_strerror=ve.Q,o._zip_fclose=ve.R,o._zip_file_add=ve.S,o._zip_file_get_external_attributes=ve.T,o._zip_file_set_external_attributes=ve.U,o._zip_file_set_mtime=ve.V,o._zip_fopen=ve.W,o._zip_fopen_index=ve.X,o._zip_fread=ve.Y,o._zip_get_name=ve.Z,o._zip_get_num_entries=ve._,o._zip_name_locate=ve.$,o._zip_open=ve.aa,o._zip_open_from_source=ve.ba,o._zip_set_file_compression=ve.ca,o._zip_source_buffer=ve.da,o._zip_source_buffer_create=ve.ea,o._zip_source_close=ve.fa,o._zip_source_error=ve.ga,o._zip_source_free=ve.ha,o._zip_source_keep=ve.ia,o._zip_source_open=ve.ja,o._zip_source_read=ve.ka,o._zip_source_seek=ve.la,o._zip_source_set_mtime=ve.ma,o._zip_source_tell=ve.na,o._zip_stat=ve.oa,o._zip_stat_index=ve.pa,o._zip_ext_count_symlinks=ve.qa,o.___errno_location=ve.ra),Ne=o.__get_tzname=ve.sa,Fe=o.__get_daylight=ve.ta,Ke=o.__get_timezone=ve.ua,Me=o.stackSave=ve.va,Re=o.stackRestore=ve.wa,xe=o.stackAlloc=ve.xa,Le=o._malloc=ve.ya;o._free=ve.za;function Pe(e){function t(){De||(De=!0,o.calledRun=!0,I||(!0,o.noFSInit||pe.init.initialized||pe.init(),ce.init(),Ae(U),pe.ignorePermissions=!1,Ae(T),o.onRuntimeInitialized&&o.onRuntimeInitialized(),function(){if(o.postRun)for("function"==typeof o.postRun&&(o.postRun=[o.postRun]);o.postRun.length;)e=o.postRun.shift(),j.unshift(e);var e;Ae(j)}()))}e=e||l,q>0||(!function(){if(o.preRun)for("function"==typeof o.preRun&&(o.preRun=[o.preRun]);o.preRun.length;)e=o.preRun.shift(),O.unshift(e);var e;Ae(O)}(),q>0||(o.setStatus?(o.setStatus("Running..."),setTimeout((function(){setTimeout((function(){o.setStatus("")}),1),t()}),1)):t()))}if(o.cwrap=function(e,t,r,A){var n=(r=r||[]).every((function(e){return"number"===e}));return"string"!==t&&n&&!A?B(e):function(){return y(e,t,r,arguments)}},o.getValue=function(e,t,r){switch("*"===(t=t||"i8").charAt(t.length-1)&&(t="i32"),t){case"i1":case"i8":return N[e>>0];case"i16":return K[e>>1];case"i32":case"i64":return M[e>>2];case"float":return R[e>>2];case"double":return x[e>>3];default:_("invalid type for getValue: "+t)}return null},W=function e(){De||Pe(),De||(W=e)},o.run=Pe,o.preInit)for("function"==typeof o.preInit&&(o.preInit=[o.preInit]);o.preInit.length>0;)o.preInit.pop()();Pe()},98261:e=>{"use strict";function t(e,r,A,n){this.message=e,this.expected=r,this.found=A,this.location=n,this.name="SyntaxError","function"==typeof Error.captureStackTrace&&Error.captureStackTrace(this,t)}!function(e,t){function r(){this.constructor=e}r.prototype=t.prototype,e.prototype=new r}(t,Error),t.buildMessage=function(e,t){var r={literal:function(e){return`"${n(e.text)}"`},class:function(e){var t,r="";for(t=0;t0){for(t=1,A=1;tf&&(f=p,I=[]),I.push(e))}function Q(e,r,A){return new t(t.buildMessage(e,r),e,r,A)}function D(){var t,r,A,o;return t=p,(r=b())!==n?(47===e.charCodeAt(p)?(A="/",p++):(A=n,w(s)),A!==n&&(o=b())!==n?(d=t,t=r={from:r,descriptor:o}):(p=t,t=n)):(p=t,t=n),t===n&&(t=p,(r=b())!==n&&(d=t,r=function(e){return{descriptor:e}}(r)),t=r),t}function b(){var t,r,A,o;return t=p,(r=v())!==n?(64===e.charCodeAt(p)?(A="@",p++):(A=n,w(a)),A!==n&&(o=function(){var t,r,A;t=p,r=[],u.test(e.charAt(p))?(A=e.charAt(p),p++):(A=n,w(h));if(A!==n)for(;A!==n;)r.push(A),u.test(e.charAt(p))?(A=e.charAt(p),p++):(A=n,w(h));else r=n;r!==n&&(d=t,r=c());return t=r}())!==n?(d=t,t=r={fullName:r,description:o}):(p=t,t=n)):(p=t,t=n),t===n&&(t=p,(r=v())!==n&&(d=t,r=function(e){return{fullName:e}}(r)),t=r),t}function v(){var t,r,A;return t=p,64===e.charCodeAt(p)?(r="@",p++):(r=n,w(a)),r!==n&&S()!==n?(47===e.charCodeAt(p)?(A="/",p++):(A=n,w(s)),A!==n&&S()!==n?(d=t,t=r=c()):(p=t,t=n)):(p=t,t=n),t===n&&(t=p,(r=S())!==n&&(d=t,r=c()),t=r),t}function S(){var t,r,A;if(t=p,r=[],g.test(e.charAt(p))?(A=e.charAt(p),p++):(A=n,w(l)),A!==n)for(;A!==n;)r.push(A),g.test(e.charAt(p))?(A=e.charAt(p),p++):(A=n,w(l));else r=n;return r!==n&&(d=t,r=c()),t=r}if((A=i())!==n&&p===e.length)return A;throw A!==n&&p{"use strict";function t(e,r,A,n){this.message=e,this.expected=r,this.found=A,this.location=n,this.name="SyntaxError","function"==typeof Error.captureStackTrace&&Error.captureStackTrace(this,t)}!function(e,t){function r(){this.constructor=e}r.prototype=t.prototype,e.prototype=new r}(t,Error),t.buildMessage=function(e,t){var r={literal:function(e){return'"'+n(e.text)+'"'},class:function(e){var t,r="";for(t=0;t0){for(t=1,A=1;t>",!1),I=le(">&",!1),E=le(">",!1),B=le("<<<",!1),y=le("<&",!1),m=le("<",!1),w=le("'",!1),Q=le('"',!1),D=function(e){return{type:"text",text:e}},b=le("\\",!1),v={type:"any"},S=/^[^']/,k=ue(["'"],!0,!1),N=function(e){return e.join("")},F=/^[^$"]/,K=ue(["$",'"'],!0,!1),M=le("-",!1),R=le("+",!1),x=/^[0-9]/,L=ue([["0","9"]],!1,!1),P=le(".",!1),O=le("*",!1),U=le("/",!1),T=le("$((",!1),j=le("))",!1),Y=le("$(",!1),G=le("${",!1),H=le(":-",!1),J=le(":-}",!1),q=function(e){return{name:e}},z=le("$",!1),W=/^[a-zA-Z0-9_]/,V=ue([["a","z"],["A","Z"],["0","9"],"_"],!1,!1),X=function(){return e.substring(ie,oe)},_=/^[$@*?#a-zA-Z0-9_\-]/,Z=ue(["$","@","*","?","#",["a","z"],["A","Z"],["0","9"],"_","-"],!1,!1),$=/^[(){}<>$|&; \t"']/,ee=ue(["(",")","{","}","<",">","$","|","&",";"," ","\t",'"',"'"],!1,!1),te=/^[<>&; \t"']/,re=ue(["<",">","&",";"," ","\t",'"',"'"],!1,!1),Ae=/^[ \t]/,ne=ue([" ","\t"],!1,!1),oe=0,ie=0,se=[{line:1,column:1}],ae=0,ce=[],ge=0;if("startRule"in r){if(!(r.startRule in o))throw new Error("Can't start parsing from rule \""+r.startRule+'".');i=o[r.startRule]}function le(e,t){return{type:"literal",text:e,ignoreCase:t}}function ue(e,t,r){return{type:"class",parts:e,inverted:t,ignoreCase:r}}function he(t){var r,A=se[t];if(A)return A;for(r=t-1;!se[r];)r--;for(A={line:(A=se[r]).line,column:A.column};rae&&(ae=oe,ce=[]),ce.push(e))}function Ce(e,r,A){return new t(t.buildMessage(e,r),e,r,A)}function fe(){var e,t;return e=oe,(t=Ie())===n&&(t=null),t!==n&&(ie=e,t=t||[]),e=t}function Ie(){var e,t,r,A,o;if(e=oe,(t=Be())!==n){for(r=[],A=Te();A!==n;)r.push(A),A=Te();r!==n&&(A=Ee())!==n?((o=function(){var e,t,r,A,o;e=oe,t=[],r=Te();for(;r!==n;)t.push(r),r=Te();if(t!==n)if((r=Ie())!==n){for(A=[],o=Te();o!==n;)A.push(o),o=Te();A!==n?(ie=e,e=t=r):(oe=e,e=n)}else oe=e,e=n;else oe=e,e=n;return e}())===n&&(o=null),o!==n?(ie=e,e=t=[t].concat(o||[])):(oe=e,e=n)):(oe=e,e=n)}else oe=e,e=n;if(e===n)if(e=oe,(t=Be())!==n){for(r=[],A=Te();A!==n;)r.push(A),A=Te();r!==n?((A=Ee())===n&&(A=null),A!==n?(ie=e,e=t=function(e,t){return[e]}(t)):(oe=e,e=n)):(oe=e,e=n)}else oe=e,e=n;return e}function Ee(){var t;return 59===e.charCodeAt(oe)?(t=";",oe++):(t=n,0===ge&&de(s)),t}function Be(){var t,r,A,o,i;return t=oe,(r=ye())!==n?((A=function(){var t,r,A,o,i,s,g;t=oe,r=[],A=Te();for(;A!==n;)r.push(A),A=Te();if(r!==n)if((A=function(){var t;"&&"===e.substr(oe,2)?(t="&&",oe+=2):(t=n,0===ge&&de(a));t===n&&("||"===e.substr(oe,2)?(t="||",oe+=2):(t=n,0===ge&&de(c)));return t}())!==n){for(o=[],i=Te();i!==n;)o.push(i),i=Te();if(o!==n)if((i=Be())!==n){for(s=[],g=Te();g!==n;)s.push(g),g=Te();s!==n?(ie=t,t=r={type:A,line:i}):(oe=t,t=n)}else oe=t,t=n;else oe=t,t=n}else oe=t,t=n;else oe=t,t=n;return t}())===n&&(A=null),A!==n?(ie=t,o=r,t=r=(i=A)?{chain:o,then:i}:{chain:o}):(oe=t,t=n)):(oe=t,t=n),t}function ye(){var t,r,A,o,i;return t=oe,(r=function(){var t,r,A,o,i,s,a,c,g,l,u;t=oe,r=[],A=Te();for(;A!==n;)r.push(A),A=Te();if(r!==n)if(40===e.charCodeAt(oe)?(A="(",oe++):(A=n,0===ge&&de(h)),A!==n){for(o=[],i=Te();i!==n;)o.push(i),i=Te();if(o!==n)if((i=Ie())!==n){for(s=[],a=Te();a!==n;)s.push(a),a=Te();if(s!==n)if(41===e.charCodeAt(oe)?(a=")",oe++):(a=n,0===ge&&de(p)),a!==n){for(c=[],g=Te();g!==n;)c.push(g),g=Te();if(c!==n){for(g=[],l=Qe();l!==n;)g.push(l),l=Qe();if(g!==n){for(l=[],u=Te();u!==n;)l.push(u),u=Te();l!==n?(ie=t,t=r={type:"subshell",subshell:i,args:g}):(oe=t,t=n)}else oe=t,t=n}else oe=t,t=n}else oe=t,t=n;else oe=t,t=n}else oe=t,t=n;else oe=t,t=n}else oe=t,t=n;else oe=t,t=n;if(t===n){for(t=oe,r=[],A=Te();A!==n;)r.push(A),A=Te();if(r!==n)if(123===e.charCodeAt(oe)?(A="{",oe++):(A=n,0===ge&&de(d)),A!==n){for(o=[],i=Te();i!==n;)o.push(i),i=Te();if(o!==n)if((i=Ie())!==n){for(s=[],a=Te();a!==n;)s.push(a),a=Te();if(s!==n)if(125===e.charCodeAt(oe)?(a="}",oe++):(a=n,0===ge&&de(C)),a!==n){for(c=[],g=Te();g!==n;)c.push(g),g=Te();if(c!==n){for(g=[],l=Qe();l!==n;)g.push(l),l=Qe();if(g!==n){for(l=[],u=Te();u!==n;)l.push(u),u=Te();l!==n?(ie=t,r=function(e,t){return{type:"group",group:e,args:t}}(i,g),t=r):(oe=t,t=n)}else oe=t,t=n}else oe=t,t=n}else oe=t,t=n;else oe=t,t=n}else oe=t,t=n;else oe=t,t=n}else oe=t,t=n;else oe=t,t=n;if(t===n){for(t=oe,r=[],A=Te();A!==n;)r.push(A),A=Te();if(r!==n){for(A=[],o=me();o!==n;)A.push(o),o=me();if(A!==n){for(o=[],i=Te();i!==n;)o.push(i),i=Te();if(o!==n){if(i=[],(s=we())!==n)for(;s!==n;)i.push(s),s=we();else i=n;if(i!==n){for(s=[],a=Te();a!==n;)s.push(a),a=Te();s!==n?(ie=t,r=function(e,t){return{type:"command",args:t,envs:e}}(A,i),t=r):(oe=t,t=n)}else oe=t,t=n}else oe=t,t=n}else oe=t,t=n}else oe=t,t=n;if(t===n){for(t=oe,r=[],A=Te();A!==n;)r.push(A),A=Te();if(r!==n){if(A=[],(o=me())!==n)for(;o!==n;)A.push(o),o=me();else A=n;if(A!==n){for(o=[],i=Te();i!==n;)o.push(i),i=Te();o!==n?(ie=t,t=r={type:"envs",envs:A}):(oe=t,t=n)}else oe=t,t=n}else oe=t,t=n}}}return t}())!==n?((A=function(){var t,r,A,o,i,s,a;t=oe,r=[],A=Te();for(;A!==n;)r.push(A),A=Te();if(r!==n)if((A=function(){var t;"|&"===e.substr(oe,2)?(t="|&",oe+=2):(t=n,0===ge&&de(g));t===n&&(124===e.charCodeAt(oe)?(t="|",oe++):(t=n,0===ge&&de(l)));return t}())!==n){for(o=[],i=Te();i!==n;)o.push(i),i=Te();if(o!==n)if((i=ye())!==n){for(s=[],a=Te();a!==n;)s.push(a),a=Te();s!==n?(ie=t,t=r={type:A,chain:i}):(oe=t,t=n)}else oe=t,t=n;else oe=t,t=n}else oe=t,t=n;else oe=t,t=n;return t}())===n&&(A=null),A!==n?(ie=t,o=r,t=r=(i=A)?{...o,then:i}:o):(oe=t,t=n)):(oe=t,t=n),t}function me(){var t,r,A,o,i,s;if(t=oe,(r=Le())!==n)if(61===e.charCodeAt(oe)?(A="=",oe++):(A=n,0===ge&&de(u)),A!==n)if((o=be())!==n){for(i=[],s=Te();s!==n;)i.push(s),s=Te();i!==n?(ie=t,t=r={name:r,args:[o]}):(oe=t,t=n)}else oe=t,t=n;else oe=t,t=n;else oe=t,t=n;if(t===n)if(t=oe,(r=Le())!==n)if(61===e.charCodeAt(oe)?(A="=",oe++):(A=n,0===ge&&de(u)),A!==n){for(o=[],i=Te();i!==n;)o.push(i),i=Te();o!==n?(ie=t,t=r=function(e){return{name:e,args:[]}}(r)):(oe=t,t=n)}else oe=t,t=n;else oe=t,t=n;return t}function we(){var e,t,r;for(e=oe,t=[],r=Te();r!==n;)t.push(r),r=Te();if(t!==n&&(r=Qe())!==n?(ie=e,e=t=r):(oe=e,e=n),e===n){for(e=oe,t=[],r=Te();r!==n;)t.push(r),r=Te();t!==n&&(r=De())!==n?(ie=e,e=t=r):(oe=e,e=n)}return e}function Qe(){var t,r,A,o;for(t=oe,r=[],A=Te();A!==n;)r.push(A),A=Te();return r!==n&&(A=function(){var t;">>"===e.substr(oe,2)?(t=">>",oe+=2):(t=n,0===ge&&de(f));t===n&&(">&"===e.substr(oe,2)?(t=">&",oe+=2):(t=n,0===ge&&de(I)),t===n&&(62===e.charCodeAt(oe)?(t=">",oe++):(t=n,0===ge&&de(E)),t===n&&("<<<"===e.substr(oe,3)?(t="<<<",oe+=3):(t=n,0===ge&&de(B)),t===n&&("<&"===e.substr(oe,2)?(t="<&",oe+=2):(t=n,0===ge&&de(y)),t===n&&(60===e.charCodeAt(oe)?(t="<",oe++):(t=n,0===ge&&de(m)))))));return t}())!==n&&(o=De())!==n?(ie=t,t=r={type:"redirection",subtype:A,args:[o]}):(oe=t,t=n),t}function De(){var e,t,r;for(e=oe,t=[],r=Te();r!==n;)t.push(r),r=Te();return t!==n&&(r=be())!==n?(ie=e,e=t=r):(oe=e,e=n),e}function be(){var e,t,r,A;if(e=oe,t=[],(r=ve())!==n)for(;r!==n;)t.push(r),r=ve();else t=n;return t!==n&&(ie=e,A=t,t={type:"argument",segments:[].concat(...A)}),e=t}function ve(){var t,r;return t=oe,(r=function(){var t,r,A,o;t=oe,39===e.charCodeAt(oe)?(r="'",oe++):(r=n,0===ge&&de(w));r!==n&&(A=function(){var t,r,A,o,i;t=oe,r=[],A=oe,92===e.charCodeAt(oe)?(o="\\",oe++):(o=n,0===ge&&de(b));o!==n?(e.length>oe?(i=e.charAt(oe),oe++):(i=n,0===ge&&de(v)),i!==n?(ie=A,A=o=i):(oe=A,A=n)):(oe=A,A=n);A===n&&(S.test(e.charAt(oe))?(A=e.charAt(oe),oe++):(A=n,0===ge&&de(k)));for(;A!==n;)r.push(A),A=oe,92===e.charCodeAt(oe)?(o="\\",oe++):(o=n,0===ge&&de(b)),o!==n?(e.length>oe?(i=e.charAt(oe),oe++):(i=n,0===ge&&de(v)),i!==n?(ie=A,A=o=i):(oe=A,A=n)):(oe=A,A=n),A===n&&(S.test(e.charAt(oe))?(A=e.charAt(oe),oe++):(A=n,0===ge&&de(k)));r!==n&&(ie=t,r=N(r));return t=r}())!==n?(39===e.charCodeAt(oe)?(o="'",oe++):(o=n,0===ge&&de(w)),o!==n?(ie=t,r=function(e){return[{type:"text",text:e}]}(A),t=r):(oe=t,t=n)):(oe=t,t=n);return t}())!==n&&(ie=t,r=r),(t=r)===n&&(t=oe,(r=function(){var t,r,A,o;t=oe,34===e.charCodeAt(oe)?(r='"',oe++):(r=n,0===ge&&de(Q));if(r!==n){for(A=[],o=Se();o!==n;)A.push(o),o=Se();A!==n?(34===e.charCodeAt(oe)?(o='"',oe++):(o=n,0===ge&&de(Q)),o!==n?(ie=t,t=r=A):(oe=t,t=n)):(oe=t,t=n)}else oe=t,t=n;return t}())!==n&&(ie=t,r=r),(t=r)===n&&(t=oe,(r=function(){var e,t,r;if(e=oe,t=[],(r=ke())!==n)for(;r!==n;)t.push(r),r=ke();else t=n;t!==n&&(ie=e,t=t);return e=t}())!==n&&(ie=t,r=r),t=r)),t}function Se(){var t,r,A;return t=oe,(r=Me())!==n&&(ie=t,r={type:"arithmetic",arithmetic:r,quoted:!0}),(t=r)===n&&(t=oe,(r=Re())!==n&&(ie=t,r={type:"shell",shell:r,quoted:!0}),(t=r)===n&&(t=oe,(r=xe())!==n&&(ie=t,A=r,r={type:"variable",...A,quoted:!0}),(t=r)===n&&(t=oe,(r=function(){var t,r,A,o,i;t=oe,r=[],A=oe,92===e.charCodeAt(oe)?(o="\\",oe++):(o=n,0===ge&&de(b));o!==n?(e.length>oe?(i=e.charAt(oe),oe++):(i=n,0===ge&&de(v)),i!==n?(ie=A,A=o=i):(oe=A,A=n)):(oe=A,A=n);A===n&&(F.test(e.charAt(oe))?(A=e.charAt(oe),oe++):(A=n,0===ge&&de(K)));if(A!==n)for(;A!==n;)r.push(A),A=oe,92===e.charCodeAt(oe)?(o="\\",oe++):(o=n,0===ge&&de(b)),o!==n?(e.length>oe?(i=e.charAt(oe),oe++):(i=n,0===ge&&de(v)),i!==n?(ie=A,A=o=i):(oe=A,A=n)):(oe=A,A=n),A===n&&(F.test(e.charAt(oe))?(A=e.charAt(oe),oe++):(A=n,0===ge&&de(K)));else r=n;r!==n&&(ie=t,r=N(r));return t=r}())!==n&&(ie=t,r=D(r)),t=r))),t}function ke(){var t,A,o;return t=oe,(A=Me())!==n&&(ie=t,A={type:"arithmetic",arithmetic:A,quoted:!1}),(t=A)===n&&(t=oe,(A=Re())!==n&&(ie=t,A={type:"shell",shell:A,quoted:!1}),(t=A)===n&&(t=oe,(A=xe())!==n&&(ie=t,o=A,A={type:"variable",...o,quoted:!1}),(t=A)===n&&(t=oe,(A=function(){var t,A;t=oe,(A=function(){var t,r,A,o,i;t=oe,r=[],A=oe,o=oe,ge++,i=Ue(),ge--,i===n?o=void 0:(oe=o,o=n);o!==n?(e.length>oe?(i=e.charAt(oe),oe++):(i=n,0===ge&&de(v)),i!==n?(ie=A,A=o=i):(oe=A,A=n)):(oe=A,A=n);if(A!==n)for(;A!==n;)r.push(A),A=oe,o=oe,ge++,i=Ue(),ge--,i===n?o=void 0:(oe=o,o=n),o!==n?(e.length>oe?(i=e.charAt(oe),oe++):(i=n,0===ge&&de(v)),i!==n?(ie=A,A=o=i):(oe=A,A=n)):(oe=A,A=n);else r=n;r!==n&&(ie=t,r=N(r));return t=r}())!==n?(ie=oe,o=A,(r.isGlobPattern(o)?void 0:n)!==n?(ie=t,t=A=A):(oe=t,t=n)):(oe=t,t=n);var o;return t}())!==n&&(ie=t,A={type:"glob",pattern:A}),(t=A)===n&&(t=oe,(A=function(){var t,r,A,o,i;t=oe,r=[],A=oe,92===e.charCodeAt(oe)?(o="\\",oe++):(o=n,0===ge&&de(b));o!==n?(e.length>oe?(i=e.charAt(oe),oe++):(i=n,0===ge&&de(v)),i!==n?(ie=A,A=o=i):(oe=A,A=n)):(oe=A,A=n);A===n&&(A=oe,o=oe,ge++,i=Oe(),ge--,i===n?o=void 0:(oe=o,o=n),o!==n?(e.length>oe?(i=e.charAt(oe),oe++):(i=n,0===ge&&de(v)),i!==n?(ie=A,A=o=i):(oe=A,A=n)):(oe=A,A=n));if(A!==n)for(;A!==n;)r.push(A),A=oe,92===e.charCodeAt(oe)?(o="\\",oe++):(o=n,0===ge&&de(b)),o!==n?(e.length>oe?(i=e.charAt(oe),oe++):(i=n,0===ge&&de(v)),i!==n?(ie=A,A=o=i):(oe=A,A=n)):(oe=A,A=n),A===n&&(A=oe,o=oe,ge++,i=Oe(),ge--,i===n?o=void 0:(oe=o,o=n),o!==n?(e.length>oe?(i=e.charAt(oe),oe++):(i=n,0===ge&&de(v)),i!==n?(ie=A,A=o=i):(oe=A,A=n)):(oe=A,A=n));else r=n;r!==n&&(ie=t,r=N(r));return t=r}())!==n&&(ie=t,A=D(A)),t=A)))),t}function Ne(){var t,r,A,o,i,s,a,c;if(t=oe,45===e.charCodeAt(oe)?(r="-",oe++):(r=n,0===ge&&de(M)),r===n&&(43===e.charCodeAt(oe)?(r="+",oe++):(r=n,0===ge&&de(R))),r===n&&(r=null),r!==n){if(A=[],x.test(e.charAt(oe))?(o=e.charAt(oe),oe++):(o=n,0===ge&&de(L)),o!==n)for(;o!==n;)A.push(o),x.test(e.charAt(oe))?(o=e.charAt(oe),oe++):(o=n,0===ge&&de(L));else A=n;if(A!==n)if(46===e.charCodeAt(oe)?(o=".",oe++):(o=n,0===ge&&de(P)),o!==n){if(i=[],x.test(e.charAt(oe))?(s=e.charAt(oe),oe++):(s=n,0===ge&&de(L)),s!==n)for(;s!==n;)i.push(s),x.test(e.charAt(oe))?(s=e.charAt(oe),oe++):(s=n,0===ge&&de(L));else i=n;i!==n?(ie=t,a=i,t=r={type:"number",value:("-"===r?-1:1)*parseFloat(A.join("")+"."+a.join(""))}):(oe=t,t=n)}else oe=t,t=n;else oe=t,t=n}else oe=t,t=n;if(t===n){if(t=oe,45===e.charCodeAt(oe)?(r="-",oe++):(r=n,0===ge&&de(M)),r===n&&(43===e.charCodeAt(oe)?(r="+",oe++):(r=n,0===ge&&de(R))),r===n&&(r=null),r!==n){if(A=[],x.test(e.charAt(oe))?(o=e.charAt(oe),oe++):(o=n,0===ge&&de(L)),o!==n)for(;o!==n;)A.push(o),x.test(e.charAt(oe))?(o=e.charAt(oe),oe++):(o=n,0===ge&&de(L));else A=n;A!==n?(ie=t,t=r=function(e,t){return{type:"number",value:("-"===e?-1:1)*parseInt(t.join(""))}}(r,A)):(oe=t,t=n)}else oe=t,t=n;if(t===n&&(t=oe,(r=xe())!==n&&(ie=t,c=r,r={type:"variable",...c}),(t=r)===n&&(t=oe,(r=Pe())!==n&&(ie=t,r={type:"variable",name:r}),(t=r)===n)))if(t=oe,40===e.charCodeAt(oe)?(r="(",oe++):(r=n,0===ge&&de(h)),r!==n){for(A=[],o=Te();o!==n;)A.push(o),o=Te();if(A!==n)if((o=Ke())!==n){for(i=[],s=Te();s!==n;)i.push(s),s=Te();i!==n?(41===e.charCodeAt(oe)?(s=")",oe++):(s=n,0===ge&&de(p)),s!==n?(ie=t,t=r=o):(oe=t,t=n)):(oe=t,t=n)}else oe=t,t=n;else oe=t,t=n}else oe=t,t=n}return t}function Fe(){var t,r,A,o,i,s;if(t=oe,(r=Ne())!==n){for(A=[],o=Te();o!==n;)A.push(o),o=Te();if(A!==n)if(42===e.charCodeAt(oe)?(o="*",oe++):(o=n,0===ge&&de(O)),o!==n){for(i=[],s=Te();s!==n;)i.push(s),s=Te();i!==n&&(s=Fe())!==n?(ie=t,t=r={type:"multiplication",left:r,right:s}):(oe=t,t=n)}else oe=t,t=n;else oe=t,t=n}else oe=t,t=n;if(t===n){if(t=oe,(r=Ne())!==n){for(A=[],o=Te();o!==n;)A.push(o),o=Te();if(A!==n)if(47===e.charCodeAt(oe)?(o="/",oe++):(o=n,0===ge&&de(U)),o!==n){for(i=[],s=Te();s!==n;)i.push(s),s=Te();i!==n&&(s=Fe())!==n?(ie=t,t=r=function(e,t){return{type:"division",left:e,right:t}}(r,s)):(oe=t,t=n)}else oe=t,t=n;else oe=t,t=n}else oe=t,t=n;t===n&&(t=Ne())}return t}function Ke(){var t,r,A,o,i,s;if(t=oe,(r=Fe())!==n){for(A=[],o=Te();o!==n;)A.push(o),o=Te();if(A!==n)if(43===e.charCodeAt(oe)?(o="+",oe++):(o=n,0===ge&&de(R)),o!==n){for(i=[],s=Te();s!==n;)i.push(s),s=Te();i!==n&&(s=Ke())!==n?(ie=t,t=r={type:"addition",left:r,right:s}):(oe=t,t=n)}else oe=t,t=n;else oe=t,t=n}else oe=t,t=n;if(t===n){if(t=oe,(r=Fe())!==n){for(A=[],o=Te();o!==n;)A.push(o),o=Te();if(A!==n)if(45===e.charCodeAt(oe)?(o="-",oe++):(o=n,0===ge&&de(M)),o!==n){for(i=[],s=Te();s!==n;)i.push(s),s=Te();i!==n&&(s=Ke())!==n?(ie=t,t=r=function(e,t){return{type:"subtraction",left:e,right:t}}(r,s)):(oe=t,t=n)}else oe=t,t=n;else oe=t,t=n}else oe=t,t=n;t===n&&(t=Fe())}return t}function Me(){var t,r,A,o,i,s;if(t=oe,"$(("===e.substr(oe,3)?(r="$((",oe+=3):(r=n,0===ge&&de(T)),r!==n){for(A=[],o=Te();o!==n;)A.push(o),o=Te();if(A!==n)if((o=Ke())!==n){for(i=[],s=Te();s!==n;)i.push(s),s=Te();i!==n?("))"===e.substr(oe,2)?(s="))",oe+=2):(s=n,0===ge&&de(j)),s!==n?(ie=t,t=r=o):(oe=t,t=n)):(oe=t,t=n)}else oe=t,t=n;else oe=t,t=n}else oe=t,t=n;return t}function Re(){var t,r,A,o;return t=oe,"$("===e.substr(oe,2)?(r="$(",oe+=2):(r=n,0===ge&&de(Y)),r!==n&&(A=Ie())!==n?(41===e.charCodeAt(oe)?(o=")",oe++):(o=n,0===ge&&de(p)),o!==n?(ie=t,t=r=A):(oe=t,t=n)):(oe=t,t=n),t}function xe(){var t,r,A,o,i,s;return t=oe,"${"===e.substr(oe,2)?(r="${",oe+=2):(r=n,0===ge&&de(G)),r!==n&&(A=Pe())!==n?(":-"===e.substr(oe,2)?(o=":-",oe+=2):(o=n,0===ge&&de(H)),o!==n&&(i=function(){var e,t,r,A,o;for(e=oe,t=[],r=Te();r!==n;)t.push(r),r=Te();if(t!==n){if(r=[],(A=De())!==n)for(;A!==n;)r.push(A),A=De();else r=n;if(r!==n){for(A=[],o=Te();o!==n;)A.push(o),o=Te();A!==n?(ie=e,e=t=r):(oe=e,e=n)}else oe=e,e=n}else oe=e,e=n;return e}())!==n?(125===e.charCodeAt(oe)?(s="}",oe++):(s=n,0===ge&&de(C)),s!==n?(ie=t,t=r={name:A,defaultValue:i}):(oe=t,t=n)):(oe=t,t=n)):(oe=t,t=n),t===n&&(t=oe,"${"===e.substr(oe,2)?(r="${",oe+=2):(r=n,0===ge&&de(G)),r!==n&&(A=Pe())!==n?(":-}"===e.substr(oe,3)?(o=":-}",oe+=3):(o=n,0===ge&&de(J)),o!==n?(ie=t,t=r=function(e){return{name:e,defaultValue:[]}}(A)):(oe=t,t=n)):(oe=t,t=n),t===n&&(t=oe,"${"===e.substr(oe,2)?(r="${",oe+=2):(r=n,0===ge&&de(G)),r!==n&&(A=Pe())!==n?(125===e.charCodeAt(oe)?(o="}",oe++):(o=n,0===ge&&de(C)),o!==n?(ie=t,t=r=q(A)):(oe=t,t=n)):(oe=t,t=n),t===n&&(t=oe,36===e.charCodeAt(oe)?(r="$",oe++):(r=n,0===ge&&de(z)),r!==n&&(A=Pe())!==n?(ie=t,t=r=q(A)):(oe=t,t=n)))),t}function Le(){var t,r,A;if(t=oe,r=[],W.test(e.charAt(oe))?(A=e.charAt(oe),oe++):(A=n,0===ge&&de(V)),A!==n)for(;A!==n;)r.push(A),W.test(e.charAt(oe))?(A=e.charAt(oe),oe++):(A=n,0===ge&&de(V));else r=n;return r!==n&&(ie=t,r=X()),t=r}function Pe(){var t,r,A;if(t=oe,r=[],_.test(e.charAt(oe))?(A=e.charAt(oe),oe++):(A=n,0===ge&&de(Z)),A!==n)for(;A!==n;)r.push(A),_.test(e.charAt(oe))?(A=e.charAt(oe),oe++):(A=n,0===ge&&de(Z));else r=n;return r!==n&&(ie=t,r=X()),t=r}function Oe(){var t;return $.test(e.charAt(oe))?(t=e.charAt(oe),oe++):(t=n,0===ge&&de(ee)),t}function Ue(){var t;return te.test(e.charAt(oe))?(t=e.charAt(oe),oe++):(t=n,0===ge&&de(re)),t}function Te(){var t,r;if(t=[],Ae.test(e.charAt(oe))?(r=e.charAt(oe),oe++):(r=n,0===ge&&de(ne)),r!==n)for(;r!==n;)t.push(r),Ae.test(e.charAt(oe))?(r=e.charAt(oe),oe++):(r=n,0===ge&&de(ne));else t=n;return t}if((A=i())!==n&&oe===e.length)return A;throw A!==n&&oe{"use strict";function t(e,r,A,n){this.message=e,this.expected=r,this.found=A,this.location=n,this.name="SyntaxError","function"==typeof Error.captureStackTrace&&Error.captureStackTrace(this,t)}!function(e,t){function r(){this.constructor=e}r.prototype=t.prototype,e.prototype=new r}(t,Error),t.buildMessage=function(e,t){var r={literal:function(e){return`"${n(e.text)}"`},class:function(e){var t,r="";for(t=0;t0){for(t=1,A=1;t'"%@`\-]/,I=oe(["\r","\n","\t"," ","?",":",",","]","[","{","}","#","&","*","!","|",">","'",'"',"%","@","`","-"],!0,!1),E=/^[^\r\n\t ,\][{}:#"']/,B=oe(["\r","\n","\t"," ",",","]","[","{","}",":","#",'"',"'"],!0,!1),y=function(){return Ae().replace(/^ *| *$/g,"")},m=ne("--",!1),w=/^[a-zA-Z\/0-9]/,Q=oe([["a","z"],["A","Z"],"/",["0","9"]],!1,!1),D=/^[^\r\n\t :,]/,b=oe(["\r","\n","\t"," ",":",","],!0,!1),v=ne("null",!1),S=ne("true",!1),k=ne("false",!1),N=ie("string"),F=ne('"',!1),K=/^[^"\\\0-\x1F\x7F]/,M=oe(['"',"\\",["\0",""],""],!0,!1),R=ne('\\"',!1),x=ne("\\\\",!1),L=ne("\\/",!1),P=ne("\\b",!1),O=ne("\\f",!1),U=ne("\\n",!1),T=ne("\\r",!1),j=ne("\\t",!1),Y=ne("\\u",!1),G=/^[0-9a-fA-F]/,H=oe([["0","9"],["a","f"],["A","F"]],!1,!1),J=ie("blank space"),q=/^[ \t]/,z=oe([" ","\t"],!1,!1),W=(ie("white space"),oe([" ","\t","\n","\r"],!1,!1),ne("\r\n",!1)),V=ne("\n",!1),X=ne("\r",!1),_=0,Z=0,$=[{line:1,column:1}],ee=0,te=[],re=0;if("startRule"in r){if(!(r.startRule in o))throw new Error(`Can't start parsing from rule "${r.startRule}".`);i=o[r.startRule]}function Ae(){return e.substring(Z,_)}function ne(e,t){return{type:"literal",text:e,ignoreCase:t}}function oe(e,t,r){return{type:"class",parts:e,inverted:t,ignoreCase:r}}function ie(e){return{type:"other",description:e}}function se(t){var r,A=$[t];if(A)return A;for(r=t-1;!$[r];)r--;for(A={line:(A=$[r]).line,column:A.column};ree&&(ee=_,te=[]),te.push(e))}function ge(e,r,A){return new t(t.buildMessage(e,r),e,r,A)}function le(){return he()}function ue(){var t,r,A;return t=_,Ce()!==n?(45===e.charCodeAt(_)?(r="-",_++):(r=n,0===re&&ce(s)),r!==n&&be()!==n&&(A=de())!==n?(Z=t,t=A):(_=t,t=n)):(_=t,t=n),t}function he(){var e,t,r,A;for(e=_,t=[],r=pe();r!==n;)t.push(r),r=pe();return t!==n&&(Z=e,A=t,t=Object.assign({},...A)),e=t}function pe(){var t,r,A,o,i,s,p,d,C,f,I,E;if(t=_,(r=be())===n&&(r=null),r!==n){if(A=_,35===e.charCodeAt(_)?(o="#",_++):(o=n,0===re&&ce(a)),o!==n){if(i=[],s=_,p=_,re++,d=Se(),re--,d===n?p=void 0:(_=p,p=n),p!==n?(e.length>_?(d=e.charAt(_),_++):(d=n,0===re&&ce(c)),d!==n?s=p=[p,d]:(_=s,s=n)):(_=s,s=n),s!==n)for(;s!==n;)i.push(s),s=_,p=_,re++,d=Se(),re--,d===n?p=void 0:(_=p,p=n),p!==n?(e.length>_?(d=e.charAt(_),_++):(d=n,0===re&&ce(c)),d!==n?s=p=[p,d]:(_=s,s=n)):(_=s,s=n);else i=n;i!==n?A=o=[o,i]:(_=A,A=n)}else _=A,A=n;if(A===n&&(A=null),A!==n){if(o=[],(i=ve())!==n)for(;i!==n;)o.push(i),i=ve();else o=n;o!==n?(Z=t,t=r={}):(_=t,t=n)}else _=t,t=n}else _=t,t=n;if(t===n&&(t=_,(r=Ce())!==n&&(A=function(){var e;(e=we())===n&&(e=Be());return e}())!==n?((o=be())===n&&(o=null),o!==n?(58===e.charCodeAt(_)?(i=":",_++):(i=n,0===re&&ce(g)),i!==n?((s=be())===n&&(s=null),s!==n&&(p=de())!==n?(Z=t,t=r=l(A,p)):(_=t,t=n)):(_=t,t=n)):(_=t,t=n)):(_=t,t=n),t===n&&(t=_,(r=Ce())!==n&&(A=Ee())!==n?((o=be())===n&&(o=null),o!==n?(58===e.charCodeAt(_)?(i=":",_++):(i=n,0===re&&ce(g)),i!==n?((s=be())===n&&(s=null),s!==n&&(p=de())!==n?(Z=t,t=r=l(A,p)):(_=t,t=n)):(_=t,t=n)):(_=t,t=n)):(_=t,t=n),t===n))){if(t=_,(r=Ce())!==n)if((A=Ee())!==n)if((o=be())!==n)if((i=function(){var e;(e=me())===n&&(e=we())===n&&(e=ye());return e}())!==n){if(s=[],(p=ve())!==n)for(;p!==n;)s.push(p),p=ve();else s=n;s!==n?(Z=t,t=r=l(A,i)):(_=t,t=n)}else _=t,t=n;else _=t,t=n;else _=t,t=n;else _=t,t=n;if(t===n)if(t=_,(r=Ce())!==n)if((A=Ee())!==n){if(o=[],i=_,(s=be())===n&&(s=null),s!==n?(44===e.charCodeAt(_)?(p=",",_++):(p=n,0===re&&ce(u)),p!==n?((d=be())===n&&(d=null),d!==n&&(C=Ee())!==n?(Z=i,i=s=h(0,C)):(_=i,i=n)):(_=i,i=n)):(_=i,i=n),i!==n)for(;i!==n;)o.push(i),i=_,(s=be())===n&&(s=null),s!==n?(44===e.charCodeAt(_)?(p=",",_++):(p=n,0===re&&ce(u)),p!==n?((d=be())===n&&(d=null),d!==n&&(C=Ee())!==n?(Z=i,i=s=h(0,C)):(_=i,i=n)):(_=i,i=n)):(_=i,i=n);else o=n;o!==n?((i=be())===n&&(i=null),i!==n?(58===e.charCodeAt(_)?(s=":",_++):(s=n,0===re&&ce(g)),s!==n?((p=be())===n&&(p=null),p!==n&&(d=de())!==n?(Z=t,f=A,I=o,E=d,t=r=Object.assign({},...[f].concat(I).map(e=>({[e]:E})))):(_=t,t=n)):(_=t,t=n)):(_=t,t=n)):(_=t,t=n)}else _=t,t=n;else _=t,t=n}return t}function de(){var t,r,A,o,i,a,c;if(t=_,r=_,re++,A=_,(o=Se())!==n&&(i=function(){var t,r,A;t=_,r=[],32===e.charCodeAt(_)?(A=" ",_++):(A=n,0===re&&ce(d));for(;A!==n;)r.push(A),32===e.charCodeAt(_)?(A=" ",_++):(A=n,0===re&&ce(d));r!==n?(Z=_,(A=(A=r.length===(Ne+1)*ke)?void 0:n)!==n?t=r=[r,A]:(_=t,t=n)):(_=t,t=n);return t}())!==n?(45===e.charCodeAt(_)?(a="-",_++):(a=n,0===re&&ce(s)),a!==n&&(c=be())!==n?A=o=[o,i,a,c]:(_=A,A=n)):(_=A,A=n),re--,A!==n?(_=r,r=void 0):r=n,r!==n&&(A=ve())!==n&&(o=fe())!==n&&(i=function(){var e,t,r,A;for(e=_,t=[],r=ue();r!==n;)t.push(r),r=ue();return t!==n&&(Z=e,A=t,t=[].concat(...A)),e=t}())!==n&&(a=Ie())!==n?(Z=t,t=r=i):(_=t,t=n),t===n&&(t=_,(r=Se())!==n&&(A=fe())!==n&&(o=he())!==n&&(i=Ie())!==n?(Z=t,t=r=o):(_=t,t=n),t===n))if(t=_,(r=function(){var t;(t=me())===n&&(t=function(){var t,r;t=_,"true"===e.substr(_,4)?(r="true",_+=4):(r=n,0===re&&ce(S));r!==n&&(Z=t,r=!0);(t=r)===n&&(t=_,"false"===e.substr(_,5)?(r="false",_+=5):(r=n,0===re&&ce(k)),r!==n&&(Z=t,r=!1),t=r);return t}())===n&&(t=we())===n&&(t=Be());return t}())!==n){if(A=[],(o=ve())!==n)for(;o!==n;)A.push(o),o=ve();else A=n;A!==n?(Z=t,t=r=r):(_=t,t=n)}else _=t,t=n;return t}function Ce(){var t,r,A;for(re++,t=_,r=[],32===e.charCodeAt(_)?(A=" ",_++):(A=n,0===re&&ce(d));A!==n;)r.push(A),32===e.charCodeAt(_)?(A=" ",_++):(A=n,0===re&&ce(d));return r!==n?(Z=_,(A=(A=r.length===Ne*ke)?void 0:n)!==n?t=r=[r,A]:(_=t,t=n)):(_=t,t=n),re--,t===n&&(r=n,0===re&&ce(p)),t}function fe(){return Z=_,Ne++,!0?void 0:n}function Ie(){return Z=_,Ne--,!0?void 0:n}function Ee(){var e,t,r;if((e=we())===n){if(e=_,t=[],(r=ye())!==n)for(;r!==n;)t.push(r),r=ye();else t=n;t!==n&&(Z=e,t=Ae()),e=t}return e}function Be(){var t,r,A,o,i,s;if(re++,t=_,f.test(e.charAt(_))?(r=e.charAt(_),_++):(r=n,0===re&&ce(I)),r!==n){for(A=[],o=_,(i=be())===n&&(i=null),i!==n?(E.test(e.charAt(_))?(s=e.charAt(_),_++):(s=n,0===re&&ce(B)),s!==n?o=i=[i,s]:(_=o,o=n)):(_=o,o=n);o!==n;)A.push(o),o=_,(i=be())===n&&(i=null),i!==n?(E.test(e.charAt(_))?(s=e.charAt(_),_++):(s=n,0===re&&ce(B)),s!==n?o=i=[i,s]:(_=o,o=n)):(_=o,o=n);A!==n?(Z=t,t=r=y()):(_=t,t=n)}else _=t,t=n;return re--,t===n&&(r=n,0===re&&ce(C)),t}function ye(){var t,r,A,o,i;if(t=_,"--"===e.substr(_,2)?(r="--",_+=2):(r=n,0===re&&ce(m)),r===n&&(r=null),r!==n)if(w.test(e.charAt(_))?(A=e.charAt(_),_++):(A=n,0===re&&ce(Q)),A!==n){for(o=[],D.test(e.charAt(_))?(i=e.charAt(_),_++):(i=n,0===re&&ce(b));i!==n;)o.push(i),D.test(e.charAt(_))?(i=e.charAt(_),_++):(i=n,0===re&&ce(b));o!==n?(Z=t,t=r=y()):(_=t,t=n)}else _=t,t=n;else _=t,t=n;return t}function me(){var t,r;return t=_,"null"===e.substr(_,4)?(r="null",_+=4):(r=n,0===re&&ce(v)),r!==n&&(Z=t,r=null),t=r}function we(){var t,r,A,o;return re++,t=_,34===e.charCodeAt(_)?(r='"',_++):(r=n,0===re&&ce(F)),r!==n?(34===e.charCodeAt(_)?(A='"',_++):(A=n,0===re&&ce(F)),A!==n?(Z=t,t=r=""):(_=t,t=n)):(_=t,t=n),t===n&&(t=_,34===e.charCodeAt(_)?(r='"',_++):(r=n,0===re&&ce(F)),r!==n&&(A=function(){var e,t,r;if(e=_,t=[],(r=Qe())!==n)for(;r!==n;)t.push(r),r=Qe();else t=n;t!==n&&(Z=e,t=t.join(""));return e=t}())!==n?(34===e.charCodeAt(_)?(o='"',_++):(o=n,0===re&&ce(F)),o!==n?(Z=t,t=r=A):(_=t,t=n)):(_=t,t=n)),re--,t===n&&(r=n,0===re&&ce(N)),t}function Qe(){var t,r,A,o,i,s,a,c,g,l;return K.test(e.charAt(_))?(t=e.charAt(_),_++):(t=n,0===re&&ce(M)),t===n&&(t=_,'\\"'===e.substr(_,2)?(r='\\"',_+=2):(r=n,0===re&&ce(R)),r!==n&&(Z=t,r='"'),(t=r)===n&&(t=_,"\\\\"===e.substr(_,2)?(r="\\\\",_+=2):(r=n,0===re&&ce(x)),r!==n&&(Z=t,r="\\"),(t=r)===n&&(t=_,"\\/"===e.substr(_,2)?(r="\\/",_+=2):(r=n,0===re&&ce(L)),r!==n&&(Z=t,r="/"),(t=r)===n&&(t=_,"\\b"===e.substr(_,2)?(r="\\b",_+=2):(r=n,0===re&&ce(P)),r!==n&&(Z=t,r="\b"),(t=r)===n&&(t=_,"\\f"===e.substr(_,2)?(r="\\f",_+=2):(r=n,0===re&&ce(O)),r!==n&&(Z=t,r="\f"),(t=r)===n&&(t=_,"\\n"===e.substr(_,2)?(r="\\n",_+=2):(r=n,0===re&&ce(U)),r!==n&&(Z=t,r="\n"),(t=r)===n&&(t=_,"\\r"===e.substr(_,2)?(r="\\r",_+=2):(r=n,0===re&&ce(T)),r!==n&&(Z=t,r="\r"),(t=r)===n&&(t=_,"\\t"===e.substr(_,2)?(r="\\t",_+=2):(r=n,0===re&&ce(j)),r!==n&&(Z=t,r="\t"),(t=r)===n&&(t=_,"\\u"===e.substr(_,2)?(r="\\u",_+=2):(r=n,0===re&&ce(Y)),r!==n&&(A=De())!==n&&(o=De())!==n&&(i=De())!==n&&(s=De())!==n?(Z=t,a=A,c=o,g=i,l=s,t=r=String.fromCharCode(parseInt(`0x${a}${c}${g}${l}`))):(_=t,t=n)))))))))),t}function De(){var t;return G.test(e.charAt(_))?(t=e.charAt(_),_++):(t=n,0===re&&ce(H)),t}function be(){var t,r;if(re++,t=[],q.test(e.charAt(_))?(r=e.charAt(_),_++):(r=n,0===re&&ce(z)),r!==n)for(;r!==n;)t.push(r),q.test(e.charAt(_))?(r=e.charAt(_),_++):(r=n,0===re&&ce(z));else t=n;return re--,t===n&&(r=n,0===re&&ce(J)),t}function ve(){var e,t,r,A,o,i;if(e=_,(t=Se())!==n){for(r=[],A=_,(o=be())===n&&(o=null),o!==n&&(i=Se())!==n?A=o=[o,i]:(_=A,A=n);A!==n;)r.push(A),A=_,(o=be())===n&&(o=null),o!==n&&(i=Se())!==n?A=o=[o,i]:(_=A,A=n);r!==n?e=t=[t,r]:(_=e,e=n)}else _=e,e=n;return e}function Se(){var t;return"\r\n"===e.substr(_,2)?(t="\r\n",_+=2):(t=n,0===re&&ce(W)),t===n&&(10===e.charCodeAt(_)?(t="\n",_++):(t=n,0===re&&ce(V)),t===n&&(13===e.charCodeAt(_)?(t="\r",_++):(t=n,0===re&&ce(X)))),t}const ke=2;let Ne=0;if((A=i())!==n&&_===e.length)return A;throw A!==n&&_{let A;e.exports=()=>(void 0===A&&(A=r(78761).brotliDecompressSync(Buffer.from("W4VmWMM2BubfuhOQtPrf2v23OidkIrLQsV6vuo6ON5J6yagfMdrY7lWBqNRd9a47LpsBgqCqmpd0iExCZ1KAzk71/+8domYYLado6QgLVcDZGShUGZeMQlqNVNopK7ifA0nn9MKZyFF65wTuzVq9y8KLJIXtKHLGSuK1rAktpPEa3o/D+bTWy0Lum8P5dbi+afFDC2tbv6C+vb8PfoBYODmqfft9Hf5Pe0ggAgnkcyCScddvJcAQUaLFtBxiDzlFX6Xu3f20V3zi9/KX9v3n56uXPdxdESLXXGIvbEJOH2X8Th4liNWx9UwsCsmzw1aZ510Tdb5Rj+J7MJ8y4+/0oG7C5N5U/e6+nCb6u2syhiiXVOk32T1VbmmOnkICBEwLGCIzQ4HSPv1vU+s8vpwklpeRcMyX3CZhQ0hpXNKalPCFW0gBPcDD7EDWf21mpzNkxFiDnHpaxMPpp+2Fb0z5U8DCOE7xbpaa//u8NH5Zl8StbCqWBFeISIAGQJVrsNMLfOS+6WPU487yt6HHvVyqxkCGr9rxWKj5mb72aqpVcNinJQUMBonXOVfO3ff9fGydsqWp75+uSrpgOe34S2n6rY3EkbmxyDG4JPxoICAtZfP8L7kEnGpRcJiK7IrwPCabx4MHO4eKx/eTtA0Q4INF6w2rfFzV6uoWdLNp/e/zQ9s80fgiyQayGUyu1EbdOJV0LmX3p9qP6wXd/TIC/1lwJelIZmsp/rZYUk38z63G5Xvw7dummA0Go0VwYLs5GsIE/AD7Yf7W8eCBquyuHN9MJmn6ZRoK1BsfCbWLiKgVF1+m/efnuW234z4lWU4CSaniecD+KO8qKwbSjr1LjR81tj8eOkhlfTy+WQYYFGxASroh5mLUXxVrJYvaq/HHw/sYfzZRjlU9DQwC5EbGiXyTlXVDtDGWUDwofvwP59Pnx+7u49XU5n2emTsXhgA64E3EvxTrkKDBFhUtPGU2++PxO8t2fC0LEHuTzHaEZNJqi+WnICMb389Zli3hnEpdFg6ZtdTpSzwwO+DAMYS/NbQ/XoGUnXoEW12ZkX5IfFBvSTJfos/EWRVFnv9PNS1bh9RePIHCn43YkDqJK81QPoSd4ffvm5aSJ3dWxvlQSWJ9lrGrbr27/Kb7TDca2AFA8IzhOnJn1pqqeq+xvxuYOQCG2kNyJlhjZZyJdJREihIXKk1WSmX2e/s37pQhjCgxbs/Vfe0coZkJeFKrT/8UkL0B4CVkAeWaGWe0ZYbWf97303pT0HRTxpkkkiISZPMbY5Owa5uzhvVMiSgUMQOAgNQku3+bcc2W8Wftvc+97716hSkUQIoEexzlnMukVEmi/OtnMpHC6KEoQ1mXTaj/m1rSaZq5d76a+NIaQAEsmpEs36Z1QkOlP/4vUXvvdvc2vaLKEo1kZ8c6p5UKaACrhAaQYFi6Yf7eVP+t/sy9uyQFkQ4gFYZy/DH2DnRIsShdi+ecu1e8YWFhF+TX7hK0FwDlB4DSNwA+jgnwPazoAPIl6YeQKjomgZBm4ot0iKlMqQu5+607u/O4c/mLzqWr3lXtonbfurf/fW9p1fb97x7uAYAZRGZSpVDdI/Xa3QGCKrNka71YFd679x2j///+tw5XlQh3DzPAI8KKEQjYkEDArKje++4BvO8IMN2DAMsjCGYGQGYNwGLWgKxqM2YLmcgcxapRcjnTy1lss0Zq23evdkIxc6RYSf1vOpbqyDmE8+0FwlRLnUTiEIb/GtyUgCqbJaZMnSoZTEvmDL9CSqjDUeUqnCzPf9yn+v+5k1ltE9tA3wQoxssOHKGghXxpC0LBAltBtPBSe5swB1i7DYxBub83F2EoxiF03obaFB5bsh0Kc1bzrIwh3LQFCHQJIft/5CJOSAK0iCZowEvBt1E6se+QClLxyQDb/P6zGf+p4F3PzaDCAkTKwIoZSUwHunbpXlxNMWf/zySGe2fKzMwV7SAKgg0s2GpiS2JLsSU2hF26mHr3yxBu1v/vXtvs726Ps7eLFkKQEPAgwYpoQimiQYN4BXwmQ8sJtGRi4JvqJhOIEwjkbtY/rpP199/CClNIYbApTjXqCNN2WnKIGmUPa42wSoQ9jPAOe3hI+9ecvrylsbdHMMEED79ocIIGDTco4QgabtDgnVaQN7MkVf57pnDAhQoXIpigwoUh5hDBEBFUqBBBHCpcDGT9/93z0K/7HuDMzIMgOBAEQRAEQRAEF4IgOLBnrQMbmvl/3eIffPefkNv2BIIlFYgKllQgEAgEAoFAnEBcMsRlQVRUVNRvLp4Hn71PVT+xIiLQiIiIiBERESlERISylBVLiUjpFIYyYiiHNu3/0+fVV+2Rf8gGmIx5Oqweg87ORHPWoCK7ErY0QUikWCgWsCCIpSbaKRaQpO/ufT7JheKaKwOv5/+/KO15Qt3RkRCyzMSKsEuNtuxSK6gaK0YX5977m8Tq6Vkg8WFgFXHmNHyNkNthOPkkpeW3tyfaXr3W/Nhgzz10+7keQmIsRg6Nou1V9G2ouQrSXvz7RuQRM+xkIu5hKxFQDMCnijKYAOB5O1MvmlNyXfsYOqP676qcmPtHtcuoDuGsJDHT4rILl0OMh4Zj3fay5erEe+MJIAy9Y/jQEoCMkOML38mHoY0XTN2PnLn+l9AMOgbfm/WChFjb43o/INsWlyw5TyXJGo0jkzBVQhHpGQWQZe3PQzCf6OWq/mVwdbA6RGmy4IFePesVn5f250+VPdv2wODMfQYJsAZvRPbpDZCkhOhUNSmnVXaZszIeZNX51IJ9Ol16VNEUgkNtPXZqIfxDs1/MGXprB/9PAnj/JMnlUIzwIJyX8qe8LKT/bYffcwJHBscc2utF+e5/57jWSqHVooqW/YjHiFl4XEUJ9s98myoPWIzhQzVTOQ4kLey5KUDYV2MQ1cY4+7d9Cf+Bjv1hF1vvbJWYwy5BvlGKS9DkREkpgx8xST5PU4ikNC5wLB7cOmcGp+bpTrwJ73OkrOWEWGV/hSRJkwh87Z7aHxsaQMuNwvYREDvirh/o6xQ/MKgiU6hXgP2Sc1p6PQTcPPbG9kYfexMBckCiE8YsNTtM+02OimepUlRaPoVsFrSaU5Yd8oVSc0oD9/mSJJ30VeAbYu6fPRizwyyv9iWtAOH6fYetXKdOw73xEh4YJx5Xj7NZdnoNcknKz6B9i2bFto9LVeHtpL4aQBlkNaFQdMjwE/8v1Yr7beThYGvLiZC1769LxOjL0M4UhQIqHajDClFvQdp+wycLk0s6nzBWe3esZZ9hKyGKe5Ib2RI4XcGMnY+N3AKRpDW4dMcuQIm7bt/iJ7Hei2XIrGpFTj1nSVJjTSKeshvOEJV3PyKGVS2rxDCkrrr9QlilCBTyjsKyOhLZJEHH/43MSNIK/76cE+J1GpGrWksmgU1Y0zQShuPd6n2xtG5LBWlRW1xSP0VKlr9TkjFlvUpkTwAMwKfOnKWEGmYB9sjl06lKyNWDom5mkSN8ba+PY37qy1izbKkD/j1fmTLDzYfDN++/b4/PIV//LfryKYWIt/Tin5RpX2t+YFhbfnyyty8EWhXyY2vcfvoD2p9L9pAvbTGNcxsOlKNz/WLlfxU4n1ZKGsakG7dMjpCOY7N55I+jxutb+2jg6/h+JH3z0vnKHzf9o+t9hPrwAO1YpcActX78v14SNmwMb3FfJNbWvrLdzjQxjujYFjj0h1K6v9bH0JX36+g2yUAsD8kBbSxrwb4R5UP25WJf5bhjzAU/xW3ty6FuN/yfjiQAxG9w9up/rSjCsHZdqO9ogNUk9Rg739V0ncE2mB167H9FiyzIP1UEHIzsCZZRf4hrME2lgK0TVIrZjgSrZOJLegE2O/oEtdEO3UPPdbKqZXD4JwDEtQWScWmNgbbHGaqkBYljkIY1sAQzpHTpWK2zpZtLbg1Y11SHxM+0uVGqd9jOez6W45/k1HFwCUYm2LjHI4z/GJEs7M+OOW7rfmk7jWpaJRyn25rmgMfSJyMd9gXOengtpUtG3p44XehGvj3kHe5pHLW1grUtJHk+vznHp13/p0bqbiiRsZmTOprJNCxF7ClPs1mKjyxc+GNRgsW5NnTKNhdBsMS+w9TYO1wGImfKvoZPoMJNsWP5aAQrLUhxtod5bAsvxXSwMeZFjxIHf1fORSeMPxvOxpKgmtI1y4gKxCwt3B25pu94u+I7k8oXzyzmgKwAOcMSiK58m0YylrR6zVGOL7+BKLEcc1BMICUvQbGZj4JSrXnuKfQd5vNUiHUqMrdDhbaFntQVLBY8NU26PPoJ5pGHYZWGbI1EM2PL6ILZKDl9vPQz2X9OBkSEUcYOrNQBtRYijGVSkk6TRx+CkqYzT3eNkqQ5hFg8Mnu5nzUg5zo53n04Jy/Z9eqGUETJk8e9W8jPWknj/CrUWdOwlNyYI8aoxNuF5xsMDVWvLvqJSx3ETwMWBf++Z7npjTCwjtqJ0mWXB7Li6tDclg2/rfqKfycZIKl8KeiRB6blfTGj/KEs1lRKNTl7tqnyYHLc/lonojXr1bRKR3gqOdSU/7dF4J5/afUU+qlkdPZD5vb/T4mabuc5qnQxDu7+WLjQLoRYPTwo3FZQsqjxsrYaGZAzrBdkAtMZrN+UJQaQUW1HZDwsSaoXyrLuyelQv4nNBpgTcDuHLYTrmO4mpnCs4EcZVy8rGg9gdklu0ebi35f+L6qMlY6QGkpbH/Xe9ZpoC1k2k9Up5VamhCmJ8CwTvStCK2xfpadQlX98NrTrp0BGxI+vF5Zeb+CT2PW0Rv2Jt3X8ZKEo7RVi9VyiPfbYWQdMbd69FFx+fbSnK53UrFsNYomC9m1hmXIrqh9KLPK5o5ib57j9MK5TZfhq8jvNNgjlFtIwWlAoyGHkdDm1xVxBXwuqYAJJ9cHWMDN/k/s5UJIh7GjiLnAktTimKNw1aFdnDZUMz914oN7/PxEMy6umhrpujJcj6Ee5WWLc+5LVZNADEFnu+1uyZ4hllPvKek27k5QnC4T0PThr1742tJO1ceahcXcOKXmCxi4CAlN85CLncdMUCbJaRWJf/ITIttifhyGCpxLI9MSYkmjj5poU4UYUE2U+yxs5+ixzOpC02+8ggSRggUlqbHRHr5/G8hquDdvlcDizInUfhPRDgiKst0IKDE4kAVpop0W9ZjVzy8sXcPovaqGKUShVYVwT0KFipjART2vEhGHjbVVC94uIKciKJ1dTDCX+q4JotaAMWTrNtuRiaSBNPFcazlx5HCMDycTHrq2yzDBV+6HzlyWfz1Ozp4n5qJ2j2YZD4CVHK5/euOjmf8SipVYMFEyI379ZETelNf1CqZBI6410/YHWIxJsZq5AzaHEvaUP85zyxB7WPNjfKrxe2K+KOyIEpc6xFPoOL2DYqNfhLatlNe5q94MPTV7oj8YdNxHB4CgEEezyh3BM1kNyyDJv2qyMRC3v2ja7zhvqjmRVJx//f+v8T4EgRvgIZnD/oa6t9gbswIf1J2iNdtsZaO/MX1I/EdCvKfbdE0U69QwshO80slrAeSSr/ISCIgLuh9o58qSjNqX9D3bMguzPknHn5Fw8ELBiDUWE9n2/auRjQeTVubna1JVxS7FZDqEOwZ4DUV3iXky26Nw7+xU8Y61m+ZySuCOxjJlsRAIrERYTI4QhK/yEGN2VKtBXYRbJTkvSK0rwvXnYcT0tk+3C39ANXwhrp4UKoP7Jaa1WMKRdK1nLMiyBNp89NvzR7pb1EtiNGSFuzsMRG/sXlnKltEBSub32/TvWhz2yUxWdMRCLJXrWYSuHMBsC08S/hbf9uK3+E1f1vpwbqS8CEJduz+hKZyFvR0u00YAKB8xp4VKxIllmzHXmYXcP6Pya1eC2VBdLdxXlB9ot4s4LUjh2Gq9Xan6QjLwLsITV98peRxPBe4fZFhvPdV5GbCl/YLOGMkSHqyme2e+vuxj3XassqCypW3B9TyzrvMkt0uC2ZRrHzPmVx04AmjFgJHmSB5jmqhn1zQCh+HEdM7dR4a6Pqojf/YE7JY0ZpXUpVCrsPZluAWlJcJYsJqHniYMk/nBH7jzNsw1N+3zGUA4myFfQXcgN/nHGGwNYCuAYLwbKRd7d8rIqqvdfMUBdCQWKaxvqqyVyNz1ESg7EB1IVUQ6F0jBU53L+soeWsWSNhEk/S6+v6nj6rMXETB4uffJRMy6CuUI8ms7WkZhL5YDnzpy7gGmm0yJ0ihhgzCdwMTEgHKjY58ub2jyBqgcWyBDtzT1a0Kq54eVyz7Mto103NgLn9ShJiXEFonvmBf3o1hG4X2YAYsQNBHfgvf5+dJLeGBubmAdZSK6pAYe6ikIL/ijhEDEcQIJB8JJKSMZn4Xw2UpgvGvzmxYFg21zOchCaOBzwFpO+iSI7+mqWU7OQw8+6e2xhH7rxKYB5TI0QFGjUSpAK5iZzkSBbk1iM2Eag5jRytvX65NviR6NF2hFCfmhrNgvzCX5+cLqguF9bmFigr/yCxSYCg+V7C3Crx3w2mnblE5t2fSvN7a+tbvi6DYxVk6g/C/r3mGTDv1lhYugGGmrjDDgteUKWx2ojGGU3/hLtheHcIDc0Fm+bqs8g03oXtL8ZjWIO0ZGSBs8olWMzcO8CkAPl2Wdi/L5coM3t/go14CLwv/0qZ6TLkE3g8AgSdFI9kBcGC29Q8BbBtvR7C6brqalTy4T7Nw0iT/95OsG1vH+9523stLye1ahJ5i6BSiX3grDHyjjPS2Id/AGX+i2eFlJM/EitK7QaGYovCg4N++hyDIoGCOjaUJsDf6XN2hbEjrC88vaZl1IiVLlqohvtq6K18M6YiskllOFwA5rWG7ZtNIfNf+/PCiDzOjd4h1EdQbN8cveHQ8adr6aax0mfabY9MYgyDuus3fJxgnjnF7p6/XxKwkFiN8THE1wgZdfUyAvoydjWq8ELUHaJwei87FMSh4BIjcnYh9BtwaNzW24kD2PA4gWqx95VH3VCpnKxbs7FeFq+4cRjVFovhlFYd8GsQJfAZB/UZYg/fU+CobAOcDhrYQS9XDyhdd88YI1uG8Rz26wcL50Eu/f+dGzNYLZ9VLxru45es+CfjmXih1ECnVq/900JLJj3GdRwxVP8dn7rgvWoBOXGb/KSWXOP/Nj4jjN7c45br/q9O0zrY2kFg/UMc+aXb3LrCYQkuwjlU2o3H8wz6r7O9z+7w6IDCDUqPzLzVGwh0P0UTsLg0VqLyj0RwNC8wph3F/dQAKPeM9XoBd52ZBd82+sW3o/kdxYDsJdYP3BXtoTkle0iAzV8riQTkUymeUbowNm/cYvckH/PwEOP7Dr18CYHkn1oiRwILsf4RFrC4ZEgHAyo6GnH+gddJFxDIR8l9Z2sGUEUU3RQ2UR2dYccNhiJycflZXCGreabJAka9eg2sjb9iQrY3DXg5tO0HN7DItWqhMxyOH+V8Q3WSxnddMG3qa8xOR9YXAAuHdib+ZBFPqrF2BlcUaBvCWiIj6Cw3UnX/L5P5a0Rj1j8e3dufotL0buKCGvlYz3d4AmRzrFwjpaAwlm7lU9d6B0HhYd+NFjycC8b5MVU3Nz9AfHbShibHDE9MZGVjRZlcao5HxJhMHIriHcabV7IfsLaEVWFFUN7rvr+PEfcjgMMXQv3BLrXS/2kO3w5Qwt4zCFxX+g1J+s49ht1l2VofLebe2D3OAX5w55iyG0v9s6zmlHTts4YMA6X8COkPsaI/a98PENtk68rAw+ZIbVHOvBTPAitwv+nq855mf1bnKuN3aSoSbSr/7MZzvH5gaJKmCrZdeROYaR3qX/0f/Hat/LhX4WwDGHV2jfqiiVqjswil3YZkUP5EOt6yRkkp6WTw8fTDXDC1Zj6fIb0bKNSLRj1KSj+SsN5P+f/D7GMAwg1h7LLtimpIsP0QTJ1raePPj5binPYxg7xrdJ24FmzGKPOO7GlMI8GcJ24bNxL2IX92o3RwEvq5+ZDTCRBrjar1b/NauEvnOXfn/oZ75S+mvBRjBmU2jzlAj+k/BbCHRTGPJA8jldtJxHr2RQnZ/8Byo7jQxTfgR0kVpvjs9zhtu3WYSj8NjcVu2jnVG/AZa6MvPSw25E/mJ5yj2ZpXw3rpg6+32BmjTrQ91P5G4Eu3/+ZP3f7UyEuBsJW2sv7//2kPJP6Kem/QlO6dwAD9je6divfu1Hyc9GGW7o0As3+Cag4YGefgsTROaIbteMq5VLBVnctR9tgF5Z8nqq5R/XXkPhWzjTjHyj257X9XsC77Un0IYGPn2Qnb1N0AnTXax6R9RXlYDPegTDbXhzt7Rg2sXt5y23hHG9XvDx6Zzsussq5ZuLPeai2queckiXW3JkVUUXZ+f6wT7I2YKV6sSXUlvio30C6/xK7GZKrziOlfxSueAf1lITFE2CV7TzTdpyt4vpbcwy5+DSFhM5SrCr2D6T8lI6iZts5ErZ4Er6V62Z6Ru3SRCvxdfBvlWdSvyWy8M9egAh91CvznZH5/I4I+DAX47htxDsCWDwBNL/c+zCmwWrg35obKXaiKSQiJI5jT+JC0VwKF0nBenuEHFIJSfwoNOqSuep7+3Nv/lbZ6P0EceUkGH1gMTykKkOWL8PgJ9Sg/OCNRiaN/yDxWpCTSTZgAtNGYfcD+DFUDo17a54/9Nqq/9vIIlpl+30UQg2ndWnQQneGEYMJd1m6RGpGYrO52OZ7FDNa9mlbkAef/jRXVsFvFyBnSfcjTqvsLK4OUZUNjEHOKd1AZL/Rmetv7tUeP4PIIj6oc9Qj7E/Ro4v7h/mgD/s4pbFke/E+aXeREdg5gNArlhbeH0Tzg0fDoMXx3CFSygMZyOg7gnh/W3k1O8CBw3kEmVs1xA5HRTTBeMtOd2FdedsRxppNXXWTVP7aCzRZznIRiu4CLvPiyHQsFSwp2e0wBzHZ1lVG1jRdIoc6xCwCwQRspnyk63lsiXsuHrJSK/ySGsf5baxVo4p+orzG6GYWGiYk7bKVT4X9qbmRgIIBqfGmPbqDpLwrIF1bjWOffrCrX47lt7YTlm2vN1yocxDdRY3Dgsq5mWMofThHimEoyvOJEPF1SCcN9yMOUFmWpuVpHMgDeQCBcAqQ5ngXqeOEvYzJfRCvXqJ/avdX+SUCA1kjCVsZN42TjouVmF07Sv6NemBeszR4UGlTC3ijyaJ1M3AYbuCk5EWVlCwpdFA5W92acB3WMpLm7HWYM+rIwB0j/Zj1SzUkTfvGOYM8NWMft86f5TVlNV+6UCN0kfYCbRryRJgBLs8En0ws1y+Cus1AxKMS0PDkgw9FpmHQFxPDxUBiFhFSA9jT6xaaFkHZNuV1O0c9nSI1/xnB1eipNGIOGjljJaRXH9XlOfKDjnoYrcuxx41B2MG0GEaq3Dx/TO239qCPI+izcLpzvaaM1Q984OWmOtYwrUBWT+9OCd8mQyaKuK8kcENfjjjMRCB2NygLjA30Eb8M5v18Q4TQQY2LjFwRnG1EZPmda0wskxFRhXzi9a8D4Y+QKUZm4ItQGIsg3jSRL+Pe/6Xzpxf3/kfs/e2qZpSW/5eAD/9TYsWQkZ8BwPUxyERRTEg5xFrCr1/fpePx2qHs/yUrMzxTglUALMzANyXnAFBXeYfUwyyG/Assot8rvFktnH1JVidGsBJWBo7mSmxlbAa+do7NcSbzky71XKzHupl7lFvO/KvVVJcMwQ9E+M5CDTSWqlFldTX6Z5CFc2TgFCKI0wWY86ctlBQdT2n5+ru5igi99tPOb5ym3HXTVNv2UnCwG98Py4nWUBW6LG5lXCCbRDzzkQ7qxmF3EINSUGkNE3sd4AEw2T7N43QP5hskM7HzQZeRweEhkB8ZAr6TEQKdxhBQLw/BtHVUfz5wjQoHpIWRbFW4tujbzdDC+WyGmIJsF8hcOPiGxVeaq5pBJF7CZClIsj7c4YIuW/935VwCTxRghFtEJ4a77McbmG6acuoUnwhY1o4dH5E4DJujr1tOHUHcuFqX89uthMVGoqE8XpsLr1Ym/3MohGOW79yhz83/egW92PD+gywk4IwLCjGzwgJ4WAVG+GYSfnxl65fpvMDNolNi869ZxyqBPasqmYjZGqoX8qnoL0/il6movMux5fQkPXLjeyVjGzPvHgwPFOLfTfs/Js5wVnnb19EMHLyVwDj5GU8V31iRg7YZAOo2tAdAOKxpimoXAnQc4EQFeg/1nDL9QDFnGkLeR27G7XmLT+3UNeWea0vp9/pe1ff/dgzdbYzlHplivn1vbuQTk0urP2eXotFVixp9dLfVH+u7ID80ctXPlNMZZExej54DvoZCAjsHKqhQnZIrxNqT110T49F8wTGbxEBWZlCIcHMZ5c2BZTFXCmKpktNUoty+GvPykHaCWtSAXAzNalNCVGqdp9FZBgEr5pysySQ4fzsLJqcF1aZL8sU5sDMumje9dgpwsJjqeZ6rD3AO8b4eQDYgzlnpaMgTzT3E6QQjVQafR+sDY3MGAMjqQNhDkGL+BbhtpYFXS6EDEX2jVgSUhhmMsuMDEGckZA2JR9gDST20olD6W2qU1G+pqkRSm/obDGTyWg5HWUDKmdl4vMPg3jMApwMnmzNy9WJmwmrxuRIbSKP2RS+05KElaK2Oh2E2AmFjPNOWjR+c/eN6W5svDuCC5DrQeFvCD/FmOLxyz5t58ngLghRHCvc/UUAsigtTMGdEGpYW79ZGAUP71NK2iHFyjGWe6x+IAMEJ07E9wp34GgUQBRBBM1+bEG/rtJqVOWG4CUOGp2+ppfD85J9VrNO8zljBETA5oNyOe+2WE6drcfiduMHQaMBvTczzUmEkD+iMyHXn4vkO1ciADQDcsQAnXibs20EDlgPgDNUosuNx1VDEeHWtczNnAxgMYd10mXdmRPNLlDUzNyOLYb3jTIjaJHUL4YQrJ2Rh3ZS1xt5ge53TMEgAqAGTszAneHGqR7n9LceHVDQi2sjWmPui1m1jM3grPLc37/034v0Gu9VEKCevozs63baUE2I5cNqUZooJBYsC5WK7z0yQZcpt75mpZhQl5d0hsoq1EVhsiwkGAOiQ3/aS01ZiTFyABKMxWx567SIzdwAMkNUOMoME3hb7p9bnupnRyyZ+OhdApENG57m6D2gRAeAtDSVYy0Pc9ooTRkKps4iQFkakDDvtojLFjKWOFlip7dJayix3btOOjBvJ2/MA3PxCJ8Qy5DK7yNRSciWaHQp0QjwjZkeCTLZZJgBXbJdQCRZxARQWSF/X79IEWFwUuEdPXRiBS18P7zMDJCZIXZuGJVr6BhCm7bVsyBwy1T9LqDwcqATxXVr4b45ocIdW7Hnfc/l+sidiL1qMI4/x4DHwUJB2SNrDCRm/PY7jgiY4Cu2Y28CupBFtR5DzdhN1gSfPdMwK09Xws0YWSLsBcpOwLup3aesb9kBF1obzH91L25xTIPVD9Tqza8IIKHUgUq4GgKgGPAu7iVoJo44GzObiq06MZWbhoivwAGDI/YutmTQATt6/yAoAAAXrxdVsPOp5c1gbxdOTEmN3U7beyqzs8T2rptsnAlJG2kd5oMzoj52QAb63TonT4z5A3YtccZEIGcxIAHaYFLCvdSdlDjo6NBRqtqGVjZI3MCo2Xp4zYmWTuGpVICJk4g/ckLEeiGlgUbBf4WXQwNeRdrUb7GmqcN72rO0DflBmaGNiuFP8xvjJhnye9r3bePTw/9Rst4sw4y0oyNGLbzxiZnLSwvvO+fZ/yU6o0jW1VQQvnfIauL4GcXy8QPGPcWRzZfVTfVCIJ77iaaEOJOxirSwKYkICC4TFMuSrdc3dBK5Ci7u7/69n6jzgyysCW1gQTCNJlV54kWI32HGgZhe1ku6RNkvOMuaFW9NG7O5S91Px7QlhYN/KhKzZc2ggL0AL7bk352gVLC6iiDJhqj58DWkckO5ZEduJJCiELE0eMEYnJiMjcZWyJLkA/prI+zVCJA4P1Tk/HJTkvwb47TEYrW+/l8YaKopDdch4pMWdzMMojibSB2WVoB64WwucXVkSgJoH2YaTvvIx1HXfHd9Hjvsz85DcWAVBFIsyxkQJgfsgHBJHqyJf4JnEyts2LwLgKwp/IZFmDEGc0psSSkubTdawSzb0YdVvoa7k5liXhUqgrmXaMX46rEY7K3F+cbLLc1jPUjEHAc01GYkhEH+5GNsMdSD0eubjKXBsBgDc2LBFYuq9HmrmH8g0HLDRhxZKkapaC8ke4F8UOU95XBsUvyWURtGk9WQGuiYt5RZzSbkhZljmglTF0G6bfzbQ+Hyd2uyc/BHmnNnuXKIiIMc46nmy4Tkap3pqWkm96MqFrP2O5ecTh2DwkfL8STZ273kG5g2SOWg24hysGyxOhA13Q/H52s7XGwUzbMCkY0DD5qwMatg8KLDhwWDbPvzGp2KvemZoJjj7nf/dbSXHVYsdA5gx2SY+h1/Z+XyyWxqwOWd+9iSAf790biQtUCeUxJnhhp12KVzcZAfy7VqH5yIArfcA7BoIHdmkGgIpo03biXtP9n/NSejteizFmXnPt06vD+zsbdR/uxf9dfkkq71/TEd1Fd7J7hPipUL43oE7iyHWnbMbRruLJWd/n1FDLTTxtD8h7dtaA8MovkToU5PtjnnkAXKPYcFM2oTPV77rVcwEDTjaicZI4Rwz7xKeM1c3yzbN4CNye0HxQ4Y+qO28WsRMWPgIpw1yTguyAQcRZrtdOGsLMaZ8Nk8k65ELaaF4sYyUIxE1oIEmJSGKzHvUCvQ2DVRAe0H62YnJixnL/Ua8EdoG1/eWWAKHsJrAZVNKJCmlsk4iQtH+B6Ro9xOAnaK06L1mmQFp94qzaS0CmM1jv8dAGDR2IL2ZD2SaxKztG41cavp1gmtQb5bqyaM3w62lydD+F2/OyhbzAMt0rUEnI9mZOCVw8n36Nqi0EZHviB8PUgy4knq5l0mtv5r7vK+44H2Dcr/y1vIipo6cZLxldNei3bs10pMwF/QU85Eg3hEvhxNRok8blnPf9lehIrQAXqEc4bB3lkCD3XqL5vAWLIWs/Hta9Dj/VhVfFiGr45nTELSU7C3/qJTSBxaExX1NFLjlCNRIxk0BZjJqu2+44hzOPtGgc4AwRDadKHHUv1qeQ7hVFv6V93UdFAyuSGArOZqnsMxHx+wFaNYQcaFiAV+uWIN+4PoR/l7Iiyd4lfhw1xhFrIsT95uqsYZZEP5UtR9e2xSVOx8dulm4idZLOwMFrzoWiyO+I6bknOrmmhXFFswTMqvEX4gPX5E/YcZRrJe1OWaP0wK4FkhglveA+zJBEk3uEbFUvS73mDiy+UKuiiTQltw69dxBWRH0iCHwAEGVj6W5W92zRG/hNMTdS8i2Vm1/rZZUgUYrHiW6P8mZEagE/UkNOoFKUGQCjUdIVOQXV4ngCcIhvmwqIQ4URV5WEUKCedfZ/xTzDKgEweQBA6CIceUHXkxWE2em0USIV42N9euNB2sYDTOfErZBuXBfgvvSUt476XLrTbuZ50DIox14N5fPYdR5lzKl+4Vi4BEQHavRMwNJLvtASdQF4r3K2flfPQ+DYeYzSS1yhq+wd5WHXp6BkqoLVnMhBFjeZoKCAih8bvR6SbCw9KXXNAXbZnyYA+4Rs50aMU1hAQ4GRc2LKFW03cQCOZebUc53kOVxIVVngp8T5ijuU2aAxwiM/OTbvorPW55XykpCYqqSLduALba9xzyj+Zh2kxssNQllfy8sPB3/Sm+H7anuJ2LOIqjFOh+3ObPbAI1qCnvXKFg4sJJ9pgfGj3yDiHVOovAp/SQda8jFL/zwvNKROUYKR97hsQc33wGKFSgLT8iwUCwyrLrO5tSlEeKZp10VJ8Ln0SExkvGf4Jr0mi8LVSzMPnW2xUl76qGCyVif3seHYm/ZXjIwFQGkwKnrQ7M/XXExTHxpis3YlDy/2/0YkirXhdSMamfvjVs083w6cHcwdMontKjdySoBMkEYl2nNVULhcHmKGP959/PKSHsVmBKigNxHEkI3IceJIXW6Xs1JIKt+OmhEa7r7FXOoL5dMnMkpJgyVaWPCcHziFKKl5YXaYH0EK8ggmboPo2IVpfr+wrvo9J6aA8dO1CguwfI5XOymrXDer4OV+nspjb0XVJLw93Ajg0/ZqPR8LC7mTmS/8rk37v3as3EmJwPIpH1ngsLID1U9FsGYbUphUF+k4+Y8ZhuO2YE7hyLJYdxvmQfQyjGFa+Ro9dzAmncIYUioAqSQtcEPIqBXBVaNq0vqV6nS5fTKvYTQZd/VM2eM2iS6ccCVMqNvsaf+kdah3d+ZwEwo0yscC/qh0FGvxddfx+PANq5NcO9Ab7WQ9tdKiOt6BGENENyyzc49UfLrDPlCMsHGRW8zzRXBrSGR2yGwMozEvNkjdGIr1wzlgD0vL82dxi6+gsVpt6HYelL8spCpY0lFubGpk3rUYJXUGFUmG33/Ig8sqtrLFk3V9mzgsUak3JYbPx6WxiTjfAEre9KA5hdIpuAzKNGuJMMP73AIorNw0Iza2h9LfJ5zEWYdtFzzoXcGo3lJyEXxahevdwBZst7ER+HYUpX5bs8ThS8D4mVDg7CdmQB7eP8zMt99eYLHx7sGWYnmaZFXuYofCWFQjgwd60bl9KH65fTYiPWzKkR1W1r+4C26soBW1FgASFkD1AWdgtBhL/dhGlKp1hmF1A4FNPg18CCG6Toij0cO9/20u2zyMYS8kruPjzBSBcpoPIFpQlmqx2jHfo+aGDFa7j0CVebXN/CyvEWvcNA/20T0BP3xiHE9uajnJno88C0wMt+aiOSZYPCIHr05zL/ZI+eMvqzyIM7OQPiOt0yen9P/RlI8InugAk8GKIQaVytwiVAgQBYa1xz+K79uiTg8Ald/xGzkUzq9/1oLxT4roohMMkeVDrUNFYqzX6TeAbR+hTm73F0H1ZGG1zggLVH9gGpEB5UmUjyD/1QeS+5qFkBtcIi6gS4hKI9LetgXU2OLkrqS7i87WHsDmzh1LsFLs0UrtyiCtL10PxOyMWusXuhvdGaGWUHfzXz3ZcX+56qI+ZlLzEGfMcUDj1w/kebJ27mHP36Om2rwE0vBXQkGoCr+1XP08fG0jwB1x7vcTPQAkoENfnYXXB4fkknsxa23ZE65TX+f9PWHwE9WXNUVsw2mbcvTDhX3AKKwGgLITqNwUZd0qwdZnppfYEIY2IaTsRw7gOi3PIOd6fFnaOEhw5Uwv3wm1rTOQ9lw6MY8MgxD1HmCoW4clFYbZMKwoWXl7qnBe8iVYKkPCh/5W+mrMpJrevw1jQNj/lTumN1FQVb7cKgAxbx6S+bpvH2/JARQR8zc/wUDtUV+S92hrihFBBT3v8Y26DWYh9YpJSr3JzC0idU2CoqL0BulZjBNsX0xGxxyYt9VRZihoQ9E2NZKXL3kErt/Bw8QA9NM7Wc4d9WIafmaz0TVF2y4YnjwCacVCQdqPs5ZVA1+XA8cq0lDBruEeihvZntLz6vEX59kWU/efTR15W68E8g/hb1/1hxGfV5EIV4jEOmAn0vL5NDbpOQ18sUX5ML7IBauvNqCNxTRmFA2GMrqTUQ8v8yFYOncxLRMxTgeT82CzVcvswBmkVAYo6vSzFBKeCcV/mXhy+bdzC7PcI5tnBKcM+RGCf7vtKoDoLq4LQN8yhfG+YRvbBh14S1Da+w0f3fEsLz/g3r8lyvYHe3ecx09k1iYH2pAyqAauVua39aKRSZuQGNVNaYrtPDfql2ipAx6xILApr7OpcqYPVITV1U/Vy7+XbXC93jYLea6qxRxxRqNg7wE43hbCErhzlp7XIwXSw6NRUPM64wLEB6DFccpidjGQOZRLna6E+viLKTTzbI8szurQqQjKeJS5AsAsXt/7Omeo3y0TUs+AS8kGqs1EogZhop7KXGcbSMvORBxYyE4ZVjiDpfdLcfSwyxEU/TWJ9PoZeURVCXdnYjr+4sW7ntpYPyzBSF5+gvLDXGj7rHLxU3rz5qRgv0kApNb1v92GR4rhPh3XSKRpAmEpgwBEJqUNYKSrowYNrAJkhIqexF5ET9HrLGQ4xsQAFFqeD4BLI9yA5P8mVRG/hK5arZ8151tF7bP1hK/YGceJGIYXv/PsHW+vRYwIOKUw/fqPpjteln6AJfpWcAM7bJlNKkW7IjDsGeBnaeuLuthE/qPKiUq2VIpC6Ubzj/1w2JJw037aqgbslLf7Gd4Nvah9K4c0d1QnSMCueMrCh/Ole2J1F67X6k60RrswKt81D+579/YXVDXUUNQmlYJLdoyvosaf5mm8W0GOn31DfdLIKC/+iTZkADA+B5g72XwGWQextd4ywF20K1hfD8FC0l2A5j+I00tDTfLqm+UtMPm7j6NlbuP4CWIHUlEMNdppy7FEQaMAosayNn6Nll06y9Y28gXYp5x1W7qv2OEk6Du9tnMDRxctKD9iS9WtJl4xEmQozO7I7uXoVmQFSxOcAWGzSE9Q8yzYouhpr2fibm1HhHSr15TWxUV7OpyT2/EgV4iscC3fXxgb/baaX/IdcbnIFsx1UipwKO4rw8QGRNJ1tB01dzMptJCJNsM0IVLi4ufq3BJM2O0jijv55RqQrCZREZdW9+QP7/LeUzCiPN3wqyX9xTxL6KX22v0SyuQcyR83a91YpRdqFyM0tBIiXxTXIBwK0WdhxrzdszcwWH/LzL0VxzFVuXk/VBNQI7WJWXem+Yw6j0h2ywEu5RoVBuBA4ede6wZLCUsgLqfWGB1zSFiDyXRtOfnSpal8iQquvVlEO13NGLeUCW7FePcUcJYFEaJ8w94idDHw01U02s469Hirschh9F08FCdKQFHdCSTOyzQyXpAiGGUxVw86z3NnLk43orZF0Fzxw0zRDnqyxxcYT1i17Zf/+tpE7+lJC50AmTnO9Ds5qh9s04/KlZqaHEx/bpJQe3Lou4a41tuOdZSyOt9wDzGEg0Vur+InPmB3IQebDIz7llzmbG/fFbrk4jGB5mBF0p/NoqRzryiyBt444Q5mL+x7zkefBGmvKtmMYqFAMNngNLIkcGYC5et9XlMa5vqqdZakXnWnJ4PksNSHL8uzKBR9wIIlNEKzmq5ExsNjP0nUso0A7FU5s4+gJJmG+RTXGH8T+6HxrR4w70XdF5P0XNWJvtTpeT5+WiPcSkJI+JEq/KZ5HXmLRRN2QFPB8q8FewBezdIqqmPGpMDMHX6Jss+F5209AFmfdzoNoFKx3CnmvOpo8P5IPFhqfDy4ZGfQbtzGgk/m1w8mt8VojGwe2RXXO49TLNJLhthzkh0GHdYXLkBPMK433Y5pLPqpNct1bKZQjE+upPQ4KU1nHz3NUWZCUari03L1MJw7l1lVorlQM/aFeJtgAEaV9GcoO9p/V4EsBiVEaQBxNBNa/zsiUkctH0rKocREPr1HIUoDjE5FZBCs27rHh5/rvJ93+8n18lqKJQIn0C1lID6Y9+ChDf7wFEs9KptngHEI+G6ifQBexRQmNvR4e1qx1vbzLGL3Uwg7lgpMRTpP1K6ZOqwu40u0Ob64yAX6uqeeYIT87B0AYA6a8WlFwUnaG0MF5wZPUtZu9iVJXKzZcmyhq451GPD34qnHcsfoiHKECYb/HwGOdu5GECKPD9ktL9cQI9i/QatRyDrbBSgB/EolXzMMNnuEnRx1QtHz6E4QkuZfPc8BDW4YjrwHfqOg4dfenIlRnpjnJmn6UQHlkT/saPDjykC8Al9Q4IILZTY6j4Xbr5hK8EoK+vNzto2Nzgx06Wch/U5RrYPfFvOiv6nk245WRbyaItCYB1NSQg3zWdgd23s+YNNLO7ips+fq8NX6LPOfrK4Va6OcIlgCk87N9WhQyfZj51h/v8KpMO19vAP6h20BTPxsEgBxMQXc7VfM40I84EllUt7DKQ4757AEaMaXPz2ujr29Y0aDbquQ7vPEyxPcu4SO4ZcWOZ4WcnHAezSQPFa142+zVm6vtvEEx7aexd9KXZf3uaf/IhL4wxHyH11sJlx+RqdfJTLTQ7VRYRPwhIZHvD+yMOgGcnf88kfOA2jgNN43G+4Zjl/W5egXnDDjib/fsxTapzNUpbg7RstIlbS279UAQVHg7xrzI6mMqpD9x8IxUN6Vr1/UUNhHDMVGHtPHkBe5ifemTZbPTlftXnSvqqK8Dz0MyYbJBDQTCzW1ryELCJHMwwTdxj7GNRnYWCGU54akwz1xPHNj+R2oPod7V/0yeA0eYQ7mmfyk7wVTB/CGzJ7POfh/ZvwIC7zJ34cYFiLXnnXv03PQ7aVzcgdti0MuPZYQMhotN9Q9uqv29CeiEkat6fcKRmDvdGWDTM0Zs/DSXSCbtSlv2yffiVFTnwsgMQwpBbZ8iRUKFVR/BHExDtCn+szBfZmblqWU51wmK3LQafRo/m0XuzTCp/2YQ32s/1wMMwWAtpDKvkA958oCA7T/wRMi53fqZfklKaFcYVFJXM9iQnL29LSnCbSv9klmIcaLc22QeIA7oGs2DGT93xj/FhxOlKCBDftX3AjZiacN0d4kWXtXXb31+sDk+62adFPTxTn+m6SbTLwu5qNx6TrEzhR1prLPFsXS1k7nieg8Go+v0oA+xVyEnw+vHBWk1ygOXmB+HgUmpfLDHeYFGfFyXc2J+fPkt308Ppf/pFlksp/bJepkx2kl0XSyA2i6jdg8F7RmbtSZqhthV/O+xfGXbpH7lH3g+LH1+6j2Ok0yn6PznpKUkpkg6bgMpq3BOUd+VvHTbjDrO8yeyJ++4pzsIURRtRLAEKmNQi5dvA5O/TJTYKrWYwQZwHkM24erpZ5MiG1Hj8nGFb4U0VCjXpgxmjqeqZSCzD5AYMwnvjRNAlf/3DtGhSUxLTyvhy/uFa2vcrihn6iHBkF9xFq3PxofP6ie7fOQeJQrv0GH9p070Ww76cYkczi8h9O12C4qu/O+n/XLb5zNKJV7PvRjyUnu1opp/mbmL2575GAS0Mrg75wq933SbejxbZ2bErvRUw92yGOIB7bPOV03ZFRnPHVL/Rcc/vunQ5o6OZngn7/s8WhlzGNTBlievj+dJAC2MImK/cxHvE2Ft2WEiij3LzI64mKJclywnlmxqFpp/FtvvROnyOMNW4w6KPb0ubyjXmCXTkuNMqMlWA8R3RDmTBmfm8ZTgFG83xBullGHEkFcvFcumVCB3OTLKjCHDPbvQDIFVU835N3Zy2r+fazq+LhdI4RS/QWyJK8rJtvGnaEO+VLa1qwPWeNi8yFsxUYimO8LkfRiE9kZle9zTB5TC9YAmM46WQwuACsNpOxP3/NDLq/kV6ip8oKClQcqVhk1gSItbmBupqoijPiLyaCLdVOUICGZvcX1ZMt5wqkx9K9lKmLLmzVairAhcF1Ui+m7rlTTTGGXjUAiLKNaLinGmlYUGuKmgxmIuca7IKC3bglHwI78Sj1e0Y1f5A11p0kiqphBGVODZiiCTpLS4YkmmiL4larjdNmooFxp3BAPNVvLDFkyzfYDY54a2WKDZvQsSg2ulDtBqb8dsE7JHMO2+o78pJXbcAfdVZi9s5KC3g9ZamolQcIkCtAfW0Pm4SCVxzlmrf4GqT+u3D9Fg8WPH51U0utK7zrD+Z7817phDtg34njpmB8KMGTO9P8vyMMLKMTq/7Ze6dvfSkvvv5thmXXAGHrj4dKuVICMsAjXkFGKE5H66Eucp7CZUVNhZp7uaDindSzA5LXuQVnDXtFv3Ib0Hz70SUXMuVwkffg4J4gjurXzTvyXZKeWkx3EIZlIncTcfkywjEUy+K5zV9D1deU1ZOJ+Yrr0mbtMg6Lm92QxS85G9c8pXrsDpH/ayvyu/PXe411VzSxsiQWALhf5ioNHuM5Fh1XdgXc7mGOKzPjKYi7pca3sKvfIS+3i8A784xK3J5i9zN4MozezPO9O2b4Hkos8cbpPwuLzI/ID2Hywdn5vI3G+vJ2HF2WrYwGV2FLdB54Ujpt8fX3msV6OdlfOWOp4Ei4Pu91g/u/FzQUFwpWy519lz4d98jL2mXY/CUt3gUoHdFqh9Vxz1UdpbRdXLc7GXdbNPJchXl/zHx1u5/E5gUz3f+fC4OfszRarvNozmPwD4xNPHnJN3TsCEwbfhIYiGObmJy4Nca7OXXZ3VB3aIqeQVL7Ix18zy6XnhvOKMazSTG60p2i47iGeCqzgOkCziMGDiswvpKvDSdW8wlLf+Sa9u5R63AtBYPj3hSKLbHIPKw1xG66xN+088U+no9jDhslq7fmEfqUHhyO7aSZMhLs2AB3YXNFhQgYVorXuLcGvnYh37OB8zDTXRo8V1tdVybeutA1inpR/ExU8OwY1WogTwjHn/gWPwkPnoD39oXvXeUDvkF6PVBr+rNDvtZN8sfe+Cqf4BgWKRgjsP4AsWH/iNZLw9/ndEJrIJH7bHINGhSqWvNBC0ZzG5PN9YdTsC5N4mXELP6Fo/GTvBvnttB8zyBZIsFEHAWQOP58jaJym48P/cQDwWgYaTMZUtE/c3IfgNX9K13HOptZQyDheQhZOPVgmjmZoC+2jD/QArEpHl6Nb113/zYyNl9ZrzOuardToezdEahpOg2jV3rHmzVI0vlQFbHRZqgrvvs1fx3//Yz8vw3JIqYALNX+WN6jz2dDVnu+648p+/91uUNkPB6bSZLJBJLkOGDJ4YWts8klmUsTOQI3cg46x0FE5oNx1pHzwRNyIs+r+RlK93GOHcN0vAKJhahCSTpoh5ch83sHoBHhjlr9SGe84tjRNhPiqK2msFFOh39y2wLGeELm27yGJBpGFPLpYFVeJ6k2wq1rMC1GEwOX49dW4ewL73Lp37/xhsHur0ogmPW/ZOTSRS35Ifss4r2SL9cPrRNlL6Avqdzn30Sxsp/dKJQer6xkyVptS7Xa1TsnE5zgkNCIHGXlcqtuHrKrO+PLW/imdm0xIfb9aUVuKp0Ns9izFgeGLJ0mAlOS5pwLMesfhoePcxVzmFt7syCCanWYMdvUmp3IgmtiuS7jxIgbNzuaQf7TeRaZs+KcNwWPohnvgO8paH7Rjpv3CC02GaleNHa0z31CPVbJHEu/hilmcgLpqw+oqBA32D25NKxYheq/AsgYJPf8EsKijcGFjy/CylroVKy/UkCrkmFmSTw3C7UPVRIz+aM++4Zszj+2P2PVZ6D5NdkCGxBcQLUrJ+hOnu8HoSTNWUs88AsnCv0nTHSB56k7Syer9DzOhAu9m9TtIuVsd1YVoFbuObuyRivFOCTHq5IWjq+pZLkmL9ussPFNXkAbymBnrGleLFI7CbLqt/LJj4PjdA1X8vMFphonHNbdy/7QGO+MgVR5UXTDIo8slsQ4SVbcA1ysHwcOwznQGc/bodIzg/dllNsYHoYIFpPec9GOYLyAlLNEyQapk9V0DowWC9BlS4rPvmx9xywr3qUz66a99TZ76x/m04oh9bWJRt2lqMklS1tFYV8X+T89djO0wtLowIPpXsDuPi8IEJf4iSPq8VI7G0avBc9G0r1pjh4zNwC1JjJXc2msd0yxwDQe8Vxr7TsUl+KlPpwnvh88mSTM33Qt9ZImX+ldL14bUcMZcLHWxLUhUDWmwinWi0n5hBDOsWLQehjcmy+eT8JPWMRsoafZK5RJy0lpD6w6eWUZ1xEiWOZvQF0zAiclKsjaAIxQ4T+fz++qgIb+d/asZjN3B7fby1l+xhhN8FVnHl8iVt5kzpjUxZ97RTiou2Y3Dnk6nBjlQO/Jbq7DO59mm4s8eeZZNfL8AHviIGYz1q/exDxzhwY1pVnZT1z+jfX+8eRNeYfGuxfioZ+PxfPYGLbD0LC6bx+Xw43FmBb3GDSYlWCOnWXGhqPQEi18D6jLlE4Tk0t/rsBDX1L77egO5/EdEVnbZLXQW2+BJDLqdbG+7q1jxM3zuEhgXVXqvBMmAq9suQ5bgef9KAYE0yimTTOtZ38HZGCPbPFppT8hyCl7IE5shOTLn2cY61GrAvw84rFfDix7E1B0v7yiTqSLjaJnj/Str6Tsy1wuboeAuVGmkAm5bDTvlMChtV212U5/InMGu5Mu418zKd0wJGkYXZwu+CRPxYsvdSpg3+MA8wHJud4h+JPMfm0Gh72x/sEJhCmy32XfPwbudntINuNSb++oO5qA/18rwvF/7ZrKhoQ5xobmCSl6PKMCyOvsiVIQQF9pEnz9DDB/vIz6Czsg//trKxYIQR+RBXQYLCCamY9nW3Z8Ob+l/Wc8JHiaPM636qJreb7f3CDBXH1JHlcgaXxlofIAdTnEA733b/wom4ikVwAtTvr1Oa0SwDUOcFHco5WHosa9tBJdROM41psFBbTJWXHydw7iqoJhjDpxjq6JAcf52kd6FJCfw6YryYApjaY20fyBphyK5TOF104SBgOvafb86rtPonQmjNcW0ITLFSbLSViYxhHnRcb10m1YivSnTcF9Xx8LAm0rf1F7Fdm1cgTOcGMSnCFpcbkG7HWptvi5LF6Xh+FqAcmQnBhOAECrSN5sXbXWoUdPp+M9uFY7Hz32bV4pnTPMMhiCwQe83zPk2Bg7CXueZOGfmB7EtQ4VDgu9itp1zF5pER8EF4t2nELrjvnpwnF+vp4dzQHwScSjEsgni4IuDj7OVeEv/uurCMRpnbusf9sQkz7/KPYfGnwvYtEO1cDP/l+LGIUHOpdrlAGyk8FPMpbacNueQs8Mc2qGmrfJQdhbSef/quenMSp9vRztt4HhVTa2znKjyZ28vr+WcK8m72eO5UR7Qapykf69smGOCP7o1aNbDQ/0B2uLAsVTSuw3E1rs44NXI5wjUXKQpQwlyX4oa+dBEGPah4UR10jCDRWyKwkCRqbZD/1RxD36tfeUZWLghD2Dg/ZDBPU0E3z8xGW2rZ7zc2M68rc+5zxmnKiHXUaMtUt42JbC4Zvv60Wnh3gX+zLvezRbcVZqqFg+kI1fksGBWe8Ufk34/E5hcyTaVpAeBKgKLE7zdSgXGrdAkYDv6zAhQP3Ml/Udx1OVT1m0mOjccBowlFcJ4kLN+ef3bIodwc9I1zJFta1tUtfheSgoUtv19bS3zbgfNqwubo+HeEuO6bRZDYOXfARg8cO57/GhucsCN6IR4y1E+iPT4uj52D3zmdoGjNq98+QpWcNJ4cLPkM0G0koy6Lu/Ty0onLy3kKBAEIK4zAED5S6P/3u3qqXg8Y+qBKy/sNRkXAVl851IuJLCv3M7nis8bCAQdR4ODm+KYrJNvsz//jki0jQS1Pak7/6TA22Kp0eXeQFvQNjDj+s8Dwqhdt8UQN5M64axNprVM6sCh4sHvp+bXJ/bcy8dNy+XGBRej0jJXc7FdYeQ49eDNyPjkNymOwUFLFLSbzPpLLwFUSRxBNdX2teA2wsnYH4Wt2k0nBEROdvz8wF3StiFubjvp1/RZFNXp0J9GlrEiLJuS+GFfAq+Tg6YBFtH+oblPRTgO9sSPzH+UvmQFZrmEkTw456ftzm3TTUp/50TveD9J66BtYtxwDnOhsDG2XDRt/X59Q8daqgJS4MM+7z/LVIScwDP5YoMzb0Ajyu2GuVyMPtQaa5dCNqmUbRqryIbKnoeUob7RfiaAosIX+6qFFKgnyu1wnQtEa+/dQadAssYjgRW/XxI5rJUkIAmnXol6mX7lOoO1AZpYhB/LIbpxqjCPWZ+E5RySPhcSv4KknAYO5MMv8yQ/qgKQyXJyY+RJwhmAFS1zwLlly0hY5RwJqHlEAddmF42QXZUBIT6kUO8KRGgd0aAWoz8GfYF9wf1/pv3/j+S9/9RvP9mvL/v0nuoDCnxKZIEzgwUZLuuyP1SrYl4ZQsCvTTqrqeHSrnFwCRJAy8AQlpxm+2XOCfklTqI9NOr7+WtSx4YWFTHdCBMgb7m9LKAy4IOCW32bDvq1nen7/Xsvfi7r9mu/M8fgDMt3KWJtEB23ed3W9xQ6msv/R+o37y3TO3i7/ELohbAIwsafGCRgxiT7nm4bXwN2A+OUzPLg/rdQHhDdK2lFl8U/IeKH/S+bK4PoYU6CklZlIMHAgWgHfXBCS2Xnuqoi++oS+AZVvFyqUObuAgyfoAGLI3gI7ni/dYWn+wfKD8vHHWWiN9Tfl9ezBc76JcfOVUEIdMkT/jAZ6RV9mFX9zuzjU219XxUcPevjpJ2Pkfm/Pgp1f3ceY4DDwl/6fluUps3ZNuvStI//f9Nzh5aTsqT2ML2BpHPqrkWQjAo8NoohJA+en/rWxDIe/vuVx/JPVDklyEKZpaGdQPRGgS97PyRvMsaDA2eurWoY3aiICENRF9m+VA5M5+RsZ02cHHVJP5dzHPyGK3d88qH8pWM1+Jf2j+8dqlfoAQK0LF2K+a5sU5uvs71dqs+1Byaq9Psq1sp5PJUQ7l5QjplKDd+STD6JRaI6mGxUqca0tvcuNuZNU2MW3CejmR+KzKr8wi0WUd87YZ+I6HRV+OInAyZAebkd3QdOtbc48c/K6xQNK+XZmqqIOqNAEeoNGBleAjEV4cAa2gIJAeGQE4P9e+NMVQ9KtxDdAGUtHXbSDYlDBzeMOC3w/o9MoZKtM/GGPmCcAYa1OWbfPhl3yRnVgWQ0nPev23CUG2gxMeoQcYpmQlvKWdtqs1E/BEQWGH1/KdJEgbxiQBwysCWchaQiLgBEFABfRd84xpxV9ZdLoYUeZPqjtH4qeXqBTtVAVrUrHoAXHKm9fdAM7SaC1zM0QZOGsC6Y5nzV/8uNaNKcEo14Hknc+sUIX+6md3j39FCad/BMrsA4yhn3p8CXX2WniAcfuwl6CWRpmDs1YRQ3+ElJha+s7p+NTlL9KX/YW4ULbEghnoYa4+Ms6kNRnfsU/uKnCt9X3cE55Qu1rX0sNj3YuPyTO9v0TJ1Q459agxmZotd3899sMaPnKECMRGMuHNAkPCDQM9BfT/voYXaoD5HsiBZABl330O2X8aUirOgMwUlm9kFtT+NINC7F1BQ9qUbVPf4S4h3jyTInx8gsi5PAHS9MAfTQNI98aetJMLZ73trBhJav7D6IufxPTuX4l932ggGHU7+DaLUb8HENUHDay5Bkx9kYq/Vt5cDj7jyvX/i8cLeRjNvIDa+v4snrjGEhEGWxYrFUa0KdcfBRYuo84b1luMeyk3kDQ9du23FY2VMpGzwTCKtmrZcdTIl9Trwonx+C3H+4ssLjopM8zaFIKkxGXku4/vZw/00bnVif7bPwPMkOx67yQ2vdlDCkL0/keFDmOot08Jd0v+Bz46eNdp/Urs1EvE7sURPHKpwM+42IZC6EQCZY8GVfT+OwZ4JcDcut2ZBct0lyLqxyB0heCZK/PzylfVX2tiDXgkK2PF35wL4PSu/XmnMRfID4uRvqPF4YnxRfgML/BAc6Knv6dBT6rX4jiKh2MQnLdDUvUNRhxpjkWeuYM93+W6XGi/yfajjPXkCY7NP+hYxxEOz/21lvJcJIOFWvus6qmSzLZ2aMppHOig4BSVpcUyj8Vc+lj4tu1U2yMYpJHPxEPZAixY2JI/sYvts1HdbVgLds9j1vlI1ssyaZlGGwSZMu1Tt6D6orcq3IOlXUsjoGJXEIYl1j3NHCQsuzgWI2rmpcBIg9eiOn+anzAOlLO6ge+1uiD7sVHLjssoD4vkrSZ/uWeCDhokY58tQ9hoo43LV1tw5lsVyTQrt59v1BW2jtW278ARsdwdVobn/umZWq+K9OPMb1HE+Eu7UfnQL+DWcr4Q5AKP+IUfHNrCwkynW2X/HUzrG5e9diyQnAHI1Nc8dDqDnHhaSzelndq4RvBsMFfXnzdR7brqeCl4/aAVOLf1UPz55wFr2UJNyzd957MKKaIq01vSeynH4m3v4J4oInFOypIzE/rNDrwPMDCvi5njOf13yrSnjo5q81+WG63SxS1f8bF6pMOz4Wg4B5937PYSZw9cajEO2aGbN+J5nWPSmp/FlxoD1C/Mxgf8gXv80Vj3orXV/epD2lcNcLNUavqUlPBZ9IrvylWpKQCynTID73sWJTFy+mkdNdobHmA8R1dmUfLSB+JaJcGohqKsFmVPwgiy/fh+UQCt4nM/ykvioFJ9qHOrX65xPRndnM0WN+9w1tOlGOs9xHRtXL/XTOP2f0rnMT3H6hb0xQeWq1gwTFu8Jy/WhFelxXmpWFjEzozIwhPtQABtNZI+Lw9ufWa3Vdqi9o3gs5tslZZ8/irbH5eOFFITos6/+vXfO7fjLsrK98bL3FM+FR37cH0smkwINpLa4G0WGhnsJovJc3H0oIjCRuUgxRM1BEdlqHyDb4bKYzn55yYQQIrMjedBkb1Ig19ltczwwxKhI6orLPyKcRaFF5orhrymIekDjiUBXUP+oQ9Iuq8hMIT/e+usGkdCOsVJptsBEZrr4PAnRkSjgMBYvj5po45HQRs/SVr5BaVUMEdsZdZSy16SIXFf+TCFRlKh8Y+oOlIKW1YWWd+kkq4KgUyL1hV2SsNmTCug6+SsbmiUIciG+aES7DDcWCe0U+uOkqTwHRfwQtDgLfYpLLqCfYf0jT7nfH0gTkdRG88NcGXhWOUTsVwExNlCR0s/8MgxtaFHZZuSIVedgIjOF3C9X+BoZHHg2OnidARvCo0IBwSu9ccDxGJk7Z8Vktn0FILoiEWVGuqdAzON7qFNh/UEwLrst8xfibYGnhm6AG9n5cOpFvwDg/mGS46LDfu4BTweMFw7QElFaxeXCn9FBhvejeDQNLetR5BxCxqZ6iC5lvv2xQIHYvQElgQDy8+aw8DYOKIZSUT44+cEE7KzqXNJ2tMW5C1DWwcAqTs5ksekHqDPI1qHRAo5qVTVXc9cklIEloSikhq3sWiRbljrPAwelMKcc534vWVzt1YhTDdI9l9mwDVYjm2/iJUJS1hrVTJ2sunGDabvsJcQ1HpptZ6nx+PGdYY2nPwUkUQ4lS8Tjnvk0C0S8xoG7MBPya1ybM6ZbLR04cN7/3VXjc+lGhLA2lLWotLp13mGI/uQkFfNjP1nM2PNqzuQ5hSdTATKxqOq2TuKn0CjjKQxlPkWwUOUhcw8R2ZOHyRZ28RRnW4E4CBtgxYLqdHsA/nR9HdqIeDnWSN/TeKCot5MJhK6IqhpsAEJJztvaZk41w4FMeFUgG8PP/VJgJhyC/K3jFHPSVXODb0JBbS42KXoUvKVruBwU342CkjT5Ki9BEN+jicJraVDz6/0WdM1ST3TIsQGDVLwRDgu18aHUKVQl52BOwzLOSwHd0g1xxU9ZdWXrSxcV7mXzhwKHIpILzw8AAUyLQpEMzqWBKHCiQhYrqeW5i1r4HVJzu9nH5L23SZtDUXt7rlaIHa8wokBYgE6va8UCD2XjxV4dycKSBvxx9ju6hCfX6Xw/Hx1r9+XmV7aiurpK+lneOYIAv/nyE7LARbYFYUNzzYLBcB/UfbDxdjikKv1hda90Z5rhNDgsz4zVMNpAihRR+mPN9LZO8rbWEtZ2WUxiTRuKCpyBSlkefGngGmLne5EqEKblgny0MMf+apsCWHq5JKkaJuR0UdEs9amW5qg+EYop5A8FWq8DuLWXKhTyONXB73d3yTqKpQihkSxAYi2XlflhHAssNzUo5k9bLy1CPnWzuoCPeVWViHVAVaqbM2iq5hkulP4SOlw7cRmcCx3B8nxoi6kwqHboZ3RZC9BCalIuUMJ7ljC3rlO83MEGb3Quy2i9nQnUz8FxxCrYGKJN2SB/RYZl8NlBDGOLwDiIcU7L/cih8awPsSnCgi5SwhW9oo3dGBGo9elbC63cYOu1cp940k9mRelCSfR8Xk50E9X4JjktXiV02yBox9zx9gaYKB5xPDe7VeyfGkXdMFeRIghsHAJMJTLcJMQairSB29luj7tk4DBQCfsjh5XwmB4DvxyLQ28VyF1tmBXOofV3ZPKBdXhk3ljPxgI6w4FGfOdf40Y1gWqkhTdYX+WhG9H1NrFrt0/rGHR/Sf1tzMl3+ZyvrjwuDsIk6Hv2Lla3GpTPUJSvlv/CGyj0N/plXV2WcRUMX9rqiwItpMtCoDf1ycL1I+dJ1HBnBy/s53JOHf/7Y2yKOdm6ob+LT39wike6atNW2nJJ4U95iYmhr64zgvCHUgXDaW3M/U9x6Ygfmm1zgCfR0tNoPpg6318LguZt38DjTmnfEdKTSseGLKQMH+bufSEqYcdPCwISQwaymURRWLz/1CB8Os/xx9ZI3H+UShFOAHU2N3Dw98QBoO6b8xz6KK5S3U1qgDsImQxfxx0CDgg4cMfh7ThQ4MAch9XwCAlogs+WU3JGdNC0KIU/8otcwEJ2JDtHDlkCEHBIBN6jIYAdBb4OPKkEyxOyz1qs7PvzejfoVacxnCenRdXm1TuV4EbhSfATRQYQ4KKg2+lhKxDvUOS3JrJuq1WPK/W2TDqW8RghQds6N0fEwr8M4QherJfRjM+wdoTFw24/uf1CkEHdDiAlfvdGlXuBalOUYBIX2+T99G7CZK9J9fn4Ccnr2+Ivs7tdDZB8odP5jnY5+e67lIEtceTt7zYKs0/Lv9DQzvtwnxTDSGzjkag9rn6brPgNq+SKXnkVBFmPU0XuF3Gd37rlXDkhHKCedFAQcVUJO0JYShyPB+trl2+yAg1OwGQmH839qC9u/jAWcJfPtIM/585v4dq/W7nQ9e4DfbyVWtO8BLsUUJNY8RPUNY3ZmyzvVpOo7LGreHto1vk2z9T5i8d2qsEKuLo9SHBn8X1IyDa4CIyxrvCaW3I8k286jzq+LP4QG9O3rExzztxQqC0bRTcOfxyJ91PmnB+bFRvHToAWCupEbExWHzDtrYfwawHL354oZsg6BixnUJPk0QYC3Eq5VfSafVCJKbntH4bOeVDYr4PaMeFusiRj+NpZ4pWlRbEJNcfM3g1gvlMtrD/C019fX2F1NJBAW9urec+HDjGN+AwxTqqYmMdjt7JE2Lh3celZlvvMzXwijYfNBjsztw4QudHKSY7evZK8k1uXs0pHcChoKDHyI70JYc7vSvai+OFQ7w0Y4YP7YAUILieIUjZqWebfWCbU93ESuh/DIZ1e5/HqzGI15AawU7pSsxploeUqG4aVUZLnYjP39Ed41YhTiP5saqfNPOfD6hacLsyOY1Nj2FEfCwG/QJsAwjl7p/6kkoUMOp5D6ovZoBMUiFMNQSAiWs2IdwgJuleaVc0u8jyfuhLim9C5p4l3gC0AMRld/3UwRLQFkOeG9z87Dr9uhe6XMKwaEONC+fzB8bD9UewdnSMCJJIscZYKubRc6AR8TbgScEBOb7DmhVwJrosMYv4KQ4PlLGN1RCY4L46b0q/4nsiOX9gNroYVuLi1wgQNyVt3L6AcXNYp4foXGFfCXUlMSiDq6eDqYpNt9Lrh+aStDThaxKRa+HsAtWwHNDk/sCTi6ebWfFeGn/wf/2MwqnZXJWZtwi99Pboe5VNpP18P/fHNYbl+EbDHWt/qcfh0KNeX7e9+syrZXL72v35z632qtyHGSjo6GQX/USx4VSzxx1dP+4dh8yWOl0/max/1vhjqQX95cLctrpq4VSwSlxXT/C2+anvhX5gtedSmNMWD6Hj+erHMlCfIx+6VwVjwxGrDCag+6BHq2kaCVMINn/NFSt4ufDE4eSMCHCpE2IMRMJJrNRJU1wHpUptBdTM7/IofbWCVvyKXeN83skaKfMjysA92z6493NdNZlqSIJhUTyx9FKyQAG9fnkSukKZs5rgPY99MgUPjI7Y21WwqSvK1+cByLlXjW4bthKT6CsM6uSNRL1n0fbgTzibAIHCpo4wO5/T44OrN/h79+7P5eKuR4ld2OJhj+EQGNddJa7JNJZhiwLB8RS+guQ6ApOrhFPUtA65v5RrWExh6FLcDBDq7uf7kCCY9E/8Rkp+bLH9ZBTZjPoKU9P259We7WCWhVJGs+v51yNAbAo2m29o1RAlZt+QTD+FizI6rw5eMHM71Ncj4ZJ2oRuzww4CZ53mPBPX9nn3uQ4RSNBAqfoVlstsUOAq0017udNjyx27/+GulZjDiTrvRLRMYzqe0ziNLwGHzzGsW50bJW58BUqpr33l3COWrm2gPsnpvZ6QKB2kXjLQgDjbxXpe8/yfb/hY3Jmd0S9JtyJNgpbYXn607OgveGOz8SpdUNnwu3ZnsusCnq7JfeLsh2OeR7QJkuwDZ5pYv7iYH7icR9iT03ijincMxPp6ql6EkA0rvt3qAMdIpHqtodXloR7j0HovG8yIIRwBkmN7Z0X8OcbBkjPs2+tkoQFVcO0cuw16ewX8uMnbkjJyOQitUTYI+bkdUcQS3Snx/HVCpEOZ7iaK+j1Wmdix+rJ+eqXXd8C/GcHfenzppRRof7OkihAB8Epv0wOlpuG4o1XGkkgL7vhCnYMIO+2QqEVzvBosHqKc1AYygVCto8NtbUO6NvK6G//cFH94G9l1rJGG/4yC/zPcMnfvlMOemQBCOPCa02LTwu5OPv56/uI4qK/6uKptMVXlgo4AS1NY9WVqc6LorDs/Fp1POQVsBUSae55j4dwCKtCLF0P9IgEceH0TIun1cs7nTuX1AyVZnDDdQMN4iE8PguN+p5KE5Yrw00Ud++VE297NjDMUr6oLJfD4enGmT7yoXZrj1KIxSdXIqRqaYPEisvDIoe3MYq+reKfI2UzCvUToIjK9UIca1nd6iupSfudwcIRzAqHS8keKTYNptcciLqgoZNaTCqhtqBKVRos6/2S+qCr+ynMAC3eqaoOzBB/fAHXzlIQDbSNeWttmwiThGYg9gGcyZ33bFACIDucd2d3HFDHZ8xUtCkY9xEMHLmPCopyCGaaD/BEwwwm29aM/ScXDyGMueBTKTu59t/HAsG1Mw6hQZfX1U+5nMH7VTMnb/HumN275tp7t9oRkYfHAl2oFffXswYTluFSLYq5TylsidcIDw9j0TeoEmO6F1/wreJ/01NlN2CuVRfKiNdqbEejklX5T6XuODRR8KFWdpu/KheGBHoYHQC2ENa3FXyrrsctNb5fSamyW0cYdS5c1zFcyeqO1EcDXQ/KB16YoZFUPSWOiAzHnrfV6Jnxa3NTXb4pN+pqckZpGc8S5c2Kabp+nYBwxqlx7EMpUbgzjvhr0RDhtzG7Q7kqQxoMfBS2GCtQFgESsg8jz6nT0sihZkOXtHOzFz/4mu/aVJrWSx7su+vLHAne+JmPseLcYtsMyLTyH4oV+raRkJzzeo1DV2XYAWQTmGxn+vVe6zaAFH27x3iiMkpLyUUCgRIlPK6sL7b22OXJDx+ttWhImlSiP/LLn0Pw2+RPVamuKEn+Nbra+jNas8UnaxWdS2M28xwQQt5Uf2p1aZcHD9a2Yktqs7+3bHUTK5RfO4rhC4p3Zz6YBuzclDrDWupxr46NrqQ+LLYh+vBNvElG1Iom1WFqNpk7JIpdrVXOpHPShmBlDC6FhiEJMzNn6RtgyaqRUlwBuioASg+mvNCzx74OMgapEn6WdBGDR1zYaMIGsd8toJOYcYbAATjOiGqFNH4QbL4wHVh2f6QnJfkDA+/C/HjnirE5F1n0JqbEZqqLHVBp5gi9ZgvNWGP/cDdATxBltux8+jKQKRR11CmpuoBoLUOW9bQBbaDjlaRHTO0w0mUBFC/itMHcGUjoKgilkOESFW9nIZWgXEN5Y1eJjqgsYSR3bVOFgjQWkJjgOayFegG3qxExMVCCQhpek+2Pe+IFXqFqQrM7WriDBBMVEELezNH5jxHA2ud0Qe/TJMV6hFo3SL5L4UwzURHw5SVeTV7CM4Wy8RtsFSvWNu5NrDxPQYZZ6m87moxCq3Y77WtJ9Tdm4eULQtc2tdqS70s+i4HocinhaWSx8s0d+Z0fQKgA5hj3raomfDEeNoxsZlgf46FC5cyCbBFDzrSRj3kh4urMxXzm1pAwj4PJgYrWoZJKygDtZXNACYZA+dzL2v8/NcEO9FEEco5qbZ0RgnDmYO3Xzm7zovX6IDB3pCFzC9A5uDtoaec+PjoezhsGZVxl0IKhWE4MEYOuastAAo0h14dkijuYkmOak3kpBfgNFuih3aLfjoPtQJS/amEXIczHfqAlCePXzQ5GOoXuHZG8ZucHl7MhOvAKkhG2bMXgt9dbI2cOJdDwe2HQqIPcfuDJxpJmQZlFkpPlnS/91jkRC/Qo20RhGxVLODhPCI/TkZmXBjux8CqHDUadTP3XTWZ725nk1oQXpRsEPmpTWOp30tO0TqEKEpDSwqUuPuw7U89dPlJ0RgLBLH3IsYB1XIobH2wPkL9nErX9ePQFZ9xcBQfGrxVcQh2V1LfMliI8baEkKrt8f5JsTCGpT6w6+X2Aah9QD4wMkLwsPNkQgp0riV8b0PQmdjfWFby0k5F/Evl+RUM6Q6OQWhN6DYBzZcgdEQ4AxWZaphG79O7geQJ24JlcEj94UMp1EnqJbCmHlU6tNwiRY6UTnjTBG3HoZqx4ZBnOIKUCTpwpZA5Hy4ojXs6AzFA/a/WrTCQ5QAZ26IOkROlEEF63aBBjGDZxO9wt7Wy8qG2d54NWCDyNbpyA5UWhvXXTmaWMwVIpZZKBjFkF7LnsDBqNxJyghxjXFz7nPNm26SiJhOLe/GkjIp/hs8W3Mke1+jlS53QRTItz7KjrMfWOGxPWpCLVnY5rFtQWPEG7HRdBPKY0hJ8pssdiOeRPnuXDP6lS8hKkwS07Ry7yoC8aoJTnj+X/Sqc5OmY6TbXFGc09Amyao4nhS1y1u5mC6CN1uhFaVvEg+BjzcSWZzPaAfHCqdUsESFjXNNvKG9DEzN2Q4H1hsEyWBwpLPXh8/uKtZiJx4o12CFBYudRa4Dit2lgkpLSuZDLdimXOzgCo36I2CJiH032cpSRNE48zxba3i5LXNad/utWJ//axS8RA0e+In/3Q8UffjLKS4Nj/led6gn3b6QL91xw4FNxa6hoDqsfPi5dSXE6c0C1Gj+0B3bpVw4feqtO8cMBUPYgyZHcTlSwu8/iEgMHx+L1+NJFbMd4IVyC5v+juEiCpl476Oml3HH90WHixXyrm5ODKJ8DR+pfbMUwm3cuQed9QsVGG5ZLGIl9A+aHJZktaxyRMTdYTN1DVegiy22CKk5txSRE7y54Bx5/YN169ies5cDcEHGnql9d9fde+GROLV8bA/A7ZR4zGP3YJULETQtCbINI5DKCZFvVKFj//GWR2okCiFxwA2DpskTfkCqRum9GRrBmTot0EJogYnz/s0DCPo7mmZ2UNvPvBfP1axW90sN2bhE8AvkIzCDDAl8fce2FS/hIPRv6e3dJ8pGQXQtyYhkBz/FfdwEyoRqxc8Gcxv2PYw6LE3bT7FRrE44hVoOpmXp4woD3xOSLuXpDs6isGFA3d5Yn4Eh2VYp1XdIqWdv9qFcUKzUy6GIxAb+Li+mALdA235rcqW63n+AqWCxODuGUu9IKRILUEdMG9ylWw0f18LEJnsB7DChPvoKeXN4Q/+0JvQhaaOF/NhkcAxuHMpdYRMCvoyZbnucQYrBwSLVA3sa+x4eSLP3eaft+JHE1M23yQ8UnHRRjjjrYqHCdPkUhbU0T4HW16AyQ7sGVmn7qEyZyP6mojZJUeFuIKFwT3W9GzDtjqI4kLg4toAMuCVy3j1vkLLi8uBQ0koNisMbudEAJIyTufE15r/vKLFvbrn52QSTKo9fWvjhOgLHhvjg+wB5GfBXAPKjOjsvRUed3VOPRm4ZqtJUKq86LTW0moaFg6KGrUQIG2mPvaOutX/KsRyLeIfIULNjNgt9LCIlMHlwBPoza61zF1iCu/mD1cmP4LZ4kezPVLmfjrsm6Y1gZUj2BCZAgduoRHxcqlHtNruv57NQpBIaAjduLIBzu30dqMIcTattKY7ZB4Qpszv6n0OCmim75jGVr6gSBoWo47EqU06JEyKvcbezaC+EmQngo/cbEia/yqUJaxb93aGEB9RVroxsAZ6XoXYdEXRghDXYhfF54BBWguz1KF1SeSToPY9sQF50uWhtXvDAYsWONCphCCamU6LrMyxAsDj0oAU9786zrCQQsIxkC2xb43zgtmHgG4/14kAUp5SqGD67BLDDltK/+u7NUMXxWNFeyH1As5IEnFe5HQrwxhlrLWm5iMkc9dXRLUJlGWFuxDwed6xuHlmdCU2aukybrHCsgigRHV0rx7puaw3tfTZs62esH+yU7Qj97cS9Kks/w8bL4s0JMyW23TNqb+ncoXMq4TbBm5a3sTT4acOlPhLkV0hdsgFWkM6EDBURjmQ5XwtMlvZW7okTE3raE90eqBwFGOjqzXccip0n4wsBOs5Ivtxr8fwZUzJNwIH/VcXqTtRcPRfiflgD6MoaxboB8Y0uoxf7qdBYYBk+FnCweGiF2QuLpaE6yKOQOWyNtXsKOcmD47WPFmKDDstJdLLUiGBE9f4nkl1VhwZL0vmFIcwMOAwsGB5vuiHUf6W95T0zgcg8W2o03JQxH4Ww2JVkA9enNeratQ3uW8bPBBI9PpixJq1/Mz9RoJwItlMf3WtswaakaYGJo6S0ZPHK61gjFKtEQo8X7INo1sj/yG0U2VA//8BPuyPTuzem6k2VbVkVlcGFsBmKQtpJ9UiKnytF6Kwv4HgEhE4wNJgPRU8ZCne2prqhft3z3yQbd6OoADyZNUXTf9Va61wcFWEmNxi9bxIP778XjgEXcwbz9iGKgjDfkC9G5pium+CarOmpbu5neEpzm3CFfBtyQRMohksHo1bsCwHSZvkeTxB2CW1B55yBrav0BHp5wSxYiAQH1NVeJfx4k6KQ6nu/sxzuRyze8KxFKcXOrBz57L6/0BRirWcah7QxV1a9h+9cmL8hFmRcSRQDswvYADOKodBbymnh2z/d3PCzN2rFcxc1uSRidRpHd4oI9hsL3YpWDbJFEgZbIXe1rTgqMHbNNJDaYBQkdV/hHekBGZElwrcGBu7Vi2A3KBxqZNFgT2XEa++lgyQmM2plQioOsbF47+mxt1LsdDKNtkcMr03Rhaxka2siu4SD4hVhcwdLdFPuRRaHqHtb/C5n3ONC9r5V7EE5+gG+Za0zpO260iQErqPq5NyqEbeekwds4X1LE6L/fV10Poer8T+Hr9UyhsBAmAs5THx8dz2J0x2kGlqDO7tsvTf4sMn/7ScFvDiFJ4CZq4tFKdflT7b4w/kJtlxqsNMrJG7byMZ2QisURpNX017WgKz1Syecggdyo683nDmKlfGEBY7sBAjerR0DSN6ETzpQdS3jmkYOuHfewuMS+8Skmcky+QuZErP+AXyF6HSVdzQu0EN7RpLZNjrb1kyJgpOwkjaZqbCesWocS8VEoGQXvhLSYkO4LohI04o76gIcx2x+eShjLy3/H/LPTUnB2GvTl5saXWEyJ83QLRRdaZwf1U1oCiHB9LvI8W11zZ8zAXAHOKYrBvBKwDUOxcvSorsQJsp9FyPU9wwYlfVuo2sxq855eziSovCeNKY5uvCFMzWk02zrhyIlFaXm14nUX3278hWWnoJKwMuMTY5XLGlvr2Ju0CC+ZEz7dBZ12mfNAtFRg+2L5uYMo7x1Irb2DqcQ/zbCh0/h8+dFVmyo4Sk2NmsNj6wXjQoqTRSmxcbFi+7YwkNgNVq5fzkgA6v0NPzsZDM1hcItKa7cyC9LdfuJYx3VyvdIvhEvdsAnQ2Tk7FJzcwQqy8w+A4giu3CREou4SmqojNRmT00qmoT7vxAYwUM8gKeO9divnP+qZl6FHstKZlOMdFlOQRdBIgYmkoCTV4k5iX7CoD5dD3fqQhxpzT9/s3k+7WrL+TPxKyZ5fs2m47bELFGNJci7lAKao3lts5pBCpP11kVCrT3j+OWY8c96R7nsEZoQAZKeigoz5dNxyF4dNKrveZI1VpcyiITr9XrlfibGz0Gtx/jMLp6LJBnrW9jzlzfP44XVZeDaKLfazB0LvTL/G7sYA62vgql4nAFUd0/v5XwUJw5i5/ZIReA06xYMm+ZtSo8/yJXUY5wSCkytCHJ8yGYVVPTB8hOe3WOvAAiDD22AeZtBkGktR87Vy4woo66khcLA0bfkYxm41X/UD5LCsdLJPLK8VJn71VnDIvj6aK2hx/HouiE0OWkc/iu9pbHUeJC0U2G76aCu1VqGenRCzW20/VC7Xeel4xc7uwqdnOGmQrQpoqeL1cqd+KcnN6XVqTnN6fvWj7GhS27uaJufIEN7jc7OfNgqFMKRIxvPoL9+j8DBZtt6Eb+CNEP8Hbcc3YAS9JErNhTzxZEo8nIl+bxIk6guW8fMXIv7AGidajtNdWzlDvqeGv9h+U/FwA08NGCJajM8iTIVoKy1zmqS6vOyRhhvFJZc5IFpd0BIIhiAvIjRnSvO1eju7F4XTTTsHQ/Pw8kvAvbabQFqN4hPidWDhNxlTyW4LyrxC49mzsuLKkxAz0tk4uDC8n6b7IpDdqpeWaZUR9at8sDKExUVqY6SGoVSjV/TgjmbKhFKr9kqrXmNnkrooHf+fFFMAKDSxlYDLL/sC0uUHKbexQFZpM3E/Ez9Yn11gmusiACEVZw40gOjoZrz2BTOQtQSOcbUSMaDoh3q//O9FKoRqEfpWJdXf5wGABcwy4DmqrzhjqsubqSDIhY5AU6OLiQxh1AO7yLpFLhbJz8zZb6FHF0jUrloXo5+aQW+4QFuaqX0qEshzYsYqWKL2nVs8/Hbs+fds3812ZcAgBSh9fOVB7PhMvdPGVDWFrkIjMA365hRyHkI7vjJiFhLBHOLA9gP2n1wJxGpNuTnZo9aRi+Ey2N5WB4xfejTNG827l8/KwON8W+PTDUi4TmxZlqxUVUett4p/po3UY7NU9rDO03SHuYFyyJ9KLDxZpOmjO0Ysdi/giB+PQgMHfKTJcUCGnRNk11Fou9rEeyRjRizi7cznSodVIpem0FJfrpyb6+CgLST8ADxfcm861Vn4Aw5rrI5v2E1XoyE8y4Utf19ynDUWOWo5LwTem+pGwZtJFKW1HQylyPoK+cwL7FZ3Og3qOkU46MPvefUMT7yYJdCxQQWw5HGAUUxK45HnF4+CReXFQ+uDQa8uXt/CLBmbPNHi6P2GtjukPeyFPGeERToplEgVF7qEtqRGvwaxUbGZ21leP6cE0hASzsVZiUmSxJ/9mxebPcE1r2j/rgYCm/pyrKYse6xwAJVSOg9VzT3UfDgjZKsAPMwtgS2BXxQbEvRsFopRDCV+qSjqUKSUt9iIRxR1FudiMIJ9xkKM71YqRpqPADqGbAApVpUyIPnCMQhFZx90MRVmkO3/U9lweehXKnegRfmjlf1zumxg+7z/jiaADI61y3A42I/Hx6+V6L4lPvynmn78JqKPGjOz4cvZG8ChWjcALFA3fXGUQsb3nBzIc07R1IMMvI5/7OcJ48yeOVtAjFSZTLIV820Wt6IpsMu7SafKmo64hMUZKSnBwJZcf8wTeWJgPlNgSCdVa9qmFoHPoLp4Cghotu6kjwNopbZGcIXHwaa09jAAqPp0fUucOA5udEKSIHubxpHLPIcuv3r/HMNEoq3f7kZzhBiRBdMnzCUjwtOIstu1hfWJYRfzKiazbdkDHkqnaWbhtNkS+8dfozb1JsfmBF6TiAghM7F+QLEI+M2FNDFIIOyMRMP+rFQRp0+jbPAWgePUxSRuaR6sjQpuSYSYYTUrkXnBnNiLr9GKBwyfblmChry36cGnaw8BTzZcQ3jS4Wgpu+PHT7pHX/BLSSZYAyBBol7dVVNY4iGFRgtH1nq8vhE7ERJHKkHxSNQCTxIxMMnT0cuRfSrKjIQxJo4wsL4j6wF0/RZmRk8+rhVpC812TAx/Qvp4Tq2I9wk9EntRloVsTzVmliaOiLSUUXI8ISMMT9heStlkmyINfgZSg2vmoVISv0I3UJfo0xzY8q+SnVNGXWUrQlezdXwOPoa9xPTlkdWDoGk1NjMrBknAl3XDwTQn0c+Ds46kgA1MEKm8HhRXGdSK74j5Xn7hysBLSEiJetTlia5il6iodzAekhjWZEoEbS58veVcsPrCTbNyFpkiMNtVBJcamIbq19DCXAdXz7MaXulc4umSgKtsoEpki+nWZErHUok7M5BvPEJnkwW70ruIoTR/nwYUgoRNbTL0su6NM0Fl1iAu6n+kPHYMbBo7RGq2D3Ac3mPxXTCGrjuVyEWVEuilS20laS7CzzzmWQIrYKQDRmZn6DAJBETA9RzdX7YNEIs9QXzTLcweDKhsmxeTRVsIVoNINqyOgumSVVhJMqUrzYBeJ2c9rbdvKqRmk7RVNGjbjZcV1qhejw1E1Q7DGThlaRVjYhIXstacj9zJJzwgYzMiCGkhAjCoAsnbnQTluvXaVQ3GfUggbTdAysSEkai/NAKrWaSvHihXrvnqTmNaATD2CI9eJA1ebHQ8OT75CPb+P/Wj6gFwIWWLiohOHvGHQXCcC0OynbvFtpBbt5HpGA2MKEBDTW254s7cDO0QEJ0x/ZmelWm0cxhjapPf5ko5CSE5kWk5G1CnQ7L5LSnpODIVP+60hioqse09UQ7I7cOFCmiZtUZwO8Vw2OK3loNTQ3S4rkq7th7SZ3N+ZOsqI4eGfVs5aXa9wxKn11SAMHK4lPiDm6aj1tHTfMxj1MjfmKeKHwhiEaDqUIZwRFziWZbkSRc3NMqC1k7c41+HEyjqy35tNV/ZlG0mZt3CJFVm9rVtQrpFiXeZDHBJ6uRYoLF6l2Psx5vR+68cOGIHj/2lI6ef2Al+5Fs5fNNUrEm3i7ZdnSI3Ih9ssICu9aE4oBYVkAVLavlZzdJ9p3cidK2uCloTSUENDRw16lRNthR0qRdSc3N9JuiD24ruXAeddv5aQR51rGtS+mXrLytboba7cEGXa7AqXAuGhYNqu+YsqO0udXx6+9hSyN8oBZ7vbR66l2Wjz9373iG/ikYR0sJhw5APw9TgerD5yq7ePEkg1uUdJV2j6zZtTM7fIE6Lhk7OQUmlQ5Ju3mqh8PECHFu9Ai77nJKbd789yWWJV+q/kdLAKEJ2saJr+4AVwFxthEDuyKeWbq2+Sc0npYLsOnBA0Y+imoiC8cnb9SnhAEudjTNnb3KpaHAuME0gdeckaPCzr1qyRZSUxsvwYvgZoIsSkGLbNCmAh5omJUmMPEUrtHEo1zznzAsw5t1p1IAob3B/USMRZHAMVSaoSvfWgHb5YRMYcsTsrKXK/QeIJZj6SEa5x/8vfnRKo5ms8uimML534e9qPEtStDkR0cG/Qj+lgTB5kbhPS/hoB96o9VxTRv0cKMHgO3bjV1qOUsven1NM4BE9CCLIgkqDly5DqJUTBMigNp/xJ65HeS+5r0JQj41plMEbfoz+kh8mieAsxlILhlMxSMtXA1VSbzA7xr+XLQy25CUJGhSfInlot+y3QBR6ZqOKXb7oMlTxUO73xmp4XH8ZgOsYGwxmJ381AbgfENeKlqA2mXhozgcz7t8bSzRZVndwEGDZBB2nBcYQXC59YxvIMRt9aHrmOq6McFeDDBOGJNnXG/MN1mfDHGJ+2GvfwPrJXwnipetyxKFBjUiKWmUeUPO9Eb4vUpsy74fCHoGa88L62WTrPkkeBg7oyCu3bUeF+dgVzaIsTZs6kOs/JzA/tIeI3Td86jugZ9Rpk9AQrybo2GrzOYB/dgglhc9Aoq7UP4H70qd/42fubAez1TuzTe6pC1PUXGWChDNi5Bg23KWL1N6e2uBYp/bHqjHZScu2gkRPov/2ANFVLd9aGVO9isJnWiSbTjIIrv6GrZhsc/KxqudRFCV1UyygMM1pAOgiArogCVYyeejDDL8+XSw03Gy3goAuhRT6yJ24PiHBhIBqbnIumiVpjZeohQgZiOwoy8V9JBD7rLYcxTnMKQLhtt6OqMGa2rnb2JMtZreuxw9odQW8TjrBBLd2nJhR+w22uMWjTIXPOtkl2DGyrIHrRDGwSt7NjwSev1/mUpU7h0oNHlRG7R/GapM+4Yq3yV1TqP+YrSVwusE1XKv7UtAgv2dLCAPlE6d8h91oE59YtWOBgAQpaJuYMyQ/iW26rxArRkOOWvob6Kbug7qc2XtT6Ym852Luq5pv+3vJCp2AUXTgRCcYPqz8wKhaXzxTgyQtjV4pSjiTcspoBpeZCefFse0DxJySZZNsdgkCIHklDlooSv5CrS80XHKNhd+V+flAL8VVLJ9RRnf6hokZa52DrdmGzZIKM2TOpI8V20q3DyvgjIlm6TMpqo2BkHUiNOO1rSEQs60o1XBNpskAV51Ve75y8HS2Qlis48qK4QtYYWqArdqBV0nPuFSaxbAvs2mKao382w+wt+BAbhccrZWocrCKMGBFZRyoryQ1tjjA1EAVfHtlOkW7bMIKAStUbw0tXI7SEzRQ7UyUD+wH2mftakwusfl/GztC1ZEhmHgpo3wmMcYoeiBQbjfk6BdpGlhfawyBSMUxhgO2Wk6DnGGvGTx57vedijQZnSsoS6FH2ppLoY5zr2hgap7Zw/T63k0TC11z+RFPYmFnJIieHQSMvz1osyRnDsYkNWsbYNCv1jXVXBRfmuumD3kNm55lRYZF82yPvCbZ51PaXbwDuNYi2rS/h8EWOpBgCj0Wmwford9Ni2bevHqVNrScL/XMyUTA/Ku0f+Q0URXHhGHZsh4BPw0gDPcUU51x08DcygEI/OYb32eKgVBYWmhs/9+I5H9MgEj8q/bQh0IX6n80ja8NH9oTlW4/LAGYdRp22JU+NXSGSbpBxONMMiOBOCmjKotftcr6JzWz0pd4/hxP8CxcmlAeO4Yl2kV1FvXQh8DfbDSswLUA0++QUAwnXnYDJEJS0mwRyfP6oALQp7L8go84AqY/lLk3AnK9xAme+97PvzqAYx4uN9tgDSr29StBkHr6YcxNIZLBva38Qzirjd5POuykvJ58ovjWDhyIkjrxgCIa+hmMpDXvT8iYZtu8vfXeexcxQ9x0cXJJJrwWb0x20hfYmUnygtvyTLIWu85y+Hdxl3xn1VkvY+Gxj5om5POZ0i/MW44LGJgepWstbEIXamWXQJYG+/YWbF+ZV56YZrQRI9n6aPn8bSbrerxhTuhCSPwVb82Mxl7E1ib3i9Ng0CYn1MwAlPmL/nZZCvmZJUN9IoQYpkx+SeCJWYgblkayc5043raGZ7RvACa5lM8l+eqvGxSxWncix+rLLQKoEn9IHdwnpcNHcS+uGBpAPHO6GgQWsUMEsYUl/KWRbWQOPevU2PjGDDGJsbwJQ6pk7STYX+NUgQDq3Xv6gBru+2YJpWmogEE7MiGmPVpPNsZwvyDd0Es5TRx3dDrqv9uxTKEpjMIdXicpUekywYCjDEBsNXrk50Dce0NANkNYqAOBV2rF7UM91RbAL9HMPQTs8HIHBng5/GcV/AZUmlC9W6rHaJ6T866l2EiZ4I6mfepi8Ap9s7OZodQUcZ2UNDaEHy2f8UWgb/VU7zQ3NulTRr9rgEhGQ6mTfT7S64wxhvKefmEbWTBDHnHY6+8Wqnyq4kAvVkSIokM23KzSPfxWw+vaOqXfxOlS6iKR3PU1NOpLE0vEZKdQUjNzXWojBXqvRzfG2AcSLMNvLKO2vOmM0+szghHs/oy9CAMk6d1K4S1DW7DTXXyoVo1AoZugkgYd8z95k/M565zNO6iJrgydnKsNSIbhxiH00fHIiOju/h4Iv+ul9sBw5Y5f4o1Ydm+baYSWxOaTRK9RrpLsxRch0bB5j3Zc0WLNaFxcfPvXIN0+NnzKYGFQbamyh11uTLoXwYWIpI1XE0y0GXgleMJjpTsZvbkaGbQA8msPJhzwcfoJsVS+AGmwvcGaQ4HTmXw7fDCvtKMFE86nu/bssmlD/IYVop5R6eXYvT99A5nn2OaqSXF43yRlXDpnrmPpi61m3SooogjirwEZilmvceWbrRA9Jz3CPJVsdz3kvErVm0A+twtzDTlf4fSXALbgm/ZkB5OvPoaaMtQa+wgI+8/BJrFXTvETxiuHEecywryxFUjjT93bOIf5reVLPd/J/ObWF1gieARGBvxknmWV5lTS0Y32JsAT9nMbGkqF+mnH0Bx81XpDZAyMZRsEwMfCOZeyKzAz8A2GHtu17714iS86ymSmJ+vNONaQlOb+23HS4paIER0DzbwMi12HmUhMTajUqY/mr6OQjd/EBBvjbB5+hpVNMQKo8RCKIQWfJ8owr08cm162yOHEDgDNhm2A8LBLrUayCvb78ck0TDwzERx5Mi4yh51YNd0pNFh8Jvd/+sJoaYK+bkq55Wf7A2KTadsTQOcM+bgxrF4gWyzfmkiI++Pq1qXeFsDwOZruY47zlJkjKgoXTH88NFO5nNHYVxO7cvMsoUd2fBdrofV+Xhdvrd9Texg0U/P3xGLqPcTGIdZ/+8RERd1ap6j1C6wyeFmRMywo9+/aPnbnC7/h2/FjHzIKdBwEsPh4tqO7bfNrQ0kmv+jXvp/dd9X7rx+d61LvvhEU8z2zlVnVSxexrIAwiUTmCyRP75yAiy4Uq7QCJksoSC3RVKRvHPCu4AubDsAKL5e6Np382fPYYURPqj2K/+fuGXDDjqrlRUAXHl8Fd79KaUxTE4+V/v0BRC62+BdrWklJ1SmbUO0epMkEt856mOk//EMOjfCp1ayXwbYwdOtnxLvacN/zgKgrlAzHXUmVipiiJkLoMmVX5a7A+0V6InINZFe3deigKFJh++AA8bvrJ0bEc4KOX37sHyBppdx31p+sKrWBuySbvwvlyhM0fWzsH99k8ZIJ/qzwlgRSMddsw710N81XMHDxBHDaUiQEqQy4aHPeUozPw9crCp0gTyFSfxbuYXu/XOlaMMhxs18kH0bDDSTuiM1VFE3YuEC51iIBAa8j9ROIx2b3DpUtYuSqI3/7Wyp1SLVUNRkj+X4o4XIyCN6coibsz0zMDcKzhE3awaO6doxD7YAttLzhGZoKzlp0+JE69ryts13w5bIMW9vtS9u2nvW+9XuAlmXdW9Cud/bNoBL4fdZrKjNFPaCRfc8pP1OF/Dndx1GI16Dwq67JFZMaiZEp9VyP0a+D50mnJ4kXrxSbRjfDkcIU5R4mPnkSDIjD593chXG4pczzyaCqAYdvi2/l3dkzoFOilmAHE5fJ1ut8ON4FVjBnMgZvwuSfLACcFUCpnzfg1tTT1tCKfrR11zh+FwnAV2szg4/anXd2fX3swtCnuiQ0A7yd+X1cXxLpKlZa7fh+/OMd8W3BMC6cd8E/iuTTtjeM36S3te7RPxWSajiZGeqPt8pFi+/JtQxXzJsaR2UJ4rJ8+jQMB4rqEsYdt4jZiGWLr3AT2bL0R9KhK54XnOKMX4sNSRiXasduV8wc6/DfbfhEkFMG91RjBD7P4xU3a6Iiaij4VBnPt7Ban24JlInnS6Fvfg03t3OJBtK5mYxqki0CgEI5laXxYDXEMANLt+mZEQB9dmW95uDFjxzk8psPJ34yZgMKj1zszJ+1s56RtYNHzSsNhYkaJWUrT/Zq20s0QESh2bNe6eOYZnw831waDcStBxham2bwCwdTbk2nKNpgTGSxa25abhENOKtbDc7Pycqzp0ft324ZNqBaOA6eQFsrZRnw7gepWozWzoeFmBnGuTRcb4sDRTuKqvWVx3iIhMm7J2hFlcmseV+iyZwvNDoaA4bMDPwwgWjfosI1TmCrfKhLItL6d+SvnnquKHGCz4XFT+7UZJQX6ADzBquLmdx9VC+IsiccvuSL42tj/lL6XtuAJIhJhN2OT9J50AAq7/6QI+3+cC2bgZu+TbOdfDVOHnQp+5sobErukmthBxcbB3IvGYCDii9/pgG3ETs4pB5RBRPZB0sA/UDcQXZ14ilHYrqNjSNioMdZDTDG11Mv4wQ/zfleoU4BplYSXv4iwtexkKtcoZzfOcXMU8TuuTjgelNaFSDGEU+dWtugsCcpM/3U7QfKW3OuxeqfkkpHChAYHW4I6tftcDXzTHXHW8j22MR2s0UfsiDw5riba6fwmy3MxLqq6v+bo7wIPHCD7Jor/Tu56gVceMkkmGFIEeEfuazINyODPPaoiG8alkQwVVxsbB8vZydMl+s18pIC1xJ2NHdnzagpYXfJvtE4tsp3cyQB8rD2FeVr0ECT21VDdi9jaiYrj+UzktQGd/LM1vTxO8y9493EVWt5cOa2xVdNhiO3mLjuTRuj8GOAyOmfTBR8mOGeHg1oyAvc5wcC2Z8BVu4g5jDxLKh495g/tKzamn+Zh5wdkFX98c8Vx9PMYXc5Z6DUZ5BJH+Rm6bcSaGUYDwQl9cuhM19g3OcmGSqi9awOfYcfZVd3R9GrDbGxNCgHtfFFY7pnO4jwDT3K37zNxlAXB4lmN8lYzZS894UzVqXBZ6zkQcLNEfIQQLqTUafbttduWzCNd0O9FV5PWtEO6VCTUvIDVa1jtoa9/XYturLog7m9/tmEA8To19MBRAHrArUjlcucHH5ZkASw0Zzq7MoOUltOvS4P9W0T3O0bRjU8+Tkl4sDtccJw8jitZkDc23DaYroEcKp2mPlD4y5VcpVcewklv93PPVlZbrZWDMfOX93sqXW+UNuDTc5qXDk7+enBYZBNWwZLy23goVL29Yjdi58ND87Y4CPvg+62DRDlPL3jOXP/OcRlVEN6KuytrjpHogFhYsLBRoCbDmPOuLb1sfmWKiak97ien/b5klB5ZenJiRtsq+oKrmlcywTfVqLuOHQUnlOk4LiYcQIfLp6TwBEEV9x/ETlD/OeKSGwVKNGi2kMH66iusmgwdpwAFbqbKqn+LNNM61jX4h0pB34Tps0NAn10CyU/Cxf+9n/X0TfAG8ogezZJERsrrg93s4hRPXj5vJcepIUFF8dgJNOu9sFz+5RgTDmnLKlxO6LHFQ4v9vq83SqV5SshfirBezccqVoPTEJqK6RS/mdYuNE7j72PbCpKeg54GnLArCdB3d8eOFva2WDBUPwmDAHv+3p48UrbRXZaULMcSDPUz7z9OjsXeyYglAwXXz9H7myN9fTsmnxFWnDdNhG0unaMHkrvuOlE++0DRvjZ2nGINgeYfz6ro0QwgIRWShntGkSduTEF14s3bIKSS8271fLHBWCEZyTGiMS5hN5F8B1P/jTPv7uc9XmHJkS27UaaFrfRKUE7jKaEqfVJoKYyFfq3ypmZQRtf/yTOzIPPDG+q3vEpXih0PIcgEplCURc+/7K5ZCJYp1kxBQK9+ahUedLvXr1hIPHoZ5uqGLRSx/Y2U3jJwZdHx3geCYATFdqzNVZ34JF4GP5TThu+MLpV4Uvucs8mQUBqdnhFuqE0zmATGLGJHhMbVd10velrxwdwyegbMmJMXhRMV+XeWFDW6RoFmBmXf4ShGURcDV/iYouPNftUo4hlKUjm59LBczxYs+82VokOycXbsYcNwWPVirIZWowvXRwoTB+AacKOD4gTrGghwiSwuofkdg3AzPouyxo8isQdeSs72eB0VUTkd9iDVzz4piPW5LDTAzeSMDAVBy2gvGh/BvUc+XmcY3GWJSZJSyW2dKsuQhlbBj7LBQ+qQ+oMU9MxgqTZZSxDYN94WKYq3aOmGD2DnJxUmuJxFhiVTJunTITX2nBX5SZ/ktM+/fjuHKet7mfz0bMxGMTwyJYk0I0v3NQu8zHQzqpB4Nli7lgop9rsvgMvSu8cZIouhi7SBpdqh75INtCenAhjQZM0WVA6XxiXJNRomHzgu4k8X1jO0INtRnislcBrr6dFQiT+0q4BRtgTs9JPAhAorCokmX6zZIkF4q5/g1nr8cjue12JXx5Kb5h6BCLJy3n6IzvCw+yYqFWUiJM3NmSGEtLr76rg59NzJZ+YrIXfPaPHr75hrqrApIxg8HfpVMKSCns5ehieL6n8OjWfjbv7sFxEHAmHC3Iclk32VzuhGoddtP+obywTxkXfWGTYXHVCf6dHnaJK5/1Ke/1sAltx3mwhR+ovFCFemkDwdCgBCD9l0VOvwibvXiZTxiLvm/H1bhO0LFZQegr33VB8dtPMIIS9/ZgeFIa6jaVcVXOpNY+yo8pakhP2ZT2ptnE2UKBaR8zkVygK00T+eSi6RlJ2xYlTPybHY85fQxyBykJXbT4o3qhEW+xKlfkLmobrGYlixnpO+pFA3mDzwBXTL+elqWPMWb4VInuL9izxUPE+IiSdmXx9yVlc/lm9QcsSZ/b++jPvp1pWN/92y8n4PyYFe13Odd5TJzk+N8kN/N/B7/Ywe1ab6/Ntx9R+j83WpPHHMNgwYwweYqu0z+a56NlNykXze54kfC+58F0EkRG4TApF4ZNb9r6hhCd9R9lDvk1avwibe/f4rHLm7n2cUeJuYUq3UlgzK4ewy5wuks/s/jnBe2nrJtprik27ygu1YqL+Gn6TCmMewDhb9mj2OEXymbZk71iV+RK7EMW0HYWdvWAiTrXAuXlV/LzLWB1ue1nWeBwBUo9x83ph+R9qdoujoDdIOVh9th+1u9fAdcjkyr1YsD12LS817GQU2TeHXOdpnYDc/QwQu6ld/GzbtzZQcK5rd8ec32X6XazCkpMBo30f82xlQR+DAaDblwRadrn2z5yiHsOFN01XoOMIVKjF+NmW38oHgUFOau13uUF16ghMDnrNNb2H5rtU0EW5892H7XOtP6AcB42bhcUY5GL7gUF9OKFFfKs/mF9bsu9Sel54QGUXDXo86ap3mPeOKkpLNASVybfgOU/pC6v+e6Vnv7YT8dGhtX6WYWO+wmVd2L2Gk2cxeo0tW8paa0f7ABLg1ObvjMIjJxJ/Nmql2npcdhOGYbg8s6wiuw7ffClNlO7OkyxBZxNMmph+SXVfWLKp3L7/oYIxMXT75aOQ9BhBQOiXf/XbI+FBGNXW/jEuPaRgxUSh+2JGsu3lv9pdV0QcYsIIoH9ClqLi/+KlqNdYKobybACMS9ZKMuWV2bqYMlh81c5uqmAFtzCyeJV7gbwPm+wxc50FnFYJPrRCyqHMjzrIt2xwOQJEkt56kexTcypLCu4uRB1lubLOYmuMvWPOvGOKn4Jooy0IfZLtbLMbC2TsvjawWNIIOxzJXUxrBnUlDgWDan7d9a9FZNNr2Q0tGywBGKWCFpnUdZFeDgpY2hkHzL0ONWBERhxkW7KG43UjwVLILnFZjzHu9ybt5s5ANbgPaqiQYp0WInz5J8EjXVa2jw5k5YBm5u4xz5aw5bKiJYM51frhqaAeiFINJAaQyLKZ0fBkpxZo0ulid4Ir6I/CRWS4a0+OqRtPFW/uhNXrpHTJ+0EfzC/Mr2gPM8MLppHCjDgJXDi3VyY85ssT95jx8PqMT0rxqfXlKvT/QuBrgud4SHb6v/5gWpeghKxJXBnB/5oCmM8OSqJLufJGEtYSu15ctY3Q4iJ9EgqeAQQz2kh1Dp3J1+/r57GGbTy8PyeaoRxtyHfQUDNgNT9KAM4nPq2I7r7mXgVdp9q6iCeLcpnZ7qFjcrkXmY8guZNHi9qyl2fc0yZ+LgdcHhs3oHnTs5z9mh1BDjcUKL44ON8NjQHr74bUuzg1BtubB3givRqASP9z9ibFz0I+AYq6I9lBL0Gff01fgL5FXtF/Lrkqo5zFRgvTEQd/vo7Xje5lDUMJZOUtXaWi2NXgsGPjAFgyknaC44y3CDUu3B0skHVKjYwai8Vac2B1ScfKWYJR3buJcqP9s+h6g2gxDF43orKRPu/2X0j6uz4MZP/G8hBPECGttSdZ0lJBr/z8RFlQgFdKB0CCE6jmuEqCTePzz47YkkmDoT+osRH5G6BUx9Q9zFK5VdViYq31eBkbAstibePXYR6E6fkZDGPLfn4VzhTM+beJ6Wq7kXnQSxG8q4wDNSPQpku7V5SG/mLbQtFCqv/22ud8E/iv5BVyE1YPB+zblF8XURN7CtWfubzKKVFvi8gsB+4BlDK16xytdiWMo/maYMWuNiQeXarnMrRPA/iLTa6vysPgjU+wtpkQu8rbUB+rElvAq9PhF8ko6iRMFgYqFDHTbqp4L2NipI4VT1y5KEpHbH0iTPAbBaU3TuWUzhdRqMKRnwsomMxJF7m3/c/qE5d1O9XqfVcIjw8AFBM3mGOxSItNGNsd4oPyX1UEQSISegSNBPDjIvtF9Q9CRtCfZacnyDEW7ThWg7f0slfBi+rB4y7UEGu9BhJCx101NzxX/l9PHHZTSMmSmYzhe9hRpHPrqkKMc7q+siFnCYxbJu4gVFzFakyQdOQVRRy+/hjA3tawUAoUMjYYEqw8zvtEKsQUsx6el083tJeL0VmtAZBDvvifRa46gbe0kjxLMBihfeZkn4dPT5rT4MSUSyOU8qjoKHMR6WyWcB51o41ZctR0eYVMNv14eqpWa2rBXf+yYDvfgzqyR2JbWSVoT2pjwPDiEfk8SLBmNEaoFVRZiLec8gyCt78aHrep592Yd7ofrwtTcR7VGieTA+O6SpAeJLav3VVaZFeorEGNlSUfR37Y6Vdpzsl90jgALLMKyy9VkFu/rMIEsG8RceC+vhLkiYQDnIUezsT1uPBQ+5uejoizGSNw4CeW/iLiJl1hkaT1G2ONDTis8Lly4MZepwy/PtmMGpiKnOOl9+rs3f99t4slt/hclTed17KEAXjJgd/Jy6JLCRmuytgC/1vC7ihkfM6NXq99v6xEk2ObA7UfBMO/wiKqQvIYtZZTtmDc4sB/4iSLmQ7DyveXNoytn2lSPIrhztV0Lnd4BEQ21H5b2N3iwzlEKMJ0+Np7u8PKefCm/3r0bvoOIDTWTyK+evKtDAMQiEx+GyB3XeWbM5EGVX+3Fmwo8KkWgC/G82TYGBWbI3cnrxIW/RLVRcEtNkg1Q7brGL6nHknT69Pvj7c5F66AlK7wDV0YDap1XGbQllmCvqKi8isgmM/lvrwM2ubSET6Ffa8mCEvnIIjX62Z94umkvlvepEqUNJUKje7U+B/IkyjiUQRj3FR6hmsroUyoFsjz/WeDQw7kwk7UTzarFo8YKTdrJ4oqKCDSTkr2cKhuBgxf90VlHy2CGFpz0/in5ZbGiHR+aeMJtsfiUIRTlRU1z6OvimiJgvQR2PA7UCg6bRhysPwZplfjvK1FfYV6OFFFhUTW8S+Se1Tj/yJLs65KUFfT7g/c1Wp8oCCUvVj5VhRJCNWBSh1U8cUdr3Y/65QFTKVecjKF1QWWVnxPRw+icC0uC8n91KG1chp6QPLq42T7LBtayHjaMcNqo9d9rm1NFVssICPpnb9vQNi8E5dWTdWD+MG4FPoLVX6+b+wXQuTUyZDZudF4Nbx/+5XsBYvrfX3jN7gKiHjcfaf+Clm7TTrrW8QH/4ZLoj4CGd42PXRTuC2ps3H+8Z2D0FlrLCYYMjUfIvb+hpogb6iXLzjwWA3YvAZN97fNvqsKMltwAYejt8IE1AaKnWqh404zp+/v6c8AzdUVxReDr3RN6Jfcw1YHfRLvMXXjAdAlYnHusU0NR/y2SCk44DNSiEbBHdaoK8on8ST39oS/po7mk+AvuEzacj2+z80xn9tFxj9sGgCxDt1r+bIxUtAY9IFJarMgHAE9CNh48RiypyPSwOoqHM07c+ukwKKgUEOYf8XizJZFixGbraAhNWpmBm8A9p70CKgLWbB4m/k//2myWOsaPAMnrz/vndFHRwn05BMAs2dL9GAGOXXt5IKtC9QcC+8k98cE9qWTZlifwZOdwGwpHr8iFzK0jHmUWSMUd2XM4mmKcV2776nxGXA1n2TwF1jljizVOjtToJLWjI6hm/v1M1PTo28hWkQWxGqh8aOBKrFKk8osu6Oe19weT6zDdE4yuGPnQnXN03QmgBhwJKFh3d+9KxoDr2AE+n47kc0sMixnwjqntuntc/4WkDIWSH0w4iDgRhhHQVHHQUOFKAcBXkZNYjZp9cVlCxGKTti10koa7ULvxRwyAvaAoXfEYpyXCbbH2pUDzPG0WUjBcrb8LSrYD2pPkMzDqt7jz5IhtajC6oN+olW6ySHwM3x/h07a175ZinmftH8uYHku4BmvyS7rRs/rkA/dHGlN7GYs4fBt8dghozWX/yXHWuuTo+HoF1VZjzZ6JdIPR7c/y3Ex1fmb5yx0a3gTtOYP7GcXWnAnA96ldVsE45t5MbDgyu01U45s2tR10XnSB5yck/Xvi6xz1DZ86686ifUxtT68lWBGkZh71LrKs6SqvNuixlxB8VA5YXkNFnc9wEHtG/XNJCX99pZC0XXNTZ+M4aKMkEtVkFWeduiAFuFyXvp63B/Z6gfv3nJz3W8DEoHxf3Rt1pHzUwnPm7AoNrpemJePh6Cn3w9dN36xicWfBs65RYC+WckReOu/+eI24FGlKjg62NOVy8uvDVYKtKhnP0JrSSRBLA1fkFl3k46sMT3BYp8ovChV1wzgXf7GaQxTDxgP/0xqgGzHqcvYQn2H47Q7t9DGQHLn0cNAFJozC3lOXxjPN6cH5byvDW7KXPF/hXEHX5TtGzOD0907Cvl3hZGeDMxqW/OfFcOFwzYq97S8MUZec2XpOv4Ky+PtTxLAoK4wPXlEoDC6KVwIAomorKaON0HwaLLKC1id3ifD3rCzNnhypaqBbazVwFAPdRqFzrfABVlGsWJzUhehUkWF2afFJYpH8ogBkxQEUEyLSM5GIdd8otUCktyEGVn89Xd2eEKp2aa1nKanx7yo/mIVD7NkVUCpg6scew9WkSPdMAabnuwQ8yOMJ7HiyMTxEzj9TWIwpEALDpm09Iq2GaybbBd+v/oFBwtziIcd0FaKzM09abrc86dJyto8GRyQdeSk+c01UsGwHD0lhN03kt4YowGS6CpdkzuBYMUPATMImkDyi0n/YMGR04i1m7JqawIkRwM4Cq6ik0j0AW8EByR8qVTLDC0DosQU/guRAiCKi6PDssJYqxO462zjiJHguEODV4sEhYhuauF5MlpDHGMzChz68SdujnEmbc0cwZDAxoEUgVNKdZWaCxFm6rcNCUaIPeQmnPSbrFBsAAM+O8WNChE55QZOQBTkGLlcoADkESFJWFwGIx2IZXuQ3KA0362OPYPHEPjLDCA347BaFNCEE4BgEcRSEAE1GGRsTQjAyymIgokTw6CRue1XXsb1zD0jMnPXbwlJ4TksGIM6AMsslNW0D+L9XLIpRTzWrCxHjVecm8MOcmzui25vGJZOJrAa46k5u/R0rNMQqP85EAb9Uu0rEiD0HTcENniNuRyRpx6moEvi7TN/hMtE6teaArWuVyxmDqaKW8apcG1WLlhnhy7yFuO1GQ/oGXDqhN2DZcWaGf+FS3vmaljZ/whyJ36P2i5p47CbspEg8zwhs6OrfpLdPbSqtuisz+t+gM661v1z+jstVX/hM7eWuWb09ORcup4Ox6h7PZ3gQuC278FbHX2t1XfobOxVf+Izr5alS9Oly3VILzdtNRT4V2OVL3wXh6pJ8L77IjvPe/LIwWO982RfOp43x3JJ473hyN1Ibw/Hamz8H48Uo/C++sR6t3zW0Bpr4KKoOPz0da/+A9PdfHFV3aj1i1fnfuhWDAO7lsXkbFzJ1uUjOoy+Q2f5j7y/JVL5LtJcmZzYYDPjfPicpid5zVoeR6fIqEaX7iBpcUykoxF65zDR+IFpsbNnGdDJA3EbNzMOd86HH5OTJE0EPUC04W7Gpbo07mRiDRLHPjBWABs25+iNhEcw72bgIV02y9ReYlSsxqQanwLCkeS0PWpQYcgqB0K4zKPuFIu4BmFiUwtOkBRnqPA4cr8P3hGmRLDUcoJUqZmEJZQVbeIon4/JlItAvsIO+xOpTvCitqhaST1bJzP3xHoZzoyh8K2c8f159LGCAH1SmAWPxoTGZDAHuDewGdHdXGGc0xQVEHdnqfEcHJgOllVv1+YiSE391DymEY2SoZZLcuzidn3RQZFQ5w7R+QvogQlAjNFkAoZHBZbgR1Jko6eaAmFulVgkJZ0jiKOaEVIv81QCR6J0BhgcQ79CyyDoraoLqkRVs0C+/C/7JwLW4H0bAaikG9wKCSg7q4HpDzU0E6HEdrf49GANWWTipZq2XNsQCj7y4kGukFie0Re2HhQksu4nnZQiGPaMTM4noxe48yA3XbyWkeLMJAGUpREgL+hRK3HNJRD6TOskx0icgYsdaV41y06Q9BrRLjH3iSE1mcqbNk7IGw0wAc0AVXw1hYJl9yGTtpC73J0P3yioPL0qB/gpFs1UrvtDtEKGDh6smL141mo+3WyjF33kaFFVuKCEGpFivyyBdtasKc/pNXWdlgpInwAdy+nArk0FI3z+6/I3fcCKc4PW+DoETBBkTLiUdWIODmjh+Bq5/uye23tO8I56s/y1k6WKg8cG2xb3I1Y5s4PIc2m29KzDn1gIszcqcC5MftIDO/DgJgxoXDMddnjsLAzyBwh22Swkn0FvzvjxCDupWI5tYhAjY2KQX/2tbHOyUK5OpFlhZm2JUgtSNT9N8kTmlID7GHDLSrCpaPnas7WE0f2yOGoRxrTLyp/B6Y13gmUj4dxhFU+0qUlUWyQW2zAPkkeprWWUgOaKR/eJ+4kIWVipMjZF5bCBN4XLIO5529nnGUWMjBVOUdA4hmSYQf3Ylh/NROCs+TwriifsgJM46mFFXBsEDwtgUG2wrR4iI7w6h3NK8+NR8DlG9fotKUD7cXnKjjXvBWMOYgKjsBrFjUlpDsP+g6PBQasHDrSXSq/81xE46MIanPIAhREJm2OpNSATkwngB1uZuCzr43imEAcKcc/n7NPa+jBtF+i5kn0qCgFNhzxklezFinv5uBZW5eYLu6W269RmWYXH8m9Wtp/tl/PP4+K3Y+M0sTNvcdHjMlRlPbauqPnlyjMihKYSL/enI7zeOGE701GIRiDmmWI/SkngsiDoCTcv18ilJQGu91PERbIjCJDCijkJGyFmJdKazM3jbZNb5GqxkEIRkU+0r2ntlJkajSd5AaP871qS2MwcIYS7iknE7iuPmIa2cJ8xiloMRM69Vr3PL170RTuyMwj6HPaNUgsj5QsI5JJXNWxxVoQZ3m/rL+IpMKo+ZCBIooouQWbQYCaJNbAYW+aUNPYzuMm4WCman+vK6BSr3i4NrCSLlFjAYGxLhsIGVYHZEbKMGzj4C9N9XaSH4qiJM5dAXwc6qjDQpyOQPNKgfSlMuCrRhvlncq2r+RawsFStSV+j+m1clMM+VomHKnY3bNvF39N41sEvBtxZUdpC3dEwKBz71RaI6QnFUFsK85Faa/LzoHDi8hC1EcA7oJFt048RIGuCH6YNC6TE6P5wlIckBV33D8i9aE1yg4pgYmEE7D6NHBcLlfVph2Qah/elcCQsdvd7rSkm5uHRdt3MimfMGAYQUH5sJJeXohGwV5yX78fE5jGNAT5jcr2fXOEhRgYufXUjYAiPuxl24je0vMdKVum4rtiT7aO/5Q9HtT2Ck/y6nQniKRbikVk1PaEK1nkIyL4pcA9GKEdor+V3nGdoV2J4SIinxNWXUaqSAsytJoYw4deZy8+Es84no/RuLD6aAQPJk34kpATDNcqdEqLQbEpOGGtp9oEFsSpdtGZtC+2Xpyi4n90vT+qbPV4HBOqvpLfiIpWjCgmzz7Eci4RBnb/kXF/8e8PIci4WtopD/sLROhgRgYWD/7L+rYzatYIBLATVrRSDD9uZOLxbRXjwoVzkdkxyWHE/hx1dqSs1U3aiw17DSnsg2vHxOVDGCTKXc+brKRiOJHh7VKRJYqsHsn49vmbGXkDqLdycxDCzWRLwO/UNqFVhTgPYPyFh6sGAdHv/U0dKWGxJ/B0sbzWMhzyxgLQJWUSUR6Ud9jf2f4k4ahN6GyL2Qyk6spn5EdAQWQfpzftqLI/ageGCaRUsxt4GnHmxJiVxyLccmrjvfLtfhkQVcppP9CgA+B1ln17hHMSH23N7SSDbbORW15QrxyNK8EsXqr5+OPEY4FAZdGwXUW2LeTL8kLfnkrC/KAAa+AJoNCZbL30NAJ1JHncC2ZO7t5tI8B5nBnBXTnjpmawh2I6+7diwWNGahCdTTgR+BcEfKduklSMDDMjoI8YM9rRx0Scq3HE4K5iEmgnSSYVrq4X7slRXspZKPF6HSvE8QIstUcTt8iA9FyFq+sj3umKsNAWKhOdDn7Z7szspKaSx8MYJ2guXChOdsCdB5IVVsfE6glRztAe+uQaiw+ZMYwNtw+Yau1EE0COeiFl4k8bTEMg8xXxohrZeuLbzTX5Kfiu3lHahEdHcebVH5jDdj6WBPJSUpxPmcVAVWkl4g9ho+wjevQIAUvd+HKXs+K3kgcO/cOeaTlQsBcDB863wS9dgtjo0rykEGgPrDUHCm1U/qGYpnhYYx0M7PcF9+bfJ58tZ4U/KV7ts8OcCB5BBswEEUK8vK3pZvvx63Z/Gu1q+FqSD9MBcSx4T3nJcf1l5DK5DAqK8hL1Z3r7sc1aM5Tje1IQAPLoh38GoifdT5oeXSRrzYS1oFlFOtZ62B4QA0BEBktyTCB117/qHKoMZJhpXTe4jdRmqxwdX/nMV8/XtFpVYS+VCLRYRHBji40fsjRghTXVPYtF0Re1lB4/OIKeajQrQb8ZuCvr4Sv982HlnoIcea5C+ICiN307kVh5vcHBS0t+dh7xTzzA2NBpPtKExgLcrr7Q7LcpbT216kFsH152FRmQGCpMONga0pxVVyI6ZG0ByRvntCtCFA+XfcBivPDXtwmapITRqhc53POQdZqienBh7Mmo3O31nKfZ5qVbkI4O8szLZk5YgLUjz8lfuKCSHGG9t4VfOKtCxp+0Amk5+OJS3s0+12WDuUUH5hCMJMHLIm8HIibjnwWOs9JmIoBjN47SE7TqT08a0ASlO6Y8CO6xekw8jovxPWGu5X9VeOv3pV+yPU9KJs5dYghuDNwaC5Kqt5fGpZFxeby0TyLpqsHShOd4+9op0dhvwl1MNLPivfh4ALk87UPlqduQP1K+JStZFjjXAA0A1LcpTZVEKI8SwSRc3X8ONAeKIhY/SGsclNxWppPRPtaxu5Iecyr3vv3JdL8Ut0jt8AFyF4IyF+S+rOEPnRO7E/OUuKgptI4rqsENtBLgDfBJTrmRaLUtIv0jQVWioMWmJZiIUH4upBHtxQ5xAstXKNp23XWkcfQ67NwkinNR0Yy9v5MO0ac0+Fh0fjTbfrsr5TYlOiq5DabIDXdU4as82WKxvDX/SHiaMko5fU+a29o0/wV4pvOhn67EvKioLUBg0aN5ya4gxVSDXlK2gKg7zhqUpcXa1a2wYQQA7FF9BoO5MmPyoJLb60PFHUj5J90eq5gzEHVRnD/0DqHRV5TtIM2ZYb+brFzmbdymER9lCA0gmB5a8VT/rbrJXy9o+gZo9X20ipK2AZZ8eUXotZp6qqACqy489h1WpsOxEAUZDe/ZQK6Wg2kAs/NUhE23FlIoqNCcWiyrVoUVHzBDV4wyTKUIz26bLRpTz+NAmEUBwUEvGyJEhkFyYUz5w1Fk5LzfiSI7gigK+SNry9dR86ATyiLC7EUa7mHsxX4bX3WEe9ZnC6YCLpG9ZgWQP3RFpkIWaenKmbeiDWZDx+dCObNmh7Eq33+vR/ZxbGTA9AJTYSYU7lCeFCedzmfdYFHXJKenFQNMvadVVZWvBBM0RVTS1osyCcYmCARpyRqBBOaUbuC3nyI8CkInwiB1TYnt0gryKkMg/Pfo2nJ9udEO0WKngygjEV1XYsTLVsixamGFX4HQdOuKoIQ6uUflo0y0U/y9N2VbP7Tth0dLvmgPp5cIDduPu/w9sWWszhFBDHPXthlHir41wQQA7Kvr0OUGiWfUWSMhxH9Enz5c30z+cEaXXqqprFLFJSUKQ6ICpAzNFNxEj4NFjh71LUwL7cTggV5XHbZELeuGLbe2dqpXs6vwnOf/lbkixkIq8QmVXEeSQfeBrQTt1EtZpQgh/mecMYqsC7h84vYTRPRErKLQ8gvBaLitIAdNQJIEum8aSJAkoCHcpMwXvMcs0snATaw2fCxJtLKlgg3OB0ekWA2m2CtMt3h+Pqw5UBphUqQF4tgBikOKSCVOchL2FcGV54pgrV/u8UhVbrWNOTSsYZYI7n51zZd7jDJD4ZpTMDsdrEW5SOOZ+TRADSCgMEBV4D4AaO5dIrcblQmwPhVQycDWtbQ4HCplLbJ2y3eiFRSs2v8ofwizXyzzf0Z+iLQ+uHSkjwkMx2QkCSiIXv10Wu77/JtgvJIXIi/8bdOUKFn/TR/2A8DKRZE8Wg+CDTxch9eK4mpa89IXUC3e3/2KQJtrRbmBgJi6ERFW1QUIht2yjwwQfBgvSPcocPEx2glEFH4XSemkPiiDwuDIfH1aoVaTxYuK+D0U5CtqxJq0AdVAgiBRU0dtWLEWwoDU3BMEtRDKjyD5Pbo+RgikFGdbioLMBsXGqLFsRwUqiQZ23aAaHDJzMqXQjzcesNrXYLW+4GlPRXOp5/D9DnJ9V9YlVPn75ZdQm1iUOHLbbwYf/0/DAe+BIOFwBWkDuTNoSiK+DVPeJsCtmULEbm6U2uk/02IZNI+zRbGCeYuVG1x2C101sewvgLwBcA25Vrstl02z2sBvfPZsXKn1VI1/drg8PGy9WAfoNIBCnRJx9BQqn4EMDpNICgJbFAkW6adciK59EXUDiZftRtN3kJbOuBOmivwv1aq1RVWxye/stm/F2kYkTcbIpF/TxU6TW4nVZ3Ws6B8gRoRCchqWKLlRyREtN2eIJx120WTtijb57nOUEcOZ0pi6bT7AsgMGDSQS/JetFLx2UC34e+UvrLD4hJlAsnn7ExElubW9sNyEKWEt1XHgWuKGIs9BL/mji0SahsSxStg/J1SPxoT78BdYrB0iZtj6ZGBgZFhDU5KjHjClVQQTi5GKpvDm5LXQGxBV2ANZQNX+ZRay0foBK/vpbtnG7NC1xrmb4x00VgrE1ZVijoxR1pC2qjH6zrUqGYhEZjm2HlCw4a5CyCNRyBMncjfOcw2DAF/MiZ20yE2KTrBiYIEV3GOE2Oy9kS600BWDRTCVobHwo1QLicufEXLb1kiBeLq4nEalYg07nFmUWinsKlMArk4MZ0hidynRhf56MCMFYlNjhFOgeOma3pxy2cwPsoj3metJGAoMLlTFD9h8/6l5pVKg/Z/aJyCSScvzZtEtT8CV1+0iKlLrzYZZtaq5secbVdpdgUzsWWquXM9JmqufzJ4Zgq2WEoSBWvsh7IJgAcXGsFYzgcbXAT+sluiSa6YT+spIOrImQ8QFZmMw7BhMukhOennltVk7AAT1fZ6FBu0en86YANxTW/cZ2Mdkb9T7GhaqTbjPdFqYVYRwZHRgsIdRSQdBI6nAEjXX7C/Qh+ooy6+1ciA6SslXZ/tfE3AC3bGjJG2egdpgskEY1fIRCu3KV4+U+erwFNkvES4T6JRe4dOLPKj0yZEPmJkhOFYSmCNvP4dpqcTX946lboueTGFxBbH/q9/4CvyV7GMfEWtwXD+XpkewE8JLWbH1XhEL0fjGb1EfZAAVrXipocSlkkkFWNkQayLFFVavG/dbBkHM2VCiV9CReAvIRtOnIlJ0APMxa1jEZLcooVte35QEwh4VWf1WUeKMuHURqqvdUnx2ay6Nb87h9tDOTsMwuL6GVrGHI2HgHpwl9ZekDqRbEee6xRxDLdLeFDTCBFNpQbhFYvHpMzW1us5HdnKizGs7WDPxWcneedEgdMGErcorlt15nyFwfMqJdyjEP5bmeM2CPBZn7Y4g4Hlk3Pt7Vs3wavQA6PXmc6QmHr3OF4s9tAFEhl2lHWPFBhYzCRkWXRU0ebjSlmPFeHt0B5AeVtJtyxhzhBYB9FBMx5FxtHICirLJQg1oiZnzSvXp9+T5jl2EDhqwjHFmbLFGfJl7yJIdP4XKZl4f7gIPwGsrUa8/CwEOo13Mq27De/akJzdWvAi2F8KyxSUPbyopC/loKqXEtFMygtD6x6MO7HVPlARFmtsVy8wG5ZoQQT4jk5z+lQ3kv8sAZWOIm/+ZjpoarlDSxX4cbygv//O4nTyfFHbNX2U8+sS3ArNv7B6YaqK3/v2XNXaMJOhsh4XjjOIZo+FLrUO3g3hjoS3iBSAdyq1MoN6eJz6ftW1q4rqDbXTVZj7wrVZQ9O1uCoLQ+ukX09PJ+pKhKFjziA+5p/n+IK4yB8aCgxcPT7xVTlVCLEmJ5BjEjgYQ6qBOaiyZj/aawKBVhAex4A50MnOJWmueaDuxDFUuR6X11A63HiYVUWRruMie/NswbIO1zRCFTiwEr2tSlUS78YE3v5TvrAsnM8p3W5QRYb0tp81STOuCqh+Q+8Ts2p5H1DZV1aQhCjvSNuQawbmQgouUhRyD7yL6uBWazLwPPIVI8630mCPNH1xhDDhCGSGIQqkbC3bnU/1YQ+abnH8+XfkVEgKfnvmd6lkSX3Y9tXH9VGsmUFg6FELO8yLcljZGUMC1n6X/QTMysS0KNcooYfVXknrW9x7bK6QLA9Dco71hGp07E5gP69gGag3nRWmsphwty3Ds6yNGVuMTey/jCABfpP1tNB5glQ0zHTK4KedroqVLWhClve466pLGSO+eYzL9t+vtJEFADU1XnWVXqmL3T7oIBYaZQAWpu0JTW07n8iNmh19KK7jR3E/FjGVgnuryQa/xrHT1tIK+bhMVAm3hvMbBPV4q8m3ST5Nqgj3th3E8eNns7WR23dCejXPBDw7qEkLX1jzkteNV7kNHxRe/4kveFIfRWkKwI7CPI5N+0UOlbF6qb4D/iHtWlJOaaFYgyPmamrKYG66y6BNtqTVnQxfY1H8Liyd8nl4pbjeYRZ5KxGZSp0z9uaZHNw9xp8OOXiR2xXJ9LhKCh7rHejhrAuhgBRcaaN20z/Y6VCrOGuQImup+Q3hEYRZyKxFloYcXAksxdi34OeTNtXPUvMKYRRGRiag4lJMR8qPuKJOVg3Y3eD3cLM4en06HvoHvcv41scZbNU5DWEUMntQjmIbukBEVhNGiGYYHEKHXpYs82J2wR4bGbfgGmHTVYGAp7it720E5Da1XtmIuMQtnnKkEEJKpll+9+l9axJIwaW5pqDIVozEq/iL9XYn9m9AprtfzAWQjo0y8My8AfWjS/wGI2jH2MxzyEFDwcj8meI2vCqklFXONdP+nPAkeK9ZJsU4sZ5HcumM1TwtzGJebv1J234m+bzrh3ZKZADtO0i5szOHvIeRRESosxRSZ3r0+4WuQyV80mKCMUnI3G7XshLnh4QY9r4iFzG3l8oFa8a+Yi+rjvjmnl5mSkDdNdSamnO5ww/FVmBsWmk3X2x+Di1GilHO9UWSoGOlhXt0J9VeIsXcfyNveK/T8FpyZsskpkdBD2Ln3Bl8j1E2Mo/W/Q9CBWPs26lXD2WUwYvK0oA3HCqEYO3ix8Fw9PcDnFdMn+upJwEb1lfPG3OHQ+c6YwdZOXB5SxGpRzXTL9r9D0MCuAvybeHUl3Ic8jGqZmlFbN+uWuj7O93RG0ElqLTTDFSc7u+BxN3q+lbX2T3Ee5PIQfgJceLha7+ODJ/xOlUL+9J0P7wkwj+vqROyecJSAhC4uK7wGTxqupNcyfW9NqzNsd6lLeCGg+QEDTXKiTApCteeh/pCnaQta9/DcMtoDnzBqtG3fUmCWhBE27o0ERf4WxstA+DIlKZB+FlJTR3NxrYoNe9bHAo10bkSOio45KEJaa+lwJ/gGcqfSSXJLJ7nmbyEzLl9IZYzrWSdIde9W5FU7DL8KXxRMX0gX0+IWw9YIirIY0+4tc+JPDCgKWr/yUEqS0CA1IUBaNvXkOdl3FOGiSB/js3kgsaWK6hv8AkOTBLYwWiLFKAJVUD/FEUc2VrVzb4ikn1/erOmvUXM70hBBvzf+bH3UY3CCA2eMUQh0omyK9chw5dJpFwXVk8XTRYUhhFxY/JbXLqXBfP008SIxUd5jJbdEA8uEr4N9Ir5yfRnlHU8qviZ89DKSpbwKqp2q6PtB0Ah00j14NWMo3bwM+00uLTGePwTs9qS0zIbJXBHklNl86QYGj3Cogr7yv0PD/c01P4B7EE3ifjtOCY4h+xMR/8Xq+Ab2SkHD9jUQxXBrpXfoH4N4hrAphsRz/Dg5biXccbBRkVNSmkb79myReqT3ZrJ1q2q52BzhIt24LrQnlVgbFpx4o2gv+xzL1sV9wHjmnZLbpguCKkSeP2IkPHU9FLRqv53nGAotJzptadw5ke5512nDoOjQ+gP21ixHAyeRlMtCAjYXQtqSMX1lwWpavU8vH4peQJXgRPP9FgXL5zowobK2WJqTmM9fdes/HsAECNdw52FE4IdsSlUJ9KjpS543Ys6odA+R8EWIq9SkhBFITWZCEmlXYsFF9in/pujGNFeZIqQV3dqYklawWC4Jc16fqFvj/ouVzgY68LdoTIwSPPxyUZwwC/sZZ6wgoCopEB08yS/SWgmYiGi/B4MGmHT34pVXvvNZqWiW9OhC9bGnbQyVIP9hJu4CILIIEpSr4mpU94Wa8BT+zT7VCpieCqOth8pSdlfoKm66cokh5t2b7WIjVdUHCTvw9TCsfHkU5/Cu8hD8xWQiJb1KWGqDQMAWL2Oc/YSUL2MGLEQoY/cIDULBOCUP2Z1uIznRk72lGi8hDTXgtG3PEiP2ss6tHIZQk6atUopkqc+pktcl4+dq0aXGoFY2b1bQo5gOXHmOapFG2jckusRArdqBxqmUcvxYHIMiPEkbg5MaijndNw/yMAmr63kilm/e0HiZOS9SbdXUJzhnbjW1/GR5HbLIObwiPjiyVG79xXdS7ZLiIZmQ5rcPUdtIQpshxD56XgNpcUTPb6V7OSbz3+A8IKT4ykpv/7XgrE58hkL+AYvt9aZiQExlHClX2rpF6CrEcqPYm+PM/Lnz0G/v2I6zaT6xG+hzittm2Z/X6gueLTscyYeoZE1SLJISpCgK62RHyMykJDNbWjLA1z1ZQrl6QCZLlogd9N+HHsmUfvJby5tpGewz+wQCOCVKIQKxwMJM1Am+qoWwvd1E2X42VuQik8v7RshE+PKcjy9pS1nLrQsTvIgTpzX7WicMKX2OEwtSSkjo54iEiEaftUtnlcq1MjgzKaTzMiTpp4MhWmjoO0UvQHsrZ3Yr5AVyyQLRSUEYtCOIjSPvKvMxUUQjkjYeIac3cUFbge74L/UjCgkYcJSob5MA1W82TaI1vuyYWmpiV7IKGVlYS3YMYaFmWT1odujNT9hBJJg8rTbBckwuGdGrDEtUmWVX8hW0K5KmskLCzac9mfsqVfN/2rYERZb/pBd6JEjUEDCsTTgxIl79aSbA7AmdP7P5/8/NRxbWw68JYMB+b2YgCNT42fQwghgOL5a4eT83bCBTSTGLkxk/U3SzC2OXT/MerJT5VO2NtHIy7Mb3kerlHEr1ts5uAic2uZvOsjQGG2sddi7/S7KuLH9cTNSe8FUaOFzxNWgh7cAG0rzZf97+gTs30z5GRwDanFa/tJDMxSVu8UQJY5Gu0coGMHlDtjnliE6SwO5VOKBznKFS5WXcx95XZbodS+BPYYNfIYHNntD1Uue457SwuS8pPGqlsqI9SUU7P7dRg7j3rnsH08ASSrVIMWC2sF+xPV/ORQPCcRxT1RWRGHCb+KGDPfJDadJejq1CzAzo3sg9lJEPNSZeGJEOQxGrlZvTUxJWZ6l3sO3Cgm1KzJY6QDwE6pgsCdoXCD8K68H73ySSY/zIfUjUMLmmDgI4ZWNlIK3PUKi5UAOg4e2QM5CSQbO6MFnimlGCXBABrKRHWGafGhm+mbl5TNEzLpDoJcDzDE2fv1rE9M6FLEf9LEU8v1ZhVj7KkDJNc3l2/xf+I8cxR1VUqvFNJkKztk7gVi+g3lfmyTsFkUKNfUJpzexT2AALsEMf1zlQu3WpyO8PogK0UePbnjStJ+uV/XVEsKCpqHoFVUmZgpWb1b/THYWmD29j0ZwMN2ClrwXHC0YdzsIlQB09R4GSBeiEQAGR7voQw31EYzhYSG7Mh0Dwu1d/MG5uqBUlYfA8aY5g+pJpPcM3FWKRDXKMqYpOSorCPToEruRbsXnKOAsP0CGdJwVAmBVH5jxKNG2TpBLcuUiJh982uNwFlCDmLvnIuryH6+MUnRbmgxtxp9qWVXkhzHxw+W5mDoIVHRNToqLCHG30d9FYIigAEUGo0AXhWlZq2AEjKgq4WJu8oSN81bLiIxCSmxMwZrHhDbFEQ7paj6Cy6SMdFzOGzA0qsXn4SMZGI0lVlaP982hYi9Qkbk0Id7JQHD2hNbY3voQfiyPK/VvClf6M0NDHxPoJdHS9MUtuOI57DPOq/tmRj/mazmUbkISGZ09ly74Zc1F3ZeoAb7gUAsKDOB5xWkJyxgRoc72XXYsmFWv+9SiN9Nx0ka2KTpulqdFaDS41ixxfc0y6715Vc+Ll5CfdqcREBttY/bBBjvVE/jYKwfbJNLJVX3HSCpCpzUdXbt0gkFmca2O/B7Pq08IJ1tZiG8V5Az47yQhPLVJYuavxEmaaNgiEqUssZ8rHYrcbk4vkMV3ZNAE/G66US0CG2KlSvCnMjZDySwVYKoEHxeVJOSgQVUvwKN2pb539snqQqLJHWVEzoSEelP3Ip/MYJNk2Uh/XfzqdXYLiWJOtyvnY4Tmi+efxck9cdedPtHggLqJPOqppYHPnuenBmi5Vf90llseiuufAEB+ty1Dw30eoiiRb9MsS0ErJApnTyp2mx1MQuWz5H122dvJgEj59s+rxoZFuYTQh/ZaYL0/uqZRi110KkS0c3S4ImXzOHP2fey2wX4z2K+aCGkjl9aBKSynnwirXA7lRNFVDwQBv38AeUQ1P1dF16HpS0NbP/kDbFIU8AXUb/z7y/pigBb065az2LJElHZE9L4dKX8DPBmjsebdg7YuweZb4KrF0RoCwZAx0npWqSeW4XHqjWZ9GyFDRy5wuchUEnNnM0qI1hcBRv3EoMrHoLI4GYBp8ZbdedTbKFcME8JhUJcqx1KAuRp8bus40yntgb8UtO9KCyhBs5BXlCzuSqRTpoMMy83LClIiV6JGRxn5HxJCRvQRYMQslDqH5zwVvAJyEQSsF1J8dcY4ZknJkZIvSeOwV80hWTuf53jztCPY6E+2gXCAbNZYTsXXMKA9IKV1Tn5UsuuYvCTJYUz8mR44cThVYpjrjJ31D8dFxLYGq+G8dpBwpfCz3gmMc4W9Y6YzMqNfgkISr5zyQ01gKD+n44ED/6Y3Yj9vw+L6TPmSjltLO6EkR84rjMFypb3Bl9iQSo+IFC+OVP6te6bUcovoNoa67stITS36EHEg4UQCWsy1iBJr05xzRy0LGYDDNLh2JR04sWmLh9oYtmU7+eDlmCbDb6DtTC/O0RZzq4cSdkOwLJ660NFfXOoSsKoQ8YMS2Z9t3ovzUXCMrK7ZjnNDp6A7TcNFCd2tuOAra/OSvi2aBYpzo/SdSA5Jgyr5vGuG10JrSecI5K/vi+hBbNSye+iQa4Jf2PHr1sS8rPYwGkUJLwbuSux9TpZGOUk91HaObXVO/ve4eKFZua+0q13Pbd9cXLx6CoDTKQ1d5x2TjrAI6PbEMQKf5fiqdNu3+7h8+siKfdYBk8xX34D+Y3/a5L+o3HqO8Xd8F9dvIdipmEW7o4mJXGlv5BgDHLau0AnK3wPFKt9OrtPw7e7qpQgPc/ShA2bWsyXwnw8LtYboAAPdC/fZmX1Y3ZG9Kw3G9LDv0TPviDKtopBd+/2Dvz4IwcqAy14uhMqXROZC+Yrkhq64ZqmRNJOVTdZyNNHOVZPruCC8/EdmqhY2nv6i9XJsE01Hfr30MQqN7plQLOFDqLHF5BPDH1pvnPOn6qi7JOV/hpm6Fqts+2ulsivO6Tr9IG2KNcDa3Gcl6NEbueH1OTlRvEgn52JxlyqS8VSPhycaSjZNt6XSxDoxeXVr33PAHcShnBqPcn7HdfmimFWR2Aah9MnOzTPg7NNpjIImu6yUJCZIUa1/TLpbXYkoKQ1cptZnTolK6qGEIL/YUwNZasyKNo3JU1nMyQ0TW0oSySE0aNRiHSGPOc5YURaUqjU53pmTmAP8LEs2iy/gwrdvEz9rhPhfZ1GEQ3HmW46xLZvXnwNCpna/ay9Q1XXZV3t0d40i2nk2c7PHafthsoMNYSQNe/o7P8wExBMEvpnzAOozQP/ii4C+aNIR28TkinAkMd/pW+8Q2LH4t8qHhoG+0/MPgAS1a1AsGu4lOZlDt3+KfwOfZ67E5J1Ca4rwmx8lL58WpHQK3pr4y8zXmR4tDR56N6kMAIu3VxSVrkrKkTA2NG4tz+6RVolaus0Ka0qEUx6NGc5iq49F6suJU8Bg4/s2d4sbxTnU+IRANwoFl08NhDQ5qKPSbKvDeKQAUjYQ8CFCSEJeFdSrIkU6W44/e0AIfxdsU8uZP9JQ9u4jLWS1lIcULzAK0uEeJ0iC0ja1yl4G4dBeUyPWMn12Nj3ViGTXLKMdjwtFYaqzcEv45our13377tbmLn4dwd+yTvgEjqFS/v9EABFrqNI2aN4zjiWd2PgZa85p9HyPhGB08PvvO0fqkRe5BxourOgtEQCfqqoiUSbyyCosUEli6AtPDrGC48/EWWY3bRCYLJyuW/o6FVNM0j8drStksuMmhG0GONKP6cYKJ9xaety1BAIQa5DBNRfpG2f1MgoYyMMx/cEr6MYNiZvvXS8iCbZoSPXhGHi8BU42y6ZtUo+CIhkiXFl6nPe+6iB0BOJ9AjNMaTQd5QczpOIm/aJ6LZlU90XgGBcmgP9GlJdJMon78UxmVjI7bnhGcF2TEZZU8yn+0mRLJHkvg14rDHYxLIH8jGWGAIGkfrsyXPKHkpFF4UV7b9OiVy5FIC7BHoCf1nk4sUdi7KoXgb2iREVizF1mVPkpXsxy3wXp0z90GdCBvxXy5ZZz4uXNHeN+yFvZW+ioFibAMwSti7dedMSZmTl03kUUEDcmbNNT+2jsHHrfuVtV61a5YZwPNF502GQ9Uzj0nzeVYTn14uKocUS6vTZ8xkAPPr+9y+uzNmuO7jdE3nz/iHZO1T7U+lK1qJ/dybalaXkxvRPcZEbjX/+3c2t4JHDA+vT7OLZqvKB+uTsdpXyb8KKLl1S9+GkqweZmt/+74G/yGgHb6ZO0l4XP2v5Pjw6kaN7l6Fkzzcu8J4egk+n+LQ9SBw4YCGHX3BsQzinvIjZE0bRbNGQhVK4o8eQj+ybKFUczu6sr7B0hvQhMXFYUu/YDJEITOZHSesnQBhxR6t88/E8hiffqGfiQAW/Tww6HrId2ZekTuCPJ0DgJLoQrNUhqpvces+czp9RXiBKiiy46krIeoMcNGtisQWVn5PMAzCR25m41EcFFIUVRoAfrqxwOL0byWjJ7+Q6bL6g3pIv8n8oWPktKwnt0bQZWrLH9R0lud0ILMRsh6KmawK51KRU7cWPf6wM+MbKqcCXCEqdZ2ynlVD58XSH6SlPB7k+lcZ4p46OTkklVhcwBbFua+59+JBjpyizJz7s4vRRh/fQheqmT5CH+PUjkXzm+7c2l5mfC+s9T77q+okJVNpYEV57mh1iB/9nlmd6XjGMpOtNYM5CkWRaV9av22Xhcv8CvOGCq0zOwY+Ilwe6aBSDIJvDegPFOI8FzsnNei1MAXnyqGiLskG2tCnhpXLTek2A1Msjlh2c4wGvLlmlQAq5aQ1vtR5001u2/JiIPWoTGf4A5LhPuurztXrta8MkbSWlmpid+0Uvk7ON23JbbMTor2FUn9K7bvulO0mBiVuiD3mRn44uIlSCSMHDqHhSl9v5V2sxRPKqYp2L+D5/JPzAixb5+q1T3OshFSw1gXyk/SJplQtO3Xid9I60De2ND8bO70GBwqB8oSJn/T+17W3+vymKCxlSu+ZEygtUiX9v4/PxtYd34CD57BRd/sL9xCmjeev0A50yrgVcEz2NYTW09L2CuxACoc7YeXs3+gAzOz3Jlxp41pgohCuhBJ2cXCFORYzxQf7NyPg26gY1Js2fi0x+4Ib5PsOL2S/wAqhlGn0HaNY1adtbFboo+KD69smL2e2Z27xBWfd5Jy8UdviEVjjXvTYUF+sKMfHZ5b8G5613XY0G1oEpUP24GesXV3+Gv+x3CwSG+d5nexUhJVE7BpxdnjAiCrUoWnHYUlda3na5b2rjcbh1MV0WPpGir1ngKp7GHWNhqzOqCQqB0txVt/IGG6J0P9unLoHX94ykKGbsiJW1DraBdESTgzZh9cH7h4uKR95DAiqIsjXzJ93z6C/WzVoNChBd2I2YnrRTMLhvIo3so0V2Ij4QcFwCPtRFKzOBOI+VylXS7PgZMabUd6g4oFUhBRGAbPniKkWdVpDHeafe0pN3JlmUyDI4hqVBYTMZJB6I8IydEPC/CwL8ZPuTOIFKTnzJQTQb0WWxSDEA4R3Yi6OMANmjgZyzbKx6lPSEM3JGuCiVYtkvK6Lot1J/RUpFL3A2Nv/sIBklN8P4Ji/UJE62n3hF36uX4iZK5xgfaTov8LnW1+y3IAJFZuTnoLxIcHQVhR06+IZm4v6zqiqtyXNczDUEhiGUQKOR4I4KeT/kYT7YSgLpBsGIRWV4qnY+2YIbK5UVFIvq88u2v3Z8XBTKliZKWKenL4iU7RylLp5shq/KCWxi44n4kZpoJOoooglRqV4UDDnsDTSDHAyF/UZaZBdSt9O8LJ6Ya0UPizEQIUwea7wHZ+Os0ysaSPasOYVTVVIwsdiL2s1grXAEgbY/TKERPgg9AFhor9r1AYqbws6oO+6TjHv6KdQSFN6VlZDvqZlg5/EXbmLLzZaJjDMRnEWYVzeFyfTyqOUIq3wDjWnYxzhGPHigPmFJLOWbo5L3hUdw9wntMBT+76ywYT69NB7jWe0zm+BdjrKkcT1d62fG4iYEx0KkC3BSSPuc/2qazqSMjwixWZ0FzC+rVEghOcmw2eP2S3O7/El3SNdMmFjhLVYvzELqSE7zhLjbsg9BHN4YvYi8AtcsUhB457oxagALurrZfk+OJeMkVkH1Uh0UwrQB3Cs9j4/zrS76M4WID3wQec3/PtZIxqUWMgOxsKGyMKfAbbLnybOtQLgXY6WvOeckDpgOIAiV3VQaKzlnQXrQO9ew43gN38oH2OK9eFkklRitvedEZre2gkBCEM+tmJo5T1q3i6HYl+VnF90+6X94pXYDpb6z7yTYqoIAlzvxNoFXqJR+8RuSzQzKxXxCcPAusT+gO7uLeNU46280RgypANGoPkDjcVtW7P4LobZxYxMq2LEPiWCamvvJfjvRx932unqqMUQQUcVGRi2Rodg8z4yBU6qUvYi7UKgxhXFMoJJtrxcGNQm8M4Io08GL7p736Q0s1R7xi6yS9+mpz79d/rUvAAKuGWRBvedDhQFZ7+tPPzjs4A7iYUPaOTFyb6BODJFew63S8PBTYg2iMKUlWdeEwHIY1L/GSU5obEvRyi9wXUiuarv+gpz0bUPj+EDMK9ve92fQvZRsKPlp9u+7z1fGYR2wQROo4RpOZx1s0RSN8YjsrVm6u/1YLjbIPzIiBlo2/2s2UCBeGgvE6JFzEusx37MVIAvpR5dH6Sy4tM4UBEGsL5P7vjPMI8l/STH/OHSgKWfbh/QELWUTvBwqxW80WQa9iyd0RQWC0qQD2P/lk7RaiVO4E1sX0aO9huu0MSKOjSxgi2DQfAYtPZ4atNgKe2a7dxJkB92pnEkXWMPowHzhnsWZMnBTMOL3/VLvsCRC6eU2PN2YCQjArh83NqeFtTushP5auOcf8YpEPqFTLWGxUGX1KccropZ6ynnhIdzMV0HiM/AocQSTOro3tkGyITmMKMsnhOeTkrk+d8s06AoyWL7SoPsCIiE91NxIIeGMfnn6KhF5AeX/XSYcgW1NoSa3wr3b3LiSqzjCrwSADMoneAnFSlF1jsiD9hUzczhldqsyWrKJ8s8KBxeTo5tJ3liV+ljgpwbJrA4/bWGuqRqM0bJpajKcqdODY6spxggvXVaVGKHiMu7wE2CHrPcdn9IeypeJiyVgTd9Kc4xgRmwgRf88Z3QrzegR66aaGGlfM2tsj/r0GLIWq0ze+nKPMXulHSGHr5GJlZ0SBYQzjMw+nNqO5TReQ8/+YDZfVAhqpaE6nW0UVavaaRcqKiqg8Tdr1xciLgYWwOCrfSUQJUjV1aee5Qj2rPprU9BmIZsjkacc4RR9q8YmzByKQWUaIbzIBIdX4iD6slYjG25ax/iB6QorYeRZVHNVC1OAeQZBWTJrMyrrbBGIL+GsgCwCkkud176qxc1HkUZcw4VDBm0f9j/6H8XtBCIg4XYWpKffLJw2Mcw41xBZD4hV3iPIi4fe719T2SWFtGBxU1qLQ6FcRwajZDgbJPGBXdeNW8YvEgsjxpUZ8xp+8BLhbpThzLPydTd4tntJ+EvSC0pcATc2RzDiIkrThq2vp0x0jfCcxdTisMAIGCl8NIvkhVMNfv/yVlnnGP4JOHbFj2+g0/z1G8h6TACpyinIUOxLbIkTs9V7VWBB0yTRkPEG6KakVg4mMi786bWl6c4aPAwbIaFK0oHms2lPFQFw6lY/6W9mw73kmlUSJZjCtjSySxvFeZS9bVm5dcSZ29qmpWCiBPVxAybpKJQAyOxqm8PGm7KnQsWLj1nKhWVB0gsM2wqF3CMcsrokDmoXCiFc/iPq7brUOqFLb7doHpW3/b+izW0OlFpRsje/q5cYOetW5O876U3+65UnA//kKHuw8yTy2wdECTs4OKJb66FiLNKjKQBR3xcv0DrYXoYFekztiWpPA9ozhS62wjjgMagZozbbSuPAFRTQynNSS4dVd7/MfZjL4+bL0qttVp3IqbNrVsafOtTVrk1VYsPGdgR/TxYqQrc95Q1WFZXANVVtu9ApbcuVhMiySx7qpXdOS5nJ1CHzmS1n8Yuo7YFpF9WEX0jlvCex+TZjEkRRjoAKd/76fT8dCKSx8nG+aQYgPpC6P+qTFDtIC2JX09JN4F5LwUEl8Uo5/7+GYhOsAkELkR9VOfJ9AADeqXAPTrjfHUI2c11eDmjy4++MOT/wr7SLGFofPLDVSHzOlvu57bsTHPhz2SDQrVvnZVhxOMriIjh3IKZkpbJA69fuj4DIsbH+zNRuSWYQgao7E21h/s/aMdpuWVJbDgRURPq0HLu0EeTCUOnIfoRJtUkdM81h+WEeKSjaq4T3qFw2kk5WyqX2ZvwEhPW59sLZtypaiL1g0FpGCNsOOe33Eg+knyHeALlUSkn74m8fOghKTEppNuzIRGDzezCoKzp9XtYp1M2kQy4+KHPVROSdgIj7RzjbyLsNYeg+cWrhG7lgDRn8xfyqkbKe+5boZxHMOgoBjs3dWPOlPrzyihC7OAKDL1kpTPUG4qNgnQ+l0/AlbBgwgUvWZ+ry4EDdWEUu0t/yhki1GlynGWCX/X2TxIK+YG3piJesTFGAWN0W8nEzJfiLJTJVH3FoydYHDsrrVRuLQiR49rweCI2LWesPKZRNDKBPlMJHBBVpspwREGCfsVpsP3F9i8mq/nEhlc6CwwDLxQvJoq3khGbL64Q/w6zhGeF7C6wCaARtMLxDnAA9kGGBZcI6yOiLpIhtZtWwieEW0AF89K3aaIrkrxojaNLcKeA9BDeS89nVJQxAjx2HEaQ9UpV07cDMACmrCVxbBJlbI40oxsSNlcAp25hUUcG0jYgYGeVnm82giiATWfZAcqeD+pBAjb7B4CXh4ySpqwT1ogtfp6YPEImYcbNu0QC/9F4w3risYxOOfhhkGwuiT+GlVVbmiYOwfBBJnJF8A2cERUBRyNIE9GlBsobjfsshUuPWvmPAKJW7WJgCK3PSSTWnRT+2QPeClns/qaXprSkP6kmpYf4akC8y6QCHUpCxYO1O1iOwArW4gl+8V60waGW/j17AJ+m+yxmIIa8pSbEILq7HdwLS9tJZ8b0pMw/PGW0IvJ4UlziTHhUITHoGfHNwGFAIu+QakCihG0EqzaKj628kq374DtEJt3JN8DuHnq/A0s/zYiXwSO3lvwPLZjNvXqOS6cr+lBwagpuNI7PgbX1Gjjl3oeSHJn7P0s5H8UqSKGbj5Cjszgi3ECBiES0ISKylEonMBwHBBC3cOWB8QKpYmVfxBq9SJADt5WwMhxD88VaM0P2jyQh+Y3b46N7clfHYkxoZNzpLN8lYf4BOcq0keD73KIKr7rhTK5R2y0wGe8sqggGrXuFF+Ispu6tAPcODtKIZPz7xy7CnkoS5RX3sAnOedv00BQ1RjRwzdP3k9nBN9gAJSsljpVCkApUFIYdlAQPZSWjrCuUq+2sR+pizWHuf63qEeFUJK5I8FaIJwXaHrgIn8rSrLqwKlxse0eNsd+S9y4WAZjrba2SqC5/ZiP+8BiPjZQRWkKTdoKZXfQz7jls87p9iblnVWc4MnA6hSP+thxBi1gZSROPZuv4DuvqBkFK8CqZPa6eK9LR4Gecg3uWnxdiXzRC7IEjVwzz5XGFjOjyEWqH6+eCRlO9x1ctMfVl/i/34i40uVOmPYpERridOvJQ5wXeYRqKONTNUGLUEl+RlkyZJqJv9whcwGEAdFHEKz2ldi3WCl9aaST6uuHp3bhgwPn1YxcD49w8+WGuSd+sOVxs8Di8BOWdYDxTavJ6so0zF4uxxueScee9JUJAe3qCdT6CJNpvGDyuvL0HpMOsHQlWcfl5ySLjD8DdT3Qc3fa1jTMpprmiSBdTvdCb3vwnU70fuVJZMym6kvn++vETjNQtgfC2HG7QMqgVbePOnajAVbCyFUkPFol5oaJO8+GeDH+Feo9IArLIbnOlXhKkBPW9td8M4Vnz4FrRDuMKskdwUjig8ZZHM5jBW1TdTVbD6U+4MXY9Pcd2rj2sALxc9e6S7H5Ua/BBJAnAzQEf6csuTB+cY3ptRSq/QrAA+MIrcVLJUqf5mbCJyrIJH/QPODltErvXnsDdeDUHXz+8JTuQLGXpSEyL/6B1zB8vVfsGLyYkLqSJGXz1GkThZecX5NU2MRbs76Szfd8utJ/TlmTU0tEXzNURUwKbsdd72hs/Oh5WQwDM4tpz+WqP/7BDcM1ZxPmtFu3OxGsnFZVD0cK9hrPHAZnhgte3rZYvDG+E4gbdnTaMP9OSMwhdkkP4Hq3G7Kuxte1YEflaOkUd4y1+EH+g69Pmas88ZeTFs2nKPiGAWRB7ahH9ED7U22sYvzxlROaGNknAg/SF4BEvotHo2SPxqR3SiNX1Djgr1z6+Zf+b5hUG0iIJJitEuzKHvMTG+UzXc4MXv2yLJRJmS7vAWZxl9w+09MsYy6QWCdXdtc/9lWQknf2YV+t0XxqjMwy6c+GHS87K7JkxHQmln3s/kRF6oKZ2GpyjvzwbVbLrVJTJoKW6sOPea+Q2prSDWvA8vwYs1G55CQPvl3g8WdP6qbOUufB8D8B1DcNdgDFcLj6zj1//7k7QpX2XHkcfXDftc3XKRtD3hNxEUMq3e4I5lrQfR8SP7X/P/lBj377c3bP7JdrN9WJ28zJ3ZXH0iGI9RvxwSPfz49cl/giWliyLPJkIvYiUKDzkoEuef6KLhZCBwsXJNJvvE5tWEq8Yi/sIg/DIuFWv2z7xDQrmBR8/u9Ja+Im5eeol11ZL2XMTx6IiitcNMuXMNlkF3TBPXiQ/vRWZ3JeZuI47dFLpToxvVOPa9QIB7v8NGXXEs+qLnfIBiu6yLqQDKJtJHRUrYOC8dZnZKIoNn06SWrRMhzI7lO0o/bMIfc39RsyqmCiUoBHbqJzmpcAH+8CCam/+z5r4VQ/NSdQk78sCDIyTMYufCnFUHZvFDU5efkGczFaltp9wwz7iZ7fphmYX2b9Ra1bn7XvOfFZSDwVk2FoxyuKPtKdkpC4oCAyYXwyqp2VEU3k7L5X6/L7PHyeTKStN0PxMiAHw8SbbCyyUEbeGWXn/K2gYOLEOeEK7QsrI08NCiV29nQjiG2/Xlg6hjxHFTQHHE3TUUNiE1t854mp+4bC2MylnnQdUMBxVsmFZ2H7erSVpbEO8IIL5fHqpCa9iyTCpCrBzMIgMTPINXdPEwH9KAk00XE/F7jtt+Aa2bJ4VBEmTbkkgRn2jJUpm1oG7VIsNGwWlFrQzeUGkCdvYbfS7ju7T6GKTP7/wJyOTZvvDs33Wo1HXrRzuz3d42oH1jDdzDM++RaFkJNLnV+bpDFWO3Mv1jlPX40OcchM4nMnRgcT3QHSbpXXcuwmtceqybrzxV4EOt5Kb+nOdgDIGY0EWeRgha86gazP08mMDVn0kQjum8MjOFArDdKK+bDU+YINoaX7CfAy69neJ1VBTeTyj4753zHHrZnxwNpnb9P3TQ6vnXSy0mi/68aaaRTq4J6yBiuvmxkNvolllKNxSeQBbF8uBbqhMBOdpbwqWbEoJJyfrkWas0IfUHAajdB8gogzx4q83g30Hm/QV6ClmFqD9fg3WtkjByuvUReSZzI3ipGtQg6lijRp8igwbPFHmZKrdRfqreelVyzjce8azdli7QBNpb4IkWcUqx1Q7mNlFbyQrjzcpx7Rw1wpVkEgSS1BQ5fN/jvsS2GPswLIoVKZCf6GluQWv00uU/M2QokMFB/KkXHxxCtLujZXtcO7H7AxPXwI/KCxDsWtLbtJMiDl7IgGPGL+O41qt/o/yhELKN5nASZeDTllPMZB7PycsREs8QnxhnGVjiOOjWhkO9L1aOvWCLOpz46cH+nYxQAJYDkhQX4OO8fArZjHwGXUcVgLDF5lRzpAbJUjR9b9QLULu8/vC9TWqy5/j5D1eWZ5PGsVEfz/rCpFrhrfiqTssF9e27EBfM1lwX6gK8P2NVhNyCZ8aMOo3GgqSvP++PWcBiwVfHB+BP5sQZcf05HvhxFu2XOtMyCezsl0xvqAxoiejsU4j2T8op8xi18dyEzQf+jovJ5xl5tNZZgFUvj7pl28/DwEvO3Z9qe5bMUEAECL3/YuMAKujG/vi3bdvIuyYR/Pz6KBgTl/ax55TQ65bihtoUdNF35skF2ETs4aJmN3V0o6Wtu2NHhPzGJ+xL1ITDoUendFO7ASuCxvg4XCkniu153OiEKp0PBYKE00g3bKvQ7FMM+vVceMRkkriOFY6uROrkNLSeGW866QOLbIKLJ9YBoxMX6WD7cxE9V8hdclgd540FRPqqV0eLWSwm+UAkgdrawcW1VK8GZXHLqKcvSoXUbtpJ//L7Aotq+sRU42el6d0QuLxc+oH4loSlohgZlL2b7NMhmLkBEB2B2XkT2siB9Xso5MQcb1G79xUpBdmyhXJI7+iiuWcRoG22Ot31GiVjMskLUInOmZ3JHZL5AJm899z43qUw7BRV0QAdkBuvIGQvNoTOmZyVjlIdvpFoVxZu2mSaZc0SBj5GGOed04hglVqcIBHpcXvok4PHKbZGrLUUn9Ay4xHUJdEGAYxxQ9DV2CsiP2EZVUUp99reRKh1RAt0gOtHiQCoh2ch0YdGB3dDZ6+to+EppDuDDH1BRRg/swPWKFD9qGPHE6N5JnvMDnz8hFAtiCyW88CZpkvDkrvK/NxQBD1vYIe9aSNeggAfcLW8UaM6suOpXT0K52ipFJyRSGkbckMUMldI6D9oipXleucJVI9xrWDa8AzyLSpND+TfzrLGfkT1XmrTso/UqyARcgaZOpsYKVqbLMoIDSXDQwjnaReT0XmzotTiuttUz2eOm//8trrcXycBdcYiu7mNSimWHL4TXf0YxZtwQlg0FINXnmUcc7PbLTeE9RZfaucJ8Jh9nf3SWhZejIMI+u6bE2/WgBCJ0IVB+Ui/fkQsv7lQoXrng5Oy1WNqUZEsFokg3dfr4FgP8IqqBSM44mwhArPdb8QHOOsYi9Np87cFY4xYx8tyAXPJiC0i4EqGq8Ymwi6rAOtu/bJ24cr6C//LTJ7CjKHgNMQV3gtnttUoXfMJOTtiAUK3OQIyLkAHznhToICG9FL2bJe/2GWPPsEG48gKpQewJgjAEtx7HhQo0foKUCI76nq/M9GoqSkxDhW51G9sfplZ6g5QqP5F6d4I7zRf17zQ+qUEc9IH6XQYBGSullc/xQ8Er+cXDX02KhVWcD0gGyjLSwvL8vpzFZ/LqtrPU6808S6AfknS57l0RplSVKsBLEte+tN6sQKn7LMR2E4f0mZzwwR797wSek5+yws346jif/l19nfI1ErOuxIzmsCBqr9HvMnumhwzBNDYmOI1Or8qQI5Kk/pVVyQ2GZGXKsTM7Onithswv7chThkfWqj4Uk8mIUtRsgKz5N5KB+elVvOnf4bbjDfHxSy+IvIQxqJAK3HB09uE0M4jGms1xRGs71i7Ba7DZWBIqgnW/3a7Xo7recKIVJZnAjU7dniechtGyK1VPscJA2pgkYvPK0PvOBscFl4vhD8jsmSM0YMYIe9Q1QlDArb+y/SdJcTAT0cgqxxGmERF+ymQTL3L/NVCt+g7TjXB7NJfrl+c3wim/eEmGM6F3YiUOe5XzKsucA0ab8fnrW5pWD49i11jNrRWiSIB8955Mlw2ZhBKAAU06nLcNCDEnSzqwU/9yNaAk0H+qzG/2XIj1oOD0CJ+VsfgQTIjK1Uv7lNhZc92PR0g9vXwFzX9GX0voDzX9PXSpJ4sshjXgoeEM32k2xC5IRAo7Qt21i2YNWjERtUUPbowwJQP60vJEMLLNamVNhOCME5bAXpmZtRpo2YYmfNc24UezQ9Bc9bRD0tJCJQ5AbDVeZKsors2V7gIsYsM1aQkw+B7D3D68JScvAik+l97rnK2XZmWoqjmU3N/ohR9QGW9mtVF45pjyxYi71QXXO5oJYzx9e/4So1llP/Pii356VAq6mT2e8Gzt3ZcIo2qO5pJr0ilk8WbbgqWfgB+6aVEqK46fXq8bPTHDX8YRmWcBSNyQv6/W2Hqi/usm6rvQ7DKIqsjTVdZ9BpgbHEqn7OoSR2TEhXFd1z3j8NR04naiWN4NsxZy4UAW57ntjdR0n/bod3sstIK4113HbmfFaLQ9wuGRwcST+UIyfGe+f0MnyqSv8hdzC9FPMPvuITw9Slw/X3WdNe7agl14tJmoZlr5p0RP3M0RxdVr86+AqkFjT/obqG1gjhLlaeZJy1etqDsMDZoP0+WK9i2FnJcOtFwS8qWBZghmv0IZTik3mgvmDqqBwmR1CvpSWrZsMG46kx5LZ2PmAps8kqG1vOQ/vmB9Izo2adUtT6fH4aCY8jJIpF+k03xT0iuku/UGa40xLUtwLDO3gydzGd64Bc/yo1YICpUEOVrbCrP9whvR31L3pdT9OwD+w4r+6bNgG+Ui+CMkx4Bsa1yvqEA0U2aCGT9NQdtZrsLqROz9fx5A95HUFQahrKNR4zjw7gx5+43iA36nN8Vf/A2FfD+Vx1LPqhVO4aeIZj8/OQbF1KruTHtbmOFQXR2+RTrtK89AQrkGMD8LIXWQi/JwlwGdi2xZueVyfl5CZi4FM9q+53nuqSKjrHsfY7c59YvBFTpjdcbJ4Qqte5fi0B0U/d5GvJNAM2lw2iy4Lhtrxlhy4iub8mhqZXufzT1Hyr9x5vZUdMMean+zw2Zg1i0DeGSLZCy80RWW9H9j9CouVq/RWep6oFFCeLWs7VKYrNttEqTbcQpPbrp5Hz/aQpsWZHPz0K6CSSiHvfoTtvrdczuoFjZrzgGrecsqY/0RD9KmcPPMLjqSLSZK3aPF3CEB5o7MnuK0vtPloU1gJf/hkwa5e0MC8WKRwh5STacBL1Hf3rOhjq9x9TdHRpgbtViitfOwOn8+78m81siRRdxx/m35bsgaKu1LIgs3fDZfGlKwyXMDxfsUe6RRF8+rJv5g1FnU7kBuEGOGkB1kqIDVvRSROaWBtwK3v4U6fLHMrbHn9DHn/FFdwMrtldIxdPEr3EGULY9yGrDVMNoYDbZvFvjhyrCutMzKLPE/xbWeOeW6nt0lf93ON3Qg6MKpzo/hmfUrvzLFQveEV2PWppBzBgGV+uylC5zQ0rHOGnX17T5rIsOtUBJRZvBha4fTblEVUMmb3Ao93pz8nwDhZugKqVLV3q3+ivPeWigHHrxZ+u2RqA4ia6qG4y3wcg5giFnT5/+Hb9ZTS5b6EmYSTaz8knhgfZSYaGq5QNftmB7qDuNhcKeBpQel9GSNww5J35LDNbzD4bAZ0jK5ybHycy2RQlZWrkJp5ydswJqeIB+tMIPdTt6Fho5tXPGM4i1QK1eyZOY7AGtCLFHDZfGSSb4HE38MTXeKXeOEhfY6oUsY9KGf3ZwbBf0nxo4vINEiJPyFSvmi1VDRmT43iTRCLYfULEw1gyyegVqOdEMhcK52pokT3KCZwv2tjBHyW+Fh9o3Ql0lcC/84CImQKIcsKy2XaoIEOk38AU4Xuehl8USMlK9XSmDA4nu51LK2djbnIQu84v8OF1VIpukNa61QvIBb7rRVey/50ueLFwxejR60Rm2rDfE5E5mZ8XKYHJSV/R/JHtPR3KpP6/8r2rrq/OuJrzSMRldZ07ovbnm0nx2s3CWjpS04C03riVP/dzKTTLN0mavDS0cQ4JTA1nzGL98f7w66ETnB+M8sg3xdKJ8b/K0fTIleHVhPs5w6ykhsmVR5hgFm54sq8kOUpC6zK1aWanxm2P7Pp508hkJaBE+5FFHc24LeU/Jx7WRBu9PwpH0/fDkiOZa73s9QgCwd43ALbYVX/sau7bW7LaPFTpzZvMWXHt5BWWyATv0BwZ7uJKgnm1ZJjO5eQRqL+hLD13gBxfCDjSBuFAWE81uSPlVyAyix2xBviV3PIcQ/0h5Y5gaKVUCnq62OcAR1H/lmBkPVcA4aT49u5/Td/xKHd+kppsM2NSBNbYuRT27U/79Y35FUKpcRPldEp8nhDVZukBTSIsf5G2NYu5LS+BuAp2Zz0Z8oAbwe//xV87oXTlr+S01NuhDknXVMX0CnZpyvfWmbH77ayRDH6MDlze7A8DQJedIw/M9AuxQvW3xZqSyiMHCM3DIs+gkLPBPM3QZ/BZeVJcNpKkKGa0Wy0U4uX6hrafrpvQMx+hYMdxzDpFCYvGy9Q8gR8mzSLEHevtBq+KuUx/o7XI9mUZfOPnesBW5kpwJJHVhM5Yqbop6/k9KzhSe08gPD9MqZekgQOWccDCjdyzsLUj+zuc5SYeSj4Mgyv3GBhCIPcFsm9DZmi1TItqqg3TifsQd0P2YPc3cOuoM/gtNJpJvc5VP9MnyEcmdSoB5rbVMrKp9Iprrqqwx2NJeoKG+PYCFXT9coMoZxIxPh+RN++bRJ4U8926DZACEtACif3CoheiZ4hQ0q+F2RazkW8P/3JB6m3MiJEPT6wwntjBd4MWE9x5Xa5zoOUzJ7DSaEnz3goeSYQ52RUZJG9yY+j8fJf9PGobiT/OEq068hvu7FXlBBpIeIPc3M3jhLkuzmANtgRfdfOSfoOQZRILKfdqA4e97mOehWrE+/IFZ3Jjuvl3G1zkXa0xFQu45dfCl7xe/5y12+7+8DAiXln1J8RWPc+lE84vEJov8N/J/kATHhUp/k8DpQNPS9FyoAhAYVPigR2nS5sxuVhaHB6piTiOaTh1e9jAZ73SsZCO8SzqGIVGpXNvT5EdwzKcf/J5cT884UkqfPZtcj/yiDd7k8hToBJidUs2WPJWCBXn+5k7dB7wuJL8M2j1F/J3Oqj9V8iUKmCvomWTUlAJThtuj9dXUqSKg3vRy8AB5PgatWgDfYAgXj3VFpeaTtLKwDXORg8wZW6Cza74p3tjbtvtwJIX+lsegIGV8g8rkboHx342Pqgn1v/mtWz6FEJ7y+NgoO+C7ikRPhs1I/yV+Y2UAVY8e9NkXOQd0pieNs2Io42p23B9sJlv+CPDGxzwMXtVGY2mcP2z2zDHf/nMRdwUBxKcj7kOJ8rNeautlBKq8/JMGCpJ92GcljPzCX3SIPBLRXSZKlpdMWyQWnOdB9SoF3czNV0HTCphBzSihM+ZIO7GFGcPS+yLjE98nxFtIB1NH9RtSy6CPOL1p/3+2NONjamL49LuFlEzRSHyCm3fBGDh4+Z9uDGrqBSXLZS61B2QpXmZwwUfM+Q9P1Ux2f5adlQxU5by3Yed8t31r4FH91mWdphO0jOVtTC+642VClHd3uxo1Sx0Ms11Jl66CnrXjODmk3nMxlEVFoaqxbKKpmrkncf1OVu3knaCwX79P/sujHsAxzel94PDK8vrROcH7boFa6dL1rvBFYdFzcH/KhaHPmOmLAXT9uZ3RzqizyVIqTevz/+CR4sdT0rhjL93BDKWLflPV+EEeTZenD9BDN4tT5t1UEI3p7lC5pJEPM04dCOlSjx8durFau6qhKlIXvg3KubSkURv+X2Rnkh2j2vEfY0Ac/ank6zrvyYCTJT0XMoo+6AdGXPP23yW08IBtHmedaQFHsPBKx5OTGOGbcfEGnx5Grfe3+/FRFF/MczA0KYz+Yjm0gzazqnST6zsJlf6yFLUs1gSQsrfME35+FpF4asyMeh79bF+gwZMqv7WXgt1aNkfa/BDCbqNu2R5qJ3BKJ0JF4aVz6fmlJqmO6M5tWFd96YAjZsi9YpNIv8WJU6LHYOWPMlY5I3QWdCJ8p0/caZ1yXVqf0xnBDKbO9mBDmv7zdBiqFYVfOVlVJabR9R2ap3PzEXzFcW4lgCnV6otP7IOkJ8tdyfYVt15DNEi2w26QK1UNJkxhQNRPOtii5l3u3p7dkaoRvNbTZcjM+53em0qYSK5uY3ZorZNYs8FSovvOeEt1mWv37fosOajRovaTtfm8gWlB2uG5hIp6mVFiYakd7TbBTyAlVKGCs5VVP87cL2czyE7Loci72pIjqc6osiCvmzoBBrKEaiC2liEESKR7tNDZx8hjFTboJpaz9SjHVrl6S4q5OHnMRxtPIYehWe1qLpdjhb80gxlnqqNWfGtHcM2FITfcgApVozcVTVoyGhVrOxmCKACYfWYByGJXfr/w8k6xCy1slUCq6ZCCMWed5iWojb5zwT55ee6c5SnTEOWZCZ545DSfSKQ0PBA50ji1gKMwy2R5zynghUkAuvkbc6hJU0KPscmgy+Q4InnJF2HA2oXiy9YaJBQzms/nLZcWj3u5VdTIi3r9lbxeX2P37ERfFa2lipy0+Nzdfy6SAWVr0MJsNs8zO1ecioZy7OHqbSfsc/JjRXTaAqzkkh5k/H2MA150QJEneQ7dbMimfB3JhfrD4ZS9aSu/Pukr6bqFXyDiyZERF3bGvpuL+rDWgmcXnEPlZTD33pAikvKWTaPMeVqj3fbnVYvmLz0/VZwQTv3zDdS/fGdiZ1/LjeZhJbc0DRnmPPEg0799pKcW+oGm9+aRnMwCO4C/4w1p7f+lSsfJmLzY3g48i5fZNr0NhZ6pa8RUutjJg30CXd3Z6jwkc63AUoY2Wl+HkLYixb9jyD2xGlppM2py02H6eNRV5oizfn8ly1mKZ134m8HIJzub4Cz0jiQi5HNXEFS58Zblr/CKb5a0rP5dY3Mzijy9Wm5PY+btRs5UWDgoyZCtGppslVuFCOTB8j0hRC0iS/Z8F5gpfLOUAqe116CP8EW9GquD4ZN2J8RbDCnTILoAp82kI5qGu8eCJBkw7cODY5pR7p4CvCSwPE+vuzB6eL0gFBsyt8yCUOLrqE7bAEakfz5hVAuSPHNah96U6b2c0slSSsNXCgz9TnTJzBxRcApZFGSGbESUnpVkbAwaJuGDs6xlLBkml5lWTRRNCcFexDPubQvKpxOF+Q/zvjDSCONCTuW7GYGnOCCdlrCfoinY8KoovLi3mXMlY/E+5FRFHJMbSiMLfY/RExrGz/M3bJqdCuni4V9YyONXsaYeLxWpFcz/fahMmzUuLD14HWUmerH5k8rlB2DX6Jhxz+c8NTzFw2LJRObdWuRnDR3I5I8n7ozHPnkWymGkevg8ujU5eCkUsDvFr5bhJhpeQ4AwtftkQgggxf2QbgqneMrjmwV6cNYzaosKxOMavuuX0rT24zDcoWPyVWd9QBU55bSG/j0hgVIDGASj4GuF5Zy1gq84xcBmAzvBpB4j3wIFAg3wGKljeHgj41VweMtJl0/W64Mz4ega0YnUvyra2T8Q7F5CmUEbfVXcaHJpGVnI5Efjc3ONzxx3ZoQfHiwZifR3CAxD+wDdEtIqomYUCQcGykXaLkBPUCtKTELFWnhtFF0IeX+58x3T0wbHFrkNcpfao5nZ87ouR68ij0G0Ee53V+Mi0ue4/EF8Y8yBrxFKA6397SQv2HIc663wngGAs4RAvzbK9JmzgrIDymx7RlvzOu0XD9MD8Vm9ahk5PXhWI2HPEJ4fcUNA2gVRHXbVcy7AWPJAvTXJzhPFx2wZbzp0fVuJVqh9PIMagz+d80JfpLcwLS4xqqUm5FLEdSS5HNbFB6DU5rhNYpo2X9ZBKmiKFr67EOwjGbtB66yU96yi7PCkmq+QC+dB61V457DTjdtFOTjyfL8RufjSFDqpPWYqGeh9D9PPZf/Bt/TLMsLR1w2NWIz8kpy+ywvdvi3GiDHHUKCuUHGceY4mR5yMgnuLSfUyyia2WUh9SK0fiWmlHFmdQNnXA04h0uuttJx2DeIHJKt7nbiePACQTkm+B2gUOkSPXowiBsLDiFOzKYtm6ZjfPysMpdvg2th3SfggLhBrHmncsCy91HrY9u2ZQ7aosS4K51wa9bM38T6J1KVWg//N/sKvfEdFTpF+1SBRVgiSmYmXmAYN3x4NHPysXxD+2k4XX2bDeh+4o2HDs7tFWaYcmwNGRVetySbv13uli4TBbcR+m9VIy/tBQnZiooV1z930Ugqc6nM9ay+Oq3y/DqRse2quyJ+VLayPMjL0P1UZPMvThF9vP5Mp2Qqv5juKAEW67xepI1CPPNcukAPx1h0vr13iULc+RWdCI6XOeFMepyvyKOyBWtiKG1LZwhuZUQbTurMBTO/q5uTUmBpRVShciM2lyixI0KfqvvA1RD0VcgW4Wyyq843+TNgO/5bHHg0y4842anxTJfIxao/kzs9EEY38XMaQXIJyL3gKdY+fIGz3RunHZApIcZN+JOp/i1p+GBWWHkgRpyLtKhZx335zU0SpI/tbV/N67JUxMhdM/SrvSSVtSbZKu0feHin5D2s6lVdY0EFGwUntyY/JMsDShfbpy0sAzQr7CIksjSizuda2nYDgIoh6R7KWfs4sS0tzG0ftIwA6QtKg/dUVOXYKMorC4o69ZnbKOOptaSThfgCM8d7ZD6o/9YOPjqecflSiguqu/iRvoHpEmua2KZCLGGO3fb1G0JqQKSAIy4QADghMTg+ARkgOIxW2AY9fRyBKYoFh9BhJqlCFUlCcwCnhwYUayT+iNty4nSugbgokTrkNB6ujUK9RQqQzorBLXsr3l49s2qel00PyFy+0M+23EF87bsfEGwlm1nuSgs8ExjTTekMTXnJKh17HriD6zUNzFdBN9l0noEXcvlZ937vVynigyQDGX/NLwmnLOsn3l/1+BrBRICwbRJLPMePpj6W87Aqcl2FwpDIaydqw+rBd4/XFNjKfbt9Vjcxb3RNFWgKvSzp0Xy4i/v8nO66zpqhSQfZlX0qOpqVXnka8AmOazssCw2yFpo2WO6E1vi+SfxOYHiEu2XZqyoCTtb+3FZy9kxAT/BqSnS1pIXyYpnzraWiCNL3H8S92Sy01wiOiN5nDFGjpMscfdJvP/XpZ/o7BSHuUXiokVYJnF4icsncUvIjizRlnRx3KysimOWOH8S12RMQlezwq6xHca4Y2L5I1FjtkXwwm7TFUvcjeYwdxrRNN6i20XzAd1ZmZHFKeGBzHj2h2rnurlmeTDdQ8dLyPKpNHsZcxJO5PKwSdKipsWMUnJsVLlRS1Hb/dCtQg2zuLxik1vB6npVChoIGnjnMK8LH+xhYbUX5sx8gkHovrUkqRgqgn7CIMA+9caeEl6xPLSsYewqwOMNa3uAzqmuXCrbOeTuCfZ68mW+p+x3Y9eJyGWYypXoZAFYegPZJPrl8hXz4nmzIucUf5NkhoROf2e4QFx7KSrnnhjwswhFu4t1tmwdYfaHbabLMXBhOnrqzlXUqlyOVabk1XHOz8nR9yWGl+VCIYOpXJWqYPLdmL6wpIlP/OFW94KjbZ/jlN9cS3oK9/yHp5LF3ib6m//FsyNdUByBcUb/pPKExVNYOn8p6tTuMImdl2GgOrORWBpzLY8qUUUvyeQRRVskVBZYjJSofPTcXApJmyziMiUxnAWMi7MXde+5CeD5sN5zAt/fkbWslnC8xC3tMEz/1BhZ4v6TuCeXtZHF0PYOJvOobAI+ES4d+U3CY01WnP7aUnNb73DcaLpfqs+tWq4bB0i0OQ/qw8aUhDX0LuauMk9pC24juhzN6GvMdwkt6vxvk3Nl2w//LJp7WYdz0dq4dJdEzWcrvHHA9MsiAiDVdvVSTRw3W6yzZs+1Eup2kvyOylLsjwXwMl3Q0av523Fh4Pb8nNMIp2K0lbkTjZbF4SUun8QtASs4se6AaRrGVO+jLb47X6QXS5iPHuDDe1Tjv2i6oTUKP4dxFzvf0GjYmfPf8RwkrgmYOYy6qEXsBVS42yeL7bEwbPErKl9sNC5Cra8I/QyLINkljk/iGJWQ5KytbqQHjH++AiQ/8DyuS70RYE/gZQ+ENKlLDmq7S1EEP5wNek07ROjhDv+FDogvAzpziPTCkSJwmVpi8Ul5su5FHtBQEcAaAg4BEQHueOgEf8GL04DKhbPwgUkpAzKX4HAjynNbQYxHgYCYLVwxWDYHCJcguChTqegagHgYGp7Uk4sTDQXpOXzvBvhXRuRKLW6mnSWBcjFZVbIaNp4WHJA6YaGU0WN1l6pUzZrEn4/bCzQN0yeFh8ShsVb2SuPnEcTY83zmQYkcaKK14BXiHCAy/sfBvRRKAt18WSrM6AVNWUfFrIFmtYHW8LRD2FQNzTJO0Mgn5hPh5BKBNSTypHgkU3PM+zOY7ewgY5t/dV+tlyJe3Rde9orCInV14BfJYQmVZyUQ3QU/VBKkVQZkLeUwZ1mnwLtiuQCpmd8B3AJC+EkOIKIqBiRqLLQijdGN0hKVT6I6hwgWjeaYOOg1XOiT9khMPdbQDfVknFEipEkQlB9WEBPCygZIynNHgrKbJFHTMStYOcAfQEkC81EWxWP8EWOMqPQCkiUIuMBWmpeU22E5Jg+9J4bR7iP+fAPN83jsvvCiEwbjjzCRQIvqnvaigRNqg7yGZzAzUfFYczA/Ix29M1ekuUgoc46F36OVUB1gD0xPnnCCispEeyYZ51s0G9jvSinbSaQxJnm5c2byZSXnXJeHhGwCtzI/AmS+XKkdNWKHblcVRK9l4u0okmiWDNPGi9+8qlstazP4j3D+A9UP2CRlGwmDn7XiQY17unwK/9XZS1Vd/CqbUMmU7sI/8KBZM36ExlzGnIlO4Y9XuOuqxbR3lnCwsi5/eBsxaTH72BU+pyLAfMSZ4YniGd2VUQIZ6xGKxnl1sJn/+sxs4W15sY0INDLvMnZ7xUjyt4fv2yu2FA9moc/CFQgnkYZESO4hMcRz4sQsRg5UkKfmX/HnyhIumOOH+pbq96T4HaX5GBkY00/nMrW2NTNUZRYXneO0aEYBmvHZYea42kxkCoQZYOuvxyHqJXOtRnoT1xkufBuYQHm7xBXtdd2NmsBSGF88PIwDwMzPWKsBE5oCYV/O/j8oURlPB1uY3D0OFaYxJcLXcqwa7YTEdobPM7tpTgsrzkbZg+DVjI2gQVqVxQYY5BgABKSajw1eyoWjILwArpWXluWv0qmYUGktZOzXTTKi5e2O6W3vhuqCrwzB88U89N0WR3ZJTpTTV1tKSC5fskDKPetWwCTSO/HTi9arrd8opRI6p7BznUs8nDBTumSi+Hlnnk1c5XeaalQSSqgMHUzm3VfjY45JCAelzBVyrWdrO9sol3x5TA9laqpbNbcWuUo61pn7Jicry5sFZu2tNnuu5iwNPeKyehOw+CPhxuweNWzkzDsr2UvF9KBvFApNwyQj9YFlP+WtXOS63pd2Qp9br3p5gBFaNomS6r8GDf8+Vl4v1iFXhW3/GFCGNg7vspJ00KCSdFY4AOxznQ9pQzg8+Ve2jPqn6IK7JdGF7mjVlC6XgOepa+d0TQ3F8uNiCfgPNr8/oqh/158vimHabxMNBUQEEqVk2iA4qa21WXYmfPlEn6xDXZamD7IoXerj4CZ/NqLB2QakGRxAJFEaJ9FFsb7Biwira+cH6zJ5f0H8M78shAxfoMDZyi8Nc2cIcGwMAf2Tzn5y4dmvlKN6JlJneS+KFM/5O3licDW5ziyiRulDe+YX3XoKWSKisu57Sb4J6/lcp5YXwc8/RVhtMBMwvAyKm+ONdxZofZc+6dTHie1EjDRkIvrRnkleeFGu1UBjwCIsXnR4P1nK7D90tdmRHEIT8Nps7U2OKQbzARRwOIIYcytb4tenwHGzdgyCbvUV3fweeYFruHqh15t2WRArKN53WpIS3p9PPPR8/Tj9XH4UG1aewLX5nA3s0/22+kd8eQ2Zbuc0NTdvcLOqJjncUfACis2EizQbYvmRsaoJxEF57XOmL9Q8faGdnIgaQn4hwf9DDAmG55/OHFmCfaNYpKAZpXTLleKxVj3rZ0FpqeVkbLGjvY2rmQItjUCqREztVAf/sJdhIYrP0HrNA9kiPjOydfOH0CqjXEBk34yrwuKPgp8JmX5/bDEHCgoaZedieevqdH7WliWDwBxNg8UoWpjVD9/466cpuoGTotGUL0LygUyKKW9letRGJWfap6KUKdny/KpSvXX3cOrLLeyvW8duKYlidc42sB9ZKYnx1qavSdz261Ovh3FUlmc5k52tEN78wPjEnMva4H1q3G+bkYlK4ylWgcTsLUAdzHXqb8pzCf0egaVP8SR/vvkNeO8S2733Zio6w3+ouS6zWGWX+BriE7oQ6hB4XKT9uomd6D2XYYZUl7XUx3zgtpLREyp7K4oIHVfM48DKiS5lFbJ7zdlpa0oex5KoX1sQ4djCdDZRmG20AmUaREfZ1+GdfX8QqR5rg4ZQr+kVNPWjgMgU7u1mXAHoGzwt26/ZKFQgqNmUvOKceoev6iTIqaP6QpEaQjZNy7MrPkcVwUwDYV+qG+ZbjzKi7VzouJ1UaD/msffSJAfawzKScqvKVkKXohHw/7k9iqMWzIXuWogwEdFQRbHrYKxt6ImJNSRypyAqv69q3a7EVdXk43dq/5WlkZp048nnQ1sbhcefzX71ZwJr0IA39L54MzhG7IRp+ar5slWs4h+wRbiaWPoBYtWoAx0FEJuqhbIJ3B0ozxPLyAnomq36ldXvdydxX7zzvKDF/jDFW0Hn1PSahQlt09beTxvatl7PWq/Qo391m4wJ2do4+8KzxeA7f2Q5AglEqbR6Q01fz80J5zDgtZLl95TuSmy/MvOmJ0RO5VU1RJdylVjIQgqalFvJCFqMDlfSubvA/ue4CFkKJYwIx06p1OObO7aVvZfI8qf5/HNaX7td00orX8RBAeqp7zkk5N8wCSneBsfd8FuiGLH0/2tOqNSmkkaTEOwvgJTiWytEwKBs+OiiuLWazREO/N7IehUWerwr8Mr82/JyT0q1imumFVzMS0IOMtU+IGjwcgF8EXnoCkJJl17BxTtG2raejJkpmBFPgR2H5AokyeBrER9WZL4advQHbfOAb1T9TrNucB3nkNSPxiTPr9fhODafwTc4WytA6SETxSb/5ZvreIOA8E9fg71EEr3Wkv3YNCX3voTnhEJsPYGiPhzBX6/83IpURX8sij4/C7CObdlcqVB7mtviJSP4fw5mRyHtBSDjGWjgIQKGm2pyvK77v9joeMyfXi0p7kVbuMD2GRbu2KBQHhJ2IuDGhGzuFYgKfJwVtE8mvaiHyWS60PRuGCf3BMwoI0PPGVRHITc61b10aNSxp9sseEdgDJHrZ/p9K2gJ7FOU+c6ICiVVxhcAqWJxgIIfkUaouqAolOrKSU0OxqK5XiQ92/2I2o89pALWiKUbRLc+majhtjFvkjUqPj7VcNLkDA0OftSc6o4R09JN+wS0Eg947JpprQDU3ZBNCxMdlenUWsr13lsDz5PhajGhuoFNzjXi+mFc3Ssd1BM9w93aqXVevuZqMWOQ6Wb0TiW9AJYdJHdHFKmnJQKvosj1jrg6wlq4pVRk0jrDKz0xUxKMYtak9joT1VwHbOLiU0C5lS5jMDeb5BtM40HZ5E+aSAke0qobU32sFbFuUh2EWMycadgDqtCCwN2OumBIevtyH9JcBFOo/PWFSwilvt+PF+SRJYK8TNXbS/3z61NeUZUTyPiYu4nHhyrOH1H+hJunv+OW8YecBbb8RmaJT9m4rkPQTnyKbZ/ulCipgi58SG88wBTl66q/1Ktv8eCu5UBi5xWkrZ4uwHDQgzwRyaNLaZi/m/cHKxeL7YCd/mUiAfecP+ZkEaaNAhFNXF0bVgDcTSXkJ0z6TtFUnLv4Jf9FYJZ8f9S/urYB7uUakIRnN4vFunTiRPvQMGX4lsrsAQTQHLzDErl5Rr+OU8OvvMIOXcXayl0yEPlcKqUs7KzNqxGk05PJ/dXyrdYdTmC/RpfiOh/LiQQy2fuIex6tIxUw38zPdBt3Bs8h5oKpg/NzLA12sv5hnQ5a5v+mLfWoII0BMgOccUCW/Rc+w1rWkIsFrZ28CGKyU4vwWBvnuy2bvJ9AblCmdLR7aeo7iBUR+cbcHVnU6V4XAfkrWMWO05e4Sf4xPOfwcZXuBoNvwaTF0VHdFemiPo5G+7b62cituvT9fOvGx6mhM1R6CawnSQTeHBoJ0/llO2Y0MIUMWU2Uhvt0OV2M1j8T8CpOgoanvY8u9+HINvo90J84sfCfDlrSPkuBrb7plGWLht05X+xZFnnmAWTj2xQqe3fhb+6B9PvjHuvwkuDrEhdmNpy66i/SI6CQifpB8ziSMhRh2nw2wj5i73C/TLFqjMDWSDk8igINTiUSCt7b7JBoT0kPv+pH+5qWWc4apvC0tyj+UkQqIxACQFkrql3k7yGUT8E3hxQ5GUoGc1Nhoq5KuDl5ez1/D/ccf6UrPK3KjXzs08cg0zgsupfR72L735NMy4v+H+bATXxpuazY848d41KxEmE0PVi757cCDFmn95VJNraLBROqXcB1saGtCJYEo+tt6a3v/XZnE93hCevOpfTNbfpsb3/exr8nGo7iQLD0eLYTStWMEZCyOFKSBpLszOSaRfejmm5LSsvGRPW1PRXeHyo5Zn/KeB3IeHnsvf7+twhpZxvu38lcYWoKC1GgCswtSDbz4+gk7w3DPZb3TxB974oGYPN0fr2vUuXH5D0ZAe24tkEMvfC9sT4SOCszPXyJNe7kjvhefMKM/REKYLsV5H6OWHpgQJFfI+yu1gfXC4LA9MPmJ1h8JwCrjgn1GPzrAlDk/+UnggKOY2P4vHWix9ih1iWWtwALShn5ymWLABy216S6miIH8u5D7B9tSWbmpVwQnOex7/h7pfT6nKEeQqp4fbJjUDPzK6mmtNLk898PtbXuv5k2mD9Roo6znYHBpzQ/RcVc401HSkO3gQS7G7t5u+QKp6wfYtOlQ4p9rAisXbZgUmDAtwFL2RhzOxB6LiOGPw4h+XxwSvy1UMeXbJLucM9G+4/uhCPCwwff7UPuIaOBc+Cww2uyqKKzq0+ARfGLOET9+eByvhRmhx720kqHCWPJbUpm0C1yq6fnP8nXQD3D0v60n1vWN2+bsKunfbsfv2zLgVQRqop7QopZoO5Lm8iiP15uwLYWGGqzpuSonQx62Kb56iedkBZejRZYihWxM4/qd5cUC8h5W1JvFGxlN6aAGecoxAjKVi5yoECgZ36tL51G0dd2EYOlJcX7PUyIenv3uc6sLDPl4DClhDtT4ebJ8uB8lShnf0zVt9WJrJLtYRXNdzsGb+0crvhMWokcdynXGCA2TuM5Ijt8iSTbCRnNwkl2/lyY/muaNqxLuHYnHZSIV9NQLtfvqM+MJ+ga0Kq9nVznCAuwxeec5H4L/pV93o/hXq6u10+ff8KlUAvFR+xCE9IcIcWCA5sKmbZqnD30bocA16jsiTK2cvcjUY5XKoWur9oN/LjChhLK8vBXuOW+9Eke+kD9LYbgozyoufv8O+rQaY0GZGIYJhEgceJhers2EyKNM7miNi8SwmGbsGG7fXxR7g65zKLpblo4p089Y8LdAmG14wtAjrVc9UWPO2NfeKT4rYjyTnt3Wczo/pG9xbJFr1vUKMO2iFq4WYrw2LSnN3b3l1WbleKWYhg2zk9oBsNdwivSjQgl+duMx7rrOzlV++dik8yE6n/oRSlo92tY/e2RHFawmTHJENRoDn83Clxnl2G1s30opilbf8AOV6UuqTVnHY+hiVoOUDpv/dYZLbHlJEQJBm4/rvJfLkAfWka89HLUlNJGmd+boHUCzw7WVUtMvbtKHrw3t2vu1VEqzuWh4nv85Q5EKJaSWvGCanliNO2USX4P1jS9Tem4CaMBH+p6gvvTn0qmKiRja5PZ0MbJxgmrr7U9Idiac0hPN2+WD1AYSfLV+dpOkUouRP+3tgeFlOatJTT0xb1dF8olb858GClilfoSxttqZzNIUaDxsC1hoRzslY9F0JoRwlEayRsvjc5AgII3nUJW3aJ8ZWdbP60mOXvcLtMoEY+cG8Qa8vPUOaXKg8S/sRT69XFMSGQrHdN0pJpwmbR0dwhbyicvZss3XShRBgsjAAmmzRU4UNzEUFd/J66hIswMCI1fDQGi/jNn4fW/UxFOk4TeTIO3wWOBdh3jP3MgTegCablR4rGPEc6MSN9ZoTNre3he2YSsF2vtH8hlFtugS08b2ztPNBx8VacJNKHq2woKKGhP7Od6hASttw98ha+2elFnVg06p7jc0U/2F7tsAAqBnTv6sTZHqhOZRvJpPZ19gNRNRw5YecUzmt7m033qzZaBcXNLHB7U+uZ3Hrjsirg1N5Jf1DxynJw7penf7nP9H5D5Wy4NOtEp+hssWd+tR6GFk+S+C9soQSewKOOBHNJQ8UqgHBSS5DkwMP25khrXkENglF8RKvef+RjDOP4w6bAKSt6ZJ6V/RWVVz5Nd5StgGwSo/9d3zDZeTHPWw6Pnn/fccqo4V/LqrquuuAZge1l9PVE6j3Zdzi735SJRsKevEcexFoDkmfss4Zie/C5v+5JfZdezBz9LH0dyBeL01GnTG3aVfSKCZlih+U1lS5cU/ckt1PMnLIf4OmRVOtF5F8BB5HtWNjwOgl9TxrFGg3I6qfxdBPJPpz5GragbaXOlLVNkstTpaJog61o4dxSyl/CcwHg4pMPpOzIkNCknbSRUz9f/+Gng6bf6TFiX9YYJX1j5vP7zfI6Stu408WBE/NVrdD3k5nz7DG03dVd4itGJk+fYXoenPG2CehIZJ0dKNScjB3ZMMFeV952JOPEQLD8M++ghv/w3InYpS0zhZC6n28saBtYsRtEtR7vK+06V/+BSf2YhWXuY44BVnFNzVMiyREAEfPQbRmxKK89EdaTj97X7ojgDGBKoyXVY41atKhrUqVGLBhS35IyjmWrOkcqAo98R5+sFqLTwqAUvGKT4sgpd7Ka6AKpIv65pd+CQPCnauiO7MMkS3F3kZ3v1plrArCo7S5OS+pBT9qzgkbMU99A0wFIJ0z3zEwadsGKFl2wPLRQbK6XQ3Mro8PH1Fr6fHVqn/jNppnJJnj/2voqUkRlb7QxPYDBXjDCtRyirg7xWvdS/SZ39b2aWXbuRYniFd7GxgwgjhgJswqbYjaxsFK/jgpAVEC1xsIgV9lrFvOphjVcpWk/J1RMdNSqyknstQAh2uC51xhi4AbNTm2RA9ThWolwWrz2XC49X7Ctx2EksFdn3DfCA6fBewtvL0i4wZsk+bEdhesDJpNOzx5arcXDXXyMcAKZ35s5C+a0muZ500+hw6zM0gA9IXsNwXv0e6LmIFEYShYZD4tG2GP0P0pdrnw9APz2tcD2TVvNv84Em/hLZm1JXsFQ4isRnCJeHndi3amV3dow1Me5qDkmkLv1ANKbsnn36F+IN8DTt98x9m6ngm6wU8oGbbhactGx93pAz2/6WiPuVDjCUfnssB5NR5GZfzxpDOH1GUqSU3KglcWXVGXwVKK/aL9m+XdHTs6gQtT0lS9C+qpXioaNOHJX77sQnbU4pkIoIWq7OoqYGVjWZLKnIRN0RNN/NZKTDLtPsHb8VBzJ8uXvX17qu90+GPdBUsU0txWRepx7+nLlA0gqLXq97FJU2hwSdvFU9gBqSYMvwSzdeZ6XS2M1hTf5nEoC0ihZBkbiLNvUVvraIKkm/Dk/kVheE57RxMCaN2fO0Lyl2FXcNhGcZC10sriORxugZt63UutRDCLaekah0CENSTFWi+HKFpgE16jNWtI+TWNtxkIJUOhEFgXi1bSRaHTYqw6sbFT0KCjfnnvE+XpCd36TAXdOX2vKLiV/4VQch8pIxH2iRIkhQ0vu2OXvH0otc086p+C1e2QO+69FU4urSu+LcXDmrsGmWQ9wS5H0bf3+189xTBqOYTkxQImsb4frwDwjzx6QELZScuZ7b7C1ceqMUJDanvaQnJasgz11AVDbrmtAs8XttPmWncApjHIxWBa9ymtU+u1matPQzri461sPEfF/UgZs9BshW5og9H7hnumuY4YRHVwuC7dXQBwgN4EL38cqiBaN+oCNKTS8nl7zbmSguFxP6MA6c9K6EfwSaOZeVq6WJ4dkUTU7IiMmBH5KCKH1l00EZ3BugdlBfhKXNsHGFRtfYp4Sz6sMq+gZ8Cp4rt9wq2KxtusYktSSPuXAKvENzH/ImoTqzqVSFk6yLtQQS+u5vIArY2pnZARcl1lJYD38cDbshbSx3rOWZREN87ph0rNIUgZkQDxH5+0T8fUw3GtTaTqikVfwr9OwazrwNKwangr2GDCr/pdLfT4OM88Ix+odOwNh0WK6pR/3S0GzQARKsw+213BWUmfwtHbqmKv1pyW5pDIem9eoMCvZ6l1wR3vJHBLcYUGCEYx+wpcGXxmPugNySc4uoBLGL7IYdCwL5OB8WYqQMjuYLdWXPpdSdcywJggSxTxgtd/JVZfef+MyNYxb8YBdqgrxzckxVCK+qpib7U1UGr3TfseHkChlRcRZ8bJ6aw61Eipm1fL0H0E7YSIyy8QW/Qv2owW81muGHMuzPOcwIy/DIgoQ4ynGH7+AJr9553QPg62OaTc6G2jdKoWvOMAgG1t/tDFB6DCpNaxtcEHzi/Lha5EK+u0yyH05t2j/o0r1t8SNrsKHTRA4pA55LC6kfCaW+/NjHIjRRXCh/s5xb1NAgxW5ie0n3kMdppazR4AB4kMWrqydlvV6WHQOF82Ly0DadnvMAw8BJRETly5gQdm3bEYuv1d7YkhPMMDOe1GCn7d34KQ95RKh2YbkPkB7hVEBPyo6xGProwSs7kkv2VrTtpzi6uhEyO1qzxsfuZ7tyKrVVPf3OhNFQ0zYOJS7AdpvDmOMjz3ZfpQ8dQpifDG8sr3qd+cE+4BL9zcuSf/lWy7pL4UlR3QoszxjLo1HbiaE1E3pq5V9v5O0UqOfeq5+GlTfWXBarsKO4D4DMNBnbse0iQuWQdiFMIQB1g7ZOj2unJVGE3I+tVLCHY/mKHcAUxXDYJA1oGDpDm0WjkhNM7HB7nvaMYYShK1r6hAV6Hhg4XsFA16gCcDI4thLA2xb/ThhP7V0i2OJj6kUQjiBUbqhYeoEORESDS8rMSFARdKhxfi5Fiy052ZIcQcmDQh9v4AasuU3wASjgCWNahem1RVB5prLqGRDZvhaOC46knnHqhOmXaZpNsaVjhoi0Jl5CDvo2IDT1kbaDo85+4Gn4BmtIywHBcfhU8tu27q2rl3/klhsRw8WlJReSAjRL0cUHbE7JO7Hscg/IrMBUm7vN8OFa+emoevcSsXHit6BXfX0YLq6wF5k7bts6DVeOrfYaT34/XSzvV47BXoRdcUAzZ2t1F7qYksR+MXLIrfugkh8+gpUS59u0VOfHdnbM5A5QuOA+hUP7f6gFh04kl7UQKxvBtVXY4TPyB0wWVDV1/kI+7UQb8PJ52ARACYSxvI3xpmnXK++7qxnCLkePAa3z6UWc93Ul31d90hnS1fWAcLvyBQXeJPpsJ9wz9roM1S88jo+K+GiGzs0mOfWvEoSKjMkLATbREV5Qd33NTK1Y8LmsSxaRIT6mPQlSwxW/zUX+ZHKSmc1kvMUjA2OndIdGi+HkKK69rL+MgpDgCh47Q+YVtgcZReWMzys+1LGYanX5YcjIM7B3LL/Q7tDUKE8pg554qvvUUX15yzLk5HcWDXL36l4GFnIOQ5GrqEy/s3BNX4Het4sVA5H0pFIbmJe6foBwBWhpz5M2sexc/lkNiFGHjQEU8grGFdh3CJvSIRhKPE92ES6suMmnqscyukVFTRRBtB+dtmje9x8x1y2WVylqcOVfnel8A80S82v5LNrtBJYmR2jNQ3DA6v8WUzFYYRReUiSNtQLT43ESdXdeHmweO16Wd/88C/Pb9l6SEeI3Fnf6ld+H3+kSQ0NjN7jWQPWNH2DirHfxplaOslAt2JALFn7TfBMtbyb6G+c8TqO7XT3tJ8ofypaeP7obuwYW/MZecU/b6x3INy24LHX8BkJkUpHerydwBQOrQnqKLqx9772m7b3RE6xaY8nmKe054HgMGPZsHrF5AovlvqA1ilMMxN5khBjDjw4PSPIf9oiDmKhcB8nL2WVR4k1Fg4CXV+12LKF9QHRiHSBC0QRL4SsOC65Gq9cj9RjyIyGIOqhp5hPNQjMNpFTOL9788qQAykSKCF+OxvfXCTdt/45bHBjmJD47j5dodE64LFTNZD+5nlPJJDaoWauCn8XA9g4DJg7Bg5CarGCfHty/r+hVJtSMs/illuiZubfcKEyLIP7Ts0QzNG0bZSQeNPsujYz7F8DzBHefE2FaVxTu7dVBfd+49B3BvWonV+zGU8rHNOzkKi4rV4I9lwmZggXA/TmWRA9WmPgxcFIxTTVSe0xfuwx9Fe/ny01mbymfTImuMBVfZCDVb9gNhA53ZiYhzvlRq2JT0Rn7Wvg9wsTetrJKnCfPvwqd3uU10aCubaoJOAJOmoTjp43ox62szBBN31tq9472Ze0218FqFdQVtdx7RH51R/oiq1qoxm1lddYo8a6TVAKJ0qpDtoTe5RaP/2ZMyUh/7zEWuVMgIWLyvggmImgfgBhJBCficm3J/ggTkE36hyzEkrlMtyjZWA6cmor1GecvgLYTEjj1Bk1qO2kxyqOUptHZlZU+EYpZSt9FSXkaExfFNAc0MkBLcox46/CFBqCL0paFvFea1EAubW+5f5E01LXZW2OTeHalLfnEFroIFzb3bQWrtmRVfDEHTLJUWHgmp+9IIUntsIxWbA4KuVheCafYHsFD2C9qrdFVRctZs7lrKkafgwwv9rvxcXa1ILYuSY2A32ZgkK13LlLpvUc2yEJHHPbwPB9q7y+IoH9nPToZavptj5dzVHcJVmAJ8Kwktaqi4lQ8Nhh4iQLfJAraS5S6Jnz+g8wd9cAfAeXLNKJr88XgqxH0OLuoTtcgHmNjTcF2YU4wacHpCsRStswgRq7IMAAdmFAUvC5T55Ega7HR2vdYZzuisY59sw8uDwTWj++OtG1uODhEdVYYqOirWAUebtXHzFd9xNv/1aQxes/XL5VTVG9Azg79HGWewZBjCO9c2vjB703eJp1dMGJKb4H1h6LSEsL91RXQ2O5ikibAEqFxoj9iOjrKMkYgOXX/C2R4QEeX4ISbNCDa6E4RLq968JQoAvdyBdlJ/U+RgGW97rtrJENwpRL7ZwZ6/fPuY7HOkJ0204MlFGBG7QgDTMtzFMQ1nKBMXHY+t2jLCWuAoJyAdAQA6lvVfmAmkM3Qc7BEoPPtG4CPHCt3nMhnKNJCi3OJsJjujzXm9bukoBV7Nj9SGn6avpkHSNFAel5Ttio17A2YuVRMAWvSKRWnJxwyedswR/AO6fqsg9QeZgh7YzQm8saxYbW5/j+tLMU1sMjhCloBleoppj+vggJdgXPYub4/4GiNNxxheswP7mtJRvYv1FqVP/nBhr8h0KSUezCtPtk+ZL1yziTDIh9/xro1Sc44f2wC4aeXvNInILxToMi++a04yX6nF1SiYnMIWIZlTzQxmaT1jl60shE6qArgL+JcUcr33B/4zuBTCiKIHZc7lyrsIeDUg0Xtrq0E9nFTTPp5Tzta7AWwo/pPaxEPR+CNyM/e7O9bys2qjSDS0z8HW8q/EdEpKjgtuoyseS3ere7HP5KgldeGCV+MePKqUiiwLe0HtYNtz0X4iPUiYbn7EcRx29+hZ91SzrS77nFOtmIiTdVZ7p+3b49f6OO2+72b6k9tnh5AZ+Chm7qtx0kzJgjjk3BwqhJpMsG8CmAvOCxtUwrMep6MiUNOI5S9XRTTVu2p+UTMMC273e47meC+AS4ow3sHvbyq3biNx9bL7N4RavYSM1sQMpC1SsFudy6NOI1p4jiF6aVxh2BxDkfmXhXwFdcFgmmoDIHWXN6+7p7a6p9MjwjFk+DejyLqYzsVMAIF02hGS8jsjBlN6b3H0/XpNQVF7IG9ErDs/c2G7pggXzqhmTbKHOgwazrq90fLLFY4HIVwn6n/32Z6jdqAvTBxml0Z/CWQ23h4y9OqfWJdI4wgHdUOT0xgRLOqabyaT0xKj/OhImK0NlTwcYh4+al5TMxCCtcVWoqDtWjjVj8fmc24xEDThPIBFXN3jrNL4gjRthRLFhMsiLMWUYxdlmjisBvmZQJjs3/zyWNH6WNf7Y3PJiKZqKzHNOLyuX1J0z5TfJlWF27/3OCHdSoGBB4H9VVkaG/QVBxjiWi7Fg6phZoQnR20x378jYM7GuQZi27bSZlnyxisTTGWG4k/zRIxFbDqDVMvA6s8e/qTpEpkKNgvuc9xUHMnNczgMq0L0D9CWzLfy9kWxEovxPBEjIMDv5rfJsc1s+i/PgxYt8ICjqgyjsQLAw5EhbTmULi4JUwCW+mOJvHDAIEZsOZ17Z89d78YawZWmXmFE7uLZ0quny0m7SHPemQk7BiAWbaerp4JlK6p+weD7qwphFWPgzMQU1Di2LtuEhYhhHRjZiZS9XHxsy7T6MdCCobw4khyAT/Vb6hA6DCaMbfFxHEjwBdbqxT2QmJgfb3enFWLROS3+GIsLVoifHzxKlew2VKX5ddpCT3F7xTQ2Nd0KYleKRXTQy8Qcno45OyW9mby+L3yN9ac2Ry1TfpJagb1iXxNYBfhLhWpQCbKDrarGpnFdh3PE2J1q7TLpieJPKVqljB0LWhBPo8DdLMq9JK9Xp2FX1FYEr/9Rd5PxcczMMITRV3ztCFsp3y+AqnuXfbViOjYb5TRwiH8yifbvppWH+zhUbaNmidcpRaYL+XXjj0z2UjN+SUgkciPQ3Dx3b3cTDUGvrKYTr/9dMdoR6RQfQN3Dqk61k/o+PVTeEl5VsCNG806FhKht6p8cyj2n2eRo807U9+fZ07cPCb725KNUGldVDl7NdY3WYPVkKvqcOC6TMYkn5c9xiHkluQ6H44gc0/IFqS0VvewXOPkNJJQLOWN28uzequmMdyw/Jl71ojbx/bPWXjYxpPLdxP1E2zjHqVAbkvgJ7LxOpqFL93p6SDnXyYskKBHjNiZMYjzGtEq0PClzolfFqcUmJ2g9jbvmGq/les6lBe75MTibwLGDrHtw2kyYniS7CCDWaKnPaVKyzjsLiWE9FDOEsBrUYTRLI0W182TCBhtOoa3B5gwBCa6L/n3BdOCbPThr2T6P+VG9maSI94uTuV4hMM+wv4cBp5FB10SFRr+Nbb6tkiH7jicxOLzQ10oF04V/RuXl7cR+gmrMR2hhCtyZw/NMTfhC1ZEONwmkLNLDQClwj1dY1rpoJB4jqd9ZLGdU6R01ltxjrSsYyOH74yzkxch6xFnYRwGgKeLP17YsR1M/7US6zfee5psMJmmF0d3lRpOGLUgv2EE+mfEdK7RnkjBMev7XhP3keyLlj+zF8ubinuayYmsAbTv3ZmJ1HfwZFIkQfunCGJYRYRpaqxAPwmfsgqlelWk7+9TEVREUAvMMicbiHR8Xl1pBEJ9tTKzBbPhj41gvoHy3sy09U4RqEdZvGx8rbtM1BDPV+VJqsxOdRJeqYJVyTf14rOp7FUe7HyG0MlmUSwPZiqdBy9w3gqjGdipjUbDAUfOCFd2hd33xGYaWkibkByTxGl+OnEfuf5jM05n4cc48ttEEjVlDLh6QjiCEhw/RB9rJkrvcDcOEMtO6TOEF59rD1jgDDxttsQAg/Mj5mVu/oAm4/xixU8Wd7EzMxL30Yorhs5ZOgjIKDGe924q7ri2hjbE6h0I+kbIx6JAvUxcRVIT4pL3PLJF/u5s7CDcBWMXokHRIA6gDvF5AYeEir/B6Bsen/UwLnuytNFiKj8zYTuU4prqZrOLMtMv2whxAamlVSi4wDoJpSdjQ/Ys9shVL1T1mNcxa6Gs66rBhBNLMu/EwnF0sNl4ER8Wx99IqwlMPFs34NgXZyqR4lb/RnlXxfLRY5lep9RPnpdf1HEeRAXx+X7quJFjkIyljdYVEIknTQzuogj6JYAw9TabuF9++JL+A20gGmkJ28DviSPNUhS/s7sDrGykgV8PPx3UhmTmCl/HK1wWSfDHMWEihbECgm3zx+to1W3jzca4houHgTLAwRTaFdH76HaN4hYaRUEIHdA0vdpB8mKadYsokqaDJex9Uj3to+TPdUA0Z8qS6+bmw+hKhYW72A45s4EcHuzNXmZIJ0I6Uw3baSi1dDVKsH4IFaOTPybccV3mjUhwBZr3twwiiXKnikUnf45H/BAuTruSLwc14Gb8WXBj6IxH/MCT0DD56Eazmqp5PhJ+WyLlOryIrGnyrIm1EUsSEwsyQaQXu51U09TkaYo764bja488uqgexlhQgru1WXOqXBDSg0oBtbxQ2VAfGLqyvfIkQ+tWB5ojGMwhT/pAr4kVB6HL/b6Pr831LHfWwAqAWkfnkBHGqA2PvLhT88QHmEV70cOLHM/zgv/gSKdQnRiRxPelePov6dZwkd9Ptz756fVea+M6LmJlImmEeLzlZZcTaC0n4/TrhNzCOSkqX1uBA88klb424ly/Pe3vW07ovuE3MIIuP/u9ErpALD7j5Mo1YrlVpGNOostTJoFP68ZC/E4Q3Ep78QtHw2LE8tEi5qSVjGrAVk2zs8mT32KP7/QN1zdDuvc2h7IsLdqTLfPhGuwNdPxpFH6Q/XYNGweUcvmVcrqvOrrFMYlW8lh+h5YQjCC84boirLu7RwfiPKyAPP1q0OxIBadxDs6NpbelfYukw1grpR6Vf/HAxA37AzrLv7yw9Edot5tNIPGmguR+VBkNqenm6/kx74OR7ICz8a+sabrBs6NE07BFZ2CGwprZ9F9QpgIZmd5qW8RR5teocGmfDAHfhFZHU8RlDT9JJf2HK36lE/UdxOS2ryG3EGVXXH4nO9Kwo4+I3f+d7pzCMWiKxH4LbiHf/hSLn7Vvgnk3iochzxZU0bnWl98XdCKoGbHOPAvLB17dnaTo4YO7QycKhmwmT0166ENgMjdMxwC8z6xvwiFVd9h7CXlPNxmCfe5v6GWulC/iOMjhtlNB/Psp+eWct+xYSK590gF2JTru9H1doINYA+sWeNOrPiUidK8raJtF2R1Lfh82DrlmUOpxG78Gj6836Jof8dkSWPXfx7BTtThHzaw6l9GvBfTtvfZC0t5+T5Dy3yS/Iq34YetDEhSfQ8rp9NDRo95FEMdOfprmKmsiT1hrSec4gvUD/FcTUWp1O+lGSVwVR4xkR9orYgalYFqHmmGlVFkZxLGp5heaIznBZknJGmPa6QdclHUha4MkmkOKJOjoAW2RgFzfcpuZnyhTfLPsbZMyUsBs7c3RqYj/qGvdg1qnVyXJp/gqZoMaKC6rUBZeziq3+QTyR3g8F1zGMh6/SWs06pvqz8yy/5vbFn99c0yag0yXju3JiYuSHCjGFl3/Q9uBDWh4XG63HXhDf9ZopGWQjT+agUmiRyPSqvS0tkwjvi5x/BIw91hk/mEXel17RVOoQOm7OIjv63XHanG55wY63irN3WGx1DiR6/b22F1ksurwIu9GYJ5N4bSHUzn1QpG8K7NKkPZPAC3qZB0SD44eW1VzMVuUnAWemXf3K93bifx2/5z8ptGIg378QXuML8hIphYomkuEhvaZvcaxEzUoBA8vxHDe0KqW5wjDhOItStfArsx8PWqbP+76XOJMcJ8tDX8a5IlgDoJhEDRQuKOi20Ghnjx/fLGJ7V49vKnmzheHkW3qzuFIbLsU1gmClQKUCx+jHQ2h4/nDtP+tYPDQjGNgtAsiICW9FSivHtU076I0FBkEqF2smCiYBrAj3Tof4gd8JvPmBxHZieWWNxew1OazQdAKu7EJC4fmHLWdr1PEMaCWi4Bh8vca3+kp0QleCXlc9kP0gt6G6NqN+7vV3y+dK/AFPEf9R8xbMLYivBeUuqGzaTlFeOY9ynOEN0L8dV8K9InLoU1+09AzqH7N+yFuTffNE0uJAccxBTToy/QzvkKFPS+F/Czk3AmyCYW1PVtF85M0OR6Xc8y2DUrtXNmExW3utvk/Uej5aok9nL0ULuiJg84fJzRCcZJMSIq3yk163OAftUEoKoE/Wg6XKPFPlVF8o5p8taff3rzfYzrv0+gMv1yGjB4CbpTKS7TF7Yo4ngKoafwemaOiP8Gx1FCT7Qsxv9n1BKE99oy9uI8Bk7tt3aonmzA9d1D4zOxpbVe12PwqeDybZvd6tkTpycfoKx9ZSK7i6wZaQpPYqZ3Lut1OfNhMEx2AAak+vezx1W0eeLbm1lx8dibZqPBgqj6Z2GHRooo2VaZ7vA5budOjNZY+1JexPp4n2d11RzrbXtcjd40JTetxo9sFDyNLFujjdjCT8ikuGbbtBsYKirVFIuqDhUWKBGzammJkT5l4Ell021mAXU3wneY7je0bTywKD/cofCC1u20C73sud92zfk/bx5xu+qyzYL4z8zGQUckfxSWqaL3qV6/D2JyTfNKNHZhWx2+q2opzxtMH93eD4xSKhiDzLmoTpcdXNA4SZ5eeH92YkimlYnMHi0dQPlzRmcJFon9FnG08HLa+1m6H1mbkR0TgLiJPP7c+tI7vvhSuSJH4y4dp3FaTy/bsy5oJKICHmVQLgD09JqtyIfwNC/dcJqqR5H8hKcUXyauoMpLvp3379cs/U42aAEq1a8aEEMjYZoqj58c/pW4/Xw1SJHImmjJoTduQ3Eq7nQnWXX31tsuvK/ivTqYYxLqgBsV4noebTofsmmKdavswmx3wph9m+N4y6LJRuNnsfW1KPagl+pkUa0w4YFPDCdLalHLLpDXApttKhaQzr3O3aZGEzuJaG1yS1XmreMrLhdIXY5P6xkh+qkuSbrqEURGiQddVn3Ltr2xacvkIYiN4JCXO5YZ+4zPvwQOyzUbM2fjw5gT/VbigrSA5E92W/+6FRAb6Jr7p4mJqBqNiqY8yJFnf4BrU0qE2oXsNLjKoRGPtPePo3hNzwIFsnxjNmIq4EN+iQbGisUUCIjWn/0eMuovSsxE8LJMbpgiz8TQP0ncE26ZV3i7WxGdsAxvv2iLXjDsJbdtjmpb1XB8pWFbLiuZNfFMg3EVR1LoVZ3no0723qPNrFBeasvNaGyWKBh6ewJWtdDUmaOtaNTg6WDg7ezzmWccZSW9eAsxU98XIoge/R46nbdgoAvba6c7H06uQmSBd/69zT6Pl4jb6yyXCw995C0u0iK0F9rYTqfj4RnGO9EZPKxr7jY9HiS5O5SJJlu1FLX8ijP0BXVTnpVGK7pU4Fu+ng4HvXs8tMMV09oFNMoy2chtlKDAmGZcJ3q4hXyNxfvybqVnUEsqolNqMQRXalP0OKk/220sV/Z/1JIbGrCZsFnkG3oVtRgJUnCt2y/Mp1Km23rBum/KnjgWLQsNq42zWCV6mpKySebL9gKEdRrY2jzxO3gbIIHytnWArdTFvvMxtDUq65ER+qai9v6MiCKHXq0cZBZK/eCIwghdHVvTMClzn0uaeajKoixTBW9ofRqFwBIqJkWw5JAW61rXHnPJUDfYEazieNcuwoP6W/vWgIC31gBSY4LSPkklXwCuOa+gHL+VwlreiG7DGWxjqZftBK8iRLdgWBausldJ5wHX17xGgSRogWoYqastWxG/kkG+eOZqSBMVDCHBmhM4Owvj4lljAr4SsKqb2y9tHFettSMEjF72skE4VHsCVAum8WSpy9w7p6Q57vNYemnkJPPTihDKIgYYxL8Pbos7wNnLOZoRdZPZCnR2syDaAwh53ZhGyExvOdn5cs5tu8W9AaQaxU00WUIkEvq+CpxWK3cDMdtFgrC6pdW9FSGH7P3LTXz4jt2bCrxLcxgp/FSy0bOZ1tZl2hCpQrXIn3Fb1TdU3GCBRgDhRX/uQP5NZBOx3sPb1CBkLSG4nlYos6XstZBbHAK8muD7oPtHLOGNZfI6N+PNr6Nusj7NwEER1/0O1L2R8lLPV84lv/75IegvW7ZikJwPBDX7+XyMroavlEGM4ji0N8CRyCIQNLiuwvjXZpz9LoON/mZ4444m9qM8tUz+wnvmUOjKItlOKbNJjcUv+2WmWidHQ6NQ+8Gj04RkWNRgE911GLUv3If9q3JMZj9gUEIWaWra6jrPdiCvKRWIWKbBh6rDgN2PP27TPAbG6fTNecHSzk/a5ebP+IhBr0jkYoe3ltlrv2q1bqndghTicyT/YrzGKZbhsS2ps5D8Z1ttRbh0sB8S7pwsq6p/G3b2BjPK7F7OFEbRhNF3xKuuS0wWzff7DSj7SxWCn0ciwCRQsO59vp8n5MgYhtdh9s771Ukl+N/PJP5dhfNHNW9StH+Us3Kb3vqOlsECApw/P8OgSfWoYI1XJc9TxPRursZQKEF98vAiCAxH9MaX9Pt+tdSkNN59LnLUd3no32yYLlHhJG1LG2fqRWhdpfpaqmZ3IKJCPyjm8sVnJ98dSM2dABD965KytETZa1/eyijfrIiA71FyFuHo69I1fu93ph+6OCtpL/18SnFLNq+g81MbgyYrl1c83EcV6vsyO/2AoKF8r88hYH9v6kKD7ko1cjWi/wgdYXSRC5t8D7/MWvgHW+/311Nai/T8dTtXxLujluwWGPXL2KyKZzcLmp4IlpjGtP8smD1gfYHgz+5oD2Lr5kbLGumSrSb5S7ERHKVpz2yDw5gGA1tjCN5F46nWmyjXCSNoI7GzovnEMF8UYceJg5/AuOyA2V6saQtbpaerJLuoZP0fb243G72EPSrdcd3JUfzATyQ6+dFkbmoixsxXadmHCNzzpE3SOr3IBBH8rJNQnJjbLqfFj7+BP69JNEzcKUUIQm1Gdy3PztMPwvIYfms0ldvUsUMGCLuC1K3ynKvPnB6XnTQob5nldA06/q3yoFnufi8Y2wP5twlcfy/+ID+on9YkOC/2iy1axu2t0xSCOEySLjeX1zo7+pLR0qk2g6RVECsuJ+mspJuo4i6y/zZ6iNMi4MfMxQJBzTv9gQeb6xNX3DWroGDYP/itUQc0FG/u1IiZsQmbeVRbhYx38fMVrxdemwjLgyEtlYq3B1oA3j8o/9GEEvhQLEQY2Avg43Lj1+yAjIGPiaT2Ojtz0RRHfAuoeJGXPmIF73Doc7Vw/XVfSmgBs+fKw8vl5GaOIVOHcYkWQIckZkkbng07bsmOyqG5A3PLdAiK9NwNJS6bt/y5r2QF9ocTBAwf2/O0oqLg2Dq4BfYsOJIoT7Nma+vSzdc7BqYfX5IfbUdNRqaIHjWqObhXKyeJkDVXiWUze1+SQCJurfq1D0LwpDD5v2sIbg/WvgE4boM75AvPVFMMqr4QB6kN0r3Vkv/pZ9HcIAhFjs06NdoIwEieqcUvo9fXV0rlCQSXwj6I3upa6i+bFnOthZze7tYU3q7qg4ADi12cibnu60phYpKLObOqWzRrMuvXFAChyqi5/Y90SeOcA+ksS7zDze4FqEEpsmQDzcv53ogFZv4IygjiJr01wj7h4+qkVusEvdtbzZcXIZRrLoU4yVw9KDriVKYtRXPuOTt9wEGJ4FXIlx+AzIetT2v6lGy8xp3TRr2VwMw2JjS0JxgY+oslA8Y4KzWCjOJFnztwuZxN4fCmTOTq2aZ1uWoqFtVuvGWt6jUgx5dMqzKli6rG5HlHpm8JlHWdQp0cAbJOxcRlUhGHigKkHF8XR0nypwJKprMOTDM5xM/LL82cpxE2Zkm+HELgcs52mk3JCRw8q+FXynzWFnUUR5Xw0WnDRTXLm7KSFSbEmst9ulI96/IMN8x5TlG+8GndHxYHQDof22ZblTsFuDrYdjnlE7Jb0J8W6PfbGjXIVOr/i/EPxH2wFhH+j2yM2IEE7E8nNPCvHm+8jhWXWiMCvu7CrPRXyyadyGbImN45C7Jkd3jS5xZ9qxr8PR/cFsLLPtOxvn5aHTwh+lXZiBRpsbDVaz6P88xVSVCLs4EtNBqE07Ft72M4IKS7VTwnrv9mArjFPoCq7C4M2fASZ88UiIp5BDq4RZtcnlihtLg2WvPbGVgU5hnFuCnUqvQ6doGC48mHmIETxo+PAQH06wDL4bzXWh+4O0bafgrOyvsmb6IZOWDh/5HpGe5McX6N+vDeYre1T8FAS4CayAzA/qO5fAS85ccxWIt16wwbfa1FDn3hJ7hmgRL9dEhuCjvTC9TZDrZhVL70EU6nssJNeizPAfuIp8IiHRE/hgHzLlrmkaYldwbAz9tIrJ4dXuXqT4E24gCg32qBz06soK8dI/uWGAFGWZTIgVv24GT4orMTC2g4ErYMJm4DzfIv3haA+Om9i76GWwlgUvXg2Z13NMOUrWcu9VgakNV20H1AZL5BXOKq5dUpCQByVZcRWWAVqAeRAeqyrmMHp9snjaubrlf1Yw/tWIkt/lmiKWBUd0RZEXZmyraRIC5FlVfxUpMNf2aI6l7yIroBzz4BIICpKbCYSiCpyBlHymDJtvK7GKOKxCGeZcLsImMrlZYaXMbNYk6bd+vM9S23uIY1QVCD1bZPXNsVgX0IBdAl6XKHL3qIGpowcI9W+ZkuuQHZMN6dSeZdwefjtpE4AoHWtkpko0szwOODoRbz12tGSG8d3NYnD4uDu42Arr2SBIxcbKrR0EndUEsXSFUsUNz0NKjn3FWpaJVzlMNLEoFZ/DuSEQ6UxuG6rd8OkKOw2x4KTOqsugI++4kox5gwRZpQavW1LO4/hc9RK/7YKLYL7eeRqvSGwlcwFcwkjB7MEJXWikvsajSesKHT/f9smplS8y6NYgpg/6/EV/fsop0UM6w01Y2YRm5xFPXt3m6VO1AQX/3qfS3WfjghYldvGTEgk8939qmRTBQJiW5YUPeGkUjRXTStydit2oG0VIdrZ9c139z9LeY6+fY3QGNxPXyK6T321Uk6c+2WjBkExgaiHRimaADDQO4F4wHQNLEXSw/eB+tfIS4ADIua14YpkKed1d0llMIHZY7j52mkYyMN9oAAKvTnNWpmITQCGzgX+OZYIqXH+NJJQWHsYGtmPSqDKrnHdsQYI8XWc9TMUN2K92L2eiHMITdwA45rmGp6QGXCbFBPA61JNDXkjuM3UoyetnuyilQ3i07yCau+QF2Nu7maOTf0s3PYXzZC2Ftk95OwP1S3F0hAWl20/M/SFZud6mS6M6Gz7sUGOJBSD7BxCwCIiZPStK9U/t+mthRrFo7fXrYVOgdMQ34zMIxJzz2SMhn1SnV/MER4p5X0TJfMQLsnOkLV0qTBm295fdJPFcXpJcUlNhBQmkvHA4IxOm8rdMA2dVewgjpQjW772MTGUYW9jWZKr75u8GXBiWQhYgSVXO54JSIuaMw+HNU9g537hVQ81K3G3mAEdK1Sqw4/16h/uX3t90qH1OQmi5pAKP25ikM6HaZtnoLH+bzq0Lev8MUFDOdJh7BwmWfjf2IoF7Z6DhvZ5Za0c8Hf3tMmOKbHftYufhyEJLbUvIaOe5nZjD37U/Kk4zUX1CNP1Qw5hEKVWbTHAPBldJKg1S/6Rb4IHwhsh7SLpUM1WyR5rbBNW29bwNHfMiK+0XkhhxUsYJzF3zHIE9zj9+GMAjRtjVeo5ouMr3ZaJGgGkDYXbHttLuAV11+/hv9k8JfE7TzJWizERo6WX8a3byEfvK6jBJInJw3nXToOMR0J9tel+S6Oxj6R/O+jaxYwPAHfNIjYv4DrSeulqIR8r1uMRj8jzt/gaOqPQr6ZC7RAUbTrblVvZH7AKQmaH4G9Ledw4RyLdfHtS0lDpYpd/JSLU2O/J3ddJ/+0qzgwcF8/TxVaUWS/wZNf5irRsNmHe1H/O6HJ/CuvdxyMsCqfnpR6nbXpPd7pmIIcCk6Rs0C5qaKpx0aphkMsJ/JM2jYF2u6Kk8zBdZS7QU4sKpIPaUPz2/XCIHxHztA7QfSom5KeZKpd+VYxxifjFP/iBO3hIk9/UUAuudPBTeXyFOM0MC6eC2e1sieYTCSgwuSZQ6CiKULmAzmYaIKtkeMcGsShQ+sn11e8RFm2cNgcYK9UyU3LmHmjl9lN7ijafjKpeosEu5MAU8AHW2eDK/v9PLLgJeZIAY8WgObcwHDXtuCJ/Y2It/kMGBVCFleUmrLN0iAxk6ZQkFIGW5etVR4GpUR2fqiBqnZHt9k1aF0XEszs4FKe57BJ0cxdOaRWlEXnEPM1BoecdLZ+B7LFtRXtSGyVnprJFIDXWefR5gFJBPOhFHmK9PCukUBO1vij8WujVZsO4mhqDForiYHeQUGCloPRZtRgGQuRupcEJaZRcHq53jM/qZYxZzQ/bwMznIHtMZKFrDI/IO0SVlsCP93PJLkpZqK2CSspPmuizL5hoJAz/QUkdvQcO8JIeUJ2lcFXJv1orbjRZOI9FQfU/+RiOjVNY0daJa0mNX5637m40pxO1QErzfKIG9pzy1d/WQXbTi4kLQXoZpSvOfOukZXJaDen5cLMwAgX271WysUQS56vaWYsrA87wja7D2ckB+WWxa0/UtwDfzS6l8vk23Di2DD1ORUHZSUB1P821ZkeTtM3cxmfKH8eU2gRraHXMrd9xHTORZgswiA/HrtJzkq5BnqZC7YVrQLWx3mIR4yZtt+17k+cEb/U41K8by58EPDeKAsf2xf7u6YmMUMYOC36OYyCAtM5a8+mXK/6/8pBhTxD2YWS8mzLJi0UAkVgEAGEZKWt0ibdI85qOGuhgY8n+q+RnvCsNqWOTMJeOOnw5tpD5SDjBF6ml8EX9h5twah1hSTL0MJkvWXDSQpd6DiTLYTyGang3hMwdDFREOWL08cgTyJf7NLVBjdM5hAtIJp69MNcof0yCKqIiK7YYNHK7EGIXafdCdS1WbBF3qYVMbU3roNvld2aJkwZQQfOVhMVz9I8jPEALSdaec53Lm9iwAIrAFMwKnvPIo4czscuYi6Zl6MDHU8/+rIwh2nW2qn97B/WN4xlMBQW6E6W7w2PhIXfxfi62bIbnFuOxNUXrUwpbZefpsUdfDSQOzzsZYXYFSYBIbhTG3YhHa1w+PXn9GoRtHR752WtQV5Ig+qPMdgEgPKA2Cr6UMsmG6pTNsepcalg9n3m/gtNiacaw/E0OWKBNfwwFy3rP7wE4joErxoGydpyUEABdIgbPOueHVJB46wOIUAtZeEFx3DLkcBrGeXS7yGMQ/h4AMcbBdZ31lTqDBM/Vry/UHEyyY1arnAyyl5vL1y0ODzXGLLhlnL4HPmjE9/NA5ooYW+Jru59fe1rOszt6vF+fJEGWIKihQIT6unUzJ+LfR15QXRJkUCac0R4WsJEFxb/ZKpqv/vNKTvekJoShj8s/tkD8t3lSqX6/ISBqAXL394jlf2AAPYKbbYw9CF+wF1Y2G556wvBMd7WHpNYVQqiT31f0hZn3HfjU+pEzLBUqL5E8xtu2renZQ73aZQRMKO6Ww+SY+Ni2KKOtuVOLJonFlFQwr2F93FydZR+NDrGB4IB+dgbzdGSpP8w3PiUSy8fAagXgXvNhzjFBquNYr6FHgMFNwSvRXOJAHPuZjqY05n0NGT5l0hDDNpE7MSUCEXYftKAWdbq0hWseJ96qyhwaAgAK4ptrfd46gcvEs+A8Z1UZzBO4v444YqcQjDmnhOdZSuGqq1ShSq8ypaD+BHQbU9QDy84l9bHEI7h3faCN0RUOKIQrOhtdQjb84PThJHQKQz3AMzIbSZOHLA3fIBhaoDyhu+7XNhLZAsgbwjJ/KYa3zbXUvIZldcL8r2ekOe5jygfMP/kuPM7vUjdgolXO++MdBoUntVXjcRtoE7iykU2GQ564iCd60KiCKGk0ZZmv1geBZuWc3juZk923UMaHhPucZaJz/hbzhzK9HSMMUFWp93S5PgZPWW956ZFrMWe7TgefqbpIAR3iSYajy9OIQE7kW/fEfrgxPzA7zkpUr6l66BBixU10H7BXO3FE+dSzO4T2VIlLaiyl0YROzmk92i5OgQtzpUPNfPybzGIywKAWzoZcsoN0ZMxcZqAagMlzWcp2Z8E9WzG+ZfbhK02w3S5wS1cN7KusDw/ehmAlMNc4h3r2aX2PpmWpXtbh7mv+9+NcravmbFHirnlV/ry8WPTuNseQBM9xglvBu4G/0pPBr9b26JIvYg4AGZ1BR13pHWAy2c3NjJ+DgnadOJ/N2E3sOCcF/rHngSLSGAUiK1QgnCZBelu5MiCgcikwP6WFcxIalAvx+emml4qjBY9Yg/QF2az7c+pvh8y/PkVuf8xO4bgCJoGQcvJesZ0bo/NHJu7405Zxf9i50u1KCv6djHOYZ9YOZ1W7cPe2MsNZ3EoY0BeZPHJomA4kWHILel6BcUo2DjPhNFH91jY/izNdLTqQANVBKoHB1dO8QhfMOT/85ydQcZaqvKEhCKkLBcZO6n8kiLfPp5GYi0Uff034sglgRg4UzmHEW4xPgTPD1oyGbBC5kh/J73ulGG2aTWnK2DFNr9bsnXXY4yjHOc66NS1K7+0+u7+A0/ezNYu05uRVSXf3+mdmM5mJfVlqfCNAx460+rJB87I6XPxLxjxPUpQ6ZLF8uBRC0xO1AiYS64QStswjFt+rj0atJwWbBzoni26seQnkdCB0UJuRj9OBeEzAeteW6SEPTxrmFECpxktC9yT9vj1gu5s7huI/q4EM3TXoUierDLzVNVYvyYfSP5y6UYhL3dhD+LTHxfn4orp74chjlLYQJq4U8iUf/s5MlPwmGcWG9odA3DETn5npmhZHdZ2iH6H08hcU3Mntc0oweU57/vopV2EnxRr+w/r2GZ0gYf65QQ7ljETaU7rxs2x17zVUSlOrpStxbe60rry5x9UCGeqhbVWpN0tnoxKjWfKxyXYl6OlCSpZXxeHNek6qm+07DJ1cxLRZgv0otepUJ/VR+GxiaoD5AkmTgGrLkdSnioFLNxCQLnCaJRukajG2RcWSSS+jh6SGVIou2n27X0MQlTDVEWl/qMMPQbgXbSfP3/Op+CKMlhX1R2o0OYXSu12pvRy8fwNop9iC1hTV8bnOd3AO50+j7WjTGWfsr5/WUNMeyYErKht2XAzgljOXauINfu4XM9afCKgpXC8SEVZwa5qOdaZYXGTH/orFUqBCOHMEHVojIMUemRHVagwm7YunH9M+btMxORbzNDtZkcieKvHdql1JzYc/Q+u0T7pRuajh1CTTWt8EAhO5ZHNtiVpJFNN214ha9bjtJFwcgO4mEXu555TetIkzSVnUj5xRq6lR8tq7Z/KUKFeDn6m5vHQNjCpjOpzW0DpD9XAGc+f6MQWM2pKiN0O5JEf8GbTILY7oc+IRf9OyIo/rU7hTiYmrguRWmwcWhoHZEZZrxgfsSCyZliQDPJfO+Cz16ZIL17f86L+FNczOvh7R2+bdxhUG+FqT8jK3lVM5qV7/F9AApf36LLJ95T7+pMf+G9LO0Ke/J/Yj8/GUWrHMID+in0Q6mH4D8td/6dUS2/Q7Qgmc/j6Qct8/w+RXRAVPnzFmtz9m4pta3BPIdrQa/j1gO4TDOEZ/fAmpnthvXa8SNfKovbR0xziQ6s2whA5lOk8hsT6v47GDVL65gIDHci+ae4EdEu0JE1h9p+FSDlAkyOU5vzZ9TaIyM++7ZMlLmzVDIlB0KZ3IPvSYj/SES9DYL2MdE0/pa9XzE5F9DzwPWbXWww2GJQdnzg0Fcucv5E36i16mgDBWa5SWfysEnoDU/+NKF7iYOrQnO/RRwRl5/zhe5qb1a0KGzrEsga6L4zldfRH2GmNJeWcYtR/a/gOm3vQpZtP2LA8zv934pNf93qxeBnFSpWCBlGG00KBqGqn09xXGLUq6bZ3Hd49Wg1MPwPOU06HSoljsy0vHytFdhUGnQecZ5237WrltuyLI7le1EIqpvvrlqPudwEqkvbspe1X3RDN8T3SfZ6ePOVnL2qU87MsSC3GE3rgl6VJMjNRMr+wZFGpYVsbaUkjsnvW+5WDPc9loe995GZgOs+SO3nvBNNtYKV0Xbm9+G5Kmv3pX5J2hnj/c22Kf0/0SpTJvESB3ffaJl6SiEKPhmv5zKoTh0eIIXBDbsUXFFwJ0ciCJpdEa+zAysEpWah5lSEqRDG5P4f7wSCDfk7n8Wjgbvo2VeskiEvEmyMH79InyRQd4+edxe18/mG3zJjUPeB8T6xdz/79kfL5YI/jJ5JZjclauyrZlM35/NLq7asTllMRyNFap4DuznKGRFXyIRKzMmMuZ1uiQnueOa5SFyiRWZ5ZejGBCo6VQZnuruijPmXhYj10op1Ze/xYgs+/s9wZqREZWmWLIpc+yHmMnhdexxMO+LKWd4BAuLwnI6NUfTv0AwChOjVH17Q2gNXibla2m3P2KvO9SqCgHQCxLMNrLrEEaLMIEQ3pbnWYKlux8nOCR2GyuOwjfPqqJ5kMa5+zS5Wo/VZA45r52KH/Ljl6Tvh+Zz4WHFUPP1TtAzN370eOuSQ7vzxTOWdLdJPWqqhhmh9O2H/4K/P/EHdAK2Sz3GdLhLoU74cQRlbsPjj6j1dqKXWZD8XOmpocber0cEzwQ6fxuHHKBNr6V/gbkfkUaQfl7amc5i+l+QWXmisc2akp5jv5gJHTxsmkqgW/J+afy4eIF9mdtZZE3ISD+Rd2/jdm2Ih+nS19v6KJpPKdhi1BC4GRv7wj35S/orHo07qeyWwx44cVJF3hCjfCXVtww3Nz+X7HMvqFssul71mAX3Kf8EoKSozv4qWuJQgh3umgBUJu3vmmLhmQvrk/Tz5kg9x6XJrTWfCmXu9H1uCldVKTQls7VS4nFyaK+jBGE9EPcvfaNnxvTVckx2WINk9Meb/8tNvtyRXeccVrbT6yVo2tpJmvRXT+07YxHGIbmu/MCqBR+T47hP+eIb2htH5LXPHfinlkpHr5d7E+RoxBwy3z7fu5I8L4uxeeu9D+G6FjzT4lfxQcMRoqlHqhPVdLwnVv83k0JEMkx91XPcVXd65pN6YeLmIkydKewo8ytT5mllOwunxblFkrJJTLjk5w5/y9Y5TjTjzcU1HF+RZrDgopgrAFFj0qf0IqZc1tK0/hyyjRmMal8iNuPO+6z+/rcQmMgEO6sNBF13JIoij0uTzW7HYIm/Uto12I5RBCYnm/rtqOxZOqbTK/bIxDTlZaRZ5406NP/A9Xxw7lohdi+JOB7pw8NJajBoL7pA6OLOHgDDqVqJqeYXCH77n9/VCO8r6sHV5EfzuaTVfBj5k+JX7UeLvUA6QhaQdCZW9ifWoaehW5z2wHK/04Gnv/jnjK38BjD/DVauR+L1fdE/Xk04cNbfW4m/T3eGDbRalCSiEuYOm52YIUSocY3rwpLtmsiGRcRQJrQte9Ltkl77NG/Ik8rS3FkwAHPZdkuhW4jOoknxRhR40HVAYruUm1NFiu6ihDF9MvurHkYU3JOdBR4BSMKdPLm3/6kDLCP1cOOsYhITTqODFKce0BYImsGyS2nmRsHXUtyqLjdhgZYWgBTgtuzWw177qKcGjrGviQIRkuXHURP27hjO7PBXqtoQH/IzcesyXkfd7qBj5DTsU6Frho4bDJOV7y41at9JqHLuKzc+1u0N/ti6K774R+NvtbPWmsUpDvx4+/rgLzYW/G03Nbpr0K6HhiOymeBLu9t1059behi1g7Hd39FXyBaVVe8ybrrO0sOEio/4q3sQ11+gDllsrje0ViPr05+TaB9cwo1VIILYX4btEac+2jGcAvQqx8psCX35/5dfJp0XZPWMlgPGFBj5Uwx4+YOEF2TrMIMQCWQugHbUe+Vm4gPtrYPNbxDxsRnRkcL2dfLwOnhUvbbEbBx3V2lUCJVDaMf2pyiZEnEJmWOBK5RsEqJyjxPlLPKcBc34wcizWT8x72En0sdVMO+Vkzd7Ovn9bqSINDAxSC0wF1hHcBK9xym68m6wmZPEi9PHj4YsSbA5lXOvP0PeFvAdgR12qsijosZ0MpWPE1zoDRhY05K/hm1SFEI8W8yyg7s6DuYDz1Da7ns67BTe0bfTVRCuYg2k5K7TPBlX/cXWgGwJvqBPEAG11qtm17v1vxHN5dq3UQy1Dr4Wh+x0+BlCxxIay6MwNkdJ9+fJVrLA4mdFO73mVVjCkIXNE2s9wGINQJO6XHW2D+21wRRWvd3T3chys3xzlqKNiiTszXquydR9rtiNOccEoeEiKK4Bxuv6/0i3hxLT2GJe2wVZahIgnxqfMWnO4LgObpV1AkGboap5Vcg9VgFWpbsTbYhOeQo99iSYp+EFSkNwj9qeANv2rBx4lwstoiUrBPL8AphNbxgmXJq7mLt9Y+2gSZLM7EPhlDkhh0kYVUYh7xVu4dyQ13v23WLtW/BF2Q0xWMjKKUIgvO0np7vHu9Ypal5E/X/MN8pPj+77CYxYxdTOKAITukF2WZP2I6YV4NU06p2RTAWVKq6Eh9tDLLYU6pPVas51Y7uFR8LvfyFp4WjHbaY1kGC+4s9gjD7bWePdnoYNEew/OKFald6mz+nIH/k2Q6VnYzicG+nZde6mL5e+p0DC3Rh8pwwPq2vjRUR3btQiRfgF5g2zK1QOIaZ+nk4WfnNck8tXSP4JmoCgGBTtQTzqtV8weNPdqjUqhIsA+mqsgO3/mQ0s8sgHJOdbLsOssNO0e2dGyQxxYFuWlxCiwZsY5d1pTrS0ueqS5dLWDFPbmEmv/YssbznzE3Sf6fT9CaRYTjTz2ANcicPuW46luDkyKmNdF5JZ0gxWBY9nNMPjHKA+GGKV1TWKao1Futodp+FGy7lFyuHHzXzQBX9OkeNO2cMkbSOhSvgcHbi8eXPQj60COSYfnmilWrud2dn/i4RJtJqr6n8BSwrVX4MZzzl/hswjUtBApAQoyV+HATwnwsU/5wL8Or8HK+dIENxCL/bJGNndmVQQAqw4xh77hZxPUdy/S1X3HCwrS+8blxXp1+/mxC8OeLUBONzwkxHKCLZokhZWXZ8+BVypS53yFwpMt1ylDXlQBO4/HH/PeAdkB1ISZ2L3MZhYb98VASRGOSgFhBPBE3FBxebqTMPMoB5Tv1+EMXulFECx8py2bltnzO3bNCgCBTRilAl26lvhKU1d/p9nsZMWS4QOAM4XgzqGs/cErKIGy3qn+8xoOjtnJpmRRkuPc5lz4bVcjlM2A8YVJEXI6jycrRgVEHcDsczzv/5ABn2Zad8p5oWF8NM6KhMWqvauVy4CPipSwtUJYH+0ysATRtOO3OPGqVd3BuqB2fRLyg72339uvMHXK7pwJ4QKgMMy3DesDdN25lbS3fixNzevHKbxjKY62rZF9w69oo+Fcwv6uWNdYrmMDxkU+dm5dxHeZJI7U2tPIurXT+7r9T54fy4SpEXP2hcelvKYo95xQIB18GaBwNdR84pCCYaNPviuopRRCH9Im1+Jb25BexKqnDVXbK1r9sYMnlXlPE1XYY3hvNwopMveSpxsxB8ZMTq0oAHFcUoWJD/EVV8UCA86fieLUzxXJhe/y5PPenb7APLDdSTbshTQQWiCAOU94lwIB+6Es4FpsVLmOUyNQhCjkNnWYQAhxcA+APocQXwwSQEOEuNc51lwc1ag3i0mYgSVLZdAsNb2yCqMyPihm1jNYXxxWtC8+5RYmYPvyDlh3cQtQDvOSK8RBp12doh8j0W6xrTNmOLi6B3gYzg0ZEgHMg3mb6ugno94Z2P45kv0isx6fNLv28q6AYNuSN+8oviPOdmTT1sTLYIsZ2MxNjGHz8EyfMT08MwA+j95ra9P20U7fRoRIS0DMqqAvm0EBkOrI/kpXdJAnrncL/SfK5+QPQfUN6lgSZFvzi1B/Bg9D/xpzXVj2NGRpfBYHV/XXvCNBtqH3bQRO8wNEVV/MCebSVO1IOYUJ0ImapD7AH38srWgCu0QFdyJWUz6PAmPdoW9NxaDfZ6DRuipxSzo4qFn1Mf6dI8UfeOFElQCp6QlxFZr+P21+mXyIytffACiiLG2yNdmCw7O2nZ/xrTVkFDiJ6tHJMqYQ0NUJYAubN5KuMayul2nU2tDoLLKGeI5myohBXd3zhxVJEdkPxccO/xShBeqyrYFrf8Ii4NnJJznMjL6ZB9aQTfLTaMKOh9ullcTpKYi2THvqTLpvg+NkAt3vwGaErS/UIo4PKDErrCseLX39he73AtrFA60OOyIou3MkMy3V8n7mTf0CoV3dsGCA/lSEfR0OUMukwWTzquy1zXH+KynRT9pr49yqcllJsHwLirywQrRJMMDTtv6OFIztRgYmIhMelu5fc/7TNVVcx20VIqtccC8JKIVJGrgNWdrcOYkIss2z1QxaRnGNXb+6UkjvWr1KKrSHo2Szy6rGokp2V5I23qvj02fyZB8F2LHqizYaJ7Aq1zdV6Mbcfb4Xbh3+1syras2j9DmvcYJ5ycz5qDZ1ZQEEPdjaCWQxH/0GmExwxjgLX3ePn/X3n/abQTD+22aKK25LUGGfpWF2XIbVyBxBGjW9q98tCFZlU9+MqV8c0fwdIp774rrl8x21Aru6EOtYK+cOpZTCaqkZsqMfaL5iwHAVorSeYBudA7NQFi/o7Mamp2JreSnM7EdkA1svTaH+WEMwNWtLFP+hxJbdp5WAsxwiwBp/QrobKvB5M5S+T0VYPs9tvPbQCbuvlgmXQHBdx3zGDlB02uGwDoO6ZblH09DRq0EHCvsOw91IrmRSUkMlt2GGxhoV8R/ahfpfE4GJ57SLHnvGiVtDLJdiFWjPZZYLDtN9gZTVbE6Vrfpm6dGGL7Y154mn0TE+qs7GJs5galRl33m3+SUAZoODy5rhiybnmeezecqgvaHphIO34a62N3F5oqw/9ncuvvAhbb7bVkO+RK7Re67KrPktzBBeLuf229eHTyqujQOA0rcupUgpWfM4Jj2r+6CGNCu/lJC6Mqtat/amLq6VsVlYkZTsg3lbTlc36f2wjLor/Jlrb6gaq+xnrVxtdkyDCL1QM8QmE7GX6hG7eFXqlFBrUi3NFIo36VBI/jwGVIOsEvACCLrAW5wm6GmEC6um0dL90RQpkmoI6A0fQh9pB36UvEBVgO/CXv8tL4NQkZPEwyTOwyc9QVIHo4Bg7e/DiaCqYPgzc67UoK/EGjwVG9eEvGPxRotdMqgLt/dgVxY25w+rNzy/C8v9os+rYMDUHyzWzbKXOuPjC+1rGRH5hv6DRkceUEjxIUA7Zo3jdDLO/GkQcshM+nGxb6vHIkEyfJ4dyQczVZyNDdTNERxQ9/sA4smwGLAGeGsBPEwE8jznKb+Czy0W7DZjAh9TzL2u7s713uZPhEuClYxeFunEN51KxmzaaV8u9c0UZule1JAAAYG69J6koifp3gTvqT2dQcZSGTedAKM+TabM4rOcye5hL+cVIl+euLMDaSQGODpjvj/jWFiLBM0kC2HGy5B9apV70ox8bVl/oOyW3ncYfK9IMhkdfxh7H9l6iAy+Pl+xL66RideWXl/qWdWXP+e5qG1+/OVT4HrkwXTG57uJ+1jqjWRlnP2sF5iAhfsApMnD3dAevHQai8mCW0zoC6KpOqZRj347R6TFM4L93YR9uCrVSPUh1QOHMYKo79ta6lEctL5uQ3CxIUapx0CsxOtoDXVQqC4+XEYWJpiZVX37tAApRlPfGZb6b+y3ne7QexviQOTL8I/v1m5TJ5uKyNghKD7jLwX6uwxqNb0gfDSyxPLoi9LvbuRkMIaXhdUhdJMd4CbaMDlPxfrIy0zFJzChwfNJEoLek4mZ1M+4xRBhh8WIDu0gRgNeFT2Xr1kcuea+BpvUsBAswVukFx9yMC0bBrYaFlu2WRcWZ+ENPme3D4tftNFs3OWHw/HGji7pikY7bXLNITfIZS2w6viN42NnLwB12y2H5g6eLZfB/lddeYs0elhZJgc3vycnMZFKlFgO1H1PCFs5vmoXXqseC8bvtnzIPeTYbXeL8d3TKuX05t0fdLC2kWRbsir4mOnNHN9PrC7kSO3LLyG7/UrOb6jSGBmsgk9BczEBLpO4ZL9oFfhVEcVXkEi5gG6UVPNJ0c1GUucndPGNC3+Ck3Tb9Ui3Y0QipiFAdpCJc6bxX+XM8nw0LuYE14rOxRq7lgljdKTXRTWQuTiFLpGvPX02RJOVVPSVGip39aAPx9zel1X1SCDNl2jOs5MQbwGDKvp2oRRUm+CLIbiw1LgwDp4YmOdpWDSzXtRJL9uUGAJIVdHlw1qeVPee6VpT3YeM6IiC+tyPtmoTRsmRlM/jDNrH0jphFyBRWltv/w1ElgGCDsQ5Q+X+OOTNJOCXknHIpnnPax2m1YSxmJRMMVDVmIx6Dxmjfb6HMyFktjWoH81JcVnxmmQLjh+6WD31Bi+YOdxIHzRiFHUL0UqjWsgCSC9klHrxzAUrMqqm+uD4U3rR+qEReMVggi8JRUXdwr3XM69hJzi89Hc1NPxVaBzr910K5OUeOSuWTV3E6xA+5A1J9obfGXg2Axufi5ZJdLjgvEe/PZaauV6qi59X0eYvv3xnzf5zjpW614c69jTcdKx8b5RC7ZQAO3fBhjDvpsutNRsNsE8i71JD3c76s4dlXTA2csrfz0pU0k1rfn2BTEN8bdrGjWjH7wBINzZ0ujx5zyFUVTfuMWKapyfQm5e/LcHbfl1+7ITGs/74ohpC4I1mBIOK/1A+swHHzk7BtfCmIU4NGYY5jjqC/hYBlPSqCBPW4aCLU8UesB9EqhaL6i2k0iZszYfrEeTV27fmpdkIuneHl/qo/3sCJIOtTtHAT1pe3NE2bKw+XtFiD0lWavoLH8uqYo1+UdzDRhgEROUrfnsUkbxbmYOG+l7dWkcDQoqHInph6Zm0axcZMuajUAz24r2rhgSVnGSOtkuyQJr2v6IMrbhTlYSi3TL9+GCxrTPTBC3zUNhMksveKw+0OhskPCHhg9NOcEgjmvM/lk6TQBXaDuKsLWFWyqX47Rtb+IyM6HYunTPhPt12mizBcNahparGkyd7nb4ftmpSP4ZjTkGXCmvo5iMVUskh0eT95ScGYzms1kPmIOxZpyLFf1amGFApvhEL8kFTlvUx+0w6OpLvOIRC04A/KyV8Njy05sDMfLiPk/DB0QU5adePnT+M2uVhJif41c2mB2sFZFRsK3bnRjXDSuXrejvCPkncTQtC+o1go0nWC276Z2w3W3AKsoc/PzNzhqkDsZ4eMVJy/4TKtJu0CZFgDRIpNPBWj3iun26XVeAFoyYHNoOuNlLAT0RLE3hNRq6w197W8msNLhkb+YuJJD8gk+wWO3Ms0ybSgiP4beJaJnMUt4SSJ7d/zbMLyKdvChl4qq00gwdk3nDi+qGyVy09EcrlnS90/lUHmstA/fZWOt8I3xs5s2SvhxytDEvVo9o9qAPCNcQsoKn3uJqEN5Slqsd09DP70/MmQdiIOV2bqUQm+udAM1Or5alp6NwczRDa16QwMYQTRT1ZNQ79xOsezjn9N9VYKW0s6Ay1NxzjXAJ7y4bUTZT9H7Tj3O9je5tC/gHd52vpBrOCTRtg+QGzNwANivZ4aW117Zj/vfITBi5rZ8KH8Q1uqT3sQl96R17W7KBef7Sv9/zJQ77qruJljRviGKzrAzJdf7lh9VOWiPKZ7BcS0g2Rz0ZS4nFTP3wB6Yw0deiar+YaxuzXb+o+R+3myCpK8KIUcPq03hs7rSu3M5wx49viNuAKLzZqbHQlPlNa1PEu+S/13TQDzrmDsXZQ0Ko2CaEjnnaTMnnApDUhMBymsjkX8mFrndt16Y4sJjyZhlm/DxbuESnrT3QRNMRdHqoBoNXfbzM+VzPjmeydKvO7DwqVITucPsE0N5IbIH0WHeNgv1LNICibB7pLNwMRQ6IVNxcvsvrHRw0lMK1v5pUUfJ/Bap4Kp6MxWGPNjiUyKXZY2dyyvom4jbWNjEHWPMdA5QMXHyMiW+cVIdpZ0Mud+//lzmVgyndjl0GGMDIhGz34HKhB4uteZmrpSf4Zcb+8C0+HlRRARBgvhVQdY+NhNwqM7KOM1D5nVJxdX3xIzZqCV7ZZafsfOn1LC7YVg2NQiQviadSkLZPU3fH9lJ1VJ/djxeP+1OJhs5SDRA3hDVK8eJLJD7hOhmUykcaZk2ikCb5h68xDPIkXon78sobJYLt34gh3zA7z66rAIbIY1dt9Q1x17W+22fPmCNYe9i2IUnvnqcyaNwMhOlQ5+5rgxrfAdXyDue4xasmvBqdxqvP93YyO5WmLICkssGWVFm/9hKnqDLaaV5upsk3DDTWjpVyh0P8tSzZjXnmFTp5b6z77XRcW20lWXGF8LHdbGGLFIcXmdpU5YhDfWjKobKhoUHApD5yep1Krz4eByW1yhGVIeMb7RlhAplQTE49oINo8ie6n/lXibBlgOeJxn03mTuMYMCoZnfYig2NEoT2tuPHQ/p6/Lc1baVVlXrQ4oqM1Kh1rjlRZW/gsAusqmTgYz2tLEFFsg4aU8aWzBZYPm2GiaYaKujn0LG2aRDfiZRYJ6ONKi8j7cGA7hWF/AqVIjjYfhyiqYde9/WLNyzQ3KDjUZpQik1LNd6gGTSl2Gyoc4EMhSeUePzBg7Kd/jgckVY7OIR0DISoNB3Jj6UTc0NzTctnvLvBb4py2cD99imXkg5j2T9LLmabYD5fhhq4x+IG4dlZGUrvA/64UpkLldL/d76PJ8oEAeQ6jS2oJ0/QaeutbUDSNmVwSAExkRCgZqTz8ac6SF7FHGSYkrG5HH58iQXb8lR+SnT2G7hvZfhSdW4K2RE2VIzJw80fug3nxfiDPnxXjakfKpnbhaeENDNA44aX8ZLnvYpaRMFcM/lPULxI0odcTSboNjgNkbQO9ZtzCRDZauLng61oB8Y9lwkKVo5cbQR4I3s0sKF367bLdN4FwJmDglz3JD0CqIBHCC+oXe78lsXVw81Zr1wtq1LhJZoszYV5k3aM+bJxRzc0E1rdnPi7LqW/nZS8TQDkAGMuEAA4IRL8T/n5E+BoWp+giYzv74xAufNAuYFkLAsAAvAFnl1jazmyDR+JmG0hXByxyM1vN5+3skJLzfYCHWsuT/XDnV5aTsXU+WL3ZfG/kOzPcWKL6O5FzucK5Bazih8AaL2BMEPjlz8CNty4hSG6GZZY1M1UAswjT4mm3kYluJajGtuv4/bgp3wdALc06uu8pJrvo6VUzmS4vCj99enQbNukO8EqVZStdJKmCcOenOAqdCHtZMh0vfvupQnXk+AaUUMsekRnFmT61zbLOmxhMC8TVE46awREkxL5DMa/V5+qZGPNTigNpZGu3LD8vB54+GO7geunod66htu8V0qnexpT8/SAHkrdnqd63u6g8mOcdyix7tLfVDwSpluhzFO1vNzQrT9gg1eDrb6M6b0Ld8WyuHUm4dPvDdiU7TI4FnFzM7vDvtoQQUyvu/PbLgH0yCpwRXQdEnIlNg0otETInZMNEjrO5a9f+sR3DRnPrC8CKiuJW3DCF7kn3hLxPi5m5ATQmxpRVjhrV2C7UOmh+QdkydwDpHwa8fqgeaKMG3w516/eo+UvjIKT1qVAt/uuDfw/Y4vlt8cpz+3pgIqJtwvnYsdzhXL5ei1ePQZYHzZli9HtcYJSuMBxe++QmpmIdU5oJo9X7huwFTowHdlaZ0tSIWZp5so8ucN7VIpm5H8Zrjv7mRI6/t3/fkB1+XR2dIuvA5T0HbawjEYbOhF7oPad5SdfVW/6p38uFn+Cv2CjUlV3nhX+v1vdvX/h4ZvCY/4jV0rnCRhukka7fWwbDPvv07ln6TSeFrb7pX9xn+k08wBdoRJFVMCn3Boty36Qg5FHAEMnttiSw8HJfXaCmK8YRyG6fdPWLuWKKfdShDD4Olt5ZcZrpRZGOXJP8o3tfGnXS8obje++piMGJ76odfZfellzzrnWVN2cZTUFOfizCvGuVAnpi+lEPWw2C7WZOIsCkB8N1aFCw/OFXcZHTkqZN7erDv8lpV7QSaN8mnQZ6uhI7NecG/YJwBIavlxZU/DTfjquugaeDZVCiYgqa6+UWgzdNFOXP0DR+YExhPYn7jpBOqJm37g+HgCqxO3/sCF6gTenKCtXF8d9VieLqTKxi1nOGZVTzjakukTY2fmVstlt6S6MIjrf2uLy4eDQBragzFOb2IGdHJMqk9aSX2DtR1ykBxt942pJ/yltWNfTzVwSUt63Id0lBvC8iHLthzlXS49H/d9Rb8Yk4rT1L/OxJs7+i8rxRdrMBpIokGdjGLNfuH8sPV565El68yNUW8IsNaZjgckWFwci3S4X3g6tuiQCyJRcnokZtw/11vsrhYIyz3SC580EBMowp1LEpS/wV63R50qkJQc0cnsRyLEKZcp4DnoRJiyvMcszW9ljtjm1TnuCWtvS4GV0rB9N8j/CARBLCIVhEUjxqY7N+TbAyfU9WijeG35JmNEsVDem98r+m+RphZeQZH4/LtFpdNJPfNK7xnUHZWsH3ZtIo73YJoxRCykhw7vakes3gtm28V8xhTjQsyYjcQPR9BsBIuEUpkSxCz1KG5siH3eafIQQJWjPuVsDBLZa6yWVUNzXvKoMXW6Ui7ofiZjL1yl4QPF6EdrUOVYvW8KzrusCiNfRvCsOzMIBNatGCPhXD0j2duRLU0iiPK1YdFgg8iJgcbtXWUtLuyaFlGRXF4SjVD+kQLyY+ZHJM6FlV4wGnkB2aBSGLT9EMIknZqhAOLCcuvZQL9WYC9wHeiLRopIUlhvsSb9bg8zzXzVq60cj6cBsxzZxhzC04M090Wv2G2R3UJ5hLVlOO+KfNcoi8/jo7WxAsTjy+/Zsc8IF+NsWazQ2itx5QhKe77DcnGw4aoBk7LJtapHJ5FlRBGZ6viOJXPyeaX0yE9ihNwEjQSwQOBNEZTmP1TyiRaiM2NieSkFO6AKZWFLTokQg/0ZKHiAt+wjiBoC/J1YQ1iww7rp0vdk7OsH5GBgGRT6hpDfw+XT497cVfuMgthuiGWTvlrfKJb5n4qhC88QgcnovN9q1jVlxN7alqnl8RMFYFOQ044K8kX9lTeqMZZoX8N6iEeGd2mTlod/KI3zoCrtzli3f7xXyHVAsh2MLa1XQ9EElVv5t8+T1cRKUucaebPva4tpErCFfBalAYTbQRlEnu4vrNkGhcWgfbVXcBLk9rhtnsBzKWvLXjltc3jMfXK12ZG5CEBNwWB7ojTAcKZZ2sC5IuMOimQuWYEDYtU1TVO+qp/BRIDia2PvBKlp4cN8xkoQhCDIWT8AMaG8on9MvOJ658w59riUkyAdgzBswwgWxeOTUvHPshUQMLewP+R6bkfogOfokMnjCF2uGVzrFzJ0cLySKuhM1eyFxfzcuhL8MvT2+zn/H/+/nEMGuD+cPzym786afFA9u5J4X8aE5dwz5RpGMww6wldIR3JTHibQckDcUn9MKaqA0VXJfy3urJNX+BFWiFH9QDes1AVQehPcB05WOfaNZ/l4jige7yzT2V/aAqjF7bGHGH8EizDhNE4zFffcIhlyCvmnMXw79Bs4xtBsPrNevDwT5Ss3+S8RgV6t0Ec5C9oQdew1vhUGY5z2CsuuwMOFs+T3ixL+/a005gs+rmQQi8MgA14swF9o6JGJbAQRGga4l6GIBu7ChExfs5ivXmSdlUesnkq2VR86amRTJwF97J20QlDzsVFixJ9xY0JVZKHqCdlO4VCBYERG0voLqbnMmbdUAqo4dXYcWhMwoKeFyNjtmsP421RkxMoi+U3JzgfqvTp8Aw1OcB5gips5Uwixr+betsHlPA1kPQ8PfAAK4s6BHLz4/iuZiLuGfraNfqQxcjNDWb/EkqKmkFvJpjX5KLcyQKULIGqIk4uXQPnEGrIEJ5gPde7hZk3ysZFUzL/R8mNW4xEGGNyhn+9YWITCphQWUINacT9FgZlQVLmAynm1zJYsOklRw7AOFvdi+Vfnb3aVhxqEhvsB8BsuQHINFdXEAnrmpgiLtWq8gGbcCd1HXsOQp4TSJorQ82gixIhKlepGV/xSzHQK7k3HGEPybOrhWTkmBbQ4QyfBL4EWKrKljSftyt8B2oWuoLpYOgqCrfmjdTeoBlnpzPU/V23QC0JumGgoA4DgtrK4tnGvIU4q8ixHQO7ZSbFPTghsVbDrFOuHDf+O9M+3IJtQPFIaS6vSneUFUWKzi/I2aVrzGGxSbzVWYKXJefo3tQZmW5fhdHOvAWXuhb0UOEPmnwWzaS3z1KszWcuaLgmHtdlYiVRPRwSsDFQgkhvVQ4nI6vY+1TtlEnnylIeHKF1OsUZcK4jW77kdA3QqzsaAmGWrLmsBoyIrCbsTzH5r6QMLz6Twh3PPTqIuKxe8I+YBe78huGCYvxVN7Dg2JjOPLtpVKMNgYI03B9PRObPMkoWbOrurZ0i5CbZM9ChfqhXNQ6FXY8NOWH4pxeKK+iJkKb/2lR7o5/b40xV6c+TjQEi7yMObkivGJoprjEqpVMlARFRwZ3P8yasCCe4YYmOeOhidNYZJjfqgkBqpyn8EoXKbM2HJ32BLUYDwqi3DMhA845aGZOFYcjaDb0UkrRYoRgGYhZPjsCasJ2y1Z8Ga5CWPsXhqOIpNbhN9hoOGWMEzEh/xHm+UOxf7zsxkRppU49eNP0zkNkHylAFFMQorQrOiLD2lGHSIvZG6ZSLqakwJ1F9wkukI/0hk4wVVxDjMNpNMi5QByxeqm5+B4wICGnFQeX4kHUaLHkU2naBm/m7IL5qRihgUAUsMZIYlEshgWDIKpAeuBMJW6DiipcbAF1ECKwYzpfmEsJs53+IINIP5n+Tki/w7FHHVtQ1DRezTKeXIZnLoPQX1597JcSKh+dfcPUi8V0vm76hpcFyktoY9TbAlAMpLp+T4zhVmJ8fEC+eQo0835rUDLs6Qw1/XMJl04+QAZDwqocsUE1baL2/GWZoYavxTNsCIighuPVxp3jcJ0hP5Zc0DMl5ABozCU81Sli6XkXN11ZLXbugRRVdDpiDIuW9zjxWH6/zQ3Qg2LLWUlHkEfkfwOJZpmIGtrYHbBdviU7m61u7Th30DRy//9i0+/dhA1DVtR2zbKT+tC54+6QYeDttUlOt48yq0Ftb24DGwawjdl32jxbPiyT4/B44G9jpmA65JtLXQsa8OvO3UqU+w/adR6EgF2gNFGCfk7qPcQcRHTNS7rsBlb7m2nTn61n3j+jmK5eDJKtHrWs4xHYMDZzhY1NZTksaU+kWwEOq9JCdpVX+K/ddc6NZ/myesRTjlG//p+28eZzMQoOWdP1MQswEHq7uMgY0w0rsQNROIqnkwziA9bwvhoCeOCK15xLm1h+uR4GWNugxE/PSGQ4jW9spE/HALnpT5/FCT9/ckACHh7AbS9wl8XH2FASMDzxEp+4bw/mZQq6sFDGKCXR0/Fe8XHINQFJ6jCoOlAO3VWAGwktJjItO0QHgzVZx1bhPbUp//NeKhtmskcbbCMUiZohaBibWugrNh1j3mJ2Y8LZ3KtOLLsu0hnuKoJiXNetuU2gN0GgnMZiuUOYR5uti2Qb+7ITM3Fs+GvCsSLOxmGwdjBcBBc5YoqNG0pHjNOjxBdsCQx2U/15Qer1+jGu54bcGuivZFBgtKEO81MMYu4vmvdKmqLmdsuxrHY/cUOntiw+yaV+OCHeVzxGOchhKoWHY1bEaxA0Yz1v3a95Al+BXuzQcBE6R1Xf8IG0XH/Kc+ol0arpGsvCWGgx20E0bupKPIft7CYUC8+IulKBkgbI/lDw/0DKW7pHPOc3eqdgDIDNw35C99i5FhNmMtHzWYwbNZExlCPB10d3MSn5/ba4Irm1aMx/bdK+Sst9uDMpCNFsbF1Jg/h+RjpfyonmFiQ21TUkom+0VxCoHI/KICCHr/sOCepOROJWYOwYDrbYnZvt43rNTcMzt89CidXb7eHhnGl2kqx/8dqtczbwCFauW6NRWOS29cBwR/6n58KPwjmC39WdhFzySKvKeDbF6WfpS/F/hePQE5TKJRN2M7zdj6mvx0F08eFCM7d4ZNI4jNsBsVTniNIfwvB+bTq21DiOIkUQi9/wZwKNZnXl2JCKBW4h/VO53ghh4WB/3NQRmX+SaeFQ6DTlZPimEwFPHx7/vKh+JY9CdjKeOWp17ngC6Dw/STBKGaRfbjvZpQUo7QEpzo43h7AvziZpy36F8PYLOdvSjE8chpe9C1ACFGODhrei/mYphb3bE6G1X6GP2hJy1U4eLMC47OZlnsAGkL0hPoDLH4flceO4XWrafVN1mIJSY3qUJy/S2q+GxP/U3MpQQprn9ReAuABPQ/4oZs53GePOfOTZ4vdSdh8fajuVWBEkD5NtxrFejjy/RmrAFNoI61gv+RMZXMu1a1Efq8ejDSZ597RYm2+9XLKASAjpvNwop7i5saMuP7nzfMsSbaiBTMcJ1OaEcIuQEUQSJiUfSatyUbu6xIs5elEj5bGR20tEiMPU6GiIJTP2HS9MGYnBA6sZ26tbNnMLuKAtTNZg4kznoclt4naiePyRNWUZHNPAjxN6STzJOlzFkePChGo+77LcBHeU33vaWrpVMxefAKnzD9Iuey4xJ5XQY1fIbNUsiy+O2rdsVgDY9EbbF2zM+2hWgmqutBZoa+RLbwgDPPullGUgi6q5BMFsfqHTm9anEzUWhbZu8giODqVlnwseqRY+4dWMfDvmxL6XzrmRWyBvII1dED/behiyK8EIrFeJ7QtRz+2+6B9LdZsRyitHLtsdYNZkInXzYL8w8BKTH/Zk2UwITWBSTpitKrIZVMYmiOXqvxjcxC6V3+9akMUyuQsvr7Bss/60UiEvr67ZkUMUPsRdX8K8ztrcuDLAhdgByzWQPwDHNQ6U1PioER8pC2Pk6yNabSAPETIq7vVBJV4vgbZvfitCk88Fi6rqLudI+WYOZF9PNsNJIteQ4PdyeVUPe/UY9uG/alJVl0P9A1gyrRt+LNbDCEkNT8fXp0lHlYMXf0cJ03a3NiSjj8uX/xd9GVZbx3NDVbsoyT2gQufp2ZTbRl9VY8EYlVwxqX3/JjG2pWNYfnPjfgPFW3p37lS5Z/P6dJ9yBjH9/y3b4cBUidYZXd03ZC1M8r6f2G2cgy1N7oLPSS7H0+DrFh+rFAJnOl9kaPXgcLU3KOThc0uv6LfhGIDqcsA0tw3PBcRhQ85FlY3Zt91uEImgS4c3lVcvI/9B9Y5HNlUiuU0+i3hFdqpicZaBMRDjtcPIScNe2X3ZIyOTe4xV4D810wl+a7F4x4r0eAdUV+aCpNi1SIeHdjuwNKe7p9zbGJuT0qChVY01TsydZSMM4zz5Cd0ia/JkPImlIx4aHYwn1UJElr23P7khipbC92I3vuQ5KyeZTj2JTZ15GreJA9fDl4mD1zphyyonz435Fudj81sjiu/EDn5YWncZmfLMVatE84g4MwD3Yi2Da16yla8f5ouUPCIqMmbo3Xe2YR3vyz/RNPh1OTz/tAfKJ57KuEQYX/i83JpczSNfpjDv8nQIsxD5Q3oqnIQnpzogfoSMtjGhN0PhPtI+BH82sGRHbC6bnAkPKYPR/4se+9awFj/iquxZFY0SEKxxLvkbImtFwRcPM4I9+kr4jqIb95xgKrfw3S1OYFUZtaKHzQ1E88VGAbifcL+ldwr8NimFY9zsNkYxcQB2NrztgkqVhwvhS9NhCJ83cJBg3kRBJBwZwbgtnHzDandSSSltgbRrakdFQGwjxwCF9YZRGlCBo7z5zADDyqa7e4XNlRmLtP1V10gygEkr2+al8JKri4cpPFYjcbDXzCWG/VPx/ey6q6VDvbVyuOP7+9EJjwvOIYnc5CV3i+8tLxuiPew6P67Z7AgQBU4Fmc/8sSPwPkm0AYYeLM0IkQQrYIMXMFmB7bmC42ce22KY8vd/k95mHi2VWmXLSq09ZgVwlhMdj5p5mamNi0cYRCX12vg+OvyyErZ27xDWZI0pQjqS/pcXyvhTlwZabbMHIS2Hvtv3XQKc2x+risMuuYdotssqE/+H2Zx3LHqxEmOVs1siFhdeWV34ZwYww16uh4F2TS1YV3xKoa2Ed/OIWw1/njK0MBwTQWbSMt1Ncvl0K5yi7mZutRoXBLApemwl6u2q7L/1rQPzd9QCphPYjJb/wTn76qIlqQymRarPY64MoC2rsSrwHN4OGN/W9hDoBUZrYs0HWQBspyhn8tLuPbTr1KgEpcPMyBw0ss8Uyz+WMsOvGqN8Sq9XUH+Uv4r6b+LKO3LaqQ59bxAYRrTLdEHd0AKngbz3FM13iWozhcojPCsD0XBdVYNiUTuUbDWrTZoLfP6Oek70UxsJBc/iaax5HY4vK10GcT/Yn9ulW8EIdrIj5z099iZXBZvhO3yD2GMpsemJ3qjBDwkB2gNytHoz1p2gnYdOL2g+FH0e0kdohndbUw7HH9PH3tABIxxBfC7zXK+3S4Aj97OTUorKOzCJbRpUvdLpqfaRmohN/ZFTMwG1lifVnHC4EPJWFxsArVffTChiFLDX9jv24V3VzC4QpzHsyi3r6zMnoWTEsX8TYld2n7lc0mNu8QcXa8Erf/jaK+u7q4XWCtev/c9PzkrOnqRqrbvEWXjwArfberyvudIMuItpwcLKJt5AFXDdAiy/aZn1pLmNXbh17cpmXqWBKjbPXSFBhyzOXK+o/gAJtjdgTCQKNQnFmg+NLtlD98gmdOBgd9Qq0GTiZAOynh9OPod2/Gu8k29SoEyt6e4QfnKit9WiKnidG+eHH1waFGNu1SWropgmVSr81r6bQsiEj7iWkxAPEU7pHq6PUfUAX6APgvwK0pVNNbTIo75ItjbufrkuZbaHAFjZe/extRiLkBfihBHkWh0wZiLME1ojDkBixyCX4lCpfaAE0F3IuBBS0ErUA6MdBZC3VRAYZUE2/jBgUIAAIAe+tTXnHuERbzra1Z+F+8KlSDz6OgIl88Lfr+7i6x70CVqC4JFrmvLpcO6StBcg+6W8FHYwJM/Rh5lbH0Ob95GCoPFVHGTWfO3vidxtlMdK2LAPshGI4L5Y2zg6AXJdVxTza071XblZMTQl36mXTdAxrB7ln60IvFfgNnSc7azCadQ3WPHVj9apqsdswIARI9UoIYNA/uMO905sexlwVjThb8gxPxYTGL83LKA/O/Msy4OpgEJjRdMLfFxKYHcK52n3Pm6kWfDJB/B4b8iTGHBQrFNl/mReSj7kY8D+IlBGPibiPK8cemLaQDMK07rUJ5f7hO4XVQ9poj2Lw3nMZ0ChsCH+L8kmoN+pGUVP5Rri+1yfbC7eNDZ7pnjlO+CDvLOZM/DbQ2m2DGd5dEb+EC8NlkI64DtUF7GKHpKos2EOAwdr816th2CX9JJB+toO7DJ6eWR6oKbCzZEy2Ke4aobc7+iSFFot+wHXUhITu95OoI+VM7SjPWAg/GEpKzY2BNqHBt2L2cVKfPFPqiZTIMJ9LGf21aRhr8AQC37TGgVpAHRMlw1AIoz0W77FrSGozHiR2hApT5JG3mfnaNqwP+ad67UidVJ6S3DTIbJyv4o+wYfww92naMFF9CVOGEzjYInPoyDkcSksL8qpqHS0haYv4xKixl+Ay47d+QODoSyVcOq7L2zqF7C0wVsZ2baeMgkN6fxZ1XZ67vjKJYGJln/40vBrYn/HRqb8mPMlxtd0lrpejlOasYESobHofYfcufw8jjW+4gSzStBEdRFq6iIJca894w2pFich14Pg/y3vJ0cmYrrHyTHDuNZYjo6IeUYyMLSM7OMzudV9neAXgxO4SNWXUuzi/sZYqA9VXPOEkSlkMSqEhH1iHxy0LnUb3a7lL4HMK3HnXSNhVVJBSV8a3lJbsHoPdnn2cuO1+2hvRsNz0svDmxBCvIPInwdVjS82YBVt6L+D2NUq+b7fdufLp/DTRRo3mpS7CGKG88vPtc5OUmnNJRExtGgEXuosZc9LGq2ckdQrabxQqC/ullG9IjfT6HQ87IKiJ5LlWPiZrsY9bMrXQ2P3e0lW2mwv4Ti8DCmUUVP3wYsRk2cHRd4rK0SyNF0mIvhFcvC1oV8z7j8QTAe83JNfLcAXRaknPpAVV3Pxq1V0Mv9e9mQBMe01XnbUmydwlVqGSlGae0T9aAYOoPKR0fnXFlcJ4iO8vwDjBtMENE8UeeqLIUbbFIjy/LoHlc69kN3oqEKSVqVJx4xw/K1StPNO9xLTulCxX3CIkSHYX4x6IbNCAIaiui6qJx8CdVmagB2GD/784R7dl3zVCtPyCy/uQc0Tw5Ynjy+PfGGB09MKWHXp/X6SBbLSkcTkLacuTOW+srgCO9tm9+XqIpMVrQm+kghmEYxvGFXErUzux1PvignTXCIxViqEQRaYXX6MVT1n86DSla9aJ0t7v6GzjulLYMwyejw4+J60yws8FJW1Y7OXB1zmuZHgltv7BdbBjkOwnjeO+wAN8DFCajRFYzoXnCdGIvTtIGZqJvQs+57PuzNQ5hFG/fI7fB2obkYG7w7M+UoVXjXkwBQxGyb0VEdMuJCav6F6f5n+A8Hj3M8TjibNvwMq6u2h2c5ZfOO6vhp9zw3fDnO+qWRmcGmUMgTGb13xzy+mjK8p3FoLCgJ41uiAaN7SJzzshUeHA/1dQYebAvan4rok8cqyqJVfX7++h/sKrN/x76JZuh/A0ESjvxhA1onBJcILkmWQ9A7m3fAHkkTUxd5noIswGafj301NIp880YzLc9UkmAeWx2a1wgn3N4IxaaF4YiPbnX6xvttoTd8iKXMNe4Hu4Bs1MLa1xFZzLrSshm46V1Aqs+/wN3ODbLrmjRqYru6gxdZsZcOwobj2+TVHkDG5kZTFVPVvmROQPhER/3qeYC9YPLwTJZayEIl6m0umub9teKP7ERStvAVtXQC+IBSE8Mb0a+j0uyXRV6lWhDH+JGqb7PpUTijp4HUCdLReVTSHqG0vQWj7U1KoCuvw9arzDxsfLlu554gALy+aZ0Gpw/FzIDejFuA+gzrSEPeUhXLNS/14qieROupPkPbUub7qs3mEt6fW9ZO67omp9+yD0gEIkQgz9UyHnVjHqU3ql2tpB+thFEFBHq2FwLCe8Q680DZk08QSKfrBvENyLPLFP7pYTsFIneTB6oUwxpwGy+QnePGXUfxm4VZtJH30isZpC0q6NF/0yV6K39MgT9+1W9+bnAcDxnhMgfed86U9bLHe2lQruora1gPKO2w5N5P3/PEuCwzb3k1jzxaWFqsUbMgBCdLq1NE6+tj9l8bnPPeUicR924Wsu76618fKZJ2jr+H55vmjAAKiMmBgy3b/IxdSZV0FK8/eCcQreFkP2Dz+2WqkCLlyX9thB6GJJO11xMqZqrL45MCwZ3nQfyFjo++LcnszXrxmu1aH+Ovs9zpdC4sgskshXSUnkMOeeb7OWp0EgCi+9abhLomSHGoD54ogoj9kNUQ6YCrAlJSMG7cn2IH1WTcGsPJrTCzAhAaorUDqZbvyqw2AdENZxJIlCDE0bvQDbeTsA2Uw81cuw9l9CPGjKnhr3+vx6J85lCOV9FJeeAJkDjxWwVYnMKVUHWQGWaPfUpF5enedxC5VboScKlQf027a446gO1ti/5PTlJ+uHsGz8nGsufADS5mfcBvutS4FgF8PJ8p7Cb8EMG0r1SrpprOiLDPS1/KJpJ0XxGn5wTzLOrd28mjFIpb/Ftw8bWD/Q8n2EYhuHL7WnEC1YcPspxiTm/hXPq/TkO6Zg/k1WCyH8iLHANq/9vl6czcXzQloQDI7WHjAstH2EaTU8xzQ7KgkO5Xm1f+aucUp6rTv6GMmGJg/uofELkUzr0ent7+IyG9LMVWLiBhH6tSd0FdwjeX2DdzGaD3rCxoFoITBzQoWrrxh0gDP4+20oI7/MvHGAOwrZwwX4uoe1xzzoYKg0Zzg6bOO7Tu04f1DzszHSkVeI94YaL96Cj0LDWHfr1knGFf7DCXdUqe/NiwKio+QuPUx1eM+lMUiWYTlnnSWHjX+WE5ZSbTaYJQoPSBuTGl+uxhWbfVy9M5Pi+7LODa88UVKc4c5p5FIfbdx+HqsCHH5WVQk1NVINot5z1V0RdcaJDuDI/tR4AxEOpiGNgWol0u9ZcqJEnXx5U7NsYobpR7Z2vR9/fo4VcIC9JwpLAdbDXK1cyOIPvo0QWLujFxfT7P3NacEcUUIzgPt2OPQllloj4ACbSESPhIdUXXpkyM6vYWTHu2GOrVgxGS4ZNvYoj17vfHh1AnXNfa9jLzNfichKQZDpcaQcZyQVTyxFiVlVUweV104nNhIeYDR9GTk4+3YHZhQrdmenN0N5fOHzm6IQz47Fb/yIWIriUoBb5sN5xl+DnLjppXxEviYzS9EiqIeI9l4AhHvjGIhrCO56gew8BRvrj9kRlFLNI+6j0dI3tPtYNCp/uFLyKLyX7kXVgAudbTb0oW7H8K1yJjpRkKLHQAevABcL6k0gWZAMuOpbmjdIbHyxqD6q/KldrYHPSEPweR7qXvDp70jm8CoijK7ZbhXD4v8ZsjuoSurUZN4TydxQEldaM/QNjYkxQ9K9pm57YsjLH2CT3hF9mCunn3j4vio7lqsOBH6WVli7R0fvrAmHeHQboaSszBLHAoMmVE3a8ITmZ/994N5v5CYKhTDUVBxxJUcW94pWxDTlS1WF7+RfT+LkPaiysrjltdqwa99G62y+u+k1A7Z1v9bMFl6NGiIV8w0EQ6Xd3/zGo83J0y1Gze4hrKk+Zy+kuT/L6dcAfYF2zPZS8mLqWbiwiBlN97CW/+idgYF4T31K/tqq3UpUAeGINscRH7fqlvC7lf+oZuEsgOYYuI74Es58m/cfAY044DQFLrsNUlVUmWKEypZO8rCEpK1L06WAJBir3ogl9Y8Dcfh0l0WqbuH3gD06yBrK0dSSXZjMwId12PN+8vZb7fR8OT8sob5eAUy2yc2c7lsqKm/itqRxDeBUE8CRiQau7hoIMYsl2utasciSJDpJt4ayKlN09YIU4pCsQ7nz+/M8V8nCAP2lo9QjDsSPZRTkrMoaa8GpyJCCbd1Yl/FT26lbsRtbRLB43kPS95G4YhmHYMSU/rKMadbuI+3TVeEQ027j5yqTfOvsi3DKrkvw66E1Wm5PhAdPhm0kKFiY7EB72EpH2z0DrGhMTJ4G7OnxHB+i5kWC9WrDXF9Be7jNYEiWQ+UVKnpNVWJ1A649ZcE+DUGKFEyCrwcZJR1KKmTCozFnof9me5t151UUXxd6obxFvpW87OP0PDWI4+ZgGLOAoIwa+GLvZtE2qGPdRt8XS8bQYAg1Xu6coUONNtG35gbhMNBIVE7FgJtNpF9BkTAN5YcZLReuZLhroeL50JIdGcHh6+EWR2TGD5LHf0z+52vQuVMFQUVKzepGpTX1HGcxXShEEblhASLDrxdMaOmK9POKBRSEzR/ZlnyYkNTtoRGSA5dv+lkUBIEg8z57qs4gEKr7/FOXdSvN/LQafiFO6iykskDnY/aHn7sk1vzSU+VHlcsTG+j5u62schtRRkkOeA9I2VY/sRLYHioypqZKDpQmMeB75fWhe3zFPIe183sRgnP6TW5nKTrP0NTw2qvbnNKgb3/HUPVRwMnxjkAgeZDg1xpvA4rsE8YPSRJqABy4Tpg/pLOJnwMzMTOqnQslypUO/aig8jsDx7EZWsfD0DhQVD73lYh7ix2Mr/v1liWu4g4UvA8Kupab9Qs+W0hFYRP5FBAgcx6rQbO/PIAND68RtOGVgjCm3dojPb5FpSoaki4fRU4+sDLvzASJPayGK6i51hgPD9yma1c98MF/QctSjO4h0hCsKYYQN0TyTvQLpZbyU8iSJmWcJcWZ+6+go296PqH+jKkKrRWfgX3bKN7ZS1c0doOFNiaRF41EzVHHE5Rk8w9Sot0Ypm7VvNd4lbnmrPeJZHdf6qwCBKEWnmchkTCekm1z1fp54HSyY+vT1esZ76jbscnMSBVnLi2KdHU7Gk9RzpDRela0bve6QjBgCe//pdWqwzzlNOA34J9fU+m+B284XWlqyzFNoKqjacm/P5rZCanEmsiYsnB55IjAikdjE9aNa/sW2ptzSEEJVJFnAamUo/YuY6zr55cdp39Wy1XupgFotC0iuW3kgbrKE75Tbq44WCK/7ThQ5fmBf6zpnx99MyiKjseS4O/1/bnaVYKaTN448oHdEeoXOBJrkMrfqGycvKl4C9HcYsmWn2rWiiPcUrygSf6GZi1mGT49vDobz6qUNENZCyy7q4UoCAGu71VG5vfklYAkiCI/Q9CDE38UpBV+k9kpgJIeDdmRyi7NYQGEivgl3nBWHfzQ4usFf++wD/s4Y29jEOltRKnqObm4Mko9C0W9FlC45V5QLoJv4rQsTDuH+0ziOOlYZdsSnymdGpe9C7vGk53xwmt83T5/3uq7iHLjAehgv8TcvNEoSnt6CxJYYwzAMUz7FM16YlXhfyoUSwSKoIMXsRivgmhABPE9euDxk3vEqjurdgJnxKq+1hySNeg7PXu8idVcVpjuVc7+IK+eFk0rbo9j6f8Wi0uo4i7Z7BsvwiVb+TpseHCS23xaFn6ttlErX8thwB8SblhbzITJi4SOGlJszwf9w3zuNSfvnpRitkblsBUcsi2vqXMQKxQC+6z1+4NKK2dbIyO3hbubRAgzaN0l/flFztOs/7vB6klumiMIvjJqJ+RO3a4fDhPjcEZQYYx19HCQcCElCpOQ+dIbZ/3K2fa1ReunIyH8Nd6l4zSaN8jZ/euyCTnjOnaOfHEmtIRRiK2cXknYQXZ4vOzByXjhZAnUcRdKBo83S2yaDdO5BPZPgsFYdBvMmxlJTxz88bqqJuilky69NUiOLeT3taXuIm0pfjE9mwUTnHtROkUti10bBg9hqxwj4wa7xKT3SWGGKQhsyzFNunOZ8+rYaSoScfu/9BuqTUkt6KZdUiHSw2psmRYF34EuheUxiYu2h+28Wxch+cP18553A6PhoMpbVABXuCdE5BEDmSkQLlJ8ztUeV4p5rc5mswHLwbzxGiWeL5otgyce/GjDha3MF52QbwL2M8zlP047lcnpBk2PRf0V5wBV4i6t0hd6DpZWzOum8M3G6DBMdFOUGLX4ExCcSeocP+ejrsVcI1nxcdpMWwpB5x8veC637BgcFPpcquj9+rrbhj7IZjyGGLqzuYGGOmUcLUE1rtlmO9T+Xz9VAyTXcpaKQPO/yw+Om0D5dD7UYS03tyh46QCNqHCfsmFJHmvPpm0+HhINkIKGZCn13I5grEU116R0/fpX03e/kDbgVeg9mcyhkCJ9ZT2iyO6AYhhi64NPgF5wSmYLSdIvlbJOBhAbdZw53wnt3tj9L7vMJ790py8prgyL8/RDtjMLBmy/k7U4TUBVne2AflS5Gpkagt4jqgvW5wctVeD2nzHwKJ+5jyHrJ/eYLee8azX3NfoqbF+vmxhp6DBIVDBnUq5tT1cF3tbdInhraQ0r2p87htuAPl6eGNjODtFWHZfb0xyKVyDpsLOAR6C16d8lLUJHCvjcfIv2dBy1EjpcRwMd/QZKFjtBU2562B9tygA3qguY2JtMbny8SIB4ocnlpnpMsirkd6qKVwon7BD70VkiJZFGLyzhn0SNRBYKh26exzUDwIk6/7WaMhs19zJf65TceH/IDf1DanH5pC0lMREPj6kIQkM91vp/i5p1zFJ0vgz7nZNINSWkTtY92deGk6JK6Xf8cDAIjfddK8e07143WP/zMcGrWdJ0MwhZozK5mgI7FqtDjfJPmVHWkkAQbFkdNznTrreEexJEY+jyftYSLiL7HyVyAyTAMw7BDbgTCZ04ap32w/yDu8TouXYKuGI7b3A40Ox61giSLAhUa6dX7TSh7T5uzvuuhzevRVQ9I1XyI1eJN8UM7J4yij3iGU9nuAyHy7aTKtZ9laJLxJLJfcpaF2GBe1LRXEqUHs7ndo9d7vvm5Pl0pGocomEtPAQsCiFJwxq9E2HJe16tUiBHV53YcsMVlS1V9u179D1k1jy7GgBzRl4ZwuW+r4K7gniO3ocnpA0YDbkTXpXBrRj6HzHmPJ/PtiUIJQlFpyZL6WYjuS0vnaOjHRoFVZxQa0rmfW6aMvPBOPJM/yS+eeXXRis4DdVwUVoAmDiL74uk4+7onHZnYZtss7j/xmsy48AzU2dJnIBtZICYL2zsE6WhJTygWaJkzZ2m8yHsSSQuPNm6VLWBI9I+/wTCjCP+ikt9r16F1G1AbccFwsBDsISadadOZOzZEjJ5VEhi1sbnygdW7R9e7PqBqB8PvXlVJ6YgejI6j3apUxLdqwr9BL3kOVpgLrUBSntbwvqL/FF1p/D3D6J8MljKSu29G0q1gZxC1oXgbBUbcqVrSffKgQ66U13yIxOXq8QXNsNGsL1Y7WQ/Jik0hmnEUWNUJogodKjtDXjKOp/WhHpD/FwydeaDjiM5sU1/UiwP5D94k/exgCKki9RtXYyeWZt5bNjgVeeRvUGndnPoD2eCtrqzdyjUTDByDsx+XEgN06UM5lDP4ifigWRqK1dtmJgz25ngG90Tv85Qt6iRcbJ6l3HfoxG4BcxYRJWGeUASSJk1tdsEnXwJdEk1/irjB6b+YYc54rb7HOfMYI5sIPjGMtyjGG2DXlaycd4a2i9a+KB7+TYv1/WxVQJ9TBGeYfFsTKivIMvNylWHBRn67lqHzCaGsstttKSFg63bLlZ4YgsWgyBJsQIhu79fmqDTaRwFBvhXaYCiem35TvXD58GYEBpZEDZT5//O7Tdgw2WjjfqvTF93INz8DsGEOVn9PoeoMzL7xK3erZDTFW6KmUlgSFES3Q8er1PxpH+cq+oF77J96izcg/uuxgZmV0GdAJAwb0nuGPmfs8yke6SQDr8CwJPXtwf5CaFPOwjeEmEJA4sx4sDlmWNU740u63iQC9rpAooBudTzEPGdLOJ7/GDJMDgrUG51ll6yzVYV24lWiLcI8UY8pCX9ImBxPAXOI2bUGNO6nJ5P3MjhZg5RsVd/24SIxt0evMkQ4HBDMbbUKQnCGyhKDooruJvj0qOHZXFWefQvduKpCnu6IpnX195F/Q9CcuRQ8jU56il9UL+p/ezvIDNnP1C0GaOPSV8+8o+rj+r0x5lypZME3XaJ7kUYX/MZ4Rlu4z/k16vEtcjHTdWSCN4OcZlPPP3w+XTQMwzAM+0wLymB+kDeqdI+DzGV9wR43RzyeWeuK6L+ZyLemezGga2GUOWJxxIvxjTlDBkSOgqimz63YyTVn4f5QoW7mI1e+6r5AV75YlbDQKn2UvrP7maRHstEgJ0UTTLsKTB2NT+M9KOTCtLbs76tCaItLINrYo7wZ1s9LXF2uaQmwhPGTrZsF+aWaZTU3dvm0QPYP0C6ObhsMEfQQF0gBErdlYuIvnf9x9vwJJGkDa4QV2PJcCOfGByH3ZrwCi3rujqfMuCXArALUC3bJGVFDnwywoWzMXH38NHlKq9pGqM0dpHEXgbbUCkqspPGYVnjwK9vOcaA5r9+xMnUUumzwMy0oU4T9TKNGFWX4h/JWWuLGKMup638nJILiV5ZR7saEisot6JGpXTuQIs6/nXQi3sjeUAlKNaCLsBgr+R47nevPdUgw4Crlbdl7ld+bQ0QX3E7vVgJvnvGix0zzb/Fht6OUkiBQaCPCviFpQxSim2Z5DEvucFfmpDQWkQLs2gd9/H2sKmZC7MFG7Q+bW8ajjU425beP+kFvduKqOZnI6B5eNgmFRGm06Agk4irK8ASyaQwuw8Pt7wzzpA2W3rNwQEWtE/oGl8IlfPN4dNKJGoA904sKse2nU7N+F+Q4AId7Z1Vtroh2HUX52Y7d0JJiSeACFHMzycD47YZrvXv0iflB3lg8WuR1dxTghaHWiFQJdcD/DJ7jjuftbFwuwTvxrQ4LRl5OwwNfN4/5mdhuS3Bgh1vz2Zn2vv2ZRkxjcdeQf9k8BZW6DK7lMd90yG4zIbXMAdAtIYFT9Qo6Fms4TD386tk616Dg0/LQRAVpLNSO6qQ+/H1XT2NICNypDVJoWolwg+gLGtI71Tlkbl8Gjs4yfJvAP2N3SXuyh/Kljpflzpt9tEX5DVtgcp7BeSyyk2yOAGW8ZdD2VEi7p7Jr+YYkIBheMXK1hHQr8L4t4xVqHB4/P/o/+ZQWtxyMS6ix7mfA8i2gOFO9WlG5yr3y+wuOXBqIlAe2/ZhG9jcarqfSPQ6ck9cvOnQnp6/2qrFTtPZEMSJusOFBR9xagCm8OJO/DKg4sBdAYbFWNNcrvqQdnH9eWj6BP/0S6a37D8WI2fnB0wtnzWKYiYWE/WPn2i1cSSonR9OXygoT1xlJfyZWliodFzEE2LDEgy9ygZySMFBv0IbSlGBFLPGbBMeKuVW6s2hNc63Vlja+tRHuBWTkXsnfrbmqvkfAIWzf+XbRTCVCsvb2rhMuHMbZeP40u9jN+moC4YBWX9vItuxEPOexUNAcxLbzfA7cfO8V9yfT95eHcTzAa5GiyiPa0yFheNFFl+lL6IkAFoCJdKVSYeR/1e0eLVscf8NrhexEYloQwzAMc+nvnGaL+imHd2bg1SNaHP51RfHKmMFgMZcFdhURpFk0zQmAlpNok5oF2z6iBu8ARk17glZ8Xf5mkrxsFLBjPAPdaNg7IahU4Gw/VpQ0+Rjt/BLVWcaK4lColX9ZuMf0o7tCIvrAcIKXLJlcJR3gohLq30Pa83bcwcmr/GXMt/9Y0h9tzvXnfOaazJjMHfDtOgJvzSthSlkKjaeVnCaZDJUQgem+3UN0Vv7GYgP7ICipF8l171howteteyP9o4Fd66lV/YpLZ3B7N4+lXUPjTR81zKl26Gglndc/I/FRDQmEqZDFPuNJ8nrFVhMcAQZFygxCU7M81OPa4lk9Or1uYnvWYsPNK6cc0mUyCr0u8iPb8W2Nfc+UjDk5nyhutci8h7dPfILeeomjIZYUBRX63EYj0Fgs+X2U9aClklGHyRPqf0S9nDi+rJUTtgivkOM9DJo2OFj4FMh4hPRFzu/D7OeJ6HDdcFigJDOfsmByfrALntIlqNEqNqTmJYMOqd4F3+Cbk67CbWPNOsD9eQpuEzI/xv5C5Wd9vd6yfd2EhwKvpO+dGqpHnALPXDDqSwkd+QXPjZ433vBs71ZlmP1AM5sW/4Iza05NXCWLXVxuaVJngYXc5Y8+6Nj5MnHR1WHtL/b1LTYe59gdZXdVqVRDrapjWAmSjpnVbcDf811wevZniJdi5cIscNjgIZVhZ33igSylxBXNR1Tl0y8Ep1lIBausC+QSh4tpbY3Na22VzSVGbSDkxCc5y+kBsU4I7VjSwNaf9LilqnnATQe4ZnQqQmFbJaRZopE4pqh1Ksc99AU342nYBd0Q+0grm24xOo5Y4X8LXoVIPa71qIDy50dHytZxXE/8nJySFdMEQlCK2o8qcVYDmjGshJQcpeSfgv7yZkhm1H96BERSlq2YwJLIdOcU+5TdeUoYIjqNGrzw56/b+HczeKKXJDigjMWeJ5izqW0fsPFNKgQZs8ZJjxjpVEYswbjs9xMk8M22OsHVQHn6LampDGYQvgWBGx8v4leY9N+SmtCvoC7wAAjyAng0HgSSL/eur+5yRuB7dJM2/l6D7maSIdWMlWyikTkFNcES0HIFguCZN/nBpd+4o44ePqXkgt6fEceCZ1pCVBIDoh+Y2w3Tzvzg5OYX33h8j6kiEsE/IkDzGtXoG/pEkiuKpJQOkAS+1FHEVvfV+tMp6Pjt9XxpWcuZelC+Rp5pKpfpjWXSy91GIF+uvskTK1DnChMnyu8a/mxiwcSkZKXfCi7MIKbzaG4MwmFYEUSElLbZbJ/r+3TvjXZfAJGjyjkeS+kShq9RzwcjKZHCJQ+2Zw89mY/DSZQ38sDiPGS5cWhDXTK/VU0ZnqR+xTr5yzAMofbHlHrppE7GlHBJp5jN+H1xqgbK5HDppk7HZHMZoRbOOHoCpegJsz7coWZNO3iSr6RKO3BCraxOe3QRpXo0BKLyAidm8Aq3zDJnuCc3PuBMofyDpyQ4YSIpk+AblsYj3qiVK/zIHG7wE9ZZIATUxBOUjUpF6AjIjDAQsiRCwa3JmhIalS1lYofsKFt2WVrKnpXJIzazVnnGTmmRIy7SZulxDQ8m7zhjo/KJG9lCX7gJj1kyaaAz+SFVnlQuqDteoEvqgZcsU+qCg8Fx2jHh3wd15BJv1A2X2X9Sj/zF/6eecI0PpIZv9W+ULTf4C9aRs+wvWU/5Zb4jjwzZvZJ31lt9pC6YZn/FOlCo+6QY+M5ovMp8q5syD3xmd80sPDi8DnRRpsImh9C4CttnAOVq/HmCV0DSrxxujRX4mDekOW/J5Y1Qly3xM/zfwHsKOUyN+0XJwSi3pZja96czqGdoFXTp8AkX5eaUhsNbmS0N1n2r3y2N1gl1AzGY39ndMsUPee25bjhRv/HH/KeuCk6T7mSre777l3Y7P+GalwcXLd7C680jMf4F1Xb+GxleDt/um5zXAQAAotvcVpSyEOtow1iKiW5zCpSyQCPaNBBwmwJqLgcjTYyytfeK019NfAoBO4mQjRBlOwGbA4boXtsjicIyeN+gDYHf+Hd5JX4GtaORnlqOF7M0gdJuI5/Yy6ivomo8bvg3VrydZNwnX4velhMUUxFDn3wD41vR9WAVP4D/mitcv/Rg3X8AqrmBsB2Aaz4B33MD19sebesd/LsQCI6sQbSpxNpKcldL/s+9Lms/m30Oc2fDp5DHxedHTp5PDy2W/8VW3iY3/pPlqX0jAE9TTXJMt/9TqlubXblp7spjG96ruy9P9GMoFsLvvH+oNr839tVx+L0wPlYn/Iuqw4FfWsVTvblBTwfOMtp5Oi6MeolO74+f0CCz9eYd0bOK4c9Mt+HkugigjwA6Q3CtETgMw7kb9ar/MWz46emyKyDxDRAUaguAKSAkA+oTnzn8zDGfKXvSQktkqSZcI8O4BMYC4i0Zs3G48QEiVYbxyzd8qVnSeeRzUwfrcBftQpznzZMXU5Lbai3j21U9jy8OydyNy33aWMXeSTmvtkiu3B1trtJI8eZdNc+aJXfu+dyFvXWsvF6YzCvMk3/+kdyztWWc+VbPf6EyBNKogmOdCjYNKthUquDUk+rNCqr30UX1b+DMkgcPfO7Si3WUjheaeZl58uoPye0sLeOXT/X8x4DCcr8KX9sqPO1N8QZzi+TG5Cnpf8ot2jNkMmZJnMot9LQ5ZCzxeSWf+3FVJz+erGOBL465hXBhnHfj4q+LefLXxmqeI7lHJ2Xy6MEyrtUWuWsv6nl3Rxe148UuqTXSvIzLvXtXJe/+WMU9a5a7t1TOu+fjt0+L5Le99TxzTHNrrxemydqvFP8V5rn/tqp5/0gcvJklB2vLeXM+d+5bnZybWH9B8il/HUgWC0QZo91hSZSrorPikwm6oDF4JkmjUv9i6liW5mVpfx7557ft19eueZa8JkEZWXdYEs1V0brjkwm5oNF7IEljqY70ueWRjVeE1zQfFmq7fMHFrR5qZoE7ZqHIMkvKd//DZzoxGKuQvksvTT1gWje9jZZXwIx1ffXd5jOmbGDzrS73jfeCFb9kSai4gkXMPFwYP03DJuLoZmJD6bImcsF5C3NCVVCes9fw6VyW4HLzWNut+lb3tq+9d95w96k9kfA9YZmZN/8Gf+kEka/VAP8eJHvpjqN8X9iXiW/zBRvZ770qHMSHf+ll8iYV+bc6wxdFfd9wwjgxUSUMuKWpbpZgw+3Y2R1bxfsmFueYY0cg6Hh316KAwgkcmhP+fRiqfPVQ/LJoQBGlgg6GGQxwpoIpQblFOlzmACfmmV/MiGa5pUp02XnmiZz9HxAFACCAInMWjiibvBGcyBYsObmslI/6vLJTDWxVQsG3gR+mx49tow39HaDHKyck0KoTUgCtBA0OTSKE6ndCkUn86qzF++iFeQWn5BNckbGSwuxPU4cYTnlABpyxhUZS6KCCWgUCcOKrWwC7BcZ/W4njo54lQfXZ6/iYWBWELTHW/9JaJHGt0s1GpgNi0XoVYLNFHZ8Du75n765qxP6h5+/P5VuY9mvVKx76T7nIEJRW2x3d61Lz8EXduvpFkQjx2UO8Y4BK6jThMqTeWfTB9IbQ29NQTLd7hsfqPebPugkGxEH/vyq+x98s2xizOYynpIM1KZ5DffSGELSExLazuMfp0xh6v6MrBvVVJ6emZ+lfV3QI1G8hfwEZ90fPlr463KJJr2uCWvU46umSWLbZCPsnDafORsxmEcdfcbmnLPXtamX0Qf43fXREf2e1n+kku3AmC/Z+jg2qKazU860oEjZ1BSG2i+XDWS4mMMfnR8Macxo+F/w7ngls34SQxG05x/4YnL69y2wO9cacLwi+7lwByaQq66ioB8gSFb96tGwMzpojuq+f8cfChoQe5R+teiKHL5XIuX/7bRBNIz+s+FKX8SNxqTNSg57RMlbJA4ahCtn/hG37IOGP7c2ERQwpDXqL1uNBfkaMCeoGecK8dhvUJ4gzOGdUILHDiGhTVsmK0aAOeHKrK+a9e1HvEK+wRVNYvCKVQu/RPiGscAqoO8izKceIeoFIhnNr0rrZkTpDn6JdcC+nDmNEXUIeDT2hvkHCDtvExMKOlBF9a2rqj2zJd8L4Rl0Z0ql57RaoV0NcxLlH6UgsDId2ySq5w9ijPhryoBx496gvRvwAW2OKS9iRaoD+ifYF4Q84zVH3hhzU7FiingyRlpWOKdUpI3UL/QLtB3eSpxhvqGbIPqNXqGEkvMI2CotTpJygP6O943G6uIJxBnVryFNWvbtQn424Cc5T1AdD4k8YK7RzxOQDY4OaV55cvGLu3Y06KvEBmzOxOEOqgH5EG4ww4ySoVZHnaHasUM+KSA/nrSnVqx2pe+iXaEVnyClgfKAuFHmM6DPUSUn4HbZvYRFI2aDvTJQelnyPGL9Q14p0g1q7JepNEdfg/ImaFImPGCXaVadLNown1KLIw8DG+y3qqxJfYNtLXMqMVAX6F9o/I3yH0xL1oMhhUI4e9bgjkjjoH29KddyROkH/QTuZIXnE+IOqHdm36B7VMwlXsL0Ji2SkHKE/or2afSquYFyjbnbkqTX3bqE+ZeJGOF+gkpH4D4wF2k2nS24w7lGHLALz3v2o90x8B9vKFBafkaqD/o721whHONWou4w8T8yOM9RLRmSK87No3WaknqKfQ/vdmXIaMf6jLjPyOEFfo75lEn7DdqZiASlBV5PGYzblNMXIqCtIF8yOc9QrxIHzEQWJMECbrKySW4wW9RHyEMx711BfIN5g25jCElakMugD2qiEDqeIuoccgtkxoJ4gohz0zx9J9TwjtUIv0L7VneQCo0c1yL5HD6gBCStsH8LiIGWG3qG9qcfp1xWMKeoW8tSr3p2ozxCX4XyJ+gCJO4yEdqZWyQlji5o7h5sn5r17UEcjPmIrTWFxGaki+gvahxIKJ4daDXluzI416tkQGeC8M2mtGakH6Fdov1bu5ZQwPlEXhjw26HPUyUj4A7ZfJhZRpGyh35kVHuQnYVygrg3pCvParVFvhrgWzl+oyZD4CqNCu15ZJfcYz6jFkIfCgfc/qK9G/ATbk8Slykg1Qf+H9l8JP+G0Qj0Ycul9yFgHWMNremxxlm7KwCxCRsovQ166Kf+w0lBD/lJTqm7K87LCDJSYutTq/CdJGdFypoLyKsi3bsqFmtMyWfkq91TW/OXLgZfn3apO6Ka88qVTjeWHMWfJkjlfDvyqTpf7bso77zmlZCifwrx1U274spKEueFt87iR8U9WRvQ9os1jNvyksrHVETTkMH2lWlBoTUqIWHEgZY6RRqDP0aEjHdDYHg01sTUCKSBIDOryaHJH5YDG95gQR/L4Rcp5rK89MMhxgJEqciTCp9lcMVB5Ve1fQG4E89+pUzCkHuKD8La+QaOnJk8tNsnT7WsxfoBz70l7LRlsMXLL+GNNi+EEHn4NxHBreh3Z8iV5IDDV7AGszQpABfQlAEjLLSSnHlyJjbd5oeRMPbYzcKyNH5D/gfRzr2S8DpAi/WAcqxduQDmHuwCixS5+3aZfDARTCdqxrW3s6PLQtOLfKLUrgR5F8D5n92bMLwOSjp0UTqRRD1sAkDFGfPKXxkrk7lsyXntI/ju49rE6OjEv9yEcf9w16hR/oSsPv62BOuKv5tfu28/DwypFo0EXl8cmf+cxfWes3zlI/4Zr+jdg/Rc8vf7eoau/F8ifhldnbfUGlSU9xoHsdQ/JoyNc0eFigYgLXf4f+fV23DbRKPNpKW0U/G0w7zi8FOWmewz6vIm+RbG5fax/d4dt33SIeF4H1kD1QU73ug7zuoi4f0/L+5/ji5ht+I92RZQP6+x4OudkGjcds8/y9XtJt49Ylk16NqIxFvIi23TOH7cv0T2GbOXzyBY5jc6AkCUSNoKKCYMH85zXFM++x5xC8BFeDtaKxTNjIy7YtcvvLpzlVEh0WUwOgwp0LL4yayLH4dMiJBAW6E88p6mw3t0pOoRvTqGcvkVvozezvrn87TuSRWIoosK2feagcdUBci9Rn8Wrl+OzDKhciGukY4np9U2cxi26Fl9fO37GDmscWsadjPo0izrK8+jn2B64QhL2s5NXe3SOyoffPqk/W9RcHh1roo70wh5naJGVGKy2fOknrct0Pe46n2LHoNE7NStZ9i2nsOZnOs5Fh3phhO4iynLlUqHfWIO8PqqhzCN0wLMiLISdXEIfmB3dTjpwbA430MHerRklJdAxFTGM+Jrt5KYOkrKUGNGMbyAGG9IZ19L7F2ogQi5gOuO60zKr0ZvqVmvCJZ4+WIuEIGwY+nGfNMWgfxU61J3RRx+skVAJakl5MJuxRGLIe6/qzX9uhzmC9NtrMWT6b0kzaGmTDXuqGUr/w+epWFCLXpAKWsH4RrOmvfzT18jaq4SPcLRew6uo1wM9fEh9suu8WsSbUdGXx21akIvIyrnz8SwFH+hIGs1xURGIo+rN54xZdr1LhlqWbumHAGuscbttFikV61FKgrDaEMLhAw0096CqjQTKAfBsrnQylmRBtayBq/mvM+XbPKjXvcv0NAnL0qF+J9pdpUWlNUbCjE5cqTUUliSYv2yRlP0UUGYaTge08ZwR1wR1kbGLa0DdiXfPkiEZt2lR24uS3rRHrizzQ7ec2kSjifh3U57D2tihY0hIudA7O8uMsvbDxFA8Vck2NaT7zq3odlNOl4/I1JOyskYIy4DM8/RuAsHhqnhNTEEYm9rDwFnuTttHW0TbVsY0lZIs0H8CSDvtat/0ES5wJEVU07oQ0k2oVd+WPpcNCEpYuZxa4tD1BnLQR8paqrYHYVHGazvrChhXIGmPvwSVjg5dMkDmfAVGltboqqxK1Js0TBH5wEXCXnra6Lv1Az6fi5YFxcYIGKQNJ2hy0EHZzy4sUXtZokmP/7bHRmHvFs6PKwSf73R8l1KzmUhsxqYMVZiSHsGydg1xOt/u3WgKSNJ2zuLdf3y72QTV+qXtUq3ZWKbevlU6Pi5G+yumh9bJ63ouTsXAbITa6HB2UPqCfM73B4CncI9c5Fqx6U/rrTf4Lv5BXUfIR4Vh+0JKqJ5hSJZAosoOe/qpS2scXCpv3yIo4+drvh11ILVjtjLUpZyQAHxWWoGkCWVCUxZtogNEDHmgTxcjSc0ANXNA8qr/VoNAfKaMBxvWEmh+/ZK38xkDY1FyqKdqUk3fvohNvdXfvePXkunGBc3sBZqmzT4uWSGubWhf37bHwhLpFESsvCzFtBFwaiKkFOjcYAxLFUh3OZbH8IYg1hUSxU5GRh5S44xQvkafw0FL/GEhYp6iJC/4Zfbpm+nwYaNf+6sPZYdptCJ0n+tF3+D4gH8ldwX8QNP6IWL4HUe23yQNVSQHD7tqZ3Ubxw5s/yTumCOD1S5b7pQng3ew1OK9HNVoT6tNOuT1ry7w/wpllJgD1o1bZKxSD0BeFgACpBh+u/af4E170qKY/Nj3PkKOnMWxGo4ts+L5GLpbgh6L1diVIeKwBlKrdNk1h415gGRtdjwYlKSzr5n5UPk+bPbLNiCa5oCkVR11lmoiyw+kxo2J6DKPOlpwrAgdO1m3lSbQRJLDe0ct2KJ17TCVsGz0Ygi0tNthrDrNU9boNP4Yi6OCggeqWxn4rpviUXCAQvRuzhIQdkci0EhxdxfAPJrw5uDaxNZOjL9H4oZTlWJGNAMWYRANMNhT8BYqVxWformrdOTs1AnTbAYpTKyGVhQ4ztx2YwTHGYBSsUZCE9ZAZS36iMNMSwZahpg9ixkxhni9yZXlvUmPn2573UilzO8Utlt56fiulbUNUQwofFxLFMiVNQ5rFIlU67UvbD1tiIiJ1QgbTWXIAdxnJBR5BP7odbTV3OO4+YlsDFrytnpERg7ilxbX3Yg44ZIg5kiWOGx/l2ysTCxCwngOTXYTWPHFF5jrKPProH6nMSWceGCK/saNkWXZHGtORPos/nzCYuXlju+PYdosYLSHmZUEIJ0q8guV0UY9pc2p6i47AxZ61ZmmKI+BSREhlLsrMJcCb30LiARaPp5X24hXg4Bdp6iMMOwNGJB0kfEKvwoWhoDDY5EGSLcGaQt9ZFBjwiZqtWGJefIYYGAMOFu87JEEAQr+Yl10NbQoj1gSElcGX8M1CcgJVSxZC99WauP779Hna/1bE2A6hvjfg2a+UAjAOkPXrHyjiluLF7zDQ6dMYjX44aC4FBIsl0uerCJr3WUkw7GAespxQEl0+pFps/HMyRXA/OfHTv914to2Z0Fl+rdpUlxJ71SlSgHGaYobRjcHMIzuKrIORIGIfOWK+FcMappvpPaMfKVQDSYd57GA8VHEhr7F5M/uCWKMDsGGBi1qW5LOUKjMvJHpkinY6fSeXnFT7cBkW6QboFs4L05BuWHHkGx5dDDK8SZIybYAxM/diGxD9hD5bRSZwoi9y3hlIBq9I538M3XChBysNmkfYlT28kA7dNET/qEA4rBY2E1hT75dPNrdAN/JIt9aTAc91dSC5aPnRpxSPNp17BZ2W/ATSsnXTL1HQIlqq4OCE5RaVf7j6X9/vtXN3+G/fwZYDXCRJ+ZTdWsiButW24fE09HJLOi19m3FBVurN1vf/cff4BJ+jsGuPWO4Sk1uPlcjp1ia5aY4wgoQxe1EwTE6T6+ELQCTi5ZsWarj57jxAkmzoa+27bDSdyGbCTiXsK4Go7tZvERz9e2Vh3NxaJYzV/lutKqGOmOac7WG8l4nIOnVyFFUuPyZt0WbXFjd4kC6YuSuHv79S6vOrUV5Gnk7FglJnIY0wkhlzoYiU5HFtgT60dVxlDVeVWnbvduSaXfrp7v0W6MUhM01LPcGETs1iKj89374kHsY1e+3z79gRg7L+uVIf8iBaw3+9umPWaSr/O+731hSPLh5w9wiuu4Oi3s31tm55q5J4IODBKHmfOU8mvd3fVpsDJ6tmg+PkT8Vxv9DGyx0hCJJOu1GWwL6aX9dJY8jOigNhNCv/HI0w6FCW3JukEO1+uzz5tPsBRFM83+yKK1ccODdOOl3fZ21reL+KYQqLjB2Bi6FL8z26dLsYPm+MLN3EwGxplxDEtcxA0EMdcLK9nCDlXKLa4bnlqFRx+vPX9Xf8/t1FF5cRLhuOXUbFrQA90lw8rbgy6k1LSgiS93esgDhQ7e9KQQkOxaHBKNseP+dQOr3rin4THVdrsel8jKr7ugeUiu1WW9iH0yxU6qqPChXjzb+7mC2vzw8PtiA9lJNBeFJir4inLiCmBaXDyOYkyrLTfCjFL4iSJVtnEPh43Xx8qD7w7SO298QHzPvVG1VNuTNfz/1qbbcMkH1qBXLzbEfQLzSzbGDL8m+TUkADSWkhxRQte7RbMnjkaM2CKv1rsyaeKFjiwMtt18xMRxn6xTZcTbc7E4Q2nTQ3sQ38zyZ09B1dkCkafCFbYy5Sjl5ViNlAcKcxUiA7KxRF14Qh0G6r4MuvZkoWmJ9ZLtTbIXYPVPV2N1ARtEIOuZAuGWvGWBsG3eIf220Lqe6yrFVDkmtBGSJWnG15rgu8t5CokJTs0x6uVStH0rRihx2lHwhpwMQXytNBKc7FGRzGBEzN22zU2y0jbnmTUYedEaBs5rgETJCv+HCFAa7T9Sh2eiiJLHDCzfZ0WyAMG2cmgGbiyHqrKlOqLc+FG6fzL4n48DvheFUgvKIzkYHVkd4BpAWjgcH6jbdG1SbeeIn3LZKM73JCbqCLdOieZggJHe25ktOf6/cr8gf7cJCUJql318mSQggOzm6xbou7by/irvzPf4MPvtWFNs0IAa31CNDLaqtFGVVJKObS/kUIvWLbOTUN8oQ0omYKq9cLG0w28V0fygj6j0/i74nRilD4RYcqgIoVZmOd1s3P6Vxx7UPU1vyNCsAcJrk12BxBrbqg6d0GMelBVkWdkJ9ix72j8BrafJs5L3iEkbFm12YKPq5cYEqJtp9FS8aFK/7j6Rsq+NtqbZpSHTM+/0konixYOOhdLBKzWmhKvP3i4lEr1wrT+MSDeASkMLyXoTXirzmAZ9i6rV4DuMpqHrliBYbfZWAJWVLG6ZGF8+E1alOvuCPEldEQseUnuKUi+ZnauMORVGlLtVKL2BQkWdKiobF1kNeu9xH8UIQH6kBYtLyCBZNLAx+aHq/dXktwftYK8/gisIQMU6bti8jJvzpM0+vELgwf1ULidqKdw6iaxS2Ht1YVb6xdQtnQ7tUXDifDzR6sSkRUfiswK4JJU6NoQKxefKaBCv69JeX48xHR6K8kZivVdwGRubUNq0IURsXDfpJKdutT370ZIdSR/qz0Ss+ifPK0afpMvFX4HgS49KRk+HkyqcOS65AAWuPoIHmTjF6s1K72glNiHCaNdftj8Po1UGDgrp4J7NmCU8AlkS/ES+4mOV85nhG5cpDbeQaQCCuNNIYs4FFhoSsvaW6bgck+HedVXUvKK53ZzcU8IRnWOi1mh01LyXYTvmUdtcNhLjhA0QIq2q1auW2DqUiMf7KaHNM26Rc2Utih5DS9+jxVp0ERs0w6hiGjNgZImckdLbJBXq4B36FSNDdCOtaOJ9MtQDxw9N+KXFf4eGqUp2kOdNH0UNlfkxaWR5YLCJw4qI+OCwrj9XtqFUEpYDUlRj4yChW93hkBSNmUWXFq93x8/vM9KIJnVQuGr8IiPcJCsyhOQ8x5hjctnOo27/OLg3DcLIR7YXcMe6r54k24r6R9+PxfNyzVuz59zb9q5YNA0j6F+lax4tCm5h9e2Npp/leo/Wp+/R8WUgIt68OJmTS9+6DUSCy+ra4Y2bpjChMxj4Og7Mr1KZobj9j4gUb9FdXwXw+2wJJh8lxF1ZRSTCGW/PmRhHbGOchx879vFcg4tJ6Zg5UsTYK0R30JUv3PckPnkk5EcHLlUrrANWt9IUEz4BsSaIP5+EFQZqkg3Vzt4jBZUU17luxjNFGQzz66rSa0PPbw7uveW87ApzlPtXlUlSJ2OuKPrzWhzDqgPOBpvsIV5d6qOwgZt5Zv7+yHCu/18KpJm0HV6HgOoS/fFlJA1IZMA3j1CHY0liMjKQM9BHDB0VpwyAyE0COcj4/QiM+3SB/17xAvy/78owrmBuPFL7gt60VjwPc4pyD8LmVIllCFuVYTNUx4i4rHQtwaBHcvHRq7DYqJHHZ/Co3X+yhWp5Zkx18D3Nwla15q9V17oA6Cl8zfEFJobLzp+gW+eFrbC9232+j18HHCMEDRxM/W18r/TN4Qm0aHcri8vtGoMr0Ldh3cFiB7/ZuqFpk3MZ24r2xRjxL8lK/xXSbT5VcvdY4PbGEovDW0jpGgeO8jyjT+8WXRfIuX77ufMn4hxerFJqkUxoxesvhY04UAgy0gh2LX5f9aCuBXbVIyKxYSb7gGmEfnmD613P/a7OKESMLkLfD2Y4RJWLEf488Y6uRMeq/oZMxZFaC/O8cMkaUiBFtvlLMqaLoe3L/0MgtgFBMqRMuf8BZPznZPdfSjEoxQ9HwME+ZFvAc6cFY2Ij/UDiTxA9YgRAteo0xqlSMYrZJhjfSKLt+VmojvZBFtPJZhAxVqh7KP1XSiNZ0nhsgqfiw+QIZh/NS3tLRgHeNKOjRB+NzQ9dasswOrfnL2XO7zaNLbZTYkZi8XSN0YY1LQicZlOZKcP27vKrWmnprkh6FqCBOQEg7eWARhLQwuYDAevvR5LD0QRPBoJHC32nMZrpewxIxKxCm7zHye//V8CDaPhEAGgBS9hazJjc54uo6HQIyQKDMAwYdfs7aO54tGXKAJ3mDgGwH4qm8+7kf0pVrx86mfORThm5oQoJmUlzrMgllFLxax8G+wZGBKWXFGhdpmb0gv0LKZsx9trZ/lWz7VYoPKoVK0NNmZuhsm4L70O16myS3ipSCQhSIxBISiMfzKXAR8IpC23EaJ+/9zV0ZlfZYMW2n9SA7rDwovMJzreoaf8cg1t6q2BQUspnk4+kuXy9Tt93Zjgzlf4vIMuZKvESDw2qZJoFNV7804p4qed54/cjYPrJEQu3qJO+TcPLXUMgo8DmABbnHyzb3gUJ5fYFXYZe4FCtmv837rbk3s74z1Nq8d2U1oJx6XqOh+kb6etO8UQs4GmiKoV0SFM6OzdGvhT9d2qZlhaPJSRMhN1xoqHjebItXnLGxivPaZ9vOZUU4MrSN1+U4tLMMwfl9Nsg9l2M/ayrVKZwOPOO4gffU9W5xlTrDySS7g+IYC9K+ElYLaEWKT0LBCO3XZ+Xp90mY2+jiKl4rvGu8EUD/RJPhZOyAtghBP51bAIq/OSoK84/Wz94yMxAxnT/O0DVsxvSgowyqjI4Tp4KxHrTGwDh7vdOysI9dfcQGps1g5s9p8QMrvXWTz2kHaUY1BvKF6eU4IKJypQnoV8ic0HkksdjToQczuR1Ud5MRv2nrs5f9UPVIGfup9a6U21160cxKYdaHn8/tYKEIA/MkVDUPL+TocZoy42KIPWQMUQxkwNPogFSaEyRTy8Yn8fEVzyUBkrkZFzq23EQZWhnPntgReu9hdvCh5S4PWOAmsXZWdaw1Upz9LrIJl7HqRF/d5YUqt29QsnigAAXqnBgujRw0INtmxTnWg5p4tUAxSyUHkWCLqTEHHK5J7ngUAGMHiEd27T966CGTCC8YPMQVLuSAKgX96pyx7oCTRIt5BXV0BcXXhCAXk2/PLX+jB5Ug62xdnVG+fD0K5tDjlhNoKrkS4GI0flyblZocr8VHty0dTM31OQF5xOL3nALUbVDJYviHH3NdnHiqVX8RydObxFlFnUubEymtys6op4MUyGKeyfWUqYcRdYMdeiTj2tAEarLTczriVQ13QaK/9+mNZ+gpaVEd1xgED2FUcz6VGD6ks1dVInh3JHe0nMMR8NgSBpLuZ9sezdcm7GPyd6RpMdXil6YaWfpcA6uLnNYd0MK2IvBCx70N1nHPdFRcasHFTdc8cToUqRNPC7/eQ54QN9c/KS07+IV4xckOfQNYEdRCk7Bc5nOSQ7n/IRTAZUIl9gqDn8L1F+PZUUi8Ro1sZBWiFmE8pKqAdtwrgGOPWSyZc3pNt6dafYdDYlQx+Yo7YmGNokbtRk01Xw3SOoEaGaiZc01I1n1GNurWMIYL445Qz8eHXsHbMjpcglVLoS13knroh7Rhgan5Ym4OHWcExKVixeQysHZGZUHJDyeOOpjeHhVIPiRBkagPS6WaahCbLRmzKuG4BtHzYfs4hl1y+hS2HdtZU99l/CKqSyMReyWDnlv0WC1FIIOQ6mskMEw4Ek4NqjwEVVisB255P48JoRlHo0yywL55FYGLbr2NcbUUeyQQlbQrJ0iYo1DYy48L5CeBZTpiyp20ka/2xt9autPxoZhvSqkqwdQ3q0C1zYTiP0JGMOFNOYE7oYFG9TGZEymaCSSTAHCRvQkm1EIJunLQ9uRzG8z7LVZk98yU2RjS5RFpHMjWJoH+nqppHM7HSHzIs6rffQ0aAWRamvQKJTwIyfgj+gKuRXVXDROnT8ymBS+4OovCb/2FWW5ImV8uhug51UZVCDulXun4gH6sPt0QxdlUBTs5tXXY30w1I5bir4p2fpgtGbkge+t6YIpZctr+OXzs7+Psm17JXALR0gfJ5PTvYkHExQWAfGcVygfeEzfNjaoxfUSVJSA2CWdN78TSKoZFKSQyVybk919kmjY8lTpL7PouyAVxbhf5AEyFzF59RIuvjM8cMInjwsP06orgH0z2fEkj+iWwADHpiOGxnI1vfWzCAKZnGjY2RTybEpoDLwQx+mBh1ue6LamA0bDj9xgTPpRVIyJCRmspnQlGFmlU85nUeJUEZBHf4DM7qLVbt3Ghio9cNS1aMLqn/Vi7nfrBZ/amkrpUWgkAz1hPSVdvs04d2ZVZlWJhdIYnKvHWJSWmgs/N0nhKK1XgBVMIfEKaLW4XKdd+CayXaeXFSLV/6Xr1pR05KeOeXn9RHd/m2dS3NlaWqbmdDgZXn2VVESJKRlGrmRFj0QQqGSHLzpP5dE1bP1RH4YW+fe+oy/qhjFpBT5YRsLBVYNriU0qWjLTxMVcukgRV5iKM76lUZK4xr0xpBgfQjdipseonMQJetQeMBbYdme7bRWgf/Y+YAclextSwU8wI8g7Xoh3qJuAULE3S2vdCDSIV73yuo9eYXL+RPrHQitizkJOtEJuDx2bdB9MTJCWvS7f0k+uZtFmEzOs0Q0rJEz09Q343kxlLPKEzDQ4ToAGhoK1k2o7mQPpn63llzDdBQxepomjW1FBLaV1I7wcJObhV64UlAIUBmu0qrDMrWg1JxSnOo2NNETuAyoBLOvBjK3MT8kbl8T0Z0xSlMyCJtNpmeJY9tEThRfwLtQFoQt4tWYmH9ReS6HEwi7qoqjPo45WCVmUZs5jZkpU2nlRyw6fSVjZi/BQAS7pCpRaJ/0S35w03WqAqQu6hRDcpmrNdVFQWwmlpthi9KUF/dfVL0QRlkNhOl0khq+BKLA47oDph+UQ9iUYrkkHzV19qgOBJN9CMTQ34qFisyK6mw1B/9NpA8DRilEFqDrU/dUHKI2JibEkzjUberUdTNXwS7Uf+12RgIu+2BJyw1pq85Ij/cTeKMGcs+s75uoja28y/smDNaI890idqPhrLVYc3SayVSQ0fb4XF+3oxBCrveHqMgE1KjNr8jIkG85WdkxO5r5zwWjdf50ly2AirJOFkSWoWJu6nYMt0jeEM9sEK7GuivQBaHt1NNMinRg8LkX5fPe0ymckxyF7iH/w5oHfkfPJIrOkrdPi2SCZkWPLRj8BDqpHpftwCuiQjP/7wYK8R3V/wH+Xq54BLL5XUQ64DmB7E9/aaPyqFziKY18ldZ16euorZnq7V4qmtsKpg4nwh6res9iLKwzCYCd+0ypgQxF/7eZHHjpPbYfg+h+595WTZGQSHe5oqHr9Fx8Osxq/fcbXI4Yb+DUeZYyozDeDhFpwZ5r+hZ023n+1M7+mEJQPhYNcHS4dRfcz0NubOJHIhdukAA0TkNAzEcYDkh3hd1MX71rkXeKr8gcFt1/Fd0KGGg5DnApLNlQNJ+iqwA5FV1aofiEoLsOy2ZMjW1PUkv614pM6c46hNfGZW5fe9A6tItNABnO0WwrgT3NOGHc9MC+zuV9DB4yJ7+2Xev/Ym1VOE4BmtsA1t5Dz/j0IpeVCcPrmGnhd8o9B1PQzhAcImNbdC/aHecfssnerYUl3Jwvn8F2SA330DUSDcQDaLo62CN8YlXhhpuOnASLY1VlNk9DTHHdmzalyzHcc3/sQPNYKCkoRQ5ciXbiqYcHCZ3sUQT6FDcZtKG6EXi4cBgkahvL3WodkgQJU+CAEfCjZrUbkqbnDjebitXJyA+5wPbZrfNuZuHi1gu4uDpy2nVjNkKddaGR15JBNS/ckNuqOTAziSUNCTdajmpmNwdL3ku11jokEY4keq15w2iMWNAuKESYFIIq/C75ia1MGvDjdJr9Y3Wb06Hal4RX6H7dsm9qkPKo53KO5A4zaO6GPIi/oumndggrwGXCEBTQzlj5CPqDlX4H/RMDtY6dnnscF43I4SeVH4NwUCWpR4Toeh8UObuTrhsnvVzYeK5YxWBFIv7QoQTZPRG0fT7PFp5/SuomDxNbNxm9H5ulX9EDkUCV79Dx9w4YDHF9mygWoW1OS+sV/P+dDadcP/PjipJE/0x9xx14vYKo9tLmK4SeX8VV0ZM3zE3OxiKxW3/E8IrMh72/r7XhfKPj7n8w0TB5xpvWjZ4dfD7RdiEZoAz/+kjJ12nyOpKA/Pd2Lc1Xe2HhF/aQiPo3j+q2Dc0feri5dXUw4pTnsYcL6uEbjuZDy/pjgFBwr9xBbks/z6eEPsvDtSd2kkfNxDOtcxvGDKK7k7kJ+g//zKY7571uY1hEe0Zo00vbtYS317M7IVVruZSaanQBZmeHjOJynjD9CdUnTQy6KysnUUvD5zR3Q9SGdu132+j2fkCZwvTOOHvsubHnVpL2O3QREcHEf3Tw+YwA4ls4HEx3qfPH/Vw3l+FrhesZrVFxv4C5GNLssdxektni9t+SCTFgM6sIGHqM5cZxp//lyHr/9Dt6MHJL1BoieSoeAW2gKEaepfo4fdHtVu8wvVgUdU8nUDq6AfKOzLWe8x/tItU25sTdMZn07GBqRUf3fKqRnQPnY7gU79WN7NnDogRvEMruRz5OnklNjC76GdXQpnHX8FyTpnj3+V1FMxov1GAnupq+zXOZZ8O8q2uRGFi/GKB/SyB/SSz6EcAvQgzIRiKId4SwCy2bpO2IJaj3z9HWhsxWU/EJyv+L6zagFgrg/ZCaCbGWO1vWOVGFlCcQLA5CZQ0Mr2G8eNnqzz3NgKnJecuRlLQG+QM3X0YQTWzjxhuFMk9kvl/LVSEnRAOeDowwDMijlguBNxmFKOlwrT5KCznTp9IZiA9sU8+Ih2UDfRMgD7a+NU97Wg4U7C3W+GS0dNTAFU6T6qDWzbagWkYU8h4AD5R7iBupeYUcYu4/AH6HN4IOWjSM2P3dgnFZ94hgG3W8z/up7jvudLsbnU6tbbG+icyJ1fwgNfU5lynGLrvQFrBGXog7IdcOwXAz+M7MO7wSUKyNn4G80XHqsDKJ8OIQoHiMHxPEEUDoloBnCrDqB9XzriKCRa1h3xX3jp55GOPWYMWm3Z9DSauiEW2+VG00SlXlizJIerNSSZUSXisHa9IJ2fjp4OnjLOYgkYhdyU/AvBS1QHe87R5VnvGDAjKcTObASYkx78Gnlp10/nKLubOKSI0dOYF4YcP+xoIZwxoDdU9+MFOwnRRFOgbeTEskiVzm7D1Yx5tdh4lVhWkkNBL6sGOyd33G7y+fF9bcM0qDg8bFBNnhxkYxsn4y2cHhHE3UmS8LxNK/W/E4evghIqBVAouaaCE2wfagAJTfYSffOn8YQMPZVwd0Jl29TE7TlFEMYTpkrGe4MQzxraYgj8+6NpdeiotZcdg3ExUQZzg6jskpk/OEOmfXfU3CBfq0d4yRsNTxUxcxaKpNt3U4lQFGehSqEfKbzwQ/Dda3JhhcCnC2WnUb2b07OLAEoddc3umkHVHKNcfOoDQqZxtF2qHsv4766OXY7iOJyfmeWFzcjE6xVv3i9moU9o2TmIdJH1+WxK9mwHBwiI2x1i9LkF1YcpvyDGZ07G8waDCMf3PqwKEmQEbCxLi5JTWM9rExWX8bCjqAHzB+wQDspb50A1xPI5VhqZCtnpxSllsjGBMFA+jobbXkc883cTufPHvFihRsKWjr5GzEl5rFBsUhyjqb2jN2BY7bpgS5zlVgNPVMrAWINZpscN7gd4QeHg53XAZbJ9kcVvS3saLwlArHWtF3Lw8ijv+2bPZtJf1bviBUksvL/EC5novdAMYnvIxyj55YmLkbzEgw66Lu9BQX3Ow7Ex9wvBZphQFXg8Dwlv9R++GnZTo7Y5Tm6Z0K4U9kEmtJ9f8q+ECHhZVvMU24DMDfvvtGCMLhx4PoYG4gUtrAFB78/PM9Jymd0SnhewPk9yNCB8wQ4B1oXNjcd2NC+H93tiF3kl1/aFiUoSo3MxlcO+41TQKGrwByX4D3h5ICm25DScPIxLZbe4toOc7gktrL516mI29IIU2gXloo4SEV/m12HYwrD1lWnPoXSSbhQzK39QGCYgMNyyItvFGT6O/OWRw77lP6jgcyASXjknY+1wMdyXly/Rhu2W0AjsCvmq/uAzYO4HfxeP4P2iYtzQLlnDhemnioxomaayiiNXNlK3FLsgAiHiOJxHjF5cIhEWOhHo4hLy1AFqTwHx4ajCOL4Ivy0rB2uRq08z0yq3FN5gZ8Hc2ETd7xaSRdFzdri+WmwZKmSr4weink4nutyrmGbbU44P6v+IKrGNuDdh8YTtHdcVpXfr3F1wG+OexHJo6yyObWzqGC23dv5AxhmfxUZU2gN2aXedaxlzXzqZPcf7XsD6FZsre69ytMEsmoOQ4ofuM+Wgggji1Aa3sscZaeCpVvtz7N7Jsx1iMRkK+0OMhIcJLrepfFg0h8G89JmFPN3BnZYDZure3ptLRc8u95tb50awiAlRv09+LDqXXqrGERFSSQJAHkkFNMBpD78cG1Pgtxa8Bxgpr1ghioy7qFt+Dxit/UhP6HWmK9VL+4NIyfl6+DO8wPpzmhvJbYZOAJY3nBS00Z8BtJkyJlWrNJPtlb/Vp/vyJ4WeIbOZQad3IORtlx6aAPgLbavDrvCz3NIppetTGjVBCwTko2FVEQnlugEd7o9dHEwdLorpbtAp47Kp/ioIsASIfl1Vd4pjscRH7a+6HCHK9kXd93skLLykx+XioCSzytKiBqMAwS/QBwROaE6Pa/AK204HRjyxJBVuJguS8HtgVn/IT03Tu4AvxGV9L447/NgJWiCVEf9+nCqameyFn/AbVU2ZE6Pn8Dm/fZS10eNfpOP0x+/RNeqnQzvgMsaRruVSqPVDRu5oEkIJtaadprmharOwO63pj9q0hJVt0B131AIeJdpNMb+gUyy+Ri2mESRiI7Yk/5OCbzT91mbGG+2fMjZZparWsyKkAS9HWdYlCiQ7HvCExiwL48b79UCU14cz+m4Q9TWrL2Z37gBARgtDiwxN3gA8OAcl58kC4oiNRTdZJgUol0rdDHBJzxS4OXIA7JpRlzDlcSTwqlRHm8x3z02K2DLXFUax3rEI/PqLtjDisZCZurwEj0mxvXLAdGgy6lW9qVG/Aku+dWVMYOM/1ujILba9bEuipjgQz+AYu/VlSxYPTikF63JCMuhIR6ikC96mxKoubtF9f1AYxPOTsSoLe+5BY1bqotm9j3AQ3bY/GiWL5mkEsLYrdB87C5qvnqPT0dwob7ougbuyPlYrOKrotAsW6oiC6FHpch0wH6dX1wk2UaKyAzGCO7Jk7PyV1qFe/faioaLMuFGYKVGGLqAnehQCsbDpOnVfcuLtcyPUnfdQLIRL0MzCBjD4MY8/79txSaB5kiOXXy7olpG85rM4M1HMyQDqjqDNFwuy0szbi6YVwNS0L5Si3WQ2tNHSb8CLsi1U8GscEPi10iIT6EJTgyTDDKowc3QK7TtM4QxFcOfCCssyjpsmtbCHIDCeVU1HMrtGRqPDG5AjbjpwyyWpjulFZzCVzdiJrRbNYzOMsw8yTFA+9cupLq2yV+6+68s0ChdRFA28z6PGOcEIKLVxsc6NFIxyPbD+BF3LBp+eXR1Lu/TfAE8OlT/wtiMgg8ht9O79H9GQgMS6S+7gs7DkJwF/11CmdnaMivEbvbeOOraNLZCfKQfphBxjmdJL6dQSGFI5gQjSvhy5kARhW81nWOQbNOJ+C2iwIexQSewiV8fqTYKR7VQnj+APwkcvDP5TF0W+e0+62VQRdAxRobwFsB76yrenz9DTkrPBGugdJLbe7dsEySXv1YxhCb8hmaa2iFZhB1DdHrgeLR8KKQFzbVy6PGTfY2iI/5Rkab2rgVT500oEwGVGMvx6cHbVu9+uxexX9pPuX0nYtvJMVHGZEDPT3TpW9shqtwCBEQYdsRQhbYUN/OaNHRcAjhBa3NG6ubKe6cTDg2JNbu/GmyOCxa6CFKweWXglsml5QQr5KMFhYl8vHKqKYKOZF0Bn7si4OQP60xLWpX7fHc/SHfuT8TLIaHnY5AuLdGx3N9H3kEmaHMAtrG5UootHpjhX7J4bmw6TCZ9ZeEe4OQUbfG0/9R8rBNvBFofGXkq6fKmMPTSWjwcD39c4d8b1gcx1xlzEb27ReGn0MD2YVr3I9GjHi3E0SqAptyroaN0pWihZKtN3FgBqr6TGZ3FhxkmQtyrh5vZxl+vZSBXC+DSar2Wcymi6KCHi0lik2KVCh3gWeWTXebDlU0F+uQ47Gk4VwpRuLRhQnYhgPbiSEQ96g3BEqVduMB77rcNB9TONSNwQx7ct8Jia0ldDK5b4yZZ4+SyMinH0mz8iI/JwkESknXGIZY78cdjiGrCBOxoxlLafJK6LPyePW61TwyHUrePRau++mds92JyFsmjuzNWeSDeTEGH7OkzYZqC+PathdxzEbJR40C7vSeZHyx1Qz54f68P8XM/MjzMLw+PDL/I2oRNWazOOoZdyMZzhaOxwzjCnovX47zJGDlkJwUpdayvYFlSqFtAt5dKs05Cdt9ro+tdl+puLK6HxZJ/db64OEMmSh0Lv0sCYcvFE8Pkce3VgSq5qq/fE9lE4k8Fcb8MASqYE8j6rrcFH63M3Hebk2HDOBbdmbVCAIe7RBXtWm/6GoarNlixPi4la1MtPCvxwm1K7JyKZb4eqUSfjvoW2cP8W5UouEXgkVHOlnWfjGayPTbOmtbdzlHzgJHP4UeI2luejw8Z5M45017wj0o4+vheDcR+FV6kMF1MFrtbobNBKzCxHpECo3Nz6NbgcciVbrfzSvs2gbUPrvdhTuXPY2daRRx/wf4zlUFLrdEyv4dRncmsKUhpfmy2hGYxXHfMBa9w3Z1Yz8eLY7QhH+RIQAOglSiUE3lplw639qmNyGfwk1e8aAL1FoQ9WVSlqrnL+tppLtsVcCCoRGTTUQMefnVdjx4AZTmft5nAKdMGMjro/RREQcrll2zQdMnIOM1rJ+4qT/+VN643t8OIuYLBsWmrx71rgB/CyKBo2xH7xuS8GE+ekylTB38w1ByT7Y0LnkB1yLky9NIq8swWCg5P1SJDWl4dU3vYcMgtzvSjFp2ixEQYLqA4iUQUVcKD/2P6Hrph1ANzw5jgNCIHDUrs7hUtkm1SWlxWJRWjZgWVw+NMy1osw8chUgQaruIfpTeB2BNmBVjGIIGeQNPnZOKvzWn7cTPCwsDvorQd4VZTbcwnYo+2Ig2DUcHa/LE98lNcWpOa+5urGZMdVTUKzRdB8IPsqL6OBxgjQu8YNvpPh/nscNlWs661cJ65POFM4dzRCH0nGOsE+8Zcip2Y5qHLB7Fm2A89ULg0nd7Z4ilPNIFfZgsbfUounfCiug7nHXe6i85QipmFZP+aQOfQRYGOtPy2IxF2XL08+w7OIWsfwh6nxJszi6nFJIffGMpKxKtscX+qpERwqqzPD7YnQEbEZg/iYEhc0ZSRAaXBAR9F6npBqTv66LIhz7AgOabjA8ycejRqluWAw9xc1MHzxFwLQlMDkWH0UF6y1ZFOgp62GBa5koZpTVtkgwQ3Lrg0r9VxQy9vkM669QJMatLS2NmSqj5P3njAUD5up06eNAN+ED6lp2Q9cMX+es1Qsp9jDO9x53gOTFo6CpFqRs45Ggs2bWvJAgMfFb9lwczd3wO0Hp+jywobEghFf+mXhMV74T7Tb0qJrqTRqSkdX7s12fAuHmwUzRbIYcvJTeHvJ37jHtCL1WsOA32kVj9eBJA+I6je5c6NjdNB+cNFBdiJFYRtTp2unp9Yf8HYjIu+/SIfRQkTjSDbAfpZd6ZL2JLIBPwCoDj/CweYMgKZ8mGf2CIj0cIwhRP2rjqefhx5KNRCum/BZ751XJ/vHGk0m5SD1rJ108hf2UC4+e8GpHkNtomc/YAPr0TUePRwxTPAddvQCoZdZ8nzVi27SwBHo5ki6ZU1ZG+l8dyM22Q+xomLCeBZzb2KbuoXjg60PdEfs4o9HOsieYpCGWt/tXltX6at9RR/mXasnkPbLseTbuWet+vWiRLCForOIdgL2MM8Eji+kYiGGR0hxLoQxUJoaxpaOrqKIniZOnK+Ax/wV2FQSoWYgTs8bleEmzo2HRUfV/SHrSM2owgfIFO90cVOJPRZOrLWKwwlclG4rqDMW0UYXmsy8M1ypwObQJg5usKyNae93v4qQzgZgS+5d3uWeetkfVs2tE866wXPS7TRRAwYx8kZdFpfk0doj+/lJr+jFbK9MoAiEScOjcYziwRGgO55sIT0bmCWJuhCGPIJ0SN/ocOdGsW5DKPer7oumSXJ4JPR+3VN7lIEMvjg6forTSHgdnbn1FmG0YpFV093458yX+NeE/BhxGcupBeqabZt4jIUiJEGaWBcFT7SoE0lrQnwFgy6NjHyR7m2ox5naHLzTojR7ggqxr4HR8jiQEyr0YudEEySxEI7eVup3Cvl3kj8h5ER00NI3n3TU7BQccy9PsNnSA2g47FTjjVue8s1bfzj9+Cm4h4ihtYGfOiPtcknGXGofRhB4/iMN20kioK6gMFIxkL1QPn3rjvoMMAABF3bXbwzNGc++BYyrPptyiplD88tddNwGei+amCf/Kbvlb8NUMM63ZHf1JvwIpcCVT+MS22V0hh2QbQ9BvOAe+qR542aDAZ97af57y8tm9FDiLxrfcjYBmUvIjBUoxOcP3rOKhf5JT9hUSf2ZlngMXBrN6tl2GqzZH1yYNjWdnuLxdcC36kmPUX9B9L/Nl9a7Y3lfwWRAecggZUaiv3yJqfWERh1PHxFb9+v7beIZz6ifV9vfirKV0T4Q/J7vVBDBqawfJnrblmWjCAhLR7Ux0yeA0nknHZUghZEXqSSWX6srp6du/ZnIUSZliQNft7Xdv1TNPdgUTdItL0cEsY6RHwqArL2GgmgXH+p2j5gGC+8zfyOtBf81ggtBGg03h5WRvLD4orjplCEC0baAP4+f4UPDqbEFGJW9cvufecfwZ/epFNrUzPKIydBRITWVNYvjw5lmkiniQMG9IplxfB1TKSIosUHw1zBsEE9ogu3b077iZGX5BGTQ5jfGpruob3T5AgGltL+4qF57tfg+w8MGNPaa4EWSJDTWCXLFocjXV3uFGcjoaJ6fB7uA5H8UuUJh7kdYnZeJW3muMw/MMGK0lApqw5WuaJLnToHVuCVvPMHzdMhmUNUcpyHhaX/mxq+4cGuHSl5rykzhkZ5yE+AvoVroTMcjdlckom+JH6eyoGrSm2fe8HojTeTHds3u1GGTpVKXcYUM+SxLWiIhqSDxGOUHEuCDRQv8IccilkgxISLI30NRyRSNvwrUyLgNMXyG29+y30lIUDqwlwO9/7PVyTFgQkKBWXtJF3rBKzRujfIYA5CMnWqSRvOnHyj0DS92QfF0Y2Z2qi9P7GGBSNXXHKMadfr6UuQuYcb0jZzjbW9gprXA+VL0/4u8I+zrjfuu8R3DbCPfKhizAMboJirc2Jxqgvtb8qbAiu8fXVnpxq92n1PiA5KOUHHUAYjfJlTQbLjVW8iHjhy4UcMnscUlh7hV531/yHxu4miCYIbd5pUrj5OI+8zIHOXID+/86Hpy+I3wBqn26G0ZRzC9fnRyrYjpPcJQdpTUUHdcK16OcIOY8Nde6gFmd06KLW0tAv7OZeyDa8WCQkqA8qEHcJS1BfY7Hm5XH4iVii1Mk8XJyZ0Gd5SA9qNoGrRctqugagstTPiZIvheHIzxSqsG30ky5sZx67ng1qoI3ao/yWqOu5hdAcu8nt2ddauL8mHl6TSc5W14OJ3ixJhtBxsNWxtSM4pR+zdSjuJMT5FUn8c5Z4bt6MR4XV7Dc4FOwcnajyYeozVYpLYUd/ohuD1Nii38owAMtP09Tpz+Xecnki1o95Eu43Yqqi1PZctzVSVzhYlX2rCivnVcOM9XvcXGDg3ix8jcv/sx6iZzR9uRMipzlI5VbLGFnr+PaEUXNczODRmzf/swdOk/DbBY8oCTYfD2mRldW9ZJjIZ4gCpJ5xAngiDSGYU3P0FJMbYKYFOjYEw+QyDrh4ed/P9SEAU8zZh0ST3McaSrKUULm2riYXqPhhAXpQU9XgyfRfdnu2a4mjyl8GfvOlG4wSZGxgOc09PqhMrgbznT4AYBMM7JgJNrhZOKc+/K4L5Y27NdSBkORzUHx6BpE/A1yWwQA3ZiAIKkb/WUXeJSiYicAAUr12Kt/T10C0oScmVbzazKE6NQ7MLB/qLkeiMMb3J84Lkh/TvS5By742SdEBt50qxjnHFtMrnMtTTGDG0MRN0gfvM/qJuxPsMkKyBKhurdKjwvXjWRLWDZqWILDNP+kds6QggTVn/CN+HJ3D5KxPrfnoLgU+Tf2i3l4MVswqjCjY2WIZZJl8I8gS4s33a6VRt50+FLxcre2Kz4x9rzPA8b6BewoAN7q/X8XQ7bwmjaQqkw3UX8Ftx6ZO+3FYayNPlKxJcSOLJHPDVM1o9mNVoqzCKtQOeUFm8JDhyABsgJoALYIvZCnaA/v6v1C496/HdjVpkxaF+PjJW+DyoJliuD2YzGhzRgRah407F0dFbMclPlyQDZNSBjNNa4h09dCkwVK1T33C5r+n4B3Oa6jw7Yvp+iZbWeECua4RMaQnUhQiPqcmwGgBkD6D7OOGV+of/cJzXIH+JBhVFi23HnocSCEwfm5AzqGG/bud10rmD+gQ1oswzw3vdMP1c2QTDdsgswXKGJMjK3feX5et/PFBuBLiTTDq4/xl9Z7XkWXxrHbTSDtOc97jfW+7vT5mu/AcjYi6p9QSCY1aq4eEu7clGWFjfJiVar/EizOFguhxGEKOPLX0sYYbundhIno6Jh+ueFYzP6Xj7nx8rJuMwgLzxhhmsWEb3G2AhKWYVnHCJJLwurBTAWCFD3hbTd92ZCqzE5IbC5xI5MDJ3MNdQOClOgFHeuUHteHgwUojx+8Qr6hkbt+TJAWEEsyZ1Xt9uF5SSGVy1kwCIam4mNhahPwYpt3DWchZWjeVTQtL3HujYNfT3tifn/iCpSjXDYy9Hh+CWiYIQSpQWl4uBO1y8/L6E16Rv81zeWwmK20JJ5hGEoAXDmPM6Gyu6FyWDyvJx1zKwhxJJJk0AWH7UDE5Sx1O6nAeXjiT3YV8EWJTIwyDxPuJEnp8xA15+EVMCSl6H5OI+o3SEYf61HWrN/FbxxunfLGm+gjU0GN3LMHCWDvoFDj5rfs+BhuIqhhR3f5EzkCt6ckS0WkLCAG67z51dzdXVXTx/VzMfFibYHw/SoeI0pG+uhY5IYqUtINP280BBY5lRjFa846/tvsfpby8SLHPjSdhE8uMJ4Qz86oiBS7Z9CTG7TC+UrrqWyt1qQ5wL0dXGznwXUpl8/uDqYIIrsq98cFE8mtEGEmmFcVP2BpsxcCJqzy8P0npppG5x1dV6sY4fGAGQU8aTo9C+3n1zOrdhOqiKTe8C6rPrJgLp1rxj4ngas10Ss3s+FjBAksvaNoykCFu7dAhAfoiNA3AhHdARID1mMAOGIf5rG+sKGnFUXF8K2eQWsTvigfMrFtfxEFdqpf5JXXb5XN/hBWnUAYwefOgXZRjgUtUQTYaE3lhGhfO3qD2rf++C8+rMmRq5KqzF9AMjNiOt4zCuAmGrX8hU7W5GX2QhKqzXqCnmpZJ99fwGCxYOEnjF3PrxsxqNtPt0Vm3hkvvO9u6T8SaTsp/m8kBMGUWKx2fcRTTAJW9qgfg8X3Nqx+prv+srP1/fTD4vwxibeZYBnd3xQK1OvPH4wq0OY4+9vD/yWIuQkwnlnGdF+Ht1CJvpF/YMcgJj670ONup0uixjDq8VFI7i8pNb4gD6d3uk35ta0bVhMmV0OSXzsh5DCzCSU+HUIYc7IrLOgikSmPiVcmh7GhsT32271l7mh7gexaETxnaxik2PxzKtesoB7pu64z6PRoZkxvnGvP1UetljnpsYyC2TyqALp/QXbce5WcgsLZOwqSgbyNqwuVVidgLeZM3EENr1wGV8bOejvFkdPJWy2q4tKHqhq+6OBdPAr5C7SiY7CuucRxTWXx93+AnerJwY0xjGgJ+lkZzY18mZgY9oghqytdXOrzbw+hCyydd3GomQWQ3hPFD3WBH/vEiGfBGmEwYjykU4001JzyJdOQUP6oKkgz+1lxAIHJbwLr0RmunEyLG9oLVzldD3K29aBC7WO9LLa0CewGYud7hB9wDhjQuFTHx8hp8j+FZuLr5RvGgDsw+5itMZjQyy/HIlsP0SKMEtwEmi7x//COajPUIX9LUa/bvqt5shf+dPLVzGL24GEdXnQjoPB4r9VG2Z+uDXRVDpv/LQ7BYwmuWCFj3Y3G+W83SqrO2cISNixRSS8L8SAea2+faHhufLBZeLat0g8NCqc1M9iZpJbo5keVvEq8KwErwC9iizLta6Z2MVFptptu5lbf1mAWiq2z48FqR2ZHJ4SlXL/V2ocRqHK6OG6SS2eHT789umn6jbc/OZOz17yAl0eKqe8sHajr9LFTAVGMbcEOY3Mwmy139a//GAYyhu2P3QXh2WfbKOX0WOJ1PYNzteVelHM2BGRF/1FCsMefbSAIykQVPUsM1jrqz45IuLH9JdiweG/2mNn/EVMWR8qcUEhTw4P6OzAzuB28OT6imDyd9ZnfC7tkkf3OY00a8n+fY996DK1Mchi5nMfwQYTnW5G8i6SyZtO6ArSb3RMQo4ATo/WWgc5jis75Ej4M+kAs/amIv3E7+IKALyH79F1p0hO8lgCu3k2b11Zvkc9Sa0DdTKWBPcbqUNMn9Fa9SCsVOjGk0lKG7f1r5qLHCTnNpAeysu7nfuS2xQeRjyoHOviXOMJHXTIRfLQjacfvBFrrYCgUo9R7rD22Nx+HwGczu3XnIjNV+sP30W34h3PQs60uJ5pZo/VfwRiqwKB7MPBPC9q8OEnPn1RG4liLj3ewsxeK8SdllpOyFHgm+g6/mxw3/y20X8F57Y8Lrscuwm+Hyjz0xWhz49SFn+oBrlqADVBAg5ytFyHkTQeT3IYHPAwlE4QD/Ljvn5uAs5ljhVn7GF2oDHXSGbA5sgD8nDXHcuxZhfZpqSaowpeGHVTqcXuk2PROHK77D9WPx08nde2QhKK6aqOu5DZqUNRS3GHDTLlZN1IBy3jmWa3DkR1MxDawSGKISia/gKlRwh8+W3uT9Kypnx1nfHIsq3DjHucrzA2/I+3GA3t6nhFbsL3fISCfPdxnbBGOHnFsZE8erZHKWtLWkATqsfjilhMIjjPjvpgyVXUFJIXgA7OjJ05EphG9urkfrn0SGqw+RB9xm9xO+trmkcBdIL3M480GXk1czxs78L7SPJXJofSqe9z4d2HRopuMR2R85p86M3NS29oOPhuhvhlZuurJtS9oupdJeIJeCAga+UeYBc8GfeLnpQbuGizgU3V7XGR2sZ0PUsjDNnbNRhwPxb+anLYuIgCy+McELYGMSRA7zbfdeTTv+4ecAxnnalcMI4nrV8W5ZH7Wdmawe6CvhQ7QUHwQauwegcpkWkz6Pb07ZH7uE9dGhtAyIdnbBBjdmLxO2BpvPQSaq0UP4RhkyqnUu2xyXx5Rb4NOitrdfiZJWPc4/OIjt/8OZIyYP71Epg9c7NotIYe6eag2xNBO4Hvq0ADH9FkBDkEbMDQZnD9iNZ7YCOwUl57AZFl9KiwphgBBo4yMZ+7L1iJYkyeO0TIAYviSEgZmc8ujaGJS0aa8cvaayG22vHc9c6rHoKUdPBNUYgO+8At1bsYhBt701pAmEHEJeMXdYJXHmH+FrLJPxqyxF3VPn4QcLRPmQjYv2VJmyfofySvrA5WnrCduDzqdnp6On+VpRSt/CE4a1Fsy4aLDhR95ViWkEvYXTIytjdNvn0674MFbuz34Jwq7nsHK+/RP7bnQGyLZS68Wz3Obz7jVnVtZ+AuyBOMjP87x6KG7FIMIpmGL9jjBa76rRW3oZdq4G470oNhrR6WzlvuzjL/b7vsTBqbSyNuauamI8u/K4WnuKft21b42WcVydDNtPkyqlnWsAP5P6NcosadTy/gLOfOOEe2Pwgsh68CHdcZ0AV6c8l5UaBpuuAMIMAOQ1TCAP3aTrgFzuo9xJX4k+bb732AX2obn8BDlvWMC2TER5JyPsKKimw4enubxxsPY/vgn7cFR6GrkqaH6ZHhP5IsvbSECveFdOHOVOLKnl/CI/qdJqHdmHMsOZGyXkcrcitk6dG2xYnjRyU4QHeu9CC8sWw3hvvg8TLjZMwxBiM9osQ9p8s9rKJyeKg6f533BHdSDmtx3FWNTrFe8JPkU31I08AX9aTVSTwfcRk8Z9ZkTb74Iwbm/BO5UT53ty+MieKv/IZ/2IlRavdr4Pire0M4MU9p4y6bKI5h6vDwrf/rhTbCy3PPwef6Y93oeZeDsCvCOGvXksQwDNfKH9Rd4FfXEfDXMoDX/uqTf6wQF2tvoAeJpVT56xo1RlIozwZCol5ql+sgGdx6fPyMmio/BQnR3YsWPNuIjDt7hw1/JNEYx6umuPfxaL/3WKzLrX9FM7TXhsBB/SjfvSzvN7DtatXtoCBUvrBeWN13HMMVU+GDV8bpTDdr8E5Fy6KPUu7LRkVdI+ifUZAPxm1BPIFF4KZrG8EW5EM8qWnQEB9YwydMF7DsJRdsz62dxSaca9tv25v+GUa305qLxkgpF3z+7DaGz1UiOK++8XSXklNnKhuEi2DSbvXqsxFk30LbsIIbJOtY+bPTb1zTUmzu4IO02c0cxCsMb6UIx0zBnxLzXFK90sMrD6eGrmIopLk2B28WesdIwV+ZyGe3xpzejG/kdLPap3jQ1QaKVbZ5pR8M+OkXGFDZFtOPzxe0wda+lEZdRhq13pPcaz3iIhfPzfhx+R9I+ocMgta1EtVrlxAF+hpZ49+ni0WzI9ExfdHGTVUWb+3TOjbvJ8du//sShI1d9pdqsOqAcE94fMrysmnr8UcNujOX+0URsw8B7gVPeSP0vw5vyDzYIyxgmecxyh8bgl5fOTf4qlgoxTk4QChPjyP2p+T+2EgqCDtp5JuYvpb6lcZ489aPGkeMQRxSVgLpC6/yzeu9oV4+pcCzjD6OryATN6xF/a0oMRG11eZRds7q+bCVxllDpeOUP9tHtsBLofWJEsjiLaK3vjy/8TGZkdGSPwZHOkC1L59n0YIeDRCajlecM3yc50VI1D7mU5/3Zicb/3rrAiPzziOlzYufTjQppBObr/7Oy8pb8p2yBKeP62e+9+pL28vd5ZybPjaRa9M/7vIbz+RabNIdoioZbGhFFmWzIFANvJuwW20/dL+wpBCRv0KFZhbLcP72w01vQfulGv3lN1KBi7r+9mNi7+AsIk8TVa+236oDsWxn9p6Ca7NMjNUHHHtfPg76bH3KTzUXEpzQ/M1p2fxYhiLb7bKdi+I/jxBeI6+XXsOv7g3uKS+XcztQPecRY0mehfMf5rTFsft5RXRwE4cKC18damcPV57QEAeAodCEERWYlk36P9nsWa0Ot+h5318evufb1R8/a3sM9wGxSv31VpwQtQqh4jwyGX+8b1cPPXRKH6bEzRyjLpRCH2dcEQ4hY25dXkUoHEglayW0lcQ9qyften6KO+MSHGIEepPX+zlaGml098XD87XJ6tDAugertf5OLe28kl6MlXaFKNtZnWHBNnbXsxzMiJE/qbGa3Hp2a1PKcHUdfDWW0nr7E3l1Y6lD+eWLTx5tzSfJ6BOc6lTYv7+jfOY/xYmSMDQ3ouBRKNmI0n+ofy9J1b1ecgx9WOk+RwevMIcphi4TFmMNz5MKHebmuPKJvdCg3Qvqb+rlo+dHFq9132bm+lj+r7Ktx9B95ofLMDaWBy2zZhze1k73dupO7N/AEgUV+D3yk8+aJZOLvJouwwrt2pkRdrYSPdTTN8ttkCqemzwQoIVG/+mfDp4JF3EvwyRibA0QtQcaaIG9d3Cu2C5zZCHdNzVMFRt8dJaZTPYuHHf6z0lpyx30SGAyZP2RwghdTSgOaoCuUI8mZ1IA+liI7bbNjT8KU3EFR0ElL1GQ8uRaT/8i/svFZHY+FVaeyuEMZ/99sY0f/kwPraCKep5oD2sA0Z6Ir3AiOESvTnZdJJM6YaCq/jc0j/Kriij/hyjq0heYpYe1/DNndjmXp3/rGMVmPFPlAnNzvSl+5RI3zy9ZWf9RtgyJ1p69omWzVB8qEyey5q9dCMcTuTG/nOm4vVD44mkvNWgrof3IOW++1Rn0paAZSGDD6YLeq2DA7hBcv98BQOaq6ySxTR6F50llWvvRasaUB9/Lg08+2mEzKTmmpZI5TlwXqTcd+t5Lsbq8+e9nhRI7m3t9MEX8Mps3aMiapidRAZudA2em17RSKahGzzX1OPROSU/Lpy/4gdh15WTL5CnI6nG7j2ftrp8cHVp6zeHXIHcNgd0uXfkfWCeGbT/qxRyW5CCsylaYDSthdWB6gO/Yl3Ip9OkfTwFR94p5P3ii6MjygLPgHaiimWX1Foyxl58WtonynRfDOlmxF9G26ie/ZZkU6QmgtyW/24BCH7Ady3nGvLL4/+vMyoVv42723pqn24bNqcec4OA8J6XjWMtV4H5gT9Mz/qYbUpXtDfkvm6J/RIahFwx/7cNqR5YSem2Xmm1m/XKGvcT868tz3y+a5KMw3OHt4i9IQqziRmdb5vH97RXTQ4GdRWDAv2YHJUcOnQ/HCWBelBNBDVkMvUux+w8FwiIRhg5evkPcJ3cOeAKApoQIDAQfZE81NfPPUbY/yy2tC8PRj/tvioU93W3CH2/QTntcZXFX7V7M3s4R+sFv0Ptg+HyZpHwI6+cwlczkcPnpFnY8jNVpB7n8mWsqNmBYnMQfkxd9wW8Jv9e8kAnNSwPtVQavhpWDr8Rbtr52ZdvQvUBK3fXjG8iac9PR395NPgVveXzWUL2ZMG2sCtpdCTWtiC9Yrx9G/unOetnqpRa6PsOvSa1GW86Q5rJtsMiZPVh+BYEt4ytpchOcQdCDslyi7XHoYPpEjrKHpX2dmfbFVbuI34RP/2WGa5HUbjiT0o1tKSOfCtEkxP1d642U5Em9+GPvqhh72/K8rVg276SRFmOM+sWVcwxheVzZ6X86DC7hHssXp6UdKlpI3u55Sdn10uK1rp+kwhqxn4tE1joDXP9gL6gjzz503xMj0KFRJ8g/SctT1JJ3p7Tvz3N7VLOnYWDPulMHeSfAHLlBnan41M3zbt5gELqWaMGoCQSJkQbo04nfXVHs9XfkjUM+T3/JRxiC3XC6f2voK3PSDEfy+ehjTN260jf99hVOwog9Odt4eqD+7roWPl6ahva7Z7B+TSkAGC1X2W/05Pa8TUMb5PBHz/hfzNB2V77j39koRcz+BMcwsOi6W4hIt89bjOMP/j89Y2r/kzcvw83wZ+BnPodw6wTfUeSYA75HAJ+33kIKsdZWz8r0GSSzNUczmQFM/pmzOmysfQedWJKidzJsbH+R2U/LjlcZo8MI/Ituxzacsn2CTt8RDk4v2EUsbRvrFIDU1ABsDiBOYj7hPnA9/lvsRyCIHtrEfbJJthn9i/6m87+wqpvcX9H+xrH/lvx1xyonXav9qJZ/QiJx+CPNP5n/dbnZ/Yj9bCanIW2j2u31cz8GwCvs8pLFk4n1sI/Fet+GgMVQSqb6ZFAn16sETSs3wsmqeYs+vFf9nb09nf0IT9DRrUQHAM8F4eRbnfSBxztXr/wVW2flUfLUzE3CmLwGqfklA20a3lJ/f+YFdNhP2JM8vAtihUsv3715QZ/yvoTL9AlHyq+ueHR8DJQRl2Oo2ApgZUmaAN0y5hNnascYJoC4OhcIrDkInSHYJl6ZQINKF5iXGIGhMMcBmlNprMF/c+IohdhrF1RHN3n70yPfsjR9ZIAtl7CZBkXrqzMgWDNVb2yNC87Zd/41pY0uCJcT0P+jInAGnUPrH4MtY1I9kUZmPLgPu0MflsywnT8/Ks6cyfKRFfItjZPgwyfz+on3+O/t/bneJ9Kpfe9t0g9mxsgFIgFhW9JhsT7a/mJAIHwVR+jw+/xtzKNJ1aUnF62hOnFOKK3URy7vq78O44TQ8roaOlCmG4U6dKIOAt2/XNxZ9DopJsStrvFB/+ZhVGLycRRE5OTWlC+62lKNaPOC/bYgrlmjErOa3n67COVKgOnuIVwMljT3mwx1f7wtGQYpN/lxSVy10Jj+H1jVpPwHMEK7EVo/q6wDYKRtEQFbO/zPfe2CKMmKqumGadmO6/lBGMVJmuVFWdVN2/XDOM3Luu3Hed3P+/31vFIYPbL67Xk4nVgo10l6N4CsF3G4Xn92b3a5hc9XuAXAvXFvd7lD2c3PEVWj0fT3vv+gQKj+lHCGvDg9/vCRBh12ibJJ8u3EsacGWkoDzJJvdobmeG+1A88ESIyCxIf3zYf37YfnHTJ+nrRyJW0Pl/p4Wd1kBXe1qM4NaZcSZdK3BJzbD1YmbvmtNnIeVSsKwBMIHu3C+Si1JYX+aD29jRZVYQHFE5vy2ptztib+Mr17I7eQkJ/arYTWAz1uSWZm9v0D5wmppQ5Xf1jtRLPZQ5WF1aXOwSxDip4/jYdsEqjosDY8Xs1OonTtfDXMwyuJkaF1m8uU1c84fPTtrIIpSu5lH7Vd7T7TI2uxBnfjyUQt6JzTxa3vGsAleGi0rhfJnIwcF/th3lsIiNm7nZlxOgUw0BJNNl9D0ZW4dTKWiX5eHx3Yz5i9HL+DZ5SszxjxkuTH/epW7dk/xp2TQQcZMS4zTMMvMPnLzCy0Exuz8a/K4J+F5hHVw8Tk3vrHZ0j1RPXWT2girwtyusZITeDc7iNSXeFl9pSAwm9wVEtVIFZnSKkss/6M1/4ToPsyTjs1PsN2WistG5Qba123r2X1VnsZCV2VXC4PCYpHNJ7L68HSbWCWUIUIx8R4VW9cdmwBbDr2ZDlu7yIhhHaqqaU6MHod00x7reE+SsHktdOAnwGHdP1jCv99lk8AHm3W8HNhVRv2m8rp79ckF4cECs5XWu18aP3aUvGoVAxtDqsuiySl28iOTWc6DzAjGDh2vIUWnETdphw7mVEQJxHBwe7pYTgrYKVOIzd29upS4b5Wn+dDGOXWuIW0mXARZ/VFPkJTApCQAIxe6iSosyGo66t9EkGigjMWlu+0V78Qi7Q5WL3X3uwCELoMbH44h7ct7QEH6o/5gGpZYs1IYF7j0y8cQ69goSo+h33eBSdJu6mLGXfJloiXJwQa16+w4eA5q3jhxkHBTwUJsL69/W704vj/1wMD9OvowtTe3Vny6XjgPqeE1E5V8UVHMwyxCc5I9L7muwJ1GrnWt+1BT1yCMxLPf48C+WEmSMPV/MHDQQYYo24jWy14gLusSFKnkWv8J7v9Qv6pLIF4gMyAWEYwwo0q7wQwS+IZCYnSc9oYHvguwB/gzaYNk/eplwAkJAADdU5uCG109m1KNCmj6mVHcAvpyVrS6cr2ow6sl6TUiSn7TYyIlJls4ClFYcpM1l/O3HwCdGJA39824SMC1c8HwtrpXhJe6TSMDcx5+lV2/qWWQE45pZXKJ5FYPj5jFkSzASNe/F7/w0+AeQ1tBAtCnT3wQZdharHanVBNWFO3RBw4BHhiwEknsf9JMoIyAicrStdPaKDLNK00R72lSnCmKvo//33hx9SC82Id4pdFgrLbNOwGr8L/UwG91EG27WJUNe2imWmcUH/364ZpBOkki37Tuw1nhi8TVswA4zHp/izkgSyZBCO0npos7YVKqPXmtL9eil0z2Qs6F3SUi0qeVA1BwF3WMYEArXBcifRceOQOQL8DoOJxa5qvAF5BVcMI3XTSADtvP5d2DklvCUy9kKHcvRZPl8JT3oDuhhuC3jL9F0idMXck445HvUzrWXW+82jxbx/Jf2dbGMER+Jqx/eDy9F/kcT8zELB94yIbIMlPuaLAOS5jRCD2MJV1DeRT1pODmQYngLITOmXo7L+DEKPYfIs6Z7IIMkW486iabX+rv9GxZuGXmEUgxHTpgOywZXCqJrHs1+0vPo11i36bDgsGW5H9up1CukAGKpPryZ/5Y5T5/7AJRrmgCTc6TRDAjnzdWywWSLcXC06iHjkxJZQ4472sack7YZjRi6teVB2BrdqPJsyAbT+wsTN+t+q1uFbG7aoVq6oRGMSEf84YEduai5VdaeJYKD7DNjndyvF1P6XYRwVQdxWh3XQbBu/3bgmbLKRowGY6TA2Z3XV4e9YQI4JT/8a0gaDFzcPDznLmFjsQ/60xt3JdqLZWaTOpSeq/7FTNKDKci2BesogYcoi35plHnHs7oWR6OfqHjUnWLJRKsowLuwILs0OILHP54l4On6kc8R4qWJ6bFJT1QCIz8r1Y5hkDJIEdBgvbWNyG6ZO6XWf6+4tkwenW46CILMt1q6//DJt7xNG0Z2CIAq5A+e35U8oW4t+31uhEUsvJgsPvl8aCT48qpoFAtTaS2Nk83LSLe181Uo16fC/HNO+zYDIGvDhH9Op+j2NkPvmsn+gzKwGVf1D8yxZfKjISx4Ko8Z6fGwSNeh6beH7towyMRQKY9kAGHb/F2iR2VNkUy2EQoKiOyzOHgWBjz/VXz8ffyn2LBsw97BTAQ4/NEK4kzJ36BaEENtCuKz2Bqt0OMqfREgD3Ovyji9oXuo+74bvgJOz57Xf33jvM34kfbIlxkV9xilAyyabhpF3gwizObhiDzPMjn9q2YJd43ros+vk4bacK","base64")).toString()),A)},42357:e=>{"use strict";e.exports=require("assert")},64293:e=>{"use strict";e.exports=require("buffer")},63129:e=>{"use strict";e.exports=require("child_process")},27619:e=>{"use strict";e.exports=require("constants")},76417:e=>{"use strict";e.exports=require("crypto")},40881:e=>{"use strict";e.exports=require("dns")},28614:e=>{"use strict";e.exports=require("events")},35747:e=>{"use strict";e.exports=require("fs")},98605:e=>{"use strict";e.exports=require("http")},97565:e=>{"use strict";e.exports=require("http2")},57211:e=>{"use strict";e.exports=require("https")},32282:e=>{"use strict";e.exports=require("module")},11631:e=>{"use strict";e.exports=require("net")},12087:e=>{"use strict";e.exports=require("os")},85622:e=>{"use strict";e.exports=require("path")},71191:e=>{"use strict";e.exports=require("querystring")},51058:e=>{"use strict";e.exports=require("readline")},92413:e=>{"use strict";e.exports=require("stream")},24304:e=>{"use strict";e.exports=require("string_decoder")},4016:e=>{"use strict";e.exports=require("tls")},33867:e=>{"use strict";e.exports=require("tty")},78835:e=>{"use strict";e.exports=require("url")},31669:e=>{"use strict";e.exports=require("util")},78761:e=>{"use strict";e.exports=require("zlib")}},t={};function r(A){if(t[A])return t[A].exports;var n=t[A]={id:A,loaded:!1,exports:{}};return e[A].call(n.exports,n,n.exports,r),n.loaded=!0,n.exports}return r.c=t,r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.t=function(e,t){if(1&t&&(e=this(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var A=Object.create(null);r.r(A);var n={};if(2&t&&"object"==typeof e&&e)for(const t in e)n[t]=()=>e[t];return n.default=()=>e,r.d(A,n),A},r.d=(e,t)=>{for(var A in t)r.o(t,A)&&!r.o(e,A)&&Object.defineProperty(e,A,{enumerable:!0,get:t[A]})},r.hmd=e=>((e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set:()=>{throw new Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e),r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),r(43418)})(); \ No newline at end of file diff --git a/tgui/.yarn/releases/yarn-3.4.1.cjs b/tgui/.yarn/releases/yarn-3.4.1.cjs new file mode 100644 index 0000000000..2bdb752d86 --- /dev/null +++ b/tgui/.yarn/releases/yarn-3.4.1.cjs @@ -0,0 +1,873 @@ +#!/usr/bin/env node +/* eslint-disable */ +//prettier-ignore +(()=>{var Mue=Object.create;var Wb=Object.defineProperty;var Kue=Object.getOwnPropertyDescriptor;var Uue=Object.getOwnPropertyNames;var Hue=Object.getPrototypeOf,Gue=Object.prototype.hasOwnProperty;var J=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw new Error('Dynamic require of "'+r+'" is not supported')});var Yue=(r,e)=>()=>(r&&(e=r(r=0)),e);var w=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports),ut=(r,e)=>{for(var t in e)Wb(r,t,{get:e[t],enumerable:!0})},jue=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Uue(e))!Gue.call(r,n)&&n!==t&&Wb(r,n,{get:()=>e[n],enumerable:!(i=Kue(e,n))||i.enumerable});return r};var Pe=(r,e,t)=>(t=r!=null?Mue(Hue(r)):{},jue(e||!r||!r.__esModule?Wb(t,"default",{value:r,enumerable:!0}):t,r));var _1=w((O7e,X1)=>{X1.exports=V1;V1.sync=uge;var W1=J("fs");function cge(r,e){var t=e.pathExt!==void 0?e.pathExt:process.env.PATHEXT;if(!t||(t=t.split(";"),t.indexOf("")!==-1))return!0;for(var i=0;i{tK.exports=$1;$1.sync=gge;var Z1=J("fs");function $1(r,e,t){Z1.stat(r,function(i,n){t(i,i?!1:eK(n,e))})}function gge(r,e){return eK(Z1.statSync(r),e)}function eK(r,e){return r.isFile()&&fge(r,e)}function fge(r,e){var t=r.mode,i=r.uid,n=r.gid,s=e.uid!==void 0?e.uid:process.getuid&&process.getuid(),o=e.gid!==void 0?e.gid:process.getgid&&process.getgid(),a=parseInt("100",8),l=parseInt("010",8),c=parseInt("001",8),u=a|l,g=t&c||t&l&&n===o||t&a&&i===s||t&u&&s===0;return g}});var nK=w((U7e,iK)=>{var K7e=J("fs"),_E;process.platform==="win32"||global.TESTING_WINDOWS?_E=_1():_E=rK();iK.exports=uS;uS.sync=hge;function uS(r,e,t){if(typeof e=="function"&&(t=e,e={}),!t){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(i,n){uS(r,e||{},function(s,o){s?n(s):i(o)})})}_E(r,e||{},function(i,n){i&&(i.code==="EACCES"||e&&e.ignoreErrors)&&(i=null,n=!1),t(i,n)})}function hge(r,e){try{return _E.sync(r,e||{})}catch(t){if(e&&e.ignoreErrors||t.code==="EACCES")return!1;throw t}}});var uK=w((H7e,cK)=>{var Ig=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",sK=J("path"),pge=Ig?";":":",oK=nK(),aK=r=>Object.assign(new Error(`not found: ${r}`),{code:"ENOENT"}),AK=(r,e)=>{let t=e.colon||pge,i=r.match(/\//)||Ig&&r.match(/\\/)?[""]:[...Ig?[process.cwd()]:[],...(e.path||process.env.PATH||"").split(t)],n=Ig?e.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",s=Ig?n.split(t):[""];return Ig&&r.indexOf(".")!==-1&&s[0]!==""&&s.unshift(""),{pathEnv:i,pathExt:s,pathExtExe:n}},lK=(r,e,t)=>{typeof e=="function"&&(t=e,e={}),e||(e={});let{pathEnv:i,pathExt:n,pathExtExe:s}=AK(r,e),o=[],a=c=>new Promise((u,g)=>{if(c===i.length)return e.all&&o.length?u(o):g(aK(r));let f=i[c],h=/^".*"$/.test(f)?f.slice(1,-1):f,p=sK.join(h,r),C=!h&&/^\.[\\\/]/.test(r)?r.slice(0,2)+p:p;u(l(C,c,0))}),l=(c,u,g)=>new Promise((f,h)=>{if(g===n.length)return f(a(u+1));let p=n[g];oK(c+p,{pathExt:s},(C,y)=>{if(!C&&y)if(e.all)o.push(c+p);else return f(c+p);return f(l(c,u,g+1))})});return t?a(0).then(c=>t(null,c),t):a(0)},dge=(r,e)=>{e=e||{};let{pathEnv:t,pathExt:i,pathExtExe:n}=AK(r,e),s=[];for(let o=0;o{"use strict";var gK=(r={})=>{let e=r.env||process.env;return(r.platform||process.platform)!=="win32"?"PATH":Object.keys(e).reverse().find(i=>i.toUpperCase()==="PATH")||"Path"};gS.exports=gK;gS.exports.default=gK});var CK=w((Y7e,dK)=>{"use strict";var hK=J("path"),Cge=uK(),mge=fK();function pK(r,e){let t=r.options.env||process.env,i=process.cwd(),n=r.options.cwd!=null,s=n&&process.chdir!==void 0&&!process.chdir.disabled;if(s)try{process.chdir(r.options.cwd)}catch{}let o;try{o=Cge.sync(r.command,{path:t[mge({env:t})],pathExt:e?hK.delimiter:void 0})}catch{}finally{s&&process.chdir(i)}return o&&(o=hK.resolve(n?r.options.cwd:"",o)),o}function Ege(r){return pK(r)||pK(r,!0)}dK.exports=Ege});var mK=w((j7e,hS)=>{"use strict";var fS=/([()\][%!^"`<>&|;, *?])/g;function Ige(r){return r=r.replace(fS,"^$1"),r}function yge(r,e){return r=`${r}`,r=r.replace(/(\\*)"/g,'$1$1\\"'),r=r.replace(/(\\*)$/,"$1$1"),r=`"${r}"`,r=r.replace(fS,"^$1"),e&&(r=r.replace(fS,"^$1")),r}hS.exports.command=Ige;hS.exports.argument=yge});var IK=w((q7e,EK)=>{"use strict";EK.exports=/^#!(.*)/});var wK=w((J7e,yK)=>{"use strict";var wge=IK();yK.exports=(r="")=>{let e=r.match(wge);if(!e)return null;let[t,i]=e[0].replace(/#! ?/,"").split(" "),n=t.split("/").pop();return n==="env"?i:i?`${n} ${i}`:n}});var QK=w((W7e,BK)=>{"use strict";var pS=J("fs"),Bge=wK();function Qge(r){let t=Buffer.alloc(150),i;try{i=pS.openSync(r,"r"),pS.readSync(i,t,0,150,0),pS.closeSync(i)}catch{}return Bge(t.toString())}BK.exports=Qge});var xK=w((z7e,vK)=>{"use strict";var bge=J("path"),bK=CK(),SK=mK(),Sge=QK(),vge=process.platform==="win32",xge=/\.(?:com|exe)$/i,Pge=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function Dge(r){r.file=bK(r);let e=r.file&&Sge(r.file);return e?(r.args.unshift(r.file),r.command=e,bK(r)):r.file}function kge(r){if(!vge)return r;let e=Dge(r),t=!xge.test(e);if(r.options.forceShell||t){let i=Pge.test(e);r.command=bge.normalize(r.command),r.command=SK.command(r.command),r.args=r.args.map(s=>SK.argument(s,i));let n=[r.command].concat(r.args).join(" ");r.args=["/d","/s","/c",`"${n}"`],r.command=process.env.comspec||"cmd.exe",r.options.windowsVerbatimArguments=!0}return r}function Rge(r,e,t){e&&!Array.isArray(e)&&(t=e,e=null),e=e?e.slice(0):[],t=Object.assign({},t);let i={command:r,args:e,options:t,file:void 0,original:{command:r,args:e}};return t.shell?i:kge(i)}vK.exports=Rge});var kK=w((V7e,DK)=>{"use strict";var dS=process.platform==="win32";function CS(r,e){return Object.assign(new Error(`${e} ${r.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${e} ${r.command}`,path:r.command,spawnargs:r.args})}function Fge(r,e){if(!dS)return;let t=r.emit;r.emit=function(i,n){if(i==="exit"){let s=PK(n,e,"spawn");if(s)return t.call(r,"error",s)}return t.apply(r,arguments)}}function PK(r,e){return dS&&r===1&&!e.file?CS(e.original,"spawn"):null}function Nge(r,e){return dS&&r===1&&!e.file?CS(e.original,"spawnSync"):null}DK.exports={hookChildProcess:Fge,verifyENOENT:PK,verifyENOENTSync:Nge,notFoundError:CS}});var IS=w((X7e,yg)=>{"use strict";var RK=J("child_process"),mS=xK(),ES=kK();function FK(r,e,t){let i=mS(r,e,t),n=RK.spawn(i.command,i.args,i.options);return ES.hookChildProcess(n,i),n}function Lge(r,e,t){let i=mS(r,e,t),n=RK.spawnSync(i.command,i.args,i.options);return n.error=n.error||ES.verifyENOENTSync(n.status,i),n}yg.exports=FK;yg.exports.spawn=FK;yg.exports.sync=Lge;yg.exports._parse=mS;yg.exports._enoent=ES});var LK=w((_7e,NK)=>{"use strict";function Tge(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function Ml(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,Ml)}Tge(Ml,Error);Ml.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g0){for(g=1,f=1;g>",ie=me(">>",!1),de=">&",tt=me(">&",!1),Pt=">",It=me(">",!1),Or="<<<",ii=me("<<<",!1),gi="<&",hr=me("<&",!1),fi="<",ni=me("<",!1),Ls=function(m){return{type:"argument",segments:[].concat(...m)}},pr=function(m){return m},Ei="$'",_n=me("$'",!1),oa="'",aA=me("'",!1),eg=function(m){return[{type:"text",text:m}]},Zn='""',AA=me('""',!1),aa=function(){return{type:"text",text:""}},up='"',lA=me('"',!1),cA=function(m){return m},wr=function(m){return{type:"arithmetic",arithmetic:m,quoted:!0}},wl=function(m){return{type:"shell",shell:m,quoted:!0}},tg=function(m){return{type:"variable",...m,quoted:!0}},po=function(m){return{type:"text",text:m}},rg=function(m){return{type:"arithmetic",arithmetic:m,quoted:!1}},gp=function(m){return{type:"shell",shell:m,quoted:!1}},fp=function(m){return{type:"variable",...m,quoted:!1}},vr=function(m){return{type:"glob",pattern:m}},se=/^[^']/,Co=Je(["'"],!0,!1),Dn=function(m){return m.join("")},ig=/^[^$"]/,Qt=Je(["$",'"'],!0,!1),Bl=`\\ +`,kn=me(`\\ +`,!1),$n=function(){return""},es="\\",gt=me("\\",!1),mo=/^[\\$"`]/,At=Je(["\\","$",'"',"`"],!1,!1),an=function(m){return m},S="\\a",Tt=me("\\a",!1),ng=function(){return"a"},Ql="\\b",hp=me("\\b",!1),pp=function(){return"\b"},dp=/^[Ee]/,Cp=Je(["E","e"],!1,!1),mp=function(){return"\x1B"},G="\\f",yt=me("\\f",!1),uA=function(){return"\f"},ji="\\n",bl=me("\\n",!1),Xe=function(){return` +`},Aa="\\r",sg=me("\\r",!1),bE=function(){return"\r"},Ep="\\t",SE=me("\\t",!1),ar=function(){return" "},Rn="\\v",Sl=me("\\v",!1),Ip=function(){return"\v"},Ts=/^[\\'"?]/,la=Je(["\\","'",'"',"?"],!1,!1),An=function(m){return String.fromCharCode(parseInt(m,16))},Te="\\x",og=me("\\x",!1),vl="\\u",Os=me("\\u",!1),xl="\\U",gA=me("\\U",!1),ag=function(m){return String.fromCodePoint(parseInt(m,16))},Ag=/^[0-7]/,ca=Je([["0","7"]],!1,!1),ua=/^[0-9a-fA-f]/,rt=Je([["0","9"],["a","f"],["A","f"]],!1,!1),Eo=nt(),fA="-",Pl=me("-",!1),Ms="+",Dl=me("+",!1),vE=".",yp=me(".",!1),lg=function(m,b,N){return{type:"number",value:(m==="-"?-1:1)*parseFloat(b.join("")+"."+N.join(""))}},wp=function(m,b){return{type:"number",value:(m==="-"?-1:1)*parseInt(b.join(""))}},xE=function(m){return{type:"variable",...m}},kl=function(m){return{type:"variable",name:m}},PE=function(m){return m},cg="*",hA=me("*",!1),Rr="/",DE=me("/",!1),Ks=function(m,b,N){return{type:b==="*"?"multiplication":"division",right:N}},Us=function(m,b){return b.reduce((N,U)=>({left:N,...U}),m)},ug=function(m,b,N){return{type:b==="+"?"addition":"subtraction",right:N}},pA="$((",R=me("$((",!1),q="))",Ce=me("))",!1),Ke=function(m){return m},Re="$(",ze=me("$(",!1),dt=function(m){return m},Ft="${",Fn=me("${",!1),Db=":-",$M=me(":-",!1),e1=function(m,b){return{name:m,defaultValue:b}},kb=":-}",t1=me(":-}",!1),r1=function(m){return{name:m,defaultValue:[]}},Rb=":+",i1=me(":+",!1),n1=function(m,b){return{name:m,alternativeValue:b}},Fb=":+}",s1=me(":+}",!1),o1=function(m){return{name:m,alternativeValue:[]}},Nb=function(m){return{name:m}},a1="$",A1=me("$",!1),l1=function(m){return e.isGlobPattern(m)},c1=function(m){return m},Lb=/^[a-zA-Z0-9_]/,Tb=Je([["a","z"],["A","Z"],["0","9"],"_"],!1,!1),Ob=function(){return T()},Mb=/^[$@*?#a-zA-Z0-9_\-]/,Kb=Je(["$","@","*","?","#",["a","z"],["A","Z"],["0","9"],"_","-"],!1,!1),u1=/^[(){}<>$|&; \t"']/,gg=Je(["(",")","{","}","<",">","$","|","&",";"," "," ",'"',"'"],!1,!1),Ub=/^[<>&; \t"']/,Hb=Je(["<",">","&",";"," "," ",'"',"'"],!1,!1),kE=/^[ \t]/,RE=Je([" "," "],!1,!1),Q=0,Me=0,dA=[{line:1,column:1}],d=0,E=[],I=0,k;if("startRule"in e){if(!(e.startRule in i))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=i[e.startRule]}function T(){return r.substring(Me,Q)}function _(){return Et(Me,Q)}function te(m,b){throw b=b!==void 0?b:Et(Me,Q),ki([lt(m)],r.substring(Me,Q),b)}function Be(m,b){throw b=b!==void 0?b:Et(Me,Q),Nn(m,b)}function me(m,b){return{type:"literal",text:m,ignoreCase:b}}function Je(m,b,N){return{type:"class",parts:m,inverted:b,ignoreCase:N}}function nt(){return{type:"any"}}function wt(){return{type:"end"}}function lt(m){return{type:"other",description:m}}function it(m){var b=dA[m],N;if(b)return b;for(N=m-1;!dA[N];)N--;for(b=dA[N],b={line:b.line,column:b.column};Nd&&(d=Q,E=[]),E.push(m))}function Nn(m,b){return new Ml(m,null,null,b)}function ki(m,b,N){return new Ml(Ml.buildMessage(m,b),m,b,N)}function CA(){var m,b;return m=Q,b=Mr(),b===t&&(b=null),b!==t&&(Me=m,b=s(b)),m=b,m}function Mr(){var m,b,N,U,ce;if(m=Q,b=Kr(),b!==t){for(N=[],U=He();U!==t;)N.push(U),U=He();N!==t?(U=ga(),U!==t?(ce=ts(),ce===t&&(ce=null),ce!==t?(Me=m,b=o(b,U,ce),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)}else Q=m,m=t;if(m===t)if(m=Q,b=Kr(),b!==t){for(N=[],U=He();U!==t;)N.push(U),U=He();N!==t?(U=ga(),U===t&&(U=null),U!==t?(Me=m,b=a(b,U),m=b):(Q=m,m=t)):(Q=m,m=t)}else Q=m,m=t;return m}function ts(){var m,b,N,U,ce;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t)if(N=Mr(),N!==t){for(U=[],ce=He();ce!==t;)U.push(ce),ce=He();U!==t?(Me=m,b=l(N),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t;return m}function ga(){var m;return r.charCodeAt(Q)===59?(m=c,Q++):(m=t,I===0&&Qe(u)),m===t&&(r.charCodeAt(Q)===38?(m=g,Q++):(m=t,I===0&&Qe(f))),m}function Kr(){var m,b,N;return m=Q,b=g1(),b!==t?(N=yue(),N===t&&(N=null),N!==t?(Me=m,b=h(b,N),m=b):(Q=m,m=t)):(Q=m,m=t),m}function yue(){var m,b,N,U,ce,Se,ht;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t)if(N=wue(),N!==t){for(U=[],ce=He();ce!==t;)U.push(ce),ce=He();if(U!==t)if(ce=Kr(),ce!==t){for(Se=[],ht=He();ht!==t;)Se.push(ht),ht=He();Se!==t?(Me=m,b=p(N,ce),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t;return m}function wue(){var m;return r.substr(Q,2)===C?(m=C,Q+=2):(m=t,I===0&&Qe(y)),m===t&&(r.substr(Q,2)===B?(m=B,Q+=2):(m=t,I===0&&Qe(v))),m}function g1(){var m,b,N;return m=Q,b=bue(),b!==t?(N=Bue(),N===t&&(N=null),N!==t?(Me=m,b=D(b,N),m=b):(Q=m,m=t)):(Q=m,m=t),m}function Bue(){var m,b,N,U,ce,Se,ht;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t)if(N=Que(),N!==t){for(U=[],ce=He();ce!==t;)U.push(ce),ce=He();if(U!==t)if(ce=g1(),ce!==t){for(Se=[],ht=He();ht!==t;)Se.push(ht),ht=He();Se!==t?(Me=m,b=L(N,ce),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t;return m}function Que(){var m;return r.substr(Q,2)===H?(m=H,Q+=2):(m=t,I===0&&Qe(j)),m===t&&(r.charCodeAt(Q)===124?(m=$,Q++):(m=t,I===0&&Qe(V))),m}function FE(){var m,b,N,U,ce,Se;if(m=Q,b=Q1(),b!==t)if(r.charCodeAt(Q)===61?(N=W,Q++):(N=t,I===0&&Qe(Z)),N!==t)if(U=p1(),U!==t){for(ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();ce!==t?(Me=m,b=A(b,U),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t;else Q=m,m=t;if(m===t)if(m=Q,b=Q1(),b!==t)if(r.charCodeAt(Q)===61?(N=W,Q++):(N=t,I===0&&Qe(Z)),N!==t){for(U=[],ce=He();ce!==t;)U.push(ce),ce=He();U!==t?(Me=m,b=ae(b),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t;return m}function bue(){var m,b,N,U,ce,Se,ht,Bt,Jr,hi,rs;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t)if(r.charCodeAt(Q)===40?(N=ge,Q++):(N=t,I===0&&Qe(re)),N!==t){for(U=[],ce=He();ce!==t;)U.push(ce),ce=He();if(U!==t)if(ce=Mr(),ce!==t){for(Se=[],ht=He();ht!==t;)Se.push(ht),ht=He();if(Se!==t)if(r.charCodeAt(Q)===41?(ht=O,Q++):(ht=t,I===0&&Qe(F)),ht!==t){for(Bt=[],Jr=He();Jr!==t;)Bt.push(Jr),Jr=He();if(Bt!==t){for(Jr=[],hi=Bp();hi!==t;)Jr.push(hi),hi=Bp();if(Jr!==t){for(hi=[],rs=He();rs!==t;)hi.push(rs),rs=He();hi!==t?(Me=m,b=ue(ce,Jr),m=b):(Q=m,m=t)}else Q=m,m=t}else Q=m,m=t}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t;if(m===t){for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t)if(r.charCodeAt(Q)===123?(N=he,Q++):(N=t,I===0&&Qe(ke)),N!==t){for(U=[],ce=He();ce!==t;)U.push(ce),ce=He();if(U!==t)if(ce=Mr(),ce!==t){for(Se=[],ht=He();ht!==t;)Se.push(ht),ht=He();if(Se!==t)if(r.charCodeAt(Q)===125?(ht=Fe,Q++):(ht=t,I===0&&Qe(Ne)),ht!==t){for(Bt=[],Jr=He();Jr!==t;)Bt.push(Jr),Jr=He();if(Bt!==t){for(Jr=[],hi=Bp();hi!==t;)Jr.push(hi),hi=Bp();if(Jr!==t){for(hi=[],rs=He();rs!==t;)hi.push(rs),rs=He();hi!==t?(Me=m,b=oe(ce,Jr),m=b):(Q=m,m=t)}else Q=m,m=t}else Q=m,m=t}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t;if(m===t){for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t){for(N=[],U=FE();U!==t;)N.push(U),U=FE();if(N!==t){for(U=[],ce=He();ce!==t;)U.push(ce),ce=He();if(U!==t){if(ce=[],Se=h1(),Se!==t)for(;Se!==t;)ce.push(Se),Se=h1();else ce=t;if(ce!==t){for(Se=[],ht=He();ht!==t;)Se.push(ht),ht=He();Se!==t?(Me=m,b=le(N,ce),m=b):(Q=m,m=t)}else Q=m,m=t}else Q=m,m=t}else Q=m,m=t}else Q=m,m=t;if(m===t){for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t){if(N=[],U=FE(),U!==t)for(;U!==t;)N.push(U),U=FE();else N=t;if(N!==t){for(U=[],ce=He();ce!==t;)U.push(ce),ce=He();U!==t?(Me=m,b=we(N),m=b):(Q=m,m=t)}else Q=m,m=t}else Q=m,m=t}}}return m}function f1(){var m,b,N,U,ce;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t){if(N=[],U=NE(),U!==t)for(;U!==t;)N.push(U),U=NE();else N=t;if(N!==t){for(U=[],ce=He();ce!==t;)U.push(ce),ce=He();U!==t?(Me=m,b=fe(N),m=b):(Q=m,m=t)}else Q=m,m=t}else Q=m,m=t;return m}function h1(){var m,b,N;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t?(N=Bp(),N!==t?(Me=m,b=Ae(N),m=b):(Q=m,m=t)):(Q=m,m=t),m===t){for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();b!==t?(N=NE(),N!==t?(Me=m,b=Ae(N),m=b):(Q=m,m=t)):(Q=m,m=t)}return m}function Bp(){var m,b,N,U,ce;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();return b!==t?(qe.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(ne)),N===t&&(N=null),N!==t?(U=Sue(),U!==t?(ce=NE(),ce!==t?(Me=m,b=Y(N,U,ce),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m}function Sue(){var m;return r.substr(Q,2)===pe?(m=pe,Q+=2):(m=t,I===0&&Qe(ie)),m===t&&(r.substr(Q,2)===de?(m=de,Q+=2):(m=t,I===0&&Qe(tt)),m===t&&(r.charCodeAt(Q)===62?(m=Pt,Q++):(m=t,I===0&&Qe(It)),m===t&&(r.substr(Q,3)===Or?(m=Or,Q+=3):(m=t,I===0&&Qe(ii)),m===t&&(r.substr(Q,2)===gi?(m=gi,Q+=2):(m=t,I===0&&Qe(hr)),m===t&&(r.charCodeAt(Q)===60?(m=fi,Q++):(m=t,I===0&&Qe(ni))))))),m}function NE(){var m,b,N;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();return b!==t?(N=p1(),N!==t?(Me=m,b=Ae(N),m=b):(Q=m,m=t)):(Q=m,m=t),m}function p1(){var m,b,N;if(m=Q,b=[],N=d1(),N!==t)for(;N!==t;)b.push(N),N=d1();else b=t;return b!==t&&(Me=m,b=Ls(b)),m=b,m}function d1(){var m,b;return m=Q,b=vue(),b!==t&&(Me=m,b=pr(b)),m=b,m===t&&(m=Q,b=xue(),b!==t&&(Me=m,b=pr(b)),m=b,m===t&&(m=Q,b=Pue(),b!==t&&(Me=m,b=pr(b)),m=b,m===t&&(m=Q,b=Due(),b!==t&&(Me=m,b=pr(b)),m=b))),m}function vue(){var m,b,N,U;return m=Q,r.substr(Q,2)===Ei?(b=Ei,Q+=2):(b=t,I===0&&Qe(_n)),b!==t?(N=Fue(),N!==t?(r.charCodeAt(Q)===39?(U=oa,Q++):(U=t,I===0&&Qe(aA)),U!==t?(Me=m,b=eg(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m}function xue(){var m,b,N,U;return m=Q,r.charCodeAt(Q)===39?(b=oa,Q++):(b=t,I===0&&Qe(aA)),b!==t?(N=kue(),N!==t?(r.charCodeAt(Q)===39?(U=oa,Q++):(U=t,I===0&&Qe(aA)),U!==t?(Me=m,b=eg(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m}function Pue(){var m,b,N,U;if(m=Q,r.substr(Q,2)===Zn?(b=Zn,Q+=2):(b=t,I===0&&Qe(AA)),b!==t&&(Me=m,b=aa()),m=b,m===t)if(m=Q,r.charCodeAt(Q)===34?(b=up,Q++):(b=t,I===0&&Qe(lA)),b!==t){for(N=[],U=C1();U!==t;)N.push(U),U=C1();N!==t?(r.charCodeAt(Q)===34?(U=up,Q++):(U=t,I===0&&Qe(lA)),U!==t?(Me=m,b=cA(N),m=b):(Q=m,m=t)):(Q=m,m=t)}else Q=m,m=t;return m}function Due(){var m,b,N;if(m=Q,b=[],N=m1(),N!==t)for(;N!==t;)b.push(N),N=m1();else b=t;return b!==t&&(Me=m,b=cA(b)),m=b,m}function C1(){var m,b;return m=Q,b=w1(),b!==t&&(Me=m,b=wr(b)),m=b,m===t&&(m=Q,b=B1(),b!==t&&(Me=m,b=wl(b)),m=b,m===t&&(m=Q,b=qb(),b!==t&&(Me=m,b=tg(b)),m=b,m===t&&(m=Q,b=Rue(),b!==t&&(Me=m,b=po(b)),m=b))),m}function m1(){var m,b;return m=Q,b=w1(),b!==t&&(Me=m,b=rg(b)),m=b,m===t&&(m=Q,b=B1(),b!==t&&(Me=m,b=gp(b)),m=b,m===t&&(m=Q,b=qb(),b!==t&&(Me=m,b=fp(b)),m=b,m===t&&(m=Q,b=Tue(),b!==t&&(Me=m,b=vr(b)),m=b,m===t&&(m=Q,b=Lue(),b!==t&&(Me=m,b=po(b)),m=b)))),m}function kue(){var m,b,N;for(m=Q,b=[],se.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(Co));N!==t;)b.push(N),se.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(Co));return b!==t&&(Me=m,b=Dn(b)),m=b,m}function Rue(){var m,b,N;if(m=Q,b=[],N=E1(),N===t&&(ig.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(Qt))),N!==t)for(;N!==t;)b.push(N),N=E1(),N===t&&(ig.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(Qt)));else b=t;return b!==t&&(Me=m,b=Dn(b)),m=b,m}function E1(){var m,b,N;return m=Q,r.substr(Q,2)===Bl?(b=Bl,Q+=2):(b=t,I===0&&Qe(kn)),b!==t&&(Me=m,b=$n()),m=b,m===t&&(m=Q,r.charCodeAt(Q)===92?(b=es,Q++):(b=t,I===0&&Qe(gt)),b!==t?(mo.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(At)),N!==t?(Me=m,b=an(N),m=b):(Q=m,m=t)):(Q=m,m=t)),m}function Fue(){var m,b,N;for(m=Q,b=[],N=I1(),N===t&&(se.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(Co)));N!==t;)b.push(N),N=I1(),N===t&&(se.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(Co)));return b!==t&&(Me=m,b=Dn(b)),m=b,m}function I1(){var m,b,N;return m=Q,r.substr(Q,2)===S?(b=S,Q+=2):(b=t,I===0&&Qe(Tt)),b!==t&&(Me=m,b=ng()),m=b,m===t&&(m=Q,r.substr(Q,2)===Ql?(b=Ql,Q+=2):(b=t,I===0&&Qe(hp)),b!==t&&(Me=m,b=pp()),m=b,m===t&&(m=Q,r.charCodeAt(Q)===92?(b=es,Q++):(b=t,I===0&&Qe(gt)),b!==t?(dp.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(Cp)),N!==t?(Me=m,b=mp(),m=b):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===G?(b=G,Q+=2):(b=t,I===0&&Qe(yt)),b!==t&&(Me=m,b=uA()),m=b,m===t&&(m=Q,r.substr(Q,2)===ji?(b=ji,Q+=2):(b=t,I===0&&Qe(bl)),b!==t&&(Me=m,b=Xe()),m=b,m===t&&(m=Q,r.substr(Q,2)===Aa?(b=Aa,Q+=2):(b=t,I===0&&Qe(sg)),b!==t&&(Me=m,b=bE()),m=b,m===t&&(m=Q,r.substr(Q,2)===Ep?(b=Ep,Q+=2):(b=t,I===0&&Qe(SE)),b!==t&&(Me=m,b=ar()),m=b,m===t&&(m=Q,r.substr(Q,2)===Rn?(b=Rn,Q+=2):(b=t,I===0&&Qe(Sl)),b!==t&&(Me=m,b=Ip()),m=b,m===t&&(m=Q,r.charCodeAt(Q)===92?(b=es,Q++):(b=t,I===0&&Qe(gt)),b!==t?(Ts.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(la)),N!==t?(Me=m,b=an(N),m=b):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Nue()))))))))),m}function Nue(){var m,b,N,U,ce,Se,ht,Bt,Jr,hi,rs,Jb;return m=Q,r.charCodeAt(Q)===92?(b=es,Q++):(b=t,I===0&&Qe(gt)),b!==t?(N=Gb(),N!==t?(Me=m,b=An(N),m=b):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Te?(b=Te,Q+=2):(b=t,I===0&&Qe(og)),b!==t?(N=Q,U=Q,ce=Gb(),ce!==t?(Se=Ln(),Se!==t?(ce=[ce,Se],U=ce):(Q=U,U=t)):(Q=U,U=t),U===t&&(U=Gb()),U!==t?N=r.substring(N,Q):N=U,N!==t?(Me=m,b=An(N),m=b):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===vl?(b=vl,Q+=2):(b=t,I===0&&Qe(Os)),b!==t?(N=Q,U=Q,ce=Ln(),ce!==t?(Se=Ln(),Se!==t?(ht=Ln(),ht!==t?(Bt=Ln(),Bt!==t?(ce=[ce,Se,ht,Bt],U=ce):(Q=U,U=t)):(Q=U,U=t)):(Q=U,U=t)):(Q=U,U=t),U!==t?N=r.substring(N,Q):N=U,N!==t?(Me=m,b=An(N),m=b):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===xl?(b=xl,Q+=2):(b=t,I===0&&Qe(gA)),b!==t?(N=Q,U=Q,ce=Ln(),ce!==t?(Se=Ln(),Se!==t?(ht=Ln(),ht!==t?(Bt=Ln(),Bt!==t?(Jr=Ln(),Jr!==t?(hi=Ln(),hi!==t?(rs=Ln(),rs!==t?(Jb=Ln(),Jb!==t?(ce=[ce,Se,ht,Bt,Jr,hi,rs,Jb],U=ce):(Q=U,U=t)):(Q=U,U=t)):(Q=U,U=t)):(Q=U,U=t)):(Q=U,U=t)):(Q=U,U=t)):(Q=U,U=t)):(Q=U,U=t),U!==t?N=r.substring(N,Q):N=U,N!==t?(Me=m,b=ag(N),m=b):(Q=m,m=t)):(Q=m,m=t)))),m}function Gb(){var m;return Ag.test(r.charAt(Q))?(m=r.charAt(Q),Q++):(m=t,I===0&&Qe(ca)),m}function Ln(){var m;return ua.test(r.charAt(Q))?(m=r.charAt(Q),Q++):(m=t,I===0&&Qe(rt)),m}function Lue(){var m,b,N,U,ce;if(m=Q,b=[],N=Q,r.charCodeAt(Q)===92?(U=es,Q++):(U=t,I===0&&Qe(gt)),U!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Eo)),ce!==t?(Me=N,U=an(ce),N=U):(Q=N,N=t)):(Q=N,N=t),N===t&&(N=Q,U=Q,I++,ce=b1(),I--,ce===t?U=void 0:(Q=U,U=t),U!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Eo)),ce!==t?(Me=N,U=an(ce),N=U):(Q=N,N=t)):(Q=N,N=t)),N!==t)for(;N!==t;)b.push(N),N=Q,r.charCodeAt(Q)===92?(U=es,Q++):(U=t,I===0&&Qe(gt)),U!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Eo)),ce!==t?(Me=N,U=an(ce),N=U):(Q=N,N=t)):(Q=N,N=t),N===t&&(N=Q,U=Q,I++,ce=b1(),I--,ce===t?U=void 0:(Q=U,U=t),U!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Eo)),ce!==t?(Me=N,U=an(ce),N=U):(Q=N,N=t)):(Q=N,N=t));else b=t;return b!==t&&(Me=m,b=Dn(b)),m=b,m}function Yb(){var m,b,N,U,ce,Se;if(m=Q,r.charCodeAt(Q)===45?(b=fA,Q++):(b=t,I===0&&Qe(Pl)),b===t&&(r.charCodeAt(Q)===43?(b=Ms,Q++):(b=t,I===0&&Qe(Dl))),b===t&&(b=null),b!==t){if(N=[],qe.test(r.charAt(Q))?(U=r.charAt(Q),Q++):(U=t,I===0&&Qe(ne)),U!==t)for(;U!==t;)N.push(U),qe.test(r.charAt(Q))?(U=r.charAt(Q),Q++):(U=t,I===0&&Qe(ne));else N=t;if(N!==t)if(r.charCodeAt(Q)===46?(U=vE,Q++):(U=t,I===0&&Qe(yp)),U!==t){if(ce=[],qe.test(r.charAt(Q))?(Se=r.charAt(Q),Q++):(Se=t,I===0&&Qe(ne)),Se!==t)for(;Se!==t;)ce.push(Se),qe.test(r.charAt(Q))?(Se=r.charAt(Q),Q++):(Se=t,I===0&&Qe(ne));else ce=t;ce!==t?(Me=m,b=lg(b,N,ce),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;if(m===t){if(m=Q,r.charCodeAt(Q)===45?(b=fA,Q++):(b=t,I===0&&Qe(Pl)),b===t&&(r.charCodeAt(Q)===43?(b=Ms,Q++):(b=t,I===0&&Qe(Dl))),b===t&&(b=null),b!==t){if(N=[],qe.test(r.charAt(Q))?(U=r.charAt(Q),Q++):(U=t,I===0&&Qe(ne)),U!==t)for(;U!==t;)N.push(U),qe.test(r.charAt(Q))?(U=r.charAt(Q),Q++):(U=t,I===0&&Qe(ne));else N=t;N!==t?(Me=m,b=wp(b,N),m=b):(Q=m,m=t)}else Q=m,m=t;if(m===t&&(m=Q,b=qb(),b!==t&&(Me=m,b=xE(b)),m=b,m===t&&(m=Q,b=Rl(),b!==t&&(Me=m,b=kl(b)),m=b,m===t)))if(m=Q,r.charCodeAt(Q)===40?(b=ge,Q++):(b=t,I===0&&Qe(re)),b!==t){for(N=[],U=He();U!==t;)N.push(U),U=He();if(N!==t)if(U=y1(),U!==t){for(ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();ce!==t?(r.charCodeAt(Q)===41?(Se=O,Q++):(Se=t,I===0&&Qe(F)),Se!==t?(Me=m,b=PE(U),m=b):(Q=m,m=t)):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t}return m}function jb(){var m,b,N,U,ce,Se,ht,Bt;if(m=Q,b=Yb(),b!==t){for(N=[],U=Q,ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();if(ce!==t)if(r.charCodeAt(Q)===42?(Se=cg,Q++):(Se=t,I===0&&Qe(hA)),Se===t&&(r.charCodeAt(Q)===47?(Se=Rr,Q++):(Se=t,I===0&&Qe(DE))),Se!==t){for(ht=[],Bt=He();Bt!==t;)ht.push(Bt),Bt=He();ht!==t?(Bt=Yb(),Bt!==t?(Me=U,ce=Ks(b,Se,Bt),U=ce):(Q=U,U=t)):(Q=U,U=t)}else Q=U,U=t;else Q=U,U=t;for(;U!==t;){for(N.push(U),U=Q,ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();if(ce!==t)if(r.charCodeAt(Q)===42?(Se=cg,Q++):(Se=t,I===0&&Qe(hA)),Se===t&&(r.charCodeAt(Q)===47?(Se=Rr,Q++):(Se=t,I===0&&Qe(DE))),Se!==t){for(ht=[],Bt=He();Bt!==t;)ht.push(Bt),Bt=He();ht!==t?(Bt=Yb(),Bt!==t?(Me=U,ce=Ks(b,Se,Bt),U=ce):(Q=U,U=t)):(Q=U,U=t)}else Q=U,U=t;else Q=U,U=t}N!==t?(Me=m,b=Us(b,N),m=b):(Q=m,m=t)}else Q=m,m=t;return m}function y1(){var m,b,N,U,ce,Se,ht,Bt;if(m=Q,b=jb(),b!==t){for(N=[],U=Q,ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();if(ce!==t)if(r.charCodeAt(Q)===43?(Se=Ms,Q++):(Se=t,I===0&&Qe(Dl)),Se===t&&(r.charCodeAt(Q)===45?(Se=fA,Q++):(Se=t,I===0&&Qe(Pl))),Se!==t){for(ht=[],Bt=He();Bt!==t;)ht.push(Bt),Bt=He();ht!==t?(Bt=jb(),Bt!==t?(Me=U,ce=ug(b,Se,Bt),U=ce):(Q=U,U=t)):(Q=U,U=t)}else Q=U,U=t;else Q=U,U=t;for(;U!==t;){for(N.push(U),U=Q,ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();if(ce!==t)if(r.charCodeAt(Q)===43?(Se=Ms,Q++):(Se=t,I===0&&Qe(Dl)),Se===t&&(r.charCodeAt(Q)===45?(Se=fA,Q++):(Se=t,I===0&&Qe(Pl))),Se!==t){for(ht=[],Bt=He();Bt!==t;)ht.push(Bt),Bt=He();ht!==t?(Bt=jb(),Bt!==t?(Me=U,ce=ug(b,Se,Bt),U=ce):(Q=U,U=t)):(Q=U,U=t)}else Q=U,U=t;else Q=U,U=t}N!==t?(Me=m,b=Us(b,N),m=b):(Q=m,m=t)}else Q=m,m=t;return m}function w1(){var m,b,N,U,ce,Se;if(m=Q,r.substr(Q,3)===pA?(b=pA,Q+=3):(b=t,I===0&&Qe(R)),b!==t){for(N=[],U=He();U!==t;)N.push(U),U=He();if(N!==t)if(U=y1(),U!==t){for(ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();ce!==t?(r.substr(Q,2)===q?(Se=q,Q+=2):(Se=t,I===0&&Qe(Ce)),Se!==t?(Me=m,b=Ke(U),m=b):(Q=m,m=t)):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;return m}function B1(){var m,b,N,U;return m=Q,r.substr(Q,2)===Re?(b=Re,Q+=2):(b=t,I===0&&Qe(ze)),b!==t?(N=Mr(),N!==t?(r.charCodeAt(Q)===41?(U=O,Q++):(U=t,I===0&&Qe(F)),U!==t?(Me=m,b=dt(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m}function qb(){var m,b,N,U,ce,Se;return m=Q,r.substr(Q,2)===Ft?(b=Ft,Q+=2):(b=t,I===0&&Qe(Fn)),b!==t?(N=Rl(),N!==t?(r.substr(Q,2)===Db?(U=Db,Q+=2):(U=t,I===0&&Qe($M)),U!==t?(ce=f1(),ce!==t?(r.charCodeAt(Q)===125?(Se=Fe,Q++):(Se=t,I===0&&Qe(Ne)),Se!==t?(Me=m,b=e1(N,ce),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Ft?(b=Ft,Q+=2):(b=t,I===0&&Qe(Fn)),b!==t?(N=Rl(),N!==t?(r.substr(Q,3)===kb?(U=kb,Q+=3):(U=t,I===0&&Qe(t1)),U!==t?(Me=m,b=r1(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Ft?(b=Ft,Q+=2):(b=t,I===0&&Qe(Fn)),b!==t?(N=Rl(),N!==t?(r.substr(Q,2)===Rb?(U=Rb,Q+=2):(U=t,I===0&&Qe(i1)),U!==t?(ce=f1(),ce!==t?(r.charCodeAt(Q)===125?(Se=Fe,Q++):(Se=t,I===0&&Qe(Ne)),Se!==t?(Me=m,b=n1(N,ce),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Ft?(b=Ft,Q+=2):(b=t,I===0&&Qe(Fn)),b!==t?(N=Rl(),N!==t?(r.substr(Q,3)===Fb?(U=Fb,Q+=3):(U=t,I===0&&Qe(s1)),U!==t?(Me=m,b=o1(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Ft?(b=Ft,Q+=2):(b=t,I===0&&Qe(Fn)),b!==t?(N=Rl(),N!==t?(r.charCodeAt(Q)===125?(U=Fe,Q++):(U=t,I===0&&Qe(Ne)),U!==t?(Me=m,b=Nb(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.charCodeAt(Q)===36?(b=a1,Q++):(b=t,I===0&&Qe(A1)),b!==t?(N=Rl(),N!==t?(Me=m,b=Nb(N),m=b):(Q=m,m=t)):(Q=m,m=t)))))),m}function Tue(){var m,b,N;return m=Q,b=Oue(),b!==t?(Me=Q,N=l1(b),N?N=void 0:N=t,N!==t?(Me=m,b=c1(b),m=b):(Q=m,m=t)):(Q=m,m=t),m}function Oue(){var m,b,N,U,ce;if(m=Q,b=[],N=Q,U=Q,I++,ce=S1(),I--,ce===t?U=void 0:(Q=U,U=t),U!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Eo)),ce!==t?(Me=N,U=an(ce),N=U):(Q=N,N=t)):(Q=N,N=t),N!==t)for(;N!==t;)b.push(N),N=Q,U=Q,I++,ce=S1(),I--,ce===t?U=void 0:(Q=U,U=t),U!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Eo)),ce!==t?(Me=N,U=an(ce),N=U):(Q=N,N=t)):(Q=N,N=t);else b=t;return b!==t&&(Me=m,b=Dn(b)),m=b,m}function Q1(){var m,b,N;if(m=Q,b=[],Lb.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(Tb)),N!==t)for(;N!==t;)b.push(N),Lb.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(Tb));else b=t;return b!==t&&(Me=m,b=Ob()),m=b,m}function Rl(){var m,b,N;if(m=Q,b=[],Mb.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(Kb)),N!==t)for(;N!==t;)b.push(N),Mb.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(Kb));else b=t;return b!==t&&(Me=m,b=Ob()),m=b,m}function b1(){var m;return u1.test(r.charAt(Q))?(m=r.charAt(Q),Q++):(m=t,I===0&&Qe(gg)),m}function S1(){var m;return Ub.test(r.charAt(Q))?(m=r.charAt(Q),Q++):(m=t,I===0&&Qe(Hb)),m}function He(){var m,b;if(m=[],kE.test(r.charAt(Q))?(b=r.charAt(Q),Q++):(b=t,I===0&&Qe(RE)),b!==t)for(;b!==t;)m.push(b),kE.test(r.charAt(Q))?(b=r.charAt(Q),Q++):(b=t,I===0&&Qe(RE));else m=t;return m}if(k=n(),k!==t&&Q===r.length)return k;throw k!==t&&Q{"use strict";function Mge(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function Ul(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,Ul)}Mge(Ul,Error);Ul.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g0){for(g=1,f=1;gH&&(H=v,j=[]),j.push(ne))}function Ne(ne,Y){return new Ul(ne,null,null,Y)}function oe(ne,Y,pe){return new Ul(Ul.buildMessage(ne,Y),ne,Y,pe)}function le(){var ne,Y,pe,ie;return ne=v,Y=we(),Y!==t?(r.charCodeAt(v)===47?(pe=s,v++):(pe=t,$===0&&Fe(o)),pe!==t?(ie=we(),ie!==t?(D=ne,Y=a(Y,ie),ne=Y):(v=ne,ne=t)):(v=ne,ne=t)):(v=ne,ne=t),ne===t&&(ne=v,Y=we(),Y!==t&&(D=ne,Y=l(Y)),ne=Y),ne}function we(){var ne,Y,pe,ie;return ne=v,Y=fe(),Y!==t?(r.charCodeAt(v)===64?(pe=c,v++):(pe=t,$===0&&Fe(u)),pe!==t?(ie=qe(),ie!==t?(D=ne,Y=g(Y,ie),ne=Y):(v=ne,ne=t)):(v=ne,ne=t)):(v=ne,ne=t),ne===t&&(ne=v,Y=fe(),Y!==t&&(D=ne,Y=f(Y)),ne=Y),ne}function fe(){var ne,Y,pe,ie,de;return ne=v,r.charCodeAt(v)===64?(Y=c,v++):(Y=t,$===0&&Fe(u)),Y!==t?(pe=Ae(),pe!==t?(r.charCodeAt(v)===47?(ie=s,v++):(ie=t,$===0&&Fe(o)),ie!==t?(de=Ae(),de!==t?(D=ne,Y=h(),ne=Y):(v=ne,ne=t)):(v=ne,ne=t)):(v=ne,ne=t)):(v=ne,ne=t),ne===t&&(ne=v,Y=Ae(),Y!==t&&(D=ne,Y=h()),ne=Y),ne}function Ae(){var ne,Y,pe;if(ne=v,Y=[],p.test(r.charAt(v))?(pe=r.charAt(v),v++):(pe=t,$===0&&Fe(C)),pe!==t)for(;pe!==t;)Y.push(pe),p.test(r.charAt(v))?(pe=r.charAt(v),v++):(pe=t,$===0&&Fe(C));else Y=t;return Y!==t&&(D=ne,Y=h()),ne=Y,ne}function qe(){var ne,Y,pe;if(ne=v,Y=[],y.test(r.charAt(v))?(pe=r.charAt(v),v++):(pe=t,$===0&&Fe(B)),pe!==t)for(;pe!==t;)Y.push(pe),y.test(r.charAt(v))?(pe=r.charAt(v),v++):(pe=t,$===0&&Fe(B));else Y=t;return Y!==t&&(D=ne,Y=h()),ne=Y,ne}if(V=n(),V!==t&&v===r.length)return V;throw V!==t&&v{"use strict";function UK(r){return typeof r>"u"||r===null}function Uge(r){return typeof r=="object"&&r!==null}function Hge(r){return Array.isArray(r)?r:UK(r)?[]:[r]}function Gge(r,e){var t,i,n,s;if(e)for(s=Object.keys(e),t=0,i=s.length;t{"use strict";function Op(r,e){Error.call(this),this.name="YAMLException",this.reason=r,this.mark=e,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():""),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack||""}Op.prototype=Object.create(Error.prototype);Op.prototype.constructor=Op;Op.prototype.toString=function(e){var t=this.name+": ";return t+=this.reason||"(unknown reason)",!e&&this.mark&&(t+=" "+this.mark.toString()),t};HK.exports=Op});var jK=w((pXe,YK)=>{"use strict";var GK=Gl();function SS(r,e,t,i,n){this.name=r,this.buffer=e,this.position=t,this.line=i,this.column=n}SS.prototype.getSnippet=function(e,t){var i,n,s,o,a;if(!this.buffer)return null;for(e=e||4,t=t||75,i="",n=this.position;n>0&&`\0\r +\x85\u2028\u2029`.indexOf(this.buffer.charAt(n-1))===-1;)if(n-=1,this.position-n>t/2-1){i=" ... ",n+=5;break}for(s="",o=this.position;ot/2-1){s=" ... ",o-=5;break}return a=this.buffer.slice(n,o),GK.repeat(" ",e)+i+a+s+` +`+GK.repeat(" ",e+this.position-n+i.length)+"^"};SS.prototype.toString=function(e){var t,i="";return this.name&&(i+='in "'+this.name+'" '),i+="at line "+(this.line+1)+", column "+(this.column+1),e||(t=this.getSnippet(),t&&(i+=`: +`+t)),i};YK.exports=SS});var si=w((dXe,JK)=>{"use strict";var qK=Qg(),qge=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],Jge=["scalar","sequence","mapping"];function Wge(r){var e={};return r!==null&&Object.keys(r).forEach(function(t){r[t].forEach(function(i){e[String(i)]=t})}),e}function zge(r,e){if(e=e||{},Object.keys(e).forEach(function(t){if(qge.indexOf(t)===-1)throw new qK('Unknown option "'+t+'" is met in definition of "'+r+'" YAML type.')}),this.tag=r,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.defaultStyle=e.defaultStyle||null,this.styleAliases=Wge(e.styleAliases||null),Jge.indexOf(this.kind)===-1)throw new qK('Unknown kind "'+this.kind+'" is specified for "'+r+'" YAML type.')}JK.exports=zge});var Yl=w((CXe,zK)=>{"use strict";var WK=Gl(),nI=Qg(),Vge=si();function vS(r,e,t){var i=[];return r.include.forEach(function(n){t=vS(n,e,t)}),r[e].forEach(function(n){t.forEach(function(s,o){s.tag===n.tag&&s.kind===n.kind&&i.push(o)}),t.push(n)}),t.filter(function(n,s){return i.indexOf(s)===-1})}function Xge(){var r={scalar:{},sequence:{},mapping:{},fallback:{}},e,t;function i(n){r[n.kind][n.tag]=r.fallback[n.tag]=n}for(e=0,t=arguments.length;e{"use strict";var _ge=si();VK.exports=new _ge("tag:yaml.org,2002:str",{kind:"scalar",construct:function(r){return r!==null?r:""}})});var ZK=w((EXe,_K)=>{"use strict";var Zge=si();_K.exports=new Zge("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(r){return r!==null?r:[]}})});var eU=w((IXe,$K)=>{"use strict";var $ge=si();$K.exports=new $ge("tag:yaml.org,2002:map",{kind:"mapping",construct:function(r){return r!==null?r:{}}})});var sI=w((yXe,tU)=>{"use strict";var efe=Yl();tU.exports=new efe({explicit:[XK(),ZK(),eU()]})});var iU=w((wXe,rU)=>{"use strict";var tfe=si();function rfe(r){if(r===null)return!0;var e=r.length;return e===1&&r==="~"||e===4&&(r==="null"||r==="Null"||r==="NULL")}function ife(){return null}function nfe(r){return r===null}rU.exports=new tfe("tag:yaml.org,2002:null",{kind:"scalar",resolve:rfe,construct:ife,predicate:nfe,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})});var sU=w((BXe,nU)=>{"use strict";var sfe=si();function ofe(r){if(r===null)return!1;var e=r.length;return e===4&&(r==="true"||r==="True"||r==="TRUE")||e===5&&(r==="false"||r==="False"||r==="FALSE")}function afe(r){return r==="true"||r==="True"||r==="TRUE"}function Afe(r){return Object.prototype.toString.call(r)==="[object Boolean]"}nU.exports=new sfe("tag:yaml.org,2002:bool",{kind:"scalar",resolve:ofe,construct:afe,predicate:Afe,represent:{lowercase:function(r){return r?"true":"false"},uppercase:function(r){return r?"TRUE":"FALSE"},camelcase:function(r){return r?"True":"False"}},defaultStyle:"lowercase"})});var aU=w((QXe,oU)=>{"use strict";var lfe=Gl(),cfe=si();function ufe(r){return 48<=r&&r<=57||65<=r&&r<=70||97<=r&&r<=102}function gfe(r){return 48<=r&&r<=55}function ffe(r){return 48<=r&&r<=57}function hfe(r){if(r===null)return!1;var e=r.length,t=0,i=!1,n;if(!e)return!1;if(n=r[t],(n==="-"||n==="+")&&(n=r[++t]),n==="0"){if(t+1===e)return!0;if(n=r[++t],n==="b"){for(t++;t=0?"0b"+r.toString(2):"-0b"+r.toString(2).slice(1)},octal:function(r){return r>=0?"0"+r.toString(8):"-0"+r.toString(8).slice(1)},decimal:function(r){return r.toString(10)},hexadecimal:function(r){return r>=0?"0x"+r.toString(16).toUpperCase():"-0x"+r.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})});var cU=w((bXe,lU)=>{"use strict";var AU=Gl(),Cfe=si(),mfe=new RegExp("^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");function Efe(r){return!(r===null||!mfe.test(r)||r[r.length-1]==="_")}function Ife(r){var e,t,i,n;return e=r.replace(/_/g,"").toLowerCase(),t=e[0]==="-"?-1:1,n=[],"+-".indexOf(e[0])>=0&&(e=e.slice(1)),e===".inf"?t===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:e===".nan"?NaN:e.indexOf(":")>=0?(e.split(":").forEach(function(s){n.unshift(parseFloat(s,10))}),e=0,i=1,n.forEach(function(s){e+=s*i,i*=60}),t*e):t*parseFloat(e,10)}var yfe=/^[-+]?[0-9]+e/;function wfe(r,e){var t;if(isNaN(r))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===r)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===r)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(AU.isNegativeZero(r))return"-0.0";return t=r.toString(10),yfe.test(t)?t.replace("e",".e"):t}function Bfe(r){return Object.prototype.toString.call(r)==="[object Number]"&&(r%1!==0||AU.isNegativeZero(r))}lU.exports=new Cfe("tag:yaml.org,2002:float",{kind:"scalar",resolve:Efe,construct:Ife,predicate:Bfe,represent:wfe,defaultStyle:"lowercase"})});var xS=w((SXe,uU)=>{"use strict";var Qfe=Yl();uU.exports=new Qfe({include:[sI()],implicit:[iU(),sU(),aU(),cU()]})});var PS=w((vXe,gU)=>{"use strict";var bfe=Yl();gU.exports=new bfe({include:[xS()]})});var dU=w((xXe,pU)=>{"use strict";var Sfe=si(),fU=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),hU=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");function vfe(r){return r===null?!1:fU.exec(r)!==null||hU.exec(r)!==null}function xfe(r){var e,t,i,n,s,o,a,l=0,c=null,u,g,f;if(e=fU.exec(r),e===null&&(e=hU.exec(r)),e===null)throw new Error("Date resolve error");if(t=+e[1],i=+e[2]-1,n=+e[3],!e[4])return new Date(Date.UTC(t,i,n));if(s=+e[4],o=+e[5],a=+e[6],e[7]){for(l=e[7].slice(0,3);l.length<3;)l+="0";l=+l}return e[9]&&(u=+e[10],g=+(e[11]||0),c=(u*60+g)*6e4,e[9]==="-"&&(c=-c)),f=new Date(Date.UTC(t,i,n,s,o,a,l)),c&&f.setTime(f.getTime()-c),f}function Pfe(r){return r.toISOString()}pU.exports=new Sfe("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:vfe,construct:xfe,instanceOf:Date,represent:Pfe})});var mU=w((PXe,CU)=>{"use strict";var Dfe=si();function kfe(r){return r==="<<"||r===null}CU.exports=new Dfe("tag:yaml.org,2002:merge",{kind:"scalar",resolve:kfe})});var yU=w((DXe,IU)=>{"use strict";var jl;try{EU=J,jl=EU("buffer").Buffer}catch{}var EU,Rfe=si(),DS=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= +\r`;function Ffe(r){if(r===null)return!1;var e,t,i=0,n=r.length,s=DS;for(t=0;t64)){if(e<0)return!1;i+=6}return i%8===0}function Nfe(r){var e,t,i=r.replace(/[\r\n=]/g,""),n=i.length,s=DS,o=0,a=[];for(e=0;e>16&255),a.push(o>>8&255),a.push(o&255)),o=o<<6|s.indexOf(i.charAt(e));return t=n%4*6,t===0?(a.push(o>>16&255),a.push(o>>8&255),a.push(o&255)):t===18?(a.push(o>>10&255),a.push(o>>2&255)):t===12&&a.push(o>>4&255),jl?jl.from?jl.from(a):new jl(a):a}function Lfe(r){var e="",t=0,i,n,s=r.length,o=DS;for(i=0;i>18&63],e+=o[t>>12&63],e+=o[t>>6&63],e+=o[t&63]),t=(t<<8)+r[i];return n=s%3,n===0?(e+=o[t>>18&63],e+=o[t>>12&63],e+=o[t>>6&63],e+=o[t&63]):n===2?(e+=o[t>>10&63],e+=o[t>>4&63],e+=o[t<<2&63],e+=o[64]):n===1&&(e+=o[t>>2&63],e+=o[t<<4&63],e+=o[64],e+=o[64]),e}function Tfe(r){return jl&&jl.isBuffer(r)}IU.exports=new Rfe("tag:yaml.org,2002:binary",{kind:"scalar",resolve:Ffe,construct:Nfe,predicate:Tfe,represent:Lfe})});var BU=w((kXe,wU)=>{"use strict";var Ofe=si(),Mfe=Object.prototype.hasOwnProperty,Kfe=Object.prototype.toString;function Ufe(r){if(r===null)return!0;var e=[],t,i,n,s,o,a=r;for(t=0,i=a.length;t{"use strict";var Gfe=si(),Yfe=Object.prototype.toString;function jfe(r){if(r===null)return!0;var e,t,i,n,s,o=r;for(s=new Array(o.length),e=0,t=o.length;e{"use strict";var Jfe=si(),Wfe=Object.prototype.hasOwnProperty;function zfe(r){if(r===null)return!0;var e,t=r;for(e in t)if(Wfe.call(t,e)&&t[e]!==null)return!1;return!0}function Vfe(r){return r!==null?r:{}}SU.exports=new Jfe("tag:yaml.org,2002:set",{kind:"mapping",resolve:zfe,construct:Vfe})});var Sg=w((NXe,xU)=>{"use strict";var Xfe=Yl();xU.exports=new Xfe({include:[PS()],implicit:[dU(),mU()],explicit:[yU(),BU(),bU(),vU()]})});var DU=w((LXe,PU)=>{"use strict";var _fe=si();function Zfe(){return!0}function $fe(){}function ehe(){return""}function the(r){return typeof r>"u"}PU.exports=new _fe("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:Zfe,construct:$fe,predicate:the,represent:ehe})});var RU=w((TXe,kU)=>{"use strict";var rhe=si();function ihe(r){if(r===null||r.length===0)return!1;var e=r,t=/\/([gim]*)$/.exec(r),i="";return!(e[0]==="/"&&(t&&(i=t[1]),i.length>3||e[e.length-i.length-1]!=="/"))}function nhe(r){var e=r,t=/\/([gim]*)$/.exec(r),i="";return e[0]==="/"&&(t&&(i=t[1]),e=e.slice(1,e.length-i.length-1)),new RegExp(e,i)}function she(r){var e="/"+r.source+"/";return r.global&&(e+="g"),r.multiline&&(e+="m"),r.ignoreCase&&(e+="i"),e}function ohe(r){return Object.prototype.toString.call(r)==="[object RegExp]"}kU.exports=new rhe("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:ihe,construct:nhe,predicate:ohe,represent:she})});var LU=w((OXe,NU)=>{"use strict";var oI;try{FU=J,oI=FU("esprima")}catch{typeof window<"u"&&(oI=window.esprima)}var FU,ahe=si();function Ahe(r){if(r===null)return!1;try{var e="("+r+")",t=oI.parse(e,{range:!0});return!(t.type!=="Program"||t.body.length!==1||t.body[0].type!=="ExpressionStatement"||t.body[0].expression.type!=="ArrowFunctionExpression"&&t.body[0].expression.type!=="FunctionExpression")}catch{return!1}}function lhe(r){var e="("+r+")",t=oI.parse(e,{range:!0}),i=[],n;if(t.type!=="Program"||t.body.length!==1||t.body[0].type!=="ExpressionStatement"||t.body[0].expression.type!=="ArrowFunctionExpression"&&t.body[0].expression.type!=="FunctionExpression")throw new Error("Failed to resolve function");return t.body[0].expression.params.forEach(function(s){i.push(s.name)}),n=t.body[0].expression.body.range,t.body[0].expression.body.type==="BlockStatement"?new Function(i,e.slice(n[0]+1,n[1]-1)):new Function(i,"return "+e.slice(n[0],n[1]))}function che(r){return r.toString()}function uhe(r){return Object.prototype.toString.call(r)==="[object Function]"}NU.exports=new ahe("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:Ahe,construct:lhe,predicate:uhe,represent:che})});var Mp=w((MXe,OU)=>{"use strict";var TU=Yl();OU.exports=TU.DEFAULT=new TU({include:[Sg()],explicit:[DU(),RU(),LU()]})});var r2=w((KXe,Kp)=>{"use strict";var da=Gl(),jU=Qg(),ghe=jK(),qU=Sg(),fhe=Mp(),wA=Object.prototype.hasOwnProperty,aI=1,JU=2,WU=3,AI=4,kS=1,hhe=2,MU=3,phe=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,dhe=/[\x85\u2028\u2029]/,Che=/[,\[\]\{\}]/,zU=/^(?:!|!!|![a-z\-]+!)$/i,VU=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function KU(r){return Object.prototype.toString.call(r)}function Bo(r){return r===10||r===13}function Jl(r){return r===9||r===32}function un(r){return r===9||r===32||r===10||r===13}function vg(r){return r===44||r===91||r===93||r===123||r===125}function mhe(r){var e;return 48<=r&&r<=57?r-48:(e=r|32,97<=e&&e<=102?e-97+10:-1)}function Ehe(r){return r===120?2:r===117?4:r===85?8:0}function Ihe(r){return 48<=r&&r<=57?r-48:-1}function UU(r){return r===48?"\0":r===97?"\x07":r===98?"\b":r===116||r===9?" ":r===110?` +`:r===118?"\v":r===102?"\f":r===114?"\r":r===101?"\x1B":r===32?" ":r===34?'"':r===47?"/":r===92?"\\":r===78?"\x85":r===95?"\xA0":r===76?"\u2028":r===80?"\u2029":""}function yhe(r){return r<=65535?String.fromCharCode(r):String.fromCharCode((r-65536>>10)+55296,(r-65536&1023)+56320)}var XU=new Array(256),_U=new Array(256);for(ql=0;ql<256;ql++)XU[ql]=UU(ql)?1:0,_U[ql]=UU(ql);var ql;function whe(r,e){this.input=r,this.filename=e.filename||null,this.schema=e.schema||fhe,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=r.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function ZU(r,e){return new jU(e,new ghe(r.filename,r.input,r.position,r.line,r.position-r.lineStart))}function ft(r,e){throw ZU(r,e)}function lI(r,e){r.onWarning&&r.onWarning.call(null,ZU(r,e))}var HU={YAML:function(e,t,i){var n,s,o;e.version!==null&&ft(e,"duplication of %YAML directive"),i.length!==1&&ft(e,"YAML directive accepts exactly one argument"),n=/^([0-9]+)\.([0-9]+)$/.exec(i[0]),n===null&&ft(e,"ill-formed argument of the YAML directive"),s=parseInt(n[1],10),o=parseInt(n[2],10),s!==1&&ft(e,"unacceptable YAML version of the document"),e.version=i[0],e.checkLineBreaks=o<2,o!==1&&o!==2&&lI(e,"unsupported YAML version of the document")},TAG:function(e,t,i){var n,s;i.length!==2&&ft(e,"TAG directive accepts exactly two arguments"),n=i[0],s=i[1],zU.test(n)||ft(e,"ill-formed tag handle (first argument) of the TAG directive"),wA.call(e.tagMap,n)&&ft(e,'there is a previously declared suffix for "'+n+'" tag handle'),VU.test(s)||ft(e,"ill-formed tag prefix (second argument) of the TAG directive"),e.tagMap[n]=s}};function yA(r,e,t,i){var n,s,o,a;if(e1&&(r.result+=da.repeat(` +`,e-1))}function Bhe(r,e,t){var i,n,s,o,a,l,c,u,g=r.kind,f=r.result,h;if(h=r.input.charCodeAt(r.position),un(h)||vg(h)||h===35||h===38||h===42||h===33||h===124||h===62||h===39||h===34||h===37||h===64||h===96||(h===63||h===45)&&(n=r.input.charCodeAt(r.position+1),un(n)||t&&vg(n)))return!1;for(r.kind="scalar",r.result="",s=o=r.position,a=!1;h!==0;){if(h===58){if(n=r.input.charCodeAt(r.position+1),un(n)||t&&vg(n))break}else if(h===35){if(i=r.input.charCodeAt(r.position-1),un(i))break}else{if(r.position===r.lineStart&&cI(r)||t&&vg(h))break;if(Bo(h))if(l=r.line,c=r.lineStart,u=r.lineIndent,zr(r,!1,-1),r.lineIndent>=e){a=!0,h=r.input.charCodeAt(r.position);continue}else{r.position=o,r.line=l,r.lineStart=c,r.lineIndent=u;break}}a&&(yA(r,s,o,!1),FS(r,r.line-l),s=o=r.position,a=!1),Jl(h)||(o=r.position+1),h=r.input.charCodeAt(++r.position)}return yA(r,s,o,!1),r.result?!0:(r.kind=g,r.result=f,!1)}function Qhe(r,e){var t,i,n;if(t=r.input.charCodeAt(r.position),t!==39)return!1;for(r.kind="scalar",r.result="",r.position++,i=n=r.position;(t=r.input.charCodeAt(r.position))!==0;)if(t===39)if(yA(r,i,r.position,!0),t=r.input.charCodeAt(++r.position),t===39)i=r.position,r.position++,n=r.position;else return!0;else Bo(t)?(yA(r,i,n,!0),FS(r,zr(r,!1,e)),i=n=r.position):r.position===r.lineStart&&cI(r)?ft(r,"unexpected end of the document within a single quoted scalar"):(r.position++,n=r.position);ft(r,"unexpected end of the stream within a single quoted scalar")}function bhe(r,e){var t,i,n,s,o,a;if(a=r.input.charCodeAt(r.position),a!==34)return!1;for(r.kind="scalar",r.result="",r.position++,t=i=r.position;(a=r.input.charCodeAt(r.position))!==0;){if(a===34)return yA(r,t,r.position,!0),r.position++,!0;if(a===92){if(yA(r,t,r.position,!0),a=r.input.charCodeAt(++r.position),Bo(a))zr(r,!1,e);else if(a<256&&XU[a])r.result+=_U[a],r.position++;else if((o=Ehe(a))>0){for(n=o,s=0;n>0;n--)a=r.input.charCodeAt(++r.position),(o=mhe(a))>=0?s=(s<<4)+o:ft(r,"expected hexadecimal character");r.result+=yhe(s),r.position++}else ft(r,"unknown escape sequence");t=i=r.position}else Bo(a)?(yA(r,t,i,!0),FS(r,zr(r,!1,e)),t=i=r.position):r.position===r.lineStart&&cI(r)?ft(r,"unexpected end of the document within a double quoted scalar"):(r.position++,i=r.position)}ft(r,"unexpected end of the stream within a double quoted scalar")}function She(r,e){var t=!0,i,n=r.tag,s,o=r.anchor,a,l,c,u,g,f={},h,p,C,y;if(y=r.input.charCodeAt(r.position),y===91)l=93,g=!1,s=[];else if(y===123)l=125,g=!0,s={};else return!1;for(r.anchor!==null&&(r.anchorMap[r.anchor]=s),y=r.input.charCodeAt(++r.position);y!==0;){if(zr(r,!0,e),y=r.input.charCodeAt(r.position),y===l)return r.position++,r.tag=n,r.anchor=o,r.kind=g?"mapping":"sequence",r.result=s,!0;t||ft(r,"missed comma between flow collection entries"),p=h=C=null,c=u=!1,y===63&&(a=r.input.charCodeAt(r.position+1),un(a)&&(c=u=!0,r.position++,zr(r,!0,e))),i=r.line,Pg(r,e,aI,!1,!0),p=r.tag,h=r.result,zr(r,!0,e),y=r.input.charCodeAt(r.position),(u||r.line===i)&&y===58&&(c=!0,y=r.input.charCodeAt(++r.position),zr(r,!0,e),Pg(r,e,aI,!1,!0),C=r.result),g?xg(r,s,f,p,h,C):c?s.push(xg(r,null,f,p,h,C)):s.push(h),zr(r,!0,e),y=r.input.charCodeAt(r.position),y===44?(t=!0,y=r.input.charCodeAt(++r.position)):t=!1}ft(r,"unexpected end of the stream within a flow collection")}function vhe(r,e){var t,i,n=kS,s=!1,o=!1,a=e,l=0,c=!1,u,g;if(g=r.input.charCodeAt(r.position),g===124)i=!1;else if(g===62)i=!0;else return!1;for(r.kind="scalar",r.result="";g!==0;)if(g=r.input.charCodeAt(++r.position),g===43||g===45)kS===n?n=g===43?MU:hhe:ft(r,"repeat of a chomping mode identifier");else if((u=Ihe(g))>=0)u===0?ft(r,"bad explicit indentation width of a block scalar; it cannot be less than one"):o?ft(r,"repeat of an indentation width identifier"):(a=e+u-1,o=!0);else break;if(Jl(g)){do g=r.input.charCodeAt(++r.position);while(Jl(g));if(g===35)do g=r.input.charCodeAt(++r.position);while(!Bo(g)&&g!==0)}for(;g!==0;){for(RS(r),r.lineIndent=0,g=r.input.charCodeAt(r.position);(!o||r.lineIndenta&&(a=r.lineIndent),Bo(g)){l++;continue}if(r.lineIndente)&&l!==0)ft(r,"bad indentation of a sequence entry");else if(r.lineIndente)&&(Pg(r,e,AI,!0,n)&&(p?f=r.result:h=r.result),p||(xg(r,c,u,g,f,h,s,o),g=f=h=null),zr(r,!0,-1),y=r.input.charCodeAt(r.position)),r.lineIndent>e&&y!==0)ft(r,"bad indentation of a mapping entry");else if(r.lineIndente?l=1:r.lineIndent===e?l=0:r.lineIndente?l=1:r.lineIndent===e?l=0:r.lineIndent tag; it should be "scalar", not "'+r.kind+'"'),g=0,f=r.implicitTypes.length;g tag; it should be "'+h.kind+'", not "'+r.kind+'"'),h.resolve(r.result)?(r.result=h.construct(r.result),r.anchor!==null&&(r.anchorMap[r.anchor]=r.result)):ft(r,"cannot resolve a node with !<"+r.tag+"> explicit tag")):ft(r,"unknown tag !<"+r.tag+">");return r.listener!==null&&r.listener("close",r),r.tag!==null||r.anchor!==null||u}function Rhe(r){var e=r.position,t,i,n,s=!1,o;for(r.version=null,r.checkLineBreaks=r.legacy,r.tagMap={},r.anchorMap={};(o=r.input.charCodeAt(r.position))!==0&&(zr(r,!0,-1),o=r.input.charCodeAt(r.position),!(r.lineIndent>0||o!==37));){for(s=!0,o=r.input.charCodeAt(++r.position),t=r.position;o!==0&&!un(o);)o=r.input.charCodeAt(++r.position);for(i=r.input.slice(t,r.position),n=[],i.length<1&&ft(r,"directive name must not be less than one character in length");o!==0;){for(;Jl(o);)o=r.input.charCodeAt(++r.position);if(o===35){do o=r.input.charCodeAt(++r.position);while(o!==0&&!Bo(o));break}if(Bo(o))break;for(t=r.position;o!==0&&!un(o);)o=r.input.charCodeAt(++r.position);n.push(r.input.slice(t,r.position))}o!==0&&RS(r),wA.call(HU,i)?HU[i](r,i,n):lI(r,'unknown document directive "'+i+'"')}if(zr(r,!0,-1),r.lineIndent===0&&r.input.charCodeAt(r.position)===45&&r.input.charCodeAt(r.position+1)===45&&r.input.charCodeAt(r.position+2)===45?(r.position+=3,zr(r,!0,-1)):s&&ft(r,"directives end mark is expected"),Pg(r,r.lineIndent-1,AI,!1,!0),zr(r,!0,-1),r.checkLineBreaks&&dhe.test(r.input.slice(e,r.position))&&lI(r,"non-ASCII line breaks are interpreted as content"),r.documents.push(r.result),r.position===r.lineStart&&cI(r)){r.input.charCodeAt(r.position)===46&&(r.position+=3,zr(r,!0,-1));return}if(r.position"u"&&(t=e,e=null);var i=$U(r,t);if(typeof e!="function")return i;for(var n=0,s=i.length;n"u"&&(t=e,e=null),e2(r,e,da.extend({schema:qU},t))}function Nhe(r,e){return t2(r,da.extend({schema:qU},e))}Kp.exports.loadAll=e2;Kp.exports.load=t2;Kp.exports.safeLoadAll=Fhe;Kp.exports.safeLoad=Nhe});var b2=w((UXe,OS)=>{"use strict";var Hp=Gl(),Gp=Qg(),Lhe=Mp(),The=Sg(),c2=Object.prototype.toString,u2=Object.prototype.hasOwnProperty,Ohe=9,Up=10,Mhe=13,Khe=32,Uhe=33,Hhe=34,g2=35,Ghe=37,Yhe=38,jhe=39,qhe=42,f2=44,Jhe=45,h2=58,Whe=61,zhe=62,Vhe=63,Xhe=64,p2=91,d2=93,_he=96,C2=123,Zhe=124,m2=125,Fi={};Fi[0]="\\0";Fi[7]="\\a";Fi[8]="\\b";Fi[9]="\\t";Fi[10]="\\n";Fi[11]="\\v";Fi[12]="\\f";Fi[13]="\\r";Fi[27]="\\e";Fi[34]='\\"';Fi[92]="\\\\";Fi[133]="\\N";Fi[160]="\\_";Fi[8232]="\\L";Fi[8233]="\\P";var $he=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];function epe(r,e){var t,i,n,s,o,a,l;if(e===null)return{};for(t={},i=Object.keys(e),n=0,s=i.length;n0?r.charCodeAt(s-1):null,f=f&&s2(o,a)}else{for(s=0;si&&r[g+1]!==" ",g=s);else if(!Dg(o))return uI;a=s>0?r.charCodeAt(s-1):null,f=f&&s2(o,a)}c=c||u&&s-g-1>i&&r[g+1]!==" "}return!l&&!c?f&&!n(r)?I2:y2:t>9&&E2(r)?uI:c?B2:w2}function ope(r,e,t,i){r.dump=function(){if(e.length===0)return"''";if(!r.noCompatMode&&$he.indexOf(e)!==-1)return"'"+e+"'";var n=r.indent*Math.max(1,t),s=r.lineWidth===-1?-1:Math.max(Math.min(r.lineWidth,40),r.lineWidth-n),o=i||r.flowLevel>-1&&t>=r.flowLevel;function a(l){return rpe(r,l)}switch(spe(e,o,r.indent,s,a)){case I2:return e;case y2:return"'"+e.replace(/'/g,"''")+"'";case w2:return"|"+o2(e,r.indent)+a2(n2(e,n));case B2:return">"+o2(e,r.indent)+a2(n2(ape(e,s),n));case uI:return'"'+Ape(e,s)+'"';default:throw new Gp("impossible error: invalid scalar style")}}()}function o2(r,e){var t=E2(r)?String(e):"",i=r[r.length-1]===` +`,n=i&&(r[r.length-2]===` +`||r===` +`),s=n?"+":i?"":"-";return t+s+` +`}function a2(r){return r[r.length-1]===` +`?r.slice(0,-1):r}function ape(r,e){for(var t=/(\n+)([^\n]*)/g,i=function(){var c=r.indexOf(` +`);return c=c!==-1?c:r.length,t.lastIndex=c,A2(r.slice(0,c),e)}(),n=r[0]===` +`||r[0]===" ",s,o;o=t.exec(r);){var a=o[1],l=o[2];s=l[0]===" ",i+=a+(!n&&!s&&l!==""?` +`:"")+A2(l,e),n=s}return i}function A2(r,e){if(r===""||r[0]===" ")return r;for(var t=/ [^ ]/g,i,n=0,s,o=0,a=0,l="";i=t.exec(r);)a=i.index,a-n>e&&(s=o>n?o:a,l+=` +`+r.slice(n,s),n=s+1),o=a;return l+=` +`,r.length-n>e&&o>n?l+=r.slice(n,o)+` +`+r.slice(o+1):l+=r.slice(n),l.slice(1)}function Ape(r){for(var e="",t,i,n,s=0;s=55296&&t<=56319&&(i=r.charCodeAt(s+1),i>=56320&&i<=57343)){e+=i2((t-55296)*1024+i-56320+65536),s++;continue}n=Fi[t],e+=!n&&Dg(t)?r[s]:n||i2(t)}return e}function lpe(r,e,t){var i="",n=r.tag,s,o;for(s=0,o=t.length;s1024&&(u+="? "),u+=r.dump+(r.condenseFlow?'"':"")+":"+(r.condenseFlow?"":" "),Wl(r,e,c,!1,!1)&&(u+=r.dump,i+=u));r.tag=n,r.dump="{"+i+"}"}function gpe(r,e,t,i){var n="",s=r.tag,o=Object.keys(t),a,l,c,u,g,f;if(r.sortKeys===!0)o.sort();else if(typeof r.sortKeys=="function")o.sort(r.sortKeys);else if(r.sortKeys)throw new Gp("sortKeys must be a boolean or a function");for(a=0,l=o.length;a1024,g&&(r.dump&&Up===r.dump.charCodeAt(0)?f+="?":f+="? "),f+=r.dump,g&&(f+=NS(r,e)),Wl(r,e+1,u,!0,g)&&(r.dump&&Up===r.dump.charCodeAt(0)?f+=":":f+=": ",f+=r.dump,n+=f));r.tag=s,r.dump=n||"{}"}function l2(r,e,t){var i,n,s,o,a,l;for(n=t?r.explicitTypes:r.implicitTypes,s=0,o=n.length;s tag resolver accepts not "'+l+'" style');r.dump=i}return!0}return!1}function Wl(r,e,t,i,n,s){r.tag=null,r.dump=t,l2(r,t,!1)||l2(r,t,!0);var o=c2.call(r.dump);i&&(i=r.flowLevel<0||r.flowLevel>e);var a=o==="[object Object]"||o==="[object Array]",l,c;if(a&&(l=r.duplicates.indexOf(t),c=l!==-1),(r.tag!==null&&r.tag!=="?"||c||r.indent!==2&&e>0)&&(n=!1),c&&r.usedDuplicates[l])r.dump="*ref_"+l;else{if(a&&c&&!r.usedDuplicates[l]&&(r.usedDuplicates[l]=!0),o==="[object Object]")i&&Object.keys(r.dump).length!==0?(gpe(r,e,r.dump,n),c&&(r.dump="&ref_"+l+r.dump)):(upe(r,e,r.dump),c&&(r.dump="&ref_"+l+" "+r.dump));else if(o==="[object Array]"){var u=r.noArrayIndent&&e>0?e-1:e;i&&r.dump.length!==0?(cpe(r,u,r.dump,n),c&&(r.dump="&ref_"+l+r.dump)):(lpe(r,u,r.dump),c&&(r.dump="&ref_"+l+" "+r.dump))}else if(o==="[object String]")r.tag!=="?"&&ope(r,r.dump,e,s);else{if(r.skipInvalid)return!1;throw new Gp("unacceptable kind of an object to dump "+o)}r.tag!==null&&r.tag!=="?"&&(r.dump="!<"+r.tag+"> "+r.dump)}return!0}function fpe(r,e){var t=[],i=[],n,s;for(LS(r,t,i),n=0,s=i.length;n{"use strict";var gI=r2(),S2=b2();function fI(r){return function(){throw new Error("Function "+r+" is deprecated and cannot be used.")}}Fr.exports.Type=si();Fr.exports.Schema=Yl();Fr.exports.FAILSAFE_SCHEMA=sI();Fr.exports.JSON_SCHEMA=xS();Fr.exports.CORE_SCHEMA=PS();Fr.exports.DEFAULT_SAFE_SCHEMA=Sg();Fr.exports.DEFAULT_FULL_SCHEMA=Mp();Fr.exports.load=gI.load;Fr.exports.loadAll=gI.loadAll;Fr.exports.safeLoad=gI.safeLoad;Fr.exports.safeLoadAll=gI.safeLoadAll;Fr.exports.dump=S2.dump;Fr.exports.safeDump=S2.safeDump;Fr.exports.YAMLException=Qg();Fr.exports.MINIMAL_SCHEMA=sI();Fr.exports.SAFE_SCHEMA=Sg();Fr.exports.DEFAULT_SCHEMA=Mp();Fr.exports.scan=fI("scan");Fr.exports.parse=fI("parse");Fr.exports.compose=fI("compose");Fr.exports.addConstructor=fI("addConstructor")});var P2=w((GXe,x2)=>{"use strict";var ppe=v2();x2.exports=ppe});var k2=w((YXe,D2)=>{"use strict";function dpe(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function zl(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,zl)}dpe(zl,Error);zl.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g0){for(g=1,f=1;g({[Ke]:Ce})))},H=function(R){return R},j=function(R){return R},$=Ts("correct indentation"),V=" ",W=ar(" ",!1),Z=function(R){return R.length===pA*ug},A=function(R){return R.length===(pA+1)*ug},ae=function(){return pA++,!0},ge=function(){return pA--,!0},re=function(){return sg()},O=Ts("pseudostring"),F=/^[^\r\n\t ?:,\][{}#&*!|>'"%@`\-]/,ue=Rn(["\r",` +`," "," ","?",":",",","]","[","{","}","#","&","*","!","|",">","'",'"',"%","@","`","-"],!0,!1),he=/^[^\r\n\t ,\][{}:#"']/,ke=Rn(["\r",` +`," "," ",",","]","[","{","}",":","#",'"',"'"],!0,!1),Fe=function(){return sg().replace(/^ *| *$/g,"")},Ne="--",oe=ar("--",!1),le=/^[a-zA-Z\/0-9]/,we=Rn([["a","z"],["A","Z"],"/",["0","9"]],!1,!1),fe=/^[^\r\n\t :,]/,Ae=Rn(["\r",` +`," "," ",":",","],!0,!1),qe="null",ne=ar("null",!1),Y=function(){return null},pe="true",ie=ar("true",!1),de=function(){return!0},tt="false",Pt=ar("false",!1),It=function(){return!1},Or=Ts("string"),ii='"',gi=ar('"',!1),hr=function(){return""},fi=function(R){return R},ni=function(R){return R.join("")},Ls=/^[^"\\\0-\x1F\x7F]/,pr=Rn(['"',"\\",["\0",""],"\x7F"],!0,!1),Ei='\\"',_n=ar('\\"',!1),oa=function(){return'"'},aA="\\\\",eg=ar("\\\\",!1),Zn=function(){return"\\"},AA="\\/",aa=ar("\\/",!1),up=function(){return"/"},lA="\\b",cA=ar("\\b",!1),wr=function(){return"\b"},wl="\\f",tg=ar("\\f",!1),po=function(){return"\f"},rg="\\n",gp=ar("\\n",!1),fp=function(){return` +`},vr="\\r",se=ar("\\r",!1),Co=function(){return"\r"},Dn="\\t",ig=ar("\\t",!1),Qt=function(){return" "},Bl="\\u",kn=ar("\\u",!1),$n=function(R,q,Ce,Ke){return String.fromCharCode(parseInt(`0x${R}${q}${Ce}${Ke}`))},es=/^[0-9a-fA-F]/,gt=Rn([["0","9"],["a","f"],["A","F"]],!1,!1),mo=Ts("blank space"),At=/^[ \t]/,an=Rn([" "," "],!1,!1),S=Ts("white space"),Tt=/^[ \t\n\r]/,ng=Rn([" "," ",` +`,"\r"],!1,!1),Ql=`\r +`,hp=ar(`\r +`,!1),pp=` +`,dp=ar(` +`,!1),Cp="\r",mp=ar("\r",!1),G=0,yt=0,uA=[{line:1,column:1}],ji=0,bl=[],Xe=0,Aa;if("startRule"in e){if(!(e.startRule in i))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=i[e.startRule]}function sg(){return r.substring(yt,G)}function bE(){return An(yt,G)}function Ep(R,q){throw q=q!==void 0?q:An(yt,G),vl([Ts(R)],r.substring(yt,G),q)}function SE(R,q){throw q=q!==void 0?q:An(yt,G),og(R,q)}function ar(R,q){return{type:"literal",text:R,ignoreCase:q}}function Rn(R,q,Ce){return{type:"class",parts:R,inverted:q,ignoreCase:Ce}}function Sl(){return{type:"any"}}function Ip(){return{type:"end"}}function Ts(R){return{type:"other",description:R}}function la(R){var q=uA[R],Ce;if(q)return q;for(Ce=R-1;!uA[Ce];)Ce--;for(q=uA[Ce],q={line:q.line,column:q.column};Ceji&&(ji=G,bl=[]),bl.push(R))}function og(R,q){return new zl(R,null,null,q)}function vl(R,q,Ce){return new zl(zl.buildMessage(R,q),R,q,Ce)}function Os(){var R;return R=ag(),R}function xl(){var R,q,Ce;for(R=G,q=[],Ce=gA();Ce!==t;)q.push(Ce),Ce=gA();return q!==t&&(yt=R,q=s(q)),R=q,R}function gA(){var R,q,Ce,Ke,Re;return R=G,q=ua(),q!==t?(r.charCodeAt(G)===45?(Ce=o,G++):(Ce=t,Xe===0&&Te(a)),Ce!==t?(Ke=Rr(),Ke!==t?(Re=ca(),Re!==t?(yt=R,q=l(Re),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t),R}function ag(){var R,q,Ce;for(R=G,q=[],Ce=Ag();Ce!==t;)q.push(Ce),Ce=Ag();return q!==t&&(yt=R,q=c(q)),R=q,R}function Ag(){var R,q,Ce,Ke,Re,ze,dt,Ft,Fn;if(R=G,q=Rr(),q===t&&(q=null),q!==t){if(Ce=G,r.charCodeAt(G)===35?(Ke=u,G++):(Ke=t,Xe===0&&Te(g)),Ke!==t){if(Re=[],ze=G,dt=G,Xe++,Ft=Us(),Xe--,Ft===t?dt=void 0:(G=dt,dt=t),dt!==t?(r.length>G?(Ft=r.charAt(G),G++):(Ft=t,Xe===0&&Te(f)),Ft!==t?(dt=[dt,Ft],ze=dt):(G=ze,ze=t)):(G=ze,ze=t),ze!==t)for(;ze!==t;)Re.push(ze),ze=G,dt=G,Xe++,Ft=Us(),Xe--,Ft===t?dt=void 0:(G=dt,dt=t),dt!==t?(r.length>G?(Ft=r.charAt(G),G++):(Ft=t,Xe===0&&Te(f)),Ft!==t?(dt=[dt,Ft],ze=dt):(G=ze,ze=t)):(G=ze,ze=t);else Re=t;Re!==t?(Ke=[Ke,Re],Ce=Ke):(G=Ce,Ce=t)}else G=Ce,Ce=t;if(Ce===t&&(Ce=null),Ce!==t){if(Ke=[],Re=Ks(),Re!==t)for(;Re!==t;)Ke.push(Re),Re=Ks();else Ke=t;Ke!==t?(yt=R,q=h(),R=q):(G=R,R=t)}else G=R,R=t}else G=R,R=t;if(R===t&&(R=G,q=ua(),q!==t?(Ce=Pl(),Ce!==t?(Ke=Rr(),Ke===t&&(Ke=null),Ke!==t?(r.charCodeAt(G)===58?(Re=p,G++):(Re=t,Xe===0&&Te(C)),Re!==t?(ze=Rr(),ze===t&&(ze=null),ze!==t?(dt=ca(),dt!==t?(yt=R,q=y(Ce,dt),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t),R===t&&(R=G,q=ua(),q!==t?(Ce=Ms(),Ce!==t?(Ke=Rr(),Ke===t&&(Ke=null),Ke!==t?(r.charCodeAt(G)===58?(Re=p,G++):(Re=t,Xe===0&&Te(C)),Re!==t?(ze=Rr(),ze===t&&(ze=null),ze!==t?(dt=ca(),dt!==t?(yt=R,q=y(Ce,dt),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t),R===t))){if(R=G,q=ua(),q!==t)if(Ce=Ms(),Ce!==t)if(Ke=Rr(),Ke!==t)if(Re=vE(),Re!==t){if(ze=[],dt=Ks(),dt!==t)for(;dt!==t;)ze.push(dt),dt=Ks();else ze=t;ze!==t?(yt=R,q=y(Ce,Re),R=q):(G=R,R=t)}else G=R,R=t;else G=R,R=t;else G=R,R=t;else G=R,R=t;if(R===t)if(R=G,q=ua(),q!==t)if(Ce=Ms(),Ce!==t){if(Ke=[],Re=G,ze=Rr(),ze===t&&(ze=null),ze!==t?(r.charCodeAt(G)===44?(dt=B,G++):(dt=t,Xe===0&&Te(v)),dt!==t?(Ft=Rr(),Ft===t&&(Ft=null),Ft!==t?(Fn=Ms(),Fn!==t?(yt=Re,ze=D(Ce,Fn),Re=ze):(G=Re,Re=t)):(G=Re,Re=t)):(G=Re,Re=t)):(G=Re,Re=t),Re!==t)for(;Re!==t;)Ke.push(Re),Re=G,ze=Rr(),ze===t&&(ze=null),ze!==t?(r.charCodeAt(G)===44?(dt=B,G++):(dt=t,Xe===0&&Te(v)),dt!==t?(Ft=Rr(),Ft===t&&(Ft=null),Ft!==t?(Fn=Ms(),Fn!==t?(yt=Re,ze=D(Ce,Fn),Re=ze):(G=Re,Re=t)):(G=Re,Re=t)):(G=Re,Re=t)):(G=Re,Re=t);else Ke=t;Ke!==t?(Re=Rr(),Re===t&&(Re=null),Re!==t?(r.charCodeAt(G)===58?(ze=p,G++):(ze=t,Xe===0&&Te(C)),ze!==t?(dt=Rr(),dt===t&&(dt=null),dt!==t?(Ft=ca(),Ft!==t?(yt=R,q=L(Ce,Ke,Ft),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)}else G=R,R=t;else G=R,R=t}return R}function ca(){var R,q,Ce,Ke,Re,ze,dt;if(R=G,q=G,Xe++,Ce=G,Ke=Us(),Ke!==t?(Re=rt(),Re!==t?(r.charCodeAt(G)===45?(ze=o,G++):(ze=t,Xe===0&&Te(a)),ze!==t?(dt=Rr(),dt!==t?(Ke=[Ke,Re,ze,dt],Ce=Ke):(G=Ce,Ce=t)):(G=Ce,Ce=t)):(G=Ce,Ce=t)):(G=Ce,Ce=t),Xe--,Ce!==t?(G=q,q=void 0):q=t,q!==t?(Ce=Ks(),Ce!==t?(Ke=Eo(),Ke!==t?(Re=xl(),Re!==t?(ze=fA(),ze!==t?(yt=R,q=H(Re),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t),R===t&&(R=G,q=Us(),q!==t?(Ce=Eo(),Ce!==t?(Ke=ag(),Ke!==t?(Re=fA(),Re!==t?(yt=R,q=H(Ke),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t),R===t))if(R=G,q=Dl(),q!==t){if(Ce=[],Ke=Ks(),Ke!==t)for(;Ke!==t;)Ce.push(Ke),Ke=Ks();else Ce=t;Ce!==t?(yt=R,q=j(q),R=q):(G=R,R=t)}else G=R,R=t;return R}function ua(){var R,q,Ce;for(Xe++,R=G,q=[],r.charCodeAt(G)===32?(Ce=V,G++):(Ce=t,Xe===0&&Te(W));Ce!==t;)q.push(Ce),r.charCodeAt(G)===32?(Ce=V,G++):(Ce=t,Xe===0&&Te(W));return q!==t?(yt=G,Ce=Z(q),Ce?Ce=void 0:Ce=t,Ce!==t?(q=[q,Ce],R=q):(G=R,R=t)):(G=R,R=t),Xe--,R===t&&(q=t,Xe===0&&Te($)),R}function rt(){var R,q,Ce;for(R=G,q=[],r.charCodeAt(G)===32?(Ce=V,G++):(Ce=t,Xe===0&&Te(W));Ce!==t;)q.push(Ce),r.charCodeAt(G)===32?(Ce=V,G++):(Ce=t,Xe===0&&Te(W));return q!==t?(yt=G,Ce=A(q),Ce?Ce=void 0:Ce=t,Ce!==t?(q=[q,Ce],R=q):(G=R,R=t)):(G=R,R=t),R}function Eo(){var R;return yt=G,R=ae(),R?R=void 0:R=t,R}function fA(){var R;return yt=G,R=ge(),R?R=void 0:R=t,R}function Pl(){var R;return R=kl(),R===t&&(R=yp()),R}function Ms(){var R,q,Ce;if(R=kl(),R===t){if(R=G,q=[],Ce=lg(),Ce!==t)for(;Ce!==t;)q.push(Ce),Ce=lg();else q=t;q!==t&&(yt=R,q=re()),R=q}return R}function Dl(){var R;return R=wp(),R===t&&(R=xE(),R===t&&(R=kl(),R===t&&(R=yp()))),R}function vE(){var R;return R=wp(),R===t&&(R=kl(),R===t&&(R=lg())),R}function yp(){var R,q,Ce,Ke,Re,ze;if(Xe++,R=G,F.test(r.charAt(G))?(q=r.charAt(G),G++):(q=t,Xe===0&&Te(ue)),q!==t){for(Ce=[],Ke=G,Re=Rr(),Re===t&&(Re=null),Re!==t?(he.test(r.charAt(G))?(ze=r.charAt(G),G++):(ze=t,Xe===0&&Te(ke)),ze!==t?(Re=[Re,ze],Ke=Re):(G=Ke,Ke=t)):(G=Ke,Ke=t);Ke!==t;)Ce.push(Ke),Ke=G,Re=Rr(),Re===t&&(Re=null),Re!==t?(he.test(r.charAt(G))?(ze=r.charAt(G),G++):(ze=t,Xe===0&&Te(ke)),ze!==t?(Re=[Re,ze],Ke=Re):(G=Ke,Ke=t)):(G=Ke,Ke=t);Ce!==t?(yt=R,q=Fe(),R=q):(G=R,R=t)}else G=R,R=t;return Xe--,R===t&&(q=t,Xe===0&&Te(O)),R}function lg(){var R,q,Ce,Ke,Re;if(R=G,r.substr(G,2)===Ne?(q=Ne,G+=2):(q=t,Xe===0&&Te(oe)),q===t&&(q=null),q!==t)if(le.test(r.charAt(G))?(Ce=r.charAt(G),G++):(Ce=t,Xe===0&&Te(we)),Ce!==t){for(Ke=[],fe.test(r.charAt(G))?(Re=r.charAt(G),G++):(Re=t,Xe===0&&Te(Ae));Re!==t;)Ke.push(Re),fe.test(r.charAt(G))?(Re=r.charAt(G),G++):(Re=t,Xe===0&&Te(Ae));Ke!==t?(yt=R,q=Fe(),R=q):(G=R,R=t)}else G=R,R=t;else G=R,R=t;return R}function wp(){var R,q;return R=G,r.substr(G,4)===qe?(q=qe,G+=4):(q=t,Xe===0&&Te(ne)),q!==t&&(yt=R,q=Y()),R=q,R}function xE(){var R,q;return R=G,r.substr(G,4)===pe?(q=pe,G+=4):(q=t,Xe===0&&Te(ie)),q!==t&&(yt=R,q=de()),R=q,R===t&&(R=G,r.substr(G,5)===tt?(q=tt,G+=5):(q=t,Xe===0&&Te(Pt)),q!==t&&(yt=R,q=It()),R=q),R}function kl(){var R,q,Ce,Ke;return Xe++,R=G,r.charCodeAt(G)===34?(q=ii,G++):(q=t,Xe===0&&Te(gi)),q!==t?(r.charCodeAt(G)===34?(Ce=ii,G++):(Ce=t,Xe===0&&Te(gi)),Ce!==t?(yt=R,q=hr(),R=q):(G=R,R=t)):(G=R,R=t),R===t&&(R=G,r.charCodeAt(G)===34?(q=ii,G++):(q=t,Xe===0&&Te(gi)),q!==t?(Ce=PE(),Ce!==t?(r.charCodeAt(G)===34?(Ke=ii,G++):(Ke=t,Xe===0&&Te(gi)),Ke!==t?(yt=R,q=fi(Ce),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)),Xe--,R===t&&(q=t,Xe===0&&Te(Or)),R}function PE(){var R,q,Ce;if(R=G,q=[],Ce=cg(),Ce!==t)for(;Ce!==t;)q.push(Ce),Ce=cg();else q=t;return q!==t&&(yt=R,q=ni(q)),R=q,R}function cg(){var R,q,Ce,Ke,Re,ze;return Ls.test(r.charAt(G))?(R=r.charAt(G),G++):(R=t,Xe===0&&Te(pr)),R===t&&(R=G,r.substr(G,2)===Ei?(q=Ei,G+=2):(q=t,Xe===0&&Te(_n)),q!==t&&(yt=R,q=oa()),R=q,R===t&&(R=G,r.substr(G,2)===aA?(q=aA,G+=2):(q=t,Xe===0&&Te(eg)),q!==t&&(yt=R,q=Zn()),R=q,R===t&&(R=G,r.substr(G,2)===AA?(q=AA,G+=2):(q=t,Xe===0&&Te(aa)),q!==t&&(yt=R,q=up()),R=q,R===t&&(R=G,r.substr(G,2)===lA?(q=lA,G+=2):(q=t,Xe===0&&Te(cA)),q!==t&&(yt=R,q=wr()),R=q,R===t&&(R=G,r.substr(G,2)===wl?(q=wl,G+=2):(q=t,Xe===0&&Te(tg)),q!==t&&(yt=R,q=po()),R=q,R===t&&(R=G,r.substr(G,2)===rg?(q=rg,G+=2):(q=t,Xe===0&&Te(gp)),q!==t&&(yt=R,q=fp()),R=q,R===t&&(R=G,r.substr(G,2)===vr?(q=vr,G+=2):(q=t,Xe===0&&Te(se)),q!==t&&(yt=R,q=Co()),R=q,R===t&&(R=G,r.substr(G,2)===Dn?(q=Dn,G+=2):(q=t,Xe===0&&Te(ig)),q!==t&&(yt=R,q=Qt()),R=q,R===t&&(R=G,r.substr(G,2)===Bl?(q=Bl,G+=2):(q=t,Xe===0&&Te(kn)),q!==t?(Ce=hA(),Ce!==t?(Ke=hA(),Ke!==t?(Re=hA(),Re!==t?(ze=hA(),ze!==t?(yt=R,q=$n(Ce,Ke,Re,ze),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)))))))))),R}function hA(){var R;return es.test(r.charAt(G))?(R=r.charAt(G),G++):(R=t,Xe===0&&Te(gt)),R}function Rr(){var R,q;if(Xe++,R=[],At.test(r.charAt(G))?(q=r.charAt(G),G++):(q=t,Xe===0&&Te(an)),q!==t)for(;q!==t;)R.push(q),At.test(r.charAt(G))?(q=r.charAt(G),G++):(q=t,Xe===0&&Te(an));else R=t;return Xe--,R===t&&(q=t,Xe===0&&Te(mo)),R}function DE(){var R,q;if(Xe++,R=[],Tt.test(r.charAt(G))?(q=r.charAt(G),G++):(q=t,Xe===0&&Te(ng)),q!==t)for(;q!==t;)R.push(q),Tt.test(r.charAt(G))?(q=r.charAt(G),G++):(q=t,Xe===0&&Te(ng));else R=t;return Xe--,R===t&&(q=t,Xe===0&&Te(S)),R}function Ks(){var R,q,Ce,Ke,Re,ze;if(R=G,q=Us(),q!==t){for(Ce=[],Ke=G,Re=Rr(),Re===t&&(Re=null),Re!==t?(ze=Us(),ze!==t?(Re=[Re,ze],Ke=Re):(G=Ke,Ke=t)):(G=Ke,Ke=t);Ke!==t;)Ce.push(Ke),Ke=G,Re=Rr(),Re===t&&(Re=null),Re!==t?(ze=Us(),ze!==t?(Re=[Re,ze],Ke=Re):(G=Ke,Ke=t)):(G=Ke,Ke=t);Ce!==t?(q=[q,Ce],R=q):(G=R,R=t)}else G=R,R=t;return R}function Us(){var R;return r.substr(G,2)===Ql?(R=Ql,G+=2):(R=t,Xe===0&&Te(hp)),R===t&&(r.charCodeAt(G)===10?(R=pp,G++):(R=t,Xe===0&&Te(dp)),R===t&&(r.charCodeAt(G)===13?(R=Cp,G++):(R=t,Xe===0&&Te(mp)))),R}let ug=2,pA=0;if(Aa=n(),Aa!==t&&G===r.length)return Aa;throw Aa!==t&&G{"use strict";var wpe=r=>{let e=!1,t=!1,i=!1;for(let n=0;n{if(!(typeof r=="string"||Array.isArray(r)))throw new TypeError("Expected the input to be `string | string[]`");e=Object.assign({pascalCase:!1},e);let t=n=>e.pascalCase?n.charAt(0).toUpperCase()+n.slice(1):n;return Array.isArray(r)?r=r.map(n=>n.trim()).filter(n=>n.length).join("-"):r=r.trim(),r.length===0?"":r.length===1?e.pascalCase?r.toUpperCase():r.toLowerCase():(r!==r.toLowerCase()&&(r=wpe(r)),r=r.replace(/^[_.\- ]+/,"").toLowerCase().replace(/[_.\- ]+(\w|$)/g,(n,s)=>s.toUpperCase()).replace(/\d+(\w|$)/g,n=>n.toUpperCase()),t(r))};KS.exports=T2;KS.exports.default=T2});var M2=w((VXe,Bpe)=>{Bpe.exports=[{name:"AppVeyor",constant:"APPVEYOR",env:"APPVEYOR",pr:"APPVEYOR_PULL_REQUEST_NUMBER"},{name:"Azure Pipelines",constant:"AZURE_PIPELINES",env:"SYSTEM_TEAMFOUNDATIONCOLLECTIONURI",pr:"SYSTEM_PULLREQUEST_PULLREQUESTID"},{name:"Appcircle",constant:"APPCIRCLE",env:"AC_APPCIRCLE"},{name:"Bamboo",constant:"BAMBOO",env:"bamboo_planKey"},{name:"Bitbucket Pipelines",constant:"BITBUCKET",env:"BITBUCKET_COMMIT",pr:"BITBUCKET_PR_ID"},{name:"Bitrise",constant:"BITRISE",env:"BITRISE_IO",pr:"BITRISE_PULL_REQUEST"},{name:"Buddy",constant:"BUDDY",env:"BUDDY_WORKSPACE_ID",pr:"BUDDY_EXECUTION_PULL_REQUEST_ID"},{name:"Buildkite",constant:"BUILDKITE",env:"BUILDKITE",pr:{env:"BUILDKITE_PULL_REQUEST",ne:"false"}},{name:"CircleCI",constant:"CIRCLE",env:"CIRCLECI",pr:"CIRCLE_PULL_REQUEST"},{name:"Cirrus CI",constant:"CIRRUS",env:"CIRRUS_CI",pr:"CIRRUS_PR"},{name:"AWS CodeBuild",constant:"CODEBUILD",env:"CODEBUILD_BUILD_ARN"},{name:"Codefresh",constant:"CODEFRESH",env:"CF_BUILD_ID",pr:{any:["CF_PULL_REQUEST_NUMBER","CF_PULL_REQUEST_ID"]}},{name:"Codeship",constant:"CODESHIP",env:{CI_NAME:"codeship"}},{name:"Drone",constant:"DRONE",env:"DRONE",pr:{DRONE_BUILD_EVENT:"pull_request"}},{name:"dsari",constant:"DSARI",env:"DSARI"},{name:"GitHub Actions",constant:"GITHUB_ACTIONS",env:"GITHUB_ACTIONS",pr:{GITHUB_EVENT_NAME:"pull_request"}},{name:"GitLab CI",constant:"GITLAB",env:"GITLAB_CI",pr:"CI_MERGE_REQUEST_ID"},{name:"GoCD",constant:"GOCD",env:"GO_PIPELINE_LABEL"},{name:"LayerCI",constant:"LAYERCI",env:"LAYERCI",pr:"LAYERCI_PULL_REQUEST"},{name:"Hudson",constant:"HUDSON",env:"HUDSON_URL"},{name:"Jenkins",constant:"JENKINS",env:["JENKINS_URL","BUILD_ID"],pr:{any:["ghprbPullId","CHANGE_ID"]}},{name:"Magnum CI",constant:"MAGNUM",env:"MAGNUM"},{name:"Netlify CI",constant:"NETLIFY",env:"NETLIFY",pr:{env:"PULL_REQUEST",ne:"false"}},{name:"Nevercode",constant:"NEVERCODE",env:"NEVERCODE",pr:{env:"NEVERCODE_PULL_REQUEST",ne:"false"}},{name:"Render",constant:"RENDER",env:"RENDER",pr:{IS_PULL_REQUEST:"true"}},{name:"Sail CI",constant:"SAIL",env:"SAILCI",pr:"SAIL_PULL_REQUEST_NUMBER"},{name:"Semaphore",constant:"SEMAPHORE",env:"SEMAPHORE",pr:"PULL_REQUEST_NUMBER"},{name:"Screwdriver",constant:"SCREWDRIVER",env:"SCREWDRIVER",pr:{env:"SD_PULL_REQUEST",ne:"false"}},{name:"Shippable",constant:"SHIPPABLE",env:"SHIPPABLE",pr:{IS_PULL_REQUEST:"true"}},{name:"Solano CI",constant:"SOLANO",env:"TDDIUM",pr:"TDDIUM_PR_ID"},{name:"Strider CD",constant:"STRIDER",env:"STRIDER"},{name:"TaskCluster",constant:"TASKCLUSTER",env:["TASK_ID","RUN_ID"]},{name:"TeamCity",constant:"TEAMCITY",env:"TEAMCITY_VERSION"},{name:"Travis CI",constant:"TRAVIS",env:"TRAVIS",pr:{env:"TRAVIS_PULL_REQUEST",ne:"false"}},{name:"Vercel",constant:"VERCEL",env:"NOW_BUILDER"},{name:"Visual Studio App Center",constant:"APPCENTER",env:"APPCENTER_BUILD_ID"}]});var Vl=w(On=>{"use strict";var U2=M2(),Qo=process.env;Object.defineProperty(On,"_vendors",{value:U2.map(function(r){return r.constant})});On.name=null;On.isPR=null;U2.forEach(function(r){let t=(Array.isArray(r.env)?r.env:[r.env]).every(function(i){return K2(i)});if(On[r.constant]=t,t)switch(On.name=r.name,typeof r.pr){case"string":On.isPR=!!Qo[r.pr];break;case"object":"env"in r.pr?On.isPR=r.pr.env in Qo&&Qo[r.pr.env]!==r.pr.ne:"any"in r.pr?On.isPR=r.pr.any.some(function(i){return!!Qo[i]}):On.isPR=K2(r.pr);break;default:On.isPR=null}});On.isCI=!!(Qo.CI||Qo.CONTINUOUS_INTEGRATION||Qo.BUILD_NUMBER||Qo.RUN_ID||On.name);function K2(r){return typeof r=="string"?!!Qo[r]:Object.keys(r).every(function(e){return Qo[e]===r[e]})}});var gn={};ut(gn,{KeyRelationship:()=>Xl,applyCascade:()=>zp,base64RegExp:()=>q2,colorStringAlphaRegExp:()=>j2,colorStringRegExp:()=>Y2,computeKey:()=>BA,getPrintable:()=>Vr,hasExactLength:()=>X2,hasForbiddenKeys:()=>tde,hasKeyRelationship:()=>JS,hasMaxLength:()=>Mpe,hasMinLength:()=>Ope,hasMutuallyExclusiveKeys:()=>rde,hasRequiredKeys:()=>ede,hasUniqueItems:()=>Kpe,isArray:()=>Ppe,isAtLeast:()=>Gpe,isAtMost:()=>Ype,isBase64:()=>Zpe,isBoolean:()=>Spe,isDate:()=>xpe,isDict:()=>kpe,isEnum:()=>Wi,isHexColor:()=>_pe,isISO8601:()=>Xpe,isInExclusiveRange:()=>qpe,isInInclusiveRange:()=>jpe,isInstanceOf:()=>Fpe,isInteger:()=>Jpe,isJSON:()=>$pe,isLiteral:()=>Qpe,isLowerCase:()=>Wpe,isNegative:()=>Upe,isNullable:()=>Tpe,isNumber:()=>vpe,isObject:()=>Rpe,isOneOf:()=>Npe,isOptional:()=>Lpe,isPositive:()=>Hpe,isString:()=>Wp,isTuple:()=>Dpe,isUUID4:()=>Vpe,isUnknown:()=>V2,isUpperCase:()=>zpe,iso8601RegExp:()=>qS,makeCoercionFn:()=>_l,makeSetter:()=>z2,makeTrait:()=>W2,makeValidator:()=>bt,matchesRegExp:()=>Vp,plural:()=>EI,pushError:()=>pt,simpleKeyRegExp:()=>G2,uuid4RegExp:()=>J2});function bt({test:r}){return W2(r)()}function Vr(r){return r===null?"null":r===void 0?"undefined":r===""?"an empty string":JSON.stringify(r)}function BA(r,e){var t,i,n;return typeof e=="number"?`${(t=r==null?void 0:r.p)!==null&&t!==void 0?t:"."}[${e}]`:G2.test(e)?`${(i=r==null?void 0:r.p)!==null&&i!==void 0?i:""}.${e}`:`${(n=r==null?void 0:r.p)!==null&&n!==void 0?n:"."}[${JSON.stringify(e)}]`}function _l(r,e){return t=>{let i=r[e];return r[e]=t,_l(r,e).bind(null,i)}}function z2(r,e){return t=>{r[e]=t}}function EI(r,e,t){return r===1?e:t}function pt({errors:r,p:e}={},t){return r==null||r.push(`${e!=null?e:"."}: ${t}`),!1}function Qpe(r){return bt({test:(e,t)=>e!==r?pt(t,`Expected a literal (got ${Vr(r)})`):!0})}function Wi(r){let e=Array.isArray(r)?r:Object.values(r),t=new Set(e);return bt({test:(i,n)=>t.has(i)?!0:pt(n,`Expected a valid enumeration value (got ${Vr(i)})`)})}var G2,Y2,j2,q2,J2,qS,W2,V2,Wp,bpe,Spe,vpe,xpe,Ppe,Dpe,kpe,Rpe,Fpe,Npe,zp,Lpe,Tpe,Ope,Mpe,X2,Kpe,Upe,Hpe,Gpe,Ype,jpe,qpe,Jpe,Vp,Wpe,zpe,Vpe,Xpe,_pe,Zpe,$pe,ede,tde,rde,Xl,ide,JS,ns=Yue(()=>{G2=/^[a-zA-Z_][a-zA-Z0-9_]*$/,Y2=/^#[0-9a-f]{6}$/i,j2=/^#[0-9a-f]{6}([0-9a-f]{2})?$/i,q2=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/,J2=/^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}$/i,qS=/^(?:[1-9]\d{3}(-?)(?:(?:0[1-9]|1[0-2])\1(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])\1(?:29|30)|(?:0[13578]|1[02])(?:\1)31|00[1-9]|0[1-9]\d|[12]\d{2}|3(?:[0-5]\d|6[0-5]))|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)(?:(-?)02(?:\2)29|-?366))T(?:[01]\d|2[0-3])(:?)[0-5]\d(?:\3[0-5]\d)?(?:Z|[+-][01]\d(?:\3[0-5]\d)?)$/,W2=r=>()=>r;V2=()=>bt({test:(r,e)=>!0});Wp=()=>bt({test:(r,e)=>typeof r!="string"?pt(e,`Expected a string (got ${Vr(r)})`):!0});bpe=new Map([["true",!0],["True",!0],["1",!0],[1,!0],["false",!1],["False",!1],["0",!1],[0,!1]]),Spe=()=>bt({test:(r,e)=>{var t;if(typeof r!="boolean"){if(typeof(e==null?void 0:e.coercions)<"u"){if(typeof(e==null?void 0:e.coercion)>"u")return pt(e,"Unbound coercion result");let i=bpe.get(r);if(typeof i<"u")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return pt(e,`Expected a boolean (got ${Vr(r)})`)}return!0}}),vpe=()=>bt({test:(r,e)=>{var t;if(typeof r!="number"){if(typeof(e==null?void 0:e.coercions)<"u"){if(typeof(e==null?void 0:e.coercion)>"u")return pt(e,"Unbound coercion result");let i;if(typeof r=="string"){let n;try{n=JSON.parse(r)}catch{}if(typeof n=="number")if(JSON.stringify(n)===r)i=n;else return pt(e,`Received a number that can't be safely represented by the runtime (${r})`)}if(typeof i<"u")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return pt(e,`Expected a number (got ${Vr(r)})`)}return!0}}),xpe=()=>bt({test:(r,e)=>{var t;if(!(r instanceof Date)){if(typeof(e==null?void 0:e.coercions)<"u"){if(typeof(e==null?void 0:e.coercion)>"u")return pt(e,"Unbound coercion result");let i;if(typeof r=="string"&&qS.test(r))i=new Date(r);else{let n;if(typeof r=="string"){let s;try{s=JSON.parse(r)}catch{}typeof s=="number"&&(n=s)}else typeof r=="number"&&(n=r);if(typeof n<"u")if(Number.isSafeInteger(n)||!Number.isSafeInteger(n*1e3))i=new Date(n*1e3);else return pt(e,`Received a timestamp that can't be safely represented by the runtime (${r})`)}if(typeof i<"u")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return pt(e,`Expected a date (got ${Vr(r)})`)}return!0}}),Ppe=(r,{delimiter:e}={})=>bt({test:(t,i)=>{var n;if(typeof t=="string"&&typeof e<"u"&&typeof(i==null?void 0:i.coercions)<"u"){if(typeof(i==null?void 0:i.coercion)>"u")return pt(i,"Unbound coercion result");t=t.split(e),i.coercions.push([(n=i.p)!==null&&n!==void 0?n:".",i.coercion.bind(null,t)])}if(!Array.isArray(t))return pt(i,`Expected an array (got ${Vr(t)})`);let s=!0;for(let o=0,a=t.length;o{let t=X2(r.length);return bt({test:(i,n)=>{var s;if(typeof i=="string"&&typeof e<"u"&&typeof(n==null?void 0:n.coercions)<"u"){if(typeof(n==null?void 0:n.coercion)>"u")return pt(n,"Unbound coercion result");i=i.split(e),n.coercions.push([(s=n.p)!==null&&s!==void 0?s:".",n.coercion.bind(null,i)])}if(!Array.isArray(i))return pt(n,`Expected a tuple (got ${Vr(i)})`);let o=t(i,Object.assign({},n));for(let a=0,l=i.length;abt({test:(t,i)=>{if(typeof t!="object"||t===null)return pt(i,`Expected an object (got ${Vr(t)})`);let n=Object.keys(t),s=!0;for(let o=0,a=n.length;o{let t=Object.keys(r);return bt({test:(i,n)=>{if(typeof i!="object"||i===null)return pt(n,`Expected an object (got ${Vr(i)})`);let s=new Set([...t,...Object.keys(i)]),o={},a=!0;for(let l of s){if(l==="constructor"||l==="__proto__")a=pt(Object.assign(Object.assign({},n),{p:BA(n,l)}),"Unsafe property name");else{let c=Object.prototype.hasOwnProperty.call(r,l)?r[l]:void 0,u=Object.prototype.hasOwnProperty.call(i,l)?i[l]:void 0;typeof c<"u"?a=c(u,Object.assign(Object.assign({},n),{p:BA(n,l),coercion:_l(i,l)}))&&a:e===null?a=pt(Object.assign(Object.assign({},n),{p:BA(n,l)}),`Extraneous property (got ${Vr(u)})`):Object.defineProperty(o,l,{enumerable:!0,get:()=>u,set:z2(i,l)})}if(!a&&(n==null?void 0:n.errors)==null)break}return e!==null&&(a||(n==null?void 0:n.errors)!=null)&&(a=e(o,n)&&a),a}})},Fpe=r=>bt({test:(e,t)=>e instanceof r?!0:pt(t,`Expected an instance of ${r.name} (got ${Vr(e)})`)}),Npe=(r,{exclusive:e=!1}={})=>bt({test:(t,i)=>{var n,s,o;let a=[],l=typeof(i==null?void 0:i.errors)<"u"?[]:void 0;for(let c=0,u=r.length;c1?pt(i,`Expected to match exactly a single predicate (matched ${a.join(", ")})`):(o=i==null?void 0:i.errors)===null||o===void 0||o.push(...l),!1}}),zp=(r,e)=>bt({test:(t,i)=>{var n,s;let o={value:t},a=typeof(i==null?void 0:i.coercions)<"u"?_l(o,"value"):void 0,l=typeof(i==null?void 0:i.coercions)<"u"?[]:void 0;if(!r(t,Object.assign(Object.assign({},i),{coercion:a,coercions:l})))return!1;let c=[];if(typeof l<"u")for(let[,u]of l)c.push(u());try{if(typeof(i==null?void 0:i.coercions)<"u"){if(o.value!==t){if(typeof(i==null?void 0:i.coercion)>"u")return pt(i,"Unbound coercion result");i.coercions.push([(n=i.p)!==null&&n!==void 0?n:".",i.coercion.bind(null,o.value)])}(s=i==null?void 0:i.coercions)===null||s===void 0||s.push(...l)}return e.every(u=>u(o.value,i))}finally{for(let u of c)u()}}}),Lpe=r=>bt({test:(e,t)=>typeof e>"u"?!0:r(e,t)}),Tpe=r=>bt({test:(e,t)=>e===null?!0:r(e,t)}),Ope=r=>bt({test:(e,t)=>e.length>=r?!0:pt(t,`Expected to have a length of at least ${r} elements (got ${e.length})`)}),Mpe=r=>bt({test:(e,t)=>e.length<=r?!0:pt(t,`Expected to have a length of at most ${r} elements (got ${e.length})`)}),X2=r=>bt({test:(e,t)=>e.length!==r?pt(t,`Expected to have a length of exactly ${r} elements (got ${e.length})`):!0}),Kpe=({map:r}={})=>bt({test:(e,t)=>{let i=new Set,n=new Set;for(let s=0,o=e.length;sbt({test:(r,e)=>r<=0?!0:pt(e,`Expected to be negative (got ${r})`)}),Hpe=()=>bt({test:(r,e)=>r>=0?!0:pt(e,`Expected to be positive (got ${r})`)}),Gpe=r=>bt({test:(e,t)=>e>=r?!0:pt(t,`Expected to be at least ${r} (got ${e})`)}),Ype=r=>bt({test:(e,t)=>e<=r?!0:pt(t,`Expected to be at most ${r} (got ${e})`)}),jpe=(r,e)=>bt({test:(t,i)=>t>=r&&t<=e?!0:pt(i,`Expected to be in the [${r}; ${e}] range (got ${t})`)}),qpe=(r,e)=>bt({test:(t,i)=>t>=r&&tbt({test:(e,t)=>e!==Math.round(e)?pt(t,`Expected to be an integer (got ${e})`):Number.isSafeInteger(e)?!0:pt(t,`Expected to be a safe integer (got ${e})`)}),Vp=r=>bt({test:(e,t)=>r.test(e)?!0:pt(t,`Expected to match the pattern ${r.toString()} (got ${Vr(e)})`)}),Wpe=()=>bt({test:(r,e)=>r!==r.toLowerCase()?pt(e,`Expected to be all-lowercase (got ${r})`):!0}),zpe=()=>bt({test:(r,e)=>r!==r.toUpperCase()?pt(e,`Expected to be all-uppercase (got ${r})`):!0}),Vpe=()=>bt({test:(r,e)=>J2.test(r)?!0:pt(e,`Expected to be a valid UUID v4 (got ${Vr(r)})`)}),Xpe=()=>bt({test:(r,e)=>qS.test(r)?!1:pt(e,`Expected to be a valid ISO 8601 date string (got ${Vr(r)})`)}),_pe=({alpha:r=!1})=>bt({test:(e,t)=>(r?Y2.test(e):j2.test(e))?!0:pt(t,`Expected to be a valid hexadecimal color string (got ${Vr(e)})`)}),Zpe=()=>bt({test:(r,e)=>q2.test(r)?!0:pt(e,`Expected to be a valid base 64 string (got ${Vr(r)})`)}),$pe=(r=V2())=>bt({test:(e,t)=>{let i;try{i=JSON.parse(e)}catch{return pt(t,`Expected to be a valid JSON string (got ${Vr(e)})`)}return r(i,t)}}),ede=r=>{let e=new Set(r);return bt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)||s.push(o);return s.length>0?pt(i,`Missing required ${EI(s.length,"property","properties")} ${s.map(o=>`"${o}"`).join(", ")}`):!0}})},tde=r=>{let e=new Set(r);return bt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)&&s.push(o);return s.length>0?pt(i,`Forbidden ${EI(s.length,"property","properties")} ${s.map(o=>`"${o}"`).join(", ")}`):!0}})},rde=r=>{let e=new Set(r);return bt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)&&s.push(o);return s.length>1?pt(i,`Mutually exclusive properties ${s.map(o=>`"${o}"`).join(", ")}`):!0}})};(function(r){r.Forbids="Forbids",r.Requires="Requires"})(Xl||(Xl={}));ide={[Xl.Forbids]:{expect:!1,message:"forbids using"},[Xl.Requires]:{expect:!0,message:"requires using"}},JS=(r,e,t,{ignore:i=[]}={})=>{let n=new Set(i),s=new Set(t),o=ide[e];return bt({test:(a,l)=>{let c=new Set(Object.keys(a));if(!c.has(r)||n.has(a[r]))return!0;let u=[];for(let g of s)(c.has(g)&&!n.has(a[g]))!==o.expect&&u.push(g);return u.length>=1?pt(l,`Property "${r}" ${o.message} ${EI(u.length,"property","properties")} ${u.map(g=>`"${g}"`).join(", ")}`):!0}})}});var fH=w((V_e,gH)=>{"use strict";gH.exports=(r,...e)=>new Promise(t=>{t(r(...e))})});var Tg=w((X_e,ev)=>{"use strict";var Ide=fH(),hH=r=>{if(r<1)throw new TypeError("Expected `concurrency` to be a number from 1 and up");let e=[],t=0,i=()=>{t--,e.length>0&&e.shift()()},n=(a,l,...c)=>{t++;let u=Ide(a,...c);l(u),u.then(i,i)},s=(a,l,...c)=>{tnew Promise(c=>s(a,c,...l));return Object.defineProperties(o,{activeCount:{get:()=>t},pendingCount:{get:()=>e.length}}),o};ev.exports=hH;ev.exports.default=hH});var ed=w((Z_e,pH)=>{var yde="2.0.0",wde=Number.MAX_SAFE_INTEGER||9007199254740991,Bde=16;pH.exports={SEMVER_SPEC_VERSION:yde,MAX_LENGTH:256,MAX_SAFE_INTEGER:wde,MAX_SAFE_COMPONENT_LENGTH:Bde}});var td=w(($_e,dH)=>{var Qde=typeof process=="object"&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...r)=>console.error("SEMVER",...r):()=>{};dH.exports=Qde});var Zl=w((bA,CH)=>{var{MAX_SAFE_COMPONENT_LENGTH:tv}=ed(),bde=td();bA=CH.exports={};var Sde=bA.re=[],$e=bA.src=[],et=bA.t={},vde=0,St=(r,e,t)=>{let i=vde++;bde(i,e),et[r]=i,$e[i]=e,Sde[i]=new RegExp(e,t?"g":void 0)};St("NUMERICIDENTIFIER","0|[1-9]\\d*");St("NUMERICIDENTIFIERLOOSE","[0-9]+");St("NONNUMERICIDENTIFIER","\\d*[a-zA-Z-][a-zA-Z0-9-]*");St("MAINVERSION",`(${$e[et.NUMERICIDENTIFIER]})\\.(${$e[et.NUMERICIDENTIFIER]})\\.(${$e[et.NUMERICIDENTIFIER]})`);St("MAINVERSIONLOOSE",`(${$e[et.NUMERICIDENTIFIERLOOSE]})\\.(${$e[et.NUMERICIDENTIFIERLOOSE]})\\.(${$e[et.NUMERICIDENTIFIERLOOSE]})`);St("PRERELEASEIDENTIFIER",`(?:${$e[et.NUMERICIDENTIFIER]}|${$e[et.NONNUMERICIDENTIFIER]})`);St("PRERELEASEIDENTIFIERLOOSE",`(?:${$e[et.NUMERICIDENTIFIERLOOSE]}|${$e[et.NONNUMERICIDENTIFIER]})`);St("PRERELEASE",`(?:-(${$e[et.PRERELEASEIDENTIFIER]}(?:\\.${$e[et.PRERELEASEIDENTIFIER]})*))`);St("PRERELEASELOOSE",`(?:-?(${$e[et.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${$e[et.PRERELEASEIDENTIFIERLOOSE]})*))`);St("BUILDIDENTIFIER","[0-9A-Za-z-]+");St("BUILD",`(?:\\+(${$e[et.BUILDIDENTIFIER]}(?:\\.${$e[et.BUILDIDENTIFIER]})*))`);St("FULLPLAIN",`v?${$e[et.MAINVERSION]}${$e[et.PRERELEASE]}?${$e[et.BUILD]}?`);St("FULL",`^${$e[et.FULLPLAIN]}$`);St("LOOSEPLAIN",`[v=\\s]*${$e[et.MAINVERSIONLOOSE]}${$e[et.PRERELEASELOOSE]}?${$e[et.BUILD]}?`);St("LOOSE",`^${$e[et.LOOSEPLAIN]}$`);St("GTLT","((?:<|>)?=?)");St("XRANGEIDENTIFIERLOOSE",`${$e[et.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);St("XRANGEIDENTIFIER",`${$e[et.NUMERICIDENTIFIER]}|x|X|\\*`);St("XRANGEPLAIN",`[v=\\s]*(${$e[et.XRANGEIDENTIFIER]})(?:\\.(${$e[et.XRANGEIDENTIFIER]})(?:\\.(${$e[et.XRANGEIDENTIFIER]})(?:${$e[et.PRERELEASE]})?${$e[et.BUILD]}?)?)?`);St("XRANGEPLAINLOOSE",`[v=\\s]*(${$e[et.XRANGEIDENTIFIERLOOSE]})(?:\\.(${$e[et.XRANGEIDENTIFIERLOOSE]})(?:\\.(${$e[et.XRANGEIDENTIFIERLOOSE]})(?:${$e[et.PRERELEASELOOSE]})?${$e[et.BUILD]}?)?)?`);St("XRANGE",`^${$e[et.GTLT]}\\s*${$e[et.XRANGEPLAIN]}$`);St("XRANGELOOSE",`^${$e[et.GTLT]}\\s*${$e[et.XRANGEPLAINLOOSE]}$`);St("COERCE",`(^|[^\\d])(\\d{1,${tv}})(?:\\.(\\d{1,${tv}}))?(?:\\.(\\d{1,${tv}}))?(?:$|[^\\d])`);St("COERCERTL",$e[et.COERCE],!0);St("LONETILDE","(?:~>?)");St("TILDETRIM",`(\\s*)${$e[et.LONETILDE]}\\s+`,!0);bA.tildeTrimReplace="$1~";St("TILDE",`^${$e[et.LONETILDE]}${$e[et.XRANGEPLAIN]}$`);St("TILDELOOSE",`^${$e[et.LONETILDE]}${$e[et.XRANGEPLAINLOOSE]}$`);St("LONECARET","(?:\\^)");St("CARETTRIM",`(\\s*)${$e[et.LONECARET]}\\s+`,!0);bA.caretTrimReplace="$1^";St("CARET",`^${$e[et.LONECARET]}${$e[et.XRANGEPLAIN]}$`);St("CARETLOOSE",`^${$e[et.LONECARET]}${$e[et.XRANGEPLAINLOOSE]}$`);St("COMPARATORLOOSE",`^${$e[et.GTLT]}\\s*(${$e[et.LOOSEPLAIN]})$|^$`);St("COMPARATOR",`^${$e[et.GTLT]}\\s*(${$e[et.FULLPLAIN]})$|^$`);St("COMPARATORTRIM",`(\\s*)${$e[et.GTLT]}\\s*(${$e[et.LOOSEPLAIN]}|${$e[et.XRANGEPLAIN]})`,!0);bA.comparatorTrimReplace="$1$2$3";St("HYPHENRANGE",`^\\s*(${$e[et.XRANGEPLAIN]})\\s+-\\s+(${$e[et.XRANGEPLAIN]})\\s*$`);St("HYPHENRANGELOOSE",`^\\s*(${$e[et.XRANGEPLAINLOOSE]})\\s+-\\s+(${$e[et.XRANGEPLAINLOOSE]})\\s*$`);St("STAR","(<|>)?=?\\s*\\*");St("GTE0","^\\s*>=\\s*0.0.0\\s*$");St("GTE0PRE","^\\s*>=\\s*0.0.0-0\\s*$")});var rd=w((eZe,mH)=>{var xde=["includePrerelease","loose","rtl"],Pde=r=>r?typeof r!="object"?{loose:!0}:xde.filter(e=>r[e]).reduce((e,t)=>(e[t]=!0,e),{}):{};mH.exports=Pde});var bI=w((tZe,yH)=>{var EH=/^[0-9]+$/,IH=(r,e)=>{let t=EH.test(r),i=EH.test(e);return t&&i&&(r=+r,e=+e),r===e?0:t&&!i?-1:i&&!t?1:rIH(e,r);yH.exports={compareIdentifiers:IH,rcompareIdentifiers:Dde}});var Li=w((rZe,bH)=>{var SI=td(),{MAX_LENGTH:wH,MAX_SAFE_INTEGER:vI}=ed(),{re:BH,t:QH}=Zl(),kde=rd(),{compareIdentifiers:id}=bI(),Un=class{constructor(e,t){if(t=kde(t),e instanceof Un){if(e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease)return e;e=e.version}else if(typeof e!="string")throw new TypeError(`Invalid Version: ${e}`);if(e.length>wH)throw new TypeError(`version is longer than ${wH} characters`);SI("SemVer",e,t),this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease;let i=e.trim().match(t.loose?BH[QH.LOOSE]:BH[QH.FULL]);if(!i)throw new TypeError(`Invalid Version: ${e}`);if(this.raw=e,this.major=+i[1],this.minor=+i[2],this.patch=+i[3],this.major>vI||this.major<0)throw new TypeError("Invalid major version");if(this.minor>vI||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>vI||this.patch<0)throw new TypeError("Invalid patch version");i[4]?this.prerelease=i[4].split(".").map(n=>{if(/^[0-9]+$/.test(n)){let s=+n;if(s>=0&&s=0;)typeof this.prerelease[i]=="number"&&(this.prerelease[i]++,i=-2);i===-1&&this.prerelease.push(0)}t&&(this.prerelease[0]===t?isNaN(this.prerelease[1])&&(this.prerelease=[t,0]):this.prerelease=[t,0]);break;default:throw new Error(`invalid increment argument: ${e}`)}return this.format(),this.raw=this.version,this}};bH.exports=Un});var $l=w((iZe,PH)=>{var{MAX_LENGTH:Rde}=ed(),{re:SH,t:vH}=Zl(),xH=Li(),Fde=rd(),Nde=(r,e)=>{if(e=Fde(e),r instanceof xH)return r;if(typeof r!="string"||r.length>Rde||!(e.loose?SH[vH.LOOSE]:SH[vH.FULL]).test(r))return null;try{return new xH(r,e)}catch{return null}};PH.exports=Nde});var kH=w((nZe,DH)=>{var Lde=$l(),Tde=(r,e)=>{let t=Lde(r,e);return t?t.version:null};DH.exports=Tde});var FH=w((sZe,RH)=>{var Ode=$l(),Mde=(r,e)=>{let t=Ode(r.trim().replace(/^[=v]+/,""),e);return t?t.version:null};RH.exports=Mde});var LH=w((oZe,NH)=>{var Kde=Li(),Ude=(r,e,t,i)=>{typeof t=="string"&&(i=t,t=void 0);try{return new Kde(r,t).inc(e,i).version}catch{return null}};NH.exports=Ude});var ss=w((aZe,OH)=>{var TH=Li(),Hde=(r,e,t)=>new TH(r,t).compare(new TH(e,t));OH.exports=Hde});var xI=w((AZe,MH)=>{var Gde=ss(),Yde=(r,e,t)=>Gde(r,e,t)===0;MH.exports=Yde});var HH=w((lZe,UH)=>{var KH=$l(),jde=xI(),qde=(r,e)=>{if(jde(r,e))return null;{let t=KH(r),i=KH(e),n=t.prerelease.length||i.prerelease.length,s=n?"pre":"",o=n?"prerelease":"";for(let a in t)if((a==="major"||a==="minor"||a==="patch")&&t[a]!==i[a])return s+a;return o}};UH.exports=qde});var YH=w((cZe,GH)=>{var Jde=Li(),Wde=(r,e)=>new Jde(r,e).major;GH.exports=Wde});var qH=w((uZe,jH)=>{var zde=Li(),Vde=(r,e)=>new zde(r,e).minor;jH.exports=Vde});var WH=w((gZe,JH)=>{var Xde=Li(),_de=(r,e)=>new Xde(r,e).patch;JH.exports=_de});var VH=w((fZe,zH)=>{var Zde=$l(),$de=(r,e)=>{let t=Zde(r,e);return t&&t.prerelease.length?t.prerelease:null};zH.exports=$de});var _H=w((hZe,XH)=>{var eCe=ss(),tCe=(r,e,t)=>eCe(e,r,t);XH.exports=tCe});var $H=w((pZe,ZH)=>{var rCe=ss(),iCe=(r,e)=>rCe(r,e,!0);ZH.exports=iCe});var PI=w((dZe,tG)=>{var eG=Li(),nCe=(r,e,t)=>{let i=new eG(r,t),n=new eG(e,t);return i.compare(n)||i.compareBuild(n)};tG.exports=nCe});var iG=w((CZe,rG)=>{var sCe=PI(),oCe=(r,e)=>r.sort((t,i)=>sCe(t,i,e));rG.exports=oCe});var sG=w((mZe,nG)=>{var aCe=PI(),ACe=(r,e)=>r.sort((t,i)=>aCe(i,t,e));nG.exports=ACe});var nd=w((EZe,oG)=>{var lCe=ss(),cCe=(r,e,t)=>lCe(r,e,t)>0;oG.exports=cCe});var DI=w((IZe,aG)=>{var uCe=ss(),gCe=(r,e,t)=>uCe(r,e,t)<0;aG.exports=gCe});var rv=w((yZe,AG)=>{var fCe=ss(),hCe=(r,e,t)=>fCe(r,e,t)!==0;AG.exports=hCe});var kI=w((wZe,lG)=>{var pCe=ss(),dCe=(r,e,t)=>pCe(r,e,t)>=0;lG.exports=dCe});var RI=w((BZe,cG)=>{var CCe=ss(),mCe=(r,e,t)=>CCe(r,e,t)<=0;cG.exports=mCe});var iv=w((QZe,uG)=>{var ECe=xI(),ICe=rv(),yCe=nd(),wCe=kI(),BCe=DI(),QCe=RI(),bCe=(r,e,t,i)=>{switch(e){case"===":return typeof r=="object"&&(r=r.version),typeof t=="object"&&(t=t.version),r===t;case"!==":return typeof r=="object"&&(r=r.version),typeof t=="object"&&(t=t.version),r!==t;case"":case"=":case"==":return ECe(r,t,i);case"!=":return ICe(r,t,i);case">":return yCe(r,t,i);case">=":return wCe(r,t,i);case"<":return BCe(r,t,i);case"<=":return QCe(r,t,i);default:throw new TypeError(`Invalid operator: ${e}`)}};uG.exports=bCe});var fG=w((bZe,gG)=>{var SCe=Li(),vCe=$l(),{re:FI,t:NI}=Zl(),xCe=(r,e)=>{if(r instanceof SCe)return r;if(typeof r=="number"&&(r=String(r)),typeof r!="string")return null;e=e||{};let t=null;if(!e.rtl)t=r.match(FI[NI.COERCE]);else{let i;for(;(i=FI[NI.COERCERTL].exec(r))&&(!t||t.index+t[0].length!==r.length);)(!t||i.index+i[0].length!==t.index+t[0].length)&&(t=i),FI[NI.COERCERTL].lastIndex=i.index+i[1].length+i[2].length;FI[NI.COERCERTL].lastIndex=-1}return t===null?null:vCe(`${t[2]}.${t[3]||"0"}.${t[4]||"0"}`,e)};gG.exports=xCe});var pG=w((SZe,hG)=>{"use strict";hG.exports=function(r){r.prototype[Symbol.iterator]=function*(){for(let e=this.head;e;e=e.next)yield e.value}}});var sd=w((vZe,dG)=>{"use strict";dG.exports=Ht;Ht.Node=ec;Ht.create=Ht;function Ht(r){var e=this;if(e instanceof Ht||(e=new Ht),e.tail=null,e.head=null,e.length=0,r&&typeof r.forEach=="function")r.forEach(function(n){e.push(n)});else if(arguments.length>0)for(var t=0,i=arguments.length;t1)t=e;else if(this.head)i=this.head.next,t=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;i!==null;n++)t=r(t,i.value,n),i=i.next;return t};Ht.prototype.reduceReverse=function(r,e){var t,i=this.tail;if(arguments.length>1)t=e;else if(this.tail)i=this.tail.prev,t=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=this.length-1;i!==null;n--)t=r(t,i.value,n),i=i.prev;return t};Ht.prototype.toArray=function(){for(var r=new Array(this.length),e=0,t=this.head;t!==null;e++)r[e]=t.value,t=t.next;return r};Ht.prototype.toArrayReverse=function(){for(var r=new Array(this.length),e=0,t=this.tail;t!==null;e++)r[e]=t.value,t=t.prev;return r};Ht.prototype.slice=function(r,e){e=e||this.length,e<0&&(e+=this.length),r=r||0,r<0&&(r+=this.length);var t=new Ht;if(ethis.length&&(e=this.length);for(var i=0,n=this.head;n!==null&&ithis.length&&(e=this.length);for(var i=this.length,n=this.tail;n!==null&&i>e;i--)n=n.prev;for(;n!==null&&i>r;i--,n=n.prev)t.push(n.value);return t};Ht.prototype.splice=function(r,e,...t){r>this.length&&(r=this.length-1),r<0&&(r=this.length+r);for(var i=0,n=this.head;n!==null&&i{"use strict";var RCe=sd(),tc=Symbol("max"),Ia=Symbol("length"),Og=Symbol("lengthCalculator"),ad=Symbol("allowStale"),rc=Symbol("maxAge"),Ea=Symbol("dispose"),CG=Symbol("noDisposeOnSet"),di=Symbol("lruList"),Ws=Symbol("cache"),EG=Symbol("updateAgeOnGet"),nv=()=>1,ov=class{constructor(e){if(typeof e=="number"&&(e={max:e}),e||(e={}),e.max&&(typeof e.max!="number"||e.max<0))throw new TypeError("max must be a non-negative number");let t=this[tc]=e.max||1/0,i=e.length||nv;if(this[Og]=typeof i!="function"?nv:i,this[ad]=e.stale||!1,e.maxAge&&typeof e.maxAge!="number")throw new TypeError("maxAge must be a number");this[rc]=e.maxAge||0,this[Ea]=e.dispose,this[CG]=e.noDisposeOnSet||!1,this[EG]=e.updateAgeOnGet||!1,this.reset()}set max(e){if(typeof e!="number"||e<0)throw new TypeError("max must be a non-negative number");this[tc]=e||1/0,od(this)}get max(){return this[tc]}set allowStale(e){this[ad]=!!e}get allowStale(){return this[ad]}set maxAge(e){if(typeof e!="number")throw new TypeError("maxAge must be a non-negative number");this[rc]=e,od(this)}get maxAge(){return this[rc]}set lengthCalculator(e){typeof e!="function"&&(e=nv),e!==this[Og]&&(this[Og]=e,this[Ia]=0,this[di].forEach(t=>{t.length=this[Og](t.value,t.key),this[Ia]+=t.length})),od(this)}get lengthCalculator(){return this[Og]}get length(){return this[Ia]}get itemCount(){return this[di].length}rforEach(e,t){t=t||this;for(let i=this[di].tail;i!==null;){let n=i.prev;mG(this,e,i,t),i=n}}forEach(e,t){t=t||this;for(let i=this[di].head;i!==null;){let n=i.next;mG(this,e,i,t),i=n}}keys(){return this[di].toArray().map(e=>e.key)}values(){return this[di].toArray().map(e=>e.value)}reset(){this[Ea]&&this[di]&&this[di].length&&this[di].forEach(e=>this[Ea](e.key,e.value)),this[Ws]=new Map,this[di]=new RCe,this[Ia]=0}dump(){return this[di].map(e=>LI(this,e)?!1:{k:e.key,v:e.value,e:e.now+(e.maxAge||0)}).toArray().filter(e=>e)}dumpLru(){return this[di]}set(e,t,i){if(i=i||this[rc],i&&typeof i!="number")throw new TypeError("maxAge must be a number");let n=i?Date.now():0,s=this[Og](t,e);if(this[Ws].has(e)){if(s>this[tc])return Mg(this,this[Ws].get(e)),!1;let l=this[Ws].get(e).value;return this[Ea]&&(this[CG]||this[Ea](e,l.value)),l.now=n,l.maxAge=i,l.value=t,this[Ia]+=s-l.length,l.length=s,this.get(e),od(this),!0}let o=new av(e,t,s,n,i);return o.length>this[tc]?(this[Ea]&&this[Ea](e,t),!1):(this[Ia]+=o.length,this[di].unshift(o),this[Ws].set(e,this[di].head),od(this),!0)}has(e){if(!this[Ws].has(e))return!1;let t=this[Ws].get(e).value;return!LI(this,t)}get(e){return sv(this,e,!0)}peek(e){return sv(this,e,!1)}pop(){let e=this[di].tail;return e?(Mg(this,e),e.value):null}del(e){Mg(this,this[Ws].get(e))}load(e){this.reset();let t=Date.now();for(let i=e.length-1;i>=0;i--){let n=e[i],s=n.e||0;if(s===0)this.set(n.k,n.v);else{let o=s-t;o>0&&this.set(n.k,n.v,o)}}}prune(){this[Ws].forEach((e,t)=>sv(this,t,!1))}},sv=(r,e,t)=>{let i=r[Ws].get(e);if(i){let n=i.value;if(LI(r,n)){if(Mg(r,i),!r[ad])return}else t&&(r[EG]&&(i.value.now=Date.now()),r[di].unshiftNode(i));return n.value}},LI=(r,e)=>{if(!e||!e.maxAge&&!r[rc])return!1;let t=Date.now()-e.now;return e.maxAge?t>e.maxAge:r[rc]&&t>r[rc]},od=r=>{if(r[Ia]>r[tc])for(let e=r[di].tail;r[Ia]>r[tc]&&e!==null;){let t=e.prev;Mg(r,e),e=t}},Mg=(r,e)=>{if(e){let t=e.value;r[Ea]&&r[Ea](t.key,t.value),r[Ia]-=t.length,r[Ws].delete(t.key),r[di].removeNode(e)}},av=class{constructor(e,t,i,n,s){this.key=e,this.value=t,this.length=i,this.now=n,this.maxAge=s||0}},mG=(r,e,t,i)=>{let n=t.value;LI(r,n)&&(Mg(r,t),r[ad]||(n=void 0)),n&&e.call(i,n.value,n.key,r)};IG.exports=ov});var os=w((PZe,bG)=>{var ic=class{constructor(e,t){if(t=NCe(t),e instanceof ic)return e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease?e:new ic(e.raw,t);if(e instanceof Av)return this.raw=e.value,this.set=[[e]],this.format(),this;if(this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease,this.raw=e,this.set=e.split(/\s*\|\|\s*/).map(i=>this.parseRange(i.trim())).filter(i=>i.length),!this.set.length)throw new TypeError(`Invalid SemVer Range: ${e}`);if(this.set.length>1){let i=this.set[0];if(this.set=this.set.filter(n=>!BG(n[0])),this.set.length===0)this.set=[i];else if(this.set.length>1){for(let n of this.set)if(n.length===1&&KCe(n[0])){this.set=[n];break}}}this.format()}format(){return this.range=this.set.map(e=>e.join(" ").trim()).join("||").trim(),this.range}toString(){return this.range}parseRange(e){e=e.trim();let i=`parseRange:${Object.keys(this.options).join(",")}:${e}`,n=wG.get(i);if(n)return n;let s=this.options.loose,o=s?Ti[Bi.HYPHENRANGELOOSE]:Ti[Bi.HYPHENRANGE];e=e.replace(o,VCe(this.options.includePrerelease)),Gr("hyphen replace",e),e=e.replace(Ti[Bi.COMPARATORTRIM],TCe),Gr("comparator trim",e,Ti[Bi.COMPARATORTRIM]),e=e.replace(Ti[Bi.TILDETRIM],OCe),e=e.replace(Ti[Bi.CARETTRIM],MCe),e=e.split(/\s+/).join(" ");let a=s?Ti[Bi.COMPARATORLOOSE]:Ti[Bi.COMPARATOR],l=e.split(" ").map(f=>UCe(f,this.options)).join(" ").split(/\s+/).map(f=>zCe(f,this.options)).filter(this.options.loose?f=>!!f.match(a):()=>!0).map(f=>new Av(f,this.options)),c=l.length,u=new Map;for(let f of l){if(BG(f))return[f];u.set(f.value,f)}u.size>1&&u.has("")&&u.delete("");let g=[...u.values()];return wG.set(i,g),g}intersects(e,t){if(!(e instanceof ic))throw new TypeError("a Range is required");return this.set.some(i=>QG(i,t)&&e.set.some(n=>QG(n,t)&&i.every(s=>n.every(o=>s.intersects(o,t)))))}test(e){if(!e)return!1;if(typeof e=="string")try{e=new LCe(e,this.options)}catch{return!1}for(let t=0;tr.value==="<0.0.0-0",KCe=r=>r.value==="",QG=(r,e)=>{let t=!0,i=r.slice(),n=i.pop();for(;t&&i.length;)t=i.every(s=>n.intersects(s,e)),n=i.pop();return t},UCe=(r,e)=>(Gr("comp",r,e),r=YCe(r,e),Gr("caret",r),r=HCe(r,e),Gr("tildes",r),r=qCe(r,e),Gr("xrange",r),r=WCe(r,e),Gr("stars",r),r),Vi=r=>!r||r.toLowerCase()==="x"||r==="*",HCe=(r,e)=>r.trim().split(/\s+/).map(t=>GCe(t,e)).join(" "),GCe=(r,e)=>{let t=e.loose?Ti[Bi.TILDELOOSE]:Ti[Bi.TILDE];return r.replace(t,(i,n,s,o,a)=>{Gr("tilde",r,i,n,s,o,a);let l;return Vi(n)?l="":Vi(s)?l=`>=${n}.0.0 <${+n+1}.0.0-0`:Vi(o)?l=`>=${n}.${s}.0 <${n}.${+s+1}.0-0`:a?(Gr("replaceTilde pr",a),l=`>=${n}.${s}.${o}-${a} <${n}.${+s+1}.0-0`):l=`>=${n}.${s}.${o} <${n}.${+s+1}.0-0`,Gr("tilde return",l),l})},YCe=(r,e)=>r.trim().split(/\s+/).map(t=>jCe(t,e)).join(" "),jCe=(r,e)=>{Gr("caret",r,e);let t=e.loose?Ti[Bi.CARETLOOSE]:Ti[Bi.CARET],i=e.includePrerelease?"-0":"";return r.replace(t,(n,s,o,a,l)=>{Gr("caret",r,n,s,o,a,l);let c;return Vi(s)?c="":Vi(o)?c=`>=${s}.0.0${i} <${+s+1}.0.0-0`:Vi(a)?s==="0"?c=`>=${s}.${o}.0${i} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.0${i} <${+s+1}.0.0-0`:l?(Gr("replaceCaret pr",l),s==="0"?o==="0"?c=`>=${s}.${o}.${a}-${l} <${s}.${o}.${+a+1}-0`:c=`>=${s}.${o}.${a}-${l} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.${a}-${l} <${+s+1}.0.0-0`):(Gr("no pr"),s==="0"?o==="0"?c=`>=${s}.${o}.${a}${i} <${s}.${o}.${+a+1}-0`:c=`>=${s}.${o}.${a}${i} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.${a} <${+s+1}.0.0-0`),Gr("caret return",c),c})},qCe=(r,e)=>(Gr("replaceXRanges",r,e),r.split(/\s+/).map(t=>JCe(t,e)).join(" ")),JCe=(r,e)=>{r=r.trim();let t=e.loose?Ti[Bi.XRANGELOOSE]:Ti[Bi.XRANGE];return r.replace(t,(i,n,s,o,a,l)=>{Gr("xRange",r,i,n,s,o,a,l);let c=Vi(s),u=c||Vi(o),g=u||Vi(a),f=g;return n==="="&&f&&(n=""),l=e.includePrerelease?"-0":"",c?n===">"||n==="<"?i="<0.0.0-0":i="*":n&&f?(u&&(o=0),a=0,n===">"?(n=">=",u?(s=+s+1,o=0,a=0):(o=+o+1,a=0)):n==="<="&&(n="<",u?s=+s+1:o=+o+1),n==="<"&&(l="-0"),i=`${n+s}.${o}.${a}${l}`):u?i=`>=${s}.0.0${l} <${+s+1}.0.0-0`:g&&(i=`>=${s}.${o}.0${l} <${s}.${+o+1}.0-0`),Gr("xRange return",i),i})},WCe=(r,e)=>(Gr("replaceStars",r,e),r.trim().replace(Ti[Bi.STAR],"")),zCe=(r,e)=>(Gr("replaceGTE0",r,e),r.trim().replace(Ti[e.includePrerelease?Bi.GTE0PRE:Bi.GTE0],"")),VCe=r=>(e,t,i,n,s,o,a,l,c,u,g,f,h)=>(Vi(i)?t="":Vi(n)?t=`>=${i}.0.0${r?"-0":""}`:Vi(s)?t=`>=${i}.${n}.0${r?"-0":""}`:o?t=`>=${t}`:t=`>=${t}${r?"-0":""}`,Vi(c)?l="":Vi(u)?l=`<${+c+1}.0.0-0`:Vi(g)?l=`<${c}.${+u+1}.0-0`:f?l=`<=${c}.${u}.${g}-${f}`:r?l=`<${c}.${u}.${+g+1}-0`:l=`<=${l}`,`${t} ${l}`.trim()),XCe=(r,e,t)=>{for(let i=0;i0){let n=r[i].semver;if(n.major===e.major&&n.minor===e.minor&&n.patch===e.patch)return!0}return!1}return!0}});var Ad=w((DZe,DG)=>{var ld=Symbol("SemVer ANY"),Kg=class{static get ANY(){return ld}constructor(e,t){if(t=_Ce(t),e instanceof Kg){if(e.loose===!!t.loose)return e;e=e.value}cv("comparator",e,t),this.options=t,this.loose=!!t.loose,this.parse(e),this.semver===ld?this.value="":this.value=this.operator+this.semver.version,cv("comp",this)}parse(e){let t=this.options.loose?SG[vG.COMPARATORLOOSE]:SG[vG.COMPARATOR],i=e.match(t);if(!i)throw new TypeError(`Invalid comparator: ${e}`);this.operator=i[1]!==void 0?i[1]:"",this.operator==="="&&(this.operator=""),i[2]?this.semver=new xG(i[2],this.options.loose):this.semver=ld}toString(){return this.value}test(e){if(cv("Comparator.test",e,this.options.loose),this.semver===ld||e===ld)return!0;if(typeof e=="string")try{e=new xG(e,this.options)}catch{return!1}return lv(e,this.operator,this.semver,this.options)}intersects(e,t){if(!(e instanceof Kg))throw new TypeError("a Comparator is required");if((!t||typeof t!="object")&&(t={loose:!!t,includePrerelease:!1}),this.operator==="")return this.value===""?!0:new PG(e.value,t).test(this.value);if(e.operator==="")return e.value===""?!0:new PG(this.value,t).test(e.semver);let i=(this.operator===">="||this.operator===">")&&(e.operator===">="||e.operator===">"),n=(this.operator==="<="||this.operator==="<")&&(e.operator==="<="||e.operator==="<"),s=this.semver.version===e.semver.version,o=(this.operator===">="||this.operator==="<=")&&(e.operator===">="||e.operator==="<="),a=lv(this.semver,"<",e.semver,t)&&(this.operator===">="||this.operator===">")&&(e.operator==="<="||e.operator==="<"),l=lv(this.semver,">",e.semver,t)&&(this.operator==="<="||this.operator==="<")&&(e.operator===">="||e.operator===">");return i||n||s&&o||a||l}};DG.exports=Kg;var _Ce=rd(),{re:SG,t:vG}=Zl(),lv=iv(),cv=td(),xG=Li(),PG=os()});var cd=w((kZe,kG)=>{var ZCe=os(),$Ce=(r,e,t)=>{try{e=new ZCe(e,t)}catch{return!1}return e.test(r)};kG.exports=$Ce});var FG=w((RZe,RG)=>{var eme=os(),tme=(r,e)=>new eme(r,e).set.map(t=>t.map(i=>i.value).join(" ").trim().split(" "));RG.exports=tme});var LG=w((FZe,NG)=>{var rme=Li(),ime=os(),nme=(r,e,t)=>{let i=null,n=null,s=null;try{s=new ime(e,t)}catch{return null}return r.forEach(o=>{s.test(o)&&(!i||n.compare(o)===-1)&&(i=o,n=new rme(i,t))}),i};NG.exports=nme});var OG=w((NZe,TG)=>{var sme=Li(),ome=os(),ame=(r,e,t)=>{let i=null,n=null,s=null;try{s=new ome(e,t)}catch{return null}return r.forEach(o=>{s.test(o)&&(!i||n.compare(o)===1)&&(i=o,n=new sme(i,t))}),i};TG.exports=ame});var UG=w((LZe,KG)=>{var uv=Li(),Ame=os(),MG=nd(),lme=(r,e)=>{r=new Ame(r,e);let t=new uv("0.0.0");if(r.test(t)||(t=new uv("0.0.0-0"),r.test(t)))return t;t=null;for(let i=0;i{let a=new uv(o.semver.version);switch(o.operator){case">":a.prerelease.length===0?a.patch++:a.prerelease.push(0),a.raw=a.format();case"":case">=":(!s||MG(a,s))&&(s=a);break;case"<":case"<=":break;default:throw new Error(`Unexpected operation: ${o.operator}`)}}),s&&(!t||MG(t,s))&&(t=s)}return t&&r.test(t)?t:null};KG.exports=lme});var GG=w((TZe,HG)=>{var cme=os(),ume=(r,e)=>{try{return new cme(r,e).range||"*"}catch{return null}};HG.exports=ume});var TI=w((OZe,JG)=>{var gme=Li(),qG=Ad(),{ANY:fme}=qG,hme=os(),pme=cd(),YG=nd(),jG=DI(),dme=RI(),Cme=kI(),mme=(r,e,t,i)=>{r=new gme(r,i),e=new hme(e,i);let n,s,o,a,l;switch(t){case">":n=YG,s=dme,o=jG,a=">",l=">=";break;case"<":n=jG,s=Cme,o=YG,a="<",l="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(pme(r,e,i))return!1;for(let c=0;c{h.semver===fme&&(h=new qG(">=0.0.0")),g=g||h,f=f||h,n(h.semver,g.semver,i)?g=h:o(h.semver,f.semver,i)&&(f=h)}),g.operator===a||g.operator===l||(!f.operator||f.operator===a)&&s(r,f.semver))return!1;if(f.operator===l&&o(r,f.semver))return!1}return!0};JG.exports=mme});var zG=w((MZe,WG)=>{var Eme=TI(),Ime=(r,e,t)=>Eme(r,e,">",t);WG.exports=Ime});var XG=w((KZe,VG)=>{var yme=TI(),wme=(r,e,t)=>yme(r,e,"<",t);VG.exports=wme});var $G=w((UZe,ZG)=>{var _G=os(),Bme=(r,e,t)=>(r=new _G(r,t),e=new _G(e,t),r.intersects(e));ZG.exports=Bme});var tY=w((HZe,eY)=>{var Qme=cd(),bme=ss();eY.exports=(r,e,t)=>{let i=[],n=null,s=null,o=r.sort((u,g)=>bme(u,g,t));for(let u of o)Qme(u,e,t)?(s=u,n||(n=u)):(s&&i.push([n,s]),s=null,n=null);n&&i.push([n,null]);let a=[];for(let[u,g]of i)u===g?a.push(u):!g&&u===o[0]?a.push("*"):g?u===o[0]?a.push(`<=${g}`):a.push(`${u} - ${g}`):a.push(`>=${u}`);let l=a.join(" || "),c=typeof e.raw=="string"?e.raw:String(e);return l.length{var rY=os(),OI=Ad(),{ANY:gv}=OI,ud=cd(),fv=ss(),Sme=(r,e,t={})=>{if(r===e)return!0;r=new rY(r,t),e=new rY(e,t);let i=!1;e:for(let n of r.set){for(let s of e.set){let o=vme(n,s,t);if(i=i||o!==null,o)continue e}if(i)return!1}return!0},vme=(r,e,t)=>{if(r===e)return!0;if(r.length===1&&r[0].semver===gv){if(e.length===1&&e[0].semver===gv)return!0;t.includePrerelease?r=[new OI(">=0.0.0-0")]:r=[new OI(">=0.0.0")]}if(e.length===1&&e[0].semver===gv){if(t.includePrerelease)return!0;e=[new OI(">=0.0.0")]}let i=new Set,n,s;for(let h of r)h.operator===">"||h.operator===">="?n=iY(n,h,t):h.operator==="<"||h.operator==="<="?s=nY(s,h,t):i.add(h.semver);if(i.size>1)return null;let o;if(n&&s){if(o=fv(n.semver,s.semver,t),o>0)return null;if(o===0&&(n.operator!==">="||s.operator!=="<="))return null}for(let h of i){if(n&&!ud(h,String(n),t)||s&&!ud(h,String(s),t))return null;for(let p of e)if(!ud(h,String(p),t))return!1;return!0}let a,l,c,u,g=s&&!t.includePrerelease&&s.semver.prerelease.length?s.semver:!1,f=n&&!t.includePrerelease&&n.semver.prerelease.length?n.semver:!1;g&&g.prerelease.length===1&&s.operator==="<"&&g.prerelease[0]===0&&(g=!1);for(let h of e){if(u=u||h.operator===">"||h.operator===">=",c=c||h.operator==="<"||h.operator==="<=",n){if(f&&h.semver.prerelease&&h.semver.prerelease.length&&h.semver.major===f.major&&h.semver.minor===f.minor&&h.semver.patch===f.patch&&(f=!1),h.operator===">"||h.operator===">="){if(a=iY(n,h,t),a===h&&a!==n)return!1}else if(n.operator===">="&&!ud(n.semver,String(h),t))return!1}if(s){if(g&&h.semver.prerelease&&h.semver.prerelease.length&&h.semver.major===g.major&&h.semver.minor===g.minor&&h.semver.patch===g.patch&&(g=!1),h.operator==="<"||h.operator==="<="){if(l=nY(s,h,t),l===h&&l!==s)return!1}else if(s.operator==="<="&&!ud(s.semver,String(h),t))return!1}if(!h.operator&&(s||n)&&o!==0)return!1}return!(n&&c&&!s&&o!==0||s&&u&&!n&&o!==0||f||g)},iY=(r,e,t)=>{if(!r)return e;let i=fv(r.semver,e.semver,t);return i>0?r:i<0||e.operator===">"&&r.operator===">="?e:r},nY=(r,e,t)=>{if(!r)return e;let i=fv(r.semver,e.semver,t);return i<0?r:i>0||e.operator==="<"&&r.operator==="<="?e:r};sY.exports=Sme});var Xr=w((YZe,aY)=>{var hv=Zl();aY.exports={re:hv.re,src:hv.src,tokens:hv.t,SEMVER_SPEC_VERSION:ed().SEMVER_SPEC_VERSION,SemVer:Li(),compareIdentifiers:bI().compareIdentifiers,rcompareIdentifiers:bI().rcompareIdentifiers,parse:$l(),valid:kH(),clean:FH(),inc:LH(),diff:HH(),major:YH(),minor:qH(),patch:WH(),prerelease:VH(),compare:ss(),rcompare:_H(),compareLoose:$H(),compareBuild:PI(),sort:iG(),rsort:sG(),gt:nd(),lt:DI(),eq:xI(),neq:rv(),gte:kI(),lte:RI(),cmp:iv(),coerce:fG(),Comparator:Ad(),Range:os(),satisfies:cd(),toComparators:FG(),maxSatisfying:LG(),minSatisfying:OG(),minVersion:UG(),validRange:GG(),outside:TI(),gtr:zG(),ltr:XG(),intersects:$G(),simplifyRange:tY(),subset:oY()}});var pv=w(MI=>{"use strict";Object.defineProperty(MI,"__esModule",{value:!0});MI.VERSION=void 0;MI.VERSION="9.1.0"});var Gt=w((exports,module)=>{"use strict";var __spreadArray=exports&&exports.__spreadArray||function(r,e,t){if(t||arguments.length===2)for(var i=0,n=e.length,s;i{(function(r,e){typeof define=="function"&&define.amd?define([],e):typeof KI=="object"&&KI.exports?KI.exports=e():r.regexpToAst=e()})(typeof self<"u"?self:AY,function(){function r(){}r.prototype.saveState=function(){return{idx:this.idx,input:this.input,groupIdx:this.groupIdx}},r.prototype.restoreState=function(p){this.idx=p.idx,this.input=p.input,this.groupIdx=p.groupIdx},r.prototype.pattern=function(p){this.idx=0,this.input=p,this.groupIdx=0,this.consumeChar("/");var C=this.disjunction();this.consumeChar("/");for(var y={type:"Flags",loc:{begin:this.idx,end:p.length},global:!1,ignoreCase:!1,multiLine:!1,unicode:!1,sticky:!1};this.isRegExpFlag();)switch(this.popChar()){case"g":o(y,"global");break;case"i":o(y,"ignoreCase");break;case"m":o(y,"multiLine");break;case"u":o(y,"unicode");break;case"y":o(y,"sticky");break}if(this.idx!==this.input.length)throw Error("Redundant input: "+this.input.substring(this.idx));return{type:"Pattern",flags:y,value:C,loc:this.loc(0)}},r.prototype.disjunction=function(){var p=[],C=this.idx;for(p.push(this.alternative());this.peekChar()==="|";)this.consumeChar("|"),p.push(this.alternative());return{type:"Disjunction",value:p,loc:this.loc(C)}},r.prototype.alternative=function(){for(var p=[],C=this.idx;this.isTerm();)p.push(this.term());return{type:"Alternative",value:p,loc:this.loc(C)}},r.prototype.term=function(){return this.isAssertion()?this.assertion():this.atom()},r.prototype.assertion=function(){var p=this.idx;switch(this.popChar()){case"^":return{type:"StartAnchor",loc:this.loc(p)};case"$":return{type:"EndAnchor",loc:this.loc(p)};case"\\":switch(this.popChar()){case"b":return{type:"WordBoundary",loc:this.loc(p)};case"B":return{type:"NonWordBoundary",loc:this.loc(p)}}throw Error("Invalid Assertion Escape");case"(":this.consumeChar("?");var C;switch(this.popChar()){case"=":C="Lookahead";break;case"!":C="NegativeLookahead";break}a(C);var y=this.disjunction();return this.consumeChar(")"),{type:C,value:y,loc:this.loc(p)}}l()},r.prototype.quantifier=function(p){var C,y=this.idx;switch(this.popChar()){case"*":C={atLeast:0,atMost:1/0};break;case"+":C={atLeast:1,atMost:1/0};break;case"?":C={atLeast:0,atMost:1};break;case"{":var B=this.integerIncludingZero();switch(this.popChar()){case"}":C={atLeast:B,atMost:B};break;case",":var v;this.isDigit()?(v=this.integerIncludingZero(),C={atLeast:B,atMost:v}):C={atLeast:B,atMost:1/0},this.consumeChar("}");break}if(p===!0&&C===void 0)return;a(C);break}if(!(p===!0&&C===void 0))return a(C),this.peekChar(0)==="?"?(this.consumeChar("?"),C.greedy=!1):C.greedy=!0,C.type="Quantifier",C.loc=this.loc(y),C},r.prototype.atom=function(){var p,C=this.idx;switch(this.peekChar()){case".":p=this.dotAll();break;case"\\":p=this.atomEscape();break;case"[":p=this.characterClass();break;case"(":p=this.group();break}return p===void 0&&this.isPatternCharacter()&&(p=this.patternCharacter()),a(p),p.loc=this.loc(C),this.isQuantifier()&&(p.quantifier=this.quantifier()),p},r.prototype.dotAll=function(){return this.consumeChar("."),{type:"Set",complement:!0,value:[n(` +`),n("\r"),n("\u2028"),n("\u2029")]}},r.prototype.atomEscape=function(){switch(this.consumeChar("\\"),this.peekChar()){case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return this.decimalEscapeAtom();case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}},r.prototype.decimalEscapeAtom=function(){var p=this.positiveInteger();return{type:"GroupBackReference",value:p}},r.prototype.characterClassEscape=function(){var p,C=!1;switch(this.popChar()){case"d":p=u;break;case"D":p=u,C=!0;break;case"s":p=f;break;case"S":p=f,C=!0;break;case"w":p=g;break;case"W":p=g,C=!0;break}return a(p),{type:"Set",value:p,complement:C}},r.prototype.controlEscapeAtom=function(){var p;switch(this.popChar()){case"f":p=n("\f");break;case"n":p=n(` +`);break;case"r":p=n("\r");break;case"t":p=n(" ");break;case"v":p=n("\v");break}return a(p),{type:"Character",value:p}},r.prototype.controlLetterEscapeAtom=function(){this.consumeChar("c");var p=this.popChar();if(/[a-zA-Z]/.test(p)===!1)throw Error("Invalid ");var C=p.toUpperCase().charCodeAt(0)-64;return{type:"Character",value:C}},r.prototype.nulCharacterAtom=function(){return this.consumeChar("0"),{type:"Character",value:n("\0")}},r.prototype.hexEscapeSequenceAtom=function(){return this.consumeChar("x"),this.parseHexDigits(2)},r.prototype.regExpUnicodeEscapeSequenceAtom=function(){return this.consumeChar("u"),this.parseHexDigits(4)},r.prototype.identityEscapeAtom=function(){var p=this.popChar();return{type:"Character",value:n(p)}},r.prototype.classPatternCharacterAtom=function(){switch(this.peekChar()){case` +`:case"\r":case"\u2028":case"\u2029":case"\\":case"]":throw Error("TBD");default:var p=this.popChar();return{type:"Character",value:n(p)}}},r.prototype.characterClass=function(){var p=[],C=!1;for(this.consumeChar("["),this.peekChar(0)==="^"&&(this.consumeChar("^"),C=!0);this.isClassAtom();){var y=this.classAtom(),B=y.type==="Character";if(B&&this.isRangeDash()){this.consumeChar("-");var v=this.classAtom(),D=v.type==="Character";if(D){if(v.value=this.input.length)throw Error("Unexpected end of input");this.idx++},r.prototype.loc=function(p){return{begin:p,end:this.idx}};var e=/[0-9a-fA-F]/,t=/[0-9]/,i=/[1-9]/;function n(p){return p.charCodeAt(0)}function s(p,C){p.length!==void 0?p.forEach(function(y){C.push(y)}):C.push(p)}function o(p,C){if(p[C]===!0)throw"duplicate flag "+C;p[C]=!0}function a(p){if(p===void 0)throw Error("Internal Error - Should never get here!")}function l(){throw Error("Internal Error - Should never get here!")}var c,u=[];for(c=n("0");c<=n("9");c++)u.push(c);var g=[n("_")].concat(u);for(c=n("a");c<=n("z");c++)g.push(c);for(c=n("A");c<=n("Z");c++)g.push(c);var f=[n(" "),n("\f"),n(` +`),n("\r"),n(" "),n("\v"),n(" "),n("\xA0"),n("\u1680"),n("\u2000"),n("\u2001"),n("\u2002"),n("\u2003"),n("\u2004"),n("\u2005"),n("\u2006"),n("\u2007"),n("\u2008"),n("\u2009"),n("\u200A"),n("\u2028"),n("\u2029"),n("\u202F"),n("\u205F"),n("\u3000"),n("\uFEFF")];function h(){}return h.prototype.visitChildren=function(p){for(var C in p){var y=p[C];p.hasOwnProperty(C)&&(y.type!==void 0?this.visit(y):Array.isArray(y)&&y.forEach(function(B){this.visit(B)},this))}},h.prototype.visit=function(p){switch(p.type){case"Pattern":this.visitPattern(p);break;case"Flags":this.visitFlags(p);break;case"Disjunction":this.visitDisjunction(p);break;case"Alternative":this.visitAlternative(p);break;case"StartAnchor":this.visitStartAnchor(p);break;case"EndAnchor":this.visitEndAnchor(p);break;case"WordBoundary":this.visitWordBoundary(p);break;case"NonWordBoundary":this.visitNonWordBoundary(p);break;case"Lookahead":this.visitLookahead(p);break;case"NegativeLookahead":this.visitNegativeLookahead(p);break;case"Character":this.visitCharacter(p);break;case"Set":this.visitSet(p);break;case"Group":this.visitGroup(p);break;case"GroupBackReference":this.visitGroupBackReference(p);break;case"Quantifier":this.visitQuantifier(p);break}this.visitChildren(p)},h.prototype.visitPattern=function(p){},h.prototype.visitFlags=function(p){},h.prototype.visitDisjunction=function(p){},h.prototype.visitAlternative=function(p){},h.prototype.visitStartAnchor=function(p){},h.prototype.visitEndAnchor=function(p){},h.prototype.visitWordBoundary=function(p){},h.prototype.visitNonWordBoundary=function(p){},h.prototype.visitLookahead=function(p){},h.prototype.visitNegativeLookahead=function(p){},h.prototype.visitCharacter=function(p){},h.prototype.visitSet=function(p){},h.prototype.visitGroup=function(p){},h.prototype.visitGroupBackReference=function(p){},h.prototype.visitQuantifier=function(p){},{RegExpParser:r,BaseRegExpVisitor:h,VERSION:"0.5.0"}})});var GI=w(Ug=>{"use strict";Object.defineProperty(Ug,"__esModule",{value:!0});Ug.clearRegExpParserCache=Ug.getRegExpAst=void 0;var xme=UI(),HI={},Pme=new xme.RegExpParser;function Dme(r){var e=r.toString();if(HI.hasOwnProperty(e))return HI[e];var t=Pme.pattern(e);return HI[e]=t,t}Ug.getRegExpAst=Dme;function kme(){HI={}}Ug.clearRegExpParserCache=kme});var fY=w(pn=>{"use strict";var Rme=pn&&pn.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(pn,"__esModule",{value:!0});pn.canMatchCharCode=pn.firstCharOptimizedIndices=pn.getOptimizedStartCodesIndices=pn.failedOptimizationPrefixMsg=void 0;var cY=UI(),as=Gt(),uY=GI(),ya=Cv(),gY="Complement Sets are not supported for first char optimization";pn.failedOptimizationPrefixMsg=`Unable to use "first char" lexer optimizations: +`;function Fme(r,e){e===void 0&&(e=!1);try{var t=(0,uY.getRegExpAst)(r),i=jI(t.value,{},t.flags.ignoreCase);return i}catch(s){if(s.message===gY)e&&(0,as.PRINT_WARNING)(""+pn.failedOptimizationPrefixMsg+(" Unable to optimize: < "+r.toString()+` > +`)+` Complement Sets cannot be automatically optimized. + This will disable the lexer's first char optimizations. + See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#COMPLEMENT for details.`);else{var n="";e&&(n=` + This will disable the lexer's first char optimizations. + See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#REGEXP_PARSING for details.`),(0,as.PRINT_ERROR)(pn.failedOptimizationPrefixMsg+` +`+(" Failed parsing: < "+r.toString()+` > +`)+(" Using the regexp-to-ast library version: "+cY.VERSION+` +`)+" Please open an issue at: https://github.com/bd82/regexp-to-ast/issues"+n)}}return[]}pn.getOptimizedStartCodesIndices=Fme;function jI(r,e,t){switch(r.type){case"Disjunction":for(var i=0;i=ya.minOptimizationVal)for(var f=u.from>=ya.minOptimizationVal?u.from:ya.minOptimizationVal,h=u.to,p=(0,ya.charCodeToOptimizedIndex)(f),C=(0,ya.charCodeToOptimizedIndex)(h),y=p;y<=C;y++)e[y]=y}}});break;case"Group":jI(o.value,e,t);break;default:throw Error("Non Exhaustive Match")}var a=o.quantifier!==void 0&&o.quantifier.atLeast===0;if(o.type==="Group"&&dv(o)===!1||o.type!=="Group"&&a===!1)break}break;default:throw Error("non exhaustive match!")}return(0,as.values)(e)}pn.firstCharOptimizedIndices=jI;function YI(r,e,t){var i=(0,ya.charCodeToOptimizedIndex)(r);e[i]=i,t===!0&&Nme(r,e)}function Nme(r,e){var t=String.fromCharCode(r),i=t.toUpperCase();if(i!==t){var n=(0,ya.charCodeToOptimizedIndex)(i.charCodeAt(0));e[n]=n}else{var s=t.toLowerCase();if(s!==t){var n=(0,ya.charCodeToOptimizedIndex)(s.charCodeAt(0));e[n]=n}}}function lY(r,e){return(0,as.find)(r.value,function(t){if(typeof t=="number")return(0,as.contains)(e,t);var i=t;return(0,as.find)(e,function(n){return i.from<=n&&n<=i.to})!==void 0})}function dv(r){return r.quantifier&&r.quantifier.atLeast===0?!0:r.value?(0,as.isArray)(r.value)?(0,as.every)(r.value,dv):dv(r.value):!1}var Lme=function(r){Rme(e,r);function e(t){var i=r.call(this)||this;return i.targetCharCodes=t,i.found=!1,i}return e.prototype.visitChildren=function(t){if(this.found!==!0){switch(t.type){case"Lookahead":this.visitLookahead(t);return;case"NegativeLookahead":this.visitNegativeLookahead(t);return}r.prototype.visitChildren.call(this,t)}},e.prototype.visitCharacter=function(t){(0,as.contains)(this.targetCharCodes,t.value)&&(this.found=!0)},e.prototype.visitSet=function(t){t.complement?lY(t,this.targetCharCodes)===void 0&&(this.found=!0):lY(t,this.targetCharCodes)!==void 0&&(this.found=!0)},e}(cY.BaseRegExpVisitor);function Tme(r,e){if(e instanceof RegExp){var t=(0,uY.getRegExpAst)(e),i=new Lme(r);return i.visit(t),i.found}else return(0,as.find)(e,function(n){return(0,as.contains)(r,n.charCodeAt(0))})!==void 0}pn.canMatchCharCode=Tme});var Cv=w(Ve=>{"use strict";var hY=Ve&&Ve.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Ve,"__esModule",{value:!0});Ve.charCodeToOptimizedIndex=Ve.minOptimizationVal=Ve.buildLineBreakIssueMessage=Ve.LineTerminatorOptimizedTester=Ve.isShortPattern=Ve.isCustomPattern=Ve.cloneEmptyGroups=Ve.performWarningRuntimeChecks=Ve.performRuntimeChecks=Ve.addStickyFlag=Ve.addStartOfInput=Ve.findUnreachablePatterns=Ve.findModesThatDoNotExist=Ve.findInvalidGroupType=Ve.findDuplicatePatterns=Ve.findUnsupportedFlags=Ve.findStartOfInputAnchor=Ve.findEmptyMatchRegExps=Ve.findEndOfInputAnchor=Ve.findInvalidPatterns=Ve.findMissingPatterns=Ve.validatePatterns=Ve.analyzeTokenTypes=Ve.enableSticky=Ve.disableSticky=Ve.SUPPORT_STICKY=Ve.MODES=Ve.DEFAULT_MODE=void 0;var pY=UI(),ir=gd(),xe=Gt(),Hg=fY(),dY=GI(),So="PATTERN";Ve.DEFAULT_MODE="defaultMode";Ve.MODES="modes";Ve.SUPPORT_STICKY=typeof new RegExp("(?:)").sticky=="boolean";function Ome(){Ve.SUPPORT_STICKY=!1}Ve.disableSticky=Ome;function Mme(){Ve.SUPPORT_STICKY=!0}Ve.enableSticky=Mme;function Kme(r,e){e=(0,xe.defaults)(e,{useSticky:Ve.SUPPORT_STICKY,debug:!1,safeMode:!1,positionTracking:"full",lineTerminatorCharacters:["\r",` +`],tracer:function(v,D){return D()}});var t=e.tracer;t("initCharCodeToOptimizedIndexMap",function(){Vme()});var i;t("Reject Lexer.NA",function(){i=(0,xe.reject)(r,function(v){return v[So]===ir.Lexer.NA})});var n=!1,s;t("Transform Patterns",function(){n=!1,s=(0,xe.map)(i,function(v){var D=v[So];if((0,xe.isRegExp)(D)){var L=D.source;return L.length===1&&L!=="^"&&L!=="$"&&L!=="."&&!D.ignoreCase?L:L.length===2&&L[0]==="\\"&&!(0,xe.contains)(["d","D","s","S","t","r","n","t","0","c","b","B","f","v","w","W"],L[1])?L[1]:e.useSticky?Iv(D):Ev(D)}else{if((0,xe.isFunction)(D))return n=!0,{exec:D};if((0,xe.has)(D,"exec"))return n=!0,D;if(typeof D=="string"){if(D.length===1)return D;var H=D.replace(/[\\^$.*+?()[\]{}|]/g,"\\$&"),j=new RegExp(H);return e.useSticky?Iv(j):Ev(j)}else throw Error("non exhaustive match")}})});var o,a,l,c,u;t("misc mapping",function(){o=(0,xe.map)(i,function(v){return v.tokenTypeIdx}),a=(0,xe.map)(i,function(v){var D=v.GROUP;if(D!==ir.Lexer.SKIPPED){if((0,xe.isString)(D))return D;if((0,xe.isUndefined)(D))return!1;throw Error("non exhaustive match")}}),l=(0,xe.map)(i,function(v){var D=v.LONGER_ALT;if(D){var L=(0,xe.isArray)(D)?(0,xe.map)(D,function(H){return(0,xe.indexOf)(i,H)}):[(0,xe.indexOf)(i,D)];return L}}),c=(0,xe.map)(i,function(v){return v.PUSH_MODE}),u=(0,xe.map)(i,function(v){return(0,xe.has)(v,"POP_MODE")})});var g;t("Line Terminator Handling",function(){var v=DY(e.lineTerminatorCharacters);g=(0,xe.map)(i,function(D){return!1}),e.positionTracking!=="onlyOffset"&&(g=(0,xe.map)(i,function(D){if((0,xe.has)(D,"LINE_BREAKS"))return D.LINE_BREAKS;if(xY(D,v)===!1)return(0,Hg.canMatchCharCode)(v,D.PATTERN)}))});var f,h,p,C;t("Misc Mapping #2",function(){f=(0,xe.map)(i,wv),h=(0,xe.map)(s,vY),p=(0,xe.reduce)(i,function(v,D){var L=D.GROUP;return(0,xe.isString)(L)&&L!==ir.Lexer.SKIPPED&&(v[L]=[]),v},{}),C=(0,xe.map)(s,function(v,D){return{pattern:s[D],longerAlt:l[D],canLineTerminator:g[D],isCustom:f[D],short:h[D],group:a[D],push:c[D],pop:u[D],tokenTypeIdx:o[D],tokenType:i[D]}})});var y=!0,B=[];return e.safeMode||t("First Char Optimization",function(){B=(0,xe.reduce)(i,function(v,D,L){if(typeof D.PATTERN=="string"){var H=D.PATTERN.charCodeAt(0),j=yv(H);mv(v,j,C[L])}else if((0,xe.isArray)(D.START_CHARS_HINT)){var $;(0,xe.forEach)(D.START_CHARS_HINT,function(W){var Z=typeof W=="string"?W.charCodeAt(0):W,A=yv(Z);$!==A&&($=A,mv(v,A,C[L]))})}else if((0,xe.isRegExp)(D.PATTERN))if(D.PATTERN.unicode)y=!1,e.ensureOptimizations&&(0,xe.PRINT_ERROR)(""+Hg.failedOptimizationPrefixMsg+(" Unable to analyze < "+D.PATTERN.toString()+` > pattern. +`)+` The regexp unicode flag is not currently supported by the regexp-to-ast library. + This will disable the lexer's first char optimizations. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNICODE_OPTIMIZE`);else{var V=(0,Hg.getOptimizedStartCodesIndices)(D.PATTERN,e.ensureOptimizations);(0,xe.isEmpty)(V)&&(y=!1),(0,xe.forEach)(V,function(W){mv(v,W,C[L])})}else e.ensureOptimizations&&(0,xe.PRINT_ERROR)(""+Hg.failedOptimizationPrefixMsg+(" TokenType: <"+D.name+`> is using a custom token pattern without providing parameter. +`)+` This will disable the lexer's first char optimizations. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_OPTIMIZE`),y=!1;return v},[])}),t("ArrayPacking",function(){B=(0,xe.packArray)(B)}),{emptyGroups:p,patternIdxToConfig:C,charCodeToPatternIdxToConfig:B,hasCustom:n,canBeOptimized:y}}Ve.analyzeTokenTypes=Kme;function Ume(r,e){var t=[],i=CY(r);t=t.concat(i.errors);var n=mY(i.valid),s=n.valid;return t=t.concat(n.errors),t=t.concat(Hme(s)),t=t.concat(QY(s)),t=t.concat(bY(s,e)),t=t.concat(SY(s)),t}Ve.validatePatterns=Ume;function Hme(r){var e=[],t=(0,xe.filter)(r,function(i){return(0,xe.isRegExp)(i[So])});return e=e.concat(EY(t)),e=e.concat(yY(t)),e=e.concat(wY(t)),e=e.concat(BY(t)),e=e.concat(IY(t)),e}function CY(r){var e=(0,xe.filter)(r,function(n){return!(0,xe.has)(n,So)}),t=(0,xe.map)(e,function(n){return{message:"Token Type: ->"+n.name+"<- missing static 'PATTERN' property",type:ir.LexerDefinitionErrorType.MISSING_PATTERN,tokenTypes:[n]}}),i=(0,xe.difference)(r,e);return{errors:t,valid:i}}Ve.findMissingPatterns=CY;function mY(r){var e=(0,xe.filter)(r,function(n){var s=n[So];return!(0,xe.isRegExp)(s)&&!(0,xe.isFunction)(s)&&!(0,xe.has)(s,"exec")&&!(0,xe.isString)(s)}),t=(0,xe.map)(e,function(n){return{message:"Token Type: ->"+n.name+"<- static 'PATTERN' can only be a RegExp, a Function matching the {CustomPatternMatcherFunc} type or an Object matching the {ICustomPattern} interface.",type:ir.LexerDefinitionErrorType.INVALID_PATTERN,tokenTypes:[n]}}),i=(0,xe.difference)(r,e);return{errors:t,valid:i}}Ve.findInvalidPatterns=mY;var Gme=/[^\\][\$]/;function EY(r){var e=function(n){hY(s,n);function s(){var o=n!==null&&n.apply(this,arguments)||this;return o.found=!1,o}return s.prototype.visitEndAnchor=function(o){this.found=!0},s}(pY.BaseRegExpVisitor),t=(0,xe.filter)(r,function(n){var s=n[So];try{var o=(0,dY.getRegExpAst)(s),a=new e;return a.visit(o),a.found}catch{return Gme.test(s.source)}}),i=(0,xe.map)(t,function(n){return{message:`Unexpected RegExp Anchor Error: + Token Type: ->`+n.name+`<- static 'PATTERN' cannot contain end of input anchor '$' + See chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:ir.LexerDefinitionErrorType.EOI_ANCHOR_FOUND,tokenTypes:[n]}});return i}Ve.findEndOfInputAnchor=EY;function IY(r){var e=(0,xe.filter)(r,function(i){var n=i[So];return n.test("")}),t=(0,xe.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'PATTERN' must not match an empty string",type:ir.LexerDefinitionErrorType.EMPTY_MATCH_PATTERN,tokenTypes:[i]}});return t}Ve.findEmptyMatchRegExps=IY;var Yme=/[^\\[][\^]|^\^/;function yY(r){var e=function(n){hY(s,n);function s(){var o=n!==null&&n.apply(this,arguments)||this;return o.found=!1,o}return s.prototype.visitStartAnchor=function(o){this.found=!0},s}(pY.BaseRegExpVisitor),t=(0,xe.filter)(r,function(n){var s=n[So];try{var o=(0,dY.getRegExpAst)(s),a=new e;return a.visit(o),a.found}catch{return Yme.test(s.source)}}),i=(0,xe.map)(t,function(n){return{message:`Unexpected RegExp Anchor Error: + Token Type: ->`+n.name+`<- static 'PATTERN' cannot contain start of input anchor '^' + See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:ir.LexerDefinitionErrorType.SOI_ANCHOR_FOUND,tokenTypes:[n]}});return i}Ve.findStartOfInputAnchor=yY;function wY(r){var e=(0,xe.filter)(r,function(i){var n=i[So];return n instanceof RegExp&&(n.multiline||n.global)}),t=(0,xe.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'PATTERN' may NOT contain global('g') or multiline('m')",type:ir.LexerDefinitionErrorType.UNSUPPORTED_FLAGS_FOUND,tokenTypes:[i]}});return t}Ve.findUnsupportedFlags=wY;function BY(r){var e=[],t=(0,xe.map)(r,function(s){return(0,xe.reduce)(r,function(o,a){return s.PATTERN.source===a.PATTERN.source&&!(0,xe.contains)(e,a)&&a.PATTERN!==ir.Lexer.NA&&(e.push(a),o.push(a)),o},[])});t=(0,xe.compact)(t);var i=(0,xe.filter)(t,function(s){return s.length>1}),n=(0,xe.map)(i,function(s){var o=(0,xe.map)(s,function(l){return l.name}),a=(0,xe.first)(s).PATTERN;return{message:"The same RegExp pattern ->"+a+"<-"+("has been used in all of the following Token Types: "+o.join(", ")+" <-"),type:ir.LexerDefinitionErrorType.DUPLICATE_PATTERNS_FOUND,tokenTypes:s}});return n}Ve.findDuplicatePatterns=BY;function QY(r){var e=(0,xe.filter)(r,function(i){if(!(0,xe.has)(i,"GROUP"))return!1;var n=i.GROUP;return n!==ir.Lexer.SKIPPED&&n!==ir.Lexer.NA&&!(0,xe.isString)(n)}),t=(0,xe.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'GROUP' can only be Lexer.SKIPPED/Lexer.NA/A String",type:ir.LexerDefinitionErrorType.INVALID_GROUP_TYPE_FOUND,tokenTypes:[i]}});return t}Ve.findInvalidGroupType=QY;function bY(r,e){var t=(0,xe.filter)(r,function(n){return n.PUSH_MODE!==void 0&&!(0,xe.contains)(e,n.PUSH_MODE)}),i=(0,xe.map)(t,function(n){var s="Token Type: ->"+n.name+"<- static 'PUSH_MODE' value cannot refer to a Lexer Mode ->"+n.PUSH_MODE+"<-which does not exist";return{message:s,type:ir.LexerDefinitionErrorType.PUSH_MODE_DOES_NOT_EXIST,tokenTypes:[n]}});return i}Ve.findModesThatDoNotExist=bY;function SY(r){var e=[],t=(0,xe.reduce)(r,function(i,n,s){var o=n.PATTERN;return o===ir.Lexer.NA||((0,xe.isString)(o)?i.push({str:o,idx:s,tokenType:n}):(0,xe.isRegExp)(o)&&qme(o)&&i.push({str:o.source,idx:s,tokenType:n})),i},[]);return(0,xe.forEach)(r,function(i,n){(0,xe.forEach)(t,function(s){var o=s.str,a=s.idx,l=s.tokenType;if(n"+i.name+"<-")+`in the lexer's definition. +See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNREACHABLE`;e.push({message:c,type:ir.LexerDefinitionErrorType.UNREACHABLE_PATTERN,tokenTypes:[i,l]})}})}),e}Ve.findUnreachablePatterns=SY;function jme(r,e){if((0,xe.isRegExp)(e)){var t=e.exec(r);return t!==null&&t.index===0}else{if((0,xe.isFunction)(e))return e(r,0,[],{});if((0,xe.has)(e,"exec"))return e.exec(r,0,[],{});if(typeof e=="string")return e===r;throw Error("non exhaustive match")}}function qme(r){var e=[".","\\","[","]","|","^","$","(",")","?","*","+","{"];return(0,xe.find)(e,function(t){return r.source.indexOf(t)!==-1})===void 0}function Ev(r){var e=r.ignoreCase?"i":"";return new RegExp("^(?:"+r.source+")",e)}Ve.addStartOfInput=Ev;function Iv(r){var e=r.ignoreCase?"iy":"y";return new RegExp(""+r.source,e)}Ve.addStickyFlag=Iv;function Jme(r,e,t){var i=[];return(0,xe.has)(r,Ve.DEFAULT_MODE)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+Ve.DEFAULT_MODE+`> property in its definition +`,type:ir.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE}),(0,xe.has)(r,Ve.MODES)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+Ve.MODES+`> property in its definition +`,type:ir.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY}),(0,xe.has)(r,Ve.MODES)&&(0,xe.has)(r,Ve.DEFAULT_MODE)&&!(0,xe.has)(r.modes,r.defaultMode)&&i.push({message:"A MultiMode Lexer cannot be initialized with a "+Ve.DEFAULT_MODE+": <"+r.defaultMode+`>which does not exist +`,type:ir.LexerDefinitionErrorType.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST}),(0,xe.has)(r,Ve.MODES)&&(0,xe.forEach)(r.modes,function(n,s){(0,xe.forEach)(n,function(o,a){(0,xe.isUndefined)(o)&&i.push({message:"A Lexer cannot be initialized using an undefined Token Type. Mode:"+("<"+s+"> at index: <"+a+`> +`),type:ir.LexerDefinitionErrorType.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED})})}),i}Ve.performRuntimeChecks=Jme;function Wme(r,e,t){var i=[],n=!1,s=(0,xe.compact)((0,xe.flatten)((0,xe.mapValues)(r.modes,function(l){return l}))),o=(0,xe.reject)(s,function(l){return l[So]===ir.Lexer.NA}),a=DY(t);return e&&(0,xe.forEach)(o,function(l){var c=xY(l,a);if(c!==!1){var u=PY(l,c),g={message:u,type:c.issue,tokenType:l};i.push(g)}else(0,xe.has)(l,"LINE_BREAKS")?l.LINE_BREAKS===!0&&(n=!0):(0,Hg.canMatchCharCode)(a,l.PATTERN)&&(n=!0)}),e&&!n&&i.push({message:`Warning: No LINE_BREAKS Found. + This Lexer has been defined to track line and column information, + But none of the Token Types can be identified as matching a line terminator. + See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#LINE_BREAKS + for details.`,type:ir.LexerDefinitionErrorType.NO_LINE_BREAKS_FLAGS}),i}Ve.performWarningRuntimeChecks=Wme;function zme(r){var e={},t=(0,xe.keys)(r);return(0,xe.forEach)(t,function(i){var n=r[i];if((0,xe.isArray)(n))e[i]=[];else throw Error("non exhaustive match")}),e}Ve.cloneEmptyGroups=zme;function wv(r){var e=r.PATTERN;if((0,xe.isRegExp)(e))return!1;if((0,xe.isFunction)(e))return!0;if((0,xe.has)(e,"exec"))return!0;if((0,xe.isString)(e))return!1;throw Error("non exhaustive match")}Ve.isCustomPattern=wv;function vY(r){return(0,xe.isString)(r)&&r.length===1?r.charCodeAt(0):!1}Ve.isShortPattern=vY;Ve.LineTerminatorOptimizedTester={test:function(r){for(var e=r.length,t=this.lastIndex;t Token Type +`)+(" Root cause: "+e.errMsg+`. +`)+" For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#IDENTIFY_TERMINATOR";if(e.issue===ir.LexerDefinitionErrorType.CUSTOM_LINE_BREAK)return`Warning: A Custom Token Pattern should specify the option. +`+(" The problem is in the <"+r.name+`> Token Type +`)+" For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_LINE_BREAK";throw Error("non exhaustive match")}Ve.buildLineBreakIssueMessage=PY;function DY(r){var e=(0,xe.map)(r,function(t){return(0,xe.isString)(t)&&t.length>0?t.charCodeAt(0):t});return e}function mv(r,e,t){r[e]===void 0?r[e]=[t]:r[e].push(t)}Ve.minOptimizationVal=256;var qI=[];function yv(r){return r255?255+~~(r/255):r}}});var Gg=w(Nt=>{"use strict";Object.defineProperty(Nt,"__esModule",{value:!0});Nt.isTokenType=Nt.hasExtendingTokensTypesMapProperty=Nt.hasExtendingTokensTypesProperty=Nt.hasCategoriesProperty=Nt.hasShortKeyProperty=Nt.singleAssignCategoriesToksMap=Nt.assignCategoriesMapProp=Nt.assignCategoriesTokensProp=Nt.assignTokenDefaultProps=Nt.expandCategories=Nt.augmentTokenTypes=Nt.tokenIdxToClass=Nt.tokenShortNameIdx=Nt.tokenStructuredMatcherNoCategories=Nt.tokenStructuredMatcher=void 0;var _r=Gt();function Xme(r,e){var t=r.tokenTypeIdx;return t===e.tokenTypeIdx?!0:e.isParent===!0&&e.categoryMatchesMap[t]===!0}Nt.tokenStructuredMatcher=Xme;function _me(r,e){return r.tokenTypeIdx===e.tokenTypeIdx}Nt.tokenStructuredMatcherNoCategories=_me;Nt.tokenShortNameIdx=1;Nt.tokenIdxToClass={};function Zme(r){var e=kY(r);RY(e),NY(e),FY(e),(0,_r.forEach)(e,function(t){t.isParent=t.categoryMatches.length>0})}Nt.augmentTokenTypes=Zme;function kY(r){for(var e=(0,_r.cloneArr)(r),t=r,i=!0;i;){t=(0,_r.compact)((0,_r.flatten)((0,_r.map)(t,function(s){return s.CATEGORIES})));var n=(0,_r.difference)(t,e);e=e.concat(n),(0,_r.isEmpty)(n)?i=!1:t=n}return e}Nt.expandCategories=kY;function RY(r){(0,_r.forEach)(r,function(e){LY(e)||(Nt.tokenIdxToClass[Nt.tokenShortNameIdx]=e,e.tokenTypeIdx=Nt.tokenShortNameIdx++),Bv(e)&&!(0,_r.isArray)(e.CATEGORIES)&&(e.CATEGORIES=[e.CATEGORIES]),Bv(e)||(e.CATEGORIES=[]),TY(e)||(e.categoryMatches=[]),OY(e)||(e.categoryMatchesMap={})})}Nt.assignTokenDefaultProps=RY;function FY(r){(0,_r.forEach)(r,function(e){e.categoryMatches=[],(0,_r.forEach)(e.categoryMatchesMap,function(t,i){e.categoryMatches.push(Nt.tokenIdxToClass[i].tokenTypeIdx)})})}Nt.assignCategoriesTokensProp=FY;function NY(r){(0,_r.forEach)(r,function(e){Qv([],e)})}Nt.assignCategoriesMapProp=NY;function Qv(r,e){(0,_r.forEach)(r,function(t){e.categoryMatchesMap[t.tokenTypeIdx]=!0}),(0,_r.forEach)(e.CATEGORIES,function(t){var i=r.concat(e);(0,_r.contains)(i,t)||Qv(i,t)})}Nt.singleAssignCategoriesToksMap=Qv;function LY(r){return(0,_r.has)(r,"tokenTypeIdx")}Nt.hasShortKeyProperty=LY;function Bv(r){return(0,_r.has)(r,"CATEGORIES")}Nt.hasCategoriesProperty=Bv;function TY(r){return(0,_r.has)(r,"categoryMatches")}Nt.hasExtendingTokensTypesProperty=TY;function OY(r){return(0,_r.has)(r,"categoryMatchesMap")}Nt.hasExtendingTokensTypesMapProperty=OY;function $me(r){return(0,_r.has)(r,"tokenTypeIdx")}Nt.isTokenType=$me});var bv=w(JI=>{"use strict";Object.defineProperty(JI,"__esModule",{value:!0});JI.defaultLexerErrorProvider=void 0;JI.defaultLexerErrorProvider={buildUnableToPopLexerModeMessage:function(r){return"Unable to pop Lexer Mode after encountering Token ->"+r.image+"<- The Mode Stack is empty"},buildUnexpectedCharactersMessage:function(r,e,t,i,n){return"unexpected character: ->"+r.charAt(e)+"<- at offset: "+e+","+(" skipped "+t+" characters.")}}});var gd=w(nc=>{"use strict";Object.defineProperty(nc,"__esModule",{value:!0});nc.Lexer=nc.LexerDefinitionErrorType=void 0;var zs=Cv(),nr=Gt(),eEe=Gg(),tEe=bv(),rEe=GI(),iEe;(function(r){r[r.MISSING_PATTERN=0]="MISSING_PATTERN",r[r.INVALID_PATTERN=1]="INVALID_PATTERN",r[r.EOI_ANCHOR_FOUND=2]="EOI_ANCHOR_FOUND",r[r.UNSUPPORTED_FLAGS_FOUND=3]="UNSUPPORTED_FLAGS_FOUND",r[r.DUPLICATE_PATTERNS_FOUND=4]="DUPLICATE_PATTERNS_FOUND",r[r.INVALID_GROUP_TYPE_FOUND=5]="INVALID_GROUP_TYPE_FOUND",r[r.PUSH_MODE_DOES_NOT_EXIST=6]="PUSH_MODE_DOES_NOT_EXIST",r[r.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE=7]="MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE",r[r.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY=8]="MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY",r[r.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST=9]="MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST",r[r.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED=10]="LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED",r[r.SOI_ANCHOR_FOUND=11]="SOI_ANCHOR_FOUND",r[r.EMPTY_MATCH_PATTERN=12]="EMPTY_MATCH_PATTERN",r[r.NO_LINE_BREAKS_FLAGS=13]="NO_LINE_BREAKS_FLAGS",r[r.UNREACHABLE_PATTERN=14]="UNREACHABLE_PATTERN",r[r.IDENTIFY_TERMINATOR=15]="IDENTIFY_TERMINATOR",r[r.CUSTOM_LINE_BREAK=16]="CUSTOM_LINE_BREAK"})(iEe=nc.LexerDefinitionErrorType||(nc.LexerDefinitionErrorType={}));var fd={deferDefinitionErrorsHandling:!1,positionTracking:"full",lineTerminatorsPattern:/\n|\r\n?/g,lineTerminatorCharacters:[` +`,"\r"],ensureOptimizations:!1,safeMode:!1,errorMessageProvider:tEe.defaultLexerErrorProvider,traceInitPerf:!1,skipValidations:!1};Object.freeze(fd);var nEe=function(){function r(e,t){var i=this;if(t===void 0&&(t=fd),this.lexerDefinition=e,this.lexerDefinitionErrors=[],this.lexerDefinitionWarning=[],this.patternIdxToConfig={},this.charCodeToPatternIdxToConfig={},this.modes=[],this.emptyGroups={},this.config=void 0,this.trackStartLines=!0,this.trackEndLines=!0,this.hasCustom=!1,this.canModeBeOptimized={},typeof t=="boolean")throw Error(`The second argument to the Lexer constructor is now an ILexerConfig Object. +a boolean 2nd argument is no longer supported`);this.config=(0,nr.merge)(fd,t);var n=this.config.traceInitPerf;n===!0?(this.traceInitMaxIdent=1/0,this.traceInitPerf=!0):typeof n=="number"&&(this.traceInitMaxIdent=n,this.traceInitPerf=!0),this.traceInitIndent=-1,this.TRACE_INIT("Lexer Constructor",function(){var s,o=!0;i.TRACE_INIT("Lexer Config handling",function(){if(i.config.lineTerminatorsPattern===fd.lineTerminatorsPattern)i.config.lineTerminatorsPattern=zs.LineTerminatorOptimizedTester;else if(i.config.lineTerminatorCharacters===fd.lineTerminatorCharacters)throw Error(`Error: Missing property on the Lexer config. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#MISSING_LINE_TERM_CHARS`);if(t.safeMode&&t.ensureOptimizations)throw Error('"safeMode" and "ensureOptimizations" flags are mutually exclusive.');i.trackStartLines=/full|onlyStart/i.test(i.config.positionTracking),i.trackEndLines=/full/i.test(i.config.positionTracking),(0,nr.isArray)(e)?(s={modes:{}},s.modes[zs.DEFAULT_MODE]=(0,nr.cloneArr)(e),s[zs.DEFAULT_MODE]=zs.DEFAULT_MODE):(o=!1,s=(0,nr.cloneObj)(e))}),i.config.skipValidations===!1&&(i.TRACE_INIT("performRuntimeChecks",function(){i.lexerDefinitionErrors=i.lexerDefinitionErrors.concat((0,zs.performRuntimeChecks)(s,i.trackStartLines,i.config.lineTerminatorCharacters))}),i.TRACE_INIT("performWarningRuntimeChecks",function(){i.lexerDefinitionWarning=i.lexerDefinitionWarning.concat((0,zs.performWarningRuntimeChecks)(s,i.trackStartLines,i.config.lineTerminatorCharacters))})),s.modes=s.modes?s.modes:{},(0,nr.forEach)(s.modes,function(u,g){s.modes[g]=(0,nr.reject)(u,function(f){return(0,nr.isUndefined)(f)})});var a=(0,nr.keys)(s.modes);if((0,nr.forEach)(s.modes,function(u,g){i.TRACE_INIT("Mode: <"+g+"> processing",function(){if(i.modes.push(g),i.config.skipValidations===!1&&i.TRACE_INIT("validatePatterns",function(){i.lexerDefinitionErrors=i.lexerDefinitionErrors.concat((0,zs.validatePatterns)(u,a))}),(0,nr.isEmpty)(i.lexerDefinitionErrors)){(0,eEe.augmentTokenTypes)(u);var f;i.TRACE_INIT("analyzeTokenTypes",function(){f=(0,zs.analyzeTokenTypes)(u,{lineTerminatorCharacters:i.config.lineTerminatorCharacters,positionTracking:t.positionTracking,ensureOptimizations:t.ensureOptimizations,safeMode:t.safeMode,tracer:i.TRACE_INIT.bind(i)})}),i.patternIdxToConfig[g]=f.patternIdxToConfig,i.charCodeToPatternIdxToConfig[g]=f.charCodeToPatternIdxToConfig,i.emptyGroups=(0,nr.merge)(i.emptyGroups,f.emptyGroups),i.hasCustom=f.hasCustom||i.hasCustom,i.canModeBeOptimized[g]=f.canBeOptimized}})}),i.defaultMode=s.defaultMode,!(0,nr.isEmpty)(i.lexerDefinitionErrors)&&!i.config.deferDefinitionErrorsHandling){var l=(0,nr.map)(i.lexerDefinitionErrors,function(u){return u.message}),c=l.join(`----------------------- +`);throw new Error(`Errors detected in definition of Lexer: +`+c)}(0,nr.forEach)(i.lexerDefinitionWarning,function(u){(0,nr.PRINT_WARNING)(u.message)}),i.TRACE_INIT("Choosing sub-methods implementations",function(){if(zs.SUPPORT_STICKY?(i.chopInput=nr.IDENTITY,i.match=i.matchWithTest):(i.updateLastIndex=nr.NOOP,i.match=i.matchWithExec),o&&(i.handleModes=nr.NOOP),i.trackStartLines===!1&&(i.computeNewColumn=nr.IDENTITY),i.trackEndLines===!1&&(i.updateTokenEndLineColumnLocation=nr.NOOP),/full/i.test(i.config.positionTracking))i.createTokenInstance=i.createFullToken;else if(/onlyStart/i.test(i.config.positionTracking))i.createTokenInstance=i.createStartOnlyToken;else if(/onlyOffset/i.test(i.config.positionTracking))i.createTokenInstance=i.createOffsetOnlyToken;else throw Error('Invalid config option: "'+i.config.positionTracking+'"');i.hasCustom?(i.addToken=i.addTokenUsingPush,i.handlePayload=i.handlePayloadWithCustom):(i.addToken=i.addTokenUsingMemberAccess,i.handlePayload=i.handlePayloadNoCustom)}),i.TRACE_INIT("Failed Optimization Warnings",function(){var u=(0,nr.reduce)(i.canModeBeOptimized,function(g,f,h){return f===!1&&g.push(h),g},[]);if(t.ensureOptimizations&&!(0,nr.isEmpty)(u))throw Error("Lexer Modes: < "+u.join(", ")+` > cannot be optimized. + Disable the "ensureOptimizations" lexer config flag to silently ignore this and run the lexer in an un-optimized mode. + Or inspect the console log for details on how to resolve these issues.`)}),i.TRACE_INIT("clearRegExpParserCache",function(){(0,rEe.clearRegExpParserCache)()}),i.TRACE_INIT("toFastProperties",function(){(0,nr.toFastProperties)(i)})})}return r.prototype.tokenize=function(e,t){if(t===void 0&&(t=this.defaultMode),!(0,nr.isEmpty)(this.lexerDefinitionErrors)){var i=(0,nr.map)(this.lexerDefinitionErrors,function(o){return o.message}),n=i.join(`----------------------- +`);throw new Error(`Unable to Tokenize because Errors detected in definition of Lexer: +`+n)}var s=this.tokenizeInternal(e,t);return s},r.prototype.tokenizeInternal=function(e,t){var i=this,n,s,o,a,l,c,u,g,f,h,p,C,y,B,v,D,L=e,H=L.length,j=0,$=0,V=this.hasCustom?0:Math.floor(e.length/10),W=new Array(V),Z=[],A=this.trackStartLines?1:void 0,ae=this.trackStartLines?1:void 0,ge=(0,zs.cloneEmptyGroups)(this.emptyGroups),re=this.trackStartLines,O=this.config.lineTerminatorsPattern,F=0,ue=[],he=[],ke=[],Fe=[];Object.freeze(Fe);var Ne=void 0;function oe(){return ue}function le(pr){var Ei=(0,zs.charCodeToOptimizedIndex)(pr),_n=he[Ei];return _n===void 0?Fe:_n}var we=function(pr){if(ke.length===1&&pr.tokenType.PUSH_MODE===void 0){var Ei=i.config.errorMessageProvider.buildUnableToPopLexerModeMessage(pr);Z.push({offset:pr.startOffset,line:pr.startLine!==void 0?pr.startLine:void 0,column:pr.startColumn!==void 0?pr.startColumn:void 0,length:pr.image.length,message:Ei})}else{ke.pop();var _n=(0,nr.last)(ke);ue=i.patternIdxToConfig[_n],he=i.charCodeToPatternIdxToConfig[_n],F=ue.length;var oa=i.canModeBeOptimized[_n]&&i.config.safeMode===!1;he&&oa?Ne=le:Ne=oe}};function fe(pr){ke.push(pr),he=this.charCodeToPatternIdxToConfig[pr],ue=this.patternIdxToConfig[pr],F=ue.length,F=ue.length;var Ei=this.canModeBeOptimized[pr]&&this.config.safeMode===!1;he&&Ei?Ne=le:Ne=oe}fe.call(this,t);for(var Ae;jc.length){c=a,u=g,Ae=tt;break}}}break}}if(c!==null){if(f=c.length,h=Ae.group,h!==void 0&&(p=Ae.tokenTypeIdx,C=this.createTokenInstance(c,j,p,Ae.tokenType,A,ae,f),this.handlePayload(C,u),h===!1?$=this.addToken(W,$,C):ge[h].push(C)),e=this.chopInput(e,f),j=j+f,ae=this.computeNewColumn(ae,f),re===!0&&Ae.canLineTerminator===!0){var It=0,Or=void 0,ii=void 0;O.lastIndex=0;do Or=O.test(c),Or===!0&&(ii=O.lastIndex-1,It++);while(Or===!0);It!==0&&(A=A+It,ae=f-ii,this.updateTokenEndLineColumnLocation(C,h,ii,It,A,ae,f))}this.handleModes(Ae,we,fe,C)}else{for(var gi=j,hr=A,fi=ae,ni=!1;!ni&&j <"+e+">");var n=(0,nr.timer)(t),s=n.time,o=n.value,a=s>10?console.warn:console.log;return this.traceInitIndent time: "+s+"ms"),this.traceInitIndent--,o}else return t()},r.SKIPPED="This marks a skipped Token pattern, this means each token identified by it willbe consumed and then thrown into oblivion, this can be used to for example to completely ignore whitespace.",r.NA=/NOT_APPLICABLE/,r}();nc.Lexer=nEe});var SA=w(Qi=>{"use strict";Object.defineProperty(Qi,"__esModule",{value:!0});Qi.tokenMatcher=Qi.createTokenInstance=Qi.EOF=Qi.createToken=Qi.hasTokenLabel=Qi.tokenName=Qi.tokenLabel=void 0;var Vs=Gt(),sEe=gd(),Sv=Gg();function oEe(r){return JY(r)?r.LABEL:r.name}Qi.tokenLabel=oEe;function aEe(r){return r.name}Qi.tokenName=aEe;function JY(r){return(0,Vs.isString)(r.LABEL)&&r.LABEL!==""}Qi.hasTokenLabel=JY;var AEe="parent",MY="categories",KY="label",UY="group",HY="push_mode",GY="pop_mode",YY="longer_alt",jY="line_breaks",qY="start_chars_hint";function WY(r){return lEe(r)}Qi.createToken=WY;function lEe(r){var e=r.pattern,t={};if(t.name=r.name,(0,Vs.isUndefined)(e)||(t.PATTERN=e),(0,Vs.has)(r,AEe))throw`The parent property is no longer supported. +See: https://github.com/chevrotain/chevrotain/issues/564#issuecomment-349062346 for details.`;return(0,Vs.has)(r,MY)&&(t.CATEGORIES=r[MY]),(0,Sv.augmentTokenTypes)([t]),(0,Vs.has)(r,KY)&&(t.LABEL=r[KY]),(0,Vs.has)(r,UY)&&(t.GROUP=r[UY]),(0,Vs.has)(r,GY)&&(t.POP_MODE=r[GY]),(0,Vs.has)(r,HY)&&(t.PUSH_MODE=r[HY]),(0,Vs.has)(r,YY)&&(t.LONGER_ALT=r[YY]),(0,Vs.has)(r,jY)&&(t.LINE_BREAKS=r[jY]),(0,Vs.has)(r,qY)&&(t.START_CHARS_HINT=r[qY]),t}Qi.EOF=WY({name:"EOF",pattern:sEe.Lexer.NA});(0,Sv.augmentTokenTypes)([Qi.EOF]);function cEe(r,e,t,i,n,s,o,a){return{image:e,startOffset:t,endOffset:i,startLine:n,endLine:s,startColumn:o,endColumn:a,tokenTypeIdx:r.tokenTypeIdx,tokenType:r}}Qi.createTokenInstance=cEe;function uEe(r,e){return(0,Sv.tokenStructuredMatcher)(r,e)}Qi.tokenMatcher=uEe});var dn=w(Wt=>{"use strict";var wa=Wt&&Wt.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Wt,"__esModule",{value:!0});Wt.serializeProduction=Wt.serializeGrammar=Wt.Terminal=Wt.Alternation=Wt.RepetitionWithSeparator=Wt.Repetition=Wt.RepetitionMandatoryWithSeparator=Wt.RepetitionMandatory=Wt.Option=Wt.Alternative=Wt.Rule=Wt.NonTerminal=Wt.AbstractProduction=void 0;var Ar=Gt(),gEe=SA(),vo=function(){function r(e){this._definition=e}return Object.defineProperty(r.prototype,"definition",{get:function(){return this._definition},set:function(e){this._definition=e},enumerable:!1,configurable:!0}),r.prototype.accept=function(e){e.visit(this),(0,Ar.forEach)(this.definition,function(t){t.accept(e)})},r}();Wt.AbstractProduction=vo;var zY=function(r){wa(e,r);function e(t){var i=r.call(this,[])||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return Object.defineProperty(e.prototype,"definition",{get:function(){return this.referencedRule!==void 0?this.referencedRule.definition:[]},set:function(t){},enumerable:!1,configurable:!0}),e.prototype.accept=function(t){t.visit(this)},e}(vo);Wt.NonTerminal=zY;var VY=function(r){wa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.orgText="",(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(vo);Wt.Rule=VY;var XY=function(r){wa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.ignoreAmbiguities=!1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(vo);Wt.Alternative=XY;var _Y=function(r){wa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(vo);Wt.Option=_Y;var ZY=function(r){wa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(vo);Wt.RepetitionMandatory=ZY;var $Y=function(r){wa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(vo);Wt.RepetitionMandatoryWithSeparator=$Y;var ej=function(r){wa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(vo);Wt.Repetition=ej;var tj=function(r){wa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(vo);Wt.RepetitionWithSeparator=tj;var rj=function(r){wa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,i.ignoreAmbiguities=!1,i.hasPredicates=!1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return Object.defineProperty(e.prototype,"definition",{get:function(){return this._definition},set:function(t){this._definition=t},enumerable:!1,configurable:!0}),e}(vo);Wt.Alternation=rj;var WI=function(){function r(e){this.idx=1,(0,Ar.assign)(this,(0,Ar.pick)(e,function(t){return t!==void 0}))}return r.prototype.accept=function(e){e.visit(this)},r}();Wt.Terminal=WI;function fEe(r){return(0,Ar.map)(r,hd)}Wt.serializeGrammar=fEe;function hd(r){function e(s){return(0,Ar.map)(s,hd)}if(r instanceof zY){var t={type:"NonTerminal",name:r.nonTerminalName,idx:r.idx};return(0,Ar.isString)(r.label)&&(t.label=r.label),t}else{if(r instanceof XY)return{type:"Alternative",definition:e(r.definition)};if(r instanceof _Y)return{type:"Option",idx:r.idx,definition:e(r.definition)};if(r instanceof ZY)return{type:"RepetitionMandatory",idx:r.idx,definition:e(r.definition)};if(r instanceof $Y)return{type:"RepetitionMandatoryWithSeparator",idx:r.idx,separator:hd(new WI({terminalType:r.separator})),definition:e(r.definition)};if(r instanceof tj)return{type:"RepetitionWithSeparator",idx:r.idx,separator:hd(new WI({terminalType:r.separator})),definition:e(r.definition)};if(r instanceof ej)return{type:"Repetition",idx:r.idx,definition:e(r.definition)};if(r instanceof rj)return{type:"Alternation",idx:r.idx,definition:e(r.definition)};if(r instanceof WI){var i={type:"Terminal",name:r.terminalType.name,label:(0,gEe.tokenLabel)(r.terminalType),idx:r.idx};(0,Ar.isString)(r.label)&&(i.terminalLabel=r.label);var n=r.terminalType.PATTERN;return r.terminalType.PATTERN&&(i.pattern=(0,Ar.isRegExp)(n)?n.source:n),i}else{if(r instanceof VY)return{type:"Rule",name:r.name,orgText:r.orgText,definition:e(r.definition)};throw Error("non exhaustive match")}}}Wt.serializeProduction=hd});var VI=w(zI=>{"use strict";Object.defineProperty(zI,"__esModule",{value:!0});zI.RestWalker=void 0;var vv=Gt(),Cn=dn(),hEe=function(){function r(){}return r.prototype.walk=function(e,t){var i=this;t===void 0&&(t=[]),(0,vv.forEach)(e.definition,function(n,s){var o=(0,vv.drop)(e.definition,s+1);if(n instanceof Cn.NonTerminal)i.walkProdRef(n,o,t);else if(n instanceof Cn.Terminal)i.walkTerminal(n,o,t);else if(n instanceof Cn.Alternative)i.walkFlat(n,o,t);else if(n instanceof Cn.Option)i.walkOption(n,o,t);else if(n instanceof Cn.RepetitionMandatory)i.walkAtLeastOne(n,o,t);else if(n instanceof Cn.RepetitionMandatoryWithSeparator)i.walkAtLeastOneSep(n,o,t);else if(n instanceof Cn.RepetitionWithSeparator)i.walkManySep(n,o,t);else if(n instanceof Cn.Repetition)i.walkMany(n,o,t);else if(n instanceof Cn.Alternation)i.walkOr(n,o,t);else throw Error("non exhaustive match")})},r.prototype.walkTerminal=function(e,t,i){},r.prototype.walkProdRef=function(e,t,i){},r.prototype.walkFlat=function(e,t,i){var n=t.concat(i);this.walk(e,n)},r.prototype.walkOption=function(e,t,i){var n=t.concat(i);this.walk(e,n)},r.prototype.walkAtLeastOne=function(e,t,i){var n=[new Cn.Option({definition:e.definition})].concat(t,i);this.walk(e,n)},r.prototype.walkAtLeastOneSep=function(e,t,i){var n=ij(e,t,i);this.walk(e,n)},r.prototype.walkMany=function(e,t,i){var n=[new Cn.Option({definition:e.definition})].concat(t,i);this.walk(e,n)},r.prototype.walkManySep=function(e,t,i){var n=ij(e,t,i);this.walk(e,n)},r.prototype.walkOr=function(e,t,i){var n=this,s=t.concat(i);(0,vv.forEach)(e.definition,function(o){var a=new Cn.Alternative({definition:[o]});n.walk(a,s)})},r}();zI.RestWalker=hEe;function ij(r,e,t){var i=[new Cn.Option({definition:[new Cn.Terminal({terminalType:r.separator})].concat(r.definition)})],n=i.concat(e,t);return n}});var Yg=w(XI=>{"use strict";Object.defineProperty(XI,"__esModule",{value:!0});XI.GAstVisitor=void 0;var xo=dn(),pEe=function(){function r(){}return r.prototype.visit=function(e){var t=e;switch(t.constructor){case xo.NonTerminal:return this.visitNonTerminal(t);case xo.Alternative:return this.visitAlternative(t);case xo.Option:return this.visitOption(t);case xo.RepetitionMandatory:return this.visitRepetitionMandatory(t);case xo.RepetitionMandatoryWithSeparator:return this.visitRepetitionMandatoryWithSeparator(t);case xo.RepetitionWithSeparator:return this.visitRepetitionWithSeparator(t);case xo.Repetition:return this.visitRepetition(t);case xo.Alternation:return this.visitAlternation(t);case xo.Terminal:return this.visitTerminal(t);case xo.Rule:return this.visitRule(t);default:throw Error("non exhaustive match")}},r.prototype.visitNonTerminal=function(e){},r.prototype.visitAlternative=function(e){},r.prototype.visitOption=function(e){},r.prototype.visitRepetition=function(e){},r.prototype.visitRepetitionMandatory=function(e){},r.prototype.visitRepetitionMandatoryWithSeparator=function(e){},r.prototype.visitRepetitionWithSeparator=function(e){},r.prototype.visitAlternation=function(e){},r.prototype.visitTerminal=function(e){},r.prototype.visitRule=function(e){},r}();XI.GAstVisitor=pEe});var dd=w(Oi=>{"use strict";var dEe=Oi&&Oi.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Oi,"__esModule",{value:!0});Oi.collectMethods=Oi.DslMethodsCollectorVisitor=Oi.getProductionDslName=Oi.isBranchingProd=Oi.isOptionalProd=Oi.isSequenceProd=void 0;var pd=Gt(),Qr=dn(),CEe=Yg();function mEe(r){return r instanceof Qr.Alternative||r instanceof Qr.Option||r instanceof Qr.Repetition||r instanceof Qr.RepetitionMandatory||r instanceof Qr.RepetitionMandatoryWithSeparator||r instanceof Qr.RepetitionWithSeparator||r instanceof Qr.Terminal||r instanceof Qr.Rule}Oi.isSequenceProd=mEe;function xv(r,e){e===void 0&&(e=[]);var t=r instanceof Qr.Option||r instanceof Qr.Repetition||r instanceof Qr.RepetitionWithSeparator;return t?!0:r instanceof Qr.Alternation?(0,pd.some)(r.definition,function(i){return xv(i,e)}):r instanceof Qr.NonTerminal&&(0,pd.contains)(e,r)?!1:r instanceof Qr.AbstractProduction?(r instanceof Qr.NonTerminal&&e.push(r),(0,pd.every)(r.definition,function(i){return xv(i,e)})):!1}Oi.isOptionalProd=xv;function EEe(r){return r instanceof Qr.Alternation}Oi.isBranchingProd=EEe;function IEe(r){if(r instanceof Qr.NonTerminal)return"SUBRULE";if(r instanceof Qr.Option)return"OPTION";if(r instanceof Qr.Alternation)return"OR";if(r instanceof Qr.RepetitionMandatory)return"AT_LEAST_ONE";if(r instanceof Qr.RepetitionMandatoryWithSeparator)return"AT_LEAST_ONE_SEP";if(r instanceof Qr.RepetitionWithSeparator)return"MANY_SEP";if(r instanceof Qr.Repetition)return"MANY";if(r instanceof Qr.Terminal)return"CONSUME";throw Error("non exhaustive match")}Oi.getProductionDslName=IEe;var nj=function(r){dEe(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.separator="-",t.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]},t}return e.prototype.reset=function(){this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}},e.prototype.visitTerminal=function(t){var i=t.terminalType.name+this.separator+"Terminal";(0,pd.has)(this.dslMethods,i)||(this.dslMethods[i]=[]),this.dslMethods[i].push(t)},e.prototype.visitNonTerminal=function(t){var i=t.nonTerminalName+this.separator+"Terminal";(0,pd.has)(this.dslMethods,i)||(this.dslMethods[i]=[]),this.dslMethods[i].push(t)},e.prototype.visitOption=function(t){this.dslMethods.option.push(t)},e.prototype.visitRepetitionWithSeparator=function(t){this.dslMethods.repetitionWithSeparator.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.dslMethods.repetitionMandatory.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.dslMethods.repetitionMandatoryWithSeparator.push(t)},e.prototype.visitRepetition=function(t){this.dslMethods.repetition.push(t)},e.prototype.visitAlternation=function(t){this.dslMethods.alternation.push(t)},e}(CEe.GAstVisitor);Oi.DslMethodsCollectorVisitor=nj;var _I=new nj;function yEe(r){_I.reset(),r.accept(_I);var e=_I.dslMethods;return _I.reset(),e}Oi.collectMethods=yEe});var Dv=w(Po=>{"use strict";Object.defineProperty(Po,"__esModule",{value:!0});Po.firstForTerminal=Po.firstForBranching=Po.firstForSequence=Po.first=void 0;var ZI=Gt(),sj=dn(),Pv=dd();function $I(r){if(r instanceof sj.NonTerminal)return $I(r.referencedRule);if(r instanceof sj.Terminal)return Aj(r);if((0,Pv.isSequenceProd)(r))return oj(r);if((0,Pv.isBranchingProd)(r))return aj(r);throw Error("non exhaustive match")}Po.first=$I;function oj(r){for(var e=[],t=r.definition,i=0,n=t.length>i,s,o=!0;n&&o;)s=t[i],o=(0,Pv.isOptionalProd)(s),e=e.concat($I(s)),i=i+1,n=t.length>i;return(0,ZI.uniq)(e)}Po.firstForSequence=oj;function aj(r){var e=(0,ZI.map)(r.definition,function(t){return $I(t)});return(0,ZI.uniq)((0,ZI.flatten)(e))}Po.firstForBranching=aj;function Aj(r){return[r.terminalType]}Po.firstForTerminal=Aj});var kv=w(ey=>{"use strict";Object.defineProperty(ey,"__esModule",{value:!0});ey.IN=void 0;ey.IN="_~IN~_"});var fj=w(As=>{"use strict";var wEe=As&&As.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(As,"__esModule",{value:!0});As.buildInProdFollowPrefix=As.buildBetweenProdsFollowPrefix=As.computeAllProdsFollows=As.ResyncFollowsWalker=void 0;var BEe=VI(),QEe=Dv(),lj=Gt(),cj=kv(),bEe=dn(),uj=function(r){wEe(e,r);function e(t){var i=r.call(this)||this;return i.topProd=t,i.follows={},i}return e.prototype.startWalking=function(){return this.walk(this.topProd),this.follows},e.prototype.walkTerminal=function(t,i,n){},e.prototype.walkProdRef=function(t,i,n){var s=gj(t.referencedRule,t.idx)+this.topProd.name,o=i.concat(n),a=new bEe.Alternative({definition:o}),l=(0,QEe.first)(a);this.follows[s]=l},e}(BEe.RestWalker);As.ResyncFollowsWalker=uj;function SEe(r){var e={};return(0,lj.forEach)(r,function(t){var i=new uj(t).startWalking();(0,lj.assign)(e,i)}),e}As.computeAllProdsFollows=SEe;function gj(r,e){return r.name+e+cj.IN}As.buildBetweenProdsFollowPrefix=gj;function vEe(r){var e=r.terminalType.name;return e+r.idx+cj.IN}As.buildInProdFollowPrefix=vEe});var Cd=w(Ba=>{"use strict";Object.defineProperty(Ba,"__esModule",{value:!0});Ba.defaultGrammarValidatorErrorProvider=Ba.defaultGrammarResolverErrorProvider=Ba.defaultParserErrorProvider=void 0;var jg=SA(),xEe=Gt(),Xs=Gt(),Rv=dn(),hj=dd();Ba.defaultParserErrorProvider={buildMismatchTokenMessage:function(r){var e=r.expected,t=r.actual,i=r.previous,n=r.ruleName,s=(0,jg.hasTokenLabel)(e),o=s?"--> "+(0,jg.tokenLabel)(e)+" <--":"token of type --> "+e.name+" <--",a="Expecting "+o+" but found --> '"+t.image+"' <--";return a},buildNotAllInputParsedMessage:function(r){var e=r.firstRedundant,t=r.ruleName;return"Redundant input, expecting EOF but found: "+e.image},buildNoViableAltMessage:function(r){var e=r.expectedPathsPerAlt,t=r.actual,i=r.previous,n=r.customUserDescription,s=r.ruleName,o="Expecting: ",a=(0,Xs.first)(t).image,l=` +but found: '`+a+"'";if(n)return o+n+l;var c=(0,Xs.reduce)(e,function(h,p){return h.concat(p)},[]),u=(0,Xs.map)(c,function(h){return"["+(0,Xs.map)(h,function(p){return(0,jg.tokenLabel)(p)}).join(", ")+"]"}),g=(0,Xs.map)(u,function(h,p){return" "+(p+1)+". "+h}),f=`one of these possible Token sequences: +`+g.join(` +`);return o+f+l},buildEarlyExitMessage:function(r){var e=r.expectedIterationPaths,t=r.actual,i=r.customUserDescription,n=r.ruleName,s="Expecting: ",o=(0,Xs.first)(t).image,a=` +but found: '`+o+"'";if(i)return s+i+a;var l=(0,Xs.map)(e,function(u){return"["+(0,Xs.map)(u,function(g){return(0,jg.tokenLabel)(g)}).join(",")+"]"}),c=`expecting at least one iteration which starts with one of these possible Token sequences:: + `+("<"+l.join(" ,")+">");return s+c+a}};Object.freeze(Ba.defaultParserErrorProvider);Ba.defaultGrammarResolverErrorProvider={buildRuleNotFoundError:function(r,e){var t="Invalid grammar, reference to a rule which is not defined: ->"+e.nonTerminalName+`<- +inside top level rule: ->`+r.name+"<-";return t}};Ba.defaultGrammarValidatorErrorProvider={buildDuplicateFoundError:function(r,e){function t(u){return u instanceof Rv.Terminal?u.terminalType.name:u instanceof Rv.NonTerminal?u.nonTerminalName:""}var i=r.name,n=(0,Xs.first)(e),s=n.idx,o=(0,hj.getProductionDslName)(n),a=t(n),l=s>0,c="->"+o+(l?s:"")+"<- "+(a?"with argument: ->"+a+"<-":"")+` + appears more than once (`+e.length+" times) in the top level rule: ->"+i+`<-. + For further details see: https://chevrotain.io/docs/FAQ.html#NUMERICAL_SUFFIXES + `;return c=c.replace(/[ \t]+/g," "),c=c.replace(/\s\s+/g,` +`),c},buildNamespaceConflictError:function(r){var e=`Namespace conflict found in grammar. +`+("The grammar has both a Terminal(Token) and a Non-Terminal(Rule) named: <"+r.name+`>. +`)+`To resolve this make sure each Terminal and Non-Terminal names are unique +This is easy to accomplish by using the convention that Terminal names start with an uppercase letter +and Non-Terminal names start with a lower case letter.`;return e},buildAlternationPrefixAmbiguityError:function(r){var e=(0,Xs.map)(r.prefixPath,function(n){return(0,jg.tokenLabel)(n)}).join(", "),t=r.alternation.idx===0?"":r.alternation.idx,i="Ambiguous alternatives: <"+r.ambiguityIndices.join(" ,")+`> due to common lookahead prefix +`+("in inside <"+r.topLevelRule.name+`> Rule, +`)+("<"+e+`> may appears as a prefix path in all these alternatives. +`)+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX +For Further details.`;return i},buildAlternationAmbiguityError:function(r){var e=(0,Xs.map)(r.prefixPath,function(n){return(0,jg.tokenLabel)(n)}).join(", "),t=r.alternation.idx===0?"":r.alternation.idx,i="Ambiguous Alternatives Detected: <"+r.ambiguityIndices.join(" ,")+"> in "+(" inside <"+r.topLevelRule.name+`> Rule, +`)+("<"+e+`> may appears as a prefix path in all these alternatives. +`);return i=i+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES +For Further details.`,i},buildEmptyRepetitionError:function(r){var e=(0,hj.getProductionDslName)(r.repetition);r.repetition.idx!==0&&(e+=r.repetition.idx);var t="The repetition <"+e+"> within Rule <"+r.topLevelRule.name+`> can never consume any tokens. +This could lead to an infinite loop.`;return t},buildTokenNameError:function(r){return"deprecated"},buildEmptyAlternationError:function(r){var e="Ambiguous empty alternative: <"+(r.emptyChoiceIdx+1)+">"+(" in inside <"+r.topLevelRule.name+`> Rule. +`)+"Only the last alternative may be an empty alternative.";return e},buildTooManyAlternativesError:function(r){var e=`An Alternation cannot have more than 256 alternatives: +`+(" inside <"+r.topLevelRule.name+`> Rule. + has `+(r.alternation.definition.length+1)+" alternatives.");return e},buildLeftRecursionError:function(r){var e=r.topLevelRule.name,t=xEe.map(r.leftRecursionPath,function(s){return s.name}),i=e+" --> "+t.concat([e]).join(" --> "),n=`Left Recursion found in grammar. +`+("rule: <"+e+`> can be invoked from itself (directly or indirectly) +`)+(`without consuming any Tokens. The grammar path that causes this is: + `+i+` +`)+` To fix this refactor your grammar to remove the left recursion. +see: https://en.wikipedia.org/wiki/LL_parser#Left_Factoring.`;return n},buildInvalidRuleNameError:function(r){return"deprecated"},buildDuplicateRuleNameError:function(r){var e;r.topLevelRule instanceof Rv.Rule?e=r.topLevelRule.name:e=r.topLevelRule;var t="Duplicate definition, rule: ->"+e+"<- is already defined in the grammar: ->"+r.grammarName+"<-";return t}}});var Cj=w(vA=>{"use strict";var PEe=vA&&vA.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(vA,"__esModule",{value:!0});vA.GastRefResolverVisitor=vA.resolveGrammar=void 0;var DEe=Hn(),pj=Gt(),kEe=Yg();function REe(r,e){var t=new dj(r,e);return t.resolveRefs(),t.errors}vA.resolveGrammar=REe;var dj=function(r){PEe(e,r);function e(t,i){var n=r.call(this)||this;return n.nameToTopRule=t,n.errMsgProvider=i,n.errors=[],n}return e.prototype.resolveRefs=function(){var t=this;(0,pj.forEach)((0,pj.values)(this.nameToTopRule),function(i){t.currTopLevel=i,i.accept(t)})},e.prototype.visitNonTerminal=function(t){var i=this.nameToTopRule[t.nonTerminalName];if(i)t.referencedRule=i;else{var n=this.errMsgProvider.buildRuleNotFoundError(this.currTopLevel,t);this.errors.push({message:n,type:DEe.ParserDefinitionErrorType.UNRESOLVED_SUBRULE_REF,ruleName:this.currTopLevel.name,unresolvedRefName:t.nonTerminalName})}},e}(kEe.GAstVisitor);vA.GastRefResolverVisitor=dj});var Ed=w(Nr=>{"use strict";var sc=Nr&&Nr.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Nr,"__esModule",{value:!0});Nr.nextPossibleTokensAfter=Nr.possiblePathsFrom=Nr.NextTerminalAfterAtLeastOneSepWalker=Nr.NextTerminalAfterAtLeastOneWalker=Nr.NextTerminalAfterManySepWalker=Nr.NextTerminalAfterManyWalker=Nr.AbstractNextTerminalAfterProductionWalker=Nr.NextAfterTokenWalker=Nr.AbstractNextPossibleTokensWalker=void 0;var mj=VI(),Kt=Gt(),FEe=Dv(),kt=dn(),Ej=function(r){sc(e,r);function e(t,i){var n=r.call(this)||this;return n.topProd=t,n.path=i,n.possibleTokTypes=[],n.nextProductionName="",n.nextProductionOccurrence=0,n.found=!1,n.isAtEndOfPath=!1,n}return e.prototype.startWalking=function(){if(this.found=!1,this.path.ruleStack[0]!==this.topProd.name)throw Error("The path does not start with the walker's top Rule!");return this.ruleStack=(0,Kt.cloneArr)(this.path.ruleStack).reverse(),this.occurrenceStack=(0,Kt.cloneArr)(this.path.occurrenceStack).reverse(),this.ruleStack.pop(),this.occurrenceStack.pop(),this.updateExpectedNext(),this.walk(this.topProd),this.possibleTokTypes},e.prototype.walk=function(t,i){i===void 0&&(i=[]),this.found||r.prototype.walk.call(this,t,i)},e.prototype.walkProdRef=function(t,i,n){if(t.referencedRule.name===this.nextProductionName&&t.idx===this.nextProductionOccurrence){var s=i.concat(n);this.updateExpectedNext(),this.walk(t.referencedRule,s)}},e.prototype.updateExpectedNext=function(){(0,Kt.isEmpty)(this.ruleStack)?(this.nextProductionName="",this.nextProductionOccurrence=0,this.isAtEndOfPath=!0):(this.nextProductionName=this.ruleStack.pop(),this.nextProductionOccurrence=this.occurrenceStack.pop())},e}(mj.RestWalker);Nr.AbstractNextPossibleTokensWalker=Ej;var NEe=function(r){sc(e,r);function e(t,i){var n=r.call(this,t,i)||this;return n.path=i,n.nextTerminalName="",n.nextTerminalOccurrence=0,n.nextTerminalName=n.path.lastTok.name,n.nextTerminalOccurrence=n.path.lastTokOccurrence,n}return e.prototype.walkTerminal=function(t,i,n){if(this.isAtEndOfPath&&t.terminalType.name===this.nextTerminalName&&t.idx===this.nextTerminalOccurrence&&!this.found){var s=i.concat(n),o=new kt.Alternative({definition:s});this.possibleTokTypes=(0,FEe.first)(o),this.found=!0}},e}(Ej);Nr.NextAfterTokenWalker=NEe;var md=function(r){sc(e,r);function e(t,i){var n=r.call(this)||this;return n.topRule=t,n.occurrence=i,n.result={token:void 0,occurrence:void 0,isEndOfRule:void 0},n}return e.prototype.startWalking=function(){return this.walk(this.topRule),this.result},e}(mj.RestWalker);Nr.AbstractNextTerminalAfterProductionWalker=md;var LEe=function(r){sc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkMany=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Kt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkMany.call(this,t,i,n)},e}(md);Nr.NextTerminalAfterManyWalker=LEe;var TEe=function(r){sc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkManySep=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Kt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkManySep.call(this,t,i,n)},e}(md);Nr.NextTerminalAfterManySepWalker=TEe;var OEe=function(r){sc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkAtLeastOne=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Kt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkAtLeastOne.call(this,t,i,n)},e}(md);Nr.NextTerminalAfterAtLeastOneWalker=OEe;var MEe=function(r){sc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkAtLeastOneSep=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Kt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkAtLeastOneSep.call(this,t,i,n)},e}(md);Nr.NextTerminalAfterAtLeastOneSepWalker=MEe;function Ij(r,e,t){t===void 0&&(t=[]),t=(0,Kt.cloneArr)(t);var i=[],n=0;function s(c){return c.concat((0,Kt.drop)(r,n+1))}function o(c){var u=Ij(s(c),e,t);return i.concat(u)}for(;t.length=0;ge--){var re=B.definition[ge],O={idx:p,def:re.definition.concat((0,Kt.drop)(h)),ruleStack:C,occurrenceStack:y};g.push(O),g.push(o)}else if(B instanceof kt.Alternative)g.push({idx:p,def:B.definition.concat((0,Kt.drop)(h)),ruleStack:C,occurrenceStack:y});else if(B instanceof kt.Rule)g.push(UEe(B,p,C,y));else throw Error("non exhaustive match")}}return u}Nr.nextPossibleTokensAfter=KEe;function UEe(r,e,t,i){var n=(0,Kt.cloneArr)(t);n.push(r.name);var s=(0,Kt.cloneArr)(i);return s.push(1),{idx:e,def:r.definition,ruleStack:n,occurrenceStack:s}}});var Id=w(_t=>{"use strict";var Bj=_t&&_t.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(_t,"__esModule",{value:!0});_t.areTokenCategoriesNotUsed=_t.isStrictPrefixOfPath=_t.containsPath=_t.getLookaheadPathsForOptionalProd=_t.getLookaheadPathsForOr=_t.lookAheadSequenceFromAlternatives=_t.buildSingleAlternativeLookaheadFunction=_t.buildAlternativesLookAheadFunc=_t.buildLookaheadFuncForOptionalProd=_t.buildLookaheadFuncForOr=_t.getProdType=_t.PROD_TYPE=void 0;var sr=Gt(),yj=Ed(),HEe=VI(),ty=Gg(),xA=dn(),GEe=Yg(),oi;(function(r){r[r.OPTION=0]="OPTION",r[r.REPETITION=1]="REPETITION",r[r.REPETITION_MANDATORY=2]="REPETITION_MANDATORY",r[r.REPETITION_MANDATORY_WITH_SEPARATOR=3]="REPETITION_MANDATORY_WITH_SEPARATOR",r[r.REPETITION_WITH_SEPARATOR=4]="REPETITION_WITH_SEPARATOR",r[r.ALTERNATION=5]="ALTERNATION"})(oi=_t.PROD_TYPE||(_t.PROD_TYPE={}));function YEe(r){if(r instanceof xA.Option)return oi.OPTION;if(r instanceof xA.Repetition)return oi.REPETITION;if(r instanceof xA.RepetitionMandatory)return oi.REPETITION_MANDATORY;if(r instanceof xA.RepetitionMandatoryWithSeparator)return oi.REPETITION_MANDATORY_WITH_SEPARATOR;if(r instanceof xA.RepetitionWithSeparator)return oi.REPETITION_WITH_SEPARATOR;if(r instanceof xA.Alternation)return oi.ALTERNATION;throw Error("non exhaustive match")}_t.getProdType=YEe;function jEe(r,e,t,i,n,s){var o=bj(r,e,t),a=Lv(o)?ty.tokenStructuredMatcherNoCategories:ty.tokenStructuredMatcher;return s(o,i,a,n)}_t.buildLookaheadFuncForOr=jEe;function qEe(r,e,t,i,n,s){var o=Sj(r,e,n,t),a=Lv(o)?ty.tokenStructuredMatcherNoCategories:ty.tokenStructuredMatcher;return s(o[0],a,i)}_t.buildLookaheadFuncForOptionalProd=qEe;function JEe(r,e,t,i){var n=r.length,s=(0,sr.every)(r,function(l){return(0,sr.every)(l,function(c){return c.length===1})});if(e)return function(l){for(var c=(0,sr.map)(l,function(D){return D.GATE}),u=0;u{"use strict";var Tv=zt&&zt.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(zt,"__esModule",{value:!0});zt.checkPrefixAlternativesAmbiguities=zt.validateSomeNonEmptyLookaheadPath=zt.validateTooManyAlts=zt.RepetionCollector=zt.validateAmbiguousAlternationAlternatives=zt.validateEmptyOrAlternative=zt.getFirstNoneTerminal=zt.validateNoLeftRecursion=zt.validateRuleIsOverridden=zt.validateRuleDoesNotAlreadyExist=zt.OccurrenceValidationCollector=zt.identifyProductionForDuplicates=zt.validateGrammar=void 0;var er=Gt(),br=Gt(),Do=Hn(),Ov=dd(),qg=Id(),_Ee=Ed(),_s=dn(),Mv=Yg();function ZEe(r,e,t,i,n){var s=er.map(r,function(h){return $Ee(h,i)}),o=er.map(r,function(h){return Kv(h,h,i)}),a=[],l=[],c=[];(0,br.every)(o,br.isEmpty)&&(a=(0,br.map)(r,function(h){return Rj(h,i)}),l=(0,br.map)(r,function(h){return Fj(h,e,i)}),c=Tj(r,e,i));var u=rIe(r,t,i),g=(0,br.map)(r,function(h){return Lj(h,i)}),f=(0,br.map)(r,function(h){return kj(h,r,n,i)});return er.flatten(s.concat(c,o,a,l,u,g,f))}zt.validateGrammar=ZEe;function $Ee(r,e){var t=new Dj;r.accept(t);var i=t.allProductions,n=er.groupBy(i,xj),s=er.pick(n,function(a){return a.length>1}),o=er.map(er.values(s),function(a){var l=er.first(a),c=e.buildDuplicateFoundError(r,a),u=(0,Ov.getProductionDslName)(l),g={message:c,type:Do.ParserDefinitionErrorType.DUPLICATE_PRODUCTIONS,ruleName:r.name,dslName:u,occurrence:l.idx},f=Pj(l);return f&&(g.parameter=f),g});return o}function xj(r){return(0,Ov.getProductionDslName)(r)+"_#_"+r.idx+"_#_"+Pj(r)}zt.identifyProductionForDuplicates=xj;function Pj(r){return r instanceof _s.Terminal?r.terminalType.name:r instanceof _s.NonTerminal?r.nonTerminalName:""}var Dj=function(r){Tv(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.allProductions=[],t}return e.prototype.visitNonTerminal=function(t){this.allProductions.push(t)},e.prototype.visitOption=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetition=function(t){this.allProductions.push(t)},e.prototype.visitAlternation=function(t){this.allProductions.push(t)},e.prototype.visitTerminal=function(t){this.allProductions.push(t)},e}(Mv.GAstVisitor);zt.OccurrenceValidationCollector=Dj;function kj(r,e,t,i){var n=[],s=(0,br.reduce)(e,function(a,l){return l.name===r.name?a+1:a},0);if(s>1){var o=i.buildDuplicateRuleNameError({topLevelRule:r,grammarName:t});n.push({message:o,type:Do.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:r.name})}return n}zt.validateRuleDoesNotAlreadyExist=kj;function eIe(r,e,t){var i=[],n;return er.contains(e,r)||(n="Invalid rule override, rule: ->"+r+"<- cannot be overridden in the grammar: ->"+t+"<-as it is not defined in any of the super grammars ",i.push({message:n,type:Do.ParserDefinitionErrorType.INVALID_RULE_OVERRIDE,ruleName:r})),i}zt.validateRuleIsOverridden=eIe;function Kv(r,e,t,i){i===void 0&&(i=[]);var n=[],s=yd(e.definition);if(er.isEmpty(s))return[];var o=r.name,a=er.contains(s,r);a&&n.push({message:t.buildLeftRecursionError({topLevelRule:r,leftRecursionPath:i}),type:Do.ParserDefinitionErrorType.LEFT_RECURSION,ruleName:o});var l=er.difference(s,i.concat([r])),c=er.map(l,function(u){var g=er.cloneArr(i);return g.push(u),Kv(r,u,t,g)});return n.concat(er.flatten(c))}zt.validateNoLeftRecursion=Kv;function yd(r){var e=[];if(er.isEmpty(r))return e;var t=er.first(r);if(t instanceof _s.NonTerminal)e.push(t.referencedRule);else if(t instanceof _s.Alternative||t instanceof _s.Option||t instanceof _s.RepetitionMandatory||t instanceof _s.RepetitionMandatoryWithSeparator||t instanceof _s.RepetitionWithSeparator||t instanceof _s.Repetition)e=e.concat(yd(t.definition));else if(t instanceof _s.Alternation)e=er.flatten(er.map(t.definition,function(o){return yd(o.definition)}));else if(!(t instanceof _s.Terminal))throw Error("non exhaustive match");var i=(0,Ov.isOptionalProd)(t),n=r.length>1;if(i&&n){var s=er.drop(r);return e.concat(yd(s))}else return e}zt.getFirstNoneTerminal=yd;var Uv=function(r){Tv(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.alternations=[],t}return e.prototype.visitAlternation=function(t){this.alternations.push(t)},e}(Mv.GAstVisitor);function Rj(r,e){var t=new Uv;r.accept(t);var i=t.alternations,n=er.reduce(i,function(s,o){var a=er.dropRight(o.definition),l=er.map(a,function(c,u){var g=(0,_Ee.nextPossibleTokensAfter)([c],[],null,1);return er.isEmpty(g)?{message:e.buildEmptyAlternationError({topLevelRule:r,alternation:o,emptyChoiceIdx:u}),type:Do.ParserDefinitionErrorType.NONE_LAST_EMPTY_ALT,ruleName:r.name,occurrence:o.idx,alternative:u+1}:null});return s.concat(er.compact(l))},[]);return n}zt.validateEmptyOrAlternative=Rj;function Fj(r,e,t){var i=new Uv;r.accept(i);var n=i.alternations;n=(0,br.reject)(n,function(o){return o.ignoreAmbiguities===!0});var s=er.reduce(n,function(o,a){var l=a.idx,c=a.maxLookahead||e,u=(0,qg.getLookaheadPathsForOr)(l,r,c,a),g=tIe(u,a,r,t),f=Oj(u,a,r,t);return o.concat(g,f)},[]);return s}zt.validateAmbiguousAlternationAlternatives=Fj;var Nj=function(r){Tv(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.allProductions=[],t}return e.prototype.visitRepetitionWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetition=function(t){this.allProductions.push(t)},e}(Mv.GAstVisitor);zt.RepetionCollector=Nj;function Lj(r,e){var t=new Uv;r.accept(t);var i=t.alternations,n=er.reduce(i,function(s,o){return o.definition.length>255&&s.push({message:e.buildTooManyAlternativesError({topLevelRule:r,alternation:o}),type:Do.ParserDefinitionErrorType.TOO_MANY_ALTS,ruleName:r.name,occurrence:o.idx}),s},[]);return n}zt.validateTooManyAlts=Lj;function Tj(r,e,t){var i=[];return(0,br.forEach)(r,function(n){var s=new Nj;n.accept(s);var o=s.allProductions;(0,br.forEach)(o,function(a){var l=(0,qg.getProdType)(a),c=a.maxLookahead||e,u=a.idx,g=(0,qg.getLookaheadPathsForOptionalProd)(u,n,l,c),f=g[0];if((0,br.isEmpty)((0,br.flatten)(f))){var h=t.buildEmptyRepetitionError({topLevelRule:n,repetition:a});i.push({message:h,type:Do.ParserDefinitionErrorType.NO_NON_EMPTY_LOOKAHEAD,ruleName:n.name})}})}),i}zt.validateSomeNonEmptyLookaheadPath=Tj;function tIe(r,e,t,i){var n=[],s=(0,br.reduce)(r,function(a,l,c){return e.definition[c].ignoreAmbiguities===!0||(0,br.forEach)(l,function(u){var g=[c];(0,br.forEach)(r,function(f,h){c!==h&&(0,qg.containsPath)(f,u)&&e.definition[h].ignoreAmbiguities!==!0&&g.push(h)}),g.length>1&&!(0,qg.containsPath)(n,u)&&(n.push(u),a.push({alts:g,path:u}))}),a},[]),o=er.map(s,function(a){var l=(0,br.map)(a.alts,function(u){return u+1}),c=i.buildAlternationAmbiguityError({topLevelRule:t,alternation:e,ambiguityIndices:l,prefixPath:a.path});return{message:c,type:Do.ParserDefinitionErrorType.AMBIGUOUS_ALTS,ruleName:t.name,occurrence:e.idx,alternatives:[a.alts]}});return o}function Oj(r,e,t,i){var n=[],s=(0,br.reduce)(r,function(o,a,l){var c=(0,br.map)(a,function(u){return{idx:l,path:u}});return o.concat(c)},[]);return(0,br.forEach)(s,function(o){var a=e.definition[o.idx];if(a.ignoreAmbiguities!==!0){var l=o.idx,c=o.path,u=(0,br.findAll)(s,function(f){return e.definition[f.idx].ignoreAmbiguities!==!0&&f.idx{"use strict";Object.defineProperty(Jg,"__esModule",{value:!0});Jg.validateGrammar=Jg.resolveGrammar=void 0;var Gv=Gt(),iIe=Cj(),nIe=Hv(),Mj=Cd();function sIe(r){r=(0,Gv.defaults)(r,{errMsgProvider:Mj.defaultGrammarResolverErrorProvider});var e={};return(0,Gv.forEach)(r.rules,function(t){e[t.name]=t}),(0,iIe.resolveGrammar)(e,r.errMsgProvider)}Jg.resolveGrammar=sIe;function oIe(r){return r=(0,Gv.defaults)(r,{errMsgProvider:Mj.defaultGrammarValidatorErrorProvider}),(0,nIe.validateGrammar)(r.rules,r.maxLookahead,r.tokenTypes,r.errMsgProvider,r.grammarName)}Jg.validateGrammar=oIe});var Wg=w(mn=>{"use strict";var wd=mn&&mn.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(mn,"__esModule",{value:!0});mn.EarlyExitException=mn.NotAllInputParsedException=mn.NoViableAltException=mn.MismatchedTokenException=mn.isRecognitionException=void 0;var aIe=Gt(),Uj="MismatchedTokenException",Hj="NoViableAltException",Gj="EarlyExitException",Yj="NotAllInputParsedException",jj=[Uj,Hj,Gj,Yj];Object.freeze(jj);function AIe(r){return(0,aIe.contains)(jj,r.name)}mn.isRecognitionException=AIe;var ry=function(r){wd(e,r);function e(t,i){var n=this.constructor,s=r.call(this,t)||this;return s.token=i,s.resyncedTokens=[],Object.setPrototypeOf(s,n.prototype),Error.captureStackTrace&&Error.captureStackTrace(s,s.constructor),s}return e}(Error),lIe=function(r){wd(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=Uj,s}return e}(ry);mn.MismatchedTokenException=lIe;var cIe=function(r){wd(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=Hj,s}return e}(ry);mn.NoViableAltException=cIe;var uIe=function(r){wd(e,r);function e(t,i){var n=r.call(this,t,i)||this;return n.name=Yj,n}return e}(ry);mn.NotAllInputParsedException=uIe;var gIe=function(r){wd(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=Gj,s}return e}(ry);mn.EarlyExitException=gIe});var jv=w(Mi=>{"use strict";Object.defineProperty(Mi,"__esModule",{value:!0});Mi.attemptInRepetitionRecovery=Mi.Recoverable=Mi.InRuleRecoveryException=Mi.IN_RULE_RECOVERY_EXCEPTION=Mi.EOF_FOLLOW_KEY=void 0;var iy=SA(),ls=Gt(),fIe=Wg(),hIe=kv(),pIe=Hn();Mi.EOF_FOLLOW_KEY={};Mi.IN_RULE_RECOVERY_EXCEPTION="InRuleRecoveryException";function Yv(r){this.name=Mi.IN_RULE_RECOVERY_EXCEPTION,this.message=r}Mi.InRuleRecoveryException=Yv;Yv.prototype=Error.prototype;var dIe=function(){function r(){}return r.prototype.initRecoverable=function(e){this.firstAfterRepMap={},this.resyncFollows={},this.recoveryEnabled=(0,ls.has)(e,"recoveryEnabled")?e.recoveryEnabled:pIe.DEFAULT_PARSER_CONFIG.recoveryEnabled,this.recoveryEnabled&&(this.attemptInRepetitionRecovery=qj)},r.prototype.getTokenToInsert=function(e){var t=(0,iy.createTokenInstance)(e,"",NaN,NaN,NaN,NaN,NaN,NaN);return t.isInsertedInRecovery=!0,t},r.prototype.canTokenTypeBeInsertedInRecovery=function(e){return!0},r.prototype.tryInRepetitionRecovery=function(e,t,i,n){for(var s=this,o=this.findReSyncTokenType(),a=this.exportLexerState(),l=[],c=!1,u=this.LA(1),g=this.LA(1),f=function(){var h=s.LA(0),p=s.errorMessageProvider.buildMismatchTokenMessage({expected:n,actual:u,previous:h,ruleName:s.getCurrRuleFullName()}),C=new fIe.MismatchedTokenException(p,u,s.LA(0));C.resyncedTokens=(0,ls.dropRight)(l),s.SAVE_ERROR(C)};!c;)if(this.tokenMatcher(g,n)){f();return}else if(i.call(this)){f(),e.apply(this,t);return}else this.tokenMatcher(g,o)?c=!0:(g=this.SKIP_TOKEN(),this.addToResyncTokens(g,l));this.importLexerState(a)},r.prototype.shouldInRepetitionRecoveryBeTried=function(e,t,i){return!(i===!1||e===void 0||t===void 0||this.tokenMatcher(this.LA(1),e)||this.isBackTracking()||this.canPerformInRuleRecovery(e,this.getFollowsForInRuleRecovery(e,t)))},r.prototype.getFollowsForInRuleRecovery=function(e,t){var i=this.getCurrentGrammarPath(e,t),n=this.getNextPossibleTokenTypes(i);return n},r.prototype.tryInRuleRecovery=function(e,t){if(this.canRecoverWithSingleTokenInsertion(e,t)){var i=this.getTokenToInsert(e);return i}if(this.canRecoverWithSingleTokenDeletion(e)){var n=this.SKIP_TOKEN();return this.consumeToken(),n}throw new Yv("sad sad panda")},r.prototype.canPerformInRuleRecovery=function(e,t){return this.canRecoverWithSingleTokenInsertion(e,t)||this.canRecoverWithSingleTokenDeletion(e)},r.prototype.canRecoverWithSingleTokenInsertion=function(e,t){var i=this;if(!this.canTokenTypeBeInsertedInRecovery(e)||(0,ls.isEmpty)(t))return!1;var n=this.LA(1),s=(0,ls.find)(t,function(o){return i.tokenMatcher(n,o)})!==void 0;return s},r.prototype.canRecoverWithSingleTokenDeletion=function(e){var t=this.tokenMatcher(this.LA(2),e);return t},r.prototype.isInCurrentRuleReSyncSet=function(e){var t=this.getCurrFollowKey(),i=this.getFollowSetFromFollowKey(t);return(0,ls.contains)(i,e)},r.prototype.findReSyncTokenType=function(){for(var e=this.flattenFollowSet(),t=this.LA(1),i=2;;){var n=t.tokenType;if((0,ls.contains)(e,n))return n;t=this.LA(i),i++}},r.prototype.getCurrFollowKey=function(){if(this.RULE_STACK.length===1)return Mi.EOF_FOLLOW_KEY;var e=this.getLastExplicitRuleShortName(),t=this.getLastExplicitRuleOccurrenceIndex(),i=this.getPreviousExplicitRuleShortName();return{ruleName:this.shortRuleNameToFullName(e),idxInCallingRule:t,inRule:this.shortRuleNameToFullName(i)}},r.prototype.buildFullFollowKeyStack=function(){var e=this,t=this.RULE_STACK,i=this.RULE_OCCURRENCE_STACK;return(0,ls.map)(t,function(n,s){return s===0?Mi.EOF_FOLLOW_KEY:{ruleName:e.shortRuleNameToFullName(n),idxInCallingRule:i[s],inRule:e.shortRuleNameToFullName(t[s-1])}})},r.prototype.flattenFollowSet=function(){var e=this,t=(0,ls.map)(this.buildFullFollowKeyStack(),function(i){return e.getFollowSetFromFollowKey(i)});return(0,ls.flatten)(t)},r.prototype.getFollowSetFromFollowKey=function(e){if(e===Mi.EOF_FOLLOW_KEY)return[iy.EOF];var t=e.ruleName+e.idxInCallingRule+hIe.IN+e.inRule;return this.resyncFollows[t]},r.prototype.addToResyncTokens=function(e,t){return this.tokenMatcher(e,iy.EOF)||t.push(e),t},r.prototype.reSyncTo=function(e){for(var t=[],i=this.LA(1);this.tokenMatcher(i,e)===!1;)i=this.SKIP_TOKEN(),this.addToResyncTokens(i,t);return(0,ls.dropRight)(t)},r.prototype.attemptInRepetitionRecovery=function(e,t,i,n,s,o,a){},r.prototype.getCurrentGrammarPath=function(e,t){var i=this.getHumanReadableRuleStack(),n=(0,ls.cloneArr)(this.RULE_OCCURRENCE_STACK),s={ruleStack:i,occurrenceStack:n,lastTok:e,lastTokOccurrence:t};return s},r.prototype.getHumanReadableRuleStack=function(){var e=this;return(0,ls.map)(this.RULE_STACK,function(t){return e.shortRuleNameToFullName(t)})},r}();Mi.Recoverable=dIe;function qj(r,e,t,i,n,s,o){var a=this.getKeyForAutomaticLookahead(i,n),l=this.firstAfterRepMap[a];if(l===void 0){var c=this.getCurrRuleFullName(),u=this.getGAstProductions()[c],g=new s(u,n);l=g.startWalking(),this.firstAfterRepMap[a]=l}var f=l.token,h=l.occurrence,p=l.isEndOfRule;this.RULE_STACK.length===1&&p&&f===void 0&&(f=iy.EOF,h=1),this.shouldInRepetitionRecoveryBeTried(f,h,o)&&this.tryInRepetitionRecovery(r,e,t,f)}Mi.attemptInRepetitionRecovery=qj});var ny=w(qt=>{"use strict";Object.defineProperty(qt,"__esModule",{value:!0});qt.getKeyForAutomaticLookahead=qt.AT_LEAST_ONE_SEP_IDX=qt.MANY_SEP_IDX=qt.AT_LEAST_ONE_IDX=qt.MANY_IDX=qt.OPTION_IDX=qt.OR_IDX=qt.BITS_FOR_ALT_IDX=qt.BITS_FOR_RULE_IDX=qt.BITS_FOR_OCCURRENCE_IDX=qt.BITS_FOR_METHOD_TYPE=void 0;qt.BITS_FOR_METHOD_TYPE=4;qt.BITS_FOR_OCCURRENCE_IDX=8;qt.BITS_FOR_RULE_IDX=12;qt.BITS_FOR_ALT_IDX=8;qt.OR_IDX=1<{"use strict";Object.defineProperty(sy,"__esModule",{value:!0});sy.LooksAhead=void 0;var Qa=Id(),Zs=Gt(),Jj=Hn(),ba=ny(),oc=dd(),mIe=function(){function r(){}return r.prototype.initLooksAhead=function(e){this.dynamicTokensEnabled=(0,Zs.has)(e,"dynamicTokensEnabled")?e.dynamicTokensEnabled:Jj.DEFAULT_PARSER_CONFIG.dynamicTokensEnabled,this.maxLookahead=(0,Zs.has)(e,"maxLookahead")?e.maxLookahead:Jj.DEFAULT_PARSER_CONFIG.maxLookahead,this.lookAheadFuncsCache=(0,Zs.isES2015MapSupported)()?new Map:[],(0,Zs.isES2015MapSupported)()?(this.getLaFuncFromCache=this.getLaFuncFromMap,this.setLaFuncCache=this.setLaFuncCacheUsingMap):(this.getLaFuncFromCache=this.getLaFuncFromObj,this.setLaFuncCache=this.setLaFuncUsingObj)},r.prototype.preComputeLookaheadFunctions=function(e){var t=this;(0,Zs.forEach)(e,function(i){t.TRACE_INIT(i.name+" Rule Lookahead",function(){var n=(0,oc.collectMethods)(i),s=n.alternation,o=n.repetition,a=n.option,l=n.repetitionMandatory,c=n.repetitionMandatoryWithSeparator,u=n.repetitionWithSeparator;(0,Zs.forEach)(s,function(g){var f=g.idx===0?"":g.idx;t.TRACE_INIT(""+(0,oc.getProductionDslName)(g)+f,function(){var h=(0,Qa.buildLookaheadFuncForOr)(g.idx,i,g.maxLookahead||t.maxLookahead,g.hasPredicates,t.dynamicTokensEnabled,t.lookAheadBuilderForAlternatives),p=(0,ba.getKeyForAutomaticLookahead)(t.fullRuleNameToShort[i.name],ba.OR_IDX,g.idx);t.setLaFuncCache(p,h)})}),(0,Zs.forEach)(o,function(g){t.computeLookaheadFunc(i,g.idx,ba.MANY_IDX,Qa.PROD_TYPE.REPETITION,g.maxLookahead,(0,oc.getProductionDslName)(g))}),(0,Zs.forEach)(a,function(g){t.computeLookaheadFunc(i,g.idx,ba.OPTION_IDX,Qa.PROD_TYPE.OPTION,g.maxLookahead,(0,oc.getProductionDslName)(g))}),(0,Zs.forEach)(l,function(g){t.computeLookaheadFunc(i,g.idx,ba.AT_LEAST_ONE_IDX,Qa.PROD_TYPE.REPETITION_MANDATORY,g.maxLookahead,(0,oc.getProductionDslName)(g))}),(0,Zs.forEach)(c,function(g){t.computeLookaheadFunc(i,g.idx,ba.AT_LEAST_ONE_SEP_IDX,Qa.PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR,g.maxLookahead,(0,oc.getProductionDslName)(g))}),(0,Zs.forEach)(u,function(g){t.computeLookaheadFunc(i,g.idx,ba.MANY_SEP_IDX,Qa.PROD_TYPE.REPETITION_WITH_SEPARATOR,g.maxLookahead,(0,oc.getProductionDslName)(g))})})})},r.prototype.computeLookaheadFunc=function(e,t,i,n,s,o){var a=this;this.TRACE_INIT(""+o+(t===0?"":t),function(){var l=(0,Qa.buildLookaheadFuncForOptionalProd)(t,e,s||a.maxLookahead,a.dynamicTokensEnabled,n,a.lookAheadBuilderForOptional),c=(0,ba.getKeyForAutomaticLookahead)(a.fullRuleNameToShort[e.name],i,t);a.setLaFuncCache(c,l)})},r.prototype.lookAheadBuilderForOptional=function(e,t,i){return(0,Qa.buildSingleAlternativeLookaheadFunction)(e,t,i)},r.prototype.lookAheadBuilderForAlternatives=function(e,t,i,n){return(0,Qa.buildAlternativesLookAheadFunc)(e,t,i,n)},r.prototype.getKeyForAutomaticLookahead=function(e,t){var i=this.getLastExplicitRuleShortName();return(0,ba.getKeyForAutomaticLookahead)(i,e,t)},r.prototype.getLaFuncFromCache=function(e){},r.prototype.getLaFuncFromMap=function(e){return this.lookAheadFuncsCache.get(e)},r.prototype.getLaFuncFromObj=function(e){return this.lookAheadFuncsCache[e]},r.prototype.setLaFuncCache=function(e,t){},r.prototype.setLaFuncCacheUsingMap=function(e,t){this.lookAheadFuncsCache.set(e,t)},r.prototype.setLaFuncUsingObj=function(e,t){this.lookAheadFuncsCache[e]=t},r}();sy.LooksAhead=mIe});var zj=w(ko=>{"use strict";Object.defineProperty(ko,"__esModule",{value:!0});ko.addNoneTerminalToCst=ko.addTerminalToCst=ko.setNodeLocationFull=ko.setNodeLocationOnlyOffset=void 0;function EIe(r,e){isNaN(r.startOffset)===!0?(r.startOffset=e.startOffset,r.endOffset=e.endOffset):r.endOffset{"use strict";Object.defineProperty(PA,"__esModule",{value:!0});PA.defineNameProp=PA.functionName=PA.classNameFromInstance=void 0;var BIe=Gt();function QIe(r){return Xj(r.constructor)}PA.classNameFromInstance=QIe;var Vj="name";function Xj(r){var e=r.name;return e||"anonymous"}PA.functionName=Xj;function bIe(r,e){var t=Object.getOwnPropertyDescriptor(r,Vj);return(0,BIe.isUndefined)(t)||t.configurable?(Object.defineProperty(r,Vj,{enumerable:!1,configurable:!0,writable:!1,value:e}),!0):!1}PA.defineNameProp=bIe});var tq=w(bi=>{"use strict";Object.defineProperty(bi,"__esModule",{value:!0});bi.validateRedundantMethods=bi.validateMissingCstMethods=bi.validateVisitor=bi.CstVisitorDefinitionError=bi.createBaseVisitorConstructorWithDefaults=bi.createBaseSemanticVisitorConstructor=bi.defaultVisit=void 0;var cs=Gt(),Bd=qv();function _j(r,e){for(var t=(0,cs.keys)(r),i=t.length,n=0;n: + `+(""+s.join(` + +`).replace(/\n/g,` + `)))}}};return t.prototype=i,t.prototype.constructor=t,t._RULE_NAMES=e,t}bi.createBaseSemanticVisitorConstructor=SIe;function vIe(r,e,t){var i=function(){};(0,Bd.defineNameProp)(i,r+"BaseSemanticsWithDefaults");var n=Object.create(t.prototype);return(0,cs.forEach)(e,function(s){n[s]=_j}),i.prototype=n,i.prototype.constructor=i,i}bi.createBaseVisitorConstructorWithDefaults=vIe;var Jv;(function(r){r[r.REDUNDANT_METHOD=0]="REDUNDANT_METHOD",r[r.MISSING_METHOD=1]="MISSING_METHOD"})(Jv=bi.CstVisitorDefinitionError||(bi.CstVisitorDefinitionError={}));function Zj(r,e){var t=$j(r,e),i=eq(r,e);return t.concat(i)}bi.validateVisitor=Zj;function $j(r,e){var t=(0,cs.map)(e,function(i){if(!(0,cs.isFunction)(r[i]))return{msg:"Missing visitor method: <"+i+"> on "+(0,Bd.functionName)(r.constructor)+" CST Visitor.",type:Jv.MISSING_METHOD,methodName:i}});return(0,cs.compact)(t)}bi.validateMissingCstMethods=$j;var xIe=["constructor","visit","validateVisitor"];function eq(r,e){var t=[];for(var i in r)(0,cs.isFunction)(r[i])&&!(0,cs.contains)(xIe,i)&&!(0,cs.contains)(e,i)&&t.push({msg:"Redundant visitor method: <"+i+"> on "+(0,Bd.functionName)(r.constructor)+` CST Visitor +There is no Grammar Rule corresponding to this method's name. +`,type:Jv.REDUNDANT_METHOD,methodName:i});return t}bi.validateRedundantMethods=eq});var iq=w(oy=>{"use strict";Object.defineProperty(oy,"__esModule",{value:!0});oy.TreeBuilder=void 0;var zg=zj(),Zr=Gt(),rq=tq(),PIe=Hn(),DIe=function(){function r(){}return r.prototype.initTreeBuilder=function(e){if(this.CST_STACK=[],this.outputCst=e.outputCst,this.nodeLocationTracking=(0,Zr.has)(e,"nodeLocationTracking")?e.nodeLocationTracking:PIe.DEFAULT_PARSER_CONFIG.nodeLocationTracking,!this.outputCst)this.cstInvocationStateUpdate=Zr.NOOP,this.cstFinallyStateUpdate=Zr.NOOP,this.cstPostTerminal=Zr.NOOP,this.cstPostNonTerminal=Zr.NOOP,this.cstPostRule=Zr.NOOP;else if(/full/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=zg.setNodeLocationFull,this.setNodeLocationFromNode=zg.setNodeLocationFull,this.cstPostRule=Zr.NOOP,this.setInitialNodeLocation=this.setInitialNodeLocationFullRecovery):(this.setNodeLocationFromToken=Zr.NOOP,this.setNodeLocationFromNode=Zr.NOOP,this.cstPostRule=this.cstPostRuleFull,this.setInitialNodeLocation=this.setInitialNodeLocationFullRegular);else if(/onlyOffset/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=zg.setNodeLocationOnlyOffset,this.setNodeLocationFromNode=zg.setNodeLocationOnlyOffset,this.cstPostRule=Zr.NOOP,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRecovery):(this.setNodeLocationFromToken=Zr.NOOP,this.setNodeLocationFromNode=Zr.NOOP,this.cstPostRule=this.cstPostRuleOnlyOffset,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRegular);else if(/none/i.test(this.nodeLocationTracking))this.setNodeLocationFromToken=Zr.NOOP,this.setNodeLocationFromNode=Zr.NOOP,this.cstPostRule=Zr.NOOP,this.setInitialNodeLocation=Zr.NOOP;else throw Error('Invalid config option: "'+e.nodeLocationTracking+'"')},r.prototype.setInitialNodeLocationOnlyOffsetRecovery=function(e){e.location={startOffset:NaN,endOffset:NaN}},r.prototype.setInitialNodeLocationOnlyOffsetRegular=function(e){e.location={startOffset:this.LA(1).startOffset,endOffset:NaN}},r.prototype.setInitialNodeLocationFullRecovery=function(e){e.location={startOffset:NaN,startLine:NaN,startColumn:NaN,endOffset:NaN,endLine:NaN,endColumn:NaN}},r.prototype.setInitialNodeLocationFullRegular=function(e){var t=this.LA(1);e.location={startOffset:t.startOffset,startLine:t.startLine,startColumn:t.startColumn,endOffset:NaN,endLine:NaN,endColumn:NaN}},r.prototype.cstInvocationStateUpdate=function(e,t){var i={name:e,children:{}};this.setInitialNodeLocation(i),this.CST_STACK.push(i)},r.prototype.cstFinallyStateUpdate=function(){this.CST_STACK.pop()},r.prototype.cstPostRuleFull=function(e){var t=this.LA(0),i=e.location;i.startOffset<=t.startOffset?(i.endOffset=t.endOffset,i.endLine=t.endLine,i.endColumn=t.endColumn):(i.startOffset=NaN,i.startLine=NaN,i.startColumn=NaN)},r.prototype.cstPostRuleOnlyOffset=function(e){var t=this.LA(0),i=e.location;i.startOffset<=t.startOffset?i.endOffset=t.endOffset:i.startOffset=NaN},r.prototype.cstPostTerminal=function(e,t){var i=this.CST_STACK[this.CST_STACK.length-1];(0,zg.addTerminalToCst)(i,t,e),this.setNodeLocationFromToken(i.location,t)},r.prototype.cstPostNonTerminal=function(e,t){var i=this.CST_STACK[this.CST_STACK.length-1];(0,zg.addNoneTerminalToCst)(i,t,e),this.setNodeLocationFromNode(i.location,e.location)},r.prototype.getBaseCstVisitorConstructor=function(){if((0,Zr.isUndefined)(this.baseCstVisitorConstructor)){var e=(0,rq.createBaseSemanticVisitorConstructor)(this.className,(0,Zr.keys)(this.gastProductionsCache));return this.baseCstVisitorConstructor=e,e}return this.baseCstVisitorConstructor},r.prototype.getBaseCstVisitorConstructorWithDefaults=function(){if((0,Zr.isUndefined)(this.baseCstVisitorWithDefaultsConstructor)){var e=(0,rq.createBaseVisitorConstructorWithDefaults)(this.className,(0,Zr.keys)(this.gastProductionsCache),this.getBaseCstVisitorConstructor());return this.baseCstVisitorWithDefaultsConstructor=e,e}return this.baseCstVisitorWithDefaultsConstructor},r.prototype.getLastExplicitRuleShortName=function(){var e=this.RULE_STACK;return e[e.length-1]},r.prototype.getPreviousExplicitRuleShortName=function(){var e=this.RULE_STACK;return e[e.length-2]},r.prototype.getLastExplicitRuleOccurrenceIndex=function(){var e=this.RULE_OCCURRENCE_STACK;return e[e.length-1]},r}();oy.TreeBuilder=DIe});var sq=w(ay=>{"use strict";Object.defineProperty(ay,"__esModule",{value:!0});ay.LexerAdapter=void 0;var nq=Hn(),kIe=function(){function r(){}return r.prototype.initLexerAdapter=function(){this.tokVector=[],this.tokVectorLength=0,this.currIdx=-1},Object.defineProperty(r.prototype,"input",{get:function(){return this.tokVector},set:function(e){if(this.selfAnalysisDone!==!0)throw Error("Missing invocation at the end of the Parser's constructor.");this.reset(),this.tokVector=e,this.tokVectorLength=e.length},enumerable:!1,configurable:!0}),r.prototype.SKIP_TOKEN=function(){return this.currIdx<=this.tokVector.length-2?(this.consumeToken(),this.LA(1)):nq.END_OF_FILE},r.prototype.LA=function(e){var t=this.currIdx+e;return t<0||this.tokVectorLength<=t?nq.END_OF_FILE:this.tokVector[t]},r.prototype.consumeToken=function(){this.currIdx++},r.prototype.exportLexerState=function(){return this.currIdx},r.prototype.importLexerState=function(e){this.currIdx=e},r.prototype.resetLexerState=function(){this.currIdx=-1},r.prototype.moveToTerminatedState=function(){this.currIdx=this.tokVector.length-1},r.prototype.getLexerPosition=function(){return this.exportLexerState()},r}();ay.LexerAdapter=kIe});var aq=w(Ay=>{"use strict";Object.defineProperty(Ay,"__esModule",{value:!0});Ay.RecognizerApi=void 0;var oq=Gt(),RIe=Wg(),Wv=Hn(),FIe=Cd(),NIe=Hv(),LIe=dn(),TIe=function(){function r(){}return r.prototype.ACTION=function(e){return e.call(this)},r.prototype.consume=function(e,t,i){return this.consumeInternal(t,e,i)},r.prototype.subrule=function(e,t,i){return this.subruleInternal(t,e,i)},r.prototype.option=function(e,t){return this.optionInternal(t,e)},r.prototype.or=function(e,t){return this.orInternal(t,e)},r.prototype.many=function(e,t){return this.manyInternal(e,t)},r.prototype.atLeastOne=function(e,t){return this.atLeastOneInternal(e,t)},r.prototype.CONSUME=function(e,t){return this.consumeInternal(e,0,t)},r.prototype.CONSUME1=function(e,t){return this.consumeInternal(e,1,t)},r.prototype.CONSUME2=function(e,t){return this.consumeInternal(e,2,t)},r.prototype.CONSUME3=function(e,t){return this.consumeInternal(e,3,t)},r.prototype.CONSUME4=function(e,t){return this.consumeInternal(e,4,t)},r.prototype.CONSUME5=function(e,t){return this.consumeInternal(e,5,t)},r.prototype.CONSUME6=function(e,t){return this.consumeInternal(e,6,t)},r.prototype.CONSUME7=function(e,t){return this.consumeInternal(e,7,t)},r.prototype.CONSUME8=function(e,t){return this.consumeInternal(e,8,t)},r.prototype.CONSUME9=function(e,t){return this.consumeInternal(e,9,t)},r.prototype.SUBRULE=function(e,t){return this.subruleInternal(e,0,t)},r.prototype.SUBRULE1=function(e,t){return this.subruleInternal(e,1,t)},r.prototype.SUBRULE2=function(e,t){return this.subruleInternal(e,2,t)},r.prototype.SUBRULE3=function(e,t){return this.subruleInternal(e,3,t)},r.prototype.SUBRULE4=function(e,t){return this.subruleInternal(e,4,t)},r.prototype.SUBRULE5=function(e,t){return this.subruleInternal(e,5,t)},r.prototype.SUBRULE6=function(e,t){return this.subruleInternal(e,6,t)},r.prototype.SUBRULE7=function(e,t){return this.subruleInternal(e,7,t)},r.prototype.SUBRULE8=function(e,t){return this.subruleInternal(e,8,t)},r.prototype.SUBRULE9=function(e,t){return this.subruleInternal(e,9,t)},r.prototype.OPTION=function(e){return this.optionInternal(e,0)},r.prototype.OPTION1=function(e){return this.optionInternal(e,1)},r.prototype.OPTION2=function(e){return this.optionInternal(e,2)},r.prototype.OPTION3=function(e){return this.optionInternal(e,3)},r.prototype.OPTION4=function(e){return this.optionInternal(e,4)},r.prototype.OPTION5=function(e){return this.optionInternal(e,5)},r.prototype.OPTION6=function(e){return this.optionInternal(e,6)},r.prototype.OPTION7=function(e){return this.optionInternal(e,7)},r.prototype.OPTION8=function(e){return this.optionInternal(e,8)},r.prototype.OPTION9=function(e){return this.optionInternal(e,9)},r.prototype.OR=function(e){return this.orInternal(e,0)},r.prototype.OR1=function(e){return this.orInternal(e,1)},r.prototype.OR2=function(e){return this.orInternal(e,2)},r.prototype.OR3=function(e){return this.orInternal(e,3)},r.prototype.OR4=function(e){return this.orInternal(e,4)},r.prototype.OR5=function(e){return this.orInternal(e,5)},r.prototype.OR6=function(e){return this.orInternal(e,6)},r.prototype.OR7=function(e){return this.orInternal(e,7)},r.prototype.OR8=function(e){return this.orInternal(e,8)},r.prototype.OR9=function(e){return this.orInternal(e,9)},r.prototype.MANY=function(e){this.manyInternal(0,e)},r.prototype.MANY1=function(e){this.manyInternal(1,e)},r.prototype.MANY2=function(e){this.manyInternal(2,e)},r.prototype.MANY3=function(e){this.manyInternal(3,e)},r.prototype.MANY4=function(e){this.manyInternal(4,e)},r.prototype.MANY5=function(e){this.manyInternal(5,e)},r.prototype.MANY6=function(e){this.manyInternal(6,e)},r.prototype.MANY7=function(e){this.manyInternal(7,e)},r.prototype.MANY8=function(e){this.manyInternal(8,e)},r.prototype.MANY9=function(e){this.manyInternal(9,e)},r.prototype.MANY_SEP=function(e){this.manySepFirstInternal(0,e)},r.prototype.MANY_SEP1=function(e){this.manySepFirstInternal(1,e)},r.prototype.MANY_SEP2=function(e){this.manySepFirstInternal(2,e)},r.prototype.MANY_SEP3=function(e){this.manySepFirstInternal(3,e)},r.prototype.MANY_SEP4=function(e){this.manySepFirstInternal(4,e)},r.prototype.MANY_SEP5=function(e){this.manySepFirstInternal(5,e)},r.prototype.MANY_SEP6=function(e){this.manySepFirstInternal(6,e)},r.prototype.MANY_SEP7=function(e){this.manySepFirstInternal(7,e)},r.prototype.MANY_SEP8=function(e){this.manySepFirstInternal(8,e)},r.prototype.MANY_SEP9=function(e){this.manySepFirstInternal(9,e)},r.prototype.AT_LEAST_ONE=function(e){this.atLeastOneInternal(0,e)},r.prototype.AT_LEAST_ONE1=function(e){return this.atLeastOneInternal(1,e)},r.prototype.AT_LEAST_ONE2=function(e){this.atLeastOneInternal(2,e)},r.prototype.AT_LEAST_ONE3=function(e){this.atLeastOneInternal(3,e)},r.prototype.AT_LEAST_ONE4=function(e){this.atLeastOneInternal(4,e)},r.prototype.AT_LEAST_ONE5=function(e){this.atLeastOneInternal(5,e)},r.prototype.AT_LEAST_ONE6=function(e){this.atLeastOneInternal(6,e)},r.prototype.AT_LEAST_ONE7=function(e){this.atLeastOneInternal(7,e)},r.prototype.AT_LEAST_ONE8=function(e){this.atLeastOneInternal(8,e)},r.prototype.AT_LEAST_ONE9=function(e){this.atLeastOneInternal(9,e)},r.prototype.AT_LEAST_ONE_SEP=function(e){this.atLeastOneSepFirstInternal(0,e)},r.prototype.AT_LEAST_ONE_SEP1=function(e){this.atLeastOneSepFirstInternal(1,e)},r.prototype.AT_LEAST_ONE_SEP2=function(e){this.atLeastOneSepFirstInternal(2,e)},r.prototype.AT_LEAST_ONE_SEP3=function(e){this.atLeastOneSepFirstInternal(3,e)},r.prototype.AT_LEAST_ONE_SEP4=function(e){this.atLeastOneSepFirstInternal(4,e)},r.prototype.AT_LEAST_ONE_SEP5=function(e){this.atLeastOneSepFirstInternal(5,e)},r.prototype.AT_LEAST_ONE_SEP6=function(e){this.atLeastOneSepFirstInternal(6,e)},r.prototype.AT_LEAST_ONE_SEP7=function(e){this.atLeastOneSepFirstInternal(7,e)},r.prototype.AT_LEAST_ONE_SEP8=function(e){this.atLeastOneSepFirstInternal(8,e)},r.prototype.AT_LEAST_ONE_SEP9=function(e){this.atLeastOneSepFirstInternal(9,e)},r.prototype.RULE=function(e,t,i){if(i===void 0&&(i=Wv.DEFAULT_RULE_CONFIG),(0,oq.contains)(this.definedRulesNames,e)){var n=FIe.defaultGrammarValidatorErrorProvider.buildDuplicateRuleNameError({topLevelRule:e,grammarName:this.className}),s={message:n,type:Wv.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:e};this.definitionErrors.push(s)}this.definedRulesNames.push(e);var o=this.defineRule(e,t,i);return this[e]=o,o},r.prototype.OVERRIDE_RULE=function(e,t,i){i===void 0&&(i=Wv.DEFAULT_RULE_CONFIG);var n=[];n=n.concat((0,NIe.validateRuleIsOverridden)(e,this.definedRulesNames,this.className)),this.definitionErrors=this.definitionErrors.concat(n);var s=this.defineRule(e,t,i);return this[e]=s,s},r.prototype.BACKTRACK=function(e,t){return function(){this.isBackTrackingStack.push(1);var i=this.saveRecogState();try{return e.apply(this,t),!0}catch(n){if((0,RIe.isRecognitionException)(n))return!1;throw n}finally{this.reloadRecogState(i),this.isBackTrackingStack.pop()}}},r.prototype.getGAstProductions=function(){return this.gastProductionsCache},r.prototype.getSerializedGastProductions=function(){return(0,LIe.serializeGrammar)((0,oq.values)(this.gastProductionsCache))},r}();Ay.RecognizerApi=TIe});var uq=w(cy=>{"use strict";Object.defineProperty(cy,"__esModule",{value:!0});cy.RecognizerEngine=void 0;var Pr=Gt(),Gn=ny(),ly=Wg(),Aq=Id(),Vg=Ed(),lq=Hn(),OIe=jv(),cq=SA(),Qd=Gg(),MIe=qv(),KIe=function(){function r(){}return r.prototype.initRecognizerEngine=function(e,t){if(this.className=(0,MIe.classNameFromInstance)(this),this.shortRuleNameToFull={},this.fullRuleNameToShort={},this.ruleShortNameIdx=256,this.tokenMatcher=Qd.tokenStructuredMatcherNoCategories,this.definedRulesNames=[],this.tokensMap={},this.isBackTrackingStack=[],this.RULE_STACK=[],this.RULE_OCCURRENCE_STACK=[],this.gastProductionsCache={},(0,Pr.has)(t,"serializedGrammar"))throw Error(`The Parser's configuration can no longer contain a property. + See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_6-0-0 + For Further details.`);if((0,Pr.isArray)(e)){if((0,Pr.isEmpty)(e))throw Error(`A Token Vocabulary cannot be empty. + Note that the first argument for the parser constructor + is no longer a Token vector (since v4.0).`);if(typeof e[0].startOffset=="number")throw Error(`The Parser constructor no longer accepts a token vector as the first argument. + See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_4-0-0 + For Further details.`)}if((0,Pr.isArray)(e))this.tokensMap=(0,Pr.reduce)(e,function(o,a){return o[a.name]=a,o},{});else if((0,Pr.has)(e,"modes")&&(0,Pr.every)((0,Pr.flatten)((0,Pr.values)(e.modes)),Qd.isTokenType)){var i=(0,Pr.flatten)((0,Pr.values)(e.modes)),n=(0,Pr.uniq)(i);this.tokensMap=(0,Pr.reduce)(n,function(o,a){return o[a.name]=a,o},{})}else if((0,Pr.isObject)(e))this.tokensMap=(0,Pr.cloneObj)(e);else throw new Error(" argument must be An Array of Token constructors, A dictionary of Token constructors or an IMultiModeLexerDefinition");this.tokensMap.EOF=cq.EOF;var s=(0,Pr.every)((0,Pr.values)(e),function(o){return(0,Pr.isEmpty)(o.categoryMatches)});this.tokenMatcher=s?Qd.tokenStructuredMatcherNoCategories:Qd.tokenStructuredMatcher,(0,Qd.augmentTokenTypes)((0,Pr.values)(this.tokensMap))},r.prototype.defineRule=function(e,t,i){if(this.selfAnalysisDone)throw Error("Grammar rule <"+e+`> may not be defined after the 'performSelfAnalysis' method has been called' +Make sure that all grammar rule definitions are done before 'performSelfAnalysis' is called.`);var n=(0,Pr.has)(i,"resyncEnabled")?i.resyncEnabled:lq.DEFAULT_RULE_CONFIG.resyncEnabled,s=(0,Pr.has)(i,"recoveryValueFunc")?i.recoveryValueFunc:lq.DEFAULT_RULE_CONFIG.recoveryValueFunc,o=this.ruleShortNameIdx<t},r.prototype.orInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(Gn.OR_IDX,t),n=(0,Pr.isArray)(e)?e:e.DEF,s=this.getLaFuncFromCache(i),o=s.call(this,n);if(o!==void 0){var a=n[o];return a.ALT.call(this)}this.raiseNoAltException(t,e.ERR_MSG)},r.prototype.ruleFinallyStateUpdate=function(){if(this.RULE_STACK.pop(),this.RULE_OCCURRENCE_STACK.pop(),this.cstFinallyStateUpdate(),this.RULE_STACK.length===0&&this.isAtEndOfInput()===!1){var e=this.LA(1),t=this.errorMessageProvider.buildNotAllInputParsedMessage({firstRedundant:e,ruleName:this.getCurrRuleFullName()});this.SAVE_ERROR(new ly.NotAllInputParsedException(t,e))}},r.prototype.subruleInternal=function(e,t,i){var n;try{var s=i!==void 0?i.ARGS:void 0;return n=e.call(this,t,s),this.cstPostNonTerminal(n,i!==void 0&&i.LABEL!==void 0?i.LABEL:e.ruleName),n}catch(o){this.subruleInternalError(o,i,e.ruleName)}},r.prototype.subruleInternalError=function(e,t,i){throw(0,ly.isRecognitionException)(e)&&e.partialCstResult!==void 0&&(this.cstPostNonTerminal(e.partialCstResult,t!==void 0&&t.LABEL!==void 0?t.LABEL:i),delete e.partialCstResult),e},r.prototype.consumeInternal=function(e,t,i){var n;try{var s=this.LA(1);this.tokenMatcher(s,e)===!0?(this.consumeToken(),n=s):this.consumeInternalError(e,s,i)}catch(o){n=this.consumeInternalRecovery(e,t,o)}return this.cstPostTerminal(i!==void 0&&i.LABEL!==void 0?i.LABEL:e.name,n),n},r.prototype.consumeInternalError=function(e,t,i){var n,s=this.LA(0);throw i!==void 0&&i.ERR_MSG?n=i.ERR_MSG:n=this.errorMessageProvider.buildMismatchTokenMessage({expected:e,actual:t,previous:s,ruleName:this.getCurrRuleFullName()}),this.SAVE_ERROR(new ly.MismatchedTokenException(n,t,s))},r.prototype.consumeInternalRecovery=function(e,t,i){if(this.recoveryEnabled&&i.name==="MismatchedTokenException"&&!this.isBackTracking()){var n=this.getFollowsForInRuleRecovery(e,t);try{return this.tryInRuleRecovery(e,n)}catch(s){throw s.name===OIe.IN_RULE_RECOVERY_EXCEPTION?i:s}}else throw i},r.prototype.saveRecogState=function(){var e=this.errors,t=(0,Pr.cloneArr)(this.RULE_STACK);return{errors:e,lexerState:this.exportLexerState(),RULE_STACK:t,CST_STACK:this.CST_STACK}},r.prototype.reloadRecogState=function(e){this.errors=e.errors,this.importLexerState(e.lexerState),this.RULE_STACK=e.RULE_STACK},r.prototype.ruleInvocationStateUpdate=function(e,t,i){this.RULE_OCCURRENCE_STACK.push(i),this.RULE_STACK.push(e),this.cstInvocationStateUpdate(t,e)},r.prototype.isBackTracking=function(){return this.isBackTrackingStack.length!==0},r.prototype.getCurrRuleFullName=function(){var e=this.getLastExplicitRuleShortName();return this.shortRuleNameToFull[e]},r.prototype.shortRuleNameToFullName=function(e){return this.shortRuleNameToFull[e]},r.prototype.isAtEndOfInput=function(){return this.tokenMatcher(this.LA(1),cq.EOF)},r.prototype.reset=function(){this.resetLexerState(),this.isBackTrackingStack=[],this.errors=[],this.RULE_STACK=[],this.CST_STACK=[],this.RULE_OCCURRENCE_STACK=[]},r}();cy.RecognizerEngine=KIe});var fq=w(uy=>{"use strict";Object.defineProperty(uy,"__esModule",{value:!0});uy.ErrorHandler=void 0;var zv=Wg(),Vv=Gt(),gq=Id(),UIe=Hn(),HIe=function(){function r(){}return r.prototype.initErrorHandler=function(e){this._errors=[],this.errorMessageProvider=(0,Vv.has)(e,"errorMessageProvider")?e.errorMessageProvider:UIe.DEFAULT_PARSER_CONFIG.errorMessageProvider},r.prototype.SAVE_ERROR=function(e){if((0,zv.isRecognitionException)(e))return e.context={ruleStack:this.getHumanReadableRuleStack(),ruleOccurrenceStack:(0,Vv.cloneArr)(this.RULE_OCCURRENCE_STACK)},this._errors.push(e),e;throw Error("Trying to save an Error which is not a RecognitionException")},Object.defineProperty(r.prototype,"errors",{get:function(){return(0,Vv.cloneArr)(this._errors)},set:function(e){this._errors=e},enumerable:!1,configurable:!0}),r.prototype.raiseEarlyExitException=function(e,t,i){for(var n=this.getCurrRuleFullName(),s=this.getGAstProductions()[n],o=(0,gq.getLookaheadPathsForOptionalProd)(e,s,t,this.maxLookahead),a=o[0],l=[],c=1;c<=this.maxLookahead;c++)l.push(this.LA(c));var u=this.errorMessageProvider.buildEarlyExitMessage({expectedIterationPaths:a,actual:l,previous:this.LA(0),customUserDescription:i,ruleName:n});throw this.SAVE_ERROR(new zv.EarlyExitException(u,this.LA(1),this.LA(0)))},r.prototype.raiseNoAltException=function(e,t){for(var i=this.getCurrRuleFullName(),n=this.getGAstProductions()[i],s=(0,gq.getLookaheadPathsForOr)(e,n,this.maxLookahead),o=[],a=1;a<=this.maxLookahead;a++)o.push(this.LA(a));var l=this.LA(0),c=this.errorMessageProvider.buildNoViableAltMessage({expectedPathsPerAlt:s,actual:o,previous:l,customUserDescription:t,ruleName:this.getCurrRuleFullName()});throw this.SAVE_ERROR(new zv.NoViableAltException(c,this.LA(1),l))},r}();uy.ErrorHandler=HIe});var dq=w(gy=>{"use strict";Object.defineProperty(gy,"__esModule",{value:!0});gy.ContentAssist=void 0;var hq=Ed(),pq=Gt(),GIe=function(){function r(){}return r.prototype.initContentAssist=function(){},r.prototype.computeContentAssist=function(e,t){var i=this.gastProductionsCache[e];if((0,pq.isUndefined)(i))throw Error("Rule ->"+e+"<- does not exist in this grammar.");return(0,hq.nextPossibleTokensAfter)([i],t,this.tokenMatcher,this.maxLookahead)},r.prototype.getNextPossibleTokenTypes=function(e){var t=(0,pq.first)(e.ruleStack),i=this.getGAstProductions(),n=i[t],s=new hq.NextAfterTokenWalker(n,e).startWalking();return s},r}();gy.ContentAssist=GIe});var Qq=w(py=>{"use strict";Object.defineProperty(py,"__esModule",{value:!0});py.GastRecorder=void 0;var En=Gt(),Ro=dn(),YIe=gd(),Iq=Gg(),yq=SA(),jIe=Hn(),qIe=ny(),hy={description:"This Object indicates the Parser is during Recording Phase"};Object.freeze(hy);var Cq=!0,mq=Math.pow(2,qIe.BITS_FOR_OCCURRENCE_IDX)-1,wq=(0,yq.createToken)({name:"RECORDING_PHASE_TOKEN",pattern:YIe.Lexer.NA});(0,Iq.augmentTokenTypes)([wq]);var Bq=(0,yq.createTokenInstance)(wq,`This IToken indicates the Parser is in Recording Phase + See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,-1,-1,-1,-1,-1,-1);Object.freeze(Bq);var JIe={name:`This CSTNode indicates the Parser is in Recording Phase + See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,children:{}},WIe=function(){function r(){}return r.prototype.initGastRecorder=function(e){this.recordingProdStack=[],this.RECORDING_PHASE=!1},r.prototype.enableRecording=function(){var e=this;this.RECORDING_PHASE=!0,this.TRACE_INIT("Enable Recording",function(){for(var t=function(n){var s=n>0?n:"";e["CONSUME"+s]=function(o,a){return this.consumeInternalRecord(o,n,a)},e["SUBRULE"+s]=function(o,a){return this.subruleInternalRecord(o,n,a)},e["OPTION"+s]=function(o){return this.optionInternalRecord(o,n)},e["OR"+s]=function(o){return this.orInternalRecord(o,n)},e["MANY"+s]=function(o){this.manyInternalRecord(n,o)},e["MANY_SEP"+s]=function(o){this.manySepFirstInternalRecord(n,o)},e["AT_LEAST_ONE"+s]=function(o){this.atLeastOneInternalRecord(n,o)},e["AT_LEAST_ONE_SEP"+s]=function(o){this.atLeastOneSepFirstInternalRecord(n,o)}},i=0;i<10;i++)t(i);e.consume=function(n,s,o){return this.consumeInternalRecord(s,n,o)},e.subrule=function(n,s,o){return this.subruleInternalRecord(s,n,o)},e.option=function(n,s){return this.optionInternalRecord(s,n)},e.or=function(n,s){return this.orInternalRecord(s,n)},e.many=function(n,s){this.manyInternalRecord(n,s)},e.atLeastOne=function(n,s){this.atLeastOneInternalRecord(n,s)},e.ACTION=e.ACTION_RECORD,e.BACKTRACK=e.BACKTRACK_RECORD,e.LA=e.LA_RECORD})},r.prototype.disableRecording=function(){var e=this;this.RECORDING_PHASE=!1,this.TRACE_INIT("Deleting Recording methods",function(){for(var t=0;t<10;t++){var i=t>0?t:"";delete e["CONSUME"+i],delete e["SUBRULE"+i],delete e["OPTION"+i],delete e["OR"+i],delete e["MANY"+i],delete e["MANY_SEP"+i],delete e["AT_LEAST_ONE"+i],delete e["AT_LEAST_ONE_SEP"+i]}delete e.consume,delete e.subrule,delete e.option,delete e.or,delete e.many,delete e.atLeastOne,delete e.ACTION,delete e.BACKTRACK,delete e.LA})},r.prototype.ACTION_RECORD=function(e){},r.prototype.BACKTRACK_RECORD=function(e,t){return function(){return!0}},r.prototype.LA_RECORD=function(e){return jIe.END_OF_FILE},r.prototype.topLevelRuleRecord=function(e,t){try{var i=new Ro.Rule({definition:[],name:e});return i.name=e,this.recordingProdStack.push(i),t.call(this),this.recordingProdStack.pop(),i}catch(n){if(n.KNOWN_RECORDER_ERROR!==!0)try{n.message=n.message+` + This error was thrown during the "grammar recording phase" For more info see: + https://chevrotain.io/docs/guide/internals.html#grammar-recording`}catch{throw n}throw n}},r.prototype.optionInternalRecord=function(e,t){return bd.call(this,Ro.Option,e,t)},r.prototype.atLeastOneInternalRecord=function(e,t){bd.call(this,Ro.RepetitionMandatory,t,e)},r.prototype.atLeastOneSepFirstInternalRecord=function(e,t){bd.call(this,Ro.RepetitionMandatoryWithSeparator,t,e,Cq)},r.prototype.manyInternalRecord=function(e,t){bd.call(this,Ro.Repetition,t,e)},r.prototype.manySepFirstInternalRecord=function(e,t){bd.call(this,Ro.RepetitionWithSeparator,t,e,Cq)},r.prototype.orInternalRecord=function(e,t){return zIe.call(this,e,t)},r.prototype.subruleInternalRecord=function(e,t,i){if(fy(t),!e||(0,En.has)(e,"ruleName")===!1){var n=new Error(" argument is invalid"+(" expecting a Parser method reference but got: <"+JSON.stringify(e)+">")+(` + inside top level rule: <`+this.recordingProdStack[0].name+">"));throw n.KNOWN_RECORDER_ERROR=!0,n}var s=(0,En.peek)(this.recordingProdStack),o=e.ruleName,a=new Ro.NonTerminal({idx:t,nonTerminalName:o,label:i==null?void 0:i.LABEL,referencedRule:void 0});return s.definition.push(a),this.outputCst?JIe:hy},r.prototype.consumeInternalRecord=function(e,t,i){if(fy(t),!(0,Iq.hasShortKeyProperty)(e)){var n=new Error(" argument is invalid"+(" expecting a TokenType reference but got: <"+JSON.stringify(e)+">")+(` + inside top level rule: <`+this.recordingProdStack[0].name+">"));throw n.KNOWN_RECORDER_ERROR=!0,n}var s=(0,En.peek)(this.recordingProdStack),o=new Ro.Terminal({idx:t,terminalType:e,label:i==null?void 0:i.LABEL});return s.definition.push(o),Bq},r}();py.GastRecorder=WIe;function bd(r,e,t,i){i===void 0&&(i=!1),fy(t);var n=(0,En.peek)(this.recordingProdStack),s=(0,En.isFunction)(e)?e:e.DEF,o=new r({definition:[],idx:t});return i&&(o.separator=e.SEP),(0,En.has)(e,"MAX_LOOKAHEAD")&&(o.maxLookahead=e.MAX_LOOKAHEAD),this.recordingProdStack.push(o),s.call(this),n.definition.push(o),this.recordingProdStack.pop(),hy}function zIe(r,e){var t=this;fy(e);var i=(0,En.peek)(this.recordingProdStack),n=(0,En.isArray)(r)===!1,s=n===!1?r:r.DEF,o=new Ro.Alternation({definition:[],idx:e,ignoreAmbiguities:n&&r.IGNORE_AMBIGUITIES===!0});(0,En.has)(r,"MAX_LOOKAHEAD")&&(o.maxLookahead=r.MAX_LOOKAHEAD);var a=(0,En.some)(s,function(l){return(0,En.isFunction)(l.GATE)});return o.hasPredicates=a,i.definition.push(o),(0,En.forEach)(s,function(l){var c=new Ro.Alternative({definition:[]});o.definition.push(c),(0,En.has)(l,"IGNORE_AMBIGUITIES")?c.ignoreAmbiguities=l.IGNORE_AMBIGUITIES:(0,En.has)(l,"GATE")&&(c.ignoreAmbiguities=!0),t.recordingProdStack.push(c),l.ALT.call(t),t.recordingProdStack.pop()}),hy}function Eq(r){return r===0?"":""+r}function fy(r){if(r<0||r>mq){var e=new Error("Invalid DSL Method idx value: <"+r+`> + `+("Idx value must be a none negative value smaller than "+(mq+1)));throw e.KNOWN_RECORDER_ERROR=!0,e}}});var Sq=w(dy=>{"use strict";Object.defineProperty(dy,"__esModule",{value:!0});dy.PerformanceTracer=void 0;var bq=Gt(),VIe=Hn(),XIe=function(){function r(){}return r.prototype.initPerformanceTracer=function(e){if((0,bq.has)(e,"traceInitPerf")){var t=e.traceInitPerf,i=typeof t=="number";this.traceInitMaxIdent=i?t:1/0,this.traceInitPerf=i?t>0:t}else this.traceInitMaxIdent=0,this.traceInitPerf=VIe.DEFAULT_PARSER_CONFIG.traceInitPerf;this.traceInitIndent=-1},r.prototype.TRACE_INIT=function(e,t){if(this.traceInitPerf===!0){this.traceInitIndent++;var i=new Array(this.traceInitIndent+1).join(" ");this.traceInitIndent <"+e+">");var n=(0,bq.timer)(t),s=n.time,o=n.value,a=s>10?console.warn:console.log;return this.traceInitIndent time: "+s+"ms"),this.traceInitIndent--,o}else return t()},r}();dy.PerformanceTracer=XIe});var vq=w(Cy=>{"use strict";Object.defineProperty(Cy,"__esModule",{value:!0});Cy.applyMixins=void 0;function _Ie(r,e){e.forEach(function(t){var i=t.prototype;Object.getOwnPropertyNames(i).forEach(function(n){if(n!=="constructor"){var s=Object.getOwnPropertyDescriptor(i,n);s&&(s.get||s.set)?Object.defineProperty(r.prototype,n,s):r.prototype[n]=t.prototype[n]}})})}Cy.applyMixins=_Ie});var Hn=w(dr=>{"use strict";var Dq=dr&&dr.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(dr,"__esModule",{value:!0});dr.EmbeddedActionsParser=dr.CstParser=dr.Parser=dr.EMPTY_ALT=dr.ParserDefinitionErrorType=dr.DEFAULT_RULE_CONFIG=dr.DEFAULT_PARSER_CONFIG=dr.END_OF_FILE=void 0;var Xi=Gt(),ZIe=fj(),xq=SA(),kq=Cd(),Pq=Kj(),$Ie=jv(),eye=Wj(),tye=iq(),rye=sq(),iye=aq(),nye=uq(),sye=fq(),oye=dq(),aye=Qq(),Aye=Sq(),lye=vq();dr.END_OF_FILE=(0,xq.createTokenInstance)(xq.EOF,"",NaN,NaN,NaN,NaN,NaN,NaN);Object.freeze(dr.END_OF_FILE);dr.DEFAULT_PARSER_CONFIG=Object.freeze({recoveryEnabled:!1,maxLookahead:3,dynamicTokensEnabled:!1,outputCst:!0,errorMessageProvider:kq.defaultParserErrorProvider,nodeLocationTracking:"none",traceInitPerf:!1,skipValidations:!1});dr.DEFAULT_RULE_CONFIG=Object.freeze({recoveryValueFunc:function(){},resyncEnabled:!0});var cye;(function(r){r[r.INVALID_RULE_NAME=0]="INVALID_RULE_NAME",r[r.DUPLICATE_RULE_NAME=1]="DUPLICATE_RULE_NAME",r[r.INVALID_RULE_OVERRIDE=2]="INVALID_RULE_OVERRIDE",r[r.DUPLICATE_PRODUCTIONS=3]="DUPLICATE_PRODUCTIONS",r[r.UNRESOLVED_SUBRULE_REF=4]="UNRESOLVED_SUBRULE_REF",r[r.LEFT_RECURSION=5]="LEFT_RECURSION",r[r.NONE_LAST_EMPTY_ALT=6]="NONE_LAST_EMPTY_ALT",r[r.AMBIGUOUS_ALTS=7]="AMBIGUOUS_ALTS",r[r.CONFLICT_TOKENS_RULES_NAMESPACE=8]="CONFLICT_TOKENS_RULES_NAMESPACE",r[r.INVALID_TOKEN_NAME=9]="INVALID_TOKEN_NAME",r[r.NO_NON_EMPTY_LOOKAHEAD=10]="NO_NON_EMPTY_LOOKAHEAD",r[r.AMBIGUOUS_PREFIX_ALTS=11]="AMBIGUOUS_PREFIX_ALTS",r[r.TOO_MANY_ALTS=12]="TOO_MANY_ALTS"})(cye=dr.ParserDefinitionErrorType||(dr.ParserDefinitionErrorType={}));function uye(r){return r===void 0&&(r=void 0),function(){return r}}dr.EMPTY_ALT=uye;var my=function(){function r(e,t){this.definitionErrors=[],this.selfAnalysisDone=!1;var i=this;if(i.initErrorHandler(t),i.initLexerAdapter(),i.initLooksAhead(t),i.initRecognizerEngine(e,t),i.initRecoverable(t),i.initTreeBuilder(t),i.initContentAssist(),i.initGastRecorder(t),i.initPerformanceTracer(t),(0,Xi.has)(t,"ignoredIssues"))throw new Error(`The IParserConfig property has been deprecated. + Please use the flag on the relevant DSL method instead. + See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#IGNORING_AMBIGUITIES + For further details.`);this.skipValidations=(0,Xi.has)(t,"skipValidations")?t.skipValidations:dr.DEFAULT_PARSER_CONFIG.skipValidations}return r.performSelfAnalysis=function(e){throw Error("The **static** `performSelfAnalysis` method has been deprecated. \nUse the **instance** method with the same name instead.")},r.prototype.performSelfAnalysis=function(){var e=this;this.TRACE_INIT("performSelfAnalysis",function(){var t;e.selfAnalysisDone=!0;var i=e.className;e.TRACE_INIT("toFastProps",function(){(0,Xi.toFastProperties)(e)}),e.TRACE_INIT("Grammar Recording",function(){try{e.enableRecording(),(0,Xi.forEach)(e.definedRulesNames,function(s){var o=e[s],a=o.originalGrammarAction,l=void 0;e.TRACE_INIT(s+" Rule",function(){l=e.topLevelRuleRecord(s,a)}),e.gastProductionsCache[s]=l})}finally{e.disableRecording()}});var n=[];if(e.TRACE_INIT("Grammar Resolving",function(){n=(0,Pq.resolveGrammar)({rules:(0,Xi.values)(e.gastProductionsCache)}),e.definitionErrors=e.definitionErrors.concat(n)}),e.TRACE_INIT("Grammar Validations",function(){if((0,Xi.isEmpty)(n)&&e.skipValidations===!1){var s=(0,Pq.validateGrammar)({rules:(0,Xi.values)(e.gastProductionsCache),maxLookahead:e.maxLookahead,tokenTypes:(0,Xi.values)(e.tokensMap),errMsgProvider:kq.defaultGrammarValidatorErrorProvider,grammarName:i});e.definitionErrors=e.definitionErrors.concat(s)}}),(0,Xi.isEmpty)(e.definitionErrors)&&(e.recoveryEnabled&&e.TRACE_INIT("computeAllProdsFollows",function(){var s=(0,ZIe.computeAllProdsFollows)((0,Xi.values)(e.gastProductionsCache));e.resyncFollows=s}),e.TRACE_INIT("ComputeLookaheadFunctions",function(){e.preComputeLookaheadFunctions((0,Xi.values)(e.gastProductionsCache))})),!r.DEFER_DEFINITION_ERRORS_HANDLING&&!(0,Xi.isEmpty)(e.definitionErrors))throw t=(0,Xi.map)(e.definitionErrors,function(s){return s.message}),new Error(`Parser Definition Errors detected: + `+t.join(` +------------------------------- +`))})},r.DEFER_DEFINITION_ERRORS_HANDLING=!1,r}();dr.Parser=my;(0,lye.applyMixins)(my,[$Ie.Recoverable,eye.LooksAhead,tye.TreeBuilder,rye.LexerAdapter,nye.RecognizerEngine,iye.RecognizerApi,sye.ErrorHandler,oye.ContentAssist,aye.GastRecorder,Aye.PerformanceTracer]);var gye=function(r){Dq(e,r);function e(t,i){i===void 0&&(i=dr.DEFAULT_PARSER_CONFIG);var n=this,s=(0,Xi.cloneObj)(i);return s.outputCst=!0,n=r.call(this,t,s)||this,n}return e}(my);dr.CstParser=gye;var fye=function(r){Dq(e,r);function e(t,i){i===void 0&&(i=dr.DEFAULT_PARSER_CONFIG);var n=this,s=(0,Xi.cloneObj)(i);return s.outputCst=!1,n=r.call(this,t,s)||this,n}return e}(my);dr.EmbeddedActionsParser=fye});var Fq=w(Ey=>{"use strict";Object.defineProperty(Ey,"__esModule",{value:!0});Ey.createSyntaxDiagramsCode=void 0;var Rq=pv();function hye(r,e){var t=e===void 0?{}:e,i=t.resourceBase,n=i===void 0?"https://unpkg.com/chevrotain@"+Rq.VERSION+"/diagrams/":i,s=t.css,o=s===void 0?"https://unpkg.com/chevrotain@"+Rq.VERSION+"/diagrams/diagrams.css":s,a=` + + + + + +`,l=` + +`,c=` +